diff --git a/examples/layaair/backend/.vscode/launch.json b/examples/layaair/backend/.vscode/launch.json new file mode 100644 index 0000000..9ba4218 --- /dev/null +++ b/examples/layaair/backend/.vscode/launch.json @@ -0,0 +1,30 @@ +{ + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "mocha current file", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "${file}" + ], + "internalConsoleOptions": "openOnSessionStart", + "cwd": "${workspaceFolder}" + }, + { + "type": "node", + "request": "launch", + "name": "ts-node current file", + "protocol": "inspector", + "args": [ + "${relativeFile}" + ], + "cwd": "${workspaceRoot}", + "runtimeArgs": [ + "-r", + "ts-node/register" + ], + "internalConsoleOptions": "openOnSessionStart" + } + ] +} \ No newline at end of file diff --git a/examples/layaair/backend/.vscode/settings.json b/examples/layaair/backend/.vscode/settings.json new file mode 100644 index 0000000..00ad71f --- /dev/null +++ b/examples/layaair/backend/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "typescript.tsdk": "node_modules\\typescript\\lib" +} \ No newline at end of file diff --git a/examples/layaair/backend/README.md b/examples/layaair/backend/README.md new file mode 100644 index 0000000..7492c22 --- /dev/null +++ b/examples/layaair/backend/README.md @@ -0,0 +1,35 @@ +# TSRPC Server + +## Run +### Local Dev Server +``` +npm run dev +``` + + + +### Build +``` +npm run build +``` + +--- + +## Files +### Generate ServiceProto +``` +npm run proto +``` + +### Generate API templates +``` +npm run api +``` + +### Sync shared code to client + +``` +npm run sync +``` + +> If you chose symlink when using `create-tsrpc-app`, it would re-create the symlink instead of copy files. diff --git a/examples/layaair/backend/package.json b/examples/layaair/backend/package.json new file mode 100644 index 0000000..a0e26be --- /dev/null +++ b/examples/layaair/backend/package.json @@ -0,0 +1,23 @@ +{ + "name": "tsrpc-app-backend", + "version": "0.1.0", + "main": "index.js", + "private": true, + "scripts": { + "proto": "tsrpc proto -i src/shared/protocols -o src/shared/protocols/serviceProto.ts", + "sync": "tsrpc sync --from src/shared --to ../frontend/src/shared", + "api": "tsrpc api -i src/shared/protocols/serviceProto.ts -o src/api", + "dev": "onchange \"src/**/*.ts\" -i -k -- ts-node \"src/index.ts\"", + "build": "tsrpc build" + }, + "devDependencies": { + "@types/node": "^15.14.1", + "onchange": "^7.1.0", + "ts-node": "^10.0.0", + "tsrpc-cli": "^2.0.3", + "typescript": "^4.3.5" + }, + "dependencies": { + "tsrpc": "^3.0.4" + } +} diff --git a/examples/layaair/backend/src/api/ApiAddData.ts b/examples/layaair/backend/src/api/ApiAddData.ts new file mode 100644 index 0000000..c064789 --- /dev/null +++ b/examples/layaair/backend/src/api/ApiAddData.ts @@ -0,0 +1,26 @@ +import { ApiCall } from "tsrpc"; +import { ReqAddData, ResAddData } from "../shared/protocols/PtlAddData"; +import { AllData } from "./ApiGetData"; + +// This is a demo code file +// Feel free to delete it + +export async function ApiAddData(call: ApiCall) { + // Error + if (call.req.content === '') { + call.error('Content is empty'); + return; + } + + let time = new Date(); + AllData.unshift({ + content: call.req.content, + time: time + }) + console.log('AllData', AllData) + + // Success + call.succ({ + time: time + }); +} \ No newline at end of file diff --git a/examples/layaair/backend/src/api/ApiGetData.ts b/examples/layaair/backend/src/api/ApiGetData.ts new file mode 100644 index 0000000..2996ee4 --- /dev/null +++ b/examples/layaair/backend/src/api/ApiGetData.ts @@ -0,0 +1,13 @@ +import { ApiCall } from "tsrpc"; +import { ReqGetData, ResGetData } from "../shared/protocols/PtlGetData"; + +// This is a demo code file +// Feel free to delete it + +export async function ApiGetData(call: ApiCall) { + call.succ({ + data: AllData + }) +} + +export const AllData: { content: string, time: Date }[] = []; \ No newline at end of file diff --git a/examples/layaair/backend/src/index copy.ts b/examples/layaair/backend/src/index copy.ts new file mode 100644 index 0000000..c9d7dce --- /dev/null +++ b/examples/layaair/backend/src/index copy.ts @@ -0,0 +1,60 @@ +import { IncomingMessage } from "http"; +import * as path from "path"; +import { Counter, HttpConnection, HttpServer } from "tsrpc"; +import { serviceProto, ServiceType } from "./shared/protocols/serviceProto"; + +// Create the Server +const server = new HttpServer(serviceProto, { + port: 3000, + cors: '*' +}); + +// Init +export async function init(context: any, callback: (err: Error | null, data: any) => void) { + // Auto implement APIs + await server.autoImplementApi(path.resolve(__dirname, 'api')); + callback(null, ''); +} + +const connCounter = new Counter(1); + +// Handler +export function handler(httpReq: IncomingMessage, httpRes: { + setStatusCode: (code: number) => void, + setHeader: (key: string, value: string) => void, + deleteHeader: (key: string) => void, + send: (body: Buffer | string) => void +}, context: any) { + httpRes.setStatusCode(200); + httpRes.setHeader('X-Powered-By', `TSRPC`); + httpRes.setHeader('Access-Control-Allow-Origin', '*'); + httpRes.setHeader('Access-Control-Allow-Headers', 'Content-Type,*'); + if (httpReq.method === 'OPTIONS') { + httpRes.send(''); + return; + } + + let chunks: Buffer[] = []; + httpReq.on('data', data => { + chunks.push(data); + }); + + let conn: HttpConnection | undefined; + httpReq.on('end', async () => { + let isJSON = false; + conn = new HttpConnection({ + server: 'FAAS' as any, + id: '' + connCounter.getNext(), + ip: '???', + httpReq: httpReq, + httpRes: { end: httpRes.send.bind(httpRes) } as any, + isJSON: isJSON + }); + await server.flows.postConnectFlow.exec(conn, conn.logger); + + let buf = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks); + + server['_onRecvBuffer'](conn, buf); + }); +} + diff --git a/examples/layaair/backend/src/index.ts b/examples/layaair/backend/src/index.ts new file mode 100644 index 0000000..aa8f288 --- /dev/null +++ b/examples/layaair/backend/src/index.ts @@ -0,0 +1,38 @@ +import * as path from "path"; +import { HttpConnection, HttpServer } from "tsrpc"; +import { serviceProto } from "./shared/protocols/serviceProto"; + +// Create the Server +const server = new HttpServer(serviceProto, { + port: 3000, + cors: '*', + socketTimeout: 0, + keepAliveTimeout: 0 +}); + +server.flows.preRecvBufferFlow.push(v => { + let conn = v.conn as HttpConnection; + if (conn.httpReq.method === 'GET') { + conn.httpRes.end('TSRPC Server'); + return undefined; + } + + return v; +}) + +// Entry function +async function main() { + // Auto implement APIs + await server.autoImplementApi(path.resolve(__dirname, 'api')); + + // TODO + // Prepare something... (e.g. connect the db) + + await server.start(); +}; + +main().catch(e => { + // Exit if any error during the startup + server.logger.error(e); + process.exit(-1); +}); \ No newline at end of file diff --git a/examples/layaair/backend/src/shared/protocols/PtlAddData.ts b/examples/layaair/backend/src/shared/protocols/PtlAddData.ts new file mode 100644 index 0000000..7f442ae --- /dev/null +++ b/examples/layaair/backend/src/shared/protocols/PtlAddData.ts @@ -0,0 +1,10 @@ +// This is a demo code file +// Feel free to delete it + +export interface ReqAddData { + content: string; +} + +export interface ResAddData { + time: Date +} \ No newline at end of file diff --git a/examples/layaair/backend/src/shared/protocols/PtlGetData.ts b/examples/layaair/backend/src/shared/protocols/PtlGetData.ts new file mode 100644 index 0000000..8ac35a7 --- /dev/null +++ b/examples/layaair/backend/src/shared/protocols/PtlGetData.ts @@ -0,0 +1,13 @@ +// This is a demo code file +// Feel free to delete it + +export interface ReqGetData { + +} + +export interface ResGetData { + data: { + content: string, + time: Date + }[] +} \ No newline at end of file diff --git a/examples/layaair/backend/src/shared/protocols/serviceProto.ts b/examples/layaair/backend/src/shared/protocols/serviceProto.ts new file mode 100644 index 0000000..e7207a9 --- /dev/null +++ b/examples/layaair/backend/src/shared/protocols/serviceProto.ts @@ -0,0 +1,98 @@ +import { ServiceProto } from 'tsrpc-proto'; +import { ReqAddData, ResAddData } from './PtlAddData'; +import { ReqGetData, ResGetData } from './PtlGetData'; + +// This is a demo service proto file (auto generated) +// Feel free to delete it + +export interface ServiceType { + api: { + "AddData": { + req: ReqAddData, + res: ResAddData + }, + "GetData": { + req: ReqGetData, + res: ResGetData + } + }, + msg: { + + } +} + +export const serviceProto: ServiceProto = { + "version": 1, + "services": [ + { + "id": 0, + "name": "AddData", + "type": "api" + }, + { + "id": 1, + "name": "GetData", + "type": "api" + } + ], + "types": { + "PtlAddData/ReqAddData": { + "type": "Interface", + "properties": [ + { + "id": 0, + "name": "content", + "type": { + "type": "String" + } + } + ] + }, + "PtlAddData/ResAddData": { + "type": "Interface", + "properties": [ + { + "id": 0, + "name": "time", + "type": { + "type": "Date" + } + } + ] + }, + "PtlGetData/ReqGetData": { + "type": "Interface" + }, + "PtlGetData/ResGetData": { + "type": "Interface", + "properties": [ + { + "id": 0, + "name": "data", + "type": { + "type": "Array", + "elementType": { + "type": "Interface", + "properties": [ + { + "id": 0, + "name": "content", + "type": { + "type": "String" + } + }, + { + "id": 1, + "name": "time", + "type": { + "type": "Date" + } + } + ] + } + } + } + ] + } + } +}; \ No newline at end of file diff --git a/examples/layaair/backend/tsconfig.json b/examples/layaair/backend/tsconfig.json new file mode 100644 index 0000000..d18498f --- /dev/null +++ b/examples/layaair/backend/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "lib": [ + "es2018" + ], + "module": "commonjs", + "target": "es2018", + "outDir": "dist", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "moduleResolution": "node" + }, + "include": [ + "src" + ] +} \ No newline at end of file diff --git a/examples/layaair/frontend/.gitignore b/examples/layaair/frontend/.gitignore new file mode 100644 index 0000000..55112ec --- /dev/null +++ b/examples/layaair/frontend/.gitignore @@ -0,0 +1,2 @@ +.rpt2_cache +node_modules \ No newline at end of file diff --git a/examples/layaair/frontend/.laya/compile.js b/examples/layaair/frontend/.laya/compile.js new file mode 100644 index 0000000..5d74584 --- /dev/null +++ b/examples/layaair/frontend/.laya/compile.js @@ -0,0 +1,75 @@ +// v1.2.7 +//是否使用IDE自带的node环境和插件,设置false后,则使用自己环境(使用命令行方式执行) +const useIDENode = process.argv[0].indexOf("LayaAir") > -1 ? true : false; +const useCMDNode = process.argv[1].indexOf("layaair2-cmd") > -1 ? true : false; + +function useOtherNode(){ + return useIDENode||useCMDNode; +} +//获取Node插件和工作路径 +let ideModuleDir = useOtherNode() ? process.argv[1].replace("gulp\\bin\\gulp.js", "").replace("gulp/bin/gulp.js", "") : ""; +let workSpaceDir = useOtherNode() ? process.argv[2].replace("--gulpfile=", "").replace("\\.laya\\compile.js", "").replace("/.laya/compile.js", "") : "./../"; + +const gulp = require(ideModuleDir + "gulp"); +const rollup = require(ideModuleDir + "rollup"); +const typescript = require(ideModuleDir + 'rollup-plugin-typescript2');//typescript2 plugin +const glsl = require(ideModuleDir + 'rollup-plugin-glsl'); +const path = require('path'); +const fs = require('fs'); + +// 如果是发布时调用编译功能,增加prevTasks +let prevTasks = ""; +if (global.publish) { + prevTasks = ["loadConfig"]; +} + +gulp.task("compile", prevTasks, function () { + // 发布时调用编译功能,判断是否点击了编译选项 + if (global.publish) { + workSpaceDir = global.workSpaceDir; // 发布时调用编译,workSpaceDir使用publish.js里的变量 + let forceCompile = !fs.existsSync(path.join(workSpaceDir, "bin", "js", "bundle.js")); // 发布时,并且没有编译过,则强制编译 + if (!global.config.compile && !forceCompile) { + return; + } + } + + return rollup.rollup({ + input: workSpaceDir + '/src/Main.ts', + onwarn:(waring,warn)=>{ + if(waring.code == "CIRCULAR_DEPENDENCY"){ + console.log("warnning Circular dependency:"); + console.log(waring); + } + }, + treeshake: false, //建议忽略 + plugins: [ + typescript({ + tsconfig:workSpaceDir + "/tsconfig.json", + check: true, //Set to false to avoid doing any diagnostic checks on the code + tsconfigOverride:{compilerOptions:{removeComments: true}}, + include:/.*.ts/, + }), + glsl({ + // By default, everything gets included + include: /.*(.glsl|.vs|.fs)$/, + sourceMap: false, + compress:false + }), + /*terser({ + output: { + }, + numWorkers:1,//Amount of workers to spawn. Defaults to the number of CPUs minus 1 + sourcemap: false + })*/ + ] + }).then(bundle => { + return bundle.write({ + file: workSpaceDir + '/bin/js/bundle.js', + format: 'iife', + name: 'laya', + sourcemap: false + }); + }).catch(err=>{ + console.log(err); + }); +}); \ No newline at end of file diff --git a/examples/layaair/frontend/.laya/layame/account.info b/examples/layaair/frontend/.laya/layame/account.info new file mode 100644 index 0000000..9f92ef2 --- /dev/null +++ b/examples/layaair/frontend/.laya/layame/account.info @@ -0,0 +1 @@ +{"username":null,"gameId":null} \ No newline at end of file diff --git a/examples/layaair/frontend/.laya/pub_utils.js b/examples/layaair/frontend/.laya/pub_utils.js new file mode 100644 index 0000000..ab83b7e --- /dev/null +++ b/examples/layaair/frontend/.laya/pub_utils.js @@ -0,0 +1,92 @@ +// v1.0.0 +const ideModuleDir = global.ideModuleDir; +const workSpaceDir = global.workSpaceDir; + +const fs = require("fs"); +const path = require("path"); +const crypto = require("crypto"); + +function getEngineVersion() { + let coreLibPath = path.join(workSpaceDir, "bin", "libs", "laya.core.js"); + let isHasCoreLib = fs.existsSync(coreLibPath); + let isOldAsProj = fs.existsSync(`${workSpaceDir}/asconfig.json`) && !isHasCoreLib; + let isNewTsProj = fs.existsSync(`${workSpaceDir}/src/tsconfig.json`) && !isHasCoreLib; + let EngineVersion; + if (isHasCoreLib) { + let con = fs.readFileSync(coreLibPath, "utf8"); + let matchList = con.match(/Laya\.version\s*=\s*['"]([0-9\.]+(beta)?.*)['"]/); + if (!Array.isArray(matchList)) { + return null; + } + EngineVersion = matchList[1]; + } else { // newts项目和旧版本as项目 + if (isOldAsProj) { + let coreLibFilePath = path.join(workSpaceDir, "libs", "laya", "src", "Laya.as"); + if (!fs.existsSync(coreLibFilePath)) { + return null; + } + let con = fs.readFileSync(coreLibFilePath, "utf8"); + let matchList = con.match(/version:String\s*=\s*['"]([0-9\.]+(beta)?.*)['"]/); + if (!Array.isArray(matchList)) { + return null; + } + EngineVersion = matchList[1]; + } else if (isNewTsProj) { + let coreLibFilePath = path.join(workSpaceDir, "libs", "Laya.ts"); + if (!fs.existsSync(coreLibFilePath)) { + return null; + } + let con = fs.readFileSync(coreLibFilePath, "utf8"); + let matchList = con.match(/static\s*version:\s*string\s*=\s*['"]([0-9\.]+(beta)?.*)['"]/); + if (!Array.isArray(matchList)) { + return null; + } + EngineVersion = matchList[1]; + } + } + // 特殊处理,因为历史原因,我们有一些4位的正式版本,调整为3位 + if (EngineVersion && /[\d\.]+/.test(EngineVersion) && EngineVersion.split(".").length > 3) { + let verList = EngineVersion.split("."); + verList.length = 3; + EngineVersion = verList.join("."); + } + return EngineVersion; +} + +function getFileMd5(filePath) { + return new Promise(function(resolve, reject) { + let md5 = crypto.createHash('md5'); + let stream = fs.createReadStream(filePath); + stream.on("data", function(data) { + md5.update(data); + }); + stream.on("end", function() { + let md5Str = md5.digest('hex'); + return resolve(md5Str); + }); + }); +} + +function canUsePluginEngine(libsVersion, minVersionNum) { + let compileMacthList = minVersionNum.match(/^(\d+)\.(\d+)\.(\d+)/); + let matchList = libsVersion.match(/^(\d+)\.(\d+)\.(\d+)/); + let + s1n = Number(matchList[1]), // src first number + s2n = Number(matchList[2]), + s3n = Number(matchList[3]), + t1n = Number(compileMacthList[1]), // to first number + t2n = Number(compileMacthList[2]), + t3n = Number(compileMacthList[3]); + if (s1n > t1n) { + return true; + } + if (s1n === t1n && s2n > t2n) { + return true; + } + if (s1n === t1n && s2n === t2n && s3n >= t3n) { + return true; + } + return false; +} + +module.exports = { getEngineVersion, getFileMd5, canUsePluginEngine } diff --git a/examples/layaair/frontend/.laya/publish.js b/examples/layaair/frontend/.laya/publish.js new file mode 100644 index 0000000..11df7d4 --- /dev/null +++ b/examples/layaair/frontend/.laya/publish.js @@ -0,0 +1,794 @@ +// v1.8.18 +//是否使用IDE自带的node环境和插件,设置false后,则使用自己环境(使用命令行方式执行) +const useIDENode = process.argv[0].indexOf("LayaAir") > -1 ? true : false; +const useCMDNode = process.argv[1].indexOf("layaair2-cmd") > -1 ? true : false; +const pubLayame = process.argv.length >= 4 && process.argv[3].startsWith("--config") && process.argv[3].endsWith("layame.json"); +function useOtherNode(){ + return useIDENode||useCMDNode ||pubLayame; +} +//获取Node插件和工作路径 +const ideModuleDir = useOtherNode() ? process.argv[1].replace("gulp\\bin\\gulp.js", "").replace("gulp/bin/gulp.js", "") : ""; +const workSpaceDir = useOtherNode() ? process.argv[2].replace("--gulpfile=", "").replace("\\.laya\\publish.js", "").replace("/.laya/publish.js", "") + "/" : "./../"; +global.ideModuleDir = ideModuleDir; +global.workSpaceDir = workSpaceDir; +//引用插件模块 +const gulp = require(ideModuleDir + "gulp"); +const fs = require("fs"); +const path = require("path"); +const childProcess = require("child_process"); +const uglify = require(ideModuleDir + 'gulp-uglify-es').default; +const jsonminify = require(ideModuleDir + "gulp-jsonminify"); +const image = require(ideModuleDir + "gulp-image"); +const rev = require(ideModuleDir + "gulp-rev"); +const revdel = require(ideModuleDir + "gulp-rev-delete-original"); +const revCollector = require(ideModuleDir + 'gulp-rev-collector'); +const del = require(ideModuleDir + "del"); +const requireDir = require(ideModuleDir + 'require-dir'); +const babel = require(ideModuleDir + 'gulp-babel'); + +// 结合compile.js使用 +global.publish = true; +const fileList = ["compile.js", "pub_utils.js", "publish_xmgame.js", "publish_oppogame.js", "publish_vivogame.js", "publish_biligame.js", + "publish_alipaygame.js", "publish_wxgame.js", "publish_bdgame.js", "publish_qqgame.js", "publish_bytedancegame.js", "publish_hwgame.js", + "publish_taobaominiapp.js", "publish_youkugame.js", "publish_taobaowidget.js", "publish_layame.js"]; +requireDir('./', { + filter: function (fullPath) { + // 只用到了compile.js和publish.js + if (fileList.includes(path.basename(fullPath))) { + return true; + } else { + return false; + } + } +}); + +const QUICKGAMELIST = ["xmgame", "oppogame", "vivogame", "hwgame"]; + +// 清理临时文件夹,加载配置 +let config, + releaseDir, + binPath, + platform = "web", + isOpendataProj = false, + platformCopyTask = [],// 平台脚本拷贝任务 + platformTask = [], // 平台需要执行的任务 + commandSuffix = ".cmd", + adbPath = "adb", + opensslPath = "openssl"; +let execTask; +//任务对照列表 +const copyTasks = { + "layame": "copy", + "taobaowidget": "preCreate_TBWidget", + "youkugame": "copyPlatformFile_youku", + "taobaominiapp": "preCreate_TBMini", + "hwgame": "copyPlatformFile_HW", + "bytedancegame": "copyPlatformFile_ByteDance", + "biligame": "copyPlatformFile_Bili", + "Alipaygame": "copyPlatformFile_Alipay", + "vivogame": "copyPlatformFile_VIVO", + "oppogame": "copyPlatformFile_OPPO", + "xmgame": "copyPlatformFile_XM", + "bdgame": "copyPlatformFile_BD", + "qqgame": "copyPlatformFile_QQ", + "wxgame": "fitwasm_WX", + "web": "copyPlatformLibsJsFile" +} +const tasks = { + "layame": "buildLayaMeProj", + "taobaowidget": "buildTBWidgetProj", + "youkugame": "buildYKProj", + "taobaominiapp": "buildTBMiniProj", + "hwgame": "buildHWProj", + "bytedancegame": "buildByteDanceProj", + "biligame": "buildBiliProj", + "Alipaygame": "buildAlipayProj", + "vivogame": "buildVivoProj", + "oppogame": "buildOPPOProj", + "xmgame": "buildXiaomiProj", + "bdgame": "buildBDProj", + "qqgame": "buildQQProj", + "wxgame": "buildWXProj", + "web": "version2" +} +// 是否build指定部分(debug版本layame) +let buildOptions = null; +function toBuildPart(part) { + if (!buildOptions) { + return true; + } + if ('all' == part ) { + return buildOptions.type == 'all'; + } + if (buildOptions.type == 'all') { + return true; + } + return (buildOptions.buildList.includes(part)); +} +if (!useOtherNode() && process.argv.length > 5 && process.argv[4] == "--config") { + platform = process.argv[5].replace(".json", ""); +} +if (useOtherNode() && process.argv.length >= 4 && process.argv[3].startsWith("--config") && process.argv[3].endsWith(".json")) { + platform = process.argv[3].match(/(\w+).json/)[1]; + platformCopyTask.push(copyTasks[platform]); + platformTask.push(tasks[platform]); + execTask = process.argv[4]; +} +let isDebugLayaMe = false; +gulp.task("loadConfig", function (cb) { + let _path; + if (!useOtherNode()) { + _path = platform + ".json"; + releaseDir = "../release/" + platform; + binPath = "../bin/"; + } + if (useOtherNode()) { + _path = path.join(workSpaceDir, ".laya", `${platform}.json`); + releaseDir = path.join(workSpaceDir, "release", platform).replace(/\\/g, "/"); + binPath = path.join(workSpaceDir, "bin").replace(/\\/g, "/"); + } + global.platform = platform; + let file = fs.readFileSync(_path, "utf-8"); + if (file) { + if (platform == 'layame') { + let tmpconfig = JSON.parse(file); + if (tmpconfig.debugLayaMe) { + // 如本地调试版layame + releaseDir = path.join(workSpaceDir, 'layaMe').replace(/\\/g, "/"); + isDebugLayaMe = true; + } + } + if ([...QUICKGAMELIST, "taobaominiapp", "taobaowidget"].includes(platform)) { + file = file.replace(/\$basePath/g, releaseDir + "/temprelease"); + } else { + file = file.replace(/\$basePath/g, releaseDir); + } + config = JSON.parse(file); + global.config = config; + if (isDebugLayaMe) { + buildOptions = config.buildOptions; + } + // 我们遇到一个bug,当使用min库,同时开启es6toes5后,es6toes5时会将min库部分变量忽略,导致程序出错 + // 我们原来的逻辑: 1) 将min库es6toes5 2) 将转换后的库重新压缩 + // 所以,当使用min库同时开启es6toes5时,我们将: 1) 使用普通库 2) 开启js压缩 + if (config.useMinJsLibs && config.es6toes5) { + config.useMinJsLibs = false; + config.compressJs = true; + } + } + // 是否是开放域项目 + let projInfoPath = path.join(workSpaceDir, path.basename(workSpaceDir) + ".laya"); + let isExist = fs.existsSync(projInfoPath); + if (isExist) { + try { + let projInfo = fs.readFileSync(projInfoPath, "utf8"); + projInfo = projInfo && JSON.parse(projInfo); + isOpendataProj = projInfo.layaProType === 12; + } catch (e) {} + } + // 其他变量的初始化 + let layarepublicPath = path.join(ideModuleDir, "../", "code", "layarepublic"); + if (!fs.existsSync(layarepublicPath)) { + layarepublicPath = path.join(ideModuleDir, "../", "out", "layarepublic"); + } + global.layarepublicPath = layarepublicPath; + + if (process.platform === "darwin") { + commandSuffix = ""; + } + global.commandSuffix = commandSuffix; + + // 检查环境中是否存在adb和openssl + let otherLibsPath = path.join(layarepublicPath, "../", "vs", "layaEditor", "libs"); + childProcess.exec("adb version", (error, stdout, stderr) => { + if (error) { + if (process.platform === "darwin") { + adbPath = path.join(otherLibsPath, "adb", "darwin", "adb"); + } else { + adbPath = path.join(otherLibsPath, "adb", "win", "adb.exe"); + } + adbPath = `"${adbPath}"`; + } + global.adbPath = adbPath; + if (global.opensslPath) { + cb(); + } + }); + childProcess.exec("openssl version", (error, stdout, stderr) => { + if (error) { + if (process.platform === "darwin") { + opensslPath = path.join(otherLibsPath, "openssl", "darwin", "bin", "openssl"); + } else { + opensslPath = path.join(otherLibsPath, "openssl", "win", "bin", "openssl.exe"); + let opensslCnfPath = path.join(otherLibsPath, "openssl", "win", "bin", "openssl.cfg"); + // 特别的,当windows没有openssl时,需要额外的OPENSSL_CONF设置变量 + // childProcess.execSync(`set OPENSSL_CONF=${opensslCnfPath}`); + process.env.OPENSSL_CONF = opensslCnfPath; + console.log("OPENSSL_CONF: " + childProcess.execSync("echo %OPENSSL_CONF%")); + } + opensslPath = `"${opensslPath}"`; + } + global.opensslPath = opensslPath; + if (global.adbPath) { + cb(); + } + }); +}); + +// 清理release文件夹 +gulp.task("clearReleaseDir", ["compile"], function (cb) { + if (platform === "layame" && execTask !== "clearReleaseDir") { // 特殊的,layame项目不执行清理命令 + return cb(); + } + if (config.clearReleaseDir) { + let delList = [`${releaseDir}/**`, releaseDir + "_pack"]; + if (config.packfileTargetValue) { + delList.push(config.packfileTargetValue); + } + // 小米快游戏,使用即存的项目,删掉Laya工程文件,保留小米环境项目文件 + if (platform === "xmgame") { + let xmProj = path.join(releaseDir, config.xmInfo.projName); + // 这里不是node-glob语法,详见: https://github.com/sindresorhus/del + delList = [`${xmProj}/**`, `!${xmProj}`, `!${xmProj}/node_modules/**`, `!${xmProj}/sign/**`, `!${xmProj}/{babel.config.js,main.js,manifest.json,package.json,package-lock.json}`]; + } else if (platform === "oppogame") { + let oppoProjSrc = path.join(releaseDir, config.oppoInfo.projName); + delList = [`${oppoProjSrc}/**`, `!${oppoProjSrc}`, `!${oppoProjSrc}/{manifest.json,main.js}`]; + } else if (platform === "vivogame") { + let vvProj = path.join(releaseDir, config.vivoInfo.projName); + let vvProjSrc = path.join(vvProj, "src"); + // 这里不是node-glob语法,详见: https://github.com/sindresorhus/del + delList = [`${vvProj}/engine/**`, `${vvProj}/laya-library/**`, `${vvProj}/config/**`, + `${vvProjSrc}/**`, `!${vvProjSrc}`, `!${vvProjSrc}/{game.js,manifest.json}`]; + } else if (platform === "hwgame") { + let hwProjSrc = path.join(releaseDir, config.hwInfo.projName); + delList = [`${hwProjSrc}/**`, `!${hwProjSrc}`, `!${hwProjSrc}/{game.js,manifest.json}`]; + } + // 保留平台配置文件 + if (config.keepPlatformFile) { + if (["wxgame", "qqgame", "Alipaygame", "bytedancegame"].includes(platform)) { + delList = delList.concat(`!${releaseDir}`, `!${releaseDir}/{game.js,game.json,project.config.json}`); + } else if (platform === "bdgame") { + delList = delList.concat(`!${releaseDir}`, `!${releaseDir}/{game.js,game.json,project.swan.json}`); + } else if (platform === "biligame") { + delList = delList.concat(`!${releaseDir}`, `!${releaseDir}/{game.js,game.json}`); + } else if (platform === "taobaominiapp") { // 特殊的,淘宝平台,仅删除确定为我们的文件 + // 删除 node_modules/layaengine/libs 下引擎文件,以及 node_modules/layaengine/laya.js 文件 + // 删除 pages/index 下除 game.js,game.json,game.axml 外所有文件 + // release/taobaominiapp/node_modules/layaengine/adapter.js 必更新 + // 删除最外层除 .tea .mini-ide node_modules pages app.acss app.js app.json mini.project.json package.json + delList = [`${releaseDir}/node_modules/layaengine/libs`, `${releaseDir}/node_modules/layaengine/laya.js`, + `${releaseDir}/**`, `!${releaseDir}`, `!${releaseDir}/.tea/**`, `!${releaseDir}/.mini-ide/**·`, + `!${releaseDir}/node_modules/**`, `!${releaseDir}/pages/**`, `!${releaseDir}/{app.acss,app.js,app.json,mini.project.json,package.json}`, + // `${releaseDir}/node_modules/layaengine`, `!${releaseDir}/node_modules/layaengine`, `!${releaseDir}/node_modules/layaengine/{adapter.js,index.js/package.json}`, + `${releaseDir}/pages/index/**`, `!${releaseDir}/pages/index`, `!${releaseDir}/pages/index/{game.js,game.json,game.axml}`]; + } else if (platform === "taobaowidget") { + delList = [`${releaseDir}/widget/component/**`, `!${releaseDir}/widget/component`, `!${releaseDir}/widget/component/{game.js,game.json,game.axml,game.acss,package.json}`]; + } + } + del(delList, { force: true }).then(paths => { + cb(); + }).catch((err) => { + throw err; + }) + } else cb(); +}); + +// copy bin文件到release文件夹 +gulp.task("copyFile", ["clearReleaseDir"], function () { + let baseCopyFilter = [`${workSpaceDir}/bin/**/*.*`, `!${workSpaceDir}/bin/indexmodule.html`, `!${workSpaceDir}/bin/import/*.*`]; + // 只拷贝index.js中引用的类库 + if (config.onlyIndexJS) { + baseCopyFilter = baseCopyFilter.concat(`!${workSpaceDir}/bin/libs/**/*.*`); + } + if (platform === "wxgame" && isOpendataProj) { // 开放域项目微信发布,仅拷贝用到的文件 + config.copyFilesFilter = [`${workSpaceDir}/bin/js/bundle.js`, `${workSpaceDir}/bin/index.js`, `${workSpaceDir}/bin/game.js`]; + if (config.projectType !== "as") { // 开放域精简类库 + config.copyFilesFilter.push(`${workSpaceDir}/bin/libs/laya.opendata.js`); + } + } else if (platform === "wxgame") { // 微信项目,不拷贝index.html,不拷贝百度bin目录中的文件 + config.copyFilesFilter = baseCopyFilter.concat([`!${workSpaceDir}/bin/{project.swan.json,swan-game-adapter.js}`]); + } else if (platform === "bdgame") { // 百度项目,不拷贝index.html,不拷贝微信bin目录中的文件 + config.copyFilesFilter = baseCopyFilter.concat([`!${workSpaceDir}/bin/{project.config.json,weapp-adapter.js}`]); + } else if (platform === "layame") { // layame项目,不拷贝js/libs文件夹,不拷贝index.js文件 + config.copyFilesFilter = baseCopyFilter.concat([`!${workSpaceDir}/bin/{js/**/*.*,libs/**/*.*,index.js,version.json}`]); + + } else { // 除微信、百度外,不拷贝微信、百度在bin目录中的文件 + config.copyFilesFilter = baseCopyFilter.concat([`!${workSpaceDir}/bin/{game.js,game.json,project.config.json,weapp-adapter.js,project.swan.json,swan-game-adapter.js}`]); + } + // bili/alipay/qq,不拷贝index.html + if (platform !== "web") { + config.copyFilesFilter = config.copyFilesFilter.concat([`!${workSpaceDir}/bin/index.html`]); + } + // 快游戏,需要新建一个快游戏项目,拷贝的只是项目的一部分,将文件先拷贝到文件夹的临时目录中去 + if ([...QUICKGAMELIST, "taobaominiapp", "taobaowidget"].includes(platform)) { + releaseDir = global.tempReleaseDir = path.join(releaseDir, "temprelease").replace(/\\/g, "/"); + } + if (config.exclude) { // 排除文件 + config.excludeFilter.forEach(function(item, index, list) { + releaseDir = releaseDir.replace(/\\/g, "/"); + config.excludeFilter[index] = item.replace(releaseDir, binPath); + }); + config.copyFilesFilter = config.copyFilesFilter.concat(config.excludeFilter); + } + global.releaseDir = releaseDir; + if (isDebugLayaMe) { + if (!toBuildPart('ui')) { + if(!fs.existsSync(releaseDir)) { + fs.mkdirSync(releaseDir); + } + return; + } + } + var stream = gulp.src(config.copyFilesFilter, { base: `${workSpaceDir}/bin` }); + return stream.pipe(gulp.dest(releaseDir)); +}); + +// 使用min版本引擎 +gulp.task("useMinJsLibs", ["copyFile"], function () { + if (!config.useMinJsLibs) { + return; + } + if (platform === "wxgame" && isOpendataProj) { // 开放域项目微信发布,拷贝文件时已经拷贝类库文件了 + return; + } + // 开放域项目,as语言,没有libs目录,mac系统报错 + let libs = path.join(workSpaceDir, "bin", "libs"); + if (!fs.existsSync(libs)) { + return; + } + if (platform === "layame") { + return; + } + // 分析index.js + let indexJSPath = path.join(releaseDir, "index.js"); + let indexJsContent = fs.readFileSync(indexJSPath, "utf8"); + let libsList = indexJsContent.match(/loadLib\(['"]libs\/[\w-./]+\.(js|wasm)['"]\)/g); + if (!libsList) { + return; + } + let + item, + libsName = "", + minLibsName = ""; + for (let i = 0, len = libsList.length; i < len; i++) { + item = libsList[i]; + libsName = item.match(/loadLib\(['"]libs\/([\w-./]+\.(js|wasm))['"]\)/); + minLibsName = `min/${libsName[1].replace(".js", ".min.js")}`; + indexJsContent = indexJsContent.replace(libsName[1], minLibsName); + } + fs.writeFileSync(indexJSPath, indexJsContent); +}); + +// copy libs中的js文件到release文件夹 +gulp.task("copyLibsJsFile", ["useMinJsLibs"], function () { + if (platform === "layame") { + return; + } + // 分析index.js + let indexJSPath = path.join(releaseDir, "index.js"); + let indexJsContent = fs.readFileSync(indexJSPath, "utf8"); + indexJsContent = indexJsContent.replace(/(loadLib\(['"]libs\/[\w-./]+\.wasm\.wasm['"]\))/g, "// $1"); + fs.writeFileSync(indexJSPath, indexJsContent, "utf8"); + if (!config.onlyIndexJS) { + return; + } + if (platform === "wxgame" && isOpendataProj) { // 开放域项目微信发布,拷贝文件时已经拷贝类库文件了 + return; + } + // 开放域项目,as语言,没有libs目录,mac系统报错 + let libs = path.join(workSpaceDir, "bin", "libs"); + if (!fs.existsSync(libs)) { + return; + } + let libsList = indexJsContent.match(/loadLib\(['"]libs\/[\w-./]+\.(js|wasm)['"]\)/g); + if (!libsList) { + libsList = []; + } + let + item, + libsName = "", + libsStr = ""; + for (let i = 0, len = libsList.length; i < len; i++) { + item = libsList[i]; + libsName = item.match(/loadLib\(['"]libs\/([\w-./]+\.(js|wasm))['"]\)/); + libsStr += libsStr ? `,${libsName[1]}` : libsName[1]; + } + // 发布web项目,如果使用了physics3D,默认拷贝runtime + if (platform === "web" && libsStr.includes("laya.physics3D")) { + if (config.useMinJsLibs) { + libsStr += ',min/laya.physics3D.runtime.min.js'; + } else { + libsStr += ',laya.physics3D.runtime.js'; + } + } + let copyLibsList = [`${workSpaceDir}/bin/libs/{${libsStr}}`]; + if (!libsStr.includes(",")) { + copyLibsList = [`${workSpaceDir}/bin/libs/${libsStr}`]; + } + var stream = gulp.src(copyLibsList, { base: `${workSpaceDir}/bin` }); + return stream.pipe(gulp.dest(releaseDir)); +}); + +gulp.task("fitwasm", ["copyLibsJsFile"], function() { + let + phy3dWasmJs = path.join(releaseDir, "libs", "laya.physics3D.wasm.js"), + phy3dWasmMinJs = path.join(releaseDir, "libs", "min", "laya.physics3D.wasm.min.js"); + let isPhy3dWasmJsExist = fs.existsSync(phy3dWasmJs); + let isPhy3dWasmMinJsExist = fs.existsSync(phy3dWasmMinJs); + if (!isPhy3dWasmJsExist && !isPhy3dWasmMinJsExist) { + return; + } + let phy3dWasmName = isPhy3dWasmJsExist ? phy3dWasmJs : phy3dWasmMinJs; + con = fs.readFileSync(phy3dWasmName, "utf8"); + if (isPhy3dWasmJsExist) { + con = con.replace(/laya\.physics3D\.wasm\.wasm/mg, "libs/laya.physics3D.wasm.wasm"); + } + if (isPhy3dWasmMinJsExist) { + con = con.replace(/laya\.physics3D\.wasm\.wasm/mg, "libs/min/laya.physics3D.wasm.wasm"); + } + fs.writeFileSync(phy3dWasmName, con, "utf8"); +}) + +gulp.task("copyPlatformLibsJsFile", ["fitwasm"], function () { + if (platform === "wxgame" && isOpendataProj) { // 开放域项目微信发布,拷贝文件时已经拷贝类库文件了 + return; + } + // 开放域项目,as语言,没有libs目录,mac系统报错 + let libs = path.join(workSpaceDir, "bin", "libs"); + if (!fs.existsSync(libs)) { + return; + } + if (platform === "web") { + return; + } + if (platform === "layame") { + return; + } + let platformLibName = ""; + switch (platform) { + case "wxgame": + platformLibName = "laya.wxmini.js"; + break; + case "qqgame": + platformLibName = "laya.qqmini.js"; + break; + case "bdgame": + platformLibName = "laya.bdmini.js"; + break; + case "Alipaygame": + platformLibName = "laya.Alipaymini.js"; + break; + case "biligame": + platformLibName = "laya.bilimini.js"; + break; + case "bytedancegame": + platformLibName = "laya.ttmini.js"; + break; + case "oppogame": + platformLibName = "laya.quickgamemini.js"; + break; + case "vivogame": + platformLibName = "laya.vvmini.js"; + break; + case "xmgame": + platformLibName = "laya.xmmini.js"; + break; + case "hwgame": + platformLibName = "laya.hwmini.js"; + break; + case "taobaominiapp": + platformLibName = "laya.tbmini.js"; + break; + case "taobaowidget": + platformLibName = "laya.tbpluginmini.js"; + break; + } + let copyPath = `${workSpaceDir}/bin/libs`; + if (config.useMinJsLibs) { + platformLibName = platformLibName.replace(".js", ".min.js"); + copyPath = path.join(copyPath, "min"); + } + let copyLibPath = path.join(copyPath, platformLibName); + var stream = gulp.src(copyLibPath, { base: `${workSpaceDir}/bin` }); + return stream.pipe(gulp.dest(releaseDir)); +}); + +// es6toes5 +gulp.task("es6toes5", platformCopyTask, function() { + if (config.es6toes5) { + process.env.BROWSERSLIST_IGNORE_OLD_DATA = true; + return gulp.src(`${releaseDir}/**/*.js`, { base: releaseDir }) + .pipe(babel({ + presets: ['@babel/env'], + compact: false // 1) 为规避500K限制,不能为"auto" 2) 为便于调试,并防止开发者误解已经经过压缩,调整为false + })) + .on('error', function (err) { + console.warn(err.toString()); + }) + .pipe(gulp.dest(releaseDir)); + } +}) + +// 压缩json +gulp.task("compressJson", ["es6toes5"], function () { + if (platform === "layame" && isDebugLayaMe) { + if (!toBuildPart('all')) { + return; + } + } + if (config.compressJson) { + return gulp.src(config.compressJsonFilter, { base: releaseDir }) + .pipe(jsonminify()) + .pipe(gulp.dest(releaseDir)); + } +}); + +// 压缩js +gulp.task("compressJs", ["compressJson"], function () { + let compressJsFilter = null; + if (platform === "layame" && isDebugLayaMe) { + if (!toBuildPart('all')) { + return; + } + } + if (!config.compressJs) { + if (config.es6toes5 && config.useMinJsLibs) { // 如果开启了es6toes5并使用了压缩版类库 + console.log("发布提示:\n 您当前开启了es6toes5并使用了压缩版类库,为了保证符合预期,脚本将对min文件夹下类库进行压缩"); + compressJsFilter = [`${releaseDir}/libs/min/**/*.js`]; + } + } else { + if (config.es6toes5 && config.useMinJsLibs) { // 如果开启了es6toes5并使用了压缩版类库 + console.log("发布提示:\n 您当前开启了es6toes5并使用了压缩版类库,为了保证符合预期,脚本将对min文件夹下类库进行压缩"); + compressJsFilter = config.compressJsFilter; + let index = compressJsFilter.indexOf(`!${releaseDir}/libs/min/**/*.js`) + if (index !== -1) { + compressJsFilter.splice(index, 1); + } + } else { + compressJsFilter = config.compressJsFilter; + } + } + if (!compressJsFilter) { + return; + } + + let options = { + mangle: { + keep_fnames:true + } + } + if (["taobaominiapp", "taobaowidget"].includes(platform)) { + options = { + mangle: { + keep_fnames:true, + // sequences: false, // 不使用逗号 + reserved: ["window"] + } + } + } + console.log("compressJsFilter: ", compressJsFilter); + return gulp.src(compressJsFilter, { base: releaseDir }) + .pipe(uglify(options)) + .on('error', function (err) { + console.warn(err.toString()); + }) + .pipe(gulp.dest(releaseDir)); +}); + +// 压缩png,jpg +gulp.task("compressImage", ["compressJs"], function () { + // if (platform === "layame") { + // return; + // } + if (platform === "layame" && isDebugLayaMe) { + if (!toBuildPart('ui')) { + return; + } + } + if (config.compressImage) { + return gulp.src(config.compressImageFilter, { base: releaseDir }) + .pipe(image({ + pngquant: true, //PNG优化工具 + optipng: false, //PNG优化工具 + zopflipng: true, //PNG优化工具 + jpegRecompress: false, //jpg优化工具 + mozjpeg: true, //jpg优化工具 + guetzli: false, //jpg优化工具 + gifsicle: false, //gif优化工具 + svgo: false, //SVG优化工具 + concurrent: 10, //并发线程数 + quiet: true //是否是静默方式 + // optipng: ['-i 1', '-strip all', '-fix', '-o7', '-force'], + // pngquant: ['--speed=1', '--force', 256], + // zopflipng: ['-y', '--lossy_8bit', '--lossy_transparent'], + // jpegRecompress: ['--strip', '--quality', 'medium', '--min', 40, '--max', 80], + // mozjpeg: ['-optimize', '-progressive'], + // guetzli: ['--quality', 85] + })) + .pipe(gulp.dest(releaseDir)); + } +}); + +// 生成版本管理信息 +gulp.task("version1", ["compressImage"], function () { + if (platform === "layame") { + return; + } + if (config.version) { + return gulp.src(config.versionFilter, { base: releaseDir }) + .pipe(rev()) + .pipe(gulp.dest(releaseDir)) + .pipe(revdel()) + .pipe(rev.manifest("version.json")) + .pipe(gulp.dest(releaseDir)); + } +}); + +// 更新index.js的hash值 +gulp.task("renameIndexJs", ["version1"], function (cb) { + if (platform === "layame") { + return cb(); + } + if (config.version) { + let versionPath = releaseDir + "/version.json"; + let versionCon = fs.readFileSync(versionPath, "utf8"); + versionCon = JSON.parse(versionCon); + let indexJSPath; + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + indexJSPath = releaseDir + "/" + indexJsStr; + + return new Promise((resolve, reject) => { + let srcList = [versionPath, indexJSPath]; + gulp.src(srcList) + .pipe(revCollector()) + .pipe(gulp.dest(releaseDir)); + setTimeout(resolve, 1500); + }).then(function() { + return new Promise(async function(resolve, reject) { + // index-xxx.js => index.js + let indexJsOrigin = path.join(releaseDir, "index.js") + fs.renameSync(indexJSPath, indexJsOrigin); + gulp.src(indexJsOrigin, { base: releaseDir }) + .pipe(rev()) + .pipe(gulp.dest(releaseDir)) + .pipe(revdel()) + .pipe(rev.manifest({ + path: versionPath, + merge: true + })) + .pipe(gulp.dest("./")); // 注意,这里不能是releaseDir (https://segmentfault.com/q/1010000002876613) + setTimeout(cb, 2000); + }) + }).catch(function(e) { + throw e; + }) + } else { + cb(); + } +}); +// 修改版本文件名 +gulp.task("renameVersionJson", ["renameIndexJs"] , function () { + + if (platform === "layame") { + return; + } + if (config.version) { + // 如果启用版本管理,则修改version文件名 + console.log('releaseDir', releaseDir); + let versionJsonJsOrigin = path.join(releaseDir, "version.json"); + let versionPath = versionJsonJsOrigin;// releaseDir + "/version.json"; + gulp.src(versionJsonJsOrigin, { base: releaseDir }) + .pipe(rev()) + .pipe(rev.manifest({ + path: versionPath, + merge: true + })) + .pipe(gulp.dest("./")) + .on('end', function () { + + let versionJsonJsOrigin = path.join(releaseDir, "version.json"); + let versionConStr = fs.readFileSync(versionJsonJsOrigin, "utf8"); + let versionCon = JSON.parse(versionConStr); + console.log('versionCon',versionCon ); + let renameVersionJson = path.join(releaseDir, versionCon['version.json']); + // fs.renameSync(versionJsonJsOrigin, renameVersionJson); + // 最后再删除versionjson + fs.writeFileSync(renameVersionJson, versionConStr, 'utf8'); + + + // 修改js/bundle.js里加载version.json路径 + var bundleJSPath = path.join(releaseDir, versionCon['js/bundle.js']) ; + bundleJSStr = fs.readFileSync(bundleJSPath, "utf8"); + bundleJSStr = bundleJSStr.replace('Laya.ResourceVersion.enable(\"version.json\"', `Laya.ResourceVersion.enable("${versionCon['version.json']}"`); + fs.writeFileSync(bundleJSPath, bundleJSStr, "utf8"); + + }); + + } +}); +// 替换index.html/game.js/main.js以及index.js里面的变化的文件名 +gulp.task("version2", ["renameVersionJson"], function () { + if (platform === "layame") { + return; + } + if (config.version) { + //替换index.html和index.js里面的文件名称 + let htmlPath = releaseDir + "/index.html"; + let versionPath = releaseDir + "/version.json"; + let gameJSPath = releaseDir + "/game.js"; + let mainJSPath = releaseDir + "/main.js"; + let indexJSPath; + let versionCon = fs.readFileSync(versionPath, "utf8"); + versionCon = JSON.parse(versionCon); + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + indexJSPath = releaseDir + "/" + indexJsStr; + // 替换config.packfileFullValue中的路径 + let packfileStr = JSON.stringify(config.packfileFullValue).replace(/\\\\/g, "/"); + let tempPackfile = `${workSpaceDir}/.laya/configTemp.json`; + fs.writeFileSync(tempPackfile, packfileStr, "utf8"); + + let srcList = [versionPath, indexJSPath, tempPackfile]; + if (fs.existsSync(htmlPath)) { + srcList.push(htmlPath); + } + if (fs.existsSync(gameJSPath)) { + srcList.push(gameJSPath); + } + if (fs.existsSync(mainJSPath)) { + srcList.push(mainJSPath); + } + return gulp.src(srcList) + .pipe(revCollector()) + .pipe(gulp.dest(releaseDir)); + } +}); + +// 筛选4M包 +gulp.task("packfile", platformTask, function() { + if (platform === "layame") { + return; + } + let taobaoFolders = ""; + switch (platform) { + case "taobaominiapp": + taobaoFolders = "pages/index"; + break; + case "taobaowidget": + taobaoFolders = "widget/component"; + break; + default: + taobaoFolders = "quickgame"; + } + if (config.version) { + releaseDir = releaseDir.replace("temprelease", taobaoFolders); + // 从release目录取得带有版本号的目录 + let tempPackfile = `${workSpaceDir}/.laya/configTemp.json`; + let releasePackfile = `${releaseDir}/configTemp.json`; + let packfileStr = fs.readFileSync(releasePackfile, "utf8"); + config.packfileFullValue = JSON.parse(packfileStr); + // 删掉临时目录 + fs.unlinkSync(tempPackfile); + fs.unlinkSync(releasePackfile); + } + if (["taobaominiapp", "taobaowidget"].includes(platform)) { + releaseDir = releaseDir.replace("/temprelease", "").replace(`/${taobaoFolders}`, ""); + for (let len = config.packfileFullValue.length, i = 0; i < len; i++) { + config.packfileFullValue[i] = config.packfileFullValue[i].replace("temprelease", ""); + } + } + if (config.packfile) { // 提取本地包(文件列表形式) + return gulp.src(config.packfileFullValue, { base: releaseDir }) + .pipe(gulp.dest(config.packfileTargetValue || releaseDir + "_pack")); + } + if (platform === "layame") { + return; + } + if (config.version) { + let versionJsonJsOrigin = path.join(releaseDir, "version.json"); + fs.unlinkSync(versionJsonJsOrigin); + } +}); +// 起始任务 +gulp.task("publish", ["packfile"] , function () { + console.log("All tasks completed!"); +}); \ No newline at end of file diff --git a/examples/layaair/frontend/.laya/publish_alipaygame.js b/examples/layaair/frontend/.laya/publish_alipaygame.js new file mode 100644 index 0000000..2b7acb3 --- /dev/null +++ b/examples/layaair/frontend/.laya/publish_alipaygame.js @@ -0,0 +1,117 @@ +// v1.8.0 +const ideModuleDir = global.ideModuleDir; +const workSpaceDir = global.workSpaceDir; + +//引用插件模块 +const gulp = require(ideModuleDir + "gulp"); +const fs = require("fs"); +const path = require("path"); +const revCollector = require(ideModuleDir + 'gulp-rev-collector'); + +let copyLibsTask = ["copyPlatformLibsJsFile"]; +let versiontask = ["version2"]; + +let + config, + releaseDir; +let versionCon; // 版本管理version.json +let commandSuffix, + layarepublicPath; + +gulp.task("preCreate_Alipay", copyLibsTask, function() { + releaseDir = global.releaseDir; + config = global.config; + commandSuffix = global.commandSuffix; + layarepublicPath = global.layarepublicPath; +}); + +gulp.task("copyPlatformFile_Alipay", ["preCreate_Alipay"], function() { + let adapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "Alipayfiles"); + let hasPublishPlatform = + fs.existsSync(path.join(releaseDir, "game.js")) && + fs.existsSync(path.join(releaseDir, "game.json")) && + fs.existsSync(path.join(releaseDir, "project.config.json")); + let copyLibsList; + if (hasPublishPlatform) { + copyLibsList = [`${adapterPath}/my-adapter.js`]; + } else { + copyLibsList = [`${adapterPath}/*.*`]; + } + var stream = gulp.src(copyLibsList); + return stream.pipe(gulp.dest(releaseDir)); +}); + +gulp.task("modifyFile_Alipay", versiontask, function() { + // 修改game.json文件 + let gameJsonPath = path.join(releaseDir, "game.json"); + let content = fs.readFileSync(gameJsonPath, "utf8"); + let conJson = JSON.parse(content); + conJson.screenOrientation = config.AlipayInfo.orientation; + content = JSON.stringify(conJson, null, 4); + fs.writeFileSync(gameJsonPath, content, "utf8"); + + // 修改game.js + let filePath = path.join(releaseDir, "game.js"); + let fileContent = fs.existsSync(filePath) && fs.readFileSync(filePath, "utf8"); + let reWriteMainJs = !fs.existsSync(filePath) || !fileContent.includes("Alipaymini"); + if (reWriteMainJs) { + fileContent = `require("./my-adapter.js"); +require("./libs/laya.Alipaymini.js");\nrequire("./index.js");`; + fs.writeFileSync(filePath, fileContent, "utf8"); + } + + if (config.version || config.enableVersion) { + let versionPath = releaseDir + "/version.json"; + versionCon = fs.readFileSync(versionPath, "utf8"); + versionCon = JSON.parse(versionCon); + } + // 修改index.js + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + let indexFilePath = path.join(releaseDir, indexJsStr); + if (!fs.existsSync(indexFilePath)) { + return; + } + let indexFileContent = fs.readFileSync(indexFilePath, "utf8"); + indexFileContent = indexFileContent.replace(/loadLib(\(['"])/gm, "require$1./"); + fs.writeFileSync(indexFilePath, indexFileContent, "utf8"); +}) + +gulp.task("modifyMinJs_Alipay", ["modifyFile_Alipay"], function() { + // 如果保留了平台文件,如果同时取消使用min类库,就会出现文件引用不正确的问题 + if (config.keepPlatformFile) { + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/min\/laya(-[\w\d]+)?\.Alipaymini\.min\.js/gm, "laya.Alipaymini.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + } + if (!config.useMinJsLibs) { + return; + } + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/(min\/)?laya(-[\w\d]+)?\.Alipaymini(\.min)?\.js/gm, "min/laya.Alipaymini.min.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); +}); + +gulp.task("version_Alipay", ["modifyMinJs_Alipay"], function () { + // 如果保留了平台文件,如果同时开启版本管理,就会出现文件引用不正确的问题 + if (config.keepPlatformFile) { + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/laya(-[\w\d]+)?\.Alipaymini/gm, "laya.Alipaymini"); + content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + } + if (config.version) { + let versionPath = releaseDir + "/version.json"; + let gameJSPath = releaseDir + "/game.js"; + let srcList = [versionPath, gameJSPath]; + return gulp.src(srcList) + .pipe(revCollector()) + .pipe(gulp.dest(releaseDir)); + } +}); + +gulp.task("buildAlipayProj", ["version_Alipay"], function() { + console.log("all tasks completed"); +}); \ No newline at end of file diff --git a/examples/layaair/frontend/.laya/publish_bdgame.js b/examples/layaair/frontend/.laya/publish_bdgame.js new file mode 100644 index 0000000..160b67a --- /dev/null +++ b/examples/layaair/frontend/.laya/publish_bdgame.js @@ -0,0 +1,163 @@ +// v1.8.0 +const ideModuleDir = global.ideModuleDir; +const workSpaceDir = global.workSpaceDir; + +//引用插件模块 +const gulp = require(ideModuleDir + "gulp"); +const fs = require("fs"); +const path = require("path"); +const revCollector = require(ideModuleDir + 'gulp-rev-collector'); + +let copyLibsTask = ["copyPlatformLibsJsFile"]; +let versiontask = ["version2"]; + +let + config, + releaseDir; +let versionCon; // 版本管理version.json +let commandSuffix, + layarepublicPath; + +gulp.task("preCreate_BD", copyLibsTask, function() { + releaseDir = global.releaseDir; + config = global.config; + commandSuffix = global.commandSuffix; + layarepublicPath = global.layarepublicPath; +}); + +gulp.task("copyPlatformFile_BD", ["preCreate_BD"], function() { + let adapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "bdfiles"); + // 如果新建项目时已经点击了"微信/百度小游戏bin目录快速调试",不再拷贝 + let hasPlatform = + fs.existsSync(path.join(workSpaceDir, "bin", "game.js")) && + fs.existsSync(path.join(workSpaceDir, "bin", "game.json")) && + fs.existsSync(path.join(workSpaceDir, "bin", "project.swan.json")); + let hasPublishPlatform = + fs.existsSync(path.join(releaseDir, "game.js")) && + fs.existsSync(path.join(releaseDir, "game.json")) && + fs.existsSync(path.join(releaseDir, "project.swan.json")); + let copyLibsList; + if (hasPlatform || hasPublishPlatform) { + copyLibsList = [`${adapterPath}/swan-game-adapter.js`]; + } else { + copyLibsList = [`${adapterPath}/*.*`]; + } + var stream = gulp.src(copyLibsList); + return stream.pipe(gulp.dest(releaseDir)); +}); + +gulp.task("modifyFile_BD", versiontask, function() { + // 修改game.json文件 + let gameJsonPath = path.join(releaseDir, "game.json"); + let content = fs.readFileSync(gameJsonPath, "utf8"); + let conJson = JSON.parse(content); + conJson.deviceOrientation = config.bdInfo.orientation; + content = JSON.stringify(conJson, null, 4); + fs.writeFileSync(gameJsonPath, content, "utf8"); + + if (config.version) { + let versionPath = releaseDir + "/version.json"; + versionCon = fs.readFileSync(versionPath, "utf8"); + versionCon = JSON.parse(versionCon); + } + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + // 百度小游戏项目,修改index.js + let filePath = path.join(releaseDir, indexJsStr); + if (!fs.existsSync(filePath)) { + return; + } + let fileContent = fs.readFileSync(filePath, "utf8"); + fileContent = fileContent.replace(/loadLib(\(['"])/gm, "require$1./"); + fs.writeFileSync(filePath, fileContent, "utf8"); +}); + +// 开放域的情况下,合并game.js和index.js,并删除game.js +gulp.task("openData_BD", ["modifyFile_BD"], function (cb) { + if (config.openDataZone) { + let versionCon; + if (config.version) { + let versionPath = releaseDir + "/version.json"; + versionCon = fs.readFileSync(versionPath, "utf8"); + versionCon = JSON.parse(versionCon); + } + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + let indexPath = path.join(releaseDir, indexJsStr); + let indexjs = readFile(indexPath); + let gamejs = readFile(releaseDir + "/game.js"); + if (gamejs && indexjs) { + gamejs = gamejs.replace(`require("index.js")`, indexjs); + fs.writeFileSync(indexPath, gamejs, 'utf-8'); + } + return cb(); + } + cb(); +}); + +function readFile(path) { + if (fs.existsSync(path)) { + return fs.readFileSync(path, "utf-8"); + } + return null; +} + +gulp.task("modifyMinJs_BD", ["openData_BD"], function() { + // 如果保留了平台文件,如果同时取消使用min类库,就会出现文件引用不正确的问题 + if (config.keepPlatformFile) { + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/min\/laya(-[\w\d]+)?\.bdmini\.min\.js/gm, "laya.bdmini.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + } + if (!config.useMinJsLibs) { + return; + } + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/(min\/)?laya(-[\w\d]+)?\.bdmini(\.min)?\.js/gm, "min/laya.bdmini.min.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); +}); + +gulp.task("version_BD", ["modifyMinJs_BD"], function() { + // 如果保留了平台文件,如果同时开启版本管理,就会出现文件引用不正确的问题 + if (config.keepPlatformFile) { + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/laya(-[\w\d]+)?\.bdmini/gm, "laya.bdmini"); + content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + } + if (config.version) { + let versionPath = releaseDir + "/version.json"; + let gameJSPath = releaseDir + "/game.js"; + let srcList = [versionPath, gameJSPath]; + return gulp.src(srcList) + .pipe(revCollector()) + .pipe(gulp.dest(releaseDir)); + } +}); + +gulp.task("optimizeOpen_BD", ["version_BD"], function(cb) { + let bdOptimize = config.bdOptimize; + if (!bdOptimize || !bdOptimize.useOptimizeOpen) { + return cb(); + } + // 首屏加载优化(秒开),修改game.json + let filePath = path.join(releaseDir, "game.json"); + if (!fs.existsSync(filePath)) { + return cb(); + } + let fileContent = fs.readFileSync(filePath, "utf8"); + let fileConObj = JSON.parse(fileContent); + if (bdOptimize.preloadRes) { + fileConObj.preloadResources = bdOptimize.preloadResList; + } else { + delete fileConObj.preloadResources; + } + + fs.writeFileSync(filePath, JSON.stringify(fileConObj, null, 4), "utf8"); + return cb(); +}); + +gulp.task("buildBDProj", ["optimizeOpen_BD"], function() { + console.log("all tasks completed"); +}); \ No newline at end of file diff --git a/examples/layaair/frontend/.laya/publish_biligame.js b/examples/layaair/frontend/.laya/publish_biligame.js new file mode 100644 index 0000000..ea3fe5a --- /dev/null +++ b/examples/layaair/frontend/.laya/publish_biligame.js @@ -0,0 +1,106 @@ +// v1.8.0 +const ideModuleDir = global.ideModuleDir; +const workSpaceDir = global.workSpaceDir; + +//引用插件模块 +const gulp = require(ideModuleDir + "gulp"); +const fs = require("fs"); +const path = require("path"); +const revCollector = require(ideModuleDir + 'gulp-rev-collector'); + +let copyLibsTask = ["copyPlatformLibsJsFile"]; +let versiontask = ["version2"]; + +let + config, + releaseDir; +let versionCon; // 版本管理version.json +let commandSuffix, + layarepublicPath; + +gulp.task("preCreate_Bili", copyLibsTask, function() { + releaseDir = global.releaseDir; + config = global.config; + commandSuffix = global.commandSuffix; + layarepublicPath = global.layarepublicPath; +}); + +gulp.task("copyPlatformFile_Bili", ["preCreate_Bili"], function() { + let adapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "bilifiles"); + let hasPublishPlatform = + fs.existsSync(path.join(releaseDir, "game.js")) && + fs.existsSync(path.join(releaseDir, "game.json")); + let copyLibsList; + if (hasPublishPlatform) { + copyLibsList = [`${adapterPath}/weapp-adapter.js`]; + } else { + copyLibsList = [`${adapterPath}/*.*`]; + } + var stream = gulp.src(copyLibsList); + return stream.pipe(gulp.dest(releaseDir)); +}); + +gulp.task("modifyFile_Bili", versiontask, function() { + // 修改game.json文件 + let gameJsonPath = path.join(releaseDir, "game.json"); + let content = fs.readFileSync(gameJsonPath, "utf8"); + let conJson = JSON.parse(content); + conJson.deviceOrientation = config.biliInfo.orientation; + content = JSON.stringify(conJson, null, 4); + fs.writeFileSync(gameJsonPath, content, "utf8"); + + if (config.version) { + let versionPath = releaseDir + "/version.json"; + versionCon = fs.readFileSync(versionPath, "utf8"); + versionCon = JSON.parse(versionCon); + } + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + // bili小游戏项目,修改index.js + let filePath = path.join(releaseDir, indexJsStr); + if (!fs.existsSync(filePath)) { + return; + } + let fileContent = fs.readFileSync(filePath, "utf8"); + fileContent = fileContent.replace(/loadLib(\(['"])/gm, "require$1./"); + fs.writeFileSync(filePath, fileContent, "utf8"); +}); + +gulp.task("modifyMinJs_Bili", ["modifyFile_Bili"], function() { + // 如果保留了平台文件,如果同时取消使用min类库,就会出现文件引用不正确的问题 + if (config.keepPlatformFile) { + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/min\/laya(-[\w\d]+)?\.bilimini\.min\.js/gm, "laya.bilimini.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + } + if (!config.useMinJsLibs) { + return; + } + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/(min\/)?laya(-[\w\d]+)?\.bilimini(\.min)?\.js/gm, "min/laya.bilimini.min.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); +}); + +gulp.task("version_Bili", ["modifyMinJs_Bili"], function() { + // 如果保留了平台文件,如果同时开启版本管理,就会出现文件引用不正确的问题 + if (config.keepPlatformFile) { + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/laya(-[\w\d]+)?\.bilimini/gm, "laya.bilimini"); + content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + } + if (config.version) { + let versionPath = releaseDir + "/version.json"; + let gameJSPath = releaseDir + "/game.js"; + let srcList = [versionPath, gameJSPath]; + return gulp.src(srcList) + .pipe(revCollector()) + .pipe(gulp.dest(releaseDir)); + } +}); + +gulp.task("buildBiliProj", ["version_Bili"], function() { + console.log("all tasks completed"); +}); \ No newline at end of file diff --git a/examples/layaair/frontend/.laya/publish_bytedancegame.js b/examples/layaair/frontend/.laya/publish_bytedancegame.js new file mode 100644 index 0000000..42ef6d8 --- /dev/null +++ b/examples/layaair/frontend/.laya/publish_bytedancegame.js @@ -0,0 +1,325 @@ +// v1.1.3 +const ideModuleDir = global.ideModuleDir; +const workSpaceDir = global.workSpaceDir; + +//引用插件模块 +const gulp = require(ideModuleDir + "gulp"); +const fs = require("fs"); +const path = require("path"); +const del = require(ideModuleDir + "del"); +const revCollector = require(ideModuleDir + 'gulp-rev-collector'); +const { getEngineVersion, getFileMd5, canUsePluginEngine } = require("./pub_utils"); + +const provider = "tt13aa65178c90228a"; +const minPluginVersion = "2.7.0"; +let fullRemoteEngineList = ["laya.core.js", "laya.filter.js", "laya.ani.js", "laya.tiledmap.js", "laya.d3.js", "laya.html.js", "laya.particle.js", "laya.ui.js", "laya.webgl.js", "laya.filter.js", "laya.d3Plugin.js"]; +let copyLibsTask = ["copyPlatformLibsJsFile"]; +let versiontask = ["version2"]; + +let + config, + releaseDir; +let versionCon; // 版本管理version.json +let commandSuffix, + layarepublicPath; + +gulp.task("preCreate_ByteDance", copyLibsTask, function() { + releaseDir = global.releaseDir; + config = global.config; + commandSuffix = global.commandSuffix; + layarepublicPath = global.layarepublicPath; + + if (config.useMinJsLibs) { + fullRemoteEngineList = fullRemoteEngineList.map((item, index) => { + return item.replace(".js", ".min.js"); + }) + } +}); + +gulp.task("copyPlatformFile_ByteDance", ["preCreate_ByteDance"], function() { + let adapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "bytefiles"); + let hasPublishPlatform = + fs.existsSync(path.join(releaseDir, "game.js")) && + fs.existsSync(path.join(releaseDir, "game.json")) && + fs.existsSync(path.join(releaseDir, "project.config.json")); + let copyLibsList; + if (hasPublishPlatform) { + copyLibsList = [`${adapterPath}/microgame-adapter.js`]; + } else { + copyLibsList = [`${adapterPath}/*.*`]; + } + var stream = gulp.src(copyLibsList); + return stream.pipe(gulp.dest(releaseDir)); +}); + +gulp.task("modifyFile_ByteDance", versiontask, function() { + // 修改game.json文件 + let gameJsonPath = path.join(releaseDir, "game.json"); + let content = fs.readFileSync(gameJsonPath, "utf8"); + let conJson = JSON.parse(content); + conJson.deviceOrientation = config.bytedanceInfo.orientation; + if (config.bytedanceInfo.subpack) { // 分包 + conJson.subPackages = config.bytedanceSubpack; + + // 检测分包目录是否有入口文件 + console.log('检查分包文件...'); + if (conJson.subPackages) { + for(let i = 0; i < conJson.subPackages.length; i ++) { + let conf = conJson.subPackages[i]; + if (conf.root) { + let rootPath = path.join(releaseDir, conf.root); + if (!fs.existsSync(rootPath)) { + + throw new Error(`分包文件/目录 ${rootPath} 不存在!`); + } + let jsIndex = rootPath.lastIndexOf('.js'); + let jsPath = rootPath; + if (jsIndex < 0 || jsIndex != rootPath.length - 3) { + jsPath = path.join(rootPath, 'game.js'); + } + if (!fs.existsSync(jsPath)) { + + throw new Error(`分包文件/目录 ${jsPath} 不存在!`); + } + } + } + } + } else { + delete conJson.subPackages; + } + content = JSON.stringify(conJson, null, 4); + fs.writeFileSync(gameJsonPath, content, "utf8"); + + if (config.version || config.enableVersion) { + let versionPath = releaseDir + "/version.json"; + versionCon = fs.readFileSync(versionPath, "utf8"); + versionCon = JSON.parse(versionCon); + } + // 修改index.js + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + let indexFilePath = path.join(releaseDir, indexJsStr); + if (!fs.existsSync(indexFilePath)) { + return; + } + let indexFileContent = fs.readFileSync(indexFilePath, "utf8"); + indexFileContent = indexFileContent.replace(/loadLib(\(['"])/gm, "require$1./"); + fs.writeFileSync(indexFilePath, indexFileContent, "utf8"); +}) + +gulp.task("modifyMinJs_ByteDance", ["modifyFile_ByteDance"], function() { + // 如果保留了平台文件,如果同时取消使用min类库,就会出现文件引用不正确的问题 + if (config.keepPlatformFile) { + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/min\/laya(-[\w\d]+)?\.ttmini\.min\.js/gm, "laya.ttmini.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + } + if (!config.useMinJsLibs) { + return; + } + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/(min\/)?laya(-[\w\d]+)?\.ttmini(\.min)?\.js/gm, "min/laya.ttmini.min.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); +}); + +gulp.task("version_ByteDance", ["modifyMinJs_ByteDance"], function() { + // 如果保留了平台文件,如果同时开启版本管理,就会出现文件引用不正确的问题 + if (config.keepPlatformFile) { + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/laya(-[\w\d]+)?\.ttmini/gm, "laya.ttmini"); + content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + } + if (config.version) { + let versionPath = releaseDir + "/version.json"; + let gameJSPath = releaseDir + "/game.js"; + let srcList = [versionPath, gameJSPath]; + return gulp.src(srcList) + .pipe(revCollector()) + .pipe(gulp.dest(releaseDir)); + } +}); + +gulp.task("pluginEngin_ByteDance", ["version_ByteDance"], function(cb) { + if (!config.uesEnginePlugin) { // 没有使用引擎插件,还是像以前一样发布 + let gameJsonPath = path.join(releaseDir, "game.json"); + let gameJsonContent = fs.readFileSync(gameJsonPath, "utf8"); + let conJson = JSON.parse(gameJsonContent); + if (conJson.plugins) { + delete conJson.plugins; + gameJsonContent = JSON.stringify(conJson, null, 4); + fs.writeFileSync(gameJsonPath, gameJsonContent, "utf8"); + + let gameJsPath = path.join(releaseDir, "game.js"); + let gameJscontent = fs.readFileSync(gameJsPath, "utf8"); + gameJscontent = gameJscontent.replace(/requirePlugin\("[\w\/\.]+"\);?\n?/mg, ""); + fs.writeFileSync(gameJsPath, gameJscontent, "utf8"); + } + return cb(); + } + if (config.version) { + let versionPath = releaseDir + "/version.json"; + versionCon = fs.readFileSync(versionPath, "utf8"); + versionCon = JSON.parse(versionCon); + } + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + + // 获取version等信息 + let coreLibPath = path.join(workSpaceDir, "bin", "libs", "laya.core.js"); + let isHasCoreLib = fs.existsSync(coreLibPath); + let isOldAsProj = fs.existsSync(`${workSpaceDir}/asconfig.json`) && !isHasCoreLib; + let isNewTsProj = fs.existsSync(`${workSpaceDir}/src/tsconfig.json`) && !isHasCoreLib; + let EngineVersion = getEngineVersion(); + if (!EngineVersion) { + throw new Error(`读取引擎版本号失败,请于服务提供商联系!`); + } + if (!EngineVersion || EngineVersion.includes("beta") || !canUsePluginEngine(EngineVersion, minPluginVersion)) { + throw new Error(`该版本引擎无法使用引擎插件功能(engineVersion: ${EngineVersion})`); + } + console.log(`通过版本号检查: ${EngineVersion}`); + // 使用引擎插件 + let localUseEngineList = []; + let copyEnginePathList; + new Promise(function(resolve, reject) { + console.log(`修改game.js和game.json`); + // 1) 修改game.js和game.json + // 修改game.js + let gameJsPath = path.join(releaseDir, "game.js"); + let platformJs = config.useMinJsLibs ? `require("./libs/min/laya.ttmini.min.js");` : `require("./libs/laya.ttmini.js");`; + let gameJscontent = `require("microgame-adapter.js");\n${platformJs}\nrequirePlugin('layaPlugin');\nwindow.loadLib = require;\nrequire("./${indexJsStr}");`; + fs.writeFileSync(gameJsPath, gameJscontent, "utf8"); + // 修改game.json,使其支持引擎插件 + let gameJsonPath = path.join(releaseDir, "game.json"); + let gameJsonContent = fs.readFileSync(gameJsonPath, "utf8"); + let conJson = JSON.parse(gameJsonContent); + conJson.plugins = { + "layaPlugin": { + "version": EngineVersion, + "provider": provider, + "path": "laya-libs" + } + } + gameJsonContent = JSON.stringify(conJson, null, 4); + fs.writeFileSync(gameJsonPath, gameJsonContent, "utf8"); + resolve(); + }).then(function() { + return new Promise(function(resolve, reject) { + console.log(`确定用到的插件引擎`); + // 2) 确定用到了那些插件引擎,并将插件引擎从index.js的引用中去掉 + let indexJsPath = path.join(releaseDir, indexJsStr); + let indexJsCon = fs.readFileSync(indexJsPath, "utf8"); + let item, fullRequireItem; + for (let i = 0, len = fullRemoteEngineList.length; i < len; i++) { + item = fullRemoteEngineList[i]; + fullRequireItem = config.useMinJsLibs ? `require("./libs/min/${item}")` : `require("./libs/${item}")`; + if (indexJsCon.includes(fullRequireItem)) { + let _item = item.replace(".min.js", ".js"), _minItem = item; + localUseEngineList.push(_item); + indexJsCon = indexJsCon.replace(fullRequireItem + ";", "").replace(fullRequireItem + ",", "").replace(fullRequireItem, ""); + // 如果引用了压缩的类库,将其重命名为未压缩的类库,并拷贝到libs中 + if (config.useMinJsLibs) { + let oldMinlibPath = path.join(releaseDir, "libs", "min", _minItem); + let newMinlibPath = path.join(releaseDir, "libs", "min", _item); + let newlibPath = path.join(releaseDir, "libs", _item); + fs.renameSync(oldMinlibPath, newMinlibPath); + // fs.copyFileSync(newlibPath, newMinlibPath); + let con = fs.readFileSync(newMinlibPath, "utf8"); + fs.writeFileSync(newlibPath, con, "utf8"); + fs.unlinkSync(newMinlibPath); + } + } + } + if (isOldAsProj || isNewTsProj) { // 如果as||ts_new语言,开发者将laya.js也写入index.js中了,将其删掉 + fullRequireItem = `require("./laya.js")`; + if (indexJsCon.includes(fullRequireItem)) { + indexJsCon = indexJsCon.replace(fullRequireItem + ";", "").replace(fullRequireItem + ",", "").replace(fullRequireItem, ""); + } + } + fs.writeFileSync(indexJsPath, indexJsCon, "utf8"); + // ts/js再次修改game.js,仅引用使用到的类库 + // as||ts_new因为本地只有laya.js,无法仅引用使用到的类库 + if (!isOldAsProj && !isNewTsProj) { + let pluginCon = ""; + localUseEngineList.forEach(function(item) { + pluginCon += `requirePlugin("layaPlugin/${item}");\n`; + }); + let gameJsPath = path.join(releaseDir, "game.js"); + let gameJsCon = fs.readFileSync(gameJsPath, "utf8"); + gameJsCon = gameJsCon.replace(`requirePlugin('layaPlugin');`, pluginCon); + fs.writeFileSync(gameJsPath, gameJsCon, "utf8"); + } + resolve(); + }); + }).then(function() { + return new Promise(function(resolve, reject) { + console.log(`将本地的引擎插件移动到laya-libs中`); + // 3) 将本地的引擎插件移动到laya-libs中 + let libsPath = /** config.useMinJsLibs ? `${releaseDir}/libs/min` : */`${releaseDir}/libs`; + copyEnginePathList = [`${libsPath}/{${localUseEngineList.join(",")}}`]; + if (isOldAsProj || isNewTsProj) { // 单独拷贝laya.js + copyEnginePathList = [`${releaseDir}/laya.js`]; + } + gulp.src(copyEnginePathList).pipe(gulp.dest(`${releaseDir}/laya-libs`)); + setTimeout(resolve, 500); + }); + }).then(function() { + return new Promise(function(resolve, reject) { + console.log(`将libs中的本地引擎插件删掉`); + // 4) 将libs中的本地引擎插件删掉 + del(copyEnginePathList, { force: true }).then(resolve); + }); + }).then(function() { + return new Promise(async function(resolve, reject) { + console.log(`完善引擎插件目录`); + // 5) 引擎插件目录laya-libs中还需要新建几个文件,使该目录能够使用 + if (isOldAsProj || isNewTsProj) { // 单独拷贝laya.js + localUseEngineList.push("laya.js"); + } + let + layalibsPath = path.join(releaseDir, "laya-libs"), + engineIndex = path.join(layalibsPath, "index.js"), + engineplugin = path.join(layalibsPath, "plugin.json"), + enginesignature = path.join(layalibsPath, "signature.json"); + // index.js + if (!fs.existsSync(layalibsPath)) { + throw new Error("引擎插件目录创建失败,请与服务提供商联系!"); + } + let indexCon = ""; + localUseEngineList.forEach(function(item) { + indexCon += `require("./${item}");\n`; + }); + fs.writeFileSync(engineIndex, indexCon, "utf8"); + // plugin.json + let pluginCon = {"main": "index.js"}; + fs.writeFileSync(engineplugin, JSON.stringify(pluginCon, null, 4), "utf8"); + // signature.json,目前平台方将其作为保留用途,不会做插件的md5校验;IDE仍将生成md5 + let signatureCon = { + "provider": provider, + "signature": [] + }; + localUseEngineList.unshift("index.js"); + let fileName, md5Str; + for (let i = 0, len = localUseEngineList.length; i < len; i++) { + fileName = localUseEngineList[i]; + let md5Str = await getFileMd5(path.join(releaseDir, "laya-libs", fileName)); + signatureCon.signature.push({ + "path": fileName, + "md5": md5Str + }); + } + fs.writeFileSync(enginesignature, JSON.stringify(signatureCon, null, 4), "utf8"); + resolve(); + }); + }) + .then(function() { + cb(); + }).catch(function(e) { + throw e; + }) +}); + +gulp.task("buildByteDanceProj", ["pluginEngin_ByteDance"], function() { + console.log("all tasks completed"); +}); \ No newline at end of file diff --git a/examples/layaair/frontend/.laya/publish_hwgame.js b/examples/layaair/frontend/.laya/publish_hwgame.js new file mode 100644 index 0000000..5f9143d --- /dev/null +++ b/examples/layaair/frontend/.laya/publish_hwgame.js @@ -0,0 +1,663 @@ +// v1.0.7 +const ideModuleDir = global.ideModuleDir; +const workSpaceDir = global.workSpaceDir; + +//引用插件模块 +const gulp = require(ideModuleDir + "gulp"); +const fs = require("fs"); +const path = require("path"); +const https = require("https"); +const childProcess = require("child_process"); +const del = require(ideModuleDir + "del"); +const revCollector = require(ideModuleDir + 'gulp-rev-collector'); +const iconv = require(ideModuleDir + "iconv-lite"); +const request = require(ideModuleDir + "request"); + +let copyLibsTask = ["copyPlatformLibsJsFile"]; +let versiontask = ["version2"]; + +let + config, + releaseDir, + toolkitPath, + tempReleaseDir, // 华为临时拷贝目录 + projDir; // 华为快游戏工程目录 +let versionCon; // 版本管理version.json +let commandSuffix, + adbPath, + opensslPath, + layarepublicPath; +let isDevices = false; + +// 创建华为项目前,拷贝华为引擎库、修改index.js +gulp.task("preCreate_HW", copyLibsTask, function() { + releaseDir = global.releaseDir; + config = global.config; + commandSuffix = global.commandSuffix; + adbPath = global.adbPath; + opensslPath = global.opensslPath; + layarepublicPath = global.layarepublicPath; + tempReleaseDir = global.tempReleaseDir; + + toolkitPath = path.join(layarepublicPath, "pub_huawei"); +}); + +gulp.task("copyPlatformFile_HW", ["preCreate_HW"], function() { + let hwAdapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "hwfiles"); + let copyLibsList = [`${hwAdapterPath}/**/*.*`]; + var stream = gulp.src(copyLibsList); + return stream.pipe(gulp.dest(tempReleaseDir)); +}); + +// 新建华为项目-华为项目与其他项目不同,需要安装华为 quickgame node_modules,并打包成.rpk文件 +gulp.task("installModules_HW", versiontask, function() { + releaseDir = path.dirname(releaseDir); + projDir = path.join(releaseDir, config.hwInfo.projName); + // 如果IDE里对应华为包已经install node_modules了,忽略这一步 + if (fs.existsSync(path.join(toolkitPath, "node_modules"))) { + return; + } + // 安装华为 quickgame node_modules + return new Promise((resolve, reject) => { + console.log("开始安装华为 toolkit node_modules,请耐心等待..."); + let cmd = `npm${commandSuffix}`; + let args = ["install"]; + let opts = { + cwd: toolkitPath, + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + // reject(); + }); + + cp.on('close', (code) => { + console.log(`子进程退出码:${code}`); + resolve(); + }); + }); +}); + +// 拷贝文件到华为快游戏 +gulp.task("copyFileToProj_HW", ["installModules_HW"], function() { + // 将临时文件夹中的文件,拷贝到项目中去 + let originalDir = `${tempReleaseDir}/**/*.*`; + let stream = gulp.src(originalDir); + return stream.pipe(gulp.dest(path.join(projDir))); +}); + +// 拷贝icon到华为快游戏 +gulp.task("copyIconToProj_HW", ["copyFileToProj_HW"], function() { + let originalDir = config.hwInfo.icon; + let stream = gulp.src(originalDir); + return stream.pipe(gulp.dest(path.join(projDir))); +}); + +// 清除华为快游戏临时目录 +gulp.task("clearTempDir_HW", ["copyIconToProj_HW"], function() { + // 删掉临时目录 + return del([tempReleaseDir], { force: true }); +}); + +// 生成release签名(私钥文件 private.pem 和证书文件 certificate.pem ) +gulp.task("generateSign_HW", ["clearTempDir_HW"], function() { + if (!config.hwSign.generateSign) { + return; + } + // https://doc.quickapp.cn/tools/compiling-tools.html + return new Promise((resolve, reject) => { + let cmd = `${opensslPath}`; + let args = ["req", "-newkey", "rsa:2048", "-nodes", "-keyout", "private.pem", + "-x509", "-days", "3650", "-out", "certificate.pem"]; + let opts = { + cwd: projDir, + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + data += ""; + if (data.includes("Country Name")) { + cp.stdin.write(`${config.hwSign.countryName}\n`); + console.log(`Country Name: ${config.hwSign.countryName}`); + } else if (data.includes("Province Name")) { + cp.stdin.write(`${config.hwSign.provinceName}\n`); + console.log(`Province Name: ${config.hwSign.provinceName}`); + } else if (data.includes("Locality Name")) { + cp.stdin.write(`${config.hwSign.localityName}\n`); + console.log(`Locality Name: ${config.hwSign.localityName}`); + } else if (data.includes("Organization Name")) { + cp.stdin.write(`${config.hwSign.orgName}\n`); + console.log(`Organization Name: ${config.hwSign.orgName}`); + } else if (data.includes("Organizational Unit Name")) { + cp.stdin.write(`${config.hwSign.orgUnitName}\n`); + console.log(`Organizational Unit Name: ${config.hwSign.orgUnitName}`); + } else if (data.includes("Common Name")) { + cp.stdin.write(`${config.hwSign.commonName}\n`); + console.log(`Common Name: ${config.hwSign.commonName}`); + } else if (data.includes("Email Address")) { + cp.stdin.write(`${config.hwSign.emailAddr}\n`); + console.log(`Email Address: ${config.hwSign.emailAddr}`); + // cp.stdin.end(); + } + // reject(); + }); + + cp.on('close', (code) => { + console.log(`子进程退出码:${code}`); + // 签名是否生成成功 + let + privatePem = path.join(projDir, "private.pem"), + certificatePem = path.join(projDir, "certificate.pem"); + let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem); + if (!isSignExits) { + throw new Error("签名生成失败,请检查!"); + } + resolve(); + }); + }); +}); + +// 拷贝sign文件到指定位置 +gulp.task("copySignFile_HW", ["generateSign_HW"], function() { + // debug签名拷贝,默认拷贝 + let + privatePem = path.join(toolkitPath, "sign", "debug", "private.pem"), + certificatePem = path.join(toolkitPath, "sign", "debug", "certificate.pem"); + let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem); + if (!isSignExits) { + return; + } + let + signDest = `${projDir}/sign/debug`; + let stream = gulp.src([privatePem, certificatePem]); + stream.pipe(gulp.dest(signDest)); + + if (config.hwSign.generateSign) { // 新生成的签名 + // 移动签名文件到项目中(Laya & 华为快游戏项目中) + let + privatePem = path.join(projDir, "private.pem"), + certificatePem = path.join(projDir, "certificate.pem"); + let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem); + if (!isSignExits) { + return; + } + let + xiaomiDest = `${projDir}/sign/release`, + layaDest = `${workSpaceDir}/sign/release`; + let stream = gulp.src([privatePem, certificatePem]); + return stream.pipe(gulp.dest(xiaomiDest)) + .pipe(gulp.dest(layaDest)); + } else if (config.hwInfo.useReleaseSign && !config.hwSign.generateSign) { // 使用release签名,并且没有重新生成 + // 从项目中将签名拷贝到华为快游戏项目中 + let + privatePem = path.join(workSpaceDir, "sign", "release", "private.pem"), + certificatePem = path.join(workSpaceDir, "sign", "release", "certificate.pem"); + let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem); + if (!isSignExits) { + return; + } + let + xiaomiDest = `${projDir}/sign/release`; + let stream = gulp.src([privatePem, certificatePem]); + return stream.pipe(gulp.dest(xiaomiDest)); + } +}); + +gulp.task("deleteSignFile_HW", ["copySignFile_HW"], function() { + if (config.hwSign.generateSign) { // 新生成的签名 + let + privatePem = path.join(projDir, "private.pem"), + certificatePem = path.join(projDir, "certificate.pem"); + return del([privatePem, certificatePem], { force: true }); + } +}); + +gulp.task("modifyFile_HW", ["deleteSignFile_HW"], function() { + // 修改manifest.json文件 + let manifestPath = path.join(projDir, "manifest.json"); + let manifestJson; + if (fs.existsSync(manifestPath)) { + let manifestContent = fs.readFileSync(manifestPath, "utf8"); + manifestJson = JSON.parse(manifestContent); + } else { + manifestJson = { + "package": "", + "name": "", + "appType": "fastgame", + "icon": "", + "versionName": "", + "versionCode": 0, + "minPlatformVersion": 1000, + "config": { + "logLevel": "off" + }, + "display": { + "orientation": "portrait" + } + } + } + manifestJson.package = config.hwInfo.package; + manifestJson.name = config.hwInfo.name; + manifestJson.display.orientation = config.hwInfo.orientation; + manifestJson.config.logLevel = config.hwInfo.logLevel || "off"; + manifestJson.versionName = config.hwInfo.versionName; + manifestJson.versionCode = config.hwInfo.versionCode; + manifestJson.minPlatformVersion = config.hwInfo.minPlatformVersion; + manifestJson.icon = `/${path.basename(config.hwInfo.icon)}`; + if (config.hwInfo.subpack) { + let hwSubpackList = []; + for (let i = 0, len = config.hwSubpack.length; i < len; i++) { + hwSubpackList.push({ + name: config.hwSubpack[i].name, + resource: config.hwSubpack[i].root + }) + } + manifestJson.subpackages = hwSubpackList; + + // 检测分包目录是否有入口文件 + console.log('检查分包文件...'); + + if (manifestJson.subpackages) { + for(let i = 0; i < manifestJson.subpackages.length; i ++) { + let conf = manifestJson.subpackages[i]; + if (conf.name) { + let rootPath = path.join(projDir, conf.name); + if (!fs.existsSync(rootPath)) { + + throw new Error(`分包文件/目录 ${rootPath} 不存在!`); + } + let jsPath = path.join(rootPath, 'game.js'); ; + if (!fs.existsSync(jsPath)) { + + throw new Error(`分包文件/目录 ${jsPath} 不存在!`); + } + } + } + } + } else { + delete manifestJson.subpackages; + } + + fs.writeFileSync(manifestPath, JSON.stringify(manifestJson, null, 4), "utf8"); + + if (config.version) { + let versionPath = projDir + "/version.json"; + versionCon = fs.readFileSync(versionPath, "utf8"); + versionCon = JSON.parse(versionCon); + } + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + // 华为项目,修改game.js + let filePath = path.join(projDir, "game.js"); + if (!fs.existsSync(filePath)) { + let fileContent = `require("./huawei-adapter.js");\nrequire("./libs/laya.hwmini.js");\nrequire("index.js");`; + fs.writeFileSync(filePath, fileContent, "utf8"); + } + + // 华为项目,修改index.js + let indexFilePath = path.join(projDir, indexJsStr); + if (!fs.existsSync(indexFilePath)) { + return; + } + let indexFileContent = fs.readFileSync(indexFilePath, "utf8"); + indexFileContent = indexFileContent.replace(/loadLib(\(['"])/gm, "require$1./"); + fs.writeFileSync(indexFilePath, indexFileContent, "utf8"); +}); + +gulp.task("modifyMinJs_HW", ["modifyFile_HW"], function() { + let fileJsPath = path.join(projDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + if (!config.useMinJsLibs) { // 默认保留了平台文件,如果同时取消使用min类库,就会出现文件引用不正确的问题 + content = content.replace(/min\/laya(-[\w\d]+)?\.hwmini\.min\.js/gm, "laya.hwmini.js"); + } else { + content = content.replace(/(min\/)?laya(-[\w\d]+)?\.hwmini(\.min)?\.js/gm, "min/laya.hwmini.min.js"); + } + fs.writeFileSync(fileJsPath, content, 'utf-8'); +}); + +gulp.task("version_HW", ["modifyMinJs_HW"], function () { + // main.js默认不覆盖,如果同时开启版本管理,就会出现文件引用不正确的问题 + let fileJsPath = path.join(projDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/laya(-[\w\d]+)?\.hwmini/gm, "laya.hwmini"); + content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + + if (config.version) { + let versionPath = projDir + "/version.json"; + let mainJSPath = projDir + "/game.js"; + let srcList = [versionPath, mainJSPath]; + return gulp.src(srcList) + .pipe(revCollector()) + .pipe(gulp.dest(projDir)); + } +}); + +// 打包rpk +gulp.task("buildRPK_HW", ["version_HW"], function() { + // 在华为快游戏项目目录中执行: + // node .\signtool\package\index.js .\web .\dist com.demo .\release\private.pem .\release\certificate.pem + let + signtoolPath = path.join(toolkitPath, "index.js"), + releasePath = projDir, + distPath = path.join(projDir, "dist"), + name = config.hwInfo.package, + privatePem = path.join(projDir, "sign", "debug", "private.pem"), + certificatePemPath = path.join(projDir, "sign", "debug", "certificate.pem"); + if (config.hwInfo.useReleaseSign) { + privatePem = path.join(projDir, "sign", "release", "private.pem"), + certificatePemPath = path.join(projDir, "sign", "release", "certificate.pem"); + } + return new Promise((resolve, reject) => { + let cmd = `node`; + let args = [`"${signtoolPath}"`, `"${releasePath}"`, `"${distPath}"`, name, `"${privatePem}"`, `"${certificatePemPath}"`]; + let opts = { + cwd: projDir, + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + // let cp = childProcess.spawn('npx.cmd', ['-v']); + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + console.log(`stderr(iconv): ${iconv.decode(data, 'gbk')}`); + // reject(); + }); + + cp.on('close', (code) => { + console.log(`子进程退出码:${code}`); + // rpk是否生成成功 + let distRpkPath = path.join(distPath, `${name}.rpk`); + if (!fs.existsSync(distRpkPath)) { + throw new Error("rpk生成失败,请检查!"); + } + resolve(); + }); + }); +}); + + +gulp.task("getDevices_HW", ["buildRPK_HW"], function(cb) { + let cmd = `${adbPath} devices`; + childProcess.exec(cmd, (error, stdout, stderr) => { + if (error) { + console.error("获取设备失败..."); + return cb(); + } + if (stdout && stdout.match(/\bdevice\b/)) { + isDevices = true; + } + console.log(`检测到设备: ${isDevices}`); + return cb(); + }); +}); + +// 更新快应用加载器 +gulp.task("updateAPK_HW", ["getDevices_HW"], function(cb) { + if (!config.hwInfo.apkUpdate || !isDevices) { + return cb(); + } + let remoteInfo, remoteAPKVer, localAPKVer; + new Promise((resolve, reject) => { + https.get('https://deveco.huawei.com/FastIDE/update/api/update/engineVersion/', (res) => { + res.on('data', (data) => { + remoteInfo = JSON.parse(data); + remoteAPKVer = remoteInfo.version; + console.log("remote apk version: ", remoteAPKVer); + resolve(); + }); + }).on('error', (e) => { + reject(`获取远端快应用加载器失败: ${e}`); + }); + }).then(() => { + return new Promise((resolve, reject) => { + // Unable为找不到快应用加载器 + let cmd = `${adbPath} shell dumpsys package com.huawei.fastapp.dev | `; + if (process.platform === "darwin") { + cmd += `grep "versionName\\|Unable"`; + } else { + cmd += `findstr "versionName Unable"` + } + childProcess.exec(cmd, (error, stdout, stderr) => { + if (stdout && stdout.indexOf("Unable") >= 0) { + // 未安装 + localAPKVer = '0.0.0.0_dev'; + console.log("未安装快应用加载器"); + return resolve(); + } + if (error) { + console.log("获取快应用加载器本地版本号失败: "); + console.log(error); + console.log(stderr); + return resolve(error); + } + let matchList = stdout.match(/versionName=(.+)/); + if (!Array.isArray(matchList)) { + console.log("获取快应用加载器本地版本号失败: "); + return resolve(); + } + localAPKVer = matchList[1]; + console.log("local apk version: ", localAPKVer); + resolve(); + }); + }); + }).then(() => { + return new Promise((resolve, reject) => { + if (remoteAPKVer === localAPKVer || donotUpdate(remoteAPKVer, localAPKVer)) { + console.log("您的快应用加载器是最新版本!"); + return resolve(); + } + let url = remoteInfo.url; + let apkName = path.basename(url); + let apkDownRoot = path.join(toolkitPath, "fastapp"); + let apkDownPath = path.join(apkDownRoot, apkName); + // 1) 如果本地已经有最新版本的快应用加载器,则不再下载 + if (fs.existsSync(apkDownPath)) { + console.log("您本地有最新版本的快应用加载器,将直接安装!"); + return installAPK().then(() => { + return resolve(); + }).catch((err) => { + return reject(err); + }) + } + // 2) 下载并安装快应用加载器 + console.log("正在下载快应用加载器,请稍等..."); + !(fs.existsSync(apkDownRoot)) && fs.mkdirSync(apkDownRoot); + downFileToDir(url, apkDownPath).then(() => { + return installAPK(); + }).then(() => { + return resolve(); + }).catch((err) => { + return reject(err); + }) + + // 安装apk + function installAPK() { + return new Promise((resolve, reject) => { + console.log("正在安装快应用加载器,请稍等..."); + let cmd = `${adbPath} install -r ${apkDownPath}`; + childProcess.exec(cmd, (error, stdout, stderr) => { + if (error) { + console.error("安装快应用加载器本地版本号失败: "); + console.error(error); + console.error(stderr); + return reject(error); + } + console.log("安装快应用加载器成功!"); + resolve(); + }); + }) + } + }); + }).then(() => { + return cb(); + }).catch((re) => { + console.error("更新快应用加载器失败: ", re); + return cb(); + }); +}); + +function downFileToDir(uri, dest){ + return new Promise((resolve, reject) => { + if (!uri || !dest) { + reject(new Error(`downFileToDir 参数不全: ${uri}/${dest}`)); + return; + } + + let + totalLen = 9999, + progress = 0, + layaresponse; + var stream = fs.createWriteStream(dest); + request(uri).on('error', function(err) { + console.log("tool down err:" + err); + reject(err); + }).on("data", function(data) { + progress += data.length; + let downPercent = (progress / totalLen * 100).toFixed(3); + // console.log(`down: ${downPercent}%`); + }).on("response", function(response) { + layaresponse = response; + totalLen = response.caseless.dict['content-length']; + }).pipe(stream).on('close', function() { + if (layaresponse.statusCode == 200) { + console.log("下载成功!"); + resolve(); + } else { + reject(new Error("下载失败,连接关闭")); + } + }); + }); +} + +gulp.task("pushRPK_HW", ["updateAPK_HW"], function() { + if (!config.hwInfo.adbDebug || !isDevices) { + return; + } + // 在华为快游戏项目目录中执行: + // adb shell am force-stop com.huawei.fastapp.dev + // adb push {rpk_file_path} /data/local/tmp/ + // adb shell am start --es rpkpath /data/local/tmp/{rpk_file_name} --ei debugmode 1 --activity-clear-top com.huawei.fastapp.dev/com.huawei.fastapp.app.RpkRunnerActivity + return new Promise((resolve, reject) => { + // adb shell am force-stop com.huawei.fastapp.dev + console.log(`1) force-stop: `); + let cmd = `${adbPath}`; + let args = ["shell", "am", "force-stop", "com.huawei.fastapp.dev"]; + let opts = { + cwd: projDir, + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + // let cp = childProcess.spawn('npx.cmd', ['-v']); + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + // reject(); + }); + + cp.on('close', (code) => { + console.log(`force-stop 子进程退出码:${code}`); + resolve(); + }); + }).then(() => { + return new Promise((resolve, reject) => { + // adb push {rpk_file_path} /data/local/tmp/ + console.log(`2) push_RPK: `); + let rpkFilePath = path.join(projDir, "dist", `${config.hwInfo.package}.rpk`); + let cmd = `${adbPath}`; + let args = ["push", `"${rpkFilePath}"`, "/data/local/tmp/"]; + let opts = { + cwd: projDir, + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + // let cp = childProcess.spawn('npx.cmd', ['-v']); + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + // reject(); + }); + + cp.on('close', (code) => { + console.log(`push_RPK 子进程退出码:${code}`); + resolve(); + }); + }); + }).then(() => { + return new Promise((resolve, reject) => { + // adb shell am start --es rpkpath /data/local/tmp/{rpk_file_name} --ei debugmode 1 --activity-clear-top com.huawei.fastapp.dev/com.huawei.fastapp.app.RpkRunnerActivity + console.log(`3) 启动apk,加载rpk: `); + let cmd = `${adbPath}`; + let args = ["shell", "am", "start", "--es", "rpkpath", `file://data/local/tmp/${config.hwInfo.package}.rpk`, "--ei", "debugmode", "1", "--activity-clear-top", "com.huawei.fastapp.dev/com.huawei.fastapp.app.RpkRunnerActivity"]; + let opts = { + cwd: projDir, + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + // let cp = childProcess.spawn('npx.cmd', ['-v']); + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + // reject(); + }); + + cp.on('close', (code) => { + console.log(`启动apk,加载rpk: 子进程退出码:${code}`); + resolve(); + }); + }); + }); +}); + +function donotUpdate(remoteAPKVer, localAPKVer) { + let remoteAPKVerN = remoteAPKVer.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)/); + let localAPKVerN = localAPKVer.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)/); + let + l1n = Number(localAPKVerN[1]), // local first number + l2n = Number(localAPKVerN[2]), + l3n = Number(localAPKVerN[3]), + l4n = Number(localAPKVerN[4]), + r1n = Number(remoteAPKVerN[1]), // remote first number + r2n = Number(remoteAPKVerN[2]), + r3n = Number(remoteAPKVerN[3]); + r4n = Number(remoteAPKVerN[4]); + if (l1n > r1n) { + return true; + } + if (l1n === r1n && l2n > r2n) { + return true; + } + if (l1n === r1n && l2n === r2n && l3n > r3n) { + return true; + } + if (l1n === r1n && l2n === r2n && l3n === r3n && l4n >= r4n) { + return true; + } + return false; +} + +gulp.task("buildHWProj", ["pushRPK_HW"], function() { + console.log("all tasks completed"); +}); \ No newline at end of file diff --git a/examples/layaair/frontend/.laya/publish_layame.js b/examples/layaair/frontend/.laya/publish_layame.js new file mode 100644 index 0000000..3cec3f6 --- /dev/null +++ b/examples/layaair/frontend/.laya/publish_layame.js @@ -0,0 +1,453 @@ +// v1.1.5 +const ideModuleDir = global.ideModuleDir; +const workSpaceDir = global.workSpaceDir; + +var Stream = require('stream'); +//引用插件模块 +const gulp = require(ideModuleDir + "gulp"); +const fs = require("fs"); +const path = require("path"); +const del = require(ideModuleDir + "del"); + +let copyLibsTask = ["copyPlatformLibsJsFile"]; +let versiontask = ["version2"]; +let exec = require('child_process').exec; +let tsconfigPath = path.join(workSpaceDir, "tsconfig.json"); +let isTS = fs.existsSync(tsconfigPath); +let buildOptions = null; +gulp.task("preCreate_LayaMe", copyLibsTask, function() { + releaseDir = global.releaseDir; + config = global.config; + buildOptions = config.buildOptions; + commandSuffix = global.commandSuffix; +}); +// 是否build指定部分(debug版本layame) +function toBuildPart(part) { + if (!buildOptions) { + return true; + } + if ('all' == part ) { + return buildOptions.type == 'all'; + } + if (buildOptions.type == 'all') { + return true; + } + return (buildOptions.buildList.includes(part)); +} +function toBuildTs() { + if (!buildOptions) { + return true; + } + return buildOptions.hasScript; +} + +gulp.task("del", ["preCreate_LayaMe"], function(cb) { + let buildFolder = path.join(workSpaceDir, "build"); + if (!isTS || !fs.existsSync(buildFolder)) { + return cb(); + } + let delList = [`${buildFolder}/**`]; + del(delList, { force: true }).then(paths => { + cb(); + }).catch((err) => { + throw err; + }) +}); + +gulp.task("tsc", ["del"], function(cb) { + if (!isTS) { + return cb(); + } + if(!toBuildTs()) { + return cb(); + } + console.log('tsconfigPath', tsconfigPath); + let tscPath = path.join(ideModuleDir, ".bin", `tsc${commandSuffix}`); + return exec(` "${tscPath}" -p "${tsconfigPath}"`, { + cwd: workSpaceDir, + shell: true + }, function(error, stdout, stderr) { + let errStr = stderr || ''; + if (errStr.indexOf(": node: ") >= 0 || errStr.indexOf("'node'") >= 0) { + // 提示未安装node + console.log("err"); + console.log("node not installed"); + } else { + if (error) console.log("error", error); + if (stdout) console.log("stdout", stdout); + if (stderr) console.log("stderr", stderr); + cb(); + } + }); +}); +function getFolderList(rootPath, fileList, fileType, deep= 0) { + if (!fs.existsSync(rootPath)) { + return fileList; + } + let dirList = fs.readdirSync(rootPath); + let fileName, fileFullPath; + for (let i = 0, len = dirList.length; i < len; i++) { + fileName = dirList[i]; + fileFullPath = path.join(rootPath, fileName); + if (fs.statSync(fileFullPath).isDirectory()) { + getFolderList(fileFullPath, fileList, fileType, deep + 1); + } else { + if (!!fileType && !fileFullPath.endsWith(fileType)) { + continue; + } + fileList.push({path: fileFullPath,deep:deep}); + } + } +} +// 把ui里type为view的runtime删除 +gulp.task("deletRuntime", ["tsc"], function() { + // const pageUIFolder = path.join(releaseDir, "pageUI"); + // let sceneList= []; + // getFolderList(pageUIFolder, sceneList, ".json"); + // for (let i = 0, len = sceneList.length; i < len; i++) { + // let filePath = sceneList[i].path; + // let fileCon = fs.readFileSync(filePath, "utf8"); + // let jsonData = JSON.parse(fileCon); + // if (jsonData.type == 'View') { + // if (jsonData.props && jsonData.props.runtime) { + // delete jsonData.props.runtime; + // fs.writeFileSync(filePath, JSON.stringify(jsonData), 'utf8'); + // } + // } + // } +}); +// 将引入的库的路径改为src根目录的LayaMeMain,并且将引入的该类合并到最终发布目录的根目录下的LayaMeMain.js里 +function sortJS (a, b) { + + return b.c - a.c; +} + +function getFInfoByPath(path, list) { + for (let i = 0, len = list.length; i < len; i++) { + let info = list[i]; + if (info.path === path) { + return info; + } + } + return null; +} +gulp.task("mergrToLayaMeMain", ["deletRuntime"], function() { + if (!toBuildPart('LayaMeMain')) { + return; + } + let source = "src"; + if (isTS) { + source = "build"; + } + let sourceFolder = path.join(workSpaceDir, source); + const scriptPath = path.join(sourceFolder, "script"); + let jsList= []; + let scriptStrList = []; + let filePath, fileCon, deep; + // 遍历所有的script,合并到LayaMeMain.js + jsList= []; + scriptStrList = []; + + getFolderList(scriptPath, jsList, ".js"); + // sort jsList + let needSort = false; + let sortList = []; + let otherList = []; + for (let i = 0, len = jsList.length; i < len; i++) { + let jsInfo = jsList[i]; + filePath = jsInfo.path; + fileCon = fs.readFileSync(filePath, "utf8"); + jsInfo.content = fileCon; + let extendsCls = fileCon.match((/\ s*extends \s*(.+?)\{/)); + if (extendsCls) { + if (extendsCls[1]) { + extendsCls = extendsCls[1].trim(); + if (extendsCls && !extendsCls.includes('.')) { // not include Laya. + let importCls = fileCon.match(`import\\s*[{| ]\\s*${extendsCls}\\s*[}| ]\\s*from (.+?)["']`) ; + // console.log( extendsCls, jsInfo.path, !!importCls ); + if (importCls && importCls[1]) { + importCls = importCls[1].trim(); + importCls = importCls.substr(1); console.log( importCls); + let deep = jsInfo.deep; + let currPath = null; + let _index = importCls.lastIndexOf('./'); + let parenPath = ''; + if (_index >= 0) { + let fPath = jsInfo.path; + let _index2 = fPath.indexOf('/') >= 0 ? fPath.lastIndexOf('/') : fPath.lastIndexOf('\\') ; + currPath = fPath.substring(0,_index2); + currPath = path.join(jsInfo.path,parenPath + '../', importCls) + '.js'; + jsInfo.extendsCls = extendsCls;// currPath; + // console.log(jsInfo); + needSort = true; + if (!sortList.includes(jsInfo)) { + sortList.push(jsInfo); + } + let importJs = getFInfoByPath(currPath, jsList); + if (!importJs) { + throw new Error('not found', currPath); + } + if (!jsInfo.c) { + jsInfo.c = 0; + } + importJs.c = jsInfo.c + 1; + if (!sortList.includes(importJs)) { + sortList.push(importJs); + } + // console.log(currPath,_index,parenPath, jsInfo.path, importCls, extendsCls); + + } + + } + } + } + } + // .vs .fs 解析 + let fileConTmp = fileCon + ''; + let vsOrfsImport = fileConTmp.match(/import \s*(.+?) from \s*(.+?).[fv]s['"]/); + + while (vsOrfsImport) { + let importVar = vsOrfsImport[1]; + let filetype = vsOrfsImport[0]; + let importFile = vsOrfsImport[2]; + importFile = importFile.replace("'", ''); + importFile = importFile.replace('"', ''); + if (filetype.indexOf('.vs') >= 0) { + filetype = '.vs'; + } else { + filetype = '.fs'; + } + importFile = importFile + filetype; + let importFilePath = path.join(filePath,'../',importFile ); + console.log('importFilePath', importFilePath); + fileConTmp = fileConTmp.replace(vsOrfsImport[0], ''); + // console.log('fileConTmp', fileConTmp); + vsOrfsImport = fileConTmp.match(/import \s*(.+?) from \s*(.+?).[fv]s['"]/); + let srcPath = path.join(workSpaceDir, 'src'); + importFilePath = importFilePath.replace(sourceFolder, srcPath); + + let importFileStr = fs.readFileSync(importFilePath, 'utf8'); + importFileStr = importFileStr.replace(/\r?\n/gm, '\\n'); + importFileStr = importFileStr.replace(/"/gm,'\''); + importFileStr = importFileStr.replace(/\t/gm,'\\t'); + importFileStr = importFileStr.replace(/\\n\s*/g,'\\n'); + importFileStr = importFileStr.replace(/\\n\\n/g,'\\n'); + // let lineList = importFileStr.split('\n'); + // let rStr = ''; + // for(let i = 0,len = lineList.length; i < len; i ++) { + // let lineStr = lineList[i]; + // lineStr = lineStr.replace(/\r?\n/gm, '\\n'); + // lineStr = lineStr.replace(/"/gm,'\\"'); + // lineStr = lineStr.replace(/\t/gm,'\\t'); + // lineStr = lineStr.trim(); + // rStr = rStr + lineStr + '\\n'; + // } + // // fs.writeFileSync(importFilePath + '2',rStr.replace(/\\n/gm,'\n'), 'utf8'); + jsInfo.content = `var ${importVar} = "${importFileStr}";\n` + jsInfo.content; + } + } + // console.log('ssssssssss',sortList); + if (needSort) { + sortList.sort(sortJS); + for (let i = 0, len = sortList.length; i < len; i++) { + let jsInfo = sortList[i]; + scriptStrList.push(jsInfo.content); + } + } + for (let i = 0, len = jsList.length; i < len; i++) { + let jsInfo = jsList[i]; + if (!needSort || !sortList.includes(jsInfo)) { + scriptStrList.push(jsInfo.content); + } + } + let layaMeMainStr = ''; + const layaMeMainPath = path.join(sourceFolder, "LayaMeMain.js"); + if (fs.existsSync(layaMeMainPath)) { + layaMeMainStr = fs.readFileSync(layaMeMainPath, "utf8"); + } + if (scriptStrList.length > 0) { + let scriptStrAll = scriptStrList.join('\n'); + layaMeMainStr = scriptStrAll + layaMeMainStr; + } + if (layaMeMainStr) { + // console.log(jsList.length,'layaMeMainStr' , layaMeMainStr); + layaMeMainStr = layaMeMainStr.replace(/import/mg, "// import"); + // 去掉class前面的字符 + layaMeMainStr = layaMeMainStr.replace(/export\s+default\s+[class\.]+\s*/mg, "class "); + layaMeMainStr = layaMeMainStr.replace(/export\s+[class\.]+\s*/mg, "class "); + fs.writeFileSync(`${releaseDir}/LayaMeMain.js`, layaMeMainStr, "utf8"); + } +}); +// 修改extends Laya.Script3D 为 extends GameScript +// 修改 config.json,把.ts替换为.js +function commentImport (str){ + + str = str.replace(/import/mg, "// import"); + return str; +} +function changeComponentsFile() { + var stream = new Stream.Transform({ objectMode: true }); + let source = "src"; + if (isTS) { + source = "build"; + } + let sourceFolder = path.join(workSpaceDir, source); + const scriptPath = path.join(sourceFolder, "script"); + const componentsPath = path.join(sourceFolder, "components"); + const actionScriptPath = path.join(sourceFolder, "actionScript", "actionFunc.js"); + const uiScriptPath = path.join(sourceFolder, "uiScript"); + let importPathList = [scriptPath, componentsPath, actionScriptPath, uiScriptPath]; + stream._transform = function (originalFile, unused, callback) { + let fPath = originalFile.path; + // throw new Error(); + let file = null; + const getFile = () => { + if (!file) { + file = originalFile.clone({ contents: false }); + } + return file; + } + // console.log('fPth', fPath, componentsPath); + // 注释import + for(let k =0; k = 0) { + if ( fPath.endsWith('.js')) { + file = getFile(); + let stringData = String(file.contents); + stringData = stringData.replace(/extends\s+[Laya.Script3D\.]+\s*{/mg, "extends GameScript {"); + let finalBinaryData = Buffer.from(stringData); + file.contents = finalBinaryData; + + } else if (fPath.endsWith('config.json')) { + file = getFile(); + let stringData = String(file.contents); + stringData = stringData.replace(/.ts\"/mg, '.js"'); + let finalBinaryData = Buffer.from(stringData); + file.contents = finalBinaryData; + } + } + // 去掉class前面的字符 + if (fPath.endsWith('.js')) { + file = getFile(); + let stringData = String(file.contents); + stringData = stringData.replace(/export\s+default\s+[class\.]+\s*/mg, "class "); + stringData = stringData.replace(/export\s+[class\.]+\s*/mg, "class "); + let finalBinaryData = Buffer.from(stringData); + file.contents = finalBinaryData; + } + if (file) { + callback(null, file); + } else { + callback(null, originalFile); + } + }; + return stream; +} + +gulp.task("genPreloadMap", ["mergrToLayaMeMain"], function() { + let atlasList = []; + getFolderList(releaseDir,atlasList, '.atlas'); + let preloadJson = { + atlas: [], + atlasPng:[], + textures: [] + + }; + let releaseDirTmp = releaseDir.replace(/\\/g, '/'); + for(let i = 0,len = atlasList.length; i < len; i ++) { + let file = atlasList[i].path; + file = file.replace(/\\/g, '/'); + file = file.replace(releaseDirTmp, ''); + file = file.replace('/', ''); + preloadJson.atlas.push(file); + preloadJson.atlasPng.push( file.replace('.atlas', '.png')); + } + let texturesList = []; + let texturesDir = path.join(releaseDir, 'textures'); + getFolderList(texturesDir,texturesList, '.png'); + getFolderList(texturesDir,texturesList, '.jpg'); + getFolderList(texturesDir,texturesList, '.jpeg'); + + let texturesDirTmp = releaseDir.replace(/\\/g, '/'); + for(let i = 0,len = texturesList.length; i < len; i ++) { + let file = texturesList[i].path; + file = file.replace(/\\/g, '/'); + file = file.replace(texturesDirTmp, ''); + file = file.replace('/', ''); + preloadJson.textures.push(file); + } + fs.writeFileSync(path.join(releaseDir, 'preload.json'), JSON.stringify(preloadJson, null ,4), 'utf8'); + // console.log('atlasList', preloadJson); +}); +gulp.task("copy", ["genPreloadMap"], function() { + + let source = "src"; + if (isTS) { + source = "build"; + } + let sourceFolder = path.join(workSpaceDir, source); + let layameInfo = config.layameInfo; + let filter1list = []; + + if (toBuildPart('uiScript')) { + filter1list.push('uiScript/**/*.*'); + } + if (toBuildPart('actionScript')) { + filter1list.push('actionScript/**/*.*'); + } + if (toBuildPart('components')) { + filter1list.push('components/**/*.*'); + } + let filter1 = ``; + if (filter1list.length > 1) { + filter1 = `${sourceFolder}/{`; + filter1 += filter1list.join(','); + filter1 += '}'; + } else if (filter1list.length == 1) { + filter1 = `${sourceFolder}/{,`; + filter1 += filter1list[0]; + filter1 += '}'; + } else { + return; + } + let filters = [filter1]; + // console.log('filter1', filter1);throw new Error(); + if (isTS) { + let filter2 = `${workSpaceDir}/src/{,`; + let filter2list =[]; + if (toBuildPart('uiScript')) { + filter2list.push('uiScript/**/!(*.ts)'); + } + if (toBuildPart('actionScript')) { + filter2list.push('actionScript/**/!(*.ts)'); + } + if (toBuildPart('components')) { + filter2list.push('components/**/!(*.ts)'); + } + if (filter2list.length > 1) { + filter2 += filter2list.join(','); + } else if (filter2list.length == 1) { + filter2 += filter2list[0]; + } + filter2 += '}'; + filters.push( + filter2 + ); + } + return gulp.src(filters) + .pipe(changeComponentsFile()) + .pipe(gulp.dest(releaseDir)); +}); + +gulp.task("buildLayaMeProj", versiontask, function() { + console.log("all tasks completed"); +}); \ No newline at end of file diff --git a/examples/layaair/frontend/.laya/publish_oppogame.js b/examples/layaair/frontend/.laya/publish_oppogame.js new file mode 100644 index 0000000..d4f1e52 --- /dev/null +++ b/examples/layaair/frontend/.laya/publish_oppogame.js @@ -0,0 +1,813 @@ +// v1.9.3 +const ideModuleDir = global.ideModuleDir; +const workSpaceDir = global.workSpaceDir; + +//引用插件模块 +const gulp = require(ideModuleDir + "gulp"); +const fs = require("fs"); +const path = require("path"); +const childProcess = require("child_process"); +const del = require(ideModuleDir + "del"); +const revCollector = require(ideModuleDir + 'gulp-rev-collector'); +const iconv = require(ideModuleDir + "iconv-lite"); +const request = require(ideModuleDir + "request"); +const { getEngineVersion, canUsePluginEngine } = require("./pub_utils"); + +let fullRemoteEngineList = ["laya.core.js", "laya.webgl.js", "laya.filter.js", "laya.ani.js", "laya.d3.js", "laya.html.js", "laya.particle.js", "laya.ui.js", "laya.d3Plugin.js", "bytebuffer.js", "laya.device.js", "laya.physics.js", "laya.physics3D.js", "laya.tiledmap.js", "worker.js", "workerloader.js"]; +let copyLibsTask = ["copyPlatformLibsJsFile"]; +let versiontask = ["version2"]; + +let + config, + releaseDir, + toolkitPath, + tempReleaseDir, // OPPO临时拷贝目录 + projDir; // OPPO快游戏工程目录 +let versionCon; // 版本管理version.json +let commandSuffix, + adbPath, + opensslPath, + layarepublicPath; + +// 创建OPPO项目前,拷贝OPPO引擎库、修改index.js +gulp.task("preCreate_OPPO", copyLibsTask, function() { + releaseDir = global.releaseDir; + config = global.config; + commandSuffix = global.commandSuffix; + adbPath = global.adbPath; + opensslPath = global.opensslPath; + layarepublicPath = global.layarepublicPath; + tempReleaseDir = global.tempReleaseDir; + + toolkitPath = path.join(layarepublicPath, "oppo", "quickgame-toolkit"); + + if (config.useMinJsLibs) { + fullRemoteEngineList = fullRemoteEngineList.map((item, index) => { + return item.replace(".js", ".min.js"); + }) + } +}); + +gulp.task("copyPlatformFile_OPPO", ["preCreate_OPPO"], function() { + return; +}); + +// 新建OPPO项目-OPPO项目与其他项目不同,需要安装OPPO quickgame node_modules,并打包成.rpk文件 +gulp.task("installModules_OPPO", versiontask, function() { + releaseDir = path.dirname(releaseDir); + projDir = path.join(releaseDir, config.oppoInfo.projName); + // 如果IDE里对应OPPO包已经install node_modules了,忽略这一步 + if (fs.existsSync(path.join(toolkitPath, "node_modules"))) { + return; + } + // 安装OPPO quickgame node_modules + return new Promise((resolve, reject) => { + console.log("开始安装OPPO quickgame node_modules,请耐心等待..."); + let cmd = `npm${commandSuffix}`; + let args = ["install"]; + let opts = { + cwd: toolkitPath, + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + // reject(); + }); + + cp.on('close', (code) => { + console.log(`子进程退出码:${code}`); + resolve(); + }); + }); +}); + +// 拷贝文件到OPPO快游戏 +gulp.task("copyFileToProj_OPPO", ["installModules_OPPO"], function() { + // 将临时文件夹中的文件,拷贝到项目中去 + let originalDir = `${tempReleaseDir}/**/*.*`; + let stream = gulp.src(originalDir); + return stream.pipe(gulp.dest(path.join(projDir))); +}); + +// 拷贝icon到OPPO快游戏 +gulp.task("copyIconToProj_OPPO", ["copyFileToProj_OPPO"], function() { + let originalDir = config.oppoInfo.icon; + let stream = gulp.src(originalDir); + return stream.pipe(gulp.dest(path.join(projDir))); +}); + +// 清除OPPO快游戏临时目录 +gulp.task("clearTempDir_OPPO", ["copyIconToProj_OPPO"], function() { + // 删掉临时目录 + return del([tempReleaseDir], { force: true }); +}); + +// 生成release签名(私钥文件 private.pem 和证书文件 certificate.pem ) +gulp.task("generateSign_OPPO", ["clearTempDir_OPPO"], function() { + if (!config.oppoSign.generateSign) { + return; + } + // https://doc.quickapp.cn/tools/compiling-tools.html + return new Promise((resolve, reject) => { + let cmd = `${opensslPath}`; + let args = ["req", "-newkey", "rsa:2048", "-nodes", "-keyout", "private.pem", + "-x509", "-days", "3650", "-out", "certificate.pem"]; + let opts = { + cwd: projDir, + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + data += ""; + if (data.includes("Country Name")) { + cp.stdin.write(`${config.oppoSign.countryName}\n`); + console.log(`Country Name: ${config.oppoSign.countryName}`); + } else if (data.includes("Province Name")) { + cp.stdin.write(`${config.oppoSign.provinceName}\n`); + console.log(`Province Name: ${config.oppoSign.provinceName}`); + } else if (data.includes("Locality Name")) { + cp.stdin.write(`${config.oppoSign.localityName}\n`); + console.log(`Locality Name: ${config.oppoSign.localityName}`); + } else if (data.includes("Organization Name")) { + cp.stdin.write(`${config.oppoSign.orgName}\n`); + console.log(`Organization Name: ${config.oppoSign.orgName}`); + } else if (data.includes("Organizational Unit Name")) { + cp.stdin.write(`${config.oppoSign.orgUnitName}\n`); + console.log(`Organizational Unit Name: ${config.oppoSign.orgUnitName}`); + } else if (data.includes("Common Name")) { + cp.stdin.write(`${config.oppoSign.commonName}\n`); + console.log(`Common Name: ${config.oppoSign.commonName}`); + } else if (data.includes("Email Address")) { + cp.stdin.write(`${config.oppoSign.emailAddr}\n`); + console.log(`Email Address: ${config.oppoSign.emailAddr}`); + // cp.stdin.end(); + } + // reject(); + }); + + cp.on('close', (code) => { + console.log(`子进程退出码:${code}`); + // 签名是否生成成功 + let + privatePem = path.join(projDir, "private.pem"), + certificatePem = path.join(projDir, "certificate.pem"); + let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem); + if (!isSignExits) { + throw new Error("签名生成失败,请检查!"); + } + resolve(); + }); + }); +}); + +// 拷贝sign文件到指定位置 +gulp.task("copySignFile_OPPO", ["generateSign_OPPO"], function() { + if (config.oppoSign.generateSign) { // 新生成的签名 + // 移动签名文件到项目中(Laya & OPPO快游戏项目中) + let + privatePem = path.join(projDir, "private.pem"), + certificatePem = path.join(projDir, "certificate.pem"); + let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem); + if (!isSignExits) { + return; + } + let + xiaomiDest = `${projDir}/sign/release`, + layaDest = `${workSpaceDir}/sign/release`; + let stream = gulp.src([privatePem, certificatePem]); + return stream.pipe(gulp.dest(xiaomiDest)) + .pipe(gulp.dest(layaDest)); + } else if (config.oppoInfo.useReleaseSign && !config.oppoSign.generateSign) { // 使用release签名,并且没有重新生成 + // 从项目中将签名拷贝到OPPO快游戏项目中 + let + privatePem = path.join(workSpaceDir, "sign", "release", "private.pem"), + certificatePem = path.join(workSpaceDir, "sign", "release", "certificate.pem"); + let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem); + if (!isSignExits) { + return; + } + let + xiaomiDest = `${projDir}/sign/release`; + let stream = gulp.src([privatePem, certificatePem]); + return stream.pipe(gulp.dest(xiaomiDest)); + } +}); + +gulp.task("deleteSignFile_OPPO", ["copySignFile_OPPO"], function() { + if (config.oppoSign.generateSign) { // 新生成的签名 + let + privatePem = path.join(projDir, "private.pem"), + certificatePem = path.join(projDir, "certificate.pem"); + return del([privatePem, certificatePem], { force: true }); + } +}); + +gulp.task("modifyFile_OPPO", ["deleteSignFile_OPPO"], function() { + // 修改manifest.json文件 + let manifestPath = path.join(projDir, "manifest.json"); + let IDEManifestPath = path.join(toolkitPath, "tpl", "manifest.json"); + if (!fs.existsSync(IDEManifestPath) && !fs.existsSync(manifestPath)) { + return; + } + let manifestContent; + if (fs.existsSync(manifestPath)) { + manifestContent = fs.readFileSync(manifestPath, "utf8"); + } else { + manifestContent = fs.readFileSync(IDEManifestPath, "utf8"); + } + let manifestJson = JSON.parse(manifestContent); + manifestJson.package = config.oppoInfo.package; + manifestJson.name = config.oppoInfo.name; + manifestJson.orientation = config.oppoInfo.orientation; + manifestJson.config.logLevel = config.oppoInfo.logLevel || "off"; + manifestJson.versionName = config.oppoInfo.versionName; + manifestJson.versionCode = config.oppoInfo.versionCode; + manifestJson.minPlatformVersion = config.oppoInfo.minPlatformVersion; + manifestJson.icon = `./${path.basename(config.oppoInfo.icon)}`; + if (config.oppoInfo.subpack) { + manifestJson.subpackages = config.oppoSubpack; + // 检测分包目录是否有入口文件 + console.log('检查分包文件...'); + + if (manifestJson.subpackages) { + for(let i = 0; i < manifestJson.subpackages.length; i ++) { + let conf = manifestJson.subpackages[i]; + if (conf.root) { + let rootPath = path.join(projDir, conf.root); + if (!fs.existsSync(rootPath)) { + + throw new Error(`分包文件/目录 ${rootPath} 不存在!`); + } + let jsIndex = rootPath.lastIndexOf('.js'); + let jsPath = rootPath; + if (jsIndex < 0 || jsIndex != rootPath.length - 3) { + jsPath = path.join(rootPath, 'main.js'); + } + if (!fs.existsSync(jsPath)) { + + throw new Error(`分包文件/目录 ${jsPath} 不存在!`); + } + } + } + } + } else { + delete manifestJson.subpackages; + } + fs.writeFileSync(manifestPath, JSON.stringify(manifestJson, null, 4), "utf8"); + + if (config.version) { + let versionPath = projDir + "/version.json"; + versionCon = fs.readFileSync(versionPath, "utf8"); + versionCon = JSON.parse(versionCon); + } + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + // OPPO项目,修改main.js + let filePath = path.join(projDir, "main.js"); + let fileContent; + if (!fs.existsSync(filePath)) { + fileContent = `window.navigator.userAgent = 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E8301 OPPO MiniGame NetType/WIFI Language/zh_CN'; +require("./libs/laya.quickgamemini.js");\nrequire("index.js");`; + } else { + // 额外的,如果有引擎插件相关代码,需要删掉 + fileContent = fs.readFileSync(filePath, "utf8"); + fileContent = fileContent.replace(/if\s\(window\.requirePlugin\)\s{\n[\w\"\.\-\/\(\);\s\n]*\n}\selse\s{\n[\w\"\.\-\/\(\);\s\n]*\n}\n/gm, ""); + } + fs.writeFileSync(filePath, fileContent, "utf8"); + + // OPPO项目,修改index.js + let indexFilePath = path.join(projDir, indexJsStr); + if (!fs.existsSync(indexFilePath)) { + return; + } + let indexFileContent = fs.readFileSync(indexFilePath, "utf8"); + indexFileContent = indexFileContent.replace(/loadLib(\(['"])/gm, "require$1./"); + fs.writeFileSync(indexFilePath, indexFileContent, "utf8"); +}); + +gulp.task("modifyMinJs_OPPO", ["modifyFile_OPPO"], function() { + let fileJsPath = path.join(projDir, "main.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + if (!config.useMinJsLibs) { // 默认保留了平台文件,如果同时取消使用min类库,就会出现文件引用不正确的问题 + content = content.replace(/min\/laya(-[\w\d]+)?\.quickgamemini\.min\.js/gm, "laya.quickgamemini.js"); + } else { + content = content.replace(/(min\/)?laya(-[\w\d]+)?\.quickgamemini(\.min)?\.js/gm, "min/laya.quickgamemini.min.js"); + } + fs.writeFileSync(fileJsPath, content, 'utf-8'); +}); + +gulp.task("version_OPPO", ["modifyMinJs_OPPO"], function () { + // main.js默认不覆盖,如果同时开启版本管理,就会出现文件引用不正确的问题 + let fileJsPath = path.join(projDir, "main.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/laya(-[\w\d]+)?\.quickgamemini/gm, "laya.quickgamemini"); + content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + + if (config.version) { + let versionPath = projDir + "/version.json"; + let mainJSPath = projDir + "/main.js"; + let srcList = [versionPath, mainJSPath]; + return gulp.src(srcList) + .pipe(revCollector()) + .pipe(gulp.dest(projDir)); + } +}); + +// 处理引擎插件 +// 我们会将所有的libs下的文件放到engine里,但不能认定libs下全是我们的引擎,所以还是要加判断 +gulp.task("pluginEngin_OPPO", ["version_OPPO"], function(cb) { + let manifestJsonPath = path.join(projDir, "manifest.json"); + let manifestJsonContent = fs.readFileSync(manifestJsonPath, "utf8"); + let conJson = JSON.parse(manifestJsonContent); + let copyBinPath; + + if (!config.uesEnginePlugin) { // 没有使用引擎插件,还是像以前一样发布 + delete conJson.plugins; + manifestJsonContent = JSON.stringify(conJson, null, 4); + fs.writeFileSync(manifestJsonPath, manifestJsonContent, "utf8"); + return cb(); + } + // 引擎源码项目 + // 将所有的min拷贝进来 + if (config.useMinJsLibs) { + copyBinPath = path.join(workSpaceDir, "bin", "libs", "min"); + } else { // 如果不是min + copyBinPath = path.join(workSpaceDir, "bin", "libs"); + } + // 针对min引擎文件,很多配置文件也需要该,同时改 + if (config.version) { + let versionPath = projDir + "/version.json"; + versionCon = fs.readFileSync(versionPath, "utf8"); + versionCon = JSON.parse(versionCon); + } + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + + // 获取version等信息 + let coreLibPath = path.join(workSpaceDir, "bin", "libs", "laya.core.js"); + let isHasCoreLib = fs.existsSync(coreLibPath); + let isOldAsProj = fs.existsSync(`${workSpaceDir}/asconfig.json`) && !isHasCoreLib; + let isNewTsProj = fs.existsSync(`${workSpaceDir}/src/tsconfig.json`) && !isHasCoreLib; + let EngineVersion = getEngineVersion(); + if (isOldAsProj || isNewTsProj) { + // 下载对应版本js引擎,按照普通项目走 + console.log(`ts源码项目(${isNewTsProj})或as源码项目(${isOldAsProj}),开始处理引擎`); + let engineNum = EngineVersion.split("beta")[0]; + let suffix = EngineVersion.includes("beta") ? `_beta${EngineVersion.split("beta")[1]}` : ""; + let engineURL; + if (canUsePluginEngine(EngineVersion, "2.7.2")) { // 2.7.2 开始,下载地址更新为 cos 服务器 + engineURL = `https://ldc-1251285021.cos.ap-shanghai.myqcloud.com/download/Libs/LayaAirJS_${engineNum}${suffix}.zip`; + } else { + engineURL = `http://ldc.layabox.com/download/LayaAirJS_${engineNum}${suffix}.zip`; + } + let engineDownPath = path.join(releaseDir, `LayaAirJS_${engineNum}${suffix}.zip`); + let engineExtractPath = path.join(releaseDir, `LayaAirJS_${engineNum}${suffix}`); + if (config.useMinJsLibs) { + copyBinPath = path.join(engineExtractPath, "js", "libs", "min"); + } else { // 如果不是min + copyBinPath = path.join(engineExtractPath, "js", "libs"); + } + // 情况1) 如果已经下载过引擎了,直接开始处理引擎插件 + if (fs.existsSync(copyBinPath)) { + console.log("情况1) 如果已经下载过引擎了,直接开始处理引擎插件"); + return dealPluginEngine().then(() => { + // return cb(); + }).catch((err) => { + console.error("ts源码项目及as源码项目,下载或处理oppo引擎插件项目失败(code 1)!"); + throw err; + }); + } + // 情况2) 下载并解压引擎,然后开始处理引擎插件 + console.log("情况2) 下载并解压引擎,然后开始处理引擎插件"); + return downFileToDir(engineURL, engineDownPath).then(() => { + console.log("下载引擎库成功,开始解压"); + return extractZipFile(engineDownPath, engineExtractPath); + }).then(() => { + console.log("解压成功,开始处理引擎插件"); + return dealPluginEngine(); + }).then(() => { + // return cb(); + }).catch((err) => { + console.error("ts源码项目及as源码项目,下载或处理oppo引擎插件项目失败(code 2)!"); + throw err; + }) + } + // 情况3) 非源码项目,开始处理引擎插件 + console.log("情况3) 非源码项目,开始处理引擎插件"); + return dealPluginEngine().then(() => { + // return cb(); + }).catch((err) => { + throw err; + }); + + function dealPluginEngine() { + // 使用引擎插件 + let localUseEngineList = []; + let copyEnginePathList; + return new Promise(function(resolve, reject) { + console.log(`修改main.js和manifest.json`); + // 1) 修改main.js和manifest.json + // 修改main.js + let gameJsPath = path.join(projDir, "main.js"); + let gameJscontent = fs.readFileSync(gameJsPath, "utf8"); + gameJscontent = gameJscontent.replace(`require("${indexJsStr}");`, `requirePlugin('layaPlugin');\nrequire("${indexJsStr}");`); + fs.writeFileSync(gameJsPath, gameJscontent, "utf8"); + + // 修改manifest.json,使其支持引擎插件 + conJson.plugins = { + "laya-library": { + "version": EngineVersion, + "provider": "", + "path": "laya-library" + } + } + manifestJsonContent = JSON.stringify(conJson, null, 4); + fs.writeFileSync(manifestJsonPath, manifestJsonContent, "utf8"); + resolve(); + }).then(function() { + return new Promise(function(resolve, reject) { + console.log(`确定用到的插件引擎`); + // 2) 确定用到了那些插件引擎,并将插件引擎从index.js的引用中去掉 + let indexJsPath = path.join(projDir, indexJsStr); + let indexJsCon = fs.readFileSync(indexJsPath, "utf8"); + let item, fullRequireItem; + for (let i = 0, len = fullRemoteEngineList.length; i < len; i++) { + item = fullRemoteEngineList[i]; + fullRequireItem = config.useMinJsLibs ? `require("./libs/min/${item}")` : `require("./libs/${item}")`; + if (indexJsCon.includes(fullRequireItem)) { + localUseEngineList.push(item); + indexJsCon = indexJsCon.replace(fullRequireItem + ";", "").replace(fullRequireItem + ",", "").replace(fullRequireItem, ""); + } + } + // 源码项目需要特殊处理 + if (isNewTsProj || isOldAsProj) { + indexJsCon = indexJsCon.replace(`require("./laya.js");`, "").replace(`require("./laya.js"),`, "").replace(`require("./laya.js")`, ""); + let item, libPath/*, oppoConfigList = []*/; + for (let i = 0, len = fullRemoteEngineList.length; i < len; i++) { + item = fullRemoteEngineList[i]; + libPath = path.join(copyBinPath, item); + if (fs.existsSync(libPath) && !["bytebuffer", "laya.physics3D", "worker", "workerloader"].includes(item.replace(".min.js", "").replace(".js", ""))) { + localUseEngineList.push(item); + // config.useMinJsLibs ? oppoConfigList.push(`libs/min/${item}`) : oppoConfigList.push(`libs/${item}`); + } + } + // let bundleJsStr = (versionCon && versionCon["js/bundle.js"]) ? versionCon["js/bundle.js"] : "js/bundle.js"; + // oppoConfigList.push(bundleJsStr); + // configoppoConfigFile(oppoConfigList, true); + } + fs.writeFileSync(indexJsPath, indexJsCon, "utf8"); + // 再次修改game.js,仅引用使用到的类库 + let pluginCon = "", normalCon = ""; + localUseEngineList.forEach(function(item) { + pluginCon += `\trequirePlugin("laya-library/${item}");\n`; + normalCon += `\trequire("laya-library/${item}");\n`; + }); + let finalyPluginCon = `if (window.requirePlugin) {\n${pluginCon}\n} else {\n${normalCon}\n}`; + let gameJsPath = path.join(projDir, "main.js"); + let gameJsCon = fs.readFileSync(gameJsPath, "utf8"); + gameJsCon = gameJsCon.replace(`requirePlugin('layaPlugin');`, finalyPluginCon); + fs.writeFileSync(gameJsPath, gameJsCon, "utf8"); + resolve(); + }); + }).then(function() { + return new Promise(function(resolve, reject) { + console.log(`将本地的引擎插件移动到laya-libs中`); + // 3) 将本地的引擎插件移动到laya-libs中 + copyEnginePathList = [`${copyBinPath}/{${fullRemoteEngineList.join(",")}}`]; + gulp.src(copyEnginePathList).pipe(gulp.dest(`${projDir}/laya-library`)); + setTimeout(resolve, 500); + }); + }).then(function() { + return new Promise(function(resolve, reject) { + console.log(`将libs中的本地引擎插件删掉`); + // 4) 将libs中的本地引擎插件删掉 + let deleteList = [`${projDir}/libs/{${localUseEngineList.join(",")}}`, `${projDir}/libs/min/{${localUseEngineList.join(",")}}`]; + del(deleteList, { force: true }).then(resolve); + }); + }).then(function() { + return new Promise(async function(resolve, reject) { + console.log(`完善引擎插件目录`); + // 5) 引擎插件目录laya-libs中还需要新建几个文件,使该目录能够使用 + let + layalibsPath = path.join(projDir, "laya-library"), + engineIndex = path.join(layalibsPath, "index.js"), + engineplugin = path.join(layalibsPath, "plugin.json"); + // enginesignature = path.join(layalibsPath, "signature.json"); + // index.js + if (!fs.existsSync(layalibsPath)) { + throw new Error("引擎插件目录创建失败,请与服务提供商联系!"); + } + let layaLibraryList = fs.readdirSync(layalibsPath); + let indexCon = ""; + layaLibraryList.forEach(function(item) { + indexCon += `require("./${item}");\n`; + }); + fs.writeFileSync(engineIndex, indexCon, "utf8"); + // plugin.json + let pluginCon = {"main": "index.js"}; + fs.writeFileSync(engineplugin, JSON.stringify(pluginCon, null, 4), "utf8"); + // signature.json + // let signatureCon = { + // "provider": provider, + // "signature": [] + // }; + // localUseEngineList.unshift("index.js"); + // let fileName, md5Str; + // for (let i = 0, len = localUseEngineList.length; i < len; i++) { + // fileName = localUseEngineList[i]; + // let md5Str = await getFileMd5(path.join(projDir, "laya-library", fileName)); + // signatureCon.signature.push({ + // "path": fileName, + // "md5": md5Str + // }); + // } + // fs.writeFileSync(enginesignature, JSON.stringify(signatureCon, null, 4), "utf8"); + resolve(); + }); + }).catch(function(e) { + throw e; + }) + } +}); + +function downFileToDir(uri, dest){ + return new Promise((resolve, reject) => { + if (!uri || !dest) { + reject(new Error(`downFileToDir 参数不全: ${uri}/${dest}`)); + return; + } + + let + totalLen = 9999, + progress = 0, + layaresponse; + var stream = fs.createWriteStream(dest); + request(uri).on('error', function(err) { + console.log("tool down err:" + err); + reject(err); + }).on("data", function(data) { + progress += data.length; + let downPercent = (progress / totalLen * 100).toFixed(3); + // console.log(`down: ${downPercent}%`); + }).on("response", function(response) { + layaresponse = response; + totalLen = response.caseless.dict['content-length']; + }).pipe(stream).on('close', function() { + if (layaresponse.statusCode == 200) { + console.log("下载成功!"); + resolve(); + } else { + reject(new Error(`下载失败,连接关闭 -> ${uri}`)); + } + }); + }); +} + +function extractZipFile(zipPath, extractDir) { + return new Promise((resolve, reject) => { + if (!zipPath || !extractDir) { + reject(new Error(`extractZipFile 参数不全: ${zipPath}/${extractDir}`)); + return false; + } + + zipPath = `"${zipPath}"`; + let unzipexepath = path.join(ideModuleDir, "../", "out", "codeextension", "updateversion", "tools", "unzip.exe"); + unzipexepath = `"${unzipexepath}"`; + let cmd; + if (process.platform === 'darwin') { + cmd = "unzip -o " + zipPath + " -d " + "\"" + extractDir + "\""; + } else { + cmd = unzipexepath + " -o " + zipPath + " -d " + "\"" + extractDir + "\""; + } + childProcess.exec(cmd, (error, stdout, stderr) => { + if (error || stderr) { + reject(error || stderr); + return; + } + resolve(); + }); + }); +} + +// 打包rpk +gulp.task("buildRPK_OPPO", ["pluginEngin_OPPO"], function() { + // 在OPPO轻游戏项目目录中执行: + // quickgame pack || quickgame pack release + // quickgame subpack --no-build-js || quickgame subpack release --no-build-js + let cmdStr = ""; + let packStr = "pack"; + let nobuildjs = ""; + if (config.oppoInfo.subpack) { + packStr = "subpack"; + nobuildjs = "--no-build-js"; + } + if (config.oppoInfo.useReleaseSign) { + cmdStr = "release"; + } + return new Promise((resolve, reject) => { + let cmd = path.join(toolkitPath, "lib", "bin", `quickgame${commandSuffix}`); + let args = [packStr, cmdStr, nobuildjs]; + let opts = { + cwd: projDir, + shell: true + }; + let cp = childProcess.spawn(`"${cmd}"`, args, opts); + // let cp = childProcess.spawn('npx.cmd', ['-v']); + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + console.log(`stderr(iconv): ${iconv.decode(data, 'gbk')}`); + // reject(); + }); + + cp.on('close', (code) => { + console.log(`子进程退出码:${code}`); + // rpk是否生成成功 + let distRpkPath = path.join(projDir, "dist", `${config.oppoInfo.package}${config.oppoInfo.useReleaseSign ? ".signed" : ""}.rpk`); + if (!fs.existsSync(distRpkPath)) { + throw new Error("rpk生成失败,请检查!"); + } + resolve(); + }); + }); +}); + +gulp.task("pushRPK_OPPO", ["buildRPK_OPPO"], function() { + if (!config.oppoInfo.adbDebug) { + return; + } + // 在OPPO轻游戏项目目录中执行: + // adb push dist/game.rpk sdcard/games + // adb push layarepublicPath/oppo/instant_app_settings.properties + // adb shell am force-stop com.nearme.instant.platform + // adb shell am start -n com.nearme.instant.platform/com.oppo.autotest.main.InstantAppActivity + return new Promise((resolve, reject) => { + if (!config.oppoInfo.subpack) { + return resolve(); + } + + let cmd = `${adbPath}`; + let args = ["shell", "mkdir", `sdcard/subPkg`]; + let opts = { + cwd: projDir, + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + // let cp = childProcess.spawn('npx.cmd', ['-v']); + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + // reject(); + }); + + cp.on('close', (code) => { + console.log(`pre) push_RPK 子进程退出码:${code}`); + resolve(); + }); + }).then(() => { + + + return new Promise((resolve, reject) => { + if (!config.uesEnginePlugin) { + resolve(); + return; + }else { + // 如果使用引擎插件,解压完整包 + let distRpkPath = path.join(projDir, "dist", `${config.oppoInfo.package}${config.oppoInfo.useReleaseSign ? ".signed" : ""}.rpk`); + console.log("解压完整包",distRpkPath); + let tmpDir = path.join(projDir, "dist", `tmp`); + if (!fs.existsSync(tmpDir)) { + fs.mkdirSync(tmpDir); + } + extractZipFile(distRpkPath, tmpDir).then(() => { + console.log('解压完整包完成'); + resolve(); + }); + } + }) + }).then(() => { + return new Promise((resolve, reject) => { + let cmd = `${adbPath}`; + let sdGamesPath = config.oppoInfo.subpack ? "sdcard/subPkg" : "sdcard/games"; + let args = ["push", `dist${config.uesEnginePlugin ?"/tmp" : "" }/${config.oppoInfo.package}${config.oppoInfo.useReleaseSign ? ".signed" : ""}.rpk`, sdGamesPath]; + let opts = { + cwd: projDir, + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + // let cp = childProcess.spawn('npx.cmd', ['-v']); + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + // reject(); + }); + + cp.on('close', (code) => { + console.log(`1) push_RPK 子进程退出码:${code}`); + resolve(); + }); + }) + }).then(() => { + return new Promise((resolve, reject) => { + // 如果是分包,需要修改里面的内容 + let oppoPropPath = path.join(layarepublicPath, "oppo", "instant_app_settings.properties"); + if (config.oppoInfo.subpack) { + fs.writeFileSync(oppoPropPath, "default_tab=game_split", "utf8"); + } else { + fs.writeFileSync(oppoPropPath, "default_tab=game", "utf8"); + } + let cmd = `${adbPath}`; + let args = ["push", oppoPropPath, "sdcard/"]; + let opts = { + cwd: projDir, + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + // let cp = childProcess.spawn('npx.cmd', ['-v']); + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + // reject(); + }); + + cp.on('close', (code) => { + console.log(`2) push_RPK 子进程退出码:${code}`); + resolve(); + }); + }); + }).then(() => { + return new Promise((resolve, reject) => { + let cmd = `${adbPath}`; + let args = ["shell", "am", "force-stop", "com.nearme.instant.platform"]; + let opts = { + cwd: projDir, + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + // let cp = childProcess.spawn('npx.cmd', ['-v']); + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + // reject(); + }); + + cp.on('close', (code) => { + console.log(`3) push_RPK 子进程退出码:${code}`); + resolve(); + }); + }); + }).then(() => { + return new Promise((resolve, reject) => { + let cmd = `${adbPath}`; + let args = ["shell", "am", "start", "-n", "com.nearme.instant.platform/com.oppo.autotest.main.InstantAppActivity"]; + let opts = { + cwd: projDir, + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + // let cp = childProcess.spawn('npx.cmd', ['-v']); + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + // reject(); + }); + + cp.on('close', (code) => { + console.log(`4) push_RPK 子进程退出码:${code}`); + resolve(); + }); + }); + }); +}); + +gulp.task("buildOPPOProj", ["pushRPK_OPPO"], function() { + console.log("all tasks completed"); +}); \ No newline at end of file diff --git a/examples/layaair/frontend/.laya/publish_qqgame.js b/examples/layaair/frontend/.laya/publish_qqgame.js new file mode 100644 index 0000000..75651b2 --- /dev/null +++ b/examples/layaair/frontend/.laya/publish_qqgame.js @@ -0,0 +1,296 @@ +// v1.8.7 +const ideModuleDir = global.ideModuleDir; +const workSpaceDir = global.workSpaceDir; + +//引用插件模块 +const gulp = require(ideModuleDir + "gulp"); +const fs = require("fs"); +const path = require("path"); +const del = require(ideModuleDir + "del"); +const revCollector = require(ideModuleDir + 'gulp-rev-collector'); +const { getEngineVersion, getFileMd5, canUsePluginEngine } = require("./pub_utils"); + +const provider = "1109625052"; +const minPluginVersion = "2.1.1"; +let fullRemoteEngineList = ["laya.core.js", "laya.filter.js", "laya.ani.js", "laya.tiledmap.js", "laya.d3.js", "laya.html.js", "laya.particle.js", "laya.ui.js", "laya.webgl.js", "laya.filter.js", "laya.d3Plugin.js"]; +let copyLibsTask = ["copyPlatformLibsJsFile"]; +let versiontask = ["version2"]; + +let + config, + releaseDir; +let versionCon; // 版本管理version.json +let commandSuffix, + layarepublicPath; + +gulp.task("preCreate_QQ", copyLibsTask, function() { + releaseDir = global.releaseDir; + config = global.config; + commandSuffix = global.commandSuffix; + layarepublicPath = global.layarepublicPath; + + if (config.useMinJsLibs) { + fullRemoteEngineList = fullRemoteEngineList.map((item, index) => { + return item.replace(".js", ".min.js"); + }) + } +}); + +gulp.task("copyPlatformFile_QQ", ["preCreate_QQ"], function() { + let adapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "qqfiles"); + let hasPublishPlatform = + fs.existsSync(path.join(releaseDir, "game.js")) && + fs.existsSync(path.join(releaseDir, "game.json")) && + fs.existsSync(path.join(releaseDir, "project.config.json")); + let copyLibsList; + if (hasPublishPlatform) { + copyLibsList = [`${adapterPath}/weapp-adapter.js`]; + } else { + copyLibsList = [`${adapterPath}/*.*`]; + } + var stream = gulp.src(copyLibsList); + return stream.pipe(gulp.dest(releaseDir)); +}); + +gulp.task("modifyFile_QQ", versiontask, function() { + // 修改game.json文件 + let gameJsonPath = path.join(releaseDir, "game.json"); + let content = fs.readFileSync(gameJsonPath, "utf8"); + let conJson = JSON.parse(content); + conJson.deviceOrientation = config.qqInfo.orientation; + content = JSON.stringify(conJson, null, 4); + fs.writeFileSync(gameJsonPath, content, "utf8"); + + if (config.version) { + let versionPath = releaseDir + "/version.json"; + versionCon = fs.readFileSync(versionPath, "utf8"); + versionCon = JSON.parse(versionCon); + } + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + // QQ小游戏项目,修改index.js + let filePath = path.join(releaseDir, indexJsStr); + if (!fs.existsSync(filePath)) { + return; + } + let fileContent = fs.readFileSync(filePath, "utf8"); + fileContent = fileContent.replace(/loadLib(\(['"])/gm, "require$1./"); + fs.writeFileSync(filePath, fileContent, "utf8"); +}); + +gulp.task("modifyMinJs_QQ", ["modifyFile_QQ"], function() { + // 如果保留了平台文件,如果同时取消使用min类库,就会出现文件引用不正确的问题 + if (config.keepPlatformFile) { + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/min\/laya(-[\w\d]+)?\.qqmini\.min\.js/gm, "laya.qqmini.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + } + if (!config.useMinJsLibs) { + return; + } + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/(min\/)?laya(-[\w\d]+)?\.qqmini(\.min)?\.js/gm, "min/laya.qqmini.min.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); +}); + +gulp.task("version_QQ", ["modifyMinJs_QQ"], function() { + // 如果保留了平台文件,如果同时开启版本管理,就会出现文件引用不正确的问题 + if (config.keepPlatformFile) { + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/laya(-[\w\d]+)?\.qqmini/gm, "laya.qqmini"); + content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + } + if (config.version) { + let versionPath = releaseDir + "/version.json"; + let gameJSPath = releaseDir + "/game.js"; + let srcList = [versionPath, gameJSPath]; + return gulp.src(srcList) + .pipe(revCollector()) + .pipe(gulp.dest(releaseDir)); + } +}); + +gulp.task("pluginEngin_QQ", ["version_QQ"], function(cb) { + if (!config.uesEnginePlugin) { // 没有使用引擎插件,还是像以前一样发布 + let gameJsonPath = path.join(releaseDir, "game.json"); + let gameJsonContent = fs.readFileSync(gameJsonPath, "utf8"); + let conJson = JSON.parse(gameJsonContent); + if (conJson.plugins) { + delete conJson.plugins; + gameJsonContent = JSON.stringify(conJson, null, 4); + fs.writeFileSync(gameJsonPath, gameJsonContent, "utf8"); + + let gameJsPath = path.join(releaseDir, "game.js"); + let gameJscontent = fs.readFileSync(gameJsPath, "utf8"); + gameJscontent = gameJscontent.replace(/requirePlugin\("[\w\/\.]+"\);?\n?/mg, ""); + fs.writeFileSync(gameJsPath, gameJscontent, "utf8"); + } + return cb(); + } + if (config.version) { + let versionPath = releaseDir + "/version.json"; + versionCon = fs.readFileSync(versionPath, "utf8"); + versionCon = JSON.parse(versionCon); + } + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + + // 获取version等信息 + let coreLibPath = path.join(workSpaceDir, "bin", "libs", "laya.core.js"); + let isHasCoreLib = fs.existsSync(coreLibPath); + let isOldAsProj = fs.existsSync(`${workSpaceDir}/asconfig.json`) && !isHasCoreLib; + let isNewTsProj = fs.existsSync(`${workSpaceDir}/src/tsconfig.json`) && !isHasCoreLib; + let EngineVersion = getEngineVersion(); + if (!EngineVersion) { + throw new Error(`读取引擎版本号失败,请于服务提供商联系!`); + } + if (!EngineVersion || EngineVersion.includes("beta") || !canUsePluginEngine(EngineVersion, minPluginVersion)) { + throw new Error(`该版本引擎无法使用引擎插件功能(engineVersion: ${EngineVersion})`); + } + console.log(`通过版本号检查: ${EngineVersion}`); + // 使用引擎插件 + let localUseEngineList = []; + let copyEnginePathList; + new Promise(function(resolve, reject) { + console.log(`修改game.js和game.json`); + // 1) 修改game.js和game.json + // 修改game.js + let gameJsPath = path.join(releaseDir, "game.js"); + let platformJs = config.useMinJsLibs ? `require("./libs/min/laya.qqmini.min.js");` : `require("./libs/laya.qqmini.js");`; + let gameJscontent = `require("weapp-adapter.js");\n${platformJs}\nrequirePlugin('layaPlugin');\nwindow.loadLib = require;\nrequire("./${indexJsStr}");`; + fs.writeFileSync(gameJsPath, gameJscontent, "utf8"); + // 修改game.json,使其支持引擎插件 + let gameJsonPath = path.join(releaseDir, "game.json"); + let gameJsonContent = fs.readFileSync(gameJsonPath, "utf8"); + let conJson = JSON.parse(gameJsonContent); + conJson.plugins = { + "layaPlugin": { + "version": EngineVersion, + "provider": provider, + "path": "laya-libs" + } + } + gameJsonContent = JSON.stringify(conJson, null, 4); + fs.writeFileSync(gameJsonPath, gameJsonContent, "utf8"); + resolve(); + }).then(function() { + return new Promise(function(resolve, reject) { + console.log(`确定用到的插件引擎`); + // 2) 确定用到了那些插件引擎,并将插件引擎从index.js的引用中去掉 + let indexJsPath = path.join(releaseDir, indexJsStr); + let indexJsCon = fs.readFileSync(indexJsPath, "utf8"); + let item, fullRequireItem; + for (let i = 0, len = fullRemoteEngineList.length; i < len; i++) { + item = fullRemoteEngineList[i]; + fullRequireItem = config.useMinJsLibs ? `require("./libs/min/${item}")` : `require("./libs/${item}")`; + if (indexJsCon.includes(fullRequireItem)) { + let _item = item.replace(".min.js", ".js"), _minItem = item; + localUseEngineList.push(_item); + indexJsCon = indexJsCon.replace(fullRequireItem + ";", "").replace(fullRequireItem + ",", "").replace(fullRequireItem, ""); + // 如果引用了压缩的类库,将其重命名为未压缩的类库,并拷贝到libs中 + if (config.useMinJsLibs) { + let oldMinlibPath = path.join(releaseDir, "libs", "min", _minItem); + let newMinlibPath = path.join(releaseDir, "libs", "min", _item); + let newlibPath = path.join(releaseDir, "libs", _item); + fs.renameSync(oldMinlibPath, newMinlibPath); + // fs.copyFileSync(newlibPath, newMinlibPath); + let con = fs.readFileSync(newMinlibPath, "utf8"); + fs.writeFileSync(newlibPath, con, "utf8"); + fs.unlinkSync(newMinlibPath); + } + } + } + if (isOldAsProj || isNewTsProj) { // 如果as||ts_new语言,开发者将laya.js也写入index.js中了,将其删掉 + fullRequireItem = `require("./laya.js")`; + if (indexJsCon.includes(fullRequireItem)) { + indexJsCon = indexJsCon.replace(fullRequireItem + ";", "").replace(fullRequireItem + ",", "").replace(fullRequireItem, ""); + } + } + fs.writeFileSync(indexJsPath, indexJsCon, "utf8"); + // ts/js再次修改game.js,仅引用使用到的类库 + // as||ts_new因为本地只有laya.js,无法仅引用使用到的类库 + if (!isOldAsProj && !isNewTsProj) { + let pluginCon = ""; + localUseEngineList.forEach(function(item) { + pluginCon += `requirePlugin("layaPlugin/${item}");\n`; + }); + let gameJsPath = path.join(releaseDir, "game.js"); + let gameJsCon = fs.readFileSync(gameJsPath, "utf8"); + gameJsCon = gameJsCon.replace(`requirePlugin('layaPlugin');`, pluginCon); + fs.writeFileSync(gameJsPath, gameJsCon, "utf8"); + } + resolve(); + }); + }).then(function() { + return new Promise(function(resolve, reject) { + console.log(`将本地的引擎插件移动到laya-libs中`); + // 3) 将本地的引擎插件移动到laya-libs中 + let libsPath = /** config.useMinJsLibs ? `${releaseDir}/libs/min` : */`${releaseDir}/libs`; + copyEnginePathList = [`${libsPath}/{${localUseEngineList.join(",")}}`]; + if (isOldAsProj || isNewTsProj) { // 单独拷贝laya.js + copyEnginePathList = [`${releaseDir}/laya.js`]; + } + gulp.src(copyEnginePathList).pipe(gulp.dest(`${releaseDir}/laya-libs`)); + setTimeout(resolve, 500); + }); + }).then(function() { + return new Promise(function(resolve, reject) { + console.log(`将libs中的本地引擎插件删掉`); + // 4) 将libs中的本地引擎插件删掉 + del(copyEnginePathList, { force: true }).then(resolve); + }); + }).then(function() { + return new Promise(async function(resolve, reject) { + console.log(`完善引擎插件目录`); + // 5) 引擎插件目录laya-libs中还需要新建几个文件,使该目录能够使用 + if (isOldAsProj || isNewTsProj) { // 单独拷贝laya.js + localUseEngineList.push("laya.js"); + } + let + layalibsPath = path.join(releaseDir, "laya-libs"), + engineIndex = path.join(layalibsPath, "index.js"), + engineplugin = path.join(layalibsPath, "plugin.json"), + enginesignature = path.join(layalibsPath, "signature.json"); + // index.js + if (!fs.existsSync(layalibsPath)) { + throw new Error("引擎插件目录创建失败,请与服务提供商联系!"); + } + let indexCon = ""; + localUseEngineList.forEach(function(item) { + indexCon += `require("./${item}");\n`; + }); + fs.writeFileSync(engineIndex, indexCon, "utf8"); + // plugin.json + let pluginCon = {"main": "index.js"}; + fs.writeFileSync(engineplugin, JSON.stringify(pluginCon, null, 4), "utf8"); + // signature.json,目前平台方将其作为保留用途,不会做插件的md5校验;IDE仍将生成md5 + let signatureCon = { + "provider": provider, + "signature": [] + }; + localUseEngineList.unshift("index.js"); + let fileName, md5Str; + for (let i = 0, len = localUseEngineList.length; i < len; i++) { + fileName = localUseEngineList[i]; + let md5Str = await getFileMd5(path.join(releaseDir, "laya-libs", fileName)); + signatureCon.signature.push({ + "path": fileName, + "md5": md5Str + }); + } + fs.writeFileSync(enginesignature, JSON.stringify(signatureCon, null, 4), "utf8"); + resolve(); + }); + }) + .then(function() { + cb(); + }).catch(function(e) { + throw e; + }) +}); + +gulp.task("buildQQProj", ["pluginEngin_QQ"], function() { + console.log("all tasks completed"); +}); \ No newline at end of file diff --git a/examples/layaair/frontend/.laya/publish_taobaominiapp.js b/examples/layaair/frontend/.laya/publish_taobaominiapp.js new file mode 100644 index 0000000..7809120 --- /dev/null +++ b/examples/layaair/frontend/.laya/publish_taobaominiapp.js @@ -0,0 +1,265 @@ +// v1.1.5 +const ideModuleDir = global.ideModuleDir; +const workSpaceDir = global.workSpaceDir; + +//引用插件模块 +const gulp = require(ideModuleDir + "gulp"); +const fs = require("fs"); +const path = require("path"); +const del = require(ideModuleDir + "del"); +const revCollector = require(ideModuleDir + 'gulp-rev-collector'); + +let copyLibsTask = ["copyPlatformLibsJsFile"]; +let versiontask = ["version2"]; + +let + config, + releaseDir, + tempReleaseDir; +let versionCon; // 版本管理version.json +let commandSuffix, + layarepublicPath; + +let subList = []; + +gulp.task("preCreate_TBMini", copyLibsTask, function() { + releaseDir = global.releaseDir; + tempReleaseDir = global.tempReleaseDir; + config = global.config; + commandSuffix = global.commandSuffix; + layarepublicPath = global.layarepublicPath; +}); + +gulp.task("copyPlatformFile_TBMini", versiontask, function() { + releaseDir = path.dirname(releaseDir); + let adapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "taobaofiles"); + let hasPublishPlatform = + fs.existsSync(path.join(releaseDir, "app.js")) && + fs.existsSync(path.join(releaseDir, "app.json")) && + fs.existsSync(path.join(releaseDir, "package.json")); + let copyLibsList; + if (hasPublishPlatform) { + copyLibsList = [`${adapterPath}/node_modules/layaengine/adapter.js`]; + } else { + copyLibsList = [`${adapterPath}/**/*.*`]; + } + var stream = gulp.src(copyLibsList, {base: adapterPath}); + return stream.pipe(gulp.dest(releaseDir)); +}); + +gulp.task("copyFiles2Pages_TBMini", ["copyPlatformFile_TBMini"], function() { + return gulp.src([`${tempReleaseDir}/**/*.*`, `!${tempReleaseDir}/libs/**/*.*`]).pipe(gulp.dest(`${releaseDir}/pages/index`)); +}); + +gulp.task("moveToLibs_TBMini", ["copyFiles2Pages_TBMini"], function() { + let libsPath = path.join(tempReleaseDir, "libs"); + let layaenginePath = path.join(releaseDir, "node_modules", "layaengine", "libs"); + return gulp.src(`${libsPath}/**/*.*`) + .pipe(gulp.dest(layaenginePath)); +}); + +gulp.task("delFiles_TBMini", ["moveToLibs_TBMini"], function(cb) { + let delList = [`${tempReleaseDir}/**`]; + del(delList, { force: true }).then(paths => { + cb(); + }).catch((err) => { + throw err; + }) +}); + +gulp.task("modifyFile_TBMini", ["delFiles_TBMini"], function() { + if (config.version || config.enableVersion) { + let versionPath = path.join(releaseDir, "pages", "index", "version.json"); + versionCon = fs.readFileSync(versionPath, "utf-8"); + versionCon = JSON.parse(versionCon); + } + + // 修改 app.json mini.project.json 文件 + let miniProJJsonPath = path.join(releaseDir, "mini.project.json"); + let minicontent = fs.readFileSync(miniProJJsonPath, "utf8"); + let miniConJson = JSON.parse(minicontent); + let appJsonPath = path.join(releaseDir, "app.json"); + let content = fs.readFileSync(appJsonPath, "utf8"); + let conJson = JSON.parse(content); + // 先删掉之前的记录 + delete conJson.subPackages; + delete conJson.subPackageBuildType; + delete miniConJson.enableEnhancedBuild; + let index = 0, value; + while(miniConJson.include.length > index) { + value = miniConJson.include[index]; + if (value.match(/[\w]+\/\*\*/mg)) { + miniConJson.include.splice(index, 1); + continue; + } + index++; + } + if (config.taobaoInfo.subpack) { // 分包 + let subpack = config.taobaoSubpack; + let subitem, obj; + conJson.subPackages = []; + for (let i = 0, len = subpack.length; i < len; i++) { + subitem = subpack[i]; + obj = { + "root": subitem.name + }; + if (config.taobaoInfo.ispagesub) { // 页面分包 + if (!subitem.root) continue; + obj.pages = subitem.root.split(",") + } else { // 资源分包 + conJson.subPackageBuildType = "shared"; + miniConJson.enableEnhancedBuild = true; + if (!miniConJson.include) miniConJson.include = []; + miniConJson.include.push(`${subitem.name}/**`); + } + conJson.subPackages.push(obj); + } + } + content = JSON.stringify(conJson, null, 4); + fs.writeFileSync(appJsonPath, content, "utf8"); + minicontent = JSON.stringify(miniConJson, null, 4); + fs.writeFileSync(miniProJJsonPath, minicontent, "utf8"); + + // 修改index.js + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + let indexFilePath = path.join(releaseDir, "pages", "index", indexJsStr); + if (!fs.existsSync(indexFilePath)) { + return; + } + let indexFileContent = fs.readFileSync(indexFilePath, "utf-8"); + indexFileContent = indexFileContent.replace(/(window.screenOrientation\s*=\s*"\w+"[,;]?)/gm, "/**$1*/"); + indexFileContent = indexFileContent.replace(/loadLib(\(['"]libs\/)/gm, `require("layaengine/libs/`); + indexFileContent = indexFileContent.replace(/loadLib(\(['"])/gm, "require$1./"); + indexFileContent = indexFileContent.replace(/require\(\"\.\/laya([-\w]*)\.js\"\)/gm, `require("layaengine/laya$1.js")`); + // 特殊的,增加清除缓存 + indexFileContent = indexFileContent.replace(/(require(\(['"][\w\/\.]+['"]\));?)/gm, "delete require.cache[require.resolve$2];\n$1"); + fs.writeFileSync(indexFilePath, indexFileContent, "utf-8"); +}) + +gulp.task("movesubpack_TBMini", ["modifyFile_TBMini"], function() { + if (!config.taobaoInfo.subpack) { // 分包 + return; + } + let subpack = config.taobaoSubpack; + let subitem, obj; + // conJson.subPackages = []; + for (let i = 0, len = subpack.length; i < len; i++) { + subitem = subpack[i]; + subList.push(`${subitem.name}/**`); + } + let source = `${path.join(releaseDir, "pages", "index")}/${subList.length > 1 ? `{${subList.join(",")}}` : `${subList[0]}`}`; + return gulp.src(source, { base: path.join(releaseDir, "pages", "index") }).pipe(gulp.dest(releaseDir)); +}) + +gulp.task("rmsubpack_TBMini", ["movesubpack_TBMini"], function(cb) { + if (!config.taobaoInfo.subpack || subList.length == 0) { // 分包 + return cb(); + } + let delList = []; + for (let i = 0, len = subList.length; i < len; i++) { + delList.push(`${releaseDir}/pages/index/${subList[i]}`); + } + console.log(delList); + del(delList, { force: true }).then(paths => { + cb(); + }).catch((err) => { + throw err; + }) +}); + +gulp.task("modifyMinJs_TBMini", ["rmsubpack_TBMini"], function() { + // 如果保留了平台文件,如果同时取消使用min类库,就会出现文件引用不正确的问题 + if (config.keepPlatformFile) { + let fileJsPath = path.join(releaseDir, "pages", "index", "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/min\/laya(-[\w\d]+)?\.tbmini\.min\.js/gm, "laya.tbmini.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + } + if (!config.useMinJsLibs) { + return; + } + let fileJsPath = path.join(releaseDir, "pages", "index", "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/(min\/)?laya(-[\w\d]+)?\.tbmini(\.min)?\.js/gm, "min/laya.tbmini.min.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); +}); + +gulp.task("modifyLibsJs_TBMini", ["modifyMinJs_TBMini"], function() { + const NONCORESTR = "var window = $global.window;\nvar document = window.document;\nvar XMLHttpRequest = window.XMLHttpRequest;\nvar Laya = window.Laya;\nvar Config = window.Config;\nvar Config3D = window.Config3D;\nvar Laya3D = window.Laya3D;\nvar performance = window.performance;\nvar CANNON = window.CANNON;\nvar spine = window.spin;\n"; + const CORESTR = "var window = $global.window;\nvar document = window.document;\nvar XMLHttpRequest = window.XMLHttpRequest;\n"; + // libs + let libsPath = path.join(releaseDir, "node_modules", "layaengine", "libs", config.useMinJsLibs ? "min" : ""); + let libsList = fs.readdirSync(libsPath); + for (let libName, fullPath, con, len = libsList.length, i = 0; i < len; i++) { + libName = libsList[i]; + fullPath = path.join(libsPath, libName); + con = fs.readFileSync(fullPath, "utf8"); + if (/laya(-[\w\d]+)?\.core/gm.test(libName)) { + con = CORESTR + con; + } else { + con = NONCORESTR + con; + } + fs.writeFileSync(fullPath, con, "utf8"); + } + // bundle.js + let bundleJsStr = (versionCon && versionCon["js/bundle.js"]) ? versionCon["js/bundle.js"] : "js/bundle.js"; + let bundlePath = path.join(releaseDir, "pages", "index", bundleJsStr); + let con = fs.readFileSync(bundlePath, "utf8"); + // as 侵入式的修改bundle.js + if (fs.existsSync(path.join(workSpaceDir, "asconfig.json"))) { + let fileList = fs.readdirSync(path.join(workSpaceDir, "src")); + for (let i = 0, len = fileList.length, fileItem, filePath, isDir; i < len; i++) { + fileItem = fileList[i]; + filePath = path.join(workSpaceDir, "src", fileItem); + isDir = fs.statSync(filePath).isDirectory(); + if (isDir && (con.includes(`window.${fileItem} = {};`) || con.includes(`window.${fileItem}={}`))) { + // 因为压缩时不能禁用逗号,只能穷尽所有可能 + con = con.replace(`window.${fileItem} = {};`, `var ${fileItem} = window.${fileItem} = {};`) + .replace(`;window.${fileItem}={};`, `;var ${fileItem}=window.${fileItem}={};`) + .replace(`,window.${fileItem}={};`, `;var ${fileItem}=window.${fileItem}={};`) + .replace(`,window.${fileItem}={},`, `;var ${fileItem}=window.${fileItem}={};`) + .replace(`;window.${fileItem}={},`, `;var ${fileItem}=window.${fileItem}={};`) + if (!con.includes(`;var ${fileItem}=window.${fileItem}={};`)) { + con = con.replace(`window.${fileItem}={}`, `;var ${fileItem}=window.${fileItem}={};`) + } + } + } + } + con = NONCORESTR + con; + fs.writeFileSync(bundlePath, con, "utf8"); + // laya.js + let layaJsStr = (versionCon && versionCon["laya.js"]) ? versionCon["laya.js"] : "laya.js"; + let layaPath = path.join(releaseDir, "pages", "index", layaJsStr); + if (fs.existsSync(layaPath)) { + let con = fs.readFileSync(layaPath, "utf8"); + con = CORESTR + con; + + // 移动到 layaengine 下 + let newLayaPath = path.join(releaseDir, "node_modules", "layaengine", layaJsStr); + fs.writeFileSync(newLayaPath, con, "utf8"); + fs.unlinkSync(layaPath); + } +}); + +gulp.task("version_TBMini", ["modifyLibsJs_TBMini"], function() { + // 如果保留了平台文件,如果同时开启版本管理,就会出现文件引用不正确的问题 + if (config.keepPlatformFile) { + let fileJsPath = path.join(releaseDir, "pages", "index", "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/laya(-[\w\d]+)?\.tbmini/gm, "laya.tbmini"); + content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + } + if (config.version) { + let versionPath = path.join(releaseDir, "pages", "index", "version.json"); + let gameJSPath = path.join(releaseDir, "pages", "index", "game.js"); + let srcList = [versionPath, gameJSPath]; + return gulp.src(srcList) + .pipe(revCollector()) + .pipe(gulp.dest(`${releaseDir}/pages/index`)); + } +}); + +gulp.task("buildTBMiniProj", ["version_TBMini"], function() { + console.log("all tasks completed"); +}); \ No newline at end of file diff --git a/examples/layaair/frontend/.laya/publish_taobaowidget.js b/examples/layaair/frontend/.laya/publish_taobaowidget.js new file mode 100644 index 0000000..c07e495 --- /dev/null +++ b/examples/layaair/frontend/.laya/publish_taobaowidget.js @@ -0,0 +1,177 @@ +// v1.0.2 +const ideModuleDir = global.ideModuleDir; +const workSpaceDir = global.workSpaceDir; + +//引用插件模块 +const gulp = require(ideModuleDir + "gulp"); +const fs = require("fs"); +const path = require("path"); +const del = require(ideModuleDir + "del"); +const revCollector = require(ideModuleDir + 'gulp-rev-collector'); + +let copyLibsTask = ["copyPlatformLibsJsFile"]; +let versiontask = ["version2"]; + +let + config, + releaseDir, + tempReleaseDir; +let versionCon; // 版本管理version.json +let commandSuffix, + layarepublicPath; + +gulp.task("preCreate_TBWidget", copyLibsTask, function() { + releaseDir = global.releaseDir; + tempReleaseDir = global.tempReleaseDir; + config = global.config; + commandSuffix = global.commandSuffix; + layarepublicPath = global.layarepublicPath; +}); + +gulp.task("copyPlatformFile_TBWidget", versiontask, function() { + releaseDir = path.dirname(releaseDir); + let adapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "taobaowidgetfiles"); + let hasPublishPlatform = + fs.existsSync(path.join(releaseDir, "client")) && + fs.existsSync(path.join(releaseDir, "widget")) && + fs.existsSync(path.join(releaseDir, "mini.project.json")); + let copyLibsList; + if (hasPublishPlatform) { + copyLibsList = [`${adapterPath}/widget/component/adapter.js`]; + } else { + copyLibsList = [`${adapterPath}/**/*.*`]; + } + var stream = gulp.src(copyLibsList, {base: adapterPath}); + return stream.pipe(gulp.dest(releaseDir)); +}); + +gulp.task("copyFiles2Pages_TBWidget", ["copyPlatformFile_TBWidget"], function() { + return gulp.src(`${tempReleaseDir}/**/*.*`).pipe(gulp.dest(`${releaseDir}/widget/component`)); +}); + +gulp.task("delFiles_TBWidget", ["copyFiles2Pages_TBWidget"], function(cb) { + let delList = [`${tempReleaseDir}/**`]; + del(delList, { force: true }).then(paths => { + cb(); + }).catch((err) => { + throw err; + }) +}); + +gulp.task("modifyFile_TBWidget", ["delFiles_TBWidget"], function() { + if (config.version || config.enableVersion) { + let versionPath = path.join(releaseDir, "widget", "component", "version.json"); + versionCon = fs.readFileSync(versionPath, "utf-8"); + versionCon = JSON.parse(versionCon); + } + // 修改index.js + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + let indexFilePath = path.join(releaseDir, "widget", "component", indexJsStr); + if (!fs.existsSync(indexFilePath)) { + return; + } + let indexFileContent = fs.readFileSync(indexFilePath, "utf-8"); + indexFileContent = indexFileContent.replace(/(window.screenOrientation\s*=\s*"\w+"[,;]?)/gm, "/**$1*/"); + indexFileContent = indexFileContent.replace(/loadLib(\(['"]libs\/)/gm, `require("./libs/`); + indexFileContent = indexFileContent.replace(/loadLib(\(['"])/gm, "require$1./"); + indexFileContent = indexFileContent.replace(/require\(\"\.\/laya([-\w]*)\.js\"\)/gm, `require("./laya$1.js")`); + // 特殊的,增加清除缓存 + indexFileContent = indexFileContent.replace(/(require(\(['"][\w\/\.]+['"]\));?)/gm, "delete require.cache[require.resolve$2];\n$1"); + fs.writeFileSync(indexFilePath, indexFileContent, "utf-8"); +}) + +gulp.task("modifyMinJs_TBWidget", ["modifyFile_TBWidget"], function() { + // 如果保留了平台文件,如果同时取消使用min类库,就会出现文件引用不正确的问题 + if (config.keepPlatformFile) { + let fileJsPath = path.join(releaseDir, "widget", "component", "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/min\/laya(-[\w\d]+)?\.tbpluginmini\.min\.js/gm, "laya.tbpluginmini.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + } + if (!config.useMinJsLibs) { + return; + } + let fileJsPath = path.join(releaseDir, "widget", "component", "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/(min\/)?laya(-[\w\d]+)?\.tbpluginmini(\.min)?\.js/gm, "min/laya.tbpluginmini.min.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); +}); + +gulp.task("modifyLibsJs_TBWidget", ["modifyMinJs_TBWidget"], function() { + const NONCORESTR = "var window = $global.window;\nvar document = window.document;\nvar XMLHttpRequest = window.XMLHttpRequest;\nvar Laya = window.Laya;\nvar Config = window.Config;\nvar Config3D = window.Config3D;\nvar Laya3D = window.Laya3D;\nvar performance = window.performance;\nvar CANNON = window.CANNON;\nvar spine = window.spin;\n"; + const CORESTR = "var window = $global.window;\nvar document = window.document;\nvar XMLHttpRequest = window.XMLHttpRequest;\n"; + // libs + let libsPath = path.join(releaseDir, "widget", "component", "libs", config.useMinJsLibs ? "min" : ""); + let libsList = fs.readdirSync(libsPath); + for (let libName, fullPath, con, len = libsList.length, i = 0; i < len; i++) { + libName = libsList[i]; + fullPath = path.join(libsPath, libName); + if (path.extname(fullPath) !== ".js") { + continue; + } + con = fs.readFileSync(fullPath, "utf8"); + if (/laya(-[\w\d]+)?\.core/gm.test(libName)) { + con = CORESTR + con; + } else { + con = NONCORESTR + con; + } + fs.writeFileSync(fullPath, con, "utf8"); + } + // bundle.js + let bundleJsStr = (versionCon && versionCon["js/bundle.js"]) ? versionCon["js/bundle.js"] : "js/bundle.js"; + let bundlePath = path.join(releaseDir, "widget", "component", bundleJsStr); + let con = fs.readFileSync(bundlePath, "utf8"); + // as 侵入式的修改bundle.js + if (fs.existsSync(path.join(workSpaceDir, "asconfig.json"))) { + let fileList = fs.readdirSync(path.join(workSpaceDir, "src")); + for (let i = 0, len = fileList.length, fileItem, filePath, isDir; i < len; i++) { + fileItem = fileList[i]; + filePath = path.join(workSpaceDir, "src", fileItem); + isDir = fs.statSync(filePath).isDirectory(); + if (isDir && (con.includes(`window.${fileItem} = {};`) || con.includes(`window.${fileItem}={}`))) { + // 因为压缩时不能禁用逗号,只能穷尽所有可能 + con = con.replace(`window.${fileItem} = {};`, `var ${fileItem} = window.${fileItem} = {};`) + .replace(`;window.${fileItem}={};`, `;var ${fileItem}=window.${fileItem}={};`) + .replace(`,window.${fileItem}={};`, `;var ${fileItem}=window.${fileItem}={};`) + .replace(`,window.${fileItem}={},`, `;var ${fileItem}=window.${fileItem}={};`) + .replace(`;window.${fileItem}={},`, `;var ${fileItem}=window.${fileItem}={};`) + if (!con.includes(`;var ${fileItem}=window.${fileItem}={};`)) { + con = con.replace(`window.${fileItem}={}`, `;var ${fileItem}=window.${fileItem}={};`) + } + } + } + } + con = NONCORESTR + con; + fs.writeFileSync(bundlePath, con, "utf8"); + // laya.js + let layaJsStr = (versionCon && versionCon["laya.js"]) ? versionCon["laya.js"] : "laya.js"; + let layaPath = path.join(releaseDir, "widget", "component", layaJsStr); + if (fs.existsSync(layaPath)) { + let con = fs.readFileSync(layaPath, "utf8"); + con = CORESTR + con; + fs.writeFileSync(layaPath, con, "utf8"); + } +}); + +gulp.task("version_TBWidget", ["modifyLibsJs_TBWidget"], function() { + // 如果保留了平台文件,如果同时开启版本管理,就会出现文件引用不正确的问题 + if (config.keepPlatformFile) { + let fileJsPath = path.join(releaseDir, "widget", "component", "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/laya(-[\w\d]+)?\.tbpluginmini/gm, "laya.tbpluginmini"); + content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + } + if (config.version) { + let versionPath = path.join(releaseDir, "widget", "component", "version.json"); + let gameJSPath = path.join(releaseDir, "widget", "component", "game.js"); + let srcList = [versionPath, gameJSPath]; + return gulp.src(srcList) + .pipe(revCollector()) + .pipe(gulp.dest(`${releaseDir}/widget/component`)); + } +}); + +gulp.task("buildTBWidgetProj", ["version_TBWidget"], function() { + console.log("all tasks completed"); +}); \ No newline at end of file diff --git a/examples/layaair/frontend/.laya/publish_vivogame.js b/examples/layaair/frontend/.laya/publish_vivogame.js new file mode 100644 index 0000000..cad1de0 --- /dev/null +++ b/examples/layaair/frontend/.laya/publish_vivogame.js @@ -0,0 +1,1003 @@ +// v1.8.7 +const ideModuleDir = global.ideModuleDir; +const workSpaceDir = global.workSpaceDir; + +//引用插件模块 +const gulp = require(ideModuleDir + "gulp"); +const fs = require("fs"); +const path = require("path"); +const childProcess = require("child_process"); +const del = require(ideModuleDir + "del"); +const iconv = require(ideModuleDir + "iconv-lite"); +const revCollector = require(ideModuleDir + 'gulp-rev-collector'); +const request = require(ideModuleDir + "request"); +const { getEngineVersion, canUsePluginEngine } = require("./pub_utils"); + +let fullRemoteEngineList = ["laya.core.js", "laya.webgl.js", "laya.filter.js", "laya.ani.js", "laya.d3.js", "laya.html.js", "laya.particle.js", "laya.ui.js", "laya.d3Plugin.js", "bytebuffer.js", "laya.device.js", "laya.physics.js", "laya.physics3D.js", "laya.tiledmap.js", "worker.js", "workerloader.js"]; +let copyLibsTask = ["copyPlatformLibsJsFile"]; +let versiontask = ["version2"]; + +let + config, + releaseDir, + tempReleaseDir, // vivo临时拷贝目录 + projDir, // vivo快游戏工程目录 + isDealNoCompile = true, + physicsLibsPathList = [], + isExistEngineFolder = false; // bin目录下是否存在engine文件夹 +let projSrc; +let versionCon; // 版本管理version.json +let commandSuffix, + opensslPath, + layarepublicPath; + +// 创建vivo项目前,拷贝vivo引擎库、修改index.js +gulp.task("preCreate_VIVO", copyLibsTask, function() { + releaseDir = global.releaseDir; + config = global.config; + commandSuffix = global.commandSuffix; + opensslPath = global.opensslPath; + layarepublicPath = global.layarepublicPath; + tempReleaseDir = global.tempReleaseDir; + + if (config.useMinJsLibs) { + fullRemoteEngineList = fullRemoteEngineList.map((item, index) => { + return item.replace(".js", ".min.js"); + }) + } +}); + +gulp.task("copyPlatformFile_VIVO", ["preCreate_VIVO"], function() { + return; +}); + +// 检查是否全局安装了qgame +gulp.task("createGlobalQGame_VIVO", versiontask, function() { + releaseDir = path.dirname(releaseDir); + projDir = path.join(releaseDir, config.vivoInfo.projName); + projSrc = path.join(projDir, "src"); + // npm view @vivo-minigame/cli version + // npm install -g @vivo-minigame/cli + let remoteVersion, localVersion; + let isGetRemote, isGetLocal; + let isUpdateGlobalQGame = true; + return new Promise((resolve, reject) => { // 远程版本号 + childProcess.exec("npm view @vivo-minigame/cli version", function(error, stdout, stderr) { + if (!stdout) { // 获取 @vivo-minigame/cli 远程版本号失败 + console.log("Failed to get the remote version number"); + resolve(); + return; + } + remoteVersion = stdout; + isGetRemote = true; + if (isGetRemote && isGetLocal) { + isUpdateGlobalQGame = remoteVersion != localVersion; + console.log(`remoteVersion: ${remoteVersion}, localVersion: ${localVersion}`); + resolve(); + } + }); + childProcess.exec("mg -v", function(error, stdout, stderr) { + if (!stdout) { // 获取 @vivo-minigame/cli 本地版本号失败 + console.log("Failed to get the local version number"); + resolve(); + return; + } + localVersion = stdout; + isGetLocal = true; + if (isGetRemote && isGetLocal) { + isUpdateGlobalQGame = remoteVersion != localVersion; + console.log(`remoteVersion: ${remoteVersion}, localVersion: ${localVersion}`); + resolve(); + } + }); + setTimeout(() => { + // 如果获取到了本地版本号,但未获取到远程版本号,默认通过 + if (isGetLocal && !isGetRemote) { + isUpdateGlobalQGame = false; + console.log("Gets the version number timeout, does not get the remote version number, but the local version number exists, passes by default"); + resolve(); + return; + } + }, 10000); + }).then(() => { + return new Promise((resolve, reject) => { + if (!isUpdateGlobalQGame) { + resolve(); + return; + } + console.log("全局安装@vivo-minigame/cli"); + // npm install -g @vivo-minigame/cli + let cmd = `npm${commandSuffix}`; + let args = ["install", "@vivo-minigame/cli", "-g"]; + let opts = { + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + // reject(); + }); + + cp.on('close', (code) => { + console.log(`2 end) npm install -g @vivo-minigame/cli:${code}`); + resolve(); + }); + }); + }).catch((e) => { + console.log("catch e", e); + }); +}); + +gulp.task("createProj_VIVO", ["createGlobalQGame_VIVO"], function() { + // 如果有即存项目,不再新建 + let isProjExist = fs.existsSync(projDir + "/node_modules") && + fs.existsSync(projDir + "/sign"); + if (isProjExist) { + // 检测是否需要升级 + let packageCon = fs.readFileSync(`${projDir}/package.json`, "utf8"); + let minigamePath = path.join(projDir, "minigame.config.js"); + if (packageCon.includes("@vivo-minigame/cli-service") && fs.existsSync(minigamePath)) { + return; + } + } + // 如果有即存项目,但是是旧的项目,删掉后重新创建 + return new Promise((resolve, reject) => { + if (!fs.existsSync(projDir)) { + return resolve(); + } + let delList = [projDir]; + del(delList, { force: true }).then(paths => { + resolve(); + }); + }).then(function() { + // 在项目中创建vivo项目 + return new Promise((resolve, reject) => { + console.log("(proj)开始创建vivo快游戏项目"); + // mg init + let cmd = `mg${commandSuffix}`; + let args = ["init", config.vivoInfo.projName]; + let opts = { + cwd: releaseDir, + shell: true + }; + + let cp = childProcess.spawn(cmd, args, opts); + + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + // reject(); + }); + + cp.on('close', (code) => { + cp = null; + console.log(`子进程退出码:${code}`); + resolve(); + }); + }); + }); +}); + +// 检查是否安装了adapter +gulp.task("createAdapter_VIVO", ["createProj_VIVO"], function() { + // npm view @qgame/adapter version + // npm i -S @qgame/adapter@latest + let remoteVersion, localVersion; + let isGetRemote, isGetLocal; + let isUpdateAdapter = true; + return new Promise((resolve, reject) => { // 远程版本号 + childProcess.exec("npm view @qgame/adapter version", function(error, stdout, stderr) { + if (!stdout) { // 获取 @vivo-minigame/cli 远程版本号失败 + console.log("Failed to get the remote adapter version number"); + resolve(); + return; + } + remoteVersion = stdout.replace(/[\r\n]/g, "").trim(); + isGetRemote = true; + if (isGetRemote && isGetLocal) { + isUpdateAdapter = remoteVersion != localVersion; + console.log(`remoteVersion: ${remoteVersion}, localVersion: ${localVersion}`); + resolve(); + } + }); + childProcess.exec("npm ls @qgame/adapter version", { cwd: projDir }, function(error, stdout, stderr) { + if (!stdout) { // 获取 @vivo-minigame/cli 本地版本号失败 + console.log("Failed to get the local adapter version number"); + resolve(); + return; + } + let info = stdout.split("@qgame/adapter@"); //@qgame/adapter@1.0.3 + info = Array.isArray(info) && info[1] && info[1].replace(/[\r\n]/g, "").trim(); + localVersion = info; + isGetLocal = true; + if (isGetRemote && isGetLocal) { + isUpdateAdapter = remoteVersion != localVersion; + console.log(`remoteVersion: ${remoteVersion}, localVersion: ${localVersion}`); + resolve(); + } + }); + setTimeout(() => { + // 如果获取到了本地版本号,但未获取到远程版本号,默认通过 + if (!isGetLocal || !isGetRemote) { + console.log("Failed to get the local or remote version number"); + resolve(); + return; + } + }, 10000); + }).then(() => { + return new Promise((resolve, reject) => { + if (!isUpdateAdapter) { + resolve(); + return; + } + console.log("安装@qgame/adapter"); + // npm i -S @qgame/adapter@latest + let cmd = `npm${commandSuffix}`; + let args = ["install", "-S", "@qgame/adapter@latest"]; + let opts = { + shell: true, + cwd: projDir + }; + let cp = childProcess.spawn(cmd, args, opts); + + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + // reject(); + }); + + cp.on('close', (code) => { + console.log(`2 end) npm i -S @qgame/adapter@latest:${code}`); + resolve(); + }); + }); + }).catch((e) => { + console.log("catch e", e); + }); +}); + +// 拷贝文件到vivo快游戏 +gulp.task("copyFileToProj_VIVO", ["createAdapter_VIVO"], function() { + // 如果有js/main.js,将其删除 + let vivoMainPath = path.join(projDir, "src", "js", "main.js"); + if (fs.existsSync(vivoMainPath)) { + fs.unlinkSync(vivoMainPath); + } + // 将临时文件夹中的文件,拷贝到项目中去 + let originalDir = `${tempReleaseDir}/**/*.*`; + let stream = gulp.src(originalDir); + return stream.pipe(gulp.dest(path.join(projSrc))); +}); + +// 拷贝icon到vivo快游戏 +gulp.task("copyIconToProj_VIVO", ["copyFileToProj_VIVO"], function() { + let originalDir = config.vivoInfo.icon; + let stream = gulp.src(originalDir); + return stream.pipe(gulp.dest(projSrc)); +}); + +// 清除vivo快游戏临时目录 +gulp.task("clearTempDir_VIVO", ["copyIconToProj_VIVO"], function() { + // 删掉临时目录 + return del([tempReleaseDir], { force: true }); +}); + +// 生成release签名(私钥文件 private.pem 和证书文件 certificate.pem ) +gulp.task("generateSign_VIVO", ["clearTempDir_VIVO"], function() { + if (!config.vivoSign.generateSign) { + return; + } + // https://doc.quickapp.cn/tools/compiling-tools.html + return new Promise((resolve, reject) => { + let cmd = `${opensslPath}`; + let args = ["req", "-newkey", "rsa:2048", "-nodes", "-keyout", "private.pem", + "-x509", "-days", "3650", "-out", "certificate.pem"]; + let opts = { + cwd: projDir, + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + data += ""; + if (data.includes("Country Name")) { + cp.stdin.write(`${config.vivoSign.countryName}\n`); + console.log(`Country Name: ${config.vivoSign.countryName}`); + } else if (data.includes("Province Name")) { + cp.stdin.write(`${config.vivoSign.provinceName}\n`); + console.log(`Province Name: ${config.vivoSign.provinceName}`); + } else if (data.includes("Locality Name")) { + cp.stdin.write(`${config.vivoSign.localityName}\n`); + console.log(`Locality Name: ${config.vivoSign.localityName}`); + } else if (data.includes("Organization Name")) { + cp.stdin.write(`${config.vivoSign.orgName}\n`); + console.log(`Organization Name: ${config.vivoSign.orgName}`); + } else if (data.includes("Organizational Unit Name")) { + cp.stdin.write(`${config.vivoSign.orgUnitName}\n`); + console.log(`Organizational Unit Name: ${config.vivoSign.orgUnitName}`); + } else if (data.includes("Common Name")) { + cp.stdin.write(`${config.vivoSign.commonName}\n`); + console.log(`Common Name: ${config.vivoSign.commonName}`); + } else if (data.includes("Email Address")) { + cp.stdin.write(`${config.vivoSign.emailAddr}\n`); + console.log(`Email Address: ${config.vivoSign.emailAddr}`); + // cp.stdin.end(); + } + // reject(); + }); + + cp.on('close', (code) => { + console.log(`子进程退出码:${code}`); + // 签名是否生成成功 + let + privatePem = path.join(projDir, "private.pem"), + certificatePem = path.join(projDir, "certificate.pem"); + let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem); + if (!isSignExits) { + throw new Error("签名生成失败,请检查!"); + } + resolve(); + }); + }); +}); + +// 拷贝sign文件到指定位置 +gulp.task("copySignFile_VIVO", ["generateSign_VIVO"], function() { + if (config.vivoSign.generateSign) { // 新生成的签名 + // 移动签名文件到项目中(Laya & vivo快游戏项目中) + let + privatePem = path.join(projDir, "private.pem"), + certificatePem = path.join(projDir, "certificate.pem"); + let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem); + if (!isSignExits) { + return; + } + let + xiaomiDest = `${projDir}/sign/release`, + layaDest = `${workSpaceDir}/sign/release`; + let stream = gulp.src([privatePem, certificatePem]); + return stream.pipe(gulp.dest(xiaomiDest)) + .pipe(gulp.dest(layaDest)); + } else if (config.vivoInfo.useReleaseSign && !config.vivoSign.generateSign) { // 使用release签名,并且没有重新生成 + // 从项目中将签名拷贝到vivo快游戏项目中 + let + privatePem = path.join(workSpaceDir, "sign", "release", "private.pem"), + certificatePem = path.join(workSpaceDir, "sign", "release", "certificate.pem"); + let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem); + if (!isSignExits) { + return; + } + let + xiaomiDest = `${projDir}/sign/release`; + let stream = gulp.src([privatePem, certificatePem]); + return stream.pipe(gulp.dest(xiaomiDest)); + } +}); + +gulp.task("deleteSignFile_VIVO", ["copySignFile_VIVO"], function() { + if (config.vivoSign.generateSign) { // 新生成的签名 + let + privatePem = path.join(projDir, "private.pem"), + certificatePem = path.join(projDir, "certificate.pem"); + return del([privatePem, certificatePem], { force: true }); + } +}); + +gulp.task("modifyFile_VIVO", ["deleteSignFile_VIVO"], function() { + // 修改manifest.json文件 + let manifestPath = path.join(projSrc, "manifest.json"); + if (!fs.existsSync(manifestPath)) { + return; + } + let manifestContent = fs.readFileSync(manifestPath, "utf8"); + let manifestJson = JSON.parse(manifestContent); + manifestJson.package = config.vivoInfo.package; + manifestJson.name = config.vivoInfo.name; + manifestJson.orientation = config.vivoInfo.orientation; + manifestJson.config.logLevel = config.vivoInfo.logLevel || "off"; + manifestJson.deviceOrientation = config.vivoInfo.orientation; + manifestJson.versionName = config.vivoInfo.versionName; + manifestJson.versionCode = config.vivoInfo.versionCode; + manifestJson.minPlatformVersion = config.vivoInfo.minPlatformVersion; + manifestJson.icon = `/${path.basename(config.vivoInfo.icon)}`; + if (config.vivoInfo.subpack) { // 分包 + manifestJson.subpackages = config.vivoSubpack; + // 检测分包目录是否有入口文件 + console.log('检查分包文件...'); + + if (manifestJson.subpackages) { + for(let i = 0; i < manifestJson.subpackages.length; i ++) { + let conf = manifestJson.subpackages[i]; + if (conf.root) { + let rootPath = path.join(projSrc, conf.root); + if (!fs.existsSync(rootPath)) { + + throw new Error(`分包文件/目录 ${rootPath} 不存在!`); + } + let jsIndex = rootPath.lastIndexOf('.js'); + let jsPath = rootPath; + if (jsIndex < 0 || jsIndex != rootPath.length - 3) { + jsPath = path.join(rootPath, 'game.js'); + } + if (!fs.existsSync(jsPath)) { + + throw new Error(`分包文件/目录 ${jsPath} 不存在!`); + } + } + } + } + } else { + delete manifestJson.subpackages; + } + // 增加thirdEngine字段 + let EngineVersion = getEngineVersion(); + if (EngineVersion) { + manifestJson.thirdEngine = { + "laya": EngineVersion + }; + } + fs.writeFileSync(manifestPath, JSON.stringify(manifestJson, null, 4), "utf8"); + + if (config.version) { + let versionPath = projSrc + "/version.json"; + versionCon = fs.readFileSync(versionPath, "utf8"); + versionCon = JSON.parse(versionCon); + } + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + // 修改game.js文件 + let gameJsPath = path.join(projSrc, "game.js"); + let content = fs.existsSync(gameJsPath) && fs.readFileSync(gameJsPath, "utf8"); + let reWriteMainJs = !fs.existsSync(gameJsPath) || !content.includes("vvmini"); + if (reWriteMainJs) { + content = `require("@qgame/adapter");\nif(!window.navigator)\n\twindow.navigator = {};\nwindow.navigator.userAgent = 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E8301 VVGame NetType/WIFI Language/zh_CN'; +require("./libs/laya.vvmini.js");\nrequire("./index.js");`; + } else { + // 额外的,如果有引擎插件相关代码,需要删掉 + content = content.replace(/if\s\(window\.requirePlugin\)\s{\n[\w\"\.\-\/\(\);\s\n]*\n}\selse\s{\n[\w\"\.\-\/\(\);\s\n]*\n}\n/gm, ""); + } + fs.writeFileSync(gameJsPath, content, "utf8"); + + // vivo项目,修改index.js + let filePath = path.join(projSrc, indexJsStr); + if (!fs.existsSync(filePath)) { + return; + } + let fileContent = fs.readFileSync(filePath, "utf8"); + fileContent = fileContent.replace(/loadLib(\(['"])/gm, "require$1./"); + fs.writeFileSync(filePath, fileContent, "utf8"); +}) + +gulp.task("modifyMinJs_VIVO", ["modifyFile_VIVO"], function() { + let fileJsPath = path.join(projSrc, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + if (!config.useMinJsLibs) { // 默认保留了平台文件,如果同时取消使用min类库,就会出现文件引用不正确的问题 + content = content.replace(/min\/laya(-[\w\d]+)?\.vvmini\.min\.js/gm, "laya.vvmini.js"); + } else { + content = content.replace(/(min\/)?laya(-[\w\d]+)?\.vvmini(\.min)?\.js/gm, "min/laya.vvmini.min.js"); + } + fs.writeFileSync(fileJsPath, content, 'utf-8'); +}); + +gulp.task("version_VIVO", ["modifyMinJs_VIVO"], function () { + // game.js默认不覆盖,如果同时开启版本管理,就会出现文件引用不正确的问题 + let fileJsPath = path.join(projSrc, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/laya(-[\w\d]+)?\.xmmini/gm, "laya.xmmini"); + content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + + if (config.version) { + let versionPath = projSrc + "/version.json"; + let mainJSPath = projSrc + "/game.js"; + let srcList = [versionPath, mainJSPath]; + return gulp.src(srcList) + .pipe(revCollector()) + .pipe(gulp.dest(projSrc)); + } +}); + +// 处理engine文件夹,允许开发者自己在bin下定义engine文件夹,以获得针对性的优化 +gulp.task("dealEngineFolder1_VIVO", ["version_VIVO"], function() { + // 如果项目中有engine文件夹,我们默认该开发者是熟悉VIVO发布流程的,已经处理好所有的逻辑 + // 值得注意的: + // 1) 如果有engine文件夹而未处理2D物理库(box2d.js/physics.js),项目将无法运行 + // 2) 如果未处理3D物理库(physics3D.js),打包时间将会很长 + + let engineFolder = path.join(projDir, "src", "engine"); + isExistEngineFolder = fs.existsSync(engineFolder); + if (!isExistEngineFolder) { + return; + } + + // 不想写一堆task任务,500ms默认拷贝完成吧 + // 未来有了更好的解决方案再修改 + return new Promise(function(resolve, reject) { + // 将engine文件夹拷贝到projRoot下 + setTimeout(resolve, 500); + var stream = gulp.src([`${engineFolder}/**/*.*`], {base: `${projDir}/src`}); + return stream.pipe(gulp.dest(projDir)); + }).then(function() { + return new Promise(function(resolve, reject) { + // 删掉src下的engine和adapter + setTimeout(resolve, 500); + return del([engineFolder], { force: true }); + }); + }).catch(function(err) { + console.log(err); + }); +}); + +gulp.task("dealEngineFolder2_VIVO", ["dealEngineFolder1_VIVO"], function() { + if (!isExistEngineFolder) { + return; + } + + let engineFolder = path.join(projDir, "engine"); + let engineFileList = fs.readdirSync(engineFolder); + // 修改配置文件 + configVivoConfigFile(engineFileList); +}); + +// 如果项目中用到了 box2d.js|laya.physics.js/laya.physics3D.js ,需要特殊处理 +// 之前处理的是有项目中已经存在engine文件夹的情况,现在开始处理没有文件夹的情况 +gulp.task("dealNoCompile1_VIVO", ["dealEngineFolder2_VIVO"], function() { + if (!isDealNoCompile) { + return; + } + + // 将js/bundle.js | libs/*.* 全放到engine文件夹中 + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + let bundleJsStr = (versionCon && versionCon["js/bundle.js"]) ? versionCon["js/bundle.js"] : "js/bundle.js"; + let layaJsStr = (versionCon && versionCon["laya.js"]) ? versionCon["laya.js"] : "laya.js"; + + // 修改index.js,去掉物理库前面的libs + let filePath = path.join(projSrc, indexJsStr); + let fileContent = fs.readFileSync(filePath, "utf8"); + let physicsNameList = []; + + if (fileContent.includes(bundleJsStr)) { + let adapterJsPath = path.join(projSrc, bundleJsStr); + physicsNameList.push(bundleJsStr); + physicsLibsPathList.push(adapterJsPath); + } + if (fileContent.includes(layaJsStr)) { + let layaJsPath = path.join(projSrc, layaJsStr); + physicsNameList.push(layaJsStr); + physicsLibsPathList.push(layaJsPath); + } + let libsList = fs.readdirSync(path.join(projSrc, "libs")); + let libsFileName, libsFilePath; + for (let i = 0, len = libsList.length; i < len; i++) { + libsFileName = libsList[i]; + libsFilePath = path.join(projSrc, "libs", libsFileName); + physicsNameList.push(`libs/${libsFileName}`); + physicsLibsPathList.push(libsFilePath); + } + let minPath = path.join(projSrc, "libs", "min"); + if (fs.existsSync(minPath)) { + let minLibsList = fs.readdirSync(minPath); + let minLibsFileName, minLibsFilePath; + for (let i = 0, len = minLibsList.length; i < len; i++) { + minLibsFileName = minLibsList[i]; + minLibsFilePath = path.join(minPath, minLibsFileName); + physicsNameList.push(`libs/min/${minLibsFileName}`); + physicsLibsPathList.push(minLibsFilePath); + } + } + + // 修改配置文件 + configVivoConfigFile(physicsNameList); + + // 将物理库拷贝到engine中 + var stream = gulp.src(physicsLibsPathList, {base: projSrc}); + return stream.pipe(gulp.dest(path.join(projDir, "engine"))); +}); + +function configVivoConfigFile(engineFileList, isAppend) { + let vvConfigPath = path.join(projDir, "minigame.config.js"); + let content = fs.readFileSync(vvConfigPath, "utf8"); + let externalsStr = ""; + let libName; + // let engineStr = ''; + let inLayaLibs = false, dirName, newLibPath; + for (let i = 0, len = engineFileList.length; i < len; i++) { + libName = engineFileList[i]; + if (i !== 0) { + externalsStr += ',\n'; + } + newLibPath = libName.replace("libs/min/", "").replace("libs/", ""); + inLayaLibs = config.uesEnginePlugin && fullRemoteEngineList.includes(newLibPath); + dirName = inLayaLibs ? "laya-library" : "engine"; + if (inLayaLibs) { + // engineStr += `{\n\t\tmodule_name:'${dirName}/${newLibPath}',\n\t\tmodule_path:'${dirName}/${newLibPath}',\n\t\tmodule_from:'${dirName}/${newLibPath}'\n\t},`; + externalsStr += `\t{\n\t\tmodule_name:'${dirName}/${newLibPath}',\n\t\tmodule_path:'${dirName}/${newLibPath}',\n\t\tmodule_from:'${dirName}/${newLibPath}'\n\t}`; + } else { + externalsStr += `\t{\n\t\tmodule_name:'./${libName}',\n\t\tmodule_path:'./${libName}',\n\t\tmodule_from:'${dirName}/${libName}'\n\t}`; + } + } + if (isAppend) { // 只有源码项目会走这个逻辑 + let oldExternalsReg = content.match(/const externals = (\[([^*].|\n|\r)*\])/); + if (!oldExternalsReg) { + throw new Error("源码项目适配vivo引擎插件,设置配置文件出错,请与服务提供商联系(code 3)!"); + } + externalsStr = oldExternalsReg[1].replace(/\]$/, `,${externalsStr}\n]`); + externalsStr = `const externals = ${externalsStr}`; + } else { + externalsStr = `const externals = [\n${externalsStr}\n]`; + } + content = content.replace(/const externals = \[([^*].|\n|\r)*\]/gm, externalsStr); + fs.writeFileSync(vvConfigPath, content, "utf8"); +} + +gulp.task("dealNoCompile2_VIVO", ["dealNoCompile1_VIVO"], function() { + if (!isDealNoCompile || physicsLibsPathList.length === 0) { + return; + } + return del(physicsLibsPathList, { force: true }); +}); + +// 处理引擎插件 +// 我们会将所有的libs下的文件放到engine里,但不能认定libs下全是我们的引擎,所以还是要加判断 +gulp.task("pluginEngin_VIVO", ["dealNoCompile2_VIVO"], function(cb) { + let manifestJsonPath = path.join(projSrc, "manifest.json"); + let manifestJsonContent = fs.readFileSync(manifestJsonPath, "utf8"); + let conJson = JSON.parse(manifestJsonContent); + let copyBinPath; + + if (!config.uesEnginePlugin) { // 没有使用引擎插件,还是像以前一样发布 + delete conJson.plugins; + manifestJsonContent = JSON.stringify(conJson, null, 4); + fs.writeFileSync(manifestJsonPath, manifestJsonContent, "utf8"); + return cb(); + } + // 引擎源码项目 + // 将所有的min拷贝进来 + if (config.useMinJsLibs) { + copyBinPath = path.join(workSpaceDir, "bin", "libs", "min"); + } else { // 如果不是min + copyBinPath = path.join(workSpaceDir, "bin", "libs"); + } + // 针对min引擎文件,很多配置文件也需要该,同时改 + if (config.version) { + let versionPath = projSrc + "/version.json"; + versionCon = fs.readFileSync(versionPath, "utf8"); + versionCon = JSON.parse(versionCon); + } + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + + // 获取version等信息 + let coreLibPath = path.join(workSpaceDir, "bin", "libs", "laya.core.js"); + let isHasCoreLib = fs.existsSync(coreLibPath); + let isOldAsProj = fs.existsSync(`${workSpaceDir}/asconfig.json`) && !isHasCoreLib; + let isNewTsProj = fs.existsSync(`${workSpaceDir}/src/tsconfig.json`) && !isHasCoreLib; + let EngineVersion = getEngineVersion(); + if (isOldAsProj || isNewTsProj) { + // 下载对应版本js引擎,按照普通项目走 + console.log(`ts源码项目(${isNewTsProj})或as源码项目(${isOldAsProj}),开始处理引擎`); + let engineNum = EngineVersion.split("beta")[0]; + let suffix = EngineVersion.includes("beta") ? `_beta${EngineVersion.split("beta")[1]}` : ""; + let engineURL; + if (canUsePluginEngine(EngineVersion, "2.7.2")) { // 2.7.2 开始,下载地址更新为 cos 服务器 + engineURL = `https://ldc-1251285021.cos.ap-shanghai.myqcloud.com/download/Libs/LayaAirJS_${engineNum}${suffix}.zip`; + } else { + engineURL = `http://ldc.layabox.com/download/LayaAirJS_${engineNum}${suffix}.zip`; + } + let engineDownPath = path.join(releaseDir, `LayaAirJS_${engineNum}${suffix}.zip`); + let engineExtractPath = path.join(releaseDir, `LayaAirJS_${engineNum}${suffix}`); + if (config.useMinJsLibs) { + copyBinPath = path.join(engineExtractPath, "js", "libs", "min"); + } else { // 如果不是min + copyBinPath = path.join(engineExtractPath, "js", "libs"); + } + // 情况1) 如果已经下载过引擎了,直接开始处理引擎插件 + if (fs.existsSync(copyBinPath)) { + console.log("情况1) 如果已经下载过引擎了,直接开始处理引擎插件"); + return dealPluginEngine().then(() => { + // return cb(); + }).catch((err) => { + console.error("ts源码项目及as源码项目,下载或处理vivo引擎插件项目失败(code 1)!"); + throw err; + }); + } + // 情况2) 下载并解压引擎,然后开始处理引擎插件 + console.log("情况2) 下载并解压引擎,然后开始处理引擎插件"); + return downFileToDir(engineURL, engineDownPath).then(() => { + console.log("下载引擎库成功,开始解压"); + return extractZipFile(engineDownPath, engineExtractPath); + }).then(() => { + console.log("解压成功,开始处理引擎插件"); + return dealPluginEngine(); + }).then(() => { + // return cb(); + }).catch((err) => { + console.error("ts源码项目及as源码项目,下载或处理vivo引擎插件项目失败(code 2)!"); + throw err; + }) + } + // 情况3) 非源码项目,开始处理引擎插件 + console.log("情况3) 非源码项目,开始处理引擎插件"); + return dealPluginEngine().then(() => { + // return cb(); + }).catch((err) => { + throw err; + }); + + function dealPluginEngine() { + // 使用引擎插件 + let localUseEngineList = []; + let copyEnginePathList; + return new Promise(function(resolve, reject) { + console.log(`修改game.js和game.json`); + // 1) 修改game.js和game.json + // 修改game.js + let gameJsPath = path.join(projSrc, "game.js"); + let gameJscontent = fs.readFileSync(gameJsPath, "utf8"); + gameJscontent = gameJscontent.replace(`require("./${indexJsStr}");`, `requirePlugin('layaPlugin');\nrequire("./${indexJsStr}");`); + fs.writeFileSync(gameJsPath, gameJscontent, "utf8"); + + // 修改manifest.json,使其支持引擎插件 + conJson.plugins = { + "laya-library": { + "version": EngineVersion, + "provider": "", + "path": "laya-library" + } + } + manifestJsonContent = JSON.stringify(conJson, null, 4); + fs.writeFileSync(manifestJsonPath, manifestJsonContent, "utf8"); + resolve(); + }).then(function() { + return new Promise(function(resolve, reject) { + console.log(`确定用到的插件引擎`); + // 2) 确定用到了那些插件引擎,并将插件引擎从index.js的引用中去掉 + let indexJsPath = path.join(projSrc, indexJsStr); + let indexJsCon = fs.readFileSync(indexJsPath, "utf8"); + let item, fullRequireItem; + for (let i = 0, len = fullRemoteEngineList.length; i < len; i++) { + item = fullRemoteEngineList[i]; + fullRequireItem = config.useMinJsLibs ? `require("./libs/min/${item}")` : `require("./libs/${item}")`; + if (indexJsCon.includes(fullRequireItem)) { + localUseEngineList.push(item); + indexJsCon = indexJsCon.replace(fullRequireItem + ";", "").replace(fullRequireItem + ",", "").replace(fullRequireItem, ""); + } + } + // 源码项目需要特殊处理 + if (isNewTsProj || isOldAsProj) { + indexJsCon = indexJsCon.replace(`require("./laya.js");`, "").replace(`require("./laya.js"),`, "").replace(`require("./laya.js")`, ""); + let item, libPath, vivoConfigList = []; + for (let i = 0, len = fullRemoteEngineList.length; i < len; i++) { + item = fullRemoteEngineList[i]; + libPath = path.join(copyBinPath, item); + if (fs.existsSync(libPath) && !["bytebuffer", "laya.physics3D", "worker", "workerloader"].includes(item.replace(".min.js", "").replace(".js", ""))) { + localUseEngineList.push(item); + config.useMinJsLibs ? vivoConfigList.push(`libs/min/${item}`) : vivoConfigList.push(`libs/${item}`); + } + } + // let bundleJsStr = (versionCon && versionCon["js/bundle.js"]) ? versionCon["js/bundle.js"] : "js/bundle.js"; + // vivoConfigList.push(bundleJsStr); + configVivoConfigFile(vivoConfigList, true); + } + fs.writeFileSync(indexJsPath, indexJsCon, "utf8"); + // 再次修改game.js,仅引用使用到的类库 + let pluginCon = "", normalCon = ""; + localUseEngineList.forEach(function(item) { + pluginCon += `\trequirePlugin("laya-library/${item}");\n`; + normalCon += `\trequire("laya-library/${item}");\n`; + }); + let finalyPluginCon = `if (window.requirePlugin) {\n${pluginCon}\n} else {\n${normalCon}\n}`; + let gameJsPath = path.join(projSrc, "game.js"); + let gameJsCon = fs.readFileSync(gameJsPath, "utf8"); + gameJsCon = gameJsCon.replace(`requirePlugin('layaPlugin');`, finalyPluginCon); + fs.writeFileSync(gameJsPath, gameJsCon, "utf8"); + resolve(); + }); + }).then(function() { + return new Promise(function(resolve, reject) { + console.log(`将本地的引擎插件移动到laya-libs中`); + // 3) 将本地的引擎插件移动到laya-libs中 + copyEnginePathList = [`${copyBinPath}/{${fullRemoteEngineList.join(",")}}`]; + gulp.src(copyEnginePathList).pipe(gulp.dest(`${projDir}/laya-library`)); + setTimeout(resolve, 500); + }); + }).then(function() { + return new Promise(function(resolve, reject) { + console.log(`将libs中的本地引擎插件删掉`); + // 4) 将libs中的本地引擎插件删掉 + let deleteList = [`${projDir}/engine/libs/{${localUseEngineList.join(",")}}`, `${projDir}/engine/libs/min/{${localUseEngineList.join(",")}}`]; + del(deleteList, { force: true }).then(resolve); + }); + }).then(function() { + return new Promise(async function(resolve, reject) { + console.log(`完善引擎插件目录`); + // 5) 引擎插件目录laya-libs中还需要新建几个文件,使该目录能够使用 + let + layalibsPath = path.join(projDir, "laya-library"), + engineIndex = path.join(layalibsPath, "index.js"), + engineplugin = path.join(layalibsPath, "plugin.json"); + // enginesignature = path.join(layalibsPath, "signature.json"); + // index.js + if (!fs.existsSync(layalibsPath)) { + throw new Error("引擎插件目录创建失败,请与服务提供商联系!"); + } + let layaLibraryList = fs.readdirSync(layalibsPath); + let indexCon = ""; + layaLibraryList.forEach(function(item) { + indexCon += `require("./${item}");\n`; + }); + fs.writeFileSync(engineIndex, indexCon, "utf8"); + // plugin.json + let pluginCon = {"main": "index.js"}; + fs.writeFileSync(engineplugin, JSON.stringify(pluginCon, null, 4), "utf8"); + // signature.json + // let signatureCon = { + // "provider": provider, + // "signature": [] + // }; + // localUseEngineList.unshift("index.js"); + // let fileName, md5Str; + // for (let i = 0, len = localUseEngineList.length; i < len; i++) { + // fileName = localUseEngineList[i]; + // let md5Str = await getFileMd5(path.join(projDir, "laya-library", fileName)); + // signatureCon.signature.push({ + // "path": fileName, + // "md5": md5Str + // }); + // } + // fs.writeFileSync(enginesignature, JSON.stringify(signatureCon, null, 4), "utf8"); + resolve(); + }); + }).catch(function(e) { + throw e; + }) + } +}); + +function downFileToDir(uri, dest){ + return new Promise((resolve, reject) => { + if (!uri || !dest) { + reject(new Error(`downFileToDir 参数不全: ${uri}/${dest}`)); + return; + } + + let + totalLen = 9999, + progress = 0, + layaresponse; + var stream = fs.createWriteStream(dest); + request(uri).on('error', function(err) { + console.log("tool down err:" + err); + reject(err); + }).on("data", function(data) { + progress += data.length; + let downPercent = (progress / totalLen * 100).toFixed(3); + // console.log(`down: ${downPercent}%`); + }).on("response", function(response) { + layaresponse = response; + totalLen = response.caseless.dict['content-length']; + }).pipe(stream).on('close', function() { + if (layaresponse.statusCode == 200) { + console.log("下载成功!"); + resolve(); + } else { + reject(new Error(`下载失败,连接关闭 -> ${uri}`)); + } + }); + }); +} + +function extractZipFile(zipPath, extractDir) { + return new Promise((resolve, reject) => { + if (!zipPath || !extractDir) { + reject(new Error(`extractZipFile 参数不全: ${zipPath}/${extractDir}`)); + return false; + } + + zipPath = `"${zipPath}"`; + let unzipexepath = path.join(ideModuleDir, "../", "out", "codeextension", "updateversion", "tools", "unzip.exe"); + unzipexepath = `"${unzipexepath}"`; + let cmd; + if (process.platform === 'darwin') { + cmd = "unzip -o " + zipPath + " -d " + "\"" + extractDir + "\""; + } else { + cmd = unzipexepath + " -o " + zipPath + " -d " + "\"" + extractDir + "\""; + } + childProcess.exec(cmd, (error, stdout, stderr) => { + if (error || stderr) { + reject(error || stderr); + return; + } + resolve(); + }); + }); +} + +// 打包rpk +gulp.task("buildRPK_VIVO", ["pluginEngin_VIVO"], function() { + // 在vivo轻游戏项目目录中执行: + // npm run build || npm run release + let cmdStr = "build"; + if (config.vivoInfo.useReleaseSign) { + cmdStr = "release"; + } + return new Promise((resolve, reject) => { + let cmd = `npm${commandSuffix}`; + let args = ["run", cmdStr]; + let opts = { + cwd: projDir, + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + // let cp = childProcess.spawn(`npx${commandSuffix}`, ['-v']); + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + console.log(`stderr(iconv): ${iconv.decode(data, 'gbk')}`); + + // reject(); + }); + + cp.on('close', (code) => { + console.log(`子进程退出码:${code}`); + // rpk是否生成成功 + let distRpkPath = path.join(projDir, "dist", `${config.vivoInfo.package}${config.vivoInfo.useReleaseSign ? ".signed" : ""}.rpk`); + if (!fs.existsSync(distRpkPath)) { + throw new Error("rpk生成失败,请检查!"); + } + resolve(); + }); + }); +}); + +gulp.task("showQRCode_VIVO", ["buildRPK_VIVO"], function() { + // 在vivo轻游戏项目目录中执行: + // npm run server + return new Promise((resolve, reject) => { + let cmd = `npm${commandSuffix}`; + let args = ["run", "server"]; + let opts = { + cwd: projDir, + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + // let cp = childProcess.spawn(`npx${commandSuffix}`, ['-v']); + cp.stdout.on('data', (data) => { + console.log(`${data}`); + // 输出pid,macos要用: macos无法kill进程树,也无法执行命令获取3000端口pid(没有查询权限),导致无法kill这个进程 + console.log('vv_qrcode_pid:' + cp.pid); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + console.log(`stderr(iconv): ${iconv.decode(data, 'gbk')}`); + // reject(); + }); + + cp.on('close', (code) => { + console.log(`子进程退出码:${code}`); + resolve(); + }); + }); +}); + + +gulp.task("buildVivoProj", ["showQRCode_VIVO"], function() { + console.log("all tasks completed"); +}); \ No newline at end of file diff --git a/examples/layaair/frontend/.laya/publish_wxgame.js b/examples/layaair/frontend/.laya/publish_wxgame.js new file mode 100644 index 0000000..88ad55f --- /dev/null +++ b/examples/layaair/frontend/.laya/publish_wxgame.js @@ -0,0 +1,384 @@ +// v1.8.9 +const ideModuleDir = global.ideModuleDir; +const workSpaceDir = global.workSpaceDir; + +//引用插件模块 +const gulp = require(ideModuleDir + "gulp"); +const fs = require("fs"); +const path = require("path"); +const del = require(ideModuleDir + "del"); +const revCollector = require(ideModuleDir + 'gulp-rev-collector'); +const { getEngineVersion, getFileMd5, canUsePluginEngine } = require("./pub_utils"); + +const provider = "wx70d8aa25ec591f7a"; +const minPluginVersion = "2.0.1"; +let fullRemoteEngineList = ["laya.core.js", "laya.filter.js", "laya.ani.js", "laya.tiledmap.js", "laya.d3.js", "laya.html.js", "laya.particle.js", "laya.ui.js", "laya.webgl.js", "laya.filter.js", "laya.d3Plugin.js"]; +let copyLibsTask = ["copyPlatformLibsJsFile"]; +let versiontask = ["version2"]; + +let + config, + releaseDir; +let isOpendataProj; +let versionCon; // 版本管理version.json +let commandSuffix, + layarepublicPath; + +gulp.task("preCreate_WX", copyLibsTask, function() { + releaseDir = global.releaseDir; + config = global.config; + commandSuffix = global.commandSuffix; + layarepublicPath = global.layarepublicPath; + + if (config.useMinJsLibs) { + fullRemoteEngineList = fullRemoteEngineList.map((item, index) => { + return item.replace(".js", ".min.js"); + }) + } + + // 是否是开放域项目 + let projInfoPath = path.join(workSpaceDir, path.basename(workSpaceDir) + ".laya"); + let isExist = fs.existsSync(projInfoPath); + if (isExist) { + try { + let projInfo = fs.readFileSync(projInfoPath, "utf8"); + projInfo = projInfo && JSON.parse(projInfo); + isOpendataProj = projInfo.layaProType === 12; + } catch (e) {} + } +}); + +gulp.task("copyPlatformFile_WX", ["preCreate_WX"], function() { + let adapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "wxfiles"); + // 开放域项目 + if (isOpendataProj) { + let platformDir = path.join(adapterPath, "weapp-adapter.js"); + let stream = gulp.src(platformDir); + return stream.pipe(gulp.dest(releaseDir)); + } + // 如果新建项目时已经点击了"微信/百度小游戏bin目录快速调试",不再拷贝 + let hasPlatform = + fs.existsSync(path.join(workSpaceDir, "bin", "game.js")) && + fs.existsSync(path.join(workSpaceDir, "bin", "game.json")) && + fs.existsSync(path.join(workSpaceDir, "bin", "project.config.json")); + let hasPublishPlatform = + fs.existsSync(path.join(releaseDir, "game.js")) && + fs.existsSync(path.join(releaseDir, "game.json")) && + fs.existsSync(path.join(releaseDir, "project.config.json")); + let copyLibsList; + if (hasPlatform || hasPublishPlatform) { + copyLibsList = [`${adapterPath}/weapp-adapter.js`]; + } else { + copyLibsList = [`${adapterPath}/*.*`]; + } + var stream = gulp.src(copyLibsList); + return stream.pipe(gulp.dest(releaseDir)); +}); + +// 适配微信wasm +gulp.task("fitwasm_WX", ["copyPlatformFile_WX"], function() { + let + phy3dWasmJs = path.join(releaseDir, "libs", "laya.physics3D.wasm.js"), + phy3dWasmMinJs = path.join(releaseDir, "libs", "min", "laya.physics3D.wasm.min.js"); + let isPhy3dWasmJsExist = fs.existsSync(phy3dWasmJs); + let isPhy3dWasmMinJsExist = fs.existsSync(phy3dWasmMinJs); + if (!isPhy3dWasmJsExist && !isPhy3dWasmMinJsExist) { + return; + } + let phy3dWasmName = isPhy3dWasmJsExist ? phy3dWasmJs : phy3dWasmMinJs; + con = fs.readFileSync(phy3dWasmName, "utf8"); + con = con.replace(/WebAssembly/mg, "WXWebAssembly"); + con = con.replace(/(fetch\(("[\w./]+")\)\.then[(\w)\s=>]+\{\n?\s*[(\.\w)\s=>]+\{)(\n?\s*WXWebAssembly\.instantiate\()(\w+,)/mg, "/** $1 */$3/** $4 */$2,"); + con = con.replace(/(\}\);?\n?\s*\}\);?\n?)(\s*\}\);?\n?\s*\};)/mg, "/** $1 */$2"); + fs.writeFileSync(phy3dWasmName, con, "utf8"); +}) + +// 开放域的情况下,合并game.js和index.js,并删除game.js +gulp.task("openData_WX", versiontask, function (cb) { + if (config.openDataZone) { + let versionCon; + if (config.version) { + let versionPath = releaseDir + "/version.json"; + versionCon = fs.readFileSync(versionPath, "utf8"); + versionCon = JSON.parse(versionCon); + } + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + let indexPath = path.join(releaseDir, indexJsStr); + let indexjs = readFile(indexPath); + let gamejs = readFile(releaseDir + "/game.js"); + if (gamejs && indexjs) { + gamejs = gamejs.replace(`require("index.js")`, indexjs); + fs.writeFileSync(indexPath, gamejs, 'utf-8'); + } + if (isOpendataProj) { + // 开放域项目,将game.js删掉,发布最小包 + del(`${releaseDir}/game.js`, { force: true }).then(paths => { + cb(); + }); + } else { + cb(); + } + } else { + cb(); + } +}); + +function readFile(path) { + if (fs.existsSync(path)) { + return fs.readFileSync(path, "utf-8"); + } + return null; +} + +gulp.task("modifyMinJs_WX", ["openData_WX"], function() { + if (config.openDataZone) { + return; + } + // 如果保留了平台文件,如果同时取消使用min类库,就会出现文件引用不正确的问题 + if (config.keepPlatformFile) { + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/min\/laya(-[\w\d]+)?\.wxmini\.min\.js/gm, "laya.wxmini.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + } + if (!config.useMinJsLibs) { + return; + } + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/(min\/)?laya(-[\w\d]+)?\.wxmini(\.min)?\.js/gm, "min/laya.wxmini.min.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); +}); + +gulp.task("version_WX", ["modifyMinJs_WX"], function() { + if (config.openDataZone) { + return; + } + // 如果保留了平台文件,如果同时开启版本管理,就会出现文件引用不正确的问题 + if (config.keepPlatformFile) { + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/laya(-[\w\d]+)?\.wxmini/gm, "laya.wxmini"); + content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + } + if (config.version) { + let versionPath = releaseDir + "/version.json"; + let gameJSPath = releaseDir + "/game.js"; + let srcList = [versionPath, gameJSPath]; + return gulp.src(srcList) + .pipe(revCollector()) + .pipe(gulp.dest(releaseDir)); + } +}); + +gulp.task("optimizeOpen_WX", ["version_WX"], function(cb) { + let wxOptimize = config.wxOptimize; + if (!wxOptimize || !wxOptimize.useOptimizeOpen) { // 没有使用微信引擎插件,还是像以前一样发布 + return cb(); + } + // 首屏加载优化(秒开),修改game.json + let filePath = path.join(releaseDir, "game.json"); + if (!fs.existsSync(filePath)) { + return cb(); + } + let fileContent = fs.readFileSync(filePath, "utf8"); + let fileConObj = JSON.parse(fileContent); + if (wxOptimize.preloadRes) { + fileConObj.preloadResources = wxOptimize.preloadResList; + } else { + delete fileConObj.preloadResources; + } + if (wxOptimize.preloadSubpack) { + fileConObj.preloadSubpackages = wxOptimize.preloadSubpackList; + } else { + delete fileConObj.preloadSubpackages; + } + fs.writeFileSync(filePath, JSON.stringify(fileConObj, null, 4), "utf8"); + return cb(); +}); + +gulp.task("pluginEngin_WX", ["optimizeOpen_WX"], function(cb) { + if (!config.uesEnginePlugin) { // 没有使用引擎插件,还是像以前一样发布 + let gameJsonPath = path.join(releaseDir, "game.json"); + if (!fs.existsSync(gameJsonPath)) { + return cb(); + } + let gameJsonContent = fs.readFileSync(gameJsonPath, "utf8"); + let conJson = JSON.parse(gameJsonContent); + if (conJson.plugins) { + delete conJson.plugins; + gameJsonContent = JSON.stringify(conJson, null, 4); + fs.writeFileSync(gameJsonPath, gameJsonContent, "utf8"); + + let gameJsPath = path.join(releaseDir, "game.js"); + let gameJscontent = fs.readFileSync(gameJsPath, "utf8"); + gameJscontent = gameJscontent.replace(/requirePlugin\("[\w\/\.]+"\);?\n?/mg, ""); + fs.writeFileSync(gameJsPath, gameJscontent, "utf8"); + } + return cb(); + } + if (config.version) { + let versionPath = releaseDir + "/version.json"; + versionCon = fs.readFileSync(versionPath, "utf8"); + versionCon = JSON.parse(versionCon); + } + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + + // 获取version等信息 + let coreLibPath = path.join(workSpaceDir, "bin", "libs", "laya.core.js"); + let isHasCoreLib = fs.existsSync(coreLibPath); + let isOldAsProj = fs.existsSync(`${workSpaceDir}/asconfig.json`) && !isHasCoreLib; + let isNewTsProj = fs.existsSync(`${workSpaceDir}/src/tsconfig.json`) && !isHasCoreLib; + let EngineVersion = getEngineVersion(); + if (!EngineVersion) { + throw new Error(`读取引擎版本号失败,请于服务提供商联系!`); + } + if (!EngineVersion || EngineVersion.includes("beta") || !canUsePluginEngine(EngineVersion, minPluginVersion)) { + throw new Error(`该版本引擎无法使用引擎插件功能(engineVersion: ${EngineVersion})`); + } + console.log(`通过版本号检查: ${EngineVersion}`); + // 使用引擎插件 + let localUseEngineList = []; + let copyEnginePathList; + new Promise(function(resolve, reject) { + console.log(`修改game.js和game.json`); + // 1) 修改game.js和game.json + // 修改game.js + let gameJsPath = path.join(releaseDir, "game.js"); + let platformJs = config.useMinJsLibs ? `require("./libs/min/laya.wxmini.min.js");` : `require("./libs/laya.wxmini.js");`; + let gameJscontent = `require("weapp-adapter.js");\n${platformJs}\nrequirePlugin('layaPlugin');\nwindow.loadLib = require;\nrequire("./${indexJsStr}");`; + fs.writeFileSync(gameJsPath, gameJscontent, "utf8"); + // 修改game.json,使其支持引擎插件 + let gameJsonPath = path.join(releaseDir, "game.json"); + let gameJsonContent = fs.readFileSync(gameJsonPath, "utf8"); + let conJson = JSON.parse(gameJsonContent); + conJson.plugins = { + "layaPlugin": { + "version": EngineVersion, + "provider": provider, + "path": "laya-libs" + } + } + gameJsonContent = JSON.stringify(conJson, null, 4); + fs.writeFileSync(gameJsonPath, gameJsonContent, "utf8"); + resolve(); + }).then(function() { + return new Promise(function(resolve, reject) { + console.log(`确定用到的插件引擎`); + // 2) 确定用到了那些插件引擎,并将插件引擎从index.js的引用中去掉 + let indexJsPath = path.join(releaseDir, indexJsStr); + let indexJsCon = fs.readFileSync(indexJsPath, "utf8"); + let item, fullRequireItem; + for (let i = 0, len = fullRemoteEngineList.length; i < len; i++) { + item = fullRemoteEngineList[i]; + fullRequireItem = config.useMinJsLibs ? `loadLib("libs/min/${item}")` : `loadLib("libs/${item}")`; + if (indexJsCon.includes(fullRequireItem)) { + let _item = item.replace(".min.js", ".js"), _minItem = item; + localUseEngineList.push(_item); + indexJsCon = indexJsCon.replace(fullRequireItem + ";", "").replace(fullRequireItem + ",", "").replace(fullRequireItem, ""); + // 如果引用了压缩的类库,将其重命名为未压缩的类库,并拷贝到libs中 + if (config.useMinJsLibs) { + let oldMinlibPath = path.join(releaseDir, "libs", "min", _minItem); + let newMinlibPath = path.join(releaseDir, "libs", "min", _item); + let newlibPath = path.join(releaseDir, "libs", _item); + fs.renameSync(oldMinlibPath, newMinlibPath); + // fs.copyFileSync(newlibPath, newMinlibPath); + let con = fs.readFileSync(newMinlibPath, "utf8"); + fs.writeFileSync(newlibPath, con, "utf8"); + fs.unlinkSync(newMinlibPath); + } + } + } + if (isOldAsProj || isNewTsProj) { // 如果as||ts_new语言,开发者将laya.js也写入index.js中了,将其删掉 + fullRequireItem = `loadLib("laya.js")`; + if (indexJsCon.includes(fullRequireItem)) { + indexJsCon = indexJsCon.replace(fullRequireItem + ";", "").replace(fullRequireItem + ",", "").replace(fullRequireItem, ""); + } + } + fs.writeFileSync(indexJsPath, indexJsCon, "utf8"); + // ts/js再次修改game.js,仅引用使用到的类库 + // as||ts_new因为本地只有laya.js,无法仅引用使用到的类库 + if (!isOldAsProj && !isNewTsProj) { + let pluginCon = ""; + localUseEngineList.forEach(function(item) { + pluginCon += `requirePlugin("layaPlugin/${item}");\n`; + }); + let gameJsPath = path.join(releaseDir, "game.js"); + let gameJsCon = fs.readFileSync(gameJsPath, "utf8"); + gameJsCon = gameJsCon.replace(`requirePlugin('layaPlugin');`, pluginCon); + fs.writeFileSync(gameJsPath, gameJsCon, "utf8"); + } + resolve(); + }); + }).then(function() { + return new Promise(function(resolve, reject) { + console.log(`将本地的引擎插件移动到laya-libs中`); + // 3) 将本地的引擎插件移动到laya-libs中 + let libsPath = /** config.useMinJsLibs ? `${releaseDir}/libs/min` : */`${releaseDir}/libs`; + copyEnginePathList = [`${libsPath}/{${localUseEngineList.join(",")}}`]; + if (isOldAsProj || isNewTsProj) { // 单独拷贝laya.js + copyEnginePathList = [`${releaseDir}/laya.js`]; + } + gulp.src(copyEnginePathList).pipe(gulp.dest(`${releaseDir}/laya-libs`)); + setTimeout(resolve, 500); + }); + }).then(function() { + return new Promise(function(resolve, reject) { + console.log(`将libs中的本地引擎插件删掉`); + // 4) 将libs中的本地引擎插件删掉 + del(copyEnginePathList, { force: true }).then(resolve); + }); + }).then(function() { + return new Promise(async function(resolve, reject) { + console.log(`完善引擎插件目录`); + // 5) 引擎插件目录laya-libs中还需要新建几个文件,使该目录能够使用 + if (isOldAsProj || isNewTsProj) { // 单独拷贝laya.js + localUseEngineList.push("laya.js"); + } + let + layalibsPath = path.join(releaseDir, "laya-libs"), + engineIndex = path.join(layalibsPath, "index.js"), + engineplugin = path.join(layalibsPath, "plugin.json"), + enginesignature = path.join(layalibsPath, "signature.json"); + // index.js + if (!fs.existsSync(layalibsPath)) { + throw new Error("引擎插件目录创建失败,请与服务提供商联系!"); + } + let indexCon = ""; + localUseEngineList.forEach(function(item) { + indexCon += `require("./${item}");\n`; + }); + fs.writeFileSync(engineIndex, indexCon, "utf8"); + // plugin.json + let pluginCon = {"main": "index.js"}; + fs.writeFileSync(engineplugin, JSON.stringify(pluginCon, null, 4), "utf8"); + // signature.json,目前平台方将其作为保留用途,不会做插件的md5校验;IDE仍将生成md5 + let signatureCon = { + "provider": provider, + "signature": [] + }; + localUseEngineList.unshift("index.js"); + let fileName, md5Str; + for (let i = 0, len = localUseEngineList.length; i < len; i++) { + fileName = localUseEngineList[i]; + let md5Str = await getFileMd5(path.join(releaseDir, "laya-libs", fileName)); + signatureCon.signature.push({ + "path": fileName, + "md5": md5Str + }); + } + fs.writeFileSync(enginesignature, JSON.stringify(signatureCon, null, 4), "utf8"); + resolve(); + }); + }) + .then(function() { + cb(); + }).catch(function(e) { + throw e; + }) +}); + +gulp.task("buildWXProj", ["pluginEngin_WX"], function() { + console.log("all tasks completed"); +}); \ No newline at end of file diff --git a/examples/layaair/frontend/.laya/publish_xmgame.js b/examples/layaair/frontend/.laya/publish_xmgame.js new file mode 100644 index 0000000..bc4530a --- /dev/null +++ b/examples/layaair/frontend/.laya/publish_xmgame.js @@ -0,0 +1,379 @@ +// v1.8.2 +const ideModuleDir = global.ideModuleDir; +const workSpaceDir = global.workSpaceDir; + +//引用插件模块 +const gulp = require(ideModuleDir + "gulp"); +const fs = require("fs"); +const path = require("path"); +const childProcess = require("child_process"); +const del = require(ideModuleDir + "del"); +const revCollector = require(ideModuleDir + 'gulp-rev-collector'); + +let copyLibsTask = ["copyPlatformLibsJsFile"]; +let versiontask = ["version2"]; + +let + config, + releaseDir, + tempReleaseDir, // 小米临时拷贝目录 + projDir; // 小米快游戏工程目录 +let versionCon; // 版本管理version.json +let commandSuffix, + opensslPath, + layarepublicPath; + +// 创建小米项目前,拷贝小米引擎库、修改index.js +gulp.task("preCreate_XM", copyLibsTask, function() { + releaseDir = global.releaseDir; + config = global.config; + commandSuffix = global.commandSuffix; + opensslPath = global.opensslPath; + layarepublicPath = global.layarepublicPath; + tempReleaseDir = global.tempReleaseDir; +}); + +gulp.task("copyPlatformFile_XM", ["preCreate_XM"], function() { + let xmAdapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "xmfiles"); + let copyLibsList = [`${xmAdapterPath}/**/*.*`]; + var stream = gulp.src(copyLibsList); + return stream.pipe(gulp.dest(tempReleaseDir)); +}); + +gulp.task("createProj_XM", versiontask, function() { + releaseDir = path.dirname(releaseDir); + projDir = path.join(releaseDir, config.xmInfo.projName); + // 如果有即存项目,不再新建 + let isProjExist = fs.existsSync(projDir + "/node_modules") && + fs.existsSync(projDir + "/sign"); + if (isProjExist) { + return; + } + // 在项目中创建小米项目 + return new Promise((resolve, reject) => { + console.log("(proj)开始创建小米快游戏项目,请耐心等待(预计需要10分钟)..."); + let cmd = `npx${commandSuffix}`; + let args = ["create-quickgame", config.xmInfo.projName, `path=${releaseDir}`, + `package=${config.xmInfo.package}`, `versionName=${config.xmInfo.versionName}`, + `versionCode=${config.xmInfo.versionCode}`, `minPlatformVersion=${config.xmInfo.minPlatformVersion}`, + `icon=/layaicon/${path.basename(config.xmInfo.icon)}`, `name=${config.xmInfo.name}`, `rebuild=true`]; + let opts = { + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + // reject(); + }); + + cp.on('close', (code) => { + console.log(`子进程退出码:${code}`); + resolve(); + }); + }); +}); + +// 拷贝文件到小米快游戏 +gulp.task("copyFileToProj_XM", ["createProj_XM"], function() { + // 将临时文件夹中的文件,拷贝到项目中去 + let originalDir = `${tempReleaseDir}/**/*.*`; + let stream = gulp.src(originalDir); + return stream.pipe(gulp.dest(path.join(projDir))); +}); + +// 拷贝icon到小米快游戏 +gulp.task("copyIconToProj_XM", ["copyFileToProj_XM"], function() { + let originalDir = config.xmInfo.icon; + let stream = gulp.src(originalDir); + return stream.pipe(gulp.dest(path.join(projDir, "layaicon"))); +}); + +// 清除小米快游戏临时目录 +gulp.task("clearTempDir_XM", ["copyIconToProj_XM"], function() { + // 删掉临时目录 + return del([tempReleaseDir], { force: true }); +}); + +// 生成release签名(私钥文件 private.pem 和证书文件 certificate.pem ) +gulp.task("generateSign_XM", ["clearTempDir_XM"], function() { + if (!config.xmSign.generateSign) { + return; + } + // https://doc.quickapp.cn/tools/compiling-tools.html + return new Promise((resolve, reject) => { + let cmd = `${opensslPath}`; + let args = ["req", "-newkey", "rsa:2048", "-nodes", "-keyout", "private.pem", + "-x509", "-days", "3650", "-out", "certificate.pem"]; + let opts = { + cwd: projDir, + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + data += ""; + if (data.includes("Country Name")) { + cp.stdin.write(`${config.xmSign.countryName}\n`); + console.log(`Country Name: ${config.xmSign.countryName}`); + } else if (data.includes("Province Name")) { + cp.stdin.write(`${config.xmSign.provinceName}\n`); + console.log(`Province Name: ${config.xmSign.provinceName}`); + } else if (data.includes("Locality Name")) { + cp.stdin.write(`${config.xmSign.localityName}\n`); + console.log(`Locality Name: ${config.xmSign.localityName}`); + } else if (data.includes("Organization Name")) { + cp.stdin.write(`${config.xmSign.orgName}\n`); + console.log(`Organization Name: ${config.xmSign.orgName}`); + } else if (data.includes("Organizational Unit Name")) { + cp.stdin.write(`${config.xmSign.orgUnitName}\n`); + console.log(`Organizational Unit Name: ${config.xmSign.orgUnitName}`); + } else if (data.includes("Common Name")) { + cp.stdin.write(`${config.xmSign.commonName}\n`); + console.log(`Common Name: ${config.xmSign.commonName}`); + } else if (data.includes("Email Address")) { + cp.stdin.write(`${config.xmSign.emailAddr}\n`); + console.log(`Email Address: ${config.xmSign.emailAddr}`); + // cp.stdin.end(); + } + // reject(); + }); + + cp.on('close', (code) => { + console.log(`子进程退出码:${code}`); + // 签名是否生成成功 + let + privatePem = path.join(projDir, "private.pem"), + certificatePem = path.join(projDir, "certificate.pem"); + let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem); + if (!isSignExits) { + throw new Error("签名生成失败,请检查!"); + } + resolve(); + }); + }); +}); + +// 拷贝sign文件到指定位置 +gulp.task("copySignFile_XM", ["generateSign_XM"], function() { + if (config.xmSign.generateSign) { // 新生成的签名 + // 移动签名文件到项目中(Laya & 小米快游戏项目中) + let + privatePem = path.join(projDir, "private.pem"), + certificatePem = path.join(projDir, "certificate.pem"); + let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem); + if (!isSignExits) { + return; + } + let + xiaomiDest = `${projDir}/sign/release`, + layaDest = `${workSpaceDir}/sign/release`; + let stream = gulp.src([privatePem, certificatePem]); + return stream.pipe(gulp.dest(xiaomiDest)) + .pipe(gulp.dest(layaDest)); + } else if (config.xmInfo.useReleaseSign && !config.xmSign.generateSign) { // 使用release签名,并且没有重新生成 + // 从项目中将签名拷贝到小米快游戏项目中 + let + privatePem = path.join(workSpaceDir, "sign", "release", "private.pem"), + certificatePem = path.join(workSpaceDir, "sign", "release", "certificate.pem"); + let isSignExits = fs.existsSync(privatePem) && fs.existsSync(certificatePem); + if (!isSignExits) { + return; + } + let + xiaomiDest = `${projDir}/sign/release`; + let stream = gulp.src([privatePem, certificatePem]); + return stream.pipe(gulp.dest(xiaomiDest)); + } +}); + +gulp.task("deleteSignFile_XM", ["copySignFile_XM"], function() { + if (config.xmSign.generateSign) { // 新生成的签名 + let + privatePem = path.join(projDir, "private.pem"), + certificatePem = path.join(projDir, "certificate.pem"); + return del([privatePem, certificatePem], { force: true }); + } +}); + +gulp.task("modifyFile_XM", ["deleteSignFile_XM"], function() { + // 修改manifest.json文件 + let manifestPath = path.join(projDir, "manifest.json"); + if (!fs.existsSync(manifestPath)) { + return; + } + let manifestContent = fs.readFileSync(manifestPath, "utf8"); + let manifestJson = JSON.parse(manifestContent); + manifestJson.package = config.xmInfo.package; + manifestJson.name = config.xmInfo.name; + manifestJson.orientation = config.xmInfo.orientation; + manifestJson.config.logLevel = config.xmInfo.logLevel || "off"; + manifestJson.versionName = config.xmInfo.versionName; + manifestJson.versionCode = config.xmInfo.versionCode; + manifestJson.minPlatformVersion = config.xmInfo.minPlatformVersion; + manifestJson.icon = `/layaicon/${path.basename(config.xmInfo.icon)}`; + if (config.xmInfo.subpack) { // 分包 + manifestJson.subpackages = config.xmSubpack; + // 检测分包目录是否有入口文件 + console.log('检查分包文件...'); + + if (manifestJson.subpackages) { + for(let i = 0; i < manifestJson.subpackages.length; i ++) { + let conf = manifestJson.subpackages[i]; + if (conf.root) { + let rootPath = path.join(projDir, conf.root); + if (!fs.existsSync(rootPath)) { + + throw new Error(`分包文件/目录 ${rootPath} 不存在!`); + } + let jsIndex = rootPath.lastIndexOf('.js'); + let jsPath = rootPath; + if (jsIndex < 0 || jsIndex != rootPath.length - 3) { + jsPath = path.join(rootPath, 'main.js'); + } + if (!fs.existsSync(jsPath)) { + + throw new Error(`分包文件/目录 ${jsPath} 不存在!`); + } + } + } + } + } else { + delete manifestJson.subpackages; + } + fs.writeFileSync(manifestPath, JSON.stringify(manifestJson, null, 4), "utf8"); + + if (config.version) { + let versionPath = projDir + "/version.json"; + versionCon = fs.readFileSync(versionPath, "utf8"); + versionCon = JSON.parse(versionCon); + } + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + // 修改main.js文件 + let mainJsPath = path.join(projDir, "main.js"); + let mainJsCon = fs.existsSync(mainJsPath) && fs.readFileSync(mainJsPath, "utf8"); + let reWriteMainJs = !fs.existsSync(mainJsPath) || !mainJsCon.includes("xmmini"); + if (reWriteMainJs) { + mainJsCon = 'require("./qg-adapter.js");\nrequire("./libs/laya.xmmini.js");\nrequire("./index.js");'; + fs.writeFileSync(mainJsPath, mainJsCon, "utf8"); + } + + // 小米项目,修改index.js + let filePath = path.join(projDir, indexJsStr); + if (!fs.existsSync(filePath)) { + return; + } + let fileContent = fs.readFileSync(filePath, "utf8"); + fileContent = fileContent.replace(/loadLib(\(['"])/gm, "require$1./"); + fs.writeFileSync(filePath, fileContent, "utf8"); +}) + +gulp.task("modifyMinJs_XM", ["modifyFile_XM"], function() { + let fileJsPath = path.join(projDir, "main.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + if (!config.useMinJsLibs) { // 默认保留了平台文件,如果同时取消使用min类库,就会出现文件引用不正确的问题 + content = content.replace(/min\/laya(-[\w\d]+)?\.xmmini\.min\.js/gm, "laya.xmmini.js"); + } else { + content = content.replace(/(min\/)?laya(-[\w\d]+)?\.xmmini(\.min)?\.js/gm, "min/laya.xmmini.min.js"); + } + fs.writeFileSync(fileJsPath, content, 'utf-8'); +}); + +gulp.task("version_XM", ["modifyMinJs_XM"], function () { + // main.js默认不覆盖,如果同时开启版本管理,就会出现文件引用不正确的问题 + let fileJsPath = path.join(projDir, "main.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/laya(-[\w\d]+)?\.xmmini/gm, "laya.xmmini"); + content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + + if (config.version) { + let versionPath = projDir + "/version.json"; + let mainJSPath = projDir + "/main.js"; + let srcList = [versionPath, mainJSPath]; + return gulp.src(srcList) + .pipe(revCollector()) + .pipe(gulp.dest(projDir)); + } +}); + +// 打包rpk +gulp.task("buildRPK_XM", ["version_XM"], function() { + // 在小米轻游戏项目目录中执行: + // npm run build || npm run release + let cmdStr = "build"; + if (config.xmInfo.useReleaseSign) { + cmdStr = "release"; + } + return new Promise((resolve, reject) => { + let cmd = `npm${commandSuffix}`; + let args = ["run", cmdStr]; + let opts = { + cwd: projDir, + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + // let cp = childProcess.spawn(`npx${commandSuffix}`, ['-v']); + cp.stdout.on('data', (data) => { + console.log(`stdout: ${data}`); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + // reject(); + }); + + cp.on('close', (code) => { + console.log(`子进程退出码:${code}`); + // rpk是否生成成功 + let distRpkPath = path.join(projDir, "dist", `${config.xmInfo.package}${config.xmInfo.useReleaseSign ? ".release" : ".debug"}.rpk`); + if (!fs.existsSync(distRpkPath)) { + throw new Error("rpk生成失败,请检查!"); + } + resolve(); + }); + }); +}); + +gulp.task("showQRCode_XM", ["buildRPK_XM"], function() { + // 在小米轻游戏项目目录中执行: + // npm run server + return new Promise((resolve, reject) => { + let cmd = `npm${commandSuffix}`; + let args = ["run", "server"]; + let opts = { + cwd: projDir, + shell: true + }; + let cp = childProcess.spawn(cmd, args, opts); + // let cp = childProcess.spawn(`npx${commandSuffix}`, ['-v']); + cp.stdout.on('data', (data) => { + console.log(`${data}`); + // 输出pid,macos要用: macos无法kill进程树,也无法执行命令获取3000端口pid(没有查询权限),导致无法kill这个进程 + console.log('xm_qrcode_pid:' + cp.pid); + }); + + cp.stderr.on('data', (data) => { + console.log(`stderr: ${data}`); + // reject(); + }); + + cp.on('close', (code) => { + console.log(`子进程退出码:${code}`); + resolve(); + }); + }); +}); + + +gulp.task("buildXiaomiProj", ["showQRCode_XM"], function() { + console.log("all tasks completed"); +}); \ No newline at end of file diff --git a/examples/layaair/frontend/.laya/publish_youkugame.js b/examples/layaair/frontend/.laya/publish_youkugame.js new file mode 100644 index 0000000..9aa304a --- /dev/null +++ b/examples/layaair/frontend/.laya/publish_youkugame.js @@ -0,0 +1,118 @@ +// v1.0.0 +const ideModuleDir = global.ideModuleDir; +const workSpaceDir = global.workSpaceDir; + +//引用插件模块 +const gulp = require(ideModuleDir + "gulp"); +const fs = require("fs"); +const path = require("path"); +const revCollector = require(ideModuleDir + 'gulp-rev-collector'); + +let copyLibsTask = ["copyPlatformLibsJsFile"]; +let versiontask = ["version2"]; + +let + config, + releaseDir; +let versionCon; // 版本管理version.json +let commandSuffix, + layarepublicPath; + +gulp.task("preCreate_youku", copyLibsTask, function() { + releaseDir = global.releaseDir; + config = global.config; + commandSuffix = global.commandSuffix; + layarepublicPath = global.layarepublicPath; +}); + +gulp.task("copyPlatformFile_youku", ["preCreate_youku"], function() { + let adapterPath = path.join(layarepublicPath, "LayaAirProjectPack", "lib", "data", "youkufiles"); + let hasPublishPlatform = + fs.existsSync(path.join(releaseDir, "game.js")) && + fs.existsSync(path.join(releaseDir, "game.json")) && + fs.existsSync(path.join(releaseDir, "project.config.json")); + let copyLibsList; + if (hasPublishPlatform) { + copyLibsList = [`${adapterPath}/my-adapter.js`]; + } else { + copyLibsList = [`${adapterPath}/*.*`]; + } + var stream = gulp.src(copyLibsList); + return stream.pipe(gulp.dest(releaseDir)); +}); + +gulp.task("modifyFile_youku", versiontask, function() { + // 修改game.json文件 + let gameJsonPath = path.join(releaseDir, "game.json"); + let content = fs.readFileSync(gameJsonPath, "utf8"); + let conJson = JSON.parse(content); + conJson.screenOrientation = config.youkuInfo.orientation; + content = JSON.stringify(conJson, null, 4); + fs.writeFileSync(gameJsonPath, content, "utf8"); + + // 修改game.js + let filePath = path.join(releaseDir, "game.js"); + let fileContent = fs.existsSync(filePath) && fs.readFileSync(filePath, "utf8"); + let reWriteMainJs = !fs.existsSync(filePath) || !fileContent.includes("ykmini"); + if (reWriteMainJs) { + fileContent = `window.navigator.userAgent += " youku"; +require("./my-adapter.js"); +require("./libs/laya.ykmini.js");\nrequire("./index.js");`; + fs.writeFileSync(filePath, fileContent, "utf8"); + } + + if (config.version || config.enableVersion) { + let versionPath = releaseDir + "/version.json"; + versionCon = fs.readFileSync(versionPath, "utf8"); + versionCon = JSON.parse(versionCon); + } + // 修改index.js + let indexJsStr = (versionCon && versionCon["index.js"]) ? versionCon["index.js"] : "index.js"; + let indexFilePath = path.join(releaseDir, indexJsStr); + if (!fs.existsSync(indexFilePath)) { + return; + } + let indexFileContent = fs.readFileSync(indexFilePath, "utf8"); + indexFileContent = indexFileContent.replace(/loadLib(\(['"])/gm, "require$1./"); + fs.writeFileSync(indexFilePath, indexFileContent, "utf8"); +}) + +gulp.task("modifyMinJs_youku", ["modifyFile_youku"], function() { + // 如果保留了平台文件,如果同时取消使用min类库,就会出现文件引用不正确的问题 + if (config.keepPlatformFile) { + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/min\/laya(-[\w\d]+)?\.ykmini\.min\.js/gm, "laya.ykmini.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + } + if (!config.useMinJsLibs) { + return; + } + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/(min\/)?laya(-[\w\d]+)?\.ykmini(\.min)?\.js/gm, "min/laya.ykmini.min.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); +}); + +gulp.task("version_youku", ["modifyMinJs_youku"], function () { + // 如果保留了平台文件,如果同时开启版本管理,就会出现文件引用不正确的问题 + if (config.keepPlatformFile) { + let fileJsPath = path.join(releaseDir, "game.js"); + let content = fs.readFileSync(fileJsPath, "utf-8"); + content = content.replace(/laya(-[\w\d]+)?\.ykmini/gm, "laya.ykmini"); + content = content.replace(/index(-[\w\d]+)?\.js/gm, "index.js"); + fs.writeFileSync(fileJsPath, content, 'utf-8'); + } + if (config.version) { + let versionPath = releaseDir + "/version.json"; + let gameJSPath = releaseDir + "/game.js"; + let srcList = [versionPath, gameJSPath]; + return gulp.src(srcList) + .pipe(revCollector()) + .pipe(gulp.dest(releaseDir)); + } +}); + +gulp.task("buildYKProj", ["version_youku"], function() { + console.log("all tasks completed"); +}); \ No newline at end of file diff --git a/examples/layaair/frontend/.vscode/launch.json b/examples/layaair/frontend/.vscode/launch.json new file mode 100644 index 0000000..7b83dd0 --- /dev/null +++ b/examples/layaair/frontend/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "chrome调试", + "type": "chrome", + "request": "launch", + "file": "${workspaceRoot}/bin/index.html", + // "换成自己的谷歌安装路径,": 比如 + //window 默认安装路径为: "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe" + //mac 系统上的默认安装路径为 "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"; + // "runtimeExecutable": "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe", + "runtimeArgs": [ + "--allow-file-access-from-files", + "--disable-web-security" + ], + "sourceMaps": true, + "webRoot": "${workspaceRoot}", + //假如谷歌调试报userDataDir不可用,请把谷歌安装路径取得管理员权限,或者更换${tmpdir}为其他可以读写的文件夹,也可以删除。 + "userDataDir": "${workspaceRoot}/.laya/chrome", + "sourceMapPathOverrides": { + "src/*": "${workspaceRoot}/src/*" + } + } + ] +} \ No newline at end of file diff --git a/examples/layaair/frontend/README.md b/examples/layaair/frontend/README.md new file mode 100644 index 0000000..0a94142 --- /dev/null +++ b/examples/layaair/frontend/README.md @@ -0,0 +1,9 @@ +# Laya Air + +测试于 LayaAir 2.12.0 + +1. 使用请前先 `npm install`。 +2. 由于 Laya 本身不支持 NPM,所以 `npm install` 的作用仅仅是获取代码提示(类型定义)。 +3. `tsrpc-browser` 打包为单个文件 `src/tsrpc_browser/index.js`,请从该文件中引用 `HttpClient`、`WsClient` 等。 + +示例,见 `Main.ts` 头部。 \ No newline at end of file diff --git a/examples/layaair/frontend/bin/fileconfig.json b/examples/layaair/frontend/bin/fileconfig.json new file mode 100644 index 0000000..24790e3 --- /dev/null +++ b/examples/layaair/frontend/bin/fileconfig.json @@ -0,0 +1 @@ +{"res/atlas/comp.atlas":["comp/",["btn_close.png","button.png","check_circle.png","checkbox.png","clip_num.png","clip_tree_arrow.png","clip_tree_folder.png","colorPicker.png","combobox.png","fontClip.png","fontClip_num.png","hscroll$bar.png","hscroll$down.png","hscroll$up.png","hscroll.png","hslider$bar.png","hslider.png","html.png","image.png","img_bg.png","img_bg2.png","img_bg3.png","img_bg4.png","img_bg5.png","img_blank.png","label.png","progress$bar.png","progress.png","radio.png","radiogroup.png","tab.png","textarea.png","textinput.png","vscroll$bar.png","vscroll$down.png","vscroll$up.png","vscroll.png","vslider$bar.png","vslider.png"]],"res/atlas/test.atlas":["test/",["b1.png","b2.png","block.png","c1.png","c2.png","p1.png","t1.png","tra.png"]]} \ No newline at end of file diff --git a/examples/layaair/frontend/bin/index.html b/examples/layaair/frontend/bin/index.html new file mode 100644 index 0000000..a21db22 --- /dev/null +++ b/examples/layaair/frontend/bin/index.html @@ -0,0 +1,32 @@ + + + + www.layabox.com + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/layaair/frontend/bin/index.js b/examples/layaair/frontend/bin/index.js new file mode 100644 index 0000000..8e11ed9 --- /dev/null +++ b/examples/layaair/frontend/bin/index.js @@ -0,0 +1,15 @@ +/** + * 设置LayaNative屏幕方向,可设置以下值 + * landscape 横屏 + * portrait 竖屏 + * sensor_landscape 横屏(双方向) + * sensor_portrait 竖屏(双方向) + */ +window.screenOrientation = "sensor_landscape"; + +//-----libs-begin----- +loadLib("libs/laya.core.js") +loadLib("libs/laya.ui.js") +loadLib("libs/laya.physics.js") +//-----libs-end------- +loadLib("js/bundle.js"); diff --git a/examples/layaair/frontend/bin/js/bundle.js b/examples/layaair/frontend/bin/js/bundle.js new file mode 100644 index 0000000..8c3eed5 --- /dev/null +++ b/examples/layaair/frontend/bin/js/bundle.js @@ -0,0 +1,4951 @@ +(function () { + 'use strict'; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. All rights reserved. + Licensed under the Apache License, Version 2.0 (the "License"); you may not use + this file except in compliance with the License. You may obtain a copy of the + License at http://www.apache.org/licenses/LICENSE-2.0 + + THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED + WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, + MERCHANTABLITY OR NON-INFRINGEMENT. + + See the Apache Version 2.0 License for specific language governing permissions + and limitations under the License. + ***************************************************************************** */ + /* global Reflect, Promise */ + + var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + + function __extends(d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + + var __assign = function() { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + + function __rest(s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; + } + + function __decorate(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + } + + function __param(paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } + } + + function __metadata(metadataKey, metadataValue) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); + } + + function __awaiter(thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + } + + function __generator(thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } + } + + function __exportStar(m, exports) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; + } + + function __values(o) { + var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; + if (m) return m.call(o); + return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; + } + + function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; + } + + function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) + ar = ar.concat(__read(arguments[i])); + return ar; + } + + function __await(v) { + return this instanceof __await ? (this.v = v, this) : new __await(v); + } + + function __asyncGenerator(thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; + function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } + function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } + function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } + function fulfill(value) { resume("next", value); } + function reject(value) { resume("throw", value); } + function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } + } + + function __asyncDelegator(o) { + var i, p; + return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; + function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } + } + + function __asyncValues(o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); + function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } + function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } + } + + function __makeTemplateObject(cooked, raw) { + if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } + return cooked; + }; + + function __importStar(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result.default = mod; + return result; + } + + function __importDefault(mod) { + return (mod && mod.__esModule) ? mod : { default: mod }; + } + + var Scene = Laya.Scene; + var REG = Laya.ClassUtils.regClass; + var ui; + (function (ui) { + var test; + (function (test) { + class TestSceneUI extends Scene { + constructor() { super(); } + createChildren() { + super.createChildren(); + this.loadScene("test/TestScene"); + } + } + test.TestSceneUI = TestSceneUI; + REG("ui.test.TestSceneUI", TestSceneUI); + })(test = ui.test || (ui.test = {})); + })(ui || (ui = {})); + + class GameControl extends Laya.Script { + constructor() { + super(); + this.createBoxInterval = 1000; + this._time = 0; + this._started = false; + } + onEnable() { + this._time = Date.now(); + this._gameBox = this.owner.getChildByName("gameBox"); + } + onUpdate() { + let now = Date.now(); + if (now - this._time > this.createBoxInterval && this._started) { + this._time = now; + this.createBox(); + } + } + createBox() { + let box = Laya.Pool.getItemByCreateFun("dropBox", this.dropBox.create, this.dropBox); + box.pos(Math.random() * (Laya.stage.width - 100), -100); + this._gameBox.addChild(box); + } + onStageClick(e) { + e.stopPropagation(); + let flyer = Laya.Pool.getItemByCreateFun("bullet", this.bullet.create, this.bullet); + flyer.pos(Laya.stage.mouseX, Laya.stage.mouseY); + this._gameBox.addChild(flyer); + } + startGame() { + if (!this._started) { + this._started = true; + this.enabled = true; + } + } + stopGame() { + this._started = false; + this.enabled = false; + this.createBoxInterval = 1000; + this._gameBox.removeChildren(); + } + } + + class GameUI extends ui.test.TestSceneUI { + constructor() { + super(); + GameUI.instance = this; + Laya.MouseManager.multiTouchEnabled = false; + } + onEnable() { + this._control = this.getComponent(GameControl); + this.tipLbll.on(Laya.Event.CLICK, this, this.onTipClick); + } + onTipClick(e) { + this.tipLbll.visible = false; + this._score = 0; + this.scoreLbl.text = ""; + this._control.startGame(); + } + addScore(value = 1) { + this._score += value; + this.scoreLbl.changeText("分数:" + this._score); + if (this._control.createBoxInterval > 600 && this._score % 20 == 0) + this._control.createBoxInterval -= 20; + } + stopGame() { + this.tipLbll.visible = true; + this.tipLbll.text = "游戏结束了,点击屏幕重新开始"; + this._control.stopGame(); + } + } + + class Bullet extends Laya.Script { + constructor() { super(); } + onEnable() { + var rig = this.owner.getComponent(Laya.RigidBody); + rig.setVelocity({ x: 0, y: -10 }); + } + onTriggerEnter(other, self, contact) { + this.owner.removeSelf(); + } + onUpdate() { + if (this.owner.y < -10) { + this.owner.removeSelf(); + } + } + onDisable() { + Laya.Pool.recover("bullet", this.owner); + } + } + + class DropBox extends Laya.Script { + constructor() { + super(); + this.level = 1; + } + onEnable() { + this._rig = this.owner.getComponent(Laya.RigidBody); + this.level = Math.round(Math.random() * 5) + 1; + this._text = this.owner.getChildByName("levelTxt"); + this._text.text = this.level + ""; + } + onUpdate() { + this.owner.rotation++; + } + onTriggerEnter(other, self, contact) { + var owner = this.owner; + if (other.label === "buttle") { + if (this.level > 1) { + this.level--; + this._text.changeText(this.level + ""); + owner.getComponent(Laya.RigidBody).setVelocity({ x: 0, y: -10 }); + Laya.SoundManager.playSound("sound/hit.wav"); + } + else { + if (owner.parent) { + let effect = Laya.Pool.getItemByCreateFun("effect", this.createEffect, this); + effect.pos(owner.x, owner.y); + owner.parent.addChild(effect); + effect.play(0, true); + owner.removeSelf(); + Laya.SoundManager.playSound("sound/destroy.wav"); + } + } + GameUI.instance.addScore(1); + } + else if (other.label === "ground") { + owner.removeSelf(); + GameUI.instance.stopGame(); + } + } + createEffect() { + let ani = new Laya.Animation(); + ani.loadAnimation("test/TestAni.ani"); + ani.on(Laya.Event.COMPLETE, null, recover); + function recover() { + ani.removeSelf(); + Laya.Pool.recover("effect", ani); + } + return ani; + } + onDisable() { + Laya.Pool.recover("dropBox", this.owner); + } + } + + class GameConfig { + constructor() { + } + static init() { + var reg = Laya.ClassUtils.regClass; + reg("script/GameUI.ts", GameUI); + reg("script/GameControl.ts", GameControl); + reg("script/Bullet.ts", Bullet); + reg("script/DropBox.ts", DropBox); + } + } + GameConfig.width = 640; + GameConfig.height = 1136; + GameConfig.scaleMode = "fixedwidth"; + GameConfig.screenMode = "none"; + GameConfig.alignV = "top"; + GameConfig.alignH = "left"; + GameConfig.startScene = "test/TestScene.scene"; + GameConfig.sceneRoot = ""; + GameConfig.debug = false; + GameConfig.stat = false; + GameConfig.physicsDebug = false; + GameConfig.exportSceneToJson = true; + GameConfig.init(); + + const serviceProto = { + "version": 1, + "services": [ + { + "id": 0, + "name": "AddData", + "type": "api" + }, + { + "id": 1, + "name": "GetData", + "type": "api" + } + ], + "types": { + "PtlAddData/ReqAddData": { + "type": "Interface", + "properties": [ + { + "id": 0, + "name": "content", + "type": { + "type": "String" + } + } + ] + }, + "PtlAddData/ResAddData": { + "type": "Interface", + "properties": [ + { + "id": 0, + "name": "time", + "type": { + "type": "Date" + } + } + ] + }, + "PtlGetData/ReqGetData": { + "type": "Interface" + }, + "PtlGetData/ResGetData": { + "type": "Interface", + "properties": [ + { + "id": 0, + "name": "data", + "type": { + "type": "Array", + "elementType": { + "type": "Interface", + "properties": [ + { + "id": 0, + "name": "content", + "type": { + "type": "String" + } + }, + { + "id": 1, + "name": "time", + "type": { + "type": "Date" + } + } + ] + } + } + } + ] + } + } + }; + + !Array.prototype.__k8w_extended && Object.defineProperties(Array.prototype, { + remove: { + value: function value(filter) { + if (typeof filter == 'function') { + for (var i = this.length - 1; i > -1; --i) { + filter(this[i], i, this) && this.splice(i, 1); + } + } + else { + for (var i = this.length - 1; i > -1; --i) { + this[i] === filter && this.splice(i, 1); + } + } + return this; + } + }, + removeOne: { + value: function value(filter) { + if (typeof filter == 'function') { + for (var i = 0; i < this.length; ++i) { + if (filter(this[i], i, this)) { + this.splice(i, 1); + return this; + } + } + } + else { + for (var i = 0; i < this.length; ++i) { + if (this[i] === filter) { + this.splice(i, 1); + return this; + } + } + } + return this; + } + }, + first: { + value: function value() { + return this.length ? this[0] : null; + } + }, + last: { + value: function value() { + return this.length ? this[this.length - 1] : null; + } + }, + max: { + value: function value(mapper) { + if (!this.length) { + return null; + } + function _max(a, b) { + return a > b ? a : b; + } + if (typeof mapper == 'function') { + var max = mapper(this[0], 0, this); + for (var i = 1; i < this.length; ++i) { + var temp = mapper(this[i], i, this); + max = temp > max ? temp : max; + } + return max; + } + else { + return this.reduce(function (prev, cur) { + return _max(prev, cur); + }); + } + } + }, + min: { + value: function value(mapper) { + if (!this.length) { + return null; + } + function _min(a, b) { + return a < b ? a : b; + } + if (typeof mapper == 'function') { + var min = mapper(this[0], 0, this); + for (var i = 1; i < this.length; ++i) { + var temp = mapper(this[i], i, this); + min = temp < min ? temp : min; + } + return min; + } + else { + return this.reduce(function (prev, cur) { + return _min(prev, cur); + }); + } + } + }, + distinct: { + value: function value() { + return this.filter(function (v, i, arr) { + return arr.indexOf(v) === i; + }); + } + }, + filterIndex: { + value: function value(filter) { + var output = []; + for (var i = 0; i < this.length; ++i) { + if (filter(this[i], i, this)) { + output.push(i); + } + } + return output; + } + }, + count: { + value: function value(filter) { + var result = 0; + for (var i = 0; i < this.length; ++i) { + if (filter(this[i], i, this)) { + ++result; + } + } + return result; + } + }, + sum: { + value: function value(mapper) { + var result = 0; + for (var i = 0; i < this.length; ++i) { + result += mapper ? mapper(this[i], i, this) : this[i]; + } + return result; + } + }, + average: { + value: function value(mapper) { + return this.sum(mapper) / this.length; + } + }, + orderBy: { + value: function value() { + var mappers = []; + for (var _i = 0; _i < arguments.length; _i++) { + mappers[_i] = arguments[_i]; + } + return this.slice().sort(function (a, b) { + for (var i = 0; i < mappers.length; ++i) { + var va = mappers[i](a); + var vb = mappers[i](b); + if (va > vb) { + return 1; + } + else if (va < vb) { + return -1; + } + } + return 0; + }); + } + }, + orderByDesc: { + value: function value() { + var mappers = []; + for (var _i = 0; _i < arguments.length; _i++) { + mappers[_i] = arguments[_i]; + } + return this.slice().sort(function (a, b) { + for (var i = 0; i < mappers.length; ++i) { + var va = mappers[i](a); + var vb = mappers[i](b); + if (va > vb) { + return -1; + } + else if (va < vb) { + return 1; + } + } + return 0; + }); + } + }, + binarySearch: { + value: function value(_value, keyMapper) { + var low = 0, high = this.length - 1; + while (low <= high) { + var mid = (high + low) / 2 | 0; + var midValue = keyMapper ? keyMapper(this[mid]) : this[mid]; + if (_value === midValue) { + return mid; + } + else if (_value > midValue) { + low = mid + 1; + } + else if (_value < midValue) { + high = mid - 1; + } + } + return -1; + } + }, + binaryInsert: { + value: function value(item, keyMapper, unique) { + if (typeof keyMapper == 'boolean') { + unique = keyMapper; + keyMapper = undefined; + } + var low = 0, high = this.length - 1; + var mid = NaN; + var itemValue = keyMapper ? keyMapper(item) : item; + while (low <= high) { + mid = (high + low) / 2 | 0; + var midValue = keyMapper ? keyMapper(this[mid]) : this[mid]; + if (itemValue === midValue) { + if (unique) { + return mid; + } + else { + break; + } + } + else if (itemValue > midValue) { + low = mid + 1; + } + else if (itemValue < midValue) { + high = mid - 1; + } + } + var index = low > mid ? mid + 1 : mid; + this.splice(index, 0, item); + return index; + } + }, + binaryDistinct: { + value: function value(keyMapper) { + return this.filter(function (v, i, arr) { + return arr.binarySearch(v, keyMapper) === i; + }); + } + }, + findLast: { + value: function value(predicate) { + for (var i = this.length - 1; i > -1; --i) { + if (predicate(this[i], i, this)) { + return this[i]; + } + } + return undefined; + } + }, + findLastIndex: { + value: function value(predicate) { + for (var i = this.length - 1; i > -1; --i) { + if (predicate(this[i], i, this)) { + return i; + } + } + return -1; + } + }, + groupBy: { + value: function value(grouper) { + var group = this.reduce(function (prev, next) { + var groupKey = grouper(next); + if (!prev[groupKey]) { + prev[groupKey] = []; + } + prev[groupKey].push(next); + return prev; + }, {}); + return Object.keys(group).map(function (key) { + var arr = group[key]; + arr.key = key; + return arr; + }); + } + }, + __k8w_extended: { + value: true + } + }); + function repeat(str, times) { + var output = ''; + for (var i = 0; i < times; ++i) { + output += str; + } + return output; + } + Date.prototype.format = function (formatString) { + if (formatString === void 0) { + formatString = 'yyyy-MM-dd hh:mm:ss'; + } + var o = { + "M+": this.getMonth() + 1, + "d+": this.getDate(), + "h+": this.getHours(), + "m+": this.getMinutes(), + "s+": this.getSeconds(), + "q+": Math.floor((this.getMonth() + 3) / 3), + "S+": this.getMilliseconds() + }; + if (/(y+)/.test(formatString)) + formatString = formatString.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); + for (var k in o) { + if (new RegExp("(" + k + ")").test(formatString)) + formatString = formatString.replace(RegExp.$1, repeat('0', Math.max(RegExp.$1.length - ('' + o[k]).length, 0)) + o[k]); + } + return formatString; + }; + Date.today = function () { + var now = new Date(); + return new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime(); + }; + function _typeof(obj) { + "@babel/helpers - typeof"; + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function (obj) { + return typeof obj; + }; + } + else { + _typeof = function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }; + } + return _typeof(obj); + } + Object.merge = function (target) { + var sources = []; + for (var _i = 1; _i < arguments.length; _i++) { + sources[_i - 1] = arguments[_i]; + } + for (var i = 0; i < sources.length; ++i) { + var source = sources[i]; + if (_typeof(source) != 'object' || source == null) { + continue; + } + for (var skey in source) { + if (!source.hasOwnProperty(skey)) { + continue; + } + if (source[skey] instanceof Date) { + target[skey] = new Date(source[skey]); + continue; + } + else if (_typeof(target[skey]) == 'object' && target[skey] != null && _typeof(source[skey]) == 'object' && source[skey] != null) { + Object.merge(target[skey], source[skey]); + } + else { + if (Array.isArray(source[skey])) { + target[skey] = Object.merge([], source[skey]); + } + else if (_typeof(source[skey]) == 'object' && source[skey] !== null) { + target[skey] = Object.merge({}, source[skey]); + } + else { + target[skey] = source[skey]; + } + } + } + } + return target; + }; + if (!Object.values) { + Object.values = function (obj) { + var output = []; + for (var k in obj) { + obj.hasOwnProperty(k) && output.push(obj[k]); + } + return output; + }; + } + if (!Object.entries) { + Object.entries = function (obj) { + var output = []; + for (var key in obj) { + if (!obj.hasOwnProperty(key)) { + continue; + } + output.push([key, obj[key]]); + } + return output; + }; + } + Object.forEach = function (obj, handler) { + for (var key in obj) { + if (!obj.hasOwnProperty(key)) { + return; + } + handler(obj[key], key, obj); + } + }; + if (typeof window != 'undefined' && !window.console) { + window.console = {}; + console.log = console.debug = console.info = console.warn = console.error = console.time = console.timeEnd = function () { }; + } + if (!console.debug) { + console.debug = console.log; + } + var extendStatics$1 = function (d, b) { + extendStatics$1 = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) + if (Object.prototype.hasOwnProperty.call(b, p)) + d[p] = b[p]; }; + return extendStatics$1(d, b); + }; + function __extends$1(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics$1(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + var __assign$1 = function () { + __assign$1 = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) + if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign$1.apply(this, arguments); + }; + function __awaiter$1(thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { + step(generator.next(value)); + } + catch (e) { + reject(e); + } } + function rejected(value) { try { + step(generator["throw"](value)); + } + catch (e) { + reject(e); + } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + } + function __generator$1(thisArg, body) { + var _ = { label: 0, sent: function () { if (t[0] & 1) + throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) + throw new TypeError("Generator is already executing."); + while (_) + try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) + return t; + if (y = 0, t) + op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: + case 1: + t = op; + break; + case 4: + _.label++; + return { value: op[1], done: false }; + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; + case 7: + op = _.ops.pop(); + _.trys.pop(); + continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { + _ = 0; + continue; + } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { + _.label = op[1]; + break; + } + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + if (t && _.label < t[2]) { + _.label = t[2]; + _.ops.push(op); + break; + } + if (t[2]) + _.ops.pop(); + _.trys.pop(); + continue; + } + op = body.call(thisArg, _); + } + catch (e) { + op = [6, e]; + y = 0; + } + finally { + f = t = 0; + } + if (op[0] & 5) + throw op[1]; + return { value: op[0] ? op[1] : void 0, done: true }; + } + } + var TsrpcErrorType; + (function (TsrpcErrorType) { + TsrpcErrorType["NetworkError"] = "NetworkError"; + TsrpcErrorType["ServerError"] = "ServerError"; + TsrpcErrorType["ClientError"] = "ClientError"; + TsrpcErrorType["ApiError"] = "ApiError"; + })(TsrpcErrorType || (TsrpcErrorType = {})); + var TransportDataProto = { + "ServerInputData": { + "type": "Interface", + "properties": [{ + "id": 0, + "name": "serviceId", + "type": { + "type": "Number", + "scalarType": "uint" + } + }, { + "id": 1, + "name": "buffer", + "type": { + "type": "Buffer", + "arrayType": "Uint8Array" + } + }, { + "id": 2, + "name": "sn", + "type": { + "type": "Number", + "scalarType": "uint" + }, + "optional": true + }] + }, + "ServerOutputData": { + "type": "Interface", + "properties": [{ + "id": 0, + "name": "buffer", + "type": { + "type": "Buffer", + "arrayType": "Uint8Array" + }, + "optional": true + }, { + "id": 1, + "name": "error", + "type": { + "type": "Reference", + "target": "TsrpcErrorData" + }, + "optional": true + }, { + "id": 2, + "name": "serviceId", + "type": { + "type": "Number", + "scalarType": "uint" + }, + "optional": true + }, { + "id": 3, + "name": "sn", + "type": { + "type": "Number", + "scalarType": "uint" + }, + "optional": true + }] + }, + "TsrpcErrorData": { + "type": "Interface", + "properties": [{ + "id": 0, + "name": "message", + "type": { + "type": "String" + } + }, { + "id": 1, + "name": "type", + "type": { + "type": "Reference", + "target": "TsrpcErrorType" + } + }, { + "id": 2, + "name": "code", + "type": { + "type": "Union", + "members": [{ + "id": 0, + "type": { + "type": "String" + } + }, { + "id": 1, + "type": { + "type": "Number", + "scalarType": "int" + } + }] + }, + "optional": true + }], + "indexSignature": { + "keyType": "String", + "type": { + "type": "Any" + } + } + }, + "TsrpcErrorType": { + "type": "Enum", + "members": [{ + "id": 0, + "value": "NetworkError" + }, { + "id": 1, + "value": "ServerError" + }, { + "id": 2, + "value": "ClientError" + }, { + "id": 3, + "value": "ApiError" + }] + } + }; + var TsrpcError = function () { + function TsrpcError(dataOrMessage, data) { + var _a; + if (typeof dataOrMessage === 'string') { + this.message = dataOrMessage; + this.type = (_a = data === null || data === void 0 ? void 0 : data.type) !== null && _a !== void 0 ? _a : TsrpcErrorType.ApiError; + __assign$1(this, data); + } + else { + __assign$1(this, dataOrMessage); + } + } + TsrpcError.prototype.toString = function () { + return "[TSRPC " + this.type + "]: " + this.message; + }; + TsrpcError.Type = TsrpcErrorType; + return TsrpcError; + }(); + var SchemaType; + (function (SchemaType) { + SchemaType["Boolean"] = "Boolean"; + SchemaType["Number"] = "Number"; + SchemaType["String"] = "String"; + SchemaType["Array"] = "Array"; + SchemaType["Tuple"] = "Tuple"; + SchemaType["Enum"] = "Enum"; + SchemaType["Any"] = "Any"; + SchemaType["Literal"] = "Literal"; + SchemaType["Object"] = "Object"; + SchemaType["Interface"] = "Interface"; + SchemaType["Buffer"] = "Buffer"; + SchemaType["IndexedAccess"] = "IndexedAccess"; + SchemaType["Reference"] = "Reference"; + SchemaType["Union"] = "Union"; + SchemaType["Intersection"] = "Intersection"; + SchemaType["NonNullable"] = "NonNullable"; + SchemaType["Date"] = "Date"; + SchemaType["Pick"] = "Pick"; + SchemaType["Partial"] = "Partial"; + SchemaType["Omit"] = "Omit"; + SchemaType["Overwrite"] = "Overwrite"; + })(SchemaType || (SchemaType = {})); + var ProtoHelper = function () { + function ProtoHelper(proto) { + this._schemaWithUuids = []; + this._unionPropertiesCache = {}; + this._flatInterfaceSchemaCache = {}; + this.proto = proto; + } + ProtoHelper.prototype.parseReference = function (schema) { + if (schema.type === SchemaType.Reference) { + var parsedSchema = this.proto[schema.target]; + if (!parsedSchema) { + throw new Error("Cannot find reference target: " + schema.target); + } + if (this.isTypeReference(parsedSchema)) { + return this.parseReference(parsedSchema); + } + else { + return parsedSchema; + } + } + else if (schema.type === SchemaType.IndexedAccess) { + if (!this.isInterface(schema.objectType)) { + throw new Error("Error objectType: " + schema.objectType.type); + } + var flat = this.getFlatInterfaceSchema(schema.objectType); + var propItem = flat.properties.find(function (v) { + return v.name === schema.index; + }); + var propType = void 0; + if (propItem) { + propType = propItem.type; + } + else { + if (flat.indexSignature) { + propType = flat.indexSignature.type; + } + else { + throw new Error("Error index: " + schema.index); + } + } + if (propItem && propItem.optional && (propItem.type.type !== SchemaType.Union + || propItem.type.members.findIndex(function (v) { + return v.type.type === SchemaType.Literal && v.type.literal === undefined; + }) === -1)) { + propType = { + type: SchemaType.Union, + members: [{ + id: 0, + type: propType + }, { + id: 1, + type: { + type: SchemaType.Literal, + literal: undefined + } + }] + }; + } + return this.isTypeReference(propType) ? this.parseReference(propType) : propType; + } + else { + return schema; + } + }; + ProtoHelper.prototype.isInterface = function (schema, excludeReference) { + if (excludeReference === void 0) { + excludeReference = false; + } + if (!excludeReference && this.isTypeReference(schema)) { + var parsed = this.parseReference(schema); + return this.isInterface(parsed, excludeReference); + } + else { + return schema.type === SchemaType.Interface || schema.type === SchemaType.Pick || schema.type === SchemaType.Partial || schema.type === SchemaType.Omit || schema.type === SchemaType.Overwrite; + } + }; + ProtoHelper.prototype.isTypeReference = function (schema) { + return schema.type === SchemaType.Reference || schema.type === SchemaType.IndexedAccess; + }; + ProtoHelper.prototype._getSchemaUuid = function (schema) { + var schemaWithUuid = schema; + if (!schemaWithUuid.uuid) { + schemaWithUuid.uuid = this._schemaWithUuids.push(schemaWithUuid); + } + return schemaWithUuid.uuid; + }; + ProtoHelper.prototype.getUnionProperties = function (schema) { + var uuid = this._getSchemaUuid(schema); + if (!this._unionPropertiesCache[uuid]) { + this._unionPropertiesCache[uuid] = this._addUnionProperties([], schema.members.map(function (v) { + return v.type; + })); + } + return this._unionPropertiesCache[uuid]; + }; + ProtoHelper.prototype._addUnionProperties = function (unionProperties, schemas) { + for (var i = 0, len = schemas.length; i < len; ++i) { + var schema = this.parseReference(schemas[i]); + if (this.isInterface(schema)) { + var flat = this.getFlatInterfaceSchema(schema); + flat.properties.forEach(function (v) { + unionProperties.binaryInsert(v.name, true); + }); + if (flat.indexSignature) { + var key = "[[" + flat.indexSignature.keyType + "]]"; + unionProperties.binaryInsert(key, true); + } + } + else if (schema.type === SchemaType.Intersection || schema.type === SchemaType.Union) { + this._addUnionProperties(unionProperties, schema.members.map(function (v) { + return v.type; + })); + } + } + return unionProperties; + }; + ProtoHelper.prototype.applyUnionProperties = function (schema, unionProperties) { + var newSchema = __assign$1(__assign$1({}, schema), { + properties: schema.properties.slice() + }); + var _loop_1 = function _loop_1(prop) { + if (prop === '[[String]]') { + newSchema.indexSignature = newSchema.indexSignature || { + keyType: SchemaType.String, + type: { + type: SchemaType.Any + } + }; + } + else if (prop === '[[Number]]') { + newSchema.indexSignature = newSchema.indexSignature || { + keyType: SchemaType.Number, + type: { + type: SchemaType.Any + } + }; + } + else if (!schema.properties.find(function (v) { + return v.name === prop; + })) { + newSchema.properties.push({ + id: -1, + name: prop, + optional: true, + type: { + type: SchemaType.Any + } + }); + } + }; + for (var _i = 0, unionProperties_1 = unionProperties; _i < unionProperties_1.length; _i++) { + var prop = unionProperties_1[_i]; + _loop_1(prop); + } + return newSchema; + }; + ProtoHelper.prototype.getFlatInterfaceSchema = function (schema) { + var uuid = this._getSchemaUuid(schema); + if (this._flatInterfaceSchemaCache[uuid]) { + return this._flatInterfaceSchemaCache[uuid]; + } + if (this.isTypeReference(schema)) { + var parsed = this.parseReference(schema); + if (parsed.type !== SchemaType.Interface) { + throw new Error("Cannot flatten non interface type: " + parsed.type); + } + this._flatInterfaceSchemaCache[uuid] = this.getFlatInterfaceSchema(parsed); + } + else if (schema.type === SchemaType.Interface) { + this._flatInterfaceSchemaCache[uuid] = this._flattenInterface(schema); + } + else { + this._flatInterfaceSchemaCache[uuid] = this._flattenMappedType(schema); + } + return this._flatInterfaceSchemaCache[uuid]; + }; + ProtoHelper.prototype._flattenInterface = function (schema) { + var properties = {}; + var indexSignature; + if (schema.properties) { + for (var _i = 0, _a = schema.properties; _i < _a.length; _i++) { + var prop = _a[_i]; + properties[prop.name] = { + optional: prop.optional, + type: prop.type + }; + } + } + if (schema.indexSignature) { + indexSignature = schema.indexSignature; + } + if (schema.extends) { + for (var _b = 0, _c = schema.extends; _b < _c.length; _b++) { + var extend = _c[_b]; + var parsedExtRef = this.parseReference(extend.type); + if (parsedExtRef.type !== SchemaType.Interface) { + throw new Error('SchemaError: extends must from interface but from ' + parsedExtRef.type); + } + var flatenExtendsSchema = this.getFlatInterfaceSchema(parsedExtRef); + if (flatenExtendsSchema.properties) { + for (var _d = 0, _e = flatenExtendsSchema.properties; _d < _e.length; _d++) { + var prop = _e[_d]; + if (!properties[prop.name]) { + properties[prop.name] = { + optional: prop.optional, + type: prop.type + }; + } + } + } + if (flatenExtendsSchema.indexSignature && !indexSignature) { + indexSignature = flatenExtendsSchema.indexSignature; + } + } + } + return { + type: SchemaType.Interface, + properties: Object.entries(properties).map(function (v, i) { + return { + id: i, + name: v[0], + optional: v[1].optional, + type: v[1].type + }; + }), + indexSignature: indexSignature + }; + }; + ProtoHelper.prototype._flattenMappedType = function (schema) { + var target; + if (this.isTypeReference(schema.target)) { + var parsed = this.parseReference(schema.target); + target = parsed; + } + else { + target = schema.target; + } + var flatTarget; + if (target.type === SchemaType.Pick || target.type === SchemaType.Partial || target.type === SchemaType.Omit || target.type === SchemaType.Overwrite) { + flatTarget = this._flattenMappedType(target); + } + else if (target.type === SchemaType.Interface) { + flatTarget = this._flattenInterface(target); + } + else { + throw new Error("Invalid target.type: " + target.type); + } + if (schema.type === SchemaType.Pick) { + var properties = []; + var _loop_2 = function _loop_2(key) { + var propItem = flatTarget.properties.find(function (v) { + return v.name === key; + }); + if (propItem) { + properties.push({ + id: properties.length, + name: key, + optional: propItem.optional, + type: propItem.type + }); + } + else if (flatTarget.indexSignature) { + properties.push({ + id: properties.length, + name: key, + type: flatTarget.indexSignature.type + }); + } + else { + throw new Error("Cannot find pick key [" + key + "]"); + } + }; + for (var _i = 0, _a = schema.keys; _i < _a.length; _i++) { + var key = _a[_i]; + _loop_2(key); + } + return { + type: SchemaType.Interface, + properties: properties + }; + } + else if (schema.type === SchemaType.Partial) { + for (var _b = 0, _c = flatTarget.properties; _b < _c.length; _b++) { + var v = _c[_b]; + v.optional = true; + } + return flatTarget; + } + else if (schema.type === SchemaType.Omit) { + var _loop_3 = function _loop_3(key) { + flatTarget.properties.removeOne(function (v) { + return v.name === key; + }); + }; + for (var _d = 0, _e = schema.keys; _d < _e.length; _d++) { + var key = _e[_d]; + _loop_3(key); + } + return flatTarget; + } + else if (schema.type === SchemaType.Overwrite) { + var overwrite = this.getFlatInterfaceSchema(schema.overwrite); + if (overwrite.indexSignature) { + flatTarget.indexSignature = overwrite.indexSignature; + } + var _loop_4 = function _loop_4(prop) { + flatTarget.properties.removeOne(function (v) { + return v.name === prop.name; + }); + flatTarget.properties.push(prop); + }; + for (var _f = 0, _g = overwrite.properties; _f < _g.length; _f++) { + var prop = _g[_f]; + _loop_4(prop); + } + return flatTarget; + } + else { + throw new Error("Unknown type: " + schema.type); + } + }; + ProtoHelper.prototype.parseMappedType = function (schema) { + var parents = []; + var child = schema; + do { + parents.push(child); + child = this.parseReference(child.target); + } while (child.type === SchemaType.Pick || child.type === SchemaType.Omit || child.type === SchemaType.Partial || child.type === SchemaType.Overwrite); + if (child.type === SchemaType.Interface) { + return child; + } + else if (child.type === SchemaType.Union) { + var newSchema = { + type: SchemaType.Union, + members: child.members.map(function (v) { + var type = v.type; + for (var i = parents.length - 1; i > -1; --i) { + var parent_1 = parents[i]; + type = __assign$1(__assign$1({}, parent_1), { + target: type + }); + } + return { + id: v.id, + type: type + }; + }) + }; + return newSchema; + } + else { + throw new Error("Unsupported pattern " + schema.type + "<" + child.type + ">"); + } + }; + return ProtoHelper; + }(); + var _a; + var ErrorType; + (function (ErrorType) { + ErrorType["TypeError"] = "TypeError"; + ErrorType["InvalidScalarType"] = "InvalidScalarType"; + ErrorType["TupleOverLength"] = "TupleOverLength"; + ErrorType["InvalidEnumValue"] = "InvalidEnumValue"; + ErrorType["InvalidLiteralValue"] = "InvalidLiteralValue"; + ErrorType["MissingRequiredProperty"] = "MissingRequiredProperty"; + ErrorType["ExcessProperty"] = "ExcessProperty"; + ErrorType["InvalidNumberKey"] = "InvalidNumberKey"; + ErrorType["UnionTypesNotMatch"] = "UnionTypesNotMatch"; + ErrorType["UnionMembersNotMatch"] = "UnionMembersNotMatch"; + })(ErrorType || (ErrorType = {})); + var ErrorMsg = (_a = {}, _a[ErrorType.TypeError] = function (expect, actual) { + return "Expected type to be `" + expect + "`, actually `" + actual + "`."; + }, _a[ErrorType.InvalidScalarType] = function (value, scalarType) { + return "`" + value + "` is not a valid `" + scalarType + "`."; + }, _a[ErrorType.TupleOverLength] = function (valueLength, schemaLength) { + return "Value has " + valueLength + " elements but schema allows only " + schemaLength + "."; + }, _a[ErrorType.InvalidEnumValue] = function (value) { + return "`" + value + "` is not a valid enum member."; + }, _a[ErrorType.InvalidLiteralValue] = function (expected, actual) { + return "Expected to equals `" + stringify(expected) + "`, actually `" + stringify(actual) + "`"; + }, _a[ErrorType.MissingRequiredProperty] = function (propName) { + return "Missing required property `" + propName + "`."; + }, _a[ErrorType.ExcessProperty] = function (propName) { + return "Excess property `" + propName + "` should not exists."; + }, _a[ErrorType.InvalidNumberKey] = function (key) { + return "`" + key + "` is not a valid key, the key here should be a `number`."; + }, + _a[ErrorType.UnionTypesNotMatch] = function (value, types) { + return "`" + stringify(value) + "` is not matched to `" + types.join(' | ') + "`"; + }, _a[ErrorType.UnionMembersNotMatch] = function (memberErrors) { + return "No union member matched, detail:\n" + memberErrors.map(function (v, i) { + return " <" + i + "> " + v.errMsg; + }).join('\n'); + }, _a); + function stringify(value) { + if (typeof value === 'string') { + var output = JSON.stringify(value); + return "'" + output.substr(1, output.length - 2) + "'"; + } + return JSON.stringify(value); + } + var ValidateResultError = function () { + function ValidateResultError(error) { + this.isSucc = false; + this.error = error; + } + Object.defineProperty(ValidateResultError.prototype, "errMsg", { + get: function get() { + return ValidateResultError.getErrMsg(this.error); + }, + enumerable: false, + configurable: true + }); + ValidateResultError.getErrMsg = function (error) { + var _a; + var errMsg = ErrorMsg[error.type].apply(ErrorMsg, error.params); + if ((_a = error.inner) === null || _a === void 0 ? void 0 : _a.property.length) { + return "Property `" + error.inner.property.join('.') + "`: " + errMsg; + } + else { + return errMsg; + } + }; + return ValidateResultError; + }(); + var ValidateResultUtil = function () { + function ValidateResultUtil() { } + ValidateResultUtil.error = function (type) { + var params = []; + for (var _i = 1; _i < arguments.length; _i++) { + params[_i - 1] = arguments[_i]; + } + return new ValidateResultError({ + type: type, + params: params + }); + }; + ValidateResultUtil.innerError = function (property, value, schema, error) { + var _a; + if (error.error.inner) { + if (typeof property === 'string') { + error.error.inner.property.unshift(property); + } + else { + (_a = error.error.inner.property).unshift.apply(_a, property); + } + } + else { + error.error.inner = { + property: typeof property === 'string' ? [property] : property, + value: value, + schema: schema + }; + } + return error; + }; + ValidateResultUtil.succ = { + isSucc: true + }; + return ValidateResultUtil; + }(); + var typedArrays = { + Int8Array: Int8Array, + Int16Array: Int16Array, + Int32Array: Int32Array, + BigInt64Array: typeof BigInt64Array !== 'undefined' ? BigInt64Array : undefined, + Uint8Array: Uint8Array, + Uint16Array: Uint16Array, + Uint32Array: Uint32Array, + BigUint64Array: typeof BigUint64Array !== 'undefined' ? BigUint64Array : undefined, + Float32Array: Float32Array, + Float64Array: Float64Array + }; + var TSBufferValidator = function () { + function TSBufferValidator(proto, options) { + this.options = { + excessPropertyChecks: true, + strictNullChecks: true, + cloneProto: true + }; + if (options) { + this.options = __assign$1(__assign$1({}, this.options), options); + } + this.proto = this.options.cloneProto ? Object.merge({}, proto) : proto; + this.protoHelper = new ProtoHelper(this.proto); + } + TSBufferValidator.prototype.validate = function (value, schemaOrId, options) { + var _a, _b; + var schema; + var schemaId; + if (typeof schemaOrId === 'string') { + schemaId = schemaOrId; + schema = this.proto[schemaId]; + if (!schema) { + throw new Error("Cannot find schema: " + schemaId); + } + } + else { + schema = schemaOrId; + } + return this._validate(value, schema, __assign$1(__assign$1({}, options), { + excessPropertyChecks: (_a = options === null || options === void 0 ? void 0 : options.excessPropertyChecks) !== null && _a !== void 0 ? _a : this.options.excessPropertyChecks, + strictNullChecks: (_b = options === null || options === void 0 ? void 0 : options.strictNullChecks) !== null && _b !== void 0 ? _b : this.options.strictNullChecks + })); + }; + TSBufferValidator.prototype._validate = function (value, schema, options) { + var _a; + var vRes; + switch (schema.type) { + case SchemaType.Boolean: + vRes = this._validateBooleanType(value, schema); + break; + case SchemaType.Number: + vRes = this._validateNumberType(value, schema); + break; + case SchemaType.String: + vRes = this._validateStringType(value, schema); + break; + case SchemaType.Array: + vRes = this._validateArrayType(value, schema, options); + break; + case SchemaType.Tuple: + vRes = this._validateTupleType(value, schema, options); + break; + case SchemaType.Enum: + vRes = this._validateEnumType(value, schema); + break; + case SchemaType.Any: + vRes = this._validateAnyType(value); + break; + case SchemaType.Literal: + vRes = this._validateLiteralType(value, schema, (_a = options === null || options === void 0 ? void 0 : options.strictNullChecks) !== null && _a !== void 0 ? _a : this.options.strictNullChecks); + break; + case SchemaType.Object: + vRes = this._validateObjectType(value, schema); + break; + case SchemaType.Interface: + vRes = this._validateInterfaceType(value, schema, options); + break; + case SchemaType.Buffer: + vRes = this._validateBufferType(value, schema); + break; + case SchemaType.IndexedAccess: + case SchemaType.Reference: + vRes = this._validateReferenceType(value, schema, options); + break; + case SchemaType.Union: + vRes = this._validateUnionType(value, schema, options); + break; + case SchemaType.Intersection: + vRes = this._validateIntersectionType(value, schema, options); + break; + case SchemaType.Pick: + case SchemaType.Omit: + case SchemaType.Partial: + case SchemaType.Overwrite: + vRes = this._validateMappedType(value, schema, options); + break; + case SchemaType.Date: + vRes = this._validateDateType(value); + break; + case SchemaType.NonNullable: + vRes = this._validateNonNullableType(value, schema, options); + break; + default: + throw new Error("Unsupported schema type: " + schema.type); + } + if (options === null || options === void 0 ? void 0 : options.prune) { + if (options.prune.output === undefined) { + options.prune.output = value; + } + if (options.prune.parent) { + options.prune.parent.value[options.prune.parent.key] = options.prune.output; + } + } + return vRes; + }; + TSBufferValidator.prototype.prune = function (value, schemaOrId, options) { + var _a; + var schema = typeof schemaOrId === 'string' ? this.proto[schemaOrId] : schemaOrId; + if (!schema) { + throw new Error('Cannot find schema: ' + schemaOrId); + } + var prune = {}; + var vRes = this._validate(value, schema, __assign$1(__assign$1({}, options), { + prune: prune, + excessPropertyChecks: false, + strictNullChecks: (_a = options === null || options === void 0 ? void 0 : options.strictNullChecks) !== null && _a !== void 0 ? _a : this.options.strictNullChecks + })); + if (vRes.isSucc) { + vRes.pruneOutput = prune.output; + } + return vRes; + }; + TSBufferValidator.prototype._validateBooleanType = function (value, schema) { + var type = this._getTypeof(value); + if (type === 'boolean') { + return ValidateResultUtil.succ; + } + else { + return ValidateResultUtil.error(ErrorType.TypeError, 'boolean', type); + } + }; + TSBufferValidator.prototype._validateNumberType = function (value, schema) { + var scalarType = schema.scalarType || 'double'; + var type = this._getTypeof(value); + var rightType = scalarType.indexOf('big') > -1 ? 'bigint' : 'number'; + if (type !== rightType) { + return ValidateResultUtil.error(ErrorType.TypeError, rightType, type); + } + if (scalarType !== 'double' && type === 'number' && !Number.isInteger(value)) { + return ValidateResultUtil.error(ErrorType.InvalidScalarType, value, scalarType); + } + if (scalarType.indexOf('uint') > -1 && value < 0) { + return ValidateResultUtil.error(ErrorType.InvalidScalarType, value, scalarType); + } + return ValidateResultUtil.succ; + }; + TSBufferValidator.prototype._validateStringType = function (value, schema) { + var type = this._getTypeof(value); + return type === 'string' ? ValidateResultUtil.succ : ValidateResultUtil.error(ErrorType.TypeError, 'string', type); + }; + TSBufferValidator.prototype._validateArrayType = function (value, schema, options) { + var type = this._getTypeof(value); + if (type !== SchemaType.Array) { + return ValidateResultUtil.error(ErrorType.TypeError, SchemaType.Array, type); + } + var prune = options.prune; + if (prune) { + prune.output = Array.from({ + length: value.length + }); + } + for (var i = 0; i < value.length; ++i) { + var elemValidateResult = this._validate(value[i], schema.elementType, __assign$1(__assign$1({}, options), { + prune: (prune === null || prune === void 0 ? void 0 : prune.output) ? { + parent: { + value: prune.output, + key: i + } + } : undefined + })); + if (!elemValidateResult.isSucc) { + return ValidateResultUtil.innerError('' + i, value[i], schema.elementType, elemValidateResult); + } + } + return ValidateResultUtil.succ; + }; + TSBufferValidator.prototype._validateTupleType = function (value, schema, options) { + var type = this._getTypeof(value); + if (type !== SchemaType.Array) { + return ValidateResultUtil.error(ErrorType.TypeError, SchemaType.Array, type); + } + var prune = options.prune; + if (!prune && options.excessPropertyChecks && value.length > schema.elementTypes.length) { + return ValidateResultUtil.error(ErrorType.TupleOverLength, value.length, schema.elementTypes.length); + } + if (prune) { + prune.output = Array.from({ + length: Math.min(value.length, schema.elementTypes.length) + }); + } + for (var i = 0; i < schema.elementTypes.length; ++i) { + if (value[i] === undefined || value[i] === null && !options.strictNullChecks) { + var isOptional = schema.optionalStartIndex !== undefined && i >= schema.optionalStartIndex || this._canBeUndefined(schema.elementTypes[i]); + if (isOptional) { + continue; + } + else { + return ValidateResultUtil.error(ErrorType.MissingRequiredProperty, i); + } + } + var elemValidateResult = this._validate(value[i], schema.elementTypes[i], { + prune: (prune === null || prune === void 0 ? void 0 : prune.output) ? { + parent: { + value: prune.output, + key: i + } + } : undefined, + strictNullChecks: options.strictNullChecks, + excessPropertyChecks: options.excessPropertyChecks + }); + if (!elemValidateResult.isSucc) { + return ValidateResultUtil.innerError('' + i, value[i], schema.elementTypes[i], elemValidateResult); + } + } + return ValidateResultUtil.succ; + }; + TSBufferValidator.prototype._canBeUndefined = function (schema) { + var _this = this; + if (schema.type === SchemaType.Union) { + return schema.members.some(function (v) { + return _this._canBeUndefined(v.type); + }); + } + if (schema.type === SchemaType.Literal && schema.literal === undefined) { + return true; + } + return false; + }; + TSBufferValidator.prototype._validateEnumType = function (value, schema) { + var type = this._getTypeof(value); + if (type !== 'string' && type !== 'number') { + return ValidateResultUtil.error(ErrorType.TypeError, 'string | number', type); + } + if (schema.members.some(function (v) { + return v.value === value; + })) { + return ValidateResultUtil.succ; + } + else { + return ValidateResultUtil.error(ErrorType.InvalidEnumValue, value); + } + }; + TSBufferValidator.prototype._validateAnyType = function (value) { + return ValidateResultUtil.succ; + }; + TSBufferValidator.prototype._validateLiteralType = function (value, schema, strictNullChecks) { + if (!strictNullChecks && (schema.literal === null || schema.literal === undefined)) { + return value === null || value === undefined ? ValidateResultUtil.succ : ValidateResultUtil.error(ErrorType.InvalidLiteralValue, schema.literal, value); + } + return value === schema.literal ? ValidateResultUtil.succ : ValidateResultUtil.error(ErrorType.InvalidLiteralValue, schema.literal, value); + }; + TSBufferValidator.prototype._validateObjectType = function (value, schema) { + var type = this._getTypeof(value); + return type === 'Object' || type === 'Array' ? ValidateResultUtil.succ : ValidateResultUtil.error(ErrorType.TypeError, 'Object', type); + }; + TSBufferValidator.prototype._validateInterfaceType = function (value, schema, options) { + var type = this._getTypeof(value); + if (type !== 'Object') { + return ValidateResultUtil.error(ErrorType.TypeError, 'Object', type); + } + var flatSchema = this.protoHelper.getFlatInterfaceSchema(schema); + if (options.unionProperties) { + flatSchema = this.protoHelper.applyUnionProperties(flatSchema, options.unionProperties); + } + return this._validateFlatInterface(value, flatSchema, options); + }; + TSBufferValidator.prototype._validateMappedType = function (value, schema, options) { + var parsed = this.protoHelper.parseMappedType(schema); + if (parsed.type === SchemaType.Interface) { + return this._validateInterfaceType(value, schema, options); + } + else if (parsed.type === SchemaType.Union) { + return this._validateUnionType(value, parsed, options); + } + throw new Error(); + }; + TSBufferValidator.prototype._validateFlatInterface = function (value, schema, options) { + if (schema.indexSignature && schema.indexSignature.keyType === SchemaType.Number) { + for (var key in value) { + if (!this._isNumberKey(key)) { + return ValidateResultUtil.error(ErrorType.InvalidNumberKey, key); + } + } + } + var prune = options.prune; + if (prune) { + prune.output = {}; + } + if (!prune && options.excessPropertyChecks && !schema.indexSignature) { + var validProperties_1 = schema.properties.map(function (v) { + return v.name; + }); + var firstExcessProperty = Object.keys(value).find(function (v) { + return validProperties_1.indexOf(v) === -1; + }); + if (firstExcessProperty) { + return ValidateResultUtil.error(ErrorType.ExcessProperty, firstExcessProperty); + } + } + if (schema.properties) { + for (var _i = 0, _a = schema.properties; _i < _a.length; _i++) { + var property = _a[_i]; + if (value[property.name] === undefined || value[property.name] === null && !options.strictNullChecks) { + var isOptional = property.optional || this._canBeUndefined(property.type); + if (isOptional) { + continue; + } + else { + return ValidateResultUtil.error(ErrorType.MissingRequiredProperty, property.name); + } + } + var vRes = this._validate(value[property.name], property.type, { + prune: (prune === null || prune === void 0 ? void 0 : prune.output) && property.id > -1 ? { + parent: { + value: prune.output, + key: property.name + } + } : undefined, + strictNullChecks: options.strictNullChecks, + excessPropertyChecks: options.excessPropertyChecks + }); + if (!vRes.isSucc) { + return ValidateResultUtil.innerError(property.name, value[property.name], property.type, vRes); + } + } + } + if (schema.indexSignature) { + for (var key in value) { + var vRes = this._validate(value[key], schema.indexSignature.type, { + prune: (prune === null || prune === void 0 ? void 0 : prune.output) ? { + parent: { + value: prune.output, + key: key + } + } : undefined, + strictNullChecks: options.strictNullChecks, + excessPropertyChecks: options.excessPropertyChecks + }); + if (!vRes.isSucc) { + return ValidateResultUtil.innerError(key, value[key], schema.indexSignature.type, vRes); + } + } + } + return ValidateResultUtil.succ; + }; + TSBufferValidator.prototype._validateBufferType = function (value, schema) { + var _a, _b; + var type = this._getTypeof(value); + if (type !== 'Object') { + return ValidateResultUtil.error(ErrorType.TypeError, schema.arrayType || 'ArrayBuffer', type); + } + else if (schema.arrayType) { + var typeArrayClass = typedArrays[schema.arrayType]; + if (!typeArrayClass) { + throw new Error("Error TypedArray type: " + schema.arrayType); + } + return value instanceof typeArrayClass ? ValidateResultUtil.succ : ValidateResultUtil.error(ErrorType.TypeError, schema.arrayType, (_a = value === null || value === void 0 ? void 0 : value.constructor) === null || _a === void 0 ? void 0 : _a.name); + } + else { + return value instanceof ArrayBuffer ? ValidateResultUtil.succ : ValidateResultUtil.error(ErrorType.TypeError, 'ArrayBuffer', (_b = value === null || value === void 0 ? void 0 : value.constructor) === null || _b === void 0 ? void 0 : _b.name); + } + }; + TSBufferValidator.prototype._validateReferenceType = function (value, schema, options) { + return this._validate(value, this.protoHelper.parseReference(schema), options); + }; + TSBufferValidator.prototype._validateUnionType = function (value, schema, options) { + var _this = this; + options.unionProperties = options.unionProperties || this.protoHelper.getUnionProperties(schema); + var isObjectPrune = false; + var prune = options.prune; + if (prune && value && Object.getPrototypeOf(value) === Object.prototype) { + isObjectPrune = true; + prune.output = {}; + } + var isSomeSucc = false; + var memberErrors = []; + for (var i = 0; i < schema.members.length; ++i) { + var member = schema.members[i]; + var memberType = this.protoHelper.isTypeReference(member.type) ? this.protoHelper.parseReference(member.type) : member.type; + var memberPrune = prune ? {} : undefined; + var vRes = this._validate(value, memberType, __assign$1(__assign$1({}, options), { + prune: memberPrune + })); + if (vRes.isSucc) { + isSomeSucc = true; + if (isObjectPrune) { + prune.output = __assign$1(__assign$1({}, prune.output), memberPrune.output); + } + else { + break; + } + } + else { + memberErrors.push(vRes); + } + } + if (isSomeSucc) { + return ValidateResultUtil.succ; + } + else { + var msg0_1 = memberErrors[0].errMsg; + if (memberErrors.every(function (v) { + return v.errMsg === msg0_1; + })) { + return memberErrors[0]; + } + var nonLiteralErrors = memberErrors.filter(function (v) { + return v.error.type !== ErrorType.InvalidLiteralValue; + }); + if (nonLiteralErrors.length === 1) { + return nonLiteralErrors[0]; + } + if (memberErrors.every(function (v) { + return !v.error.inner && (v.error.type === ErrorType.TypeError || v.error.type === ErrorType.InvalidLiteralValue); + })) { + var valueType = this._getTypeof(value); + var expectedTypes = memberErrors.map(function (v) { + return v.error.type === ErrorType.TypeError ? v.error.params[0] : _this._getTypeof(v.error.params[0]); + }).distinct(); + if (expectedTypes.indexOf(valueType) === -1) { + return ValidateResultUtil.error(ErrorType.TypeError, expectedTypes.join(' | '), this._getTypeof(value)); + } + if (valueType !== 'Object' && valueType !== SchemaType.Array) { + var types = memberErrors.map(function (v) { + return v.error.type === ErrorType.TypeError ? v.error.params[0] : stringify(v.error.params[0]); + }).distinct(); + return ValidateResultUtil.error(ErrorType.UnionTypesNotMatch, value, types); + } + } + return ValidateResultUtil.error(ErrorType.UnionMembersNotMatch, memberErrors); + } + }; + TSBufferValidator.prototype._validateIntersectionType = function (value, schema, options) { + options.unionProperties = options.unionProperties || this.protoHelper.getUnionProperties(schema); + var isObjectPrune = false; + var prune = options.prune; + if (prune && value && Object.getPrototypeOf(value) === Object.prototype) { + prune.output = {}; + isObjectPrune = true; + } + for (var i = 0, len = schema.members.length; i < len; ++i) { + var memberType = schema.members[i].type; + memberType = this.protoHelper.isTypeReference(memberType) ? this.protoHelper.parseReference(memberType) : memberType; + var memberPrune = prune ? {} : undefined; + var vRes = this._validate(value, memberType, __assign$1(__assign$1({}, options), { + prune: memberPrune + })); + if (!vRes.isSucc) { + return vRes; + } + if (isObjectPrune) { + prune.output = __assign$1(__assign$1({}, prune.output), memberPrune.output); + } + } + return ValidateResultUtil.succ; + }; + TSBufferValidator.prototype._validateDateType = function (value) { + if (value instanceof Date) { + return ValidateResultUtil.succ; + } + else { + return ValidateResultUtil.error(ErrorType.TypeError, 'Date', this._getTypeof(value)); + } + }; + TSBufferValidator.prototype._validateNonNullableType = function (value, schema, options) { + var type = this._getTypeof(value); + if ((type === 'null' || type === 'undefined') && schema.target.type !== 'Any') { + return ValidateResultUtil.error(ErrorType.TypeError, 'NonNullable', type); + } + return this._validate(value, schema.target, options); + }; + TSBufferValidator.prototype._isNumberKey = function (key) { + var int = parseInt(key); + return !(isNaN(int) || '' + int !== key); + }; + TSBufferValidator.prototype._getTypeof = function (value) { + var type = _typeof(value); + if (type === 'object') { + if (value === null) { + return 'null'; + } + else if (Array.isArray(value)) { + return SchemaType.Array; + } + else { + return 'Object'; + } + } + return type; + }; + return TSBufferValidator; + }(); + var IdBlockUtil = function () { + function IdBlockUtil() { } + IdBlockUtil.getPayloadLengthInfo = function (parsedSchema) { + switch (parsedSchema.type) { + case SchemaType.Boolean: + case SchemaType.Enum: + return { + lengthType: LengthType.Varint + }; + case SchemaType.Number: + if (!parsedSchema.scalarType || parsedSchema.scalarType.includes('64') || parsedSchema.scalarType === 'double') { + return { + lengthType: LengthType.Bit64 + }; + } + else if (parsedSchema.scalarType && parsedSchema.scalarType.startsWith('big')) { + return { + lengthType: LengthType.LengthDelimited + }; + } + else { + return { + lengthType: LengthType.Varint + }; + } + case SchemaType.Buffer: + case SchemaType.String: + case SchemaType.Any: + case SchemaType.Object: + return { + lengthType: LengthType.LengthDelimited + }; + case SchemaType.Interface: + case SchemaType.Pick: + case SchemaType.Partial: + case SchemaType.Omit: + case SchemaType.Union: + case SchemaType.Intersection: + return { + lengthType: LengthType.IdBlock + }; + case SchemaType.Array: + case SchemaType.Overwrite: + case SchemaType.Tuple: + return { + lengthType: LengthType.LengthDelimited, + needLengthPrefix: true + }; + case SchemaType.Literal: + return { + lengthType: LengthType.LengthDelimited, + needLengthPrefix: false + }; + case SchemaType.Date: + return { + lengthType: LengthType.Varint + }; + default: + throw new Error("Unrecognized schema type: " + parsedSchema.type); + } + }; + return IdBlockUtil; + }(); + var LengthType; + (function (LengthType) { + LengthType[LengthType["LengthDelimited"] = 0] = "LengthDelimited"; + LengthType[LengthType["Varint"] = 1] = "Varint"; + LengthType[LengthType["Bit64"] = 2] = "Bit64"; + LengthType[LengthType["IdBlock"] = 3] = "IdBlock"; + })(LengthType || (LengthType = {})); + var SchemaUtil = function () { + function SchemaUtil() { } + SchemaUtil.canBeLiteral = function (schema, literal) { + var _this = this; + if (schema.type === SchemaType.Union) { + return schema.members.some(function (v) { + return _this.canBeLiteral(v.type, literal); + }); + } + if (schema.type === SchemaType.Any) { + return true; + } + if (schema.type === SchemaType.Literal && schema.literal === literal) { + return true; + } + return false; + }; + return SchemaUtil; + }(); + var TypedArrays = { + Int8Array: Int8Array, + Int16Array: Int16Array, + Int32Array: Int32Array, + Uint8Array: Uint8Array, + Uint16Array: Uint16Array, + Uint32Array: Uint32Array, + Float32Array: Float32Array, + Float64Array: Float64Array + }; + var Utf8CoderJS = { + measureLength: function measureLength(str) { + var len = 0, c = 0; + for (var i = 0; i < str.length; ++i) { + c = str.charCodeAt(i); + if (c < 128) + len += 1; + else if (c < 2048) + len += 2; + else if ((c & 0xFC00) === 0xD800 && (str.charCodeAt(i + 1) & 0xFC00) === 0xDC00) { + ++i; + len += 4; + } + else + len += 3; + } + return len; + }, + write: function write(str, buf, pos) { + var start = pos, c1, c2; + for (var i = 0; i < str.length; ++i) { + c1 = str.charCodeAt(i); + if (c1 < 128) { + buf[pos++] = c1; + } + else if (c1 < 2048) { + buf[pos++] = c1 >> 6 | 192; + buf[pos++] = c1 & 63 | 128; + } + else if ((c1 & 0xFC00) === 0xD800 && ((c2 = str.charCodeAt(i + 1)) & 0xFC00) === 0xDC00) { + c1 = 0x10000 + ((c1 & 0x03FF) << 10) + (c2 & 0x03FF); + ++i; + buf[pos++] = c1 >> 18 | 240; + buf[pos++] = c1 >> 12 & 63 | 128; + buf[pos++] = c1 >> 6 & 63 | 128; + buf[pos++] = c1 & 63 | 128; + } + else { + buf[pos++] = c1 >> 12 | 224; + buf[pos++] = c1 >> 6 & 63 | 128; + buf[pos++] = c1 & 63 | 128; + } + } + return pos - start; + }, + read: function read(buf, pos, length) { + if (length < 1) + return ""; + var parts = undefined, chunk = [], i = 0, t; + var end = pos + length; + while (pos < end) { + t = buf[pos++]; + if (t < 128) + chunk[i++] = t; + else if (t > 191 && t < 224) + chunk[i++] = (t & 31) << 6 | buf[pos++] & 63; + else if (t > 239 && t < 365) { + t = ((t & 7) << 18 | (buf[pos++] & 63) << 12 | (buf[pos++] & 63) << 6 | buf[pos++] & 63) - 0x10000; + chunk[i++] = 0xD800 + (t >> 10); + chunk[i++] = 0xDC00 + (t & 1023); + } + else + chunk[i++] = (t & 15) << 12 | (buf[pos++] & 63) << 6 | buf[pos++] & 63; + if (i > 8191) { + (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk)); + i = 0; + } + } + if (parts) { + if (i) + parts.push(String.fromCharCode.apply(String, chunk.slice(0, i))); + return parts.join(""); + } + return String.fromCharCode.apply(String, chunk.slice(0, i)); + } + }; + var Utf8CoderNode = { + measureLength: function measureLength(str) { + return Buffer.byteLength(str, 'utf-8'); + }, + write: function write(str, buf, pos) { + return Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength).write(str, pos, 'utf-8'); + }, + read: function read(buf, pos, length) { + return Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength).toString('utf-8', pos, pos + length); + } + }; + var Utf8Coder = typeof Buffer !== 'undefined' && Buffer.from && Buffer.prototype.write ? Utf8CoderNode : Utf8CoderJS; + var Varint64 = function () { + function Varint64(high, low, byteLength) { + this.uint32s = new Uint32Array([high, low]); + if (byteLength !== undefined) { + this._byteLength = byteLength; + } + } + Varint64.from = function (value) { + if (value === 0) { + return this.Zero; + } + var sign = value < 0; + if (sign) { + value = -value; + } + var lo = value >>> 0, hi = (value - lo) / 4294967296 >>> 0; + if (sign) { + hi = ~hi >>> 0; + lo = ~lo >>> 0; + if (++lo > 4294967295) { + lo = 0; + if (++hi > 4294967295) + hi = 0; + } + } + return new Varint64(hi, lo); + }; + Varint64.prototype.toNumber = function (unsigned) { + if (!unsigned && this.uint32s[0] >>> 31) { + var low = ~this.uint32s[1] + 1 >>> 0, high = ~this.uint32s[0] >>> 0; + if (!low) + high = high + 1 >>> 0; + return -(low + high * 4294967296); + } + return this.uint32s[1] + this.uint32s[0] * 4294967296; + }; + Varint64.prototype.zzEncode = function () { + var mask = this.uint32s[0] >> 31; + this.uint32s[0] = ((this.uint32s[0] << 1 | this.uint32s[1] >>> 31) ^ mask) >>> 0; + this.uint32s[1] = (this.uint32s[1] << 1 ^ mask) >>> 0; + return this; + }; + Varint64.prototype.zzDecode = function () { + var mask = -(this.uint32s[1] & 1); + this.uint32s[1] = ((this.uint32s[1] >>> 1 | this.uint32s[0] << 31) ^ mask) >>> 0; + this.uint32s[0] = (this.uint32s[0] >>> 1 ^ mask) >>> 0; + return this; + }; + Object.defineProperty(Varint64.prototype, "byteLength", { + get: function get() { + if (this._byteLength === undefined) { + var part0 = this.uint32s[1], part1 = (this.uint32s[1] >>> 28 | this.uint32s[0] << 4) >>> 0, part2 = this.uint32s[0] >>> 24; + this._byteLength = part2 === 0 ? part1 === 0 ? part0 < 16384 ? part0 < 128 ? 1 : 2 : part0 < 2097152 ? 3 : 4 : part1 < 16384 ? part1 < 128 ? 5 : 6 : part1 < 2097152 ? 7 : 8 : part2 < 128 ? 9 : 10; + } + return this._byteLength; + }, + enumerable: false, + configurable: true + }); + Varint64.prototype.writeToBuffer = function (buf, pos) { + while (this.uint32s[0]) { + buf[pos++] = this.uint32s[1] & 127 | 128; + this.uint32s[1] = (this.uint32s[1] >>> 7 | this.uint32s[0] << 25) >>> 0; + this.uint32s[0] >>>= 7; + } + while (this.uint32s[1] > 127) { + buf[pos++] = this.uint32s[1] & 127 | 128; + this.uint32s[1] = this.uint32s[1] >>> 7; + } + buf[pos++] = this.uint32s[1]; + return pos; + }; + Varint64.readFromBuffer = function (buf, pos) { + var startPos = pos; + var hi = 0, lo = 0; + var i = 0; + if (buf.byteLength - pos > 4) { + for (; i < 4; ++i) { + lo = (lo | (buf[pos] & 127) << i * 7) >>> 0; + if (buf[pos++] < 128) + return new Varint64(hi, lo, pos - startPos); + } + lo = (lo | (buf[pos] & 127) << 28) >>> 0; + hi = (hi | (buf[pos] & 127) >> 4) >>> 0; + if (buf[pos++] < 128) + return new Varint64(hi, lo, pos - startPos); + i = 0; + } + else { + for (; i < 3; ++i) { + if (pos >= buf.byteLength) + throw new Error('Read varint error: index out of range'); + lo = (lo | (buf[pos] & 127) << i * 7) >>> 0; + if (buf[pos++] < 128) + return new Varint64(hi, lo, pos - startPos); + } + lo = (lo | (buf[pos++] & 127) << i * 7) >>> 0; + return new Varint64(hi, lo, pos - startPos); + } + if (buf.byteLength - pos > 4) { + for (; i < 5; ++i) { + hi = (hi | (buf[pos] & 127) << i * 7 + 3) >>> 0; + if (buf[pos++] < 128) + return new Varint64(hi, lo, pos - startPos); + } + } + else { + for (; i < 5; ++i) { + if (pos >= buf.byteLength) + throw new Error('Read varint error: index out of range'); + hi = (hi | (buf[pos] & 127) << i * 7 + 3) >>> 0; + if (buf[pos++] < 128) + return new Varint64(hi, lo, pos - startPos); + } + } + throw Error("invalid varint encoding"); + }; + Varint64.Zero = new Varint64(0, 0); + return Varint64; + }(); + var BufferReader = function () { + function BufferReader() { + this._pos = 0; + } + BufferReader.prototype.load = function (buf, pos) { + if (pos === void 0) { + pos = 0; + } + this._buf = buf; + this._pos = pos; + this._view = new DataView(buf.buffer); + }; + BufferReader.prototype.readVarint = function () { + var varint = Varint64.readFromBuffer(this._buf, this._pos); + this._pos += varint.byteLength; + return varint; + }; + BufferReader.prototype.readUint = function () { + return this.readVarint().toNumber(true); + }; + BufferReader.prototype.readInt = function () { + return this.readVarint().zzDecode().toNumber(); + }; + BufferReader.prototype.readDouble = function () { + var pos = this._pos; + this._pos += 8; + return this._view.getFloat64(this._buf.byteOffset + pos); + }; + BufferReader.prototype.readString = function () { + var strByteLength = this.readUint(); + var str = Utf8Coder.read(this._buf, this._pos, strByteLength); + this._pos += strByteLength; + return str; + }; + BufferReader.prototype.readBuffer = function () { + var bufByteLength = this.readUint(); + var buf = this._buf.subarray(this._pos, this._pos + bufByteLength); + this._pos += bufByteLength; + return buf; + }; + BufferReader.prototype.skip = function (byteLength) { + this._pos += byteLength; + }; + BufferReader.prototype.skipByLengthType = function (lengthType) { + if (lengthType === LengthType.Bit64) { + this._pos += 8; + } + else if (lengthType === LengthType.Varint) { + this.readVarint(); + } + else if (lengthType === LengthType.LengthDelimited) { + var bufByteLength = this.readUint(); + this._pos += bufByteLength; + } + else if (lengthType === LengthType.IdBlock) { + this.skipIdBlock(); + } + else { + throw new Error('Unknown lengthType: ' + lengthType); + } + }; + BufferReader.prototype.skipIdBlock = function () { + var idNum = this.readUint(); + for (var i = 0; i < idNum; ++i) { + var id = this.readUint(); + var lengthType = id & 3; + this.skipByLengthType(lengthType); + } + }; + BufferReader.prototype.readBoolean = function () { + var value = this._view.getUint8(this._buf.byteOffset + this._pos++); + if (value === 255) { + return true; + } + else if (value === 0) { + return false; + } + else { + throw new Error("Invalid boolean encoding [" + value + "] at pos " + (this._pos - 1)); + } + }; + Object.defineProperty(BufferReader.prototype, "unreadByteLength", { + get: function get() { + return this._buf.byteLength - this._pos; + }, + enumerable: false, + configurable: true + }); + BufferReader.prototype.dispose = function () { + this._buf = this._view = undefined; + }; + return BufferReader; + }(); + var Decoder = function () { + function Decoder(options) { + this._options = options; + this._reader = new BufferReader(); + this._validator = options.validator; + } + Decoder.prototype.decode = function (buffer, schema) { + this._reader.load(buffer); + return this._read(schema); + }; + Decoder.prototype._read = function (schema) { + switch (schema.type) { + case SchemaType.Boolean: + return this._reader.readBoolean(); + case SchemaType.Number: + return this._readNumber(schema); + case SchemaType.String: + return this._reader.readString(); + case SchemaType.Array: + { + var output = []; + var length_1 = this._reader.readUint(); + for (var i = 0; i < length_1; ++i) { + var item = this._read(schema.elementType); + output.push(item); + } + return output; + } + case SchemaType.Tuple: + { + if (schema.elementTypes.length > 64) { + throw new Error('Elements oversized, maximum supported tuple elements is 64, now get ' + schema.elementTypes.length); + } + var output = []; + var payloadMask = this._reader.readVarint(); + var maskIndices = []; + for (var i = 0; i < 32; ++i) { + if (payloadMask.uint32s[1] & 1 << i) { + maskIndices.push(i); + } + } + for (var i = 0; i < 32; ++i) { + if (payloadMask.uint32s[0] & 1 << i) { + maskIndices.push(i + 32); + } + } + if (!maskIndices.length) { + return []; + } + var maxIndex = maskIndices.last(); + for (var i = 0, nextMaskIndex = 0, next = maskIndices[0]; i <= maxIndex; ++i) { + if (i === next) { + output[i] = this._read(schema.elementTypes[i]); + ++nextMaskIndex; + next = maskIndices[nextMaskIndex]; + } + else { + output[i] = undefined; + } + } + for (var i = 0; i < schema.elementTypes.length; ++i) { + if (this._undefinedAsNull(output[i], schema.elementTypes[i], schema.optionalStartIndex !== undefined && i >= schema.optionalStartIndex)) { + output[i] = null; + } + } + return output; + } + case SchemaType.Enum: + var enumId_1 = this._reader.readVarint().toNumber(); + var enumItem = schema.members.find(function (v) { + return v.id === enumId_1; + }); + if (!enumItem) { + throw new Error("Invalid enum encoding: unexpected id " + enumId_1); + } + return enumItem.value; + case SchemaType.Any: + case SchemaType.Object: + var jsonStr = this._reader.readString(); + if (jsonStr === 'undefined') { + return undefined; + } + return JSON.parse(jsonStr); + case SchemaType.Literal: + return schema.literal; + case SchemaType.Interface: + return this._readInterface(schema); + case SchemaType.Buffer: + var uint8Arr = this._reader.readBuffer(); + if (schema.arrayType) { + if (schema.arrayType === 'BigInt64Array' || schema.arrayType === 'BigUint64Array') { + throw new Error('Unsupported arrayType: ' + schema.arrayType); + } + else if (schema.arrayType === 'Uint8Array') { + return uint8Arr; + } + else { + var typedArr = TypedArrays[schema.arrayType]; + if (uint8Arr.byteOffset % typedArr.BYTES_PER_ELEMENT === 0) { + return new typedArr(uint8Arr.buffer, uint8Arr.byteOffset, uint8Arr.byteLength / typedArr.BYTES_PER_ELEMENT); + } + else { + var arrBuf = uint8Arr.buffer.slice(uint8Arr.byteOffset, uint8Arr.byteOffset + uint8Arr.byteLength); + return new typedArr(arrBuf); + } + } + } + else { + return uint8Arr.buffer.slice(uint8Arr.byteOffset, uint8Arr.byteOffset + uint8Arr.byteLength); + } + case SchemaType.IndexedAccess: + case SchemaType.Reference: + return this._read(this._validator.protoHelper.parseReference(schema)); + case SchemaType.Partial: + case SchemaType.Pick: + case SchemaType.Omit: + case SchemaType.Overwrite: + var parsed = this._validator.protoHelper.parseMappedType(schema); + if (parsed.type === 'Interface') { + return this._readPureMappedType(schema); + } + else if (parsed.type === 'Union') { + return this._readUnionOrIntersection(parsed); + } + break; + case SchemaType.Union: + case SchemaType.Intersection: + return this._readUnionOrIntersection(schema); + case SchemaType.Date: + return new Date(this._reader.readUint()); + case SchemaType.NonNullable: + return this._read(schema.target); + default: + throw new Error("Unrecognized schema type: " + schema.type); + } + }; + Decoder.prototype._readPureMappedType = function (schema) { + var output; + var overwrite; + if (schema.type === 'Overwrite') { + overwrite = this._read(schema.overwrite); + } + var parsedTarget = this._validator.protoHelper.parseReference(schema.target); + if (parsedTarget.type === 'Interface') { + output = this._readInterface(parsedTarget); + } + else if (parsedTarget.type === 'Pick' || parsedTarget.type === 'Omit' || parsedTarget.type === 'Partial' || parsedTarget.type === 'Overwrite') { + output = this._readPureMappedType(parsedTarget); + } + else { + throw new Error('Invalid PureMappedType child: ' + schema.type); + } + if (schema.type === 'Pick') { + for (var key in output) { + if (schema.keys.indexOf(key) === -1) { + delete output[key]; + } + } + } + else if (schema.type === 'Omit') { + for (var key in output) { + if (schema.keys.indexOf(key) > -1) { + delete output[key]; + } + } + } + else if (schema.type === 'Overwrite') { + Object.assign(output, overwrite); + } + return output; + }; + Decoder.prototype._readNumber = function (schema) { + var scalarType = schema.scalarType || 'double'; + switch (scalarType) { + case 'double': + return this._reader.readDouble(); + case 'int': + return this._reader.readInt(); + case 'uint': + return this._reader.readUint(); + default: + throw new Error('Scalar type not support : ' + scalarType); + } + }; + Decoder.prototype._readInterface = function (schema) { + var output = {}; + var flatSchema = this._validator.protoHelper.getFlatInterfaceSchema(schema); + var blockIdNum = this._reader.readUint(); + var _loop_1 = function _loop_1(i) { + var readBlockId = this_1._reader.readUint(); + var lengthType = readBlockId & 3; + var blockId = readBlockId >> 2; + if (blockId === 0) { + if (flatSchema.indexSignature) { + var type = flatSchema.indexSignature.type; + var fieldName = this_1._reader.readString(); + this_1._skipIdLengthPrefix(this_1._validator.protoHelper.parseReference(type)); + output[fieldName] = this_1._read(type); + } + else { + this_1._reader.skipByLengthType(LengthType.LengthDelimited); + this_1._reader.skipByLengthType(lengthType); + } + } + else if (blockId <= 9) { + var extendId_1 = blockId - 1; + var extend = schema.extends && schema.extends.find(function (v) { + return v.id === extendId_1; + }); + if (extend) { + this_1._skipIdLengthPrefix(this_1._validator.protoHelper.parseReference(extend.type)); + var extendValue = this_1._read(extend.type); + Object.assign(output, extendValue); + } + else { + this_1._reader.skipByLengthType(lengthType); + } + } + else { + var propertyId_1 = blockId - 10; + var property = schema.properties && schema.properties.find(function (v) { + return v.id === propertyId_1; + }); + if (property) { + this_1._skipIdLengthPrefix(this_1._validator.protoHelper.parseReference(property.type)); + output[property.name] = this_1._read(property.type); + } + else { + this_1._reader.skipByLengthType(lengthType); + } + } + }; + var this_1 = this; + for (var i = 0; i < blockIdNum; ++i) { + _loop_1(); + } + for (var _i = 0, _a = flatSchema.properties; _i < _a.length; _i++) { + var property = _a[_i]; + if (output.hasOwnProperty(property.name)) { + continue; + } + var parsedType = this._validator.protoHelper.parseReference(property.type); + if (parsedType.type === 'Literal') { + output[property.name] = parsedType.literal; + continue; + } + if (this._undefinedAsNull(output[property.name], parsedType, property.optional)) { + output[property.name] = null; + continue; + } + } + return output; + }; + Decoder.prototype._undefinedAsNull = function (value, type, isOptional) { + return value === undefined && this._options.undefinedAsNull && !SchemaUtil.canBeLiteral(type, undefined) && !isOptional && SchemaUtil.canBeLiteral(type, null); + }; + Decoder.prototype._skipIdLengthPrefix = function (parsedSchema) { + var lengthInfo = IdBlockUtil.getPayloadLengthInfo(parsedSchema); + if (lengthInfo.needLengthPrefix) { + this._reader.skipByLengthType(LengthType.Varint); + } + }; + Decoder.prototype._readUnionOrIntersection = function (schema) { + var output; + var idNum = this._reader.readUint(); + var _loop_2 = function _loop_2(i) { + var readId = this_2._reader.readUint(); + var lengthType = readId & 3; + var id = readId >> 2; + var member = schema.members.find(function (v) { + return v.id === id; + }); + if (!member) { + this_2._reader.skipByLengthType(lengthType); + return "continue"; + } + this_2._skipIdLengthPrefix(this_2._validator.protoHelper.parseReference(member.type)); + var value = this_2._read(member.type); + if (this_2._isObject(output) && this_2._isObject(value)) { + Object.assign(output, value); + } + else { + output = value; + } + }; + var this_2 = this; + for (var i = 0; i < idNum; ++i) { + _loop_2(); + } + if (this._undefinedAsNull(output, schema)) { + output = null; + } + return output; + }; + Decoder.prototype._isObject = function (value) { + return _typeof(value) === 'object' && value !== null; + }; + return Decoder; + }(); + var Config = { + interface: { + maxExtendsNum: 9 + } + }; + var BufferWriter = function () { + function BufferWriter() { + this._ops = []; + } + Object.defineProperty(BufferWriter.prototype, "ops", { + get: function get() { + return this._ops; + }, + enumerable: false, + configurable: true + }); + BufferWriter.prototype.clear = function () { + this._ops = []; + }; + BufferWriter.prototype.push = function (req) { + this._ops.push(this.req2op(req)); + return this; + }; + BufferWriter.prototype.req2op = function (req) { + if (req.type === 'string' || req.type === 'buffer') { + var valueLength = this.measureLength(req); + this.push({ + type: 'varint', + value: Varint64.from(valueLength) + }); + return __assign$1(__assign$1({}, req), { + length: valueLength + }); + } + else { + var length_1 = this.measureLength(req); + return __assign$1(__assign$1({}, req), { + length: length_1 + }); + } + }; + BufferWriter.prototype.measureLength = function (req) { + switch (req.type) { + case 'varint': + return req.value.byteLength; + case 'string': + return Utf8Coder.measureLength(req.value); + case 'buffer': + return req.value.byteLength; + case 'double': + return 8; + case 'boolean': + return 1; + default: + return NaN; + } + }; + BufferWriter.prototype.finish = function () { + var byteLength = this._ops.sum(function (v) { + return v.length; + }); + var pos = 0; + var buf = new Uint8Array(byteLength); + var view = new DataView(buf.buffer); + for (var _i = 0, _a = this._ops; _i < _a.length; _i++) { + var op = _a[_i]; + switch (op.type) { + case 'varint': + var newPos = op.value.writeToBuffer(buf, pos); + if (newPos !== pos + op.length) { + throw new Error("Error varint measuredLength " + op.length + ", actual is " + (newPos - pos) + ", value is " + op.value.toNumber()); + } + break; + case 'double': + view.setFloat64(buf.byteOffset + pos, op.value); + break; + case 'string': + var encLen = Utf8Coder.write(op.value, buf, pos); + if (encLen !== op.length) { + throw new Error("Expect " + op.length + " bytes but encoded " + encLen + " bytes"); + } + break; + case 'buffer': + buf.subarray(pos, pos + op.length).set(op.value); + break; + case 'boolean': + view.setUint8(buf.byteOffset + pos, op.value ? 255 : 0); + break; + } + pos += op.length; + } + return buf; + }; + return BufferWriter; + }(); + var Encoder = function () { + function Encoder(options) { + this._options = options; + this._writer = new BufferWriter(); + this._validator = options.validator; + } + Encoder.prototype.encode = function (value, schema) { + this._writer.clear(); + this._write(value, schema); + return this._writer.finish(); + }; + Encoder.prototype._write = function (value, schema, options) { + switch (schema.type) { + case SchemaType.Boolean: + this._writer.push({ + type: 'boolean', + value: value + }); + break; + case SchemaType.Number: + this._writeNumber(value, schema); + break; + case SchemaType.String: + this._writer.push({ + type: 'string', + value: value + }); + break; + case SchemaType.Array: + { + var _v = value; + this._writer.push({ + type: 'varint', + value: Varint64.from(_v.length) + }); + for (var i = 0; i < _v.length; ++i) { + this._write(_v[i], schema.elementType); + } + break; + } + case SchemaType.Tuple: + { + if (schema.elementTypes.length > 64) { + throw new Error('Elements oversized, maximum supported tuple elements is 64, now get ' + schema.elementTypes.length); + } + var _v = value; + var maskIndices = []; + for (var i = 0; i < _v.length; ++i) { + if (_v[i] === undefined || this._nullAsUndefined(_v[i], schema.elementTypes[i])) { + continue; + } + maskIndices.push(i); + } + var lo = 0; + var hi = 0; + for (var _i = 0, maskIndices_1 = maskIndices; _i < maskIndices_1.length; _i++) { + var v = maskIndices_1[_i]; + if (v < 32) { + lo |= 1 << v; + } + else { + hi |= 1 << v - 32; + } + } + this._writer.push({ + type: 'varint', + value: new Varint64(hi, lo) + }); + for (var _a = 0, maskIndices_2 = maskIndices; _a < maskIndices_2.length; _a++) { + var i = maskIndices_2[_a]; + this._write(_v[i], schema.elementTypes[i]); + } + break; + } + case SchemaType.Enum: + var enumItem = schema.members.find(function (v) { + return v.value === value; + }); + if (!enumItem) { + throw new Error("Unexpect enum value: " + value); + } + this._writer.push({ + type: 'varint', + value: Varint64.from(enumItem.id) + }); + break; + case SchemaType.Any: + if (value === undefined) { + this._writer.push({ + type: 'string', + value: 'undefined' + }); + } + else { + this._writer.push({ + type: 'string', + value: JSON.stringify(value) + }); + } + break; + case SchemaType.Object: + this._writer.push({ + type: 'string', + value: JSON.stringify(value) + }); + break; + case SchemaType.Literal: + break; + case SchemaType.Interface: + this._writeInterface(value, schema, options); + break; + case SchemaType.Buffer: + this._writeBuffer(value, schema); + break; + case SchemaType.IndexedAccess: + case SchemaType.Reference: + this._write(value, this._validator.protoHelper.parseReference(schema), options); + break; + case SchemaType.Partial: + case SchemaType.Pick: + case SchemaType.Omit: + case SchemaType.Overwrite: + var parsed = this._validator.protoHelper.parseMappedType(schema); + if (parsed.type === 'Interface') { + this._writePureMappedType(value, schema, options); + } + else { + this._writeUnion(value, parsed, options === null || options === void 0 ? void 0 : options.skipFields); + } + break; + case SchemaType.Union: + this._writeUnion(value, schema, options === null || options === void 0 ? void 0 : options.skipFields); + break; + case SchemaType.Intersection: + this._writeIntersection(value, schema, options === null || options === void 0 ? void 0 : options.skipFields); + break; + case SchemaType.Date: + this._writer.push({ + type: 'varint', + value: Varint64.from(value.getTime()) + }); + break; + case SchemaType.NonNullable: + this._write(value, schema.target, options); + break; + default: + throw new Error("Unrecognized schema type: " + schema.type); + } + }; + Encoder.prototype._writePureMappedType = function (value, schema, options) { + if (!options) { + options = {}; + } + if (schema.type === 'Pick') { + if (options.pickFields) { + var newPickFields = {}; + for (var _i = 0, _a = schema.keys; _i < _a.length; _i++) { + var v = _a[_i]; + if (options.pickFields[v]) { + newPickFields[v] = 1; + } + } + options.pickFields = newPickFields; + } + else { + options.pickFields = {}; + for (var _b = 0, _c = schema.keys; _b < _c.length; _b++) { + var v = _c[_b]; + options.pickFields[v] = 1; + } + } + } + else if (schema.type === 'Omit') { + if (!(options === null || options === void 0 ? void 0 : options.skipFields)) { + if (!options) { + options = {}; + } + options.skipFields = {}; + } + for (var _d = 0, _e = schema.keys; _d < _e.length; _d++) { + var v = _e[_d]; + options.skipFields[v] = 1; + } + } + else if (schema.type === 'Overwrite') { + var parsed = this._parseOverwrite(value, schema); + this._write(parsed.overwriteValue, parsed.overwrite, options); + } + else if (schema.type === 'Partial') + ; + else { + throw new Error('Invalid PureMappedType child: ' + schema.type); + } + var parsedTarget = this._validator.protoHelper.parseReference(schema.target); + if (parsedTarget.type === 'Interface') { + this._writeInterface(value, parsedTarget, options); + } + else { + this._writePureMappedType(value, parsedTarget, options); + } + }; + Encoder.prototype._writeNumber = function (value, schema) { + var scalarType = schema.scalarType || 'double'; + switch (scalarType) { + case 'double': + this._writer.push({ + type: scalarType, + value: value + }); + break; + case 'int': + this._writer.push({ + type: 'varint', + value: Varint64.from(value).zzEncode() + }); + break; + case 'uint': + this._writer.push({ + type: 'varint', + value: Varint64.from(value) + }); + break; + default: + throw new Error('Scalar type not support : ' + scalarType); + } + }; + Encoder.prototype._writeInterface = function (value, schema, options) { + if (!options) { + options = {}; + } + if (!options.skipFields) { + options.skipFields = {}; + } + var opStartOps = this._writer.ops.length; + var blockIdCount = 0; + if (schema.extends) { + if (schema.extends.length > Config.interface.maxExtendsNum) { + throw new Error("Max support " + Config.interface.maxExtendsNum + " extends, actual: " + schema.extends.length); + } + for (var _i = 0, _a = schema.extends; _i < _a.length; _i++) { + var extend = _a[_i]; + var blockId = extend.id + 1; + this._writer.push({ + type: 'varint', + value: Varint64.from(blockId) + }); + var blockIdPos = this._writer.ops.length - 1; + var opsLengthBeforeWrite = this._writer.ops.length; + var parsedExtend = this._validator.protoHelper.parseReference(extend.type); + this._writeInterface(value, parsedExtend, __assign$1(__assign$1({}, options), { + skipIndexSignature: !!schema.indexSignature || options.skipIndexSignature + })); + if (this._writer.ops.length === opsLengthBeforeWrite + 1) { + this._writer.ops.splice(this._writer.ops.length - 2, 2); + } + else { + ++blockIdCount; + this._processIdWithLengthType(blockIdPos, extend.type); + } + } + } + if (schema.properties) { + for (var _b = 0, _c = schema.properties; _b < _c.length; _b++) { + var property = _c[_b]; + var parsedType = this._validator.protoHelper.parseReference(property.type); + var propValue = value[property.name]; + if (options.pickFields && !options.pickFields[property.name]) { + continue; + } + if (parsedType.type === 'Literal') { + options.skipFields[property.name] = 1; + continue; + } + if (this._nullAsUndefined(propValue, property.type)) { + propValue = undefined; + } + if (propValue === undefined) { + continue; + } + if (options.skipFields[property.name]) { + continue; + } + options.skipFields[property.name] = 1; + var blockId = property.id + Config.interface.maxExtendsNum + 1; + this._writer.push({ + type: 'varint', + value: Varint64.from(blockId) + }); + var blockIdPos = this._writer.ops.length - 1; + this._write(propValue, parsedType); + ++blockIdCount; + this._processIdWithLengthType(blockIdPos, parsedType); + } + } + if (!options.skipIndexSignature) { + var flat = this._validator.protoHelper.getFlatInterfaceSchema(schema); + if (flat.indexSignature) { + for (var key in value) { + if (value[key] === undefined || this._nullAsUndefined(value[key], flat.indexSignature.type)) { + continue; + } + if (options.pickFields && !options.pickFields[key]) { + continue; + } + if (options.skipFields[key]) { + continue; + } + options.skipFields[key] = 1; + this._writer.push({ + type: 'varint', + value: Varint64.from(0) + }); + var blockIdPos = this._writer.ops.length - 1; + this._writer.push({ + type: 'string', + value: key + }); + var lengthPrefixPos = this._writer.ops.length; + this._write(value[key], flat.indexSignature.type); + ++blockIdCount; + this._processIdWithLengthType(blockIdPos, flat.indexSignature.type, lengthPrefixPos); + } + } + } + this._writer.ops.splice(opStartOps, 0, this._writer.req2op({ + type: 'varint', + value: Varint64.from(blockIdCount) + })); + }; + Encoder.prototype._nullAsUndefined = function (value, type) { + return value === null && this._options.nullAsUndefined && !SchemaUtil.canBeLiteral(type, null); + }; + Encoder.prototype._parseOverwrite = function (value, schema) { + var skipFields = {}; + var target = this._validator.protoHelper.parseReference(schema.target); + var overwrite = this._validator.protoHelper.parseReference(schema.overwrite); + var flatTarget = this._validator.protoHelper.getFlatInterfaceSchema(target); + var flatOverwrite = this._validator.protoHelper.getFlatInterfaceSchema(overwrite); + var overwriteValue = {}; + var targetValue = {}; + if (flatOverwrite.properties) { + for (var _i = 0, _a = flatOverwrite.properties; _i < _a.length; _i++) { + var property = _a[_i]; + if (value[property.name] !== undefined && !skipFields[property.name]) { + overwriteValue[property.name] = value[property.name]; + skipFields[property.name] = 1; + } + } + } + if (flatTarget.properties) { + for (var _b = 0, _c = flatTarget.properties; _b < _c.length; _b++) { + var property = _c[_b]; + if (value[property.name] !== undefined && !skipFields[property.name]) { + targetValue[property.name] = value[property.name]; + skipFields[property.name] = 1; + } + } + } + var indexSignatureWriteValue; + var indexSignature; + if (flatOverwrite.indexSignature) { + indexSignature = flatOverwrite.indexSignature; + indexSignatureWriteValue = overwriteValue; + } + else if (flatTarget.indexSignature) { + indexSignature = flatTarget.indexSignature; + indexSignatureWriteValue = targetValue; + } + if (indexSignature) { + for (var key in value) { + if (skipFields[key]) { + continue; + } + indexSignatureWriteValue[key] = value[key]; + skipFields[key] = 1; + } + } + return { + target: target, + targetValue: targetValue, + overwrite: overwrite, + overwriteValue: overwriteValue + }; + }; + Encoder.prototype._writeUnion = function (value, schema, skipFields, unionProperties) { + if (skipFields === void 0) { + skipFields = {}; + } + var encodeStartPos = this._writer.ops.length; + var idNum = 0; + if (this._nullAsUndefined(value, schema)) { + value = undefined; + } + for (var _i = 0, _a = schema.members; _i < _a.length; _i++) { + var member = _a[_i]; + var vRes = this._validator.validate(value, member.type, { + excessPropertyChecks: false, + strictNullChecks: true + }); + if (vRes.isSucc) { + this._writer.push({ + type: 'varint', + value: Varint64.from(member.id) + }); + var idPos = this._writer.ops.length - 1; + if (member.type.type === 'Union') { + this._writeUnion(value, member.type, skipFields); + } + else { + this._write(value, member.type, { + skipFields: skipFields + }); + } + idNum++; + this._processIdWithLengthType(idPos, member.type); + if (_typeof(value) !== 'object') { + break; + } + } + } + if (idNum > 0) { + this._writer.ops.splice(encodeStartPos, 0, this._writer.req2op({ + type: 'varint', + value: Varint64.from(idNum) + })); + return; + } + else { + throw new Error('Non member is satisfied for union type'); + } + }; + Encoder.prototype._writeIntersection = function (value, schema, skipFields) { + if (skipFields === void 0) { + skipFields = {}; + } + this._writer.push({ + type: 'varint', + value: Varint64.from(schema.members.length) + }); + for (var _i = 0, _a = schema.members; _i < _a.length; _i++) { + var member = _a[_i]; + this._writer.push({ + type: 'varint', + value: Varint64.from(member.id) + }); + var idPos = this._writer.ops.length - 1; + this._write(value, member.type, { + skipFields: skipFields + }); + this._processIdWithLengthType(idPos, member.type); + } + }; + Encoder.prototype._writeBuffer = function (value, schema) { + if (value instanceof ArrayBuffer) { + this._writer.push({ + type: 'buffer', + value: new Uint8Array(value) + }); + } + else if (value instanceof Uint8Array) { + this._writer.push({ + type: 'buffer', + value: value + }); + } + else { + var key = value.constructor.name; + var arrType = TypedArrays[key]; + var uint8Arr = new Uint8Array(value.buffer, value.byteOffset, value.length * arrType.BYTES_PER_ELEMENT); + this._writer.push({ + type: 'buffer', + value: uint8Arr + }); + } + }; + Encoder.prototype._processIdWithLengthType = function (idPos, payloadType, lengthPrefixPos) { + var idOp = this._writer.ops[idPos]; + if (idOp.type !== 'varint') { + throw new Error('Error idPos: ' + idPos); + } + var parsedSchema = this._validator.protoHelper.parseReference(payloadType); + var lengthInfo = IdBlockUtil.getPayloadLengthInfo(parsedSchema); + var newId = (idOp.value.toNumber() << 2) + lengthInfo.lengthType; + this._writer.ops[idPos] = this._writer.req2op({ + type: 'varint', + value: Varint64.from(newId) + }); + if (lengthInfo.needLengthPrefix) { + var payloadByteLength = this._writer.ops.filter(function (v, i) { + return i > idPos; + }).sum(function (v) { + return v.length; + }); + this._writer.ops.splice(lengthPrefixPos == undefined ? idPos + 1 : lengthPrefixPos, 0, this._writer.req2op({ + type: 'varint', + value: Varint64.from(payloadByteLength) + })); + } + }; + return Encoder; + }(); + var TSBuffer = function () { + function TSBuffer(proto, options) { + this._options = { + excessPropertyChecks: true, + strictNullChecks: true, + skipEncodeValidate: false, + skipDecodeValidate: false, + cloneProto: true + }; + this._options = __assign$1(__assign$1({}, this._options), options); + this._proto = this._options.cloneProto ? Object.merge({}, proto) : proto; + this._validator = new TSBufferValidator(this._proto, { + excessPropertyChecks: this._options.excessPropertyChecks, + strictNullChecks: this._options.strictNullChecks + }); + this.validate = this._validator.validate.bind(this._validator); + this.prune = this._validator.prune.bind(this._validator); + this._encoder = new Encoder({ + validator: this._validator, + nullAsUndefined: !this._options.strictNullChecks + }); + this._decoder = new Decoder({ + validator: this._validator, + undefinedAsNull: !this._options.strictNullChecks + }); + } + TSBuffer.prototype.encode = function (value, schemaOrId, options) { + var _a; + var schema; + if (typeof schemaOrId === 'string') { + schema = this._proto[schemaOrId]; + if (!schema) { + return { + isSucc: false, + errMsg: "Cannot find schema\uFF1A " + schemaOrId + }; + } + } + else { + schema = schemaOrId; + } + if (!((_a = options === null || options === void 0 ? void 0 : options.skipValidate) !== null && _a !== void 0 ? _a : this._options.skipEncodeValidate)) { + var vRes = this._validator.validate(value, schema, { + excessPropertyChecks: false + }); + if (!vRes.isSucc) { + return vRes; + } + } + var buf; + try { + buf = this._encoder.encode(value, schema); + } + catch (e) { + return { + isSucc: false, + errMsg: e.message + }; + } + return { + isSucc: true, + buf: buf + }; + }; + TSBuffer.prototype.decode = function (buf, schemaOrId, options) { + var _a; + var schema; + if (typeof schemaOrId === 'string') { + schema = this._proto[schemaOrId]; + if (!schema) { + return { + isSucc: false, + errMsg: "Cannot find schema\uFF1A " + schemaOrId + }; + } + } + else { + schema = schemaOrId; + } + var value; + try { + value = this._decoder.decode(buf, schema); + } + catch (e) { + return { + isSucc: false, + errMsg: e.message + }; + } + if (!((_a = options === null || options === void 0 ? void 0 : options.skipValidate) !== null && _a !== void 0 ? _a : this._options.skipDecodeValidate)) { + var vRes = this._validator.validate(value, schema); + if (!vRes.isSucc) { + return vRes; + } + } + return { + isSucc: true, + value: value + }; + }; + return TSBuffer; + }(); + var Counter = function () { + function Counter(min, max) { + if (min === void 0) { + min = 1; + } + if (max === void 0) { + max = Number.MAX_SAFE_INTEGER; + } + this._min = min; + this._max = max; + this._last = max; + } + Counter.prototype.reset = function () { + this._last = this._max; + }; + Counter.prototype.getNext = function (notInc) { + return this._last >= this._max ? this._last = this._min : notInc ? this._last : ++this._last; + }; + Object.defineProperty(Counter.prototype, "last", { + get: function get() { + return this._last; + }, + enumerable: false, + configurable: true + }); + return Counter; + }(); + var Flow = function () { + function Flow() { + this.nodes = []; + this.onError = function (e, last, input, logger) { + logger === null || logger === void 0 ? void 0 : logger.error('Uncaught FlowError:', e); + }; + } + Flow.prototype.exec = function (input, logger) { + return __awaiter$1(this, void 0, void 0, function () { + var res, i, e_1; + return __generator$1(this, function (_a) { + switch (_a.label) { + case 0: + res = input; + i = 0; + _a.label = 1; + case 1: + if (!(i < this.nodes.length)) + return [3, + 7]; + _a.label = 2; + case 2: + _a.trys.push([2, 4, , 5]); + return [4, + this.nodes[i](res)]; + case 3: + res = _a.sent(); + return [3, + 5]; + case 4: + e_1 = _a.sent(); + this.onError(e_1, res, input, logger); + return [2, + undefined]; + case 5: + if (res === null || res === undefined) { + return [2, + res]; + } + _a.label = 6; + case 6: + ++i; + return [3, + 1]; + case 7: + return [2, + res]; + } + }); + }); + }; + Flow.prototype.push = function (node) { + this.nodes.push(node); + return node; + }; + Flow.prototype.remove = function (node) { + return this.nodes.remove(function (v) { + return v === node; + }); + }; + return Flow; + }(); + var MsgHandlerManager = function () { + function MsgHandlerManager() { + this._handlers = {}; + } + MsgHandlerManager.prototype.forEachHandler = function (msgName, logger) { + var args = []; + for (var _i = 2; _i < arguments.length; _i++) { + args[_i - 2] = arguments[_i]; + } + var handlers = this._handlers[msgName]; + if (!handlers) { + return []; + } + var output = []; + for (var _a = 0, handlers_1 = handlers; _a < handlers_1.length; _a++) { + var handler = handlers_1[_a]; + try { + output.push(handler.apply(void 0, args)); + } + catch (e) { + logger === null || logger === void 0 ? void 0 : logger.error('[MsgHandlerError]', e); + } + } + return output; + }; + MsgHandlerManager.prototype.addHandler = function (msgName, handler) { + var handlers = this._handlers[msgName]; + if (!handlers) { + handlers = this._handlers[msgName] = []; + } + else if (handlers.some(function (v) { + return v === handler; + })) { + return; + } + handlers.push(handler); + }; + MsgHandlerManager.prototype.removeHandler = function (msgName, handler) { + var handlers = this._handlers[msgName]; + if (!handlers) { + return; + } + handlers.removeOne(function (v) { + return v === handler; + }); + }; + MsgHandlerManager.prototype.removeAllHandlers = function (msgName) { + this._handlers[msgName] = undefined; + }; + return MsgHandlerManager; + }(); + var ServiceMapUtil = function () { + function ServiceMapUtil() { } + ServiceMapUtil.getServiceMap = function (proto) { + var map = { + id2Service: {}, + apiName2Service: {}, + msgName2Service: {} + }; + for (var _i = 0, _a = proto.services; _i < _a.length; _i++) { + var v = _a[_i]; + var match = v.name.match(/(.+\/)?([^\/]+)$/); + var path = match[1] || ''; + var name_1 = match[2]; + if (v.type === 'api') { + var svc = __assign$1(__assign$1({}, v), { + reqSchemaId: path + "Ptl" + name_1 + "/Req" + name_1, + resSchemaId: path + "Ptl" + name_1 + "/Res" + name_1 + }); + map.apiName2Service[v.name] = svc; + map.id2Service[v.id] = svc; + } + else { + var svc = __assign$1(__assign$1({}, v), { + msgSchemaId: path + "Msg" + name_1 + "/Msg" + name_1 + }); + map.msgName2Service[v.name] = svc; + map.id2Service[v.id] = svc; + } + } + return map; + }; + return ServiceMapUtil; + }(); + var TransportDataUtil = function () { + function TransportDataUtil() { } + Object.defineProperty(TransportDataUtil, "tsbuffer", { + get: function get() { + if (!this._tsbuffer) { + this._tsbuffer = new TSBuffer(TransportDataProto); + } + return this._tsbuffer; + }, + enumerable: false, + configurable: true + }); + TransportDataUtil.encodeApiReturn = function (tsbuffer, service, apiReturn, sn) { + var serverOutputData = { + sn: sn, + serviceId: sn !== undefined ? service.id : undefined + }; + if (apiReturn.isSucc) { + var op = tsbuffer.encode(apiReturn.res, service.resSchemaId); + if (!op.isSucc) { + return op; + } + serverOutputData.buffer = op.buf; + } + else { + serverOutputData.error = apiReturn.err; + } + return this.tsbuffer.encode(serverOutputData, 'ServerOutputData'); + }; + TransportDataUtil.encodeClientMsg = function (tsbuffer, service, msg) { + var op = tsbuffer.encode(msg, service.msgSchemaId); + if (!op.isSucc) { + return op; + } + var serverInputData = { + serviceId: service.id, + buffer: op.buf + }; + return this.tsbuffer.encode(serverInputData, 'ServerInputData'); + }; + TransportDataUtil.encodeApiReq = function (tsbuffer, service, req, sn) { + var op = tsbuffer.encode(req, service.reqSchemaId); + if (!op.isSucc) { + return op; + } + var serverInputData = { + serviceId: service.id, + buffer: op.buf, + sn: sn + }; + return this.tsbuffer.encode(serverInputData, 'ServerInputData'); + }; + TransportDataUtil.encodeServerMsg = function (tsbuffer, service, msg) { + var op = tsbuffer.encode(msg, service.msgSchemaId); + if (!op.isSucc) { + return op; + } + var serverOutputData = { + serviceId: service.id, + buffer: op.buf + }; + return this.tsbuffer.encode(serverOutputData, 'ServerOutputData'); + }; + TransportDataUtil.parseServerInput = function (tsbuffer, serviceMap, buf) { + var opServerInputData = this.tsbuffer.decode(buf, 'ServerInputData'); + if (!opServerInputData.isSucc) { + return opServerInputData; + } + var serverInput = opServerInputData.value; + var service = serviceMap.id2Service[serverInput.serviceId]; + if (!service) { + return { + isSucc: false, + errMsg: "Cannot find service ID: " + serverInput.serviceId + }; + } + if (service.type === 'api') { + var opReq = tsbuffer.decode(serverInput.buffer, service.reqSchemaId); + return opReq.isSucc ? { + isSucc: true, + result: { + type: 'api', + service: service, + req: opReq.value, + sn: serverInput.sn + } + } : opReq; + } + else { + var opMsg = tsbuffer.decode(serverInput.buffer, service.msgSchemaId); + return opMsg.isSucc ? { + isSucc: true, + result: { + type: 'msg', + service: service, + msg: opMsg.value + } + } : opMsg; + } + }; + TransportDataUtil.parseServerOutout = function (tsbuffer, serviceMap, buf, serviceId) { + var opServerOutputData = this.tsbuffer.decode(buf, 'ServerOutputData'); + if (!opServerOutputData.isSucc) { + return opServerOutputData; + } + var serverOutputData = opServerOutputData.value; + serviceId = serviceId !== null && serviceId !== void 0 ? serviceId : serverOutputData.serviceId; + if (serviceId === undefined) { + return { + isSucc: false, + errMsg: "Missing 'serviceId' in ServerOutput" + }; + } + var service = serviceMap.id2Service[serviceId]; + if (!service) { + return { + isSucc: false, + errMsg: "Invalid service ID: " + serviceId + " (from ServerOutput)" + }; + } + if (service.type === 'msg') { + if (!serverOutputData.buffer) { + return { + isSucc: false, + errMsg: 'Empty msg buffer (from ServerOutput)' + }; + } + var opMsg = tsbuffer.decode(serverOutputData.buffer, service.msgSchemaId); + if (!opMsg.isSucc) { + return opMsg; + } + return { + isSucc: true, + result: { + type: 'msg', + service: service, + msg: opMsg.value + } + }; + } + else { + if (serverOutputData.error) { + return { + isSucc: true, + result: { + type: 'api', + service: service, + sn: serverOutputData.sn, + ret: { + isSucc: false, + err: new TsrpcError(serverOutputData.error) + } + } + }; + } + else { + if (!serverOutputData.buffer) { + return { + isSucc: false, + errMsg: 'Empty API res buffer (from ServerOutput)' + }; + } + var opRes = tsbuffer.decode(serverOutputData.buffer, service.resSchemaId); + if (!opRes.isSucc) { + return opRes; + } + return { + isSucc: true, + result: { + type: 'api', + service: service, + sn: serverOutputData.sn, + ret: { + isSucc: true, + res: opRes.value + } + } + }; + } + } + }; + return TransportDataUtil; + }(); + var BaseClient = function () { + function BaseClient(proto, options) { + this._msgHandlers = new MsgHandlerManager(); + this.flows = { + preCallApiFlow: new Flow(), + preApiReturnFlow: new Flow(), + postApiReturnFlow: new Flow(), + preSendMsgFlow: new Flow(), + postSendMsgFlow: new Flow(), + preSendBufferFlow: new Flow(), + preRecvBufferFlow: new Flow(), + preConnectFlow: new Flow(), + postConnectFlow: new Flow(), + postDisconnectFlow: new Flow() + }; + this._apiSnCounter = new Counter(1); + this._pendingApis = []; + this.options = options; + this.serviceMap = ServiceMapUtil.getServiceMap(proto); + this.tsbuffer = new TSBuffer(proto.types); + this.logger = this.options.logger; + } + Object.defineProperty(BaseClient.prototype, "lastSN", { + get: function get() { + return this._apiSnCounter.last; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(BaseClient.prototype, "nextSN", { + get: function get() { + return this._apiSnCounter.getNext(true); + }, + enumerable: false, + configurable: true + }); + BaseClient.prototype.callApi = function (apiName, req, options) { + if (options === void 0) { + options = {}; + } + return __awaiter$1(this, void 0, void 0, function () { + var sn, pendingItem, promise; + var _this = this; + return __generator$1(this, function (_a) { + sn = this._apiSnCounter.getNext(); + pendingItem = { + sn: sn, + abortKey: options.abortKey, + service: this.serviceMap.apiName2Service[apiName] + }; + this._pendingApis.push(pendingItem); + promise = new Promise(function (rs) { + return __awaiter$1(_this, void 0, void 0, function () { + var pre, ret, preReturn; + return __generator$1(this, function (_a) { + switch (_a.label) { + case 0: + return [4, + this.flows.preCallApiFlow.exec({ + apiName: apiName, + req: req, + options: options + }, this.logger)]; + case 1: + pre = _a.sent(); + if (!pre || pendingItem.isAborted) { + this.abort(pendingItem.sn); + return [2 + ]; + } + if (!pre.return) + return [3, + 2]; + ret = pre.return; + return [3, + 4]; + case 2: + return [4, + this._doCallApi(pre.apiName, pre.req, pre.options, pendingItem)]; + case 3: + ret = _a.sent(); + _a.label = 4; + case 4: + if (pendingItem.isAborted) { + return [2 + ]; + } + return [4, + this.flows.preApiReturnFlow.exec(__assign$1(__assign$1({}, pre), { + return: ret + }), this.logger)]; + case 5: + preReturn = _a.sent(); + if (!preReturn) { + this.abort(pendingItem.sn); + return [2 + ]; + } + rs(preReturn.return); + this.flows.postApiReturnFlow.exec(preReturn, this.logger); + return [2 + ]; + } + }); + }); + }); + promise.catch().then(function () { + _this._pendingApis.removeOne(function (v) { + return v.sn === pendingItem.sn; + }); + }); + return [2, + promise]; + }); + }); + }; + BaseClient.prototype._doCallApi = function (apiName, req, options, pendingItem) { + var _a; + if (options === void 0) { + options = {}; + } + return __awaiter$1(this, void 0, void 0, function () { + var promise; + var _this = this; + return __generator$1(this, function (_b) { + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.log("[ApiReq] #" + pendingItem.sn, apiName, req); + promise = new Promise(function (rs) { + return __awaiter$1(_this, void 0, void 0, function () { + var service, opEncode, promiseReturn, promiseSend, opSend, ret; + var _a, _b, _c; + return __generator$1(this, function (_d) { + switch (_d.label) { + case 0: + service = this.serviceMap.apiName2Service[apiName]; + if (!service) { + rs({ + isSucc: false, + err: new TsrpcError('Invalid api name: ' + apiName, { + code: 'INVALID_API_NAME', + type: TsrpcErrorType.ClientError + }) + }); + return [2 + ]; + } + pendingItem.service = service; + opEncode = this._encodeApiReq(service, req, pendingItem); + if (!opEncode.isSucc) { + rs({ + isSucc: false, + err: new TsrpcError(opEncode.errMsg, { + type: TsrpcErrorType.ClientError, + code: 'ENCODE_REQ_ERR' + }) + }); + return [2 + ]; + } + promiseReturn = this._waitApiReturn(pendingItem, (_a = options.timeout) !== null && _a !== void 0 ? _a : this.options.timeout); + promiseSend = this._sendBuf(opEncode.buf, options, service.id, pendingItem); + return [4, + promiseSend]; + case 1: + opSend = _d.sent(); + if (opSend.err) { + rs({ + isSucc: false, + err: opSend.err + }); + return [2 + ]; + } + return [4, + promiseReturn]; + case 2: + ret = _d.sent(); + if (pendingItem.isAborted) { + return [2 + ]; + } + if (ret.isSucc) { + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.log("[ApiRes] #" + pendingItem.sn + " " + apiName, ret.res); + } + else { + (_c = this.logger) === null || _c === void 0 ? void 0 : _c.log("[ApiErr] #" + pendingItem.sn + " " + apiName, ret.err); + } + rs(ret); + return [2 + ]; + } + }); + }); + }); + return [2, + promise]; + }); + }); + }; + BaseClient.prototype._encodeApiReq = function (service, req, pendingItem) { + return TransportDataUtil.encodeApiReq(this.tsbuffer, service, req, this.type === 'LONG' ? pendingItem.sn : undefined); + }; + BaseClient.prototype.sendMsg = function (msgName, msg, options) { + var _this = this; + if (options === void 0) { + options = {}; + } + var promise = new Promise(function (rs) { + return __awaiter$1(_this, void 0, void 0, function () { + var pre, service, opEncode, promiseSend, opSend; + var _a, _b; + return __generator$1(this, function (_c) { + switch (_c.label) { + case 0: + return [4, + this.flows.preSendMsgFlow.exec({ + msgName: msgName, + msg: msg, + options: options + }, this.logger)]; + case 1: + pre = _c.sent(); + if (!pre) { + return [2 + ]; + } + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.log("[SendMsg]", msgName, msg); + service = this.serviceMap.msgName2Service[msgName]; + if (!service) { + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.error('Invalid msg name: ' + msgName); + rs({ + isSucc: false, + err: new TsrpcError('Invalid msg name: ' + msgName, { + code: 'INVALID_MSG_NAME', + type: TsrpcErrorType.ClientError + }) + }); + return [2 + ]; + } + opEncode = this._encodeClientMsg(service, msg); + if (!opEncode.isSucc) { + rs({ + isSucc: false, + err: new TsrpcError(opEncode.errMsg, { + type: TsrpcErrorType.ClientError, + code: 'ENCODE_MSG_ERR' + }) + }); + return [2 + ]; + } + promiseSend = this._sendBuf(opEncode.buf, options, service.id); + return [4, + promiseSend]; + case 2: + opSend = _c.sent(); + if (opSend.err) { + rs({ + isSucc: false, + err: opSend.err + }); + return [2 + ]; + } + rs({ + isSucc: true + }); + this.flows.postSendMsgFlow.exec(pre, this.logger); + return [2 + ]; + } + }); + }); + }); + return promise; + }; + BaseClient.prototype._encodeClientMsg = function (service, msg) { + return TransportDataUtil.encodeClientMsg(this.tsbuffer, service, msg); + }; + BaseClient.prototype.listenMsg = function (msgName, handler) { + this._msgHandlers.addHandler(msgName, handler); + return handler; + }; + BaseClient.prototype.unlistenMsg = function (msgName, handler) { + this._msgHandlers.removeHandler(msgName, handler); + }; + BaseClient.prototype.unlistenMsgAll = function (msgName) { + this._msgHandlers.removeAllHandlers(msgName); + }; + BaseClient.prototype.abort = function (sn) { + var _a, _b; + var index = this._pendingApis.findIndex(function (v) { + return v.sn === sn; + }); + if (index === -1) { + return; + } + var pendingItem = this._pendingApis[index]; + this._pendingApis.splice(index, 1); + pendingItem.onReturn = undefined; + pendingItem.isAborted = true; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.log("[ApiAbort] #" + pendingItem.sn + " " + pendingItem.service.name); + (_b = pendingItem.onAbort) === null || _b === void 0 ? void 0 : _b.call(pendingItem); + }; + BaseClient.prototype.abortByKey = function (abortKey) { + var _this = this; + this._pendingApis.filter(function (v) { + return v.abortKey === abortKey; + }).forEach(function (v) { + _this.abort(v.sn); + }); + }; + BaseClient.prototype.abortAll = function () { + var _this = this; + this._pendingApis.slice().forEach(function (v) { + return _this.abort(v.sn); + }); + }; + BaseClient.prototype._onRecvBuf = function (buf, pendingApiItem) { + var _a, _b, _c, _d, _e, _f, _g; + return __awaiter$1(this, void 0, void 0, function () { + var sn, pre, opParsed, parsed; + return __generator$1(this, function (_h) { + switch (_h.label) { + case 0: + sn = pendingApiItem === null || pendingApiItem === void 0 ? void 0 : pendingApiItem.sn; + this.options.debugBuf && ((_a = this.logger) === null || _a === void 0 ? void 0 : _a.debug('[RecvBuf]' + (sn ? ' #' + sn : ''), 'length=' + buf.length, buf)); + return [4, + this.flows.preRecvBufferFlow.exec({ + buf: buf, + sn: sn + }, this.logger)]; + case 1: + pre = _h.sent(); + if (!pre) { + return [2 + ]; + } + buf = pre.buf; + opParsed = TransportDataUtil.parseServerOutout(this.tsbuffer, this.serviceMap, buf, pendingApiItem === null || pendingApiItem === void 0 ? void 0 : pendingApiItem.service.id); + if (opParsed.isSucc) { + parsed = opParsed.result; + if (parsed.type === 'api') { + sn = sn !== null && sn !== void 0 ? sn : parsed.sn; + (_c = (_b = this._pendingApis.find(function (v) { + return v.sn === sn; + })) === null || _b === void 0 ? void 0 : _b.onReturn) === null || _c === void 0 ? void 0 : _c.call(_b, parsed.ret); + } + else if (parsed.type === 'msg') { + (_d = this.logger) === null || _d === void 0 ? void 0 : _d.log("[RecvMsg] " + parsed.service.name, parsed.msg); + this._msgHandlers.forEachHandler(parsed.service.name, this.logger, parsed.msg, this); + } + } + else { + (_e = this.logger) === null || _e === void 0 ? void 0 : _e.error('ParseServerOutputError: ' + opParsed.errMsg); + (_f = this.logger) === null || _f === void 0 ? void 0 : _f.error('Please check whether the proto on the server is the same as that on the client'); + if (pendingApiItem) { + (_g = pendingApiItem.onReturn) === null || _g === void 0 ? void 0 : _g.call(pendingApiItem, { + isSucc: false, + err: new TsrpcError('Parse server output error', { + type: TsrpcErrorType.ServerError + }) + }); + } + } + return [2 + ]; + } + }); + }); + }; + BaseClient.prototype._waitApiReturn = function (pendingItem, timeout) { + return __awaiter$1(this, void 0, void 0, function () { + var _this = this; + return __generator$1(this, function (_a) { + return [2, + new Promise(function (rs) { + var timer; + if (timeout) { + timer = setTimeout(function () { + timer = undefined; + _this._pendingApis.removeOne(function (v) { + return v.sn === pendingItem.sn; + }); + rs({ + isSucc: false, + err: new TsrpcError('Request Timeout', { + type: TsrpcErrorType.NetworkError, + code: 'TIMEOUT' + }) + }); + }, timeout); + } + pendingItem.onReturn = function (ret) { + if (timer) { + clearTimeout(timer); + timer = undefined; + } + _this._pendingApis.removeOne(function (v) { + return v.sn === pendingItem.sn; + }); + rs(ret); + }; + })]; + }); + }); + }; + return BaseClient; + }(); + var defaultBaseClientOptions = {}; + var BaseHttpClient = function (_super) { + __extends$1(BaseHttpClient, _super); + function BaseHttpClient(proto, http, options) { + var _a; + var _this = _super.call(this, proto, __assign$1(__assign$1({}, defaultBaseHttpClientOptions), options)) || this; + _this.type = 'SHORT'; + _this._http = http; + _this._jsonServer = _this.options.server + (_this.options.server.endsWith('/') ? '' : '/'); + (_a = _this.logger) === null || _a === void 0 ? void 0 : _a.log('TSRPC HTTP Client :', _this.options.server); + return _this; + } + BaseHttpClient.prototype._encodeApiReq = function (service, req, pendingItem) { + if (this.options.json) { + if (this.options.jsonPrune) { + var opPrune = this.tsbuffer.prune(req, pendingItem.service.reqSchemaId); + if (!opPrune.isSucc) { + return opPrune; + } + req = opPrune.pruneOutput; + } + return { + isSucc: true, + buf: JSON.stringify(req) + }; + } + else { + return TransportDataUtil.encodeApiReq(this.tsbuffer, service, req, undefined); + } + }; + BaseHttpClient.prototype._encodeClientMsg = function (service, msg) { + if (this.options.json) { + if (this.options.jsonPrune) { + var opPrune = this.tsbuffer.prune(msg, service.msgSchemaId); + if (!opPrune.isSucc) { + return opPrune; + } + msg = opPrune.pruneOutput; + } + return { + isSucc: true, + buf: JSON.stringify(msg) + }; + } + else { + return TransportDataUtil.encodeClientMsg(this.tsbuffer, service, msg); + } + }; + BaseHttpClient.prototype._sendBuf = function (buf, options, serviceId, pendingApiItem) { + return __awaiter$1(this, void 0, void 0, function () { + var sn, promise; + var _this = this; + return __generator$1(this, function (_a) { + if (this.options.json) { + return [2, + this._sendJSON(buf, options, serviceId, pendingApiItem)]; + } + sn = pendingApiItem === null || pendingApiItem === void 0 ? void 0 : pendingApiItem.sn; + promise = new Promise(function (rs) { + return __awaiter$1(_this, void 0, void 0, function () { + var pre, _a, fetchPromise, abort, fetchRes; + var _b; + return __generator$1(this, function (_c) { + switch (_c.label) { + case 0: + return [4, + this.flows.preSendBufferFlow.exec({ + buf: buf, + sn: pendingApiItem === null || pendingApiItem === void 0 ? void 0 : pendingApiItem.sn + }, this.logger)]; + case 1: + pre = _c.sent(); + if (!pre) { + return [2 + ]; + } + buf = pre.buf; + this.options.debugBuf && ((_b = this.logger) === null || _b === void 0 ? void 0 : _b.debug('[SendBuf]' + (sn ? ' #' + sn : ''), "length=" + buf.length, buf)); + _a = this._http.fetch({ + url: this.options.server, + data: buf, + method: 'POST', + timeout: options.timeout || this.options.timeout, + transportOptions: options, + responseType: 'arraybuffer' + }), fetchPromise = _a.promise, abort = _a.abort; + if (pendingApiItem) { + pendingApiItem.onAbort = function () { + abort(); + }; + } + if (pendingApiItem === null || pendingApiItem === void 0 ? void 0 : pendingApiItem.isAborted) { + return [2 + ]; + } + return [4, + fetchPromise]; + case 2: + fetchRes = _c.sent(); + if (!fetchRes.isSucc) { + rs({ + err: fetchRes.err + }); + return [2 + ]; + } + rs({}); + this._onRecvBuf(fetchRes.res, pendingApiItem); + return [2 + ]; + } + }); + }); + }); + promise.catch(function (e) { }).then(function () { + if (pendingApiItem) { + pendingApiItem.onAbort = undefined; + } + }); + return [2, + promise]; + }); + }); + }; + BaseHttpClient.prototype._sendJSON = function (jsonStr, options, serviceId, pendingApiItem) { + return __awaiter$1(this, void 0, void 0, function () { + var _this = this; + return __generator$1(this, function (_a) { + return [2, + new Promise(function (rs) { + return __awaiter$1(_this, void 0, void 0, function () { + var _a, fetchPromise, abort, fetchRes, ret, opPrune; + var _b; + return __generator$1(this, function (_c) { + switch (_c.label) { + case 0: + _a = this._http.fetch({ + url: this._jsonServer + this.serviceMap.id2Service[serviceId].name, + data: jsonStr, + method: 'POST', + timeout: options.timeout || this.options.timeout, + headers: { + 'Content-Type': 'application/json' + }, + transportOptions: options, + responseType: 'text' + }), fetchPromise = _a.promise, abort = _a.abort; + if (pendingApiItem) { + pendingApiItem.onAbort = function () { + abort(); + }; + } + if (pendingApiItem === null || pendingApiItem === void 0 ? void 0 : pendingApiItem.isAborted) { + return [2 + ]; + } + return [4, + fetchPromise]; + case 1: + fetchRes = _c.sent(); + if (!fetchRes.isSucc) { + rs({ + err: fetchRes.err + }); + return [2 + ]; + } + rs({}); + try { + ret = JSON.parse(fetchRes.res); + } + catch (e) { + ret = { + isSucc: false, + err: new TsrpcError({ + message: e.message, + type: TsrpcError.Type.ServerError, + res: fetchRes.res + }) + }; + } + if (pendingApiItem) { + if (ret.isSucc) { + if (this.options.jsonPrune) { + opPrune = this.tsbuffer.prune(ret.res, pendingApiItem.service.resSchemaId); + if (opPrune.isSucc) { + ret.res = opPrune.pruneOutput; + } + else { + ret = { + isSucc: false, + err: new TsrpcError('Invalid Server Output', { + type: TsrpcError.Type.ClientError, + innerErr: opPrune.errMsg + }) + }; + } + } + } + else { + ret.err = new TsrpcError(ret.err); + } + (_b = pendingApiItem.onReturn) === null || _b === void 0 ? void 0 : _b.call(pendingApiItem, ret); + } + return [2 + ]; + } + }); + }); + })]; + }); + }); + }; + return BaseHttpClient; + }(BaseClient); + var defaultBaseHttpClientOptions = __assign$1(__assign$1({}, defaultBaseClientOptions), { + server: 'http://localhost:3000', + json: false, + jsonPrune: true + }); + var BaseWsClient = function (_super) { + __extends$1(BaseWsClient, _super); + function BaseWsClient(proto, wsp, options) { + var _a; + var _this = _super.call(this, proto, __assign$1(__assign$1({}, defaultBaseWsClientOptions), options)) || this; + _this.type = 'LONG'; + _this._onWsOpen = function () { + var _a; + if (!_this._connecting) { + return; + } + _this._status = WsClientStatus.Opened; + _this._connecting.rs({ + isSucc: true + }); + _this._connecting = undefined; + (_a = _this.logger) === null || _a === void 0 ? void 0 : _a.log('WebSocket connection to server successful'); + _this.flows.postConnectFlow.exec({}, _this.logger); + }; + _this._onWsClose = function (code, reason) { + var _a, _b; + var isConnectedBefore = _this.isConnected; + _this._status = WsClientStatus.Closed; + if (_this._connecting) { + _this._connecting.rs({ + isSucc: false, + errMsg: 'WebSocket connection to server failed' + }); + _this._connecting = undefined; + } + var isManual = !!_this._rsDisconnecting; + if (_this._rsDisconnecting) { + _this._rsDisconnecting(); + _this._rsDisconnecting = undefined; + (_a = _this.logger) === null || _a === void 0 ? void 0 : _a.log('Disconnected succ', "code=" + code + " reason=" + reason); + } + else if (isConnectedBefore) { + (_b = _this.logger) === null || _b === void 0 ? void 0 : _b.log("Lost connection to " + _this.options.server, "code=" + code + " reason=" + reason); + } + if (isConnectedBefore) { + _this.flows.postDisconnectFlow.exec({ + reason: reason, + isManual: isManual + }, _this.logger); + } + }; + _this._onWsError = function (e) { + var _a; + (_a = _this.logger) === null || _a === void 0 ? void 0 : _a.error('[WebSocket Error]', e); + }; + _this._onWsMessage = function (data) { + var _a; + if (typeof data === 'string') { + (_a = _this.logger) === null || _a === void 0 ? void 0 : _a.warn('[RecvText]', data); + } + else { + _this._onRecvBuf(data); + } + }; + _this._status = WsClientStatus.Closed; + _this._wsp = wsp; + wsp.options = { + onOpen: _this._onWsOpen, + onClose: _this._onWsClose, + onError: _this._onWsError, + onMessage: _this._onWsMessage, + logger: _this.logger + }; + (_a = _this.logger) === null || _a === void 0 ? void 0 : _a.log('TSRPC WebSocket Client :', _this.options.server); + return _this; + } + BaseWsClient.prototype._sendBuf = function (buf, options, serviceId, pendingApiItem) { + return __awaiter$1(this, void 0, void 0, function () { + var _this = this; + return __generator$1(this, function (_a) { + return [2, + new Promise(function (rs) { + return __awaiter$1(_this, void 0, void 0, function () { + var pre; + var _a; + return __generator$1(this, function (_b) { + switch (_b.label) { + case 0: + return [4, + this.flows.preSendBufferFlow.exec({ + buf: buf, + sn: pendingApiItem === null || pendingApiItem === void 0 ? void 0 : pendingApiItem.sn + }, this.logger)]; + case 1: + pre = _b.sent(); + if (!pre) { + return [2 + ]; + } + buf = pre.buf; + if (!this.isConnected) { + rs({ + err: new TsrpcError('WebSocket is not connected', { + code: 'WS_NOT_OPEN', + type: TsrpcError.Type.ClientError + }) + }); + return [2 + ]; + } + if (this.options.debugBuf && buf instanceof Uint8Array) { + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.debug('[SendBuf]' + (pendingApiItem ? ' #' + pendingApiItem.sn : ''), "length=" + buf.byteLength, buf); + } + rs(this._wsp.send(buf)); + return [2 + ]; + } + }); + }); + })]; + }); + }); + }; + Object.defineProperty(BaseWsClient.prototype, "status", { + get: function get() { + return this._status; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(BaseWsClient.prototype, "isConnected", { + get: function get() { + return this._status === WsClientStatus.Opened; + }, + enumerable: false, + configurable: true + }); + BaseWsClient.prototype.connect = function () { + var _a; + return __awaiter$1(this, void 0, void 0, function () { + var pre, promiseConnect; + var _this = this; + return __generator$1(this, function (_b) { + switch (_b.label) { + case 0: + if (this.isConnected) { + return [2, + { + isSucc: true + }]; + } + if (this._connecting) { + return [2, + this._connecting.promise]; + } + return [4, + this.flows.preConnectFlow.exec({}, this.logger)]; + case 1: + pre = _b.sent(); + if (pre === null || pre === void 0 ? void 0 : pre.return) { + return [2, + pre.return]; + } + if (!pre) { + return [2, + new Promise(function (rs) { })]; + } + try { + this._wsp.connect(this.options.server); + } + catch (e) { + return [2, + { + isSucc: false, + errMsg: e.message + }]; + } + this._status = WsClientStatus.Opening; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.log("Start connecting " + this.options.server + "..."); + this._connecting = {}; + promiseConnect = new Promise(function (rs) { + _this._connecting.rs = rs; + }); + this._connecting.promise = promiseConnect; + return [2, + promiseConnect]; + } + }); + }); + }; + BaseWsClient.prototype.disconnect = function (code, reason) { + var _a; + return __awaiter$1(this, void 0, void 0, function () { + var _this = this; + return __generator$1(this, function (_b) { + if (this._status === WsClientStatus.Closed) { + return [2 + ]; + } + this._status = WsClientStatus.Closing; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.log('Start disconnecting...'); + return [2, + new Promise(function (rs) { + _this._rsDisconnecting = rs; + _this._wsp.close(code, reason); + })]; + }); + }); + }; + return BaseWsClient; + }(BaseClient); + var defaultBaseWsClientOptions = __assign$1(__assign$1({}, defaultBaseClientOptions), { + server: 'ws://localhost:3000' + }); + var WsClientStatus; + (function (WsClientStatus) { + WsClientStatus["Opening"] = "OPENING"; + WsClientStatus["Opened"] = "OPENED"; + WsClientStatus["Closing"] = "CLOSING"; + WsClientStatus["Closed"] = "CLOSED"; + })(WsClientStatus || (WsClientStatus = {})); + var HttpProxy = (function () { + function HttpProxy() { + } + HttpProxy.prototype.fetch = function (options) { + var _this = this; + var rs; + var promise = new Promise(function (_rs) { + rs = _rs; + }); + var xhr = new XMLHttpRequest(); + if (navigator.userAgent.indexOf('MSIE 8.0;') > -1) { + xhr.onreadystatechange = function () { + return __awaiter$1(_this, void 0, void 0, function () { + return __generator$1(this, function (_a) { + if (xhr.readyState == 4) { + if (xhr.status == 0 || (xhr.response == null && xhr.responseText == null)) { + rs({ + isSucc: false, + err: new TsrpcError('Network Error', { + type: TsrpcError.Type.NetworkError, + httpCode: xhr.status + }) + }); + return [2]; + } + if (xhr.status == 12029) { + rs({ + isSucc: false, + err: new TsrpcError({ + message: 'Network Error', + type: TsrpcError.Type.NetworkError, + httpCode: xhr.status + }) + }); + return [2]; + } + rs({ + isSucc: true, + res: options.responseType === 'text' ? xhr.responseText : new Uint8Array(xhr.response) + }); + } + return [2]; + }); + }); + }; + } + else { + xhr.onerror = function () { + rs({ + isSucc: false, + err: new TsrpcError({ + message: 'Network Error', + type: TsrpcError.Type.NetworkError, + httpCode: xhr.status + }) + }); + }; + xhr.ontimeout = function () { + rs({ + isSucc: false, + err: new TsrpcError({ + message: 'Request Timeout', + type: TsrpcError.Type.NetworkError, + code: 'TIMEOUT' + }) + }); + }; + xhr.onload = function () { + return __awaiter$1(_this, void 0, void 0, function () { + return __generator$1(this, function (_a) { + rs({ + isSucc: true, + res: xhr.response && (options.responseType === 'text' ? xhr.responseText : new Uint8Array(xhr.response)) + }); + return [2]; + }); + }); + }; + var transportOptions_1 = options.transportOptions; + if (!!transportOptions_1.onProgress) { + xhr.upload.onprogress = function (e) { + var _a; + (_a = transportOptions_1.onProgress) === null || _a === void 0 ? void 0 : _a.call(transportOptions_1, e.loaded / e.total); + }; + } + } + xhr.open(options.method, options.url, true); + if (options.headers) { + for (var key in options.headers) { + xhr.setRequestHeader(key, options.headers[key]); + } + } + xhr.responseType = options.responseType; + var timeout = options.timeout; + if (timeout) { + xhr.timeout = timeout; + } + xhr.send(options.data); + var abort = xhr.abort.bind(xhr); + return { + promise: promise, + abort: abort + }; + }; + return HttpProxy; + }()); + var HttpClient = (function (_super) { + __extends$1(HttpClient, _super); + function HttpClient(proto, options) { + var _this = this; + var httpProxy = new HttpProxy; + _this = _super.call(this, proto, httpProxy, __assign$1(__assign$1({}, defaultHttpClientOptions), options)) || this; + return _this; + } + HttpClient.prototype.callApi = function (apiName, req, options) { + if (options === void 0) { + options = {}; + } + return _super.prototype.callApi.call(this, apiName, req, options); + }; + HttpClient.prototype.sendMsg = function (msgName, msg, options) { + if (options === void 0) { + options = {}; + } + return _super.prototype.sendMsg.call(this, msgName, msg, options); + }; + return HttpClient; + }(BaseHttpClient)); + var defaultHttpClientOptions = __assign$1({}, defaultBaseHttpClientOptions); + var WebSocketProxy = (function () { + function WebSocketProxy() { + } + WebSocketProxy.prototype.connect = function (server) { + var _this = this; + this._ws = new WebSocket(server); + this._ws.binaryType = 'arraybuffer'; + this._ws.onopen = this.options.onOpen; + this._ws.onclose = function (e) { + _this.options.onClose(e.code, e.reason); + _this._ws = undefined; + }; + this._ws.onmessage = function (e) { + var _a; + if (e.data instanceof ArrayBuffer) { + _this.options.onMessage(new Uint8Array(e.data)); + } + else if (typeof e.data === 'string') { + _this.options.onMessage(e.data); + } + else { + (_a = _this.options.logger) === null || _a === void 0 ? void 0 : _a.warn('[Unresolved Recv]', e.data); + } + }; + }; + WebSocketProxy.prototype.close = function (code, reason) { + var _a; + (_a = this._ws) === null || _a === void 0 ? void 0 : _a.close(code, reason); + this._ws = undefined; + }; + WebSocketProxy.prototype.send = function (data) { + return __awaiter$1(this, void 0, void 0, function () { + var sendData, buf; + return __generator$1(this, function (_a) { + try { + sendData = void 0; + if (typeof data === 'string') { + sendData = data; + } + else { + buf = data; + if (buf.byteOffset === 0 && buf.byteLength === buf.buffer.byteLength) { + sendData = buf.buffer; + } + else { + sendData = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + } + } + this._ws.send(sendData); + return [2, {}]; + } + catch (err) { + return [2, { + err: new TsrpcError('Network Error', { + code: 'SEND_BUF_ERR', + type: TsrpcError.Type.NetworkError, + innerErr: err + }) + }]; + } + return [2]; + }); + }); + }; + return WebSocketProxy; + }()); + var WsClient = (function (_super) { + __extends$1(WsClient, _super); + function WsClient(proto, options) { + var _this = this; + var wsp = new WebSocketProxy(); + _this = _super.call(this, proto, wsp, __assign$1(__assign$1({}, defaultWsClientOptions), options)) || this; + return _this; + } + return WsClient; + }(BaseWsClient)); + var defaultWsClientOptions = __assign$1({}, defaultBaseWsClientOptions); + + let client = new HttpClient(serviceProto, { + server: 'http://localhost:3000', + logger: console + }); + function test() { + return __awaiter(this, void 0, void 0, function* () { + yield client.callApi('AddData', { + content: 'AAAAA' + }); + let ret = yield client.callApi('GetData', {}); + console.log('ret', ret); + }); + } + test(); + class Main { + constructor() { + if (window["Laya3D"]) + Laya3D.init(GameConfig.width, GameConfig.height); + else + Laya.init(GameConfig.width, GameConfig.height, Laya["WebGL"]); + Laya["Physics"] && Laya["Physics"].enable(); + Laya["DebugPanel"] && Laya["DebugPanel"].enable(); + Laya.stage.scaleMode = GameConfig.scaleMode; + Laya.stage.screenMode = GameConfig.screenMode; + Laya.stage.alignV = GameConfig.alignV; + Laya.stage.alignH = GameConfig.alignH; + Laya.URL.exportSceneToJson = GameConfig.exportSceneToJson; + if (GameConfig.debug || Laya.Utils.getQueryString("debug") == "true") + Laya.enableDebugPanel(); + if (GameConfig.physicsDebug && Laya["PhysicsDebugDraw"]) + Laya["PhysicsDebugDraw"].enable(); + if (GameConfig.stat) + Laya.Stat.show(); + Laya.alertGlobalError(true); + Laya.ResourceVersion.enable("version.json", Laya.Handler.create(this, this.onVersionLoaded), Laya.ResourceVersion.FILENAME_VERSION); + } + onVersionLoaded() { + Laya.AtlasInfoManager.enable("fileconfig.json", Laya.Handler.create(this, this.onConfigLoaded)); + } + onConfigLoaded() { + GameConfig.startScene && Laya.Scene.open(GameConfig.startScene); + } + } + new Main(); + +}()); diff --git a/examples/layaair/frontend/bin/libs/bytebuffer.js b/examples/layaair/frontend/bin/libs/bytebuffer.js new file mode 100644 index 0000000..5495d89 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/bytebuffer.js @@ -0,0 +1,3746 @@ +/* + Copyright 2013-2014 Daniel Wirtz + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +/** + * @license bytebuffer.js (c) 2015 Daniel Wirtz + * Backing buffer: ArrayBuffer, Accessor: Uint8Array + * Released under the Apache License, Version 2.0 + * see: https://github.com/dcodeIO/bytebuffer.js for details + */ +(function(global, factory) { + + /* AMD */ if (typeof define === 'function' && define["amd"]) + define(["long"], factory); + /* CommonJS */ else if (typeof require === 'function' && typeof module === "object" && module && module["exports"]) + module['exports'] = (function() { + var Long; try { Long = require("long"); } catch (e) {} + return factory(Long); + })(); + /* Global */ else + (global["dcodeIO"] = global["dcodeIO"] || {})["ByteBuffer"] = factory(global["dcodeIO"]["Long"]); + +})(this, function(Long) { + "use strict"; + + /** + * Constructs a new ByteBuffer. + * @class The swiss army knife for binary data in JavaScript. + * @exports ByteBuffer + * @constructor + * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}. + * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to + * {@link ByteBuffer.DEFAULT_ENDIAN}. + * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to + * {@link ByteBuffer.DEFAULT_NOASSERT}. + * @expose + */ + var ByteBuffer = function(capacity, littleEndian, noAssert) { + if (typeof capacity === 'undefined') + capacity = ByteBuffer.DEFAULT_CAPACITY; + if (typeof littleEndian === 'undefined') + littleEndian = ByteBuffer.DEFAULT_ENDIAN; + if (typeof noAssert === 'undefined') + noAssert = ByteBuffer.DEFAULT_NOASSERT; + if (!noAssert) { + capacity = capacity | 0; + if (capacity < 0) + throw RangeError("Illegal capacity"); + littleEndian = !!littleEndian; + noAssert = !!noAssert; + } + + /** + * Backing ArrayBuffer. + * @type {!ArrayBuffer} + * @expose + */ + this.buffer = capacity === 0 ? EMPTY_BUFFER : new ArrayBuffer(capacity); + + /** + * Uint8Array utilized to manipulate the backing buffer. Becomes `null` if the backing buffer has a capacity of `0`. + * @type {?Uint8Array} + * @expose + */ + this.view = capacity === 0 ? null : new Uint8Array(this.buffer); + + /** + * Absolute read/write offset. + * @type {number} + * @expose + * @see ByteBuffer#flip + * @see ByteBuffer#clear + */ + this.offset = 0; + + /** + * Marked offset. + * @type {number} + * @expose + * @see ByteBuffer#mark + * @see ByteBuffer#reset + */ + this.markedOffset = -1; + + /** + * Absolute limit of the contained data. Set to the backing buffer's capacity upon allocation. + * @type {number} + * @expose + * @see ByteBuffer#flip + * @see ByteBuffer#clear + */ + this.limit = capacity; + + /** + * Whether to use little endian byte order, defaults to `false` for big endian. + * @type {boolean} + * @expose + */ + this.littleEndian = littleEndian; + + /** + * Whether to skip assertions of offsets and values, defaults to `false`. + * @type {boolean} + * @expose + */ + this.noAssert = noAssert; + }; + + /** + * ByteBuffer version. + * @type {string} + * @const + * @expose + */ + ByteBuffer.VERSION = "5.0.1"; + + /** + * Little endian constant that can be used instead of its boolean value. Evaluates to `true`. + * @type {boolean} + * @const + * @expose + */ + ByteBuffer.LITTLE_ENDIAN = true; + + /** + * Big endian constant that can be used instead of its boolean value. Evaluates to `false`. + * @type {boolean} + * @const + * @expose + */ + ByteBuffer.BIG_ENDIAN = false; + + /** + * Default initial capacity of `16`. + * @type {number} + * @expose + */ + ByteBuffer.DEFAULT_CAPACITY = 16; + + /** + * Default endianess of `false` for big endian. + * @type {boolean} + * @expose + */ + ByteBuffer.DEFAULT_ENDIAN = ByteBuffer.BIG_ENDIAN; + + /** + * Default no assertions flag of `false`. + * @type {boolean} + * @expose + */ + ByteBuffer.DEFAULT_NOASSERT = false; + + /** + * A `Long` class for representing a 64-bit two's-complement integer value. May be `null` if Long.js has not been loaded + * and int64 support is not available. + * @type {?Long} + * @const + * @see https://github.com/dcodeIO/long.js + * @expose + */ + ByteBuffer.Long = Long || null; + + /** + * @alias ByteBuffer.prototype + * @inner + */ + var ByteBufferPrototype = ByteBuffer.prototype; + + /** + * An indicator used to reliably determine if an object is a ByteBuffer or not. + * @type {boolean} + * @const + * @expose + * @private + */ + ByteBufferPrototype.__isByteBuffer__; + + Object.defineProperty(ByteBufferPrototype, "__isByteBuffer__", { + value: true, + enumerable: false, + configurable: false + }); + + // helpers + + /** + * @type {!ArrayBuffer} + * @inner + */ + var EMPTY_BUFFER = new ArrayBuffer(0); + + /** + * String.fromCharCode reference for compile-time renaming. + * @type {function(...number):string} + * @inner + */ + var stringFromCharCode = String.fromCharCode; + + /** + * Creates a source function for a string. + * @param {string} s String to read from + * @returns {function():number|null} Source function returning the next char code respectively `null` if there are + * no more characters left. + * @throws {TypeError} If the argument is invalid + * @inner + */ + function stringSource(s) { + var i=0; return function() { + return i < s.length ? s.charCodeAt(i++) : null; + }; + } + + /** + * Creates a destination function for a string. + * @returns {function(number=):undefined|string} Destination function successively called with the next char code. + * Returns the final string when called without arguments. + * @inner + */ + function stringDestination() { + var cs = [], ps = []; return function() { + if (arguments.length === 0) + return ps.join('')+stringFromCharCode.apply(String, cs); + if (cs.length + arguments.length > 1024) + ps.push(stringFromCharCode.apply(String, cs)), + cs.length = 0; + Array.prototype.push.apply(cs, arguments); + }; + } + + /** + * Gets the accessor type. + * @returns {Function} `Buffer` under node.js, `Uint8Array` respectively `DataView` in the browser (classes) + * @expose + */ + ByteBuffer.accessor = function() { + return Uint8Array; + }; + /** + * Allocates a new ByteBuffer backed by a buffer of the specified capacity. + * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}. + * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to + * {@link ByteBuffer.DEFAULT_ENDIAN}. + * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to + * {@link ByteBuffer.DEFAULT_NOASSERT}. + * @returns {!ByteBuffer} + * @expose + */ + ByteBuffer.allocate = function(capacity, littleEndian, noAssert) { + return new ByteBuffer(capacity, littleEndian, noAssert); + }; + + /** + * Concatenates multiple ByteBuffers into one. + * @param {!Array.} buffers Buffers to concatenate + * @param {(string|boolean)=} encoding String encoding if `buffers` contains a string ("base64", "hex", "binary", + * defaults to "utf8") + * @param {boolean=} littleEndian Whether to use little or big endian byte order for the resulting ByteBuffer. Defaults + * to {@link ByteBuffer.DEFAULT_ENDIAN}. + * @param {boolean=} noAssert Whether to skip assertions of offsets and values for the resulting ByteBuffer. Defaults to + * {@link ByteBuffer.DEFAULT_NOASSERT}. + * @returns {!ByteBuffer} Concatenated ByteBuffer + * @expose + */ + ByteBuffer.concat = function(buffers, encoding, littleEndian, noAssert) { + if (typeof encoding === 'boolean' || typeof encoding !== 'string') { + noAssert = littleEndian; + littleEndian = encoding; + encoding = undefined; + } + var capacity = 0; + for (var i=0, k=buffers.length, length; i 0) capacity += length; + } + if (capacity === 0) + return new ByteBuffer(0, littleEndian, noAssert); + var bb = new ByteBuffer(capacity, littleEndian, noAssert), + bi; + i=0; while (i} buffer Anything that can be wrapped + * @param {(string|boolean)=} encoding String encoding if `buffer` is a string ("base64", "hex", "binary", defaults to + * "utf8") + * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to + * {@link ByteBuffer.DEFAULT_ENDIAN}. + * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to + * {@link ByteBuffer.DEFAULT_NOASSERT}. + * @returns {!ByteBuffer} A ByteBuffer wrapping `buffer` + * @expose + */ + ByteBuffer.wrap = function(buffer, encoding, littleEndian, noAssert) { + if (typeof encoding !== 'string') { + noAssert = littleEndian; + littleEndian = encoding; + encoding = undefined; + } + if (typeof buffer === 'string') { + if (typeof encoding === 'undefined') + encoding = "utf8"; + switch (encoding) { + case "base64": + return ByteBuffer.fromBase64(buffer, littleEndian); + case "hex": + return ByteBuffer.fromHex(buffer, littleEndian); + case "binary": + return ByteBuffer.fromBinary(buffer, littleEndian); + case "utf8": + return ByteBuffer.fromUTF8(buffer, littleEndian); + case "debug": + return ByteBuffer.fromDebug(buffer, littleEndian); + default: + throw Error("Unsupported encoding: "+encoding); + } + } + if (buffer === null || typeof buffer !== 'object') + throw TypeError("Illegal buffer"); + var bb; + if (ByteBuffer.isByteBuffer(buffer)) { + bb = ByteBufferPrototype.clone.call(buffer); + bb.markedOffset = -1; + return bb; + } + if (buffer instanceof Uint8Array) { // Extract ArrayBuffer from Uint8Array + bb = new ByteBuffer(0, littleEndian, noAssert); + if (buffer.length > 0) { // Avoid references to more than one EMPTY_BUFFER + bb.buffer = buffer.buffer; + bb.offset = buffer.byteOffset; + bb.limit = buffer.byteOffset + buffer.byteLength; + bb.view = new Uint8Array(buffer.buffer); + } + } else if (buffer instanceof ArrayBuffer) { // Reuse ArrayBuffer + bb = new ByteBuffer(0, littleEndian, noAssert); + if (buffer.byteLength > 0) { + bb.buffer = buffer; + bb.offset = 0; + bb.limit = buffer.byteLength; + bb.view = buffer.byteLength > 0 ? new Uint8Array(buffer) : null; + } + } else if (Object.prototype.toString.call(buffer) === "[object Array]") { // Create from octets + bb = new ByteBuffer(buffer.length, littleEndian, noAssert); + bb.limit = buffer.length; + for (var i=0; i} value Array of booleans to write + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted. + * @returns {!ByteBuffer} + * @expose + */ + ByteBufferPrototype.writeBitSet = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (!(value instanceof Array)) + throw TypeError("Illegal BitSet: Not an array"); + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + + var start = offset, + bits = value.length, + bytes = (bits >> 3), + bit = 0, + k; + + offset += this.writeVarint32(bits,offset); + + while(bytes--) { + k = (!!value[bit++] & 1) | + ((!!value[bit++] & 1) << 1) | + ((!!value[bit++] & 1) << 2) | + ((!!value[bit++] & 1) << 3) | + ((!!value[bit++] & 1) << 4) | + ((!!value[bit++] & 1) << 5) | + ((!!value[bit++] & 1) << 6) | + ((!!value[bit++] & 1) << 7); + this.writeByte(k,offset++); + } + + if(bit < bits) { + var m = 0; k = 0; + while(bit < bits) k = k | ((!!value[bit++] & 1) << (m++)); + this.writeByte(k,offset++); + } + + if (relative) { + this.offset = offset; + return this; + } + return offset - start; + } + + /** + * Reads a BitSet as an array of booleans. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted. + * @returns {Array + * @expose + */ + ByteBufferPrototype.readBitSet = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + + var ret = this.readVarint32(offset), + bits = ret.value, + bytes = (bits >> 3), + bit = 0, + value = [], + k; + + offset += ret.length; + + while(bytes--) { + k = this.readByte(offset++); + value[bit++] = !!(k & 0x01); + value[bit++] = !!(k & 0x02); + value[bit++] = !!(k & 0x04); + value[bit++] = !!(k & 0x08); + value[bit++] = !!(k & 0x10); + value[bit++] = !!(k & 0x20); + value[bit++] = !!(k & 0x40); + value[bit++] = !!(k & 0x80); + } + + if(bit < bits) { + var m = 0; + k = this.readByte(offset++); + while(bit < bits) value[bit++] = !!((k >> (m++)) & 1); + } + + if (relative) { + this.offset = offset; + } + return value; + } + /** + * Reads the specified number of bytes. + * @param {number} length Number of bytes to read + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted. + * @returns {!ByteBuffer} + * @expose + */ + ByteBufferPrototype.readBytes = function(length, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + length > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength); + } + var slice = this.slice(offset, offset + length); + if (relative) this.offset += length; + return slice; + }; + + /** + * Writes a payload of bytes. This is an alias of {@link ByteBuffer#append}. + * @function + * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to write. If `source` is a ByteBuffer, its offsets + * will be modified according to the performed read operation. + * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8") + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeBytes = ByteBufferPrototype.append; + + // types/ints/int8 + + /** + * Writes an 8bit signed integer. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeInt8 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value !== 'number' || value % 1 !== 0) + throw TypeError("Illegal value: "+value+" (not an integer)"); + value |= 0; + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + offset += 1; + var capacity0 = this.buffer.byteLength; + if (offset > capacity0) + this.resize((capacity0 *= 2) > offset ? capacity0 : offset); + offset -= 1; + this.view[offset] = value; + if (relative) this.offset += 1; + return this; + }; + + /** + * Writes an 8bit signed integer. This is an alias of {@link ByteBuffer#writeInt8}. + * @function + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeByte = ByteBufferPrototype.writeInt8; + + /** + * Reads an 8bit signed integer. + * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. + * @returns {number} Value read + * @expose + */ + ByteBufferPrototype.readInt8 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 1 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); + } + var value = this.view[offset]; + if ((value & 0x80) === 0x80) value = -(0xFF - value + 1); // Cast to signed + if (relative) this.offset += 1; + return value; + }; + + /** + * Reads an 8bit signed integer. This is an alias of {@link ByteBuffer#readInt8}. + * @function + * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. + * @returns {number} Value read + * @expose + */ + ByteBufferPrototype.readByte = ByteBufferPrototype.readInt8; + + /** + * Writes an 8bit unsigned integer. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeUint8 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value !== 'number' || value % 1 !== 0) + throw TypeError("Illegal value: "+value+" (not an integer)"); + value >>>= 0; + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + offset += 1; + var capacity1 = this.buffer.byteLength; + if (offset > capacity1) + this.resize((capacity1 *= 2) > offset ? capacity1 : offset); + offset -= 1; + this.view[offset] = value; + if (relative) this.offset += 1; + return this; + }; + + /** + * Writes an 8bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint8}. + * @function + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeUInt8 = ByteBufferPrototype.writeUint8; + + /** + * Reads an 8bit unsigned integer. + * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. + * @returns {number} Value read + * @expose + */ + ByteBufferPrototype.readUint8 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 1 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); + } + var value = this.view[offset]; + if (relative) this.offset += 1; + return value; + }; + + /** + * Reads an 8bit unsigned integer. This is an alias of {@link ByteBuffer#readUint8}. + * @function + * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted. + * @returns {number} Value read + * @expose + */ + ByteBufferPrototype.readUInt8 = ByteBufferPrototype.readUint8; + + // types/ints/int16 + + /** + * Writes a 16bit signed integer. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. + * @throws {TypeError} If `offset` or `value` is not a valid number + * @throws {RangeError} If `offset` is out of bounds + * @expose + */ + ByteBufferPrototype.writeInt16 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value !== 'number' || value % 1 !== 0) + throw TypeError("Illegal value: "+value+" (not an integer)"); + value |= 0; + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + offset += 2; + var capacity2 = this.buffer.byteLength; + if (offset > capacity2) + this.resize((capacity2 *= 2) > offset ? capacity2 : offset); + offset -= 2; + if (this.littleEndian) { + this.view[offset+1] = (value & 0xFF00) >>> 8; + this.view[offset ] = value & 0x00FF; + } else { + this.view[offset] = (value & 0xFF00) >>> 8; + this.view[offset+1] = value & 0x00FF; + } + if (relative) this.offset += 2; + return this; + }; + + /** + * Writes a 16bit signed integer. This is an alias of {@link ByteBuffer#writeInt16}. + * @function + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. + * @throws {TypeError} If `offset` or `value` is not a valid number + * @throws {RangeError} If `offset` is out of bounds + * @expose + */ + ByteBufferPrototype.writeShort = ByteBufferPrototype.writeInt16; + + /** + * Reads a 16bit signed integer. + * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. + * @returns {number} Value read + * @throws {TypeError} If `offset` is not a valid number + * @throws {RangeError} If `offset` is out of bounds + * @expose + */ + ByteBufferPrototype.readInt16 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 2 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength); + } + var value = 0; + if (this.littleEndian) { + value = this.view[offset ]; + value |= this.view[offset+1] << 8; + } else { + value = this.view[offset ] << 8; + value |= this.view[offset+1]; + } + if ((value & 0x8000) === 0x8000) value = -(0xFFFF - value + 1); // Cast to signed + if (relative) this.offset += 2; + return value; + }; + + /** + * Reads a 16bit signed integer. This is an alias of {@link ByteBuffer#readInt16}. + * @function + * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. + * @returns {number} Value read + * @throws {TypeError} If `offset` is not a valid number + * @throws {RangeError} If `offset` is out of bounds + * @expose + */ + ByteBufferPrototype.readShort = ByteBufferPrototype.readInt16; + + /** + * Writes a 16bit unsigned integer. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. + * @throws {TypeError} If `offset` or `value` is not a valid number + * @throws {RangeError} If `offset` is out of bounds + * @expose + */ + ByteBufferPrototype.writeUint16 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value !== 'number' || value % 1 !== 0) + throw TypeError("Illegal value: "+value+" (not an integer)"); + value >>>= 0; + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + offset += 2; + var capacity3 = this.buffer.byteLength; + if (offset > capacity3) + this.resize((capacity3 *= 2) > offset ? capacity3 : offset); + offset -= 2; + if (this.littleEndian) { + this.view[offset+1] = (value & 0xFF00) >>> 8; + this.view[offset ] = value & 0x00FF; + } else { + this.view[offset] = (value & 0xFF00) >>> 8; + this.view[offset+1] = value & 0x00FF; + } + if (relative) this.offset += 2; + return this; + }; + + /** + * Writes a 16bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint16}. + * @function + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. + * @throws {TypeError} If `offset` or `value` is not a valid number + * @throws {RangeError} If `offset` is out of bounds + * @expose + */ + ByteBufferPrototype.writeUInt16 = ByteBufferPrototype.writeUint16; + + /** + * Reads a 16bit unsigned integer. + * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. + * @returns {number} Value read + * @throws {TypeError} If `offset` is not a valid number + * @throws {RangeError} If `offset` is out of bounds + * @expose + */ + ByteBufferPrototype.readUint16 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 2 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength); + } + var value = 0; + if (this.littleEndian) { + value = this.view[offset ]; + value |= this.view[offset+1] << 8; + } else { + value = this.view[offset ] << 8; + value |= this.view[offset+1]; + } + if (relative) this.offset += 2; + return value; + }; + + /** + * Reads a 16bit unsigned integer. This is an alias of {@link ByteBuffer#readUint16}. + * @function + * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted. + * @returns {number} Value read + * @throws {TypeError} If `offset` is not a valid number + * @throws {RangeError} If `offset` is out of bounds + * @expose + */ + ByteBufferPrototype.readUInt16 = ByteBufferPrototype.readUint16; + + // types/ints/int32 + + /** + * Writes a 32bit signed integer. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @expose + */ + ByteBufferPrototype.writeInt32 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value !== 'number' || value % 1 !== 0) + throw TypeError("Illegal value: "+value+" (not an integer)"); + value |= 0; + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + offset += 4; + var capacity4 = this.buffer.byteLength; + if (offset > capacity4) + this.resize((capacity4 *= 2) > offset ? capacity4 : offset); + offset -= 4; + if (this.littleEndian) { + this.view[offset+3] = (value >>> 24) & 0xFF; + this.view[offset+2] = (value >>> 16) & 0xFF; + this.view[offset+1] = (value >>> 8) & 0xFF; + this.view[offset ] = value & 0xFF; + } else { + this.view[offset ] = (value >>> 24) & 0xFF; + this.view[offset+1] = (value >>> 16) & 0xFF; + this.view[offset+2] = (value >>> 8) & 0xFF; + this.view[offset+3] = value & 0xFF; + } + if (relative) this.offset += 4; + return this; + }; + + /** + * Writes a 32bit signed integer. This is an alias of {@link ByteBuffer#writeInt32}. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @expose + */ + ByteBufferPrototype.writeInt = ByteBufferPrototype.writeInt32; + + /** + * Reads a 32bit signed integer. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @returns {number} Value read + * @expose + */ + ByteBufferPrototype.readInt32 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 4 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength); + } + var value = 0; + if (this.littleEndian) { + value = this.view[offset+2] << 16; + value |= this.view[offset+1] << 8; + value |= this.view[offset ]; + value += this.view[offset+3] << 24 >>> 0; + } else { + value = this.view[offset+1] << 16; + value |= this.view[offset+2] << 8; + value |= this.view[offset+3]; + value += this.view[offset ] << 24 >>> 0; + } + value |= 0; // Cast to signed + if (relative) this.offset += 4; + return value; + }; + + /** + * Reads a 32bit signed integer. This is an alias of {@link ByteBuffer#readInt32}. + * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `4` if omitted. + * @returns {number} Value read + * @expose + */ + ByteBufferPrototype.readInt = ByteBufferPrototype.readInt32; + + /** + * Writes a 32bit unsigned integer. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @expose + */ + ByteBufferPrototype.writeUint32 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value !== 'number' || value % 1 !== 0) + throw TypeError("Illegal value: "+value+" (not an integer)"); + value >>>= 0; + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + offset += 4; + var capacity5 = this.buffer.byteLength; + if (offset > capacity5) + this.resize((capacity5 *= 2) > offset ? capacity5 : offset); + offset -= 4; + if (this.littleEndian) { + this.view[offset+3] = (value >>> 24) & 0xFF; + this.view[offset+2] = (value >>> 16) & 0xFF; + this.view[offset+1] = (value >>> 8) & 0xFF; + this.view[offset ] = value & 0xFF; + } else { + this.view[offset ] = (value >>> 24) & 0xFF; + this.view[offset+1] = (value >>> 16) & 0xFF; + this.view[offset+2] = (value >>> 8) & 0xFF; + this.view[offset+3] = value & 0xFF; + } + if (relative) this.offset += 4; + return this; + }; + + /** + * Writes a 32bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint32}. + * @function + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @expose + */ + ByteBufferPrototype.writeUInt32 = ByteBufferPrototype.writeUint32; + + /** + * Reads a 32bit unsigned integer. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @returns {number} Value read + * @expose + */ + ByteBufferPrototype.readUint32 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 4 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength); + } + var value = 0; + if (this.littleEndian) { + value = this.view[offset+2] << 16; + value |= this.view[offset+1] << 8; + value |= this.view[offset ]; + value += this.view[offset+3] << 24 >>> 0; + } else { + value = this.view[offset+1] << 16; + value |= this.view[offset+2] << 8; + value |= this.view[offset+3]; + value += this.view[offset ] << 24 >>> 0; + } + if (relative) this.offset += 4; + return value; + }; + + /** + * Reads a 32bit unsigned integer. This is an alias of {@link ByteBuffer#readUint32}. + * @function + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @returns {number} Value read + * @expose + */ + ByteBufferPrototype.readUInt32 = ByteBufferPrototype.readUint32; + + // types/ints/int64 + + if (Long) { + + /** + * Writes a 64bit signed integer. + * @param {number|!Long} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeInt64 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value === 'number') + value = Long.fromNumber(value); + else if (typeof value === 'string') + value = Long.fromString(value); + else if (!(value && value instanceof Long)) + throw TypeError("Illegal value: "+value+" (not an integer or Long)"); + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + if (typeof value === 'number') + value = Long.fromNumber(value); + else if (typeof value === 'string') + value = Long.fromString(value); + offset += 8; + var capacity6 = this.buffer.byteLength; + if (offset > capacity6) + this.resize((capacity6 *= 2) > offset ? capacity6 : offset); + offset -= 8; + var lo = value.low, + hi = value.high; + if (this.littleEndian) { + this.view[offset+3] = (lo >>> 24) & 0xFF; + this.view[offset+2] = (lo >>> 16) & 0xFF; + this.view[offset+1] = (lo >>> 8) & 0xFF; + this.view[offset ] = lo & 0xFF; + offset += 4; + this.view[offset+3] = (hi >>> 24) & 0xFF; + this.view[offset+2] = (hi >>> 16) & 0xFF; + this.view[offset+1] = (hi >>> 8) & 0xFF; + this.view[offset ] = hi & 0xFF; + } else { + this.view[offset ] = (hi >>> 24) & 0xFF; + this.view[offset+1] = (hi >>> 16) & 0xFF; + this.view[offset+2] = (hi >>> 8) & 0xFF; + this.view[offset+3] = hi & 0xFF; + offset += 4; + this.view[offset ] = (lo >>> 24) & 0xFF; + this.view[offset+1] = (lo >>> 16) & 0xFF; + this.view[offset+2] = (lo >>> 8) & 0xFF; + this.view[offset+3] = lo & 0xFF; + } + if (relative) this.offset += 8; + return this; + }; + + /** + * Writes a 64bit signed integer. This is an alias of {@link ByteBuffer#writeInt64}. + * @param {number|!Long} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeLong = ByteBufferPrototype.writeInt64; + + /** + * Reads a 64bit signed integer. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!Long} + * @expose + */ + ByteBufferPrototype.readInt64 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 8 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength); + } + var lo = 0, + hi = 0; + if (this.littleEndian) { + lo = this.view[offset+2] << 16; + lo |= this.view[offset+1] << 8; + lo |= this.view[offset ]; + lo += this.view[offset+3] << 24 >>> 0; + offset += 4; + hi = this.view[offset+2] << 16; + hi |= this.view[offset+1] << 8; + hi |= this.view[offset ]; + hi += this.view[offset+3] << 24 >>> 0; + } else { + hi = this.view[offset+1] << 16; + hi |= this.view[offset+2] << 8; + hi |= this.view[offset+3]; + hi += this.view[offset ] << 24 >>> 0; + offset += 4; + lo = this.view[offset+1] << 16; + lo |= this.view[offset+2] << 8; + lo |= this.view[offset+3]; + lo += this.view[offset ] << 24 >>> 0; + } + var value = new Long(lo, hi, false); + if (relative) this.offset += 8; + return value; + }; + + /** + * Reads a 64bit signed integer. This is an alias of {@link ByteBuffer#readInt64}. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!Long} + * @expose + */ + ByteBufferPrototype.readLong = ByteBufferPrototype.readInt64; + + /** + * Writes a 64bit unsigned integer. + * @param {number|!Long} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeUint64 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value === 'number') + value = Long.fromNumber(value); + else if (typeof value === 'string') + value = Long.fromString(value); + else if (!(value && value instanceof Long)) + throw TypeError("Illegal value: "+value+" (not an integer or Long)"); + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + if (typeof value === 'number') + value = Long.fromNumber(value); + else if (typeof value === 'string') + value = Long.fromString(value); + offset += 8; + var capacity7 = this.buffer.byteLength; + if (offset > capacity7) + this.resize((capacity7 *= 2) > offset ? capacity7 : offset); + offset -= 8; + var lo = value.low, + hi = value.high; + if (this.littleEndian) { + this.view[offset+3] = (lo >>> 24) & 0xFF; + this.view[offset+2] = (lo >>> 16) & 0xFF; + this.view[offset+1] = (lo >>> 8) & 0xFF; + this.view[offset ] = lo & 0xFF; + offset += 4; + this.view[offset+3] = (hi >>> 24) & 0xFF; + this.view[offset+2] = (hi >>> 16) & 0xFF; + this.view[offset+1] = (hi >>> 8) & 0xFF; + this.view[offset ] = hi & 0xFF; + } else { + this.view[offset ] = (hi >>> 24) & 0xFF; + this.view[offset+1] = (hi >>> 16) & 0xFF; + this.view[offset+2] = (hi >>> 8) & 0xFF; + this.view[offset+3] = hi & 0xFF; + offset += 4; + this.view[offset ] = (lo >>> 24) & 0xFF; + this.view[offset+1] = (lo >>> 16) & 0xFF; + this.view[offset+2] = (lo >>> 8) & 0xFF; + this.view[offset+3] = lo & 0xFF; + } + if (relative) this.offset += 8; + return this; + }; + + /** + * Writes a 64bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint64}. + * @function + * @param {number|!Long} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeUInt64 = ByteBufferPrototype.writeUint64; + + /** + * Reads a 64bit unsigned integer. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!Long} + * @expose + */ + ByteBufferPrototype.readUint64 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 8 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength); + } + var lo = 0, + hi = 0; + if (this.littleEndian) { + lo = this.view[offset+2] << 16; + lo |= this.view[offset+1] << 8; + lo |= this.view[offset ]; + lo += this.view[offset+3] << 24 >>> 0; + offset += 4; + hi = this.view[offset+2] << 16; + hi |= this.view[offset+1] << 8; + hi |= this.view[offset ]; + hi += this.view[offset+3] << 24 >>> 0; + } else { + hi = this.view[offset+1] << 16; + hi |= this.view[offset+2] << 8; + hi |= this.view[offset+3]; + hi += this.view[offset ] << 24 >>> 0; + offset += 4; + lo = this.view[offset+1] << 16; + lo |= this.view[offset+2] << 8; + lo |= this.view[offset+3]; + lo += this.view[offset ] << 24 >>> 0; + } + var value = new Long(lo, hi, true); + if (relative) this.offset += 8; + return value; + }; + + /** + * Reads a 64bit unsigned integer. This is an alias of {@link ByteBuffer#readUint64}. + * @function + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!Long} + * @expose + */ + ByteBufferPrototype.readUInt64 = ByteBufferPrototype.readUint64; + + } // Long + + + // types/floats/float32 + + /* + ieee754 - https://github.com/feross/ieee754 + + The MIT License (MIT) + + Copyright (c) Feross Aboukhadijeh + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + */ + + /** + * Reads an IEEE754 float from a byte array. + * @param {!Array} buffer + * @param {number} offset + * @param {boolean} isLE + * @param {number} mLen + * @param {number} nBytes + * @returns {number} + * @inner + */ + function ieee754_read(buffer, offset, isLE, mLen, nBytes) { + var e, m, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + nBits = -7, + i = isLE ? (nBytes - 1) : 0, + d = isLE ? -1 : 1, + s = buffer[offset + i]; + + i += d; + + e = s & ((1 << (-nBits)) - 1); + s >>= (-nBits); + nBits += eLen; + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1); + e >>= (-nBits); + nBits += mLen; + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity); + } else { + m = m + Math.pow(2, mLen); + e = e - eBias; + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen); + } + + /** + * Writes an IEEE754 float to a byte array. + * @param {!Array} buffer + * @param {number} value + * @param {number} offset + * @param {boolean} isLE + * @param {number} mLen + * @param {number} nBytes + * @inner + */ + function ieee754_write(buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), + i = isLE ? 0 : (nBytes - 1), + d = isLE ? 1 : -1, + s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; + + value = Math.abs(value); + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0; + e = eMax; + } else { + e = Math.floor(Math.log(value) / Math.LN2); + if (value * (c = Math.pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e + eBias >= 1) { + value += rt / c; + } else { + value += rt * Math.pow(2, 1 - eBias); + } + if (value * c >= 2) { + e++; + c /= 2; + } + + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen); + e = e + eBias; + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); + e = 0; + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + + e = (e << mLen) | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + + buffer[offset + i - d] |= s * 128; + } + + /** + * Writes a 32bit float. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeFloat32 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value !== 'number') + throw TypeError("Illegal value: "+value+" (not a number)"); + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + offset += 4; + var capacity8 = this.buffer.byteLength; + if (offset > capacity8) + this.resize((capacity8 *= 2) > offset ? capacity8 : offset); + offset -= 4; + ieee754_write(this.view, value, offset, this.littleEndian, 23, 4); + if (relative) this.offset += 4; + return this; + }; + + /** + * Writes a 32bit float. This is an alias of {@link ByteBuffer#writeFloat32}. + * @function + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeFloat = ByteBufferPrototype.writeFloat32; + + /** + * Reads a 32bit float. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @returns {number} + * @expose + */ + ByteBufferPrototype.readFloat32 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 4 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength); + } + var value = ieee754_read(this.view, offset, this.littleEndian, 23, 4); + if (relative) this.offset += 4; + return value; + }; + + /** + * Reads a 32bit float. This is an alias of {@link ByteBuffer#readFloat32}. + * @function + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted. + * @returns {number} + * @expose + */ + ByteBufferPrototype.readFloat = ByteBufferPrototype.readFloat32; + + // types/floats/float64 + + /** + * Writes a 64bit float. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeFloat64 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value !== 'number') + throw TypeError("Illegal value: "+value+" (not a number)"); + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + offset += 8; + var capacity9 = this.buffer.byteLength; + if (offset > capacity9) + this.resize((capacity9 *= 2) > offset ? capacity9 : offset); + offset -= 8; + ieee754_write(this.view, value, offset, this.littleEndian, 52, 8); + if (relative) this.offset += 8; + return this; + }; + + /** + * Writes a 64bit float. This is an alias of {@link ByteBuffer#writeFloat64}. + * @function + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.writeDouble = ByteBufferPrototype.writeFloat64; + + /** + * Reads a 64bit float. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {number} + * @expose + */ + ByteBufferPrototype.readFloat64 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 8 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength); + } + var value = ieee754_read(this.view, offset, this.littleEndian, 52, 8); + if (relative) this.offset += 8; + return value; + }; + + /** + * Reads a 64bit float. This is an alias of {@link ByteBuffer#readFloat64}. + * @function + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted. + * @returns {number} + * @expose + */ + ByteBufferPrototype.readDouble = ByteBufferPrototype.readFloat64; + + + // types/varints/varint32 + + /** + * Maximum number of bytes required to store a 32bit base 128 variable-length integer. + * @type {number} + * @const + * @expose + */ + ByteBuffer.MAX_VARINT32_BYTES = 5; + + /** + * Calculates the actual number of bytes required to store a 32bit base 128 variable-length integer. + * @param {number} value Value to encode + * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT32_BYTES} + * @expose + */ + ByteBuffer.calculateVarint32 = function(value) { + // ref: src/google/protobuf/io/coded_stream.cc + value = value >>> 0; + if (value < 1 << 7 ) return 1; + else if (value < 1 << 14) return 2; + else if (value < 1 << 21) return 3; + else if (value < 1 << 28) return 4; + else return 5; + }; + + /** + * Zigzag encodes a signed 32bit integer so that it can be effectively used with varint encoding. + * @param {number} n Signed 32bit integer + * @returns {number} Unsigned zigzag encoded 32bit integer + * @expose + */ + ByteBuffer.zigZagEncode32 = function(n) { + return (((n |= 0) << 1) ^ (n >> 31)) >>> 0; // ref: src/google/protobuf/wire_format_lite.h + }; + + /** + * Decodes a zigzag encoded signed 32bit integer. + * @param {number} n Unsigned zigzag encoded 32bit integer + * @returns {number} Signed 32bit integer + * @expose + */ + ByteBuffer.zigZagDecode32 = function(n) { + return ((n >>> 1) ^ -(n & 1)) | 0; // // ref: src/google/protobuf/wire_format_lite.h + }; + + /** + * Writes a 32bit base 128 variable-length integer. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written + * @expose + */ + ByteBufferPrototype.writeVarint32 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value !== 'number' || value % 1 !== 0) + throw TypeError("Illegal value: "+value+" (not an integer)"); + value |= 0; + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + var size = ByteBuffer.calculateVarint32(value), + b; + offset += size; + var capacity10 = this.buffer.byteLength; + if (offset > capacity10) + this.resize((capacity10 *= 2) > offset ? capacity10 : offset); + offset -= size; + value >>>= 0; + while (value >= 0x80) { + b = (value & 0x7f) | 0x80; + this.view[offset++] = b; + value >>>= 7; + } + this.view[offset++] = value; + if (relative) { + this.offset = offset; + return this; + } + return size; + }; + + /** + * Writes a zig-zag encoded (signed) 32bit base 128 variable-length integer. + * @param {number} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written + * @expose + */ + ByteBufferPrototype.writeVarint32ZigZag = function(value, offset) { + return this.writeVarint32(ByteBuffer.zigZagEncode32(value), offset); + }; + + /** + * Reads a 32bit base 128 variable-length integer. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read + * and the actual number of bytes read. + * @throws {Error} If it's not a valid varint. Has a property `truncated = true` if there is not enough data available + * to fully decode the varint. + * @expose + */ + ByteBufferPrototype.readVarint32 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 1 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); + } + var c = 0, + value = 0 >>> 0, + b; + do { + if (!this.noAssert && offset > this.limit) { + var err = Error("Truncated"); + err['truncated'] = true; + throw err; + } + b = this.view[offset++]; + if (c < 5) + value |= (b & 0x7f) << (7*c); + ++c; + } while ((b & 0x80) !== 0); + value |= 0; + if (relative) { + this.offset = offset; + return value; + } + return { + "value": value, + "length": c + }; + }; + + /** + * Reads a zig-zag encoded (signed) 32bit base 128 variable-length integer. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read + * and the actual number of bytes read. + * @throws {Error} If it's not a valid varint + * @expose + */ + ByteBufferPrototype.readVarint32ZigZag = function(offset) { + var val = this.readVarint32(offset); + if (typeof val === 'object') + val["value"] = ByteBuffer.zigZagDecode32(val["value"]); + else + val = ByteBuffer.zigZagDecode32(val); + return val; + }; + + // types/varints/varint64 + + if (Long) { + + /** + * Maximum number of bytes required to store a 64bit base 128 variable-length integer. + * @type {number} + * @const + * @expose + */ + ByteBuffer.MAX_VARINT64_BYTES = 10; + + /** + * Calculates the actual number of bytes required to store a 64bit base 128 variable-length integer. + * @param {number|!Long} value Value to encode + * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT64_BYTES} + * @expose + */ + ByteBuffer.calculateVarint64 = function(value) { + if (typeof value === 'number') + value = Long.fromNumber(value); + else if (typeof value === 'string') + value = Long.fromString(value); + // ref: src/google/protobuf/io/coded_stream.cc + var part0 = value.toInt() >>> 0, + part1 = value.shiftRightUnsigned(28).toInt() >>> 0, + part2 = value.shiftRightUnsigned(56).toInt() >>> 0; + if (part2 == 0) { + if (part1 == 0) { + if (part0 < 1 << 14) + return part0 < 1 << 7 ? 1 : 2; + else + return part0 < 1 << 21 ? 3 : 4; + } else { + if (part1 < 1 << 14) + return part1 < 1 << 7 ? 5 : 6; + else + return part1 < 1 << 21 ? 7 : 8; + } + } else + return part2 < 1 << 7 ? 9 : 10; + }; + + /** + * Zigzag encodes a signed 64bit integer so that it can be effectively used with varint encoding. + * @param {number|!Long} value Signed long + * @returns {!Long} Unsigned zigzag encoded long + * @expose + */ + ByteBuffer.zigZagEncode64 = function(value) { + if (typeof value === 'number') + value = Long.fromNumber(value, false); + else if (typeof value === 'string') + value = Long.fromString(value, false); + else if (value.unsigned !== false) value = value.toSigned(); + // ref: src/google/protobuf/wire_format_lite.h + return value.shiftLeft(1).xor(value.shiftRight(63)).toUnsigned(); + }; + + /** + * Decodes a zigzag encoded signed 64bit integer. + * @param {!Long|number} value Unsigned zigzag encoded long or JavaScript number + * @returns {!Long} Signed long + * @expose + */ + ByteBuffer.zigZagDecode64 = function(value) { + if (typeof value === 'number') + value = Long.fromNumber(value, false); + else if (typeof value === 'string') + value = Long.fromString(value, false); + else if (value.unsigned !== false) value = value.toSigned(); + // ref: src/google/protobuf/wire_format_lite.h + return value.shiftRightUnsigned(1).xor(value.and(Long.ONE).toSigned().negate()).toSigned(); + }; + + /** + * Writes a 64bit base 128 variable-length integer. + * @param {number|Long} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written. + * @expose + */ + ByteBufferPrototype.writeVarint64 = function(value, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof value === 'number') + value = Long.fromNumber(value); + else if (typeof value === 'string') + value = Long.fromString(value); + else if (!(value && value instanceof Long)) + throw TypeError("Illegal value: "+value+" (not an integer or Long)"); + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + if (typeof value === 'number') + value = Long.fromNumber(value, false); + else if (typeof value === 'string') + value = Long.fromString(value, false); + else if (value.unsigned !== false) value = value.toSigned(); + var size = ByteBuffer.calculateVarint64(value), + part0 = value.toInt() >>> 0, + part1 = value.shiftRightUnsigned(28).toInt() >>> 0, + part2 = value.shiftRightUnsigned(56).toInt() >>> 0; + offset += size; + var capacity11 = this.buffer.byteLength; + if (offset > capacity11) + this.resize((capacity11 *= 2) > offset ? capacity11 : offset); + offset -= size; + switch (size) { + case 10: this.view[offset+9] = (part2 >>> 7) & 0x01; + case 9 : this.view[offset+8] = size !== 9 ? (part2 ) | 0x80 : (part2 ) & 0x7F; + case 8 : this.view[offset+7] = size !== 8 ? (part1 >>> 21) | 0x80 : (part1 >>> 21) & 0x7F; + case 7 : this.view[offset+6] = size !== 7 ? (part1 >>> 14) | 0x80 : (part1 >>> 14) & 0x7F; + case 6 : this.view[offset+5] = size !== 6 ? (part1 >>> 7) | 0x80 : (part1 >>> 7) & 0x7F; + case 5 : this.view[offset+4] = size !== 5 ? (part1 ) | 0x80 : (part1 ) & 0x7F; + case 4 : this.view[offset+3] = size !== 4 ? (part0 >>> 21) | 0x80 : (part0 >>> 21) & 0x7F; + case 3 : this.view[offset+2] = size !== 3 ? (part0 >>> 14) | 0x80 : (part0 >>> 14) & 0x7F; + case 2 : this.view[offset+1] = size !== 2 ? (part0 >>> 7) | 0x80 : (part0 >>> 7) & 0x7F; + case 1 : this.view[offset ] = size !== 1 ? (part0 ) | 0x80 : (part0 ) & 0x7F; + } + if (relative) { + this.offset += size; + return this; + } else { + return size; + } + }; + + /** + * Writes a zig-zag encoded 64bit base 128 variable-length integer. + * @param {number|Long} value Value to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written. + * @expose + */ + ByteBufferPrototype.writeVarint64ZigZag = function(value, offset) { + return this.writeVarint64(ByteBuffer.zigZagEncode64(value), offset); + }; + + /** + * Reads a 64bit base 128 variable-length integer. Requires Long.js. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * read if omitted. + * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and + * the actual number of bytes read. + * @throws {Error} If it's not a valid varint + * @expose + */ + ByteBufferPrototype.readVarint64 = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 1 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); + } + // ref: src/google/protobuf/io/coded_stream.cc + var start = offset, + part0 = 0, + part1 = 0, + part2 = 0, + b = 0; + b = this.view[offset++]; part0 = (b & 0x7F) ; if ( b & 0x80 ) { + b = this.view[offset++]; part0 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { + b = this.view[offset++]; part0 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { + b = this.view[offset++]; part0 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { + b = this.view[offset++]; part1 = (b & 0x7F) ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { + b = this.view[offset++]; part1 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { + b = this.view[offset++]; part1 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { + b = this.view[offset++]; part1 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { + b = this.view[offset++]; part2 = (b & 0x7F) ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { + b = this.view[offset++]; part2 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) { + throw Error("Buffer overrun"); }}}}}}}}}} + var value = Long.fromBits(part0 | (part1 << 28), (part1 >>> 4) | (part2) << 24, false); + if (relative) { + this.offset = offset; + return value; + } else { + return { + 'value': value, + 'length': offset-start + }; + } + }; + + /** + * Reads a zig-zag encoded 64bit base 128 variable-length integer. Requires Long.js. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * read if omitted. + * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and + * the actual number of bytes read. + * @throws {Error} If it's not a valid varint + * @expose + */ + ByteBufferPrototype.readVarint64ZigZag = function(offset) { + var val = this.readVarint64(offset); + if (val && val['value'] instanceof Long) + val["value"] = ByteBuffer.zigZagDecode64(val["value"]); + else + val = ByteBuffer.zigZagDecode64(val); + return val; + }; + + } // Long + + + // types/strings/cstring + + /** + * Writes a NULL-terminated UTF8 encoded string. For this to work the specified string must not contain any NULL + * characters itself. + * @param {string} str String to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * contained in `str` + 1 if omitted. + * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written + * @expose + */ + ByteBufferPrototype.writeCString = function(str, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + var i, + k = str.length; + if (!this.noAssert) { + if (typeof str !== 'string') + throw TypeError("Illegal str: Not a string"); + for (i=0; i>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + // UTF8 strings do not contain zero bytes in between except for the zero character, so: + k = utfx.calculateUTF16asUTF8(stringSource(str))[1]; + offset += k+1; + var capacity12 = this.buffer.byteLength; + if (offset > capacity12) + this.resize((capacity12 *= 2) > offset ? capacity12 : offset); + offset -= k+1; + utfx.encodeUTF16toUTF8(stringSource(str), function(b) { + this.view[offset++] = b; + }.bind(this)); + this.view[offset++] = 0; + if (relative) { + this.offset = offset; + return this; + } + return k; + }; + + /** + * Reads a NULL-terminated UTF8 encoded string. For this to work the string read must not contain any NULL characters + * itself. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * read if omitted. + * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string + * read and the actual number of bytes read. + * @expose + */ + ByteBufferPrototype.readCString = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 1 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); + } + var start = offset, + temp; + // UTF8 strings do not contain zero bytes in between except for the zero character itself, so: + var sd, b = -1; + utfx.decodeUTF8toUTF16(function() { + if (b === 0) return null; + if (offset >= this.limit) + throw RangeError("Illegal range: Truncated data, "+offset+" < "+this.limit); + b = this.view[offset++]; + return b === 0 ? null : b; + }.bind(this), sd = stringDestination(), true); + if (relative) { + this.offset = offset; + return sd(); + } else { + return { + "string": sd(), + "length": offset - start + }; + } + }; + + // types/strings/istring + + /** + * Writes a length as uint32 prefixed UTF8 encoded string. + * @param {string} str String to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written + * @expose + * @see ByteBuffer#writeVarint32 + */ + ByteBufferPrototype.writeIString = function(str, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof str !== 'string') + throw TypeError("Illegal str: Not a string"); + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + var start = offset, + k; + k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1]; + offset += 4+k; + var capacity13 = this.buffer.byteLength; + if (offset > capacity13) + this.resize((capacity13 *= 2) > offset ? capacity13 : offset); + offset -= 4+k; + if (this.littleEndian) { + this.view[offset+3] = (k >>> 24) & 0xFF; + this.view[offset+2] = (k >>> 16) & 0xFF; + this.view[offset+1] = (k >>> 8) & 0xFF; + this.view[offset ] = k & 0xFF; + } else { + this.view[offset ] = (k >>> 24) & 0xFF; + this.view[offset+1] = (k >>> 16) & 0xFF; + this.view[offset+2] = (k >>> 8) & 0xFF; + this.view[offset+3] = k & 0xFF; + } + offset += 4; + utfx.encodeUTF16toUTF8(stringSource(str), function(b) { + this.view[offset++] = b; + }.bind(this)); + if (offset !== start + 4 + k) + throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+4+k)); + if (relative) { + this.offset = offset; + return this; + } + return offset - start; + }; + + /** + * Reads a length as uint32 prefixed UTF8 encoded string. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * read if omitted. + * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string + * read and the actual number of bytes read. + * @expose + * @see ByteBuffer#readVarint32 + */ + ByteBufferPrototype.readIString = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 4 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength); + } + var start = offset; + var len = this.readUint32(offset); + var str = this.readUTF8String(len, ByteBuffer.METRICS_BYTES, offset += 4); + offset += str['length']; + if (relative) { + this.offset = offset; + return str['string']; + } else { + return { + 'string': str['string'], + 'length': offset - start + }; + } + }; + + // types/strings/utf8string + + /** + * Metrics representing number of UTF8 characters. Evaluates to `c`. + * @type {string} + * @const + * @expose + */ + ByteBuffer.METRICS_CHARS = 'c'; + + /** + * Metrics representing number of bytes. Evaluates to `b`. + * @type {string} + * @const + * @expose + */ + ByteBuffer.METRICS_BYTES = 'b'; + + /** + * Writes an UTF8 encoded string. + * @param {string} str String to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted. + * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written. + * @expose + */ + ByteBufferPrototype.writeUTF8String = function(str, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + var k; + var start = offset; + k = utfx.calculateUTF16asUTF8(stringSource(str))[1]; + offset += k; + var capacity14 = this.buffer.byteLength; + if (offset > capacity14) + this.resize((capacity14 *= 2) > offset ? capacity14 : offset); + offset -= k; + utfx.encodeUTF16toUTF8(stringSource(str), function(b) { + this.view[offset++] = b; + }.bind(this)); + if (relative) { + this.offset = offset; + return this; + } + return offset - start; + }; + + /** + * Writes an UTF8 encoded string. This is an alias of {@link ByteBuffer#writeUTF8String}. + * @function + * @param {string} str String to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted. + * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written. + * @expose + */ + ByteBufferPrototype.writeString = ByteBufferPrototype.writeUTF8String; + + /** + * Calculates the number of UTF8 characters of a string. JavaScript itself uses UTF-16, so that a string's + * `length` property does not reflect its actual UTF8 size if it contains code points larger than 0xFFFF. + * @param {string} str String to calculate + * @returns {number} Number of UTF8 characters + * @expose + */ + ByteBuffer.calculateUTF8Chars = function(str) { + return utfx.calculateUTF16asUTF8(stringSource(str))[0]; + }; + + /** + * Calculates the number of UTF8 bytes of a string. + * @param {string} str String to calculate + * @returns {number} Number of UTF8 bytes + * @expose + */ + ByteBuffer.calculateUTF8Bytes = function(str) { + return utfx.calculateUTF16asUTF8(stringSource(str))[1]; + }; + + /** + * Calculates the number of UTF8 bytes of a string. This is an alias of {@link ByteBuffer.calculateUTF8Bytes}. + * @function + * @param {string} str String to calculate + * @returns {number} Number of UTF8 bytes + * @expose + */ + ByteBuffer.calculateString = ByteBuffer.calculateUTF8Bytes; + + /** + * Reads an UTF8 encoded string. + * @param {number} length Number of characters or bytes to read. + * @param {string=} metrics Metrics specifying what `length` is meant to count. Defaults to + * {@link ByteBuffer.METRICS_CHARS}. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * read if omitted. + * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string + * read and the actual number of bytes read. + * @expose + */ + ByteBufferPrototype.readUTF8String = function(length, metrics, offset) { + if (typeof metrics === 'number') { + offset = metrics; + metrics = undefined; + } + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (typeof metrics === 'undefined') metrics = ByteBuffer.METRICS_CHARS; + if (!this.noAssert) { + if (typeof length !== 'number' || length % 1 !== 0) + throw TypeError("Illegal length: "+length+" (not an integer)"); + length |= 0; + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + var i = 0, + start = offset, + sd; + if (metrics === ByteBuffer.METRICS_CHARS) { // The same for node and the browser + sd = stringDestination(); + utfx.decodeUTF8(function() { + return i < length && offset < this.limit ? this.view[offset++] : null; + }.bind(this), function(cp) { + ++i; utfx.UTF8toUTF16(cp, sd); + }); + if (i !== length) + throw RangeError("Illegal range: Truncated data, "+i+" == "+length); + if (relative) { + this.offset = offset; + return sd(); + } else { + return { + "string": sd(), + "length": offset - start + }; + } + } else if (metrics === ByteBuffer.METRICS_BYTES) { + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + length > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength); + } + var k = offset + length; + utfx.decodeUTF8toUTF16(function() { + return offset < k ? this.view[offset++] : null; + }.bind(this), sd = stringDestination(), this.noAssert); + if (offset !== k) + throw RangeError("Illegal range: Truncated data, "+offset+" == "+k); + if (relative) { + this.offset = offset; + return sd(); + } else { + return { + 'string': sd(), + 'length': offset - start + }; + } + } else + throw TypeError("Unsupported metrics: "+metrics); + }; + + /** + * Reads an UTF8 encoded string. This is an alias of {@link ByteBuffer#readUTF8String}. + * @function + * @param {number} length Number of characters or bytes to read + * @param {number=} metrics Metrics specifying what `n` is meant to count. Defaults to + * {@link ByteBuffer.METRICS_CHARS}. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * read if omitted. + * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string + * read and the actual number of bytes read. + * @expose + */ + ByteBufferPrototype.readString = ByteBufferPrototype.readUTF8String; + + // types/strings/vstring + + /** + * Writes a length as varint32 prefixed UTF8 encoded string. + * @param {string} str String to write + * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written + * @expose + * @see ByteBuffer#writeVarint32 + */ + ByteBufferPrototype.writeVString = function(str, offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof str !== 'string') + throw TypeError("Illegal str: Not a string"); + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + var start = offset, + k, l; + k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1]; + l = ByteBuffer.calculateVarint32(k); + offset += l+k; + var capacity15 = this.buffer.byteLength; + if (offset > capacity15) + this.resize((capacity15 *= 2) > offset ? capacity15 : offset); + offset -= l+k; + offset += this.writeVarint32(k, offset); + utfx.encodeUTF16toUTF8(stringSource(str), function(b) { + this.view[offset++] = b; + }.bind(this)); + if (offset !== start+k+l) + throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+k+l)); + if (relative) { + this.offset = offset; + return this; + } + return offset - start; + }; + + /** + * Reads a length as varint32 prefixed UTF8 encoded string. + * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * read if omitted. + * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string + * read and the actual number of bytes read. + * @expose + * @see ByteBuffer#readVarint32 + */ + ByteBufferPrototype.readVString = function(offset) { + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 1 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength); + } + var start = offset; + var len = this.readVarint32(offset); + var str = this.readUTF8String(len['value'], ByteBuffer.METRICS_BYTES, offset += len['length']); + offset += str['length']; + if (relative) { + this.offset = offset; + return str['string']; + } else { + return { + 'string': str['string'], + 'length': offset - start + }; + } + }; + + + /** + * Appends some data to this ByteBuffer. This will overwrite any contents behind the specified offset up to the appended + * data's length. + * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to append. If `source` is a ByteBuffer, its offsets + * will be modified according to the performed read operation. + * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8") + * @param {number=} offset Offset to append at. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. + * @returns {!ByteBuffer} this + * @expose + * @example A relative `<01 02>03.append(<04 05>)` will result in `<01 02 04 05>, 04 05|` + * @example An absolute `<01 02>03.append(04 05>, 1)` will result in `<01 04>05, 04 05|` + */ + ByteBufferPrototype.append = function(source, encoding, offset) { + if (typeof encoding === 'number' || typeof encoding !== 'string') { + offset = encoding; + encoding = undefined; + } + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + if (!(source instanceof ByteBuffer)) + source = ByteBuffer.wrap(source, encoding); + var length = source.limit - source.offset; + if (length <= 0) return this; // Nothing to append + offset += length; + var capacity16 = this.buffer.byteLength; + if (offset > capacity16) + this.resize((capacity16 *= 2) > offset ? capacity16 : offset); + offset -= length; + this.view.set(source.view.subarray(source.offset, source.limit), offset); + source.offset += length; + if (relative) this.offset += length; + return this; + }; + + /** + * Appends this ByteBuffer's contents to another ByteBuffer. This will overwrite any contents at and after the + specified offset up to the length of this ByteBuffer's data. + * @param {!ByteBuffer} target Target ByteBuffer + * @param {number=} offset Offset to append to. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * read if omitted. + * @returns {!ByteBuffer} this + * @expose + * @see ByteBuffer#append + */ + ByteBufferPrototype.appendTo = function(target, offset) { + target.append(this, offset); + return this; + }; + + /** + * Enables or disables assertions of argument types and offsets. Assertions are enabled by default but you can opt to + * disable them if your code already makes sure that everything is valid. + * @param {boolean} assert `true` to enable assertions, otherwise `false` + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.assert = function(assert) { + this.noAssert = !assert; + return this; + }; + + /** + * Gets the capacity of this ByteBuffer's backing buffer. + * @returns {number} Capacity of the backing buffer + * @expose + */ + ByteBufferPrototype.capacity = function() { + return this.buffer.byteLength; + }; + /** + * Clears this ByteBuffer's offsets by setting {@link ByteBuffer#offset} to `0` and {@link ByteBuffer#limit} to the + * backing buffer's capacity. Discards {@link ByteBuffer#markedOffset}. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.clear = function() { + this.offset = 0; + this.limit = this.buffer.byteLength; + this.markedOffset = -1; + return this; + }; + + /** + * Creates a cloned instance of this ByteBuffer, preset with this ByteBuffer's values for {@link ByteBuffer#offset}, + * {@link ByteBuffer#markedOffset} and {@link ByteBuffer#limit}. + * @param {boolean=} copy Whether to copy the backing buffer or to return another view on the same, defaults to `false` + * @returns {!ByteBuffer} Cloned instance + * @expose + */ + ByteBufferPrototype.clone = function(copy) { + var bb = new ByteBuffer(0, this.littleEndian, this.noAssert); + if (copy) { + bb.buffer = new ArrayBuffer(this.buffer.byteLength); + bb.view = new Uint8Array(bb.buffer); + } else { + bb.buffer = this.buffer; + bb.view = this.view; + } + bb.offset = this.offset; + bb.markedOffset = this.markedOffset; + bb.limit = this.limit; + return bb; + }; + + /** + * Compacts this ByteBuffer to be backed by a {@link ByteBuffer#buffer} of its contents' length. Contents are the bytes + * between {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. Will set `offset = 0` and `limit = capacity` and + * adapt {@link ByteBuffer#markedOffset} to the same relative position if set. + * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset} + * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit} + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.compact = function(begin, end) { + if (typeof begin === 'undefined') begin = this.offset; + if (typeof end === 'undefined') end = this.limit; + if (!this.noAssert) { + if (typeof begin !== 'number' || begin % 1 !== 0) + throw TypeError("Illegal begin: Not an integer"); + begin >>>= 0; + if (typeof end !== 'number' || end % 1 !== 0) + throw TypeError("Illegal end: Not an integer"); + end >>>= 0; + if (begin < 0 || begin > end || end > this.buffer.byteLength) + throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); + } + if (begin === 0 && end === this.buffer.byteLength) + return this; // Already compacted + var len = end - begin; + if (len === 0) { + this.buffer = EMPTY_BUFFER; + this.view = null; + if (this.markedOffset >= 0) this.markedOffset -= begin; + this.offset = 0; + this.limit = 0; + return this; + } + var buffer = new ArrayBuffer(len); + var view = new Uint8Array(buffer); + view.set(this.view.subarray(begin, end)); + this.buffer = buffer; + this.view = view; + if (this.markedOffset >= 0) this.markedOffset -= begin; + this.offset = 0; + this.limit = len; + return this; + }; + + /** + * Creates a copy of this ByteBuffer's contents. Contents are the bytes between {@link ByteBuffer#offset} and + * {@link ByteBuffer#limit}. + * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}. + * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}. + * @returns {!ByteBuffer} Copy + * @expose + */ + ByteBufferPrototype.copy = function(begin, end) { + if (typeof begin === 'undefined') begin = this.offset; + if (typeof end === 'undefined') end = this.limit; + if (!this.noAssert) { + if (typeof begin !== 'number' || begin % 1 !== 0) + throw TypeError("Illegal begin: Not an integer"); + begin >>>= 0; + if (typeof end !== 'number' || end % 1 !== 0) + throw TypeError("Illegal end: Not an integer"); + end >>>= 0; + if (begin < 0 || begin > end || end > this.buffer.byteLength) + throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); + } + if (begin === end) + return new ByteBuffer(0, this.littleEndian, this.noAssert); + var capacity = end - begin, + bb = new ByteBuffer(capacity, this.littleEndian, this.noAssert); + bb.offset = 0; + bb.limit = capacity; + if (bb.markedOffset >= 0) bb.markedOffset -= begin; + this.copyTo(bb, 0, begin, end); + return bb; + }; + + /** + * Copies this ByteBuffer's contents to another ByteBuffer. Contents are the bytes between {@link ByteBuffer#offset} and + * {@link ByteBuffer#limit}. + * @param {!ByteBuffer} target Target ByteBuffer + * @param {number=} targetOffset Offset to copy to. Will use and increase the target's {@link ByteBuffer#offset} + * by the number of bytes copied if omitted. + * @param {number=} sourceOffset Offset to start copying from. Will use and increase {@link ByteBuffer#offset} by the + * number of bytes copied if omitted. + * @param {number=} sourceLimit Offset to end copying from, defaults to {@link ByteBuffer#limit} + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.copyTo = function(target, targetOffset, sourceOffset, sourceLimit) { + var relative, + targetRelative; + if (!this.noAssert) { + if (!ByteBuffer.isByteBuffer(target)) + throw TypeError("Illegal target: Not a ByteBuffer"); + } + targetOffset = (targetRelative = typeof targetOffset === 'undefined') ? target.offset : targetOffset | 0; + sourceOffset = (relative = typeof sourceOffset === 'undefined') ? this.offset : sourceOffset | 0; + sourceLimit = typeof sourceLimit === 'undefined' ? this.limit : sourceLimit | 0; + + if (targetOffset < 0 || targetOffset > target.buffer.byteLength) + throw RangeError("Illegal target range: 0 <= "+targetOffset+" <= "+target.buffer.byteLength); + if (sourceOffset < 0 || sourceLimit > this.buffer.byteLength) + throw RangeError("Illegal source range: 0 <= "+sourceOffset+" <= "+this.buffer.byteLength); + + var len = sourceLimit - sourceOffset; + if (len === 0) + return target; // Nothing to copy + + target.ensureCapacity(targetOffset + len); + + target.view.set(this.view.subarray(sourceOffset, sourceLimit), targetOffset); + + if (relative) this.offset += len; + if (targetRelative) target.offset += len; + + return this; + }; + + /** + * Makes sure that this ByteBuffer is backed by a {@link ByteBuffer#buffer} of at least the specified capacity. If the + * current capacity is exceeded, it will be doubled. If double the current capacity is less than the required capacity, + * the required capacity will be used instead. + * @param {number} capacity Required capacity + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.ensureCapacity = function(capacity) { + var current = this.buffer.byteLength; + if (current < capacity) + return this.resize((current *= 2) > capacity ? current : capacity); + return this; + }; + + /** + * Overwrites this ByteBuffer's contents with the specified value. Contents are the bytes between + * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. + * @param {number|string} value Byte value to fill with. If given as a string, the first character is used. + * @param {number=} begin Begin offset. Will use and increase {@link ByteBuffer#offset} by the number of bytes + * written if omitted. defaults to {@link ByteBuffer#offset}. + * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}. + * @returns {!ByteBuffer} this + * @expose + * @example `someByteBuffer.clear().fill(0)` fills the entire backing buffer with zeroes + */ + ByteBufferPrototype.fill = function(value, begin, end) { + var relative = typeof begin === 'undefined'; + if (relative) begin = this.offset; + if (typeof value === 'string' && value.length > 0) + value = value.charCodeAt(0); + if (typeof begin === 'undefined') begin = this.offset; + if (typeof end === 'undefined') end = this.limit; + if (!this.noAssert) { + if (typeof value !== 'number' || value % 1 !== 0) + throw TypeError("Illegal value: "+value+" (not an integer)"); + value |= 0; + if (typeof begin !== 'number' || begin % 1 !== 0) + throw TypeError("Illegal begin: Not an integer"); + begin >>>= 0; + if (typeof end !== 'number' || end % 1 !== 0) + throw TypeError("Illegal end: Not an integer"); + end >>>= 0; + if (begin < 0 || begin > end || end > this.buffer.byteLength) + throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); + } + if (begin >= end) + return this; // Nothing to fill + while (begin < end) this.view[begin++] = value; + if (relative) this.offset = begin; + return this; + }; + + /** + * Makes this ByteBuffer ready for a new sequence of write or relative read operations. Sets `limit = offset` and + * `offset = 0`. Make sure always to flip a ByteBuffer when all relative read or write operations are complete. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.flip = function() { + this.limit = this.offset; + this.offset = 0; + return this; + }; + /** + * Marks an offset on this ByteBuffer to be used later. + * @param {number=} offset Offset to mark. Defaults to {@link ByteBuffer#offset}. + * @returns {!ByteBuffer} this + * @throws {TypeError} If `offset` is not a valid number + * @throws {RangeError} If `offset` is out of bounds + * @see ByteBuffer#reset + * @expose + */ + ByteBufferPrototype.mark = function(offset) { + offset = typeof offset === 'undefined' ? this.offset : offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + this.markedOffset = offset; + return this; + }; + /** + * Sets the byte order. + * @param {boolean} littleEndian `true` for little endian byte order, `false` for big endian + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.order = function(littleEndian) { + if (!this.noAssert) { + if (typeof littleEndian !== 'boolean') + throw TypeError("Illegal littleEndian: Not a boolean"); + } + this.littleEndian = !!littleEndian; + return this; + }; + + /** + * Switches (to) little endian byte order. + * @param {boolean=} littleEndian Defaults to `true`, otherwise uses big endian + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.LE = function(littleEndian) { + this.littleEndian = typeof littleEndian !== 'undefined' ? !!littleEndian : true; + return this; + }; + + /** + * Switches (to) big endian byte order. + * @param {boolean=} bigEndian Defaults to `true`, otherwise uses little endian + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.BE = function(bigEndian) { + this.littleEndian = typeof bigEndian !== 'undefined' ? !bigEndian : false; + return this; + }; + /** + * Prepends some data to this ByteBuffer. This will overwrite any contents before the specified offset up to the + * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer + * will be resized and its contents moved accordingly. + * @param {!ByteBuffer|string|!ArrayBuffer} source Data to prepend. If `source` is a ByteBuffer, its offset will be + * modified according to the performed read operation. + * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8") + * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes + * prepended if omitted. + * @returns {!ByteBuffer} this + * @expose + * @example A relative `00<01 02 03>.prepend(<04 05>)` results in `<04 05 01 02 03>, 04 05|` + * @example An absolute `00<01 02 03>.prepend(<04 05>, 2)` results in `04<05 02 03>, 04 05|` + */ + ByteBufferPrototype.prepend = function(source, encoding, offset) { + if (typeof encoding === 'number' || typeof encoding !== 'string') { + offset = encoding; + encoding = undefined; + } + var relative = typeof offset === 'undefined'; + if (relative) offset = this.offset; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: "+offset+" (not an integer)"); + offset >>>= 0; + if (offset < 0 || offset + 0 > this.buffer.byteLength) + throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength); + } + if (!(source instanceof ByteBuffer)) + source = ByteBuffer.wrap(source, encoding); + var len = source.limit - source.offset; + if (len <= 0) return this; // Nothing to prepend + var diff = len - offset; + if (diff > 0) { // Not enough space before offset, so resize + move + var buffer = new ArrayBuffer(this.buffer.byteLength + diff); + var view = new Uint8Array(buffer); + view.set(this.view.subarray(offset, this.buffer.byteLength), len); + this.buffer = buffer; + this.view = view; + this.offset += diff; + if (this.markedOffset >= 0) this.markedOffset += diff; + this.limit += diff; + offset += diff; + } else { + var arrayView = new Uint8Array(this.buffer); + } + this.view.set(source.view.subarray(source.offset, source.limit), offset - len); + + source.offset = source.limit; + if (relative) + this.offset -= len; + return this; + }; + + /** + * Prepends this ByteBuffer to another ByteBuffer. This will overwrite any contents before the specified offset up to the + * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer + * will be resized and its contents moved accordingly. + * @param {!ByteBuffer} target Target ByteBuffer + * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes + * prepended if omitted. + * @returns {!ByteBuffer} this + * @expose + * @see ByteBuffer#prepend + */ + ByteBufferPrototype.prependTo = function(target, offset) { + target.prepend(this, offset); + return this; + }; + /** + * Prints debug information about this ByteBuffer's contents. + * @param {function(string)=} out Output function to call, defaults to console.log + * @expose + */ + ByteBufferPrototype.printDebug = function(out) { + if (typeof out !== 'function') out = console.log.bind(console); + out( + this.toString()+"\n"+ + "-------------------------------------------------------------------\n"+ + this.toDebug(/* columns */ true) + ); + }; + + /** + * Gets the number of remaining readable bytes. Contents are the bytes between {@link ByteBuffer#offset} and + * {@link ByteBuffer#limit}, so this returns `limit - offset`. + * @returns {number} Remaining readable bytes. May be negative if `offset > limit`. + * @expose + */ + ByteBufferPrototype.remaining = function() { + return this.limit - this.offset; + }; + /** + * Resets this ByteBuffer's {@link ByteBuffer#offset}. If an offset has been marked through {@link ByteBuffer#mark} + * before, `offset` will be set to {@link ByteBuffer#markedOffset}, which will then be discarded. If no offset has been + * marked, sets `offset = 0`. + * @returns {!ByteBuffer} this + * @see ByteBuffer#mark + * @expose + */ + ByteBufferPrototype.reset = function() { + if (this.markedOffset >= 0) { + this.offset = this.markedOffset; + this.markedOffset = -1; + } else { + this.offset = 0; + } + return this; + }; + /** + * Resizes this ByteBuffer to be backed by a buffer of at least the given capacity. Will do nothing if already that + * large or larger. + * @param {number} capacity Capacity required + * @returns {!ByteBuffer} this + * @throws {TypeError} If `capacity` is not a number + * @throws {RangeError} If `capacity < 0` + * @expose + */ + ByteBufferPrototype.resize = function(capacity) { + if (!this.noAssert) { + if (typeof capacity !== 'number' || capacity % 1 !== 0) + throw TypeError("Illegal capacity: "+capacity+" (not an integer)"); + capacity |= 0; + if (capacity < 0) + throw RangeError("Illegal capacity: 0 <= "+capacity); + } + if (this.buffer.byteLength < capacity) { + var buffer = new ArrayBuffer(capacity); + var view = new Uint8Array(buffer); + view.set(this.view); + this.buffer = buffer; + this.view = view; + } + return this; + }; + /** + * Reverses this ByteBuffer's contents. + * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset} + * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit} + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.reverse = function(begin, end) { + if (typeof begin === 'undefined') begin = this.offset; + if (typeof end === 'undefined') end = this.limit; + if (!this.noAssert) { + if (typeof begin !== 'number' || begin % 1 !== 0) + throw TypeError("Illegal begin: Not an integer"); + begin >>>= 0; + if (typeof end !== 'number' || end % 1 !== 0) + throw TypeError("Illegal end: Not an integer"); + end >>>= 0; + if (begin < 0 || begin > end || end > this.buffer.byteLength) + throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); + } + if (begin === end) + return this; // Nothing to reverse + Array.prototype.reverse.call(this.view.subarray(begin, end)); + return this; + }; + /** + * Skips the next `length` bytes. This will just advance + * @param {number} length Number of bytes to skip. May also be negative to move the offset back. + * @returns {!ByteBuffer} this + * @expose + */ + ByteBufferPrototype.skip = function(length) { + if (!this.noAssert) { + if (typeof length !== 'number' || length % 1 !== 0) + throw TypeError("Illegal length: "+length+" (not an integer)"); + length |= 0; + } + var offset = this.offset + length; + if (!this.noAssert) { + if (offset < 0 || offset > this.buffer.byteLength) + throw RangeError("Illegal length: 0 <= "+this.offset+" + "+length+" <= "+this.buffer.byteLength); + } + this.offset = offset; + return this; + }; + + /** + * Slices this ByteBuffer by creating a cloned instance with `offset = begin` and `limit = end`. + * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}. + * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}. + * @returns {!ByteBuffer} Clone of this ByteBuffer with slicing applied, backed by the same {@link ByteBuffer#buffer} + * @expose + */ + ByteBufferPrototype.slice = function(begin, end) { + if (typeof begin === 'undefined') begin = this.offset; + if (typeof end === 'undefined') end = this.limit; + if (!this.noAssert) { + if (typeof begin !== 'number' || begin % 1 !== 0) + throw TypeError("Illegal begin: Not an integer"); + begin >>>= 0; + if (typeof end !== 'number' || end % 1 !== 0) + throw TypeError("Illegal end: Not an integer"); + end >>>= 0; + if (begin < 0 || begin > end || end > this.buffer.byteLength) + throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); + } + var bb = this.clone(); + bb.offset = begin; + bb.limit = end; + return bb; + }; + /** + * Returns a copy of the backing buffer that contains this ByteBuffer's contents. Contents are the bytes between + * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. + * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory if + * possible. Defaults to `false` + * @returns {!ArrayBuffer} Contents as an ArrayBuffer + * @expose + */ + ByteBufferPrototype.toBuffer = function(forceCopy) { + var offset = this.offset, + limit = this.limit; + if (!this.noAssert) { + if (typeof offset !== 'number' || offset % 1 !== 0) + throw TypeError("Illegal offset: Not an integer"); + offset >>>= 0; + if (typeof limit !== 'number' || limit % 1 !== 0) + throw TypeError("Illegal limit: Not an integer"); + limit >>>= 0; + if (offset < 0 || offset > limit || limit > this.buffer.byteLength) + throw RangeError("Illegal range: 0 <= "+offset+" <= "+limit+" <= "+this.buffer.byteLength); + } + // NOTE: It's not possible to have another ArrayBuffer reference the same memory as the backing buffer. This is + // possible with Uint8Array#subarray only, but we have to return an ArrayBuffer by contract. So: + if (!forceCopy && offset === 0 && limit === this.buffer.byteLength) + return this.buffer; + if (offset === limit) + return EMPTY_BUFFER; + var buffer = new ArrayBuffer(limit - offset); + new Uint8Array(buffer).set(new Uint8Array(this.buffer).subarray(offset, limit), 0); + return buffer; + }; + + /** + * Returns a raw buffer compacted to contain this ByteBuffer's contents. Contents are the bytes between + * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. This is an alias of {@link ByteBuffer#toBuffer}. + * @function + * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory. + * Defaults to `false` + * @returns {!ArrayBuffer} Contents as an ArrayBuffer + * @expose + */ + ByteBufferPrototype.toArrayBuffer = ByteBufferPrototype.toBuffer; + + /** + * Converts the ByteBuffer's contents to a string. + * @param {string=} encoding Output encoding. Returns an informative string representation if omitted but also allows + * direct conversion to "utf8", "hex", "base64" and "binary" encoding. "debug" returns a hex representation with + * highlighted offsets. + * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset} + * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit} + * @returns {string} String representation + * @throws {Error} If `encoding` is invalid + * @expose + */ + ByteBufferPrototype.toString = function(encoding, begin, end) { + if (typeof encoding === 'undefined') + return "ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+")"; + if (typeof encoding === 'number') + encoding = "utf8", + begin = encoding, + end = begin; + switch (encoding) { + case "utf8": + return this.toUTF8(begin, end); + case "base64": + return this.toBase64(begin, end); + case "hex": + return this.toHex(begin, end); + case "binary": + return this.toBinary(begin, end); + case "debug": + return this.toDebug(); + case "columns": + return this.toColumns(); + default: + throw Error("Unsupported encoding: "+encoding); + } + }; + + // lxiv-embeddable + + /** + * lxiv-embeddable (c) 2014 Daniel Wirtz + * Released under the Apache License, Version 2.0 + * see: https://github.com/dcodeIO/lxiv for details + */ + var lxiv = function() { + "use strict"; + + /** + * lxiv namespace. + * @type {!Object.} + * @exports lxiv + */ + var lxiv = {}; + + /** + * Character codes for output. + * @type {!Array.} + * @inner + */ + var aout = [ + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47 + ]; + + /** + * Character codes for input. + * @type {!Array.} + * @inner + */ + var ain = []; + for (var i=0, k=aout.length; i>2)&0x3f]); + t = (b&0x3)<<4; + if ((b = src()) !== null) { + t |= (b>>4)&0xf; + dst(aout[(t|((b>>4)&0xf))&0x3f]); + t = (b&0xf)<<2; + if ((b = src()) !== null) + dst(aout[(t|((b>>6)&0x3))&0x3f]), + dst(aout[b&0x3f]); + else + dst(aout[t&0x3f]), + dst(61); + } else + dst(aout[t&0x3f]), + dst(61), + dst(61); + } + }; + + /** + * Decodes base64 char codes to bytes. + * @param {!function():number|null} src Characters source as a function returning the next char code respectively + * `null` if there are no more characters left. + * @param {!function(number)} dst Bytes destination as a function successively called with the next byte. + * @throws {Error} If a character code is invalid + */ + lxiv.decode = function(src, dst) { + var c, t1, t2; + function fail(c) { + throw Error("Illegal character code: "+c); + } + while ((c = src()) !== null) { + t1 = ain[c]; + if (typeof t1 === 'undefined') fail(c); + if ((c = src()) !== null) { + t2 = ain[c]; + if (typeof t2 === 'undefined') fail(c); + dst((t1<<2)>>>0|(t2&0x30)>>4); + if ((c = src()) !== null) { + t1 = ain[c]; + if (typeof t1 === 'undefined') + if (c === 61) break; else fail(c); + dst(((t2&0xf)<<4)>>>0|(t1&0x3c)>>2); + if ((c = src()) !== null) { + t2 = ain[c]; + if (typeof t2 === 'undefined') + if (c === 61) break; else fail(c); + dst(((t1&0x3)<<6)>>>0|t2); + } + } + } + } + }; + + /** + * Tests if a string is valid base64. + * @param {string} str String to test + * @returns {boolean} `true` if valid, otherwise `false` + */ + lxiv.test = function(str) { + return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(str); + }; + + return lxiv; + }(); + + // encodings/base64 + + /** + * Encodes this ByteBuffer's contents to a base64 encoded string. + * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}. + * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}. + * @returns {string} Base64 encoded string + * @throws {RangeError} If `begin` or `end` is out of bounds + * @expose + */ + ByteBufferPrototype.toBase64 = function(begin, end) { + if (typeof begin === 'undefined') + begin = this.offset; + if (typeof end === 'undefined') + end = this.limit; + begin = begin | 0; end = end | 0; + if (begin < 0 || end > this.capacity || begin > end) + throw RangeError("begin, end"); + var sd; lxiv.encode(function() { + return begin < end ? this.view[begin++] : null; + }.bind(this), sd = stringDestination()); + return sd(); + }; + + /** + * Decodes a base64 encoded string to a ByteBuffer. + * @param {string} str String to decode + * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to + * {@link ByteBuffer.DEFAULT_ENDIAN}. + * @returns {!ByteBuffer} ByteBuffer + * @expose + */ + ByteBuffer.fromBase64 = function(str, littleEndian) { + if (typeof str !== 'string') + throw TypeError("str"); + var bb = new ByteBuffer(str.length/4*3, littleEndian), + i = 0; + lxiv.decode(stringSource(str), function(b) { + bb.view[i++] = b; + }); + bb.limit = i; + return bb; + }; + + /** + * Encodes a binary string to base64 like `window.btoa` does. + * @param {string} str Binary string + * @returns {string} Base64 encoded string + * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.btoa + * @expose + */ + ByteBuffer.btoa = function(str) { + return ByteBuffer.fromBinary(str).toBase64(); + }; + + /** + * Decodes a base64 encoded string to binary like `window.atob` does. + * @param {string} b64 Base64 encoded string + * @returns {string} Binary string + * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.atob + * @expose + */ + ByteBuffer.atob = function(b64) { + return ByteBuffer.fromBase64(b64).toBinary(); + }; + + // encodings/binary + + /** + * Encodes this ByteBuffer to a binary encoded string, that is using only characters 0x00-0xFF as bytes. + * @param {number=} begin Offset to begin at. Defaults to {@link ByteBuffer#offset}. + * @param {number=} end Offset to end at. Defaults to {@link ByteBuffer#limit}. + * @returns {string} Binary encoded string + * @throws {RangeError} If `offset > limit` + * @expose + */ + ByteBufferPrototype.toBinary = function(begin, end) { + if (typeof begin === 'undefined') + begin = this.offset; + if (typeof end === 'undefined') + end = this.limit; + begin |= 0; end |= 0; + if (begin < 0 || end > this.capacity() || begin > end) + throw RangeError("begin, end"); + if (begin === end) + return ""; + var chars = [], + parts = []; + while (begin < end) { + chars.push(this.view[begin++]); + if (chars.length >= 1024) + parts.push(String.fromCharCode.apply(String, chars)), + chars = []; + } + return parts.join('') + String.fromCharCode.apply(String, chars); + }; + + /** + * Decodes a binary encoded string, that is using only characters 0x00-0xFF as bytes, to a ByteBuffer. + * @param {string} str String to decode + * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to + * {@link ByteBuffer.DEFAULT_ENDIAN}. + * @returns {!ByteBuffer} ByteBuffer + * @expose + */ + ByteBuffer.fromBinary = function(str, littleEndian) { + if (typeof str !== 'string') + throw TypeError("str"); + var i = 0, + k = str.length, + charCode, + bb = new ByteBuffer(k, littleEndian); + while (i 0xff) + throw RangeError("illegal char code: "+charCode); + bb.view[i++] = charCode; + } + bb.limit = k; + return bb; + }; + + // encodings/debug + + /** + * Encodes this ByteBuffer to a hex encoded string with marked offsets. Offset symbols are: + * * `<` : offset, + * * `'` : markedOffset, + * * `>` : limit, + * * `|` : offset and limit, + * * `[` : offset and markedOffset, + * * `]` : markedOffset and limit, + * * `!` : offset, markedOffset and limit + * @param {boolean=} columns If `true` returns two columns hex + ascii, defaults to `false` + * @returns {string|!Array.} Debug string or array of lines if `asArray = true` + * @expose + * @example `>00'01 02<03` contains four bytes with `limit=0, markedOffset=1, offset=3` + * @example `00[01 02 03>` contains four bytes with `offset=markedOffset=1, limit=4` + * @example `00|01 02 03` contains four bytes with `offset=limit=1, markedOffset=-1` + * @example `|` contains zero bytes with `offset=limit=0, markedOffset=-1` + */ + ByteBufferPrototype.toDebug = function(columns) { + var i = -1, + k = this.buffer.byteLength, + b, + hex = "", + asc = "", + out = ""; + while (i 32 && b < 127 ? String.fromCharCode(b) : '.'; + } + ++i; + if (columns) { + if (i > 0 && i % 16 === 0 && i !== k) { + while (hex.length < 3*16+3) hex += " "; + out += hex+asc+"\n"; + hex = asc = ""; + } + } + if (i === this.offset && i === this.limit) + hex += i === this.markedOffset ? "!" : "|"; + else if (i === this.offset) + hex += i === this.markedOffset ? "[" : "<"; + else if (i === this.limit) + hex += i === this.markedOffset ? "]" : ">"; + else + hex += i === this.markedOffset ? "'" : (columns || (i !== 0 && i !== k) ? " " : ""); + } + if (columns && hex !== " ") { + while (hex.length < 3*16+3) + hex += " "; + out += hex + asc + "\n"; + } + return columns ? out : hex; + }; + + /** + * Decodes a hex encoded string with marked offsets to a ByteBuffer. + * @param {string} str Debug string to decode (not be generated with `columns = true`) + * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to + * {@link ByteBuffer.DEFAULT_ENDIAN}. + * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to + * {@link ByteBuffer.DEFAULT_NOASSERT}. + * @returns {!ByteBuffer} ByteBuffer + * @expose + * @see ByteBuffer#toDebug + */ + ByteBuffer.fromDebug = function(str, littleEndian, noAssert) { + var k = str.length, + bb = new ByteBuffer(((k+1)/3)|0, littleEndian, noAssert); + var i = 0, j = 0, ch, b, + rs = false, // Require symbol next + ho = false, hm = false, hl = false, // Already has offset (ho), markedOffset (hm), limit (hl)? + fail = false; + while (i': + if (!noAssert) { + if (hl) { + fail = true; + break; + } + hl = true; + } + bb.limit = j; + rs = false; + break; + case "'": + if (!noAssert) { + if (hm) { + fail = true; + break; + } + hm = true; + } + bb.markedOffset = j; + rs = false; + break; + case ' ': + rs = false; + break; + default: + if (!noAssert) { + if (rs) { + fail = true; + break; + } + } + b = parseInt(ch+str.charAt(i++), 16); + if (!noAssert) { + if (isNaN(b) || b < 0 || b > 255) + throw TypeError("Illegal str: Not a debug encoded string"); + } + bb.view[j++] = b; + rs = true; + } + if (fail) + throw TypeError("Illegal str: Invalid symbol at "+i); + } + if (!noAssert) { + if (!ho || !hl) + throw TypeError("Illegal str: Missing offset or limit"); + if (j>>= 0; + if (typeof end !== 'number' || end % 1 !== 0) + throw TypeError("Illegal end: Not an integer"); + end >>>= 0; + if (begin < 0 || begin > end || end > this.buffer.byteLength) + throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); + } + var out = new Array(end - begin), + b; + while (begin < end) { + b = this.view[begin++]; + if (b < 0x10) + out.push("0", b.toString(16)); + else out.push(b.toString(16)); + } + return out.join(''); + }; + + /** + * Decodes a hex encoded string to a ByteBuffer. + * @param {string} str String to decode + * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to + * {@link ByteBuffer.DEFAULT_ENDIAN}. + * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to + * {@link ByteBuffer.DEFAULT_NOASSERT}. + * @returns {!ByteBuffer} ByteBuffer + * @expose + */ + ByteBuffer.fromHex = function(str, littleEndian, noAssert) { + if (!noAssert) { + if (typeof str !== 'string') + throw TypeError("Illegal str: Not a string"); + if (str.length % 2 !== 0) + throw TypeError("Illegal str: Length not a multiple of 2"); + } + var k = str.length, + bb = new ByteBuffer((k / 2) | 0, littleEndian), + b; + for (var i=0, j=0; i 255) + throw TypeError("Illegal str: Contains non-hex characters"); + bb.view[j++] = b; + } + bb.limit = j; + return bb; + }; + + // utfx-embeddable + + /** + * utfx-embeddable (c) 2014 Daniel Wirtz + * Released under the Apache License, Version 2.0 + * see: https://github.com/dcodeIO/utfx for details + */ + var utfx = function() { + "use strict"; + + /** + * utfx namespace. + * @inner + * @type {!Object.} + */ + var utfx = {}; + + /** + * Maximum valid code point. + * @type {number} + * @const + */ + utfx.MAX_CODEPOINT = 0x10FFFF; + + /** + * Encodes UTF8 code points to UTF8 bytes. + * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point + * respectively `null` if there are no more code points left or a single numeric code point. + * @param {!function(number)} dst Bytes destination as a function successively called with the next byte + */ + utfx.encodeUTF8 = function(src, dst) { + var cp = null; + if (typeof src === 'number') + cp = src, + src = function() { return null; }; + while (cp !== null || (cp = src()) !== null) { + if (cp < 0x80) + dst(cp&0x7F); + else if (cp < 0x800) + dst(((cp>>6)&0x1F)|0xC0), + dst((cp&0x3F)|0x80); + else if (cp < 0x10000) + dst(((cp>>12)&0x0F)|0xE0), + dst(((cp>>6)&0x3F)|0x80), + dst((cp&0x3F)|0x80); + else + dst(((cp>>18)&0x07)|0xF0), + dst(((cp>>12)&0x3F)|0x80), + dst(((cp>>6)&0x3F)|0x80), + dst((cp&0x3F)|0x80); + cp = null; + } + }; + + /** + * Decodes UTF8 bytes to UTF8 code points. + * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there + * are no more bytes left. + * @param {!function(number)} dst Code points destination as a function successively called with each decoded code point. + * @throws {RangeError} If a starting byte is invalid in UTF8 + * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the + * remaining bytes. + */ + utfx.decodeUTF8 = function(src, dst) { + var a, b, c, d, fail = function(b) { + b = b.slice(0, b.indexOf(null)); + var err = Error(b.toString()); + err.name = "TruncatedError"; + err['bytes'] = b; + throw err; + }; + while ((a = src()) !== null) { + if ((a&0x80) === 0) + dst(a); + else if ((a&0xE0) === 0xC0) + ((b = src()) === null) && fail([a, b]), + dst(((a&0x1F)<<6) | (b&0x3F)); + else if ((a&0xF0) === 0xE0) + ((b=src()) === null || (c=src()) === null) && fail([a, b, c]), + dst(((a&0x0F)<<12) | ((b&0x3F)<<6) | (c&0x3F)); + else if ((a&0xF8) === 0xF0) + ((b=src()) === null || (c=src()) === null || (d=src()) === null) && fail([a, b, c ,d]), + dst(((a&0x07)<<18) | ((b&0x3F)<<12) | ((c&0x3F)<<6) | (d&0x3F)); + else throw RangeError("Illegal starting byte: "+a); + } + }; + + /** + * Converts UTF16 characters to UTF8 code points. + * @param {!function():number|null} src Characters source as a function returning the next char code respectively + * `null` if there are no more characters left. + * @param {!function(number)} dst Code points destination as a function successively called with each converted code + * point. + */ + utfx.UTF16toUTF8 = function(src, dst) { + var c1, c2 = null; + while (true) { + if ((c1 = c2 !== null ? c2 : src()) === null) + break; + if (c1 >= 0xD800 && c1 <= 0xDFFF) { + if ((c2 = src()) !== null) { + if (c2 >= 0xDC00 && c2 <= 0xDFFF) { + dst((c1-0xD800)*0x400+c2-0xDC00+0x10000); + c2 = null; continue; + } + } + } + dst(c1); + } + if (c2 !== null) dst(c2); + }; + + /** + * Converts UTF8 code points to UTF16 characters. + * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point + * respectively `null` if there are no more code points left or a single numeric code point. + * @param {!function(number)} dst Characters destination as a function successively called with each converted char code. + * @throws {RangeError} If a code point is out of range + */ + utfx.UTF8toUTF16 = function(src, dst) { + var cp = null; + if (typeof src === 'number') + cp = src, src = function() { return null; }; + while (cp !== null || (cp = src()) !== null) { + if (cp <= 0xFFFF) + dst(cp); + else + cp -= 0x10000, + dst((cp>>10)+0xD800), + dst((cp%0x400)+0xDC00); + cp = null; + } + }; + + /** + * Converts and encodes UTF16 characters to UTF8 bytes. + * @param {!function():number|null} src Characters source as a function returning the next char code respectively `null` + * if there are no more characters left. + * @param {!function(number)} dst Bytes destination as a function successively called with the next byte. + */ + utfx.encodeUTF16toUTF8 = function(src, dst) { + utfx.UTF16toUTF8(src, function(cp) { + utfx.encodeUTF8(cp, dst); + }); + }; + + /** + * Decodes and converts UTF8 bytes to UTF16 characters. + * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there + * are no more bytes left. + * @param {!function(number)} dst Characters destination as a function successively called with each converted char code. + * @throws {RangeError} If a starting byte is invalid in UTF8 + * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the remaining bytes. + */ + utfx.decodeUTF8toUTF16 = function(src, dst) { + utfx.decodeUTF8(src, function(cp) { + utfx.UTF8toUTF16(cp, dst); + }); + }; + + /** + * Calculates the byte length of an UTF8 code point. + * @param {number} cp UTF8 code point + * @returns {number} Byte length + */ + utfx.calculateCodePoint = function(cp) { + return (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4; + }; + + /** + * Calculates the number of UTF8 bytes required to store UTF8 code points. + * @param {(!function():number|null)} src Code points source as a function returning the next code point respectively + * `null` if there are no more code points left. + * @returns {number} The number of UTF8 bytes required + */ + utfx.calculateUTF8 = function(src) { + var cp, l=0; + while ((cp = src()) !== null) + l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4; + return l; + }; + + /** + * Calculates the number of UTF8 code points respectively UTF8 bytes required to store UTF16 char codes. + * @param {(!function():number|null)} src Characters source as a function returning the next char code respectively + * `null` if there are no more characters left. + * @returns {!Array.} The number of UTF8 code points at index 0 and the number of UTF8 bytes required at index 1. + */ + utfx.calculateUTF16asUTF8 = function(src) { + var n=0, l=0; + utfx.UTF16toUTF8(src, function(cp) { + ++n; l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4; + }); + return [n,l]; + }; + + return utfx; + }(); + + // encodings/utf8 + + /** + * Encodes this ByteBuffer's contents between {@link ByteBuffer#offset} and {@link ByteBuffer#limit} to an UTF8 encoded + * string. + * @returns {string} Hex encoded string + * @throws {RangeError} If `offset > limit` + * @expose + */ + ByteBufferPrototype.toUTF8 = function(begin, end) { + if (typeof begin === 'undefined') begin = this.offset; + if (typeof end === 'undefined') end = this.limit; + if (!this.noAssert) { + if (typeof begin !== 'number' || begin % 1 !== 0) + throw TypeError("Illegal begin: Not an integer"); + begin >>>= 0; + if (typeof end !== 'number' || end % 1 !== 0) + throw TypeError("Illegal end: Not an integer"); + end >>>= 0; + if (begin < 0 || begin > end || end > this.buffer.byteLength) + throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength); + } + var sd; try { + utfx.decodeUTF8toUTF16(function() { + return begin < end ? this.view[begin++] : null; + }.bind(this), sd = stringDestination()); + } catch (e) { + if (begin !== end) + throw RangeError("Illegal range: Truncated data, "+begin+" != "+end); + } + return sd(); + }; + + /** + * Decodes an UTF8 encoded string to a ByteBuffer. + * @param {string} str String to decode + * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to + * {@link ByteBuffer.DEFAULT_ENDIAN}. + * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to + * {@link ByteBuffer.DEFAULT_NOASSERT}. + * @returns {!ByteBuffer} ByteBuffer + * @expose + */ + ByteBuffer.fromUTF8 = function(str, littleEndian, noAssert) { + if (!noAssert) + if (typeof str !== 'string') + throw TypeError("Illegal str: Not a string"); + var bb = new ByteBuffer(utfx.calculateUTF16asUTF8(stringSource(str), true)[1], littleEndian, noAssert), + i = 0; + utfx.encodeUTF16toUTF8(stringSource(str), function(b) { + bb.view[i++] = b; + }); + bb.limit = i; + return bb; + }; + + return ByteBuffer; +}); diff --git a/examples/layaair/frontend/bin/libs/domparserinone.js b/examples/layaair/frontend/bin/libs/domparserinone.js new file mode 100644 index 0000000..d3d532d --- /dev/null +++ b/examples/layaair/frontend/bin/libs/domparserinone.js @@ -0,0 +1,2357 @@ +var entityMap = { + lt: '<', + gt: '>', + amp: '&', + quot: '"', + apos: "'", + Agrave: "À", + Aacute: "Á", + Acirc: "Â", + Atilde: "Ã", + Auml: "Ä", + Aring: "Å", + AElig: "Æ", + Ccedil: "Ç", + Egrave: "È", + Eacute: "É", + Ecirc: "Ê", + Euml: "Ë", + Igrave: "Ì", + Iacute: "Í", + Icirc: "Î", + Iuml: "Ï", + ETH: "Ð", + Ntilde: "Ñ", + Ograve: "Ò", + Oacute: "Ó", + Ocirc: "Ô", + Otilde: "Õ", + Ouml: "Ö", + Oslash: "Ø", + Ugrave: "Ù", + Uacute: "Ú", + Ucirc: "Û", + Uuml: "Ü", + Yacute: "Ý", + THORN: "Þ", + szlig: "ß", + agrave: "à", + aacute: "á", + acirc: "â", + atilde: "ã", + auml: "ä", + aring: "å", + aelig: "æ", + ccedil: "ç", + egrave: "è", + eacute: "é", + ecirc: "ê", + euml: "ë", + igrave: "ì", + iacute: "í", + icirc: "î", + iuml: "ï", + eth: "ð", + ntilde: "ñ", + ograve: "ò", + oacute: "ó", + ocirc: "ô", + otilde: "õ", + ouml: "ö", + oslash: "ø", + ugrave: "ù", + uacute: "ú", + ucirc: "û", + uuml: "ü", + yacute: "ý", + thorn: "þ", + yuml: "ÿ", + nbsp: " ", + iexcl: "¡", + cent: "¢", + pound: "£", + curren: "¤", + yen: "¥", + brvbar: "¦", + sect: "§", + uml: "¨", + copy: "©", + ordf: "ª", + laquo: "«", + not: "¬", + shy: "­­", + reg: "®", + macr: "¯", + deg: "°", + plusmn: "±", + sup2: "²", + sup3: "³", + acute: "´", + micro: "µ", + para: "¶", + middot: "·", + cedil: "¸", + sup1: "¹", + ordm: "º", + raquo: "»", + frac14: "¼", + frac12: "½", + frac34: "¾", + iquest: "¿", + times: "×", + divide: "÷", + forall: "∀", + part: "∂", + exist: "∃", + empty: "∅", + nabla: "∇", + isin: "∈", + notin: "∉", + ni: "∋", + prod: "∏", + sum: "∑", + minus: "−", + lowast: "∗", + radic: "√", + prop: "∝", + infin: "∞", + ang: "∠", + and: "∧", + or: "∨", + cap: "∩", + cup: "∪", + 'int': "∫", + there4: "∴", + sim: "∼", + cong: "≅", + asymp: "≈", + ne: "≠", + equiv: "≡", + le: "≤", + ge: "≥", + sub: "⊂", + sup: "⊃", + nsub: "⊄", + sube: "⊆", + supe: "⊇", + oplus: "⊕", + otimes: "⊗", + perp: "⊥", + sdot: "⋅", + Alpha: "Α", + Beta: "Β", + Gamma: "Γ", + Delta: "Δ", + Epsilon: "Ε", + Zeta: "Ζ", + Eta: "Η", + Theta: "Θ", + Iota: "Ι", + Kappa: "Κ", + Lambda: "Λ", + Mu: "Μ", + Nu: "Ν", + Xi: "Ξ", + Omicron: "Ο", + Pi: "Π", + Rho: "Ρ", + Sigma: "Σ", + Tau: "Τ", + Upsilon: "Υ", + Phi: "Φ", + Chi: "Χ", + Psi: "Ψ", + Omega: "Ω", + alpha: "α", + beta: "β", + gamma: "γ", + delta: "δ", + epsilon: "ε", + zeta: "ζ", + eta: "η", + theta: "θ", + iota: "ι", + kappa: "κ", + lambda: "λ", + mu: "μ", + nu: "ν", + xi: "ξ", + omicron: "ο", + pi: "π", + rho: "ρ", + sigmaf: "ς", + sigma: "σ", + tau: "τ", + upsilon: "υ", + phi: "φ", + chi: "χ", + psi: "ψ", + omega: "ω", + thetasym: "ϑ", + upsih: "ϒ", + piv: "ϖ", + OElig: "Œ", + oelig: "œ", + Scaron: "Š", + scaron: "š", + Yuml: "Ÿ", + fnof: "ƒ", + circ: "ˆ", + tilde: "˜", + ensp: " ", + emsp: " ", + thinsp: " ", + zwnj: "‌", + zwj: "‍", + lrm: "‎", + rlm: "‏", + ndash: "–", + mdash: "—", + lsquo: "‘", + rsquo: "’", + sbquo: "‚", + ldquo: "“", + rdquo: "”", + bdquo: "„", + dagger: "†", + Dagger: "‡", + bull: "•", + hellip: "…", + permil: "‰", + prime: "′", + Prime: "″", + lsaquo: "‹", + rsaquo: "›", + oline: "‾", + euro: "€", + trade: "™", + larr: "←", + uarr: "↑", + rarr: "→", + darr: "↓", + harr: "↔", + crarr: "↵", + lceil: "⌈", + rceil: "⌉", + lfloor: "⌊", + rfloor: "⌋", + loz: "◊", + spades: "♠", + clubs: "♣", + hearts: "♥", + diams: "♦" +}; +//for(var n in exports.entityMap){console.log(exports.entityMap[n].charCodeAt())} + +//[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF] +//[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040] +//[5] Name ::= NameStartChar (NameChar)* +var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]///\u10000-\uEFFFF +var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]"); +var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$'); +//var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/ +//var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',') + +//S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE +//S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE +var S_TAG = 0;//tag name offerring +var S_ATTR = 1;//attr name offerring +var S_ATTR_SPACE=2;//attr name end and space offer +var S_EQ = 3;//=space? +var S_ATTR_NOQUOT_VALUE = 4;//attr value(no quot value only) +var S_ATTR_END = 5;//attr value end and no space(quot end) +var S_TAG_SPACE = 6;//(attr value end || tag end ) && (space offer) +var S_TAG_CLOSE = 7;//closed el + +SaxO={}; +function XMLReader(){ + +} + +XMLReader.prototype = { + parse:function(source,defaultNSMap,entityMap){ + var domBuilder = this.domBuilder; + domBuilder.startDocument(); + _copy(defaultNSMap ,defaultNSMap = {}) + parse(source,defaultNSMap,entityMap, + domBuilder,this.errorHandler); + domBuilder.endDocument(); + } +} +function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){ + function fixedFromCharCode(code) { + // String.prototype.fromCharCode does not supports + // > 2 bytes unicode chars directly + if (code > 0xffff) { + code -= 0x10000; + var surrogate1 = 0xd800 + (code >> 10) + , surrogate2 = 0xdc00 + (code & 0x3ff); + + return String.fromCharCode(surrogate1, surrogate2); + } else { + return String.fromCharCode(code); + } + } + function entityReplacer(a){ + var k = a.slice(1,-1); + if(k in entityMap){ + return entityMap[k]; + }else if(k.charAt(0) === '#'){ + return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x'))) + }else{ + errorHandler.error('entity not found:'+a); + return a; + } + } + function appendText(end){//has some bugs + if(end>start){ + var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer); + locator&&position(start); + domBuilder.characters(xt,0,end-start); + start = end + } + } + function position(p,m){ + while(p>=lineEnd && (m = linePattern.exec(source))){ + lineStart = m.index; + lineEnd = lineStart + m[0].length; + locator.lineNumber++; + //console.log('line++:',locator,startPos,endPos) + } + locator.columnNumber = p-lineStart+1; + } + var lineStart = 0; + var lineEnd = 0; + var linePattern = /.*(?:\r\n?|\n)|.*$/g + var locator = domBuilder.locator; + + var parseStack = [{currentNSMap:defaultNSMapCopy}] + var closeMap = {}; + var start = 0; + while(true){ + try{ + var tagStart = source.indexOf('<',start); + if(tagStart<0){ + if(!source.substr(start).match(/^\s*$/)){ + var doc = domBuilder.doc; + var text = doc.createTextNode(source.substr(start)); + doc.appendChild(text); + domBuilder.currentElement = text; + } + return; + } + if(tagStart>start){ + appendText(tagStart); + } + switch(source.charAt(tagStart+1)){ + case '/': + var end = source.indexOf('>',tagStart+3); + var tagName = source.substring(tagStart+2,end); + var config = parseStack.pop(); + if(end<0){ + + tagName = source.substring(tagStart+2).replace(/[\s<].*/,''); + //console.error('#@@@@@@'+tagName) + errorHandler.error("end tag name: "+tagName+' is not complete:'+config.tagName); + end = tagStart+1+tagName.length; + }else if(tagName.match(/\s + locator&&position(tagStart); + end = parseInstruction(source,tagStart,domBuilder); + break; + case '!':// start){ + start = end; + }else{ + //TODO: 这里有可能sax回退,有位置错误风险 + appendText(Math.max(tagStart,start)+1); + } + } +} +function copyLocator(f,t){ + t.lineNumber = f.lineNumber; + t.columnNumber = f.columnNumber; + return t; +} + +/** + * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack); + * @return end of the elementStartPart(end of elementEndPart for selfClosed el) + */ +function parseElementStartPart(source,start,el,currentNSMap,entityReplacer,errorHandler){ + var attrName; + var value; + var p = ++start; + var s = S_TAG;//status + while(true){ + var c = source.charAt(p); + switch(c){ + case '=': + if(s === S_ATTR){//attrName + attrName = source.slice(start,p); + s = S_EQ; + }else if(s === S_ATTR_SPACE){ + s = S_EQ; + }else{ + //fatalError: equal must after attrName or space after attrName + throw new Error('attribute equal must after attrName'); + } + break; + case '\'': + case '"': + if(s === S_EQ || s === S_ATTR //|| s == S_ATTR_SPACE + ){//equal + if(s === S_ATTR){ + errorHandler.warning('attribute value must after "="') + attrName = source.slice(start,p) + } + start = p+1; + p = source.indexOf(c,start) + if(p>0){ + value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer); + el.add(attrName,value,start-1); + s = S_ATTR_END; + }else{ + //fatalError: no end quot match + throw new Error('attribute value no end \''+c+'\' match'); + } + }else if(s == S_ATTR_NOQUOT_VALUE){ + value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer); + //console.log(attrName,value,start,p) + el.add(attrName,value,start); + //console.dir(el) + errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!'); + start = p+1; + s = S_ATTR_END + }else{ + //fatalError: no equal before + throw new Error('attribute value must after "="'); + } + break; + case '/': + switch(s){ + case S_TAG: + el.setTagName(source.slice(start,p)); + case S_ATTR_END: + case S_TAG_SPACE: + case S_TAG_CLOSE: + s =S_TAG_CLOSE; + el.closed = true; + case S_ATTR_NOQUOT_VALUE: + case S_ATTR: + case S_ATTR_SPACE: + break; + //case S_EQ: + default: + throw new Error("attribute invalid close char('/')") + } + break; + case ''://end document + //throw new Error('unexpected end of input') + errorHandler.error('unexpected end of input'); + if(s == S_TAG){ + el.setTagName(source.slice(start,p)); + } + return p; + case '>': + switch(s){ + case S_TAG: + el.setTagName(source.slice(start,p)); + case S_ATTR_END: + case S_TAG_SPACE: + case S_TAG_CLOSE: + break;//normal + case S_ATTR_NOQUOT_VALUE://Compatible state + case S_ATTR: + value = source.slice(start,p); + if(value.slice(-1) === '/'){ + el.closed = true; + value = value.slice(0,-1) + } + case S_ATTR_SPACE: + if(s === S_ATTR_SPACE){ + value = attrName; + } + if(s == S_ATTR_NOQUOT_VALUE){ + errorHandler.warning('attribute "'+value+'" missed quot(")!!'); + el.add(attrName,value.replace(/&#?\w+;/g,entityReplacer),start) + }else{ + if(currentNSMap[''] !== 'http://www.w3.org/1999/xhtml' || !value.match(/^(?:disabled|checked|selected)$/i)){ + errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!') + } + el.add(value,value,start) + } + break; + case S_EQ: + throw new Error('attribute value missed!!'); + } +// console.log(tagName,tagNamePattern,tagNamePattern.test(tagName)) + return p; + /*xml space '\x20' | #x9 | #xD | #xA; */ + case '\u0080': + c = ' '; + default: + if(c<= ' '){//space + switch(s){ + case S_TAG: + el.setTagName(source.slice(start,p));//tagName + s = S_TAG_SPACE; + break; + case S_ATTR: + attrName = source.slice(start,p) + s = S_ATTR_SPACE; + break; + case S_ATTR_NOQUOT_VALUE: + var value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer); + errorHandler.warning('attribute "'+value+'" missed quot(")!!'); + el.add(attrName,value,start) + case S_ATTR_END: + s = S_TAG_SPACE; + break; + //case S_TAG_SPACE: + //case S_EQ: + //case S_ATTR_SPACE: + // void();break; + //case S_TAG_CLOSE: + //ignore warning + } + }else{//not space +//S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE +//S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE + switch(s){ + //case S_TAG:void();break; + //case S_ATTR:void();break; + //case S_ATTR_NOQUOT_VALUE:void();break; + case S_ATTR_SPACE: + var tagName = el.tagName; + if(currentNSMap[''] !== 'http://www.w3.org/1999/xhtml' || !attrName.match(/^(?:disabled|checked|selected)$/i)){ + errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead2!!') + } + el.add(attrName,attrName,start); + start = p; + s = S_ATTR; + break; + case S_ATTR_END: + errorHandler.warning('attribute space is required"'+attrName+'"!!') + case S_TAG_SPACE: + s = S_ATTR; + start = p; + break; + case S_EQ: + s = S_ATTR_NOQUOT_VALUE; + start = p; + break; + case S_TAG_CLOSE: + throw new Error("elements closed character '/' and '>' must be connected to"); + } + } + }//end outer switch + //console.log('p++',p) + p++; + } +} +/** + * @return true if has new namespace define + */ +SaxO.appendElement=function appendElement(el,domBuilder,currentNSMap){ + var tagName = el.tagName; + var localNSMap = null; + //var currentNSMap = parseStack[parseStack.length-1].currentNSMap; + var i = el.length; + while(i--){ + var a = el[i]; + var qName = a.qName; + var value = a.value; + var nsp = qName.indexOf(':'); + if(nsp>0){ + var prefix = a.prefix = qName.slice(0,nsp); + var localName = qName.slice(nsp+1); + var nsPrefix = prefix === 'xmlns' && localName + }else{ + localName = qName; + prefix = null + nsPrefix = qName === 'xmlns' && '' + } + //can not set prefix,because prefix !== '' + a.localName = localName ; + //prefix == null for no ns prefix attribute + if(nsPrefix !== false){//hack!! + if(localNSMap == null){ + localNSMap = {} + //console.log(currentNSMap,0) + _copy(currentNSMap,currentNSMap={}) + //console.log(currentNSMap,1) + } + currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value; + a.uri = 'http://www.w3.org/2000/xmlns/' + domBuilder.startPrefixMapping(nsPrefix, value) + } + } + var i = el.length; + while(i--){ + a = el[i]; + var prefix = a.prefix; + if(prefix){//no prefix attribute has no namespace + if(prefix === 'xml'){ + a.uri = 'http://www.w3.org/XML/1998/namespace'; + }if(prefix !== 'xmlns'){ + a.uri = currentNSMap[prefix || ''] + + //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)} + } + } + } + var nsp = tagName.indexOf(':'); + if(nsp>0){ + prefix = el.prefix = tagName.slice(0,nsp); + localName = el.localName = tagName.slice(nsp+1); + }else{ + prefix = null;//important!! + localName = el.localName = tagName; + } + //no prefix element has default namespace + var ns = el.uri = currentNSMap[prefix || '']; + domBuilder.startElement(ns,localName,tagName,el); + //endPrefixMapping and startPrefixMapping have not any help for dom builder + //localNSMap = null + if(el.closed){ + domBuilder.endElement(ns,localName,tagName); + if(localNSMap){ + for(prefix in localNSMap){ + domBuilder.endPrefixMapping(prefix) + } + } + }else{ + el.currentNSMap = currentNSMap; + el.localNSMap = localNSMap; + //parseStack.push(el); + return true; + } +} +function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){ + if(/^(?:script|textarea)$/i.test(tagName)){ + var elEndStart = source.indexOf('',elStartEnd); + var text = source.substring(elStartEnd+1,elEndStart); + if(/[&<]/.test(text)){ + if(/^script$/i.test(tagName)){ + //if(!/\]\]>/.test(text)){ + //lexHandler.startCDATA(); + domBuilder.characters(text,0,text.length); + //lexHandler.endCDATA(); + return elEndStart; + //} + }//}else{//text area + text = text.replace(/&#?\w+;/g,entityReplacer); + domBuilder.characters(text,0,text.length); + return elEndStart; + //} + + } + } + return elStartEnd+1; +} +function fixSelfClosed(source,elStartEnd,tagName,closeMap){ + //if(tagName in closeMap){ + var pos = closeMap[tagName]; + if(pos == null){ + //console.log(tagName) + pos = source.lastIndexOf('') + if(pos',start+4); + //append comment source.substring(4,end)//"); + case DOCUMENT_TYPE_NODE: + var pubid = node.publicId; + var sysid = node.systemId; + buf.push(''); + }else if(sysid && sysid!='.'){ + buf.push(' SYSTEM "',sysid,'">'); + }else{ + var sub = node.internalSubset; + if(sub){ + buf.push(" [",sub,"]"); + } + buf.push(">"); + } + return; + case PROCESSING_INSTRUCTION_NODE: + return buf.push( ""); + case ENTITY_REFERENCE_NODE: + return buf.push( '&',node.nodeName,';'); + //case ENTITY_NODE: + //case NOTATION_NODE: + default: + buf.push('??',node.nodeName); + } +} +function importNode(doc,node,deep){ + var node2; + switch (node.nodeType) { + case ELEMENT_NODE: + node2 = node.cloneNode(false); + node2.ownerDocument = doc; + //var attrs = node2.attributes; + //var len = attrs.length; + //for(var i=0;i -1; + var entityMap = isHTML?htmlEntity.entityMap:{'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"}; + if(locator){ + domBuilder.setDocumentLocator(locator) + } + + sax.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator); + sax.domBuilder = options.domBuilder || domBuilder; + if(isHTML){ + defaultNSMap['']= 'http://www.w3.org/1999/xhtml'; + } + defaultNSMap.xml = defaultNSMap.xml || 'http://www.w3.org/XML/1998/namespace'; + if(source){ + sax.parse(source,defaultNSMap,entityMap); + }else{ + sax.errorHandler.error("invalid doc source"); + } + return domBuilder.doc; +} +function buildErrorHandler(errorImpl,domBuilder,locator){ + if(!errorImpl){ + if(domBuilder instanceof DOMHandler){ + return domBuilder; + } + errorImpl = domBuilder ; + } + var errorHandler = {} + var isCallback = errorImpl instanceof Function; + locator = locator||{} + function build(key){ + var fn = errorImpl[key]; + if(!fn && isCallback){ + fn = errorImpl.length == 2?function(msg){errorImpl(key,msg)}:errorImpl; + } + errorHandler[key] = fn && function(msg){ + fn('[xmldom '+key+']\t'+msg+_locator(locator)); + }||function(){}; + } + build('warning'); + build('error'); + build('fatalError'); + return errorHandler; +} + +//console.log('#\n\n\n\n\n\n\n####') +/** + * +ContentHandler+ErrorHandler + * +LexicalHandler+EntityResolver2 + * -DeclHandler-DTDHandler + * + * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler + * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2 + * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html + */ +function DOMHandler() { + this.cdata = false; +} +function position(locator,node){ + node.lineNumber = locator.lineNumber; + node.columnNumber = locator.columnNumber; +} +/** + * @see org.xml.sax.ContentHandler#startDocument + * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html + */ +DOMHandler.prototype = { + startDocument : function() { + this.doc = new DOMImplementation().createDocument(null, null, null); + if (this.locator) { + this.doc.documentURI = this.locator.systemId; + } + }, + startElement:function(namespaceURI, localName, qName, attrs) { + var doc = this.doc; + var el = doc.createElementNS(namespaceURI, qName||localName); + var len = attrs.length; + appendElement(this, el); + this.currentElement = el; + + this.locator && position(this.locator,el) + for (var i = 0 ; i < len; i++) { + var namespaceURI = attrs.getURI(i); + var value = attrs.getValue(i); + var qName = attrs.getQName(i); + var attr = doc.createAttributeNS(namespaceURI, qName); + this.locator &&position(attrs.getLocator(i),attr); + attr.value = attr.nodeValue = value; + el.setAttributeNode(attr) + } + }, + endElement:function(namespaceURI, localName, qName) { + var current = this.currentElement + var tagName = current.tagName; + this.currentElement = current.parentNode; + }, + startPrefixMapping:function(prefix, uri) { + }, + endPrefixMapping:function(prefix) { + }, + processingInstruction:function(target, data) { + var ins = this.doc.createProcessingInstruction(target, data); + this.locator && position(this.locator,ins) + appendElement(this, ins); + }, + ignorableWhitespace:function(ch, start, length) { + }, + characters:function(chars, start, length) { + chars = _toString.apply(this,arguments) + //console.log(chars) + if(chars){ + if (this.cdata) { + var charNode = this.doc.createCDATASection(chars); + } else { + var charNode = this.doc.createTextNode(chars); + } + if(this.currentElement){ + this.currentElement.appendChild(charNode); + }else if(/^\s*$/.test(chars)){ + this.doc.appendChild(charNode); + //process xml + } + this.locator && position(this.locator,charNode) + } + }, + skippedEntity:function(name) { + }, + endDocument:function() { + this.doc.normalize(); + }, + setDocumentLocator:function (locator) { + if(this.locator = locator){// && !('lineNumber' in locator)){ + locator.lineNumber = 0; + } + }, + //LexicalHandler + comment:function(chars, start, length) { + chars = _toString.apply(this,arguments) + var comm = this.doc.createComment(chars); + this.locator && position(this.locator,comm) + appendElement(this, comm); + }, + + startCDATA:function() { + //used in characters() methods + this.cdata = true; + }, + endCDATA:function() { + this.cdata = false; + }, + + startDTD:function(name, publicId, systemId) { + var impl = this.doc.implementation; + if (impl && impl.createDocumentType) { + var dt = impl.createDocumentType(name, publicId, systemId); + this.locator && position(this.locator,dt) + appendElement(this, dt); + } + }, + /** + * @see org.xml.sax.ErrorHandler + * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html + */ + warning:function(error) { + console.warn('[xmldom warning]\t'+error,_locator(this.locator)); + }, + error:function(error) { + console.error('[xmldom error]\t'+error,_locator(this.locator)); + }, + fatalError:function(error) { + console.error('[xmldom fatalError]\t'+error,_locator(this.locator)); + throw error; + } +} +function _locator(l){ + if(l){ + return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']' + } +} +function _toString(chars,start,length){ + if(typeof chars == 'string'){ + return chars.substr(start,length) + }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)") + if(chars.length >= start+length || start){ + return new java.lang.String(chars,start,length)+''; + } + return chars; + } +} + +/* + * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html + * used method of org.xml.sax.ext.LexicalHandler: + * #comment(chars, start, length) + * #startCDATA() + * #endCDATA() + * #startDTD(name, publicId, systemId) + * + * + * IGNORED method of org.xml.sax.ext.LexicalHandler: + * #endDTD() + * #startEntity(name) + * #endEntity(name) + * + * + * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html + * IGNORED method of org.xml.sax.ext.DeclHandler + * #attributeDecl(eName, aName, type, mode, value) + * #elementDecl(name, model) + * #externalEntityDecl(name, publicId, systemId) + * #internalEntityDecl(name, value) + * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html + * IGNORED method of org.xml.sax.EntityResolver2 + * #resolveEntity(String name,String publicId,String baseURI,String systemId) + * #resolveEntity(publicId, systemId) + * #getExternalSubset(name, baseURI) + * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html + * IGNORED method of org.xml.sax.DTDHandler + * #notationDecl(name, publicId, systemId) {}; + * #unparsedEntityDecl(name, publicId, systemId, notationName) {}; + */ +"endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){ + DOMHandler.prototype[key] = function(){return null} +}) + +/* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */ +function appendElement (hander,node) { + if (!hander.currentElement) { + hander.doc.appendChild(node); + } else { + hander.currentElement.appendChild(node); + } +}//appendChild and setAttributeNS are preformance key + + + htmlEntity={}; + htmlEntity.entityMap=entityMap; + + + +window.Parser = { DOMParser :DOMParser}; \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/laya.Alipaymini.js b/examples/layaair/frontend/bin/libs/laya.Alipaymini.js new file mode 100644 index 0000000..dc2a35e --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.Alipaymini.js @@ -0,0 +1,1825 @@ +window.aliPayMiniGame = function (exports, Laya) { + 'use strict'; + + class MiniFileMgr { + static isLocalNativeFile(url) { + for (var i = 0, sz = ALIMiniAdapter.nativefiles.length; i < sz; i++) { + if (url.indexOf(ALIMiniAdapter.nativefiles[i]) != -1) + return true; + } + return false; + } + static isNetFile(url) { + return (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) && url.indexOf(ALIMiniAdapter.window.my.env.USER_DATA_PATH) == -1; + } + static getFileInfo(fileUrl) { + var fileNativePath = fileUrl; + var fileObj = MiniFileMgr.fakeObj[fileNativePath]; + if (fileObj == null) + return null; + else + return fileObj; + } + static read(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "") { + var fileUrl; + if (readyUrl != "" && (readyUrl.indexOf("http://") != -1 || readyUrl.indexOf("https://") != -1)) { + fileUrl = MiniFileMgr.getFileNativePath(filePath); + } + else { + fileUrl = filePath; + } + fileUrl = Laya.URL.getAdptedFilePath(fileUrl); + MiniFileMgr.fs.readFile({ filePath: fileUrl, encoding: encoding, success: function (data) { + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data && readyUrl != "") + MiniFileMgr.downFiles(encodeURI(readyUrl), encoding, callBack, readyUrl, isSaveFile, fileType); + else + callBack != null && callBack.runWith([1]); + } }); + } + static isFile(url) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(url); + } + catch (err) { + return false; + } + return stat.isFile(); + } + static downFiles(fileUrl, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + var downloadTask = MiniFileMgr.down({ url: fileUrl, success: function (data) { + if (!data.hasOwnProperty("statusCode")) { + data.statusCode = 200; + } + if (data.statusCode === 200) + MiniFileMgr.readFile(data.apFilePath, encoding, callBack, readyUrl, isSaveFile, fileType, isAutoClear); + else if (data.statusCode === 403) { + callBack != null && callBack.runWith([0, fileUrl]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + downloadTask.onProgressUpdate(function (data) { + callBack != null && callBack.runWith([2, data.progress]); + }); + } + static readFile(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + filePath = Laya.URL.getAdptedFilePath(filePath); + MiniFileMgr.fs.readFile({ filePath: filePath, encoding: encoding, success: function (data) { + if ((filePath.indexOf("http://") != -1 || filePath.indexOf("https://") != -1) && filePath.indexOf(ALIMiniAdapter.window.my.env.USER_DATA_PATH) == -1) { + if (ALIMiniAdapter.AutoCacheDownFile || isSaveFile) { + callBack != null && callBack.runWith([0, data]); + MiniFileMgr.copyTOCache(filePath, readyUrl, null, encoding, isAutoClear); + } + else + callBack != null && callBack.runWith([0, data]); + } + else + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data) + callBack != null && callBack.runWith([1, data]); + } }); + } + static downOtherFiles(fileUrl, callBack = null, readyUrl = "", isSaveFile = false, isAutoClear = true) { + MiniFileMgr.down({ url: fileUrl, success: function (data) { + if (!data.hasOwnProperty("statusCode")) + data.statusCode = 200; + if (data.statusCode === 200) { + if ((ALIMiniAdapter.autoCacheFile || isSaveFile) && readyUrl.indexOf(".php") == -1) { + callBack != null && callBack.runWith([0, data.apFilePath]); + MiniFileMgr.copyTOCache(data.apFilePath, readyUrl, null, "", isAutoClear); + } + else + callBack != null && callBack.runWith([0, data.apFilePath]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static copyFile(src, dest, complete = null) { + MiniFileMgr.fs.copyFile({ + srcPath: src, + destPath: dest, + success: function () { + complete && complete.runWith(0); + }, + fail: function (err) { + complete && complete.runWith([1, err]); + } + }); + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + if (window.navigator.userAgent.indexOf('AlipayMiniGame') < 0) { + Laya.Laya.loader.load(fileUrl, callBack); + } + else { + if (fileType == Laya.Loader.IMAGE || fileType == Laya.Loader.SOUND) + MiniFileMgr.downOtherFiles(fileUrl, callBack, fileUrl, true, false); + else + MiniFileMgr.downFiles(fileUrl, encoding, callBack, fileUrl, true, fileType, false); + } + } + static copyTOCache(tempFilePath, readyUrl, callBack, encoding = "", isAutoClear = true) { + var temp = tempFilePath.split("/"); + var tempFileName = temp[temp.length - 1]; + var fileurlkey = readyUrl; + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fakeObj[fileurlkey] = { md5: tempFileName, readyUrl: readyUrl, size: 0, times: Laya.Browser.now(), encoding: encoding, tempFilePath: tempFilePath }; + var totalSize = ALIMiniAdapter.sizeLimit; + var chaSize = 4 * 1024 * 1024; + var fileUseSize = MiniFileMgr.getCacheUseSize(); + if (fileObj) { + if (fileObj.readyUrl != readyUrl) { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > ALIMiniAdapter.minClearSize) + ALIMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.deleteFile(tempFilePath, readyUrl, callBack, encoding, data.size); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + else + callBack != null && callBack.runWith([0]); + } + else { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > ALIMiniAdapter.minClearSize) + ALIMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.fs.copyFile({ srcPath: tempFilePath, destPath: saveFilePath, success: function (data2) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, data.size); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + } + static onClearCacheRes() { + var memSize = ALIMiniAdapter.minClearSize; + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + MiniFileMgr.sortOn(tempFileListArr, "times", MiniFileMgr.NUMERIC); + var clearSize = 0; + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + if (clearSize >= memSize) + break; + clearSize += fileObj.size; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + } + static sortOn(array, name, options = 0) { + if (options == MiniFileMgr.NUMERIC) + return array.sort(function (a, b) { return a[name] - b[name]; }); + if (options == (MiniFileMgr.NUMERIC | MiniFileMgr.DESCENDING)) + return array.sort(function (a, b) { return b[name] - a[name]; }); + return array.sort(function (a, b) { return a[name] - b[name]; }); + } + static getFileNativePath(fileName) { + return MiniFileMgr.fileNativeDir + "/" + fileName; + } + static deleteFile(tempFileName, readyUrl = "", callBack = null, encoding = "", fileSize = 0) { + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var deleteFileUrl = MiniFileMgr.getFileNativePath(fileObj.md5); + MiniFileMgr.fs.unlink({ filePath: deleteFileUrl, success: function (data) { + if (tempFileName != "") { + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fs.copyFile({ srcPath: tempFileName, destPath: saveFilePath, success: function (data) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, fileSize); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + else { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, false, encoding, callBack, fileSize); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static deleteAll() { + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj.fileUsedSize) { + MiniFileMgr.filesListObj.fileUsedSize = 0; + } + MiniFileMgr.writeFilesList("", JSON.stringify({}), false); + } + static onSaveFile(readyUrl, md5Name, isAdd = true, encoding = "", callBack = null, fileSize = 0) { + var fileurlkey = readyUrl; + if (MiniFileMgr.filesListObj['fileUsedSize'] == null) + MiniFileMgr.filesListObj['fileUsedSize'] = 0; + if (isAdd) { + var fileNativeName = MiniFileMgr.getFileNativePath(md5Name); + MiniFileMgr.filesListObj[fileurlkey] = { md5: md5Name, readyUrl: readyUrl, size: fileSize, times: Laya.Browser.now(), encoding: encoding, tempFilePath: fileNativeName }; + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) + fileSize; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), true); + callBack != null && callBack.runWith([0]); + } + else { + if (MiniFileMgr.filesListObj[fileurlkey]) { + var deletefileSize = parseInt(MiniFileMgr.filesListObj[fileurlkey].size); + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) - deletefileSize; + if (MiniFileMgr.fakeObj[fileurlkey].md5 == MiniFileMgr.filesListObj[fileurlkey].md5) { + delete MiniFileMgr.fakeObj[fileurlkey]; + } + delete MiniFileMgr.filesListObj[fileurlkey]; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), false); + callBack != null && callBack.runWith([0]); + } + } + } + static writeFilesList(fileurlkey, filesListStr, isAdd) { + var listFilesPath = MiniFileMgr.fileNativeDir + "/" + MiniFileMgr.fileListName; + MiniFileMgr.fs.writeFile({ filePath: listFilesPath, encoding: 'utf8', data: filesListStr, success: function (data) { + }, fail: function (data) { + } }); + if (!ALIMiniAdapter.isZiYu && ALIMiniAdapter.isPosMsgYu && ALIMiniAdapter.window.my.postMessage) { + ALIMiniAdapter.window.my.postMessage({ url: fileurlkey, data: MiniFileMgr.filesListObj[fileurlkey], isLoad: "filenative", isAdd: isAdd }); + } + } + static getCacheUseSize() { + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj['fileUsedSize']) + return MiniFileMgr.filesListObj['fileUsedSize']; + return 0; + } + static getCacheList(dirPath, cb) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(dirPath); + } + catch (err) { + stat = null; + } + if (stat) { + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", cb); + } + else { + MiniFileMgr.fs.mkdirSync(dirPath, true); + cb && cb.runWith([1]); + } + } + static existDir(dirPath, callBack) { + MiniFileMgr.fs.mkdir({ dirPath: dirPath, success: function (data) { + callBack != null && callBack.runWith([0, { data: JSON.stringify({}) }]); + }, fail: function (data) { + if (data.error == 10025) + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", callBack); + else + callBack != null && callBack.runWith([1, data]); + } }); + } + static readSync(filePath, encoding = "utf8", callBack = null, readyUrl = "") { + var fileUrl = MiniFileMgr.getFileNativePath(filePath); + var filesListStr; + try { + filesListStr = MiniFileMgr.fs.readFileSync(fileUrl, encoding); + callBack != null && callBack.runWith([0, { data: filesListStr }]); + } + catch (error) { + callBack != null && callBack.runWith([1]); + } + } + static setNativeFileDir(value) { + MiniFileMgr.fileNativeDir = ALIMiniAdapter.window.my.env.USER_DATA_PATH + value; + } + } + MiniFileMgr.fs = window.my.getFileSystemManager(); + MiniFileMgr.down = window.my.downloadFile; + MiniFileMgr.filesListObj = {}; + MiniFileMgr.fakeObj = {}; + MiniFileMgr.fileListName = "layaairfiles.txt"; + MiniFileMgr.ziyuFileData = {}; + MiniFileMgr.ziyuFileTextureData = {}; + MiniFileMgr.loadPath = ""; + MiniFileMgr.DESCENDING = 2; + MiniFileMgr.NUMERIC = 16; + + class MiniSoundChannel extends Laya.SoundChannel { + constructor(audio, miniSound) { + super(); + this._audio = audio; + this._miniSound = miniSound; + this._onEnd = MiniSoundChannel.bindToThis(this.__onEnd, this); + audio.onEnded(this._onEnd); + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + __onEnd() { + if (this.loops == 1) { + if (this.completeHandler) { + Laya.Laya.systemTimer.once(10, this, this.__runComplete, [this.completeHandler], false); + this.completeHandler = null; + } + this.stop(); + this.event(Laya.Event.COMPLETE); + return; + } + if (this.loops > 0) { + this.loops--; + } + this.startTime = 0; + this.play(); + } + play() { + this.isStopped = false; + Laya.SoundManager.addChannel(this); + this._audio.play(); + } + set startTime(time) { + if (this._audio) { + this._audio.startTime = time; + } + } + set autoplay(value) { + this._audio.autoplay = value; + } + get autoplay() { + return this._audio.autoplay; + } + get position() { + if (!this._audio) + return 0; + return this._audio.currentTime; + } + get duration() { + if (!this._audio) + return 0; + return this._audio.duration; + } + stop() { + this.isStopped = true; + Laya.SoundManager.removeChannel(this); + this.completeHandler = null; + if (!this._audio) + return; + this._audio.stop(); + if (!this.loop) { + this._audio.offEnded(null); + this._miniSound.dispose(); + this._audio = null; + this._miniSound = null; + this._onEnd = null; + } + } + pause() { + this.isStopped = true; + this._audio.pause(); + } + get loop() { + return this._audio.loop; + } + set loop(value) { + this._audio.loop = value; + } + resume() { + if (!this._audio) + return; + this.isStopped = false; + Laya.SoundManager.addChannel(this); + this._audio.play(); + } + set volume(v) { + if (!this._audio) + return; + this._audio.volume = v; + } + get volume() { + if (!this._audio) + return 1; + return this._audio.volume; + } + } + + class MiniSound extends Laya.EventDispatcher { + constructor() { + super(); + this.loaded = false; + } + static _createSound() { + MiniSound._id++; + return ALIMiniAdapter.window.my.createInnerAudioContext(); + } + load(url) { + if (!MiniSound._musicAudio) + MiniSound._musicAudio = MiniSound._createSound(); + if (!MiniFileMgr.isLocalNativeFile(url)) { + url = Laya.URL.formatURL(url); + } + else { + if (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + if (tempStr != "") + url = url.split(tempStr)[1]; + } + } + } + this.url = url; + this.readyUrl = url; + if (MiniSound._audioCache[this.readyUrl]) { + this.event(Laya.Event.COMPLETE); + return; + } + if (ALIMiniAdapter.autoCacheFile && MiniFileMgr.getFileInfo(url)) { + this.onDownLoadCallBack(url, 0); + } + else { + if (!ALIMiniAdapter.autoCacheFile) { + this.onDownLoadCallBack(url, 0); + } + else { + if (MiniFileMgr.isLocalNativeFile(url)) { + tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + if (ALIMiniAdapter.subNativeFiles && ALIMiniAdapter.subNativeheads.length == 0) { + for (var key in ALIMiniAdapter.subNativeFiles) { + var tempArr = ALIMiniAdapter.subNativeFiles[key]; + ALIMiniAdapter.subNativeheads = ALIMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + ALIMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (ALIMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && ALIMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = ALIMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + this.onDownLoadCallBack(url, 0); + } + else { + if (!MiniFileMgr.isLocalNativeFile(url) && (url.indexOf("http://") == -1 && url.indexOf("https://") == -1) || (url.indexOf(ALIMiniAdapter.window.my.env.USER_DATA_PATH) != -1)) { + this.onDownLoadCallBack(url, 0); + } + else { + MiniFileMgr.downOtherFiles(encodeURI(url), Laya.Handler.create(this, this.onDownLoadCallBack, [url]), url); + } + } + } + } + } + onDownLoadCallBack(sourceUrl, errorCode, tempFilePath = null) { + if (!errorCode) { + var fileNativeUrl; + if (ALIMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = sourceUrl; + if (tempStr != "" && (sourceUrl.indexOf("http://") != -1 || sourceUrl.indexOf("https://") != -1)) + fileNativeUrl = sourceUrl.split(tempStr)[1]; + if (!fileNativeUrl) { + fileNativeUrl = tempUrl; + } + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + var fileMd5Name = fileObj.md5; + fileNativeUrl = MiniFileMgr.getFileNativePath(fileMd5Name); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + if (this.url != Laya.SoundManager._bgMusic) { + this._sound = MiniSound._createSound(); + this._sound.src = this.url = fileNativeUrl; + } + else { + this._sound = MiniSound._musicAudio; + this._sound.src = this.url = fileNativeUrl; + } + } + else { + if (this.url != Laya.SoundManager._bgMusic) { + this._sound = MiniSound._createSound(); + this._sound.src = sourceUrl; + } + else { + this._sound = MiniSound._musicAudio; + this._sound.src = sourceUrl; + } + } + this._sound.onCanPlay(MiniSound.bindToThis(this.onCanPlay, this)); + this._sound.onError(MiniSound.bindToThis(this.onError, this)); + } + else { + this.event(Laya.Event.ERROR); + } + } + onError(error) { + this.event(Laya.Event.ERROR); + this._sound.offError(null); + } + onCanPlay() { + this.loaded = true; + this.event(Laya.Event.COMPLETE); + this._sound.offCanPlay(null); + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + play(startTime = 0, loops = 0) { + var tSound; + if (this.url == Laya.SoundManager._bgMusic) { + if (!MiniSound._musicAudio) + MiniSound._musicAudio = MiniSound._createSound(); + tSound = MiniSound._musicAudio; + } + else { + if (MiniSound._audioCache[this.readyUrl]) { + tSound = MiniSound._audioCache[this.readyUrl]._sound; + } + else { + tSound = MiniSound._createSound(); + } + } + if (!tSound) + return null; + if (ALIMiniAdapter.autoCacheFile && MiniFileMgr.getFileInfo(this.url)) { + var fileObj = MiniFileMgr.getFileInfo(this.url); + var fileMd5Name = fileObj.md5; + tSound.src = this.url = MiniFileMgr.getFileNativePath(fileMd5Name); + } + else { + tSound.src = encodeURI(this.url); + } + var channel = new MiniSoundChannel(tSound, this); + channel.url = this.url; + channel.loops = loops; + channel.loop = (loops === 0 ? true : false); + channel.startTime = startTime; + channel.play(); + Laya.SoundManager.addChannel(channel); + return channel; + } + get duration() { + return this._sound.duration; + } + dispose() { + var ad = MiniSound._audioCache[this.readyUrl]; + if (ad) { + ad.src = ""; + if (ad._sound) { + ad._sound.destroy(); + ad._sound = null; + ad = null; + } + delete MiniSound._audioCache[this.readyUrl]; + } + if (this._sound) { + this._sound.destroy(); + this._sound = null; + this.readyUrl = this.url = null; + } + } + } + MiniSound._id = 0; + MiniSound._audioCache = {}; + + class MiniInput { + constructor() { + } + static _createInputElement() { + Laya.Input['_initInput'](Laya.Input['area'] = Laya.Browser.createElement("textarea")); + Laya.Input['_initInput'](Laya.Input['input'] = Laya.Browser.createElement("input")); + Laya.Input['inputContainer'] = Laya.Browser.createElement("div"); + Laya.Input['inputContainer'].style.position = "absolute"; + Laya.Input['inputContainer'].style.zIndex = 1E5; + Laya.Browser.container.appendChild(Laya.Input['inputContainer']); + Laya.Laya.stage.on("resize", null, MiniInput._onStageResize); + ALIMiniAdapter.window.my.onWindowResize && ALIMiniAdapter.window.my.onWindowResize(function (res) { + }); + Laya.SoundManager._soundClass = MiniSound; + Laya.SoundManager._musicClass = MiniSound; + var model = ALIMiniAdapter.systemInfo.model; + var system = ALIMiniAdapter.systemInfo.system; + if (model.indexOf("iPhone") != -1) { + Laya.Browser.onIPhone = true; + Laya.Browser.onIOS = true; + Laya.Browser.onIPad = true; + Laya.Browser.onAndroid = false; + } + if (system.indexOf("Android") != -1 || system.indexOf("Adr") != -1) { + Laya.Browser.onAndroid = true; + Laya.Browser.onIPhone = false; + Laya.Browser.onIOS = false; + Laya.Browser.onIPad = false; + } + } + static _onStageResize() { + var ts = Laya.Laya.stage._canvasTransform.identity(); + ts.scale((Laya.Browser.width / Laya.Render.canvas.width / Laya.Browser.pixelRatio), Laya.Browser.height / Laya.Render.canvas.height / Laya.Browser.pixelRatio); + } + static wxinputFocus(e) { + var _inputTarget = Laya.Input['inputElement'].target; + if (_inputTarget && !_inputTarget.editable) { + return; + } + ALIMiniAdapter.window.my.offKeyboardConfirm(); + ALIMiniAdapter.window.my.offKeyboardInput(); + ALIMiniAdapter.window.my.showKeyboard({ defaultValue: _inputTarget.text, maxLength: _inputTarget.maxChars, multiple: _inputTarget.multiline, confirmHold: true, confirmType: _inputTarget["confirmType"] || 'done', success: function (res) { + }, fail: function (res) { + } }); + ALIMiniAdapter.window.my.onKeyboardConfirm(function (res) { + var str = res ? res.value : ""; + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + MiniInput.inputEnter(); + _inputTarget.event("confirm"); + }); + ALIMiniAdapter.window.my.onKeyboardInput(function (res) { + var str = res ? res.value : ""; + if (!_inputTarget.multiline) { + if (str.indexOf("\n") != -1) { + MiniInput.inputEnter(); + return; + } + } + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + }); + } + static inputEnter() { + Laya.Input['inputElement'].target.focus = false; + } + static wxinputblur() { + MiniInput.hideKeyboard(); + } + static hideKeyboard() { + ALIMiniAdapter.window.my.offKeyboardConfirm(); + ALIMiniAdapter.window.my.offKeyboardInput(); + ALIMiniAdapter.window.my.hideKeyboard({ success: function (res) { + console.log('隐藏键盘'); + }, fail: function (res) { + console.log("隐藏键盘出错:" + (res ? res.errMsg : "")); + } }); + } + } + + class MiniLoader extends Laya.EventDispatcher { + constructor() { + super(); + } + _loadResourceFilter(type, url) { + var thisLoader = this; + this.sourceUrl = Laya.URL.formatURL(url); + if (MiniFileMgr.isNetFile(url)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (ALIMiniAdapter.subNativeFiles && ALIMiniAdapter.subNativeheads.length == 0) { + for (var key in ALIMiniAdapter.subNativeFiles) { + var tempArr = ALIMiniAdapter.subNativeFiles[key]; + ALIMiniAdapter.subNativeheads = ALIMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + ALIMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (ALIMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && ALIMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = ALIMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + switch (type) { + case Laya.Loader.IMAGE: + case "htmlimage": + case "nativeimage": + MiniLoader._transformImgUrl(url, type, thisLoader); + break; + case Laya.Loader.SOUND: + thisLoader._loadSound(url); + break; + default: + thisLoader._loadResource(type, url); + } + } + _loadSound(url) { + var thisLoader = this; + if (!ALIMiniAdapter.autoCacheFile) { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + else { + var tempurl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downOtherFiles(encodeURI(tempurl), Laya.Handler.create(MiniLoader, MiniLoader.onDownLoadCallBack, [tempurl, thisLoader]), tempurl); + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + } + static onDownLoadCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = null) { + if (!errorCode) { + var fileNativeUrl; + if (ALIMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + fileNativeUrl = sourceUrl; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + } + else { + fileNativeUrl = Laya.URL.formatURL(sourceUrl); + } + sourceUrl = fileNativeUrl; + var sound = (new Laya.SoundManager._soundClass()); + sound.load(encodeURI(sourceUrl)); + thisLoader.onLoaded(sound); + } + else { + thisLoader.event(Laya.Event.ERROR, "Load sound failed"); + } + } + complete(data) { + if (data instanceof Laya.Resource) { + data._setCreateURL(this.sourceUrl); + } + else if ((data instanceof Laya.Texture) && (data.bitmap instanceof Laya.Resource)) { + data.bitmap._setCreateURL(this.sourceUrl); + } + this.originComplete(data); + } + _loadHttpRequestWhat(url, contentType) { + var thisLoader = this; + var encoding = ALIMiniAdapter.getUrlEncode(url, contentType); + if (Laya.Loader.preLoadedMap[url]) + thisLoader.onLoaded(Laya.Loader.preLoadedMap[url]); + else { + var tempurl = Laya.URL.formatURL(url); + if (!ALIMiniAdapter.AutoCacheDownFile) { + if (MiniFileMgr.isNetFile(tempurl)) { + thisLoader._loadHttpRequest(tempurl, contentType, thisLoader, thisLoader.onLoaded, thisLoader, thisLoader.onProgress, thisLoader, thisLoader.onError); + } + else + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + else { + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downFiles(encodeURI(tempurl), encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), tempurl, true); + } + else { + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + else { + var tempUrl = url; + var fileObj = MiniFileMgr.getFileInfo(tempurl); + if (fileObj && fileObj.md5) { + tempUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + MiniFileMgr.readFile(tempUrl, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + } + } + static onReadNativeCallBack(url, type = null, thisLoader = null, errorCode = 0, data = null) { + if (!errorCode) { + var tempData; + if (type == Laya.Loader.JSON || type == Laya.Loader.ATLAS || type == Laya.Loader.PREFAB || type == Laya.Loader.PLF) { + tempData = ALIMiniAdapter.getJson(data.data); + } + else if (type == Laya.Loader.XML) { + tempData = Laya.Utils.parseXMLFromString(data.data); + } + else { + tempData = data.data; + } + if (!ALIMiniAdapter.isZiYu && ALIMiniAdapter.isPosMsgYu && type != Laya.Loader.BUFFER && ALIMiniAdapter.window.my.postMessage) { + ALIMiniAdapter.window.my.postMessage({ url: url, data: tempData, isLoad: "filedata" }); + } + thisLoader.onLoaded(tempData); + } + else if (errorCode == 1) { + thisLoader._loadHttpRequest(url, type, thisLoader, thisLoader.onLoaded, thisLoader, thisLoader.onProgress, thisLoader, thisLoader.onError); + } + } + static _transformImgUrl(url, type, thisLoader) { + if (ALIMiniAdapter.isZiYu || MiniFileMgr.isLocalNativeFile(url)) { + thisLoader._loadImage(url, false); + return; + } + if (!ALIMiniAdapter.autoCacheFile) { + thisLoader._loadImage(encodeURI(url)); + } + else { + var tempUrl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempUrl)) { + if (MiniFileMgr.isNetFile(tempUrl)) { + MiniFileMgr.downOtherFiles(encodeURI(tempUrl), new Laya.Handler(MiniLoader, MiniLoader.onDownImgCallBack, [url, thisLoader]), tempUrl); + } + else { + MiniLoader.onCreateImage(url, thisLoader, true); + } + } + else { + MiniLoader.onCreateImage(url, thisLoader); + } + } + } + static onDownImgCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = "") { + if (!errorCode) + MiniLoader.onCreateImage(sourceUrl, thisLoader, false, tempFilePath); + else { + thisLoader.onError(null); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (ALIMiniAdapter.autoCacheFile) { + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + var fileObj = MiniFileMgr.getFileInfo(Laya.URL.formatURL(sourceUrl)); + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + } + else if (ALIMiniAdapter.isZiYu) { + var tempUrl = Laya.URL.formatURL(sourceUrl); + if (MiniFileMgr.ziyuFileTextureData[tempUrl]) { + fileNativeUrl = MiniFileMgr.ziyuFileTextureData[tempUrl]; + } + else + fileNativeUrl = sourceUrl; + } + else + fileNativeUrl = sourceUrl; + } + else { + if (!isLocal) + fileNativeUrl = tempFilePath; + else + fileNativeUrl = sourceUrl; + } + thisLoader._loadImage(fileNativeUrl, false); + } + } + + class MiniLocalStorage { + constructor() { + } + static __init__() { + MiniLocalStorage.items = MiniLocalStorage; + } + static setItem(key, value) { + ALIMiniAdapter.window.my.setStorageSync({ key: key, value: value }); + } + static getItem(key) { + return ALIMiniAdapter.window.my.getStorageSync({ "key": key }); + } + static setJSON(key, value) { + try { + MiniLocalStorage.setItem(key, JSON.stringify(value)); + } + catch (e) { + console.warn("set localStorage failed", e); + } + } + static getJSON(key) { + return JSON.parse(MiniLocalStorage.getItem(key)); + } + static removeItem(key) { + ALIMiniAdapter.window.my.removeStorageSync(key); + } + static clear() { + ALIMiniAdapter.window.my.clearStorageSync(); + } + static getStorageInfoSync() { + try { + var res = ALIMiniAdapter.window.my.getStorageInfoSync(); + console.log(res.keys); + console.log(res.currentSize); + console.log(res.limitSize); + return res; + } + catch (e) { + } + return null; + } + } + MiniLocalStorage.support = true; + + function ImageDataPolyfill() { + let width, height, data; + if (arguments.length == 3) { + if (arguments[0] instanceof Uint8ClampedArray) { + if (arguments[0].length % 4 !== 0) { + throw new Error("Failed to construct 'ImageData': The input data length is not a multiple of 4."); + } + if (arguments[0].length !== arguments[1] * arguments[2] * 4) { + throw new Error("Failed to construct 'ImageData': The input data length is not equal to (4 * width * height)."); + } + else { + data = arguments[0]; + width = arguments[1]; + height = arguments[2]; + } + } + else { + throw new Error("Failed to construct 'ImageData': parameter 1 is not of type 'Uint8ClampedArray'."); + } + } + else if (arguments.length == 2) { + width = arguments[0]; + height = arguments[1]; + data = new Uint8ClampedArray(arguments[0] * arguments[1] * 4); + } + else if (arguments.length < 2) { + throw new Error("Failed to construct 'ImageData': 2 arguments required, but only " + arguments.length + " present."); + } + let imgdata = Laya.Browser.canvas.getContext("2d").getImageData(0, 0, width, height); + for (let i = 0; i < data.length; i += 4) { + imgdata.data[i] = data[i]; + imgdata.data[i + 1] = data[i + 1]; + imgdata.data[i + 2] = data[i + 2]; + imgdata.data[i + 3] = data[i + 3]; + } + return imgdata; + } + + class ALIMiniAdapter { + static getJson(data) { + return JSON.parse(data); + } + static enable() { + ALIMiniAdapter.init(Laya.Laya.isWXPosMsg, Laya.Laya.isWXOpenDataContext); + } + static init(isPosMsg = false, isSon = false) { + if (ALIMiniAdapter._inited) + return; + ALIMiniAdapter._inited = true; + ALIMiniAdapter.window = window; + if (!ALIMiniAdapter.window.hasOwnProperty("my")) + return; + if (ALIMiniAdapter.window.navigator.userAgent.indexOf('AlipayMiniGame') < 0) + return; + ALIMiniAdapter.isZiYu = isSon; + ALIMiniAdapter.isPosMsgYu = isPosMsg; + ALIMiniAdapter.EnvConfig = {}; + if (!ALIMiniAdapter.isZiYu) { + MiniFileMgr.setNativeFileDir("/layaairGame"); + MiniFileMgr.getCacheList(MiniFileMgr.fileNativeDir, Laya.Handler.create(ALIMiniAdapter, ALIMiniAdapter.onMkdirCallBack)); + } + ALIMiniAdapter.systemInfo = ALIMiniAdapter.window.my.getSystemInfoSync(); + ALIMiniAdapter.window.focus = function () { + }; + Laya.Laya['_getUrlPath'] = function () { + return ""; + }; + ALIMiniAdapter.window.logtime = function (str) { + }; + ALIMiniAdapter.window.alertTimeLog = function (str) { + }; + ALIMiniAdapter.window.resetShareInfo = function () { + }; + ALIMiniAdapter.window.CanvasRenderingContext2D = function () { + }; + ALIMiniAdapter.window.CanvasRenderingContext2D.prototype = ALIMiniAdapter.window.my.createCanvas().getContext('2d').__proto__; + ALIMiniAdapter.window.document.body.appendChild = function () { + }; + ALIMiniAdapter.EnvConfig.pixelRatioInt = 0; + Laya.Browser["_pixelRatio"] = ALIMiniAdapter.pixelRatio(); + ALIMiniAdapter._preCreateElement = Laya.Browser.createElement; + Laya.Browser["createElement"] = ALIMiniAdapter.createElement; + Laya.RunDriver.createShaderCondition = ALIMiniAdapter.createShaderCondition; + Laya.Utils['parseXMLFromString'] = ALIMiniAdapter.parseXMLFromString; + Laya.Input['_createInputElement'] = MiniInput['_createInputElement']; + if (!window.ImageData) { + window.ImageData = ImageDataPolyfill; + } + Laya.Loader.prototype._loadResourceFilter = MiniLoader.prototype._loadResourceFilter; + Laya.Loader.prototype.originComplete = Laya.Loader.prototype.complete; + Laya.Loader.prototype.complete = MiniLoader.prototype.complete; + Laya.Loader.prototype._loadSound = MiniLoader.prototype._loadSound; + Laya.Loader.prototype._loadHttpRequestWhat = MiniLoader.prototype._loadHttpRequestWhat; + Laya.LocalStorage._baseClass = MiniLocalStorage; + MiniLocalStorage.__init__(); + Laya.Config.useRetinalCanvas = true; + ALIMiniAdapter.window.my.onMessage && ALIMiniAdapter.window.my.onMessage(ALIMiniAdapter._onMessage); + } + static _onMessage(data) { + switch (data.type) { + case "changeMatrix": + Laya.Laya.stage.transform.identity(); + Laya.Laya.stage._width = data.w; + Laya.Laya.stage._height = data.h; + Laya.Laya.stage._canvasTransform = new Laya.Matrix(data.a, data.b, data.c, data.d, data.tx, data.ty); + break; + case "display": + Laya.Laya.stage.frameRate = data.rate || Laya.Stage.FRAME_FAST; + break; + case "undisplay": + Laya.Laya.stage.frameRate = Laya.Stage.FRAME_SLEEP; + break; + } + if (data['isLoad'] == "opendatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + else if (data['isLoad'] == "openJsondatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + } + } + else if (data['isLoad'] == "openJsondatacontextPic") { + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + static getUrlEncode(url, type) { + if (type == "arraybuffer") + return ""; + return "utf8"; + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + var fileObj = MiniFileMgr.getFileInfo(fileUrl); + if (!fileObj) + MiniFileMgr.downLoadFile(fileUrl, fileType, callBack, encoding); + else { + callBack != null && callBack.runWith([0]); + } + } + static remove(fileUrl, callBack = null) { + MiniFileMgr.deleteFile("", fileUrl, callBack, "", 0); + } + static removeAll() { + MiniFileMgr.deleteAll(); + } + static hasNativeFile(fileUrl) { + return MiniFileMgr.isLocalNativeFile(fileUrl); + } + static getFileInfo(fileUrl) { + return MiniFileMgr.getFileInfo(fileUrl); + } + static getFileList() { + return MiniFileMgr.filesListObj; + } + static onMkdirCallBack(errorCode, data) { + if (!errorCode) { + MiniFileMgr.filesListObj = JSON.parse(data.data); + MiniFileMgr.fakeObj = JSON.parse(data.data); + } + else { + MiniFileMgr.fakeObj = {}; + MiniFileMgr.filesListObj = {}; + } + let files = MiniFileMgr.fs.readdirSync(MiniFileMgr.fileNativeDir); + if (!files.length) + return; + var tempMd5ListObj = {}; + var fileObj; + for (let key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") { + fileObj = MiniFileMgr.filesListObj[key]; + tempMd5ListObj[fileObj.md5] = fileObj.readyUrl; + } + } + var fileName; + for (let i = 0, sz = files.length; i < sz; i++) { + fileName = files[i]; + if (fileName == MiniFileMgr.fileListName) + continue; + if (!tempMd5ListObj[fileName]) { + let deleteFileUrl = MiniFileMgr.getFileNativePath(fileName); + MiniFileMgr.fs.unlink({ + filePath: deleteFileUrl, + success: function (data) { + console.log("删除无引用的磁盘文件:" + fileName); + } + }); + } + delete tempMd5ListObj[fileName]; + } + for (let key in tempMd5ListObj) { + delete MiniFileMgr.filesListObj[tempMd5ListObj[key]]; + delete MiniFileMgr.fakeObj[tempMd5ListObj[key]]; + console.log("删除错误记录:", tempMd5ListObj[key]); + } + } + static pixelRatio() { + if (!ALIMiniAdapter.EnvConfig.pixelRatioInt) { + try { + ALIMiniAdapter.EnvConfig.pixelRatioInt = ALIMiniAdapter.systemInfo.pixelRatio; + return ALIMiniAdapter.systemInfo.pixelRatio; + } + catch (error) { + } + } + return ALIMiniAdapter.EnvConfig.pixelRatioInt; + } + static createElement(type) { + if (type == "canvas") { + var _source; + if (ALIMiniAdapter.idx == 1) { + if (ALIMiniAdapter.isZiYu) { + _source = ALIMiniAdapter.window.sharedCanvas; + _source.style = {}; + } + else { + _source = ALIMiniAdapter.window.canvas; + } + } + else { + _source = ALIMiniAdapter.window.my.createCanvas(); + } + ALIMiniAdapter.idx++; + return _source; + } + else if (type == "textarea" || type == "input") { + return ALIMiniAdapter.onCreateInput(type); + } + else if (type == "div") { + var node = ALIMiniAdapter._preCreateElement(type); + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + else { + return ALIMiniAdapter._preCreateElement(type); + } + } + static onCreateInput(type) { + var node = ALIMiniAdapter._preCreateElement(type); + node.focus = MiniInput.wxinputFocus; + node.blur = MiniInput.wxinputblur; + node.style = {}; + node.value = 0; + node.parentElement = {}; + node.placeholder = {}; + node.type = {}; + node.setColor = function (value) { + }; + node.setType = function (value) { + }; + node.setFontFace = function (value) { + }; + node.addEventListener = function (value) { + }; + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + static createShaderCondition(conditionScript) { + var func = function () { + return this[conditionScript.replace("this.", "")]; + }; + return func; + } + static sendAtlasToOpenDataContext(url) { + if (!ALIMiniAdapter.isZiYu) { + var atlasJson = Laya.Loader.getRes(Laya.URL.formatURL(url)); + if (atlasJson) { + var textureArr = atlasJson.meta.image.split(","); + if (atlasJson.meta && atlasJson.meta.image) { + var toloadPics = atlasJson.meta.image.split(","); + var split = url.indexOf("/") >= 0 ? "/" : "\\"; + var idx = url.lastIndexOf(split); + var folderPath = idx >= 0 ? url.substr(0, idx + 1) : ""; + for (var i = 0, len = toloadPics.length; i < len; i++) { + toloadPics[i] = folderPath + toloadPics[i]; + } + } + else { + toloadPics = [url.replace(".json", ".png")]; + } + for (i = 0; i < toloadPics.length; i++) { + var tempAtlasPngUrl = toloadPics[i]; + ALIMiniAdapter.postInfoToContext(Laya.Laya.URL.formatURL(url), Laya.Laya.URL.formatURL(tempAtlasPngUrl), atlasJson); + } + } + else { + throw "传递的url没有获取到对应的图集数据信息,请确保图集已经过!"; + } + } + } + static postInfoToContext(url, atlaspngUrl, atlasJson) { + var postData = { "frames": atlasJson.frames, "meta": atlasJson.meta }; + var textureUrl = atlaspngUrl; + var fileObj = MiniFileMgr.getFileInfo(Laya.URL.formatURL(atlaspngUrl)); + if (fileObj) { + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = textureUrl; + } + if (fileNativeUrl) { + ALIMiniAdapter.window.my.postMessage({ url: url, atlasdata: postData, imgNativeUrl: fileNativeUrl, imgReadyUrl: textureUrl, isLoad: "opendatacontext" }); + } + else { + throw "获取图集的磁盘url路径不存在!"; + } + } + static sendSinglePicToOpenDataContext(url) { + var tempTextureUrl = Laya.URL.formatURL(url); + var fileObj = MiniFileMgr.getFileInfo(tempTextureUrl); + if (fileObj) { + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + url = tempTextureUrl; + } + else { + fileNativeUrl = url; + } + if (fileNativeUrl) { + url = Laya.Laya.URL.formatURL(url); + ALIMiniAdapter.window.my.postMessage({ url: url, imgNativeUrl: fileNativeUrl, imgReadyUrl: url, isLoad: "openJsondatacontextPic" }); + } + else { + throw "获取图集的磁盘url路径不存在!"; + } + } + static sendJsonDataToDataContext(url) { + if (!ALIMiniAdapter.isZiYu) { + url = Laya.Laya.URL.formatURL(url); + var atlasJson = Laya.Loader.getRes(url); + if (atlasJson) { + ALIMiniAdapter.window.my.postMessage({ url: url, atlasdata: atlasJson, isLoad: "openJsondatacontext" }); + } + else { + throw "传递的url没有获取到对应的图集数据信息,请确保图集已经过!"; + } + } + } + } + ALIMiniAdapter._inited = false; + ALIMiniAdapter.autoCacheFile = false; + ALIMiniAdapter.minClearSize = (5 * 1024 * 1024); + ALIMiniAdapter.sizeLimit = (50 * 1024 * 1024); + ALIMiniAdapter.nativefiles = ["layaNativeDir"]; + ALIMiniAdapter.subNativeFiles = []; + ALIMiniAdapter.subNativeheads = []; + ALIMiniAdapter.subMaps = []; + ALIMiniAdapter.AutoCacheDownFile = false; + ALIMiniAdapter.parseXMLFromString = function (value) { + var rst; + value = value.replace(/>\s+<'); + try { + rst = (new ALIMiniAdapter.window.Parser.DOMParser()).parseFromString(value, 'text/xml'); + } + catch (error) { + throw "需要引入xml解析库文件"; + } + return rst; + }; + ALIMiniAdapter.idx = 1; + + class MiniAccelerator extends Laya.EventDispatcher { + constructor() { + super(); + } + static __init__() { + try { + var Acc; + Acc = Laya.Accelerator; + if (!Acc) + return; + Acc["prototype"]["on"] = MiniAccelerator["prototype"]["on"]; + Acc["prototype"]["off"] = MiniAccelerator["prototype"]["off"]; + } + catch (e) { + } + } + static startListen(callBack) { + MiniAccelerator._callBack = callBack; + if (MiniAccelerator._isListening) + return; + MiniAccelerator._isListening = true; + try { + ALIMiniAdapter.window.my.onAccelerometerChange(MiniAccelerator.onAccelerometerChange); + } + catch (e) { } + } + static stopListen() { + MiniAccelerator._isListening = false; + try { + ALIMiniAdapter.window.my.stopAccelerometer({}); + } + catch (e) { } + } + static onAccelerometerChange(res) { + var e; + e = {}; + e.acceleration = res; + e.accelerationIncludingGravity = res; + e.rotationRate = {}; + if (MiniAccelerator._callBack != null) { + MiniAccelerator._callBack(e); + } + } + on(type, caller, listener, args = null) { + super.on(type, caller, listener, args); + MiniAccelerator.startListen(this["onDeviceOrientationChange"]); + return this; + } + off(type, caller, listener, onceOnly = false) { + if (!this.hasListener(type)) + MiniAccelerator.stopListen(); + return super.off(type, caller, listener, onceOnly); + } + } + MiniAccelerator._isListening = false; + + class MiniImage { + _loadImage(url) { + var thisLoader = this; + if (ALIMiniAdapter.isZiYu) { + MiniImage.onCreateImage(url, thisLoader, true); + return; + } + var isTransformUrl; + if (!MiniFileMgr.isLocalNativeFile(url)) { + isTransformUrl = true; + url = Laya.URL.formatURL(url); + } + else { + if (url.indexOf("http://usr/") == -1 && (url.indexOf("http://") != -1 || url.indexOf("https://") != -1)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (ALIMiniAdapter.subNativeFiles && ALIMiniAdapter.subNativeheads.length == 0) { + for (var key in ALIMiniAdapter.subNativeFiles) { + var tempArr = ALIMiniAdapter.subNativeFiles[key]; + ALIMiniAdapter.subNativeheads = ALIMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + ALIMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (ALIMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && ALIMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = ALIMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + } + if (!MiniFileMgr.getFileInfo(url)) { + if (url.indexOf('http://usr/') == -1 && (url.indexOf("http://") != -1 || url.indexOf("https://") != -1)) { + if (ALIMiniAdapter.isZiYu) { + MiniImage.onCreateImage(url, thisLoader, true); + } + else { + MiniFileMgr.downOtherFiles(encodeURI(url), new Laya.Handler(MiniImage, MiniImage.onDownImgCallBack, [url, thisLoader]), url); + } + } + else + MiniImage.onCreateImage(url, thisLoader, true); + } + else { + MiniImage.onCreateImage(url, thisLoader, !isTransformUrl); + } + } + static onDownImgCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = "") { + if (!errorCode) + MiniImage.onCreateImage(sourceUrl, thisLoader, false, tempFilePath); + else { + thisLoader.onError(null); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (ALIMiniAdapter.autoCacheFile) { + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + var fileMd5Name = fileObj.md5; + fileNativeUrl = MiniFileMgr.getFileNativePath(fileMd5Name); + } + } + else if (ALIMiniAdapter.isZiYu) { + var tempUrl = Laya.URL.formatURL(sourceUrl); + if (MiniFileMgr.ziyuFileTextureData[tempUrl]) { + fileNativeUrl = MiniFileMgr.ziyuFileTextureData[tempUrl]; + } + else + fileNativeUrl = sourceUrl; + } + else + fileNativeUrl = sourceUrl; + } + else { + if (!isLocal) + fileNativeUrl = tempFilePath; + else + fileNativeUrl = sourceUrl; + } + if (thisLoader._imgCache == null) + thisLoader._imgCache = {}; + var image; + function clear() { + var img = thisLoader._imgCache[fileNativeUrl]; + if (img) { + img.onload = null; + img.onerror = null; + delete thisLoader._imgCache[fileNativeUrl]; + } + } + var onerror = function () { + clear(); + delete MiniFileMgr.fakeObj[sourceUrl]; + delete MiniFileMgr.filesListObj[sourceUrl]; + thisLoader.event(Laya.Event.ERROR, "Load image failed"); + }; + if (thisLoader._type == "nativeimage") { + var onload = function () { + clear(); + thisLoader.onLoaded(image); + }; + image = new Laya.Browser.window.Image(); + image.crossOrigin = ""; + image.onload = onload; + image.onerror = onerror; + image.src = fileNativeUrl; + thisLoader._imgCache[fileNativeUrl] = image; + } + else { + var imageSource = new Laya.Browser.window.Image(); + onload = function () { + image = Laya.HTMLImage.create(imageSource.width, imageSource.height); + image.loadImageSource(imageSource, true); + image._setCreateURL(fileNativeUrl); + clear(); + thisLoader.onLoaded(image); + }; + imageSource.crossOrigin = ""; + imageSource.onload = onload; + imageSource.onerror = onerror; + imageSource.src = fileNativeUrl; + thisLoader._imgCache[fileNativeUrl] = imageSource; + } + } + } + + class MiniLocation { + constructor() { + } + static __init__() { + ALIMiniAdapter.window.navigator.geolocation.getCurrentPosition = MiniLocation.getCurrentPosition; + ALIMiniAdapter.window.navigator.geolocation.watchPosition = MiniLocation.watchPosition; + ALIMiniAdapter.window.navigator.geolocation.clearWatch = MiniLocation.clearWatch; + } + static getCurrentPosition(success = null, error = null, options = null) { + var paramO; + paramO = {}; + paramO.success = getSuccess; + paramO.fail = error; + ALIMiniAdapter.window.my.getLocation(paramO); + function getSuccess(res) { + if (success != null) { + success(res); + } + } + } + static watchPosition(success = null, error = null, options = null) { + MiniLocation._curID++; + var curWatchO; + curWatchO = {}; + curWatchO.success = success; + curWatchO.error = error; + MiniLocation._watchDic[MiniLocation._curID] = curWatchO; + Laya.Laya.systemTimer.loop(1000, null, MiniLocation._myLoop); + return MiniLocation._curID; + } + static clearWatch(id) { + delete MiniLocation._watchDic[id]; + if (!MiniLocation._hasWatch()) { + Laya.Laya.systemTimer.clear(null, MiniLocation._myLoop); + } + } + static _hasWatch() { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key]) + return true; + } + return false; + } + static _myLoop() { + MiniLocation.getCurrentPosition(MiniLocation._mySuccess, MiniLocation._myError); + } + static _mySuccess(res) { + var rst = {}; + rst.coords = res; + rst.timestamp = Laya.Browser.now(); + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].success) { + MiniLocation._watchDic[key].success(rst); + } + } + } + static _myError(res) { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].error) { + MiniLocation._watchDic[key].error(res); + } + } + } + } + MiniLocation._watchDic = {}; + MiniLocation._curID = 0; + + class MiniVideo { + constructor(width = 320, height = 240) { + this.videoend = false; + this.videourl = ""; + this.videoElement = ALIMiniAdapter.window.my.createVideo({ width: width, height: height, autoplay: true }); + } + static __init__() { + } + on(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.onPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.onEnded = this.onEndedFunction.bind(this); + } + this.videoElement.onTimeUpdate = this.onTimeUpdateFunc.bind(this); + } + onTimeUpdateFunc(data) { + this.position = data.position; + this._duration = data.duration; + } + get duration() { + return this._duration; + } + onPlayFunction() { + if (this.videoElement) + this.videoElement.readyState = 200; + console.log("=====视频加载完成========"); + this.onPlayFunc != null && this.onPlayFunc(); + } + onEndedFunction() { + if (!this.videoElement) + return; + this.videoend = true; + console.log("=====视频播放完毕========"); + this.onEndedFunC != null && this.onEndedFunC(); + } + off(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.offPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.offEnded = this.onEndedFunction.bind(this); + } + } + load(url) { + if (!this.videoElement) + return; + this.videoElement.src = url; + } + play() { + if (!this.videoElement) + return; + this.videoend = false; + this.videoElement.play(); + } + pause() { + if (!this.videoElement) + return; + this.videoend = true; + this.videoElement.pause(); + } + get currentTime() { + if (!this.videoElement) + return 0; + return this.videoElement.initialTime; + } + set currentTime(value) { + if (!this.videoElement) + return; + this.videoElement.initialTime = value; + } + get videoWidth() { + if (!this.videoElement) + return 0; + return this.videoElement.width; + } + get videoHeight() { + if (!this.videoElement) + return 0; + return this.videoElement.height; + } + get ended() { + return this.videoend; + } + get loop() { + if (!this.videoElement) + return false; + return this.videoElement.loop; + } + set loop(value) { + if (!this.videoElement) + return; + this.videoElement.loop = value; + } + get playbackRate() { + if (!this.videoElement) + return 0; + return this.videoElement.playbackRate; + } + set playbackRate(value) { + if (!this.videoElement) + return; + this.videoElement.playbackRate = value; + } + get muted() { + if (!this.videoElement) + return false; + return this.videoElement.muted; + } + set muted(value) { + if (!this.videoElement) + return; + this.videoElement.muted = value; + } + get paused() { + if (!this.videoElement) + return false; + return this.videoElement.paused; + } + size(width, height) { + if (!this.videoElement) + return; + this.videoElement.width = width; + this.videoElement.height = height; + } + get x() { + if (!this.videoElement) + return 0; + return this.videoElement.x; + } + set x(value) { + if (!this.videoElement) + return; + this.videoElement.x = value; + } + get y() { + if (!this.videoElement) + return 0; + return this.videoElement.y; + } + set y(value) { + if (!this.videoElement) + return; + this.videoElement.y = value; + } + get currentSrc() { + return this.videoElement.src; + } + destroy() { + if (this.videoElement) + this.videoElement.destroy(); + this.videoElement = null; + this.onEndedFunC = null; + this.onPlayFunc = null; + this.videoend = false; + this.videourl = null; + } + reload() { + if (!this.videoElement) + return; + this.videoElement.src = this.videourl; + } + } + + exports.ALIMiniAdapter = ALIMiniAdapter; + exports.ImageDataPolyfill = ImageDataPolyfill; + exports.MiniAccelerator = MiniAccelerator; + exports.MiniFileMgr = MiniFileMgr; + exports.MiniImage = MiniImage; + exports.MiniInput = MiniInput; + exports.MiniLoader = MiniLoader; + exports.MiniLocalStorage = MiniLocalStorage; + exports.MiniLocation = MiniLocation; + exports.MiniSound = MiniSound; + exports.MiniSoundChannel = MiniSoundChannel; + exports.MiniVideo = MiniVideo; + +} diff --git a/examples/layaair/frontend/bin/libs/laya.ani.js b/examples/layaair/frontend/bin/libs/laya.ani.js new file mode 100644 index 0000000..23e6adf --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.ani.js @@ -0,0 +1,4172 @@ +(function (exports, Laya) { + 'use strict'; + + class IAniLib { + } + IAniLib.Skeleton = null; + IAniLib.AnimationTemplet = null; + IAniLib.Templet = null; + + class AnimationContent { + } + + class AnimationNodeContent { + } + + class KeyFramesContent { + } + + class AnimationParser01 { + static parse(templet, reader) { + var data = reader.__getBuffer(); + var i, j, k, n, l, m, o; + var aniClassName = reader.readUTFString(); + templet._aniClassName = aniClassName; + var strList = reader.readUTFString().split("\n"); + var aniCount = reader.getUint8(); + var publicDataPos = reader.getUint32(); + var publicExtDataPos = reader.getUint32(); + var publicData; + if (publicDataPos > 0) + publicData = data.slice(publicDataPos, publicExtDataPos); + var publicRead = new Laya.Byte(publicData); + if (publicExtDataPos > 0) + templet._publicExtData = data.slice(publicExtDataPos, data.byteLength); + templet._useParent = !!reader.getUint8(); + templet._anis.length = aniCount; + for (i = 0; i < aniCount; i++) { + var ani = templet._anis[i] = new AnimationContent(); + ani.nodes = []; + var name = ani.name = strList[reader.getUint16()]; + templet._aniMap[name] = i; + ani.bone3DMap = {}; + ani.playTime = reader.getFloat32(); + var boneCount = ani.nodes.length = reader.getUint8(); + ani.totalKeyframeDatasLength = 0; + for (j = 0; j < boneCount; j++) { + var node = ani.nodes[j] = new AnimationNodeContent(); + node.childs = []; + var nameIndex = reader.getInt16(); + if (nameIndex >= 0) { + node.name = strList[nameIndex]; + ani.bone3DMap[node.name] = j; + } + node.keyFrame = []; + node.parentIndex = reader.getInt16(); + node.parentIndex == -1 ? node.parent = null : node.parent = ani.nodes[node.parentIndex]; + node.lerpType = reader.getUint8(); + var keyframeParamsOffset = reader.getUint32(); + publicRead.pos = keyframeParamsOffset; + var keyframeDataCount = node.keyframeWidth = publicRead.getUint16(); + ani.totalKeyframeDatasLength += keyframeDataCount; + if (node.lerpType === 0 || node.lerpType === 1) { + node.interpolationMethod = []; + node.interpolationMethod.length = keyframeDataCount; + for (k = 0; k < keyframeDataCount; k++) + node.interpolationMethod[k] = IAniLib.AnimationTemplet.interpolation[publicRead.getUint8()]; + } + if (node.parent != null) + node.parent.childs.push(node); + var privateDataLen = reader.getUint16(); + if (privateDataLen > 0) { + node.extenData = data.slice(reader.pos, reader.pos + privateDataLen); + reader.pos += privateDataLen; + } + var keyframeCount = reader.getUint16(); + node.keyFrame.length = keyframeCount; + var startTime = 0; + var keyFrame; + for (k = 0, n = keyframeCount; k < n; k++) { + keyFrame = node.keyFrame[k] = new KeyFramesContent(); + keyFrame.duration = reader.getFloat32(); + keyFrame.startTime = startTime; + if (node.lerpType === 2) { + keyFrame.interpolationData = []; + var interDataLength = reader.getUint8(); + var lerpType; + lerpType = reader.getFloat32(); + switch (lerpType) { + case 254: + keyFrame.interpolationData.length = keyframeDataCount; + for (o = 0; o < keyframeDataCount; o++) + keyFrame.interpolationData[o] = 0; + break; + case 255: + keyFrame.interpolationData.length = keyframeDataCount; + for (o = 0; o < keyframeDataCount; o++) + keyFrame.interpolationData[o] = 5; + break; + default: + keyFrame.interpolationData.push(lerpType); + for (m = 1; m < interDataLength; m++) { + keyFrame.interpolationData.push(reader.getFloat32()); + } + } + } + keyFrame.data = new Float32Array(keyframeDataCount); + keyFrame.dData = new Float32Array(keyframeDataCount); + keyFrame.nextData = new Float32Array(keyframeDataCount); + for (l = 0; l < keyframeDataCount; l++) { + keyFrame.data[l] = reader.getFloat32(); + if (keyFrame.data[l] > -0.00000001 && keyFrame.data[l] < 0.00000001) + keyFrame.data[l] = 0; + } + startTime += keyFrame.duration; + } + keyFrame.startTime = ani.playTime; + node.playTime = ani.playTime; + templet._calculateKeyFrame(node, keyframeCount, keyframeDataCount); + } + } + } + } + + class AnimationParser02 { + static READ_DATA() { + AnimationParser02._DATA.offset = AnimationParser02._reader.getUint32(); + AnimationParser02._DATA.size = AnimationParser02._reader.getUint32(); + } + static READ_BLOCK() { + var count = AnimationParser02._BLOCK.count = AnimationParser02._reader.getUint16(); + var blockStarts = AnimationParser02._BLOCK.blockStarts = []; + var blockLengths = AnimationParser02._BLOCK.blockLengths = []; + for (var i = 0; i < count; i++) { + blockStarts.push(AnimationParser02._reader.getUint32()); + blockLengths.push(AnimationParser02._reader.getUint32()); + } + } + static READ_STRINGS() { + var offset = AnimationParser02._reader.getUint32(); + var count = AnimationParser02._reader.getUint16(); + var prePos = AnimationParser02._reader.pos; + AnimationParser02._reader.pos = offset + AnimationParser02._DATA.offset; + for (var i = 0; i < count; i++) + AnimationParser02._strings[i] = AnimationParser02._reader.readUTFString(); + AnimationParser02._reader.pos = prePos; + } + static parse(templet, reader) { + AnimationParser02._templet = templet; + AnimationParser02._reader = reader; + var arrayBuffer = reader.__getBuffer(); + AnimationParser02.READ_DATA(); + AnimationParser02.READ_BLOCK(); + AnimationParser02.READ_STRINGS(); + for (var i = 0, n = AnimationParser02._BLOCK.count; i < n; i++) { + var index = reader.getUint16(); + var blockName = AnimationParser02._strings[index]; + var fn = AnimationParser02["READ_" + blockName]; + if (fn == null) + throw new Error("model file err,no this function:" + index + " " + blockName); + else + fn.call(null); + } + } + static READ_ANIMATIONS() { + var reader = AnimationParser02._reader; + var arrayBuffer = reader.__getBuffer(); + var i, j, k, n; + var keyframeWidth = reader.getUint16(); + var interpolationMethod = []; + interpolationMethod.length = keyframeWidth; + for (i = 0; i < keyframeWidth; i++) + interpolationMethod[i] = IAniLib.AnimationTemplet.interpolation[reader.getByte()]; + var aniCount = reader.getUint8(); + AnimationParser02._templet._anis.length = aniCount; + for (i = 0; i < aniCount; i++) { + var ani = AnimationParser02._templet._anis[i] = new AnimationContent(); + ani.nodes = []; + var aniName = ani.name = AnimationParser02._strings[reader.getUint16()]; + AnimationParser02._templet._aniMap[aniName] = i; + ani.bone3DMap = {}; + ani.playTime = reader.getFloat32(); + var boneCount = ani.nodes.length = reader.getInt16(); + ani.totalKeyframeDatasLength = 0; + for (j = 0; j < boneCount; j++) { + var node = ani.nodes[j] = new AnimationNodeContent(); + node.keyframeWidth = keyframeWidth; + node.childs = []; + var nameIndex = reader.getUint16(); + if (nameIndex >= 0) { + node.name = AnimationParser02._strings[nameIndex]; + ani.bone3DMap[node.name] = j; + } + node.keyFrame = []; + node.parentIndex = reader.getInt16(); + node.parentIndex == -1 ? node.parent = null : node.parent = ani.nodes[node.parentIndex]; + ani.totalKeyframeDatasLength += keyframeWidth; + node.interpolationMethod = interpolationMethod; + if (node.parent != null) + node.parent.childs.push(node); + var keyframeCount = reader.getUint16(); + node.keyFrame.length = keyframeCount; + var keyFrame = null, lastKeyFrame = null; + for (k = 0, n = keyframeCount; k < n; k++) { + keyFrame = node.keyFrame[k] = new KeyFramesContent(); + keyFrame.startTime = reader.getFloat32(); + (lastKeyFrame) && (lastKeyFrame.duration = keyFrame.startTime - lastKeyFrame.startTime); + keyFrame.dData = new Float32Array(keyframeWidth); + keyFrame.nextData = new Float32Array(keyframeWidth); + var offset = AnimationParser02._DATA.offset; + var keyframeDataOffset = reader.getUint32(); + var keyframeDataLength = keyframeWidth * 4; + var keyframeArrayBuffer = arrayBuffer.slice(offset + keyframeDataOffset, offset + keyframeDataOffset + keyframeDataLength); + keyFrame.data = new Float32Array(keyframeArrayBuffer); + lastKeyFrame = keyFrame; + } + keyFrame.duration = 0; + node.playTime = ani.playTime; + AnimationParser02._templet._calculateKeyFrame(node, keyframeCount, keyframeWidth); + } + } + } + } + AnimationParser02._strings = []; + AnimationParser02._BLOCK = { count: 0 }; + AnimationParser02._DATA = { offset: 0, size: 0 }; + + class AnimationState { + constructor() { + } + } + AnimationState.stopped = 0; + AnimationState.paused = 1; + AnimationState.playing = 2; + + class AnimationPlayer extends Laya.EventDispatcher { + constructor() { + super(); + this.isCache = true; + this.playbackRate = 1.0; + this._destroyed = false; + this._currentAnimationClipIndex = -1; + this._currentKeyframeIndex = -1; + this._currentTime = 0.0; + this._overallDuration = Number.MAX_VALUE; + this._stopWhenCircleFinish = false; + this._elapsedPlaybackTime = 0; + this._startUpdateLoopCount = -1; + this._cachePlayRate = 1.0; + this.cacheFrameRate = 60; + this.returnToZeroStopped = false; + } + get templet() { + return this._templet; + } + set templet(value) { + if (!(this.state === AnimationState.stopped)) + this.stop(true); + if (this._templet !== value) { + this._templet = value; + this._computeFullKeyframeIndices(); + } + } + get playStart() { + return this._playStart; + } + get playEnd() { + return this._playEnd; + } + get playDuration() { + return this._playDuration; + } + get overallDuration() { + return this._overallDuration; + } + get currentAnimationClipIndex() { + return this._currentAnimationClipIndex; + } + get currentKeyframeIndex() { + return this._currentKeyframeIndex; + } + get currentPlayTime() { + return this._currentTime + this._playStart; + } + get currentFrameTime() { + return this._currentFrameTime; + } + get cachePlayRate() { + return this._cachePlayRate; + } + set cachePlayRate(value) { + if (this._cachePlayRate !== value) { + this._cachePlayRate = value; + if (this._templet) + this._computeFullKeyframeIndices(); + } + } + get cacheFrameRate() { + return this._cacheFrameRate; + } + set cacheFrameRate(value) { + if (this._cacheFrameRate !== value) { + this._cacheFrameRate = value; + this._cacheFrameRateInterval = 1000.0 / this._cacheFrameRate; + if (this._templet) + this._computeFullKeyframeIndices(); + } + } + set currentTime(value) { + if (this._currentAnimationClipIndex === -1 || !this._templet) + return; + if (value < this._playStart || value > this._playEnd) + throw new Error("AnimationPlayer:value must large than playStartTime,small than playEndTime."); + this._startUpdateLoopCount = Laya.Stat.loopCount; + var cacheFrameInterval = this._cacheFrameRateInterval * this._cachePlayRate; + this._currentTime = value; + this._currentKeyframeIndex = Math.floor(this.currentPlayTime / cacheFrameInterval); + this._currentFrameTime = this._currentKeyframeIndex * cacheFrameInterval; + } + get paused() { + return this._paused; + } + set paused(value) { + this._paused = value; + value && this.event(Laya.Event.PAUSED); + } + get cacheFrameRateInterval() { + return this._cacheFrameRateInterval; + } + get state() { + if (this._currentAnimationClipIndex === -1) + return AnimationState.stopped; + if (this._paused) + return AnimationState.paused; + return AnimationState.playing; + } + get destroyed() { + return this._destroyed; + } + _onTempletLoadedComputeFullKeyframeIndices(cachePlayRate, cacheFrameRate, templet) { + if (this._templet === templet && this._cachePlayRate === cachePlayRate && this._cacheFrameRate === cacheFrameRate) + this._computeFullKeyframeIndices(); + } + _computeFullKeyframeIndices() { + return; + } + _onAnimationTempletLoaded() { + (this.destroyed) || (this._calculatePlayDuration()); + } + _calculatePlayDuration() { + if (this.state !== AnimationState.stopped) { + var oriDuration = this._templet.getAniDuration(this._currentAnimationClipIndex); + (this._playEnd === 0) && (this._playEnd = oriDuration); + if (this._playEnd > oriDuration) + this._playEnd = oriDuration; + this._playDuration = this._playEnd - this._playStart; + } + } + _setPlayParams(time, cacheFrameInterval) { + this._currentTime = time; + this._currentKeyframeIndex = Math.floor((this.currentPlayTime) / cacheFrameInterval + 0.01); + this._currentFrameTime = this._currentKeyframeIndex * cacheFrameInterval; + } + _setPlayParamsWhenStop(currentAniClipPlayDuration, cacheFrameInterval, playEnd = -1) { + this._currentTime = currentAniClipPlayDuration; + var endTime = playEnd > 0 ? playEnd : currentAniClipPlayDuration; + this._currentKeyframeIndex = Math.floor(endTime / cacheFrameInterval + 0.01); + this._currentKeyframeIndex = Math.floor(currentAniClipPlayDuration / cacheFrameInterval + 0.01); + this._currentFrameTime = this._currentKeyframeIndex * cacheFrameInterval; + this._currentAnimationClipIndex = -1; + } + _update(elapsedTime) { + if (this._currentAnimationClipIndex === -1 || this._paused || !this._templet) + return; + var cacheFrameInterval = this._cacheFrameRateInterval * this._cachePlayRate; + var time = 0; + (this._startUpdateLoopCount !== Laya.Stat.loopCount) && (time = elapsedTime * this.playbackRate, this._elapsedPlaybackTime += time); + var currentAniClipPlayDuration = this.playDuration; + time += this._currentTime; + if ((this._overallDuration !== 0 && this._elapsedPlaybackTime >= this._overallDuration) || (this._overallDuration === 0 && this._elapsedPlaybackTime >= currentAniClipPlayDuration + || (this._overallDuration === 0 && time >= this.playEnd))) { + this._setPlayParamsWhenStop(currentAniClipPlayDuration, cacheFrameInterval, this.playEnd); + this.event(Laya.Event.STOPPED); + return; + } + if (currentAniClipPlayDuration > 0) { + if (time >= currentAniClipPlayDuration) { + if (this._stopWhenCircleFinish) { + this._setPlayParamsWhenStop(currentAniClipPlayDuration, cacheFrameInterval); + this._stopWhenCircleFinish = false; + this.event(Laya.Event.STOPPED); + return; + } + else { + time = time % currentAniClipPlayDuration; + this._setPlayParams(time, cacheFrameInterval); + this.event(Laya.Event.COMPLETE); + return; + } + } + else { + this._setPlayParams(time, cacheFrameInterval); + } + } + else { + if (this._stopWhenCircleFinish) { + this._setPlayParamsWhenStop(currentAniClipPlayDuration, cacheFrameInterval); + this._stopWhenCircleFinish = false; + this.event(Laya.Event.STOPPED); + return; + } + this._currentTime = this._currentFrameTime = this._currentKeyframeIndex = 0; + this.event(Laya.Event.COMPLETE); + } + } + _destroy() { + this.offAll(); + this._templet = null; + this._destroyed = true; + } + play(index = 0, playbackRate = 1.0, overallDuration = 2147483647, playStart = 0, playEnd = 0) { + if (!this._templet) + throw new Error("AnimationPlayer:templet must not be null,maybe you need to set url."); + if (overallDuration < 0 || playStart < 0 || playEnd < 0) + throw new Error("AnimationPlayer:overallDuration,playStart and playEnd must large than zero."); + if ((playEnd !== 0) && (playStart > playEnd)) + throw new Error("AnimationPlayer:start must less than end."); + this._currentTime = 0; + this._currentFrameTime = 0; + this._elapsedPlaybackTime = 0; + this.playbackRate = playbackRate; + this._overallDuration = overallDuration; + this._playStart = playStart; + this._playEnd = playEnd; + this._paused = false; + this._currentAnimationClipIndex = index; + this._currentKeyframeIndex = 0; + this._startUpdateLoopCount = Laya.Stat.loopCount; + this.event(Laya.Event.PLAYED); + this._calculatePlayDuration(); + this._update(0); + } + playByFrame(index = 0, playbackRate = 1.0, overallDuration = 2147483647, playStartFrame = 0, playEndFrame = 0, fpsIn3DBuilder = 30) { + var interval = 1000.0 / fpsIn3DBuilder; + this.play(index, playbackRate, overallDuration, playStartFrame * interval, playEndFrame * interval); + } + stop(immediate = true) { + if (immediate) { + this._currentTime = this._currentFrameTime = this._currentKeyframeIndex = 0; + this._currentAnimationClipIndex = -1; + this.event(Laya.Event.STOPPED); + } + else { + this._stopWhenCircleFinish = true; + } + } + destroy() { + } + } + + class BezierLerp { + constructor() { + } + static getBezierRate(t, px0, py0, px1, py1) { + var key = BezierLerp._getBezierParamKey(px0, py0, px1, py1); + var vKey = key * 100 + t; + if (BezierLerp._bezierResultCache[vKey]) + return BezierLerp._bezierResultCache[vKey]; + var points = BezierLerp._getBezierPoints(px0, py0, px1, py1, key); + var i, len; + len = points.length; + for (i = 0; i < len; i += 2) { + if (t <= points[i]) { + BezierLerp._bezierResultCache[vKey] = points[i + 1]; + return points[i + 1]; + } + } + BezierLerp._bezierResultCache[vKey] = 1; + return 1; + } + static _getBezierParamKey(px0, py0, px1, py1) { + return (((px0 * 100 + py0) * 100 + px1) * 100 + py1) * 100; + } + static _getBezierPoints(px0, py0, px1, py1, key) { + if (BezierLerp._bezierPointsCache[key]) + return BezierLerp._bezierPointsCache[key]; + var controlPoints; + controlPoints = [0, 0, px0, py0, px1, py1, 1, 1]; + var bz; + bz = new Laya.Bezier(); + var points; + points = bz.getBezierPoints(controlPoints, 100, 3); + BezierLerp._bezierPointsCache[key] = points; + return points; + } + } + BezierLerp._bezierResultCache = {}; + BezierLerp._bezierPointsCache = {}; + + class AnimationTemplet extends Laya.Resource { + constructor() { + super(); + this._anis = []; + this._aniMap = {}; + this.unfixedLastAniIndex = -1; + this._fullFrames = null; + this._boneCurKeyFrm = []; + } + static _LinearInterpolation_0(bone, index, out, outOfs, data, dt, dData, duration, nextData, interData = null) { + out[outOfs] = data[index] + dt * dData[index]; + return 1; + } + static _QuaternionInterpolation_1(bone, index, out, outOfs, data, dt, dData, duration, nextData, interData = null) { + var amount = duration === 0 ? 0 : dt / duration; + Laya.MathUtil.slerpQuaternionArray(data, index, nextData, index, amount, out, outOfs); + return 4; + } + static _AngleInterpolation_2(bone, index, out, outOfs, data, dt, dData, duration, nextData, interData = null) { + return 0; + } + static _RadiansInterpolation_3(bone, index, out, outOfs, data, dt, dData, duration, nextData, interData = null) { + return 0; + } + static _Matrix4x4Interpolation_4(bone, index, out, outOfs, data, dt, dData, duration, nextData, interData = null) { + for (var i = 0; i < 16; i++, index++) + out[outOfs + i] = data[index] + dt * dData[index]; + return 16; + } + static _NoInterpolation_5(bone, index, out, outOfs, data, dt, dData, duration, nextData, interData = null) { + out[outOfs] = data[index]; + return 1; + } + static _BezierInterpolation_6(bone, index, out, outOfs, data, dt, dData, duration, nextData, interData = null, offset = 0) { + out[outOfs] = data[index] + (nextData[index] - data[index]) * BezierLerp.getBezierRate(dt / duration, interData[offset], interData[offset + 1], interData[offset + 2], interData[offset + 3]); + return 5; + } + static _BezierInterpolation_7(bone, index, out, outOfs, data, dt, dData, duration, nextData, interData = null, offset = 0) { + out[outOfs] = interData[offset + 4] + interData[offset + 5] * BezierLerp.getBezierRate((dt * 0.001 + interData[offset + 6]) / interData[offset + 7], interData[offset], interData[offset + 1], interData[offset + 2], interData[offset + 3]); + return 9; + } + parse(data) { + var reader = new Laya.Byte(data); + this._aniVersion = reader.readUTFString(); + AnimationParser01.parse(this, reader); + } + _calculateKeyFrame(node, keyframeCount, keyframeDataCount) { + var keyFrames = node.keyFrame; + keyFrames[keyframeCount] = keyFrames[0]; + for (var i = 0; i < keyframeCount; i++) { + var keyFrame = keyFrames[i]; + for (var j = 0; j < keyframeDataCount; j++) { + keyFrame.dData[j] = (keyFrame.duration === 0) ? 0 : (keyFrames[i + 1].data[j] - keyFrame.data[j]) / keyFrame.duration; + keyFrame.nextData[j] = keyFrames[i + 1].data[j]; + } + } + keyFrames.length--; + } + _onAsynLoaded(data, propertyParams = null) { + var reader = new Laya.Byte(data); + this._aniVersion = reader.readUTFString(); + switch (this._aniVersion) { + case "LAYAANIMATION:02": + AnimationParser02.parse(this, reader); + break; + default: + AnimationParser01.parse(this, reader); + } + } + getAnimationCount() { + return this._anis.length; + } + getAnimation(aniIndex) { + return this._anis[aniIndex]; + } + getAniDuration(aniIndex) { + return this._anis[aniIndex].playTime; + } + getNodes(aniIndex) { + return this._anis[aniIndex].nodes; + } + getNodeIndexWithName(aniIndex, name) { + return this._anis[aniIndex].bone3DMap[name]; + } + getNodeCount(aniIndex) { + return this._anis[aniIndex].nodes.length; + } + getTotalkeyframesLength(aniIndex) { + return this._anis[aniIndex].totalKeyframeDatasLength; + } + getPublicExtData() { + return this._publicExtData; + } + getAnimationDataWithCache(key, cacheDatas, aniIndex, frameIndex) { + var aniDatas = cacheDatas[aniIndex]; + if (!aniDatas) { + return null; + } + else { + var keyDatas = aniDatas[key]; + if (!keyDatas) + return null; + else { + return keyDatas[frameIndex]; + } + } + } + setAnimationDataWithCache(key, cacheDatas, aniIndex, frameIndex, data) { + var aniDatas = (cacheDatas[aniIndex]) || (cacheDatas[aniIndex] = {}); + var aniDatasCache = (aniDatas[key]) || (aniDatas[key] = []); + aniDatasCache[frameIndex] = data; + } + getNodeKeyFrame(nodeframes, nodeid, tm) { + var cid = this._boneCurKeyFrm[nodeid]; + var frmNum = nodeframes.length; + if (cid == void 0 || cid >= frmNum) { + cid = this._boneCurKeyFrm[nodeid] = 0; + } + var kinfo = nodeframes[cid]; + var curFrmTm = kinfo.startTime; + var dt = tm - curFrmTm; + if (dt == 0 || (dt > 0 && kinfo.duration > dt)) { + return cid; + } + var i = 0; + if (dt > 0) { + tm = tm + 0.01; + for (i = cid + 1; i < frmNum; i++) { + kinfo = nodeframes[i]; + if (kinfo.startTime <= tm && kinfo.startTime + kinfo.duration > tm) { + this._boneCurKeyFrm[nodeid] = i; + return i; + } + } + return frmNum - 1; + } + else { + for (i = 0; i < cid; i++) { + kinfo = nodeframes[i]; + if (kinfo.startTime <= tm && kinfo.startTime + kinfo.duration > tm) { + this._boneCurKeyFrm[nodeid] = i; + return i; + } + } + return cid; + } + } + getOriginalData(aniIndex, originalData, nodesFrameIndices, frameIndex, playCurTime) { + var oneAni = this._anis[aniIndex]; + var nodes = oneAni.nodes; + var curKFrm = this._boneCurKeyFrm; + if (curKFrm.length < nodes.length) { + curKFrm.length = nodes.length; + } + var j = 0; + for (var i = 0, n = nodes.length, outOfs = 0; i < n; i++) { + var node = nodes[i]; + var key; + var kfrm = node.keyFrame; + key = kfrm[this.getNodeKeyFrame(kfrm, i, playCurTime)]; + node.dataOffset = outOfs; + var dt = playCurTime - key.startTime; + var lerpType = node.lerpType; + if (lerpType) { + switch (lerpType) { + case 0: + case 1: + for (j = 0; j < node.keyframeWidth;) + j += node.interpolationMethod[j](node, j, originalData, outOfs + j, key.data, dt, key.dData, key.duration, key.nextData); + break; + case 2: + var interpolationData = key.interpolationData; + var interDataLen = interpolationData.length; + var dataIndex = 0; + for (j = 0; j < interDataLen;) { + var type = interpolationData[j]; + switch (type) { + case 6: + j += AnimationTemplet.interpolation[type](node, dataIndex, originalData, outOfs + dataIndex, key.data, dt, key.dData, key.duration, key.nextData, interpolationData, j + 1); + break; + case 7: + j += AnimationTemplet.interpolation[type](node, dataIndex, originalData, outOfs + dataIndex, key.data, dt, key.dData, key.duration, key.nextData, interpolationData, j + 1); + break; + default: + j += AnimationTemplet.interpolation[type](node, dataIndex, originalData, outOfs + dataIndex, key.data, dt, key.dData, key.duration, key.nextData); + } + dataIndex++; + } + break; + } + } + else { + for (j = 0; j < node.keyframeWidth;) + j += node.interpolationMethod[j](node, j, originalData, outOfs + j, key.data, dt, key.dData, key.duration, key.nextData); + } + outOfs += node.keyframeWidth; + } + } + getNodesCurrentFrameIndex(aniIndex, playCurTime) { + var ani = this._anis[aniIndex]; + var nodes = ani.nodes; + if (aniIndex !== this.unfixedLastAniIndex) { + this.unfixedCurrentFrameIndexes = new Uint32Array(nodes.length); + this.unfixedCurrentTimes = new Float32Array(nodes.length); + this.unfixedLastAniIndex = aniIndex; + } + for (var i = 0, n = nodes.length; i < n; i++) { + var node = nodes[i]; + if (playCurTime < this.unfixedCurrentTimes[i]) + this.unfixedCurrentFrameIndexes[i] = 0; + this.unfixedCurrentTimes[i] = playCurTime; + while ((this.unfixedCurrentFrameIndexes[i] < node.keyFrame.length)) { + if (node.keyFrame[this.unfixedCurrentFrameIndexes[i]].startTime > this.unfixedCurrentTimes[i]) + break; + this.unfixedCurrentFrameIndexes[i]++; + } + this.unfixedCurrentFrameIndexes[i]--; + } + return this.unfixedCurrentFrameIndexes; + } + getOriginalDataUnfixedRate(aniIndex, originalData, playCurTime) { + var oneAni = this._anis[aniIndex]; + var nodes = oneAni.nodes; + if (aniIndex !== this.unfixedLastAniIndex) { + this.unfixedCurrentFrameIndexes = new Uint32Array(nodes.length); + this.unfixedCurrentTimes = new Float32Array(nodes.length); + this.unfixedKeyframes = []; + this.unfixedLastAniIndex = aniIndex; + } + var j = 0; + for (var i = 0, n = nodes.length, outOfs = 0; i < n; i++) { + var node = nodes[i]; + if (playCurTime < this.unfixedCurrentTimes[i]) + this.unfixedCurrentFrameIndexes[i] = 0; + this.unfixedCurrentTimes[i] = playCurTime; + while (this.unfixedCurrentFrameIndexes[i] < node.keyFrame.length) { + if (node.keyFrame[this.unfixedCurrentFrameIndexes[i]].startTime > this.unfixedCurrentTimes[i]) + break; + this.unfixedKeyframes[i] = node.keyFrame[this.unfixedCurrentFrameIndexes[i]]; + this.unfixedCurrentFrameIndexes[i]++; + } + var key = this.unfixedKeyframes[i]; + node.dataOffset = outOfs; + var dt = playCurTime - key.startTime; + var lerpType = node.lerpType; + if (lerpType) { + switch (node.lerpType) { + case 0: + case 1: + for (j = 0; j < node.keyframeWidth;) + j += node.interpolationMethod[j](node, j, originalData, outOfs + j, key.data, dt, key.dData, key.duration, key.nextData); + break; + case 2: + var interpolationData = key.interpolationData; + var interDataLen = interpolationData.length; + var dataIndex = 0; + for (j = 0; j < interDataLen;) { + var type = interpolationData[j]; + switch (type) { + case 6: + j += AnimationTemplet.interpolation[type](node, dataIndex, originalData, outOfs + dataIndex, key.data, dt, key.dData, key.duration, key.nextData, interpolationData, j + 1); + break; + case 7: + j += AnimationTemplet.interpolation[type](node, dataIndex, originalData, outOfs + dataIndex, key.data, dt, key.dData, key.duration, key.nextData, interpolationData, j + 1); + break; + default: + j += AnimationTemplet.interpolation[type](node, dataIndex, originalData, outOfs + dataIndex, key.data, dt, key.dData, key.duration, key.nextData); + } + dataIndex++; + } + break; + } + } + else { + for (j = 0; j < node.keyframeWidth;) + j += node.interpolationMethod[j](node, j, originalData, outOfs + j, key.data, dt, key.dData, key.duration, key.nextData); + } + outOfs += node.keyframeWidth; + } + } + } + AnimationTemplet.interpolation = [AnimationTemplet._LinearInterpolation_0, AnimationTemplet._QuaternionInterpolation_1, AnimationTemplet._AngleInterpolation_2, AnimationTemplet._RadiansInterpolation_3, AnimationTemplet._Matrix4x4Interpolation_4, AnimationTemplet._NoInterpolation_5, AnimationTemplet._BezierInterpolation_6, AnimationTemplet._BezierInterpolation_7]; + IAniLib.AnimationTemplet = AnimationTemplet; + + class GraphicsAni extends Laya.Graphics { + drawSkin(skinA, alpha) { + this.drawTriangles(skinA.texture, 0, 0, skinA.vertices, skinA.uvs, skinA.indexes, skinA.transform || Laya.Matrix.EMPTY, alpha); + } + static create() { + var rs = GraphicsAni._caches.pop(); + return rs || new GraphicsAni(); + } + static recycle(graphics) { + graphics.clear(); + GraphicsAni._caches.push(graphics); + } + } + GraphicsAni._caches = []; + + class Transform { + constructor() { + this.skX = 0; + this.skY = 0; + this.scX = 1; + this.scY = 1; + this.x = 0; + this.y = 0; + this.skewX = 0; + this.skewY = 0; + } + initData(data) { + if (data.x != undefined) { + this.x = data.x; + } + if (data.y != undefined) { + this.y = data.y; + } + if (data.skX != undefined) { + this.skX = data.skX; + } + if (data.skY != undefined) { + this.skY = data.skY; + } + if (data.scX != undefined) { + this.scX = data.scX; + } + if (data.scY != undefined) { + this.scY = data.scY; + } + } + getMatrix() { + var tMatrix; + if (this.mMatrix) { + tMatrix = this.mMatrix; + } + else { + tMatrix = this.mMatrix = new Laya.Matrix(); + } + tMatrix.identity(); + tMatrix.scale(this.scX, this.scY); + if (this.skewX || this.skewY) { + this.skew(tMatrix, this.skewX * Math.PI / 180, this.skewY * Math.PI / 180); + } + tMatrix.rotate(this.skX * Math.PI / 180); + tMatrix.translate(this.x, this.y); + return tMatrix; + } + skew(m, x, y) { + var sinX = Math.sin(y); + var cosX = Math.cos(y); + var sinY = Math.sin(x); + var cosY = Math.cos(x); + m.setTo(m.a * cosY - m.b * sinX, m.a * sinY + m.b * cosX, m.c * cosY - m.d * sinX, m.c * sinY + m.d * cosX, m.tx * cosY - m.ty * sinX, m.tx * sinY + m.ty * cosX); + return m; + } + } + + class Bone { + constructor() { + this.length = 10; + this.resultTransform = new Transform(); + this.resultMatrix = new Laya.Matrix(); + this.inheritScale = true; + this.inheritRotation = true; + this.d = -1; + this._children = []; + } + setTempMatrix(matrix) { + this._tempMatrix = matrix; + var i = 0, n = 0; + var tBone; + for (i = 0, n = this._children.length; i < n; i++) { + tBone = this._children[i]; + tBone.setTempMatrix(this._tempMatrix); + } + } + update(pMatrix = null) { + this.rotation = this.transform.skX; + var tResultMatrix; + if (pMatrix) { + tResultMatrix = this.resultTransform.getMatrix(); + Laya.Matrix.mul(tResultMatrix, pMatrix, this.resultMatrix); + this.resultRotation = this.rotation; + } + else { + this.resultRotation = this.rotation + this.parentBone.resultRotation; + if (this.parentBone) { + if (this.inheritRotation && this.inheritScale) { + tResultMatrix = this.resultTransform.getMatrix(); + Laya.Matrix.mul(tResultMatrix, this.parentBone.resultMatrix, this.resultMatrix); + } + else { + var parent = this.parentBone; + var tAngle; + var cos; + var sin; + var tParentMatrix = this.parentBone.resultMatrix; + tResultMatrix = this.resultTransform.getMatrix(); + var worldX = tParentMatrix.a * tResultMatrix.tx + tParentMatrix.c * tResultMatrix.ty + tParentMatrix.tx; + var worldY = tParentMatrix.b * tResultMatrix.tx + tParentMatrix.d * tResultMatrix.ty + tParentMatrix.ty; + var tTestMatrix = new Laya.Matrix(); + if (this.inheritRotation) { + tAngle = Math.atan2(parent.resultMatrix.b, parent.resultMatrix.a); + cos = Math.cos(tAngle), sin = Math.sin(tAngle); + tTestMatrix.setTo(cos, sin, -sin, cos, 0, 0); + Laya.Matrix.mul(this._tempMatrix, tTestMatrix, Laya.Matrix.TEMP); + Laya.Matrix.TEMP.copyTo(tTestMatrix); + tResultMatrix = this.resultTransform.getMatrix(); + Laya.Matrix.mul(tResultMatrix, tTestMatrix, this.resultMatrix); + if (this.resultTransform.scX * this.resultTransform.scY < 0) { + this.resultMatrix.rotate(Math.PI * 0.5); + } + this.resultMatrix.tx = worldX; + this.resultMatrix.ty = worldY; + } + else if (this.inheritScale) { + tResultMatrix = this.resultTransform.getMatrix(); + Laya.Matrix.TEMP.identity(); + Laya.Matrix.TEMP.d = this.d; + Laya.Matrix.mul(tResultMatrix, Laya.Matrix.TEMP, this.resultMatrix); + this.resultMatrix.tx = worldX; + this.resultMatrix.ty = worldY; + } + else { + tResultMatrix = this.resultTransform.getMatrix(); + Laya.Matrix.TEMP.identity(); + Laya.Matrix.TEMP.d = this.d; + Laya.Matrix.mul(tResultMatrix, Laya.Matrix.TEMP, this.resultMatrix); + this.resultMatrix.tx = worldX; + this.resultMatrix.ty = worldY; + } + } + } + else { + tResultMatrix = this.resultTransform.getMatrix(); + tResultMatrix.copyTo(this.resultMatrix); + } + } + var i = 0, n = 0; + var tBone; + for (i = 0, n = this._children.length; i < n; i++) { + tBone = this._children[i]; + tBone.update(); + } + } + updateChild() { + var i = 0, n = 0; + var tBone; + for (i = 0, n = this._children.length; i < n; i++) { + tBone = this._children[i]; + tBone.update(); + } + } + setRotation(rd) { + if (this._sprite) { + this._sprite.rotation = rd * 180 / Math.PI; + } + } + updateDraw(x, y) { + if (!Bone.ShowBones || Bone.ShowBones[this.name]) { + if (this._sprite) { + this._sprite.x = x + this.resultMatrix.tx; + this._sprite.y = y + this.resultMatrix.ty; + } + else { + this._sprite = new Laya.Sprite(); + this._sprite.graphics.drawCircle(0, 0, 5, "#ff0000"); + this._sprite.graphics.drawLine(0, 0, this.length, 0, "#00ff00"); + this._sprite.graphics.fillText(this.name, 0, 0, "20px Arial", "#00ff00", "center"); + Laya.ILaya.stage.addChild(this._sprite); + this._sprite.x = x + this.resultMatrix.tx; + this._sprite.y = y + this.resultMatrix.ty; + } + } + var i = 0, n = 0; + var tBone; + for (i = 0, n = this._children.length; i < n; i++) { + tBone = this._children[i]; + tBone.updateDraw(x, y); + } + } + addChild(bone) { + this._children.push(bone); + bone.parentBone = this; + } + findBone(boneName) { + if (this.name == boneName) { + return this; + } + else { + var i, n; + var tBone; + var tResult; + for (i = 0, n = this._children.length; i < n; i++) { + tBone = this._children[i]; + tResult = tBone.findBone(boneName); + if (tResult) { + return tResult; + } + } + } + return null; + } + localToWorld(local) { + var localX = local[0]; + var localY = local[1]; + local[0] = localX * this.resultMatrix.a + localY * this.resultMatrix.c + this.resultMatrix.tx; + local[1] = localX * this.resultMatrix.b + localY * this.resultMatrix.d + this.resultMatrix.ty; + } + } + Bone.ShowBones = {}; + + class UVTools { + constructor() { + } + static getRelativeUV(bigUV, smallUV, rst = null) { + var startX = bigUV[0]; + var width = bigUV[2] - bigUV[0]; + var startY = bigUV[1]; + var height = bigUV[5] - bigUV[1]; + if (!rst) + rst = []; + rst.length = smallUV.length; + var i, len; + len = rst.length; + var dWidth = 1 / width; + var dHeight = 1 / height; + for (i = 0; i < len; i += 2) { + rst[i] = (smallUV[i] - startX) * dWidth; + rst[i + 1] = (smallUV[i + 1] - startY) * dHeight; + } + return rst; + } + static getAbsoluteUV(bigUV, smallUV, rst = null) { + if (bigUV[0] == 0 && bigUV[1] == 0 && bigUV[4] == 1 && bigUV[5] == 1) { + if (rst) { + Laya.Utils.copyArray(rst, smallUV); + return rst; + } + else { + return smallUV; + } + } + var startX = bigUV[0]; + var width = bigUV[2] - bigUV[0]; + var startY = bigUV[1]; + var height = bigUV[5] - bigUV[1]; + if (!rst) + rst = []; + rst.length = smallUV.length; + var i, len; + len = rst.length; + for (i = 0; i < len; i += 2) { + rst[i] = smallUV[i] * width + startX; + rst[i + 1] = smallUV[i + 1] * height + startY; + } + return rst; + } + } + + class MeshData { + constructor() { + this.uvs = new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]); + this.vertices = new Float32Array([0, 0, 100, 0, 100, 100, 0, 100]); + this.indexes = new Uint16Array([0, 1, 3, 3, 1, 2]); + this.useUvTransform = false; + this.canvasPadding = 1; + } + getBounds() { + return Laya.Rectangle._getWrapRec(this.vertices); + } + } + + class SkinMeshForGraphic extends MeshData { + constructor() { + super(); + } + init2(texture, ps, verticles, uvs) { + if (this.transform) { + this.transform = null; + } + var _ps = ps || [0, 1, 3, 3, 1, 2]; + this.texture = texture; + this.indexes = new Uint16Array(_ps); + this.vertices = new Float32Array(verticles); + this.uvs = new Float32Array(uvs); + } + } + + class BoneSlot { + constructor() { + this.srcDisplayIndex = -1; + this.type = "src"; + this.displayIndex = -1; + this.originalIndex = -1; + this._replaceDic = {}; + } + showSlotData(slotData, freshIndex = true) { + this.currSlotData = slotData; + if (freshIndex) + this.displayIndex = this.srcDisplayIndex; + this.currDisplayData = null; + this.currTexture = null; + } + showDisplayByName(name) { + if (this.currSlotData) { + this.showDisplayByIndex(this.currSlotData.getDisplayByName(name)); + } + } + replaceDisplayByName(tarName, newName) { + if (!this.currSlotData) + return; + var preIndex; + preIndex = this.currSlotData.getDisplayByName(tarName); + var newIndex; + newIndex = this.currSlotData.getDisplayByName(newName); + this.replaceDisplayByIndex(preIndex, newIndex); + } + replaceDisplayByIndex(tarIndex, newIndex) { + if (!this.currSlotData) + return; + this._replaceDic[tarIndex] = newIndex; + if (this.originalIndex == tarIndex) { + this.showDisplayByIndex(tarIndex); + } + } + showDisplayByIndex(index) { + this.originalIndex = index; + if (this._replaceDic[index] != null) + index = this._replaceDic[index]; + if (this.currSlotData && index > -1 && index < this.currSlotData.displayArr.length) { + this.displayIndex = index; + this.currDisplayData = this.currSlotData.displayArr[index]; + if (this.currDisplayData) { + var tName = this.currDisplayData.name; + this.currTexture = this.templet.getTexture(tName); + if (this.currTexture && this.currDisplayData.type == 0 && this.currDisplayData.uvs) { + this.currTexture = this.currDisplayData.createTexture(this.currTexture); + } + } + } + else { + this.displayIndex = -1; + this.currDisplayData = null; + this.currTexture = null; + } + } + replaceSkin(_texture) { + this._diyTexture = _texture; + if (this._curDiyUV) + this._curDiyUV.length = 0; + if (this.currDisplayData && this._diyTexture == this.currDisplayData.texture) { + this._diyTexture = null; + } + } + setParentMatrix(parentMatrix) { + this._parentMatrix = parentMatrix; + } + static createSkinMesh() { + return new SkinMeshForGraphic(); + } + static isSameArr(arrA, arrB) { + if (arrA.length != arrB.length) + return false; + var i, len; + len = arrA.length; + for (i = 0; i < len; i++) { + if (arrA[i] != arrB[i]) + return false; + } + return true; + } + getSaveVerticle(tArr) { + if (BoneSlot.useSameMatrixAndVerticle && this._preGraphicVerticle && BoneSlot.isSameArr(tArr, this._preGraphicVerticle)) { + tArr = this._preGraphicVerticle; + } + else { + tArr = Laya.ILaya.Utils.copyArray([], tArr); + this._preGraphicVerticle = tArr; + } + return tArr; + } + static isSameMatrix(mtA, mtB) { + return mtA.a == mtB.a && mtA.b == mtB.b && mtA.c == mtB.c && mtA.d == mtB.d && Math.abs(mtA.tx - mtB.tx) < 0.00001 && Math.abs(mtA.ty - mtB.ty) < 0.00001; + } + getSaveMatrix(tResultMatrix) { + if (BoneSlot.useSameMatrixAndVerticle && this._preGraphicMatrix && BoneSlot.isSameMatrix(tResultMatrix, this._preGraphicMatrix)) { + tResultMatrix = this._preGraphicMatrix; + } + else { + var newMatrix = tResultMatrix.clone(); + tResultMatrix = newMatrix; + this._preGraphicMatrix = tResultMatrix; + } + return tResultMatrix; + } + draw(graphics, boneMatrixArray, noUseSave = false, alpha = 1) { + if ((this._diyTexture == null && this.currTexture == null) || this.currDisplayData == null) { + if (!(this.currDisplayData && this.currDisplayData.type == 3)) { + return; + } + } + var tTexture = this.currTexture; + if (this._diyTexture) + tTexture = this._diyTexture; + var tSkinSprite; + switch (this.currDisplayData.type) { + case 0: + if (graphics) { + var tCurrentMatrix = this.getDisplayMatrix(); + if (this._parentMatrix) { + var tRotateKey = false; + if (tCurrentMatrix) { + Laya.Matrix.mul(tCurrentMatrix, this._parentMatrix, Laya.Matrix.TEMP); + var tResultMatrix; + if (noUseSave) { + if (this._resultMatrix == null) + this._resultMatrix = new Laya.Matrix(); + tResultMatrix = this._resultMatrix; + } + else { + tResultMatrix = BoneSlot._tempResultMatrix; + } + if (this._diyTexture && this.currDisplayData.uvs) { + var tTestMatrix = BoneSlot._tempMatrix; + tTestMatrix.identity(); + if (this.currDisplayData.uvs[1] > this.currDisplayData.uvs[5]) { + tTestMatrix.d = -1; + } + if (this.currDisplayData.uvs[0] > this.currDisplayData.uvs[4] + && this.currDisplayData.uvs[1] > this.currDisplayData.uvs[5]) { + tRotateKey = true; + tTestMatrix.rotate(-Math.PI / 2); + } + Laya.Matrix.mul(tTestMatrix, Laya.Matrix.TEMP, tResultMatrix); + } + else { + Laya.Matrix.TEMP.copyTo(tResultMatrix); + } + if (!noUseSave) { + tResultMatrix = this.getSaveMatrix(tResultMatrix); + } + tResultMatrix._checkTransform(); + if (tRotateKey) { + graphics.drawTexture(tTexture, -this.currDisplayData.height / 2, -this.currDisplayData.width / 2, this.currDisplayData.height, this.currDisplayData.width, tResultMatrix, alpha); + } + else { + graphics.drawTexture(tTexture, -this.currDisplayData.width / 2, -this.currDisplayData.height / 2, this.currDisplayData.width, this.currDisplayData.height, tResultMatrix, alpha); + } + } + } + } + break; + case 1: + if (noUseSave) { + if (this._skinSprite == null) { + this._skinSprite = BoneSlot.createSkinMesh(); + } + tSkinSprite = this._skinSprite; + } + else { + tSkinSprite = BoneSlot.createSkinMesh(); + } + if (tSkinSprite == null) { + return; + } + var tIBArray; + if (this.currDisplayData.bones == null) { + var tVertices = this.currDisplayData.weights; + if (this.deformData) { + tVertices = this.deformData; + } + var tUVs; + if (this._diyTexture) { + if (!this._curDiyUV) { + this._curDiyUV = []; + } + if (this._curDiyUV.length == 0) { + this._curDiyUV = UVTools.getRelativeUV(this.currTexture.uv, this.currDisplayData.uvs, this._curDiyUV); + this._curDiyUV = UVTools.getAbsoluteUV(this._diyTexture.uv, this._curDiyUV, this._curDiyUV); + } + tUVs = this._curDiyUV; + } + else { + tUVs = this.currDisplayData.uvs; + } + this._mVerticleArr = tVertices; + var tTriangleNum = this.currDisplayData.triangles.length / 3; + tIBArray = this.currDisplayData.triangles; + if (this.deformData) { + if (!noUseSave) { + this._mVerticleArr = this.getSaveVerticle(this._mVerticleArr); + } + } + tSkinSprite.init2(tTexture, tIBArray, this._mVerticleArr, tUVs); + var tCurrentMatrix2 = this.getDisplayMatrix(); + if (this._parentMatrix) { + if (tCurrentMatrix2) { + Laya.Matrix.mul(tCurrentMatrix2, this._parentMatrix, Laya.Matrix.TEMP); + var tResultMatrix2; + if (noUseSave) { + if (this._resultMatrix == null) + this._resultMatrix = new Laya.Matrix(); + tResultMatrix2 = this._resultMatrix; + } + else { + tResultMatrix2 = BoneSlot._tempResultMatrix; + } + Laya.Matrix.TEMP.copyTo(tResultMatrix2); + if (!noUseSave) { + tResultMatrix2 = this.getSaveMatrix(tResultMatrix2); + } + tSkinSprite.transform = tResultMatrix2; + } + } + } + else { + this.skinMesh(boneMatrixArray, tSkinSprite); + } + graphics.drawSkin(tSkinSprite, alpha); + break; + case 2: + if (noUseSave) { + if (this._skinSprite == null) { + this._skinSprite = BoneSlot.createSkinMesh(); + } + tSkinSprite = this._skinSprite; + } + else { + tSkinSprite = BoneSlot.createSkinMesh(); + } + if (tSkinSprite == null) { + return; + } + this.skinMesh(boneMatrixArray, tSkinSprite); + graphics.drawSkin(tSkinSprite, alpha); + break; + } + } + skinMesh(boneMatrixArray, skinSprite) { + var tTexture = this.currTexture; + var tBones = this.currDisplayData.bones; + var tUvs; + if (this._diyTexture) { + tTexture = this._diyTexture; + if (!this._curDiyUV) { + this._curDiyUV = []; + } + if (this._curDiyUV.length == 0) { + this._curDiyUV = UVTools.getRelativeUV(this.currTexture.uv, this.currDisplayData.uvs, this._curDiyUV); + this._curDiyUV = UVTools.getAbsoluteUV(this._diyTexture.uv, this._curDiyUV, this._curDiyUV); + } + tUvs = this._curDiyUV; + } + else { + tUvs = this.currDisplayData.uvs; + } + var tWeights = this.currDisplayData.weights; + var tTriangles = this.currDisplayData.triangles; + var tIBArray; + var tRx = 0; + var tRy = 0; + var nn = 0; + var tMatrix; + var tX; + var tY; + var tB = 0; + var tWeight = 0; + var tVertices; + var i = 0, n = 0; + BoneSlot._tempVerticleArr.length = 0; + tVertices = BoneSlot._tempVerticleArr; + if (this.deformData && this.deformData.length > 0) { + var f = 0; + for (i = 0, n = tBones.length; i < n;) { + nn = tBones[i++] + i; + tRx = 0, tRy = 0; + for (; i < nn; i++) { + tMatrix = boneMatrixArray[tBones[i]]; + tX = tWeights[tB] + this.deformData[f++]; + tY = tWeights[tB + 1] + this.deformData[f++]; + tWeight = tWeights[tB + 2]; + tRx += (tX * tMatrix.a + tY * tMatrix.c + tMatrix.tx) * tWeight; + tRy += (tX * tMatrix.b + tY * tMatrix.d + tMatrix.ty) * tWeight; + tB += 3; + } + tVertices.push(tRx, tRy); + } + } + else { + for (i = 0, n = tBones.length; i < n;) { + nn = tBones[i++] + i; + tRx = 0, tRy = 0; + for (; i < nn; i++) { + tMatrix = boneMatrixArray[tBones[i]]; + tX = tWeights[tB]; + tY = tWeights[tB + 1]; + tWeight = tWeights[tB + 2]; + tRx += (tX * tMatrix.a + tY * tMatrix.c + tMatrix.tx) * tWeight; + tRy += (tX * tMatrix.b + tY * tMatrix.d + tMatrix.ty) * tWeight; + tB += 3; + } + tVertices.push(tRx, tRy); + } + } + this._mVerticleArr = tVertices; + tIBArray = tTriangles; + this._mVerticleArr = this.getSaveVerticle(this._mVerticleArr); + skinSprite.init2(tTexture, tIBArray, this._mVerticleArr, tUvs); + } + drawBonePoint(graphics) { + if (graphics && this._parentMatrix) { + graphics.drawCircle(this._parentMatrix.tx, this._parentMatrix.ty, 5, "#ff0000"); + } + } + getDisplayMatrix() { + if (this.currDisplayData) { + return this.currDisplayData.transform.getMatrix(); + } + return null; + } + getMatrix() { + return this._resultMatrix; + } + copy() { + var tBoneSlot = new BoneSlot(); + tBoneSlot.type = "copy"; + tBoneSlot.name = this.name; + tBoneSlot.attachmentName = this.attachmentName; + tBoneSlot.srcDisplayIndex = this.srcDisplayIndex; + tBoneSlot.parent = this.parent; + tBoneSlot.displayIndex = this.displayIndex; + tBoneSlot.templet = this.templet; + tBoneSlot.currSlotData = this.currSlotData; + tBoneSlot.currTexture = this.currTexture; + tBoneSlot.currDisplayData = this.currDisplayData; + return tBoneSlot; + } + } + BoneSlot._tempMatrix = new Laya.Matrix(); + BoneSlot._tempResultMatrix = new Laya.Matrix(); + BoneSlot.useSameMatrixAndVerticle = true; + BoneSlot._tempVerticleArr = []; + + class DeformAniData { + constructor() { + this.deformSlotDataList = []; + } + } + + class DeformSlotData { + constructor() { + this.deformSlotDisplayList = []; + } + } + + class DeformSlotDisplayData { + constructor() { + this.slotIndex = -1; + this.timeList = []; + this.vectices = []; + this.tweenKeyList = []; + this.frameIndex = 0; + } + binarySearch1(values, target) { + var low = 0; + var high = values.length - 2; + if (high == 0) + return 1; + var current = high >>> 1; + while (true) { + if (values[Math.floor(current + 1)] <= target) + low = current + 1; + else + high = current; + if (low == high) + return low + 1; + current = (low + high) >>> 1; + } + return 0; + } + apply(time, boneSlot, alpha = 1) { + time += 0.05; + if (this.timeList.length <= 0) { + return; + } + var i = 0; + var tTime = this.timeList[0]; + if (time < tTime) { + return; + } + var tVertexCount = this.vectices[0].length; + var tVertices = []; + var tFrameIndex = this.binarySearch1(this.timeList, time); + this.frameIndex = tFrameIndex; + if (time >= this.timeList[this.timeList.length - 1]) { + var lastVertices = this.vectices[this.vectices.length - 1]; + if (alpha < 1) { + for (i = 0; i < tVertexCount; i++) { + tVertices[i] += (lastVertices[i] - tVertices[i]) * alpha; + } + } + else { + for (i = 0; i < tVertexCount; i++) { + tVertices[i] = lastVertices[i]; + } + } + this.deformData = tVertices; + return; + } + var tPrevVertices = this.vectices[this.frameIndex - 1]; + var tNextVertices = this.vectices[this.frameIndex]; + var tPreFrameTime = this.timeList[this.frameIndex - 1]; + var tFrameTime = this.timeList[this.frameIndex]; + if (this.tweenKeyList[tFrameIndex - 1]) { + alpha = (time - tPreFrameTime) / (tFrameTime - tPreFrameTime); + } + else { + alpha = 0; + } + var tPrev; + for (i = 0; i < tVertexCount; i++) { + tPrev = tPrevVertices[i]; + tVertices[i] = tPrev + (tNextVertices[i] - tPrev) * alpha; + } + this.deformData = tVertices; + } + } + + class DrawOrderData { + constructor() { + this.drawOrder = []; + } + } + + class EventData { + constructor() { + } + } + + class IkConstraint { + constructor(data, bones) { + this.isSpine = true; + this.isDebug = false; + this._targetBone = bones[data.targetBoneIndex]; + this.isSpine = data.isSpine; + if (this._bones == null) + this._bones = []; + this._bones.length = 0; + for (var i = 0, n = data.boneIndexs.length; i < n; i++) { + this._bones.push(bones[data.boneIndexs[i]]); + } + this.name = data.name; + this.mix = data.mix; + this.bendDirection = data.bendDirection; + } + apply() { + switch (this._bones.length) { + case 1: + this._applyIk1(this._bones[0], this._targetBone.resultMatrix.tx, this._targetBone.resultMatrix.ty, this.mix); + break; + case 2: + if (this.isSpine) { + this._applyIk2(this._bones[0], this._bones[1], this._targetBone.resultMatrix.tx, this._targetBone.resultMatrix.ty, this.bendDirection, this.mix); + } + else { + this._applyIk3(this._bones[0], this._bones[1], this._targetBone.resultMatrix.tx, this._targetBone.resultMatrix.ty, this.bendDirection, this.mix); + } + break; + } + } + _applyIk1(bone, targetX, targetY, alpha) { + var pp = bone.parentBone; + var id = 1 / (pp.resultMatrix.a * pp.resultMatrix.d - pp.resultMatrix.b * pp.resultMatrix.c); + var x = targetX - pp.resultMatrix.tx; + var y = targetY - pp.resultMatrix.ty; + var tx = (x * pp.resultMatrix.d - y * pp.resultMatrix.c) * id - bone.transform.x; + var ty = (y * pp.resultMatrix.a - x * pp.resultMatrix.b) * id - bone.transform.y; + var rotationIK = Math.atan2(ty, tx) * IkConstraint.radDeg - 0 - bone.transform.skX; + if (bone.transform.scX < 0) + rotationIK += 180; + if (rotationIK > 180) + rotationIK -= 360; + else if (rotationIK < -180) + rotationIK += 360; + bone.transform.skX = bone.transform.skY = bone.transform.skX + rotationIK * alpha; + bone.update(); + } + updatePos(x, y) { + if (this._sp) { + this._sp.pos(x, y); + } + } + _applyIk2(parent, child, targetX, targetY, bendDir, alpha) { + if (alpha == 0) { + return; + } + var px = parent.resultTransform.x, py = parent.resultTransform.y; + var psx = parent.transform.scX, psy = parent.transform.scY; + var csx = child.transform.scX; + var os1, os2, s2; + if (psx < 0) { + psx = -psx; + os1 = 180; + s2 = -1; + } + else { + os1 = 0; + s2 = 1; + } + if (psy < 0) { + psy = -psy; + s2 = -s2; + } + if (csx < 0) { + csx = -csx; + os2 = 180; + } + else { + os2 = 0; + } + var cx = child.resultTransform.x, cy, cwx, cwy; + var a = parent.resultMatrix.a, b = parent.resultMatrix.c; + var c = parent.resultMatrix.b, d = parent.resultMatrix.d; + var u = Math.abs(psx - psy) <= 0.0001; + if (!u) { + cy = 0; + cwx = a * cx + parent.resultMatrix.tx; + cwy = c * cx + parent.resultMatrix.ty; + } + else { + cy = child.resultTransform.y; + cwx = a * cx + b * cy + parent.resultMatrix.tx; + cwy = c * cx + d * cy + parent.resultMatrix.ty; + } + if (this.isDebug) { + if (!this._sp) { + this._sp = new Laya.Sprite(); + Laya.ILaya.stage.addChild(this._sp); + } + this._sp.graphics.clear(); + this._sp.graphics.drawCircle(targetX, targetY, 15, "#ffff00"); + this._sp.graphics.drawCircle(cwx, cwy, 15, "#ff00ff"); + } + parent.setRotation(Math.atan2(cwy - parent.resultMatrix.ty, cwx - parent.resultMatrix.tx)); + var pp = parent.parentBone; + a = pp.resultMatrix.a; + b = pp.resultMatrix.c; + c = pp.resultMatrix.b; + d = pp.resultMatrix.d; + var id = 1 / (a * d - b * c); + var x = targetX - pp.resultMatrix.tx, y = targetY - pp.resultMatrix.ty; + var tx = (x * d - y * b) * id - px; + var ty = (y * a - x * c) * id - py; + x = cwx - pp.resultMatrix.tx; + y = cwy - pp.resultMatrix.ty; + var dx = (x * d - y * b) * id - px; + var dy = (y * a - x * c) * id - py; + var l1 = Math.sqrt(dx * dx + dy * dy); + var l2 = child.length * csx; + var a1, a2; + if (u) { + l2 *= psx; + var cos = (tx * tx + ty * ty - l1 * l1 - l2 * l2) / (2 * l1 * l2); + if (cos < -1) + cos = -1; + else if (cos > 1) + cos = 1; + a2 = Math.acos(cos) * bendDir; + a = l1 + l2 * cos; + b = l2 * Math.sin(a2); + a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b); + } + else { + a = psx * l2; + b = psy * l2; + var aa = a * a, bb = b * b, dd = tx * tx + ty * ty, ta = Math.atan2(ty, tx); + c = bb * l1 * l1 + aa * dd - aa * bb; + var c1 = -2 * bb * l1, c2 = bb - aa; + d = c1 * c1 - 4 * c2 * c; + if (d > 0) { + var q = Math.sqrt(d); + if (c1 < 0) + q = -q; + q = -(c1 + q) / 2; + var r0 = q / c2, r1 = c / q; + var r = Math.abs(r0) < Math.abs(r1) ? r0 : r1; + if (r * r <= dd) { + y = Math.sqrt(dd - r * r) * bendDir; + a1 = ta - Math.atan2(y, r); + a2 = Math.atan2(y / psy, (r - l1) / psx); + } + } + var minAngle = 0, minDist = Number.MAX_VALUE, minX = 0, minY = 0; + var maxAngle = 0, maxDist = 0, maxX = 0, maxY = 0; + x = l1 + a; + d = x * x; + if (d > maxDist) { + maxAngle = 0; + maxDist = d; + maxX = x; + } + x = l1 - a; + d = x * x; + if (d < minDist) { + minAngle = Math.PI; + minDist = d; + minX = x; + } + var angle = Math.acos(-a * l1 / (aa - bb)); + x = a * Math.cos(angle) + l1; + y = b * Math.sin(angle); + d = x * x + y * y; + if (d < minDist) { + minAngle = angle; + minDist = d; + minX = x; + minY = y; + } + if (d > maxDist) { + maxAngle = angle; + maxDist = d; + maxX = x; + maxY = y; + } + if (dd <= (minDist + maxDist) / 2) { + a1 = ta - Math.atan2(minY * bendDir, minX); + a2 = minAngle * bendDir; + } + else { + a1 = ta - Math.atan2(maxY * bendDir, maxX); + a2 = maxAngle * bendDir; + } + } + var os = Math.atan2(cy, cx) * s2; + var rotation = parent.resultTransform.skX; + a1 = (a1 - os) * IkConstraint.radDeg + os1 - rotation; + if (a1 > 180) + a1 -= 360; + else if (a1 < -180) + a1 += 360; + parent.resultTransform.x = px; + parent.resultTransform.y = py; + parent.resultTransform.skX = parent.resultTransform.skY = rotation + a1 * alpha; + rotation = child.resultTransform.skX; + rotation = rotation % 360; + a2 = ((a2 + os) * IkConstraint.radDeg - 0) * s2 + os2 - rotation; + if (a2 > 180) + a2 -= 360; + else if (a2 < -180) + a2 += 360; + child.resultTransform.x = cx; + child.resultTransform.y = cy; + child.resultTransform.skX = child.resultTransform.skY = child.resultTransform.skY + a2 * alpha; + parent.update(); + } + _applyIk3(parent, child, targetX, targetY, bendDir, alpha) { + if (alpha == 0) { + return; + } + var cwx, cwy; + const x = child.resultMatrix.a * child.length; + const y = child.resultMatrix.b * child.length; + const lLL = x * x + y * y; + const lL = Math.sqrt(lLL); + var parentX = parent.resultMatrix.tx; + var parentY = parent.resultMatrix.ty; + var childX = child.resultMatrix.tx; + var childY = child.resultMatrix.ty; + var dX = childX - parentX; + var dY = childY - parentY; + const lPP = dX * dX + dY * dY; + const lP = Math.sqrt(lPP); + dX = targetX - parent.resultMatrix.tx; + dY = targetY - parent.resultMatrix.ty; + const lTT = dX * dX + dY * dY; + const lT = Math.sqrt(lTT); + if (lL + lP <= lT || lT + lL <= lP || lT + lP <= lL) { + var rate; + if (lL + lP <= lT) { + rate = 1; + } + else { + rate = -1; + } + childX = parentX + rate * (targetX - parentX) * lP / lT; + childY = parentY + rate * (targetY - parentY) * lP / lT; + } + else { + const h = (lPP - lLL + lTT) / (2 * lTT); + const r = Math.sqrt(lPP - h * h * lTT) / lT; + const hX = parentX + (dX * h); + const hY = parentY + (dY * h); + const rX = -dY * r; + const rY = dX * r; + if (bendDir > 0) { + childX = hX - rX; + childY = hY - rY; + } + else { + childX = hX + rX; + childY = hY + rY; + } + } + cwx = childX; + cwy = childY; + if (this.isDebug) { + if (!this._sp) { + this._sp = new Laya.Sprite(); + Laya.ILaya.stage.addChild(this._sp); + } + this._sp.graphics.clear(); + this._sp.graphics.drawCircle(parentX, parentY, 15, "#ff00ff"); + this._sp.graphics.drawCircle(targetX, targetY, 15, "#ffff00"); + this._sp.graphics.drawCircle(cwx, cwy, 15, "#ff00ff"); + } + var pRotation; + pRotation = Math.atan2(cwy - parent.resultMatrix.ty, cwx - parent.resultMatrix.tx); + parent.setRotation(pRotation); + var pTarMatrix; + pTarMatrix = IkConstraint._tempMatrix; + pTarMatrix.identity(); + pTarMatrix.rotate(pRotation); + pTarMatrix.scale(parent.resultMatrix.getScaleX(), parent.resultMatrix.getScaleY()); + pTarMatrix.translate(parent.resultMatrix.tx, parent.resultMatrix.ty); + pTarMatrix.copyTo(parent.resultMatrix); + parent.updateChild(); + var childRotation; + childRotation = Math.atan2(targetY - cwy, targetX - cwx); + child.setRotation(childRotation); + var childTarMatrix; + childTarMatrix = IkConstraint._tempMatrix; + childTarMatrix.identity(); + childTarMatrix.rotate(childRotation); + childTarMatrix.scale(child.resultMatrix.getScaleX(), child.resultMatrix.getScaleY()); + childTarMatrix.translate(cwx, cwy); + pTarMatrix.copyTo(child.resultMatrix); + child.updateChild(); + } + } + IkConstraint.radDeg = 180 / Math.PI; + IkConstraint.degRad = Math.PI / 180; + IkConstraint._tempMatrix = new Laya.Matrix(); + + class IkConstraintData { + constructor() { + this.boneNames = []; + this.bendDirection = 1; + this.mix = 1; + this.isSpine = true; + this.targetBoneIndex = -1; + this.boneIndexs = []; + } + } + + class PathConstraint { + constructor(data, bones) { + this._debugKey = false; + this._segments = []; + this._curves = []; + this.data = data; + this.position = data.position; + this.spacing = data.spacing; + this.rotateMix = data.rotateMix; + this.translateMix = data.translateMix; + this.bones = []; + var tBoneIds = this.data.bones; + for (var i = 0, n = tBoneIds.length; i < n; i++) { + this.bones.push(bones[tBoneIds[i]]); + } + } + apply(boneList, graphics) { + if (!this.target) + return; + var tTranslateMix = this.translateMix; + var tRotateMix = this.translateMix; + var tRotate = tRotateMix > 0; + var tSpacingMode = this.data.spacingMode; + var tLengthSpacing = tSpacingMode == "length"; + var tRotateMode = this.data.rotateMode; + var tTangents = tRotateMode == "tangent"; + var tScale = tRotateMode == "chainScale"; + var lengths = []; + var boneCount = this.bones.length; + var spacesCount = tTangents ? boneCount : boneCount + 1; + var spaces = []; + this._spaces = spaces; + spaces[0] = this.position; + var spacing = this.spacing; + if (tScale || tLengthSpacing) { + for (var i = 0, n = spacesCount - 1; i < n;) { + var bone = this.bones[i]; + var length = bone.length; + var x = length * bone.resultMatrix.a; + var y = length * bone.resultMatrix.b; + length = Math.sqrt(x * x + y * y); + if (tScale) + lengths[i] = length; + spaces[++i] = tLengthSpacing ? Math.max(0, length + spacing) : spacing; + } + } + else { + for (i = 1; i < spacesCount; i++) { + spaces[i] = spacing; + } + } + var positions = this.computeWorldPositions(this.target, boneList, graphics, spacesCount, tTangents, this.data.positionMode == "percent", tSpacingMode == "percent"); + if (this._debugKey) { + for (i = 0; i < positions.length; i++) { + graphics.drawCircle(positions[i++], positions[i++], 5, "#00ff00"); + } + var tLinePos = []; + for (i = 0; i < positions.length; i++) { + tLinePos.push(positions[i++], positions[i++]); + } + graphics.drawLines(0, 0, tLinePos, "#ff0000"); + } + var boneX = positions[0]; + var boneY = positions[1]; + var offsetRotation = this.data.offsetRotation; + var tip = tRotateMode == "chain" && offsetRotation == 0; + var p; + for (i = 0, p = 3; i < boneCount; i++, p += 3) { + bone = this.bones[i]; + bone.resultMatrix.tx += (boneX - bone.resultMatrix.tx) * tTranslateMix; + bone.resultMatrix.ty += (boneY - bone.resultMatrix.ty) * tTranslateMix; + x = positions[p]; + y = positions[p + 1]; + var dx = x - boneX, dy = y - boneY; + if (tScale) { + length = lengths[i]; + if (length != 0) { + var s = (Math.sqrt(dx * dx + dy * dy) / length - 1) * tRotateMix + 1; + bone.resultMatrix.a *= s; + bone.resultMatrix.c *= s; + } + } + boneX = x; + boneY = y; + if (tRotate) { + var a = bone.resultMatrix.a; + var b = bone.resultMatrix.c; + var c = bone.resultMatrix.b; + var d = bone.resultMatrix.d; + var r; + var cos; + var sin; + if (tTangents) { + r = positions[p - 1]; + } + else if (spaces[i + 1] == 0) { + r = positions[p + 2]; + } + else { + r = Math.atan2(dy, dx); + } + r -= Math.atan2(c, a) - offsetRotation / 180 * Math.PI; + if (tip) { + cos = Math.cos(r); + sin = Math.sin(r); + length = bone.length; + boneX += (length * (cos * a - sin * c) - dx) * tRotateMix; + boneY += (length * (sin * a + cos * c) - dy) * tRotateMix; + } + if (r > Math.PI) { + r -= (Math.PI * 2); + } + else if (r < -Math.PI) { + r += (Math.PI * 2); + } + r *= tRotateMix; + cos = Math.cos(r); + sin = Math.sin(r); + bone.resultMatrix.a = cos * a - sin * c; + bone.resultMatrix.c = cos * b - sin * d; + bone.resultMatrix.b = sin * a + cos * c; + bone.resultMatrix.d = sin * b + cos * d; + } + } + } + computeWorldVertices2(boneSlot, boneList, start, count, worldVertices, offset) { + var tBones = boneSlot.currDisplayData.bones; + var tWeights = boneSlot.currDisplayData.weights; + var tTriangles = boneSlot.currDisplayData.triangles; + var tMatrix; + var i = 0; + var v = 0; + var skip = 0; + var n = 0; + var w = 0; + var b = 0; + var wx = 0; + var wy = 0; + var vx = 0; + var vy = 0; + var bone; + var len; + if (tBones == null) { + if (!tTriangles) + tTriangles = tWeights; + if (boneSlot.deformData) + tTriangles = boneSlot.deformData; + var parentName; + parentName = boneSlot.parent; + if (boneList) { + len = boneList.length; + for (i = 0; i < len; i++) { + if (boneList[i].name == parentName) { + bone = boneList[i]; + break; + } + } + } + var tBoneMt; + if (bone) { + tBoneMt = bone.resultMatrix; + } + if (!tBoneMt) + tBoneMt = PathConstraint._tempMt; + var x = tBoneMt.tx; + var y = tBoneMt.ty; + var a = tBoneMt.a, bb = tBoneMt.b, c = tBoneMt.c, d = tBoneMt.d; + if (bone) + d *= bone.d; + for (v = start, w = offset; w < count; v += 2, w += 2) { + vx = tTriangles[v], vy = tTriangles[v + 1]; + worldVertices[w] = vx * a + vy * bb + x; + worldVertices[w + 1] = -(vx * c + vy * d + y); + } + return; + } + for (i = 0; i < start; i += 2) { + n = tBones[v]; + v += n + 1; + skip += n; + } + var skeletonBones = boneList; + for (w = offset, b = skip * 3; w < count; w += 2) { + wx = 0, wy = 0; + n = tBones[v++]; + n += v; + for (; v < n; v++, b += 3) { + tMatrix = skeletonBones[tBones[v]].resultMatrix; + vx = tWeights[b]; + vy = tWeights[b + 1]; + var weight = tWeights[b + 2]; + wx += (vx * tMatrix.a + vy * tMatrix.c + tMatrix.tx) * weight; + wy += (vx * tMatrix.b + vy * tMatrix.d + tMatrix.ty) * weight; + } + worldVertices[w] = wx; + worldVertices[w + 1] = wy; + } + } + computeWorldPositions(boneSlot, boneList, graphics, spacesCount, tangents, percentPosition, percentSpacing) { + var tBones = boneSlot.currDisplayData.bones; + var tWeights = boneSlot.currDisplayData.weights; + var tTriangles = boneSlot.currDisplayData.triangles; + var tVertices = []; + var i = 0; + var verticesLength = boneSlot.currDisplayData.verLen; + var position = this.position; + var spaces = this._spaces; + var world = []; + var out = []; + var curveCount = verticesLength / 6; + var prevCurve = -1; + var pathLength; + var o, curve; + var p; + var space; + var prev; + var length; + { + curveCount--; + verticesLength -= 4; + this.computeWorldVertices2(boneSlot, boneList, 2, verticesLength, tVertices, 0); + if (this._debugKey) { + for (i = 0; i < tVertices.length;) { + graphics.drawCircle(tVertices[i++], tVertices[i++], 10, "#ff0000"); + } + } + world = tVertices; + } + this._curves.length = curveCount; + var curves = this._curves; + pathLength = 0; + var x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0; + var tmpx, tmpy, dddfx, dddfy, ddfx, ddfy, dfx, dfy; + var w; + for (i = 0, w = 2; i < curveCount; i++, w += 6) { + cx1 = world[w]; + cy1 = world[w + 1]; + cx2 = world[w + 2]; + cy2 = world[w + 3]; + x2 = world[w + 4]; + y2 = world[w + 5]; + tmpx = (x1 - cx1 * 2 + cx2) * 0.1875; + tmpy = (y1 - cy1 * 2 + cy2) * 0.1875; + dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375; + dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375; + ddfx = tmpx * 2 + dddfx; + ddfy = tmpy * 2 + dddfy; + dfx = (cx1 - x1) * 0.75 + tmpx + dddfx * 0.16666667; + dfy = (cy1 - y1) * 0.75 + tmpy + dddfy * 0.16666667; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx; + dfy += ddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx + dddfx; + dfy += ddfy + dddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + curves[i] = pathLength; + x1 = x2; + y1 = y2; + } + if (percentPosition) + position *= pathLength; + if (percentSpacing) { + for (i = 0; i < spacesCount; i++) + spaces[i] *= pathLength; + } + var segments = this._segments; + var curveLength = 0; + var segment; + for (i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) { + space = spaces[i]; + position += space; + p = position; + if (p < 0) { + this.addBeforePosition(p, world, 0, out, o); + continue; + } + else if (p > pathLength) { + this.addAfterPosition(p - pathLength, world, verticesLength - 4, out, o); + continue; + } + for (;; curve++) { + length = curves[curve]; + if (p > length) + continue; + if (curve == 0) + p /= length; + else { + prev = curves[curve - 1]; + p = (p - prev) / (length - prev); + } + break; + } + if (curve != prevCurve) { + prevCurve = curve; + var ii = curve * 6; + x1 = world[ii]; + y1 = world[ii + 1]; + cx1 = world[ii + 2]; + cy1 = world[ii + 3]; + cx2 = world[ii + 4]; + cy2 = world[ii + 5]; + x2 = world[ii + 6]; + y2 = world[ii + 7]; + tmpx = (x1 - cx1 * 2 + cx2) * 0.03; + tmpy = (y1 - cy1 * 2 + cy2) * 0.03; + dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006; + dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.006; + ddfx = tmpx * 2 + dddfx; + ddfy = tmpy * 2 + dddfy; + dfx = (cx1 - x1) * 0.3 + tmpx + dddfx * 0.16666667; + dfy = (cy1 - y1) * 0.3 + tmpy + dddfy * 0.16666667; + curveLength = Math.sqrt(dfx * dfx + dfy * dfy); + segments[0] = curveLength; + for (ii = 1; ii < 8; ii++) { + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[ii] = curveLength; + } + dfx += ddfx; + dfy += ddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[8] = curveLength; + dfx += ddfx + dddfx; + dfy += ddfy + dddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[9] = curveLength; + segment = 0; + } + p *= curveLength; + for (;; segment++) { + length = segments[segment]; + if (p > length) + continue; + if (segment == 0) + p /= length; + else { + prev = segments[segment - 1]; + p = segment + (p - prev) / (length - prev); + } + break; + } + this.addCurvePosition(p * 0.1, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space == 0)); + } + return out; + } + addBeforePosition(p, temp, i, out, o) { + var x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = Math.atan2(dy, dx); + out[o] = x1 + p * Math.cos(r); + out[o + 1] = y1 + p * Math.sin(r); + out[o + 2] = r; + } + addAfterPosition(p, temp, i, out, o) { + var x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = Math.atan2(dy, dx); + out[o] = x1 + p * Math.cos(r); + out[o + 1] = y1 + p * Math.sin(r); + out[o + 2] = r; + } + addCurvePosition(p, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents) { + if (p == 0) + p = 0.0001; + var tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u; + var ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p; + var x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt; + out[o] = x; + out[o + 1] = y; + if (tangents) { + out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt)); + } + else { + out[o + 2] = 0; + } + } + } + PathConstraint.BEFORE = -2; + PathConstraint.AFTER = -3; + PathConstraint._tempMt = new Laya.Matrix(); + + class PathConstraintData { + constructor() { + this.bones = []; + } + } + + class TfConstraint { + constructor(data, bones) { + this._temp = []; + this._data = data; + if (this._bones == null) { + this._bones = []; + } + this.target = bones[data.targetIndex]; + var j, n; + for (j = 0, n = data.boneIndexs.length; j < n; j++) { + this._bones.push(bones[data.boneIndexs[j]]); + } + this.rotateMix = data.rotateMix; + this.translateMix = data.translateMix; + this.scaleMix = data.scaleMix; + this.shearMix = data.shearMix; + } + apply() { + var tTfBone; + var ta = this.target.resultMatrix.a, tb = this.target.resultMatrix.b, tc = this.target.resultMatrix.c, td = this.target.resultMatrix.d; + for (var j = 0, n = this._bones.length; j < n; j++) { + tTfBone = this._bones[j]; + if (this.rotateMix > 0) { + var a = tTfBone.resultMatrix.a, b = tTfBone.resultMatrix.b, c = tTfBone.resultMatrix.c, d = tTfBone.resultMatrix.d; + var r = Math.atan2(tc, ta) - Math.atan2(c, a) + this._data.offsetRotation * Math.PI / 180; + if (r > Math.PI) + r -= Math.PI * 2; + else if (r < -Math.PI) + r += Math.PI * 2; + r *= this.rotateMix; + var cos = Math.cos(r), sin = Math.sin(r); + tTfBone.resultMatrix.a = cos * a - sin * c; + tTfBone.resultMatrix.b = cos * b - sin * d; + tTfBone.resultMatrix.c = sin * a + cos * c; + tTfBone.resultMatrix.d = sin * b + cos * d; + } + if (this.translateMix) { + this._temp[0] = this._data.offsetX; + this._temp[1] = this._data.offsetY; + this.target.localToWorld(this._temp); + tTfBone.resultMatrix.tx += (this._temp[0] - tTfBone.resultMatrix.tx) * this.translateMix; + tTfBone.resultMatrix.ty += (this._temp[1] - tTfBone.resultMatrix.ty) * this.translateMix; + tTfBone.updateChild(); + } + if (this.scaleMix > 0) { + var bs = Math.sqrt(tTfBone.resultMatrix.a * tTfBone.resultMatrix.a + tTfBone.resultMatrix.c * tTfBone.resultMatrix.c); + var ts = Math.sqrt(ta * ta + tc * tc); + var s = bs > 0.00001 ? (bs + (ts - bs + this._data.offsetScaleX) * this.scaleMix) / bs : 0; + tTfBone.resultMatrix.a *= s; + tTfBone.resultMatrix.c *= s; + bs = Math.sqrt(tTfBone.resultMatrix.b * tTfBone.resultMatrix.b + tTfBone.resultMatrix.d * tTfBone.resultMatrix.d); + ts = Math.sqrt(tb * tb + td * td); + s = bs > 0.00001 ? (bs + (ts - bs + this._data.offsetScaleY) * this.scaleMix) / bs : 0; + tTfBone.resultMatrix.b *= s; + tTfBone.resultMatrix.d *= s; + } + if (this.shearMix > 0) { + b = tTfBone.resultMatrix.b, d = tTfBone.resultMatrix.d; + var by = Math.atan2(d, b); + r = Math.atan2(td, tb) - Math.atan2(tc, ta) - (by - Math.atan2(tTfBone.resultMatrix.c, tTfBone.resultMatrix.a)); + if (r > Math.PI) + r -= Math.PI * 2; + else if (r < -Math.PI) + r += Math.PI * 2; + r = by + (r + this._data.offsetShearY * Math.PI / 180) * this.shearMix; + s = Math.sqrt(b * b + d * d); + tTfBone.resultMatrix.b = Math.cos(r) * s; + tTfBone.resultMatrix.d = Math.sin(r) * s; + } + } + } + } + + class Skeleton extends Laya.Sprite { + constructor(templet = null, aniMode = 0) { + super(); + this._boneMatrixArray = []; + this._lastTime = 0; + this._currAniIndex = -1; + this._pause = true; + this._aniClipIndex = -1; + this._clipIndex = -1; + this._skinIndex = 0; + this._skinName = "default"; + this._aniMode = 0; + this._index = -1; + this._total = -1; + this._indexControl = false; + this._eventIndex = 0; + this._drawOrderIndex = 0; + this._drawOrder = null; + this._lastAniClipIndex = -1; + this._lastUpdateAniClipIndex = -1; + this._playAudio = true; + this._soundChannelArr = []; + if (templet) + this.init(templet, aniMode); + } + init(templet, aniMode = 0) { + var i = 0, n; + if (aniMode == 1) { + this._graphicsCache = []; + for (i = 0, n = templet.getAnimationCount(); i < n; i++) { + this._graphicsCache.push([]); + } + } + this._yReverseMatrix = templet.yReverseMatrix; + this._aniMode = aniMode; + this._templet = templet; + this._templet._addReference(1); + this._player = new AnimationPlayer(); + this._player.cacheFrameRate = templet.rate; + this._player.templet = templet; + this._player.play(); + this._parseSrcBoneMatrix(); + this._boneList = templet.mBoneArr; + this._rootBone = templet.mRootBone; + this._aniSectionDic = templet.aniSectionDic; + if (templet.ikArr.length > 0) { + this._ikArr = []; + for (i = 0, n = templet.ikArr.length; i < n; i++) { + this._ikArr.push(new IkConstraint(templet.ikArr[i], this._boneList)); + } + } + if (templet.pathArr.length > 0) { + var tPathData; + var tPathConstraint; + if (this._pathDic == null) + this._pathDic = {}; + var tBoneSlot; + for (i = 0, n = templet.pathArr.length; i < n; i++) { + tPathData = templet.pathArr[i]; + tPathConstraint = new PathConstraint(tPathData, this._boneList); + tBoneSlot = this._boneSlotDic[tPathData.name]; + if (tBoneSlot) { + tPathConstraint = new PathConstraint(tPathData, this._boneList); + tPathConstraint.target = tBoneSlot; + } + this._pathDic[tPathData.name] = tPathConstraint; + } + } + if (templet.tfArr.length > 0) { + this._tfArr = []; + for (i = 0, n = templet.tfArr.length; i < n; i++) { + this._tfArr.push(new TfConstraint(templet.tfArr[i], this._boneList)); + } + } + if (templet.skinDataArray.length > 0) { + var tSkinData = this._templet.skinDataArray[this._skinIndex]; + this._skinName = tSkinData.name; + } + this._player.on(Laya.Event.PLAYED, this, this._onPlay); + this._player.on(Laya.Event.STOPPED, this, this._onStop); + this._player.on(Laya.Event.PAUSED, this, this._onPause); + } + get url() { + return this._aniPath; + } + set url(path) { + this.load(path); + } + load(path, complete = null, aniMode = 0) { + this._aniPath = path; + this._complete = complete; + this._loadAniMode = aniMode; + Laya.ILaya.loader.load([{ url: path, type: Laya.ILaya.Loader.BUFFER }], Laya.Handler.create(this, this._onLoaded)); + } + _onLoaded() { + var arraybuffer = Laya.ILaya.Loader.getRes(this._aniPath); + if (arraybuffer == null) + return; + if (IAniLib.Templet.TEMPLET_DICTIONARY == null) { + IAniLib.Templet.TEMPLET_DICTIONARY = {}; + } + var tFactory; + tFactory = IAniLib.Templet.TEMPLET_DICTIONARY[this._aniPath]; + if (tFactory) { + if (tFactory.isParseFail) { + this._parseFail(); + } + else { + if (tFactory.isParserComplete) { + this._parseComplete(); + } + else { + tFactory.on(Laya.Event.COMPLETE, this, this._parseComplete); + tFactory.on(Laya.Event.ERROR, this, this._parseFail); + } + } + } + else { + tFactory = new IAniLib.Templet(); + tFactory._setCreateURL(this._aniPath); + IAniLib.Templet.TEMPLET_DICTIONARY[this._aniPath] = tFactory; + tFactory.on(Laya.Event.COMPLETE, this, this._parseComplete); + tFactory.on(Laya.Event.ERROR, this, this._parseFail); + tFactory.isParserComplete = false; + tFactory.parseData(null, arraybuffer); + } + } + _parseComplete() { + var tTemple = IAniLib.Templet.TEMPLET_DICTIONARY[this._aniPath]; + if (tTemple) { + this.init(tTemple, this._loadAniMode); + this.play(0, true); + } + this._complete && this._complete.runWith(this); + } + _parseFail() { + console.log("[Error]:" + this._aniPath + "解析失败"); + } + _onPlay() { + this.event(Laya.Event.PLAYED); + } + _onStop() { + var tEventData; + var tEventAniArr = this._templet.eventAniArr; + var tEventArr = tEventAniArr[this._aniClipIndex]; + if (tEventArr && this._eventIndex < tEventArr.length) { + for (; this._eventIndex < tEventArr.length; this._eventIndex++) { + tEventData = tEventArr[this._eventIndex]; + if (tEventData.time >= this._player.playStart && tEventData.time <= this._player.playEnd) { + this.event(Laya.Event.LABEL, tEventData); + } + } + } + this._drawOrder = null; + this.event(Laya.Event.STOPPED); + } + _onPause() { + this.event(Laya.Event.PAUSED); + } + _parseSrcBoneMatrix() { + var i = 0, n = 0; + n = this._templet.srcBoneMatrixArr.length; + for (i = 0; i < n; i++) { + this._boneMatrixArray.push(new Laya.Matrix()); + } + if (this._aniMode == 0) { + this._boneSlotDic = this._templet.boneSlotDic; + this._bindBoneBoneSlotDic = this._templet.bindBoneBoneSlotDic; + this._boneSlotArray = this._templet.boneSlotArray; + } + else { + if (this._boneSlotDic == null) + this._boneSlotDic = {}; + if (this._bindBoneBoneSlotDic == null) + this._bindBoneBoneSlotDic = {}; + if (this._boneSlotArray == null) + this._boneSlotArray = []; + var tArr = this._templet.boneSlotArray; + var tBS; + var tBSArr; + for (i = 0, n = tArr.length; i < n; i++) { + tBS = tArr[i]; + tBSArr = this._bindBoneBoneSlotDic[tBS.parent]; + if (tBSArr == null) { + this._bindBoneBoneSlotDic[tBS.parent] = tBSArr = []; + } + this._boneSlotDic[tBS.name] = tBS = tBS.copy(); + tBSArr.push(tBS); + this._boneSlotArray.push(tBS); + } + } + } + _emitMissedEvents(startTime, endTime, startIndex = 0) { + var tEventAniArr = this._templet.eventAniArr; + var tEventArr = tEventAniArr[this._player.currentAnimationClipIndex]; + if (tEventArr) { + var i = 0, len; + var tEventData; + len = tEventArr.length; + for (i = startIndex; i < len; i++) { + tEventData = tEventArr[i]; + if (tEventData.time >= this._player.playStart && tEventData.time <= this._player.playEnd) { + this.event(Laya.Event.LABEL, tEventData); + } + } + } + } + _update(autoKey = true) { + if (autoKey && this._pause) + return; + if (autoKey && this._indexControl) { + return; + } + var tCurrTime = this.timer.currTimer; + var preIndex = this._player.currentKeyframeIndex; + var dTime = tCurrTime - this._lastTime; + if (autoKey) { + this._player._update(dTime); + } + else { + preIndex = -1; + } + this._lastTime = tCurrTime; + if (!this._player) + return; + this._index = this._clipIndex = this._player.currentKeyframeIndex; + if (this._index < 0) + return; + if (dTime > 0 && this._clipIndex == preIndex && this._lastUpdateAniClipIndex == this._aniClipIndex) { + return; + } + this._lastUpdateAniClipIndex = this._aniClipIndex; + if (preIndex > this._clipIndex && this._eventIndex != 0) { + this._emitMissedEvents(this._player.playStart, this._player.playEnd, this._eventIndex); + this._eventIndex = 0; + } + var tEventArr = this._templet.eventAniArr[this._aniClipIndex]; + var _soundChannel; + if (tEventArr && this._eventIndex < tEventArr.length) { + var tEventData = tEventArr[this._eventIndex]; + if (tEventData.time >= this._player.playStart && tEventData.time <= this._player.playEnd) { + if (this._player.currentPlayTime >= tEventData.time) { + this.event(Laya.Event.LABEL, tEventData); + this._eventIndex++; + if (this._playAudio && tEventData.audioValue && tEventData.audioValue !== "null" && tEventData.audioValue !== "undefined") { + _soundChannel = Laya.SoundManager.playSound(this._player.templet._path + tEventData.audioValue, 1, Laya.Handler.create(this, this._onAniSoundStoped)); + Laya.SoundManager.playbackRate = this._player.playbackRate; + _soundChannel && this._soundChannelArr.push(_soundChannel); + } + } + } + else if (tEventData.time < this._player.playStart && this._playAudio && tEventData.audioValue && tEventData.audioValue !== "null" && tEventData.audioValue !== "undefined") { + this._eventIndex++; + _soundChannel = Laya.SoundManager.playSound(this._player.templet._path + tEventData.audioValue, 1, Laya.Handler.create(this, this._onAniSoundStoped), null, (this._player.currentPlayTime - tEventData.time) / 1000); + Laya.SoundManager.playbackRate = this._player.playbackRate; + _soundChannel && this._soundChannelArr.push(_soundChannel); + } + else { + this._eventIndex++; + } + } + var tGraphics; + if (this._aniMode == 0) { + tGraphics = this._templet.getGrahicsDataWithCache(this._aniClipIndex, this._clipIndex) || this._createGraphics(); + if (tGraphics && this.graphics != tGraphics) { + this.graphics = tGraphics; + } + } + else if (this._aniMode == 1) { + tGraphics = this._getGrahicsDataWithCache(this._aniClipIndex, this._clipIndex) || this._createGraphics(); + if (tGraphics && this.graphics != tGraphics) { + this.graphics = tGraphics; + } + } + else { + this._createGraphics(); + } + } + _onAniSoundStoped(force) { + var _channel; + for (var len = this._soundChannelArr.length, i = 0; i < len; i++) { + _channel = this._soundChannelArr[i]; + if (_channel.isStopped || force) { + !_channel.isStopped && _channel.stop(); + this._soundChannelArr.splice(i, 1); + len--; + i--; + } + } + } + _createGraphics(_clipIndex = -1) { + if (_clipIndex == -1) + _clipIndex = this._clipIndex; + var curTime = _clipIndex * this._player.cacheFrameRateInterval; + var tDrawOrderData; + var tDrawOrderAniArr = this._templet.drawOrderAniArr; + var tDrawOrderArr = tDrawOrderAniArr[this._aniClipIndex]; + if (tDrawOrderArr && tDrawOrderArr.length > 0) { + this._drawOrderIndex = 0; + tDrawOrderData = tDrawOrderArr[this._drawOrderIndex]; + while (curTime >= tDrawOrderData.time) { + this._drawOrder = tDrawOrderData.drawOrder; + this._drawOrderIndex++; + if (this._drawOrderIndex >= tDrawOrderArr.length) { + break; + } + tDrawOrderData = tDrawOrderArr[this._drawOrderIndex]; + } + } + if (this._aniMode == 0 || this._aniMode == 1) { + this.graphics = GraphicsAni.create(); + } + else { + if (this.graphics instanceof GraphicsAni) { + this.graphics.clear(); + } + else { + this.graphics = GraphicsAni.create(); + } + } + var tGraphics = this.graphics; + var bones = this._templet.getNodes(this._aniClipIndex); + var stopped = this._player.state == 0; + this._templet.getOriginalData(this._aniClipIndex, this._curOriginalData, null, _clipIndex, stopped ? (curTime + this._player.cacheFrameRateInterval) : curTime); + var tSectionArr = this._aniSectionDic[this._aniClipIndex]; + var tStartIndex = 0; + var i = 0, j = 0, k = 0, n = 0; + var tDBBoneSlot; + var tDBBoneSlotArr; + var tParentTransform; + var tSrcBone; + var boneCount = this._templet.srcBoneMatrixArr.length; + var origDt = this._curOriginalData; + for (i = 0, n = tSectionArr[0]; i < boneCount; i++) { + tSrcBone = this._boneList[i]; + var resultTrans = tSrcBone.resultTransform; + tParentTransform = this._templet.srcBoneMatrixArr[i]; + resultTrans.scX = tParentTransform.scX * origDt[tStartIndex++]; + resultTrans.skX = tParentTransform.skX + origDt[tStartIndex++]; + resultTrans.skY = tParentTransform.skY + origDt[tStartIndex++]; + resultTrans.scY = tParentTransform.scY * origDt[tStartIndex++]; + resultTrans.x = tParentTransform.x + origDt[tStartIndex++]; + resultTrans.y = tParentTransform.y + origDt[tStartIndex++]; + if (this._templet.tMatrixDataLen === 8) { + resultTrans.skewX = tParentTransform.skewX + origDt[tStartIndex++]; + resultTrans.skewY = tParentTransform.skewY + origDt[tStartIndex++]; + } + } + var tSlotDic = {}; + var tSlotAlphaDic = {}; + var tBoneData; + for (n += tSectionArr[1]; i < n; i++) { + tBoneData = bones[i]; + tSlotDic[tBoneData.name] = origDt[tStartIndex++]; + tSlotAlphaDic[tBoneData.name] = origDt[tStartIndex++]; + tStartIndex += 4; + } + var tBendDirectionDic = {}; + var tMixDic = {}; + for (n += tSectionArr[2]; i < n; i++) { + tBoneData = bones[i]; + tBendDirectionDic[tBoneData.name] = origDt[tStartIndex++]; + tMixDic[tBoneData.name] = origDt[tStartIndex++]; + tStartIndex += 4; + } + if (this._pathDic) { + var tPathConstraint; + for (n += tSectionArr[3]; i < n; i++) { + tBoneData = bones[i]; + tPathConstraint = this._pathDic[tBoneData.name]; + if (tPathConstraint) { + var tByte = new Laya.Byte(tBoneData.extenData); + switch (tByte.getByte()) { + case 1: + tPathConstraint.position = origDt[tStartIndex++]; + break; + case 2: + tPathConstraint.spacing = origDt[tStartIndex++]; + break; + case 3: + tPathConstraint.rotateMix = origDt[tStartIndex++]; + tPathConstraint.translateMix = origDt[tStartIndex++]; + break; + } + } + } + } + this._rootBone.update(this._yReverseMatrix || Laya.Matrix.TEMP.identity()); + if (this._ikArr) { + var tIkConstraint; + for (i = 0, n = this._ikArr.length; i < n; i++) { + tIkConstraint = this._ikArr[i]; + if (tIkConstraint.name in tBendDirectionDic) { + tIkConstraint.bendDirection = tBendDirectionDic[tIkConstraint.name]; + } + if (tIkConstraint.name in tMixDic) { + tIkConstraint.mix = tMixDic[tIkConstraint.name]; + } + tIkConstraint.apply(); + } + } + if (this._pathDic) { + for (var tPathStr in this._pathDic) { + tPathConstraint = this._pathDic[tPathStr]; + tPathConstraint.apply(this._boneList, tGraphics); + } + } + if (this._tfArr) { + var tTfConstraint; + for (i = 0, k = this._tfArr.length; i < k; i++) { + tTfConstraint = this._tfArr[i]; + tTfConstraint.apply(); + } + } + for (i = 0, k = this._boneList.length; i < k; i++) { + tSrcBone = this._boneList[i]; + tDBBoneSlotArr = this._bindBoneBoneSlotDic[tSrcBone.name]; + tSrcBone.resultMatrix.copyTo(this._boneMatrixArray[i]); + if (tDBBoneSlotArr) { + for (j = 0, n = tDBBoneSlotArr.length; j < n; j++) { + tDBBoneSlot = tDBBoneSlotArr[j]; + if (tDBBoneSlot) { + tDBBoneSlot.setParentMatrix(tSrcBone.resultMatrix); + } + } + } + } + var tDeformDic = {}; + var tDeformAniArr = this._templet.deformAniArr; + var tDeformAniData; + if (tDeformAniArr && tDeformAniArr.length > 0) { + if (this._lastAniClipIndex != this._aniClipIndex) { + this._lastAniClipIndex = this._aniClipIndex; + for (i = 0, n = this._boneSlotArray.length; i < n; i++) { + tDBBoneSlot = this._boneSlotArray[i]; + tDBBoneSlot.deformData = null; + } + } + var tSkinDeformAni = tDeformAniArr[this._aniClipIndex]; + tDeformAniData = (tSkinDeformAni["default"]); + this._setDeform(tDeformAniData, tDeformDic, this._boneSlotArray, curTime); + var tSkin; + for (tSkin in tSkinDeformAni) { + if (tSkin != "default" && tSkin != this._skinName) { + tDeformAniData = tSkinDeformAni[tSkin]; + this._setDeform(tDeformAniData, tDeformDic, this._boneSlotArray, curTime); + } + } + tDeformAniData = (tSkinDeformAni[this._skinName]); + this._setDeform(tDeformAniData, tDeformDic, this._boneSlotArray, curTime); + } + var tSlotData2; + var tSlotData3; + var tObject; + if (this._drawOrder) { + for (i = 0, n = this._drawOrder.length; i < n; i++) { + tDBBoneSlot = this._boneSlotArray[this._drawOrder[i]]; + tSlotData2 = tSlotDic[tDBBoneSlot.name]; + tSlotData3 = tSlotAlphaDic[tDBBoneSlot.name]; + if (!isNaN(tSlotData2) && tSlotData2 != -2) { + if (this._templet.attachmentNames) { + tDBBoneSlot.showDisplayByName(this._templet.attachmentNames[tSlotData2]); + } + else { + tDBBoneSlot.showDisplayByIndex(tSlotData2); + } + } + if (tDeformDic[this._drawOrder[i]]) { + tObject = tDeformDic[this._drawOrder[i]]; + if (tDBBoneSlot.currDisplayData && tObject[tDBBoneSlot.currDisplayData.attachmentName]) { + tDBBoneSlot.deformData = tObject[tDBBoneSlot.currDisplayData.attachmentName]; + } + else { + tDBBoneSlot.deformData = null; + } + } + else { + tDBBoneSlot.deformData = null; + } + if (!isNaN(tSlotData3)) { + tDBBoneSlot.draw(tGraphics, this._boneMatrixArray, this._aniMode == 2, tSlotData3); + } + else { + tDBBoneSlot.draw(tGraphics, this._boneMatrixArray, this._aniMode == 2); + } + } + } + else { + for (i = 0, n = this._boneSlotArray.length; i < n; i++) { + tDBBoneSlot = this._boneSlotArray[i]; + tSlotData2 = tSlotDic[tDBBoneSlot.name]; + tSlotData3 = tSlotAlphaDic[tDBBoneSlot.name]; + if (!isNaN(tSlotData2) && tSlotData2 != -2) { + if (this._templet.attachmentNames) { + tDBBoneSlot.showDisplayByName(this._templet.attachmentNames[tSlotData2]); + } + else { + tDBBoneSlot.showDisplayByIndex(tSlotData2); + } + } + if (tDeformDic[i]) { + tObject = tDeformDic[i]; + if (tDBBoneSlot.currDisplayData && tObject[tDBBoneSlot.currDisplayData.attachmentName]) { + tDBBoneSlot.deformData = tObject[tDBBoneSlot.currDisplayData.attachmentName]; + } + else { + tDBBoneSlot.deformData = null; + } + } + else { + tDBBoneSlot.deformData = null; + } + if (!isNaN(tSlotData3)) { + tDBBoneSlot.draw(tGraphics, this._boneMatrixArray, this._aniMode == 2, tSlotData3); + } + else { + tDBBoneSlot.draw(tGraphics, this._boneMatrixArray, this._aniMode == 2); + } + } + } + if (this._aniMode == 0) { + this._templet.setGrahicsDataWithCache(this._aniClipIndex, _clipIndex, tGraphics); + this._checkIsAllParsed(this._aniClipIndex); + } + else if (this._aniMode == 1) { + this._setGrahicsDataWithCache(this._aniClipIndex, _clipIndex, tGraphics); + } + return tGraphics; + } + _checkIsAllParsed(_aniClipIndex) { + var i, len; + len = Math.floor(0.01 + this._templet.getAniDuration(_aniClipIndex) / 1000 * this._player.cacheFrameRate); + for (i = 0; i < len; i++) { + if (!this._templet.getGrahicsDataWithCache(_aniClipIndex, i)) + return; + } + if (!this._templet.getGrahicsDataWithCache(_aniClipIndex, len)) { + this._createGraphics(len); + return; + } + this._templet.deleteAniData(_aniClipIndex); + } + _setDeform(tDeformAniData, tDeformDic, _boneSlotArray, curTime) { + if (!tDeformAniData) + return; + var tDeformSlotData; + var tDeformSlotDisplayData; + var tDBBoneSlot; + var i, n, j; + if (tDeformAniData) { + for (i = 0, n = tDeformAniData.deformSlotDataList.length; i < n; i++) { + tDeformSlotData = tDeformAniData.deformSlotDataList[i]; + for (j = 0; j < tDeformSlotData.deformSlotDisplayList.length; j++) { + tDeformSlotDisplayData = tDeformSlotData.deformSlotDisplayList[j]; + tDBBoneSlot = _boneSlotArray[tDeformSlotDisplayData.slotIndex]; + tDeformSlotDisplayData.apply(curTime, tDBBoneSlot); + if (!tDeformDic[tDeformSlotDisplayData.slotIndex]) { + tDeformDic[tDeformSlotDisplayData.slotIndex] = {}; + } + tDeformDic[tDeformSlotDisplayData.slotIndex][tDeformSlotDisplayData.attachment] = tDeformSlotDisplayData.deformData; + } + } + } + } + getAnimNum() { + return this._templet.getAnimationCount(); + } + getAniNameByIndex(index) { + return this._templet.getAniNameByIndex(index); + } + getSlotByName(name) { + return this._boneSlotDic[name]; + } + showSkinByName(name, freshSlotIndex = true) { + this.showSkinByIndex(this._templet.getSkinIndexByName(name), freshSlotIndex); + } + showSkinByIndex(skinIndex, freshSlotIndex = true) { + for (var i = 0; i < this._boneSlotArray.length; i++) { + this._boneSlotArray[i].showSlotData(null, freshSlotIndex); + } + if (this._templet.showSkinByIndex(this._boneSlotDic, skinIndex, freshSlotIndex)) { + var tSkinData = this._templet.skinDataArray[skinIndex]; + this._skinIndex = skinIndex; + this._skinName = tSkinData.name; + } + this._clearCache(); + } + showSlotSkinByIndex(slotName, index) { + if (this._aniMode == 0) + return; + var tBoneSlot = this.getSlotByName(slotName); + if (tBoneSlot) { + tBoneSlot.showDisplayByIndex(index); + } + this._clearCache(); + } + showSlotSkinByName(slotName, name) { + if (this._aniMode == 0) + return; + var tBoneSlot = this.getSlotByName(slotName); + if (tBoneSlot) { + tBoneSlot.showDisplayByName(name); + } + this._clearCache(); + } + replaceSlotSkinName(slotName, oldName, newName) { + if (this._aniMode == 0) + return; + var tBoneSlot = this.getSlotByName(slotName); + if (tBoneSlot) { + tBoneSlot.replaceDisplayByName(oldName, newName); + } + this._clearCache(); + } + replaceSlotSkinByIndex(slotName, oldIndex, newIndex) { + if (this._aniMode == 0) + return; + var tBoneSlot = this.getSlotByName(slotName); + if (tBoneSlot) { + tBoneSlot.replaceDisplayByIndex(oldIndex, newIndex); + } + this._clearCache(); + } + setSlotSkin(slotName, texture) { + if (this._aniMode == 0) + return; + var tBoneSlot = this.getSlotByName(slotName); + if (tBoneSlot) { + tBoneSlot.replaceSkin(texture); + } + this._clearCache(); + } + _clearCache() { + if (this._aniMode == 1) { + for (var i = 0, n = this._graphicsCache.length; i < n; i++) { + for (var j = 0, len = this._graphicsCache[i].length; j < len; j++) { + var gp = this._graphicsCache[i][j]; + if (gp && gp != this.graphics) { + GraphicsAni.recycle(gp); + } + } + this._graphicsCache[i].length = 0; + } + } + } + play(nameOrIndex, loop, force = true, start = 0, end = 0, freshSkin = true, playAudio = true) { + this._playAudio = playAudio; + this._indexControl = false; + var index = -1; + var duration; + if (loop) { + duration = 2147483647; + } + else { + duration = 0; + } + if (typeof (nameOrIndex) == 'string') { + for (var i = 0, n = this._templet.getAnimationCount(); i < n; i++) { + var animation = this._templet.getAnimation(i); + if (animation && nameOrIndex == animation.name) { + index = i; + break; + } + } + } + else { + index = nameOrIndex; + } + if (index > -1 && index < this.getAnimNum()) { + this._aniClipIndex = index; + if (force || this._pause || this._currAniIndex != index) { + this._currAniIndex = index; + this._curOriginalData = new Float32Array(this._templet.getTotalkeyframesLength(index)); + this._drawOrder = null; + this._eventIndex = 0; + this._player.play(index, this._player.playbackRate, duration, start, end); + if (freshSkin) + this._templet.showSkinByIndex(this._boneSlotDic, this._skinIndex); + if (this._pause) { + this._pause = false; + this._lastTime = Laya.ILaya.Browser.now(); + this.timer.frameLoop(1, this, this._update, null, true); + } + this._update(); + } + } + } + stop() { + if (!this._pause) { + this._pause = true; + if (this._player) { + this._player.stop(true); + } + if (this._soundChannelArr.length > 0) { + this._onAniSoundStoped(true); + } + this.timer.clear(this, this._update); + } + } + playbackRate(value) { + if (this._player) { + this._player.playbackRate = value; + } + } + paused() { + if (!this._pause) { + this._pause = true; + if (this._player) { + this._player.paused = true; + } + if (this._soundChannelArr.length > 0) { + var _soundChannel; + for (var len = this._soundChannelArr.length, i = 0; i < len; i++) { + _soundChannel = this._soundChannelArr[i]; + if (!_soundChannel.isStopped) { + _soundChannel.pause(); + } + } + } + this.timer.clear(this, this._update); + } + } + resume() { + this._indexControl = false; + if (this._pause) { + this._pause = false; + if (this._player) { + this._player.paused = false; + } + if (this._soundChannelArr.length > 0) { + var _soundChannel; + for (var len = this._soundChannelArr.length, i = 0; i < len; i++) { + _soundChannel = this._soundChannelArr[i]; + if (_soundChannel.audioBuffer) { + _soundChannel.resume(); + } + } + } + this._lastTime = Laya.ILaya.Browser.now(); + this.timer.frameLoop(1, this, this._update, null, true); + } + } + _getGrahicsDataWithCache(aniIndex, frameIndex) { + return this._graphicsCache[aniIndex][frameIndex]; + } + _setGrahicsDataWithCache(aniIndex, frameIndex, graphics) { + this._graphicsCache[aniIndex][frameIndex] = graphics; + } + destroy(destroyChild = true) { + super.destroy(destroyChild); + this._templet._removeReference(1); + this._templet = null; + if (this._player) + this._player.offAll(); + this._player = null; + this._curOriginalData = null; + this._boneMatrixArray.length = 0; + this._lastTime = 0; + this.timer.clear(this, this._update); + if (this._soundChannelArr.length > 0) { + this._onAniSoundStoped(true); + } + } + get index() { + return this._index; + } + set index(value) { + if (this.player) { + this._index = value; + this._player.currentTime = this._index * 1000 / this._player.cacheFrameRate; + this._indexControl = true; + if (this._aniClipIndex < 0 || this._aniClipIndex >= this.getAnimNum()) { + this._aniClipIndex = 0; + this._currAniIndex = 0; + this._curOriginalData = new Float32Array(this._templet.getTotalkeyframesLength(this._currAniIndex)); + this._drawOrder = null; + this._eventIndex = 0; + } + this._update(false); + } + } + get total() { + if (this._templet && this._player) { + this._total = Math.floor(this._templet.getAniDuration(this._player.currentAnimationClipIndex) / 1000 * this._player.cacheFrameRate); + } + else { + this._total = -1; + } + return this._total; + } + get player() { + return this._player; + } + get templet() { + return this._templet; + } + } + Skeleton.useSimpleMeshInCanvas = false; + IAniLib.Skeleton = Skeleton; + Laya.ILaya.regClass(Skeleton); + Laya.ClassUtils.regClass("laya.ani.bone.Skeleton", Skeleton); + Laya.ClassUtils.regClass("Laya.Skeleton", Skeleton); + + class SkinData { + constructor() { + this.slotArr = []; + } + } + + class SkinSlotDisplayData { + createTexture(currTexture) { + if (this.texture) + return this.texture; + this.texture = new Laya.Texture(currTexture.bitmap, this.uvs); + if (this.uvs[0] > this.uvs[4] + && this.uvs[1] > this.uvs[5]) { + this.texture.width = currTexture.height; + this.texture.height = currTexture.width; + this.texture.offsetX = -currTexture.offsetX; + this.texture.offsetY = -currTexture.offsetY; + this.texture.sourceWidth = currTexture.sourceHeight; + this.texture.sourceHeight = currTexture.sourceWidth; + } + else { + this.texture.width = currTexture.width; + this.texture.height = currTexture.height; + this.texture.offsetX = -currTexture.offsetX; + this.texture.offsetY = -currTexture.offsetY; + this.texture.sourceWidth = currTexture.sourceWidth; + this.texture.sourceHeight = currTexture.sourceHeight; + } + return this.texture; + } + destory() { + if (this.texture) + this.texture.destroy(); + } + } + + class SlotData { + constructor() { + this.displayArr = []; + } + getDisplayByName(name) { + var tDisplay; + for (var i = 0, n = this.displayArr.length; i < n; i++) { + tDisplay = this.displayArr[i]; + if (tDisplay.attachmentName == name) { + return i; + } + } + return -1; + } + } + + class TfConstraintData { + constructor() { + this.boneIndexs = []; + } + } + + class Templet extends AnimationTemplet { + constructor() { + super(...arguments); + this._graphicsCache = []; + this.srcBoneMatrixArr = []; + this.ikArr = []; + this.tfArr = []; + this.pathArr = []; + this.boneSlotDic = {}; + this.bindBoneBoneSlotDic = {}; + this.boneSlotArray = []; + this.skinDataArray = []; + this.skinDic = {}; + this.subTextureDic = {}; + this.isParseFail = false; + this.drawOrderAniArr = []; + this.eventAniArr = []; + this.attachmentNames = null; + this.deformAniArr = []; + this.skinSlotDisplayDataArr = []; + this._isParseAudio = false; + this._isDestroyed = false; + this._rate = 30; + this.isParserComplete = false; + this.aniSectionDic = {}; + this._textureDic = {}; + this.mBoneArr = []; + } + loadAni(url) { + this._skBufferUrl = url; + Laya.ILaya.loader.load(url, Laya.Handler.create(this, this.onComplete), null, Laya.ILaya.Loader.BUFFER); + } + onComplete(content = null) { + if (this._isDestroyed) { + this.destroy(); + return; + } + var tSkBuffer = Laya.ILaya.Loader.getRes(this._skBufferUrl); + if (!tSkBuffer) { + this.event(Laya.Event.ERROR, "load failed:" + this._skBufferUrl); + return; + } + this._path = this._skBufferUrl.slice(0, this._skBufferUrl.lastIndexOf("/")) + "/"; + this.parseData(null, tSkBuffer); + } + parseData(texture, skeletonData, playbackRate = 30) { + if (!this._path) { + var s1 = (this._relativeUrl || this.url); + if (s1) { + var p1 = s1.lastIndexOf('/'); + if (p1 > 0) { + this._path = s1.slice(0, p1) + "/"; + } + else { + this._path = ''; + } + } + } + this._mainTexture = texture; + this._rate = playbackRate; + this.parse(skeletonData); + } + buildArmature(aniMode = 0) { + return new Skeleton(this, aniMode); + } + parse(data) { + super.parse(data); + this.event(Laya.Event.LOADED, this); + if (this._aniVersion === Templet.LAYA_ANIMATION_VISION) { + this._isParseAudio = true; + } + else if (this._aniVersion != Templet.LAYA_ANIMATION_160_VISION) { + console.log("[Error] 版本不一致,请使用IDE版本配套的重新导出" + this._aniVersion + "->" + Templet.LAYA_ANIMATION_VISION); + } + if (this._mainTexture) { + this._parsePublicExtData(); + } + else { + this._parseTexturePath(); + } + } + _parseTexturePath() { + if (this._isDestroyed) { + this.destroy(); + return; + } + var i = 0; + this._loadList = []; + var tByte = new Laya.Byte(this.getPublicExtData()); + var tX = 0, tY = 0, tWidth = 0, tHeight = 0; + var tTempleData = 0; + var tTextureLen = tByte.getInt32(); + var tTextureName = tByte.readUTFString(); + var tTextureNameArr = tTextureName.split("\n"); + var tSrcTexturePath; + for (i = 0; i < tTextureLen; i++) { + tSrcTexturePath = this._path + tTextureNameArr[i * 2]; + tTextureName = tTextureNameArr[i * 2 + 1]; + tX = tByte.getFloat32(); + tY = tByte.getFloat32(); + tWidth = tByte.getFloat32(); + tHeight = tByte.getFloat32(); + tTempleData = tByte.getFloat32(); + tTempleData = tByte.getFloat32(); + tTempleData = tByte.getFloat32(); + tTempleData = tByte.getFloat32(); + if (this._loadList.indexOf(tSrcTexturePath) == -1) { + this._loadList.push(tSrcTexturePath); + } + } + Laya.ILaya.loader.load(this._loadList, Laya.Handler.create(this, this._textureComplete)); + } + _textureComplete() { + var tTextureName; + for (var i = 0, n = this._loadList.length; i < n; i++) { + tTextureName = this._loadList[i]; + this._textureDic[tTextureName] = Laya.ILaya.Loader.getRes(tTextureName); + } + this._parsePublicExtData(); + } + _parsePublicExtData() { + var i = 0, j = 0, k = 0, l = 0, n = 0; + for (i = 0, n = this.getAnimationCount(); i < n; i++) { + this._graphicsCache.push([]); + } + var isSpine; + isSpine = this._aniClassName != "Dragon"; + var tByte = new Laya.Byte(this.getPublicExtData()); + var tX = 0, tY = 0, tWidth = 0, tHeight = 0; + var tFrameX = 0, tFrameY = 0, tFrameWidth = 0, tFrameHeight = 0; + var tTempleData = 0; + var tTextureLen = tByte.getInt32(); + var tTextureName = tByte.readUTFString(); + var tTextureNameArr = tTextureName.split("\n"); + var tTexture; + var tSrcTexturePath; + for (i = 0; i < tTextureLen; i++) { + tTexture = this._mainTexture; + tSrcTexturePath = this._path + tTextureNameArr[i * 2]; + tTextureName = tTextureNameArr[i * 2 + 1]; + if (this._mainTexture == null) { + tTexture = this._textureDic[tSrcTexturePath]; + } + if (!tTexture) { + this.event(Laya.Event.ERROR, this); + this.isParseFail = true; + return; + } + tX = tByte.getFloat32(); + tY = tByte.getFloat32(); + tWidth = tByte.getFloat32(); + tHeight = tByte.getFloat32(); + tTempleData = tByte.getFloat32(); + tFrameX = isNaN(tTempleData) ? 0 : tTempleData; + tTempleData = tByte.getFloat32(); + tFrameY = isNaN(tTempleData) ? 0 : tTempleData; + tTempleData = tByte.getFloat32(); + tFrameWidth = isNaN(tTempleData) ? tWidth : tTempleData; + tTempleData = tByte.getFloat32(); + tFrameHeight = isNaN(tTempleData) ? tHeight : tTempleData; + this.subTextureDic[tTextureName] = Laya.Texture.create(tTexture, tX, tY, tWidth, tHeight, -tFrameX, -tFrameY, tFrameWidth, tFrameHeight); + } + this._mainTexture = tTexture; + var tAniCount = tByte.getUint16(); + var tSectionArr; + for (i = 0; i < tAniCount; i++) { + tSectionArr = []; + tSectionArr.push(tByte.getUint16()); + tSectionArr.push(tByte.getUint16()); + tSectionArr.push(tByte.getUint16()); + tSectionArr.push(tByte.getUint16()); + this.aniSectionDic[i] = tSectionArr; + } + var tBone; + var tParentBone; + var tName; + var tParentName; + var tBoneLen = tByte.getInt16(); + var tBoneDic = {}; + var tRootBone; + for (i = 0; i < tBoneLen; i++) { + tBone = new Bone(); + if (i == 0) { + tRootBone = tBone; + } + else { + tBone.root = tRootBone; + } + tBone.d = isSpine ? -1 : 1; + tName = tByte.readUTFString(); + tParentName = tByte.readUTFString(); + tBone.length = tByte.getFloat32(); + if (tByte.getByte() == 1) { + tBone.inheritRotation = false; + } + if (tByte.getByte() == 1) { + tBone.inheritScale = false; + } + tBone.name = tName; + if (tParentName) { + tParentBone = tBoneDic[tParentName]; + if (tParentBone) { + tParentBone.addChild(tBone); + } + else { + this.mRootBone = tBone; + } + } + tBoneDic[tName] = tBone; + this.mBoneArr.push(tBone); + } + this.tMatrixDataLen = tByte.getUint16(); + var tLen = tByte.getUint16(); + var boneLength = Math.floor(tLen / this.tMatrixDataLen); + var tResultTransform; + var tMatrixArray = this.srcBoneMatrixArr; + for (i = 0; i < boneLength; i++) { + tResultTransform = new Transform(); + tResultTransform.scX = tByte.getFloat32(); + tResultTransform.skX = tByte.getFloat32(); + tResultTransform.skY = tByte.getFloat32(); + tResultTransform.scY = tByte.getFloat32(); + tResultTransform.x = tByte.getFloat32(); + tResultTransform.y = tByte.getFloat32(); + if (this.tMatrixDataLen === 8) { + tResultTransform.skewX = tByte.getFloat32(); + tResultTransform.skewY = tByte.getFloat32(); + } + tMatrixArray.push(tResultTransform); + tBone = this.mBoneArr[i]; + tBone.transform = tResultTransform; + } + var tIkConstraintData; + var tIkLen = tByte.getUint16(); + var tIkBoneLen; + for (i = 0; i < tIkLen; i++) { + tIkConstraintData = new IkConstraintData(); + tIkBoneLen = tByte.getUint16(); + for (j = 0; j < tIkBoneLen; j++) { + tIkConstraintData.boneNames.push(tByte.readUTFString()); + tIkConstraintData.boneIndexs.push(tByte.getInt16()); + } + tIkConstraintData.name = tByte.readUTFString(); + tIkConstraintData.targetBoneName = tByte.readUTFString(); + tIkConstraintData.targetBoneIndex = tByte.getInt16(); + tIkConstraintData.bendDirection = tByte.getFloat32(); + tIkConstraintData.mix = tByte.getFloat32(); + tIkConstraintData.isSpine = isSpine; + this.ikArr.push(tIkConstraintData); + } + var tTfConstraintData; + var tTfLen = tByte.getUint16(); + var tTfBoneLen; + for (i = 0; i < tTfLen; i++) { + tTfConstraintData = new TfConstraintData(); + tTfBoneLen = tByte.getUint16(); + for (j = 0; j < tTfBoneLen; j++) { + tTfConstraintData.boneIndexs.push(tByte.getInt16()); + } + tTfConstraintData.name = tByte.getUTFString(); + tTfConstraintData.targetIndex = tByte.getInt16(); + tTfConstraintData.rotateMix = tByte.getFloat32(); + tTfConstraintData.translateMix = tByte.getFloat32(); + tTfConstraintData.scaleMix = tByte.getFloat32(); + tTfConstraintData.shearMix = tByte.getFloat32(); + tTfConstraintData.offsetRotation = tByte.getFloat32(); + tTfConstraintData.offsetX = tByte.getFloat32(); + tTfConstraintData.offsetY = tByte.getFloat32(); + tTfConstraintData.offsetScaleX = tByte.getFloat32(); + tTfConstraintData.offsetScaleY = tByte.getFloat32(); + tTfConstraintData.offsetShearY = tByte.getFloat32(); + this.tfArr.push(tTfConstraintData); + } + var tPathConstraintData; + var tPathLen = tByte.getUint16(); + var tPathBoneLen; + for (i = 0; i < tPathLen; i++) { + tPathConstraintData = new PathConstraintData(); + tPathConstraintData.name = tByte.readUTFString(); + tPathBoneLen = tByte.getUint16(); + for (j = 0; j < tPathBoneLen; j++) { + tPathConstraintData.bones.push(tByte.getInt16()); + } + tPathConstraintData.target = tByte.readUTFString(); + tPathConstraintData.positionMode = tByte.readUTFString(); + tPathConstraintData.spacingMode = tByte.readUTFString(); + tPathConstraintData.rotateMode = tByte.readUTFString(); + tPathConstraintData.offsetRotation = tByte.getFloat32(); + tPathConstraintData.position = tByte.getFloat32(); + tPathConstraintData.spacing = tByte.getFloat32(); + tPathConstraintData.rotateMix = tByte.getFloat32(); + tPathConstraintData.translateMix = tByte.getFloat32(); + this.pathArr.push(tPathConstraintData); + } + var tDeformSlotLen; + var tDeformSlotDisplayLen; + var tDSlotIndex; + var tDAttachment; + var tDeformTimeLen; + var tDTime; + var tDeformVecticesLen; + var tDeformAniData; + var tDeformSlotData; + var tDeformSlotDisplayData; + var tDeformVectices; + var tDeformAniLen = tByte.getInt16(); + for (i = 0; i < tDeformAniLen; i++) { + var tDeformSkinLen = tByte.getUint8(); + var tSkinDic = {}; + this.deformAniArr.push(tSkinDic); + for (var f = 0; f < tDeformSkinLen; f++) { + tDeformAniData = new DeformAniData(); + tDeformAniData.skinName = tByte.getUTFString(); + tSkinDic[tDeformAniData.skinName] = tDeformAniData; + tDeformSlotLen = tByte.getInt16(); + for (j = 0; j < tDeformSlotLen; j++) { + tDeformSlotData = new DeformSlotData(); + tDeformAniData.deformSlotDataList.push(tDeformSlotData); + tDeformSlotDisplayLen = tByte.getInt16(); + for (k = 0; k < tDeformSlotDisplayLen; k++) { + tDeformSlotDisplayData = new DeformSlotDisplayData(); + tDeformSlotData.deformSlotDisplayList.push(tDeformSlotDisplayData); + tDeformSlotDisplayData.slotIndex = tDSlotIndex = tByte.getInt16(); + tDeformSlotDisplayData.attachment = tDAttachment = tByte.getUTFString(); + tDeformTimeLen = tByte.getInt16(); + for (l = 0; l < tDeformTimeLen; l++) { + if (tByte.getByte() == 1) { + tDeformSlotDisplayData.tweenKeyList.push(true); + } + else { + tDeformSlotDisplayData.tweenKeyList.push(false); + } + tDTime = tByte.getFloat32(); + tDeformSlotDisplayData.timeList.push(tDTime); + tDeformVectices = []; + tDeformSlotDisplayData.vectices.push(tDeformVectices); + tDeformVecticesLen = tByte.getInt16(); + for (n = 0; n < tDeformVecticesLen; n++) { + tDeformVectices.push(tByte.getFloat32()); + } + } + } + } + } + } + var tDrawOrderArr; + var tDrawOrderAniLen = tByte.getInt16(); + var tDrawOrderLen; + var tDrawOrderData; + var tDoLen; + for (i = 0; i < tDrawOrderAniLen; i++) { + tDrawOrderLen = tByte.getInt16(); + tDrawOrderArr = []; + for (j = 0; j < tDrawOrderLen; j++) { + tDrawOrderData = new DrawOrderData(); + tDrawOrderData.time = tByte.getFloat32(); + tDoLen = tByte.getInt16(); + for (k = 0; k < tDoLen; k++) { + tDrawOrderData.drawOrder.push(tByte.getInt16()); + } + tDrawOrderArr.push(tDrawOrderData); + } + this.drawOrderAniArr.push(tDrawOrderArr); + } + var tEventArr; + var tEventAniLen = tByte.getInt16(); + var tEventLen; + var tEventData; + for (i = 0; i < tEventAniLen; i++) { + tEventLen = tByte.getInt16(); + tEventArr = []; + for (j = 0; j < tEventLen; j++) { + tEventData = new EventData(); + tEventData.name = tByte.getUTFString(); + if (this._isParseAudio) + tEventData.audioValue = tByte.getUTFString(); + tEventData.intValue = tByte.getInt32(); + tEventData.floatValue = tByte.getFloat32(); + tEventData.stringValue = tByte.getUTFString(); + tEventData.time = tByte.getFloat32(); + tEventArr.push(tEventData); + } + this.eventAniArr.push(tEventArr); + } + var tAttachmentLen = tByte.getInt16(); + if (tAttachmentLen > 0) { + this.attachmentNames = []; + for (i = 0; i < tAttachmentLen; i++) { + this.attachmentNames.push(tByte.getUTFString()); + } + } + var tBoneSlotLen = tByte.getInt16(); + var tDBBoneSlot; + var tDBBoneSlotArr; + for (i = 0; i < tBoneSlotLen; i++) { + tDBBoneSlot = new BoneSlot(); + tDBBoneSlot.name = tByte.readUTFString(); + tDBBoneSlot.parent = tByte.readUTFString(); + tDBBoneSlot.attachmentName = tByte.readUTFString(); + tDBBoneSlot.srcDisplayIndex = tDBBoneSlot.displayIndex = tByte.getInt16(); + tDBBoneSlot.templet = this; + this.boneSlotDic[tDBBoneSlot.name] = tDBBoneSlot; + tDBBoneSlotArr = this.bindBoneBoneSlotDic[tDBBoneSlot.parent]; + if (tDBBoneSlotArr == null) { + this.bindBoneBoneSlotDic[tDBBoneSlot.parent] = tDBBoneSlotArr = []; + } + tDBBoneSlotArr.push(tDBBoneSlot); + this.boneSlotArray.push(tDBBoneSlot); + } + var tNameString = tByte.readUTFString(); + var tNameArray = tNameString.split("\n"); + var tNameStartIndex = 0; + var tSkinDataLen = tByte.getUint8(); + var tSkinData, tSlotData, tDisplayData; + var tSlotDataLen, tDisplayDataLen; + var tUvLen, tWeightLen, tTriangleLen, tVerticeLen, tLengthLen; + for (i = 0; i < tSkinDataLen; i++) { + tSkinData = new SkinData(); + tSkinData.name = tNameArray[tNameStartIndex++]; + tSlotDataLen = tByte.getUint8(); + for (j = 0; j < tSlotDataLen; j++) { + tSlotData = new SlotData(); + tSlotData.name = tNameArray[tNameStartIndex++]; + tDBBoneSlot = this.boneSlotDic[tSlotData.name]; + tDisplayDataLen = tByte.getUint8(); + for (k = 0; k < tDisplayDataLen; k++) { + tDisplayData = new SkinSlotDisplayData(); + this.skinSlotDisplayDataArr.push(tDisplayData); + tDisplayData.name = tNameArray[tNameStartIndex++]; + tDisplayData.attachmentName = tNameArray[tNameStartIndex++]; + tDisplayData.transform = new Transform(); + tDisplayData.transform.scX = tByte.getFloat32(); + tDisplayData.transform.skX = tByte.getFloat32(); + tDisplayData.transform.skY = tByte.getFloat32(); + tDisplayData.transform.scY = tByte.getFloat32(); + tDisplayData.transform.x = tByte.getFloat32(); + tDisplayData.transform.y = tByte.getFloat32(); + tSlotData.displayArr.push(tDisplayData); + tDisplayData.width = tByte.getFloat32(); + tDisplayData.height = tByte.getFloat32(); + tDisplayData.type = tByte.getUint8(); + tDisplayData.verLen = tByte.getUint16(); + tBoneLen = tByte.getUint16(); + if (tBoneLen > 0) { + tDisplayData.bones = []; + for (l = 0; l < tBoneLen; l++) { + var tBoneId = tByte.getUint16(); + tDisplayData.bones.push(tBoneId); + } + } + tUvLen = tByte.getUint16(); + if (tUvLen > 0) { + tDisplayData.uvs = []; + for (l = 0; l < tUvLen; l++) { + tDisplayData.uvs.push(tByte.getFloat32()); + } + } + tWeightLen = tByte.getUint16(); + if (tWeightLen > 0) { + tDisplayData.weights = []; + for (l = 0; l < tWeightLen; l++) { + tDisplayData.weights.push(tByte.getFloat32()); + } + } + tTriangleLen = tByte.getUint16(); + if (tTriangleLen > 0) { + tDisplayData.triangles = []; + for (l = 0; l < tTriangleLen; l++) { + tDisplayData.triangles.push(tByte.getUint16()); + } + } + tVerticeLen = tByte.getUint16(); + if (tVerticeLen > 0) { + tDisplayData.vertices = []; + for (l = 0; l < tVerticeLen; l++) { + tDisplayData.vertices.push(tByte.getFloat32()); + } + } + tLengthLen = tByte.getUint16(); + if (tLengthLen > 0) { + tDisplayData.lengths = []; + for (l = 0; l < tLengthLen; l++) { + tDisplayData.lengths.push(tByte.getFloat32()); + } + } + } + tSkinData.slotArr.push(tSlotData); + } + this.skinDic[tSkinData.name] = tSkinData; + this.skinDataArray.push(tSkinData); + } + var tReverse = tByte.getUint8(); + if (tReverse == 1) { + this.yReverseMatrix = new Laya.Matrix(1, 0, 0, -1, 0, 0); + if (tRootBone) { + tRootBone.setTempMatrix(this.yReverseMatrix); + } + } + else { + if (tRootBone) { + tRootBone.setTempMatrix(new Laya.Matrix()); + } + } + this.showSkinByIndex(this.boneSlotDic, 0); + this.isParserComplete = true; + this.event(Laya.Event.COMPLETE, this); + } + getTexture(name) { + var tTexture = this.subTextureDic[name]; + if (!tTexture) { + tTexture = this.subTextureDic[name.substr(0, name.length - 1)]; + } + if (tTexture == null) { + return this._mainTexture; + } + return tTexture; + } + showSkinByIndex(boneSlotDic, skinIndex, freshDisplayIndex = true) { + if (skinIndex < 0 && skinIndex >= this.skinDataArray.length) + return false; + var i, n; + var tBoneSlot; + var tSlotData; + var tSkinData = this.skinDataArray[skinIndex]; + if (tSkinData) { + for (i = 0, n = tSkinData.slotArr.length; i < n; i++) { + tSlotData = tSkinData.slotArr[i]; + if (tSlotData) { + tBoneSlot = boneSlotDic[tSlotData.name]; + if (tBoneSlot) { + tBoneSlot.showSlotData(tSlotData, freshDisplayIndex); + if (freshDisplayIndex && tBoneSlot.attachmentName != "undefined" && tBoneSlot.attachmentName != "null") { + tBoneSlot.showDisplayByName(tBoneSlot.attachmentName); + } + else { + tBoneSlot.showDisplayByIndex(tBoneSlot.displayIndex); + } + } + } + } + return true; + } + return false; + } + getSkinIndexByName(skinName) { + var tSkinData; + for (var i = 0, n = this.skinDataArray.length; i < n; i++) { + tSkinData = this.skinDataArray[i]; + if (tSkinData.name == skinName) { + return i; + } + } + return -1; + } + getGrahicsDataWithCache(aniIndex, frameIndex) { + if (this._graphicsCache[aniIndex] && this._graphicsCache[aniIndex][frameIndex]) { + return this._graphicsCache[aniIndex][frameIndex]; + } + return null; + } + _setCreateURL(url) { + this._skBufferUrl = this._relativeUrl = url; + super._setCreateURL(url); + } + setGrahicsDataWithCache(aniIndex, frameIndex, graphics) { + this._graphicsCache[aniIndex][frameIndex] = graphics; + } + deleteAniData(aniIndex) { + if (this._anis[aniIndex]) { + var tAniDataO = this._anis[aniIndex]; + tAniDataO.bone3DMap = null; + tAniDataO.nodes = null; + } + } + destroy() { + this._isDestroyed = true; + var tTexture; + for (tTexture in this.subTextureDic) { + if (tTexture) { + this.subTextureDic[tTexture].destroy(); + } + } + for (tTexture in this._textureDic) { + if (tTexture) { + this._textureDic[tTexture].destroy(); + } + } + var tSkinSlotDisplayData; + for (var i = 0, n = this.skinSlotDisplayDataArr.length; i < n; i++) { + tSkinSlotDisplayData = this.skinSlotDisplayDataArr[i]; + tSkinSlotDisplayData.destory(); + } + this.skinSlotDisplayDataArr.length = 0; + if (this._relativeUrl) { + delete Templet.TEMPLET_DICTIONARY[this._relativeUrl]; + } + super.destroy(); + Laya.ILaya.loader.clearRes(this._skBufferUrl); + } + getAniNameByIndex(index) { + var tAni = this.getAnimation(index); + if (tAni) + return tAni.name; + return null; + } + get rate() { + return this._rate; + } + set rate(v) { + this._rate = v; + } + } + Templet.LAYA_ANIMATION_160_VISION = "LAYAANIMATION:1.6.0"; + Templet.LAYA_ANIMATION_VISION = "LAYAANIMATION:1.7.0"; + IAniLib.Templet = Templet; + + class MovieClip extends Laya.Sprite { + constructor(parentMovieClip = null) { + super(); + this._start = 0; + this._Pos = 0; + this._ended = true; + this._loadedImage = {}; + this._endFrame = -1; + this.interval = 30; + this._ids = {}; + this._idOfSprite = []; + this._reset(); + this._playing = false; + this._parentMovieClip = parentMovieClip; + if (!parentMovieClip) { + this._movieClipList = [this]; + this._isRoot = true; + this._setBitUp(Laya.Const.DISPLAY); + } + else { + this._isRoot = false; + this._movieClipList = parentMovieClip._movieClipList; + this._movieClipList.push(this); + } + } + destroy(destroyChild = true) { + this._clear(); + super.destroy(destroyChild); + } + _setDisplay(value) { + super._setDisplay(value); + if (this._isRoot) { + this._onDisplay(value); + } + } + _onDisplay(value) { + if (value) + this.timer.loop(this.interval, this, this.updates, null, true); + else + this.timer.clear(this, this.updates); + } + updates() { + if (this._parentMovieClip) + return; + var i, len; + len = this._movieClipList.length; + for (i = 0; i < len; i++) { + this._movieClipList[i] && this._movieClipList[i]._update(); + } + } + get index() { + return this._playIndex; + } + set index(value) { + this._playIndex = value; + if (this._data) + this._displayFrame(this._playIndex); + if (this._labels && this._labels[value]) + this.event(Laya.Event.LABEL, this._labels[value]); + } + addLabel(label, index) { + if (!this._labels) + this._labels = {}; + this._labels[index] = label; + } + removeLabel(label) { + if (!label) + this._labels = null; + else if (!this._labels) { + for (var name in this._labels) { + if (this._labels[name] === label) { + delete this._labels[name]; + break; + } + } + } + } + get count() { + return this._count; + } + get playing() { + return this._playing; + } + _update() { + if (!this._data) + return; + if (!this._playing) + return; + this._playIndex++; + if (this._playIndex >= this._count) { + if (!this.loop) { + this._playIndex--; + this.stop(); + return; + } + this._playIndex = 0; + } + this._parseFrame(this._playIndex); + if (this._labels && this._labels[this._playIndex]) + this.event(Laya.Event.LABEL, this._labels[this._playIndex]); + if (this._endFrame != -1 && this._endFrame == this._playIndex) { + this._endFrame = -1; + if (this._completeHandler != null) { + var handler = this._completeHandler; + this._completeHandler = null; + handler.run(); + } + this.stop(); + } + } + stop() { + this._playing = false; + } + gotoAndStop(index) { + this.index = index; + this.stop(); + } + _clear() { + this.stop(); + this._idOfSprite.length = 0; + if (!this._parentMovieClip) { + this.timer.clear(this, this.updates); + var i, len; + len = this._movieClipList.length; + for (i = 0; i < len; i++) { + if (this._movieClipList[i] != this) + this._movieClipList[i]._clear(); + } + this._movieClipList.length = 0; + } + if (this._atlasPath) { + Laya.ILaya.Loader.clearRes(this._atlasPath); + } + var key; + for (key in this._loadedImage) { + if (this._loadedImage[key]) { + Laya.ILaya.Loader.clearRes(key); + this._loadedImage[key] = false; + } + } + this.removeChildren(); + this.graphics = null; + this._parentMovieClip = null; + } + play(index = 0, loop = true) { + this.loop = loop; + this._playing = true; + if (this._data) + this._displayFrame(index); + } + _displayFrame(frameIndex = -1) { + if (frameIndex != -1) { + if (this._curIndex > frameIndex) + this._reset(); + this._parseFrame(frameIndex); + } + } + _reset(rm = true) { + if (rm && this._curIndex != 1) + this.removeChildren(); + this._preIndex = this._curIndex = -1; + this._Pos = this._start; + } + _parseFrame(frameIndex) { + var mc, sp, key, type, tPos, ttype, ifAdd = false; + var _idOfSprite = this._idOfSprite, _data = this._data, eStr; + if (this._ended) + this._reset(); + _data.pos = this._Pos; + this._ended = false; + this._playIndex = frameIndex; + if (this._curIndex > frameIndex && frameIndex < this._preIndex) { + this._reset(true); + _data.pos = this._Pos; + } + while ((this._curIndex <= frameIndex) && (!this._ended)) { + type = _data.getUint16(); + switch (type) { + case 12: + key = _data.getUint16(); + tPos = this._ids[_data.getUint16()]; + this._Pos = _data.pos; + _data.pos = tPos; + if ((ttype = _data.getUint8()) == 0) { + var pid = _data.getUint16(); + sp = _idOfSprite[key]; + if (!sp) { + sp = _idOfSprite[key] = new Laya.Sprite(); + var spp = new Laya.Sprite(); + spp.loadImage(this.basePath + pid + ".png"); + this._loadedImage[this.basePath + pid + ".png"] = true; + sp.addChild(spp); + spp.size(_data.getFloat32(), _data.getFloat32()); + var mat = _data._getMatrix(); + spp.transform = mat; + } + sp.alpha = 1; + } + else if (ttype == 1) { + mc = _idOfSprite[key]; + if (!mc) { + _idOfSprite[key] = mc = new MovieClip(this); + mc.interval = this.interval; + mc._ids = this._ids; + mc.basePath = this.basePath; + mc._setData(_data, tPos); + mc._initState(); + mc.play(0); + } + mc.alpha = 1; + } + _data.pos = this._Pos; + break; + case 3: + var node = _idOfSprite[_data.getUint16()]; + if (node) { + this.addChild(node); + node.zOrder = _data.getUint16(); + ifAdd = true; + } + break; + case 4: + node = _idOfSprite[_data.getUint16()]; + node && node.removeSelf(); + break; + case 5: + _idOfSprite[_data.getUint16()][MovieClip._ValueList[_data.getUint16()]] = (_data.getFloat32()); + break; + case 6: + _idOfSprite[_data.getUint16()].visible = (_data.getUint8() > 0); + break; + case 7: + sp = _idOfSprite[_data.getUint16()]; + var mt = sp.transform || Laya.Matrix.create(); + mt.setTo(_data.getFloat32(), _data.getFloat32(), _data.getFloat32(), _data.getFloat32(), _data.getFloat32(), _data.getFloat32()); + sp.transform = mt; + break; + case 8: + _idOfSprite[_data.getUint16()].setPos(_data.getFloat32(), _data.getFloat32()); + break; + case 9: + _idOfSprite[_data.getUint16()].setSize(_data.getFloat32(), _data.getFloat32()); + break; + case 10: + _idOfSprite[_data.getUint16()].alpha = _data.getFloat32(); + break; + case 11: + _idOfSprite[_data.getUint16()].setScale(_data.getFloat32(), _data.getFloat32()); + break; + case 98: + eStr = _data.getString(); + this.event(eStr); + if (eStr == "stop") + this.stop(); + break; + case 99: + this._curIndex = _data.getUint16(); + ifAdd && this.updateZOrder(); + break; + case 100: + this._count = this._curIndex + 1; + this._ended = true; + if (this._playing) { + this.event(Laya.Event.FRAME); + this.event(Laya.Event.END); + this.event(Laya.Event.COMPLETE); + } + this._reset(false); + break; + } + } + if (this._playing && !this._ended) + this.event(Laya.Event.FRAME); + this._Pos = _data.pos; + } + _setData(data, start) { + this._data = data; + this._start = start + 3; + } + set url(path) { + this.load(path); + } + load(url, atlas = false, atlasPath = null) { + this._url = url; + if (atlas) + this._atlasPath = atlasPath ? atlasPath : url.split(".swf")[0] + ".json"; + this.stop(); + this._clear(); + this._movieClipList = [this]; + var urls; + urls = [{ url: url, type: Laya.ILaya.Loader.BUFFER }]; + if (this._atlasPath) { + urls.push({ url: this._atlasPath, type: Laya.ILaya.Loader.ATLAS }); + } + Laya.ILaya.loader.load(urls, Laya.Handler.create(this, this._onLoaded)); + } + _onLoaded() { + var data; + data = Laya.ILaya.Loader.getRes(this._url); + if (!data) { + this.event(Laya.Event.ERROR, "file not find"); + return; + } + if (this._atlasPath && !Laya.ILaya.Loader.getAtlas(this._atlasPath)) { + this.event(Laya.Event.ERROR, "Atlas not find"); + return; + } + this.basePath = this._atlasPath ? Laya.ILaya.Loader.getAtlas(this._atlasPath).dir : this._url.split(".swf")[0] + "/image/"; + this._initData(data); + } + _initState() { + this._reset(); + this._ended = false; + var preState = this._playing; + this._playing = false; + this._curIndex = 0; + while (!this._ended) + this._parseFrame(++this._curIndex); + this._playing = preState; + } + _initData(data) { + this._data = new Laya.Byte(data); + var i, len = this._data.getUint16(); + for (i = 0; i < len; i++) + this._ids[this._data.getInt16()] = this._data.getInt32(); + this.interval = 1000 / this._data.getUint16(); + this._setData(this._data, this._ids[32767]); + this._initState(); + this.play(0); + this.event(Laya.Event.LOADED); + if (!this._parentMovieClip) + this.timer.loop(this.interval, this, this.updates, null, true); + } + playTo(start, end, complete = null) { + this._completeHandler = complete; + this._endFrame = end; + this.play(start, false); + } + } + MovieClip._ValueList = ["x", "y", "width", "height", "scaleX", "scaleY", "rotation", "alpha"]; + + exports.AnimationContent = AnimationContent; + exports.AnimationNodeContent = AnimationNodeContent; + exports.AnimationParser01 = AnimationParser01; + exports.AnimationParser02 = AnimationParser02; + exports.AnimationPlayer = AnimationPlayer; + exports.AnimationState = AnimationState; + exports.AnimationTemplet = AnimationTemplet; + exports.BezierLerp = BezierLerp; + exports.Bone = Bone; + exports.BoneSlot = BoneSlot; + exports.DeformAniData = DeformAniData; + exports.DeformSlotData = DeformSlotData; + exports.DeformSlotDisplayData = DeformSlotDisplayData; + exports.DrawOrderData = DrawOrderData; + exports.EventData = EventData; + exports.GraphicsAni = GraphicsAni; + exports.IAniLib = IAniLib; + exports.IkConstraint = IkConstraint; + exports.IkConstraintData = IkConstraintData; + exports.KeyFramesContent = KeyFramesContent; + exports.MeshData = MeshData; + exports.MovieClip = MovieClip; + exports.PathConstraint = PathConstraint; + exports.PathConstraintData = PathConstraintData; + exports.Skeleton = Skeleton; + exports.SkinData = SkinData; + exports.SkinMeshForGraphic = SkinMeshForGraphic; + exports.SkinSlotDisplayData = SkinSlotDisplayData; + exports.SlotData = SlotData; + exports.Templet = Templet; + exports.TfConstraint = TfConstraint; + exports.TfConstraintData = TfConstraintData; + exports.Transform = Transform; + exports.UVTools = UVTools; + +}(window.Laya = window.Laya || {}, Laya)); diff --git a/examples/layaair/frontend/bin/libs/laya.bdmini.js b/examples/layaair/frontend/bin/libs/laya.bdmini.js new file mode 100644 index 0000000..ab5ebfa --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.bdmini.js @@ -0,0 +1,1829 @@ +window.bdMiniGame = function (exports, Laya) { + 'use strict'; + + class MiniFileMgr { + static isLocalNativeFile(url) { + for (var i = 0, sz = BMiniAdapter.nativefiles.length; i < sz; i++) { + if (url.indexOf(BMiniAdapter.nativefiles[i]) != -1) + return true; + } + return false; + } + static isNetFile(url) { + return (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) && url.indexOf(BMiniAdapter.window.swan.env.USER_DATA_PATH) == -1; + } + static getFileInfo(fileUrl) { + var fileNativePath = fileUrl; + var fileObj = MiniFileMgr.fakeObj[fileNativePath]; + if (fileObj == null) + return null; + else + return fileObj; + } + static read(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "") { + var fileUrl; + if (readyUrl != "" && (readyUrl.indexOf("http://") != -1 || readyUrl.indexOf("https://") != -1)) { + fileUrl = MiniFileMgr.getFileNativePath(filePath); + } + else { + fileUrl = filePath; + } + fileUrl = Laya.URL.getAdptedFilePath(fileUrl); + MiniFileMgr.fs.readFile({ filePath: fileUrl, encoding: encoding, success: function (data) { + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data && readyUrl != "") + MiniFileMgr.downFiles(encodeURI(readyUrl), encoding, callBack, readyUrl, isSaveFile, fileType); + else + callBack != null && callBack.runWith([1]); + } }); + } + static isFile(url) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(url); + } + catch (err) { + return false; + } + return stat.isFile(); + } + static downFiles(fileUrl, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + var downloadTask = MiniFileMgr.down({ url: fileUrl, success: function (data) { + if (data.statusCode === 200) + MiniFileMgr.readFile(data.tempFilePath, encoding, callBack, readyUrl, isSaveFile, fileType, isAutoClear); + else if (data.statusCode === 403) { + callBack != null && callBack.runWith([0, fileUrl]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + downloadTask.onProgressUpdate(function (data) { + callBack != null && callBack.runWith([2, data.progress]); + }); + } + static readFile(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + filePath = Laya.URL.getAdptedFilePath(filePath); + MiniFileMgr.fs.readFile({ filePath: filePath, encoding: encoding, success: function (data) { + if ((filePath.indexOf("http://") != -1 || filePath.indexOf("https://") != -1) && filePath.indexOf(BMiniAdapter.window.swan.env.USER_DATA_PATH) == -1) { + if (BMiniAdapter.AutoCacheDownFile || isSaveFile) { + callBack != null && callBack.runWith([0, data]); + MiniFileMgr.copyTOCache(filePath, readyUrl, null, encoding, isAutoClear); + } + else + callBack != null && callBack.runWith([0, data]); + } + else + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data) + callBack != null && callBack.runWith([1, data]); + } }); + } + static downOtherFiles(fileUrl, callBack = null, readyUrl = "", isSaveFile = false, isAutoClear = true) { + MiniFileMgr.down({ url: fileUrl, success: function (data) { + if (data.statusCode === 200) { + if ((BMiniAdapter.autoCacheFile || isSaveFile) && readyUrl.indexOf(".php") == -1) { + callBack != null && callBack.runWith([0, data.tempFilePath]); + MiniFileMgr.copyTOCache(data.tempFilePath, readyUrl, null, "", isAutoClear); + } + else + callBack != null && callBack.runWith([0, data.tempFilePath]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static copyFile(src, dest, complete = null) { + MiniFileMgr.fs.copyFile({ + srcPath: src, + destPath: dest, + success: function () { + complete && complete.runWith(0); + }, + fail: function (err) { + complete && complete.runWith([1, err]); + } + }); + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + if (window.navigator.userAgent.indexOf('SwanGame') < 0) { + Laya.Laya.loader.load(fileUrl, callBack); + } + else { + if (fileType == Laya.Loader.IMAGE || fileType == Laya.Loader.SOUND) + MiniFileMgr.downOtherFiles(fileUrl, callBack, fileUrl, true, false); + else + MiniFileMgr.downFiles(fileUrl, encoding, callBack, fileUrl, true, fileType, false); + } + } + static copyTOCache(tempFilePath, readyUrl, callBack, encoding = "", isAutoClear = true) { + var temp = tempFilePath.split("/"); + var tempFileName = temp[temp.length - 1]; + var fileurlkey = readyUrl; + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fakeObj[fileurlkey] = { md5: tempFileName, readyUrl: readyUrl, size: 0, times: Laya.Browser.now(), encoding: encoding, tempFilePath: tempFilePath }; + var totalSize = BMiniAdapter.sizeLimit; + var chaSize = 4 * 1024 * 1024; + var fileUseSize = MiniFileMgr.getCacheUseSize(); + if (fileObj) { + if (fileObj.readyUrl != readyUrl) { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > BMiniAdapter.minClearSize) + BMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.deleteFile(tempFilePath, readyUrl, callBack, encoding, data.size); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + else + callBack != null && callBack.runWith([0]); + } + else { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > BMiniAdapter.minClearSize) + BMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.fs.copyFile({ srcPath: tempFilePath, destPath: saveFilePath, success: function (data2) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, data.size); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + } + static onClearCacheRes() { + var memSize = BMiniAdapter.minClearSize; + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + MiniFileMgr.sortOn(tempFileListArr, "times", MiniFileMgr.NUMERIC); + var clearSize = 0; + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + if (clearSize >= memSize) + break; + clearSize += fileObj.size; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + } + static sortOn(array, name, options = 0) { + if (options == MiniFileMgr.NUMERIC) + return array.sort(function (a, b) { return a[name] - b[name]; }); + if (options == (MiniFileMgr.NUMERIC | MiniFileMgr.DESCENDING)) + return array.sort(function (a, b) { return b[name] - a[name]; }); + return array.sort(function (a, b) { return a[name] - b[name]; }); + } + static getFileNativePath(fileName) { + return MiniFileMgr.fileNativeDir + "/" + fileName; + } + static deleteFile(tempFileName, readyUrl = "", callBack = null, encoding = "", fileSize = 0) { + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var deleteFileUrl = MiniFileMgr.getFileNativePath(fileObj.md5); + MiniFileMgr.fs.unlink({ filePath: deleteFileUrl, success: function (data) { + if (tempFileName != "") { + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fs.copyFile({ srcPath: tempFileName, destPath: saveFilePath, success: function (data) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, fileSize); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + else { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, false, encoding, callBack, fileSize); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static deleteAll() { + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj.fileUsedSize) { + MiniFileMgr.filesListObj.fileUsedSize = 0; + } + MiniFileMgr.writeFilesList("", JSON.stringify({}), false); + } + static onSaveFile(readyUrl, md5Name, isAdd = true, encoding = "", callBack = null, fileSize = 0) { + var fileurlkey = readyUrl; + if (MiniFileMgr.filesListObj['fileUsedSize'] == null) + MiniFileMgr.filesListObj['fileUsedSize'] = 0; + if (isAdd) { + var fileNativeName = MiniFileMgr.getFileNativePath(md5Name); + MiniFileMgr.filesListObj[fileurlkey] = { md5: md5Name, readyUrl: readyUrl, size: fileSize, times: Laya.Browser.now(), encoding: encoding, tempFilePath: fileNativeName }; + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) + fileSize; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), true); + callBack != null && callBack.runWith([0]); + } + else { + if (MiniFileMgr.filesListObj[fileurlkey]) { + var deletefileSize = parseInt(MiniFileMgr.filesListObj[fileurlkey].size); + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) - deletefileSize; + if (MiniFileMgr.fakeObj[fileurlkey].md5 == MiniFileMgr.filesListObj[fileurlkey].md5) { + delete MiniFileMgr.fakeObj[fileurlkey]; + } + delete MiniFileMgr.filesListObj[fileurlkey]; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), false); + callBack != null && callBack.runWith([0]); + } + } + } + static writeFilesList(fileurlkey, filesListStr, isAdd) { + var listFilesPath = MiniFileMgr.fileNativeDir + "/" + MiniFileMgr.fileListName; + MiniFileMgr.fs.writeFile({ filePath: listFilesPath, encoding: 'utf8', data: filesListStr, success: function (data) { + }, fail: function (data) { + } }); + if (!BMiniAdapter.isZiYu && BMiniAdapter.isPosMsgYu) { + BMiniAdapter.window.swan.postMessage({ url: fileurlkey, data: MiniFileMgr.filesListObj[fileurlkey], isLoad: "filenative", isAdd: isAdd }); + } + } + static getCacheUseSize() { + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj['fileUsedSize']) + return MiniFileMgr.filesListObj['fileUsedSize']; + return 0; + } + static getCacheList(dirPath, cb) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(dirPath); + } + catch (err) { + stat = null; + } + if (stat) { + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", cb); + } + else { + MiniFileMgr.fs.mkdirSync(dirPath, true); + cb && cb.runWith([1]); + } + } + static existDir(dirPath, callBack) { + MiniFileMgr.fs.mkdir({ dirPath: dirPath, success: function (data) { + callBack != null && callBack.runWith([0, { data: JSON.stringify({}) }]); + }, fail: function (data) { + if (data.errMsg.indexOf("file already exists") != -1) + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", callBack); + else + callBack != null && callBack.runWith([1, data]); + } }); + } + static readSync(filePath, encoding = "utf8", callBack = null, readyUrl = "") { + var fileUrl = MiniFileMgr.getFileNativePath(filePath); + var filesListStr; + try { + filesListStr = MiniFileMgr.fs.readFileSync(fileUrl, encoding); + callBack != null && callBack.runWith([0, { data: filesListStr }]); + } + catch (error) { + callBack != null && callBack.runWith([1]); + } + } + static setNativeFileDir(value) { + MiniFileMgr.fileNativeDir = BMiniAdapter.window.swan.env.USER_DATA_PATH + value; + } + } + MiniFileMgr.fs = window.swan.getFileSystemManager(); + MiniFileMgr.down = window.swan.downloadFile; + MiniFileMgr.filesListObj = {}; + MiniFileMgr.fakeObj = {}; + MiniFileMgr.fileListName = "layaairfiles.txt"; + MiniFileMgr.ziyuFileData = {}; + MiniFileMgr.ziyuFileTextureData = {}; + MiniFileMgr.loadPath = ""; + MiniFileMgr.DESCENDING = 2; + MiniFileMgr.NUMERIC = 16; + + class MiniSoundChannel extends Laya.SoundChannel { + constructor(audio, miniSound) { + super(); + this._audio = audio; + this._miniSound = miniSound; + this._onEnd = MiniSoundChannel.bindToThis(this.__onEnd, this); + audio.onEnded(this._onEnd); + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + __onEnd() { + if (this.loops == 1) { + if (this.completeHandler) { + Laya.Laya.systemTimer.once(10, this, this.__runComplete, [this.completeHandler], false); + this.completeHandler = null; + } + this.stop(); + this.event(Laya.Event.COMPLETE); + return; + } + if (this.loops > 0) { + this.loops--; + } + this.startTime = 0; + this.play(); + } + play() { + this.isStopped = false; + Laya.SoundManager.addChannel(this); + this._audio.play(); + } + set startTime(time) { + if (this._audio) { + this._audio.startTime = time; + } + } + set autoplay(value) { + this._audio.autoplay = value; + } + get autoplay() { + return this._audio.autoplay; + } + get position() { + if (!this._audio) + return 0; + return this._audio.currentTime; + } + get duration() { + if (!this._audio) + return 0; + return this._audio.duration; + } + stop() { + this.isStopped = true; + Laya.SoundManager.removeChannel(this); + this.completeHandler = null; + if (!this._audio) + return; + this._audio.stop(); + if (!this.loop) { + this._audio.offEnded(null); + this._miniSound.dispose(); + this._audio = null; + this._miniSound = null; + this._onEnd = null; + } + } + pause() { + this.isStopped = true; + this._audio.pause(); + } + get loop() { + return this._audio.loop; + } + set loop(value) { + this._audio.loop = value; + } + resume() { + if (!this._audio) + return; + this.isStopped = false; + Laya.SoundManager.addChannel(this); + this._audio.play(); + } + set volume(v) { + if (!this._audio) + return; + this._audio.volume = v; + } + get volume() { + if (!this._audio) + return 1; + return this._audio.volume; + } + } + + class MiniSound extends Laya.EventDispatcher { + constructor() { + super(); + this.loaded = false; + } + static _createSound() { + MiniSound._id++; + return BMiniAdapter.window.swan.createInnerAudioContext(); + } + load(url) { + if (!MiniSound._musicAudio) + MiniSound._musicAudio = MiniSound._createSound(); + if (!MiniFileMgr.isLocalNativeFile(url)) { + url = Laya.URL.formatURL(url); + } + else { + if (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + if (tempStr != "") + url = url.split(tempStr)[1]; + } + } + } + this.url = url; + this.readyUrl = url; + if (MiniSound._audioCache[this.readyUrl]) { + this.event(Laya.Event.COMPLETE); + return; + } + if (BMiniAdapter.autoCacheFile && MiniFileMgr.getFileInfo(url)) { + this.onDownLoadCallBack(url, 0); + } + else { + if (!BMiniAdapter.autoCacheFile) { + this.onDownLoadCallBack(url, 0); + } + else { + if (MiniFileMgr.isLocalNativeFile(url)) { + tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + if (BMiniAdapter.subNativeFiles && BMiniAdapter.subNativeheads.length == 0) { + for (var key in BMiniAdapter.subNativeFiles) { + var tempArr = BMiniAdapter.subNativeFiles[key]; + BMiniAdapter.subNativeheads = BMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + BMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (BMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && BMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = BMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + this.onDownLoadCallBack(url, 0); + } + else { + if (!MiniFileMgr.isLocalNativeFile(url) && (url.indexOf("http://") == -1 && url.indexOf("https://") == -1) || (url.indexOf(BMiniAdapter.window.swan.env.USER_DATA_PATH) != -1)) { + this.onDownLoadCallBack(url, 0); + } + else { + MiniFileMgr.downOtherFiles(encodeURI(url), Laya.Handler.create(this, this.onDownLoadCallBack, [url]), url); + } + } + } + } + } + onDownLoadCallBack(sourceUrl, errorCode) { + if (!errorCode) { + var fileNativeUrl; + if (BMiniAdapter.autoCacheFile) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = sourceUrl; + if (tempStr != "" && (sourceUrl.indexOf("http://") != -1 || sourceUrl.indexOf("https://") != -1)) + fileNativeUrl = sourceUrl.split(tempStr)[1]; + if (!fileNativeUrl) { + fileNativeUrl = tempUrl; + } + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + var fileMd5Name = fileObj.md5; + fileNativeUrl = MiniFileMgr.getFileNativePath(fileMd5Name); + } + else { + fileNativeUrl = sourceUrl; + } + } + if (this.url != Laya.SoundManager._bgMusic) { + this._sound = MiniSound._createSound(); + this._sound.src = this.url = fileNativeUrl; + } + else { + this._sound = MiniSound._musicAudio; + this._sound.src = this.url = fileNativeUrl; + } + } + else { + if (this.url != Laya.SoundManager._bgMusic) { + this._sound = MiniSound._createSound(); + this._sound.src = sourceUrl; + } + else { + this._sound = MiniSound._musicAudio; + this._sound.src = sourceUrl; + } + } + this._sound.onCanplay(MiniSound.bindToThis(this.onCanPlay, this)); + this._sound.onError(MiniSound.bindToThis(this.onError, this)); + } + else { + this.event(Laya.Event.ERROR); + } + } + onError(error) { + try { + console.log("-----1---------------minisound-----id:" + MiniSound._id); + console.log(error); + } + catch (error) { + console.log("-----2---------------minisound-----id:" + MiniSound._id); + console.log(error); + } + this.event(Laya.Event.ERROR); + this._sound.offError(null); + } + onCanPlay() { + this.loaded = true; + this.event(Laya.Event.COMPLETE); + this._sound.offCanplay(null); + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + play(startTime = 0, loops = 0) { + var tSound; + if (this.url == Laya.SoundManager._bgMusic) { + if (!MiniSound._musicAudio) + MiniSound._musicAudio = MiniSound._createSound(); + tSound = MiniSound._musicAudio; + } + else { + if (MiniSound._audioCache[this.readyUrl]) { + tSound = MiniSound._audioCache[this.readyUrl]._sound; + } + else { + tSound = MiniSound._createSound(); + } + } + if (!tSound) + return null; + if (BMiniAdapter.autoCacheFile && MiniFileMgr.getFileInfo(this.url)) { + var fileObj = MiniFileMgr.getFileInfo(this.url); + var fileMd5Name = fileObj.md5; + tSound.src = this.url = MiniFileMgr.getFileNativePath(fileMd5Name); + } + else { + tSound.src = encodeURI(this.url); + } + var channel = new MiniSoundChannel(tSound, this); + channel.url = this.url; + channel.loops = loops; + channel.loop = (loops === 0 ? true : false); + channel.startTime = startTime; + channel.play(); + Laya.SoundManager.addChannel(channel); + return channel; + } + get duration() { + return this._sound.duration; + } + dispose() { + var ad = MiniSound._audioCache[this.readyUrl]; + if (ad) { + ad.src = ""; + if (ad._sound) { + ad._sound.destroy(); + ad._sound = null; + ad = null; + } + delete MiniSound._audioCache[this.readyUrl]; + } + if (this._sound) { + this._sound.destroy(); + this._sound = null; + this.readyUrl = this.url = null; + } + } + } + MiniSound._id = 0; + MiniSound._audioCache = {}; + + class MiniInput { + constructor() { + } + static _createInputElement() { + Laya.Input['_initInput'](Laya.Input['area'] = Laya.Browser.createElement("textarea")); + Laya.Input['_initInput'](Laya.Input['input'] = Laya.Browser.createElement("input")); + Laya.Input['inputContainer'] = Laya.Browser.createElement("div"); + Laya.Input['inputContainer'].style.position = "absolute"; + Laya.Input['inputContainer'].style.zIndex = 1E5; + Laya.Browser.container.appendChild(Laya.Input['inputContainer']); + Laya.Laya.stage.on("resize", null, MiniInput._onStageResize); + BMiniAdapter.window.swan.onWindowResize && BMiniAdapter.window.swan.onWindowResize(function (res) { + }); + Laya.SoundManager._soundClass = MiniSound; + Laya.SoundManager._musicClass = MiniSound; + var model = BMiniAdapter.systemInfo.model; + var system = BMiniAdapter.systemInfo.system; + if (model.indexOf("iPhone") != -1) { + Laya.Browser.onIPhone = true; + Laya.Browser.onIOS = true; + Laya.Browser.onIPad = true; + Laya.Browser.onAndroid = false; + } + if (system.indexOf("Android") != -1 || system.indexOf("Adr") != -1) { + Laya.Browser.onAndroid = true; + Laya.Browser.onIPhone = false; + Laya.Browser.onIOS = false; + Laya.Browser.onIPad = false; + } + } + static _onStageResize() { + var ts = Laya.Laya.stage._canvasTransform.identity(); + ts.scale((Laya.Browser.width / Laya.Render.canvas.width / Laya.Browser.pixelRatio), Laya.Browser.height / Laya.Render.canvas.height / Laya.Browser.pixelRatio); + } + static wxinputFocus(e) { + var _inputTarget = Laya.Input['inputElement'].target; + if (_inputTarget && !_inputTarget.editable) { + return; + } + BMiniAdapter.window.swan.offKeyboardConfirm(); + BMiniAdapter.window.swan.offKeyboardInput(); + BMiniAdapter.window.swan.showKeyboard({ defaultValue: _inputTarget.text, maxLength: _inputTarget.maxChars, multiple: _inputTarget.multiline, confirmHold: true, confirmType: _inputTarget["confirmType"] || 'done', success: function (res) { + }, fail: function (res) { + } }); + BMiniAdapter.window.swan.onKeyboardConfirm(function (res) { + var str = res ? res.value : ""; + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + MiniInput.inputEnter(); + _inputTarget.event("confirm"); + }); + BMiniAdapter.window.swan.onKeyboardInput(function (res) { + var str = res ? res.value : ""; + if (!_inputTarget.multiline) { + if (str.indexOf("\n") != -1) { + MiniInput.inputEnter(); + return; + } + } + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + }); + } + static inputEnter() { + Laya.Input['inputElement'].target.focus = false; + } + static wxinputblur() { + MiniInput.hideKeyboard(); + } + static hideKeyboard() { + BMiniAdapter.window.swan.offKeyboardConfirm(); + BMiniAdapter.window.swan.offKeyboardInput(); + BMiniAdapter.window.swan.hideKeyboard({ success: function (res) { + console.log('隐藏键盘'); + }, fail: function (res) { + console.log("隐藏键盘出错:" + (res ? res.errMsg : "")); + } }); + } + } + + class MiniLoader extends Laya.EventDispatcher { + constructor() { + super(); + } + _loadResourceFilter(type, url) { + var thisLoader = this; + this.sourceUrl = Laya.URL.formatURL(url); + if (MiniFileMgr.isNetFile(url)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (BMiniAdapter.subNativeFiles && BMiniAdapter.subNativeheads.length == 0) { + for (var key in BMiniAdapter.subNativeFiles) { + var tempArr = BMiniAdapter.subNativeFiles[key]; + BMiniAdapter.subNativeheads = BMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + BMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (BMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && BMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = BMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + switch (type) { + case Laya.Loader.IMAGE: + case "htmlimage": + case "nativeimage": + MiniLoader._transformImgUrl(url, type, thisLoader); + break; + case Laya.Loader.SOUND: + thisLoader._loadSound(url); + break; + default: + thisLoader._loadResource(type, url); + } + } + _loadSound(url) { + var thisLoader = this; + if (!BMiniAdapter.autoCacheFile) { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + else { + var tempurl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downOtherFiles(encodeURI(tempurl), Laya.Handler.create(MiniLoader, MiniLoader.onDownLoadCallBack, [tempurl, thisLoader]), tempurl); + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + } + static onDownLoadCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = null) { + if (!errorCode) { + var fileNativeUrl; + if (BMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + fileNativeUrl = sourceUrl; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + } + else { + fileNativeUrl = Laya.URL.formatURL(sourceUrl); + } + sourceUrl = fileNativeUrl; + var sound = (new Laya.SoundManager._soundClass()); + sound.load(encodeURI(sourceUrl)); + thisLoader.onLoaded(sound); + } + else { + thisLoader.event(Laya.Event.ERROR, "Load sound failed"); + } + } + complete(data) { + if (data instanceof Laya.Resource) { + data._setCreateURL(this.sourceUrl); + } + else if ((data instanceof Laya.Texture) && (data.bitmap instanceof Laya.Resource)) { + data.bitmap._setCreateURL(this.sourceUrl); + } + this.originComplete(data); + } + _loadHttpRequestWhat(url, contentType) { + var thisLoader = this; + var encoding = BMiniAdapter.getUrlEncode(url, contentType); + if (Laya.Loader.preLoadedMap[url]) + thisLoader.onLoaded(Laya.Loader.preLoadedMap[url]); + else { + var tempurl = Laya.URL.formatURL(url); + if (!BMiniAdapter.AutoCacheDownFile) { + if (MiniFileMgr.isNetFile(tempurl)) { + thisLoader._loadHttpRequest(tempurl, contentType, thisLoader, thisLoader.onLoaded, thisLoader, thisLoader.onProgress, thisLoader, thisLoader.onError); + } + else + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + else { + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downFiles(encodeURI(tempurl), encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), tempurl, true); + } + else { + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + else { + var tempUrl = url; + var fileObj = MiniFileMgr.getFileInfo(tempurl); + if (fileObj && fileObj.md5) { + tempUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + MiniFileMgr.readFile(tempUrl, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + } + } + static onReadNativeCallBack(url, type = null, thisLoader = null, errorCode = 0, data = null) { + if (!errorCode) { + var tempData; + if (type == Laya.Loader.JSON || type == Laya.Loader.ATLAS || type == Laya.Loader.PREFAB || type == Laya.Loader.PLF) { + tempData = BMiniAdapter.getJson(data.data); + } + else if (type == Laya.Loader.XML) { + tempData = Laya.Utils.parseXMLFromString(data.data); + } + else { + tempData = data.data; + } + if (!BMiniAdapter.isZiYu && BMiniAdapter.isPosMsgYu && type != Laya.Loader.BUFFER) { + BMiniAdapter.window.swan.postMessage({ url: url, data: tempData, isLoad: "filedata" }); + } + thisLoader.onLoaded(tempData); + } + else if (errorCode == 1) { + thisLoader._loadHttpRequest(url, type, thisLoader, thisLoader.onLoaded, thisLoader, thisLoader.onProgress, thisLoader, thisLoader.onError); + } + } + static _transformImgUrl(url, type, thisLoader) { + if (BMiniAdapter.isZiYu || MiniFileMgr.isLocalNativeFile(url)) { + thisLoader._loadImage(url, false); + return; + } + if (!BMiniAdapter.autoCacheFile) { + thisLoader._loadImage(encodeURI(url)); + } + else { + var tempUrl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempUrl)) { + if (MiniFileMgr.isNetFile(tempUrl)) { + MiniFileMgr.downOtherFiles(encodeURI(tempUrl), new Laya.Handler(MiniLoader, MiniLoader.onDownImgCallBack, [url, thisLoader]), tempUrl); + } + else { + MiniLoader.onCreateImage(url, thisLoader, true); + } + } + else { + MiniLoader.onCreateImage(url, thisLoader); + } + } + } + static onDownImgCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = "") { + if (!errorCode) + MiniLoader.onCreateImage(sourceUrl, thisLoader, false, tempFilePath); + else { + thisLoader.onError(null); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (BMiniAdapter.autoCacheFile) { + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + var fileObj = MiniFileMgr.getFileInfo(Laya.URL.formatURL(sourceUrl)); + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + } + else if (BMiniAdapter.isZiYu) { + var tempUrl = Laya.URL.formatURL(sourceUrl); + if (MiniFileMgr.ziyuFileTextureData[tempUrl]) { + fileNativeUrl = MiniFileMgr.ziyuFileTextureData[tempUrl]; + } + else + fileNativeUrl = sourceUrl; + } + else + fileNativeUrl = sourceUrl; + } + else { + if (!isLocal) + fileNativeUrl = tempFilePath; + else + fileNativeUrl = sourceUrl; + } + thisLoader._loadImage(fileNativeUrl, false); + } + } + + class MiniLocalStorage { + constructor() { + } + static __init__() { + MiniLocalStorage.items = MiniLocalStorage; + } + static setItem(key, value) { + try { + BMiniAdapter.window.swan.setStorageSync(key, value); + } + catch (error) { + BMiniAdapter.window.swan.setStorage({ + key: key, + data: value + }); + } + } + static getItem(key) { + return BMiniAdapter.window.swan.getStorageSync(key); + } + static setJSON(key, value) { + MiniLocalStorage.setItem(key, value); + } + static getJSON(key) { + return MiniLocalStorage.getItem(key); + } + static removeItem(key) { + BMiniAdapter.window.swan.removeStorageSync(key); + } + static clear() { + BMiniAdapter.window.swan.clearStorageSync(); + } + static getStorageInfoSync() { + try { + var res = BMiniAdapter.window.swan.getStorageInfoSync(); + console.log(res.keys); + console.log(res.currentSize); + console.log(res.limitSize); + return res; + } + catch (e) { + } + return null; + } + } + MiniLocalStorage.support = true; + + function ImageDataPolyfill() { + let width, height, data; + if (arguments.length == 3) { + if (arguments[0] instanceof Uint8ClampedArray) { + if (arguments[0].length % 4 !== 0) { + throw new Error("Failed to construct 'ImageData': The input data length is not a multiple of 4."); + } + if (arguments[0].length !== arguments[1] * arguments[2] * 4) { + throw new Error("Failed to construct 'ImageData': The input data length is not equal to (4 * width * height)."); + } + else { + data = arguments[0]; + width = arguments[1]; + height = arguments[2]; + } + } + else { + throw new Error("Failed to construct 'ImageData': parameter 1 is not of type 'Uint8ClampedArray'."); + } + } + else if (arguments.length == 2) { + width = arguments[0]; + height = arguments[1]; + data = new Uint8ClampedArray(arguments[0] * arguments[1] * 4); + } + else if (arguments.length < 2) { + throw new Error("Failed to construct 'ImageData': 2 arguments required, but only " + arguments.length + " present."); + } + let imgdata = Laya.Browser.canvas.getContext("2d").getImageData(0, 0, width, height); + for (let i = 0; i < data.length; i += 4) { + imgdata.data[i] = data[i]; + imgdata.data[i + 1] = data[i + 1]; + imgdata.data[i + 2] = data[i + 2]; + imgdata.data[i + 3] = data[i + 3]; + } + return imgdata; + } + + class BMiniAdapter { + static getJson(data) { + return JSON.parse(data); + } + static enable() { + BMiniAdapter.init(Laya.Laya.isWXPosMsg, Laya.Laya.isWXOpenDataContext); + } + static init(isPosMsg = false, isSon = false) { + if (BMiniAdapter._inited) + return; + BMiniAdapter._inited = true; + BMiniAdapter.window = window; + if (!BMiniAdapter.window.hasOwnProperty("swan")) + return; + if (BMiniAdapter.window.navigator.userAgent.indexOf('SwanGame') < 0) + return; + BMiniAdapter.isZiYu = isSon; + BMiniAdapter.isPosMsgYu = isPosMsg; + BMiniAdapter.EnvConfig = {}; + if (!BMiniAdapter.isZiYu) { + MiniFileMgr.setNativeFileDir("/layaairGame"); + MiniFileMgr.getCacheList(MiniFileMgr.fileNativeDir, Laya.Handler.create(BMiniAdapter, BMiniAdapter.onMkdirCallBack)); + } + BMiniAdapter.systemInfo = BMiniAdapter.window.swan.getSystemInfoSync(); + BMiniAdapter.window.focus = function () { + }; + Laya.Laya['_getUrlPath'] = function () { + return ""; + }; + BMiniAdapter.window.logtime = function (str) { + }; + BMiniAdapter.window.alertTimeLog = function (str) { + }; + BMiniAdapter.window.resetShareInfo = function () { + }; + BMiniAdapter.window.CanvasRenderingContext2D = function () { + }; + BMiniAdapter.window.CanvasRenderingContext2D.prototype = BMiniAdapter.window.swan.createCanvas().getContext('2d').__proto__; + BMiniAdapter.window.document.body.appendChild = function () { + }; + BMiniAdapter.EnvConfig.pixelRatioInt = 0; + Laya.Browser["_pixelRatio"] = BMiniAdapter.pixelRatio(); + BMiniAdapter._preCreateElement = Laya.Browser.createElement; + Laya.Browser["createElement"] = BMiniAdapter.createElement; + Laya.RunDriver.createShaderCondition = BMiniAdapter.createShaderCondition; + Laya.Utils['parseXMLFromString'] = BMiniAdapter.parseXMLFromString; + Laya.Input['_createInputElement'] = MiniInput['_createInputElement']; + if (!window.ImageData) { + window.ImageData = ImageDataPolyfill; + } + Laya.Loader.prototype._loadResourceFilter = MiniLoader.prototype._loadResourceFilter; + Laya.Loader.prototype.originComplete = Laya.Loader.prototype.complete; + Laya.Loader.prototype.complete = MiniLoader.prototype.complete; + Laya.Loader.prototype._loadSound = MiniLoader.prototype._loadSound; + Laya.Loader.prototype._loadHttpRequestWhat = MiniLoader.prototype._loadHttpRequestWhat; + Laya.LocalStorage._baseClass = MiniLocalStorage; + MiniLocalStorage.__init__(); + BMiniAdapter.window.swan.onMessage && BMiniAdapter.window.swan.onMessage(BMiniAdapter._onMessage); + } + static _onMessage(data) { + switch (data.type) { + case "changeMatrix": + Laya.Laya.stage.transform.identity(); + Laya.Laya.stage._width = data.w; + Laya.Laya.stage._height = data.h; + Laya.Laya.stage._canvasTransform = new Laya.Matrix(data.a, data.b, data.c, data.d, data.tx, data.ty); + break; + case "display": + Laya.Laya.stage.frameRate = data.rate || Laya.Stage.FRAME_FAST; + break; + case "undisplay": + Laya.Laya.stage.frameRate = Laya.Stage.FRAME_SLEEP; + break; + } + if (data['isLoad'] == "opendatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + else if (data['isLoad'] == "openJsondatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + } + } + else if (data['isLoad'] == "openJsondatacontextPic") { + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + static getUrlEncode(url, type) { + if (type == "arraybuffer") + return ""; + return "utf8"; + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + var fileObj = MiniFileMgr.getFileInfo(fileUrl); + if (!fileObj) + MiniFileMgr.downLoadFile(fileUrl, fileType, callBack, encoding); + else { + callBack != null && callBack.runWith([0]); + } + } + static remove(fileUrl, callBack = null) { + MiniFileMgr.deleteFile("", fileUrl, callBack, "", 0); + } + static removeAll() { + MiniFileMgr.deleteAll(); + } + static hasNativeFile(fileUrl) { + return MiniFileMgr.isLocalNativeFile(fileUrl); + } + static getFileInfo(fileUrl) { + return MiniFileMgr.getFileInfo(fileUrl); + } + static getFileList() { + return MiniFileMgr.filesListObj; + } + static exitMiniProgram() { + BMiniAdapter.window["swan"].exitMiniProgram(); + } + static onMkdirCallBack(errorCode, data) { + if (!errorCode) { + MiniFileMgr.filesListObj = JSON.parse(data.data); + MiniFileMgr.fakeObj = JSON.parse(data.data); + } + else { + MiniFileMgr.fakeObj = {}; + MiniFileMgr.filesListObj = {}; + } + let files = MiniFileMgr.fs.readdirSync(MiniFileMgr.fileNativeDir); + if (!files.length) + return; + var tempMd5ListObj = {}; + var fileObj; + for (let key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") { + fileObj = MiniFileMgr.filesListObj[key]; + tempMd5ListObj[fileObj.md5] = fileObj.readyUrl; + } + } + var fileName; + for (let i = 0, sz = files.length; i < sz; i++) { + fileName = files[i]; + if (fileName == MiniFileMgr.fileListName) + continue; + if (!tempMd5ListObj[fileName]) { + let deleteFileUrl = MiniFileMgr.getFileNativePath(fileName); + MiniFileMgr.fs.unlink({ + filePath: deleteFileUrl, + success: function (data) { + console.log("删除无引用的磁盘文件:" + fileName); + } + }); + } + delete tempMd5ListObj[fileName]; + } + for (let key in tempMd5ListObj) { + delete MiniFileMgr.filesListObj[tempMd5ListObj[key]]; + delete MiniFileMgr.fakeObj[tempMd5ListObj[key]]; + console.log("删除错误记录:", tempMd5ListObj[key]); + } + } + static pixelRatio() { + if (!BMiniAdapter.EnvConfig.pixelRatioInt) { + try { + BMiniAdapter.EnvConfig.pixelRatioInt = BMiniAdapter.systemInfo.pixelRatio; + return BMiniAdapter.systemInfo.pixelRatio; + } + catch (error) { + } + } + return BMiniAdapter.EnvConfig.pixelRatioInt; + } + static createElement(type) { + if (type == "canvas") { + var _source; + if (BMiniAdapter.idx == 1) { + if (BMiniAdapter.isZiYu) { + _source = BMiniAdapter.window.sharedCanvas; + } + else { + _source = BMiniAdapter.window.canvas; + } + } + else { + _source = BMiniAdapter.window.swan.createCanvas(); + } + _source.style = {}; + BMiniAdapter.idx++; + return _source; + } + else if (type == "textarea" || type == "input") { + return BMiniAdapter.onCreateInput(type); + } + else if (type == "div") { + var node = BMiniAdapter._preCreateElement(type); + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + else { + return BMiniAdapter._preCreateElement(type); + } + } + static onCreateInput(type) { + var node = BMiniAdapter._preCreateElement(type); + node.focus = MiniInput.wxinputFocus; + node.blur = MiniInput.wxinputblur; + node.style = {}; + node.value = 0; + if (!node.parentElement) + node.parentElement = {}; + node.placeholder = {}; + node.type = {}; + node.setColor = function (value) { + }; + node.setType = function (value) { + }; + node.setFontFace = function (value) { + }; + node.addEventListener = function (value) { + }; + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + static createShaderCondition(conditionScript) { + var func = function () { + return this[conditionScript.replace("this.", "")]; + }; + return func; + } + static sendAtlasToOpenDataContext(url) { + if (!BMiniAdapter.isZiYu) { + var atlasJson = Laya.Loader.getRes(Laya.URL.formatURL(url)); + if (atlasJson) { + var textureArr = atlasJson.meta.image.split(","); + if (atlasJson.meta && atlasJson.meta.image) { + var toloadPics = atlasJson.meta.image.split(","); + var split = url.indexOf("/") >= 0 ? "/" : "\\"; + var idx = url.lastIndexOf(split); + var folderPath = idx >= 0 ? url.substr(0, idx + 1) : ""; + for (var i = 0, len = toloadPics.length; i < len; i++) { + toloadPics[i] = folderPath + toloadPics[i]; + } + } + else { + toloadPics = [url.replace(".json", ".png")]; + } + for (i = 0; i < toloadPics.length; i++) { + var tempAtlasPngUrl = toloadPics[i]; + BMiniAdapter.postInfoToContext(Laya.Laya.URL.formatURL(url), Laya.Laya.URL.formatURL(tempAtlasPngUrl), atlasJson); + } + } + else { + throw "传递的url没有获取到对应的图集数据信息,请确保图集已经过!"; + } + } + } + static postInfoToContext(url, atlaspngUrl, atlasJson) { + var postData = { "frames": atlasJson.frames, "meta": atlasJson.meta }; + var textureUrl = atlaspngUrl; + var fileObj = MiniFileMgr.getFileInfo(Laya.URL.formatURL(atlaspngUrl)); + if (fileObj) { + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = textureUrl; + } + if (fileNativeUrl) { + BMiniAdapter.window.swan.postMessage({ url: url, atlasdata: postData, imgNativeUrl: fileNativeUrl, imgReadyUrl: textureUrl, isLoad: "opendatacontext" }); + } + else { + throw "获取图集的磁盘url路径不存在!"; + } + } + static sendSinglePicToOpenDataContext(url) { + var tempTextureUrl = Laya.URL.formatURL(url); + var fileObj = MiniFileMgr.getFileInfo(tempTextureUrl); + if (fileObj) { + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + url = tempTextureUrl; + } + else { + fileNativeUrl = url; + } + if (fileNativeUrl) { + url = Laya.Laya.URL.formatURL(url); + BMiniAdapter.window.swan.postMessage({ url: url, imgNativeUrl: fileNativeUrl, imgReadyUrl: url, isLoad: "openJsondatacontextPic" }); + } + else { + throw "获取图集的磁盘url路径不存在!"; + } + } + static sendJsonDataToDataContext(url) { + if (!BMiniAdapter.isZiYu) { + url = Laya.Laya.URL.formatURL(url); + var atlasJson = Laya.Loader.getRes(url); + if (atlasJson) { + BMiniAdapter.window.swan.postMessage({ url: url, atlasdata: atlasJson, isLoad: "openJsondatacontext" }); + } + else { + throw "传递的url没有获取到对应的图集数据信息,请确保图集已经过!"; + } + } + } + } + BMiniAdapter._inited = false; + BMiniAdapter.autoCacheFile = true; + BMiniAdapter.minClearSize = (5 * 1024 * 1024); + BMiniAdapter.sizeLimit = (50 * 1024 * 1024); + BMiniAdapter.nativefiles = ["layaNativeDir", "wxlocal"]; + BMiniAdapter.subNativeFiles = []; + BMiniAdapter.subNativeheads = []; + BMiniAdapter.subMaps = []; + BMiniAdapter.AutoCacheDownFile = false; + BMiniAdapter.parseXMLFromString = function (value) { + var rst; + value = value.replace(/>\s+<'); + try { + rst = (new BMiniAdapter.window.Parser.DOMParser()).parseFromString(value, 'text/xml'); + } + catch (error) { + throw "需要引入xml解析库文件"; + } + return rst; + }; + BMiniAdapter.idx = 1; + + class MiniAccelerator extends Laya.EventDispatcher { + constructor() { + super(); + } + static __init__() { + try { + var Acc; + Acc = Laya.Accelerator; + if (!Acc) + return; + Acc["prototype"]["on"] = MiniAccelerator["prototype"]["on"]; + Acc["prototype"]["off"] = MiniAccelerator["prototype"]["off"]; + } + catch (e) { + } + } + static startListen(callBack) { + MiniAccelerator._callBack = callBack; + if (MiniAccelerator._isListening) + return; + MiniAccelerator._isListening = true; + try { + BMiniAdapter.window.swan.onAccelerometerChange(MiniAccelerator.onAccelerometerChange); + } + catch (e) { } + } + static stopListen() { + MiniAccelerator._isListening = false; + try { + BMiniAdapter.window.swan.stopAccelerometer({}); + } + catch (e) { } + } + static onAccelerometerChange(res) { + var e; + e = {}; + e.acceleration = res; + e.accelerationIncludingGravity = res; + e.rotationRate = {}; + if (MiniAccelerator._callBack != null) { + MiniAccelerator._callBack(e); + } + } + on(type, caller, listener, args = null) { + super.on(type, caller, listener, args); + MiniAccelerator.startListen(this["onDeviceOrientationChange"]); + return this; + } + off(type, caller, listener, onceOnly = false) { + if (!this.hasListener(type)) + MiniAccelerator.stopListen(); + return super.off(type, caller, listener, onceOnly); + } + } + MiniAccelerator._isListening = false; + + class MiniImage { + _loadImage(url) { + var thisLoader = this; + if (BMiniAdapter.isZiYu) { + MiniImage.onCreateImage(url, thisLoader, true); + return; + } + var isTransformUrl; + if (!MiniFileMgr.isLocalNativeFile(url)) { + isTransformUrl = true; + url = Laya.URL.formatURL(url); + } + else { + if (url.indexOf("http://usr/") == -1 && (url.indexOf("http://") != -1 || url.indexOf("https://") != -1)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (BMiniAdapter.subNativeFiles && BMiniAdapter.subNativeheads.length == 0) { + for (var key in BMiniAdapter.subNativeFiles) { + var tempArr = BMiniAdapter.subNativeFiles[key]; + BMiniAdapter.subNativeheads = BMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + BMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (BMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && BMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = BMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + } + if (!MiniFileMgr.getFileInfo(url)) { + if (url.indexOf('http://usr/') == -1 && (url.indexOf("http://") != -1 || url.indexOf("https://") != -1)) { + if (BMiniAdapter.isZiYu) { + MiniImage.onCreateImage(url, thisLoader, true); + } + else { + MiniFileMgr.downOtherFiles(url, new Laya.Handler(MiniImage, MiniImage.onDownImgCallBack, [url, thisLoader]), url); + } + } + else + MiniImage.onCreateImage(url, thisLoader, true); + } + else { + MiniImage.onCreateImage(url, thisLoader, !isTransformUrl); + } + } + static onDownImgCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = "") { + if (!errorCode) + MiniImage.onCreateImage(sourceUrl, thisLoader, false, tempFilePath); + else { + thisLoader.onError(null); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (BMiniAdapter.autoCacheFile) { + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + var fileMd5Name = fileObj.md5; + fileNativeUrl = MiniFileMgr.getFileNativePath(fileMd5Name); + } + } + else if (BMiniAdapter.isZiYu) { + var tempUrl = Laya.URL.formatURL(sourceUrl); + if (MiniFileMgr.ziyuFileTextureData[tempUrl]) { + fileNativeUrl = MiniFileMgr.ziyuFileTextureData[tempUrl]; + } + else + fileNativeUrl = sourceUrl; + } + else + fileNativeUrl = sourceUrl; + } + else { + if (!isLocal) + fileNativeUrl = tempFilePath; + else + fileNativeUrl = sourceUrl; + } + if (thisLoader._imgCache == null) + thisLoader._imgCache = {}; + var image; + function clear() { + var img = thisLoader._imgCache[fileNativeUrl]; + if (img) { + img.onload = null; + img.onerror = null; + delete thisLoader._imgCache[fileNativeUrl]; + } + } + var onerror = function () { + clear(); + delete MiniFileMgr.fakeObj[sourceUrl]; + delete MiniFileMgr.filesListObj[sourceUrl]; + thisLoader.event(Laya.Event.ERROR, "Load image failed"); + }; + if (thisLoader._type == "nativeimage") { + var onload = function () { + clear(); + thisLoader.onLoaded(image); + }; + image = new Laya.Browser.window.Image(); + image.crossOrigin = ""; + image.onload = onload; + image.onerror = onerror; + image.src = fileNativeUrl; + thisLoader._imgCache[fileNativeUrl] = image; + } + else { + var imageSource = new Laya.Browser.window.Image(); + onload = function () { + image = Laya.HTMLImage.create(imageSource.width, imageSource.height); + image.loadImageSource(imageSource, true); + image._setCreateURL(fileNativeUrl); + clear(); + thisLoader.onLoaded(image); + }; + imageSource.crossOrigin = ""; + imageSource.onload = onload; + imageSource.onerror = onerror; + imageSource.src = fileNativeUrl; + thisLoader._imgCache[fileNativeUrl] = imageSource; + } + } + } + + class MiniLocation { + constructor() { + } + static __init__() { + BMiniAdapter.window.navigator.geolocation.getCurrentPosition = MiniLocation.getCurrentPosition; + BMiniAdapter.window.navigator.geolocation.watchPosition = MiniLocation.watchPosition; + BMiniAdapter.window.navigator.geolocation.clearWatch = MiniLocation.clearWatch; + } + static getCurrentPosition(success = null, error = null, options = null) { + var paramO; + paramO = {}; + paramO.success = getSuccess; + paramO.fail = error; + BMiniAdapter.window.swan.getLocation(paramO); + function getSuccess(res) { + if (success != null) { + success(res); + } + } + } + static watchPosition(success = null, error = null, options = null) { + MiniLocation._curID++; + var curWatchO; + curWatchO = {}; + curWatchO.success = success; + curWatchO.error = error; + MiniLocation._watchDic[MiniLocation._curID] = curWatchO; + Laya.Laya.systemTimer.loop(1000, null, MiniLocation._myLoop); + return MiniLocation._curID; + } + static clearWatch(id) { + delete MiniLocation._watchDic[id]; + if (!MiniLocation._hasWatch()) { + Laya.Laya.systemTimer.clear(null, MiniLocation._myLoop); + } + } + static _hasWatch() { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key]) + return true; + } + return false; + } + static _myLoop() { + MiniLocation.getCurrentPosition(MiniLocation._mySuccess, MiniLocation._myError); + } + static _mySuccess(res) { + var rst = {}; + rst.coords = res; + rst.timestamp = Laya.Browser.now(); + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].success) { + MiniLocation._watchDic[key].success(rst); + } + } + } + static _myError(res) { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].error) { + MiniLocation._watchDic[key].error(res); + } + } + } + } + MiniLocation._watchDic = {}; + MiniLocation._curID = 0; + + class MiniVideo { + constructor(width = 320, height = 240) { + this.videoend = false; + this.videourl = ""; + this.videoElement = BMiniAdapter.window.swan.createVideo({ width: width, height: height, autoplay: true }); + } + static __init__() { + } + on(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.onPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.onEnded = this.onEndedFunction.bind(this); + } + this.videoElement.onTimeUpdate = this.onTimeUpdateFunc.bind(this); + } + onTimeUpdateFunc(data) { + this.position = data.position; + this._duration = data.duration; + } + get duration() { + return this._duration; + } + onPlayFunction() { + if (this.videoElement) + this.videoElement.readyState = 200; + console.log("=====视频加载完成========"); + this.onPlayFunc != null && this.onPlayFunc(); + } + onEndedFunction() { + if (!this.videoElement) + return; + this.videoend = true; + console.log("=====视频播放完毕========"); + this.onEndedFunC != null && this.onEndedFunC(); + } + off(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.offPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.offEnded = this.onEndedFunction.bind(this); + } + } + load(url) { + if (!this.videoElement) + return; + this.videoElement.src = url; + } + play() { + if (!this.videoElement) + return; + this.videoend = false; + this.videoElement.play(); + } + pause() { + if (!this.videoElement) + return; + this.videoend = true; + this.videoElement.pause(); + } + get currentTime() { + if (!this.videoElement) + return 0; + return this.videoElement.initialTime; + } + set currentTime(value) { + if (!this.videoElement) + return; + this.videoElement.initialTime = value; + } + get videoWidth() { + if (!this.videoElement) + return 0; + return this.videoElement.width; + } + get videoHeight() { + if (!this.videoElement) + return 0; + return this.videoElement.height; + } + get ended() { + return this.videoend; + } + get loop() { + if (!this.videoElement) + return false; + return this.videoElement.loop; + } + set loop(value) { + if (!this.videoElement) + return; + this.videoElement.loop = value; + } + get playbackRate() { + if (!this.videoElement) + return 0; + return this.videoElement.playbackRate; + } + set playbackRate(value) { + if (!this.videoElement) + return; + this.videoElement.playbackRate = value; + } + get muted() { + if (!this.videoElement) + return false; + return this.videoElement.muted; + } + set muted(value) { + if (!this.videoElement) + return; + this.videoElement.muted = value; + } + get paused() { + if (!this.videoElement) + return false; + return this.videoElement.paused; + } + size(width, height) { + if (!this.videoElement) + return; + this.videoElement.width = width; + this.videoElement.height = height; + } + get x() { + if (!this.videoElement) + return 0; + return this.videoElement.x; + } + set x(value) { + if (!this.videoElement) + return; + this.videoElement.x = value; + } + get y() { + if (!this.videoElement) + return 0; + return this.videoElement.y; + } + set y(value) { + if (!this.videoElement) + return; + this.videoElement.y = value; + } + get currentSrc() { + return this.videoElement.src; + } + destroy() { + if (this.videoElement) + this.videoElement.destroy(); + this.videoElement = null; + this.onEndedFunC = null; + this.onPlayFunc = null; + this.videoend = false; + this.videourl = null; + } + reload() { + if (!this.videoElement) + return; + this.videoElement.src = this.videourl; + } + } + + exports.BMiniAdapter = BMiniAdapter; + exports.ImageDataPolyfill = ImageDataPolyfill; + exports.MiniAccelerator = MiniAccelerator; + exports.MiniFileMgr = MiniFileMgr; + exports.MiniImage = MiniImage; + exports.MiniInput = MiniInput; + exports.MiniLoader = MiniLoader; + exports.MiniLocalStorage = MiniLocalStorage; + exports.MiniLocation = MiniLocation; + exports.MiniSound = MiniSound; + exports.MiniSoundChannel = MiniSoundChannel; + exports.MiniVideo = MiniVideo; + +} diff --git a/examples/layaair/frontend/bin/libs/laya.bilimini.js b/examples/layaair/frontend/bin/libs/laya.bilimini.js new file mode 100644 index 0000000..2053d41 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.bilimini.js @@ -0,0 +1,1855 @@ +window.biliMiniGame = function (exports, Laya) { + 'use strict'; + + class MiniFileMgr { + static isLocalNativeFile(url) { + for (var i = 0, sz = BLMiniAdapter.nativefiles.length; i < sz; i++) { + if (url.indexOf(BLMiniAdapter.nativefiles[i]) != -1) + return true; + } + return false; + } + static isNetFile(url) { + return (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) && url.indexOf(BLMiniAdapter.window.bl.env.USER_DATA_PATH) == -1; + } + static getFileInfo(fileUrl) { + var fileNativePath = fileUrl; + var fileObj = MiniFileMgr.fakeObj[fileNativePath]; + if (fileObj == null) + return null; + else + return fileObj; + } + static read(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "") { + var fileUrl; + if (readyUrl != "" && (readyUrl.indexOf("http://") != -1 || readyUrl.indexOf("https://") != -1)) { + fileUrl = MiniFileMgr.getFileNativePath(filePath); + } + else { + fileUrl = filePath; + } + fileUrl = Laya.URL.getAdptedFilePath(fileUrl); + MiniFileMgr.fs.readFile({ filePath: fileUrl, encoding: encoding, success: function (data) { + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data && readyUrl != "") + MiniFileMgr.downFiles(BLMiniAdapter.safeEncodeURI(readyUrl), encoding, callBack, readyUrl, isSaveFile, fileType); + else + callBack != null && callBack.runWith([1]); + } }); + } + static isFile(url) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(url); + } + catch (err) { + return false; + } + return stat.isFile(); + } + static downFiles(fileUrl, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + var downloadTask = MiniFileMgr.down({ url: fileUrl, success: function (data) { + if (data.statusCode === 200) + MiniFileMgr.readFile(data.tempFilePath, encoding, callBack, readyUrl, isSaveFile, fileType, isAutoClear); + else if (data.statusCode === 403) { + callBack != null && callBack.runWith([0, fileUrl]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + downloadTask.onProgressUpdate(function (data) { + callBack != null && callBack.runWith([2, data.progress]); + }); + } + static readFile(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + filePath = Laya.URL.getAdptedFilePath(filePath); + MiniFileMgr.fs.readFile({ filePath: filePath, encoding: encoding, success: function (data) { + if ((filePath.indexOf("http://") != -1 || filePath.indexOf("https://") != -1) && filePath.indexOf(BLMiniAdapter.window.bl.env.USER_DATA_PATH) == -1) { + if (BLMiniAdapter.AutoCacheDownFile || isSaveFile) { + callBack != null && callBack.runWith([0, data]); + MiniFileMgr.copyTOCache(filePath, readyUrl, null, encoding, isAutoClear); + } + else + callBack != null && callBack.runWith([0, data]); + } + else + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data) + callBack != null && callBack.runWith([1, data]); + } }); + } + static downOtherFiles(fileUrl, callBack = null, readyUrl = "", isSaveFile = false, isAutoClear = true) { + MiniFileMgr.down({ url: fileUrl, success: function (data) { + if (data.statusCode === 200) { + if ((BLMiniAdapter.autoCacheFile || isSaveFile) && readyUrl.indexOf(".php") == -1) { + callBack != null && callBack.runWith([0, data.tempFilePath]); + MiniFileMgr.copyTOCache(data.tempFilePath, readyUrl, null, "", isAutoClear); + } + else + callBack != null && callBack.runWith([0, data.tempFilePath]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static copyFile(src, dest, complete = null) { + MiniFileMgr.fs.copyFile({ + srcPath: src, + destPath: dest, + success: function () { + complete && complete.runWith(0); + }, + fail: function (err) { + complete && complete.runWith([1, err]); + } + }); + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + if (window.navigator.userAgent.indexOf('MiniGame') < 0) { + Laya.Laya.loader.load(fileUrl, callBack); + } + else { + if (fileType == Laya.Loader.IMAGE || fileType == Laya.Loader.SOUND) + MiniFileMgr.downOtherFiles(fileUrl, callBack, fileUrl, true, false); + else + MiniFileMgr.downFiles(fileUrl, encoding, callBack, fileUrl, true, fileType, false); + } + } + static copyTOCache(tempFilePath, readyUrl, callBack, encoding = "", isAutoClear = true) { + var temp = tempFilePath.split("/"); + var tempFileName = temp[temp.length - 1]; + var fileurlkey = readyUrl; + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fakeObj[fileurlkey] = { md5: tempFileName, readyUrl: readyUrl, size: 0, times: Laya.Browser.now(), encoding: encoding, tempFilePath: tempFilePath }; + var totalSize = BLMiniAdapter.sizeLimit; + var chaSize = 4 * 1024 * 1024; + var fileUseSize = MiniFileMgr.getCacheUseSize(); + if (fileObj) { + if (fileObj.readyUrl != readyUrl) { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > BLMiniAdapter.minClearSize) + BLMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.deleteFile(tempFilePath, readyUrl, callBack, encoding, data.size); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + else + callBack != null && callBack.runWith([0]); + } + else { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > BLMiniAdapter.minClearSize) + BLMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.fs.copyFile({ srcPath: tempFilePath, destPath: saveFilePath, success: function (data2) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, data.size); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + } + static onClearCacheRes() { + var memSize = BLMiniAdapter.minClearSize; + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + MiniFileMgr.sortOn(tempFileListArr, "times", MiniFileMgr.NUMERIC); + var clearSize = 0; + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + if (clearSize >= memSize) + break; + clearSize += fileObj.size; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + } + static sortOn(array, name, options = 0) { + if (options == MiniFileMgr.NUMERIC) + return array.sort(function (a, b) { return a[name] - b[name]; }); + if (options == (MiniFileMgr.NUMERIC | MiniFileMgr.DESCENDING)) + return array.sort(function (a, b) { return b[name] - a[name]; }); + return array.sort(function (a, b) { return a[name] - b[name]; }); + } + static getFileNativePath(fileName) { + return MiniFileMgr.fileNativeDir + "/" + fileName; + } + static deleteFile(tempFileName, readyUrl = "", callBack = null, encoding = "", fileSize = 0) { + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var deleteFileUrl = MiniFileMgr.getFileNativePath(fileObj.md5); + MiniFileMgr.fs.unlink({ filePath: deleteFileUrl, success: function (data) { + if (tempFileName != "") { + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fs.copyFile({ srcPath: tempFileName, destPath: saveFilePath, success: function (data) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, fileSize); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + else { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, false, encoding, callBack, fileSize); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static deleteAll() { + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj.fileUsedSize) { + MiniFileMgr.filesListObj.fileUsedSize = 0; + } + MiniFileMgr.writeFilesList("", JSON.stringify({}), false); + } + static onSaveFile(readyUrl, md5Name, isAdd = true, encoding = "", callBack = null, fileSize = 0) { + var fileurlkey = readyUrl; + if (MiniFileMgr.filesListObj['fileUsedSize'] == null) + MiniFileMgr.filesListObj['fileUsedSize'] = 0; + if (isAdd) { + var fileNativeName = MiniFileMgr.getFileNativePath(md5Name); + MiniFileMgr.filesListObj[fileurlkey] = { md5: md5Name, readyUrl: readyUrl, size: fileSize, times: Laya.Browser.now(), encoding: encoding, tempFilePath: fileNativeName }; + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) + fileSize; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), true); + callBack != null && callBack.runWith([0]); + } + else { + if (MiniFileMgr.filesListObj[fileurlkey]) { + var deletefileSize = parseInt(MiniFileMgr.filesListObj[fileurlkey].size); + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) - deletefileSize; + if (MiniFileMgr.fakeObj[fileurlkey].md5 == MiniFileMgr.filesListObj[fileurlkey].md5) { + delete MiniFileMgr.fakeObj[fileurlkey]; + } + delete MiniFileMgr.filesListObj[fileurlkey]; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), false); + callBack != null && callBack.runWith([0]); + } + } + } + static writeFilesList(fileurlkey, filesListStr, isAdd) { + var listFilesPath = MiniFileMgr.fileNativeDir + "/" + MiniFileMgr.fileListName; + MiniFileMgr.fs.writeFile({ filePath: listFilesPath, encoding: 'utf8', data: filesListStr, success: function (data) { + }, fail: function (data) { + } }); + if (!BLMiniAdapter.isZiYu && BLMiniAdapter.isPosMsgYu) { + BLMiniAdapter.window.bl.postMessage({ url: fileurlkey, data: MiniFileMgr.filesListObj[fileurlkey], isLoad: "filenative", isAdd: isAdd }); + } + } + static getCacheUseSize() { + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj['fileUsedSize']) + return MiniFileMgr.filesListObj['fileUsedSize']; + return 0; + } + static getCacheList(dirPath, cb) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(dirPath); + } + catch (err) { + stat = null; + } + if (stat) { + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", cb); + } + else { + MiniFileMgr.fs.mkdirSync(dirPath, true); + cb && cb.runWith([1]); + } + } + static existDir(dirPath, callBack) { + MiniFileMgr.fs.mkdir({ dirPath: dirPath, success: function (data) { + callBack != null && callBack.runWith([0, { data: JSON.stringify({}) }]); + }, fail: function (data) { + if (data.errMsg.indexOf("file already exists") != -1 || data.errMsg.indexOf("EXISTS") != -1) + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", callBack); + else + callBack != null && callBack.runWith([1, data]); + } }); + } + static readSync(filePath, encoding = "utf8", callBack = null, readyUrl = "") { + var fileUrl = MiniFileMgr.getFileNativePath(filePath); + var filesListStr; + try { + filesListStr = MiniFileMgr.fs.readFileSync(fileUrl, encoding); + callBack != null && callBack.runWith([0, { data: filesListStr }]); + } + catch (error) { + callBack != null && callBack.runWith([1]); + } + } + static setNativeFileDir(value) { + MiniFileMgr.fileNativeDir = BLMiniAdapter.window.bl.env.USER_DATA_PATH + value; + } + } + MiniFileMgr.fs = window.bl.getFileSystemManager(); + MiniFileMgr.down = window.bl.downloadFile; + MiniFileMgr.filesListObj = {}; + MiniFileMgr.fakeObj = {}; + MiniFileMgr.fileListName = "layaairfiles.txt"; + MiniFileMgr.ziyuFileData = {}; + MiniFileMgr.ziyuFileTextureData = {}; + MiniFileMgr.loadPath = ""; + MiniFileMgr.DESCENDING = 2; + MiniFileMgr.NUMERIC = 16; + + class MiniSoundChannel extends Laya.SoundChannel { + constructor(audio, miniSound) { + super(); + this._audio = audio; + this._miniSound = miniSound; + this._onEnd = MiniSoundChannel.bindToThis(this.__onEnd, this); + audio.onEnded(this._onEnd); + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + __onEnd() { + if (this.loops == 1) { + if (this.completeHandler) { + Laya.Laya.systemTimer.once(10, this, this.__runComplete, [this.completeHandler], false); + this.completeHandler = null; + } + this.stop(); + this.event(Laya.Event.COMPLETE); + return; + } + if (this.loops > 0) { + this.loops--; + } + this.startTime = 0; + this.play(); + } + play() { + this.isStopped = false; + Laya.SoundManager.addChannel(this); + this._audio.play(); + } + set startTime(time) { + if (this._audio) { + this._audio.startTime = time; + } + } + set autoplay(value) { + this._audio.autoplay = value; + } + get autoplay() { + return this._audio.autoplay; + } + get position() { + if (!this._audio) + return 0; + return this._audio.currentTime; + } + get duration() { + if (!this._audio) + return 0; + return this._audio.duration; + } + stop() { + this.isStopped = true; + Laya.SoundManager.removeChannel(this); + this.completeHandler = null; + if (!this._audio) + return; + this._audio.stop(); + if (!this.loop) { + this._audio.offEnded(null); + this._miniSound.dispose(); + this._audio = null; + this._miniSound = null; + this._onEnd = null; + } + } + pause() { + this.isStopped = true; + this._audio.pause(); + } + get loop() { + return this._audio.loop; + } + set loop(value) { + this._audio.loop = value; + } + resume() { + if (!this._audio) + return; + this.isStopped = false; + Laya.SoundManager.addChannel(this); + this._audio.play(); + } + set volume(v) { + if (!this._audio) + return; + this._audio.volume = v; + } + get volume() { + if (!this._audio) + return 1; + return this._audio.volume; + } + } + + class MiniSound extends Laya.EventDispatcher { + constructor() { + super(); + this.loaded = false; + } + static _createSound() { + MiniSound._id++; + return BLMiniAdapter.window.bl.createInnerAudioContext(); + } + load(url) { + if (!MiniSound._musicAudio) + MiniSound._musicAudio = MiniSound._createSound(); + if (!MiniFileMgr.isLocalNativeFile(url)) { + url = Laya.URL.formatURL(url); + } + else { + if (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + if (tempStr != "") + url = url.split(tempStr)[1]; + } + } + } + this.url = url; + this.readyUrl = url; + if (MiniSound._audioCache[this.readyUrl]) { + this.event(Laya.Event.COMPLETE); + return; + } + if (BLMiniAdapter.autoCacheFile && MiniFileMgr.getFileInfo(url)) { + this.onDownLoadCallBack(url, 0); + } + else { + if (!BLMiniAdapter.autoCacheFile) { + this.onDownLoadCallBack(url, 0); + } + else { + if (MiniFileMgr.isLocalNativeFile(url)) { + tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + if (BLMiniAdapter.subNativeFiles && BLMiniAdapter.subNativeheads.length == 0) { + for (var key in BLMiniAdapter.subNativeFiles) { + var tempArr = BLMiniAdapter.subNativeFiles[key]; + BLMiniAdapter.subNativeheads = BLMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + BLMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (BLMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && BLMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = BLMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + this.onDownLoadCallBack(url, 0); + } + else { + if (!MiniFileMgr.isLocalNativeFile(url) && (url.indexOf("http://") == -1 && url.indexOf("https://") == -1) || (url.indexOf("http://usr/") != -1)) { + this.onDownLoadCallBack(url, 0); + } + else { + MiniFileMgr.downOtherFiles(url, Laya.Handler.create(this, this.onDownLoadCallBack, [url]), url); + } + } + } + } + } + onDownLoadCallBack(sourceUrl, errorCode, tempFilePath = null) { + if (!errorCode) { + var fileNativeUrl; + if (BLMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = sourceUrl; + if (tempStr != "" && (sourceUrl.indexOf("http://") != -1 || sourceUrl.indexOf("https://") != -1)) + fileNativeUrl = sourceUrl.split(tempStr)[1]; + if (!fileNativeUrl) { + fileNativeUrl = tempUrl; + } + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + var fileMd5Name = fileObj.md5; + fileNativeUrl = MiniFileMgr.getFileNativePath(fileMd5Name); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + if (this.url != Laya.SoundManager._bgMusic) { + this._sound = MiniSound._createSound(); + this._sound.src = this.url = fileNativeUrl; + } + else { + this._sound = MiniSound._musicAudio; + this._sound.src = this.url = fileNativeUrl; + } + } + else { + if (this.url != Laya.SoundManager._bgMusic) { + this._sound = MiniSound._createSound(); + this._sound.src = sourceUrl; + } + else { + this._sound = MiniSound._musicAudio; + this._sound.src = sourceUrl; + } + } + this._sound.onCanplay(MiniSound.bindToThis(this.onCanPlay, this)); + this._sound.onError(MiniSound.bindToThis(this.onError, this)); + } + else { + this.event(Laya.Event.ERROR); + } + } + onError(error) { + try { + console.log("-----1---------------minisound-----id:" + MiniSound._id); + console.log(error); + } + catch (error) { + console.log("-----2---------------minisound-----id:" + MiniSound._id); + console.log(error); + } + this.event(Laya.Event.ERROR); + this._sound.offError(MiniSound.bindToThis(this.onError, this)); + } + onCanPlay() { + this.loaded = true; + this.event(Laya.Event.COMPLETE); + this._sound.offCanplay(MiniSound.bindToThis(this.onCanPlay, this)); + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + play(startTime = 0, loops = 0) { + var tSound; + if (this.url == Laya.SoundManager._bgMusic) { + if (!MiniSound._musicAudio) + MiniSound._musicAudio = MiniSound._createSound(); + tSound = MiniSound._musicAudio; + } + else { + if (MiniSound._audioCache[this.readyUrl]) { + tSound = MiniSound._audioCache[this.readyUrl]._sound; + } + else { + tSound = MiniSound._createSound(); + } + } + if (!tSound) + return null; + if (BLMiniAdapter.autoCacheFile && MiniFileMgr.getFileInfo(this.url)) { + var fileObj = MiniFileMgr.getFileInfo(this.url); + var fileMd5Name = fileObj.md5; + tSound.src = this.url = MiniFileMgr.getFileNativePath(fileMd5Name); + } + else { + tSound.src = this.url; + } + var channel = new MiniSoundChannel(tSound, this); + channel.url = this.url; + channel.loops = loops; + channel.loop = (loops === 0 ? true : false); + channel.startTime = startTime; + channel.play(); + Laya.SoundManager.addChannel(channel); + return channel; + } + get duration() { + return this._sound.duration; + } + dispose() { + var ad = MiniSound._audioCache[this.readyUrl]; + if (ad) { + ad.src = ""; + if (ad._sound) { + ad._sound.destroy(); + ad._sound = null; + ad = null; + } + delete MiniSound._audioCache[this.readyUrl]; + } + if (this._sound) { + this._sound.destroy(); + this._sound = null; + this.readyUrl = this.url = null; + } + } + } + MiniSound._id = 0; + MiniSound._audioCache = {}; + + class MiniInput { + constructor() { + } + static _createInputElement() { + Laya.Input['_initInput'](Laya.Input['area'] = Laya.Browser.createElement("textarea")); + Laya.Input['_initInput'](Laya.Input['input'] = Laya.Browser.createElement("input")); + Laya.Input['inputContainer'] = Laya.Browser.createElement("div"); + Laya.Input['inputContainer'].style.position = "absolute"; + Laya.Input['inputContainer'].style.zIndex = 1E5; + Laya.Browser.container.appendChild(Laya.Input['inputContainer']); + Laya.Laya.stage.on("resize", null, MiniInput._onStageResize); + BLMiniAdapter.window.bl.onWindowResize && BLMiniAdapter.window.bl.onWindowResize(function (res) { + }); + Laya.SoundManager._soundClass = MiniSound; + Laya.SoundManager._musicClass = MiniSound; + var model = BLMiniAdapter.systemInfo.model; + var system = BLMiniAdapter.systemInfo.system; + if (model.indexOf("iPhone") != -1) { + Laya.Browser.onIPhone = true; + Laya.Browser.onIOS = true; + Laya.Browser.onIPad = true; + Laya.Browser.onAndroid = false; + } + if (system.indexOf("Android") != -1 || system.indexOf("Adr") != -1) { + Laya.Browser.onAndroid = true; + Laya.Browser.onIPhone = false; + Laya.Browser.onIOS = false; + Laya.Browser.onIPad = false; + } + } + static _onStageResize() { + var ts = Laya.Laya.stage._canvasTransform.identity(); + ts.scale((Laya.Browser.width / Laya.Render.canvas.width / Laya.Browser.pixelRatio), Laya.Browser.height / Laya.Render.canvas.height / Laya.Browser.pixelRatio); + } + static wxinputFocus(e) { + var _inputTarget = Laya.Input['inputElement'].target; + if (_inputTarget && !_inputTarget.editable) { + return; + } + BLMiniAdapter.window.bl.offKeyboardConfirm(); + BLMiniAdapter.window.bl.offKeyboardInput(); + BLMiniAdapter.window.bl.showKeyboard({ defaultValue: _inputTarget.text, maxLength: _inputTarget.maxChars, multiple: _inputTarget.multiline, confirmHold: true, confirmType: _inputTarget["confirmType"] || 'done', success: function (res) { + }, fail: function (res) { + } }); + BLMiniAdapter.window.bl.onKeyboardConfirm(function (res) { + var str = res ? res.value : ""; + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + MiniInput.inputEnter(); + _inputTarget.event("confirm"); + }); + BLMiniAdapter.window.bl.onKeyboardInput(function (res) { + var str = res ? res.value : ""; + if (!_inputTarget.multiline) { + if (str.indexOf("\n") != -1) { + MiniInput.inputEnter(); + return; + } + } + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + }); + } + static inputEnter() { + Laya.Input['inputElement'].target.focus = false; + } + static wxinputblur() { + MiniInput.hideKeyboard(); + } + static hideKeyboard() { + BLMiniAdapter.window.bl.offKeyboardConfirm(); + BLMiniAdapter.window.bl.offKeyboardInput(); + BLMiniAdapter.window.bl.hideKeyboard({ success: function (res) { + console.log('隐藏键盘'); + }, fail: function (res) { + console.log("隐藏键盘出错:" + (res ? res.errMsg : "")); + } }); + } + } + + class MiniLoader extends Laya.EventDispatcher { + constructor() { + super(); + } + _loadResourceFilter(type, url) { + var thisLoader = this; + this.sourceUrl = Laya.URL.formatURL(url); + if (MiniFileMgr.isNetFile(url)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (BLMiniAdapter.subNativeFiles && BLMiniAdapter.subNativeheads.length == 0) { + for (var key in BLMiniAdapter.subNativeFiles) { + var tempArr = BLMiniAdapter.subNativeFiles[key]; + BLMiniAdapter.subNativeheads = BLMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + BLMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (BLMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && BLMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = BLMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + switch (type) { + case Laya.Loader.IMAGE: + case "htmlimage": + case "nativeimage": + MiniLoader._transformImgUrl(url, type, thisLoader); + break; + case Laya.Loader.SOUND: + thisLoader._loadSound(url); + break; + default: + thisLoader._loadResource(type, url); + } + } + _loadSound(url) { + var thisLoader = this; + if (!BLMiniAdapter.autoCacheFile) { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + else { + var tempurl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downOtherFiles(BLMiniAdapter.safeEncodeURI(tempurl), Laya.Handler.create(MiniLoader, MiniLoader.onDownLoadCallBack, [tempurl, thisLoader]), tempurl); + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + } + static onDownLoadCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = null) { + if (!errorCode) { + var fileNativeUrl; + if (BLMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + fileNativeUrl = sourceUrl; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + } + else { + fileNativeUrl = Laya.URL.formatURL(sourceUrl); + } + sourceUrl = fileNativeUrl; + var sound = (new Laya.SoundManager._soundClass()); + sound.load(BLMiniAdapter.safeEncodeURI(sourceUrl)); + thisLoader.onLoaded(sound); + } + else { + thisLoader.event(Laya.Event.ERROR, "Load sound failed"); + } + } + complete(data) { + if (data instanceof Laya.Resource) { + data._setCreateURL(this.sourceUrl); + } + else if ((data instanceof Laya.Texture) && (data.bitmap instanceof Laya.Resource)) { + data.bitmap._setCreateURL(this.sourceUrl); + } + this.originComplete(data); + } + _loadHttpRequestWhat(url, contentType) { + var thisLoader = this; + var encoding = BLMiniAdapter.getUrlEncode(url, contentType); + if (Laya.Loader.preLoadedMap[url]) + thisLoader.onLoaded(Laya.Loader.preLoadedMap[url]); + else { + var tempurl = Laya.URL.formatURL(url); + if (!BLMiniAdapter.AutoCacheDownFile) { + if (MiniFileMgr.isNetFile(tempurl)) { + thisLoader._loadHttpRequest(tempurl, contentType, thisLoader, thisLoader.onLoaded, thisLoader, thisLoader.onProgress, thisLoader, thisLoader.onError); + } + else + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + else { + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downFiles(BLMiniAdapter.safeEncodeURI(tempurl), encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), tempurl, true); + } + else { + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + else { + var tempUrl = url; + var fileObj = MiniFileMgr.getFileInfo(tempurl); + if (fileObj && fileObj.md5) { + tempUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + MiniFileMgr.readFile(tempUrl, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + } + } + static onReadNativeCallBack(url, type = null, thisLoader = null, errorCode = 0, data = null) { + if (!errorCode) { + var tempData; + if (type == Laya.Loader.JSON || type == Laya.Loader.ATLAS || type == Laya.Loader.PREFAB || type == Laya.Loader.PLF) { + tempData = BLMiniAdapter.getJson(data.data); + } + else if (type == Laya.Loader.XML) { + tempData = Laya.Utils.parseXMLFromString(data.data); + } + else { + tempData = data.data; + } + if (!BLMiniAdapter.isZiYu && BLMiniAdapter.isPosMsgYu && type != Laya.Loader.BUFFER) { + BLMiniAdapter.window.bl.postMessage({ url: url, data: tempData, isLoad: "filedata" }); + } + thisLoader.onLoaded(tempData); + } + else if (errorCode == 1) { + thisLoader._loadHttpRequest(url, type, thisLoader, thisLoader.onLoaded, thisLoader, thisLoader.onProgress, thisLoader, thisLoader.onError); + } + } + static _transformImgUrl(url, type, thisLoader) { + if (BLMiniAdapter.isZiYu || MiniFileMgr.isLocalNativeFile(url)) { + thisLoader._loadImage(url, false); + return; + } + if (!BLMiniAdapter.autoCacheFile) { + thisLoader._loadImage(BLMiniAdapter.safeEncodeURI(url)); + } + else { + var tempUrl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempUrl)) { + if (MiniFileMgr.isNetFile(tempUrl)) { + MiniFileMgr.downOtherFiles(BLMiniAdapter.safeEncodeURI(tempUrl), new Laya.Handler(MiniLoader, MiniLoader.onDownImgCallBack, [url, thisLoader]), tempUrl); + } + else { + MiniLoader.onCreateImage(url, thisLoader, true); + } + } + else { + MiniLoader.onCreateImage(url, thisLoader); + } + } + } + static onDownImgCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = "") { + if (!errorCode) + MiniLoader.onCreateImage(sourceUrl, thisLoader, false, tempFilePath); + else { + thisLoader.onError(null); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (BLMiniAdapter.autoCacheFile) { + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + var fileObj = MiniFileMgr.getFileInfo(Laya.URL.formatURL(sourceUrl)); + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + } + else if (BLMiniAdapter.isZiYu) { + var tempUrl = Laya.URL.formatURL(sourceUrl); + if (MiniFileMgr.ziyuFileTextureData[tempUrl]) { + fileNativeUrl = MiniFileMgr.ziyuFileTextureData[tempUrl]; + } + else + fileNativeUrl = sourceUrl; + } + else + fileNativeUrl = sourceUrl; + } + else { + if (!isLocal) + fileNativeUrl = tempFilePath; + else + fileNativeUrl = sourceUrl; + } + thisLoader._loadImage(fileNativeUrl, false); + } + } + + class MiniLocalStorage { + constructor() { + } + static __init__() { + MiniLocalStorage.items = MiniLocalStorage; + } + static setItem(key, value) { + try { + BLMiniAdapter.window.bl.setStorageSync(key, value); + } + catch (error) { + BLMiniAdapter.window.bl.setStorage({ + key: key, + data: value + }); + } + } + static getItem(key) { + return BLMiniAdapter.window.bl.getStorageSync(key); + } + static setJSON(key, value) { + MiniLocalStorage.setItem(key, value); + } + static getJSON(key) { + return MiniLocalStorage.getItem(key); + } + static removeItem(key) { + BLMiniAdapter.window.bl.removeStorageSync(key); + } + static clear() { + BLMiniAdapter.window.bl.clearStorageSync(); + } + static getStorageInfoSync() { + try { + var res = BLMiniAdapter.window.bl.getStorageInfoSync(); + console.log(res.keys); + console.log(res.currentSize); + console.log(res.limitSize); + return res; + } + catch (e) { + } + return null; + } + } + MiniLocalStorage.support = true; + + function ImageDataPolyfill() { + let width, height, data; + if (arguments.length == 3) { + if (arguments[0] instanceof Uint8ClampedArray) { + if (arguments[0].length % 4 !== 0) { + throw new Error("Failed to construct 'ImageData': The input data length is not a multiple of 4."); + } + if (arguments[0].length !== arguments[1] * arguments[2] * 4) { + throw new Error("Failed to construct 'ImageData': The input data length is not equal to (4 * width * height)."); + } + else { + data = arguments[0]; + width = arguments[1]; + height = arguments[2]; + } + } + else { + throw new Error("Failed to construct 'ImageData': parameter 1 is not of type 'Uint8ClampedArray'."); + } + } + else if (arguments.length == 2) { + width = arguments[0]; + height = arguments[1]; + data = new Uint8ClampedArray(arguments[0] * arguments[1] * 4); + } + else if (arguments.length < 2) { + throw new Error("Failed to construct 'ImageData': 2 arguments required, but only " + arguments.length + " present."); + } + let imgdata = Laya.Browser.canvas.getContext("2d").getImageData(0, 0, width, height); + for (let i = 0; i < data.length; i += 4) { + imgdata.data[i] = data[i]; + imgdata.data[i + 1] = data[i + 1]; + imgdata.data[i + 2] = data[i + 2]; + imgdata.data[i + 3] = data[i + 3]; + } + return imgdata; + } + + class BLMiniAdapter { + static getJson(data) { + return JSON.parse(data); + } + static enable() { + BLMiniAdapter.init(Laya.Laya.isWXPosMsg, Laya.Laya.isWXOpenDataContext); + } + static init(isPosMsg = false, isSon = false) { + if (BLMiniAdapter._inited) + return; + BLMiniAdapter._inited = true; + BLMiniAdapter.window = window; + if (!BLMiniAdapter.window.hasOwnProperty("bl")) + return; + if (BLMiniAdapter.window.navigator.userAgent.indexOf('MiniGame') < 0) + return; + BLMiniAdapter.isZiYu = isSon; + BLMiniAdapter.isPosMsgYu = isPosMsg; + BLMiniAdapter.EnvConfig = {}; + if (!BLMiniAdapter.isZiYu) { + MiniFileMgr.setNativeFileDir("/layaairGame"); + MiniFileMgr.getCacheList(MiniFileMgr.fileNativeDir, Laya.Handler.create(BLMiniAdapter, BLMiniAdapter.onMkdirCallBack)); + } + BLMiniAdapter.systemInfo = BLMiniAdapter.window.bl.getSystemInfoSync(); + BLMiniAdapter.window.focus = function () { + }; + Laya.Laya['_getUrlPath'] = function () { + return ""; + }; + BLMiniAdapter.window.logtime = function (str) { + }; + BLMiniAdapter.window.alertTimeLog = function (str) { + }; + BLMiniAdapter.window.resetShareInfo = function () { + }; + BLMiniAdapter.window.CanvasRenderingContext2D = function () { + }; + BLMiniAdapter.window.CanvasRenderingContext2D.prototype = BLMiniAdapter.window.bl.createCanvas().getContext('2d').__proto__; + BLMiniAdapter.window.document.body.appendChild = function () { + }; + Laya.HttpRequest._urlEncode = BLMiniAdapter.safeEncodeURI; + BLMiniAdapter.EnvConfig.pixelRatioInt = 0; + Laya.Browser["_pixelRatio"] = BLMiniAdapter.pixelRatio(); + BLMiniAdapter._preCreateElement = Laya.Browser.createElement; + Laya.Browser["createElement"] = BLMiniAdapter.createElement; + Laya.RunDriver.createShaderCondition = BLMiniAdapter.createShaderCondition; + Laya.Utils['parseXMLFromString'] = BLMiniAdapter.parseXMLFromString; + Laya.Input['_createInputElement'] = MiniInput['_createInputElement']; + if (!window.ImageData) { + window.ImageData = ImageDataPolyfill; + } + Laya.Loader.prototype._loadResourceFilter = MiniLoader.prototype._loadResourceFilter; + Laya.Loader.prototype.originComplete = Laya.Loader.prototype.complete; + Laya.Loader.prototype.complete = MiniLoader.prototype.complete; + Laya.Loader.prototype._loadSound = MiniLoader.prototype._loadSound; + Laya.Loader.prototype._loadHttpRequestWhat = MiniLoader.prototype._loadHttpRequestWhat; + Laya.LocalStorage._baseClass = MiniLocalStorage; + MiniLocalStorage.__init__(); + Laya.Config.useRetinalCanvas = true; + BLMiniAdapter.window.bl.onMessage && BLMiniAdapter.window.bl.onMessage(BLMiniAdapter._onMessage); + } + static _onMessage(data) { + switch (data.type) { + case "changeMatrix": + Laya.Laya.stage.transform.identity(); + Laya.Laya.stage._width = data.w; + Laya.Laya.stage._height = data.h; + Laya.Laya.stage._canvasTransform = new Laya.Matrix(data.a, data.b, data.c, data.d, data.tx, data.ty); + break; + case "display": + Laya.Laya.stage.frameRate = data.rate || Laya.Stage.FRAME_FAST; + break; + case "undisplay": + Laya.Laya.stage.frameRate = Laya.Stage.FRAME_SLEEP; + break; + } + if (data['isLoad'] == "opendatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + else if (data['isLoad'] == "openJsondatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + } + } + else if (data['isLoad'] == "openJsondatacontextPic") { + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + static getUrlEncode(url, type) { + if (type == "arraybuffer") + return ""; + return "utf8"; + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + var fileObj = MiniFileMgr.getFileInfo(fileUrl); + if (!fileObj) + MiniFileMgr.downLoadFile(fileUrl, fileType, callBack, encoding); + else { + callBack != null && callBack.runWith([0]); + } + } + static remove(fileUrl, callBack = null) { + MiniFileMgr.deleteFile("", fileUrl, callBack, "", 0); + } + static removeAll() { + MiniFileMgr.deleteAll(); + } + static hasNativeFile(fileUrl) { + return MiniFileMgr.isLocalNativeFile(fileUrl); + } + static getFileInfo(fileUrl) { + return MiniFileMgr.getFileInfo(fileUrl); + } + static getFileList() { + return MiniFileMgr.filesListObj; + } + static exitMiniProgram() { + BLMiniAdapter.window["bl"].exitMiniProgram(); + } + static onMkdirCallBack(errorCode, data) { + if (!errorCode) { + MiniFileMgr.filesListObj = JSON.parse(data.data); + MiniFileMgr.fakeObj = JSON.parse(data.data); + } + else { + MiniFileMgr.fakeObj = {}; + MiniFileMgr.filesListObj = {}; + } + let files = MiniFileMgr.fs.readdirSync(MiniFileMgr.fileNativeDir); + if (!files.length) + return; + var tempMd5ListObj = {}; + var fileObj; + for (let key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") { + fileObj = MiniFileMgr.filesListObj[key]; + tempMd5ListObj[fileObj.md5] = fileObj.readyUrl; + } + } + var fileName; + for (let i = 0, sz = files.length; i < sz; i++) { + fileName = files[i]; + if (fileName == MiniFileMgr.fileListName) + continue; + if (!tempMd5ListObj[fileName]) { + let deleteFileUrl = MiniFileMgr.getFileNativePath(fileName); + MiniFileMgr.fs.unlink({ + filePath: deleteFileUrl, + success: function (data) { + console.log("删除无引用的磁盘文件:" + fileName); + } + }); + } + delete tempMd5ListObj[fileName]; + } + for (let key in tempMd5ListObj) { + delete MiniFileMgr.filesListObj[tempMd5ListObj[key]]; + delete MiniFileMgr.fakeObj[tempMd5ListObj[key]]; + console.log("删除错误记录:", tempMd5ListObj[key]); + } + } + static pixelRatio() { + if (!BLMiniAdapter.EnvConfig.pixelRatioInt) { + try { + BLMiniAdapter.EnvConfig.pixelRatioInt = BLMiniAdapter.systemInfo.pixelRatio; + return BLMiniAdapter.systemInfo.pixelRatio; + } + catch (error) { + } + } + return BLMiniAdapter.EnvConfig.pixelRatioInt; + } + static createElement(type) { + if (type == "canvas") { + var _source; + if (BLMiniAdapter.idx == 1) { + if (BLMiniAdapter.isZiYu) { + _source = BLMiniAdapter.window.sharedCanvas; + _source.style = {}; + } + else { + _source = BLMiniAdapter.window.canvas; + } + } + else { + _source = window.document.createElement("canvas"); + } + BLMiniAdapter.idx++; + return _source; + } + else if (type == "textarea" || type == "input") { + return BLMiniAdapter.onCreateInput(type); + } + else if (type == "div") { + var node = BLMiniAdapter._preCreateElement(type); + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + else { + return BLMiniAdapter._preCreateElement(type); + } + } + static onCreateInput(type) { + var node = BLMiniAdapter._preCreateElement(type); + node.focus = MiniInput.wxinputFocus; + node.blur = MiniInput.wxinputblur; + node.style = {}; + node.value = 0; + node.parentElement = {}; + node.placeholder = {}; + node.type = {}; + node.setColor = function (value) { + }; + node.setType = function (value) { + }; + node.setFontFace = function (value) { + }; + node.addEventListener = function (value) { + }; + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + static createShaderCondition(conditionScript) { + var func = function () { + return this[conditionScript.replace("this.", "")]; + }; + return func; + } + static sendAtlasToOpenDataContext(url) { + if (!BLMiniAdapter.isZiYu) { + var atlasJson = Laya.Loader.getRes(Laya.URL.formatURL(url)); + if (atlasJson) { + var textureArr = atlasJson.meta.image.split(","); + if (atlasJson.meta && atlasJson.meta.image) { + var toloadPics = atlasJson.meta.image.split(","); + var split = url.indexOf("/") >= 0 ? "/" : "\\"; + var idx = url.lastIndexOf(split); + var folderPath = idx >= 0 ? url.substr(0, idx + 1) : ""; + for (var i = 0, len = toloadPics.length; i < len; i++) { + toloadPics[i] = folderPath + toloadPics[i]; + } + } + else { + toloadPics = [url.replace(".json", ".png")]; + } + for (i = 0; i < toloadPics.length; i++) { + var tempAtlasPngUrl = toloadPics[i]; + BLMiniAdapter.postInfoToContext(Laya.Laya.URL.formatURL(url), Laya.Laya.URL.formatURL(tempAtlasPngUrl), atlasJson); + } + } + else { + throw "传递的url没有获取到对应的图集数据信息,请确保图集已经过!"; + } + } + } + static postInfoToContext(url, atlaspngUrl, atlasJson) { + var postData = { "frames": atlasJson.frames, "meta": atlasJson.meta }; + var textureUrl = atlaspngUrl; + var fileObj = MiniFileMgr.getFileInfo(Laya.URL.formatURL(atlaspngUrl)); + if (fileObj) { + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = textureUrl; + } + if (fileNativeUrl) { + BLMiniAdapter.window.bl.postMessage({ url: url, atlasdata: postData, imgNativeUrl: fileNativeUrl, imgReadyUrl: textureUrl, isLoad: "opendatacontext" }); + } + else { + throw "获取图集的磁盘url路径不存在!"; + } + } + static sendSinglePicToOpenDataContext(url) { + var tempTextureUrl = Laya.URL.formatURL(url); + var fileObj = MiniFileMgr.getFileInfo(tempTextureUrl); + if (fileObj) { + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + url = tempTextureUrl; + } + else { + fileNativeUrl = url; + } + if (fileNativeUrl) { + url = Laya.Laya.URL.formatURL(url); + BLMiniAdapter.window.bl.postMessage({ url: url, imgNativeUrl: fileNativeUrl, imgReadyUrl: url, isLoad: "openJsondatacontextPic" }); + } + else { + throw "获取图集的磁盘url路径不存在!"; + } + } + static sendJsonDataToDataContext(url) { + if (!BLMiniAdapter.isZiYu) { + url = Laya.Laya.URL.formatURL(url); + var atlasJson = Laya.Loader.getRes(url); + if (atlasJson) { + BLMiniAdapter.window.bl.postMessage({ url: url, atlasdata: atlasJson, isLoad: "openJsondatacontext" }); + } + else { + throw "传递的url没有获取到对应的图集数据信息,请确保图集已经过!"; + } + } + } + } + BLMiniAdapter.IGNORE = new RegExp("[-_.!~*'();/?:@&=+$,#%]|[0-9|A-Z|a-z]"); + BLMiniAdapter.safeEncodeURI = function (str) { + var strTemp = ""; + var length = str.length; + for (var i = 0; i < length; i++) { + var word = str[i]; + if (BLMiniAdapter.IGNORE.test(word)) { + strTemp += word; + } + else { + try { + strTemp += encodeURI(word); + } + catch (e) { + console.log("errorInfo", ">>>" + word); + } + } + } + return strTemp; + }; + BLMiniAdapter._inited = false; + BLMiniAdapter.autoCacheFile = true; + BLMiniAdapter.minClearSize = (5 * 1024 * 1024); + BLMiniAdapter.sizeLimit = (50 * 1024 * 1024); + BLMiniAdapter.nativefiles = ["layaNativeDir", "bllocal"]; + BLMiniAdapter.subNativeFiles = []; + BLMiniAdapter.subNativeheads = []; + BLMiniAdapter.subMaps = []; + BLMiniAdapter.AutoCacheDownFile = false; + BLMiniAdapter.parseXMLFromString = function (value) { + var rst; + value = value.replace(/>\s+<'); + try { + rst = (new BLMiniAdapter.window.Parser.DOMParser()).parseFromString(value, 'text/xml'); + } + catch (error) { + throw "需要引入xml解析库文件"; + } + return rst; + }; + BLMiniAdapter.idx = 1; + + class MiniAccelerator extends Laya.EventDispatcher { + constructor() { + super(); + } + static __init__() { + try { + var Acc; + Acc = Laya.Accelerator; + if (!Acc) + return; + Acc["prototype"]["on"] = MiniAccelerator["prototype"]["on"]; + Acc["prototype"]["off"] = MiniAccelerator["prototype"]["off"]; + } + catch (e) { + } + } + static startListen(callBack) { + MiniAccelerator._callBack = callBack; + if (MiniAccelerator._isListening) + return; + MiniAccelerator._isListening = true; + try { + BLMiniAdapter.window.bl.onAccelerometerChange(MiniAccelerator.onAccelerometerChange); + } + catch (e) { } + } + static stopListen() { + MiniAccelerator._isListening = false; + try { + BLMiniAdapter.window.bl.stopAccelerometer({}); + } + catch (e) { } + } + static onAccelerometerChange(res) { + var e; + e = {}; + e.acceleration = res; + e.accelerationIncludingGravity = res; + e.rotationRate = {}; + if (MiniAccelerator._callBack != null) { + MiniAccelerator._callBack(e); + } + } + on(type, caller, listener, args = null) { + super.on(type, caller, listener, args); + MiniAccelerator.startListen(this["onDeviceOrientationChange"]); + return this; + } + off(type, caller, listener, onceOnly = false) { + if (!this.hasListener(type)) + MiniAccelerator.stopListen(); + return super.off(type, caller, listener, onceOnly); + } + } + MiniAccelerator._isListening = false; + + class MiniImage { + _loadImage(url) { + var thisLoader = this; + if (BLMiniAdapter.isZiYu) { + MiniImage.onCreateImage(url, thisLoader, true); + return; + } + var isTransformUrl; + if (!MiniFileMgr.isLocalNativeFile(url)) { + isTransformUrl = true; + url = Laya.URL.formatURL(url); + } + else { + if (url.indexOf(BLMiniAdapter.window.bl.env.USER_DATA_PATH) == -1 && (url.indexOf("http://") != -1 || url.indexOf("https://") != -1)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (BLMiniAdapter.subNativeFiles && BLMiniAdapter.subNativeheads.length == 0) { + for (var key in BLMiniAdapter.subNativeFiles) { + var tempArr = BLMiniAdapter.subNativeFiles[key]; + BLMiniAdapter.subNativeheads = BLMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + BLMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (BLMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && BLMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = BLMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + } + if (!MiniFileMgr.getFileInfo(url)) { + if (url.indexOf(BLMiniAdapter.window.bl.env.USER_DATA_PATH) == -1 && (url.indexOf("http://") != -1 || url.indexOf("https://") != -1)) { + if (BLMiniAdapter.isZiYu) { + MiniImage.onCreateImage(url, thisLoader, true); + } + else { + MiniFileMgr.downOtherFiles(url, new Laya.Handler(MiniImage, MiniImage.onDownImgCallBack, [url, thisLoader]), url); + } + } + else + MiniImage.onCreateImage(url, thisLoader, true); + } + else { + MiniImage.onCreateImage(url, thisLoader, !isTransformUrl); + } + } + static onDownImgCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = "") { + if (!errorCode) + MiniImage.onCreateImage(sourceUrl, thisLoader, false, tempFilePath); + else { + thisLoader.onError(null); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (BLMiniAdapter.autoCacheFile) { + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + var fileMd5Name = fileObj.md5; + fileNativeUrl = MiniFileMgr.getFileNativePath(fileMd5Name); + } + } + else if (BLMiniAdapter.isZiYu) { + var tempUrl = Laya.URL.formatURL(sourceUrl); + if (MiniFileMgr.ziyuFileTextureData[tempUrl]) { + fileNativeUrl = MiniFileMgr.ziyuFileTextureData[tempUrl]; + } + else + fileNativeUrl = sourceUrl; + } + else + fileNativeUrl = sourceUrl; + } + else { + if (!isLocal) + fileNativeUrl = tempFilePath; + else + fileNativeUrl = sourceUrl; + } + if (thisLoader._imgCache == null) + thisLoader._imgCache = {}; + var image; + function clear() { + var img = thisLoader._imgCache[fileNativeUrl]; + if (img) { + img.onload = null; + img.onerror = null; + delete thisLoader._imgCache[fileNativeUrl]; + } + } + var onerror = function () { + clear(); + delete MiniFileMgr.fakeObj[sourceUrl]; + delete MiniFileMgr.filesListObj[sourceUrl]; + thisLoader.event(Laya.Event.ERROR, "Load image failed"); + }; + if (thisLoader._type == "nativeimage") { + var onload = function () { + clear(); + thisLoader.onLoaded(image); + }; + image = new Laya.Browser.window.Image(); + image.crossOrigin = ""; + image.onload = onload; + image.onerror = onerror; + image.src = fileNativeUrl; + thisLoader._imgCache[fileNativeUrl] = image; + } + else { + var imageSource = new Laya.Browser.window.Image(); + onload = function () { + image = Laya.HTMLImage.create(imageSource.width, imageSource.height); + image.loadImageSource(imageSource, true); + image._setCreateURL(fileNativeUrl); + clear(); + thisLoader.onLoaded(image); + }; + imageSource.crossOrigin = ""; + imageSource.onload = onload; + imageSource.onerror = onerror; + imageSource.src = fileNativeUrl; + thisLoader._imgCache[fileNativeUrl] = imageSource; + } + } + } + + class MiniLocation { + constructor() { + } + static __init__() { + BLMiniAdapter.window.navigator.geolocation.getCurrentPosition = MiniLocation.getCurrentPosition; + BLMiniAdapter.window.navigator.geolocation.watchPosition = MiniLocation.watchPosition; + BLMiniAdapter.window.navigator.geolocation.clearWatch = MiniLocation.clearWatch; + } + static getCurrentPosition(success = null, error = null, options = null) { + var paramO; + paramO = {}; + paramO.success = getSuccess; + paramO.fail = error; + BLMiniAdapter.window.bl.getLocation(paramO); + function getSuccess(res) { + if (success != null) { + success(res); + } + } + } + static watchPosition(success = null, error = null, options = null) { + MiniLocation._curID++; + var curWatchO; + curWatchO = {}; + curWatchO.success = success; + curWatchO.error = error; + MiniLocation._watchDic[MiniLocation._curID] = curWatchO; + Laya.Laya.systemTimer.loop(1000, null, MiniLocation._myLoop); + return MiniLocation._curID; + } + static clearWatch(id) { + delete MiniLocation._watchDic[id]; + if (!MiniLocation._hasWatch()) { + Laya.Laya.systemTimer.clear(null, MiniLocation._myLoop); + } + } + static _hasWatch() { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key]) + return true; + } + return false; + } + static _myLoop() { + MiniLocation.getCurrentPosition(MiniLocation._mySuccess, MiniLocation._myError); + } + static _mySuccess(res) { + var rst = {}; + rst.coords = res; + rst.timestamp = Laya.Browser.now(); + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].success) { + MiniLocation._watchDic[key].success(rst); + } + } + } + static _myError(res) { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].error) { + MiniLocation._watchDic[key].error(res); + } + } + } + } + MiniLocation._watchDic = {}; + MiniLocation._curID = 0; + + class MiniVideo { + constructor(width = 320, height = 240) { + this.videoend = false; + this.videourl = ""; + this.videoElement = BLMiniAdapter.window.bl.createVideo({ width: width, height: height, autoplay: true }); + } + static __init__() { + } + on(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.onPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.onEnded = this.onEndedFunction.bind(this); + } + this.videoElement.onTimeUpdate = this.onTimeUpdateFunc.bind(this); + } + onTimeUpdateFunc(data) { + this.position = data.position; + this._duration = data.duration; + } + get duration() { + return this._duration; + } + onPlayFunction() { + if (this.videoElement) + this.videoElement.readyState = 200; + console.log("=====视频加载完成========"); + this.onPlayFunc != null && this.onPlayFunc(); + } + onEndedFunction() { + if (!this.videoElement) + return; + this.videoend = true; + console.log("=====视频播放完毕========"); + this.onEndedFunC != null && this.onEndedFunC(); + } + off(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.offPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.offEnded = this.onEndedFunction.bind(this); + } + } + load(url) { + if (!this.videoElement) + return; + this.videoElement.src = url; + } + play() { + if (!this.videoElement) + return; + this.videoend = false; + this.videoElement.play(); + } + pause() { + if (!this.videoElement) + return; + this.videoend = true; + this.videoElement.pause(); + } + get currentTime() { + if (!this.videoElement) + return 0; + return this.videoElement.initialTime; + } + set currentTime(value) { + if (!this.videoElement) + return; + this.videoElement.initialTime = value; + } + get videoWidth() { + if (!this.videoElement) + return 0; + return this.videoElement.width; + } + get videoHeight() { + if (!this.videoElement) + return 0; + return this.videoElement.height; + } + get ended() { + return this.videoend; + } + get loop() { + if (!this.videoElement) + return false; + return this.videoElement.loop; + } + set loop(value) { + if (!this.videoElement) + return; + this.videoElement.loop = value; + } + get playbackRate() { + if (!this.videoElement) + return 0; + return this.videoElement.playbackRate; + } + set playbackRate(value) { + if (!this.videoElement) + return; + this.videoElement.playbackRate = value; + } + get muted() { + if (!this.videoElement) + return false; + return this.videoElement.muted; + } + set muted(value) { + if (!this.videoElement) + return; + this.videoElement.muted = value; + } + get paused() { + if (!this.videoElement) + return false; + return this.videoElement.paused; + } + size(width, height) { + if (!this.videoElement) + return; + this.videoElement.width = width; + this.videoElement.height = height; + } + get x() { + if (!this.videoElement) + return 0; + return this.videoElement.x; + } + set x(value) { + if (!this.videoElement) + return; + this.videoElement.x = value; + } + get y() { + if (!this.videoElement) + return 0; + return this.videoElement.y; + } + set y(value) { + if (!this.videoElement) + return; + this.videoElement.y = value; + } + get currentSrc() { + return this.videoElement.src; + } + destroy() { + if (this.videoElement) + this.videoElement.destroy(); + this.videoElement = null; + this.onEndedFunC = null; + this.onPlayFunc = null; + this.videoend = false; + this.videourl = null; + } + reload() { + if (!this.videoElement) + return; + this.videoElement.src = this.videourl; + } + } + + exports.BLMiniAdapter = BLMiniAdapter; + exports.ImageDataPolyfill = ImageDataPolyfill; + exports.MiniAccelerator = MiniAccelerator; + exports.MiniFileMgr = MiniFileMgr; + exports.MiniImage = MiniImage; + exports.MiniInput = MiniInput; + exports.MiniLoader = MiniLoader; + exports.MiniLocalStorage = MiniLocalStorage; + exports.MiniLocation = MiniLocation; + exports.MiniSound = MiniSound; + exports.MiniSoundChannel = MiniSoundChannel; + exports.MiniVideo = MiniVideo; + +} diff --git a/examples/layaair/frontend/bin/libs/laya.cannonPhysics.js b/examples/layaair/frontend/bin/libs/laya.cannonPhysics.js new file mode 100644 index 0000000..6e48901 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.cannonPhysics.js @@ -0,0 +1,15198 @@ +/* + * Copyright (c) 2015 cannon.js Authors + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +!function(e){if("object"==typeof exports&&"undefined"!=typeof module&&false)module.exports=e();else if("function"==typeof define&&false)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.CANNON=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o (http://steffe.se)", + "keywords": [ + "cannon.js", + "cannon", + "physics", + "engine", + "3d" + ], + "main": "./build/cannon.js", + "engines": { + "node": "*" + }, + "repository": { + "type": "git", + "url": "https://github.com/schteppe/cannon.js.git" + }, + "bugs": { + "url": "https://github.com/schteppe/cannon.js/issues" + }, + "licenses": [ + { + "type": "MIT" + } + ], + "devDependencies": { + "jshint": "latest", + "uglify-js": "latest", + "nodeunit": "^0.9.0", + "grunt": "~0.4.0", + "grunt-contrib-jshint": "~0.1.1", + "grunt-contrib-nodeunit": "^0.4.1", + "grunt-contrib-concat": "~0.1.3", + "grunt-contrib-uglify": "^0.5.1", + "grunt-browserify": "^2.1.4", + "grunt-contrib-yuidoc": "^0.5.2", + "browserify": "*" + }, + "dependencies": {} +} + +},{}],2:[function(_dereq_,module,exports){ +// Export classes +module.exports = { + version : _dereq_('../package.json').version, + + AABB : _dereq_('./collision/AABB'), + ArrayCollisionMatrix : _dereq_('./collision/ArrayCollisionMatrix'), + Body : _dereq_('./objects/Body'), + Box : _dereq_('./shapes/Box'), + Broadphase : _dereq_('./collision/Broadphase'), + Constraint : _dereq_('./constraints/Constraint'), + ContactEquation : _dereq_('./equations/ContactEquation'), + Narrowphase : _dereq_('./world/Narrowphase'), + ConeTwistConstraint : _dereq_('./constraints/ConeTwistConstraint'), + ContactMaterial : _dereq_('./material/ContactMaterial'), + ConvexPolyhedron : _dereq_('./shapes/ConvexPolyhedron'), + Cylinder : _dereq_('./shapes/Cylinder'), + DistanceConstraint : _dereq_('./constraints/DistanceConstraint'), + Equation : _dereq_('./equations/Equation'), + EventTarget : _dereq_('./utils/EventTarget'), + FrictionEquation : _dereq_('./equations/FrictionEquation'), + GSSolver : _dereq_('./solver/GSSolver'), + GridBroadphase : _dereq_('./collision/GridBroadphase'), + Heightfield : _dereq_('./shapes/Heightfield'), + HingeConstraint : _dereq_('./constraints/HingeConstraint'), + LockConstraint : _dereq_('./constraints/LockConstraint'), + Mat3 : _dereq_('./math/Mat3'), + Material : _dereq_('./material/Material'), + NaiveBroadphase : _dereq_('./collision/NaiveBroadphase'), + ObjectCollisionMatrix : _dereq_('./collision/ObjectCollisionMatrix'), + Pool : _dereq_('./utils/Pool'), + Particle : _dereq_('./shapes/Particle'), + Plane : _dereq_('./shapes/Plane'), + PointToPointConstraint : _dereq_('./constraints/PointToPointConstraint'), + Quaternion : _dereq_('./math/Quaternion'), + Ray : _dereq_('./collision/Ray'), + RaycastVehicle : _dereq_('./objects/RaycastVehicle'), + RaycastResult : _dereq_('./collision/RaycastResult'), + RigidVehicle : _dereq_('./objects/RigidVehicle'), + RotationalEquation : _dereq_('./equations/RotationalEquation'), + RotationalMotorEquation : _dereq_('./equations/RotationalMotorEquation'), + SAPBroadphase : _dereq_('./collision/SAPBroadphase'), + SPHSystem : _dereq_('./objects/SPHSystem'), + Shape : _dereq_('./shapes/Shape'), + Solver : _dereq_('./solver/Solver'), + Sphere : _dereq_('./shapes/Sphere'), + SplitSolver : _dereq_('./solver/SplitSolver'), + Spring : _dereq_('./objects/Spring'), + Trimesh : _dereq_('./shapes/Trimesh'), + Vec3 : _dereq_('./math/Vec3'), + Vec3Pool : _dereq_('./utils/Vec3Pool'), + World : _dereq_('./world/World'), +}; + +},{"../package.json":1,"./collision/AABB":3,"./collision/ArrayCollisionMatrix":4,"./collision/Broadphase":5,"./collision/GridBroadphase":6,"./collision/NaiveBroadphase":7,"./collision/ObjectCollisionMatrix":8,"./collision/Ray":9,"./collision/RaycastResult":10,"./collision/SAPBroadphase":11,"./constraints/ConeTwistConstraint":12,"./constraints/Constraint":13,"./constraints/DistanceConstraint":14,"./constraints/HingeConstraint":15,"./constraints/LockConstraint":16,"./constraints/PointToPointConstraint":17,"./equations/ContactEquation":19,"./equations/Equation":20,"./equations/FrictionEquation":21,"./equations/RotationalEquation":22,"./equations/RotationalMotorEquation":23,"./material/ContactMaterial":24,"./material/Material":25,"./math/Mat3":27,"./math/Quaternion":28,"./math/Vec3":30,"./objects/Body":31,"./objects/RaycastVehicle":32,"./objects/RigidVehicle":33,"./objects/SPHSystem":34,"./objects/Spring":35,"./shapes/Box":37,"./shapes/ConvexPolyhedron":38,"./shapes/Cylinder":39,"./shapes/Heightfield":40,"./shapes/Particle":41,"./shapes/Plane":42,"./shapes/Shape":43,"./shapes/Sphere":44,"./shapes/Trimesh":45,"./solver/GSSolver":46,"./solver/Solver":47,"./solver/SplitSolver":48,"./utils/EventTarget":49,"./utils/Pool":51,"./utils/Vec3Pool":54,"./world/Narrowphase":55,"./world/World":56}],3:[function(_dereq_,module,exports){ +var Vec3 = _dereq_('../math/Vec3'); +var Utils = _dereq_('../utils/Utils'); + +module.exports = AABB; + +/** + * Axis aligned bounding box class. + * @class AABB + * @constructor + * @param {Object} [options] + * @param {Vec3} [options.upperBound] + * @param {Vec3} [options.lowerBound] + */ +function AABB(options){ + options = options || {}; + + /** + * The lower bound of the bounding box. + * @property lowerBound + * @type {Vec3} + */ + this.lowerBound = new Vec3(); + if(options.lowerBound){ + this.lowerBound.copy(options.lowerBound); + } + + /** + * The upper bound of the bounding box. + * @property upperBound + * @type {Vec3} + */ + this.upperBound = new Vec3(); + if(options.upperBound){ + this.upperBound.copy(options.upperBound); + } +} + +var tmp = new Vec3(); + +/** + * Set the AABB bounds from a set of points. + * @method setFromPoints + * @param {Array} points An array of Vec3's. + * @param {Vec3} position + * @param {Quaternion} quaternion + * @param {number} skinSize + * @return {AABB} The self object + */ +AABB.prototype.setFromPoints = function(points, position, quaternion, skinSize){ + var l = this.lowerBound, + u = this.upperBound, + q = quaternion; + + // Set to the first point + l.copy(points[0]); + if(q){ + q.vmult(l, l); + } + u.copy(l); + + for(var i = 1; i u.x){ u.x = p.x; } + if(p.x < l.x){ l.x = p.x; } + if(p.y > u.y){ u.y = p.y; } + if(p.y < l.y){ l.y = p.y; } + if(p.z > u.z){ u.z = p.z; } + if(p.z < l.z){ l.z = p.z; } + } + + // Add offset + if (position) { + position.vadd(l, l); + position.vadd(u, u); + } + + if(skinSize){ + l.x -= skinSize; + l.y -= skinSize; + l.z -= skinSize; + u.x += skinSize; + u.y += skinSize; + u.z += skinSize; + } + + return this; +}; + +/** + * Copy bounds from an AABB to this AABB + * @method copy + * @param {AABB} aabb Source to copy from + * @return {AABB} The this object, for chainability + */ +AABB.prototype.copy = function(aabb){ + this.lowerBound.copy(aabb.lowerBound); + this.upperBound.copy(aabb.upperBound); + return this; +}; + +/** + * Clone an AABB + * @method clone + */ +AABB.prototype.clone = function(){ + return new AABB().copy(this); +}; + +/** + * Extend this AABB so that it covers the given AABB too. + * @method extend + * @param {AABB} aabb + */ +AABB.prototype.extend = function(aabb){ + // Extend lower bound + var l = aabb.lowerBound.x; + if(this.lowerBound.x > l){ + this.lowerBound.x = l; + } + + // Upper + var u = aabb.upperBound.x; + if(this.upperBound.x < u){ + this.upperBound.x = u; + } + + // Extend lower bound + var l = aabb.lowerBound.y; + if(this.lowerBound.y > l){ + this.lowerBound.y = l; + } + + // Upper + var u = aabb.upperBound.y; + if(this.upperBound.y < u){ + this.upperBound.y = u; + } + + // Extend lower bound + var l = aabb.lowerBound.z; + if(this.lowerBound.z > l){ + this.lowerBound.z = l; + } + + // Upper + var u = aabb.upperBound.z; + if(this.upperBound.z < u){ + this.upperBound.z = u; + } +}; + +/** + * Returns true if the given AABB overlaps this AABB. + * @method overlaps + * @param {AABB} aabb + * @return {Boolean} + */ +AABB.prototype.overlaps = function(aabb){ + var l1 = this.lowerBound, + u1 = this.upperBound, + l2 = aabb.lowerBound, + u2 = aabb.upperBound; + + // l2 u2 + // |---------| + // |--------| + // l1 u1 + + return ((l2.x <= u1.x && u1.x <= u2.x) || (l1.x <= u2.x && u2.x <= u1.x)) && + ((l2.y <= u1.y && u1.y <= u2.y) || (l1.y <= u2.y && u2.y <= u1.y)) && + ((l2.z <= u1.z && u1.z <= u2.z) || (l1.z <= u2.z && u2.z <= u1.z)); +}; + +/** + * Returns true if the given AABB is fully contained in this AABB. + * @method contains + * @param {AABB} aabb + * @return {Boolean} + */ +AABB.prototype.contains = function(aabb){ + var l1 = this.lowerBound, + u1 = this.upperBound, + l2 = aabb.lowerBound, + u2 = aabb.upperBound; + + // l2 u2 + // |---------| + // |---------------| + // l1 u1 + + return ( + (l1.x <= l2.x && u1.x >= u2.x) && + (l1.y <= l2.y && u1.y >= u2.y) && + (l1.z <= l2.z && u1.z >= u2.z) + ); +}; + +/** + * @method getCorners + * @param {Vec3} a + * @param {Vec3} b + * @param {Vec3} c + * @param {Vec3} d + * @param {Vec3} e + * @param {Vec3} f + * @param {Vec3} g + * @param {Vec3} h + */ +AABB.prototype.getCorners = function(a, b, c, d, e, f, g, h){ + var l = this.lowerBound, + u = this.upperBound; + + a.copy(l); + b.set( u.x, l.y, l.z ); + c.set( u.x, u.y, l.z ); + d.set( l.x, u.y, u.z ); + e.set( u.x, l.y, l.z ); + f.set( l.x, u.y, l.z ); + g.set( l.x, l.y, u.z ); + h.copy(u); +}; + +var transformIntoFrame_corners = [ + new Vec3(), + new Vec3(), + new Vec3(), + new Vec3(), + new Vec3(), + new Vec3(), + new Vec3(), + new Vec3() +]; + +/** + * Get the representation of an AABB in another frame. + * @method toLocalFrame + * @param {Transform} frame + * @param {AABB} target + * @return {AABB} The "target" AABB object. + */ +AABB.prototype.toLocalFrame = function(frame, target){ + + var corners = transformIntoFrame_corners; + var a = corners[0]; + var b = corners[1]; + var c = corners[2]; + var d = corners[3]; + var e = corners[4]; + var f = corners[5]; + var g = corners[6]; + var h = corners[7]; + + // Get corners in current frame + this.getCorners(a, b, c, d, e, f, g, h); + + // Transform them to new local frame + for(var i=0; i !== 8; i++){ + var corner = corners[i]; + frame.pointToLocal(corner, corner); + } + + return target.setFromPoints(corners); +}; + +/** + * Get the representation of an AABB in the global frame. + * @method toWorldFrame + * @param {Transform} frame + * @param {AABB} target + * @return {AABB} The "target" AABB object. + */ +AABB.prototype.toWorldFrame = function(frame, target){ + + var corners = transformIntoFrame_corners; + var a = corners[0]; + var b = corners[1]; + var c = corners[2]; + var d = corners[3]; + var e = corners[4]; + var f = corners[5]; + var g = corners[6]; + var h = corners[7]; + + // Get corners in current frame + this.getCorners(a, b, c, d, e, f, g, h); + + // Transform them to new local frame + for(var i=0; i !== 8; i++){ + var corner = corners[i]; + frame.pointToWorld(corner, corner); + } + + return target.setFromPoints(corners); +}; + +},{"../math/Vec3":30,"../utils/Utils":53}],4:[function(_dereq_,module,exports){ +module.exports = ArrayCollisionMatrix; + +/** + * Collision "matrix". It's actually a triangular-shaped array of whether two bodies are touching this step, for reference next step + * @class ArrayCollisionMatrix + * @constructor + */ +function ArrayCollisionMatrix() { + + /** + * The matrix storage + * @property matrix + * @type {Array} + */ + this.matrix = []; +} + +/** + * Get an element + * @method get + * @param {Number} i + * @param {Number} j + * @return {Number} + */ +ArrayCollisionMatrix.prototype.get = function(i, j) { + i = i.index; + j = j.index; + if (j > i) { + var temp = j; + j = i; + i = temp; + } + return this.matrix[(i*(i + 1)>>1) + j-1]; +}; + +/** + * Set an element + * @method set + * @param {Number} i + * @param {Number} j + * @param {Number} value + */ +ArrayCollisionMatrix.prototype.set = function(i, j, value) { + i = i.index; + j = j.index; + if (j > i) { + var temp = j; + j = i; + i = temp; + } + this.matrix[(i*(i + 1)>>1) + j-1] = value ? 1 : 0; +}; + +/** + * Sets all elements to zero + * @method reset + */ +ArrayCollisionMatrix.prototype.reset = function() { + for (var i=0, l=this.matrix.length; i!==l; i++) { + this.matrix[i]=0; + } +}; + +/** + * Sets the max number of objects + * @method setNumObjects + * @param {Number} n + */ +ArrayCollisionMatrix.prototype.setNumObjects = function(n) { + this.matrix.length = n*(n-1)>>1; +}; + +},{}],5:[function(_dereq_,module,exports){ +var Body = _dereq_('../objects/Body'); +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var Shape = _dereq_('../shapes/Shape'); +var Plane = _dereq_('../shapes/Plane'); + +module.exports = Broadphase; + +/** + * Base class for broadphase implementations + * @class Broadphase + * @constructor + * @author schteppe + */ +function Broadphase(){ + /** + * The world to search for collisions in. + * @property world + * @type {World} + */ + this.world = null; + + /** + * If set to true, the broadphase uses bounding boxes for intersection test, else it uses bounding spheres. + * @property useBoundingBoxes + * @type {Boolean} + */ + this.useBoundingBoxes = false; + + /** + * Set to true if the objects in the world moved. + * @property {Boolean} dirty + */ + this.dirty = true; +} + +/** + * Get the collision pairs from the world + * @method collisionPairs + * @param {World} world The world to search in + * @param {Array} p1 Empty array to be filled with body objects + * @param {Array} p2 Empty array to be filled with body objects + */ +Broadphase.prototype.collisionPairs = function(world,p1,p2){ + throw new Error("collisionPairs not implemented for this BroadPhase class!"); +}; + +/** + * Check if a body pair needs to be intersection tested at all. + * @method needBroadphaseCollision + * @param {Body} bodyA + * @param {Body} bodyB + * @return {bool} + */ +var Broadphase_needBroadphaseCollision_STATIC_OR_KINEMATIC = Body.STATIC | Body.KINEMATIC; +Broadphase.prototype.needBroadphaseCollision = function(bodyA,bodyB){ + + // Check collision filter masks + if( (bodyA.collisionFilterGroup & bodyB.collisionFilterMask)===0 || (bodyB.collisionFilterGroup & bodyA.collisionFilterMask)===0){ + return false; + } + + // Check types + if(((bodyA.type & Body.STATIC)!==0 || bodyA.sleepState === Body.SLEEPING) && + ((bodyB.type & Body.STATIC)!==0 || bodyB.sleepState === Body.SLEEPING)) { + // Both bodies are static, kinematic or sleeping. Skip. + return false; + } + + return true; +}; + +/** + * Check if the bounding volumes of two bodies intersect. + * @method intersectionTest + * @param {Body} bodyA + * @param {Body} bodyB + * @param {array} pairs1 + * @param {array} pairs2 + */ +Broadphase.prototype.intersectionTest = function(bodyA, bodyB, pairs1, pairs2){ + if(this.useBoundingBoxes){ + this.doBoundingBoxBroadphase(bodyA,bodyB,pairs1,pairs2); + } else { + this.doBoundingSphereBroadphase(bodyA,bodyB,pairs1,pairs2); + } +}; + +/** + * Check if the bounding spheres of two bodies are intersecting. + * @method doBoundingSphereBroadphase + * @param {Body} bodyA + * @param {Body} bodyB + * @param {Array} pairs1 bodyA is appended to this array if intersection + * @param {Array} pairs2 bodyB is appended to this array if intersection + */ +var Broadphase_collisionPairs_r = new Vec3(), // Temp objects + Broadphase_collisionPairs_normal = new Vec3(), + Broadphase_collisionPairs_quat = new Quaternion(), + Broadphase_collisionPairs_relpos = new Vec3(); +Broadphase.prototype.doBoundingSphereBroadphase = function(bodyA,bodyB,pairs1,pairs2){ + var r = Broadphase_collisionPairs_r; + bodyB.position.vsub(bodyA.position,r); + var boundingRadiusSum2 = Math.pow(bodyA.boundingRadius + bodyB.boundingRadius, 2); + var norm2 = r.norm2(); + if(norm2 < boundingRadiusSum2){ + pairs1.push(bodyA); + pairs2.push(bodyB); + } +}; + +/** + * Check if the bounding boxes of two bodies are intersecting. + * @method doBoundingBoxBroadphase + * @param {Body} bodyA + * @param {Body} bodyB + * @param {Array} pairs1 + * @param {Array} pairs2 + */ +Broadphase.prototype.doBoundingBoxBroadphase = function(bodyA,bodyB,pairs1,pairs2){ + if(bodyA.aabbNeedsUpdate){ + bodyA.computeAABB(); + } + if(bodyB.aabbNeedsUpdate){ + bodyB.computeAABB(); + } + + // Check AABB / AABB + if(bodyA.aabb.overlaps(bodyB.aabb)){ + pairs1.push(bodyA); + pairs2.push(bodyB); + } +}; + +/** + * Removes duplicate pairs from the pair arrays. + * @method makePairsUnique + * @param {Array} pairs1 + * @param {Array} pairs2 + */ +var Broadphase_makePairsUnique_temp = { keys:[] }, + Broadphase_makePairsUnique_p1 = [], + Broadphase_makePairsUnique_p2 = []; +Broadphase.prototype.makePairsUnique = function(pairs1,pairs2){ + var t = Broadphase_makePairsUnique_temp, + p1 = Broadphase_makePairsUnique_p1, + p2 = Broadphase_makePairsUnique_p2, + N = pairs1.length; + + for(var i=0; i!==N; i++){ + p1[i] = pairs1[i]; + p2[i] = pairs2[i]; + } + + pairs1.length = 0; + pairs2.length = 0; + + for(var i=0; i!==N; i++){ + var id1 = p1[i].id, + id2 = p2[i].id; + var key = id1 < id2 ? id1+","+id2 : id2+","+id1; + t[key] = i; + t.keys.push(key); + } + + for(var i=0; i!==t.keys.length; i++){ + var key = t.keys.pop(), + pairIndex = t[key]; + pairs1.push(p1[pairIndex]); + pairs2.push(p2[pairIndex]); + delete t[key]; + } +}; + +/** + * To be implemented by subcasses + * @method setWorld + * @param {World} world + */ +Broadphase.prototype.setWorld = function(world){ +}; + +/** + * Check if the bounding spheres of two bodies overlap. + * @method boundingSphereCheck + * @param {Body} bodyA + * @param {Body} bodyB + * @return {boolean} + */ +var bsc_dist = new Vec3(); +Broadphase.boundingSphereCheck = function(bodyA,bodyB){ + var dist = bsc_dist; + bodyA.position.vsub(bodyB.position,dist); + return Math.pow(bodyA.shape.boundingSphereRadius + bodyB.shape.boundingSphereRadius,2) > dist.norm2(); +}; + +/** + * Returns all the bodies within the AABB. + * @method aabbQuery + * @param {World} world + * @param {AABB} aabb + * @param {array} result An array to store resulting bodies in. + * @return {array} + */ +Broadphase.prototype.aabbQuery = function(world, aabb, result){ + console.warn('.aabbQuery is not implemented in this Broadphase subclass.'); + return []; +}; +},{"../math/Quaternion":28,"../math/Vec3":30,"../objects/Body":31,"../shapes/Plane":42,"../shapes/Shape":43}],6:[function(_dereq_,module,exports){ +module.exports = GridBroadphase; + +var Broadphase = _dereq_('./Broadphase'); +var Vec3 = _dereq_('../math/Vec3'); +var Shape = _dereq_('../shapes/Shape'); + +/** + * Axis aligned uniform grid broadphase. + * @class GridBroadphase + * @constructor + * @extends Broadphase + * @todo Needs support for more than just planes and spheres. + * @param {Vec3} aabbMin + * @param {Vec3} aabbMax + * @param {Number} nx Number of boxes along x + * @param {Number} ny Number of boxes along y + * @param {Number} nz Number of boxes along z + */ +function GridBroadphase(aabbMin,aabbMax,nx,ny,nz){ + Broadphase.apply(this); + this.nx = nx || 10; + this.ny = ny || 10; + this.nz = nz || 10; + this.aabbMin = aabbMin || new Vec3(100,100,100); + this.aabbMax = aabbMax || new Vec3(-100,-100,-100); + var nbins = this.nx * this.ny * this.nz; + if (nbins <= 0) { + throw "GridBroadphase: Each dimension's n must be >0"; + } + this.bins = []; + this.binLengths = []; //Rather than continually resizing arrays (thrashing the memory), just record length and allow them to grow + this.bins.length = nbins; + this.binLengths.length = nbins; + for (var i=0;i= nx) { xoff0 = nx - 1; } + if (yoff0 < 0) { yoff0 = 0; } else if (yoff0 >= ny) { yoff0 = ny - 1; } + if (zoff0 < 0) { zoff0 = 0; } else if (zoff0 >= nz) { zoff0 = nz - 1; } + if (xoff1 < 0) { xoff1 = 0; } else if (xoff1 >= nx) { xoff1 = nx - 1; } + if (yoff1 < 0) { yoff1 = 0; } else if (yoff1 >= ny) { yoff1 = ny - 1; } + if (zoff1 < 0) { zoff1 = 0; } else if (zoff1 >= nz) { zoff1 = nz - 1; } + + xoff0 *= xstep; + yoff0 *= ystep; + zoff0 *= zstep; + xoff1 *= xstep; + yoff1 *= ystep; + zoff1 *= zstep; + + for (var xoff = xoff0; xoff <= xoff1; xoff += xstep) { + for (var yoff = yoff0; yoff <= yoff1; yoff += ystep) { + for (var zoff = zoff0; zoff <= zoff1; zoff += zstep) { + var idx = xoff+yoff+zoff; + bins[idx][binLengths[idx]++] = bi; + } + } + } + } + + // Put all bodies into the bins + for(var i=0; i!==N; i++){ + var bi = bodies[i]; + var si = bi.shape; + + switch(si.type){ + case SPHERE: + // Put in bin + // check if overlap with other bins + var x = bi.position.x, + y = bi.position.y, + z = bi.position.z; + var r = si.radius; + + addBoxToBins(x-r, y-r, z-r, x+r, y+r, z+r, bi); + break; + + case PLANE: + if(si.worldNormalNeedsUpdate){ + si.computeWorldNormal(bi.quaternion); + } + var planeNormal = si.worldNormal; + + //Relative position from origin of plane object to the first bin + //Incremented as we iterate through the bins + var xreset = xmin + binsizeX*0.5 - bi.position.x, + yreset = ymin + binsizeY*0.5 - bi.position.y, + zreset = zmin + binsizeZ*0.5 - bi.position.z; + + var d = GridBroadphase_collisionPairs_d; + d.set(xreset, yreset, zreset); + + for (var xi = 0, xoff = 0; xi !== nx; xi++, xoff += xstep, d.y = yreset, d.x += binsizeX) { + for (var yi = 0, yoff = 0; yi !== ny; yi++, yoff += ystep, d.z = zreset, d.y += binsizeY) { + for (var zi = 0, zoff = 0; zi !== nz; zi++, zoff += zstep, d.z += binsizeZ) { + if (d.dot(planeNormal) < binRadius) { + var idx = xoff + yoff + zoff; + bins[idx][binLengths[idx]++] = bi; + } + } + } + } + break; + + default: + if (bi.aabbNeedsUpdate) { + bi.computeAABB(); + } + + addBoxToBins( + bi.aabb.lowerBound.x, + bi.aabb.lowerBound.y, + bi.aabb.lowerBound.z, + bi.aabb.upperBound.x, + bi.aabb.upperBound.y, + bi.aabb.upperBound.z, + bi); + break; + } + } + + // Check each bin + for(var i=0; i!==Nbins; i++){ + var binLength = binLengths[i]; + //Skip bins with no potential collisions + if (binLength > 1) { + var bin = bins[i]; + + // Do N^2 broadphase inside + for(var xi=0; xi!==binLength; xi++){ + var bi = bin[xi]; + for(var yi=0; yi!==xi; yi++){ + var bj = bin[yi]; + if(this.needBroadphaseCollision(bi,bj)){ + this.intersectionTest(bi,bj,pairs1,pairs2); + } + } + } + } + } + +// for (var zi = 0, zoff=0; zi < nz; zi++, zoff+= zstep) { +// console.log("layer "+zi); +// for (var yi = 0, yoff=0; yi < ny; yi++, yoff += ystep) { +// var row = ''; +// for (var xi = 0, xoff=0; xi < nx; xi++, xoff += xstep) { +// var idx = xoff + yoff + zoff; +// row += ' ' + binLengths[idx]; +// } +// console.log(row); +// } +// } + + this.makePairsUnique(pairs1,pairs2); +}; + +},{"../math/Vec3":30,"../shapes/Shape":43,"./Broadphase":5}],7:[function(_dereq_,module,exports){ +module.exports = NaiveBroadphase; + +var Broadphase = _dereq_('./Broadphase'); +var AABB = _dereq_('./AABB'); + +/** + * Naive broadphase implementation, used in lack of better ones. + * @class NaiveBroadphase + * @constructor + * @description The naive broadphase looks at all possible pairs without restriction, therefore it has complexity N^2 (which is bad) + * @extends Broadphase + */ +function NaiveBroadphase(){ + Broadphase.apply(this); +} +NaiveBroadphase.prototype = new Broadphase(); +NaiveBroadphase.prototype.constructor = NaiveBroadphase; + +/** + * Get all the collision pairs in the physics world + * @method collisionPairs + * @param {World} world + * @param {Array} pairs1 + * @param {Array} pairs2 + */ +NaiveBroadphase.prototype.collisionPairs = function(world,pairs1,pairs2){ + var bodies = world.bodies, + n = bodies.length, + i,j,bi,bj; + + // Naive N^2 ftw! + for(i=0; i!==n; i++){ + for(j=0; j!==i; j++){ + + bi = bodies[i]; + bj = bodies[j]; + + if(!this.needBroadphaseCollision(bi,bj)){ + continue; + } + + this.intersectionTest(bi,bj,pairs1,pairs2); + } + } +}; + +var tmpAABB = new AABB(); + +/** + * Returns all the bodies within an AABB. + * @method aabbQuery + * @param {World} world + * @param {AABB} aabb + * @param {array} result An array to store resulting bodies in. + * @return {array} + */ +NaiveBroadphase.prototype.aabbQuery = function(world, aabb, result){ + result = result || []; + + for(var i = 0; i < world.bodies.length; i++){ + var b = world.bodies[i]; + + if(b.aabbNeedsUpdate){ + b.computeAABB(); + } + + // Ugly hack until Body gets aabb + if(b.aabb.overlaps(aabb)){ + result.push(b); + } + } + + return result; +}; +},{"./AABB":3,"./Broadphase":5}],8:[function(_dereq_,module,exports){ +module.exports = ObjectCollisionMatrix; + +/** + * Records what objects are colliding with each other + * @class ObjectCollisionMatrix + * @constructor + */ +function ObjectCollisionMatrix() { + + /** + * The matrix storage + * @property matrix + * @type {Object} + */ + this.matrix = {}; +} + +/** + * @method get + * @param {Number} i + * @param {Number} j + * @return {Number} + */ +ObjectCollisionMatrix.prototype.get = function(i, j) { + i = i.id; + j = j.id; + if (j > i) { + var temp = j; + j = i; + i = temp; + } + return i+'-'+j in this.matrix; +}; + +/** + * @method set + * @param {Number} i + * @param {Number} j + * @param {Number} value + */ +ObjectCollisionMatrix.prototype.set = function(i, j, value) { + i = i.id; + j = j.id; + if (j > i) { + var temp = j; + j = i; + i = temp; + } + if (value) { + this.matrix[i+'-'+j] = true; + } + else { + delete this.matrix[i+'-'+j]; + } +}; + +/** + * Empty the matrix + * @method reset + */ +ObjectCollisionMatrix.prototype.reset = function() { + this.matrix = {}; +}; + +/** + * Set max number of objects + * @method setNumObjects + * @param {Number} n + */ +ObjectCollisionMatrix.prototype.setNumObjects = function(n) { +}; + +},{}],9:[function(_dereq_,module,exports){ +module.exports = Ray; + +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var Transform = _dereq_('../math/Transform'); +var ConvexPolyhedron = _dereq_('../shapes/ConvexPolyhedron'); +var Box = _dereq_('../shapes/Box'); +var RaycastResult = _dereq_('../collision/RaycastResult'); +var Shape = _dereq_('../shapes/Shape'); +var AABB = _dereq_('../collision/AABB'); + +/** + * A line in 3D space that intersects bodies and return points. + * @class Ray + * @constructor + * @param {Vec3} from + * @param {Vec3} to + */ +function Ray(from, to){ + /** + * @property {Vec3} from + */ + this.from = from ? from.clone() : new Vec3(); + + /** + * @property {Vec3} to + */ + this.to = to ? to.clone() : new Vec3(); + + /** + * @private + * @property {Vec3} _direction + */ + this._direction = new Vec3(); + + /** + * The precision of the ray. Used when checking parallelity etc. + * @property {Number} precision + */ + this.precision = 0.0001; + + /** + * Set to true if you want the Ray to take .collisionResponse flags into account on bodies and shapes. + * @property {Boolean} checkCollisionResponse + */ + this.checkCollisionResponse = true; + + /** + * If set to true, the ray skips any hits with normal.dot(rayDirection) < 0. + * @property {Boolean} skipBackfaces + */ + this.skipBackfaces = false; + + /** + * @property {number} collisionFilterMask + * @default -1 + */ + this.collisionFilterMask = -1; + + /** + * @property {number} collisionFilterGroup + * @default -1 + */ + this.collisionFilterGroup = -1; + + /** + * The intersection mode. Should be Ray.ANY, Ray.ALL or Ray.CLOSEST. + * @property {number} mode + */ + this.mode = Ray.ANY; + + /** + * Current result object. + * @property {RaycastResult} result + */ + this.result = new RaycastResult(); + + /** + * Will be set to true during intersectWorld() if the ray hit anything. + * @property {Boolean} hasHit + */ + this.hasHit = false; + + /** + * Current, user-provided result callback. Will be used if mode is Ray.ALL. + * @property {Function} callback + */ + this.callback = function(result){}; +} +Ray.prototype.constructor = Ray; + +Ray.CLOSEST = 1; +Ray.ANY = 2; +Ray.ALL = 4; + +var tmpAABB = new AABB(); +var tmpArray = []; + +/** + * Do itersection against all bodies in the given World. + * @method intersectWorld + * @param {World} world + * @param {object} options + * @return {Boolean} True if the ray hit anything, otherwise false. + */ +Ray.prototype.intersectWorld = function (world, options) { + this.mode = options.mode || Ray.ANY; + this.result = options.result || new RaycastResult(); + this.skipBackfaces = !!options.skipBackfaces; + this.collisionFilterMask = typeof(options.collisionFilterMask) !== 'undefined' ? options.collisionFilterMask : -1; + this.collisionFilterGroup = typeof(options.collisionFilterGroup) !== 'undefined' ? options.collisionFilterGroup : -1; + if(options.from){ + this.from.copy(options.from); + } + if(options.to){ + this.to.copy(options.to); + } + this.callback = options.callback || function(){}; + this.hasHit = false; + + this.result.reset(); + this._updateDirection(); + + this.getAABB(tmpAABB); + tmpArray.length = 0; + world.broadphase.aabbQuery(world, tmpAABB, tmpArray); + this.intersectBodies(tmpArray); + + return this.hasHit; +}; + +var v1 = new Vec3(), + v2 = new Vec3(); + +/* + * As per "Barycentric Technique" as named here http://www.blackpawn.com/texts/pointinpoly/default.html But without the division + */ +Ray.pointInTriangle = pointInTriangle; +function pointInTriangle(p, a, b, c) { + c.vsub(a,v0); + b.vsub(a,v1); + p.vsub(a,v2); + + var dot00 = v0.dot( v0 ); + var dot01 = v0.dot( v1 ); + var dot02 = v0.dot( v2 ); + var dot11 = v1.dot( v1 ); + var dot12 = v1.dot( v2 ); + + var u,v; + + return ( (u = dot11 * dot02 - dot01 * dot12) >= 0 ) && + ( (v = dot00 * dot12 - dot01 * dot02) >= 0 ) && + ( u + v < ( dot00 * dot11 - dot01 * dot01 ) ); +} + +/** + * Shoot a ray at a body, get back information about the hit. + * @method intersectBody + * @private + * @param {Body} body + * @param {RaycastResult} [result] Deprecated - set the result property of the Ray instead. + */ +var intersectBody_xi = new Vec3(); +var intersectBody_qi = new Quaternion(); +Ray.prototype.intersectBody = function (body, result) { + if(result){ + this.result = result; + this._updateDirection(); + } + var checkCollisionResponse = this.checkCollisionResponse; + + if(checkCollisionResponse && !body.collisionResponse){ + return; + } + + if((this.collisionFilterGroup & body.collisionFilterMask)===0 || (body.collisionFilterGroup & this.collisionFilterMask)===0){ + return; + } + + var xi = intersectBody_xi; + var qi = intersectBody_qi; + + for (var i = 0, N = body.shapes.length; i < N; i++) { + var shape = body.shapes[i]; + + if(checkCollisionResponse && !shape.collisionResponse){ + continue; // Skip + } + + body.quaternion.mult(body.shapeOrientations[i], qi); + body.quaternion.vmult(body.shapeOffsets[i], xi); + xi.vadd(body.position, xi); + + this.intersectShape( + shape, + qi, + xi, + body + ); + + if(this.result._shouldStop){ + break; + } + } +}; + +/** + * @method intersectBodies + * @param {Array} bodies An array of Body objects. + * @param {RaycastResult} [result] Deprecated + */ +Ray.prototype.intersectBodies = function (bodies, result) { + if(result){ + this.result = result; + this._updateDirection(); + } + + for ( var i = 0, l = bodies.length; !this.result._shouldStop && i < l; i ++ ) { + this.intersectBody(bodies[i]); + } +}; + +/** + * Updates the _direction vector. + * @private + * @method _updateDirection + */ +Ray.prototype._updateDirection = function(){ + this.to.vsub(this.from, this._direction); + this._direction.normalize(); +}; + +/** + * @method intersectShape + * @private + * @param {Shape} shape + * @param {Quaternion} quat + * @param {Vec3} position + * @param {Body} body + */ +Ray.prototype.intersectShape = function(shape, quat, position, body){ + var from = this.from; + + + // Checking boundingSphere + var distance = distanceFromIntersection(from, this._direction, position); + if ( distance > shape.boundingSphereRadius ) { + return; + } + + var intersectMethod = this[shape.type]; + if(intersectMethod){ + intersectMethod.call(this, shape, quat, position, body); + } +}; + +var vector = new Vec3(); +var normal = new Vec3(); +var intersectPoint = new Vec3(); + +var a = new Vec3(); +var b = new Vec3(); +var c = new Vec3(); +var d = new Vec3(); + +var tmpRaycastResult = new RaycastResult(); + +/** + * @method intersectBox + * @private + * @param {Shape} shape + * @param {Quaternion} quat + * @param {Vec3} position + * @param {Body} body + */ +Ray.prototype.intersectBox = function(shape, quat, position, body){ + return this.intersectConvex(shape.convexPolyhedronRepresentation, quat, position, body); +}; +Ray.prototype[Shape.types.BOX] = Ray.prototype.intersectBox; + +/** + * @method intersectPlane + * @private + * @param {Shape} shape + * @param {Quaternion} quat + * @param {Vec3} position + * @param {Body} body + */ +Ray.prototype.intersectPlane = function(shape, quat, position, body){ + var from = this.from; + var to = this.to; + var direction = this._direction; + + // Get plane normal + var worldNormal = new Vec3(0, 0, 1); + quat.vmult(worldNormal, worldNormal); + + var len = new Vec3(); + from.vsub(position, len); + var planeToFrom = len.dot(worldNormal); + to.vsub(position, len); + var planeToTo = len.dot(worldNormal); + + if(planeToFrom * planeToTo > 0){ + // "from" and "to" are on the same side of the plane... bail out + return; + } + + if(from.distanceTo(to) < planeToFrom){ + return; + } + + var n_dot_dir = worldNormal.dot(direction); + + if (Math.abs(n_dot_dir) < this.precision) { + // No intersection + return; + } + + var planePointToFrom = new Vec3(); + var dir_scaled_with_t = new Vec3(); + var hitPointWorld = new Vec3(); + + from.vsub(position, planePointToFrom); + var t = -worldNormal.dot(planePointToFrom) / n_dot_dir; + direction.scale(t, dir_scaled_with_t); + from.vadd(dir_scaled_with_t, hitPointWorld); + + this.reportIntersection(worldNormal, hitPointWorld, shape, body, -1); +}; +Ray.prototype[Shape.types.PLANE] = Ray.prototype.intersectPlane; + +/** + * Get the world AABB of the ray. + * @method getAABB + * @param {AABB} aabb + */ +Ray.prototype.getAABB = function(result){ + var to = this.to; + var from = this.from; + result.lowerBound.x = Math.min(to.x, from.x); + result.lowerBound.y = Math.min(to.y, from.y); + result.lowerBound.z = Math.min(to.z, from.z); + result.upperBound.x = Math.max(to.x, from.x); + result.upperBound.y = Math.max(to.y, from.y); + result.upperBound.z = Math.max(to.z, from.z); +}; + +var intersectConvexOptions = { + faceList: [0] +}; + +/** + * @method intersectHeightfield + * @private + * @param {Shape} shape + * @param {Quaternion} quat + * @param {Vec3} position + * @param {Body} body + */ +Ray.prototype.intersectHeightfield = function(shape, quat, position, body){ + var data = shape.data, + w = shape.elementSize, + worldPillarOffset = new Vec3(); + + // Convert the ray to local heightfield coordinates + var localRay = new Ray(this.from, this.to); + Transform.pointToLocalFrame(position, quat, localRay.from, localRay.from); + Transform.pointToLocalFrame(position, quat, localRay.to, localRay.to); + + // Get the index of the data points to test against + var index = []; + var iMinX = null; + var iMinY = null; + var iMaxX = null; + var iMaxY = null; + + var inside = shape.getIndexOfPosition(localRay.from.x, localRay.from.y, index, false); + if(inside){ + iMinX = index[0]; + iMinY = index[1]; + iMaxX = index[0]; + iMaxY = index[1]; + } + inside = shape.getIndexOfPosition(localRay.to.x, localRay.to.y, index, false); + if(inside){ + if (iMinX === null || index[0] < iMinX) { iMinX = index[0]; } + if (iMaxX === null || index[0] > iMaxX) { iMaxX = index[0]; } + if (iMinY === null || index[1] < iMinY) { iMinY = index[1]; } + if (iMaxY === null || index[1] > iMaxY) { iMaxY = index[1]; } + } + + if(iMinX === null){ + return; + } + + var minMax = []; + shape.getRectMinMax(iMinX, iMinY, iMaxX, iMaxY, minMax); + var min = minMax[0]; + var max = minMax[1]; + + // // Bail out if the ray can't touch the bounding box + // // TODO + // var aabb = new AABB(); + // this.getAABB(aabb); + // if(aabb.intersects()){ + // return; + // } + + for(var i = iMinX; i <= iMaxX; i++){ + for(var j = iMinY; j <= iMaxY; j++){ + + if(this.result._shouldStop){ + return; + } + + // Lower triangle + shape.getConvexTrianglePillar(i, j, false); + Transform.pointToWorldFrame(position, quat, shape.pillarOffset, worldPillarOffset); + this.intersectConvex(shape.pillarConvex, quat, worldPillarOffset, body, intersectConvexOptions); + + if(this.result._shouldStop){ + return; + } + + // Upper triangle + shape.getConvexTrianglePillar(i, j, true); + Transform.pointToWorldFrame(position, quat, shape.pillarOffset, worldPillarOffset); + this.intersectConvex(shape.pillarConvex, quat, worldPillarOffset, body, intersectConvexOptions); + } + } +}; +Ray.prototype[Shape.types.HEIGHTFIELD] = Ray.prototype.intersectHeightfield; + +var Ray_intersectSphere_intersectionPoint = new Vec3(); +var Ray_intersectSphere_normal = new Vec3(); + +/** + * @method intersectSphere + * @private + * @param {Shape} shape + * @param {Quaternion} quat + * @param {Vec3} position + * @param {Body} body + */ +Ray.prototype.intersectSphere = function(shape, quat, position, body){ + var from = this.from, + to = this.to, + r = shape.radius; + + var a = Math.pow(to.x - from.x, 2) + Math.pow(to.y - from.y, 2) + Math.pow(to.z - from.z, 2); + var b = 2 * ((to.x - from.x) * (from.x - position.x) + (to.y - from.y) * (from.y - position.y) + (to.z - from.z) * (from.z - position.z)); + var c = Math.pow(from.x - position.x, 2) + Math.pow(from.y - position.y, 2) + Math.pow(from.z - position.z, 2) - Math.pow(r, 2); + + var delta = Math.pow(b, 2) - 4 * a * c; + + var intersectionPoint = Ray_intersectSphere_intersectionPoint; + var normal = Ray_intersectSphere_normal; + + if(delta < 0){ + // No intersection + return; + + } else if(delta === 0){ + // single intersection point + from.lerp(to, delta, intersectionPoint); + + intersectionPoint.vsub(position, normal); + normal.normalize(); + + this.reportIntersection(normal, intersectionPoint, shape, body, -1); + + } else { + var d1 = (- b - Math.sqrt(delta)) / (2 * a); + var d2 = (- b + Math.sqrt(delta)) / (2 * a); + + if(d1 >= 0 && d1 <= 1){ + from.lerp(to, d1, intersectionPoint); + intersectionPoint.vsub(position, normal); + normal.normalize(); + this.reportIntersection(normal, intersectionPoint, shape, body, -1); + } + + if(this.result._shouldStop){ + return; + } + + if(d2 >= 0 && d2 <= 1){ + from.lerp(to, d2, intersectionPoint); + intersectionPoint.vsub(position, normal); + normal.normalize(); + this.reportIntersection(normal, intersectionPoint, shape, body, -1); + } + } +}; +Ray.prototype[Shape.types.SPHERE] = Ray.prototype.intersectSphere; + + +var intersectConvex_normal = new Vec3(); +var intersectConvex_minDistNormal = new Vec3(); +var intersectConvex_minDistIntersect = new Vec3(); +var intersectConvex_vector = new Vec3(); + +/** + * @method intersectConvex + * @private + * @param {Shape} shape + * @param {Quaternion} quat + * @param {Vec3} position + * @param {Body} body + * @param {object} [options] + * @param {array} [options.faceList] + */ +Ray.prototype.intersectConvex = function intersectConvex( + shape, + quat, + position, + body, + options +){ + var minDistNormal = intersectConvex_minDistNormal; + var normal = intersectConvex_normal; + var vector = intersectConvex_vector; + var minDistIntersect = intersectConvex_minDistIntersect; + var faceList = (options && options.faceList) || null; + + // Checking faces + var faces = shape.faces, + vertices = shape.vertices, + normals = shape.faceNormals; + var direction = this._direction; + + var from = this.from; + var to = this.to; + var fromToDistance = from.distanceTo(to); + + var minDist = -1; + var Nfaces = faceList ? faceList.length : faces.length; + var result = this.result; + + for (var j = 0; !result._shouldStop && j < Nfaces; j++) { + var fi = faceList ? faceList[j] : j; + + var face = faces[fi]; + var faceNormal = normals[fi]; + var q = quat; + var x = position; + + // determine if ray intersects the plane of the face + // note: this works regardless of the direction of the face normal + + // Get plane point in world coordinates... + vector.copy(vertices[face[0]]); + q.vmult(vector,vector); + vector.vadd(x,vector); + + // ...but make it relative to the ray from. We'll fix this later. + vector.vsub(from,vector); + + // Get plane normal + q.vmult(faceNormal,normal); + + // If this dot product is negative, we have something interesting + var dot = direction.dot(normal); + + // Bail out if ray and plane are parallel + if ( Math.abs( dot ) < this.precision ){ + continue; + } + + // calc distance to plane + var scalar = normal.dot(vector) / dot; + + // if negative distance, then plane is behind ray + if (scalar < 0){ + continue; + } + + // if (dot < 0) { + + // Intersection point is from + direction * scalar + direction.mult(scalar,intersectPoint); + intersectPoint.vadd(from,intersectPoint); + + // a is the point we compare points b and c with. + a.copy(vertices[face[0]]); + q.vmult(a,a); + x.vadd(a,a); + + for(var i = 1; !result._shouldStop && i < face.length - 1; i++){ + // Transform 3 vertices to world coords + b.copy(vertices[face[i]]); + c.copy(vertices[face[i+1]]); + q.vmult(b,b); + q.vmult(c,c); + x.vadd(b,b); + x.vadd(c,c); + + var distance = intersectPoint.distanceTo(from); + + if(!(pointInTriangle(intersectPoint, a, b, c) || pointInTriangle(intersectPoint, b, a, c)) || distance > fromToDistance){ + continue; + } + + this.reportIntersection(normal, intersectPoint, shape, body, fi); + } + // } + } +}; +Ray.prototype[Shape.types.CONVEXPOLYHEDRON] = Ray.prototype.intersectConvex; + +var intersectTrimesh_normal = new Vec3(); +var intersectTrimesh_localDirection = new Vec3(); +var intersectTrimesh_localFrom = new Vec3(); +var intersectTrimesh_localTo = new Vec3(); +var intersectTrimesh_worldNormal = new Vec3(); +var intersectTrimesh_worldIntersectPoint = new Vec3(); +var intersectTrimesh_localAABB = new AABB(); +var intersectTrimesh_triangles = []; +var intersectTrimesh_treeTransform = new Transform(); + +/** + * @method intersectTrimesh + * @private + * @param {Shape} shape + * @param {Quaternion} quat + * @param {Vec3} position + * @param {Body} body + * @param {object} [options] + * @todo Optimize by transforming the world to local space first. + * @todo Use Octree lookup + */ +Ray.prototype.intersectTrimesh = function intersectTrimesh( + mesh, + quat, + position, + body, + options +){ + var normal = intersectTrimesh_normal; + var triangles = intersectTrimesh_triangles; + var treeTransform = intersectTrimesh_treeTransform; + var minDistNormal = intersectConvex_minDistNormal; + var vector = intersectConvex_vector; + var minDistIntersect = intersectConvex_minDistIntersect; + var localAABB = intersectTrimesh_localAABB; + var localDirection = intersectTrimesh_localDirection; + var localFrom = intersectTrimesh_localFrom; + var localTo = intersectTrimesh_localTo; + var worldIntersectPoint = intersectTrimesh_worldIntersectPoint; + var worldNormal = intersectTrimesh_worldNormal; + var faceList = (options && options.faceList) || null; + + // Checking faces + var indices = mesh.indices, + vertices = mesh.vertices, + normals = mesh.faceNormals; + + var from = this.from; + var to = this.to; + var direction = this._direction; + + var minDist = -1; + treeTransform.position.copy(position); + treeTransform.quaternion.copy(quat); + + // Transform ray to local space! + Transform.vectorToLocalFrame(position, quat, direction, localDirection); + //body.vectorToLocalFrame(direction, localDirection); + Transform.pointToLocalFrame(position, quat, from, localFrom); + //body.pointToLocalFrame(from, localFrom); + Transform.pointToLocalFrame(position, quat, to, localTo); + //body.pointToLocalFrame(to, localTo); + var fromToDistanceSquared = localFrom.distanceSquared(localTo); + + mesh.tree.rayQuery(this, treeTransform, triangles); + + for (var i = 0, N = triangles.length; !this.result._shouldStop && i !== N; i++) { + var trianglesIndex = triangles[i]; + + mesh.getNormal(trianglesIndex, normal); + + // determine if ray intersects the plane of the face + // note: this works regardless of the direction of the face normal + + // Get plane point in world coordinates... + mesh.getVertex(indices[trianglesIndex * 3], a); + + // ...but make it relative to the ray from. We'll fix this later. + a.vsub(localFrom,vector); + + // Get plane normal + // quat.vmult(normal, normal); + + // If this dot product is negative, we have something interesting + var dot = localDirection.dot(normal); + + // Bail out if ray and plane are parallel + // if (Math.abs( dot ) < this.precision){ + // continue; + // } + + // calc distance to plane + var scalar = normal.dot(vector) / dot; + + // if negative distance, then plane is behind ray + if (scalar < 0){ + continue; + } + + // Intersection point is from + direction * scalar + localDirection.scale(scalar,intersectPoint); + intersectPoint.vadd(localFrom,intersectPoint); + + // Get triangle vertices + mesh.getVertex(indices[trianglesIndex * 3 + 1], b); + mesh.getVertex(indices[trianglesIndex * 3 + 2], c); + + var squaredDistance = intersectPoint.distanceSquared(localFrom); + + if(!(pointInTriangle(intersectPoint, b, a, c) || pointInTriangle(intersectPoint, a, b, c)) || squaredDistance > fromToDistanceSquared){ + continue; + } + + // transform intersectpoint and normal to world + Transform.vectorToWorldFrame(quat, normal, worldNormal); + //body.vectorToWorldFrame(normal, worldNormal); + Transform.pointToWorldFrame(position, quat, intersectPoint, worldIntersectPoint); + //body.pointToWorldFrame(intersectPoint, worldIntersectPoint); + this.reportIntersection(worldNormal, worldIntersectPoint, mesh, body, trianglesIndex); + } + triangles.length = 0; +}; +Ray.prototype[Shape.types.TRIMESH] = Ray.prototype.intersectTrimesh; + + +/** + * @method reportIntersection + * @private + * @param {Vec3} normal + * @param {Vec3} hitPointWorld + * @param {Shape} shape + * @param {Body} body + * @return {boolean} True if the intersections should continue + */ +Ray.prototype.reportIntersection = function(normal, hitPointWorld, shape, body, hitFaceIndex){ + var from = this.from; + var to = this.to; + var distance = from.distanceTo(hitPointWorld); + var result = this.result; + + // Skip back faces? + if(this.skipBackfaces && normal.dot(this._direction) > 0){ + return; + } + + result.hitFaceIndex = typeof(hitFaceIndex) !== 'undefined' ? hitFaceIndex : -1; + + switch(this.mode){ + case Ray.ALL: + this.hasHit = true; + result.set( + from, + to, + normal, + hitPointWorld, + shape, + body, + distance + ); + result.hasHit = true; + this.callback(result); + break; + + case Ray.CLOSEST: + + // Store if closer than current closest + if(distance < result.distance || !result.hasHit){ + this.hasHit = true; + result.hasHit = true; + result.set( + from, + to, + normal, + hitPointWorld, + shape, + body, + distance + ); + } + break; + + case Ray.ANY: + + // Report and stop. + this.hasHit = true; + result.hasHit = true; + result.set( + from, + to, + normal, + hitPointWorld, + shape, + body, + distance + ); + result._shouldStop = true; + break; + } +}; + +var v0 = new Vec3(), + intersect = new Vec3(); +function distanceFromIntersection(from, direction, position) { + + // v0 is vector from from to position + position.vsub(from,v0); + var dot = v0.dot(direction); + + // intersect = direction*dot + from + direction.mult(dot,intersect); + intersect.vadd(from,intersect); + + var distance = position.distanceTo(intersect); + + return distance; +} + + +},{"../collision/AABB":3,"../collision/RaycastResult":10,"../math/Quaternion":28,"../math/Transform":29,"../math/Vec3":30,"../shapes/Box":37,"../shapes/ConvexPolyhedron":38,"../shapes/Shape":43}],10:[function(_dereq_,module,exports){ +var Vec3 = _dereq_('../math/Vec3'); + +module.exports = RaycastResult; + +/** + * Storage for Ray casting data. + * @class RaycastResult + * @constructor + */ +function RaycastResult(){ + + /** + * @property {Vec3} rayFromWorld + */ + this.rayFromWorld = new Vec3(); + + /** + * @property {Vec3} rayToWorld + */ + this.rayToWorld = new Vec3(); + + /** + * @property {Vec3} hitNormalWorld + */ + this.hitNormalWorld = new Vec3(); + + /** + * @property {Vec3} hitPointWorld + */ + this.hitPointWorld = new Vec3(); + + /** + * @property {boolean} hasHit + */ + this.hasHit = false; + + /** + * The hit shape, or null. + * @property {Shape} shape + */ + this.shape = null; + + /** + * The hit body, or null. + * @property {Body} body + */ + this.body = null; + + /** + * The index of the hit triangle, if the hit shape was a trimesh. + * @property {number} hitFaceIndex + * @default -1 + */ + this.hitFaceIndex = -1; + + /** + * Distance to the hit. Will be set to -1 if there was no hit. + * @property {number} distance + * @default -1 + */ + this.distance = -1; + + /** + * If the ray should stop traversing the bodies. + * @private + * @property {Boolean} _shouldStop + * @default false + */ + this._shouldStop = false; +} + +/** + * Reset all result data. + * @method reset + */ +RaycastResult.prototype.reset = function () { + this.rayFromWorld.setZero(); + this.rayToWorld.setZero(); + this.hitNormalWorld.setZero(); + this.hitPointWorld.setZero(); + this.hasHit = false; + this.shape = null; + this.body = null; + this.hitFaceIndex = -1; + this.distance = -1; + this._shouldStop = false; +}; + +/** + * @method abort + */ +RaycastResult.prototype.abort = function(){ + this._shouldStop = true; +}; + +/** + * @method set + * @param {Vec3} rayFromWorld + * @param {Vec3} rayToWorld + * @param {Vec3} hitNormalWorld + * @param {Vec3} hitPointWorld + * @param {Shape} shape + * @param {Body} body + * @param {number} distance + */ +RaycastResult.prototype.set = function( + rayFromWorld, + rayToWorld, + hitNormalWorld, + hitPointWorld, + shape, + body, + distance +){ + this.rayFromWorld.copy(rayFromWorld); + this.rayToWorld.copy(rayToWorld); + this.hitNormalWorld.copy(hitNormalWorld); + this.hitPointWorld.copy(hitPointWorld); + this.shape = shape; + this.body = body; + this.distance = distance; +}; +},{"../math/Vec3":30}],11:[function(_dereq_,module,exports){ +var Shape = _dereq_('../shapes/Shape'); +var Broadphase = _dereq_('../collision/Broadphase'); + +module.exports = SAPBroadphase; + +/** + * Sweep and prune broadphase along one axis. + * + * @class SAPBroadphase + * @constructor + * @param {World} [world] + * @extends Broadphase + */ +function SAPBroadphase(world){ + Broadphase.apply(this); + + /** + * List of bodies currently in the broadphase. + * @property axisList + * @type {Array} + */ + this.axisList = []; + + /** + * The world to search in. + * @property world + * @type {World} + */ + this.world = null; + + /** + * Axis to sort the bodies along. Set to 0 for x axis, and 1 for y axis. For best performance, choose an axis that the bodies are spread out more on. + * @property axisIndex + * @type {Number} + */ + this.axisIndex = 0; + + var axisList = this.axisList; + + this._addBodyHandler = function(e){ + axisList.push(e.body); + }; + + this._removeBodyHandler = function(e){ + var idx = axisList.indexOf(e.body); + if(idx !== -1){ + axisList.splice(idx,1); + } + }; + + if(world){ + this.setWorld(world); + } +} +SAPBroadphase.prototype = new Broadphase(); + +/** + * Change the world + * @method setWorld + * @param {World} world + */ +SAPBroadphase.prototype.setWorld = function(world){ + // Clear the old axis array + this.axisList.length = 0; + + // Add all bodies from the new world + for(var i=0; i=0;j--) { + if(a[j].aabb.lowerBound.x <= v.aabb.lowerBound.x){ + break; + } + a[j+1] = a[j]; + } + a[j+1] = v; + } + return a; +}; + +/** + * @static + * @method insertionSortY + * @param {Array} a + * @return {Array} + */ +SAPBroadphase.insertionSortY = function(a) { + for(var i=1,l=a.length;i=0;j--) { + if(a[j].aabb.lowerBound.y <= v.aabb.lowerBound.y){ + break; + } + a[j+1] = a[j]; + } + a[j+1] = v; + } + return a; +}; + +/** + * @static + * @method insertionSortZ + * @param {Array} a + * @return {Array} + */ +SAPBroadphase.insertionSortZ = function(a) { + for(var i=1,l=a.length;i=0;j--) { + if(a[j].aabb.lowerBound.z <= v.aabb.lowerBound.z){ + break; + } + a[j+1] = a[j]; + } + a[j+1] = v; + } + return a; +}; + +/** + * Collect all collision pairs + * @method collisionPairs + * @param {World} world + * @param {Array} p1 + * @param {Array} p2 + */ +SAPBroadphase.prototype.collisionPairs = function(world,p1,p2){ + var bodies = this.axisList, + N = bodies.length, + axisIndex = this.axisIndex, + i, j; + + if(this.dirty){ + this.sortList(); + this.dirty = false; + } + + // Look through the list + for(i=0; i !== N; i++){ + var bi = bodies[i]; + + for(j=i+1; j < N; j++){ + var bj = bodies[j]; + + if(!this.needBroadphaseCollision(bi,bj)){ + continue; + } + + if(!SAPBroadphase.checkBounds(bi,bj,axisIndex)){ + break; + } + + this.intersectionTest(bi,bj,p1,p2); + } + } +}; + +SAPBroadphase.prototype.sortList = function(){ + var axisList = this.axisList; + var axisIndex = this.axisIndex; + var N = axisList.length; + + // Update AABBs + for(var i = 0; i!==N; i++){ + var bi = axisList[i]; + if(bi.aabbNeedsUpdate){ + bi.computeAABB(); + } + } + + // Sort the list + if(axisIndex === 0){ + SAPBroadphase.insertionSortX(axisList); + } else if(axisIndex === 1){ + SAPBroadphase.insertionSortY(axisList); + } else if(axisIndex === 2){ + SAPBroadphase.insertionSortZ(axisList); + } +}; + +/** + * Check if the bounds of two bodies overlap, along the given SAP axis. + * @static + * @method checkBounds + * @param {Body} bi + * @param {Body} bj + * @param {Number} axisIndex + * @return {Boolean} + */ +SAPBroadphase.checkBounds = function(bi, bj, axisIndex){ + var biPos; + var bjPos; + + if(axisIndex === 0){ + biPos = bi.position.x; + bjPos = bj.position.x; + } else if(axisIndex === 1){ + biPos = bi.position.y; + bjPos = bj.position.y; + } else if(axisIndex === 2){ + biPos = bi.position.z; + bjPos = bj.position.z; + } + + var ri = bi.boundingRadius, + rj = bj.boundingRadius, + boundA1 = biPos - ri, + boundA2 = biPos + ri, + boundB1 = bjPos - rj, + boundB2 = bjPos + rj; + + return boundB1 < boundA2; +}; + +/** + * Computes the variance of the body positions and estimates the best + * axis to use. Will automatically set property .axisIndex. + * @method autoDetectAxis + */ +SAPBroadphase.prototype.autoDetectAxis = function(){ + var sumX=0, + sumX2=0, + sumY=0, + sumY2=0, + sumZ=0, + sumZ2=0, + bodies = this.axisList, + N = bodies.length, + invN=1/N; + + for(var i=0; i!==N; i++){ + var b = bodies[i]; + + var centerX = b.position.x; + sumX += centerX; + sumX2 += centerX*centerX; + + var centerY = b.position.y; + sumY += centerY; + sumY2 += centerY*centerY; + + var centerZ = b.position.z; + sumZ += centerZ; + sumZ2 += centerZ*centerZ; + } + + var varianceX = sumX2 - sumX*sumX*invN, + varianceY = sumY2 - sumY*sumY*invN, + varianceZ = sumZ2 - sumZ*sumZ*invN; + + if(varianceX > varianceY){ + if(varianceX > varianceZ){ + this.axisIndex = 0; + } else{ + this.axisIndex = 2; + } + } else if(varianceY > varianceZ){ + this.axisIndex = 1; + } else{ + this.axisIndex = 2; + } +}; + +/** + * Returns all the bodies within an AABB. + * @method aabbQuery + * @param {World} world + * @param {AABB} aabb + * @param {array} result An array to store resulting bodies in. + * @return {array} + */ +SAPBroadphase.prototype.aabbQuery = function(world, aabb, result){ + result = result || []; + + if(this.dirty){ + this.sortList(); + this.dirty = false; + } + + var axisIndex = this.axisIndex, axis = 'x'; + if(axisIndex === 1){ axis = 'y'; } + if(axisIndex === 2){ axis = 'z'; } + + var axisList = this.axisList; + var lower = aabb.lowerBound[axis]; + var upper = aabb.upperBound[axis]; + for(var i = 0; i < axisList.length; i++){ + var b = axisList[i]; + + if(b.aabbNeedsUpdate){ + b.computeAABB(); + } + + if(b.aabb.overlaps(aabb)){ + result.push(b); + } + } + + return result; +}; +},{"../collision/Broadphase":5,"../shapes/Shape":43}],12:[function(_dereq_,module,exports){ +module.exports = ConeTwistConstraint; + +var Constraint = _dereq_('./Constraint'); +var PointToPointConstraint = _dereq_('./PointToPointConstraint'); +var ConeEquation = _dereq_('../equations/ConeEquation'); +var RotationalEquation = _dereq_('../equations/RotationalEquation'); +var ContactEquation = _dereq_('../equations/ContactEquation'); +var Vec3 = _dereq_('../math/Vec3'); + +/** + * @class ConeTwistConstraint + * @constructor + * @author schteppe + * @param {Body} bodyA + * @param {Body} bodyB + * @param {object} [options] + * @param {Vec3} [options.pivotA] + * @param {Vec3} [options.pivotB] + * @param {Vec3} [options.axisA] + * @param {Vec3} [options.axisB] + * @param {Number} [options.maxForce=1e6] + * @extends PointToPointConstraint + */ +function ConeTwistConstraint(bodyA, bodyB, options){ + options = options || {}; + var maxForce = typeof(options.maxForce) !== 'undefined' ? options.maxForce : 1e6; + + // Set pivot point in between + var pivotA = options.pivotA ? options.pivotA.clone() : new Vec3(); + var pivotB = options.pivotB ? options.pivotB.clone() : new Vec3(); + this.axisA = options.axisA ? options.axisA.clone() : new Vec3(); + this.axisB = options.axisB ? options.axisB.clone() : new Vec3(); + + PointToPointConstraint.call(this, bodyA, pivotA, bodyB, pivotB, maxForce); + + this.collideConnected = !!options.collideConnected; + + this.angle = typeof(options.angle) !== 'undefined' ? options.angle : 0; + + /** + * @property {ConeEquation} coneEquation + */ + var c = this.coneEquation = new ConeEquation(bodyA,bodyB,options); + + /** + * @property {RotationalEquation} twistEquation + */ + var t = this.twistEquation = new RotationalEquation(bodyA,bodyB,options); + this.twistAngle = typeof(options.twistAngle) !== 'undefined' ? options.twistAngle : 0; + + // Make the cone equation push the bodies toward the cone axis, not outward + c.maxForce = 0; + c.minForce = -maxForce; + + // Make the twist equation add torque toward the initial position + t.maxForce = 0; + t.minForce = -maxForce; + + this.equations.push(c, t); +} +ConeTwistConstraint.prototype = new PointToPointConstraint(); +ConeTwistConstraint.constructor = ConeTwistConstraint; + +var ConeTwistConstraint_update_tmpVec1 = new Vec3(); +var ConeTwistConstraint_update_tmpVec2 = new Vec3(); + +ConeTwistConstraint.prototype.update = function(){ + var bodyA = this.bodyA, + bodyB = this.bodyB, + cone = this.coneEquation, + twist = this.twistEquation; + + PointToPointConstraint.prototype.update.call(this); + + // Update the axes to the cone constraint + bodyA.vectorToWorldFrame(this.axisA, cone.axisA); + bodyB.vectorToWorldFrame(this.axisB, cone.axisB); + + // Update the world axes in the twist constraint + this.axisA.tangents(twist.axisA, twist.axisA); + bodyA.vectorToWorldFrame(twist.axisA, twist.axisA); + + this.axisB.tangents(twist.axisB, twist.axisB); + bodyB.vectorToWorldFrame(twist.axisB, twist.axisB); + + cone.angle = this.angle; + twist.maxAngle = this.twistAngle; +}; + + +},{"../equations/ConeEquation":18,"../equations/ContactEquation":19,"../equations/RotationalEquation":22,"../math/Vec3":30,"./Constraint":13,"./PointToPointConstraint":17}],13:[function(_dereq_,module,exports){ +module.exports = Constraint; + +var Utils = _dereq_('../utils/Utils'); + +/** + * Constraint base class + * @class Constraint + * @author schteppe + * @constructor + * @param {Body} bodyA + * @param {Body} bodyB + * @param {object} [options] + * @param {boolean} [options.collideConnected=true] + * @param {boolean} [options.wakeUpBodies=true] + */ +function Constraint(bodyA, bodyB, options){ + options = Utils.defaults(options,{ + collideConnected : true, + wakeUpBodies : true, + }); + + /** + * Equations to be solved in this constraint + * @property equations + * @type {Array} + */ + this.equations = []; + + /** + * @property {Body} bodyA + */ + this.bodyA = bodyA; + + /** + * @property {Body} bodyB + */ + this.bodyB = bodyB; + + /** + * @property {Number} id + */ + this.id = Constraint.idCounter++; + + /** + * Set to true if you want the bodies to collide when they are connected. + * @property collideConnected + * @type {boolean} + */ + this.collideConnected = options.collideConnected; + + if(options.wakeUpBodies){ + if(bodyA){ + bodyA.wakeUp(); + } + if(bodyB){ + bodyB.wakeUp(); + } + } +} + +/** + * Update all the equations with data. + * @method update + */ +Constraint.prototype.update = function(){ + throw new Error("method update() not implmemented in this Constraint subclass!"); +}; + +/** + * Enables all equations in the constraint. + * @method enable + */ +Constraint.prototype.enable = function(){ + var eqs = this.equations; + for(var i=0; i + // G = [0 axisA 0 -axisB] + + GA.rotational.copy(axisA); + axisB.negate(GB.rotational); + + var GW = this.computeGW() - this.targetVelocity, + GiMf = this.computeGiMf(); + + var B = - GW * b - h * GiMf; + + return B; +}; + +},{"../math/Mat3":27,"../math/Vec3":30,"./Equation":20}],24:[function(_dereq_,module,exports){ +var Utils = _dereq_('../utils/Utils'); + +module.exports = ContactMaterial; + +/** + * Defines what happens when two materials meet. + * @class ContactMaterial + * @constructor + * @param {Material} m1 + * @param {Material} m2 + * @param {object} [options] + * @param {Number} [options.friction=0.3] + * @param {Number} [options.restitution=0.3] + * @param {number} [options.contactEquationStiffness=1e7] + * @param {number} [options.contactEquationRelaxation=3] + * @param {number} [options.frictionEquationStiffness=1e7] + * @param {Number} [options.frictionEquationRelaxation=3] + */ +function ContactMaterial(m1, m2, options){ + options = Utils.defaults(options, { + friction: 0.3, + restitution: 0.3, + contactEquationStiffness: 1e7, + contactEquationRelaxation: 3, + frictionEquationStiffness: 1e7, + frictionEquationRelaxation: 3 + }); + + /** + * Identifier of this material + * @property {Number} id + */ + this.id = ContactMaterial.idCounter++; + + /** + * Participating materials + * @property {Array} materials + * @todo Should be .materialA and .materialB instead + */ + this.materials = [m1, m2]; + + /** + * Friction coefficient + * @property {Number} friction + */ + this.friction = options.friction; + + /** + * Restitution coefficient + * @property {Number} restitution + */ + this.restitution = options.restitution; + + /** + * Stiffness of the produced contact equations + * @property {Number} contactEquationStiffness + */ + this.contactEquationStiffness = options.contactEquationStiffness; + + /** + * Relaxation time of the produced contact equations + * @property {Number} contactEquationRelaxation + */ + this.contactEquationRelaxation = options.contactEquationRelaxation; + + /** + * Stiffness of the produced friction equations + * @property {Number} frictionEquationStiffness + */ + this.frictionEquationStiffness = options.frictionEquationStiffness; + + /** + * Relaxation time of the produced friction equations + * @property {Number} frictionEquationRelaxation + */ + this.frictionEquationRelaxation = options.frictionEquationRelaxation; +} + +ContactMaterial.idCounter = 0; + +},{"../utils/Utils":53}],25:[function(_dereq_,module,exports){ +module.exports = Material; + +/** + * Defines a physics material. + * @class Material + * @constructor + * @param {object} [options] + * @author schteppe + */ +function Material(options){ + var name = ''; + options = options || {}; + + // Backwards compatibility fix + if(typeof(options) === 'string'){ + name = options; + options = {}; + } else if(typeof(options) === 'object') { + name = ''; + } + + /** + * @property name + * @type {String} + */ + this.name = name; + + /** + * material id. + * @property id + * @type {number} + */ + this.id = Material.idCounter++; + + /** + * Friction for this material. If non-negative, it will be used instead of the friction given by ContactMaterials. If there's no matching ContactMaterial, the value from .defaultContactMaterial in the World will be used. + * @property {number} friction + * miner 修改默认的摩擦力 + */ + this.friction = typeof(options.friction) !== 'undefined' ? options.friction : -1; + + /** + * Restitution for this material. If non-negative, it will be used instead of the restitution given by ContactMaterials. If there's no matching ContactMaterial, the value from .defaultContactMaterial in the World will be used. + * @property {number} restitution + * miner 修改默认的弹力 + */ + this.restitution = typeof(options.restitution) !== 'undefined' ? options.restitution : -1; +} + +Material.idCounter = 0; + +},{}],26:[function(_dereq_,module,exports){ +module.exports = JacobianElement; + +var Vec3 = _dereq_('./Vec3'); + +/** + * An element containing 6 entries, 3 spatial and 3 rotational degrees of freedom. + * @class JacobianElement + * @constructor + */ +function JacobianElement(){ + + /** + * @property {Vec3} spatial + */ + this.spatial = new Vec3(); + + /** + * @property {Vec3} rotational + */ + this.rotational = new Vec3(); +} + +/** + * Multiply with other JacobianElement + * @method multiplyElement + * @param {JacobianElement} element + * @return {Number} + */ +JacobianElement.prototype.multiplyElement = function(element){ + return element.spatial.dot(this.spatial) + element.rotational.dot(this.rotational); +}; + +/** + * Multiply with two vectors + * @method multiplyVectors + * @param {Vec3} spatial + * @param {Vec3} rotational + * @return {Number} + */ +JacobianElement.prototype.multiplyVectors = function(spatial,rotational){ + return spatial.dot(this.spatial) + rotational.dot(this.rotational); +}; + +},{"./Vec3":30}],27:[function(_dereq_,module,exports){ +module.exports = Mat3; + +var Vec3 = _dereq_('./Vec3'); + +/** + * A 3x3 matrix. + * @class Mat3 + * @constructor + * @param array elements Array of nine elements. Optional. + * @author schteppe / http://github.com/schteppe + */ +function Mat3(elements){ + /** + * A vector of length 9, containing all matrix elements + * @property {Array} elements + */ + if(elements){ + this.elements = elements; + } else { + this.elements = [0,0,0,0,0,0,0,0,0]; + } +} + +/** + * Sets the matrix to identity + * @method identity + * @todo Should perhaps be renamed to setIdentity() to be more clear. + * @todo Create another function that immediately creates an identity matrix eg. eye() + */ +Mat3.prototype.identity = function(){ + var e = this.elements; + e[0] = 1; + e[1] = 0; + e[2] = 0; + + e[3] = 0; + e[4] = 1; + e[5] = 0; + + e[6] = 0; + e[7] = 0; + e[8] = 1; +}; + +/** + * Set all elements to zero + * @method setZero + */ +Mat3.prototype.setZero = function(){ + var e = this.elements; + e[0] = 0; + e[1] = 0; + e[2] = 0; + e[3] = 0; + e[4] = 0; + e[5] = 0; + e[6] = 0; + e[7] = 0; + e[8] = 0; +}; + +/** + * Sets the matrix diagonal elements from a Vec3 + * @method setTrace + * @param {Vec3} vec3 + */ +Mat3.prototype.setTrace = function(vec3){ + var e = this.elements; + e[0] = vec3.x; + e[4] = vec3.y; + e[8] = vec3.z; +}; + +/** + * Gets the matrix diagonal elements + * @method getTrace + * @return {Vec3} + */ +Mat3.prototype.getTrace = function(target){ + var target = target || new Vec3(); + var e = this.elements; + target.x = e[0]; + target.y = e[4]; + target.z = e[8]; +}; + +/** + * Matrix-Vector multiplication + * @method vmult + * @param {Vec3} v The vector to multiply with + * @param {Vec3} target Optional, target to save the result in. + */ +Mat3.prototype.vmult = function(v,target){ + target = target || new Vec3(); + + var e = this.elements, + x = v.x, + y = v.y, + z = v.z; + target.x = e[0]*x + e[1]*y + e[2]*z; + target.y = e[3]*x + e[4]*y + e[5]*z; + target.z = e[6]*x + e[7]*y + e[8]*z; + + return target; +}; + +/** + * Matrix-scalar multiplication + * @method smult + * @param {Number} s + */ +Mat3.prototype.smult = function(s){ + for(var i=0; i1 acos and sqrt will produce errors, this cant happen if quaternion is normalised + var angle = 2 * Math.acos(this.w); + var s = Math.sqrt(1-this.w*this.w); // assuming quaternion normalised then w is less than 1, so term always positive. + if (s < 0.001) { // test to avoid divide by zero, s is always positive due to sqrt + // if s close to zero then direction of axis not important + targetAxis.x = this.x; // if it is important that axis is normalised then replace with x=1; y=z=0; + targetAxis.y = this.y; + targetAxis.z = this.z; + } else { + targetAxis.x = this.x / s; // normalise axis + targetAxis.y = this.y / s; + targetAxis.z = this.z / s; + } + return [targetAxis,angle]; +}; + +var sfv_t1 = new Vec3(), + sfv_t2 = new Vec3(); + +/** + * Set the quaternion value given two vectors. The resulting rotation will be the needed rotation to rotate u to v. + * @method setFromVectors + * @param {Vec3} u + * @param {Vec3} v + */ +Quaternion.prototype.setFromVectors = function(u,v){ + if(u.isAntiparallelTo(v)){ + var t1 = sfv_t1; + var t2 = sfv_t2; + + u.tangents(t1,t2); + this.setFromAxisAngle(t1,Math.PI); + } else { + var a = u.cross(v); + this.x = a.x; + this.y = a.y; + this.z = a.z; + this.w = Math.sqrt(Math.pow(u.norm(),2) * Math.pow(v.norm(),2)) + u.dot(v); + this.normalize(); + } +}; + +/** + * Quaternion multiplication + * @method mult + * @param {Quaternion} q + * @param {Quaternion} target Optional. + * @return {Quaternion} + */ +var Quaternion_mult_va = new Vec3(); +var Quaternion_mult_vb = new Vec3(); +var Quaternion_mult_vaxvb = new Vec3(); +Quaternion.prototype.mult = function(q,target){ + target = target || new Quaternion(); + var w = this.w, + va = Quaternion_mult_va, + vb = Quaternion_mult_vb, + vaxvb = Quaternion_mult_vaxvb; + + va.set(this.x,this.y,this.z); + vb.set(q.x,q.y,q.z); + target.w = w*q.w - va.dot(vb); + va.cross(vb,vaxvb); + + target.x = w * vb.x + q.w*va.x + vaxvb.x; + target.y = w * vb.y + q.w*va.y + vaxvb.y; + target.z = w * vb.z + q.w*va.z + vaxvb.z; + + return target; +}; + +/** + * Get the inverse quaternion rotation. + * @method inverse + * @param {Quaternion} target + * @return {Quaternion} + */ +Quaternion.prototype.inverse = function(target){ + var x = this.x, y = this.y, z = this.z, w = this.w; + target = target || new Quaternion(); + + this.conjugate(target); + var inorm2 = 1/(x*x + y*y + z*z + w*w); + target.x *= inorm2; + target.y *= inorm2; + target.z *= inorm2; + target.w *= inorm2; + + return target; +}; + +/** + * Get the quaternion conjugate + * @method conjugate + * @param {Quaternion} target + * @return {Quaternion} + */ +Quaternion.prototype.conjugate = function(target){ + target = target || new Quaternion(); + + target.x = -this.x; + target.y = -this.y; + target.z = -this.z; + target.w = this.w; + + return target; +}; + +/** + * Normalize the quaternion. Note that this changes the values of the quaternion. + * @method normalize + */ +Quaternion.prototype.normalize = function(){ + var l = Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w); + if ( l === 0 ) { + this.x = 0; + this.y = 0; + this.z = 0; + this.w = 0; + } else { + l = 1 / l; + this.x *= l; + this.y *= l; + this.z *= l; + this.w *= l; + } +}; + +/** + * Approximation of quaternion normalization. Works best when quat is already almost-normalized. + * @method normalizeFast + * @see http://jsperf.com/fast-quaternion-normalization + * @author unphased, https://github.com/unphased + */ +Quaternion.prototype.normalizeFast = function () { + var f = (3.0-(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w))/2.0; + if ( f === 0 ) { + this.x = 0; + this.y = 0; + this.z = 0; + this.w = 0; + } else { + this.x *= f; + this.y *= f; + this.z *= f; + this.w *= f; + } +}; + +/** + * Multiply the quaternion by a vector + * @method vmult + * @param {Vec3} v + * @param {Vec3} target Optional + * @return {Vec3} + */ +Quaternion.prototype.vmult = function(v,target){ + target = target || new Vec3(); + + var x = v.x, + y = v.y, + z = v.z; + + var qx = this.x, + qy = this.y, + qz = this.z, + qw = this.w; + + // q*v + var ix = qw * x + qy * z - qz * y, + iy = qw * y + qz * x - qx * z, + iz = qw * z + qx * y - qy * x, + iw = -qx * x - qy * y - qz * z; + + target.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; + target.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; + target.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + + return target; +}; + +/** + * Copies value of source to this quaternion. + * @method copy + * @param {Quaternion} source + * @return {Quaternion} this + */ +Quaternion.prototype.copy = function(source){ + this.x = source.x; + this.y = source.y; + this.z = source.z; + this.w = source.w; + return this; +}; + +/** + * Convert the quaternion to euler angle representation. Order: YZX, as this page describes: http://www.euclideanspace.com/maths/standards/index.htm + * @method toEuler + * @param {Vec3} target + * @param string order Three-character string e.g. "YZX", which also is default. + */ +Quaternion.prototype.toEuler = function(target,order){ + order = order || "YZX"; + + var heading, attitude, bank; + var x = this.x, y = this.y, z = this.z, w = this.w; + + switch(order){ + case "YZX": + var test = x*y + z*w; + if (test > 0.499) { // singularity at north pole + heading = 2 * Math.atan2(x,w); + attitude = Math.PI/2; + bank = 0; + } + if (test < -0.499) { // singularity at south pole + heading = -2 * Math.atan2(x,w); + attitude = - Math.PI/2; + bank = 0; + } + if(isNaN(heading)){ + var sqx = x*x; + var sqy = y*y; + var sqz = z*z; + heading = Math.atan2(2*y*w - 2*x*z , 1 - 2*sqy - 2*sqz); // Heading + attitude = Math.asin(2*test); // attitude + bank = Math.atan2(2*x*w - 2*y*z , 1 - 2*sqx - 2*sqz); // bank + } + break; + default: + throw new Error("Euler order "+order+" not supported yet."); + } + + target.y = heading; + target.z = attitude; + target.x = bank; +}; + +/** + * See http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/content/SpinCalc.m + * @method setFromEuler + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @param {String} order The order to apply angles: 'XYZ' or 'YXZ' or any other combination + */ +Quaternion.prototype.setFromEuler = function ( x, y, z, order ) { + order = order || "XYZ"; + + var c1 = Math.cos( x / 2 ); + var c2 = Math.cos( y / 2 ); + var c3 = Math.cos( z / 2 ); + var s1 = Math.sin( x / 2 ); + var s2 = Math.sin( y / 2 ); + var s3 = Math.sin( z / 2 ); + + if ( order === 'XYZ' ) { + + this.x = s1 * c2 * c3 + c1 * s2 * s3; + this.y = c1 * s2 * c3 - s1 * c2 * s3; + this.z = c1 * c2 * s3 + s1 * s2 * c3; + this.w = c1 * c2 * c3 - s1 * s2 * s3; + + } else if ( order === 'YXZ' ) { + + this.x = s1 * c2 * c3 + c1 * s2 * s3; + this.y = c1 * s2 * c3 - s1 * c2 * s3; + this.z = c1 * c2 * s3 - s1 * s2 * c3; + this.w = c1 * c2 * c3 + s1 * s2 * s3; + + } else if ( order === 'ZXY' ) { + + this.x = s1 * c2 * c3 - c1 * s2 * s3; + this.y = c1 * s2 * c3 + s1 * c2 * s3; + this.z = c1 * c2 * s3 + s1 * s2 * c3; + this.w = c1 * c2 * c3 - s1 * s2 * s3; + + } else if ( order === 'ZYX' ) { + + this.x = s1 * c2 * c3 - c1 * s2 * s3; + this.y = c1 * s2 * c3 + s1 * c2 * s3; + this.z = c1 * c2 * s3 - s1 * s2 * c3; + this.w = c1 * c2 * c3 + s1 * s2 * s3; + + } else if ( order === 'YZX' ) { + + this.x = s1 * c2 * c3 + c1 * s2 * s3; + this.y = c1 * s2 * c3 + s1 * c2 * s3; + this.z = c1 * c2 * s3 - s1 * s2 * c3; + this.w = c1 * c2 * c3 - s1 * s2 * s3; + + } else if ( order === 'XZY' ) { + + this.x = s1 * c2 * c3 - c1 * s2 * s3; + this.y = c1 * s2 * c3 - s1 * c2 * s3; + this.z = c1 * c2 * s3 + s1 * s2 * c3; + this.w = c1 * c2 * c3 + s1 * s2 * s3; + + } + + return this; + +}; + +Quaternion.prototype.clone = function(){ + return new Quaternion(this.x, this.y, this.z, this.w); +}; +},{"./Vec3":30}],29:[function(_dereq_,module,exports){ +var Vec3 = _dereq_('./Vec3'); +var Quaternion = _dereq_('./Quaternion'); + +module.exports = Transform; + +/** + * @class Transform + * @constructor + */ +function Transform(options) { + options = options || {}; + + /** + * @property {Vec3} position + */ + this.position = new Vec3(); + if(options.position){ + this.position.copy(options.position); + } + + /** + * @property {Quaternion} quaternion + */ + this.quaternion = new Quaternion(); + if(options.quaternion){ + this.quaternion.copy(options.quaternion); + } +} + +var tmpQuat = new Quaternion(); + +/** + * @static + * @method pointToLocaFrame + * @param {Vec3} position + * @param {Quaternion} quaternion + * @param {Vec3} worldPoint + * @param {Vec3} result + */ +Transform.pointToLocalFrame = function(position, quaternion, worldPoint, result){ + var result = result || new Vec3(); + worldPoint.vsub(position, result); + quaternion.conjugate(tmpQuat); + tmpQuat.vmult(result, result); + return result; +}; + +/** + * Get a global point in local transform coordinates. + * @method pointToLocal + * @param {Vec3} point + * @param {Vec3} result + * @return {Vec3} The "result" vector object + */ +Transform.prototype.pointToLocal = function(worldPoint, result){ + return Transform.pointToLocalFrame(this.position, this.quaternion, worldPoint, result); +}; + +/** + * @static + * @method pointToWorldFrame + * @param {Vec3} position + * @param {Vec3} quaternion + * @param {Vec3} localPoint + * @param {Vec3} result + */ +Transform.pointToWorldFrame = function(position, quaternion, localPoint, result){ + var result = result || new Vec3(); + quaternion.vmult(localPoint, result); + result.vadd(position, result); + return result; +}; + +/** + * Get a local point in global transform coordinates. + * @method pointToWorld + * @param {Vec3} point + * @param {Vec3} result + * @return {Vec3} The "result" vector object + */ +Transform.prototype.pointToWorld = function(localPoint, result){ + return Transform.pointToWorldFrame(this.position, this.quaternion, localPoint, result); +}; + + +Transform.prototype.vectorToWorldFrame = function(localVector, result){ + var result = result || new Vec3(); + this.quaternion.vmult(localVector, result); + return result; +}; + +Transform.vectorToWorldFrame = function(quaternion, localVector, result){ + quaternion.vmult(localVector, result); + return result; +}; + +Transform.vectorToLocalFrame = function(position, quaternion, worldVector, result){ + var result = result || new Vec3(); + quaternion.w *= -1; + quaternion.vmult(worldVector, result); + quaternion.w *= -1; + return result; +}; + +},{"./Quaternion":28,"./Vec3":30}],30:[function(_dereq_,module,exports){ +module.exports = Vec3; + +var Mat3 = _dereq_('./Mat3'); + +/** + * 3-dimensional vector + * @class Vec3 + * @constructor + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @author schteppe + * @example + * var v = new Vec3(1, 2, 3); + * console.log('x=' + v.x); // x=1 + */ +function Vec3(x,y,z){ + /** + * @property x + * @type {Number} + */ + this.x = x||0.0; + + /** + * @property y + * @type {Number} + */ + this.y = y||0.0; + + /** + * @property z + * @type {Number} + */ + this.z = z||0.0; +} + +/** + * @static + * @property {Vec3} ZERO + */ +Vec3.ZERO = new Vec3(0, 0, 0); + +/** + * @static + * @property {Vec3} UNIT_X + */ +Vec3.UNIT_X = new Vec3(1, 0, 0); + +/** + * @static + * @property {Vec3} UNIT_Y + */ +Vec3.UNIT_Y = new Vec3(0, 1, 0); + +/** + * @static + * @property {Vec3} UNIT_Z + */ +Vec3.UNIT_Z = new Vec3(0, 0, 1); + +/** + * Vector cross product + * @method cross + * @param {Vec3} v + * @param {Vec3} target Optional. Target to save in. + * @return {Vec3} + */ +Vec3.prototype.cross = function(v,target){ + var vx=v.x, vy=v.y, vz=v.z, x=this.x, y=this.y, z=this.z; + target = target || new Vec3(); + + target.x = (y * vz) - (z * vy); + target.y = (z * vx) - (x * vz); + target.z = (x * vy) - (y * vx); + + return target; +}; + +/** + * Set the vectors' 3 elements + * @method set + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @return Vec3 + */ +Vec3.prototype.set = function(x,y,z){ + this.x = x; + this.y = y; + this.z = z; + return this; +}; + +/** + * Set all components of the vector to zero. + * @method setZero + */ +Vec3.prototype.setZero = function(){ + this.x = this.y = this.z = 0; +}; + +/** + * Vector addition + * @method vadd + * @param {Vec3} v + * @param {Vec3} target Optional. + * @return {Vec3} + */ +Vec3.prototype.vadd = function(v,target){ + if(target){ + target.x = v.x + this.x; + target.y = v.y + this.y; + target.z = v.z + this.z; + } else { + return new Vec3(this.x + v.x, + this.y + v.y, + this.z + v.z); + } +}; + +/** + * Vector subtraction + * @method vsub + * @param {Vec3} v + * @param {Vec3} target Optional. Target to save in. + * @return {Vec3} + */ +Vec3.prototype.vsub = function(v,target){ + if(target){ + target.x = this.x - v.x; + target.y = this.y - v.y; + target.z = this.z - v.z; + } else { + return new Vec3(this.x-v.x, + this.y-v.y, + this.z-v.z); + } +}; + +/** + * Get the cross product matrix a_cross from a vector, such that a x b = a_cross * b = c + * @method crossmat + * @see http://www8.cs.umu.se/kurser/TDBD24/VT06/lectures/Lecture6.pdf + * @return {Mat3} + */ +Vec3.prototype.crossmat = function(){ + return new Mat3([ 0, -this.z, this.y, + this.z, 0, -this.x, + -this.y, this.x, 0]); +}; + +/** + * Normalize the vector. Note that this changes the values in the vector. + * @method normalize + * @return {Number} Returns the norm of the vector + */ +Vec3.prototype.normalize = function(){ + var x=this.x, y=this.y, z=this.z; + var n = Math.sqrt(x*x + y*y + z*z); + if(n>0.0){ + var invN = 1/n; + this.x *= invN; + this.y *= invN; + this.z *= invN; + } else { + // Make something up + this.x = 0; + this.y = 0; + this.z = 0; + } + return n; +}; + +/** + * Get the version of this vector that is of length 1. + * @method unit + * @param {Vec3} target Optional target to save in + * @return {Vec3} Returns the unit vector + */ +Vec3.prototype.unit = function(target){ + target = target || new Vec3(); + var x=this.x, y=this.y, z=this.z; + var ninv = Math.sqrt(x*x + y*y + z*z); + if(ninv>0.0){ + ninv = 1.0/ninv; + target.x = x * ninv; + target.y = y * ninv; + target.z = z * ninv; + } else { + target.x = 1; + target.y = 0; + target.z = 0; + } + return target; +}; + +/** + * Get the length of the vector + * @method norm + * @return {Number} + * @deprecated Use .length() instead + */ +Vec3.prototype.norm = function(){ + var x=this.x, y=this.y, z=this.z; + return Math.sqrt(x*x + y*y + z*z); +}; + +/** + * Get the length of the vector + * @method length + * @return {Number} + */ +Vec3.prototype.length = Vec3.prototype.norm; + +/** + * Get the squared length of the vector + * @method norm2 + * @return {Number} + * @deprecated Use .lengthSquared() instead. + */ +Vec3.prototype.norm2 = function(){ + return this.dot(this); +}; + +/** + * Get the squared length of the vector. + * @method lengthSquared + * @return {Number} + */ +Vec3.prototype.lengthSquared = Vec3.prototype.norm2; + +/** + * Get distance from this point to another point + * @method distanceTo + * @param {Vec3} p + * @return {Number} + */ +Vec3.prototype.distanceTo = function(p){ + var x=this.x, y=this.y, z=this.z; + var px=p.x, py=p.y, pz=p.z; + return Math.sqrt((px-x)*(px-x)+ + (py-y)*(py-y)+ + (pz-z)*(pz-z)); +}; + +/** + * Get squared distance from this point to another point + * @method distanceSquared + * @param {Vec3} p + * @return {Number} + */ +Vec3.prototype.distanceSquared = function(p){ + var x=this.x, y=this.y, z=this.z; + var px=p.x, py=p.y, pz=p.z; + return (px-x)*(px-x) + (py-y)*(py-y) + (pz-z)*(pz-z); +}; + +/** + * Multiply all the components of the vector with a scalar. + * @deprecated Use .scale instead + * @method mult + * @param {Number} scalar + * @param {Vec3} target The vector to save the result in. + * @return {Vec3} + * @deprecated Use .scale() instead + */ +Vec3.prototype.mult = function(scalar,target){ + target = target || new Vec3(); + var x = this.x, + y = this.y, + z = this.z; + target.x = scalar * x; + target.y = scalar * y; + target.z = scalar * z; + return target; +}; + +/** + * Multiply the vector with a scalar. + * @method scale + * @param {Number} scalar + * @param {Vec3} target + * @return {Vec3} + */ +Vec3.prototype.scale = Vec3.prototype.mult; + +/** + * Calculate dot product + * @method dot + * @param {Vec3} v + * @return {Number} + */ +Vec3.prototype.dot = function(v){ + return this.x * v.x + this.y * v.y + this.z * v.z; +}; + +/** + * @method isZero + * @return bool + */ +Vec3.prototype.isZero = function(){ + return this.x===0 && this.y===0 && this.z===0; +}; + +/** + * Make the vector point in the opposite direction. + * @method negate + * @param {Vec3} target Optional target to save in + * @return {Vec3} + */ +Vec3.prototype.negate = function(target){ + target = target || new Vec3(); + target.x = -this.x; + target.y = -this.y; + target.z = -this.z; + return target; +}; + +/** + * Compute two artificial tangents to the vector + * @method tangents + * @param {Vec3} t1 Vector object to save the first tangent in + * @param {Vec3} t2 Vector object to save the second tangent in + */ +var Vec3_tangents_n = new Vec3(); +var Vec3_tangents_randVec = new Vec3(); +Vec3.prototype.tangents = function(t1,t2){ + var norm = this.norm(); + if(norm>0.0){ + var n = Vec3_tangents_n; + var inorm = 1/norm; + n.set(this.x*inorm,this.y*inorm,this.z*inorm); + var randVec = Vec3_tangents_randVec; + if(Math.abs(n.x) < 0.9){ + randVec.set(1,0,0); + n.cross(randVec,t1); + } else { + randVec.set(0,1,0); + n.cross(randVec,t1); + } + n.cross(t1,t2); + } else { + // The normal length is zero, make something up + t1.set(1, 0, 0); + t2.set(0, 1, 0); + } +}; + +/** + * Converts to a more readable format + * @method toString + * @return string + */ +Vec3.prototype.toString = function(){ + return this.x+","+this.y+","+this.z; +}; + +/** + * Converts to an array + * @method toArray + * @return Array + */ +Vec3.prototype.toArray = function(){ + return [this.x, this.y, this.z]; +}; + +/** + * Copies value of source to this vector. + * @method copy + * @param {Vec3} source + * @return {Vec3} this + */ +Vec3.prototype.copy = function(source){ + this.x = source.x; + this.y = source.y; + this.z = source.z; + return this; +}; + + +/** + * Do a linear interpolation between two vectors + * @method lerp + * @param {Vec3} v + * @param {Number} t A number between 0 and 1. 0 will make this function return u, and 1 will make it return v. Numbers in between will generate a vector in between them. + * @param {Vec3} target + */ +Vec3.prototype.lerp = function(v,t,target){ + var x=this.x, y=this.y, z=this.z; + target.x = x + (v.x-x)*t; + target.y = y + (v.y-y)*t; + target.z = z + (v.z-z)*t; +}; + +/** + * Check if a vector equals is almost equal to another one. + * @method almostEquals + * @param {Vec3} v + * @param {Number} precision + * @return bool + */ +Vec3.prototype.almostEquals = function(v,precision){ + if(precision===undefined){ + precision = 1e-6; + } + if( Math.abs(this.x-v.x)>precision || + Math.abs(this.y-v.y)>precision || + Math.abs(this.z-v.z)>precision){ + return false; + } + return true; +}; + +/** + * Check if a vector is almost zero + * @method almostZero + * @param {Number} precision + */ +Vec3.prototype.almostZero = function(precision){ + if(precision===undefined){ + precision = 1e-6; + } + if( Math.abs(this.x)>precision || + Math.abs(this.y)>precision || + Math.abs(this.z)>precision){ + return false; + } + return true; +}; + +var antip_neg = new Vec3(); + +/** + * Check if the vector is anti-parallel to another vector. + * @method isAntiparallelTo + * @param {Vec3} v + * @param {Number} precision Set to zero for exact comparisons + * @return {Boolean} + */ +Vec3.prototype.isAntiparallelTo = function(v,precision){ + this.negate(antip_neg); + return antip_neg.almostEquals(v,precision); +}; + +/** + * Clone the vector + * @method clone + * @return {Vec3} + */ +Vec3.prototype.clone = function(){ + return new Vec3(this.x, this.y, this.z); +}; +},{"./Mat3":27}],31:[function(_dereq_,module,exports){ +module.exports = Body; + +var EventTarget = _dereq_('../utils/EventTarget'); +var Shape = _dereq_('../shapes/Shape'); +var Vec3 = _dereq_('../math/Vec3'); +var Mat3 = _dereq_('../math/Mat3'); +var Quaternion = _dereq_('../math/Quaternion'); +var Material = _dereq_('../material/Material'); +var AABB = _dereq_('../collision/AABB'); +var Box = _dereq_('../shapes/Box'); + +/** + * Base class for all body types. + * @class Body + * @constructor + * @extends EventTarget + * @param {object} [options] + * @param {Vec3} [options.position] + * @param {Vec3} [options.velocity] + * @param {Vec3} [options.angularVelocity] + * @param {Quaternion} [options.quaternion] + * @param {number} [options.mass] + * @param {Material} [options.material] + * @param {number} [options.type] + * @param {number} [options.linearDamping=0.01] + * @param {number} [options.angularDamping=0.01] + * @param {boolean} [options.allowSleep=true] + * @param {number} [options.sleepSpeedLimit=0.1] + * @param {number} [options.sleepTimeLimit=1] + * @param {number} [options.collisionFilterGroup=1] + * @param {number} [options.collisionFilterMask=1] + * @param {boolean} [options.fixedRotation=false] + * @param {Body} [options.shape] + * @example + * var body = new Body({ + * mass: 1 + * }); + * var shape = new Sphere(1); + * body.addShape(shape); + * world.add(body); + */ +function Body(options){ + options = options || {}; + + EventTarget.apply(this); + + this.id = Body.idCounter++; + //miner laya对应ID + this.layaID; + //istriger的功能添加 + this.isTrigger = false; + /** + * Reference to the world the body is living in + * @property world + * @type {World} + */ + this.world = null; + + /** + * Callback function that is used BEFORE stepping the system. Use it to apply forces, for example. Inside the function, "this" will refer to this Body object. + * @property preStep + * @type {Function} + * @deprecated Use World events instead + */ + this.preStep = null; + + /** + * Callback function that is used AFTER stepping the system. Inside the function, "this" will refer to this Body object. + * @property postStep + * @type {Function} + * @deprecated Use World events instead + */ + this.postStep = null; + + this.vlambda = new Vec3(); + + /** + * @property {Number} collisionFilterGroup + */ + this.collisionFilterGroup = typeof(options.collisionFilterGroup) === 'number' ? options.collisionFilterGroup : 1; + + /** + * @property {Number} collisionFilterMask + */ + this.collisionFilterMask = typeof(options.collisionFilterMask) === 'number' ? options.collisionFilterMask : 1; + + /** + * Whether to produce contact forces when in contact with other bodies. Note that contacts will be generated, but they will be disabled. + * @property {Number} collisionResponse + */ + this.collisionResponse = true; + + /** + * @property position + * @type {Vec3} + */ + this.position = new Vec3(); + + if(options.position){ + this.position.copy(options.position); + } + + /** + * @property {Vec3} previousPosition + */ + this.previousPosition = new Vec3(); + + /** + * Initial position of the body + * @property initPosition + * @type {Vec3} + */ + this.initPosition = new Vec3(); + + /** + * @property velocity + * @type {Vec3} + */ + this.velocity = new Vec3(); + + if(options.velocity){ + this.velocity.copy(options.velocity); + } + + /** + * @property initVelocity + * @type {Vec3} + */ + this.initVelocity = new Vec3(); + + /** + * Linear force on the body + * @property force + * @type {Vec3} + */ + this.force = new Vec3(); + + var mass = typeof(options.mass) === 'number' ? options.mass : 0; + + /** + * @property mass + * @type {Number} + * @default 0 + */ + this.mass = mass; + + /** + * @property invMass + * @type {Number} + */ + this.invMass = mass > 0 ? 1.0 / mass : 0; + + /** + * @property material + * @type {Material} + */ + this.material = options.material || null; + + /** + * @property linearDamping + * @type {Number} + */ + this.linearDamping = typeof(options.linearDamping) === 'number' ? options.linearDamping : 0.01; + + /** + * One of: Body.DYNAMIC, Body.STATIC and Body.KINEMATIC. + * @property type + * @type {Number} + */ + this.type = (mass <= 0.0 ? Body.STATIC : Body.DYNAMIC); + if(typeof(options.type) === typeof(Body.STATIC)){ + this.type = options.type; + } + + /** + * If true, the body will automatically fall to sleep. + * @property allowSleep + * @type {Boolean} + * @default true + */ + this.allowSleep = typeof(options.allowSleep) !== 'undefined' ? options.allowSleep : true; + + /** + * Current sleep state. + * @property sleepState + * @type {Number} + */ + this.sleepState = 0; + + /** + * If the speed (the norm of the velocity) is smaller than this value, the body is considered sleepy. + * @property sleepSpeedLimit + * @type {Number} + * @default 0.1 + */ + this.sleepSpeedLimit = typeof(options.sleepSpeedLimit) !== 'undefined' ? options.sleepSpeedLimit : 0.1; + + /** + * If the body has been sleepy for this sleepTimeLimit seconds, it is considered sleeping. + * @property sleepTimeLimit + * @type {Number} + * @default 1 + */ + this.sleepTimeLimit = typeof(options.sleepTimeLimit) !== 'undefined' ? options.sleepTimeLimit : 1; + + this.timeLastSleepy = 0; + + this._wakeUpAfterNarrowphase = false; + + + /** + * Rotational force on the body, around center of mass + * @property {Vec3} torque + */ + this.torque = new Vec3(); + + /** + * Orientation of the body + * @property quaternion + * @type {Quaternion} + */ + this.quaternion = new Quaternion(); + + if(options.quaternion){ + this.quaternion.copy(options.quaternion); + } + + /** + * @property initQuaternion + * @type {Quaternion} + */ + this.initQuaternion = new Quaternion(); + + /** + * @property angularVelocity + * @type {Vec3} + */ + this.angularVelocity = new Vec3(); + + if(options.angularVelocity){ + this.angularVelocity.copy(options.angularVelocity); + } + + /** + * @property initAngularVelocity + * @type {Vec3} + */ + this.initAngularVelocity = new Vec3(); + + this.interpolatedPosition = new Vec3(); + this.interpolatedQuaternion = new Quaternion(); + + /** + * @property shapes + * @type {array} + */ + this.shapes = []; + + /** + * @property shapeOffsets + * @type {array} + */ + this.shapeOffsets = []; + + /** + * @property shapeOrientations + * @type {array} + */ + this.shapeOrientations = []; + + /** + * @property inertia + * @type {Vec3} + */ + this.inertia = new Vec3(); + + /** + * @property {Vec3} invInertia + */ + this.invInertia = new Vec3(); + + /** + * @property {Mat3} invInertiaWorld + */ + this.invInertiaWorld = new Mat3(); + + this.invMassSolve = 0; + + /** + * @property {Vec3} invInertiaSolve + */ + this.invInertiaSolve = new Vec3(); + + /** + * @property {Mat3} invInertiaWorldSolve + */ + this.invInertiaWorldSolve = new Mat3(); + + /** + * Set to true if you don't want the body to rotate. Make sure to run .updateMassProperties() after changing this. + * @property {Boolean} fixedRotation + * @default false + */ + this.fixedRotation = typeof(options.fixedRotation) !== "undefined" ? options.fixedRotation : false; + + /** + * @property {Number} angularDamping + */ + this.angularDamping = typeof(options.angularDamping) !== 'undefined' ? options.angularDamping : 0.01; + + /** + * @property aabb + * @type {AABB} + */ + this.aabb = new AABB(); + + /** + * Indicates if the AABB needs to be updated before use. + * @property aabbNeedsUpdate + * @type {Boolean} + */ + this.aabbNeedsUpdate = true; + + this.wlambda = new Vec3(); + + if(options.shape){ + this.addShape(options.shape); + } + + this.updateMassProperties(); +} +Body.prototype = new EventTarget(); +Body.prototype.constructor = Body; + +/** + * A dynamic body is fully simulated. Can be moved manually by the user, but normally they move according to forces. A dynamic body can collide with all body types. A dynamic body always has finite, non-zero mass. + * @static + * @property DYNAMIC + * @type {Number} + */ +Body.DYNAMIC = 1; + +/** + * A static body does not move during simulation and behaves as if it has infinite mass. Static bodies can be moved manually by setting the position of the body. The velocity of a static body is always zero. Static bodies do not collide with other static or kinematic bodies. + * @static + * @property STATIC + * @type {Number} + */ +Body.STATIC = 2; + +/** + * A kinematic body moves under simulation according to its velocity. They do not respond to forces. They can be moved manually, but normally a kinematic body is moved by setting its velocity. A kinematic body behaves as if it has infinite mass. Kinematic bodies do not collide with other static or kinematic bodies. + * @static + * @property KINEMATIC + * @type {Number} + */ +Body.KINEMATIC = 4; + + + +/** + * @static + * @property AWAKE + * @type {number} + */ +Body.AWAKE = 0; + +/** + * @static + * @property SLEEPY + * @type {number} + */ +Body.SLEEPY = 1; + +/** + * @static + * @property SLEEPING + * @type {number} + */ +Body.SLEEPING = 2; + +Body.idCounter = 0; + +/** + * Wake the body up. + * @method wakeUp + */ +Body.prototype.wakeUp = function(){ + var s = this.sleepState; + this.sleepState = 0; + if(s === Body.SLEEPING){ + this.dispatchEvent({type:"wakeup"}); + } +}; + +/** + * Force body sleep + * @method sleep + */ +Body.prototype.sleep = function(){ + this.sleepState = Body.SLEEPING; + this.velocity.set(0,0,0); + this.angularVelocity.set(0,0,0); +}; + +Body.sleepyEvent = { + type: "sleepy" +}; + +Body.sleepEvent = { + type: "sleep" +}; + +/** + * Called every timestep to update internal sleep timer and change sleep state if needed. + * @method sleepTick + * @param {Number} time The world time in seconds + */ +Body.prototype.sleepTick = function(time){ + if(this.allowSleep){ + var sleepState = this.sleepState; + var speedSquared = this.velocity.norm2() + this.angularVelocity.norm2(); + var speedLimitSquared = Math.pow(this.sleepSpeedLimit,2); + if(sleepState===Body.AWAKE && speedSquared < speedLimitSquared){ + this.sleepState = Body.SLEEPY; // Sleepy + this.timeLastSleepy = time; + this.dispatchEvent(Body.sleepyEvent); + } else if(sleepState===Body.SLEEPY && speedSquared > speedLimitSquared){ + this.wakeUp(); // Wake up + } else if(sleepState===Body.SLEEPY && (time - this.timeLastSleepy ) > this.sleepTimeLimit){ + this.sleep(); // Sleeping + this.dispatchEvent(Body.sleepEvent); + } + } +}; + +/** + * If the body is sleeping, it should be immovable / have infinite mass during solve. We solve it by having a separate "solve mass". + * @method updateSolveMassProperties + */ +Body.prototype.updateSolveMassProperties = function(){ + if(this.sleepState === Body.SLEEPING || this.type === Body.KINEMATIC){ + this.invMassSolve = 0; + this.invInertiaSolve.setZero(); + this.invInertiaWorldSolve.setZero(); + } else { + this.invMassSolve = this.invMass; + this.invInertiaSolve.copy(this.invInertia); + this.invInertiaWorldSolve.copy(this.invInertiaWorld); + } +}; + +/** + * Convert a world point to local body frame. + * @method pointToLocalFrame + * @param {Vec3} worldPoint + * @param {Vec3} result + * @return {Vec3} + */ +Body.prototype.pointToLocalFrame = function(worldPoint,result){ + var result = result || new Vec3(); + worldPoint.vsub(this.position,result); + this.quaternion.conjugate().vmult(result,result); + return result; +}; + +/** + * Convert a world vector to local body frame. + * @method vectorToLocalFrame + * @param {Vec3} worldPoint + * @param {Vec3} result + * @return {Vec3} + */ +Body.prototype.vectorToLocalFrame = function(worldVector, result){ + var result = result || new Vec3(); + this.quaternion.conjugate().vmult(worldVector,result); + return result; +}; + +/** + * Convert a local body point to world frame. + * @method pointToWorldFrame + * @param {Vec3} localPoint + * @param {Vec3} result + * @return {Vec3} + */ +Body.prototype.pointToWorldFrame = function(localPoint,result){ + var result = result || new Vec3(); + this.quaternion.vmult(localPoint,result); + result.vadd(this.position,result); + return result; +}; + +/** + * Convert a local body point to world frame. + * @method vectorToWorldFrame + * @param {Vec3} localVector + * @param {Vec3} result + * @return {Vec3} + */ +Body.prototype.vectorToWorldFrame = function(localVector, result){ + var result = result || new Vec3(); + this.quaternion.vmult(localVector, result); + return result; +}; + +var tmpVec = new Vec3(); +var tmpQuat = new Quaternion(); + +/** + * Add a shape to the body with a local offset and orientation. + * @method addShape + * @param {Shape} shape + * @param {Vec3} offset + * @param {Quaternion} quaternion + * @return {Body} The body object, for chainability. + */ +Body.prototype.addShape = function(shape, _offset, _orientation){ + var offset = new Vec3(); + var orientation = new Quaternion(); + + if(_offset){ + offset.copy(_offset); + } + if(_orientation){ + orientation.copy(_orientation); + } + + this.shapes.push(shape); + this.shapeOffsets.push(offset); + this.shapeOrientations.push(orientation); + this.updateMassProperties(); + this.updateBoundingRadius(); + + this.aabbNeedsUpdate = true; + + return this; +}; + +/** + * Update the bounding radius of the body. Should be done if any of the shapes are changed. + * @method updateBoundingRadius + */ +Body.prototype.updateBoundingRadius = function(){ + var shapes = this.shapes, + shapeOffsets = this.shapeOffsets, + N = shapes.length, + radius = 0; + + for(var i=0; i!==N; i++){ + var shape = shapes[i]; + shape.updateBoundingSphereRadius(); + var offset = shapeOffsets[i].norm(), + r = shape.boundingSphereRadius; + if(offset + r > radius){ + radius = offset + r; + } + } + + this.boundingRadius = radius; +}; + +var computeAABB_shapeAABB = new AABB(); + +/** + * Updates the .aabb + * @method computeAABB + * @todo rename to updateAABB() + */ +Body.prototype.computeAABB = function(){ + var shapes = this.shapes, + shapeOffsets = this.shapeOffsets, + shapeOrientations = this.shapeOrientations, + N = shapes.length, + offset = tmpVec, + orientation = tmpQuat, + bodyQuat = this.quaternion, + aabb = this.aabb, + shapeAABB = computeAABB_shapeAABB; + + for(var i=0; i!==N; i++){ + var shape = shapes[i]; + + // Get shape world quaternion + shapeOrientations[i].mult(bodyQuat, orientation); + + // Get shape world position + orientation.vmult(shapeOffsets[i], offset); + offset.vadd(this.position, offset); + + // vec2.rotate(offset, shapeOffsets[i], bodyAngle); + // vec2.add(offset, offset, this.position); + + // Get shape AABB + shape.calculateWorldAABB(offset, orientation, shapeAABB.lowerBound, shapeAABB.upperBound); + + if(i === 0){ + aabb.copy(shapeAABB); + } else { + aabb.extend(shapeAABB); + } + } + + this.aabbNeedsUpdate = false; +}; + +var uiw_m1 = new Mat3(), + uiw_m2 = new Mat3(), + uiw_m3 = new Mat3(); + +/** + * Update .inertiaWorld and .invInertiaWorld + * @method updateInertiaWorld + */ +Body.prototype.updateInertiaWorld = function(force){ + var I = this.invInertia; + if (I.x === I.y && I.y === I.z && !force) { + // If inertia M = s*I, where I is identity and s a scalar, then + // R*M*R' = R*(s*I)*R' = s*R*I*R' = s*R*R' = s*I = M + // where R is the rotation matrix. + // In other words, we don't have to transform the inertia if all + // inertia diagonal entries are equal. + } else { + var m1 = uiw_m1, + m2 = uiw_m2, + m3 = uiw_m3; + m1.setRotationFromQuaternion(this.quaternion); + m1.transpose(m2); + m1.scale(I,m1); + m1.mmult(m2,this.invInertiaWorld); + //m3.getTrace(this.invInertiaWorld); + } + + /* + this.quaternion.vmult(this.inertia,this.inertiaWorld); + this.quaternion.vmult(this.invInertia,this.invInertiaWorld); + */ +}; + +/** + * Apply force to a world point. This could for example be a point on the Body surface. Applying force this way will add to Body.force and Body.torque. + * @method applyForce + * @param {Vec3} force The amount of force to add. + * @param {Vec3} worldPoint A world point to apply the force on. + */ +var Body_applyForce_r = new Vec3(); +var Body_applyForce_rotForce = new Vec3(); +Body.prototype.applyForce = function(force,worldPoint){ + if(this.type !== Body.DYNAMIC){ + return; + } + + // Compute point position relative to the body center + var r = Body_applyForce_r; + worldPoint.vsub(this.position,r); + + // Compute produced rotational force + var rotForce = Body_applyForce_rotForce; + r.cross(force,rotForce); + + // Add linear force + this.force.vadd(force,this.force); + + // Add rotational force + this.torque.vadd(rotForce,this.torque); +}; + +/** + * Apply force to a local point in the body. + * @method applyLocalForce + * @param {Vec3} force The force vector to apply, defined locally in the body frame. + * @param {Vec3} localPoint A local point in the body to apply the force on. + */ +var Body_applyLocalForce_worldForce = new Vec3(); +var Body_applyLocalForce_worldPoint = new Vec3(); +Body.prototype.applyLocalForce = function(localForce, localPoint){ + if(this.type !== Body.DYNAMIC){ + return; + } + + var worldForce = Body_applyLocalForce_worldForce; + var worldPoint = Body_applyLocalForce_worldPoint; + + // Transform the force vector to world space + this.vectorToWorldFrame(localForce, worldForce); + this.pointToWorldFrame(localPoint, worldPoint); + + this.applyForce(worldForce, worldPoint); +}; + +/** + * Apply impulse to a world point. This could for example be a point on the Body surface. An impulse is a force added to a body during a short period of time (impulse = force * time). Impulses will be added to Body.velocity and Body.angularVelocity. + * @method applyImpulse + * @param {Vec3} impulse The amount of impulse to add. + * @param {Vec3} worldPoint A world point to apply the force on. + */ +var Body_applyImpulse_r = new Vec3(); +var Body_applyImpulse_velo = new Vec3(); +var Body_applyImpulse_rotVelo = new Vec3(); +Body.prototype.applyImpulse = function(impulse, worldPoint){ + if(this.type !== Body.DYNAMIC){ + return; + } + + // Compute point position relative to the body center + var r = Body_applyImpulse_r; + worldPoint.vsub(this.position,r); + + // Compute produced central impulse velocity + var velo = Body_applyImpulse_velo; + velo.copy(impulse); + velo.mult(this.invMass,velo); + + // Add linear impulse + this.velocity.vadd(velo, this.velocity); + + // Compute produced rotational impulse velocity + var rotVelo = Body_applyImpulse_rotVelo; + r.cross(impulse,rotVelo); + + /* + rotVelo.x *= this.invInertia.x; + rotVelo.y *= this.invInertia.y; + rotVelo.z *= this.invInertia.z; + */ + this.invInertiaWorld.vmult(rotVelo,rotVelo); + + // Add rotational Impulse + this.angularVelocity.vadd(rotVelo, this.angularVelocity); +}; + +/** + * Apply locally-defined impulse to a local point in the body. + * @method applyLocalImpulse + * @param {Vec3} force The force vector to apply, defined locally in the body frame. + * @param {Vec3} localPoint A local point in the body to apply the force on. + */ +var Body_applyLocalImpulse_worldImpulse = new Vec3(); +var Body_applyLocalImpulse_worldPoint = new Vec3(); +Body.prototype.applyLocalImpulse = function(localImpulse, localPoint){ + if(this.type !== Body.DYNAMIC){ + return; + } + + var worldImpulse = Body_applyLocalImpulse_worldImpulse; + var worldPoint = Body_applyLocalImpulse_worldPoint; + + // Transform the force vector to world space + this.vectorToWorldFrame(localImpulse, worldImpulse); + this.pointToWorldFrame(localPoint, worldPoint); + + this.applyImpulse(worldImpulse, worldPoint); +}; + +var Body_updateMassProperties_halfExtents = new Vec3(); + +/** + * Should be called whenever you change the body shape or mass. + * @method updateMassProperties + */ +Body.prototype.updateMassProperties = function(){ + var halfExtents = Body_updateMassProperties_halfExtents; + + this.invMass = this.mass > 0 ? 1.0 / this.mass : 0; + var I = this.inertia; + var fixed = this.fixedRotation; + + // Approximate with AABB box + this.computeAABB(); + halfExtents.set( + (this.aabb.upperBound.x-this.aabb.lowerBound.x) / 2, + (this.aabb.upperBound.y-this.aabb.lowerBound.y) / 2, + (this.aabb.upperBound.z-this.aabb.lowerBound.z) / 2 + ); + Box.calculateInertia(halfExtents, this.mass, I); + + this.invInertia.set( + I.x > 0 && !fixed ? 1.0 / I.x : 0, + I.y > 0 && !fixed ? 1.0 / I.y : 0, + I.z > 0 && !fixed ? 1.0 / I.z : 0 + ); + this.updateInertiaWorld(true); +}; + +/** + * Get world velocity of a point in the body. + * @method getVelocityAtWorldPoint + * @param {Vec3} worldPoint + * @param {Vec3} result + * @return {Vec3} The result vector. + */ +Body.prototype.getVelocityAtWorldPoint = function(worldPoint, result){ + var r = new Vec3(); + worldPoint.vsub(this.position, r); + this.angularVelocity.cross(r, result); + this.velocity.vadd(result, result); + return result; +}; + +},{"../collision/AABB":3,"../material/Material":25,"../math/Mat3":27,"../math/Quaternion":28,"../math/Vec3":30,"../shapes/Box":37,"../shapes/Shape":43,"../utils/EventTarget":49}],32:[function(_dereq_,module,exports){ +var Body = _dereq_('./Body'); +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var RaycastResult = _dereq_('../collision/RaycastResult'); +var Ray = _dereq_('../collision/Ray'); +var WheelInfo = _dereq_('../objects/WheelInfo'); + +module.exports = RaycastVehicle; + +/** + * Vehicle helper class that casts rays from the wheel positions towards the ground and applies forces. + * @class RaycastVehicle + * @constructor + * @param {object} [options] + * @param {Body} [options.chassisBody] The car chassis body. + * @param {integer} [options.indexRightAxis] Axis to use for right. x=0, y=1, z=2 + * @param {integer} [options.indexLeftAxis] + * @param {integer} [options.indexUpAxis] + */ +function RaycastVehicle(options){ + + /** + * @property {Body} chassisBody + */ + this.chassisBody = options.chassisBody; + + /** + * An array of WheelInfo objects. + * @property {array} wheelInfos + */ + this.wheelInfos = []; + + /** + * Will be set to true if the car is sliding. + * @property {boolean} sliding + */ + this.sliding = false; + + /** + * @property {World} world + */ + this.world = null; + + /** + * Index of the right axis, 0=x, 1=y, 2=z + * @property {integer} indexRightAxis + * @default 1 + */ + this.indexRightAxis = typeof(options.indexRightAxis) !== 'undefined' ? options.indexRightAxis : 1; + + /** + * Index of the forward axis, 0=x, 1=y, 2=z + * @property {integer} indexForwardAxis + * @default 0 + */ + this.indexForwardAxis = typeof(options.indexForwardAxis) !== 'undefined' ? options.indexForwardAxis : 0; + + /** + * Index of the up axis, 0=x, 1=y, 2=z + * @property {integer} indexUpAxis + * @default 2 + */ + this.indexUpAxis = typeof(options.indexUpAxis) !== 'undefined' ? options.indexUpAxis : 2; +} + +var tmpVec1 = new Vec3(); +var tmpVec2 = new Vec3(); +var tmpVec3 = new Vec3(); +var tmpVec4 = new Vec3(); +var tmpVec5 = new Vec3(); +var tmpVec6 = new Vec3(); +var tmpRay = new Ray(); + +/** + * Add a wheel. For information about the options, see WheelInfo. + * @method addWheel + * @param {object} [options] + */ +RaycastVehicle.prototype.addWheel = function(options){ + options = options || {}; + + var info = new WheelInfo(options); + var index = this.wheelInfos.length; + this.wheelInfos.push(info); + + return index; +}; + +/** + * Set the steering value of a wheel. + * @method setSteeringValue + * @param {number} value + * @param {integer} wheelIndex + */ +RaycastVehicle.prototype.setSteeringValue = function(value, wheelIndex){ + var wheel = this.wheelInfos[wheelIndex]; + wheel.steering = value; +}; + +var torque = new Vec3(); + +/** + * Set the wheel force to apply on one of the wheels each time step + * @method applyEngineForce + * @param {number} value + * @param {integer} wheelIndex + */ +RaycastVehicle.prototype.applyEngineForce = function(value, wheelIndex){ + this.wheelInfos[wheelIndex].engineForce = value; +}; + +/** + * Set the braking force of a wheel + * @method setBrake + * @param {number} brake + * @param {integer} wheelIndex + */ +RaycastVehicle.prototype.setBrake = function(brake, wheelIndex){ + this.wheelInfos[wheelIndex].brake = brake; +}; + +/** + * Add the vehicle including its constraints to the world. + * @method addToWorld + * @param {World} world + */ +RaycastVehicle.prototype.addToWorld = function(world){ + var constraints = this.constraints; + world.add(this.chassisBody); + var that = this; + this.preStepCallback = function(){ + that.updateVehicle(world.dt); + }; + world.addEventListener('preStep', this.preStepCallback); + this.world = world; +}; + +/** + * Get one of the wheel axles, world-oriented. + * @private + * @method getVehicleAxisWorld + * @param {integer} axisIndex + * @param {Vec3} result + */ +RaycastVehicle.prototype.getVehicleAxisWorld = function(axisIndex, result){ + result.set( + axisIndex === 0 ? 1 : 0, + axisIndex === 1 ? 1 : 0, + axisIndex === 2 ? 1 : 0 + ); + this.chassisBody.vectorToWorldFrame(result, result); +}; + +RaycastVehicle.prototype.updateVehicle = function(timeStep){ + var wheelInfos = this.wheelInfos; + var numWheels = wheelInfos.length; + var chassisBody = this.chassisBody; + + for (var i = 0; i < numWheels; i++) { + this.updateWheelTransform(i); + } + + this.currentVehicleSpeedKmHour = 3.6 * chassisBody.velocity.norm(); + + var forwardWorld = new Vec3(); + this.getVehicleAxisWorld(this.indexForwardAxis, forwardWorld); + + if (forwardWorld.dot(chassisBody.velocity) < 0){ + this.currentVehicleSpeedKmHour *= -1; + } + + // simulate suspension + for (var i = 0; i < numWheels; i++) { + this.castRay(wheelInfos[i]); + } + + this.updateSuspension(timeStep); + + var impulse = new Vec3(); + var relpos = new Vec3(); + for (var i = 0; i < numWheels; i++) { + //apply suspension force + var wheel = wheelInfos[i]; + var suspensionForce = wheel.suspensionForce; + if (suspensionForce > wheel.maxSuspensionForce) { + suspensionForce = wheel.maxSuspensionForce; + } + wheel.raycastResult.hitNormalWorld.scale(suspensionForce * timeStep, impulse); + + wheel.raycastResult.hitPointWorld.vsub(chassisBody.position, relpos); + chassisBody.applyImpulse(impulse, wheel.raycastResult.hitPointWorld/*relpos*/); + } + + this.updateFriction(timeStep); + + var hitNormalWorldScaledWithProj = new Vec3(); + var fwd = new Vec3(); + var vel = new Vec3(); + for (i = 0; i < numWheels; i++) { + var wheel = wheelInfos[i]; + //var relpos = new Vec3(); + //wheel.chassisConnectionPointWorld.vsub(chassisBody.position, relpos); + chassisBody.getVelocityAtWorldPoint(wheel.chassisConnectionPointWorld, vel); + + // Hack to get the rotation in the correct direction + var m = 1; + switch(this.indexUpAxis){ + case 1: + m = -1; + break; + } + + if (wheel.isInContact) { + + this.getVehicleAxisWorld(this.indexForwardAxis, fwd); + var proj = fwd.dot(wheel.raycastResult.hitNormalWorld); + wheel.raycastResult.hitNormalWorld.scale(proj, hitNormalWorldScaledWithProj); + + fwd.vsub(hitNormalWorldScaledWithProj, fwd); + + var proj2 = fwd.dot(vel); + wheel.deltaRotation = m * proj2 * timeStep / wheel.radius; + } + + if((wheel.sliding || !wheel.isInContact) && wheel.engineForce !== 0 && wheel.useCustomSlidingRotationalSpeed){ + // Apply custom rotation when accelerating and sliding + wheel.deltaRotation = (wheel.engineForce > 0 ? 1 : -1) * wheel.customSlidingRotationalSpeed * timeStep; + } + + // Lock wheels + if(Math.abs(wheel.brake) > Math.abs(wheel.engineForce)){ + wheel.deltaRotation = 0; + } + + wheel.rotation += wheel.deltaRotation; // Use the old value + wheel.deltaRotation *= 0.99; // damping of rotation when not in contact + } +}; + +RaycastVehicle.prototype.updateSuspension = function(deltaTime) { + var chassisBody = this.chassisBody; + var chassisMass = chassisBody.mass; + var wheelInfos = this.wheelInfos; + var numWheels = wheelInfos.length; + + for (var w_it = 0; w_it < numWheels; w_it++){ + var wheel = wheelInfos[w_it]; + + if (wheel.isInContact){ + var force; + + // Spring + var susp_length = wheel.suspensionRestLength; + var current_length = wheel.suspensionLength; + var length_diff = (susp_length - current_length); + + force = wheel.suspensionStiffness * length_diff * wheel.clippedInvContactDotSuspension; + + // Damper + var projected_rel_vel = wheel.suspensionRelativeVelocity; + var susp_damping; + if (projected_rel_vel < 0) { + susp_damping = wheel.dampingCompression; + } else { + susp_damping = wheel.dampingRelaxation; + } + force -= susp_damping * projected_rel_vel; + + wheel.suspensionForce = force * chassisMass; + if (wheel.suspensionForce < 0) { + wheel.suspensionForce = 0; + } + } else { + wheel.suspensionForce = 0; + } + } +}; + +/** + * Remove the vehicle including its constraints from the world. + * @method removeFromWorld + * @param {World} world + */ +RaycastVehicle.prototype.removeFromWorld = function(world){ + var constraints = this.constraints; + world.remove(this.chassisBody); + world.removeEventListener('preStep', this.preStepCallback); + this.world = null; +}; + +var castRay_rayvector = new Vec3(); +var castRay_target = new Vec3(); +RaycastVehicle.prototype.castRay = function(wheel) { + var rayvector = castRay_rayvector; + var target = castRay_target; + + this.updateWheelTransformWorld(wheel); + var chassisBody = this.chassisBody; + + var depth = -1; + + var raylen = wheel.suspensionRestLength + wheel.radius; + + wheel.directionWorld.scale(raylen, rayvector); + var source = wheel.chassisConnectionPointWorld; + source.vadd(rayvector, target); + var raycastResult = wheel.raycastResult; + + var param = 0; + + raycastResult.reset(); + // Turn off ray collision with the chassis temporarily + var oldState = chassisBody.collisionResponse; + chassisBody.collisionResponse = false; + + // Cast ray against world + this.world.rayTest(source, target, raycastResult); + chassisBody.collisionResponse = oldState; + + var object = raycastResult.body; + + wheel.raycastResult.groundObject = 0; + + if (object) { + depth = raycastResult.distance; + wheel.raycastResult.hitNormalWorld = raycastResult.hitNormalWorld; + wheel.isInContact = true; + + var hitDistance = raycastResult.distance; + wheel.suspensionLength = hitDistance - wheel.radius; + + // clamp on max suspension travel + var minSuspensionLength = wheel.suspensionRestLength - wheel.maxSuspensionTravel; + var maxSuspensionLength = wheel.suspensionRestLength + wheel.maxSuspensionTravel; + if (wheel.suspensionLength < minSuspensionLength) { + wheel.suspensionLength = minSuspensionLength; + } + if (wheel.suspensionLength > maxSuspensionLength) { + wheel.suspensionLength = maxSuspensionLength; + wheel.raycastResult.reset(); + } + + var denominator = wheel.raycastResult.hitNormalWorld.dot(wheel.directionWorld); + + var chassis_velocity_at_contactPoint = new Vec3(); + chassisBody.getVelocityAtWorldPoint(wheel.raycastResult.hitPointWorld, chassis_velocity_at_contactPoint); + + var projVel = wheel.raycastResult.hitNormalWorld.dot( chassis_velocity_at_contactPoint ); + + if (denominator >= -0.1) { + wheel.suspensionRelativeVelocity = 0; + wheel.clippedInvContactDotSuspension = 1 / 0.1; + } else { + var inv = -1 / denominator; + wheel.suspensionRelativeVelocity = projVel * inv; + wheel.clippedInvContactDotSuspension = inv; + } + + } else { + + //put wheel info as in rest position + wheel.suspensionLength = wheel.suspensionRestLength + 0 * wheel.maxSuspensionTravel; + wheel.suspensionRelativeVelocity = 0.0; + wheel.directionWorld.scale(-1, wheel.raycastResult.hitNormalWorld); + wheel.clippedInvContactDotSuspension = 1.0; + } + + return depth; +}; + +RaycastVehicle.prototype.updateWheelTransformWorld = function(wheel){ + wheel.isInContact = false; + var chassisBody = this.chassisBody; + chassisBody.pointToWorldFrame(wheel.chassisConnectionPointLocal, wheel.chassisConnectionPointWorld); + chassisBody.vectorToWorldFrame(wheel.directionLocal, wheel.directionWorld); + chassisBody.vectorToWorldFrame(wheel.axleLocal, wheel.axleWorld); +}; + + +/** + * Update one of the wheel transform. + * Note when rendering wheels: during each step, wheel transforms are updated BEFORE the chassis; ie. their position becomes invalid after the step. Thus when you render wheels, you must update wheel transforms before rendering them. See raycastVehicle demo for an example. + * @method updateWheelTransform + * @param {integer} wheelIndex The wheel index to update. + */ +RaycastVehicle.prototype.updateWheelTransform = function(wheelIndex){ + var up = tmpVec4; + var right = tmpVec5; + var fwd = tmpVec6; + + var wheel = this.wheelInfos[wheelIndex]; + this.updateWheelTransformWorld(wheel); + + wheel.directionLocal.scale(-1, up); + right.copy(wheel.axleLocal); + up.cross(right, fwd); + fwd.normalize(); + right.normalize(); + + // Rotate around steering over the wheelAxle + var steering = wheel.steering; + var steeringOrn = new Quaternion(); + steeringOrn.setFromAxisAngle(up, steering); + + var rotatingOrn = new Quaternion(); + rotatingOrn.setFromAxisAngle(right, wheel.rotation); + + // World rotation of the wheel + var q = wheel.worldTransform.quaternion; + this.chassisBody.quaternion.mult(steeringOrn, q); + q.mult(rotatingOrn, q); + + q.normalize(); + + // world position of the wheel + var p = wheel.worldTransform.position; + p.copy(wheel.directionWorld); + p.scale(wheel.suspensionLength, p); + p.vadd(wheel.chassisConnectionPointWorld, p); +}; + +var directions = [ + new Vec3(1, 0, 0), + new Vec3(0, 1, 0), + new Vec3(0, 0, 1) +]; + +/** + * Get the world transform of one of the wheels + * @method getWheelTransformWorld + * @param {integer} wheelIndex + * @return {Transform} + */ +RaycastVehicle.prototype.getWheelTransformWorld = function(wheelIndex) { + return this.wheelInfos[wheelIndex].worldTransform; +}; + + +var updateFriction_surfNormalWS_scaled_proj = new Vec3(); +var updateFriction_axle = []; +var updateFriction_forwardWS = []; +var sideFrictionStiffness2 = 1; +RaycastVehicle.prototype.updateFriction = function(timeStep) { + var surfNormalWS_scaled_proj = updateFriction_surfNormalWS_scaled_proj; + + //calculate the impulse, so that the wheels don't move sidewards + var wheelInfos = this.wheelInfos; + var numWheels = wheelInfos.length; + var chassisBody = this.chassisBody; + var forwardWS = updateFriction_forwardWS; + var axle = updateFriction_axle; + + var numWheelsOnGround = 0; + + for (var i = 0; i < numWheels; i++) { + var wheel = wheelInfos[i]; + + var groundObject = wheel.raycastResult.body; + if (groundObject){ + numWheelsOnGround++; + } + + wheel.sideImpulse = 0; + wheel.forwardImpulse = 0; + if(!forwardWS[i]){ + forwardWS[i] = new Vec3(); + } + if(!axle[i]){ + axle[i] = new Vec3(); + } + } + + for (var i = 0; i < numWheels; i++){ + var wheel = wheelInfos[i]; + + var groundObject = wheel.raycastResult.body; + + if (groundObject) { + var axlei = axle[i]; + var wheelTrans = this.getWheelTransformWorld(i); + + // Get world axle + wheelTrans.vectorToWorldFrame(directions[this.indexRightAxis], axlei); + + var surfNormalWS = wheel.raycastResult.hitNormalWorld; + var proj = axlei.dot(surfNormalWS); + surfNormalWS.scale(proj, surfNormalWS_scaled_proj); + axlei.vsub(surfNormalWS_scaled_proj, axlei); + axlei.normalize(); + + surfNormalWS.cross(axlei, forwardWS[i]); + forwardWS[i].normalize(); + + wheel.sideImpulse = resolveSingleBilateral( + chassisBody, + wheel.raycastResult.hitPointWorld, + groundObject, + wheel.raycastResult.hitPointWorld, + axlei + ); + + wheel.sideImpulse *= sideFrictionStiffness2; + } + } + + var sideFactor = 1; + var fwdFactor = 0.5; + + this.sliding = false; + for (var i = 0; i < numWheels; i++) { + var wheel = wheelInfos[i]; + var groundObject = wheel.raycastResult.body; + + var rollingFriction = 0; + + wheel.slipInfo = 1; + if (groundObject) { + var defaultRollingFrictionImpulse = 0; + var maxImpulse = wheel.brake ? wheel.brake : defaultRollingFrictionImpulse; + + // btWheelContactPoint contactPt(chassisBody,groundObject,wheelInfraycastInfo.hitPointWorld,forwardWS[wheel],maxImpulse); + // rollingFriction = calcRollingFriction(contactPt); + rollingFriction = calcRollingFriction(chassisBody, groundObject, wheel.raycastResult.hitPointWorld, forwardWS[i], maxImpulse); + + rollingFriction += wheel.engineForce * timeStep; + + // rollingFriction = 0; + var factor = maxImpulse / rollingFriction; + wheel.slipInfo *= factor; + } + + //switch between active rolling (throttle), braking and non-active rolling friction (nthrottle/break) + + wheel.forwardImpulse = 0; + wheel.skidInfo = 1; + + if (groundObject) { + wheel.skidInfo = 1; + + var maximp = wheel.suspensionForce * timeStep * wheel.frictionSlip; + var maximpSide = maximp; + + var maximpSquared = maximp * maximpSide; + + wheel.forwardImpulse = rollingFriction;//wheelInfo.engineForce* timeStep; + + var x = wheel.forwardImpulse * fwdFactor; + var y = wheel.sideImpulse * sideFactor; + + var impulseSquared = x * x + y * y; + + wheel.sliding = false; + if (impulseSquared > maximpSquared) { + this.sliding = true; + wheel.sliding = true; + + var factor = maximp / Math.sqrt(impulseSquared); + + wheel.skidInfo *= factor; + } + } + } + + if (this.sliding) { + for (var i = 0; i < numWheels; i++) { + var wheel = wheelInfos[i]; + if (wheel.sideImpulse !== 0) { + if (wheel.skidInfo < 1){ + wheel.forwardImpulse *= wheel.skidInfo; + wheel.sideImpulse *= wheel.skidInfo; + } + } + } + } + + // apply the impulses + for (var i = 0; i < numWheels; i++) { + var wheel = wheelInfos[i]; + + var rel_pos = new Vec3(); + //wheel.raycastResult.hitPointWorld.vsub(chassisBody.position, rel_pos); + // cannons applyimpulse is using world coord for the position + rel_pos.copy(wheel.raycastResult.hitPointWorld); + + if (wheel.forwardImpulse !== 0) { + var impulse = new Vec3(); + forwardWS[i].scale(wheel.forwardImpulse, impulse); + chassisBody.applyImpulse(impulse, rel_pos); + } + + if (wheel.sideImpulse !== 0){ + var groundObject = wheel.raycastResult.body; + + var rel_pos2 = new Vec3(); + //wheel.raycastResult.hitPointWorld.vsub(groundObject.position, rel_pos2); + rel_pos2.copy(wheel.raycastResult.hitPointWorld); + var sideImp = new Vec3(); + axle[i].scale(wheel.sideImpulse, sideImp); + + // Scale the relative position in the up direction with rollInfluence. + // If rollInfluence is 1, the impulse will be applied on the hitPoint (easy to roll over), if it is zero it will be applied in the same plane as the center of mass (not easy to roll over). + chassisBody.pointToLocalFrame(rel_pos, rel_pos); + rel_pos['xyz'[this.indexUpAxis]] *= wheel.rollInfluence; + chassisBody.pointToWorldFrame(rel_pos, rel_pos); + chassisBody.applyImpulse(sideImp, rel_pos); + + //apply friction impulse on the ground + sideImp.scale(-1, sideImp); + groundObject.applyImpulse(sideImp, rel_pos2); + } + } +}; + +var calcRollingFriction_vel1 = new Vec3(); +var calcRollingFriction_vel2 = new Vec3(); +var calcRollingFriction_vel = new Vec3(); + +function calcRollingFriction(body0, body1, frictionPosWorld, frictionDirectionWorld, maxImpulse) { + var j1 = 0; + var contactPosWorld = frictionPosWorld; + + // var rel_pos1 = new Vec3(); + // var rel_pos2 = new Vec3(); + var vel1 = calcRollingFriction_vel1; + var vel2 = calcRollingFriction_vel2; + var vel = calcRollingFriction_vel; + // contactPosWorld.vsub(body0.position, rel_pos1); + // contactPosWorld.vsub(body1.position, rel_pos2); + + body0.getVelocityAtWorldPoint(contactPosWorld, vel1); + body1.getVelocityAtWorldPoint(contactPosWorld, vel2); + vel1.vsub(vel2, vel); + + var vrel = frictionDirectionWorld.dot(vel); + + var denom0 = computeImpulseDenominator(body0, frictionPosWorld, frictionDirectionWorld); + var denom1 = computeImpulseDenominator(body1, frictionPosWorld, frictionDirectionWorld); + var relaxation = 1; + var jacDiagABInv = relaxation / (denom0 + denom1); + + // calculate j that moves us to zero relative velocity + j1 = -vrel * jacDiagABInv; + + if (maxImpulse < j1) { + j1 = maxImpulse; + } + if (j1 < -maxImpulse) { + j1 = -maxImpulse; + } + + return j1; +} + +var computeImpulseDenominator_r0 = new Vec3(); +var computeImpulseDenominator_c0 = new Vec3(); +var computeImpulseDenominator_vec = new Vec3(); +var computeImpulseDenominator_m = new Vec3(); +function computeImpulseDenominator(body, pos, normal) { + var r0 = computeImpulseDenominator_r0; + var c0 = computeImpulseDenominator_c0; + var vec = computeImpulseDenominator_vec; + var m = computeImpulseDenominator_m; + + pos.vsub(body.position, r0); + r0.cross(normal, c0); + body.invInertiaWorld.vmult(c0, m); + m.cross(r0, vec); + + return body.invMass + normal.dot(vec); +} + + +var resolveSingleBilateral_vel1 = new Vec3(); +var resolveSingleBilateral_vel2 = new Vec3(); +var resolveSingleBilateral_vel = new Vec3(); + +//bilateral constraint between two dynamic objects +function resolveSingleBilateral(body1, pos1, body2, pos2, normal, impulse){ + var normalLenSqr = normal.norm2(); + if (normalLenSqr > 1.1){ + return 0; // no impulse + } + // var rel_pos1 = new Vec3(); + // var rel_pos2 = new Vec3(); + // pos1.vsub(body1.position, rel_pos1); + // pos2.vsub(body2.position, rel_pos2); + + var vel1 = resolveSingleBilateral_vel1; + var vel2 = resolveSingleBilateral_vel2; + var vel = resolveSingleBilateral_vel; + body1.getVelocityAtWorldPoint(pos1, vel1); + body2.getVelocityAtWorldPoint(pos2, vel2); + + vel1.vsub(vel2, vel); + + var rel_vel = normal.dot(vel); + + var contactDamping = 0.2; + var massTerm = 1 / (body1.invMass + body2.invMass); + var impulse = - contactDamping * rel_vel * massTerm; + + return impulse; +} +},{"../collision/Ray":9,"../collision/RaycastResult":10,"../math/Quaternion":28,"../math/Vec3":30,"../objects/WheelInfo":36,"./Body":31}],33:[function(_dereq_,module,exports){ +var Body = _dereq_('./Body'); +var Sphere = _dereq_('../shapes/Sphere'); +var Box = _dereq_('../shapes/Box'); +var Vec3 = _dereq_('../math/Vec3'); +var HingeConstraint = _dereq_('../constraints/HingeConstraint'); + +module.exports = RigidVehicle; + +/** + * Simple vehicle helper class with spherical rigid body wheels. + * @class RigidVehicle + * @constructor + * @param {Body} [options.chassisBody] + */ +function RigidVehicle(options){ + this.wheelBodies = []; + + /** + * @property coordinateSystem + * @type {Vec3} + */ + this.coordinateSystem = typeof(options.coordinateSystem)==='undefined' ? new Vec3(1, 2, 3) : options.coordinateSystem.clone(); + + /** + * @property {Body} chassisBody + */ + this.chassisBody = options.chassisBody; + + if(!this.chassisBody){ + // No chassis body given. Create it! + var chassisShape = new Box(new Vec3(5, 2, 0.5)); + this.chassisBody = new Body(1, chassisShape); + } + + /** + * @property constraints + * @type {Array} + */ + this.constraints = []; + + this.wheelAxes = []; + this.wheelForces = []; +} + +/** + * Add a wheel + * @method addWheel + * @param {object} options + * @param {boolean} [options.isFrontWheel] + * @param {Vec3} [options.position] Position of the wheel, locally in the chassis body. + * @param {Vec3} [options.direction] Slide direction of the wheel along the suspension. + * @param {Vec3} [options.axis] Axis of rotation of the wheel, locally defined in the chassis. + * @param {Body} [options.body] The wheel body. + */ +RigidVehicle.prototype.addWheel = function(options){ + options = options || {}; + var wheelBody = options.body; + if(!wheelBody){ + wheelBody = new Body(1, new Sphere(1.2)); + } + this.wheelBodies.push(wheelBody); + this.wheelForces.push(0); + + // Position constrain wheels + var zero = new Vec3(); + var position = typeof(options.position) !== 'undefined' ? options.position.clone() : new Vec3(); + + // Set position locally to the chassis + var worldPosition = new Vec3(); + this.chassisBody.pointToWorldFrame(position, worldPosition); + wheelBody.position.set(worldPosition.x, worldPosition.y, worldPosition.z); + + // Constrain wheel + var axis = typeof(options.axis) !== 'undefined' ? options.axis.clone() : new Vec3(0, 1, 0); + this.wheelAxes.push(axis); + + var hingeConstraint = new HingeConstraint(this.chassisBody, wheelBody, { + pivotA: position, + axisA: axis, + pivotB: Vec3.ZERO, + axisB: axis, + collideConnected: false + }); + this.constraints.push(hingeConstraint); + + return this.wheelBodies.length - 1; +}; + +/** + * Set the steering value of a wheel. + * @method setSteeringValue + * @param {number} value + * @param {integer} wheelIndex + * @todo check coordinateSystem + */ +RigidVehicle.prototype.setSteeringValue = function(value, wheelIndex){ + // Set angle of the hinge axis + var axis = this.wheelAxes[wheelIndex]; + + var c = Math.cos(value), + s = Math.sin(value), + x = axis.x, + y = axis.y; + this.constraints[wheelIndex].axisA.set( + c*x -s*y, + s*x +c*y, + 0 + ); +}; + +/** + * Set the target rotational speed of the hinge constraint. + * @method setMotorSpeed + * @param {number} value + * @param {integer} wheelIndex + */ +RigidVehicle.prototype.setMotorSpeed = function(value, wheelIndex){ + var hingeConstraint = this.constraints[wheelIndex]; + hingeConstraint.enableMotor(); + hingeConstraint.motorTargetVelocity = value; +}; + +/** + * Set the target rotational speed of the hinge constraint. + * @method disableMotor + * @param {number} value + * @param {integer} wheelIndex + */ +RigidVehicle.prototype.disableMotor = function(wheelIndex){ + var hingeConstraint = this.constraints[wheelIndex]; + hingeConstraint.disableMotor(); +}; + +var torque = new Vec3(); + +/** + * Set the wheel force to apply on one of the wheels each time step + * @method setWheelForce + * @param {number} value + * @param {integer} wheelIndex + */ +RigidVehicle.prototype.setWheelForce = function(value, wheelIndex){ + this.wheelForces[wheelIndex] = value; +}; + +/** + * Apply a torque on one of the wheels. + * @method applyWheelForce + * @param {number} value + * @param {integer} wheelIndex + */ +RigidVehicle.prototype.applyWheelForce = function(value, wheelIndex){ + var axis = this.wheelAxes[wheelIndex]; + var wheelBody = this.wheelBodies[wheelIndex]; + var bodyTorque = wheelBody.torque; + + axis.scale(value, torque); + wheelBody.vectorToWorldFrame(torque, torque); + bodyTorque.vadd(torque, bodyTorque); +}; + +/** + * Add the vehicle including its constraints to the world. + * @method addToWorld + * @param {World} world + */ +RigidVehicle.prototype.addToWorld = function(world){ + var constraints = this.constraints; + var bodies = this.wheelBodies.concat([this.chassisBody]); + + for (var i = 0; i < bodies.length; i++) { + world.add(bodies[i]); + } + + for (var i = 0; i < constraints.length; i++) { + world.addConstraint(constraints[i]); + } + + world.addEventListener('preStep', this._update.bind(this)); +}; + +RigidVehicle.prototype._update = function(){ + var wheelForces = this.wheelForces; + for (var i = 0; i < wheelForces.length; i++) { + this.applyWheelForce(wheelForces[i], i); + } +}; + +/** + * Remove the vehicle including its constraints from the world. + * @method removeFromWorld + * @param {World} world + */ +RigidVehicle.prototype.removeFromWorld = function(world){ + var constraints = this.constraints; + var bodies = this.wheelBodies.concat([this.chassisBody]); + + for (var i = 0; i < bodies.length; i++) { + world.remove(bodies[i]); + } + + for (var i = 0; i < constraints.length; i++) { + world.removeConstraint(constraints[i]); + } +}; + +var worldAxis = new Vec3(); + +/** + * Get current rotational velocity of a wheel + * @method getWheelSpeed + * @param {integer} wheelIndex + */ +RigidVehicle.prototype.getWheelSpeed = function(wheelIndex){ + var axis = this.wheelAxes[wheelIndex]; + var wheelBody = this.wheelBodies[wheelIndex]; + var w = wheelBody.angularVelocity; + this.chassisBody.vectorToWorldFrame(axis, worldAxis); + return w.dot(worldAxis); +}; + +},{"../constraints/HingeConstraint":15,"../math/Vec3":30,"../shapes/Box":37,"../shapes/Sphere":44,"./Body":31}],34:[function(_dereq_,module,exports){ +module.exports = SPHSystem; + +var Shape = _dereq_('../shapes/Shape'); +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var Particle = _dereq_('../shapes/Particle'); +var Body = _dereq_('../objects/Body'); +var Material = _dereq_('../material/Material'); + +/** + * Smoothed-particle hydrodynamics system + * @class SPHSystem + * @constructor + */ +function SPHSystem(){ + this.particles = []; + + /** + * Density of the system (kg/m3). + * @property {number} density + */ + this.density = 1; + + /** + * Distance below which two particles are considered to be neighbors. + * It should be adjusted so there are about 15-20 neighbor particles within this radius. + * @property {number} smoothingRadius + */ + this.smoothingRadius = 1; + this.speedOfSound = 1; + + /** + * Viscosity of the system. + * @property {number} viscosity + */ + this.viscosity = 0.01; + this.eps = 0.000001; + + // Stuff Computed per particle + this.pressures = []; + this.densities = []; + this.neighbors = []; +} + +/** + * Add a particle to the system. + * @method add + * @param {Body} particle + */ +SPHSystem.prototype.add = function(particle){ + this.particles.push(particle); + if(this.neighbors.length < this.particles.length){ + this.neighbors.push([]); + } +}; + +/** + * Remove a particle from the system. + * @method remove + * @param {Body} particle + */ +SPHSystem.prototype.remove = function(particle){ + var idx = this.particles.indexOf(particle); + if(idx !== -1){ + this.particles.splice(idx,1); + if(this.neighbors.length > this.particles.length){ + this.neighbors.pop(); + } + } +}; + +/** + * Get neighbors within smoothing volume, save in the array neighbors + * @method getNeighbors + * @param {Body} particle + * @param {Array} neighbors + */ +var SPHSystem_getNeighbors_dist = new Vec3(); +SPHSystem.prototype.getNeighbors = function(particle,neighbors){ + var N = this.particles.length, + id = particle.id, + R2 = this.smoothingRadius * this.smoothingRadius, + dist = SPHSystem_getNeighbors_dist; + for(var i=0; i!==N; i++){ + var p = this.particles[i]; + p.position.vsub(particle.position,dist); + if(id!==p.id && dist.norm2() < R2){ + neighbors.push(p); + } + } +}; + +// Temp vectors for calculation +var SPHSystem_update_dist = new Vec3(), + SPHSystem_update_a_pressure = new Vec3(), + SPHSystem_update_a_visc = new Vec3(), + SPHSystem_update_gradW = new Vec3(), + SPHSystem_update_r_vec = new Vec3(), + SPHSystem_update_u = new Vec3(); // Relative velocity +SPHSystem.prototype.update = function(){ + var N = this.particles.length, + dist = SPHSystem_update_dist, + cs = this.speedOfSound, + eps = this.eps; + + for(var i=0; i!==N; i++){ + var p = this.particles[i]; // Current particle + var neighbors = this.neighbors[i]; + + // Get neighbors + neighbors.length = 0; + this.getNeighbors(p,neighbors); + neighbors.push(this.particles[i]); // Add current too + var numNeighbors = neighbors.length; + + // Accumulate density for the particle + var sum = 0.0; + for(var j=0; j!==numNeighbors; j++){ + + //printf("Current particle has position %f %f %f\n",objects[id].pos.x(),objects[id].pos.y(),objects[id].pos.z()); + p.position.vsub(neighbors[j].position, dist); + var len = dist.norm(); + + var weight = this.w(len); + sum += neighbors[j].mass * weight; + } + + // Save + this.densities[i] = sum; + this.pressures[i] = cs * cs * (this.densities[i] - this.density); + } + + // Add forces + + // Sum to these accelerations + var a_pressure= SPHSystem_update_a_pressure; + var a_visc = SPHSystem_update_a_visc; + var gradW = SPHSystem_update_gradW; + var r_vec = SPHSystem_update_r_vec; + var u = SPHSystem_update_u; + + for(var i=0; i!==N; i++){ + + var particle = this.particles[i]; + + a_pressure.set(0,0,0); + a_visc.set(0,0,0); + + // Init vars + var Pij; + var nabla; + var Vij; + + // Sum up for all other neighbors + var neighbors = this.neighbors[i]; + var numNeighbors = neighbors.length; + + //printf("Neighbors: "); + for(var j=0; j!==numNeighbors; j++){ + + var neighbor = neighbors[j]; + //printf("%d ",nj); + + // Get r once for all.. + particle.position.vsub(neighbor.position,r_vec); + var r = r_vec.norm(); + + // Pressure contribution + Pij = -neighbor.mass * (this.pressures[i] / (this.densities[i]*this.densities[i] + eps) + this.pressures[j] / (this.densities[j]*this.densities[j] + eps)); + this.gradw(r_vec, gradW); + // Add to pressure acceleration + gradW.mult(Pij , gradW); + a_pressure.vadd(gradW, a_pressure); + + // Viscosity contribution + neighbor.velocity.vsub(particle.velocity, u); + u.mult( 1.0 / (0.0001+this.densities[i] * this.densities[j]) * this.viscosity * neighbor.mass , u ); + nabla = this.nablaw(r); + u.mult(nabla,u); + // Add to viscosity acceleration + a_visc.vadd( u, a_visc ); + } + + // Calculate force + a_visc.mult(particle.mass, a_visc); + a_pressure.mult(particle.mass, a_pressure); + + // Add force to particles + particle.force.vadd(a_visc, particle.force); + particle.force.vadd(a_pressure, particle.force); + } +}; + +// Calculate the weight using the W(r) weightfunction +SPHSystem.prototype.w = function(r){ + // 315 + var h = this.smoothingRadius; + return 315.0/(64.0*Math.PI*Math.pow(h,9)) * Math.pow(h*h-r*r,3); +}; + +// calculate gradient of the weight function +SPHSystem.prototype.gradw = function(rVec,resultVec){ + var r = rVec.norm(), + h = this.smoothingRadius; + rVec.mult(945.0/(32.0*Math.PI*Math.pow(h,9)) * Math.pow((h*h-r*r),2) , resultVec); +}; + +// Calculate nabla(W) +SPHSystem.prototype.nablaw = function(r){ + var h = this.smoothingRadius; + var nabla = 945.0/(32.0*Math.PI*Math.pow(h,9)) * (h*h-r*r)*(7*r*r - 3*h*h); + return nabla; +}; + +},{"../material/Material":25,"../math/Quaternion":28,"../math/Vec3":30,"../objects/Body":31,"../shapes/Particle":41,"../shapes/Shape":43}],35:[function(_dereq_,module,exports){ +var Vec3 = _dereq_('../math/Vec3'); + +module.exports = Spring; + +/** + * A spring, connecting two bodies. + * + * @class Spring + * @constructor + * @param {Body} bodyA + * @param {Body} bodyB + * @param {Object} [options] + * @param {number} [options.restLength] A number > 0. Default: 1 + * @param {number} [options.stiffness] A number >= 0. Default: 100 + * @param {number} [options.damping] A number >= 0. Default: 1 + * @param {Vec3} [options.worldAnchorA] Where to hook the spring to body A, in world coordinates. + * @param {Vec3} [options.worldAnchorB] + * @param {Vec3} [options.localAnchorA] Where to hook the spring to body A, in local body coordinates. + * @param {Vec3} [options.localAnchorB] + */ +function Spring(bodyA,bodyB,options){ + options = options || {}; + + /** + * Rest length of the spring. + * @property restLength + * @type {number} + */ + this.restLength = typeof(options.restLength) === "number" ? options.restLength : 1; + + /** + * Stiffness of the spring. + * @property stiffness + * @type {number} + */ + this.stiffness = options.stiffness || 100; + + /** + * Damping of the spring. + * @property damping + * @type {number} + */ + this.damping = options.damping || 1; + + /** + * First connected body. + * @property bodyA + * @type {Body} + */ + this.bodyA = bodyA; + + /** + * Second connected body. + * @property bodyB + * @type {Body} + */ + this.bodyB = bodyB; + + /** + * Anchor for bodyA in local bodyA coordinates. + * @property localAnchorA + * @type {Vec3} + */ + this.localAnchorA = new Vec3(); + + /** + * Anchor for bodyB in local bodyB coordinates. + * @property localAnchorB + * @type {Vec3} + */ + this.localAnchorB = new Vec3(); + + if(options.localAnchorA){ + this.localAnchorA.copy(options.localAnchorA); + } + if(options.localAnchorB){ + this.localAnchorB.copy(options.localAnchorB); + } + if(options.worldAnchorA){ + this.setWorldAnchorA(options.worldAnchorA); + } + if(options.worldAnchorB){ + this.setWorldAnchorB(options.worldAnchorB); + } +} + +/** + * Set the anchor point on body A, using world coordinates. + * @method setWorldAnchorA + * @param {Vec3} worldAnchorA + */ +Spring.prototype.setWorldAnchorA = function(worldAnchorA){ + this.bodyA.pointToLocalFrame(worldAnchorA,this.localAnchorA); +}; + +/** + * Set the anchor point on body B, using world coordinates. + * @method setWorldAnchorB + * @param {Vec3} worldAnchorB + */ +Spring.prototype.setWorldAnchorB = function(worldAnchorB){ + this.bodyB.pointToLocalFrame(worldAnchorB,this.localAnchorB); +}; + +/** + * Get the anchor point on body A, in world coordinates. + * @method getWorldAnchorA + * @param {Vec3} result The vector to store the result in. + */ +Spring.prototype.getWorldAnchorA = function(result){ + this.bodyA.pointToWorldFrame(this.localAnchorA,result); +}; + +/** + * Get the anchor point on body B, in world coordinates. + * @method getWorldAnchorB + * @param {Vec3} result The vector to store the result in. + */ +Spring.prototype.getWorldAnchorB = function(result){ + this.bodyB.pointToWorldFrame(this.localAnchorB,result); +}; + +var applyForce_r = new Vec3(), + applyForce_r_unit = new Vec3(), + applyForce_u = new Vec3(), + applyForce_f = new Vec3(), + applyForce_worldAnchorA = new Vec3(), + applyForce_worldAnchorB = new Vec3(), + applyForce_ri = new Vec3(), + applyForce_rj = new Vec3(), + applyForce_ri_x_f = new Vec3(), + applyForce_rj_x_f = new Vec3(), + applyForce_tmp = new Vec3(); + +/** + * Apply the spring force to the connected bodies. + * @method applyForce + */ +Spring.prototype.applyForce = function(){ + var k = this.stiffness, + d = this.damping, + l = this.restLength, + bodyA = this.bodyA, + bodyB = this.bodyB, + r = applyForce_r, + r_unit = applyForce_r_unit, + u = applyForce_u, + f = applyForce_f, + tmp = applyForce_tmp; + + var worldAnchorA = applyForce_worldAnchorA, + worldAnchorB = applyForce_worldAnchorB, + ri = applyForce_ri, + rj = applyForce_rj, + ri_x_f = applyForce_ri_x_f, + rj_x_f = applyForce_rj_x_f; + + // Get world anchors + this.getWorldAnchorA(worldAnchorA); + this.getWorldAnchorB(worldAnchorB); + + // Get offset points + worldAnchorA.vsub(bodyA.position,ri); + worldAnchorB.vsub(bodyB.position,rj); + + // Compute distance vector between world anchor points + worldAnchorB.vsub(worldAnchorA,r); + var rlen = r.norm(); + r_unit.copy(r); + r_unit.normalize(); + + // Compute relative velocity of the anchor points, u + bodyB.velocity.vsub(bodyA.velocity,u); + // Add rotational velocity + + bodyB.angularVelocity.cross(rj,tmp); + u.vadd(tmp,u); + bodyA.angularVelocity.cross(ri,tmp); + u.vsub(tmp,u); + + // F = - k * ( x - L ) - D * ( u ) + r_unit.mult(-k*(rlen-l) - d*u.dot(r_unit), f); + + // Add forces to bodies + bodyA.force.vsub(f,bodyA.force); + bodyB.force.vadd(f,bodyB.force); + + // Angular force + ri.cross(f,ri_x_f); + rj.cross(f,rj_x_f); + bodyA.torque.vsub(ri_x_f,bodyA.torque); + bodyB.torque.vadd(rj_x_f,bodyB.torque); +}; + +},{"../math/Vec3":30}],36:[function(_dereq_,module,exports){ +var Vec3 = _dereq_('../math/Vec3'); +var Transform = _dereq_('../math/Transform'); +var RaycastResult = _dereq_('../collision/RaycastResult'); +var Utils = _dereq_('../utils/Utils'); + +module.exports = WheelInfo; + +/** + * @class WheelInfo + * @constructor + * @param {Object} [options] + * + * @param {Vec3} [options.chassisConnectionPointLocal] + * @param {Vec3} [options.chassisConnectionPointWorld] + * @param {Vec3} [options.directionLocal] + * @param {Vec3} [options.directionWorld] + * @param {Vec3} [options.axleLocal] + * @param {Vec3} [options.axleWorld] + * @param {number} [options.suspensionRestLength=1] + * @param {number} [options.suspensionMaxLength=2] + * @param {number} [options.radius=1] + * @param {number} [options.suspensionStiffness=100] + * @param {number} [options.dampingCompression=10] + * @param {number} [options.dampingRelaxation=10] + * @param {number} [options.frictionSlip=10000] + * @param {number} [options.steering=0] + * @param {number} [options.rotation=0] + * @param {number} [options.deltaRotation=0] + * @param {number} [options.rollInfluence=0.01] + * @param {number} [options.maxSuspensionForce] + * @param {boolean} [options.isFrontWheel=true] + * @param {number} [options.clippedInvContactDotSuspension=1] + * @param {number} [options.suspensionRelativeVelocity=0] + * @param {number} [options.suspensionForce=0] + * @param {number} [options.skidInfo=0] + * @param {number} [options.suspensionLength=0] + * @param {number} [options.maxSuspensionTravel=1] + * @param {boolean} [options.useCustomSlidingRotationalSpeed=false] + * @param {number} [options.customSlidingRotationalSpeed=-0.1] + */ +function WheelInfo(options){ + options = Utils.defaults(options, { + chassisConnectionPointLocal: new Vec3(), + chassisConnectionPointWorld: new Vec3(), + directionLocal: new Vec3(), + directionWorld: new Vec3(), + axleLocal: new Vec3(), + axleWorld: new Vec3(), + suspensionRestLength: 1, + suspensionMaxLength: 2, + radius: 1, + suspensionStiffness: 100, + dampingCompression: 10, + dampingRelaxation: 10, + frictionSlip: 10000, + steering: 0, + rotation: 0, + deltaRotation: 0, + rollInfluence: 0.01, + maxSuspensionForce: Number.MAX_VALUE, + isFrontWheel: true, + clippedInvContactDotSuspension: 1, + suspensionRelativeVelocity: 0, + suspensionForce: 0, + skidInfo: 0, + suspensionLength: 0, + maxSuspensionTravel: 1, + useCustomSlidingRotationalSpeed: false, + customSlidingRotationalSpeed: -0.1 + }); + + /** + * Max travel distance of the suspension, in meters. + * @property {number} maxSuspensionTravel + */ + this.maxSuspensionTravel = options.maxSuspensionTravel; + + /** + * Speed to apply to the wheel rotation when the wheel is sliding. + * @property {number} customSlidingRotationalSpeed + */ + this.customSlidingRotationalSpeed = options.customSlidingRotationalSpeed; + + /** + * If the customSlidingRotationalSpeed should be used. + * @property {Boolean} useCustomSlidingRotationalSpeed + */ + this.useCustomSlidingRotationalSpeed = options.useCustomSlidingRotationalSpeed; + + /** + * @property {Boolean} sliding + */ + this.sliding = false; + + /** + * Connection point, defined locally in the chassis body frame. + * @property {Vec3} chassisConnectionPointLocal + */ + this.chassisConnectionPointLocal = options.chassisConnectionPointLocal.clone(); + + /** + * @property {Vec3} chassisConnectionPointWorld + */ + this.chassisConnectionPointWorld = options.chassisConnectionPointWorld.clone(); + + /** + * @property {Vec3} directionLocal + */ + this.directionLocal = options.directionLocal.clone(); + + /** + * @property {Vec3} directionWorld + */ + this.directionWorld = options.directionWorld.clone(); + + /** + * @property {Vec3} axleLocal + */ + this.axleLocal = options.axleLocal.clone(); + + /** + * @property {Vec3} axleWorld + */ + this.axleWorld = options.axleWorld.clone(); + + /** + * @property {number} suspensionRestLength + */ + this.suspensionRestLength = options.suspensionRestLength; + + /** + * @property {number} suspensionMaxLength + */ + this.suspensionMaxLength = options.suspensionMaxLength; + + /** + * @property {number} radius + */ + this.radius = options.radius; + + /** + * @property {number} suspensionStiffness + */ + this.suspensionStiffness = options.suspensionStiffness; + + /** + * @property {number} dampingCompression + */ + this.dampingCompression = options.dampingCompression; + + /** + * @property {number} dampingRelaxation + */ + this.dampingRelaxation = options.dampingRelaxation; + + /** + * @property {number} frictionSlip + */ + this.frictionSlip = options.frictionSlip; + + /** + * @property {number} steering + */ + this.steering = 0; + + /** + * Rotation value, in radians. + * @property {number} rotation + */ + this.rotation = 0; + + /** + * @property {number} deltaRotation + */ + this.deltaRotation = 0; + + /** + * @property {number} rollInfluence + */ + this.rollInfluence = options.rollInfluence; + + /** + * @property {number} maxSuspensionForce + */ + this.maxSuspensionForce = options.maxSuspensionForce; + + /** + * @property {number} engineForce + */ + this.engineForce = 0; + + /** + * @property {number} brake + */ + this.brake = 0; + + /** + * @property {number} isFrontWheel + */ + this.isFrontWheel = options.isFrontWheel; + + /** + * @property {number} clippedInvContactDotSuspension + */ + this.clippedInvContactDotSuspension = 1; + + /** + * @property {number} suspensionRelativeVelocity + */ + this.suspensionRelativeVelocity = 0; + + /** + * @property {number} suspensionForce + */ + this.suspensionForce = 0; + + /** + * @property {number} skidInfo + */ + this.skidInfo = 0; + + /** + * @property {number} suspensionLength + */ + this.suspensionLength = 0; + + /** + * @property {number} sideImpulse + */ + this.sideImpulse = 0; + + /** + * @property {number} forwardImpulse + */ + this.forwardImpulse = 0; + + /** + * The result from raycasting + * @property {RaycastResult} raycastResult + */ + this.raycastResult = new RaycastResult(); + + /** + * Wheel world transform + * @property {Transform} worldTransform + */ + this.worldTransform = new Transform(); + + /** + * @property {boolean} isInContact + */ + this.isInContact = false; +} + +var chassis_velocity_at_contactPoint = new Vec3(); +var relpos = new Vec3(); +var chassis_velocity_at_contactPoint = new Vec3(); +WheelInfo.prototype.updateWheel = function(chassis){ + var raycastResult = this.raycastResult; + + if (this.isInContact){ + var project= raycastResult.hitNormalWorld.dot(raycastResult.directionWorld); + raycastResult.hitPointWorld.vsub(chassis.position, relpos); + chassis.getVelocityAtWorldPoint(relpos, chassis_velocity_at_contactPoint); + var projVel = raycastResult.hitNormalWorld.dot( chassis_velocity_at_contactPoint ); + if (project >= -0.1) { + this.suspensionRelativeVelocity = 0.0; + this.clippedInvContactDotSuspension = 1.0 / 0.1; + } else { + var inv = -1 / project; + this.suspensionRelativeVelocity = projVel * inv; + this.clippedInvContactDotSuspension = inv; + } + + } else { + // Not in contact : position wheel in a nice (rest length) position + raycastResult.suspensionLength = this.suspensionRestLength; + this.suspensionRelativeVelocity = 0.0; + raycastResult.directionWorld.scale(-1, raycastResult.hitNormalWorld); + this.clippedInvContactDotSuspension = 1.0; + } +}; +},{"../collision/RaycastResult":10,"../math/Transform":29,"../math/Vec3":30,"../utils/Utils":53}],37:[function(_dereq_,module,exports){ +module.exports = Box; + +var Shape = _dereq_('./Shape'); +var Vec3 = _dereq_('../math/Vec3'); +var ConvexPolyhedron = _dereq_('./ConvexPolyhedron'); + +/** + * A 3d box shape. + * @class Box + * @constructor + * @param {Vec3} halfExtents + * @author schteppe + * @extends Shape + */ +function Box(halfExtents){ + Shape.call(this); + + this.type = Shape.types.BOX; + + /** + * @property halfExtents + * @type {Vec3} + */ + this.halfExtents = halfExtents; + + /** + * Used by the contact generator to make contacts with other convex polyhedra for example + * @property convexPolyhedronRepresentation + * @type {ConvexPolyhedron} + */ + this.convexPolyhedronRepresentation = null; + + this.updateConvexPolyhedronRepresentation(); + this.updateBoundingSphereRadius(); +} +Box.prototype = new Shape(); +Box.prototype.constructor = Box; + +/** + * Updates the local convex polyhedron representation used for some collisions. + * @method updateConvexPolyhedronRepresentation + */ +Box.prototype.updateConvexPolyhedronRepresentation = function(){ + var sx = this.halfExtents.x; + var sy = this.halfExtents.y; + var sz = this.halfExtents.z; + var V = Vec3; + + var vertices = [ + new V(-sx,-sy,-sz), + new V( sx,-sy,-sz), + new V( sx, sy,-sz), + new V(-sx, sy,-sz), + new V(-sx,-sy, sz), + new V( sx,-sy, sz), + new V( sx, sy, sz), + new V(-sx, sy, sz) + ]; + + var indices = [ + [3,2,1,0], // -z + [4,5,6,7], // +z + [5,4,0,1], // -y + [2,3,7,6], // +y + [0,4,7,3], // -x + [1,2,6,5], // +x + ]; + + var axes = [ + new V(0, 0, 1), + new V(0, 1, 0), + new V(1, 0, 0) + ]; + + var h = new ConvexPolyhedron(vertices, indices); + this.convexPolyhedronRepresentation = h; + h.material = this.material; +}; + +/** + * @method calculateLocalInertia + * @param {Number} mass + * @param {Vec3} target + * @return {Vec3} + */ +Box.prototype.calculateLocalInertia = function(mass,target){ + target = target || new Vec3(); + Box.calculateInertia(this.halfExtents, mass, target); + return target; +}; + +Box.calculateInertia = function(halfExtents,mass,target){ + var e = halfExtents; + target.x = 1.0 / 12.0 * mass * ( 2*e.y*2*e.y + 2*e.z*2*e.z ); + target.y = 1.0 / 12.0 * mass * ( 2*e.x*2*e.x + 2*e.z*2*e.z ); + target.z = 1.0 / 12.0 * mass * ( 2*e.y*2*e.y + 2*e.x*2*e.x ); +}; + +/** + * Get the box 6 side normals + * @method getSideNormals + * @param {array} sixTargetVectors An array of 6 vectors, to store the resulting side normals in. + * @param {Quaternion} quat Orientation to apply to the normal vectors. If not provided, the vectors will be in respect to the local frame. + * @return {array} + */ +Box.prototype.getSideNormals = function(sixTargetVectors,quat){ + var sides = sixTargetVectors; + var ex = this.halfExtents; + sides[0].set( ex.x, 0, 0); + sides[1].set( 0, ex.y, 0); + sides[2].set( 0, 0, ex.z); + sides[3].set( -ex.x, 0, 0); + sides[4].set( 0, -ex.y, 0); + sides[5].set( 0, 0, -ex.z); + + if(quat!==undefined){ + for(var i=0; i!==sides.length; i++){ + quat.vmult(sides[i],sides[i]); + } + } + + return sides; +}; + +Box.prototype.volume = function(){ + return 8.0 * this.halfExtents.x * this.halfExtents.y * this.halfExtents.z; +}; + +Box.prototype.updateBoundingSphereRadius = function(){ + this.boundingSphereRadius = this.halfExtents.norm(); +}; + +var worldCornerTempPos = new Vec3(); +var worldCornerTempNeg = new Vec3(); +Box.prototype.forEachWorldCorner = function(pos,quat,callback){ + + var e = this.halfExtents; + var corners = [[ e.x, e.y, e.z], + [ -e.x, e.y, e.z], + [ -e.x, -e.y, e.z], + [ -e.x, -e.y, -e.z], + [ e.x, -e.y, -e.z], + [ e.x, e.y, -e.z], + [ -e.x, e.y, -e.z], + [ e.x, -e.y, e.z]]; + for(var i=0; i max.x){ + max.x = x; + } + if(y > max.y){ + max.y = y; + } + if(z > max.z){ + max.z = z; + } + + if(x < min.x){ + min.x = x; + } + if(y < min.y){ + min.y = y; + } + if(z < min.z){ + min.z = z; + } + } + + // Get each axis max + // min.set(Infinity,Infinity,Infinity); + // max.set(-Infinity,-Infinity,-Infinity); + // this.forEachWorldCorner(pos,quat,function(x,y,z){ + // if(x > max.x){ + // max.x = x; + // } + // if(y > max.y){ + // max.y = y; + // } + // if(z > max.z){ + // max.z = z; + // } + + // if(x < min.x){ + // min.x = x; + // } + // if(y < min.y){ + // min.y = y; + // } + // if(z < min.z){ + // min.z = z; + // } + // }); +}; + +},{"../math/Vec3":30,"./ConvexPolyhedron":38,"./Shape":43}],38:[function(_dereq_,module,exports){ +module.exports = ConvexPolyhedron; + +var Shape = _dereq_('./Shape'); +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var Transform = _dereq_('../math/Transform'); + +/** + * A set of polygons describing a convex shape. + * @class ConvexPolyhedron + * @constructor + * @extends Shape + * @description The shape MUST be convex for the code to work properly. No polygons may be coplanar (contained + * in the same 3D plane), instead these should be merged into one polygon. + * + * @param {array} points An array of Vec3's + * @param {array} faces Array of integer arrays, describing which vertices that is included in each face. + * + * @author qiao / https://github.com/qiao (original author, see https://github.com/qiao/three.js/commit/85026f0c769e4000148a67d45a9e9b9c5108836f) + * @author schteppe / https://github.com/schteppe + * @see http://www.altdevblogaday.com/2011/05/13/contact-generation-between-3d-convex-meshes/ + * @see http://bullet.googlecode.com/svn/trunk/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp + * + * @todo Move the clipping functions to ContactGenerator? + * @todo Automatically merge coplanar polygons in constructor. + */ +function ConvexPolyhedron(points, faces, uniqueAxes) { + var that = this; + Shape.call(this); + this.type = Shape.types.CONVEXPOLYHEDRON; + + /** + * Array of Vec3 + * @property vertices + * @type {Array} + */ + this.vertices = points||[]; + + this.worldVertices = []; // World transformed version of .vertices + this.worldVerticesNeedsUpdate = true; + + /** + * Array of integer arrays, indicating which vertices each face consists of + * @property faces + * @type {Array} + */ + this.faces = faces||[]; + + /** + * Array of Vec3 + * @property faceNormals + * @type {Array} + */ + this.faceNormals = []; + this.computeNormals(); + + this.worldFaceNormalsNeedsUpdate = true; + this.worldFaceNormals = []; // World transformed version of .faceNormals + + /** + * Array of Vec3 + * @property uniqueEdges + * @type {Array} + */ + this.uniqueEdges = []; + + /** + * If given, these locally defined, normalized axes are the only ones being checked when doing separating axis check. + * @property {Array} uniqueAxes + */ + this.uniqueAxes = uniqueAxes ? uniqueAxes.slice() : null; + + this.computeEdges(); + this.updateBoundingSphereRadius(); +} +ConvexPolyhedron.prototype = new Shape(); +ConvexPolyhedron.prototype.constructor = ConvexPolyhedron; + +var computeEdges_tmpEdge = new Vec3(); +/** + * Computes uniqueEdges + * @method computeEdges + */ +ConvexPolyhedron.prototype.computeEdges = function(){ + var faces = this.faces; + var vertices = this.vertices; + var nv = vertices.length; + var edges = this.uniqueEdges; + + edges.length = 0; + + var edge = computeEdges_tmpEdge; + + for(var i=0; i !== faces.length; i++){ + var face = faces[i]; + var numVertices = face.length; + for(var j = 0; j !== numVertices; j++){ + var k = ( j+1 ) % numVertices; + vertices[face[j]].vsub(vertices[face[k]], edge); + edge.normalize(); + var found = false; + for(var p=0; p !== edges.length; p++){ + if (edges[p].almostEquals(edge) || edges[p].almostEquals(edge)){ + found = true; + break; + } + } + + if (!found){ + edges.push(edge.clone()); + } + } + } +}; + +/** + * Compute the normals of the faces. Will reuse existing Vec3 objects in the .faceNormals array if they exist. + * @method computeNormals + */ +ConvexPolyhedron.prototype.computeNormals = function(){ + this.faceNormals.length = this.faces.length; + + // Generate normals + for(var i=0; i dmax){ + dmax = d; + closestFaceB = face; + } + } + var worldVertsB1 = []; + var polyB = hullB.faces[closestFaceB]; + var numVertices = polyB.length; + for(var e0=0; e0=0){ + this.clipFaceAgainstHull(separatingNormal, + posA, + quatA, + worldVertsB1, + minDist, + maxDist, + result); + } +}; + +/** + * Find the separating axis between this hull and another + * @method findSeparatingAxis + * @param {ConvexPolyhedron} hullB + * @param {Vec3} posA + * @param {Quaternion} quatA + * @param {Vec3} posB + * @param {Quaternion} quatB + * @param {Vec3} target The target vector to save the axis in + * @return {bool} Returns false if a separation is found, else true + */ +var fsa_faceANormalWS3 = new Vec3(), + fsa_Worldnormal1 = new Vec3(), + fsa_deltaC = new Vec3(), + fsa_worldEdge0 = new Vec3(), + fsa_worldEdge1 = new Vec3(), + fsa_Cross = new Vec3(); +ConvexPolyhedron.prototype.findSeparatingAxis = function(hullB,posA,quatA,posB,quatB,target, faceListA, faceListB){ + var faceANormalWS3 = fsa_faceANormalWS3, + Worldnormal1 = fsa_Worldnormal1, + deltaC = fsa_deltaC, + worldEdge0 = fsa_worldEdge0, + worldEdge1 = fsa_worldEdge1, + Cross = fsa_Cross; + + var dmin = Number.MAX_VALUE; + var hullA = this; + var curPlaneTests=0; + + if(!hullA.uniqueAxes){ + + var numFacesA = faceListA ? faceListA.length : hullA.faces.length; + + // Test face normals from hullA + for(var i=0; i0.0){ + target.negate(target); + } + + return true; +}; + +var maxminA=[], maxminB=[]; + +/** + * Test separating axis against two hulls. Both hulls are projected onto the axis and the overlap size is returned if there is one. + * @method testSepAxis + * @param {Vec3} axis + * @param {ConvexPolyhedron} hullB + * @param {Vec3} posA + * @param {Quaternion} quatA + * @param {Vec3} posB + * @param {Quaternion} quatB + * @return {number} The overlap depth, or FALSE if no penetration. + */ +ConvexPolyhedron.prototype.testSepAxis = function(axis, hullB, posA, quatA, posB, quatB){ + var hullA=this; + ConvexPolyhedron.project(hullA, axis, posA, quatA, maxminA); + ConvexPolyhedron.project(hullB, axis, posB, quatB, maxminB); + var maxA = maxminA[0]; + var minA = maxminA[1]; + var maxB = maxminB[0]; + var minB = maxminB[1]; + if(maxA= 0, so output intersection + var newv = new Vec3(); + firstVertex.lerp(lastVertex, + n_dot_first / (n_dot_first - n_dot_last), + newv); + outVertices.push(newv); + } + } else { + if(n_dot_last<0){ + // Start >= 0, end < 0 so output intersection and end + var newv = new Vec3(); + firstVertex.lerp(lastVertex, + n_dot_first / (n_dot_first - n_dot_last), + newv); + outVertices.push(newv); + outVertices.push(lastVertex); + } + } + firstVertex = lastVertex; + n_dot_first = n_dot_last; + } + return outVertices; +}; + +// Updates .worldVertices and sets .worldVerticesNeedsUpdate to false. +ConvexPolyhedron.prototype.computeWorldVertices = function(position,quat){ + var N = this.vertices.length; + while(this.worldVertices.length < N){ + this.worldVertices.push( new Vec3() ); + } + + var verts = this.vertices, + worldVerts = this.worldVertices; + for(var i=0; i!==N; i++){ + quat.vmult( verts[i] , worldVerts[i] ); + position.vadd( worldVerts[i] , worldVerts[i] ); + } + + this.worldVerticesNeedsUpdate = false; +}; + +var computeLocalAABB_worldVert = new Vec3(); +ConvexPolyhedron.prototype.computeLocalAABB = function(aabbmin,aabbmax){ + var n = this.vertices.length, + vertices = this.vertices, + worldVert = computeLocalAABB_worldVert; + + aabbmin.set(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE); + aabbmax.set(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE); + + for(var i=0; i aabbmax.x){ + aabbmax.x = v.x; + } + if (v.y < aabbmin.y){ + aabbmin.y = v.y; + } else if(v.y > aabbmax.y){ + aabbmax.y = v.y; + } + if (v.z < aabbmin.z){ + aabbmin.z = v.z; + } else if(v.z > aabbmax.z){ + aabbmax.z = v.z; + } + } +}; + +/** + * Updates .worldVertices and sets .worldVerticesNeedsUpdate to false. + * @method computeWorldFaceNormals + * @param {Quaternion} quat + */ +ConvexPolyhedron.prototype.computeWorldFaceNormals = function(quat){ + var N = this.faceNormals.length; + while(this.worldFaceNormals.length < N){ + this.worldFaceNormals.push( new Vec3() ); + } + + var normals = this.faceNormals, + worldNormals = this.worldFaceNormals; + for(var i=0; i!==N; i++){ + quat.vmult( normals[i] , worldNormals[i] ); + } + + this.worldFaceNormalsNeedsUpdate = false; +}; + +/** + * @method updateBoundingSphereRadius + */ +ConvexPolyhedron.prototype.updateBoundingSphereRadius = function(){ + // Assume points are distributed with local (0,0,0) as center + var max2 = 0; + var verts = this.vertices; + for(var i=0, N=verts.length; i!==N; i++) { + var norm2 = verts[i].norm2(); + if(norm2 > max2){ + max2 = norm2; + } + } + this.boundingSphereRadius = Math.sqrt(max2); +}; + +var tempWorldVertex = new Vec3(); + +/** + * @method calculateWorldAABB + * @param {Vec3} pos + * @param {Quaternion} quat + * @param {Vec3} min + * @param {Vec3} max + */ +ConvexPolyhedron.prototype.calculateWorldAABB = function(pos,quat,min,max){ + var n = this.vertices.length, verts = this.vertices; + var minx,miny,minz,maxx,maxy,maxz; + for(var i=0; i maxx || maxx===undefined){ + maxx = v.x; + } + + if (v.y < miny || miny===undefined){ + miny = v.y; + } else if(v.y > maxy || maxy===undefined){ + maxy = v.y; + } + + if (v.z < minz || minz===undefined){ + minz = v.z; + } else if(v.z > maxz || maxz===undefined){ + maxz = v.z; + } + } + min.set(minx,miny,minz); + max.set(maxx,maxy,maxz); +}; + +/** + * Get approximate convex volume + * @method volume + * @return {Number} + */ +ConvexPolyhedron.prototype.volume = function(){ + return 4.0 * Math.PI * this.boundingSphereRadius / 3.0; +}; + +/** + * Get an average of all the vertices positions + * @method getAveragePointLocal + * @param {Vec3} target + * @return {Vec3} + */ +ConvexPolyhedron.prototype.getAveragePointLocal = function(target){ + target = target || new Vec3(); + var n = this.vertices.length, + verts = this.vertices; + for(var i=0; i0) || (r1>0 && r2<0)){ + return false; // Encountered some other sign. Exit. + } else { + } + } + + // If we got here, all dot products were of the same sign. + return positiveResult ? 1 : -1; +}; + +/** + * Get max and min dot product of a convex hull at position (pos,quat) projected onto an axis. Results are saved in the array maxmin. + * @static + * @method project + * @param {ConvexPolyhedron} hull + * @param {Vec3} axis + * @param {Vec3} pos + * @param {Quaternion} quat + * @param {array} result result[0] and result[1] will be set to maximum and minimum, respectively. + */ +var project_worldVertex = new Vec3(); +var project_localAxis = new Vec3(); +var project_localOrigin = new Vec3(); +ConvexPolyhedron.project = function(hull, axis, pos, quat, result){ + var n = hull.vertices.length, + worldVertex = project_worldVertex, + localAxis = project_localAxis, + max = 0, + min = 0, + localOrigin = project_localOrigin, + vs = hull.vertices; + + localOrigin.setZero(); + + // Transform the axis to local + Transform.vectorToLocalFrame(pos, quat, axis, localAxis); + Transform.pointToLocalFrame(pos, quat, localOrigin, localOrigin); + var add = localOrigin.dot(localAxis); + + min = max = vs[0].dot(localAxis); + + for(var i = 1; i < n; i++){ + var val = vs[i].dot(localAxis); + + if(val > max){ + max = val; + } + + if(val < min){ + min = val; + } + } + + min -= add; + max -= add; + + if(min > max){ + // Inconsistent - swap + var temp = min; + min = max; + max = temp; + } + // Output + result[0] = max; + result[1] = min; +}; + +},{"../math/Quaternion":28,"../math/Transform":29,"../math/Vec3":30,"./Shape":43}],39:[function(_dereq_,module,exports){ +module.exports = Cylinder; + +var Shape = _dereq_('./Shape'); +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var ConvexPolyhedron = _dereq_('./ConvexPolyhedron'); + +/** + * @class Cylinder + * @constructor + * @extends ConvexPolyhedron + * @author schteppe / https://github.com/schteppe + * @param {Number} radiusTop + * @param {Number} radiusBottom + * @param {Number} height + * @param {Number} numSegments The number of segments to build the cylinder out of + */ +function Cylinder( radiusTop, radiusBottom, height , numSegments ) { + var N = numSegments, + verts = [], + axes = [], + faces = [], + bottomface = [], + topface = [], + cos = Math.cos, + sin = Math.sin; + + // First bottom point + verts.push(new Vec3(radiusBottom*cos(0), + radiusBottom*sin(0), + -height*0.5)); + bottomface.push(0); + + // First top point + verts.push(new Vec3(radiusTop*cos(0), + radiusTop*sin(0), + height*0.5)); + topface.push(1); + + for(var i=0; i { convex: ..., offset: ... } + // for example: + // _cachedPillars["0_2_1"] + this._cachedPillars = {}; +} +Heightfield.prototype = new Shape(); + +/** + * Call whenever you change the data array. + * @method update + */ +Heightfield.prototype.update = function(){ + this._cachedPillars = {}; +}; + +/** + * Update the .minValue property + * @method updateMinValue + */ +Heightfield.prototype.updateMinValue = function(){ + var data = this.data; + var minValue = data[0][0]; + for(var i=0; i !== data.length; i++){ + for(var j=0; j !== data[i].length; j++){ + var v = data[i][j]; + if(v < minValue){ + minValue = v; + } + } + } + this.minValue = minValue; +}; + +/** + * Update the .maxValue property + * @method updateMaxValue + */ +Heightfield.prototype.updateMaxValue = function(){ + var data = this.data; + var maxValue = data[0][0]; + for(var i=0; i !== data.length; i++){ + for(var j=0; j !== data[i].length; j++){ + var v = data[i][j]; + if(v > maxValue){ + maxValue = v; + } + } + } + this.maxValue = maxValue; +}; + +/** + * Set the height value at an index. Don't forget to update maxValue and minValue after you're done. + * @method setHeightValueAtIndex + * @param {integer} xi + * @param {integer} yi + * @param {number} value + */ +Heightfield.prototype.setHeightValueAtIndex = function(xi, yi, value){ + var data = this.data; + data[xi][yi] = value; + + // Invalidate cache + this.clearCachedConvexTrianglePillar(xi, yi, false); + if(xi > 0){ + this.clearCachedConvexTrianglePillar(xi - 1, yi, true); + this.clearCachedConvexTrianglePillar(xi - 1, yi, false); + } + if(yi > 0){ + this.clearCachedConvexTrianglePillar(xi, yi - 1, true); + this.clearCachedConvexTrianglePillar(xi, yi - 1, false); + } + if(yi > 0 && xi > 0){ + this.clearCachedConvexTrianglePillar(xi - 1, yi - 1, true); + } +}; + +/** + * Get max/min in a rectangle in the matrix data + * @method getRectMinMax + * @param {integer} iMinX + * @param {integer} iMinY + * @param {integer} iMaxX + * @param {integer} iMaxY + * @param {array} [result] An array to store the results in. + * @return {array} The result array, if it was passed in. Minimum will be at position 0 and max at 1. + */ +Heightfield.prototype.getRectMinMax = function (iMinX, iMinY, iMaxX, iMaxY, result) { + result = result || []; + + // Get max and min of the data + var data = this.data, + max = this.minValue; // Set first value + for(var i = iMinX; i <= iMaxX; i++){ + for(var j = iMinY; j <= iMaxY; j++){ + var height = data[i][j]; + if(height > max){ + max = height; + } + } + } + + result[0] = this.minValue; + result[1] = max; +}; + +/** + * Get the index of a local position on the heightfield. The indexes indicate the rectangles, so if your terrain is made of N x N height data points, you will have rectangle indexes ranging from 0 to N-1. + * @method getIndexOfPosition + * @param {number} x + * @param {number} y + * @param {array} result Two-element array + * @param {boolean} clamp If the position should be clamped to the heightfield edge. + * @return {boolean} + */ +Heightfield.prototype.getIndexOfPosition = function (x, y, result, clamp) { + + // Get the index of the data points to test against + var w = this.elementSize; + var data = this.data; + var xi = Math.floor(x / w); + var yi = Math.floor(y / w); + + result[0] = xi; + result[1] = yi; + + if(clamp){ + // Clamp index to edges + if(xi < 0){ xi = 0; } + if(yi < 0){ yi = 0; } + if(xi >= data.length - 1){ xi = data.length - 1; } + if(yi >= data[0].length - 1){ yi = data[0].length - 1; } + } + + // Bail out if we are out of the terrain + if(xi < 0 || yi < 0 || xi >= data.length-1 || yi >= data[0].length-1){ + return false; + } + + return true; +}; + +Heightfield.prototype.getHeightAt = function(x, y, edgeClamp){ + var idx = []; + this.getIndexOfPosition(x, y, idx, edgeClamp); + + // TODO: get upper or lower triangle, then use barycentric interpolation to get the height in the triangle. + var minmax = []; + this.getRectMinMax(idx[0], idx[1] + 1, idx[0], idx[1] + 1, minmax); + + return (minmax[0] + minmax[1]) / 2; // average +}; + +Heightfield.prototype.getCacheConvexTrianglePillarKey = function(xi, yi, getUpperTriangle){ + return xi + '_' + yi + '_' + (getUpperTriangle ? 1 : 0); +}; + +Heightfield.prototype.getCachedConvexTrianglePillar = function(xi, yi, getUpperTriangle){ + return this._cachedPillars[this.getCacheConvexTrianglePillarKey(xi, yi, getUpperTriangle)]; +}; + +Heightfield.prototype.setCachedConvexTrianglePillar = function(xi, yi, getUpperTriangle, convex, offset){ + this._cachedPillars[this.getCacheConvexTrianglePillarKey(xi, yi, getUpperTriangle)] = { + convex: convex, + offset: offset + }; +}; + +Heightfield.prototype.clearCachedConvexTrianglePillar = function(xi, yi, getUpperTriangle){ + delete this._cachedPillars[this.getCacheConvexTrianglePillarKey(xi, yi, getUpperTriangle)]; +}; + +/** + * Get a triangle in the terrain in the form of a triangular convex shape. + * @method getConvexTrianglePillar + * @param {integer} i + * @param {integer} j + * @param {boolean} getUpperTriangle + */ +Heightfield.prototype.getConvexTrianglePillar = function(xi, yi, getUpperTriangle){ + var result = this.pillarConvex; + var offsetResult = this.pillarOffset; + + if(this.cacheEnabled){ + var data = this.getCachedConvexTrianglePillar(xi, yi, getUpperTriangle); + if(data){ + this.pillarConvex = data.convex; + this.pillarOffset = data.offset; + return; + } + + result = new ConvexPolyhedron(); + offsetResult = new Vec3(); + + this.pillarConvex = result; + this.pillarOffset = offsetResult; + } + + var data = this.data; + var elementSize = this.elementSize; + var faces = result.faces; + + // Reuse verts if possible + result.vertices.length = 6; + for (var i = 0; i < 6; i++) { + if(!result.vertices[i]){ + result.vertices[i] = new Vec3(); + } + } + + // Reuse faces if possible + faces.length = 5; + for (var i = 0; i < 5; i++) { + if(!faces[i]){ + faces[i] = []; + } + } + + var verts = result.vertices; + + var h = (Math.min( + data[xi][yi], + data[xi+1][yi], + data[xi][yi+1], + data[xi+1][yi+1] + ) - this.minValue ) / 2 + this.minValue; + + if (!getUpperTriangle) { + + // Center of the triangle pillar - all polygons are given relative to this one + offsetResult.set( + (xi + 0.25) * elementSize, // sort of center of a triangle + (yi + 0.25) * elementSize, + h // vertical center + ); + + // Top triangle verts + verts[0].set( + -0.25 * elementSize, + -0.25 * elementSize, + data[xi][yi] - h + ); + verts[1].set( + 0.75 * elementSize, + -0.25 * elementSize, + data[xi + 1][yi] - h + ); + verts[2].set( + -0.25 * elementSize, + 0.75 * elementSize, + data[xi][yi + 1] - h + ); + + // bottom triangle verts + verts[3].set( + -0.25 * elementSize, + -0.25 * elementSize, + -h-1 + ); + verts[4].set( + 0.75 * elementSize, + -0.25 * elementSize, + -h-1 + ); + verts[5].set( + -0.25 * elementSize, + 0.75 * elementSize, + -h-1 + ); + + // top triangle + faces[0][0] = 0; + faces[0][1] = 1; + faces[0][2] = 2; + + // bottom triangle + faces[1][0] = 5; + faces[1][1] = 4; + faces[1][2] = 3; + + // -x facing quad + faces[2][0] = 0; + faces[2][1] = 2; + faces[2][2] = 5; + faces[2][3] = 3; + + // -y facing quad + faces[3][0] = 1; + faces[3][1] = 0; + faces[3][2] = 3; + faces[3][3] = 4; + + // +xy facing quad + faces[4][0] = 4; + faces[4][1] = 5; + faces[4][2] = 2; + faces[4][3] = 1; + + + } else { + + // Center of the triangle pillar - all polygons are given relative to this one + offsetResult.set( + (xi + 0.75) * elementSize, // sort of center of a triangle + (yi + 0.75) * elementSize, + h // vertical center + ); + + // Top triangle verts + verts[0].set( + 0.25 * elementSize, + 0.25 * elementSize, + data[xi + 1][yi + 1] - h + ); + verts[1].set( + -0.75 * elementSize, + 0.25 * elementSize, + data[xi][yi + 1] - h + ); + verts[2].set( + 0.25 * elementSize, + -0.75 * elementSize, + data[xi + 1][yi] - h + ); + + // bottom triangle verts + verts[3].set( + 0.25 * elementSize, + 0.25 * elementSize, + - h-1 + ); + verts[4].set( + -0.75 * elementSize, + 0.25 * elementSize, + - h-1 + ); + verts[5].set( + 0.25 * elementSize, + -0.75 * elementSize, + - h-1 + ); + + // Top triangle + faces[0][0] = 0; + faces[0][1] = 1; + faces[0][2] = 2; + + // bottom triangle + faces[1][0] = 5; + faces[1][1] = 4; + faces[1][2] = 3; + + // +x facing quad + faces[2][0] = 2; + faces[2][1] = 5; + faces[2][2] = 3; + faces[2][3] = 0; + + // +y facing quad + faces[3][0] = 3; + faces[3][1] = 4; + faces[3][2] = 1; + faces[3][3] = 0; + + // -xy facing quad + faces[4][0] = 1; + faces[4][1] = 4; + faces[4][2] = 5; + faces[4][3] = 2; + } + + result.computeNormals(); + result.computeEdges(); + result.updateBoundingSphereRadius(); + + this.setCachedConvexTrianglePillar(xi, yi, getUpperTriangle, result, offsetResult); +}; + +Heightfield.prototype.calculateLocalInertia = function(mass, target){ + target = target || new Vec3(); + target.set(0, 0, 0); + return target; +}; + +Heightfield.prototype.volume = function(){ + return Number.MAX_VALUE; // The terrain is infinite +}; + +Heightfield.prototype.calculateWorldAABB = function(pos, quat, min, max){ + // TODO: do it properly + min.set(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE); + max.set(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE); +}; + +Heightfield.prototype.updateBoundingSphereRadius = function(){ + // Use the bounding box of the min/max values + var data = this.data, + s = this.elementSize; + this.boundingSphereRadius = new Vec3(data.length * s, data[0].length * s, Math.max(Math.abs(this.maxValue), Math.abs(this.minValue))).norm(); +}; + +},{"../math/Vec3":30,"../utils/Utils":53,"./ConvexPolyhedron":38,"./Shape":43}],41:[function(_dereq_,module,exports){ +module.exports = Particle; + +var Shape = _dereq_('./Shape'); +var Vec3 = _dereq_('../math/Vec3'); + +/** + * Particle shape. + * @class Particle + * @constructor + * @author schteppe + * @extends Shape + */ +function Particle(){ + Shape.call(this); + + this.type = Shape.types.PARTICLE; +} +Particle.prototype = new Shape(); +Particle.prototype.constructor = Particle; + +/** + * @method calculateLocalInertia + * @param {Number} mass + * @param {Vec3} target + * @return {Vec3} + */ +Particle.prototype.calculateLocalInertia = function(mass,target){ + target = target || new Vec3(); + target.set(0, 0, 0); + return target; +}; + +Particle.prototype.volume = function(){ + return 0; +}; + +Particle.prototype.updateBoundingSphereRadius = function(){ + this.boundingSphereRadius = 0; +}; + +Particle.prototype.calculateWorldAABB = function(pos,quat,min,max){ + // Get each axis max + min.copy(pos); + max.copy(pos); +}; + +},{"../math/Vec3":30,"./Shape":43}],42:[function(_dereq_,module,exports){ +module.exports = Plane; + +var Shape = _dereq_('./Shape'); +var Vec3 = _dereq_('../math/Vec3'); + +/** + * A plane, facing in the Z direction. The plane has its surface at z=0 and everything below z=0 is assumed to be solid plane. To make the plane face in some other direction than z, you must put it inside a RigidBody and rotate that body. See the demos. + * @class Plane + * @constructor + * @extends Shape + * @author schteppe + */ +function Plane(){ + Shape.call(this); + this.type = Shape.types.PLANE; + + // World oriented normal + this.worldNormal = new Vec3(); + this.worldNormalNeedsUpdate = true; + + this.boundingSphereRadius = Number.MAX_VALUE; +} +Plane.prototype = new Shape(); +Plane.prototype.constructor = Plane; + +Plane.prototype.computeWorldNormal = function(quat){ + var n = this.worldNormal; + n.set(0,0,1); + quat.vmult(n,n); + this.worldNormalNeedsUpdate = false; +}; + +Plane.prototype.calculateLocalInertia = function(mass,target){ + target = target || new Vec3(); + return target; +}; + +Plane.prototype.volume = function(){ + return Number.MAX_VALUE; // The plane is infinite... +}; + +var tempNormal = new Vec3(); +Plane.prototype.calculateWorldAABB = function(pos, quat, min, max){ + // The plane AABB is infinite, except if the normal is pointing along any axis + tempNormal.set(0,0,1); // Default plane normal is z + quat.vmult(tempNormal,tempNormal); + var maxVal = Number.MAX_VALUE; + min.set(-maxVal, -maxVal, -maxVal); + max.set(maxVal, maxVal, maxVal); + + if(tempNormal.x === 1){ max.x = pos.x; } + if(tempNormal.y === 1){ max.y = pos.y; } + if(tempNormal.z === 1){ max.z = pos.z; } + + if(tempNormal.x === -1){ min.x = pos.x; } + if(tempNormal.y === -1){ min.y = pos.y; } + if(tempNormal.z === -1){ min.z = pos.z; } +}; + +Plane.prototype.updateBoundingSphereRadius = function(){ + this.boundingSphereRadius = Number.MAX_VALUE; +}; +},{"../math/Vec3":30,"./Shape":43}],43:[function(_dereq_,module,exports){ +module.exports = Shape; + +var Shape = _dereq_('./Shape'); +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var Material = _dereq_('../material/Material'); + +/** + * Base class for shapes + * @class Shape + * @constructor + * @author schteppe + * @todo Should have a mechanism for caching bounding sphere radius instead of calculating it each time + */ +function Shape(){ + + /** + * Identifyer of the Shape. + * @property {number} id + */ + this.id = Shape.idCounter++; + + /** + * The type of this shape. Must be set to an int > 0 by subclasses. + * @property type + * @type {Number} + * @see Shape.types + */ + this.type = 0; + + /** + * The local bounding sphere radius of this shape. + * @property {Number} boundingSphereRadius + */ + this.boundingSphereRadius = 0; + + /** + * Whether to produce contact forces when in contact with other bodies. Note that contacts will be generated, but they will be disabled. + * @property {boolean} collisionResponse + */ + this.collisionResponse = true; + + /** + * @property {Material} material + */ + this.material = null; +} +Shape.prototype.constructor = Shape; + +/** + * Computes the bounding sphere radius. The result is stored in the property .boundingSphereRadius + * @method updateBoundingSphereRadius + * @return {Number} + */ +Shape.prototype.updateBoundingSphereRadius = function(){ + throw "computeBoundingSphereRadius() not implemented for shape type "+this.type; +}; + +/** + * Get the volume of this shape + * @method volume + * @return {Number} + */ +Shape.prototype.volume = function(){ + throw "volume() not implemented for shape type "+this.type; +}; + +/** + * Calculates the inertia in the local frame for this shape. + * @method calculateLocalInertia + * @return {Vec3} + * @see http://en.wikipedia.org/wiki/List_of_moments_of_inertia + */ +Shape.prototype.calculateLocalInertia = function(mass,target){ + throw "calculateLocalInertia() not implemented for shape type "+this.type; +}; + +Shape.idCounter = 0; + +/** + * The available shape types. + * @static + * @property types + * @type {Object} + */ +Shape.types = { + SPHERE:1, + PLANE:2, + BOX:4, + COMPOUND:8, + CONVEXPOLYHEDRON:16, + HEIGHTFIELD:32, + PARTICLE:64, + CYLINDER:128, + TRIMESH:256 +}; + + +},{"../material/Material":25,"../math/Quaternion":28,"../math/Vec3":30,"./Shape":43}],44:[function(_dereq_,module,exports){ +module.exports = Sphere; + +var Shape = _dereq_('./Shape'); +var Vec3 = _dereq_('../math/Vec3'); + +/** + * Spherical shape + * @class Sphere + * @constructor + * @extends Shape + * @param {Number} radius The radius of the sphere, a non-negative number. + * @author schteppe / http://github.com/schteppe + */ +function Sphere(radius){ + Shape.call(this); + + /** + * @property {Number} radius + */ + this.radius = radius!==undefined ? Number(radius) : 1.0; + this.type = Shape.types.SPHERE; + + if(this.radius < 0){ + throw new Error('The sphere radius cannot be negative.'); + } + + this.updateBoundingSphereRadius(); +} +Sphere.prototype = new Shape(); +Sphere.prototype.constructor = Sphere; + +Sphere.prototype.calculateLocalInertia = function(mass,target){ + target = target || new Vec3(); + var I = 2.0*mass*this.radius*this.radius/5.0; + target.x = I; + target.y = I; + target.z = I; + return target; +}; + +Sphere.prototype.volume = function(){ + return 4.0 * Math.PI * this.radius / 3.0; +}; + +Sphere.prototype.updateBoundingSphereRadius = function(){ + this.boundingSphereRadius = this.radius; +}; + +Sphere.prototype.calculateWorldAABB = function(pos,quat,min,max){ + var r = this.radius; + var axes = ['x','y','z']; + for(var i=0; i u.x){ + u.x = v.x; + } + + if(v.y < l.y){ + l.y = v.y; + } else if(v.y > u.y){ + u.y = v.y; + } + + if(v.z < l.z){ + l.z = v.z; + } else if(v.z > u.z){ + u.z = v.z; + } + } +}; + + +/** + * Update the .aabb property + * @method updateAABB + */ +Trimesh.prototype.updateAABB = function(){ + this.computeLocalAABB(this.aabb); +}; + +/** + * Will update the .boundingSphereRadius property + * @method updateBoundingSphereRadius + */ +Trimesh.prototype.updateBoundingSphereRadius = function(){ + // Assume points are distributed with local (0,0,0) as center + var max2 = 0; + var vertices = this.vertices; + var v = new Vec3(); + for(var i=0, N=vertices.length / 3; i !== N; i++) { + this.getVertex(i, v); + var norm2 = v.norm2(); + if(norm2 > max2){ + max2 = norm2; + } + } + this.boundingSphereRadius = Math.sqrt(max2); +}; + +var tempWorldVertex = new Vec3(); +var calculateWorldAABB_frame = new Transform(); +var calculateWorldAABB_aabb = new AABB(); + +/** + * @method calculateWorldAABB + * @param {Vec3} pos + * @param {Quaternion} quat + * @param {Vec3} min + * @param {Vec3} max + */ +Trimesh.prototype.calculateWorldAABB = function(pos,quat,min,max){ + /* + var n = this.vertices.length / 3, + verts = this.vertices; + var minx,miny,minz,maxx,maxy,maxz; + + var v = tempWorldVertex; + for(var i=0; i maxx || maxx===undefined){ + maxx = v.x; + } + + if (v.y < miny || miny===undefined){ + miny = v.y; + } else if(v.y > maxy || maxy===undefined){ + maxy = v.y; + } + + if (v.z < minz || minz===undefined){ + minz = v.z; + } else if(v.z > maxz || maxz===undefined){ + maxz = v.z; + } + } + min.set(minx,miny,minz); + max.set(maxx,maxy,maxz); + */ + + // Faster approximation using local AABB + var frame = calculateWorldAABB_frame; + var result = calculateWorldAABB_aabb; + frame.position = pos; + frame.quaternion = quat; + this.aabb.toWorldFrame(frame, result); + min.copy(result.lowerBound); + max.copy(result.upperBound); +}; + +/** + * Get approximate volume + * @method volume + * @return {Number} + */ +Trimesh.prototype.volume = function(){ + return 4.0 * Math.PI * this.boundingSphereRadius / 3.0; +}; + +/** + * Create a Trimesh instance, shaped as a torus. + * @static + * @method createTorus + * @param {number} [radius=1] + * @param {number} [tube=0.5] + * @param {number} [radialSegments=8] + * @param {number} [tubularSegments=6] + * @param {number} [arc=6.283185307179586] + * @return {Trimesh} A torus + */ +Trimesh.createTorus = function (radius, tube, radialSegments, tubularSegments, arc) { + radius = radius || 1; + tube = tube || 0.5; + radialSegments = radialSegments || 8; + tubularSegments = tubularSegments || 6; + arc = arc || Math.PI * 2; + + var vertices = []; + var indices = []; + + for ( var j = 0; j <= radialSegments; j ++ ) { + for ( var i = 0; i <= tubularSegments; i ++ ) { + var u = i / tubularSegments * arc; + var v = j / radialSegments * Math.PI * 2; + + var x = ( radius + tube * Math.cos( v ) ) * Math.cos( u ); + var y = ( radius + tube * Math.cos( v ) ) * Math.sin( u ); + var z = tube * Math.sin( v ); + + vertices.push( x, y, z ); + } + } + + for ( var j = 1; j <= radialSegments; j ++ ) { + for ( var i = 1; i <= tubularSegments; i ++ ) { + var a = ( tubularSegments + 1 ) * j + i - 1; + var b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1; + var c = ( tubularSegments + 1 ) * ( j - 1 ) + i; + var d = ( tubularSegments + 1 ) * j + i; + + indices.push(a, b, d); + indices.push(b, c, d); + } + } + + return new Trimesh(vertices, indices); +}; + +},{"../collision/AABB":3,"../math/Quaternion":28,"../math/Transform":29,"../math/Vec3":30,"../utils/Octree":50,"./Shape":43}],46:[function(_dereq_,module,exports){ +module.exports = GSSolver; + +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var Solver = _dereq_('./Solver'); + +/** + * Constraint equation Gauss-Seidel solver. + * @class GSSolver + * @constructor + * @todo The spook parameters should be specified for each constraint, not globally. + * @author schteppe / https://github.com/schteppe + * @see https://www8.cs.umu.se/kurser/5DV058/VT09/lectures/spooknotes.pdf + * @extends Solver + */ +function GSSolver(){ + Solver.call(this); + + /** + * The number of solver iterations determines quality of the constraints in the world. The more iterations, the more correct simulation. More iterations need more computations though. If you have a large gravity force in your world, you will need more iterations. + * @property iterations + * @type {Number} + * @todo write more about solver and iterations in the wiki + */ + this.iterations = 10; + + /** + * When tolerance is reached, the system is assumed to be converged. + * @property tolerance + * @type {Number} + */ + this.tolerance = 1e-7; +} +GSSolver.prototype = new Solver(); + +var GSSolver_solve_lambda = []; // Just temporary number holders that we want to reuse each solve. +var GSSolver_solve_invCs = []; +var GSSolver_solve_Bs = []; +GSSolver.prototype.solve = function(dt,world){ + var iter = 0, + maxIter = this.iterations, + tolSquared = this.tolerance*this.tolerance, + equations = this.equations, + Neq = equations.length, + bodies = world.bodies, + Nbodies = bodies.length, + h = dt, + q, B, invC, deltalambda, deltalambdaTot, GWlambda, lambdaj; + + // Update solve mass + if(Neq !== 0){ + for(var i=0; i!==Nbodies; i++){ + bodies[i].updateSolveMassProperties(); + } + } + + // Things that does not change during iteration can be computed once + var invCs = GSSolver_solve_invCs, + Bs = GSSolver_solve_Bs, + lambda = GSSolver_solve_lambda; + invCs.length = Neq; + Bs.length = Neq; + lambda.length = Neq; + for(var i=0; i!==Neq; i++){ + var c = equations[i]; + lambda[i] = 0.0; + Bs[i] = c.computeB(h); + invCs[i] = 1.0 / c.computeC(); + } + + if(Neq !== 0){ + + // Reset vlambda + for(var i=0; i!==Nbodies; i++){ + var b=bodies[i], + vlambda=b.vlambda, + wlambda=b.wlambda; + vlambda.set(0,0,0); + if(wlambda){ + wlambda.set(0,0,0); + } + } + + // Iterate over equations + for(iter=0; iter!==maxIter; iter++){ + + // Accumulate the total error for each iteration. + deltalambdaTot = 0.0; + + for(var j=0; j!==Neq; j++){ + + var c = equations[j]; + + // Compute iteration + B = Bs[j]; + invC = invCs[j]; + lambdaj = lambda[j]; + GWlambda = c.computeGWlambda(); + deltalambda = invC * ( B - GWlambda - c.eps * lambdaj ); + + // Clamp if we are not within the min/max interval + if(lambdaj + deltalambda < c.minForce){ + deltalambda = c.minForce - lambdaj; + } else if(lambdaj + deltalambda > c.maxForce){ + deltalambda = c.maxForce - lambdaj; + } + lambda[j] += deltalambda; + + deltalambdaTot += deltalambda > 0.0 ? deltalambda : -deltalambda; // abs(deltalambda) + + c.addToWlambda(deltalambda); + } + + // If the total error is small enough - stop iterate + if(deltalambdaTot*deltalambdaTot < tolSquared){ + break; + } + } + + // Add result to velocity + for(var i=0; i!==Nbodies; i++){ + var b=bodies[i], + v=b.velocity, + w=b.angularVelocity; + v.vadd(b.vlambda, v); + if(w){ + w.vadd(b.wlambda, w); + } + } + } + + return iter; +}; + +},{"../math/Quaternion":28,"../math/Vec3":30,"./Solver":47}],47:[function(_dereq_,module,exports){ +module.exports = Solver; + +/** + * Constraint equation solver base class. + * @class Solver + * @constructor + * @author schteppe / https://github.com/schteppe + */ +function Solver(){ + /** + * All equations to be solved + * @property {Array} equations + */ + this.equations = []; +} + +/** + * Should be implemented in subclasses! + * @method solve + * @param {Number} dt + * @param {World} world + */ +Solver.prototype.solve = function(dt,world){ + // Should return the number of iterations done! + return 0; +}; + +/** + * Add an equation + * @method addEquation + * @param {Equation} eq + */ +Solver.prototype.addEquation = function(eq){ + if (eq.enabled) { + this.equations.push(eq); + } +}; + +/** + * Remove an equation + * @method removeEquation + * @param {Equation} eq + */ +Solver.prototype.removeEquation = function(eq){ + var eqs = this.equations; + var i = eqs.indexOf(eq); + if(i !== -1){ + eqs.splice(i,1); + } +}; + +/** + * Add all equations + * @method removeAllEquations + */ +Solver.prototype.removeAllEquations = function(){ + this.equations.length = 0; +}; + + +},{}],48:[function(_dereq_,module,exports){ +module.exports = SplitSolver; + +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var Solver = _dereq_('./Solver'); +var Body = _dereq_('../objects/Body'); + +/** + * Splits the equations into islands and solves them independently. Can improve performance. + * @class SplitSolver + * @constructor + * @extends Solver + * @param {Solver} subsolver + */ +function SplitSolver(subsolver){ + Solver.call(this); + this.iterations = 10; + this.tolerance = 1e-7; + this.subsolver = subsolver; + this.nodes = []; + this.nodePool = []; + + // Create needed nodes, reuse if possible + while(this.nodePool.length < 128){ + this.nodePool.push(this.createNode()); + } +} +SplitSolver.prototype = new Solver(); + +// Returns the number of subsystems +var SplitSolver_solve_nodes = []; // All allocated node objects +var SplitSolver_solve_nodePool = []; // All allocated node objects +var SplitSolver_solve_eqs = []; // Temp array +var SplitSolver_solve_bds = []; // Temp array +var SplitSolver_solve_dummyWorld = {bodies:[]}; // Temp object + +var STATIC = Body.STATIC; +function getUnvisitedNode(nodes){ + var Nnodes = nodes.length; + for(var i=0; i!==Nnodes; i++){ + var node = nodes[i]; + if(!node.visited && !(node.body.type & STATIC)){ + return node; + } + } + return false; +} + +var queue = []; +function bfs(root,visitFunc,bds,eqs){ + queue.push(root); + root.visited = true; + visitFunc(root,bds,eqs); + while(queue.length) { + var node = queue.pop(); + // Loop over unvisited child nodes + var child; + while((child = getUnvisitedNode(node.children))) { + child.visited = true; + visitFunc(child,bds,eqs); + queue.push(child); + } + } +} + +function visitFunc(node,bds,eqs){ + bds.push(node.body); + var Neqs = node.eqs.length; + for(var i=0; i!==Neqs; i++){ + var eq = node.eqs[i]; + if(eqs.indexOf(eq) === -1){ + eqs.push(eq); + } + } +} + +SplitSolver.prototype.createNode = function(){ + return { body:null, children:[], eqs:[], visited:false }; +}; + +/** + * Solve the subsystems + * @method solve + * @param {Number} dt + * @param {World} world + */ +SplitSolver.prototype.solve = function(dt,world){ + var nodes=SplitSolver_solve_nodes, + nodePool=this.nodePool, + bodies=world.bodies, + equations=this.equations, + Neq=equations.length, + Nbodies=bodies.length, + subsolver=this.subsolver; + + // Create needed nodes, reuse if possible + while(nodePool.length < Nbodies){ + nodePool.push(this.createNode()); + } + nodes.length = Nbodies; + for (var i = 0; i < Nbodies; i++) { + nodes[i] = nodePool[i]; + } + + // Reset node values + for(var i=0; i!==Nbodies; i++){ + var node = nodes[i]; + node.body = bodies[i]; + node.children.length = 0; + node.eqs.length = 0; + node.visited = false; + } + for(var k=0; k!==Neq; k++){ + var eq=equations[k], + i=bodies.indexOf(eq.bi), + j=bodies.indexOf(eq.bj), + ni=nodes[i], + nj=nodes[j]; + ni.children.push(nj); + ni.eqs.push(eq); + nj.children.push(ni); + nj.eqs.push(eq); + } + + var child, n=0, eqs=SplitSolver_solve_eqs; + + subsolver.tolerance = this.tolerance; + subsolver.iterations = this.iterations; + + var dummyWorld = SplitSolver_solve_dummyWorld; + while((child = getUnvisitedNode(nodes))){ + eqs.length = 0; + dummyWorld.bodies.length = 0; + bfs(child, visitFunc, dummyWorld.bodies, eqs); + + var Neqs = eqs.length; + + eqs = eqs.sort(sortById); + + for(var i=0; i!==Neqs; i++){ + subsolver.addEquation(eqs[i]); + } + + var iter = subsolver.solve(dt,dummyWorld); + subsolver.removeAllEquations(); + n++; + } + + return n; +}; + +function sortById(a, b){ + return b.id - a.id; +} +},{"../math/Quaternion":28,"../math/Vec3":30,"../objects/Body":31,"./Solver":47}],49:[function(_dereq_,module,exports){ +/** + * Base class for objects that dispatches events. + * @class EventTarget + * @constructor + */ +var EventTarget = function () { + +}; + +module.exports = EventTarget; + +EventTarget.prototype = { + constructor: EventTarget, + + /** + * Add an event listener + * @method addEventListener + * @param {String} type + * @param {Function} listener + * @return {EventTarget} The self object, for chainability. + */ + addEventListener: function ( type, listener ) { + if ( this._listeners === undefined ){ this._listeners = {}; } + var listeners = this._listeners; + if ( listeners[ type ] === undefined ) { + listeners[ type ] = []; + } + if ( listeners[ type ].indexOf( listener ) === - 1 ) { + listeners[ type ].push( listener ); + } + return this; + }, + + /** + * Check if an event listener is added + * @method hasEventListener + * @param {String} type + * @param {Function} listener + * @return {Boolean} + */ + hasEventListener: function ( type, listener ) { + if ( this._listeners === undefined ){ return false; } + var listeners = this._listeners; + if ( listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1 ) { + return true; + } + return false; + }, + + /** + * Remove an event listener + * @method removeEventListener + * @param {String} type + * @param {Function} listener + * @return {EventTarget} The self object, for chainability. + */ + removeEventListener: function ( type, listener ) { + if ( this._listeners === undefined ){ return this; } + var listeners = this._listeners; + if ( listeners[type] === undefined ){ return this; } + var index = listeners[ type ].indexOf( listener ); + if ( index !== - 1 ) { + listeners[ type ].splice( index, 1 ); + } + return this; + }, + + /** + * Emit an event. + * @method dispatchEvent + * @param {Object} event + * @param {String} event.type + * @return {EventTarget} The self object, for chainability. + */ + dispatchEvent: function ( event ) { + if ( this._listeners === undefined ){ return this; } + var listeners = this._listeners; + var listenerArray = listeners[ event.type ]; + if ( listenerArray !== undefined ) { + event.target = this; + for ( var i = 0, l = listenerArray.length; i < l; i ++ ) { + listenerArray[ i ].call( this, event ); + } + } + return this; + } +}; + +},{}],50:[function(_dereq_,module,exports){ +var AABB = _dereq_('../collision/AABB'); +var Vec3 = _dereq_('../math/Vec3'); + +module.exports = Octree; + +/** + * @class OctreeNode + * @param {object} [options] + * @param {Octree} [options.root] + * @param {AABB} [options.aabb] + */ +function OctreeNode(options){ + options = options || {}; + + /** + * The root node + * @property {OctreeNode} root + */ + this.root = options.root || null; + + /** + * Boundary of this node + * @property {AABB} aabb + */ + this.aabb = options.aabb ? options.aabb.clone() : new AABB(); + + /** + * Contained data at the current node level. + * @property {Array} data + */ + this.data = []; + + /** + * Children to this node + * @property {Array} children + */ + this.children = []; +} + +/** + * @class Octree + * @param {AABB} aabb The total AABB of the tree + * @param {object} [options] + * @param {number} [options.maxDepth=8] + * @extends OctreeNode + */ +function Octree(aabb, options){ + options = options || {}; + options.root = null; + options.aabb = aabb; + OctreeNode.call(this, options); + + /** + * Maximum subdivision depth + * @property {number} maxDepth + */ + this.maxDepth = typeof(options.maxDepth) !== 'undefined' ? options.maxDepth : 8; +} +Octree.prototype = new OctreeNode(); + +OctreeNode.prototype.reset = function(aabb, options){ + this.children.length = this.data.length = 0; +}; + +/** + * Insert data into this node + * @method insert + * @param {AABB} aabb + * @param {object} elementData + * @return {boolean} True if successful, otherwise false + */ +OctreeNode.prototype.insert = function(aabb, elementData, level){ + var nodeData = this.data; + level = level || 0; + + // Ignore objects that do not belong in this node + if (!this.aabb.contains(aabb)){ + return false; // object cannot be added + } + + var children = this.children; + + if(level < (this.maxDepth || this.root.maxDepth)){ + // Subdivide if there are no children yet + var subdivided = false; + if (!children.length){ + this.subdivide(); + subdivided = true; + } + + // add to whichever node will accept it + for (var i = 0; i !== 8; i++) { + if (children[i].insert(aabb, elementData, level + 1)){ + return true; + } + } + + if(subdivided){ + // No children accepted! Might as well just remove em since they contain none + children.length = 0; + } + } + + // Too deep, or children didnt want it. add it in current node + nodeData.push(elementData); + + return true; +}; + +var halfDiagonal = new Vec3(); + +/** + * Create 8 equally sized children nodes and put them in the .children array. + * @method subdivide + */ +OctreeNode.prototype.subdivide = function() { + var aabb = this.aabb; + var l = aabb.lowerBound; + var u = aabb.upperBound; + + var children = this.children; + + children.push( + new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(0,0,0) }) }), + new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(1,0,0) }) }), + new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(1,1,0) }) }), + new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(1,1,1) }) }), + new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(0,1,1) }) }), + new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(0,0,1) }) }), + new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(1,0,1) }) }), + new OctreeNode({ aabb: new AABB({ lowerBound: new Vec3(0,1,0) }) }) + ); + + u.vsub(l, halfDiagonal); + halfDiagonal.scale(0.5, halfDiagonal); + + var root = this.root || this; + + for (var i = 0; i !== 8; i++) { + var child = children[i]; + + // Set current node as root + child.root = root; + + // Compute bounds + var lowerBound = child.aabb.lowerBound; + lowerBound.x *= halfDiagonal.x; + lowerBound.y *= halfDiagonal.y; + lowerBound.z *= halfDiagonal.z; + + lowerBound.vadd(l, lowerBound); + + // Upper bound is always lower bound + halfDiagonal + lowerBound.vadd(halfDiagonal, child.aabb.upperBound); + } +}; + +/** + * Get all data, potentially within an AABB + * @method aabbQuery + * @param {AABB} aabb + * @param {array} result + * @return {array} The "result" object + */ +OctreeNode.prototype.aabbQuery = function(aabb, result) { + + var nodeData = this.data; + + // abort if the range does not intersect this node + // if (!this.aabb.overlaps(aabb)){ + // return result; + // } + + // Add objects at this level + // Array.prototype.push.apply(result, nodeData); + + // Add child data + // @todo unwrap recursion into a queue / loop, that's faster in JS + var children = this.children; + + + // for (var i = 0, N = this.children.length; i !== N; i++) { + // children[i].aabbQuery(aabb, result); + // } + + var queue = [this]; + while (queue.length) { + var node = queue.pop(); + if (node.aabb.overlaps(aabb)){ + Array.prototype.push.apply(result, node.data); + } + Array.prototype.push.apply(queue, node.children); + } + + return result; +}; + +var tmpAABB = new AABB(); + +/** + * Get all data, potentially intersected by a ray. + * @method rayQuery + * @param {Ray} ray + * @param {Transform} treeTransform + * @param {array} result + * @return {array} The "result" object + */ +OctreeNode.prototype.rayQuery = function(ray, treeTransform, result) { + + // Use aabb query for now. + // @todo implement real ray query which needs less lookups + ray.getAABB(tmpAABB); + tmpAABB.toLocalFrame(treeTransform, tmpAABB); + this.aabbQuery(tmpAABB, result); + + return result; +}; + +/** + * @method removeEmptyNodes + */ +OctreeNode.prototype.removeEmptyNodes = function() { + var queue = [this]; + while (queue.length) { + var node = queue.pop(); + for (var i = node.children.length - 1; i >= 0; i--) { + if(!node.children[i].data.length){ + node.children.splice(i, 1); + } + } + Array.prototype.push.apply(queue, node.children); + } +}; + +},{"../collision/AABB":3,"../math/Vec3":30}],51:[function(_dereq_,module,exports){ +module.exports = Pool; + +/** + * For pooling objects that can be reused. + * @class Pool + * @constructor + */ +function Pool(){ + /** + * The pooled objects + * @property {Array} objects + */ + this.objects = []; + + /** + * Constructor of the objects + * @property {mixed} type + */ + this.type = Object; +} + +/** + * Release an object after use + * @method release + * @param {Object} obj + */ +Pool.prototype.release = function(){ + var Nargs = arguments.length; + for(var i=0; i!==Nargs; i++){ + this.objects.push(arguments[i]); + } +}; + +/** + * Get an object + * @method get + * @return {mixed} + */ +Pool.prototype.get = function(){ + if(this.objects.length===0){ + return this.constructObject(); + } else { + return this.objects.pop(); + } +}; + +/** + * Construct an object. Should be implmented in each subclass. + * @method constructObject + * @return {mixed} + */ +Pool.prototype.constructObject = function(){ + throw new Error("constructObject() not implemented in this Pool subclass yet!"); +}; + +},{}],52:[function(_dereq_,module,exports){ +module.exports = TupleDictionary; + +/** + * @class TupleDictionary + * @constructor + */ +function TupleDictionary() { + + /** + * The data storage + * @property data + * @type {Object} + */ + this.data = { keys:[] }; +} + +/** + * @method get + * @param {Number} i + * @param {Number} j + * @return {Number} + */ +TupleDictionary.prototype.get = function(i, j) { + if (i > j) { + // swap + var temp = j; + j = i; + i = temp; + } + return this.data[i+'-'+j]; +}; + +/** + * @method set + * @param {Number} i + * @param {Number} j + * @param {Number} value + */ +TupleDictionary.prototype.set = function(i, j, value) { + if (i > j) { + var temp = j; + j = i; + i = temp; + } + var key = i+'-'+j; + + // Check if key already exists + if(!this.get(i,j)){ + this.data.keys.push(key); + } + + this.data[key] = value; +}; + +/** + * @method reset + */ +TupleDictionary.prototype.reset = function() { + var data = this.data, + keys = data.keys; + while(keys.length > 0){ + var key = keys.pop(); + delete data[key]; + } +}; + +},{}],53:[function(_dereq_,module,exports){ +function Utils(){} + +module.exports = Utils; + +/** + * Extend an options object with default values. + * @static + * @method defaults + * @param {object} options The options object. May be falsy: in this case, a new object is created and returned. + * @param {object} defaults An object containing default values. + * @return {object} The modified options object. + */ +Utils.defaults = function(options, defaults){ + options = options || {}; + + for(var key in defaults){ + if(!(key in options)){ + options[key] = defaults[key]; + } + } + + return options; +}; + +},{}],54:[function(_dereq_,module,exports){ +module.exports = Vec3Pool; + +var Vec3 = _dereq_('../math/Vec3'); +var Pool = _dereq_('./Pool'); + +/** + * @class Vec3Pool + * @constructor + * @extends Pool + */ +function Vec3Pool(){ + Pool.call(this); + this.type = Vec3; +} +Vec3Pool.prototype = new Pool(); + +/** + * Construct a vector + * @method constructObject + * @return {Vec3} + */ +Vec3Pool.prototype.constructObject = function(){ + return new Vec3(); +}; + +},{"../math/Vec3":30,"./Pool":51}],55:[function(_dereq_,module,exports){ +module.exports = Narrowphase; + +var AABB = _dereq_('../collision/AABB'); +var Shape = _dereq_('../shapes/Shape'); +var Ray = _dereq_('../collision/Ray'); +var Vec3 = _dereq_('../math/Vec3'); +var Transform = _dereq_('../math/Transform'); +var ConvexPolyhedron = _dereq_('../shapes/ConvexPolyhedron'); +var Quaternion = _dereq_('../math/Quaternion'); +var Solver = _dereq_('../solver/Solver'); +var Vec3Pool = _dereq_('../utils/Vec3Pool'); +var ContactEquation = _dereq_('../equations/ContactEquation'); +var FrictionEquation = _dereq_('../equations/FrictionEquation'); + +/** + * Helper class for the World. Generates ContactEquations. + * @class Narrowphase + * @constructor + * @todo Sphere-ConvexPolyhedron contacts + * @todo Contact reduction + * @todo should move methods to prototype + */ +function Narrowphase(world){ + + /** + * Internal storage of pooled contact points. + * @property {Array} contactPointPool + */ + this.contactPointPool = []; + + this.frictionEquationPool = []; + + this.result = []; + this.frictionResult = []; + + /** + * Pooled vectors. + * @property {Vec3Pool} v3pool + */ + this.v3pool = new Vec3Pool(); + + this.world = world; + this.currentContactMaterial = null; + + /** + * @property {Boolean} enableFrictionReduction + */ + this.enableFrictionReduction = false; +} + +/** + * Make a contact object, by using the internal pool or creating a new one. + * @method createContactEquation + * @return {ContactEquation} + */ +Narrowphase.prototype.createContactEquation = function(bi, bj, si, sj, rsi, rsj){ + var c; + if(this.contactPointPool.length){ + c = this.contactPointPool.pop(); + c.bi = bi; + c.bj = bj; + } else { + c = new ContactEquation(bi, bj); + } + + c.enabled = bi.collisionResponse && bj.collisionResponse && si.collisionResponse && sj.collisionResponse; + + var cm = this.currentContactMaterial; + + c.restitution = cm.restitution; + + c.setSpookParams( + cm.contactEquationStiffness, + cm.contactEquationRelaxation, + this.world.dt + ); + + var matA = si.material || bi.material; + var matB = sj.material || bj.material; + if(matA && matB && matA.restitution >= 0 && matB.restitution >= 0){ + c.restitution = matA.restitution * matB.restitution; + } + + c.si = rsi || si; + c.sj = rsj || sj; + + return c; +}; + +Narrowphase.prototype.createFrictionEquationsFromContact = function(contactEquation, outArray){ + var bodyA = contactEquation.bi; + var bodyB = contactEquation.bj; + var shapeA = contactEquation.si; + var shapeB = contactEquation.sj; + + var world = this.world; + var cm = this.currentContactMaterial; + + // If friction or restitution were specified in the material, use them + var friction = cm.friction; + var matA = shapeA.material || bodyA.material; + var matB = shapeB.material || bodyB.material; + if(matA && matB && matA.friction >= 0 && matB.friction >= 0){ + friction = matA.friction * matB.friction; + } + + if(friction > 0){ + + // Create 2 tangent equations + var mug = friction * world.gravity.length(); + var reducedMass = (bodyA.invMass + bodyB.invMass); + if(reducedMass > 0){ + reducedMass = 1/reducedMass; + } + var pool = this.frictionEquationPool; + var c1 = pool.length ? pool.pop() : new FrictionEquation(bodyA,bodyB,mug*reducedMass); + var c2 = pool.length ? pool.pop() : new FrictionEquation(bodyA,bodyB,mug*reducedMass); + + c1.bi = c2.bi = bodyA; + c1.bj = c2.bj = bodyB; + c1.minForce = c2.minForce = -mug*reducedMass; + c1.maxForce = c2.maxForce = mug*reducedMass; + + // Copy over the relative vectors + c1.ri.copy(contactEquation.ri); + c1.rj.copy(contactEquation.rj); + c2.ri.copy(contactEquation.ri); + c2.rj.copy(contactEquation.rj); + + // Construct tangents + contactEquation.ni.tangents(c1.t, c2.t); + + // Set spook params + c1.setSpookParams(cm.frictionEquationStiffness, cm.frictionEquationRelaxation, world.dt); + c2.setSpookParams(cm.frictionEquationStiffness, cm.frictionEquationRelaxation, world.dt); + + c1.enabled = c2.enabled = contactEquation.enabled; + + outArray.push(c1, c2); + + return true; + } + + return false; +}; + +var averageNormal = new Vec3(); +var averageContactPointA = new Vec3(); +var averageContactPointB = new Vec3(); + +// Take the average N latest contact point on the plane. +Narrowphase.prototype.createFrictionFromAverage = function(numContacts){ + // The last contactEquation + var c = this.result[this.result.length - 1]; + + // Create the result: two "average" friction equations + if (!this.createFrictionEquationsFromContact(c, this.frictionResult) || numContacts === 1) { + return; + } + + var f1 = this.frictionResult[this.frictionResult.length - 2]; + var f2 = this.frictionResult[this.frictionResult.length - 1]; + + averageNormal.setZero(); + averageContactPointA.setZero(); + averageContactPointB.setZero(); + + var bodyA = c.bi; + var bodyB = c.bj; + for(var i=0; i!==numContacts; i++){ + c = this.result[this.result.length - 1 - i]; + if(c.bodyA !== bodyA){ + averageNormal.vadd(c.ni, averageNormal); // vec2.add(eq.t, eq.t, c.normalA); + averageContactPointA.vadd(c.ri, averageContactPointA); // vec2.add(eq.contactPointA, eq.contactPointA, c.contactPointA); + averageContactPointB.vadd(c.rj, averageContactPointB); + } else { + averageNormal.vsub(c.ni, averageNormal); // vec2.sub(eq.t, eq.t, c.normalA); + averageContactPointA.vadd(c.rj, averageContactPointA); // vec2.add(eq.contactPointA, eq.contactPointA, c.contactPointA); + averageContactPointB.vadd(c.ri, averageContactPointB); + } + } + + var invNumContacts = 1 / numContacts; + averageContactPointA.scale(invNumContacts, f1.ri); // vec2.scale(eq.contactPointA, eq.contactPointA, invNumContacts); + averageContactPointB.scale(invNumContacts, f1.rj); // vec2.scale(eq.contactPointB, eq.contactPointB, invNumContacts); + f2.ri.copy(f1.ri); // Should be the same + f2.rj.copy(f1.rj); + averageNormal.normalize(); + averageNormal.tangents(f1.t, f2.t); + // return eq; +}; + + +var tmpVec1 = new Vec3(); +var tmpVec2 = new Vec3(); +var tmpQuat1 = new Quaternion(); +var tmpQuat2 = new Quaternion(); + +/** + * Generate all contacts between a list of body pairs + * @method getContacts + * @param {array} p1 Array of body indices + * @param {array} p2 Array of body indices + * @param {World} world + * @param {array} result Array to store generated contacts + * @param {array} oldcontacts Optional. Array of reusable contact objects + */ +Narrowphase.prototype.getContacts = function(p1, p2, world, result, oldcontacts, frictionResult, frictionPool){ + // Save old contact objects + this.contactPointPool = oldcontacts; + this.frictionEquationPool = frictionPool; + this.result = result; + this.frictionResult = frictionResult; + + var qi = tmpQuat1; + var qj = tmpQuat2; + var xi = tmpVec1; + var xj = tmpVec2; + + for(var k=0, N=p1.length; k!==N; k++){ + + // Get current collision bodies + var bi = p1[k], + bj = p2[k]; + + // Get contact material + //miner使用两个body的材质的弹力和摩擦力 + var bodyContactMaterial = false; + if(bi.material && bj.material){ + bodyContactMaterial =true;//world.getContactMaterial(bi.material,bj.material) || null; + } + + for (var i = 0; i < bi.shapes.length; i++) { + bi.quaternion.mult(bi.shapeOrientations[i], qi); + bi.quaternion.vmult(bi.shapeOffsets[i], xi); + xi.vadd(bi.position, xi); + var si = bi.shapes[i]; + + for (var j = 0; j < bj.shapes.length; j++) { + + // Compute world transform of shapes + bj.quaternion.mult(bj.shapeOrientations[j], qj); + bj.quaternion.vmult(bj.shapeOffsets[j], xj); + xj.vadd(bj.position, xj); + var sj = bj.shapes[j]; + + if(xi.distanceTo(xj) > si.boundingSphereRadius + sj.boundingSphereRadius){ + continue; + } + + // Get collision material + var shapeContactMaterial = null; + if(si.material && sj.material){ + shapeContactMaterial = world.getContactMaterial(si.material,sj.material) || null; + } + // Layaminer在这儿改掉 + // this.currentContactMaterial = shapeContactMaterial || bodyContactMaterial || world.defaultContactMaterial; + + if(bodyContactMaterial) + { + this.currentContactMaterial = world.defaultContactMaterial2; + this.currentContactMaterial.materials[0] = bi.material; + this.currentContactMaterial.materials[1] = bj.material; + this.currentContactMaterial.friction =bi.material.friction+ bj.material.friction; + this.currentContactMaterial.restitution = bi.material.restitution*bj.material.restitution; + } + else + this.currentContactMaterial = world.defaultContactMaterial2; + + this.currentContactMaterial = world.defaultContactMaterial2; + + // Get contacts + var resolver = this[si.type | sj.type]; + if(resolver){ + if (si.type < sj.type) { + resolver.call(this, si, sj, xi, xj, qi, qj, bi, bj, si, sj); + } else { + resolver.call(this, sj, si, xj, xi, qj, qi, bj, bi, si, sj); + } + } + } + } + } +}; + +var numWarnings = 0; +var maxWarnings = 10; + +function warn(msg){ + if(numWarnings > maxWarnings){ + return; + } + + numWarnings++; + + console.warn(msg); +} + +Narrowphase.prototype[Shape.types.BOX | Shape.types.BOX] = +Narrowphase.prototype.boxBox = function(si,sj,xi,xj,qi,qj,bi,bj){ + si.convexPolyhedronRepresentation.material = si.material; + sj.convexPolyhedronRepresentation.material = sj.material; + si.convexPolyhedronRepresentation.collisionResponse = si.collisionResponse; + sj.convexPolyhedronRepresentation.collisionResponse = sj.collisionResponse; + this.convexConvex(si.convexPolyhedronRepresentation,sj.convexPolyhedronRepresentation,xi,xj,qi,qj,bi,bj,si,sj); +}; + +Narrowphase.prototype[Shape.types.BOX | Shape.types.CONVEXPOLYHEDRON] = +Narrowphase.prototype.boxConvex = function(si,sj,xi,xj,qi,qj,bi,bj){ + si.convexPolyhedronRepresentation.material = si.material; + si.convexPolyhedronRepresentation.collisionResponse = si.collisionResponse; + this.convexConvex(si.convexPolyhedronRepresentation,sj,xi,xj,qi,qj,bi,bj,si,sj); +}; + +Narrowphase.prototype[Shape.types.BOX | Shape.types.PARTICLE] = +Narrowphase.prototype.boxParticle = function(si,sj,xi,xj,qi,qj,bi,bj){ + si.convexPolyhedronRepresentation.material = si.material; + si.convexPolyhedronRepresentation.collisionResponse = si.collisionResponse; + this.convexParticle(si.convexPolyhedronRepresentation,sj,xi,xj,qi,qj,bi,bj,si,sj); +}; + +/** + * @method sphereSphere + * @param {Shape} si + * @param {Shape} sj + * @param {Vec3} xi + * @param {Vec3} xj + * @param {Quaternion} qi + * @param {Quaternion} qj + * @param {Body} bi + * @param {Body} bj + */ +Narrowphase.prototype[Shape.types.SPHERE] = +Narrowphase.prototype.sphereSphere = function(si,sj,xi,xj,qi,qj,bi,bj){ + // We will have only one contact in this case + var r = this.createContactEquation(bi,bj,si,sj); + + // Contact normal + xj.vsub(xi, r.ni); + r.ni.normalize(); + + // Contact point locations + r.ri.copy(r.ni); + r.rj.copy(r.ni); + r.ri.mult(si.radius, r.ri); + r.rj.mult(-sj.radius, r.rj); + + r.ri.vadd(xi, r.ri); + r.ri.vsub(bi.position, r.ri); + + r.rj.vadd(xj, r.rj); + r.rj.vsub(bj.position, r.rj); + + this.result.push(r); + + this.createFrictionEquationsFromContact(r, this.frictionResult); +}; + +/** + * @method planeTrimesh + * @param {Shape} si + * @param {Shape} sj + * @param {Vec3} xi + * @param {Vec3} xj + * @param {Quaternion} qi + * @param {Quaternion} qj + * @param {Body} bi + * @param {Body} bj + */ +var planeTrimesh_normal = new Vec3(); +var planeTrimesh_relpos = new Vec3(); +var planeTrimesh_projected = new Vec3(); +Narrowphase.prototype[Shape.types.PLANE | Shape.types.TRIMESH] = +Narrowphase.prototype.planeTrimesh = function( + planeShape, + trimeshShape, + planePos, + trimeshPos, + planeQuat, + trimeshQuat, + planeBody, + trimeshBody +){ + // Make contacts! + var v = new Vec3(); + + var normal = planeTrimesh_normal; + normal.set(0,0,1); + planeQuat.vmult(normal,normal); // Turn normal according to plane + + for(var i=0; i 0 && positionAlongEdgeB < 0){ + + // Now check the orthogonal distance from edge to sphere center + localSpherePos.vsub(edgeVertexA, tmp); + + edgeVectorUnit.copy(edgeVector); + edgeVectorUnit.normalize(); + positionAlongEdgeA = tmp.dot(edgeVectorUnit); + + edgeVectorUnit.scale(positionAlongEdgeA, tmp); + tmp.vadd(edgeVertexA, tmp); + + // tmp is now the sphere center position projected to the edge, defined locally in the trimesh frame + var dist = tmp.distanceTo(localSpherePos); + if(dist < sphereShape.radius){ + var r = this.createContactEquation(sphereBody, trimeshBody, sphereShape, trimeshShape); + + tmp.vsub(localSpherePos, r.ni); + r.ni.normalize(); + r.ni.scale(sphereShape.radius, r.ri); + + Transform.pointToWorldFrame(trimeshPos, trimeshQuat, tmp, tmp); + tmp.vsub(trimeshBody.position, r.rj); + + Transform.vectorToWorldFrame(trimeshQuat, r.ni, r.ni); + Transform.vectorToWorldFrame(trimeshQuat, r.ri, r.ri); + + this.result.push(r); + this.createFrictionEquationsFromContact(r, this.frictionResult); + } + } + } + } + + // Triangle faces + var va = sphereTrimesh_va; + var vb = sphereTrimesh_vb; + var vc = sphereTrimesh_vc; + var normal = sphereTrimesh_normal; + for(var i=0, N = triangles.length; i !== N; i++){ + trimeshShape.getTriangleVertices(triangles[i], va, vb, vc); + trimeshShape.getNormal(triangles[i], normal); + localSpherePos.vsub(va, tmp); + var dist = tmp.dot(normal); + normal.scale(dist, tmp); + localSpherePos.vsub(tmp, tmp); + + // tmp is now the sphere position projected to the triangle plane + dist = tmp.distanceTo(localSpherePos); + if(Ray.pointInTriangle(tmp, va, vb, vc) && dist < sphereShape.radius){ + var r = this.createContactEquation(sphereBody, trimeshBody, sphereShape, trimeshShape); + + tmp.vsub(localSpherePos, r.ni); + r.ni.normalize(); + r.ni.scale(sphereShape.radius, r.ri); + + Transform.pointToWorldFrame(trimeshPos, trimeshQuat, tmp, tmp); + tmp.vsub(trimeshBody.position, r.rj); + + Transform.vectorToWorldFrame(trimeshQuat, r.ni, r.ni); + Transform.vectorToWorldFrame(trimeshQuat, r.ri, r.ri); + + this.result.push(r); + this.createFrictionEquationsFromContact(r, this.frictionResult); + } + } + + triangles.length = 0; +}; + +var point_on_plane_to_sphere = new Vec3(); +var plane_to_sphere_ortho = new Vec3(); + +/** + * @method spherePlane + * @param {Shape} si + * @param {Shape} sj + * @param {Vec3} xi + * @param {Vec3} xj + * @param {Quaternion} qi + * @param {Quaternion} qj + * @param {Body} bi + * @param {Body} bj + */ +Narrowphase.prototype[Shape.types.SPHERE | Shape.types.PLANE] = +Narrowphase.prototype.spherePlane = function(si,sj,xi,xj,qi,qj,bi,bj){ + // We will have one contact in this case + var r = this.createContactEquation(bi,bj,si,sj); + + // Contact normal + r.ni.set(0,0,1); + qj.vmult(r.ni, r.ni); + r.ni.negate(r.ni); // body i is the sphere, flip normal + r.ni.normalize(); // Needed? + + // Vector from sphere center to contact point + r.ni.mult(si.radius, r.ri); + + // Project down sphere on plane + xi.vsub(xj, point_on_plane_to_sphere); + r.ni.mult(r.ni.dot(point_on_plane_to_sphere), plane_to_sphere_ortho); + point_on_plane_to_sphere.vsub(plane_to_sphere_ortho,r.rj); // The sphere position projected to plane + + if(-point_on_plane_to_sphere.dot(r.ni) <= si.radius){ + + // Make it relative to the body + var ri = r.ri; + var rj = r.rj; + ri.vadd(xi, ri); + ri.vsub(bi.position, ri); + rj.vadd(xj, rj); + rj.vsub(bj.position, rj); + + this.result.push(r); + this.createFrictionEquationsFromContact(r, this.frictionResult); + } +}; + +// See http://bulletphysics.com/Bullet/BulletFull/SphereTriangleDetector_8cpp_source.html +var pointInPolygon_edge = new Vec3(); +var pointInPolygon_edge_x_normal = new Vec3(); +var pointInPolygon_vtp = new Vec3(); +function pointInPolygon(verts, normal, p){ + var positiveResult = null; + var N = verts.length; + for(var i=0; i!==N; i++){ + var v = verts[i]; + + // Get edge to the next vertex + var edge = pointInPolygon_edge; + verts[(i+1) % (N)].vsub(v,edge); + + // Get cross product between polygon normal and the edge + var edge_x_normal = pointInPolygon_edge_x_normal; + //var edge_x_normal = new Vec3(); + edge.cross(normal,edge_x_normal); + + // Get vector between point and current vertex + var vertex_to_p = pointInPolygon_vtp; + p.vsub(v,vertex_to_p); + + // This dot product determines which side of the edge the point is + var r = edge_x_normal.dot(vertex_to_p); + + // If all such dot products have same sign, we are inside the polygon. + if(positiveResult===null || (r>0 && positiveResult===true) || (r<=0 && positiveResult===false)){ + if(positiveResult===null){ + positiveResult = r>0; + } + continue; + } else { + return false; // Encountered some other sign. Exit. + } + } + + // If we got here, all dot products were of the same sign. + return true; +} + +var box_to_sphere = new Vec3(); +var sphereBox_ns = new Vec3(); +var sphereBox_ns1 = new Vec3(); +var sphereBox_ns2 = new Vec3(); +var sphereBox_sides = [new Vec3(),new Vec3(),new Vec3(),new Vec3(),new Vec3(),new Vec3()]; +var sphereBox_sphere_to_corner = new Vec3(); +var sphereBox_side_ns = new Vec3(); +var sphereBox_side_ns1 = new Vec3(); +var sphereBox_side_ns2 = new Vec3(); + +/** + * @method sphereBox + * @param {Shape} si + * @param {Shape} sj + * @param {Vec3} xi + * @param {Vec3} xj + * @param {Quaternion} qi + * @param {Quaternion} qj + * @param {Body} bi + * @param {Body} bj + */ +Narrowphase.prototype[Shape.types.SPHERE | Shape.types.BOX] = +Narrowphase.prototype.sphereBox = function(si,sj,xi,xj,qi,qj,bi,bj){ + var v3pool = this.v3pool; + + // we refer to the box as body j + var sides = sphereBox_sides; + xi.vsub(xj,box_to_sphere); + sj.getSideNormals(sides,qj); + var R = si.radius; + var penetrating_sides = []; + + // Check side (plane) intersections + var found = false; + + // Store the resulting side penetration info + var side_ns = sphereBox_side_ns; + var side_ns1 = sphereBox_side_ns1; + var side_ns2 = sphereBox_side_ns2; + var side_h = null; + var side_penetrations = 0; + var side_dot1 = 0; + var side_dot2 = 0; + var side_distance = null; + for(var idx=0,nsides=sides.length; idx!==nsides && found===false; idx++){ + // Get the plane side normal (ns) + var ns = sphereBox_ns; + ns.copy(sides[idx]); + + var h = ns.norm(); + ns.normalize(); + + // The normal/distance dot product tells which side of the plane we are + var dot = box_to_sphere.dot(ns); + + if(dot0){ + // Intersects plane. Now check the other two dimensions + var ns1 = sphereBox_ns1; + var ns2 = sphereBox_ns2; + ns1.copy(sides[(idx+1)%3]); + ns2.copy(sides[(idx+2)%3]); + var h1 = ns1.norm(); + var h2 = ns2.norm(); + ns1.normalize(); + ns2.normalize(); + var dot1 = box_to_sphere.dot(ns1); + var dot2 = box_to_sphere.dot(ns2); + if(dot1

-h1 && dot2

-h2){ + var dist = Math.abs(dot-h-R); + if(side_distance===null || dist < side_distance){ + side_distance = dist; + side_dot1 = dot1; + side_dot2 = dot2; + side_h = h; + side_ns.copy(ns); + side_ns1.copy(ns1); + side_ns2.copy(ns2); + side_penetrations++; + } + } + } + } + if(side_penetrations){ + found = true; + var r = this.createContactEquation(bi,bj,si,sj); + side_ns.mult(-R,r.ri); // Sphere r + r.ni.copy(side_ns); + r.ni.negate(r.ni); // Normal should be out of sphere + side_ns.mult(side_h,side_ns); + side_ns1.mult(side_dot1,side_ns1); + side_ns.vadd(side_ns1,side_ns); + side_ns2.mult(side_dot2,side_ns2); + side_ns.vadd(side_ns2,r.rj); + + // Make relative to bodies + r.ri.vadd(xi, r.ri); + r.ri.vsub(bi.position, r.ri); + r.rj.vadd(xj, r.rj); + r.rj.vsub(bj.position, r.rj); + + this.result.push(r); + this.createFrictionEquationsFromContact(r, this.frictionResult); + } + + // Check corners + var rj = v3pool.get(); + var sphere_to_corner = sphereBox_sphere_to_corner; + for(var j=0; j!==2 && !found; j++){ + for(var k=0; k!==2 && !found; k++){ + for(var l=0; l!==2 && !found; l++){ + rj.set(0,0,0); + if(j){ + rj.vadd(sides[0],rj); + } else { + rj.vsub(sides[0],rj); + } + if(k){ + rj.vadd(sides[1],rj); + } else { + rj.vsub(sides[1],rj); + } + if(l){ + rj.vadd(sides[2],rj); + } else { + rj.vsub(sides[2],rj); + } + + // World position of corner + xj.vadd(rj,sphere_to_corner); + sphere_to_corner.vsub(xi,sphere_to_corner); + + if(sphere_to_corner.norm2() < R*R){ + found = true; + var r = this.createContactEquation(bi,bj,si,sj); + r.ri.copy(sphere_to_corner); + r.ri.normalize(); + r.ni.copy(r.ri); + r.ri.mult(R,r.ri); + r.rj.copy(rj); + + // Make relative to bodies + r.ri.vadd(xi, r.ri); + r.ri.vsub(bi.position, r.ri); + r.rj.vadd(xj, r.rj); + r.rj.vsub(bj.position, r.rj); + + this.result.push(r); + this.createFrictionEquationsFromContact(r, this.frictionResult); + } + } + } + } + v3pool.release(rj); + rj = null; + + // Check edges + var edgeTangent = v3pool.get(); + var edgeCenter = v3pool.get(); + var r = v3pool.get(); // r = edge center to sphere center + var orthogonal = v3pool.get(); + var dist = v3pool.get(); + var Nsides = sides.length; + for(var j=0; j!==Nsides && !found; j++){ + for(var k=0; k!==Nsides && !found; k++){ + if(j%3 !== k%3){ + // Get edge tangent + sides[k].cross(sides[j],edgeTangent); + edgeTangent.normalize(); + sides[j].vadd(sides[k], edgeCenter); + r.copy(xi); + r.vsub(edgeCenter,r); + r.vsub(xj,r); + var orthonorm = r.dot(edgeTangent); // distance from edge center to sphere center in the tangent direction + edgeTangent.mult(orthonorm,orthogonal); // Vector from edge center to sphere center in the tangent direction + + // Find the third side orthogonal to this one + var l = 0; + while(l===j%3 || l===k%3){ + l++; + } + + // vec from edge center to sphere projected to the plane orthogonal to the edge tangent + dist.copy(xi); + dist.vsub(orthogonal,dist); + dist.vsub(edgeCenter,dist); + dist.vsub(xj,dist); + + // Distances in tangent direction and distance in the plane orthogonal to it + var tdist = Math.abs(orthonorm); + var ndist = dist.norm(); + + if(tdist < sides[l].norm() && ndist si.boundingSphereRadius + sj.boundingSphereRadius){ + // return; + // } + + // Check corners + for(var i=0; i!==verts.length; i++){ + var v = verts[i]; + + // World position of corner + var worldCorner = sphereConvex_worldCorner; + qj.vmult(v,worldCorner); + xj.vadd(worldCorner,worldCorner); + var sphere_to_corner = sphereConvex_sphereToCorner; + worldCorner.vsub(xi, sphere_to_corner); + if(sphere_to_corner.norm2() < R * R){ + found = true; + var r = this.createContactEquation(bi,bj,si,sj); + r.ri.copy(sphere_to_corner); + r.ri.normalize(); + r.ni.copy(r.ri); + r.ri.mult(R,r.ri); + worldCorner.vsub(xj,r.rj); + + // Should be relative to the body. + r.ri.vadd(xi, r.ri); + r.ri.vsub(bi.position, r.ri); + + // Should be relative to the body. + r.rj.vadd(xj, r.rj); + r.rj.vsub(bj.position, r.rj); + + this.result.push(r); + this.createFrictionEquationsFromContact(r, this.frictionResult); + return; + } + } + + // Check side (plane) intersections + var found = false; + for(var i=0, nfaces=faces.length; i!==nfaces && found===false; i++){ + var normal = normals[i]; + var face = faces[i]; + + // Get world-transformed normal of the face + var worldNormal = sphereConvex_worldNormal; + qj.vmult(normal,worldNormal); + + // Get a world vertex from the face + var worldPoint = sphereConvex_worldPoint; + qj.vmult(verts[face[0]],worldPoint); + worldPoint.vadd(xj,worldPoint); + + // Get a point on the sphere, closest to the face normal + var worldSpherePointClosestToPlane = sphereConvex_worldSpherePointClosestToPlane; + worldNormal.mult(-R, worldSpherePointClosestToPlane); + xi.vadd(worldSpherePointClosestToPlane, worldSpherePointClosestToPlane); + + // Vector from a face point to the closest point on the sphere + var penetrationVec = sphereConvex_penetrationVec; + worldSpherePointClosestToPlane.vsub(worldPoint,penetrationVec); + + // The penetration. Negative value means overlap. + var penetration = penetrationVec.dot(worldNormal); + + var worldPointToSphere = sphereConvex_sphereToWorldPoint; + xi.vsub(worldPoint, worldPointToSphere); + + if(penetration < 0 && worldPointToSphere.dot(worldNormal)>0){ + // Intersects plane. Now check if the sphere is inside the face polygon + var faceVerts = []; // Face vertices, in world coords + for(var j=0, Nverts=face.length; j!==Nverts; j++){ + var worldVertex = v3pool.get(); + qj.vmult(verts[face[j]], worldVertex); + xj.vadd(worldVertex,worldVertex); + faceVerts.push(worldVertex); + } + + if(pointInPolygon(faceVerts,worldNormal,xi)){ // Is the sphere center in the face polygon? + found = true; + var r = this.createContactEquation(bi,bj,si,sj); + + worldNormal.mult(-R, r.ri); // Contact offset, from sphere center to contact + worldNormal.negate(r.ni); // Normal pointing out of sphere + + var penetrationVec2 = v3pool.get(); + worldNormal.mult(-penetration, penetrationVec2); + var penetrationSpherePoint = v3pool.get(); + worldNormal.mult(-R, penetrationSpherePoint); + + //xi.vsub(xj).vadd(penetrationSpherePoint).vadd(penetrationVec2 , r.rj); + xi.vsub(xj,r.rj); + r.rj.vadd(penetrationSpherePoint,r.rj); + r.rj.vadd(penetrationVec2 , r.rj); + + // Should be relative to the body. + r.rj.vadd(xj, r.rj); + r.rj.vsub(bj.position, r.rj); + + // Should be relative to the body. + r.ri.vadd(xi, r.ri); + r.ri.vsub(bi.position, r.ri); + + v3pool.release(penetrationVec2); + v3pool.release(penetrationSpherePoint); + + this.result.push(r); + this.createFrictionEquationsFromContact(r, this.frictionResult); + + // Release world vertices + for(var j=0, Nfaceverts=faceVerts.length; j!==Nfaceverts; j++){ + v3pool.release(faceVerts[j]); + } + + return; // We only expect *one* face contact + } else { + // Edge? + for(var j=0; j!==face.length; j++){ + + // Get two world transformed vertices + var v1 = v3pool.get(); + var v2 = v3pool.get(); + qj.vmult(verts[face[(j+1)%face.length]], v1); + qj.vmult(verts[face[(j+2)%face.length]], v2); + xj.vadd(v1, v1); + xj.vadd(v2, v2); + + // Construct edge vector + var edge = sphereConvex_edge; + v2.vsub(v1,edge); + + // Construct the same vector, but normalized + var edgeUnit = sphereConvex_edgeUnit; + edge.unit(edgeUnit); + + // p is xi projected onto the edge + var p = v3pool.get(); + var v1_to_xi = v3pool.get(); + xi.vsub(v1, v1_to_xi); + var dot = v1_to_xi.dot(edgeUnit); + edgeUnit.mult(dot, p); + p.vadd(v1, p); + + // Compute a vector from p to the center of the sphere + var xi_to_p = v3pool.get(); + p.vsub(xi, xi_to_p); + + // Collision if the edge-sphere distance is less than the radius + // AND if p is in between v1 and v2 + if(dot > 0 && dot*dot si.boundingSphereRadius + sj.boundingSphereRadius){ + return; + } + + if(si.findSeparatingAxis(sj,xi,qi,xj,qj,sepAxis,faceListA,faceListB)){ + var res = []; + var q = convexConvex_q; + si.clipAgainstHull(xi,qi,sj,xj,qj,sepAxis,-100,100,res); + var numContacts = 0; + for(var j = 0; j !== res.length; j++){ + var r = this.createContactEquation(bi,bj,si,sj,rsi,rsj), + ri = r.ri, + rj = r.rj; + sepAxis.negate(r.ni); + res[j].normal.negate(q); + q.mult(res[j].depth, q); + res[j].point.vadd(q, ri); + rj.copy(res[j].point); + + // Contact points are in world coordinates. Transform back to relative + ri.vsub(xi,ri); + rj.vsub(xj,rj); + + // Make relative to bodies + ri.vadd(xi, ri); + ri.vsub(bi.position, ri); + rj.vadd(xj, rj); + rj.vsub(bj.position, rj); + + this.result.push(r); + numContacts++; + if(!this.enableFrictionReduction){ + this.createFrictionEquationsFromContact(r, this.frictionResult); + } + } + if(this.enableFrictionReduction && numContacts){ + this.createFrictionFromAverage(numContacts); + } + } +}; + + +/** + * @method convexTrimesh + * @param {Array} result + * @param {Shape} si + * @param {Shape} sj + * @param {Vec3} xi + * @param {Vec3} xj + * @param {Quaternion} qi + * @param {Quaternion} qj + * @param {Body} bi + * @param {Body} bj + */ +// Narrowphase.prototype[Shape.types.CONVEXPOLYHEDRON | Shape.types.TRIMESH] = +// Narrowphase.prototype.convexTrimesh = function(si,sj,xi,xj,qi,qj,bi,bj,rsi,rsj,faceListA,faceListB){ +// var sepAxis = convexConvex_sepAxis; + +// if(xi.distanceTo(xj) > si.boundingSphereRadius + sj.boundingSphereRadius){ +// return; +// } + +// // Construct a temp hull for each triangle +// var hullB = new ConvexPolyhedron(); + +// hullB.faces = [[0,1,2]]; +// var va = new Vec3(); +// var vb = new Vec3(); +// var vc = new Vec3(); +// hullB.vertices = [ +// va, +// vb, +// vc +// ]; + +// for (var i = 0; i < sj.indices.length / 3; i++) { + +// var triangleNormal = new Vec3(); +// sj.getNormal(i, triangleNormal); +// hullB.faceNormals = [triangleNormal]; + +// sj.getTriangleVertices(i, va, vb, vc); + +// var d = si.testSepAxis(triangleNormal, hullB, xi, qi, xj, qj); +// if(!d){ +// triangleNormal.scale(-1, triangleNormal); +// d = si.testSepAxis(triangleNormal, hullB, xi, qi, xj, qj); + +// if(!d){ +// continue; +// } +// } + +// var res = []; +// var q = convexConvex_q; +// si.clipAgainstHull(xi,qi,hullB,xj,qj,triangleNormal,-100,100,res); +// for(var j = 0; j !== res.length; j++){ +// var r = this.createContactEquation(bi,bj,si,sj,rsi,rsj), +// ri = r.ri, +// rj = r.rj; +// r.ni.copy(triangleNormal); +// r.ni.negate(r.ni); +// res[j].normal.negate(q); +// q.mult(res[j].depth, q); +// res[j].point.vadd(q, ri); +// rj.copy(res[j].point); + +// // Contact points are in world coordinates. Transform back to relative +// ri.vsub(xi,ri); +// rj.vsub(xj,rj); + +// // Make relative to bodies +// ri.vadd(xi, ri); +// ri.vsub(bi.position, ri); +// rj.vadd(xj, rj); +// rj.vsub(bj.position, rj); + +// result.push(r); +// } +// } +// }; + +var particlePlane_normal = new Vec3(); +var particlePlane_relpos = new Vec3(); +var particlePlane_projected = new Vec3(); + +/** + * @method particlePlane + * @param {Array} result + * @param {Shape} si + * @param {Shape} sj + * @param {Vec3} xi + * @param {Vec3} xj + * @param {Quaternion} qi + * @param {Quaternion} qj + * @param {Body} bi + * @param {Body} bj + */ +Narrowphase.prototype[Shape.types.PLANE | Shape.types.PARTICLE] = +Narrowphase.prototype.planeParticle = function(sj,si,xj,xi,qj,qi,bj,bi){ + var normal = particlePlane_normal; + normal.set(0,0,1); + bj.quaternion.vmult(normal,normal); // Turn normal according to plane orientation + var relpos = particlePlane_relpos; + xi.vsub(bj.position,relpos); + var dot = normal.dot(relpos); + if(dot <= 0.0){ + var r = this.createContactEquation(bi,bj,si,sj); + r.ni.copy(normal); // Contact normal is the plane normal + r.ni.negate(r.ni); + r.ri.set(0,0,0); // Center of particle + + // Get particle position projected on plane + var projected = particlePlane_projected; + normal.mult(normal.dot(xi),projected); + xi.vsub(projected,projected); + //projected.vadd(bj.position,projected); + + // rj is now the projected world position minus plane position + r.rj.copy(projected); + this.result.push(r); + this.createFrictionEquationsFromContact(r, this.frictionResult); + } +}; + +var particleSphere_normal = new Vec3(); + +/** + * @method particleSphere + * @param {Array} result + * @param {Shape} si + * @param {Shape} sj + * @param {Vec3} xi + * @param {Vec3} xj + * @param {Quaternion} qi + * @param {Quaternion} qj + * @param {Body} bi + * @param {Body} bj + */ +Narrowphase.prototype[Shape.types.PARTICLE | Shape.types.SPHERE] = +Narrowphase.prototype.sphereParticle = function(sj,si,xj,xi,qj,qi,bj,bi){ + // The normal is the unit vector from sphere center to particle center + var normal = particleSphere_normal; + normal.set(0,0,1); + xi.vsub(xj,normal); + var lengthSquared = normal.norm2(); + + if(lengthSquared <= sj.radius * sj.radius){ + var r = this.createContactEquation(bi,bj,si,sj); + normal.normalize(); + r.rj.copy(normal); + r.rj.mult(sj.radius,r.rj); + r.ni.copy(normal); // Contact normal + r.ni.negate(r.ni); + r.ri.set(0,0,0); // Center of particle + this.result.push(r); + this.createFrictionEquationsFromContact(r, this.frictionResult); + } +}; + +// WIP +var cqj = new Quaternion(); +var convexParticle_local = new Vec3(); +var convexParticle_normal = new Vec3(); +var convexParticle_penetratedFaceNormal = new Vec3(); +var convexParticle_vertexToParticle = new Vec3(); +var convexParticle_worldPenetrationVec = new Vec3(); + +/** + * @method convexParticle + * @param {Array} result + * @param {Shape} si + * @param {Shape} sj + * @param {Vec3} xi + * @param {Vec3} xj + * @param {Quaternion} qi + * @param {Quaternion} qj + * @param {Body} bi + * @param {Body} bj + */ +Narrowphase.prototype[Shape.types.PARTICLE | Shape.types.CONVEXPOLYHEDRON] = +Narrowphase.prototype.convexParticle = function(sj,si,xj,xi,qj,qi,bj,bi){ + var penetratedFaceIndex = -1; + var penetratedFaceNormal = convexParticle_penetratedFaceNormal; + var worldPenetrationVec = convexParticle_worldPenetrationVec; + var minPenetration = null; + var numDetectedFaces = 0; + + // Convert particle position xi to local coords in the convex + var local = convexParticle_local; + local.copy(xi); + local.vsub(xj,local); // Convert position to relative the convex origin + qj.conjugate(cqj); + cqj.vmult(local,local); + + if(sj.pointIsInside(local)){ + + if(sj.worldVerticesNeedsUpdate){ + sj.computeWorldVertices(xj,qj); + } + if(sj.worldFaceNormalsNeedsUpdate){ + sj.computeWorldFaceNormals(qj); + } + + // For each world polygon in the polyhedra + for(var i=0,nfaces=sj.faces.length; i!==nfaces; i++){ + + // Construct world face vertices + var verts = [ sj.worldVertices[ sj.faces[i][0] ] ]; + var normal = sj.worldFaceNormals[i]; + + // Check how much the particle penetrates the polygon plane. + xi.vsub(verts[0],convexParticle_vertexToParticle); + var penetration = -normal.dot(convexParticle_vertexToParticle); + if(minPenetration===null || Math.abs(penetration) data.length || iMinY > data[0].length){ + return; + } + + // Clamp index to edges + if(iMinX < 0){ iMinX = 0; } + if(iMaxX < 0){ iMaxX = 0; } + if(iMinY < 0){ iMinY = 0; } + if(iMaxY < 0){ iMaxY = 0; } + if(iMinX >= data.length){ iMinX = data.length - 1; } + if(iMaxX >= data.length){ iMaxX = data.length - 1; } + if(iMaxY >= data[0].length){ iMaxY = data[0].length - 1; } + if(iMinY >= data[0].length){ iMinY = data[0].length - 1; } + + var minMax = []; + hfShape.getRectMinMax(iMinX, iMinY, iMaxX, iMaxY, minMax); + var min = minMax[0]; + var max = minMax[1]; + + // Bail out if we're cant touch the bounding height box + if(localConvexPos.z - radius > max || localConvexPos.z + radius < min){ + return; + } + + for(var i = iMinX; i < iMaxX; i++){ + for(var j = iMinY; j < iMaxY; j++){ + + // Lower triangle + hfShape.getConvexTrianglePillar(i, j, false); + Transform.pointToWorldFrame(hfPos, hfQuat, hfShape.pillarOffset, worldPillarOffset); + if (convexPos.distanceTo(worldPillarOffset) < hfShape.pillarConvex.boundingSphereRadius + convexShape.boundingSphereRadius) { + this.convexConvex(convexShape, hfShape.pillarConvex, convexPos, worldPillarOffset, convexQuat, hfQuat, convexBody, hfBody, null, null, faceList, null); + } + + // Upper triangle + hfShape.getConvexTrianglePillar(i, j, true); + Transform.pointToWorldFrame(hfPos, hfQuat, hfShape.pillarOffset, worldPillarOffset); + if (convexPos.distanceTo(worldPillarOffset) < hfShape.pillarConvex.boundingSphereRadius + convexShape.boundingSphereRadius) { + this.convexConvex(convexShape, hfShape.pillarConvex, convexPos, worldPillarOffset, convexQuat, hfQuat, convexBody, hfBody, null, null, faceList, null); + } + } + } +}; + +var sphereHeightfield_tmp1 = new Vec3(); +var sphereHeightfield_tmp2 = new Vec3(); + +/** + * @method sphereHeightfield + */ +Narrowphase.prototype[Shape.types.SPHERE | Shape.types.HEIGHTFIELD] = +Narrowphase.prototype.sphereHeightfield = function ( + sphereShape, + hfShape, + spherePos, + hfPos, + sphereQuat, + hfQuat, + sphereBody, + hfBody +){ + var data = hfShape.data, + radius = sphereShape.radius, + w = hfShape.elementSize, + worldPillarOffset = sphereHeightfield_tmp2; + + // Get sphere position to heightfield local! + var localSpherePos = sphereHeightfield_tmp1; + Transform.pointToLocalFrame(hfPos, hfQuat, spherePos, localSpherePos); + + // Get the index of the data points to test against + var iMinX = Math.floor((localSpherePos.x - radius) / w) - 1, + iMaxX = Math.ceil((localSpherePos.x + radius) / w) + 1, + iMinY = Math.floor((localSpherePos.y - radius) / w) - 1, + iMaxY = Math.ceil((localSpherePos.y + radius) / w) + 1; + + // Bail out if we are out of the terrain + if(iMaxX < 0 || iMaxY < 0 || iMinX > data.length || iMaxY > data[0].length){ + return; + } + + // Clamp index to edges + if(iMinX < 0){ iMinX = 0; } + if(iMaxX < 0){ iMaxX = 0; } + if(iMinY < 0){ iMinY = 0; } + if(iMaxY < 0){ iMaxY = 0; } + if(iMinX >= data.length){ iMinX = data.length - 1; } + if(iMaxX >= data.length){ iMaxX = data.length - 1; } + if(iMaxY >= data[0].length){ iMaxY = data[0].length - 1; } + if(iMinY >= data[0].length){ iMinY = data[0].length - 1; } + + var minMax = []; + hfShape.getRectMinMax(iMinX, iMinY, iMaxX, iMaxY, minMax); + var min = minMax[0]; + var max = minMax[1]; + + // Bail out if we're cant touch the bounding height box + if(localSpherePos.z - radius > max || localSpherePos.z + radius < min){ + return; + } + + var result = this.result; + for(var i = iMinX; i < iMaxX; i++){ + for(var j = iMinY; j < iMaxY; j++){ + + var numContactsBefore = result.length; + + // Lower triangle + hfShape.getConvexTrianglePillar(i, j, false); + Transform.pointToWorldFrame(hfPos, hfQuat, hfShape.pillarOffset, worldPillarOffset); + if (spherePos.distanceTo(worldPillarOffset) < hfShape.pillarConvex.boundingSphereRadius + sphereShape.boundingSphereRadius) { + this.sphereConvex(sphereShape, hfShape.pillarConvex, spherePos, worldPillarOffset, sphereQuat, hfQuat, sphereBody, hfBody); + } + + // Upper triangle + hfShape.getConvexTrianglePillar(i, j, true); + Transform.pointToWorldFrame(hfPos, hfQuat, hfShape.pillarOffset, worldPillarOffset); + if (spherePos.distanceTo(worldPillarOffset) < hfShape.pillarConvex.boundingSphereRadius + sphereShape.boundingSphereRadius) { + this.sphereConvex(sphereShape, hfShape.pillarConvex, spherePos, worldPillarOffset, sphereQuat, hfQuat, sphereBody, hfBody); + } + + var numContacts = result.length - numContactsBefore; + + if(numContacts > 2){ + return; + } + /* + // Skip all but 1 + for (var k = 0; k < numContacts - 1; k++) { + result.pop(); + } + */ + } + } +}; + +},{"../collision/AABB":3,"../collision/Ray":9,"../equations/ContactEquation":19,"../equations/FrictionEquation":21,"../math/Quaternion":28,"../math/Transform":29,"../math/Vec3":30,"../shapes/ConvexPolyhedron":38,"../shapes/Shape":43,"../solver/Solver":47,"../utils/Vec3Pool":54}],56:[function(_dereq_,module,exports){ +/* global performance */ + +module.exports = World; + +var Shape = _dereq_('../shapes/Shape'); +var Vec3 = _dereq_('../math/Vec3'); +var Quaternion = _dereq_('../math/Quaternion'); +var GSSolver = _dereq_('../solver/GSSolver'); +var Vec3Pool = _dereq_('../utils/Vec3Pool'); +var ContactEquation = _dereq_('../equations/ContactEquation'); +var FrictionEquation = _dereq_('../equations/FrictionEquation'); +var Narrowphase = _dereq_('./Narrowphase'); +var EventTarget = _dereq_('../utils/EventTarget'); +var ArrayCollisionMatrix = _dereq_('../collision/ArrayCollisionMatrix'); +var Material = _dereq_('../material/Material'); +var ContactMaterial = _dereq_('../material/ContactMaterial'); +var Body = _dereq_('../objects/Body'); +var TupleDictionary = _dereq_('../utils/TupleDictionary'); +var RaycastResult = _dereq_('../collision/RaycastResult'); +var AABB = _dereq_('../collision/AABB'); +var Ray = _dereq_('../collision/Ray'); +var NaiveBroadphase = _dereq_('../collision/NaiveBroadphase'); + +/** + * The physics world + * @class World + * @constructor + * @extends EventTarget + */ +function World(){ + EventTarget.apply(this); + + /** + * Currently / last used timestep. Is set to -1 if not available. This value is updated before each internal step, which means that it is "fresh" inside event callbacks. + * @property {Number} dt + */ + this.dt = -1; + + /** + * Makes bodies go to sleep when they've been inactive + * @property allowSleep + * @type {Boolean} + */ + this.allowSleep = false; + + /** + * All the current contacts (instances of ContactEquation) in the world. + * @property contacts + * @type {Array} + */ + this.contacts = []; + //miner所有碰撞点 + this.allContacts = []; + this.frictionEquations = []; + + /** + * How often to normalize quaternions. Set to 0 for every step, 1 for every second etc.. A larger value increases performance. If bodies tend to explode, set to a smaller value (zero to be sure nothing can go wrong). + * @property quatNormalizeSkip + * @type {Number} + */ + this.quatNormalizeSkip = 0; + + /** + * Set to true to use fast quaternion normalization. It is often enough accurate to use. If bodies tend to explode, set to false. + * @property quatNormalizeFast + * @type {Boolean} + * @see Quaternion.normalizeFast + * @see Quaternion.normalize + */ + this.quatNormalizeFast = false; + + /** + * The wall-clock time since simulation start + * @property time + * @type {Number} + */ + this.time = 0.0; + + /** + * Number of timesteps taken since start + * @property stepnumber + * @type {Number} + */ + this.stepnumber = 0; + + /// Default and last timestep sizes + this.default_dt = 1/60; + + this.nextId = 0; + /** + * @property gravity + * @type {Vec3} + */ + this.gravity = new Vec3(); + + /** + * @property broadphase + * @type {Broadphase} + */ + this.broadphase = new NaiveBroadphase(); + + /** + * @property bodies + * @type {Array} + */ + this.bodies = []; + + /** + * miner 所有通知laya的变换Body + * @property bodies + * @type {Array} + */ + this.callBackBody = []; + /** + * @property solver + * @type {Solver} + */ + this.solver = new GSSolver(); + + /** + * @property constraints + * @type {Array} + */ + this.constraints = []; + + /** + * @property narrowphase + * @type {Narrowphase} + */ + this.narrowphase = new Narrowphase(this); + + /** + * @property {ArrayCollisionMatrix} collisionMatrix + * @type {ArrayCollisionMatrix} + */ + this.collisionMatrix = new ArrayCollisionMatrix(); + + /** + * CollisionMatrix from the previous step. + * @property {ArrayCollisionMatrix} collisionMatrixPrevious + * @type {ArrayCollisionMatrix} + */ + this.collisionMatrixPrevious = new ArrayCollisionMatrix(); + + /** + * All added materials + * @property materials + * @type {Array} + */ + this.materials = []; + + /** + * @property contactmaterials + * @type {Array} + */ + this.contactmaterials = []; + + /** + * Used to look up a ContactMaterial given two instances of Material. + * @property {TupleDictionary} contactMaterialTable + */ + this.contactMaterialTable = new TupleDictionary(); + + this.defaultMaterial = new Material("default"); + + /** + * This contact material is used if no suitable contactmaterial is found for a contact. + * @property defaultContactMaterial + * @type {ContactMaterial} + */ + this.defaultContactMaterial = new ContactMaterial(this.defaultMaterial, this.defaultMaterial, { friction: 0.3, restitution: 0.0 }); + //miner增加一个默认的摩擦材质 + this.defaultContactMaterial2 = new ContactMaterial(this.defaultMaterial, this.defaultMaterial, { friction: 0.3, restitution: 0.0 }); + + /** + * @property doProfiling + * @type {Boolean} + */ + this.doProfiling = false; + + /** + * @property profile + * @type {Object} + */ + this.profile = { + solve:0, + makeContactConstraints:0, + broadphase:0, + integrate:0, + narrowphase:0, + }; + + /** + * @property subsystems + * @type {Array} + */ + this.subsystems = []; + + this.addBodyEvent = { + type:"addBody", + body : null, + }; + + this.removeBodyEvent = { + type:"removeBody", + body : null, + }; +} +World.prototype = new EventTarget(); + +// Temp stuff +var tmpAABB1 = new AABB(); +var tmpArray1 = []; +var tmpRay = new Ray(); + +/** + * Get the contact material between materials m1 and m2 + * @method getContactMaterial + * @param {Material} m1 + * @param {Material} m2 + * @return {ContactMaterial} The contact material if it was found. + */ +World.prototype.getContactMaterial = function(m1,m2){ + return this.contactMaterialTable.get(m1.id,m2.id); //this.contactmaterials[this.mats2cmat[i+j*this.materials.length]]; +}; + +/** + * Get number of objects in the world. + * @method numObjects + * @return {Number} + * @deprecated + */ +World.prototype.numObjects = function(){ + return this.bodies.length; +}; + +/** + * Store old collision state info + * @method collisionMatrixTick + */ +World.prototype.collisionMatrixTick = function(){ + var temp = this.collisionMatrixPrevious; + this.collisionMatrixPrevious = this.collisionMatrix; + this.collisionMatrix = temp; + this.collisionMatrix.reset(); +}; + +/** + * Add a rigid body to the simulation. + * @method add + * @param {Body} body + * @todo If the simulation has not yet started, why recrete and copy arrays for each body? Accumulate in dynamic arrays in this case. + * @todo Adding an array of bodies should be possible. This would save some loops too + * @deprecated Use .addBody instead + */ +World.prototype.add = World.prototype.addBody = function(body){ + if(this.bodies.indexOf(body) !== -1){ + return; + } + body.index = this.bodies.length; + this.bodies.push(body); + body.world = this; + body.initPosition.copy(body.position); + body.initVelocity.copy(body.velocity); + body.timeLastSleepy = this.time; + if(body instanceof Body){ + body.initAngularVelocity.copy(body.angularVelocity); + body.initQuaternion.copy(body.quaternion); + } + this.collisionMatrix.setNumObjects(this.bodies.length); + this.addBodyEvent.body = body; + this.dispatchEvent(this.addBodyEvent); +}; + +/** + * Add a constraint to the simulation. + * @method addConstraint + * @param {Constraint} c + */ +World.prototype.addConstraint = function(c){ + this.constraints.push(c); +}; + +/** + * Removes a constraint + * @method removeConstraint + * @param {Constraint} c + */ +World.prototype.removeConstraint = function(c){ + var idx = this.constraints.indexOf(c); + if(idx!==-1){ + this.constraints.splice(idx,1); + } +}; + +/** + * Raycast test + * @method rayTest + * @param {Vec3} from + * @param {Vec3} to + * @param {Function|RaycastResult} result + * @deprecated Use .raycastAll, .raycastClosest or .raycastAny instead. + */ +World.prototype.rayTest = function(from, to, result){ + if(result instanceof RaycastResult){ + // Do raycastclosest + this.raycastClosest(from, to, { + skipBackfaces: true + }, result); + } else { + // Do raycastAll + this.raycastAll(from, to, { + skipBackfaces: true + }, result); + } +}; + +/** + * Ray cast against all bodies. The provided callback will be executed for each hit with a RaycastResult as single argument. + * @method raycastAll + * @param {Vec3} from + * @param {Vec3} to + * @param {Object} options + * @param {number} [options.collisionFilterMask=-1] + * @param {number} [options.collisionFilterGroup=-1] + * @param {boolean} [options.skipBackfaces=false] + * @param {boolean} [options.checkCollisionResponse=true] + * @param {Function} callback + * @return {boolean} True if any body was hit. + */ +World.prototype.raycastAll = function(from, to, options, callback){ + options.mode = Ray.ALL; + options.from = from; + options.to = to; + options.callback = callback; + return tmpRay.intersectWorld(this, options); +}; + +/** + * Ray cast, and stop at the first result. Note that the order is random - but the method is fast. + * @method raycastAny + * @param {Vec3} from + * @param {Vec3} to + * @param {Object} options + * @param {number} [options.collisionFilterMask=-1] + * @param {number} [options.collisionFilterGroup=-1] + * @param {boolean} [options.skipBackfaces=false] + * @param {boolean} [options.checkCollisionResponse=true] + * @param {RaycastResult} result + * @return {boolean} True if any body was hit. + */ +World.prototype.raycastAny = function(from, to, options, result){ + options.mode = Ray.ANY; + options.from = from; + options.to = to; + options.result = result; + return tmpRay.intersectWorld(this, options); +}; + +/** + * Ray cast, and return information of the closest hit. + * @method raycastClosest + * @param {Vec3} from + * @param {Vec3} to + * @param {Object} options + * @param {number} [options.collisionFilterMask=-1] + * @param {number} [options.collisionFilterGroup=-1] + * @param {boolean} [options.skipBackfaces=false] + * @param {boolean} [options.checkCollisionResponse=true] + * @param {RaycastResult} result + * @return {boolean} True if any body was hit. + */ +World.prototype.raycastClosest = function(from, to, options, result){ + options.mode = Ray.CLOSEST; + options.from = from; + options.to = to; + options.result = result; + return tmpRay.intersectWorld(this, options); +}; + +/** + * Remove a rigid body from the simulation. + * @method remove + * @param {Body} body + * @deprecated Use .removeBody instead + */ +World.prototype.remove = function(body){ + body.world = null; + var n = this.bodies.length-1, + bodies = this.bodies, + idx = bodies.indexOf(body); + if(idx !== -1){ + bodies.splice(idx, 1); // Todo: should use a garbage free method + + // Recompute index + for(var i=0; i!==bodies.length; i++){ + bodies[i].index = i; + } + + this.collisionMatrix.setNumObjects(n); + this.removeBodyEvent.body = body; + this.dispatchEvent(this.removeBodyEvent); + } +}; + +/** + * Remove a rigid body from the simulation. + * @method removeBody + * @param {Body} body + */ +World.prototype.removeBody = World.prototype.remove; + +/** + * Adds a material to the World. + * @method addMaterial + * @param {Material} m + * @todo Necessary? + */ +World.prototype.addMaterial = function(m){ + this.materials.push(m); +}; + +/** + * Adds a contact material to the World + * @method addContactMaterial + * @param {ContactMaterial} cmat + */ +World.prototype.addContactMaterial = function(cmat) { + + // Add contact material + this.contactmaterials.push(cmat); + + // Add current contact material to the material table + this.contactMaterialTable.set(cmat.materials[0].id,cmat.materials[1].id,cmat); +}; + +// performance.now() +if(typeof performance === 'undefined'){ + performance = {}; +} +if(!performance.now){ + var nowOffset = Date.now(); + if (performance.timing && performance.timing.navigationStart){ + nowOffset = performance.timing.navigationStart; + } + performance.now = function(){ + return Date.now() - nowOffset; + }; +} + +var step_tmp1 = new Vec3(); + +/** + * Step the physics world forward in time. + * + * There are two modes. The simple mode is fixed timestepping without interpolation. In this case you only use the first argument. The second case uses interpolation. In that you also provide the time since the function was last used, as well as the maximum fixed timesteps to take. + * + * @method step + * @param {Number} dt The fixed time step size to use. + * @param {Number} [timeSinceLastCalled] The time elapsed since the function was last called. + * @param {Number} [maxSubSteps=10] Maximum number of fixed steps to take per function call. + * + * @example + * // fixed timestepping without interpolation + * world.step(1/60); + * + * @see http://bulletphysics.org/mediawiki-1.5.8/index.php/Stepping_The_World + */ +World.prototype.step = function(dt, timeSinceLastCalled, maxSubSteps){ + maxSubSteps = maxSubSteps || 10; + timeSinceLastCalled = timeSinceLastCalled || 0; + + if(timeSinceLastCalled === 0){ // Fixed, simple stepping + + this.internalStep(dt); + + // Increment time + this.time += dt; + + } else { + + // Compute the number of fixed steps we should have taken since the last step + var internalSteps = Math.floor((this.time + timeSinceLastCalled) / dt) - Math.floor(this.time / dt); + internalSteps = Math.min(internalSteps,maxSubSteps); + + // Do some fixed steps to catch up + var t0 = performance.now(); + for(var i=0; i!==internalSteps; i++){ + this.internalStep(dt); + if(performance.now() - t0 > dt * 1000){ + // We are slower than real-time. Better bail out. + break; + } + } + + // Increment internal clock + this.time += timeSinceLastCalled; + + // Compute "Left over" time step + var h = this.time % dt; + var h_div_dt = h / dt; + var interpvelo = step_tmp1; + var bodies = this.bodies; + + for(var j=0; j !== bodies.length; j++){ + var b = bodies[j]; + if(b.type !== Body.STATIC && b.sleepState !== Body.SLEEPING){ + + // Interpolate + b.position.vsub(b.previousPosition, interpvelo); + interpvelo.scale(h_div_dt, interpvelo); + b.position.vadd(interpvelo, b.interpolatedPosition); + + // TODO: interpolate quaternion + // b.interpolatedAngle = b.angle + (b.angle - b.previousAngle) * h_div_dt; + + } else { + + // For static bodies, just copy. Who else will do it? + b.interpolatedPosition.copy(b.position); + b.interpolatedQuaternion.copy(b.quaternion); + } + } + } +}; + +/** + * Step the simulation + * @method step + * @param {Number} dt + */ +var World_step_postStepEvent = {type:"postStep"}, // Reusable event objects to save memory + World_step_preStepEvent = {type:"preStep"}, + World_step_collideEvent = {type:"collide", body:null, contact:null }, + World_step_oldContacts = [], // Pools for unused objects + World_step_frictionEquationPool = [], + World_step_p1 = [], // Reusable arrays for collision pairs + World_step_p2 = [], + World_step_gvec = new Vec3(), // Temporary vectors and quats + World_step_vi = new Vec3(), + World_step_vj = new Vec3(), + World_step_wi = new Vec3(), + World_step_wj = new Vec3(), + World_step_t1 = new Vec3(), + World_step_t2 = new Vec3(), + World_step_rixn = new Vec3(), + World_step_rjxn = new Vec3(), + World_step_step_q = new Quaternion(), + World_step_step_w = new Quaternion(), + World_step_step_wq = new Quaternion(), + invI_tau_dt = new Vec3(); +World.prototype.internalStep = function(dt){ + this.dt = dt; + + var world = this, + that = this, + contacts = this.contacts, + allContacts = this.allContacts, + p1 = World_step_p1, + p2 = World_step_p2, + N = this.numObjects(), + bodies = this.bodies, + solver = this.solver, + gravity = this.gravity, + doProfiling = this.doProfiling, + profile = this.profile, + DYNAMIC = Body.DYNAMIC, + profilingStart, + constraints = this.constraints, + frictionEquationPool = World_step_frictionEquationPool, + gnorm = gravity.norm(), + gx = gravity.x, + gy = gravity.y, + gz = gravity.z, + i=0; + + if(doProfiling){ + profilingStart = performance.now(); + } + + // Add gravity to all objects + for(i=0; i!==N; i++){ + var bi = bodies[i]; + if(bi.type & DYNAMIC){ // Only for dynamic bodies + var f = bi.force, m = bi.mass; + f.x += m*gx; + f.y += m*gy; + f.z += m*gz; + } + } + + // Update subsystems + for(var i=0, Nsubsystems=this.subsystems.length; i!==Nsubsystems; i++){ + this.subsystems[i].update(); + } + + // Collision detection + if(doProfiling){ profilingStart = performance.now(); } + p1.length = 0; // Clean up pair arrays from last step + p2.length = 0; + this.broadphase.collisionPairs(this,p1,p2); + if(doProfiling){ profile.broadphase = performance.now() - profilingStart; } + + // Remove constrained pairs with collideConnected == false + var Nconstraints = constraints.length; + for(i=0; i!==Nconstraints; i++){ + var c = constraints[i]; + if(!c.collideConnected){ + for(var j = p1.length-1; j>=0; j-=1){ + if( (c.bodyA === p1[j] && c.bodyB === p2[j]) || + (c.bodyB === p1[j] && c.bodyA === p2[j])){ + p1.splice(j, 1); + p2.splice(j, 1); + } + } + } + } + + this.collisionMatrixTick(); + + // Generate contacts + if(doProfiling){ profilingStart = performance.now(); } + var oldcontacts = World_step_oldContacts; + //miner + var NoldContacts = allContacts.length; + + for(i=0; i!==NoldContacts; i++){ + //miner + oldcontacts.push(allContacts[i]); + } + contacts.length = 0; + //miner + allContacts.length = 0; + // Transfer FrictionEquation from current list to the pool for reuse + var NoldFrictionEquations = this.frictionEquations.length; + for(i=0; i!==NoldFrictionEquations; i++){ + frictionEquationPool.push(this.frictionEquations[i]); + } + this.frictionEquations.length = 0; + + this.narrowphase.getContacts( + p1, + p2, + this, + allContacts,//miner + oldcontacts, // To be reused + this.frictionEquations, + frictionEquationPool + ); + //排除istrigger的碰撞物体 + var ncontactss = allContacts.length; + for(var ii = 0;ii != ncontactss;ii++) + { + var tempContact = allContacts[ii]; + if(!(tempContact.bi.isTrigger||tempContact.bj.isTrigger)) + { + contacts.push(tempContact); + } + } + + if(doProfiling){ + profile.narrowphase = performance.now() - profilingStart; + } + + // Loop over all collisions + if(doProfiling){ + profilingStart = performance.now(); + } + + // Add all friction eqs + for (var i = 0; i < this.frictionEquations.length; i++) { + solver.addEquation(this.frictionEquations[i]); + } + + var ncontacts = contacts.length; + for(var k=0; k!==ncontacts; k++){ + + // Current contact + var c = contacts[k]; + + // Get current collision indeces + var bi = c.bi, + bj = c.bj, + si = c.si, + sj = c.sj; + + // Get collision properties + var cm; + if(bi.material && bj.material){ + cm = this.getContactMaterial(bi.material,bj.material) || this.defaultContactMaterial; + } else { + cm = this.defaultContactMaterial; + } + + // c.enabled = bi.collisionResponse && bj.collisionResponse && si.collisionResponse && sj.collisionResponse; + + var mu = cm.friction; + // c.restitution = cm.restitution; + + // If friction or restitution were specified in the material, use them + if(bi.material && bj.material){ + if(bi.material.friction >= 0 && bj.material.friction >= 0){ + mu = bi.material.friction * bj.material.friction; + } + + if(bi.material.restitution >= 0 && bj.material.restitution >= 0){ + c.restitution = bi.material.restitution * bj.material.restitution; + } + } + + // c.setSpookParams( + // cm.contactEquationStiffness, + // cm.contactEquationRelaxation, + // dt + // ); + + solver.addEquation(c); + + // // Add friction constraint equation + // if(mu > 0){ + + // // Create 2 tangent equations + // var mug = mu * gnorm; + // var reducedMass = (bi.invMass + bj.invMass); + // if(reducedMass > 0){ + // reducedMass = 1/reducedMass; + // } + // var pool = frictionEquationPool; + // var c1 = pool.length ? pool.pop() : new FrictionEquation(bi,bj,mug*reducedMass); + // var c2 = pool.length ? pool.pop() : new FrictionEquation(bi,bj,mug*reducedMass); + // this.frictionEquations.push(c1, c2); + + // c1.bi = c2.bi = bi; + // c1.bj = c2.bj = bj; + // c1.minForce = c2.minForce = -mug*reducedMass; + // c1.maxForce = c2.maxForce = mug*reducedMass; + + // // Copy over the relative vectors + // c1.ri.copy(c.ri); + // c1.rj.copy(c.rj); + // c2.ri.copy(c.ri); + // c2.rj.copy(c.rj); + + // // Construct tangents + // c.ni.tangents(c1.t, c2.t); + + // // Set spook params + // c1.setSpookParams(cm.frictionEquationStiffness, cm.frictionEquationRelaxation, dt); + // c2.setSpookParams(cm.frictionEquationStiffness, cm.frictionEquationRelaxation, dt); + + // c1.enabled = c2.enabled = c.enabled; + + // // Add equations to solver + // solver.addEquation(c1); + // solver.addEquation(c2); + // } + + if( bi.allowSleep && + bi.type === Body.DYNAMIC && + bi.sleepState === Body.SLEEPING && + bj.sleepState === Body.AWAKE && + bj.type !== Body.STATIC + ){ + var speedSquaredB = bj.velocity.norm2() + bj.angularVelocity.norm2(); + var speedLimitSquaredB = Math.pow(bj.sleepSpeedLimit,2); + if(speedSquaredB >= speedLimitSquaredB*2){ + bi._wakeUpAfterNarrowphase = true; + } + } + + if( bj.allowSleep && + bj.type === Body.DYNAMIC && + bj.sleepState === Body.SLEEPING && + bi.sleepState === Body.AWAKE && + bi.type !== Body.STATIC + ){ + var speedSquaredA = bi.velocity.norm2() + bi.angularVelocity.norm2(); + var speedLimitSquaredA = Math.pow(bi.sleepSpeedLimit,2); + if(speedSquaredA >= speedLimitSquaredA*2){ + bj._wakeUpAfterNarrowphase = true; + } + } + + // Now we know that i and j are in contact. Set collision matrix state + this.collisionMatrix.set(bi, bj, true); + + if (!this.collisionMatrixPrevious.get(bi, bj)) { + // First contact! + // We reuse the collideEvent object, otherwise we will end up creating new objects for each new contact, even if there's no event listener attached. + World_step_collideEvent.body = bj; + World_step_collideEvent.contact = c; + bi.dispatchEvent(World_step_collideEvent); + + World_step_collideEvent.body = bi; + bj.dispatchEvent(World_step_collideEvent); + } + } + if(doProfiling){ + profile.makeContactConstraints = performance.now() - profilingStart; + profilingStart = performance.now(); + } + + // Wake up bodies + for(i=0; i!==N; i++){ + var bi = bodies[i]; + if(bi._wakeUpAfterNarrowphase){ + bi.wakeUp(); + bi._wakeUpAfterNarrowphase = false; + } + } + + // Add user-added constraints + var Nconstraints = constraints.length; + for(i=0; i!==Nconstraints; i++){ + var c = constraints[i]; + c.update(); + for(var j=0, Neq=c.equations.length; j!==Neq; j++){ + var eq = c.equations[j]; + solver.addEquation(eq); + } + } + + // Solve the constrained system + solver.solve(dt,this); + + if(doProfiling){ + profile.solve = performance.now() - profilingStart; + } + + // Remove all contacts from solver + solver.removeAllEquations(); + + // Apply damping, see http://code.google.com/p/bullet/issues/detail?id=74 for details + var pow = Math.pow; + for(i=0; i!==N; i++){ + var bi = bodies[i]; + if(bi.type & DYNAMIC){ // Only for dynamic bodies + var ld = pow(1.0 - bi.linearDamping,dt); + var v = bi.velocity; + v.mult(ld,v); + var av = bi.angularVelocity; + if(av){ + var ad = pow(1.0 - bi.angularDamping,dt); + av.mult(ad,av); + } + } + } + + this.dispatchEvent(World_step_preStepEvent); + + // Invoke pre-step callbacks + for(i=0; i!==N; i++){ + var bi = bodies[i]; + if(bi.preStep){ + bi.preStep.call(bi); + } + } + + // Leap frog + // vnew = v + h*f/m + // xnew = x + h*vnew + if(doProfiling){ + profilingStart = performance.now(); + } + var q = World_step_step_q; + var w = World_step_step_w; + var wq = World_step_step_wq; + var stepnumber = this.stepnumber; + var DYNAMIC_OR_KINEMATIC = Body.DYNAMIC | Body.KINEMATIC; + var quatNormalize = stepnumber % (this.quatNormalizeSkip+1) === 0; + var quatNormalizeFast = this.quatNormalizeFast; + var half_dt = dt * 0.5; + var PLANE = Shape.types.PLANE, + CONVEX = Shape.types.CONVEXPOLYHEDRON; + //miner 清楚队列 + this.callBackBody.length = 0; + for(i=0; i!==N; i++){ + var b = bodies[i], + force = b.force, + tau = b.torque; + if((b.type & DYNAMIC_OR_KINEMATIC) && b.sleepState !== Body.SLEEPING){ // Only for dynamic + var velo = b.velocity, + angularVelo = b.angularVelocity, + pos = b.position, + quat = b.quaternion, + invMass = b.invMass, + invInertia = b.invInertiaWorld; + //miner 组织所有的变动大的物体 + + //miner end + velo.x += force.x * invMass * dt; + velo.y += force.y * invMass * dt; + velo.z += force.z * invMass * dt; + + if(b.angularVelocity){ + invInertia.vmult(tau,invI_tau_dt); + invI_tau_dt.mult(dt,invI_tau_dt); + invI_tau_dt.vadd(angularVelo,angularVelo); + } + + // Use new velocity - leap frog + pos.x += velo.x * dt; + pos.y += velo.y * dt; + pos.z += velo.z * dt; + + if(b.angularVelocity){ + w.set(angularVelo.x, angularVelo.y, angularVelo.z, 0); + w.mult(quat,wq); + quat.x += half_dt * wq.x; + quat.y += half_dt * wq.y; + quat.z += half_dt * wq.z; + quat.w += half_dt * wq.w; + if(quatNormalize){ + if(quatNormalizeFast){ + quat.normalizeFast(); + } else { + quat.normalize(); + } + } + } + //if(velo.length()>0.0001||(wq.x!=0||wq.y!=0||wq.z!=0||wq.w!=0)) + this.callBackBody.push(b); + if(b.aabb){ + b.aabbNeedsUpdate = true; + } + + // Update world inertia + if(b.updateInertiaWorld){ + b.updateInertiaWorld(); + } + } + } + this.clearForces(); + + this.broadphase.dirty = true; + + if(doProfiling){ + profile.integrate = performance.now() - profilingStart; + } + + // Update world time + this.time += dt; + this.stepnumber += 1; + + this.dispatchEvent(World_step_postStepEvent); + + // Invoke post-step callbacks + for(i=0; i!==N; i++){ + var bi = bodies[i]; + var postStep = bi.postStep; + if(postStep){ + postStep.call(bi); + } + } + + // Sleeping update + if(this.allowSleep){ + for(i=0; i!==N; i++){ + bodies[i].sleepTick(this.time); + } + } +}; + +/** + * Sets all body forces in the world to zero. + * @method clearForces + */ +World.prototype.clearForces = function(){ + var bodies = this.bodies; + var N = bodies.length; + for(var i=0; i !== N; i++){ + var b = bodies[i], + force = b.force, + tau = b.torque; + + b.force.set(0,0,0); + b.torque.set(0,0,0); + } +}; + +},{"../collision/AABB":3,"../collision/ArrayCollisionMatrix":4,"../collision/NaiveBroadphase":7,"../collision/Ray":9,"../collision/RaycastResult":10,"../equations/ContactEquation":19,"../equations/FrictionEquation":21,"../material/ContactMaterial":24,"../material/Material":25,"../math/Quaternion":28,"../math/Vec3":30,"../objects/Body":31,"../shapes/Shape":43,"../solver/GSSolver":46,"../utils/EventTarget":49,"../utils/TupleDictionary":52,"../utils/Vec3Pool":54,"./Narrowphase":55}]},{},[2]) +(2) +}); +(function (exports, Laya) { + 'use strict'; + + class CannonCollision { + constructor() { + this._lastUpdateFrame = -2147483648; + this._updateFrame = -2147483648; + this._isTrigger = false; + this.contacts = []; + } + _setUpdateFrame(farme) { + this._lastUpdateFrame = this._updateFrame; + this._updateFrame = farme; + } + } + + class CannonContactPoint { + constructor() { + this._idCounter = 0; + this.colliderA = null; + this.colliderB = null; + this.distance = 0; + this.normal = new Laya.Vector3(); + this.positionOnA = new Laya.Vector3(); + this.positionOnB = new Laya.Vector3(); + this._id = ++this._idCounter; + } + } + + class CannonHitResult { + constructor() { + this.succeeded = false; + this.collider = null; + this.point = new Laya.Vector3(); + this.normal = new Laya.Vector3(); + this.hitFraction = 0; + } + } + + class CannonCollisionTool { + constructor() { + this._hitResultsPoolIndex = 0; + this._hitResultsPool = []; + this._contactPonintsPoolIndex = 0; + this._contactPointsPool = []; + this._collisionsPool = []; + this._collisions = {}; + } + getHitResult() { + var hitResult = this._hitResultsPool[this._hitResultsPoolIndex++]; + if (!hitResult) { + hitResult = new CannonHitResult(); + this._hitResultsPool.push(hitResult); + } + return hitResult; + } + recoverAllHitResultsPool() { + this._hitResultsPoolIndex = 0; + } + getContactPoints() { + var contactPoint = this._contactPointsPool[this._contactPonintsPoolIndex++]; + if (!contactPoint) { + contactPoint = new CannonContactPoint(); + this._contactPointsPool.push(contactPoint); + } + return contactPoint; + } + recoverAllContactPointsPool() { + this._contactPonintsPoolIndex = 0; + } + getCollision(physicComponentA, physicComponentB) { + var collision; + var idA = physicComponentA.id; + var idB = physicComponentB.id; + var subCollisionFirst = this._collisions[idA]; + if (subCollisionFirst) + collision = subCollisionFirst[idB]; + if (!collision) { + if (!subCollisionFirst) { + subCollisionFirst = {}; + this._collisions[idA] = subCollisionFirst; + } + collision = this._collisionsPool.length === 0 ? new CannonCollision() : this._collisionsPool.pop(); + collision._colliderA = physicComponentA; + collision._colliderB = physicComponentB; + subCollisionFirst[idB] = collision; + } + return collision; + } + recoverCollision(collision) { + var idA = collision._colliderA.id; + var idB = collision._colliderB.id; + this._collisions[idA][idB] = null; + this._collisionsPool.push(collision); + } + garbageCollection() { + this._hitResultsPoolIndex = 0; + this._hitResultsPool.length = 0; + this._contactPonintsPoolIndex = 0; + this._contactPointsPool.length = 0; + this._collisionsPool.length = 0; + for (var subCollisionsKey in this._collisionsPool) { + var subCollisions = this._collisionsPool[subCollisionsKey]; + var wholeDelete = true; + for (var collisionKey in subCollisions) { + if (subCollisions[collisionKey]) + wholeDelete = false; + else + delete subCollisions[collisionKey]; + } + if (wholeDelete) + delete this._collisionsPool[subCollisionsKey]; + } + } + } + + class CannonColliderShape { + constructor() { + this._scale = new Laya.Vector3(1, 1, 1); + this._centerMatrix = new Laya.Matrix4x4(); + this._attatched = false; + this._indexInCompound = -1; + this._compoundParent = null; + this._attatchedCollisionObject = null; + this._referenceCount = 0; + this._localOffset = new Laya.Vector3(0, 0, 0); + this._localRotation = new Laya.Quaternion(0, 0, 0, 1); + this.needsCustomCollisionCallback = false; + } + static __init__() { + CannonColliderShape._btScale = new CANNON.Vec3(); + CannonColliderShape._btVector30 = new CANNON.Vec3(); + CannonColliderShape._btQuaternion0 = new CANNON.Quaternion(); + } + static _createAffineTransformation(trans, rot, outE) { + var x = rot.x, y = rot.y, z = rot.z, w = rot.w, x2 = x + x, y2 = y + y, z2 = z + z; + var xx = x * x2, xy = x * y2, xz = x * z2, yy = y * y2, yz = y * z2, zz = z * z2; + var wx = w * x2, wy = w * y2, wz = w * z2; + outE[0] = (1 - (yy + zz)); + outE[1] = (xy + wz); + outE[2] = (xz - wy); + outE[3] = 0; + outE[4] = (xy - wz); + outE[5] = (1 - (xx + zz)); + outE[6] = (yz + wx); + outE[7] = 0; + outE[8] = (xz + wy); + outE[9] = (yz - wx); + outE[10] = (1 - (xx + yy)); + outE[11] = 0; + outE[12] = trans.x; + outE[13] = trans.y; + outE[14] = trans.z; + outE[15] = 1; + } + get type() { + return this._type; + } + get localOffset() { + return this._localOffset; + } + set localOffset(value) { + value.cloneTo(this._localOffset); + } + get localRotation() { + return this._localRotation; + } + set localRotation(value) { + this._localRotation = value; + if (this._compoundParent) + this._compoundParent._updateChildTransform(this); + } + _setScale(value) { + } + _addReference() { + this._referenceCount++; + } + _removeReference() { + this._referenceCount--; + } + updateLocalTransformations() { + if (this._compoundParent) { + var offset = CannonColliderShape._tempVector30; + Laya.Vector3.multiply(this.localOffset, this._scale, offset); + CannonColliderShape._createAffineTransformation(offset, this.localRotation, this._centerMatrix.elements); + } + else { + CannonColliderShape._createAffineTransformation(this.localOffset, this.localRotation, this._centerMatrix.elements); + } + } + cloneTo(destObject) { + var destColliderShape = destObject; + this._localOffset.cloneTo(destColliderShape.localOffset); + this._localRotation.cloneTo(destColliderShape.localRotation); + destColliderShape.localOffset = destColliderShape.localOffset; + destColliderShape.localRotation = destColliderShape.localRotation; + } + clone() { + return null; + } + destroy() { + if (this._btShape) { + this._btShape = null; + } + } + } + CannonColliderShape.SHAPEORIENTATION_UPX = 0; + CannonColliderShape.SHAPEORIENTATION_UPY = 1; + CannonColliderShape.SHAPEORIENTATION_UPZ = 2; + CannonColliderShape.SHAPETYPES_BOX = 0; + CannonColliderShape.SHAPETYPES_SPHERE = 1; + CannonColliderShape.SHAPETYPES_CYLINDER = 2; + CannonColliderShape.SHAPETYPES_CAPSULE = 3; + CannonColliderShape.SHAPETYPES_CONVEXHULL = 4; + CannonColliderShape.SHAPETYPES_COMPOUND = 5; + CannonColliderShape.SHAPETYPES_STATICPLANE = 6; + CannonColliderShape.SHAPETYPES_CONE = 7; + CannonColliderShape._tempVector30 = new Laya.Vector3(); + + class CannonBoxColliderShape extends CannonColliderShape { + constructor(sizeX = 1.0, sizeY = 1.0, sizeZ = 1.0) { + super(); + this._sizeX = sizeX; + this._sizeY = sizeY; + this._sizeZ = sizeZ; + this._type = CannonColliderShape.SHAPETYPES_BOX; + var btsize = new CANNON.Vec3(sizeX / 2, sizeY / 2, sizeZ / 2); + this._btShape = new CANNON.Box(btsize); + } + static __init__() { + CannonBoxColliderShape._btSize = new CANNON.Vec3(); + } + get sizeX() { + return this._sizeX; + } + get sizeY() { + return this._sizeY; + } + get sizeZ() { + return this._sizeZ; + } + _setScale(scale) { + this._scale.setValue(scale.x, scale.y, scale.z); + this._btShape.halfExtents.set(this.sizeX / 2 * scale.x, this.sizeY / 2 * scale.y, this.sizeZ / 2 * scale.z); + this._btShape.updateConvexPolyhedronRepresentation(); + this._btShape.updateBoundingSphereRadius(); + } + clone() { + var dest = new CannonBoxColliderShape(this._sizeX, this._sizeY, this._sizeZ); + this.cloneTo(dest); + return dest; + } + } + + class CannonSphereColliderShape extends CannonColliderShape { + constructor(radius = 0.5) { + super(); + this._radius = radius; + this._type = CannonColliderShape.SHAPETYPES_SPHERE; + this._btShape = new CANNON.Sphere(radius); + } + get radius() { + return this._radius; + } + _setScale(scale) { + var max = Math.max(scale.x, scale.y, scale.z); + this._scale.setValue(max, max, max); + this._btShape.radius = max * this.radius; + this._btShape.updateBoundingSphereRadius(); + } + clone() { + var dest = new CannonSphereColliderShape(this._radius); + this.cloneTo(dest); + return dest; + } + } + + class CannonPhysicsComponent extends Laya.Component { + constructor(collisionGroup, canCollideWith) { + super(); + this._restitution = 0.0; + this._friction = 0.5; + this._collisionGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER; + this._canCollideWith = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER; + this._colliderShape = null; + this._transformFlag = 2147483647; + this._controlBySimulation = false; + this._enableProcessCollisions = true; + this._inPhysicUpdateListIndex = -1; + this.canScaleShape = true; + this._collisionGroup = collisionGroup; + this._canCollideWith = canCollideWith; + CannonPhysicsComponent._physicObjectsMap[this.id] = this; + } + static __init__() { + CannonPhysicsComponent._btVector30 = new CANNON.Vec3(0, 0, 0); + CannonPhysicsComponent._btQuaternion0 = new CANNON.Quaternion(0, 0, 0, 1); + } + static _creatShape(shapeData) { + var colliderShape; + switch (shapeData.type) { + case "BoxColliderShape": + var sizeData = shapeData.size; + colliderShape = sizeData ? new CannonBoxColliderShape(sizeData[0], sizeData[1], sizeData[2]) : new CannonBoxColliderShape(); + break; + case "SphereColliderShape": + colliderShape = new CannonSphereColliderShape(shapeData.radius); + break; + default: + throw "unknown shape type."; + } + if (shapeData.center) { + var localOffset = colliderShape.localOffset; + localOffset.fromArray(shapeData.center); + colliderShape.localOffset = localOffset; + } + return colliderShape; + } + static physicQuaternionMultiply(lx, ly, lz, lw, right, out) { + var rx = right.x; + var ry = right.y; + var rz = right.z; + var rw = right.w; + var a = (ly * rz - lz * ry); + var b = (lz * rx - lx * rz); + var c = (lx * ry - ly * rx); + var d = (lx * rx + ly * ry + lz * rz); + out.x = (lx * rw + rx * lw) + a; + out.y = (ly * rw + ry * lw) + b; + out.z = (lz * rw + rz * lw) + c; + out.w = lw * rw - d; + } + get restitution() { + return this._restitution; + } + set restitution(value) { + this._restitution = value; + this._btColliderObject && (this._btColliderObject.material.restitution = value); + } + get friction() { + return this._friction; + } + set friction(value) { + this._friction = value; + this._btColliderObject && (this._btColliderObject.material.friction = value); + } + get colliderShape() { + return this._colliderShape; + } + set colliderShape(value) { + var lastColliderShape = this._colliderShape; + if (lastColliderShape) { + lastColliderShape._attatched = false; + lastColliderShape._attatchedCollisionObject = null; + } + this._colliderShape = value; + if (value) { + if (value._attatched) { + throw "PhysicsComponent: this shape has attatched to other entity."; + } + else { + value._attatched = true; + value._attatchedCollisionObject = this; + } + if (this._btColliderObject) { + if (value.type != CannonColliderShape.SHAPETYPES_COMPOUND) { + this._btColliderObject.shapes.length = 0; + this._btColliderObject.shapeOffsets.length = 0; + this._btColliderObject.shapeOrientations.length = 0; + var localOffset = value.localOffset; + var scale = value._scale; + var vecs = new CANNON.Vec3(localOffset.x * scale.x, localOffset.y * scale.y, localOffset.z * scale.z); + this._btColliderObject.addShape(this._colliderShape._btShape, vecs); + this._btColliderObject.updateBoundingRadius(); + } + else { + value.bindRigidBody(this); + } + var canInSimulation = this._simulation && this._enabled; + (canInSimulation && lastColliderShape) && (this._removeFromSimulation()); + this._onShapeChange(value); + if (canInSimulation) { + this._derivePhysicsTransformation(true); + this._addToSimulation(); + } + } + } + else { + if (this._simulation && this._enabled) + lastColliderShape && this._removeFromSimulation(); + } + } + get simulation() { + return this._simulation; + } + get collisionGroup() { + return this._collisionGroup; + } + set collisionGroup(value) { + if (this._collisionGroup !== value) { + this._collisionGroup = value; + this._btColliderObject.collisionFilterGroup = value; + if (this._simulation && this._colliderShape && this._enabled) { + this._removeFromSimulation(); + this._addToSimulation(); + } + } + } + get canCollideWith() { + return this._canCollideWith; + } + set canCollideWith(value) { + if (this._canCollideWith !== value) { + this._canCollideWith = value; + this._btColliderObject.collisionFilterMask = value; + if (this._simulation && this._colliderShape && this._enabled) { + this._removeFromSimulation(); + this._addToSimulation(); + } + } + } + _parseShape(shapesData) { + var shapeCount = shapesData.length; + if (shapeCount === 1) { + var shape = CannonPhysicsComponent._creatShape(shapesData[0]); + this.colliderShape = shape; + } + } + _onScaleChange(scale) { + this._colliderShape._setScale(scale); + this._btColliderObject.updateBoundingRadius(); + } + _onEnable() { + this._simulation = this.owner._scene._cannonPhysicsSimulation; + if (this._colliderShape) { + this._derivePhysicsTransformation(true); + this._addToSimulation(); + } + } + _onDisable() { + if (this._colliderShape) { + this._removeFromSimulation(); + (this._inPhysicUpdateListIndex !== -1) && (this._simulation._physicsUpdateList.remove(this)); + } + this._simulation = null; + } + _onDestroy() { + delete CannonPhysicsComponent._physicObjectsMap[this.id]; + this._btColliderObject = null; + this._colliderShape.destroy(); + super._onDestroy(); + this._btColliderObject = null; + this._colliderShape = null; + this._simulation = null; + this.owner.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onTransformChanged); + } + _isValid() { + return this._simulation && this._colliderShape && this._enabled; + } + _parse(data) { + (data.collisionGroup != null) && (this.collisionGroup = data.collisionGroup); + (data.canCollideWith != null) && (this.canCollideWith = data.canCollideWith); + } + _setTransformFlag(type, value) { + if (value) + this._transformFlag |= type; + else + this._transformFlag &= ~type; + } + _getTransformFlag(type) { + return (this._transformFlag & type) != 0; + } + _addToSimulation() { + } + _removeFromSimulation() { + } + _derivePhysicsTransformation(force) { + var btColliderObject = this._btColliderObject; + this._innerDerivePhysicsTransformation(btColliderObject, force); + } + _innerDerivePhysicsTransformation(physicTransformOut, force) { + var transform = this.owner._transform; + if (force || this._getTransformFlag(Laya.Transform3D.TRANSFORM_WORLDPOSITION)) { + var shapeOffset = this._colliderShape.localOffset; + var position = transform.position; + var btPosition = CannonPhysicsComponent._btVector30; + if (shapeOffset.x !== 0 || shapeOffset.y !== 0 || shapeOffset.z !== 0) { + var physicPosition = CannonPhysicsComponent._tempVector30; + var worldMat = transform.worldMatrix; + Laya.Vector3.transformCoordinate(shapeOffset, worldMat, physicPosition); + btPosition.set(physicPosition.x, physicPosition.y, physicPosition.z); + } + else { + btPosition.set(position.x, position.y, position.z); + } + physicTransformOut.position.set(btPosition.x, btPosition.y, btPosition.z); + this._setTransformFlag(Laya.Transform3D.TRANSFORM_WORLDPOSITION, false); + } + if (force || this._getTransformFlag(Laya.Transform3D.TRANSFORM_WORLDQUATERNION)) { + var shapeRotation = this._colliderShape.localRotation; + var btRotation = CannonPhysicsComponent._btQuaternion0; + var rotation = transform.rotation; + if (shapeRotation.x !== 0 || shapeRotation.y !== 0 || shapeRotation.z !== 0 || shapeRotation.w !== 1) { + var physicRotation = CannonPhysicsComponent._tempQuaternion0; + CannonPhysicsComponent.physicQuaternionMultiply(rotation.x, rotation.y, rotation.z, rotation.w, shapeRotation, physicRotation); + btRotation.set(physicRotation.x, physicRotation.y, physicRotation.z, physicRotation.w); + } + else { + btRotation.set(rotation.x, rotation.y, rotation.z, rotation.w); + } + physicTransformOut.quaternion.set(btRotation.x, btRotation.y, btRotation.z, btRotation.w); + this._setTransformFlag(Laya.Transform3D.TRANSFORM_WORLDQUATERNION, false); + } + if (force || this._getTransformFlag(Laya.Transform3D.TRANSFORM_WORLDSCALE)) { + this._onScaleChange(transform.getWorldLossyScale()); + this._setTransformFlag(Laya.Transform3D.TRANSFORM_WORLDSCALE, false); + } + } + _updateTransformComponent(physicsTransform) { + var colliderShape = this._colliderShape; + var localOffset = colliderShape.localOffset; + var localRotation = colliderShape.localRotation; + var transform = this.owner._transform; + var position = transform.position; + var rotation = transform.rotation; + var btPosition = physicsTransform.position; + var btRotation = physicsTransform.quaternion; + var btRotX = btRotation.x; + var btRotY = btRotation.y; + var btRotZ = btRotation.z; + var btRotW = btRotation.w; + if (localRotation.x !== 0 || localRotation.y !== 0 || localRotation.z !== 0 || localRotation.w !== 1) { + var invertShapeRotaion = CannonPhysicsComponent._tempQuaternion0; + localRotation.invert(invertShapeRotaion); + CannonPhysicsComponent.physicQuaternionMultiply(btRotX, btRotY, btRotZ, btRotW, invertShapeRotaion, rotation); + } + else { + rotation.x = btRotX; + rotation.y = btRotY; + rotation.z = btRotZ; + rotation.w = btRotW; + } + transform.rotation = rotation; + if (localOffset.x !== 0 || localOffset.y !== 0 || localOffset.z !== 0) { + var rotShapePosition = CannonPhysicsComponent._tempVector30; + rotShapePosition.x = localOffset.x; + rotShapePosition.y = localOffset.y; + rotShapePosition.z = localOffset.z; + Laya.Vector3.transformQuat(rotShapePosition, rotation, rotShapePosition); + position.x = btPosition.x - rotShapePosition.x; + position.y = btPosition.y - rotShapePosition.z; + position.z = btPosition.z - rotShapePosition.y; + } + else { + position.x = btPosition.x; + position.y = btPosition.y; + position.z = btPosition.z; + } + transform.position = position; + } + _onShapeChange(colShape) { + } + _onAdded() { + this.enabled = this._enabled; + this.restitution = this._restitution; + this.friction = this._friction; + this.owner.transform.on(Laya.Event.TRANSFORM_CHANGED, this, this._onTransformChanged); + } + _onTransformChanged(flag) { + if (CannonPhysicsComponent._addUpdateList || !this._controlBySimulation) { + flag &= Laya.Transform3D.TRANSFORM_WORLDPOSITION | Laya.Transform3D.TRANSFORM_WORLDQUATERNION | Laya.Transform3D.TRANSFORM_WORLDSCALE; + if (flag) { + this._transformFlag |= flag; + if (this._isValid() && this._inPhysicUpdateListIndex === -1) + this._simulation._physicsUpdateList.add(this); + } + } + } + _cloneTo(dest) { + var destPhysicsComponent = dest; + destPhysicsComponent.restitution = this._restitution; + destPhysicsComponent.friction = this._friction; + destPhysicsComponent.collisionGroup = this._collisionGroup; + destPhysicsComponent.canCollideWith = this._canCollideWith; + destPhysicsComponent.canScaleShape = this.canScaleShape; + (this._colliderShape) && (destPhysicsComponent.colliderShape = this._colliderShape.clone()); + } + } + CannonPhysicsComponent.ACTIVATIONSTATE_ACTIVE_TAG = 1; + CannonPhysicsComponent.ACTIVATIONSTATE_ISLAND_SLEEPING = 2; + CannonPhysicsComponent.ACTIVATIONSTATE_WANTS_DEACTIVATION = 3; + CannonPhysicsComponent.ACTIVATIONSTATE_DISABLE_DEACTIVATION = 4; + CannonPhysicsComponent.ACTIVATIONSTATE_DISABLE_SIMULATION = 5; + CannonPhysicsComponent.COLLISIONFLAGS_STATIC_OBJECT = 1; + CannonPhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT = 2; + CannonPhysicsComponent.COLLISIONFLAGS_NO_CONTACT_RESPONSE = 4; + CannonPhysicsComponent.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK = 8; + CannonPhysicsComponent.COLLISIONFLAGS_CHARACTER_OBJECT = 16; + CannonPhysicsComponent.COLLISIONFLAGS_DISABLE_VISUALIZE_OBJECT = 32; + CannonPhysicsComponent.COLLISIONFLAGS_DISABLE_SPU_COLLISION_PROCESSING = 64; + CannonPhysicsComponent._tempVector30 = new Laya.Vector3(); + CannonPhysicsComponent._tempQuaternion0 = new Laya.Quaternion(); + CannonPhysicsComponent._tempQuaternion1 = new Laya.Quaternion(); + CannonPhysicsComponent._tempMatrix4x40 = new Laya.Matrix4x4(); + CannonPhysicsComponent._physicObjectsMap = {}; + CannonPhysicsComponent._addUpdateList = true; + + class CannonPhysicsTriggerComponent extends CannonPhysicsComponent { + constructor(collisionGroup, canCollideWith) { + super(collisionGroup, canCollideWith); + this._isTrigger = false; + } + get isTrigger() { + return this._isTrigger; + } + set isTrigger(value) { + this._isTrigger = value; + if (this._btColliderObject) { + this._btColliderObject.isTrigger = value; + if (value) { + var flag = this._btColliderObject.type; + this._btColliderObject.collisionResponse = false; + if ((flag & CANNON.Body.STATIC) === 0) + this._btColliderObject.type |= CANNON.Body.STATIC; + } + else { + this._btColliderObject.collisionResponse = true; + if ((flag & CANNON.Body.STATIC) !== 0) + this._btColliderObject.type ^= CANNON.Body.STATIC; + } + } + } + _onAdded() { + super._onAdded(); + this.isTrigger = this._isTrigger; + } + _cloneTo(dest) { + super._cloneTo(dest); + dest.isTrigger = this._isTrigger; + } + } + + class CannonPhysicsCollider extends CannonPhysicsTriggerComponent { + constructor(collisionGroup = -1, canCollideWith = -1) { + super(collisionGroup, canCollideWith); + this._enableProcessCollisions = false; + } + _addToSimulation() { + this._simulation._addPhysicsCollider(this); + } + _removeFromSimulation() { + this._simulation._removePhysicsCollider(this); + } + _parse(data) { + (data.friction != null) && (this.friction = data.friction); + (data.restitution != null) && (this.restitution = data.restitution); + (data.isTrigger != null) && (this.isTrigger = data.isTrigger); + super._parse(data); + this._parseShape(data.shapes); + } + _onAdded() { + this._btColliderObject = new CANNON.Body(); + this._btColliderObject.material = new CANNON.Material(); + this._btColliderObject.layaID = this._id; + this._btColliderObject.type = CANNON.Body.STATIC; + this._btColliderObject.collisionFilterGroup = this._collisionGroup; + this._btColliderObject.collisionFilterMask = this._canCollideWith; + super._onAdded(); + } + } + + class CannonPhysicsSettings { + constructor() { + this.flags = 0; + this.maxSubSteps = 3; + this.fixedTimeStep = 1.0 / 60.0; + this.contactEquationRelaxation = 10; + this.contactEquationStiffness = 1e6; + } + } + + class CannonPhysicsUpdateList extends Laya.SingletonList { + constructor() { + super(); + } + add(element) { + var index = element._inPhysicUpdateListIndex; + if (index !== -1) + throw "PhysicsUpdateList:element has in PhysicsUpdateList."; + this._add(element); + element._inPhysicUpdateListIndex = this.length++; + } + remove(element) { + var index = element._inPhysicUpdateListIndex; + this.length--; + if (index !== this.length) { + var end = this.elements[this.length]; + this.elements[index] = end; + end._inPhysicUpdateListIndex = index; + } + element._inPhysicUpdateListIndex = -1; + } + } + + class CannonPhysicsSimulation { + constructor(configuration) { + this._gravity = new Laya.Vector3(0, -10, 0); + this._btClosestRayResultCallback = new CANNON.RaycastResult(); + this._btRayoption = {}; + this._collisionsUtils = new CannonCollisionTool(); + this._previousFrameCollisions = []; + this._currentFrameCollisions = []; + this._physicsUpdateList = new CannonPhysicsUpdateList(); + this._updatedRigidbodies = 0; + this.maxSubSteps = 1; + this.fixedTimeStep = 1.0 / 60.0; + this.maxSubSteps = configuration.maxSubSteps; + this.fixedTimeStep = configuration.fixedTimeStep; + this._btDiscreteDynamicsWorld = new CANNON.World(); + this._btBroadphase = new CANNON.NaiveBroadphase(); + this._btDiscreteDynamicsWorld.broadphase = this._btBroadphase; + this._btDiscreteDynamicsWorld.defaultContactMaterial.contactEquationRelaxation = configuration.contactEquationRelaxation; + this._btDiscreteDynamicsWorld.defaultContactMaterial.contactEquationStiffness = configuration.contactEquationStiffness; + this.gravity = this._gravity; + CannonPhysicsSimulation._cannonPhysicsSimulation = this; + } + static __init__() { + CannonPhysicsSimulation._btTempVector30 = new CANNON.Vec3(0, 0, 0); + CannonPhysicsSimulation._btTempVector31 = new CANNON.Vec3(0, 0, 0); + } + static createConstraint() { + } + get gravity() { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + return this._gravity; + } + set gravity(value) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + this._gravity = value; + this._btDiscreteDynamicsWorld.gravity.set(value.x, value.y, value.z); + } + get solverIterations() { + if (!(this._btDiscreteDynamicsWorld && this._btDiscreteDynamicsWorld.solver)) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + return this._iterations; + } + set solverIterations(value) { + if (!(this._btDiscreteDynamicsWorld && this._btDiscreteDynamicsWorld.solver)) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + this._btDiscreteDynamicsWorld.solver.iterations = value; + this._iterations = value; + } + _simulate(deltaTime) { + this._updatedRigidbodies = 0; + if (this._btDiscreteDynamicsWorld) { + this._btDiscreteDynamicsWorld.callBackBody.length = 0; + this._btDiscreteDynamicsWorld.allContacts.length = 0; + this._btDiscreteDynamicsWorld.step(this.fixedTimeStep, deltaTime, this.maxSubSteps); + } + var callBackBody = this._btDiscreteDynamicsWorld.callBackBody; + for (var i = 0, n = callBackBody.length; i < n; i++) { + var cannonBody = callBackBody[i]; + var rigidbody = CannonPhysicsComponent._physicObjectsMap[cannonBody.layaID]; + rigidbody._simulation._updatedRigidbodies++; + rigidbody._updateTransformComponent(rigidbody._btColliderObject); + } + } + _destroy() { + this._btDiscreteDynamicsWorld = null; + this._btBroadphase = null; + } + _addPhysicsCollider(component) { + this._btDiscreteDynamicsWorld.addBody(component._btColliderObject); + } + _removePhysicsCollider(component) { + this._btDiscreteDynamicsWorld.removeBody(component._btColliderObject); + } + _addRigidBody(rigidBody) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + this._btDiscreteDynamicsWorld.addBody(rigidBody._btColliderObject); + } + _removeRigidBody(rigidBody) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + this._btDiscreteDynamicsWorld.removeBody(rigidBody._btColliderObject); + } + raycastFromTo(from, to, out = null, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + var rayResultCall = this._btClosestRayResultCallback; + rayResultCall.hasHit = false; + var rayOptions = this._btRayoption; + var rayFrom = CannonPhysicsSimulation._btTempVector30; + var rayTo = CannonPhysicsSimulation._btTempVector31; + rayFrom.set(from.x, from.y, from.z); + rayTo.set(to.x, to.y, to.z); + rayOptions.skipBackfaces = true; + rayOptions.collisionFilterMask = collisionMask; + rayOptions.collisionFilterGroup = collisonGroup; + rayOptions.result = rayResultCall; + this._btDiscreteDynamicsWorld.raycastClosest(rayFrom, rayTo, rayOptions, rayResultCall); + if (rayResultCall.hasHit) { + if (out) { + out.succeeded = true; + out.collider = CannonPhysicsComponent._physicObjectsMap[rayResultCall.body.layaID]; + var point = out.point; + var normal = out.normal; + var resultPoint = rayResultCall.hitPointWorld; + var resultNormal = rayResultCall.hitNormalWorld; + point.setValue(resultPoint.x, resultPoint.y, resultPoint.z); + normal.setValue(resultNormal.x, resultNormal.y, resultNormal.z); + } + return true; + } + else { + out.succeeded = false; + } + return false; + } + raycastAllFromTo(from, to, out, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + var rayOptions = this._btRayoption; + var rayFrom = CannonPhysicsSimulation._btTempVector30; + var rayTo = CannonPhysicsSimulation._btTempVector31; + rayFrom.set(from.x, from.y, from.z); + rayTo.set(to.x, to.y, to.z); + rayOptions.skipBackfaces = true; + rayOptions.collisionFilterMask = collisionMask; + rayOptions.collisionFilterGroup = collisonGroup; + out.length = 0; + this._btDiscreteDynamicsWorld.raycastAll(rayFrom, rayTo, rayOptions, function (result) { + var hitResult = CannonPhysicsSimulation._cannonPhysicsSimulation._collisionsUtils.getHitResult(); + out.push(hitResult); + hitResult.succeeded = true; + hitResult.collider = CannonPhysicsComponent._physicObjectsMap[result.body.layaID]; + var point = hitResult.point; + var normal = hitResult.normal; + var resultPoint = result.hitPointWorld; + var resultNormal = result.hitNormalWorld; + point.setValue(resultPoint.x, resultPoint.y, resultPoint.z); + normal.setValue(resultNormal.x, resultNormal.y, resultNormal.z); + }); + if (out.length != 0) + return true; + else + return false; + } + rayCast(ray, outHitResult = null, distance = 2147483647, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + var from = ray.origin; + var to = CannonPhysicsSimulation._tempVector30; + Laya.Vector3.normalize(ray.direction, to); + Laya.Vector3.scale(to, distance, to); + Laya.Vector3.add(from, to, to); + return this.raycastFromTo(from, to, outHitResult, collisonGroup, collisionMask); + } + rayCastAll(ray, out, distance = 2147483647, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + var from = ray.origin; + var to = CannonPhysicsSimulation._tempVector30; + Laya.Vector3.normalize(ray.direction, to); + Laya.Vector3.scale(to, distance, to); + Laya.Vector3.add(from, to, to); + return this.raycastAllFromTo(from, to, out, collisonGroup, collisionMask); + } + _updatePhysicsTransformFromRender() { + var elements = this._physicsUpdateList.elements; + for (var i = 0, n = this._physicsUpdateList.length; i < n; i++) { + var physicCollider = elements[i]; + physicCollider._derivePhysicsTransformation(false); + physicCollider._inPhysicUpdateListIndex = -1; + } + this._physicsUpdateList.length = 0; + } + _updateCollisions() { + this._collisionsUtils.recoverAllContactPointsPool(); + var previous = this._currentFrameCollisions; + this._currentFrameCollisions = this._previousFrameCollisions; + this._currentFrameCollisions.length = 0; + this._previousFrameCollisions = previous; + var loopCount = Laya.Stat.loopCount; + var allContacts = this._btDiscreteDynamicsWorld.allContacts; + var numManifolds = allContacts.length; + for (var i = 0; i < numManifolds; i++) { + var contactEquation = allContacts[i]; + var componentA = CannonPhysicsComponent._physicObjectsMap[contactEquation.bi.layaID]; + var componentB = CannonPhysicsComponent._physicObjectsMap[contactEquation.bj.layaID]; + var collision = null; + var isFirstCollision; + var contacts = null; + var isTrigger = componentA.isTrigger || componentB.isTrigger; + if (isTrigger && (componentA.owner._needProcessTriggers || componentB.owner._needProcessTriggers)) { + collision = this._collisionsUtils.getCollision(componentA, componentB); + contacts = collision.contacts; + isFirstCollision = collision._updateFrame !== loopCount; + if (isFirstCollision) { + collision._isTrigger = true; + contacts.length = 0; + } + } + else if (componentA.owner._needProcessCollisions || componentB.owner._needProcessCollisions) { + if (componentA._enableProcessCollisions || componentB._enableProcessCollisions) { + var contactPoint = this._collisionsUtils.getContactPoints(); + contactPoint.colliderA = componentA; + contactPoint.colliderB = componentB; + var normal = contactPoint.normal; + var positionOnA = contactPoint.positionOnA; + var positionOnB = contactPoint.positionOnB; + var connectNormal = contactEquation.ni; + var connectOnA = contactEquation.ri; + var connectOnB = contactEquation.rj; + normal.setValue(connectNormal.x, connectNormal.y, connectNormal.z); + positionOnA.setValue(connectOnA.x, connectOnA.y, connectOnA.z); + positionOnB.setValue(connectOnB.x, connectOnB.y, -connectOnB.z); + collision = this._collisionsUtils.getCollision(componentA, componentB); + contacts = collision.contacts; + isFirstCollision = collision._updateFrame !== loopCount; + if (isFirstCollision) { + collision._isTrigger = false; + contacts.length = 0; + } + contacts.push(contactPoint); + } + } + if (collision && isFirstCollision) { + this._currentFrameCollisions.push(collision); + collision._setUpdateFrame(loopCount); + } + } + } + _eventScripts() { + var loopCount = Laya.Stat.loopCount; + for (var i = 0, n = this._currentFrameCollisions.length; i < n; i++) { + var curFrameCol = this._currentFrameCollisions[i]; + var colliderA = curFrameCol._colliderA; + var colliderB = curFrameCol._colliderB; + if (colliderA.destroyed || colliderB.destroyed) + continue; + if (loopCount - curFrameCol._lastUpdateFrame === 1) { + var ownerA = colliderA.owner; + var scriptsA = ownerA._scripts; + if (scriptsA) { + if (curFrameCol._isTrigger) { + if (ownerA._needProcessTriggers) { + for (var j = 0, m = scriptsA.length; j < m; j++) + scriptsA[j].onTriggerStay(colliderB); + } + } + else { + if (ownerA._needProcessCollisions) { + for (j = 0, m = scriptsA.length; j < m; j++) { + curFrameCol.other = colliderB; + scriptsA[j].onCollisionStay(curFrameCol); + } + } + } + } + var ownerB = colliderB.owner; + var scriptsB = ownerB._scripts; + if (scriptsB) { + if (curFrameCol._isTrigger) { + if (ownerB._needProcessTriggers) { + for (j = 0, m = scriptsB.length; j < m; j++) + scriptsB[j].onTriggerStay(colliderA); + } + } + else { + if (ownerB._needProcessCollisions) { + for (j = 0, m = scriptsB.length; j < m; j++) { + curFrameCol.other = colliderA; + scriptsB[j].onCollisionStay(curFrameCol); + } + } + } + } + } + else { + ownerA = colliderA.owner; + scriptsA = ownerA._scripts; + if (scriptsA) { + if (curFrameCol._isTrigger) { + if (ownerA._needProcessTriggers) { + for (j = 0, m = scriptsA.length; j < m; j++) + scriptsA[j].onTriggerEnter(colliderB); + } + } + else { + if (ownerA._needProcessCollisions) { + for (j = 0, m = scriptsA.length; j < m; j++) { + curFrameCol.other = colliderB; + scriptsA[j].onCollisionEnter(curFrameCol); + } + } + } + } + ownerB = colliderB.owner; + scriptsB = ownerB._scripts; + if (scriptsB) { + if (curFrameCol._isTrigger) { + if (ownerB._needProcessTriggers) { + for (j = 0, m = scriptsB.length; j < m; j++) + scriptsB[j].onTriggerEnter(colliderA); + } + } + else { + if (ownerB._needProcessCollisions) { + for (j = 0, m = scriptsB.length; j < m; j++) { + curFrameCol.other = colliderA; + scriptsB[j].onCollisionEnter(curFrameCol); + } + } + } + } + } + } + for (i = 0, n = this._previousFrameCollisions.length; i < n; i++) { + var preFrameCol = this._previousFrameCollisions[i]; + var preColliderA = preFrameCol._colliderA; + var preColliderB = preFrameCol._colliderB; + if (preColliderA.destroyed || preColliderB.destroyed) + continue; + if (loopCount - preFrameCol._updateFrame === 1) { + this._collisionsUtils.recoverCollision(preFrameCol); + ownerA = preColliderA.owner; + scriptsA = ownerA._scripts; + if (scriptsA) { + if (preFrameCol._isTrigger) { + if (ownerA._needProcessTriggers) { + for (j = 0, m = scriptsA.length; j < m; j++) + scriptsA[j].onTriggerExit(preColliderB); + } + } + else { + if (ownerA._needProcessCollisions) { + for (j = 0, m = scriptsA.length; j < m; j++) { + preFrameCol.other = preColliderB; + scriptsA[j].onCollisionExit(preFrameCol); + } + } + } + } + ownerB = preColliderB.owner; + scriptsB = ownerB._scripts; + if (scriptsB) { + if (preFrameCol._isTrigger) { + if (ownerB._needProcessTriggers) { + for (j = 0, m = scriptsB.length; j < m; j++) + scriptsB[j].onTriggerExit(preColliderA); + } + } + else { + if (ownerB._needProcessCollisions) { + for (j = 0, m = scriptsB.length; j < m; j++) { + preFrameCol.other = preColliderA; + scriptsB[j].onCollisionExit(preFrameCol); + } + } + } + } + } + } + } + clearForces() { + if (!this._btDiscreteDynamicsWorld) + throw "Cannot perform this action when the physics engine is set to CollisionsOnly"; + } + } + CannonPhysicsSimulation.PHYSICSENGINEFLAGS_NONE = 0x0; + CannonPhysicsSimulation.PHYSICSENGINEFLAGS_COLLISIONSONLY = 0x1; + CannonPhysicsSimulation.PHYSICSENGINEFLAGS_SOFTBODYSUPPORT = 0x2; + CannonPhysicsSimulation.PHYSICSENGINEFLAGS_MULTITHREADED = 0x4; + CannonPhysicsSimulation.PHYSICSENGINEFLAGS_USEHARDWAREWHENPOSSIBLE = 0x8; + CannonPhysicsSimulation.SOLVERMODE_RANDMIZE_ORDER = 1; + CannonPhysicsSimulation.SOLVERMODE_FRICTION_SEPARATE = 2; + CannonPhysicsSimulation.SOLVERMODE_USE_WARMSTARTING = 4; + CannonPhysicsSimulation.SOLVERMODE_USE_2_FRICTION_DIRECTIONS = 16; + CannonPhysicsSimulation.SOLVERMODE_ENABLE_FRICTION_DIRECTION_CACHING = 32; + CannonPhysicsSimulation.SOLVERMODE_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION = 64; + CannonPhysicsSimulation.SOLVERMODE_CACHE_FRIENDLY = 128; + CannonPhysicsSimulation.SOLVERMODE_SIMD = 256; + CannonPhysicsSimulation.SOLVERMODE_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS = 512; + CannonPhysicsSimulation.SOLVERMODE_ALLOW_ZERO_LENGTH_FRICTION_DIRECTIONS = 1024; + CannonPhysicsSimulation._tempVector30 = new Laya.Vector3(); + CannonPhysicsSimulation.disableSimulation = false; + + class CannonRigidbody3D extends CannonPhysicsCollider { + constructor(collisionGroup = -1, canCollideWith = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + super(collisionGroup, canCollideWith); + this._isKinematic = false; + this._mass = 1.0; + this._gravity = new Laya.Vector3(0, -10, 0); + this._angularDamping = 0.0; + this._linearDamping = 0.0; + this._totalTorque = new Laya.Vector3(0, 0, 0); + this._totalForce = new Laya.Vector3(0, 0, 0); + this._linearVelocity = new Laya.Vector3(); + this._angularVelocity = new Laya.Vector3(); + this._controlBySimulation = true; + } + static __init__() { + CannonRigidbody3D._btTempVector30 = new CANNON.Vec3(); + CannonRigidbody3D._btTempVector31 = new CANNON.Vec3(); + } + get mass() { + return this._mass; + } + set mass(value) { + value = Math.max(value, 1e-07); + this._mass = value; + (this._isKinematic) || (this._updateMass(value)); + } + get isKinematic() { + return this._isKinematic; + } + set isKinematic(value) { + this._isKinematic = value; + this._controlBySimulation = !value; + var canInSimulation = !!(this._simulation && this._enabled && this._colliderShape); + canInSimulation && this._removeFromSimulation(); + var natColObj = this._btColliderObject; + var flags = natColObj.type; + if (value) { + flags = flags | CANNON.Body.KINEMATIC; + natColObj.type = flags; + this._enableProcessCollisions = false; + this._updateMass(0); + } + else { + if ((flags & CANNON.Body.KINEMATIC) > 0) + flags = flags ^ CANNON.Body.KINEMATIC; + natColObj.allowSleep = true; + natColObj.type = flags; + this._enableProcessCollisions = true; + this._updateMass(this._mass); + } + natColObj.velocity.set(0.0, 0.0, 0.0); + natColObj.angularVelocity.set(0.0, 0.0, 0.0); + canInSimulation && this._addToSimulation(); + } + get linearDamping() { + return this._linearDamping; + } + set linearDamping(value) { + this._linearDamping = value; + if (this._btColliderObject) + this._btColliderObject.linearDamping = value; + } + get angularDamping() { + return this._angularDamping; + } + set angularDamping(value) { + this._angularDamping = value; + if (this._btColliderObject) + this._btColliderObject.angularDamping = value; + } + get totalForce() { + if (this._btColliderObject) { + var btTotalForce = this.btColliderObject.force; + this.totalForce.setValue(btTotalForce.x, btTotalForce.y, btTotalForce.z); + return this._totalForce; + } + return null; + } + get linearVelocity() { + if (this._btColliderObject) { + var phylinear = this.btColliderObject.velocity; + this._linearVelocity.setValue(phylinear.x, phylinear.y, phylinear.z); + } + return this._linearVelocity; + } + set linearVelocity(value) { + this._linearVelocity = value; + if (this._btColliderObject) { + var btValue = this.btColliderObject.velocity; + (this.isSleeping) && (this.wakeUp()); + btValue.set(value.x, value.y, value.z); + this.btColliderObject.velocity = btValue; + } + } + get angularVelocity() { + if (this._btColliderObject) { + var phtqua = this._btColliderObject.angularVelocity; + this.angularVelocity.setValue(phtqua.x, phtqua.y, phtqua.z); + } + return this._angularVelocity; + } + set angularVelocity(value) { + this._angularVelocity = value; + if (this._btColliderObject) { + var btValue = this.btColliderObject.angularVelocity; + (this.isSleeping) && (this.wakeUp()); + btValue.set(value.x, value.y, value.z); + this.btColliderObject.angularVelocity = btValue; + } + } + get totalTorque() { + if (this._btColliderObject) { + var btTotalTorque = this._btColliderObject.torque; + this._totalTorque.setValue(btTotalTorque.x, btTotalTorque.y, btTotalTorque.z); + return this._totalTorque; + } + return null; + } + get isSleeping() { + if (this._btColliderObject) + return this._btColliderObject.sleepState != CANNON.Body.AWAKE; + return false; + } + get sleepLinearVelocity() { + return this._btColliderObject.sleepSpeedLimit; + } + set sleepLinearVelocity(value) { + this._btColliderObject.sleepSpeedLimit = value; + } + get btColliderObject() { + return this._btColliderObject; + } + _updateMass(mass) { + if (this._btColliderObject && this._colliderShape) { + this._btColliderObject.mass = mass; + this._btColliderObject.updateMassProperties(); + this._btColliderObject.updateSolveMassProperties(); + } + } + _onScaleChange(scale) { + super._onScaleChange(scale); + this._updateMass(this._isKinematic ? 0 : this._mass); + } + _derivePhysicsTransformation(force) { + this._innerDerivePhysicsTransformation(this.btColliderObject, force); + } + _onAdded() { + var btRigid = new CANNON.Body(); + btRigid.material = new CANNON.Material(); + btRigid.layaID = this.id; + btRigid.collisionFilterGroup = this.collisionGroup; + btRigid.collisionFilterMask = this._canCollideWith; + this._btColliderObject = btRigid; + super._onAdded(); + this.mass = this._mass; + this.linearDamping = this._linearDamping; + this.angularDamping = this._angularDamping; + this.isKinematic = this._isKinematic; + if (!this.isKinematic) + this._btColliderObject.type = CANNON.Body.DYNAMIC; + else + this._btColliderObject.type = CANNON.Body.KINEMATIC; + } + _onShapeChange(colShape) { + super._onShapeChange(colShape); + if (this._isKinematic) { + this._updateMass(0); + } + else { + this._updateMass(this._mass); + } + } + _parse(data) { + (data.friction != null) && (this.friction = data.friction); + (data.restitution != null) && (this.restitution = data.restitution); + (data.isTrigger != null) && (this.isTrigger = data.isTrigger); + (data.mass != null) && (this.mass = data.mass); + (data.isKinematic != null) && (this.isKinematic = data.isKinematic); + (data.linearDamping != null) && (this.linearDamping = data.linearDamping); + (data.angularDamping != null) && (this.angularDamping = data.angularDamping); + super._parse(data); + this._parseShape(data.shapes); + } + _onDestroy() { + super._onDestroy(); + this._gravity = null; + this._totalTorque = null; + this._linearVelocity = null; + this._angularVelocity = null; + } + _addToSimulation() { + this._simulation._addRigidBody(this); + } + _removeFromSimulation() { + this._simulation._removeRigidBody(this); + } + _cloneTo(dest) { + super._cloneTo(dest); + var destRigidbody3D = dest; + destRigidbody3D.isKinematic = this._isKinematic; + destRigidbody3D.mass = this._mass; + destRigidbody3D.angularDamping = this._angularDamping; + destRigidbody3D.linearDamping = this._linearDamping; + destRigidbody3D.linearVelocity = this._linearVelocity; + destRigidbody3D.angularVelocity = this._angularVelocity; + } + applyForce(force, localOffset = null) { + if (this._btColliderObject == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + var btForce = CannonRigidbody3D._btTempVector30; + btForce.set(force.x, force.y, force.z); + var btOffset = CannonRigidbody3D._btTempVector31; + if (localOffset) + btOffset.set(localOffset.x, localOffset.y, localOffset.z); + else + btOffset.set(0.0, 0.0, 0.0); + this.btColliderObject.applyLocalForce(btForce, btOffset); + } + applyTorque(torque) { + if (this._btColliderObject == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + var btTorque = CannonRigidbody3D._btTempVector30; + btTorque.set(torque.x, torque.y, torque.z); + var oriTorque = this.btColliderObject.torque; + oriTorque.set(oriTorque.x + btTorque.x, oriTorque.y + btTorque.y, oriTorque.z + btTorque.z); + this.btColliderObject.torque = oriTorque; + } + applyImpulse(impulse, localOffset = null) { + if (this._btColliderObject == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + if (this._btColliderObject == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + var btForce = CannonRigidbody3D._btTempVector30; + btForce.set(impulse.x, impulse.y, impulse.z); + var btOffset = CannonRigidbody3D._btTempVector31; + if (localOffset) + btOffset.set(localOffset.x, localOffset.y, localOffset.z); + else + btOffset.set(0.0, 0.0, 0.0); + this.btColliderObject.applyImpulse(btForce, btOffset); + } + wakeUp() { + this._btColliderObject && this._btColliderObject.wakeUp(); + } + clearForces() { + var rigidBody = this._btColliderObject; + if (rigidBody == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + rigidBody.velocity.set(0.0, 0.0, 0.0); + rigidBody.velocity = rigidBody.velocity; + rigidBody.angularVelocity.set(0.0, 0.0, 0.0); + rigidBody.angularVelocity = rigidBody.angularVelocity; + } + } + CannonRigidbody3D.TYPE_STATIC = 0; + CannonRigidbody3D.TYPE_DYNAMIC = 1; + CannonRigidbody3D.TYPE_KINEMATIC = 2; + CannonRigidbody3D._BT_DISABLE_WORLD_GRAVITY = 1; + CannonRigidbody3D._BT_ENABLE_GYROPSCOPIC_FORCE = 2; + + class CannonCompoundColliderShape extends CannonColliderShape { + constructor() { + super(); + this._childColliderShapes = []; + this._type = CannonColliderShape.SHAPETYPES_COMPOUND; + } + static __init__() { + } + _clearChildShape(shape) { + shape._attatched = false; + shape._compoundParent = null; + shape._indexInCompound = -1; + } + _addReference() { + this._referenceCount++; + } + _removeReference() { + this._referenceCount--; + } + addChildShape(shape, localOffset = null) { + if (shape._attatched) + throw "CompoundColliderShape: this shape has attatched to other entity."; + shape._attatched = true; + shape._compoundParent = this; + shape._indexInCompound = this._childColliderShapes.length; + this._childColliderShapes.push(shape); + shape.localOffset = localOffset; + if (this.physicColliderObject) { + CannonCompoundColliderShape._tempCannonQue.set(0, 0, 0, 1); + CannonCompoundColliderShape._tempCannonVec.set(localOffset.x * this._scale.x, localOffset.y * this._scale.y, localOffset.z * this._scale.z); + this.physicColliderObject._btColliderObject.addShape(shape._btShape, CannonCompoundColliderShape._tempCannonVec, CANNON.Vec3.ZERO); + } + } + removeChildShape(shape) { + if (shape._compoundParent === this) { + var index = shape._indexInCompound; + this._clearChildShape(shape); + var endShape = this._childColliderShapes[this._childColliderShapes.length - 1]; + endShape._indexInCompound = index; + this._childColliderShapes[index] = endShape; + this._childColliderShapes.pop(); + if (this.physicColliderObject) + this.bindRigidBody(this.physicColliderObject); + } + } + bindRigidBody(rigidbody) { + this.physicColliderObject = rigidbody; + var body = rigidbody._btColliderObject; + body.shapes.length = 0; + body.shapeOffsets.length = 0; + body.shapeOrientations.length = 0; + var origoffset; + for (var i = 0, n = this._childColliderShapes.length; i != n; i++) { + var shape = this._childColliderShapes[i]; + body.shapes.push(shape._btShape); + origoffset = shape.localOffset; + body.shapeOffsets.push(new CANNON.Vec3(origoffset.x * this._scale.x, origoffset.y * this._scale.y, origoffset.z * this._scale.z)); + body.shapeOrientations.push(CannonCompoundColliderShape._tempCannonQue); + } + body.updateMassProperties(); + body.updateBoundingRadius(); + body.aabbNeedsUpdate = true; + } + _setScale(scale) { + this._scale.setValue(scale.x, scale.y, scale.z); + var body = this.physicColliderObject._btColliderObject; + var length = this.getChildShapeCount(); + var shapeoffsets = body.shapeOffsets; + for (var i = 0; i < length; i++) { + var offset = shapeoffsets[i]; + var shape = this._childColliderShapes[i]; + shape._setScale(scale); + var orioffset = shape.localOffset; + offset.set(orioffset.x * scale.x, orioffset.y * scale.y, orioffset.z * scale.z); + } + body.updateMassProperties(); + body.updateBoundingRadius(); + body.aabbNeedsUpdate = true; + } + getChildShapeCount() { + return this._childColliderShapes.length; + } + cloneTo(destObject) { + var destCompoundColliderShape = destObject; + for (var i = 0, n = this._childColliderShapes.length; i < n; i++) + destCompoundColliderShape.addChildShape(this._childColliderShapes[i].clone()); + } + clone() { + var dest = new CannonCompoundColliderShape(); + this.cloneTo(dest); + return dest; + } + destroy() { + super.destroy(); + for (var i = 0, n = this._childColliderShapes.length; i < n; i++) { + var childShape = this._childColliderShapes[i]; + if (childShape._referenceCount === 0) + childShape.destroy(); + } + } + } + CannonCompoundColliderShape._tempCannonQue = new CANNON.Quaternion(0, 0, 0, 1); + CannonCompoundColliderShape._tempCannonVec = new CANNON.Vec3(0, 0, 0); + + exports.CannonBoxColliderShape = CannonBoxColliderShape; + exports.CannonColliderShape = CannonColliderShape; + exports.CannonCollision = CannonCollision; + exports.CannonCollisionTool = CannonCollisionTool; + exports.CannonCompoundColliderShape = CannonCompoundColliderShape; + exports.CannonContactPoint = CannonContactPoint; + exports.CannonHitResult = CannonHitResult; + exports.CannonPhysicsCollider = CannonPhysicsCollider; + exports.CannonPhysicsComponent = CannonPhysicsComponent; + exports.CannonPhysicsSettings = CannonPhysicsSettings; + exports.CannonPhysicsSimulation = CannonPhysicsSimulation; + exports.CannonPhysicsTriggerComponent = CannonPhysicsTriggerComponent; + exports.CannonPhysicsUpdateList = CannonPhysicsUpdateList; + exports.CannonRigidbody3D = CannonRigidbody3D; + exports.CannonSphereColliderShape = CannonSphereColliderShape; + +}(window.Laya = window.Laya || {}, Laya)); diff --git a/examples/layaair/frontend/bin/libs/laya.core.js b/examples/layaair/frontend/bin/libs/laya.core.js new file mode 100644 index 0000000..1cc436a --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.core.js @@ -0,0 +1,26606 @@ +window.Laya= (function (exports) { + 'use strict'; + + class Config { + } + Config.animationInterval = 50; + Config.isAntialias = true; + Config.isAlpha = false; + Config.premultipliedAlpha = true; + Config.isStencil = true; + Config.preserveDrawingBuffer = false; + Config.webGL2D_MeshAllocMaxMem = true; + Config.is2DPixelArtGame = false; + Config.useWebGL2 = true; + Config.printWebglOrder = false; + Config.allowGPUInstanceDynamicBatch = true; + Config.enableStaticBatch = true; + Config.useRetinalCanvas = false; + window.Config = Config; + + class ILaya { + static regClass(c) { + ILaya.__classMap[c.name] = c; + } + } + ILaya.Laya = null; + ILaya.Timer = null; + ILaya.WorkerLoader = null; + ILaya.Dragging = null; + ILaya.GraphicsBounds = null; + ILaya.Sprite = null; + ILaya.TextRender = null; + ILaya.TextAtlas = null; + ILaya.timer = null; + ILaya.systemTimer = null; + ILaya.startTimer = null; + ILaya.updateTimer = null; + ILaya.lateTimer = null; + ILaya.physicsTimer = null; + ILaya.stage = null; + ILaya.Loader = null; + ILaya.loader = null; + ILaya.TTFLoader = null; + ILaya.SoundManager = null; + ILaya.WebAudioSound = null; + ILaya.AudioSound = null; + ILaya.ShaderCompile = null; + ILaya.ClassUtils = null; + ILaya.SceneUtils = null; + ILaya.Context = null; + ILaya.Render = null; + ILaya.MouseManager = null; + ILaya.Text = null; + ILaya.Browser = null; + ILaya.WebGL = null; + ILaya.Pool = null; + ILaya.Utils = null; + ILaya.Graphics = null; + ILaya.Submit = null; + ILaya.Stage = null; + ILaya.Resource = null; + ILaya.__classMap = {}; + + class Pool { + static getPoolBySign(sign) { + return Pool._poolDic[sign] || (Pool._poolDic[sign] = []); + } + static clearBySign(sign) { + if (Pool._poolDic[sign]) + Pool._poolDic[sign].length = 0; + } + static recover(sign, item) { + if (item[Pool.POOLSIGN]) + return; + item[Pool.POOLSIGN] = true; + Pool.getPoolBySign(sign).push(item); + } + static recoverByClass(instance) { + if (instance) { + var className = instance["__className"] || instance.constructor._$gid; + if (className) + Pool.recover(className, instance); + } + } + static _getClassSign(cla) { + var className = cla["__className"] || cla["_$gid"]; + if (!className) { + cla["_$gid"] = className = Pool._CLSID + ""; + Pool._CLSID++; + } + return className; + } + static createByClass(cls) { + return Pool.getItemByClass(Pool._getClassSign(cls), cls); + } + static getItemByClass(sign, cls) { + if (!Pool._poolDic[sign]) + return new cls(); + var pool = Pool.getPoolBySign(sign); + if (pool.length) { + var rst = pool.pop(); + rst[Pool.POOLSIGN] = false; + } + else { + rst = new cls(); + } + return rst; + } + static getItemByCreateFun(sign, createFun, caller = null) { + var pool = Pool.getPoolBySign(sign); + var rst = pool.length ? pool.pop() : createFun.call(caller); + rst[Pool.POOLSIGN] = false; + return rst; + } + static getItem(sign) { + var pool = Pool.getPoolBySign(sign); + var rst = pool.length ? pool.pop() : null; + if (rst) { + rst[Pool.POOLSIGN] = false; + } + return rst; + } + } + Pool._CLSID = 0; + Pool.POOLSIGN = "__InPool"; + Pool._poolDic = {}; + + class AlphaCmd { + static create(alpha) { + var cmd = Pool.getItemByClass("AlphaCmd", AlphaCmd); + cmd.alpha = alpha; + return cmd; + } + recover() { + Pool.recover("AlphaCmd", this); + } + run(context, gx, gy) { + context.alpha(this.alpha); + } + get cmdID() { + return AlphaCmd.ID; + } + } + AlphaCmd.ID = "Alpha"; + + class DrawCircleCmd { + static create(x, y, radius, fillColor, lineColor, lineWidth, vid) { + var cmd = Pool.getItemByClass("DrawCircleCmd", DrawCircleCmd); + cmd.x = x; + cmd.y = y; + cmd.radius = radius; + cmd.fillColor = fillColor; + cmd.lineColor = lineColor; + cmd.lineWidth = lineWidth; + cmd.vid = vid; + return cmd; + } + recover() { + this.fillColor = null; + this.lineColor = null; + Pool.recover("DrawCircleCmd", this); + } + run(context, gx, gy) { + context._drawCircle(this.x + gx, this.y + gy, this.radius, this.fillColor, this.lineColor, this.lineWidth, this.vid); + } + get cmdID() { + return DrawCircleCmd.ID; + } + } + DrawCircleCmd.ID = "DrawCircle"; + + class DrawCurvesCmd { + static create(x, y, points, lineColor, lineWidth) { + var cmd = Pool.getItemByClass("DrawCurvesCmd", DrawCurvesCmd); + cmd.x = x; + cmd.y = y; + cmd.points = points; + cmd.lineColor = lineColor; + cmd.lineWidth = lineWidth; + return cmd; + } + recover() { + this.points = null; + this.lineColor = null; + Pool.recover("DrawCurvesCmd", this); + } + run(context, gx, gy) { + if (this.points) + context.drawCurves(this.x + gx, this.y + gy, this.points, this.lineColor, this.lineWidth); + } + get cmdID() { + return DrawCurvesCmd.ID; + } + } + DrawCurvesCmd.ID = "DrawCurves"; + + class DrawImageCmd { + static create(texture, x, y, width, height) { + var cmd = Pool.getItemByClass("DrawImageCmd", DrawImageCmd); + cmd.texture = texture; + texture._addReference(); + cmd.x = x; + cmd.y = y; + cmd.width = width; + cmd.height = height; + return cmd; + } + recover() { + this.texture && this.texture._removeReference(); + this.texture = null; + Pool.recover("DrawImageCmd", this); + } + run(context, gx, gy) { + if (this.texture) + context.drawTexture(this.texture, this.x + gx, this.y + gy, this.width, this.height); + } + get cmdID() { + return DrawImageCmd.ID; + } + } + DrawImageCmd.ID = "DrawImage"; + + class DrawLineCmd { + static create(fromX, fromY, toX, toY, lineColor, lineWidth, vid) { + var cmd = Pool.getItemByClass("DrawLineCmd", DrawLineCmd); + cmd.fromX = fromX; + cmd.fromY = fromY; + cmd.toX = toX; + cmd.toY = toY; + cmd.lineColor = lineColor; + cmd.lineWidth = lineWidth; + cmd.vid = vid; + return cmd; + } + recover() { + Pool.recover("DrawLineCmd", this); + } + run(context, gx, gy) { + context._drawLine(gx, gy, this.fromX, this.fromY, this.toX, this.toY, this.lineColor, this.lineWidth, this.vid); + } + get cmdID() { + return DrawLineCmd.ID; + } + } + DrawLineCmd.ID = "DrawLine"; + + class DrawLinesCmd { + static create(x, y, points, lineColor, lineWidth, vid) { + var cmd = Pool.getItemByClass("DrawLinesCmd", DrawLinesCmd); + cmd.x = x; + cmd.y = y; + cmd.points = points; + cmd.lineColor = lineColor; + cmd.lineWidth = lineWidth; + cmd.vid = vid; + return cmd; + } + recover() { + this.points = null; + this.lineColor = null; + Pool.recover("DrawLinesCmd", this); + } + run(context, gx, gy) { + this.points && context._drawLines(this.x + gx, this.y + gy, this.points, this.lineColor, this.lineWidth, this.vid); + } + get cmdID() { + return DrawLinesCmd.ID; + } + } + DrawLinesCmd.ID = "DrawLines"; + + class DrawPathCmd { + static create(x, y, paths, brush, pen) { + var cmd = Pool.getItemByClass("DrawPathCmd", DrawPathCmd); + cmd.x = x; + cmd.y = y; + cmd.paths = paths; + cmd.brush = brush; + cmd.pen = pen; + return cmd; + } + recover() { + this.paths = null; + this.brush = null; + this.pen = null; + Pool.recover("DrawPathCmd", this); + } + run(context, gx, gy) { + this.paths && context._drawPath(this.x + gx, this.y + gy, this.paths, this.brush, this.pen); + } + get cmdID() { + return DrawPathCmd.ID; + } + } + DrawPathCmd.ID = "DrawPath"; + + class DrawPieCmd { + static create(x, y, radius, startAngle, endAngle, fillColor, lineColor, lineWidth, vid) { + var cmd = Pool.getItemByClass("DrawPieCmd", DrawPieCmd); + cmd.x = x; + cmd.y = y; + cmd.radius = radius; + cmd._startAngle = startAngle; + cmd._endAngle = endAngle; + cmd.fillColor = fillColor; + cmd.lineColor = lineColor; + cmd.lineWidth = lineWidth; + cmd.vid = vid; + return cmd; + } + recover() { + this.fillColor = null; + this.lineColor = null; + Pool.recover("DrawPieCmd", this); + } + run(context, gx, gy) { + context._drawPie(this.x + gx, this.y + gy, this.radius, this._startAngle, this._endAngle, this.fillColor, this.lineColor, this.lineWidth, this.vid); + } + get cmdID() { + return DrawPieCmd.ID; + } + get startAngle() { + return this._startAngle * 180 / Math.PI; + } + set startAngle(value) { + this._startAngle = value * Math.PI / 180; + } + get endAngle() { + return this._endAngle * 180 / Math.PI; + } + set endAngle(value) { + this._endAngle = value * Math.PI / 180; + } + } + DrawPieCmd.ID = "DrawPie"; + + class DrawPolyCmd { + static create(x, y, points, fillColor, lineColor, lineWidth, isConvexPolygon, vid) { + var cmd = Pool.getItemByClass("DrawPolyCmd", DrawPolyCmd); + cmd.x = x; + cmd.y = y; + cmd.points = points; + cmd.fillColor = fillColor; + cmd.lineColor = lineColor; + cmd.lineWidth = lineWidth; + cmd.isConvexPolygon = isConvexPolygon; + cmd.vid = vid; + return cmd; + } + recover() { + this.points = null; + this.fillColor = null; + this.lineColor = null; + Pool.recover("DrawPolyCmd", this); + } + run(context, gx, gy) { + this.points && context._drawPoly(this.x + gx, this.y + gy, this.points, this.fillColor, this.lineColor, this.lineWidth, this.isConvexPolygon, this.vid); + } + get cmdID() { + return DrawPolyCmd.ID; + } + } + DrawPolyCmd.ID = "DrawPoly"; + + class DrawRectCmd { + static create(x, y, width, height, fillColor, lineColor, lineWidth) { + var cmd = Pool.getItemByClass("DrawRectCmd", DrawRectCmd); + cmd.x = x; + cmd.y = y; + cmd.width = width; + cmd.height = height; + cmd.fillColor = fillColor; + cmd.lineColor = lineColor; + cmd.lineWidth = lineWidth; + return cmd; + } + recover() { + this.fillColor = null; + this.lineColor = null; + Pool.recover("DrawRectCmd", this); + } + run(context, gx, gy) { + context.drawRect(this.x + gx, this.y + gy, this.width, this.height, this.fillColor, this.lineColor, this.lineWidth); + } + get cmdID() { + return DrawRectCmd.ID; + } + } + DrawRectCmd.ID = "DrawRect"; + + class Matrix { + constructor(a = 1, b = 0, c = 0, d = 1, tx = 0, ty = 0, nums = 0) { + this._bTransform = false; + if (Matrix._createFun != null) { + return Matrix._createFun(a, b, c, d, tx, ty, nums); + } + this.a = a; + this.b = b; + this.c = c; + this.d = d; + this.tx = tx; + this.ty = ty; + this._checkTransform(); + } + identity() { + this.a = this.d = 1; + this.b = this.tx = this.ty = this.c = 0; + this._bTransform = false; + return this; + } + _checkTransform() { + return this._bTransform = (this.a !== 1 || this.b !== 0 || this.c !== 0 || this.d !== 1); + } + setTranslate(x, y) { + this.tx = x; + this.ty = y; + return this; + } + translate(x, y) { + this.tx += x; + this.ty += y; + return this; + } + scale(x, y) { + this.a *= x; + this.d *= y; + this.c *= x; + this.b *= y; + this.tx *= x; + this.ty *= y; + this._bTransform = true; + return this; + } + rotate(angle) { + var cos = Math.cos(angle); + var sin = Math.sin(angle); + var a1 = this.a; + var c1 = this.c; + var tx1 = this.tx; + this.a = a1 * cos - this.b * sin; + this.b = a1 * sin + this.b * cos; + this.c = c1 * cos - this.d * sin; + this.d = c1 * sin + this.d * cos; + this.tx = tx1 * cos - this.ty * sin; + this.ty = tx1 * sin + this.ty * cos; + this._bTransform = true; + return this; + } + skew(x, y) { + var tanX = Math.tan(x); + var tanY = Math.tan(y); + var a1 = this.a; + var b1 = this.b; + this.a += tanY * this.c; + this.b += tanY * this.d; + this.c += tanX * a1; + this.d += tanX * b1; + return this; + } + invertTransformPoint(out) { + var a1 = this.a; + var b1 = this.b; + var c1 = this.c; + var d1 = this.d; + var tx1 = this.tx; + var n = a1 * d1 - b1 * c1; + var a2 = d1 / n; + var b2 = -b1 / n; + var c2 = -c1 / n; + var d2 = a1 / n; + var tx2 = (c1 * this.ty - d1 * tx1) / n; + var ty2 = -(a1 * this.ty - b1 * tx1) / n; + return out.setTo(a2 * out.x + c2 * out.y + tx2, b2 * out.x + d2 * out.y + ty2); + } + transformPoint(out) { + return out.setTo(this.a * out.x + this.c * out.y + this.tx, this.b * out.x + this.d * out.y + this.ty); + } + transformPointN(out) { + return out.setTo(this.a * out.x + this.c * out.y, this.b * out.x + this.d * out.y); + } + getScaleX() { + return this.b === 0 ? this.a : Math.sqrt(this.a * this.a + this.b * this.b); + } + getScaleY() { + return this.c === 0 ? this.d : Math.sqrt(this.c * this.c + this.d * this.d); + } + invert() { + var a1 = this.a; + var b1 = this.b; + var c1 = this.c; + var d1 = this.d; + var tx1 = this.tx; + var n = a1 * d1 - b1 * c1; + this.a = d1 / n; + this.b = -b1 / n; + this.c = -c1 / n; + this.d = a1 / n; + this.tx = (c1 * this.ty - d1 * tx1) / n; + this.ty = -(a1 * this.ty - b1 * tx1) / n; + return this; + } + setTo(a, b, c, d, tx, ty) { + this.a = a, this.b = b, this.c = c, this.d = d, this.tx = tx, this.ty = ty; + return this; + } + concat(matrix) { + var a = this.a; + var c = this.c; + var tx = this.tx; + this.a = a * matrix.a + this.b * matrix.c; + this.b = a * matrix.b + this.b * matrix.d; + this.c = c * matrix.a + this.d * matrix.c; + this.d = c * matrix.b + this.d * matrix.d; + this.tx = tx * matrix.a + this.ty * matrix.c + matrix.tx; + this.ty = tx * matrix.b + this.ty * matrix.d + matrix.ty; + return this; + } + static mul(m1, m2, out) { + var aa = m1.a, ab = m1.b, ac = m1.c, ad = m1.d, atx = m1.tx, aty = m1.ty; + var ba = m2.a, bb = m2.b, bc = m2.c, bd = m2.d, btx = m2.tx, bty = m2.ty; + if (bb !== 0 || bc !== 0) { + out.a = aa * ba + ab * bc; + out.b = aa * bb + ab * bd; + out.c = ac * ba + ad * bc; + out.d = ac * bb + ad * bd; + out.tx = ba * atx + bc * aty + btx; + out.ty = bb * atx + bd * aty + bty; + } + else { + out.a = aa * ba; + out.b = ab * bd; + out.c = ac * ba; + out.d = ad * bd; + out.tx = ba * atx + btx; + out.ty = bd * aty + bty; + } + return out; + } + static mul16(m1, m2, out) { + var aa = m1.a, ab = m1.b, ac = m1.c, ad = m1.d, atx = m1.tx, aty = m1.ty; + var ba = m2.a, bb = m2.b, bc = m2.c, bd = m2.d, btx = m2.tx, bty = m2.ty; + if (bb !== 0 || bc !== 0) { + out[0] = aa * ba + ab * bc; + out[1] = aa * bb + ab * bd; + out[4] = ac * ba + ad * bc; + out[5] = ac * bb + ad * bd; + out[12] = ba * atx + bc * aty + btx; + out[13] = bb * atx + bd * aty + bty; + } + else { + out[0] = aa * ba; + out[1] = ab * bd; + out[4] = ac * ba; + out[5] = ad * bd; + out[12] = ba * atx + btx; + out[13] = bd * aty + bty; + } + return out; + } + scaleEx(x, y) { + var ba = this.a, bb = this.b, bc = this.c, bd = this.d; + if (bb !== 0 || bc !== 0) { + this.a = x * ba; + this.b = x * bb; + this.c = y * bc; + this.d = y * bd; + } + else { + this.a = x * ba; + this.b = 0 * bd; + this.c = 0 * ba; + this.d = y * bd; + } + this._bTransform = true; + } + rotateEx(angle) { + var cos = Math.cos(angle); + var sin = Math.sin(angle); + var ba = this.a, bb = this.b, bc = this.c, bd = this.d; + if (bb !== 0 || bc !== 0) { + this.a = cos * ba + sin * bc; + this.b = cos * bb + sin * bd; + this.c = -sin * ba + cos * bc; + this.d = -sin * bb + cos * bd; + } + else { + this.a = cos * ba; + this.b = sin * bd; + this.c = -sin * ba; + this.d = cos * bd; + } + this._bTransform = true; + } + clone() { + var dec = Matrix.create(); + dec.a = this.a; + dec.b = this.b; + dec.c = this.c; + dec.d = this.d; + dec.tx = this.tx; + dec.ty = this.ty; + dec._bTransform = this._bTransform; + return dec; + } + copyTo(dec) { + dec.a = this.a; + dec.b = this.b; + dec.c = this.c; + dec.d = this.d; + dec.tx = this.tx; + dec.ty = this.ty; + dec._bTransform = this._bTransform; + return dec; + } + toString() { + return this.a + "," + this.b + "," + this.c + "," + this.d + "," + this.tx + "," + this.ty; + } + destroy() { + this.recover(); + } + recover() { + Pool.recover("Matrix", this.identity()); + } + static create() { + return Pool.getItemByClass("Matrix", Matrix); + } + } + Matrix.EMPTY = new Matrix(); + Matrix.TEMP = new Matrix(); + Matrix._createFun = null; + + class Point { + constructor(x = 0, y = 0) { + this.x = x; + this.y = y; + } + static create() { + return Pool.getItemByClass("Point", Point); + } + setTo(x, y) { + this.x = x; + this.y = y; + return this; + } + reset() { + this.x = this.y = 0; + return this; + } + recover() { + Pool.recover("Point", this.reset()); + } + distance(x, y) { + return Math.sqrt((this.x - x) * (this.x - x) + (this.y - y) * (this.y - y)); + } + toString() { + return this.x + "," + this.y; + } + normalize() { + var d = Math.sqrt(this.x * this.x + this.y * this.y); + if (d > 0) { + var id = 1.0 / d; + this.x *= id; + this.y *= id; + } + } + copy(point) { + return this.setTo(point.x, point.y); + } + } + Point.TEMP = new Point(); + Point.EMPTY = new Point(); + + class Rectangle { + constructor(x = 0, y = 0, width = 0, height = 0) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + get right() { + return this.x + this.width; + } + get bottom() { + return this.y + this.height; + } + setTo(x, y, width, height) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + return this; + } + reset() { + this.x = this.y = this.width = this.height = 0; + return this; + } + recover() { + if (this == Rectangle.TEMP || this == Rectangle.EMPTY) { + console.log("recover Temp or Empty:", this); + return; + } + Pool.recover("Rectangle", this.reset()); + } + static create() { + return Pool.getItemByClass("Rectangle", Rectangle); + } + copyFrom(source) { + this.x = source.x; + this.y = source.y; + this.width = source.width; + this.height = source.height; + return this; + } + contains(x, y) { + if (this.width <= 0 || this.height <= 0) + return false; + if (x >= this.x && x < this.right) { + if (y >= this.y && y < this.bottom) { + return true; + } + } + return false; + } + intersects(rect) { + return !(rect.x > (this.x + this.width) || (rect.x + rect.width) < this.x || rect.y > (this.y + this.height) || (rect.y + rect.height) < this.y); + } + intersection(rect, out = null) { + if (!this.intersects(rect)) + return null; + out || (out = new Rectangle()); + out.x = Math.max(this.x, rect.x); + out.y = Math.max(this.y, rect.y); + out.width = Math.min(this.right, rect.right) - out.x; + out.height = Math.min(this.bottom, rect.bottom) - out.y; + return out; + } + union(source, out = null) { + out || (out = new Rectangle()); + this.clone(out); + if (source.width <= 0 || source.height <= 0) + return out; + out.addPoint(source.x, source.y); + out.addPoint(source.right, source.bottom); + return this; + } + clone(out = null) { + out || (out = new Rectangle()); + out.x = this.x; + out.y = this.y; + out.width = this.width; + out.height = this.height; + return out; + } + toString() { + return this.x + "," + this.y + "," + this.width + "," + this.height; + } + equals(rect) { + if (!rect || rect.x !== this.x || rect.y !== this.y || rect.width !== this.width || rect.height !== this.height) + return false; + return true; + } + addPoint(x, y) { + this.x > x && (this.width += this.x - x, this.x = x); + this.y > y && (this.height += this.y - y, this.y = y); + if (this.width < x - this.x) + this.width = x - this.x; + if (this.height < y - this.y) + this.height = y - this.y; + return this; + } + _getBoundPoints() { + var rst = Rectangle._temB; + rst.length = 0; + if (this.width == 0 || this.height == 0) + return rst; + rst.push(this.x, this.y, this.x + this.width, this.y, this.x, this.y + this.height, this.x + this.width, this.y + this.height); + return rst; + } + static _getBoundPointS(x, y, width, height) { + var rst = Rectangle._temA; + rst.length = 0; + if (width == 0 || height == 0) + return rst; + rst.push(x, y, x + width, y, x, y + height, x + width, y + height); + return rst; + } + static _getWrapRec(pointList, rst = null) { + if (!pointList || pointList.length < 1) + return rst ? rst.setTo(0, 0, 0, 0) : Rectangle.TEMP.setTo(0, 0, 0, 0); + rst = rst ? rst : Rectangle.create(); + var i, len = pointList.length, minX, maxX, minY, maxY, tPoint = Point.TEMP; + minX = minY = 99999; + maxX = maxY = -minX; + for (i = 0; i < len; i += 2) { + tPoint.x = pointList[i]; + tPoint.y = pointList[i + 1]; + minX = minX < tPoint.x ? minX : tPoint.x; + minY = minY < tPoint.y ? minY : tPoint.y; + maxX = maxX > tPoint.x ? maxX : tPoint.x; + maxY = maxY > tPoint.y ? maxY : tPoint.y; + } + return rst.setTo(minX, minY, maxX - minX, maxY - minY); + } + isEmpty() { + if (this.width <= 0 || this.height <= 0) + return true; + return false; + } + } + Rectangle.EMPTY = new Rectangle(); + Rectangle.TEMP = new Rectangle(); + Rectangle._temB = []; + Rectangle._temA = []; + + class LayaGL { + } + LayaGL.ARRAY_BUFFER_TYPE_DATA = 0; + LayaGL.ARRAY_BUFFER_TYPE_CMD = 1; + LayaGL.ARRAY_BUFFER_REF_REFERENCE = 0; + LayaGL.ARRAY_BUFFER_REF_COPY = 1; + LayaGL.UPLOAD_SHADER_UNIFORM_TYPE_ID = 0; + LayaGL.UPLOAD_SHADER_UNIFORM_TYPE_DATA = 1; + + var _sFactor = 1; + var _dFactor = 0; + class WebGLContext { + static __init__() { + var gl = LayaGL.instance; + WebGLContext._depthFunc = gl.LESS; + WebGLContext._blendEquation = gl.FUNC_ADD; + WebGLContext._blendEquationRGB = gl.FUNC_ADD; + WebGLContext._blendEquationAlpha = gl.FUNC_ADD; + _sFactor = gl.ONE; + _dFactor = gl.ZERO; + WebGLContext._sFactorAlpha = gl.ONE; + WebGLContext._dFactorAlpha = gl.ZERO; + WebGLContext._activedTextureID = gl.TEXTURE0; + var maxTexturenum = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS); + WebGLContext._activeTextures = new Array(maxTexturenum); + WebGLContext._glTextureIDs = [gl.TEXTURE0, gl.TEXTURE1, gl.TEXTURE2, gl.TEXTURE3, gl.TEXTURE4, gl.TEXTURE5, gl.TEXTURE6, gl.TEXTURE7, gl.TEXTURE8, gl.TEXTURE9, gl.TEXTURE10, gl.TEXTURE11, gl.TEXTURE12, gl.TEXTURE13, gl.TEXTURE14, gl.TEXTURE15, gl.TEXTURE16, gl.TEXTURE17, gl.TEXTURE18, gl.TEXTURE19, gl.TEXTURE20, gl.TEXTURE21, gl.TEXTURE22, gl.TEXTURE23, gl.TEXTURE24, gl.TEXTURE25, gl.TEXTURE26, gl.TEXTURE27, gl.TEXTURE28, gl.TEXTURE29, gl.TEXTURE30, gl.TEXTURE31]; + var maxVertexUniform = gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS); + var maxFragUniform = gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS); + WebGLContext._maxUniformFragmentVectors = Math.min(maxVertexUniform, maxFragUniform); + } + static useProgram(gl, program) { + if (WebGLContext._useProgram === program) + return false; + gl.useProgram(program); + WebGLContext._useProgram = program; + return true; + } + static setDepthTest(gl, value) { + value !== WebGLContext._depthTest && (WebGLContext._depthTest = value, value ? gl.enable(gl.DEPTH_TEST) : gl.disable(gl.DEPTH_TEST)); + } + static setDepthMask(gl, value) { + value !== WebGLContext._depthMask && (WebGLContext._depthMask = value, gl.depthMask(value)); + } + static setDepthFunc(gl, value) { + value !== WebGLContext._depthFunc && (WebGLContext._depthFunc = value, gl.depthFunc(value)); + } + static setBlend(gl, value) { + value !== WebGLContext._blend && (WebGLContext._blend = value, value ? gl.enable(gl.BLEND) : gl.disable(gl.BLEND)); + } + static setBlendEquation(gl, blendEquation) { + if (blendEquation !== WebGLContext._blendEquation) { + WebGLContext._blendEquation = blendEquation; + WebGLContext._blendEquationRGB = WebGLContext._blendEquationAlpha = null; + gl.blendEquation(blendEquation); + } + } + static setBlendEquationSeparate(gl, blendEquationRGB, blendEquationAlpha) { + if (blendEquationRGB !== WebGLContext._blendEquationRGB || blendEquationAlpha !== WebGLContext._blendEquationAlpha) { + WebGLContext._blendEquationRGB = blendEquationRGB; + WebGLContext._blendEquationAlpha = blendEquationAlpha; + WebGLContext._blendEquation = null; + gl.blendEquationSeparate(blendEquationRGB, blendEquationAlpha); + } + } + static setBlendFunc(gl, sFactor, dFactor, force = false) { + if (force || sFactor !== _sFactor || dFactor !== _dFactor) { + _sFactor = sFactor; + _dFactor = dFactor; + WebGLContext._sFactorRGB = null; + WebGLContext._dFactorRGB = null; + WebGLContext._sFactorAlpha = null; + WebGLContext._dFactorAlpha = null; + gl.blendFunc(sFactor, dFactor); + } + } + static setBlendFuncSeperate(gl, srcRGB, dstRGB, srcAlpha, dstAlpha) { + if (srcRGB !== WebGLContext._sFactorRGB || dstRGB !== WebGLContext._dFactorRGB || srcAlpha !== WebGLContext._sFactorAlpha || dstAlpha !== WebGLContext._dFactorAlpha) { + WebGLContext._sFactorRGB = srcRGB; + WebGLContext._dFactorRGB = dstRGB; + WebGLContext._sFactorAlpha = srcAlpha; + WebGLContext._dFactorAlpha = dstAlpha; + _sFactor = null; + _dFactor = null; + gl.blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); + } + } + static setCullFace(gl, value) { + value !== WebGLContext._cullFace && (WebGLContext._cullFace = value, value ? gl.enable(gl.CULL_FACE) : gl.disable(gl.CULL_FACE)); + } + static setFrontFace(gl, value) { + value !== WebGLContext._frontFace && (WebGLContext._frontFace = value, gl.frontFace(value)); + } + static activeTexture(gl, textureID) { + if (WebGLContext._activedTextureID !== textureID) { + gl.activeTexture(textureID); + WebGLContext._activedTextureID = textureID; + } + } + static bindTexture(gl, target, texture) { + if (WebGLContext._activeTextures[WebGLContext._activedTextureID - gl.TEXTURE0] !== texture) { + gl.bindTexture(target, texture); + WebGLContext._activeTextures[WebGLContext._activedTextureID - gl.TEXTURE0] = texture; + } + } + static __init_native() { + if (!ILaya.Render.supportWebGLPlusRendering) + return; + var webGLContext = WebGLContext; + webGLContext.activeTexture = webGLContext.activeTextureForNative; + webGLContext.bindTexture = webGLContext.bindTextureForNative; + } + static useProgramForNative(gl, program) { + gl.useProgram(program); + return true; + } + static setDepthTestForNative(gl, value) { + if (value) + gl.enable(gl.DEPTH_TEST); + else + gl.disable(gl.DEPTH_TEST); + } + static setDepthMaskForNative(gl, value) { + gl.depthMask(value); + } + static setDepthFuncForNative(gl, value) { + gl.depthFunc(value); + } + static setBlendForNative(gl, value) { + if (value) + gl.enable(gl.BLEND); + else + gl.disable(gl.BLEND); + } + static setBlendFuncForNative(gl, sFactor, dFactor) { + gl.blendFunc(sFactor, dFactor); + } + static setCullFaceForNative(gl, value) { + if (value) + gl.enable(gl.CULL_FACE); + else + gl.disable(gl.CULL_FACE); + } + static setFrontFaceForNative(gl, value) { + gl.frontFace(value); + } + static activeTextureForNative(gl, textureID) { + gl.activeTexture(textureID); + } + static bindTextureForNative(gl, target, texture) { + gl.bindTexture(target, texture); + } + static bindVertexArrayForNative(gl, vertexArray) { + gl.bindVertexArray(vertexArray); + } + static getUniformMaxVector() { + return WebGLContext._maxUniformFragmentVectors; + } + } + WebGLContext._activeTextures = new Array(1); + WebGLContext._useProgram = null; + WebGLContext._depthTest = true; + WebGLContext._depthMask = true; + WebGLContext._blend = false; + WebGLContext._cullFace = false; + WebGLContext.mainContext = null; + + class Handler { + constructor(caller = null, method = null, args = null, once = false) { + this.once = false; + this._id = 0; + this.setTo(caller, method, args, once); + } + setTo(caller, method, args, once = false) { + this._id = Handler._gid++; + this.caller = caller; + this.method = method; + this.args = args; + this.once = once; + return this; + } + run() { + if (this.method == null) + return null; + var id = this._id; + var result = this.method.apply(this.caller, this.args); + this._id === id && this.once && this.recover(); + return result; + } + runWith(data) { + if (this.method == null) + return null; + var id = this._id; + if (data == null) + var result = this.method.apply(this.caller, this.args); + else if (!this.args && !data.unshift) + result = this.method.call(this.caller, data); + else if (this.args) + result = this.method.apply(this.caller, this.args.concat(data)); + else + result = this.method.apply(this.caller, data); + this._id === id && this.once && this.recover(); + return result; + } + clear() { + this.caller = null; + this.method = null; + this.args = null; + return this; + } + recover() { + if (this._id > 0) { + this._id = 0; + Handler._pool.push(this.clear()); + } + } + static create(caller, method, args = null, once = true) { + if (Handler._pool.length) + return Handler._pool.pop().setTo(caller, method, args, once); + return new Handler(caller, method, args, once); + } + } + Handler._pool = []; + Handler._gid = 1; + + class EventDispatcher { + hasListener(type) { + var listener = this._events && this._events[type]; + return !!listener; + } + event(type, data = null) { + if (!this._events || !this._events[type]) + return false; + var listeners = this._events[type]; + if (listeners.run) { + if (listeners.once) + delete this._events[type]; + data != null ? listeners.runWith(data) : listeners.run(); + } + else { + for (var i = 0, n = listeners.length; i < n; i++) { + var listener = listeners[i]; + if (listener) { + (data != null) ? listener.runWith(data) : listener.run(); + } + if (!listener || listener.once) { + listeners.splice(i, 1); + i--; + n--; + } + } + if (listeners.length === 0 && this._events) + delete this._events[type]; + } + return true; + } + on(type, caller, listener, args = null) { + return this._createListener(type, caller, listener, args, false); + } + once(type, caller, listener, args = null) { + return this._createListener(type, caller, listener, args, true); + } + _createListener(type, caller, listener, args, once, offBefore = true) { + offBefore && this.off(type, caller, listener, once); + var handler = EventHandler.create(caller || this, listener, args, once); + this._events || (this._events = {}); + var events = this._events; + if (!events[type]) + events[type] = handler; + else { + if (!events[type].run) + events[type].push(handler); + else + events[type] = [events[type], handler]; + } + return this; + } + off(type, caller, listener, onceOnly = false) { + if (!this._events || !this._events[type]) + return this; + var listeners = this._events[type]; + if (listeners != null) { + if (listeners.run) { + if ((!caller || listeners.caller === caller) && (listener == null || listeners.method === listener) && (!onceOnly || listeners.once)) { + delete this._events[type]; + listeners.recover(); + } + } + else { + var count = 0; + for (var i = 0, n = listeners.length; i < n; i++) { + var item = listeners[i]; + if (!item) { + count++; + continue; + } + if (item && (!caller || item.caller === caller) && (listener == null || item.method === listener) && (!onceOnly || item.once)) { + count++; + listeners[i] = null; + item.recover(); + } + } + if (count === n) + delete this._events[type]; + } + } + return this; + } + offAll(type = null) { + var events = this._events; + if (!events) + return this; + if (type) { + this._recoverHandlers(events[type]); + delete events[type]; + } + else { + for (var name in events) { + this._recoverHandlers(events[name]); + } + this._events = null; + } + return this; + } + offAllCaller(caller) { + if (caller && this._events) { + for (var name in this._events) { + this.off(name, caller, null); + } + } + return this; + } + _recoverHandlers(arr) { + if (!arr) + return; + if (arr.run) { + arr.recover(); + } + else { + for (var i = arr.length - 1; i > -1; i--) { + if (arr[i]) { + arr[i].recover(); + arr[i] = null; + } + } + } + } + isMouseEvent(type) { + return EventDispatcher.MOUSE_EVENTS[type] || false; + } + } + EventDispatcher.MOUSE_EVENTS = { "rightmousedown": true, "rightmouseup": true, "rightclick": true, "mousedown": true, "mouseup": true, "mousemove": true, "mouseover": true, "mouseout": true, "click": true, "doubleclick": true }; + class EventHandler extends Handler { + constructor(caller, method, args, once) { + super(caller, method, args, once); + } + recover() { + if (this._id > 0) { + this._id = 0; + EventHandler._pool.push(this.clear()); + } + } + static create(caller, method, args = null, once = true) { + if (EventHandler._pool.length) + return EventHandler._pool.pop().setTo(caller, method, args, once); + return new EventHandler(caller, method, args, once); + } + } + EventHandler._pool = []; + + class URL { + constructor(url) { + this._url = URL.formatURL(url); + this._path = URL.getPath(url); + } + get url() { + return this._url; + } + get path() { + return this._path; + } + static set basePath(value) { + URL._basePath = ILaya.Laya._getUrlPath(); + URL._basePath = URL.formatURL(value); + } + static get basePath() { + return URL._basePath; + } + static formatURL(url) { + if (!url) + return "null path"; + if (url.indexOf(":") > 0) + return url; + if (URL.exportSceneToJson) + url = URL.getAdptedFilePath(url); + if (URL.customFormat != null) + url = URL.customFormat(url); + if (url.indexOf(":") > 0) + return url; + var char1 = url.charAt(0); + if (char1 === ".") { + return URL._formatRelativePath(URL._basePath + url); + } + else if (char1 === '~') { + return URL.rootPath + url.substring(1); + } + else if (char1 === "d") { + if (url.indexOf("data:image") === 0) + return url; + } + else if (char1 === "/") { + return url; + } + return URL._basePath + url; + } + static _formatRelativePath(value) { + var parts = value.split("/"); + for (var i = 0, len = parts.length; i < len; i++) { + if (parts[i] == '..') { + parts.splice(i - 1, 2); + i -= 2; + } + } + return parts.join('/'); + } + static getPath(url) { + var ofs = url.lastIndexOf('/'); + return ofs > 0 ? url.substr(0, ofs + 1) : ""; + } + static getFileName(url) { + var ofs = url.lastIndexOf('/'); + return ofs > 0 ? url.substr(ofs + 1) : url; + } + static getAdptedFilePath(url) { + if (!URL.exportSceneToJson || !url) + return url; + var i, len; + len = URL._adpteTypeList.length; + var tArr; + for (i = 0; i < len; i++) { + tArr = URL._adpteTypeList[i]; + url = url.replace(tArr[0], tArr[1]); + } + return url; + } + } + URL.version = {}; + URL.exportSceneToJson = false; + URL._basePath = ""; + URL.rootPath = ""; + URL.customFormat = function (url) { + var newUrl = URL.version[url]; + if (!window.conch && newUrl) + url += "?v=" + newUrl; + return url; + }; + URL._adpteTypeList = [[".scene3d", ".json"], [".scene", ".json"], [".taa", ".json"], [".prefab", ".json"]]; + + class Resource extends EventDispatcher { + constructor() { + super(); + this._id = 0; + this._url = null; + this._cpuMemory = 0; + this._gpuMemory = 0; + this._destroyed = false; + this._referenceCount = 0; + this.lock = false; + this.name = null; + this._id = ++Resource._uniqueIDCounter; + this._destroyed = false; + this._referenceCount = 0; + Resource._idResourcesMap[this.id] = this; + this.lock = false; + } + static get cpuMemory() { + return Resource._cpuMemory; + } + static get gpuMemory() { + return Resource._gpuMemory; + } + static _addCPUMemory(size) { + Resource._cpuMemory += size; + } + static _addGPUMemory(size) { + Resource._gpuMemory += size; + } + static _addMemory(cpuSize, gpuSize) { + Resource._cpuMemory += cpuSize; + Resource._gpuMemory += gpuSize; + } + static getResourceByID(id) { + return Resource._idResourcesMap[id]; + } + static getResourceByURL(url, index = 0) { + return Resource._urlResourcesMap[url][index]; + } + static destroyUnusedResources() { + for (var k in Resource._idResourcesMap) { + var res = Resource._idResourcesMap[k]; + if (!res.lock && res._referenceCount === 0) + res.destroy(); + } + } + get id() { + return this._id; + } + get url() { + return this._url; + } + get cpuMemory() { + return this._cpuMemory; + } + get gpuMemory() { + return this._gpuMemory; + } + get destroyed() { + return this._destroyed; + } + get referenceCount() { + return this._referenceCount; + } + _setCPUMemory(value) { + var offsetValue = value - this._cpuMemory; + this._cpuMemory = value; + Resource._addCPUMemory(offsetValue); + } + _setGPUMemory(value) { + var offsetValue = value - this._gpuMemory; + this._gpuMemory = value; + Resource._addGPUMemory(offsetValue); + } + _setCreateURL(url) { + url = URL.formatURL(url); + if (this._url !== url) { + var resList; + if (this._url) { + resList = Resource._urlResourcesMap[this._url]; + resList.splice(resList.indexOf(this), 1); + (resList.length === 0) && (delete Resource._urlResourcesMap[this._url]); + } + if (url) { + resList = Resource._urlResourcesMap[url]; + (resList) || (Resource._urlResourcesMap[url] = resList = []); + resList.push(this); + } + this._url = url; + } + } + _addReference(count = 1) { + this._referenceCount += count; + } + _removeReference(count = 1) { + this._referenceCount -= count; + } + _clearReference() { + this._referenceCount = 0; + } + _recoverResource() { + } + _disposeResource() { + } + _activeResource() { + } + destroy() { + if (this._destroyed) + return; + this._destroyed = true; + this.lock = false; + this._disposeResource(); + delete Resource._idResourcesMap[this.id]; + var resList; + if (this._url) { + resList = Resource._urlResourcesMap[this._url]; + if (resList) { + resList.splice(resList.indexOf(this), 1); + (resList.length === 0) && (delete Resource._urlResourcesMap[this._url]); + } + var resou = ILaya.Loader.loadedMap[this._url]; + (resou == this) && (delete ILaya.Loader.loadedMap[this._url]); + } + } + } + Resource._uniqueIDCounter = 0; + Resource._idResourcesMap = {}; + Resource._urlResourcesMap = {}; + Resource._cpuMemory = 0; + Resource._gpuMemory = 0; + + class Bitmap extends Resource { + constructor() { + super(); + this._width = -1; + this._height = -1; + } + get width() { + return this._width; + } + set width(width) { + this._width = width; + } + get height() { + return this._height; + } + set height(height) { + this._height = height; + } + _getSource() { + throw "Bitmap: must override it."; + } + } + + (function (FilterMode) { + FilterMode[FilterMode["Point"] = 0] = "Point"; + FilterMode[FilterMode["Bilinear"] = 1] = "Bilinear"; + FilterMode[FilterMode["Trilinear"] = 2] = "Trilinear"; + })(exports.FilterMode || (exports.FilterMode = {})); + + (function (TextureFormat) { + TextureFormat[TextureFormat["R8G8B8"] = 0] = "R8G8B8"; + TextureFormat[TextureFormat["R8G8B8A8"] = 1] = "R8G8B8A8"; + TextureFormat[TextureFormat["R5G6B5"] = 16] = "R5G6B5"; + TextureFormat[TextureFormat["Alpha8"] = 2] = "Alpha8"; + TextureFormat[TextureFormat["DXT1"] = 3] = "DXT1"; + TextureFormat[TextureFormat["DXT5"] = 4] = "DXT5"; + TextureFormat[TextureFormat["ETC1RGB"] = 5] = "ETC1RGB"; + TextureFormat[TextureFormat["ETC2RGB"] = 6] = "ETC2RGB"; + TextureFormat[TextureFormat["ETC2RGBA"] = 7] = "ETC2RGBA"; + TextureFormat[TextureFormat["ETC2RGB_Alpha8"] = 8] = "ETC2RGB_Alpha8"; + TextureFormat[TextureFormat["ETC2SRGB"] = 28] = "ETC2SRGB"; + TextureFormat[TextureFormat["PVRTCRGB_2BPPV"] = 9] = "PVRTCRGB_2BPPV"; + TextureFormat[TextureFormat["PVRTCRGBA_2BPPV"] = 10] = "PVRTCRGBA_2BPPV"; + TextureFormat[TextureFormat["PVRTCRGB_4BPPV"] = 11] = "PVRTCRGB_4BPPV"; + TextureFormat[TextureFormat["PVRTCRGBA_4BPPV"] = 12] = "PVRTCRGBA_4BPPV"; + TextureFormat[TextureFormat["R32G32B32A32"] = 15] = "R32G32B32A32"; + TextureFormat[TextureFormat["R16G16B16A16"] = 17] = "R16G16B16A16"; + TextureFormat[TextureFormat["ASTC4x4"] = 18] = "ASTC4x4"; + TextureFormat[TextureFormat["ASTC4x4SRGB"] = 23] = "ASTC4x4SRGB"; + TextureFormat[TextureFormat["ASTC6x6"] = 19] = "ASTC6x6"; + TextureFormat[TextureFormat["ASTC6x6SRGB"] = 24] = "ASTC6x6SRGB"; + TextureFormat[TextureFormat["ASTC8x8"] = 20] = "ASTC8x8"; + TextureFormat[TextureFormat["ASTC8x8SRGB"] = 25] = "ASTC8x8SRGB"; + TextureFormat[TextureFormat["ASTC10x10"] = 21] = "ASTC10x10"; + TextureFormat[TextureFormat["ASTC10x10SRGB"] = 26] = "ASTC10x10SRGB"; + TextureFormat[TextureFormat["ASTC12x12"] = 22] = "ASTC12x12"; + TextureFormat[TextureFormat["ASTC12x12SRGB"] = 27] = "ASTC12x12SRGB"; + TextureFormat[TextureFormat["KTXTEXTURE"] = -1] = "KTXTEXTURE"; + TextureFormat[TextureFormat["PVRTEXTURE"] = -2] = "PVRTEXTURE"; + })(exports.TextureFormat || (exports.TextureFormat = {})); + + (function (WarpMode) { + WarpMode[WarpMode["Repeat"] = 0] = "Repeat"; + WarpMode[WarpMode["Clamp"] = 1] = "Clamp"; + })(exports.WarpMode || (exports.WarpMode = {})); + + class BaseTexture extends Bitmap { + constructor(format, mipMap) { + super(); + this._wrapModeU = exports.WarpMode.Repeat; + this._wrapModeV = exports.WarpMode.Repeat; + this._filterMode = exports.FilterMode.Bilinear; + this._readyed = false; + this._width = -1; + this._height = -1; + this._format = format; + this._mipmap = mipMap; + this._anisoLevel = 1; + this._glTexture = LayaGL.instance.createTexture(); + } + get mipmap() { + return this._mipmap; + } + get format() { + return this._format; + } + get wrapModeU() { + return this._wrapModeU; + } + set wrapModeU(value) { + if (this._wrapModeU !== value) { + this._wrapModeU = value; + (this._width !== -1) && (this._setWarpMode(LayaGL.instance.TEXTURE_WRAP_S, value)); + } + } + get wrapModeV() { + return this._wrapModeV; + } + set wrapModeV(value) { + if (this._wrapModeV !== value) { + this._wrapModeV = value; + (this._height !== -1) && (this._setWarpMode(LayaGL.instance.TEXTURE_WRAP_T, value)); + } + } + get filterMode() { + return this._filterMode; + } + set filterMode(value) { + if (value !== this._filterMode) { + this._filterMode = value; + ((this._width !== -1) && (this._height !== -1)) && (this._setFilterMode(value)); + } + } + get anisoLevel() { + return this._anisoLevel; + } + set anisoLevel(value) { + if (value !== this._anisoLevel) { + this._anisoLevel = Math.max(1, Math.min(16, value)); + ((this._width !== -1) && (this._height !== -1)) && (this._setAnisotropy(value)); + } + } + get mipmapCount() { + return this._mipmapCount; + } + get defaulteTexture() { + throw "BaseTexture:must override it."; + } + _getFormatByteCount() { + switch (this._format) { + case exports.TextureFormat.R8G8B8: + return 3; + case exports.TextureFormat.R8G8B8A8: + return 4; + case exports.TextureFormat.R5G6B5: + return 1; + case exports.TextureFormat.Alpha8: + return 1; + case exports.TextureFormat.R16G16B16A16: + return 2; + case exports.TextureFormat.R32G32B32A32: + return 4; + default: + throw "Texture2D: unknown format."; + } + } + _isPot(size) { + return (size & (size - 1)) === 0; + } + _getGLFormat() { + var glFormat; + var gl = LayaGL.instance; + var gpu = LayaGL.layaGPUInstance; + switch (this._format) { + case exports.TextureFormat.R8G8B8: + case exports.TextureFormat.R5G6B5: + glFormat = gl.RGB; + break; + case exports.TextureFormat.R8G8B8A8: + glFormat = gl.RGBA; + break; + case exports.TextureFormat.Alpha8: + glFormat = gl.ALPHA; + break; + case exports.TextureFormat.R32G32B32A32: + case exports.TextureFormat.R16G16B16A16: + glFormat = gl.RGBA; + break; + case exports.TextureFormat.DXT1: + if (gpu._compressedTextureS3tc) + glFormat = gpu._compressedTextureS3tc.COMPRESSED_RGB_S3TC_DXT1_EXT; + else + throw "BaseTexture: not support DXT1 format."; + break; + case exports.TextureFormat.DXT5: + if (gpu._compressedTextureS3tc) + glFormat = gpu._compressedTextureS3tc.COMPRESSED_RGBA_S3TC_DXT5_EXT; + else + throw "BaseTexture: not support DXT5 format."; + break; + case exports.TextureFormat.ETC1RGB: + if (gpu._compressedTextureEtc1) + glFormat = gpu._compressedTextureEtc1.COMPRESSED_RGB_ETC1_WEBGL; + else + throw "BaseTexture: not support ETC1RGB format."; + break; + case exports.TextureFormat.ETC2RGB: + if (gpu._compressedTextureETC) + glFormat = gpu._compressedTextureETC.COMPRESSED_RGB8_ETC2; + else + throw "BaseTexture: not support ETC2RGB format."; + break; + case exports.TextureFormat.ETC2RGBA: + if (gpu._compressedTextureETC) + glFormat = gpu._compressedTextureETC.COMPRESSED_RGBA8_ETC2_EAC; + else + throw "BaseTexture: not support ETC2RGBA format."; + break; + case exports.TextureFormat.ETC2RGB_Alpha8: + if (gpu._compressedTextureETC) + glFormat = gpu._compressedTextureETC.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC; + else + throw "BaseTexture: not support ETC2SRGB_Alpha8 format."; + break; + case exports.TextureFormat.ETC2SRGB: + if (gpu._compressedTextureETC) + glFormat = gpu._compressedTextureETC.COMPRESSED_SRGB8_ETC2; + else + throw "BaseTexture: not support ETC2SRGB format."; + break; + case exports.TextureFormat.PVRTCRGB_2BPPV: + if (gpu._compressedTexturePvrtc) + glFormat = gpu._compressedTexturePvrtc.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; + else + throw "BaseTexture: not support PVRTCRGB_2BPPV format."; + break; + case exports.TextureFormat.PVRTCRGBA_2BPPV: + if (gpu._compressedTexturePvrtc) + glFormat = gpu._compressedTexturePvrtc.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; + else + throw "BaseTexture: not support PVRTCRGBA_2BPPV format."; + break; + case exports.TextureFormat.PVRTCRGB_4BPPV: + if (gpu._compressedTexturePvrtc) + glFormat = gpu._compressedTexturePvrtc.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; + else + throw "BaseTexture: not support PVRTCRGB_4BPPV format."; + break; + case exports.TextureFormat.PVRTCRGBA_4BPPV: + if (gpu._compressedTexturePvrtc) + glFormat = gpu._compressedTexturePvrtc.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; + else + throw "BaseTexture: not support PVRTCRGBA_4BPPV format."; + break; + case exports.TextureFormat.ASTC4x4: + if (gpu._compressedTextureASTC) + glFormat = gpu._compressedTextureASTC.COMPRESSED_RGBA_ASTC_4x4_KHR; + else + throw "BaseTexture: not support ASTC4x4 format."; + break; + case exports.TextureFormat.ASTC4x4SRGB: + if (gpu._compressedTextureASTC) + glFormat = gpu._compressedTextureASTC.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR; + else + throw "BaseTexture: not support ASTC4x4_KHR format."; + break; + case exports.TextureFormat.ASTC6x6: + if (gpu._compressedTextureASTC) + glFormat = gpu._compressedTextureASTC.COMPRESSED_RGBA_ASTC_6x6_KHR; + else + throw "BaseTexture: not support ASTC6x6 format."; + break; + case exports.TextureFormat.ASTC6x6SRGB: + if (gpu._compressedTextureASTC) + glFormat = gpu._compressedTextureASTC.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR; + else + throw "BaseTexture: not support ASTC6x6_KHR format."; + break; + case exports.TextureFormat.ASTC8x8: + if (gpu._compressedTextureASTC) + glFormat = gpu._compressedTextureASTC.COMPRESSED_RGBA_ASTC_8x8_KHR; + else + throw "BaseTexture: not support ASTC8x8 format."; + break; + case exports.TextureFormat.ASTC8x8SRGB: + if (gpu._compressedTextureASTC) + glFormat = gpu._compressedTextureASTC.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR; + else + throw "BaseTexture: not support ASTC8x8 format."; + break; + case exports.TextureFormat.ASTC10x10: + if (gpu._compressedTextureASTC) + glFormat = gpu._compressedTextureASTC.COMPRESSED_RGBA_ASTC_10x10_KHR; + else + throw "BaseTexture: not support ASTC10x10 format."; + break; + case exports.TextureFormat.ASTC10x10SRGB: + if (gpu._compressedTextureASTC) + glFormat = gpu._compressedTextureASTC.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR; + else + throw "BaseTexture: not support ASTC10x10 format."; + break; + case exports.TextureFormat.ASTC12x12: + if (gpu._compressedTextureASTC) + glFormat = gpu._compressedTextureASTC.COMPRESSED_RGBA_ASTC_12x12_KHR; + else + throw "BaseTexture: not support ASTC12x12 format."; + break; + case exports.TextureFormat.ASTC12x12SRGB: + if (gpu._compressedTextureASTC) + glFormat = gpu._compressedTextureASTC.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR; + else + throw "BaseTexture: not support ASTC12x12 format."; + break; + default: + throw "BaseTexture: unknown texture format."; + } + return glFormat; + } + _setFilterMode(value) { + var gl = LayaGL.instance; + WebGLContext.bindTexture(gl, this._glTextureType, this._glTexture); + switch (value) { + case exports.FilterMode.Point: + if (this._mipmap) + gl.texParameteri(this._glTextureType, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST); + else + gl.texParameteri(this._glTextureType, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(this._glTextureType, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + break; + case exports.FilterMode.Bilinear: + if (this._mipmap) + gl.texParameteri(this._glTextureType, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST); + else + gl.texParameteri(this._glTextureType, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(this._glTextureType, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + break; + case exports.FilterMode.Trilinear: + if (this._mipmap) + gl.texParameteri(this._glTextureType, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR); + else + gl.texParameteri(this._glTextureType, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(this._glTextureType, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + break; + default: + throw new Error("BaseTexture:unknown filterMode value."); + } + } + _setWarpMode(orientation, mode) { + var gl = LayaGL.instance; + WebGLContext.bindTexture(gl, this._glTextureType, this._glTexture); + if (this._isPot(this._width) && this._isPot(this._height)) { + switch (mode) { + case exports.WarpMode.Repeat: + gl.texParameteri(this._glTextureType, orientation, gl.REPEAT); + break; + case exports.WarpMode.Clamp: + gl.texParameteri(this._glTextureType, orientation, gl.CLAMP_TO_EDGE); + break; + } + } + else { + gl.texParameteri(this._glTextureType, orientation, gl.CLAMP_TO_EDGE); + } + } + _setAnisotropy(value) { + var anisotropic = LayaGL.layaGPUInstance._extTextureFilterAnisotropic; + if (anisotropic) { + value = Math.max(value, 1); + var gl = LayaGL.instance; + WebGLContext.bindTexture(gl, this._glTextureType, this._glTexture); + value = Math.min(gl.getParameter(anisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT), value); + gl.texParameterf(this._glTextureType, anisotropic.TEXTURE_MAX_ANISOTROPY_EXT, value); + } + } + _disposeResource() { + if (this._glTexture) { + LayaGL.instance.deleteTexture(this._glTexture); + this._glTexture = null; + this._setGPUMemory(0); + } + } + _getSource() { + if (this._readyed) + return this._glTexture; + else + return null; + } + generateMipmap() { + if (this._isPot(this.width) && this._isPot(this.height)) + LayaGL.instance.generateMipmap(this._glTextureType); + } + } + BaseTexture._rgbmRange = 5.0; + BaseTexture.FORMAT_R8G8B8 = 0; + BaseTexture.FORMAT_R8G8B8A8 = 1; + BaseTexture.FORMAT_ALPHA8 = 2; + BaseTexture.FORMAT_DXT1 = 3; + BaseTexture.FORMAT_DXT5 = 4; + BaseTexture.FORMAT_ETC1RGB = 5; + BaseTexture.FORMAT_PVRTCRGB_2BPPV = 9; + BaseTexture.FORMAT_PVRTCRGBA_2BPPV = 10; + BaseTexture.FORMAT_PVRTCRGB_4BPPV = 11; + BaseTexture.FORMAT_PVRTCRGBA_4BPPV = 12; + BaseTexture.RENDERTEXTURE_FORMAT_RGBA_HALF_FLOAT = 14; + BaseTexture.FORMAT_R32G32B32A32 = 15; + BaseTexture.FORMAT_DEPTH_16 = 0; + BaseTexture.FORMAT_STENCIL_8 = 1; + BaseTexture.FORMAT_DEPTHSTENCIL_16_8 = 2; + BaseTexture.FORMAT_DEPTHSTENCIL_NONE = 3; + BaseTexture.FILTERMODE_POINT = 0; + BaseTexture.FILTERMODE_BILINEAR = 1; + BaseTexture.FILTERMODE_TRILINEAR = 2; + BaseTexture.WARPMODE_REPEAT = 0; + BaseTexture.WARPMODE_CLAMP = 1; + + class Byte { + constructor(data = null) { + this._xd_ = true; + this._allocated_ = 8; + this._pos_ = 0; + this._length = 0; + if (data) { + this._u8d_ = new Uint8Array(data); + this._d_ = new DataView(this._u8d_.buffer); + this._length = this._d_.byteLength; + } + else { + this._resizeBuffer(this._allocated_); + } + } + static getSystemEndian() { + if (!Byte._sysEndian) { + var buffer = new ArrayBuffer(2); + new DataView(buffer).setInt16(0, 256, true); + Byte._sysEndian = (new Int16Array(buffer))[0] === 256 ? Byte.LITTLE_ENDIAN : Byte.BIG_ENDIAN; + } + return Byte._sysEndian; + } + get buffer() { + var rstBuffer = this._d_.buffer; + if (rstBuffer.byteLength === this._length) + return rstBuffer; + return rstBuffer.slice(0, this._length); + } + get endian() { + return this._xd_ ? Byte.LITTLE_ENDIAN : Byte.BIG_ENDIAN; + } + set endian(value) { + this._xd_ = (value === Byte.LITTLE_ENDIAN); + } + set length(value) { + if (this._allocated_ < value) + this._resizeBuffer(this._allocated_ = Math.floor(Math.max(value, this._allocated_ * 2))); + else if (this._allocated_ > value) + this._resizeBuffer(this._allocated_ = value); + this._length = value; + } + get length() { + return this._length; + } + _resizeBuffer(len) { + try { + var newByteView = new Uint8Array(len); + if (this._u8d_ != null) { + if (this._u8d_.length <= len) + newByteView.set(this._u8d_); + else + newByteView.set(this._u8d_.subarray(0, len)); + } + this._u8d_ = newByteView; + this._d_ = new DataView(newByteView.buffer); + } + catch (err) { + throw "Invalid typed array length:" + len; + } + } + getString() { + return this.readString(); + } + readString() { + return this._rUTF(this.getUint16()); + } + getFloat32Array(start, len) { + return this.readFloat32Array(start, len); + } + readFloat32Array(start, len) { + var end = start + len; + end = (end > this._length) ? this._length : end; + var v = new Float32Array(this._d_.buffer.slice(start, end)); + this._pos_ = end; + return v; + } + getUint8Array(start, len) { + return this.readUint8Array(start, len); + } + readUint8Array(start, len) { + var end = start + len; + end = (end > this._length) ? this._length : end; + var v = new Uint8Array(this._d_.buffer.slice(start, end)); + this._pos_ = end; + return v; + } + getInt16Array(start, len) { + return this.readInt16Array(start, len); + } + readInt16Array(start, len) { + var end = start + len; + end = (end > this._length) ? this._length : end; + var v = new Int16Array(this._d_.buffer.slice(start, end)); + this._pos_ = end; + return v; + } + getFloat32() { + return this.readFloat32(); + } + readFloat32() { + if (this._pos_ + 4 > this._length) + throw "getFloat32 error - Out of bounds"; + var v = this._d_.getFloat32(this._pos_, this._xd_); + this._pos_ += 4; + return v; + } + getFloat64() { + return this.readFloat64(); + } + readFloat64() { + if (this._pos_ + 8 > this._length) + throw "getFloat64 error - Out of bounds"; + var v = this._d_.getFloat64(this._pos_, this._xd_); + this._pos_ += 8; + return v; + } + writeFloat32(value) { + this._ensureWrite(this._pos_ + 4); + this._d_.setFloat32(this._pos_, value, this._xd_); + this._pos_ += 4; + } + writeFloat64(value) { + this._ensureWrite(this._pos_ + 8); + this._d_.setFloat64(this._pos_, value, this._xd_); + this._pos_ += 8; + } + getInt32() { + return this.readInt32(); + } + readInt32() { + if (this._pos_ + 4 > this._length) + throw "getInt32 error - Out of bounds"; + var float = this._d_.getInt32(this._pos_, this._xd_); + this._pos_ += 4; + return float; + } + getUint32() { + return this.readUint32(); + } + readUint32() { + if (this._pos_ + 4 > this._length) + throw "getUint32 error - Out of bounds"; + var v = this._d_.getUint32(this._pos_, this._xd_); + this._pos_ += 4; + return v; + } + writeInt32(value) { + this._ensureWrite(this._pos_ + 4); + this._d_.setInt32(this._pos_, value, this._xd_); + this._pos_ += 4; + } + writeUint32(value) { + this._ensureWrite(this._pos_ + 4); + this._d_.setUint32(this._pos_, value, this._xd_); + this._pos_ += 4; + } + getInt16() { + return this.readInt16(); + } + readInt16() { + if (this._pos_ + 2 > this._length) + throw "getInt16 error - Out of bounds"; + var us = this._d_.getInt16(this._pos_, this._xd_); + this._pos_ += 2; + return us; + } + getUint16() { + return this.readUint16(); + } + readUint16() { + if (this._pos_ + 2 > this._length) + throw "getUint16 error - Out of bounds"; + var us = this._d_.getUint16(this._pos_, this._xd_); + this._pos_ += 2; + return us; + } + writeUint16(value) { + this._ensureWrite(this._pos_ + 2); + this._d_.setUint16(this._pos_, value, this._xd_); + this._pos_ += 2; + } + writeInt16(value) { + this._ensureWrite(this._pos_ + 2); + this._d_.setInt16(this._pos_, value, this._xd_); + this._pos_ += 2; + } + getUint8() { + return this.readUint8(); + } + readUint8() { + if (this._pos_ + 1 > this._length) + throw "getUint8 error - Out of bounds"; + return this._u8d_[this._pos_++]; + } + writeUint8(value) { + this._ensureWrite(this._pos_ + 1); + this._d_.setUint8(this._pos_, value); + this._pos_++; + } + _getUInt8(pos) { + return this._readUInt8(pos); + } + _readUInt8(pos) { + return this._d_.getUint8(pos); + } + _getUint16(pos) { + return this._readUint16(pos); + } + _readUint16(pos) { + return this._d_.getUint16(pos, this._xd_); + } + _getMatrix() { + return this._readMatrix(); + } + _readMatrix() { + var rst = new Matrix(this.getFloat32(), this.getFloat32(), this.getFloat32(), this.getFloat32(), this.getFloat32(), this.getFloat32()); + return rst; + } + _rUTF(len) { + var max = this._pos_ + len, c, c2, c3, f = String.fromCharCode; + var u = this._u8d_; + var strs = []; + var n = 0; + strs.length = 1000; + while (this._pos_ < max) { + c = u[this._pos_++]; + if (c < 0x80) { + if (c != 0) + strs[n++] = f(c); + } + else if (c < 0xE0) { + strs[n++] = f(((c & 0x3F) << 6) | (u[this._pos_++] & 0x7F)); + } + else if (c < 0xF0) { + c2 = u[this._pos_++]; + strs[n++] = f(((c & 0x1F) << 12) | ((c2 & 0x7F) << 6) | (u[this._pos_++] & 0x7F)); + } + else { + c2 = u[this._pos_++]; + c3 = u[this._pos_++]; + const _code = ((c & 0x0F) << 18) | ((c2 & 0x7F) << 12) | ((c3 & 0x7F) << 6) | (u[this._pos_++] & 0x7F); + if (_code >= 0x10000) { + const _offset = _code - 0x10000; + const _lead = 0xd800 | (_offset >> 10); + const _trail = 0xdc00 | (_offset & 0x3ff); + strs[n++] = f(_lead); + strs[n++] = f(_trail); + } + else { + strs[n++] = f(_code); + } + } + } + strs.length = n; + return strs.join(''); + } + getCustomString(len) { + return this.readCustomString(len); + } + readCustomString(len) { + var v = "", ulen = 0, c, c2, f = String.fromCharCode; + var u = this._u8d_; + while (len > 0) { + c = u[this._pos_]; + if (c < 0x80) { + v += f(c); + this._pos_++; + len--; + } + else { + ulen = c - 0x80; + this._pos_++; + len -= ulen; + while (ulen > 0) { + c = u[this._pos_++]; + c2 = u[this._pos_++]; + v += f((c2 << 8) | c); + ulen--; + } + } + } + return v; + } + get pos() { + return this._pos_; + } + set pos(value) { + this._pos_ = value; + } + get bytesAvailable() { + return this._length - this._pos_; + } + clear() { + this._pos_ = 0; + this.length = 0; + } + __getBuffer() { + return this._d_.buffer; + } + writeUTFBytes(value) { + value = value + ""; + for (var i = 0, sz = value.length; i < sz; i++) { + var c = value.charCodeAt(i); + if (c <= 0x7F) { + this.writeByte(c); + } + else if (c <= 0x7FF) { + this._ensureWrite(this._pos_ + 2); + this._u8d_.set([0xC0 | (c >> 6), 0x80 | (c & 0x3F)], this._pos_); + this._pos_ += 2; + } + else if (c >= 0xD800 && c <= 0xDBFF) { + i++; + const c2 = value.charCodeAt(i); + if (!Number.isNaN(c2) && c2 >= 0xDC00 && c2 <= 0xDFFF) { + const _p1 = (c & 0x3FF) + 0x40; + const _p2 = c2 & 0x3FF; + const _b1 = 0xF0 | ((_p1 >> 8) & 0x3F); + const _b2 = 0x80 | ((_p1 >> 2) & 0x3F); + const _b3 = 0x80 | ((_p1 & 0x3) << 4) | ((_p2 >> 6) & 0xF); + const _b4 = 0x80 | (_p2 & 0x3F); + this._ensureWrite(this._pos_ + 4); + this._u8d_.set([_b1, _b2, _b3, _b4], this._pos_); + this._pos_ += 4; + } + } + else if (c <= 0xFFFF) { + this._ensureWrite(this._pos_ + 3); + this._u8d_.set([0xE0 | (c >> 12), 0x80 | ((c >> 6) & 0x3F), 0x80 | (c & 0x3F)], this._pos_); + this._pos_ += 3; + } + else { + this._ensureWrite(this._pos_ + 4); + this._u8d_.set([0xF0 | (c >> 18), 0x80 | ((c >> 12) & 0x3F), 0x80 | ((c >> 6) & 0x3F), 0x80 | (c & 0x3F)], this._pos_); + this._pos_ += 4; + } + } + } + writeUTFString(value) { + var tPos = this.pos; + this.writeUint16(1); + this.writeUTFBytes(value); + var dPos = this.pos - tPos - 2; + this._d_.setUint16(tPos, dPos, this._xd_); + } + writeUTFString32(value) { + var tPos = this.pos; + this.writeUint32(1); + this.writeUTFBytes(value); + var dPos = this.pos - tPos - 4; + this._d_.setUint32(tPos, dPos, this._xd_); + } + readUTFString() { + return this.readUTFBytes(this.getUint16()); + } + readUTFString32() { + return this.readUTFBytes(this.getUint32()); + } + getUTFString() { + return this.readUTFString(); + } + readUTFBytes(len = -1) { + if (len === 0) + return ""; + var lastBytes = this.bytesAvailable; + if (len > lastBytes) + throw "readUTFBytes error - Out of bounds"; + len = len > 0 ? len : lastBytes; + return this._rUTF(len); + } + getUTFBytes(len = -1) { + return this.readUTFBytes(len); + } + writeByte(value) { + this._ensureWrite(this._pos_ + 1); + this._d_.setInt8(this._pos_, value); + this._pos_ += 1; + } + readByte() { + if (this._pos_ + 1 > this._length) + throw "readByte error - Out of bounds"; + return this._d_.getInt8(this._pos_++); + } + getByte() { + return this.readByte(); + } + _ensureWrite(lengthToEnsure) { + if (this._length < lengthToEnsure) + this._length = lengthToEnsure; + if (this._allocated_ < lengthToEnsure) + this.length = lengthToEnsure; + } + writeArrayBuffer(arraybuffer, offset = 0, length = 0) { + if (offset < 0 || length < 0) + throw "writeArrayBuffer error - Out of bounds"; + if (length == 0) + length = arraybuffer.byteLength - offset; + this._ensureWrite(this._pos_ + length); + var uint8array = new Uint8Array(arraybuffer); + this._u8d_.set(uint8array.subarray(offset, offset + length), this._pos_); + this._pos_ += length; + } + readArrayBuffer(length) { + var rst; + rst = this._u8d_.buffer.slice(this._pos_, this._pos_ + length); + this._pos_ = this._pos_ + length; + return rst; + } + } + Byte.BIG_ENDIAN = "bigEndian"; + Byte.LITTLE_ENDIAN = "littleEndian"; + Byte._sysEndian = null; + + (function (RenderTextureFormat) { + RenderTextureFormat[RenderTextureFormat["R8G8B8"] = 0] = "R8G8B8"; + RenderTextureFormat[RenderTextureFormat["R8G8B8A8"] = 1] = "R8G8B8A8"; + RenderTextureFormat[RenderTextureFormat["Alpha8"] = 2] = "Alpha8"; + RenderTextureFormat[RenderTextureFormat["R16G16B16A16"] = 14] = "R16G16B16A16"; + RenderTextureFormat[RenderTextureFormat["Depth"] = 15] = "Depth"; + RenderTextureFormat[RenderTextureFormat["ShadowMap"] = 16] = "ShadowMap"; + })(exports.RenderTextureFormat || (exports.RenderTextureFormat = {})); + (function (RenderTextureDepthFormat) { + RenderTextureDepthFormat[RenderTextureDepthFormat["DEPTH_16"] = 0] = "DEPTH_16"; + RenderTextureDepthFormat[RenderTextureDepthFormat["STENCIL_8"] = 1] = "STENCIL_8"; + RenderTextureDepthFormat[RenderTextureDepthFormat["DEPTHSTENCIL_24_8"] = 2] = "DEPTHSTENCIL_24_8"; + RenderTextureDepthFormat[RenderTextureDepthFormat["DEPTHSTENCIL_NONE"] = 3] = "DEPTHSTENCIL_NONE"; + RenderTextureDepthFormat[RenderTextureDepthFormat["DEPTHSTENCIL_16_8"] = 2] = "DEPTHSTENCIL_16_8"; + })(exports.RenderTextureDepthFormat || (exports.RenderTextureDepthFormat = {})); + + class SystemUtils { + static get maxTextureCount() { + return this._maxTextureCount; + } + static get maxTextureSize() { + return this._maxTextureSize; + } + static get shaderCapailityLevel() { + return this._shaderCapailityLevel; + } + static supportTextureFormat(format) { + switch (format) { + case exports.TextureFormat.R32G32B32A32: + return (!LayaGL.layaGPUInstance._isWebGL2 && !LayaGL.layaGPUInstance._oesTextureFloat) ? false : true; + case exports.TextureFormat.R16G16B16A16: + return (!LayaGL.layaGPUInstance._isWebGL2 && !LayaGL.layaGPUInstance._oesTextureHalfFloat) ? false : true; + default: + return true; + } + } + static supportRenderTextureFormat(format) { + switch (format) { + case exports.RenderTextureFormat.R16G16B16A16: + return (((!!LayaGL.layaGPUInstance._isWebGL2) && (!!LayaGL.layaGPUInstance._extColorBufferFloat)) || LayaGL.layaGPUInstance._oesTextureHalfFloat && LayaGL.layaGPUInstance._oesTextureHalfFloatLinear) ? true : false; + case exports.RenderTextureFormat.Depth: + return (LayaGL.layaGPUInstance._isWebGL2 || LayaGL.layaGPUInstance._webgl_depth_texture) ? true : false; + case exports.RenderTextureFormat.ShadowMap: + return LayaGL.layaGPUInstance._isWebGL2 ? true : false; + default: + return true; + } + } + } + + class HalfFloatUtils { + static __init__() { + for (var i = 0; i < 256; ++i) { + var e = i - 127; + if (e < -27) { + HalfFloatUtils._baseTable[i | 0x000] = 0x0000; + HalfFloatUtils._baseTable[i | 0x100] = 0x8000; + HalfFloatUtils._shiftTable[i | 0x000] = 24; + HalfFloatUtils._shiftTable[i | 0x100] = 24; + } + else if (e < -14) { + HalfFloatUtils._baseTable[i | 0x000] = 0x0400 >> (-e - 14); + HalfFloatUtils._baseTable[i | 0x100] = (0x0400 >> (-e - 14)) | 0x8000; + HalfFloatUtils._shiftTable[i | 0x000] = -e - 1; + HalfFloatUtils._shiftTable[i | 0x100] = -e - 1; + } + else if (e <= 15) { + HalfFloatUtils._baseTable[i | 0x000] = (e + 15) << 10; + HalfFloatUtils._baseTable[i | 0x100] = ((e + 15) << 10) | 0x8000; + HalfFloatUtils._shiftTable[i | 0x000] = 13; + HalfFloatUtils._shiftTable[i | 0x100] = 13; + } + else if (e < 128) { + HalfFloatUtils._baseTable[i | 0x000] = 0x7c00; + HalfFloatUtils._baseTable[i | 0x100] = 0xfc00; + HalfFloatUtils._shiftTable[i | 0x000] = 24; + HalfFloatUtils._shiftTable[i | 0x100] = 24; + } + else { + HalfFloatUtils._baseTable[i | 0x000] = 0x7c00; + HalfFloatUtils._baseTable[i | 0x100] = 0xfc00; + HalfFloatUtils._shiftTable[i | 0x000] = 13; + HalfFloatUtils._shiftTable[i | 0x100] = 13; + } + } + HalfFloatUtils._mantissaTable[0] = 0; + for (i = 1; i < 1024; ++i) { + var m = i << 13; + e = 0; + while ((m & 0x00800000) === 0) { + e -= 0x00800000; + m <<= 1; + } + m &= ~0x00800000; + e += 0x38800000; + HalfFloatUtils._mantissaTable[i] = m | e; + } + for (i = 1024; i < 2048; ++i) { + HalfFloatUtils._mantissaTable[i] = 0x38000000 + ((i - 1024) << 13); + } + HalfFloatUtils._exponentTable[0] = 0; + for (i = 1; i < 31; ++i) { + HalfFloatUtils._exponentTable[i] = i << 23; + } + HalfFloatUtils._exponentTable[31] = 0x47800000; + HalfFloatUtils._exponentTable[32] = 0x80000000; + for (i = 33; i < 63; ++i) { + HalfFloatUtils._exponentTable[i] = 0x80000000 + ((i - 32) << 23); + } + HalfFloatUtils._exponentTable[63] = 0xc7800000; + HalfFloatUtils._offsetTable[0] = 0; + for (i = 1; i < 64; ++i) { + if (i === 32) { + HalfFloatUtils._offsetTable[i] = 0; + } + else { + HalfFloatUtils._offsetTable[i] = 1024; + } + } + } + static roundToFloat16Bits(num) { + HalfFloatUtils._floatView[0] = num; + var f = HalfFloatUtils._uint32View[0]; + var e = (f >> 23) & 0x1ff; + return HalfFloatUtils._baseTable[e] + ((f & 0x007fffff) >> HalfFloatUtils._shiftTable[e]); + } + static convertToNumber(float16bits) { + var m = float16bits >> 10; + HalfFloatUtils._uint32View[0] = HalfFloatUtils._mantissaTable[HalfFloatUtils._offsetTable[m] + (float16bits & 0x3ff)] + HalfFloatUtils._exponentTable[m]; + return HalfFloatUtils._floatView[0]; + } + } + HalfFloatUtils._buffer = new ArrayBuffer(4); + HalfFloatUtils._floatView = new Float32Array(HalfFloatUtils._buffer); + HalfFloatUtils._uint32View = new Uint32Array(HalfFloatUtils._buffer); + HalfFloatUtils._baseTable = new Uint32Array(512); + HalfFloatUtils._shiftTable = new Uint32Array(512); + HalfFloatUtils._mantissaTable = new Uint32Array(2048); + HalfFloatUtils._exponentTable = new Uint32Array(64); + HalfFloatUtils._offsetTable = new Uint32Array(64); + + class Texture2D extends BaseTexture { + constructor(width = 0, height = 0, format = exports.TextureFormat.R8G8B8A8, mipmap = true, canRead = false) { + super(format, mipmap); + var gl = LayaGL.instance; + this._glTextureType = gl.TEXTURE_2D; + this._width = width; + this._height = height; + this._canRead = canRead; + this._setWarpMode(gl.TEXTURE_WRAP_S, this._wrapModeU); + this._setWarpMode(gl.TEXTURE_WRAP_T, this._wrapModeV); + this._setFilterMode(this._filterMode); + this._setAnisotropy(this._anisoLevel); + var compress = this._gpuCompressFormat(); + if (mipmap) { + var mipCount = Math.max(Math.ceil(Math.log2(width)) + 1, Math.ceil(Math.log2(height)) + 1); + if (!compress) { + for (var i = 0; i < mipCount; i++) + this._setPixels(null, i, Math.max(width >> i, 1), Math.max(height >> i, 1)); + } + this._mipmapCount = mipCount; + this._setGPUMemory(width * height * 4 * (1 + 1 / 3)); + } + else { + if (!compress) + this._setPixels(null, 0, width, height); + this._mipmapCount = 1; + this._setGPUMemory(width * height * 4); + } + } + static __init__() { + var pixels = new Uint8Array(3); + pixels[0] = 128; + pixels[1] = 128; + pixels[2] = 128; + Texture2D.grayTexture = new Texture2D(1, 1, exports.TextureFormat.R8G8B8, false, false); + Texture2D.grayTexture.setPixels(pixels); + Texture2D.grayTexture.lock = true; + pixels[0] = 255; + pixels[1] = 255; + pixels[2] = 255; + Texture2D.whiteTexture = new Texture2D(1, 1, exports.TextureFormat.R8G8B8, false, false); + Texture2D.whiteTexture.setPixels(pixels); + Texture2D.whiteTexture.lock = true; + pixels[0] = 0; + pixels[1] = 0; + pixels[2] = 0; + Texture2D.blackTexture = new Texture2D(1, 1, exports.TextureFormat.R8G8B8, false, false); + Texture2D.blackTexture.setPixels(pixels); + Texture2D.blackTexture.lock = true; + Texture2D.erroTextur = Texture2D.whiteTexture; + } + static _parse(data, propertyParams = null, constructParams = null) { + var texture = constructParams ? new Texture2D(constructParams[0], constructParams[1], constructParams[2], constructParams[3], constructParams[4]) : new Texture2D(0, 0); + if (propertyParams) { + texture.wrapModeU = propertyParams.wrapModeU; + texture.wrapModeV = propertyParams.wrapModeV; + texture.filterMode = propertyParams.filterMode; + texture.anisoLevel = propertyParams.anisoLevel; + } + switch (texture._format) { + case exports.TextureFormat.R8G8B8: + case exports.TextureFormat.R8G8B8A8: + texture.loadImageSource(data); + break; + case exports.TextureFormat.DXT1: + case exports.TextureFormat.DXT5: + case exports.TextureFormat.ETC1RGB: + case exports.TextureFormat.PVRTCRGB_2BPPV: + case exports.TextureFormat.PVRTCRGBA_2BPPV: + case exports.TextureFormat.PVRTCRGB_4BPPV: + case exports.TextureFormat.PVRTCRGBA_4BPPV: + case exports.TextureFormat.ETC2RGB: + case exports.TextureFormat.ETC2RGBA: + case exports.TextureFormat.ETC2SRGB: + case exports.TextureFormat.ASTC4x4: + case exports.TextureFormat.ASTC6x6: + case exports.TextureFormat.ASTC8x8: + case exports.TextureFormat.ASTC10x10: + case exports.TextureFormat.ASTC12x12: + case exports.TextureFormat.KTXTEXTURE: + case exports.TextureFormat.PVRTEXTURE: + texture.setCompressData(data); + break; + default: + throw "Texture2D:unkonwn format."; + } + return texture; + } + static _SimpleAnimatorTextureParse(data, propertyParams = null, constructParams = null) { + var byte = new Byte(data); + var version = byte.readUTFString(); + var texture; + var pixelDataArrays; + var usePixelData; + switch (version) { + case "LAYAANIMATORTEXTURE:0000": + var textureWidth = byte.readInt32(); + var pixelDataLength = byte.readInt32(); + pixelDataArrays = new Float32Array(textureWidth * textureWidth * 4); + usePixelData = new Float32Array(byte.readArrayBuffer(pixelDataLength * 4)); + pixelDataArrays.set(usePixelData, 0); + var texture = new Texture2D(textureWidth, textureWidth, exports.TextureFormat.R32G32B32A32, false, false); + texture.setPixels(pixelDataArrays, 0); + texture.filterMode = exports.FilterMode.Point; + break; + case "LAYACOMPRESSANIMATORTEXTURE:0000": + var textureWidth = byte.readInt32(); + var pixelDataLength = byte.readInt32(); + pixelDataArrays = new Uint16Array(byte.readArrayBuffer(pixelDataLength * 2)); + if (!SystemUtils.supportTextureFormat(exports.TextureFormat.R16G16B16A16)) { + console.log("The platform does not support 16-bit floating-point textures"); + if (!SystemUtils.supportTextureFormat(exports.TextureFormat.R32G32B32A32)) + console.error("The platform does not support 32-bit floating-point textures"); + usePixelData = new Float32Array(textureWidth * textureWidth * 4); + for (var i = 0, n = pixelDataArrays.length; i < n; i++) { + usePixelData[i] = HalfFloatUtils.convertToNumber(pixelDataArrays[i]); + } + texture = new Texture2D(textureWidth, textureWidth, exports.TextureFormat.R32G32B32A32, false, false); + texture.setPixels(usePixelData, 0); + texture.filterMode = exports.FilterMode.Point; + } + else { + usePixelData = new Uint16Array(textureWidth * textureWidth * 4); + usePixelData.set(pixelDataArrays, 0); + texture = new Texture2D(textureWidth, textureWidth, exports.TextureFormat.R16G16B16A16, false, false); + texture.setPixels(usePixelData, 0); + texture.filterMode = exports.FilterMode.Point; + } + break; + default: + throw "Laya3D:unknow version."; + } + return texture; + } + static load(url, complete) { + ILaya.loader.create(url, complete, null, ILaya.Loader.TEXTURE2D); + } + get defaulteTexture() { + return Texture2D.grayTexture; + } + _gpuCompressFormat() { + return (this._format != exports.TextureFormat.R8G8B8A8 && this._format != exports.TextureFormat.R8G8B8 && + this._format != exports.TextureFormat.R16G16B16A16 && + this._format != exports.TextureFormat.R32G32B32A32 && this._format != exports.TextureFormat.R5G6B5 && this._format != exports.TextureFormat.Alpha8); + } + _setPixels(pixels, miplevel, width, height) { + var gl = LayaGL.instance; + var textureType = this._glTextureType; + var glFormat = this._getGLFormat(); + WebGLContext.bindTexture(gl, textureType, this._glTexture); + switch (this.format) { + case exports.TextureFormat.R8G8B8: + gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1); + gl.texImage2D(textureType, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels); + gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4); + break; + case exports.TextureFormat.R5G6B5: + gl.pixelStorei(gl.UNPACK_ALIGNMENT, 2); + gl.texImage2D(textureType, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_SHORT_5_6_5, pixels); + gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4); + break; + case exports.TextureFormat.R32G32B32A32: + if (LayaGL.layaGPUInstance._isWebGL2) + gl.texImage2D(textureType, miplevel, gl.RGBA32F, width, height, 0, glFormat, gl.FLOAT, pixels); + else + gl.texImage2D(textureType, miplevel, gl.RGBA, width, height, 0, glFormat, gl.FLOAT, pixels); + break; + case exports.TextureFormat.R16G16B16A16: + if (LayaGL.layaGPUInstance._isWebGL2) + gl.texImage2D(textureType, miplevel, gl.RGBA16F, width, height, 0, glFormat, gl.HALF_FLOAT, pixels); + else + gl.texImage2D(textureType, miplevel, gl.RGBA, width, height, 0, glFormat, LayaGL.layaGPUInstance._oesTextureHalfFloat.HALF_FLOAT_OES, pixels); + break; + default: + gl.texImage2D(textureType, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels); + } + } + _calcualatesCompressedDataSize(format, width, height) { + switch (format) { + case exports.TextureFormat.DXT1: + return ((width + 3) >> 2) * ((height + 3) >> 2) * 8; + case exports.TextureFormat.DXT5: + return ((width + 3) >> 2) * ((height + 3) >> 2) * 16; + case exports.TextureFormat.PVRTCRGB_4BPPV: + case exports.TextureFormat.PVRTCRGBA_4BPPV: + return Math.floor((Math.max(width, 8) * Math.max(height, 8) * 4 + 7) / 8); + case exports.TextureFormat.PVRTCRGB_2BPPV: + case exports.TextureFormat.PVRTCRGBA_2BPPV: + return Math.floor((Math.max(width, 16) * Math.max(height, 8) * 2 + 7) / 8); + default: + return 0; + } + } + _pharseDDS(arrayBuffer) { + const FOURCC_DXT1 = 827611204; + const FOURCC_DXT5 = 894720068; + const DDPF_FOURCC = 0x4; + const DDSD_MIPMAPCOUNT = 0x20000; + const DDS_MAGIC = 0x20534444; + const DDS_HEADER_LENGTH = 31; + const DDS_HEADER_MAGIC = 0; + const DDS_HEADER_SIZE = 1; + const DDS_HEADER_FLAGS = 2; + const DDS_HEADER_HEIGHT = 3; + const DDS_HEADER_WIDTH = 4; + const DDS_HEADER_MIPMAPCOUNT = 7; + const DDS_HEADER_PF_FLAGS = 20; + const DDS_HEADER_PF_FOURCC = 21; + var header = new Int32Array(arrayBuffer, 0, DDS_HEADER_LENGTH); + if (header[DDS_HEADER_MAGIC] != DDS_MAGIC) + throw "Invalid magic number in DDS header"; + if (!(header[DDS_HEADER_PF_FLAGS] & DDPF_FOURCC)) + throw "Unsupported format, must contain a FourCC code"; + var compressedFormat = header[DDS_HEADER_PF_FOURCC]; + switch (this._format) { + case exports.TextureFormat.DXT1: + if (compressedFormat !== FOURCC_DXT1) + throw "the FourCC code is not same with texture format."; + break; + case exports.TextureFormat.DXT5: + if (compressedFormat !== FOURCC_DXT5) + throw "the FourCC code is not same with texture format."; + break; + default: + throw "unknown texture format."; + } + var mipLevels = 1; + if (header[DDS_HEADER_FLAGS] & DDSD_MIPMAPCOUNT) { + mipLevels = Math.max(1, header[DDS_HEADER_MIPMAPCOUNT]); + if (!this._mipmap) + throw "the mipmap is not same with Texture2D."; + } + else { + if (this._mipmap) + throw "the mipmap is not same with Texture2D."; + } + var width = header[DDS_HEADER_WIDTH]; + var height = header[DDS_HEADER_HEIGHT]; + this._width = width; + this._height = height; + var dataOffset = header[DDS_HEADER_SIZE] + 4; + this._upLoadCompressedTexImage2D(arrayBuffer, width, height, mipLevels, dataOffset, 0); + } + _pharseKTX(arrayBuffer) { + const ETC_HEADER_LENGTH = 13; + const ETC_HEADER_FORMAT = 4; + const ETC_HEADER_HEIGHT = 7; + const ETC_HEADER_WIDTH = 6; + const ETC_HEADER_MIPMAPCOUNT = 11; + const ETC_HEADER_METADATA = 12; + var id = new Uint8Array(arrayBuffer, 0, 12); + if (id[0] != 0xAB || id[1] != 0x4B || id[2] != 0x54 || id[3] != 0x58 || id[4] != 0x20 || id[5] != 0x31 || id[6] != 0x31 || id[7] != 0xBB || id[8] != 0x0D || id[9] != 0x0A || id[10] != 0x1A || id[11] != 0x0A) + throw ("Invalid fileIdentifier in KTX header"); + var header = new Int32Array(id.buffer, id.length, ETC_HEADER_LENGTH); + var compressedFormat = header[ETC_HEADER_FORMAT]; + this._format = -1; + if (LayaGL.layaGPUInstance._compressedTextureASTC) { + switch (compressedFormat) { + case LayaGL.layaGPUInstance._compressedTextureASTC.COMPRESSED_RGBA_ASTC_4x4_KHR: + this._format = exports.TextureFormat.ASTC4x4; + break; + case LayaGL.layaGPUInstance._compressedTextureASTC.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: + this._format = exports.TextureFormat.ASTC4x4SRGB; + break; + case LayaGL.layaGPUInstance._compressedTextureASTC.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: + this._format = exports.TextureFormat.ASTC6x6SRGB; + break; + case LayaGL.layaGPUInstance._compressedTextureASTC.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: + this._format = exports.TextureFormat.ASTC8x8SRGB; + break; + case LayaGL.layaGPUInstance._compressedTextureASTC.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: + this._format = exports.TextureFormat.ASTC10x10SRGB; + break; + case LayaGL.layaGPUInstance._compressedTextureASTC.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: + this._format = exports.TextureFormat.ASTC12x12SRGB; + break; + case LayaGL.layaGPUInstance._compressedTextureASTC.COMPRESSED_RGBA_ASTC_6x6_KHR: + this._format = exports.TextureFormat.ASTC6x6; + break; + case LayaGL.layaGPUInstance._compressedTextureASTC.COMPRESSED_RGBA_ASTC_8x8_KHR: + this._format = exports.TextureFormat.ASTC8x8; + break; + case LayaGL.layaGPUInstance._compressedTextureASTC.COMPRESSED_RGBA_ASTC_10x10_KHR: + this._format = exports.TextureFormat.ASTC10x10; + break; + case LayaGL.layaGPUInstance._compressedTextureASTC.COMPRESSED_RGBA_ASTC_12x12_KHR: + this._format = exports.TextureFormat.ASTC12x12; + break; + } + } + if (LayaGL.layaGPUInstance._compressedTextureEtc1) { + switch (compressedFormat) { + case LayaGL.layaGPUInstance._compressedTextureEtc1.COMPRESSED_RGB_ETC1_WEBGL: + this._format = exports.TextureFormat.ETC1RGB; + break; + } + } + if (LayaGL.layaGPUInstance._compressedTextureETC) { + switch (compressedFormat) { + case LayaGL.layaGPUInstance._compressedTextureETC.COMPRESSED_RGBA8_ETC2_EAC: + this._format = exports.TextureFormat.ETC2RGBA; + break; + case LayaGL.layaGPUInstance._compressedTextureETC.COMPRESSED_RGB8_ETC2: + this._format = exports.TextureFormat.ETC2RGB; + break; + case LayaGL.layaGPUInstance._compressedTextureETC.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + this._format = exports.TextureFormat.ETC2RGB_Alpha8; + break; + case LayaGL.layaGPUInstance._compressedTextureETC.COMPRESSED_SRGB8_ETC2: + this._format = exports.TextureFormat.ETC2SRGB; + break; + } + } + if (this._format == -1) { + throw "unknown texture format."; + } + var mipLevels = header[ETC_HEADER_MIPMAPCOUNT]; + var width = header[ETC_HEADER_WIDTH]; + var height = header[ETC_HEADER_HEIGHT]; + this._width = width; + this._height = height; + var dataOffset = 64 + header[ETC_HEADER_METADATA]; + this._upLoadKTXCompressedTexImage2D(arrayBuffer, width, height, mipLevels, dataOffset, 4); + } + _pharsePVR(arrayBuffer) { + const PVR_FORMAT_2BPP_RGB = 0; + const PVR_FORMAT_2BPP_RGBA = 1; + const PVR_FORMAT_4BPP_RGB = 2; + const PVR_FORMAT_4BPP_RGBA = 3; + const PVR_MAGIC = 0x03525650; + const PVR_HEADER_LENGTH = 13; + const PVR_HEADER_MAGIC = 0; + const PVR_HEADER_FORMAT = 2; + const PVR_HEADER_HEIGHT = 6; + const PVR_HEADER_WIDTH = 7; + const PVR_HEADER_MIPMAPCOUNT = 11; + const PVR_HEADER_METADATA = 12; + var header = new Int32Array(arrayBuffer, 0, PVR_HEADER_LENGTH); + if (header[PVR_HEADER_MAGIC] != PVR_MAGIC) + throw ("Invalid magic number in PVR header"); + var compressedFormat = header[PVR_HEADER_FORMAT]; + switch (compressedFormat) { + case PVR_FORMAT_2BPP_RGB: + this._format = exports.TextureFormat.PVRTCRGB_2BPPV; + break; + case PVR_FORMAT_4BPP_RGB: + this._format = exports.TextureFormat.PVRTCRGB_4BPPV; + break; + case PVR_FORMAT_2BPP_RGBA: + this._format = exports.TextureFormat.PVRTCRGBA_2BPPV; + break; + case PVR_FORMAT_4BPP_RGBA: + this._format = exports.TextureFormat.PVRTCRGBA_4BPPV; + break; + default: + throw "Texture2D:unknown PVR format."; + } + var mipLevels = header[PVR_HEADER_MIPMAPCOUNT]; + var width = header[PVR_HEADER_WIDTH]; + var height = header[PVR_HEADER_HEIGHT]; + this._width = width; + this._height = height; + var dataOffset = header[PVR_HEADER_METADATA] + 52; + this._upLoadCompressedTexImage2D(arrayBuffer, width, height, mipLevels, dataOffset, 0); + } + _upLoadCompressedTexImage2D(data, width, height, miplevelCount, dataOffset, imageSizeOffset) { + var gl = LayaGL.instance; + var textureType = this._glTextureType; + WebGLContext.bindTexture(gl, textureType, this._glTexture); + var glFormat = this._getGLFormat(); + var offset = dataOffset; + for (var i = 0; i < miplevelCount; i++) { + offset += imageSizeOffset; + var mipDataSize = this._calcualatesCompressedDataSize(this._format, width, height); + var mipData = new Uint8Array(data, offset, mipDataSize); + gl.compressedTexImage2D(textureType, i, glFormat, width, height, 0, mipData); + width = Math.max(width >> 1, 1.0); + height = Math.max(height >> 1, 1.0); + offset += mipDataSize; + } + var memory = offset; + this._setGPUMemory(memory); + this._readyed = true; + this._activeResource(); + } + _upLoadKTXCompressedTexImage2D(data, width, height, miplevelCount, dataOffset, imageSizeOffset) { + var gl = LayaGL.instance; + var textureType = this._glTextureType; + WebGLContext.bindTexture(gl, textureType, this._glTexture); + var glFormat = this._getGLFormat(); + var offset = dataOffset; + for (var i = 0; i < miplevelCount; i++) { + var mipDataSize = new Int32Array(data, offset, 1)[0]; + offset += imageSizeOffset; + var mipData = new Uint8Array(data, offset, mipDataSize); + gl.compressedTexImage2D(textureType, i, glFormat, width, height, 0, mipData); + width = Math.max(width >> 1, 1.0); + height = Math.max(height >> 1, 1.0); + offset += mipDataSize; + offset += 3 - ((mipDataSize + 3) % 4); + } + var memory = offset; + this._setGPUMemory(memory); + this._readyed = true; + this._activeResource(); + } + loadImageSource(source, premultiplyAlpha = false) { + var gl = LayaGL.instance; + var width = source.width; + var height = source.height; + this._width = width; + this._height = height; + if (!(this._isPot(width) && this._isPot(height))) + this._mipmap = false; + this._setWarpMode(gl.TEXTURE_WRAP_S, this._wrapModeU); + this._setWarpMode(gl.TEXTURE_WRAP_T, this._wrapModeV); + this._setFilterMode(this._filterMode); + WebGLContext.bindTexture(gl, this._glTextureType, this._glTexture); + var glFormat = this._getGLFormat(); + if (ILaya.Render.isConchApp) { + if (source.setPremultiplyAlpha) { + source.setPremultiplyAlpha(premultiplyAlpha); + } + gl.texImage2D(this._glTextureType, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source); + } + else { + (premultiplyAlpha) && (gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true)); + if (this.format == exports.TextureFormat.R5G6B5) + gl.texImage2D(this._glTextureType, 0, gl.RGB, gl.RGB, gl.UNSIGNED_SHORT_5_6_5, source); + else + gl.texImage2D(this._glTextureType, 0, glFormat, glFormat, gl.UNSIGNED_BYTE, source); + (premultiplyAlpha) && (gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false)); + } + if (this._mipmap) { + gl.generateMipmap(this._glTextureType); + this._setGPUMemory(width * height * 4 * (1 + 1 / 3)); + } + else { + this._setGPUMemory(width * height * 4); + } + if (this._canRead) { + if (ILaya.Render.isConchApp) { + this._pixels = new Uint8Array(source._nativeObj.getImageData(0, 0, width, height)); + } + else { + ILaya.Browser.canvas.size(width, height); + ILaya.Browser.canvas.clear(); + ILaya.Browser.context.drawImage(source, 0, 0, width, height); + this._pixels = new Uint8Array(ILaya.Browser.context.getImageData(0, 0, width, height).data.buffer); + } + } + this._readyed = true; + this._activeResource(); + } + setPixels(pixels, miplevel = 0) { + if (this._gpuCompressFormat()) + throw "Texture2D:the format is GPU compression format."; + if (!pixels) + throw "Texture2D:pixels can't be null."; + var width = Math.max(this._width >> miplevel, 1); + var height = Math.max(this._height >> miplevel, 1); + var pixelsCount = width * height * this._getFormatByteCount(); + if (pixels.length < pixelsCount) + throw "Texture2D:pixels length should at least " + pixelsCount + "."; + this._setPixels(pixels, miplevel, width, height); + if (this._canRead) + this._pixels = pixels; + this._readyed = true; + this._activeResource(); + } + setSubPixels(x, y, width, height, pixels, miplevel = 0) { + if (this._gpuCompressFormat()) + throw "Texture2D:the format is GPU compression format."; + if (!pixels) + throw "Texture2D:pixels can't be null."; + var gl = LayaGL.instance; + var textureType = this._glTextureType; + WebGLContext.bindTexture(gl, textureType, this._glTexture); + var glFormat = this._getGLFormat(); + switch (this.format) { + case exports.TextureFormat.R8G8B8: + gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1); + gl.texSubImage2D(textureType, miplevel, x, y, width, height, glFormat, gl.UNSIGNED_BYTE, pixels); + gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4); + break; + case exports.TextureFormat.R5G6B5: + gl.pixelStorei(gl.UNPACK_ALIGNMENT, 2); + gl.texSubImage2D(textureType, miplevel, x, y, width, height, glFormat, gl.UNSIGNED_SHORT_5_6_5, pixels); + gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4); + break; + case exports.TextureFormat.R32G32B32A32: + gl.texSubImage2D(textureType, miplevel, x, y, width, height, glFormat, gl.FLOAT, pixels); + break; + default: + gl.texSubImage2D(textureType, miplevel, x, y, width, height, glFormat, gl.UNSIGNED_BYTE, pixels); + } + this._readyed = true; + this._activeResource(); + } + setCompressData(data) { + switch (this._format) { + case exports.TextureFormat.DXT1: + case exports.TextureFormat.DXT5: + this._pharseDDS(data); + break; + case exports.TextureFormat.ETC1RGB: + case exports.TextureFormat.ETC2RGB: + case exports.TextureFormat.ETC2RGBA: + case exports.TextureFormat.ETC2RGB_Alpha8: + case exports.TextureFormat.ETC2SRGB: + case exports.TextureFormat.ASTC4x4: + case exports.TextureFormat.ASTC4x4SRGB: + case exports.TextureFormat.ASTC6x6: + case exports.TextureFormat.ASTC6x6SRGB: + case exports.TextureFormat.ASTC8x8: + case exports.TextureFormat.ASTC8x8SRGB: + case exports.TextureFormat.ASTC10x10: + case exports.TextureFormat.ASTC10x10SRGB: + case exports.TextureFormat.ASTC12x12: + case exports.TextureFormat.ASTC12x12SRGB: + case exports.TextureFormat.KTXTEXTURE: + this._pharseKTX(data); + break; + case exports.TextureFormat.PVRTCRGB_2BPPV: + case exports.TextureFormat.PVRTCRGBA_2BPPV: + case exports.TextureFormat.PVRTCRGB_4BPPV: + case exports.TextureFormat.PVRTCRGBA_4BPPV: + case exports.TextureFormat.PVRTEXTURE: + this._pharsePVR(data); + break; + default: + throw "Texture2D:unkonwn format."; + } + if ((this.mipmapCount != 1) && (this.width == (1 << this.mipmapCount - 1) || this.height == (1 << (this.mipmapCount)))) { + this._mipmap = true; + } + else + this._mipmap = false; + let gl = LayaGL.instance; + this._setWarpMode(gl.TEXTURE_WRAP_S, this._wrapModeU); + this._setWarpMode(gl.TEXTURE_WRAP_T, this._wrapModeV); + this._setFilterMode(this._filterMode); + } + getPixels() { + if (this._canRead) + return this._pixels; + else + throw new Error("Texture2D: must set texture canRead is true."); + } + } + Texture2D.TEXTURE2D = "TEXTURE2D"; + Texture2D.grayTexture = null; + Texture2D.whiteTexture = null; + Texture2D.blackTexture = null; + Texture2D.erroTextur = null; + + class BaseShader extends Resource { + constructor() { + super(); + } + } + + class RenderState2D { + static mat2MatArray(mat, matArray) { + var m = mat; + var m4 = matArray; + m4[0] = m.a; + m4[1] = m.b; + m4[2] = RenderState2D.EMPTYMAT4_ARRAY[2]; + m4[3] = RenderState2D.EMPTYMAT4_ARRAY[3]; + m4[4] = m.c; + m4[5] = m.d; + m4[6] = RenderState2D.EMPTYMAT4_ARRAY[6]; + m4[7] = RenderState2D.EMPTYMAT4_ARRAY[7]; + m4[8] = RenderState2D.EMPTYMAT4_ARRAY[8]; + m4[9] = RenderState2D.EMPTYMAT4_ARRAY[9]; + m4[10] = RenderState2D.EMPTYMAT4_ARRAY[10]; + m4[11] = RenderState2D.EMPTYMAT4_ARRAY[11]; + m4[12] = m.tx; + m4[13] = m.ty; + m4[14] = RenderState2D.EMPTYMAT4_ARRAY[14]; + m4[15] = RenderState2D.EMPTYMAT4_ARRAY[15]; + return matArray; + } + static restoreTempArray() { + RenderState2D.TEMPMAT4_ARRAY[0] = 1; + RenderState2D.TEMPMAT4_ARRAY[1] = 0; + RenderState2D.TEMPMAT4_ARRAY[4] = 0; + RenderState2D.TEMPMAT4_ARRAY[5] = 1; + RenderState2D.TEMPMAT4_ARRAY[12] = 0; + RenderState2D.TEMPMAT4_ARRAY[13] = 0; + } + static clear() { + RenderState2D.worldScissorTest = false; + RenderState2D.worldAlpha = 1; + } + } + RenderState2D._MAXSIZE = 99999999; + RenderState2D.EMPTYMAT4_ARRAY = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; + RenderState2D.TEMPMAT4_ARRAY = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; + RenderState2D.worldMatrix4 = RenderState2D.TEMPMAT4_ARRAY; + RenderState2D.worldMatrix = new Matrix(); + RenderState2D.matWVP = null; + RenderState2D.worldAlpha = 1.0; + RenderState2D.worldScissorTest = false; + RenderState2D.width = 0; + RenderState2D.height = 0; + + class RenderTexture2D extends BaseTexture { + constructor(width, height, format = exports.RenderTextureFormat.R8G8B8, depthStencilFormat = exports.RenderTextureDepthFormat.DEPTH_16) { + super(format, false); + this._mgrKey = 0; + this._glTextureType = LayaGL.instance.TEXTURE_2D; + this._width = width; + this._height = height; + this._depthStencilFormat = depthStencilFormat; + this._create(width, height); + this.lock = true; + } + static get currentActive() { + return RenderTexture2D._currentActive; + } + get depthStencilFormat() { + return this._depthStencilFormat; + } + get defaulteTexture() { + return Texture2D.grayTexture; + } + getIsReady() { + return true; + } + get sourceWidth() { + return this._width; + } + get sourceHeight() { + return this._height; + } + get offsetX() { + return 0; + } + get offsetY() { + return 0; + } + _create(width, height) { + var gl = LayaGL.instance; + this._frameBuffer = gl.createFramebuffer(); + WebGLContext.bindTexture(gl, this._glTextureType, this._glTexture); + var glFormat = this._getGLFormat(); + gl.texImage2D(this._glTextureType, 0, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, null); + this._setGPUMemory(width * height * 4); + gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this._glTexture, 0); + if (this._depthStencilFormat !== exports.RenderTextureDepthFormat.DEPTHSTENCIL_NONE) { + this._depthStencilBuffer = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, this._depthStencilBuffer); + switch (this._depthStencilFormat) { + case exports.RenderTextureDepthFormat.DEPTH_16: + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this._depthStencilBuffer); + break; + case exports.RenderTextureDepthFormat.STENCIL_8: + gl.renderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, width, height); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, this._depthStencilBuffer); + break; + case exports.RenderTextureDepthFormat.DEPTHSTENCIL_24_8: + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this._depthStencilBuffer); + break; + } + } + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.bindRenderbuffer(gl.RENDERBUFFER, null); + this._setWarpMode(gl.TEXTURE_WRAP_S, this._wrapModeU); + this._setWarpMode(gl.TEXTURE_WRAP_T, this._wrapModeV); + this._setFilterMode(this._filterMode); + this._setAnisotropy(this._anisoLevel); + this._readyed = true; + this._activeResource(); + } + generateMipmap() { + if (this._isPot(this.width) && this._isPot(this.height)) { + this._mipmap = true; + LayaGL.instance.generateMipmap(this._glTextureType); + this._setFilterMode(this._filterMode); + this._setGPUMemory(this.width * this.height * 4 * (1 + 1 / 3)); + } + else { + this._mipmap = false; + this._setGPUMemory(this.width * this.height * 4); + } + } + static pushRT() { + RenderTexture2D.rtStack.push({ rt: RenderTexture2D._currentActive, w: RenderState2D.width, h: RenderState2D.height }); + } + static popRT() { + var gl = LayaGL.instance; + var top = RenderTexture2D.rtStack.pop(); + if (top) { + if (RenderTexture2D._currentActive != top.rt) { + LayaGL.instance.bindFramebuffer(gl.FRAMEBUFFER, top.rt ? top.rt._frameBuffer : null); + RenderTexture2D._currentActive = top.rt; + } + gl.viewport(0, 0, top.w, top.h); + RenderState2D.width = top.w; + RenderState2D.height = top.h; + } + } + start() { + var gl = LayaGL.instance; + LayaGL.instance.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer); + this._lastRT = RenderTexture2D._currentActive; + RenderTexture2D._currentActive = this; + this._readyed = true; + gl.viewport(0, 0, this._width, this._height); + this._lastWidth = RenderState2D.width; + this._lastHeight = RenderState2D.height; + RenderState2D.width = this._width; + RenderState2D.height = this._height; + BaseShader.activeShader = null; + } + end() { + var gl = LayaGL.instance; + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + RenderTexture2D._currentActive = null; + this._readyed = true; + } + restore() { + var gl = LayaGL.instance; + if (this._lastRT != RenderTexture2D._currentActive) { + LayaGL.instance.bindFramebuffer(gl.FRAMEBUFFER, this._lastRT ? this._lastRT._frameBuffer : null); + RenderTexture2D._currentActive = this._lastRT; + } + this._readyed = true; + gl.viewport(0, 0, this._lastWidth, this._lastHeight); + RenderState2D.width = this._lastWidth; + RenderState2D.height = this._lastHeight; + BaseShader.activeShader = null; + } + clear(r = 0.0, g = 0.0, b = 0.0, a = 1.0) { + var gl = LayaGL.instance; + gl.clearColor(r, g, b, a); + var clearFlag = gl.COLOR_BUFFER_BIT; + switch (this._depthStencilFormat) { + case gl.DEPTH_COMPONENT16: + clearFlag |= gl.DEPTH_BUFFER_BIT; + break; + case gl.STENCIL_INDEX8: + clearFlag |= gl.STENCIL_BUFFER_BIT; + break; + case gl.DEPTH_STENCIL: + clearFlag |= gl.DEPTH_BUFFER_BIT; + clearFlag |= gl.STENCIL_BUFFER_BIT; + break; + } + gl.clear(clearFlag); + } + getData(x, y, width, height) { + if (ILaya.Render.isConchApp && window.conchConfig.threadMode == 2) { + throw "native 2 thread mode use getDataAsync"; + } + var gl = LayaGL.instance; + gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer); + var canRead = (gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE); + if (!canRead) { + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + return null; + } + var pixels = new Uint8Array(this._width * this._height * 4); + var glFormat = this._getGLFormat(); + gl.readPixels(x, y, width, height, glFormat, gl.UNSIGNED_BYTE, pixels); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + return pixels; + } + getDataAsync(x, y, width, height, callBack) { + var gl = LayaGL.instance; + gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer); + gl.readPixelsAsync(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, function (data) { + callBack(new Uint8Array(data)); + }); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + } + recycle() { + } + _disposeResource() { + if (this._frameBuffer) { + var gl = LayaGL.instance; + gl.deleteTexture(this._glTexture); + gl.deleteFramebuffer(this._frameBuffer); + gl.deleteRenderbuffer(this._depthStencilBuffer); + this._glTexture = null; + this._frameBuffer = null; + this._depthStencilBuffer = null; + this._setGPUMemory(0); + } + } + } + RenderTexture2D.rtStack = []; + RenderTexture2D.defuv = [0, 0, 1, 0, 1, 1, 0, 1]; + RenderTexture2D.flipyuv = [0, 1, 1, 1, 1, 0, 0, 0]; + + class WebGLRTMgr { + static getRT(w, h) { + w = w | 0; + h = h | 0; + if (w >= 10000) { + console.error('getRT error! w too big'); + } + var ret; + ret = new RenderTexture2D(w, h, exports.RenderTextureFormat.R8G8B8A8, -1); + return ret; + } + static releaseRT(rt) { + rt.destroy(); + return; + } + } + WebGLRTMgr.dict = {}; + + class BlendMode { + static _init_(gl) { + BlendMode.fns = [ + BlendMode.BlendNormal, + BlendMode.BlendAdd, + BlendMode.BlendMultiply, + BlendMode.BlendScreen, + BlendMode.BlendOverlay, + BlendMode.BlendLight, + BlendMode.BlendMask, + BlendMode.BlendDestinationOut, + BlendMode.BlendAddOld + ]; + BlendMode.targetFns = [ + BlendMode.BlendNormalTarget, + BlendMode.BlendAddTarget, + BlendMode.BlendMultiplyTarget, + BlendMode.BlendScreenTarget, + BlendMode.BlendOverlayTarget, + BlendMode.BlendLightTarget, + BlendMode.BlendMask, + BlendMode.BlendDestinationOut, + BlendMode.BlendAddTargetOld + ]; + } + static BlendNormal(gl) { + WebGLContext.setBlendFunc(gl, gl.ONE, gl.ONE_MINUS_SRC_ALPHA, true); + } + static BlendAddOld(gl) { + WebGLContext.setBlendFunc(gl, gl.ONE, gl.DST_ALPHA, true); + } + static BlendAdd(gl) { + WebGLContext.setBlendFunc(gl, gl.ONE, gl.ONE, true); + } + static BlendMultiply(gl) { + WebGLContext.setBlendFunc(gl, gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA, true); + } + static BlendScreen(gl) { + WebGLContext.setBlendFunc(gl, gl.ONE, gl.ONE, true); + } + static BlendOverlay(gl) { + WebGLContext.setBlendFunc(gl, gl.ONE, gl.ONE_MINUS_SRC_COLOR, true); + } + static BlendLight(gl) { + WebGLContext.setBlendFunc(gl, gl.ONE, gl.ONE, true); + } + static BlendNormalTarget(gl) { + WebGLContext.setBlendFunc(gl, gl.ONE, gl.ONE_MINUS_SRC_ALPHA, true); + } + static BlendAddTargetOld(gl) { + WebGLContext.setBlendFunc(gl, gl.ONE, gl.DST_ALPHA, true); + } + static BlendAddTarget(gl) { + WebGLContext.setBlendFunc(gl, gl.ONE, gl.ONE, true); + } + static BlendMultiplyTarget(gl) { + WebGLContext.setBlendFunc(gl, gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA, true); + } + static BlendScreenTarget(gl) { + WebGLContext.setBlendFunc(gl, gl.ONE, gl.ONE, true); + } + static BlendOverlayTarget(gl) { + WebGLContext.setBlendFunc(gl, gl.ONE, gl.ONE_MINUS_SRC_COLOR, true); + } + static BlendLightTarget(gl) { + WebGLContext.setBlendFunc(gl, gl.ONE, gl.ONE, true); + } + static BlendMask(gl) { + WebGLContext.setBlendFunc(gl, gl.ZERO, gl.SRC_ALPHA, true); + } + static BlendDestinationOut(gl) { + WebGLContext.setBlendFunc(gl, gl.ZERO, gl.ZERO, true); + } + } + BlendMode.activeBlendFunction = null; + BlendMode.NAMES = [ + "normal", + "add", + "multiply", + "screen", + "overlay", + "light", + "mask", + "destination-out", + "add_old" + ]; + BlendMode.TOINT = { + "normal": 0, + "add": 1, + "multiply": 2, + "screen": 3, + "overlay": 4, + "light": 5, + "mask": 6, + "destination-out": 7, + "lighter": 1, + "lighter_old": 8, + "add_old": 8 + }; + BlendMode.NORMAL = "normal"; + BlendMode.MASK = "mask"; + BlendMode.LIGHTER = "lighter"; + + class ShaderDefinesBase { + constructor(name2int, int2name, int2nameMap) { + this._value = 0; + this._name2int = name2int; + this._int2name = int2name; + this._int2nameMap = int2nameMap; + } + add(value) { + if (typeof (value) == 'string') { + this._value |= this._name2int[value]; + } + else { + this._value |= value; + } + return this._value; + } + addInt(value) { + this._value |= value; + return this._value; + } + remove(value) { + if (typeof (value) == 'string') { + this._value &= ~(this._name2int[value]); + } + else { + this._value &= (~value); + } + return this._value; + } + isDefine(def) { + return (this._value & def) === def; + } + getValue() { + return this._value; + } + setValue(value) { + this._value = value; + } + toNameDic() { + var r = this._int2nameMap[this._value]; + return r ? r : ShaderDefinesBase._toText(this._value, this._int2name, this._int2nameMap); + } + static _reg(name, value, _name2int, _int2name) { + _name2int[name] = value; + _int2name[value] = name; + } + static _toText(value, _int2name, _int2nameMap) { + var r = _int2nameMap[value]; + if (r) + return r; + var o = {}; + var d = 1; + for (var i = 0; i < 32; i++) { + d = 1 << i; + if (d > value) + break; + if (value & d) { + var name = _int2name[d]; + name && (o[name] = ""); + } + } + _int2nameMap[value] = o; + return o; + } + static _toInt(names, _name2int) { + var words = names.split('.'); + var num = 0; + for (var i = 0, n = words.length; i < n; i++) { + var value = _name2int[words[i]]; + if (!value) + throw new Error("Defines to int err:" + names + "/" + words[i]); + num |= value; + } + return num; + } + } + + class ShaderDefines2D extends ShaderDefinesBase { + constructor() { + super(ShaderDefines2D.__name2int, ShaderDefines2D.__int2name, ShaderDefines2D.__int2nameMap); + } + static __init__() { + ShaderDefines2D.reg("TEXTURE2D", ShaderDefines2D.TEXTURE2D); + ShaderDefines2D.reg("PRIMITIVE", ShaderDefines2D.PRIMITIVE); + ShaderDefines2D.reg("GLOW_FILTER", ShaderDefines2D.FILTERGLOW); + ShaderDefines2D.reg("BLUR_FILTER", ShaderDefines2D.FILTERBLUR); + ShaderDefines2D.reg("COLOR_FILTER", ShaderDefines2D.FILTERCOLOR); + ShaderDefines2D.reg("COLOR_ADD", ShaderDefines2D.COLORADD); + ShaderDefines2D.reg("WORLDMAT", ShaderDefines2D.WORLDMAT); + ShaderDefines2D.reg("FILLTEXTURE", ShaderDefines2D.FILLTEXTURE); + ShaderDefines2D.reg('MVP3D', ShaderDefines2D.MVP3D); + } + static reg(name, value) { + this._reg(name, value, ShaderDefines2D.__name2int, ShaderDefines2D.__int2name); + } + static toText(value, int2name, int2nameMap) { + return this._toText(value, int2name, int2nameMap); + } + static toInt(names) { + return this._toInt(names, ShaderDefines2D.__name2int); + } + } + ShaderDefines2D.TEXTURE2D = 0x01; + ShaderDefines2D.PRIMITIVE = 0x04; + ShaderDefines2D.FILTERGLOW = 0x08; + ShaderDefines2D.FILTERBLUR = 0x10; + ShaderDefines2D.FILTERCOLOR = 0x20; + ShaderDefines2D.COLORADD = 0x40; + ShaderDefines2D.WORLDMAT = 0x80; + ShaderDefines2D.FILLTEXTURE = 0x100; + ShaderDefines2D.SKINMESH = 0x200; + ShaderDefines2D.MVP3D = 0x800; + ShaderDefines2D.NOOPTMASK = ShaderDefines2D.FILTERGLOW | ShaderDefines2D.FILTERBLUR | ShaderDefines2D.FILTERCOLOR | ShaderDefines2D.FILLTEXTURE; + ShaderDefines2D.__name2int = {}; + ShaderDefines2D.__int2name = []; + ShaderDefines2D.__int2nameMap = []; + + class Stat { + static show(x = 0, y = 0) { + Stat._StatRender.show(x, y); + } + static enable() { + Stat._StatRender.enable(); + } + static hide() { + Stat._StatRender.hide(); + } + static clear() { + Stat.trianglesFaces = Stat.renderBatches = Stat.savedRenderBatches = Stat.shaderCall = Stat.spriteRenderUseCacheCount = Stat.frustumCulling = Stat.octreeNodeCulling = Stat.canvasNormal = Stat.canvasBitmap = Stat.canvasReCache = 0; + } + static set onclick(fn) { + Stat._StatRender.set_onclick(fn); + } + } + Stat.FPS = 0; + Stat.loopCount = 0; + Stat.shaderCall = 0; + Stat.renderBatches = 0; + Stat.savedRenderBatches = 0; + Stat.trianglesFaces = 0; + Stat.spriteCount = 0; + Stat.spriteRenderUseCacheCount = 0; + Stat.frustumCulling = 0; + Stat.octreeNodeCulling = 0; + Stat.canvasNormal = 0; + Stat.canvasBitmap = 0; + Stat.canvasReCache = 0; + Stat.renderSlow = false; + Stat._fpsData = []; + Stat._timer = 0; + Stat._count = 0; + Stat._StatRender = null; + + class StringKey { + constructor() { + this._strsToID = {}; + this._idToStrs = []; + this._length = 0; + } + add(str) { + var index = this._strsToID[str]; + if (index != null) + return index; + this._idToStrs[this._length] = str; + return this._strsToID[str] = this._length++; + } + getID(str) { + var index = this._strsToID[str]; + return index == null ? -1 : index; + } + getName(id) { + var str = this._idToStrs[id]; + return str == null ? undefined : str; + } + } + + class Shader extends BaseShader { + constructor(vs, ps, saveName = null, nameMap = null, bindAttrib = null) { + super(); + this._attribInfo = null; + this.customCompile = false; + this._curActTexIndex = 0; + this.tag = {}; + this._program = null; + this._params = null; + this._paramsMap = {}; + if ((!vs) || (!ps)) + throw "Shader Error"; + this._attribInfo = bindAttrib; + this._id = ++Shader._count; + this._vs = vs; + this._ps = ps; + this._nameMap = nameMap ? nameMap : {}; + saveName != null && (Shader.sharders[saveName] = this); + this.recreateResource(); + this.lock = true; + } + static getShader(name) { + return Shader.sharders[name]; + } + static create(vs, ps, saveName = null, nameMap = null, bindAttrib = null) { + return new Shader(vs, ps, saveName, nameMap, bindAttrib); + } + static withCompile(nameID, define, shaderName, createShader) { + if (shaderName && Shader.sharders[shaderName]) + return Shader.sharders[shaderName]; + var pre = Shader._preCompileShader[Shader.SHADERNAME2ID * nameID]; + if (!pre) + throw new Error("withCompile shader err!" + nameID); + return pre.createShader(define, shaderName, createShader, null); + } + static withCompile2D(nameID, mainID, define, shaderName, createShader, bindAttrib = null) { + if (shaderName && Shader.sharders[shaderName]) + return Shader.sharders[shaderName]; + var pre = Shader._preCompileShader[Shader.SHADERNAME2ID * nameID + mainID]; + if (!pre) + throw new Error("withCompile shader err!" + nameID + " " + mainID); + return pre.createShader(define, shaderName, createShader, bindAttrib); + } + static addInclude(fileName, txt) { + ILaya.ShaderCompile.addInclude(fileName, txt); + } + static preCompile(nameID, vs, ps, nameMap) { + var id = Shader.SHADERNAME2ID * nameID; + Shader._preCompileShader[id] = new ILaya.ShaderCompile(vs, ps, nameMap); + } + static preCompile2D(nameID, mainID, vs, ps, nameMap) { + var id = Shader.SHADERNAME2ID * nameID + mainID; + Shader._preCompileShader[id] = new ILaya.ShaderCompile(vs, ps, nameMap); + } + recreateResource() { + this._compile(); + this._setGPUMemory(0); + } + _disposeResource() { + WebGLContext.mainContext.deleteShader(this._vshader); + WebGLContext.mainContext.deleteShader(this._pshader); + WebGLContext.mainContext.deleteProgram(this._program); + this._vshader = this._pshader = this._program = null; + this._params = null; + this._paramsMap = {}; + this._setGPUMemory(0); + this._curActTexIndex = 0; + } + _compile() { + if (!this._vs || !this._ps || this._params) + return; + this._reCompile = true; + this._params = []; + var result; + if (this.customCompile) + result = ILaya.ShaderCompile.preGetParams(this._vs, this._ps); + var gl = WebGLContext.mainContext; + this._program = gl.createProgram(); + this._vshader = Shader._createShader(gl, this._vs, gl.VERTEX_SHADER); + this._pshader = Shader._createShader(gl, this._ps, gl.FRAGMENT_SHADER); + gl.attachShader(this._program, this._vshader); + gl.attachShader(this._program, this._pshader); + var one, i, n, location; + var attribDescNum = this._attribInfo ? this._attribInfo.length : 0; + for (i = 0; i < attribDescNum; i += 2) { + gl.bindAttribLocation(this._program, this._attribInfo[i + 1], this._attribInfo[i]); + } + gl.linkProgram(this._program); + if (!this.customCompile && !gl.getProgramParameter(this._program, gl.LINK_STATUS)) { + throw gl.getProgramInfoLog(this._program); + } + var nUniformNum = this.customCompile ? result.uniforms.length : gl.getProgramParameter(this._program, gl.ACTIVE_UNIFORMS); + for (i = 0; i < nUniformNum; i++) { + var uniform = this.customCompile ? result.uniforms[i] : gl.getActiveUniform(this._program, i); + location = gl.getUniformLocation(this._program, uniform.name); + one = { vartype: "uniform", glfun: null, ivartype: 1, location: location, name: uniform.name, type: uniform.type, isArray: false, isSame: false, preValue: null, indexOfParams: 0 }; + if (one.name.indexOf('[0]') > 0) { + one.name = one.name.substr(0, one.name.length - 3); + one.isArray = true; + one.location = gl.getUniformLocation(this._program, one.name); + } + this._params.push(one); + } + for (i = 0, n = this._params.length; i < n; i++) { + one = this._params[i]; + one.indexOfParams = i; + one.index = 1; + one.value = [one.location, null]; + one.codename = one.name; + one.name = this._nameMap[one.codename] ? this._nameMap[one.codename] : one.codename; + this._paramsMap[one.name] = one; + one._this = this; + one.uploadedValue = []; + switch (one.type) { + case gl.INT: + one.fun = one.isArray ? this._uniform1iv : this._uniform1i; + break; + case gl.FLOAT: + one.fun = one.isArray ? this._uniform1fv : this._uniform1f; + break; + case gl.FLOAT_VEC2: + one.fun = one.isArray ? this._uniform_vec2v : this._uniform_vec2; + break; + case gl.FLOAT_VEC3: + one.fun = one.isArray ? this._uniform_vec3v : this._uniform_vec3; + break; + case gl.FLOAT_VEC4: + one.fun = one.isArray ? this._uniform_vec4v : this._uniform_vec4; + break; + case gl.SAMPLER_2D: + one.fun = this._uniform_sampler2D; + break; + case gl.SAMPLER_CUBE: + one.fun = this._uniform_samplerCube; + break; + case gl.FLOAT_MAT4: + one.glfun = gl.uniformMatrix4fv; + one.fun = this._uniformMatrix4fv; + break; + case gl.BOOL: + one.fun = this._uniform1i; + break; + case gl.FLOAT_MAT2: + case gl.FLOAT_MAT3: + throw new Error("compile shader err!"); + default: + throw new Error("compile shader err!"); + } + } + } + static _createShader(gl, str, type) { + var shader = gl.createShader(type); + gl.shaderSource(shader, str); + gl.compileShader(shader); + if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + return shader; + } + else { + console.log(gl.getShaderInfoLog(shader)); + return null; + } + } + getUniform(name) { + return this._paramsMap[name]; + } + _uniform1f(one, value) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== value) { + WebGLContext.mainContext.uniform1f(one.location, uploadedValue[0] = value); + return 1; + } + return 0; + } + _uniform1fv(one, value) { + if (value.length < 4) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2] || uploadedValue[3] !== value[3]) { + WebGLContext.mainContext.uniform1fv(one.location, value); + uploadedValue[0] = value[0]; + uploadedValue[1] = value[1]; + uploadedValue[2] = value[2]; + uploadedValue[3] = value[3]; + return 1; + } + return 0; + } + else { + WebGLContext.mainContext.uniform1fv(one.location, value); + return 1; + } + } + _uniform_vec2(one, value) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1]) { + WebGLContext.mainContext.uniform2f(one.location, uploadedValue[0] = value[0], uploadedValue[1] = value[1]); + return 1; + } + return 0; + } + _uniform_vec2v(one, value) { + if (value.length < 2) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2] || uploadedValue[3] !== value[3]) { + WebGLContext.mainContext.uniform2fv(one.location, value); + uploadedValue[0] = value[0]; + uploadedValue[1] = value[1]; + uploadedValue[2] = value[2]; + uploadedValue[3] = value[3]; + return 1; + } + return 0; + } + else { + WebGLContext.mainContext.uniform2fv(one.location, value); + return 1; + } + } + _uniform_vec3(one, value) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2]) { + WebGLContext.mainContext.uniform3f(one.location, uploadedValue[0] = value[0], uploadedValue[1] = value[1], uploadedValue[2] = value[2]); + return 1; + } + return 0; + } + _uniform_vec3v(one, value) { + WebGLContext.mainContext.uniform3fv(one.location, value); + return 1; + } + _uniform_vec4(one, value) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2] || uploadedValue[3] !== value[3]) { + WebGLContext.mainContext.uniform4f(one.location, uploadedValue[0] = value[0], uploadedValue[1] = value[1], uploadedValue[2] = value[2], uploadedValue[3] = value[3]); + return 1; + } + return 0; + } + _uniform_vec4v(one, value) { + WebGLContext.mainContext.uniform4fv(one.location, value); + return 1; + } + _uniformMatrix2fv(one, value) { + WebGLContext.mainContext.uniformMatrix2fv(one.location, false, value); + return 1; + } + _uniformMatrix3fv(one, value) { + WebGLContext.mainContext.uniformMatrix3fv(one.location, false, value); + return 1; + } + _uniformMatrix4fv(one, value) { + WebGLContext.mainContext.uniformMatrix4fv(one.location, false, value); + return 1; + } + _uniform1i(one, value) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== value) { + WebGLContext.mainContext.uniform1i(one.location, uploadedValue[0] = value); + return 1; + } + return 0; + } + _uniform1iv(one, value) { + WebGLContext.mainContext.uniform1iv(one.location, value); + return 1; + } + _uniform_ivec2(one, value) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1]) { + WebGLContext.mainContext.uniform2i(one.location, uploadedValue[0] = value[0], uploadedValue[1] = value[1]); + return 1; + } + return 0; + } + _uniform_ivec2v(one, value) { + WebGLContext.mainContext.uniform2iv(one.location, value); + return 1; + } + _uniform_vec3i(one, value) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2]) { + WebGLContext.mainContext.uniform3i(one.location, uploadedValue[0] = value[0], uploadedValue[1] = value[1], uploadedValue[2] = value[2]); + return 1; + } + return 0; + } + _uniform_vec3vi(one, value) { + WebGLContext.mainContext.uniform3iv(one.location, value); + return 1; + } + _uniform_vec4i(one, value) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2] || uploadedValue[3] !== value[3]) { + WebGLContext.mainContext.uniform4i(one.location, uploadedValue[0] = value[0], uploadedValue[1] = value[1], uploadedValue[2] = value[2], uploadedValue[3] = value[3]); + return 1; + } + return 0; + } + _uniform_vec4vi(one, value) { + WebGLContext.mainContext.uniform4iv(one.location, value); + return 1; + } + _uniform_sampler2D(one, value) { + var gl = WebGLContext.mainContext; + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] == null) { + uploadedValue[0] = this._curActTexIndex; + gl.uniform1i(one.location, this._curActTexIndex); + WebGLContext.activeTexture(gl, gl.TEXTURE0 + this._curActTexIndex); + WebGLContext.bindTexture(gl, gl.TEXTURE_2D, value); + this._curActTexIndex++; + return 1; + } + else { + WebGLContext.activeTexture(gl, gl.TEXTURE0 + uploadedValue[0]); + WebGLContext.bindTexture(gl, gl.TEXTURE_2D, value); + return 0; + } + } + _uniform_samplerCube(one, value) { + var gl = WebGLContext.mainContext; + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] == null) { + uploadedValue[0] = this._curActTexIndex; + gl.uniform1i(one.location, this._curActTexIndex); + WebGLContext.activeTexture(gl, gl.TEXTURE0 + this._curActTexIndex); + WebGLContext.bindTexture(gl, gl.TEXTURE_CUBE_MAP, value); + this._curActTexIndex++; + return 1; + } + else { + WebGLContext.activeTexture(gl, gl.TEXTURE0 + uploadedValue[0]); + WebGLContext.bindTexture(gl, gl.TEXTURE_CUBE_MAP, value); + return 0; + } + } + _noSetValue(one) { + console.log("no....:" + one.name); + } + uploadOne(name, value) { + WebGLContext.useProgram(WebGLContext.mainContext, this._program); + var one = this._paramsMap[name]; + one.fun.call(this, one, value); + } + uploadTexture2D(value) { + var CTX = WebGLContext; + if (CTX._activeTextures[0] !== value) { + CTX.bindTexture(WebGLContext.mainContext, LayaGL.instance.TEXTURE_2D, value); + CTX._activeTextures[0] = value; + } + } + upload(shaderValue, params = null) { + BaseShader.activeShader = BaseShader.bindShader = this; + var gl = WebGLContext.mainContext; + WebGLContext.useProgram(gl, this._program); + if (this._reCompile) { + params = this._params; + this._reCompile = false; + } + else { + params = params || this._params; + } + var one, value, n = params.length, shaderCall = 0; + for (var i = 0; i < n; i++) { + one = params[i]; + if ((value = shaderValue[one.name]) !== null) + shaderCall += one.fun.call(this, one, value); + } + Stat.shaderCall += shaderCall; + } + uploadArray(shaderValue, length, _bufferUsage) { + BaseShader.activeShader = this; + BaseShader.bindShader = this; + WebGLContext.useProgram(WebGLContext.mainContext, this._program); + var params = this._params, value; + var one, shaderCall = 0; + for (var i = length - 2; i >= 0; i -= 2) { + one = this._paramsMap[shaderValue[i]]; + if (!one) + continue; + value = shaderValue[i + 1]; + if (value != null) { + _bufferUsage && _bufferUsage[one.name] && _bufferUsage[one.name].bind(); + shaderCall += one.fun.call(this, one, value); + } + } + Stat.shaderCall += shaderCall; + } + getParams() { + return this._params; + } + setAttributesLocation(attribDesc) { + this._attribInfo = attribDesc; + } + } + Shader._count = 0; + Shader._preCompileShader = {}; + Shader.SHADERNAME2ID = 0.0002; + Shader.nameKey = new StringKey(); + Shader.sharders = new Array(0x20); + + class Shader2X extends Shader { + constructor(vs, ps, saveName = null, nameMap = null, bindAttrib = null) { + super(vs, ps, saveName, nameMap, bindAttrib); + this._params2dQuick2 = null; + this._shaderValueWidth = 0; + this._shaderValueHeight = 0; + } + _disposeResource() { + super._disposeResource(); + this._params2dQuick2 = null; + } + upload2dQuick2(shaderValue) { + this.upload(shaderValue, this._params2dQuick2 || this._make2dQuick2()); + } + _make2dQuick2() { + if (!this._params2dQuick2) { + this._params2dQuick2 = []; + var params = this._params, one; + for (var i = 0, n = params.length; i < n; i++) { + one = params[i]; + if (one.name !== "size") + this._params2dQuick2.push(one); + } + } + return this._params2dQuick2; + } + static create(vs, ps, saveName = null, nameMap = null, bindAttrib = null) { + return new Shader2X(vs, ps, saveName, nameMap, bindAttrib); + } + } + + class Value2D { + constructor(mainID, subID) { + this.defines = new ShaderDefines2D(); + this.size = [0, 0]; + this.alpha = 1.0; + this.ALPHA = 1.0; + this.subID = 0; + this.ref = 1; + this._cacheID = 0; + this.clipMatDir = [ILaya.Context._MAXSIZE, 0, 0, ILaya.Context._MAXSIZE]; + this.clipMatPos = [0, 0]; + this.clipOff = [0, 0]; + this.mainID = mainID; + this.subID = subID; + this.textureHost = null; + this.texture = null; + this.color = null; + this.colorAdd = null; + this.u_mmat2 = null; + this._cacheID = mainID | subID; + this._inClassCache = Value2D._cache[this._cacheID]; + if (mainID > 0 && !this._inClassCache) { + this._inClassCache = Value2D._cache[this._cacheID] = []; + this._inClassCache._length = 0; + } + this.clear(); + } + static _initone(type, classT) { + Value2D._typeClass[type] = classT; + Value2D._cache[type] = []; + Value2D._cache[type]._length = 0; + } + static __init__() { + } + setValue(value) { } + _ShaderWithCompile() { + var ret = Shader.withCompile2D(0, this.mainID, this.defines.toNameDic(), this.mainID | this.defines._value, Shader2X.create, this._attribLocation); + return ret; + } + upload() { + var renderstate2d = RenderState2D; + RenderState2D.worldMatrix4 === RenderState2D.TEMPMAT4_ARRAY || this.defines.addInt(ShaderDefines2D.WORLDMAT); + this.mmat = renderstate2d.worldMatrix4; + if (RenderState2D.matWVP) { + this.defines.addInt(ShaderDefines2D.MVP3D); + this.u_MvpMatrix = RenderState2D.matWVP.elements; + } + var sd = Shader.sharders[this.mainID | this.defines._value] || this._ShaderWithCompile(); + if (sd._shaderValueWidth !== renderstate2d.width || sd._shaderValueHeight !== renderstate2d.height) { + this.size[0] = renderstate2d.width; + this.size[1] = renderstate2d.height; + sd._shaderValueWidth = renderstate2d.width; + sd._shaderValueHeight = renderstate2d.height; + sd.upload(this, null); + } + else { + sd.upload(this, sd._params2dQuick2 || sd._make2dQuick2()); + } + } + setFilters(value) { + this.filters = value; + if (!value) + return; + var n = value.length, f; + for (var i = 0; i < n; i++) { + f = value[i]; + if (f) { + this.defines.add(f.type); + f.action.setValue(this); + } + } + } + clear() { + this.defines._value = this.subID; + this.clipOff[0] = 0; + } + release() { + if ((--this.ref) < 1) { + this._inClassCache && (this._inClassCache[this._inClassCache._length++] = this); + this.clear(); + this.filters = null; + this.ref = 1; + this.clipOff[0] = 0; + } + } + static create(mainType, subType) { + var types = Value2D._cache[mainType | subType]; + if (types._length) + return types[--types._length]; + else + return new Value2D._typeClass[mainType | subType](subType); + } + } + Value2D._cache = []; + Value2D._typeClass = []; + Value2D.TEMPMAT4_ARRAY = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; + + class SubmitKey { + constructor() { + this.clear(); + } + clear() { + this.submitType = -1; + this.blendShader = this.other = 0; + } + copyFrom(src) { + this.other = src.other; + this.blendShader = src.blendShader; + this.submitType = src.submitType; + } + copyFrom2(src, submitType, other) { + this.other = other; + this.submitType = submitType; + } + equal3_2(next, submitType, other) { + return this.submitType === submitType && this.other === other && this.blendShader === next.blendShader; + } + equal4_2(next, submitType, other) { + return this.submitType === submitType && this.other === other && this.blendShader === next.blendShader; + } + equal_3(next) { + return this.submitType === next.submitType && this.blendShader === next.blendShader; + } + equal(next) { + return this.other === next.other && this.submitType === next.submitType && this.blendShader === next.blendShader; + } + } + + class SubmitCMD { + constructor() { + this._ref = 1; + this._key = new SubmitKey(); + } + renderSubmit() { + this.fun.apply(this._this, this.args); + return 1; + } + getRenderType() { + return 0; + } + releaseRender() { + if ((--this._ref) < 1) { + var pool = SubmitCMD.POOL; + pool[pool._length++] = this; + } + } + static create(args, fun, thisobj) { + var o = SubmitCMD.POOL._length ? SubmitCMD.POOL[--SubmitCMD.POOL._length] : new SubmitCMD(); + o.fun = fun; + o.args = args; + o._this = thisobj; + o._ref = 1; + o._key.clear(); + return o; + } + } + SubmitCMD.POOL = []; + { + SubmitCMD.POOL._length = 0; + } + + class Filter { + constructor() { } + get type() { return -1; } + } + Filter.BLUR = 0x10; + Filter.COLOR = 0x20; + Filter.GLOW = 0x08; + Filter._filter = function (sprite, context, x, y) { + var webglctx = context; + var next = this._next; + if (next) { + var filters = sprite.filters, len = filters.length; + if (len == 1 && (filters[0].type == Filter.COLOR)) { + context.save(); + context.setColorFilter(filters[0]); + next._fun.call(next, sprite, context, x, y); + context.restore(); + return; + } + var svCP = Value2D.create(ShaderDefines2D.TEXTURE2D, 0); + var b; + var p = Point.TEMP; + var tMatrix = webglctx._curMat; + var mat = Matrix.create(); + tMatrix.copyTo(mat); + var tPadding = 0; + var tHalfPadding = 0; + var tIsHaveGlowFilter = false; + var source = null; + var out = sprite._cacheStyle.filterCache || null; + if (!out || sprite.getRepaint() != 0) { + tIsHaveGlowFilter = sprite._isHaveGlowFilter(); + if (tIsHaveGlowFilter) { + tPadding = 50; + tHalfPadding = 25; + } + b = new Rectangle(); + b.copyFrom(sprite.getSelfBounds()); + b.x += sprite.x; + b.y += sprite.y; + b.x -= sprite.pivotX + 4; + b.y -= sprite.pivotY + 4; + var tSX = b.x; + var tSY = b.y; + b.width += (tPadding + 8); + b.height += (tPadding + 8); + p.x = b.x * mat.a + b.y * mat.c; + p.y = b.y * mat.d + b.x * mat.b; + b.x = p.x; + b.y = p.y; + p.x = b.width * mat.a + b.height * mat.c; + p.y = b.height * mat.d + b.width * mat.b; + b.width = p.x; + b.height = p.y; + if (b.width <= 0 || b.height <= 0) { + return; + } + out && WebGLRTMgr.releaseRT(out); + source = WebGLRTMgr.getRT(b.width, b.height); + var outRT = out = WebGLRTMgr.getRT(b.width, b.height); + sprite._getCacheStyle().filterCache = out; + webglctx.pushRT(); + webglctx.useRT(source); + var tX = sprite.x - tSX + tHalfPadding; + var tY = sprite.y - tSY + tHalfPadding; + next._fun.call(next, sprite, context, tX, tY); + webglctx.useRT(outRT); + for (var i = 0; i < len; i++) { + if (i != 0) { + webglctx.useRT(source); + webglctx.drawTarget(outRT, 0, 0, b.width, b.height, Matrix.TEMP.identity(), svCP, null, BlendMode.TOINT.overlay); + webglctx.useRT(outRT); + } + var fil = filters[i]; + switch (fil.type) { + case Filter.BLUR: + fil._glRender && fil._glRender.render(source, context, b.width, b.height, fil); + break; + case Filter.GLOW: + fil._glRender && fil._glRender.render(source, context, b.width, b.height, fil); + break; + case Filter.COLOR: + webglctx.setColorFilter(fil); + webglctx.drawTarget(source, 0, 0, b.width, b.height, Matrix.EMPTY.identity(), Value2D.create(ShaderDefines2D.TEXTURE2D, 0)); + webglctx.setColorFilter(null); + break; + } + } + webglctx.popRT(); + } + else { + tIsHaveGlowFilter = sprite._isHaveGlowFilter() || false; + if (tIsHaveGlowFilter) { + tPadding = 50; + tHalfPadding = 25; + } + b = sprite.getBounds(); + if (b.width <= 0 || b.height <= 0) { + return; + } + b.width += (tPadding + 8); + b.height += (tPadding + 8); + b.x -= sprite.pivotX + 4; + b.y -= sprite.pivotY + 4; + p.x = b.x * mat.a + b.y * mat.c; + p.y = b.y * mat.d + b.x * mat.b; + b.x = p.x; + b.y = p.y; + p.x = b.width * mat.a + b.height * mat.c; + p.y = b.height * mat.d + b.width * mat.b; + b.width = p.x; + b.height = p.y; + } + x = x - tHalfPadding - sprite.x; + y = y - tHalfPadding - sprite.y; + p.setTo(x, y); + mat.transformPoint(p); + x = p.x + b.x; + y = p.y + b.y; + webglctx._drawRenderTexture(out, x, y, b.width, b.height, Matrix.TEMP.identity(), 1.0, RenderTexture2D.defuv); + if (source) { + var submit = SubmitCMD.create([source], function (s) { + s.destroy(); + }, this); + source = null; + context.addRenderObject(submit); + } + mat.destroy(); + } + }; + + class Utils { + static toRadian(angle) { + return angle * Utils._pi2; + } + static toAngle(radian) { + return radian * Utils._pi; + } + static toHexColor(color) { + if (color < 0 || isNaN(color)) + return null; + var str = color.toString(16); + while (str.length < 6) + str = "0" + str; + return "#" + str; + } + static getGID() { + return Utils._gid++; + } + static concatArray(source, array) { + if (!array) + return source; + if (!source) + return array; + var i, len = array.length; + for (i = 0; i < len; i++) { + source.push(array[i]); + } + return source; + } + static clearArray(array) { + if (!array) + return array; + array.length = 0; + return array; + } + static copyArray(source, array) { + source || (source = []); + if (!array) + return source; + source.length = array.length; + var i, len = array.length; + for (i = 0; i < len; i++) { + source[i] = array[i]; + } + return source; + } + static getGlobalRecByPoints(sprite, x0, y0, x1, y1) { + var newLTPoint; + newLTPoint = Point.create().setTo(x0, y0); + newLTPoint = sprite.localToGlobal(newLTPoint); + var newRBPoint; + newRBPoint = Point.create().setTo(x1, y1); + newRBPoint = sprite.localToGlobal(newRBPoint); + var rst = Rectangle._getWrapRec([newLTPoint.x, newLTPoint.y, newRBPoint.x, newRBPoint.y]); + newLTPoint.recover(); + newRBPoint.recover(); + return rst; + } + static getGlobalPosAndScale(sprite) { + return Utils.getGlobalRecByPoints(sprite, 0, 0, 1, 1); + } + static bind(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + static updateOrder(array) { + if (!array || array.length < 2) + return false; + var i = 1, j, len = array.length, key, c; + while (i < len) { + j = i; + c = array[j]; + key = array[j]._zOrder; + while (--j > -1) { + if (array[j]._zOrder > key) + array[j + 1] = array[j]; + else + break; + } + array[j + 1] = c; + i++; + } + return true; + } + static transPointList(points, x, y) { + var i, len = points.length; + for (i = 0; i < len; i += 2) { + points[i] += x; + points[i + 1] += y; + } + } + static parseInt(str, radix = 0) { + var result = parseInt(str, radix); + if (isNaN(result)) + return 0; + return result; + } + static getFileExtension(path) { + Utils._extReg.lastIndex = path.lastIndexOf("."); + var result = Utils._extReg.exec(path); + if (result && result.length > 1) { + return result[1].toLowerCase(); + } + return null; + } + static getFilecompatibleExtension(path) { + var result = path.split("."); + var resultlen = result.length; + if (result.length > 2) + return result[resultlen - 2] + "." + result[resultlen - 1]; + else + return null; + } + static getTransformRelativeToWindow(coordinateSpace, x, y) { + var stage = Utils.gStage; + var globalTransform = Utils.getGlobalPosAndScale(coordinateSpace); + var canvasMatrix = stage._canvasTransform.clone(); + var canvasLeft = canvasMatrix.tx; + var canvasTop = canvasMatrix.ty; + canvasMatrix.rotate(-Math.PI / 180 * stage.canvasDegree); + canvasMatrix.scale(stage.clientScaleX, stage.clientScaleY); + var perpendicular = (stage.canvasDegree % 180 != 0); + var tx, ty; + if (perpendicular) { + tx = y + globalTransform.y; + ty = x + globalTransform.x; + tx *= canvasMatrix.d; + ty *= canvasMatrix.a; + if (stage.canvasDegree == 90) { + tx = canvasLeft - tx; + ty += canvasTop; + } + else { + tx += canvasLeft; + ty = canvasTop - ty; + } + } + else { + tx = x + globalTransform.x; + ty = y + globalTransform.y; + tx *= canvasMatrix.a; + ty *= canvasMatrix.d; + tx += canvasLeft; + ty += canvasTop; + } + ty += stage['_safariOffsetY']; + var domScaleX, domScaleY; + if (perpendicular) { + domScaleX = canvasMatrix.d * globalTransform.height; + domScaleY = canvasMatrix.a * globalTransform.width; + } + else { + domScaleX = canvasMatrix.a * globalTransform.width; + domScaleY = canvasMatrix.d * globalTransform.height; + } + return { x: tx, y: ty, scaleX: domScaleX, scaleY: domScaleY }; + } + static fitDOMElementInArea(dom, coordinateSpace, x, y, width, height) { + if (!dom._fitLayaAirInitialized) { + dom._fitLayaAirInitialized = true; + dom.style.transformOrigin = dom.style.webKittransformOrigin = "left top"; + dom.style.position = "absolute"; + } + var transform = Utils.getTransformRelativeToWindow(coordinateSpace, x, y); + dom.style.transform = dom.style.webkitTransform = "scale(" + transform.scaleX + "," + transform.scaleY + ") rotate(" + (Utils.gStage.canvasDegree) + "deg)"; + dom.style.width = width + 'px'; + dom.style.height = height + 'px'; + dom.style.left = transform.x + 'px'; + dom.style.top = transform.y + 'px'; + } + static isOkTextureList(textureList) { + if (!textureList) + return false; + var i, len = textureList.length; + var tTexture; + for (i = 0; i < len; i++) { + tTexture = textureList[i]; + if (!tTexture || !tTexture._getSource()) + return false; + } + return true; + } + static isOKCmdList(cmds) { + if (!cmds) + return false; + var i, len = cmds.length; + var cmd; + for (i = 0; i < len; i++) { + cmd = cmds[i]; + } + return true; + } + static getQueryString(name) { + if (ILaya.Browser.onMiniGame) + return null; + if (!window.location || !window.location.search) + return null; + var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); + var r = window.location.search.substr(1).match(reg); + if (r != null) + return unescape(r[2]); + return null; + } + } + Utils.gStage = null; + Utils._gid = 1; + Utils._pi = 180 / Math.PI; + Utils._pi2 = Math.PI / 180; + Utils._extReg = /\.(\w+)\??/g; + Utils.parseXMLFromString = function (value) { + var rst; + value = value.replace(/>\s+<'); + rst = (new DOMParser()).parseFromString(value, 'text/xml'); + if (rst.firstChild.textContent.indexOf("This page contains the following errors") > -1) { + throw new Error(rst.firstChild.firstChild.textContent); + } + return rst; + }; + + class ColorUtils { + constructor(value) { + this.arrColor = []; + if (value == null || value == 'none') { + this.strColor = "#00000000"; + this.numColor = 0; + this.arrColor = [0, 0, 0, 0]; + return; + } + var i, len; + var color; + if (typeof (value) == 'string') { + if (value.indexOf("rgba(") >= 0 || value.indexOf("rgb(") >= 0) { + var tStr = value; + var beginI, endI; + beginI = tStr.indexOf("("); + endI = tStr.indexOf(")"); + tStr = tStr.substring(beginI + 1, endI); + this.arrColor = tStr.split(","); + len = this.arrColor.length; + for (i = 0; i < len; i++) { + this.arrColor[i] = parseFloat(this.arrColor[i]); + if (i < 3) { + this.arrColor[i] = Math.round(this.arrColor[i]); + } + } + if (this.arrColor.length == 4) { + color = ((this.arrColor[0] * 256 + this.arrColor[1]) * 256 + this.arrColor[2]) * 256 + Math.round(this.arrColor[3] * 255); + } + else { + color = ((this.arrColor[0] * 256 + this.arrColor[1]) * 256 + this.arrColor[2]); + } + this.strColor = value; + } + else { + this.strColor = value; + value.charAt(0) === '#' && (value = value.substr(1)); + len = value.length; + if (len === 3 || len === 4) { + var temp = ""; + for (i = 0; i < len; i++) { + temp += (value[i] + value[i]); + } + value = temp; + } + color = parseInt(value, 16); + } + } + else { + color = value; + this.strColor = Utils.toHexColor(color); + } + if (this.strColor.indexOf("rgba") >= 0 || this.strColor.length === 9) { + this.arrColor = [((0xFF000000 & color) >>> 24) / 255, ((0xFF0000 & color) >> 16) / 255, ((0xFF00 & color) >> 8) / 255, (0xFF & color) / 255]; + this.numColor = (0xff000000 & color) >>> 24 | (color & 0xff0000) >> 8 | (color & 0x00ff00) << 8 | ((color & 0xff) << 24); + } + else { + this.arrColor = [((0xFF0000 & color) >> 16) / 255, ((0xFF00 & color) >> 8) / 255, (0xFF & color) / 255, 1]; + this.numColor = 0xff000000 | (color & 0xff0000) >> 16 | (color & 0x00ff00) | (color & 0xff) << 16; + } + this.arrColor.__id = ++ColorUtils._COLODID; + } + static _initDefault() { + ColorUtils._DEFAULT = {}; + for (var i in ColorUtils._COLOR_MAP) + ColorUtils._SAVE[i] = ColorUtils._DEFAULT[i] = new ColorUtils(ColorUtils._COLOR_MAP[i]); + return ColorUtils._DEFAULT; + } + static _initSaveMap() { + ColorUtils._SAVE_SIZE = 0; + ColorUtils._SAVE = {}; + for (var i in ColorUtils._DEFAULT) + ColorUtils._SAVE[i] = ColorUtils._DEFAULT[i]; + } + static create(value) { + var key = value + ""; + var color = ColorUtils._SAVE[key]; + if (color != null) + return color; + if (ColorUtils._SAVE_SIZE < 1000) + ColorUtils._initSaveMap(); + return ColorUtils._SAVE[key] = new ColorUtils(value); + } + } + ColorUtils._SAVE = {}; + ColorUtils._SAVE_SIZE = 0; + ColorUtils._COLOR_MAP = { "purple": "#800080", "orange": "#ffa500", "white": '#FFFFFF', "red": '#FF0000', "green": '#00FF00', "blue": '#0000FF', "black": '#000000', "yellow": '#FFFF00', 'gray': '#808080' }; + ColorUtils._DEFAULT = ColorUtils._initDefault(); + ColorUtils._COLODID = 1; + + class ColorFilter extends Filter { + constructor(mat = null) { + super(); + if (!mat) + mat = this._copyMatrix(ColorFilter.IDENTITY_MATRIX); + this._mat = new Float32Array(16); + this._alpha = new Float32Array(4); + this.setByMatrix(mat); + } + gray() { + return this.setByMatrix(ColorFilter.GRAY_MATRIX); + } + color(red = 0, green = 0, blue = 0, alpha = 1) { + return this.setByMatrix([1, 0, 0, 0, red, 0, 1, 0, 0, green, 0, 0, 1, 0, blue, 0, 0, 0, 1, alpha]); + } + setColor(color) { + var arr = ColorUtils.create(color).arrColor; + var mt = [0, 0, 0, 0, 256 * arr[0], 0, 0, 0, 0, 256 * arr[1], 0, 0, 0, 0, 256 * arr[2], 0, 0, 0, 1, 0]; + return this.setByMatrix(mt); + } + setByMatrix(matrix) { + if (this._matrix != matrix) + this._copyMatrix(matrix); + var j = 0; + var z = 0; + for (var i = 0; i < 20; i++) { + if (i % 5 != 4) { + this._mat[j++] = matrix[i]; + } + else { + this._alpha[z++] = matrix[i]; + } + } + return this; + } + get type() { + return Filter.COLOR; + } + adjustColor(brightness, contrast, saturation, hue) { + this.adjustHue(hue); + this.adjustContrast(contrast); + this.adjustBrightness(brightness); + this.adjustSaturation(saturation); + return this; + } + adjustBrightness(brightness) { + brightness = this._clampValue(brightness, 100); + if (brightness == 0 || isNaN(brightness)) + return this; + return this._multiplyMatrix([1, 0, 0, 0, brightness, 0, 1, 0, 0, brightness, 0, 0, 1, 0, brightness, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1]); + } + adjustContrast(contrast) { + contrast = this._clampValue(contrast, 100); + if (contrast == 0 || isNaN(contrast)) + return this; + var x; + if (contrast < 0) { + x = 127 + contrast / 100 * 127; + } + else { + x = contrast % 1; + if (x == 0) { + x = ColorFilter.DELTA_INDEX[contrast]; + } + else { + x = ColorFilter.DELTA_INDEX[(contrast << 0)] * (1 - x) + ColorFilter.DELTA_INDEX[(contrast << 0) + 1] * x; + } + x = x * 127 + 127; + } + var x1 = x / 127; + var x2 = (127 - x) * 0.5; + return this._multiplyMatrix([x1, 0, 0, 0, x2, 0, x1, 0, 0, x2, 0, 0, x1, 0, x2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1]); + } + adjustSaturation(saturation) { + saturation = this._clampValue(saturation, 100); + if (saturation == 0 || isNaN(saturation)) + return this; + var x = 1 + ((saturation > 0) ? 3 * saturation / 100 : saturation / 100); + var dx = 1 - x; + var r = 0.3086 * dx; + var g = 0.6094 * dx; + var b = 0.0820 * dx; + return this._multiplyMatrix([r + x, g, b, 0, 0, r, g + x, b, 0, 0, r, g, b + x, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1]); + } + adjustHue(hue) { + hue = this._clampValue(hue, 180) / 180 * Math.PI; + if (hue == 0 || isNaN(hue)) + return this; + var cos = Math.cos(hue); + var sin = Math.sin(hue); + var r = 0.213; + var g = 0.715; + var b = 0.072; + return this._multiplyMatrix([r + cos * (1 - r) + sin * (-r), g + cos * (-g) + sin * (-g), b + cos * (-b) + sin * (1 - b), 0, 0, r + cos * (-r) + sin * (0.143), g + cos * (1 - g) + sin * (0.140), b + cos * (-b) + sin * (-0.283), 0, 0, r + cos * (-r) + sin * (-(1 - r)), g + cos * (-g) + sin * (g), b + cos * (1 - b) + sin * (b), 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1]); + } + reset() { + return this.setByMatrix(this._copyMatrix(ColorFilter.IDENTITY_MATRIX)); + } + _multiplyMatrix(matrix) { + var col = []; + this._matrix = this._fixMatrix(this._matrix); + for (var i = 0; i < 5; i++) { + for (var j = 0; j < 5; j++) { + col[j] = this._matrix[j + i * 5]; + } + for (j = 0; j < 5; j++) { + var val = 0; + for (var k = 0; k < 5; k++) { + val += matrix[j + k * 5] * col[k]; + } + this._matrix[j + i * 5] = val; + } + } + return this.setByMatrix(this._matrix); + } + _clampValue(val, limit) { + return Math.min(limit, Math.max(-limit, val)); + } + _fixMatrix(matrix = null) { + if (matrix == null) + return ColorFilter.IDENTITY_MATRIX; + if (matrix.length < ColorFilter.LENGTH) + matrix = matrix.slice(0, matrix.length).concat(ColorFilter.IDENTITY_MATRIX.slice(matrix.length, ColorFilter.LENGTH)); + else if (matrix.length > ColorFilter.LENGTH) + matrix = matrix.slice(0, ColorFilter.LENGTH); + return matrix; + } + _copyMatrix(matrix) { + var len = ColorFilter.LENGTH; + if (!this._matrix) + this._matrix = []; + for (var i = 0; i < len; i++) { + this._matrix[i] = matrix[i]; + } + return this._matrix; + } + } + ColorFilter.DELTA_INDEX = [0, 0.01, 0.02, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.11, 0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.20, 0.21, 0.22, 0.24, 0.25, 0.27, 0.28, 0.30, 0.32, 0.34, 0.36, 0.38, 0.40, 0.42, 0.44, 0.46, 0.48, 0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68, 0.71, 0.74, 0.77, 0.80, 0.83, 0.86, 0.89, 0.92, 0.95, 0.98, 1.0, 1.06, 1.12, 1.18, 1.24, 1.30, 1.36, 1.42, 1.48, 1.54, 1.60, 1.66, 1.72, 1.78, 1.84, 1.90, 1.96, 2.0, 2.12, 2.25, 2.37, 2.50, 2.62, 2.75, 2.87, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.3, 4.7, 4.9, 5.0, 5.5, 6.0, 6.5, 6.8, 7.0, 7.3, 7.5, 7.8, 8.0, 8.4, 8.7, 9.0, 9.4, 9.6, 9.8, 10.0]; + ColorFilter.GRAY_MATRIX = [0.3086, 0.6094, 0.082, 0, 0, 0.3086, 0.6094, 0.082, 0, 0, 0.3086, 0.6094, 0.082, 0, 0, 0, 0, 0, 1, 0]; + ColorFilter.IDENTITY_MATRIX = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1]; + ColorFilter.LENGTH = 25; + + class DrawTextureCmd { + constructor() { + this.colorFlt = null; + this.uv = null; + } + static create(texture, x, y, width, height, matrix, alpha, color, blendMode, uv) { + var cmd = Pool.getItemByClass("DrawTextureCmd", DrawTextureCmd); + cmd.texture = texture; + texture._addReference(); + cmd.x = x; + cmd.y = y; + cmd.width = width; + cmd.height = height; + cmd.matrix = matrix; + cmd.alpha = alpha; + cmd.color = color; + cmd.blendMode = blendMode; + cmd.uv = uv == undefined ? null : uv; + if (color) { + cmd.colorFlt = new ColorFilter(); + cmd.colorFlt.setColor(color); + } + return cmd; + } + recover() { + this.texture && this.texture._removeReference(); + this.texture = null; + this.matrix = null; + Pool.recover("DrawTextureCmd", this); + } + run(context, gx, gy) { + this.texture && context.drawTextureWithTransform(this.texture, this.x, this.y, this.width, this.height, this.matrix, gx, gy, this.alpha, this.blendMode, this.colorFlt, this.uv); + } + get cmdID() { + return DrawTextureCmd.ID; + } + } + DrawTextureCmd.ID = "DrawTexture"; + + class FillTextureCmd { + static create(texture, x, y, width, height, type, offset, other) { + var cmd = Pool.getItemByClass("FillTextureCmd", FillTextureCmd); + cmd.texture = texture; + cmd.x = x; + cmd.y = y; + cmd.width = width; + cmd.height = height; + cmd.type = type; + cmd.offset = offset; + cmd.other = other; + return cmd; + } + recover() { + this.texture = null; + this.offset = null; + this.other = null; + Pool.recover("FillTextureCmd", this); + } + run(context, gx, gy) { + context.fillTexture(this.texture, this.x + gx, this.y + gy, this.width, this.height, this.type, this.offset, this.other); + } + get cmdID() { + return FillTextureCmd.ID; + } + } + FillTextureCmd.ID = "FillTexture"; + + class RestoreCmd { + static create() { + var cmd = Pool.getItemByClass("RestoreCmd", RestoreCmd); + return cmd; + } + recover() { + Pool.recover("RestoreCmd", this); + } + run(context, gx, gy) { + context.restore(); + } + get cmdID() { + return RestoreCmd.ID; + } + } + RestoreCmd.ID = "Restore"; + + class RotateCmd { + static create(angle, pivotX, pivotY) { + var cmd = Pool.getItemByClass("RotateCmd", RotateCmd); + cmd.angle = angle; + cmd.pivotX = pivotX; + cmd.pivotY = pivotY; + return cmd; + } + recover() { + Pool.recover("RotateCmd", this); + } + run(context, gx, gy) { + context._rotate(this.angle, this.pivotX + gx, this.pivotY + gy); + } + get cmdID() { + return RotateCmd.ID; + } + } + RotateCmd.ID = "Rotate"; + + class ScaleCmd { + static create(scaleX, scaleY, pivotX, pivotY) { + var cmd = Pool.getItemByClass("ScaleCmd", ScaleCmd); + cmd.scaleX = scaleX; + cmd.scaleY = scaleY; + cmd.pivotX = pivotX; + cmd.pivotY = pivotY; + return cmd; + } + recover() { + Pool.recover("ScaleCmd", this); + } + run(context, gx, gy) { + context._scale(this.scaleX, this.scaleY, this.pivotX + gx, this.pivotY + gy); + } + get cmdID() { + return ScaleCmd.ID; + } + } + ScaleCmd.ID = "Scale"; + + class TransformCmd { + static create(matrix, pivotX, pivotY) { + var cmd = Pool.getItemByClass("TransformCmd", TransformCmd); + cmd.matrix = matrix; + cmd.pivotX = pivotX; + cmd.pivotY = pivotY; + return cmd; + } + recover() { + this.matrix = null; + Pool.recover("TransformCmd", this); + } + run(context, gx, gy) { + context._transform(this.matrix, this.pivotX + gx, this.pivotY + gy); + } + get cmdID() { + return TransformCmd.ID; + } + } + TransformCmd.ID = "Transform"; + + class TranslateCmd { + static create(tx, ty) { + var cmd = Pool.getItemByClass("TranslateCmd", TranslateCmd); + cmd.tx = tx; + cmd.ty = ty; + return cmd; + } + recover() { + Pool.recover("TranslateCmd", this); + } + run(context, gx, gy) { + context.translate(this.tx, this.ty); + } + get cmdID() { + return TranslateCmd.ID; + } + } + TranslateCmd.ID = "Translate"; + + class Bezier { + constructor() { + this._controlPoints = [new Point(), new Point(), new Point()]; + this._calFun = this.getPoint2; + } + _switchPoint(x, y) { + var tPoint = this._controlPoints.shift(); + tPoint.setTo(x, y); + this._controlPoints.push(tPoint); + } + getPoint2(t, rst) { + var p1 = this._controlPoints[0]; + var p2 = this._controlPoints[1]; + var p3 = this._controlPoints[2]; + var lineX = Math.pow((1 - t), 2) * p1.x + 2 * t * (1 - t) * p2.x + Math.pow(t, 2) * p3.x; + var lineY = Math.pow((1 - t), 2) * p1.y + 2 * t * (1 - t) * p2.y + Math.pow(t, 2) * p3.y; + rst.push(lineX, lineY); + } + getPoint3(t, rst) { + var p1 = this._controlPoints[0]; + var p2 = this._controlPoints[1]; + var p3 = this._controlPoints[2]; + var p4 = this._controlPoints[3]; + var lineX = Math.pow((1 - t), 3) * p1.x + 3 * p2.x * t * (1 - t) * (1 - t) + 3 * p3.x * t * t * (1 - t) + p4.x * Math.pow(t, 3); + var lineY = Math.pow((1 - t), 3) * p1.y + 3 * p2.y * t * (1 - t) * (1 - t) + 3 * p3.y * t * t * (1 - t) + p4.y * Math.pow(t, 3); + rst.push(lineX, lineY); + } + insertPoints(count, rst) { + var i; + count = count > 0 ? count : 5; + var dLen; + dLen = 1 / count; + for (i = 0; i <= 1; i += dLen) { + this._calFun(i, rst); + } + } + getBezierPoints(pList, inSertCount = 5, count = 2) { + var i, len; + len = pList.length; + if (len < (count + 1) * 2) + return []; + var rst = []; + switch (count) { + case 2: + this._calFun = this.getPoint2; + break; + case 3: + this._calFun = this.getPoint3; + break; + default: + return []; + } + while (this._controlPoints.length <= count) { + this._controlPoints.push(Point.create()); + } + for (i = 0; i < count * 2; i += 2) { + this._switchPoint(pList[i], pList[i + 1]); + } + for (i = count * 2; i < len; i += 2) { + this._switchPoint(pList[i], pList[i + 1]); + if ((i / 2) % count == 0) + this.insertPoints(inSertCount, rst); + } + return rst; + } + } + Bezier.I = new Bezier(); + + class GrahamScan { + static multiply(p1, p2, p0) { + return ((p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y)); + } + static dis(p1, p2) { + return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y); + } + static _getPoints(count, tempUse = false, rst = null) { + if (!GrahamScan._mPointList) + GrahamScan._mPointList = []; + while (GrahamScan._mPointList.length < count) + GrahamScan._mPointList.push(new Point()); + if (!rst) + rst = []; + rst.length = 0; + if (tempUse) { + GrahamScan.getFrom(rst, GrahamScan._mPointList, count); + } + else { + GrahamScan.getFromR(rst, GrahamScan._mPointList, count); + } + return rst; + } + static getFrom(rst, src, count) { + var i; + for (i = 0; i < count; i++) { + rst.push(src[i]); + } + return rst; + } + static getFromR(rst, src, count) { + var i; + for (i = 0; i < count; i++) { + rst.push(src.pop()); + } + return rst; + } + static pListToPointList(pList, tempUse = false) { + var i, len = pList.length / 2, rst = GrahamScan._getPoints(len, tempUse, GrahamScan._tempPointList); + for (i = 0; i < len; i++) { + rst[i].setTo(pList[i + i], pList[i + i + 1]); + } + return rst; + } + static pointListToPlist(pointList) { + var i, len = pointList.length, rst = GrahamScan._temPList, tPoint; + rst.length = 0; + for (i = 0; i < len; i++) { + tPoint = pointList[i]; + rst.push(tPoint.x, tPoint.y); + } + return rst; + } + static scanPList(pList) { + return Utils.copyArray(pList, GrahamScan.pointListToPlist(GrahamScan.scan(GrahamScan.pListToPointList(pList, true)))); + } + static scan(PointSet) { + var i, j, k = 0, tmp, n = PointSet.length, ch; + var _tmpDic = {}; + var key; + ch = GrahamScan._temArr; + ch.length = 0; + n = PointSet.length; + for (i = n - 1; i >= 0; i--) { + tmp = PointSet[i]; + key = tmp.x + "_" + tmp.y; + if (!(key in _tmpDic)) { + _tmpDic[key] = true; + ch.push(tmp); + } + } + n = ch.length; + Utils.copyArray(PointSet, ch); + for (i = 1; i < n; i++) + if ((PointSet[i].y < PointSet[k].y) || ((PointSet[i].y == PointSet[k].y) && (PointSet[i].x < PointSet[k].x))) + k = i; + tmp = PointSet[0]; + PointSet[0] = PointSet[k]; + PointSet[k] = tmp; + for (i = 1; i < n - 1; i++) { + k = i; + for (j = i + 1; j < n; j++) + if ((GrahamScan.multiply(PointSet[j], PointSet[k], PointSet[0]) > 0) || ((GrahamScan.multiply(PointSet[j], PointSet[k], PointSet[0]) == 0) && (GrahamScan.dis(PointSet[0], PointSet[j]) < GrahamScan.dis(PointSet[0], PointSet[k])))) + k = j; + tmp = PointSet[i]; + PointSet[i] = PointSet[k]; + PointSet[k] = tmp; + } + ch = GrahamScan._temArr; + ch.length = 0; + if (PointSet.length < 3) { + return Utils.copyArray(ch, PointSet); + } + ch.push(PointSet[0], PointSet[1], PointSet[2]); + for (i = 3; i < n; i++) { + while (ch.length >= 2 && GrahamScan.multiply(PointSet[i], ch[ch.length - 1], ch[ch.length - 2]) >= 0) + ch.pop(); + PointSet[i] && ch.push(PointSet[i]); + } + return ch; + } + } + GrahamScan._tempPointList = []; + GrahamScan._temPList = []; + GrahamScan._temArr = []; + + class DrawStyle { + constructor(value) { + this.setValue(value); + } + static create(value) { + if (value) { + var color = (value instanceof ColorUtils) ? value : ColorUtils.create(value); + return color._drawStyle || (color._drawStyle = new DrawStyle(value)); + } + return DrawStyle.DEFAULT; + } + setValue(value) { + if (value) { + this._color = (value instanceof ColorUtils) ? value : ColorUtils.create(value); + } + else + this._color = ColorUtils.create("#000000"); + } + reset() { + this._color = ColorUtils.create("#000000"); + } + toInt() { + return this._color.numColor; + } + equal(value) { + if (typeof (value) == 'string') + return this._color.strColor === value; + if (value instanceof ColorUtils) + return this._color.numColor === value.numColor; + return false; + } + toColorStr() { + return this._color.strColor; + } + } + DrawStyle.DEFAULT = new DrawStyle("#000000"); + + class Path { + constructor() { + this._lastOriX = 0; + this._lastOriY = 0; + this.paths = []; + this._curPath = null; + } + beginPath(convex) { + this.paths.length = 1; + this._curPath = this.paths[0] = new renderPath(); + this._curPath.convex = convex; + } + closePath() { + this._curPath.loop = true; + } + newPath() { + this._curPath = new renderPath(); + this.paths.push(this._curPath); + } + addPoint(pointX, pointY) { + this._curPath.path.push(pointX, pointY); + } + push(points, convex) { + if (!this._curPath) { + this._curPath = new renderPath(); + this.paths.push(this._curPath); + } + else if (this._curPath.path.length > 0) { + this._curPath = new renderPath(); + this.paths.push(this._curPath); + } + var rp = this._curPath; + rp.path = points.slice(); + rp.convex = convex; + } + reset() { + this.paths.length = 0; + } + } + class renderPath { + constructor() { + this.path = []; + this.loop = false; + this.convex = false; + } + } + + class SubmitBase { + constructor(renderType = SubmitBase.TYPE_2D) { + this.clipInfoID = -1; + this._mesh = null; + this._blendFn = null; + this._id = 0; + this._renderType = 0; + this._parent = null; + this._key = new SubmitKey(); + this._startIdx = 0; + this._numEle = 0; + this._ref = 1; + this.shaderValue = null; + this._renderType = renderType; + this._id = ++SubmitBase.ID; + } + static __init__() { + var s = SubmitBase.RENDERBASE = new SubmitBase(-1); + s.shaderValue = new Value2D(0, 0); + s.shaderValue.ALPHA = 1; + s._ref = 0xFFFFFFFF; + } + getID() { + return this._id; + } + getRenderType() { + return this._renderType; + } + toString() { + return "ibindex:" + this._startIdx + " num:" + this._numEle + " key=" + this._key; + } + renderSubmit() { return 1; } + releaseRender() { } + } + SubmitBase.TYPE_2D = 10000; + SubmitBase.TYPE_CANVAS = 10003; + SubmitBase.TYPE_CMDSETRT = 10004; + SubmitBase.TYPE_CUSTOM = 10005; + SubmitBase.TYPE_BLURRT = 10006; + SubmitBase.TYPE_CMDDESTORYPRERT = 10007; + SubmitBase.TYPE_DISABLESTENCIL = 10008; + SubmitBase.TYPE_OTHERIBVB = 10009; + SubmitBase.TYPE_PRIMITIVE = 10010; + SubmitBase.TYPE_RT = 10011; + SubmitBase.TYPE_BLUR_RT = 10012; + SubmitBase.TYPE_TARGET = 10013; + SubmitBase.TYPE_CHANGE_VALUE = 10014; + SubmitBase.TYPE_SHAPE = 10015; + SubmitBase.TYPE_TEXTURE = 10016; + SubmitBase.TYPE_FILLTEXTURE = 10017; + SubmitBase.KEY_ONCE = -1; + SubmitBase.KEY_FILLRECT = 1; + SubmitBase.KEY_DRAWTEXTURE = 2; + SubmitBase.KEY_VG = 3; + SubmitBase.KEY_TRIANGLES = 4; + SubmitBase.ID = 1; + SubmitBase.preRender = null; + + class SaveBase { + constructor() { + } + static _createArray() { + var value = []; + value._length = 0; + return value; + } + static _init() { + var namemap = SaveBase._namemap = {}; + namemap[SaveBase.TYPE_ALPHA] = "ALPHA"; + namemap[SaveBase.TYPE_FILESTYLE] = "fillStyle"; + namemap[SaveBase.TYPE_FONT] = "font"; + namemap[SaveBase.TYPE_LINEWIDTH] = "lineWidth"; + namemap[SaveBase.TYPE_STROKESTYLE] = "strokeStyle"; + namemap[SaveBase.TYPE_ENABLEMERGE] = "_mergeID"; + namemap[SaveBase.TYPE_MARK] = namemap[SaveBase.TYPE_TRANSFORM] = namemap[SaveBase.TYPE_TRANSLATE] = []; + namemap[SaveBase.TYPE_TEXTBASELINE] = "textBaseline"; + namemap[SaveBase.TYPE_TEXTALIGN] = "textAlign"; + namemap[SaveBase.TYPE_GLOBALCOMPOSITEOPERATION] = "_nBlendType"; + namemap[SaveBase.TYPE_SHADER] = "shader"; + namemap[SaveBase.TYPE_FILTERS] = "filters"; + namemap[SaveBase.TYPE_COLORFILTER] = '_colorFiler'; + return namemap; + } + isSaveMark() { return false; } + restore(context) { + this._dataObj[this._valueName] = this._value; + SaveBase.POOL[SaveBase.POOL._length++] = this; + this._newSubmit && (context._curSubmit = SubmitBase.RENDERBASE); + } + static save(context, type, dataObj, newSubmit) { + if ((context._saveMark._saveuse & type) !== type) { + context._saveMark._saveuse |= type; + var cache = SaveBase.POOL; + var o = cache._length > 0 ? cache[--cache._length] : (new SaveBase()); + o._value = dataObj[o._valueName = SaveBase._namemap[type]]; + o._dataObj = dataObj; + o._newSubmit = newSubmit; + var _save = context._save; + _save[_save._length++] = o; + } + } + } + SaveBase.TYPE_ALPHA = 0x1; + SaveBase.TYPE_FILESTYLE = 0x2; + SaveBase.TYPE_FONT = 0x8; + SaveBase.TYPE_LINEWIDTH = 0x100; + SaveBase.TYPE_STROKESTYLE = 0x200; + SaveBase.TYPE_MARK = 0x400; + SaveBase.TYPE_TRANSFORM = 0x800; + SaveBase.TYPE_TRANSLATE = 0x1000; + SaveBase.TYPE_ENABLEMERGE = 0x2000; + SaveBase.TYPE_TEXTBASELINE = 0x4000; + SaveBase.TYPE_TEXTALIGN = 0x8000; + SaveBase.TYPE_GLOBALCOMPOSITEOPERATION = 0x10000; + SaveBase.TYPE_CLIPRECT = 0x20000; + SaveBase.TYPE_CLIPRECT_STENCIL = 0x40000; + SaveBase.TYPE_IBVB = 0x80000; + SaveBase.TYPE_SHADER = 0x100000; + SaveBase.TYPE_FILTERS = 0x200000; + SaveBase.TYPE_FILTERS_TYPE = 0x400000; + SaveBase.TYPE_COLORFILTER = 0x800000; + SaveBase.POOL = SaveBase._createArray(); + SaveBase._namemap = SaveBase._init(); + + class SaveClipRect { + constructor() { + this._globalClipMatrix = new Matrix(); + this._clipInfoID = -1; + this._clipRect = new Rectangle(); + this.incache = false; + } + isSaveMark() { return false; } + restore(context) { + this._globalClipMatrix.copyTo(context._globalClipMatrix); + this._clipRect.clone(context._clipRect); + context._clipInfoID = this._clipInfoID; + SaveClipRect.POOL[SaveClipRect.POOL._length++] = this; + context._clipInCache = this.incache; + } + static save(context) { + if ((context._saveMark._saveuse & SaveBase.TYPE_CLIPRECT) == SaveBase.TYPE_CLIPRECT) + return; + context._saveMark._saveuse |= SaveBase.TYPE_CLIPRECT; + var cache = SaveClipRect.POOL; + var o = cache._length > 0 ? cache[--cache._length] : (new SaveClipRect()); + context._globalClipMatrix.copyTo(o._globalClipMatrix); + context._clipRect.clone(o._clipRect); + o._clipInfoID = context._clipInfoID; + o.incache = context._clipInCache; + var _save = context._save; + _save[_save._length++] = o; + } + } + SaveClipRect.POOL = SaveBase._createArray(); + + class SaveMark { + constructor() { + this._saveuse = 0; + } + isSaveMark() { + return true; + } + restore(context) { + context._saveMark = this._preSaveMark; + SaveMark.POOL[SaveMark.POOL._length++] = this; + } + static Create(context) { + var no = SaveMark.POOL; + var o = no._length > 0 ? no[--no._length] : (new SaveMark()); + o._saveuse = 0; + o._preSaveMark = context._saveMark; + context._saveMark = o; + return o; + } + } + SaveMark.POOL = SaveBase._createArray(); + + class SaveTransform { + constructor() { + this._matrix = new Matrix(); + } + isSaveMark() { return false; } + restore(context) { + context._curMat = this._savematrix; + SaveTransform.POOL[SaveTransform.POOL._length++] = this; + } + static save(context) { + var _saveMark = context._saveMark; + if ((_saveMark._saveuse & SaveBase.TYPE_TRANSFORM) === SaveBase.TYPE_TRANSFORM) + return; + _saveMark._saveuse |= SaveBase.TYPE_TRANSFORM; + var no = SaveTransform.POOL; + var o = no._length > 0 ? no[--no._length] : (new SaveTransform()); + o._savematrix = context._curMat; + context._curMat = context._curMat.copyTo(o._matrix); + var _save = context._save; + _save[_save._length++] = o; + } + } + SaveTransform.POOL = SaveBase._createArray(); + + class SaveTranslate { + constructor() { + this._mat = new Matrix(); + } + isSaveMark() { return false; } + restore(context) { + this._mat.copyTo(context._curMat); + SaveTranslate.POOL[SaveTranslate.POOL._length++] = this; + } + static save(context) { + var no = SaveTranslate.POOL; + var o = no._length > 0 ? no[--no._length] : (new SaveTranslate()); + context._curMat.copyTo(o._mat); + var _save = context._save; + _save[_save._length++] = o; + } + } + SaveTranslate.POOL = SaveBase._createArray(); + + class BufferStateBase { + constructor() { + this._nativeVertexArrayObject = LayaGL.layaGPUInstance.createVertexArray(); + } + bind() { + if (BufferStateBase._curBindedBufferState !== this) { + LayaGL.layaGPUInstance.bindVertexArray(this._nativeVertexArrayObject); + BufferStateBase._curBindedBufferState = this; + } + } + unBind() { + if (BufferStateBase._curBindedBufferState === this) { + LayaGL.layaGPUInstance.bindVertexArray(null); + BufferStateBase._curBindedBufferState = null; + } + else { + throw "BufferState: must call bind() function first."; + } + } + destroy() { + LayaGL.layaGPUInstance.deleteVertexArray(this._nativeVertexArrayObject); + } + bindForNative() { + LayaGL.instance.bindVertexArray(this._nativeVertexArrayObject); + BufferStateBase._curBindedBufferState = this; + } + unBindForNative() { + LayaGL.instance.bindVertexArray(null); + BufferStateBase._curBindedBufferState = null; + } + } + + class BufferState2D extends BufferStateBase { + constructor() { + super(); + } + } + + class Buffer { + constructor() { + this._byteLength = 0; + this._glBuffer = LayaGL.instance.createBuffer(); + } + get bufferUsage() { + return this._bufferUsage; + } + _bindForVAO() { + } + bind() { + return false; + } + destroy() { + if (this._glBuffer) { + LayaGL.instance.deleteBuffer(this._glBuffer); + this._glBuffer = null; + } + } + } + + class RenderInfo { + } + RenderInfo.loopStTm = 0; + RenderInfo.loopCount = 0; + + class Buffer2D extends Buffer { + constructor() { + super(); + this._maxsize = 0; + this._upload = true; + this._uploadSize = 0; + this._bufferSize = 0; + this._u8Array = null; + } + static __int__(gl) { + } + get bufferLength() { + return this._buffer.byteLength; + } + set byteLength(value) { + this.setByteLength(value); + } + setByteLength(value) { + if (this._byteLength !== value) { + value <= this._bufferSize || (this._resizeBuffer(value * 2 + 256, true)); + this._byteLength = value; + } + } + needSize(sz) { + var old = this._byteLength; + if (sz) { + var needsz = this._byteLength + sz; + needsz <= this._bufferSize || (this._resizeBuffer(needsz << 1, true)); + this._byteLength = needsz; + } + return old; + } + _bufferData() { + this._maxsize = Math.max(this._maxsize, this._byteLength); + if (RenderInfo.loopCount % 30 == 0) { + if (this._buffer.byteLength > (this._maxsize + 64)) { + this._buffer = this._buffer.slice(0, this._maxsize + 64); + this._bufferSize = this._buffer.byteLength; + this._checkArrayUse(); + } + this._maxsize = this._byteLength; + } + if (this._uploadSize < this._buffer.byteLength) { + this._uploadSize = this._buffer.byteLength; + LayaGL.instance.bufferData(this._bufferType, this._uploadSize, this._bufferUsage); + } + LayaGL.instance.bufferSubData(this._bufferType, 0, new Uint8Array(this._buffer, 0, this._byteLength)); + } + _bufferSubData(offset = 0, dataStart = 0, dataLength = 0) { + this._maxsize = Math.max(this._maxsize, this._byteLength); + if (RenderInfo.loopCount % 30 == 0) { + if (this._buffer.byteLength > (this._maxsize + 64)) { + this._buffer = this._buffer.slice(0, this._maxsize + 64); + this._bufferSize = this._buffer.byteLength; + this._checkArrayUse(); + } + this._maxsize = this._byteLength; + } + if (this._uploadSize < this._buffer.byteLength) { + this._uploadSize = this._buffer.byteLength; + LayaGL.instance.bufferData(this._bufferType, this._uploadSize, this._bufferUsage); + } + if (dataStart || dataLength) { + var subBuffer = this._buffer.slice(dataStart, dataLength); + LayaGL.instance.bufferSubData(this._bufferType, offset, subBuffer); + } + else { + LayaGL.instance.bufferSubData(this._bufferType, offset, this._buffer); + } + } + _checkArrayUse() { + } + _bind_uploadForVAO() { + if (!this._upload) + return false; + this._upload = false; + this._bindForVAO(); + this._bufferData(); + return true; + } + _bind_upload() { + if (!this._upload) + return false; + this._upload = false; + this.bind(); + this._bufferData(); + return true; + } + _bind_subUpload(offset = 0, dataStart = 0, dataLength = 0) { + if (!this._upload) + return false; + this._upload = false; + this.bind(); + this._bufferSubData(offset, dataStart, dataLength); + return true; + } + _resizeBuffer(nsz, copy) { + var buff = this._buffer; + if (nsz <= buff.byteLength) + return this; + var u8buf = this._u8Array; + if (copy && buff && buff.byteLength > 0) { + var newbuffer = new ArrayBuffer(nsz); + var oldU8Arr = (u8buf && u8buf.buffer == buff) ? u8buf : new Uint8Array(buff); + u8buf = this._u8Array = new Uint8Array(newbuffer); + u8buf.set(oldU8Arr, 0); + buff = this._buffer = newbuffer; + } + else { + buff = this._buffer = new ArrayBuffer(nsz); + this._u8Array = null; + } + this._checkArrayUse(); + this._upload = true; + this._bufferSize = buff.byteLength; + return this; + } + append(data) { + this._upload = true; + var byteLen, n; + byteLen = data.byteLength; + if (data instanceof Uint8Array) { + this._resizeBuffer(this._byteLength + byteLen, true); + n = new Uint8Array(this._buffer, this._byteLength); + } + else if (data instanceof Uint16Array) { + this._resizeBuffer(this._byteLength + byteLen, true); + n = new Uint16Array(this._buffer, this._byteLength); + } + else if (data instanceof Float32Array) { + this._resizeBuffer(this._byteLength + byteLen, true); + n = new Float32Array(this._buffer, this._byteLength); + } + n.set(data, 0); + this._byteLength += byteLen; + this._checkArrayUse(); + } + appendU16Array(data, len) { + this._resizeBuffer(this._byteLength + len * 2, true); + var u = new Uint16Array(this._buffer, this._byteLength, len); + if (len == 6) { + u[0] = data[0]; + u[1] = data[1]; + u[2] = data[2]; + u[3] = data[3]; + u[4] = data[4]; + u[5] = data[5]; + } + else if (len >= 100) { + u.set(new Uint16Array(data.buffer, 0, len)); + } + else { + for (var i = 0; i < len; i++) { + u[i] = data[i]; + } + } + this._byteLength += len * 2; + this._checkArrayUse(); + } + appendEx(data, type) { + this._upload = true; + var byteLen, n; + byteLen = data.byteLength; + this._resizeBuffer(this._byteLength + byteLen, true); + n = new type(this._buffer, this._byteLength); + n.set(data, 0); + this._byteLength += byteLen; + this._checkArrayUse(); + } + appendEx2(data, type, dataLen, perDataLen = 1) { + this._upload = true; + var byteLen, n; + byteLen = dataLen * perDataLen; + this._resizeBuffer(this._byteLength + byteLen, true); + n = new type(this._buffer, this._byteLength); + var i; + for (i = 0; i < dataLen; i++) { + n[i] = data[i]; + } + this._byteLength += byteLen; + this._checkArrayUse(); + } + getBuffer() { + return this._buffer; + } + setNeedUpload() { + this._upload = true; + } + getNeedUpload() { + return this._upload; + } + upload() { + var gl = LayaGL.instance; + var scuess = this._bind_upload(); + gl.bindBuffer(this._bufferType, null); + if (this._bufferType == gl.ARRAY_BUFFER) + Buffer._bindedVertexBuffer = null; + if (this._bufferType == gl.ELEMENT_ARRAY_BUFFER) + Buffer._bindedIndexBuffer = null; + BaseShader.activeShader = null; + return scuess; + } + subUpload(offset = 0, dataStart = 0, dataLength = 0) { + var gl = LayaGL.instance; + var scuess = this._bind_subUpload(); + gl.bindBuffer(this._bufferType, null); + if (this._bufferType == gl.ARRAY_BUFFER) + Buffer._bindedVertexBuffer = null; + if (this._bufferType == gl.ELEMENT_ARRAY_BUFFER) + Buffer._bindedIndexBuffer = null; + BaseShader.activeShader = null; + return scuess; + } + _disposeResource() { + this._upload = true; + this._uploadSize = 0; + } + clear() { + this._byteLength = 0; + this._upload = true; + } + } + Buffer2D.FLOAT32 = 4; + Buffer2D.SHORT = 2; + + class IndexBuffer2D extends Buffer2D { + constructor(bufferUsage = 0x88e4) { + super(); + this._bufferUsage = bufferUsage; + this._bufferType = LayaGL.instance.ELEMENT_ARRAY_BUFFER; + this._buffer = new ArrayBuffer(8); + } + _checkArrayUse() { + this._uint16Array && (this._uint16Array = new Uint16Array(this._buffer)); + } + getUint16Array() { + return this._uint16Array || (this._uint16Array = new Uint16Array(this._buffer)); + } + _bindForVAO() { + var gl = LayaGL.instance; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._glBuffer); + } + bind() { + if (Buffer._bindedIndexBuffer !== this._glBuffer) { + var gl = LayaGL.instance; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._glBuffer); + Buffer._bindedIndexBuffer = this._glBuffer; + return true; + } + return false; + } + destory() { + this._uint16Array = null; + this._buffer = null; + } + disposeResource() { + this._disposeResource(); + } + } + IndexBuffer2D.create = function (bufferUsage = 0x88e4) { + return new IndexBuffer2D(bufferUsage); + }; + + class VertexBuffer2D extends Buffer2D { + constructor(vertexStride, bufferUsage) { + super(); + this._vertexStride = vertexStride; + this._bufferUsage = bufferUsage; + this._bufferType = LayaGL.instance.ARRAY_BUFFER; + this._buffer = new ArrayBuffer(8); + this._floatArray32 = new Float32Array(this._buffer); + this._uint32Array = new Uint32Array(this._buffer); + } + get vertexStride() { + return this._vertexStride; + } + getFloat32Array() { + return this._floatArray32; + } + appendArray(data) { + var oldoff = this._byteLength >> 2; + this.setByteLength(this._byteLength + data.length * 4); + var vbdata = this.getFloat32Array(); + vbdata.set(data, oldoff); + this._upload = true; + } + _checkArrayUse() { + this._floatArray32 && (this._floatArray32 = new Float32Array(this._buffer)); + this._uint32Array && (this._uint32Array = new Uint32Array(this._buffer)); + } + deleteBuffer() { + super._disposeResource(); + } + _bindForVAO() { + var gl = LayaGL.instance; + gl.bindBuffer(gl.ARRAY_BUFFER, this._glBuffer); + } + bind() { + if (Buffer._bindedVertexBuffer !== this._glBuffer) { + var gl = LayaGL.instance; + gl.bindBuffer(gl.ARRAY_BUFFER, this._glBuffer); + Buffer._bindedVertexBuffer = this._glBuffer; + return true; + } + return false; + } + destroy() { + super.destroy(); + this._byteLength = 0; + this._upload = true; + this._buffer = null; + this._floatArray32 = null; + } + } + VertexBuffer2D.create = function (vertexStride, bufferUsage = 0x88e8) { + return new VertexBuffer2D(vertexStride, bufferUsage); + }; + + class Mesh2D { + constructor(stride, vballoc, iballoc) { + this._stride = 0; + this.vertNum = 0; + this.indexNum = 0; + this._applied = false; + this._quadNum = 0; + this.canReuse = false; + this._stride = stride; + this._vb = new VertexBuffer2D(stride, LayaGL.instance.DYNAMIC_DRAW); + if (vballoc) { + this._vb._resizeBuffer(vballoc, false); + } + else { + Config.webGL2D_MeshAllocMaxMem && this._vb._resizeBuffer(64 * 1024 * stride, false); + } + this._ib = new IndexBuffer2D(); + if (iballoc) { + this._ib._resizeBuffer(iballoc, false); + } + } + cloneWithNewVB() { + var mesh = new Mesh2D(this._stride, 0, 0); + mesh._ib = this._ib; + mesh._quadNum = this._quadNum; + mesh._attribInfo = this._attribInfo; + return mesh; + } + cloneWithNewVBIB() { + var mesh = new Mesh2D(this._stride, 0, 0); + mesh._attribInfo = this._attribInfo; + return mesh; + } + getVBW() { + this._vb.setNeedUpload(); + return this._vb; + } + getVBR() { + return this._vb; + } + getIBR() { + return this._ib; + } + getIBW() { + this._ib.setNeedUpload(); + return this._ib; + } + createQuadIB(QuadNum) { + this._quadNum = QuadNum; + this._ib._resizeBuffer(QuadNum * 6 * 2, false); + this._ib.byteLength = this._ib.bufferLength; + var bd = this._ib.getUint16Array(); + var idx = 0; + var curvert = 0; + for (var i = 0; i < QuadNum; i++) { + bd[idx++] = curvert; + bd[idx++] = curvert + 2; + bd[idx++] = curvert + 1; + bd[idx++] = curvert; + bd[idx++] = curvert + 3; + bd[idx++] = curvert + 2; + curvert += 4; + } + this._ib.setNeedUpload(); + } + setAttributes(attribs) { + this._attribInfo = attribs; + if (this._attribInfo.length % 3 != 0) { + throw 'Mesh2D setAttributes error!'; + } + } + configVAO(gl) { + if (this._applied) + return; + this._applied = true; + if (!this._vao) { + this._vao = new BufferState2D(); + } + this._vao.bind(); + this._vb._bindForVAO(); + this._ib.setNeedUpload(); + this._ib._bind_uploadForVAO(); + var attribNum = this._attribInfo.length / 3; + var idx = 0; + for (var i = 0; i < attribNum; i++) { + var _size = this._attribInfo[idx + 1]; + var _type = this._attribInfo[idx]; + var _off = this._attribInfo[idx + 2]; + gl.enableVertexAttribArray(i); + gl.vertexAttribPointer(i, _size, _type, false, this._stride, _off); + idx += 3; + } + this._vao.unBind(); + } + useMesh(gl) { + this._applied || this.configVAO(gl); + this._vao.bind(); + this._vb.bind(); + this._ib._bind_upload() || this._ib.bind(); + this._vb._bind_upload() || this._vb.bind(); + } + getEleNum() { + return this._ib.getBuffer().byteLength / 2; + } + releaseMesh() { } + destroy() { + } + clearVB() { + this._vb.clear(); + } + } + Mesh2D._gvaoid = 0; + + class MeshQuadTexture extends Mesh2D { + constructor() { + super(MeshQuadTexture.const_stride, 4, 4); + this.canReuse = true; + this.setAttributes(MeshQuadTexture._fixattriInfo); + if (!MeshQuadTexture._fixib) { + this.createQuadIB(MeshQuadTexture._maxIB); + MeshQuadTexture._fixib = this._ib; + } + else { + this._ib = MeshQuadTexture._fixib; + this._quadNum = MeshQuadTexture._maxIB; + } + } + static __int__() { + MeshQuadTexture._fixattriInfo = [5126, 4, 0, + 5121, 4, 16, + 5121, 4, 20]; + } + static getAMesh(mainctx) { + var ret = null; + if (MeshQuadTexture._POOL.length) { + ret = MeshQuadTexture._POOL.pop(); + } + else + ret = new MeshQuadTexture(); + mainctx && ret._vb._resizeBuffer(64 * 1024 * MeshQuadTexture.const_stride, false); + return ret; + } + releaseMesh() { + this._vb.setByteLength(0); + this.vertNum = 0; + this.indexNum = 0; + MeshQuadTexture._POOL.push(this); + } + destroy() { + this._vb.destroy(); + this._vb.deleteBuffer(); + } + addQuad(pos, uv, color, useTex) { + var vb = this._vb; + var vpos = (vb._byteLength >> 2); + vb.setByteLength((vpos + MeshQuadTexture.const_stride) << 2); + var vbdata = vb._floatArray32 || vb.getFloat32Array(); + var vbu32Arr = vb._uint32Array; + var cpos = vpos; + var useTexVal = useTex ? 0xff : 0; + vbdata[cpos++] = pos[0]; + vbdata[cpos++] = pos[1]; + vbdata[cpos++] = uv[0]; + vbdata[cpos++] = uv[1]; + vbu32Arr[cpos++] = color; + vbu32Arr[cpos++] = useTexVal; + vbdata[cpos++] = pos[2]; + vbdata[cpos++] = pos[3]; + vbdata[cpos++] = uv[2]; + vbdata[cpos++] = uv[3]; + vbu32Arr[cpos++] = color; + vbu32Arr[cpos++] = useTexVal; + vbdata[cpos++] = pos[4]; + vbdata[cpos++] = pos[5]; + vbdata[cpos++] = uv[4]; + vbdata[cpos++] = uv[5]; + vbu32Arr[cpos++] = color; + vbu32Arr[cpos++] = useTexVal; + vbdata[cpos++] = pos[6]; + vbdata[cpos++] = pos[7]; + vbdata[cpos++] = uv[6]; + vbdata[cpos++] = uv[7]; + vbu32Arr[cpos++] = color; + vbu32Arr[cpos++] = useTexVal; + vb._upload = true; + } + } + MeshQuadTexture.const_stride = 24; + MeshQuadTexture._maxIB = 16 * 1024; + MeshQuadTexture._POOL = []; + + class MeshTexture extends Mesh2D { + constructor() { + super(MeshTexture.const_stride, 4, 4); + this.canReuse = true; + this.setAttributes(MeshTexture._fixattriInfo); + } + static __init__() { + MeshTexture._fixattriInfo = [5126, 4, 0, + 5121, 4, 16, + 5121, 4, 20]; + } + static getAMesh(mainctx) { + var ret; + if (MeshTexture._POOL.length) { + ret = MeshTexture._POOL.pop(); + } + else + ret = new MeshTexture(); + mainctx && ret._vb._resizeBuffer(64 * 1024 * MeshTexture.const_stride, false); + return ret; + } + addData(vertices, uvs, idx, matrix, rgba) { + var vb = this._vb; + var ib = this._ib; + var vertsz = vertices.length >> 1; + var startpos = vb.needSize(vertsz * MeshTexture.const_stride); + var f32pos = startpos >> 2; + var vbdata = vb._floatArray32 || vb.getFloat32Array(); + var vbu32Arr = vb._uint32Array; + var ci = 0; + var m00 = matrix.a; + var m01 = matrix.b; + var m10 = matrix.c; + var m11 = matrix.d; + var tx = matrix.tx; + var ty = matrix.ty; + var i = 0; + for (i = 0; i < vertsz; i++) { + var x = vertices[ci], y = vertices[ci + 1]; + vbdata[f32pos] = x * m00 + y * m10 + tx; + vbdata[f32pos + 1] = x * m01 + y * m11 + ty; + vbdata[f32pos + 2] = uvs[ci]; + vbdata[f32pos + 3] = uvs[ci + 1]; + vbu32Arr[f32pos + 4] = rgba; + vbu32Arr[f32pos + 5] = 0xff; + f32pos += 6; + ci += 2; + } + vb.setNeedUpload(); + var vertN = this.vertNum; + var sz = idx.length; + var stib = ib.needSize(idx.byteLength); + var cidx = ib.getUint16Array(); + var stibid = stib >> 1; + if (vertN > 0) { + var end = stibid + sz; + var si = 0; + for (i = stibid; i < end; i++, si++) { + cidx[i] = idx[si] + vertN; + } + } + else { + cidx.set(idx, stibid); + } + ib.setNeedUpload(); + this.vertNum += vertsz; + this.indexNum += idx.length; + } + releaseMesh() { + this._vb.setByteLength(0); + this._ib.setByteLength(0); + this.vertNum = 0; + this.indexNum = 0; + MeshTexture._POOL.push(this); + } + destroy() { + this._ib.destroy(); + this._vb.destroy(); + this._ib.disposeResource(); + this._vb.deleteBuffer(); + } + } + MeshTexture.const_stride = 24; + MeshTexture._POOL = []; + + class MeshVG extends Mesh2D { + constructor() { + super(MeshVG.const_stride, 4, 4); + this.canReuse = true; + this.setAttributes(MeshVG._fixattriInfo); + } + static __init__() { + MeshVG._fixattriInfo = [5126, 2, 0, + 5121, 4, 8]; + } + static getAMesh(mainctx) { + var ret; + if (MeshVG._POOL.length) { + ret = MeshVG._POOL.pop(); + } + else + ret = new MeshVG(); + mainctx && ret._vb._resizeBuffer(64 * 1024 * MeshVG.const_stride, false); + return ret; + } + addVertAndIBToMesh(ctx, points, rgba, ib) { + var startpos = this._vb.needSize(points.length / 2 * MeshVG.const_stride); + var f32pos = startpos >> 2; + var vbdata = this._vb._floatArray32 || this._vb.getFloat32Array(); + var vbu32Arr = this._vb._uint32Array; + var ci = 0; + var sz = points.length / 2; + for (var i = 0; i < sz; i++) { + vbdata[f32pos++] = points[ci]; + vbdata[f32pos++] = points[ci + 1]; + ci += 2; + vbu32Arr[f32pos++] = rgba; + } + this._vb.setNeedUpload(); + this._ib.append(new Uint16Array(ib)); + this._ib.setNeedUpload(); + this.vertNum += sz; + this.indexNum += ib.length; + } + releaseMesh() { + this._vb.setByteLength(0); + this._ib.setByteLength(0); + this.vertNum = 0; + this.indexNum = 0; + MeshVG._POOL.push(this); + } + destroy() { + this._ib.destroy(); + this._vb.destroy(); + this._ib.disposeResource(); + this._vb.deleteBuffer(); + } + } + MeshVG.const_stride = 12; + MeshVG._POOL = []; + + class WebGLCacheAsNormalCanvas { + constructor(ctx, sp) { + this.submitStartPos = 0; + this.submitEndPos = 0; + this.touches = []; + this.submits = []; + this.sprite = null; + this.meshlist = []; + this.cachedClipInfo = new Matrix(); + this.oldTx = 0; + this.oldTy = 0; + this.invMat = new Matrix(); + this.context = ctx; + this.sprite = sp; + ctx._globalClipMatrix.copyTo(this.cachedClipInfo); + } + startRec() { + let context = this.context; + if (context._charSubmitCache && context._charSubmitCache._enable) { + context._charSubmitCache.enable(false, context); + context._charSubmitCache.enable(true, context); + } + context._incache = true; + this.touches.length = 0; + context.touches = this.touches; + context._globalClipMatrix.copyTo(this.cachedClipInfo); + this.submits.length = 0; + this.submitStartPos = context._submits._length; + for (var i = 0, sz = this.meshlist.length; i < sz; i++) { + var curm = this.meshlist[i]; + curm.canReuse ? (curm.releaseMesh()) : (curm.destroy()); + } + this.meshlist.length = 0; + this._mesh = MeshQuadTexture.getAMesh(false); + this._pathMesh = MeshVG.getAMesh(false); + this._triangleMesh = MeshTexture.getAMesh(false); + this.meshlist.push(this._mesh); + this.meshlist.push(this._pathMesh); + this.meshlist.push(this._triangleMesh); + context._curSubmit = SubmitBase.RENDERBASE; + this._oldMesh = context._mesh; + this._oldPathMesh = context._pathMesh; + this._oldTriMesh = context._triangleMesh; + this._oldMeshList = context.meshlist; + context._mesh = this._mesh; + context._pathMesh = this._pathMesh; + context._triangleMesh = this._triangleMesh; + context.meshlist = this.meshlist; + this.oldTx = context._curMat.tx; + this.oldTy = context._curMat.ty; + context._curMat.tx = 0; + context._curMat.ty = 0; + context._curMat.copyTo(this.invMat); + this.invMat.invert(); + } + endRec() { + let context = this.context; + if (context._charSubmitCache && context._charSubmitCache._enable) { + context._charSubmitCache.enable(false, context); + context._charSubmitCache.enable(true, context); + } + var parsubmits = context._submits; + this.submitEndPos = parsubmits._length; + var num = this.submitEndPos - this.submitStartPos; + for (var i = 0; i < num; i++) { + this.submits.push(parsubmits[this.submitStartPos + i]); + } + parsubmits._length -= num; + context._mesh = this._oldMesh; + context._pathMesh = this._oldPathMesh; + context._triangleMesh = this._oldTriMesh; + context.meshlist = this._oldMeshList; + context._curSubmit = SubmitBase.RENDERBASE; + context._curMat.tx = this.oldTx; + context._curMat.ty = this.oldTy; + context.touches = null; + context._incache = false; + } + isCacheValid() { + var curclip = this.context._globalClipMatrix; + if (curclip.a != this.cachedClipInfo.a || curclip.b != this.cachedClipInfo.b || curclip.c != this.cachedClipInfo.c + || curclip.d != this.cachedClipInfo.d || curclip.tx != this.cachedClipInfo.tx || curclip.ty != this.cachedClipInfo.ty) + return false; + return true; + } + flushsubmit() { + var curSubmit = SubmitBase.RENDERBASE; + this.submits.forEach(function (subm) { + if (subm == SubmitBase.RENDERBASE) + return; + SubmitBase.preRender = curSubmit; + curSubmit = subm; + subm.renderSubmit(); + }); + } + releaseMem() { + } + } + WebGLCacheAsNormalCanvas.matI = new Matrix(); + + var texture_vs = "/*\r\n\ttexture和fillrect使用的。\r\n*/\r\nattribute vec4 posuv;\r\nattribute vec4 attribColor;\r\nattribute vec4 attribFlags;\r\n//attribute vec4 clipDir;\r\n//attribute vec2 clipRect;\r\nuniform vec4 clipMatDir;\r\nuniform vec2 clipMatPos;\t\t// 这个是全局的,不用再应用矩阵了。\r\nvarying vec2 cliped;\r\nuniform vec2 size;\r\nuniform vec2 clipOff;\t\t\t// 使用要把clip偏移。cacheas normal用. 只用了[0]\r\n#ifdef WORLDMAT\r\n\tuniform mat4 mmat;\r\n#endif\r\n#ifdef MVP3D\r\n\tuniform mat4 u_MvpMatrix;\r\n#endif\r\nvarying vec4 v_texcoordAlpha;\r\nvarying vec4 v_color;\r\nvarying float v_useTex;\r\n\r\nvoid main() {\r\n\r\n\tvec4 pos = vec4(posuv.xy,0.,1.);\r\n#ifdef WORLDMAT\r\n\tpos=mmat*pos;\r\n#endif\r\n\tvec4 pos1 =vec4((pos.x/size.x-0.5)*2.0,(0.5-pos.y/size.y)*2.0,0.,1.0);\r\n#ifdef MVP3D\r\n\tgl_Position=u_MvpMatrix*pos1;\r\n#else\r\n\tgl_Position=pos1;\r\n#endif\r\n\tv_texcoordAlpha.xy = posuv.zw;\r\n\t//v_texcoordAlpha.z = attribColor.a/255.0;\r\n\tv_color = attribColor/255.0;\r\n\tv_color.xyz*=v_color.w;//反正后面也要预乘\r\n\t\r\n\tv_useTex = attribFlags.r/255.0;\r\n\tfloat clipw = length(clipMatDir.xy);\r\n\tfloat cliph = length(clipMatDir.zw);\r\n\t\r\n\tvec2 clpos = clipMatPos.xy;\r\n\t#ifdef WORLDMAT\r\n\t\t// 如果有mmat,需要修改clipMatPos,因为 这是cacheas normal (如果不是就错了), clipMatPos被去掉了偏移\r\n\t\tif(clipOff[0]>0.0){\r\n\t\t\tclpos.x+=mmat[3].x;\t//tx\t最简单处理\r\n\t\t\tclpos.y+=mmat[3].y;\t//ty\r\n\t\t}\r\n\t#endif\r\n\tvec2 clippos = pos.xy - clpos;\t//pos已经应用矩阵了,为了减的有意义,clip的位置也要缩放\r\n\tif(clipw>20000. && cliph>20000.)\r\n\t\tcliped = vec2(0.5,0.5);\r\n\telse {\r\n\t\t//转成0到1之间。/clipw/clipw 表示clippos与normalize之后的clip朝向点积之后,再除以clipw\r\n\t\tcliped=vec2( dot(clippos,clipMatDir.xy)/clipw/clipw, dot(clippos,clipMatDir.zw)/cliph/cliph);\r\n\t}\r\n\r\n}"; + + var texture_ps = "/*\r\n\ttexture和fillrect使用的。\r\n*/\r\n#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\nprecision highp float;\r\n#else\r\nprecision mediump float;\r\n#endif\r\n\r\nvarying vec4 v_texcoordAlpha;\r\nvarying vec4 v_color;\r\nvarying float v_useTex;\r\nuniform sampler2D texture;\r\nvarying vec2 cliped;\r\n\r\n#ifdef BLUR_FILTER\r\nuniform vec4 strength_sig2_2sig2_gauss1;\r\nuniform vec2 blurInfo;\r\n\r\n#define PI 3.141593\r\n\r\nfloat getGaussian(float x, float y){\r\n return strength_sig2_2sig2_gauss1.w*exp(-(x*x+y*y)/strength_sig2_2sig2_gauss1.z);\r\n}\r\n\r\nvec4 blur(){\r\n const float blurw = 9.0;\r\n vec4 vec4Color = vec4(0.0,0.0,0.0,0.0);\r\n vec2 halfsz=vec2(blurw,blurw)/2.0/blurInfo; \r\n vec2 startpos=v_texcoordAlpha.xy-halfsz;\r\n vec2 ctexcoord = startpos;\r\n vec2 step = 1.0/blurInfo; //每个像素 \r\n \r\n for(float y = 0.0;y<=blurw; ++y){\r\n ctexcoord.x=startpos.x;\r\n for(float x = 0.0;x<=blurw; ++x){\r\n //TODO 纹理坐标的固定偏移应该在vs中处理\r\n vec4Color += texture2D(texture, ctexcoord)*getGaussian(x-blurw/2.0,y-blurw/2.0);\r\n ctexcoord.x+=step.x;\r\n }\r\n ctexcoord.y+=step.y;\r\n }\r\n return vec4Color;\r\n}\r\n#endif\r\n\r\n#ifdef COLOR_FILTER\r\nuniform vec4 colorAlpha;\r\nuniform mat4 colorMat;\r\n#endif\r\n\r\n#ifdef GLOW_FILTER\r\nuniform vec4 u_color;\r\nuniform vec4 u_blurInfo1;\r\nuniform vec4 u_blurInfo2;\r\n#endif\r\n\r\n#ifdef COLOR_ADD\r\nuniform vec4 colorAdd;\r\n#endif\r\n\r\n#ifdef FILLTEXTURE\t\r\nuniform vec4 u_TexRange;//startu,startv,urange, vrange\r\n#endif\r\nvoid main() {\r\n\tif(cliped.x<0.) discard;\r\n\tif(cliped.x>1.) discard;\r\n\tif(cliped.y<0.) discard;\r\n\tif(cliped.y>1.) discard;\r\n\t\r\n#ifdef FILLTEXTURE\t\r\n vec4 color= texture2D(texture, fract(v_texcoordAlpha.xy)*u_TexRange.zw + u_TexRange.xy);\r\n#else\r\n vec4 color= texture2D(texture, v_texcoordAlpha.xy);\r\n#endif\r\n\r\n if(v_useTex<=0.)color = vec4(1.,1.,1.,1.);\r\n color.a*=v_color.w;\r\n //color.rgb*=v_color.w;\r\n color.rgb*=v_color.rgb;\r\n gl_FragColor=color;\r\n \r\n #ifdef COLOR_ADD\r\n\tgl_FragColor = vec4(colorAdd.rgb,colorAdd.a*gl_FragColor.a);\r\n\tgl_FragColor.xyz *= colorAdd.a;\r\n #endif\r\n \r\n #ifdef BLUR_FILTER\r\n\tgl_FragColor = blur();\r\n\tgl_FragColor.w*=v_color.w; \r\n #endif\r\n \r\n #ifdef COLOR_FILTER\r\n\tmat4 alphaMat =colorMat;\r\n\r\n\talphaMat[0][3] *= gl_FragColor.a;\r\n\talphaMat[1][3] *= gl_FragColor.a;\r\n\talphaMat[2][3] *= gl_FragColor.a;\r\n\r\n\tgl_FragColor = gl_FragColor * alphaMat;\r\n\tgl_FragColor += colorAlpha/255.0*gl_FragColor.a;\r\n #endif\r\n \r\n #ifdef GLOW_FILTER\r\n\tconst float c_IterationTime = 10.0;\r\n\tfloat floatIterationTotalTime = c_IterationTime * c_IterationTime;\r\n\tvec4 vec4Color = vec4(0.0,0.0,0.0,0.0);\r\n\tvec2 vec2FilterDir = vec2(-(u_blurInfo1.z)/u_blurInfo2.x,-(u_blurInfo1.w)/u_blurInfo2.y);\r\n\tvec2 vec2FilterOff = vec2(u_blurInfo1.x/u_blurInfo2.x/c_IterationTime * 2.0,u_blurInfo1.y/u_blurInfo2.y/c_IterationTime * 2.0);\r\n\tfloat maxNum = u_blurInfo1.x * u_blurInfo1.y;\r\n\tvec2 vec2Off = vec2(0.0,0.0);\r\n\tfloat floatOff = c_IterationTime/2.0;\r\n\tfor(float i = 0.0;i<=c_IterationTime; ++i){\r\n\t\tfor(float j = 0.0;j<=c_IterationTime; ++j){\r\n\t\t\tvec2Off = vec2(vec2FilterOff.x * (i - floatOff),vec2FilterOff.y * (j - floatOff));\r\n\t\t\tvec4Color += texture2D(texture, v_texcoordAlpha.xy + vec2FilterDir + vec2Off)/floatIterationTotalTime;\r\n\t\t}\r\n\t}\r\n\tgl_FragColor = vec4(u_color.rgb,vec4Color.a * u_blurInfo2.z);\r\n\tgl_FragColor.rgb *= gl_FragColor.a; \r\n #endif\r\n \r\n}"; + + var prime_vs = "attribute vec4 position;\r\nattribute vec4 attribColor;\r\n//attribute vec4 clipDir;\r\n//attribute vec2 clipRect;\r\nuniform vec4 clipMatDir;\r\nuniform vec2 clipMatPos;\r\n#ifdef WORLDMAT\r\n\tuniform mat4 mmat;\r\n#endif\r\nuniform mat4 u_mmat2;\r\n//uniform vec2 u_pos;\r\nuniform vec2 size;\r\nvarying vec4 color;\r\n//vec4 dirxy=vec4(0.9,0.1, -0.1,0.9);\r\n//vec4 clip=vec4(100.,30.,300.,600.);\r\nvarying vec2 cliped;\r\nvoid main(){\r\n\t\r\n#ifdef WORLDMAT\r\n\tvec4 pos=mmat*vec4(position.xy,0.,1.);\r\n\tgl_Position =vec4((pos.x/size.x-0.5)*2.0,(0.5-pos.y/size.y)*2.0,pos.z,1.0);\r\n#else\r\n\tgl_Position =vec4((position.x/size.x-0.5)*2.0,(0.5-position.y/size.y)*2.0,position.z,1.0);\r\n#endif\t\r\n\tfloat clipw = length(clipMatDir.xy);\r\n\tfloat cliph = length(clipMatDir.zw);\r\n\tvec2 clippos = position.xy - clipMatPos.xy;\t//pos已经应用矩阵了,为了减的有意义,clip的位置也要缩放\r\n\tif(clipw>20000. && cliph>20000.)\r\n\t\tcliped = vec2(0.5,0.5);\r\n\telse {\r\n\t\t//clipdir是带缩放的方向,由于上面clippos是在缩放后的空间计算的,所以需要把方向先normalize一下\r\n\t\tcliped=vec2( dot(clippos,clipMatDir.xy)/clipw/clipw, dot(clippos,clipMatDir.zw)/cliph/cliph);\r\n\t}\r\n //pos2d.x = dot(clippos,dirx);\r\n color=attribColor/255.;\r\n}"; + + var prime_ps = "precision mediump float;\r\n//precision mediump float;\r\nvarying vec4 color;\r\n//uniform float alpha;\r\nvarying vec2 cliped;\r\nvoid main(){\r\n\t//vec4 a=vec4(color.r, color.g, color.b, 1);\r\n\t//a.a*=alpha;\r\n gl_FragColor= color;// vec4(color.r, color.g, color.b, alpha);\r\n\tgl_FragColor.rgb*=color.a;\r\n\tif(cliped.x<0.) discard;\r\n\tif(cliped.x>1.) discard;\r\n\tif(cliped.y<0.) discard;\r\n\tif(cliped.y>1.) discard;\r\n}"; + + var skin_vs = "attribute vec2 position;\r\nattribute vec2 texcoord;\r\nattribute vec4 color;\r\nuniform vec2 size;\r\nuniform float offsetX;\r\nuniform float offsetY;\r\nuniform mat4 mmat;\r\nuniform mat4 u_mmat2;\r\nvarying vec2 v_texcoord;\r\nvarying vec4 v_color;\r\nvoid main() {\r\n vec4 pos=mmat*u_mmat2*vec4(offsetX+position.x,offsetY+position.y,0,1 );\r\n gl_Position = vec4((pos.x/size.x-0.5)*2.0,(0.5-pos.y/size.y)*2.0,pos.z,1.0);\r\n v_color = color;\r\n v_color.rgb *= v_color.a;\r\n v_texcoord = texcoord; \r\n}"; + + var skin_ps = "precision mediump float;\r\nvarying vec2 v_texcoord;\r\nvarying vec4 v_color;\r\nuniform sampler2D texture;\r\nuniform float alpha;\r\nvoid main() {\r\n\tvec4 t_color = texture2D(texture, v_texcoord);\r\n\tgl_FragColor = t_color.rgba * v_color;\r\n\tgl_FragColor *= alpha;\r\n}"; + + class Shader2D { + constructor() { + this.ALPHA = 1; + this.defines = new ShaderDefines2D(); + this.shaderType = 0; + this.fillStyle = DrawStyle.DEFAULT; + this.strokeStyle = DrawStyle.DEFAULT; + } + destroy() { + this.defines = null; + this.filters = null; + } + static __init__() { + Shader.preCompile2D(0, ShaderDefines2D.TEXTURE2D, texture_vs, texture_ps, null); + Shader.preCompile2D(0, ShaderDefines2D.PRIMITIVE, prime_vs, prime_ps, null); + Shader.preCompile2D(0, ShaderDefines2D.SKINMESH, skin_vs, skin_ps, null); + } + } + + class SkinMeshBuffer { + constructor() { + var gl = LayaGL.instance; + this.ib = IndexBuffer2D.create(gl.DYNAMIC_DRAW); + this.vb = VertexBuffer2D.create(8); + } + static getInstance() { + return SkinMeshBuffer.instance = SkinMeshBuffer.instance || new SkinMeshBuffer(); + } + addSkinMesh(skinMesh) { + skinMesh.getData2(this.vb, this.ib, this.vb._byteLength / 32); + } + reset() { + this.vb.clear(); + this.ib.clear(); + } + } + + class BasePoly { + static createLine2(p, indices, lineWidth, indexBase, outVertex, loop) { + if (p.length < 4) + return null; + var points = BasePoly.tempData.length > (p.length + 2) ? BasePoly.tempData : new Array(p.length + 2); + points[0] = p[0]; + points[1] = p[1]; + var newlen = 2; + var i = 0; + var length = p.length; + for (i = 2; i < length; i += 2) { + if (Math.abs(p[i] - p[i - 2]) + Math.abs(p[i + 1] - p[i - 1]) > 0.01) { + points[newlen++] = p[i]; + points[newlen++] = p[i + 1]; + } + } + if (loop && Math.abs(p[0] - points[newlen - 2]) + Math.abs(p[1] - points[newlen - 1]) > 0.01) { + points[newlen++] = p[0]; + points[newlen++] = p[1]; + } + var result = outVertex; + length = newlen / 2; + var w = lineWidth / 2; + var px, py, p1x, p1y, p2x, p2y, p3x, p3y; + var perpx, perpy, perp2x, perp2y; + var a1, b1, c1, a2, b2, c2; + var denom, dist; + p1x = points[0]; + p1y = points[1]; + p2x = points[2]; + p2y = points[3]; + perpx = -(p1y - p2y); + perpy = p1x - p2x; + dist = Math.sqrt(perpx * perpx + perpy * perpy); + perpx = perpx / dist * w; + perpy = perpy / dist * w; + result.push(p1x - perpx, p1y - perpy, p1x + perpx, p1y + perpy); + for (i = 1; i < length - 1; i++) { + p1x = points[(i - 1) * 2]; + p1y = points[(i - 1) * 2 + 1]; + p2x = points[(i) * 2]; + p2y = points[(i) * 2 + 1]; + p3x = points[(i + 1) * 2]; + p3y = points[(i + 1) * 2 + 1]; + perpx = -(p1y - p2y); + perpy = p1x - p2x; + dist = Math.sqrt(perpx * perpx + perpy * perpy); + perpx = perpx / dist * w; + perpy = perpy / dist * w; + perp2x = -(p2y - p3y); + perp2y = p2x - p3x; + dist = Math.sqrt(perp2x * perp2x + perp2y * perp2y); + perp2x = perp2x / dist * w; + perp2y = perp2y / dist * w; + a1 = (-perpy + p1y) - (-perpy + p2y); + b1 = (-perpx + p2x) - (-perpx + p1x); + c1 = (-perpx + p1x) * (-perpy + p2y) - (-perpx + p2x) * (-perpy + p1y); + a2 = (-perp2y + p3y) - (-perp2y + p2y); + b2 = (-perp2x + p2x) - (-perp2x + p3x); + c2 = (-perp2x + p3x) * (-perp2y + p2y) - (-perp2x + p2x) * (-perp2y + p3y); + denom = a1 * b2 - a2 * b1; + if (Math.abs(denom) < 0.1) { + denom += 10.1; + result.push(p2x - perpx, p2y - perpy, p2x + perpx, p2y + perpy); + continue; + } + px = (b1 * c2 - b2 * c1) / denom; + py = (a2 * c1 - a1 * c2) / denom; + result.push(px, py, p2x - (px - p2x), p2y - (py - p2y)); + } + p1x = points[newlen - 4]; + p1y = points[newlen - 3]; + p2x = points[newlen - 2]; + p2y = points[newlen - 1]; + perpx = -(p1y - p2y); + perpy = p1x - p2x; + dist = Math.sqrt(perpx * perpx + perpy * perpy); + perpx = perpx / dist * w; + perpy = perpy / dist * w; + result.push(p2x - perpx, p2y - perpy, p2x + perpx, p2y + perpy); + for (i = 1; i < length; i++) { + indices.push(indexBase + (i - 1) * 2, indexBase + (i - 1) * 2 + 1, indexBase + i * 2 + 1, indexBase + i * 2 + 1, indexBase + i * 2, indexBase + (i - 1) * 2); + } + return result; + } + static createLineTriangle(path, color, width, loop, outvb, vbstride, outib) { + var points = path.slice(); + var ptlen = points.length; + var p1x = points[0], p1y = points[1]; + var p2x = points[2], p2y = points[2]; + var len = 0; + var rp = 0; + var dx = 0, dy = 0; + var pointnum = ptlen / 2; + if (pointnum <= 1) + return; + if (pointnum == 2) { + return; + } + var tmpData = new Array(pointnum * 4); + var realPtNum = 0; + var ci = 0; + for (var i = 0; i < pointnum - 1; i++) { + p1x = points[ci++], p1y = points[ci++]; + p2x = points[ci++], p2y = points[ci++]; + dx = p2x - p1x, dy = p2y - p1y; + if (dx != 0 && dy != 0) { + len = Math.sqrt(dx * dx + dy * dy); + if (len > 1e-3) { + rp = realPtNum * 4; + tmpData[rp] = p1x; + tmpData[rp + 1] = p1y; + tmpData[rp + 2] = dx / len; + tmpData[rp + 3] = dy / len; + realPtNum++; + } + } + } + if (loop) { + p1x = points[ptlen - 2], p1y = points[ptlen - 1]; + p2x = points[0], p2y = points[1]; + dx = p2x - p1x, dy = p2y - p1y; + if (dx != 0 && dy != 0) { + len = Math.sqrt(dx * dx + dy * dy); + if (len > 1e-3) { + rp = realPtNum * 4; + tmpData[rp] = p1x; + tmpData[rp + 1] = p1y; + tmpData[rp + 2] = dx / len; + tmpData[rp + 3] = dy / len; + realPtNum++; + } + } + } + else { + rp = realPtNum * 4; + tmpData[rp] = p1x; + tmpData[rp + 1] = p1y; + tmpData[rp + 2] = dx / len; + tmpData[rp + 3] = dy / len; + realPtNum++; + } + ci = 0; + for (i = 0; i < pointnum; i++) { + p1x = points[ci], p1y = points[ci + 1]; + p2x = points[ci + 2], p2y = points[ci + 3]; + } + } + } + BasePoly.tempData = new Array(256); + + class EarcutNode { + constructor(i, x, y) { + this.i = i; + this.x = x; + this.y = y; + this.prev = null; + this.next = null; + this.z = null; + this.prevZ = null; + this.nextZ = null; + this.steiner = false; + } + } + + class Earcut { + static earcut(data, holeIndices, dim) { + dim = dim || 2; + var hasHoles = holeIndices && holeIndices.length, outerLen = hasHoles ? holeIndices[0] * dim : data.length, outerNode = Earcut.linkedList(data, 0, outerLen, dim, true), triangles = []; + if (!outerNode) + return triangles; + var minX, minY, maxX, maxY, x, y, invSize; + if (hasHoles) + outerNode = Earcut.eliminateHoles(data, holeIndices, outerNode, dim); + if (data.length > 80 * dim) { + minX = maxX = data[0]; + minY = maxY = data[1]; + for (var i = dim; i < outerLen; i += dim) { + x = data[i]; + y = data[i + 1]; + if (x < minX) + minX = x; + if (y < minY) + minY = y; + if (x > maxX) + maxX = x; + if (y > maxY) + maxY = y; + } + invSize = Math.max(maxX - minX, maxY - minY); + invSize = invSize !== 0 ? 1 / invSize : 0; + } + Earcut.earcutLinked(outerNode, triangles, dim, minX, minY, invSize); + return triangles; + } + static linkedList(data, start, end, dim, clockwise) { + var i, last; + if (clockwise === (Earcut.signedArea(data, start, end, dim) > 0)) { + for (i = start; i < end; i += dim) + last = Earcut.insertNode(i, data[i], data[i + 1], last); + } + else { + for (i = end - dim; i >= start; i -= dim) + last = Earcut.insertNode(i, data[i], data[i + 1], last); + } + if (last && Earcut.equals(last, last.next)) { + Earcut.removeNode(last); + last = last.next; + } + return last; + } + static filterPoints(start, end) { + if (!start) + return start; + if (!end) + end = start; + var p = start, again; + do { + again = false; + if (!p.steiner && (Earcut.equals(p, p.next) || Earcut.area(p.prev, p, p.next) === 0)) { + Earcut.removeNode(p); + p = end = p.prev; + if (p === p.next) + break; + again = true; + } + else { + p = p.next; + } + } while (again || p !== end); + return end; + } + static earcutLinked(ear, triangles, dim, minX, minY, invSize, pass = null) { + if (!ear) + return; + if (!pass && invSize) + Earcut.indexCurve(ear, minX, minY, invSize); + var stop = ear, prev, next; + while (ear.prev !== ear.next) { + prev = ear.prev; + next = ear.next; + if (invSize ? Earcut.isEarHashed(ear, minX, minY, invSize) : Earcut.isEar(ear)) { + triangles.push(prev.i / dim); + triangles.push(ear.i / dim); + triangles.push(next.i / dim); + Earcut.removeNode(ear); + ear = next.next; + stop = next.next; + continue; + } + ear = next; + if (ear === stop) { + if (!pass) { + Earcut.earcutLinked(Earcut.filterPoints(ear, null), triangles, dim, minX, minY, invSize, 1); + } + else if (pass === 1) { + ear = Earcut.cureLocalIntersections(ear, triangles, dim); + Earcut.earcutLinked(ear, triangles, dim, minX, minY, invSize, 2); + } + else if (pass === 2) { + Earcut.splitEarcut(ear, triangles, dim, minX, minY, invSize); + } + break; + } + } + } + static isEar(ear) { + var a = ear.prev, b = ear, c = ear.next; + if (Earcut.area(a, b, c) >= 0) + return false; + var p = ear.next.next; + while (p !== ear.prev) { + if (Earcut.pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && + Earcut.area(p.prev, p, p.next) >= 0) + return false; + p = p.next; + } + return true; + } + static isEarHashed(ear, minX, minY, invSize) { + var a = ear.prev, b = ear, c = ear.next; + if (Earcut.area(a, b, c) >= 0) + return false; + var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x), minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y), maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x), maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y); + var minZ = Earcut.zOrder(minTX, minTY, minX, minY, invSize), maxZ = Earcut.zOrder(maxTX, maxTY, minX, minY, invSize); + var p = ear.nextZ; + while (p && p.z <= maxZ) { + if (p !== ear.prev && p !== ear.next && + Earcut.pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && + Earcut.area(p.prev, p, p.next) >= 0) + return false; + p = p.nextZ; + } + p = ear.prevZ; + while (p && p.z >= minZ) { + if (p !== ear.prev && p !== ear.next && + Earcut.pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && + Earcut.area(p.prev, p, p.next) >= 0) + return false; + p = p.prevZ; + } + return true; + } + static cureLocalIntersections(start, triangles, dim) { + var p = start; + do { + var a = p.prev, b = p.next.next; + if (!Earcut.equals(a, b) && Earcut.intersects(a, p, p.next, b) && Earcut.locallyInside(a, b) && Earcut.locallyInside(b, a)) { + triangles.push(a.i / dim); + triangles.push(p.i / dim); + triangles.push(b.i / dim); + Earcut.removeNode(p); + Earcut.removeNode(p.next); + p = start = b; + } + p = p.next; + } while (p !== start); + return p; + } + static splitEarcut(start, triangles, dim, minX, minY, invSize) { + var a = start; + do { + var b = a.next.next; + while (b !== a.prev) { + if (a.i !== b.i && Earcut.isValidDiagonal(a, b)) { + var c = Earcut.splitPolygon(a, b); + a = Earcut.filterPoints(a, a.next); + c = Earcut.filterPoints(c, c.next); + Earcut.earcutLinked(a, triangles, dim, minX, minY, invSize); + Earcut.earcutLinked(c, triangles, dim, minX, minY, invSize); + return; + } + b = b.next; + } + a = a.next; + } while (a !== start); + } + static eliminateHoles(data, holeIndices, outerNode, dim) { + var queue = [], i, len, start, end, list; + for (i = 0, len = holeIndices.length; i < len; i++) { + start = holeIndices[i] * dim; + end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; + list = Earcut.linkedList(data, start, end, dim, false); + if (list === list.next) + list.steiner = true; + queue.push(Earcut.getLeftmost(list)); + } + queue.sort(Earcut.compareX); + for (i = 0; i < queue.length; i++) { + Earcut.eliminateHole(queue[i], outerNode); + outerNode = Earcut.filterPoints(outerNode, outerNode.next); + } + return outerNode; + } + static compareX(a, b) { + return a.x - b.x; + } + static eliminateHole(hole, outerNode) { + outerNode = Earcut.findHoleBridge(hole, outerNode); + if (outerNode) { + var b = Earcut.splitPolygon(outerNode, hole); + Earcut.filterPoints(b, b.next); + } + } + static findHoleBridge(hole, outerNode) { + var p = outerNode, hx = hole.x, hy = hole.y, qx = -Infinity, m; + do { + if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) { + var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); + if (x <= hx && x > qx) { + qx = x; + if (x === hx) { + if (hy === p.y) + return p; + if (hy === p.next.y) + return p.next; + } + m = p.x < p.next.x ? p : p.next; + } + } + p = p.next; + } while (p !== outerNode); + if (!m) + return null; + if (hx === qx) + return m.prev; + var stop = m, mx = m.x, my = m.y, tanMin = Infinity, tan; + p = m.next; + while (p !== stop) { + if (hx >= p.x && p.x >= mx && hx !== p.x && + Earcut.pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) { + tan = Math.abs(hy - p.y) / (hx - p.x); + if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && Earcut.locallyInside(p, hole)) { + m = p; + tanMin = tan; + } + } + p = p.next; + } + return m; + } + static indexCurve(start, minX, minY, invSize) { + var p = start; + do { + if (p.z === null) + p.z = Earcut.zOrder(p.x, p.y, minX, minY, invSize); + p.prevZ = p.prev; + p.nextZ = p.next; + p = p.next; + } while (p !== start); + p.prevZ.nextZ = null; + p.prevZ = null; + Earcut.sortLinked(p); + } + static sortLinked(list) { + var i, p, q, e, tail, numMerges, pSize, qSize, inSize = 1; + do { + p = list; + list = null; + tail = null; + numMerges = 0; + while (p) { + numMerges++; + q = p; + pSize = 0; + for (i = 0; i < inSize; i++) { + pSize++; + q = q.nextZ; + if (!q) + break; + } + qSize = inSize; + while (pSize > 0 || (qSize > 0 && q)) { + if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) { + e = p; + p = p.nextZ; + pSize--; + } + else { + e = q; + q = q.nextZ; + qSize--; + } + if (tail) + tail.nextZ = e; + else + list = e; + e.prevZ = tail; + tail = e; + } + p = q; + } + tail.nextZ = null; + inSize *= 2; + } while (numMerges > 1); + return list; + } + static zOrder(x, y, minX, minY, invSize) { + x = 32767 * (x - minX) * invSize; + y = 32767 * (y - minY) * invSize; + x = (x | (x << 8)) & 0x00FF00FF; + x = (x | (x << 4)) & 0x0F0F0F0F; + x = (x | (x << 2)) & 0x33333333; + x = (x | (x << 1)) & 0x55555555; + y = (y | (y << 8)) & 0x00FF00FF; + y = (y | (y << 4)) & 0x0F0F0F0F; + y = (y | (y << 2)) & 0x33333333; + y = (y | (y << 1)) & 0x55555555; + return x | (y << 1); + } + static getLeftmost(start) { + var p = start, leftmost = start; + do { + if (p.x < leftmost.x) + leftmost = p; + p = p.next; + } while (p !== start); + return leftmost; + } + static pointInTriangle(ax, ay, bx, by, cx, cy, px, py) { + return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 && + (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 && + (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0; + } + static isValidDiagonal(a, b) { + return a.next.i !== b.i && a.prev.i !== b.i && !Earcut.intersectsPolygon(a, b) && + Earcut.locallyInside(a, b) && Earcut.locallyInside(b, a) && Earcut.middleInside(a, b); + } + static area(p, q, r) { + return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); + } + static equals(p1, p2) { + return p1.x === p2.x && p1.y === p2.y; + } + static intersects(p1, q1, p2, q2) { + if ((Earcut.equals(p1, q1) && Earcut.equals(p2, q2)) || + (Earcut.equals(p1, q2) && Earcut.equals(p2, q1))) + return true; + return Earcut.area(p1, q1, p2) > 0 !== Earcut.area(p1, q1, q2) > 0 && + Earcut.area(p2, q2, p1) > 0 !== Earcut.area(p2, q2, q1) > 0; + } + static intersectsPolygon(a, b) { + var p = a; + do { + if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && + Earcut.intersects(p, p.next, a, b)) + return true; + p = p.next; + } while (p !== a); + return false; + } + static locallyInside(a, b) { + return Earcut.area(a.prev, a, a.next) < 0 ? + Earcut.area(a, b, a.next) >= 0 && Earcut.area(a, a.prev, b) >= 0 : + Earcut.area(a, b, a.prev) < 0 || Earcut.area(a, a.next, b) < 0; + } + static middleInside(a, b) { + var p = a, inside = false, px = (a.x + b.x) / 2, py = (a.y + b.y) / 2; + do { + if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y && + (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)) + inside = !inside; + p = p.next; + } while (p !== a); + return inside; + } + static splitPolygon(a, b) { + var a2 = new EarcutNode(a.i, a.x, a.y), b2 = new EarcutNode(b.i, b.x, b.y), an = a.next, bp = b.prev; + a.next = b; + b.prev = a; + a2.next = an; + an.prev = a2; + b2.next = a2; + a2.prev = b2; + bp.next = b2; + b2.prev = bp; + return b2; + } + static insertNode(i, x, y, last) { + var p = new EarcutNode(i, x, y); + if (!last) { + p.prev = p; + p.next = p; + } + else { + p.next = last.next; + p.prev = last; + last.next.prev = p; + last.next = p; + } + return p; + } + static removeNode(p) { + p.next.prev = p.prev; + p.prev.next = p.next; + if (p.prevZ) + p.prevZ.nextZ = p.nextZ; + if (p.nextZ) + p.nextZ.prevZ = p.prevZ; + } + static signedArea(data, start, end, dim) { + var sum = 0; + for (var i = start, j = end - dim; i < end; i += dim) { + sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); + j = i; + } + return sum; + } + } + + class CONST3D2D { + } + CONST3D2D.BYTES_PE = 4; + CONST3D2D.BYTES_PIDX = 2; + CONST3D2D.defaultMatrix4 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; + CONST3D2D.defaultMinusYMatrix4 = [1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; + CONST3D2D.uniformMatrix3 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0]; + CONST3D2D._TMPARRAY = []; + CONST3D2D._OFFSETX = 0; + CONST3D2D._OFFSETY = 0; + + class Submit extends SubmitBase { + constructor(renderType = SubmitBase.TYPE_2D) { + super(renderType); + } + renderSubmit() { + if (this._numEle === 0 || !this._mesh || this._numEle == 0) + return 1; + var _tex = this.shaderValue.textureHost; + if (_tex) { + var source = _tex._getSource(); + if (!source) + return 1; + this.shaderValue.texture = source; + } + var gl = WebGLContext.mainContext; + this._mesh.useMesh(gl); + this.shaderValue.upload(); + if (BlendMode.activeBlendFunction !== this._blendFn) { + WebGLContext.setBlend(gl, true); + this._blendFn(gl); + BlendMode.activeBlendFunction = this._blendFn; + } + gl.drawElements(gl.TRIANGLES, this._numEle, gl.UNSIGNED_SHORT, this._startIdx); + Stat.renderBatches++; + Stat.trianglesFaces += this._numEle / 3; + return 1; + } + releaseRender() { + if (SubmitBase.RENDERBASE == this) + return; + if ((--this._ref) < 1) { + Submit.POOL[Submit._poolSize++] = this; + this.shaderValue.release(); + this.shaderValue = null; + this._mesh = null; + this._parent && (this._parent.releaseRender(), this._parent = null); + } + } + static create(context, mesh, sv) { + var o = Submit._poolSize ? Submit.POOL[--Submit._poolSize] : new Submit(); + o._ref = 1; + o._mesh = mesh; + o._key.clear(); + o._startIdx = mesh.indexNum * CONST3D2D.BYTES_PIDX; + o._numEle = 0; + var blendType = context._nBlendType; + o._blendFn = context._targets ? BlendMode.targetFns[blendType] : BlendMode.fns[blendType]; + o.shaderValue = sv; + o.shaderValue.setValue(context._shader2D); + var filters = context._shader2D.filters; + filters && o.shaderValue.setFilters(filters); + return o; + } + static createShape(ctx, mesh, numEle, sv) { + var o = Submit._poolSize ? Submit.POOL[--Submit._poolSize] : (new Submit()); + o._mesh = mesh; + o._numEle = numEle; + o._startIdx = mesh.indexNum * 2; + o._ref = 1; + o.shaderValue = sv; + o.shaderValue.setValue(ctx._shader2D); + var blendType = ctx._nBlendType; + o._key.blendShader = blendType; + o._blendFn = ctx._targets ? BlendMode.targetFns[blendType] : BlendMode.fns[blendType]; + return o; + } + } + Submit._poolSize = 0; + Submit.POOL = []; + + class SubmitCanvas extends SubmitBase { + constructor() { + super(SubmitBase.TYPE_2D); + this._matrix = new Matrix(); + this._matrix4 = CONST3D2D.defaultMatrix4.concat(); + this.shaderValue = new Value2D(0, 0); + } + static create(canvas, alpha, filters) { + var o = (!SubmitCanvas.POOL._length) ? (new SubmitCanvas()) : SubmitCanvas.POOL[--SubmitCanvas.POOL._length]; + o.canv = canvas; + o._ref = 1; + o._numEle = 0; + var v = o.shaderValue; + v.alpha = alpha; + v.defines.setValue(0); + filters && filters.length && v.setFilters(filters); + return o; + } + renderSubmit() { + var preAlpha = RenderState2D.worldAlpha; + var preMatrix4 = RenderState2D.worldMatrix4; + var preMatrix = RenderState2D.worldMatrix; + var preFilters = RenderState2D.worldFilters; + var preWorldShaderDefines = RenderState2D.worldShaderDefines; + var v = this.shaderValue; + var m = this._matrix; + var m4 = this._matrix4; + var mout = Matrix.TEMP; + Matrix.mul(m, preMatrix, mout); + m4[0] = mout.a; + m4[1] = mout.b; + m4[4] = mout.c; + m4[5] = mout.d; + m4[12] = mout.tx; + m4[13] = mout.ty; + RenderState2D.worldMatrix = mout.clone(); + RenderState2D.worldMatrix4 = m4; + RenderState2D.worldAlpha = RenderState2D.worldAlpha * v.alpha; + if (v.filters && v.filters.length) { + RenderState2D.worldFilters = v.filters; + RenderState2D.worldShaderDefines = v.defines; + } + this.canv['flushsubmit'](); + RenderState2D.worldAlpha = preAlpha; + RenderState2D.worldMatrix4 = preMatrix4; + RenderState2D.worldMatrix.destroy(); + RenderState2D.worldMatrix = preMatrix; + RenderState2D.worldFilters = preFilters; + RenderState2D.worldShaderDefines = preWorldShaderDefines; + return 1; + } + releaseRender() { + if ((--this._ref) < 1) { + var cache = SubmitCanvas.POOL; + this._mesh = null; + cache[cache._length++] = this; + } + } + getRenderType() { + return SubmitBase.TYPE_CANVAS; + } + } + SubmitCanvas.POOL = []; + { + SubmitCanvas.POOL._length = 0; + } + + class SubmitTarget { + constructor() { + this.blendType = 0; + this._ref = 1; + this._key = new SubmitKey(); + } + renderSubmit() { + var gl = WebGLContext.mainContext; + this._mesh.useMesh(gl); + var target = this.srcRT; + if (target) { + this.shaderValue.texture = target._getSource(); + this.shaderValue.upload(); + this.blend(); + Stat.renderBatches++; + Stat.trianglesFaces += this._numEle / 3; + gl.drawElements(gl.TRIANGLES, this._numEle, gl.UNSIGNED_SHORT, this._startIdx); + } + return 1; + } + blend() { + if (BlendMode.activeBlendFunction !== BlendMode.fns[this.blendType]) { + var gl = WebGLContext.mainContext; + gl.enable(gl.BLEND); + BlendMode.fns[this.blendType](gl); + BlendMode.activeBlendFunction = BlendMode.fns[this.blendType]; + } + } + getRenderType() { + return 0; + } + releaseRender() { + if ((--this._ref) < 1) { + var pool = SubmitTarget.POOL; + pool[pool._length++] = this; + } + } + static create(context, mesh, sv, rt) { + var o = SubmitTarget.POOL._length ? SubmitTarget.POOL[--SubmitTarget.POOL._length] : new SubmitTarget(); + o._mesh = mesh; + o.srcRT = rt; + o._startIdx = mesh.indexNum * CONST3D2D.BYTES_PIDX; + o._ref = 1; + o._key.clear(); + o._numEle = 0; + o.blendType = context._nBlendType; + o._key.blendShader = o.blendType; + o.shaderValue = sv; + o.shaderValue.setValue(context._shader2D); + if (context._colorFiler) { + var ft = context._colorFiler; + sv.defines.add(ft.type); + sv.colorMat = ft._mat; + sv.colorAlpha = ft._alpha; + } + return o; + } + } + SubmitTarget.POOL = []; + { + SubmitTarget.POOL._length = 0; + } + + class SubmitTexture extends SubmitBase { + constructor(renderType = SubmitBase.TYPE_2D) { + super(renderType); + } + releaseRender() { + if ((--this._ref) < 1) { + SubmitTexture.POOL[SubmitTexture._poolSize++] = this; + this.shaderValue.release(); + this._mesh = null; + this._parent && (this._parent.releaseRender(), this._parent = null); + } + } + renderSubmit() { + if (this._numEle === 0) + return 1; + var tex = this.shaderValue.textureHost; + if (tex) { + var source = tex ? tex._getSource() : null; + if (!source) + return 1; + } + var gl = WebGLContext.mainContext; + this._mesh.useMesh(gl); + var lastSubmit = SubmitBase.preRender; + var prekey = SubmitBase.preRender._key; + if (this._key.blendShader === 0 && (this._key.submitType === prekey.submitType && this._key.blendShader === prekey.blendShader) && BaseShader.activeShader && + SubmitBase.preRender.clipInfoID == this.clipInfoID && + lastSubmit.shaderValue.defines._value === this.shaderValue.defines._value && + (this.shaderValue.defines._value & ShaderDefines2D.NOOPTMASK) == 0) { + BaseShader.activeShader.uploadTexture2D(source); + } + else { + if (BlendMode.activeBlendFunction !== this._blendFn) { + WebGLContext.setBlend(gl, true); + this._blendFn(gl); + BlendMode.activeBlendFunction = this._blendFn; + } + this.shaderValue.texture = source; + this.shaderValue.upload(); + } + gl.drawElements(gl.TRIANGLES, this._numEle, gl.UNSIGNED_SHORT, this._startIdx); + Stat.renderBatches++; + Stat.trianglesFaces += this._numEle / 3; + return 1; + } + static create(context, mesh, sv) { + var o = SubmitTexture._poolSize ? SubmitTexture.POOL[--SubmitTexture._poolSize] : new SubmitTexture(SubmitBase.TYPE_TEXTURE); + o._mesh = mesh; + o._key.clear(); + o._key.submitType = SubmitBase.KEY_DRAWTEXTURE; + o._ref = 1; + o._startIdx = mesh.indexNum * CONST3D2D.BYTES_PIDX; + o._numEle = 0; + var blendType = context._nBlendType; + o._key.blendShader = blendType; + o._blendFn = context._targets ? BlendMode.targetFns[blendType] : BlendMode.fns[blendType]; + o.shaderValue = sv; + if (context._colorFiler) { + var ft = context._colorFiler; + sv.defines.add(ft.type); + sv.colorMat = ft._mat; + sv.colorAlpha = ft._alpha; + } + return o; + } + } + SubmitTexture._poolSize = 0; + SubmitTexture.POOL = []; + + class CharSubmitCache { + constructor() { + this._data = []; + this._ndata = 0; + this._clipid = -1; + this._clipMatrix = new Matrix(); + this._enable = false; + } + clear() { + this._tex = null; + this._imgId = -1; + this._ndata = 0; + this._enable = false; + this._colorFiler = null; + } + destroy() { + this.clear(); + this._data.length = 0; + this._data = null; + } + add(ctx, tex, imgid, pos, uv, color) { + if (this._ndata > 0 && (this._tex != tex || this._imgId != imgid || + (this._clipid >= 0 && this._clipid != ctx._clipInfoID))) { + this.submit(ctx); + } + this._clipid = ctx._clipInfoID; + ctx._globalClipMatrix.copyTo(this._clipMatrix); + this._tex = tex; + this._imgId = imgid; + this._colorFiler = ctx._colorFiler; + this._data[this._ndata] = pos; + this._data[this._ndata + 1] = uv; + this._data[this._ndata + 2] = color; + this._ndata += 3; + } + getPos() { + if (CharSubmitCache.__nPosPool == 0) + return new Array(8); + return CharSubmitCache.__posPool[--CharSubmitCache.__nPosPool]; + } + enable(value, ctx) { + if (value === this._enable) + return; + this._enable = value; + this._enable || this.submit(ctx); + } + submit(ctx) { + var n = this._ndata; + if (!n) + return; + var _mesh = ctx._mesh; + var colorFiler = ctx._colorFiler; + ctx._colorFiler = this._colorFiler; + var submit = SubmitTexture.create(ctx, _mesh, Value2D.create(ShaderDefines2D.TEXTURE2D, 0)); + ctx._submits[ctx._submits._length++] = ctx._curSubmit = submit; + submit.shaderValue.textureHost = this._tex; + submit._key.other = this._imgId; + ctx._colorFiler = colorFiler; + ctx._copyClipInfo(submit, this._clipMatrix); + submit.clipInfoID = this._clipid; + for (var i = 0; i < n; i += 3) { + _mesh.addQuad(this._data[i], this._data[i + 1], this._data[i + 2], true); + CharSubmitCache.__posPool[CharSubmitCache.__nPosPool++] = this._data[i]; + } + n /= 3; + submit._numEle += n * 6; + _mesh.indexNum += n * 6; + _mesh.vertNum += n * 4; + ctx._drawCount += n; + this._ndata = 0; + if (RenderInfo.loopCount % 100 == 0) + this._data.length = 0; + } + } + CharSubmitCache.__posPool = []; + CharSubmitCache.__nPosPool = 0; + + class AtlasGrid { + constructor(width = 0, height = 0, id = 0) { + this.atlasID = 0; + this._width = 0; + this._height = 0; + this._texCount = 0; + this._rowInfo = null; + this._cells = null; + this._used = 0; + this._cells = null; + this._rowInfo = null; + this.atlasID = id; + this._init(width, height); + } + addRect(type, width, height, pt) { + if (!this._get(width, height, pt)) + return false; + this._fill(pt.x, pt.y, width, height, type); + this._texCount++; + return true; + } + _release() { + this._cells = null; + this._rowInfo = null; + } + _init(width, height) { + this._width = width; + this._height = height; + this._release(); + if (this._width == 0) + return false; + this._cells = new Uint8Array(this._width * this._height * 3); + this._rowInfo = new Uint8Array(this._height); + this._used = 0; + this._clear(); + return true; + } + _get(width, height, pt) { + if (width > this._width || height > this._height) { + return false; + } + var rx = -1; + var ry = -1; + var nWidth = this._width; + var nHeight = this._height; + var pCellBox = this._cells; + for (var y = 0; y < nHeight; y++) { + if (this._rowInfo[y] < width) + continue; + for (var x = 0; x < nWidth;) { + var tm = (y * nWidth + x) * 3; + if (pCellBox[tm] != 0 || pCellBox[tm + 1] < width || pCellBox[tm + 2] < height) { + x += pCellBox[tm + 1]; + continue; + } + rx = x; + ry = y; + for (var xx = 0; xx < width; xx++) { + if (pCellBox[3 * xx + tm + 2] < height) { + rx = -1; + break; + } + } + if (rx < 0) { + x += pCellBox[tm + 1]; + continue; + } + pt.x = rx; + pt.y = ry; + return true; + } + } + return false; + } + _fill(x, y, w, h, type) { + var nWidth = this._width; + var nHeghit = this._height; + this._check((x + w) <= nWidth && (y + h) <= nHeghit); + for (var yy = y; yy < (h + y); ++yy) { + this._check(this._rowInfo[yy] >= w); + this._rowInfo[yy] -= w; + for (var xx = 0; xx < w; xx++) { + var tm = (x + yy * nWidth + xx) * 3; + this._check(this._cells[tm] == 0); + this._cells[tm] = type; + this._cells[tm + 1] = w; + this._cells[tm + 2] = h; + } + } + if (x > 0) { + for (yy = 0; yy < h; ++yy) { + var s = 0; + for (xx = x - 1; xx >= 0; --xx, ++s) { + if (this._cells[((y + yy) * nWidth + xx) * 3] != 0) + break; + } + for (xx = s; xx > 0; --xx) { + this._cells[((y + yy) * nWidth + x - xx) * 3 + 1] = xx; + this._check(xx > 0); + } + } + } + if (y > 0) { + for (xx = x; xx < (x + w); ++xx) { + s = 0; + for (yy = y - 1; yy >= 0; --yy, s++) { + if (this._cells[(xx + yy * nWidth) * 3] != 0) + break; + } + for (yy = s; yy > 0; --yy) { + this._cells[(xx + (y - yy) * nWidth) * 3 + 2] = yy; + this._check(yy > 0); + } + } + } + this._used += (w * h) / (this._width * this._height); + } + _check(ret) { + if (ret == false) { + console.log("xtexMerger 错误啦"); + } + } + _clear() { + this._texCount = 0; + for (var y = 0; y < this._height; y++) { + this._rowInfo[y] = this._width; + } + for (var i = 0; i < this._height; i++) { + for (var j = 0; j < this._width; j++) { + var tm = (i * this._width + j) * 3; + this._cells[tm] = 0; + this._cells[tm + 1] = this._width - j; + this._cells[tm + 2] = this._width - i; + } + } + } + } + + class TextTexture extends Resource { + constructor(textureW, textureH) { + super(); + this._texW = 0; + this._texH = 0; + this.__destroyed = false; + this._discardTm = 0; + this.genID = 0; + this.bitmap = { id: 0, _glTexture: null }; + this.curUsedCovRate = 0; + this.curUsedCovRateAtlas = 0; + this.lastTouchTm = 0; + this.ri = null; + this._texW = textureW || TextTexture.gTextRender.atlasWidth; + this._texH = textureH || TextTexture.gTextRender.atlasWidth; + this.bitmap.id = this.id; + this.lock = true; + } + recreateResource() { + if (this._source) + return; + var gl = LayaGL.instance; + var glTex = this._source = gl.createTexture(); + this.bitmap._glTexture = glTex; + WebGLContext.bindTexture(gl, gl.TEXTURE_2D, glTex); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this._texW, this._texH, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + if (TextTexture.gTextRender.debugUV) { + this.fillWhite(); + } + } + addChar(data, x, y, uv = null) { + if (TextTexture.gTextRender.isWan1Wan) { + return this.addCharCanvas(data, x, y, uv); + } + !this._source && this.recreateResource(); + var gl = LayaGL.instance; + WebGLContext.bindTexture(gl, gl.TEXTURE_2D, this._source); + !ILaya.Render.isConchApp && gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); + var dt = data.data; + if (data.data instanceof Uint8ClampedArray) + dt = new Uint8Array(dt.buffer); + gl.texSubImage2D(gl.TEXTURE_2D, 0, x, y, data.width, data.height, gl.RGBA, gl.UNSIGNED_BYTE, dt); + !ILaya.Render.isConchApp && gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + var u0; + var v0; + var u1; + var v1; + u0 = x / this._texW; + v0 = y / this._texH; + u1 = (x + data.width) / this._texW; + v1 = (y + data.height) / this._texH; + uv = uv || new Array(8); + uv[0] = u0, uv[1] = v0; + uv[2] = u1, uv[3] = v0; + uv[4] = u1, uv[5] = v1; + uv[6] = u0, uv[7] = v1; + return uv; + } + addCharCanvas(canv, x, y, uv = null) { + !this._source && this.recreateResource(); + var gl = LayaGL.instance; + WebGLContext.bindTexture(gl, gl.TEXTURE_2D, this._source); + !ILaya.Render.isConchApp && gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); + gl.texSubImage2D(gl.TEXTURE_2D, 0, x, y, gl.RGBA, gl.UNSIGNED_BYTE, canv); + !ILaya.Render.isConchApp && gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + var u0; + var v0; + var u1; + var v1; + if (ILaya.Render.isConchApp) { + u0 = x / this._texW; + v0 = y / this._texH; + u1 = (x + canv.width) / this._texW; + v1 = (y + canv.height) / this._texH; + } + else { + u0 = (x + 1) / this._texW; + v0 = (y + 1) / this._texH; + u1 = (x + canv.width - 1) / this._texW; + v1 = (y + canv.height - 1) / this._texH; + } + uv = uv || new Array(8); + uv[0] = u0, uv[1] = v0; + uv[2] = u1, uv[3] = v0; + uv[4] = u1, uv[5] = v1; + uv[6] = u0, uv[7] = v1; + return uv; + } + fillWhite() { + !this._source && this.recreateResource(); + var gl = LayaGL.instance; + var dt = new Uint8Array(this._texW * this._texH * 4); + dt.fill(0xff); + gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, this._texW, this._texH, gl.RGBA, gl.UNSIGNED_BYTE, dt); + } + discard() { + ILaya.stage.setGlobalRepaint(); + this.destroy(); + return; + } + static getTextTexture(w, h) { + return new TextTexture(w, h); + } + destroy() { + this.__destroyed = true; + var gl = LayaGL.instance; + this._source && gl.deleteTexture(this._source); + this._source = null; + } + static clean() { + var curtm = RenderInfo.loopStTm; + if (TextTexture.cleanTm === 0) + TextTexture.cleanTm = curtm; + if (curtm - TextTexture.cleanTm >= TextTexture.gTextRender.checkCleanTextureDt) { + for (var i = 0; i < TextTexture.poolLen; i++) { + var p = TextTexture.pool[i]; + if (curtm - p._discardTm >= TextTexture.gTextRender.destroyUnusedTextureDt) { + p.destroy(); + TextTexture.pool[i] = TextTexture.pool[TextTexture.poolLen - 1]; + TextTexture.poolLen--; + i--; + } + } + TextTexture.cleanTm = curtm; + } + } + touchRect(ri, curloop) { + if (this.lastTouchTm != curloop) { + this.curUsedCovRate = 0; + this.curUsedCovRateAtlas = 0; + this.lastTouchTm = curloop; + } + var texw2 = TextTexture.gTextRender.atlasWidth * TextTexture.gTextRender.atlasWidth; + var gridw2 = ILaya.TextAtlas.atlasGridW * ILaya.TextAtlas.atlasGridW; + this.curUsedCovRate += (ri.bmpWidth * ri.bmpHeight) / texw2; + this.curUsedCovRateAtlas += (Math.ceil(ri.bmpWidth / ILaya.TextAtlas.atlasGridW) * Math.ceil(ri.bmpHeight / ILaya.TextAtlas.atlasGridW)) / (texw2 / gridw2); + } + get texture() { + return this; + } + _getSource() { + return this._source; + } + drawOnScreen(x, y) { + } + } + TextTexture.gTextRender = null; + TextTexture.pool = new Array(10); + TextTexture.poolLen = 0; + TextTexture.cleanTm = 0; + + class TextAtlas { + constructor() { + this.texWidth = 1024; + this.texHeight = 1024; + this.texture = null; + this.charMaps = {}; + this.texHeight = this.texWidth = ILaya.TextRender.atlasWidth; + this.texture = TextTexture.getTextTexture(this.texWidth, this.texHeight); + if (this.texWidth / TextAtlas.atlasGridW > 256) { + TextAtlas.atlasGridW = Math.ceil(this.texWidth / 256); + } + this.atlasgrid = new AtlasGrid(this.texWidth / TextAtlas.atlasGridW, this.texHeight / TextAtlas.atlasGridW, this.texture.id); + } + setProtecteDist(d) { + } + getAEmpty(w, h, pt) { + var find = this.atlasgrid.addRect(1, Math.ceil(w / TextAtlas.atlasGridW), Math.ceil(h / TextAtlas.atlasGridW), pt); + if (find) { + pt.x *= TextAtlas.atlasGridW; + pt.y *= TextAtlas.atlasGridW; + } + return find; + } + get usedRate() { + return this.atlasgrid._used; + } + destroy() { + for (var k in this.charMaps) { + var ri = this.charMaps[k]; + ri.deleted = true; + } + this.texture.discard(); + } + printDebugInfo() { + } + } + TextAtlas.atlasGridW = 16; + + class Event { + setTo(type, currentTarget, target) { + this.type = type; + this.currentTarget = currentTarget; + this.target = target; + return this; + } + stopPropagation() { + this._stoped = true; + } + get touches() { + if (!this.nativeEvent) + return null; + var arr = this.nativeEvent.touches; + if (arr) { + var stage = ILaya.stage; + for (var i = 0, n = arr.length; i < n; i++) { + var e = arr[i]; + var point = Point.TEMP; + point.setTo(e.clientX, e.clientY); + stage._canvasTransform.invertTransformPoint(point); + stage.transform.invertTransformPoint(point); + e.stageX = point.x; + e.stageY = point.y; + } + } + return arr; + } + get altKey() { + return this.nativeEvent.altKey; + } + get ctrlKey() { + return this.nativeEvent.ctrlKey; + } + get shiftKey() { + return this.nativeEvent.shiftKey; + } + get charCode() { + return this.nativeEvent.charCode; + } + get keyLocation() { + return this.nativeEvent.location || this.nativeEvent.keyLocation; + } + get stageX() { + return ILaya.stage.mouseX; + } + get stageY() { + return ILaya.stage.mouseY; + } + } + Event.EMPTY = new Event(); + Event.MOUSE_DOWN = "mousedown"; + Event.MOUSE_UP = "mouseup"; + Event.CLICK = "click"; + Event.RIGHT_MOUSE_DOWN = "rightmousedown"; + Event.RIGHT_MOUSE_UP = "rightmouseup"; + Event.RIGHT_CLICK = "rightclick"; + Event.MOUSE_MOVE = "mousemove"; + Event.MOUSE_OVER = "mouseover"; + Event.MOUSE_OUT = "mouseout"; + Event.MOUSE_WHEEL = "mousewheel"; + Event.ROLL_OVER = "mouseover"; + Event.ROLL_OUT = "mouseout"; + Event.DOUBLE_CLICK = "doubleclick"; + Event.CHANGE = "change"; + Event.CHANGED = "changed"; + Event.RESIZE = "resize"; + Event.ADDED = "added"; + Event.REMOVED = "removed"; + Event.DISPLAY = "display"; + Event.UNDISPLAY = "undisplay"; + Event.ERROR = "error"; + Event.COMPLETE = "complete"; + Event.LOADED = "loaded"; + Event.READY = "ready"; + Event.PROGRESS = "progress"; + Event.INPUT = "input"; + Event.RENDER = "render"; + Event.OPEN = "open"; + Event.MESSAGE = "message"; + Event.CLOSE = "close"; + Event.KEY_DOWN = "keydown"; + Event.KEY_PRESS = "keypress"; + Event.KEY_UP = "keyup"; + Event.FRAME = "enterframe"; + Event.DRAG_START = "dragstart"; + Event.DRAG_MOVE = "dragmove"; + Event.DRAG_END = "dragend"; + Event.ENTER = "enter"; + Event.SELECT = "select"; + Event.BLUR = "blur"; + Event.FOCUS = "focus"; + Event.VISIBILITY_CHANGE = "visibilitychange"; + Event.FOCUS_CHANGE = "focuschange"; + Event.PLAYED = "played"; + Event.PAUSED = "paused"; + Event.STOPPED = "stopped"; + Event.START = "start"; + Event.END = "end"; + Event.COMPONENT_ADDED = "componentadded"; + Event.COMPONENT_REMOVED = "componentremoved"; + Event.RELEASED = "released"; + Event.LINK = "link"; + Event.LABEL = "label"; + Event.FULL_SCREEN_CHANGE = "fullscreenchange"; + Event.DEVICE_LOST = "devicelost"; + Event.TRANSFORM_CHANGED = "transformchanged"; + Event.ANIMATION_CHANGED = "animationchanged"; + Event.TRAIL_FILTER_CHANGE = "trailfilterchange"; + Event.TRIGGER_ENTER = "triggerenter"; + Event.TRIGGER_STAY = "triggerstay"; + Event.TRIGGER_EXIT = "triggerexit"; + + class Texture extends EventDispatcher { + constructor(bitmap = null, uv = null, sourceWidth = 0, sourceHeight = 0) { + super(); + this.uvrect = [0, 0, 1, 1]; + this._destroyed = false; + this._referenceCount = 0; + this.$_GID = 0; + this.offsetX = 0; + this.offsetY = 0; + this._w = 0; + this._h = 0; + this.sourceWidth = 0; + this.sourceHeight = 0; + this.url = null; + this.scaleRate = 1; + this.setTo(bitmap, uv, sourceWidth, sourceHeight); + } + static moveUV(offsetX, offsetY, uv) { + for (var i = 0; i < 8; i += 2) { + uv[i] += offsetX; + uv[i + 1] += offsetY; + } + return uv; + } + static create(source, x, y, width, height, offsetX = 0, offsetY = 0, sourceWidth = 0, sourceHeight = 0) { + return Texture._create(source, x, y, width, height, offsetX, offsetY, sourceWidth, sourceHeight); + } + static _create(source, x, y, width, height, offsetX = 0, offsetY = 0, sourceWidth = 0, sourceHeight = 0, outTexture = null) { + var btex = source instanceof Texture; + var uv = btex ? source.uv : Texture.DEF_UV; + var bitmap = btex ? source.bitmap : source; + if (bitmap.width && (x + width) > bitmap.width) + width = bitmap.width - x; + if (bitmap.height && (y + height) > bitmap.height) + height = bitmap.height - y; + var tex; + if (outTexture) { + tex = outTexture; + tex.setTo(bitmap, null, sourceWidth || width, sourceHeight || height); + } + else { + tex = new Texture(bitmap, null, sourceWidth || width, sourceHeight || height); + } + tex.width = width; + tex.height = height; + tex.offsetX = offsetX; + tex.offsetY = offsetY; + var dwidth = 1 / bitmap.width; + var dheight = 1 / bitmap.height; + x *= dwidth; + y *= dheight; + width *= dwidth; + height *= dheight; + var u1 = tex.uv[0], v1 = tex.uv[1], u2 = tex.uv[4], v2 = tex.uv[5]; + var inAltasUVWidth = (u2 - u1), inAltasUVHeight = (v2 - v1); + var oriUV = Texture.moveUV(uv[0], uv[1], [x, y, x + width, y, x + width, y + height, x, y + height]); + tex.uv = new Float32Array([u1 + oriUV[0] * inAltasUVWidth, v1 + oriUV[1] * inAltasUVHeight, + u2 - (1 - oriUV[2]) * inAltasUVWidth, v1 + oriUV[3] * inAltasUVHeight, + u2 - (1 - oriUV[4]) * inAltasUVWidth, v2 - (1 - oriUV[5]) * inAltasUVHeight, + u1 + oriUV[6] * inAltasUVWidth, v2 - (1 - oriUV[7]) * inAltasUVHeight]); + var bitmapScale = bitmap.scaleRate; + if (bitmapScale && bitmapScale != 1) { + tex.sourceWidth /= bitmapScale; + tex.sourceHeight /= bitmapScale; + tex.width /= bitmapScale; + tex.height /= bitmapScale; + tex.scaleRate = bitmapScale; + } + else { + tex.scaleRate = 1; + } + return tex; + } + static createFromTexture(texture, x, y, width, height) { + var texScaleRate = texture.scaleRate; + if (texScaleRate != 1) { + x *= texScaleRate; + y *= texScaleRate; + width *= texScaleRate; + height *= texScaleRate; + } + var rect = Rectangle.TEMP.setTo(x - texture.offsetX, y - texture.offsetY, width, height); + var result = rect.intersection(Texture._rect1.setTo(0, 0, texture.width, texture.height), Texture._rect2); + if (result) + var tex = Texture.create(texture, result.x, result.y, result.width, result.height, result.x - rect.x, result.y - rect.y, width, height); + else + return null; + return tex; + } + get uv() { + return this._uv; + } + set uv(value) { + this.uvrect[0] = Math.min(value[0], value[2], value[4], value[6]); + this.uvrect[1] = Math.min(value[1], value[3], value[5], value[7]); + this.uvrect[2] = Math.max(value[0], value[2], value[4], value[6]) - this.uvrect[0]; + this.uvrect[3] = Math.max(value[1], value[3], value[5], value[7]) - this.uvrect[1]; + this._uv = value; + } + get width() { + if (this._w) + return this._w; + if (!this.bitmap) + return 0; + return (this.uv && this.uv !== Texture.DEF_UV) ? (this.uv[2] - this.uv[0]) * this.bitmap.width : this.bitmap.width; + } + set width(value) { + this._w = value; + this.sourceWidth || (this.sourceWidth = value); + } + get height() { + if (this._h) + return this._h; + if (!this.bitmap) + return 0; + return (this.uv && this.uv !== Texture.DEF_UV) ? (this.uv[5] - this.uv[1]) * this.bitmap.height : this.bitmap.height; + } + set height(value) { + this._h = value; + this.sourceHeight || (this.sourceHeight = value); + } + get bitmap() { + return this._bitmap; + } + set bitmap(value) { + this._bitmap && this._bitmap._removeReference(this._referenceCount); + this._bitmap = value; + value && (value._addReference(this._referenceCount)); + } + get destroyed() { + return this._destroyed; + } + _addReference() { + this._bitmap && this._bitmap._addReference(); + this._referenceCount++; + } + _removeReference() { + this._bitmap && this._bitmap._removeReference(); + this._referenceCount--; + } + _getSource(cb = null) { + if (this._destroyed || !this._bitmap) + return null; + this.recoverBitmap(cb); + return this._bitmap.destroyed ? null : this.bitmap._getSource(); + } + _onLoaded(complete, context) { + if (!context) ; + else if (context == this) ; + else if (context instanceof Texture) { + var tex = context; + Texture._create(context, 0, 0, tex.width, tex.height, 0, 0, tex.sourceWidth, tex.sourceHeight, this); + } + else { + this.bitmap = context; + this.sourceWidth = this._w = context.width; + this.sourceHeight = this._h = context.height; + } + complete && complete.run(); + this.event(Event.READY, this); + } + getIsReady() { + return this._destroyed ? false : (this._bitmap ? true : false); + } + setTo(bitmap = null, uv = null, sourceWidth = 0, sourceHeight = 0) { + this.bitmap = bitmap; + this.sourceWidth = sourceWidth; + this.sourceHeight = sourceHeight; + if (bitmap) { + this._w = bitmap.width; + this._h = bitmap.height; + this.sourceWidth = this.sourceWidth || bitmap.width; + this.sourceHeight = this.sourceHeight || bitmap.height; + } + this.uv = uv || Texture.DEF_UV; + } + load(url, complete = null) { + if (!this._destroyed) + ILaya.loader.load(url, Handler.create(this, this._onLoaded, [complete]), null, "htmlimage", 1, true); + } + getTexturePixels(x, y, width, height) { + var st, dst, i; + var tex2d = this.bitmap; + var texw = this._w; + var texh = this._h; + var sourceWidth = this.sourceWidth; + var sourceHeight = this.sourceHeight; + var tex2dw = tex2d.width; + var tex2dh = tex2d.height; + var offsetX = this.offsetX; + var offsetY = this.offsetY; + let draww = width; + let drawh = height; + if (x + width > texw + offsetX) + draww -= (x + width) - texw - offsetX; + if (x + width > sourceWidth) + width -= (x + width) - sourceWidth; + if (y + height > texh + offsetY) + drawh -= (y + height) - texh - offsetY; + if (y + height > sourceHeight) + height -= (y + height) - sourceHeight; + if (width <= 0 || height <= 0) + return null; + let marginL = offsetX > x ? offsetX - x : 0; + let marginT = offsetY > y ? offsetY - y : 0; + let rePosX = x > offsetX ? x - offsetX : 0; + let rePosY = y > offsetY ? y - offsetY : 0; + draww -= marginL; + drawh -= marginT; + var wstride = width * 4; + var pix = null; + try { + pix = tex2d.getPixels(); + } + catch (e) { + } + if (pix) { + if (x == 0 && y == 0 && width == tex2dw && height == tex2dh) + return pix; + let uv = this._uv.slice(); + let atlasPosX = Math.round(uv[0] * tex2dw); + let atlasPosY = Math.round(uv[1] * tex2dh); + var ret = new Uint8Array(width * height * 4); + wstride = tex2dw * 4; + dst = (atlasPosY + rePosY) * wstride; + st = atlasPosX * 4 + rePosX * 4 + dst; + for (i = 0; i < drawh; i++) { + ret.set(pix.slice(st, st + draww * 4), width * 4 * (i + marginT) + marginL * 4); + st += wstride; + } + return ret; + } + var ctx = new ILaya.Context(); + ctx.size(width, height); + ctx.asBitmap = true; + var uv = null; + if (x != 0 || y != 0 || width != tex2dw || height != tex2dh) { + uv = this._uv.slice(); + var stu = uv[0]; + var stv = uv[1]; + var uvw = uv[2] - stu; + var uvh = uv[7] - stv; + var uk = uvw / texw; + var vk = uvh / texh; + uv = [stu + rePosX * uk, stv + rePosY * vk, + stu + (rePosX + draww) * uk, stv + rePosY * vk, + stu + (rePosX + draww) * uk, stv + (rePosY + drawh) * vk, + stu + rePosX * uk, stv + (rePosY + drawh) * vk]; + } + ctx._drawTextureM(this, marginL, marginT, draww, drawh, null, 1.0, uv); + ctx._targets.start(); + ctx.flush(); + ctx._targets.end(); + ctx._targets.restore(); + var dt = ctx._targets.getData(0, 0, width, height); + ctx.destroy(); + ret = new Uint8Array(width * height * 4); + st = 0; + dst = (height - 1) * wstride; + for (i = height - 1; i >= 0; i--) { + ret.set(dt.slice(dst, dst + wstride), st); + st += wstride; + dst -= wstride; + } + return ret; + } + getPixels(x, y, width, height) { + if (window.conch) { + return this._nativeObj.getImageData(x, y, width, height); + } + else { + return this.getTexturePixels(x, y, width, height); + } + } + recoverBitmap(onok = null) { + var url = this._bitmap.url; + if (!this._destroyed && (!this._bitmap || this._bitmap.destroyed) && url) { + let tex = ILaya.Loader.loadedMap[url]; + if (tex) { + this.bitmap = tex; + onok && onok(); + } + else { + ILaya.loader.load(url, Handler.create(this, (bit) => { + this.bitmap = bit; + onok && onok(); + }), null, "htmlimage", 1, true); + } + } + } + disposeBitmap() { + if (!this._destroyed && this._bitmap) { + this._bitmap.destroy(); + } + } + destroy(force = false) { + if (!this._destroyed) { + this._destroyed = true; + var bit = this._bitmap; + if (bit) { + bit._removeReference(this._referenceCount); + if (bit.referenceCount === 0 || force) + bit.destroy(); + bit = null; + } + if (this.url && this === ILaya.loader.getRes(this.url)) + ILaya.Loader.clearRes(this.url); + } + } + } + Texture.DEF_UV = new Float32Array([0, 0, 1.0, 0, 1.0, 1.0, 0, 1.0]); + Texture.NO_UV = new Float32Array([0, 0, 0, 0, 0, 0, 0, 0]); + Texture.INV_UV = new Float32Array([0, 1, 1.0, 1, 1.0, 0.0, 0, 0.0]); + Texture._rect1 = new Rectangle(); + Texture._rect2 = new Rectangle(); + + class FontInfo { + constructor(font) { + this._font = "14px Arial"; + this._family = "Arial"; + this._size = 14; + this._italic = false; + this._bold = false; + this._id = FontInfo._gfontID++; + this.setFont(font || this._font); + } + static Parse(font) { + if (font === FontInfo._lastFont) { + return FontInfo._lastFontInfo; + } + var r = FontInfo._cache[font]; + if (!r) { + r = FontInfo._cache[font] = new FontInfo(font); + } + FontInfo._lastFont = font; + FontInfo._lastFontInfo = r; + return r; + } + setFont(value) { + this._font = value; + var _words = value.split(' '); + var l = _words.length; + if (l < 2) { + if (l == 1) { + if (_words[0].indexOf('px') > 0) { + this._size = parseInt(_words[0]); + } + } + return; + } + var szpos = -1; + for (var i = 0; i < l; i++) { + if (_words[i].indexOf('px') > 0 || _words[i].indexOf('pt') > 0) { + szpos = i; + this._size = parseInt(_words[i]); + if (this._size <= 0) { + console.error('font parse error:' + value); + this._size = 14; + } + break; + } + } + var fpos = szpos + 1; + var familys = _words[fpos]; + fpos++; + for (; fpos < l; fpos++) { + familys += ' ' + _words[fpos]; + } + this._family = (familys.split(','))[0]; + this._italic = _words.indexOf('italic') >= 0; + this._bold = _words.indexOf('bold') >= 0; + } + } + FontInfo.EMPTY = new FontInfo(null); + FontInfo._cache = {}; + FontInfo._gfontID = 0; + FontInfo._lastFont = ''; + + class WordText { + constructor() { + this.save = []; + this.toUpperCase = null; + this.width = -1; + this.pageChars = []; + this.startID = 0; + this.startIDStroke = 0; + this.lastGCCnt = 0; + this.splitRender = false; + this.scalex = 1; + this.scaley = 1; + } + setText(txt) { + this.changed = true; + this._text = txt; + this.width = -1; + this.cleanCache(); + } + toString() { + return this._text; + } + get length() { + return this._text ? this._text.length : 0; + } + charCodeAt(i) { + return this._text ? this._text.charCodeAt(i) : NaN; + } + charAt(i) { + return this._text ? this._text.charAt(i) : null; + } + cleanCache() { + let pagecharse = this.pageChars; + for (var i in pagecharse) { + let p = pagecharse[i]; + var tex = p.tex; + var words = p.words; + if (words.length == 1 && tex && tex.ri) { + tex.destroy(); + } + } + this.pageChars = []; + this.startID = 0; + this.scalex = 1; + this.scaley = 1; + } + } + + class CharRenderInfo { + constructor() { + this.char = ''; + this.deleted = false; + this.uv = new Array(8); + this.pos = 0; + this.orix = 0; + this.oriy = 0; + this.touchTick = 0; + this.isSpace = false; + } + touch() { + var curLoop = RenderInfo.loopCount; + if (this.touchTick != curLoop) { + this.tex.touchRect(this, curLoop); + } + this.touchTick = curLoop; + } + } + + class ICharRender { + constructor() { + this.fontsz = 16; + } + getWidth(font, str) { return 0; } + scale(sx, sy) { + } + get canvasWidth() { + return 0; + } + set canvasWidth(w) { + } + getCharBmp(char, font, lineWidth, colStr, strokeColStr, size, margin_left, margin_top, margin_right, margin_bottom, rect = null) { + return null; + } + } + + class Browser { + static __init__() { + var Laya = window.Laya || ILaya.Laya; + if (Browser._window) + return Browser._window; + var win = Browser._window = window; + var doc = Browser._document = win.document; + var u = Browser.userAgent = win.navigator.userAgent; + var maxTouchPoints = win.navigator.maxTouchPoints || 0; + var platform = win.navigator.platform; + if ("my" in Browser.window) { + if (u.indexOf('TB/') > -1 || u.indexOf('Taobao/') > -1 || u.indexOf('TM/') > -1) { + window.tbMiniGame(Laya, Laya); + if (!Laya["TBMiniAdapter"]) { + console.error("请先添加淘宝适配库,详细教程:https://ldc2.layabox.com/doc/?language=zh&nav=zh-ts-5-6-0"); + } + else { + Laya["TBMiniAdapter"].enable(); + } + } + else if (u.indexOf('AlipayMiniGame') > -1) { + window.aliPayMiniGame(Laya, Laya); + if (!Laya["ALIMiniAdapter"]) { + console.error("请先添加阿里小游戏适配库,详细教程:https://ldc2.layabox.com/doc/?language=zh&nav=zh-ts-5-6-0"); + } + else { + Laya["ALIMiniAdapter"].enable(); + } + } + } + if (u.indexOf('OPPO') == -1 && u.indexOf("MiniGame") > -1 && "wx" in Browser.window) { + if ("tt" in Browser.window) { + window.ttMiniGame(Laya, Laya); + if (!Laya["TTMiniAdapter"]) { + console.error("请引入字节跳动小游戏的适配库"); + } + else { + Laya["TTMiniAdapter"].enable(); + } + } + else if ("bl" in Browser.window) { + window.biliMiniGame(Laya, Laya); + if (!Laya["BLMiniAdapter"]) { + console.error("请引入bilibili小游戏的适配库,详细教程:https://ldc2.layabox.com/doc/?language=zh&nav=zh-ts-5-7-0"); + } + else { + Laya["BLMiniAdapter"].enable(); + } + } + else if ("qq" in Browser.window) { + window.qqMiniGame(Laya, Laya); + if (!Laya["QQMiniAdapter"]) { + console.error("请引入手机QQ小游戏的适配库,详细教程:https://ldc2.layabox.com/doc/?language=zh&nav=zh-ts-5-0-0"); + } + else { + Laya["QQMiniAdapter"].enable(); + } + } + else { + window.wxMiniGame(Laya, Laya); + if (!Laya["MiniAdpter"]) { + console.error("请先添加小游戏适配库,详细教程:https://ldc2.layabox.com/doc/?nav=zh-ts-5-0-0"); + } + else { + Laya["MiniAdpter"].enable(); + } + } + } + if ("hbs" in Browser.window) { + window.hwMiniGame(Laya, Laya); + if (!Laya["HWMiniAdapter"]) { + console.error("请先添加小游戏适配库!"); + } + else { + Laya["HWMiniAdapter"].enable(); + } + } + if (u.indexOf("SwanGame") > -1) { + window.bdMiniGame(Laya, Laya); + if (!Laya["BMiniAdapter"]) { + console.error("请先添加百度小游戏适配库,详细教程:https://ldc2.layabox.com/doc/?language=zh&nav=zh-ts-5-1-0"); + } + else { + Laya["BMiniAdapter"].enable(); + } + } + if (u.indexOf('QuickGame') > -1) { + window.miMiniGame(Laya, Laya); + if (!Laya["KGMiniAdapter"]) { + console.error("请先添加小米小游戏适配库,详细教程:https://ldc2.layabox.com/doc/?language=zh&nav=zh-ts-5-2-0"); + } + else { + Laya["KGMiniAdapter"].enable(); + } + } + if (u.indexOf('OPPO') > -1 && u.indexOf('MiniGame') > -1) { + window.qgMiniGame(Laya, Laya); + if (!Laya["QGMiniAdapter"]) { + console.error("请先添加OPPO小游戏适配库,详细教程:https://ldc2.layabox.com/doc/?language=zh&nav=zh-ts-5-3-0"); + } + else { + Laya["QGMiniAdapter"].enable(); + } + } + if (u.indexOf('VVGame') > -1) { + window.vvMiniGame(Laya, Laya); + if (!Laya["VVMiniAdapter"]) { + console.error("请先添加VIVO小游戏适配库,详细教程:https://ldc2.layabox.com/doc/?language=zh&nav=zh-ts-5-4-0"); + } + else { + Laya["VVMiniAdapter"].enable(); + } + } + win.trace = console.log; + win.requestAnimationFrame = win.requestAnimationFrame || win.webkitRequestAnimationFrame || win.mozRequestAnimationFrame || win.oRequestAnimationFrame || win.msRequestAnimationFrame || function (fun) { + return win.setTimeout(fun, 1000 / 60); + }; + var bodyStyle = doc.body.style; + bodyStyle.margin = 0; + bodyStyle.overflow = 'hidden'; + bodyStyle['-webkit-user-select'] = 'none'; + bodyStyle['-webkit-tap-highlight-color'] = 'rgba(200,200,200,0)'; + var metas = doc.getElementsByTagName('meta'); + var i = 0, flag = false, content = 'width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no'; + while (i < metas.length) { + var meta = metas[i]; + if (meta.name == 'viewport') { + meta.content = content; + flag = true; + break; + } + i++; + } + if (!flag) { + meta = doc.createElement('meta'); + meta.name = 'viewport', meta.content = content; + doc.getElementsByTagName('head')[0].appendChild(meta); + } + Browser.onMobile = window.conch ? true : u.indexOf("Mobile") > -1; + Browser.onIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); + Browser.onIPhone = u.indexOf("iPhone") > -1; + Browser.onMac = u.indexOf("Mac OS X") > -1; + Browser.onIPad = u.indexOf("iPad") > -1 || (platform === 'MacIntel' && maxTouchPoints > 1); + Browser.onAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; + Browser.onWP = u.indexOf("Windows Phone") > -1; + Browser.onQQBrowser = u.indexOf("QQBrowser") > -1; + Browser.onMQQBrowser = u.indexOf("MQQBrowser") > -1 || (u.indexOf("Mobile") > -1 && u.indexOf("QQ") > -1); + Browser.onIE = !!win.ActiveXObject || "ActiveXObject" in win; + Browser.onWeiXin = u.indexOf('MicroMessenger') > -1; + Browser.onSafari = u.indexOf("Safari") > -1; + Browser.onPC = !Browser.onMobile; + Browser.onFirefox = u.indexOf('Firefox') > -1; + Browser.onEdge = u.indexOf('Edge') > -1; + Browser.onMiniGame = u.indexOf('MiniGame') > -1; + Browser.onBDMiniGame = u.indexOf('SwanGame') > -1; + Browser.onLayaRuntime = !!window.conch; + if (u.indexOf('OPPO') > -1 && u.indexOf('MiniGame') > -1) { + Browser.onQGMiniGame = true; + Browser.onMiniGame = false; + } + else if ("qq" in Browser.window && u.indexOf('MiniGame') > -1) { + Browser.onQQMiniGame = true; + Browser.onMiniGame = false; + } + else if ("bl" in Browser.window && u.indexOf('MiniGame') > -1) { + Browser.onBLMiniGame = true; + Browser.onMiniGame = false; + } + else if ("tt" in Browser.window && u.indexOf('MiniGame') > -1) { + Browser.onTTMiniGame = true; + Browser.onMiniGame = false; + } + Browser.onHWMiniGame = "hbs" in Browser.window; + Browser.onVVMiniGame = u.indexOf('VVGame') > -1; + Browser.onKGMiniGame = u.indexOf('QuickGame') > -1; + if (u.indexOf('AlipayMiniGame') > -1) { + Browser.onAlipayMiniGame = true; + Browser.onMiniGame = false; + } + if (u.indexOf('TB/') > -1 || u.indexOf('Taobao/') > -1 || u.indexOf('TM/') > -1) { + Browser.onTBMiniGame = true; + } + return win; + } + static get _isMiniGame() { + return Browser.onMiniGame || Browser.onBDMiniGame || Browser.onQGMiniGame || Browser.onKGMiniGame || Browser.onVVMiniGame || Browser.onAlipayMiniGame || Browser.onQQMiniGame || Browser.onBLMiniGame || Browser.onTTMiniGame || Browser.onHWMiniGame || Browser.onTBMiniGame; + } + static createElement(type) { + Browser.__init__(); + return Browser._document.createElement(type); + } + static getElementById(type) { + Browser.__init__(); + return Browser._document.getElementById(type); + } + static removeElement(ele) { + if (ele && ele.parentNode) + ele.parentNode.removeChild(ele); + } + static now() { + return Date.now(); + } + static get clientWidth() { + Browser.__init__(); + return Browser._window.innerWidth || Browser._document.body.clientWidth; + } + static get clientHeight() { + Browser.__init__(); + return Browser._window.innerHeight || Browser._document.body.clientHeight || Browser._document.documentElement.clientHeight; + } + static get width() { + Browser.__init__(); + return ((ILaya.stage && ILaya.stage.canvasRotation) ? Browser.clientHeight : Browser.clientWidth) * Browser.pixelRatio; + } + static get height() { + Browser.__init__(); + return ((ILaya.stage && ILaya.stage.canvasRotation) ? Browser.clientWidth : Browser.clientHeight) * Browser.pixelRatio; + } + static get pixelRatio() { + if (Browser._pixelRatio < 0) { + Browser.__init__(); + if (Browser.userAgent.indexOf("Mozilla/6.0(Linux; Android 6.0; HUAWEI NXT-AL10 Build/HUAWEINXT-AL10)") > -1) + Browser._pixelRatio = 2; + else { + Browser._pixelRatio = (Browser._window.devicePixelRatio || 1); + if (Browser._pixelRatio < 1) + Browser._pixelRatio = 1; + } + } + return Browser._pixelRatio; + } + static get container() { + if (!Browser._container) { + Browser.__init__(); + Browser._container = Browser.createElement("div"); + Browser._container.id = "layaContainer"; + Browser._document.body.appendChild(Browser._container); + } + return Browser._container; + } + static set container(value) { + Browser._container = value; + } + static get window() { + return Browser._window || Browser.__init__(); + } + static get document() { + Browser.__init__(); + return Browser._document; + } + } + Browser._pixelRatio = -1; + Browser.mainCanvas = null; + Browser.hanzi = new RegExp("^[\u4E00-\u9FA5]$"); + Browser.fontMap = {}; + Browser.measureText = function (txt, font) { + var isChinese = Browser.hanzi.test(txt); + if (isChinese && Browser.fontMap[font]) { + return Browser.fontMap[font]; + } + var ctx = Browser.context; + ctx.font = font; + var r = ctx.measureText(txt); + if (isChinese) + Browser.fontMap[font] = r; + return r; + }; + + class CharRender_Canvas extends ICharRender { + constructor(maxw, maxh, scalefont = true, useImageData = true, showdbg = false) { + super(); + this.ctx = null; + this.lastScaleX = 1.0; + this.lastScaleY = 1.0; + this.maxTexW = 0; + this.maxTexH = 0; + this.scaleFontSize = true; + this.showDbgInfo = false; + this.supportImageData = true; + this.maxTexW = maxw; + this.maxTexH = maxh; + this.scaleFontSize = scalefont; + this.supportImageData = useImageData; + this.showDbgInfo = showdbg; + if (!CharRender_Canvas.canvas) { + CharRender_Canvas.canvas = Browser.createElement('canvas'); + CharRender_Canvas.canvas.width = 1024; + CharRender_Canvas.canvas.height = 512; + CharRender_Canvas.canvas.style.left = "-10000px"; + CharRender_Canvas.canvas.style.position = "absolute"; + document.body.appendChild(CharRender_Canvas.canvas); + this.ctx = CharRender_Canvas.canvas.getContext('2d'); + } + } + get canvasWidth() { + return CharRender_Canvas.canvas.width; + } + set canvasWidth(w) { + if (CharRender_Canvas.canvas.width == w) + return; + CharRender_Canvas.canvas.width = w; + if (w > 2048) { + console.warn("画文字设置的宽度太大,超过2048了"); + } + this.ctx.setTransform(1, 0, 0, 1, 0, 0); + this.ctx.scale(this.lastScaleX, this.lastScaleY); + } + getWidth(font, str) { + if (!this.ctx) + return 0; + if (this.ctx._lastFont != font) { + this.ctx.font = font; + this.ctx._lastFont = font; + } + return this.ctx.measureText(str).width; + } + scale(sx, sy) { + if (!this.supportImageData) { + this.lastScaleX = sx; + this.lastScaleY = sy; + return; + } + if (this.lastScaleX != sx || this.lastScaleY != sy) { + this.ctx.setTransform(sx, 0, 0, sy, 0, 0); + this.lastScaleX = sx; + this.lastScaleY = sy; + } + } + getCharBmp(char, font, lineWidth, colStr, strokeColStr, cri, margin_left, margin_top, margin_right, margin_bottom, rect = null) { + if (!this.supportImageData) + return this.getCharCanvas(char, font, lineWidth, colStr, strokeColStr, cri, margin_left, margin_top, margin_right, margin_bottom); + var ctx = this.ctx; + var sz = this.fontsz; + if (ctx.font != font) { + ctx.font = font; + ctx._lastFont = font; + } + cri.width = ctx.measureText(char).width; + var w = cri.width * this.lastScaleX; + var h = cri.height * this.lastScaleY; + w += (margin_left + margin_right) * this.lastScaleX; + h += (margin_top + margin_bottom) * this.lastScaleY; + w = Math.ceil(w); + h = Math.ceil(h); + w = Math.min(w, CharRender_Canvas.canvas.width); + h = Math.min(h, CharRender_Canvas.canvas.height); + var clearW = w + lineWidth * 2 + 1; + var clearH = h + lineWidth * 2 + 1; + if (rect) { + clearW = Math.max(clearW, rect[0] + rect[2] + 1); + clearH = Math.max(clearH, rect[1] + rect[3] + 1); + } + ctx.clearRect(0, 0, clearW / this.lastScaleX + 1, clearH / this.lastScaleY + 1); + ctx.save(); + ctx.textBaseline = "middle"; + if (lineWidth > 0) { + ctx.strokeStyle = strokeColStr; + ctx.lineWidth = lineWidth; + ctx.strokeText(char, margin_left, margin_top + sz / 2); + } + if (colStr) { + ctx.fillStyle = colStr; + ctx.fillText(char, margin_left, margin_top + sz / 2); + } + if (this.showDbgInfo) { + ctx.strokeStyle = '#ff0000'; + ctx.strokeRect(1, 1, w - 2, h - 2); + ctx.strokeStyle = '#00ff00'; + ctx.strokeRect(margin_left, margin_top, cri.width, cri.height); + } + if (rect) { + if (rect[2] == -1) + rect[2] = Math.ceil((cri.width + lineWidth * 2) * this.lastScaleX); + if (rect[2] <= 0) + rect[2] = 1; + } + var imgdt = rect ? (ctx.getImageData(rect[0], rect[1], rect[2], rect[3] + 1)) : (ctx.getImageData(0, 0, w, h + 1)); + ctx.restore(); + cri.bmpWidth = imgdt.width; + cri.bmpHeight = imgdt.height; + return imgdt; + } + getCharCanvas(char, font, lineWidth, colStr, strokeColStr, cri, margin_left, margin_top, margin_right, margin_bottom) { + var ctx = this.ctx; + if (ctx.font != font) { + ctx.font = font; + ctx._lastFont = font; + } + cri.width = ctx.measureText(char).width; + var w = cri.width * this.lastScaleX; + var h = cri.height * this.lastScaleY; + w += (margin_left + margin_right) * this.lastScaleX; + h += ((margin_top + margin_bottom) * this.lastScaleY + 1); + w = Math.min(w, this.maxTexW); + h = Math.min(h, this.maxTexH); + CharRender_Canvas.canvas.width = Math.min(w + 1, this.maxTexW); + CharRender_Canvas.canvas.height = Math.min(h + 1, this.maxTexH); + ctx.font = font; + ctx.clearRect(0, 0, w + 1 + lineWidth, h + 1 + lineWidth); + ctx.setTransform(1, 0, 0, 1, 0, 0); + ctx.save(); + if (this.scaleFontSize) { + ctx.scale(this.lastScaleX, this.lastScaleY); + } + ctx.translate(margin_left, margin_top); + ctx.textAlign = "left"; + var sz = this.fontsz; + ctx.textBaseline = "middle"; + if (lineWidth > 0) { + ctx.strokeStyle = strokeColStr; + ctx.fillStyle = colStr; + ctx.lineWidth = lineWidth; + if (ctx.fillAndStrokeText) { + ctx.fillAndStrokeText(char, 0, sz / 2); + } + else { + ctx.strokeText(char, 0, sz / 2); + ctx.fillText(char, 0, sz / 2); + } + } + else if (colStr) { + ctx.fillStyle = colStr; + ctx.fillText(char, 0, sz / 2); + } + if (this.showDbgInfo) { + ctx.strokeStyle = '#ff0000'; + ctx.strokeRect(0, 0, w, h); + ctx.strokeStyle = '#00ff00'; + ctx.strokeRect(0, 0, cri.width, cri.height); + } + ctx.restore(); + cri.bmpWidth = CharRender_Canvas.canvas.width; + cri.bmpHeight = CharRender_Canvas.canvas.height; + return CharRender_Canvas.canvas; + } + } + CharRender_Canvas.canvas = null; + + class CharRender_Native extends ICharRender { + constructor() { + super(); + this.lastFont = ''; + this.lastScaleX = 1.0; + this.lastScaleY = 1.0; + } + getWidth(font, str) { + if (!window.conchTextCanvas) + return 0; + window.conchTextCanvas.font = font; + this.lastFont = font; + return window.conchTextCanvas.measureText(str).width; + } + scale(sx, sy) { + this.lastScaleX = sx; + this.lastScaleY = sy; + } + getCharBmp(char, font, lineWidth, colStr, strokeColStr, size, margin_left, margin_top, margin_right, margin_bottom, rect = null) { + if (!window.conchTextCanvas) + return null; + window.conchTextCanvas.font = font; + this.lastFont = font; + var w = size.width = window.conchTextCanvas.measureText(char).width; + var h = size.height; + w += (margin_left + margin_right); + h += (margin_top + margin_bottom); + window.conchTextCanvas.scale && window.conchTextCanvas.scale(this.lastScaleX, this.lastScaleY); + var c1 = ColorUtils.create(strokeColStr); + var nStrokeColor = c1.numColor; + var c2 = ColorUtils.create(colStr); + var nTextColor = c2.numColor; + var textInfo = window.conchTextCanvas.getTextBitmapData(char, nTextColor, lineWidth > 2 ? 2 : lineWidth, nStrokeColor); + size.bmpWidth = textInfo.width; + size.bmpHeight = textInfo.height; + return textInfo; + } + } + + class TextRender { + constructor() { + this.fontSizeInfo = {}; + this.mapFont = {}; + this.fontID = 0; + this.fontScaleX = 1.0; + this.fontScaleY = 1.0; + this._curStrPos = 0; + this.textAtlases = []; + this.isoTextures = []; + this.lastFont = null; + this.fontSizeW = 0; + this.fontSizeH = 0; + this.fontSizeOffX = 0; + this.fontSizeOffY = 0; + this.renderPerChar = true; + this.tmpAtlasPos = new Point(); + this.textureMem = 0; + ILaya.TextAtlas = TextAtlas; + var bugIOS = false; + var miniadp = ILaya.Laya['MiniAdpter']; + if (miniadp && miniadp.systemInfo && miniadp.systemInfo.system) { + bugIOS = miniadp.systemInfo.system.toLowerCase() === 'ios 10.1.1'; + } + if ((ILaya.Browser.onMiniGame || ILaya.Browser.onTTMiniGame || ILaya.Browser.onBLMiniGame || ILaya.Browser.onAlipayMiniGame || ILaya.Browser.onTBMiniGame) && !bugIOS) + TextRender.isWan1Wan = true; + this.charRender = ILaya.Render.isConchApp ? (new CharRender_Native()) : (new CharRender_Canvas(2048, 2048, TextRender.scaleFontWithCtx, !TextRender.isWan1Wan, false)); + TextRender.textRenderInst = this; + ILaya.Laya['textRender'] = this; + TextRender.atlasWidth2 = TextRender.atlasWidth * TextRender.atlasWidth; + } + setFont(font) { + if (this.lastFont == font) + return; + this.lastFont = font; + var fontsz = this.getFontSizeInfo(font._family); + var offx = fontsz >> 24; + var offy = (fontsz >> 16) & 0xff; + var fw = (fontsz >> 8) & 0xff; + var fh = fontsz & 0xff; + var k = font._size / TextRender.standardFontSize; + this.fontSizeOffX = Math.ceil(offx * k); + this.fontSizeOffY = Math.ceil(offy * k); + this.fontSizeW = Math.ceil(fw * k); + this.fontSizeH = Math.ceil(fh * k); + if (font._font.indexOf('italic') >= 0) { + this.fontStr = font._font.replace('italic', ''); + } + else { + this.fontStr = font._font; + } + } + getNextChar(str) { + var len = str.length; + var start = this._curStrPos; + if (!str.substring) + return null; + if (start >= len) + return null; + var i = start; + var state = 0; + for (; i < len; i++) { + var c = str.charCodeAt(i); + if ((c >>> 11) == 0x1b) { + if (state == 1) + break; + state = 1; + i++; + } + else if (c === 0xfe0e || c === 0xfe0f) ; + else if (c == 0x200d) { + state = 2; + } + else { + if (state == 0) + state = 1; + else if (state == 1) + break; + } + } + this._curStrPos = i; + return str.substring(start, i); + } + filltext(ctx, data, x, y, fontStr, color, strokeColor, lineWidth, textAlign, underLine = 0) { + if (data.length <= 0) + return; + var font = FontInfo.Parse(fontStr); + var nTextAlign = 0; + switch (textAlign) { + case 'center': + nTextAlign = ILaya.Context.ENUM_TEXTALIGN_CENTER; + break; + case 'right': + nTextAlign = ILaya.Context.ENUM_TEXTALIGN_RIGHT; + break; + } + this._fast_filltext(ctx, data, null, x, y, font, color, strokeColor, lineWidth, nTextAlign, underLine); + } + fillWords(ctx, data, x, y, fontStr, color, strokeColor, lineWidth) { + if (!data) + return; + if (data.length <= 0) + return; + var font = typeof (fontStr) === 'string' ? FontInfo.Parse(fontStr) : fontStr; + this._fast_filltext(ctx, null, data, x, y, font, color, strokeColor, lineWidth, 0, 0); + } + _fast_filltext(ctx, data, htmlchars, x, y, font, color, strokeColor, lineWidth, textAlign, underLine = 0) { + if (data && !(data.length >= 1)) + return; + if (htmlchars && htmlchars.length < 1) + return; + if (lineWidth < 0) + lineWidth = 0; + this.setFont(font); + this.fontScaleX = this.fontScaleY = 1.0; + if (TextRender.scaleFontWithCtx) { + var sx = 1; + var sy = 1; + if (!ILaya.Render.isConchApp || (window.conchTextCanvas.scale)) { + sx = ctx.getMatScaleX(); + sy = ctx.getMatScaleY(); + } + if (sx < 1e-4 || sy < 1e-1) + return; + if (sx > 1) + this.fontScaleX = sx; + if (sy > 1) + this.fontScaleY = sy; + } + font._italic && (ctx._italicDeg = 13); + var wt = data; + var isWT = !htmlchars && (data instanceof WordText); + var str = data && data.toString(); + var isHtmlChar = !!htmlchars; + var sameTexData = isWT ? wt.pageChars : []; + var strWidth = 0; + if (isWT) { + str = wt._text; + strWidth = wt.width; + if (strWidth < 0) { + strWidth = wt.width = this.charRender.getWidth(this.fontStr, str); + } + } + else { + strWidth = str ? this.charRender.getWidth(this.fontStr, str) : 0; + } + switch (textAlign) { + case ILaya.Context.ENUM_TEXTALIGN_CENTER: + x -= strWidth / 2; + break; + case ILaya.Context.ENUM_TEXTALIGN_RIGHT: + x -= strWidth; + break; + } + if (wt && sameTexData) { + if (this.hasFreedText(sameTexData)) { + sameTexData = wt.pageChars = []; + } + } + var ri = null; + var splitTex = this.renderPerChar = (!isWT) || TextRender.forceSplitRender || isHtmlChar || (isWT && wt.splitRender); + if (!sameTexData || sameTexData.length < 1) { + if (isWT) { + wt.scalex = this.fontScaleX; + wt.scaley = this.fontScaleY; + } + if (splitTex) { + var stx = 0; + var sty = 0; + this._curStrPos = 0; + var curstr; + while (true) { + if (htmlchars) { + var chc = htmlchars[this._curStrPos++]; + if (chc) { + curstr = chc.char; + stx = chc.x; + sty = chc.y; + } + else { + curstr = null; + } + } + else { + curstr = this.getNextChar(str); + } + if (!curstr) + break; + ri = this.getCharRenderInfo(curstr, font, color, strokeColor, lineWidth, false); + if (!ri) { + break; + } + if (ri.isSpace) ; + else { + var add = sameTexData[ri.tex.id]; + if (!add) { + var o1 = { texgen: ri.tex.genID, tex: ri.tex, words: new Array() }; + sameTexData[ri.tex.id] = o1; + add = o1.words; + } + else { + add = add.words; + } + add.push({ ri: ri, x: stx, y: sty, w: ri.bmpWidth / this.fontScaleX, h: ri.bmpHeight / this.fontScaleY }); + stx += ri.width; + } + } + } + else { + var margin = ILaya.Render.isConchApp ? 0 : (font._size / 3 | 0); + var isotex = TextRender.noAtlas || (strWidth + margin + margin) * this.fontScaleX > TextRender.atlasWidth; + ri = this.getCharRenderInfo(str, font, color, strokeColor, lineWidth, isotex); + sameTexData[0] = { texgen: ri.tex.genID, tex: ri.tex, words: [{ ri: ri, x: 0, y: 0, w: ri.bmpWidth / this.fontScaleX, h: ri.bmpHeight / this.fontScaleY }] }; + } + } + this._drawResortedWords(ctx, x, y, sameTexData); + ctx._italicDeg = 0; + } + _drawResortedWords(ctx, startx, starty, samePagesData) { + var isLastRender = ctx._charSubmitCache ? ctx._charSubmitCache._enable : false; + var mat = ctx._curMat; + for (var id in samePagesData) { + var dt = samePagesData[id]; + if (!dt) + continue; + var pri = dt.words; + var pisz = pri.length; + if (pisz <= 0) + continue; + var tex = samePagesData[id].tex; + for (var j = 0; j < pisz; j++) { + var riSaved = pri[j]; + var ri = riSaved.ri; + if (ri.isSpace) + continue; + ri.touch(); + ctx.drawTexAlign = true; + if (ILaya.Render.isConchApp) { + ctx._drawTextureM(tex.texture, startx + riSaved.x - ri.orix, starty + riSaved.y - ri.oriy, riSaved.w, riSaved.h, null, 1.0, ri.uv); + } + else { + let t = tex; + ctx._inner_drawTexture(t.texture, t.id, startx + riSaved.x - ri.orix, starty + riSaved.y - ri.oriy, riSaved.w, riSaved.h, mat, ri.uv, 1.0, isLastRender); + } + if (ctx.touches) { + ctx.touches.push(ri); + } + } + } + } + hasFreedText(txts) { + for (let i in txts) { + var pri = txts[i]; + if (!pri) + continue; + var tex = pri.tex; + if (tex.__destroyed || tex.genID != pri.texgen) { + return true; + } + } + return false; + } + getCharRenderInfo(str, font, color, strokeColor, lineWidth, isoTexture = false) { + var fid = this.mapFont[font._family]; + if (fid == undefined) { + this.mapFont[font._family] = fid = this.fontID++; + } + var key = str + '_' + fid + '_' + font._size + '_' + color; + if (lineWidth > 0) + key += '_' + strokeColor + lineWidth; + if (font._bold) + key += 'P'; + if (this.fontScaleX != 1 || this.fontScaleY != 1) { + key += (this.fontScaleX * 20 | 0) + '_' + (this.fontScaleY * 20 | 0); + } + var i = 0; + var sz = this.textAtlases.length; + var ri; + var atlas; + if (!isoTexture) { + for (i = 0; i < sz; i++) { + atlas = this.textAtlases[i]; + ri = atlas.charMaps[key]; + if (ri) { + ri.touch(); + return ri; + } + } + } + ri = new CharRenderInfo(); + this.charRender.scale(this.fontScaleX, this.fontScaleY); + ri.char = str; + ri.height = font._size; + var margin = ILaya.Render.isConchApp ? 0 : (font._size / 3 | 0); + var imgdt = null; + if (!lineWidth) { + lineWidth = 0; + } + var w1 = Math.ceil((this.charRender.getWidth(this.fontStr, str) + 2 * lineWidth) * this.fontScaleX); + if (w1 > this.charRender.canvasWidth) { + this.charRender.canvasWidth = Math.min(2048, w1 + margin * 2); + } + if (isoTexture) { + this.charRender.fontsz = font._size; + imgdt = this.charRender.getCharBmp(str, this.fontStr, lineWidth, color, strokeColor, ri, margin, margin, margin, margin, null); + if (imgdt) { + var tex = TextTexture.getTextTexture(imgdt.width, imgdt.height); + tex.addChar(imgdt, 0, 0, ri.uv); + ri.tex = tex; + ri.orix = margin; + ri.oriy = margin; + tex.ri = ri; + this.isoTextures.push(tex); + } + } + else { + var len = str.length; + var lineExt = lineWidth * 1; + var fw = Math.ceil((this.fontSizeW + lineExt * 2) * this.fontScaleX); + var fh = Math.ceil((this.fontSizeH + lineExt * 2) * this.fontScaleY); + TextRender.imgdtRect[0] = ((margin - this.fontSizeOffX - lineExt) * this.fontScaleX) | 0; + TextRender.imgdtRect[1] = ((margin - this.fontSizeOffY - lineExt) * this.fontScaleY) | 0; + if (this.renderPerChar || len == 1) { + TextRender.imgdtRect[2] = Math.max(w1, fw); + TextRender.imgdtRect[3] = Math.max(w1, fh); + } + else { + TextRender.imgdtRect[2] = -1; + TextRender.imgdtRect[3] = fh; + } + this.charRender.fontsz = font._size; + imgdt = this.charRender.getCharBmp(str, this.fontStr, lineWidth, color, strokeColor, ri, margin, margin, margin, margin, TextRender.imgdtRect); + if (imgdt) { + atlas = this.addBmpData(imgdt, ri); + if (TextRender.isWan1Wan) { + ri.orix = margin; + ri.oriy = margin; + } + else { + ri.orix = (this.fontSizeOffX + lineExt); + ri.oriy = (this.fontSizeOffY + lineExt); + } + atlas.charMaps[key] = ri; + } + } + return ri; + } + addBmpData(data, ri) { + var w = data.width; + var h = data.height; + var sz = this.textAtlases.length; + var atlas; + var find = false; + for (var i = 0; i < sz; i++) { + atlas = this.textAtlases[i]; + find = atlas.getAEmpty(w, h, this.tmpAtlasPos); + if (find) { + break; + } + } + if (!find) { + atlas = new TextAtlas(); + this.textAtlases.push(atlas); + find = atlas.getAEmpty(w, h, this.tmpAtlasPos); + if (!find) { + throw 'err1'; + } + this.cleanAtlases(); + } + if (find) { + atlas.texture.addChar(data, this.tmpAtlasPos.x, this.tmpAtlasPos.y, ri.uv); + ri.tex = atlas.texture; + } + return atlas; + } + GC() { + var i = 0; + var sz = this.textAtlases.length; + var dt = 0; + var destroyDt = TextRender.destroyAtlasDt; + var totalUsedRate = 0; + var totalUsedRateAtlas = 0; + var curloop = RenderInfo.loopCount; + var maxWasteRateID = -1; + var maxWasteRate = 0; + var tex = null; + var curatlas = null; + for (; i < sz; i++) { + curatlas = this.textAtlases[i]; + tex = curatlas.texture; + if (tex) { + totalUsedRate += tex.curUsedCovRate; + totalUsedRateAtlas += tex.curUsedCovRateAtlas; + var waste = curatlas.usedRate - tex.curUsedCovRateAtlas; + if (maxWasteRate < waste) { + maxWasteRate = waste; + maxWasteRateID = i; + } + } + dt = curloop - curatlas.texture.lastTouchTm; + if (dt > destroyDt) { + TextRender.showLog && console.log('TextRender GC delete atlas ' + tex ? curatlas.texture.id : 'unk'); + curatlas.destroy(); + this.textAtlases[i] = this.textAtlases[sz - 1]; + sz--; + i--; + maxWasteRateID = -1; + } + } + this.textAtlases.length = sz; + sz = this.isoTextures.length; + for (i = 0; i < sz; i++) { + tex = this.isoTextures[i]; + dt = curloop - tex.lastTouchTm; + if (dt > TextRender.destroyUnusedTextureDt) { + tex.ri.deleted = true; + tex.ri.tex = null; + tex.destroy(); + this.isoTextures[i] = this.isoTextures[sz - 1]; + sz--; + i--; + } + } + this.isoTextures.length = sz; + var needGC = this.textAtlases.length > 1 && this.textAtlases.length - totalUsedRateAtlas >= 2; + if (TextRender.atlasWidth * TextRender.atlasWidth * 4 * this.textAtlases.length > TextRender.cleanMem || needGC || TextRender.simClean) { + TextRender.simClean = false; + TextRender.showLog && console.log('清理使用率低的贴图。总使用率:', totalUsedRateAtlas, ':', this.textAtlases.length, '最差贴图:' + maxWasteRateID); + if (maxWasteRateID >= 0) { + curatlas = this.textAtlases[maxWasteRateID]; + curatlas.destroy(); + this.textAtlases[maxWasteRateID] = this.textAtlases[this.textAtlases.length - 1]; + this.textAtlases.length = this.textAtlases.length - 1; + } + } + TextTexture.clean(); + } + cleanAtlases() { + } + getCharBmp(c) { + } + checkBmpLine(data, l, sx, ex) { + if (this.bmpData32.buffer != data.data.buffer) { + this.bmpData32 = new Uint32Array(data.data.buffer); + } + var stpos = data.width * l + sx; + for (var x = sx; x < ex; x++) { + if (this.bmpData32[stpos++] != 0) + return true; + } + return false; + } + updateBbx(data, curbbx, onlyH = false) { + var w = data.width; + var h = data.height; + var x = 0; + var sy = curbbx[1]; + var ey = 0; + var y = sy; + if (this.checkBmpLine(data, sy, 0, w)) { + while (true) { + y = (sy + ey) / 2 | 0; + if (y + 1 >= sy) { + curbbx[1] = y; + break; + } + if (this.checkBmpLine(data, y, 0, w)) { + sy = y; + } + else { + ey = y; + } + } + } + if (curbbx[3] > h) + curbbx[3] = h; + else { + y = sy = curbbx[3]; + ey = h; + if (this.checkBmpLine(data, sy, 0, w)) { + while (true) { + y = (sy + ey) / 2 | 0; + if (y - 1 <= sy) { + curbbx[3] = y; + break; + } + if (this.checkBmpLine(data, y, 0, w)) { + sy = y; + } + else { + ey = y; + } + } + } + } + if (onlyH) + return; + var minx = curbbx[0]; + var stpos = w * curbbx[1]; + for (y = curbbx[1]; y < curbbx[3]; y++) { + for (x = 0; x < minx; x++) { + if (this.bmpData32[stpos + x] != 0) { + minx = x; + break; + } + } + stpos += w; + } + curbbx[0] = minx; + var maxx = curbbx[2]; + stpos = w * curbbx[1]; + for (y = curbbx[1]; y < curbbx[3]; y++) { + for (x = maxx; x < w; x++) { + if (this.bmpData32[stpos + x] != 0) { + maxx = x; + break; + } + } + stpos += w; + } + curbbx[2] = maxx; + } + getFontSizeInfo(font) { + var finfo = this.fontSizeInfo[font]; + if (finfo != undefined) + return finfo; + var fontstr = 'bold ' + TextRender.standardFontSize + 'px ' + font; + if (TextRender.isWan1Wan) { + this.fontSizeW = this.charRender.getWidth(fontstr, '有') * 1.5; + this.fontSizeH = TextRender.standardFontSize * 1.5; + var szinfo = this.fontSizeW << 8 | this.fontSizeH; + this.fontSizeInfo[font] = szinfo; + return szinfo; + } + TextRender.pixelBBX[0] = TextRender.standardFontSize / 2; + TextRender.pixelBBX[1] = TextRender.standardFontSize / 2; + TextRender.pixelBBX[2] = TextRender.standardFontSize; + TextRender.pixelBBX[3] = TextRender.standardFontSize; + var orix = 16; + var oriy = 16; + var marginr = 16; + var marginb = 16; + this.charRender.scale(1, 1); + TextRender.tmpRI.height = TextRender.standardFontSize; + this.charRender.fontsz = TextRender.standardFontSize; + var bmpdt = this.charRender.getCharBmp('g', fontstr, 0, 'red', null, TextRender.tmpRI, orix, oriy, marginr, marginb); + if (ILaya.Render.isConchApp) { + bmpdt.data = new Uint8ClampedArray(bmpdt.data); + } + this.bmpData32 = new Uint32Array(bmpdt.data.buffer); + this.updateBbx(bmpdt, TextRender.pixelBBX, false); + bmpdt = this.charRender.getCharBmp('有', fontstr, 0, 'red', null, TextRender.tmpRI, oriy, oriy, marginr, marginb); + if (ILaya.Render.isConchApp) { + bmpdt.data = new Uint8ClampedArray(bmpdt.data); + } + this.bmpData32 = new Uint32Array(bmpdt.data.buffer); + if (TextRender.pixelBBX[2] < orix + TextRender.tmpRI.width) + TextRender.pixelBBX[2] = orix + TextRender.tmpRI.width; + this.updateBbx(bmpdt, TextRender.pixelBBX, false); + if (ILaya.Render.isConchApp) { + orix = 0; + oriy = 0; + } + var xoff = Math.max(orix - TextRender.pixelBBX[0], 0); + var yoff = Math.max(oriy - TextRender.pixelBBX[1], 0); + var bbxw = TextRender.pixelBBX[2] - TextRender.pixelBBX[0]; + var bbxh = TextRender.pixelBBX[3] - TextRender.pixelBBX[1]; + var sizeinfo = xoff << 24 | yoff << 16 | bbxw << 8 | bbxh; + this.fontSizeInfo[font] = sizeinfo; + return sizeinfo; + } + printDbgInfo() { + console.log('图集个数:' + this.textAtlases.length + ',每个图集大小:' + TextRender.atlasWidth + 'x' + TextRender.atlasWidth, ' 用canvas:', TextRender.isWan1Wan); + console.log('图集占用空间:' + (TextRender.atlasWidth * TextRender.atlasWidth * 4 / 1024 / 1024 * this.textAtlases.length) + 'M'); + console.log('缓存用到的字体:'); + for (var f in this.mapFont) { + var fontsz = this.getFontSizeInfo(f); + var offx = fontsz >> 24; + var offy = (fontsz >> 16) & 0xff; + var fw = (fontsz >> 8) & 0xff; + var fh = fontsz & 0xff; + console.log(' ' + f, ' off:', offx, offy, ' size:', fw, fh); + } + var num = 0; + console.log('缓存数据:'); + var totalUsedRate = 0; + var totalUsedRateAtlas = 0; + this.textAtlases.forEach(function (a) { + var id = a.texture.id; + var dt = RenderInfo.loopCount - a.texture.lastTouchTm; + var dtstr = dt > 0 ? ('' + dt + '帧以前') : '当前帧'; + totalUsedRate += a.texture.curUsedCovRate; + totalUsedRateAtlas += a.texture.curUsedCovRateAtlas; + console.log('--图集(id:' + id + ',当前使用率:' + (a.texture.curUsedCovRate * 1000 | 0) + '‰', '当前图集使用率:', (a.texture.curUsedCovRateAtlas * 100 | 0) + '%', '图集使用率:', (a.usedRate * 100 | 0), '%, 使用于:' + dtstr + ')--:'); + for (var k in a.charMaps) { + var ri = a.charMaps[k]; + console.log(' off:', ri.orix, ri.oriy, ' bmp宽高:', ri.bmpWidth, ri.bmpHeight, '无效:', ri.deleted, 'touchdt:', (RenderInfo.loopCount - ri.touchTick), '位置:', ri.uv[0] * TextRender.atlasWidth | 0, ri.uv[1] * TextRender.atlasWidth | 0, '字符:', ri.char, 'key:', k); + num++; + } + }); + console.log('独立贴图文字(' + this.isoTextures.length + '个):'); + this.isoTextures.forEach(function (tex) { + console.log(' size:', tex._texW, tex._texH, 'touch间隔:', (RenderInfo.loopCount - tex.lastTouchTm), 'char:', tex.ri.char); + }); + console.log('总缓存:', num, '总使用率:', totalUsedRate, '总当前图集使用率:', totalUsedRateAtlas); + } + showAtlas(n, bgcolor, x, y, w, h) { + if (!this.textAtlases[n]) { + console.log('没有这个图集'); + return null; + } + var sp = new ILaya.Sprite(); + var texttex = this.textAtlases[n].texture; + var texture = { + width: TextRender.atlasWidth, + height: TextRender.atlasWidth, + sourceWidth: TextRender.atlasWidth, + sourceHeight: TextRender.atlasWidth, + offsetX: 0, + offsetY: 0, + getIsReady: function () { return true; }, + _addReference: function () { }, + _removeReference: function () { }, + _getSource: function () { return texttex._getSource(); }, + bitmap: { id: texttex.id }, + _uv: Texture.DEF_UV + }; + sp.size = function (w, h) { + this.width = w; + this.height = h; + sp.graphics.clear(); + sp.graphics.drawRect(0, 0, sp.width, sp.height, bgcolor); + sp.graphics.drawTexture(texture, 0, 0, sp.width, sp.height); + return this; + }; + sp.graphics.drawRect(0, 0, w, h, bgcolor); + sp.graphics.drawTexture(texture, 0, 0, w, h); + sp.pos(x, y); + ILaya.stage.addChild(sp); + return sp; + } + filltext_native(ctx, data, htmlchars, x, y, fontStr, color, strokeColor, lineWidth, textAlign, underLine = 0) { + if (data && data.length <= 0) + return; + if (htmlchars && htmlchars.length < 1) + return; + var font = FontInfo.Parse(fontStr); + var nTextAlign = 0; + switch (textAlign) { + case 'center': + nTextAlign = ILaya.Context.ENUM_TEXTALIGN_CENTER; + break; + case 'right': + nTextAlign = ILaya.Context.ENUM_TEXTALIGN_RIGHT; + break; + } + return this._fast_filltext(ctx, data, htmlchars, x, y, font, color, strokeColor, lineWidth, nTextAlign, underLine); + } + } + TextRender.useOldCharBook = false; + TextRender.atlasWidth = 1024; + TextRender.noAtlas = false; + TextRender.forceSplitRender = false; + TextRender.forceWholeRender = false; + TextRender.scaleFontWithCtx = true; + TextRender.standardFontSize = 32; + TextRender.destroyAtlasDt = 10; + TextRender.checkCleanTextureDt = 2000; + TextRender.destroyUnusedTextureDt = 3000; + TextRender.cleanMem = 100 * 1024 * 1024; + TextRender.isWan1Wan = false; + TextRender.showLog = false; + TextRender.debugUV = false; + TextRender.tmpRI = new CharRenderInfo(); + TextRender.pixelBBX = [0, 0, 0, 0]; + TextRender.imgdtRect = [0, 0, 0, 0]; + TextRender.simClean = false; + TextTexture.gTextRender = TextRender; + + class Context { + constructor() { + this._tmpMatrix = new Matrix(); + this._drawTexToDrawTri_Vert = new Float32Array(8); + this._drawTexToDrawTri_Index = new Uint16Array([0, 1, 2, 0, 2, 3]); + this._tempUV = new Float32Array(8); + this._drawTriUseAbsMatrix = false; + this._id = ++Context._COUNT; + this._other = null; + this._renderNextSubmitIndex = 0; + this._path = null; + this._drawCount = 1; + this._width = Context._MAXSIZE; + this._height = Context._MAXSIZE; + this._renderCount = 0; + this._submits = null; + this._curSubmit = null; + this._submitKey = new SubmitKey(); + this._pathMesh = null; + this._triangleMesh = null; + this.meshlist = []; + this._transedPoints = new Array(8); + this._temp4Points = new Array(8); + this._clipRect = Context.MAXCLIPRECT; + this._globalClipMatrix = new Matrix(Context._MAXSIZE, 0, 0, Context._MAXSIZE, 0, 0); + this._clipInCache = false; + this._clipInfoID = 0; + this._clipID_Gen = 0; + this._lastMatScaleX = 1.0; + this._lastMatScaleY = 1.0; + this._lastMat_a = 1.0; + this._lastMat_b = 0.0; + this._lastMat_c = 0.0; + this._lastMat_d = 1.0; + this._nBlendType = 0; + this._save = null; + this._targets = null; + this._charSubmitCache = null; + this._saveMark = null; + this._shader2D = new Shader2D(); + this.sprite = null; + this._italicDeg = 0; + this._lastTex = null; + this._fillColor = 0; + this._flushCnt = 0; + this.defTexture = null; + this._colorFiler = null; + this.drawTexAlign = false; + this._incache = false; + this.isMain = false; + Context._contextcount++; + Context._textRender = Context._textRender || new TextRender(); + if (!this.defTexture) { + var defTex2d = new Texture2D(2, 2); + defTex2d.setPixels(new Uint8Array(16)); + defTex2d.lock = true; + this.defTexture = new Texture(defTex2d); + } + this._lastTex = this.defTexture; + this.clear(); + } + static __init__() { + Context.MAXCLIPRECT = new Rectangle(0, 0, Context._MAXSIZE, Context._MAXSIZE); + ContextParams.DEFAULT = new ContextParams(); + } + drawImage(...args) { + } + getImageData(...args) { + } + measureText(text) { + return null; + } + setTransform(...args) { + } + $transform(a, b, c, d, tx, ty) { + } + get lineJoin() { + return ''; + } + set lineJoin(value) { + } + get lineCap() { + return ''; + } + set lineCap(value) { + } + get miterLimit() { + return ''; + } + set miterLimit(value) { + } + clearRect(x, y, width, height) { + } + _drawRect(x, y, width, height, style) { + Stat.renderBatches++; + style && (this.fillStyle = style); + this.fillRect(x, y, width, height, null); + } + drawTexture2(x, y, pivotX, pivotY, m, args2) { + } + transformByMatrix(matrix, tx, ty) { + this.transform(matrix.a, matrix.b, matrix.c, matrix.d, matrix.tx + tx, matrix.ty + ty); + } + saveTransform(matrix) { + this.save(); + } + restoreTransform(matrix) { + this.restore(); + } + drawRect(x, y, width, height, fillColor, lineColor, lineWidth) { + var ctx = this; + if (fillColor != null) { + ctx.fillStyle = fillColor; + ctx.fillRect(x, y, width, height); + } + if (lineColor != null) { + ctx.strokeStyle = lineColor; + ctx.lineWidth = lineWidth; + ctx.strokeRect(x, y, width, height); + } + } + alpha(value) { + this.globalAlpha *= value; + } + _transform(mat, pivotX, pivotY) { + this.translate(pivotX, pivotY); + this.transform(mat.a, mat.b, mat.c, mat.d, mat.tx, mat.ty); + this.translate(-pivotX, -pivotY); + } + _rotate(angle, pivotX, pivotY) { + this.translate(pivotX, pivotY); + this.rotate(angle); + this.translate(-pivotX, -pivotY); + } + _scale(scaleX, scaleY, pivotX, pivotY) { + this.translate(pivotX, pivotY); + this.scale(scaleX, scaleY); + this.translate(-pivotX, -pivotY); + } + _drawLine(x, y, fromX, fromY, toX, toY, lineColor, lineWidth, vid) { + this.beginPath(); + this.strokeStyle = lineColor; + this.lineWidth = lineWidth; + this.moveTo(x + fromX, y + fromY); + this.lineTo(x + toX, y + toY); + this.stroke(); + } + _drawLines(x, y, points, lineColor, lineWidth, vid) { + this.beginPath(); + this.strokeStyle = lineColor; + this.lineWidth = lineWidth; + this.addPath(points.slice(), false, false, x, y); + this.stroke(); + } + drawCurves(x, y, points, lineColor, lineWidth) { + this.beginPath(); + this.strokeStyle = lineColor; + this.lineWidth = lineWidth; + this.moveTo(x + points[0], y + points[1]); + var i = 2, n = points.length; + while (i < n) { + this.quadraticCurveTo(x + points[i++], y + points[i++], x + points[i++], y + points[i++]); + } + this.stroke(); + } + _fillAndStroke(fillColor, strokeColor, lineWidth, isConvexPolygon = false) { + if (fillColor != null) { + this.fillStyle = fillColor; + this.fill(); + } + if (strokeColor != null && lineWidth > 0) { + this.strokeStyle = strokeColor; + this.lineWidth = lineWidth; + this.stroke(); + } + } + _drawCircle(x, y, radius, fillColor, lineColor, lineWidth, vid) { + Stat.renderBatches++; + this.beginPath(true); + this.arc(x, y, radius, 0, Context.PI2); + this.closePath(); + this._fillAndStroke(fillColor, lineColor, lineWidth); + } + _drawPie(x, y, radius, startAngle, endAngle, fillColor, lineColor, lineWidth, vid) { + this.beginPath(); + this.moveTo(x, y); + this.arc(x, y, radius, startAngle, endAngle); + this.closePath(); + this._fillAndStroke(fillColor, lineColor, lineWidth); + } + _drawPoly(x, y, points, fillColor, lineColor, lineWidth, isConvexPolygon, vid) { + this.beginPath(); + this.addPath(points.slice(), true, isConvexPolygon, x, y); + this.closePath(); + this._fillAndStroke(fillColor, lineColor, lineWidth, isConvexPolygon); + } + _drawPath(x, y, paths, brush, pen) { + this.beginPath(); + for (var i = 0, n = paths.length; i < n; i++) { + var path = paths[i]; + switch (path[0]) { + case "moveTo": + this.moveTo(x + path[1], y + path[2]); + break; + case "lineTo": + this.lineTo(x + path[1], y + path[2]); + break; + case "arcTo": + this.arcTo(x + path[1], y + path[2], x + path[3], y + path[4], path[5]); + break; + case "closePath": + this.closePath(); + break; + } + } + if (brush != null) { + this.fillStyle = brush.fillStyle; + this.fill(); + } + if (pen != null) { + this.strokeStyle = pen.strokeStyle; + this.lineWidth = pen.lineWidth || 1; + this.lineJoin = pen.lineJoin; + this.lineCap = pen.lineCap; + this.miterLimit = pen.miterLimit; + this.stroke(); + } + } + static set2DRenderConfig() { + var gl = LayaGL.instance; + WebGLContext.setBlend(gl, true); + WebGLContext.setBlendEquation(gl, gl.FUNC_ADD); + BlendMode.activeBlendFunction = null; + WebGLContext.setBlendFunc(gl, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + WebGLContext.setDepthTest(gl, false); + WebGLContext.setCullFace(gl, false); + WebGLContext.setDepthMask(gl, true); + WebGLContext.setFrontFace(gl, gl.CCW); + gl.viewport(0, 0, RenderState2D.width, RenderState2D.height); + } + clearBG(r, g, b, a) { + var gl = WebGLContext.mainContext; + gl.clearColor(r, g, b, a); + gl.clear(gl.COLOR_BUFFER_BIT); + } + _getSubmits() { + return this._submits; + } + _releaseMem(keepRT = false) { + if (!this._submits) + return; + this._curMat && this._curMat.destroy(); + this._curMat = null; + this._shader2D.destroy(); + this._shader2D = null; + this._charSubmitCache.clear(); + for (var i = 0, n = this._submits._length; i < n; i++) { + this._submits[i].releaseRender(); + } + this._submits.length = 0; + this._submits._length = 0; + this._submits = null; + this._curSubmit = null; + this._path = null; + this._save = null; + var sz; + for (i = 0, sz = this.meshlist.length; i < sz; i++) { + var curm = this.meshlist[i]; + curm.destroy(); + } + this.meshlist.length = 0; + this.sprite = null; + if (!keepRT) { + this._targets && (this._targets.destroy()); + this._targets = null; + } + } + destroy(keepRT = false) { + --Context._contextcount; + this.sprite = null; + this._releaseMem(keepRT); + this._charSubmitCache && this._charSubmitCache.destroy(); + this._mesh.destroy(); + if (!keepRT) { + this._targets && this._targets.destroy(); + this._targets = null; + } + } + clear() { + if (!this._submits) { + this._other = ContextParams.DEFAULT; + this._curMat = Matrix.create(); + this._charSubmitCache = new CharSubmitCache(); + this._mesh = MeshQuadTexture.getAMesh(this.isMain); + this.meshlist.push(this._mesh); + this._pathMesh = MeshVG.getAMesh(this.isMain); + this.meshlist.push(this._pathMesh); + this._triangleMesh = MeshTexture.getAMesh(this.isMain); + this.meshlist.push(this._triangleMesh); + this._submits = []; + this._save = [SaveMark.Create(this)]; + this._save.length = 10; + this._shader2D = new Shader2D(); + } + this._submitKey.clear(); + this._mesh.clearVB(); + this._drawCount = 1; + this._other = ContextParams.DEFAULT; + this._other.lineWidth = this._shader2D.ALPHA = 1.0; + this._nBlendType = 0; + this._clipRect = Context.MAXCLIPRECT; + this._curSubmit = SubmitBase.RENDERBASE; + SubmitBase.RENDERBASE._ref = 0xFFFFFF; + SubmitBase.RENDERBASE._numEle = 0; + this._shader2D.fillStyle = this._shader2D.strokeStyle = DrawStyle.DEFAULT; + for (var i = 0, n = this._submits._length; i < n; i++) + this._submits[i].releaseRender(); + this._submits._length = 0; + this._curMat.identity(); + this._other.clear(); + this._saveMark = this._save[0]; + this._save._length = 1; + } + size(w, h) { + if (this._width != w || this._height != h) { + this._width = w; + this._height = h; + if (this._targets) { + this._targets.destroy(); + this._targets = new RenderTexture2D(w, h, exports.RenderTextureFormat.R8G8B8A8, -1); + } + if (this.isMain) { + WebGLContext.mainContext.viewport(0, 0, w, h); + RenderState2D.width = w; + RenderState2D.height = h; + } + } + if (w === 0 && h === 0) + this._releaseMem(); + } + set asBitmap(value) { + if (value) { + let rt = this._targets; + if (!this._width || !this._height) + throw Error("asBitmap no size!"); + if (!rt || rt.width != this._width || rt.height != this._height) { + if (rt) { + rt.destroy(); + } + this._targets = new RenderTexture2D(this._width, this._height, exports.RenderTextureFormat.R8G8B8A8, -1); + } + } + else { + this._targets && this._targets.destroy(); + this._targets = null; + } + } + getMatScaleX() { + if (this._lastMat_a == this._curMat.a && this._lastMat_b == this._curMat.b) + return this._lastMatScaleX; + this._lastMatScaleX = this._curMat.getScaleX(); + this._lastMat_a = this._curMat.a; + this._lastMat_b = this._curMat.b; + return this._lastMatScaleX; + } + getMatScaleY() { + if (this._lastMat_c == this._curMat.c && this._lastMat_d == this._curMat.d) + return this._lastMatScaleY; + this._lastMatScaleY = this._curMat.getScaleY(); + this._lastMat_c = this._curMat.c; + this._lastMat_d = this._curMat.d; + return this._lastMatScaleY; + } + setFillColor(color) { + this._fillColor = color; + } + getFillColor() { + return this._fillColor; + } + set fillStyle(value) { + if (!this._shader2D.fillStyle.equal(value)) { + SaveBase.save(this, SaveBase.TYPE_FILESTYLE, this._shader2D, false); + this._shader2D.fillStyle = DrawStyle.create(value); + this._submitKey.other = -this._shader2D.fillStyle.toInt(); + } + } + get fillStyle() { + return this._shader2D.fillStyle; + } + set globalAlpha(value) { + value = Math.floor(value * 1000) / 1000; + if (value != this._shader2D.ALPHA) { + SaveBase.save(this, SaveBase.TYPE_ALPHA, this._shader2D, false); + this._shader2D.ALPHA = value; + } + } + get globalAlpha() { + return this._shader2D.ALPHA; + } + set textAlign(value) { + (this._other.textAlign === value) || (this._other = this._other.make(), SaveBase.save(this, SaveBase.TYPE_TEXTALIGN, this._other, false), this._other.textAlign = value); + } + get textAlign() { + return this._other.textAlign; + } + set textBaseline(value) { + (this._other.textBaseline === value) || (this._other = this._other.make(), SaveBase.save(this, SaveBase.TYPE_TEXTBASELINE, this._other, false), this._other.textBaseline = value); + } + get textBaseline() { + return this._other.textBaseline; + } + set globalCompositeOperation(value) { + var n = BlendMode.TOINT[value]; + n == null || (this._nBlendType === n) || (SaveBase.save(this, SaveBase.TYPE_GLOBALCOMPOSITEOPERATION, this, true), this._curSubmit = SubmitBase.RENDERBASE, this._nBlendType = n); + } + get globalCompositeOperation() { + return BlendMode.NAMES[this._nBlendType]; + } + set strokeStyle(value) { + this._shader2D.strokeStyle.equal(value) || (SaveBase.save(this, SaveBase.TYPE_STROKESTYLE, this._shader2D, false), this._shader2D.strokeStyle = DrawStyle.create(value), this._submitKey.other = -this._shader2D.strokeStyle.toInt()); + } + get strokeStyle() { + return this._shader2D.strokeStyle; + } + translate(x, y) { + if (x !== 0 || y !== 0) { + SaveTranslate.save(this); + if (this._curMat._bTransform) { + SaveTransform.save(this); + this._curMat.tx += (x * this._curMat.a + y * this._curMat.c); + this._curMat.ty += (x * this._curMat.b + y * this._curMat.d); + } + else { + this._curMat.tx = x; + this._curMat.ty = y; + } + } + } + set lineWidth(value) { + (this._other.lineWidth === value) || (this._other = this._other.make(), SaveBase.save(this, SaveBase.TYPE_LINEWIDTH, this._other, false), this._other.lineWidth = value); + } + get lineWidth() { + return this._other.lineWidth; + } + save() { + this._save[this._save._length++] = SaveMark.Create(this); + } + restore() { + var sz = this._save._length; + var lastBlend = this._nBlendType; + if (sz < 1) + return; + for (var i = sz - 1; i >= 0; i--) { + var o = this._save[i]; + o.restore(this); + if (o.isSaveMark()) { + this._save._length = i; + return; + } + } + if (lastBlend != this._nBlendType) { + this._curSubmit = SubmitBase.RENDERBASE; + } + } + set font(str) { + this._other = this._other.make(); + SaveBase.save(this, SaveBase.TYPE_FONT, this._other, false); + } + fillText(txt, x, y, fontStr, color, align, lineWidth = 0, borderColor = "") { + Context._textRender.filltext(this, txt, x, y, fontStr, color, borderColor, lineWidth, align); + } + drawText(text, x, y, font, color, textAlign) { + Context._textRender.filltext(this, text, x, y, font, color, null, 0, textAlign); + } + fillWords(words, x, y, fontStr, color) { + Context._textRender.fillWords(this, words, x, y, fontStr, color, null, 0); + } + strokeWord(text, x, y, font, color, lineWidth, textAlign) { + Context._textRender.filltext(this, text, x, y, font, null, color, lineWidth, textAlign); + } + fillBorderText(txt, x, y, font, color, borderColor, lineWidth, textAlign) { + Context._textRender.filltext(this, txt, x, y, font, color, borderColor, lineWidth, textAlign); + } + fillBorderWords(words, x, y, font, color, borderColor, lineWidth) { + Context._textRender.fillWords(this, words, x, y, font, color, borderColor, lineWidth); + } + _fast_filltext(data, x, y, fontObj, color, strokeColor, lineWidth, textAlign, underLine = 0) { + Context._textRender._fast_filltext(this, data, null, x, y, fontObj, color, strokeColor, lineWidth, textAlign, underLine); + } + _fillRect(x, y, width, height, rgba) { + var submit = this._curSubmit; + var sameKey = submit && (submit._key.submitType === SubmitBase.KEY_DRAWTEXTURE && submit._key.blendShader === this._nBlendType); + if (this._mesh.vertNum + 4 > Context._MAXVERTNUM) { + this._mesh = MeshQuadTexture.getAMesh(this.isMain); + this.meshlist.push(this._mesh); + sameKey = false; + } + sameKey && (sameKey = sameKey && this.isSameClipInfo(submit)); + this.transformQuad(x, y, width, height, 0, this._curMat, this._transedPoints); + if (!this.clipedOff(this._transedPoints)) { + this._mesh.addQuad(this._transedPoints, Texture.NO_UV, rgba, false); + if (!sameKey) { + submit = this._curSubmit = SubmitTexture.create(this, this._mesh, Value2D.create(ShaderDefines2D.TEXTURE2D, 0)); + this._submits[this._submits._length++] = submit; + this._copyClipInfo(submit, this._globalClipMatrix); + submit.shaderValue.textureHost = this._lastTex; + submit._key.other = (this._lastTex && this._lastTex.bitmap) ? this._lastTex.bitmap.id : -1; + submit._renderType = SubmitBase.TYPE_TEXTURE; + } + this._curSubmit._numEle += 6; + this._mesh.indexNum += 6; + this._mesh.vertNum += 4; + } + } + fillRect(x, y, width, height, fillStyle) { + var drawstyle = fillStyle ? DrawStyle.create(fillStyle) : this._shader2D.fillStyle; + var rgba = this.mixRGBandAlpha(drawstyle.toInt()); + this._fillRect(x, y, width, height, rgba); + } + fillTexture(texture, x, y, width, height, type, offset, other) { + if (!texture._getSource()) { + this.sprite && ILaya.systemTimer.callLater(this, this._repaintSprite); + return; + } + this._fillTexture(texture, texture.width, texture.height, texture.uvrect, x, y, width, height, type, offset.x, offset.y); + } + _fillTexture(texture, texw, texh, texuvRect, x, y, width, height, type, offsetx, offsety) { + var submit = this._curSubmit; + if (this._mesh.vertNum + 4 > Context._MAXVERTNUM) { + this._mesh = MeshQuadTexture.getAMesh(this.isMain); + this.meshlist.push(this._mesh); + } + var repeatx = true; + var repeaty = true; + switch (type) { + case "repeat": break; + case "repeat-x": + repeaty = false; + break; + case "repeat-y": + repeatx = false; + break; + case "no-repeat": + repeatx = repeaty = false; + break; + } + var uv = this._temp4Points; + var stu = 0; + var stv = 0; + var stx = 0, sty = 0, edx = 0, edy = 0; + if (offsetx < 0) { + stx = x; + stu = (-offsetx % texw) / texw; + } + else { + stx = x + offsetx; + } + if (offsety < 0) { + sty = y; + stv = (-offsety % texh) / texh; + } + else { + sty = y + offsety; + } + edx = x + width; + edy = y + height; + (!repeatx) && (edx = Math.min(edx, x + offsetx + texw)); + (!repeaty) && (edy = Math.min(edy, y + offsety + texh)); + if (edx < x || edy < y) + return; + if (stx > edx || sty > edy) + return; + var edu = (edx - x - offsetx) / texw; + var edv = (edy - y - offsety) / texh; + this.transformQuad(stx, sty, edx - stx, edy - sty, 0, this._curMat, this._transedPoints); + uv[0] = stu; + uv[1] = stv; + uv[2] = edu; + uv[3] = stv; + uv[4] = edu; + uv[5] = edv; + uv[6] = stu; + uv[7] = edv; + if (!this.clipedOff(this._transedPoints)) { + var rgba = this._mixRGBandAlpha(0xffffffff, this._shader2D.ALPHA); + this._mesh.addQuad(this._transedPoints, uv, rgba, true); + var sv = Value2D.create(ShaderDefines2D.TEXTURE2D, 0); + sv.defines.add(ShaderDefines2D.FILLTEXTURE); + sv.u_TexRange = texuvRect.concat(); + submit = this._curSubmit = SubmitTexture.create(this, this._mesh, sv); + this._submits[this._submits._length++] = submit; + this._copyClipInfo(submit, this._globalClipMatrix); + submit.shaderValue.textureHost = texture; + submit._renderType = SubmitBase.TYPE_TEXTURE; + this._curSubmit._numEle += 6; + this._mesh.indexNum += 6; + this._mesh.vertNum += 4; + } + this.breakNextMerge(); + } + setColorFilter(filter) { + SaveBase.save(this, SaveBase.TYPE_COLORFILTER, this, true); + this._colorFiler = filter; + this._curSubmit = SubmitBase.RENDERBASE; + } + drawTexture(tex, x, y, width, height) { + this._drawTextureM(tex, x, y, width, height, null, 1, null); + } + drawTextures(tex, pos, tx, ty) { + if (!tex._getSource()) { + this.sprite && ILaya.systemTimer.callLater(this, this._repaintSprite); + return; + } + var n = pos.length / 2; + var ipos = 0; + var bmpid = tex.bitmap.id; + for (var i = 0; i < n; i++) { + this._inner_drawTexture(tex, bmpid, pos[ipos++] + tx, pos[ipos++] + ty, 0, 0, null, null, 1.0, false); + } + } + _drawTextureAddSubmit(imgid, tex) { + var submit = null; + submit = SubmitTexture.create(this, this._mesh, Value2D.create(ShaderDefines2D.TEXTURE2D, 0)); + this._submits[this._submits._length++] = submit; + submit.shaderValue.textureHost = tex; + submit._key.other = imgid; + submit._renderType = SubmitBase.TYPE_TEXTURE; + this._curSubmit = submit; + } + _drawTextureM(tex, x, y, width, height, m, alpha, uv) { + var cs = this.sprite; + if (!tex._getSource(function () { + if (cs) { + cs.repaint(); + } + })) { + return false; + } + return this._inner_drawTexture(tex, tex.bitmap.id, x, y, width, height, m, uv, alpha, false); + } + _drawRenderTexture(tex, x, y, width, height, m, alpha, uv) { + return this._inner_drawTexture(tex, -1, x, y, width, height, m, uv, 1.0, false); + } + submitDebugger() { + this._submits[this._submits._length++] = SubmitCMD.create([], function () { debugger; }, this); + } + _copyClipInfo(submit, clipInfo) { + var cm = submit.shaderValue.clipMatDir; + cm[0] = clipInfo.a; + cm[1] = clipInfo.b; + cm[2] = clipInfo.c; + cm[3] = clipInfo.d; + var cmp = submit.shaderValue.clipMatPos; + cmp[0] = clipInfo.tx; + cmp[1] = clipInfo.ty; + submit.clipInfoID = this._clipInfoID; + if (this._clipInCache) { + submit.shaderValue.clipOff[0] = 1; + } + } + isSameClipInfo(submit) { + return (submit.clipInfoID === this._clipInfoID); + } + _useNewTex2DSubmit(tex, minVertNum) { + if (this._mesh.vertNum + minVertNum > Context._MAXVERTNUM) { + this._mesh = MeshQuadTexture.getAMesh(this.isMain); + this.meshlist.push(this._mesh); + } + var submit = SubmitTexture.create(this, this._mesh, Value2D.create(ShaderDefines2D.TEXTURE2D, 0)); + this._submits[this._submits._length++] = this._curSubmit = submit; + submit.shaderValue.textureHost = tex; + this._copyClipInfo(submit, this._globalClipMatrix); + } + _drawTexRect(x, y, w, h, uv) { + this.transformQuad(x, y, w, h, this._italicDeg, this._curMat, this._transedPoints); + var ops = this._transedPoints; + ops[0] = (ops[0] + 0.5) | 0; + ops[1] = (ops[1] + 0.5) | 0; + ops[2] = (ops[2] + 0.5) | 0; + ops[3] = (ops[3] + 0.5) | 0; + ops[4] = (ops[4] + 0.5) | 0; + ops[5] = (ops[5] + 0.5) | 0; + ops[6] = (ops[6] + 0.5) | 0; + ops[7] = (ops[7] + 0.5) | 0; + if (!this.clipedOff(this._transedPoints)) { + this._mesh.addQuad(this._transedPoints, uv, this._fillColor, true); + this._curSubmit._numEle += 6; + this._mesh.indexNum += 6; + this._mesh.vertNum += 4; + } + } + drawCallOptimize(enable) { + this._charSubmitCache.enable(enable, this); + return enable; + } + _inner_drawTexture(tex, imgid, x, y, width, height, m, uv, alpha, lastRender) { + if (width <= 0 || height <= 0) { + return false; + } + var preKey = this._curSubmit._key; + uv = uv || tex._uv; + if (preKey.submitType === SubmitBase.KEY_TRIANGLES && preKey.other === imgid) { + var tv = this._drawTexToDrawTri_Vert; + tv[0] = x; + tv[1] = y; + tv[2] = x + width, tv[3] = y, tv[4] = x + width, tv[5] = y + height, tv[6] = x, tv[7] = y + height; + this._drawTriUseAbsMatrix = true; + var tuv = this._tempUV; + tuv[0] = uv[0]; + tuv[1] = uv[1]; + tuv[2] = uv[2]; + tuv[3] = uv[3]; + tuv[4] = uv[4]; + tuv[5] = uv[5]; + tuv[6] = uv[6]; + tuv[7] = uv[7]; + this.drawTriangles(tex, 0, 0, tv, tuv, this._drawTexToDrawTri_Index, m, alpha, null, null); + this._drawTriUseAbsMatrix = false; + return true; + } + var mesh = this._mesh; + var submit = this._curSubmit; + var ops = lastRender ? this._charSubmitCache.getPos() : this._transedPoints; + this.transformQuad(x, y, width || tex.width, height || tex.height, this._italicDeg, m || this._curMat, ops); + if (this.drawTexAlign) { + var round = Math.round; + ops[0] = round(ops[0]); + ops[1] = round(ops[1]); + ops[2] = round(ops[2]); + ops[3] = round(ops[3]); + ops[4] = round(ops[4]); + ops[5] = round(ops[5]); + ops[6] = round(ops[6]); + ops[7] = round(ops[7]); + this.drawTexAlign = false; + } + var rgba = this._mixRGBandAlpha(0xffffffff, this._shader2D.ALPHA * alpha); + if (lastRender) { + this._charSubmitCache.add(this, tex, imgid, ops, uv, rgba); + return true; + } + this._drawCount++; + var sameKey = imgid >= 0 && preKey.submitType === SubmitBase.KEY_DRAWTEXTURE && preKey.other === imgid; + sameKey && (sameKey = sameKey && this.isSameClipInfo(submit)); + this._lastTex = tex; + if (mesh.vertNum + 4 > Context._MAXVERTNUM) { + mesh = this._mesh = MeshQuadTexture.getAMesh(this.isMain); + this.meshlist.push(mesh); + sameKey = false; + } + { + mesh.addQuad(ops, uv, rgba, true); + if (!sameKey) { + this._submits[this._submits._length++] = this._curSubmit = submit = SubmitTexture.create(this, mesh, Value2D.create(ShaderDefines2D.TEXTURE2D, 0)); + submit.shaderValue.textureHost = tex; + submit._key.other = imgid; + this._copyClipInfo(submit, this._globalClipMatrix); + } + submit._numEle += 6; + mesh.indexNum += 6; + mesh.vertNum += 4; + return true; + } + } + transform4Points(a, m, out) { + var tx = m.tx; + var ty = m.ty; + var ma = m.a; + var mb = m.b; + var mc = m.c; + var md = m.d; + var a0 = a[0]; + var a1 = a[1]; + var a2 = a[2]; + var a3 = a[3]; + var a4 = a[4]; + var a5 = a[5]; + var a6 = a[6]; + var a7 = a[7]; + if (m._bTransform) { + out[0] = a0 * ma + a1 * mc + tx; + out[1] = a0 * mb + a1 * md + ty; + out[2] = a2 * ma + a3 * mc + tx; + out[3] = a2 * mb + a3 * md + ty; + out[4] = a4 * ma + a5 * mc + tx; + out[5] = a4 * mb + a5 * md + ty; + out[6] = a6 * ma + a7 * mc + tx; + out[7] = a6 * mb + a7 * md + ty; + } + else { + out[0] = a0 + tx; + out[1] = a1 + ty; + out[2] = a2 + tx; + out[3] = a3 + ty; + out[4] = a4 + tx; + out[5] = a5 + ty; + out[6] = a6 + tx; + out[7] = a7 + ty; + } + } + clipedOff(pt) { + if (this._clipRect.width <= 0 || this._clipRect.height <= 0) + return true; + return false; + } + transformQuad(x, y, w, h, italicDeg, m, out) { + var xoff = 0; + if (italicDeg != 0) { + xoff = Math.tan(italicDeg * Math.PI / 180) * h; + } + var maxx = x + w; + var maxy = y + h; + var tx = m.tx; + var ty = m.ty; + var ma = m.a; + var mb = m.b; + var mc = m.c; + var md = m.d; + var a0 = x + xoff; + var a1 = y; + var a2 = maxx + xoff; + var a3 = y; + var a4 = maxx; + var a5 = maxy; + var a6 = x; + var a7 = maxy; + if (m._bTransform) { + out[0] = a0 * ma + a1 * mc + tx; + out[1] = a0 * mb + a1 * md + ty; + out[2] = a2 * ma + a3 * mc + tx; + out[3] = a2 * mb + a3 * md + ty; + out[4] = a4 * ma + a5 * mc + tx; + out[5] = a4 * mb + a5 * md + ty; + out[6] = a6 * ma + a7 * mc + tx; + out[7] = a6 * mb + a7 * md + ty; + } + else { + out[0] = a0 + tx; + out[1] = a1 + ty; + out[2] = a2 + tx; + out[3] = a3 + ty; + out[4] = a4 + tx; + out[5] = a5 + ty; + out[6] = a6 + tx; + out[7] = a7 + ty; + } + } + pushRT() { + this.addRenderObject(SubmitCMD.create(null, RenderTexture2D.pushRT, this)); + } + popRT() { + this.addRenderObject(SubmitCMD.create(null, RenderTexture2D.popRT, this)); + this.breakNextMerge(); + } + useRT(rt) { + function _use(rt) { + if (!rt) { + throw 'error useRT'; + } + else { + rt.start(); + rt.clear(0, 0, 0, 0); + } + } + this.addRenderObject(SubmitCMD.create([rt], _use, this)); + this.breakNextMerge(); + } + RTRestore(rt) { + function _restore(rt) { + rt.restore(); + } + this.addRenderObject(SubmitCMD.create([rt], _restore, this)); + this.breakNextMerge(); + } + breakNextMerge() { + this._curSubmit = SubmitBase.RENDERBASE; + } + _repaintSprite() { + this.sprite && this.sprite.repaint(); + } + drawTextureWithTransform(tex, x, y, width, height, transform, tx, ty, alpha, blendMode, colorfilter = null, uv) { + var oldcomp; + var curMat = this._curMat; + if (blendMode) { + oldcomp = this.globalCompositeOperation; + this.globalCompositeOperation = blendMode; + } + var oldColorFilter = this._colorFiler; + if (colorfilter) { + this.setColorFilter(colorfilter); + } + if (!transform) { + this._drawTextureM(tex, x + tx, y + ty, width, height, curMat, alpha, uv); + if (blendMode) { + this.globalCompositeOperation = oldcomp; + } + if (colorfilter) { + this.setColorFilter(oldColorFilter); + } + return; + } + var tmpMat = this._tmpMatrix; + tmpMat.a = transform.a; + tmpMat.b = transform.b; + tmpMat.c = transform.c; + tmpMat.d = transform.d; + tmpMat.tx = transform.tx + tx; + tmpMat.ty = transform.ty + ty; + tmpMat._bTransform = transform._bTransform; + if (transform && curMat._bTransform) { + Matrix.mul(tmpMat, curMat, tmpMat); + transform = tmpMat; + transform._bTransform = true; + } + else { + tmpMat.tx += curMat.tx; + tmpMat.ty += curMat.ty; + transform = tmpMat; + } + this._drawTextureM(tex, x, y, width, height, transform, alpha, uv); + if (blendMode) { + this.globalCompositeOperation = oldcomp; + } + if (colorfilter) { + this.setColorFilter(oldColorFilter); + } + } + _flushToTarget(context, target) { + RenderState2D.worldScissorTest = false; + var gl = LayaGL.instance; + gl.disable(gl.SCISSOR_TEST); + var preAlpha = RenderState2D.worldAlpha; + var preMatrix4 = RenderState2D.worldMatrix4; + var preMatrix = RenderState2D.worldMatrix; + RenderState2D.worldMatrix = Matrix.EMPTY; + RenderState2D.restoreTempArray(); + RenderState2D.worldMatrix4 = RenderState2D.TEMPMAT4_ARRAY; + RenderState2D.worldAlpha = 1; + BaseShader.activeShader = null; + target.start(); + if (context._submits._length > 0) + target.clear(0, 0, 0, 0); + context._curSubmit = SubmitBase.RENDERBASE; + context.flush(); + context.clear(); + target.restore(); + context._curSubmit = SubmitBase.RENDERBASE; + BaseShader.activeShader = null; + RenderState2D.worldAlpha = preAlpha; + RenderState2D.worldMatrix4 = preMatrix4; + RenderState2D.worldMatrix = preMatrix; + } + drawCanvas(canvas, x, y, width, height) { + if (!canvas) + return; + var src = canvas.context; + var submit; + if (src._targets) { + if (src._submits._length > 0) { + submit = SubmitCMD.create([src, src._targets], this._flushToTarget, this); + this._submits[this._submits._length++] = submit; + } + this._drawRenderTexture(src._targets, x, y, width, height, null, 1.0, RenderTexture2D.flipyuv); + this._curSubmit = SubmitBase.RENDERBASE; + } + else { + var canv = canvas; + if (canv.touches) { + canv.touches.forEach(function (v) { v.touch(); }); + } + submit = SubmitCanvas.create(canvas, this._shader2D.ALPHA, this._shader2D.filters); + this._submits[this._submits._length++] = submit; + submit._key.clear(); + var mat = submit._matrix; + this._curMat.copyTo(mat); + var tx = mat.tx, ty = mat.ty; + mat.tx = mat.ty = 0; + mat.transformPoint(Point.TEMP.setTo(x, y)); + mat.translate(Point.TEMP.x + tx, Point.TEMP.y + ty); + Matrix.mul(canv.invMat, mat, mat); + this._curSubmit = SubmitBase.RENDERBASE; + } + } + drawTarget(rt, x, y, width, height, m, shaderValue, uv = null, blend = -1) { + this._drawCount++; + if (this._mesh.vertNum + 4 > Context._MAXVERTNUM) { + this._mesh = MeshQuadTexture.getAMesh(this.isMain); + this.meshlist.push(this._mesh); + } + this.transformQuad(x, y, width, height, 0, m || this._curMat, this._transedPoints); + if (!this.clipedOff(this._transedPoints)) { + this._mesh.addQuad(this._transedPoints, uv || Texture.DEF_UV, 0xffffffff, true); + var submit = this._curSubmit = SubmitTarget.create(this, this._mesh, shaderValue, rt); + submit.blendType = (blend == -1) ? this._nBlendType : blend; + this._copyClipInfo(submit, this._globalClipMatrix); + submit._numEle = 6; + this._mesh.indexNum += 6; + this._mesh.vertNum += 4; + this._submits[this._submits._length++] = submit; + this._curSubmit = SubmitBase.RENDERBASE; + return true; + } + this._curSubmit = SubmitBase.RENDERBASE; + return false; + } + drawTriangles(tex, x, y, vertices, uvs, indices, matrix, alpha, color, blendMode, colorNum = 0xffffffff) { + if (!tex._getSource()) { + if (this.sprite) { + ILaya.systemTimer.callLater(this, this._repaintSprite); + } + return; + } + var oldcomp = null; + if (blendMode) { + oldcomp = this.globalCompositeOperation; + this.globalCompositeOperation = blendMode; + } + this._drawCount++; + var tmpMat = this._tmpMatrix; + var triMesh = this._triangleMesh; + var oldColorFilter = null; + var needRestorFilter = false; + if (color) { + oldColorFilter = this._colorFiler; + this._colorFiler = color; + this._curSubmit = SubmitBase.RENDERBASE; + needRestorFilter = oldColorFilter != color; + } + var webGLImg = tex.bitmap; + var preKey = this._curSubmit._key; + var sameKey = preKey.submitType === SubmitBase.KEY_TRIANGLES && preKey.other === webGLImg.id && preKey.blendShader == this._nBlendType; + if (triMesh.vertNum + vertices.length / 2 > Context._MAXVERTNUM) { + triMesh = this._triangleMesh = MeshTexture.getAMesh(this.isMain); + this.meshlist.push(triMesh); + sameKey = false; + } + if (!sameKey) { + var submit = this._curSubmit = SubmitTexture.create(this, triMesh, Value2D.create(ShaderDefines2D.TEXTURE2D, 0)); + submit.shaderValue.textureHost = tex; + submit._renderType = SubmitBase.TYPE_TEXTURE; + submit._key.submitType = SubmitBase.KEY_TRIANGLES; + submit._key.other = webGLImg.id; + this._copyClipInfo(submit, this._globalClipMatrix); + this._submits[this._submits._length++] = submit; + } + var rgba = this._mixRGBandAlpha(colorNum, this._shader2D.ALPHA * alpha); + if (!this._drawTriUseAbsMatrix) { + if (!matrix) { + tmpMat.a = 1; + tmpMat.b = 0; + tmpMat.c = 0; + tmpMat.d = 1; + tmpMat.tx = x; + tmpMat.ty = y; + } + else { + tmpMat.a = matrix.a; + tmpMat.b = matrix.b; + tmpMat.c = matrix.c; + tmpMat.d = matrix.d; + tmpMat.tx = matrix.tx + x; + tmpMat.ty = matrix.ty + y; + } + Matrix.mul(tmpMat, this._curMat, tmpMat); + triMesh.addData(vertices, uvs, indices, tmpMat || this._curMat, rgba); + } + else { + triMesh.addData(vertices, uvs, indices, matrix, rgba); + } + this._curSubmit._numEle += indices.length; + if (needRestorFilter) { + this._colorFiler = oldColorFilter; + this._curSubmit = SubmitBase.RENDERBASE; + } + if (blendMode) { + this.globalCompositeOperation = oldcomp; + } + } + transform(a, b, c, d, tx, ty) { + SaveTransform.save(this); + Matrix.mul(Matrix.TEMP.setTo(a, b, c, d, tx, ty), this._curMat, this._curMat); + this._curMat._checkTransform(); + } + _transformByMatrix(matrix, tx, ty) { + matrix.setTranslate(tx, ty); + Matrix.mul(matrix, this._curMat, this._curMat); + matrix.setTranslate(0, 0); + this._curMat._bTransform = true; + } + setTransformByMatrix(value) { + value.copyTo(this._curMat); + } + rotate(angle) { + SaveTransform.save(this); + this._curMat.rotateEx(angle); + } + scale(scaleX, scaleY) { + SaveTransform.save(this); + this._curMat.scaleEx(scaleX, scaleY); + } + clipRect(x, y, width, height) { + SaveClipRect.save(this); + if (this._clipRect == Context.MAXCLIPRECT) { + this._clipRect = new Rectangle(x, y, width, height); + } + else { + this._clipRect.width = width; + this._clipRect.height = height; + this._clipRect.x = x; + this._clipRect.y = y; + } + this._clipID_Gen++; + this._clipID_Gen %= 10000; + this._clipInfoID = this._clipID_Gen; + var cm = this._globalClipMatrix; + var minx = cm.tx; + var miny = cm.ty; + var maxx = minx + cm.a; + var maxy = miny + cm.d; + if (this._clipRect.width >= Context._MAXSIZE) { + cm.a = cm.d = Context._MAXSIZE; + cm.b = cm.c = cm.tx = cm.ty = 0; + } + else { + if (this._curMat._bTransform) { + cm.tx = this._clipRect.x * this._curMat.a + this._clipRect.y * this._curMat.c + this._curMat.tx; + cm.ty = this._clipRect.x * this._curMat.b + this._clipRect.y * this._curMat.d + this._curMat.ty; + cm.a = this._clipRect.width * this._curMat.a; + cm.b = this._clipRect.width * this._curMat.b; + cm.c = this._clipRect.height * this._curMat.c; + cm.d = this._clipRect.height * this._curMat.d; + } + else { + cm.tx = this._clipRect.x + this._curMat.tx; + cm.ty = this._clipRect.y + this._curMat.ty; + cm.a = this._clipRect.width; + cm.b = cm.c = 0; + cm.d = this._clipRect.height; + } + if (this._incache) { + this._clipInCache = true; + } + } + if (cm.a > 0 && cm.d > 0) { + var cmaxx = cm.tx + cm.a; + var cmaxy = cm.ty + cm.d; + if (cmaxx <= minx || cmaxy <= miny || cm.tx >= maxx || cm.ty >= maxy) { + cm.a = -0.1; + cm.d = -0.1; + } + else { + if (cm.tx < minx) { + cm.a -= (minx - cm.tx); + cm.tx = minx; + } + if (cmaxx > maxx) { + cm.a -= (cmaxx - maxx); + } + if (cm.ty < miny) { + cm.d -= (miny - cm.ty); + cm.ty = miny; + } + if (cmaxy > maxy) { + cm.d -= (cmaxy - maxy); + } + if (cm.a <= 0) + cm.a = -0.1; + if (cm.d <= 0) + cm.d = -0.1; + } + } + } + drawMesh(x, y, ib, vb, numElement, mat, shader, shaderValues, startIndex = 0) { + } + addRenderObject(o) { + this._submits[this._submits._length++] = o; + } + submitElement(start, end) { + var mainCtx = this.isMain; + var renderList = this._submits; + var ret = renderList._length; + end < 0 && (end = renderList._length); + var submit = SubmitBase.RENDERBASE; + while (start < end) { + this._renderNextSubmitIndex = start + 1; + if (renderList[start] === SubmitBase.RENDERBASE) { + start++; + continue; + } + SubmitBase.preRender = submit; + submit = renderList[start]; + start += submit.renderSubmit(); + } + return ret; + } + flush() { + this._clipID_Gen = 0; + var ret = this.submitElement(0, this._submits._length); + this._path && this._path.reset(); + SkinMeshBuffer.instance && SkinMeshBuffer.getInstance().reset(); + this._curSubmit = SubmitBase.RENDERBASE; + for (var i = 0, sz = this.meshlist.length; i < sz; i++) { + var curm = this.meshlist[i]; + curm.canReuse ? (curm.releaseMesh()) : (curm.destroy()); + } + this.meshlist.length = 0; + this._mesh = MeshQuadTexture.getAMesh(this.isMain); + this._pathMesh = MeshVG.getAMesh(this.isMain); + this._triangleMesh = MeshTexture.getAMesh(this.isMain); + this.meshlist.push(this._mesh, this._pathMesh, this._triangleMesh); + this._flushCnt++; + if (this._flushCnt % 60 == 0 && this.isMain) { + if (TextRender.textRenderInst) { + TextRender.textRenderInst.GC(); + } + } + return ret; + } + beginPath(convex = false) { + var tPath = this._getPath(); + tPath.beginPath(convex); + } + closePath() { + this._path.closePath(); + } + addPath(points, close, convex, dx, dy) { + var ci = 0; + for (var i = 0, sz = points.length / 2; i < sz; i++) { + var x1 = points[ci] + dx, y1 = points[ci + 1] + dy; + points[ci] = x1; + points[ci + 1] = y1; + ci += 2; + } + this._getPath().push(points, convex); + } + fill() { + var m = this._curMat; + var tPath = this._getPath(); + var submit = this._curSubmit; + var sameKey = (submit._key.submitType === SubmitBase.KEY_VG && submit._key.blendShader === this._nBlendType); + sameKey && (sameKey = sameKey && this.isSameClipInfo(submit)); + if (!sameKey) { + this._curSubmit = this.addVGSubmit(this._pathMesh); + } + var rgba = this.mixRGBandAlpha(this.fillStyle.toInt()); + var curEleNum = 0; + var idx; + for (var i = 0, sz = tPath.paths.length; i < sz; i++) { + var p = tPath.paths[i]; + var vertNum = p.path.length / 2; + if (vertNum < 3 || (vertNum == 3 && !p.convex)) + continue; + var cpath = p.path.concat(); + var pi = 0; + var xp, yp; + var _x, _y; + if (m._bTransform) { + for (pi = 0; pi < vertNum; pi++) { + xp = pi << 1; + yp = xp + 1; + _x = cpath[xp]; + _y = cpath[yp]; + cpath[xp] = m.a * _x + m.c * _y + m.tx; + cpath[yp] = m.b * _x + m.d * _y + m.ty; + } + } + else { + for (pi = 0; pi < vertNum; pi++) { + xp = pi << 1; + yp = xp + 1; + _x = cpath[xp]; + _y = cpath[yp]; + cpath[xp] = _x + m.tx; + cpath[yp] = _y + m.ty; + } + } + if (this._pathMesh.vertNum + vertNum > Context._MAXVERTNUM) { + this._curSubmit._numEle += curEleNum; + curEleNum = 0; + this._pathMesh = MeshVG.getAMesh(this.isMain); + this._curSubmit = this.addVGSubmit(this._pathMesh); + } + var curvert = this._pathMesh.vertNum; + if (p.convex) { + var faceNum = vertNum - 2; + idx = new Array(faceNum * 3); + var idxpos = 0; + for (var fi = 0; fi < faceNum; fi++) { + idx[idxpos++] = curvert; + idx[idxpos++] = fi + 1 + curvert; + idx[idxpos++] = fi + 2 + curvert; + } + } + else { + idx = Earcut.earcut(cpath, null, 2); + if (curvert > 0) { + for (var ii = 0; ii < idx.length; ii++) { + idx[ii] += curvert; + } + } + } + this._pathMesh.addVertAndIBToMesh(this, cpath, rgba, idx); + curEleNum += idx.length; + } + this._curSubmit._numEle += curEleNum; + } + addVGSubmit(mesh) { + var submit = Submit.createShape(this, mesh, 0, Value2D.create(ShaderDefines2D.PRIMITIVE, 0)); + submit._key.submitType = SubmitBase.KEY_VG; + this._submits[this._submits._length++] = submit; + this._copyClipInfo(submit, this._globalClipMatrix); + return submit; + } + stroke() { + if (this.lineWidth > 0) { + var rgba = this.mixRGBandAlpha(this.strokeStyle._color.numColor); + var tPath = this._getPath(); + var submit = this._curSubmit; + var sameKey = (submit._key.submitType === SubmitBase.KEY_VG && submit._key.blendShader === this._nBlendType); + sameKey && (sameKey = sameKey && this.isSameClipInfo(submit)); + if (!sameKey) { + this._curSubmit = this.addVGSubmit(this._pathMesh); + } + var curEleNum = 0; + for (var i = 0, sz = tPath.paths.length; i < sz; i++) { + var p = tPath.paths[i]; + if (p.path.length <= 0) + continue; + var idx = []; + var vertex = []; + var maxVertexNum = p.path.length * 2; + if (maxVertexNum < 2) + continue; + if (this._pathMesh.vertNum + maxVertexNum > Context._MAXVERTNUM) { + this._curSubmit._numEle += curEleNum; + curEleNum = 0; + this._pathMesh = MeshVG.getAMesh(this.isMain); + this.meshlist.push(this._pathMesh); + this._curSubmit = this.addVGSubmit(this._pathMesh); + } + BasePoly.createLine2(p.path, idx, this.lineWidth, this._pathMesh.vertNum, vertex, p.loop); + var ptnum = vertex.length / 2; + var m = this._curMat; + var pi = 0; + var xp, yp; + var _x, _y; + if (m._bTransform) { + for (pi = 0; pi < ptnum; pi++) { + xp = pi << 1; + yp = xp + 1; + _x = vertex[xp]; + _y = vertex[yp]; + vertex[xp] = m.a * _x + m.c * _y + m.tx; + vertex[yp] = m.b * _x + m.d * _y + m.ty; + } + } + else { + for (pi = 0; pi < ptnum; pi++) { + xp = pi << 1; + yp = xp + 1; + _x = vertex[xp]; + _y = vertex[yp]; + vertex[xp] = _x + m.tx; + vertex[yp] = _y + m.ty; + } + } + this._pathMesh.addVertAndIBToMesh(this, vertex, rgba, idx); + curEleNum += idx.length; + } + this._curSubmit._numEle += curEleNum; + } + } + moveTo(x, y) { + var tPath = this._getPath(); + tPath.newPath(); + tPath._lastOriX = x; + tPath._lastOriY = y; + tPath.addPoint(x, y); + } + lineTo(x, y) { + var tPath = this._getPath(); + if (Math.abs(x - tPath._lastOriX) < 1e-3 && Math.abs(y - tPath._lastOriY) < 1e-3) + return; + tPath._lastOriX = x; + tPath._lastOriY = y; + tPath.addPoint(x, y); + } + arcTo(x1, y1, x2, y2, r) { + var i = 0; + var x = 0, y = 0; + var dx = this._path._lastOriX - x1; + var dy = this._path._lastOriY - y1; + var len1 = Math.sqrt(dx * dx + dy * dy); + if (len1 <= 0.000001) { + return; + } + var ndx = dx / len1; + var ndy = dy / len1; + var dx2 = x2 - x1; + var dy2 = y2 - y1; + var len22 = dx2 * dx2 + dy2 * dy2; + var len2 = Math.sqrt(len22); + if (len2 <= 0.000001) { + return; + } + var ndx2 = dx2 / len2; + var ndy2 = dy2 / len2; + var odx = ndx + ndx2; + var ody = ndy + ndy2; + var olen = Math.sqrt(odx * odx + ody * ody); + if (olen <= 0.000001) { + return; + } + var nOdx = odx / olen; + var nOdy = ody / olen; + var alpha = Math.acos(nOdx * ndx + nOdy * ndy); + var halfAng = Math.PI / 2 - alpha; + len1 = r / Math.tan(halfAng); + var ptx1 = len1 * ndx + x1; + var pty1 = len1 * ndy + y1; + var orilen = Math.sqrt(len1 * len1 + r * r); + var orix = x1 + nOdx * orilen; + var oriy = y1 + nOdy * orilen; + var dir = ndx * ndy2 - ndy * ndx2; + var fChgAng = 0; + var sinx = 0.0; + var cosx = 0.0; + if (dir >= 0) { + fChgAng = halfAng * 2; + var fda = fChgAng / Context.SEGNUM; + sinx = Math.sin(fda); + cosx = Math.cos(fda); + } + else { + fChgAng = -halfAng * 2; + fda = fChgAng / Context.SEGNUM; + sinx = Math.sin(fda); + cosx = Math.cos(fda); + } + var lastx = this._path._lastOriX, lasty = this._path._lastOriY; + var _x1 = ptx1, _y1 = pty1; + if (Math.abs(_x1 - this._path._lastOriX) > 0.1 || Math.abs(_y1 - this._path._lastOriY) > 0.1) { + x = _x1; + y = _y1; + lastx = _x1; + lasty = _y1; + this._path._lastOriX = x; + this._path._lastOriY = y; + this._path.addPoint(x, y); + } + var cvx = ptx1 - orix; + var cvy = pty1 - oriy; + for (i = 0; i < Context.SEGNUM; i++) { + var cx = cvx * cosx + cvy * sinx; + var cy = -cvx * sinx + cvy * cosx; + x = cx + orix; + y = cy + oriy; + if (Math.abs(lastx - x) > 0.1 || Math.abs(lasty - y) > 0.1) { + this._path._lastOriX = x; + this._path._lastOriY = y; + this._path.addPoint(x, y); + lastx = x; + lasty = y; + } + cvx = cx; + cvy = cy; + } + } + arc(cx, cy, r, startAngle, endAngle, counterclockwise = false, b = true) { + var a = 0, da = 0; + var dx = 0, dy = 0, x = 0, y = 0; + var i, ndivs; + da = endAngle - startAngle; + if (!counterclockwise) { + if (Math.abs(da) >= Math.PI * 2) { + da = Math.PI * 2; + } + else { + while (da < 0.0) { + da += Math.PI * 2; + } + } + } + else { + if (Math.abs(da) >= Math.PI * 2) { + da = -Math.PI * 2; + } + else { + while (da > 0.0) { + da -= Math.PI * 2; + } + } + } + var sx = this.getMatScaleX(); + var sy = this.getMatScaleY(); + var sr = r * (sx > sy ? sx : sy); + var cl = 2 * Math.PI * sr; + ndivs = (Math.max(cl / 10, 10)) | 0; + var tPath = this._getPath(); + for (i = 0; i <= ndivs; i++) { + a = startAngle + da * (i / ndivs); + dx = Math.cos(a); + dy = Math.sin(a); + x = cx + dx * r; + y = cy + dy * r; + if (x != this._path._lastOriX || y != this._path._lastOriY) { + tPath.addPoint(x, y); + } + } + dx = Math.cos(endAngle); + dy = Math.sin(endAngle); + x = cx + dx * r; + y = cy + dy * r; + if (x != this._path._lastOriX || y != this._path._lastOriY) { + tPath.addPoint(x, y); + } + } + quadraticCurveTo(cpx, cpy, x, y) { + var tBezier = Bezier.I; + var tArray = tBezier.getBezierPoints([this._path._lastOriX, this._path._lastOriY, cpx, cpy, x, y], 30, 2); + for (var i = 0, n = tArray.length / 2; i < n; i++) { + this.lineTo(tArray[i * 2], tArray[i * 2 + 1]); + } + this.lineTo(x, y); + } + mixRGBandAlpha(color) { + return this._mixRGBandAlpha(color, this._shader2D.ALPHA); + } + _mixRGBandAlpha(color, alpha) { + if (alpha >= 1) { + return color; + } + var a = ((color & 0xff000000) >>> 24); + if (a != 0) { + a *= alpha; + } + else { + a = alpha * 255; + } + return (color & 0x00ffffff) | (a << 24); + } + strokeRect(x, y, width, height, parameterLineWidth) { + if (this.lineWidth > 0) { + var rgba = this.mixRGBandAlpha(this.strokeStyle._color.numColor); + var hw = this.lineWidth / 2; + this._fillRect(x - hw, y - hw, width + this.lineWidth, this.lineWidth, rgba); + this._fillRect(x - hw, y - hw + height, width + this.lineWidth, this.lineWidth, rgba); + this._fillRect(x - hw, y + hw, this.lineWidth, height - this.lineWidth, rgba); + this._fillRect(x - hw + width, y + hw, this.lineWidth, height - this.lineWidth, rgba); + } + } + clip() { + } + drawParticle(x, y, pt) { + pt.x = x; + pt.y = y; + this._submits[this._submits._length++] = pt; + } + _getPath() { + return this._path || (this._path = new Path()); + } + get canvas() { + return this._canvas; + } + _fillTexture_h(tex, imgid, uv, oriw, orih, x, y, w) { + if (oriw <= 0) + console.error('_fillTexture_h error: oriw must>0'); + var stx = x; + var num = Math.floor(w / oriw); + var left = w % oriw; + for (var i = 0; i < num; i++) { + this._inner_drawTexture(tex, imgid, stx, y, oriw, orih, this._curMat, uv, 1, false); + stx += oriw; + } + if (left > 0) { + var du = uv[2] - uv[0]; + var uvr = uv[0] + du * (left / oriw); + var tuv = Context.tmpuv1; + tuv[0] = uv[0]; + tuv[1] = uv[1]; + tuv[2] = uvr; + tuv[3] = uv[3]; + tuv[4] = uvr; + tuv[5] = uv[5]; + tuv[6] = uv[6]; + tuv[7] = uv[7]; + this._inner_drawTexture(tex, imgid, stx, y, left, orih, this._curMat, tuv, 1, false); + } + } + _fillTexture_v(tex, imgid, uv, oriw, orih, x, y, h) { + if (orih <= 0) + console.error('_fillTexture_v error: orih must>0'); + var sty = y; + var num = Math.floor(h / orih); + var left = h % orih; + for (var i = 0; i < num; i++) { + this._inner_drawTexture(tex, imgid, x, sty, oriw, orih, this._curMat, uv, 1, false); + sty += orih; + } + if (left > 0) { + var dv = uv[7] - uv[1]; + var uvb = uv[1] + dv * (left / orih); + var tuv = Context.tmpuv1; + tuv[0] = uv[0]; + tuv[1] = uv[1]; + tuv[2] = uv[2]; + tuv[3] = uv[3]; + tuv[4] = uv[4]; + tuv[5] = uvb; + tuv[6] = uv[6]; + tuv[7] = uvb; + this._inner_drawTexture(tex, imgid, x, sty, oriw, left, this._curMat, tuv, 1, false); + } + } + drawTextureWithSizeGrid(tex, tx, ty, width, height, sizeGrid, gx, gy) { + if (!tex._getSource()) + return; + tx += gx; + ty += gy; + var uv = tex.uv, w = tex.bitmap.width, h = tex.bitmap.height; + var top = sizeGrid[0]; + var left = sizeGrid[3]; + var right = sizeGrid[1]; + var bottom = sizeGrid[2]; + var repeat = sizeGrid[4]; + var needClip = false; + if (width == w) { + left = right = 0; + } + if (height == h) { + top = bottom = 0; + } + var d_top = top / h; + var d_left = left / w; + var d_right = right / w; + var d_bottom = bottom / h; + if (left + right > width) { + var clipWidth = width; + needClip = true; + width = left + right; + this.save(); + this.clipRect(0 + tx, 0 + ty, clipWidth, height); + } + var imgid = tex.bitmap.id; + var mat = this._curMat; + var tuv = this._tempUV; + var uvl = uv[0]; + var uvt = uv[1]; + var uvr = uv[4]; + var uvb = uv[5]; + var uvl_ = uvl; + var uvt_ = uvt; + var uvr_ = uvr; + var uvb_ = uvb; + if (left && top) { + uvr_ = uvl + d_left; + uvb_ = uvt + d_top; + tuv[0] = uvl, tuv[1] = uvt, tuv[2] = uvr_, tuv[3] = uvt, + tuv[4] = uvr_, tuv[5] = uvb_, tuv[6] = uvl, tuv[7] = uvb_; + this._inner_drawTexture(tex, imgid, tx, ty, left, top, mat, tuv, 1, false); + } + if (right && top) { + uvl_ = uvr - d_right; + uvt_ = uvt; + uvr_ = uvr; + uvb_ = uvt + d_top; + tuv[0] = uvl_, tuv[1] = uvt_, tuv[2] = uvr_, tuv[3] = uvt_, + tuv[4] = uvr_, tuv[5] = uvb_, tuv[6] = uvl_, tuv[7] = uvb_; + this._inner_drawTexture(tex, imgid, width - right + tx, 0 + ty, right, top, mat, tuv, 1, false); + } + if (left && bottom) { + uvl_ = uvl; + uvt_ = uvb - d_bottom; + uvr_ = uvl + d_left; + uvb_ = uvb; + tuv[0] = uvl_, tuv[1] = uvt_, tuv[2] = uvr_, tuv[3] = uvt_, + tuv[4] = uvr_, tuv[5] = uvb_, tuv[6] = uvl_, tuv[7] = uvb_; + this._inner_drawTexture(tex, imgid, 0 + tx, height - bottom + ty, left, bottom, mat, tuv, 1, false); + } + if (right && bottom) { + uvl_ = uvr - d_right; + uvt_ = uvb - d_bottom; + uvr_ = uvr; + uvb_ = uvb; + tuv[0] = uvl_, tuv[1] = uvt_, tuv[2] = uvr_, tuv[3] = uvt_, + tuv[4] = uvr_, tuv[5] = uvb_, tuv[6] = uvl_, tuv[7] = uvb_; + this._inner_drawTexture(tex, imgid, width - right + tx, height - bottom + ty, right, bottom, mat, tuv, 1, false); + } + if (top) { + uvl_ = uvl + d_left; + uvt_ = uvt; + uvr_ = uvr - d_right; + uvb_ = uvt + d_top; + tuv[0] = uvl_, tuv[1] = uvt_, tuv[2] = uvr_, tuv[3] = uvt_, + tuv[4] = uvr_, tuv[5] = uvb_, tuv[6] = uvl_, tuv[7] = uvb_; + if (repeat) { + this._fillTexture_h(tex, imgid, tuv, tex.width - left - right, top, left + tx, ty, width - left - right); + } + else { + this._inner_drawTexture(tex, imgid, left + tx, ty, width - left - right, top, mat, tuv, 1, false); + } + } + if (bottom) { + uvl_ = uvl + d_left; + uvt_ = uvb - d_bottom; + uvr_ = uvr - d_right; + uvb_ = uvb; + tuv[0] = uvl_, tuv[1] = uvt_, tuv[2] = uvr_, tuv[3] = uvt_, + tuv[4] = uvr_, tuv[5] = uvb_, tuv[6] = uvl_, tuv[7] = uvb_; + if (repeat) { + this._fillTexture_h(tex, imgid, tuv, tex.width - left - right, bottom, left + tx, height - bottom + ty, width - left - right); + } + else { + this._inner_drawTexture(tex, imgid, left + tx, height - bottom + ty, width - left - right, bottom, mat, tuv, 1, false); + } + } + if (left) { + uvl_ = uvl; + uvt_ = uvt + d_top; + uvr_ = uvl + d_left; + uvb_ = uvb - d_bottom; + tuv[0] = uvl_, tuv[1] = uvt_, tuv[2] = uvr_, tuv[3] = uvt_, + tuv[4] = uvr_, tuv[5] = uvb_, tuv[6] = uvl_, tuv[7] = uvb_; + if (repeat) { + this._fillTexture_v(tex, imgid, tuv, left, tex.height - top - bottom, tx, top + ty, height - top - bottom); + } + else { + this._inner_drawTexture(tex, imgid, tx, top + ty, left, height - top - bottom, mat, tuv, 1, false); + } + } + if (right) { + uvl_ = uvr - d_right; + uvt_ = uvt + d_top; + uvr_ = uvr; + uvb_ = uvb - d_bottom; + tuv[0] = uvl_, tuv[1] = uvt_, tuv[2] = uvr_, tuv[3] = uvt_, + tuv[4] = uvr_, tuv[5] = uvb_, tuv[6] = uvl_, tuv[7] = uvb_; + if (repeat) { + this._fillTexture_v(tex, imgid, tuv, right, tex.height - top - bottom, width - right + tx, top + ty, height - top - bottom); + } + else { + this._inner_drawTexture(tex, imgid, width - right + tx, top + ty, right, height - top - bottom, mat, tuv, 1, false); + } + } + uvl_ = uvl + d_left; + uvt_ = uvt + d_top; + uvr_ = uvr - d_right; + uvb_ = uvb - d_bottom; + tuv[0] = uvl_, tuv[1] = uvt_, tuv[2] = uvr_, tuv[3] = uvt_, + tuv[4] = uvr_, tuv[5] = uvb_, tuv[6] = uvl_, tuv[7] = uvb_; + if (repeat) { + var tuvr = Context.tmpUVRect; + tuvr[0] = uvl_; + tuvr[1] = uvt_; + tuvr[2] = uvr_ - uvl_; + tuvr[3] = uvb_ - uvt_; + this._fillTexture(tex, tex.width - left - right, tex.height - top - bottom, tuvr, left + tx, top + ty, width - left - right, height - top - bottom, 'repeat', 0, 0); + } + else { + this._inner_drawTexture(tex, imgid, left + tx, top + ty, width - left - right, height - top - bottom, mat, tuv, 1, false); + } + if (needClip) + this.restore(); + } + } + Context.ENUM_TEXTALIGN_DEFAULT = 0; + Context.ENUM_TEXTALIGN_CENTER = 1; + Context.ENUM_TEXTALIGN_RIGHT = 2; + Context._SUBMITVBSIZE = 32000; + Context._MAXSIZE = 99999999; + Context._MAXVERTNUM = 65535; + Context.MAXCLIPRECT = null; + Context._COUNT = 0; + Context.SEGNUM = 32; + Context._contextcount = 0; + Context.PI2 = 2 * Math.PI; + Context._textRender = null; + Context.tmpuv1 = [0, 0, 0, 0, 0, 0, 0, 0]; + Context.tmpUV = [0, 0, 0, 0, 0, 0, 0, 0]; + Context.tmpUVRect = [0, 0, 0, 0]; + class ContextParams { + constructor() { + this.lineWidth = 1; + } + clear() { + this.lineWidth = 1; + this.textAlign = this.textBaseline = null; + } + make() { + return this === ContextParams.DEFAULT ? new ContextParams() : this; + } + } + + class WebGL { + static _uint8ArraySlice() { + var _this = this; + var sz = _this.length; + var dec = new Uint8Array(_this.length); + for (var i = 0; i < sz; i++) + dec[i] = _this[i]; + return dec; + } + static _float32ArraySlice() { + var _this = this; + var sz = _this.length; + var dec = new Float32Array(_this.length); + for (var i = 0; i < sz; i++) + dec[i] = _this[i]; + return dec; + } + static _uint16ArraySlice(...arg) { + var _this = this; + var sz; + var dec; + var i; + if (arg.length === 0) { + sz = _this.length; + dec = new Uint16Array(sz); + for (i = 0; i < sz; i++) + dec[i] = _this[i]; + } + else if (arg.length === 2) { + var start = arg[0]; + var end = arg[1]; + if (end > start) { + sz = end - start; + dec = new Uint16Array(sz); + for (i = start; i < end; i++) + dec[i - start] = _this[i]; + } + else { + dec = new Uint16Array(0); + } + } + return dec; + } + static _nativeRender_enable() { + } + static enable() { + return true; + } + static inner_enable() { + Float32Array.prototype.slice || (Float32Array.prototype.slice = WebGL._float32ArraySlice); + Uint16Array.prototype.slice || (Uint16Array.prototype.slice = WebGL._uint16ArraySlice); + Uint8Array.prototype.slice || (Uint8Array.prototype.slice = WebGL._uint8ArraySlice); + return true; + } + static onStageResize(width, height) { + if (WebGLContext.mainContext == null) + return; + WebGLContext.mainContext.viewport(0, 0, width, height); + RenderState2D.width = width; + RenderState2D.height = height; + } + } + WebGL._isWebGL2 = false; + WebGL.isNativeRender_enable = false; + + class VertexArrayObject { + constructor() { + } + } + (function () { + var glErrorShadow = {}; + function error(msg) { + if (window.console && window.console.error) { + window.console.error(msg); + } + } + function log(msg) { + if (window.console && window.console.log) { + window.console.log(msg); + } + } + function synthesizeGLError(err, opt_msg) { + glErrorShadow[err] = true; + if (opt_msg !== undefined) { + error(opt_msg); + } + } + function wrapGLError(gl) { + var f = gl.getError; + gl.getError = function () { + var err; + do { + err = f.apply(gl); + if (err != gl.NO_ERROR) { + glErrorShadow[err] = true; + } + } while (err != gl.NO_ERROR); + for (var err1 in glErrorShadow) { + if (glErrorShadow[err1]) { + delete glErrorShadow[err1]; + return parseInt(err1); + } + } + return gl.NO_ERROR; + }; + } + var WebGLVertexArrayObjectOES = function WebGLVertexArrayObjectOES(ext) { + var gl = ext.gl; + this.ext = ext; + this.isAlive = true; + this.hasBeenBound = false; + this.elementArrayBuffer = null; + this.attribs = new Array(ext.maxVertexAttribs); + for (var n = 0; n < this.attribs.length; n++) { + var attrib = new WebGLVertexArrayObjectOES.VertexAttrib(gl); + this.attribs[n] = attrib; + } + this.maxAttrib = 0; + }; + WebGLVertexArrayObjectOES.VertexAttrib = function VertexAttrib(gl) { + this.enabled = false; + this.buffer = null; + this.size = 4; + this.type = gl.FLOAT; + this.normalized = false; + this.stride = 16; + this.offset = 0; + this.cached = ""; + this.recache(); + }; + WebGLVertexArrayObjectOES.VertexAttrib.prototype.recache = function recache() { + this.cached = [this.size, this.type, this.normalized, this.stride, this.offset].join(":"); + }; + var OESVertexArrayObject = function OESVertexArrayObject(gl) { + var self = this; + this.gl = gl; + wrapGLError(gl); + var original = this.original = { + getParameter: gl.getParameter, + enableVertexAttribArray: gl.enableVertexAttribArray, + disableVertexAttribArray: gl.disableVertexAttribArray, + bindBuffer: gl.bindBuffer, + getVertexAttrib: gl.getVertexAttrib, + vertexAttribPointer: gl.vertexAttribPointer + }; + gl.getParameter = function getParameter(pname) { + if (pname == self.VERTEX_ARRAY_BINDING_OES) { + if (self.currentVertexArrayObject == self.defaultVertexArrayObject) { + return null; + } + else { + return self.currentVertexArrayObject; + } + } + return original.getParameter.apply(this, arguments); + }; + gl.enableVertexAttribArray = function enableVertexAttribArray(index) { + var vao = self.currentVertexArrayObject; + vao.maxAttrib = Math.max(vao.maxAttrib, index); + var attrib = vao.attribs[index]; + attrib.enabled = true; + return original.enableVertexAttribArray.apply(this, arguments); + }; + gl.disableVertexAttribArray = function disableVertexAttribArray(index) { + var vao = self.currentVertexArrayObject; + vao.maxAttrib = Math.max(vao.maxAttrib, index); + var attrib = vao.attribs[index]; + attrib.enabled = false; + return original.disableVertexAttribArray.apply(this, arguments); + }; + gl.bindBuffer = function bindBuffer(target, buffer) { + switch (target) { + case gl.ARRAY_BUFFER: + self.currentArrayBuffer = buffer; + break; + case gl.ELEMENT_ARRAY_BUFFER: + self.currentVertexArrayObject.elementArrayBuffer = buffer; + break; + } + return original.bindBuffer.apply(this, arguments); + }; + gl.getVertexAttrib = function getVertexAttrib(index, pname) { + var vao = self.currentVertexArrayObject; + var attrib = vao.attribs[index]; + switch (pname) { + case gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: + return attrib.buffer; + case gl.VERTEX_ATTRIB_ARRAY_ENABLED: + return attrib.enabled; + case gl.VERTEX_ATTRIB_ARRAY_SIZE: + return attrib.size; + case gl.VERTEX_ATTRIB_ARRAY_STRIDE: + return attrib.stride; + case gl.VERTEX_ATTRIB_ARRAY_TYPE: + return attrib.type; + case gl.VERTEX_ATTRIB_ARRAY_NORMALIZED: + return attrib.normalized; + default: + return original.getVertexAttrib.apply(this, arguments); + } + }; + gl.vertexAttribPointer = function vertexAttribPointer(indx, size, type, normalized, stride, offset) { + var vao = self.currentVertexArrayObject; + vao.maxAttrib = Math.max(vao.maxAttrib, indx); + var attrib = vao.attribs[indx]; + attrib.buffer = self.currentArrayBuffer; + attrib.size = size; + attrib.type = type; + attrib.normalized = normalized; + attrib.stride = stride; + attrib.offset = offset; + attrib.recache(); + return original.vertexAttribPointer.apply(this, arguments); + }; + if (gl.instrumentExtension) { + gl.instrumentExtension(this, "OES_vertex_array_object"); + } + gl.canvas.addEventListener('webglcontextrestored', function () { + log("OESVertexArrayObject emulation library context restored"); + self.reset_(); + }, true); + this.reset_(); + }; + OESVertexArrayObject.prototype.VERTEX_ARRAY_BINDING_OES = 0x85B5; + OESVertexArrayObject.prototype.reset_ = function reset_() { + var contextWasLost = this.vertexArrayObjects !== undefined; + if (contextWasLost) { + for (var ii = 0; ii < this.vertexArrayObjects.length; ++ii) { + this.vertexArrayObjects.isAlive = false; + } + } + var gl = this.gl; + this.maxVertexAttribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS); + this.defaultVertexArrayObject = new WebGLVertexArrayObjectOES(this); + this.currentVertexArrayObject = null; + this.currentArrayBuffer = null; + this.vertexArrayObjects = [this.defaultVertexArrayObject]; + this.bindVertexArrayOES(null); + }; + OESVertexArrayObject.prototype.createVertexArrayOES = function createVertexArrayOES() { + var arrayObject = new WebGLVertexArrayObjectOES(this); + this.vertexArrayObjects.push(arrayObject); + return arrayObject; + }; + OESVertexArrayObject.prototype.deleteVertexArrayOES = function deleteVertexArrayOES(arrayObject) { + arrayObject.isAlive = false; + this.vertexArrayObjects.splice(this.vertexArrayObjects.indexOf(arrayObject), 1); + if (this.currentVertexArrayObject == arrayObject) { + this.bindVertexArrayOES(null); + } + }; + OESVertexArrayObject.prototype.isVertexArrayOES = function isVertexArrayOES(arrayObject) { + if (arrayObject && arrayObject instanceof WebGLVertexArrayObjectOES) { + if (arrayObject.hasBeenBound && arrayObject.ext == this) { + return true; + } + } + return false; + }; + OESVertexArrayObject.prototype.bindVertexArrayOES = function bindVertexArrayOES(arrayObject) { + var gl = this.gl; + if (arrayObject && !arrayObject.isAlive) { + synthesizeGLError(gl.INVALID_OPERATION, "bindVertexArrayOES: attempt to bind deleted arrayObject"); + return; + } + var original = this.original; + var oldVAO = this.currentVertexArrayObject; + this.currentVertexArrayObject = arrayObject || this.defaultVertexArrayObject; + this.currentVertexArrayObject.hasBeenBound = true; + var newVAO = this.currentVertexArrayObject; + if (oldVAO == newVAO) { + return; + } + if (!oldVAO || newVAO.elementArrayBuffer != oldVAO.elementArrayBuffer) { + original.bindBuffer.call(gl, gl.ELEMENT_ARRAY_BUFFER, newVAO.elementArrayBuffer); + } + var currentBinding = this.currentArrayBuffer; + var maxAttrib = Math.max(oldVAO ? oldVAO.maxAttrib : 0, newVAO.maxAttrib); + for (var n = 0; n <= maxAttrib; n++) { + var attrib = newVAO.attribs[n]; + var oldAttrib = oldVAO ? oldVAO.attribs[n] : null; + if (!oldVAO || attrib.enabled != oldAttrib.enabled) { + if (attrib.enabled) { + original.enableVertexAttribArray.call(gl, n); + } + else { + original.disableVertexAttribArray.call(gl, n); + } + } + if (attrib.enabled) { + var bufferChanged = false; + if (!oldVAO || attrib.buffer != oldAttrib.buffer) { + if (currentBinding != attrib.buffer) { + original.bindBuffer.call(gl, gl.ARRAY_BUFFER, attrib.buffer); + currentBinding = attrib.buffer; + } + bufferChanged = true; + } + if (bufferChanged || attrib.cached != oldAttrib.cached) { + original.vertexAttribPointer.call(gl, n, attrib.size, attrib.type, attrib.normalized, attrib.stride, attrib.offset); + } + } + } + if (this.currentArrayBuffer != currentBinding) { + original.bindBuffer.call(gl, gl.ARRAY_BUFFER, this.currentArrayBuffer); + } + }; + window._setupVertexArrayObject = function (gl) { + var original_getSupportedExtensions = gl.getSupportedExtensions; + gl.getSupportedExtensions = function getSupportedExtensions() { + var list = original_getSupportedExtensions.call(this) || []; + if (list.indexOf("OES_vertex_array_object") < 0) { + list.push("OES_vertex_array_object"); + } + return list; + }; + var original_getExtension = gl.getExtension; + gl.getExtension = function getExtension(name) { + var ext = original_getExtension.call(this, name); + if (ext) { + return ext; + } + if (name !== "OES_vertex_array_object") { + return null; + } + if (!this.__OESVertexArrayObject) { + console.log("Setup OES_vertex_array_object polyfill"); + this.__OESVertexArrayObject = new OESVertexArrayObject(this); + } + return this.__OESVertexArrayObject; + }; + }; + }()); + + class LayaGPU { + constructor(gl, isWebGL2) { + this._gl = null; + this._vaoExt = null; + this._angleInstancedArrays = null; + this._isWebGL2 = false; + this._oesTextureHalfFloat = null; + this._oes_element_index_uint = null; + this._oesTextureHalfFloatLinear = null; + this._oesTextureFloat = null; + this._extShaderTextureLod = null; + this._extTextureFilterAnisotropic = null; + this._compressedTextureS3tc = null; + this._compressedTexturePvrtc = null; + this._compressedTextureEtc1 = null; + this._compressedTextureETC = null; + this._compressedTextureASTC = null; + this._webgl_depth_texture = null; + this._extColorBufferFloat = null; + this._gl = gl; + this._isWebGL2 = isWebGL2; + var maxTextureFS = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); + var maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); + if (!isWebGL2) { + if (!ILaya.Render.isConchApp) { + if (window._setupVertexArrayObject) + window._setupVertexArrayObject(gl); + } + this._vaoExt = this._getExtension("OES_vertex_array_object"); + this._angleInstancedArrays = this._getExtension("ANGLE_instanced_arrays"); + this._oesTextureHalfFloat = this._getExtension("OES_texture_half_float"); + this._oesTextureHalfFloatLinear = this._getExtension("OES_texture_half_float_linear"); + this._oesTextureFloat = this._getExtension("OES_texture_float"); + this._oes_element_index_uint = this._getExtension("OES_element_index_uint"); + this._extShaderTextureLod = this._getExtension("EXT_shader_texture_lod"); + this._webgl_depth_texture = this._getExtension("WEBGL_depth_texture"); + SystemUtils._shaderCapailityLevel = 30; + } + else { + this._extColorBufferFloat = this._getExtension("EXT_color_buffer_float"); + SystemUtils._shaderCapailityLevel = 35; + } + this._extTextureFilterAnisotropic = this._getExtension("EXT_texture_filter_anisotropic"); + this._compressedTextureS3tc = this._getExtension("WEBGL_compressed_texture_s3tc"); + this._compressedTexturePvrtc = this._getExtension("WEBGL_compressed_texture_pvrtc"); + this._compressedTextureEtc1 = this._getExtension("WEBGL_compressed_texture_etc1"); + this._compressedTextureETC = this._getExtension("WEBGL_compressed_texture_etc"); + this._compressedTextureASTC = this._getExtension("WEBGL_compressed_texture_astc"); + SystemUtils._maxTextureCount = maxTextureFS; + SystemUtils._maxTextureSize = maxTextureSize; + } + _getExtension(name) { + var prefixes = LayaGPU._extentionVendorPrefixes; + for (var k in prefixes) { + var ext = this._gl.getExtension(prefixes[k] + name); + if (ext) + return ext; + } + return null; + } + createVertexArray() { + if (this._isWebGL2) + return this._gl.createVertexArray(); + else + return this._vaoExt.createVertexArrayOES(); + } + bindVertexArray(vertexArray) { + if (this._isWebGL2) + this._gl.bindVertexArray(vertexArray); + else + this._vaoExt.bindVertexArrayOES(vertexArray); + } + deleteVertexArray(vertexArray) { + if (this._isWebGL2) + this._gl.deleteVertexArray(vertexArray); + else + this._vaoExt.deleteVertexArrayOES(vertexArray); + } + isVertexArray(vertexArray) { + if (this._isWebGL2) + this._gl.isVertexArray(vertexArray); + else + this._vaoExt.isVertexArrayOES(vertexArray); + } + drawElementsInstanced(mode, count, type, offset, instanceCount) { + if (this._isWebGL2) + this._gl.drawElementsInstanced(mode, count, type, offset, instanceCount); + else + this._angleInstancedArrays.drawElementsInstancedANGLE(mode, count, type, offset, instanceCount); + } + drawArraysInstanced(mode, first, count, instanceCount) { + if (this._isWebGL2) + this._gl.drawArraysInstanced(mode, first, count, instanceCount); + else + this._angleInstancedArrays.drawArraysInstancedANGLE(mode, first, count, instanceCount); + } + vertexAttribDivisor(index, divisor) { + if (this._isWebGL2) + this._gl.vertexAttribDivisor(index, divisor); + else + this._angleInstancedArrays.vertexAttribDivisorANGLE(index, divisor); + } + supportInstance() { + if ((this._isWebGL2 || this._angleInstancedArrays) && Config.allowGPUInstanceDynamicBatch) + return true; + else + return false; + } + supportElementIndexUint32() { + return this._isWebGL2 || this._oes_element_index_uint ? true : false; + } + } + LayaGPU._extentionVendorPrefixes = ["", "WEBKIT_", "MOZ_"]; + + class Render { + constructor(width, height, mainCanv) { + this._timeId = 0; + Render._mainCanvas = mainCanv; + let source = Render._mainCanvas.source; + source.id = "layaCanvas"; + source.width = width; + source.height = height; + if (Render.isConchApp) { + document.body.appendChild(source); + } + this.initRender(Render._mainCanvas, width, height); + window.requestAnimationFrame(loop); + function loop(stamp) { + ILaya.stage._loop(); + window.requestAnimationFrame(loop); + } + ILaya.stage.on("visibilitychange", this, this._onVisibilitychange); + } + _onVisibilitychange() { + if (!ILaya.stage.isVisibility) { + this._timeId = window.setInterval(this._enterFrame, 1000); + } + else if (this._timeId != 0) { + window.clearInterval(this._timeId); + } + } + initRender(canvas, w, h) { + function getWebGLContext(canvas) { + var gl; + var names = ["webgl2", "webgl", "experimental-webgl", "webkit-3d", "moz-webgl"]; + if (!Config.useWebGL2 || Browser.onBDMiniGame) { + names.shift(); + } + for (var i = 0; i < names.length; i++) { + try { + gl = canvas.getContext(names[i], { stencil: Config.isStencil, alpha: Config.isAlpha, antialias: Config.isAntialias, premultipliedAlpha: Config.premultipliedAlpha, preserveDrawingBuffer: Config.preserveDrawingBuffer }); + } + catch (e) { + } + if (gl) { + (names[i] === 'webgl2') && (WebGL._isWebGL2 = true); + return gl; + } + } + return null; + } + var gl = LayaGL.instance = WebGLContext.mainContext = getWebGLContext(Render._mainCanvas.source); + if (Config.printWebglOrder) + this._replaceWebglcall(gl); + if (!gl) + return false; + LayaGL.instance = gl; + LayaGL.layaGPUInstance = new LayaGPU(gl, WebGL._isWebGL2); + canvas.size(w, h); + Context.__init__(); + SubmitBase.__init__(); + var ctx = new Context(); + ctx.isMain = true; + Render._context = ctx; + canvas._setContext(ctx); + ShaderDefines2D.__init__(); + Value2D.__init__(); + Shader2D.__init__(); + Buffer2D.__int__(gl); + BlendMode._init_(gl); + return true; + } + _replaceWebglcall(gl) { + var tempgl = {}; + for (const key in gl) { + if (typeof gl[key] == "function" && key != "getError" && key != "__SPECTOR_Origin_getError" && key != "__proto__") { + tempgl[key] = gl[key]; + gl[key] = function () { + let arr = []; + for (let i = 0; i < arguments.length; i++) { + arr.push(arguments[i]); + } + let result = tempgl[key].apply(gl, arr); + console.log(RenderInfo.loopCount + ":gl." + key + ":" + arr); + let err = gl.getError(); + if (err) { + console.log(err); + debugger; + } + return result; + }; + } + } + } + _enterFrame(e = null) { + ILaya.stage._loop(); + } + static get context() { + return Render._context; + } + static get canvas() { + return Render._mainCanvas.source; + } + } + Render.supportWebGLPlusAnimation = false; + Render.supportWebGLPlusRendering = false; + Render.isConchApp = false; + { + Render.isConchApp = (window.conch != null); + if (Render.isConchApp) { + Render.supportWebGLPlusRendering = false; + } + else if (window.qq != null && window.qq.webglPlus != null) { + Render.supportWebGLPlusRendering = false; + } + } + + class DrawTrianglesCmd { + static create(texture, x, y, vertices, uvs, indices, matrix, alpha, color, blendMode, colorNum) { + var cmd = Pool.getItemByClass("DrawTrianglesCmd", DrawTrianglesCmd); + cmd.texture = texture; + cmd.x = x; + cmd.y = y; + cmd.vertices = vertices; + cmd.uvs = uvs; + cmd.indices = indices; + cmd.matrix = matrix; + cmd.alpha = alpha; + if (color) { + cmd.color = new ColorFilter(); + var c = ColorUtils.create(color).arrColor; + cmd.color.color(c[0] * 255, c[1] * 255, c[2] * 255, c[3] * 255); + } + cmd.blendMode = blendMode; + cmd.colorNum = colorNum; + return cmd; + } + recover() { + this.texture = null; + this.vertices = null; + this.uvs = null; + this.indices = null; + this.matrix = null; + Pool.recover("DrawTrianglesCmd", this); + } + run(context, gx, gy) { + context.drawTriangles(this.texture, this.x + gx, this.y + gy, this.vertices, this.uvs, this.indices, this.matrix, this.alpha, this.color, this.blendMode, this.colorNum); + } + get cmdID() { + return DrawTrianglesCmd.ID; + } + } + DrawTrianglesCmd.ID = "DrawTriangles"; + + class Draw9GridTexture { + constructor() { + } + static create(texture, x, y, width, height, sizeGrid) { + var cmd = Pool.getItemByClass("Draw9GridTexture", Draw9GridTexture); + cmd.texture = texture; + texture._addReference(); + cmd.x = x; + cmd.y = y; + cmd.width = width; + cmd.height = height; + cmd.sizeGrid = sizeGrid; + return cmd; + } + recover() { + this.texture._removeReference(); + Pool.recover("Draw9GridTexture", this); + } + run(context, gx, gy) { + context.drawTextureWithSizeGrid(this.texture, this.x, this.y, this.width, this.height, this.sizeGrid, gx, gy); + } + get cmdID() { + return Draw9GridTexture.ID; + } + } + Draw9GridTexture.ID = "Draw9GridTexture"; + + class SaveCmd { + static create() { + var cmd = Pool.getItemByClass("SaveCmd", SaveCmd); + return cmd; + } + recover() { + Pool.recover("SaveCmd", this); + } + run(context, gx, gy) { + context.save(); + } + get cmdID() { + return SaveCmd.ID; + } + } + SaveCmd.ID = "Save"; + + class GraphicsBounds { + constructor() { + this._cacheBoundsType = false; + } + destroy() { + this._graphics = null; + this._cacheBoundsType = false; + if (this._temp) + this._temp.length = 0; + if (this._rstBoundPoints) + this._rstBoundPoints.length = 0; + if (this._bounds) + this._bounds.recover(); + this._bounds = null; + Pool.recover("GraphicsBounds", this); + } + static create() { + return Pool.getItemByClass("GraphicsBounds", GraphicsBounds); + } + reset() { + this._temp && (this._temp.length = 0); + } + getBounds(realSize = false) { + if (!this._bounds || !this._temp || this._temp.length < 1 || realSize != this._cacheBoundsType) { + this._bounds = Rectangle._getWrapRec(this.getBoundPoints(realSize), this._bounds); + } + this._cacheBoundsType = realSize; + return this._bounds; + } + getBoundPoints(realSize = false) { + if (!this._temp || this._temp.length < 1 || realSize != this._cacheBoundsType) + this._temp = this._getCmdPoints(realSize); + this._cacheBoundsType = realSize; + return this._rstBoundPoints = Utils.copyArray(this._rstBoundPoints, this._temp); + } + _getCmdPoints(realSize = false) { + var cmds = this._graphics.cmds; + var rst; + rst = this._temp || (this._temp = []); + rst.length = 0; + if (!cmds && this._graphics._one != null) { + GraphicsBounds._tempCmds.length = 0; + GraphicsBounds._tempCmds.push(this._graphics._one); + cmds = GraphicsBounds._tempCmds; + } + if (!cmds) + return rst; + var matrixs = GraphicsBounds._tempMatrixArrays; + matrixs.length = 0; + var tMatrix = GraphicsBounds._initMatrix; + tMatrix.identity(); + var tempMatrix = GraphicsBounds._tempMatrix; + var cmd; + var tex; + for (var i = 0, n = cmds.length; i < n; i++) { + cmd = cmds[i]; + switch (cmd.cmdID) { + case AlphaCmd.ID: + case SaveCmd.ID: + matrixs.push(tMatrix); + tMatrix = tMatrix.clone(); + break; + case RestoreCmd.ID: + tMatrix = matrixs.pop(); + break; + case ScaleCmd.ID: + tempMatrix.identity(); + tempMatrix.translate(-cmd.pivotX, -cmd.pivotY); + tempMatrix.scale(cmd.scaleX, cmd.scaleY); + tempMatrix.translate(cmd.pivotX, cmd.pivotY); + this._switchMatrix(tMatrix, tempMatrix); + break; + case RotateCmd.ID: + tempMatrix.identity(); + tempMatrix.translate(-cmd.pivotX, -cmd.pivotY); + tempMatrix.rotate(cmd.angle); + tempMatrix.translate(cmd.pivotX, cmd.pivotY); + this._switchMatrix(tMatrix, tempMatrix); + break; + case TranslateCmd.ID: + tempMatrix.identity(); + tempMatrix.translate(cmd.tx, cmd.ty); + this._switchMatrix(tMatrix, tempMatrix); + break; + case TransformCmd.ID: + tempMatrix.identity(); + tempMatrix.translate(-cmd.pivotX, -cmd.pivotY); + tempMatrix.concat(cmd.matrix); + tempMatrix.translate(cmd.pivotX, cmd.pivotY); + this._switchMatrix(tMatrix, tempMatrix); + break; + case DrawImageCmd.ID: + case FillTextureCmd.ID: + GraphicsBounds._addPointArrToRst(rst, Rectangle._getBoundPointS(cmd.x, cmd.y, cmd.width, cmd.height), tMatrix); + break; + case DrawTextureCmd.ID: + tMatrix.copyTo(tempMatrix); + if (cmd.matrix) + tempMatrix.concat(cmd.matrix); + GraphicsBounds._addPointArrToRst(rst, Rectangle._getBoundPointS(cmd.x, cmd.y, cmd.width, cmd.height), tempMatrix); + break; + case DrawImageCmd.ID: + tex = cmd.texture; + if (realSize) { + if (cmd.width && cmd.height) { + GraphicsBounds._addPointArrToRst(rst, Rectangle._getBoundPointS(cmd.x, cmd.y, cmd.width, cmd.height), tMatrix); + } + else { + GraphicsBounds._addPointArrToRst(rst, Rectangle._getBoundPointS(cmd.x, cmd.y, tex.width, tex.height), tMatrix); + } + } + else { + var wRate = (cmd.width || tex.sourceWidth) / tex.width; + var hRate = (cmd.height || tex.sourceHeight) / tex.height; + var oWidth = wRate * tex.sourceWidth; + var oHeight = hRate * tex.sourceHeight; + var offX = tex.offsetX > 0 ? tex.offsetX : 0; + var offY = tex.offsetY > 0 ? tex.offsetY : 0; + offX *= wRate; + offY *= hRate; + GraphicsBounds._addPointArrToRst(rst, Rectangle._getBoundPointS(cmd.x - offX, cmd.y - offY, oWidth, oHeight), tMatrix); + } + break; + case FillTextureCmd.ID: + if (cmd.width && cmd.height) { + GraphicsBounds._addPointArrToRst(rst, Rectangle._getBoundPointS(cmd.x, cmd.y, cmd.width, cmd.height), tMatrix); + } + else { + tex = cmd.texture; + GraphicsBounds._addPointArrToRst(rst, Rectangle._getBoundPointS(cmd.x, cmd.y, tex.width, tex.height), tMatrix); + } + break; + case DrawTextureCmd.ID: + var drawMatrix; + if (cmd.matrix) { + tMatrix.copyTo(tempMatrix); + tempMatrix.concat(cmd.matrix); + drawMatrix = tempMatrix; + } + else { + drawMatrix = tMatrix; + } + if (realSize) { + if (cmd.width && cmd.height) { + GraphicsBounds._addPointArrToRst(rst, Rectangle._getBoundPointS(cmd.x, cmd.y, cmd.width, cmd.height), drawMatrix); + } + else { + tex = cmd.texture; + GraphicsBounds._addPointArrToRst(rst, Rectangle._getBoundPointS(cmd.x, cmd.y, tex.width, tex.height), drawMatrix); + } + } + else { + tex = cmd.texture; + wRate = (cmd.width || tex.sourceWidth) / tex.width; + hRate = (cmd.height || tex.sourceHeight) / tex.height; + oWidth = wRate * tex.sourceWidth; + oHeight = hRate * tex.sourceHeight; + offX = tex.offsetX > 0 ? tex.offsetX : 0; + offY = tex.offsetY > 0 ? tex.offsetY : 0; + offX *= wRate; + offY *= hRate; + GraphicsBounds._addPointArrToRst(rst, Rectangle._getBoundPointS(cmd.x - offX, cmd.y - offY, oWidth, oHeight), drawMatrix); + } + break; + case DrawRectCmd.ID: + GraphicsBounds._addPointArrToRst(rst, Rectangle._getBoundPointS(cmd.x, cmd.y, cmd.width, cmd.height), tMatrix); + break; + case DrawCircleCmd.ID: + GraphicsBounds._addPointArrToRst(rst, Rectangle._getBoundPointS(cmd.x - cmd.radius, cmd.y - cmd.radius, cmd.radius + cmd.radius, cmd.radius + cmd.radius), tMatrix); + break; + case DrawLineCmd.ID: + GraphicsBounds._tempPoints.length = 0; + var lineWidth; + lineWidth = cmd.lineWidth * 0.5; + if (cmd.fromX == cmd.toX) { + GraphicsBounds._tempPoints.push(cmd.fromX + lineWidth, cmd.fromY, cmd.toX + lineWidth, cmd.toY, cmd.fromX - lineWidth, cmd.fromY, cmd.toX - lineWidth, cmd.toY); + } + else if (cmd.fromY == cmd.toY) { + GraphicsBounds._tempPoints.push(cmd.fromX, cmd.fromY + lineWidth, cmd.toX, cmd.toY + lineWidth, cmd.fromX, cmd.fromY - lineWidth, cmd.toX, cmd.toY - lineWidth); + } + else { + GraphicsBounds._tempPoints.push(cmd.fromX, cmd.fromY, cmd.toX, cmd.toY); + } + GraphicsBounds._addPointArrToRst(rst, GraphicsBounds._tempPoints, tMatrix); + break; + case DrawCurvesCmd.ID: + GraphicsBounds._addPointArrToRst(rst, Bezier.I.getBezierPoints(cmd.points), tMatrix, cmd.x, cmd.y); + break; + case DrawLinesCmd.ID: + case DrawPolyCmd.ID: + GraphicsBounds._addPointArrToRst(rst, cmd.points, tMatrix, cmd.x, cmd.y); + break; + case DrawPathCmd.ID: + GraphicsBounds._addPointArrToRst(rst, this._getPathPoints(cmd.paths), tMatrix, cmd.x, cmd.y); + break; + case DrawPieCmd.ID: + GraphicsBounds._addPointArrToRst(rst, this._getPiePoints(cmd.x, cmd.y, cmd.radius, cmd.startAngle, cmd.endAngle), tMatrix); + break; + case DrawTrianglesCmd.ID: + GraphicsBounds._addPointArrToRst(rst, this._getTriAngBBXPoints(cmd.vertices), tMatrix); + break; + case Draw9GridTexture.ID: + GraphicsBounds._addPointArrToRst(rst, this._getDraw9GridBBXPoints(cmd), tMatrix); + break; + } + } + if (rst.length > 200) { + rst = Utils.copyArray(rst, Rectangle._getWrapRec(rst)._getBoundPoints()); + } + else if (rst.length > 8) + rst = GrahamScan.scanPList(rst); + return rst; + } + _switchMatrix(tMatix, tempMatrix) { + tempMatrix.concat(tMatix); + tempMatrix.copyTo(tMatix); + } + static _addPointArrToRst(rst, points, matrix, dx = 0, dy = 0) { + var i, len; + len = points.length; + for (i = 0; i < len; i += 2) { + GraphicsBounds._addPointToRst(rst, points[i] + dx, points[i + 1] + dy, matrix); + } + } + static _addPointToRst(rst, x, y, matrix) { + var _tempPoint = Point.TEMP; + _tempPoint.setTo(x ? x : 0, y ? y : 0); + matrix.transformPoint(_tempPoint); + rst.push(_tempPoint.x, _tempPoint.y); + } + _getPiePoints(x, y, radius, startAngle, endAngle) { + var rst = GraphicsBounds._tempPoints; + GraphicsBounds._tempPoints.length = 0; + var k = Math.PI / 180; + var d1 = endAngle - startAngle; + if (d1 >= 360 || d1 <= -360) { + rst.push(x - radius, y - radius); + rst.push(x + radius, y - radius); + rst.push(x + radius, y + radius); + rst.push(x - radius, y + radius); + return rst; + } + rst.push(x, y); + var delta = d1 % 360; + if (delta < 0) + delta += 360; + var end1 = startAngle + delta; + var st = startAngle * k; + var ed = end1 * k; + rst.push(x + radius * Math.cos(st), y + radius * Math.sin(st)); + rst.push(x + radius * Math.cos(ed), y + radius * Math.sin(ed)); + var s1 = Math.ceil(startAngle / 90) * 90; + var s2 = Math.floor(end1 / 90) * 90; + for (var cs = s1; cs <= s2; cs += 90) { + var csr = cs * k; + rst.push(x + radius * Math.cos(csr), y + radius * Math.sin(csr)); + } + return rst; + } + _getTriAngBBXPoints(vert) { + var vnum = vert.length; + if (vnum < 2) + return []; + var minx = vert[0]; + var miny = vert[1]; + var maxx = minx; + var maxy = miny; + for (var i = 2; i < vnum;) { + var cx = vert[i++]; + var cy = vert[i++]; + if (minx > cx) + minx = cx; + if (miny > cy) + miny = cy; + if (maxx < cx) + maxx = cx; + if (maxy < cy) + maxy = cy; + } + return [minx, miny, maxx, miny, maxx, maxy, minx, maxy]; + } + _getDraw9GridBBXPoints(cmd) { + var minx = 0; + var miny = 0; + var maxx = cmd.width; + var maxy = cmd.height; + return [minx, miny, maxx, miny, maxx, maxy, minx, maxy]; + } + _getPathPoints(paths) { + var i, len; + var rst = GraphicsBounds._tempPoints; + rst.length = 0; + len = paths.length; + var tCMD; + for (i = 0; i < len; i++) { + tCMD = paths[i]; + if (tCMD.length > 1) { + rst.push(tCMD[1], tCMD[2]); + if (tCMD.length > 3) { + rst.push(tCMD[3], tCMD[4]); + } + } + } + return rst; + } + } + GraphicsBounds._tempMatrix = new Matrix(); + GraphicsBounds._initMatrix = new Matrix(); + GraphicsBounds._tempPoints = []; + GraphicsBounds._tempMatrixArrays = []; + GraphicsBounds._tempCmds = []; + + class SpriteConst { + } + SpriteConst.ALPHA = 0x01; + SpriteConst.TRANSFORM = 0x02; + SpriteConst.BLEND = 0x04; + SpriteConst.CANVAS = 0x08; + SpriteConst.FILTERS = 0x10; + SpriteConst.MASK = 0x20; + SpriteConst.CLIP = 0x40; + SpriteConst.STYLE = 0x80; + SpriteConst.TEXTURE = 0x100; + SpriteConst.GRAPHICS = 0x200; + SpriteConst.LAYAGL3D = 0x400; + SpriteConst.CUSTOM = 0x800; + SpriteConst.ONECHILD = 0x1000; + SpriteConst.CHILDS = 0x2000; + SpriteConst.REPAINT_NONE = 0; + SpriteConst.REPAINT_NODE = 0x01; + SpriteConst.REPAINT_CACHE = 0x02; + SpriteConst.REPAINT_ALL = 0x03; + + class ClipRectCmd { + static create(x, y, width, height) { + var cmd = Pool.getItemByClass("ClipRectCmd", ClipRectCmd); + cmd.x = x; + cmd.y = y; + cmd.width = width; + cmd.height = height; + return cmd; + } + recover() { + Pool.recover("ClipRectCmd", this); + } + run(context, gx, gy) { + context.clipRect(this.x + gx, this.y + gy, this.width, this.height); + } + get cmdID() { + return ClipRectCmd.ID; + } + } + ClipRectCmd.ID = "ClipRect"; + + class DrawTexturesCmd { + static create(texture, pos) { + var cmd = Pool.getItemByClass("DrawTexturesCmd", DrawTexturesCmd); + cmd.texture = texture; + texture._addReference(); + cmd.pos = pos; + return cmd; + } + recover() { + this.texture._removeReference(); + this.texture = null; + this.pos = null; + Pool.recover("DrawTexturesCmd", this); + } + run(context, gx, gy) { + context.drawTextures(this.texture, this.pos, gx, gy); + } + get cmdID() { + return DrawTexturesCmd.ID; + } + } + DrawTexturesCmd.ID = "DrawTextures"; + + class FillTextCmd { + constructor() { + this._textIsWorldText = false; + this._fontColor = 0xffffffff; + this._strokeColor = 0; + this._fontObj = FillTextCmd._defFontObj; + this._nTexAlign = 0; + } + static create(text, words, x, y, font, color, textAlign, lineWidth, borderColor) { + var cmd = Pool.getItemByClass("FillTextCmd", FillTextCmd); + cmd.text = text; + cmd._textIsWorldText = text instanceof WordText; + cmd._words = words; + cmd.x = x; + cmd.y = y; + cmd.font = font; + cmd.color = color; + cmd.textAlign = textAlign; + cmd._lineWidth = lineWidth; + cmd._borderColor = borderColor; + return cmd; + } + recover() { + Pool.recover("FillTextCmd", this); + } + run(context, gx, gy) { + if (ILaya.stage.isGlobalRepaint()) { + this._textIsWorldText && this._text.cleanCache(); + } + if (this._words) { + Context._textRender.fillWords(context, this._words, this.x + gx, this.y + gy, this._fontObj, this._color, this._borderColor, this._lineWidth); + } + else { + if (this._textIsWorldText) { + context._fast_filltext(this._text, this.x + gx, this.y + gy, this._fontObj, this._color, this._borderColor, this._lineWidth, this._nTexAlign, 0); + } + else { + Context._textRender.filltext(context, this._text, this.x + gx, this.y + gy, this.font, this.color, this._borderColor, this._lineWidth, this._textAlign); + } + } + } + get cmdID() { + return FillTextCmd.ID; + } + get text() { + return this._text; + } + set text(value) { + this._text = value; + this._textIsWorldText = value instanceof WordText; + this._textIsWorldText && this._text.cleanCache(); + } + get font() { + return this._font; + } + set font(value) { + this._font = value; + this._fontObj = FontInfo.Parse(value); + this._textIsWorldText && this._text.cleanCache(); + } + get color() { + return this._color; + } + set color(value) { + this._color = value; + this._fontColor = ColorUtils.create(value).numColor; + this._textIsWorldText && this._text.cleanCache(); + } + get textAlign() { + return this._textAlign; + } + set textAlign(value) { + this._textAlign = value; + switch (value) { + case 'center': + this._nTexAlign = ILaya.Context.ENUM_TEXTALIGN_CENTER; + break; + case 'right': + this._nTexAlign = ILaya.Context.ENUM_TEXTALIGN_RIGHT; + break; + default: + this._nTexAlign = ILaya.Context.ENUM_TEXTALIGN_DEFAULT; + } + this._textIsWorldText && this._text.cleanCache(); + } + } + FillTextCmd.ID = "FillText"; + FillTextCmd._defFontObj = new FontInfo(null); + + class CacheManger { + constructor() { + } + static regCacheByFunction(disposeFunction, getCacheListFunction) { + CacheManger.unRegCacheByFunction(disposeFunction, getCacheListFunction); + var cache; + cache = { tryDispose: disposeFunction, getCacheList: getCacheListFunction }; + CacheManger._cacheList.push(cache); + } + static unRegCacheByFunction(disposeFunction, getCacheListFunction) { + var i, len; + len = CacheManger._cacheList.length; + for (i = 0; i < len; i++) { + if (CacheManger._cacheList[i].tryDispose == disposeFunction && CacheManger._cacheList[i].getCacheList == getCacheListFunction) { + CacheManger._cacheList.splice(i, 1); + return; + } + } + } + static forceDispose() { + var i, len = CacheManger._cacheList.length; + for (i = 0; i < len; i++) { + CacheManger._cacheList[i].tryDispose(true); + } + } + static beginCheck(waitTime = 15000) { + ILaya.systemTimer.loop(waitTime, null, CacheManger._checkLoop); + } + static stopCheck() { + ILaya.systemTimer.clear(null, CacheManger._checkLoop); + } + static _checkLoop() { + var cacheList = CacheManger._cacheList; + if (cacheList.length < 1) + return; + var tTime = ILaya.Browser.now(); + var count; + var len; + len = count = cacheList.length; + while (count > 0) { + CacheManger._index++; + CacheManger._index = CacheManger._index % len; + cacheList[CacheManger._index].tryDispose(false); + if (ILaya.Browser.now() - tTime > CacheManger.loopTimeLimit) + break; + count--; + } + } + } + CacheManger.loopTimeLimit = 2; + CacheManger._cacheList = []; + CacheManger._index = 0; + + class VectorGraphManager { + constructor() { + this.useDic = {}; + this.shapeDic = {}; + this.shapeLineDic = {}; + this._id = 0; + this._checkKey = false; + this._freeIdArray = []; + CacheManger.regCacheByFunction(this.startDispose.bind(this), this.getCacheList.bind(this)); + } + static getInstance() { + return VectorGraphManager.instance = VectorGraphManager.instance || new VectorGraphManager(); + } + getId() { + return this._id++; + } + addShape(id, shape) { + this.shapeDic[id] = shape; + if (!this.useDic[id]) { + this.useDic[id] = true; + } + } + addLine(id, Line) { + this.shapeLineDic[id] = Line; + if (!this.shapeLineDic[id]) { + this.shapeLineDic[id] = true; + } + } + getShape(id) { + if (this._checkKey) { + if (this.useDic[id] != null) { + this.useDic[id] = true; + } + } + } + deleteShape(id) { + if (this.shapeDic[id]) { + this.shapeDic[id] = null; + delete this.shapeDic[id]; + } + if (this.shapeLineDic[id]) { + this.shapeLineDic[id] = null; + delete this.shapeLineDic[id]; + } + if (this.useDic[id] != null) { + delete this.useDic[id]; + } + } + getCacheList() { + var str; + var list = []; + for (str in this.shapeDic) { + list.push(this.shapeDic[str]); + } + for (str in this.shapeLineDic) { + list.push(this.shapeLineDic[str]); + } + return list; + } + startDispose(key) { + var str; + for (str in this.useDic) { + this.useDic[str] = false; + } + this._checkKey = true; + } + endDispose() { + if (this._checkKey) { + var str; + for (str in this.useDic) { + if (!this.useDic[str]) { + this.deleteShape(str); + } + } + this._checkKey = false; + } + } + } + + class Graphics { + constructor() { + this._sp = null; + this._one = null; + this._render = this._renderEmpty; + this._cmds = null; + this._vectorgraphArray = null; + this._graphicBounds = null; + this.autoDestroy = false; + this._createData(); + } + _createData() { + } + _clearData() { + } + _destroyData() { + } + destroy() { + this.clear(true); + if (this._graphicBounds) + this._graphicBounds.destroy(); + this._graphicBounds = null; + this._vectorgraphArray = null; + if (this._sp) { + this._sp._renderType = 0; + this._sp._setRenderType(0); + this._sp = null; + } + this._destroyData(); + } + clear(recoverCmds = true) { + if (recoverCmds) { + var tCmd = this._one; + if (this._cmds) { + var i, len = this._cmds.length; + for (i = 0; i < len; i++) { + tCmd = this._cmds[i]; + tCmd.recover(); + } + this._cmds.length = 0; + } + else if (tCmd) { + tCmd.recover(); + } + } + else { + this._cmds = null; + } + this._one = null; + this._render = this._renderEmpty; + this._clearData(); + if (this._sp) { + this._sp._renderType &= ~SpriteConst.GRAPHICS; + this._sp._setRenderType(this._sp._renderType); + } + this._repaint(); + if (this._vectorgraphArray) { + for (i = 0, len = this._vectorgraphArray.length; i < len; i++) { + VectorGraphManager.getInstance().deleteShape(this._vectorgraphArray[i]); + } + this._vectorgraphArray.length = 0; + } + } + _clearBoundsCache() { + if (this._graphicBounds) + this._graphicBounds.reset(); + } + _initGraphicBounds() { + if (!this._graphicBounds) { + this._graphicBounds = GraphicsBounds.create(); + this._graphicBounds._graphics = this; + } + } + _repaint() { + this._clearBoundsCache(); + this._sp && this._sp.repaint(); + } + _isOnlyOne() { + return !this._cmds || this._cmds.length === 0; + } + get cmds() { + return this._cmds; + } + set cmds(value) { + if (this._sp) { + this._sp._renderType |= SpriteConst.GRAPHICS; + this._sp._setRenderType(this._sp._renderType); + } + this._cmds = value; + this._render = this._renderAll; + this._repaint(); + } + getBounds(realSize = false) { + this._initGraphicBounds(); + return this._graphicBounds.getBounds(realSize); + } + getBoundPoints(realSize = false) { + this._initGraphicBounds(); + return this._graphicBounds.getBoundPoints(realSize); + } + drawImage(texture, x = 0, y = 0, width = 0, height = 0) { + if (!texture) + return null; + if (!width) + width = texture.sourceWidth; + if (!height) + height = texture.sourceHeight; + if (texture.getIsReady()) { + var wRate = width / texture.sourceWidth; + var hRate = height / texture.sourceHeight; + width = texture.width * wRate; + height = texture.height * hRate; + if (width <= 0 || height <= 0) + return null; + x += texture.offsetX * wRate; + y += texture.offsetY * hRate; + } + if (this._sp) { + this._sp._renderType |= SpriteConst.GRAPHICS; + this._sp._setRenderType(this._sp._renderType); + } + var args = DrawImageCmd.create.call(this, texture, x, y, width, height); + if (this._one == null) { + this._one = args; + this._render = this._renderOneImg; + } + else { + this._saveToCmd(null, args); + } + this._repaint(); + return args; + } + drawTexture(texture, x = 0, y = 0, width = 0, height = 0, matrix = null, alpha = 1, color = null, blendMode = null, uv) { + if (!texture || alpha < 0.01) + return null; + if (!texture.getIsReady()) + return null; + if (!width) + width = texture.sourceWidth; + if (!height) + height = texture.sourceHeight; + if (texture.getIsReady()) { + var wRate = width / texture.sourceWidth; + var hRate = height / texture.sourceHeight; + width = texture.width * wRate; + height = texture.height * hRate; + if (width <= 0 || height <= 0) + return null; + x += texture.offsetX * wRate; + y += texture.offsetY * hRate; + } + if (this._sp) { + this._sp._renderType |= SpriteConst.GRAPHICS; + this._sp._setRenderType(this._sp._renderType); + } + var args = DrawTextureCmd.create.call(this, texture, x, y, width, height, matrix, alpha, color, blendMode, uv); + this._repaint(); + return this._saveToCmd(null, args); + } + drawTextures(texture, pos) { + if (!texture) + return null; + return this._saveToCmd(Render._context.drawTextures, DrawTexturesCmd.create.call(this, texture, pos)); + } + drawTriangles(texture, x, y, vertices, uvs, indices, matrix = null, alpha = 1, color = null, blendMode = null, colorNum = 0xffffffff) { + return this._saveToCmd(Render._context.drawTriangles, DrawTrianglesCmd.create.call(this, texture, x, y, vertices, uvs, indices, matrix, alpha, color, blendMode, colorNum)); + } + fillTexture(texture, x, y, width = 0, height = 0, type = "repeat", offset = null) { + if (texture && texture.getIsReady()) + return this._saveToCmd(Render._context._fillTexture, FillTextureCmd.create.call(this, texture, x, y, width, height, type, offset || Point.EMPTY, {})); + else + return null; + } + _saveToCmd(fun, args) { + if (this._sp) { + this._sp._renderType |= SpriteConst.GRAPHICS; + this._sp._setRenderType(this._sp._renderType); + } + if (this._one == null) { + this._one = args; + this._render = this._renderOne; + } + else { + this._render = this._renderAll; + (this._cmds || (this._cmds = [])).length === 0 && this._cmds.push(this._one); + this._cmds.push(args); + } + this._repaint(); + return args; + } + clipRect(x, y, width, height) { + return this._saveToCmd(Render._context.clipRect, ClipRectCmd.create.call(this, x, y, width, height)); + } + fillText(text, x, y, font, color, textAlign) { + return this._saveToCmd(Render._context.fillText, FillTextCmd.create.call(this, text, null, x, y, font || ILaya.Text.defaultFontStr(), color, textAlign, 0, "")); + } + fillBorderText(text, x, y, font, fillColor, textAlign, lineWidth, borderColor) { + return this._saveToCmd(Render._context.fillText, FillTextCmd.create.call(this, text, null, x, y, font || ILaya.Text.defaultFontStr(), fillColor, textAlign, lineWidth, borderColor)); + } + fillWords(words, x, y, font, color) { + return this._saveToCmd(Render._context.fillText, FillTextCmd.create.call(this, null, words, x, y, font || ILaya.Text.defaultFontStr(), color, '', 0, null)); + } + fillBorderWords(words, x, y, font, fillColor, borderColor, lineWidth) { + return this._saveToCmd(Render._context.fillText, FillTextCmd.create.call(this, null, words, x, y, font || ILaya.Text.defaultFontStr(), fillColor, "", lineWidth, borderColor)); + } + strokeText(text, x, y, font, color, lineWidth, textAlign) { + return this._saveToCmd(Render._context.fillText, FillTextCmd.create.call(this, text, null, x, y, font || ILaya.Text.defaultFontStr(), null, textAlign, lineWidth, color)); + } + alpha(alpha) { + return this._saveToCmd(Render._context.alpha, AlphaCmd.create.call(this, alpha)); + } + transform(matrix, pivotX = 0, pivotY = 0) { + return this._saveToCmd(Render._context._transform, TransformCmd.create.call(this, matrix, pivotX, pivotY)); + } + rotate(angle, pivotX = 0, pivotY = 0) { + return this._saveToCmd(Render._context._rotate, RotateCmd.create.call(this, angle, pivotX, pivotY)); + } + scale(scaleX, scaleY, pivotX = 0, pivotY = 0) { + return this._saveToCmd(Render._context._scale, ScaleCmd.create.call(this, scaleX, scaleY, pivotX, pivotY)); + } + translate(tx, ty) { + return this._saveToCmd(Render._context.translate, TranslateCmd.create.call(this, tx, ty)); + } + save() { + return this._saveToCmd(Render._context._save, SaveCmd.create.call(this)); + } + restore() { + return this._saveToCmd(Render._context.restore, RestoreCmd.create.call(this)); + } + replaceText(text) { + this._repaint(); + var cmds = this._cmds; + if (!cmds) { + if (this._one && this._isTextCmd(this._one)) { + this._one.text = text; + return true; + } + } + else { + for (var i = cmds.length - 1; i > -1; i--) { + if (this._isTextCmd(cmds[i])) { + cmds[i].text = text; + return true; + } + } + } + return false; + } + _isTextCmd(cmd) { + var cmdID = cmd.cmdID; + return cmdID == FillTextCmd.ID; + } + replaceTextColor(color) { + this._repaint(); + var cmds = this._cmds; + if (!cmds) { + if (this._one && this._isTextCmd(this._one)) { + this._setTextCmdColor(this._one, color); + } + } + else { + for (var i = cmds.length - 1; i > -1; i--) { + if (this._isTextCmd(cmds[i])) { + this._setTextCmdColor(cmds[i], color); + } + } + } + } + _setTextCmdColor(cmdO, color) { + var cmdID = cmdO.cmdID; + switch (cmdID) { + case FillTextCmd.ID: + cmdO.color = color; + break; + } + } + loadImage(url, x = 0, y = 0, width = 0, height = 0, complete = null) { + var tex = ILaya.Loader.getRes(url); + if (!tex) { + tex = new Texture(); + tex.load(url); + ILaya.Loader.cacheTexture(url, tex); + tex.once(Event.READY, this, this.drawImage, [tex, x, y, width, height]); + } + else { + if (!tex.getIsReady()) { + tex.once(Event.READY, this, this.drawImage, [tex, x, y, width, height]); + } + else + this.drawImage(tex, x, y, width, height); + } + if (complete != null) { + tex.getIsReady() ? complete.call(this._sp) : tex.on(Event.READY, this._sp, complete); + } + } + _renderEmpty(sprite, context, x, y) { + } + _renderAll(sprite, context, x, y) { + var cmds = this._cmds; + for (var i = 0, n = cmds.length; i < n; i++) { + cmds[i].run(context, x, y); + } + } + _renderOne(sprite, context, x, y) { + context.sprite = sprite; + this._one.run(context, x, y); + } + _renderOneImg(sprite, context, x, y) { + context.sprite = sprite; + this._one.run(context, x, y); + } + drawLine(fromX, fromY, toX, toY, lineColor, lineWidth = 1) { + var offset = (lineWidth < 1 || lineWidth % 2 === 0) ? 0 : 0.5; + return this._saveToCmd(Render._context._drawLine, DrawLineCmd.create.call(this, fromX + offset, fromY + offset, toX + offset, toY + offset, lineColor, lineWidth, 0)); + } + drawLines(x, y, points, lineColor, lineWidth = 1) { + if (!points || points.length < 4) + return null; + var offset = (lineWidth < 1 || lineWidth % 2 === 0) ? 0 : 0.5; + return this._saveToCmd(Render._context._drawLines, DrawLinesCmd.create.call(this, x + offset, y + offset, points, lineColor, lineWidth, 0)); + } + drawCurves(x, y, points, lineColor, lineWidth = 1) { + return this._saveToCmd(Render._context.drawCurves, DrawCurvesCmd.create.call(this, x, y, points, lineColor, lineWidth)); + } + drawRect(x, y, width, height, fillColor, lineColor = null, lineWidth = 1) { + var offset = (lineWidth >= 1 && lineColor) ? lineWidth / 2 : 0; + var lineOffset = lineColor ? lineWidth : 0; + return this._saveToCmd(Render._context.drawRect, DrawRectCmd.create.call(this, x + offset, y + offset, width - lineOffset, height - lineOffset, fillColor, lineColor, lineWidth)); + } + drawCircle(x, y, radius, fillColor, lineColor = null, lineWidth = 1) { + var offset = (lineWidth >= 1 && lineColor) ? lineWidth / 2 : 0; + return this._saveToCmd(Render._context._drawCircle, DrawCircleCmd.create.call(this, x, y, radius - offset, fillColor, lineColor, lineWidth, 0)); + } + drawPie(x, y, radius, startAngle, endAngle, fillColor, lineColor = null, lineWidth = 1) { + var offset = (lineWidth >= 1 && lineColor) ? lineWidth / 2 : 0; + var lineOffset = lineColor ? lineWidth : 0; + return this._saveToCmd(Render._context._drawPie, DrawPieCmd.create.call(this, x + offset, y + offset, radius - lineOffset, Utils.toRadian(startAngle), Utils.toRadian(endAngle), fillColor, lineColor, lineWidth, 0)); + } + drawPoly(x, y, points, fillColor, lineColor = null, lineWidth = 1) { + var tIsConvexPolygon = false; + if (points.length > 6) { + tIsConvexPolygon = false; + } + else { + tIsConvexPolygon = true; + } + var offset = (lineWidth >= 1 && lineColor) ? (lineWidth % 2 === 0 ? 0 : 0.5) : 0; + return this._saveToCmd(Render._context._drawPoly, DrawPolyCmd.create.call(this, x + offset, y + offset, points, fillColor, lineColor, lineWidth, tIsConvexPolygon, 0)); + } + drawPath(x, y, paths, brush = null, pen = null) { + return this._saveToCmd(Render._context._drawPath, DrawPathCmd.create.call(this, x, y, paths, brush, pen)); + } + draw9Grid(texture, x = 0, y = 0, width = 0, height = 0, sizeGrid) { + this._saveToCmd(null, Draw9GridTexture.create(texture, x, y, width, height, sizeGrid)); + } + } + + class Const { + } + Const.NOT_ACTIVE = 0x01; + Const.ACTIVE_INHIERARCHY = 0x02; + Const.AWAKED = 0x04; + Const.NOT_READY = 0x08; + Const.DISPLAY = 0x10; + Const.HAS_ZORDER = 0x20; + Const.HAS_MOUSE = 0x40; + Const.DISPLAYED_INSTAGE = 0x80; + Const.DRAWCALL_OPTIMIZE = 0x100; + + class LayaGLQuickRunner { + static __init__() { + LayaGLQuickRunner.map[SpriteConst.ALPHA | SpriteConst.TRANSFORM | SpriteConst.GRAPHICS] = LayaGLQuickRunner.alpha_transform_drawLayaGL; + LayaGLQuickRunner.map[SpriteConst.ALPHA | SpriteConst.GRAPHICS] = LayaGLQuickRunner.alpha_drawLayaGL; + LayaGLQuickRunner.map[SpriteConst.TRANSFORM | SpriteConst.GRAPHICS] = LayaGLQuickRunner.transform_drawLayaGL; + LayaGLQuickRunner.map[SpriteConst.TRANSFORM | SpriteConst.CHILDS] = LayaGLQuickRunner.transform_drawNodes; + LayaGLQuickRunner.map[SpriteConst.ALPHA | SpriteConst.TRANSFORM | SpriteConst.TEXTURE] = LayaGLQuickRunner.alpha_transform_drawTexture; + LayaGLQuickRunner.map[SpriteConst.ALPHA | SpriteConst.TEXTURE] = LayaGLQuickRunner.alpha_drawTexture; + LayaGLQuickRunner.map[SpriteConst.TRANSFORM | SpriteConst.TEXTURE] = LayaGLQuickRunner.transform_drawTexture; + LayaGLQuickRunner.map[SpriteConst.GRAPHICS | SpriteConst.CHILDS] = LayaGLQuickRunner.drawLayaGL_drawNodes; + } + static transform_drawTexture(sprite, context, x, y) { + var style = sprite._style; + var tex = sprite.texture; + context.saveTransform(LayaGLQuickRunner.curMat); + context.transformByMatrix(sprite.transform, x, y); + var width = sprite._width || tex.sourceWidth; + var height = sprite._height || tex.sourceHeight; + var wRate = width / tex.sourceWidth; + var hRate = height / tex.sourceHeight; + width = tex.width * wRate; + height = tex.height * hRate; + if (width <= 0 || height <= 0) + return null; + var px = -sprite.pivotX + tex.offsetX * wRate; + var py = -sprite.pivotY + tex.offsetY * hRate; + context.drawTexture(tex, px, py, width, height); + context.restoreTransform(LayaGLQuickRunner.curMat); + } + static alpha_drawTexture(sprite, context, x, y) { + var style = sprite._style; + var alpha; + var tex = sprite.texture; + if ((alpha = style.alpha) > 0.01 || sprite._needRepaint()) { + var temp = context.globalAlpha; + context.globalAlpha *= alpha; + var width = sprite._width || tex.width; + var height = sprite._height || tex.height; + var wRate = width / tex.sourceWidth; + var hRate = height / tex.sourceHeight; + width = tex.width * wRate; + height = tex.height * hRate; + if (width <= 0 || height <= 0) + return null; + var px = x - style.pivotX + tex.offsetX * wRate; + var py = y - style.pivotY + tex.offsetY * hRate; + context.drawTexture(tex, px, py, width, height); + context.globalAlpha = temp; + } + } + static alpha_transform_drawTexture(sprite, context, x, y) { + var style = sprite._style; + var alpha; + var tex = sprite.texture; + if ((alpha = style.alpha) > 0.01 || sprite._needRepaint()) { + var temp = context.globalAlpha; + context.globalAlpha *= alpha; + context.saveTransform(LayaGLQuickRunner.curMat); + context.transformByMatrix(sprite.transform, x, y); + var width = sprite._width || tex.sourceWidth; + var height = sprite._height || tex.sourceHeight; + var wRate = width / tex.sourceWidth; + var hRate = height / tex.sourceHeight; + width = tex.width * wRate; + height = tex.height * hRate; + if (width <= 0 || height <= 0) + return null; + var px = -style.pivotX + tex.offsetX * wRate; + var py = -style.pivotY + tex.offsetY * hRate; + context.drawTexture(tex, px, py, width, height); + context.restoreTransform(LayaGLQuickRunner.curMat); + context.globalAlpha = temp; + } + } + static alpha_transform_drawLayaGL(sprite, context, x, y) { + var style = sprite._style; + var alpha; + if ((alpha = style.alpha) > 0.01 || sprite._needRepaint()) { + var temp = context.globalAlpha; + context.globalAlpha *= alpha; + context.saveTransform(LayaGLQuickRunner.curMat); + context.transformByMatrix(sprite.transform, x, y); + sprite._graphics && sprite._graphics._render(sprite, context, -style.pivotX, -style.pivotY); + context.restoreTransform(LayaGLQuickRunner.curMat); + context.globalAlpha = temp; + } + } + static alpha_drawLayaGL(sprite, context, x, y) { + var style = sprite._style; + var alpha; + if ((alpha = style.alpha) > 0.01 || sprite._needRepaint()) { + var temp = context.globalAlpha; + context.globalAlpha *= alpha; + sprite._graphics && sprite._graphics._render(sprite, context, x - style.pivotX, y - style.pivotY); + context.globalAlpha = temp; + } + } + static transform_drawLayaGL(sprite, context, x, y) { + var style = sprite._style; + context.saveTransform(LayaGLQuickRunner.curMat); + context.transformByMatrix(sprite.transform, x, y); + sprite._graphics && sprite._graphics._render(sprite, context, -style.pivotX, -style.pivotY); + context.restoreTransform(LayaGLQuickRunner.curMat); + } + static transform_drawNodes(sprite, context, x, y) { + var textLastRender = sprite._getBit(Const.DRAWCALL_OPTIMIZE) && context.drawCallOptimize(true); + var style = sprite._style; + context.saveTransform(LayaGLQuickRunner.curMat); + context.transformByMatrix(sprite.transform, x, y); + x = -style.pivotX; + y = -style.pivotY; + var childs = sprite._children, n = childs.length, ele; + if (style.viewport) { + var rect = style.viewport; + var left = rect.x; + var top = rect.y; + var right = rect.right; + var bottom = rect.bottom; + var _x, _y; + for (i = 0; i < n; ++i) { + if ((ele = childs[i])._visible && ((_x = ele._x) < right && (_x + ele.width) > left && (_y = ele._y) < bottom && (_y + ele.height) > top)) { + ele.render(context, x, y); + } + } + } + else { + for (var i = 0; i < n; ++i) + (ele = childs[i])._visible && ele.render(context, x, y); + } + context.restoreTransform(LayaGLQuickRunner.curMat); + textLastRender && context.drawCallOptimize(false); + } + static drawLayaGL_drawNodes(sprite, context, x, y) { + var textLastRender = sprite._getBit(Const.DRAWCALL_OPTIMIZE) && context.drawCallOptimize(true); + var style = sprite._style; + x = x - style.pivotX; + y = y - style.pivotY; + sprite._graphics && sprite._graphics._render(sprite, context, x, y); + var childs = sprite._children, n = childs.length, ele; + if (style.viewport) { + var rect = style.viewport; + var left = rect.x; + var top = rect.y; + var right = rect.right; + var bottom = rect.bottom; + var _x, _y; + for (i = 0; i < n; ++i) { + if ((ele = childs[i])._visible && ((_x = ele._x) < right && (_x + ele.width) > left && (_y = ele._y) < bottom && (_y + ele.height) > top)) { + ele.render(context, x, y); + } + } + } + else { + for (var i = 0; i < n; ++i) + (ele = childs[i])._visible && ele.render(context, x, y); + } + textLastRender && context.drawCallOptimize(false); + } + } + LayaGLQuickRunner.map = []; + LayaGLQuickRunner.curMat = new Matrix(); + + class RenderSprite { + constructor(type, next) { + if (LayaGLQuickRunner.map[type]) { + this._fun = LayaGLQuickRunner.map[type]; + this._next = RenderSprite.NORENDER; + return; + } + this._next = next || RenderSprite.NORENDER; + switch (type) { + case 0: + this._fun = this._no; + return; + case SpriteConst.ALPHA: + this._fun = this._alpha; + return; + case SpriteConst.TRANSFORM: + this._fun = this._transform; + return; + case SpriteConst.BLEND: + this._fun = this._blend; + return; + case SpriteConst.CANVAS: + this._fun = this._canvas; + return; + case SpriteConst.MASK: + this._fun = this._mask; + return; + case SpriteConst.CLIP: + this._fun = this._clip; + return; + case SpriteConst.STYLE: + this._fun = this._style; + return; + case SpriteConst.GRAPHICS: + this._fun = this._graphics; + return; + case SpriteConst.CHILDS: + this._fun = this._children; + return; + case SpriteConst.CUSTOM: + this._fun = this._custom; + return; + case SpriteConst.TEXTURE: + this._fun = this._texture; + return; + case SpriteConst.FILTERS: + this._fun = Filter._filter; + return; + case RenderSprite.INIT: + this._fun = RenderSprite._initRenderFun; + return; + } + this.onCreate(type); + } + static __init__() { + LayaGLQuickRunner.__init__(); + var i, len; + var initRender; + initRender = new RenderSprite(RenderSprite.INIT, null); + len = RenderSprite.renders.length = SpriteConst.CHILDS * 2; + for (i = 0; i < len; i++) + RenderSprite.renders[i] = initRender; + RenderSprite.renders[0] = new RenderSprite(0, null); + } + static _initRenderFun(sprite, context, x, y) { + var type = sprite._renderType; + var r = RenderSprite.renders[type] = RenderSprite._getTypeRender(type); + r._fun(sprite, context, x, y); + } + static _getTypeRender(type) { + if (LayaGLQuickRunner.map[type]) + return new RenderSprite(type, null); + var rst = null; + var tType = SpriteConst.CHILDS; + while (tType > 0) { + if (tType & type) + rst = new RenderSprite(tType, rst); + tType = tType >> 1; + } + return rst; + } + onCreate(type) { + } + _style(sprite, context, x, y) { + var style = sprite._style; + if (style.render != null) + style.render(sprite, context, x, y); + var next = this._next; + next._fun.call(next, sprite, context, x, y); + } + _no(sprite, context, x, y) { + } + _custom(sprite, context, x, y) { + sprite.customRender(context, x, y); + this._next._fun.call(this._next, sprite, context, 0, 0); + } + _clip(sprite, context, x, y) { + var next = this._next; + if (next == RenderSprite.NORENDER) + return; + var r = sprite._style.scrollRect; + var width = r.width; + var height = r.height; + if (width === 0 || height === 0) { + return; + } + context.save(); + context.clipRect(x, y, width, height); + next._fun.call(next, sprite, context, x - r.x, y - r.y); + context.restore(); + } + _texture(sprite, context, x, y) { + var tex = sprite.texture; + if (tex._getSource()) { + var width = sprite._width || tex.sourceWidth; + var height = sprite._height || tex.sourceHeight; + var wRate = width / tex.sourceWidth; + var hRate = height / tex.sourceHeight; + width = tex.width * wRate; + height = tex.height * hRate; + if (width <= 0 || height <= 0) + return; + var px = x - sprite.pivotX + tex.offsetX * wRate; + var py = y - sprite.pivotY + tex.offsetY * hRate; + context.drawTexture(tex, px, py, width, height); + } + var next = this._next; + if (next != RenderSprite.NORENDER) + next._fun.call(next, sprite, context, x, y); + } + _graphics(sprite, context, x, y) { + var style = sprite._style; + var g = sprite._graphics; + g && g._render(sprite, context, x - style.pivotX, y - style.pivotY); + var next = this._next; + if (next != RenderSprite.NORENDER) + next._fun.call(next, sprite, context, x, y); + } + _image(sprite, context, x, y) { + var style = sprite._style; + context.drawTexture2(x, y, style.pivotX, style.pivotY, sprite.transform, sprite._graphics._one); + } + _image2(sprite, context, x, y) { + var style = sprite._style; + context.drawTexture2(x, y, style.pivotX, style.pivotY, sprite.transform, sprite._graphics._one); + } + _alpha(sprite, context, x, y) { + var style = sprite._style; + var alpha; + if ((alpha = style.alpha) > 0.01 || sprite._needRepaint()) { + var temp = context.globalAlpha; + context.globalAlpha *= alpha; + var next = this._next; + next._fun.call(next, sprite, context, x, y); + context.globalAlpha = temp; + } + } + _transform(sprite, context, x, y) { + var transform = sprite.transform, _next = this._next; + var style = sprite._style; + if (transform && _next != RenderSprite.NORENDER) { + context.save(); + context.transform(transform.a, transform.b, transform.c, transform.d, transform.tx + x, transform.ty + y); + _next._fun.call(_next, sprite, context, 0, 0); + context.restore(); + } + else { + if (_next != RenderSprite.NORENDER) + _next._fun.call(_next, sprite, context, x, y); + } + } + _children(sprite, context, x, y) { + var style = sprite._style; + var childs = sprite._children, n = childs.length, ele; + x = x - sprite.pivotX; + y = y - sprite.pivotY; + var textLastRender = sprite._getBit(Const.DRAWCALL_OPTIMIZE) && context.drawCallOptimize(true); + if (style.viewport) { + var rect = style.viewport; + var left = rect.x; + var top = rect.y; + var right = rect.right; + var bottom = rect.bottom; + var _x, _y; + for (i = 0; i < n; ++i) { + if ((ele = childs[i])._visible && ((_x = ele._x) < right && (_x + ele.width) > left && (_y = ele._y) < bottom && (_y + ele.height) > top)) { + ele.render(context, x, y); + } + } + } + else { + for (var i = 0; i < n; ++i) + (ele = childs[i])._visible && ele.render(context, x, y); + } + textLastRender && context.drawCallOptimize(false); + } + _canvas(sprite, context, x, y) { + var _cacheStyle = sprite._cacheStyle; + var _next = this._next; + if (!_cacheStyle.enableCanvasRender) { + _next._fun.call(_next, sprite, context, x, y); + return; + } + _cacheStyle.cacheAs === 'bitmap' ? (Stat.canvasBitmap++) : (Stat.canvasNormal++); + var cacheNeedRebuild = false; + var textNeedRestore = false; + if (_cacheStyle.canvas) { + var canv = _cacheStyle.canvas; + var ctx = canv.context; + var charRIs = canv.touches; + if (charRIs) { + for (var ci = 0; ci < charRIs.length; ci++) { + if (charRIs[ci].deleted) { + textNeedRestore = true; + break; + } + } + } + cacheNeedRebuild = canv.isCacheValid && !canv.isCacheValid(); + } + if (sprite._needRepaint() || (!_cacheStyle.canvas) || textNeedRestore || cacheNeedRebuild || ILaya.stage.isGlobalRepaint()) { + if (_cacheStyle.cacheAs === 'normal') { + if (context._targets) { + _next._fun.call(_next, sprite, context, x, y); + return; + } + else { + this._canvas_webgl_normal_repaint(sprite, context); + } + } + else { + this._canvas_repaint(sprite, context, x, y); + } + } + var tRec = _cacheStyle.cacheRect; + context.drawCanvas(_cacheStyle.canvas, x + tRec.x, y + tRec.y, tRec.width, tRec.height); + } + _canvas_repaint(sprite, context, x, y) { + var _cacheStyle = sprite._cacheStyle; + var _next = this._next; + var tx; + var canvas = _cacheStyle.canvas; + var left; + var top; + var tRec; + var tCacheType = _cacheStyle.cacheAs; + var w, h; + var scaleX, scaleY; + var scaleInfo; + scaleInfo = _cacheStyle._calculateCacheRect(sprite, tCacheType, x, y); + scaleX = scaleInfo.x; + scaleY = scaleInfo.y; + tRec = _cacheStyle.cacheRect; + w = tRec.width * scaleX; + h = tRec.height * scaleY; + left = tRec.x; + top = tRec.y; + if (tCacheType === 'bitmap' && (w > 2048 || h > 2048)) { + console.warn("cache bitmap size larger than 2048,cache ignored"); + _cacheStyle.releaseContext(); + _next._fun.call(_next, sprite, context, x, y); + return; + } + if (!canvas) { + _cacheStyle.createContext(); + canvas = _cacheStyle.canvas; + } + tx = canvas.context; + tx.sprite = sprite; + (canvas.width != w || canvas.height != h) && canvas.size(w, h); + if (tCacheType === 'bitmap') + tx.asBitmap = true; + else if (tCacheType === 'normal') + tx.asBitmap = false; + tx.clear(); + if (scaleX != 1 || scaleY != 1) { + var ctx = tx; + ctx.save(); + ctx.scale(scaleX, scaleY); + _next._fun.call(_next, sprite, tx, -left, -top); + ctx.restore(); + sprite._applyFilters(); + } + else { + ctx = tx; + _next._fun.call(_next, sprite, tx, -left, -top); + sprite._applyFilters(); + } + if (_cacheStyle.staticCache) + _cacheStyle.reCache = false; + Stat.canvasReCache++; + } + _canvas_webgl_normal_repaint(sprite, context) { + var _cacheStyle = sprite._cacheStyle; + var _next = this._next; + var canvas = _cacheStyle.canvas; + var tCacheType = _cacheStyle.cacheAs; + _cacheStyle._calculateCacheRect(sprite, tCacheType, 0, 0); + if (!canvas) { + canvas = new WebGLCacheAsNormalCanvas(context, sprite); + _cacheStyle.canvas = canvas; + } + var tx = canvas.context; + canvas.startRec(); + _next._fun.call(_next, sprite, tx, sprite.pivotX, sprite.pivotY); + sprite._applyFilters(); + Stat.canvasReCache++; + canvas.endRec(); + } + _blend(sprite, context, x, y) { + var style = sprite._style; + var next = this._next; + if (style.blendMode) { + context.save(); + context.globalCompositeOperation = style.blendMode; + next._fun.call(next, sprite, context, x, y); + context.restore(); + } + else { + next._fun.call(next, sprite, context, x, y); + } + } + _mask(sprite, context, x, y) { + var next = this._next; + var mask = sprite.mask; + var ctx = context; + if (mask) { + ctx.save(); + var preBlendMode = ctx.globalCompositeOperation; + var tRect = new Rectangle(); + tRect.copyFrom(mask.getBounds()); + tRect.width = Math.round(tRect.width); + tRect.height = Math.round(tRect.height); + tRect.x = Math.round(tRect.x); + tRect.y = Math.round(tRect.y); + if (tRect.width > 0 && tRect.height > 0) { + var w = tRect.width; + var h = tRect.height; + var tmpRT = WebGLRTMgr.getRT(w, h); + ctx.breakNextMerge(); + ctx.pushRT(); + ctx.addRenderObject(SubmitCMD.create([ctx, tmpRT, w, h], RenderSprite.tmpTarget, this)); + mask.render(ctx, -tRect.x, -tRect.y); + ctx.breakNextMerge(); + ctx.popRT(); + ctx.save(); + let shrink = 0.1; + ctx.clipRect(x + tRect.x - sprite.getStyle().pivotX + shrink, y + tRect.y - sprite.getStyle().pivotY + shrink, w - shrink * 2, h - shrink * 2); + next._fun.call(next, sprite, ctx, x, y); + ctx.restore(); + preBlendMode = ctx.globalCompositeOperation; + ctx.addRenderObject(SubmitCMD.create(["mask"], RenderSprite.setBlendMode, this)); + var shaderValue = Value2D.create(ShaderDefines2D.TEXTURE2D, 0); + var uv = Texture.INV_UV; + ctx.drawTarget(tmpRT, x + tRect.x - sprite.getStyle().pivotX, y + tRect.y - sprite.getStyle().pivotY, w, h, Matrix.TEMP.identity(), shaderValue, uv, 6); + ctx.addRenderObject(SubmitCMD.create([tmpRT], RenderSprite.recycleTarget, this)); + ctx.addRenderObject(SubmitCMD.create([preBlendMode], RenderSprite.setBlendMode, this)); + } + ctx.restore(); + } + else { + next._fun.call(next, sprite, context, x, y); + } + } + static tmpTarget(ctx, rt, w, h) { + rt.start(); + rt.clear(0, 0, 0, 0); + } + static recycleTarget(rt) { + WebGLRTMgr.releaseRT(rt); + } + static setBlendMode(blendMode) { + var gl = WebGLContext.mainContext; + BlendMode.targetFns[BlendMode.TOINT[blendMode]](gl); + } + } + RenderSprite.INIT = 0x11111; + RenderSprite.renders = []; + RenderSprite.NORENDER = new RenderSprite(0, null); + RenderSprite.tempUV = new Array(8); + + class HTMLCanvas extends Bitmap { + constructor(createCanvas = false) { + super(); + if (createCanvas) + this._source = Browser.createElement("canvas"); + else { + this._source = this; + } + this.lock = true; + } + get source() { + return this._source; + } + _getSource() { + return this._source; + } + clear() { + if (this._ctx) { + if (this._ctx.clear) { + this._ctx.clear(); + } + else { + this._ctx.clearRect(0, 0, this._width, this._height); + } + } + if (this._texture) { + this._texture.destroy(); + this._texture = null; + } + } + destroy() { + super.destroy(); + this._setCPUMemory(0); + this._ctx && this._ctx.destroy && this._ctx.destroy(); + this._ctx = null; + } + release() { + } + get context() { + if (this._ctx) + return this._ctx; + if (this._source == this) { + this._ctx = new ILaya.Context(); + } + else { + this._ctx = this._source.getContext(ILaya.Render.isConchApp ? 'layagl' : '2d'); + } + this._ctx._canvas = this; + return this._ctx; + } + _setContext(context) { + this._ctx = context; + } + getContext(contextID, other = null) { + return this.context; + } + getMemSize() { + return 0; + } + size(w, h) { + if (this._width != w || this._height != h || (this._source && (this._source.width != w || this._source.height != h))) { + this._width = w; + this._height = h; + this._setCPUMemory(w * h * 4); + this._ctx && this._ctx.size && this._ctx.size(w, h); + if (this._source) { + this._source.height = h; + this._source.width = w; + } + if (this._texture) { + this._texture.destroy(); + this._texture = null; + } + } + } + getTexture() { + if (!this._texture) { + var bitmap = new Texture2D(); + bitmap.loadImageSource(this.source); + this._texture = new Texture(bitmap); + } + return this._texture; + } + toBase64(type, encoderOptions) { + if (this._source) { + if (ILaya.Render.isConchApp) { + var win = window; + if (win.conchConfig.threadMode == 2) { + throw "native 2 thread mode use toBase64Async"; + } + var width = this._ctx._targets.sourceWidth; + var height = this._ctx._targets.sourceHeight; + var data = this._ctx._targets.getData(0, 0, width, height); + return win.conchToBase64FlipY ? win.conchToBase64FlipY(type, encoderOptions, data.buffer, width, height) : win.conchToBase64(type, encoderOptions, data.buffer, width, height); + } + else { + return this._source.toDataURL(type, encoderOptions); + } + } + return null; + } + toBase64Async(type, encoderOptions, callBack) { + var width = this._ctx._targets.sourceWidth; + var height = this._ctx._targets.sourceHeight; + this._ctx._targets.getDataAsync(0, 0, width, height, function (data) { + let win = window; + var base64 = win.conchToBase64FlipY ? win.conchToBase64FlipY(type, encoderOptions, data.buffer, width, height) : win.conchToBase64(type, encoderOptions, data.buffer, width, height); + callBack(base64); + }); + } + } + + class HitArea { + contains(x, y) { + if (!HitArea._isHitGraphic(x, y, this.hit)) + return false; + return !HitArea._isHitGraphic(x, y, this.unHit); + } + static _isHitGraphic(x, y, graphic) { + if (!graphic) + return false; + var cmds = graphic.cmds; + if (!cmds && graphic._one) { + cmds = HitArea._cmds; + cmds.length = 1; + cmds[0] = graphic._one; + } + if (!cmds) + return false; + var i, len; + len = cmds.length; + var cmd; + for (i = 0; i < len; i++) { + cmd = cmds[i]; + if (!cmd) + continue; + switch (cmd.cmdID) { + case "Translate": + x -= cmd.tx; + y -= cmd.ty; + } + if (HitArea._isHitCmd(x, y, cmd)) + return true; + } + return false; + } + static _isHitCmd(x, y, cmd) { + if (!cmd) + return false; + var rst = false; + switch (cmd.cmdID) { + case "DrawRect": + HitArea._rect.setTo(cmd.x, cmd.y, cmd.width, cmd.height); + rst = HitArea._rect.contains(x, y); + break; + case "DrawCircle": + var d; + x -= cmd.x; + y -= cmd.y; + d = x * x + y * y; + rst = d < cmd.radius * cmd.radius; + break; + case "DrawPoly": + x -= cmd.x; + y -= cmd.y; + rst = HitArea._ptInPolygon(x, y, cmd.points); + break; + } + return rst; + } + static _ptInPolygon(x, y, areaPoints) { + var p = HitArea._ptPoint; + p.setTo(x, y); + var nCross = 0; + var p1x, p1y, p2x, p2y; + var len; + len = areaPoints.length; + for (var i = 0; i < len; i += 2) { + p1x = areaPoints[i]; + p1y = areaPoints[i + 1]; + p2x = areaPoints[(i + 2) % len]; + p2y = areaPoints[(i + 3) % len]; + if (p1y == p2y) + continue; + if (p.y < Math.min(p1y, p2y)) + continue; + if (p.y >= Math.max(p1y, p2y)) + continue; + var tx = (p.y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x; + if (tx > p.x) + nCross++; + } + return (nCross % 2 == 1); + } + get hit() { + if (!this._hit) + this._hit = new ILaya.Graphics(); + return this._hit; + } + set hit(value) { + this._hit = value; + } + get unHit() { + if (!this._unHit) + this._unHit = new ILaya.Graphics(); + return this._unHit; + } + set unHit(value) { + this._unHit = value; + } + } + HitArea._cmds = []; + HitArea._rect = new Rectangle(); + HitArea._ptPoint = new Point(); + + class ClassUtils { + static regClass(className, classDef) { + ClassUtils._classMap[className] = classDef; + } + static regShortClassName(classes) { + for (var i = 0; i < classes.length; i++) { + var classDef = classes[i]; + var className = classDef.name; + ClassUtils._classMap[className] = classDef; + } + } + static getRegClass(className) { + return ClassUtils._classMap[className]; + } + static getClass(className) { + var classObject = ClassUtils._classMap[className] || ClassUtils._classMap['Laya.' + className] || className; + var glaya = ILaya.Laya; + if (typeof (classObject) == 'string') + return (ILaya.__classMap[classObject] || glaya[className]); + return classObject; + } + static getInstance(className) { + var compClass = ClassUtils.getClass(className); + if (compClass) + return new compClass(); + else + console.warn("[error] Undefined class:", className); + return null; + } + static createByJson(json, node = null, root = null, customHandler = null, instanceHandler = null) { + if (typeof (json) == 'string') + json = JSON.parse(json); + var props = json.props; + if (!node) { + node = instanceHandler ? instanceHandler.runWith(json) : ClassUtils.getInstance(props.runtime || json.type); + if (!node) + return null; + } + var child = json.child; + if (child) { + for (var i = 0, n = child.length; i < n; i++) { + var data = child[i]; + if ((data.props.name === "render" || data.props.renderType === "render") && node["_$set_itemRender"]) + node.itemRender = data; + else { + if (data.type == "Graphic") { + ClassUtils._addGraphicsToSprite(data, node); + } + else if (ClassUtils._isDrawType(data.type)) { + ClassUtils._addGraphicToSprite(data, node, true); + } + else { + var tChild = ClassUtils.createByJson(data, null, root, customHandler, instanceHandler); + if (data.type === "Script") { + if ("owner" in tChild) { + tChild["owner"] = node; + } + else if ("target" in tChild) { + tChild["target"] = node; + } + } + else if (data.props.renderType == "mask") { + node.mask = tChild; + } + else { + node.addChild(tChild); + } + } + } + } + } + if (props) { + for (var prop in props) { + var value = props[prop]; + if (prop === "var" && root) { + root[value] = node; + } + else if (value instanceof Array && node[prop] instanceof Function) { + node[prop].apply(node, value); + } + else { + node[prop] = value; + } + } + } + if (customHandler && json.customProps) { + customHandler.runWith([node, json]); + } + if (node["created"]) + node.created(); + return node; + } + static _addGraphicsToSprite(graphicO, sprite) { + var graphics = graphicO.child; + if (!graphics || graphics.length < 1) + return; + var g = ClassUtils._getGraphicsFromSprite(graphicO, sprite); + var ox = 0; + var oy = 0; + if (graphicO.props) { + ox = ClassUtils._getObjVar(graphicO.props, "x", 0); + oy = ClassUtils._getObjVar(graphicO.props, "y", 0); + } + if (ox != 0 && oy != 0) { + g.translate(ox, oy); + } + var i, len; + len = graphics.length; + for (i = 0; i < len; i++) { + ClassUtils._addGraphicToGraphics(graphics[i], g); + } + if (ox != 0 && oy != 0) { + g.translate(-ox, -oy); + } + } + static _addGraphicToSprite(graphicO, sprite, isChild = false) { + var g = isChild ? ClassUtils._getGraphicsFromSprite(graphicO, sprite) : sprite.graphics; + ClassUtils._addGraphicToGraphics(graphicO, g); + } + static _getGraphicsFromSprite(dataO, sprite) { + if (!dataO || !dataO.props) + return sprite.graphics; + var propsName = dataO.props.renderType; + if (propsName === "hit" || propsName === "unHit") { + var hitArea = sprite._style.hitArea || (sprite.hitArea = new HitArea()); + if (!hitArea[propsName]) { + hitArea[propsName] = new Graphics(); + } + var g = hitArea[propsName]; + } + if (!g) + g = sprite.graphics; + return g; + } + static _getTransformData(propsO) { + var m; + if ("pivotX" in propsO || "pivotY" in propsO) { + m = m || new Matrix(); + m.translate(-ClassUtils._getObjVar(propsO, "pivotX", 0), -ClassUtils._getObjVar(propsO, "pivotY", 0)); + } + var sx = ClassUtils._getObjVar(propsO, "scaleX", 1), sy = ClassUtils._getObjVar(propsO, "scaleY", 1); + var rotate = ClassUtils._getObjVar(propsO, "rotation", 0); + var skewX = ClassUtils._getObjVar(propsO, "skewX", 0); + var skewY = ClassUtils._getObjVar(propsO, "skewY", 0); + if (sx != 1 || sy != 1 || rotate != 0) { + m = m || new Matrix(); + m.scale(sx, sy); + m.rotate(rotate * 0.0174532922222222); + } + return m; + } + static _addGraphicToGraphics(graphicO, graphic) { + var propsO; + propsO = graphicO.props; + if (!propsO) + return; + var drawConfig; + drawConfig = ClassUtils.DrawTypeDic[graphicO.type]; + if (!drawConfig) + return; + var g = graphic; + var params = ClassUtils._getParams(propsO, drawConfig[1], drawConfig[2], drawConfig[3]); + var m = ClassUtils._tM; + if (m || ClassUtils._alpha != 1) { + g.save(); + if (m) + g.transform(m); + if (ClassUtils._alpha != 1) + g.alpha(ClassUtils._alpha); + } + g[drawConfig[0]].apply(g, params); + if (m || ClassUtils._alpha != 1) { + g.restore(); + } + } + static _adptLineData(params) { + params[2] = parseFloat(params[0]) + parseFloat(params[2]); + params[3] = parseFloat(params[1]) + parseFloat(params[3]); + return params; + } + static _adptTextureData(params) { + params[0] = ILaya.Loader.getRes(params[0]); + return params; + } + static _adptLinesData(params) { + params[2] = ClassUtils._getPointListByStr(params[2]); + return params; + } + static _isDrawType(type) { + if (type === "Image") + return false; + return type in ClassUtils.DrawTypeDic; + } + static _getParams(obj, params, xPos = 0, adptFun = null) { + var rst = ClassUtils._temParam; + rst.length = params.length; + var i, len; + len = params.length; + for (i = 0; i < len; i++) { + rst[i] = ClassUtils._getObjVar(obj, params[i][0], params[i][1]); + } + ClassUtils._alpha = ClassUtils._getObjVar(obj, "alpha", 1); + var m; + m = ClassUtils._getTransformData(obj); + if (m) { + if (!xPos) + xPos = 0; + m.translate(rst[xPos], rst[xPos + 1]); + rst[xPos] = rst[xPos + 1] = 0; + ClassUtils._tM = m; + } + else { + ClassUtils._tM = null; + } + if (adptFun && ClassUtils[adptFun]) { + rst = ClassUtils[adptFun](rst); + } + return rst; + } + static _getPointListByStr(str) { + var pointArr = str.split(","); + var i, len; + len = pointArr.length; + for (i = 0; i < len; i++) { + pointArr[i] = parseFloat(pointArr[i]); + } + return pointArr; + } + static _getObjVar(obj, key, noValue) { + if (key in obj) { + return obj[key]; + } + return noValue; + } + } + ClassUtils.DrawTypeDic = { "Rect": ["drawRect", [["x", 0], ["y", 0], ["width", 0], ["height", 0], ["fillColor", null], ["lineColor", null], ["lineWidth", 1]]], "Circle": ["drawCircle", [["x", 0], ["y", 0], ["radius", 0], ["fillColor", null], ["lineColor", null], ["lineWidth", 1]]], "Pie": ["drawPie", [["x", 0], ["y", 0], ["radius", 0], ["startAngle", 0], ["endAngle", 0], ["fillColor", null], ["lineColor", null], ["lineWidth", 1]]], "Image": ["drawTexture", [["x", 0], ["y", 0], ["width", 0], ["height", 0]]], "Texture": ["drawTexture", [["skin", null], ["x", 0], ["y", 0], ["width", 0], ["height", 0]], 1, "_adptTextureData"], "FillTexture": ["fillTexture", [["skin", null], ["x", 0], ["y", 0], ["width", 0], ["height", 0], ["repeat", null]], 1, "_adptTextureData"], "FillText": ["fillText", [["text", ""], ["x", 0], ["y", 0], ["font", null], ["color", null], ["textAlign", null]], 1], "Line": ["drawLine", [["x", 0], ["y", 0], ["toX", 0], ["toY", 0], ["lineColor", null], ["lineWidth", 0]], 0, "_adptLineData"], "Lines": ["drawLines", [["x", 0], ["y", 0], ["points", ""], ["lineColor", null], ["lineWidth", 0]], 0, "_adptLinesData"], "Curves": ["drawCurves", [["x", 0], ["y", 0], ["points", ""], ["lineColor", null], ["lineWidth", 0]], 0, "_adptLinesData"], "Poly": ["drawPoly", [["x", 0], ["y", 0], ["points", ""], ["fillColor", null], ["lineColor", null], ["lineWidth", 1]], 0, "_adptLinesData"] }; + ClassUtils._temParam = []; + ClassUtils._classMap = {}; + + class BoundsStyle { + reset() { + if (this.bounds) + this.bounds.recover(); + if (this.userBounds) + this.userBounds.recover(); + this.bounds = null; + this.userBounds = null; + this.temBM = null; + return this; + } + recover() { + Pool.recover("BoundsStyle", this.reset()); + } + static create() { + return Pool.getItemByClass("BoundsStyle", BoundsStyle); + } + } + + class CacheStyle { + constructor() { + this.reset(); + } + needBitmapCache() { + return this.cacheForFilters || !!this.mask; + } + needEnableCanvasRender() { + return this.userSetCache != "none" || this.cacheForFilters || !!this.mask; + } + releaseContext() { + if (this.canvas && this.canvas.size) { + Pool.recover("CacheCanvas", this.canvas); + this.canvas.size(0, 0); + try { + this.canvas.width = 0; + this.canvas.height = 0; + } + catch (e) { + } + } + this.canvas = null; + } + createContext() { + if (!this.canvas) { + this.canvas = Pool.getItem("CacheCanvas") || new HTMLCanvas(false); + var tx = this.canvas.context; + if (!tx) { + tx = this.canvas.getContext('2d'); + } + } + } + releaseFilterCache() { + var fc = this.filterCache; + if (fc) { + fc.destroy(); + fc.recycle(); + this.filterCache = null; + } + } + recover() { + if (this === CacheStyle.EMPTY) + return; + Pool.recover("SpriteCache", this.reset()); + } + reset() { + this.releaseContext(); + this.releaseFilterCache(); + this.cacheAs = "none"; + this.enableCanvasRender = false; + this.userSetCache = "none"; + this.cacheForFilters = false; + this.staticCache = false; + this.reCache = true; + this.mask = null; + this.maskParent = null; + this.filterCache = null; + this.filters = null; + this.hasGlowFilter = false; + if (this.cacheRect) + this.cacheRect.recover(); + this.cacheRect = null; + return this; + } + static create() { + return Pool.getItemByClass("SpriteCache", CacheStyle); + } + _calculateCacheRect(sprite, tCacheType, x, y) { + var _cacheStyle = sprite._cacheStyle; + if (!_cacheStyle.cacheRect) + _cacheStyle.cacheRect = Rectangle.create(); + var tRec; + if (tCacheType === "bitmap") { + tRec = sprite.getSelfBounds(); + tRec.width = tRec.width + CacheStyle.CANVAS_EXTEND_EDGE * 2; + tRec.height = tRec.height + CacheStyle.CANVAS_EXTEND_EDGE * 2; + tRec.x = tRec.x - sprite.pivotX; + tRec.y = tRec.y - sprite.pivotY; + tRec.x = tRec.x - CacheStyle.CANVAS_EXTEND_EDGE; + tRec.y = tRec.y - CacheStyle.CANVAS_EXTEND_EDGE; + tRec.x = Math.floor(tRec.x + x) - x; + tRec.y = Math.floor(tRec.y + y) - y; + tRec.width = Math.floor(tRec.width); + tRec.height = Math.floor(tRec.height); + _cacheStyle.cacheRect.copyFrom(tRec); + } + else { + _cacheStyle.cacheRect.setTo(-sprite._style.pivotX, -sprite._style.pivotY, 1, 1); + } + tRec = _cacheStyle.cacheRect; + if (sprite._style.scrollRect) { + var scrollRect = sprite._style.scrollRect; + tRec.x -= scrollRect.x; + tRec.y -= scrollRect.y; + } + CacheStyle._scaleInfo.setTo(1, 1); + return CacheStyle._scaleInfo; + } + } + CacheStyle.EMPTY = new CacheStyle(); + CacheStyle._scaleInfo = new Point(); + CacheStyle.CANVAS_EXTEND_EDGE = 16; + + class SpriteStyle { + constructor() { + this.reset(); + } + reset() { + this.scaleX = this.scaleY = 1; + this.skewX = this.skewY = 0; + this.pivotX = this.pivotY = this.rotation = 0; + this.alpha = 1; + if (this.scrollRect) + this.scrollRect.recover(); + this.scrollRect = null; + if (this.viewport) + this.viewport.recover(); + this.viewport = null; + this.hitArea = null; + this.dragging = null; + this.blendMode = null; + return this; + } + recover() { + if (this === SpriteStyle.EMPTY) + return; + Pool.recover("SpriteStyle", this.reset()); + } + static create() { + return Pool.getItemByClass("SpriteStyle", SpriteStyle); + } + } + SpriteStyle.EMPTY = new SpriteStyle(); + + class Node extends EventDispatcher { + constructor() { + super(); + this._bits = 0; + this._children = Node.ARRAY_EMPTY; + this._extUIChild = Node.ARRAY_EMPTY; + this._parent = null; + this.name = ""; + this.destroyed = false; + this.createGLBuffer(); + } + createGLBuffer() { + } + _setBit(type, value) { + if (type === Const.DISPLAY) { + var preValue = this._getBit(type); + if (preValue != value) + this._updateDisplayedInstage(); + } + if (value) + this._bits |= type; + else + this._bits &= ~type; + } + _getBit(type) { + return (this._bits & type) != 0; + } + _setUpNoticeChain() { + if (this._getBit(Const.DISPLAY)) + this._setBitUp(Const.DISPLAY); + } + _setBitUp(type) { + var ele = this; + ele._setBit(type, true); + ele = ele._parent; + while (ele) { + if (ele._getBit(type)) + return; + ele._setBit(type, true); + ele = ele._parent; + } + } + on(type, caller, listener, args = null) { + if (type === Event.DISPLAY || type === Event.UNDISPLAY) { + if (!this._getBit(Const.DISPLAY)) + this._setBitUp(Const.DISPLAY); + } + return this._createListener(type, caller, listener, args, false); + } + once(type, caller, listener, args = null) { + if (type === Event.DISPLAY || type === Event.UNDISPLAY) { + if (!this._getBit(Const.DISPLAY)) + this._setBitUp(Const.DISPLAY); + } + return this._createListener(type, caller, listener, args, true); + } + destroy(destroyChild = true) { + this.destroyed = true; + this._destroyAllComponent(); + this._parent && this._parent.removeChild(this); + if (this._children) { + if (destroyChild) + this.destroyChildren(); + else + this.removeChildren(); + } + this.onDestroy(); + this._children = null; + this.offAll(); + } + onDestroy() { + } + destroyChildren() { + if (this._children) { + for (var i = 0, n = this._children.length; i < n; i++) { + this._children[0].destroy(true); + } + } + } + addChild(node) { + if (!node || this.destroyed || node === this) + return node; + if (node._zOrder) + this._setBit(Const.HAS_ZORDER, true); + if (node._parent === this) { + var index = this.getChildIndex(node); + if (index !== this._children.length - 1) { + this._children.splice(index, 1); + this._children.push(node); + this._childChanged(); + } + } + else { + node._parent && node._parent.removeChild(node); + this._children === Node.ARRAY_EMPTY && (this._children = []); + this._children.push(node); + node._setParent(this); + this._childChanged(); + } + return node; + } + addInputChild(node) { + if (this._extUIChild == Node.ARRAY_EMPTY) { + this._extUIChild = [node]; + } + else { + if (this._extUIChild.indexOf(node) >= 0) { + return null; + } + this._extUIChild.push(node); + } + return null; + } + removeInputChild(node) { + var idx = this._extUIChild.indexOf(node); + if (idx >= 0) { + this._extUIChild.splice(idx, 1); + } + } + addChildren(...args) { + var i = 0, n = args.length; + while (i < n) { + this.addChild(args[i++]); + } + } + addChildAt(node, index) { + if (!node || this.destroyed || node === this) + return node; + if (node._zOrder) + this._setBit(Const.HAS_ZORDER, true); + if (index >= 0 && index <= this._children.length) { + if (node._parent === this) { + var oldIndex = this.getChildIndex(node); + this._children.splice(oldIndex, 1); + this._children.splice(index, 0, node); + this._childChanged(); + } + else { + node._parent && node._parent.removeChild(node); + this._children === Node.ARRAY_EMPTY && (this._children = []); + this._children.splice(index, 0, node); + node._setParent(this); + } + return node; + } + else { + throw new Error("appendChildAt:The index is out of bounds"); + } + } + getChildIndex(node) { + return this._children.indexOf(node); + } + getChildByName(name) { + var nodes = this._children; + if (nodes) { + for (var i = 0, n = nodes.length; i < n; i++) { + var node = nodes[i]; + if (node.name === name) + return node; + } + } + return null; + } + getChildAt(index) { + return this._children[index] || null; + } + setChildIndex(node, index) { + var childs = this._children; + if (index < 0 || index >= childs.length) { + throw new Error("setChildIndex:The index is out of bounds."); + } + var oldIndex = this.getChildIndex(node); + if (oldIndex < 0) + throw new Error("setChildIndex:node is must child of this object."); + childs.splice(oldIndex, 1); + childs.splice(index, 0, node); + this._childChanged(); + return node; + } + _childChanged(child = null) { + } + removeChild(node) { + if (!this._children) + return node; + var index = this._children.indexOf(node); + return this.removeChildAt(index); + } + removeSelf() { + this._parent && this._parent.removeChild(this); + return this; + } + removeChildByName(name) { + var node = this.getChildByName(name); + node && this.removeChild(node); + return node; + } + removeChildAt(index) { + var node = this.getChildAt(index); + if (node) { + this._children.splice(index, 1); + node._setParent(null); + } + return node; + } + removeChildren(beginIndex = 0, endIndex = 0x7fffffff) { + if (this._children && this._children.length > 0) { + var childs = this._children; + if (beginIndex === 0 && endIndex >= childs.length - 1) { + var arr = childs; + this._children = Node.ARRAY_EMPTY; + } + else { + arr = childs.splice(beginIndex, endIndex - beginIndex + 1); + } + for (var i = 0, n = arr.length; i < n; i++) { + arr[i]._setParent(null); + } + } + return this; + } + replaceChild(newNode, oldNode) { + var index = this._children.indexOf(oldNode); + if (index > -1) { + this._children.splice(index, 1, newNode); + oldNode._setParent(null); + newNode._setParent(this); + return newNode; + } + return null; + } + get numChildren() { + return this._children.length; + } + get parent() { + return this._parent; + } + _setParent(value) { + if (this._parent !== value) { + if (value) { + this._parent = value; + this._onAdded(); + this.event(Event.ADDED); + if (this._getBit(Const.DISPLAY)) { + this._setUpNoticeChain(); + value.displayedInStage && this._displayChild(this, true); + } + value._childChanged(this); + } + else { + this._onRemoved(); + this.event(Event.REMOVED); + this._parent._childChanged(); + if (this._getBit(Const.DISPLAY)) + this._displayChild(this, false); + this._parent = value; + } + } + } + get displayedInStage() { + if (this._getBit(Const.DISPLAY)) + return this._getBit(Const.DISPLAYED_INSTAGE); + this._setBitUp(Const.DISPLAY); + return this._getBit(Const.DISPLAYED_INSTAGE); + } + _updateDisplayedInstage() { + var ele; + ele = this; + var stage = ILaya.stage; + var displayedInStage = false; + while (ele) { + if (ele._getBit(Const.DISPLAY)) { + displayedInStage = ele._getBit(Const.DISPLAYED_INSTAGE); + break; + } + if (ele === stage || ele._getBit(Const.DISPLAYED_INSTAGE)) { + displayedInStage = true; + break; + } + ele = ele._parent; + } + this._setBit(Const.DISPLAYED_INSTAGE, displayedInStage); + } + _setDisplay(value) { + if (this._getBit(Const.DISPLAYED_INSTAGE) !== value) { + this._setBit(Const.DISPLAYED_INSTAGE, value); + if (value) + this.event(Event.DISPLAY); + else + this.event(Event.UNDISPLAY); + } + } + _displayChild(node, display) { + var childs = node._children; + if (childs) { + for (var i = 0, n = childs.length; i < n; i++) { + var child = childs[i]; + if (!child._getBit(Const.DISPLAY)) + continue; + if (child._children.length > 0) { + this._displayChild(child, display); + } + else { + child._setDisplay(display); + } + } + } + node._setDisplay(display); + } + contains(node) { + if (node === this) + return true; + while (node) { + if (node._parent === this) + return true; + node = node._parent; + } + return false; + } + timerLoop(delay, caller, method, args = null, coverBefore = true, jumpFrame = false) { + var timer = this.scene ? this.scene.timer : ILaya.timer; + timer.loop(delay, caller, method, args, coverBefore, jumpFrame); + } + timerOnce(delay, caller, method, args = null, coverBefore = true) { + var timer = this.scene ? this.scene.timer : ILaya.timer; + timer._create(false, false, delay, caller, method, args, coverBefore); + } + frameLoop(delay, caller, method, args = null, coverBefore = true) { + var timer = this.scene ? this.scene.timer : ILaya.timer; + timer._create(true, true, delay, caller, method, args, coverBefore); + } + frameOnce(delay, caller, method, args = null, coverBefore = true) { + var timer = this.scene ? this.scene.timer : ILaya.timer; + timer._create(true, false, delay, caller, method, args, coverBefore); + } + clearTimer(caller, method) { + var timer = this.scene ? this.scene.timer : ILaya.timer; + timer.clear(caller, method); + } + callLater(method, args = null) { + var timer = this.scene ? this.scene.timer : ILaya.timer; + timer.callLater(this, method, args); + } + runCallLater(method) { + var timer = this.scene ? this.scene.timer : ILaya.timer; + timer.runCallLater(this, method); + } + get scene() { + return this._scene; + } + get active() { + return !this._getBit(Const.NOT_READY) && !this._getBit(Const.NOT_ACTIVE); + } + set active(value) { + value = !!value; + if (!this._getBit(Const.NOT_ACTIVE) !== value) { + if (this._activeChangeScripts && this._activeChangeScripts.length !== 0) { + if (value) + throw "Node: can't set the main inActive node active in hierarchy,if the operate is in main inActive node or it's children script's onDisable Event."; + else + throw "Node: can't set the main active node inActive in hierarchy,if the operate is in main active node or it's children script's onEnable Event."; + } + else { + this._setBit(Const.NOT_ACTIVE, !value); + if (this._parent) { + if (this._parent.activeInHierarchy) { + if (value) + this._processActive(); + else + this._processInActive(); + } + } + } + } + } + get activeInHierarchy() { + return this._getBit(Const.ACTIVE_INHIERARCHY); + } + _onActive() { + Stat.spriteCount++; + } + _onInActive() { + Stat.spriteCount--; + } + _onActiveInScene() { + } + _onInActiveInScene() { + } + _parse(data, spriteMap) { + } + _setBelongScene(scene) { + if (!this._scene) { + this._scene = scene; + this._onActiveInScene(); + for (var i = 0, n = this._children.length; i < n; i++) + this._children[i]._setBelongScene(scene); + } + } + _setUnBelongScene() { + if (this._scene !== this) { + this._onInActiveInScene(); + this._scene = null; + for (var i = 0, n = this._children.length; i < n; i++) + this._children[i]._setUnBelongScene(); + } + } + onAwake() { + } + onEnable() { + } + _processActive() { + (this._activeChangeScripts) || (this._activeChangeScripts = []); + this._activeHierarchy(this._activeChangeScripts); + this._activeScripts(); + } + _activeHierarchy(activeChangeScripts) { + this._setBit(Const.ACTIVE_INHIERARCHY, true); + if (this._components) { + for (var i = 0, n = this._components.length; i < n; i++) { + var comp = this._components[i]; + if (comp._isScript()) + (comp._enabled) && (activeChangeScripts.push(comp)); + else + comp._setActive(true); + } + } + this._onActive(); + for (i = 0, n = this._children.length; i < n; i++) { + var child = this._children[i]; + (!child._getBit(Const.NOT_ACTIVE) && !child._getBit(Const.NOT_READY)) && (child._activeHierarchy(activeChangeScripts)); + } + if (!this._getBit(Const.AWAKED)) { + this._setBit(Const.AWAKED, true); + this.onAwake(); + } + this.onEnable(); + } + _activeScripts() { + for (var i = 0, n = this._activeChangeScripts.length; i < n; i++) { + var comp = this._activeChangeScripts[i]; + if (!comp._awaked) { + comp._awaked = true; + comp._onAwake(); + } + comp._onEnable(); + } + this._activeChangeScripts.length = 0; + } + _processInActive() { + (this._activeChangeScripts) || (this._activeChangeScripts = []); + this._inActiveHierarchy(this._activeChangeScripts); + this._inActiveScripts(); + } + _inActiveHierarchy(activeChangeScripts) { + this._onInActive(); + if (this._components) { + for (var i = 0, n = this._components.length; i < n; i++) { + var comp = this._components[i]; + (!comp._isScript()) && comp._setActive(false); + (comp._isScript() && comp._enabled) && (activeChangeScripts.push(comp)); + } + } + this._setBit(Const.ACTIVE_INHIERARCHY, false); + for (i = 0, n = this._children.length; i < n; i++) { + var child = this._children[i]; + (child && !child._getBit(Const.NOT_ACTIVE)) && (child._inActiveHierarchy(activeChangeScripts)); + } + this.onDisable(); + } + _inActiveScripts() { + for (var i = 0, n = this._activeChangeScripts.length; i < n; i++) + ((this._activeChangeScripts[i]).owner) && this._activeChangeScripts[i]._onDisable(); + this._activeChangeScripts.length = 0; + } + onDisable() { + } + _onAdded() { + if (this._activeChangeScripts && this._activeChangeScripts.length !== 0) { + throw "Node: can't set the main inActive node active in hierarchy,if the operate is in main inActive node or it's children script's onDisable Event."; + } + else { + var parentScene = this._parent.scene; + parentScene && this._setBelongScene(parentScene); + (this._parent.activeInHierarchy && this.active) && this._processActive(); + } + } + _onRemoved() { + if (this._activeChangeScripts && this._activeChangeScripts.length !== 0) { + throw "Node: can't set the main active node inActive in hierarchy,if the operate is in main active node or it's children script's onEnable Event."; + } + else { + (this._parent.activeInHierarchy && this.active) && this._processInActive(); + this._parent.scene && this._setUnBelongScene(); + } + } + _addComponentInstance(comp) { + this._components = this._components || []; + this._components.push(comp); + comp.owner = this; + comp._onAdded(); + if (this.activeInHierarchy) + comp._setActive(true); + } + _destroyComponent(comp) { + if (this._components) { + for (var i = 0, n = this._components.length; i < n; i++) { + var item = this._components[i]; + if (item === comp) { + item._destroy(); + this._components.splice(i, 1); + break; + } + } + } + } + _destroyAllComponent() { + if (this._components) { + for (var i = 0, n = this._components.length; i < n; i++) { + var item = this._components[i]; + item && item._destroy(); + } + this._components.length = 0; + } + } + _cloneTo(destObject, srcRoot, dstRoot) { + var destNode = destObject; + if (this._components) { + for (var i = 0, n = this._components.length; i < n; i++) { + var destComponent = destNode.addComponent(this._components[i].constructor); + this._components[i]._cloneTo(destComponent); + } + } + } + addComponentIntance(component) { + if (component.owner) + throw "Node:the component has belong to other node."; + if (component.isSingleton && this.getComponent(component.constructor)) + throw "Node:the component is singleton,can't add the second one."; + this._addComponentInstance(component); + return component; + } + addComponent(componentType) { + var comp = Pool.createByClass(componentType); + if (!comp) { + throw componentType.toString() + "组件不存在"; + } + comp._destroyed = false; + if (comp.isSingleton && this.getComponent(componentType)) + throw "无法实例" + componentType + "组件" + "," + componentType + "组件已存在!"; + this._addComponentInstance(comp); + return comp; + } + getComponent(componentType) { + if (this._components) { + for (var i = 0, n = this._components.length; i < n; i++) { + var comp = this._components[i]; + if (comp instanceof componentType) + return comp; + } + } + return null; + } + getComponents(componentType) { + var arr; + if (this._components) { + for (var i = 0, n = this._components.length; i < n; i++) { + var comp = this._components[i]; + if (comp instanceof componentType) { + arr = arr || []; + arr.push(comp); + } + } + } + return arr; + } + get timer() { + return this.scene ? this.scene.timer : ILaya.timer; + } + } + Node.ARRAY_EMPTY = []; + ClassUtils.regClass("laya.display.Node", Node); + ClassUtils.regClass("Laya.Node", Node); + + class Sprite extends Node { + constructor() { + super(); + this._x = 0; + this._y = 0; + this._width = 0; + this._height = 0; + this._visible = true; + this._mouseState = 0; + this._zOrder = 0; + this._renderType = 0; + this._transform = null; + this._tfChanged = false; + this._repaint = SpriteConst.REPAINT_NONE; + this._texture = null; + this._style = SpriteStyle.EMPTY; + this._cacheStyle = CacheStyle.EMPTY; + this._boundStyle = null; + this._graphics = null; + this.mouseThrough = false; + this.autoSize = false; + this.hitTestPrior = false; + } + destroy(destroyChild = true) { + super.destroy(destroyChild); + this._style && this._style.recover(); + this._cacheStyle && this._cacheStyle.recover(); + this._boundStyle && this._boundStyle.recover(); + this._transform && this._transform.recover(); + this._style = null; + this._cacheStyle = null; + this._boundStyle = null; + this._transform = null; + if (this._graphics && this._graphics.autoDestroy) { + this._graphics.destroy(); + } + this._graphics = null; + this.texture = null; + } + updateZOrder() { + Utils.updateOrder(this._children) && this.repaint(); + } + _getBoundsStyle() { + if (!this._boundStyle) + this._boundStyle = BoundsStyle.create(); + return this._boundStyle; + } + _setCustomRender() { + } + set customRenderEnable(b) { + if (b) { + this._renderType |= SpriteConst.CUSTOM; + this._setRenderType(this._renderType); + this._setCustomRender(); + } + } + get cacheAs() { + return this._cacheStyle.cacheAs; + } + _setCacheAs(value) { + } + set cacheAs(value) { + if (value === this._cacheStyle.userSetCache) + return; + if (this.mask && value === 'normal') + return; + this._setCacheAs(value); + this._getCacheStyle().userSetCache = value; + this._checkCanvasEnable(); + this.repaint(); + } + _checkCanvasEnable() { + var tEnable = this._cacheStyle.needEnableCanvasRender(); + this._getCacheStyle().enableCanvasRender = tEnable; + if (tEnable) { + if (this._cacheStyle.needBitmapCache()) { + this._cacheStyle.cacheAs = "bitmap"; + } + else { + this._cacheStyle.cacheAs = this._cacheStyle.userSetCache; + } + this._cacheStyle.reCache = true; + this._renderType |= SpriteConst.CANVAS; + } + else { + this._cacheStyle.cacheAs = "none"; + this._cacheStyle.releaseContext(); + this._renderType &= ~SpriteConst.CANVAS; + } + this._setCacheAs(this._cacheStyle.cacheAs); + this._setRenderType(this._renderType); + } + get staticCache() { + return this._cacheStyle.staticCache; + } + set staticCache(value) { + this._getCacheStyle().staticCache = value; + if (!value) + this.reCache(); + } + reCache() { + this._cacheStyle.reCache = true; + this._repaint |= SpriteConst.REPAINT_CACHE; + } + getRepaint() { + return this._repaint; + } + _setX(value) { + this._x = value; + } + _setY(value) { + this._y = value; + } + _setWidth(texture, value) { + } + _setHeight(texture, value) { + } + get x() { + return this._x; + } + set x(value) { + if (this.destroyed) + return; + if (this._x !== value) { + this._setX(value); + this.parentRepaint(SpriteConst.REPAINT_CACHE); + var p = this._cacheStyle.maskParent; + if (p) { + p.repaint(SpriteConst.REPAINT_CACHE); + } + } + } + get y() { + return this._y; + } + set y(value) { + if (this.destroyed) + return; + if (this._y !== value) { + this._setY(value); + this.parentRepaint(SpriteConst.REPAINT_CACHE); + var p = this._cacheStyle.maskParent; + if (p) { + p.repaint(SpriteConst.REPAINT_CACHE); + } + } + } + get width() { + return this.get_width(); + } + set width(value) { + this.set_width(value); + } + set_width(value) { + if (this._width !== value) { + this._width = value; + this._setWidth(this.texture, value); + this._setTranformChange(); + } + } + get_width() { + if (!this.autoSize) + return this._width || (this.texture ? this.texture.width : 0); + if (this.texture) + return this.texture.width; + if (!this._graphics && this._children.length === 0) + return 0; + return this.getSelfBounds().width; + } + get height() { + return this.get_height(); + } + set height(value) { + this.set_height(value); + } + set_height(value) { + if (this._height !== value) { + this._height = value; + this._setHeight(this.texture, value); + this._setTranformChange(); + } + } + get_height() { + if (!this.autoSize) + return this._height || (this.texture ? this.texture.height : 0); + if (this.texture) + return this.texture.height; + if (!this._graphics && this._children.length === 0) + return 0; + return this.getSelfBounds().height; + } + get displayWidth() { + return this.width * this.scaleX; + } + get displayHeight() { + return this.height * this.scaleY; + } + setSelfBounds(bound) { + this._getBoundsStyle().userBounds = bound; + } + getBounds() { + return this._getBoundsStyle().bounds = Rectangle._getWrapRec(this._boundPointsToParent()); + } + getSelfBounds() { + if (this._boundStyle && this._boundStyle.userBounds) + return this._boundStyle.userBounds; + if (!this._graphics && this._children.length === 0 && !this._texture) + return Rectangle.TEMP.setTo(0, 0, this.width, this.height); + return this._getBoundsStyle().bounds = Rectangle._getWrapRec(this._getBoundPointsM(false)); + } + _boundPointsToParent(ifRotate = false) { + var pX = 0, pY = 0; + if (this._style) { + pX = this.pivotX; + pY = this.pivotY; + ifRotate = ifRotate || (this._style.rotation !== 0); + if (this._style.scrollRect) { + pX += this._style.scrollRect.x; + pY += this._style.scrollRect.y; + } + } + var pList = this._getBoundPointsM(ifRotate); + if (!pList || pList.length < 1) + return pList; + if (pList.length != 8) { + pList = ifRotate ? GrahamScan.scanPList(pList) : Rectangle._getWrapRec(pList, Rectangle.TEMP)._getBoundPoints(); + } + if (!this.transform) { + Utils.transPointList(pList, this._x - pX, this._y - pY); + return pList; + } + var tPoint = Point.TEMP; + var i, len = pList.length; + for (i = 0; i < len; i += 2) { + tPoint.x = pList[i]; + tPoint.y = pList[i + 1]; + this.toParentPoint(tPoint); + pList[i] = tPoint.x; + pList[i + 1] = tPoint.y; + } + return pList; + } + getGraphicBounds(realSize = false) { + if (!this._graphics) + return Rectangle.TEMP.setTo(0, 0, 0, 0); + return this._graphics.getBounds(realSize); + } + _getBoundPointsM(ifRotate = false) { + if (this._boundStyle && this._boundStyle.userBounds) + return this._boundStyle.userBounds._getBoundPoints(); + if (!this._boundStyle) + this._getBoundsStyle(); + if (!this._boundStyle.temBM) + this._boundStyle.temBM = []; + if (this._style.scrollRect) { + var rst = Utils.clearArray(this._boundStyle.temBM); + var rec = Rectangle.TEMP; + rec.copyFrom(this._style.scrollRect); + Utils.concatArray(rst, rec._getBoundPoints()); + return rst; + } + var pList; + if (this._graphics) { + pList = this._graphics.getBoundPoints(); + } + else { + pList = Utils.clearArray(this._boundStyle.temBM); + } + if (this._texture) { + rec = Rectangle.TEMP; + rec.setTo(0, 0, this.width || this._texture.width, this.height || this._texture.height); + Utils.concatArray(pList, rec._getBoundPoints()); + } + var child; + var cList; + var __childs; + __childs = this._children; + for (var i = 0, n = __childs.length; i < n; i++) { + child = __childs[i]; + if (child instanceof Sprite && child._visible === true) { + cList = child._boundPointsToParent(ifRotate); + if (cList) + pList = pList ? Utils.concatArray(pList, cList) : cList; + } + } + return pList; + } + _getCacheStyle() { + this._cacheStyle === CacheStyle.EMPTY && (this._cacheStyle = CacheStyle.create()); + return this._cacheStyle; + } + getStyle() { + this._style === SpriteStyle.EMPTY && (this._style = SpriteStyle.create()); + return this._style; + } + setStyle(value) { + this._style = value; + } + get scaleX() { + return this._style.scaleX; + } + set scaleX(value) { + this.set_scaleX(value); + } + _setScaleX(value) { + this._style.scaleX = value; + } + get scaleY() { + return this._style.scaleY; + } + set scaleY(value) { + this.set_scaleY(value); + } + _setScaleY(value) { + this._style.scaleY = value; + } + set_scaleX(value) { + var style = this.getStyle(); + if (style.scaleX !== value) { + this._setScaleX(value); + this._setTranformChange(); + } + } + get_scaleX() { + return this._style.scaleX; + } + set_scaleY(value) { + var style = this.getStyle(); + if (style.scaleY !== value) { + this._setScaleY(value); + this._setTranformChange(); + } + } + get_scaleY() { + return this._style.scaleY; + } + get rotation() { + return this._style.rotation; + } + set rotation(value) { + var style = this.getStyle(); + if (style.rotation !== value) { + this._setRotation(value); + this._setTranformChange(); + } + } + _setRotation(value) { + this._style.rotation = value; + } + get skewX() { + return this._style.skewX; + } + set skewX(value) { + var style = this.getStyle(); + if (style.skewX !== value) { + this._setSkewX(value); + this._setTranformChange(); + } + } + _setSkewX(value) { + this._style.skewX = value; + } + get skewY() { + return this._style.skewY; + } + set skewY(value) { + var style = this.getStyle(); + if (style.skewY !== value) { + this._setSkewY(value); + this._setTranformChange(); + } + } + _setSkewY(value) { + this._style.skewY = value; + } + _createTransform() { + return Matrix.create(); + } + _adjustTransform() { + this._tfChanged = false; + var style = this._style; + var sx = style.scaleX, sy = style.scaleY; + var sskx = style.skewX; + var ssky = style.skewY; + var rot = style.rotation; + var m = this._transform || (this._transform = this._createTransform()); + if (rot || sx !== 1 || sy !== 1 || sskx !== 0 || ssky !== 0) { + m._bTransform = true; + var skx = (rot - sskx) * 0.0174532922222222; + var sky = (rot + ssky) * 0.0174532922222222; + var cx = Math.cos(sky); + var ssx = Math.sin(sky); + var cy = Math.sin(skx); + var ssy = Math.cos(skx); + m.a = sx * cx; + m.b = sx * ssx; + m.c = -sy * cy; + m.d = sy * ssy; + m.tx = m.ty = 0; + } + else { + m.identity(); + this._renderType &= ~SpriteConst.TRANSFORM; + this._setRenderType(this._renderType); + } + return m; + } + _setTransform(value) { + } + get transform() { + return this._tfChanged ? this._adjustTransform() : this._transform; + } + set transform(value) { + this.set_transform(value); + } + get_transform() { + return this._tfChanged ? this._adjustTransform() : this._transform; + } + set_transform(value) { + this._tfChanged = false; + var m = this._transform || (this._transform = this._createTransform()); + value.copyTo(m); + this._setTransform(m); + if (value) { + this._x = m.tx; + this._y = m.ty; + m.tx = m.ty = 0; + } + if (value) + this._renderType |= SpriteConst.TRANSFORM; + else { + this._renderType &= ~SpriteConst.TRANSFORM; + } + this._setRenderType(this._renderType); + this.parentRepaint(); + } + _setPivotX(value) { + var style = this.getStyle(); + style.pivotX = value; + } + _getPivotX() { + return this._style.pivotX; + } + _setPivotY(value) { + var style = this.getStyle(); + style.pivotY = value; + } + _getPivotY() { + return this._style.pivotY; + } + get pivotX() { + return this._getPivotX(); + } + set pivotX(value) { + this._setPivotX(value); + this.repaint(); + } + get pivotY() { + return this._getPivotY(); + } + set pivotY(value) { + this._setPivotY(value); + this.repaint(); + } + _setAlpha(value) { + if (this._style.alpha !== value) { + var style = this.getStyle(); + style.alpha = value; + if (value !== 1) + this._renderType |= SpriteConst.ALPHA; + else + this._renderType &= ~SpriteConst.ALPHA; + this._setRenderType(this._renderType); + this.parentRepaint(); + } + } + _getAlpha() { + return this._style.alpha; + } + get alpha() { + return this._getAlpha(); + } + set alpha(value) { + value = value < 0 ? 0 : (value > 1 ? 1 : value); + this._setAlpha(value); + } + get visible() { + return this.get_visible(); + } + set visible(value) { + this.set_visible(value); + } + get_visible() { + return this._visible; + } + set_visible(value) { + if (this._visible !== value) { + this._visible = value; + this.parentRepaint(SpriteConst.REPAINT_ALL); + } + } + _setBlendMode(value) { + } + get blendMode() { + return this._style.blendMode; + } + set blendMode(value) { + this._setBlendMode(value); + this.getStyle().blendMode = value; + if (value && value != "source-over") + this._renderType |= SpriteConst.BLEND; + else + this._renderType &= ~SpriteConst.BLEND; + this._setRenderType(this._renderType); + this.parentRepaint(); + } + get graphics() { + if (!this._graphics) { + this.graphics = new Graphics(); + this._graphics.autoDestroy = true; + } + return this._graphics; + } + _setGraphics(value) { + } + _setGraphicsCallBack() { + } + set graphics(value) { + if (this._graphics) + this._graphics._sp = null; + this._graphics = value; + if (value) { + this._setGraphics(value); + this._renderType |= SpriteConst.GRAPHICS; + value._sp = this; + } + else { + this._renderType &= ~SpriteConst.GRAPHICS; + } + this._setRenderType(this._renderType); + this.repaint(); + } + get scrollRect() { + return this._style.scrollRect; + } + _setScrollRect(value) { + } + set scrollRect(value) { + this.getStyle().scrollRect = value; + this._setScrollRect(value); + this.repaint(); + if (value) { + this._renderType |= SpriteConst.CLIP; + } + else { + this._renderType &= ~SpriteConst.CLIP; + } + this._setRenderType(this._renderType); + } + pos(x, y, speedMode = false) { + if (this._x !== x || this._y !== y) { + if (this.destroyed) + return this; + if (speedMode) { + this._setX(x); + this._setY(y); + this.parentRepaint(SpriteConst.REPAINT_CACHE); + var p = this._cacheStyle.maskParent; + if (p) { + p.repaint(SpriteConst.REPAINT_CACHE); + } + } + else { + this.x = x; + this.y = y; + } + } + return this; + } + pivot(x, y) { + this.pivotX = x; + this.pivotY = y; + return this; + } + size(width, height) { + this.width = width; + this.height = height; + return this; + } + scale(scaleX, scaleY, speedMode = false) { + var style = this.getStyle(); + if (style.scaleX != scaleX || style.scaleY != scaleY) { + if (this.destroyed) + return this; + if (speedMode) { + this._setScaleX(scaleX); + this._setScaleY(scaleY); + this._setTranformChange(); + } + else { + this.scaleX = scaleX; + this.scaleY = scaleY; + } + } + return this; + } + skew(skewX, skewY) { + this.skewX = skewX; + this.skewY = skewY; + return this; + } + render(ctx, x, y) { + RenderSprite.renders[this._renderType]._fun(this, ctx, x + this._x, y + this._y); + this._repaint = 0; + } + drawToCanvas(canvasWidth, canvasHeight, offsetX, offsetY) { + return Sprite.drawToCanvas(this, this._renderType, canvasWidth, canvasHeight, offsetX, offsetY); + } + drawToTexture(canvasWidth, canvasHeight, offsetX, offsetY, rt = null) { + return Sprite.drawToTexture(this, this._renderType, canvasWidth, canvasHeight, offsetX, offsetY, rt); + } + drawToTexture3D(offx, offy, tex) { + throw 'not implement'; + } + static drawToCanvas(sprite, _renderType, canvasWidth, canvasHeight, offsetX, offsetY) { + offsetX -= sprite.x; + offsetY -= sprite.y; + offsetX |= 0; + offsetY |= 0; + canvasWidth |= 0; + canvasHeight |= 0; + var ctx = new Context(); + ctx.size(canvasWidth, canvasHeight); + ctx.asBitmap = true; + ctx._targets.start(); + ctx._targets.clear(0, 0, 0, 0); + RenderSprite.renders[_renderType]._fun(sprite, ctx, offsetX, offsetY); + ctx.flush(); + ctx._targets.end(); + ctx._targets.restore(); + var dt = ctx._targets.getData(0, 0, canvasWidth, canvasHeight); + ctx.destroy(); + var imgdata = new ImageData(canvasWidth, canvasHeight); + var lineLen = canvasWidth * 4; + var dst = imgdata.data; + var y = canvasHeight - 1; + var off = y * lineLen; + var srcoff = 0; + for (; y >= 0; y--) { + dst.set(dt.subarray(srcoff, srcoff + lineLen), off); + off -= lineLen; + srcoff += lineLen; + } + var canv = new HTMLCanvas(true); + canv.size(canvasWidth, canvasHeight); + var ctx2d = canv.getContext('2d'); + ctx2d.putImageData(imgdata, 0, 0); + return canv; + } + static drawToTexture(sprite, _renderType, canvasWidth, canvasHeight, offsetX, offsetY, rt = null) { + if (!Sprite.drawtocanvCtx) { + Sprite.drawtocanvCtx = new Context(); + } + offsetX -= sprite.x; + offsetY -= sprite.y; + offsetX |= 0; + offsetY |= 0; + canvasWidth |= 0; + canvasHeight |= 0; + var ctx = rt ? Sprite.drawtocanvCtx : new Context(); + ctx.clear(); + ctx.size(canvasWidth, canvasHeight); + if (rt) { + ctx._targets = rt; + } + else { + ctx.asBitmap = true; + } + if (ctx._targets) { + ctx._targets.start(); + ctx._targets.clear(0, 0, 0, 0); + RenderSprite.renders[_renderType]._fun(sprite, ctx, offsetX, offsetY); + ctx.flush(); + ctx._targets.end(); + ctx._targets.restore(); + } + if (!rt) { + var rtex = new Texture(ctx._targets, Texture.INV_UV); + ctx.destroy(true); + return rtex; + } + sprite._repaint = 0; + return rt; + } + customRender(context, x, y) { + this._repaint = SpriteConst.REPAINT_ALL; + } + _applyFilters() { + } + get filters() { + return this._cacheStyle.filters; + } + _setColorFilter(value) { } + set filters(value) { + value && value.length === 0 && (value = null); + if (this._cacheStyle.filters == value) + return; + this._getCacheStyle().filters = value ? value.slice() : null; + if (value && value.length) { + this._setColorFilter(value[0]); + this._renderType |= SpriteConst.FILTERS; + } + else { + this._setColorFilter(null); + this._renderType &= ~SpriteConst.FILTERS; + } + this._setRenderType(this._renderType); + if (value && value.length > 0) { + if (!this._getBit(Const.DISPLAY)) + this._setBitUp(Const.DISPLAY); + if (!(value.length == 1 && (value[0] instanceof ColorFilter))) { + this._getCacheStyle().cacheForFilters = true; + this._checkCanvasEnable(); + } + } + else { + if (this._cacheStyle.cacheForFilters) { + this._cacheStyle.cacheForFilters = false; + this._checkCanvasEnable(); + } + } + this._getCacheStyle().hasGlowFilter = this._isHaveGlowFilter(); + this.repaint(); + } + _isHaveGlowFilter() { + var i, len; + if (this.filters) { + for (i = 0; i < this.filters.length; i++) { + if (this.filters[i].type == Filter.GLOW) { + return true; + } + } + } + for (i = 0, len = this._children.length; i < len; i++) { + if (this._children[i]._isHaveGlowFilter()) { + return true; + } + } + return false; + } + localToGlobal(point, createNewPoint = false, globalNode = null) { + if (createNewPoint === true) { + point = new Point(point.x, point.y); + } + var ele = this; + globalNode = globalNode || ILaya.stage; + while (ele && !ele.destroyed) { + if (ele == globalNode) + break; + point = ele.toParentPoint(point); + ele = ele.parent; + } + return point; + } + globalToLocal(point, createNewPoint = false, globalNode = null) { + if (createNewPoint) { + point = new Point(point.x, point.y); + } + var ele = this; + var list = []; + globalNode = globalNode || ILaya.stage; + while (ele && !ele.destroyed) { + if (ele == globalNode) + break; + list.push(ele); + ele = ele.parent; + } + var i = list.length - 1; + while (i >= 0) { + ele = list[i]; + point = ele.fromParentPoint(point); + i--; + } + return point; + } + toParentPoint(point) { + if (!point) + return point; + point.x -= this.pivotX; + point.y -= this.pivotY; + if (this.transform) { + this._transform.transformPoint(point); + } + point.x += this._x; + point.y += this._y; + var scroll = this._style.scrollRect; + if (scroll) { + point.x -= scroll.x; + point.y -= scroll.y; + } + return point; + } + fromParentPoint(point) { + if (!point) + return point; + point.x -= this._x; + point.y -= this._y; + var scroll = this._style.scrollRect; + if (scroll) { + point.x += scroll.x; + point.y += scroll.y; + } + if (this.transform) { + this._transform.invertTransformPoint(point); + } + point.x += this.pivotX; + point.y += this.pivotY; + return point; + } + fromStagePoint(point) { + return point; + } + on(type, caller, listener, args = null) { + if (this._mouseState !== 1 && this.isMouseEvent(type)) { + this.mouseEnabled = true; + this._setBit(Const.HAS_MOUSE, true); + if (this._parent) { + this._onDisplay(); + } + return this._createListener(type, caller, listener, args, false); + } + return super.on(type, caller, listener, args); + } + once(type, caller, listener, args = null) { + if (this._mouseState !== 1 && this.isMouseEvent(type)) { + this.mouseEnabled = true; + this._setBit(Const.HAS_MOUSE, true); + if (this._parent) { + this._onDisplay(); + } + return this._createListener(type, caller, listener, args, true); + } + return super.once(type, caller, listener, args); + } + _onDisplay(v) { + if (this._mouseState !== 1) { + var ele = this; + ele = ele.parent; + while (ele && ele._mouseState !== 1) { + if (ele._getBit(Const.HAS_MOUSE)) + break; + ele.mouseEnabled = true; + ele._setBit(Const.HAS_MOUSE, true); + ele = ele.parent; + } + } + } + _setParent(value) { + super._setParent(value); + if (value && this._getBit(Const.HAS_MOUSE)) { + this._onDisplay(); + } + } + loadImage(url, complete = null) { + if (!url) { + this.texture = null; + loaded.call(this); + } + else { + var tex = ILaya.Loader.textureMap[URL.formatURL(url)]; + if (!tex) { + tex = new Texture(); + tex.load(url); + ILaya.Loader.cacheTexture(url, tex); + } + this.texture = tex; + if (!tex.getIsReady()) + tex.once(Event.READY, this, loaded); + else + loaded.call(this); + } + function loaded() { + this.repaint(SpriteConst.REPAINT_ALL); + complete && complete.run(); + } + return this; + } + static fromImage(url) { + return new Sprite().loadImage(url); + } + repaint(type = SpriteConst.REPAINT_CACHE) { + if (!(this._repaint & type)) { + this._repaint |= type; + this.parentRepaint(type); + } + if (this._cacheStyle && this._cacheStyle.maskParent) { + this._cacheStyle.maskParent.repaint(type); + } + } + _needRepaint() { + return (this._repaint & SpriteConst.REPAINT_CACHE) && this._cacheStyle.enableCanvasRender && this._cacheStyle.reCache; + } + _childChanged(child = null) { + if (this._children.length) + this._renderType |= SpriteConst.CHILDS; + else + this._renderType &= ~SpriteConst.CHILDS; + this._setRenderType(this._renderType); + if (child && this._getBit(Const.HAS_ZORDER)) + ILaya.systemTimer.callLater(this, this.updateZOrder); + this.repaint(SpriteConst.REPAINT_ALL); + } + parentRepaint(type = SpriteConst.REPAINT_CACHE) { + var p = this._parent; + if (p && !(p._repaint & type)) { + p._repaint |= type; + p.parentRepaint(type); + } + } + get stage() { + return ILaya.stage; + } + get hitArea() { + return this._style.hitArea; + } + set hitArea(value) { + this.getStyle().hitArea = value; + } + _setMask(value) { + } + get mask() { + return this._cacheStyle.mask; + } + set mask(value) { + if (value && this.mask && this.mask._cacheStyle.maskParent) + return; + this._getCacheStyle().mask = value; + this._setMask(value); + this._checkCanvasEnable(); + if (value) { + value._getCacheStyle().maskParent = this; + } + else { + if (this.mask) { + this.mask._getCacheStyle().maskParent = null; + } + } + this._renderType |= SpriteConst.MASK; + this._setRenderType(this._renderType); + this.parentRepaint(SpriteConst.REPAINT_ALL); + } + get mouseEnabled() { + return this._mouseState > 1; + } + set mouseEnabled(value) { + this._mouseState = value ? 2 : 1; + } + startDrag(area = null, hasInertia = false, elasticDistance = 0, elasticBackTime = 300, data = null, disableMouseEvent = false, ratio = 0.92) { + this._style.dragging || (this.getStyle().dragging = new ILaya.Dragging()); + this._style.dragging.start(this, area, hasInertia, elasticDistance, elasticBackTime, data, disableMouseEvent, ratio); + } + stopDrag() { + this._style.dragging && this._style.dragging.stop(); + } + _setDisplay(value) { + if (!value) { + if (this._cacheStyle) { + this._cacheStyle.releaseContext(); + this._cacheStyle.releaseFilterCache(); + if (this._cacheStyle.hasGlowFilter) { + this._cacheStyle.hasGlowFilter = false; + } + } + } + super._setDisplay(value); + } + hitTestPoint(x, y) { + var point = this.globalToLocal(Point.TEMP.setTo(x, y)); + x = point.x; + y = point.y; + var rect = this._style.hitArea ? this._style.hitArea : (this._width > 0 && this._height > 0) ? Rectangle.TEMP.setTo(0, 0, this._width, this._height) : this.getSelfBounds(); + return rect.contains(x, y); + } + getMousePoint() { + return this.globalToLocal(Point.TEMP.setTo(ILaya.stage.mouseX, ILaya.stage.mouseY)); + } + get globalScaleX() { + var scale = 1; + var ele = this; + while (ele) { + if (ele === ILaya.stage) + break; + scale *= ele.scaleX; + ele = ele.parent; + } + return scale; + } + get globalRotation() { + var angle = 0; + var ele = this; + while (ele) { + if (ele === ILaya.stage) + break; + angle += ele.rotation; + ele = ele.parent; + } + return angle; + } + get globalScaleY() { + var scale = 1; + var ele = this; + while (ele) { + if (ele === ILaya.stage) + break; + scale *= ele.scaleY; + ele = ele.parent; + } + return scale; + } + get mouseX() { + return this.getMousePoint().x; + } + get mouseY() { + return this.getMousePoint().y; + } + get zOrder() { + return this._zOrder; + } + set zOrder(value) { + if (this._zOrder != value) { + this._zOrder = value; + if (this._parent) { + value && this._parent._setBit(Const.HAS_ZORDER, true); + ILaya.systemTimer.callLater(this._parent, this.updateZOrder); + } + } + } + get texture() { + return this._texture; + } + _setTexture(value) { + } + set texture(value) { + if (typeof (value) == 'string') { + this.loadImage(value); + } + else if (this._texture != value) { + this._texture && this._texture._removeReference(); + this._texture = value; + value && value._addReference(); + this._setTexture(value); + this._setWidth(this._texture, this.width); + this._setHeight(this._texture, this.height); + if (value) + this._renderType |= SpriteConst.TEXTURE; + else + this._renderType &= ~SpriteConst.TEXTURE; + this._setRenderType(this._renderType); + this.repaint(); + } + } + get viewport() { + return this._style.viewport; + } + set viewport(value) { + if (typeof (value) == 'string') { + var recArr; + recArr = value.split(","); + if (recArr.length > 3) { + value = new Rectangle(parseFloat(recArr[0]), parseFloat(recArr[1]), parseFloat(recArr[2]), parseFloat(recArr[3])); + } + } + this.getStyle().viewport = value; + } + _setRenderType(type) { + } + _setTranformChange() { + this._tfChanged = true; + this._renderType |= SpriteConst.TRANSFORM; + this.parentRepaint(SpriteConst.REPAINT_CACHE); + } + _setBgStyleColor(x, y, width, height, fillColor) { + } + _setBorderStyleColor(x, y, width, height, fillColor, borderWidth) { + } + captureMouseEvent(exclusive) { + ILaya.MouseManager.instance.setCapture(this, exclusive); + } + releaseMouseEvent() { + ILaya.MouseManager.instance.releaseCapture(); + } + set drawCallOptimize(value) { + this._setBit(Const.DRAWCALL_OPTIMIZE, value); + } + get drawCallOptimize() { + return this._getBit(Const.DRAWCALL_OPTIMIZE); + } + } + ClassUtils.regClass("laya.display.Sprite", Sprite); + ClassUtils.regClass("Laya.Sprite", Sprite); + + class TextStyle extends SpriteStyle { + constructor() { + super(...arguments); + this.italic = false; + } + reset() { + super.reset(); + this.italic = false; + this.align = "left"; + this.wordWrap = false; + this.leading = 0; + this.padding = [0, 0, 0, 0]; + this.bgColor = null; + this.borderColor = null; + this.asPassword = false; + this.stroke = 0; + this.strokeColor = "#000000"; + this.bold = false; + this.underline = false; + this.underlineColor = null; + this.currBitmapFont = null; + return this; + } + recover() { + if (this === TextStyle.EMPTY) + return; + Pool.recover("TextStyle", this.reset()); + } + static create() { + return Pool.getItemByClass("TextStyle", TextStyle); + } + render(sprite, context, x, y) { + (this.bgColor || this.borderColor) && context.drawRect(x - this.pivotX, y - this.pivotY, sprite.width, sprite.height, this.bgColor, this.borderColor, 1); + } + } + TextStyle.EMPTY = new TextStyle(); + + class Text extends Sprite { + constructor() { + super(); + this._textWidth = 0; + this._textHeight = 0; + this._lines = []; + this._lineWidths = []; + this._startX = 0; + this._startY = 0; + this._charSize = {}; + this._valign = "top"; + this._fontSize = Text.defaultFontSize; + this._font = Text.defaultFont; + this._color = "#000000"; + this._singleCharRender = false; + this.overflow = Text.VISIBLE; + this._style = TextStyle.EMPTY; + } + static defaultFontStr() { + return Text.defaultFontSize + "px " + Text.defaultFont; + } + getStyle() { + this._style === TextStyle.EMPTY && (this._style = TextStyle.create()); + return this._style; + } + _getTextStyle() { + if (this._style === TextStyle.EMPTY) { + this._style = TextStyle.create(); + } + return this._style; + } + static registerBitmapFont(name, bitmapFont) { + Text._bitmapFonts || (Text._bitmapFonts = {}); + Text._bitmapFonts[name] = bitmapFont; + } + static unregisterBitmapFont(name, destroy = true) { + if (Text._bitmapFonts && Text._bitmapFonts[name]) { + var tBitmapFont = Text._bitmapFonts[name]; + if (destroy) + tBitmapFont.destroy(); + delete Text._bitmapFonts[name]; + } + } + destroy(destroyChild = true) { + super.destroy(destroyChild); + this._clipPoint = null; + this._lines = null; + this._lineWidths = null; + this._words && this._words.forEach(function (w) { + w.cleanCache(); + }); + this._words = null; + this._charSize = null; + } + _getBoundPointsM(ifRotate = false) { + var rec = Rectangle.TEMP; + rec.setTo(0, 0, this.width, this.height); + return rec._getBoundPoints(); + } + getGraphicBounds(realSize = false) { + var rec = Rectangle.TEMP; + rec.setTo(0, 0, this.width, this.height); + return rec; + } + get width() { + if (this._width) + return this._width; + return this.textWidth + this.padding[1] + this.padding[3]; + } + set width(value) { + if (value != this._width) { + super.set_width(value); + this.isChanged = true; + if (this.borderColor) { + this._setBorderStyleColor(0, 0, this.width, this.height, this.borderColor, 1); + } + } + } + _getCSSStyle() { + return this._style; + } + get height() { + if (this._height) + return this._height; + return this.textHeight; + } + set height(value) { + if (value != this._height) { + super.set_height(value); + this.isChanged = true; + if (this.borderColor) { + this._setBorderStyleColor(0, 0, this.width, this.height, this.borderColor, 1); + } + } + } + get textWidth() { + this._isChanged && ILaya.systemTimer.runCallLater(this, this.typeset); + return this._textWidth; + } + get textHeight() { + this._isChanged && ILaya.systemTimer.runCallLater(this, this.typeset); + return this._textHeight; + } + get text() { + return this._text || ""; + } + get_text() { + return this._text || ""; + } + set_text(value) { + if (this._text !== value) { + this.lang(value + ""); + this.isChanged = true; + this.event(Event.CHANGE); + if (this.borderColor) { + this._setBorderStyleColor(0, 0, this.width, this.height, this.borderColor, 1); + } + } + } + set text(value) { + this.set_text(value); + } + lang(text, arg1 = null, arg2 = null, arg3 = null, arg4 = null, arg5 = null, arg6 = null, arg7 = null, arg8 = null, arg9 = null, arg10 = null) { + text = Text.langPacks && Text.langPacks[text] ? Text.langPacks[text] : text; + if (arguments.length < 2) { + this._text = text; + } + else { + for (var i = 0, n = arguments.length; i < n; i++) { + text = text.replace("{" + i + "}", arguments[i + 1]); + } + this._text = text; + } + } + get font() { + return this._font; + } + set font(value) { + if (this._style.currBitmapFont) { + this._getTextStyle().currBitmapFont = null; + this.scale(1, 1); + } + if (Text._bitmapFonts && Text._bitmapFonts[value]) { + this._getTextStyle().currBitmapFont = Text._bitmapFonts[value]; + } + this._font = value; + this.isChanged = true; + } + get fontSize() { + return this._fontSize; + } + set fontSize(value) { + if (this._fontSize != value) { + this._fontSize = value; + this.isChanged = true; + } + } + get bold() { + return this._style.bold; + } + set bold(value) { + this._getTextStyle().bold = value; + this.isChanged = true; + } + get color() { + return this._color; + } + set color(value) { + this.set_color(value); + } + get_color() { + return this._color; + } + set_color(value) { + if (this._color != value) { + this._color = value; + if (!this._isChanged && this._graphics) { + this._graphics.replaceTextColor(this.color); + } + else { + this.isChanged = true; + } + } + } + get italic() { + return this._style.italic; + } + set italic(value) { + this._getTextStyle().italic = value; + this.isChanged = true; + } + get align() { + return this._style.align; + } + set align(value) { + this._getTextStyle().align = value; + this.isChanged = true; + } + get valign() { + return this._valign; + } + set valign(value) { + this._valign = value; + this.isChanged = true; + } + get wordWrap() { + return this._style.wordWrap; + } + set wordWrap(value) { + this._getTextStyle().wordWrap = value; + this.isChanged = true; + } + get leading() { + return this._style.leading; + } + set leading(value) { + this._getTextStyle().leading = value; + this.isChanged = true; + } + get padding() { + return this._style.padding; + } + set padding(value) { + if (typeof (value) == 'string') { + var arr; + arr = value.split(","); + var i, len; + len = arr.length; + while (arr.length < 4) { + arr.push(0); + } + for (i = 0; i < len; i++) { + arr[i] = parseFloat(arr[i]) || 0; + } + value = arr; + } + this._getTextStyle().padding = value; + this.isChanged = true; + } + get bgColor() { + return this._style.bgColor; + } + set bgColor(value) { + this.set_bgColor(value); + } + set_bgColor(value) { + this._getTextStyle().bgColor = value; + this._renderType |= SpriteConst.STYLE; + this._setBgStyleColor(0, 0, this.width, this.height, value); + this._setRenderType(this._renderType); + this.isChanged = true; + } + get_bgColor() { + return this._style.bgColor; + } + get borderColor() { + return this._style.borderColor; + } + set borderColor(value) { + this._getTextStyle().borderColor = value; + this._renderType |= SpriteConst.STYLE; + this._setBorderStyleColor(0, 0, this.width, this.height, value, 1); + this._setRenderType(this._renderType); + this.isChanged = true; + } + get stroke() { + return this._style.stroke; + } + set stroke(value) { + this._getTextStyle().stroke = value; + this.isChanged = true; + } + get strokeColor() { + return this._style.strokeColor; + } + set strokeColor(value) { + this._getTextStyle().strokeColor = value; + this.isChanged = true; + } + set isChanged(value) { + if (this._isChanged !== value) { + this._isChanged = value; + value && ILaya.systemTimer.callLater(this, this.typeset); + } + } + _getContextFont() { + return (this.italic ? "italic " : "") + (this.bold ? "bold " : "") + this.fontSize + "px " + (ILaya.Browser.onIPhone ? (Text.fontFamilyMap[this.font] || this.font) : this.font); + } + _isPassWordMode() { + var style = this._style; + var password = style.asPassword; + if (("prompt" in this) && this['prompt'] == this._text) + password = false; + return password; + } + _getPassWordTxt(txt) { + var len = txt.length; + var word; + word = ""; + for (var j = len; j > 0; j--) { + word += "●"; + } + return word; + } + _renderText() { + var padding = this.padding; + var visibleLineCount = this._lines.length; + if (this.overflow != Text.VISIBLE) { + visibleLineCount = Math.min(visibleLineCount, Math.floor((this.height - padding[0] - padding[2]) / (this.leading + this._charSize.height)) + 1); + } + var beginLine = this.scrollY / (this._charSize.height + this.leading) | 0; + var graphics = this.graphics; + graphics.clear(true); + var ctxFont = this._getContextFont(); + ILaya.Browser.context.font = ctxFont; + var startX = padding[3]; + var textAlgin = "left"; + var lines = this._lines; + var lineHeight = this.leading + this._charSize.height; + var tCurrBitmapFont = this._style.currBitmapFont; + if (tCurrBitmapFont) { + lineHeight = this.leading + tCurrBitmapFont.getMaxHeight(); + } + var startY = padding[0]; + if ((!tCurrBitmapFont) && this._width > 0 && this._textWidth <= this._width) { + if (this.align == "right") { + textAlgin = "right"; + startX = this._width - padding[1]; + } + else if (this.align == "center") { + textAlgin = "center"; + startX = this._width * 0.5 + padding[3] - padding[1]; + } + } + let bitmapScale = 1; + if (tCurrBitmapFont && tCurrBitmapFont.autoScaleSize) { + bitmapScale = tCurrBitmapFont.fontSize / this.fontSize; + } + if (this._height > 0) { + var tempVAlign = (this._textHeight > this._height) ? "top" : this.valign; + if (tempVAlign === "middle") + startY = (this._height - visibleLineCount / bitmapScale * lineHeight) * 0.5 + padding[0] - padding[2]; + else if (tempVAlign === "bottom") + startY = this._height - visibleLineCount / bitmapScale * lineHeight - padding[2]; + } + if (this._clipPoint) { + graphics.save(); + if (tCurrBitmapFont && tCurrBitmapFont.autoScaleSize) { + var tClipWidth; + var tClipHeight; + this._width ? tClipWidth = (this._width - padding[3] - padding[1]) : tClipWidth = this._textWidth; + this._height ? tClipHeight = (this._height - padding[0] - padding[2]) : tClipHeight = this._textHeight; + tClipWidth *= bitmapScale; + tClipHeight *= bitmapScale; + graphics.clipRect(padding[3], padding[0], tClipWidth, tClipHeight); + } + else { + graphics.clipRect(padding[3], padding[0], this._width ? (this._width - padding[3] - padding[1]) : this._textWidth, this._height ? (this._height - padding[0] - padding[2]) : this._textHeight); + } + this.repaint(); + } + var style = this._style; + var password = style.asPassword; + if (("prompt" in this) && this['prompt'] == this._text) + password = false; + var x = 0, y = 0; + var end = Math.min(this._lines.length, visibleLineCount + beginLine) || 1; + for (var i = beginLine; i < end; i++) { + var word = lines[i]; + var _word; + if (password) { + let len = word.length; + word = ""; + for (var j = len; j > 0; j--) { + word += "●"; + } + } + if (word == null) + word = ""; + x = startX - (this._clipPoint ? this._clipPoint.x : 0); + y = startY + lineHeight * i - (this._clipPoint ? this._clipPoint.y : 0); + this.underline && this._drawUnderline(textAlgin, x, y, i); + if (tCurrBitmapFont) { + var tWidth = this.width; + if (tCurrBitmapFont.autoScaleSize) { + tWidth = this.width * bitmapScale; + x *= bitmapScale; + y *= bitmapScale; + } + tCurrBitmapFont._drawText(word, this, x, y, this.align, tWidth); + } + else { + this._words || (this._words = []); + if (this._words.length > (i - beginLine)) { + _word = this._words[i - beginLine]; + } + else { + _word = new WordText(); + this._words.push(_word); + } + _word.setText(word); + _word.splitRender = this._singleCharRender; + style.stroke ? graphics.fillBorderText(_word, x, y, ctxFont, this.color, textAlgin, style.stroke, style.strokeColor) : graphics.fillText(_word, x, y, ctxFont, this.color, textAlgin); + } + } + if (tCurrBitmapFont && tCurrBitmapFont.autoScaleSize) { + var tScale = 1 / bitmapScale; + this.scale(tScale, tScale); + } + if (this._clipPoint) + graphics.restore(); + this._startX = startX; + this._startY = startY; + } + _drawUnderline(align, x, y, lineIndex) { + var lineWidth = this._lineWidths[lineIndex]; + switch (align) { + case 'center': + x -= lineWidth / 2; + break; + case 'right': + x -= lineWidth; + break; + } + y += this._charSize.height; + this._graphics.drawLine(x, y, x + lineWidth, y, this.underlineColor || this.color, 1); + } + typeset() { + this._isChanged = false; + if (!this._text) { + this._clipPoint = null; + this._textWidth = this._textHeight = 0; + this.graphics.clear(true); + return; + } + if (ILaya.Render.isConchApp) { + window.conchTextCanvas.font = this._getContextFont(); + } + else { + ILaya.Browser.context.font = this._getContextFont(); + } + this._lines.length = 0; + this._lineWidths.length = 0; + if (this._isPassWordMode()) { + this._parseLines(this._getPassWordTxt(this._text)); + } + else + this._parseLines(this._text); + this._evalTextSize(); + if (this._checkEnabledViewportOrNot()) + this._clipPoint || (this._clipPoint = new Point(0, 0)); + else + this._clipPoint = null; + this._renderText(); + } + _evalTextSize() { + var nw, nh; + nw = Math.max.apply(this, this._lineWidths); + let bmpFont = this._style.currBitmapFont; + if (bmpFont) { + let h = bmpFont.getMaxHeight(); + if (bmpFont.autoScaleSize) { + h = this.fontSize; + } + nh = this._lines.length * (h + this.leading) + this.padding[0] + this.padding[2]; + } + else { + nh = this._lines.length * (this._charSize.height + this.leading) + this.padding[0] + this.padding[2]; + if (this._lines.length) { + nh -= this.leading; + } + } + if (nw != this._textWidth || nh != this._textHeight) { + this._textWidth = nw; + this._textHeight = nh; + } + } + _checkEnabledViewportOrNot() { + return this.overflow == Text.SCROLL && ((this._width > 0 && this._textWidth > this._width) || (this._height > 0 && this._textHeight > this._height)); + } + changeText(text) { + if (this._text !== text) { + this.lang(text + ""); + if (this._graphics && this._graphics.replaceText(this._text)) ; + else { + this.typeset(); + } + } + } + _parseLines(text) { + var needWordWrapOrTruncate = this.wordWrap || this.overflow == Text.HIDDEN; + if (needWordWrapOrTruncate) { + var wordWrapWidth = this._getWordWrapWidth(); + } + var bitmapFont = this._style.currBitmapFont; + if (bitmapFont) { + this._charSize.width = bitmapFont.getMaxWidth(); + this._charSize.height = bitmapFont.getMaxHeight(); + } + else { + var measureResult = null; + if (ILaya.Render.isConchApp) { + measureResult = window.conchTextCanvas.measureText(Text._testWord); + } + else { + measureResult = ILaya.Browser.context.measureText(Text._testWord); + } + if (!measureResult) + measureResult = { width: 100 }; + this._charSize.width = measureResult.width; + this._charSize.height = (measureResult.height || this.fontSize); + } + var lines = text.replace(/\r\n/g, "\n").split("\n"); + for (var i = 0, n = lines.length; i < n; i++) { + var line = lines[i]; + if (needWordWrapOrTruncate) + this._parseLine(line, wordWrapWidth); + else { + this._lineWidths.push(this._getTextWidth(line)); + this._lines.push(line); + } + } + } + _parseLine(line, wordWrapWidth) { + var lines = this._lines; + var maybeIndex = 0; + var charsWidth = 0; + var wordWidth = 0; + var startIndex = 0; + charsWidth = this._getTextWidth(line); + if (charsWidth <= wordWrapWidth) { + lines.push(line); + this._lineWidths.push(charsWidth); + return; + } + charsWidth = this._charSize.width; + maybeIndex = Math.floor(wordWrapWidth / charsWidth); + (maybeIndex == 0) && (maybeIndex = 1); + charsWidth = this._getTextWidth(line.substring(0, maybeIndex)); + wordWidth = charsWidth; + for (var j = maybeIndex, m = line.length; j < m; j++) { + charsWidth = this._getTextWidth(line.charAt(j)); + wordWidth += charsWidth; + if (wordWidth > wordWrapWidth) { + if (this.wordWrap) { + var newLine = line.substring(startIndex, j); + var ccode = newLine.charCodeAt(newLine.length - 1); + if (ccode < 0x4e00 || ccode > 0x9fa5) { + var execResult = /(?:[^\s\!-\/])+$/.exec(newLine); + if (execResult) { + j = execResult.index + startIndex; + if (execResult.index == 0) + j += newLine.length; + else + newLine = line.substring(startIndex, j); + } + } + lines.push(newLine); + this._lineWidths.push(wordWidth - charsWidth); + startIndex = j; + if (j + maybeIndex < m) { + j += maybeIndex; + charsWidth = this._getTextWidth(line.substring(startIndex, j)); + wordWidth = charsWidth; + j--; + } + else { + lines.push(line.substring(startIndex, m)); + this._lineWidths.push(this._getTextWidth(lines[lines.length - 1])); + startIndex = -1; + break; + } + } + else if (this.overflow == Text.HIDDEN) { + lines.push(line.substring(0, j)); + this._lineWidths.push(this._getTextWidth(lines[lines.length - 1])); + return; + } + } + } + if (this.wordWrap && startIndex != -1) { + lines.push(line.substring(startIndex, m)); + this._lineWidths.push(this._getTextWidth(lines[lines.length - 1])); + } + } + _getTextWidth(text) { + var bitmapFont = this._style.currBitmapFont; + if (bitmapFont) + return bitmapFont.getTextWidth(text); + else { + if (ILaya.Render.isConchApp) { + return window.conchTextCanvas.measureText(text).width; + } + else { + let ret = ILaya.Browser.context.measureText(text) || { width: 100 }; + return ret.width; + } + } + } + _getWordWrapWidth() { + var p = this.padding; + var w; + var bitmapFont = this._style.currBitmapFont; + if (bitmapFont && bitmapFont.autoScaleSize) + w = this._width * (bitmapFont.fontSize / this.fontSize); + else + w = this._width; + if (w <= 0) { + w = this.wordWrap ? 100 : ILaya.Browser.width; + } + w <= 0 && (w = 100); + return w - p[3] - p[1]; + } + getCharPoint(charIndex, out = null) { + this._isChanged && ILaya.systemTimer.runCallLater(this, this.typeset); + var len = 0, lines = this._lines, startIndex = 0; + for (var i = 0, n = lines.length; i < n; i++) { + len += lines[i].length; + if (charIndex < len) { + var line = i; + break; + } + startIndex = len; + } + var ctxFont = (this.italic ? "italic " : "") + (this.bold ? "bold " : "") + this.fontSize + "px " + this.font; + ILaya.Browser.context.font = ctxFont; + var width = this._getTextWidth(this._text.substring(startIndex, charIndex)); + var point = out || new Point(); + return point.setTo(this._startX + width - (this._clipPoint ? this._clipPoint.x : 0), this._startY + line * (this._charSize.height + this.leading) - (this._clipPoint ? this._clipPoint.y : 0)); + } + set scrollX(value) { + if (this.overflow != Text.SCROLL || (this.textWidth < this._width || !this._clipPoint)) + return; + value = value < this.padding[3] ? this.padding[3] : value; + var maxScrollX = this._textWidth - this._width; + value = value > maxScrollX ? maxScrollX : value; + this._clipPoint.x = value; + this._renderText(); + } + get scrollX() { + if (!this._clipPoint) + return 0; + return this._clipPoint.x; + } + set scrollY(value) { + if (this.overflow != Text.SCROLL || (this.textHeight < this._height || !this._clipPoint)) + return; + value = value < this.padding[0] ? this.padding[0] : value; + var maxScrollY = this._textHeight - this._height; + value = value > maxScrollY ? maxScrollY : value; + this._clipPoint.y = value; + this._renderText(); + } + get scrollY() { + if (!this._clipPoint) + return 0; + return this._clipPoint.y; + } + get maxScrollX() { + return (this.textWidth < this._width) ? 0 : this._textWidth - this._width; + } + get maxScrollY() { + return (this.textHeight < this._height) ? 0 : this._textHeight - this._height; + } + get lines() { + if (this._isChanged) + this.typeset(); + return this._lines; + } + get underlineColor() { + return this._style.underlineColor; + } + set underlineColor(value) { + this._getTextStyle().underlineColor = value; + if (!this._isChanged) + this._renderText(); + } + get underline() { + return this._style.underline; + } + set underline(value) { + this._getTextStyle().underline = value; + } + set singleCharRender(value) { + this._singleCharRender = value; + } + get singleCharRender() { + return this._singleCharRender; + } + } + Text.VISIBLE = "visible"; + Text.SCROLL = "scroll"; + Text.HIDDEN = "hidden"; + Text.defaultFontSize = 12; + Text.defaultFont = "Arial"; + Text.isComplexText = false; + Text.fontFamilyMap = { "报隶": "报隶-简", "黑体": "黑体-简", "楷体": "楷体-简", "兰亭黑": "兰亭黑-简", "隶变": "隶变-简", "凌慧体": "凌慧体-简", "翩翩体": "翩翩体-简", "苹方": "苹方-简", "手札体": "手札体-简", "宋体": "宋体-简", "娃娃体": "娃娃体-简", "魏碑": "魏碑-简", "行楷": "行楷-简", "雅痞": "雅痞-简", "圆体": "圆体-简" }; + Text._testWord = "游"; + Text.CharacterCache = true; + Text.RightToLeft = false; + ILaya.regClass(Text); + ClassUtils.regClass("laya.display.Text", Text); + ClassUtils.regClass("Laya.Text", Text); + + class Input extends Text { + constructor() { + super(); + this._multiline = false; + this._editable = true; + this._maxChars = 1E5; + this._type = "text"; + this._prompt = ''; + this._promptColor = "#A9A9A9"; + this._originColor = "#000000"; + this._content = ''; + Input.IOS_IFRAME = (ILaya.Browser.onIOS && ILaya.Browser.window.top != ILaya.Browser.window.self); + this._width = 100; + this._height = 20; + this.multiline = false; + this.overflow = Text.SCROLL; + this.on(Event.MOUSE_DOWN, this, this._onMouseDown); + this.on(Event.UNDISPLAY, this, this._onUnDisplay); + } + static __init__() { + Input._createInputElement(); + if (ILaya.Browser.onMobile) { + var isTrue = false; + if (ILaya.Browser.onMiniGame || ILaya.Browser.onBDMiniGame || ILaya.Browser.onQGMiniGame || ILaya.Browser.onKGMiniGame || ILaya.Browser.onVVMiniGame || ILaya.Browser.onAlipayMiniGame || ILaya.Browser.onQQMiniGame || ILaya.Browser.onBLMiniGame || ILaya.Browser.onTTMiniGame || ILaya.Browser.onHWMiniGame || ILaya.Browser.onTBMiniGame) { + isTrue = true; + } + ILaya.Render.canvas.addEventListener(Input.IOS_IFRAME ? (isTrue ? "touchend" : "click") : "touchend", Input._popupInputMethod); + } + } + static _popupInputMethod(e) { + if (!Input.isInputting) + return; + var input = Input.inputElement; + input.focus(); + } + static _createInputElement() { + Input._initInput(Input.area = ILaya.Browser.createElement("textarea")); + Input._initInput(Input.input = ILaya.Browser.createElement("input")); + Input.inputContainer = ILaya.Browser.createElement("div"); + Input.inputContainer.style.position = "absolute"; + Input.inputContainer.style.zIndex = '1E5'; + ILaya.Browser.container.appendChild(Input.inputContainer); + Input.inputContainer.setPos = function (x, y) { + Input.inputContainer.style.left = x + 'px'; + Input.inputContainer.style.top = y + 'px'; + }; + } + static _initInput(input) { + var style = input.style; + style.cssText = "position:absolute;overflow:hidden;resize:none;transform-origin:0 0;-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-o-transform-origin:0 0;"; + style.resize = 'none'; + style.backgroundColor = 'transparent'; + style.border = 'none'; + style.outline = 'none'; + style.zIndex = '1'; + input.addEventListener('input', Input._processInputting); + input.addEventListener('mousemove', Input._stopEvent); + input.addEventListener('mousedown', Input._stopEvent); + input.addEventListener('touchmove', Input._stopEvent); + input.setFontFace = function (fontFace) { input.style.fontFamily = fontFace; }; + if (!ILaya.Render.isConchApp) { + input.setColor = function (color) { input.style.color = color; }; + input.setFontSize = function (fontSize) { input.style.fontSize = fontSize + 'px'; }; + } + } + static _processInputting(e) { + var input = Input.inputElement.target; + if (!input) + return; + var value = Input.inputElement.value; + if (input._restrictPattern) { + value = value.replace(/\u2006|\x27/g, ""); + if (input._restrictPattern.test(value)) { + value = value.replace(input._restrictPattern, ""); + Input.inputElement.value = value; + } + } + input._text = value; + input.event(Event.INPUT); + } + static _stopEvent(e) { + if (e.type == 'touchmove') + e.preventDefault(); + e.stopPropagation && e.stopPropagation(); + } + setSelection(startIndex, endIndex) { + this.focus = true; + Input.inputElement.selectionStart = startIndex; + Input.inputElement.selectionEnd = endIndex; + } + get multiline() { + return this._multiline; + } + set multiline(value) { + this._multiline = value; + this.valign = value ? "top" : "middle"; + } + get nativeInput() { + return this._multiline ? Input.area : Input.input; + } + _onUnDisplay(e = null) { + this.focus = false; + } + _onMouseDown(e) { + this.focus = true; + } + _syncInputTransform() { + var inputElement = this.nativeInput; + var transform = Utils.getTransformRelativeToWindow(this, this.padding[3], this.padding[0]); + var inputWid = this._width - this.padding[1] - this.padding[3]; + var inputHei = this._height - this.padding[0] - this.padding[2]; + if (ILaya.Render.isConchApp) { + inputElement.setScale(transform.scaleX, transform.scaleY); + inputElement.setSize(inputWid, inputHei); + inputElement.setPos(transform.x, transform.y); + } + else { + Input.inputContainer.style.transform = Input.inputContainer.style.webkitTransform = "scale(" + transform.scaleX + "," + transform.scaleY + ") rotate(" + (ILaya.stage.canvasDegree) + "deg)"; + inputElement.style.width = inputWid + 'px'; + inputElement.style.height = inputHei + 'px'; + Input.inputContainer.style.left = transform.x + 'px'; + Input.inputContainer.style.top = transform.y + 'px'; + } + } + select() { + this.nativeInput.select(); + } + get focus() { + return this._focus; + } + set focus(value) { + var input = this.nativeInput; + if (this._focus !== value) { + if (value) { + if (input.target) { + input.target._focusOut(); + } + else { + this._setInputMethod(); + } + input = this.nativeInput; + input.target = this; + this._focusIn(); + } + else { + input.target = null; + this._focusOut(); + ILaya.Browser.document.body.scrollTop = 0; + input.blur(); + if (ILaya.Render.isConchApp) + input.setPos(-10000, -10000); + else if (Input.inputContainer.contains(input)) + Input.inputContainer.removeChild(input); + } + } + } + _setInputMethod() { + Input.input.parentElement && (Input.inputContainer.removeChild(Input.input)); + Input.area.parentElement && (Input.inputContainer.removeChild(Input.area)); + if (ILaya.Browser.onAndroid) { + Input.input = Input.inputElement = ILaya.Browser.createElement('input'); + Input._initInput(Input.input); + } + Input.inputElement = (this._multiline ? Input.area : Input.input); + Input.inputContainer.appendChild(Input.inputElement); + if (Text.RightToLeft) { + Input.inputElement.style.direction = "rtl"; + } + } + _focusIn() { + Input.isInputting = true; + var input = this.nativeInput; + Input.input && (Input.input.type = this._type); + this._focus = true; + var cssStyle = input.style; + cssStyle.whiteSpace = (this.wordWrap ? "pre-wrap" : "nowrap"); + this._setPromptColor(); + input.readOnly = !this._editable; + if (ILaya.Render.isConchApp) { + input.setType(this._type); + input.setForbidEdit(!this._editable); + } + input.maxLength = this._maxChars; + input.value = this._content; + input.placeholder = this._prompt; + ILaya.stage.off(Event.KEY_DOWN, this, this._onKeyDown); + ILaya.stage.on(Event.KEY_DOWN, this, this._onKeyDown); + ILaya.stage.focus = this; + this.event(Event.FOCUS); + if (ILaya.Browser.onPC) + input.focus(); + if (!ILaya.Browser.onMiniGame && !ILaya.Browser.onBDMiniGame && !ILaya.Browser.onQGMiniGame && !ILaya.Browser.onKGMiniGame && !ILaya.Browser.onVVMiniGame && !ILaya.Browser.onAlipayMiniGame && !ILaya.Browser.onQQMiniGame && !ILaya.Browser.onBLMiniGame && !ILaya.Browser.onTTMiniGame && !ILaya.Browser.onHWMiniGame && !ILaya.Browser.onTBMiniGame) { + this._text = null; + } + this.typeset(); + input.setColor(this._originColor); + input.setFontSize(this.fontSize); + input.setFontFace(ILaya.Browser.onIPhone ? (Text.fontFamilyMap[this.font] || this.font) : this.font); + if (ILaya.Render.isConchApp) { + input.setMultiAble && input.setMultiAble(this._multiline); + } + cssStyle.lineHeight = (this.leading + this.fontSize) + "px"; + cssStyle.fontStyle = (this.italic ? "italic" : "normal"); + cssStyle.fontWeight = (this.bold ? "bold" : "normal"); + cssStyle.textAlign = this.align; + cssStyle.padding = "0 0"; + this._syncInputTransform(); + if (!ILaya.Render.isConchApp && ILaya.Browser.onPC) + ILaya.systemTimer.frameLoop(1, this, this._syncInputTransform); + } + _setPromptColor() { + Input.promptStyleDOM = ILaya.Browser.getElementById("promptStyle"); + if (!Input.promptStyleDOM) { + Input.promptStyleDOM = ILaya.Browser.createElement("style"); + Input.promptStyleDOM.setAttribute("id", "promptStyle"); + ILaya.Browser.document.head.appendChild(Input.promptStyleDOM); + } + Input.promptStyleDOM.innerText = "input::-webkit-input-placeholder, textarea::-webkit-input-placeholder {" + "color:" + this._promptColor + "}" + "input:-moz-placeholder, textarea:-moz-placeholder {" + "color:" + this._promptColor + "}" + "input::-moz-placeholder, textarea::-moz-placeholder {" + "color:" + this._promptColor + "}" + "input:-ms-input-placeholder, textarea:-ms-input-placeholder {" + "color:" + this._promptColor + "}"; + } + _focusOut() { + if (!Input.isInputting) + return; + Input.isInputting = false; + this._focus = false; + this._text = null; + this._content = this.nativeInput.value; + if (!this._content) { + super.set_text(this._prompt); + super.set_color(this._promptColor); + } + else { + super.set_text(this._content); + super.set_color(this._originColor); + } + ILaya.stage.off(Event.KEY_DOWN, this, this._onKeyDown); + ILaya.stage.focus = null; + this.event(Event.BLUR); + this.event(Event.CHANGE); + if (ILaya.Render.isConchApp) + this.nativeInput.blur(); + ILaya.Browser.onPC && ILaya.systemTimer.clear(this, this._syncInputTransform); + } + _onKeyDown(e) { + if (e.keyCode === 13) { + if (ILaya.Browser.onMobile && !this._multiline) + this.focus = false; + this.event(Event.ENTER); + } + } + set text(value) { + super.set_color(this._originColor); + value += ''; + if (this._focus) { + this.nativeInput.value = value || ''; + this.event(Event.CHANGE); + } + else { + if (!this._multiline) + value = value.replace(/\r?\n/g, ''); + this._content = value; + if (value) + super.set_text(value); + else { + super.set_text(this._prompt); + super.set_color(this.promptColor); + } + } + } + get text() { + if (this._focus) + return this.nativeInput.value; + else + return this._content || ""; + } + changeText(text) { + this._content = text; + if (this._focus) { + this.nativeInput.value = text || ''; + this.event(Event.CHANGE); + } + else + super.changeText(text); + } + set color(value) { + if (this._focus) + this.nativeInput.setColor(value); + super.set_color(this._content ? value : this._promptColor); + this._originColor = value; + } + get color() { + return super.color; + } + set bgColor(value) { + super.set_bgColor(value); + if (ILaya.Render.isConchApp) + this.nativeInput.setBgColor(value); + } + get bgColor() { + return super.bgColor; + } + get restrict() { + if (this._restrictPattern) { + return this._restrictPattern.source; + } + return ""; + } + set restrict(pattern) { + if (pattern) { + pattern = "[^" + pattern + "]"; + if (pattern.indexOf("^^") > -1) + pattern = pattern.replace("^^", ""); + this._restrictPattern = new RegExp(pattern, "g"); + } + else + this._restrictPattern = null; + } + set editable(value) { + this._editable = value; + if (ILaya.Render.isConchApp) { + Input.input.setForbidEdit(!value); + } + } + get editable() { + return this._editable; + } + get maxChars() { + return this._maxChars; + } + set maxChars(value) { + if (value <= 0) + value = 1E5; + this._maxChars = value; + } + get prompt() { + return this._prompt; + } + set prompt(value) { + if (!this._text && value) + super.set_color(this._promptColor); + this.promptColor = this._promptColor; + if (this._text) + super.set_text((this._text == this._prompt) ? value : this._text); + else + super.set_text(value); + this._prompt = Text.langPacks && Text.langPacks[value] ? Text.langPacks[value] : value; + } + get promptColor() { + return this._promptColor; + } + set promptColor(value) { + this._promptColor = value; + if (!this._content) + super.set_color(value); + } + get type() { + return this._type; + } + set type(value) { + if (value === "password") + this._getTextStyle().asPassword = true; + else + this._getTextStyle().asPassword = false; + this._type = value; + } + } + Input.TYPE_TEXT = "text"; + Input.TYPE_PASSWORD = "password"; + Input.TYPE_EMAIL = "email"; + Input.TYPE_URL = "url"; + Input.TYPE_NUMBER = "number"; + Input.TYPE_RANGE = "range"; + Input.TYPE_DATE = "date"; + Input.TYPE_MONTH = "month"; + Input.TYPE_WEEK = "week"; + Input.TYPE_TIME = "time"; + Input.TYPE_DATE_TIME = "datetime"; + Input.TYPE_DATE_TIME_LOCAL = "datetime-local"; + Input.TYPE_SEARCH = "search"; + Input.IOS_IFRAME = false; + Input.inputHeight = 45; + Input.isInputting = false; + ClassUtils.regClass("laya.display.Input", Input); + ClassUtils.regClass("Laya.Input", Input); + + class TouchManager { + constructor() { + this.preOvers = []; + this.preDowns = []; + this.preRightDowns = []; + this.enable = true; + this._event = new Event(); + this._lastClickTime = 0; + } + _clearTempArrs() { + TouchManager._oldArr.length = 0; + TouchManager._newArr.length = 0; + TouchManager._tEleArr.length = 0; + } + getTouchFromArr(touchID, arr) { + var i, len; + len = arr.length; + var tTouchO; + for (i = 0; i < len; i++) { + tTouchO = arr[i]; + if (tTouchO.id == touchID) { + return tTouchO; + } + } + return null; + } + removeTouchFromArr(touchID, arr) { + var i; + for (i = arr.length - 1; i >= 0; i--) { + if (arr[i].id == touchID) { + arr.splice(i, 1); + } + } + } + createTouchO(ele, touchID) { + var rst; + rst = Pool.getItem("TouchData") || {}; + rst.id = touchID; + rst.tar = ele; + return rst; + } + onMouseDown(ele, touchID, isLeft = false) { + if (!this.enable) + return; + var preO; + var tO; + var arrs; + preO = this.getTouchFromArr(touchID, this.preOvers); + arrs = this.getEles(ele, null, TouchManager._tEleArr); + if (!preO) { + tO = this.createTouchO(ele, touchID); + this.preOvers.push(tO); + } + else { + preO.tar = ele; + } + if (Browser.onMobile) + this.sendEvents(arrs, Event.MOUSE_OVER); + var preDowns; + preDowns = isLeft ? this.preDowns : this.preRightDowns; + preO = this.getTouchFromArr(touchID, preDowns); + if (!preO) { + tO = this.createTouchO(ele, touchID); + preDowns.push(tO); + } + else { + preO.tar = ele; + } + this.sendEvents(arrs, isLeft ? Event.MOUSE_DOWN : Event.RIGHT_MOUSE_DOWN); + this._clearTempArrs(); + } + sendEvents(eles, type) { + var i, len; + len = eles.length; + this._event._stoped = false; + var _target; + _target = eles[0]; + for (i = 0; i < len; i++) { + var tE = eles[i]; + if (tE.destroyed) + return; + tE.event(type, this._event.setTo(type, tE, _target)); + if (this._event._stoped) + break; + } + } + getEles(start, end = null, rst = null) { + if (!rst) { + rst = []; + } + else { + rst.length = 0; + } + while (start && start != end) { + rst.push(start); + start = start.parent; + } + return rst; + } + checkMouseOutAndOverOfMove(eleNew, elePre, touchID = 0) { + if (elePre == eleNew) + return; + var tar; + var arrs; + var i, len; + if (elePre.contains(eleNew)) { + arrs = this.getEles(eleNew, elePre, TouchManager._tEleArr); + this.sendEvents(arrs, Event.MOUSE_OVER); + } + else if (eleNew.contains(elePre)) { + arrs = this.getEles(elePre, eleNew, TouchManager._tEleArr); + this.sendEvents(arrs, Event.MOUSE_OUT); + } + else { + arrs = TouchManager._tEleArr; + arrs.length = 0; + var oldArr; + oldArr = this.getEles(elePre, null, TouchManager._oldArr); + var newArr; + newArr = this.getEles(eleNew, null, TouchManager._newArr); + len = oldArr.length; + var tIndex; + for (i = 0; i < len; i++) { + tar = oldArr[i]; + tIndex = newArr.indexOf(tar); + if (tIndex >= 0) { + newArr.splice(tIndex, newArr.length - tIndex); + break; + } + else { + arrs.push(tar); + } + } + if (arrs.length > 0) { + this.sendEvents(arrs, Event.MOUSE_OUT); + } + if (newArr.length > 0) { + this.sendEvents(newArr, Event.MOUSE_OVER); + } + } + } + onMouseMove(ele, touchID) { + if (!this.enable) + return; + var preO; + preO = this.getTouchFromArr(touchID, this.preOvers); + var arrs; + if (!preO) { + arrs = this.getEles(ele, null, TouchManager._tEleArr); + this.sendEvents(arrs, Event.MOUSE_OVER); + this.preOvers.push(this.createTouchO(ele, touchID)); + } + else { + this.checkMouseOutAndOverOfMove(ele, preO.tar); + preO.tar = ele; + arrs = this.getEles(ele, null, TouchManager._tEleArr); + } + this.sendEvents(arrs, Event.MOUSE_MOVE); + this._clearTempArrs(); + } + getLastOvers() { + TouchManager._tEleArr.length = 0; + if (this.preOvers.length > 0 && this.preOvers[0].tar) { + return this.getEles(this.preOvers[0].tar, null, TouchManager._tEleArr); + } + TouchManager._tEleArr.push(ILaya.stage); + return TouchManager._tEleArr; + } + stageMouseOut() { + var lastOvers; + lastOvers = this.getLastOvers(); + this.preOvers.length = 0; + this.sendEvents(lastOvers, Event.MOUSE_OUT); + } + onMouseUp(ele, touchID, isLeft = false) { + if (!this.enable) + return; + var preO; + var arrs; + var oldArr; + var i, len; + var tar; + var sendArr; + var onMobile = Browser.onMobile; + arrs = this.getEles(ele, null, TouchManager._tEleArr); + this.sendEvents(arrs, isLeft ? Event.MOUSE_UP : Event.RIGHT_MOUSE_UP); + var preDowns; + preDowns = isLeft ? this.preDowns : this.preRightDowns; + preO = this.getTouchFromArr(touchID, preDowns); + if (!preO) ; + else { + var isDouble; + var now = Browser.now(); + isDouble = now - this._lastClickTime < 300; + this._lastClickTime = now; + if (ele == preO.tar) { + sendArr = arrs; + } + else { + oldArr = this.getEles(preO.tar, null, TouchManager._oldArr); + sendArr = TouchManager._newArr; + sendArr.length = 0; + len = oldArr.length; + for (i = 0; i < len; i++) { + tar = oldArr[i]; + if (arrs.indexOf(tar) >= 0) { + sendArr.push(tar); + } + } + } + if (sendArr.length > 0) { + this.sendEvents(sendArr, isLeft ? Event.CLICK : Event.RIGHT_CLICK); + } + if (isLeft && isDouble) { + this.sendEvents(sendArr, Event.DOUBLE_CLICK); + } + this.removeTouchFromArr(touchID, preDowns); + preO.tar = null; + Pool.recover("TouchData", preO); + } + preO = this.getTouchFromArr(touchID, this.preOvers); + if (!preO) ; + else { + if (onMobile) { + sendArr = this.getEles(preO.tar, null, sendArr); + if (sendArr && sendArr.length > 0) { + this.sendEvents(sendArr, Event.MOUSE_OUT); + } + this.removeTouchFromArr(touchID, this.preOvers); + preO.tar = null; + Pool.recover("TouchData", preO); + } + } + this._clearTempArrs(); + } + } + TouchManager.I = new TouchManager(); + TouchManager._oldArr = []; + TouchManager._newArr = []; + TouchManager._tEleArr = []; + + class MouseManager { + constructor() { + this.mouseX = 0; + this.mouseY = 0; + this.disableMouseEvent = false; + this.mouseDownTime = 0; + this.mouseMoveAccuracy = 2; + this._event = new Event(); + this._captureSp = null; + this._captureChain = []; + this._captureExlusiveMode = false; + this._hitCaputreSp = false; + this._point = new Point(); + this._rect = new Rectangle(); + this._lastMoveTimer = 0; + this._prePoint = new Point(); + this._touchIDs = {}; + this._curTouchID = NaN; + this._id = 1; + } + __init__(stage, canvas) { + this._stage = stage; + var _this = this; + canvas.oncontextmenu = function (e) { + if (MouseManager.enabled) + return false; + }; + canvas.addEventListener('mousedown', function (e) { + if (MouseManager.enabled) { + if (!Browser.onIE) + (e.cancelable) && (e.preventDefault()); + _this.mouseDownTime = Browser.now(); + _this.runEvent(e); + } + }); + canvas.addEventListener('mouseup', function (e) { + if (MouseManager.enabled) { + (e.cancelable) && (e.preventDefault()); + _this.mouseDownTime = -Browser.now(); + _this.runEvent(e); + } + }, true); + canvas.addEventListener('mousemove', function (e) { + if (MouseManager.enabled) { + (e.cancelable) && (e.preventDefault()); + var now = Browser.now(); + if (now - _this._lastMoveTimer < 10) + return; + _this._lastMoveTimer = now; + _this.runEvent(e); + } + }, true); + canvas.addEventListener("mouseout", function (e) { + if (MouseManager.enabled) + _this.runEvent(e); + }); + canvas.addEventListener("mouseover", function (e) { + if (MouseManager.enabled) + _this.runEvent(e); + }); + canvas.addEventListener("touchstart", function (e) { + if (MouseManager.enabled) { + if (!MouseManager._isFirstTouch && !Input.isInputting) + (e.cancelable) && (e.preventDefault()); + _this.mouseDownTime = Browser.now(); + _this.runEvent(e); + } + }); + canvas.addEventListener("touchend", function (e) { + if (MouseManager.enabled) { + if (!MouseManager._isFirstTouch && !Input.isInputting) + (e.cancelable) && (e.preventDefault()); + MouseManager._isFirstTouch = false; + _this.mouseDownTime = -Browser.now(); + _this.runEvent(e); + } + else { + _this._curTouchID = NaN; + } + }, true); + canvas.addEventListener("touchmove", function (e) { + if (MouseManager.enabled) { + (e.cancelable) && (e.preventDefault()); + _this.runEvent(e); + } + }, true); + canvas.addEventListener("touchcancel", function (e) { + if (MouseManager.enabled) { + (e.cancelable) && (e.preventDefault()); + _this.runEvent(e); + } + else { + _this._curTouchID = NaN; + } + }, true); + canvas.addEventListener('mousewheel', function (e) { + if (MouseManager.enabled) + _this.runEvent(e); + }); + canvas.addEventListener('DOMMouseScroll', function (e) { + if (MouseManager.enabled) + _this.runEvent(e); + }); + } + initEvent(e, nativeEvent = null) { + var _this = this; + _this._event._stoped = false; + _this._event.nativeEvent = nativeEvent || e; + _this._target = null; + this._point.setTo(e.pageX || e.clientX, e.pageY || e.clientY); + if (this._stage._canvasTransform) { + this._stage._canvasTransform.invertTransformPoint(this._point); + _this.mouseX = this._point.x; + _this.mouseY = this._point.y; + } + _this._event.touchId = e.identifier || 0; + this._tTouchID = _this._event.touchId; + var evt; + evt = TouchManager.I._event; + evt._stoped = false; + evt.nativeEvent = _this._event.nativeEvent; + evt.touchId = _this._event.touchId; + } + checkMouseWheel(e) { + this._event.delta = e.wheelDelta ? e.wheelDelta * 0.025 : -e.detail; + var _lastOvers = TouchManager.I.getLastOvers(); + for (var i = 0, n = _lastOvers.length; i < n; i++) { + var ele = _lastOvers[i]; + ele.event(Event.MOUSE_WHEEL, this._event.setTo(Event.MOUSE_WHEEL, ele, this._target)); + } + } + onMouseMove(ele) { + TouchManager.I.onMouseMove(ele, this._tTouchID); + } + onMouseDown(ele) { + if (Input.isInputting && ILaya.stage.focus && ILaya.stage.focus["focus"] && !ILaya.stage.focus.contains(this._target)) { + var pre_input = ILaya.stage.focus['_tf'] || ILaya.stage.focus; + var new_input = ele['_tf'] || ele; + if (new_input instanceof Input && new_input.multiline == pre_input.multiline) + pre_input['_focusOut'](); + else + pre_input.focus = false; + } + TouchManager.I.onMouseDown(ele, this._tTouchID, this._isLeftMouse); + } + onMouseUp(ele) { + TouchManager.I.onMouseUp(ele, this._tTouchID, this._isLeftMouse); + } + check(sp, mouseX, mouseY, callBack) { + this._point.setTo(mouseX, mouseY); + sp.fromParentPoint(this._point); + mouseX = this._point.x; + mouseY = this._point.y; + var scrollRect = sp._style.scrollRect; + if (scrollRect) { + this._rect.setTo(scrollRect.x, scrollRect.y, scrollRect.width, scrollRect.height); + if (!this._rect.contains(mouseX, mouseY)) + return false; + } + if (!this.disableMouseEvent) { + if (sp.hitTestPrior && !sp.mouseThrough && !this.hitTest(sp, mouseX, mouseY)) { + return false; + } + for (var i = sp._children.length - 1; i > -1; i--) { + var child = sp._children[i]; + if (!child.destroyed && child._mouseState > 1 && child._visible) { + if (this.check(child, mouseX, mouseY, callBack)) + return true; + } + } + for (i = sp._extUIChild.length - 1; i >= 0; i--) { + var c = sp._extUIChild[i]; + if (!c.destroyed && c._mouseState > 1 && c._visible) { + if (this.check(c, mouseX, mouseY, callBack)) + return true; + } + } + } + var isHit = (sp.hitTestPrior && !sp.mouseThrough && !this.disableMouseEvent) ? true : this.hitTest(sp, mouseX, mouseY); + if (isHit) { + this._target = sp; + callBack.call(this, sp); + if (this._target == this._hitCaputreSp) { + this._hitCaputreSp = true; + } + } + else if (callBack === this.onMouseUp && sp === this._stage) { + this._target = this._stage; + callBack.call(this, this._target); + } + return isHit; + } + hitTest(sp, mouseX, mouseY) { + var isHit = false; + if (sp.scrollRect) { + mouseX -= sp._style.scrollRect.x; + mouseY -= sp._style.scrollRect.y; + } + var hitArea = sp._style.hitArea; + if (hitArea && hitArea._hit) { + return hitArea.contains(mouseX, mouseY); + } + if (sp.width > 0 && sp.height > 0 || sp.mouseThrough || hitArea) { + if (!sp.mouseThrough) { + isHit = (hitArea ? hitArea : this._rect.setTo(0, 0, sp.width, sp.height)).contains(mouseX, mouseY); + } + else { + isHit = sp.getGraphicBounds().contains(mouseX, mouseY); + } + } + return isHit; + } + _checkAllBaseUI(mousex, mousey, callback) { + var ret = this.handleExclusiveCapture(this.mouseX, this.mouseY, callback); + if (ret) + return true; + ret = this.check(this._stage, this.mouseX, this.mouseY, callback); + return this.handleCapture(this.mouseX, this.mouseY, callback) || ret; + } + check3DUI(mousex, mousey, callback) { + var uis = this._stage._3dUI; + var i = 0; + var ret = false; + for (; i < uis.length; i++) { + var curui = uis[i]; + this._stage._curUIBase = curui; + if (!curui.destroyed && curui._mouseState > 1 && curui._visible) { + ret = ret || this.check(curui, this.mouseX, this.mouseY, callback); + } + } + this._stage._curUIBase = this._stage; + return ret; + } + handleExclusiveCapture(mousex, mousey, callback) { + if (this._captureExlusiveMode && this._captureSp && this._captureChain.length > 0) { + var cursp; + this._point.setTo(mousex, mousey); + for (var i = 0; i < this._captureChain.length; i++) { + cursp = this._captureChain[i]; + cursp.fromParentPoint(this._point); + } + this._target = cursp; + callback.call(this, cursp); + return true; + } + return false; + } + handleCapture(mousex, mousey, callback) { + if (!this._hitCaputreSp && this._captureSp && this._captureChain.length > 0) { + var cursp; + this._point.setTo(mousex, mousey); + for (var i = 0; i < this._captureChain.length; i++) { + cursp = this._captureChain[i]; + cursp.fromParentPoint(this._point); + } + this._target = cursp; + callback.call(this, cursp); + return true; + } + return false; + } + runEvent(evt) { + var i, n, touch; + if (evt.type !== 'mousemove') + this._prePoint.x = this._prePoint.y = -1000000; + switch (evt.type) { + case 'mousedown': + this._touchIDs[0] = this._id++; + if (!MouseManager._isTouchRespond) { + this._isLeftMouse = evt.button === 0; + this.initEvent(evt); + this._checkAllBaseUI(this.mouseX, this.mouseY, this.onMouseDown); + } + else + MouseManager._isTouchRespond = false; + break; + case 'mouseup': + this._isLeftMouse = evt.button === 0; + this.initEvent(evt); + this._checkAllBaseUI(this.mouseX, this.mouseY, this.onMouseUp); + break; + case 'mousemove': + if ((Math.abs(this._prePoint.x - evt.clientX) + Math.abs(this._prePoint.y - evt.clientY)) >= this.mouseMoveAccuracy) { + this._prePoint.x = evt.clientX; + this._prePoint.y = evt.clientY; + this.initEvent(evt); + this._checkAllBaseUI(this.mouseX, this.mouseY, this.onMouseMove); + } + break; + case "touchstart": + MouseManager._isTouchRespond = true; + this._isLeftMouse = true; + var touches = evt.changedTouches; + for (i = 0, n = touches.length; i < n; i++) { + touch = touches[i]; + if (MouseManager.multiTouchEnabled || isNaN(this._curTouchID)) { + this._curTouchID = touch.identifier; + if (this._id % 200 === 0) + this._touchIDs = {}; + this._touchIDs[touch.identifier] = this._id++; + this.initEvent(touch, evt); + this._checkAllBaseUI(this.mouseX, this.mouseY, this.onMouseDown); + } + } + break; + case "touchend": + case "touchcancel": + MouseManager._isTouchRespond = true; + this._isLeftMouse = true; + var touchends = evt.changedTouches; + for (i = 0, n = touchends.length; i < n; i++) { + touch = touchends[i]; + if (MouseManager.multiTouchEnabled || touch.identifier == this._curTouchID) { + this._curTouchID = NaN; + this.initEvent(touch, evt); + var isChecked; + isChecked = this._checkAllBaseUI(this.mouseX, this.mouseY, this.onMouseUp); + if (!isChecked) { + this.onMouseUp(null); + } + } + } + break; + case "touchmove": + var touchemoves = evt.changedTouches; + for (i = 0, n = touchemoves.length; i < n; i++) { + touch = touchemoves[i]; + if (MouseManager.multiTouchEnabled || touch.identifier == this._curTouchID) { + this.initEvent(touch, evt); + this._checkAllBaseUI(this.mouseX, this.mouseY, this.onMouseMove); + } + } + break; + case "wheel": + case "mousewheel": + case "DOMMouseScroll": + this.checkMouseWheel(evt); + break; + case "mouseout": + TouchManager.I.stageMouseOut(); + break; + case "mouseover": + this._stage.event(Event.MOUSE_OVER, this._event.setTo(Event.MOUSE_OVER, this._stage, this._stage)); + break; + } + } + setCapture(sp, exclusive = false) { + this._captureSp = sp; + this._captureExlusiveMode = exclusive; + this._captureChain.length = 0; + this._captureChain.push(sp); + var cursp = sp; + while (true) { + if (cursp == ILaya.stage) + break; + if (cursp == ILaya.stage._curUIBase) + break; + cursp = cursp.parent; + if (!cursp) + break; + this._captureChain.splice(0, 0, cursp); + } + } + releaseCapture() { + console.log('release capture'); + this._captureSp = null; + } + } + MouseManager.instance = new MouseManager(); + MouseManager.enabled = true; + MouseManager.multiTouchEnabled = true; + MouseManager._isFirstTouch = true; + + class CallLater { + constructor() { + this._pool = []; + this._map = {}; + this._laters = []; + } + _update() { + let laters = this._laters; + let len = laters.length; + if (len > 0) { + for (let i = 0, n = len - 1; i <= n; i++) { + let handler = laters[i]; + this._map[handler.key] = null; + if (handler.method !== null) { + handler.run(); + handler.clear(); + } + this._pool.push(handler); + i === n && (n = laters.length - 1); + } + laters.length = 0; + } + } + _getHandler(caller, method) { + var cid = caller ? caller.$_GID || (caller.$_GID = ILaya.Utils.getGID()) : 0; + var mid = method.$_TID || (method.$_TID = (ILaya.Timer._mid++)); + return this._map[cid + '.' + mid]; + } + callLater(caller, method, args = null) { + if (this._getHandler(caller, method) == null) { + let handler; + if (this._pool.length) + handler = this._pool.pop(); + else + handler = new LaterHandler(); + handler.caller = caller; + handler.method = method; + handler.args = args; + var cid = caller ? caller.$_GID : 0; + var mid = method["$_TID"]; + handler.key = cid + '.' + mid; + this._map[handler.key] = handler; + this._laters.push(handler); + } + } + runCallLater(caller, method) { + var handler = this._getHandler(caller, method); + if (handler && handler.method != null) { + this._map[handler.key] = null; + handler.run(); + handler.clear(); + } + } + } + CallLater.I = new CallLater(); + class LaterHandler { + clear() { + this.caller = null; + this.method = null; + this.args = null; + } + run() { + var caller = this.caller; + if (caller && caller.destroyed) + return this.clear(); + var method = this.method; + var args = this.args; + if (method == null) + return; + args ? method.apply(caller, args) : method.call(caller); + } + } + + class RunDriver { + } + RunDriver.createShaderCondition = function (conditionScript) { + var fn = "(function() {return " + conditionScript + ";})"; + return window.Laya._runScript(fn); + }; + RunDriver.changeWebGLSize = function (w, h) { + WebGL.onStageResize(w, h); + }; + + class PerformancePlugin { + static setPerformanceDataTool(tool) { + this.performanceTool = tool; + } + static begainSample(path) { + if (this.performanceTool) + this.performanceTool.enable && this.performanceTool.BegainSample(path); + } + static endSample(path) { + if (this.performanceTool) + return this.performanceTool.enable ? this.performanceTool.EndSample(path) : 0; + else + return 0; + } + static expoertFile(path) { + if (this.performanceTool) + return this.performanceTool.enable ? this.performanceTool.exportPerformanceFile() : null; + } + static showFunSampleFun(path) { + this.performanceTool.showFunSampleFun(path); + } + static set enable(value) { + if (this.performanceTool) { + this.performanceTool.enable = value; + } + } + static get enable() { + if (this.performanceTool) + return this._enable; + else + return false; + } + static set enableDataExport(value) { + if (this.performanceTool) { + this.performanceTool.enableDataExport = value; + } + } + static get enableDataExport() { + if (this.performanceTool) + return this.performanceTool.enableDataExport; + return false; + } + } + PerformancePlugin.performanceTool = null; + PerformancePlugin._enable = false; + PerformancePlugin.PERFORMANCE_LAYA = "Laya"; + PerformancePlugin.PERFORMANCE_LAYA_3D = "Laya/3D"; + PerformancePlugin.PERFORMANCE_LAYA_2D = "Laya/2D"; + PerformancePlugin.PERFORMANCE_LAYA_3D_PRERENDER = "Laya/3D/PreRender"; + PerformancePlugin.PERFORMANCE_LAYA_3D_UPDATESCRIPT = "Laya/3D/UpdateScript"; + PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS = "Laya/3D/Physics"; + PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS_SIMULATE = "Laya/3D/Physics/simulate"; + PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS_CHARACTORCOLLISION = "Laya/3D/Physics/updataCharacters&Collisions"; + PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS_EVENTSCRIPTS = "Laya/3D/Physics/eventScripts"; + PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER = "Laya/3D/Render"; + PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_SHADOWMAP = "Laya/3D/Render/ShadowMap"; + PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_CLUSTER = "Laya/3D/Render/Cluster"; + PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_CULLING = "Laya/3D/Render/Culling"; + PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDERDEPTHMDOE = "Laya/3D/Render/RenderDepthMode"; + PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDEROPAQUE = "Laya/3D/Render/RenderOpaque"; + PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDERCOMMANDBUFFER = "Laya/3D/Render/RenderCommandBuffer"; + PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDERTRANSPARENT = "Laya/3D/Render/RenderTransparent"; + PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_POSTPROCESS = "Laya/3D/Render/PostProcess"; + window.PerformancePlugin = PerformancePlugin; + + class Stage extends Sprite { + constructor() { + super(); + this.offset = new Point(); + this._frameRate = "fast"; + this.designWidth = 0; + this.designHeight = 0; + this.canvasRotation = false; + this.canvasDegree = 0; + this.renderingEnabled = true; + this.screenAdaptationEnabled = true; + this._canvasTransform = new Matrix(); + this._screenMode = "none"; + this._scaleMode = "noscale"; + this._alignV = "top"; + this._alignH = "left"; + this._bgColor = "black"; + this._mouseMoveTime = 0; + this._renderCount = 0; + this._safariOffsetY = 0; + this._frameStartTime = 0; + this._previousOrientation = Browser.window.orientation; + this._wgColor = [0, 0, 0, 1]; + this._scene3Ds = []; + this._globalRepaintSet = false; + this._globalRepaintGet = false; + this._3dUI = []; + this._curUIBase = null; + this.useRetinalCanvas = false; + super.set_transform(this._createTransform()); + this.mouseEnabled = true; + this.hitTestPrior = true; + this.autoSize = false; + this._setBit(Const.DISPLAYED_INSTAGE, true); + this._setBit(Const.ACTIVE_INHIERARCHY, true); + this._isFocused = true; + this._isVisibility = true; + this.useRetinalCanvas = Config.useRetinalCanvas; + var window = Browser.window; + window.addEventListener("focus", () => { + this._isFocused = true; + this.event(Event.FOCUS); + this.event(Event.FOCUS_CHANGE); + }); + window.addEventListener("blur", () => { + this._isFocused = false; + this.event(Event.BLUR); + this.event(Event.FOCUS_CHANGE); + if (this._isInputting()) + Input["inputElement"].target.focus = false; + }); + var state = "visibilityState", visibilityChange = "visibilitychange"; + var document = window.document; + if (typeof document.hidden !== "undefined") { + visibilityChange = "visibilitychange"; + state = "visibilityState"; + } + else if (typeof document.mozHidden !== "undefined") { + visibilityChange = "mozvisibilitychange"; + state = "mozVisibilityState"; + } + else if (typeof document.msHidden !== "undefined") { + visibilityChange = "msvisibilitychange"; + state = "msVisibilityState"; + } + else if (typeof document.webkitHidden !== "undefined") { + visibilityChange = "webkitvisibilitychange"; + state = "webkitVisibilityState"; + } + window.document.addEventListener(visibilityChange, () => { + if (Browser.document[state] == "hidden") { + this._isVisibility = false; + if (this._isInputting()) + Input["inputElement"].target.focus = false; + } + else { + this._isVisibility = true; + } + this.renderingEnabled = this._isVisibility; + this.event(Event.VISIBILITY_CHANGE); + }); + window.addEventListener("resize", () => { + var orientation = Browser.window.orientation; + if (orientation != null && orientation != this._previousOrientation && this._isInputting()) { + Input["inputElement"].target.focus = false; + } + this._previousOrientation = orientation; + if (this._isInputting()) + return; + if (Browser.onSafari) + this._safariOffsetY = (Browser.window.__innerHeight || Browser.document.body.clientHeight || Browser.document.documentElement.clientHeight) - Browser.window.innerHeight; + this._resetCanvas(); + }); + window.addEventListener("orientationchange", (e) => { + this._resetCanvas(); + }); + this.on(Event.MOUSE_MOVE, this, this._onmouseMove); + if (Browser.onMobile) + this.on(Event.MOUSE_DOWN, this, this._onmouseMove); + } + _isInputting() { + return (Browser.onMobile && Input.isInputting); + } + set width(value) { + this.designWidth = value; + super.set_width(value); + ILaya.systemTimer.callLater(this, this._changeCanvasSize); + } + get width() { + return super.get_width(); + } + set height(value) { + this.designHeight = value; + super.set_height(value); + ILaya.systemTimer.callLater(this, this._changeCanvasSize); + } + get height() { + return super.get_height(); + } + set transform(value) { + super.set_transform(value); + } + get transform() { + if (this._tfChanged) + this._adjustTransform(); + return (this._transform = this._transform || this._createTransform()); + } + get isFocused() { + return this._isFocused; + } + get isVisibility() { + return this._isVisibility; + } + _changeCanvasSize() { + this.setScreenSize(Browser.clientWidth * Browser.pixelRatio, Browser.clientHeight * Browser.pixelRatio); + } + _resetCanvas() { + if (!this.screenAdaptationEnabled) + return; + this._changeCanvasSize(); + } + setScreenSize(screenWidth, screenHeight) { + var rotation = false; + if (this._screenMode !== Stage.SCREEN_NONE) { + var screenType = screenWidth / screenHeight < 1 ? Stage.SCREEN_VERTICAL : Stage.SCREEN_HORIZONTAL; + rotation = screenType !== this._screenMode; + if (rotation) { + var temp = screenHeight; + screenHeight = screenWidth; + screenWidth = temp; + } + } + this.canvasRotation = rotation; + var canvas = Render._mainCanvas; + var canvasStyle = canvas.source.style; + var mat = this._canvasTransform.identity(); + var scaleMode = this._scaleMode; + var scaleX = screenWidth / this.designWidth; + var scaleY = screenHeight / this.designHeight; + var canvasWidth = this.useRetinalCanvas ? screenWidth : this.designWidth; + var canvasHeight = this.useRetinalCanvas ? screenHeight : this.designHeight; + var realWidth = screenWidth; + var realHeight = screenHeight; + var pixelRatio = Browser.pixelRatio; + this._width = this.designWidth; + this._height = this.designHeight; + switch (scaleMode) { + case Stage.SCALE_NOSCALE: + scaleX = scaleY = 1; + realWidth = this.designWidth; + realHeight = this.designHeight; + break; + case Stage.SCALE_SHOWALL: + scaleX = scaleY = Math.min(scaleX, scaleY); + canvasWidth = realWidth = Math.round(this.designWidth * scaleX); + canvasHeight = realHeight = Math.round(this.designHeight * scaleY); + break; + case Stage.SCALE_NOBORDER: + scaleX = scaleY = Math.max(scaleX, scaleY); + realWidth = Math.round(this.designWidth * scaleX); + realHeight = Math.round(this.designHeight * scaleY); + break; + case Stage.SCALE_FULL: + scaleX = scaleY = 1; + this._width = canvasWidth = screenWidth; + this._height = canvasHeight = screenHeight; + break; + case Stage.SCALE_FIXED_WIDTH: + scaleY = scaleX; + this._height = canvasHeight = Math.round(screenHeight / scaleX); + break; + case Stage.SCALE_FIXED_HEIGHT: + scaleX = scaleY; + this._width = canvasWidth = Math.round(screenWidth / scaleY); + break; + case Stage.SCALE_FIXED_AUTO: + if ((screenWidth / screenHeight) < (this.designWidth / this.designHeight)) { + scaleY = scaleX; + this._height = canvasHeight = Math.round(screenHeight / scaleX); + } + else { + scaleX = scaleY; + this._width = canvasWidth = Math.round(screenWidth / scaleY); + } + break; + } + if (this.useRetinalCanvas) { + realWidth = canvasWidth = screenWidth; + realHeight = canvasHeight = screenHeight; + } + scaleX *= this.scaleX; + scaleY *= this.scaleY; + if (scaleX === 1 && scaleY === 1) { + this.transform.identity(); + } + else { + this.transform.a = this._formatData(scaleX / (realWidth / canvasWidth)); + this.transform.d = this._formatData(scaleY / (realHeight / canvasHeight)); + } + canvas.size(canvasWidth, canvasHeight); + RunDriver.changeWebGLSize(canvasWidth, canvasHeight); + mat.scale(realWidth / canvasWidth / pixelRatio, realHeight / canvasHeight / pixelRatio); + if (this._alignH === Stage.ALIGN_LEFT) + this.offset.x = 0; + else if (this._alignH === Stage.ALIGN_RIGHT) + this.offset.x = screenWidth - realWidth; + else + this.offset.x = (screenWidth - realWidth) * 0.5 / pixelRatio; + if (this._alignV === Stage.ALIGN_TOP) + this.offset.y = 0; + else if (this._alignV === Stage.ALIGN_BOTTOM) + this.offset.y = screenHeight - realHeight; + else + this.offset.y = (screenHeight - realHeight) * 0.5 / pixelRatio; + this.offset.x = Math.round(this.offset.x); + this.offset.y = Math.round(this.offset.y); + mat.translate(this.offset.x, this.offset.y); + if (this._safariOffsetY) + mat.translate(0, this._safariOffsetY); + this.canvasDegree = 0; + if (rotation) { + if (this._screenMode === Stage.SCREEN_HORIZONTAL) { + mat.rotate(Math.PI / 2); + mat.translate(screenHeight / pixelRatio, 0); + this.canvasDegree = 90; + } + else { + mat.rotate(-Math.PI / 2); + mat.translate(0, screenWidth / pixelRatio); + this.canvasDegree = -90; + } + } + mat.a = this._formatData(mat.a); + mat.d = this._formatData(mat.d); + mat.tx = this._formatData(mat.tx); + mat.ty = this._formatData(mat.ty); + super.set_transform(this.transform); + canvasStyle.transformOrigin = canvasStyle.webkitTransformOrigin = canvasStyle.msTransformOrigin = canvasStyle.mozTransformOrigin = canvasStyle.oTransformOrigin = "0px 0px 0px"; + canvasStyle.transform = canvasStyle.webkitTransform = canvasStyle.msTransform = canvasStyle.mozTransform = canvasStyle.oTransform = "matrix(" + mat.toString() + ")"; + canvasStyle.width = canvasWidth; + canvasStyle.height = canvasHeight; + if (this._safariOffsetY) + mat.translate(0, -this._safariOffsetY); + mat.translate(parseInt(canvasStyle.left) || 0, parseInt(canvasStyle.top) || 0); + this.visible = true; + this._repaint |= SpriteConst.REPAINT_CACHE; + this.event(Event.RESIZE); + } + _formatData(value) { + if (Math.abs(value) < 0.000001) + return 0; + if (Math.abs(1 - value) < 0.001) + return value > 0 ? 1 : -1; + return value; + } + get scaleMode() { + return this._scaleMode; + } + set scaleMode(value) { + this._scaleMode = value; + ILaya.systemTimer.callLater(this, this._changeCanvasSize); + } + get alignH() { + return this._alignH; + } + set alignH(value) { + this._alignH = value; + ILaya.systemTimer.callLater(this, this._changeCanvasSize); + } + get alignV() { + return this._alignV; + } + set alignV(value) { + this._alignV = value; + ILaya.systemTimer.callLater(this, this._changeCanvasSize); + } + get bgColor() { + return this._bgColor; + } + set bgColor(value) { + this._bgColor = value; + if (value) + this._wgColor = ColorUtils.create(value).arrColor; + else + this._wgColor = null; + if (value) { + Render.canvas.style.background = value; + } + else { + Render.canvas.style.background = "none"; + } + } + get mouseX() { + return Math.round(MouseManager.instance.mouseX / this.clientScaleX); + } + get mouseY() { + return Math.round(MouseManager.instance.mouseY / this.clientScaleY); + } + getMousePoint() { + return Point.TEMP.setTo(this.mouseX, this.mouseY); + } + get clientScaleX() { + return this._transform ? this._transform.getScaleX() : 1; + } + get clientScaleY() { + return this._transform ? this._transform.getScaleY() : 1; + } + get screenMode() { + return this._screenMode; + } + set screenMode(value) { + this._screenMode = value; + } + repaint(type = SpriteConst.REPAINT_CACHE) { + this._repaint |= type; + } + parentRepaint(type = SpriteConst.REPAINT_CACHE) { + } + _loop() { + this._globalRepaintGet = this._globalRepaintSet; + this._globalRepaintSet = false; + this.render(Render._context, 0, 0); + return true; + } + getFrameTm() { + return this._frameStartTime; + } + _onmouseMove(e) { + this._mouseMoveTime = Browser.now(); + } + getTimeFromFrameStart() { + return Browser.now() - this._frameStartTime; + } + set visible(value) { + if (this.visible !== value) { + super.set_visible(value); + var style = Render._mainCanvas.source.style; + style.visibility = value ? "visible" : "hidden"; + } + } + get visible() { + return super.visible; + } + render(context, x, y) { + if (window.conch) { + this.renderToNative(context, x, y); + return; + } + if (this._frameRate === Stage.FRAME_SLEEP) { + var now = Browser.now(); + if (now - this._frameStartTime >= 1000) + this._frameStartTime = now; + else + return; + } + else { + if (!this._visible) { + this._renderCount++; + if (this._renderCount % 5 === 0) { + CallLater.I._update(); + Stat.loopCount++; + RenderInfo.loopCount = Stat.loopCount; + this._updateTimers(); + } + return; + } + this._frameStartTime = Browser.now(); + RenderInfo.loopStTm = this._frameStartTime; + } + this._renderCount++; + var frameMode = this._frameRate === Stage.FRAME_MOUSE ? (((this._frameStartTime - this._mouseMoveTime) < 2000) ? Stage.FRAME_FAST : Stage.FRAME_SLOW) : this._frameRate; + var isFastMode = (frameMode !== Stage.FRAME_SLOW); + var isDoubleLoop = (this._renderCount % 2 === 0); + Stat.renderSlow = !isFastMode; + if (!isFastMode && !isDoubleLoop) + return; + CallLater.I._update(); + Stat.loopCount++; + RenderInfo.loopCount = Stat.loopCount; + PerformancePlugin.begainSample(PerformancePlugin.PERFORMANCE_LAYA); + if (this.renderingEnabled) { + for (var i = 0, n = this._scene3Ds.length; i < n; i++) + this._scene3Ds[i]._update(); + context.clear(); + super.render(context, x, y); + Stat._StatRender.renderNotCanvas(context, x, y); + } + if (this.renderingEnabled) { + Stage.clear(this._bgColor); + context.flush(); + VectorGraphManager.instance && VectorGraphManager.getInstance().endDispose(); + } + this._updateTimers(); + PerformancePlugin.endSample(PerformancePlugin.PERFORMANCE_LAYA); + } + renderToNative(context, x, y) { + this._renderCount++; + if (!this._visible) { + if (this._renderCount % 5 === 0) { + CallLater.I._update(); + Stat.loopCount++; + RenderInfo.loopCount = Stat.loopCount; + this._updateTimers(); + } + return; + } + this._frameStartTime = Browser.now(); + CallLater.I._update(); + Stat.loopCount++; + RenderInfo.loopCount = Stat.loopCount; + if (this.renderingEnabled) { + for (var i = 0, n = this._scene3Ds.length; i < n; i++) + this._scene3Ds[i]._update(); + context.clear(); + super.render(context, x, y); + Stat._StatRender.renderNotCanvas(context, x, y); + } + if (this.renderingEnabled) { + Stage.clear(this._bgColor); + context.flush(); + VectorGraphManager.instance && VectorGraphManager.getInstance().endDispose(); + } + this._updateTimers(); + } + _updateTimers() { + ILaya.systemTimer._update(); + ILaya.startTimer._update(); + ILaya.physicsTimer._update(); + ILaya.updateTimer._update(); + ILaya.lateTimer._update(); + ILaya.timer._update(); + } + set fullScreenEnabled(value) { + var document = Browser.document; + var canvas = Render.canvas; + if (value) { + canvas.addEventListener('mousedown', this._requestFullscreen); + canvas.addEventListener('touchstart', this._requestFullscreen); + document.addEventListener("fullscreenchange", this._fullScreenChanged); + document.addEventListener("mozfullscreenchange", this._fullScreenChanged); + document.addEventListener("webkitfullscreenchange", this._fullScreenChanged); + document.addEventListener("msfullscreenchange", this._fullScreenChanged); + } + else { + canvas.removeEventListener('mousedown', this._requestFullscreen); + canvas.removeEventListener('touchstart', this._requestFullscreen); + document.removeEventListener("fullscreenchange", this._fullScreenChanged); + document.removeEventListener("mozfullscreenchange", this._fullScreenChanged); + document.removeEventListener("webkitfullscreenchange", this._fullScreenChanged); + document.removeEventListener("msfullscreenchange", this._fullScreenChanged); + } + } + get frameRate() { + if (!ILaya.Render.isConchApp) { + return this._frameRate; + } + else { + return this._frameRateNative; + } + } + set frameRate(value) { + if (!ILaya.Render.isConchApp) { + this._frameRate = value; + } + else { + var c = window.conch; + switch (value) { + case Stage.FRAME_FAST: + c.config.setLimitFPS(60); + break; + case Stage.FRAME_MOUSE: + c.config.setMouseFrame(2000); + break; + case Stage.FRAME_SLOW: + c.config.setSlowFrame(true); + break; + case Stage.FRAME_SLEEP: + c.config.setLimitFPS(1); + break; + } + this._frameRateNative = value; + } + } + _requestFullscreen() { + var element = Browser.document.documentElement; + if (element.requestFullscreen) { + element.requestFullscreen(); + } + else if (element.mozRequestFullScreen) { + element.mozRequestFullScreen(); + } + else if (element.webkitRequestFullscreen) { + element.webkitRequestFullscreen(); + } + else if (element.msRequestFullscreen) { + element.msRequestFullscreen(); + } + } + _fullScreenChanged() { + ILaya.stage.event(Event.FULL_SCREEN_CHANGE); + } + exitFullscreen() { + var document = Browser.document; + if (document.exitFullscreen) { + document.exitFullscreen(); + } + else if (document.mozCancelFullScreen) { + document.mozCancelFullScreen(); + } + else if (document.webkitExitFullscreen) { + document.webkitExitFullscreen(); + } + } + isGlobalRepaint() { + return this._globalRepaintGet; + } + setGlobalRepaint() { + this._globalRepaintSet = true; + } + add3DUI(uibase) { + var uiroot = uibase.rootView; + if (this._3dUI.indexOf(uiroot) >= 0) + return; + this._3dUI.push(uiroot); + } + remove3DUI(uibase) { + var uiroot = uibase.rootView; + var p = this._3dUI.indexOf(uiroot); + if (p >= 0) { + this._3dUI.splice(p, 1); + return true; + } + return false; + } + } + Stage.SCALE_NOSCALE = "noscale"; + Stage.SCALE_EXACTFIT = "exactfit"; + Stage.SCALE_SHOWALL = "showall"; + Stage.SCALE_NOBORDER = "noborder"; + Stage.SCALE_FULL = "full"; + Stage.SCALE_FIXED_WIDTH = "fixedwidth"; + Stage.SCALE_FIXED_HEIGHT = "fixedheight"; + Stage.SCALE_FIXED_AUTO = "fixedauto"; + Stage.ALIGN_LEFT = "left"; + Stage.ALIGN_RIGHT = "right"; + Stage.ALIGN_CENTER = "center"; + Stage.ALIGN_TOP = "top"; + Stage.ALIGN_MIDDLE = "middle"; + Stage.ALIGN_BOTTOM = "bottom"; + Stage.SCREEN_NONE = "none"; + Stage.SCREEN_HORIZONTAL = "horizontal"; + Stage.SCREEN_VERTICAL = "vertical"; + Stage.FRAME_FAST = "fast"; + Stage.FRAME_SLOW = "slow"; + Stage.FRAME_MOUSE = "mouse"; + Stage.FRAME_SLEEP = "sleep"; + Stage.clear = function (value) { + Context.set2DRenderConfig(); + var gl = LayaGL.instance; + RenderState2D.worldScissorTest && gl.disable(gl.SCISSOR_TEST); + var ctx = Render.context; + var c = (ctx._submits._length == 0 || Config.preserveDrawingBuffer) ? ColorUtils.create(value).arrColor : ILaya.stage._wgColor; + if (c) + ctx.clearBG(c[0], c[1], c[2], c[3]); + else + ctx.clearBG(0, 0, 0, 0); + RenderState2D.clear(); + }; + ClassUtils.regClass("laya.display.Stage", Stage); + ClassUtils.regClass("Laya.Stage", Stage); + + class KeyBoardManager { + static __init__() { + KeyBoardManager._addEvent("keydown"); + KeyBoardManager._addEvent("keypress"); + KeyBoardManager._addEvent("keyup"); + } + static _addEvent(type) { + ILaya.Browser.document.addEventListener(type, function (e) { + KeyBoardManager._dispatch(e, type); + }, true); + } + static _dispatch(e, type) { + if (!KeyBoardManager.enabled) + return; + KeyBoardManager._event._stoped = false; + KeyBoardManager._event.nativeEvent = e; + KeyBoardManager._event.keyCode = e.keyCode || e.which || e.charCode; + if (type === "keydown") + KeyBoardManager._pressKeys[KeyBoardManager._event.keyCode] = true; + else if (type === "keyup") + KeyBoardManager._pressKeys[KeyBoardManager._event.keyCode] = null; + var target = (ILaya.stage.focus && (ILaya.stage.focus.event != null) && ILaya.stage.focus.displayedInStage) ? ILaya.stage.focus : ILaya.stage; + var ct = target; + while (ct) { + ct.event(type, KeyBoardManager._event.setTo(type, ct, target)); + ct = ct.parent; + } + } + static hasKeyDown(key) { + return KeyBoardManager._pressKeys[key]; + } + } + KeyBoardManager._pressKeys = {}; + KeyBoardManager.enabled = true; + KeyBoardManager._event = new Event(); + + class SoundChannel extends EventDispatcher { + constructor() { + super(...arguments); + this.isStopped = false; + } + set volume(v) { + } + get volume() { + return 1; + } + get position() { + return 0; + } + get duration() { + return 0; + } + play() { + } + stop() { + if (this.completeHandler) + this.completeHandler.runWith(false); + } + pause() { + } + resume() { + } + __runComplete(handler) { + if (handler) { + handler.runWith(true); + } + } + } + + class AudioSoundChannel extends SoundChannel { + constructor(audio) { + super(); + this._audio = null; + this._onEnd = this.__onEnd.bind(this); + this._resumePlay = this.__resumePlay.bind(this); + audio.addEventListener("ended", this._onEnd); + this._audio = audio; + } + __onEnd(evt) { + if (this.loops == 1) { + if (this.completeHandler) { + ILaya.systemTimer.once(10, this, this.__runComplete, [this.completeHandler], false); + this.completeHandler = null; + } + this.stop(); + this.event(Event.COMPLETE); + return; + } + if (this.loops > 0) { + this.loops--; + } + this.startTime = 0; + this.play(); + } + __resumePlay() { + if (this._audio) + this._audio.removeEventListener("canplay", this._resumePlay); + if (this.isStopped) + return; + try { + this._audio.currentTime = this.startTime; + Browser.container.appendChild(this._audio); + this._audio.play(); + } + catch (e) { + this.event(Event.ERROR); + } + } + play() { + this.isStopped = false; + try { + this._audio.playbackRate = ILaya.SoundManager.playbackRate; + this._audio.currentTime = this.startTime; + } + catch (e) { + this._audio.addEventListener("canplay", this._resumePlay); + return; + } + ILaya.SoundManager.addChannel(this); + Browser.container.appendChild(this._audio); + if ("play" in this._audio) + this._audio.play(); + } + get position() { + if (!this._audio) + return 0; + return this._audio.currentTime; + } + get duration() { + if (!this._audio) + return 0; + return this._audio.duration; + } + stop() { + super.stop(); + this.isStopped = true; + ILaya.SoundManager.removeChannel(this); + this.completeHandler = null; + if (!this._audio) + return; + if ("pause" in this._audio) + if (ILaya.Render.isConchApp) { + this._audio.stop(); + } + this._audio.pause(); + this._audio.removeEventListener("ended", this._onEnd); + this._audio.removeEventListener("canplay", this._resumePlay); + if (!ILaya.Browser.onIE) { + if (this._audio != ILaya.AudioSound._musicAudio) { + ILaya.Pool.recover("audio:" + this.url, this._audio); + } + } + Browser.removeElement(this._audio); + this._audio = null; + if (ILaya.SoundManager.autoReleaseSound) + ILaya.SoundManager.disposeSoundLater(this.url); + } + pause() { + this.isStopped = true; + ILaya.SoundManager.removeChannel(this); + if (!this._audio) + return; + if ("pause" in this._audio) + this._audio.pause(); + if (ILaya.SoundManager.autoReleaseSound) + ILaya.SoundManager.disposeSoundLater(this.url); + } + resume() { + var audio = this._audio; + if (!audio) + return; + this.isStopped = false; + if (audio.readyState == 0) { + audio.src = this.url; + audio.addEventListener("canplay", this._resumePlay); + audio.load(); + } + ILaya.SoundManager.addChannel(this); + if ("play" in audio) { + audio.play(); + } + } + set volume(v) { + if (!this._audio) + return; + this._audio.volume = v; + } + get volume() { + if (!this._audio) + return 1; + return this._audio.volume; + } + } + + class AudioSound extends EventDispatcher { + constructor() { + super(...arguments); + this.loaded = false; + } + dispose() { + var ad = AudioSound._audioCache[this.url]; + Pool.clearBySign("audio:" + this.url); + if (ad) { + if (!Render.isConchApp) { + ad.src = ""; + } + delete AudioSound._audioCache[this.url]; + } + } + static _initMusicAudio() { + if (AudioSound._musicAudio) + return; + if (!AudioSound._musicAudio) + AudioSound._musicAudio = Browser.createElement("audio"); + if (!Render.isConchApp) { + Browser.document.addEventListener("mousedown", AudioSound._makeMusicOK); + } + } + static _makeMusicOK() { + Browser.document.removeEventListener("mousedown", AudioSound._makeMusicOK); + if (!AudioSound._musicAudio.src) { + AudioSound._musicAudio.src = ""; + AudioSound._musicAudio.load(); + } + else { + AudioSound._musicAudio.play(); + } + } + load(url) { + url = URL.formatURL(url); + this.url = url; + var ad; + if (url == ILaya.SoundManager._bgMusic) { + AudioSound._initMusicAudio(); + ad = AudioSound._musicAudio; + if (ad.src != url) { + delete AudioSound._audioCache[ad.src]; + ad = null; + } + } + else { + ad = AudioSound._audioCache[url]; + } + if (ad && ad.readyState >= 2) { + this.event(Event.COMPLETE); + return; + } + if (!ad) { + if (url == ILaya.SoundManager._bgMusic) { + AudioSound._initMusicAudio(); + ad = AudioSound._musicAudio; + } + else { + ad = Browser.createElement("audio"); + } + AudioSound._audioCache[url] = ad; + ad.src = url; + } + ad.addEventListener("canplaythrough", onLoaded); + ad.addEventListener("error", onErr); + var me = this; + function onLoaded() { + offs(); + me.loaded = true; + me.event(Event.COMPLETE); + } + function onErr() { + ad.load = null; + offs(); + me.event(Event.ERROR); + } + function offs() { + ad.removeEventListener("canplaythrough", onLoaded); + ad.removeEventListener("error", onErr); + } + this.audio = ad; + if (ad.load) { + ad.load(); + } + else { + onErr(); + } + } + play(startTime = 0, loops = 0) { + if (!this.url) + return null; + var ad; + if (this.url == ILaya.SoundManager._bgMusic) { + ad = AudioSound._musicAudio; + if (ad.src != "" && ad.src != this.url) { + delete AudioSound._audioCache[ad.src]; + AudioSound._audioCache[this.url] = ad; + } + } + else { + ad = AudioSound._audioCache[this.url]; + } + if (!ad) + return null; + var tAd; + tAd = Pool.getItem("audio:" + this.url); + if (Render.isConchApp) { + if (!tAd) { + tAd = Browser.createElement("audio"); + tAd.src = this.url; + } + } + else { + if (this.url == ILaya.SoundManager._bgMusic) { + AudioSound._initMusicAudio(); + tAd = AudioSound._musicAudio; + tAd.src = this.url; + } + else { + tAd = tAd ? tAd : ad.cloneNode(true); + } + } + var channel = new AudioSoundChannel(tAd); + channel.url = this.url; + channel.loops = loops; + channel.startTime = startTime; + channel.play(); + ILaya.SoundManager.addChannel(channel); + return channel; + } + get duration() { + var ad; + ad = AudioSound._audioCache[this.url]; + if (!ad) + return 0; + return ad.duration; + } + } + AudioSound._audioCache = {}; + + class WebAudioSoundChannel extends SoundChannel { + constructor() { + super(); + this.bufferSource = null; + this._currentTime = 0; + this._volume = 1; + this._startTime = 0; + this._pauseTime = 0; + this.context = ILaya.WebAudioSound.ctx; + this._onPlayEnd = Utils.bind(this.__onPlayEnd, this); + if (this.context["createGain"]) { + this.gain = this.context["createGain"](); + } + else { + this.gain = this.context["createGainNode"](); + } + } + play() { + ILaya.SoundManager.addChannel(this); + this.isStopped = false; + this._clearBufferSource(); + if (!this.audioBuffer) + return; + if (this.startTime >= this.duration) + return this.stop(); + var context = this.context; + var gain = this.gain; + var bufferSource = context.createBufferSource(); + this.bufferSource = bufferSource; + bufferSource.buffer = this.audioBuffer; + bufferSource.connect(gain); + if (gain) + gain.disconnect(); + gain.connect(context.destination); + bufferSource.onended = this._onPlayEnd; + this._startTime = Browser.now(); + if (this.gain.gain.setTargetAtTime) { + this.gain.gain.setTargetAtTime(this._volume, this.context.currentTime, WebAudioSoundChannel.SetTargetDelay); + } + else + this.gain.gain.value = this._volume; + if (this.loops == 0) { + bufferSource.loop = true; + } + if (bufferSource.playbackRate.setTargetAtTime) { + bufferSource.playbackRate.setTargetAtTime(ILaya.SoundManager.playbackRate, this.context.currentTime, WebAudioSoundChannel.SetTargetDelay); + } + else + bufferSource.playbackRate.value = ILaya.SoundManager.playbackRate; + bufferSource.start(0, this.startTime); + this._currentTime = 0; + } + __onPlayEnd() { + if (this.loops == 1) { + if (this.completeHandler) { + ILaya.timer.once(10, this, this.__runComplete, [this.completeHandler], false); + this.completeHandler = null; + } + this.stop(); + this.event(Event.COMPLETE); + return; + } + if (this.loops > 0) { + this.loops--; + } + this.startTime = 0; + this.play(); + } + get position() { + if (this.bufferSource) { + return (Browser.now() - this._startTime) / 1000 + this.startTime; + } + return 0; + } + get duration() { + if (this.audioBuffer) { + return this.audioBuffer.duration; + } + return 0; + } + _clearBufferSource() { + if (this.bufferSource) { + var sourceNode = this.bufferSource; + if (sourceNode.stop) { + sourceNode.stop(0); + } + else { + sourceNode.noteOff(0); + } + sourceNode.disconnect(0); + sourceNode.onended = null; + if (!WebAudioSoundChannel._tryCleanFailed) + this._tryClearBuffer(sourceNode); + this.bufferSource = null; + } + } + _tryClearBuffer(sourceNode) { + try { + sourceNode.buffer = null; + } + catch (e) { + WebAudioSoundChannel._tryCleanFailed = true; + } + } + stop() { + super.stop(); + this._clearBufferSource(); + this.audioBuffer = null; + if (this.gain) + this.gain.disconnect(); + this.isStopped = true; + ILaya.SoundManager.removeChannel(this); + this.completeHandler = null; + if (ILaya.SoundManager.autoReleaseSound) + ILaya.SoundManager.disposeSoundLater(this.url); + } + pause() { + if (!this.isStopped) { + this._pauseTime = this.position; + } + this._clearBufferSource(); + if (this.gain) + this.gain.disconnect(); + this.isStopped = true; + ILaya.SoundManager.removeChannel(this); + if (ILaya.SoundManager.autoReleaseSound) + ILaya.SoundManager.disposeSoundLater(this.url); + } + resume() { + this.startTime = this._pauseTime; + this.play(); + } + set volume(v) { + this._volume = v; + if (this.isStopped) { + return; + } + if (this.gain.gain.setTargetAtTime) { + this.gain.gain.setTargetAtTime(v, this.context.currentTime, WebAudioSoundChannel.SetTargetDelay); + } + else + this.gain.gain.value = v; + } + get volume() { + return this._volume; + } + } + WebAudioSoundChannel._tryCleanFailed = false; + WebAudioSoundChannel.SetTargetDelay = 0.001; + + class WebAudioSound extends EventDispatcher { + constructor() { + super(...arguments); + this.loaded = false; + this._disposed = false; + } + static decode() { + if (WebAudioSound.buffs.length <= 0 || WebAudioSound.isDecoding) { + return; + } + WebAudioSound.isDecoding = true; + WebAudioSound.tInfo = WebAudioSound.buffs.shift(); + WebAudioSound.ctx.decodeAudioData(WebAudioSound.tInfo["buffer"], WebAudioSound._done, WebAudioSound._fail); + } + static _done(audioBuffer) { + WebAudioSound.e.event("loaded:" + WebAudioSound.tInfo.url, audioBuffer); + WebAudioSound.isDecoding = false; + WebAudioSound.decode(); + } + static _fail() { + WebAudioSound.e.event("err:" + WebAudioSound.tInfo.url, null); + WebAudioSound.isDecoding = false; + WebAudioSound.decode(); + } + static _playEmptySound() { + if (WebAudioSound.ctx == null) { + return; + } + var source = WebAudioSound.ctx.createBufferSource(); + source.buffer = WebAudioSound._miniBuffer; + source.connect(WebAudioSound.ctx.destination); + source.start(0, 0, 0); + } + static _unlock() { + if (WebAudioSound._unlocked) { + return; + } + WebAudioSound._playEmptySound(); + if (WebAudioSound.ctx.state == "running") { + window.document.removeEventListener("mousedown", WebAudioSound._unlock, true); + window.document.removeEventListener("touchend", WebAudioSound._unlock, true); + window.document.removeEventListener("touchstart", WebAudioSound._unlock, true); + WebAudioSound._unlocked = true; + } + } + static initWebAudio() { + if (WebAudioSound.ctx.state != "running") { + WebAudioSound._unlock(); + window.document.addEventListener("mousedown", WebAudioSound._unlock, true); + window.document.addEventListener("touchend", WebAudioSound._unlock, true); + window.document.addEventListener("touchstart", WebAudioSound._unlock, true); + } + } + load(url) { + var me = this; + url = URL.formatURL(url); + this.url = url; + this.audioBuffer = WebAudioSound._dataCache[url]; + if (this.audioBuffer) { + this._loaded(this.audioBuffer); + return; + } + WebAudioSound.e.on("loaded:" + url, this, this._loaded); + WebAudioSound.e.on("err:" + url, this, this._err); + if (WebAudioSound.__loadingSound[url]) { + return; + } + WebAudioSound.__loadingSound[url] = true; + var request = new XMLHttpRequest(); + request.open("GET", url, true); + request.responseType = "arraybuffer"; + request.onload = function () { + if (me._disposed) { + me._removeLoadEvents(); + return; + } + me.data = request.response; + WebAudioSound.buffs.push({ "buffer": me.data, "url": me.url }); + WebAudioSound.decode(); + }; + request.onerror = function (e) { + me._err(); + }; + request.send(); + } + _err() { + this._removeLoadEvents(); + WebAudioSound.__loadingSound[this.url] = false; + this.event(Event.ERROR); + } + _loaded(audioBuffer) { + this._removeLoadEvents(); + if (this._disposed) { + return; + } + this.audioBuffer = audioBuffer; + WebAudioSound._dataCache[this.url] = this.audioBuffer; + this.loaded = true; + this.event(Event.COMPLETE); + } + _removeLoadEvents() { + WebAudioSound.e.off("loaded:" + this.url, this, this._loaded); + WebAudioSound.e.off("err:" + this.url, this, this._err); + } + __playAfterLoaded() { + if (!this.__toPlays) + return; + var i, len; + var toPlays; + toPlays = this.__toPlays; + len = toPlays.length; + var tParams; + for (i = 0; i < len; i++) { + tParams = toPlays[i]; + if (tParams[2] && !tParams[2].isStopped) { + this.play(tParams[0], tParams[1], tParams[2]); + } + } + this.__toPlays.length = 0; + } + play(startTime = 0, loops = 0, channel = null) { + channel = channel ? channel : new WebAudioSoundChannel(); + if (!this.audioBuffer) { + if (this.url) { + if (!this.__toPlays) + this.__toPlays = []; + this.__toPlays.push([startTime, loops, channel]); + this.once(Event.COMPLETE, this, this.__playAfterLoaded); + this.load(this.url); + } + } + channel.url = this.url; + channel.loops = loops; + channel.audioBuffer = this.audioBuffer; + channel.startTime = startTime; + channel.play(); + ILaya.SoundManager.addChannel(channel); + return channel; + } + get duration() { + if (this.audioBuffer) { + return this.audioBuffer.duration; + } + return 0; + } + dispose() { + this._disposed = true; + delete WebAudioSound._dataCache[this.url]; + delete WebAudioSound.__loadingSound[this.url]; + this.audioBuffer = null; + this.data = null; + this.__toPlays = []; + } + } + WebAudioSound._dataCache = {}; + WebAudioSound.webAudioEnabled = window["AudioContext"] || window["webkitAudioContext"] || window["mozAudioContext"]; + WebAudioSound.ctx = WebAudioSound.webAudioEnabled ? new (window["AudioContext"] || window["webkitAudioContext"] || window["mozAudioContext"])() : undefined; + WebAudioSound.buffs = []; + WebAudioSound.isDecoding = false; + WebAudioSound._miniBuffer = WebAudioSound.ctx ? WebAudioSound.ctx.createBuffer(1, 1, 22050) : undefined; + WebAudioSound.e = new EventDispatcher(); + WebAudioSound._unlocked = false; + WebAudioSound.__loadingSound = {}; + + class SoundManager { + static __init__() { + var win = ILaya.Browser.window; + var supportWebAudio = win["AudioContext"] || win["webkitAudioContext"] || win["mozAudioContext"] ? true : false; + if (supportWebAudio) + WebAudioSound.initWebAudio(); + SoundManager._soundClass = supportWebAudio ? WebAudioSound : AudioSound; + if (!Browser.onTBMiniGame) { + AudioSound._initMusicAudio(); + } + SoundManager._musicClass = AudioSound; + return supportWebAudio; + } + static addChannel(channel) { + if (SoundManager._channels.indexOf(channel) >= 0) + return; + SoundManager._channels.push(channel); + } + static removeChannel(channel) { + var i; + for (i = SoundManager._channels.length - 1; i >= 0; i--) { + if (SoundManager._channels[i] == channel) { + SoundManager._channels.splice(i, 1); + } + } + } + static disposeSoundLater(url) { + SoundManager._lastSoundUsedTimeDic[url] = ILaya.Browser.now(); + if (!SoundManager._isCheckingDispose) { + SoundManager._isCheckingDispose = true; + ILaya.timer.loop(5000, null, SoundManager._checkDisposeSound); + } + } + static _checkDisposeSound() { + var key; + var tTime = ILaya.Browser.now(); + var hasCheck = false; + for (key in SoundManager._lastSoundUsedTimeDic) { + if (tTime - SoundManager._lastSoundUsedTimeDic[key] > 30000) { + delete SoundManager._lastSoundUsedTimeDic[key]; + SoundManager.disposeSoundIfNotUsed(key); + } + else { + hasCheck = true; + } + } + if (!hasCheck) { + SoundManager._isCheckingDispose = false; + ILaya.timer.clear(null, SoundManager._checkDisposeSound); + } + } + static disposeSoundIfNotUsed(url) { + var i; + for (i = SoundManager._channels.length - 1; i >= 0; i--) { + if (SoundManager._channels[i].url == url) { + return; + } + } + SoundManager.destroySound(url); + } + static set autoStopMusic(v) { + ILaya.stage.off(Event.BLUR, null, SoundManager._stageOnBlur); + ILaya.stage.off(Event.FOCUS, null, SoundManager._stageOnFocus); + ILaya.stage.off(Event.VISIBILITY_CHANGE, null, SoundManager._visibilityChange); + SoundManager._autoStopMusic = v; + if (v) { + ILaya.stage.on(Event.BLUR, null, SoundManager._stageOnBlur); + ILaya.stage.on(Event.FOCUS, null, SoundManager._stageOnFocus); + ILaya.stage.on(Event.VISIBILITY_CHANGE, null, SoundManager._visibilityChange); + } + } + static get autoStopMusic() { + return SoundManager._autoStopMusic; + } + static _visibilityChange() { + if (ILaya.stage.isVisibility) { + SoundManager._stageOnFocus(); + } + else { + SoundManager._stageOnBlur(); + } + } + static _stageOnBlur() { + SoundManager._isActive = false; + if (SoundManager._musicChannel) { + if (!SoundManager._musicChannel.isStopped) { + SoundManager._blurPaused = true; + SoundManager._musicChannel.pause(); + } + } + SoundManager.stopAllSound(); + ILaya.stage.once(Event.MOUSE_DOWN, null, SoundManager._stageOnFocus); + } + static _recoverWebAudio() { + if (WebAudioSound.ctx && WebAudioSound.ctx.state != "running" && WebAudioSound.ctx.resume) + WebAudioSound.ctx.resume(); + } + static _stageOnFocus() { + SoundManager._isActive = true; + SoundManager._recoverWebAudio(); + ILaya.stage.off(Event.MOUSE_DOWN, null, SoundManager._stageOnFocus); + if (SoundManager._blurPaused) { + if (SoundManager._musicChannel && SoundManager._musicChannel.isStopped) { + SoundManager._blurPaused = false; + SoundManager._musicChannel.resume(); + } + } + } + static set muted(value) { + if (value == SoundManager._muted) + return; + if (value) { + SoundManager.stopAllSound(); + } + SoundManager.musicMuted = value; + SoundManager._muted = value; + } + static get muted() { + return SoundManager._muted; + } + static set soundMuted(value) { + SoundManager._soundMuted = value; + } + static get soundMuted() { + return SoundManager._soundMuted; + } + static set musicMuted(value) { + if (value == SoundManager._musicMuted) + return; + if (value) { + if (SoundManager._bgMusic) { + if (SoundManager._musicChannel && !SoundManager._musicChannel.isStopped) { + if (ILaya.Render.isConchApp) { + if (SoundManager._musicChannel._audio) + SoundManager._musicChannel._audio.muted = true; + } + else { + SoundManager._musicChannel.pause(); + } + } + else { + SoundManager._musicChannel = null; + } + } + else { + SoundManager._musicChannel = null; + } + SoundManager._musicMuted = value; + } + else { + SoundManager._musicMuted = value; + if (SoundManager._bgMusic) { + if (SoundManager._musicChannel) { + if (ILaya.Render.isConchApp) { + if (SoundManager._musicChannel._audio) + SoundManager._musicChannel._audio.muted = false; + } + else { + SoundManager._musicChannel.resume(); + } + } + } + } + } + static get musicMuted() { + return SoundManager._musicMuted; + } + static get useAudioMusic() { + return SoundManager._useAudioMusic; + } + static set useAudioMusic(value) { + SoundManager._useAudioMusic = value; + if (value) { + SoundManager._musicClass = AudioSound; + } + else { + SoundManager._musicClass = null; + } + } + static playSound(url, loops = 1, complete = null, soundClass = null, startTime = 0) { + if (!SoundManager._isActive || !url) + return null; + if (SoundManager._muted) + return null; + SoundManager._recoverWebAudio(); + url = URL.formatURL(url); + if (url == SoundManager._bgMusic) { + if (SoundManager._musicMuted) + return null; + } + else { + if (ILaya.Render.isConchApp) { + var ext = Utils.getFileExtension(url); + if (ext != "wav" && ext != "ogg") { + alert("The sound only supports wav or ogg format,for optimal performance reason,please refer to the official website document."); + return null; + } + } + if (SoundManager._soundMuted) + return null; + } + var tSound; + if (!Browser._isMiniGame) { + tSound = ILaya.loader.getRes(url); + } + if (!soundClass) + soundClass = SoundManager._soundClass; + if (!tSound) { + tSound = new soundClass(); + tSound.load(url); + if (!Browser._isMiniGame) { + ILaya.Loader.cacheRes(url, tSound); + } + } + var channel; + channel = tSound.play(startTime, loops); + if (!channel) + return null; + channel.url = url; + channel.volume = (url == SoundManager._bgMusic) ? SoundManager.musicVolume : SoundManager.soundVolume; + channel.completeHandler = complete; + return channel; + } + static destroySound(url) { + var tSound = ILaya.loader.getRes(url); + if (tSound) { + ILaya.Loader.clearRes(url); + tSound.dispose(); + } + } + static playMusic(url, loops = 0, complete = null, startTime = 0) { + url = URL.formatURL(url); + SoundManager._bgMusic = url; + if (SoundManager._musicChannel) + SoundManager._musicChannel.stop(); + return SoundManager._musicChannel = SoundManager.playSound(url, loops, complete, SoundManager._musicClass, startTime); + } + static stopSound(url) { + url = URL.formatURL(url); + var i; + var channel; + for (i = SoundManager._channels.length - 1; i >= 0; i--) { + channel = SoundManager._channels[i]; + if (channel.url == url) { + channel.stop(); + } + } + } + static stopAll() { + SoundManager._bgMusic = null; + var i; + var channel; + for (i = SoundManager._channels.length - 1; i >= 0; i--) { + channel = SoundManager._channels[i]; + channel.stop(); + } + } + static stopAllSound() { + var i; + var channel; + for (i = SoundManager._channels.length - 1; i >= 0; i--) { + channel = SoundManager._channels[i]; + if (channel.url != SoundManager._bgMusic) { + channel.stop(); + } + } + } + static stopMusic() { + if (SoundManager._musicChannel) + SoundManager._musicChannel.stop(); + SoundManager._bgMusic = null; + } + static setSoundVolume(volume, url = null) { + if (url) { + url = URL.formatURL(url); + SoundManager._setVolume(url, volume); + } + else { + SoundManager.soundVolume = volume; + var i; + var channel; + for (i = SoundManager._channels.length - 1; i >= 0; i--) { + channel = SoundManager._channels[i]; + if (channel.url != SoundManager._bgMusic) { + channel.volume = volume; + } + } + } + } + static setMusicVolume(volume) { + SoundManager.musicVolume = volume; + SoundManager._setVolume(SoundManager._bgMusic, volume); + } + static _setVolume(url, volume) { + url = URL.formatURL(url); + var i; + var channel; + for (i = SoundManager._channels.length - 1; i >= 0; i--) { + channel = SoundManager._channels[i]; + if (channel.url == url) { + channel.volume = volume; + } + } + } + } + SoundManager.musicVolume = 1; + SoundManager.soundVolume = 1; + SoundManager.playbackRate = 1; + SoundManager._useAudioMusic = true; + SoundManager._muted = false; + SoundManager._soundMuted = false; + SoundManager._musicMuted = false; + SoundManager._bgMusic = null; + SoundManager._musicChannel = null; + SoundManager._channels = []; + SoundManager._blurPaused = false; + SoundManager._isActive = true; + SoundManager._lastSoundUsedTimeDic = {}; + SoundManager._isCheckingDispose = false; + SoundManager.autoReleaseSound = true; + + class Prefab { + create() { + if (this.json) + return ILaya.SceneUtils.createByData(null, this.json); + return null; + } + } + + class BitmapFont { + constructor() { + this._fontCharDic = {}; + this._fontWidthMap = {}; + this._maxWidth = 0; + this._spaceWidth = 10; + this.fontSize = 12; + this.autoScaleSize = false; + this.letterSpacing = 0; + } + loadFont(path, complete) { + this._path = path; + this._complete = complete; + if (!path || path.indexOf(".fnt") === -1) { + console.error('Bitmap font configuration information must be a ".fnt" file'); + return; + } + ILaya.loader.load([{ url: path, type: ILaya.Loader.XML }, { url: path.replace(".fnt", ".png"), type: ILaya.Loader.IMAGE }], Handler.create(this, this._onLoaded)); + } + _onLoaded() { + this.parseFont(ILaya.Loader.getRes(this._path), ILaya.Loader.getRes(this._path.replace(".fnt", ".png"))); + this._complete && this._complete.run(); + } + parseFont(xml, texture) { + if (xml == null || texture == null) + return; + this._texture = texture; + var tScale = 1; + var tInfo = xml.getElementsByTagName("info"); + if (!tInfo[0].getAttributeNode) { + return this.parseFont2(xml, texture); + } + this.fontSize = parseInt(tInfo[0].getAttributeNode("size").nodeValue); + var tPadding = tInfo[0].getAttributeNode("padding").nodeValue; + var tPaddingArray = tPadding.split(","); + this._padding = [parseInt(tPaddingArray[0]), parseInt(tPaddingArray[1]), parseInt(tPaddingArray[2]), parseInt(tPaddingArray[3])]; + var chars = xml.getElementsByTagName("char"); + var i = 0; + for (i = 0; i < chars.length; i++) { + var tAttribute = chars[i]; + var tId = parseInt(tAttribute.getAttributeNode("id").nodeValue); + var xOffset = parseInt(tAttribute.getAttributeNode("xoffset").nodeValue) / tScale; + var yOffset = parseInt(tAttribute.getAttributeNode("yoffset").nodeValue) / tScale; + var xAdvance = parseInt(tAttribute.getAttributeNode("xadvance").nodeValue) / tScale; + var region = new Rectangle(); + region.x = parseInt(tAttribute.getAttributeNode("x").nodeValue); + region.y = parseInt(tAttribute.getAttributeNode("y").nodeValue); + region.width = parseInt(tAttribute.getAttributeNode("width").nodeValue); + region.height = parseInt(tAttribute.getAttributeNode("height").nodeValue); + var tTexture = Texture.create(texture, region.x, region.y, region.width, region.height, xOffset, yOffset); + this._maxWidth = Math.max(this._maxWidth, xAdvance + this.letterSpacing); + this._fontCharDic[tId] = tTexture; + this._fontWidthMap[tId] = xAdvance; + } + } + parseFont2(xml, texture) { + if (xml == null || texture == null) + return; + this._texture = texture; + var tScale = 1; + var tInfo = xml.getElementsByTagName("info"); + this.fontSize = parseInt(tInfo[0].attributes["size"].nodeValue); + var tPadding = tInfo[0].attributes["padding"].nodeValue; + var tPaddingArray = tPadding.split(","); + this._padding = [parseInt(tPaddingArray[0]), parseInt(tPaddingArray[1]), parseInt(tPaddingArray[2]), parseInt(tPaddingArray[3])]; + var chars = xml.getElementsByTagName("char"); + var i = 0; + for (i = 0; i < chars.length; i++) { + var tAttribute = chars[i].attributes; + var tId = parseInt(tAttribute["id"].nodeValue); + var xOffset = parseInt(tAttribute["xoffset"].nodeValue) / tScale; + var yOffset = parseInt(tAttribute["yoffset"].nodeValue) / tScale; + var xAdvance = parseInt(tAttribute["xadvance"].nodeValue) / tScale; + var region = new Rectangle(); + region.x = parseInt(tAttribute["x"].nodeValue); + region.y = parseInt(tAttribute["y"].nodeValue); + region.width = parseInt(tAttribute["width"].nodeValue); + region.height = parseInt(tAttribute["height"].nodeValue); + var tTexture = Texture.create(texture, region.x, region.y, region.width, region.height, xOffset, yOffset); + this._maxWidth = Math.max(this._maxWidth, xAdvance + this.letterSpacing); + this._fontCharDic[tId] = tTexture; + this._fontWidthMap[tId] = xAdvance; + } + } + getCharTexture(char) { + return this._fontCharDic[char.charCodeAt(0)]; + } + destroy() { + if (this._texture) { + for (var p in this._fontCharDic) { + var tTexture = this._fontCharDic[p]; + if (tTexture) + tTexture.destroy(); + } + this._texture.destroy(); + this._fontCharDic = null; + this._fontWidthMap = null; + this._texture = null; + this._complete = null; + this._padding = null; + } + } + setSpaceWidth(spaceWidth) { + this._spaceWidth = spaceWidth; + } + getCharWidth(char) { + var code = char.charCodeAt(0); + if (this._fontWidthMap[code]) + return this._fontWidthMap[code] + this.letterSpacing; + if (char === " ") + return this._spaceWidth + this.letterSpacing; + return 0; + } + getTextWidth(text) { + var tWidth = 0; + for (var i = 0, n = text.length; i < n; i++) { + tWidth += this.getCharWidth(text.charAt(i)); + } + return tWidth; + } + getMaxWidth() { + return this._maxWidth; + } + getMaxHeight() { + return this.fontSize; + } + _drawText(text, sprite, drawX, drawY, align, width) { + var tWidth = this.getTextWidth(text); + var tTexture; + var dx = 0; + align === "center" && (dx = (width - tWidth) / 2); + align === "right" && (dx = (width - tWidth)); + var tx = 0; + for (var i = 0, n = text.length; i < n; i++) { + tTexture = this.getCharTexture(text.charAt(i)); + if (tTexture) { + sprite.graphics.drawImage(tTexture, drawX + tx + dx, drawY); + tx += this.getCharWidth(text.charAt(i)); + } + } + } + } + ClassUtils.regClass("laya.display.BitmapFont", BitmapFont); + ClassUtils.regClass("Laya.BitmapFont", BitmapFont); + + class HttpRequest extends EventDispatcher { + constructor() { + super(...arguments); + this._http = new XMLHttpRequest(); + } + send(url, data = null, method = "get", responseType = "text", headers = null) { + this._responseType = responseType; + this._data = null; + if (Browser.onVVMiniGame || Browser.onQGMiniGame || Browser.onQQMiniGame || Browser.onAlipayMiniGame || Browser.onBLMiniGame || Browser.onHWMiniGame || Browser.onTTMiniGame || Browser.onTBMiniGame) { + url = HttpRequest._urlEncode(url); + } + this._url = url; + var _this = this; + var http = this._http; + http.open(method, url, true); + let isJson = false; + if (headers) { + for (var i = 0; i < headers.length; i++) { + http.setRequestHeader(headers[i++], headers[i]); + } + } + else if (!(window.conch)) { + if (!data || typeof (data) == 'string') + http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + else { + http.setRequestHeader("Content-Type", "application/json"); + if (!(data instanceof ArrayBuffer) && typeof data !== "string") { + isJson = true; + } + } + } + let restype = responseType !== "arraybuffer" ? "text" : "arraybuffer"; + http.responseType = restype; + if (http.dataType) { + http.dataType = restype; + } + http.onerror = function (e) { + _this._onError(e); + }; + http.onabort = function (e) { + _this._onAbort(e); + }; + http.onprogress = function (e) { + _this._onProgress(e); + }; + http.onload = function (e) { + _this._onLoad(e); + }; + if (Browser.onBLMiniGame && Browser.onAndroid && !data) + data = {}; + http.send(isJson ? JSON.stringify(data) : data); + } + _onProgress(e) { + if (e && e.lengthComputable) + this.event(Event.PROGRESS, e.loaded / e.total); + } + _onAbort(e) { + this.error("Request was aborted by user"); + } + _onError(e) { + this.error("Request failed Status:" + this._http.status + " text:" + this._http.statusText); + } + _onLoad(e) { + var http = this._http; + var status = http.status !== undefined ? http.status : 200; + if (status === 200 || status === 204 || status === 0) { + this.complete(); + } + else { + this.error("[" + http.status + "]" + http.statusText + ":" + http.responseURL); + } + } + error(message) { + this.clear(); + console.warn(this.url, message); + this.event(Event.ERROR, message); + } + complete() { + this.clear(); + var flag = true; + try { + if (this._responseType === "json") { + this._data = JSON.parse(this._http.responseText); + } + else if (this._responseType === "xml") { + this._data = Utils.parseXMLFromString(this._http.responseText); + } + else { + this._data = this._http.response || this._http.responseText; + } + } + catch (e) { + flag = false; + this.error(e.message); + } + flag && this.event(Event.COMPLETE, this._data instanceof Array ? [this._data] : this._data); + } + clear() { + var http = this._http; + http.onerror = http.onabort = http.onprogress = http.onload = null; + } + get url() { + return this._url; + } + get data() { + return this._data; + } + get http() { + return this._http; + } + } + HttpRequest._urlEncode = encodeURI; + + class Loader extends EventDispatcher { + constructor() { + super(...arguments); + this._customParse = false; + } + static getTypeFromUrl(url) { + var type = Utils.getFileExtension(url); + if (type) + return Loader.typeMap[type]; + console.warn("Not recognize the resources suffix", url); + return "text"; + } + load(url, type = null, cache = true, group = null, ignoreCache = false, useWorkerLoader = ILaya.WorkerLoader.enable) { + if (!url) { + this.onLoaded(null); + return; + } + Loader.setGroup(url, "666"); + this._url = url; + if (url.indexOf("data:image") === 0 && !type) + type = Loader.IMAGE; + else + url = URL.formatURL(url); + this._type = type || (type = Loader.getTypeFromUrl(this._url)); + this._cache = cache; + this._useWorkerLoader = useWorkerLoader; + this._data = null; + if (useWorkerLoader) + ILaya.WorkerLoader.enableWorkerLoader(); + var cacheRes; + if (type == Loader.IMAGE) { + cacheRes = Loader.textureMap[url]; + if (cacheRes && (!cacheRes.bitmap || (cacheRes.bitmap && cacheRes.bitmap.destroyed))) { + cacheRes = null; + } + } + else + cacheRes = Loader.loadedMap[url]; + if (!ignoreCache && cacheRes) { + this._data = cacheRes; + this.event(Event.PROGRESS, 1); + this.event(Event.COMPLETE, this._data); + return; + } + if (group) + Loader.setGroup(url, group); + if (Loader.parserMap[type] != null) { + this._customParse = true; + if (Loader.parserMap[type] instanceof Handler) + Loader.parserMap[type].runWith(this); + else + Loader.parserMap[type].call(null, this); + return; + } + this._loadResourceFilter(type, url); + } + _loadResourceFilter(type, url) { + this._loadResource(type, url); + } + _loadResource(type, url) { + switch (type) { + case Loader.IMAGE: + case "htmlimage": + case "nativeimage": + this._loadImage(url); + break; + case Loader.SOUND: + this._loadSound(url); + break; + case Loader.TTF: + this._loadTTF(url); + break; + case Loader.ATLAS: + case Loader.PREFAB: + case Loader.PLF: + this._loadHttpRequestWhat(url, Loader.JSON); + break; + case Loader.FONT: + this._loadHttpRequestWhat(url, Loader.XML); + break; + case Loader.PLFB: + this._loadHttpRequestWhat(url, Loader.BUFFER); + break; + default: + this._loadHttpRequestWhat(url, type); + } + } + _loadHttpRequest(url, contentType, onLoadCaller, onLoad, onProcessCaller, onProcess, onErrorCaller, onError) { + if (Browser.onVVMiniGame || Browser.onHWMiniGame) { + this._http = new HttpRequest(); + } + else { + if (!this._http) + this._http = new HttpRequest(); + } + onProcess && this._http.on(Event.PROGRESS, onProcessCaller, onProcess); + onLoad && this._http.on(Event.COMPLETE, onLoadCaller, onLoad); + this._http.on(Event.ERROR, onErrorCaller, onError); + this._http.send(url, null, "get", contentType); + } + _loadHtmlImage(url, onLoadCaller, onLoad, onErrorCaller, onError) { + var image; + function clear() { + var img = image; + img.onload = null; + img.onerror = null; + delete Loader._imgCache[url]; + } + var onerror = function () { + clear(); + onError.call(onErrorCaller); + }; + var onload = function () { + clear(); + onLoad.call(onLoadCaller, image); + }; + image = new Browser.window.Image(); + image.crossOrigin = ""; + image.onload = onload; + image.onerror = onerror; + image.src = url; + Loader._imgCache[url] = image; + } + _loadHttpRequestWhat(url, contentType) { + if (Loader.preLoadedMap[url]) + this.onLoaded(Loader.preLoadedMap[url]); + else + this._loadHttpRequest(url, contentType, this, this.onLoaded, this, this.onProgress, this, this.onError); + } + _loadTTF(url) { + url = URL.formatURL(url); + var ttfLoader = new ILaya.TTFLoader(); + ttfLoader.complete = Handler.create(this, this.onLoaded); + ttfLoader.load(url); + } + _loadImage(url, isformatURL = true) { + var _this = this; + if (isformatURL) + url = URL.formatURL(url); + var onError = function () { + _this.event(Event.ERROR, "Load image failed"); + }; + if (this._type === "nativeimage") { + this._loadHtmlImage(url, this, this.onLoaded, this, onError); + } + else { + var ext = Utils.getFileExtension(url); + if (ext == 'bin' && this._url) { + ext = Utils.getFileExtension(this._url); + } + if (ext === "ktx" || ext === "pvr") + this._loadHttpRequest(url, Loader.BUFFER, this, this.onLoaded, this, this.onProgress, this, this.onError); + else + this._loadHtmlImage(url, this, this.onLoaded, this, onError); + } + } + _loadSound(url) { + var sound = (new SoundManager._soundClass()); + var _this = this; + sound.on(Event.COMPLETE, this, soundOnload); + sound.on(Event.ERROR, this, soundOnErr); + sound.load(url); + function soundOnload() { + clear(); + _this.onLoaded(sound); + } + function soundOnErr() { + clear(); + sound.dispose(); + _this.event(Event.ERROR, "Load sound failed"); + } + function clear() { + sound.offAll(); + } + } + onProgress(value) { + if (this._type === Loader.ATLAS) + this.event(Event.PROGRESS, value * 0.3); + else if (this._originType == Loader.HIERARCHY) + this.event(Event.PROGRESS, value / 3); + else + this.event(Event.PROGRESS, value); + } + onError(message) { + this.event(Event.ERROR, message); + } + onLoaded(data = null) { + var type = this._type; + if (type == Loader.PLFB) { + this.parsePLFBData(data); + this.complete(data); + } + else if (type == Loader.PLF) { + this.parsePLFData(data); + this.complete(data); + } + else if (type === Loader.IMAGE) { + let tex; + if (data instanceof ArrayBuffer) { + var ext = Utils.getFileExtension(this._url); + let format; + switch (ext) { + case "ktx": + format = exports.TextureFormat.ETC1RGB; + break; + case "pvr": + format = exports.TextureFormat.PVRTCRGBA_4BPPV; + break; + default: { + console.error('unknown format', ext); + return; + } + } + tex = new Texture2D(0, 0, format, false, false); + tex.wrapModeU = exports.WarpMode.Clamp; + tex.wrapModeV = exports.WarpMode.Clamp; + tex.setCompressData(data); + tex._setCreateURL(this.url); + } + else if (!(data instanceof Texture2D)) { + tex = new Texture2D(data.width, data.height, 1, false, false); + tex.wrapModeU = exports.WarpMode.Clamp; + tex.wrapModeV = exports.WarpMode.Clamp; + tex.loadImageSource(data, true); + tex._setCreateURL(data.src); + } + else { + tex = data; + } + var texture = new Texture(tex); + texture.url = this._url; + this.complete(texture); + } + else if (type === Loader.SOUND || type === "nativeimage") { + this.complete(data); + } + else if (type === "htmlimage") { + let tex = new Texture2D(data.width, data.height, 1, false, false); + tex.wrapModeU = exports.WarpMode.Clamp; + tex.wrapModeV = exports.WarpMode.Clamp; + tex.loadImageSource(data, true); + tex._setCreateURL(data.src); + this.complete(tex); + } + else if (type === Loader.ATLAS) { + if (data.frames) { + var toloadPics = []; + if (!this._data) { + this._data = data; + if (data.meta && data.meta.image) { + toloadPics = data.meta.image.split(","); + var split = this._url.indexOf("/") >= 0 ? "/" : "\\"; + var idx = this._url.lastIndexOf(split); + var folderPath = idx >= 0 ? this._url.substr(0, idx + 1) : ""; + var changeType = null; + if (Browser.onAndroid && data.meta.compressTextureAndroid) { + changeType = ".ktx"; + } + if (Browser.onIOS && data.meta.compressTextureIOS) { + if (data.meta.astc) { + changeType = ".ktx"; + } + else { + changeType = ".pvr"; + } + } + for (var i = 0, len = toloadPics.length; i < len; i++) { + if (changeType) { + toloadPics[i] = folderPath + toloadPics[i].replace(".png", changeType); + } + else { + toloadPics[i] = folderPath + toloadPics[i]; + } + } + } + else { + toloadPics = [this._url.replace(".json", ".png")]; + } + toloadPics.reverse(); + data.toLoads = toloadPics; + data.pics = []; + } + this.event(Event.PROGRESS, 0.3 + 1 / toloadPics.length * 0.6); + var url = URL.formatURL(toloadPics.pop()); + var ext = Utils.getFileExtension(url); + var type = Loader.IMAGE; + if (ext == "pvr" || ext == "ktx") { + type = Loader.BUFFER; + } + return this._loadResourceFilter(type, url); + } + else { + if (!(data instanceof Texture2D)) { + if (data instanceof ArrayBuffer) { + let url = this._http ? this._http.url : this._url; + var ext = Utils.getFileExtension(url); + let format; + switch (ext) { + case "ktx": + format = exports.TextureFormat.ETC1RGB; + break; + case "pvr": + format = exports.TextureFormat.PVRTCRGBA_4BPPV; + break; + default: { + console.error('unknown format', ext); + return; + } + } + let tex = new Texture2D(0, 0, format, false, false); + tex.wrapModeU = exports.WarpMode.Clamp; + tex.wrapModeV = exports.WarpMode.Clamp; + tex.setCompressData(data); + tex._setCreateURL(url); + data = tex; + } + else { + let tex = new Texture2D(data.width, data.height, 1, false, false); + tex.wrapModeU = exports.WarpMode.Clamp; + tex.wrapModeV = exports.WarpMode.Clamp; + tex.loadImageSource(data, true); + tex._setCreateURL(data.src); + data = tex; + } + } + this._data.pics.push(data); + if (this._data.toLoads.length > 0) { + this.event(Event.PROGRESS, 0.3 + 1 / this._data.toLoads.length * 0.6); + var url = URL.formatURL(this._data.toLoads.pop()); + var ext = Utils.getFileExtension(url); + var type = Loader.IMAGE; + if (ext == "pvr" || ext == "ktx") { + type = Loader.BUFFER; + } + return this._loadResourceFilter(type, url); + } + var frames = this._data.frames; + var cleanUrl = this._url.split("?")[0]; + var directory = (this._data.meta && this._data.meta.prefix) ? this._data.meta.prefix : cleanUrl.substring(0, cleanUrl.lastIndexOf(".")) + "/"; + var pics = this._data.pics; + var atlasURL = URL.formatURL(this._url); + var map = Loader.atlasMap[atlasURL] || (Loader.atlasMap[atlasURL] = []); + map.dir = directory; + var scaleRate = 1; + if (this._data.meta && this._data.meta.scale && this._data.meta.scale != 1) { + scaleRate = parseFloat(this._data.meta.scale); + for (var name in frames) { + var obj = frames[name]; + var tPic = pics[obj.frame.idx ? obj.frame.idx : 0]; + var url = URL.formatURL(directory + name); + tPic.scaleRate = scaleRate; + var tTexture; + tTexture = Texture._create(tPic, obj.frame.x, obj.frame.y, obj.frame.w, obj.frame.h, obj.spriteSourceSize.x, obj.spriteSourceSize.y, obj.sourceSize.w, obj.sourceSize.h, Loader.getRes(url)); + Loader.cacheTexture(url, tTexture); + tTexture.url = url; + map.push(url); + } + } + else { + for (name in frames) { + obj = frames[name]; + tPic = pics[obj.frame.idx ? obj.frame.idx : 0]; + url = URL.formatURL(directory + name); + tTexture = Texture._create(tPic, obj.frame.x, obj.frame.y, obj.frame.w, obj.frame.h, obj.spriteSourceSize.x, obj.spriteSourceSize.y, obj.sourceSize.w, obj.sourceSize.h, Loader.getRes(url)); + Loader.cacheTexture(url, tTexture); + tTexture.url = url; + map.push(url); + } + } + delete this._data.pics; + this.complete(this._data); + } + } + else if (type === Loader.FONT) { + if (!data._source) { + this._data = data; + this.event(Event.PROGRESS, 0.5); + return this._loadResourceFilter(Loader.IMAGE, this._url.replace(".fnt", ".png")); + } + else { + var bFont = new BitmapFont(); + bFont.parseFont(this._data, new Texture(data)); + var tArr = this._url.split(".fnt")[0].split("/"); + var fontName = tArr[tArr.length - 1]; + Text.registerBitmapFont(fontName, bFont); + this._data = bFont; + this.complete(this._data); + } + } + else if (type === Loader.PREFAB) { + var prefab = new Prefab(); + prefab.json = data; + this.complete(prefab); + } + else { + this.complete(data); + } + } + parsePLFData(plfData) { + var type; + var filePath; + var fileDic; + for (type in plfData) { + fileDic = plfData[type]; + switch (type) { + case "json": + case "text": + for (filePath in fileDic) { + Loader.preLoadedMap[URL.formatURL(filePath)] = fileDic[filePath]; + } + break; + default: + for (filePath in fileDic) { + Loader.preLoadedMap[URL.formatURL(filePath)] = fileDic[filePath]; + } + } + } + } + parsePLFBData(plfData) { + var byte; + byte = new Byte(plfData); + var i, len; + len = byte.getInt32(); + for (i = 0; i < len; i++) { + this.parseOnePLFBFile(byte); + } + } + parseOnePLFBFile(byte) { + var fileLen; + var fileName; + var fileData; + fileName = byte.getUTFString(); + fileLen = byte.getInt32(); + fileData = byte.readArrayBuffer(fileLen); + Loader.preLoadedMap[URL.formatURL(fileName)] = fileData; + } + complete(data) { + this._data = data; + if (this._customParse) { + this.event(Event.LOADED, data instanceof Array ? [data] : data); + } + else { + Loader._loaders.push(this); + if (!Loader._isWorking) + Loader.checkNext(); + } + } + static checkNext() { + Loader._isWorking = true; + var startTimer = Browser.now(); + while (Loader._startIndex < Loader._loaders.length) { + Loader._loaders[Loader._startIndex].endLoad(); + Loader._startIndex++; + if (Browser.now() - startTimer > Loader.maxTimeOut) { + console.warn("loader callback cost a long time:" + (Browser.now() - startTimer) + " url=" + Loader._loaders[Loader._startIndex - 1].url); + ILaya.systemTimer.frameOnce(1, null, Loader.checkNext); + return; + } + } + Loader._loaders.length = 0; + Loader._startIndex = 0; + Loader._isWorking = false; + } + endLoad(content = null) { + content && (this._data = content); + if (this._cache) + Loader.cacheRes(this._url, this._data); + this.event(Event.PROGRESS, 1); + this.event(Event.COMPLETE, this.data instanceof Array ? [this.data] : this.data); + } + get url() { + return this._url; + } + get type() { + return this._type; + } + get cache() { + return this._cache; + } + get data() { + return this._data; + } + static clearRes(url) { + url = URL.formatURL(url); + var arr = Loader.getAtlas(url); + if (arr) { + for (var i = 0, n = arr.length; i < n; i++) { + var resUrl = arr[i]; + var tex = Loader.getRes(resUrl); + delete Loader.textureMap[resUrl]; + if (tex) + tex.destroy(); + } + arr.length = 0; + delete Loader.atlasMap[url]; + } + var texture = Loader.textureMap[url]; + if (texture) { + texture.destroy(); + delete Loader.textureMap[url]; + } + var res = Loader.loadedMap[url]; + (res) && (delete Loader.loadedMap[url]); + } + static clearTextureRes(url) { + url = URL.formatURL(url); + var arr = Loader.getAtlas(url); + if (arr && arr.length > 0) { + arr.forEach(function (t) { + var tex = Loader.getRes(t); + if (tex instanceof Texture) { + tex.disposeBitmap(); + } + }); + } + else { + var t = Loader.getRes(url); + if (t instanceof Texture) { + t.disposeBitmap(); + } + } + } + static getRes(url) { + var res = Loader.textureMap[URL.formatURL(url)]; + if (res) + return res; + else + return Loader.loadedMap[URL.formatURL(url)]; + } + static getAtlas(url) { + return Loader.atlasMap[URL.formatURL(url)]; + } + static cacheRes(url, data) { + url = URL.formatURL(url); + if (Loader.loadedMap[url] != null) { + console.warn("Resources already exist,is repeated loading:", url); + } + else { + if (data instanceof Texture) { + Loader.loadedMap[url] = data.bitmap; + Loader.textureMap[url] = data; + } + else { + Loader.loadedMap[url] = data; + } + } + } + static cacheResForce(url, data) { + Loader.loadedMap[url] = data; + } + static cacheTexture(url, data) { + url = URL.formatURL(url); + if (Loader.textureMap[url] != null) { + console.warn("Resources already exist,is repeated loading:", url); + } + else { + Loader.textureMap[url] = data; + } + } + static setGroup(url, group) { + if (!Loader.groupMap[group]) + Loader.groupMap[group] = []; + Loader.groupMap[group].push(url); + } + static clearResByGroup(group) { + if (!Loader.groupMap[group]) + return; + var arr = Loader.groupMap[group], i, len = arr.length; + for (i = 0; i < len; i++) { + Loader.clearRes(arr[i]); + } + arr.length = 0; + } + } + Loader.TEXT = "text"; + Loader.JSON = "json"; + Loader.PREFAB = "prefab"; + Loader.XML = "xml"; + Loader.BUFFER = "arraybuffer"; + Loader.IMAGE = "image"; + Loader.SOUND = "sound"; + Loader.ATLAS = "atlas"; + Loader.FONT = "font"; + Loader.TTF = "ttf"; + Loader.PLF = "plf"; + Loader.PLFB = "plfb"; + Loader.HIERARCHY = "HIERARCHY"; + Loader.MESH = "MESH"; + Loader.MATERIAL = "MATERIAL"; + Loader.TEXTURE2D = "TEXTURE2D"; + Loader.TEXTURECUBE = "TEXTURECUBE"; + Loader.ANIMATIONCLIP = "ANIMATIONCLIP"; + Loader.AVATAR = "AVATAR"; + Loader.TERRAINHEIGHTDATA = "TERRAINHEIGHTDATA"; + Loader.TERRAINRES = "TERRAIN"; + Loader.typeMap = { "ttf": "ttf", "png": "image", "jpg": "image", "jpeg": "image", "ktx": "image", "pvr": "image", "txt": "text", "json": "json", "prefab": "prefab", "xml": "xml", "als": "atlas", "atlas": "atlas", "mp3": "sound", "ogg": "sound", "wav": "sound", "part": "json", "fnt": "font", "plf": "plf", "plfb": "plfb", "scene": "json", "ani": "json", "sk": "arraybuffer", "wasm": "arraybuffer" }; + Loader.parserMap = {}; + Loader.maxTimeOut = 100; + Loader.groupMap = {}; + Loader.loadedMap = {}; + Loader.atlasMap = {}; + Loader.textureMap = {}; + Loader.preLoadedMap = {}; + Loader._imgCache = {}; + Loader._loaders = []; + Loader._isWorking = false; + Loader._startIndex = 0; + + class AtlasInfoManager { + static enable(infoFile, callback = null) { + ILaya.loader.load(infoFile, Handler.create(null, AtlasInfoManager._onInfoLoaded, [callback]), null, Loader.JSON); + } + static _onInfoLoaded(callback, data) { + var tKey; + var tPrefix; + var tArr; + var i, len; + for (tKey in data) { + tArr = data[tKey]; + tPrefix = tArr[0]; + tArr = tArr[1]; + len = tArr.length; + for (i = 0; i < len; i++) { + AtlasInfoManager._fileLoadDic[tPrefix + tArr[i]] = tKey; + } + } + callback && callback.run(); + } + static getFileLoadPath(file) { + return AtlasInfoManager._fileLoadDic[file] || file; + } + } + AtlasInfoManager._fileLoadDic = {}; + + class LoaderManager extends EventDispatcher { + constructor() { + super(); + this.retryNum = 1; + this.retryDelay = 0; + this.maxLoader = 5; + this._loaders = []; + this._loaderCount = 0; + this._resInfos = []; + this._infoPool = []; + this._maxPriority = 5; + this._failRes = {}; + this._statInfo = { count: 1, loaded: 1 }; + for (var i = 0; i < this._maxPriority; i++) + this._resInfos[i] = []; + } + getProgress() { + return this._statInfo.loaded / this._statInfo.count; + } + resetProgress() { + this._statInfo.count = this._statInfo.loaded = 1; + } + create(url, complete = null, progress = null, type = null, constructParams = null, propertyParams = null, priority = 1, cache = true) { + this._create(url, true, complete, progress, type, constructParams, propertyParams, priority, cache); + } + _create(url, mainResou, complete = null, progress = null, type = null, constructParams = null, propertyParams = null, priority = 1, cache = true) { + if (url instanceof Array) { + var allScuess = true; + var items = url; + var itemCount = items.length; + var loadedCount = 0; + if (progress) { + var progress2 = Handler.create(progress.caller, progress ? progress.method : null, progress.args, false); + } + for (var i = 0; i < itemCount; i++) { + var item = items[i]; + if (typeof (item) == 'string') + item = items[i] = { url: item }; + item.progress = 0; + } + for (i = 0; i < itemCount; i++) { + item = items[i]; + var progressHandler = progress ? Handler.create(null, function (item, value) { + item.progress = value; + var num = 0; + for (var j = 0; j < itemCount; j++) { + var item1 = items[j]; + num += item1.progress; + } + var v = num / itemCount; + progress2.runWith(v); + }, [item], false) : null; + var completeHandler = (progress || complete) ? Handler.create(null, function (item, content = null) { + loadedCount++; + item.progress = 1; + content || (allScuess = false); + if (loadedCount === itemCount && complete) { + complete.runWith(allScuess); + } + }, [item]) : null; + this._createOne(item.url, mainResou, completeHandler, progressHandler, item.type || type, item.constructParams || constructParams, item.propertyParams || propertyParams, item.priority || priority, cache); + } + } + else { + this._createOne(url, mainResou, complete, progress, type, constructParams, propertyParams, priority, cache); + } + } + _createOne(url, mainResou, complete = null, progress = null, type = null, constructParams = null, propertyParams = null, priority = 1, cache = true) { + var item = this.getRes(url); + if (!item) { + var extension = (LoaderManager.createMap[Utils.getFilecompatibleExtension(url)]) ? Utils.getFilecompatibleExtension(url) : Utils.getFileExtension(url); + (type) || (type = LoaderManager.createMap[extension] ? LoaderManager.createMap[extension][0] : null); + if (!type) { + this.load(url, complete, progress, type, priority, cache); + return; + } + var parserMap = Loader.parserMap; + if (!parserMap[type]) { + this.load(url, complete, progress, type, priority, cache); + return; + } + this._createLoad(url, Handler.create(null, function (createRes) { + if (createRes) { + if (!mainResou && createRes instanceof Resource) + createRes._addReference(); + createRes._setCreateURL(url); + } + complete && complete.runWith(createRes); + ILaya.loader.event(url); + }), progress, type, constructParams, propertyParams, priority, cache, true); + } + else { + if (!mainResou && item instanceof Resource) + item._addReference(); + progress && progress.runWith(1); + complete && complete.runWith(item); + } + } + load(url, complete = null, progress = null, type = null, priority = 1, cache = true, group = null, ignoreCache = false, useWorkerLoader = ILaya.WorkerLoader.enable) { + if (url instanceof Array) { + return this._loadAssets(url, complete, progress, type, priority, cache, group); + } + if (!type) { + if (url.indexOf("data:image") === 0) + type = Loader.IMAGE; + else + type = Loader.getTypeFromUrl(url); + } + var content; + if (type === Loader.IMAGE) { + content = Loader.textureMap[URL.formatURL(url)]; + if (content && (!content.bitmap || (content.bitmap && content.bitmap.destroyed))) { + content = null; + } + } + else + content = Loader.loadedMap[URL.formatURL(url)]; + if (!ignoreCache && content != null) { + ILaya.systemTimer.callLater(this, function () { + progress && progress.runWith(1); + complete && complete.runWith(content instanceof Array ? [content] : content); + this._loaderCount || this.event(Event.COMPLETE); + }); + } + else { + var original; + original = url; + url = AtlasInfoManager.getFileLoadPath(url); + if (url != original && type !== "nativeimage") { + type = Loader.ATLAS; + } + else { + original = null; + } + var info = LoaderManager._resMap[url]; + if (!info) { + info = this._infoPool.length ? this._infoPool.pop() : new ResInfo(); + info.url = url; + info.type = type; + info.cache = cache; + info.group = group; + info.ignoreCache = ignoreCache; + info.useWorkerLoader = useWorkerLoader; + info.originalUrl = original; + complete && info.on(Event.COMPLETE, complete.caller, complete.method, complete.args); + progress && info.on(Event.PROGRESS, progress.caller, progress.method, progress.args); + LoaderManager._resMap[url] = info; + priority = priority < this._maxPriority ? priority : this._maxPriority - 1; + this._resInfos[priority].push(info); + this._statInfo.count++; + this.event(Event.PROGRESS, this.getProgress()); + this._next(); + } + else { + if (complete) { + if (original) { + complete && info._createListener(Event.COMPLETE, this, this._resInfoLoaded, [original, complete], false, false); + } + else { + complete && info._createListener(Event.COMPLETE, complete.caller, complete.method, complete.args, false, false); + } + } + progress && info._createListener(Event.PROGRESS, progress.caller, progress.method, progress.args, false, false); + } + } + return this; + } + _resInfoLoaded(original, complete) { + complete.runWith(Loader.getRes(original)); + } + _createLoad(url, complete = null, progress = null, type = null, constructParams = null, propertyParams = null, priority = 1, cache = true, ignoreCache = false) { + if (url instanceof Array) + return this._loadAssets(url, complete, progress, type, priority, cache); + var content = Loader.getRes(url); + if (content != null) { + ILaya.systemTimer.frameOnce(1, this, function () { + progress && progress.runWith(1); + complete && complete.runWith(content); + this._loaderCount || this.event(Event.COMPLETE); + }); + } + else { + var info = LoaderManager._resMap[url]; + if (!info) { + info = this._infoPool.length ? this._infoPool.pop() : new ResInfo(); + info.url = url; + info.type = type; + info.cache = false; + info.ignoreCache = ignoreCache; + info.originalUrl = null; + info.group = null; + info.createCache = cache; + info.createConstructParams = constructParams; + info.createPropertyParams = propertyParams; + complete && info.on(Event.COMPLETE, complete.caller, complete.method, complete.args); + progress && info.on(Event.PROGRESS, progress.caller, progress.method, progress.args); + LoaderManager._resMap[url] = info; + priority = priority < this._maxPriority ? priority : this._maxPriority - 1; + this._resInfos[priority].push(info); + this._statInfo.count++; + this.event(Event.PROGRESS, this.getProgress()); + this._next(); + } + else { + complete && info._createListener(Event.COMPLETE, complete.caller, complete.method, complete.args, false, false); + progress && info._createListener(Event.PROGRESS, progress.caller, progress.method, progress.args, false, false); + } + } + return this; + } + _next() { + if (this._loaderCount >= this.maxLoader) + return; + for (var i = 0; i < this._maxPriority; i++) { + var infos = this._resInfos[i]; + while (infos.length > 0) { + var info = infos.shift(); + if (info) + return this._doLoad(info); + } + } + this._loaderCount || this.event(Event.COMPLETE); + } + _doLoad(resInfo) { + this._loaderCount++; + var loader = this._loaders.length ? this._loaders.pop() : new Loader(); + loader.on(Event.COMPLETE, null, onLoaded); + loader.on(Event.PROGRESS, null, function (num) { + resInfo.event(Event.PROGRESS, num); + }); + loader.on(Event.ERROR, null, function (msg) { + onLoaded(null); + }); + var _me = this; + function onLoaded(data = null) { + loader.offAll(); + loader._data = null; + loader._customParse = false; + _me._loaders.push(loader); + _me._endLoad(resInfo, data instanceof Array ? [data] : data); + _me._loaderCount--; + _me._next(); + } + loader._constructParams = resInfo.createConstructParams; + loader._propertyParams = resInfo.createPropertyParams; + loader._createCache = resInfo.createCache; + loader.load(resInfo.url, resInfo.type, resInfo.cache, resInfo.group, resInfo.ignoreCache, resInfo.useWorkerLoader); + } + _endLoad(resInfo, content) { + var url = resInfo.url; + if (content == null) { + var errorCount = this._failRes[url] || 0; + if (errorCount < this.retryNum) { + console.warn("[warn]Retry to load:", url); + this._failRes[url] = errorCount + 1; + ILaya.systemTimer.once(this.retryDelay, this, this._addReTry, [resInfo], false); + return; + } + else { + Loader.clearRes(url); + console.warn("[error]Failed to load:", url); + this.event(Event.ERROR, url); + } + } + if (this._failRes[url]) + this._failRes[url] = 0; + delete LoaderManager._resMap[url]; + if (resInfo.originalUrl) { + content = Loader.getRes(resInfo.originalUrl); + } + resInfo.event(Event.COMPLETE, content); + resInfo.offAll(); + this._infoPool.push(resInfo); + this._statInfo.loaded++; + this.event(Event.PROGRESS, this.getProgress()); + } + _addReTry(resInfo) { + this._resInfos[this._maxPriority - 1].push(resInfo); + this._next(); + } + clearRes(url) { + Loader.clearRes(url); + } + clearTextureRes(url) { + Loader.clearTextureRes(url); + } + getRes(url) { + return Loader.getRes(url); + } + cacheRes(url, data) { + Loader.cacheRes(url, data); + } + setGroup(url, group) { + Loader.setGroup(url, group); + } + clearResByGroup(group) { + Loader.clearResByGroup(group); + } + static cacheRes(url, data) { + Loader.cacheRes(url, data); + } + clearUnLoaded() { + for (var i = 0; i < this._maxPriority; i++) { + var infos = this._resInfos[i]; + for (var j = infos.length - 1; j > -1; j--) { + var info = infos[j]; + if (info) { + info.offAll(); + this._infoPool.push(info); + } + } + infos.length = 0; + } + this._loaderCount = 0; + LoaderManager._resMap = {}; + } + cancelLoadByUrls(urls) { + if (!urls) + return; + for (var i = 0, n = urls.length; i < n; i++) { + this.cancelLoadByUrl(urls[i]); + } + } + cancelLoadByUrl(url) { + for (var i = 0; i < this._maxPriority; i++) { + var infos = this._resInfos[i]; + for (var j = infos.length - 1; j > -1; j--) { + var info = infos[j]; + if (info && info.url === url) { + infos[j] = null; + info.offAll(); + this._infoPool.push(info); + } + } + } + if (LoaderManager._resMap[url]) + delete LoaderManager._resMap[url]; + } + _loadAssets(arr, complete = null, progress = null, type = null, priority = 1, cache = true, group = null) { + var itemCount = arr.length; + var loadedCount = 0; + var totalSize = 0; + var items = []; + var success = true; + for (var i = 0; i < itemCount; i++) { + let url = arr[i]; + let item; + if (typeof (url) == 'string') + item = { url: url, type: type, size: 1, priority: priority }; + else + item = url; + if (!item.size) + item.size = 1; + item.progress = 0; + totalSize += item.size; + items.push(item); + var progressHandler = progress ? Handler.create(null, loadProgress, [item], false) : null; + var completeHandler = (complete || progress) ? Handler.create(null, loadComplete, [item]) : null; + this.load(item.url, completeHandler, progressHandler, item.type, item.priority || 1, cache, item.group || group, false, item.useWorkerLoader); + } + function loadComplete(item, content = null) { + loadedCount++; + item.progress = 1; + if (!content) + success = false; + if (loadedCount === itemCount && complete) { + complete.runWith(success); + } + } + function loadProgress(item, value) { + if (progress != null) { + item.progress = value; + var num = 0; + for (var j = 0; j < items.length; j++) { + var item1 = items[j]; + if (item1) { + let prog = item1.progress == undefined ? 0 : item1.progress; + num += item1.size == undefined ? 0 : item1.size * prog; + } + } + var v = num / totalSize; + progress.runWith(v); + } + } + return this; + } + decodeBitmaps(urls) { + var i, len = urls.length; + var ctx; + ctx = ILaya.Render._context; + for (i = 0; i < len; i++) { + var atlas; + atlas = Loader.getAtlas(urls[i]); + if (atlas) { + this._decodeTexture(atlas[0], ctx); + } + else { + var tex; + tex = this.getRes(urls[i]); + if (tex && tex instanceof Texture) { + this._decodeTexture(tex, ctx); + } + } + } + } + _decodeTexture(tex, ctx) { + var bitmap = tex.bitmap; + if (!tex || !bitmap) + return; + var tImg = bitmap.source || bitmap.image; + if (!tImg) + return; + if (tImg instanceof HTMLImageElement) { + ctx.drawImage(tImg, 0, 0, 1, 1); + var info = ctx.getImageData(0, 0, 1, 1); + } + } + } + LoaderManager._resMap = {}; + LoaderManager.createMap = { atlas: [null, Loader.ATLAS] }; + class ResInfo extends EventDispatcher { + } + + class LocalStorage { + static __init__() { + if (!LocalStorage._baseClass) { + LocalStorage._baseClass = Storage; + Storage.init(); + } + LocalStorage.items = LocalStorage._baseClass.items; + LocalStorage.support = LocalStorage._baseClass.support; + return LocalStorage.support; + } + static setItem(key, value) { + LocalStorage._baseClass.setItem(key, value); + } + static getItem(key) { + return LocalStorage._baseClass.getItem(key); + } + static setJSON(key, value) { + LocalStorage._baseClass.setJSON(key, value); + } + static getJSON(key) { + return LocalStorage._baseClass.getJSON(key); + } + static removeItem(key) { + LocalStorage._baseClass.removeItem(key); + } + static clear() { + LocalStorage._baseClass.clear(); + } + } + LocalStorage.support = false; + class Storage { + static init() { + try { + Storage.support = true; + Storage.items = window.localStorage; + Storage.setItem('laya', '1'); + Storage.removeItem('laya'); + } + catch (e) { + Storage.support = false; + } + if (!Storage.support) + console.log('LocalStorage is not supprot or browser is private mode.'); + } + static setItem(key, value) { + try { + Storage.support && Storage.items.setItem(key, value); + } + catch (e) { + console.warn("set localStorage failed", e); + } + } + static getItem(key) { + return Storage.support ? Storage.items.getItem(key) : null; + } + static setJSON(key, value) { + try { + Storage.support && Storage.items.setItem(key, JSON.stringify(value)); + } + catch (e) { + console.warn("set localStorage failed", e); + } + } + static getJSON(key) { + try { + let obj = JSON.parse(Storage.support ? Storage.items.getItem(key) : null); + return obj; + } + catch (err) { + return Storage.items.getItem(key); + } + } + static removeItem(key) { + Storage.support && Storage.items.removeItem(key); + } + static clear() { + Storage.support && Storage.items.clear(); + } + } + Storage.support = false; + + class TTFLoader { + load(fontPath) { + this._url = fontPath; + var tArr = fontPath.toLowerCase().split(".ttf")[0].split("/"); + this.fontName = tArr[tArr.length - 1]; + if (ILaya.Render.isConchApp) { + this._loadConch(); + } + else if (window.FontFace) { + this._loadWithFontFace(); + } + else { + this._loadWithCSS(); + } + } + _loadConch() { + this._http = new HttpRequest(); + this._http.on(Event.ERROR, this, this._onErr); + this._http.on(Event.COMPLETE, this, this._onHttpLoaded); + this._http.send(this._url, null, "get", Loader.BUFFER); + } + _onHttpLoaded(data = null) { + window["conchTextCanvas"].setFontFaceFromBuffer(this.fontName, data); + this._clearHttp(); + this._complete(); + } + _clearHttp() { + if (this._http) { + this._http.off(Event.ERROR, this, this._onErr); + this._http.off(Event.COMPLETE, this, this._onHttpLoaded); + this._http = null; + } + } + _onErr() { + this._clearHttp(); + if (this.err) { + this.err.runWith("fail:" + this._url); + this.err = null; + } + } + _complete() { + ILaya.systemTimer.clear(this, this._complete); + ILaya.systemTimer.clear(this, this._checkComplete); + if (this._div && this._div.parentNode) { + this._div.parentNode.removeChild(this._div); + this._div = null; + } + if (this.complete) { + this.complete.runWith(this); + this.complete = null; + } + } + _checkComplete() { + if (ILaya.Browser.measureText(TTFLoader._testString, this._fontTxt).width != this._txtWidth) { + this._complete(); + } + } + _loadWithFontFace() { + var fontFace = new window.FontFace(this.fontName, "url('" + this._url + "')"); + document.fonts.add(fontFace); + var self = this; + fontFace.loaded.then((function () { + self._complete(); + })); + fontFace.load(); + } + _createDiv() { + this._div = Browser.createElement("div"); + this._div.innerHTML = "laya"; + var _style = this._div.style; + _style.fontFamily = this.fontName; + _style.position = "absolute"; + _style.left = "-100px"; + _style.top = "-100px"; + document.body.appendChild(this._div); + } + _loadWithCSS() { + var fontStyle = Browser.createElement("style"); + fontStyle.type = "text/css"; + document.body.appendChild(fontStyle); + fontStyle.textContent = "@font-face { font-family:'" + this.fontName + "'; src:url('" + this._url + "');}"; + this._fontTxt = "40px " + this.fontName; + this._txtWidth = Browser.measureText(TTFLoader._testString, this._fontTxt).width; + var self = this; + fontStyle.onload = function () { + ILaya.systemTimer.once(10000, self, self._complete); + }; + ILaya.systemTimer.loop(20, this, this._checkComplete); + this._createDiv(); + } + } + TTFLoader._testString = "LayaTTFFont"; + + class Ease { + static linearNone(t, b, c, d) { + return c * t / d + b; + } + static linearIn(t, b, c, d) { + return c * t / d + b; + } + static linearInOut(t, b, c, d) { + return c * t / d + b; + } + static linearOut(t, b, c, d) { + return c * t / d + b; + } + static bounceIn(t, b, c, d) { + return c - Ease.bounceOut(d - t, 0, c, d) + b; + } + static bounceInOut(t, b, c, d) { + if (t < d * 0.5) + return Ease.bounceIn(t * 2, 0, c, d) * .5 + b; + else + return Ease.bounceOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b; + } + static bounceOut(t, b, c, d) { + if ((t /= d) < (1 / 2.75)) + return c * (7.5625 * t * t) + b; + else if (t < (2 / 2.75)) + return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b; + else if (t < (2.5 / 2.75)) + return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b; + else + return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b; + } + static backIn(t, b, c, d, s = 1.70158) { + return c * (t /= d) * t * ((s + 1) * t - s) + b; + } + static backInOut(t, b, c, d, s = 1.70158) { + if ((t /= d * 0.5) < 1) + return c * 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b; + return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b; + } + static backOut(t, b, c, d, s = 1.70158) { + return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; + } + static elasticIn(t, b, c, d, a = 0, p = 0) { + var s; + if (t == 0) + return b; + if ((t /= d) == 1) + return b + c; + if (!p) + p = d * .3; + if (!a || (c > 0 && a < c) || (c < 0 && a < -c)) { + a = c; + s = p / 4; + } + else + s = p / Ease.PI2 * Math.asin(c / a); + return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * Ease.PI2 / p)) + b; + } + static elasticInOut(t, b, c, d, a = 0, p = 0) { + var s; + if (t == 0) + return b; + if ((t /= d * 0.5) == 2) + return b + c; + if (!p) + p = d * (.3 * 1.5); + if (!a || (c > 0 && a < c) || (c < 0 && a < -c)) { + a = c; + s = p / 4; + } + else + s = p / Ease.PI2 * Math.asin(c / a); + if (t < 1) + return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * Ease.PI2 / p)) + b; + return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * Ease.PI2 / p) * .5 + c + b; + } + static elasticOut(t, b, c, d, a = 0, p = 0) { + var s; + if (t == 0) + return b; + if ((t /= d) == 1) + return b + c; + if (!p) + p = d * .3; + if (!a || (c > 0 && a < c) || (c < 0 && a < -c)) { + a = c; + s = p / 4; + } + else + s = p / Ease.PI2 * Math.asin(c / a); + return (a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * Ease.PI2 / p) + c + b); + } + static strongIn(t, b, c, d) { + return c * (t /= d) * t * t * t * t + b; + } + static strongInOut(t, b, c, d) { + if ((t /= d * 0.5) < 1) + return c * 0.5 * t * t * t * t * t + b; + return c * 0.5 * ((t -= 2) * t * t * t * t + 2) + b; + } + static strongOut(t, b, c, d) { + return c * ((t = t / d - 1) * t * t * t * t + 1) + b; + } + static sineInOut(t, b, c, d) { + return -c * 0.5 * (Math.cos(Math.PI * t / d) - 1) + b; + } + static sineIn(t, b, c, d) { + return -c * Math.cos(t / d * Ease.HALF_PI) + c + b; + } + static sineOut(t, b, c, d) { + return c * Math.sin(t / d * Ease.HALF_PI) + b; + } + static quintIn(t, b, c, d) { + return c * (t /= d) * t * t * t * t + b; + } + static quintInOut(t, b, c, d) { + if ((t /= d * 0.5) < 1) + return c * 0.5 * t * t * t * t * t + b; + return c * 0.5 * ((t -= 2) * t * t * t * t + 2) + b; + } + static quintOut(t, b, c, d) { + return c * ((t = t / d - 1) * t * t * t * t + 1) + b; + } + static quartIn(t, b, c, d) { + return c * (t /= d) * t * t * t + b; + } + static quartInOut(t, b, c, d) { + if ((t /= d * 0.5) < 1) + return c * 0.5 * t * t * t * t + b; + return -c * 0.5 * ((t -= 2) * t * t * t - 2) + b; + } + static quartOut(t, b, c, d) { + return -c * ((t = t / d - 1) * t * t * t - 1) + b; + } + static cubicIn(t, b, c, d) { + return c * (t /= d) * t * t + b; + } + static cubicInOut(t, b, c, d) { + if ((t /= d * 0.5) < 1) + return c * 0.5 * t * t * t + b; + return c * 0.5 * ((t -= 2) * t * t + 2) + b; + } + static cubicOut(t, b, c, d) { + return c * ((t = t / d - 1) * t * t + 1) + b; + } + static quadIn(t, b, c, d) { + return c * (t /= d) * t + b; + } + static quadInOut(t, b, c, d) { + if ((t /= d * 0.5) < 1) + return c * 0.5 * t * t + b; + return -c * 0.5 * ((--t) * (t - 2) - 1) + b; + } + static quadOut(t, b, c, d) { + return -c * (t /= d) * (t - 2) + b; + } + static expoIn(t, b, c, d) { + return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b - c * 0.001; + } + static expoInOut(t, b, c, d) { + if (t == 0) + return b; + if (t == d) + return b + c; + if ((t /= d * 0.5) < 1) + return c * 0.5 * Math.pow(2, 10 * (t - 1)) + b; + return c * 0.5 * (-Math.pow(2, -10 * --t) + 2) + b; + } + static expoOut(t, b, c, d) { + return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b; + } + static circIn(t, b, c, d) { + return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b; + } + static circInOut(t, b, c, d) { + if ((t /= d * 0.5) < 1) + return -c * 0.5 * (Math.sqrt(1 - t * t) - 1) + b; + return c * 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b; + } + static circOut(t, b, c, d) { + return c * Math.sqrt(1 - (t = t / d - 1) * t) + b; + } + } + Ease.HALF_PI = Math.PI * 0.5; + Ease.PI2 = Math.PI * 2; + + class Tween { + constructor() { + this.gid = 0; + this.repeat = 1; + this._count = 0; + } + static to(target, props, duration, ease = null, complete = null, delay = 0, coverBefore = false, autoRecover = true) { + return Pool.getItemByClass("tween", Tween)._create(target, props, duration, ease, complete, delay, coverBefore, true, autoRecover, true); + } + static from(target, props, duration, ease = null, complete = null, delay = 0, coverBefore = false, autoRecover = true) { + return Pool.getItemByClass("tween", Tween)._create(target, props, duration, ease, complete, delay, coverBefore, false, autoRecover, true); + } + to(target, props, duration, ease = null, complete = null, delay = 0, coverBefore = false) { + return this._create(target, props, duration, ease, complete, delay, coverBefore, true, false, true); + } + from(target, props, duration, ease = null, complete = null, delay = 0, coverBefore = false) { + return this._create(target, props, duration, ease, complete, delay, coverBefore, false, false, true); + } + _create(target, props, duration, ease, complete, delay, coverBefore, isTo, usePool, runNow) { + if (!target) + throw new Error("Tween:target is null"); + this._target = target; + this._duration = duration; + this._ease = ease || props.ease || Tween.easeNone; + this._complete = complete || props.complete; + this._delay = delay; + this._props = []; + this._usedTimer = 0; + this._startTimer = Browser.now(); + this._usedPool = usePool; + this._delayParam = null; + this.update = props.update; + var gid = (target.$_GID || (target.$_GID = Utils.getGID())); + if (!Tween.tweenMap[gid]) { + Tween.tweenMap[gid] = [this]; + } + else { + if (coverBefore) + Tween.clearTween(target); + Tween.tweenMap[gid].push(this); + } + if (runNow) { + if (delay <= 0) + this.firstStart(target, props, isTo); + else { + this._delayParam = [target, props, isTo]; + ILaya.timer.once(delay, this, this.firstStart, this._delayParam); + } + } + else { + this._initProps(target, props, isTo); + } + return this; + } + firstStart(target, props, isTo) { + this._delayParam = null; + if (target.destroyed) { + this.clear(); + return; + } + this._initProps(target, props, isTo); + this._beginLoop(); + } + _initProps(target, props, isTo) { + for (var p in props) { + if (typeof (target[p]) == 'number') { + var start = isTo ? target[p] : props[p]; + var end = isTo ? props[p] : target[p]; + this._props.push([p, start, end - start]); + if (!isTo) + target[p] = start; + } + } + } + _beginLoop() { + ILaya.timer.frameLoop(1, this, this._doEase); + } + _doEase() { + this._updateEase(Browser.now()); + } + _updateEase(time) { + var target = this._target; + if (!target) + return; + if (target.destroyed) + return Tween.clearTween(target); + var usedTimer = this._usedTimer = time - this._startTimer - this._delay; + if (usedTimer < 0) + return; + if (usedTimer >= this._duration) + return this.complete(); + var ratio = usedTimer > 0 ? this._ease(usedTimer, 0, 1, this._duration) : 0; + var props = this._props; + for (var i = 0, n = props.length; i < n; i++) { + var prop = props[i]; + target[prop[0]] = prop[1] + (ratio * prop[2]); + } + if (this.update) + this.update.run(); + } + set progress(v) { + var uTime = v * this._duration; + this._startTimer = Browser.now() - this._delay - uTime; + } + complete() { + if (!this._target) + return; + ILaya.timer.runTimer(this, this.firstStart); + var target = this._target; + var props = this._props; + var handler = this._complete; + for (var i = 0, n = props.length; i < n; i++) { + var prop = props[i]; + target[prop[0]] = prop[1] + prop[2]; + } + if (this.update) + this.update.run(); + this._count++; + if (this.repeat != 0 && this._count >= this.repeat) { + this.clear(); + handler && handler.run(); + } + else { + this.restart(); + } + } + pause() { + ILaya.timer.clear(this, this._beginLoop); + ILaya.timer.clear(this, this._doEase); + ILaya.timer.clear(this, this.firstStart); + var time = Browser.now(); + var dTime; + dTime = time - this._startTimer - this._delay; + if (dTime < 0) { + this._usedTimer = dTime; + } + } + setStartTime(startTime) { + this._startTimer = startTime; + } + static clearAll(target) { + if (!target || !target.$_GID) + return; + var tweens = Tween.tweenMap[target.$_GID]; + if (tweens) { + for (var i = 0, n = tweens.length; i < n; i++) { + tweens[i]._clear(); + } + tweens.length = 0; + } + } + static clear(tween) { + tween.clear(); + } + static clearTween(target) { + Tween.clearAll(target); + } + clear() { + if (this._target) { + this._remove(); + this._clear(); + } + } + _clear() { + this.pause(); + ILaya.timer.clear(this, this.firstStart); + this._complete = null; + this._target = null; + this._ease = null; + this._props = null; + this._delayParam = null; + this.repeat = 1; + if (this._usedPool) { + this.update = null; + Pool.recover("tween", this); + } + } + recover() { + this._usedPool = true; + this._clear(); + } + _remove() { + var tweens = Tween.tweenMap[this._target.$_GID]; + if (tweens) { + for (var i = 0, n = tweens.length; i < n; i++) { + if (tweens[i] === this) { + tweens.splice(i, 1); + break; + } + } + } + } + restart() { + this.pause(); + this._usedTimer = 0; + this._startTimer = Browser.now(); + if (this._delayParam) { + ILaya.timer.once(this._delay, this, this.firstStart, this._delayParam); + return; + } + var props = this._props; + for (var i = 0, n = props.length; i < n; i++) { + var prop = props[i]; + this._target[prop[0]] = prop[1]; + } + ILaya.timer.once(this._delay, this, this._beginLoop); + } + resume() { + if (this._usedTimer >= this._duration) + return; + this._startTimer = Browser.now() - this._usedTimer - this._delay; + if (this._delayParam) { + if (this._usedTimer < 0) { + ILaya.timer.once(-this._usedTimer, this, this.firstStart, this._delayParam); + } + else { + this.firstStart.apply(this, this._delayParam); + } + } + else { + this._beginLoop(); + } + } + static easeNone(t, b, c, d) { + return c * t / d + b; + } + } + Tween.tweenMap = []; + + class Dragging { + constructor() { + this.ratio = 0.92; + this.maxOffset = 60; + this._dragging = false; + this._clickOnly = true; + } + start(target, area, hasInertia, elasticDistance, elasticBackTime, data, disableMouseEvent, ratio = 0.92) { + this.clearTimer(); + this.target = target; + this.area = area; + this.hasInertia = hasInertia; + this.elasticDistance = area ? elasticDistance : 0; + this.elasticBackTime = elasticBackTime; + this.data = data; + this._disableMouseEvent = disableMouseEvent; + this.ratio = ratio; + this._parent = target.parent; + this._clickOnly = true; + this._dragging = true; + this._elasticRateX = this._elasticRateY = 1; + this._lastX = this._parent.mouseX; + this._lastY = this._parent.mouseY; + ILaya.stage.on(Event.MOUSE_UP, this, this.onStageMouseUp); + ILaya.stage.on(Event.MOUSE_OUT, this, this.onStageMouseUp); + ILaya.systemTimer.frameLoop(1, this, this.loop); + } + clearTimer() { + ILaya.systemTimer.clear(this, this.loop); + ILaya.systemTimer.clear(this, this.tweenMove); + if (this._tween) { + this._tween.recover(); + this._tween = null; + } + } + stop() { + if (this._dragging) { + MouseManager.instance.disableMouseEvent = false; + ILaya.stage.off(Event.MOUSE_UP, this, this.onStageMouseUp); + ILaya.stage.off(Event.MOUSE_OUT, this, this.onStageMouseUp); + this._dragging = false; + this.target && this.area && this.backToArea(); + this.clear(); + } + } + loop() { + var point = this._parent.getMousePoint(); + var mouseX = point.x; + var mouseY = point.y; + var offsetX = mouseX - this._lastX; + var offsetY = mouseY - this._lastY; + if (this._clickOnly) { + if (Math.abs(offsetX * ILaya.stage._canvasTransform.getScaleX()) > 1 || Math.abs(offsetY * ILaya.stage._canvasTransform.getScaleY()) > 1) { + this._clickOnly = false; + this._offsets || (this._offsets = []); + this._offsets.length = 0; + this.target.event(Event.DRAG_START, this.data); + MouseManager.instance.disableMouseEvent = this._disableMouseEvent; + } + else + return; + } + else { + this._offsets.push(offsetX, offsetY); + } + if (offsetX === 0 && offsetY === 0) + return; + this._lastX = mouseX; + this._lastY = mouseY; + this.target.x += offsetX * this._elasticRateX; + this.target.y += offsetY * this._elasticRateY; + this.area && this.checkArea(); + this.target.event(Event.DRAG_MOVE, this.data); + } + checkArea() { + if (this.elasticDistance <= 0) { + this.backToArea(); + } + else { + if (this.target._x < this.area.x) { + var offsetX = this.area.x - this.target._x; + } + else if (this.target._x > this.area.x + this.area.width) { + offsetX = this.target._x - this.area.x - this.area.width; + } + else { + offsetX = 0; + } + this._elasticRateX = Math.max(0, 1 - (offsetX / this.elasticDistance)); + if (this.target._y < this.area.y) { + var offsetY = this.area.y - this.target.y; + } + else if (this.target._y > this.area.y + this.area.height) { + offsetY = this.target._y - this.area.y - this.area.height; + } + else { + offsetY = 0; + } + this._elasticRateY = Math.max(0, 1 - (offsetY / this.elasticDistance)); + } + } + backToArea() { + this.target.x = Math.min(Math.max(this.target._x, this.area.x), this.area.x + this.area.width); + this.target.y = Math.min(Math.max(this.target._y, this.area.y), this.area.y + this.area.height); + } + onStageMouseUp(e) { + MouseManager.instance.disableMouseEvent = false; + ILaya.stage.off(Event.MOUSE_UP, this, this.onStageMouseUp); + ILaya.stage.off(Event.MOUSE_OUT, this, this.onStageMouseUp); + ILaya.systemTimer.clear(this, this.loop); + if (this._clickOnly || !this.target) + return; + if (this.hasInertia) { + if (this._offsets.length < 1) { + this._offsets.push(this._parent.mouseX - this._lastX, this._parent.mouseY - this._lastY); + } + this._offsetX = this._offsetY = 0; + var len = this._offsets.length; + var n = Math.min(len, 6); + var m = this._offsets.length - n; + for (var i = len - 1; i > m; i--) { + this._offsetY += this._offsets[i--]; + this._offsetX += this._offsets[i]; + } + this._offsetX = this._offsetX / n * 2; + this._offsetY = this._offsetY / n * 2; + if (Math.abs(this._offsetX) > this.maxOffset) + this._offsetX = this._offsetX > 0 ? this.maxOffset : -this.maxOffset; + if (Math.abs(this._offsetY) > this.maxOffset) + this._offsetY = this._offsetY > 0 ? this.maxOffset : -this.maxOffset; + ILaya.systemTimer.frameLoop(1, this, this.tweenMove); + } + else if (this.elasticDistance > 0) { + this.checkElastic(); + } + else { + this.clear(); + } + } + checkElastic() { + var tx = NaN; + var ty = NaN; + if (this.target.x < this.area.x) + tx = this.area.x; + else if (this.target._x > this.area.x + this.area.width) + tx = this.area.x + this.area.width; + if (this.target.y < this.area.y) + ty = this.area.y; + else if (this.target._y > this.area.y + this.area.height) + ty = this.area.y + this.area.height; + if (!isNaN(tx) || !isNaN(ty)) { + var obj = {}; + if (!isNaN(tx)) + obj.x = tx; + if (!isNaN(ty)) + obj.y = ty; + this._tween = Tween.to(this.target, obj, this.elasticBackTime, Ease.sineOut, Handler.create(this, this.clear), 0, false, false); + } + else { + this.clear(); + } + } + tweenMove() { + this._offsetX *= this.ratio * this._elasticRateX; + this._offsetY *= this.ratio * this._elasticRateY; + this.target.x += this._offsetX; + this.target.y += this._offsetY; + this.area && this.checkArea(); + this.target.event(Event.DRAG_MOVE, this.data); + if ((Math.abs(this._offsetX) < 1 && Math.abs(this._offsetY) < 1) || this._elasticRateX < 0.5 || this._elasticRateY < 0.5) { + ILaya.systemTimer.clear(this, this.tweenMove); + if (this.elasticDistance > 0) + this.checkElastic(); + else + this.clear(); + } + } + clear() { + if (this.target) { + this.clearTimer(); + var sp = this.target; + this.target = null; + this._parent = null; + sp.event(Event.DRAG_END, this.data); + } + } + } + + class Component { + constructor() { + this._id = Utils.getGID(); + this._resetComp(); + } + get id() { + return this._id; + } + get enabled() { + return this._enabled; + } + set enabled(value) { + if (this._enabled != value) { + this._enabled = value; + if (this.owner) { + if (value) + this.owner.activeInHierarchy && this._onEnable(); + else + this.owner.activeInHierarchy && this._onDisable(); + } + } + } + get isSingleton() { + return true; + } + get destroyed() { + return this._destroyed; + } + _isScript() { + return false; + } + _resetComp() { + this._indexInList = -1; + this._enabled = true; + this._awaked = false; + this.owner = null; + } + _getIndexInList() { + return this._indexInList; + } + _setIndexInList(index) { + this._indexInList = index; + } + _onAdded() { + } + _onAwake() { + } + _onEnable() { + } + _onDisable() { + } + _onDestroy() { + } + onReset() { + } + _parse(data, interactMap = null) { + } + _parseInteractive(data = null, spriteMap = null) { + } + _cloneTo(dest) { + } + _setActive(value) { + if (value) { + if (!this._awaked) { + this._awaked = true; + this._onAwake(); + } + this._enabled && this._onEnable(); + } + else { + this._enabled && this._onDisable(); + } + } + destroy() { + if (this.owner) + this.owner._destroyComponent(this); + } + _destroy() { + if (this.owner.activeInHierarchy && this._enabled) + this._setActive(false); + this._onDestroy(); + this._destroyed = true; + if (this.onReset !== Component.prototype.onReset) { + this.onReset(); + this._resetComp(); + Pool.recoverByClass(this); + } + else { + this._resetComp(); + } + } + } + + class AnimationBase extends Sprite { + constructor() { + super(); + this.wrapMode = 0; + this._interval = Config.animationInterval; + this._isReverse = false; + this._frameRateChanged = false; + this._setBitUp(Const.DISPLAY); + } + play(start = 0, loop = true, name = "") { + this._isPlaying = true; + this._actionName = name; + this.index = (typeof (start) == 'string') ? this._getFrameByLabel(start) : start; + this.loop = loop; + this._isReverse = this.wrapMode === AnimationBase.WRAP_REVERSE; + if (this.index == 0 && this._isReverse) { + this.index = this.count - 1; + } + if (this.interval > 0) + this.timerLoop(this.interval, this, this._frameLoop, null, true, true); + } + get interval() { + return this._interval; + } + set interval(value) { + if (this._interval != value) { + this._frameRateChanged = true; + this._interval = value; + if (this._isPlaying && value > 0) { + this.timerLoop(value, this, this._frameLoop, null, true, true); + } + } + } + _getFrameByLabel(label) { + for (var i = 0; i < this._count; i++) { + var item = this._labels[i]; + if (item && item.indexOf(label) > -1) + return i; + } + return 0; + } + _frameLoop() { + if (!this._controlNode || this._controlNode.destroyed) { + this.clearTimer(this, this._frameLoop); + return; + } + if (this._isReverse) { + this._index--; + if (this._index < 0) { + if (this.loop) { + if (this.wrapMode == AnimationBase.WRAP_PINGPONG) { + this._index = this._count > 0 ? 1 : 0; + this._isReverse = false; + } + else { + this._index = this._count - 1; + } + this.event(Event.COMPLETE); + } + else { + this._index = 0; + this.stop(); + this.event(Event.COMPLETE); + return; + } + } + } + else { + this._index++; + if (this._index >= this._count) { + if (this.loop) { + if (this.wrapMode == AnimationBase.WRAP_PINGPONG) { + this._index = this._count - 2 >= 0 ? this._count - 2 : 0; + this._isReverse = true; + } + else { + this._index = 0; + } + this.event(Event.COMPLETE); + } + else { + this._index--; + this.stop(); + this.event(Event.COMPLETE); + return; + } + } + } + this.index = this._index; + } + _setControlNode(node) { + if (this._controlNode) { + this._controlNode.off(Event.DISPLAY, this, this._resumePlay); + this._controlNode.off(Event.UNDISPLAY, this, this._resumePlay); + } + this._controlNode = node; + if (node && node != this) { + node.on(Event.DISPLAY, this, this._resumePlay); + node.on(Event.UNDISPLAY, this, this._resumePlay); + } + } + _setDisplay(value) { + super._setDisplay(value); + this._resumePlay(); + } + _resumePlay() { + if (this._isPlaying) { + if (this._controlNode.displayedInStage) + this.play(this._index, this.loop, this._actionName); + else + this.clearTimer(this, this._frameLoop); + } + } + stop() { + this._isPlaying = false; + this.clearTimer(this, this._frameLoop); + } + get isPlaying() { + return this._isPlaying; + } + addLabel(label, index) { + if (!this._labels) + this._labels = {}; + if (!this._labels[index]) + this._labels[index] = []; + this._labels[index].push(label); + } + removeLabel(label) { + if (!label) + this._labels = null; + else if (this._labels) { + for (var name in this._labels) { + this._removeLabelFromList(this._labels[name], label); + } + } + } + _removeLabelFromList(list, label) { + if (!list) + return; + for (var i = list.length - 1; i >= 0; i--) { + if (list[i] == label) { + list.splice(i, 1); + } + } + } + gotoAndStop(position) { + this.index = (typeof (position) == 'string') ? this._getFrameByLabel(position) : position; + this.stop(); + } + get index() { + return this._index; + } + set index(value) { + this._index = value; + this._displayToIndex(value); + if (this._labels && this._labels[value]) { + var tArr = this._labels[value]; + for (var i = 0, len = tArr.length; i < len; i++) { + this.event(Event.LABEL, tArr[i]); + } + } + } + _displayToIndex(value) { + } + get count() { + return this._count; + } + clear() { + this.stop(); + this._labels = null; + return this; + } + } + AnimationBase.WRAP_POSITIVE = 0; + AnimationBase.WRAP_REVERSE = 1; + AnimationBase.WRAP_PINGPONG = 2; + ClassUtils.regClass("laya.display.AnimationBase", AnimationBase); + ClassUtils.regClass("Laya.AnimationBase", AnimationBase); + + class MathUtil { + static subtractVector3(l, r, o) { + o[0] = l[0] - r[0]; + o[1] = l[1] - r[1]; + o[2] = l[2] - r[2]; + } + static lerp(left, right, amount) { + return left * (1 - amount) + right * amount; + } + static scaleVector3(f, b, e) { + e[0] = f[0] * b; + e[1] = f[1] * b; + e[2] = f[2] * b; + } + static lerpVector3(l, r, t, o) { + var ax = l[0], ay = l[1], az = l[2]; + o[0] = ax + t * (r[0] - ax); + o[1] = ay + t * (r[1] - ay); + o[2] = az + t * (r[2] - az); + } + static lerpVector4(l, r, t, o) { + var ax = l[0], ay = l[1], az = l[2], aw = l[3]; + o[0] = ax + t * (r[0] - ax); + o[1] = ay + t * (r[1] - ay); + o[2] = az + t * (r[2] - az); + o[3] = aw + t * (r[3] - aw); + } + static slerpQuaternionArray(a, Offset1, b, Offset2, t, out, Offset3) { + var ax = a[Offset1 + 0], ay = a[Offset1 + 1], az = a[Offset1 + 2], aw = a[Offset1 + 3], bx = b[Offset2 + 0], by = b[Offset2 + 1], bz = b[Offset2 + 2], bw = b[Offset2 + 3]; + var omega, cosom, sinom, scale0, scale1; + cosom = ax * bx + ay * by + az * bz + aw * bw; + if (cosom < 0.0) { + cosom = -cosom; + bx = -bx; + by = -by; + bz = -bz; + bw = -bw; + } + if ((1.0 - cosom) > 0.000001) { + omega = Math.acos(cosom); + sinom = Math.sin(omega); + scale0 = Math.sin((1.0 - t) * omega) / sinom; + scale1 = Math.sin(t * omega) / sinom; + } + else { + scale0 = 1.0 - t; + scale1 = t; + } + out[Offset3 + 0] = scale0 * ax + scale1 * bx; + out[Offset3 + 1] = scale0 * ay + scale1 * by; + out[Offset3 + 2] = scale0 * az + scale1 * bz; + out[Offset3 + 3] = scale0 * aw + scale1 * bw; + return out; + } + static getRotation(x0, y0, x1, y1) { + return Math.atan2(y1 - y0, x1 - x0) / Math.PI * 180; + } + static sortBigFirst(a, b) { + if (a == b) + return 0; + return b > a ? 1 : -1; + } + static sortSmallFirst(a, b) { + if (a == b) + return 0; + return b > a ? -1 : 1; + } + static sortNumBigFirst(a, b) { + return parseFloat(b) - parseFloat(a); + } + static sortNumSmallFirst(a, b) { + return parseFloat(a) - parseFloat(b); + } + static sortByKey(key, bigFirst = false, forceNum = true) { + var _sortFun; + if (bigFirst) { + _sortFun = forceNum ? MathUtil.sortNumBigFirst : MathUtil.sortBigFirst; + } + else { + _sortFun = forceNum ? MathUtil.sortNumSmallFirst : MathUtil.sortSmallFirst; + } + return function (a, b) { + return _sortFun(a[key], b[key]); + }; + } + } + + class FrameAnimation extends AnimationBase { + constructor() { + super(); + if (FrameAnimation._sortIndexFun === undefined) { + FrameAnimation._sortIndexFun = MathUtil.sortByKey("index", false, true); + } + } + static _sortIndexFun(objpre, objnext) { + return objpre.index - objnext.index; + } + _setUp(targetDic, animationData) { + this._targetDic = targetDic; + this._animationData = animationData; + this.interval = 1000 / animationData.frameRate; + if (animationData.parsed) { + this._count = animationData.count; + this._labels = animationData.labels; + this._usedFrames = animationData.animationNewFrames; + } + else { + this._usedFrames = []; + this._calculateDatas(); + animationData.parsed = true; + animationData.labels = this._labels; + animationData.count = this._count; + animationData.animationNewFrames = this._usedFrames; + } + } + clear() { + super.clear(); + this._targetDic = null; + this._animationData = null; + return this; + } + _displayToIndex(value) { + if (!this._animationData) + return; + if (value < 0) + value = 0; + if (value > this._count) + value = this._count; + var nodes = this._animationData.nodes, i, len = nodes.length; + for (i = 0; i < len; i++) { + this._displayNodeToFrame(nodes[i], value); + } + } + _displayNodeToFrame(node, frame, targetDic = null) { + if (!targetDic) + targetDic = this._targetDic; + var target = targetDic[node.target]; + if (!target) { + return; + } + var frames = node.frames, key, propFrames, value; + var keys = node.keys, i, len = keys.length; + for (i = 0; i < len; i++) { + key = keys[i]; + propFrames = frames[key]; + if (propFrames.length > frame) { + value = propFrames[frame]; + } + else { + value = propFrames[propFrames.length - 1]; + } + target[key] = value; + } + var funkeys = node.funkeys; + len = funkeys.length; + var funFrames; + if (len == 0) + return; + for (i = 0; i < len; i++) { + key = funkeys[i]; + funFrames = frames[key]; + if (funFrames[frame] !== undefined) { + target[key] && target[key].apply(target, funFrames[frame]); + } + } + } + _calculateDatas() { + if (!this._animationData) + return; + var nodes = this._animationData.nodes, i, len = nodes.length, tNode; + this._count = 0; + for (i = 0; i < len; i++) { + tNode = nodes[i]; + this._calculateKeyFrames(tNode); + } + this._count += 1; + } + _calculateKeyFrames(node) { + var keyFrames = node.keyframes, key, tKeyFrames, target = node.target; + if (!node.frames) + node.frames = {}; + if (!node.keys) + node.keys = []; + else + node.keys.length = 0; + if (!node.funkeys) + node.funkeys = []; + else + node.funkeys.length = 0; + if (!node.initValues) + node.initValues = {}; + for (key in keyFrames) { + var isFun = key.indexOf("()") != -1; + tKeyFrames = keyFrames[key]; + if (isFun) + key = key.substr(0, key.length - 2); + if (!node.frames[key]) { + node.frames[key] = []; + } + if (!isFun) { + if (this._targetDic && this._targetDic[target]) { + node.initValues[key] = this._targetDic[target][key]; + } + tKeyFrames.sort(FrameAnimation._sortIndexFun); + node.keys.push(key); + this._calculateNodePropFrames(tKeyFrames, node.frames[key], key, target); + } + else { + node.funkeys.push(key); + var map = node.frames[key]; + for (var i = 0; i < tKeyFrames.length; i++) { + var temp = tKeyFrames[i]; + map[temp.index] = temp.value; + if (temp.index > this._count) + this._count = temp.index; + } + } + } + } + resetNodes() { + if (!this._targetDic) + return; + if (!this._animationData) + return; + var nodes = this._animationData.nodes, i, len = nodes.length; + var tNode; + var initValues; + for (i = 0; i < len; i++) { + tNode = nodes[i]; + initValues = tNode.initValues; + if (!initValues) + continue; + var target = this._targetDic[tNode.target]; + if (!target) + continue; + var key; + for (key in initValues) { + target[key] = initValues[key]; + } + } + } + _calculateNodePropFrames(keyframes, frames, key, target) { + var i, len = keyframes.length - 1; + frames.length = keyframes[len].index + 1; + for (i = 0; i < len; i++) { + this._dealKeyFrame(keyframes[i]); + this._calculateFrameValues(keyframes[i], keyframes[i + 1], frames); + } + if (len == 0) { + frames[0] = keyframes[0].value; + if (this._usedFrames) + this._usedFrames[keyframes[0].index] = true; + } + this._dealKeyFrame(keyframes[i]); + } + _dealKeyFrame(keyFrame) { + if (keyFrame.label && keyFrame.label != "") + this.addLabel(keyFrame.label, keyFrame.index); + } + _calculateFrameValues(startFrame, endFrame, result) { + var i, easeFun; + var start = startFrame.index, end = endFrame.index; + var startValue = startFrame.value; + var dValue = endFrame.value - startFrame.value; + var dLen = end - start; + var frames = this._usedFrames; + if (end > this._count) + this._count = end; + if (startFrame.tween) { + easeFun = Ease[startFrame.tweenMethod]; + if (easeFun == null) + easeFun = Ease.linearNone; + for (i = start; i < end; i++) { + result[i] = easeFun(i - start, startValue, dValue, dLen); + if (frames) + frames[i] = true; + } + } + else { + for (i = start; i < end; i++) { + result[i] = startValue; + } + } + if (frames) { + frames[startFrame.index] = true; + frames[endFrame.index] = true; + } + result[endFrame.index] = endFrame.value; + } + } + ClassUtils.regClass("laya.display.FrameAnimation", FrameAnimation); + ClassUtils.regClass("Laya.FrameAnimation", FrameAnimation); + + class WeakObject { + constructor() { + this._obj = {}; + WeakObject._maps.push(this); + } + static __init__() { + WeakObject.I = new WeakObject(); + if (!WeakObject.supportWeakMap) + ILaya.systemTimer.loop(WeakObject.delInterval, null, WeakObject.clearCache); + } + static clearCache() { + for (var i = 0, n = WeakObject._maps.length; i < n; i++) { + var obj = WeakObject._maps[i]; + obj._obj = {}; + } + } + set(key, value) { + if (key == null) + return; + if (WeakObject.supportWeakMap) ; + else { + if (typeof (key) == 'string' || typeof (key) == 'number') { + this._obj[key] = value; + } + else { + key.$_GID || (key.$_GID = Utils.getGID()); + this._obj[key.$_GID] = value; + } + } + } + get(key) { + if (key == null) + return null; + if (WeakObject.supportWeakMap) ; + else { + if (typeof (key) == 'string' || typeof (key) == 'number') + return this._obj[key]; + return this._obj[key.$_GID]; + } + } + del(key) { + if (key == null) + return; + if (WeakObject.supportWeakMap) ; + else { + if (typeof (key) == 'string' || typeof (key) == 'number') + delete this._obj[key]; + else + delete this._obj[this._obj.$_GID]; + } + } + has(key) { + if (key == null) + return false; + if (WeakObject.supportWeakMap) { + return false; + } + else { + if (typeof (key) == 'string' || typeof (key) == 'number') + return this._obj[key] != null; + return this._obj[this._obj.$_GID] != null; + } + } + } + WeakObject.supportWeakMap = false; + WeakObject.delInterval = 10 * 60 * 1000; + WeakObject._maps = []; + + class SceneUtils { + static __init() { + SceneUtils._funMap = new WeakObject(); + } + static getBindFun(value) { + var fun = SceneUtils._funMap.get(value); + if (fun == null) { + var temp = "\"" + value + "\""; + temp = temp.replace(/^"\${|}"$/g, "").replace(/\${/g, "\"+").replace(/}/g, "+\""); + var str = "(function(data){if(data==null)return;with(data){try{\nreturn " + temp + "\n}catch(e){}}})"; + fun = window.Laya._runScript(str); + SceneUtils._funMap.set(value, fun); + } + return fun; + } + static createByData(root, uiView) { + var tInitTool = InitTool.create(); + root = SceneUtils.createComp(uiView, root, root, null, tInitTool); + root._setBit(Const.NOT_READY, true); + if ("_idMap" in root) { + root["_idMap"] = tInitTool._idMap; + } + if (uiView.animations) { + var anilist = []; + var animations = uiView.animations; + var i, len = animations.length; + var tAni; + var tAniO; + for (i = 0; i < len; i++) { + tAni = new FrameAnimation(); + tAniO = animations[i]; + tAni._setUp(tInitTool._idMap, tAniO); + root[tAniO.name] = tAni; + tAni._setControlNode(root); + switch (tAniO.action) { + case 1: + tAni.play(0, false); + break; + case 2: + tAni.play(0, true); + break; + } + anilist.push(tAni); + } + root._aniList = anilist; + } + if (root._$componentType === "Scene" && root._width > 0 && uiView.props.hitTestPrior == null && !root.mouseThrough) + root.hitTestPrior = true; + tInitTool.beginLoad(root); + return root; + } + static createInitTool() { + return InitTool.create(); + } + static createComp(uiView, comp = null, view = null, dataMap = null, initTool = null) { + if (uiView.type == "Scene3D" || uiView.type == "Sprite3D") { + var outBatchSprits = []; + var scene3D = ILaya.Laya["Utils3D"]._createSceneByJsonForMaker(uiView, outBatchSprits, initTool); + if (uiView.type == "Sprite3D") + ILaya.Laya["StaticBatchManager"].combine(scene3D, outBatchSprits); + else + ILaya.Laya["StaticBatchManager"].combine(null, outBatchSprits); + return scene3D; + } + comp = comp || SceneUtils.getCompInstance(uiView); + if (!comp) { + if (uiView.props && uiView.props.runtime) + console.warn("runtime not found:" + uiView.props.runtime); + else + console.warn("can not create:" + uiView.type); + return null; + } + var child = uiView.child; + if (child) { + var isList = comp["_$componentType"] == "List"; + for (var i = 0, n = child.length; i < n; i++) { + var node = child[i]; + if ('itemRender' in comp && (node.props.name == "render" || node.props.renderType === "render")) { + comp["itemRender"] = node; + } + else if (node.type == "Graphic") { + ILaya.ClassUtils._addGraphicsToSprite(node, comp); + } + else if (ILaya.ClassUtils._isDrawType(node.type)) { + ILaya.ClassUtils._addGraphicToSprite(node, comp, true); + } + else { + if (isList) { + var arr = []; + var tChild = SceneUtils.createComp(node, null, view, arr, initTool); + if (arr.length) + tChild["_$bindData"] = arr; + } + else { + tChild = SceneUtils.createComp(node, null, view, dataMap, initTool); + } + if (node.type == "Script") { + if (tChild instanceof Component) { + comp._addComponentInstance(tChild); + } + else { + if ("owner" in tChild) { + tChild["owner"] = comp; + } + else if ("target" in tChild) { + tChild["target"] = comp; + } + } + } + else if (node.props.renderType == "mask" || node.props.name == "mask") { + comp.mask = tChild; + } + else { + tChild instanceof Node && comp.addChild(tChild); + } + } + } + } + var props = uiView.props; + for (var prop in props) { + var value = props[prop]; + if (typeof (value) == 'string' && (value.indexOf("@node:") >= 0 || value.indexOf("@Prefab:") >= 0)) { + if (initTool) { + initTool.addNodeRef(comp, prop, value); + } + } + else + SceneUtils.setCompValue(comp, prop, value, view, dataMap); + } + if (comp._afterInited) { + comp._afterInited(); + } + if (uiView.compId && initTool && initTool._idMap) { + initTool._idMap[uiView.compId] = comp; + } + return comp; + } + static setCompValue(comp, prop, value, view = null, dataMap = null) { + if (typeof (value) == 'string' && value.indexOf("${") > -1) { + SceneUtils._sheet || (SceneUtils._sheet = ILaya.ClassUtils.getClass("laya.data.Table")); + if (!SceneUtils._sheet) { + console.warn("Can not find class Sheet"); + return; + } + if (dataMap) { + dataMap.push(comp, prop, value); + } + else if (view) { + if (value.indexOf("].") == -1) { + value = value.replace(".", "[0]."); + } + var watcher = new DataWatcher(comp, prop, value); + watcher.exe(view); + var one, temp; + var str = value.replace(/\[.*?\]\./g, "."); + while ((one = SceneUtils._parseWatchData.exec(str)) != null) { + var key1 = one[1]; + while ((temp = SceneUtils._parseKeyWord.exec(key1)) != null) { + var key2 = temp[0]; + var arr = (view._watchMap[key2] || (view._watchMap[key2] = [])); + arr.push(watcher); + SceneUtils._sheet.I.notifer.on(key2, view, view.changeData, [key2]); + } + arr = (view._watchMap[key1] || (view._watchMap[key1] = [])); + arr.push(watcher); + SceneUtils._sheet.I.notifer.on(key1, view, view.changeData, [key1]); + } + } + return; + } + if (prop === "var" && view) { + view[value] = comp; + } + else { + comp[prop] = (value === "true" ? true : (value === "false" ? false : value)); + } + } + static getCompInstance(json) { + if (json.type == "UIView") { + if (json.props && json.props.pageData) { + return SceneUtils.createByData(null, json.props.pageData); + } + } + var runtime = (json.props && json.props.runtime) || json.type; + var compClass = ILaya.ClassUtils.getClass(runtime); + if (!compClass) + throw "Can not find class " + runtime; + if (json.type === "Script" && compClass.prototype._doAwake) { + var comp = Pool.createByClass(compClass); + comp._destroyed = false; + return comp; + } + if (json.props && "renderType" in json.props && json.props["renderType"] == "instance") { + if (!compClass["instance"]) + compClass["instance"] = new compClass(); + return compClass["instance"]; + } + return new compClass(); + } + } + SceneUtils._parseWatchData = /\${(.*?)}/g; + SceneUtils._parseKeyWord = /[a-zA-Z_][a-zA-Z0-9_]*(?:(?:\.[a-zA-Z_][a-zA-Z0-9_]*)+)/g; + class DataWatcher { + constructor(comp, prop, value) { + this.comp = comp; + this.prop = prop; + this.value = value; + } + exe(view) { + var fun = SceneUtils.getBindFun(this.value); + this.comp[this.prop] = fun.call(this, view); + } + } + class InitTool { + reset() { + this._nodeRefList = null; + this._initList = null; + this._idMap = null; + this._loadList = null; + this._scene = null; + } + recover() { + this.reset(); + Pool.recover("InitTool", this); + } + static create() { + var tool = Pool.getItemByClass("InitTool", InitTool); + tool._idMap = {}; + return tool; + } + addLoadRes(url, type = null) { + if (!this._loadList) + this._loadList = []; + if (ILaya.loader.getRes(url)) { + return; + } + if (!type) { + this._loadList.push(url); + } + else { + this._loadList.push({ url: url, type: type }); + } + } + addNodeRef(node, prop, referStr) { + if (!this._nodeRefList) + this._nodeRefList = []; + this._nodeRefList.push([node, prop, referStr]); + if (referStr.indexOf("@Prefab:") >= 0) { + this.addLoadRes(referStr.replace("@Prefab:", ""), Loader.PREFAB); + } + } + setNodeRef() { + if (!this._nodeRefList) + return; + if (!this._idMap) { + this._nodeRefList = null; + return; + } + var i, len; + len = this._nodeRefList.length; + var tRefInfo; + for (i = 0; i < len; i++) { + tRefInfo = this._nodeRefList[i]; + tRefInfo[0][tRefInfo[1]] = this.getReferData(tRefInfo[2]); + } + this._nodeRefList = null; + } + getReferData(referStr) { + if (referStr.indexOf("@Prefab:") >= 0) { + var prefab; + prefab = Loader.getRes(referStr.replace("@Prefab:", "")); + return prefab; + } + else if (referStr.indexOf("@arr:") >= 0) { + referStr = referStr.replace("@arr:", ""); + var list; + list = referStr.split(","); + var i, len; + var tStr; + len = list.length; + for (i = 0; i < len; i++) { + tStr = list[i]; + if (tStr) { + list[i] = this._idMap[tStr.replace("@node:", "")]; + } + else { + list[i] = null; + } + } + return list; + } + else { + return this._idMap[referStr.replace("@node:", "")]; + } + } + addInitItem(item) { + if (!this._initList) + this._initList = []; + this._initList.push(item); + } + doInits() { + if (!this._initList) + return; + this._initList = null; + } + finish() { + this.setNodeRef(); + this.doInits(); + this._scene._setBit(Const.NOT_READY, false); + if (this._scene.parent && this._scene.parent.activeInHierarchy && this._scene.active) + this._scene._processActive(); + this._scene.event("onViewCreated"); + this.recover(); + } + beginLoad(scene) { + this._scene = scene; + if (!this._loadList || this._loadList.length < 1) { + this.finish(); + } + else { + ILaya.loader.load(this._loadList, Handler.create(this, this.finish)); + } + } + } + + class IStatRender { + show(x = 0, y = 0) { + } + enable() { + } + hide() { + } + set_onclick(fn) { + } + isCanvasRender() { + return true; + } + renderNotCanvas(ctx, x, y) { } + } + + class StatUI extends IStatRender { + constructor() { + super(...arguments); + this._show = false; + this._useCanvas = false; + this._height = 100; + this._view = []; + } + show(x = 0, y = 0) { + if (!Browser._isMiniGame && !ILaya.Render.isConchApp) + this._useCanvas = true; + this._show = true; + Stat._fpsData.length = 60; + this._view[0] = { title: "FPS(WebGL)", value: "_fpsStr", color: "yellow", units: "int" }; + this._view[1] = { title: "Sprite", value: "_spriteStr", color: "white", units: "int" }; + this._view[2] = { title: "RenderBatches", value: "renderBatches", color: "white", units: "int" }; + this._view[3] = { title: "SavedRenderBatches", value: "savedRenderBatches", color: "white", units: "int" }; + this._view[4] = { title: "CPUMemory", value: "cpuMemory", color: "yellow", units: "M" }; + this._view[5] = { title: "GPUMemory", value: "gpuMemory", color: "yellow", units: "M" }; + this._view[6] = { title: "Shader", value: "shaderCall", color: "white", units: "int" }; + this._view[7] = { title: "Canvas", value: "_canvasStr", color: "white", units: "int" }; + if (Render.is3DMode) { + this._view[0].title = "FPS(3D)"; + this._view[8] = { title: "TriFaces", value: "trianglesFaces", color: "white", units: "int" }; + this._view[9] = { title: "FrustumCulling", value: "frustumCulling", color: "white", units: "int" }; + this._view[10] = { title: "OctreeNodeCulling", value: "octreeNodeCulling", color: "white", units: "int" }; + } + if (this._useCanvas) { + this.createUIPre(x, y); + } + else + this.createUI(x, y); + this.enable(); + } + createUIPre(x, y) { + var pixel = Browser.pixelRatio; + this._width = pixel * 180; + this._vx = pixel * 120; + this._height = pixel * (this._view.length * 12 + 3 * pixel) + 4; + StatUI._fontSize = 12 * pixel; + for (var i = 0; i < this._view.length; i++) { + this._view[i].x = 4; + this._view[i].y = i * StatUI._fontSize + 2 * pixel; + } + if (!this._canvas) { + this._canvas = new HTMLCanvas(true); + this._canvas.size(this._width, this._height); + this._ctx = this._canvas.getContext('2d'); + this._ctx.textBaseline = "top"; + this._ctx.font = StatUI._fontSize + "px Arial"; + this._canvas.source.style.cssText = "pointer-events:none;background:rgba(150,150,150,0.8);z-index:100000;position: absolute;direction:ltr;left:" + x + "px;top:" + y + "px;width:" + (this._width / pixel) + "px;height:" + (this._height / pixel) + "px;"; + } + if (!Browser.onKGMiniGame) { + Browser.container.appendChild(this._canvas.source); + } + this._first = true; + this.loop(); + this._first = false; + } + createUI(x, y) { + var stat = this._sp; + var pixel = Browser.pixelRatio; + if (!stat) { + stat = new Sprite(); + this._leftText = new Text(); + this._leftText.pos(5, 5); + this._leftText.color = "#ffffff"; + stat.addChild(this._leftText); + this._txt = new Text(); + this._txt.pos(130 * pixel, 5); + this._txt.color = "#ffffff"; + stat.addChild(this._txt); + this._sp = stat; + } + stat.pos(x, y); + var text = ""; + for (var i = 0; i < this._view.length; i++) { + var one = this._view[i]; + text += one.title + "\n"; + } + this._leftText.text = text; + var width = pixel * 138; + var height = pixel * (this._view.length * 12 + 3 * pixel) + 4; + this._txt.fontSize = StatUI._fontSize * pixel; + this._leftText.fontSize = StatUI._fontSize * pixel; + stat.size(width, height); + stat.graphics.clear(); + stat.graphics.alpha(0.5); + stat.graphics.drawRect(0, 0, width + 110, height + 30, "#999999"); + stat.graphics.alpha(2); + this.loop(); + } + enable() { + ILaya.systemTimer.frameLoop(1, this, this.loop); + } + hide() { + this._show = false; + ILaya.systemTimer.clear(this, this.loop); + if (this._canvas) { + Browser.removeElement(this._canvas.source); + } + } + set_onclick(fn) { + if (this._sp) { + this._sp.on("click", this._sp, fn); + } + if (this._canvas) { + this._canvas.source.onclick = fn; + this._canvas.source.style.pointerEvents = ''; + } + } + loop() { + Stat._count++; + var timer = Browser.now(); + if (timer - Stat._timer < 1000) + return; + var count = Stat._count; + Stat.FPS = Math.round((count * 1000) / (timer - Stat._timer)); + if (this._show) { + Stat.trianglesFaces = Math.round(Stat.trianglesFaces / count); + if (!this._useCanvas) { + Stat.renderBatches = Math.round(Stat.renderBatches / count) - 1; + } + else { + Stat.renderBatches = Math.round(Stat.renderBatches / count); + } + Stat.savedRenderBatches = Math.round(Stat.savedRenderBatches / count); + Stat.shaderCall = Math.round(Stat.shaderCall / count); + Stat.spriteRenderUseCacheCount = Math.round(Stat.spriteRenderUseCacheCount / count); + Stat.canvasNormal = Math.round(Stat.canvasNormal / count); + Stat.canvasBitmap = Math.round(Stat.canvasBitmap / count); + Stat.canvasReCache = Math.ceil(Stat.canvasReCache / count); + Stat.frustumCulling = Math.round(Stat.frustumCulling / count); + Stat.octreeNodeCulling = Math.round(Stat.octreeNodeCulling / count); + var delay = Stat.FPS > 0 ? Math.floor(1000 / Stat.FPS).toString() : " "; + Stat._fpsStr = Stat.FPS + (Stat.renderSlow ? " slow" : "") + " " + delay; + Stat._spriteStr = Stat.spriteCount + (Stat.spriteRenderUseCacheCount ? ("/" + Stat.spriteRenderUseCacheCount) : ''); + Stat._canvasStr = Stat.canvasReCache + "/" + Stat.canvasNormal + "/" + Stat.canvasBitmap; + Stat.cpuMemory = Resource.cpuMemory; + Stat.gpuMemory = Resource.gpuMemory; + if (this._useCanvas) { + this.renderInfoPre(); + } + else + this.renderInfo(); + Stat.clear(); + } + Stat._count = 0; + Stat._timer = timer; + } + renderInfoPre() { + var i = 0; + var one; + var value; + if (this._canvas) { + var ctx = this._ctx; + ctx.clearRect(this._first ? 0 : this._vx, 0, this._width, this._height); + for (i = 0; i < this._view.length; i++) { + one = this._view[i]; + if (this._first) { + ctx.fillStyle = "white"; + ctx.fillText(one.title, one.x, one.y); + } + ctx.fillStyle = one.color; + value = Stat[one.value]; + (one.units == "M") && (value = Math.floor(value / (1024 * 1024) * 100) / 100 + " M"); + ctx.fillText(value + "", one.x + this._vx, one.y); + } + } + } + renderInfo() { + var text = ""; + for (var i = 0; i < this._view.length; i++) { + var one = this._view[i]; + var value = Stat[one.value]; + (one.units == "M") && (value = Math.floor(value / (1024 * 1024) * 100) / 100 + " M"); + (one.units == "K") && (value = Math.floor(value / (1024) * 100) / 100 + " K"); + text += value + "\n"; + } + this._txt.text = text; + } + isCanvasRender() { + return this._useCanvas; + } + renderNotCanvas(ctx, x, y) { + this._show && this._sp && this._sp.render(ctx, 0, 0); + } + } + StatUI._fontSize = 12; + + class Timer { + constructor(autoActive = true) { + this.scale = 1; + this.currTimer = Date.now(); + this.currFrame = 0; + this._delta = 0; + this._lastTimer = Date.now(); + this._map = []; + this._handlers = []; + this._temp = []; + this._count = 0; + autoActive && Timer.gSysTimer && Timer.gSysTimer.frameLoop(1, this, this._update); + } + get delta() { + return this._delta; + } + _update() { + if (this.scale <= 0) { + this._lastTimer = Date.now(); + this._delta = 0; + return; + } + var frame = this.currFrame = this.currFrame + this.scale; + var now = Date.now(); + var awake = (now - this._lastTimer) > 30000; + this._delta = (now - this._lastTimer) * this.scale; + var timer = this.currTimer = this.currTimer + this._delta; + this._lastTimer = now; + var handlers = this._handlers; + this._count = 0; + for (var i = 0, n = handlers.length; i < n; i++) { + var handler = handlers[i]; + if (handler.method !== null) { + var t = handler.userFrame ? frame : timer; + if (t >= handler.exeTime) { + if (handler.repeat) { + if (!handler.jumpFrame || awake) { + handler.exeTime += handler.delay; + handler.run(false); + if (t > handler.exeTime) { + handler.exeTime += Math.ceil((t - handler.exeTime) / handler.delay) * handler.delay; + } + } + else { + while (t >= handler.exeTime) { + handler.exeTime += handler.delay; + handler.run(false); + } + } + } + else { + handler.run(true); + } + } + } + else { + this._count++; + } + } + if (this._count > 30 || frame % 200 === 0) + this._clearHandlers(); + } + _clearHandlers() { + var handlers = this._handlers; + for (var i = 0, n = handlers.length; i < n; i++) { + var handler = handlers[i]; + if (handler.method !== null) + this._temp.push(handler); + else + this._recoverHandler(handler); + } + this._handlers = this._temp; + handlers.length = 0; + this._temp = handlers; + } + _recoverHandler(handler) { + if (this._map[handler.key] == handler) + this._map[handler.key] = null; + handler.clear(); + Timer._pool.push(handler); + } + _create(useFrame, repeat, delay, caller, method, args, coverBefore) { + if (!delay) { + method.apply(caller, args); + return null; + } + if (coverBefore) { + var handler = this._getHandler(caller, method); + if (handler) { + handler.repeat = repeat; + handler.userFrame = useFrame; + handler.delay = delay; + handler.caller = caller; + handler.method = method; + handler.args = args; + handler.exeTime = delay + (useFrame ? this.currFrame : this.currTimer + Date.now() - this._lastTimer); + return handler; + } + } + handler = Timer._pool.length > 0 ? Timer._pool.pop() : new TimerHandler(); + handler.repeat = repeat; + handler.userFrame = useFrame; + handler.delay = delay; + handler.caller = caller; + handler.method = method; + handler.args = args; + handler.exeTime = delay + (useFrame ? this.currFrame : this.currTimer + Date.now() - this._lastTimer); + this._indexHandler(handler); + this._handlers.push(handler); + return handler; + } + _indexHandler(handler) { + var caller = handler.caller; + var method = handler.method; + var cid = caller ? caller.$_GID || (caller.$_GID = ILaya.Utils.getGID()) : 0; + var mid = method.$_TID || (method.$_TID = (Timer._mid++) * 100000); + handler.key = cid + mid; + this._map[handler.key] = handler; + } + once(delay, caller, method, args = null, coverBefore = true) { + this._create(false, false, delay, caller, method, args, coverBefore); + } + loop(delay, caller, method, args = null, coverBefore = true, jumpFrame = false) { + var handler = this._create(false, true, delay, caller, method, args, coverBefore); + if (handler) + handler.jumpFrame = jumpFrame; + } + frameOnce(delay, caller, method, args = null, coverBefore = true) { + this._create(true, false, delay, caller, method, args, coverBefore); + } + frameLoop(delay, caller, method, args = null, coverBefore = true) { + this._create(true, true, delay, caller, method, args, coverBefore); + } + toString() { + return " handlers:" + this._handlers.length + " pool:" + Timer._pool.length; + } + clear(caller, method) { + var handler = this._getHandler(caller, method); + if (handler) { + this._map[handler.key] = null; + handler.key = 0; + handler.clear(); + } + } + clearAll(caller) { + if (!caller) + return; + for (var i = 0, n = this._handlers.length; i < n; i++) { + var handler = this._handlers[i]; + if (handler.caller === caller) { + this._map[handler.key] = null; + handler.key = 0; + handler.clear(); + } + } + } + _getHandler(caller, method) { + var cid = caller ? caller.$_GID || (caller.$_GID = ILaya.Utils.getGID()) : 0; + var mid = method.$_TID || (method.$_TID = (Timer._mid++) * 100000); + return this._map[cid + mid]; + } + callLater(caller, method, args = null) { + CallLater.I.callLater(caller, method, args); + } + runCallLater(caller, method) { + CallLater.I.runCallLater(caller, method); + } + runTimer(caller, method) { + var handler = this._getHandler(caller, method); + if (handler && handler.method != null) { + this._map[handler.key] = null; + handler.run(true); + } + } + pause() { + this.scale = 0; + } + resume() { + this.scale = 1; + } + } + Timer.gSysTimer = null; + Timer._pool = []; + Timer._mid = 1; + class TimerHandler { + clear() { + this.caller = null; + this.method = null; + this.args = null; + } + run(withClear) { + var caller = this.caller; + if (caller && caller.destroyed) + return this.clear(); + var method = this.method; + var args = this.args; + withClear && this.clear(); + if (method == null) + return; + args ? method.apply(caller, args) : method.call(caller); + } + } + + class SkinSV extends Value2D { + constructor(type) { + super(ShaderDefines2D.SKINMESH, 0); + this.offsetX = 300; + this.offsetY = 0; + var gl = WebGLContext.mainContext; + var _vlen = 8 * CONST3D2D.BYTES_PE; + this.position = [2, gl.FLOAT, false, _vlen, 0]; + this.texcoord = [2, gl.FLOAT, false, _vlen, 2 * CONST3D2D.BYTES_PE]; + this.color = [4, gl.FLOAT, false, _vlen, 4 * CONST3D2D.BYTES_PE]; + } + } + + class PrimitiveSV extends Value2D { + constructor(args) { + super(ShaderDefines2D.PRIMITIVE, 0); + this._attribLocation = ['position', 0, 'attribColor', 1]; + } + } + + class TextureSV extends Value2D { + constructor(subID = 0) { + super(ShaderDefines2D.TEXTURE2D, subID); + this.strength = 0; + this.blurInfo = null; + this.colorMat = null; + this.colorAlpha = null; + this._attribLocation = ['posuv', 0, 'attribColor', 1, 'attribFlags', 2]; + } + clear() { + this.texture = null; + this.shader = null; + this.defines._value = this.subID; + } + } + + class InlcudeFile { + constructor(txt) { + this.codes = {}; + this.funs = {}; + this.curUseID = -1; + this.funnames = ""; + this.script = txt; + var begin = 0, ofs, end; + while (true) { + begin = txt.indexOf("#begin", begin); + if (begin < 0) + break; + end = begin + 5; + while (true) { + end = txt.indexOf("#end", end); + if (end < 0) + break; + if (txt.charAt(end + 4) === 'i') + end += 5; + else + break; + } + if (end < 0) { + throw "add include err,no #end:" + txt; + } + ofs = txt.indexOf('\n', begin); + var words = ILaya.ShaderCompile.splitToWords(txt.substr(begin, ofs - begin), null); + if (words[1] == 'code') { + this.codes[words[2]] = txt.substr(ofs + 1, end - ofs - 1); + } + else if (words[1] == 'function') { + ofs = txt.indexOf("function", begin); + ofs += "function".length; + this.funs[words[3]] = txt.substr(ofs + 1, end - ofs - 1); + this.funnames += words[3] + ";"; + } + begin = end + 1; + } + } + getWith(name = null) { + var r = name ? this.codes[name] : this.script; + if (!r) { + throw "get with error:" + name; + } + return r; + } + getFunsScript(funsdef) { + var r = ""; + for (var i in this.funs) { + if (funsdef.indexOf(i + ";") >= 0) { + r += this.funs[i]; + } + } + return r; + } + } + + class ShaderNode { + constructor(includefiles) { + this.childs = []; + this.text = ""; + this.useFuns = ""; + this.z = 0; + this.includefiles = includefiles; + } + setParent(parent) { + parent.childs.push(this); + this.z = parent.z + 1; + this.parent = parent; + } + setCondition(condition, type) { + if (condition) { + this.conditionType = type; + condition = condition.replace(/(\s*$)/g, ""); + this.condition = function () { + return this[condition]; + }; + this.condition.__condition = condition; + } + } + toscript(def, out) { + return this._toscript(def, out, ++ShaderNode.__id); + } + _toscript(def, out, id) { + if (this.childs.length < 1 && !this.text) + return out; + var outIndex = out.length; + if (this.condition) { + var ifdef = !!this.condition.call(def); + this.conditionType === ILaya.ShaderCompile.IFDEF_ELSE && (ifdef = !ifdef); + if (!ifdef) + return out; + } + if (this.noCompile) + this.text && out.push(this.text); + this.childs.length > 0 && this.childs.forEach(function (o, index, arr) { + o._toscript(def, out, id); + }); + if (this.includefiles.length > 0 && this.useFuns.length > 0) { + var funsCode; + for (var i = 0, n = this.includefiles.length; i < n; i++) { + if (this.includefiles[i].curUseID == id) { + continue; + } + funsCode = this.includefiles[i].file.getFunsScript(this.useFuns); + if (funsCode.length > 0) { + this.includefiles[i].curUseID = id; + out[0] = funsCode + out[0]; + } + } + } + return out; + } + } + ShaderNode.__id = 1; + + class ShaderCompile { + constructor(vs, ps, nameMap) { + this.defs = {}; + let _this = this; + function _compile(script) { + script = script.replace(ShaderCompile._clearCR, ""); + var includefiles = []; + var top = new ShaderNode(includefiles); + _this._compileToTree(top, script.split('\n'), 0, includefiles, _this.defs); + return top; + } + var startTime = Date.now(); + this._VS = _compile(vs); + this._PS = _compile(ps); + this._nameMap = nameMap; + if ((Date.now() - startTime) > 2) + console.log("ShaderCompile use time:" + (Date.now() - startTime) + " size:" + vs.length + "/" + ps.length); + } + static __init__() { + var gl = LayaGL.instance; + ShaderCompile.shaderParamsMap = { "float": gl.FLOAT, "int": gl.INT, "bool": gl.BOOL, "vec2": gl.FLOAT_VEC2, "vec3": gl.FLOAT_VEC3, "vec4": gl.FLOAT_VEC4, "ivec2": gl.INT_VEC2, "ivec3": gl.INT_VEC3, "ivec4": gl.INT_VEC4, "bvec2": gl.BOOL_VEC2, "bvec3": gl.BOOL_VEC3, "bvec4": gl.BOOL_VEC4, "mat2": gl.FLOAT_MAT2, "mat3": gl.FLOAT_MAT3, "mat4": gl.FLOAT_MAT4, "sampler2D": gl.SAMPLER_2D, "samplerCube": gl.SAMPLER_CUBE }; + } + static _parseOne(attributes, uniforms, words, i, word, b) { + var one = { type: ShaderCompile.shaderParamsMap[words[i + 1]], name: words[i + 2], size: isNaN(parseInt(words[i + 3])) ? 1 : parseInt(words[i + 3]) }; + if (b) { + if (word == "attribute") { + attributes.push(one); + } + else { + uniforms.push(one); + } + } + if (words[i + 3] == ':') { + one.type = words[i + 4]; + i += 2; + } + i += 2; + return i; + } + static addInclude(fileName, txt) { + if (!txt || txt.length === 0) + throw new Error("add shader include file err:" + fileName); + if (ShaderCompile.includes[fileName]) + throw new Error("add shader include file err, has add:" + fileName); + ShaderCompile.includes[fileName] = new InlcudeFile(txt); + } + static preGetParams(vs, ps) { + var text = [vs, ps]; + var result = {}; + var attributes = []; + var uniforms = []; + var definesInfo = {}; + var definesName = {}; + result.attributes = attributes; + result.uniforms = uniforms; + result.defines = definesInfo; + var i, n; + for (var s = 0; s < 2; s++) { + text[s] = text[s].replace(ShaderCompile._removeAnnotation, ""); + var words = text[s].match(ShaderCompile._reg); + var tempelse; + for (i = 0, n = words.length; i < n; i++) { + var word = words[i]; + if (word != "attribute" && word != "uniform") { + if (word == "#define") { + word = words[++i]; + definesName[word] = 1; + continue; + } + else if (word == "#ifdef") { + tempelse = words[++i]; + var def = definesInfo[tempelse] = definesInfo[tempelse] || []; + for (i++; i < n; i++) { + word = words[i]; + if (word != "attribute" && word != "uniform") { + if (word == "#else") { + for (i++; i < n; i++) { + word = words[i]; + if (word != "attribute" && word != "uniform") { + if (word == "#endif") { + break; + } + continue; + } + i = ShaderCompile._parseOne(attributes, uniforms, words, i, word, !definesName[tempelse]); + } + } + continue; + } + i = ShaderCompile._parseOne(attributes, uniforms, words, i, word, !!definesName[tempelse]); + } + } + continue; + } + i = ShaderCompile._parseOne(attributes, uniforms, words, i, word, true); + } + } + return result; + } + static splitToWords(str, block) { + var out = []; + var c; + var ofs = -1; + var word; + for (var i = 0, n = str.length; i < n; i++) { + c = str.charAt(i); + if (" \t=+-*/&%!<>()'\",;".indexOf(c) >= 0) { + if (ofs >= 0 && (i - ofs) > 1) { + word = str.substr(ofs, i - ofs); + out.push(word); + } + if (c == '"' || c == "'") { + var ofs2 = str.indexOf(c, i + 1); + if (ofs2 < 0) { + throw "Sharder err:" + str; + } + out.push(str.substr(i + 1, ofs2 - i - 1)); + i = ofs2; + ofs = -1; + continue; + } + if (c == '(' && block && out.length > 0) { + word = out[out.length - 1] + ";"; + if ("vec4;main;".indexOf(word) < 0) + block.useFuns += word; + } + ofs = -1; + continue; + } + if (ofs < 0) + ofs = i; + } + if (ofs < n && (n - ofs) > 1) { + word = str.substr(ofs, n - ofs); + out.push(word); + } + return out; + } + _compileToTree(parent, lines, start, includefiles, defs) { + var node, preNode; + var text, name, fname; + var ofs, words, noUseNode; + var i, n, j; + for (i = start; i < lines.length; i++) { + text = lines[i]; + if (text.length < 1) + continue; + ofs = text.indexOf("//"); + if (ofs === 0) + continue; + if (ofs >= 0) + text = text.substr(0, ofs); + node = noUseNode || new ShaderNode(includefiles); + noUseNode = null; + node.text = text; + node.noCompile = true; + if ((ofs = text.indexOf("#")) >= 0) { + name = "#"; + for (j = ofs + 1, n = text.length; j < n; j++) { + var c = text.charAt(j); + if (c === ' ' || c === '\t' || c === '?') + break; + name += c; + } + node.name = name; + switch (name) { + case "#ifdef": + case "#ifndef": + node.src = text; + node.noCompile = text.match(/[!&|()=<>]/) != null; + if (!node.noCompile) { + words = text.replace(/^\s*/, '').split(/\s+/); + node.setCondition(words[1], name === "#ifdef" ? ShaderCompile.IFDEF_YES : ShaderCompile.IFDEF_ELSE); + node.text = "//" + node.text; + } + else { + console.log("function():Boolean{return " + text.substr(ofs + node.name.length) + "}"); + } + node.setParent(parent); + parent = node; + if (defs) { + words = text.substr(j).split(ShaderCompile._splitToWordExps3); + for (j = 0; j < words.length; j++) { + text = words[j]; + text.length && (defs[text] = true); + } + } + continue; + case "#if": + node.src = text; + node.noCompile = true; + node.setParent(parent); + parent = node; + if (defs) { + words = text.substr(j).split(ShaderCompile._splitToWordExps3); + for (j = 0; j < words.length; j++) { + text = words[j]; + text.length && text != "defined" && (defs[text] = true); + } + } + continue; + case "#else": + node.src = text; + parent = parent.parent; + preNode = parent.childs[parent.childs.length - 1]; + node.noCompile = preNode.noCompile; + if (!node.noCompile) { + node.condition = preNode.condition; + node.conditionType = preNode.conditionType == ShaderCompile.IFDEF_YES ? ShaderCompile.IFDEF_ELSE : ShaderCompile.IFDEF_YES; + node.text = "//" + node.text + " " + preNode.text + " " + node.conditionType; + } + node.setParent(parent); + parent = node; + continue; + case "#endif": + parent = parent.parent; + preNode = parent.childs[parent.childs.length - 1]; + node.noCompile = preNode.noCompile; + if (!node.noCompile) { + node.text = "//" + node.text; + } + node.setParent(parent); + continue; + case "#include": + words = ShaderCompile.splitToWords(text, null); + var inlcudeFile = ShaderCompile.includes[words[1]]; + if (!inlcudeFile) { + throw "ShaderCompile error no this include file:" + words[1]; + } + if ((ofs = words[0].indexOf("?")) < 0) { + node.setParent(parent); + text = inlcudeFile.getWith(words[2] == 'with' ? words[3] : null); + this._compileToTree(node, text.split('\n'), 0, includefiles, defs); + node.text = ""; + continue; + } + node.setCondition(words[0].substr(ofs + 1), ShaderCompile.IFDEF_YES); + node.text = inlcudeFile.getWith(words[2] == 'with' ? words[3] : null); + break; + case "#import": + words = ShaderCompile.splitToWords(text, null); + fname = words[1]; + includefiles.push({ node: node, file: ShaderCompile.includes[fname], ofs: node.text.length }); + continue; + } + } + else { + preNode = parent.childs[parent.childs.length - 1]; + if (preNode && !preNode.name) { + includefiles.length > 0 && ShaderCompile.splitToWords(text, preNode); + noUseNode = node; + preNode.text += "\n" + text; + continue; + } + includefiles.length > 0 && ShaderCompile.splitToWords(text, node); + } + node.setParent(parent); + } + } + createShader(define, shaderName, createShader, bindAttrib) { + var defMap = {}; + var defineStr = ""; + if (define) { + for (var i in define) { + defineStr += "#define " + i + "\n"; + defMap[i] = true; + } + } + var vs = this._VS.toscript(defMap, []); + var ps = this._PS.toscript(defMap, []); + return (createShader || Shader.create)(defineStr + vs.join('\n'), defineStr + ps.join('\n'), shaderName, this._nameMap, bindAttrib); + } + } + ShaderCompile.IFDEF_NO = 0; + ShaderCompile.IFDEF_YES = 1; + ShaderCompile.IFDEF_ELSE = 2; + ShaderCompile.IFDEF_PARENT = 3; + ShaderCompile._removeAnnotation = new RegExp("(/\\*([^*]|[\\r\\\n]|(\\*+([^*/]|[\\r\\n])))*\\*+/)|(//.*)", "g"); + ShaderCompile._reg = new RegExp("(\".*\")|('.*')|([#\\w\\*-\\.+/()=<>{}\\\\]+)|([,;:\\\\])", "g"); + ShaderCompile._splitToWordExps = new RegExp("[(\".*\")]+|[('.*')]+|([ \\t=\\+\\-*/&%!<>!%\(\),;])", "g"); + ShaderCompile.includes = {}; + ShaderCompile._clearCR = new RegExp("\r", "g"); + ShaderCompile._splitToWordExps3 = new RegExp("[ \\t=\\+\\-*/&%!<>!%\(\),;\\|]", "g"); + + class WorkerLoader extends EventDispatcher { + constructor() { + super(); + this.worker = new Worker(WorkerLoader.workerPath); + let me = this; + this.worker.onmessage = function (evt) { + me.workerMessage(evt.data); + }; + } + static __init__() { + if (WorkerLoader._preLoadFun != null) + return false; + if (!Worker) + return false; + WorkerLoader._preLoadFun = Loader["prototype"]["_loadImage"]; + Loader["prototype"]["_loadImage"] = WorkerLoader["prototype"]["_loadImage"]; + if (!WorkerLoader.I) + WorkerLoader.I = new WorkerLoader(); + return true; + } + static workerSupported() { + return Worker ? true : false; + } + static enableWorkerLoader() { + if (!WorkerLoader._tryEnabled) { + WorkerLoader.enable = true; + WorkerLoader._tryEnabled = true; + } + } + static set enable(value) { + if (WorkerLoader._enable != value) { + WorkerLoader._enable = value; + if (value && WorkerLoader._preLoadFun == null) + WorkerLoader._enable = WorkerLoader.__init__(); + } + } + static get enable() { + return WorkerLoader._enable; + } + workerMessage(data) { + if (data) { + switch (data.type) { + case "Image": + this.imageLoaded(data); + break; + case "Disable": + WorkerLoader.enable = false; + break; + } + } + } + imageLoaded(data) { + if (!data.dataType || data.dataType != "imageBitmap") { + this.event(data.url, null); + return; + } + var imageData = data.imageBitmap; + console.log("load:", data.url); + this.event(data.url, imageData); + } + loadImage(url) { + this.worker.postMessage(url); + } + _loadImage(url) { + var _this = this; + let type = _this.type; + if (!this._useWorkerLoader || !WorkerLoader._enable) { + WorkerLoader._preLoadFun.call(_this, url); + return; + } + url = URL.formatURL(url); + function clear() { + WorkerLoader.I.off(url, _this, onload); + } + var onload = function (imageData) { + clear(); + if (imageData) { + var image = imageData; + if (type !== "nativeimage") { + image = new Texture2D(); + image.wrapModeU = exports.WarpMode.Clamp; + image.wrapModeV = exports.WarpMode.Clamp; + image.loadImageSource(imageData, true); + } + _this["onLoaded"](image); + } + else { + WorkerLoader._preLoadFun.call(_this, url); + } + }; + WorkerLoader.I.on(url, _this, onload); + WorkerLoader.I.loadImage(url); + } + } + WorkerLoader.workerPath = "libs/workerloader.js"; + WorkerLoader._enable = false; + WorkerLoader._tryEnabled = false; + + class Mouse { + static set cursor(cursorStr) { + Mouse._style.cursor = cursorStr; + } + static get cursor() { + return Mouse._style.cursor; + } + static __init__() { + Mouse._style = Browser.document.body.style; + } + static hide() { + if (Mouse.cursor != "none") { + Mouse._preCursor = Mouse.cursor; + Mouse.cursor = "none"; + } + } + static show() { + if (Mouse.cursor == "none") { + if (Mouse._preCursor) { + Mouse.cursor = Mouse._preCursor; + } + else { + Mouse.cursor = "auto"; + } + } + } + } + + class MeshParticle2D extends Mesh2D { + constructor(maxNum) { + super(MeshParticle2D.const_stride, maxNum * 4 * MeshParticle2D.const_stride, 4); + this.canReuse = true; + this.setAttributes(MeshParticle2D._fixattriInfo); + this.createQuadIB(maxNum); + this._quadNum = maxNum; + } + static __init__() { + var gl = LayaGL.instance; + MeshParticle2D._fixattriInfo = [gl.FLOAT, 4, 0, + gl.FLOAT, 3, 16, + gl.FLOAT, 3, 28, + gl.FLOAT, 4, 40, + gl.FLOAT, 4, 56, + gl.FLOAT, 3, 72, + gl.FLOAT, 2, 84, + gl.FLOAT, 4, 92, + gl.FLOAT, 1, 108, + gl.FLOAT, 1, 112]; + } + setMaxParticleNum(maxNum) { + this._vb._resizeBuffer(maxNum * 4 * MeshParticle2D.const_stride, false); + this.createQuadIB(maxNum); + } + static getAMesh(maxNum) { + if (MeshParticle2D._POOL.length) { + var ret = MeshParticle2D._POOL.pop(); + ret.setMaxParticleNum(maxNum); + return ret; + } + return new MeshParticle2D(maxNum); + } + releaseMesh() { + this._vb.setByteLength(0); + this.vertNum = 0; + this.indexNum = 0; + MeshParticle2D._POOL.push(this); + } + destroy() { + this._ib.destroy(); + this._vb.destroy(); + this._vb.deleteBuffer(); + } + } + MeshParticle2D.const_stride = 116; + MeshParticle2D._POOL = []; + + class HTMLImage extends Bitmap { + } + HTMLImage.create = function (width, height, format) { + var tex = new Texture2D(width, height, format, false, false); + tex.wrapModeU = exports.WarpMode.Clamp; + tex.wrapModeV = exports.WarpMode.Clamp; + return tex; + }; + + class Laya { + static __init(_classs) { + _classs.forEach(function (o) { o.__init$ && o.__init$(); }); + } + static init(width, height, ...plugins) { + if (Laya._isinit) + return; + Laya._isinit = true; + ArrayBuffer.prototype.slice || (ArrayBuffer.prototype.slice = Laya._arrayBufferSlice); + Browser.__init__(); + var mainCanv = Browser.mainCanvas = new HTMLCanvas(true); + var style = mainCanv.source.style; + style.position = 'absolute'; + style.top = style.left = "0px"; + style.background = "#000000"; + if (!Browser.onKGMiniGame && !Browser.onAlipayMiniGame) { + Browser.container.appendChild(mainCanv.source); + } + Browser.canvas = new HTMLCanvas(true); + Browser.context = Browser.canvas.getContext('2d'); + Browser.supportWebAudio = SoundManager.__init__(); + Browser.supportLocalStorage = LocalStorage.__init__(); + Laya.systemTimer = new Timer(false); + exports.systemTimer = Timer.gSysTimer = Laya.systemTimer; + Laya.startTimer = new Timer(false); + Laya.physicsTimer = new Timer(false); + Laya.updateTimer = new Timer(false); + Laya.lateTimer = new Timer(false); + Laya.timer = new Timer(false); + exports.startTimer = ILaya.startTimer = Laya.startTimer; + exports.lateTimer = ILaya.lateTimer = Laya.lateTimer; + exports.updateTimer = ILaya.updateTimer = Laya.updateTimer; + ILaya.systemTimer = Laya.systemTimer; + exports.timer = ILaya.timer = Laya.timer; + exports.physicsTimer = ILaya.physicsTimer = Laya.physicsTimer; + Laya.loader = new LoaderManager(); + ILaya.Laya = Laya; + exports.loader = ILaya.loader = Laya.loader; + WeakObject.__init__(); + SceneUtils.__init(); + Mouse.__init__(); + WebGL.inner_enable(); + if (plugins) { + for (var i = 0, n = plugins.length; i < n; i++) { + if (plugins[i] && plugins[i].enable) { + plugins[i].enable(); + } + } + } + if (ILaya.Render.isConchApp) { + Laya.enableNative(); + } + Laya.enableWebGLPlus(); + CacheManger.beginCheck(); + exports.stage = Laya.stage = new Stage(); + ILaya.stage = Laya.stage; + Utils.gStage = Laya.stage; + URL.rootPath = URL._basePath = Laya._getUrlPath(); + MeshQuadTexture.__int__(); + MeshVG.__init__(); + MeshTexture.__init__(); + Laya.render = new Render(0, 0, Browser.mainCanvas); + exports.render = Laya.render; + Laya.stage.size(width, height); + window.stage = Laya.stage; + WebGLContext.__init__(); + MeshParticle2D.__init__(); + ShaderCompile.__init__(); + RenderSprite.__init__(); + KeyBoardManager.__init__(); + MouseManager.instance.__init__(Laya.stage, Render.canvas); + Input.__init__(); + SoundManager.autoStopMusic = true; + Stat._StatRender = new StatUI(); + Value2D._initone(ShaderDefines2D.TEXTURE2D, TextureSV); + Value2D._initone(ShaderDefines2D.TEXTURE2D | ShaderDefines2D.FILTERGLOW, TextureSV); + Value2D._initone(ShaderDefines2D.PRIMITIVE, PrimitiveSV); + Value2D._initone(ShaderDefines2D.SKINMESH, SkinSV); + return Render.canvas; + } + static _getUrlPath() { + return URL.getPath(location.protocol + "//" + location.host + location.pathname); + } + static _arrayBufferSlice(start, end) { + var arr = this; + var arrU8List = new Uint8Array(arr, start, end - start); + var newU8List = new Uint8Array(arrU8List.length); + newU8List.set(arrU8List); + return newU8List.buffer; + } + static alertGlobalError(value) { + var erralert = 0; + if (value) { + Browser.window.onerror = function (msg, url, line, column, detail) { + if (erralert++ < 5 && detail) + this.alert("出错啦,请把此信息截图给研发商\n" + msg + "\n" + detail.stack); + }; + } + else { + Browser.window.onerror = null; + } + } + static _runScript(script) { + return Browser.window[Laya._evcode](script); + } + static enableDebugPanel(debugJsPath = "libs/laya.debugtool.js") { + if (!window['Laya']["DebugPanel"]) { + var script = Browser.createElement("script"); + script.onload = function () { + window['Laya']["DebugPanel"].enable(); + }; + script.src = debugJsPath; + Browser.document.body.appendChild(script); + } + else { + window['Laya']["DebugPanel"].enable(); + } + } + static enableWebGLPlus() { + WebGLContext.__init_native(); + } + static enableNative() { + if (Laya.isNativeRender_enable) + return; + Laya.isNativeRender_enable = true; + if (Render.supportWebGLPlusRendering) { + Shader.prototype.uploadTexture2D = function (value) { + var gl = LayaGL.instance; + gl.bindTexture(gl.TEXTURE_2D, value); + }; + } + RenderState2D.width = Browser.window.innerWidth; + RenderState2D.height = Browser.window.innerHeight; + Browser.measureText = function (txt, font) { + window["conchTextCanvas"].font = font; + return window["conchTextCanvas"].measureText(txt); + }; + Stage.clear = function (color) { + Context.set2DRenderConfig(); + var c = ColorUtils.create(color).arrColor; + var gl = LayaGL.instance; + if (c) + gl.clearColor(c[0], c[1], c[2], c[3]); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); + RenderState2D.clear(); + }; + Sprite.drawToCanvas = function (sprite, _renderType, canvasWidth, canvasHeight, offsetX, offsetY) { + offsetX -= sprite.x; + offsetY -= sprite.y; + offsetX |= 0; + offsetY |= 0; + canvasWidth |= 0; + canvasHeight |= 0; + var canv = new HTMLCanvas(false); + var ctx = canv.getContext('2d'); + canv.size(canvasWidth, canvasHeight); + ctx.asBitmap = true; + ctx._targets.start(); + RenderSprite.renders[_renderType]._fun(sprite, ctx, offsetX, offsetY); + ctx.flush(); + ctx._targets.end(); + ctx._targets.restore(); + return canv; + }; + Object["defineProperty"](RenderTexture2D.prototype, "uv", { + "get": function () { + return this._uv; + }, + "set": function (v) { + this._uv = v; + } + }); + HTMLCanvas.prototype.getTexture = function () { + if (!this._texture) { + this._texture = this.context._targets; + this._texture.uv = RenderTexture2D.flipyuv; + this._texture.bitmap = this._texture; + } + return this._texture; + }; + } + } + Laya.stage = null; + Laya.systemTimer = null; + Laya.startTimer = null; + Laya.physicsTimer = null; + Laya.updateTimer = null; + Laya.lateTimer = null; + Laya.timer = null; + Laya.loader = null; + Laya.version = "2.12.1beta"; + Laya._isinit = false; + Laya.isWXOpenDataContext = false; + Laya.isWXPosMsg = false; + Laya.__classmap = null; + Laya.Config = Config; + Laya.TextRender = TextRender; + Laya.EventDispatcher = EventDispatcher; + Laya.SoundChannel = SoundChannel; + Laya.Stage = Stage; + Laya.Render = Render; + Laya.Browser = Browser; + Laya.Sprite = Sprite; + Laya.Node = Node; + Laya.Context = Context; + Laya.WebGL = WebGL; + Laya.Handler = Handler; + Laya.RunDriver = RunDriver; + Laya.Utils = Utils; + Laya.Input = Input; + Laya.Loader = Loader; + Laya.LocalStorage = LocalStorage; + Laya.SoundManager = SoundManager; + Laya.URL = URL; + Laya.Event = Event; + Laya.Matrix = Matrix; + Laya.HTMLImage = HTMLImage; + Laya.Laya = Laya; + Laya._evcode = "eva" + "l"; + Laya.isNativeRender_enable = false; + Laya.__classmap = ILaya.__classMap; + ILaya.Timer = Timer; + ILaya.Dragging = Dragging; + ILaya.GraphicsBounds = GraphicsBounds; + ILaya.Sprite = Sprite; + ILaya.TextRender = TextRender; + ILaya.Loader = Loader; + ILaya.TTFLoader = TTFLoader; + ILaya.WebAudioSound = WebAudioSound; + ILaya.SoundManager = SoundManager; + ILaya.ShaderCompile = ShaderCompile; + ILaya.ClassUtils = ClassUtils; + ILaya.SceneUtils = SceneUtils; + ILaya.Context = Context; + ILaya.Render = Render; + ILaya.MouseManager = MouseManager; + ILaya.Text = Text; + ILaya.Browser = Browser; + ILaya.WebGL = WebGL; + ILaya.AudioSound = AudioSound; + ILaya.Pool = Pool; + ILaya.Utils = Utils; + ILaya.Graphics = Graphics; + ILaya.Submit = Submit; + ILaya.Stage = Stage; + ILaya.Resource = Resource; + ILaya.WorkerLoader = WorkerLoader; + var libs = window._layalibs; + if (libs) { + libs.sort(function (a, b) { + return a.i - b.i; + }); + for (var j = 0; j < libs.length; j++) { + libs[j].f(window, window.document, Laya); + } + } + let win = window; + if (win.Laya) { + win.Laya.Laya = Laya; + Object.assign(win.Laya, Laya); + } + else + win.Laya = Laya; + var __init = Laya.__init; + var init = Laya.init; + var version = Laya.version; + var isWXOpenDataContext; + var isWXPosMsg; + var alertGlobalError = Laya.alertGlobalError; + var enableDebugPanel = Laya.enableDebugPanel; + function _static(_class, def) { + for (var i = 0, sz = def.length; i < sz; i += 2) { + if (def[i] == 'length') + _class.length = def[i + 1].call(_class); + else { + function tmp() { + var name = def[i]; + var getfn = def[i + 1]; + Object.defineProperty(_class, name, { + get: function () { delete this[name]; return this[name] = getfn.call(this); }, + set: function (v) { delete this[name]; this[name] = v; }, enumerable: true, configurable: true + }); + } + tmp(); + } + } + } + + class CommonScript extends Component { + get isSingleton() { + return false; + } + constructor() { + super(); + } + onAwake() { + } + onEnable() { + } + onStart() { + } + onUpdate() { + } + onLateUpdate() { + } + onDisable() { + } + onDestroy() { + } + } + + class Script extends Component { + get isSingleton() { + return false; + } + _onAwake() { + this.onAwake(); + if (this.onStart !== Script.prototype.onStart) { + ILaya.startTimer.callLater(this, this.onStart); + } + } + _onEnable() { + var proto = Script.prototype; + if (this.onTriggerEnter !== proto.onTriggerEnter) { + this.owner.on(Event.TRIGGER_ENTER, this, this.onTriggerEnter); + } + if (this.onTriggerStay !== proto.onTriggerStay) { + this.owner.on(Event.TRIGGER_STAY, this, this.onTriggerStay); + } + if (this.onTriggerExit !== proto.onTriggerExit) { + this.owner.on(Event.TRIGGER_EXIT, this, this.onTriggerExit); + } + if (this.onMouseDown !== proto.onMouseDown) { + this.owner.on(Event.MOUSE_DOWN, this, this.onMouseDown); + } + if (this.onMouseUp !== proto.onMouseUp) { + this.owner.on(Event.MOUSE_UP, this, this.onMouseUp); + } + if (this.onClick !== proto.onClick) { + this.owner.on(Event.CLICK, this, this.onClick); + } + if (this.onStageMouseDown !== proto.onStageMouseDown) { + ILaya.stage.on(Event.MOUSE_DOWN, this, this.onStageMouseDown); + } + if (this.onStageMouseUp !== proto.onStageMouseUp) { + ILaya.stage.on(Event.MOUSE_UP, this, this.onStageMouseUp); + } + if (this.onStageClick !== proto.onStageClick) { + ILaya.stage.on(Event.CLICK, this, this.onStageClick); + } + if (this.onStageMouseMove !== proto.onStageMouseMove) { + ILaya.stage.on(Event.MOUSE_MOVE, this, this.onStageMouseMove); + } + if (this.onDoubleClick !== proto.onDoubleClick) { + this.owner.on(Event.DOUBLE_CLICK, this, this.onDoubleClick); + } + if (this.onRightClick !== proto.onRightClick) { + this.owner.on(Event.RIGHT_CLICK, this, this.onRightClick); + } + if (this.onMouseMove !== proto.onMouseMove) { + this.owner.on(Event.MOUSE_MOVE, this, this.onMouseMove); + } + if (this.onMouseOver !== proto.onMouseOver) { + this.owner.on(Event.MOUSE_OVER, this, this.onMouseOver); + } + if (this.onMouseOut !== proto.onMouseOut) { + this.owner.on(Event.MOUSE_OUT, this, this.onMouseOut); + } + if (this.onKeyDown !== proto.onKeyDown) { + ILaya.stage.on(Event.KEY_DOWN, this, this.onKeyDown); + } + if (this.onKeyPress !== proto.onKeyPress) { + ILaya.stage.on(Event.KEY_PRESS, this, this.onKeyPress); + } + if (this.onKeyUp !== proto.onKeyUp) { + ILaya.stage.on(Event.KEY_UP, this, this.onKeyUp); + } + if (this.onUpdate !== proto.onUpdate) { + ILaya.updateTimer.frameLoop(1, this, this.onUpdate); + } + if (this.onLateUpdate !== proto.onLateUpdate) { + ILaya.lateTimer.frameLoop(1, this, this.onLateUpdate); + } + if (this.onPreRender !== proto.onPreRender) { + ILaya.lateTimer.frameLoop(1, this, this.onPreRender); + } + this.onEnable(); + } + _onDisable() { + this.owner.offAllCaller(this); + ILaya.stage.offAllCaller(this); + ILaya.startTimer.clearAll(this); + ILaya.updateTimer.clearAll(this); + ILaya.lateTimer.clearAll(this); + } + _isScript() { + return true; + } + _onDestroy() { + this.onDestroy(); + } + onAwake() { + } + onEnable() { + } + onStart() { + } + onTriggerEnter(other, self, contact) { + } + onTriggerStay(other, self, contact) { + } + onTriggerExit(other, self, contact) { + } + onMouseDown(e) { + } + onMouseUp(e) { + } + onClick(e) { + } + onStageMouseDown(e) { + } + onStageMouseUp(e) { + } + onStageClick(e) { + } + onStageMouseMove(e) { + } + onDoubleClick(e) { + } + onRightClick(e) { + } + onMouseMove(e) { + } + onMouseOver(e) { + } + onMouseOut(e) { + } + onKeyDown(e) { + } + onKeyPress(e) { + } + onKeyUp(e) { + } + onUpdate() { + } + onLateUpdate() { + } + onPreRender() { + } + onPostRender() { + } + onDisable() { + } + onDestroy() { + } + } + + class GraphicAnimation extends FrameAnimation { + constructor() { + super(...arguments); + this._nodeIDAniDic = {}; + } + _parseNodeList(uiView) { + if (!this._nodeList) + this._nodeList = []; + this._nodeDefaultProps[uiView.compId] = uiView.props; + if (uiView.compId) + this._nodeList.push(uiView.compId); + var childs = uiView.child; + if (childs) { + var i, len = childs.length; + for (i = 0; i < len; i++) { + this._parseNodeList(childs[i]); + } + } + } + _calGraphicData(aniData) { + this._setUp(null, aniData); + this._createGraphicData(); + if (this._nodeIDAniDic) { + var key; + for (key in this._nodeIDAniDic) { + this._nodeIDAniDic[key] = null; + } + } + } + _createGraphicData() { + var gList = []; + var i, len = this.count; + var animationDataNew = this._usedFrames; + if (!animationDataNew) + animationDataNew = []; + var preGraphic; + for (i = 0; i < len; i++) { + if (animationDataNew[i] || !preGraphic) { + preGraphic = this._createFrameGraphic(i); + } + gList.push(preGraphic); + } + this._gList = gList; + } + _createFrameGraphic(frame) { + var g = new Graphics(); + if (!GraphicAnimation._rootMatrix) + GraphicAnimation._rootMatrix = new Matrix(); + this._updateNodeGraphic(this._rootNode, frame, GraphicAnimation._rootMatrix, g); + return g; + } + _updateNodeGraphic(node, frame, parentTransfrom, g, alpha = 1) { + var tNodeG; + tNodeG = this._nodeGDic[node.compId] = this._getNodeGraphicData(node.compId, frame, this._nodeGDic[node.compId]); + if (!tNodeG.resultTransform) + tNodeG.resultTransform = new Matrix(); + var tResultTransform; + tResultTransform = tNodeG.resultTransform; + Matrix.mul(tNodeG.transform, parentTransfrom, tResultTransform); + var tTex; + var tGraphicAlpha = tNodeG.alpha * alpha; + if (tGraphicAlpha < 0.01) + return; + if (tNodeG.skin) { + tTex = this._getTextureByUrl(tNodeG.skin); + if (tTex) { + if (tResultTransform._checkTransform()) { + g.drawTexture(tTex, 0, 0, tNodeG.width, tNodeG.height, tResultTransform, tGraphicAlpha); + tNodeG.resultTransform = null; + } + else { + g.drawTexture(tTex, tResultTransform.tx, tResultTransform.ty, tNodeG.width, tNodeG.height, null, tGraphicAlpha); + } + } + } + var childs = node.child; + if (!childs) + return; + var i, len; + len = childs.length; + for (i = 0; i < len; i++) { + this._updateNodeGraphic(childs[i], frame, tResultTransform, g, tGraphicAlpha); + } + } + _updateNoChilds(tNodeG, g) { + if (!tNodeG.skin) + return; + var tTex = this._getTextureByUrl(tNodeG.skin); + if (!tTex) + return; + var tTransform = tNodeG.transform; + tTransform._checkTransform(); + var onlyTranslate; + onlyTranslate = !tTransform._bTransform; + if (!onlyTranslate) { + g.drawTexture(tTex, 0, 0, tNodeG.width, tNodeG.height, tTransform.clone(), tNodeG.alpha); + } + else { + g.drawTexture(tTex, tTransform.tx, tTransform.ty, tNodeG.width, tNodeG.height, null, tNodeG.alpha); + } + } + _updateNodeGraphic2(node, frame, g) { + var tNodeG; + tNodeG = this._nodeGDic[node.compId] = this._getNodeGraphicData(node.compId, frame, this._nodeGDic[node.compId]); + if (!node.child) { + this._updateNoChilds(tNodeG, g); + return; + } + var tTransform = tNodeG.transform; + tTransform._checkTransform(); + var onlyTranslate; + onlyTranslate = !tTransform._bTransform; + var hasTrans; + hasTrans = onlyTranslate && (tTransform.tx != 0 || tTransform.ty != 0); + var ifSave; + ifSave = (tTransform._bTransform) || tNodeG.alpha != 1; + if (ifSave) + g.save(); + if (tNodeG.alpha != 1) + g.alpha(tNodeG.alpha); + if (!onlyTranslate) + g.transform(tTransform.clone()); + else if (hasTrans) + g.translate(tTransform.tx, tTransform.ty); + var childs = node.child; + var tTex; + if (tNodeG.skin) { + tTex = this._getTextureByUrl(tNodeG.skin); + if (tTex) { + g.drawImage(tTex, 0, 0, tNodeG.width, tNodeG.height); + } + } + if (childs) { + var i, len; + len = childs.length; + for (i = 0; i < len; i++) { + this._updateNodeGraphic2(childs[i], frame, g); + } + } + if (ifSave) { + g.restore(); + } + else { + if (!onlyTranslate) { + g.transform(tTransform.clone().invert()); + } + else if (hasTrans) { + g.translate(-tTransform.tx, -tTransform.ty); + } + } + } + _calculateKeyFrames(node) { + super._calculateKeyFrames(node); + this._nodeIDAniDic[node.target] = node; + } + getNodeDataByID(nodeID) { + return this._nodeIDAniDic[nodeID]; + } + _getParams(obj, params, frame, obj2) { + var rst = GraphicAnimation._temParam; + rst.length = params.length; + var i, len = params.length; + for (i = 0; i < len; i++) { + rst[i] = this._getObjVar(obj, params[i][0], frame, params[i][1], obj2); + } + return rst; + } + _getObjVar(obj, key, frame, noValue, obj2) { + if (key in obj) { + var vArr = obj[key]; + if (frame >= vArr.length) + frame = vArr.length - 1; + return obj[key][frame]; + } + if (key in obj2) { + return obj2[key]; + } + return noValue; + } + _getNodeGraphicData(nodeID, frame, rst) { + if (!rst) + rst = new GraphicNode(); + if (!rst.transform) { + rst.transform = new Matrix(); + } + else { + rst.transform.identity(); + } + var node = this.getNodeDataByID(nodeID); + if (!node) + return rst; + var frameData = node.frames; + var params = this._getParams(frameData, GraphicAnimation._drawTextureCmd, frame, this._nodeDefaultProps[nodeID]); + var url = params[0]; + var width, height; + var px = params[5], py = params[6]; + var aX = params[13], aY = params[14]; + var sx = params[7], sy = params[8]; + var rotate = params[9]; + var skewX = params[11], skewY = params[12]; + width = params[3]; + height = params[4]; + if (width == 0 || height == 0) + url = null; + if (width == -1) + width = 0; + if (height == -1) + height = 0; + var tex; + rst.skin = url; + rst.width = width; + rst.height = height; + if (url) { + tex = this._getTextureByUrl(url); + if (tex) { + if (!width) + width = tex.sourceWidth; + if (!height) + height = tex.sourceHeight; + } + else { + console.warn("lost skin:", url, ",you may load pics first"); + } + } + rst.alpha = params[10]; + var m = rst.transform; + if (aX != 0) { + px = aX * width; + } + if (aY != 0) { + py = aY * height; + } + if (px != 0 || py != 0) { + m.translate(-px, -py); + } + var tm = null; + if (rotate || sx !== 1 || sy !== 1 || skewX || skewY) { + tm = GraphicAnimation._tempMt; + tm.identity(); + tm._bTransform = true; + var skx = (rotate - skewX) * 0.0174532922222222; + var sky = (rotate + skewY) * 0.0174532922222222; + var cx = Math.cos(sky); + var ssx = Math.sin(sky); + var cy = Math.sin(skx); + var ssy = Math.cos(skx); + tm.a = sx * cx; + tm.b = sx * ssx; + tm.c = -sy * cy; + tm.d = sy * ssy; + tm.tx = tm.ty = 0; + } + if (tm) { + m = Matrix.mul(m, tm, m); + } + m.translate(params[1], params[2]); + return rst; + } + _getTextureByUrl(url) { + return Loader.getRes(url); + } + setAniData(uiView, aniName = null) { + if (uiView.animations) { + this._nodeDefaultProps = {}; + this._nodeGDic = {}; + if (this._nodeList) + this._nodeList.length = 0; + this._rootNode = uiView; + this._parseNodeList(uiView); + var aniDic = {}; + var anilist = []; + var animations = uiView.animations; + var i, len = animations.length; + var tAniO; + for (i = 0; i < len; i++) { + tAniO = animations[i]; + this._labels = null; + if (aniName && aniName != tAniO.name) { + continue; + } + if (!tAniO) + continue; + try { + this._calGraphicData(tAniO); + } + catch (e) { + console.warn("parse animation fail:" + tAniO.name + ",empty animation created"); + this._gList = []; + } + var frameO = {}; + frameO.interval = 1000 / tAniO["frameRate"]; + frameO.frames = this._gList; + frameO.labels = this._labels; + frameO.name = tAniO.name; + anilist.push(frameO); + aniDic[tAniO.name] = frameO; + } + this.animationList = anilist; + this.animationDic = aniDic; + } + GraphicAnimation._temParam.length = 0; + } + parseByData(aniData) { + var rootNode, aniO; + rootNode = aniData.nodeRoot; + aniO = aniData.aniO; + delete aniData.nodeRoot; + delete aniData.aniO; + this._nodeDefaultProps = {}; + this._nodeGDic = {}; + if (this._nodeList) + this._nodeList.length = 0; + this._rootNode = rootNode; + this._parseNodeList(rootNode); + this._labels = null; + try { + this._calGraphicData(aniO); + } + catch (e) { + console.warn("parse animation fail:" + aniO.name + ",empty animation created"); + this._gList = []; + } + var frameO = aniData; + frameO.interval = 1000 / aniO["frameRate"]; + frameO.frames = this._gList; + frameO.labels = this._labels; + frameO.name = aniO.name; + return frameO; + } + setUpAniData(uiView) { + if (uiView.animations) { + var aniDic = {}; + var anilist = []; + var animations = uiView.animations; + var i, len = animations.length; + var tAniO; + for (i = 0; i < len; i++) { + tAniO = animations[i]; + if (!tAniO) + continue; + var frameO = {}; + frameO.name = tAniO.name; + frameO.aniO = tAniO; + frameO.nodeRoot = uiView; + anilist.push(frameO); + aniDic[tAniO.name] = frameO; + } + this.animationList = anilist; + this.animationDic = aniDic; + } + } + _clear() { + this.animationList = null; + this.animationDic = null; + this._gList = null; + this._nodeGDic = null; + } + static parseAnimationByData(animationObject) { + if (!GraphicAnimation._I) + GraphicAnimation._I = new GraphicAnimation(); + var rst; + rst = GraphicAnimation._I.parseByData(animationObject); + GraphicAnimation._I._clear(); + return rst; + } + static parseAnimationData(aniData) { + if (!GraphicAnimation._I) + GraphicAnimation._I = new GraphicAnimation(); + GraphicAnimation._I.setUpAniData(aniData); + var rst; + rst = {}; + rst.animationList = GraphicAnimation._I.animationList; + rst.animationDic = GraphicAnimation._I.animationDic; + GraphicAnimation._I._clear(); + return rst; + } + } + GraphicAnimation._drawTextureCmd = [["skin", null], ["x", 0], ["y", 0], ["width", -1], ["height", -1], ["pivotX", 0], ["pivotY", 0], ["scaleX", 1], ["scaleY", 1], ["rotation", 0], ["alpha", 1], ["skewX", 0], ["skewY", 0], ["anchorX", 0], ["anchorY", 0]]; + GraphicAnimation._temParam = []; + GraphicAnimation._tempMt = new Matrix(); + class GraphicNode { + constructor() { + this.alpha = 1; + } + } + + class Animation extends AnimationBase { + constructor() { + super(); + this._setControlNode(this); + } + destroy(destroyChild = true) { + this.stop(); + super.destroy(destroyChild); + this._frames = null; + this._labels = null; + } + play(start = 0, loop = true, name = "") { + if (name) + this._setFramesFromCache(name, true); + super.play(start, loop, name); + } + _setFramesFromCache(name, showWarn = false) { + if (this._url) + name = this._url + "#" + name; + if (name && Animation.framesMap[name]) { + var tAniO = Animation.framesMap[name]; + if (tAniO instanceof Array) { + this._frames = Animation.framesMap[name]; + this._count = this._frames.length; + } + else { + if (tAniO.nodeRoot) { + Animation.framesMap[name] = GraphicAnimation.parseAnimationByData(tAniO); + tAniO = Animation.framesMap[name]; + } + this._frames = tAniO.frames; + this._count = this._frames.length; + if (!this._frameRateChanged) + this._interval = tAniO.interval; + this._labels = this._copyLabels(tAniO.labels); + } + return true; + } + else { + if (showWarn) + console.log("ani not found:", name); + } + return false; + } + _copyLabels(labels) { + if (!labels) + return null; + var rst; + rst = {}; + var key; + for (key in labels) { + rst[key] = Utils.copyArray([], labels[key]); + } + return rst; + } + _frameLoop() { + if (this._visible && this._style.alpha > 0.01 && this._frames) { + super._frameLoop(); + } + } + _displayToIndex(value) { + if (this._frames) + this.graphics = this._frames[value]; + } + get frames() { + return this._frames; + } + set frames(value) { + this._frames = value; + if (value) { + this._count = value.length; + if (this._actionName) + this._setFramesFromCache(this._actionName, true); + this.index = this._index; + } + } + set source(value) { + if (value.indexOf(".ani") > -1) + this.loadAnimation(value); + else if (value.indexOf(".json") > -1 || value.indexOf("als") > -1 || value.indexOf("atlas") > -1) + this.loadAtlas(value); + else + this.loadImages(value.split(",")); + } + set autoAnimation(value) { + this.play(0, true, value); + } + set autoPlay(value) { + if (value) + this.play(); + else + this.stop(); + } + clear() { + super.clear(); + this.stop(); + this.graphics = null; + this._frames = null; + this._labels = null; + return this; + } + loadImages(urls, cacheName = "") { + this._url = ""; + if (!this._setFramesFromCache(cacheName)) { + this.frames = Animation.framesMap[cacheName] ? Animation.framesMap[cacheName] : Animation.createFrames(urls, cacheName); + } + return this; + } + loadAtlas(url, loaded = null, cacheName = "") { + this._url = ""; + var _this = this; + if (!_this._setFramesFromCache(cacheName)) { + function onLoaded(loadUrl) { + if (url === loadUrl) { + _this.frames = Animation.framesMap[cacheName] ? Animation.framesMap[cacheName] : Animation.createFrames(url, cacheName); + if (loaded) + loaded.run(); + } + } + if (Loader.getAtlas(url)) + onLoaded(url); + else + ILaya.loader.load(url, Handler.create(null, onLoaded, [url]), null, Loader.ATLAS); + } + return this; + } + loadAnimation(url, loaded = null, atlas = null) { + this._url = url; + var _this = this; + if (!this._actionName) + this._actionName = ""; + if (!_this._setFramesFromCache(this._actionName)) { + if (!atlas || Loader.getAtlas(atlas)) { + this._loadAnimationData(url, loaded, atlas); + } + else { + ILaya.loader.load(atlas, Handler.create(this, this._loadAnimationData, [url, loaded, atlas]), null, Loader.ATLAS); + } + } + else { + _this._setFramesFromCache(this._actionName, true); + this.index = 0; + if (loaded) + loaded.run(); + } + return this; + } + _loadAnimationData(url, loaded = null, atlas = null) { + if (atlas && !Loader.getAtlas(atlas)) { + console.warn("atlas load fail:" + atlas); + return; + } + var _this = this; + function onLoaded(loadUrl) { + if (!Loader.getRes(loadUrl)) { + if (Animation.framesMap[url + "#"]) { + _this._setFramesFromCache(_this._actionName, true); + _this.index = 0; + _this._resumePlay(); + if (loaded) + loaded.run(); + } + return; + } + if (url === loadUrl) { + var tAniO; + if (!Animation.framesMap[url + "#"]) { + var aniData = GraphicAnimation.parseAnimationData(Loader.getRes(url)); + if (!aniData) + return; + var aniList = aniData.animationList; + var i, len = aniList.length; + var defaultO; + for (i = 0; i < len; i++) { + tAniO = aniList[i]; + Animation.framesMap[url + "#" + tAniO.name] = tAniO; + if (!defaultO) + defaultO = tAniO; + } + if (defaultO) { + Animation.framesMap[url + "#"] = defaultO; + _this._setFramesFromCache(_this._actionName, true); + _this.index = 0; + } + _this._resumePlay(); + } + else { + _this._setFramesFromCache(_this._actionName, true); + _this.index = 0; + _this._resumePlay(); + } + if (loaded) + loaded.run(); + } + Loader.clearRes(url); + } + if (Loader.getRes(url)) + onLoaded(url); + else + ILaya.loader.load(url, Handler.create(null, onLoaded, [url]), null, Loader.JSON); + } + static createFrames(url, name) { + var arr; + if (typeof (url) == 'string') { + var atlas = Loader.getAtlas(url); + if (atlas && atlas.length) { + arr = []; + for (var i = 0, n = atlas.length; i < n; i++) { + var g = new Graphics(); + g.drawImage(Loader.getRes(atlas[i]), 0, 0); + arr.push(g); + } + } + } + else if (url instanceof Array) { + arr = []; + for (i = 0, n = url.length; i < n; i++) { + g = new Graphics(); + g.loadImage(url[i], 0, 0); + arr.push(g); + } + } + if (name) + Animation.framesMap[name] = arr; + return arr; + } + static clearCache(key) { + var cache = Animation.framesMap; + var val; + var key2 = key + "#"; + for (val in cache) { + if (val === key || val.indexOf(key2) === 0) { + delete Animation.framesMap[val]; + } + } + } + } + Animation.framesMap = {}; + ILaya.regClass(Animation); + ClassUtils.regClass("laya.display.Animation", Animation); + ClassUtils.regClass("Laya.Animation", Animation); + + class EffectAnimation extends FrameAnimation { + constructor() { + super(...arguments); + this._initData = {}; + } + set target(v) { + if (this._target) + this._target.off(EffectAnimation.EFFECT_BEGIN, this, this._onOtherBegin); + this._target = v; + if (this._target) + this._target.on(EffectAnimation.EFFECT_BEGIN, this, this._onOtherBegin); + this._addEvent(); + } + get target() { + return this._target; + } + _onOtherBegin(effect) { + if (effect === this) + return; + this.stop(); + } + set playEvent(event) { + this._playEvent = event; + if (!event) + return; + this._addEvent(); + } + _addEvent() { + if (!this._target || !this._playEvent) + return; + this._setControlNode(this._target); + this._target.on(this._playEvent, this, this._onPlayAction); + } + _onPlayAction() { + this.play(0, false); + } + play(start = 0, loop = true, name = "") { + if (!this._target) + return; + this._target.event(EffectAnimation.EFFECT_BEGIN, [this]); + this._recordInitData(); + super.play(start, loop, name); + } + _recordInitData() { + if (!this._aniKeys) + return; + var i, len; + len = this._aniKeys.length; + var key; + for (i = 0; i < len; i++) { + key = this._aniKeys[i]; + this._initData[key] = this._target[key]; + } + } + set effectClass(classStr) { + this._effectClass = ClassUtils.getClass(classStr); + if (this._effectClass) { + var uiData = this._effectClass["uiView"]; + if (uiData) { + var aniData = uiData["animations"]; + if (aniData && aniData[0]) { + var data = aniData[0]; + this._setUp({}, data); + if (data.nodes && data.nodes[0]) { + this._aniKeys = data.nodes[0].keys; + } + } + } + } + } + set effectData(uiData) { + if (uiData) { + var aniData = uiData["animations"]; + if (aniData && aniData[0]) { + var data = aniData[0]; + this._setUp({}, data); + if (data.nodes && data.nodes[0]) { + this._aniKeys = data.nodes[0].keys; + } + } + } + } + _displayToIndex(value) { + if (!this._animationData) + return; + if (value < 0) + value = 0; + if (value > this._count) + value = this._count; + var nodes = this._animationData.nodes, i, len = nodes.length; + len = len > 1 ? 1 : len; + for (i = 0; i < len; i++) { + this._displayNodeToFrame(nodes[i], value); + } + } + _displayNodeToFrame(node, frame, targetDic = null) { + if (!this._target) + return; + var target = this._target; + var frames = node.frames, key, propFrames, value; + var keys = node.keys, i, len = keys.length; + var secondFrames = node.secondFrames; + var tSecondFrame; + var easeFun; + var tKeyFrames; + var startFrame; + var endFrame; + for (i = 0; i < len; i++) { + key = keys[i]; + propFrames = frames[key]; + tSecondFrame = secondFrames[key]; + if (tSecondFrame == -1) { + value = this._initData[key]; + } + else { + if (frame < tSecondFrame) { + tKeyFrames = node.keyframes[key]; + startFrame = tKeyFrames[0]; + if (startFrame.tween) { + easeFun = Ease[startFrame.tweenMethod]; + if (easeFun == null) + easeFun = Ease.linearNone; + endFrame = tKeyFrames[1]; + value = easeFun(frame, this._initData[key], endFrame.value - this._initData[key], endFrame.index); + } + else { + value = this._initData[key]; + } + } + else { + if (propFrames.length > frame) + value = propFrames[frame]; + else + value = propFrames[propFrames.length - 1]; + } + } + target[key] = value; + } + } + _calculateKeyFrames(node) { + super._calculateKeyFrames(node); + var keyFrames = node.keyframes, key, tKeyFrames, target = node.target; + var secondFrames = {}; + node.secondFrames = secondFrames; + for (key in keyFrames) { + tKeyFrames = keyFrames[key]; + if (tKeyFrames.length <= 1) + secondFrames[key] = -1; + else + secondFrames[key] = tKeyFrames[1].index; + } + } + } + EffectAnimation.EFFECT_BEGIN = "effectbegin"; + ClassUtils.regClass("laya.display.EffectAnimation", EffectAnimation); + ClassUtils.regClass("Laya.EffectAnimation", EffectAnimation); + + class SceneLoader extends EventDispatcher { + constructor() { + super(); + this._completeHandler = new Handler(this, this.onOneLoadComplete); + this.reset(); + } + reset() { + this._toLoadList = []; + this._isLoading = false; + this.totalCount = 0; + } + get leftCount() { + if (this._isLoading) + return this._toLoadList.length + 1; + return this._toLoadList.length; + } + get loadedCount() { + return this.totalCount - this.leftCount; + } + load(url, is3D = false, ifCheck = true) { + if (url instanceof Array) { + var i, len; + len = url.length; + for (i = 0; i < len; i++) { + this._addToLoadList(url[i], is3D); + } + } + else { + this._addToLoadList(url, is3D); + } + if (ifCheck) + this._checkNext(); + } + _addToLoadList(url, is3D = false) { + if (this._toLoadList.indexOf(url) >= 0) + return; + if (Loader.getRes(url)) + return; + if (is3D) { + this._toLoadList.push({ url: url }); + } + else + this._toLoadList.push(url); + this.totalCount++; + } + _checkNext() { + if (!this._isLoading) { + if (this._toLoadList.length == 0) { + this.event(Event.COMPLETE); + return; + } + var tItem; + tItem = this._toLoadList.pop(); + if (typeof (tItem) == 'string') { + this.loadOne(tItem); + } + else { + this.loadOne(tItem.url, true); + } + } + } + loadOne(url, is3D = false) { + this._curUrl = url; + var type = Utils.getFileExtension(this._curUrl); + if (is3D) { + ILaya.loader.create(url, this._completeHandler); + } + else if (SceneLoader.LoadableExtensions[type]) { + ILaya.loader.load(url, this._completeHandler, null, SceneLoader.LoadableExtensions[type]); + } + else if (url != AtlasInfoManager.getFileLoadPath(url) || SceneLoader.No3dLoadTypes[type] || !LoaderManager.createMap[type]) { + ILaya.loader.load(url, this._completeHandler); + } + else { + ILaya.loader.create(url, this._completeHandler); + } + } + onOneLoadComplete() { + this._isLoading = false; + if (!Loader.getRes(this._curUrl)) { + console.log("Fail to load:", this._curUrl); + } + var type = Utils.getFileExtension(this._curUrl); + if (SceneLoader.LoadableExtensions[type]) { + var dataO; + dataO = Loader.getRes(this._curUrl); + if (dataO && (dataO instanceof Prefab)) { + dataO = dataO.json; + } + if (dataO) { + if (dataO.loadList) { + this.load(dataO.loadList, false, false); + } + if (dataO.loadList3D) { + this.load(dataO.loadList3D, true, false); + } + } + } + if (type == "sk") { + this.load(this._curUrl.replace(".sk", ".png"), false, false); + } + this.event(Event.PROGRESS, this.getProgress()); + this._checkNext(); + } + getProgress() { + return this.loadedCount / this.totalCount; + } + } + SceneLoader.LoadableExtensions = { "scene": Loader.JSON, "scene3d": Loader.JSON, "ani": Loader.JSON, "ui": Loader.JSON, "prefab": Loader.PREFAB }; + SceneLoader.No3dLoadTypes = { "png": true, "jpg": true, "txt": true }; + + class Scene extends Sprite { + constructor(createChildren = true) { + super(); + this.autoDestroyAtClosed = false; + this.url = null; + this._viewCreated = false; + this._idMap = null; + this._$componentType = "Scene"; + Scene.unDestroyedScenes.push(this); + this._scene = this; + if (createChildren) + this.createChildren(); + } + createChildren() { + } + static setUIMap(url) { + let uimap = ILaya.loader.getRes(url); + if (uimap) { + for (let key in uimap) { + ILaya.Loader.loadedMap[URL.formatURL(key + ".scene")] = uimap[key]; + } + } + else { + throw "请提前加载uimap的json,再使用该接口设置!"; + } + } + loadScene(path) { + var url = path.indexOf(".") > -1 ? path : path + ".scene"; + var view = ILaya.loader.getRes(url); + if (view) { + this.createView(view); + } + else { + this._setBit(Const.NOT_READY, true); + ILaya.loader.resetProgress(); + var loader = new SceneLoader(); + loader.on(Event.COMPLETE, this, this._onSceneLoaded, [url]); + loader.load(url); + } + } + _onSceneLoaded(url) { + this.createView(ILaya.Loader.getRes(url)); + } + createView(view) { + if (view && !this._viewCreated) { + this._viewCreated = true; + SceneUtils.createByData(this, view); + } + } + getNodeByID(id) { + if (this._idMap) + return this._idMap[id]; + return null; + } + open(closeOther = true, param = null) { + if (closeOther) + Scene.closeAll(); + Scene.root.addChild(this); + this.onOpened(param); + } + onOpened(param) { + } + close(type = null) { + this.onClosed(type); + if (this.autoDestroyAtClosed) + this.destroy(); + else + this.removeSelf(); + } + onClosed(type = null) { + } + destroy(destroyChild = true) { + this._idMap = null; + super.destroy(destroyChild); + var list = Scene.unDestroyedScenes; + for (var i = list.length - 1; i > -1; i--) { + if (list[i] === this) { + list.splice(i, 1); + return; + } + } + } + set scaleX(value) { + if (super.get_scaleX() == value) + return; + super.set_scaleX(value); + this.event(Event.RESIZE); + } + get scaleX() { + return super.scaleX; + } + set scaleY(value) { + if (super.get_scaleY() == value) + return; + super.set_scaleY(value); + this.event(Event.RESIZE); + } + get scaleY() { + return super.scaleY; + } + get width() { + if (this._width) + return this._width; + var max = 0; + for (var i = this.numChildren - 1; i > -1; i--) { + var comp = this.getChildAt(i); + if (comp._visible) { + max = Math.max(comp._x + comp.width * comp.scaleX, max); + } + } + return max; + } + set width(value) { + if (super.get_width() == value) + return; + super.set_width(value); + this.callLater(this._sizeChanged); + } + get height() { + if (this._height) + return this._height; + var max = 0; + for (var i = this.numChildren - 1; i > -1; i--) { + var comp = this.getChildAt(i); + if (comp._visible) { + max = Math.max(comp._y + comp.height * comp.scaleY, max); + } + } + return max; + } + set height(value) { + if (super.get_height() == value) + return; + super.set_height(value); + this.callLater(this._sizeChanged); + } + _sizeChanged() { + this.event(Event.RESIZE); + } + static get root() { + if (!Scene._root) { + Scene._root = ILaya.stage.addChild(new Sprite()); + Scene._root.name = "root"; + ILaya.stage.on("resize", null, () => { + Scene._root.size(ILaya.stage.width, ILaya.stage.height); + Scene._root.event(Event.RESIZE); + }); + Scene._root.size(ILaya.stage.width, ILaya.stage.height); + Scene._root.event(Event.RESIZE); + } + return Scene._root; + } + get timer() { + return this._timer || ILaya.timer; + } + set timer(value) { + this._timer = value; + } + static load(url, complete = null, progress = null) { + ILaya.loader.resetProgress(); + var loader = new SceneLoader(); + loader.on(Event.PROGRESS, null, onProgress); + loader.once(Event.COMPLETE, null, create); + loader.load(url); + function onProgress(value) { + if (Scene._loadPage) + Scene._loadPage.event("progress", value); + progress && progress.runWith(value); + } + function create() { + loader.off(Event.PROGRESS, null, onProgress); + var obj = ILaya.Loader.getRes(url); + if (!obj) + throw "Can not find scene:" + url; + if (!obj.props) + throw "Scene data is error:" + url; + var runtime = obj.props.runtime ? obj.props.runtime : obj.type; + var clas = ILaya.ClassUtils.getClass(runtime); + if (obj.props.renderType == "instance") { + var scene = clas.instance || (clas.instance = new clas()); + } + else { + scene = new clas(); + } + if (scene && scene instanceof Node) { + scene.url = url; + if (scene._viewCreated) { + complete && complete.runWith(scene); + } + else { + scene.on("onViewCreated", null, function () { + complete && complete.runWith(scene); + }); + scene.createView(obj); + } + Scene.hideLoadingPage(); + } + else { + throw "Can not find scene:" + runtime; + } + } + } + static open(url, closeOther = true, param = null, complete = null, progress = null) { + if (param instanceof Handler) { + var temp = complete; + complete = param; + param = temp; + } + Scene.showLoadingPage(); + Scene.load(url, Handler.create(null, this._onSceneLoaded, [closeOther, complete, param]), progress); + } + static _onSceneLoaded(closeOther, complete, param, scene) { + scene.open(closeOther, param); + if (complete) + complete.runWith(scene); + } + static close(url, name = "") { + var flag = false; + var list = Scene.unDestroyedScenes; + for (var i = 0, n = list.length; i < n; i++) { + var scene = list[i]; + if (scene && scene.parent && scene.url === url && scene.name == name) { + scene.close(); + flag = true; + } + } + return flag; + } + static closeAll() { + var root = Scene.root; + for (var i = 0, n = root.numChildren; i < n; i++) { + var scene = root.getChildAt(0); + if (scene instanceof Scene) + scene.close(); + else + scene.removeSelf(); + } + } + static destroy(url, name = "") { + var flag = false; + var list = [].concat(Scene.unDestroyedScenes); + for (var i = 0, n = list.length; i < n; i++) { + var scene = list[i]; + if (scene.url === url && scene.name == name && !scene.destroyed) { + scene.destroy(); + flag = true; + } + } + return flag; + } + static gc() { + Resource.destroyUnusedResources(); + } + static setLoadingPage(loadPage) { + if (Scene._loadPage != loadPage) { + Scene._loadPage = loadPage; + } + } + static showLoadingPage(param = null, delay = 500) { + if (Scene._loadPage) { + ILaya.systemTimer.clear(null, Scene._showLoading); + ILaya.systemTimer.clear(null, Scene._hideLoading); + ILaya.systemTimer.once(delay, null, Scene._showLoading, [param], false); + } + } + static _showLoading(param) { + ILaya.stage.addChild(Scene._loadPage); + Scene._loadPage.onOpened(param); + } + static _hideLoading() { + Scene._loadPage.close(); + } + static hideLoadingPage(delay = 500) { + if (Scene._loadPage) { + ILaya.systemTimer.clear(null, Scene._showLoading); + ILaya.systemTimer.clear(null, Scene._hideLoading); + ILaya.systemTimer.once(delay, null, Scene._hideLoading); + } + } + } + Scene.unDestroyedScenes = []; + ILaya.regClass(Scene); + ClassUtils.regClass("laya.display.Scene", Scene); + ClassUtils.regClass("Laya.Scene", Scene); + + class DrawParticleCmd { + static create(_temp) { + var cmd = Pool.getItemByClass("DrawParticleCmd", DrawParticleCmd); + cmd._templ = _temp; + return cmd; + } + recover() { + this._templ = null; + Pool.recover("DrawParticleCmd", this); + } + run(context, gx, gy) { + context.drawParticle(gx, gy, this._templ); + } + get cmdID() { + return DrawParticleCmd.ID; + } + } + DrawParticleCmd.ID = "DrawParticleCmd"; + + class FilterSetterBase { + constructor() { + } + paramChanged() { + Laya.systemTimer.callLater(this, this.buildFilter); + } + buildFilter() { + if (this._target) { + this.addFilter(this._target); + } + } + addFilter(sprite) { + if (!sprite) + return; + if (!sprite.filters) { + sprite.filters = [this._filter]; + } + else { + var preFilters; + preFilters = sprite.filters; + if (preFilters.indexOf(this._filter) < 0) { + preFilters.push(this._filter); + sprite.filters = Utils.copyArray([], preFilters); + } + } + } + removeFilter(sprite) { + if (!sprite) + return; + sprite.filters = null; + } + set target(value) { + if (this._target != value) { + this._target = value; + this.paramChanged(); + } + } + } + + class BlurFilterGLRender { + render(rt, ctx, width, height, filter) { + var shaderValue = Value2D.create(ShaderDefines2D.TEXTURE2D, 0); + this.setShaderInfo(shaderValue, filter, rt.width, rt.height); + ctx.drawTarget(rt, 0, 0, width, height, Matrix.EMPTY.identity(), shaderValue); + } + setShaderInfo(shader, filter, w, h) { + shader.defines.add(Filter.BLUR); + var sv = shader; + BlurFilterGLRender.blurinfo[0] = w; + BlurFilterGLRender.blurinfo[1] = h; + sv.blurInfo = BlurFilterGLRender.blurinfo; + var sigma = filter.strength / 3.0; + var sigma2 = sigma * sigma; + filter.strength_sig2_2sig2_gauss1[0] = filter.strength; + filter.strength_sig2_2sig2_gauss1[1] = sigma2; + filter.strength_sig2_2sig2_gauss1[2] = 2.0 * sigma2; + filter.strength_sig2_2sig2_gauss1[3] = 1.0 / (2.0 * Math.PI * sigma2); + sv.strength_sig2_2sig2_gauss1 = filter.strength_sig2_2sig2_gauss1; + } + } + BlurFilterGLRender.blurinfo = new Array(2); + + class BlurFilter extends Filter { + constructor(strength = 4) { + super(); + this.strength_sig2_2sig2_gauss1 = []; + this.strength = strength; + this._glRender = new BlurFilterGLRender(); + } + get type() { + return Filter.BLUR; + } + getStrenth_sig2_2sig2_native() { + if (!this.strength_sig2_native) { + this.strength_sig2_native = new Float32Array(4); + } + var sigma = this.strength / 3.0; + var sigma2 = sigma * sigma; + this.strength_sig2_native[0] = this.strength; + this.strength_sig2_native[1] = sigma2; + this.strength_sig2_native[2] = 2.0 * sigma2; + this.strength_sig2_native[3] = 1.0 / (2.0 * Math.PI * sigma2); + return this.strength_sig2_native; + } + } + + class BlurFilterSetter extends FilterSetterBase { + constructor() { + super(); + this._strength = 4; + this._filter = new BlurFilter(this.strength); + } + buildFilter() { + this._filter = new BlurFilter(this.strength); + super.buildFilter(); + } + get strength() { + return this._strength; + } + set strength(value) { + this._strength = value; + } + } + ClassUtils.regClass("laya.effect.BlurFilterSetter", BlurFilterSetter); + ClassUtils.regClass("Laya.BlurFilterSetter", BlurFilterSetter); + + class ButtonEffect { + constructor() { + this._curState = 0; + this.effectScale = 1.5; + this.tweenTime = 300; + } + set target(tar) { + this._tar = tar; + tar.on(Event.MOUSE_DOWN, this, this.toChangedState); + tar.on(Event.MOUSE_UP, this, this.toInitState); + tar.on(Event.MOUSE_OUT, this, this.toInitState); + } + toChangedState() { + this._curState = 1; + if (this._curTween) + Tween.clear(this._curTween); + this._curTween = Tween.to(this._tar, { scaleX: this.effectScale, scaleY: this.effectScale }, this.tweenTime, Ease[this.effectEase], Handler.create(this, this.tweenComplete)); + } + toInitState() { + if (this._curState == 2) + return; + if (this._curTween) + Tween.clear(this._curTween); + this._curState = 2; + this._curTween = Tween.to(this._tar, { scaleX: 1, scaleY: 1 }, this.tweenTime, Ease[this.backEase], Handler.create(this, this.tweenComplete)); + } + tweenComplete() { + this._curState = 0; + this._curTween = null; + } + } + + class ColorFilterSetter extends FilterSetterBase { + constructor() { + super(); + this._brightness = 0; + this._contrast = 0; + this._saturation = 0; + this._hue = 0; + this._red = 0; + this._green = 0; + this._blue = 0; + this._alpha = 0; + this._filter = new ColorFilter(); + } + buildFilter() { + this._filter.reset(); + this._filter.color(this.red, this.green, this.blue, this.alpha); + this._filter.adjustHue(this.hue); + this._filter.adjustContrast(this.contrast); + this._filter.adjustBrightness(this.brightness); + this._filter.adjustSaturation(this.saturation); + super.buildFilter(); + } + get brightness() { + return this._brightness; + } + set brightness(value) { + this._brightness = value; + this.paramChanged(); + } + get contrast() { + return this._contrast; + } + set contrast(value) { + this._contrast = value; + this.paramChanged(); + } + get saturation() { + return this._saturation; + } + set saturation(value) { + this._saturation = value; + this.paramChanged(); + } + get hue() { + return this._hue; + } + set hue(value) { + this._hue = value; + this.paramChanged(); + } + get red() { + return this._red; + } + set red(value) { + this._red = value; + this.paramChanged(); + } + get green() { + return this._green; + } + set green(value) { + this._green = value; + this.paramChanged(); + } + get blue() { + return this._blue; + } + set blue(value) { + this._blue = value; + this.paramChanged(); + } + get color() { + return this._color; + } + set color(value) { + this._color = value; + var colorO; + colorO = ColorUtils.create(value); + this._red = colorO.arrColor[0] * 255; + this._green = colorO.arrColor[1] * 255; + this._blue = colorO.arrColor[2] * 255; + this.paramChanged(); + } + get alpha() { + return this._alpha; + } + set alpha(value) { + this._alpha = value; + this.paramChanged(); + } + } + ClassUtils.regClass("laya.effect.ColorFilterSetter", ColorFilterSetter); + ClassUtils.regClass("Laya.ColorFilterSetter", ColorFilterSetter); + + class EffectBase extends Component { + constructor() { + super(...arguments); + this.duration = 1000; + this.delay = 0; + this.repeat = 0; + this.autoDestroyAtComplete = true; + } + _onAwake() { + this.target = this.target || this.owner; + if (this.autoDestroyAtComplete) + this._comlete = Handler.create(this.target, this.target.destroy, null, false); + if (this.eventName) + this.owner.on(this.eventName, this, this._exeTween); + else + this._exeTween(); + } + _exeTween() { + this._tween = this._doTween(); + this._tween.repeat = this.repeat; + } + _doTween() { + return null; + } + onReset() { + this.duration = 1000; + this.delay = 0; + this.repeat = 0; + this.ease = null; + this.target = null; + if (this.eventName) { + this.owner.off(this.eventName, this, this._exeTween); + this.eventName = null; + } + if (this._comlete) { + this._comlete.recover(); + this._comlete = null; + } + if (this._tween) { + this._tween.clear(); + this._tween = null; + } + } + } + + class FadeIn extends EffectBase { + _doTween() { + this.target.alpha = 0; + return Tween.to(this.target, { alpha: 1 }, this.duration, Ease[this.ease], this._comlete, this.delay); + } + } + + class FadeOut extends EffectBase { + _doTween() { + this.target.alpha = 1; + return Tween.to(this.target, { alpha: 0 }, this.duration, Ease[this.ease], this._comlete, this.delay); + } + } + + class GlowFilterGLRender { + setShaderInfo(shader, w, h, data) { + shader.defines.add(data.type); + var sv = shader; + sv.u_blurInfo1 = data._sv_blurInfo1; + var info2 = data._sv_blurInfo2; + info2[0] = w; + info2[1] = h; + sv.u_blurInfo2 = info2; + sv.u_color = data.getColor(); + } + render(rt, ctx, width, height, filter) { + var w = width, h = height; + var svBlur = Value2D.create(ShaderDefines2D.TEXTURE2D, 0); + this.setShaderInfo(svBlur, w, h, filter); + var svCP = Value2D.create(ShaderDefines2D.TEXTURE2D, 0); + var matI = Matrix.TEMP.identity(); + ctx.drawTarget(rt, 0, 0, w, h, matI, svBlur); + ctx.drawTarget(rt, 0, 0, w, h, matI, svCP); + } + } + + class GlowFilter extends Filter { + constructor(color, blur = 4, offX = 6, offY = 6) { + super(); + this._elements = new Float32Array(9); + this._sv_blurInfo1 = new Array(4); + this._sv_blurInfo2 = [0, 0, 1, 0]; + this._color = new ColorUtils(color); + this.blur = Math.min(blur, 20); + this.offX = offX; + this.offY = offY; + this._sv_blurInfo1[0] = this._sv_blurInfo1[1] = this.blur; + this._sv_blurInfo1[2] = offX; + this._sv_blurInfo1[3] = -offY; + this._glRender = new GlowFilterGLRender(); + } + get type() { + return BlurFilter.GLOW; + } + get offY() { + return this._elements[6]; + } + set offY(value) { + this._elements[6] = value; + this._sv_blurInfo1[3] = -value; + } + get offX() { + return this._elements[5]; + } + set offX(value) { + this._elements[5] = value; + this._sv_blurInfo1[2] = value; + } + getColor() { + return this._color.arrColor; + } + get blur() { + return this._elements[4]; + } + set blur(value) { + this._elements[4] = value; + this._sv_blurInfo1[0] = this._sv_blurInfo1[1] = value; + } + getColorNative() { + if (!this._color_native) { + this._color_native = new Float32Array(4); + } + var color = this.getColor(); + this._color_native[0] = color[0]; + this._color_native[1] = color[1]; + this._color_native[2] = color[2]; + this._color_native[3] = color[3]; + return this._color_native; + } + getBlurInfo1Native() { + if (!this._blurInof1_native) { + this._blurInof1_native = new Float32Array(4); + } + this._blurInof1_native[0] = this._blurInof1_native[1] = this.blur; + this._blurInof1_native[2] = this.offX; + this._blurInof1_native[3] = this.offY; + return this._blurInof1_native; + } + getBlurInfo2Native() { + if (!this._blurInof2_native) { + this._blurInof2_native = new Float32Array(4); + } + this._blurInof2_native[2] = 1; + return this._blurInof2_native; + } + } + + class GlowFilterSetter extends FilterSetterBase { + constructor() { + super(); + this._color = "#ff0000"; + this._blur = 4; + this._offX = 6; + this._offY = 6; + this._filter = new GlowFilter(this._color); + } + buildFilter() { + this._filter = new GlowFilter(this.color, this.blur, this.offX, this.offY); + super.buildFilter(); + } + get color() { + return this._color; + } + set color(value) { + this._color = value; + this.paramChanged(); + } + get blur() { + return this._blur; + } + set blur(value) { + this._blur = value; + this.paramChanged(); + } + get offX() { + return this._offX; + } + set offX(value) { + this._offX = value; + this.paramChanged(); + } + get offY() { + return this._offY; + } + set offY(value) { + this._offY = value; + this.paramChanged(); + } + } + ClassUtils.regClass("laya.effect.GlowFilterSetter", GlowFilterSetter); + ClassUtils.regClass("Laya.GlowFilterSetter", GlowFilterSetter); + + class KeyLocation { + } + KeyLocation.STANDARD = 0; + KeyLocation.LEFT = 1; + KeyLocation.RIGHT = 2; + KeyLocation.NUM_PAD = 3; + + class Keyboard { + } + Keyboard.NUMBER_0 = 48; + Keyboard.NUMBER_1 = 49; + Keyboard.NUMBER_2 = 50; + Keyboard.NUMBER_3 = 51; + Keyboard.NUMBER_4 = 52; + Keyboard.NUMBER_5 = 53; + Keyboard.NUMBER_6 = 54; + Keyboard.NUMBER_7 = 55; + Keyboard.NUMBER_8 = 56; + Keyboard.NUMBER_9 = 57; + Keyboard.A = 65; + Keyboard.B = 66; + Keyboard.C = 67; + Keyboard.D = 68; + Keyboard.E = 69; + Keyboard.F = 70; + Keyboard.G = 71; + Keyboard.H = 72; + Keyboard.I = 73; + Keyboard.J = 74; + Keyboard.K = 75; + Keyboard.L = 76; + Keyboard.M = 77; + Keyboard.N = 78; + Keyboard.O = 79; + Keyboard.P = 80; + Keyboard.Q = 81; + Keyboard.R = 82; + Keyboard.S = 83; + Keyboard.T = 84; + Keyboard.U = 85; + Keyboard.V = 86; + Keyboard.W = 87; + Keyboard.X = 88; + Keyboard.Y = 89; + Keyboard.Z = 90; + Keyboard.F1 = 112; + Keyboard.F2 = 113; + Keyboard.F3 = 114; + Keyboard.F4 = 115; + Keyboard.F5 = 116; + Keyboard.F6 = 117; + Keyboard.F7 = 118; + Keyboard.F8 = 119; + Keyboard.F9 = 120; + Keyboard.F10 = 121; + Keyboard.F11 = 122; + Keyboard.F12 = 123; + Keyboard.F13 = 124; + Keyboard.F14 = 125; + Keyboard.F15 = 126; + Keyboard.NUMPAD = 21; + Keyboard.NUMPAD_0 = 96; + Keyboard.NUMPAD_1 = 97; + Keyboard.NUMPAD_2 = 98; + Keyboard.NUMPAD_3 = 99; + Keyboard.NUMPAD_4 = 100; + Keyboard.NUMPAD_5 = 101; + Keyboard.NUMPAD_6 = 102; + Keyboard.NUMPAD_7 = 103; + Keyboard.NUMPAD_8 = 104; + Keyboard.NUMPAD_9 = 105; + Keyboard.NUMPAD_ADD = 107; + Keyboard.NUMPAD_DECIMAL = 110; + Keyboard.NUMPAD_DIVIDE = 111; + Keyboard.NUMPAD_ENTER = 108; + Keyboard.NUMPAD_MULTIPLY = 106; + Keyboard.NUMPAD_SUBTRACT = 109; + Keyboard.SEMICOLON = 186; + Keyboard.EQUAL = 187; + Keyboard.COMMA = 188; + Keyboard.MINUS = 189; + Keyboard.PERIOD = 190; + Keyboard.SLASH = 191; + Keyboard.BACKQUOTE = 192; + Keyboard.LEFTBRACKET = 219; + Keyboard.BACKSLASH = 220; + Keyboard.RIGHTBRACKET = 221; + Keyboard.QUOTE = 222; + Keyboard.ALTERNATE = 18; + Keyboard.BACKSPACE = 8; + Keyboard.CAPS_LOCK = 20; + Keyboard.COMMAND = 15; + Keyboard.CONTROL = 17; + Keyboard.DELETE = 46; + Keyboard.ENTER = 13; + Keyboard.ESCAPE = 27; + Keyboard.PAGE_UP = 33; + Keyboard.PAGE_DOWN = 34; + Keyboard.END = 35; + Keyboard.HOME = 36; + Keyboard.LEFT = 37; + Keyboard.UP = 38; + Keyboard.RIGHT = 39; + Keyboard.DOWN = 40; + Keyboard.SHIFT = 16; + Keyboard.SPACE = 32; + Keyboard.TAB = 9; + Keyboard.INSERT = 45; + + class CommandEncoder { + constructor(layagl, reserveSize, adjustSize, isSyncToRenderThread) { + this._idata = []; + } + getArrayData() { + return this._idata; + } + getPtrID() { + return 0; + } + beginEncoding() { + } + endEncoding() { + } + clearEncoding() { + this._idata.length = 0; + } + getCount() { + return this._idata.length; + } + add_ShaderValue(o) { + this._idata.push(o); + } + addShaderUniform(one) { + this.add_ShaderValue(one); + } + } + + class LayaGLRunner { + static uploadShaderUniforms(layaGL, commandEncoder, shaderData, uploadUnTexture) { + var data = shaderData._data; + var shaderUniform = commandEncoder.getArrayData(); + var shaderCall = 0; + for (var i = 0, n = shaderUniform.length; i < n; i++) { + var one = shaderUniform[i]; + if (uploadUnTexture || one.textureID !== -1) { + var value = data[one.dataOffset]; + if (value != null) + shaderCall += one.fun.call(one.caller, one, value); + } + } + return shaderCall; + } + static uploadCustomUniform(layaGL, custom, index, data) { + var shaderCall = 0; + var one = custom[index]; + if (one && data != null) + shaderCall += one.fun.call(one.caller, one, data); + return shaderCall; + } + static uploadShaderUniformsForNative(layaGL, commandEncoder, shaderData) { + var nType = LayaGL.UPLOAD_SHADER_UNIFORM_TYPE_ID; + if (shaderData._runtimeCopyValues.length > 0) { + nType = LayaGL.UPLOAD_SHADER_UNIFORM_TYPE_DATA; + } + var data = shaderData._data; + return LayaGL.instance.uploadShaderUniforms(commandEncoder, data, nType); + } + } + + class QuickTestTool { + constructor() { + } + static getMCDName(type) { + return QuickTestTool._typeToNameDic[type]; + } + static showRenderTypeInfo(type, force = false) { + if (!force && QuickTestTool.showedDic[type]) + return; + QuickTestTool.showedDic[type] = true; + if (!QuickTestTool._rendertypeToStrDic[type]) { + var arr = []; + var tType; + tType = 1; + while (tType <= type) { + if (tType & type) { + arr.push(QuickTestTool.getMCDName(tType & type)); + } + tType = tType << 1; + } + QuickTestTool._rendertypeToStrDic[type] = arr.join(","); + } + console.log("cmd:", QuickTestTool._rendertypeToStrDic[type]); + } + static __init__() { + QuickTestTool._typeToNameDic[SpriteConst.ALPHA] = "ALPHA"; + QuickTestTool._typeToNameDic[SpriteConst.TRANSFORM] = "TRANSFORM"; + QuickTestTool._typeToNameDic[SpriteConst.TEXTURE] = "TEXTURE"; + QuickTestTool._typeToNameDic[SpriteConst.GRAPHICS] = "GRAPHICS"; + QuickTestTool._typeToNameDic[SpriteConst.ONECHILD] = "ONECHILD"; + QuickTestTool._typeToNameDic[SpriteConst.CHILDS] = "CHILDS"; + QuickTestTool._typeToNameDic[SpriteConst.TRANSFORM | SpriteConst.ALPHA] = "TRANSFORM|ALPHA"; + QuickTestTool._typeToNameDic[SpriteConst.CANVAS] = "CANVAS"; + QuickTestTool._typeToNameDic[SpriteConst.BLEND] = "BLEND"; + QuickTestTool._typeToNameDic[SpriteConst.FILTERS] = "FILTERS"; + QuickTestTool._typeToNameDic[SpriteConst.MASK] = "MASK"; + QuickTestTool._typeToNameDic[SpriteConst.CLIP] = "CLIP"; + QuickTestTool._typeToNameDic[SpriteConst.LAYAGL3D] = "LAYAGL3D"; + } + render(context, x, y) { + QuickTestTool._addType(this._renderType); + QuickTestTool.showRenderTypeInfo(this._renderType); + RenderSprite.renders[this._renderType]._fun(this, context, x + this._x, y + this._y); + this._repaint = 0; + } + _stageRender(context, x, y) { + QuickTestTool._countStart(); + QuickTestTool._PreStageRender.call(ILaya.stage, context, x, y); + QuickTestTool._countEnd(); + } + static _countStart() { + var key; + for (key in QuickTestTool._countDic) { + QuickTestTool._countDic[key] = 0; + } + } + static _countEnd() { + QuickTestTool._i++; + if (QuickTestTool._i > 60) { + QuickTestTool.showCountInfo(); + QuickTestTool._i = 0; + } + } + static _addType(type) { + if (!QuickTestTool._countDic[type]) { + QuickTestTool._countDic[type] = 1; + } + else { + QuickTestTool._countDic[type] += 1; + } + } + static showCountInfo() { + console.log("==================="); + var key; + for (key in QuickTestTool._countDic) { + console.log("count:" + QuickTestTool._countDic[key]); + QuickTestTool.showRenderTypeInfo(key, true); + } + } + static enableQuickTest() { + QuickTestTool.__init__(); + Sprite["prototype"]["render"] = QuickTestTool["prototype"]["render"]; + QuickTestTool._PreStageRender = Stage["prototype"]["render"]; + Stage["prototype"]["render"] = QuickTestTool["prototype"]["_stageRender"]; + } + } + QuickTestTool.showedDic = {}; + QuickTestTool._rendertypeToStrDic = {}; + QuickTestTool._typeToNameDic = {}; + QuickTestTool._countDic = {}; + QuickTestTool._i = 0; + + class Sound extends EventDispatcher { + load(url) { + } + play(startTime = 0, loops = 0) { + return null; + } + get duration() { + return 0; + } + dispose() { + } + } + + class SoundNode extends Sprite { + constructor() { + super(); + this.visible = false; + this.on(Event.ADDED, this, this._onParentChange); + this.on(Event.REMOVED, this, this._onParentChange); + } + _onParentChange() { + this.target = this.parent; + } + play(loops = 1, complete = null) { + if (isNaN(loops)) { + loops = 1; + } + if (!this.url) + return; + this.stop(); + this._channel = SoundManager.playSound(this.url, loops, complete); + } + stop() { + if (this._channel && !this._channel.isStopped) { + this._channel.stop(); + } + this._channel = null; + } + _setPlayAction(tar, event, action, add = true) { + if (!this[action]) + return; + if (!tar) + return; + if (add) { + tar.on(event, this, this[action]); + } + else { + tar.off(event, this, this[action]); + } + } + _setPlayActions(tar, events, action, add = true) { + if (!tar) + return; + if (!events) + return; + var eventArr = events.split(","); + var i, len; + len = eventArr.length; + for (i = 0; i < len; i++) { + this._setPlayAction(tar, eventArr[i], action, add); + } + } + set playEvent(events) { + this._playEvents = events; + if (!events) + return; + if (this._tar) { + this._setPlayActions(this._tar, events, "play"); + } + } + set target(tar) { + if (this._tar) { + this._setPlayActions(this._tar, this._playEvents, "play", false); + this._setPlayActions(this._tar, this._stopEvents, "stop", false); + } + this._tar = tar; + if (this._tar) { + this._setPlayActions(this._tar, this._playEvents, "play", true); + this._setPlayActions(this._tar, this._stopEvents, "stop", true); + } + } + set stopEvent(events) { + this._stopEvents = events; + if (!events) + return; + if (this._tar) { + this._setPlayActions(this._tar, events, "stop"); + } + } + } + ClassUtils.regClass("laya.media.SoundNode", SoundNode); + ClassUtils.regClass("Laya.SoundNode", SoundNode); + + class ResourceVersion { + static enable(manifestFile, callback, type = 2) { + ResourceVersion.type = type; + ILaya.loader.load(manifestFile, Handler.create(null, ResourceVersion.onManifestLoaded, [callback]), null, Loader.JSON); + } + static onManifestLoaded(callback, data) { + ResourceVersion.manifest = data; + URL.customFormat = ResourceVersion.addVersionPrefix; + callback.run(); + if (!data) { + console.warn("资源版本清单文件不存在,不使用资源版本管理。忽略ERR_FILE_NOT_FOUND错误。"); + } + } + static addVersionPrefix(originURL) { + if (ResourceVersion.manifest && ResourceVersion.manifest[originURL]) { + if (ResourceVersion.type == ResourceVersion.FILENAME_VERSION) + return ResourceVersion.manifest[originURL]; + return ResourceVersion.manifest[originURL] + "/" + originURL; + } + return originURL; + } + } + ResourceVersion.FOLDER_VERSION = 1; + ResourceVersion.FILENAME_VERSION = 2; + ResourceVersion.type = ResourceVersion.FOLDER_VERSION; + + class Socket extends EventDispatcher { + constructor(host = null, port = 0, byteClass = null, protocols = null) { + super(); + this.disableInput = false; + this.protocols = []; + this._byteClass = byteClass ? byteClass : Byte; + this.protocols = protocols; + this.endian = Socket.BIG_ENDIAN; + if (host && port > 0 && port < 65535) + this.connect(host, port); + } + get input() { + return this._input; + } + get output() { + return this._output; + } + get connected() { + return this._connected; + } + get endian() { + return this._endian; + } + set endian(value) { + this._endian = value; + if (this._input != null) + this._input.endian = value; + if (this._output != null) + this._output.endian = value; + } + connect(host, port) { + var url = "ws://" + host + ":" + port; + this.connectByUrl(url); + } + connectByUrl(url) { + if (this._socket != null) + this.close(); + this._socket && this.cleanSocket(); + if (!this.protocols || this.protocols.length == 0) { + this._socket = new Browser.window.WebSocket(url); + } + else { + this._socket = new Browser.window.WebSocket(url, this.protocols); + } + this._socket.binaryType = "arraybuffer"; + this._output = new this._byteClass(); + this._output.endian = this.endian; + this._input = new this._byteClass(); + this._input.endian = this.endian; + this._addInputPosition = 0; + this._socket.onopen = (e) => { + this._onOpen(e); + }; + this._socket.onmessage = (msg) => { + this._onMessage(msg); + }; + this._socket.onclose = (e) => { + this._onClose(e); + }; + this._socket.onerror = (e) => { + this._onError(e); + }; + } + cleanSocket() { + this.close(); + this._connected = false; + this._socket.onopen = null; + this._socket.onmessage = null; + this._socket.onclose = null; + this._socket.onerror = null; + this._socket = null; + } + close() { + if (this._socket != null) { + try { + this._socket.close(); + } + catch (e) { + } + } + } + _onOpen(e) { + this._connected = true; + this.event(Event.OPEN, e); + } + _onMessage(msg) { + if (!msg || !msg.data) + return; + var data = msg.data; + if (this.disableInput && data) { + this.event(Event.MESSAGE, data); + return; + } + if (this._input.length > 0 && this._input.bytesAvailable < 1) { + this._input.clear(); + this._addInputPosition = 0; + } + var pre = this._input.pos; + !this._addInputPosition && (this._addInputPosition = 0); + this._input.pos = this._addInputPosition; + if (data) { + if (typeof (data) == 'string') { + this._input.writeUTFBytes(data); + } + else { + this._input.writeArrayBuffer(data); + } + this._addInputPosition = this._input.pos; + this._input.pos = pre; + } + this.event(Event.MESSAGE, data); + } + _onClose(e) { + this._connected = false; + this.event(Event.CLOSE, e); + } + _onError(e) { + this.event(Event.ERROR, e); + } + send(data) { + this._socket.send(data); + } + flush() { + if (this._output && this._output.length > 0) { + var evt; + try { + this._socket && this._socket.send(this._output.__getBuffer().slice(0, this._output.length)); + } + catch (e) { + evt = e; + } + this._output.endian = this.endian; + this._output.clear(); + if (evt) + this.event(Event.ERROR, evt); + } + } + } + Socket.LITTLE_ENDIAN = "littleEndian"; + Socket.BIG_ENDIAN = "bigEndian"; + + (function (TextureDecodeFormat) { + TextureDecodeFormat[TextureDecodeFormat["Normal"] = 0] = "Normal"; + TextureDecodeFormat[TextureDecodeFormat["RGBM"] = 1] = "RGBM"; + })(exports.TextureDecodeFormat || (exports.TextureDecodeFormat = {})); + + class VideoTexture extends BaseTexture { + constructor() { + var gl = LayaGL.instance; + super(gl.RGB, false); + this._glTextureType = gl.TEXTURE_2D; + this._width = 1; + this._height = 1; + this._wrapModeU = this._wrapModeV = exports.WarpMode.Clamp; + this._filterMode = exports.FilterMode.Bilinear; + this._setWarpMode(gl.TEXTURE_WRAP_S, this._wrapModeU); + this._setWarpMode(gl.TEXTURE_WRAP_T, this._wrapModeV); + this._setFilterMode(this._filterMode); + this._needUpdate = false; + this._readyed = true; + VideoTexture._videoTexturePool.push(this); + } + static _update() { + var pool = VideoTexture._videoTexturePool; + for (var i = 0, n = pool.length; i < n; i++) { + var videoElement = pool[i]; + (videoElement) && videoElement._updateVideoData(); + } + } + get video() { + return this._video; + } + set video(value) { + if (!value || !(value instanceof HTMLVideoElement)) + return; + this._video = value; + if (Laya.Browser.onMobile) { + this._video["x5-playsInline"] = true; + this._video["x5-playsinline"] = true; + this._video.x5PlaysInline = true; + this._video.playsInline = true; + this._video["webkit-playsInline"] = true; + this._video["webkit-playsinline"] = true; + this._video.webkitPlaysInline = true; + this._video.playsinline = true; + this._video.style.playsInline = true; + this._video.crossOrigin = "anonymous"; + this._video.setAttribute('crossorigin', "anonymous"); + this._video.setAttribute('playsinline', 'true'); + this._video.setAttribute('x5-playsinline', 'true'); + this._video.setAttribute('webkit-playsinline', 'true'); + this._video.autoplay = true; + } + } + _updateVideoData() { + if (!this._video || !this._needUpdate) + return; + var gl = LayaGL.instance; + WebGLContext.bindTexture(gl, this._glTextureType, this._glTexture); + gl.texImage2D(this._glTextureType, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, this._video); + } + videoPlay() { + this._video.play(); + this._needUpdate = true; + } + videoPause() { + this._video.pause(); + this._needUpdate = false; + } + destroy() { + super.destroy(); + this._video = null; + } + } + VideoTexture._videoTexturePool = new Array(); + + class System { + static changeDefinition(name, classObj) { + window.Laya[name] = classObj; + var str = name + "=classObj"; + window['eval'](str); + } + } + + class HTMLChar { + constructor() { + this.reset(); + } + setData(char, w, h, style) { + this.char = char; + this.charNum = char.charCodeAt(0); + this.x = this.y = 0; + this.width = w; + this.height = h; + this.style = style; + this.isWord = !HTMLChar._isWordRegExp.test(char); + return this; + } + reset() { + this.x = this.y = this.width = this.height = 0; + this.isWord = false; + this.char = null; + this.charNum = 0; + this.style = null; + return this; + } + recover() { + Pool.recover("HTMLChar", this.reset()); + } + static create() { + return Pool.getItemByClass("HTMLChar", HTMLChar); + } + _isChar() { + return true; + } + _getCSSStyle() { + return this.style; + } + } + HTMLChar._isWordRegExp = new RegExp("[\\w\.]", ""); + + class Log { + static enable() { + if (!Log._logdiv) { + Log._logdiv = Browser.createElement('div'); + Log._logdiv.style.cssText = "border:white;padding:4px;overflow-y:auto;z-index:1000000;background:rgba(100,100,100,0.6);color:white;position: absolute;left:0px;top:0px;width:50%;height:50%;"; + Browser.document.body.appendChild(Log._logdiv); + Log._btn = Browser.createElement("button"); + Log._btn.innerText = "Hide"; + Log._btn.style.cssText = "z-index:1000001;position: absolute;left:10px;top:10px;"; + Log._btn.onclick = Log.toggle; + Browser.document.body.appendChild(Log._btn); + } + } + static toggle() { + var style = Log._logdiv.style; + if (style.display === "") { + Log._btn.innerText = "Show"; + style.display = "none"; + } + else { + Log._btn.innerText = "Hide"; + style.display = ""; + } + } + static print(value) { + if (Log._logdiv) { + if (Log._count >= Log.maxCount) + Log.clear(); + Log._count++; + Log._logdiv.innerText += value + "\n"; + if (Log.autoScrollToBottom) { + if (Log._logdiv.scrollHeight - Log._logdiv.scrollTop - Log._logdiv.clientHeight < 50) { + Log._logdiv.scrollTop = Log._logdiv.scrollHeight; + } + } + } + } + static clear() { + Log._logdiv.innerText = ""; + Log._count = 0; + } + } + Log._count = 0; + Log.maxCount = 50; + Log.autoScrollToBottom = true; + + let DATANUM = 300; + class PerfData { + constructor(id, color, name, scale) { + this.scale = 1.0; + this.datas = new Array(DATANUM); + this.datapos = 0; + this.id = id; + this.color = color; + this.name = name; + this.scale = scale; + } + addData(v) { + this.datas[this.datapos] = v; + this.datapos++; + this.datapos %= DATANUM; + } + } + + class PerfHUD extends Sprite { + constructor() { + super(); + this.datas = []; + this.xdata = new Array(PerfHUD.DATANUM); + this.ydata = new Array(PerfHUD.DATANUM); + this.hud_width = 800; + this.hud_height = 200; + this.gMinV = 0; + this.gMaxV = 100; + this.textSpace = 40; + this.sttm = 0; + PerfHUD.inst = this; + this._renderType |= SpriteConst.CUSTOM; + this._setRenderType(this._renderType); + this._setCustomRender(); + this.addDataDef(0, 0xffffff, 'frame', 1.0); + this.addDataDef(1, 0x00ff00, 'update', 1.0); + this.addDataDef(2, 0xff0000, 'flush', 1.0); + PerfHUD._now = performance ? performance.now.bind(performance) : Date.now; + } + now() { + return PerfHUD._now(); + } + start() { + this.sttm = PerfHUD._now(); + } + end(i) { + var dt = PerfHUD._now() - this.sttm; + this.updateValue(i, dt); + } + config(w, h) { + this.hud_width = w; + this.hud_height = h; + } + addDataDef(id, color, name, scale) { + this.datas[id] = new PerfData(id, color, name, scale); + } + updateValue(id, v) { + this.datas[id].addData(v); + } + v2y(v) { + var bb = this._y + this.hud_height * (1 - (v - this.gMinV) / this.gMaxV); + return this._y + this.hud_height * (1 - (v - this.gMinV) / this.gMaxV); + } + drawHLine(ctx, v, color, text) { + var sx = this._x; + var ex = this._x + this.hud_width; + var sy = this.v2y(v); + ctx.fillText(text, sx, sy - 6, null, 'green', null); + sx += this.textSpace; + ctx.fillStyle = color; + ctx.fillRect(sx, sy, this._x + this.hud_width, 1, null); + } + customRender(ctx, x, y) { + var now = performance.now(); + if (PerfHUD._lastTm <= 0) + PerfHUD._lastTm = now; + this.updateValue(0, now - PerfHUD._lastTm); + PerfHUD._lastTm = now; + ctx.save(); + ctx.fillRect(this._x, this._y, this.hud_width, this.hud_height + 4, '#000000cc'); + ctx.globalAlpha = 0.9; + this.drawHLine(ctx, 0, 'green', ' 0'); + this.drawHLine(ctx, 10, 'green', ' 10'); + this.drawHLine(ctx, 16.667, 'red', ' '); + this.drawHLine(ctx, 20, 'green', '50|20'); + this.drawHLine(ctx, 16.667 * 2, 'yellow', ''); + this.drawHLine(ctx, 16.667 * 3, 'yellow', ''); + this.drawHLine(ctx, 16.667 * 4, 'yellow', ''); + this.drawHLine(ctx, 50, 'green', '20|50'); + this.drawHLine(ctx, 100, 'green', '10|100'); + for (var di = 0, sz = this.datas.length; di < sz; di++) { + var cd = this.datas[di]; + if (!cd) + continue; + var dtlen = cd.datas.length; + var dx = (this.hud_width - this.textSpace) / dtlen; + var cx = cd.datapos; + var _cx = this._x + this.textSpace; + ctx.fillStyle = cd.color; + for (var dtsz = dtlen; cx < dtsz; cx++) { + var sty = this.v2y(cd.datas[cx] * cd.scale); + ctx.fillRect(_cx, sty, dx, this.hud_height + this._y - sty, null); + _cx += dx; + } + for (cx = 0; cx < cd.datapos; cx++) { + sty = this.v2y(cd.datas[cx] * cd.scale); + ctx.fillRect(_cx, sty, dx, this.hud_height + this._y - sty, null); + _cx += dx; + } + } + ctx.restore(); + } + } + PerfHUD._lastTm = 0; + PerfHUD._now = null; + PerfHUD.DATANUM = 300; + PerfHUD.drawTexTm = 0; + + class PoolCache { + constructor() { + this.maxCount = 1000; + } + getCacheList() { + return Pool.getPoolBySign(this.sign); + } + tryDispose(force) { + var list; + list = Pool.getPoolBySign(this.sign); + if (list.length > this.maxCount) { + list.splice(this.maxCount, list.length - this.maxCount); + } + } + static addPoolCacheManager(sign, maxCount = 100) { + var cache; + cache = new PoolCache(); + cache.sign = sign; + cache.maxCount = maxCount; + CacheManger.regCacheByFunction(Utils.bind(cache.tryDispose, cache), Utils.bind(cache.getCacheList, cache)); + } + } + + class TimeLine extends EventDispatcher { + constructor() { + super(...arguments); + this._tweenDic = {}; + this._tweenDataList = []; + this._currTime = 0; + this._lastTime = 0; + this._startTime = 0; + this._index = 0; + this._gidIndex = 0; + this._firstTweenDic = {}; + this._startTimeSort = false; + this._endTimeSort = false; + this._loopKey = false; + this.scale = 1; + this._frameRate = 60; + this._frameIndex = 0; + this._total = 0; + } + static to(target, props, duration, ease = null, offset = 0) { + return (new TimeLine()).to(target, props, duration, ease, offset); + } + static from(target, props, duration, ease = null, offset = 0) { + return (new TimeLine()).from(target, props, duration, ease, offset); + } + to(target, props, duration, ease = null, offset = 0) { + return this._create(target, props, duration, ease, offset, true); + } + from(target, props, duration, ease = null, offset = 0) { + return this._create(target, props, duration, ease, offset, false); + } + _create(target, props, duration, ease, offset, isTo) { + var tTweenData = Pool.getItemByClass("tweenData", tweenData); + tTweenData.isTo = isTo; + tTweenData.type = 0; + tTweenData.target = target; + tTweenData.duration = duration; + tTweenData.data = props; + tTweenData.startTime = this._startTime + offset; + tTweenData.endTime = tTweenData.startTime + tTweenData.duration; + tTweenData.ease = ease; + this._startTime = Math.max(tTweenData.endTime, this._startTime); + this._tweenDataList.push(tTweenData); + this._startTimeSort = true; + this._endTimeSort = true; + return this; + } + addLabel(label, offset) { + var tTweenData = Pool.getItemByClass("tweenData", tweenData); + tTweenData.type = 1; + tTweenData.data = label; + tTweenData.endTime = tTweenData.startTime = this._startTime + offset; + this._labelDic || (this._labelDic = {}); + this._labelDic[label] = tTweenData; + this._tweenDataList.push(tTweenData); + return this; + } + removeLabel(label) { + if (this._labelDic && this._labelDic[label]) { + var tTweenData = this._labelDic[label]; + if (tTweenData) { + var tIndex = this._tweenDataList.indexOf(tTweenData); + if (tIndex > -1) { + this._tweenDataList.splice(tIndex, 1); + } + } + delete this._labelDic[label]; + } + } + gotoTime(time) { + if (this._tweenDataList == null || this._tweenDataList.length == 0) + return; + var tTween; + var tObject; + for (var p in this._firstTweenDic) { + tObject = this._firstTweenDic[p]; + if (tObject) { + for (var tDataP in tObject) { + if (tDataP in tObject.diyTarget) { + tObject.diyTarget[tDataP] = tObject[tDataP]; + } + } + } + } + for (p in this._tweenDic) { + tTween = this._tweenDic[p]; + tTween.clear(); + delete this._tweenDic[p]; + } + this._index = 0; + this._gidIndex = 0; + this._currTime = time; + this._lastTime = Browser.now(); + var tTweenDataCopyList; + if (this._endTweenDataList == null || this._endTimeSort) { + this._endTimeSort = false; + this._endTweenDataList = tTweenDataCopyList = this._tweenDataList.concat(); + function Compare(paraA, paraB) { + if (paraA.endTime > paraB.endTime) { + return 1; + } + else if (paraA.endTime < paraB.endTime) { + return -1; + } + else { + return 0; + } + } + tTweenDataCopyList.sort(Compare); + } + else { + tTweenDataCopyList = this._endTweenDataList; + } + var tTweenData; + for (var i = 0, n = tTweenDataCopyList.length; i < n; i++) { + tTweenData = tTweenDataCopyList[i]; + if (tTweenData.type == 0) { + if (time >= tTweenData.endTime) { + this._index = Math.max(this._index, i + 1); + var props = tTweenData.data; + if (tTweenData.isTo) { + for (var tP in props) { + tTweenData.target[tP] = props[tP]; + } + } + } + else { + break; + } + } + } + for (i = 0, n = this._tweenDataList.length; i < n; i++) { + tTweenData = this._tweenDataList[i]; + if (tTweenData.type == 0) { + if (time >= tTweenData.startTime && time < tTweenData.endTime) { + this._index = Math.max(this._index, i + 1); + this._gidIndex++; + tTween = Pool.getItemByClass("tween", Tween); + tTween._create(tTweenData.target, tTweenData.data, tTweenData.duration, tTweenData.ease, Handler.create(this, this._animComplete, [this._gidIndex]), 0, false, tTweenData.isTo, true, false); + tTween.setStartTime(this._currTime - (time - tTweenData.startTime)); + tTween._updateEase(this._currTime); + tTween.gid = this._gidIndex; + this._tweenDic[this._gidIndex] = tTween; + } + } + } + } + gotoLabel(Label) { + if (this._labelDic == null) + return; + var tLabelData = this._labelDic[Label]; + if (tLabelData) + this.gotoTime(tLabelData.startTime); + } + pause() { + ILaya.timer.clear(this, this._update); + } + resume() { + this.play(this._currTime, this._loopKey); + } + play(timeOrLabel = 0, loop = false) { + if (!this._tweenDataList) + return; + if (this._startTimeSort) { + this._startTimeSort = false; + function Compare(paraA, paraB) { + if (paraA.startTime > paraB.startTime) { + return 1; + } + else if (paraA.startTime < paraB.startTime) { + return -1; + } + else { + return 0; + } + } + this._tweenDataList.sort(Compare); + for (var i = 0, n = this._tweenDataList.length; i < n; i++) { + var tTweenData = this._tweenDataList[i]; + if (tTweenData != null && tTweenData.type == 0) { + var tTarget = tTweenData.target; + var gid = (tTarget.$_GID || (tTarget.$_GID = Utils.getGID())); + var tSrcData = null; + if (this._firstTweenDic[gid] == null) { + tSrcData = {}; + tSrcData.diyTarget = tTarget; + this._firstTweenDic[gid] = tSrcData; + } + else { + tSrcData = this._firstTweenDic[gid]; + } + for (var p in tTweenData.data) { + if (tSrcData[p] == null) { + tSrcData[p] = tTarget[p]; + } + } + } + } + } + if (typeof (timeOrLabel) == 'string') { + this.gotoLabel(timeOrLabel); + } + else { + this.gotoTime(timeOrLabel); + } + this._loopKey = loop; + this._lastTime = Browser.now(); + ILaya.timer.frameLoop(1, this, this._update); + } + _update() { + if (this._currTime >= this._startTime) { + if (this._loopKey) { + this._complete(); + if (!this._tweenDataList) + return; + this.gotoTime(0); + } + else { + for (var p in this._tweenDic) { + tTween = this._tweenDic[p]; + tTween.complete(); + } + this.pause(); + this._complete(); + return; + } + } + var tNow = Browser.now(); + var tFrameTime = tNow - this._lastTime; + var tCurrTime = this._currTime += tFrameTime * this.scale; + this._lastTime = tNow; + for (p in this._tweenDic) { + tTween = this._tweenDic[p]; + tTween._updateEase(tCurrTime); + } + var tTween; + if (this._tweenDataList.length != 0 && this._index < this._tweenDataList.length) { + var tTweenData = this._tweenDataList[this._index]; + if (tCurrTime >= tTweenData.startTime) { + this._index++; + if (tTweenData.type == 0) { + this._gidIndex++; + tTween = Pool.getItemByClass("tween", Tween); + tTween._create(tTweenData.target, tTweenData.data, tTweenData.duration, tTweenData.ease, Handler.create(this, this._animComplete, [this._gidIndex]), 0, false, tTweenData.isTo, true, false); + tTween.setStartTime(tCurrTime); + tTween.gid = this._gidIndex; + this._tweenDic[this._gidIndex] = tTween; + tTween._updateEase(tCurrTime); + } + else { + this.event(Event.LABEL, tTweenData.data); + } + } + } + } + _animComplete(index) { + var tTween = this._tweenDic[index]; + if (tTween) + delete this._tweenDic[index]; + } + _complete() { + this.event(Event.COMPLETE); + } + get index() { + return this._frameIndex; + } + set index(value) { + this._frameIndex = value; + this.gotoTime(this._frameIndex / this._frameRate * 1000); + } + get total() { + this._total = Math.floor(this._startTime / 1000 * this._frameRate); + return this._total; + } + reset() { + var p; + if (this._labelDic) { + for (p in this._labelDic) { + delete this._labelDic[p]; + } + } + var tTween; + for (p in this._tweenDic) { + tTween = this._tweenDic[p]; + tTween.clear(); + delete this._tweenDic[p]; + } + for (p in this._firstTweenDic) { + delete this._firstTweenDic[p]; + } + this._endTweenDataList = null; + if (this._tweenDataList && this._tweenDataList.length) { + var i, len; + len = this._tweenDataList.length; + for (i = 0; i < len; i++) { + if (this._tweenDataList[i]) + this._tweenDataList[i].destroy(); + } + } + this._tweenDataList.length = 0; + this._currTime = 0; + this._lastTime = 0; + this._startTime = 0; + this._index = 0; + this._gidIndex = 0; + this.scale = 1; + ILaya.timer.clear(this, this._update); + } + destroy() { + this.reset(); + this._labelDic = null; + this._tweenDic = null; + this._tweenDataList = null; + this._firstTweenDic = null; + } + } + class tweenData { + constructor() { + this.type = 0; + this.isTo = true; + } + destroy() { + this.target = null; + this.ease = null; + this.data = null; + this.isTo = true; + this.type = 0; + Pool.recover("tweenData", this); + } + } + + class ShaderValue { + constructor() { + } + } + + class ArabicReshaper { + characterMapContains(c) { + for (var i = 0; i < ArabicReshaper.charsMap.length; ++i) { + if (ArabicReshaper.charsMap[i][0] === c) { + return true; + } + } + return false; + } + getCharRep(c) { + for (var i = 0; i < ArabicReshaper.charsMap.length; ++i) { + if (ArabicReshaper.charsMap[i][0] === c) { + return ArabicReshaper.charsMap[i]; + } + } + return false; + } + getCombCharRep(c1, c2) { + for (var i = 0; i < ArabicReshaper.combCharsMap.length; ++i) { + if (ArabicReshaper.combCharsMap[i][0][0] === c1 && ArabicReshaper.combCharsMap[i][0][1] === c2) { + return ArabicReshaper.combCharsMap[i]; + } + } + return false; + } + isTransparent(c) { + for (var i = 0; i < ArabicReshaper.transChars.length; ++i) { + if (ArabicReshaper.transChars[i] === c) { + return true; + } + } + return false; + } + getOriginalCharsFromCode(code) { + var j; + for (j = 0; j < ArabicReshaper.charsMap.length; ++j) { + if (ArabicReshaper.charsMap[j].indexOf(code) > -1) { + return String.fromCharCode(ArabicReshaper.charsMap[j][0]); + } + } + for (j = 0; j < ArabicReshaper.combCharsMap.length; ++j) { + if (ArabicReshaper.combCharsMap[j].indexOf(code) > -1) { + return String.fromCharCode(ArabicReshaper.combCharsMap[j][0][0]) + + String.fromCharCode(ArabicReshaper.combCharsMap[j][0][1]); + } + } + return String.fromCharCode(code); + } + convertArabic(normal) { + var crep, combcrep, shaped = ''; + for (var i = 0; i < normal.length; ++i) { + var current = normal.charCodeAt(i); + if (this.characterMapContains(current)) { + var prev = null, next = null, prevID = i - 1, nextID = i + 1; + for (; prevID >= 0; --prevID) { + if (!this.isTransparent(normal.charCodeAt(prevID))) { + break; + } + } + prev = (prevID >= 0) ? normal.charCodeAt(prevID) : null; + crep = prev ? this.getCharRep(prev) : false; + if (!crep || crep[2] == null && crep[3] == null) { + prev = null; + } + for (; nextID < normal.length; ++nextID) { + if (!this.isTransparent(normal.charCodeAt(nextID))) { + break; + } + } + next = (nextID < normal.length) ? normal.charCodeAt(nextID) : null; + crep = next ? this.getCharRep(next) : false; + if (!crep || crep[3] == null && crep[4] == null) { + next = null; + } + if (current === 0x0644 && next != null && + (next === 0x0622 || next === 0x0623 || next === 0x0625 || next === 0x0627)) { + combcrep = this.getCombCharRep(current, next); + if (prev != null) { + shaped += String.fromCharCode(combcrep[4]); + } + else { + shaped += String.fromCharCode(combcrep[1]); + } + ++i; + continue; + } + crep = this.getCharRep(current); + if (prev != null && next != null && crep[3] != null) { + shaped += String.fromCharCode(crep[3]); + continue; + } + else if (prev != null && crep[4] != null) { + shaped += String.fromCharCode(crep[4]); + continue; + } + else if (next != null && crep[2] != null) { + shaped += String.fromCharCode(crep[2]); + continue; + } + else { + shaped += String.fromCharCode(crep[1]); + } + } + else { + shaped += String.fromCharCode(current); + } + } + return shaped; + } + convertArabicBack(apfb) { + var toReturn = '', selectedChar; + var i; + for (i = 0; i < apfb.length; ++i) { + selectedChar = apfb.charCodeAt(i); + toReturn += this.getOriginalCharsFromCode(selectedChar); + } + return toReturn; + } + } + ArabicReshaper.charsMap = [[0x0621, 0xFE80, null, null, null], + [0x0622, 0xFE81, null, null, 0xFE82], + [0x0623, 0xFE83, null, null, 0xFE84], + [0x0624, 0xFE85, null, null, 0xFE86], + [0x0625, 0xFE87, null, null, 0xFE88], + [0x0626, 0xFE89, 0xFE8B, 0xFE8C, 0xFE8A], + [0x0627, 0xFE8D, null, null, 0xFE8E], + [0x0628, 0xFE8F, 0xFE91, 0xFE92, 0xFE90], + [0x0629, 0xFE93, null, null, 0xFE94], + [0x062A, 0xFE95, 0xFE97, 0xFE98, 0xFE96], + [0x062B, 0xFE99, 0xFE9B, 0xFE9C, 0xFE9A], + [0x062C, 0xFE9D, 0xFE9F, 0xFEA0, 0xFE9E], + [0x062D, 0xFEA1, 0xFEA3, 0xFEA4, 0xFEA2], + [0x062E, 0xFEA5, 0xFEA7, 0xFEA8, 0xFEA6], + [0x062F, 0xFEA9, null, null, 0xFEAA], + [0x0630, 0xFEAB, null, null, 0xFEAC], + [0x0631, 0xFEAD, null, null, 0xFEAE], + [0x0632, 0xFEAF, null, null, 0xFEB0], + [0x0633, 0xFEB1, 0xFEB3, 0xFEB4, 0xFEB2], + [0x0634, 0xFEB5, 0xFEB7, 0xFEB8, 0xFEB6], + [0x0635, 0xFEB9, 0xFEBB, 0xFEBC, 0xFEBA], + [0x0636, 0xFEBD, 0xFEBF, 0xFEC0, 0xFEBE], + [0x0637, 0xFEC1, 0xFEC3, 0xFEC4, 0xFEC2], + [0x0638, 0xFEC5, 0xFEC7, 0xFEC8, 0xFEC6], + [0x0639, 0xFEC9, 0xFECB, 0xFECC, 0xFECA], + [0x063A, 0xFECD, 0xFECF, 0xFED0, 0xFECE], + [0x0640, 0x0640, 0x0640, 0x0640, 0x0640], + [0x0641, 0xFED1, 0xFED3, 0xFED4, 0xFED2], + [0x0642, 0xFED5, 0xFED7, 0xFED8, 0xFED6], + [0x0643, 0xFED9, 0xFEDB, 0xFEDC, 0xFEDA], + [0x0644, 0xFEDD, 0xFEDF, 0xFEE0, 0xFEDE], + [0x0645, 0xFEE1, 0xFEE3, 0xFEE4, 0xFEE2], + [0x0646, 0xFEE5, 0xFEE7, 0xFEE8, 0xFEE6], + [0x0647, 0xFEE9, 0xFEEB, 0xFEEC, 0xFEEA], + [0x0648, 0xFEED, null, null, 0xFEEE], + [0x0649, 0xFEEF, null, null, 0xFEF0], + [0x064A, 0xFEF1, 0xFEF3, 0xFEF4, 0xFEF2], + [0x067E, 0xFB56, 0xFB58, 0xFB59, 0xFB57], + [0x06CC, 0xFBFC, 0xFBFE, 0xFBFF, 0xFBFD], + [0x0686, 0xFB7A, 0xFB7C, 0xFB7D, 0xFB7B], + [0x06A9, 0xFB8E, 0xFB90, 0xFB91, 0xFB8F], + [0x06AF, 0xFB92, 0xFB94, 0xFB95, 0xFB93], + [0x0698, 0xFB8A, null, null, 0xFB8B]]; + ArabicReshaper.combCharsMap = [[[0x0644, 0x0622], 0xFEF5, null, null, 0xFEF6], + [[0x0644, 0x0623], 0xFEF7, null, null, 0xFEF8], + [[0x0644, 0x0625], 0xFEF9, null, null, 0xFEFA], + [[0x0644, 0x0627], 0xFEFB, null, null, 0xFEFC]]; + ArabicReshaper.transChars = [0x0610, + 0x0612, + 0x0613, + 0x0614, + 0x0615, + 0x064B, + 0x064C, + 0x064D, + 0x064E, + 0x064F, + 0x0650, + 0x0651, + 0x0652, + 0x0653, + 0x0654, + 0x0655, + 0x0656, + 0x0657, + 0x0658, + 0x0670, + 0x06D6, + 0x06D7, + 0x06D8, + 0x06D9, + 0x06DA, + 0x06DB, + 0x06DC, + 0x06DF, + 0x06E0, + 0x06E1, + 0x06E2, + 0x06E3, + 0x06E4, + 0x06E7, + 0x06E8, + 0x06EA, + 0x06EB, + 0x06EC, + 0x06ED]; + + class MatirxArray { + static ArrayMul(a, b, o) { + if (!a) { + MatirxArray.copyArray(b, o); + return; + } + if (!b) { + MatirxArray.copyArray(a, o); + return; + } + var ai0, ai1, ai2, ai3; + for (var i = 0; i < 4; i++) { + ai0 = a[i]; + ai1 = a[i + 4]; + ai2 = a[i + 8]; + ai3 = a[i + 12]; + o[i] = ai0 * b[0] + ai1 * b[1] + ai2 * b[2] + ai3 * b[3]; + o[i + 4] = ai0 * b[4] + ai1 * b[5] + ai2 * b[6] + ai3 * b[7]; + o[i + 8] = ai0 * b[8] + ai1 * b[9] + ai2 * b[10] + ai3 * b[11]; + o[i + 12] = ai0 * b[12] + ai1 * b[13] + ai2 * b[14] + ai3 * b[15]; + } + } + static copyArray(f, t) { + if (!f) + return; + if (!t) + return; + for (var i = 0; i < f.length; i++) { + t[i] = f[i]; + } + } + } + + exports.AlphaCmd = AlphaCmd; + exports.Animation = Animation; + exports.AnimationBase = AnimationBase; + exports.ArabicReshaper = ArabicReshaper; + exports.AtlasGrid = AtlasGrid; + exports.AtlasInfoManager = AtlasInfoManager; + exports.AudioSound = AudioSound; + exports.AudioSoundChannel = AudioSoundChannel; + exports.BasePoly = BasePoly; + exports.BaseShader = BaseShader; + exports.BaseTexture = BaseTexture; + exports.Bezier = Bezier; + exports.Bitmap = Bitmap; + exports.BitmapFont = BitmapFont; + exports.BlendMode = BlendMode; + exports.BlurFilter = BlurFilter; + exports.BlurFilterGLRender = BlurFilterGLRender; + exports.BlurFilterSetter = BlurFilterSetter; + exports.BoundsStyle = BoundsStyle; + exports.Browser = Browser; + exports.Buffer = Buffer; + exports.Buffer2D = Buffer2D; + exports.BufferState2D = BufferState2D; + exports.BufferStateBase = BufferStateBase; + exports.ButtonEffect = ButtonEffect; + exports.Byte = Byte; + exports.CONST3D2D = CONST3D2D; + exports.CacheManger = CacheManger; + exports.CacheStyle = CacheStyle; + exports.CallLater = CallLater; + exports.CharRenderInfo = CharRenderInfo; + exports.CharRender_Canvas = CharRender_Canvas; + exports.CharRender_Native = CharRender_Native; + exports.CharSubmitCache = CharSubmitCache; + exports.ClassUtils = ClassUtils; + exports.ClipRectCmd = ClipRectCmd; + exports.ColorFilter = ColorFilter; + exports.ColorFilterSetter = ColorFilterSetter; + exports.ColorUtils = ColorUtils; + exports.CommandEncoder = CommandEncoder; + exports.CommonScript = CommonScript; + exports.Component = Component; + exports.Config = Config; + exports.Const = Const; + exports.Context = Context; + exports.Dragging = Dragging; + exports.Draw9GridTexture = Draw9GridTexture; + exports.DrawCircleCmd = DrawCircleCmd; + exports.DrawCurvesCmd = DrawCurvesCmd; + exports.DrawImageCmd = DrawImageCmd; + exports.DrawLineCmd = DrawLineCmd; + exports.DrawLinesCmd = DrawLinesCmd; + exports.DrawParticleCmd = DrawParticleCmd; + exports.DrawPathCmd = DrawPathCmd; + exports.DrawPieCmd = DrawPieCmd; + exports.DrawPolyCmd = DrawPolyCmd; + exports.DrawRectCmd = DrawRectCmd; + exports.DrawStyle = DrawStyle; + exports.DrawTextureCmd = DrawTextureCmd; + exports.DrawTexturesCmd = DrawTexturesCmd; + exports.DrawTrianglesCmd = DrawTrianglesCmd; + exports.Earcut = Earcut; + exports.EarcutNode = EarcutNode; + exports.Ease = Ease; + exports.EffectAnimation = EffectAnimation; + exports.EffectBase = EffectBase; + exports.Event = Event; + exports.EventDispatcher = EventDispatcher; + exports.FadeIn = FadeIn; + exports.FadeOut = FadeOut; + exports.FillTextCmd = FillTextCmd; + exports.FillTextureCmd = FillTextureCmd; + exports.Filter = Filter; + exports.FilterSetterBase = FilterSetterBase; + exports.FontInfo = FontInfo; + exports.FrameAnimation = FrameAnimation; + exports.GlowFilter = GlowFilter; + exports.GlowFilterGLRender = GlowFilterGLRender; + exports.GlowFilterSetter = GlowFilterSetter; + exports.GrahamScan = GrahamScan; + exports.GraphicAnimation = GraphicAnimation; + exports.Graphics = Graphics; + exports.GraphicsBounds = GraphicsBounds; + exports.HTMLCanvas = HTMLCanvas; + exports.HTMLChar = HTMLChar; + exports.HTMLImage = HTMLImage; + exports.HalfFloatUtils = HalfFloatUtils; + exports.Handler = Handler; + exports.HitArea = HitArea; + exports.HttpRequest = HttpRequest; + exports.ICharRender = ICharRender; + exports.ILaya = ILaya; + exports.IStatRender = IStatRender; + exports.IndexBuffer2D = IndexBuffer2D; + exports.InlcudeFile = InlcudeFile; + exports.Input = Input; + exports.KeyBoardManager = KeyBoardManager; + exports.KeyLocation = KeyLocation; + exports.Keyboard = Keyboard; + exports.Laya = Laya; + exports.LayaGL = LayaGL; + exports.LayaGLQuickRunner = LayaGLQuickRunner; + exports.LayaGLRunner = LayaGLRunner; + exports.LayaGPU = LayaGPU; + exports.Loader = Loader; + exports.LoaderManager = LoaderManager; + exports.LocalStorage = LocalStorage; + exports.Log = Log; + exports.MathUtil = MathUtil; + exports.MatirxArray = MatirxArray; + exports.Matrix = Matrix; + exports.Mesh2D = Mesh2D; + exports.MeshParticle2D = MeshParticle2D; + exports.MeshQuadTexture = MeshQuadTexture; + exports.MeshTexture = MeshTexture; + exports.MeshVG = MeshVG; + exports.Mouse = Mouse; + exports.MouseManager = MouseManager; + exports.Node = Node; + exports.Path = Path; + exports.PerfData = PerfData; + exports.PerfHUD = PerfHUD; + exports.PerformancePlugin = PerformancePlugin; + exports.Point = Point; + exports.Pool = Pool; + exports.PoolCache = PoolCache; + exports.Prefab = Prefab; + exports.PrimitiveSV = PrimitiveSV; + exports.QuickTestTool = QuickTestTool; + exports.Rectangle = Rectangle; + exports.Render = Render; + exports.RenderInfo = RenderInfo; + exports.RenderSprite = RenderSprite; + exports.RenderState2D = RenderState2D; + exports.RenderTexture2D = RenderTexture2D; + exports.Resource = Resource; + exports.ResourceVersion = ResourceVersion; + exports.RestoreCmd = RestoreCmd; + exports.RotateCmd = RotateCmd; + exports.RunDriver = RunDriver; + exports.SaveBase = SaveBase; + exports.SaveClipRect = SaveClipRect; + exports.SaveCmd = SaveCmd; + exports.SaveMark = SaveMark; + exports.SaveTransform = SaveTransform; + exports.SaveTranslate = SaveTranslate; + exports.ScaleCmd = ScaleCmd; + exports.Scene = Scene; + exports.SceneLoader = SceneLoader; + exports.SceneUtils = SceneUtils; + exports.Script = Script; + exports.Shader = Shader; + exports.Shader2D = Shader2D; + exports.Shader2X = Shader2X; + exports.ShaderCompile = ShaderCompile; + exports.ShaderDefines2D = ShaderDefines2D; + exports.ShaderDefinesBase = ShaderDefinesBase; + exports.ShaderNode = ShaderNode; + exports.ShaderValue = ShaderValue; + exports.SkinMeshBuffer = SkinMeshBuffer; + exports.SkinSV = SkinSV; + exports.Socket = Socket; + exports.Sound = Sound; + exports.SoundChannel = SoundChannel; + exports.SoundManager = SoundManager; + exports.SoundNode = SoundNode; + exports.Sprite = Sprite; + exports.SpriteConst = SpriteConst; + exports.SpriteStyle = SpriteStyle; + exports.Stage = Stage; + exports.Stat = Stat; + exports.StatUI = StatUI; + exports.StringKey = StringKey; + exports.Submit = Submit; + exports.SubmitBase = SubmitBase; + exports.SubmitCMD = SubmitCMD; + exports.SubmitCanvas = SubmitCanvas; + exports.SubmitKey = SubmitKey; + exports.SubmitTarget = SubmitTarget; + exports.SubmitTexture = SubmitTexture; + exports.System = System; + exports.SystemUtils = SystemUtils; + exports.TTFLoader = TTFLoader; + exports.Text = Text; + exports.TextAtlas = TextAtlas; + exports.TextRender = TextRender; + exports.TextStyle = TextStyle; + exports.TextTexture = TextTexture; + exports.Texture = Texture; + exports.Texture2D = Texture2D; + exports.TextureSV = TextureSV; + exports.TimeLine = TimeLine; + exports.Timer = Timer; + exports.TouchManager = TouchManager; + exports.TransformCmd = TransformCmd; + exports.TranslateCmd = TranslateCmd; + exports.Tween = Tween; + exports.URL = URL; + exports.Utils = Utils; + exports.Value2D = Value2D; + exports.VectorGraphManager = VectorGraphManager; + exports.VertexArrayObject = VertexArrayObject; + exports.VertexBuffer2D = VertexBuffer2D; + exports.VideoTexture = VideoTexture; + exports.WeakObject = WeakObject; + exports.WebAudioSound = WebAudioSound; + exports.WebAudioSoundChannel = WebAudioSoundChannel; + exports.WebGL = WebGL; + exports.WebGLCacheAsNormalCanvas = WebGLCacheAsNormalCanvas; + exports.WebGLContext = WebGLContext; + exports.WebGLRTMgr = WebGLRTMgr; + exports.WordText = WordText; + exports.WorkerLoader = WorkerLoader; + exports.__init = __init; + exports._static = _static; + exports.alertGlobalError = alertGlobalError; + exports.enableDebugPanel = enableDebugPanel; + exports.init = init; + exports.isWXOpenDataContext = isWXOpenDataContext; + exports.isWXPosMsg = isWXPosMsg; + exports.version = version; + + exports.static=_static; + + return exports; + +}({})); diff --git a/examples/layaair/frontend/bin/libs/laya.d3.js b/examples/layaair/frontend/bin/libs/laya.d3.js new file mode 100644 index 0000000..981244f --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.d3.js @@ -0,0 +1,32166 @@ +(function (exports, Laya) { + 'use strict'; + + class MathUtils3D { + constructor() { + } + static isZero(v) { + return Math.abs(v) < MathUtils3D.zeroTolerance; + } + static nearEqual(n1, n2) { + if (MathUtils3D.isZero(n1 - n2)) + return true; + return false; + } + static fastInvSqrt(value) { + if (MathUtils3D.isZero(value)) + return value; + return 1.0 / Math.sqrt(value); + } + } + MathUtils3D.zeroTolerance = 1e-6; + MathUtils3D.MaxValue = 3.40282347e+38; + MathUtils3D.MinValue = -3.40282347e+38; + MathUtils3D.Deg2Rad = Math.PI / 180; + + class Vector2 { + constructor(x = 0, y = 0) { + this.x = x; + this.y = y; + } + setValue(x, y) { + this.x = x; + this.y = y; + } + static scale(a, b, out) { + out.x = a.x * b; + out.y = a.y * b; + } + fromArray(array, offset = 0) { + this.x = array[offset + 0]; + this.y = array[offset + 1]; + } + toArray(array, offset = 0) { + array[offset + 0] = this.x; + array[offset + 1] = this.y; + } + cloneTo(destObject) { + var destVector2 = destObject; + destVector2.x = this.x; + destVector2.y = this.y; + } + static dot(a, b) { + return (a.x * b.x) + (a.y * b.y); + } + static normalize(s, out) { + var x = s.x, y = s.y; + var len = x * x + y * y; + if (len > 0) { + len = 1 / Math.sqrt(len); + out.x = x * len; + out.y = y * len; + } + } + static scalarLength(a) { + var x = a.x, y = a.y; + return Math.sqrt(x * x + y * y); + } + clone() { + var destVector2 = new Vector2(); + this.cloneTo(destVector2); + return destVector2; + } + forNativeElement(nativeElements = null) { + if (nativeElements) { + this.elements = nativeElements; + this.elements[0] = this.x; + this.elements[1] = this.y; + } + else { + this.elements = new Float32Array([this.x, this.y]); + } + Vector2.rewriteNumProperty(this, "x", 0); + Vector2.rewriteNumProperty(this, "y", 1); + } + static rewriteNumProperty(proto, name, index) { + Object["defineProperty"](proto, name, { + "get": function () { + return this.elements[index]; + }, + "set": function (v) { + this.elements[index] = v; + } + }); + } + } + Vector2.ZERO = new Vector2(0.0, 0.0); + Vector2.ONE = new Vector2(1.0, 1.0); + + class Vector4 { + constructor(x = 0, y = 0, z = 0, w = 0) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + setValue(x, y, z, w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + fromArray(array, offset = 0) { + this.x = array[offset + 0]; + this.y = array[offset + 1]; + this.z = array[offset + 2]; + this.w = array[offset + 3]; + } + toArray(array, offset = 0) { + array[offset + 0] = this.x; + array[offset + 1] = this.y; + array[offset + 2] = this.z; + array[offset + 3] = this.w; + } + cloneTo(destObject) { + var destVector4 = destObject; + destVector4.x = this.x; + destVector4.y = this.y; + destVector4.z = this.z; + destVector4.w = this.w; + } + clone() { + var destVector4 = new Vector4(); + this.cloneTo(destVector4); + return destVector4; + } + static lerp(a, b, t, out) { + var ax = a.x, ay = a.y, az = a.z, aw = a.w; + out.x = ax + t * (b.x - ax); + out.y = ay + t * (b.y - ay); + out.z = az + t * (b.z - az); + out.w = aw + t * (b.w - aw); + } + static transformByM4x4(vector4, m4x4, out) { + var vx = vector4.x; + var vy = vector4.y; + var vz = vector4.z; + var vw = vector4.w; + var me = m4x4.elements; + out.x = vx * me[0] + vy * me[4] + vz * me[8] + vw * me[12]; + out.y = vx * me[1] + vy * me[5] + vz * me[9] + vw * me[13]; + out.z = vx * me[2] + vy * me[6] + vz * me[10] + vw * me[14]; + out.w = vx * me[3] + vy * me[7] + vz * me[11] + vw * me[15]; + } + static equals(a, b) { + return MathUtils3D.nearEqual(Math.abs(a.x), Math.abs(b.x)) && MathUtils3D.nearEqual(Math.abs(a.y), Math.abs(b.y)) && MathUtils3D.nearEqual(Math.abs(a.z), Math.abs(b.z)) && MathUtils3D.nearEqual(Math.abs(a.w), Math.abs(b.w)); + } + length() { + return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w); + } + lengthSquared() { + return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; + } + static normalize(s, out) { + var len = s.length(); + if (len > 0) { + var inverse = 1.0 / len; + out.x = s.x * inverse; + out.y = s.y * inverse; + out.z = s.z * inverse; + out.w = s.w * inverse; + } + } + static add(a, b, out) { + out.x = a.x + b.x; + out.y = a.y + b.y; + out.z = a.z + b.z; + out.w = a.w + b.w; + } + static subtract(a, b, out) { + out.x = a.x - b.x; + out.y = a.y - b.y; + out.z = a.z - b.z; + out.w = a.w - b.w; + } + static multiply(a, b, out) { + out.x = a.x * b.x; + out.y = a.y * b.y; + out.z = a.z * b.z; + out.w = a.w * b.w; + } + static scale(a, b, out) { + out.x = a.x * b; + out.y = a.y * b; + out.z = a.z * b; + out.w = a.w * b; + } + static Clamp(value, min, max, out) { + var x = value.x; + var y = value.y; + var z = value.z; + var w = value.w; + var mineX = min.x; + var mineY = min.y; + var mineZ = min.z; + var mineW = min.w; + var maxeX = max.x; + var maxeY = max.y; + var maxeZ = max.z; + var maxeW = max.w; + x = (x > maxeX) ? maxeX : x; + x = (x < mineX) ? mineX : x; + y = (y > maxeY) ? maxeY : y; + y = (y < mineY) ? mineY : y; + z = (z > maxeZ) ? maxeZ : z; + z = (z < mineZ) ? mineZ : z; + w = (w > maxeW) ? maxeW : w; + w = (w < mineW) ? mineW : w; + out.x = x; + out.y = y; + out.z = z; + out.w = w; + } + static distanceSquared(value1, value2) { + var x = value1.x - value2.x; + var y = value1.y - value2.y; + var z = value1.z - value2.z; + var w = value1.w - value2.w; + return (x * x) + (y * y) + (z * z) + (w * w); + } + static distance(value1, value2) { + var x = value1.x - value2.x; + var y = value1.y - value2.y; + var z = value1.z - value2.z; + var w = value1.w - value2.w; + return Math.sqrt((x * x) + (y * y) + (z * z) + (w * w)); + } + static dot(a, b) { + return (a.x * b.x) + (a.y * b.y) + (a.z * b.z) + (a.w * b.w); + } + static min(a, b, out) { + out.x = Math.min(a.x, b.x); + out.y = Math.min(a.y, b.y); + out.z = Math.min(a.z, b.z); + out.w = Math.min(a.w, b.w); + } + static max(a, b, out) { + out.x = Math.max(a.x, b.x); + out.y = Math.max(a.y, b.y); + out.z = Math.max(a.z, b.z); + out.w = Math.max(a.w, b.w); + } + forNativeElement(nativeElements = null) { + if (nativeElements) { + this.elements = nativeElements; + this.elements[0] = this.x; + this.elements[1] = this.y; + this.elements[2] = this.z; + this.elements[3] = this.w; + } + else { + this.elements = new Float32Array([this.x, this.y, this.z, this.w]); + } + Vector2.rewriteNumProperty(this, "x", 0); + Vector2.rewriteNumProperty(this, "y", 1); + Vector2.rewriteNumProperty(this, "z", 2); + Vector2.rewriteNumProperty(this, "w", 3); + } + } + Vector4.ZERO = new Vector4(); + Vector4.ONE = new Vector4(1.0, 1.0, 1.0, 1.0); + Vector4.UnitX = new Vector4(1.0, 0.0, 0.0, 0.0); + Vector4.UnitY = new Vector4(0.0, 1.0, 0.0, 0.0); + Vector4.UnitZ = new Vector4(0.0, 0.0, 1.0, 0.0); + Vector4.UnitW = new Vector4(0.0, 0.0, 0.0, 1.0); + + class Vector3 { + constructor(x = 0, y = 0, z = 0) { + this.x = x; + this.y = y; + this.z = z; + } + static distanceSquared(value1, value2) { + var x = value1.x - value2.x; + var y = value1.y - value2.y; + var z = value1.z - value2.z; + return (x * x) + (y * y) + (z * z); + } + static distance(value1, value2) { + var x = value1.x - value2.x; + var y = value1.y - value2.y; + var z = value1.z - value2.z; + return Math.sqrt((x * x) + (y * y) + (z * z)); + } + static min(a, b, out) { + out.x = Math.min(a.x, b.x); + out.y = Math.min(a.y, b.y); + out.z = Math.min(a.z, b.z); + } + static max(a, b, out) { + out.x = Math.max(a.x, b.x); + out.y = Math.max(a.y, b.y); + out.z = Math.max(a.z, b.z); + } + static transformQuat(source, rotation, out) { + var x = source.x, y = source.y, z = source.z, qx = rotation.x, qy = rotation.y, qz = rotation.z, qw = rotation.w, ix = qw * x + qy * z - qz * y, iy = qw * y + qz * x - qx * z, iz = qw * z + qx * y - qy * x, iw = -qx * x - qy * y - qz * z; + out.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; + out.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; + out.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + } + static scalarLength(a) { + var x = a.x, y = a.y, z = a.z; + return Math.sqrt(x * x + y * y + z * z); + } + static scalarLengthSquared(a) { + var x = a.x, y = a.y, z = a.z; + return x * x + y * y + z * z; + } + static normalize(s, out) { + var x = s.x, y = s.y, z = s.z; + var len = x * x + y * y + z * z; + if (len > 0) { + len = 1 / Math.sqrt(len); + out.x = x * len; + out.y = y * len; + out.z = z * len; + } + } + static multiply(a, b, out) { + out.x = a.x * b.x; + out.y = a.y * b.y; + out.z = a.z * b.z; + } + static scale(a, b, out) { + out.x = a.x * b; + out.y = a.y * b; + out.z = a.z * b; + } + static lerp(a, b, t, out) { + var ax = a.x, ay = a.y, az = a.z; + out.x = ax + t * (b.x - ax); + out.y = ay + t * (b.y - ay); + out.z = az + t * (b.z - az); + } + static transformV3ToV3(vector, transform, result) { + var intermediate = Vector3._tempVector4; + Vector3.transformV3ToV4(vector, transform, intermediate); + result.x = intermediate.x; + result.y = intermediate.y; + result.z = intermediate.z; + } + static transformV3ToV4(vector, transform, result) { + var vectorX = vector.x; + var vectorY = vector.y; + var vectorZ = vector.z; + var transformElem = transform.elements; + result.x = (vectorX * transformElem[0]) + (vectorY * transformElem[4]) + (vectorZ * transformElem[8]) + transformElem[12]; + result.y = (vectorX * transformElem[1]) + (vectorY * transformElem[5]) + (vectorZ * transformElem[9]) + transformElem[13]; + result.z = (vectorX * transformElem[2]) + (vectorY * transformElem[6]) + (vectorZ * transformElem[10]) + transformElem[14]; + result.w = (vectorX * transformElem[3]) + (vectorY * transformElem[7]) + (vectorZ * transformElem[11]) + transformElem[15]; + } + static TransformNormal(normal, transform, result) { + var normalX = normal.x; + var normalY = normal.y; + var normalZ = normal.z; + var transformElem = transform.elements; + result.x = (normalX * transformElem[0]) + (normalY * transformElem[4]) + (normalZ * transformElem[8]); + result.y = (normalX * transformElem[1]) + (normalY * transformElem[5]) + (normalZ * transformElem[9]); + result.z = (normalX * transformElem[2]) + (normalY * transformElem[6]) + (normalZ * transformElem[10]); + } + static transformCoordinate(coordinate, transform, result) { + var coordinateX = coordinate.x; + var coordinateY = coordinate.y; + var coordinateZ = coordinate.z; + var transformElem = transform.elements; + var w = coordinateX * transformElem[3] + coordinateY * transformElem[7] + coordinateZ * transformElem[11] + transformElem[15]; + result.x = (coordinateX * transformElem[0] + coordinateY * transformElem[4] + coordinateZ * transformElem[8] + transformElem[12]) / w; + result.y = (coordinateX * transformElem[1] + coordinateY * transformElem[5] + coordinateZ * transformElem[9] + transformElem[13]) / w; + result.z = (coordinateX * transformElem[2] + coordinateY * transformElem[6] + coordinateZ * transformElem[10] + transformElem[14]) / w; + } + static Clamp(value, min, max, out) { + var x = value.x; + var y = value.y; + var z = value.z; + var mineX = min.x; + var mineY = min.y; + var mineZ = min.z; + var maxeX = max.x; + var maxeY = max.y; + var maxeZ = max.z; + x = (x > maxeX) ? maxeX : x; + x = (x < mineX) ? mineX : x; + y = (y > maxeY) ? maxeY : y; + y = (y < mineY) ? mineY : y; + z = (z > maxeZ) ? maxeZ : z; + z = (z < mineZ) ? mineZ : z; + out.x = x; + out.y = y; + out.z = z; + } + static add(a, b, out) { + out.x = a.x + b.x; + out.y = a.y + b.y; + out.z = a.z + b.z; + } + static subtract(a, b, o) { + o.x = a.x - b.x; + o.y = a.y - b.y; + o.z = a.z - b.z; + } + static cross(a, b, o) { + var ax = a.x, ay = a.y, az = a.z, bx = b.x, by = b.y, bz = b.z; + o.x = ay * bz - az * by; + o.y = az * bx - ax * bz; + o.z = ax * by - ay * bx; + } + static dot(a, b) { + return (a.x * b.x) + (a.y * b.y) + (a.z * b.z); + } + static equals(a, b) { + return MathUtils3D.nearEqual(a.x, b.x) && MathUtils3D.nearEqual(a.y, b.y) && MathUtils3D.nearEqual(a.z, b.z); + } + setValue(x, y, z) { + this.x = x; + this.y = y; + this.z = z; + } + fromArray(array, offset = 0) { + this.x = array[offset + 0]; + this.y = array[offset + 1]; + this.z = array[offset + 2]; + } + toArray(array, offset = 0) { + array[offset + 0] = this.x; + array[offset + 1] = this.y; + array[offset + 2] = this.z; + } + cloneTo(destObject) { + var destVector3 = destObject; + destVector3.x = this.x; + destVector3.y = this.y; + destVector3.z = this.z; + } + clone() { + var destVector3 = new Vector3(); + this.cloneTo(destVector3); + return destVector3; + } + toDefault() { + this.x = 0; + this.y = 0; + this.z = 0; + } + forNativeElement(nativeElements = null) { + if (nativeElements) { + this.elements = nativeElements; + this.elements[0] = this.x; + this.elements[1] = this.y; + this.elements[2] = this.z; + } + else { + this.elements = new Float32Array([this.x, this.y, this.z]); + } + Vector2.rewriteNumProperty(this, "x", 0); + Vector2.rewriteNumProperty(this, "y", 1); + Vector2.rewriteNumProperty(this, "z", 2); + } + } + Vector3._tempVector4 = new Vector4(); + Vector3._ZERO = new Vector3(0.0, 0.0, 0.0); + Vector3._ONE = new Vector3(1.0, 1.0, 1.0); + Vector3._NegativeUnitX = new Vector3(-1, 0, 0); + Vector3._UnitX = new Vector3(1, 0, 0); + Vector3._UnitY = new Vector3(0, 1, 0); + Vector3._UnitZ = new Vector3(0, 0, 1); + Vector3._ForwardRH = new Vector3(0, 0, -1); + Vector3._ForwardLH = new Vector3(0, 0, 1); + Vector3._Up = new Vector3(0, 1, 0); + + (function (PBRRenderQuality) { + PBRRenderQuality[PBRRenderQuality["High"] = 0] = "High"; + PBRRenderQuality[PBRRenderQuality["Low"] = 1] = "Low"; + })(exports.PBRRenderQuality || (exports.PBRRenderQuality = {})); + + class ILaya3D { + } + ILaya3D.Shader3D = null; + ILaya3D.Scene3D = null; + ILaya3D.MeshRenderStaticBatchManager = null; + ILaya3D.MeshRenderDynamicBatchManager = null; + ILaya3D.SubMeshDynamicBatch = null; + ILaya3D.Laya3D = null; + ILaya3D.Matrix4x4 = null; + ILaya3D.Physics3D = null; + ILaya3D.ShadowLightType = null; + ILaya3D.RenderElement = null; + ILaya3D.CommandBuffer = null; + ILaya3D.Camera = null; + ILaya3D.SubMeshRenderElement = null; + + class Physics3D { + static __bulletinit__() { + this._bullet = window.Physics3D; + if (this._bullet) { + Laya.StaticPlaneColliderShape.__init__(); + Laya.ColliderShape.__init__(); + Laya.CompoundColliderShape.__init__(); + Laya.PhysicsComponent.__init__(); + Laya.PhysicsSimulation.__init__(); + Laya.BoxColliderShape.__init__(); + Laya.CylinderColliderShape.__init__(); + Laya.CharacterController.__init__(); + Laya.Rigidbody3D.__init__(); + } + } + static __cannoninit__() { + this._cannon = window.CANNON; + if (!this._cannon) + return; + Laya.CannonColliderShape.__init__(); + Laya.CannonPhysicsComponent.__init__(); + Laya.CannonPhysicsSimulation.__init__(); + Laya.CannonBoxColliderShape.__init__(); + Laya.CannonRigidbody3D.__init__(); + } + } + Physics3D._bullet = null; + Physics3D._cannon = null; + Physics3D._enablePhysics = false; + + class Config3D { + constructor() { + this._defaultPhysicsMemory = 16; + this._maxLightCount = 32; + this._lightClusterCount = new Vector3(12, 12, 12); + this._editerEnvironment = false; + this.isAntialias = true; + this.isAlpha = false; + this.premultipliedAlpha = true; + this.isStencil = true; + this.enableMultiLight = true; + this.octreeCulling = false; + this.octreeInitialSize = 64.0; + this.octreeInitialCenter = new Vector3(0, 0, 0); + this.octreeMinNodeSize = 2.0; + this.octreeLooseness = 1.25; + this.debugFrustumCulling = false; + this.pbrRenderQuality = exports.PBRRenderQuality.High; + this.isUseCannonPhysicsEngine = false; + this._maxAreaLightCountPerClusterAverage = Math.min(Math.floor(2048 / this._lightClusterCount.z - 1) * 4, this._maxLightCount); + } + static get useCannonPhysics() { + return Config3D._config.isUseCannonPhysicsEngine; + } + static set useCannonPhysics(value) { + Config3D._config.isUseCannonPhysicsEngine = value; + if (value) { + Physics3D.__cannoninit__(); + if (!ILaya3D.Scene3D.cannonPhysicsSettings) + ILaya3D.Scene3D.cannonPhysicsSettings = new Laya.CannonPhysicsSettings(); + } + } + static set enableDynamicManager(value) { + ILaya3D.SubMeshRenderElement.enableDynamicBatch = value; + } + static get enableDynamicManager() { + return ILaya3D.SubMeshRenderElement.enableDynamicBatch; + } + static set enableStaticManager(value) { + ILaya3D.SubMeshRenderElement.enableStaticBatch = value; + } + static get enableStaticManager() { + return ILaya3D.SubMeshRenderElement.enableStaticBatch; + } + get defaultPhysicsMemory() { + return this._defaultPhysicsMemory; + } + set defaultPhysicsMemory(value) { + if (value < 16) + throw "defaultPhysicsMemory must large than 16M"; + this._defaultPhysicsMemory = value; + } + get maxLightCount() { + return this._maxLightCount; + } + set maxLightCount(value) { + if (value > 2048) { + this._maxLightCount = 2048; + console.warn("Config3D: maxLightCount must less equal 2048."); + } + else { + this._maxLightCount = value; + } + } + get lightClusterCount() { + return this._lightClusterCount; + } + set lightClusterCount(value) { + if (value.x > 128 || value.y > 128 || value.z > 128) { + this._lightClusterCount.setValue(Math.min(value.x, 128), Math.min(value.y, 128), Math.min(value.z, 128)); + console.warn("Config3D: lightClusterCount X and Y、Z must less equal 128."); + } + else { + value.cloneTo(this._lightClusterCount); + } + var maxAreaLightCountWithZ = Math.floor(2048 / this._lightClusterCount.z - 1) * 4; + if (maxAreaLightCountWithZ < this._maxLightCount) + console.warn("Config3D: if the area light(PointLight、SpotLight) count is large than " + maxAreaLightCountWithZ + ",maybe the far away culster will ingonre some light."); + this._maxAreaLightCountPerClusterAverage = Math.min(maxAreaLightCountWithZ, this._maxLightCount); + } + cloneTo(dest) { + var destConfig3D = dest; + destConfig3D._defaultPhysicsMemory = this._defaultPhysicsMemory; + destConfig3D._editerEnvironment = this._editerEnvironment; + destConfig3D.isAntialias = this.isAntialias; + destConfig3D.isAlpha = this.isAlpha; + destConfig3D.premultipliedAlpha = this.premultipliedAlpha; + destConfig3D.isStencil = this.isStencil; + destConfig3D.octreeCulling = this.octreeCulling; + this.octreeInitialCenter.cloneTo(destConfig3D.octreeInitialCenter); + destConfig3D.octreeInitialSize = this.octreeInitialSize; + destConfig3D.octreeMinNodeSize = this.octreeMinNodeSize; + destConfig3D.octreeLooseness = this.octreeLooseness; + destConfig3D.debugFrustumCulling = this.debugFrustumCulling; + destConfig3D.maxLightCount = this.maxLightCount; + destConfig3D.enableMultiLight = this.enableMultiLight; + var lightClusterCount = destConfig3D.lightClusterCount; + this.lightClusterCount.cloneTo(lightClusterCount); + destConfig3D.lightClusterCount = lightClusterCount; + destConfig3D.pbrRenderQuality = this.pbrRenderQuality; + } + clone() { + var dest = new Config3D(); + this.cloneTo(dest); + return dest; + } + } + Config3D._config = new Config3D(); + window.Config3D = Config3D; + + class KeyframeNode { + constructor() { + this._ownerPath = []; + this._propertys = []; + this._keyFrames = []; + } + get ownerPathCount() { + return this._ownerPath.length; + } + get propertyCount() { + return this._propertys.length; + } + get keyFramesCount() { + return this._keyFrames.length; + } + _setOwnerPathCount(value) { + this._ownerPath.length = value; + } + _setOwnerPathByIndex(index, value) { + this._ownerPath[index] = value; + } + _joinOwnerPath(sep) { + return this._ownerPath.join(sep); + } + _setPropertyCount(value) { + this._propertys.length = value; + } + _setPropertyByIndex(index, value) { + this._propertys[index] = value; + } + _joinProperty(sep) { + return this._propertys.join(sep); + } + _setKeyframeCount(value) { + this._keyFrames.length = value; + } + _setKeyframeByIndex(index, value) { + this._keyFrames[index] = value; + } + getOwnerPathByIndex(index) { + return this._ownerPath[index]; + } + getPropertyByIndex(index) { + return this._propertys[index]; + } + getKeyframeByIndex(index) { + return this._keyFrames[index]; + } + } + + class AnimationEvent { + constructor() { + } + } + + class Keyframe { + constructor() { + } + cloneTo(destObject) { + var destKeyFrame = destObject; + destKeyFrame.time = this.time; + } + clone() { + var dest = new Keyframe(); + this.cloneTo(dest); + return dest; + } + } + + class FloatKeyframe extends Keyframe { + constructor() { + super(); + } + cloneTo(destObject) { + super.cloneTo(destObject); + var destKeyFrame = destObject; + destKeyFrame.inTangent = this.inTangent; + destKeyFrame.outTangent = this.outTangent; + destKeyFrame.value = this.value; + } + } + + class Matrix3x3 { + constructor() { + var e = this.elements = new Float32Array(9); + e[0] = 1; + e[1] = 0; + e[2] = 0; + e[3] = 0; + e[4] = 1; + e[5] = 0; + e[6] = 0; + e[7] = 0; + e[8] = 1; + } + static createRotationQuaternion(rotation, out) { + var rotX = rotation.x; + var rotY = rotation.y; + var rotZ = rotation.z; + var rotW = rotation.w; + var xx = rotX * rotX; + var yy = rotY * rotY; + var zz = rotZ * rotZ; + var xy = rotX * rotY; + var zw = rotZ * rotW; + var zx = rotZ * rotX; + var yw = rotY * rotW; + var yz = rotY * rotZ; + var xw = rotX * rotW; + var resultE = out.elements; + resultE[0] = 1.0 - (2.0 * (yy + zz)); + resultE[1] = 2.0 * (xy + zw); + resultE[2] = 2.0 * (zx - yw); + resultE[3] = 2.0 * (xy - zw); + resultE[4] = 1.0 - (2.0 * (zz + xx)); + resultE[5] = 2.0 * (yz + xw); + resultE[6] = 2.0 * (zx + yw); + resultE[7] = 2.0 * (yz - xw); + resultE[8] = 1.0 - (2.0 * (yy + xx)); + } + static createFromTranslation(trans, out) { + var e = out.elements; + e[0] = 1; + e[1] = 0; + e[2] = 0; + e[3] = 0; + e[4] = 1; + e[5] = 0; + e[6] = trans.x; + e[7] = trans.y; + e[8] = 1; + } + static createFromRotation(rad, out) { + var e = out.elements; + var s = Math.sin(rad), c = Math.cos(rad); + e[0] = c; + e[1] = s; + e[2] = 0; + e[3] = -s; + e[4] = c; + e[5] = 0; + e[6] = 0; + e[7] = 0; + e[8] = 1; + } + static createFromScaling(scale, out) { + var e = out.elements; + e[0] = scale.x; + e[1] = 0; + e[2] = 0; + e[3] = 0; + e[4] = scale.y; + e[5] = 0; + e[6] = 0; + e[7] = 0; + e[8] = scale.z; + } + static createFromMatrix4x4(sou, out) { + var souE = sou.elements; + var outE = out.elements; + outE[0] = souE[0]; + outE[1] = souE[1]; + outE[2] = souE[2]; + outE[3] = souE[4]; + outE[4] = souE[5]; + outE[5] = souE[6]; + outE[6] = souE[8]; + outE[7] = souE[9]; + outE[8] = souE[10]; + } + static multiply(left, right, out) { + var l = left.elements; + var r = right.elements; + var e = out.elements; + var l11 = l[0], l12 = l[1], l13 = l[2]; + var l21 = l[3], l22 = l[4], l23 = l[5]; + var l31 = l[6], l32 = l[7], l33 = l[8]; + var r11 = r[0], r12 = r[1], r13 = r[2]; + var r21 = r[3], r22 = r[4], r23 = r[5]; + var r31 = r[6], r32 = r[7], r33 = r[8]; + e[0] = r11 * l11 + r12 * l21 + r13 * l31; + e[1] = r11 * l12 + r12 * l22 + r13 * r32; + e[2] = r11 * l13 + r12 * l23 + r13 * l33; + e[3] = r21 * l11 + r22 * l21 + r23 * l31; + e[4] = r21 * l12 + r22 * l22 + r23 * l32; + e[5] = r21 * l13 + r22 * l23 + r23 * l33; + e[6] = r31 * l11 + r32 * l21 + r33 * l31; + e[7] = r31 * l12 + r32 * l22 + r33 * l32; + e[8] = r31 * l13 + r32 * l23 + r33 * l33; + } + determinant() { + var f = this.elements; + var a00 = f[0], a01 = f[1], a02 = f[2]; + var a10 = f[3], a11 = f[4], a12 = f[5]; + var a20 = f[6], a21 = f[7], a22 = f[8]; + return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20); + } + translate(trans, out) { + var e = out.elements; + var f = this.elements; + var a00 = f[0], a01 = f[1], a02 = f[2]; + var a10 = f[3], a11 = f[4], a12 = f[5]; + var a20 = f[6], a21 = f[7], a22 = f[8]; + var x = trans.x, y = trans.y; + e[0] = a00; + e[1] = a01; + e[2] = a02; + e[3] = a10; + e[4] = a11; + e[5] = a12; + e[6] = x * a00 + y * a10 + a20; + e[7] = x * a01 + y * a11 + a21; + e[8] = x * a02 + y * a12 + a22; + } + rotate(rad, out) { + var e = out.elements; + var f = this.elements; + var a00 = f[0], a01 = f[1], a02 = f[2]; + var a10 = f[3], a11 = f[4], a12 = f[5]; + var a20 = f[6], a21 = f[7], a22 = f[8]; + var s = Math.sin(rad); + var c = Math.cos(rad); + e[0] = c * a00 + s * a10; + e[1] = c * a01 + s * a11; + e[2] = c * a02 + s * a12; + e[3] = c * a10 - s * a00; + e[4] = c * a11 - s * a01; + e[5] = c * a12 - s * a02; + e[6] = a20; + e[7] = a21; + e[8] = a22; + } + scale(scale, out) { + var e = out.elements; + var f = this.elements; + var x = scale.x, y = scale.y; + e[0] = x * f[0]; + e[1] = x * f[1]; + e[2] = x * f[2]; + e[3] = y * f[3]; + e[4] = y * f[4]; + e[5] = y * f[5]; + e[6] = f[6]; + e[7] = f[7]; + e[8] = f[8]; + } + invert(out) { + var e = out.elements; + var f = this.elements; + var a00 = f[0], a01 = f[1], a02 = f[2]; + var a10 = f[3], a11 = f[4], a12 = f[5]; + var a20 = f[6], a21 = f[7], a22 = f[8]; + var b01 = a22 * a11 - a12 * a21; + var b11 = -a22 * a10 + a12 * a20; + var b21 = a21 * a10 - a11 * a20; + var det = a00 * b01 + a01 * b11 + a02 * b21; + if (!det) { + return; + } + det = 1.0 / det; + e[0] = b01 * det; + e[1] = (-a22 * a01 + a02 * a21) * det; + e[2] = (a12 * a01 - a02 * a11) * det; + e[3] = b11 * det; + e[4] = (a22 * a00 - a02 * a20) * det; + e[5] = (-a12 * a00 + a02 * a10) * det; + e[6] = b21 * det; + e[7] = (-a21 * a00 + a01 * a20) * det; + e[8] = (a11 * a00 - a01 * a10) * det; + } + transpose(out) { + var e = out.elements; + var f = this.elements; + if (out === this) { + var a01 = f[1], a02 = f[2], a12 = f[5]; + e[1] = f[3]; + e[2] = f[6]; + e[3] = a01; + e[5] = f[7]; + e[6] = a02; + e[7] = a12; + } + else { + e[0] = f[0]; + e[1] = f[3]; + e[2] = f[6]; + e[3] = f[1]; + e[4] = f[4]; + e[5] = f[7]; + e[6] = f[2]; + e[7] = f[5]; + e[8] = f[8]; + } + } + identity() { + var e = this.elements; + e[0] = 1; + e[1] = 0; + e[2] = 0; + e[3] = 0; + e[4] = 1; + e[5] = 0; + e[6] = 0; + e[7] = 0; + e[8] = 1; + } + cloneTo(destObject) { + var i, s, d; + s = this.elements; + d = destObject.elements; + if (s === d) { + return; + } + for (i = 0; i < 9; ++i) { + d[i] = s[i]; + } + } + clone() { + var dest = new Matrix3x3(); + this.cloneTo(dest); + return dest; + } + static lookAt(eye, target, up, out) { + Vector3.subtract(eye, target, Matrix3x3._tempV30); + Vector3.normalize(Matrix3x3._tempV30, Matrix3x3._tempV30); + Vector3.cross(up, Matrix3x3._tempV30, Matrix3x3._tempV31); + Vector3.normalize(Matrix3x3._tempV31, Matrix3x3._tempV31); + Vector3.cross(Matrix3x3._tempV30, Matrix3x3._tempV31, Matrix3x3._tempV32); + var v0 = Matrix3x3._tempV30; + var v1 = Matrix3x3._tempV31; + var v2 = Matrix3x3._tempV32; + var me = out.elements; + me[0] = v1.x; + me[3] = v1.y; + me[6] = v1.z; + me[1] = v2.x; + me[4] = v2.y; + me[7] = v2.z; + me[2] = v0.x; + me[5] = v0.y; + me[8] = v0.z; + } + } + Matrix3x3.DEFAULT = new Matrix3x3(); + Matrix3x3._tempV30 = new Vector3(); + Matrix3x3._tempV31 = new Vector3(); + Matrix3x3._tempV32 = new Vector3(); + + class Quaternion { + constructor(x = 0, y = 0, z = 0, w = 1) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + static createFromYawPitchRoll(yaw, pitch, roll, out) { + var halfRoll = roll * 0.5; + var halfPitch = pitch * 0.5; + var halfYaw = yaw * 0.5; + var sinRoll = Math.sin(halfRoll); + var cosRoll = Math.cos(halfRoll); + var sinPitch = Math.sin(halfPitch); + var cosPitch = Math.cos(halfPitch); + var sinYaw = Math.sin(halfYaw); + var cosYaw = Math.cos(halfYaw); + out.x = (cosYaw * sinPitch * cosRoll) + (sinYaw * cosPitch * sinRoll); + out.y = (sinYaw * cosPitch * cosRoll) - (cosYaw * sinPitch * sinRoll); + out.z = (cosYaw * cosPitch * sinRoll) - (sinYaw * sinPitch * cosRoll); + out.w = (cosYaw * cosPitch * cosRoll) + (sinYaw * sinPitch * sinRoll); + } + static multiply(left, right, out) { + var lx = left.x; + var ly = left.y; + var lz = left.z; + var lw = left.w; + var rx = right.x; + var ry = right.y; + var rz = right.z; + var rw = right.w; + var a = (ly * rz - lz * ry); + var b = (lz * rx - lx * rz); + var c = (lx * ry - ly * rx); + var d = (lx * rx + ly * ry + lz * rz); + out.x = (lx * rw + rx * lw) + a; + out.y = (ly * rw + ry * lw) + b; + out.z = (lz * rw + rz * lw) + c; + out.w = lw * rw - d; + } + static arcTanAngle(x, y) { + if (x == 0) { + if (y == 1) + return Math.PI / 2; + return -Math.PI / 2; + } + if (x > 0) + return Math.atan(y / x); + if (x < 0) { + if (y > 0) + return Math.atan(y / x) + Math.PI; + return Math.atan(y / x) - Math.PI; + } + return 0; + } + static angleTo(from, location, angle) { + Vector3.subtract(location, from, Quaternion.TEMPVector30); + Vector3.normalize(Quaternion.TEMPVector30, Quaternion.TEMPVector30); + angle.x = Math.asin(Quaternion.TEMPVector30.y); + angle.y = Quaternion.arcTanAngle(-Quaternion.TEMPVector30.z, -Quaternion.TEMPVector30.x); + } + static createFromAxisAngle(axis, rad, out) { + rad = rad * 0.5; + var s = Math.sin(rad); + out.x = s * axis.x; + out.y = s * axis.y; + out.z = s * axis.z; + out.w = Math.cos(rad); + } + static createFromMatrix4x4(mat, out) { + var me = mat.elements; + var sqrt; + var half; + var scale = me[0] + me[5] + me[10]; + if (scale > 0.0) { + sqrt = Math.sqrt(scale + 1.0); + out.w = sqrt * 0.5; + sqrt = 0.5 / sqrt; + out.x = (me[6] - me[9]) * sqrt; + out.y = (me[8] - me[2]) * sqrt; + out.z = (me[1] - me[4]) * sqrt; + } + else if ((me[0] >= me[5]) && (me[0] >= me[10])) { + sqrt = Math.sqrt(1.0 + me[0] - me[5] - me[10]); + half = 0.5 / sqrt; + out.x = 0.5 * sqrt; + out.y = (me[1] + me[4]) * half; + out.z = (me[2] + me[8]) * half; + out.w = (me[6] - me[9]) * half; + } + else if (me[5] > me[10]) { + sqrt = Math.sqrt(1.0 + me[5] - me[0] - me[10]); + half = 0.5 / sqrt; + out.x = (me[4] + me[1]) * half; + out.y = 0.5 * sqrt; + out.z = (me[9] + me[6]) * half; + out.w = (me[8] - me[2]) * half; + } + else { + sqrt = Math.sqrt(1.0 + me[10] - me[0] - me[5]); + half = 0.5 / sqrt; + out.x = (me[8] + me[2]) * half; + out.y = (me[9] + me[6]) * half; + out.z = 0.5 * sqrt; + out.w = (me[1] - me[4]) * half; + } + } + static slerp(left, right, t, out) { + var ax = left.x, ay = left.y, az = left.z, aw = left.w, bx = right.x, by = right.y, bz = right.z, bw = right.w; + var omega, cosom, sinom, scale0, scale1; + cosom = ax * bx + ay * by + az * bz + aw * bw; + if (cosom < 0.0) { + cosom = -cosom; + bx = -bx; + by = -by; + bz = -bz; + bw = -bw; + } + if ((1.0 - cosom) > 0.000001) { + omega = Math.acos(cosom); + sinom = Math.sin(omega); + scale0 = Math.sin((1.0 - t) * omega) / sinom; + scale1 = Math.sin(t * omega) / sinom; + } + else { + scale0 = 1.0 - t; + scale1 = t; + } + out.x = scale0 * ax + scale1 * bx; + out.y = scale0 * ay + scale1 * by; + out.z = scale0 * az + scale1 * bz; + out.w = scale0 * aw + scale1 * bw; + return out; + } + static lerp(left, right, amount, out) { + var inverse = 1.0 - amount; + if (Quaternion.dot(left, right) >= 0) { + out.x = (inverse * left.x) + (amount * right.x); + out.y = (inverse * left.y) + (amount * right.y); + out.z = (inverse * left.z) + (amount * right.z); + out.w = (inverse * left.w) + (amount * right.w); + } + else { + out.x = (inverse * left.x) - (amount * right.x); + out.y = (inverse * left.y) - (amount * right.y); + out.z = (inverse * left.z) - (amount * right.z); + out.w = (inverse * left.w) - (amount * right.w); + } + out.normalize(out); + } + static add(left, right, out) { + out.x = left.x + right.x; + out.y = left.y + right.y; + out.z = left.z + right.z; + out.w = left.w + right.w; + } + static dot(left, right) { + return left.x * right.x + left.y * right.y + left.z * right.z + left.w * right.w; + } + scaling(scaling, out) { + out.x = this.x * scaling; + out.y = this.y * scaling; + out.z = this.z * scaling; + out.w = this.w * scaling; + } + normalize(out) { + var len = this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; + if (len > 0) { + len = 1 / Math.sqrt(len); + out.x = this.x * len; + out.y = this.y * len; + out.z = this.z * len; + out.w = this.w * len; + } + } + length() { + return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w); + } + rotateX(rad, out) { + rad *= 0.5; + var bx = Math.sin(rad), bw = Math.cos(rad); + out.x = this.x * bw + this.w * bx; + out.y = this.y * bw + this.z * bx; + out.z = this.z * bw - this.y * bx; + out.w = this.w * bw - this.x * bx; + } + rotateY(rad, out) { + rad *= 0.5; + var by = Math.sin(rad), bw = Math.cos(rad); + out.x = this.x * bw - this.z * by; + out.y = this.y * bw + this.w * by; + out.z = this.z * bw + this.x * by; + out.w = this.w * bw - this.y * by; + } + rotateZ(rad, out) { + rad *= 0.5; + var bz = Math.sin(rad), bw = Math.cos(rad); + out.x = this.x * bw + this.y * bz; + out.y = this.y * bw - this.x * bz; + out.z = this.z * bw + this.w * bz; + out.w = this.w * bw - this.z * bz; + } + getYawPitchRoll(out) { + Vector3.transformQuat(Vector3._ForwardRH, this, Quaternion.TEMPVector31); + Vector3.transformQuat(Vector3._Up, this, Quaternion.TEMPVector32); + var upe = Quaternion.TEMPVector32; + Quaternion.angleTo(Vector3._ZERO, Quaternion.TEMPVector31, Quaternion.TEMPVector33); + var angle = Quaternion.TEMPVector33; + if (angle.x == Math.PI / 2) { + angle.y = Quaternion.arcTanAngle(upe.z, upe.x); + angle.z = 0; + } + else if (angle.x == -Math.PI / 2) { + angle.y = Quaternion.arcTanAngle(-upe.z, -upe.x); + angle.z = 0; + } + else { + ILaya3D.Matrix4x4.createRotationY(-angle.y, ILaya3D.Matrix4x4.TEMPMatrix0); + ILaya3D.Matrix4x4.createRotationX(-angle.x, ILaya3D.Matrix4x4.TEMPMatrix1); + Vector3.transformCoordinate(Quaternion.TEMPVector32, ILaya3D.Matrix4x4.TEMPMatrix0, Quaternion.TEMPVector32); + Vector3.transformCoordinate(Quaternion.TEMPVector32, ILaya3D.Matrix4x4.TEMPMatrix1, Quaternion.TEMPVector32); + angle.z = Quaternion.arcTanAngle(upe.y, -upe.x); + } + if (angle.y <= -Math.PI) + angle.y = Math.PI; + if (angle.z <= -Math.PI) + angle.z = Math.PI; + if (angle.y >= Math.PI && angle.z >= Math.PI) { + angle.y = 0; + angle.z = 0; + angle.x = Math.PI - angle.x; + } + var oe = out; + oe.x = angle.y; + oe.y = angle.x; + oe.z = angle.z; + } + invert(out) { + var a0 = this.x, a1 = this.y, a2 = this.z, a3 = this.w; + var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3; + var invDot = dot ? 1.0 / dot : 0; + out.x = -a0 * invDot; + out.y = -a1 * invDot; + out.z = -a2 * invDot; + out.w = a3 * invDot; + } + identity() { + this.x = 0; + this.y = 0; + this.z = 0; + this.w = 1; + } + fromArray(array, offset = 0) { + this.x = array[offset + 0]; + this.y = array[offset + 1]; + this.z = array[offset + 2]; + this.w = array[offset + 3]; + } + cloneTo(destObject) { + if (this === destObject) { + return; + } + destObject.x = this.x; + destObject.y = this.y; + destObject.z = this.z; + destObject.w = this.w; + } + clone() { + var dest = new Quaternion(); + this.cloneTo(dest); + return dest; + } + equals(b) { + return MathUtils3D.nearEqual(this.x, b.x) && MathUtils3D.nearEqual(this.y, b.y) && MathUtils3D.nearEqual(this.z, b.z) && MathUtils3D.nearEqual(this.w, b.w); + } + static rotationLookAt(forward, up, out) { + Quaternion.lookAt(Vector3._ZERO, forward, up, out); + } + static lookAt(eye, target, up, out) { + Matrix3x3.lookAt(eye, target, up, Quaternion._tempMatrix3x3); + Quaternion.rotationMatrix(Quaternion._tempMatrix3x3, out); + } + lengthSquared() { + return (this.x * this.x) + (this.y * this.y) + (this.z * this.z) + (this.w * this.w); + } + static invert(value, out) { + var lengthSq = value.lengthSquared(); + if (!MathUtils3D.isZero(lengthSq)) { + lengthSq = 1.0 / lengthSq; + out.x = -value.x * lengthSq; + out.y = -value.y * lengthSq; + out.z = -value.z * lengthSq; + out.w = value.w * lengthSq; + } + } + static rotationMatrix(matrix3x3, out) { + var me = matrix3x3.elements; + var m11 = me[0]; + var m12 = me[1]; + var m13 = me[2]; + var m21 = me[3]; + var m22 = me[4]; + var m23 = me[5]; + var m31 = me[6]; + var m32 = me[7]; + var m33 = me[8]; + var sqrt, half; + var scale = m11 + m22 + m33; + if (scale > 0) { + sqrt = Math.sqrt(scale + 1); + out.w = sqrt * 0.5; + sqrt = 0.5 / sqrt; + out.x = (m23 - m32) * sqrt; + out.y = (m31 - m13) * sqrt; + out.z = (m12 - m21) * sqrt; + } + else if ((m11 >= m22) && (m11 >= m33)) { + sqrt = Math.sqrt(1 + m11 - m22 - m33); + half = 0.5 / sqrt; + out.x = 0.5 * sqrt; + out.y = (m12 + m21) * half; + out.z = (m13 + m31) * half; + out.w = (m23 - m32) * half; + } + else if (m22 > m33) { + sqrt = Math.sqrt(1 + m22 - m11 - m33); + half = 0.5 / sqrt; + out.x = (m21 + m12) * half; + out.y = 0.5 * sqrt; + out.z = (m32 + m23) * half; + out.w = (m31 - m13) * half; + } + else { + sqrt = Math.sqrt(1 + m33 - m11 - m22); + half = 0.5 / sqrt; + out.x = (m31 + m13) * half; + out.y = (m32 + m23) * half; + out.z = 0.5 * sqrt; + out.w = (m12 - m21) * half; + } + } + forNativeElement(nativeElements = null) { + if (nativeElements) { + this.elements = nativeElements; + this.elements[0] = this.x; + this.elements[1] = this.y; + this.elements[2] = this.z; + this.elements[3] = this.w; + } + else { + this.elements = new Float32Array([this.x, this.y, this.z, this.w]); + } + Vector2.rewriteNumProperty(this, "x", 0); + Vector2.rewriteNumProperty(this, "y", 1); + Vector2.rewriteNumProperty(this, "z", 2); + Vector2.rewriteNumProperty(this, "w", 3); + } + } + Quaternion.TEMPVector30 = new Vector3(); + Quaternion.TEMPVector31 = new Vector3(); + Quaternion.TEMPVector32 = new Vector3(); + Quaternion.TEMPVector33 = new Vector3(); + Quaternion._tempMatrix3x3 = new Matrix3x3(); + Quaternion.DEFAULT = new Quaternion(); + Quaternion.NAN = new Quaternion(NaN, NaN, NaN, NaN); + + class QuaternionKeyframe extends Keyframe { + constructor() { + super(); + this.inTangent = new Vector4(); + this.outTangent = new Vector4(); + this.value = new Quaternion(); + } + cloneTo(dest) { + super.cloneTo(dest); + var destKeyFarme = dest; + this.inTangent.cloneTo(destKeyFarme.inTangent); + this.outTangent.cloneTo(destKeyFarme.outTangent); + this.value.cloneTo(destKeyFarme.value); + } + } + + class Vector3Keyframe extends Keyframe { + constructor() { + super(); + this.inTangent = new Vector3(); + this.outTangent = new Vector3(); + this.value = new Vector3(); + } + cloneTo(dest) { + super.cloneTo(dest); + var destKeyFarme = dest; + this.inTangent.cloneTo(destKeyFarme.inTangent); + this.outTangent.cloneTo(destKeyFarme.outTangent); + this.value.cloneTo(destKeyFarme.value); + } + } + + class AnimationClipParser03 { + static READ_DATA() { + AnimationClipParser03._DATA.offset = AnimationClipParser03._reader.getUint32(); + AnimationClipParser03._DATA.size = AnimationClipParser03._reader.getUint32(); + } + static READ_BLOCK() { + var count = AnimationClipParser03._BLOCK.count = AnimationClipParser03._reader.getUint16(); + var blockStarts = AnimationClipParser03._BLOCK.blockStarts = []; + var blockLengths = AnimationClipParser03._BLOCK.blockLengths = []; + for (var i = 0; i < count; i++) { + blockStarts.push(AnimationClipParser03._reader.getUint32()); + blockLengths.push(AnimationClipParser03._reader.getUint32()); + } + } + static READ_STRINGS() { + var offset = AnimationClipParser03._reader.getUint32(); + var count = AnimationClipParser03._reader.getUint16(); + var prePos = AnimationClipParser03._reader.pos; + AnimationClipParser03._reader.pos = offset + AnimationClipParser03._DATA.offset; + for (var i = 0; i < count; i++) + AnimationClipParser03._strings[i] = AnimationClipParser03._reader.readUTFString(); + AnimationClipParser03._reader.pos = prePos; + } + static parse(clip, reader) { + AnimationClipParser03._animationClip = clip; + AnimationClipParser03._reader = reader; + AnimationClipParser03.READ_DATA(); + AnimationClipParser03.READ_BLOCK(); + AnimationClipParser03.READ_STRINGS(); + for (var i = 0, n = AnimationClipParser03._BLOCK.count; i < n; i++) { + var index = reader.getUint16(); + var blockName = AnimationClipParser03._strings[index]; + var fn = AnimationClipParser03["READ_" + blockName]; + if (fn == null) + throw new Error("model file err,no this function:" + index + " " + blockName); + else + fn.call(null); + } + } + static READ_ANIMATIONS() { + var i, j; + var node; + var reader = AnimationClipParser03._reader; + var startTimeTypes = []; + var startTimeTypeCount = reader.getUint16(); + startTimeTypes.length = startTimeTypeCount; + for (i = 0; i < startTimeTypeCount; i++) + startTimeTypes[i] = reader.getFloat32(); + var clip = AnimationClipParser03._animationClip; + clip.name = AnimationClipParser03._strings[reader.getUint16()]; + var clipDur = clip._duration = reader.getFloat32(); + clip.islooping = !!reader.getByte(); + clip._frameRate = reader.getInt16(); + var nodeCount = reader.getInt16(); + var nodes = clip._nodes; + nodes.count = nodeCount; + var nodesMap = clip._nodesMap = {}; + var nodesDic = clip._nodesDic = {}; + for (i = 0; i < nodeCount; i++) { + node = new KeyframeNode(); + nodes.setNodeByIndex(i, node); + node._indexInList = i; + var type = node.type = reader.getUint8(); + var pathLength = reader.getUint16(); + node._setOwnerPathCount(pathLength); + for (j = 0; j < pathLength; j++) + node._setOwnerPathByIndex(j, AnimationClipParser03._strings[reader.getUint16()]); + var nodePath = node._joinOwnerPath("/"); + var mapArray = nodesMap[nodePath]; + (mapArray) || (nodesMap[nodePath] = mapArray = []); + mapArray.push(node); + node.propertyOwner = AnimationClipParser03._strings[reader.getUint16()]; + var propertyLength = reader.getUint16(); + node._setPropertyCount(propertyLength); + for (j = 0; j < propertyLength; j++) + node._setPropertyByIndex(j, AnimationClipParser03._strings[reader.getUint16()]); + var fullPath = nodePath + "." + node.propertyOwner + "." + node._joinProperty("."); + nodesDic[fullPath] = node; + node.fullPath = fullPath; + var keyframeCount = reader.getUint16(); + node._setKeyframeCount(keyframeCount); + for (j = 0; j < keyframeCount; j++) { + switch (type) { + case 0: + var floatKeyframe = new FloatKeyframe(); + node._setKeyframeByIndex(j, floatKeyframe); + floatKeyframe.time = startTimeTypes[reader.getUint16()]; + floatKeyframe.inTangent = reader.getFloat32(); + floatKeyframe.outTangent = reader.getFloat32(); + floatKeyframe.value = reader.getFloat32(); + break; + case 1: + case 3: + case 4: + var floatArrayKeyframe = new Vector3Keyframe(); + node._setKeyframeByIndex(j, floatArrayKeyframe); + floatArrayKeyframe.time = startTimeTypes[reader.getUint16()]; + var inTangent = floatArrayKeyframe.inTangent; + var outTangent = floatArrayKeyframe.outTangent; + var value = floatArrayKeyframe.value; + inTangent.x = reader.getFloat32(); + inTangent.y = reader.getFloat32(); + inTangent.z = reader.getFloat32(); + outTangent.x = reader.getFloat32(); + outTangent.y = reader.getFloat32(); + outTangent.z = reader.getFloat32(); + value.x = reader.getFloat32(); + value.y = reader.getFloat32(); + value.z = reader.getFloat32(); + break; + case 2: + var quaArrayKeyframe = new QuaternionKeyframe(); + node._setKeyframeByIndex(j, quaArrayKeyframe); + quaArrayKeyframe.time = startTimeTypes[reader.getUint16()]; + var inTangentQua = quaArrayKeyframe.inTangent; + var outTangentQua = quaArrayKeyframe.outTangent; + var valueQua = quaArrayKeyframe.value; + inTangentQua.x = reader.getFloat32(); + inTangentQua.y = reader.getFloat32(); + inTangentQua.z = reader.getFloat32(); + inTangentQua.w = reader.getFloat32(); + outTangentQua.x = reader.getFloat32(); + outTangentQua.y = reader.getFloat32(); + outTangentQua.z = reader.getFloat32(); + outTangentQua.w = reader.getFloat32(); + valueQua.x = reader.getFloat32(); + valueQua.y = reader.getFloat32(); + valueQua.z = reader.getFloat32(); + valueQua.w = reader.getFloat32(); + break; + default: + throw "AnimationClipParser03:unknown type."; + } + } + } + var eventCount = reader.getUint16(); + for (i = 0; i < eventCount; i++) { + var event = new AnimationEvent(); + event.time = Math.min(clipDur, reader.getFloat32()); + event.eventName = AnimationClipParser03._strings[reader.getUint16()]; + var params = []; + var paramCount = reader.getUint16(); + (paramCount > 0) && (event.params = params = []); + for (j = 0; j < paramCount; j++) { + var eventType = reader.getByte(); + switch (eventType) { + case 0: + params.push(!!reader.getByte()); + break; + case 1: + params.push(reader.getInt32()); + break; + case 2: + params.push(reader.getFloat32()); + break; + case 3: + params.push(AnimationClipParser03._strings[reader.getUint16()]); + break; + default: + throw new Error("unknown type."); + } + } + clip.addEvent(event); + } + } + } + AnimationClipParser03._strings = []; + AnimationClipParser03._BLOCK = { count: 0 }; + AnimationClipParser03._DATA = { offset: 0, size: 0 }; + + class AnimationClipParser04 { + static READ_DATA() { + AnimationClipParser04._DATA.offset = AnimationClipParser04._reader.getUint32(); + AnimationClipParser04._DATA.size = AnimationClipParser04._reader.getUint32(); + } + static READ_BLOCK() { + var count = AnimationClipParser04._BLOCK.count = AnimationClipParser04._reader.getUint16(); + var blockStarts = AnimationClipParser04._BLOCK.blockStarts = []; + var blockLengths = AnimationClipParser04._BLOCK.blockLengths = []; + for (var i = 0; i < count; i++) { + blockStarts.push(AnimationClipParser04._reader.getUint32()); + blockLengths.push(AnimationClipParser04._reader.getUint32()); + } + } + static READ_STRINGS() { + var offset = AnimationClipParser04._reader.getUint32(); + var count = AnimationClipParser04._reader.getUint16(); + var prePos = AnimationClipParser04._reader.pos; + AnimationClipParser04._reader.pos = offset + AnimationClipParser04._DATA.offset; + for (var i = 0; i < count; i++) + AnimationClipParser04._strings[i] = AnimationClipParser04._reader.readUTFString(); + AnimationClipParser04._reader.pos = prePos; + } + static parse(clip, reader, version) { + AnimationClipParser04._animationClip = clip; + AnimationClipParser04._reader = reader; + AnimationClipParser04._version = version; + AnimationClipParser04.READ_DATA(); + AnimationClipParser04.READ_BLOCK(); + AnimationClipParser04.READ_STRINGS(); + for (var i = 0, n = AnimationClipParser04._BLOCK.count; i < n; i++) { + var index = reader.getUint16(); + var blockName = AnimationClipParser04._strings[index]; + var fn = AnimationClipParser04["READ_" + blockName]; + if (fn == null) + throw new Error("model file err,no this function:" + index + " " + blockName); + else + fn.call(null); + } + AnimationClipParser04._version = null; + AnimationClipParser04._reader = null; + AnimationClipParser04._animationClip = null; + } + static READ_ANIMATIONS() { + var i, j; + var node; + var reader = AnimationClipParser04._reader; + var startTimeTypes = []; + var startTimeTypeCount = reader.getUint16(); + startTimeTypes.length = startTimeTypeCount; + for (i = 0; i < startTimeTypeCount; i++) + startTimeTypes[i] = reader.getFloat32(); + var clip = AnimationClipParser04._animationClip; + clip.name = AnimationClipParser04._strings[reader.getUint16()]; + var clipDur = clip._duration = reader.getFloat32(); + clip.islooping = !!reader.getByte(); + clip._frameRate = reader.getInt16(); + var nodeCount = reader.getInt16(); + var nodes = clip._nodes; + nodes.count = nodeCount; + var nodesMap = clip._nodesMap = {}; + var nodesDic = clip._nodesDic = {}; + for (i = 0; i < nodeCount; i++) { + node = new KeyframeNode(); + nodes.setNodeByIndex(i, node); + node._indexInList = i; + var type = node.type = reader.getUint8(); + var pathLength = reader.getUint16(); + node._setOwnerPathCount(pathLength); + for (j = 0; j < pathLength; j++) + node._setOwnerPathByIndex(j, AnimationClipParser04._strings[reader.getUint16()]); + var nodePath = node._joinOwnerPath("/"); + var mapArray = nodesMap[nodePath]; + (mapArray) || (nodesMap[nodePath] = mapArray = []); + mapArray.push(node); + node.propertyOwner = AnimationClipParser04._strings[reader.getUint16()]; + var propertyLength = reader.getUint16(); + node._setPropertyCount(propertyLength); + for (j = 0; j < propertyLength; j++) + node._setPropertyByIndex(j, AnimationClipParser04._strings[reader.getUint16()]); + var fullPath = nodePath + "." + node.propertyOwner + "." + node._joinProperty("."); + nodesDic[fullPath] = node; + node.fullPath = fullPath; + node.nodePath = nodePath; + var keyframeCount = reader.getUint16(); + node._setKeyframeCount(keyframeCount); + switch (AnimationClipParser04._version) { + case "LAYAANIMATION:04": + for (j = 0; j < keyframeCount; j++) { + switch (type) { + case 0: + var floatKeyframe = new FloatKeyframe(); + node._setKeyframeByIndex(j, floatKeyframe); + floatKeyframe.time = startTimeTypes[reader.getUint16()]; + floatKeyframe.inTangent = reader.getFloat32(); + floatKeyframe.outTangent = reader.getFloat32(); + floatKeyframe.value = reader.getFloat32(); + break; + case 1: + case 3: + case 4: + var floatArrayKeyframe = new Vector3Keyframe(); + node._setKeyframeByIndex(j, floatArrayKeyframe); + floatArrayKeyframe.time = startTimeTypes[reader.getUint16()]; + var inTangent = floatArrayKeyframe.inTangent; + var outTangent = floatArrayKeyframe.outTangent; + var value = floatArrayKeyframe.value; + inTangent.x = reader.getFloat32(); + inTangent.y = reader.getFloat32(); + inTangent.z = reader.getFloat32(); + outTangent.x = reader.getFloat32(); + outTangent.y = reader.getFloat32(); + outTangent.z = reader.getFloat32(); + value.x = reader.getFloat32(); + value.y = reader.getFloat32(); + value.z = reader.getFloat32(); + break; + case 2: + var quaternionKeyframe = new QuaternionKeyframe(); + node._setKeyframeByIndex(j, quaternionKeyframe); + quaternionKeyframe.time = startTimeTypes[reader.getUint16()]; + var inTangentQua = quaternionKeyframe.inTangent; + var outTangentQua = quaternionKeyframe.outTangent; + var valueQua = quaternionKeyframe.value; + inTangentQua.x = reader.getFloat32(); + inTangentQua.y = reader.getFloat32(); + inTangentQua.z = reader.getFloat32(); + inTangentQua.w = reader.getFloat32(); + outTangentQua.x = reader.getFloat32(); + outTangentQua.y = reader.getFloat32(); + outTangentQua.z = reader.getFloat32(); + outTangentQua.w = reader.getFloat32(); + valueQua.x = reader.getFloat32(); + valueQua.y = reader.getFloat32(); + valueQua.z = reader.getFloat32(); + valueQua.w = reader.getFloat32(); + break; + default: + throw "AnimationClipParser04:unknown type."; + } + } + break; + case "LAYAANIMATION:COMPRESSION_04": + for (j = 0; j < keyframeCount; j++) { + switch (type) { + case 0: + floatKeyframe = new FloatKeyframe(); + node._setKeyframeByIndex(j, floatKeyframe); + floatKeyframe.time = startTimeTypes[reader.getUint16()]; + floatKeyframe.inTangent = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + floatKeyframe.outTangent = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + floatKeyframe.value = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + break; + case 1: + case 3: + case 4: + floatArrayKeyframe = new Vector3Keyframe(); + node._setKeyframeByIndex(j, floatArrayKeyframe); + floatArrayKeyframe.time = startTimeTypes[reader.getUint16()]; + inTangent = floatArrayKeyframe.inTangent; + outTangent = floatArrayKeyframe.outTangent; + value = floatArrayKeyframe.value; + inTangent.x = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + inTangent.y = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + inTangent.z = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + outTangent.x = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + outTangent.y = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + outTangent.z = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + value.x = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + value.y = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + value.z = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + break; + case 2: + quaternionKeyframe = new QuaternionKeyframe(); + node._setKeyframeByIndex(j, quaternionKeyframe); + quaternionKeyframe.time = startTimeTypes[reader.getUint16()]; + inTangentQua = quaternionKeyframe.inTangent; + outTangentQua = quaternionKeyframe.outTangent; + valueQua = quaternionKeyframe.value; + inTangentQua.x = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + inTangentQua.y = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + inTangentQua.z = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + inTangentQua.w = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + outTangentQua.x = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + outTangentQua.y = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + outTangentQua.z = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + outTangentQua.w = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + valueQua.x = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + valueQua.y = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + valueQua.z = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + valueQua.w = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + break; + default: + throw "AnimationClipParser04:unknown type."; + } + } + break; + } + } + var eventCount = reader.getUint16(); + for (i = 0; i < eventCount; i++) { + var event = new AnimationEvent(); + event.time = Math.min(clipDur, reader.getFloat32()); + event.eventName = AnimationClipParser04._strings[reader.getUint16()]; + var params = []; + var paramCount = reader.getUint16(); + (paramCount > 0) && (event.params = params = []); + for (j = 0; j < paramCount; j++) { + var eventType = reader.getByte(); + switch (eventType) { + case 0: + params.push(!!reader.getByte()); + break; + case 1: + params.push(reader.getInt32()); + break; + case 2: + params.push(reader.getFloat32()); + break; + case 3: + params.push(AnimationClipParser04._strings[reader.getUint16()]); + break; + default: + throw new Error("unknown type."); + } + } + clip.addEvent(event); + } + } + } + AnimationClipParser04._strings = []; + AnimationClipParser04._BLOCK = { count: 0 }; + AnimationClipParser04._DATA = { offset: 0, size: 0 }; + + class KeyframeNodeList { + constructor() { + this._nodes = []; + } + get count() { + return this._nodes.length; + } + set count(value) { + this._nodes.length = value; + } + getNodeByIndex(index) { + return this._nodes[index]; + } + setNodeByIndex(index, node) { + this._nodes[index] = node; + } + } + + class TextureGenerator { + constructor() { + } + static lightAttenTexture(x, y, maxX, maxY, index, data) { + var sqrRange = x / maxX; + var atten = 1.0 / (1.0 + 25.0 * sqrRange); + if (sqrRange >= 0.64) { + if (sqrRange > 1.0) { + atten = 0; + } + else { + atten *= 1 - (sqrRange - 0.64) / (1 - 0.64); + } + } + data[index] = Math.floor(atten * 255.0 + 0.5); + } + static haloTexture(x, y, maxX, maxY, index, data) { + maxX >>= 1; + maxY >>= 1; + var xFac = (x - maxX) / maxX; + var yFac = (y - maxY) / maxY; + var sqrRange = xFac * xFac + yFac * yFac; + if (sqrRange > 1.0) { + sqrRange = 1.0; + } + data[index] = Math.floor((1.0 - sqrRange) * 255.0 + 0.5); + } + static _generateTexture2D(texture, textureWidth, textureHeight, func) { + var index = 0; + var size = 0; + switch (texture.format) { + case Laya.TextureFormat.R8G8B8: + size = 3; + break; + case Laya.TextureFormat.R8G8B8A8: + size = 4; + break; + case Laya.TextureFormat.Alpha8: + size = 1; + break; + default: + throw "GeneratedTexture._generateTexture: unkonw texture format."; + } + var data = new Uint8Array(textureWidth * textureHeight * size); + for (var y = 0; y < textureHeight; y++) { + for (var x = 0; x < textureWidth; x++) { + func(x, y, textureWidth, textureHeight, index, data); + index += size; + } + } + texture.setPixels(data); + } + } + + class Utils3D { + static _createFloatTextureBuffer(width, height) { + var floatTex = new Laya.Texture2D(width, height, Laya.TextureFormat.R32G32B32A32, false, false); + floatTex.filterMode = Laya.FilterMode.Point; + floatTex.wrapModeU = Laya.WarpMode.Clamp; + floatTex.wrapModeV = Laya.WarpMode.Clamp; + floatTex.anisoLevel = 0; + return floatTex; + } + static _convertToLayaVec3(bVector, out, inverseX) { + var bullet = ILaya3D.Physics3D._bullet; + out.x = inverseX ? -bullet.btVector3_x(bVector) : bullet.btVector3_x(bVector); + out.y = bullet.btVector3_y(bVector); + out.z = bullet.btVector3_z(bVector); + } + static _convertToBulletVec3(lVector, out, inverseX) { + ILaya3D.Physics3D._bullet.btVector3_setValue(out, inverseX ? -lVector.x : lVector.x, lVector.y, lVector.z); + } + static _rotationTransformScaleSkinAnimation(tx, ty, tz, qx, qy, qz, qw, sx, sy, sz, outArray, outOffset) { + var re = Utils3D._tempArray16_0; + var se = Utils3D._tempArray16_1; + var tse = Utils3D._tempArray16_2; + var x2 = qx + qx; + var y2 = qy + qy; + var z2 = qz + qz; + var xx = qx * x2; + var yx = qy * x2; + var yy = qy * y2; + var zx = qz * x2; + var zy = qz * y2; + var zz = qz * z2; + var wx = qw * x2; + var wy = qw * y2; + var wz = qw * z2; + re[15] = 1; + re[0] = 1 - yy - zz; + re[1] = yx + wz; + re[2] = zx - wy; + re[4] = yx - wz; + re[5] = 1 - xx - zz; + re[6] = zy + wx; + re[8] = zx + wy; + re[9] = zy - wx; + re[10] = 1 - xx - yy; + se[15] = 1; + se[0] = sx; + se[5] = sy; + se[10] = sz; + var i, ai0, ai1, ai2, ai3; + for (i = 0; i < 4; i++) { + ai0 = re[i]; + ai1 = re[i + 4]; + ai2 = re[i + 8]; + ai3 = re[i + 12]; + tse[i] = ai0; + tse[i + 4] = ai1; + tse[i + 8] = ai2; + tse[i + 12] = ai0 * tx + ai1 * ty + ai2 * tz + ai3; + } + for (i = 0; i < 4; i++) { + ai0 = tse[i]; + ai1 = tse[i + 4]; + ai2 = tse[i + 8]; + ai3 = tse[i + 12]; + outArray[i + outOffset] = ai0 * se[0] + ai1 * se[1] + ai2 * se[2] + ai3 * se[3]; + outArray[i + outOffset + 4] = ai0 * se[4] + ai1 * se[5] + ai2 * se[6] + ai3 * se[7]; + outArray[i + outOffset + 8] = ai0 * se[8] + ai1 * se[9] + ai2 * se[10] + ai3 * se[11]; + outArray[i + outOffset + 12] = ai0 * se[12] + ai1 * se[13] + ai2 * se[14] + ai3 * se[15]; + } + } + static _computeBoneAndAnimationDatasByBindPoseMatrxix(bones, curData, inverGlobalBindPose, outBonesDatas, outAnimationDatas, boneIndexToMesh) { + var offset = 0; + var matOffset = 0; + var i; + var parentOffset; + var boneLength = bones.length; + for (i = 0; i < boneLength; offset += bones[i].keyframeWidth, matOffset += 16, i++) { + Utils3D._rotationTransformScaleSkinAnimation(curData[offset + 0], curData[offset + 1], curData[offset + 2], curData[offset + 3], curData[offset + 4], curData[offset + 5], curData[offset + 6], curData[offset + 7], curData[offset + 8], curData[offset + 9], outBonesDatas, matOffset); + if (i != 0) { + parentOffset = bones[i].parentIndex * 16; + Utils3D.mulMatrixByArray(outBonesDatas, parentOffset, outBonesDatas, matOffset, outBonesDatas, matOffset); + } + } + var n = inverGlobalBindPose.length; + for (i = 0; i < n; i++) { + Utils3D.mulMatrixByArrayAndMatrixFast(outBonesDatas, boneIndexToMesh[i] * 16, inverGlobalBindPose[i], outAnimationDatas, i * 16); + } + } + static _computeAnimationDatasByArrayAndMatrixFast(inverGlobalBindPose, bonesDatas, outAnimationDatas, boneIndexToMesh) { + for (var i = 0, n = inverGlobalBindPose.length; i < n; i++) + Utils3D.mulMatrixByArrayAndMatrixFast(bonesDatas, boneIndexToMesh[i] * 16, inverGlobalBindPose[i], outAnimationDatas, i * 16); + } + static _computeBoneAndAnimationDatasByBindPoseMatrxixOld(bones, curData, inverGlobalBindPose, outBonesDatas, outAnimationDatas) { + var offset = 0; + var matOffset = 0; + var i; + var parentOffset; + var boneLength = bones.length; + for (i = 0; i < boneLength; offset += bones[i].keyframeWidth, matOffset += 16, i++) { + Utils3D._rotationTransformScaleSkinAnimation(curData[offset + 7], curData[offset + 8], curData[offset + 9], curData[offset + 3], curData[offset + 4], curData[offset + 5], curData[offset + 6], curData[offset + 0], curData[offset + 1], curData[offset + 2], outBonesDatas, matOffset); + if (i != 0) { + parentOffset = bones[i].parentIndex * 16; + Utils3D.mulMatrixByArray(outBonesDatas, parentOffset, outBonesDatas, matOffset, outBonesDatas, matOffset); + } + } + var n = inverGlobalBindPose.length; + for (i = 0; i < n; i++) { + var arrayOffset = i * 16; + Utils3D.mulMatrixByArrayAndMatrixFast(outBonesDatas, arrayOffset, inverGlobalBindPose[i], outAnimationDatas, arrayOffset); + } + } + static _computeAnimationDatasByArrayAndMatrixFastOld(inverGlobalBindPose, bonesDatas, outAnimationDatas) { + var n = inverGlobalBindPose.length; + for (var i = 0; i < n; i++) { + var arrayOffset = i * 16; + Utils3D.mulMatrixByArrayAndMatrixFast(bonesDatas, arrayOffset, inverGlobalBindPose[i], outAnimationDatas, arrayOffset); + } + } + static _computeRootAnimationData(bones, curData, animationDatas) { + for (var i = 0, offset = 0, matOffset = 0, boneLength = bones.length; i < boneLength; offset += bones[i].keyframeWidth, matOffset += 16, i++) + Utils3D.createAffineTransformationArray(curData[offset + 0], curData[offset + 1], curData[offset + 2], curData[offset + 3], curData[offset + 4], curData[offset + 5], curData[offset + 6], curData[offset + 7], curData[offset + 8], curData[offset + 9], animationDatas, matOffset); + } + static transformVector3ArrayByQuat(sourceArray, sourceOffset, rotation, outArray, outOffset) { + var x = sourceArray[sourceOffset], y = sourceArray[sourceOffset + 1], z = sourceArray[sourceOffset + 2], qx = rotation.x, qy = rotation.y, qz = rotation.z, qw = rotation.w, ix = qw * x + qy * z - qz * y, iy = qw * y + qz * x - qx * z, iz = qw * z + qx * y - qy * x, iw = -qx * x - qy * y - qz * z; + outArray[outOffset] = ix * qw + iw * -qx + iy * -qz - iz * -qy; + outArray[outOffset + 1] = iy * qw + iw * -qy + iz * -qx - ix * -qz; + outArray[outOffset + 2] = iz * qw + iw * -qz + ix * -qy - iy * -qx; + } + static mulMatrixByArray(leftArray, leftOffset, rightArray, rightOffset, outArray, outOffset) { + var i, ai0, ai1, ai2, ai3; + if (outArray === rightArray) { + rightArray = Utils3D._tempArray16_3; + for (i = 0; i < 16; ++i) { + rightArray[i] = outArray[outOffset + i]; + } + rightOffset = 0; + } + for (i = 0; i < 4; i++) { + ai0 = leftArray[leftOffset + i]; + ai1 = leftArray[leftOffset + i + 4]; + ai2 = leftArray[leftOffset + i + 8]; + ai3 = leftArray[leftOffset + i + 12]; + outArray[outOffset + i] = ai0 * rightArray[rightOffset + 0] + ai1 * rightArray[rightOffset + 1] + ai2 * rightArray[rightOffset + 2] + ai3 * rightArray[rightOffset + 3]; + outArray[outOffset + i + 4] = ai0 * rightArray[rightOffset + 4] + ai1 * rightArray[rightOffset + 5] + ai2 * rightArray[rightOffset + 6] + ai3 * rightArray[rightOffset + 7]; + outArray[outOffset + i + 8] = ai0 * rightArray[rightOffset + 8] + ai1 * rightArray[rightOffset + 9] + ai2 * rightArray[rightOffset + 10] + ai3 * rightArray[rightOffset + 11]; + outArray[outOffset + i + 12] = ai0 * rightArray[rightOffset + 12] + ai1 * rightArray[rightOffset + 13] + ai2 * rightArray[rightOffset + 14] + ai3 * rightArray[rightOffset + 15]; + } + } + static mulMatrixByArrayFast(leftArray, leftOffset, rightArray, rightOffset, outArray, outOffset) { + var i, ai0, ai1, ai2, ai3; + for (i = 0; i < 4; i++) { + ai0 = leftArray[leftOffset + i]; + ai1 = leftArray[leftOffset + i + 4]; + ai2 = leftArray[leftOffset + i + 8]; + ai3 = leftArray[leftOffset + i + 12]; + outArray[outOffset + i] = ai0 * rightArray[rightOffset + 0] + ai1 * rightArray[rightOffset + 1] + ai2 * rightArray[rightOffset + 2] + ai3 * rightArray[rightOffset + 3]; + outArray[outOffset + i + 4] = ai0 * rightArray[rightOffset + 4] + ai1 * rightArray[rightOffset + 5] + ai2 * rightArray[rightOffset + 6] + ai3 * rightArray[rightOffset + 7]; + outArray[outOffset + i + 8] = ai0 * rightArray[rightOffset + 8] + ai1 * rightArray[rightOffset + 9] + ai2 * rightArray[rightOffset + 10] + ai3 * rightArray[rightOffset + 11]; + outArray[outOffset + i + 12] = ai0 * rightArray[rightOffset + 12] + ai1 * rightArray[rightOffset + 13] + ai2 * rightArray[rightOffset + 14] + ai3 * rightArray[rightOffset + 15]; + } + } + static mulMatrixByArrayAndMatrixFast(leftArray, leftOffset, rightMatrix, outArray, outOffset) { + var i, ai0, ai1, ai2, ai3; + var rightMatrixE = rightMatrix.elements; + var m11 = rightMatrixE[0], m12 = rightMatrixE[1], m13 = rightMatrixE[2], m14 = rightMatrixE[3]; + var m21 = rightMatrixE[4], m22 = rightMatrixE[5], m23 = rightMatrixE[6], m24 = rightMatrixE[7]; + var m31 = rightMatrixE[8], m32 = rightMatrixE[9], m33 = rightMatrixE[10], m34 = rightMatrixE[11]; + var m41 = rightMatrixE[12], m42 = rightMatrixE[13], m43 = rightMatrixE[14], m44 = rightMatrixE[15]; + var ai0LeftOffset = leftOffset; + var ai1LeftOffset = leftOffset + 4; + var ai2LeftOffset = leftOffset + 8; + var ai3LeftOffset = leftOffset + 12; + var ai0OutOffset = outOffset; + var ai1OutOffset = outOffset + 4; + var ai2OutOffset = outOffset + 8; + var ai3OutOffset = outOffset + 12; + for (i = 0; i < 4; i++) { + ai0 = leftArray[ai0LeftOffset + i]; + ai1 = leftArray[ai1LeftOffset + i]; + ai2 = leftArray[ai2LeftOffset + i]; + ai3 = leftArray[ai3LeftOffset + i]; + outArray[ai0OutOffset + i] = ai0 * m11 + ai1 * m12 + ai2 * m13 + ai3 * m14; + outArray[ai1OutOffset + i] = ai0 * m21 + ai1 * m22 + ai2 * m23 + ai3 * m24; + outArray[ai2OutOffset + i] = ai0 * m31 + ai1 * m32 + ai2 * m33 + ai3 * m34; + outArray[ai3OutOffset + i] = ai0 * m41 + ai1 * m42 + ai2 * m43 + ai3 * m44; + } + } + static createAffineTransformationArray(tX, tY, tZ, rX, rY, rZ, rW, sX, sY, sZ, outArray, outOffset) { + var x2 = rX + rX, y2 = rY + rY, z2 = rZ + rZ; + var xx = rX * x2, xy = rX * y2, xz = rX * z2, yy = rY * y2, yz = rY * z2, zz = rZ * z2; + var wx = rW * x2, wy = rW * y2, wz = rW * z2; + outArray[outOffset + 0] = (1 - (yy + zz)) * sX; + outArray[outOffset + 1] = (xy + wz) * sX; + outArray[outOffset + 2] = (xz - wy) * sX; + outArray[outOffset + 3] = 0; + outArray[outOffset + 4] = (xy - wz) * sY; + outArray[outOffset + 5] = (1 - (xx + zz)) * sY; + outArray[outOffset + 6] = (yz + wx) * sY; + outArray[outOffset + 7] = 0; + outArray[outOffset + 8] = (xz + wy) * sZ; + outArray[outOffset + 9] = (yz - wx) * sZ; + outArray[outOffset + 10] = (1 - (xx + yy)) * sZ; + outArray[outOffset + 11] = 0; + outArray[outOffset + 12] = tX; + outArray[outOffset + 13] = tY; + outArray[outOffset + 14] = tZ; + outArray[outOffset + 15] = 1; + } + static transformVector3ArrayToVector3ArrayCoordinate(source, sourceOffset, transform, result, resultOffset) { + var coordinateX = source[sourceOffset + 0]; + var coordinateY = source[sourceOffset + 1]; + var coordinateZ = source[sourceOffset + 2]; + var transformElem = transform.elements; + var w = ((coordinateX * transformElem[3]) + (coordinateY * transformElem[7]) + (coordinateZ * transformElem[11]) + transformElem[15]); + result[resultOffset] = (coordinateX * transformElem[0]) + (coordinateY * transformElem[4]) + (coordinateZ * transformElem[8]) + transformElem[12] / w; + result[resultOffset + 1] = (coordinateX * transformElem[1]) + (coordinateY * transformElem[5]) + (coordinateZ * transformElem[9]) + transformElem[13] / w; + result[resultOffset + 2] = (coordinateX * transformElem[2]) + (coordinateY * transformElem[6]) + (coordinateZ * transformElem[10]) + transformElem[14] / w; + } + static transformVector3ArrayToVector3ArrayNormal(source, sourceOffset, transform, result, resultOffset) { + var coordinateX = source[sourceOffset + 0]; + var coordinateY = source[sourceOffset + 1]; + var coordinateZ = source[sourceOffset + 2]; + var transformElem = transform.elements; + result[resultOffset] = coordinateX * transformElem[0] + coordinateY * transformElem[4] + coordinateZ * transformElem[8]; + result[resultOffset + 1] = coordinateX * transformElem[1] + coordinateY * transformElem[5] + coordinateZ * transformElem[9]; + result[resultOffset + 2] = coordinateX * transformElem[2] + coordinateY * transformElem[6] + coordinateZ * transformElem[10]; + } + static transformLightingMapTexcoordArray(source, sourceOffset, lightingMapScaleOffset, result, resultOffset) { + result[resultOffset + 0] = source[sourceOffset + 0] * lightingMapScaleOffset.x + lightingMapScaleOffset.z; + result[resultOffset + 1] = 1.0 - ((1.0 - source[sourceOffset + 1]) * lightingMapScaleOffset.y + lightingMapScaleOffset.w); + } + static getURLVerion(url) { + var index = url.indexOf("?"); + return index >= 0 ? url.substr(index) : null; + } + static _createAffineTransformationArray(trans, rot, scale, outE) { + var x = rot.x, y = rot.y, z = rot.z, w = rot.w, x2 = x + x, y2 = y + y, z2 = z + z; + var xx = x * x2, xy = x * y2, xz = x * z2, yy = y * y2, yz = y * z2, zz = z * z2; + var wx = w * x2, wy = w * y2, wz = w * z2, sx = scale.x, sy = scale.y, sz = scale.z; + outE[0] = (1 - (yy + zz)) * sx; + outE[1] = (xy + wz) * sx; + outE[2] = (xz - wy) * sx; + outE[3] = 0; + outE[4] = (xy - wz) * sy; + outE[5] = (1 - (xx + zz)) * sy; + outE[6] = (yz + wx) * sy; + outE[7] = 0; + outE[8] = (xz + wy) * sz; + outE[9] = (yz - wx) * sz; + outE[10] = (1 - (xx + yy)) * sz; + outE[11] = 0; + outE[12] = trans.x; + outE[13] = trans.y; + outE[14] = trans.z; + outE[15] = 1; + } + static _mulMatrixArray(left, right, rightOffset, outArray, outOffset) { + var l = right; + var r = left; + var e = outArray; + var l11 = l[rightOffset], l12 = l[rightOffset + 1], l13 = l[rightOffset + 2], l14 = l[rightOffset + 3]; + var l21 = l[rightOffset + 4], l22 = l[rightOffset + 5], l23 = l[rightOffset + 6], l24 = l[rightOffset + 7]; + var l31 = l[rightOffset + 8], l32 = l[rightOffset + 9], l33 = l[rightOffset + 10], l34 = l[rightOffset + 11]; + var l41 = l[rightOffset + 12], l42 = l[rightOffset + 13], l43 = l[rightOffset + 14], l44 = l[rightOffset + 15]; + var r11 = r[0], r12 = r[1], r13 = r[2], r14 = r[3]; + var r21 = r[4], r22 = r[5], r23 = r[6], r24 = r[7]; + var r31 = r[8], r32 = r[9], r33 = r[10], r34 = r[11]; + var r41 = r[12], r42 = r[13], r43 = r[14], r44 = r[15]; + e[outOffset] = (l11 * r11) + (l12 * r21) + (l13 * r31) + (l14 * r41); + e[outOffset + 1] = (l11 * r12) + (l12 * r22) + (l13 * r32) + (l14 * r42); + e[outOffset + 2] = (l11 * r13) + (l12 * r23) + (l13 * r33) + (l14 * r43); + e[outOffset + 3] = (l11 * r14) + (l12 * r24) + (l13 * r34) + (l14 * r44); + e[outOffset + 4] = (l21 * r11) + (l22 * r21) + (l23 * r31) + (l24 * r41); + e[outOffset + 5] = (l21 * r12) + (l22 * r22) + (l23 * r32) + (l24 * r42); + e[outOffset + 6] = (l21 * r13) + (l22 * r23) + (l23 * r33) + (l24 * r43); + e[outOffset + 7] = (l21 * r14) + (l22 * r24) + (l23 * r34) + (l24 * r44); + e[outOffset + 8] = (l31 * r11) + (l32 * r21) + (l33 * r31) + (l34 * r41); + e[outOffset + 9] = (l31 * r12) + (l32 * r22) + (l33 * r32) + (l34 * r42); + e[outOffset + 10] = (l31 * r13) + (l32 * r23) + (l33 * r33) + (l34 * r43); + e[outOffset + 11] = (l31 * r14) + (l32 * r24) + (l33 * r34) + (l34 * r44); + e[outOffset + 12] = (l41 * r11) + (l42 * r21) + (l43 * r31) + (l44 * r41); + e[outOffset + 13] = (l41 * r12) + (l42 * r22) + (l43 * r32) + (l44 * r42); + e[outOffset + 14] = (l41 * r13) + (l42 * r23) + (l43 * r33) + (l44 * r43); + e[outOffset + 15] = (l41 * r14) + (l42 * r24) + (l43 * r34) + (l44 * r44); + } + static arcTanAngle(x, y) { + if (x == 0) { + if (y == 1) + return Math.PI / 2; + return -Math.PI / 2; + } + if (x > 0) + return Math.atan(y / x); + if (x < 0) { + if (y > 0) + return Math.atan(y / x) + Math.PI; + return Math.atan(y / x) - Math.PI; + } + return 0; + } + static angleTo(from, location, angle) { + Vector3.subtract(location, from, Quaternion.TEMPVector30); + Vector3.normalize(Quaternion.TEMPVector30, Quaternion.TEMPVector30); + angle.x = Math.asin(Quaternion.TEMPVector30.y); + angle.y = Utils3D.arcTanAngle(-Quaternion.TEMPVector30.z, -Quaternion.TEMPVector30.x); + } + static transformQuat(source, rotation, out) { + var re = rotation; + var x = source.x, y = source.y, z = source.z, qx = re[0], qy = re[1], qz = re[2], qw = re[3], ix = qw * x + qy * z - qz * y, iy = qw * y + qz * x - qx * z, iz = qw * z + qx * y - qy * x, iw = -qx * x - qy * y - qz * z; + out.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; + out.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; + out.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + } + static quaternionWeight(f, weight, e) { + e.x = f.x * weight; + e.y = f.y * weight; + e.z = f.z * weight; + e.w = f.w; + } + static quaternionConjugate(value, result) { + result.x = -value.x; + result.y = -value.y; + result.z = -value.z; + result.w = value.w; + } + static scaleWeight(s, w, out) { + var sX = s.x, sY = s.y, sZ = s.z; + out.x = sX > 0 ? Math.pow(Math.abs(sX), w) : -Math.pow(Math.abs(sX), w); + out.y = sY > 0 ? Math.pow(Math.abs(sY), w) : -Math.pow(Math.abs(sY), w); + out.z = sZ > 0 ? Math.pow(Math.abs(sZ), w) : -Math.pow(Math.abs(sZ), w); + } + static scaleBlend(sa, sb, w, out) { + var saw = Utils3D._tempVector3_0; + var sbw = Utils3D._tempVector3_1; + Utils3D.scaleWeight(sa, 1.0 - w, saw); + Utils3D.scaleWeight(sb, w, sbw); + var sng = w > 0.5 ? sb : sa; + out.x = sng.x > 0 ? Math.abs(saw.x * sbw.x) : -Math.abs(saw.x * sbw.x); + out.y = sng.y > 0 ? Math.abs(saw.y * sbw.y) : -Math.abs(saw.y * sbw.y); + out.z = sng.z > 0 ? Math.abs(saw.z * sbw.z) : -Math.abs(saw.z * sbw.z); + } + static matrix4x4MultiplyFFF(a, b, e) { + var i, ai0, ai1, ai2, ai3; + if (e === b) { + b = new Float32Array(16); + for (i = 0; i < 16; ++i) { + b[i] = e[i]; + } + } + var b0 = b[0], b1 = b[1], b2 = b[2], b3 = b[3]; + var b4 = b[4], b5 = b[5], b6 = b[6], b7 = b[7]; + var b8 = b[8], b9 = b[9], b10 = b[10], b11 = b[11]; + var b12 = b[12], b13 = b[13], b14 = b[14], b15 = b[15]; + for (i = 0; i < 4; i++) { + ai0 = a[i]; + ai1 = a[i + 4]; + ai2 = a[i + 8]; + ai3 = a[i + 12]; + e[i] = ai0 * b0 + ai1 * b1 + ai2 * b2 + ai3 * b3; + e[i + 4] = ai0 * b4 + ai1 * b5 + ai2 * b6 + ai3 * b7; + e[i + 8] = ai0 * b8 + ai1 * b9 + ai2 * b10 + ai3 * b11; + e[i + 12] = ai0 * b12 + ai1 * b13 + ai2 * b14 + ai3 * b15; + } + } + static matrix4x4MultiplyFFFForNative(a, b, e) { + Laya.LayaGL.instance.matrix4x4Multiply(a, b, e); + } + static matrix4x4MultiplyMFM(left, right, out) { + Utils3D.matrix4x4MultiplyFFF(left.elements, right, out.elements); + } + static _buildTexture2D(width, height, format, colorFunc, mipmaps = false) { + var texture = new Laya.Texture2D(width, height, format, mipmaps, true); + texture.anisoLevel = 1; + texture.filterMode = Laya.FilterMode.Point; + TextureGenerator._generateTexture2D(texture, width, height, colorFunc); + return texture; + } + static _drawBound(debugLine, boundBox, color) { + if (debugLine.lineCount + 12 > debugLine.maxLineCount) + debugLine.maxLineCount += 12; + var start = Utils3D._tempVector3_0; + var end = Utils3D._tempVector3_1; + var min = boundBox.min; + var max = boundBox.max; + start.setValue(min.x, min.y, min.z); + end.setValue(max.x, min.y, min.z); + debugLine.addLine(start, end, color, color); + start.setValue(min.x, min.y, min.z); + end.setValue(min.x, min.y, max.z); + debugLine.addLine(start, end, color, color); + start.setValue(max.x, min.y, min.z); + end.setValue(max.x, min.y, max.z); + debugLine.addLine(start, end, color, color); + start.setValue(min.x, min.y, max.z); + end.setValue(max.x, min.y, max.z); + debugLine.addLine(start, end, color, color); + start.setValue(min.x, min.y, min.z); + end.setValue(min.x, max.y, min.z); + debugLine.addLine(start, end, color, color); + start.setValue(min.x, min.y, max.z); + end.setValue(min.x, max.y, max.z); + debugLine.addLine(start, end, color, color); + start.setValue(max.x, min.y, min.z); + end.setValue(max.x, max.y, min.z); + debugLine.addLine(start, end, color, color); + start.setValue(max.x, min.y, max.z); + end.setValue(max.x, max.y, max.z); + debugLine.addLine(start, end, color, color); + start.setValue(min.x, max.y, min.z); + end.setValue(max.x, max.y, min.z); + debugLine.addLine(start, end, color, color); + start.setValue(min.x, max.y, min.z); + end.setValue(min.x, max.y, max.z); + debugLine.addLine(start, end, color, color); + start.setValue(max.x, max.y, min.z); + end.setValue(max.x, max.y, max.z); + debugLine.addLine(start, end, color, color); + start.setValue(min.x, max.y, max.z); + end.setValue(max.x, max.y, max.z); + debugLine.addLine(start, end, color, color); + } + static _getHierarchyPath(rootSprite, checkSprite, path) { + path.length = 0; + var sprite = checkSprite; + while (sprite !== rootSprite) { + var parent = sprite._parent; + if (parent) + path.push(parent.getChildIndex(sprite)); + else + return null; + sprite = parent; + } + return path; + } + static _getNodeByHierarchyPath(rootSprite, invPath) { + var sprite = rootSprite; + for (var i = invPath.length - 1; i >= 0; i--) { + sprite = sprite.getChildAt(invPath[i]); + } + return sprite; + } + static uint8ArrayToArrayBuffer(rendertexture) { + let pixelArray; + let width = rendertexture.width; + let height = rendertexture.height; + switch (rendertexture.format) { + case Laya.RenderTextureFormat.R8G8B8: + pixelArray = new Uint8Array(width * height * 4); + break; + case Laya.RenderTextureFormat.R8G8B8A8: + pixelArray = new Uint8Array(width * height * 4); + break; + case Laya.RenderTextureFormat.R16G16B16A16: + pixelArray = new Float32Array(width * height * 4); + break; + default: + throw "this function is not surpprt " + rendertexture.format.toString() + "format Material"; + } + rendertexture.getData(0, 0, rendertexture.width, rendertexture.height, pixelArray); + switch (rendertexture.format) { + case Laya.RenderTextureFormat.R16G16B16A16: + let ori = pixelArray; + let trans = new Uint8Array(width * height * 4); + for (let i = 0, n = ori.length; i < n; i++) { + trans[i] = Math.min(Math.floor(ori[i] * 255), 255); + } + pixelArray = trans; + break; + } + let pixels = pixelArray; + var bs; + if (Laya.Render.isConchApp) ; + else { + var canv = new Laya.HTMLCanvas(true); + canv.lock = true; + canv.size(width, height); + var ctx2d = canv.getContext('2d'); + var imgdata = ctx2d.createImageData(width, height); + imgdata.data.set(new Uint8ClampedArray(pixels)); + ctx2d.putImageData(imgdata, 0, 0); + bs = canv.source.toDataURL(); + canv.destroy(); + } + return bs; + } + } + Utils3D._tempVector3_0 = new Vector3(); + Utils3D._tempVector3_1 = new Vector3(); + Utils3D._tempArray16_0 = new Float32Array(16); + Utils3D._tempArray16_1 = new Float32Array(16); + Utils3D._tempArray16_2 = new Float32Array(16); + Utils3D._tempArray16_3 = new Float32Array(16); + Utils3D._compIdToNode = new Object(); + + class AnimationClip extends Laya.Resource { + constructor() { + super(); + this._duration = 0; + this._frameRate = 0; + this._nodes = new KeyframeNodeList(); + this.islooping = false; + this._animationEvents = []; + } + static _parse(data) { + var clip = new AnimationClip(); + var reader = new Laya.Byte(data); + var version = reader.readUTFString(); + switch (version) { + case "LAYAANIMATION:03": + AnimationClipParser03.parse(clip, reader); + break; + case "LAYAANIMATION:04": + case "LAYAANIMATION:COMPRESSION_04": + AnimationClipParser04.parse(clip, reader, version); + break; + default: + throw "unknown animationClip version."; + } + return clip; + } + static load(url, complete) { + Laya.ILaya.loader.create(url, complete, null, AnimationClip.ANIMATIONCLIP); + } + duration() { + return this._duration; + } + _hermiteInterpolate(frame, nextFrame, t, dur) { + var t0 = frame.outTangent, t1 = nextFrame.inTangent; + if (Number.isFinite(t0) && Number.isFinite(t1)) { + var t2 = t * t; + var t3 = t2 * t; + var a = 2.0 * t3 - 3.0 * t2 + 1.0; + var b = t3 - 2.0 * t2 + t; + var c = t3 - t2; + var d = -2.0 * t3 + 3.0 * t2; + return a * frame.value + b * t0 * dur + c * t1 * dur + d * nextFrame.value; + } + else + return frame.value; + } + _hermiteInterpolateVector3(frame, nextFrame, t, dur, out) { + var p0 = frame.value; + var tan0 = frame.outTangent; + var p1 = nextFrame.value; + var tan1 = nextFrame.inTangent; + var t2 = t * t; + var t3 = t2 * t; + var a = 2.0 * t3 - 3.0 * t2 + 1.0; + var b = t3 - 2.0 * t2 + t; + var c = t3 - t2; + var d = -2.0 * t3 + 3.0 * t2; + var t0 = tan0.x, t1 = tan1.x; + if (Number.isFinite(t0) && Number.isFinite(t1)) + out.x = a * p0.x + b * t0 * dur + c * t1 * dur + d * p1.x; + else + out.x = p0.x; + t0 = tan0.y, t1 = tan1.y; + if (Number.isFinite(t0) && Number.isFinite(t1)) + out.y = a * p0.y + b * t0 * dur + c * t1 * dur + d * p1.y; + else + out.y = p0.y; + t0 = tan0.z, t1 = tan1.z; + if (Number.isFinite(t0) && Number.isFinite(t1)) + out.z = a * p0.z + b * t0 * dur + c * t1 * dur + d * p1.z; + else + out.z = p0.z; + } + _hermiteInterpolateQuaternion(frame, nextFrame, t, dur, out) { + var p0 = frame.value; + var tan0 = frame.outTangent; + var p1 = nextFrame.value; + var tan1 = nextFrame.inTangent; + var t2 = t * t; + var t3 = t2 * t; + var a = 2.0 * t3 - 3.0 * t2 + 1.0; + var b = t3 - 2.0 * t2 + t; + var c = t3 - t2; + var d = -2.0 * t3 + 3.0 * t2; + var t0 = tan0.x, t1 = tan1.x; + if (Number.isFinite(t0) && Number.isFinite(t1)) + out.x = a * p0.x + b * t0 * dur + c * t1 * dur + d * p1.x; + else + out.x = p0.x; + t0 = tan0.y, t1 = tan1.y; + if (Number.isFinite(t0) && Number.isFinite(t1)) + out.y = a * p0.y + b * t0 * dur + c * t1 * dur + d * p1.y; + else + out.y = p0.y; + t0 = tan0.z, t1 = tan1.z; + if (Number.isFinite(t0) && Number.isFinite(t1)) + out.z = a * p0.z + b * t0 * dur + c * t1 * dur + d * p1.z; + else + out.z = p0.z; + t0 = tan0.w, t1 = tan1.w; + if (Number.isFinite(t0) && Number.isFinite(t1)) + out.w = a * p0.w + b * t0 * dur + c * t1 * dur + d * p1.w; + else + out.w = p0.w; + } + _evaluateClipDatasRealTime(nodes, playCurTime, realTimeCurrentFrameIndexes, addtive, frontPlay, outDatas, avatarMask) { + for (var i = 0, n = nodes.count; i < n; i++) { + var node = nodes.getNodeByIndex(i); + var type = node.type; + var nextFrameIndex; + var keyFrames = node._keyFrames; + var keyFramesCount = keyFrames.length; + var frameIndex = realTimeCurrentFrameIndexes[i]; + if (avatarMask && (!avatarMask.getTransformActive(node.nodePath))) { + continue; + } + if (frontPlay) { + if ((frameIndex !== -1) && (playCurTime < keyFrames[frameIndex].time)) { + frameIndex = -1; + realTimeCurrentFrameIndexes[i] = frameIndex; + } + nextFrameIndex = frameIndex + 1; + while (nextFrameIndex < keyFramesCount) { + if (keyFrames[nextFrameIndex].time > playCurTime) + break; + frameIndex++; + nextFrameIndex++; + realTimeCurrentFrameIndexes[i] = frameIndex; + } + } + else { + nextFrameIndex = frameIndex + 1; + if ((nextFrameIndex !== keyFramesCount) && (playCurTime > keyFrames[nextFrameIndex].time)) { + frameIndex = keyFramesCount - 1; + realTimeCurrentFrameIndexes[i] = frameIndex; + } + nextFrameIndex = frameIndex + 1; + while (frameIndex > -1) { + if (keyFrames[frameIndex].time < playCurTime) + break; + frameIndex--; + nextFrameIndex--; + realTimeCurrentFrameIndexes[i] = frameIndex; + } + } + var isEnd = nextFrameIndex === keyFramesCount; + switch (type) { + case 0: + if (frameIndex !== -1) { + var frame = keyFrames[frameIndex]; + if (isEnd) { + outDatas[i] = frame.value; + } + else { + var nextFarme = keyFrames[nextFrameIndex]; + var d = nextFarme.time - frame.time; + var t; + if (d !== 0) + t = (playCurTime - frame.time) / d; + else + t = 0; + outDatas[i] = this._hermiteInterpolate(frame, nextFarme, t, d); + } + } + else { + outDatas[i] = keyFrames[0].value; + } + if (addtive) + outDatas[i] = outDatas[i] - keyFrames[0].value; + break; + case 1: + case 4: + var clipData = outDatas[i]; + this._evaluateFrameNodeVector3DatasRealTime(keyFrames, frameIndex, isEnd, playCurTime, clipData); + if (addtive) { + var firstFrameValue = keyFrames[0].value; + clipData.x -= firstFrameValue.x; + clipData.y -= firstFrameValue.y; + clipData.z -= firstFrameValue.z; + } + break; + case 2: + var clipQuat = outDatas[i]; + this._evaluateFrameNodeQuaternionDatasRealTime(keyFrames, frameIndex, isEnd, playCurTime, clipQuat); + if (addtive) { + var tempQuat = AnimationClip._tempQuaternion0; + var firstFrameValueQua = keyFrames[0].value; + Utils3D.quaternionConjugate(firstFrameValueQua, tempQuat); + Quaternion.multiply(tempQuat, clipQuat, clipQuat); + } + break; + case 3: + clipData = outDatas[i]; + this._evaluateFrameNodeVector3DatasRealTime(keyFrames, frameIndex, isEnd, playCurTime, clipData); + if (addtive) { + firstFrameValue = keyFrames[0].value; + clipData.x /= firstFrameValue.x; + clipData.y /= firstFrameValue.y; + clipData.z /= firstFrameValue.z; + } + break; + default: + throw "AnimationClip:unknown node type."; + } + } + } + _evaluateClipDatasRealTimeForNative(nodes, playCurTime, realTimeCurrentFrameIndexes, addtive) { + Laya.LayaGL.instance.evaluateClipDatasRealTime(nodes._nativeObj, playCurTime, realTimeCurrentFrameIndexes, addtive); + } + _evaluateFrameNodeVector3DatasRealTime(keyFrames, frameIndex, isEnd, playCurTime, outDatas) { + if (frameIndex !== -1) { + var frame = keyFrames[frameIndex]; + if (isEnd) { + var frameData = frame.value; + outDatas.x = frameData.x; + outDatas.y = frameData.y; + outDatas.z = frameData.z; + } + else { + var nextKeyFrame = keyFrames[frameIndex + 1]; + var t; + var startTime = frame.time; + var d = nextKeyFrame.time - startTime; + if (d !== 0) + t = (playCurTime - startTime) / d; + else + t = 0; + this._hermiteInterpolateVector3(frame, nextKeyFrame, t, d, outDatas); + } + } + else { + var firstFrameDatas = keyFrames[0].value; + outDatas.x = firstFrameDatas.x; + outDatas.y = firstFrameDatas.y; + outDatas.z = firstFrameDatas.z; + } + } + _evaluateFrameNodeQuaternionDatasRealTime(keyFrames, frameIndex, isEnd, playCurTime, outDatas) { + if (frameIndex !== -1) { + var frame = keyFrames[frameIndex]; + if (isEnd) { + var frameData = frame.value; + outDatas.x = frameData.x; + outDatas.y = frameData.y; + outDatas.z = frameData.z; + outDatas.w = frameData.w; + } + else { + var nextKeyFrame = keyFrames[frameIndex + 1]; + var t; + var startTime = frame.time; + var d = nextKeyFrame.time - startTime; + if (d !== 0) + t = (playCurTime - startTime) / d; + else + t = 0; + this._hermiteInterpolateQuaternion(frame, nextKeyFrame, t, d, outDatas); + } + } + else { + var firstFrameDatas = keyFrames[0].value; + outDatas.x = firstFrameDatas.x; + outDatas.y = firstFrameDatas.y; + outDatas.z = firstFrameDatas.z; + outDatas.w = firstFrameDatas.w; + } + } + _binarySearchEventIndex(time) { + var start = 0; + var end = this._animationEvents.length - 1; + var mid; + while (start <= end) { + mid = Math.floor((start + end) / 2); + var midValue = this._animationEvents[mid].time; + if (midValue == time) + return mid; + else if (midValue > time) + end = mid - 1; + else + start = mid + 1; + } + return start; + } + addEvent(event) { + var index = this._binarySearchEventIndex(event.time); + this._animationEvents.splice(index, 0, event); + } + _disposeResource() { + this._nodes = null; + this._nodesMap = null; + } + } + AnimationClip.ANIMATIONCLIP = "ANIMATIONCLIP"; + AnimationClip._tempQuaternion0 = new Quaternion(); + + class AnimatorPlayState { + constructor() { + this._currentState = null; + } + get normalizedTime() { + return this._normalizedTime; + } + get duration() { + return this._duration; + } + get animatorState() { + return this._currentState; + } + _resetPlayState(startTime, clipDuration) { + this._finish = false; + this._startPlayTime = startTime; + this._elapsedTime = startTime; + this._playEventIndex = 0; + this._lastIsFront = true; + this._normalizedTime = this._elapsedTime / clipDuration; + var playTime = this._normalizedTime % 1.0; + this._normalizedPlayTime = playTime < 0 ? playTime + 1.0 : playTime; + } + _cloneTo(dest) { + dest._finish = this._finish; + dest._startPlayTime = this._startPlayTime; + dest._elapsedTime = this._elapsedTime; + dest._normalizedTime = this._normalizedTime; + dest._normalizedPlayTime = this._normalizedPlayTime; + dest._playEventIndex = this._playEventIndex; + dest._lastIsFront = this._lastIsFront; + } + } + + class AnimatorControllerLayer { + constructor(name) { + this._referenceCount = 0; + this._playType = -1; + this._crossDuration = -1; + this._crossMark = 0; + this._crossNodesOwnersCount = 0; + this._crossNodesOwners = []; + this._crossNodesOwnersIndicesMap = {}; + this._srcCrossClipNodeIndices = []; + this._destCrossClipNodeIndices = []; + this._statesMap = {}; + this._states = []; + this._playStateInfo = new AnimatorPlayState(); + this._crossPlayStateInfo = new AnimatorPlayState(); + this.blendingMode = AnimatorControllerLayer.BLENDINGMODE_OVERRIDE; + this.defaultWeight = 1.0; + this.playOnWake = true; + this.name = name; + } + get defaultState() { + return this._defaultState; + } + set defaultState(value) { + this._defaultState = value; + this._statesMap[value.name] = value; + } + get avatarMask() { + return this._avatarMask; + } + set avatarMask(value) { + this._avatarMask = value; + } + _removeClip(clipStateInfos, statesMap, index, state) { + var clip = state._clip; + var clipStateInfo = clipStateInfos[index]; + clipStateInfos.splice(index, 1); + delete statesMap[state.name]; + if (this._animator) { + var frameNodes = clip._nodes; + var nodeOwners = clipStateInfo._nodeOwners; + clip._removeReference(); + for (var i = 0, n = frameNodes.count; i < n; i++) + this._animator._removeKeyframeNodeOwner(nodeOwners, frameNodes.getNodeByIndex(i)); + } + } + _getReferenceCount() { + return this._referenceCount; + } + _addReference(count = 1) { + for (var i = 0, n = this._states.length; i < n; i++) + this._states[i]._addReference(count); + this._referenceCount += count; + } + _removeReference(count = 1) { + for (var i = 0, n = this._states.length; i < n; i++) + this._states[i]._removeReference(count); + this._referenceCount -= count; + } + _clearReference() { + this._removeReference(-this._referenceCount); + } + getCurrentPlayState() { + return this._playStateInfo; + } + getAnimatorState(name) { + var state = this._statesMap[name]; + return state ? state : null; + } + addState(state) { + var stateName = state.name; + if (this._statesMap[stateName]) { + throw "AnimatorControllerLayer:this stat's name has exist."; + } + else { + this._statesMap[stateName] = state; + this._states.push(state); + if (this._animator) { + state._clip._addReference(); + this._animator._getOwnersByClip(state); + } + } + } + removeState(state) { + var states = this._states; + var index = -1; + for (var i = 0, n = states.length; i < n; i++) { + if (states[i] === state) { + index = i; + break; + } + } + if (index !== -1) + this._removeClip(states, this._statesMap, index, state); + } + destroy() { + this._clearReference(); + this._statesMap = null; + this._states = []; + this._playStateInfo = null; + this._crossPlayStateInfo = null; + this._defaultState = null; + } + cloneTo(destObject) { + var dest = destObject; + dest.name = this.name; + dest.blendingMode = this.blendingMode; + dest.defaultWeight = this.defaultWeight; + dest.playOnWake = this.playOnWake; + } + clone() { + var dest = new AnimatorControllerLayer(this.name); + this.cloneTo(dest); + return dest; + } + } + AnimatorControllerLayer.BLENDINGMODE_OVERRIDE = 0; + AnimatorControllerLayer.BLENDINGMODE_ADDTIVE = 1; + + class AnimatorState { + constructor() { + this._referenceCount = 0; + this._clip = null; + this._nodeOwners = []; + this._currentFrameIndices = null; + this._realtimeDatas = []; + this._scripts = null; + this.speed = 1.0; + this.clipStart = 0.0; + this.clipEnd = 1.0; + } + get clip() { + return this._clip; + } + set clip(value) { + if (this._clip !== value) { + if (this._clip) + (this._referenceCount > 0) && (this._clip._removeReference(this._referenceCount)); + if (value) { + var realtimeDatas = this._realtimeDatas; + var clipNodes = value._nodes; + var count = clipNodes.count; + this._currentFrameIndices = new Int16Array(count); + this._resetFrameIndices(); + (this._referenceCount > 0) && (value._addReference(this._referenceCount)); + this._realtimeDatas.length = count; + for (var i = 0; i < count; i++) { + switch (clipNodes.getNodeByIndex(i).type) { + case 0: + break; + case 1: + case 3: + case 4: + realtimeDatas[i] = new Vector3(); + break; + case 2: + realtimeDatas[i] = new Quaternion(); + break; + default: + throw "AnimationClipParser04:unknown type."; + } + } + } + this._clip = value; + } + } + _getReferenceCount() { + return this._referenceCount; + } + _addReference(count = 1) { + (this._clip) && (this._clip._addReference(count)); + this._referenceCount += count; + } + _removeReference(count = 1) { + (this._clip) && (this._clip._removeReference(count)); + this._referenceCount -= count; + } + _clearReference() { + this._removeReference(-this._referenceCount); + } + _resetFrameIndices() { + for (var i = 0, n = this._currentFrameIndices.length; i < n; i++) + this._currentFrameIndices[i] = -1; + } + addScript(type) { + var script = new type(); + this._scripts = this._scripts || []; + this._scripts.push(script); + return script; + } + getScript(type) { + if (this._scripts) { + for (var i = 0, n = this._scripts.length; i < n; i++) { + var script = this._scripts[i]; + if (script instanceof type) + return script; + } + } + return null; + } + getScripts(type) { + var coms = null; + if (this._scripts) { + for (var i = 0, n = this._scripts.length; i < n; i++) { + var script = this._scripts[i]; + if (script instanceof type) { + coms = coms || []; + coms.push(script); + } + } + } + return coms; + } + cloneTo(destObject) { + var dest = destObject; + dest.name = this.name; + dest.speed = this.speed; + dest.clipStart = this.clipStart; + dest.clipEnd = this.clipEnd; + dest.clip = this._clip; + } + clone() { + var dest = new AnimatorState(); + this.cloneTo(dest); + return dest; + } + } + + class AvatarMask { + constructor(animator) { + this._avatarPathMap = {}; + this._catchAnimator = animator; + } + get getCatchAnimator() { + return this._catchAnimator; + } + getTransformActive(path) { + return this._avatarPathMap[path]; + } + setTransformActive(path, value) { + this._avatarPathMap[path] = value; + } + getAllTranfromPath() { + return this._avatarPathMap; + } + } + + class KeyframeNodeOwner { + constructor() { + this.indexInList = -1; + this.referenceCount = 0; + this.updateMark = -1; + this.type = -1; + this.fullPath = null; + this.propertyOwner = null; + this.property = null; + this.defaultValue = null; + this.value = null; + this.crossFixedValue = null; + } + saveCrossFixedValue() { + var pro = this.propertyOwner; + if (pro) { + switch (this.type) { + case 0: + this.crossFixedValue = this.value; + break; + case 1: + case 3: + case 4: + this.value.cloneTo(this.crossFixedValue); + break; + case 2: + this.value.cloneTo(this.crossFixedValue); + break; + default: + throw "Animator:unknown type."; + } + } + } + } + + class Animator extends Laya.Component { + constructor() { + super(); + this._keyframeNodeOwners = []; + this._linkAvatarSpritesData = {}; + this._linkAvatarSprites = []; + this._renderableSprites = []; + this.cullingMode = Animator.CULLINGMODE_CULLCOMPLETELY; + this._controllerLayers = []; + this._linkSprites = {}; + this._speed = 1.0; + this._keyframeNodeOwnerMap = {}; + this._updateMark = 0; + } + static _update(scene) { + var pool = scene._animatorPool; + var elements = pool.elements; + for (var i = 0, n = pool.length; i < n; i++) { + var animator = elements[i]; + (animator && animator.enabled) && (animator._update()); + } + } + get speed() { + return this._speed; + } + set speed(value) { + this._speed = value; + } + get controllerLayerCount() { + return this._controllerLayers.length; + } + _linkToSprites(linkSprites) { + for (var k in linkSprites) { + var nodeOwner = this.owner; + var path = linkSprites[k]; + for (var j = 0, m = path.length; j < m; j++) { + var p = path[j]; + if (p === "") { + break; + } + else { + nodeOwner = nodeOwner.getChildByName(p); + if (!nodeOwner) + break; + } + } + (nodeOwner) && (this.linkSprite3DToAvatarNode(k, nodeOwner)); + } + } + _addKeyframeNodeOwner(clipOwners, node, propertyOwner) { + var nodeIndex = node._indexInList; + var fullPath = node.fullPath; + var keyframeNodeOwner = this._keyframeNodeOwnerMap[fullPath]; + if (keyframeNodeOwner) { + keyframeNodeOwner.referenceCount++; + clipOwners[nodeIndex] = keyframeNodeOwner; + } + else { + var property = propertyOwner; + for (var i = 0, n = node.propertyCount; i < n; i++) { + property = property[node.getPropertyByIndex(i)]; + if (!property) + break; + } + keyframeNodeOwner = this._keyframeNodeOwnerMap[fullPath] = new KeyframeNodeOwner(); + keyframeNodeOwner.fullPath = fullPath; + keyframeNodeOwner.indexInList = this._keyframeNodeOwners.length; + keyframeNodeOwner.referenceCount = 1; + keyframeNodeOwner.propertyOwner = propertyOwner; + var propertyCount = node.propertyCount; + var propertys = []; + for (i = 0; i < propertyCount; i++) + propertys[i] = node.getPropertyByIndex(i); + keyframeNodeOwner.property = propertys; + keyframeNodeOwner.type = node.type; + if (property) { + if (node.type === 0) { + keyframeNodeOwner.defaultValue = property; + } + else { + var defaultValue = new property.constructor(); + property.cloneTo(defaultValue); + keyframeNodeOwner.defaultValue = defaultValue; + keyframeNodeOwner.value = new property.constructor(); + keyframeNodeOwner.crossFixedValue = new property.constructor(); + } + } + this._keyframeNodeOwners.push(keyframeNodeOwner); + clipOwners[nodeIndex] = keyframeNodeOwner; + } + } + _removeKeyframeNodeOwner(nodeOwners, node) { + var fullPath = node.fullPath; + var keyframeNodeOwner = this._keyframeNodeOwnerMap[fullPath]; + if (keyframeNodeOwner) { + keyframeNodeOwner.referenceCount--; + if (keyframeNodeOwner.referenceCount === 0) { + delete this._keyframeNodeOwnerMap[fullPath]; + this._keyframeNodeOwners.splice(this._keyframeNodeOwners.indexOf(keyframeNodeOwner), 1); + } + nodeOwners[node._indexInList] = null; + } + } + _getOwnersByClip(clipStateInfo) { + var frameNodes = clipStateInfo._clip._nodes; + var frameNodesCount = frameNodes.count; + var nodeOwners = clipStateInfo._nodeOwners; + nodeOwners.length = frameNodesCount; + for (var i = 0; i < frameNodesCount; i++) { + var node = frameNodes.getNodeByIndex(i); + var property = this._avatar ? this._avatarNodeMap[this._avatar._rootNode.name] : this.owner; + for (var j = 0, m = node.ownerPathCount; j < m; j++) { + var ownPat = node.getOwnerPathByIndex(j); + if (ownPat === "") { + break; + } + else { + property = property.getChildByName(ownPat); + if (!property) + break; + } + } + if (property) { + var propertyOwner = node.propertyOwner; + (propertyOwner) && (property = property[propertyOwner]); + property && this._addKeyframeNodeOwner(nodeOwners, node, property); + } + } + } + _updatePlayer(animatorState, playState, elapsedTime, islooping) { + var clipDuration = animatorState._clip._duration * (animatorState.clipEnd - animatorState.clipStart); + var lastElapsedTime = playState._elapsedTime; + var elapsedPlaybackTime = lastElapsedTime + elapsedTime; + playState._lastElapsedTime = lastElapsedTime; + playState._elapsedTime = elapsedPlaybackTime; + var normalizedTime = elapsedPlaybackTime / clipDuration; + playState._normalizedTime = normalizedTime; + var playTime = normalizedTime % 1.0; + playState._normalizedPlayTime = playTime < 0 ? playTime + 1.0 : playTime; + playState._duration = clipDuration; + var scripts = animatorState._scripts; + if ((!islooping && elapsedPlaybackTime >= clipDuration)) { + playState._finish = true; + playState._elapsedTime = clipDuration; + playState._normalizedPlayTime = 1.0; + return; + } + if (scripts) { + for (var i = 0, n = scripts.length; i < n; i++) + scripts[i].onStateUpdate(); + } + } + _updateStateFinish(animatorState, playState) { + if (playState._finish) { + var scripts = animatorState._scripts; + if (scripts) { + for (var i = 0, n = scripts.length; i < n; i++) { + scripts[i].onStateExit(); + } + } + } + } + _eventScript(scripts, events, eventIndex, endTime, front) { + if (front) { + for (var n = events.length; eventIndex < n; eventIndex++) { + var event = events[eventIndex]; + if (event.time <= endTime) { + for (var j = 0, m = scripts.length; j < m; j++) { + var script = scripts[j]; + var fun = script[event.eventName]; + (fun) && (fun.apply(script, event.params)); + } + } + else { + break; + } + } + } + else { + for (; eventIndex >= 0; eventIndex--) { + event = events[eventIndex]; + if (event.time >= endTime) { + for (j = 0, m = scripts.length; j < m; j++) { + script = scripts[j]; + fun = script[event.eventName]; + (fun) && (fun.apply(script, event.params)); + } + } + else { + break; + } + } + } + return eventIndex; + } + _updateEventScript(stateInfo, playStateInfo) { + var scripts = this.owner._scripts; + if (scripts) { + var clip = stateInfo._clip; + var events = clip._animationEvents; + var clipDuration = clip._duration; + var elapsedTime = playStateInfo._elapsedTime; + var time = elapsedTime % clipDuration; + var loopCount = Math.abs(Math.floor(elapsedTime / clipDuration) - Math.floor(playStateInfo._lastElapsedTime / clipDuration)); + var frontPlay = playStateInfo._elapsedTime >= playStateInfo._lastElapsedTime; + if (playStateInfo._lastIsFront !== frontPlay) { + if (frontPlay) + playStateInfo._playEventIndex++; + else + playStateInfo._playEventIndex--; + playStateInfo._lastIsFront = frontPlay; + } + var preEventIndex = playStateInfo._playEventIndex; + if (frontPlay) { + var newEventIndex = this._eventScript(scripts, events, playStateInfo._playEventIndex, loopCount > 0 ? clipDuration : time, true); + (preEventIndex === playStateInfo._playEventIndex) && (playStateInfo._playEventIndex = newEventIndex); + for (var i = 0, n = loopCount - 1; i < n; i++) + this._eventScript(scripts, events, 0, clipDuration, true); + (loopCount > 0 && time > 0) && (playStateInfo._playEventIndex = this._eventScript(scripts, events, 0, time, true)); + } + else { + var newEventIndex = this._eventScript(scripts, events, playStateInfo._playEventIndex, loopCount > 0 ? 0 : time, false); + (preEventIndex === playStateInfo._playEventIndex) && (playStateInfo._playEventIndex = newEventIndex); + var eventIndex = events.length - 1; + for (i = 0, n = loopCount - 1; i < n; i++) + this._eventScript(scripts, events, eventIndex, 0, false); + (loopCount > 0 && time > 0) && (playStateInfo._playEventIndex = this._eventScript(scripts, events, eventIndex, time, false)); + } + } + } + _updateClipDatas(animatorState, addtive, playStateInfo, animatorMask = null) { + var clip = animatorState._clip; + var clipDuration = clip._duration; + var curPlayTime = animatorState.clipStart * clipDuration + playStateInfo._normalizedPlayTime * playStateInfo._duration; + var currentFrameIndices = animatorState._currentFrameIndices; + var frontPlay = playStateInfo._elapsedTime > playStateInfo._lastElapsedTime; + clip._evaluateClipDatasRealTime(clip._nodes, curPlayTime, currentFrameIndices, addtive, frontPlay, animatorState._realtimeDatas, animatorMask); + } + _applyFloat(pro, proName, nodeOwner, additive, weight, isFirstLayer, data) { + if (nodeOwner.updateMark === this._updateMark) { + if (additive) { + pro[proName] += weight * data; + } + else { + var oriValue = pro[proName]; + pro[proName] = oriValue + weight * (data - oriValue); + } + } + else { + if (isFirstLayer) { + if (additive) + pro[proName] = nodeOwner.defaultValue + data; + else + pro[proName] = data; + } + else { + if (additive) { + pro[proName] = nodeOwner.defaultValue + weight * (data); + } + else { + var defValue = nodeOwner.defaultValue; + pro[proName] = defValue + weight * (data - defValue); + } + } + } + } + _applyPositionAndRotationEuler(nodeOwner, additive, weight, isFirstLayer, data, out) { + if (nodeOwner.updateMark === this._updateMark) { + if (additive) { + out.x += weight * data.x; + out.y += weight * data.y; + out.z += weight * data.z; + } + else { + var oriX = out.x; + var oriY = out.y; + var oriZ = out.z; + out.x = oriX + weight * (data.x - oriX); + out.y = oriY + weight * (data.y - oriY); + out.z = oriZ + weight * (data.z - oriZ); + } + } + else { + if (isFirstLayer) { + if (additive) { + var defValue = nodeOwner.defaultValue; + out.x = defValue.x + data.x; + out.y = defValue.y + data.y; + out.z = defValue.z + data.z; + } + else { + out.x = data.x; + out.y = data.y; + out.z = data.z; + } + } + else { + defValue = nodeOwner.defaultValue; + if (additive) { + out.x = defValue.x + weight * data.x; + out.y = defValue.y + weight * data.y; + out.z = defValue.z + weight * data.z; + } + else { + var defX = defValue.x; + var defY = defValue.y; + var defZ = defValue.z; + out.x = defX + weight * (data.x - defX); + out.y = defY + weight * (data.y - defY); + out.z = defZ + weight * (data.z - defZ); + } + } + } + } + _applyRotation(nodeOwner, additive, weight, isFirstLayer, clipRot, localRotation) { + if (nodeOwner.updateMark === this._updateMark) { + if (additive) { + var tempQuat = Animator._tempQuaternion1; + Utils3D.quaternionWeight(clipRot, weight, tempQuat); + tempQuat.normalize(tempQuat); + Quaternion.multiply(localRotation, tempQuat, localRotation); + } + else { + Quaternion.lerp(localRotation, clipRot, weight, localRotation); + } + } + else { + if (isFirstLayer) { + if (additive) { + var defaultRot = nodeOwner.defaultValue; + Quaternion.multiply(defaultRot, clipRot, localRotation); + } + else { + localRotation.x = clipRot.x; + localRotation.y = clipRot.y; + localRotation.z = clipRot.z; + localRotation.w = clipRot.w; + } + } + else { + defaultRot = nodeOwner.defaultValue; + if (additive) { + tempQuat = Animator._tempQuaternion1; + Utils3D.quaternionWeight(clipRot, weight, tempQuat); + tempQuat.normalize(tempQuat); + Quaternion.multiply(defaultRot, tempQuat, localRotation); + } + else { + Quaternion.lerp(defaultRot, clipRot, weight, localRotation); + } + } + } + } + _applyScale(nodeOwner, additive, weight, isFirstLayer, clipSca, localScale) { + if (nodeOwner.updateMark === this._updateMark) { + if (additive) { + var scale = Animator._tempVector31; + Utils3D.scaleWeight(clipSca, weight, scale); + localScale.x = localScale.x * scale.x; + localScale.y = localScale.y * scale.y; + localScale.z = localScale.z * scale.z; + } + else { + Utils3D.scaleBlend(localScale, clipSca, weight, localScale); + } + } + else { + if (isFirstLayer) { + if (additive) { + var defaultSca = nodeOwner.defaultValue; + localScale.x = defaultSca.x * clipSca.x; + localScale.y = defaultSca.y * clipSca.y; + localScale.z = defaultSca.z * clipSca.z; + } + else { + localScale.x = clipSca.x; + localScale.y = clipSca.y; + localScale.z = clipSca.z; + } + } + else { + defaultSca = nodeOwner.defaultValue; + if (additive) { + scale = Animator._tempVector31; + Utils3D.scaleWeight(clipSca, weight, scale); + localScale.x = defaultSca.x * scale.x; + localScale.y = defaultSca.y * scale.y; + localScale.z = defaultSca.z * scale.z; + } + else { + Utils3D.scaleBlend(defaultSca, clipSca, weight, localScale); + } + } + } + } + _applyCrossData(nodeOwner, additive, weight, isFirstLayer, srcValue, desValue, crossWeight) { + var pro = nodeOwner.propertyOwner; + if (pro) { + switch (nodeOwner.type) { + case 0: + var proPat = nodeOwner.property; + var m = proPat.length - 1; + for (var j = 0; j < m; j++) { + pro = pro[proPat[j]]; + if (!pro) + break; + } + var crossValue = srcValue + crossWeight * (desValue - srcValue); + nodeOwner.value = crossValue; + pro && this._applyFloat(pro, proPat[m], nodeOwner, additive, weight, isFirstLayer, crossValue); + break; + case 1: + var localPos = pro.localPosition; + var position = nodeOwner.value; + var srcX = srcValue.x, srcY = srcValue.y, srcZ = srcValue.z; + position.x = srcX + crossWeight * (desValue.x - srcX); + position.y = srcY + crossWeight * (desValue.y - srcY); + position.z = srcZ + crossWeight * (desValue.z - srcZ); + this._applyPositionAndRotationEuler(nodeOwner, additive, weight, isFirstLayer, position, localPos); + pro.localPosition = localPos; + break; + case 2: + var localRot = pro.localRotation; + var rotation = nodeOwner.value; + Quaternion.lerp(srcValue, desValue, crossWeight, rotation); + this._applyRotation(nodeOwner, additive, weight, isFirstLayer, rotation, localRot); + pro.localRotation = localRot; + break; + case 3: + var localSca = pro.localScale; + var scale = nodeOwner.value; + Utils3D.scaleBlend(srcValue, desValue, crossWeight, scale); + this._applyScale(nodeOwner, additive, weight, isFirstLayer, scale, localSca); + pro.localScale = localSca; + break; + case 4: + var localEuler = pro.localRotationEuler; + var rotationEuler = nodeOwner.value; + srcX = srcValue.x, srcY = srcValue.y, srcZ = srcValue.z; + rotationEuler.x = srcX + crossWeight * (desValue.x - srcX); + rotationEuler.y = srcY + crossWeight * (desValue.y - srcY); + rotationEuler.z = srcZ + crossWeight * (desValue.z - srcZ); + this._applyPositionAndRotationEuler(nodeOwner, additive, weight, isFirstLayer, rotationEuler, localEuler); + pro.localRotationEuler = localEuler; + break; + } + nodeOwner.updateMark = this._updateMark; + } + } + _setClipDatasToNode(stateInfo, additive, weight, isFirstLayer, controllerLayer = null) { + var realtimeDatas = stateInfo._realtimeDatas; + var nodes = stateInfo._clip._nodes; + var nodeOwners = stateInfo._nodeOwners; + for (var i = 0, n = nodes.count; i < n; i++) { + var nodeOwner = nodeOwners[i]; + if (nodeOwner) { + var node = nodes.getNodeByIndex(i); + if (controllerLayer.avatarMask && (!controllerLayer.avatarMask.getTransformActive(node.nodePath))) + continue; + var pro = nodeOwner.propertyOwner; + if (pro) { + switch (nodeOwner.type) { + case 0: + var proPat = nodeOwner.property; + var m = proPat.length - 1; + for (var j = 0; j < m; j++) { + pro = pro[proPat[j]]; + if (!pro) + break; + } + pro && this._applyFloat(pro, proPat[m], nodeOwner, additive, weight, isFirstLayer, realtimeDatas[i]); + break; + case 1: + var localPos = pro.localPosition; + this._applyPositionAndRotationEuler(nodeOwner, additive, weight, isFirstLayer, realtimeDatas[i], localPos); + pro.localPosition = localPos; + break; + case 2: + var localRot = pro.localRotation; + this._applyRotation(nodeOwner, additive, weight, isFirstLayer, realtimeDatas[i], localRot); + pro.localRotation = localRot; + break; + case 3: + var localSca = pro.localScale; + this._applyScale(nodeOwner, additive, weight, isFirstLayer, realtimeDatas[i], localSca); + pro.localScale = localSca; + break; + case 4: + var localEuler = pro.localRotationEuler; + this._applyPositionAndRotationEuler(nodeOwner, additive, weight, isFirstLayer, realtimeDatas[i], localEuler); + pro.localRotationEuler = localEuler; + break; + } + nodeOwner.updateMark = this._updateMark; + } + } + } + } + _setCrossClipDatasToNode(controllerLayer, srcState, destState, crossWeight, isFirstLayer) { + var nodeOwners = controllerLayer._crossNodesOwners; + var ownerCount = controllerLayer._crossNodesOwnersCount; + var additive = controllerLayer.blendingMode !== AnimatorControllerLayer.BLENDINGMODE_OVERRIDE; + var weight = controllerLayer.defaultWeight; + var destRealtimeDatas = destState._realtimeDatas; + var destDataIndices = controllerLayer._destCrossClipNodeIndices; + var destNodeOwners = destState._nodeOwners; + var srcRealtimeDatas = srcState._realtimeDatas; + var srcDataIndices = controllerLayer._srcCrossClipNodeIndices; + var srcNodeOwners = srcState._nodeOwners; + for (var i = 0; i < ownerCount; i++) { + var nodeOwner = nodeOwners[i]; + if (nodeOwner) { + var srcIndex = srcDataIndices[i]; + var destIndex = destDataIndices[i]; + var srcValue = srcIndex !== -1 ? srcRealtimeDatas[srcIndex] : destNodeOwners[destIndex].defaultValue; + var desValue = destIndex !== -1 ? destRealtimeDatas[destIndex] : srcNodeOwners[srcIndex].defaultValue; + this._applyCrossData(nodeOwner, additive, weight, isFirstLayer, srcValue, desValue, crossWeight); + } + } + } + _setFixedCrossClipDatasToNode(controllerLayer, destState, crossWeight, isFirstLayer) { + var nodeOwners = controllerLayer._crossNodesOwners; + var ownerCount = controllerLayer._crossNodesOwnersCount; + var additive = controllerLayer.blendingMode !== AnimatorControllerLayer.BLENDINGMODE_OVERRIDE; + var weight = controllerLayer.defaultWeight; + var destRealtimeDatas = destState._realtimeDatas; + var destDataIndices = controllerLayer._destCrossClipNodeIndices; + for (var i = 0; i < ownerCount; i++) { + var nodeOwner = nodeOwners[i]; + if (nodeOwner) { + var destIndex = destDataIndices[i]; + var srcValue = nodeOwner.crossFixedValue; + var desValue = destIndex !== -1 ? destRealtimeDatas[destIndex] : nodeOwner.defaultValue; + this._applyCrossData(nodeOwner, additive, weight, isFirstLayer, srcValue, desValue, crossWeight); + } + } + } + _revertDefaultKeyframeNodes(clipStateInfo) { + var nodeOwners = clipStateInfo._nodeOwners; + for (var i = 0, n = nodeOwners.length; i < n; i++) { + var nodeOwner = nodeOwners[i]; + if (nodeOwner) { + var pro = nodeOwner.propertyOwner; + if (pro) { + switch (nodeOwner.type) { + case 0: + var proPat = nodeOwner.property; + var m = proPat.length - 1; + for (var j = 0; j < m; j++) { + pro = pro[proPat[j]]; + if (!pro) + break; + } + pro[proPat[m]] = nodeOwner.defaultValue; + break; + case 1: + var locPos = pro.localPosition; + var def = nodeOwner.defaultValue; + locPos.x = def.x; + locPos.y = def.y; + locPos.z = def.z; + pro.localPosition = locPos; + break; + case 2: + var locRot = pro.localRotation; + var defQua = nodeOwner.defaultValue; + locRot.x = defQua.x; + locRot.y = defQua.y; + locRot.z = defQua.z; + locRot.w = defQua.w; + pro.localRotation = locRot; + break; + case 3: + var locSca = pro.localScale; + def = nodeOwner.defaultValue; + locSca.x = def.x; + locSca.y = def.y; + locSca.z = def.z; + pro.localScale = locSca; + break; + case 4: + var locEul = pro.localRotationEuler; + def = nodeOwner.defaultValue; + locEul.x = def.x; + locEul.y = def.y; + locEul.z = def.z; + pro.localRotationEuler = locEul; + break; + default: + throw "Animator:unknown type."; + } + } + } + } + } + _onAdded() { + var parent = this.owner._parent; + this.owner._setHierarchyAnimator(this, parent ? parent._hierarchyAnimator : null); + this.owner._changeAnimatorToLinkSprite3DNoAvatar(this, true, []); + } + _onDestroy() { + for (var i = 0, n = this._controllerLayers.length; i < n; i++) + this._controllerLayers[i]._removeReference(); + var parent = this.owner._parent; + this.owner._clearHierarchyAnimator(this, parent ? parent._hierarchyAnimator : null); + } + _onEnable() { + this.owner._scene._animatorPool.add(this); + for (var i = 0, n = this._controllerLayers.length; i < n; i++) { + if (this._controllerLayers[i].playOnWake) { + var defaultClip = this.getDefaultState(i); + (defaultClip) && (this.play(null, i, 0)); + } + } + } + _onDisable() { + this.owner._scene._animatorPool.remove(this); + } + _handleSpriteOwnersBySprite(isLink, path, sprite) { + for (var i = 0, n = this._controllerLayers.length; i < n; i++) { + var clipStateInfos = this._controllerLayers[i]._states; + for (var j = 0, m = clipStateInfos.length; j < m; j++) { + var clipStateInfo = clipStateInfos[j]; + var clip = clipStateInfo._clip; + var nodePath = path.join("/"); + var ownersNodes = clip._nodesMap[nodePath]; + if (ownersNodes) { + var nodeOwners = clipStateInfo._nodeOwners; + for (var k = 0, p = ownersNodes.length; k < p; k++) { + if (isLink) + this._addKeyframeNodeOwner(nodeOwners, ownersNodes[k], sprite); + else + this._removeKeyframeNodeOwner(nodeOwners, ownersNodes[k]); + } + } + } + } + } + _parse(data) { + var avatarData = data.avatar; + if (avatarData) { + this.avatar = Laya.Loader.getRes(avatarData.path); + var linkSprites = avatarData.linkSprites; + this._linkSprites = linkSprites; + this._linkToSprites(linkSprites); + } + var play = data.playOnWake; + var layersData = data.layers; + for (var i = 0; i < layersData.length; i++) { + var layerData = layersData[i]; + var animatorLayer = new AnimatorControllerLayer(layerData.name); + if (i === 0) + animatorLayer.defaultWeight = 1.0; + else + animatorLayer.defaultWeight = layerData.weight; + var blendingModeData = layerData.blendingMode; + (blendingModeData) && (animatorLayer.blendingMode = blendingModeData); + this.addControllerLayer(animatorLayer); + var states = layerData.states; + for (var j = 0, m = states.length; j < m; j++) { + var state = states[j]; + var clipPath = state.clipPath; + if (clipPath) { + var name = state.name; + var motion; + motion = Laya.Loader.getRes(clipPath); + if (motion) { + var animatorState = new AnimatorState(); + animatorState.name = name; + animatorState.clip = motion; + animatorLayer.addState(animatorState); + (j === 0) && (this.getControllerLayer(i).defaultState = animatorState); + } + } + } + (play !== undefined) && (animatorLayer.playOnWake = play); + let layerMaskData = layerData.avatarMask; + if (layerMaskData) { + let avaMask = new AvatarMask(this); + animatorLayer.avatarMask = avaMask; + for (var bips in layerMaskData) { + avaMask.setTransformActive(bips, layerMaskData[bips]); + } + } + } + var cullingModeData = data.cullingMode; + (cullingModeData !== undefined) && (this.cullingMode = cullingModeData); + } + _update() { + var timer = this.owner._scene.timer; + var delta = timer._delta / 1000.0; + if (this._speed === 0 || delta === 0) + return; + var needRender; + if (this.cullingMode === Animator.CULLINGMODE_CULLCOMPLETELY) { + needRender = false; + for (var i = 0, n = this._renderableSprites.length; i < n; i++) { + if (this._renderableSprites[i]._render.isRender) { + needRender = true; + break; + } + } + } + else { + needRender = true; + } + this._updateMark++; + for (i = 0, n = this._controllerLayers.length; i < n; i++) { + var controllerLayer = this._controllerLayers[i]; + var playStateInfo = controllerLayer._playStateInfo; + var crossPlayStateInfo = controllerLayer._crossPlayStateInfo; + addtive = controllerLayer.blendingMode !== AnimatorControllerLayer.BLENDINGMODE_OVERRIDE; + switch (controllerLayer._playType) { + case 0: + var animatorState = playStateInfo._currentState; + var clip = animatorState._clip; + var speed = this._speed * animatorState.speed; + var finish = playStateInfo._finish; + finish || this._updatePlayer(animatorState, playStateInfo, delta * speed, clip.islooping); + if (needRender) { + var addtive = controllerLayer.blendingMode !== AnimatorControllerLayer.BLENDINGMODE_OVERRIDE; + this._updateClipDatas(animatorState, addtive, playStateInfo, controllerLayer.avatarMask); + this._setClipDatasToNode(animatorState, addtive, controllerLayer.defaultWeight, i === 0, controllerLayer); + finish || this._updateEventScript(animatorState, playStateInfo); + } + playStateInfo._finish && this._updateStateFinish(animatorState, playStateInfo); + break; + case 1: + animatorState = playStateInfo._currentState; + clip = animatorState._clip; + var crossState = controllerLayer._crossPlayState; + var crossClip = crossState._clip; + var crossDuratuion = controllerLayer._crossDuration; + var startPlayTime = crossPlayStateInfo._startPlayTime; + var crossClipDuration = crossClip._duration - startPlayTime; + var crossScale = crossDuratuion > crossClipDuration ? crossClipDuration / crossDuratuion : 1.0; + var crossSpeed = this._speed * crossState.speed; + this._updatePlayer(crossState, crossPlayStateInfo, delta * crossScale * crossSpeed, crossClip.islooping); + var crossWeight = ((crossPlayStateInfo._elapsedTime - startPlayTime) / crossScale) / crossDuratuion; + var needUpdateFinishcurrentState = false; + if (crossWeight >= 1.0) { + if (needRender) { + this._updateClipDatas(crossState, addtive, crossPlayStateInfo, controllerLayer.avatarMask); + this._setClipDatasToNode(crossState, addtive, controllerLayer.defaultWeight, i === 0, controllerLayer); + controllerLayer._playType = 0; + playStateInfo._currentState = crossState; + crossPlayStateInfo._cloneTo(playStateInfo); + } + } + else { + if (!playStateInfo._finish) { + speed = this._speed * animatorState.speed; + needUpdateFinishcurrentState = true; + this._updatePlayer(animatorState, playStateInfo, delta * speed, clip.islooping); + if (needRender) + this._updateClipDatas(animatorState, addtive, playStateInfo, controllerLayer.avatarMask); + } + if (needRender) { + this._updateClipDatas(crossState, addtive, crossPlayStateInfo, controllerLayer.avatarMask); + this._setCrossClipDatasToNode(controllerLayer, animatorState, crossState, crossWeight, i === 0); + } + } + if (needRender) { + this._updateEventScript(animatorState, playStateInfo); + this._updateEventScript(crossState, crossPlayStateInfo); + } + this._updateStateFinish(crossState, crossPlayStateInfo); + needUpdateFinishcurrentState && this._updateStateFinish(playStateInfo._currentState, playStateInfo); + break; + case 2: + crossState = controllerLayer._crossPlayState; + crossClip = crossState._clip; + crossDuratuion = controllerLayer._crossDuration; + startPlayTime = crossPlayStateInfo._startPlayTime; + crossClipDuration = crossClip._duration - startPlayTime; + crossScale = crossDuratuion > crossClipDuration ? crossClipDuration / crossDuratuion : 1.0; + crossSpeed = this._speed * crossState.speed; + this._updatePlayer(crossState, crossPlayStateInfo, delta * crossScale * crossSpeed, crossClip.islooping); + if (needRender) { + crossWeight = ((crossPlayStateInfo._elapsedTime - startPlayTime) / crossScale) / crossDuratuion; + if (crossWeight >= 1.0) { + this._updateClipDatas(crossState, addtive, crossPlayStateInfo, controllerLayer.avatarMask); + this._setClipDatasToNode(crossState, addtive, 1.0, i === 0, controllerLayer); + controllerLayer._playType = 0; + playStateInfo._currentState = crossState; + crossPlayStateInfo._cloneTo(playStateInfo); + } + else { + this._updateClipDatas(crossState, addtive, crossPlayStateInfo, controllerLayer.avatarMask); + this._setFixedCrossClipDatasToNode(controllerLayer, crossState, crossWeight, i === 0); + } + this._updateEventScript(crossState, crossPlayStateInfo); + } + this._updateStateFinish(crossState, crossPlayStateInfo); + break; + } + } + if (needRender) { + if (this._avatar) { + this._updateAvatarNodesToSprite(); + } + } + } + _cloneTo(dest) { + var animator = dest; + animator.avatar = this.avatar; + animator.cullingMode = this.cullingMode; + for (var i = 0, n = this._controllerLayers.length; i < n; i++) { + var controllLayer = this._controllerLayers[i]; + animator.addControllerLayer(controllLayer.clone()); + var animatorStates = controllLayer._states; + for (var j = 0, m = animatorStates.length; j < m; j++) { + var state = animatorStates[j].clone(); + var cloneLayer = animator.getControllerLayer(i); + cloneLayer.addState(state); + (j == 0) && (cloneLayer.defaultState = state); + } + } + animator._linkSprites = this._linkSprites; + animator._linkToSprites(this._linkSprites); + } + getDefaultState(layerIndex = 0) { + var controllerLayer = this._controllerLayers[layerIndex]; + return controllerLayer.defaultState; + } + addState(state, layerIndex = 0) { + var controllerLayer = this._controllerLayers[layerIndex]; + controllerLayer.addState(state); + console.warn("Animator:this function is discard,please use animatorControllerLayer.addState() instead."); + } + removeState(state, layerIndex = 0) { + var controllerLayer = this._controllerLayers[layerIndex]; + controllerLayer.removeState(state); + console.warn("Animator:this function is discard,please use animatorControllerLayer.removeState() instead."); + } + addControllerLayer(controllderLayer) { + this._controllerLayers.push(controllderLayer); + controllderLayer._animator = this; + controllderLayer._addReference(); + var states = controllderLayer._states; + for (var i = 0, n = states.length; i < n; i++) + this._getOwnersByClip(states[i]); + } + getControllerLayer(layerInex = 0) { + return this._controllerLayers[layerInex]; + } + play(name = null, layerIndex = 0, normalizedTime = Number.NEGATIVE_INFINITY) { + var controllerLayer = this._controllerLayers[layerIndex]; + if (controllerLayer) { + var defaultState = controllerLayer.defaultState; + if (!name && !defaultState) + throw new Error("Animator:must have default clip value,please set clip property."); + var playStateInfo = controllerLayer._playStateInfo; + var curPlayState = playStateInfo._currentState; + var animatorState = name ? controllerLayer._statesMap[name] : defaultState; + var clipDuration = animatorState._clip._duration; + var calclipduration = animatorState._clip._duration * (animatorState.clipEnd - animatorState.clipStart); + if (curPlayState !== animatorState) { + if (normalizedTime !== Number.NEGATIVE_INFINITY) + playStateInfo._resetPlayState(clipDuration * normalizedTime, calclipduration); + else + playStateInfo._resetPlayState(0.0, calclipduration); + (curPlayState !== null && curPlayState !== animatorState) && (this._revertDefaultKeyframeNodes(curPlayState)); + controllerLayer._playType = 0; + playStateInfo._currentState = animatorState; + } + else { + if (normalizedTime !== Number.NEGATIVE_INFINITY) { + playStateInfo._resetPlayState(clipDuration * normalizedTime, calclipduration); + controllerLayer._playType = 0; + } + } + var scripts = animatorState._scripts; + if (scripts) { + for (var i = 0, n = scripts.length; i < n; i++) + scripts[i].onStateEnter(); + } + } + else { + console.warn("Invalid layerIndex " + layerIndex + "."); + } + if (this.owner._scene) { + this._update(); + } + } + crossFade(name, transitionDuration, layerIndex = 0, normalizedTime = Number.NEGATIVE_INFINITY) { + var controllerLayer = this._controllerLayers[layerIndex]; + if (controllerLayer) { + var destAnimatorState = controllerLayer._statesMap[name]; + if (destAnimatorState) { + var playType = controllerLayer._playType; + if (playType === -1) { + this.play(name, layerIndex, normalizedTime); + return; + } + var crossPlayStateInfo = controllerLayer._crossPlayStateInfo; + var crossNodeOwners = controllerLayer._crossNodesOwners; + var crossNodeOwnerIndicesMap = controllerLayer._crossNodesOwnersIndicesMap; + var srcAnimatorState = controllerLayer._playStateInfo._currentState; + var destNodeOwners = destAnimatorState._nodeOwners; + var destCrossClipNodeIndices = controllerLayer._destCrossClipNodeIndices; + var destClip = destAnimatorState._clip; + var destNodes = destClip._nodes; + var destNodesMap = destClip._nodesDic; + var crossCount = 0; + switch (playType) { + case 0: + var srcNodeOwners = srcAnimatorState._nodeOwners; + var scrCrossClipNodeIndices = controllerLayer._srcCrossClipNodeIndices; + var srcClip = srcAnimatorState._clip; + var srcNodes = srcClip._nodes; + var srcNodesMap = srcClip._nodesDic; + controllerLayer._playType = 1; + var crossMark = ++controllerLayer._crossMark; + crossCount = controllerLayer._crossNodesOwnersCount = 0; + for (var i = 0, n = srcNodes.count; i < n; i++) { + var srcNode = srcNodes.getNodeByIndex(i); + var srcIndex = srcNode._indexInList; + var srcNodeOwner = srcNodeOwners[srcIndex]; + if (srcNodeOwner) { + var srcFullPath = srcNode.fullPath; + scrCrossClipNodeIndices[crossCount] = srcIndex; + var destNode = destNodesMap[srcFullPath]; + if (destNode) + destCrossClipNodeIndices[crossCount] = destNode._indexInList; + else + destCrossClipNodeIndices[crossCount] = -1; + crossNodeOwnerIndicesMap[srcFullPath] = crossMark; + crossNodeOwners[crossCount] = srcNodeOwner; + crossCount++; + } + } + for (i = 0, n = destNodes.count; i < n; i++) { + destNode = destNodes.getNodeByIndex(i); + var destIndex = destNode._indexInList; + var destNodeOwner = destNodeOwners[destIndex]; + if (destNodeOwner) { + var destFullPath = destNode.fullPath; + if (!srcNodesMap[destFullPath]) { + scrCrossClipNodeIndices[crossCount] = -1; + destCrossClipNodeIndices[crossCount] = destIndex; + crossNodeOwnerIndicesMap[destFullPath] = crossMark; + crossNodeOwners[crossCount] = destNodeOwner; + crossCount++; + } + } + } + break; + case 1: + case 2: + controllerLayer._playType = 2; + for (i = 0, n = crossNodeOwners.length; i < n; i++) { + var nodeOwner = crossNodeOwners[i]; + nodeOwner.saveCrossFixedValue(); + destNode = destNodesMap[nodeOwner.fullPath]; + if (destNode) + destCrossClipNodeIndices[i] = destNode._indexInList; + else + destCrossClipNodeIndices[i] = -1; + } + crossCount = controllerLayer._crossNodesOwnersCount; + crossMark = controllerLayer._crossMark; + for (i = 0, n = destNodes.count; i < n; i++) { + destNode = destNodes.getNodeByIndex(i); + destIndex = destNode._indexInList; + destNodeOwner = destNodeOwners[destIndex]; + if (destNodeOwner) { + destFullPath = destNode.fullPath; + if (crossNodeOwnerIndicesMap[destFullPath] !== crossMark) { + destCrossClipNodeIndices[crossCount] = destIndex; + crossNodeOwnerIndicesMap[destFullPath] = crossMark; + nodeOwner = destNodeOwners[destIndex]; + crossNodeOwners[crossCount] = nodeOwner; + nodeOwner.saveCrossFixedValue(); + crossCount++; + } + } + } + break; + } + controllerLayer._crossNodesOwnersCount = crossCount; + controllerLayer._crossPlayState = destAnimatorState; + controllerLayer._crossDuration = srcAnimatorState._clip._duration * transitionDuration; + if (normalizedTime !== Number.NEGATIVE_INFINITY) + crossPlayStateInfo._resetPlayState(destClip._duration * normalizedTime, controllerLayer._crossDuration); + else + crossPlayStateInfo._resetPlayState(0.0, controllerLayer._crossDuration); + var scripts = destAnimatorState._scripts; + if (scripts) { + for (i = 0, n = scripts.length; i < n; i++) + scripts[i].onStateEnter(); + } + } + else { + console.warn("Invalid name " + layerIndex + "."); + } + } + else { + console.warn("Invalid layerIndex " + layerIndex + "."); + } + } + getCurrentAnimatorPlayState(layerInex = 0) { + return this._controllerLayers[layerInex]._playStateInfo; + } + get avatar() { + return this._avatar; + } + set avatar(value) { + if (this._avatar !== value) { + this._avatar = value; + if (value) { + this._getAvatarOwnersAndInitDatasAsync(); + this.owner._changeHierarchyAnimatorAvatar(this, value); + } + else { + var parent = this.owner._parent; + this.owner._changeHierarchyAnimatorAvatar(this, parent ? parent._hierarchyAnimator._avatar : null); + } + } + } + _isLinkSpriteToAnimationNodeData(sprite, nodeName, isLink) { + var linkSprites = this._linkAvatarSpritesData[nodeName]; + if (isLink) { + linkSprites || (this._linkAvatarSpritesData[nodeName] = linkSprites = []); + linkSprites.push(sprite); + } + else { + var index = linkSprites.indexOf(sprite); + linkSprites.splice(index, 1); + } + } + _getAvatarOwnersAndInitDatasAsync() { + for (var i = 0, n = this._controllerLayers.length; i < n; i++) { + var clipStateInfos = this._controllerLayers[i]._states; + for (var j = 0, m = clipStateInfos.length; j < m; j++) + this._getOwnersByClip(clipStateInfos[j]); + } + this._avatar._cloneDatasToAnimator(this); + for (var k in this._linkAvatarSpritesData) { + var sprites = this._linkAvatarSpritesData[k]; + if (sprites) { + for (var c = 0, p = sprites.length; c < p; c++) + this._isLinkSpriteToAnimationNode(sprites[c], k, true); + } + } + } + _isLinkSpriteToAnimationNode(sprite, nodeName, isLink) { + if (this._avatar) { + var node = this._avatarNodeMap[nodeName]; + if (node) { + if (isLink) { + sprite._transform._dummy = node.transform; + this._linkAvatarSprites.push(sprite); + var nodeTransform = node.transform; + var spriteTransform = sprite.transform; + if (!spriteTransform.owner.isStatic && nodeTransform) { + var spriteWorldMatrix = spriteTransform.worldMatrix; + var ownParTra = this.owner._transform._parent; + if (ownParTra) { + Utils3D.matrix4x4MultiplyMFM(ownParTra.worldMatrix, nodeTransform.getWorldMatrix(), spriteWorldMatrix); + } + else { + var sprWorE = spriteWorldMatrix.elements; + var nodWorE = nodeTransform.getWorldMatrix(); + for (var i = 0; i < 16; i++) + sprWorE[i] = nodWorE[i]; + } + spriteTransform.worldMatrix = spriteWorldMatrix; + } + } + else { + sprite._transform._dummy = null; + this._linkAvatarSprites.splice(this._linkAvatarSprites.indexOf(sprite), 1); + } + } + } + } + _updateAvatarNodesToSprite() { + for (var i = 0, n = this._linkAvatarSprites.length; i < n; i++) { + var sprite = this._linkAvatarSprites[i]; + var nodeTransform = sprite.transform._dummy; + var spriteTransform = sprite.transform; + if (!spriteTransform.owner.isStatic && nodeTransform) { + var spriteWorldMatrix = spriteTransform.worldMatrix; + var ownTra = this.owner._transform; + Utils3D.matrix4x4MultiplyMFM(ownTra.worldMatrix, nodeTransform.getWorldMatrix(), spriteWorldMatrix); + spriteTransform.worldMatrix = spriteWorldMatrix; + } + } + } + linkSprite3DToAvatarNode(nodeName, sprite3D) { + this._isLinkSpriteToAnimationNodeData(sprite3D, nodeName, true); + this._isLinkSpriteToAnimationNode(sprite3D, nodeName, true); + return true; + } + unLinkSprite3DToAvatarNode(sprite3D) { + var dummy = sprite3D.transform._dummy; + if (dummy) { + var nodeName = dummy._owner.name; + this._isLinkSpriteToAnimationNodeData(sprite3D, nodeName, false); + this._isLinkSpriteToAnimationNode(sprite3D, nodeName, false); + return true; + } + else { + return false; + } + } + _updateAnimationNodeWorldMatix(localPositions, localRotations, localScales, worldMatrixs, parentIndices) { + Laya.LayaGL.instance.updateAnimationNodeWorldMatix(localPositions, localRotations, localScales, parentIndices, worldMatrixs); + } + } + Animator._tempVector31 = new Vector3(); + Animator._tempQuaternion1 = new Quaternion(); + Animator.CULLINGMODE_ALWAYSANIMATE = 0; + Animator.CULLINGMODE_CULLCOMPLETELY = 2; + + class RenderContext3D { + constructor() { + this.invertY = false; + this.configPipeLineMode = "Forward"; + } + } + RenderContext3D._instance = new RenderContext3D(); + + class RenderTexture extends Laya.BaseTexture { + constructor(width, height, format = Laya.RenderTextureFormat.R8G8B8, depthStencilFormat = Laya.RenderTextureDepthFormat.DEPTH_16, mulSampler = 1) { + super(format, false); + this._inPool = false; + this._mulSampler = 1; + this._mulSamplerRT = false; + this._isCameraTarget = false; + this._glTextureType = Laya.LayaGL.instance.TEXTURE_2D; + this._width = width; + this._height = height; + this._depthStencilFormat = depthStencilFormat; + this._mipmapCount = 1; + this._mulSampler = mulSampler; + this._create(width, height); + } + static get currentActive() { + return RenderTexture._currentActive; + } + static createFromPool(width, height, format = Laya.RenderTextureFormat.R8G8B8, depthStencilFormat = Laya.RenderTextureDepthFormat.DEPTH_16, mulSamples = 1) { + var tex; + for (var i = 0, n = RenderTexture._pool.length; i < n; i++) { + tex = RenderTexture._pool[i]; + if (tex._width == width && tex._height == height && tex._format == format && tex._depthStencilFormat == depthStencilFormat && tex._mulSampler == mulSamples) { + tex._inPool = false; + var end = RenderTexture._pool[n - 1]; + RenderTexture._pool[i] = end; + RenderTexture._pool.length -= 1; + return tex; + } + } + tex = new RenderTexture(width, height, format, depthStencilFormat, mulSamples); + tex.lock = true; + return tex; + } + static recoverToPool(renderTexture) { + if (renderTexture._inPool) + return; + RenderTexture._pool.push(renderTexture); + renderTexture._inPool = true; + } + get depthStencilFormat() { + return this._depthStencilFormat; + } + get defaulteTexture() { + return Laya.Texture2D.grayTexture; + } + get mulSampler() { + return this._mulSampler; + } + _create(width, height) { + var gl = Laya.LayaGL.instance; + var gl2 = gl; + var glTextureType = this._glTextureType; + var layaGPU = Laya.LayaGL.layaGPUInstance; + var isWebGL2 = layaGPU._isWebGL2; + var format = this._format; + this._frameBuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer); + this._mulSamplerRT = isWebGL2 && (this._mulSampler > 1); + if (format !== Laya.RenderTextureFormat.Depth && format !== Laya.RenderTextureFormat.ShadowMap) { + if (this._mulSamplerRT) { + this._mulRenderBuffer = gl2.createRenderbuffer(); + gl2.bindRenderbuffer(gl2.RENDERBUFFER, this._mulRenderBuffer); + switch (format) { + case Laya.RenderTextureFormat.R8G8B8: + gl2.renderbufferStorageMultisample(gl2.RENDERBUFFER, this._mulSampler, gl2.RGB8, width, height); + break; + case Laya.RenderTextureFormat.R8G8B8A8: + gl2.renderbufferStorageMultisample(gl2.RENDERBUFFER, this._mulSampler, gl2.RGBA8, width, height); + break; + case Laya.RenderTextureFormat.Alpha8: + gl2.renderbufferStorageMultisample(gl2.RENDERBUFFER, this._mulSampler, gl2.ALPHA, width, height); + break; + case Laya.RenderTextureFormat.R16G16B16A16: + gl2.renderbufferStorageMultisample(gl2.RENDERBUFFER, this._mulSampler, gl2.RGBA16F, width, height); + break; + } + gl2.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, this._mulRenderBuffer); + } + Laya.WebGLContext.bindTexture(gl, glTextureType, this._glTexture); + switch (format) { + case Laya.RenderTextureFormat.R8G8B8: + if (isWebGL2) + gl2.texStorage2D(glTextureType, this._mipmapCount, gl2.RGB8, width, height); + else + gl.texImage2D(glTextureType, 0, gl.RGB, width, height, 0, gl.RGB, gl.UNSIGNED_BYTE, null); + break; + case Laya.RenderTextureFormat.R8G8B8A8: + if (isWebGL2) + gl2.texStorage2D(glTextureType, this._mipmapCount, gl2.RGBA8, width, height); + else + gl.texImage2D(glTextureType, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + break; + case Laya.RenderTextureFormat.Alpha8: + if (isWebGL2) + gl2.texStorage2D(glTextureType, this.mipmapCount, gl2.R8, width, height); + else + gl.texImage2D(glTextureType, 0, gl.ALPHA, width, height, 0, gl.ALPHA, gl.UNSIGNED_BYTE, null); + break; + case Laya.RenderTextureFormat.R16G16B16A16: + if (isWebGL2) + gl2.texStorage2D(glTextureType, this._mipmapCount, gl2.RGBA16F, width, height); + else + gl.texImage2D(glTextureType, 0, gl.RGBA, width, height, 0, gl.RGBA, layaGPU._oesTextureHalfFloat.HALF_FLOAT_OES, null); + break; + } + if (this._mulSamplerRT) { + this._mulFrameBuffer = gl2.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, this._mulFrameBuffer); + gl.framebufferTexture2D(gl2.FRAMEBUFFER, gl2.COLOR_ATTACHMENT0, gl2.TEXTURE_2D, this._glTexture, 0); + } + else + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this._glTexture, 0); + } + if (format == Laya.RenderTextureFormat.Depth || format == Laya.RenderTextureFormat.ShadowMap) { + gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer); + Laya.WebGLContext.bindTexture(gl, glTextureType, this._glTexture); + this.filterMode = Laya.FilterMode.Point; + switch (this._depthStencilFormat) { + case Laya.RenderTextureDepthFormat.DEPTH_16: + if (isWebGL2) { + gl2.texStorage2D(glTextureType, this._mipmapCount, gl2.DEPTH_COMPONENT16, width, height); + } + else + gl.texImage2D(glTextureType, 0, gl.DEPTH_COMPONENT, width, height, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, this._glTexture, 0); + break; + case Laya.RenderTextureDepthFormat.DEPTHSTENCIL_24_8: + if (isWebGL2) + gl2.texStorage2D(glTextureType, this._mipmapCount, gl2.DEPTH24_STENCIL8, width, height); + else + gl.texImage2D(glTextureType, 0, gl.DEPTH_STENCIL, width, height, 0, gl.DEPTH_STENCIL, layaGPU._webgl_depth_texture.UNSIGNED_INT_24_8_WEBGL, null); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.TEXTURE_2D, this._glTexture, 0); + break; + default: + throw "RenderTexture: depth format RenderTexture must use depthFormat with DEPTH_16 and DEPTHSTENCIL_16_8."; + } + if (isWebGL2 && format == Laya.RenderTextureFormat.ShadowMap) + gl2.texParameteri(glTextureType, gl2.TEXTURE_COMPARE_MODE, gl2.COMPARE_REF_TO_TEXTURE); + } + else { + gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer); + if (this._depthStencilFormat !== Laya.RenderTextureDepthFormat.DEPTHSTENCIL_NONE) { + this._depthStencilBuffer = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, this._depthStencilBuffer); + if (this._mulSamplerRT) { + switch (this._depthStencilFormat) { + case Laya.RenderTextureDepthFormat.DEPTH_16: + gl2.renderbufferStorageMultisample(gl.RENDERBUFFER, this._mulSampler, gl2.DEPTH_COMPONENT16, width, height); + gl2.framebufferRenderbuffer(gl.FRAMEBUFFER, gl2.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this._depthStencilBuffer); + break; + case Laya.RenderTextureDepthFormat.STENCIL_8: + gl2.renderbufferStorageMultisample(gl.RENDERBUFFER, this._mulSampler, gl2.STENCIL_INDEX8, width, height); + gl2.framebufferRenderbuffer(gl.FRAMEBUFFER, gl2.STENCIL_ATTACHMENT, gl.RENDERBUFFER, this._depthStencilBuffer); + break; + case Laya.RenderTextureDepthFormat.DEPTHSTENCIL_24_8: + gl2.renderbufferStorageMultisample(gl.RENDERBUFFER, this._mulSampler, gl2.DEPTH_STENCIL, width, height); + gl2.framebufferRenderbuffer(gl.FRAMEBUFFER, gl2.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this._depthStencilBuffer); + break; + default: + throw "RenderTexture: unkonw depth format."; + } + } + else { + switch (this._depthStencilFormat) { + case Laya.RenderTextureDepthFormat.DEPTH_16: + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl2.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this._depthStencilBuffer); + break; + case Laya.RenderTextureDepthFormat.STENCIL_8: + gl.renderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, width, height); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, this._depthStencilBuffer); + break; + case Laya.RenderTextureDepthFormat.DEPTHSTENCIL_24_8: + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this._depthStencilBuffer); + break; + default: + throw "RenderTexture: unkonw depth format."; + } + } + gl.bindRenderbuffer(gl.RENDERBUFFER, null); + } + } + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + this._setWarpMode(gl.TEXTURE_WRAP_S, this._wrapModeU); + this._setWarpMode(gl.TEXTURE_WRAP_T, this._wrapModeV); + this._setFilterMode(this._filterMode); + this._setAnisotropy(this._anisoLevel); + this._readyed = true; + this._activeResource(); + this._setGPUMemory(width * height * 4); + } + _start() { + var gl = Laya.LayaGL.instance; + gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer); + RenderTexture._currentActive = this; + (this._isCameraTarget) && (RenderContext3D._instance.invertY = true); + this._readyed = false; + } + _end() { + var gl = Laya.LayaGL.instance; + var gl2 = gl; + if (this._mulSamplerRT) { + gl2.bindFramebuffer(gl2.READ_FRAMEBUFFER, this._frameBuffer); + gl2.bindFramebuffer(gl2.DRAW_FRAMEBUFFER, this._mulFrameBuffer); + gl2.clearBufferfv(gl2.COLOR, 0, [0.0, 0.0, 0.0, 0.0]); + gl2.blitFramebuffer(0, 0, this.width, this.height, 0, 0, this._width, this._height, gl2.COLOR_BUFFER_BIT, gl.NEAREST); + } + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + RenderTexture._currentActive = null; + (this._isCameraTarget) && (RenderContext3D._instance.invertY = false); + this._readyed = true; + } + getData(x, y, width, height, out) { + if (Laya.Render.isConchApp && window.conchConfig.threadMode == 2) { + throw "native 2 thread mode use getDataAsync"; + } + var gl = Laya.LayaGL.instance; + gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer); + var canRead = (gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE); + if (!canRead) { + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + return null; + } + switch (this.format) { + case Laya.RenderTextureFormat.R8G8B8: + gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, out); + break; + case Laya.RenderTextureFormat.R8G8B8A8: + gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, out); + break; + case Laya.RenderTextureFormat.R16G16B16A16: + gl.readPixels(x, y, width, height, gl.RGBA, gl.FLOAT, out); + debugger; + break; + } + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + return out; + } + _disposeResource() { + if (this._frameBuffer) { + var gl = Laya.LayaGL.instance; + gl.deleteTexture(this._glTexture); + gl.deleteFramebuffer(this._frameBuffer); + gl.deleteRenderbuffer(this._depthStencilBuffer); + this._glTexture = null; + this._frameBuffer = null; + this._depthStencilBuffer = null; + this._setGPUMemory(0); + } + } + getDataAsync(x, y, width, height, callBack) { + var gl = Laya.LayaGL.instance; + gl.bindFramebuffer(gl.FRAMEBUFFER, this._frameBuffer); + gl.readPixelsAsync(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, function (data) { + callBack(new Uint8Array(data)); + }); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + } + } + RenderTexture._pool = []; + + class DefineDatas { + constructor() { + this._mask = []; + this._length = 0; + } + _intersectionDefineDatas(define) { + var unionMask = define._mask; + var mask = this._mask; + for (var i = this._length - 1; i >= 0; i--) { + var value = mask[i] & unionMask[i]; + if (value == 0 && i == this._length - 1) + this._length--; + else + mask[i] = value; + } + } + add(define) { + var index = define._index; + var size = index + 1; + var mask = this._mask; + var maskStart = this._length; + if (maskStart < size) { + (mask.length < size) && (mask.length = size); + for (; maskStart < index; maskStart++) + mask[maskStart] = 0; + mask[index] = define._value; + this._length = size; + } + else { + mask[index] |= define._value; + } + } + remove(define) { + var index = define._index; + var mask = this._mask; + var endIndex = this._length - 1; + if (index > endIndex) + return; + var newValue = mask[index] & ~define._value; + if (index == endIndex && newValue === 0) + this._length--; + else + mask[index] = newValue; + } + addDefineDatas(define) { + var addMask = define._mask; + var size = define._length; + var mask = this._mask; + var maskStart = this._length; + if (maskStart < size) { + mask.length = size; + for (var i = 0; i < maskStart; i++) + mask[i] |= addMask[i]; + for (; i < size; i++) + mask[i] = addMask[i]; + this._length = size; + } + else { + for (var i = 0; i < size; i++) { + mask[i] |= addMask[i]; + } + } + } + removeDefineDatas(define) { + var removeMask = define._mask; + var mask = this._mask; + var endIndex = this._length - 1; + var i = Math.min(define._length, endIndex); + for (; i >= 0; i--) { + var newValue = mask[i] & ~removeMask[i]; + if (i == endIndex && newValue === 0) { + endIndex--; + this._length--; + } + else { + mask[i] = newValue; + } + } + } + has(define) { + var index = define._index; + if (index >= this._length) + return false; + return (this._mask[index] & define._value) !== 0; + } + clear() { + this._length = 0; + } + cloneTo(destObject) { + var destDefineData = destObject; + var destMask = destDefineData._mask; + var mask = this._mask; + var count = this._length; + destMask.length = count; + for (var i = 0; i < count; i++) + destMask[i] = mask[i]; + destDefineData._length = count; + } + clone() { + var dest = new DefineDatas(); + this.cloneTo(dest); + return dest; + } + } + + class VertexBuffer3D extends Laya.Buffer { + constructor(byteLength, bufferUsage, canRead = false) { + super(); + this._vertexDeclaration = null; + this._float32Reader = null; + var gl = Laya.LayaGL.instance; + this._bufferUsage = bufferUsage; + this._bufferType = gl.ARRAY_BUFFER; + this._canRead = canRead; + this._byteLength = byteLength; + this.bind(); + gl.bufferData(this._bufferType, this._byteLength, this._bufferUsage); + if (canRead) { + this._buffer = new Uint8Array(byteLength); + this._float32Reader = new Float32Array(this._buffer.buffer); + } + } + get vertexDeclaration() { + return this._vertexDeclaration; + } + set vertexDeclaration(value) { + this._vertexDeclaration = value; + } + get canRead() { + return this._canRead; + } + bind() { + if (Laya.Buffer._bindedVertexBuffer !== this._glBuffer) { + var gl = Laya.LayaGL.instance; + gl.bindBuffer(gl.ARRAY_BUFFER, this._glBuffer); + Laya.Buffer._bindedVertexBuffer = this._glBuffer; + return true; + } + else { + return false; + } + } + orphanStorage() { + this.bind(); + Laya.LayaGL.instance.bufferData(this._bufferType, this._byteLength, this._bufferUsage); + } + setData(buffer, bufferOffset = 0, dataStartIndex = 0, dataCount = Number.MAX_SAFE_INTEGER) { + this.bind(); + var needSubData = dataStartIndex !== 0 || dataCount !== Number.MAX_SAFE_INTEGER; + if (needSubData) { + var subData = new Uint8Array(buffer, dataStartIndex, dataCount); + Laya.LayaGL.instance.bufferSubData(this._bufferType, bufferOffset, subData); + if (this._canRead) + this._buffer.set(subData, bufferOffset); + } + else { + Laya.LayaGL.instance.bufferSubData(this._bufferType, bufferOffset, buffer); + if (this._canRead) + this._buffer.set(new Uint8Array(buffer), bufferOffset); + } + } + getUint8Data() { + if (this._canRead) + return this._buffer; + else + throw new Error("Can't read data from VertexBuffer with only write flag!"); + } + getFloat32Data() { + if (this._canRead) + return this._float32Reader; + else + throw new Error("Can't read data from VertexBuffer with only write flag!"); + } + markAsUnreadbale() { + this._canRead = false; + this._buffer = null; + this._float32Reader = null; + } + destroy() { + super.destroy(); + this._buffer = null; + this._float32Reader = null; + this._vertexDeclaration = null; + this._byteLength = 0; + } + } + VertexBuffer3D.DATATYPE_FLOAT32ARRAY = 0; + VertexBuffer3D.DATATYPE_UINT8ARRAY = 1; + + class VertexElementFormat { + static __init__() { + var gl = Laya.LayaGL.instance; + VertexElementFormat._elementInfos = { + "single": [1, gl.FLOAT, 0], + "vector2": [2, gl.FLOAT, 0], + "vector3": [3, gl.FLOAT, 0], + "vector4": [4, gl.FLOAT, 0], + "color": [4, gl.FLOAT, 0], + "byte4": [4, gl.UNSIGNED_BYTE, 0], + "byte3": [3, gl.UNSIGNED_BYTE, 0], + "byte2": [2, gl.UNSIGNED_BYTE, 0], + "byte": [1, gl.UNSIGNED_BYTE, 0], + "short2": [2, gl.FLOAT, 0], + "short4": [4, gl.FLOAT, 0], + "normalizedshort2": [2, gl.FLOAT, 0], + "normalizedshort4": [4, gl.FLOAT, 0], + "halfvector2": [2, gl.FLOAT, 0], + "halfvector4": [4, gl.FLOAT, 0] + }; + } + static getElementInfos(element) { + var info = VertexElementFormat._elementInfos[element]; + if (info) + return info; + else + throw "VertexElementFormat: this vertexElementFormat is not implement."; + } + } + VertexElementFormat.Single = "single"; + VertexElementFormat.Vector2 = "vector2"; + VertexElementFormat.Vector3 = "vector3"; + VertexElementFormat.Vector4 = "vector4"; + VertexElementFormat.Color = "color"; + VertexElementFormat.Byte4 = "byte4"; + VertexElementFormat.Byte3 = "byte3"; + VertexElementFormat.Byte2 = "byte2"; + VertexElementFormat.ByteOne = "byte"; + VertexElementFormat.Short2 = "short2"; + VertexElementFormat.Short4 = "short4"; + VertexElementFormat.NormalizedShort2 = "normalizedshort2"; + VertexElementFormat.NormalizedShort4 = "normalizedshort4"; + VertexElementFormat.HalfVector2 = "halfvector2"; + VertexElementFormat.HalfVector4 = "halfvector4"; + + class Matrix4x4 { + constructor(m11 = 1, m12 = 0, m13 = 0, m14 = 0, m21 = 0, m22 = 1, m23 = 0, m24 = 0, m31 = 0, m32 = 0, m33 = 1, m34 = 0, m41 = 0, m42 = 0, m43 = 0, m44 = 1, elements = null) { + var e = elements ? this.elements = elements : this.elements = new Float32Array(16); + e[0] = m11; + e[1] = m12; + e[2] = m13; + e[3] = m14; + e[4] = m21; + e[5] = m22; + e[6] = m23; + e[7] = m24; + e[8] = m31; + e[9] = m32; + e[10] = m33; + e[11] = m34; + e[12] = m41; + e[13] = m42; + e[14] = m43; + e[15] = m44; + } + static createRotationX(rad, out) { + var oe = out.elements; + var s = Math.sin(rad), c = Math.cos(rad); + oe[1] = oe[2] = oe[3] = oe[4] = oe[7] = oe[8] = oe[11] = oe[12] = oe[13] = oe[14] = 0; + oe[0] = oe[15] = 1; + oe[5] = oe[10] = c; + oe[6] = s; + oe[9] = -s; + } + static createRotationY(rad, out) { + var oe = out.elements; + var s = Math.sin(rad), c = Math.cos(rad); + oe[1] = oe[3] = oe[4] = oe[6] = oe[7] = oe[9] = oe[11] = oe[12] = oe[13] = oe[14] = 0; + oe[5] = oe[15] = 1; + oe[0] = oe[10] = c; + oe[2] = -s; + oe[8] = s; + } + static createRotationZ(rad, out) { + var oe = out.elements; + var s = Math.sin(rad), c = Math.cos(rad); + oe[2] = oe[3] = oe[6] = oe[7] = oe[8] = oe[9] = oe[11] = oe[12] = oe[13] = oe[14] = 0; + oe[10] = oe[15] = 1; + oe[0] = oe[5] = c; + oe[1] = s; + oe[4] = -s; + } + static createRotationYawPitchRoll(yaw, pitch, roll, result) { + Quaternion.createFromYawPitchRoll(yaw, pitch, roll, Matrix4x4._tempQuaternion); + Matrix4x4.createRotationQuaternion(Matrix4x4._tempQuaternion, result); + } + static createRotationAxis(axis, angle, result) { + var x = axis.x; + var y = axis.y; + var z = axis.z; + var cos = Math.cos(angle); + var sin = Math.sin(angle); + var xx = x * x; + var yy = y * y; + var zz = z * z; + var xy = x * y; + var xz = x * z; + var yz = y * z; + var resultE = result.elements; + resultE[3] = resultE[7] = resultE[11] = resultE[12] = resultE[13] = resultE[14] = 0; + resultE[15] = 1.0; + resultE[0] = xx + (cos * (1.0 - xx)); + resultE[1] = (xy - (cos * xy)) + (sin * z); + resultE[2] = (xz - (cos * xz)) - (sin * y); + resultE[4] = (xy - (cos * xy)) - (sin * z); + resultE[5] = yy + (cos * (1.0 - yy)); + resultE[6] = (yz - (cos * yz)) + (sin * x); + resultE[8] = (xz - (cos * xz)) + (sin * y); + resultE[9] = (yz - (cos * yz)) - (sin * x); + resultE[10] = zz + (cos * (1.0 - zz)); + } + setRotation(rotation) { + var rotationX = rotation.x; + var rotationY = rotation.y; + var rotationZ = rotation.z; + var rotationW = rotation.w; + var xx = rotationX * rotationX; + var yy = rotationY * rotationY; + var zz = rotationZ * rotationZ; + var xy = rotationX * rotationY; + var zw = rotationZ * rotationW; + var zx = rotationZ * rotationX; + var yw = rotationY * rotationW; + var yz = rotationY * rotationZ; + var xw = rotationX * rotationW; + var e = this.elements; + e[0] = 1.0 - (2.0 * (yy + zz)); + e[1] = 2.0 * (xy + zw); + e[2] = 2.0 * (zx - yw); + e[4] = 2.0 * (xy - zw); + e[5] = 1.0 - (2.0 * (zz + xx)); + e[6] = 2.0 * (yz + xw); + e[8] = 2.0 * (zx + yw); + e[9] = 2.0 * (yz - xw); + e[10] = 1.0 - (2.0 * (yy + xx)); + } + setPosition(position) { + var e = this.elements; + e[12] = position.x; + e[13] = position.y; + e[14] = position.z; + } + static createRotationQuaternion(rotation, result) { + var resultE = result.elements; + var rotationX = rotation.x; + var rotationY = rotation.y; + var rotationZ = rotation.z; + var rotationW = rotation.w; + var xx = rotationX * rotationX; + var yy = rotationY * rotationY; + var zz = rotationZ * rotationZ; + var xy = rotationX * rotationY; + var zw = rotationZ * rotationW; + var zx = rotationZ * rotationX; + var yw = rotationY * rotationW; + var yz = rotationY * rotationZ; + var xw = rotationX * rotationW; + resultE[3] = resultE[7] = resultE[11] = resultE[12] = resultE[13] = resultE[14] = 0; + resultE[15] = 1.0; + resultE[0] = 1.0 - (2.0 * (yy + zz)); + resultE[1] = 2.0 * (xy + zw); + resultE[2] = 2.0 * (zx - yw); + resultE[4] = 2.0 * (xy - zw); + resultE[5] = 1.0 - (2.0 * (zz + xx)); + resultE[6] = 2.0 * (yz + xw); + resultE[8] = 2.0 * (zx + yw); + resultE[9] = 2.0 * (yz - xw); + resultE[10] = 1.0 - (2.0 * (yy + xx)); + } + static createTranslate(trans, out) { + var oe = out.elements; + oe[4] = oe[8] = oe[1] = oe[9] = oe[2] = oe[6] = oe[3] = oe[7] = oe[11] = 0; + oe[0] = oe[5] = oe[10] = oe[15] = 1; + oe[12] = trans.x; + oe[13] = trans.y; + oe[14] = trans.z; + } + static createScaling(scale, out) { + var oe = out.elements; + oe[0] = scale.x; + oe[5] = scale.y; + oe[10] = scale.z; + oe[1] = oe[4] = oe[8] = oe[12] = oe[9] = oe[13] = oe[2] = oe[6] = oe[14] = oe[3] = oe[7] = oe[11] = 0; + oe[15] = 1; + } + static multiply(left, right, out) { + var l = right.elements; + var r = left.elements; + var e = out.elements; + var l11 = l[0], l12 = l[1], l13 = l[2], l14 = l[3]; + var l21 = l[4], l22 = l[5], l23 = l[6], l24 = l[7]; + var l31 = l[8], l32 = l[9], l33 = l[10], l34 = l[11]; + var l41 = l[12], l42 = l[13], l43 = l[14], l44 = l[15]; + var r11 = r[0], r12 = r[1], r13 = r[2], r14 = r[3]; + var r21 = r[4], r22 = r[5], r23 = r[6], r24 = r[7]; + var r31 = r[8], r32 = r[9], r33 = r[10], r34 = r[11]; + var r41 = r[12], r42 = r[13], r43 = r[14], r44 = r[15]; + e[0] = (l11 * r11) + (l12 * r21) + (l13 * r31) + (l14 * r41); + e[1] = (l11 * r12) + (l12 * r22) + (l13 * r32) + (l14 * r42); + e[2] = (l11 * r13) + (l12 * r23) + (l13 * r33) + (l14 * r43); + e[3] = (l11 * r14) + (l12 * r24) + (l13 * r34) + (l14 * r44); + e[4] = (l21 * r11) + (l22 * r21) + (l23 * r31) + (l24 * r41); + e[5] = (l21 * r12) + (l22 * r22) + (l23 * r32) + (l24 * r42); + e[6] = (l21 * r13) + (l22 * r23) + (l23 * r33) + (l24 * r43); + e[7] = (l21 * r14) + (l22 * r24) + (l23 * r34) + (l24 * r44); + e[8] = (l31 * r11) + (l32 * r21) + (l33 * r31) + (l34 * r41); + e[9] = (l31 * r12) + (l32 * r22) + (l33 * r32) + (l34 * r42); + e[10] = (l31 * r13) + (l32 * r23) + (l33 * r33) + (l34 * r43); + e[11] = (l31 * r14) + (l32 * r24) + (l33 * r34) + (l34 * r44); + e[12] = (l41 * r11) + (l42 * r21) + (l43 * r31) + (l44 * r41); + e[13] = (l41 * r12) + (l42 * r22) + (l43 * r32) + (l44 * r42); + e[14] = (l41 * r13) + (l42 * r23) + (l43 * r33) + (l44 * r43); + e[15] = (l41 * r14) + (l42 * r24) + (l43 * r34) + (l44 * r44); + } + static multiplyForNative(left, right, out) { + Laya.LayaGL.instance.matrix4x4Multiply(left.elements, right.elements, out.elements); + } + static createFromQuaternion(rotation, out) { + var e = out.elements; + var x = rotation.x, y = rotation.y, z = rotation.z, w = rotation.w; + var x2 = x + x; + var y2 = y + y; + var z2 = z + z; + var xx = x * x2; + var yx = y * x2; + var yy = y * y2; + var zx = z * x2; + var zy = z * y2; + var zz = z * z2; + var wx = w * x2; + var wy = w * y2; + var wz = w * z2; + e[0] = 1 - yy - zz; + e[1] = yx + wz; + e[2] = zx - wy; + e[3] = 0; + e[4] = yx - wz; + e[5] = 1 - xx - zz; + e[6] = zy + wx; + e[7] = 0; + e[8] = zx + wy; + e[9] = zy - wx; + e[10] = 1 - xx - yy; + e[11] = 0; + e[12] = 0; + e[13] = 0; + e[14] = 0; + e[15] = 1; + } + static createAffineTransformation(trans, rot, scale, out) { + var oe = out.elements; + var x = rot.x, y = rot.y, z = rot.z, w = rot.w, x2 = x + x, y2 = y + y, z2 = z + z; + var xx = x * x2, xy = x * y2, xz = x * z2, yy = y * y2, yz = y * z2, zz = z * z2; + var wx = w * x2, wy = w * y2, wz = w * z2, sx = scale.x, sy = scale.y, sz = scale.z; + oe[0] = (1 - (yy + zz)) * sx; + oe[1] = (xy + wz) * sx; + oe[2] = (xz - wy) * sx; + oe[3] = 0; + oe[4] = (xy - wz) * sy; + oe[5] = (1 - (xx + zz)) * sy; + oe[6] = (yz + wx) * sy; + oe[7] = 0; + oe[8] = (xz + wy) * sz; + oe[9] = (yz - wx) * sz; + oe[10] = (1 - (xx + yy)) * sz; + oe[11] = 0; + oe[12] = trans.x; + oe[13] = trans.y; + oe[14] = trans.z; + oe[15] = 1; + } + static createLookAt(eye, target, up, out) { + var oE = out.elements; + var xaxis = Matrix4x4._tempVector0; + var yaxis = Matrix4x4._tempVector1; + var zaxis = Matrix4x4._tempVector2; + Vector3.subtract(eye, target, zaxis); + Vector3.normalize(zaxis, zaxis); + Vector3.cross(up, zaxis, xaxis); + Vector3.normalize(xaxis, xaxis); + Vector3.cross(zaxis, xaxis, yaxis); + oE[3] = oE[7] = oE[11] = 0; + oE[15] = 1; + oE[0] = xaxis.x; + oE[4] = xaxis.y; + oE[8] = xaxis.z; + oE[1] = yaxis.x; + oE[5] = yaxis.y; + oE[9] = yaxis.z; + oE[2] = zaxis.x; + oE[6] = zaxis.y; + oE[10] = zaxis.z; + oE[12] = -Vector3.dot(xaxis, eye); + oE[13] = -Vector3.dot(yaxis, eye); + oE[14] = -Vector3.dot(zaxis, eye); + } + static createPerspective(fov, aspect, znear, zfar, out) { + var yScale = 1.0 / Math.tan(fov * 0.5); + var xScale = yScale / aspect; + var halfWidth = znear / xScale; + var halfHeight = znear / yScale; + Matrix4x4.createPerspectiveOffCenter(-halfWidth, halfWidth, -halfHeight, halfHeight, znear, zfar, out); + } + static createPerspectiveOffCenter(left, right, bottom, top, znear, zfar, out) { + var oe = out.elements; + var zRange = zfar / (zfar - znear); + oe[1] = oe[2] = oe[3] = oe[4] = oe[6] = oe[7] = oe[12] = oe[13] = oe[15] = 0; + oe[0] = 2.0 * znear / (right - left); + oe[5] = 2.0 * znear / (top - bottom); + oe[8] = (left + right) / (right - left); + oe[9] = (top + bottom) / (top - bottom); + oe[10] = -zRange; + oe[11] = -1.0; + oe[14] = -znear * zRange; + } + static createOrthoOffCenter(left, right, bottom, top, znear, zfar, out) { + var oe = out.elements; + var zRange = 1.0 / (zfar - znear); + oe[1] = oe[2] = oe[3] = oe[4] = oe[6] = oe[8] = oe[7] = oe[9] = oe[11] = 0; + oe[15] = 1; + oe[0] = 2.0 / (right - left); + oe[5] = 2.0 / (top - bottom); + oe[10] = -zRange; + oe[12] = (left + right) / (left - right); + oe[13] = (top + bottom) / (bottom - top); + oe[14] = -znear * zRange; + } + getElementByRowColumn(row, column) { + if (row < 0 || row > 3) + throw new Error("row Rows and columns for matrices run from 0 to 3, inclusive."); + if (column < 0 || column > 3) + throw new Error("column Rows and columns for matrices run from 0 to 3, inclusive."); + return this.elements[(row * 4) + column]; + } + setElementByRowColumn(row, column, value) { + if (row < 0 || row > 3) + throw new Error("row Rows and columns for matrices run from 0 to 3, inclusive."); + if (column < 0 || column > 3) + throw new Error("column Rows and columns for matrices run from 0 to 3, inclusive."); + this.elements[(row * 4) + column] = value; + } + equalsOtherMatrix(other) { + var e = this.elements; + var oe = other.elements; + return (MathUtils3D.nearEqual(e[0], oe[0]) && MathUtils3D.nearEqual(e[1], oe[1]) && MathUtils3D.nearEqual(e[2], oe[2]) && MathUtils3D.nearEqual(e[3], oe[3]) && MathUtils3D.nearEqual(e[4], oe[4]) && MathUtils3D.nearEqual(e[5], oe[5]) && MathUtils3D.nearEqual(e[6], oe[6]) && MathUtils3D.nearEqual(e[7], oe[7]) && MathUtils3D.nearEqual(e[8], oe[8]) && MathUtils3D.nearEqual(e[9], oe[9]) && MathUtils3D.nearEqual(e[10], oe[10]) && MathUtils3D.nearEqual(e[11], oe[11]) && MathUtils3D.nearEqual(e[12], oe[12]) && MathUtils3D.nearEqual(e[13], oe[13]) && MathUtils3D.nearEqual(e[14], oe[14]) && MathUtils3D.nearEqual(e[15], oe[15])); + } + decomposeTransRotScale(translation, rotation, scale) { + var rotationMatrix = Matrix4x4._tempMatrix4x4; + if (this.decomposeTransRotMatScale(translation, rotationMatrix, scale)) { + Quaternion.createFromMatrix4x4(rotationMatrix, rotation); + return true; + } + else { + rotation.identity(); + return false; + } + } + decomposeTransRotMatScale(translation, rotationMatrix, scale) { + var e = this.elements; + var te = translation; + var re = rotationMatrix.elements; + var se = scale; + te.x = e[12]; + te.y = e[13]; + te.z = e[14]; + var m11 = e[0], m12 = e[1], m13 = e[2]; + var m21 = e[4], m22 = e[5], m23 = e[6]; + var m31 = e[8], m32 = e[9], m33 = e[10]; + var sX = se.x = Math.sqrt((m11 * m11) + (m12 * m12) + (m13 * m13)); + var sY = se.y = Math.sqrt((m21 * m21) + (m22 * m22) + (m23 * m23)); + var sZ = se.z = Math.sqrt((m31 * m31) + (m32 * m32) + (m33 * m33)); + if (MathUtils3D.isZero(sX) || MathUtils3D.isZero(sY) || MathUtils3D.isZero(sZ)) { + re[1] = re[2] = re[3] = re[4] = re[6] = re[7] = re[8] = re[9] = re[11] = re[12] = re[13] = re[14] = 0; + re[0] = re[5] = re[10] = re[15] = 1; + return false; + } + var at = Matrix4x4._tempVector0; + at.x = m31 / sZ; + at.y = m32 / sZ; + at.z = m33 / sZ; + var tempRight = Matrix4x4._tempVector1; + tempRight.x = m11 / sX; + tempRight.y = m12 / sX; + tempRight.z = m13 / sX; + var up = Matrix4x4._tempVector2; + Vector3.cross(at, tempRight, up); + var right = Matrix4x4._tempVector1; + Vector3.cross(up, at, right); + re[3] = re[7] = re[11] = re[12] = re[13] = re[14] = 0; + re[15] = 1; + re[0] = right.x; + re[1] = right.y; + re[2] = right.z; + re[4] = up.x; + re[5] = up.y; + re[6] = up.z; + re[8] = at.x; + re[9] = at.y; + re[10] = at.z; + ((re[0] * m11 + re[1] * m12 + re[2] * m13) < 0.0) && (se.x = -sX); + ((re[4] * m21 + re[5] * m22 + re[6] * m23) < 0.0) && (se.y = -sY); + ((re[8] * m31 + re[9] * m32 + re[10] * m33) < 0.0) && (se.z = -sZ); + return true; + } + decomposeYawPitchRoll(yawPitchRoll) { + var pitch = Math.asin(-this.elements[9]); + yawPitchRoll.y = pitch; + var test = Math.cos(pitch); + if (test > MathUtils3D.zeroTolerance) { + yawPitchRoll.z = Math.atan2(this.elements[1], this.elements[5]); + yawPitchRoll.x = Math.atan2(this.elements[8], this.elements[10]); + } + else { + yawPitchRoll.z = Math.atan2(-this.elements[4], this.elements[0]); + yawPitchRoll.x = 0.0; + } + } + normalize() { + var v = this.elements; + var c = v[0], d = v[1], e = v[2], g = Math.sqrt(c * c + d * d + e * e); + if (g) { + if (g == 1) + return; + } + else { + v[0] = 0; + v[1] = 0; + v[2] = 0; + return; + } + g = 1 / g; + v[0] = c * g; + v[1] = d * g; + v[2] = e * g; + } + transpose() { + var e, t; + e = this.elements; + t = e[1]; + e[1] = e[4]; + e[4] = t; + t = e[2]; + e[2] = e[8]; + e[8] = t; + t = e[3]; + e[3] = e[12]; + e[12] = t; + t = e[6]; + e[6] = e[9]; + e[9] = t; + t = e[7]; + e[7] = e[13]; + e[13] = t; + t = e[11]; + e[11] = e[14]; + e[14] = t; + return this; + } + invert(out) { + var ae = this.elements; + var oe = out.elements; + var a00 = ae[0], a01 = ae[1], a02 = ae[2], a03 = ae[3], a10 = ae[4], a11 = ae[5], a12 = ae[6], a13 = ae[7], a20 = ae[8], a21 = ae[9], a22 = ae[10], a23 = ae[11], a30 = ae[12], a31 = ae[13], a32 = ae[14], a33 = ae[15], b00 = a00 * a11 - a01 * a10, b01 = a00 * a12 - a02 * a10, b02 = a00 * a13 - a03 * a10, b03 = a01 * a12 - a02 * a11, b04 = a01 * a13 - a03 * a11, b05 = a02 * a13 - a03 * a12, b06 = a20 * a31 - a21 * a30, b07 = a20 * a32 - a22 * a30, b08 = a20 * a33 - a23 * a30, b09 = a21 * a32 - a22 * a31, b10 = a21 * a33 - a23 * a31, b11 = a22 * a33 - a23 * a32, det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; + if (Math.abs(det) === 0.0) { + return; + } + det = 1.0 / det; + oe[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; + oe[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det; + oe[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det; + oe[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det; + oe[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det; + oe[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det; + oe[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det; + oe[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det; + oe[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det; + oe[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det; + oe[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det; + oe[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det; + oe[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det; + oe[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det; + oe[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det; + oe[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det; + } + static billboard(objectPosition, cameraPosition, cameraUp, cameraForward, mat) { + Vector3.subtract(objectPosition, cameraPosition, Matrix4x4._tempVector0); + var lengthSq = Vector3.scalarLengthSquared(Matrix4x4._tempVector0); + if (MathUtils3D.isZero(lengthSq)) { + Vector3.scale(cameraForward, -1, Matrix4x4._tempVector1); + Matrix4x4._tempVector1.cloneTo(Matrix4x4._tempVector0); + } + else { + Vector3.scale(Matrix4x4._tempVector0, 1 / Math.sqrt(lengthSq), Matrix4x4._tempVector0); + } + Vector3.cross(cameraUp, Matrix4x4._tempVector0, Matrix4x4._tempVector2); + Vector3.normalize(Matrix4x4._tempVector2, Matrix4x4._tempVector2); + Vector3.cross(Matrix4x4._tempVector0, Matrix4x4._tempVector2, Matrix4x4._tempVector3); + var crosse = Matrix4x4._tempVector2; + var finale = Matrix4x4._tempVector3; + var diffee = Matrix4x4._tempVector0; + var obpose = objectPosition; + var mate = mat.elements; + mate[0] = crosse.x; + mate[1] = crosse.y; + mate[2] = crosse.z; + mate[3] = 0.0; + mate[4] = finale.x; + mate[5] = finale.y; + mate[6] = finale.z; + mate[7] = 0.0; + mate[8] = diffee.x; + mate[9] = diffee.y; + mate[10] = diffee.z; + mate[11] = 0.0; + mate[12] = obpose.x; + mate[13] = obpose.y; + mate[14] = obpose.z; + mate[15] = 1.0; + } + identity() { + var e = this.elements; + e[1] = e[2] = e[3] = e[4] = e[6] = e[7] = e[8] = e[9] = e[11] = e[12] = e[13] = e[14] = 0; + e[0] = e[5] = e[10] = e[15] = 1; + } + cloneTo(destObject) { + var i, s, d; + s = this.elements; + d = destObject.elements; + if (s === d) { + return; + } + for (i = 0; i < 16; ++i) { + d[i] = s[i]; + } + } + clone() { + var dest = new Matrix4x4(); + this.cloneTo(dest); + return dest; + } + static translation(v3, out) { + var oe = out.elements; + oe[0] = oe[5] = oe[10] = oe[15] = 1; + oe[12] = v3.x; + oe[13] = v3.y; + oe[14] = v3.z; + } + getTranslationVector(out) { + var me = this.elements; + out.x = me[12]; + out.y = me[13]; + out.z = me[14]; + } + setTranslationVector(translate) { + var me = this.elements; + var ve = translate; + me[12] = ve.x; + me[13] = ve.y; + me[14] = ve.z; + } + getForward(out) { + var me = this.elements; + out.x = -me[8]; + out.y = -me[9]; + out.z = -me[10]; + } + setForward(forward) { + var me = this.elements; + me[8] = -forward.x; + me[9] = -forward.y; + me[10] = -forward.z; + } + getInvertFront() { + this.decomposeTransRotScale(Matrix4x4._tempVector0, Matrix4x4._tempQuaternion, Matrix4x4._tempVector1); + var scale = Matrix4x4._tempVector1; + var isInvert = scale.x < 0; + (scale.y < 0) && (isInvert = !isInvert); + (scale.z < 0) && (isInvert = !isInvert); + return isInvert; + } + } + Matrix4x4._tempMatrix4x4 = new Matrix4x4(); + Matrix4x4.TEMPMatrix0 = new Matrix4x4(); + Matrix4x4.TEMPMatrix1 = new Matrix4x4(); + Matrix4x4._tempVector0 = new Vector3(); + Matrix4x4._tempVector1 = new Vector3(); + Matrix4x4._tempVector2 = new Vector3(); + Matrix4x4._tempVector3 = new Vector3(); + Matrix4x4._tempQuaternion = new Quaternion(); + Matrix4x4.DEFAULT = new Matrix4x4(); + Matrix4x4.ZERO = new Matrix4x4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + + class ShaderData { + constructor(ownerResource = null) { + this._ownerResource = null; + this._data = null; + this._defineDatas = new DefineDatas(); + this._runtimeCopyValues = []; + this._ownerResource = ownerResource; + this._initData(); + } + _initData() { + this._data = {}; + } + getData() { + return this._data; + } + addDefine(define) { + this._defineDatas.add(define); + } + removeDefine(define) { + this._defineDatas.remove(define); + } + hasDefine(define) { + return this._defineDatas.has(define); + } + clearDefine() { + this._defineDatas.clear(); + } + getBool(index) { + return this._data[index]; + } + setBool(index, value) { + this._data[index] = value; + } + getInt(index) { + return this._data[index]; + } + setInt(index, value) { + this._data[index] = value; + } + getNumber(index) { + return this._data[index]; + } + setNumber(index, value) { + this._data[index] = value; + } + getVector2(index) { + return this._data[index]; + } + setVector2(index, value) { + this._data[index] = value; + } + getVector3(index) { + return this._data[index]; + } + setVector3(index, value) { + this._data[index] = value; + } + getVector(index) { + return this._data[index]; + } + setVector(index, value) { + this._data[index] = value; + } + getQuaternion(index) { + return this._data[index]; + } + setQuaternion(index, value) { + this._data[index] = value; + } + getMatrix4x4(index) { + return this._data[index]; + } + setMatrix4x4(index, value) { + this._data[index] = value; + } + getBuffer(shaderIndex) { + return this._data[shaderIndex]; + } + setBuffer(index, value) { + this._data[index] = value; + } + setTexture(index, value) { + var lastValue = this._data[index]; + this._data[index] = value ? value : Laya.Texture2D.erroTextur; + if (this._ownerResource && this._ownerResource.referenceCount > 0) { + (lastValue) && (lastValue._removeReference()); + (value) && (value._addReference()); + } + } + getTexture(index) { + return this._data[index]; + } + setValueData(index, value) { + this._data[index] = value; + } + getValueData(index) { + return this._data[index]; + } + setAttribute(index, value) { + this._data[index] = value; + } + getAttribute(index) { + return this._data[index]; + } + getLength() { + return this._data.length; + } + setLength(value) { + this._data.length = value; + } + cloneTo(destObject) { + var dest = destObject; + var destData = dest._data; + for (var k in this._data) { + var value = this._data[k]; + if (value != null) { + if (typeof (value) == 'number') { + destData[k] = value; + } + else if (typeof (value) == 'number') { + destData[k] = value; + } + else if (typeof (value) == "boolean") { + destData[k] = value; + } + else if (value instanceof Vector2) { + var v2 = (destData[k]) || (destData[k] = new Vector2()); + value.cloneTo(v2); + destData[k] = v2; + } + else if (value instanceof Vector3) { + var v3 = (destData[k]) || (destData[k] = new Vector3()); + value.cloneTo(v3); + destData[k] = v3; + } + else if (value instanceof Vector4) { + var v4 = (destData[k]) || (destData[k] = new Vector4()); + value.cloneTo(v4); + destData[k] = v4; + } + else if (value instanceof Matrix4x4) { + var mat = (destData[k]) || (destData[k] = new Matrix4x4()); + value.cloneTo(mat); + destData[k] = mat; + } + else if (value instanceof Laya.BaseTexture) { + destData[k] = value; + } + } + } + this._defineDatas.cloneTo(dest._defineDatas); + } + clone() { + var dest = new ShaderData(); + this.cloneTo(dest); + return dest; + } + cloneToForNative(destObject) { + var dest = destObject; + var diffSize = this._int32Data.length - dest._int32Data.length; + if (diffSize > 0) { + dest.needRenewArrayBufferForNative(this._int32Data.length); + } + dest._int32Data.set(this._int32Data, 0); + var destData = dest._nativeArray; + var dataCount = this._nativeArray.length; + destData.length = dataCount; + for (var i = 0; i < dataCount; i++) { + var value = this._nativeArray[i]; + if (value) { + if (typeof (value) == 'number') { + destData[i] = value; + dest.setNumber(i, value); + } + else if (typeof (value) == 'number') { + destData[i] = value; + dest.setInt(i, value); + } + else if (typeof (value) == "boolean") { + destData[i] = value; + dest.setBool(i, value); + } + else if (value instanceof Vector2) { + var v2 = (destData[i]) || (destData[i] = new Vector2()); + value.cloneTo(v2); + destData[i] = v2; + dest.setVector2(i, v2); + } + else if (value instanceof Vector3) { + var v3 = (destData[i]) || (destData[i] = new Vector3()); + value.cloneTo(v3); + destData[i] = v3; + dest.setVector3(i, v3); + } + else if (value instanceof Vector4) { + var v4 = (destData[i]) || (destData[i] = new Vector4()); + value.cloneTo(v4); + destData[i] = v4; + dest.setVector(i, v4); + } + else if (value instanceof Matrix4x4) { + var mat = (destData[i]) || (destData[i] = new Matrix4x4()); + value.cloneTo(mat); + destData[i] = mat; + dest.setMatrix4x4(i, mat); + } + else if (value instanceof Laya.BaseTexture) { + destData[i] = value; + dest.setTexture(i, value); + } + } + } + this._defineDatas.cloneTo(dest._defineDatas); + } + _initDataForNative() { + var length = 8; + this._frameCount = -1; + this._runtimeCopyValues.length = 0; + this._nativeArray = []; + this._data = new ArrayBuffer(length * 4); + this._int32Data = new Int32Array(this._data); + this._float32Data = new Float32Array(this._data); + Laya.LayaGL.instance.createArrayBufferRef(this._data, Laya.LayaGL.ARRAY_BUFFER_TYPE_DATA, true); + } + needRenewArrayBufferForNative(index) { + if (index >= this._int32Data.length) { + var nByteLen = (index + 1) * 4; + var pre = this._int32Data; + var preConchRef = this._data["conchRef"]; + var prePtrID = this._data["_ptrID"]; + this._data = new ArrayBuffer(nByteLen); + this._int32Data = new Int32Array(this._data); + this._float32Data = new Float32Array(this._data); + this._data["conchRef"] = preConchRef; + this._data["_ptrID"] = prePtrID; + pre && this._int32Data.set(pre, 0); + var layagl = Laya.LayaGL.instance; + if (layagl.updateArrayBufferRef) { + layagl.updateArrayBufferRef(this._data['_ptrID'], preConchRef.isSyncToRender(), this._data); + } + else { + window.conch.updateArrayBufferRef(this._data['_ptrID'], preConchRef.isSyncToRender(), this._data); + } + } + } + getDataForNative() { + return this._nativeArray; + } + getIntForNative(index) { + return this._int32Data[index]; + } + setIntForNative(index, value) { + this.needRenewArrayBufferForNative(index); + this._int32Data[index] = value; + this._nativeArray[index] = value; + } + getBoolForNative(index) { + return this._int32Data[index] == 1; + } + setBoolForNative(index, value) { + this.needRenewArrayBufferForNative(index); + this._int32Data[index] = value ? 1 : 0; + this._nativeArray[index] = value; + } + getNumberForNative(index) { + return this._float32Data[index]; + } + setNumberForNative(index, value) { + this.needRenewArrayBufferForNative(index); + this._float32Data[index] = value; + this._nativeArray[index] = value; + } + getMatrix4x4ForNative(index) { + return this._nativeArray[index]; + } + setMatrix4x4ForNative(index, value) { + this.needRenewArrayBufferForNative(index); + this._nativeArray[index] = value; + var nPtrID = this.setReferenceForNative(value.elements); + this._int32Data[index] = nPtrID; + } + getVectorForNative(index) { + return this._nativeArray[index]; + } + setVectorForNative(index, value) { + this.needRenewArrayBufferForNative(index); + this._nativeArray[index] = value; + if (!value.elements) { + value.forNativeElement(); + } + var nPtrID = this.setReferenceForNative(value.elements); + this._int32Data[index] = nPtrID; + } + getVector2ForNative(index) { + return this._nativeArray[index]; + } + setVector2ForNative(index, value) { + this.needRenewArrayBufferForNative(index); + this._nativeArray[index] = value; + if (!value.elements) { + value.forNativeElement(); + } + var nPtrID = this.setReferenceForNative(value.elements); + this._int32Data[index] = nPtrID; + } + getVector3ForNative(index) { + return this._nativeArray[index]; + } + setVector3ForNative(index, value) { + this.needRenewArrayBufferForNative(index); + this._nativeArray[index] = value; + if (!value.elements) { + value.forNativeElement(); + } + var nPtrID = this.setReferenceForNative(value.elements); + this._int32Data[index] = nPtrID; + } + getQuaternionForNative(index) { + return this._nativeArray[index]; + } + setQuaternionForNative(index, value) { + this.needRenewArrayBufferForNative(index); + this._nativeArray[index] = value; + if (!value.elements) { + value.forNativeElement(); + } + var nPtrID = this.setReferenceForNative(value.elements); + this._int32Data[index] = nPtrID; + } + getBufferForNative(shaderIndex) { + return this._nativeArray[shaderIndex]; + } + setBufferForNative(index, value) { + this.needRenewArrayBufferForNative(index); + this._nativeArray[index] = value; + var nPtrID = this.setReferenceForNative(value); + this._int32Data[index] = nPtrID; + } + getAttributeForNative(index) { + return this._nativeArray[index]; + } + setAttributeForNative(index, value) { + this._nativeArray[index] = value; + if (!value["_ptrID"]) { + Laya.LayaGL.instance.createArrayBufferRef(value, Laya.LayaGL.ARRAY_BUFFER_TYPE_DATA, true); + } + Laya.LayaGL.instance.syncBufferToRenderThread(value); + this._int32Data[index] = value["_ptrID"]; + } + getTextureForNative(index) { + return this._nativeArray[index]; + } + setTextureForNative(index, value) { + if (!value) + return; + this.needRenewArrayBufferForNative(index); + var lastValue = this._nativeArray[index]; + this._nativeArray[index] = value; + var glTexture = value._getSource() || value.defaulteTexture._getSource(); + this._int32Data[index] = glTexture.id; + if (this._ownerResource && this._ownerResource.referenceCount > 0) { + (lastValue) && (lastValue._removeReference()); + (value) && (value._addReference()); + } + } + setReferenceForNative(value) { + this.clearRuntimeCopyArray(); + var nRefID = 0; + var nPtrID = 0; + if (ShaderData._SET_RUNTIME_VALUE_MODE_REFERENCE_) { + Laya.LayaGL.instance.createArrayBufferRefs(value, Laya.LayaGL.ARRAY_BUFFER_TYPE_DATA, true, Laya.LayaGL.ARRAY_BUFFER_REF_REFERENCE); + nRefID = 0; + nPtrID = value.getPtrID(nRefID); + } + else { + Laya.LayaGL.instance.createArrayBufferRefs(value, Laya.LayaGL.ARRAY_BUFFER_TYPE_DATA, true, Laya.LayaGL.ARRAY_BUFFER_REF_COPY); + nRefID = value.getRefNum() - 1; + nPtrID = value.getPtrID(nRefID); + this._runtimeCopyValues.push({ "obj": value, "refID": nRefID, "ptrID": nPtrID }); + } + Laya.LayaGL.instance.syncBufferToRenderThread(value, nRefID); + return nPtrID; + } + static setRuntimeValueMode(bReference) { + ShaderData._SET_RUNTIME_VALUE_MODE_REFERENCE_ = bReference; + } + clearRuntimeCopyArray() { + var currentFrame = Laya.Stat.loopCount; + if (this._frameCount != currentFrame) { + this._frameCount = currentFrame; + for (var i = 0, n = this._runtimeCopyValues.length; i < n; i++) { + var obj = this._runtimeCopyValues[i]; + obj.obj.clearRefNum(); + } + this._runtimeCopyValues.length = 0; + } + } + } + ShaderData._SET_RUNTIME_VALUE_MODE_REFERENCE_ = true; + + class VertexDeclaration { + constructor(vertexStride, vertexElements) { + this._id = ++VertexDeclaration._uniqueIDCounter; + this._vertexElementsDic = {}; + this._vertexStride = vertexStride; + this._vertexElements = vertexElements; + var count = vertexElements.length; + this._shaderValues = new ShaderData(null); + for (var j = 0; j < count; j++) { + var vertexElement = vertexElements[j]; + var name = vertexElement._elementUsage; + this._vertexElementsDic[name] = vertexElement; + var value = new Int32Array(5); + var elmentInfo = VertexElementFormat.getElementInfos(vertexElement._elementFormat); + value[0] = elmentInfo[0]; + value[1] = elmentInfo[1]; + value[2] = elmentInfo[2]; + value[3] = this._vertexStride; + value[4] = vertexElement._offset; + this._shaderValues.setAttribute(name, value); + } + } + get id() { + return this._id; + } + get vertexStride() { + return this._vertexStride; + } + get vertexElementCount() { + return this._vertexElements.length; + } + getVertexElementByIndex(index) { + return this._vertexElements[index]; + } + getVertexElementByUsage(usage) { + return this._vertexElementsDic[usage]; + } + } + VertexDeclaration._uniqueIDCounter = 1; + + class VertexElement { + constructor(offset, elementFormat, elementUsage) { + this._offset = offset; + this._elementFormat = elementFormat; + this._elementUsage = elementUsage; + } + get offset() { + return this._offset; + } + get elementFormat() { + return this._elementFormat; + } + get elementUsage() { + return this._elementUsage; + } + } + + class BufferState extends Laya.BufferStateBase { + constructor() { + super(); + } + applyVertexBuffer(vertexBuffer) { + if (Laya.BufferStateBase._curBindedBufferState === this) { + var gl = Laya.LayaGL.instance; + var verDec = vertexBuffer.vertexDeclaration; + var valueData = verDec._shaderValues.getData(); + this.vertexDeclaration = verDec; + vertexBuffer.bind(); + for (var k in valueData) { + var loc = parseInt(k); + var attribute = valueData[k]; + gl.enableVertexAttribArray(loc); + gl.vertexAttribPointer(loc, attribute[0], attribute[1], !!attribute[2], attribute[3], attribute[4]); + } + } + else { + throw "BufferState: must call bind() function first."; + } + } + applyVertexBuffers(vertexBuffers) { + if (Laya.BufferStateBase._curBindedBufferState === this) { + var gl = Laya.LayaGL.instance; + for (var i = 0, n = vertexBuffers.length; i < n; i++) { + var verBuf = vertexBuffers[i]; + var verDec = verBuf.vertexDeclaration; + var valueData = verDec._shaderValues.getData(); + verBuf.bind(); + for (var k in valueData) { + var loc = parseInt(k); + var attribute = valueData[k]; + gl.enableVertexAttribArray(loc); + gl.vertexAttribPointer(loc, attribute[0], attribute[1], !!attribute[2], attribute[3], attribute[4]); + } + } + } + else { + throw "BufferState: must call bind() function first."; + } + } + applyInstanceVertexBuffer(vertexBuffer) { + if (Laya.LayaGL.layaGPUInstance.supportInstance()) { + if (Laya.BufferStateBase._curBindedBufferState === this) { + var gl = Laya.LayaGL.instance; + var verDec = vertexBuffer.vertexDeclaration; + var valueData = verDec._shaderValues.getData(); + vertexBuffer.bind(); + for (var k in valueData) { + var loc = parseInt(k); + var attribute = valueData[k]; + gl.enableVertexAttribArray(loc); + gl.vertexAttribPointer(loc, attribute[0], attribute[1], !!attribute[2], attribute[3], attribute[4]); + Laya.LayaGL.layaGPUInstance.vertexAttribDivisor(loc, 1); + } + } + else { + throw "BufferState: must call bind() function first."; + } + } + } + applyIndexBuffer(indexBuffer) { + if (Laya.BufferStateBase._curBindedBufferState === this) { + if (this._bindedIndexBuffer !== indexBuffer) { + indexBuffer._bindForVAO(); + this._bindedIndexBuffer = indexBuffer; + } + } + else { + throw "BufferState: must call bind() function first."; + } + } + } + + class ScreenQuad extends Laya.Resource { + constructor() { + super(); + this._bufferState = new BufferState(); + this._bufferStateInvertUV = new BufferState(); + var gl = Laya.LayaGL.instance; + this._vertexBuffer = new VertexBuffer3D(16 * 4, gl.STATIC_DRAW, false); + this._vertexBuffer.vertexDeclaration = ScreenQuad._vertexDeclaration; + this._vertexBuffer.setData(ScreenQuad._vertices.buffer); + this._bufferState.bind(); + this._bufferState.applyVertexBuffer(this._vertexBuffer); + this._bufferState.unBind(); + this._vertexBufferInvertUV = new VertexBuffer3D(16 * 4, gl.STATIC_DRAW, false); + this._vertexBufferInvertUV.vertexDeclaration = ScreenQuad._vertexDeclaration; + this._vertexBufferInvertUV.setData(ScreenQuad._verticesInvertUV.buffer); + this._bufferStateInvertUV.bind(); + this._bufferStateInvertUV.applyVertexBuffer(this._vertexBufferInvertUV); + this._bufferStateInvertUV.unBind(); + this._setGPUMemory(this._vertexBuffer._byteLength + this._vertexBufferInvertUV._byteLength); + } + static __init__() { + ScreenQuad._vertexDeclaration = new VertexDeclaration(16, [new VertexElement(0, VertexElementFormat.Vector4, ScreenQuad.SCREENQUAD_POSITION_UV)]); + ScreenQuad.instance = new ScreenQuad(); + ScreenQuad.instance.lock = true; + } + render() { + var gl = Laya.LayaGL.instance; + this._bufferState.bind(); + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + Laya.Stat.renderBatches++; + } + renderInvertUV() { + var gl = Laya.LayaGL.instance; + this._bufferStateInvertUV.bind(); + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + Laya.Stat.renderBatches++; + } + destroy() { + super.destroy(); + this._bufferState.destroy(); + this._vertexBuffer.destroy(); + this._bufferStateInvertUV.destroy(); + this._vertexBufferInvertUV.destroy(); + this._setGPUMemory(0); + } + } + ScreenQuad.SCREENQUAD_POSITION_UV = 0; + ScreenQuad._vertices = new Float32Array([1, 1, 1, 1, 1, -1, 1, 0, -1, 1, 0, 1, -1, -1, 0, 0]); + ScreenQuad._verticesInvertUV = new Float32Array([1, 1, 1, 0, 1, -1, 1, 1, -1, 1, 0, 0, -1, -1, 0, 1]); + + class ScreenTriangle extends Laya.Resource { + constructor() { + super(); + this._bufferState = new BufferState(); + this._bufferStateInvertUV = new BufferState(); + var gl = Laya.LayaGL.instance; + this._vertexBuffer = new VertexBuffer3D(12 * 4, gl.STATIC_DRAW, false); + this._vertexBuffer.vertexDeclaration = ScreenTriangle._vertexDeclaration; + this._vertexBuffer.setData(ScreenTriangle._vertices.buffer); + this._bufferState.bind(); + this._bufferState.applyVertexBuffer(this._vertexBuffer); + this._bufferState.unBind(); + this._vertexBufferInvertUV = new VertexBuffer3D(12 * 4, gl.STATIC_DRAW, false); + this._vertexBufferInvertUV.vertexDeclaration = ScreenTriangle._vertexDeclaration; + this._vertexBufferInvertUV.setData(ScreenTriangle._verticesInvertUV.buffer); + this._bufferStateInvertUV.bind(); + this._bufferStateInvertUV.applyVertexBuffer(this._vertexBufferInvertUV); + this._bufferStateInvertUV.unBind(); + this._setGPUMemory(this._vertexBuffer._byteLength + this._vertexBufferInvertUV._byteLength); + } + static __init__() { + ScreenTriangle._vertexDeclaration = new VertexDeclaration(16, [new VertexElement(0, VertexElementFormat.Vector4, ScreenTriangle.SCREENTRIANGLE_POSITION_UV)]); + ScreenTriangle.instance = new ScreenTriangle(); + ScreenTriangle.instance.lock = true; + } + render() { + var gl = Laya.LayaGL.instance; + this._bufferState.bind(); + gl.drawArrays(gl.TRIANGLES, 0, 3); + Laya.Stat.renderBatches++; + } + renderInvertUV() { + var gl = Laya.LayaGL.instance; + this._bufferStateInvertUV.bind(); + gl.drawArrays(gl.TRIANGLES, 0, 3); + Laya.Stat.renderBatches++; + } + destroy() { + super.destroy(); + this._bufferState.destroy(); + this._vertexBuffer.destroy(); + this._bufferStateInvertUV.destroy(); + this._vertexBufferInvertUV.destroy(); + this._setGPUMemory(0); + } + } + ScreenTriangle.SCREENTRIANGLE_POSITION_UV = 0; + ScreenTriangle._vertices = new Float32Array([-1, -1, 0, 0, -1, 3, 0, 2, 3, -1, 2, 0]); + ScreenTriangle._verticesInvertUV = new Float32Array([-1, -1, 0, 1, -1, 3, 0, -1, 3, -1, 2, 1]); + + class ShaderDefine { + constructor(index, value) { + this._index = index; + this._value = value; + } + } + + class ShaderVariant { + constructor(shader, subShaderIndex, passIndex, defines) { + this._subShaderIndex = 0; + this._passIndex = 0; + this.setValue(shader, subShaderIndex, passIndex, defines); + } + get shader() { + return this._shader; + } + get subShaderIndex() { + return this._subShaderIndex; + } + get passIndex() { + return this._passIndex; + } + get defineNames() { + return this._defineNames; + } + setValue(shader, subShaderIndex, passIndex, defineNames) { + if (shader) { + var subShader = shader.getSubShaderAt(subShaderIndex); + if (subShader) { + var pass = subShader._passes[passIndex]; + if (pass) { + var validDefine = pass._validDefine; + for (var i = 0, n = defineNames.length; i < n; i++) { + var defname = defineNames[i]; + if (!validDefine.has(ILaya3D.Shader3D.getDefineByName(defname))) + throw `ShaderVariantInfo:Invalid defineName ${defname} in ${shader._name} subShaderIndex of ${subShaderIndex} passIndex of ${passIndex}.`; + } + } + else { + throw `ShaderVariantInfo:Shader don't have passIndex of ${passIndex}.`; + } + } + else { + throw `ShaderVariantInfo:Shader don't have subShaderIndex of ${subShaderIndex}.`; + } + } + else { + throw `ShaderVariantInfo:Shader can't be null.`; + } + this._shader = shader; + this._subShaderIndex = subShaderIndex; + this._passIndex = passIndex; + this._defineNames = defineNames; + } + equal(other) { + if (this._shader !== other._shader || this._subShaderIndex !== other._subShaderIndex || this._passIndex !== other._passIndex) + return false; + var defines = this._defineNames; + var otherDefines = other._defineNames; + if (defines.length !== otherDefines.length) + return false; + for (var i = 0, n = this._defineNames.length; i < n; i++) { + if (defines[i] !== otherDefines[i]) + return false; + } + return true; + } + clone() { + var dest = new ShaderVariant(this._shader, this._subShaderIndex, this._passIndex, this._defineNames.slice()); + return dest; + } + } + class ShaderVariantCollection { + constructor() { + this._allCompiled = false; + this._variants = []; + } + get allCompiled() { + return this._allCompiled; + } + get variantCount() { + return this._variants.length; + } + add(variant) { + for (var i = 0, n = this._variants.length; i < n; i++) { + if (this._variants[i].equal(variant)) + return false; + } + this._variants.push(variant.clone()); + this._allCompiled = false; + return true; + } + remove(variant) { + for (var i = 0, n = this._variants.length; i < n; i++) { + if (this._variants[i].equal(variant)) { + this._variants.splice(i, 1); + return true; + } + } + return false; + } + contatins(variant) { + for (var i = 0, n = this._variants.length; i < n; i++) { + if (this._variants[i].equal(variant)) + return true; + } + return false; + } + getByIndex(index) { + return this._variants[index]; + } + clear() { + this._variants.length = 0; + } + compile() { + if (!this._allCompiled) { + var variants = this._variants; + for (var i = 0, n = variants.length; i < n; i++) { + var variant = variants[i]; + ILaya3D.Shader3D.compileShaderByDefineNames(variant._shader._name, variant._subShaderIndex, variant._passIndex, variant._defineNames); + } + this._allCompiled = true; + } + } + } + + class Shader3D { + constructor(name, attributeMap, uniformMap, enableInstancing, supportReflectionProbe) { + this._attributeMap = null; + this._uniformMap = null; + this._enableInstancing = false; + this._supportReflectionProbe = false; + this._subShaders = []; + this._name = name; + this._attributeMap = attributeMap; + this._uniformMap = uniformMap; + this._enableInstancing = enableInstancing; + this._supportReflectionProbe = supportReflectionProbe; + } + static _getNamesByDefineData(defineData, out) { + var maskMap = Shader3D._maskMap; + var mask = defineData._mask; + out.length = 0; + for (var i = 0, n = defineData._length; i < n; i++) { + var subMaskMap = maskMap[i]; + var subMask = mask[i]; + for (var j = 0; j < 32; j++) { + var d = 1 << j; + if (subMask > 0 && d > subMask) + break; + if (subMask & d) + out.push(subMaskMap[d]); + } + } + } + static getDefineByName(name) { + var define = Shader3D._defineMap[name]; + if (!define) { + var maskMap = Shader3D._maskMap; + var counter = Shader3D._defineCounter; + var index = Math.floor(counter / 32); + var value = 1 << counter % 32; + define = new ShaderDefine(index, value); + Shader3D._defineMap[name] = define; + if (index == maskMap.length) { + maskMap.length++; + maskMap[index] = {}; + } + maskMap[index][value] = name; + Shader3D._defineCounter++; + } + return define; + } + static propertyNameToID(name) { + if (Shader3D._propertyNameMap[name] != null) { + return Shader3D._propertyNameMap[name]; + } + else { + var id = Shader3D._propertyNameCounter++; + Shader3D._propertyNameMap[name] = id; + Shader3D._propertyNameMap[id] = name; + return id; + } + } + static addInclude(fileName, txt) { + txt = txt.replace(Laya.ShaderCompile._clearCR, ""); + Laya.ShaderCompile.addInclude(fileName, txt); + } + static compileShaderByDefineNames(shaderName, subShaderIndex, passIndex, defineNames) { + var shader = Shader3D.find(shaderName); + if (shader) { + var subShader = shader.getSubShaderAt(subShaderIndex); + if (subShader) { + var pass = subShader._passes[passIndex]; + if (pass) { + var compileDefineDatas = Shader3D._compileDefineDatas; + compileDefineDatas.clear(); + for (var i = 0, n = defineNames.length; i < n; i++) + compileDefineDatas.add(Shader3D.getDefineByName(defineNames[i])); + pass.withCompile(compileDefineDatas); + } + else { + console.warn("Shader3D: unknown passIndex."); + } + } + else { + console.warn("Shader3D: unknown subShaderIndex."); + } + } + else { + console.warn("Shader3D: unknown shader name."); + } + } + static add(name, attributeMap = null, uniformMap = null, enableInstancing = false, supportReflectionProbe = false) { + return Shader3D._preCompileShader[name] = new Shader3D(name, attributeMap, uniformMap, enableInstancing, supportReflectionProbe); + } + static find(name) { + return Shader3D._preCompileShader[name]; + } + get name() { + return this._name; + } + addSubShader(subShader) { + this._subShaders.push(subShader); + subShader._owner = this; + } + getSubShaderAt(index) { + return this._subShaders[index]; + } + static compileShader(shaderName, subShaderIndex, passIndex, ...defineMask) { + var shader = Shader3D.find(shaderName); + if (shader) { + var subShader = shader.getSubShaderAt(subShaderIndex); + if (subShader) { + var pass = subShader._passes[passIndex]; + if (pass) { + var compileDefineDatas = Shader3D._compileDefineDatas; + var mask = compileDefineDatas._mask; + mask.length = 0; + for (var i = 0, n = defineMask.length; i < n; i++) + mask.push(defineMask[i]); + compileDefineDatas._length = defineMask.length; + pass.withCompile(compileDefineDatas); + } + else { + console.warn("Shader3D: unknown passIndex."); + } + } + else { + console.warn("Shader3D: unknown subShaderIndex."); + } + } + else { + console.warn("Shader3D: unknown shader name."); + } + } + } + Shader3D._compileDefineDatas = new DefineDatas(); + Shader3D.RENDER_STATE_CULL = 0; + Shader3D.RENDER_STATE_BLEND = 1; + Shader3D.RENDER_STATE_BLEND_SRC = 2; + Shader3D.RENDER_STATE_BLEND_DST = 3; + Shader3D.RENDER_STATE_BLEND_SRC_RGB = 4; + Shader3D.RENDER_STATE_BLEND_DST_RGB = 5; + Shader3D.RENDER_STATE_BLEND_SRC_ALPHA = 6; + Shader3D.RENDER_STATE_BLEND_DST_ALPHA = 7; + Shader3D.RENDER_STATE_BLEND_CONST_COLOR = 8; + Shader3D.RENDER_STATE_BLEND_EQUATION = 9; + Shader3D.RENDER_STATE_BLEND_EQUATION_RGB = 10; + Shader3D.RENDER_STATE_BLEND_EQUATION_ALPHA = 11; + Shader3D.RENDER_STATE_DEPTH_TEST = 12; + Shader3D.RENDER_STATE_DEPTH_WRITE = 13; + Shader3D.PERIOD_CUSTOM = 0; + Shader3D.PERIOD_MATERIAL = 1; + Shader3D.PERIOD_SPRITE = 2; + Shader3D.PERIOD_CAMERA = 3; + Shader3D.PERIOD_SCENE = 4; + Shader3D._propertyNameMap = {}; + Shader3D._propertyNameCounter = 0; + Shader3D._defineCounter = 0; + Shader3D._defineMap = {}; + Shader3D._preCompileShader = {}; + Shader3D._maskMap = []; + Shader3D.debugMode = false; + Shader3D.debugShaderVariantCollection = new ShaderVariantCollection(); + + class Command { + constructor() { + this._commandBuffer = null; + } + static __init__() { + Command._screenShaderData = new ShaderData(); + Command._screenShader = Shader3D.find("BlitScreen"); + } + run() { + } + recover() { + this._commandBuffer = null; + } + setContext(context) { + this._context = context; + } + } + Command.SCREENTEXTURE_NAME = "u_MainTex"; + Command.SCREENTEXTUREOFFSETSCALE_NAME = "u_OffsetScale"; + Command.MAINTEXTURE_TEXELSIZE_NAME = "u_MainTex_TexelSize"; + Command.SCREENTEXTURE_ID = Shader3D.propertyNameToID(Command.SCREENTEXTURE_NAME); + Command.SCREENTEXTUREOFFSETSCALE_ID = Shader3D.propertyNameToID(Command.SCREENTEXTUREOFFSETSCALE_NAME); + Command.MAINTEXTURE_TEXELSIZE_ID = Shader3D.propertyNameToID(Command.MAINTEXTURE_TEXELSIZE_NAME); + + class BlitScreenQuadCMD extends Command { + constructor() { + super(...arguments); + this._source = null; + this._dest = null; + this._offsetScale = null; + this._shader = null; + this._shaderData = null; + this._subShader = 0; + this._sourceTexelSize = new Vector4(); + this._screenType = 0; + this._drawDefineCavans = false; + } + static create(source, dest, offsetScale = null, shader = null, shaderData = null, subShader = 0, screenType = BlitScreenQuadCMD._SCREENTYPE_QUAD, commandbuffer = null, definedCanvas = false) { + var cmd; + cmd = BlitScreenQuadCMD._pool.length > 0 ? BlitScreenQuadCMD._pool.pop() : new BlitScreenQuadCMD(); + cmd._source = source; + cmd._dest = dest; + cmd._offsetScale = offsetScale; + cmd._shader = shader; + cmd._shaderData = shaderData; + cmd._subShader = subShader; + cmd._screenType = screenType; + cmd._commandBuffer = commandbuffer; + cmd._drawDefineCavans = definedCanvas; + return cmd; + } + run() { + var source; + if (!this._source) { + if (!this._commandBuffer._camera._internalRenderTexture) + throw "camera internalRenderTexture is null,please set camera enableBuiltInRenderTexture"; + source = this._commandBuffer._camera._internalRenderTexture; + } + else + source = this._source; + var shader = this._shader || Command._screenShader; + var shaderData = this._shaderData || Command._screenShaderData; + var dest = this._dest ? this._dest : (this._drawDefineCavans ? this._dest : this._commandBuffer._camera._internalRenderTexture); + if (dest) { + Laya.LayaGL.instance.viewport(0, 0, dest.width, dest.height); + } + else { + let camera = this._commandBuffer._camera; + let viewport = camera.viewport; + let vpH = viewport.height; + let vpY = RenderContext3D.clientHeight - viewport.y - vpH; + Laya.LayaGL.instance.viewport(viewport.x, vpY, viewport.width, vpH); + } + shaderData.setTexture(Command.SCREENTEXTURE_ID, source); + shaderData.setVector(Command.SCREENTEXTUREOFFSETSCALE_ID, this._offsetScale || BlitScreenQuadCMD._defaultOffsetScale); + this._sourceTexelSize.setValue(1.0 / source.width, 1.0 / source.height, source.width, source.height); + shaderData.setVector(Command.MAINTEXTURE_TEXELSIZE_ID, this._sourceTexelSize); + (RenderTexture.currentActive) && (RenderTexture.currentActive._end()); + (dest) && (dest._start()); + var subShader = shader.getSubShaderAt(this._subShader); + var passes = subShader._passes; + for (var i = 0, n = passes.length; i < n; i++) { + var comDef = BlitScreenQuadCMD._compileDefine; + shaderData._defineDatas.cloneTo(comDef); + var shaderPass = passes[i].withCompile(comDef); + shaderPass.bind(); + shaderPass.uploadUniforms(shaderPass._materialUniformParamsMap, shaderData, true); + shaderPass.uploadRenderStateBlendDepth(shaderData); + shaderPass.uploadRenderStateFrontFace(shaderData, false, null); + switch (this._screenType) { + case BlitScreenQuadCMD._SCREENTYPE_QUAD: + RenderContext3D._instance.invertY ? ScreenQuad.instance.renderInvertUV() : ScreenQuad.instance.render(); + break; + case BlitScreenQuadCMD._SCREENTYPE_TRIANGLE: + RenderContext3D._instance.invertY ? ScreenTriangle.instance.renderInvertUV() : ScreenTriangle.instance.render(); + break; + default: + throw "BlitScreenQuadCMD:unknown screen Type."; + } + } + (dest) && (dest._end()); + } + recover() { + BlitScreenQuadCMD._pool.push(this); + this._source = null; + this._dest = null; + this._offsetScale = null; + this._shader = null; + this._shaderData = null; + this._drawDefineCavans = false; + super.recover(); + } + } + BlitScreenQuadCMD._SCREENTYPE_QUAD = 0; + BlitScreenQuadCMD._SCREENTYPE_TRIANGLE = 1; + BlitScreenQuadCMD._compileDefine = new DefineDatas(); + BlitScreenQuadCMD._pool = []; + BlitScreenQuadCMD._defaultOffsetScale = new Vector4(0, 0, 1, 1); + + class SetRenderTargetCMD extends Command { + constructor() { + super(...arguments); + this._renderTexture = null; + } + static create(renderTexture) { + var cmd; + cmd = SetRenderTargetCMD._pool.length > 0 ? SetRenderTargetCMD._pool.pop() : new SetRenderTargetCMD(); + cmd._renderTexture = renderTexture; + return cmd; + } + run() { + (RenderTexture.currentActive) && (RenderTexture.currentActive._end()); + Laya.LayaGL.instance.viewport(0, 0, this._renderTexture.width, this._renderTexture.height); + this._renderTexture._start(); + } + recover() { + SetRenderTargetCMD._pool.push(this); + this._renderTexture = null; + } + } + SetRenderTargetCMD._pool = []; + + (function (ShaderDataType) { + ShaderDataType[ShaderDataType["Int"] = 0] = "Int"; + ShaderDataType[ShaderDataType["Bool"] = 1] = "Bool"; + ShaderDataType[ShaderDataType["Number"] = 2] = "Number"; + ShaderDataType[ShaderDataType["Vector2"] = 3] = "Vector2"; + ShaderDataType[ShaderDataType["Vector3"] = 4] = "Vector3"; + ShaderDataType[ShaderDataType["Vector4"] = 5] = "Vector4"; + ShaderDataType[ShaderDataType["Quaternion"] = 6] = "Quaternion"; + ShaderDataType[ShaderDataType["Matrix4x4"] = 7] = "Matrix4x4"; + ShaderDataType[ShaderDataType["Buffer"] = 8] = "Buffer"; + ShaderDataType[ShaderDataType["Texture"] = 9] = "Texture"; + })(exports.ShaderDataType || (exports.ShaderDataType = {})); + class SetShaderDataCMD extends Command { + constructor() { + super(...arguments); + this._shaderData = null; + this._nameID = 0; + this._value = null; + this._dataType = -1; + } + static create(shaderData, nameID, value, shaderDataType, commandBuffer) { + var cmd; + cmd = SetShaderDataCMD._pool.length > 0 ? SetShaderDataCMD._pool.pop() : new SetShaderDataCMD(); + cmd._shaderData = shaderData; + cmd._nameID = nameID; + cmd._value = value; + cmd._dataType = shaderDataType; + cmd._commandBuffer = commandBuffer; + return cmd; + } + run() { + switch (this._dataType) { + case exports.ShaderDataType.Int: + this._shaderData.setInt(this._nameID, this._value); + break; + case exports.ShaderDataType.Number: + this._shaderData.setNumber(this._nameID, this._value); + break; + case exports.ShaderDataType.Bool: + this._shaderData.setBool(this._nameID, this._value); + break; + case exports.ShaderDataType.Matrix4x4: + this._shaderData.setMatrix4x4(this._nameID, this._value); + break; + case exports.ShaderDataType.Quaternion: + this._shaderData.setQuaternion(this._nameID, this._value); + break; + case exports.ShaderDataType.Texture: + this._shaderData.setTexture(this._nameID, this._value); + break; + case exports.ShaderDataType.Vector4: + this._shaderData.setVector(this._nameID, this._value); + break; + case exports.ShaderDataType.Vector2: + this._shaderData.setVector2(this._nameID, this._value); + break; + case exports.ShaderDataType.Vector3: + this._shaderData.setVector3(this._nameID, this._value); + break; + case exports.ShaderDataType.Buffer: + this._shaderData.setBuffer(this._nameID, this._value); + break; + default: + throw "no type shaderValue on this CommendBuffer"; + } + } + recover() { + SetShaderDataCMD._pool.push(this); + this._shaderData = null; + this._nameID = 0; + this._value = null; + this._dataType = -1; + } + } + SetShaderDataCMD._pool = []; + + class Transform3D extends Laya.EventDispatcher { + constructor(owner) { + super(); + this._localPosition = new Vector3(0, 0, 0); + this._localRotation = new Quaternion(0, 0, 0, 1); + this._localScale = new Vector3(1, 1, 1); + this._localRotationEuler = new Vector3(0, 0, 0); + this._localMatrix = new Matrix4x4(); + this._position = new Vector3(0, 0, 0); + this._rotation = new Quaternion(0, 0, 0, 1); + this._scale = new Vector3(1, 1, 1); + this._rotationEuler = new Vector3(0, 0, 0); + this._worldMatrix = new Matrix4x4(); + this._children = null; + this._parent = null; + this._dummy = null; + this._transformFlag = 0; + this._owner = owner; + this._children = []; + this._setTransformFlag(Transform3D.TRANSFORM_LOCALQUATERNION | Transform3D.TRANSFORM_LOCALEULER | Transform3D.TRANSFORM_LOCALMATRIX, false); + this._setTransformFlag(Transform3D.TRANSFORM_WORLDPOSITION | Transform3D.TRANSFORM_WORLDQUATERNION | Transform3D.TRANSFORM_WORLDEULER | Transform3D.TRANSFORM_WORLDSCALE | Transform3D.TRANSFORM_WORLDMATRIX, true); + } + get _isFrontFaceInvert() { + var scale = this.getWorldLossyScale(); + var isInvert = scale.x < 0; + (scale.y < 0) && (isInvert = !isInvert); + (scale.z < 0) && (isInvert = !isInvert); + return isInvert; + } + get owner() { + return this._owner; + } + get worldNeedUpdate() { + return this._getTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX); + } + get localPositionX() { + return this._localPosition.x; + } + set localPositionX(x) { + this._localPosition.x = x; + this.localPosition = this._localPosition; + } + get localPositionY() { + return this._localPosition.y; + } + set localPositionY(y) { + this._localPosition.y = y; + this.localPosition = this._localPosition; + } + get localPositionZ() { + return this._localPosition.z; + } + set localPositionZ(z) { + this._localPosition.z = z; + this.localPosition = this._localPosition; + } + get localPosition() { + return this._localPosition; + } + set localPosition(value) { + if (this._localPosition !== value) + value.cloneTo(this._localPosition); + this._setTransformFlag(Transform3D.TRANSFORM_LOCALMATRIX, true); + this._onWorldPositionTransform(); + } + get localRotationX() { + return this.localRotation.x; + } + set localRotationX(x) { + this._localRotation.x = x; + this.localRotation = this._localRotation; + } + get localRotationY() { + return this.localRotation.y; + } + set localRotationY(y) { + this._localRotation.y = y; + this.localRotation = this._localRotation; + } + get localRotationZ() { + return this.localRotation.z; + } + set localRotationZ(z) { + this._localRotation.z = z; + this.localRotation = this._localRotation; + } + get localRotationW() { + return this.localRotation.w; + } + set localRotationW(w) { + this._localRotation.w = w; + this.localRotation = this._localRotation; + } + get localRotation() { + if (this._getTransformFlag(Transform3D.TRANSFORM_LOCALQUATERNION)) { + var eulerE = this._localRotationEuler; + Quaternion.createFromYawPitchRoll(eulerE.y / Transform3D._angleToRandin, eulerE.x / Transform3D._angleToRandin, eulerE.z / Transform3D._angleToRandin, this._localRotation); + this._setTransformFlag(Transform3D.TRANSFORM_LOCALQUATERNION, false); + } + return this._localRotation; + } + set localRotation(value) { + if (this._localRotation !== value) + value.cloneTo(this._localRotation); + this._localRotation.normalize(this._localRotation); + this._setTransformFlag(Transform3D.TRANSFORM_LOCALEULER | Transform3D.TRANSFORM_LOCALMATRIX, true); + this._setTransformFlag(Transform3D.TRANSFORM_LOCALQUATERNION, false); + this._onWorldRotationTransform(); + } + get localScaleX() { + return this._localScale.x; + } + set localScaleX(value) { + this._localScale.x = value; + this.localScale = this._localScale; + } + get localScaleY() { + return this._localScale.y; + } + set localScaleY(value) { + this._localScale.y = value; + this.localScale = this._localScale; + } + get localScaleZ() { + return this._localScale.z; + } + set localScaleZ(value) { + this._localScale.z = value; + this.localScale = this._localScale; + } + get localScale() { + return this._localScale; + } + set localScale(value) { + if (this._localScale !== value) + value.cloneTo(this._localScale); + this._setTransformFlag(Transform3D.TRANSFORM_LOCALMATRIX, true); + this._onWorldScaleTransform(); + } + get localRotationEulerX() { + return this.localRotationEuler.x; + } + set localRotationEulerX(value) { + this._localRotationEuler.x = value; + this.localRotationEuler = this._localRotationEuler; + } + get localRotationEulerY() { + return this.localRotationEuler.y; + } + set localRotationEulerY(value) { + this._localRotationEuler.y = value; + this.localRotationEuler = this._localRotationEuler; + } + get localRotationEulerZ() { + return this.localRotationEuler.z; + } + set localRotationEulerZ(value) { + this._localRotationEuler.z = value; + this.localRotationEuler = this._localRotationEuler; + } + get localRotationEuler() { + if (this._getTransformFlag(Transform3D.TRANSFORM_LOCALEULER)) { + this._localRotation.getYawPitchRoll(Transform3D._tempVector30); + var euler = Transform3D._tempVector30; + var localRotationEuler = this._localRotationEuler; + localRotationEuler.x = euler.y * Transform3D._angleToRandin; + localRotationEuler.y = euler.x * Transform3D._angleToRandin; + localRotationEuler.z = euler.z * Transform3D._angleToRandin; + this._setTransformFlag(Transform3D.TRANSFORM_LOCALEULER, false); + } + return this._localRotationEuler; + } + set localRotationEuler(value) { + if (this._localRotationEuler !== value) + value.cloneTo(this._localRotationEuler); + this._setTransformFlag(Transform3D.TRANSFORM_LOCALEULER, false); + this._setTransformFlag(Transform3D.TRANSFORM_LOCALQUATERNION | Transform3D.TRANSFORM_LOCALMATRIX, true); + this._onWorldRotationTransform(); + } + get localMatrix() { + if (this._getTransformFlag(Transform3D.TRANSFORM_LOCALMATRIX)) { + Matrix4x4.createAffineTransformation(this._localPosition, this.localRotation, this._localScale, this._localMatrix); + this._setTransformFlag(Transform3D.TRANSFORM_LOCALMATRIX, false); + } + return this._localMatrix; + } + set localMatrix(value) { + if (this._localMatrix !== value) + value.cloneTo(this._localMatrix); + this._localMatrix.decomposeTransRotScale(this._localPosition, this._localRotation, this._localScale); + this._setTransformFlag(Transform3D.TRANSFORM_LOCALEULER, true); + this._setTransformFlag(Transform3D.TRANSFORM_LOCALMATRIX, false); + this._onWorldTransform(); + } + get position() { + if (this._getTransformFlag(Transform3D.TRANSFORM_WORLDPOSITION)) { + if (this._parent != null) { + var worldMatE = this.worldMatrix.elements; + this._position.x = worldMatE[12]; + this._position.y = worldMatE[13]; + this._position.z = worldMatE[14]; + } + else { + this._localPosition.cloneTo(this._position); + } + this._setTransformFlag(Transform3D.TRANSFORM_WORLDPOSITION, false); + } + return this._position; + } + set position(value) { + if (this._parent != null) { + var parentInvMat = Transform3D._tempMatrix0; + this._parent.worldMatrix.invert(parentInvMat); + Vector3.transformCoordinate(value, parentInvMat, this._localPosition); + } + else { + value.cloneTo(this._localPosition); + } + this.localPosition = this._localPosition; + if (this._position !== value) + value.cloneTo(this._position); + this._setTransformFlag(Transform3D.TRANSFORM_WORLDPOSITION, false); + } + get rotation() { + if (this._getTransformFlag(Transform3D.TRANSFORM_WORLDQUATERNION)) { + if (this._parent != null) + Quaternion.multiply(this._parent.rotation, this.localRotation, this._rotation); + else + this.localRotation.cloneTo(this._rotation); + this._setTransformFlag(Transform3D.TRANSFORM_WORLDQUATERNION, false); + } + return this._rotation; + } + set rotation(value) { + if (this._parent != null) { + this._parent.rotation.invert(Transform3D._tempQuaternion0); + Quaternion.multiply(Transform3D._tempQuaternion0, value, this._localRotation); + } + else { + value.cloneTo(this._localRotation); + } + this.localRotation = this._localRotation; + if (value !== this._rotation) + value.cloneTo(this._rotation); + this._setTransformFlag(Transform3D.TRANSFORM_WORLDQUATERNION, false); + } + get rotationEuler() { + if (this._getTransformFlag(Transform3D.TRANSFORM_WORLDEULER)) { + this.rotation.getYawPitchRoll(Transform3D._tempVector30); + var eulerE = Transform3D._tempVector30; + var rotationEulerE = this._rotationEuler; + rotationEulerE.x = eulerE.y * Transform3D._angleToRandin; + rotationEulerE.y = eulerE.x * Transform3D._angleToRandin; + rotationEulerE.z = eulerE.z * Transform3D._angleToRandin; + this._setTransformFlag(Transform3D.TRANSFORM_WORLDEULER, false); + } + return this._rotationEuler; + } + set rotationEuler(value) { + Quaternion.createFromYawPitchRoll(value.y / Transform3D._angleToRandin, value.x / Transform3D._angleToRandin, value.z / Transform3D._angleToRandin, this._rotation); + this.rotation = this._rotation; + if (this._rotationEuler !== value) + value.cloneTo(this._rotationEuler); + this._setTransformFlag(Transform3D.TRANSFORM_WORLDEULER, false); + } + get worldMatrix() { + if (this._getTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX)) { + if (this._parent != null) + Matrix4x4.multiply(this._parent.worldMatrix, this.localMatrix, this._worldMatrix); + else + this.localMatrix.cloneTo(this._worldMatrix); + this._setTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX, false); + } + return this._worldMatrix; + } + set worldMatrix(value) { + if (this._parent === null) { + value.cloneTo(this._localMatrix); + } + else { + this._parent.worldMatrix.invert(this._localMatrix); + Matrix4x4.multiply(this._localMatrix, value, this._localMatrix); + } + this.localMatrix = this._localMatrix; + if (this._worldMatrix !== value) + value.cloneTo(this._worldMatrix); + this._setTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX, false); + } + _getScaleMatrix() { + var invRotation = Transform3D._tempQuaternion0; + var invRotationMat = Transform3D._tempMatrix3x30; + var worldRotScaMat = Transform3D._tempMatrix3x31; + var scaMat = Transform3D._tempMatrix3x32; + Matrix3x3.createFromMatrix4x4(this.worldMatrix, worldRotScaMat); + this.rotation.invert(invRotation); + Matrix3x3.createRotationQuaternion(invRotation, invRotationMat); + Matrix3x3.multiply(invRotationMat, worldRotScaMat, scaMat); + return scaMat; + } + _setTransformFlag(type, value) { + if (value) + this._transformFlag |= type; + else + this._transformFlag &= ~type; + } + _getTransformFlag(type) { + return (this._transformFlag & type) != 0; + } + _setParent(value) { + if (this._parent !== value) { + if (this._parent) { + var parentChilds = this._parent._children; + var index = parentChilds.indexOf(this); + parentChilds.splice(index, 1); + } + if (value) { + value._children.push(this); + (value) && (this._onWorldTransform()); + } + this._parent = value; + } + } + _onWorldPositionRotationTransform() { + if (!this._getTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDPOSITION) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDQUATERNION) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDEULER)) { + this._setTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX | Transform3D.TRANSFORM_WORLDPOSITION | Transform3D.TRANSFORM_WORLDQUATERNION | Transform3D.TRANSFORM_WORLDEULER, true); + this.event(Laya.Event.TRANSFORM_CHANGED, this._transformFlag); + } + for (var i = 0, n = this._children.length; i < n; i++) + this._children[i]._onWorldPositionRotationTransform(); + } + _onWorldPositionScaleTransform() { + if (!this._getTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDPOSITION) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDSCALE)) { + this._setTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX | Transform3D.TRANSFORM_WORLDPOSITION | Transform3D.TRANSFORM_WORLDSCALE, true); + this.event(Laya.Event.TRANSFORM_CHANGED, this._transformFlag); + } + for (var i = 0, n = this._children.length; i < n; i++) + this._children[i]._onWorldPositionScaleTransform(); + } + _onWorldPositionTransform() { + if (!this._getTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDPOSITION)) { + this._setTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX | Transform3D.TRANSFORM_WORLDPOSITION, true); + this.event(Laya.Event.TRANSFORM_CHANGED, this._transformFlag); + } + for (var i = 0, n = this._children.length; i < n; i++) + this._children[i]._onWorldPositionTransform(); + } + _onWorldRotationTransform() { + if (!this._getTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDQUATERNION) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDEULER)) { + this._setTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX | Transform3D.TRANSFORM_WORLDQUATERNION | Transform3D.TRANSFORM_WORLDEULER, true); + this.event(Laya.Event.TRANSFORM_CHANGED, this._transformFlag); + } + for (var i = 0, n = this._children.length; i < n; i++) + this._children[i]._onWorldPositionRotationTransform(); + } + _onWorldScaleTransform() { + if (!this._getTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDSCALE)) { + this._setTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX | Transform3D.TRANSFORM_WORLDSCALE, true); + this.event(Laya.Event.TRANSFORM_CHANGED, this._transformFlag); + } + for (var i = 0, n = this._children.length; i < n; i++) + this._children[i]._onWorldPositionScaleTransform(); + } + _onWorldTransform() { + if (!this._getTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDPOSITION) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDQUATERNION) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDEULER) || !this._getTransformFlag(Transform3D.TRANSFORM_WORLDSCALE)) { + this._setTransformFlag(Transform3D.TRANSFORM_WORLDMATRIX | Transform3D.TRANSFORM_WORLDPOSITION | Transform3D.TRANSFORM_WORLDQUATERNION | Transform3D.TRANSFORM_WORLDEULER | Transform3D.TRANSFORM_WORLDSCALE, true); + this.event(Laya.Event.TRANSFORM_CHANGED, this._transformFlag); + } + for (var i = 0, n = this._children.length; i < n; i++) + this._children[i]._onWorldTransform(); + } + translate(translation, isLocal = true) { + if (isLocal) { + Matrix4x4.createFromQuaternion(this.localRotation, Transform3D._tempMatrix0); + Vector3.transformCoordinate(translation, Transform3D._tempMatrix0, Transform3D._tempVector30); + Vector3.add(this.localPosition, Transform3D._tempVector30, this._localPosition); + this.localPosition = this._localPosition; + } + else { + Vector3.add(this.position, translation, this._position); + this.position = this._position; + } + } + rotate(rotation, isLocal = true, isRadian = true) { + var rot; + if (isRadian) { + rot = rotation; + } + else { + Vector3.scale(rotation, Math.PI / 180.0, Transform3D._tempVector30); + rot = Transform3D._tempVector30; + } + Quaternion.createFromYawPitchRoll(rot.y, rot.x, rot.z, Transform3D._tempQuaternion0); + if (isLocal) { + Quaternion.multiply(this._localRotation, Transform3D._tempQuaternion0, this._localRotation); + this.localRotation = this._localRotation; + } + else { + Quaternion.multiply(Transform3D._tempQuaternion0, this.rotation, this._rotation); + this.rotation = this._rotation; + } + } + getForward(forward) { + var worldMatElem = this.worldMatrix.elements; + forward.x = -worldMatElem[8]; + forward.y = -worldMatElem[9]; + forward.z = -worldMatElem[10]; + } + getUp(up) { + var worldMatElem = this.worldMatrix.elements; + up.x = worldMatElem[4]; + up.y = worldMatElem[5]; + up.z = worldMatElem[6]; + } + getRight(right) { + var worldMatElem = this.worldMatrix.elements; + right.x = worldMatElem[0]; + right.y = worldMatElem[1]; + right.z = worldMatElem[2]; + } + lookAt(target, up, isLocal = false) { + var eye; + if (isLocal) { + eye = this._localPosition; + if (Math.abs(eye.x - target.x) < MathUtils3D.zeroTolerance && Math.abs(eye.y - target.y) < MathUtils3D.zeroTolerance && Math.abs(eye.z - target.z) < MathUtils3D.zeroTolerance) + return; + Quaternion.lookAt(this._localPosition, target, up, this._localRotation); + this._localRotation.invert(this._localRotation); + this.localRotation = this._localRotation; + } + else { + var worldPosition = this.position; + eye = worldPosition; + if (Math.abs(eye.x - target.x) < MathUtils3D.zeroTolerance && Math.abs(eye.y - target.y) < MathUtils3D.zeroTolerance && Math.abs(eye.z - target.z) < MathUtils3D.zeroTolerance) + return; + Quaternion.lookAt(worldPosition, target, up, this._rotation); + this._rotation.invert(this._rotation); + this.rotation = this._rotation; + } + } + getWorldLossyScale() { + if (this._getTransformFlag(Transform3D.TRANSFORM_WORLDSCALE)) { + if (this._parent !== null) { + var scaMatE = this._getScaleMatrix().elements; + this._scale.x = scaMatE[0]; + this._scale.y = scaMatE[4]; + this._scale.z = scaMatE[8]; + } + else { + this._localScale.cloneTo(this._scale); + } + this._setTransformFlag(Transform3D.TRANSFORM_WORLDSCALE, false); + } + return this._scale; + } + setWorldLossyScale(value) { + if (this._parent !== null) { + var scaleMat = Transform3D._tempMatrix3x33; + var localScaleMat = Transform3D._tempMatrix3x33; + var localScaleMatE = localScaleMat.elements; + var parInvScaleMat = this._parent._getScaleMatrix(); + parInvScaleMat.invert(parInvScaleMat); + Matrix3x3.createFromScaling(value, scaleMat); + Matrix3x3.multiply(parInvScaleMat, scaleMat, localScaleMat); + this._localScale.x = localScaleMatE[0]; + this._localScale.y = localScaleMatE[4]; + this._localScale.z = localScaleMatE[8]; + } + else { + value.cloneTo(this._localScale); + } + this.localScale = this._localScale; + if (this._scale !== value) + value.cloneTo(this._scale); + this._setTransformFlag(Transform3D.TRANSFORM_WORLDSCALE, false); + } + get scale() { + console.warn("Transfrm3D: discard function,please use getWorldLossyScale instead."); + return this.getWorldLossyScale(); + } + set scale(value) { + console.warn("Transfrm3D: discard function,please use setWorldLossyScale instead."); + this.setWorldLossyScale(value); + } + } + Transform3D._tempVector30 = new Vector3(); + Transform3D._tempQuaternion0 = new Quaternion(); + Transform3D._tempMatrix0 = new Matrix4x4(); + Transform3D._tempMatrix3x30 = new Matrix3x3(); + Transform3D._tempMatrix3x31 = new Matrix3x3(); + Transform3D._tempMatrix3x32 = new Matrix3x3(); + Transform3D._tempMatrix3x33 = new Matrix3x3(); + Transform3D.TRANSFORM_LOCALQUATERNION = 0x01; + Transform3D.TRANSFORM_LOCALEULER = 0x02; + Transform3D.TRANSFORM_LOCALMATRIX = 0x04; + Transform3D.TRANSFORM_WORLDPOSITION = 0x08; + Transform3D.TRANSFORM_WORLDQUATERNION = 0x10; + Transform3D.TRANSFORM_WORLDSCALE = 0x20; + Transform3D.TRANSFORM_WORLDMATRIX = 0x40; + Transform3D.TRANSFORM_WORLDEULER = 0x80; + Transform3D._angleToRandin = 180 / Math.PI; + + class Sprite3D extends Laya.Node { + constructor(name = null, isStatic = false) { + super(); + this._needProcessCollisions = false; + this._needProcessTriggers = false; + this._id = ++Sprite3D._uniqueIDCounter; + this._transform = new Transform3D(this); + this._isStatic = isStatic; + this.layer = 0; + this.name = name ? name : "New Sprite3D"; + } + static __init__() { + } + static instantiate(original, parent = null, worldPositionStays = true, position = null, rotation = null) { + var destSprite3D = original.clone(); + (parent) && (parent.addChild(destSprite3D)); + var transform = destSprite3D.transform; + if (worldPositionStays) { + var worldMatrix = transform.worldMatrix; + original.transform.worldMatrix.cloneTo(worldMatrix); + transform.worldMatrix = worldMatrix; + } + else { + (position) && (transform.position = position); + (rotation) && (transform.rotation = rotation); + } + return destSprite3D; + } + static load(url, complete) { + Laya.Laya.loader.create(url, complete, null, Sprite3D.HIERARCHY); + } + get id() { + return this._id; + } + get layer() { + return this._layer; + } + set layer(value) { + if (this._layer !== value) { + if (value >= 0 && value <= 30) { + this._layer = value; + } + else { + throw new Error("Layer value must be 0-30."); + } + } + } + get url() { + return this._url; + } + get isStatic() { + return this._isStatic; + } + get transform() { + return this._transform; + } + _setCreateURL(url) { + this._url = Laya.URL.formatURL(url); + } + _changeAnimatorsToLinkSprite3D(sprite3D, isLink, path) { + var animator = this.getComponent(Animator); + if (animator) { + if (!animator.avatar) + sprite3D._changeAnimatorToLinkSprite3DNoAvatar(animator, isLink, path); + } + if (this._parent && this._parent instanceof Sprite3D) { + path.unshift(this._parent.name); + var p = this._parent; + (p._hierarchyAnimator) && (p._changeAnimatorsToLinkSprite3D(sprite3D, isLink, path)); + } + } + _setHierarchyAnimator(animator, parentAnimator) { + this._changeHierarchyAnimator(animator); + this._changeAnimatorAvatar(animator.avatar); + for (var i = 0, n = this._children.length; i < n; i++) { + var child = this._children[i]; + (child._hierarchyAnimator == parentAnimator) && (child._setHierarchyAnimator(animator, parentAnimator)); + } + } + _clearHierarchyAnimator(animator, parentAnimator) { + this._changeHierarchyAnimator(parentAnimator); + this._changeAnimatorAvatar(parentAnimator ? parentAnimator.avatar : null); + for (var i = 0, n = this._children.length; i < n; i++) { + var child = this._children[i]; + (child._hierarchyAnimator == animator) && (child._clearHierarchyAnimator(animator, parentAnimator)); + } + } + _changeHierarchyAnimatorAvatar(animator, avatar) { + this._changeAnimatorAvatar(avatar); + for (var i = 0, n = this._children.length; i < n; i++) { + var child = this._children[i]; + (child._hierarchyAnimator == animator) && (child._changeHierarchyAnimatorAvatar(animator, avatar)); + } + } + _changeAnimatorToLinkSprite3DNoAvatar(animator, isLink, path) { + animator._handleSpriteOwnersBySprite(isLink, path, this); + for (var i = 0, n = this._children.length; i < n; i++) { + var child = this._children[i]; + var index = path.length; + path.push(child.name); + child._changeAnimatorToLinkSprite3DNoAvatar(animator, isLink, path); + path.splice(index, 1); + } + } + _changeHierarchyAnimator(animator) { + this._hierarchyAnimator = animator; + } + _changeAnimatorAvatar(avatar) { + } + _onInActiveInScene() { + super._onInActiveInScene(); + if (!this._scripts) + return; + for (let i = 0, n = this._scripts.length; i < n; i++) + this.scene._removeScript(this._scripts[i]); + } + _onAdded() { + if (this._parent instanceof Sprite3D) { + var parent3D = this._parent; + this.transform._setParent(parent3D.transform); + if (parent3D._hierarchyAnimator) { + (!this._hierarchyAnimator) && (this._setHierarchyAnimator(parent3D._hierarchyAnimator, null)); + parent3D._changeAnimatorsToLinkSprite3D(this, true, [this.name]); + } + } + super._onAdded(); + } + _onRemoved() { + super._onRemoved(); + if (this._parent instanceof Sprite3D) { + var parent3D = this._parent; + this.transform._setParent(null); + if (parent3D._hierarchyAnimator) { + (this._hierarchyAnimator == parent3D._hierarchyAnimator) && (this._clearHierarchyAnimator(parent3D._hierarchyAnimator, null)); + parent3D._changeAnimatorsToLinkSprite3D(this, false, [this.name]); + } + } + } + _parse(data, spriteMap) { + (data.isStatic !== undefined) && (this._isStatic = data.isStatic); + (data.active !== undefined) && (this.active = data.active); + (data.name != undefined) && (this.name = data.name); + if (data.position !== undefined) { + var loccalPosition = this.transform.localPosition; + loccalPosition.fromArray(data.position); + this.transform.localPosition = loccalPosition; + } + if (data.rotationEuler !== undefined) { + var localRotationEuler = this.transform.localRotationEuler; + localRotationEuler.fromArray(data.rotationEuler); + this.transform.localRotationEuler = localRotationEuler; + } + if (data.rotation !== undefined) { + var localRotation = this.transform.localRotation; + localRotation.fromArray(data.rotation); + this.transform.localRotation = localRotation; + } + if (data.scale !== undefined) { + var localScale = this.transform.localScale; + localScale.fromArray(data.scale); + this.transform.localScale = localScale; + } + (data.layer != undefined) && (this.layer = data.layer); + } + _cloneTo(destObject, srcRoot, dstRoot) { + if (this.destroyed) + throw new Error("Sprite3D: Can't be cloned if the Sprite3D has destroyed."); + var destSprite3D = destObject; + var trans = this._transform; + var destTrans = destSprite3D._transform; + destSprite3D.name = this.name; + destSprite3D.destroyed = this.destroyed; + destSprite3D.active = this.active; + destTrans.localPosition = trans.localPosition; + destTrans.localRotation = trans.localRotation; + destTrans.localScale = trans.localScale; + destSprite3D._isStatic = this._isStatic; + destSprite3D.layer = this.layer; + super._cloneTo(destSprite3D, srcRoot, dstRoot); + } + static _createSprite3DInstance(scrSprite) { + var node = scrSprite._create(); + var children = scrSprite._children; + for (var i = 0, n = children.length; i < n; i++) { + var child = Sprite3D._createSprite3DInstance(children[i]); + node.addChild(child); + } + return node; + } + static _parseSprite3DInstance(srcRoot, dstRoot, scrSprite, dstSprite) { + var srcChildren = scrSprite._children; + var dstChildren = dstSprite._children; + for (var i = 0, n = srcChildren.length; i < n; i++) + Sprite3D._parseSprite3DInstance(srcRoot, dstRoot, srcChildren[i], dstChildren[i]); + scrSprite._cloneTo(dstSprite, srcRoot, dstRoot); + } + clone() { + var dstSprite3D = Sprite3D._createSprite3DInstance(this); + Sprite3D._parseSprite3DInstance(this, dstSprite3D, this, dstSprite3D); + return dstSprite3D; + } + destroy(destroyChild = true) { + if (this.destroyed) + return; + super.destroy(destroyChild); + this._transform = null; + this._scripts = null; + this._url && Laya.Loader.clearRes(this._url); + } + _create() { + return new Sprite3D(); + } + } + Sprite3D.HIERARCHY = "HIERARCHY"; + Sprite3D.WORLDMATRIX = Shader3D.propertyNameToID("u_WorldMat"); + Sprite3D.MVPMATRIX = Shader3D.propertyNameToID("u_MvpMatrix"); + Sprite3D._uniqueIDCounter = 0; + + class DrawMeshCMD extends Command { + constructor() { + super(); + this._projectionViewWorldMatrix = new Matrix4x4(); + this._renderShaderValue = new ShaderData(); + this._renderShaderValue = new ShaderData(null); + } + static create(mesh, matrix, material, subMeshIndex, subShaderIndex, commandBuffer) { + var cmd; + cmd = DrawMeshCMD._pool.length > 0 ? DrawMeshCMD._pool.pop() : new DrawMeshCMD(); + cmd._mesh = mesh; + cmd._matrix = matrix; + cmd._material = material; + cmd._subMeshIndex = subMeshIndex; + cmd._subShaderIndex = subShaderIndex; + cmd._commandBuffer = commandBuffer; + return cmd; + } + run() { + var renderSubShader = this._material._shader.getSubShaderAt(this._subShaderIndex); + this.setContext(this._commandBuffer._context); + var context = this._context; + var forceInvertFace = context.invertY; + var scene = context.scene; + var cameraShaderValue = context.cameraShaderValue; + var projectionView = context.projectionViewMatrix; + Matrix4x4.multiply(projectionView, this._matrix, this._projectionViewWorldMatrix); + this._renderShaderValue.setMatrix4x4(Sprite3D.WORLDMATRIX, this._matrix); + this._renderShaderValue.setMatrix4x4(Sprite3D.MVPMATRIX, this._projectionViewWorldMatrix); + var currentPipelineMode = context.pipelineMode; + var passes = renderSubShader._passes; + for (var j = 0, m = passes.length; j < m; j++) { + var pass = passes[j]; + if (pass._pipelineMode !== currentPipelineMode) + continue; + var comDef = DrawMeshCMD._compileDefine; + scene._shaderValues._defineDatas.cloneTo(comDef); + comDef.addDefineDatas(this._renderShaderValue._defineDatas); + comDef.addDefineDatas(this._material._shaderValues._defineDatas); + var shaderIns = context.shader = pass.withCompile(comDef); + shaderIns.bind(); + shaderIns.uploadUniforms(shaderIns._sceneUniformParamsMap, scene._shaderValues, true); + shaderIns.uploadUniforms(shaderIns._spriteUniformParamsMap, this._renderShaderValue, true); + shaderIns.uploadUniforms(shaderIns._cameraUniformParamsMap, cameraShaderValue, true); + var matValues = this._material._shaderValues; + shaderIns.uploadUniforms(shaderIns._materialUniformParamsMap, matValues, true); + shaderIns.uploadRenderStateBlendDepth(matValues); + shaderIns.uploadRenderStateFrontFace(matValues, forceInvertFace, this._matrix.getInvertFront()); + } + var subGeometryElement = this._mesh._subMeshes; + var subMeshRender; + if (this._subMeshIndex == -1) { + for (var i = 0, n = subGeometryElement.length; i < n; i++) { + subMeshRender = subGeometryElement[i]; + if (subMeshRender._prepareRender(context)) { + subMeshRender._render(context); + } + } + } + else { + var subGeometryElement = this._mesh._subMeshes; + subMeshRender = subGeometryElement[this._subMeshIndex]; + if (subMeshRender._prepareRender(context)) { + subMeshRender._render(context); + } + } + } + recover() { + DrawMeshCMD._pool.push(this); + this._renderShaderValue.clearDefine(); + this._renderShaderValue._initData(); + } + } + DrawMeshCMD._pool = []; + DrawMeshCMD._compileDefine = new DefineDatas(); + + class ClearRenderTextureCMD extends Command { + constructor() { + super(...arguments); + this._clearColor = false; + this._clearDepth = false; + this._backgroundColor = new Vector4(); + this._depth = 1; + } + static create(clearColor, clearDepth, backgroundColor, depth = 1, commandBuffer) { + var cmd; + cmd = ClearRenderTextureCMD._pool.length > 0 ? ClearRenderTextureCMD._pool.pop() : new ClearRenderTextureCMD(); + cmd._clearColor = clearColor; + cmd._clearDepth = clearDepth; + backgroundColor.cloneTo(cmd._backgroundColor); + cmd._depth = depth; + cmd._commandBuffer = commandBuffer; + return cmd; + } + run() { + var gl = Laya.LayaGL.instance; + var flag; + var backgroundColor = this._backgroundColor; + if (this._clearColor) { + gl.clearColor(backgroundColor.x, backgroundColor.y, backgroundColor.z, backgroundColor.w); + flag |= gl.COLOR_BUFFER_BIT; + } + if (this._clearDepth) { + gl.clearDepth(this._depth); + flag |= gl.DEPTH_BUFFER_BIT; + } + if (this._clearColor || this._clearDepth) { + gl.clear(flag); + } + } + recover() { + } + } + ClearRenderTextureCMD._pool = []; + + class DrawRenderCMD extends Command { + static create(render, material, subShaderIndex, commandBuffer) { + var cmd; + cmd = DrawRenderCMD._pool.length > 0 ? DrawRenderCMD._pool.pop() : new DrawRenderCMD(); + cmd._render = render; + cmd._material = material; + cmd._subShaderIndex = subShaderIndex; + cmd._commandBuffer = commandBuffer; + return cmd; + } + _elementRender(renderElement, context) { + var forceInvertFace = context.invertY; + var lastStateMaterial, lastStateShaderInstance, lastStateRender; + var updateMark = ILaya3D.Camera._updateMark; + var scene = context.scene; + this._render._scene = context.scene; + var cameraShaderValue = context.cameraShaderValue; + var transform = renderElement._transform; + var geometry = renderElement._geometry; + context.renderElement = renderElement; + var updateRender = updateMark !== renderElement.render._updateMark || renderElement.renderType !== renderElement.render._updateRenderType; + if (updateRender) { + renderElement.render._renderUpdate(context, transform); + renderElement.render._renderUpdateWithCamera(context, transform); + renderElement.render._updateMark = updateMark; + renderElement.render._updateRenderType = renderElement.renderType; + } + else { + if (renderElement.renderType == ILaya3D.RenderElement.RENDERTYPE_INSTANCEBATCH) { + renderElement.render._renderUpdate(context, transform); + renderElement.render._renderUpdateWithCamera(context, transform); + } + } + var currentPipelineMode = context.pipelineMode; + if (geometry._prepareRender(context)) { + var passes = renderElement.renderSubShader._passes; + for (var j = 0, m = passes.length; j < m; j++) { + var pass = passes[j]; + if (pass._pipelineMode !== currentPipelineMode) + continue; + var comDef = DrawRenderCMD._compileDefine; + scene._shaderValues._defineDatas.cloneTo(comDef); + comDef.addDefineDatas(renderElement.render._shaderValues._defineDatas); + comDef.addDefineDatas(this._material._shaderValues._defineDatas); + var shaderIns = context.shader = pass.withCompile(comDef); + var switchShader = shaderIns.bind(); + var switchUpdateMark = (updateMark !== shaderIns._uploadMark); + var uploadScene = (shaderIns._uploadScene !== scene) || switchUpdateMark; + if (uploadScene || switchShader) { + shaderIns.uploadUniforms(shaderIns._sceneUniformParamsMap, scene._shaderValues, uploadScene); + shaderIns._uploadScene = scene; + } + var uploadSprite3D = (shaderIns._uploadRender !== renderElement.render || shaderIns._uploadRenderType !== renderElement.renderType) || switchUpdateMark; + if (uploadSprite3D || switchShader) { + shaderIns.uploadUniforms(shaderIns._spriteUniformParamsMap, renderElement.render._shaderValues, uploadSprite3D); + shaderIns._uploadRender = renderElement.render; + shaderIns._uploadRenderType = renderElement.renderType; + } + var uploadCamera = shaderIns._uploadCameraShaderValue !== cameraShaderValue || switchUpdateMark; + if (uploadCamera || switchShader) { + shaderIns.uploadUniforms(shaderIns._cameraUniformParamsMap, cameraShaderValue, uploadCamera); + shaderIns._uploadCameraShaderValue = cameraShaderValue; + } + var uploadMaterial = (shaderIns._uploadMaterial !== this._material) || switchUpdateMark; + if (uploadMaterial || switchShader) { + shaderIns.uploadUniforms(shaderIns._materialUniformParamsMap, this._material._shaderValues, uploadMaterial); + shaderIns._uploadMaterial = this._material; + } + var matValues = this._material._shaderValues; + if (lastStateMaterial !== this._material || lastStateShaderInstance !== shaderIns) { + shaderIns.uploadRenderStateBlendDepth(matValues); + shaderIns.uploadRenderStateFrontFace(matValues, forceInvertFace, renderElement.getInvertFront()); + lastStateMaterial = this._material; + lastStateShaderInstance = shaderIns; + lastStateRender = renderElement.render; + } + else { + if (lastStateRender !== renderElement.render) { + shaderIns.uploadRenderStateFrontFace(matValues, forceInvertFace, renderElement.getInvertFront()); + lastStateRender = renderElement.render; + } + } + geometry._render(context); + shaderIns._uploadMark = updateMark; + } + } + if (renderElement.renderType !== ILaya3D.RenderElement.RENDERTYPE_NORMAL) + renderElement.render._revertBatchRenderUpdate(context); + } + run() { + if (!this._material) + throw "This render command material cannot be empty"; + this.setContext(this._commandBuffer._context); + var context = this._context; + var scene = context.scene; + var renderElements = this._render._renderElements; + for (var i = 0, n = renderElements.length; i < n; i++) { + var renderelement = renderElements[i]; + this._renderElementUpdate(renderelement); + this._elementRender(renderelement, context); + } + } + _renderElementUpdate(renderelement) { + if (this._material) { + renderelement.renderSubShader = this._material._shader.getSubShaderAt(this._subShaderIndex); + } + } + recover() { + DrawRenderCMD._pool.push(this); + } + } + DrawRenderCMD._pool = []; + DrawRenderCMD._compileDefine = new DefineDatas(); + + class SetGlobalShaderDataCMD extends Command { + constructor() { + super(...arguments); + this._nameID = 0; + this._value = null; + this._dataType = -1; + } + static create(nameID, value, shaderDataType, commandBuffer) { + var cmd; + cmd = SetGlobalShaderDataCMD._pool.length > 0 ? SetGlobalShaderDataCMD._pool.pop() : new SetGlobalShaderDataCMD(); + cmd._nameID = nameID; + cmd._value = value; + cmd._dataType = shaderDataType; + cmd._commandBuffer = commandBuffer; + return cmd; + } + run() { + var shaderData = this._commandBuffer._camera.scene._shaderValues; + switch (this._dataType) { + case exports.ShaderDataType.Int: + shaderData.setInt(this._nameID, this._value); + break; + case exports.ShaderDataType.Number: + shaderData.setNumber(this._nameID, this._value); + break; + case exports.ShaderDataType.Bool: + shaderData.setBool(this._nameID, this._value); + break; + case exports.ShaderDataType.Matrix4x4: + shaderData.setMatrix4x4(this._nameID, this._value); + break; + case exports.ShaderDataType.Quaternion: + shaderData.setQuaternion(this._nameID, this._value); + break; + case exports.ShaderDataType.Texture: + shaderData.setTexture(this._nameID, this._value); + break; + case exports.ShaderDataType.Vector4: + shaderData.setVector(this._nameID, this._value); + break; + case exports.ShaderDataType.Vector2: + shaderData.setVector2(this._nameID, this._value); + break; + case exports.ShaderDataType.Vector3: + shaderData.setVector3(this._nameID, this._value); + break; + case exports.ShaderDataType.Buffer: + shaderData.setBuffer(this._nameID, this._value); + break; + default: + throw "no type shaderValue on this CommendBuffer"; + } + } + recover() { + SetGlobalShaderDataCMD._pool.push(this); + this._nameID = 0; + this._value = null; + this._dataType = -1; + } + } + SetGlobalShaderDataCMD._pool = []; + + class MeshSprite3DShaderDeclaration { + } + + class VertexMesh { + static __init__() { + VertexMesh.instanceWorldMatrixDeclaration = new VertexDeclaration(64, [new VertexElement(0, VertexElementFormat.Vector4, VertexMesh.MESH_WORLDMATRIX_ROW0), + new VertexElement(16, VertexElementFormat.Vector4, VertexMesh.MESH_WORLDMATRIX_ROW1), + new VertexElement(32, VertexElementFormat.Vector4, VertexMesh.MESH_WORLDMATRIX_ROW2), + new VertexElement(48, VertexElementFormat.Vector4, VertexMesh.MESH_WORLDMATRIX_ROW3)]); + VertexMesh.instanceSimpleAnimatorDeclaration = new VertexDeclaration(16, [new VertexElement(0, VertexElementFormat.Vector4, VertexMesh.MESH_SIMPLEANIMATOR)]); + } + static getVertexDeclaration(vertexFlag, compatible = true) { + var verDec = VertexMesh._vertexDeclarationMap[vertexFlag + (compatible ? "_0" : "_1")]; + if (!verDec) { + var subFlags = vertexFlag.split(","); + var offset = 0; + var elements = []; + for (var i = 0, n = subFlags.length; i < n; i++) { + var element; + switch (subFlags[i]) { + case "POSITION": + element = new VertexElement(offset, VertexElementFormat.Vector3, VertexMesh.MESH_POSITION0); + offset += 12; + break; + case "NORMAL": + element = new VertexElement(offset, VertexElementFormat.Vector3, VertexMesh.MESH_NORMAL0); + offset += 12; + break; + case "COLOR": + element = new VertexElement(offset, VertexElementFormat.Vector4, VertexMesh.MESH_COLOR0); + offset += 16; + break; + case "UV": + element = new VertexElement(offset, VertexElementFormat.Vector2, VertexMesh.MESH_TEXTURECOORDINATE0); + offset += 8; + break; + case "UV1": + element = new VertexElement(offset, VertexElementFormat.Vector2, VertexMesh.MESH_TEXTURECOORDINATE1); + offset += 8; + break; + case "BLENDWEIGHT": + element = new VertexElement(offset, VertexElementFormat.Vector4, VertexMesh.MESH_BLENDWEIGHT0); + offset += 16; + break; + case "BLENDINDICES": + if (compatible) { + element = new VertexElement(offset, VertexElementFormat.Vector4, VertexMesh.MESH_BLENDINDICES0); + offset += 16; + } + else { + element = new VertexElement(offset, VertexElementFormat.Byte4, VertexMesh.MESH_BLENDINDICES0); + offset += 4; + } + break; + case "TANGENT": + element = new VertexElement(offset, VertexElementFormat.Vector4, VertexMesh.MESH_TANGENT0); + offset += 16; + break; + default: + throw "VertexMesh: unknown vertex flag."; + } + elements.push(element); + } + verDec = new VertexDeclaration(offset, elements); + VertexMesh._vertexDeclarationMap[vertexFlag + (compatible ? "_0" : "_1")] = verDec; + } + return verDec; + } + } + VertexMesh.MESH_POSITION0 = 0; + VertexMesh.MESH_COLOR0 = 1; + VertexMesh.MESH_TEXTURECOORDINATE0 = 2; + VertexMesh.MESH_NORMAL0 = 3; + VertexMesh.MESH_TANGENT0 = 4; + VertexMesh.MESH_BLENDINDICES0 = 5; + VertexMesh.MESH_BLENDWEIGHT0 = 6; + VertexMesh.MESH_TEXTURECOORDINATE1 = 7; + VertexMesh.MESH_WORLDMATRIX_ROW0 = 8; + VertexMesh.MESH_WORLDMATRIX_ROW1 = 9; + VertexMesh.MESH_WORLDMATRIX_ROW2 = 10; + VertexMesh.MESH_WORLDMATRIX_ROW3 = 11; + VertexMesh.MESH_SIMPLEANIMATOR = 12; + VertexMesh.MESH_CUSTOME0 = 12; + VertexMesh.MESH_CUSTOME1 = 13; + VertexMesh.MESH_CUSTOME2 = 14; + VertexMesh.MESH_CUSTOME3 = 15; + VertexMesh._vertexDeclarationMap = {}; + + class DrawMeshInstancedCMD extends Command { + constructor() { + super(); + this._renderShaderValue = new ShaderData(null); + let gl = Laya.LayaGL.instance; + this._instanceWorldMatrixData = new Float32Array(DrawMeshInstancedCMD.maxInstanceCount * 16); + this._instanceWorldMatrixBuffer = new VertexBuffer3D(this._instanceWorldMatrixData.length * 4, gl.DYNAMIC_DRAW); + this._instanceWorldMatrixBuffer.vertexDeclaration = VertexMesh.instanceWorldMatrixDeclaration; + } + static create(mesh, subMeshIndex, matrixs, material, subShaderIndex, instanceProperty, drawnums, commandBuffer) { + var cmd; + if ((matrixs && matrixs.length > 1024) || drawnums > DrawMeshInstancedCMD.maxInstanceCount) { + throw "the number of renderings exceeds the maximum number of merges"; + } + cmd = DrawMeshInstancedCMD._pool.length > 0 ? DrawMeshInstancedCMD._pool.pop() : new DrawMeshInstancedCMD(); + cmd._mesh = mesh; + cmd._matrixs = matrixs; + cmd._material = material; + cmd._subMeshIndex = subMeshIndex; + cmd._subShaderIndex = subShaderIndex; + cmd._commandBuffer = commandBuffer; + cmd._instanceProperty = instanceProperty; + cmd._drawnums = drawnums; + matrixs || cmd._updateWorldMatrixBuffer(); + cmd._setInstanceBuffer(); + return cmd; + } + _setInstanceBuffer() { + let instanceBufferState = this._instanceBufferState = new BufferState(); + instanceBufferState.bind(); + instanceBufferState.applyVertexBuffer(this._mesh._vertexBuffer); + instanceBufferState.applyInstanceVertexBuffer(this._instanceWorldMatrixBuffer); + let propertyMap = this._instanceProperty._propertyMap; + for (let i in propertyMap) { + instanceBufferState.applyInstanceVertexBuffer(propertyMap[i]._vertexBuffer); + } + instanceBufferState.applyIndexBuffer(this._mesh._indexBuffer); + instanceBufferState.unBind(); + } + _updateWorldMatrixBuffer() { + let worldMatrixData = this._instanceWorldMatrixData; + let count = this._drawnums; + for (let i = 0; i < count; i++) { + worldMatrixData.set(this._matrixs[i].elements, i * 16); + } + let worldBuffer = this._instanceWorldMatrixBuffer; + worldBuffer.orphanStorage(); + worldBuffer.setData(worldMatrixData.buffer, 0, 0, count * 64); + } + _render(subMesh) { + let gl = Laya.LayaGL.instance; + var count = this._drawnums; + var indexCount = subMesh._indexCount; + this._instanceBufferState.bind(); + Laya.LayaGL.layaGPUInstance.drawElementsInstanced(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, subMesh._indexStart * 2, count); + Laya.Stat.renderBatches++; + Laya.Stat.trianglesFaces += indexCount * count / 3; + } + run() { + let renderSubShader = this._material._shader.getSubShaderAt(this._subShaderIndex); + this.setContext(this._commandBuffer._context); + let context = this._context; + let forceInvertFace = context.invertY; + let scene = context.scene; + let cameraShaderValue = context.cameraShaderValue; + let currentPipelineMode = context.pipelineMode; + this._renderShaderValue.addDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_GPU_INSTANCE); + let passes = renderSubShader._passes; + for (let j = 0, m = passes.length; j < m; j++) { + let pass = passes[j]; + if (pass._pipelineMode !== currentPipelineMode) + continue; + let comDef = DrawMeshInstancedCMD._compileDefine; + scene._shaderValues._defineDatas.cloneTo(comDef); + comDef.addDefineDatas(this._renderShaderValue._defineDatas); + comDef.addDefineDatas(this._material._shaderValues._defineDatas); + let shaderIns = context.shader = pass.withCompile(comDef); + shaderIns.bind(); + shaderIns.uploadUniforms(shaderIns._sceneUniformParamsMap, scene._shaderValues, true); + shaderIns.uploadUniforms(shaderIns._spriteUniformParamsMap, this._renderShaderValue, true); + shaderIns.uploadUniforms(shaderIns._cameraUniformParamsMap, cameraShaderValue, true); + let matValues = this._material._shaderValues; + shaderIns.uploadUniforms(shaderIns._materialUniformParamsMap, matValues, true); + shaderIns.uploadRenderStateBlendDepth(matValues); + shaderIns.uploadRenderStateFrontFace(matValues, forceInvertFace, false); + } + let propertyMap = this._instanceProperty._propertyMap; + for (let i in propertyMap) { + propertyMap[i].updateVertexBufferData(this._drawnums); + } + let subGeometryElement = this._mesh._subMeshes; + let subMeshRender; + if (this._subMeshIndex == -1) { + for (let i = 0, n = subGeometryElement.length; i < n; i++) { + subMeshRender = subGeometryElement[i]; + if (subMeshRender._prepareRender(context)) { + this._render(subMeshRender); + } + } + } + else { + let subGeometryElement = this._mesh._subMeshes; + subMeshRender = subGeometryElement[this._subMeshIndex]; + if (subMeshRender._prepareRender(context)) { + this._render(subMeshRender); + } + } + } + setWorldMatrix(worldMatrixArray) { + if (worldMatrixArray.length < this._drawnums) + throw "worldMatrixArray length is less then drawnums"; + this._matrixs = worldMatrixArray; + this._matrixs && this._updateWorldMatrixBuffer(); + } + setDrawNums(drawNums) { + if (this._matrixs && this._matrixs.length < drawNums) + throw "worldMatrixArray length is less then drawnums"; + this._drawnums = drawNums; + this._matrixs && this._updateWorldMatrixBuffer(); + } + recover() { + DrawMeshInstancedCMD._pool.push(this); + this._renderShaderValue.clearDefine(); + this._renderShaderValue._initData(); + this._instanceBufferState.destroy(); + this._instanceBufferState = null; + } + } + DrawMeshInstancedCMD._pool = []; + DrawMeshInstancedCMD._compileDefine = new DefineDatas(); + DrawMeshInstancedCMD.maxInstanceCount = 1024; + + class CommandBuffer { + constructor() { + this._camera = null; + this._commands = []; + } + _apply() { + for (var i = 0, n = this._commands.length; i < n; i++) + this._commands[i].run(); + } + setShaderDataTexture(shaderData, nameID, source) { + this._commands.push(SetShaderDataCMD.create(shaderData, nameID, source, exports.ShaderDataType.Texture, this)); + } + setGlobalTexture(nameID, source) { + this._commands.push(SetGlobalShaderDataCMD.create(nameID, source, exports.ShaderDataType.Texture, this)); + } + setShaderDataVector(shaderData, nameID, value) { + this._commands.push(SetShaderDataCMD.create(shaderData, nameID, value, exports.ShaderDataType.Vector4, this)); + } + setGlobalVector(nameID, source) { + this._commands.push(SetGlobalShaderDataCMD.create(nameID, source, exports.ShaderDataType.Vector4, this)); + } + setShaderDataVector3(shaderData, nameID, value) { + this._commands.push(SetShaderDataCMD.create(shaderData, nameID, value, exports.ShaderDataType.Vector3, this)); + } + setGlobalVector3(nameID, source) { + this._commands.push(SetGlobalShaderDataCMD.create(nameID, source, exports.ShaderDataType.Vector3, this)); + } + setShaderDataVector2(shaderData, nameID, value) { + this._commands.push(SetShaderDataCMD.create(shaderData, nameID, value, exports.ShaderDataType.Vector2, this)); + } + setGlobalVector2(nameID, source) { + this._commands.push(SetGlobalShaderDataCMD.create(nameID, source, exports.ShaderDataType.Vector2, this)); + } + setShaderDataNumber(shaderData, nameID, value) { + this._commands.push(SetShaderDataCMD.create(shaderData, nameID, value, exports.ShaderDataType.Number, this)); + } + setGlobalNumber(nameID, source) { + this._commands.push(SetGlobalShaderDataCMD.create(nameID, source, exports.ShaderDataType.Number, this)); + } + setShaderDataInt(shaderData, nameID, value) { + this._commands.push(SetShaderDataCMD.create(shaderData, nameID, value, exports.ShaderDataType.Int, this)); + } + setGlobalInt(nameID, source) { + this._commands.push(SetGlobalShaderDataCMD.create(nameID, source, exports.ShaderDataType.Int, this)); + } + setShaderDataMatrix(shaderData, nameID, value) { + this._commands.push(SetShaderDataCMD.create(shaderData, nameID, value, exports.ShaderDataType.Matrix4x4, this)); + } + setGlobalMatrix(nameID, source) { + this._commands.push(SetGlobalShaderDataCMD.create(nameID, source, exports.ShaderDataType.Matrix4x4, this)); + } + blitScreenQuad(source, dest, offsetScale = null, shader = null, shaderData = null, subShader = 0, definedCanvas = false) { + this._commands.push(BlitScreenQuadCMD.create(source, dest, offsetScale, shader, shaderData, subShader, BlitScreenQuadCMD._SCREENTYPE_QUAD, this, definedCanvas)); + } + blitScreenQuadByMaterial(source, dest, offsetScale = null, material = null, subShader = 0) { + var shader; + var shaderData; + if (material) { + shader = material._shader; + shaderData = material.shaderData; + } + this._commands.push(BlitScreenQuadCMD.create(source, dest, offsetScale, shader, shaderData, subShader, BlitScreenQuadCMD._SCREENTYPE_QUAD, this)); + } + blitScreenTriangle(source, dest, offsetScale = null, shader = null, shaderData = null, subShader = 0, defineCanvas = false) { + this._commands.push(BlitScreenQuadCMD.create(source, dest, offsetScale, shader, shaderData, subShader, BlitScreenQuadCMD._SCREENTYPE_TRIANGLE, this, defineCanvas)); + } + setRenderTarget(renderTexture) { + this._commands.push(SetRenderTargetCMD.create(renderTexture)); + } + clearRenderTarget(clearColor, clearDepth, backgroundColor, depth = 1) { + this._commands.push(ClearRenderTextureCMD.create(clearColor, clearDepth, backgroundColor, depth, this)); + } + drawMesh(mesh, matrix, material, submeshIndex, subShaderIndex) { + this._commands.push(DrawMeshCMD.create(mesh, matrix, material, submeshIndex, subShaderIndex, this)); + } + drawRender(render, material, subShaderIndex) { + this._commands.push(DrawRenderCMD.create(render, material, subShaderIndex, this)); + } + drawMeshInstance(mesh, subMeshIndex, matrixs, material, subShaderIndex, instanceProperty, drawnums) { + if (!Laya.LayaGL.layaGPUInstance.supportInstance()) + return null; + var drawMeshInstancedCMD = DrawMeshInstancedCMD.create(mesh, subMeshIndex, matrixs, material, subShaderIndex, instanceProperty, drawnums, this); + this._commands.push(drawMeshInstancedCMD); + return drawMeshInstancedCMD; + } + clear() { + for (var i = 0, n = this._commands.length; i < n; i++) + this._commands[i].recover(); + this._commands.length = 0; + } + } + + class PostProcessRenderContext { + constructor() { + this.source = null; + this.destination = null; + this.camera = null; + this.compositeShaderData = null; + this.command = null; + this.deferredReleaseTextures = []; + } + } + + class PostProcess { + constructor() { + this._compositeShader = Shader3D.find("PostProcessComposite"); + this._compositeShaderData = new ShaderData(); + this._effects = []; + this._enable = true; + this._context = null; + this._context = new PostProcessRenderContext(); + this._context.compositeShaderData = this._compositeShaderData; + this._context.command = new CommandBuffer(); + } + static __init__() { + PostProcess.SHADERDEFINE_BLOOM_LOW = Shader3D.getDefineByName("BLOOM_LOW"); + PostProcess.SHADERDEFINE_BLOOM = Shader3D.getDefineByName("BLOOM"); + PostProcess.SHADERDEFINE_FINALPASS = Shader3D.getDefineByName("FINALPASS"); + } + get enable() { + return this._enable; + } + set enable(value) { + this._enable = value; + } + _init(camera) { + this._context.camera = camera; + this._context.command._camera = camera; + } + _render() { + var noteValue = ShaderData._SET_RUNTIME_VALUE_MODE_REFERENCE_; + Laya.ILaya.Render.supportWebGLPlusRendering && ShaderData.setRuntimeValueMode(false); + var camera = this._context.camera; + var viewport = camera.viewport; + var cameraTarget = camera._internalRenderTexture; + var screenTexture = cameraTarget; + this._context.command.clear(); + this._context.source = screenTexture; + this._context.destination = cameraTarget; + this._context.compositeShaderData.clearDefine(); + this._context.compositeShaderData.setTexture(PostProcess.SHADERVALUE_AUTOEXPOSURETEX, Laya.Texture2D.whiteTexture); + for (var i = 0, n = this._effects.length; i < n; i++) + this._effects[i].render(this._context); + this._compositeShaderData.addDefine(PostProcess.SHADERDEFINE_FINALPASS); + var offScreenTex = camera._offScreenRenderTexture; + var dest = offScreenTex ? offScreenTex : null; + this._context.destination = dest; + var canvasWidth = camera._getCanvasWidth(), canvasHeight = camera._getCanvasHeight(); + camera._screenOffsetScale.setValue(viewport.x / canvasWidth, viewport.y / canvasHeight, viewport.width / canvasWidth, viewport.height / canvasHeight); + this._context.command.blitScreenTriangle(this._context.source, dest, camera._screenOffsetScale, this._compositeShader, this._compositeShaderData, 0, true); + RenderTexture.recoverToPool(screenTexture); + var tempRenderTextures = this._context.deferredReleaseTextures; + for (i = 0, n = tempRenderTextures.length; i < n; i++) + RenderTexture.recoverToPool(tempRenderTextures[i]); + tempRenderTextures.length = 0; + Laya.ILaya.Render.supportWebGLPlusRendering && ShaderData.setRuntimeValueMode(noteValue); + } + addEffect(effect) { + this._effects.push(effect); + } + removeEffect(effect) { + var index = this._effects.indexOf(effect); + if (index !== -1) + this._effects.splice(index, 1); + } + _applyPostProcessCommandBuffers() { + this._context.command._apply(); + } + } + PostProcess.SHADERVALUE_MAINTEX = Shader3D.propertyNameToID("u_MainTex"); + PostProcess.SHADERVALUE_BLOOMTEX = Shader3D.propertyNameToID("u_BloomTex"); + PostProcess.SHADERVALUE_AUTOEXPOSURETEX = Shader3D.propertyNameToID("u_AutoExposureTex"); + PostProcess.SHADERVALUE_BLOOM_DIRTTEX = Shader3D.propertyNameToID("u_Bloom_DirtTex"); + PostProcess.SHADERVALUE_BLOOMTEX_TEXELSIZE = Shader3D.propertyNameToID("u_BloomTex_TexelSize"); + PostProcess.SHADERVALUE_BLOOM_DIRTTILEOFFSET = Shader3D.propertyNameToID("u_Bloom_DirtTileOffset"); + PostProcess.SHADERVALUE_BLOOM_SETTINGS = Shader3D.propertyNameToID("u_Bloom_Settings"); + PostProcess.SHADERVALUE_BLOOM_COLOR = Shader3D.propertyNameToID("u_Bloom_Color"); + + class AnimationTransform3D extends Laya.EventDispatcher { + constructor(owner) { + super(); + this._owner = owner; + this._children = []; + this._localMatrix = new Float32Array(16); + this._localPosition = new Vector3(); + this._localRotation = new Quaternion(); + this._localScale = new Vector3(); + this._worldMatrix = new Float32Array(16); + this._localQuaternionUpdate = false; + this._locaEulerlUpdate = false; + this._localUpdate = false; + this._worldUpdate = true; + } + _getlocalMatrix() { + if (this._localUpdate) { + Utils3D._createAffineTransformationArray(this._localPosition, this._localRotation, this._localScale, this._localMatrix); + this._localUpdate = false; + } + return this._localMatrix; + } + _onWorldTransform() { + if (!this._worldUpdate) { + this._worldUpdate = true; + this.event(Laya.Event.TRANSFORM_CHANGED); + for (var i = 0, n = this._children.length; i < n; i++) + this._children[i]._onWorldTransform(); + } + } + get localPosition() { + return this._localPosition; + } + set localPosition(value) { + this._localPosition = value; + this._localUpdate = true; + this._onWorldTransform(); + } + get localRotation() { + if (this._localQuaternionUpdate) { + var euler = this._localRotationEuler; + Quaternion.createFromYawPitchRoll(euler.y / AnimationTransform3D._angleToRandin, euler.x / AnimationTransform3D._angleToRandin, euler.z / AnimationTransform3D._angleToRandin, this._localRotation); + this._localQuaternionUpdate = false; + } + return this._localRotation; + } + set localRotation(value) { + this._localRotation = value; + this._locaEulerlUpdate = true; + this._localQuaternionUpdate = false; + this._localUpdate = true; + this._onWorldTransform(); + } + get localScale() { + return this._localScale; + } + set localScale(value) { + this._localScale = value; + this._localUpdate = true; + this._onWorldTransform(); + } + get localRotationEuler() { + if (this._locaEulerlUpdate) { + this._localRotation.getYawPitchRoll(AnimationTransform3D._tempVector3); + var euler = AnimationTransform3D._tempVector3; + var localRotationEuler = this._localRotationEuler; + localRotationEuler.x = euler.y * AnimationTransform3D._angleToRandin; + localRotationEuler.y = euler.x * AnimationTransform3D._angleToRandin; + localRotationEuler.z = euler.z * AnimationTransform3D._angleToRandin; + this._locaEulerlUpdate = false; + } + return this._localRotationEuler; + } + set localRotationEuler(value) { + this._localRotationEuler = value; + this._locaEulerlUpdate = false; + this._localQuaternionUpdate = true; + this._localUpdate = true; + this._onWorldTransform(); + } + getWorldMatrix() { + if (this._worldUpdate) { + if (this._parent != null) { + Utils3D.matrix4x4MultiplyFFF(this._parent.getWorldMatrix(), this._getlocalMatrix(), this._worldMatrix); + } + else { + var e = this._worldMatrix; + e[1] = e[2] = e[3] = e[4] = e[6] = e[7] = e[8] = e[9] = e[11] = e[12] = e[13] = e[14] = 0; + e[0] = e[5] = e[10] = e[15] = 1; + } + this._worldUpdate = false; + } + return this._worldMatrix; + } + setParent(value) { + if (this._parent !== value) { + if (this._parent) { + var parentChilds = this._parent._children; + var index = parentChilds.indexOf(this); + parentChilds.splice(index, 1); + } + if (value) { + value._children.push(this); + (value) && (this._onWorldTransform()); + } + this._parent = value; + } + } + } + AnimationTransform3D._tempVector3 = new Vector3(); + AnimationTransform3D._angleToRandin = 180 / Math.PI; + + class AnimationNode { + constructor() { + this._parent = null; + this.name = null; + this._worldMatrixIndex = 0; + this._children = []; + this.transform = new AnimationTransform3D(this); + } + addChild(child) { + child._parent = this; + child.transform.setParent(this.transform); + this._children.push(child); + } + removeChild(child) { + var index = this._children.indexOf(child); + (index !== -1) && (this._children.splice(index, 1)); + } + getChildByName(name) { + for (var i = 0, n = this._children.length; i < n; i++) { + var child = this._children[i]; + if (child.name === name) + return child; + } + return null; + } + getChildByIndex(index) { + return this._children[index]; + } + getChildCount() { + return this._children.length; + } + cloneTo(destObject) { + var destNode = destObject; + destNode.name = this.name; + for (var i = 0, n = this._children.length; i < n; i++) { + var child = this._children[i]; + var destChild = child.clone(); + destNode.addChild(destChild); + var transform = child.transform; + var destTransform = destChild.transform; + var destLocalPosition = destTransform.localPosition; + var destLocalRotation = destTransform.localRotation; + var destLocalScale = destTransform.localScale; + transform.localPosition.cloneTo(destLocalPosition); + transform.localRotation.cloneTo(destLocalRotation); + transform.localScale.cloneTo(destLocalScale); + destTransform.localPosition = destLocalPosition; + destTransform.localRotation = destLocalRotation; + destTransform.localScale = destLocalScale; + } + } + clone() { + var dest = new AnimationNode(); + this.cloneTo(dest); + return dest; + } + _cloneNative(localPositions, localRotations, localScales, animationNodeWorldMatrixs, animationNodeParentIndices, parentIndex, avatar) { + var curID = avatar._nativeCurCloneCount; + animationNodeParentIndices[curID] = parentIndex; + var dest = new AnimationNode(); + dest._worldMatrixIndex = curID; + this._cloneToNative(dest, localPositions, localRotations, localScales, animationNodeWorldMatrixs, animationNodeParentIndices, curID, avatar); + return dest; + } + _cloneToNative(destObject, localPositions, localRotations, localScales, animationNodeWorldMatrixs, animationNodeParentIndices, parentIndex, avatar) { + var destNode = destObject; + destNode.name = this.name; + for (var i = 0, n = this._children.length; i < n; i++) { + var child = this._children[i]; + avatar._nativeCurCloneCount++; + var destChild = child._cloneNative(localPositions, localRotations, localScales, animationNodeWorldMatrixs, animationNodeParentIndices, parentIndex, avatar); + destNode.addChild(destChild); + var transform = child.transform; + var destTransform = destChild.transform; + var destLocalPosition = destTransform.localPosition; + var destLocalRotation = destTransform.localRotation; + var destLocalScale = destTransform.localScale; + transform.localPosition.cloneTo(destLocalPosition); + transform.localRotation.cloneTo(destLocalRotation); + transform.localScale.cloneTo(destLocalScale); + destTransform.localPosition = destLocalPosition; + destTransform.localRotation = destLocalRotation; + destTransform.localScale = destLocalScale; + } + } + } + + class Avatar extends Laya.Resource { + constructor() { + super(); + this._nativeNodeCount = 0; + this._nativeCurCloneCount = 0; + } + static _parse(data, propertyParams = null, constructParams = null) { + var avatar = new Avatar(); + avatar._rootNode = new AnimationNode(); + if (data.version) { + var rootNode = data.rootNode; + (rootNode) && (avatar._parseNode(rootNode, avatar._rootNode)); + } + return avatar; + } + static load(url, complete) { + Laya.ILaya.loader.create(url, complete, null, Avatar.AVATAR); + } + _initCloneToAnimator(destNode, destAnimator) { + destAnimator._avatarNodeMap[destNode.name] = destNode; + for (var i = 0, n = destNode.getChildCount(); i < n; i++) + this._initCloneToAnimator(destNode.getChildByIndex(i), destAnimator); + } + _parseNode(nodaData, node) { + var name = nodaData.props.name; + node.name = name; + var props = nodaData.props; + var transform = node.transform; + var pos = transform.localPosition; + var rot = transform.localRotation; + var sca = transform.localScale; + pos.fromArray(props.translate); + rot.fromArray(props.rotation); + sca.fromArray(props.scale); + transform.localPosition = pos; + transform.localRotation = rot; + transform.localScale = sca; + var childrenData = nodaData.child; + for (var j = 0, n = childrenData.length; j < n; j++) { + var childData = childrenData[j]; + var childBone = new AnimationNode(); + node.addChild(childBone); + this._parseNode(childData, childBone); + } + } + _cloneDatasToAnimator(destAnimator) { + var destRoot; + destRoot = this._rootNode.clone(); + var transform = this._rootNode.transform; + var destTransform = destRoot.transform; + var destPosition = destTransform.localPosition; + var destRotation = destTransform.localRotation; + var destScale = destTransform.localScale; + transform.localPosition.cloneTo(destPosition); + transform.localRotation.cloneTo(destRotation); + transform.localScale.cloneTo(destScale); + destTransform.localPosition = destPosition; + destTransform.localRotation = destRotation; + destTransform.localScale = destScale; + destAnimator._avatarNodeMap = {}; + this._initCloneToAnimator(destRoot, destAnimator); + } + cloneTo(destObject) { + var destAvatar = destObject; + var destRoot = this._rootNode.clone(); + destAvatar._rootNode = destRoot; + } + clone() { + var dest = new Avatar(); + this.cloneTo(dest); + return dest; + } + _cloneDatasToAnimatorNative(destAnimator) { + var animationNodeLocalPositions = new Float32Array(this._nativeNodeCount * 3); + var animationNodeLocalRotations = new Float32Array(this._nativeNodeCount * 4); + var animationNodeLocalScales = new Float32Array(this._nativeNodeCount * 3); + var animationNodeWorldMatrixs = new Float32Array(this._nativeNodeCount * 16); + var animationNodeParentIndices = new Int16Array(this._nativeNodeCount); + destAnimator._animationNodeLocalPositions = animationNodeLocalPositions; + destAnimator._animationNodeLocalRotations = animationNodeLocalRotations; + destAnimator._animationNodeLocalScales = animationNodeLocalScales; + destAnimator._animationNodeWorldMatrixs = animationNodeWorldMatrixs; + destAnimator._animationNodeParentIndices = animationNodeParentIndices; + this._nativeCurCloneCount = 0; + var destRoot = this._rootNode._cloneNative(animationNodeLocalPositions, animationNodeLocalRotations, animationNodeLocalScales, animationNodeWorldMatrixs, animationNodeParentIndices, -1, this); + var transform = this._rootNode.transform; + var destTransform = destRoot.transform; + var destPosition = destTransform.localPosition; + var destRotation = destTransform.localRotation; + var destScale = destTransform.localScale; + transform.localPosition.cloneTo(destPosition); + transform.localRotation.cloneTo(destRotation); + transform.localScale.cloneTo(destScale); + destTransform.localPosition = destPosition; + destTransform.localRotation = destRotation; + destTransform.localScale = destScale; + destAnimator._avatarNodeMap = {}; + this._initCloneToAnimator(destRoot, destAnimator); + } + } + Avatar.AVATAR = "AVATAR"; + + class Material extends Laya.Resource { + constructor() { + super(); + this._shaderValues = new ShaderData(this); + this.renderQueue = Material.RENDERQUEUE_OPAQUE; + this.alphaTest = false; + } + static load(url, complete) { + Laya.Laya.loader.create(url, complete, null, Material.MATERIAL); + } + static __initDefine__() { + Material.SHADERDEFINE_ALPHATEST = Shader3D.getDefineByName("ALPHATEST"); + } + static _parse(data, propertyParams = null, constructParams = null) { + var jsonData = data; + var props = jsonData.props; + var material; + var classType = props.type; + var clas = Laya.ClassUtils.getRegClass(classType); + if (clas) + material = new clas(); + else { + material = new Material(); + material.setShaderName(classType); + } + switch (jsonData.version) { + case "LAYAMATERIAL:01": + case "LAYAMATERIAL:02": + var i, n; + for (var key in props) { + switch (key) { + case "type": + break; + case "vectors": + var vectors = props[key]; + for (i = 0, n = vectors.length; i < n; i++) { + var vector = vectors[i]; + var vectorValue = vector.value; + switch (vectorValue.length) { + case 2: + material[vector.name] = new Vector2(vectorValue[0], vectorValue[1]); + break; + case 3: + material[vector.name] = new Vector3(vectorValue[0], vectorValue[1], vectorValue[2]); + break; + case 4: + material[vector.name] = new Vector4(vectorValue[0], vectorValue[1], vectorValue[2], vectorValue[3]); + break; + default: + throw new Error("BaseMaterial:unkonwn color length."); + } + } + break; + case "textures": + var textures = props[key]; + for (i = 0, n = textures.length; i < n; i++) { + var texture = textures[i]; + var path = texture.path; + (path) && (material[texture.name] = Laya.Loader.getRes(path)); + } + break; + case "defines": + var defineNames = props[key]; + for (i = 0, n = defineNames.length; i < n; i++) { + var define = Shader3D.getDefineByName(defineNames[i]); + material._shaderValues.addDefine(define); + } + break; + case "renderStates": + var renderStatesData = props[key]; + var renderStateData = renderStatesData[0]; + var mat = material; + mat.blend = renderStateData.blend; + mat.cull = renderStateData.cull; + mat.depthTest = renderStateData.depthTest; + mat.depthWrite = renderStateData.depthWrite; + mat.blendSrc = renderStateData.srcBlend; + mat.blendDst = renderStateData.dstBlend; + break; + case "cull": + material.cull = props[key]; + break; + case "blend": + material.blend = props[key]; + break; + case "depthWrite": + material.depthWrite = props[key]; + break; + case "srcBlend": + material.blendSrc = props[key]; + break; + case "dstBlend": + material.blendDst = props[key]; + break; + default: + material[key] = props[key]; + } + } + break; + case "LAYAMATERIAL:03": + var i, n; + for (var key in props) { + switch (key) { + case "type": + case "name": + break; + case "defines": + var defineNames = props[key]; + for (i = 0, n = defineNames.length; i < n; i++) { + var define = Shader3D.getDefineByName(defineNames[i]); + material._shaderValues.addDefine(define); + } + break; + case "textures": + var textures = props[key]; + for (i = 0, n = textures.length; i < n; i++) { + var texture = textures[i]; + var path = texture.path; + (path) && (material._shaderValues.setTexture(Shader3D.propertyNameToID(texture.name), Laya.Loader.getRes(path))); + } + break; + default: + var property = props[key]; + var uniName = Shader3D.propertyNameToID(key); + if (!property.length) { + material._shaderValues.setNumber(uniName, props[key]); + } + else { + var vectorValue = property; + switch (vectorValue.length) { + case 2: + material._shaderValues.setVector2(uniName, new Vector2(vectorValue[0], vectorValue[1])); + break; + case 3: + material._shaderValues.setVector3(uniName, new Vector3(vectorValue[0], vectorValue[1], vectorValue[2])); + break; + case 4: + material._shaderValues.setVector(uniName, new Vector4(vectorValue[0], vectorValue[1], vectorValue[2], vectorValue[3])); + break; + default: + throw new Error("BaseMaterial:unkonwn color length."); + } + } + } + } + break; + default: + throw new Error("BaseMaterial:unkonwn version."); + } + return material; + } + get shaderData() { + return this._shaderValues; + } + get alphaTestValue() { + return this._shaderValues.getNumber(Material.ALPHATESTVALUE); + } + set alphaTestValue(value) { + this._shaderValues.setNumber(Material.ALPHATESTVALUE, value); + } + get alphaTest() { + return this.shaderData.hasDefine(Material.SHADERDEFINE_ALPHATEST); + } + set alphaTest(value) { + if (value) + this._shaderValues.addDefine(Material.SHADERDEFINE_ALPHATEST); + else + this._shaderValues.removeDefine(Material.SHADERDEFINE_ALPHATEST); + } + get depthWrite() { + return this._shaderValues.getBool(Material.DEPTH_WRITE); + } + set depthWrite(value) { + this._shaderValues.setBool(Material.DEPTH_WRITE, value); + } + get cull() { + return this._shaderValues.getInt(Material.CULL); + } + set cull(value) { + this._shaderValues.setInt(Material.CULL, value); + } + get blend() { + return this._shaderValues.getInt(Material.BLEND); + } + set blend(value) { + this._shaderValues.setInt(Material.BLEND, value); + } + get blendSrc() { + return this._shaderValues.getInt(Material.BLEND_SRC); + } + set blendSrc(value) { + this._shaderValues.setInt(Material.BLEND_SRC, value); + } + get blendDst() { + return this._shaderValues.getInt(Material.BLEND_DST); + } + set blendDst(value) { + this._shaderValues.setInt(Material.BLEND_DST, value); + } + get depthTest() { + return this._shaderValues.getInt(Material.DEPTH_TEST); + } + set depthTest(value) { + this._shaderValues.setInt(Material.DEPTH_TEST, value); + } + get MaterialProperty() { + let propertyMap = {}; + var shaderValues = this._shaderValues.getData(); + for (let key in shaderValues) { + propertyMap[Shader3D._propertyNameMap[parseInt(key)]] = shaderValues[key]; + } + return propertyMap; + } + get MaterialDefine() { + let shaderDefineArray = new Array(); + let defineData = this._shaderValues._defineDatas; + Shader3D._getNamesByDefineData(defineData, shaderDefineArray); + return shaderDefineArray; + } + _removeTetxureReference() { + var data = this._shaderValues.getData(); + for (var k in data) { + var value = data[k]; + if (value && value instanceof Laya.BaseTexture) + value._removeReference(); + } + } + _disposeResource() { + if (this._referenceCount > 0) + this._removeTetxureReference(); + this._shaderValues = null; + } + _addReference(count = 1) { + super._addReference(count); + var data = this._shaderValues.getData(); + for (var k in data) { + var value = data[k]; + if (value && value instanceof Laya.BaseTexture) + value._addReference(); + } + } + _removeReference(count = 1) { + super._removeReference(count); + this._removeTetxureReference(); + } + setShaderName(name) { + this._shader = Shader3D.find(name); + if (!this._shader) + throw new Error("BaseMaterial: unknown shader name."); + } + setShaderPropertyValue(name, value) { + this.shaderData.setValueData(Shader3D.propertyNameToID(name), value); + } + getShaderPropertyValue(name) { + return this.shaderData.getValueData(Shader3D.propertyNameToID(name)); + } + cloneTo(destObject) { + var destBaseMaterial = destObject; + destBaseMaterial.name = this.name; + destBaseMaterial.renderQueue = this.renderQueue; + this._shaderValues.cloneTo(destBaseMaterial._shaderValues); + } + clone() { + var dest = new Material(); + this.cloneTo(dest); + return dest; + } + get _defineDatas() { + return this._shaderValues._defineDatas; + } + } + Material.MATERIAL = "MATERIAL"; + Material.RENDERQUEUE_OPAQUE = 2000; + Material.RENDERQUEUE_ALPHATEST = 2450; + Material.RENDERQUEUE_TRANSPARENT = 3000; + Material.ALPHATESTVALUE = Shader3D.propertyNameToID("u_AlphaTestValue"); + Material.CULL = Shader3D.propertyNameToID("s_Cull"); + Material.BLEND = Shader3D.propertyNameToID("s_Blend"); + Material.BLEND_SRC = Shader3D.propertyNameToID("s_BlendSrc"); + Material.BLEND_DST = Shader3D.propertyNameToID("s_BlendDst"); + Material.DEPTH_TEST = Shader3D.propertyNameToID("s_DepthTest"); + Material.DEPTH_WRITE = Shader3D.propertyNameToID("s_DepthWrite"); + + class BaseMaterial { + static load(url, complete) { + Laya.Laya.loader.create(url, complete, null, Material.MATERIAL); + } + static __initDefine__() { + BaseMaterial.SHADERDEFINE_ALPHATEST = Material.SHADERDEFINE_ALPHATEST; + } + } + BaseMaterial.MATERIAL = "MATERIAL"; + BaseMaterial.RENDERQUEUE_OPAQUE = 2000; + BaseMaterial.RENDERQUEUE_ALPHATEST = 2450; + BaseMaterial.RENDERQUEUE_TRANSPARENT = 3000; + BaseMaterial.ALPHATESTVALUE = Shader3D.propertyNameToID("u_AlphaTestValue"); + + class RenderState { + constructor() { + this.cull = RenderState.CULL_BACK; + this.blend = RenderState.BLEND_DISABLE; + this.srcBlend = RenderState.BLENDPARAM_ONE; + this.dstBlend = RenderState.BLENDPARAM_ZERO; + this.srcBlendRGB = RenderState.BLENDPARAM_ONE; + this.dstBlendRGB = RenderState.BLENDPARAM_ZERO; + this.srcBlendAlpha = RenderState.BLENDPARAM_ONE; + this.dstBlendAlpha = RenderState.BLENDPARAM_ZERO; + this.blendConstColor = new Vector4(1, 1, 1, 1); + this.blendEquation = RenderState.BLENDEQUATION_ADD; + this.blendEquationRGB = RenderState.BLENDEQUATION_ADD; + this.blendEquationAlpha = RenderState.BLENDEQUATION_ADD; + this.depthTest = RenderState.DEPTHTEST_LEQUAL; + this.depthWrite = true; + } + cloneTo(dest) { + var destState = dest; + destState.cull = this.cull; + destState.blend = this.blend; + destState.srcBlend = this.srcBlend; + destState.dstBlend = this.dstBlend; + destState.srcBlendRGB = this.srcBlendRGB; + destState.dstBlendRGB = this.dstBlendRGB; + destState.srcBlendAlpha = this.srcBlendAlpha; + destState.dstBlendAlpha = this.dstBlendAlpha; + this.blendConstColor.cloneTo(destState.blendConstColor); + destState.blendEquation = this.blendEquation; + destState.blendEquationRGB = this.blendEquationRGB; + destState.blendEquationAlpha = this.blendEquationAlpha; + destState.depthTest = this.depthTest; + destState.depthWrite = this.depthWrite; + } + clone() { + var dest = new RenderState(); + this.cloneTo(dest); + return dest; + } + } + RenderState.CULL_NONE = 0; + RenderState.CULL_FRONT = 1; + RenderState.CULL_BACK = 2; + RenderState.BLEND_DISABLE = 0; + RenderState.BLEND_ENABLE_ALL = 1; + RenderState.BLEND_ENABLE_SEPERATE = 2; + RenderState.BLENDPARAM_ZERO = 0; + RenderState.BLENDPARAM_ONE = 1; + RenderState.BLENDPARAM_SRC_COLOR = 0x0300; + RenderState.BLENDPARAM_ONE_MINUS_SRC_COLOR = 0x0301; + RenderState.BLENDPARAM_DST_COLOR = 0x0306; + RenderState.BLENDPARAM_ONE_MINUS_DST_COLOR = 0x0307; + RenderState.BLENDPARAM_SRC_ALPHA = 0x0302; + RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA = 0x0303; + RenderState.BLENDPARAM_DST_ALPHA = 0x0304; + RenderState.BLENDPARAM_ONE_MINUS_DST_ALPHA = 0x0305; + RenderState.BLENDPARAM_SRC_ALPHA_SATURATE = 0x0308; + RenderState.BLENDEQUATION_ADD = 0x8006; + RenderState.BLENDEQUATION_SUBTRACT = 0x800A; + RenderState.BLENDEQUATION_REVERSE_SUBTRACT = 0x800B; + RenderState.DEPTHTEST_OFF = 0; + RenderState.DEPTHTEST_NEVER = 0x0200; + RenderState.DEPTHTEST_LESS = 0x0201; + RenderState.DEPTHTEST_EQUAL = 0x0202; + RenderState.DEPTHTEST_LEQUAL = 0x0203; + RenderState.DEPTHTEST_GREATER = 0x0204; + RenderState.DEPTHTEST_NOTEQUAL = 0x0205; + RenderState.DEPTHTEST_GEQUAL = 0x0206; + RenderState.DEPTHTEST_ALWAYS = 0x0207; + + class BlinnPhongMaterial extends Material { + constructor() { + super(); + this.setShaderName("BLINNPHONG"); + this.albedoIntensity = 1.0; + var sv = this._shaderValues; + sv.setVector(BlinnPhongMaterial.ALBEDOCOLOR, new Vector4(1.0, 1.0, 1.0, 1.0)); + sv.setVector(BlinnPhongMaterial.MATERIALSPECULAR, new Vector4(1.0, 1.0, 1.0, 1.0)); + sv.setNumber(BlinnPhongMaterial.SHININESS, 0.078125); + sv.setNumber(Material.ALPHATESTVALUE, 0.5); + sv.setVector(BlinnPhongMaterial.TILINGOFFSET, new Vector4(1.0, 1.0, 0.0, 0.0)); + this.albedoIntensity = 1.0; + this.renderMode = BlinnPhongMaterial.RENDERMODE_OPAQUE; + } + static __initDefine__() { + BlinnPhongMaterial.SHADERDEFINE_DIFFUSEMAP = Shader3D.getDefineByName("DIFFUSEMAP"); + BlinnPhongMaterial.SHADERDEFINE_NORMALMAP = Shader3D.getDefineByName("NORMALMAP"); + BlinnPhongMaterial.SHADERDEFINE_SPECULARMAP = Shader3D.getDefineByName("SPECULARMAP"); + BlinnPhongMaterial.SHADERDEFINE_ENABLEVERTEXCOLOR = Shader3D.getDefineByName("ENABLEVERTEXCOLOR"); + BlinnPhongMaterial.SHADERDEFINE_ENABLETRANSMISSION = Shader3D.getDefineByName("ENABLETRANSMISSION"); + BlinnPhongMaterial.SHADERDEFINE_THICKNESSMAP = Shader3D.getDefineByName("THICKNESSMAP"); + } + get _ColorR() { + return this.albedoColor.x; + } + set _ColorR(value) { + let albedoColor = this.albedoColor; + albedoColor.x = value; + this.albedoColor = albedoColor; + } + get _ColorG() { + return this.albedoColor.y; + } + set _ColorG(value) { + let albedoColor = this.albedoColor; + albedoColor.y = value; + this.albedoColor = albedoColor; + } + get _ColorB() { + return this.albedoColor.z; + } + set _ColorB(value) { + let albedoColor = this.albedoColor; + albedoColor.z = value; + this.albedoColor = albedoColor; + } + get _ColorA() { + return this.albedoColor.w; + } + set _ColorA(value) { + let albedoColor = this.albedoColor; + albedoColor.w = value; + this.albedoColor = albedoColor; + } + get _Color() { + return this._shaderValues.getVector(BlinnPhongMaterial.ALBEDOCOLOR); + } + set _Color(value) { + this.albedoColor = value; + } + get _SpecColorR() { + return this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR).x; + } + set _SpecColorR(value) { + this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR).x = value; + } + get _SpecColorG() { + return this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR).y; + } + set _SpecColorG(value) { + this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR).y = value; + } + get _SpecColorB() { + return this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR).z; + } + set _SpecColorB(value) { + this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR).z = value; + } + get _SpecColorA() { + return this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR).w; + } + set _SpecColorA(value) { + this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR).w = value; + } + get _SpecColor() { + return this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR); + } + set _SpecColor(value) { + this.specularColor = value; + } + get _Shininess() { + return this._shaderValues.getNumber(BlinnPhongMaterial.SHININESS); + } + set _Shininess(value) { + value = Math.max(0.0, Math.min(1.0, value)); + this._shaderValues.setNumber(BlinnPhongMaterial.SHININESS, value); + } + get _MainTex_STX() { + return this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET).x; + } + set _MainTex_STX(x) { + var tilOff = this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET); + tilOff.x = x; + this.tilingOffset = tilOff; + } + get _MainTex_STY() { + return this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET).y; + } + set _MainTex_STY(y) { + var tilOff = this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET); + tilOff.y = y; + this.tilingOffset = tilOff; + } + get _MainTex_STZ() { + return this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET).z; + } + set _MainTex_STZ(z) { + var tilOff = this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET); + tilOff.z = z; + this.tilingOffset = tilOff; + } + get _MainTex_STW() { + return this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET).w; + } + set _MainTex_STW(w) { + var tilOff = this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET); + tilOff.w = w; + this.tilingOffset = tilOff; + } + get _MainTex_ST() { + return this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET); + } + set _MainTex_ST(value) { + this.tilingOffset = value; + } + get _Cutoff() { + return this.alphaTestValue; + } + set _Cutoff(value) { + this.alphaTestValue = value; + } + set renderMode(value) { + switch (value) { + case BlinnPhongMaterial.RENDERMODE_OPAQUE: + this.alphaTest = false; + this.renderQueue = Material.RENDERQUEUE_OPAQUE; + this.depthWrite = true; + this.cull = RenderState.CULL_BACK; + this.blend = RenderState.BLEND_DISABLE; + this.depthTest = RenderState.DEPTHTEST_LESS; + break; + case BlinnPhongMaterial.RENDERMODE_CUTOUT: + this.renderQueue = Material.RENDERQUEUE_ALPHATEST; + this.alphaTest = true; + this.depthWrite = true; + this.cull = RenderState.CULL_BACK; + this.blend = RenderState.BLEND_DISABLE; + this.depthTest = RenderState.DEPTHTEST_LESS; + break; + case BlinnPhongMaterial.RENDERMODE_TRANSPARENT: + this.renderQueue = Material.RENDERQUEUE_TRANSPARENT; + this.alphaTest = false; + this.depthWrite = false; + this.cull = RenderState.CULL_BACK; + this.blend = RenderState.BLEND_ENABLE_ALL; + this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA; + this.blendDst = RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA; + this.depthTest = RenderState.DEPTHTEST_LESS; + break; + default: + throw new Error("Material:renderMode value error."); + } + } + get enableVertexColor() { + return this._shaderValues.hasDefine(BlinnPhongMaterial.SHADERDEFINE_ENABLEVERTEXCOLOR); + } + set enableVertexColor(value) { + if (value) + this._shaderValues.addDefine(BlinnPhongMaterial.SHADERDEFINE_ENABLEVERTEXCOLOR); + else + this._shaderValues.removeDefine(BlinnPhongMaterial.SHADERDEFINE_ENABLEVERTEXCOLOR); + } + get tilingOffsetX() { + return this._MainTex_STX; + } + set tilingOffsetX(x) { + this._MainTex_STX = x; + } + get tilingOffsetY() { + return this._MainTex_STY; + } + set tilingOffsetY(y) { + this._MainTex_STY = y; + } + get tilingOffsetZ() { + return this._MainTex_STZ; + } + set tilingOffsetZ(z) { + this._MainTex_STZ = z; + } + get tilingOffsetW() { + return this._MainTex_STW; + } + set tilingOffsetW(w) { + this._MainTex_STW = w; + } + get tilingOffset() { + return this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET); + } + set tilingOffset(value) { + if (value) { + this._shaderValues.setVector(BlinnPhongMaterial.TILINGOFFSET, value); + } + else { + this._shaderValues.getVector(BlinnPhongMaterial.TILINGOFFSET).setValue(1.0, 1.0, 0.0, 0.0); + } + } + get albedoColorR() { + return this._ColorR; + } + set albedoColorR(value) { + this._ColorR = value; + } + get albedoColorG() { + return this._ColorG; + } + set albedoColorG(value) { + this._ColorG = value; + } + get albedoColorB() { + return this._ColorB; + } + set albedoColorB(value) { + this._ColorB = value; + } + get albedoColorA() { + return this._ColorA; + } + set albedoColorA(value) { + this._ColorA = value; + } + get albedoColor() { + return this._shaderValues.getVector(BlinnPhongMaterial.ALBEDOCOLOR); + } + set albedoColor(value) { + this._shaderValues.setVector(BlinnPhongMaterial.ALBEDOCOLOR, value); + } + get albedoIntensity() { + return this._shaderValues.getNumber(BlinnPhongMaterial.AlbedoIntensity); + } + set albedoIntensity(value) { + this._shaderValues.setNumber(BlinnPhongMaterial.AlbedoIntensity, value); + } + get specularColorR() { + return this._SpecColorR; + } + set specularColorR(value) { + this._SpecColorR = value; + } + get specularColorG() { + return this._SpecColorG; + } + set specularColorG(value) { + this._SpecColorG = value; + } + get specularColorB() { + return this._SpecColorB; + } + set specularColorB(value) { + this._SpecColorB = value; + } + get specularColorA() { + return this._SpecColorA; + } + set specularColorA(value) { + this._SpecColorA = value; + } + get specularColor() { + return this._shaderValues.getVector(BlinnPhongMaterial.MATERIALSPECULAR); + } + set specularColor(value) { + this._shaderValues.setVector(BlinnPhongMaterial.MATERIALSPECULAR, value); + } + get shininess() { + return this._Shininess; + } + set shininess(value) { + this._Shininess = value; + } + get albedoTexture() { + return this._shaderValues.getTexture(BlinnPhongMaterial.ALBEDOTEXTURE); + } + set albedoTexture(value) { + if (value) + this._shaderValues.addDefine(BlinnPhongMaterial.SHADERDEFINE_DIFFUSEMAP); + else + this._shaderValues.removeDefine(BlinnPhongMaterial.SHADERDEFINE_DIFFUSEMAP); + this._shaderValues.setTexture(BlinnPhongMaterial.ALBEDOTEXTURE, value); + } + get normalTexture() { + return this._shaderValues.getTexture(BlinnPhongMaterial.NORMALTEXTURE); + } + set normalTexture(value) { + if (value) + this._shaderValues.addDefine(BlinnPhongMaterial.SHADERDEFINE_NORMALMAP); + else + this._shaderValues.removeDefine(BlinnPhongMaterial.SHADERDEFINE_NORMALMAP); + this._shaderValues.setTexture(BlinnPhongMaterial.NORMALTEXTURE, value); + } + get specularTexture() { + return this._shaderValues.getTexture(BlinnPhongMaterial.SPECULARTEXTURE); + } + set specularTexture(value) { + if (value) + this._shaderValues.addDefine(BlinnPhongMaterial.SHADERDEFINE_SPECULARMAP); + else + this._shaderValues.removeDefine(BlinnPhongMaterial.SHADERDEFINE_SPECULARMAP); + this._shaderValues.setTexture(BlinnPhongMaterial.SPECULARTEXTURE, value); + } + get enableTransmission() { + return this._shaderValues.hasDefine(BlinnPhongMaterial.SHADERDEFINE_ENABLETRANSMISSION); + } + set enableTransmission(value) { + if (value) + this._shaderValues.addDefine(BlinnPhongMaterial.SHADERDEFINE_ENABLETRANSMISSION); + else + this._shaderValues.removeDefine(BlinnPhongMaterial.SHADERDEFINE_ENABLETRANSMISSION); + } + get transmissionRate() { + return this._shaderValues.getNumber(BlinnPhongMaterial.TRANSMISSIONRATE); + } + set transmissionRata(value) { + this._shaderValues.setNumber(BlinnPhongMaterial.TRANSMISSIONRATE, value); + } + get backDiffuse() { + return this._shaderValues.getNumber(BlinnPhongMaterial.IBACKDIFFUSE); + } + set backDiffuse(value) { + this._shaderValues.setNumber(BlinnPhongMaterial.IBACKDIFFUSE, Math.max(value, 1.0)); + } + get backScale() { + return this._shaderValues.getNumber(BlinnPhongMaterial.IBACKSCALE); + } + set backScale(value) { + this._shaderValues.setNumber(BlinnPhongMaterial.IBACKSCALE, value); + } + get thinknessTexture() { + return this._shaderValues.getTexture(BlinnPhongMaterial.THINKNESSTEXTURE); + } + set thinknessTexture(value) { + if (value) + this._shaderValues.addDefine(BlinnPhongMaterial.SHADERDEFINE_THICKNESSMAP); + else + this._shaderValues.removeDefine(BlinnPhongMaterial.SHADERDEFINE_THICKNESSMAP); + this._shaderValues.setTexture(BlinnPhongMaterial.THINKNESSTEXTURE, value); + } + get transmissionColor() { + return this._shaderValues.getVector(BlinnPhongMaterial.TRANSMISSIONCOLOR); + } + set transmissionColor(value) { + this._shaderValues.setVector(BlinnPhongMaterial.TRANSMISSIONCOLOR, value); + } + clone() { + var dest = new BlinnPhongMaterial(); + this.cloneTo(dest); + return dest; + } + cloneTo(destObject) { + super.cloneTo(destObject); + var destMaterial = destObject; + destMaterial.albedoIntensity = this.albedoIntensity; + destMaterial.enableVertexColor = this.enableVertexColor; + this.albedoColor.cloneTo(destMaterial.albedoColor); + } + } + BlinnPhongMaterial.RENDERMODE_OPAQUE = 0; + BlinnPhongMaterial.RENDERMODE_CUTOUT = 1; + BlinnPhongMaterial.RENDERMODE_TRANSPARENT = 2; + BlinnPhongMaterial.ALBEDOTEXTURE = Shader3D.propertyNameToID("u_DiffuseTexture"); + BlinnPhongMaterial.NORMALTEXTURE = Shader3D.propertyNameToID("u_NormalTexture"); + BlinnPhongMaterial.SPECULARTEXTURE = Shader3D.propertyNameToID("u_SpecularTexture"); + BlinnPhongMaterial.ALBEDOCOLOR = Shader3D.propertyNameToID("u_DiffuseColor"); + BlinnPhongMaterial.MATERIALSPECULAR = Shader3D.propertyNameToID("u_MaterialSpecular"); + BlinnPhongMaterial.SHININESS = Shader3D.propertyNameToID("u_Shininess"); + BlinnPhongMaterial.TILINGOFFSET = Shader3D.propertyNameToID("u_TilingOffset"); + BlinnPhongMaterial.TRANSMISSIONRATE = Shader3D.propertyNameToID("u_TransmissionRate"); + BlinnPhongMaterial.IBACKDIFFUSE = Shader3D.propertyNameToID("u_BackDiffuse"); + BlinnPhongMaterial.IBACKSCALE = Shader3D.propertyNameToID("u_BackScale"); + BlinnPhongMaterial.THINKNESSTEXTURE = Shader3D.propertyNameToID("u_ThinknessTexture"); + BlinnPhongMaterial.TRANSMISSIONCOLOR = Shader3D.propertyNameToID("u_TransmissionColor"); + BlinnPhongMaterial.AlbedoIntensity = Shader3D.propertyNameToID("u_AlbedoIntensity"); + + class EffectMaterial extends Material { + constructor() { + super(); + this.setShaderName("Effect"); + this._shaderValues.setVector(EffectMaterial.TILINGOFFSET, new Vector4(1.0, 1.0, 0.0, 0.0)); + this._shaderValues.setVector(EffectMaterial.TINTCOLOR, new Vector4(1.0, 1.0, 1.0, 1.0)); + this.renderMode = EffectMaterial.RENDERMODE_ADDTIVE; + } + static __initDefine__() { + EffectMaterial.SHADERDEFINE_MAINTEXTURE = Shader3D.getDefineByName("MAINTEXTURE"); + EffectMaterial.SHADERDEFINE_ADDTIVEFOG = Shader3D.getDefineByName("ADDTIVEFOG"); + } + get _TintColorR() { + return this.color.x; + } + set _TintColorR(value) { + let co = this.color; + co.x = value; + this.color = co; + } + get _TintColorG() { + return this.color.y; + } + set _TintColorG(value) { + let co = this.color; + co.y = value; + this.color = co; + } + get _TintColorB() { + return this.color.z; + } + set _TintColorB(value) { + let co = this.color; + co.z = value; + this.color = co; + } + get _TintColorA() { + return this.color.w; + } + set _TintColorA(value) { + let co = this.color; + co.w = value; + this.color = co; + } + get _TintColor() { + return this._shaderValues.getVector(EffectMaterial.TINTCOLOR); + } + set _TintColor(value) { + this.color = value; + } + get _MainTex_STX() { + return this._shaderValues.getVector(EffectMaterial.TILINGOFFSET).x; + } + set _MainTex_STX(x) { + var tilOff = this._shaderValues.getVector(EffectMaterial.TILINGOFFSET); + tilOff.x = x; + this.tilingOffset = tilOff; + } + get _MainTex_STY() { + return this._shaderValues.getVector(EffectMaterial.TILINGOFFSET).y; + } + set _MainTex_STY(y) { + var tilOff = this._shaderValues.getVector(EffectMaterial.TILINGOFFSET); + tilOff.y = y; + this.tilingOffset = tilOff; + } + get _MainTex_STZ() { + return this._shaderValues.getVector(EffectMaterial.TILINGOFFSET).z; + } + set _MainTex_STZ(z) { + var tilOff = this._shaderValues.getVector(EffectMaterial.TILINGOFFSET); + tilOff.z = z; + this.tilingOffset = tilOff; + } + get _MainTex_STW() { + return this._shaderValues.getVector(EffectMaterial.TILINGOFFSET).w; + } + set _MainTex_STW(w) { + var tilOff = this._shaderValues.getVector(EffectMaterial.TILINGOFFSET); + tilOff.w = w; + this.tilingOffset = tilOff; + } + get _MainTex_ST() { + return this._shaderValues.getVector(EffectMaterial.TILINGOFFSET); + } + set _MainTex_ST(value) { + this.tilingOffset = value; + } + set renderMode(value) { + switch (value) { + case EffectMaterial.RENDERMODE_ADDTIVE: + this.renderQueue = Material.RENDERQUEUE_TRANSPARENT; + this.alphaTest = false; + this.depthWrite = false; + this.cull = RenderState.CULL_NONE; + this.blend = RenderState.BLEND_ENABLE_ALL; + this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA; + this.blendDst = RenderState.BLENDPARAM_ONE; + this.depthTest = RenderState.DEPTHTEST_LESS; + this._shaderValues.addDefine(EffectMaterial.SHADERDEFINE_ADDTIVEFOG); + break; + case EffectMaterial.RENDERMODE_ALPHABLENDED: + this.renderQueue = Material.RENDERQUEUE_TRANSPARENT; + this.alphaTest = false; + this.depthWrite = false; + this.cull = RenderState.CULL_NONE; + this.blend = RenderState.BLEND_ENABLE_ALL; + this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA; + this.blendDst = RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA; + this.depthTest = RenderState.DEPTHTEST_LESS; + this._shaderValues.removeDefine(EffectMaterial.SHADERDEFINE_ADDTIVEFOG); + break; + default: + throw new Error("MeshEffectMaterial : renderMode value error."); + } + } + get colorR() { + return this._TintColorR; + } + set colorR(value) { + this._TintColorR = value; + } + get colorG() { + return this._TintColorG; + } + set colorG(value) { + this._TintColorG = value; + } + get colorB() { + return this._TintColorB; + } + set colorB(value) { + this._TintColorB = value; + } + get colorA() { + return this._TintColorA; + } + set colorA(value) { + this._TintColorA = value; + } + get color() { + return this._shaderValues.getVector(EffectMaterial.TINTCOLOR); + } + set color(value) { + this._shaderValues.setVector(EffectMaterial.TINTCOLOR, value); + } + get texture() { + return this._shaderValues.getTexture(EffectMaterial.MAINTEXTURE); + } + set texture(value) { + if (value) + this._shaderValues.addDefine(EffectMaterial.SHADERDEFINE_MAINTEXTURE); + else + this._shaderValues.removeDefine(EffectMaterial.SHADERDEFINE_MAINTEXTURE); + this._shaderValues.setTexture(EffectMaterial.MAINTEXTURE, value); + } + get tilingOffsetX() { + return this._MainTex_STX; + } + set tilingOffsetX(x) { + this._MainTex_STX = x; + } + get tilingOffsetY() { + return this._MainTex_STY; + } + set tilingOffsetY(y) { + this._MainTex_STY = y; + } + get tilingOffsetZ() { + return this._MainTex_STZ; + } + set tilingOffsetZ(z) { + this._MainTex_STZ = z; + } + get tilingOffsetW() { + return this._MainTex_STW; + } + set tilingOffsetW(w) { + this._MainTex_STW = w; + } + get tilingOffset() { + return this._shaderValues.getVector(EffectMaterial.TILINGOFFSET); + } + set tilingOffset(value) { + if (value) { + this._shaderValues.setVector(EffectMaterial.TILINGOFFSET, value); + } + else { + this._shaderValues.getVector(EffectMaterial.TILINGOFFSET).setValue(1.0, 1.0, 0.0, 0.0); + } + } + clone() { + var dest = new EffectMaterial(); + this.cloneTo(dest); + return dest; + } + } + EffectMaterial.RENDERMODE_ADDTIVE = 0; + EffectMaterial.RENDERMODE_ALPHABLENDED = 1; + EffectMaterial.MAINTEXTURE = Shader3D.propertyNameToID("u_AlbedoTexture"); + EffectMaterial.TINTCOLOR = Shader3D.propertyNameToID("u_AlbedoColor"); + EffectMaterial.TILINGOFFSET = Shader3D.propertyNameToID("u_TilingOffset"); + + class ExtendTerrainMaterial extends Material { + constructor() { + super(); + this.setShaderName("ExtendTerrain"); + this.renderMode = ExtendTerrainMaterial.RENDERMODE_OPAQUE; + } + static __initDefine__() { + ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM1 = Shader3D.getDefineByName("ExtendTerrain_DETAIL_NUM1"); + ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM2 = Shader3D.getDefineByName("ExtendTerrain_DETAIL_NUM2"); + ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM3 = Shader3D.getDefineByName("ExtendTerrain_DETAIL_NUM3"); + ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM4 = Shader3D.getDefineByName("ExtendTerrain_DETAIL_NUM4"); + ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM5 = Shader3D.getDefineByName("ExtendTerrain_DETAIL_NUM5"); + } + get splatAlphaTexture() { + return this._shaderValues.getTexture(ExtendTerrainMaterial.SPLATALPHATEXTURE); + } + set splatAlphaTexture(value) { + this._shaderValues.setTexture(ExtendTerrainMaterial.SPLATALPHATEXTURE, value); + } + get diffuseTexture1() { + return this._shaderValues.getTexture(ExtendTerrainMaterial.DIFFUSETEXTURE1); + } + set diffuseTexture1(value) { + this._shaderValues.setTexture(ExtendTerrainMaterial.DIFFUSETEXTURE1, value); + this._setDetailNum(1); + } + get diffuseTexture2() { + return this._shaderValues.getTexture(ExtendTerrainMaterial.DIFFUSETEXTURE2); + } + set diffuseTexture2(value) { + this._shaderValues.setTexture(ExtendTerrainMaterial.DIFFUSETEXTURE2, value); + this._setDetailNum(2); + } + get diffuseTexture3() { + return this._shaderValues.getTexture(ExtendTerrainMaterial.DIFFUSETEXTURE3); + } + set diffuseTexture3(value) { + this._shaderValues.setTexture(ExtendTerrainMaterial.DIFFUSETEXTURE3, value); + this._setDetailNum(3); + } + get diffuseTexture4() { + return this._shaderValues.getTexture(ExtendTerrainMaterial.DIFFUSETEXTURE4); + } + set diffuseTexture4(value) { + this._shaderValues.setTexture(ExtendTerrainMaterial.DIFFUSETEXTURE4, value); + this._setDetailNum(4); + } + get diffuseTexture5() { + return this._shaderValues.getTexture(ExtendTerrainMaterial.DIFFUSETEXTURE5); + } + set diffuseTexture5(value) { + this._shaderValues.setTexture(ExtendTerrainMaterial.DIFFUSETEXTURE5, value); + this._setDetailNum(5); + } + set diffuseScaleOffset1(scaleOffset1) { + this._shaderValues.setVector(ExtendTerrainMaterial.DIFFUSESCALEOFFSET1, scaleOffset1); + } + set diffuseScaleOffset2(scaleOffset2) { + this._shaderValues.setVector(ExtendTerrainMaterial.DIFFUSESCALEOFFSET2, scaleOffset2); + } + set diffuseScaleOffset3(scaleOffset3) { + this._shaderValues.setVector(ExtendTerrainMaterial.DIFFUSESCALEOFFSET3, scaleOffset3); + } + set diffuseScaleOffset4(scaleOffset4) { + this._shaderValues.setVector(ExtendTerrainMaterial.DIFFUSESCALEOFFSET4, scaleOffset4); + } + set diffuseScaleOffset5(scaleOffset5) { + this._shaderValues.setVector(ExtendTerrainMaterial.DIFFUSESCALEOFFSET5, scaleOffset5); + } + set renderMode(value) { + switch (value) { + case ExtendTerrainMaterial.RENDERMODE_OPAQUE: + this.renderQueue = Material.RENDERQUEUE_OPAQUE; + this.depthWrite = true; + this.cull = RenderState.CULL_BACK; + this.blend = RenderState.BLEND_DISABLE; + this.depthTest = RenderState.DEPTHTEST_LESS; + break; + case ExtendTerrainMaterial.RENDERMODE_TRANSPARENT: + this.renderQueue = Material.RENDERQUEUE_OPAQUE; + this.depthWrite = false; + this.cull = RenderState.CULL_BACK; + this.blend = RenderState.BLEND_ENABLE_ALL; + this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA; + this.blendDst = RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA; + this.depthTest = RenderState.DEPTHTEST_LEQUAL; + break; + default: + throw new Error("ExtendTerrainMaterial:renderMode value error."); + } + } + _setDetailNum(value) { + switch (value) { + case 1: + this._shaderValues.addDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM1); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM2); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM3); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM4); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM5); + break; + case 2: + this._shaderValues.addDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM2); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM1); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM3); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM4); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM5); + break; + case 3: + this._shaderValues.addDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM3); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM1); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM2); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM4); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM5); + break; + case 4: + this._shaderValues.addDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM4); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM1); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM2); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM3); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM5); + break; + case 5: + this._shaderValues.addDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM5); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM1); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM2); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM3); + this._shaderValues.removeDefine(ExtendTerrainMaterial.SHADERDEFINE_DETAIL_NUM4); + break; + } + } + clone() { + var dest = new ExtendTerrainMaterial(); + this.cloneTo(dest); + return dest; + } + } + ExtendTerrainMaterial.RENDERMODE_OPAQUE = 1; + ExtendTerrainMaterial.RENDERMODE_TRANSPARENT = 2; + ExtendTerrainMaterial.SPLATALPHATEXTURE = Shader3D.propertyNameToID("u_SplatAlphaTexture"); + ExtendTerrainMaterial.DIFFUSETEXTURE1 = Shader3D.propertyNameToID("u_DiffuseTexture1"); + ExtendTerrainMaterial.DIFFUSETEXTURE2 = Shader3D.propertyNameToID("u_DiffuseTexture2"); + ExtendTerrainMaterial.DIFFUSETEXTURE3 = Shader3D.propertyNameToID("u_DiffuseTexture3"); + ExtendTerrainMaterial.DIFFUSETEXTURE4 = Shader3D.propertyNameToID("u_DiffuseTexture4"); + ExtendTerrainMaterial.DIFFUSETEXTURE5 = Shader3D.propertyNameToID("u_DiffuseTexture5"); + ExtendTerrainMaterial.DIFFUSESCALEOFFSET1 = Shader3D.propertyNameToID("u_DiffuseScaleOffset1"); + ExtendTerrainMaterial.DIFFUSESCALEOFFSET2 = Shader3D.propertyNameToID("u_DiffuseScaleOffset2"); + ExtendTerrainMaterial.DIFFUSESCALEOFFSET3 = Shader3D.propertyNameToID("u_DiffuseScaleOffset3"); + ExtendTerrainMaterial.DIFFUSESCALEOFFSET4 = Shader3D.propertyNameToID("u_DiffuseScaleOffset4"); + ExtendTerrainMaterial.DIFFUSESCALEOFFSET5 = Shader3D.propertyNameToID("u_DiffuseScaleOffset5"); + + (function (PBRRenderMode) { + PBRRenderMode[PBRRenderMode["Opaque"] = 0] = "Opaque"; + PBRRenderMode[PBRRenderMode["Cutout"] = 1] = "Cutout"; + PBRRenderMode[PBRRenderMode["Fade"] = 2] = "Fade"; + PBRRenderMode[PBRRenderMode["Transparent"] = 3] = "Transparent"; + })(exports.PBRRenderMode || (exports.PBRRenderMode = {})); + class PBRMaterial extends Material { + constructor() { + super(); + this._shaderValues.setVector(PBRMaterial.ALBEDOCOLOR, new Vector4(1.0, 1.0, 1.0, 1.0)); + this._shaderValues.setVector(PBRMaterial.EMISSIONCOLOR, new Vector4(1.0, 1.0, 1.0, 1.0)); + this._shaderValues.setVector(PBRMaterial.TILINGOFFSET, new Vector4(1.0, 1.0, 0.0, 0.0)); + this._shaderValues.setNumber(PBRMaterial.SMOOTHNESS, 0.5); + this._shaderValues.setNumber(PBRMaterial.SMOOTHNESSSCALE, 1.0); + this._shaderValues.setNumber(PBRMaterial.OCCLUSIONSTRENGTH, 1.0); + this._shaderValues.setNumber(PBRMaterial.NORMALSCALE, 1.0); + this._shaderValues.setNumber(PBRMaterial.PARALLAXSCALE, 0.001); + this._shaderValues.setNumber(Material.ALPHATESTVALUE, 0.5); + this.renderMode = exports.PBRRenderMode.Opaque; + } + static __init__() { + PBRMaterial.SHADERDEFINE_ALBEDOTEXTURE = Shader3D.getDefineByName("ALBEDOTEXTURE"); + PBRMaterial.SHADERDEFINE_NORMALTEXTURE = Shader3D.getDefineByName("NORMALTEXTURE"); + PBRMaterial.SHADERDEFINE_PARALLAXTEXTURE = Shader3D.getDefineByName("PARALLAXTEXTURE"); + PBRMaterial.SHADERDEFINE_OCCLUSIONTEXTURE = Shader3D.getDefineByName("OCCLUSIONTEXTURE"); + PBRMaterial.SHADERDEFINE_EMISSION = Shader3D.getDefineByName("EMISSION"); + PBRMaterial.SHADERDEFINE_EMISSIONTEXTURE = Shader3D.getDefineByName("EMISSIONTEXTURE"); + PBRMaterial.SHADERDEFINE_TRANSPARENTBLEND = Shader3D.getDefineByName("TRANSPARENTBLEND"); + PBRMaterial.SHADERDEFINE_LAYA_PBR_BRDF_HIGH = Shader3D.getDefineByName("LAYA_PBR_BRDF_HIGH"); + PBRMaterial.SHADERDEFINE_LAYA_PBR_BRDF_LOW = Shader3D.getDefineByName("LAYA_PBR_BRDF_LOW"); + } + get albedoColor() { + return this._shaderValues.getVector(PBRMaterial.ALBEDOCOLOR); + } + set albedoColor(value) { + this._shaderValues.setVector(PBRMaterial.ALBEDOCOLOR, value); + } + get albedoTexture() { + return this._shaderValues.getTexture(PBRMaterial.ALBEDOTEXTURE); + } + set albedoTexture(value) { + if (value) + this._shaderValues.addDefine(PBRMaterial.SHADERDEFINE_ALBEDOTEXTURE); + else + this._shaderValues.removeDefine(PBRMaterial.SHADERDEFINE_ALBEDOTEXTURE); + this._shaderValues.setTexture(PBRMaterial.ALBEDOTEXTURE, value); + } + get normalTexture() { + return this._shaderValues.getTexture(PBRMaterial.NORMALTEXTURE); + } + set normalTexture(value) { + if (value) { + this._shaderValues.addDefine(PBRMaterial.SHADERDEFINE_NORMALTEXTURE); + } + else { + this._shaderValues.removeDefine(PBRMaterial.SHADERDEFINE_NORMALTEXTURE); + } + this._shaderValues.setTexture(PBRMaterial.NORMALTEXTURE, value); + } + get normalTextureScale() { + return this._shaderValues.getNumber(PBRMaterial.NORMALSCALE); + } + set normalTextureScale(value) { + this._shaderValues.setNumber(PBRMaterial.NORMALSCALE, value); + } + get parallaxTexture() { + return this._shaderValues.getTexture(PBRMaterial.PARALLAXTEXTURE); + } + set parallaxTexture(value) { + if (value) + this._shaderValues.addDefine(PBRMaterial.SHADERDEFINE_PARALLAXTEXTURE); + else + this._shaderValues.removeDefine(PBRMaterial.SHADERDEFINE_PARALLAXTEXTURE); + this._shaderValues.setTexture(PBRMaterial.PARALLAXTEXTURE, value); + } + get parallaxTextureScale() { + return this._shaderValues.getNumber(PBRMaterial.PARALLAXSCALE); + } + set parallaxTextureScale(value) { + this._shaderValues.setNumber(PBRMaterial.PARALLAXSCALE, Math.max(0.005, Math.min(0.08, value))); + } + get occlusionTexture() { + return this._shaderValues.getTexture(PBRMaterial.OCCLUSIONTEXTURE); + } + set occlusionTexture(value) { + if (value) + this._shaderValues.addDefine(PBRMaterial.SHADERDEFINE_OCCLUSIONTEXTURE); + else + this._shaderValues.removeDefine(PBRMaterial.SHADERDEFINE_OCCLUSIONTEXTURE); + this._shaderValues.setTexture(PBRMaterial.OCCLUSIONTEXTURE, value); + } + get occlusionTextureStrength() { + return this._shaderValues.getNumber(PBRMaterial.OCCLUSIONSTRENGTH); + } + set occlusionTextureStrength(value) { + this._shaderValues.setNumber(PBRMaterial.OCCLUSIONSTRENGTH, Math.max(0.0, Math.min(1.0, value))); + } + get smoothness() { + return this._shaderValues.getNumber(PBRMaterial.SMOOTHNESS); + } + set smoothness(value) { + this._shaderValues.setNumber(PBRMaterial.SMOOTHNESS, Math.max(0.0, Math.min(1.0, value))); + } + get smoothnessTextureScale() { + return this._shaderValues.getNumber(PBRMaterial.SMOOTHNESSSCALE); + } + set smoothnessTextureScale(value) { + this._shaderValues.setNumber(PBRMaterial.SMOOTHNESSSCALE, Math.max(0.0, Math.min(1.0, value))); + } + get enableEmission() { + return this._shaderValues.hasDefine(PBRMaterial.SHADERDEFINE_EMISSION); + } + set enableEmission(value) { + if (value) + this._shaderValues.addDefine(PBRMaterial.SHADERDEFINE_EMISSION); + else + this._shaderValues.removeDefine(PBRMaterial.SHADERDEFINE_EMISSION); + } + get emissionColor() { + return this._shaderValues.getVector(PBRMaterial.EMISSIONCOLOR); + } + set emissionColor(value) { + this._shaderValues.setVector(PBRMaterial.EMISSIONCOLOR, value); + } + get emissionTexture() { + return this._shaderValues.getTexture(PBRMaterial.EMISSIONTEXTURE); + } + set emissionTexture(value) { + if (value) + this._shaderValues.addDefine(PBRMaterial.SHADERDEFINE_EMISSIONTEXTURE); + else + this._shaderValues.removeDefine(PBRMaterial.SHADERDEFINE_EMISSIONTEXTURE); + this._shaderValues.setTexture(PBRMaterial.EMISSIONTEXTURE, value); + } + get tilingOffset() { + return this._shaderValues.getVector(PBRMaterial.TILINGOFFSET); + } + set tilingOffset(value) { + if (value) { + this._shaderValues.setVector(PBRMaterial.TILINGOFFSET, value); + } + else { + this._shaderValues.getVector(PBRMaterial.TILINGOFFSET).setValue(1.0, 1.0, 0.0, 0.0); + } + } + set renderMode(value) { + switch (value) { + case exports.PBRRenderMode.Opaque: + this.alphaTest = false; + this.renderQueue = Material.RENDERQUEUE_OPAQUE; + this.depthWrite = true; + this.cull = RenderState.CULL_BACK; + this.blend = RenderState.BLEND_DISABLE; + this.depthTest = RenderState.DEPTHTEST_LESS; + this._shaderValues.removeDefine(PBRMaterial.SHADERDEFINE_TRANSPARENTBLEND); + break; + case exports.PBRRenderMode.Cutout: + this.renderQueue = Material.RENDERQUEUE_ALPHATEST; + this.alphaTest = true; + this.depthWrite = true; + this.cull = RenderState.CULL_BACK; + this.blend = RenderState.BLEND_DISABLE; + this.depthTest = RenderState.DEPTHTEST_LESS; + this._shaderValues.removeDefine(PBRMaterial.SHADERDEFINE_TRANSPARENTBLEND); + break; + case exports.PBRRenderMode.Fade: + this.renderQueue = Material.RENDERQUEUE_TRANSPARENT; + this.alphaTest = false; + this.depthWrite = false; + this.cull = RenderState.CULL_BACK; + this.blend = RenderState.BLEND_ENABLE_ALL; + this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA; + this.blendDst = RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA; + this.depthTest = RenderState.DEPTHTEST_LESS; + this._shaderValues.removeDefine(PBRMaterial.SHADERDEFINE_TRANSPARENTBLEND); + break; + case exports.PBRRenderMode.Transparent: + this.renderQueue = Material.RENDERQUEUE_TRANSPARENT; + this.alphaTest = false; + this.depthWrite = false; + this.cull = RenderState.CULL_BACK; + this.blend = RenderState.BLEND_ENABLE_ALL; + this.blendSrc = RenderState.BLENDPARAM_ONE; + this.blendDst = RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA; + this.depthTest = RenderState.DEPTHTEST_LESS; + this._shaderValues.addDefine(PBRMaterial.SHADERDEFINE_TRANSPARENTBLEND); + break; + default: + throw new Error("PBRMaterial:unknown renderMode value."); + } + } + } + PBRMaterial.ALBEDOTEXTURE = Shader3D.propertyNameToID("u_AlbedoTexture"); + PBRMaterial.ALBEDOCOLOR = Shader3D.propertyNameToID("u_AlbedoColor"); + PBRMaterial.TILINGOFFSET = Shader3D.propertyNameToID("u_TilingOffset"); + PBRMaterial.NORMALTEXTURE = Shader3D.propertyNameToID("u_NormalTexture"); + PBRMaterial.NORMALSCALE = Shader3D.propertyNameToID("u_NormalScale"); + PBRMaterial.SMOOTHNESS = Shader3D.propertyNameToID("u_Smoothness"); + PBRMaterial.SMOOTHNESSSCALE = Shader3D.propertyNameToID("u_SmoothnessScale"); + PBRMaterial.OCCLUSIONTEXTURE = Shader3D.propertyNameToID("u_OcclusionTexture"); + PBRMaterial.OCCLUSIONSTRENGTH = Shader3D.propertyNameToID("u_occlusionStrength"); + PBRMaterial.PARALLAXTEXTURE = Shader3D.propertyNameToID("u_ParallaxTexture"); + PBRMaterial.PARALLAXSCALE = Shader3D.propertyNameToID("u_ParallaxScale"); + PBRMaterial.EMISSIONTEXTURE = Shader3D.propertyNameToID("u_EmissionTexture"); + PBRMaterial.EMISSIONCOLOR = Shader3D.propertyNameToID("u_EmissionColor"); + PBRMaterial.renderQuality = exports.PBRRenderQuality.High; + + var PBRPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n\r\n#define SETUP_BRDF_INPUT specularSetup\r\n\r\n#include \"Lighting.glsl\";\r\n#include \"PBRFSInput.glsl\";\r\n#include \"LayaPBRBRDF.glsl\";\r\n#include \"GlobalIllumination.glsl\";\r\n#include \"Shadow.glsl\"\r\n#include \"PBRCore.glsl\";\r\n\r\nvoid main()\r\n{\r\n\tfragmentForward();\r\n}"; + + var PBRVS = "#include \"PBRVSInput.glsl\";\r\n#include \"Lighting.glsl\";\r\n#include \"PBRVertex.glsl\";\r\n\r\nvoid main()\r\n{\r\n\tvertexForward();\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}"; + + var PBRShadowCasterPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n\r\n#include \"ShadowCasterFS.glsl\"\r\n\r\nvoid main()\r\n{\r\n\tgl_FragColor=shadowCasterFragment();\r\n}"; + + var PBRShadowCasterVS = "#include \"ShadowCasterVS.glsl\"\r\n\r\nvoid main()\r\n{\r\n\tvec4 positionCS = shadowCasterVertex();\r\n\tgl_Position=remapGLPositionZ(positionCS);\r\n}"; + + var DepthNormalsTextureVS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n\r\n#include \"Lighting.glsl\";\r\n#include \"LayaUtile.glsl\"\r\n\r\nattribute vec4 a_Position;\r\nattribute vec3 a_Normal;\r\n\r\n#ifdef BONE\r\n\tconst int c_MaxBoneCount = 24;\r\n\tattribute vec4 a_BoneIndices;\r\n\tattribute vec4 a_BoneWeights;\r\n\tuniform mat4 u_Bones[c_MaxBoneCount];\r\n#endif\r\n\r\n#ifdef GPU_INSTANCE\r\n\tattribute mat4 a_WorldMat;\r\n#else\r\n\tuniform mat4 u_WorldMat;\r\n#endif\r\nuniform mat4 u_View;\r\nuniform mat4 u_ViewProjection;\r\nuniform vec4 u_ProjectionParams;\r\n\r\n//传入法线\r\nvarying vec4 depthNormals;\r\n\r\n\r\nvec4 depthNormalsVertex()\r\n{\r\n\tmat4 worldMat;\r\n\t#ifdef GPU_INSTANCE\r\n\t\tworldMat = a_WorldMat;\r\n\t#else\r\n\t\tworldMat = u_WorldMat;\r\n\t#endif\r\n\t\r\n\t#ifdef BONE\r\n\t\tmat4 skinTransform;\r\n\t \t#ifdef SIMPLEBONE\r\n\t\t\tfloat currentPixelPos;\r\n\t\t\t#ifdef GPU_INSTANCE\r\n\t\t\t\tcurrentPixelPos = a_SimpleTextureParams.x+a_SimpleTextureParams.y;\r\n\t\t\t#else\r\n\t\t\t\tcurrentPixelPos = u_SimpleAnimatorParams.x+u_SimpleAnimatorParams.y;\r\n\t\t\t#endif\r\n\t\t\tfloat offset = 1.0/u_SimpleAnimatorTextureSize;\r\n\t\t\tskinTransform = loadMatFromTexture(currentPixelPos,int(a_BoneIndices.x),offset) * a_BoneWeights.x;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.y),offset) * a_BoneWeights.y;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.z),offset) * a_BoneWeights.z;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.w),offset) * a_BoneWeights.w;\r\n\t\t#else\r\n\t\t\tskinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;\r\n\t\t#endif\r\n\t\tworldMat = worldMat * skinTransform;\r\n\t#endif\r\n\r\n\tvec4 positionWS = worldMat * a_Position;\r\n\r\n\tmat3 worldInvMat;\r\n\t#ifdef BONE\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat*skinTransform));\r\n\t#else\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat));\r\n\t#endif \r\n\r\n\tvec3 normalWS = normalize(a_Normal*worldInvMat);//if no normalize will cause precision problem\r\n\t//depthNormals.xyz = normalWS;\r\n\t//存储View空间法线\r\n\tvec3 normalVS = mat3(u_View) * normalWS;\r\n\tdepthNormals.xyz = normalVS;\r\n\t\r\n\tvec4 positionCS = u_ViewProjection * positionWS;\r\n\tdepthNormals.w = (positionCS.z * 2.0 - positionCS.w)*u_ProjectionParams.w;\r\n\t\r\n return positionCS;\r\n}\r\n\r\nvoid main()\r\n{\r\n\tvec4 positionCS = depthNormalsVertex();\r\n\tgl_Position=remapGLPositionZ(positionCS);\r\n}"; + + var DepthNormalsTextureFS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n#include \"DepthNormalUtil.glsl\";\r\n\r\nvarying vec4 depthNormals;\r\n\r\nvoid main()\r\n{\r\n\tgl_FragColor=depthNormalsFragment(depthNormals);\r\n}"; + + class ShaderVariable { + constructor() { + this.textureID = -1; + } + } + + class ShaderInstance extends Laya.Resource { + constructor(vs, ps, attributeMap, uniformMap, shaderPass) { + super(); + this._stateParamsMap = []; + this._uploadMark = -1; + this._uploadRenderType = -1; + this._vs = vs; + this._ps = ps; + this._attributeMap = attributeMap; + this._uniformMap = uniformMap; + this._shaderPass = shaderPass; + this._globaluniformMap = {}; + this._create(); + this.lock = true; + } + _create() { + var gl = Laya.LayaGL.instance; + this._program = gl.createProgram(); + this._vshader = this._createShader(gl, this._vs, gl.VERTEX_SHADER); + this._pshader = this._createShader(gl, this._ps, gl.FRAGMENT_SHADER); + gl.attachShader(this._program, this._vshader); + gl.attachShader(this._program, this._pshader); + for (var k in this._attributeMap) + gl.bindAttribLocation(this._program, this._attributeMap[k], k); + gl.linkProgram(this._program); + if (!Laya.Render.isConchApp && Shader3D.debugMode && !gl.getProgramParameter(this._program, gl.LINK_STATUS)) + throw gl.getProgramInfoLog(this._program); + var sceneParms = []; + var cameraParms = []; + var spriteParms = []; + var materialParms = []; + var customParms = []; + this._customUniformParamsMap = []; + var nUniformNum = gl.getProgramParameter(this._program, gl.ACTIVE_UNIFORMS); + Laya.WebGLContext.useProgram(gl, this._program); + this._curActTexIndex = 0; + var one, i, n; + for (i = 0; i < nUniformNum; i++) { + var uniformData = gl.getActiveUniform(this._program, i); + var uniName = uniformData.name; + one = new ShaderVariable(); + one.location = gl.getUniformLocation(this._program, uniName); + if (uniName.indexOf('[0]') > 0) { + one.name = uniName = uniName.substr(0, uniName.length - 3); + one.isArray = true; + } + else { + one.name = uniName; + one.isArray = false; + } + one.type = uniformData.type; + this._addShaderUnifiormFun(one); + var uniformPeriod = this._uniformMap[uniName]; + if (uniformPeriod != null) { + one.dataOffset = Shader3D.propertyNameToID(uniName); + switch (uniformPeriod) { + case Shader3D.PERIOD_CUSTOM: + customParms.push(one); + break; + case Shader3D.PERIOD_MATERIAL: + materialParms.push(one); + break; + case Shader3D.PERIOD_SPRITE: + spriteParms.push(one); + break; + case Shader3D.PERIOD_CAMERA: + cameraParms.push(one); + break; + case Shader3D.PERIOD_SCENE: + sceneParms.push(one); + break; + default: + throw new Error("Shader3D: period is unkonw."); + } + } + else { + one.dataOffset = Shader3D.propertyNameToID(uniName); + this._globaluniformMap[uniName] = Shader3D.PERIOD_SCENE; + sceneParms.push(one); + } + } + this._sceneUniformParamsMap = Laya.LayaGL.instance.createCommandEncoder(sceneParms.length * 4 * 5 + 4, 64, true); + for (i = 0, n = sceneParms.length; i < n; i++) + this._sceneUniformParamsMap.addShaderUniform(sceneParms[i]); + this._cameraUniformParamsMap = Laya.LayaGL.instance.createCommandEncoder(cameraParms.length * 4 * 5 + 4, 64, true); + for (i = 0, n = cameraParms.length; i < n; i++) + this._cameraUniformParamsMap.addShaderUniform(cameraParms[i]); + this._spriteUniformParamsMap = Laya.LayaGL.instance.createCommandEncoder(spriteParms.length * 4 * 5 + 4, 64, true); + for (i = 0, n = spriteParms.length; i < n; i++) + this._spriteUniformParamsMap.addShaderUniform(spriteParms[i]); + this._materialUniformParamsMap = Laya.LayaGL.instance.createCommandEncoder(materialParms.length * 4 * 5 + 4, 64, true); + for (i = 0, n = materialParms.length; i < n; i++) + this._materialUniformParamsMap.addShaderUniform(materialParms[i]); + this._customUniformParamsMap.length = customParms.length; + for (i = 0, n = customParms.length; i < n; i++) { + var custom = customParms[i]; + this._customUniformParamsMap[custom.dataOffset] = custom; + } + var stateMap = this._shaderPass._stateMap; + for (var s in stateMap) + this._stateParamsMap[stateMap[s]] = Shader3D.propertyNameToID(s); + } + _getRenderState(shaderDatas, stateIndex) { + var stateID = this._stateParamsMap[stateIndex]; + if (stateID == null) + return null; + else + return shaderDatas[stateID]; + } + _disposeResource() { + Laya.LayaGL.instance.deleteShader(this._vshader); + Laya.LayaGL.instance.deleteShader(this._pshader); + Laya.LayaGL.instance.deleteProgram(this._program); + this._vshader = this._pshader = this._program = null; + this._setGPUMemory(0); + this._curActTexIndex = 0; + } + _addShaderUnifiormFun(one) { + var gl = Laya.LayaGL.instance; + one.caller = this; + var isArray = one.isArray; + switch (one.type) { + case gl.BOOL: + one.fun = this._uniform1i; + one.uploadedValue = new Array(1); + break; + case gl.INT: + one.fun = isArray ? this._uniform1iv : this._uniform1i; + one.uploadedValue = new Array(1); + break; + case gl.FLOAT: + one.fun = isArray ? this._uniform1fv : this._uniform1f; + one.uploadedValue = new Array(1); + break; + case gl.FLOAT_VEC2: + one.fun = isArray ? this._uniform_vec2v : this._uniform_vec2; + one.uploadedValue = new Array(2); + break; + case gl.FLOAT_VEC3: + one.fun = isArray ? this._uniform_vec3v : this._uniform_vec3; + one.uploadedValue = new Array(3); + break; + case gl.FLOAT_VEC4: + one.fun = isArray ? this._uniform_vec4v : this._uniform_vec4; + one.uploadedValue = new Array(4); + break; + case gl.FLOAT_MAT2: + one.fun = this._uniformMatrix2fv; + break; + case gl.FLOAT_MAT3: + one.fun = this._uniformMatrix3fv; + break; + case gl.FLOAT_MAT4: + one.fun = isArray ? this._uniformMatrix4fv : this._uniformMatrix4f; + break; + case gl.SAMPLER_2D: + case gl.SAMPLER_2D_SHADOW: + gl.uniform1i(one.location, this._curActTexIndex); + one.textureID = Laya.WebGLContext._glTextureIDs[this._curActTexIndex++]; + one.fun = this._uniform_sampler2D; + break; + case 0x8b5f: + gl.uniform1i(one.location, this._curActTexIndex); + one.textureID = Laya.WebGLContext._glTextureIDs[this._curActTexIndex++]; + one.fun = this._uniform_sampler3D; + break; + case gl.SAMPLER_CUBE: + gl.uniform1i(one.location, this._curActTexIndex); + one.textureID = Laya.WebGLContext._glTextureIDs[this._curActTexIndex++]; + one.fun = this._uniform_samplerCube; + break; + default: + throw new Error("compile shader err!"); + } + } + _createShader(gl, str, type) { + var shader = gl.createShader(type); + gl.shaderSource(shader, str); + gl.compileShader(shader); + if (Shader3D.debugMode && !gl.getShaderParameter(shader, gl.COMPILE_STATUS)) + throw gl.getShaderInfoLog(shader); + return shader; + } + _uniform1f(one, value) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== value) { + Laya.LayaGL.instance.uniform1f(one.location, uploadedValue[0] = value); + return 1; + } + return 0; + } + _uniform1fv(one, value) { + if (value.length < 4) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2] || uploadedValue[3] !== value[3]) { + Laya.LayaGL.instance.uniform1fv(one.location, value); + uploadedValue[0] = value[0]; + uploadedValue[1] = value[1]; + uploadedValue[2] = value[2]; + uploadedValue[3] = value[3]; + return 1; + } + return 0; + } + else { + Laya.LayaGL.instance.uniform1fv(one.location, value); + return 1; + } + } + _uniform_vec2(one, v) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== v.x || uploadedValue[1] !== v.y) { + Laya.LayaGL.instance.uniform2f(one.location, uploadedValue[0] = v.x, uploadedValue[1] = v.y); + return 1; + } + return 0; + } + _uniform_vec2v(one, value) { + if (value.length < 2) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2] || uploadedValue[3] !== value[3]) { + Laya.LayaGL.instance.uniform2fv(one.location, value); + uploadedValue[0] = value[0]; + uploadedValue[1] = value[1]; + uploadedValue[2] = value[2]; + uploadedValue[3] = value[3]; + return 1; + } + return 0; + } + else { + Laya.LayaGL.instance.uniform2fv(one.location, value); + return 1; + } + } + _uniform_vec3(one, v) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== v.x || uploadedValue[1] !== v.y || uploadedValue[2] !== v.z) { + Laya.LayaGL.instance.uniform3f(one.location, uploadedValue[0] = v.x, uploadedValue[1] = v.y, uploadedValue[2] = v.z); + return 1; + } + return 0; + } + _uniform_vec3v(one, v) { + Laya.LayaGL.instance.uniform3fv(one.location, v); + return 1; + } + _uniform_vec4(one, v) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== v.x || uploadedValue[1] !== v.y || uploadedValue[2] !== v.z || uploadedValue[3] !== v.w) { + Laya.LayaGL.instance.uniform4f(one.location, uploadedValue[0] = v.x, uploadedValue[1] = v.y, uploadedValue[2] = v.z, uploadedValue[3] = v.w); + return 1; + } + return 0; + } + _uniform_vec4v(one, v) { + Laya.LayaGL.instance.uniform4fv(one.location, v); + return 1; + } + _uniformMatrix2fv(one, value) { + Laya.LayaGL.instance.uniformMatrix2fv(one.location, false, value); + return 1; + } + _uniformMatrix3fv(one, value) { + Laya.LayaGL.instance.uniformMatrix3fv(one.location, false, value); + return 1; + } + _uniformMatrix4f(one, m) { + var value = m.elements; + Laya.LayaGL.instance.uniformMatrix4fv(one.location, false, value); + return 1; + } + _uniformMatrix4fv(one, m) { + Laya.LayaGL.instance.uniformMatrix4fv(one.location, false, m); + return 1; + } + _uniform1i(one, value) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== value) { + Laya.LayaGL.instance.uniform1i(one.location, uploadedValue[0] = value); + return 1; + } + return 0; + } + _uniform1iv(one, value) { + Laya.LayaGL.instance.uniform1iv(one.location, value); + return 1; + } + _uniform_ivec2(one, value) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1]) { + Laya.LayaGL.instance.uniform2i(one.location, uploadedValue[0] = value[0], uploadedValue[1] = value[1]); + return 1; + } + return 0; + } + _uniform_ivec2v(one, value) { + Laya.LayaGL.instance.uniform2iv(one.location, value); + return 1; + } + _uniform_vec3i(one, value) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2]) { + Laya.LayaGL.instance.uniform3i(one.location, uploadedValue[0] = value[0], uploadedValue[1] = value[1], uploadedValue[2] = value[2]); + return 1; + } + return 0; + } + _uniform_vec3vi(one, value) { + Laya.LayaGL.instance.uniform3iv(one.location, value); + return 1; + } + _uniform_vec4i(one, value) { + var uploadedValue = one.uploadedValue; + if (uploadedValue[0] !== value[0] || uploadedValue[1] !== value[1] || uploadedValue[2] !== value[2] || uploadedValue[3] !== value[3]) { + Laya.LayaGL.instance.uniform4i(one.location, uploadedValue[0] = value[0], uploadedValue[1] = value[1], uploadedValue[2] = value[2], uploadedValue[3] = value[3]); + return 1; + } + return 0; + } + _uniform_vec4vi(one, value) { + Laya.LayaGL.instance.uniform4iv(one.location, value); + return 1; + } + _uniform_sampler2D(one, texture) { + var value = texture._getSource() || texture.defaulteTexture._getSource(); + var gl = Laya.LayaGL.instance; + Laya.WebGLContext.activeTexture(gl, one.textureID); + Laya.WebGLContext.bindTexture(gl, gl.TEXTURE_2D, value); + return 0; + } + _uniform_sampler3D(one, texture) { + var value = texture._getSource() || texture.defaulteTexture._getSource(); + var gl = Laya.LayaGL.instance; + Laya.WebGLContext.activeTexture(gl, one.textureID); + Laya.WebGLContext.bindTexture(gl, WebGL2RenderingContext.TEXTURE_3D, value); + return 0; + } + _uniform_samplerCube(one, texture) { + var value = texture._getSource() || texture.defaulteTexture._getSource(); + var gl = Laya.LayaGL.instance; + Laya.WebGLContext.activeTexture(gl, one.textureID); + Laya.WebGLContext.bindTexture(gl, gl.TEXTURE_CUBE_MAP, value); + return 0; + } + bind() { + return Laya.WebGLContext.useProgram(Laya.LayaGL.instance, this._program); + } + uploadUniforms(shaderUniform, shaderDatas, uploadUnTexture) { + Laya.Stat.shaderCall += Laya.LayaGLRunner.uploadShaderUniforms(Laya.LayaGL.instance, shaderUniform, shaderDatas, uploadUnTexture); + } + uploadRenderStateBlendDepth(shaderDatas) { + var gl = Laya.LayaGL.instance; + var renderState = this._shaderPass.renderState; + var datas = shaderDatas.getData(); + var depthWrite = this._getRenderState(datas, Shader3D.RENDER_STATE_DEPTH_WRITE); + var depthTest = this._getRenderState(datas, Shader3D.RENDER_STATE_DEPTH_TEST); + var blend = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND); + depthWrite == null && (depthWrite = renderState.depthWrite); + depthTest == null && (depthTest = renderState.depthTest); + blend == null && (blend = renderState.blend); + Laya.WebGLContext.setDepthMask(gl, depthWrite); + if (depthTest === RenderState.DEPTHTEST_OFF) + Laya.WebGLContext.setDepthTest(gl, false); + else { + Laya.WebGLContext.setDepthTest(gl, true); + Laya.WebGLContext.setDepthFunc(gl, depthTest); + } + switch (blend) { + case RenderState.BLEND_DISABLE: + Laya.WebGLContext.setBlend(gl, false); + break; + case RenderState.BLEND_ENABLE_ALL: + var blendEquation = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND_EQUATION); + var srcBlend = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND_SRC); + var dstBlend = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND_DST); + blendEquation == null && (blendEquation = renderState.blendEquation); + srcBlend == null && (srcBlend = renderState.srcBlend); + dstBlend == null && (dstBlend = renderState.dstBlend); + Laya.WebGLContext.setBlend(gl, true); + Laya.WebGLContext.setBlendEquation(gl, blendEquation); + Laya.WebGLContext.setBlendFunc(gl, srcBlend, dstBlend); + break; + case RenderState.BLEND_ENABLE_SEPERATE: + var blendEquationRGB = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND_EQUATION_RGB); + var blendEquationAlpha = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND_EQUATION_ALPHA); + var srcRGB = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND_SRC_RGB); + var dstRGB = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND_DST_RGB); + var srcAlpha = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND_SRC_ALPHA); + var dstAlpha = this._getRenderState(datas, Shader3D.RENDER_STATE_BLEND_DST_ALPHA); + blendEquationRGB == null && (blendEquationRGB = renderState.blendEquationRGB); + blendEquationAlpha == null && (blendEquationAlpha = renderState.blendEquationAlpha); + srcRGB == null && (srcRGB = renderState.srcBlendRGB); + dstRGB == null && (dstRGB = renderState.dstBlendRGB); + srcAlpha == null && (srcAlpha = renderState.srcBlendAlpha); + dstAlpha == null && (dstAlpha = renderState.dstBlendAlpha); + Laya.WebGLContext.setBlend(gl, true); + Laya.WebGLContext.setBlendEquationSeparate(gl, blendEquationRGB, blendEquationAlpha); + Laya.WebGLContext.setBlendFuncSeperate(gl, srcRGB, dstRGB, srcAlpha, dstAlpha); + break; + } + } + uploadRenderStateFrontFace(shaderDatas, isTarget, invertFront) { + var gl = Laya.LayaGL.instance; + var renderState = this._shaderPass.renderState; + var datas = shaderDatas.getData(); + var cull = this._getRenderState(datas, Shader3D.RENDER_STATE_CULL); + cull == null && (cull = renderState.cull); + var forntFace; + switch (cull) { + case RenderState.CULL_NONE: + Laya.WebGLContext.setCullFace(gl, false); + break; + case RenderState.CULL_FRONT: + Laya.WebGLContext.setCullFace(gl, true); + if (isTarget) { + if (invertFront) + forntFace = gl.CCW; + else + forntFace = gl.CW; + } + else { + if (invertFront) + forntFace = gl.CW; + else + forntFace = gl.CCW; + } + Laya.WebGLContext.setFrontFace(gl, forntFace); + break; + case RenderState.CULL_BACK: + Laya.WebGLContext.setCullFace(gl, true); + if (isTarget) { + if (invertFront) + forntFace = gl.CW; + else + forntFace = gl.CCW; + } + else { + if (invertFront) + forntFace = gl.CCW; + else + forntFace = gl.CW; + } + Laya.WebGLContext.setFrontFace(gl, forntFace); + break; + } + } + uploadCustomUniform(index, data) { + Laya.Stat.shaderCall += Laya.LayaGLRunner.uploadCustomUniform(Laya.LayaGL.instance, this._customUniformParamsMap, index, data); + } + _uniformMatrix2fvForNative(one, value) { + Laya.LayaGL.instance.uniformMatrix2fvEx(one.location, false, value); + return 1; + } + _uniformMatrix3fvForNative(one, value) { + Laya.LayaGL.instance.uniformMatrix3fvEx(one.location, false, value); + return 1; + } + _uniformMatrix4fvForNative(one, m) { + Laya.LayaGL.instance.uniformMatrix4fvEx(one.location, false, m); + return 1; + } + } + + class SingletonList { + constructor() { + this.elements = []; + this.length = 0; + } + _add(element) { + if (this.length === this.elements.length) + this.elements.push(element); + else + this.elements[this.length] = element; + } + add(element) { + if (this.length === this.elements.length) + this.elements.push(element); + else + this.elements[this.length] = element; + this.length++; + } + } + + class SimpleSingletonList extends SingletonList { + constructor() { + super(); + } + add(element) { + var index = element._getIndexInList(); + if (index !== -1) + throw "SimpleSingletonList:" + element + " has in SingletonList."; + this._add(element); + element._setIndexInList(this.length++); + } + remove(element) { + var index = element._getIndexInList(); + this.length--; + if (index !== this.length) { + var end = this.elements[this.length]; + this.elements[index] = end; + end._setIndexInList(index); + } + element._setIndexInList(-1); + } + clear() { + var elements = this.elements; + for (var i = 0, n = this.length; i < n; i++) + elements[i]._setIndexInList(-1); + this.length = 0; + } + clearElement() { + this.elements = null; + this.length = 0; + } + } + + class Color { + constructor(r = 1, g = 1, b = 1, a = 1) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + static gammaToLinearSpace(value) { + if (value <= 0.04045) + return value / 12.92; + else if (value < 1.0) + return Math.pow((value + 0.055) / 1.055, 2.4); + else + return Math.pow(value, 2.4); + } + static linearToGammaSpace(value) { + if (value <= 0.0) + return 0.0; + else if (value <= 0.0031308) + return 12.92 * value; + else if (value <= 1.0) + return 1.055 * Math.pow(value, 0.41666) - 0.055; + else + return Math.pow(value, 0.41666); + } + toLinear(out) { + out.r = Color.gammaToLinearSpace(this.r); + out.g = Color.gammaToLinearSpace(this.g); + out.b = Color.gammaToLinearSpace(this.b); + } + toGamma(out) { + out.r = Color.linearToGammaSpace(this.r); + out.g = Color.linearToGammaSpace(this.g); + out.b = Color.linearToGammaSpace(this.b); + } + cloneTo(destObject) { + var destColor = destObject; + destColor.r = this.r; + destColor.g = this.g; + destColor.b = this.b; + destColor.a = this.a; + } + clone() { + var dest = new Color(); + this.cloneTo(dest); + return dest; + } + forNativeElement() { + } + } + Color.RED = new Color(1, 0, 0, 1); + Color.GREEN = new Color(0, 1, 0, 1); + Color.BLUE = new Color(0, 0, 1, 1); + Color.CYAN = new Color(0, 1, 1, 1); + Color.YELLOW = new Color(1, 0.92, 0.016, 1); + Color.MAGENTA = new Color(1, 0, 1, 1); + Color.GRAY = new Color(0.5, 0.5, 0.5, 1); + Color.WHITE = new Color(1, 1, 1, 1); + Color.BLACK = new Color(0, 0, 0, 1); + + class CameraCullInfo { + } + class ShadowCullInfo { + } + class FrustumCulling { + static __init__() { + } + static _drawTraversalCullingBound(renderList, debugTool) { + var renders = renderList.elements; + for (var i = 0, n = renderList.length; i < n; i++) { + var color = FrustumCulling._tempColor0; + color.r = 0; + color.g = 1; + color.b = 0; + color.a = 1; + Utils3D._drawBound(debugTool, renders[i].bounds._getBoundBox(), color); + } + } + static _traversalCulling(cameraCullInfo, scene, context, renderList, customShader, replacementTag, isShadowCasterCull) { + var renders = renderList.elements; + var boundFrustum = cameraCullInfo.boundFrustum; + var camPos = cameraCullInfo.position; + var cullMask = cameraCullInfo.cullingMask; + var loopCount = Laya.Stat.loopCount; + for (var i = 0, n = renderList.length; i < n; i++) { + var render = renders[i]; + var canPass; + if (isShadowCasterCull) + canPass = render._castShadow && render._enable; + else + canPass = ((Math.pow(2, render._owner._layer) & cullMask) != 0) && render._enable; + if (canPass) { + Laya.Stat.frustumCulling++; + if (!cameraCullInfo.useOcclusionCulling || render._needRender(boundFrustum, context)) { + render._renderMark = loopCount; + render._distanceForSort = Vector3.distance(render.bounds.getCenter(), camPos); + var elements = render._renderElements; + for (var j = 0, m = elements.length; j < m; j++) + elements[j]._update(scene, context, customShader, replacementTag); + } + } + } + } + static renderObjectCulling(cameraCullInfo, scene, context, customShader, replacementTag, isShadowCasterCull) { + var opaqueQueue = scene._opaqueQueue; + var transparentQueue = scene._transparentQueue; + var renderList = scene._renders; + scene._clearRenderQueue(); + var octree = scene._octree; + if (octree) { + octree.updateMotionObjects(); + octree.shrinkRootIfPossible(); + octree.getCollidingWithFrustum(cameraCullInfo, context, customShader, replacementTag, isShadowCasterCull); + } + FrustumCulling._traversalCulling(cameraCullInfo, scene, context, renderList, customShader, replacementTag, isShadowCasterCull); + if (FrustumCulling.debugFrustumCulling) { + var debugTool = scene._debugTool; + debugTool.clear(); + if (octree) { + octree.drawAllBounds(debugTool); + octree.drawAllObjects(debugTool); + } + FrustumCulling._drawTraversalCullingBound(renderList, debugTool); + } + var count = opaqueQueue.elements.length; + (count > 0) && (opaqueQueue._quickSort(0, count - 1)); + count = transparentQueue.elements.length; + (count > 0) && (transparentQueue._quickSort(0, count - 1)); + } + static cullingShadow(cullInfo, scene, context) { + scene._clearRenderQueue(); + var opaqueQueue = scene._opaqueQueue; + if (!scene._octree) { + var renderList = scene._renders; + var position = cullInfo.position; + var renders = renderList.elements; + var loopCount = Laya.Stat.loopCount; + for (var i = 0, n = renderList.length; i < n; i++) { + var render = renders[i]; + var canPass = render._castShadow && render._enable; + if (canPass) { + Laya.Stat.frustumCulling++; + let pass = FrustumCulling.cullingRenderBounds(render.bounds, cullInfo); + if (pass) { + render._renderMark = loopCount; + render._distanceForSort = Vector3.distance(render.bounds.getCenter(), position); + var elements = render._renderElements; + for (var j = 0, m = elements.length; j < m; j++) + elements[j]._update(scene, context, null, null); + } + } + } + } + else { + let octree = scene._octree; + octree.updateMotionObjects(); + octree.shrinkRootIfPossible(); + octree._rootNode.getCollidingWithCastShadowFrustum(cullInfo, context); + } + return opaqueQueue.elements.length > 0 ? true : false; + } + static cullingRenderBounds(bounds, cullInfo) { + var cullPlaneCount = cullInfo.cullPlaneCount; + var cullPlanes = cullInfo.cullPlanes; + var min = bounds.getMin(); + var max = bounds.getMax(); + var minX = min.x; + var minY = min.y; + var minZ = min.z; + var maxX = max.x; + var maxY = max.y; + var maxZ = max.z; + var pass = true; + for (var j = 0; j < cullPlaneCount; j++) { + var plane = cullPlanes[j]; + var normal = plane.normal; + if (plane.distance + (normal.x * (normal.x < 0.0 ? minX : maxX)) + (normal.y * (normal.y < 0.0 ? minY : maxY)) + (normal.z * (normal.z < 0.0 ? minZ : maxZ)) < 0.0) { + pass = false; + break; + } + } + return pass; + } + static cullingSpotShadow(cameraCullInfo, scene, context) { + var opaqueQueue = scene._opaqueQueue; + scene._clearRenderQueue(); + if (!scene._octree) { + var renderList = scene._renders; + var renders = renderList.elements; + var loopCount = Laya.Stat.loopCount; + for (var i = 0, n = renderList.length; i < n; i++) { + var render = renders[i]; + var canPass = render._castShadow && render._enable; + if (canPass) { + if (render._needRender(cameraCullInfo.boundFrustum, context)) { + var bounds = render.bounds; + render._renderMark = loopCount; + render._distanceForSort = Vector3.distance(bounds.getCenter(), cameraCullInfo.position); + var elements = render._renderElements; + for (var j = 0, m = elements.length; j < m; j++) + elements[j]._update(scene, context, null, null); + } + } + } + } + else { + let octree = scene._octree; + octree.updateMotionObjects(); + octree.shrinkRootIfPossible(); + octree.getCollidingWithFrustum(cameraCullInfo, context, null, null, true); + } + return opaqueQueue.elements.length > 0 ? true : false; + } + static renderObjectCullingNative(camera, scene, context, renderList, customShader, replacementTag) { + var i, j, m; + var opaqueQueue = scene._opaqueQueue; + var transparentQueue = scene._transparentQueue; + scene._clearRenderQueue(); + var validCount = renderList.length; + var renders = renderList.elements; + for (i = 0; i < validCount; i++) { + renders[i].bounds; + renders[i]._updateForNative && renders[i]._updateForNative(context); + } + FrustumCulling.cullingNative(camera._boundFrustumBuffer, FrustumCulling._cullingBuffer, scene._cullingBufferIndices, validCount, scene._cullingBufferResult); + var loopCount = Laya.Stat.loopCount; + var camPos = context.camera._transform.position; + for (i = 0; i < validCount; i++) { + var render = renders[i]; + if (!camera.useOcclusionCulling || (camera._isLayerVisible(render._owner._layer) && render._enable && scene._cullingBufferResult[i])) { + render._renderMark = loopCount; + render._distanceForSort = Vector3.distance(render.bounds.getCenter(), camPos); + var elements = render._renderElements; + for (j = 0, m = elements.length; j < m; j++) { + var element = elements[j]; + element._update(scene, context, customShader, replacementTag); + } + } + } + var count = opaqueQueue.elements.length; + (count > 0) && (opaqueQueue._quickSort(0, count - 1)); + count = transparentQueue.elements.length; + (count > 0) && (transparentQueue._quickSort(0, count - 1)); + } + static cullingNative(boundFrustumBuffer, cullingBuffer, cullingBufferIndices, cullingCount, cullingBufferResult) { + return Laya.LayaGL.instance.culling(boundFrustumBuffer, cullingBuffer, cullingBufferIndices, cullingCount, cullingBufferResult); + } + } + FrustumCulling._tempColor0 = new Color(); + FrustumCulling._cameraCullInfo = new CameraCullInfo(); + FrustumCulling._shadowCullInfo = new ShadowCullInfo(); + FrustumCulling.debugFrustumCulling = false; + + class LightBound { + } + class ClusterData { + constructor() { + this.updateMark = -1; + this.pointLightCount = 0; + this.spotLightCount = 0; + this.indices = []; + } + } + class Cluster { + constructor(xSlices, ySlices, zSlices, maxLightsPerClusterAverage) { + this._updateMark = 0; + this._depthSliceParam = new Vector2(); + this._xSlices = xSlices; + this._ySlices = ySlices; + this._zSlices = zSlices; + var clusterTexWidth = xSlices * ySlices; + var clisterTexHeight = zSlices * (1 + Math.ceil(maxLightsPerClusterAverage / 4)); + this._clusterTexture = Utils3D._createFloatTextureBuffer(clusterTexWidth, clisterTexHeight); + this._clusterTexture.lock = true; + this._clusterPixels = new Float32Array(clusterTexWidth * clisterTexHeight * 4); + var clusterDatas = new Array(this._zSlices); + for (var z = 0; z < this._zSlices; z++) { + clusterDatas[z] = new Array(this._ySlices); + for (var y = 0; y < this._ySlices; y++) { + clusterDatas[z][y] = new Array(this._xSlices); + for (var x = 0; x < this._xSlices; x++) + clusterDatas[z][y][x] = new ClusterData(); + } + } + this._clusterDatas = clusterDatas; + } + _placePointLightToClusters(lightIndex, lightBound) { + var clusterDatas = this._clusterDatas; + var updateMark = this._updateMark; + for (var z = lightBound.zMin, zEnd = lightBound.zMax; z < zEnd; z++) { + for (var y = lightBound.yMin, yEnd = lightBound.yMax; y < yEnd; y++) { + for (var x = lightBound.xMin, xEnd = lightBound.xMax; x < xEnd; x++) { + var data = clusterDatas[z][y][x]; + if (data.updateMark != updateMark) { + data.pointLightCount = 0; + data.spotLightCount = 0; + data.updateMark = updateMark; + } + var indices = data.indices; + var lightCount = data.pointLightCount++; + if (lightCount < indices.length) + indices[lightCount] = lightIndex; + else + indices.push(lightIndex); + } + } + } + } + _placeSpotLightToClusters(lightIndex, lightBound) { + var clusterDatas = this._clusterDatas; + var updateMark = this._updateMark; + for (var z = lightBound.zMin, zEnd = lightBound.zMax; z < zEnd; z++) { + for (var y = lightBound.yMin, yEnd = lightBound.yMax; y < yEnd; y++) { + for (var x = lightBound.xMin, xEnd = lightBound.xMax; x < xEnd; x++) { + var data = clusterDatas[z][y][x]; + if (data.updateMark != updateMark) { + data.pointLightCount = 0; + data.spotLightCount = 0; + data.updateMark = updateMark; + } + var indices = data.indices; + var lightCount = data.pointLightCount + data.spotLightCount++; + if (lightCount < indices.length) + indices[lightCount] = lightIndex; + else + indices.push(lightIndex); + } + } + } + } + _insertConePlane(origin, forward, radius, halfAngle, pNor) { + var V1 = Cluster._tempVector36; + var V2 = Cluster._tempVector37; + Vector3.cross(pNor, forward, V1); + Vector3.cross(V1, forward, V2); + Vector3.normalize(V2, V2); + var tanR = radius * Math.tan(halfAngle); + var capRimX = origin.x + radius * forward.x + tanR * V2.x; + var capRimY = origin.y + radius * forward.y + tanR * V2.y; + var capRimZ = origin.z + radius * forward.z + tanR * V2.z; + return capRimX * pNor.x + capRimY * pNor.y + capRimZ * pNor.z <= 0 || origin.x * pNor.x + origin.y * pNor.y + origin.z * pNor.z <= 0; + } + _shrinkSphereLightZPerspective(near, far, lightviewPos, radius, lightBound) { + var lvZ = lightviewPos.z; + var minZ = lvZ - radius; + var maxZ = lvZ + radius; + if ((minZ > far) || (maxZ <= near)) + return false; + var depthSliceParam = this._depthSliceParam; + lightBound.zMin = Math.floor(Math.log2(Math.max(minZ, near)) * depthSliceParam.x - depthSliceParam.y); + lightBound.zMax = Math.min(Math.ceil(Math.log2(maxZ) * depthSliceParam.x - depthSliceParam.y), this._zSlices); + return true; + } + _shrinkSpotLightZPerspective(near, far, viewLightPos, viewConeCap, radius, halfAngle, lightBound) { + var pbX = viewConeCap.x, pbY = viewConeCap.y, pbZ = viewConeCap.z; + var rb = Math.tan(halfAngle) * radius; + var paX = viewLightPos.x, paY = viewLightPos.y, paZ = viewLightPos.z; + var aX = pbX - paX, aY = pbY - paY, aZ = pbZ - paZ; + var dotA = aX * aX + aY * aY + aZ * aZ; + var eZ = Math.sqrt(1.0 - aZ * aZ / dotA); + var minZ = Math.max(Math.min(paZ, pbZ - eZ * rb), viewLightPos.z - radius); + var maxZ = Math.min(Math.max(paZ, pbZ + eZ * rb), viewLightPos.z + radius); + if ((minZ > far) || (maxZ <= near)) + return false; + var depthSliceParam = this._depthSliceParam; + lightBound.zMin = Math.floor(Math.log2(Math.max(minZ, near)) * depthSliceParam.x - depthSliceParam.y); + lightBound.zMax = Math.min(Math.ceil(Math.log2(maxZ) * depthSliceParam.x - depthSliceParam.y), this._zSlices); + return true; + } + _shrinkSphereLightByBoundOrth(halfX, halfY, near, far, lightviewPos, radius, lightBound) { + var lvZ = lightviewPos.z; + var minZ = lvZ - radius, maxZ = lvZ + radius; + if ((minZ > far) || (maxZ <= near)) + return false; + var lvX = lightviewPos.x; + var minX = lvX - radius, maxX = lvX + radius; + if ((minX > halfX) || (maxX <= -halfX)) + return false; + var lvY = lightviewPos.y; + var minY = lvY - radius, maxY = lvY + radius; + if ((minY > halfY) || (maxY <= -halfY)) + return false; + var xSlices = this._xSlices, ySlices = this._ySlices; + var depthSliceParam = this._depthSliceParam; + var xStride = halfX * 2 / xSlices, yStride = halfY * 2 / ySlices; + lightBound.xMin = Math.max(Math.floor((minX + halfX) / xStride), 0); + lightBound.xMax = Math.min(Math.ceil((maxX + halfX) / xStride), xSlices); + lightBound.yMin = Math.max(Math.floor((halfY - maxY) / yStride), 0); + lightBound.yMax = Math.min(Math.ceil((halfY - minY) / yStride), ySlices); + lightBound.zMin = Math.floor(Math.log2(Math.max(minZ, near)) * depthSliceParam.x - depthSliceParam.y); + lightBound.zMax = Math.min(Math.ceil(Math.log2(maxZ) * depthSliceParam.x - depthSliceParam.y), this._zSlices); + return true; + } + _shrinkSpotLightByBoundOrth(halfX, halfY, near, far, viewLightPos, viewConeCap, radius, halfAngle, lightBound) { + var pbX = viewConeCap.x, pbY = viewConeCap.y, pbZ = viewConeCap.z; + var rb = Math.tan(halfAngle) * radius; + var paX = viewLightPos.x, paY = viewLightPos.y, paZ = viewLightPos.z; + var aX = pbX - paX, aY = pbY - paY, aZ = pbZ - paZ; + var dotA = aX * aX + aY * aY + aZ * aZ; + var eZ = Math.sqrt(1.0 - aZ * aZ / dotA); + var minZ = Math.max(Math.min(paZ, pbZ - eZ * rb), viewLightPos.z - radius); + var maxZ = Math.min(Math.max(paZ, pbZ + eZ * rb), viewLightPos.z + radius); + if ((minZ > far) || (maxZ <= near)) + return false; + var eX = Math.sqrt(1.0 - aX * aX / dotA); + var minX = Math.max(Math.min(paX, pbX - eX * rb), viewLightPos.x - radius); + var maxX = Math.min(Math.max(paX, pbX + eX * rb), viewLightPos.x + radius); + if ((minX > halfX) || (maxX <= -halfX)) + return false; + var eY = Math.sqrt(1.0 - aY * aY / dotA); + var minY = Math.max(Math.min(paY, pbY - eY * rb), viewLightPos.y - radius); + var maxY = Math.min(Math.max(paY, pbY + eY * rb), viewLightPos.y + radius); + if ((minY > halfY) || (maxY <= -halfY)) + return false; + var xSlices = this._xSlices, ySlices = this._ySlices; + var depthSliceParam = this._depthSliceParam; + var xStride = halfX * 2 / xSlices, yStride = halfY * 2 / ySlices; + lightBound.xMin = Math.max(Math.floor((minX + halfX) / xStride), 0); + lightBound.xMax = Math.min(Math.ceil((maxX + halfX) / xStride), xSlices); + lightBound.yMin = Math.max(Math.floor((halfY - maxY) / yStride), 0); + lightBound.yMax = Math.min(Math.ceil((halfY - minY) / yStride), ySlices); + lightBound.zMin = Math.floor(Math.log2(Math.max(minZ, near)) * depthSliceParam.x - depthSliceParam.y); + lightBound.zMax = Math.min(Math.ceil(Math.log2(maxZ) * depthSliceParam.x - depthSliceParam.y), this._zSlices); + return true; + } + _shrinkXYByRadiusPerspective(lightviewPos, radius, lightBound, xPlanes, yPlanes) { + var xMin, yMin; + var xMax, yMax; + var lvX = lightviewPos.x, lvY = lightviewPos.y, lvZ = lightviewPos.z; + var i; + var n = this._ySlices + 1; + for (i = 0; i < n; i++) { + var plane = yPlanes[i]; + if (lvY * plane.y + lvZ * plane.z < radius) { + yMin = Math.max(0, i - 1); + break; + } + } + if (i == n) + return false; + yMax = this._ySlices; + for (i = yMin + 1; i < n; i++) { + var plane = yPlanes[i]; + if (lvY * plane.y + lvZ * plane.z <= -radius) { + yMax = Math.max(0, i); + break; + } + } + n = this._xSlices + 1; + for (i = 0; i < n; i++) { + var plane = xPlanes[i]; + if (lvX * plane.x + lvZ * plane.z < radius) { + xMin = Math.max(0, i - 1); + break; + } + } + xMax = this._xSlices; + for (i = xMin + 1; i < n; i++) { + var plane = xPlanes[i]; + if (lvX * plane.x + lvZ * plane.z <= -radius) { + xMax = Math.max(0, i); + break; + } + } + lightBound.xMin = xMin; + lightBound.xMax = xMax; + lightBound.yMin = yMin; + lightBound.yMax = yMax; + return true; + } + _shrinkSpotXYByConePerspective(lightviewPos, viewForward, radius, halfAngle, lightBound, xPlanes, yPlanes) { + var xMin, yMin; + var xMax, yMax; + var normal = Cluster._tempVector32; + var n = lightBound.yMax + 1; + for (var i = lightBound.yMin + 1; i < n; i++) { + if (this._insertConePlane(lightviewPos, viewForward, radius, halfAngle, yPlanes[i])) { + yMin = Math.max(0, i - 1); + break; + } + } + yMax = lightBound.yMax; + for (var i = yMin + 1; i < n; i++) { + var plane = yPlanes[i]; + normal.setValue(0, -plane.y, -plane.z); + if (!this._insertConePlane(lightviewPos, viewForward, radius, halfAngle, normal)) { + yMax = Math.max(0, i); + break; + } + } + n = lightBound.xMax + 1; + for (var i = lightBound.xMin + 1; i < n; i++) { + if (this._insertConePlane(lightviewPos, viewForward, radius, halfAngle, xPlanes[i])) { + xMin = Math.max(0, i - 1); + break; + } + } + xMax = lightBound.xMax; + for (var i = xMin + 1; i < n; i++) { + var plane = xPlanes[i]; + normal.setValue(-plane.x, 0, -plane.z); + if (!this._insertConePlane(lightviewPos, viewForward, radius, halfAngle, normal)) { + xMax = Math.max(0, i); + break; + } + } + lightBound.xMin = xMin; + lightBound.xMax = xMax; + lightBound.yMin = yMin; + lightBound.yMax = yMax; + } + _updatePointLightPerspective(near, far, viewMat, pointLight, lightIndex, xPlanes, yPlanes) { + var lightBound = Cluster._tempLightBound; + var lightviewPos = Cluster._tempVector30; + Vector3.transformV3ToV3(pointLight._transform.position, viewMat, lightviewPos); + lightviewPos.z *= -1; + if (!this._shrinkSphereLightZPerspective(near, far, lightviewPos, pointLight.range, lightBound)) + return; + if (!this._shrinkXYByRadiusPerspective(lightviewPos, pointLight.range, lightBound, xPlanes, yPlanes)) + return; + this._placePointLightToClusters(lightIndex, lightBound); + } + _updateSpotLightPerspective(near, far, viewMat, spotLight, lightIndex, xPlanes, yPlanes) { + var lightBound = Cluster._tempLightBound; + var viewPos = Cluster._tempVector30; + var forward = Cluster._tempVector31; + var viewConeCap = Cluster._tempVector34; + var position = spotLight._transform.position; + var range = spotLight.range; + spotLight._transform.worldMatrix.getForward(forward); + Vector3.normalize(forward, forward); + Vector3.scale(forward, range, viewConeCap); + Vector3.add(position, viewConeCap, viewConeCap); + Vector3.transformV3ToV3(position, viewMat, viewPos); + Vector3.transformV3ToV3(viewConeCap, viewMat, viewConeCap); + viewPos.z *= -1; + viewConeCap.z *= -1; + var halfAngle = (spotLight.spotAngle / 2) * Math.PI / 180; + if (!this._shrinkSpotLightZPerspective(near, far, viewPos, viewConeCap, range, halfAngle, lightBound)) + return; + if (!this._shrinkXYByRadiusPerspective(viewPos, range, lightBound, xPlanes, yPlanes)) + return; + var viewFor = Cluster._tempVector33; + viewFor.x = viewConeCap.x - viewPos.x, viewFor.y = viewConeCap.y - viewPos.y, viewFor.z = viewConeCap.z - viewPos.z; + Vector3.normalize(viewFor, viewFor); + this._shrinkSpotXYByConePerspective(viewPos, viewFor, range, halfAngle, lightBound, xPlanes, yPlanes); + this._placeSpotLightToClusters(lightIndex, lightBound); + } + _updatePointLightOrth(halfX, halfY, near, far, viewMat, pointLight, lightIndex) { + var lightBound = Cluster._tempLightBound; + var lightviewPos = Cluster._tempVector30; + Vector3.transformV3ToV3(pointLight._transform.position, viewMat, lightviewPos); + lightviewPos.z *= -1; + if (!this._shrinkSphereLightByBoundOrth(halfX, halfY, near, far, lightviewPos, pointLight.range, lightBound)) + return; + this._placePointLightToClusters(lightIndex, lightBound); + } + _updateSpotLightOrth(halfX, halfY, near, far, viewMat, spotLight, lightIndex) { + var lightBound = Cluster._tempLightBound; + var viewPos = Cluster._tempVector30; + var forward = Cluster._tempVector31; + var viewConeCap = Cluster._tempVector34; + var position = spotLight._transform.position; + var range = spotLight.range; + spotLight._transform.worldMatrix.getForward(forward); + Vector3.normalize(forward, forward); + Vector3.scale(forward, range, viewConeCap); + Vector3.add(position, viewConeCap, viewConeCap); + Vector3.transformV3ToV3(position, viewMat, viewPos); + Vector3.transformV3ToV3(viewConeCap, viewMat, viewConeCap); + viewPos.z *= -1; + viewConeCap.z *= -1; + var halfAngle = (spotLight.spotAngle / 2) * Math.PI / 180; + if (!this._shrinkSpotLightByBoundOrth(halfX, halfY, near, far, viewPos, viewConeCap, range, halfAngle, lightBound)) + return; + this._placeSpotLightToClusters(lightIndex, lightBound); + } + update(camera, scene) { + this._updateMark++; + var camNear = camera.nearPlane; + this._depthSliceParam.x = Config3D._config.lightClusterCount.z / Math.log2(camera.farPlane / camNear); + this._depthSliceParam.y = Math.log2(camNear) * this._depthSliceParam.x; + var near = camera.nearPlane; + var far = camera.farPlane; + var viewMat = camera.viewMatrix; + var curCount = scene._directionLights._length; + var pointLights = scene._pointLights; + var poiCount = pointLights._length; + var poiElements = pointLights._elements; + var spotLights = scene._spotLights; + var spoCount = spotLights._length; + var spoElements = spotLights._elements; + if (camera.orthographic) { + var halfY = camera.orthographicVerticalSize / 2.0; + var halfX = halfY * camera.aspectRatio; + for (var i = 0; i < poiCount; i++, curCount++) + this._updatePointLightOrth(halfX, halfY, near, far, viewMat, poiElements[i], curCount); + for (var i = 0; i < spoCount; i++, curCount++) + this._updateSpotLightOrth(halfX, halfY, near, far, viewMat, spoElements[i], curCount); + } + else { + camera._updateClusterPlaneXY(); + var xPlanes = camera._clusterXPlanes; + var yPlanes = camera._clusterYPlanes; + for (var i = 0; i < poiCount; i++, curCount++) + this._updatePointLightPerspective(near, far, viewMat, poiElements[i], curCount, xPlanes, yPlanes); + for (var i = 0; i < spoCount; i++, curCount++) + this._updateSpotLightPerspective(near, far, viewMat, spoElements[i], curCount, xPlanes, yPlanes); + } + if (poiCount + spoCount > 0) { + var xSlices = this._xSlices, ySlices = this._ySlices, zSlices = this._zSlices; + var widthFloat = xSlices * ySlices * 4; + var lightOff = widthFloat * zSlices; + var clusterPixels = this._clusterPixels; + var clusterPixelsCount = clusterPixels.length; + var clusterDatas = this._clusterDatas; + var updateMark = this._updateMark; + var freeSpace = true; + for (var z = 0; z < zSlices; z++) { + for (var y = 0; y < ySlices; y++) { + for (var x = 0; x < xSlices; x++) { + var data = clusterDatas[z][y][x]; + var clusterOff = (x + y * xSlices + z * xSlices * ySlices) * 4; + if (data.updateMark !== updateMark) { + clusterPixels[clusterOff] = 0; + clusterPixels[clusterOff + 1] = 0; + } + else { + if (freeSpace) { + var indices = data.indices; + var pCount = data.pointLightCount; + var sCount = data.spotLightCount; + var count = pCount + sCount; + if (lightOff + count < clusterPixelsCount) { + clusterPixels[clusterOff] = pCount; + clusterPixels[clusterOff + 1] = sCount; + clusterPixels[clusterOff + 2] = Math.floor(lightOff / widthFloat); + clusterPixels[clusterOff + 3] = lightOff % widthFloat; + for (var i = 0; i < count; i++) + clusterPixels[lightOff++] = indices[i]; + } + else { + count = clusterPixelsCount - (lightOff + count); + pCount = Math.min(pCount, count); + clusterPixels[clusterOff] = pCount; + clusterPixels[clusterOff + 1] = Math.min(sCount, count - pCount); + clusterPixels[clusterOff + 2] = Math.floor(lightOff / widthFloat); + clusterPixels[clusterOff + 3] = lightOff % widthFloat; + for (var i = 0; i < count; i++) + clusterPixels[lightOff++] = indices[i]; + freeSpace = false; + } + } + } + } + } + } + var width = this._clusterTexture.width; + this._clusterTexture.setSubPixels(0, 0, width, Math.ceil(lightOff / (4 * width)), clusterPixels); + } + } + } + Cluster._tempVector30 = new Vector3(); + Cluster._tempVector31 = new Vector3(); + Cluster._tempVector32 = new Vector3(); + Cluster._tempVector33 = new Vector3(); + Cluster._tempVector34 = new Vector3(); + Cluster._tempVector35 = new Vector3(); + Cluster._tempVector36 = new Vector3(); + Cluster._tempVector37 = new Vector3(); + Cluster._tempLightBound = new LightBound(); + + class SphericalHarmonicsL2 { + constructor() { + this._coefficients = new Float32Array(27); + } + getCoefficient(i, j) { + return this._coefficients[i * 9 + j]; + } + setCoefficient(i, j, coefficient) { + this._coefficients[i * 9 + j] = coefficient; + } + setCoefficients(i, coefficient0, coefficient1, coefficient2, coefficient3, coefficient4, coefficient5, coefficient6, coefficient7, coefficient8) { + var offset = i * 9; + this._coefficients[offset] = coefficient0; + this._coefficients[++offset] = coefficient1; + this._coefficients[++offset] = coefficient2; + this._coefficients[++offset] = coefficient3; + this._coefficients[++offset] = coefficient4; + this._coefficients[++offset] = coefficient5; + this._coefficients[++offset] = coefficient6; + this._coefficients[++offset] = coefficient7; + this._coefficients[++offset] = coefficient8; + } + cloneTo(dest) { + if (this === dest) + return; + var coes = this._coefficients; + var destCoes = dest._coefficients; + for (var i = 0; i < 27; i++) + destCoes[i] = coes[i]; + } + } + SphericalHarmonicsL2._default = new SphericalHarmonicsL2(); + + class MouseTouch { + constructor() { + this._pressedSprite = null; + this._pressedLoopCount = -1; + this.sprite = null; + this.mousePositionX = 0; + this.mousePositionY = 0; + } + } + + class Touch { + constructor() { + this._indexInList = -1; + this._identifier = -1; + this._position = new Vector2(); + } + get identifier() { + return this._identifier; + } + get position() { + return this._position; + } + _getIndexInList() { + return this._indexInList; + } + _setIndexInList(index) { + this._indexInList = index; + } + } + + class Plane { + constructor(normal, d = 0) { + this.normal = normal; + this.distance = d; + } + static createPlaneBy3P(point0, point1, point2, out) { + var x1 = point1.x - point0.x; + var y1 = point1.y - point0.y; + var z1 = point1.z - point0.z; + var x2 = point2.x - point0.x; + var y2 = point2.y - point0.y; + var z2 = point2.z - point0.z; + var yz = (y1 * z2) - (z1 * y2); + var xz = (z1 * x2) - (x1 * z2); + var xy = (x1 * y2) - (y1 * x2); + var invPyth = 1.0 / (Math.sqrt((yz * yz) + (xz * xz) + (xy * xy))); + var x = yz * invPyth; + var y = xz * invPyth; + var z = xy * invPyth; + var normal = out.normal; + normal.x = x; + normal.y = y; + normal.z = z; + out.distance = -((x * point0.x) + (y * point0.y) + (z * point0.z)); + } + normalize() { + var normalEX = this.normal.x; + var normalEY = this.normal.y; + var normalEZ = this.normal.z; + var magnitude = 1.0 / Math.sqrt(normalEX * normalEX + normalEY * normalEY + normalEZ * normalEZ); + this.normal.x = normalEX * magnitude; + this.normal.y = normalEY * magnitude; + this.normal.z = normalEZ * magnitude; + this.distance *= magnitude; + } + cloneTo(destObject) { + var dest = destObject; + this.normal.cloneTo(dest.normal); + dest.distance = this.distance; + } + clone() { + var dest = new Plane(new Vector3()); + this.cloneTo(dest); + return dest; + } + } + Plane.PlaneIntersectionType_Back = 0; + Plane.PlaneIntersectionType_Front = 1; + Plane.PlaneIntersectionType_Intersecting = 2; + + class Ray { + constructor(origin, direction) { + this.origin = origin; + this.direction = direction; + } + } + + class ContainmentType { + } + ContainmentType.Disjoint = 0; + ContainmentType.Contains = 1; + ContainmentType.Intersects = 2; + + class CollisionUtils { + constructor() { + } + static distancePlaneToPoint(plane, point) { + var dot = Vector3.dot(plane.normal, point); + return dot - plane.distance; + } + static distanceBoxToPoint(box, point) { + var boxMin = box.min; + var boxMineX = boxMin.x; + var boxMineY = boxMin.y; + var boxMineZ = boxMin.z; + var boxMax = box.max; + var boxMaxeX = boxMax.x; + var boxMaxeY = boxMax.y; + var boxMaxeZ = boxMax.z; + var pointeX = point.x; + var pointeY = point.y; + var pointeZ = point.z; + var distance = 0; + if (pointeX < boxMineX) + distance += (boxMineX - pointeX) * (boxMineX - pointeX); + if (pointeX > boxMaxeX) + distance += (boxMaxeX - pointeX) * (boxMaxeX - pointeX); + if (pointeY < boxMineY) + distance += (boxMineY - pointeY) * (boxMineY - pointeY); + if (pointeY > boxMaxeY) + distance += (boxMaxeY - pointeY) * (boxMaxeY - pointeY); + if (pointeZ < boxMineZ) + distance += (boxMineZ - pointeZ) * (boxMineZ - pointeZ); + if (pointeZ > boxMaxeZ) + distance += (boxMaxeZ - pointeZ) * (boxMaxeZ - pointeZ); + return Math.sqrt(distance); + } + static distanceBoxToBox(box1, box2) { + var box1Mine = box1.min; + var box1MineX = box1Mine.x; + var box1MineY = box1Mine.y; + var box1MineZ = box1Mine.z; + var box1Maxe = box1.max; + var box1MaxeX = box1Maxe.x; + var box1MaxeY = box1Maxe.y; + var box1MaxeZ = box1Maxe.z; + var box2Mine = box2.min; + var box2MineX = box2Mine.x; + var box2MineY = box2Mine.y; + var box2MineZ = box2Mine.z; + var box2Maxe = box2.max; + var box2MaxeX = box2Maxe.x; + var box2MaxeY = box2Maxe.y; + var box2MaxeZ = box2Maxe.z; + var distance = 0; + var delta; + if (box1MineX > box2MaxeX) { + delta = box1MineX - box2MaxeX; + distance += delta * delta; + } + else if (box2MineX > box1MaxeX) { + delta = box2MineX - box1MaxeX; + distance += delta * delta; + } + if (box1MineY > box2MaxeY) { + delta = box1MineY - box2MaxeY; + distance += delta * delta; + } + else if (box2MineY > box1MaxeY) { + delta = box2MineY - box1MaxeY; + distance += delta * delta; + } + if (box1MineZ > box2MaxeZ) { + delta = box1MineZ - box2MaxeZ; + distance += delta * delta; + } + else if (box2MineZ > box1MaxeZ) { + delta = box2MineZ - box1MaxeZ; + distance += delta * delta; + } + return Math.sqrt(distance); + } + static distanceSphereToPoint(sphere, point) { + var distance = Math.sqrt(Vector3.distanceSquared(sphere.center, point)); + distance -= sphere.radius; + return Math.max(distance, 0); + } + static distanceSphereToSphere(sphere1, sphere2) { + var distance = Math.sqrt(Vector3.distanceSquared(sphere1.center, sphere2.center)); + distance -= sphere1.radius + sphere2.radius; + return Math.max(distance, 0); + } + static intersectsRayAndTriangleRD(ray, vertex1, vertex2, vertex3, out) { + var rayO = ray.origin; + var rayOeX = rayO.x; + var rayOeY = rayO.y; + var rayOeZ = rayO.z; + var rayD = ray.direction; + var rayDeX = rayD.x; + var rayDeY = rayD.y; + var rayDeZ = rayD.z; + var v1eX = vertex1.x; + var v1eY = vertex1.y; + var v1eZ = vertex1.z; + var v2eX = vertex2.x; + var v2eY = vertex2.y; + var v2eZ = vertex2.z; + var v3eX = vertex3.x; + var v3eY = vertex3.y; + var v3eZ = vertex3.z; + var _tempV30eX = CollisionUtils._tempV30.x; + var _tempV30eY = CollisionUtils._tempV30.y; + var _tempV30eZ = CollisionUtils._tempV30.z; + _tempV30eX = v2eX - v1eX; + _tempV30eY = v2eY - v1eY; + _tempV30eZ = v2eZ - v1eZ; + var _tempV31eX = CollisionUtils._tempV31.x; + var _tempV31eY = CollisionUtils._tempV31.y; + var _tempV31eZ = CollisionUtils._tempV31.z; + _tempV31eX = v3eX - v1eX; + _tempV31eY = v3eY - v1eY; + _tempV31eZ = v3eZ - v1eZ; + var _tempV32eX = CollisionUtils._tempV32.x; + var _tempV32eY = CollisionUtils._tempV32.y; + var _tempV32eZ = CollisionUtils._tempV32.z; + _tempV32eX = (rayDeY * _tempV31eZ) - (rayDeZ * _tempV31eY); + _tempV32eY = (rayDeZ * _tempV31eX) - (rayDeX * _tempV31eZ); + _tempV32eZ = (rayDeX * _tempV31eY) - (rayDeY * _tempV31eX); + var determinant = (_tempV30eX * _tempV32eX) + (_tempV30eY * _tempV32eY) + (_tempV30eZ * _tempV32eZ); + if (MathUtils3D.isZero(determinant)) { + return false; + } + var inversedeterminant = 1 / determinant; + var _tempV33eX = CollisionUtils._tempV33.x; + var _tempV33eY = CollisionUtils._tempV33.y; + var _tempV33eZ = CollisionUtils._tempV33.z; + _tempV33eX = rayOeX - v1eX; + _tempV33eY = rayOeY - v1eY; + _tempV33eZ = rayOeZ - v1eZ; + var triangleU = (_tempV33eX * _tempV32eX) + (_tempV33eY * _tempV32eY) + (_tempV33eZ * _tempV32eZ); + triangleU *= inversedeterminant; + if (triangleU < 0 || triangleU > 1) { + return false; + } + var _tempV34eX = CollisionUtils._tempV34.x; + var _tempV34eY = CollisionUtils._tempV34.y; + var _tempV34eZ = CollisionUtils._tempV34.z; + _tempV34eX = (_tempV33eY * _tempV30eZ) - (_tempV33eZ * _tempV30eY); + _tempV34eY = (_tempV33eZ * _tempV30eX) - (_tempV33eX * _tempV30eZ); + _tempV34eZ = (_tempV33eX * _tempV30eY) - (_tempV33eY * _tempV30eX); + var triangleV = ((rayDeX * _tempV34eX) + (rayDeY * _tempV34eY)) + (rayDeZ * _tempV34eZ); + triangleV *= inversedeterminant; + if (triangleV < 0 || triangleU + triangleV > 1) { + return false; + } + var raydistance = (_tempV31eX * _tempV34eX) + (_tempV31eY * _tempV34eY) + (_tempV31eZ * _tempV34eZ); + raydistance *= inversedeterminant; + if (raydistance < 0) { + return false; + } + return true; + } + static intersectsRayAndTriangleRP(ray, vertex1, vertex2, vertex3, out) { + var distance; + if (!CollisionUtils.intersectsRayAndTriangleRD(ray, vertex1, vertex2, vertex3, distance)) { + out = Vector3._ZERO; + return false; + } + Vector3.scale(ray.direction, distance, CollisionUtils._tempV30); + Vector3.add(ray.origin, CollisionUtils._tempV30, out); + return true; + } + static intersectsRayAndPoint(ray, point) { + Vector3.subtract(ray.origin, point, CollisionUtils._tempV30); + var b = Vector3.dot(CollisionUtils._tempV30, ray.direction); + var c = Vector3.dot(CollisionUtils._tempV30, CollisionUtils._tempV30) - MathUtils3D.zeroTolerance; + if (c > 0 && b > 0) + return false; + var discriminant = b * b - c; + if (discriminant < 0) + return false; + return true; + } + static intersectsRayAndRay(ray1, ray2, out) { + var ray1o = ray1.origin; + var ray1oeX = ray1o.x; + var ray1oeY = ray1o.y; + var ray1oeZ = ray1o.z; + var ray1d = ray1.direction; + var ray1deX = ray1d.x; + var ray1deY = ray1d.y; + var ray1deZ = ray1d.z; + var ray2o = ray2.origin; + var ray2oeX = ray2o.x; + var ray2oeY = ray2o.y; + var ray2oeZ = ray2o.z; + var ray2d = ray2.direction; + var ray2deX = ray2d.x; + var ray2deY = ray2d.y; + var ray2deZ = ray2d.z; + Vector3.cross(ray1d, ray2d, CollisionUtils._tempV30); + var tempV3 = CollisionUtils._tempV30; + var denominator = Vector3.scalarLength(CollisionUtils._tempV30); + if (MathUtils3D.isZero(denominator)) { + if (MathUtils3D.nearEqual(ray2oeX, ray1oeX) && MathUtils3D.nearEqual(ray2oeY, ray1oeY) && MathUtils3D.nearEqual(ray2oeZ, ray1oeZ)) { + return true; + } + } + denominator = denominator * denominator; + var m11 = ray2oeX - ray1oeX; + var m12 = ray2oeY - ray1oeY; + var m13 = ray2oeZ - ray1oeZ; + var m21 = ray2deX; + var m22 = ray2deY; + var m23 = ray2deZ; + var m31 = tempV3.x; + var m32 = tempV3.y; + var m33 = tempV3.z; + var dets = m11 * m22 * m33 + m12 * m23 * m31 + m13 * m21 * m32 - m11 * m23 * m32 - m12 * m21 * m33 - m13 * m22 * m31; + m21 = ray1deX; + m22 = ray1deY; + m23 = ray1deZ; + var s = dets / denominator; + Vector3.scale(ray1d, s, CollisionUtils._tempV30); + Vector3.scale(ray2d, s, CollisionUtils._tempV31); + Vector3.add(ray1o, CollisionUtils._tempV30, CollisionUtils._tempV32); + Vector3.add(ray2o, CollisionUtils._tempV31, CollisionUtils._tempV33); + var point1e = CollisionUtils._tempV32; + var point2e = CollisionUtils._tempV33; + if (!MathUtils3D.nearEqual(point2e.x, point1e.x) || !MathUtils3D.nearEqual(point2e.y, point1e.y) || !MathUtils3D.nearEqual(point2e.z, point1e.z)) { + return false; + } + return true; + } + static intersectsPlaneAndTriangle(plane, vertex1, vertex2, vertex3) { + var test1 = CollisionUtils.intersectsPlaneAndPoint(plane, vertex1); + var test2 = CollisionUtils.intersectsPlaneAndPoint(plane, vertex2); + var test3 = CollisionUtils.intersectsPlaneAndPoint(plane, vertex3); + if (test1 == Plane.PlaneIntersectionType_Front && test2 == Plane.PlaneIntersectionType_Front && test3 == Plane.PlaneIntersectionType_Front) + return Plane.PlaneIntersectionType_Front; + if (test1 == Plane.PlaneIntersectionType_Back && test2 == Plane.PlaneIntersectionType_Back && test3 == Plane.PlaneIntersectionType_Back) + return Plane.PlaneIntersectionType_Back; + return Plane.PlaneIntersectionType_Intersecting; + } + static intersectsRayAndPlaneRD(ray, plane) { + var planeNor = plane.normal; + var direction = Vector3.dot(planeNor, ray.direction); + if (Math.abs(direction) < MathUtils3D.zeroTolerance) + return -1; + var position = Vector3.dot(planeNor, ray.origin); + var distance = (-plane.distance - position) / direction; + if (distance < 0) { + if (distance < -MathUtils3D.zeroTolerance) + return -1; + distance = 0; + } + return distance; + } + static intersectsRayAndPlaneRP(ray, plane, out) { + var distance = CollisionUtils.intersectsRayAndPlaneRD(ray, plane); + if (distance == -1) { + out.setValue(0, 0, 0); + return false; + } + var scaDis = CollisionUtils._tempV30; + Vector3.scale(ray.direction, distance, scaDis); + Vector3.add(ray.origin, scaDis, out); + return true; + } + static intersectsRayAndBoxRD(ray, box) { + var rayoe = ray.origin; + var rayoeX = rayoe.x; + var rayoeY = rayoe.y; + var rayoeZ = rayoe.z; + var rayde = ray.direction; + var raydeX = rayde.x; + var raydeY = rayde.y; + var raydeZ = rayde.z; + var boxMine = box.min; + var boxMineX = boxMine.x; + var boxMineY = boxMine.y; + var boxMineZ = boxMine.z; + var boxMaxe = box.max; + var boxMaxeX = boxMaxe.x; + var boxMaxeY = boxMaxe.y; + var boxMaxeZ = boxMaxe.z; + var out = 0; + var tmax = MathUtils3D.MaxValue; + if (MathUtils3D.isZero(raydeX)) { + if (rayoeX < boxMineX || rayoeX > boxMaxeX) { + return -1; + } + } + else { + var inverse = 1 / raydeX; + var t1 = (boxMineX - rayoeX) * inverse; + var t2 = (boxMaxeX - rayoeX) * inverse; + if (t1 > t2) { + var temp = t1; + t1 = t2; + t2 = temp; + } + out = Math.max(t1, out); + tmax = Math.min(t2, tmax); + if (out > tmax) { + return -1; + } + } + if (MathUtils3D.isZero(raydeY)) { + if (rayoeY < boxMineY || rayoeY > boxMaxeY) { + return -1; + } + } + else { + var inverse1 = 1 / raydeY; + var t3 = (boxMineY - rayoeY) * inverse1; + var t4 = (boxMaxeY - rayoeY) * inverse1; + if (t3 > t4) { + var temp1 = t3; + t3 = t4; + t4 = temp1; + } + out = Math.max(t3, out); + tmax = Math.min(t4, tmax); + if (out > tmax) { + return -1; + } + } + if (MathUtils3D.isZero(raydeZ)) { + if (rayoeZ < boxMineZ || rayoeZ > boxMaxeZ) { + return -1; + } + } + else { + var inverse2 = 1 / raydeZ; + var t5 = (boxMineZ - rayoeZ) * inverse2; + var t6 = (boxMaxeZ - rayoeZ) * inverse2; + if (t5 > t6) { + var temp2 = t5; + t5 = t6; + t6 = temp2; + } + out = Math.max(t5, out); + tmax = Math.min(t6, tmax); + if (out > tmax) { + return -1; + } + } + return out; + } + static intersectsRayAndBoxRP(ray, box, out) { + var distance = CollisionUtils.intersectsRayAndBoxRD(ray, box); + if (distance === -1) { + Vector3._ZERO.cloneTo(out); + return distance; + } + Vector3.scale(ray.direction, distance, CollisionUtils._tempV30); + Vector3.add(ray.origin, CollisionUtils._tempV30, CollisionUtils._tempV31); + CollisionUtils._tempV31.cloneTo(out); + return distance; + } + static intersectsRayAndSphereRD(ray, sphere) { + var sphereR = sphere.radius; + Vector3.subtract(ray.origin, sphere.center, CollisionUtils._tempV30); + var b = Vector3.dot(CollisionUtils._tempV30, ray.direction); + var c = Vector3.dot(CollisionUtils._tempV30, CollisionUtils._tempV30) - (sphereR * sphereR); + if (c > 0 && b > 0) { + return -1; + } + var discriminant = b * b - c; + if (discriminant < 0) { + return -1; + } + var distance = -b - Math.sqrt(discriminant); + if (distance < 0) + distance = 0; + return distance; + } + static intersectsRayAndSphereRP(ray, sphere, out) { + var distance = CollisionUtils.intersectsRayAndSphereRD(ray, sphere); + if (distance === -1) { + Vector3._ZERO.cloneTo(out); + return distance; + } + Vector3.scale(ray.direction, distance, CollisionUtils._tempV30); + Vector3.add(ray.origin, CollisionUtils._tempV30, CollisionUtils._tempV31); + CollisionUtils._tempV31.cloneTo(out); + return distance; + } + static intersectsSphereAndTriangle(sphere, vertex1, vertex2, vertex3) { + var sphereC = sphere.center; + var sphereR = sphere.radius; + CollisionUtils.closestPointPointTriangle(sphereC, vertex1, vertex2, vertex3, CollisionUtils._tempV30); + Vector3.subtract(CollisionUtils._tempV30, sphereC, CollisionUtils._tempV31); + var dot = Vector3.dot(CollisionUtils._tempV31, CollisionUtils._tempV31); + return dot <= sphereR * sphereR; + } + static intersectsPlaneAndPoint(plane, point) { + var distance = Vector3.dot(plane.normal, point) + plane.distance; + if (distance > 0) + return Plane.PlaneIntersectionType_Front; + if (distance < 0) + return Plane.PlaneIntersectionType_Back; + return Plane.PlaneIntersectionType_Intersecting; + } + static intersectsPlaneAndPlane(plane1, plane2) { + Vector3.cross(plane1.normal, plane2.normal, CollisionUtils._tempV30); + var denominator = Vector3.dot(CollisionUtils._tempV30, CollisionUtils._tempV30); + if (MathUtils3D.isZero(denominator)) + return false; + return true; + } + static intersectsPlaneAndPlaneRL(plane1, plane2, line) { + var plane1nor = plane1.normal; + var plane2nor = plane2.normal; + Vector3.cross(plane1nor, plane2nor, CollisionUtils._tempV34); + var denominator = Vector3.dot(CollisionUtils._tempV34, CollisionUtils._tempV34); + if (MathUtils3D.isZero(denominator)) + return false; + Vector3.scale(plane2nor, plane1.distance, CollisionUtils._tempV30); + Vector3.scale(plane1nor, plane2.distance, CollisionUtils._tempV31); + Vector3.subtract(CollisionUtils._tempV30, CollisionUtils._tempV31, CollisionUtils._tempV32); + Vector3.cross(CollisionUtils._tempV32, CollisionUtils._tempV34, CollisionUtils._tempV33); + Vector3.normalize(CollisionUtils._tempV34, CollisionUtils._tempV34); + return true; + } + static intersectsPlaneAndBox(plane, box) { + var planeD = plane.distance; + var planeNor = plane.normal; + var planeNoreX = planeNor.x; + var planeNoreY = planeNor.y; + var planeNoreZ = planeNor.z; + var boxMine = box.min; + var boxMineX = boxMine.x; + var boxMineY = boxMine.y; + var boxMineZ = boxMine.z; + var boxMaxe = box.max; + var boxMaxeX = boxMaxe.x; + var boxMaxeY = boxMaxe.y; + var boxMaxeZ = boxMaxe.z; + CollisionUtils._tempV30.x = (planeNoreX > 0) ? boxMineX : boxMaxeX; + CollisionUtils._tempV30.y = (planeNoreY > 0) ? boxMineY : boxMaxeY; + CollisionUtils._tempV30.z = (planeNoreZ > 0) ? boxMineZ : boxMaxeZ; + CollisionUtils._tempV31.x = (planeNoreX > 0) ? boxMaxeX : boxMineX; + CollisionUtils._tempV31.y = (planeNoreY > 0) ? boxMaxeY : boxMineY; + CollisionUtils._tempV31.z = (planeNoreZ > 0) ? boxMaxeZ : boxMineZ; + var distance = Vector3.dot(planeNor, CollisionUtils._tempV30); + if (distance + planeD > 0) + return Plane.PlaneIntersectionType_Front; + distance = Vector3.dot(planeNor, CollisionUtils._tempV31); + if (distance + planeD < 0) + return Plane.PlaneIntersectionType_Back; + return Plane.PlaneIntersectionType_Intersecting; + } + static intersectsPlaneAndSphere(plane, sphere) { + var sphereR = sphere.radius; + var distance = Vector3.dot(plane.normal, sphere.center) + plane.distance; + if (distance > sphereR) + return Plane.PlaneIntersectionType_Front; + if (distance < -sphereR) + return Plane.PlaneIntersectionType_Back; + return Plane.PlaneIntersectionType_Intersecting; + } + static intersectsBoxAndBox(box1, box2) { + var box1Mine = box1.min; + var box1Maxe = box1.max; + var box2Mine = box2.min; + var box2Maxe = box2.max; + if (box1Mine.x > box2Maxe.x || box2Mine.x > box1Maxe.x) + return false; + if (box1Mine.y > box2Maxe.y || box2Mine.y > box1Maxe.y) + return false; + if (box1Mine.z > box2Maxe.z || box2Mine.z > box1Maxe.z) + return false; + return true; + } + static intersectsBoxAndSphere(box, sphere) { + var center = sphere.center; + var radius = sphere.radius; + var nearest = CollisionUtils._tempV30; + Vector3.Clamp(center, box.min, box.max, nearest); + var distance = Vector3.distanceSquared(center, nearest); + return distance <= radius * radius; + } + static intersectsSphereAndSphere(sphere1, sphere2) { + var radiisum = sphere1.radius + sphere2.radius; + return Vector3.distanceSquared(sphere1.center, sphere2.center) <= radiisum * radiisum; + } + static boxContainsPoint(box, point) { + var boxMine = box.min; + var boxMaxe = box.max; + if (boxMine.x <= point.x && boxMaxe.x >= point.x && boxMine.y <= point.y && boxMaxe.y >= point.y && boxMine.z <= point.z && boxMaxe.z >= point.z) + return ContainmentType.Contains; + return ContainmentType.Disjoint; + } + static boxContainsBox(box1, box2) { + var box1Mine = box1.min; + var box1MineX = box1Mine.x; + var box1MineY = box1Mine.y; + var box1MineZ = box1Mine.z; + var box1Maxe = box1.max; + var box1MaxeX = box1Maxe.x; + var box1MaxeY = box1Maxe.y; + var box1MaxeZ = box1Maxe.z; + var box2Mine = box2.min; + var box2MineX = box2Mine.x; + var box2MineY = box2Mine.y; + var box2MineZ = box2Mine.z; + var box2Maxe = box2.max; + var box2MaxeX = box2Maxe.x; + var box2MaxeY = box2Maxe.y; + var box2MaxeZ = box2Maxe.z; + if (box1MaxeX < box2MineX || box1MineX > box2MaxeX) + return ContainmentType.Disjoint; + if (box1MaxeY < box2MineY || box1MineY > box2MaxeY) + return ContainmentType.Disjoint; + if (box1MaxeZ < box2MineZ || box1MineZ > box2MaxeZ) + return ContainmentType.Disjoint; + if (box1MineX <= box2MineX && box2MaxeX <= box1MaxeX && box1MineY <= box2MineY && box2MaxeY <= box1MaxeY && box1MineZ <= box2MineZ && box2MaxeZ <= box1MaxeZ) { + return ContainmentType.Contains; + } + return ContainmentType.Intersects; + } + static boxContainsSphere(box, sphere) { + var boxMin = box.min; + var boxMineX = boxMin.x; + var boxMineY = boxMin.y; + var boxMineZ = boxMin.z; + var boxMax = box.max; + var boxMaxeX = boxMax.x; + var boxMaxeY = boxMax.y; + var boxMaxeZ = boxMax.z; + var sphereC = sphere.center; + var sphereCeX = sphereC.x; + var sphereCeY = sphereC.y; + var sphereCeZ = sphereC.z; + var sphereR = sphere.radius; + Vector3.Clamp(sphereC, boxMin, boxMax, CollisionUtils._tempV30); + var distance = Vector3.distanceSquared(sphereC, CollisionUtils._tempV30); + if (distance > sphereR * sphereR) + return ContainmentType.Disjoint; + if ((((boxMineX + sphereR <= sphereCeX) && (sphereCeX <= boxMaxeX - sphereR)) && ((boxMaxeX - boxMineX > sphereR) && + (boxMineY + sphereR <= sphereCeY))) && (((sphereCeY <= boxMaxeY - sphereR) && (boxMaxeY - boxMineY > sphereR)) && + (((boxMineZ + sphereR <= sphereCeZ) && (sphereCeZ <= boxMaxeZ - sphereR)) && (boxMaxeZ - boxMineZ > sphereR)))) + return ContainmentType.Contains; + return ContainmentType.Intersects; + } + static sphereContainsPoint(sphere, point) { + if (Vector3.distanceSquared(point, sphere.center) <= sphere.radius * sphere.radius) + return ContainmentType.Contains; + return ContainmentType.Disjoint; + } + static sphereContainsTriangle(sphere, vertex1, vertex2, vertex3) { + var test1 = CollisionUtils.sphereContainsPoint(sphere, vertex1); + var test2 = CollisionUtils.sphereContainsPoint(sphere, vertex2); + var test3 = CollisionUtils.sphereContainsPoint(sphere, vertex3); + if (test1 == ContainmentType.Contains && test2 == ContainmentType.Contains && test3 == ContainmentType.Contains) + return ContainmentType.Contains; + if (CollisionUtils.intersectsSphereAndTriangle(sphere, vertex1, vertex2, vertex3)) + return ContainmentType.Intersects; + return ContainmentType.Disjoint; + } + static sphereContainsBox(sphere, box) { + var sphereC = sphere.center; + var sphereCeX = sphereC.x; + var sphereCeY = sphereC.y; + var sphereCeZ = sphereC.z; + var sphereR = sphere.radius; + var boxMin = box.min; + var boxMineX = boxMin.x; + var boxMineY = boxMin.y; + var boxMineZ = boxMin.z; + var boxMax = box.max; + var boxMaxeX = boxMax.x; + var boxMaxeY = boxMax.y; + var boxMaxeZ = boxMax.z; + var _tempV30e = CollisionUtils._tempV30; + var _tempV30eX = _tempV30e.x; + var _tempV30eY = _tempV30e.y; + var _tempV30eZ = _tempV30e.z; + if (!CollisionUtils.intersectsBoxAndSphere(box, sphere)) + return ContainmentType.Disjoint; + var radiusSquared = sphereR * sphereR; + _tempV30eX = sphereCeX - boxMineX; + _tempV30eY = sphereCeY - boxMaxeY; + _tempV30eZ = sphereCeZ - boxMaxeZ; + if (Vector3.scalarLengthSquared(CollisionUtils._tempV30) > radiusSquared) + return ContainmentType.Intersects; + _tempV30eX = sphereCeX - boxMaxeX; + _tempV30eY = sphereCeY - boxMaxeY; + _tempV30eZ = sphereCeZ - boxMaxeZ; + if (Vector3.scalarLengthSquared(CollisionUtils._tempV30) > radiusSquared) + return ContainmentType.Intersects; + _tempV30eX = sphereCeX - boxMaxeX; + _tempV30eY = sphereCeY - boxMineY; + _tempV30eZ = sphereCeZ - boxMaxeZ; + if (Vector3.scalarLengthSquared(CollisionUtils._tempV30) > radiusSquared) + return ContainmentType.Intersects; + _tempV30eX = sphereCeX - boxMineX; + _tempV30eY = sphereCeY - boxMineY; + _tempV30eZ = sphereCeZ - boxMaxeZ; + if (Vector3.scalarLengthSquared(CollisionUtils._tempV30) > radiusSquared) + return ContainmentType.Intersects; + _tempV30eX = sphereCeX - boxMineX; + _tempV30eY = sphereCeY - boxMaxeY; + _tempV30eZ = sphereCeZ - boxMineZ; + if (Vector3.scalarLengthSquared(CollisionUtils._tempV30) > radiusSquared) + return ContainmentType.Intersects; + _tempV30eX = sphereCeX - boxMaxeX; + _tempV30eY = sphereCeY - boxMaxeY; + _tempV30eZ = sphereCeZ - boxMineZ; + if (Vector3.scalarLengthSquared(CollisionUtils._tempV30) > radiusSquared) + return ContainmentType.Intersects; + _tempV30eX = sphereCeX - boxMaxeX; + _tempV30eY = sphereCeY - boxMineY; + _tempV30eZ = sphereCeZ - boxMineZ; + if (Vector3.scalarLengthSquared(CollisionUtils._tempV30) > radiusSquared) + return ContainmentType.Intersects; + _tempV30eX = sphereCeX - boxMineX; + _tempV30eY = sphereCeY - boxMineY; + _tempV30eZ = sphereCeZ - boxMineZ; + if (Vector3.scalarLengthSquared(CollisionUtils._tempV30) > radiusSquared) + return ContainmentType.Intersects; + return ContainmentType.Contains; + } + static sphereContainsSphere(sphere1, sphere2) { + var sphere1R = sphere1.radius; + var sphere2R = sphere2.radius; + var distance = Vector3.distance(sphere1.center, sphere2.center); + if (sphere1R + sphere2R < distance) + return ContainmentType.Disjoint; + if (sphere1R - sphere2R < distance) + return ContainmentType.Intersects; + return ContainmentType.Contains; + } + static closestPointPointTriangle(point, vertex1, vertex2, vertex3, out) { + Vector3.subtract(vertex2, vertex1, CollisionUtils._tempV30); + Vector3.subtract(vertex3, vertex1, CollisionUtils._tempV31); + Vector3.subtract(point, vertex1, CollisionUtils._tempV32); + Vector3.subtract(point, vertex2, CollisionUtils._tempV33); + Vector3.subtract(point, vertex3, CollisionUtils._tempV34); + var d1 = Vector3.dot(CollisionUtils._tempV30, CollisionUtils._tempV32); + var d2 = Vector3.dot(CollisionUtils._tempV31, CollisionUtils._tempV32); + var d3 = Vector3.dot(CollisionUtils._tempV30, CollisionUtils._tempV33); + var d4 = Vector3.dot(CollisionUtils._tempV31, CollisionUtils._tempV33); + var d5 = Vector3.dot(CollisionUtils._tempV30, CollisionUtils._tempV34); + var d6 = Vector3.dot(CollisionUtils._tempV31, CollisionUtils._tempV34); + if (d1 <= 0 && d2 <= 0) { + vertex1.cloneTo(out); + return; + } + if (d3 >= 0 && d4 <= d3) { + vertex2.cloneTo(out); + return; + } + var vc = d1 * d4 - d3 * d2; + if (vc <= 0 && d1 >= 0 && d3 <= 0) { + var v = d1 / (d1 - d3); + Vector3.scale(CollisionUtils._tempV30, v, out); + Vector3.add(vertex1, out, out); + return; + } + if (d6 >= 0 && d5 <= d6) { + vertex3.cloneTo(out); + return; + } + var vb = d5 * d2 - d1 * d6; + if (vb <= 0 && d2 >= 0 && d6 <= 0) { + var w = d2 / (d2 - d6); + Vector3.scale(CollisionUtils._tempV31, w, out); + Vector3.add(vertex1, out, out); + return; + } + var va = d3 * d6 - d5 * d4; + if (va <= 0 && (d4 - d3) >= 0 && (d5 - d6) >= 0) { + var w3 = (d4 - d3) / ((d4 - d3) + (d5 - d6)); + Vector3.subtract(vertex3, vertex2, out); + Vector3.scale(out, w3, out); + Vector3.add(vertex2, out, out); + return; + } + var denom = 1 / (va + vb + vc); + var v2 = vb * denom; + var w2 = vc * denom; + Vector3.scale(CollisionUtils._tempV30, v2, CollisionUtils._tempV35); + Vector3.scale(CollisionUtils._tempV31, w2, CollisionUtils._tempV36); + Vector3.add(CollisionUtils._tempV35, CollisionUtils._tempV36, out); + Vector3.add(vertex1, out, out); + } + static closestPointPlanePoint(plane, point, out) { + var planeN = plane.normal; + var t = Vector3.dot(planeN, point) - plane.distance; + Vector3.scale(planeN, t, CollisionUtils._tempV30); + Vector3.subtract(point, CollisionUtils._tempV30, out); + } + static closestPointBoxPoint(box, point, out) { + Vector3.max(point, box.min, CollisionUtils._tempV30); + Vector3.min(CollisionUtils._tempV30, box.max, out); + } + static closestPointSpherePoint(sphere, point, out) { + var sphereC = sphere.center; + Vector3.subtract(point, sphereC, out); + Vector3.normalize(out, out); + Vector3.scale(out, sphere.radius, out); + Vector3.add(out, sphereC, out); + } + static closestPointSphereSphere(sphere1, sphere2, out) { + var sphere1C = sphere1.center; + Vector3.subtract(sphere2.center, sphere1C, out); + Vector3.normalize(out, out); + Vector3.scale(out, sphere1.radius, out); + Vector3.add(out, sphere1C, out); + } + } + CollisionUtils._tempV30 = new Vector3(); + CollisionUtils._tempV31 = new Vector3(); + CollisionUtils._tempV32 = new Vector3(); + CollisionUtils._tempV33 = new Vector3(); + CollisionUtils._tempV34 = new Vector3(); + CollisionUtils._tempV35 = new Vector3(); + CollisionUtils._tempV36 = new Vector3(); + + (function (FrustumCorner) { + FrustumCorner[FrustumCorner["FarBottomLeft"] = 0] = "FarBottomLeft"; + FrustumCorner[FrustumCorner["FarTopLeft"] = 1] = "FarTopLeft"; + FrustumCorner[FrustumCorner["FarTopRight"] = 2] = "FarTopRight"; + FrustumCorner[FrustumCorner["FarBottomRight"] = 3] = "FarBottomRight"; + FrustumCorner[FrustumCorner["nearBottomLeft"] = 4] = "nearBottomLeft"; + FrustumCorner[FrustumCorner["nearTopLeft"] = 5] = "nearTopLeft"; + FrustumCorner[FrustumCorner["nearTopRight"] = 6] = "nearTopRight"; + FrustumCorner[FrustumCorner["nearBottomRight"] = 7] = "nearBottomRight"; + FrustumCorner[FrustumCorner["unknown"] = 8] = "unknown"; + })(exports.FrustumCorner || (exports.FrustumCorner = {})); + class BoundFrustum { + constructor(matrix) { + this._matrix = matrix; + this._near = new Plane(new Vector3()); + this._far = new Plane(new Vector3()); + this._left = new Plane(new Vector3()); + this._right = new Plane(new Vector3()); + this._top = new Plane(new Vector3()); + this._bottom = new Plane(new Vector3()); + BoundFrustum.getPlanesFromMatrix(this._matrix, this._near, this._far, this._left, this._right, this._top, this._bottom); + } + static getPlanesFromMatrix(m, np, fp, lp, rp, tp, bp) { + var matrixE = m.elements; + var m11 = matrixE[0]; + var m12 = matrixE[1]; + var m13 = matrixE[2]; + var m14 = matrixE[3]; + var m21 = matrixE[4]; + var m22 = matrixE[5]; + var m23 = matrixE[6]; + var m24 = matrixE[7]; + var m31 = matrixE[8]; + var m32 = matrixE[9]; + var m33 = matrixE[10]; + var m34 = matrixE[11]; + var m41 = matrixE[12]; + var m42 = matrixE[13]; + var m43 = matrixE[14]; + var m44 = matrixE[15]; + var nearNorE = np.normal; + nearNorE.x = m13; + nearNorE.y = m23; + nearNorE.z = m33; + np.distance = m43; + np.normalize(); + var farNorE = fp.normal; + farNorE.x = m14 - m13; + farNorE.y = m24 - m23; + farNorE.z = m34 - m33; + fp.distance = m44 - m43; + fp.normalize(); + var leftNorE = lp.normal; + leftNorE.x = m14 + m11; + leftNorE.y = m24 + m21; + leftNorE.z = m34 + m31; + lp.distance = m44 + m41; + lp.normalize(); + var rightNorE = rp.normal; + rightNorE.x = m14 - m11; + rightNorE.y = m24 - m21; + rightNorE.z = m34 - m31; + rp.distance = m44 - m41; + rp.normalize(); + var topNorE = tp.normal; + topNorE.x = m14 - m12; + topNorE.y = m24 - m22; + topNorE.z = m34 - m32; + tp.distance = m44 - m42; + tp.normalize(); + var bottomNorE = bp.normal; + bottomNorE.x = m14 + m12; + bottomNorE.y = m24 + m22; + bottomNorE.z = m34 + m32; + bp.distance = m44 + m42; + bp.normalize(); + } + get matrix() { + return this._matrix; + } + set matrix(matrix) { + matrix.cloneTo(this._matrix); + BoundFrustum.getPlanesFromMatrix(this._matrix, this._near, this._far, this._left, this._right, this._top, this._bottom); + } + get near() { + return this._near; + } + get far() { + return this._far; + } + get left() { + return this._left; + } + get right() { + return this._right; + } + get top() { + return this._top; + } + get bottom() { + return this._bottom; + } + equalsBoundFrustum(other) { + return this._matrix.equalsOtherMatrix(other.matrix); + } + equalsObj(obj) { + if (obj instanceof BoundFrustum) { + var bf = obj; + return this.equalsBoundFrustum(bf); + } + return false; + } + getPlane(index) { + switch (index) { + case 0: + return this._near; + case 1: + return this._far; + case 2: + return this._left; + case 3: + return this._right; + case 4: + return this._top; + case 5: + return this._bottom; + default: + return null; + } + } + static get3PlaneInterPoint(p1, p2, p3, out) { + var p1Nor = p1.normal; + var p2Nor = p2.normal; + var p3Nor = p3.normal; + Vector3.cross(p2Nor, p3Nor, BoundFrustum._tempV30); + Vector3.cross(p3Nor, p1Nor, BoundFrustum._tempV31); + Vector3.cross(p1Nor, p2Nor, BoundFrustum._tempV32); + var a = Vector3.dot(p1Nor, BoundFrustum._tempV30); + var b = Vector3.dot(p2Nor, BoundFrustum._tempV31); + var c = Vector3.dot(p3Nor, BoundFrustum._tempV32); + Vector3.scale(BoundFrustum._tempV30, -p1.distance / a, BoundFrustum._tempV33); + Vector3.scale(BoundFrustum._tempV31, -p2.distance / b, BoundFrustum._tempV34); + Vector3.scale(BoundFrustum._tempV32, -p3.distance / c, BoundFrustum._tempV35); + Vector3.add(BoundFrustum._tempV33, BoundFrustum._tempV34, BoundFrustum._tempV36); + Vector3.add(BoundFrustum._tempV35, BoundFrustum._tempV36, out); + } + getCorners(corners) { + BoundFrustum.get3PlaneInterPoint(this._near, this._bottom, this._right, corners[exports.FrustumCorner.nearBottomRight]); + BoundFrustum.get3PlaneInterPoint(this._near, this._top, this._right, corners[exports.FrustumCorner.nearTopRight]); + BoundFrustum.get3PlaneInterPoint(this._near, this._top, this._left, corners[exports.FrustumCorner.nearTopLeft]); + BoundFrustum.get3PlaneInterPoint(this._near, this._bottom, this._left, corners[exports.FrustumCorner.nearBottomLeft]); + BoundFrustum.get3PlaneInterPoint(this._far, this._bottom, this._right, corners[exports.FrustumCorner.FarBottomRight]); + BoundFrustum.get3PlaneInterPoint(this._far, this._top, this._right, corners[exports.FrustumCorner.FarTopRight]); + BoundFrustum.get3PlaneInterPoint(this._far, this._top, this._left, corners[exports.FrustumCorner.FarTopLeft]); + BoundFrustum.get3PlaneInterPoint(this._far, this._bottom, this._left, corners[exports.FrustumCorner.FarBottomLeft]); + } + containsPoint(point) { + var result = Plane.PlaneIntersectionType_Front; + var planeResult = Plane.PlaneIntersectionType_Front; + for (var i = 0; i < 6; i++) { + switch (i) { + case 0: + planeResult = CollisionUtils.intersectsPlaneAndPoint(this._near, point); + break; + case 1: + planeResult = CollisionUtils.intersectsPlaneAndPoint(this._far, point); + break; + case 2: + planeResult = CollisionUtils.intersectsPlaneAndPoint(this._left, point); + break; + case 3: + planeResult = CollisionUtils.intersectsPlaneAndPoint(this._right, point); + break; + case 4: + planeResult = CollisionUtils.intersectsPlaneAndPoint(this._top, point); + break; + case 5: + planeResult = CollisionUtils.intersectsPlaneAndPoint(this._bottom, point); + break; + } + switch (planeResult) { + case Plane.PlaneIntersectionType_Back: + return ContainmentType.Disjoint; + case Plane.PlaneIntersectionType_Intersecting: + result = Plane.PlaneIntersectionType_Intersecting; + break; + } + } + switch (result) { + case Plane.PlaneIntersectionType_Intersecting: + return ContainmentType.Intersects; + default: + return ContainmentType.Contains; + } + } + intersects(box) { + var min = box.min; + var max = box.max; + var minX = min.x; + var minY = min.y; + var minZ = min.z; + var maxX = max.x; + var maxY = max.y; + var maxZ = max.z; + var nearNormal = this._near.normal; + if (this._near.distance + (nearNormal.x * (nearNormal.x < 0 ? minX : maxX)) + (nearNormal.y * (nearNormal.y < 0 ? minY : maxY)) + (nearNormal.z * (nearNormal.z < 0 ? minZ : maxZ)) < 0) + return false; + var leftNormal = this._left.normal; + if (this._left.distance + (leftNormal.x * (leftNormal.x < 0 ? minX : maxX)) + (leftNormal.y * (leftNormal.y < 0 ? minY : maxY)) + (leftNormal.z * (leftNormal.z < 0 ? minZ : maxZ)) < 0) + return false; + var rightNormal = this._right.normal; + if (this._right.distance + (rightNormal.x * (rightNormal.x < 0 ? minX : maxX)) + (rightNormal.y * (rightNormal.y < 0 ? minY : maxY)) + (rightNormal.z * (rightNormal.z < 0 ? minZ : maxZ)) < 0) + return false; + var bottomNormal = this._bottom.normal; + if (this._bottom.distance + (bottomNormal.x * (bottomNormal.x < 0 ? minX : maxX)) + (bottomNormal.y * (bottomNormal.y < 0 ? minY : maxY)) + (bottomNormal.z * (bottomNormal.z < 0 ? minZ : maxZ)) < 0) + return false; + var topNormal = this._top.normal; + if (this._top.distance + (topNormal.x * (topNormal.x < 0 ? minX : maxX)) + (topNormal.y * (topNormal.y < 0 ? minY : maxY)) + (topNormal.z * (topNormal.z < 0 ? minZ : maxZ)) < 0) + return false; + var farNormal = this._far.normal; + if (this._far.distance + (farNormal.x * (farNormal.x < 0 ? minX : maxX)) + (farNormal.y * (farNormal.y < 0 ? minY : maxY)) + (farNormal.z * (farNormal.z < 0 ? minZ : maxZ)) < 0) + return false; + return true; + } + containsBoundBox(box) { + var p = BoundFrustum._tempV30, n = BoundFrustum._tempV31; + var boxMin = box.min; + var boxMax = box.max; + var result = ContainmentType.Contains; + for (var i = 0; i < 6; i++) { + var plane = this.getPlane(i); + var planeNor = plane.normal; + if (planeNor.x >= 0) { + p.x = boxMax.x; + n.x = boxMin.x; + } + else { + p.x = boxMin.x; + n.x = boxMax.x; + } + if (planeNor.y >= 0) { + p.y = boxMax.y; + n.y = boxMin.y; + } + else { + p.y = boxMin.y; + n.y = boxMax.y; + } + if (planeNor.z >= 0) { + p.z = boxMax.z; + n.z = boxMin.z; + } + else { + p.z = boxMin.z; + n.z = boxMax.z; + } + if (CollisionUtils.intersectsPlaneAndPoint(plane, p) === Plane.PlaneIntersectionType_Back) + return ContainmentType.Disjoint; + if (CollisionUtils.intersectsPlaneAndPoint(plane, n) === Plane.PlaneIntersectionType_Back) + result = ContainmentType.Intersects; + } + return result; + } + containsBoundSphere(sphere) { + var result = Plane.PlaneIntersectionType_Front; + var planeResult = Plane.PlaneIntersectionType_Front; + for (var i = 0; i < 6; i++) { + switch (i) { + case 0: + planeResult = CollisionUtils.intersectsPlaneAndSphere(this._near, sphere); + break; + case 1: + planeResult = CollisionUtils.intersectsPlaneAndSphere(this._far, sphere); + break; + case 2: + planeResult = CollisionUtils.intersectsPlaneAndSphere(this._left, sphere); + break; + case 3: + planeResult = CollisionUtils.intersectsPlaneAndSphere(this._right, sphere); + break; + case 4: + planeResult = CollisionUtils.intersectsPlaneAndSphere(this._top, sphere); + break; + case 5: + planeResult = CollisionUtils.intersectsPlaneAndSphere(this._bottom, sphere); + break; + } + switch (planeResult) { + case Plane.PlaneIntersectionType_Back: + return ContainmentType.Disjoint; + case Plane.PlaneIntersectionType_Intersecting: + result = Plane.PlaneIntersectionType_Intersecting; + break; + } + } + switch (result) { + case Plane.PlaneIntersectionType_Intersecting: + return ContainmentType.Intersects; + default: + return ContainmentType.Contains; + } + } + } + BoundFrustum._tempV30 = new Vector3(); + BoundFrustum._tempV31 = new Vector3(); + BoundFrustum._tempV32 = new Vector3(); + BoundFrustum._tempV33 = new Vector3(); + BoundFrustum._tempV34 = new Vector3(); + BoundFrustum._tempV35 = new Vector3(); + BoundFrustum._tempV36 = new Vector3(); + + class Viewport { + constructor(x, y, width, height) { + this.minDepth = 0.0; + this.maxDepth = 1.0; + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + project(source, matrix, out) { + Vector3.transformV3ToV4(source, matrix, out); + var x = out.x, y = out.y, z = out.z; + var w = out.w; + if (w !== 1.0) { + x = x / w; + y = y / w; + z = z / w; + } + out.x = (x + 1.0) * 0.5 * this.width + this.x; + out.y = (-y + 1.0) * 0.5 * this.height + this.y; + out.z = z * (this.maxDepth - this.minDepth) + this.minDepth; + } + unprojectFromMat(source, matrix, out) { + var matrixEleme = matrix.elements; + out.x = (((source.x - this.x) / this.width) * 2.0) - 1.0; + out.y = -((((source.y - this.y) / this.height) * 2.0) - 1.0); + out.z = (source.z - this.minDepth) / (this.maxDepth - this.minDepth); + var a = (((out.x * matrixEleme[3]) + (out.y * matrixEleme[7])) + (out.z * matrixEleme[11])) + matrixEleme[15]; + Vector3.transformV3ToV3(out, matrix, out); + if (a !== 1.0) { + out.x = out.x / a; + out.y = out.y / a; + out.z = out.z / a; + } + } + unprojectFromWVP(source, projection, view, world, out) { + Matrix4x4.multiply(projection, view, Viewport._tempMatrix4x4); + (world) && (Matrix4x4.multiply(Viewport._tempMatrix4x4, world, Viewport._tempMatrix4x4)); + Viewport._tempMatrix4x4.invert(Viewport._tempMatrix4x4); + this.unprojectFromMat(source, Viewport._tempMatrix4x4, out); + } + cloneTo(out) { + out.x = this.x; + out.y = this.y; + out.width = this.width; + out.height = this.height; + out.minDepth = this.minDepth; + out.maxDepth = this.maxDepth; + } + } + Viewport._tempMatrix4x4 = new Matrix4x4(); + + class Picker { + constructor() { + } + static calculateCursorRay(point, viewPort, projectionMatrix, viewMatrix, world, out) { + var x = point.x; + var y = point.y; + var nearSource = Picker._tempVector30; + var nerSourceE = nearSource; + nerSourceE.x = x; + nerSourceE.y = y; + nerSourceE.z = viewPort.minDepth; + var farSource = Picker._tempVector31; + var farSourceE = farSource; + farSourceE.x = x; + farSourceE.y = y; + farSourceE.z = viewPort.maxDepth; + var nearPoint = out.origin; + var farPoint = Picker._tempVector32; + viewPort.unprojectFromWVP(nearSource, projectionMatrix, viewMatrix, world, nearPoint); + viewPort.unprojectFromWVP(farSource, projectionMatrix, viewMatrix, world, farPoint); + var outDire = out.direction; + outDire.x = farPoint.x - nearPoint.x; + outDire.y = farPoint.y - nearPoint.y; + outDire.z = farPoint.z - nearPoint.z; + Vector3.normalize(out.direction, out.direction); + } + static rayIntersectsTriangle(ray, vertex1, vertex2, vertex3) { + var result; + var edge1 = Picker._tempVector30, edge2 = Picker._tempVector31; + Vector3.subtract(vertex2, vertex1, edge1); + Vector3.subtract(vertex3, vertex1, edge2); + var directionCrossEdge2 = Picker._tempVector32; + Vector3.cross(ray.direction, edge2, directionCrossEdge2); + var determinant; + determinant = Vector3.dot(edge1, directionCrossEdge2); + if (determinant > -Number.MIN_VALUE && determinant < Number.MIN_VALUE) { + result = Number.NaN; + return result; + } + var inverseDeterminant = 1.0 / determinant; + var distanceVector = Picker._tempVector33; + Vector3.subtract(ray.origin, vertex1, distanceVector); + var triangleU; + triangleU = Vector3.dot(distanceVector, directionCrossEdge2); + triangleU *= inverseDeterminant; + if (triangleU < 0 || triangleU > 1) { + result = Number.NaN; + return result; + } + var distanceCrossEdge1 = Picker._tempVector34; + Vector3.cross(distanceVector, edge1, distanceCrossEdge1); + var triangleV; + triangleV = Vector3.dot(ray.direction, distanceCrossEdge1); + triangleV *= inverseDeterminant; + if (triangleV < 0 || triangleU + triangleV > 1) { + result = Number.NaN; + return result; + } + var rayDistance; + rayDistance = Vector3.dot(edge2, distanceCrossEdge1); + rayDistance *= inverseDeterminant; + if (rayDistance < 0) { + result = Number.NaN; + return result; + } + result = rayDistance; + return result; + } + } + Picker._tempVector30 = new Vector3(); + Picker._tempVector31 = new Vector3(); + Picker._tempVector32 = new Vector3(); + Picker._tempVector33 = new Vector3(); + Picker._tempVector34 = new Vector3(); + + (function (IndexFormat) { + IndexFormat[IndexFormat["UInt8"] = 0] = "UInt8"; + IndexFormat[IndexFormat["UInt16"] = 1] = "UInt16"; + IndexFormat[IndexFormat["UInt32"] = 2] = "UInt32"; + })(exports.IndexFormat || (exports.IndexFormat = {})); + + class IndexBuffer3D extends Laya.Buffer { + constructor(indexType, indexCount, bufferUsage = 0x88E4, canRead = false) { + super(); + this._indexType = indexType; + this._indexCount = indexCount; + this._bufferUsage = bufferUsage; + this._bufferType = Laya.LayaGL.instance.ELEMENT_ARRAY_BUFFER; + this._canRead = canRead; + switch (indexType) { + case exports.IndexFormat.UInt32: + this._indexTypeByteCount = 4; + break; + case exports.IndexFormat.UInt16: + this._indexTypeByteCount = 2; + break; + case exports.IndexFormat.UInt8: + this._indexTypeByteCount = 1; + break; + default: + throw new Error("unidentification index type."); + } + var byteLength = this._indexTypeByteCount * indexCount; + var curBufSta = Laya.BufferStateBase._curBindedBufferState; + this._byteLength = byteLength; + if (curBufSta) { + if (curBufSta._bindedIndexBuffer === this) { + Laya.LayaGL.instance.bufferData(this._bufferType, byteLength, this._bufferUsage); + } + else { + curBufSta.unBind(); + this.bind(); + Laya.LayaGL.instance.bufferData(this._bufferType, byteLength, this._bufferUsage); + curBufSta.bind(); + } + } + else { + this.bind(); + Laya.LayaGL.instance.bufferData(this._bufferType, byteLength, this._bufferUsage); + } + if (canRead) { + switch (indexType) { + case exports.IndexFormat.UInt32: + this._buffer = new Uint32Array(indexCount); + break; + case exports.IndexFormat.UInt16: + this._buffer = new Uint16Array(indexCount); + break; + case exports.IndexFormat.UInt8: + this._buffer = new Uint8Array(indexCount); + break; + } + } + } + get indexType() { + return this._indexType; + } + get indexTypeByteCount() { + return this._indexTypeByteCount; + } + get indexCount() { + return this._indexCount; + } + get canRead() { + return this._canRead; + } + _bindForVAO() { + if (Laya.BufferStateBase._curBindedBufferState) { + var gl = Laya.LayaGL.instance; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._glBuffer); + } + else { + throw "IndexBuffer3D: must bind current BufferState."; + } + } + bind() { + if (Laya.BufferStateBase._curBindedBufferState) { + throw "IndexBuffer3D: must unbind current BufferState."; + } + else { + if (Laya.Buffer._bindedIndexBuffer !== this._glBuffer) { + var gl = Laya.LayaGL.instance; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._glBuffer); + Laya.Buffer._bindedIndexBuffer = this._glBuffer; + return true; + } + else { + return false; + } + } + } + setData(data, bufferOffset = 0, dataStartIndex = 0, dataCount = 4294967295) { + var byteCount = this._indexTypeByteCount; + if (dataStartIndex !== 0 || dataCount !== 4294967295) { + switch (this._indexType) { + case exports.IndexFormat.UInt32: + data = new Uint32Array(data.buffer, dataStartIndex * byteCount, dataCount); + break; + case exports.IndexFormat.UInt16: + data = new Uint16Array(data.buffer, dataStartIndex * byteCount, dataCount); + break; + case exports.IndexFormat.UInt8: + data = new Uint8Array(data.buffer, dataStartIndex * byteCount, dataCount); + break; + } + } + var curBufSta = Laya.BufferStateBase._curBindedBufferState; + if (curBufSta) { + if (curBufSta._bindedIndexBuffer === this) { + Laya.LayaGL.instance.bufferSubData(this._bufferType, bufferOffset * byteCount, data); + } + else { + curBufSta.unBind(); + this.bind(); + Laya.LayaGL.instance.bufferSubData(this._bufferType, bufferOffset * byteCount, data); + curBufSta.bind(); + } + } + else { + this.bind(); + Laya.LayaGL.instance.bufferSubData(this._bufferType, bufferOffset * byteCount, data); + } + if (this._canRead) { + if (bufferOffset !== 0 || dataStartIndex !== 0 || dataCount !== 4294967295) { + var maxLength = this._buffer.length - bufferOffset; + if (dataCount > maxLength) + dataCount = maxLength; + for (var i = 0; i < dataCount; i++) + this._buffer[bufferOffset + i] = data[i]; + } + else { + this._buffer = data; + } + } + } + getData() { + if (this._canRead) + return this._buffer; + else + throw new Error("Can't read data from VertexBuffer with only write flag!"); + } + destroy() { + super.destroy(); + this._buffer = null; + this._byteLength = 0; + this._indexCount = 0; + } + } + + class SkyMesh { + constructor() { + } + _render(state) { + } + } + + class SkyBox extends SkyMesh { + constructor() { + super(); + var gl = Laya.LayaGL.instance; + var halfHeight = 1.0; + var halfWidth = 1.0; + var halfDepth = 1.0; + var vertices = new Float32Array([-halfDepth, halfHeight, -halfWidth, halfDepth, halfHeight, -halfWidth, halfDepth, halfHeight, halfWidth, -halfDepth, halfHeight, halfWidth, + -halfDepth, -halfHeight, -halfWidth, halfDepth, -halfHeight, -halfWidth, halfDepth, -halfHeight, halfWidth, -halfDepth, -halfHeight, halfWidth]); + var indices = new Uint8Array([ + 0, 1, 2, 2, 3, 0, + 4, 7, 6, 6, 5, 4, + 0, 3, 7, 7, 4, 0, + 1, 5, 6, 6, 2, 1, + 3, 2, 6, 6, 7, 3, + 0, 4, 5, 5, 1, 0 + ]); + var verDec = VertexMesh.getVertexDeclaration("POSITION"); + this._vertexBuffer = new VertexBuffer3D(verDec.vertexStride * 8, gl.STATIC_DRAW, false); + this._vertexBuffer.vertexDeclaration = verDec; + this._indexBuffer = new IndexBuffer3D(exports.IndexFormat.UInt8, 36, gl.STATIC_DRAW, false); + this._vertexBuffer.setData(vertices.buffer); + this._indexBuffer.setData(indices); + var bufferState = new BufferState(); + bufferState.bind(); + bufferState.applyVertexBuffer(this._vertexBuffer); + bufferState.applyIndexBuffer(this._indexBuffer); + bufferState.unBind(); + this._bufferState = bufferState; + } + static __init__() { + SkyBox.instance = new SkyBox(); + } + _render(state) { + var gl = Laya.LayaGL.instance; + gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_BYTE, 0); + Laya.Stat.trianglesFaces += 12; + Laya.Stat.renderBatches++; + } + } + + class SkyRenderer { + constructor() { + this._mesh = SkyBox.instance; + } + get material() { + return this._material; + } + set material(value) { + if (this._material !== value) { + (this._material) && (this._material._removeReference()); + (value) && (value._addReference()); + this._material = value; + } + } + get mesh() { + return this._mesh; + } + set mesh(value) { + if (this._mesh !== value) { + this._mesh = value; + } + } + _isAvailable() { + return this._material && this._mesh ? true : false; + } + _render(context) { + if (this._material && this._mesh) { + var gl = Laya.LayaGL.instance; + var scene = context.scene; + var cameraShaderValue = context.cameraShaderValue; + var camera = context.camera; + var noteValue = ShaderData._SET_RUNTIME_VALUE_MODE_REFERENCE_; + Laya.ILaya.Render.supportWebGLPlusRendering && ShaderData.setRuntimeValueMode(false); + Laya.WebGLContext.setCullFace(gl, false); + Laya.WebGLContext.setDepthFunc(gl, gl.LEQUAL); + Laya.WebGLContext.setDepthMask(gl, false); + var comDef = SkyRenderer._compileDefine; + this._material._shaderValues._defineDatas.cloneTo(comDef); + var shader = context.shader = this._material._shader.getSubShaderAt(0)._passes[0].withCompile(comDef); + var switchShader = shader.bind(); + var switchShaderLoop = (Laya.Stat.loopCount !== shader._uploadMark); + var uploadScene = (shader._uploadScene !== scene) || switchShaderLoop; + if (uploadScene || switchShader) { + shader.uploadUniforms(shader._sceneUniformParamsMap, scene._shaderValues, uploadScene); + shader._uploadScene = scene; + } + var uploadCamera = (shader._uploadCameraShaderValue !== cameraShaderValue) || switchShaderLoop; + if (uploadCamera || switchShader) { + var viewMatrix = SkyRenderer._tempMatrix0; + var projectionMatrix = SkyRenderer._tempMatrix1; + camera.viewMatrix.cloneTo(viewMatrix); + camera.projectionMatrix.cloneTo(projectionMatrix); + viewMatrix.setTranslationVector(Vector3._ZERO); + if (camera.orthographic) + Matrix4x4.createPerspective(camera.fieldOfView, camera.aspectRatio, camera.nearPlane, camera.farPlane, projectionMatrix); + var epsilon = 1e-6; + var yScale = 1.0 / Math.tan(3.1416 * camera.fieldOfView / 180 * 0.5); + projectionMatrix.elements[0] = yScale / camera.aspectRatio; + projectionMatrix.elements[5] = yScale; + projectionMatrix.elements[10] = epsilon - 1.0; + projectionMatrix.elements[11] = -1.0; + projectionMatrix.elements[14] = -0; + camera._applyViewProject(context, viewMatrix, projectionMatrix); + shader.uploadUniforms(shader._cameraUniformParamsMap, cameraShaderValue, uploadCamera); + shader._uploadCameraShaderValue = cameraShaderValue; + } + var uploadMaterial = (shader._uploadMaterial !== this._material) || switchShaderLoop; + if (uploadMaterial || switchShader) { + shader.uploadUniforms(shader._materialUniformParamsMap, this._material._shaderValues, uploadMaterial); + shader._uploadMaterial = this._material; + } + this._mesh._bufferState.bind(); + this._mesh._render(context); + Laya.ILaya.Render.supportWebGLPlusRendering && ShaderData.setRuntimeValueMode(noteValue); + Laya.WebGLContext.setDepthFunc(gl, gl.LESS); + Laya.WebGLContext.setDepthMask(gl, true); + camera._applyViewProject(context, camera.viewMatrix, camera.projectionMatrix); + } + } + destroy() { + if (this._material) { + this._material._removeReference(); + this._material = null; + } + } + } + SkyRenderer._tempMatrix0 = new Matrix4x4(); + SkyRenderer._tempMatrix1 = new Matrix4x4(); + SkyRenderer._compileDefine = new DefineDatas(); + + class BaseCamera extends Sprite3D { + constructor(nearPlane = 0.3, farPlane = 1000) { + super(); + this._skyRenderer = new SkyRenderer(); + this._forward = new Vector3(); + this._up = new Vector3(); + this.clearColor = new Vector4(100 / 255, 149 / 255, 237 / 255, 255 / 255); + this._shaderValues = new ShaderData(null); + this._fieldOfView = 60; + this._useUserProjectionMatrix = false; + this._orthographic = false; + this._orthographicVerticalSize = 10; + this.renderingOrder = 0; + this._nearPlane = nearPlane; + this._farPlane = farPlane; + this.cullingMask = 2147483647; + this.useOcclusionCulling = true; + } + get skyRenderer() { + return this._skyRenderer; + } + get fieldOfView() { + return this._fieldOfView; + } + set fieldOfView(value) { + this._fieldOfView = value; + this._calculateProjectionMatrix(); + } + get nearPlane() { + return this._nearPlane; + } + set nearPlane(value) { + this._nearPlane = value; + this._calculateProjectionMatrix(); + } + get farPlane() { + return this._farPlane; + } + set farPlane(vaule) { + this._farPlane = vaule; + this._calculateProjectionMatrix(); + } + get orthographic() { + return this._orthographic; + } + set orthographic(vaule) { + this._orthographic = vaule; + this._calculateProjectionMatrix(); + } + get orthographicVerticalSize() { + return this._orthographicVerticalSize; + } + set orthographicVerticalSize(vaule) { + this._orthographicVerticalSize = vaule; + this._calculateProjectionMatrix(); + } + get renderingOrder() { + return this._renderingOrder; + } + set renderingOrder(value) { + this._renderingOrder = value; + this._sortCamerasByRenderingOrder(); + } + _sortCamerasByRenderingOrder() { + if (this.displayedInStage) { + var cameraPool = this.scene._cameraPool; + var n = cameraPool.length - 1; + for (var i = 0; i < n; i++) { + if (cameraPool[i].renderingOrder > cameraPool[n].renderingOrder) { + var tempCamera = cameraPool[i]; + cameraPool[i] = cameraPool[n]; + cameraPool[n] = tempCamera; + } + } + } + } + _calculateProjectionMatrix() { + } + _onScreenSizeChanged() { + this._calculateProjectionMatrix(); + } + _prepareCameraToRender() { + var cameraSV = this._shaderValues; + this.transform.getForward(this._forward); + this.transform.getUp(this._up); + cameraSV.setVector3(BaseCamera.CAMERAPOS, this.transform.position); + cameraSV.setVector3(BaseCamera.CAMERADIRECTION, this._forward); + cameraSV.setVector3(BaseCamera.CAMERAUP, this._up); + } + render(shader = null, replacementTag = null) { + } + addLayer(layer) { + this.cullingMask |= Math.pow(2, layer); + } + removeLayer(layer) { + this.cullingMask &= ~Math.pow(2, layer); + } + addAllLayers() { + this.cullingMask = 2147483647; + } + removeAllLayers() { + this.cullingMask = 0; + } + resetProjectionMatrix() { + this._useUserProjectionMatrix = false; + this._calculateProjectionMatrix(); + } + _onActive() { + this._scene._addCamera(this); + super._onActive(); + } + _onInActive() { + this._scene._removeCamera(this); + super._onInActive(); + } + _parse(data, spriteMap) { + super._parse(data, spriteMap); + this.orthographic = data.orthographic; + (data.orthographicVerticalSize !== undefined) && (this.orthographicVerticalSize = data.orthographicVerticalSize); + (data.fieldOfView !== undefined) && (this.fieldOfView = data.fieldOfView); + this.nearPlane = data.nearPlane; + this.farPlane = data.farPlane; + var color = data.clearColor; + this.clearColor = new Vector4(color[0], color[1], color[2], color[3]); + var skyboxMaterial = data.skyboxMaterial; + if (skyboxMaterial) { + this._skyRenderer.material = Laya.Loader.getRes(skyboxMaterial.path); + } + } + destroy(destroyChild = true) { + this._skyRenderer.destroy(); + this._skyRenderer = null; + Laya.Laya.stage.off(Laya.Event.RESIZE, this, this._onScreenSizeChanged); + super.destroy(destroyChild); + } + _create() { + return new BaseCamera(); + } + } + BaseCamera._tempMatrix4x40 = new Matrix4x4(); + BaseCamera.CAMERAPOS = Shader3D.propertyNameToID("u_CameraPos"); + BaseCamera.VIEWMATRIX = Shader3D.propertyNameToID("u_View"); + BaseCamera.PROJECTMATRIX = Shader3D.propertyNameToID("u_Projection"); + BaseCamera.VIEWPROJECTMATRIX = Shader3D.propertyNameToID("u_ViewProjection"); + BaseCamera.CAMERADIRECTION = Shader3D.propertyNameToID("u_CameraDirection"); + BaseCamera.CAMERAUP = Shader3D.propertyNameToID("u_CameraUp"); + BaseCamera.VIEWPORT = Shader3D.propertyNameToID("u_Viewport"); + BaseCamera.PROJECTION_PARAMS = Shader3D.propertyNameToID("u_ProjectionParams"); + BaseCamera.DEPTHTEXTURE = Shader3D.propertyNameToID("u_CameraDepthTexture"); + BaseCamera.DEPTHNORMALSTEXTURE = Shader3D.propertyNameToID("u_CameraDepthNormalsTexture"); + BaseCamera.DEPTHZBUFFERPARAMS = Shader3D.propertyNameToID("u_ZBufferParams"); + BaseCamera.SHADERDEFINE_DEPTH = Shader3D.getDefineByName("DEPTHMAP"); + BaseCamera.SHADERDEFINE_DEPTHNORMALS = Shader3D.getDefineByName("DEPTHNORMALSMAP"); + BaseCamera.RENDERINGTYPE_DEFERREDLIGHTING = "DEFERREDLIGHTING"; + BaseCamera.RENDERINGTYPE_FORWARDRENDERING = "FORWARDRENDERING"; + BaseCamera._invertYScaleMatrix = new Matrix4x4(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + BaseCamera._invertYProjectionMatrix = new Matrix4x4(); + BaseCamera._invertYProjectionViewMatrix = new Matrix4x4(); + BaseCamera.CLEARFLAG_SOLIDCOLOR = 0; + BaseCamera.CLEARFLAG_SKY = 1; + BaseCamera.CLEARFLAG_DEPTHONLY = 2; + BaseCamera.CLEARFLAG_NONE = 3; + + (function (ShadowMode) { + ShadowMode[ShadowMode["None"] = 0] = "None"; + ShadowMode[ShadowMode["Hard"] = 1] = "Hard"; + ShadowMode[ShadowMode["SoftLow"] = 2] = "SoftLow"; + ShadowMode[ShadowMode["SoftHigh"] = 3] = "SoftHigh"; + })(exports.ShadowMode || (exports.ShadowMode = {})); + + class Scene3DShaderDeclaration { + } + + (function (LightType) { + LightType[LightType["Directional"] = 0] = "Directional"; + LightType[LightType["Spot"] = 1] = "Spot"; + LightType[LightType["Point"] = 2] = "Point"; + })(exports.LightType || (exports.LightType = {})); + class LightSprite extends Sprite3D { + constructor() { + super(); + this._shadowMode = exports.ShadowMode.None; + this._isAlternate = false; + this._shadowResolution = 2048; + this._shadowDistance = 50.0; + this._shadowDepthBias = 1.0; + this._shadowNormalBias = 1.0; + this._shadowNearPlane = 0.1; + this._shadowStrength = 1.0; + this._lightWoldMatrix = new Matrix4x4(); + this._intensity = 1.0; + this._intensityColor = new Vector3(); + this.color = new Vector3(1.0, 1.0, 1.0); + this._lightmapBakedType = LightSprite.LIGHTMAPBAKEDTYPE_REALTIME; + } + get intensity() { + return this._intensity; + } + set intensity(value) { + this._intensity = value; + } + get shadowMode() { + return this._shadowMode; + } + set shadowMode(value) { + this._shadowMode = value; + } + get shadowDistance() { + return this._shadowDistance; + } + set shadowDistance(value) { + this._shadowDistance = value; + } + get shadowResolution() { + return this._shadowResolution; + } + set shadowResolution(value) { + this._shadowResolution = value; + } + get shadowDepthBias() { + return this._shadowDepthBias; + } + set shadowDepthBias(value) { + this._shadowDepthBias = value; + } + get shadowNormalBias() { + return this._shadowNormalBias; + } + set shadowNormalBias(value) { + this._shadowNormalBias = value; + } + get shadowStrength() { + return this._shadowStrength; + } + set shadowStrength(value) { + this._shadowStrength = value; + } + get shadowNearPlane() { + return this._shadowNearPlane; + } + set shadowNearPlane(value) { + this._shadowNearPlane = value; + } + get lightmapBakedType() { + return this._lightmapBakedType; + } + set lightmapBakedType(value) { + if (this._lightmapBakedType !== value) { + this._lightmapBakedType = value; + if (this.activeInHierarchy) { + if (value !== LightSprite.LIGHTMAPBAKEDTYPE_BAKED) + this._addToScene(); + else + this._removeFromScene(); + } + } + } + get lightWorldMatrix() { + var position = this.transform.position; + var quaterian = this.transform.rotation; + Matrix4x4.createAffineTransformation(position, quaterian, Vector3._ONE, this._lightWoldMatrix); + return this._lightWoldMatrix; + } + _parse(data, spriteMap) { + super._parse(data, spriteMap); + var colorData = data.color; + this.color.fromArray(colorData); + this.intensity = data.intensity; + this.lightmapBakedType = data.lightmapBakedType; + } + _cloneTo(destObject, rootSprite, dstSprite) { + super._cloneTo(destObject, rootSprite, dstSprite); + var spriteLight = destObject; + spriteLight.color = this.color.clone(); + spriteLight.intensity = this.intensity; + spriteLight.lightmapBakedType = this.lightmapBakedType; + } + _addToScene() { + var scene = this._scene; + var maxLightCount = Config3D._config.maxLightCount; + if (scene._lightCount < maxLightCount) { + scene._lightCount++; + this._addToLightQueue(); + this._isAlternate = false; + } + else { + scene._alternateLights.add(this); + this._isAlternate = true; + console.warn("LightSprite:light count has large than maxLightCount,the latest added light will be ignore."); + } + } + _removeFromScene() { + var scene = this._scene; + if (this._isAlternate) { + scene._alternateLights.remove(this); + } + else { + scene._lightCount--; + this._removeFromLightQueue(); + if (scene._alternateLights._length > 0) { + var alternateLight = scene._alternateLights.shift(); + alternateLight._addToLightQueue(); + alternateLight._isAlternate = false; + scene._lightCount++; + } + } + } + _addToLightQueue() { + } + _removeFromLightQueue() { + } + _onActive() { + super._onActive(); + (this.lightmapBakedType !== LightSprite.LIGHTMAPBAKEDTYPE_BAKED) && (this._addToScene()); + } + _onInActive() { + super._onInActive(); + (this.lightmapBakedType !== LightSprite.LIGHTMAPBAKEDTYPE_BAKED) && (this._removeFromScene()); + } + _create() { + return new LightSprite(); + } + get diffuseColor() { + console.log("LightSprite: discard property,please use color property instead."); + return this.color; + } + set diffuseColor(value) { + console.log("LightSprite: discard property,please use color property instead."); + this.color = value; + } + } + LightSprite.LIGHTMAPBAKEDTYPE_REALTIME = 0; + LightSprite.LIGHTMAPBAKEDTYPE_MIXED = 1; + LightSprite.LIGHTMAPBAKEDTYPE_BAKED = 2; + + (function (ShadowCascadesMode) { + ShadowCascadesMode[ShadowCascadesMode["NoCascades"] = 0] = "NoCascades"; + ShadowCascadesMode[ShadowCascadesMode["TwoCascades"] = 1] = "TwoCascades"; + ShadowCascadesMode[ShadowCascadesMode["FourCascades"] = 2] = "FourCascades"; + })(exports.ShadowCascadesMode || (exports.ShadowCascadesMode = {})); + + var FrustumFace; + (function (FrustumFace) { + FrustumFace[FrustumFace["Near"] = 0] = "Near"; + FrustumFace[FrustumFace["Far"] = 1] = "Far"; + FrustumFace[FrustumFace["Left"] = 2] = "Left"; + FrustumFace[FrustumFace["Right"] = 3] = "Right"; + FrustumFace[FrustumFace["Bottom"] = 4] = "Bottom"; + FrustumFace[FrustumFace["Top"] = 5] = "Top"; + })(FrustumFace || (FrustumFace = {})); + class ShadowUtils { + static supportShadow() { + return Laya.LayaGL.layaGPUInstance._isWebGL2 || Laya.SystemUtils.supportRenderTextureFormat(Laya.RenderTextureFormat.Depth); + } + static init() { + if (Laya.LayaGL.layaGPUInstance._isWebGL2) + ShadowUtils._shadowTextureFormat = Laya.RenderTextureFormat.ShadowMap; + else + ShadowUtils._shadowTextureFormat = Laya.RenderTextureFormat.Depth; + } + static getTemporaryShadowTexture(witdh, height, depthFormat) { + var shadowMap = RenderTexture.createFromPool(witdh, height, ShadowUtils._shadowTextureFormat, depthFormat); + shadowMap.filterMode = Laya.FilterMode.Bilinear; + shadowMap.wrapModeU = Laya.WarpMode.Clamp; + shadowMap.wrapModeV = Laya.WarpMode.Clamp; + return shadowMap; + } + static getShadowBias(light, shadowProjectionMatrix, shadowResolution, out) { + var frustumSize; + if (light._lightType == exports.LightType.Directional) { + frustumSize = 2.0 / shadowProjectionMatrix.elements[0]; + } + else if (light._lightType == exports.LightType.Spot) { + frustumSize = Math.tan(light.spotAngle * 0.5 * MathUtils3D.Deg2Rad) * light.range; + } + else { + console.warn("ShadowUtils:Only spot and directional shadow casters are supported now."); + frustumSize = 0.0; + } + var texelSize = frustumSize / shadowResolution; + var depthBias = -light._shadowDepthBias * texelSize; + var normalBias = -light._shadowNormalBias * texelSize; + if (light.shadowMode == exports.ShadowMode.SoftHigh) { + const kernelRadius = 2.5; + depthBias *= kernelRadius; + normalBias *= kernelRadius; + } + out.setValue(depthBias, normalBias, 0.0, 0.0); + } + static getCameraFrustumPlanes(cameraViewProjectMatrix, frustumPlanes) { + BoundFrustum.getPlanesFromMatrix(cameraViewProjectMatrix, frustumPlanes[FrustumFace.Near], frustumPlanes[FrustumFace.Far], frustumPlanes[FrustumFace.Left], frustumPlanes[FrustumFace.Right], frustumPlanes[FrustumFace.Top], frustumPlanes[FrustumFace.Bottom]); + } + static getFarWithRadius(radius, denominator) { + return Math.sqrt(radius * radius / denominator); + } + static getCascadesSplitDistance(twoSplitRatio, fourSplitRatio, cameraNear, shadowFar, fov, aspectRatio, cascadesMode, out) { + out[0] = cameraNear; + var range = shadowFar - cameraNear; + var tFov = Math.tan(fov * 0.5); + var denominator = 1.0 + tFov * tFov * (aspectRatio * aspectRatio + 1.0); + switch (cascadesMode) { + case exports.ShadowCascadesMode.NoCascades: + out[1] = ShadowUtils.getFarWithRadius(shadowFar, denominator); + break; + case exports.ShadowCascadesMode.TwoCascades: + out[1] = ShadowUtils.getFarWithRadius(cameraNear + range * twoSplitRatio, denominator); + out[2] = ShadowUtils.getFarWithRadius(shadowFar, denominator); + break; + case exports.ShadowCascadesMode.FourCascades: + out[1] = ShadowUtils.getFarWithRadius(cameraNear + range * fourSplitRatio.x, denominator); + out[2] = ShadowUtils.getFarWithRadius(cameraNear + range * fourSplitRatio.y, denominator); + out[3] = ShadowUtils.getFarWithRadius(cameraNear + range * fourSplitRatio.z, denominator); + out[4] = ShadowUtils.getFarWithRadius(shadowFar, denominator); + break; + } + } + static applySliceTransform(shadowSliceData, atlasWidth, atlasHeight, cascadeIndex, outShadowMatrices) { + var sliceE = ShadowUtils._tempMatrix0.elements; + var oneOverAtlasWidth = 1.0 / atlasWidth; + var oneOverAtlasHeight = 1.0 / atlasHeight; + sliceE[0] = shadowSliceData.resolution * oneOverAtlasWidth; + sliceE[5] = shadowSliceData.resolution * oneOverAtlasHeight; + sliceE[12] = shadowSliceData.offsetX * oneOverAtlasWidth; + sliceE[13] = shadowSliceData.offsetY * oneOverAtlasHeight; + sliceE[1] = sliceE[2] = sliceE[2] = sliceE[4] = sliceE[6] = sliceE[7] = sliceE[8] = sliceE[9] = sliceE[11] = sliceE[14] = 0; + sliceE[10] = sliceE[15] = 1; + var offset = cascadeIndex * 16; + Utils3D._mulMatrixArray(sliceE, outShadowMatrices, offset, outShadowMatrices, offset); + } + static getDirectionLightShadowCullPlanes(cameraFrustumPlanes, cascadeIndex, splitDistance, cameraNear, direction, shadowSliceData) { + var frustumCorners = ShadowUtils._frustumCorners; + var backPlaneFaces = ShadowUtils._backPlaneFaces; + var planeNeighbors = ShadowUtils._frustumPlaneNeighbors; + var twoPlaneCorners = ShadowUtils._frustumTwoPlaneCorners; + var edgePlanePoint2 = ShadowUtils._edgePlanePoint2; + var out = shadowSliceData.cullPlanes; + var near = cameraFrustumPlanes[FrustumFace.Near], far = cameraFrustumPlanes[FrustumFace.Far]; + var left = cameraFrustumPlanes[FrustumFace.Left], right = cameraFrustumPlanes[FrustumFace.Right]; + var bottom = cameraFrustumPlanes[FrustumFace.Bottom], top = cameraFrustumPlanes[FrustumFace.Top]; + var splitNearDistance = splitDistance[cascadeIndex] - cameraNear; + var splitNear = ShadowUtils._adjustNearPlane; + var splitFar = ShadowUtils._adjustFarPlane; + near.normal.cloneTo(splitNear.normal); + far.normal.cloneTo(splitFar.normal); + splitNear.distance = near.distance - splitNearDistance; + splitFar.distance = Math.min(-near.distance + shadowSliceData.sphereCenterZ + shadowSliceData.splitBoundSphere.radius, far.distance); + BoundFrustum.get3PlaneInterPoint(splitNear, bottom, right, frustumCorners[exports.FrustumCorner.nearBottomRight]); + BoundFrustum.get3PlaneInterPoint(splitNear, top, right, frustumCorners[exports.FrustumCorner.nearTopRight]); + BoundFrustum.get3PlaneInterPoint(splitNear, top, left, frustumCorners[exports.FrustumCorner.nearTopLeft]); + BoundFrustum.get3PlaneInterPoint(splitNear, bottom, left, frustumCorners[exports.FrustumCorner.nearBottomLeft]); + BoundFrustum.get3PlaneInterPoint(splitFar, bottom, right, frustumCorners[exports.FrustumCorner.FarBottomRight]); + BoundFrustum.get3PlaneInterPoint(splitFar, top, right, frustumCorners[exports.FrustumCorner.FarTopRight]); + BoundFrustum.get3PlaneInterPoint(splitFar, top, left, frustumCorners[exports.FrustumCorner.FarTopLeft]); + BoundFrustum.get3PlaneInterPoint(splitFar, bottom, left, frustumCorners[exports.FrustumCorner.FarBottomLeft]); + var backIndex = 0; + for (var i = 0; i < 6; i++) { + var plane; + switch (i) { + case FrustumFace.Near: + plane = splitNear; + break; + case FrustumFace.Far: + plane = splitFar; + break; + default: + plane = cameraFrustumPlanes[i]; + break; + } + if (Vector3.dot(plane.normal, direction) < 0.0) { + plane.cloneTo(out[backIndex]); + backPlaneFaces[backIndex] = i; + backIndex++; + } + } + var edgeIndex = backIndex; + for (var i = 0; i < backIndex; i++) { + var backFace = backPlaneFaces[i]; + var neighborFaces = planeNeighbors[backFace]; + for (var j = 0; j < 4; j++) { + var neighborFace = neighborFaces[j]; + var notBackFace = true; + for (var k = 0; k < backIndex; k++) + if (neighborFace == backPlaneFaces[k]) { + notBackFace = false; + break; + } + if (notBackFace) { + var corners = twoPlaneCorners[backFace][neighborFace]; + var point0 = frustumCorners[corners[0]]; + var point1 = frustumCorners[corners[1]]; + Vector3.add(point0, direction, edgePlanePoint2); + Plane.createPlaneBy3P(point0, point1, edgePlanePoint2, out[edgeIndex++]); + } + } + } + shadowSliceData.cullPlaneCount = edgeIndex; + } + static getBoundSphereByFrustum(near, far, fov, aspectRatio, cameraPos, forward, outBoundSphere) { + var centerZ; + var radius; + var k = Math.sqrt(1.0 + aspectRatio * aspectRatio) * Math.tan(fov / 2.0); + var k2 = k * k; + var farSNear = far - near; + var farANear = far + near; + if (k2 > farSNear / farANear) { + centerZ = far; + radius = far * k; + } + else { + centerZ = 0.5 * farANear * (1 + k2); + radius = 0.5 * Math.sqrt(farSNear * farSNear + 2.0 * (far * far + near * near) * k2 + farANear * farANear * k2 * k2); + } + var center = outBoundSphere.center; + outBoundSphere.radius = radius; + Vector3.scale(forward, centerZ, center); + Vector3.add(cameraPos, center, center); + return centerZ; + } + static getMaxTileResolutionInAtlas(atlasWidth, atlasHeight, tileCount) { + var resolution = Math.min(atlasWidth, atlasHeight); + var currentTileCount = Math.floor(atlasWidth / resolution) * Math.floor(atlasHeight / resolution); + while (currentTileCount < tileCount) { + resolution = Math.floor(resolution >> 1); + currentTileCount = Math.floor(atlasWidth / resolution) * Math.floor(atlasHeight / resolution); + } + return resolution; + } + static getDirectionalLightMatrices(lightUp, lightSide, lightForward, cascadeIndex, nearPlane, shadowResolution, shadowSliceData, shadowMatrices) { + var boundSphere = shadowSliceData.splitBoundSphere; + var center = boundSphere.center; + var radius = boundSphere.radius; + var halfShadowResolution = shadowResolution / 2; + var borderRadius = radius * halfShadowResolution / (halfShadowResolution - ShadowUtils.atlasBorderSize); + var borderDiam = borderRadius * 2.0; + var sizeUnit = shadowResolution / borderDiam; + var radiusUnit = borderDiam / shadowResolution; + var upLen = Math.ceil(Vector3.dot(center, lightUp) * sizeUnit) * radiusUnit; + var sideLen = Math.ceil(Vector3.dot(center, lightSide) * sizeUnit) * radiusUnit; + var forwardLen = Vector3.dot(center, lightForward); + center.x = lightUp.x * upLen + lightSide.x * sideLen + lightForward.x * forwardLen; + center.y = lightUp.y * upLen + lightSide.y * sideLen + lightForward.y * forwardLen; + center.z = lightUp.z * upLen + lightSide.z * sideLen + lightForward.z * forwardLen; + var origin = shadowSliceData.position; + var viewMatrix = shadowSliceData.viewMatrix; + var projectMatrix = shadowSliceData.projectionMatrix; + var viewProjectMatrix = shadowSliceData.viewProjectMatrix; + shadowSliceData.resolution = shadowResolution; + shadowSliceData.offsetX = (cascadeIndex % 2) * shadowResolution; + shadowSliceData.offsetY = Math.floor(cascadeIndex / 2) * shadowResolution; + Vector3.scale(lightForward, radius + nearPlane, origin); + Vector3.subtract(center, origin, origin); + Matrix4x4.createLookAt(origin, center, lightUp, viewMatrix); + Matrix4x4.createOrthoOffCenter(-borderRadius, borderRadius, -borderRadius, borderRadius, 0.0, radius * 2.0 + nearPlane, projectMatrix); + Matrix4x4.multiply(projectMatrix, viewMatrix, viewProjectMatrix); + Utils3D._mulMatrixArray(ShadowUtils._shadowMapScaleOffsetMatrix.elements, viewProjectMatrix.elements, 0, shadowMatrices, cascadeIndex * 16); + } + static getSpotLightShadowData(shadowSpotData, spotLight, resolution, shadowParams, shadowSpotMatrices, shadowMapSize) { + var out = shadowSpotData.position = spotLight.transform.position; + shadowSpotData.resolution = resolution; + shadowMapSize.setValue(1.0 / resolution, 1.0 / resolution, resolution, resolution); + shadowSpotData.offsetX = 0; + shadowSpotData.offsetY = 0; + var spotWorldMatrix = spotLight.lightWorldMatrix; + var viewMatrix = shadowSpotData.viewMatrix; + var projectMatrix = shadowSpotData.projectionMatrix; + var viewProjectMatrix = shadowSpotData.viewProjectMatrix; + var BoundFrustum = shadowSpotData.cameraCullInfo.boundFrustum; + spotWorldMatrix.invert(viewMatrix); + Matrix4x4.createPerspective(3.1416 * spotLight.spotAngle / 180.0, 1, 0.1, spotLight.range, projectMatrix); + shadowParams.y = spotLight.shadowStrength; + Matrix4x4.multiply(projectMatrix, viewMatrix, viewProjectMatrix); + BoundFrustum.matrix = viewProjectMatrix; + viewProjectMatrix.cloneTo(shadowSpotMatrices); + shadowSpotData.cameraCullInfo.position = out; + } + static prepareShadowReceiverShaderValues(light, shadowMapWidth, shadowMapHeight, shadowSliceDatas, cascadeCount, shadowMapSize, shadowParams, shadowMatrices, splitBoundSpheres) { + shadowMapSize.setValue(1.0 / shadowMapWidth, 1.0 / shadowMapHeight, shadowMapWidth, shadowMapHeight); + shadowParams.setValue(light._shadowStrength, 0.0, 0.0, 0.0); + if (cascadeCount > 1) { + const matrixFloatCount = 16; + for (var i = cascadeCount * matrixFloatCount, n = 4 * matrixFloatCount; i < n; i++) + shadowMatrices[i] = 0.0; + for (var i = 0; i < cascadeCount; i++) { + var boundSphere = shadowSliceDatas[i].splitBoundSphere; + var center = boundSphere.center; + var radius = boundSphere.radius; + var offset = i * 4; + splitBoundSpheres[offset] = center.x; + splitBoundSpheres[offset + 1] = center.y; + splitBoundSpheres[offset + 2] = center.z; + splitBoundSpheres[offset + 3] = radius * radius; + } + const sphereFloatCount = 4; + for (var i = cascadeCount * sphereFloatCount, n = 4 * sphereFloatCount; i < n; i++) + splitBoundSpheres[i] = 0.0; + } + } + } + ShadowUtils._tempMatrix0 = new Matrix4x4(); + ShadowUtils._shadowMapScaleOffsetMatrix = new Matrix4x4(0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.5, 0.5, 0.0, 1.0); + ShadowUtils._frustumCorners = [new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3()]; + ShadowUtils._adjustNearPlane = new Plane(new Vector3()); + ShadowUtils._adjustFarPlane = new Plane(new Vector3()); + ShadowUtils._backPlaneFaces = new Array(5); + ShadowUtils._edgePlanePoint2 = new Vector3(); + ShadowUtils._frustumPlaneNeighbors = [ + [FrustumFace.Left, FrustumFace.Right, FrustumFace.Top, FrustumFace.Bottom], + [FrustumFace.Left, FrustumFace.Right, FrustumFace.Top, FrustumFace.Bottom], + [FrustumFace.Near, FrustumFace.Far, FrustumFace.Top, FrustumFace.Bottom], + [FrustumFace.Near, FrustumFace.Far, FrustumFace.Top, FrustumFace.Bottom], + [FrustumFace.Near, FrustumFace.Far, FrustumFace.Left, FrustumFace.Right], + [FrustumFace.Near, FrustumFace.Far, FrustumFace.Left, FrustumFace.Right] + ]; + ShadowUtils._frustumTwoPlaneCorners = [ + [[exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.nearBottomLeft, exports.FrustumCorner.nearTopLeft], [exports.FrustumCorner.nearTopRight, exports.FrustumCorner.nearBottomRight], [exports.FrustumCorner.nearBottomRight, exports.FrustumCorner.nearBottomLeft], [exports.FrustumCorner.nearTopLeft, exports.FrustumCorner.nearTopRight]], + [[exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.FarTopLeft, exports.FrustumCorner.FarBottomLeft], [exports.FrustumCorner.FarBottomRight, exports.FrustumCorner.FarTopRight], [exports.FrustumCorner.FarBottomLeft, exports.FrustumCorner.FarBottomRight], [exports.FrustumCorner.FarTopRight, exports.FrustumCorner.FarTopLeft]], + [[exports.FrustumCorner.nearTopLeft, exports.FrustumCorner.nearBottomLeft], [exports.FrustumCorner.FarBottomLeft, exports.FrustumCorner.FarTopLeft], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.nearBottomLeft, exports.FrustumCorner.FarBottomLeft], [exports.FrustumCorner.FarTopLeft, exports.FrustumCorner.nearTopLeft]], + [[exports.FrustumCorner.nearBottomRight, exports.FrustumCorner.nearTopRight], [exports.FrustumCorner.FarTopRight, exports.FrustumCorner.FarBottomRight], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.FarBottomRight, exports.FrustumCorner.nearBottomRight], [exports.FrustumCorner.nearTopRight, exports.FrustumCorner.FarTopRight]], + [[exports.FrustumCorner.nearBottomLeft, exports.FrustumCorner.nearBottomRight], [exports.FrustumCorner.FarBottomRight, exports.FrustumCorner.FarBottomLeft], [exports.FrustumCorner.FarBottomLeft, exports.FrustumCorner.nearBottomLeft], [exports.FrustumCorner.nearBottomRight, exports.FrustumCorner.FarBottomRight], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown]], + [[exports.FrustumCorner.nearTopRight, exports.FrustumCorner.nearTopLeft], [exports.FrustumCorner.FarTopLeft, exports.FrustumCorner.FarTopRight], [exports.FrustumCorner.nearTopLeft, exports.FrustumCorner.FarTopLeft], [exports.FrustumCorner.FarTopRight, exports.FrustumCorner.nearTopRight], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown], [exports.FrustumCorner.unknown, exports.FrustumCorner.unknown]] + ]; + ShadowUtils.atlasBorderSize = 4.0; + + (function (DepthTextureMode) { + DepthTextureMode[DepthTextureMode["None"] = 0] = "None"; + DepthTextureMode[DepthTextureMode["Depth"] = 1] = "Depth"; + DepthTextureMode[DepthTextureMode["DepthNormals"] = 2] = "DepthNormals"; + DepthTextureMode[DepthTextureMode["MotionVectors"] = 4] = "MotionVectors"; + })(exports.DepthTextureMode || (exports.DepthTextureMode = {})); + class DepthPass { + constructor() { + this._zBufferParams = new Vector4(); + } + update(camera, depthType) { + this._viewPort = camera.viewport; + this._camera = camera; + switch (depthType) { + case exports.DepthTextureMode.Depth: + camera.depthTexture = this._depthTexture = RenderTexture.createFromPool(this._viewPort.width, this._viewPort.height, Laya.RenderTextureFormat.Depth, Laya.RenderTextureDepthFormat.DEPTH_16); + break; + case exports.DepthTextureMode.DepthNormals: + camera.depthNormalTexture = this._depthNormalsTexture = RenderTexture.createFromPool(this._viewPort.width, this._viewPort.height, Laya.RenderTextureFormat.R8G8B8A8, Laya.RenderTextureDepthFormat.DEPTH_16); + break; + case exports.DepthTextureMode.MotionVectors: + break; + default: + throw ("there is UnDefined type of DepthTextureMode"); + } + } + render(context, depthType) { + var scene = context.scene; + switch (depthType) { + case exports.DepthTextureMode.Depth: + var shaderValues = scene._shaderValues; + context.pipelineMode = "ShadowCaster"; + ShaderData.setRuntimeValueMode(false); + this._depthTexture._start(); + shaderValues.setVector(DepthPass.DEFINE_SHADOW_BIAS, DepthPass.SHADOW_BIAS); + var gl = Laya.LayaGL.instance; + var offsetX = this._viewPort.x; + var offsetY = this._viewPort.y; + gl.enable(gl.SCISSOR_TEST); + gl.viewport(offsetX, offsetY, this._viewPort.width, this._viewPort.height); + gl.scissor(offsetX, offsetY, this._viewPort.width, this._viewPort.height); + gl.clear(gl.DEPTH_BUFFER_BIT); + scene._opaqueQueue._render(context); + this._depthTexture._end(); + ShaderData.setRuntimeValueMode(true); + this._setupDepthModeShaderValue(depthType, this._camera); + context.pipelineMode = context.configPipeLineMode; + break; + case exports.DepthTextureMode.DepthNormals: + var shaderValues = scene._shaderValues; + context.pipelineMode = "DepthNormal"; + ShaderData.setRuntimeValueMode(false); + this._depthNormalsTexture._start(); + var gl = Laya.LayaGL.instance; + var offsetX = this._viewPort.x; + var offsetY = this._viewPort.y; + gl.enable(gl.SCISSOR_TEST); + gl.viewport(offsetX, offsetY, this._viewPort.width, this._viewPort.height); + gl.scissor(offsetX, offsetY, this._viewPort.width, this._viewPort.height); + gl.clearColor(0.5, 0.5, 1.0, 0.0); + gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT); + scene._opaqueQueue._render(context); + this._depthNormalsTexture._end(); + ShaderData.setRuntimeValueMode(true); + this._setupDepthModeShaderValue(depthType, this._camera); + context.pipelineMode = context.configPipeLineMode; + break; + case exports.DepthTextureMode.MotionVectors: + break; + default: + throw ("there is UnDefined type of DepthTextureMode"); + } + } + _setupDepthModeShaderValue(depthType, camera) { + switch (depthType) { + case exports.DepthTextureMode.Depth: + var far = camera.farPlane; + var near = camera.nearPlane; + this._zBufferParams.setValue(1.0 - far / near, far / near, (near - far) / (near * far), 1 / near); + camera._shaderValues.setVector(DepthPass.DEFINE_SHADOW_BIAS, DepthPass.SHADOW_BIAS); + camera._shaderValues.setTexture(DepthPass.DEPTHTEXTURE, this._depthTexture); + camera._shaderValues.setVector(DepthPass.DEPTHZBUFFERPARAMS, this._zBufferParams); + break; + case exports.DepthTextureMode.DepthNormals: + camera._shaderValues.setTexture(DepthPass.DEPTHNORMALSTEXTURE, this._depthNormalsTexture); + break; + case exports.DepthTextureMode.MotionVectors: + break; + default: + throw ("there is UnDefined type of DepthTextureMode"); + } + } + cleanUp() { + this._depthTexture && RenderTexture.recoverToPool(this._depthTexture); + this._depthNormalsTexture && RenderTexture.recoverToPool(this._depthNormalsTexture); + this._depthTexture = null; + this._depthNormalsTexture = null; + } + } + DepthPass.SHADOW_BIAS = new Vector4(); + DepthPass.DEFINE_SHADOW_BIAS = Shader3D.propertyNameToID("u_ShadowBias"); + DepthPass.DEPTHTEXTURE = Shader3D.propertyNameToID("u_CameraDepthTexture"); + DepthPass.DEPTHNORMALSTEXTURE = Shader3D.propertyNameToID("u_CameraDepthNormalsTexture"); + DepthPass.DEPTHZBUFFERPARAMS = Shader3D.propertyNameToID("u_ZBufferParams"); + + (function (CameraClearFlags) { + CameraClearFlags[CameraClearFlags["SolidColor"] = 0] = "SolidColor"; + CameraClearFlags[CameraClearFlags["Sky"] = 1] = "Sky"; + CameraClearFlags[CameraClearFlags["DepthOnly"] = 2] = "DepthOnly"; + CameraClearFlags[CameraClearFlags["Nothing"] = 3] = "Nothing"; + })(exports.CameraClearFlags || (exports.CameraClearFlags = {})); + (function (CameraEventFlags) { + CameraEventFlags[CameraEventFlags["BeforeForwardOpaque"] = 0] = "BeforeForwardOpaque"; + CameraEventFlags[CameraEventFlags["BeforeSkyBox"] = 2] = "BeforeSkyBox"; + CameraEventFlags[CameraEventFlags["BeforeTransparent"] = 4] = "BeforeTransparent"; + CameraEventFlags[CameraEventFlags["BeforeImageEffect"] = 6] = "BeforeImageEffect"; + CameraEventFlags[CameraEventFlags["AfterEveryThing"] = 8] = "AfterEveryThing"; + })(exports.CameraEventFlags || (exports.CameraEventFlags = {})); + class Camera extends BaseCamera { + constructor(aspectRatio = 0, nearPlane = 0.3, farPlane = 1000) { + super(nearPlane, farPlane); + this._updateViewMatrix = true; + this._postProcess = null; + this._enableHDR = false; + this._viewportParams = new Vector4(); + this._projectionParams = new Vector4(); + this._needBuiltInRenderTexture = false; + this._offScreenRenderTexture = null; + this._internalRenderTexture = null; + this._internalCommandBuffer = new CommandBuffer(); + this._cameraEventCommandBuffer = {}; + this._clusterPlaneCacheFlag = new Vector2(-1, -1); + this._screenOffsetScale = new Vector4(); + this.enableRender = true; + this.clearFlag = exports.CameraClearFlags.SolidColor; + this._viewMatrix = new Matrix4x4(); + this._projectionMatrix = new Matrix4x4(); + this._projectionViewMatrix = new Matrix4x4(); + this._viewport = new Viewport(0, 0, 0, 0); + this._normalizedViewport = new Viewport(0, 0, 1, 1); + this._rayViewport = new Viewport(0, 0, 0, 0); + this._aspectRatio = aspectRatio; + this._boundFrustum = new BoundFrustum(new Matrix4x4()); + this._calculateProjectionMatrix(); + Laya.Laya.stage.on(Laya.Event.RESIZE, this, this._onScreenSizeChanged); + this.transform.on(Laya.Event.TRANSFORM_CHANGED, this, this._onTransformChanged); + } + static drawRenderTextureByScene(camera, scene, renderTexture, shader = null, replacementTag = null) { + if (camera.renderTarget != renderTexture) { + camera.renderTarget && RenderTexture.recoverToPool(camera.renderTarget); + camera.renderTarget = renderTexture; + } + var viewport = camera.viewport; + var needInternalRT = camera._needInternalRenderTexture(); + var context = RenderContext3D._instance; + var scene = context.scene = scene; + context.pipelineMode = context.configPipeLineMode; + if (needInternalRT) { + camera._internalRenderTexture = RenderTexture.createFromPool(viewport.width, viewport.height, camera._getRenderTextureFormat(), Laya.RenderTextureDepthFormat.DEPTH_16); + camera._internalRenderTexture.filterMode = Laya.FilterMode.Bilinear; + } + else { + camera._internalRenderTexture = null; + } + var needShadowCasterPass = camera._renderShadowMap(scene, context); + camera._preRenderMainPass(context, scene, needInternalRT, viewport); + camera._renderMainPass(context, viewport, scene, shader, replacementTag, needInternalRT); + camera._aftRenderMainPass(needShadowCasterPass); + return camera.renderTarget; + } + get aspectRatio() { + if (this._aspectRatio === 0) { + var vp = this.viewport; + return vp.width / vp.height; + } + return this._aspectRatio; + } + set aspectRatio(value) { + if (value < 0) + throw new Error("Camera: the aspect ratio has to be a positive real number."); + this._aspectRatio = value; + this._calculateProjectionMatrix(); + } + get viewport() { + if (this._offScreenRenderTexture) + this._calculationViewport(this._normalizedViewport, this._offScreenRenderTexture.width, this._offScreenRenderTexture.height); + else + this._calculationViewport(this._normalizedViewport, RenderContext3D.clientWidth, RenderContext3D.clientHeight); + return this._viewport; + } + set viewport(value) { + var width; + var height; + if (this._offScreenRenderTexture) { + width = this._offScreenRenderTexture.width; + height = this._offScreenRenderTexture.height; + } + else { + width = RenderContext3D.clientWidth; + height = RenderContext3D.clientHeight; + } + this._normalizedViewport.x = value.x / width; + this._normalizedViewport.y = value.y / height; + this._normalizedViewport.width = value.width / width; + this._normalizedViewport.height = value.height / height; + this._calculationViewport(this._normalizedViewport, width, height); + this._calculateProjectionMatrix(); + } + get normalizedViewport() { + return this._normalizedViewport; + } + set normalizedViewport(value) { + var width; + var height; + if (this._offScreenRenderTexture) { + width = this._offScreenRenderTexture.width; + height = this._offScreenRenderTexture.height; + } + else { + width = RenderContext3D.clientWidth; + height = RenderContext3D.clientHeight; + } + if (this._normalizedViewport !== value) + value.cloneTo(this._normalizedViewport); + this._calculationViewport(value, width, height); + this._calculateProjectionMatrix(); + } + get viewMatrix() { + if (this._updateViewMatrix) { + var scale = this.transform.getWorldLossyScale(); + var scaleX = scale.x; + var scaleY = scale.y; + var scaleZ = scale.z; + var viewMatE = this._viewMatrix.elements; + this.transform.worldMatrix.cloneTo(this._viewMatrix); + viewMatE[0] /= scaleX; + viewMatE[1] /= scaleX; + viewMatE[2] /= scaleX; + viewMatE[4] /= scaleY; + viewMatE[5] /= scaleY; + viewMatE[6] /= scaleY; + viewMatE[8] /= scaleZ; + viewMatE[9] /= scaleZ; + viewMatE[10] /= scaleZ; + this._viewMatrix.invert(this._viewMatrix); + this._updateViewMatrix = false; + } + return this._viewMatrix; + } + get projectionMatrix() { + return this._projectionMatrix; + } + set projectionMatrix(value) { + this._projectionMatrix = value; + this._useUserProjectionMatrix = true; + } + get projectionViewMatrix() { + Matrix4x4.multiply(this.projectionMatrix, this.viewMatrix, this._projectionViewMatrix); + return this._projectionViewMatrix; + } + get boundFrustum() { + this._boundFrustum.matrix = this.projectionViewMatrix; + return this._boundFrustum; + } + get renderTarget() { + return this._offScreenRenderTexture; + } + set renderTarget(value) { + var lastValue = this._offScreenRenderTexture; + if (lastValue !== value) { + (lastValue) && (lastValue._isCameraTarget = false); + (value) && (value._isCameraTarget = true); + this._offScreenRenderTexture = value; + this._calculateProjectionMatrix(); + } + } + get postProcess() { + return this._postProcess; + } + set postProcess(value) { + this._postProcess = value; + if (!value) + return; + value && value._init(this); + } + get enableHDR() { + return this._enableHDR; + } + set enableHDR(value) { + if (value && !Laya.SystemUtils.supportRenderTextureFormat(Laya.RenderTextureFormat.R16G16B16A16)) { + console.warn("Camera:can't enable HDR in this device."); + return; + } + this._enableHDR = value; + } + get enableBuiltInRenderTexture() { + return this._needBuiltInRenderTexture; + } + set enableBuiltInRenderTexture(value) { + this._needBuiltInRenderTexture = value; + } + get depthTextureMode() { + return this._depthTextureMode; + } + set depthTextureMode(value) { + this._depthTextureMode = value; + } + _calculationViewport(normalizedViewport, width, height) { + var lx = normalizedViewport.x * width; + var ly = normalizedViewport.y * height; + var rx = lx + Math.max(normalizedViewport.width * width, 0); + var ry = ly + Math.max(normalizedViewport.height * height, 0); + var ceilLeftX = Math.ceil(lx); + var ceilLeftY = Math.ceil(ly); + var floorRightX = Math.floor(rx); + var floorRightY = Math.floor(ry); + var pixelLeftX = ceilLeftX - lx >= 0.5 ? Math.floor(lx) : ceilLeftX; + var pixelLeftY = ceilLeftY - ly >= 0.5 ? Math.floor(ly) : ceilLeftY; + var pixelRightX = rx - floorRightX >= 0.5 ? Math.ceil(rx) : floorRightX; + var pixelRightY = ry - floorRightY >= 0.5 ? Math.ceil(ry) : floorRightY; + this._viewport.x = pixelLeftX; + this._viewport.y = pixelLeftY; + this._viewport.width = pixelRightX - pixelLeftX; + this._viewport.height = pixelRightY - pixelLeftY; + } + _calculateProjectionMatrix() { + if (!this._useUserProjectionMatrix) { + if (this._orthographic) { + var halfHeight = this.orthographicVerticalSize * 0.5; + var halfWidth = halfHeight * this.aspectRatio; + Matrix4x4.createOrthoOffCenter(-halfWidth, halfWidth, -halfHeight, halfHeight, this.nearPlane, this.farPlane, this._projectionMatrix); + } + else { + Matrix4x4.createPerspective(3.1416 * this.fieldOfView / 180.0, this.aspectRatio, this.nearPlane, this.farPlane, this._projectionMatrix); + } + } + } + _isLayerVisible(layer) { + return (Math.pow(2, layer) & this.cullingMask) != 0; + } + _onTransformChanged(flag) { + flag &= Transform3D.TRANSFORM_WORLDMATRIX; + (flag) && (this._updateViewMatrix = true); + } + _parse(data, spriteMap) { + super._parse(data, spriteMap); + var clearFlagData = data.clearFlag; + (clearFlagData !== undefined) && (this.clearFlag = clearFlagData); + var viewport = data.viewport; + this.normalizedViewport = new Viewport(viewport[0], viewport[1], viewport[2], viewport[3]); + var enableHDR = data.enableHDR; + (enableHDR !== undefined) && (this.enableHDR = enableHDR); + } + clone() { + let camera = super.clone(); + camera.clearFlag = this.clearFlag; + camera.viewport = this.viewport; + this.normalizedViewport.cloneTo(camera.normalizedViewport); + camera.enableHDR = this.enableHDR; + camera.farPlane = this.farPlane; + camera.nearPlane = this.nearPlane; + camera.fieldOfView = this.fieldOfView; + camera.orthographic = this.orthographic; + return camera; + } + _getCanvasWidth() { + if (this._offScreenRenderTexture) + return this._offScreenRenderTexture.width; + else + return RenderContext3D.clientWidth; + } + _getCanvasHeight() { + if (this._offScreenRenderTexture) + return this._offScreenRenderTexture.height; + else + return RenderContext3D.clientHeight; + } + _getRenderTexture() { + return this._internalRenderTexture || this._offScreenRenderTexture; + } + _needInternalRenderTexture() { + return (this._postProcess && this._postProcess.enable) || this._enableHDR || this._needBuiltInRenderTexture ? true : false; + } + _getRenderTextureFormat() { + if (this._enableHDR) + return Laya.RenderTextureFormat.R16G16B16A16; + else + return Laya.RenderTextureFormat.R8G8B8; + } + _prepareCameraToRender() { + super._prepareCameraToRender(); + var vp = this.viewport; + this._viewportParams.setValue(vp.x, vp.y, vp.width, vp.height); + this._projectionParams.setValue(this._nearPlane, this._farPlane, RenderContext3D._instance.invertY ? -1 : 1, 1 / this.farPlane); + this._shaderValues.setVector(BaseCamera.VIEWPORT, this._viewportParams); + this._shaderValues.setVector(BaseCamera.PROJECTION_PARAMS, this._projectionParams); + } + _applyViewProject(context, viewMat, proMat) { + var projectView; + var shaderData = this._shaderValues; + if (context.invertY) { + Matrix4x4.multiply(BaseCamera._invertYScaleMatrix, proMat, BaseCamera._invertYProjectionMatrix); + Matrix4x4.multiply(BaseCamera._invertYProjectionMatrix, viewMat, BaseCamera._invertYProjectionViewMatrix); + proMat = BaseCamera._invertYProjectionMatrix; + projectView = BaseCamera._invertYProjectionViewMatrix; + } + else { + Matrix4x4.multiply(proMat, viewMat, this._projectionViewMatrix); + projectView = this._projectionViewMatrix; + } + context.viewMatrix = viewMat; + context.projectionMatrix = proMat; + context.projectionViewMatrix = projectView; + shaderData.setMatrix4x4(BaseCamera.VIEWMATRIX, viewMat); + shaderData.setMatrix4x4(BaseCamera.PROJECTMATRIX, proMat); + shaderData.setMatrix4x4(BaseCamera.VIEWPROJECTMATRIX, projectView); + } + _updateClusterPlaneXY() { + var fieldOfView = this.fieldOfView; + var aspectRatio = this.aspectRatio; + if (this._clusterPlaneCacheFlag.x !== fieldOfView || this._clusterPlaneCacheFlag.y !== aspectRatio) { + var clusterCount = Config3D._config.lightClusterCount; + var xSlixe = clusterCount.x, ySlice = clusterCount.y; + var xCount = xSlixe + 1, yCount = ySlice + 1; + var xPlanes = this._clusterXPlanes, yPlanes = this._clusterYPlanes; + if (!xPlanes) { + xPlanes = this._clusterXPlanes = new Array(xCount); + yPlanes = this._clusterYPlanes = new Array(yCount); + for (var i = 0; i < xCount; i++) + xPlanes[i] = new Vector3(); + for (var i = 0; i < yCount; i++) + yPlanes[i] = new Vector3(); + } + var halfY = Math.tan((this.fieldOfView / 2) * Math.PI / 180); + var halfX = this.aspectRatio * halfY; + var yLengthPerCluster = 2 * halfY / xSlixe; + var xLengthPerCluster = 2 * halfX / ySlice; + for (var i = 0; i < xCount; i++) { + var angle = -halfX + xLengthPerCluster * i; + var bigHypot = Math.sqrt(1 + angle * angle); + var normX = 1 / bigHypot; + var xPlane = xPlanes[i]; + xPlane.setValue(normX, 0, -angle * normX); + } + for (var i = 0; i < yCount; i++) { + var angle = halfY - yLengthPerCluster * i; + var bigHypot = Math.sqrt(1 + angle * angle); + var normY = -1 / bigHypot; + var yPlane = yPlanes[i]; + yPlane.setValue(0, normY, -angle * normY); + } + this._clusterPlaneCacheFlag.x = fieldOfView; + this._clusterPlaneCacheFlag.y = aspectRatio; + } + } + _applyCommandBuffer(event, context) { + Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDERCOMMANDBUFFER); + var gl = Laya.LayaGL.instance; + var commandBufferArray = this._cameraEventCommandBuffer[event]; + if (!commandBufferArray || commandBufferArray.length == 0) + return; + commandBufferArray.forEach(function (value) { + value._context = context; + value._apply(); + }); + (RenderTexture.currentActive) && (RenderTexture.currentActive._end()); + if (this._internalRenderTexture || this._offScreenRenderTexture) + this._getRenderTexture()._start(); + else { + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + } + gl.viewport(0, 0, context.viewport.width, context.viewport.height); + Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDERCOMMANDBUFFER); + } + _renderShadowMap(scene, context) { + Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_SHADOWMAP); + var shadowCasterPass; + var mainDirectLight = scene._mainDirectionLight; + var needShadowCasterPass = mainDirectLight && mainDirectLight.shadowMode !== exports.ShadowMode.None && ShadowUtils.supportShadow(); + if (needShadowCasterPass) { + scene._shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT); + scene._shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW); + shadowCasterPass = ILaya3D.Scene3D._shadowCasterPass; + shadowCasterPass.update(this, mainDirectLight, ILaya3D.ShadowLightType.DirectionLight); + shadowCasterPass.render(context, scene, ILaya3D.ShadowLightType.DirectionLight); + } + else { + scene._shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW); + } + var spotMainLight = scene._mainSpotLight; + var spotneedShadowCasterPass = spotMainLight && spotMainLight.shadowMode !== exports.ShadowMode.None && ShadowUtils.supportShadow(); + if (spotneedShadowCasterPass) { + scene._shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW); + scene._shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT); + shadowCasterPass = ILaya3D.Scene3D._shadowCasterPass; + shadowCasterPass.update(this, spotMainLight, ILaya3D.ShadowLightType.SpotLight); + shadowCasterPass.render(context, scene, ILaya3D.ShadowLightType.SpotLight); + } + else { + scene._shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT); + } + if (needShadowCasterPass) + scene._shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW); + if (spotneedShadowCasterPass) + scene._shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT); + Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_SHADOWMAP); + return needShadowCasterPass || spotneedShadowCasterPass; + } + _preRenderMainPass(context, scene, needInternalRT, viewport) { + context.camera = this; + context.cameraShaderValue = this._shaderValues; + Camera._updateMark++; + scene._preRenderScript(); + var gl = Laya.LayaGL.instance; + if (needInternalRT && !this._offScreenRenderTexture && (this.clearFlag == exports.CameraClearFlags.DepthOnly || this.clearFlag == exports.CameraClearFlags.Nothing)) { + if (this._enableHDR) { + var grabTexture = RenderTexture.createFromPool(viewport.width, viewport.height, Laya.RenderTextureFormat.R8G8B8, Laya.RenderTextureDepthFormat.DEPTH_16); + grabTexture.filterMode = Laya.FilterMode.Bilinear; + Laya.WebGLContext.bindTexture(gl, gl.TEXTURE_2D, grabTexture._getSource()); + gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, viewport.x, RenderContext3D.clientHeight - (viewport.y + viewport.height), viewport.width, viewport.height); + var blit = BlitScreenQuadCMD.create(grabTexture, this._internalRenderTexture); + blit.run(); + blit.recover(); + RenderTexture.recoverToPool(grabTexture); + } + else { + Laya.WebGLContext.bindTexture(gl, gl.TEXTURE_2D, this._internalRenderTexture._getSource()); + gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, viewport.x, RenderContext3D.clientHeight - (viewport.y + viewport.height), viewport.width, viewport.height); + } + } + } + _renderMainPass(context, viewport, scene, shader, replacementTag, needInternalRT) { + var gl = Laya.LayaGL.instance; + var renderTex = this._getRenderTexture(); + context.viewport = viewport; + this._prepareCameraToRender(); + var multiLighting = Config3D._config._multiLighting; + Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_CLUSTER); + (multiLighting) && (Cluster.instance.update(this, (scene))); + Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_CLUSTER); + Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_CULLING); + scene._preCulling(context, this, shader, replacementTag); + Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_CULLING); + if (this.depthTextureMode != 0) { + this._applyViewProject(context, this.viewMatrix, this._projectionMatrix); + this._renderDepthMode(context); + } + (renderTex) && (renderTex._start()); + this._applyViewProject(context, this.viewMatrix, this._projectionMatrix); + scene._clear(gl, context); + this._applyCommandBuffer(exports.CameraEventFlags.BeforeForwardOpaque, context); + Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDEROPAQUE); + scene._renderScene(context, ILaya3D.Scene3D.SCENERENDERFLAG_RENDERQPAQUE); + Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDEROPAQUE); + this._applyCommandBuffer(exports.CameraEventFlags.BeforeSkyBox, context); + scene._renderScene(context, ILaya3D.Scene3D.SCENERENDERFLAG_SKYBOX); + this._applyCommandBuffer(exports.CameraEventFlags.BeforeTransparent, context); + Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDERTRANSPARENT); + scene._renderScene(context, ILaya3D.Scene3D.SCENERENDERFLAG_RENDERTRANSPARENT); + Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDERTRANSPARENT); + scene._postRenderScript(); + this._applyCommandBuffer(exports.CameraEventFlags.BeforeImageEffect, context); + (renderTex) && (renderTex._end()); + if (needInternalRT) { + if (this._postProcess && this._postProcess.enable) { + Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_POSTPROCESS); + this._postProcess._render(); + this._postProcess._applyPostProcessCommandBuffers(); + Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_POSTPROCESS); + } + else if (this._enableHDR || this._needBuiltInRenderTexture) { + var canvasWidth = this._getCanvasWidth(), canvasHeight = this._getCanvasHeight(); + this._screenOffsetScale.setValue(viewport.x / canvasWidth, viewport.y / canvasHeight, viewport.width / canvasWidth, viewport.height / canvasHeight); + this._internalCommandBuffer._camera = this; + this._internalCommandBuffer.blitScreenQuad(this._internalRenderTexture, this._offScreenRenderTexture ? this._offScreenRenderTexture : null, this._screenOffsetScale, null, null, 0, true); + this._internalCommandBuffer._apply(); + this._internalCommandBuffer.clear(); + } + RenderTexture.recoverToPool(this._internalRenderTexture); + } + this._applyCommandBuffer(exports.CameraEventFlags.AfterEveryThing, context); + } + _renderDepthMode(context) { + Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDERDEPTHMDOE); + var cameraDepthMode = this._depthTextureMode; + if ((cameraDepthMode & exports.DepthTextureMode.Depth) != 0) { + Camera.depthPass.update(this, exports.DepthTextureMode.Depth); + Camera.depthPass.render(context, exports.DepthTextureMode.Depth); + } + if ((cameraDepthMode & exports.DepthTextureMode.DepthNormals) != 0) { + Camera.depthPass.update(this, exports.DepthTextureMode.DepthNormals); + Camera.depthPass.render(context, exports.DepthTextureMode.DepthNormals); + } + Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER_RENDERDEPTHMDOE); + } + get depthTexture() { + return this._depthTexture; + } + set depthTexture(value) { + this._depthTexture = value; + } + get depthNormalTexture() { + return this._depthNormalsTexture; + } + set depthNormalTexture(value) { + this._depthNormalsTexture = value; + } + _aftRenderMainPass(needShadowPass) { + if (needShadowPass) + ILaya3D.Scene3D._shadowCasterPass.cleanUp(); + Camera.depthPass.cleanUp(); + } + render(shader = null, replacementTag = null) { + if (!this.activeInHierarchy) + return; + var viewport = this.viewport; + var needInternalRT = this._needInternalRenderTexture(); + var context = RenderContext3D._instance; + var scene = context.scene = this._scene; + context.pipelineMode = context.configPipeLineMode; + if (needInternalRT) { + this._internalRenderTexture = RenderTexture.createFromPool(viewport.width, viewport.height, this._getRenderTextureFormat(), Laya.RenderTextureDepthFormat.DEPTH_16, 4); + this._internalRenderTexture.filterMode = Laya.FilterMode.Bilinear; + } + else { + this._internalRenderTexture = null; + } + var needShadowCasterPass = this._renderShadowMap(scene, context); + this._preRenderMainPass(context, scene, needInternalRT, viewport); + this._renderMainPass(context, viewport, scene, shader, replacementTag, needInternalRT); + this._aftRenderMainPass(needShadowCasterPass); + } + viewportPointToRay(point, out) { + this._rayViewport.x = this.viewport.x; + this._rayViewport.y = this.viewport.y; + this._rayViewport.width = Laya.Laya.stage._width; + this._rayViewport.height = Laya.Laya.stage._height; + Picker.calculateCursorRay(point, this._rayViewport, this._projectionMatrix, this.viewMatrix, null, out); + } + normalizedViewportPointToRay(point, out) { + var finalPoint = Camera._tempVector20; + var vp = this.viewport; + finalPoint.x = point.x * vp.width; + finalPoint.y = point.y * vp.height; + Picker.calculateCursorRay(finalPoint, this.viewport, this._projectionMatrix, this.viewMatrix, null, out); + } + worldToViewportPoint(position, out) { + Matrix4x4.multiply(this._projectionMatrix, this._viewMatrix, this._projectionViewMatrix); + this.viewport.project(position, this._projectionViewMatrix, out); + out.x = out.x / Laya.Laya.stage.clientScaleX; + out.y = out.y / Laya.Laya.stage.clientScaleY; + } + worldToNormalizedViewportPoint(position, out) { + Matrix4x4.multiply(this._projectionMatrix, this._viewMatrix, this._projectionViewMatrix); + this.normalizedViewport.project(position, this._projectionViewMatrix, out); + out.x = out.x / Laya.Laya.stage.clientScaleX; + out.y = out.y / Laya.Laya.stage.clientScaleY; + } + convertScreenCoordToOrthographicCoord(source, out) { + if (this._orthographic) { + var clientWidth = RenderContext3D.clientWidth; + var clientHeight = RenderContext3D.clientHeight; + var ratioX = this.orthographicVerticalSize * this.aspectRatio / clientWidth; + var ratioY = this.orthographicVerticalSize / clientHeight; + out.x = (-clientWidth / 2 + source.x * Laya.Laya.stage.clientScaleX) * ratioX; + out.y = (clientHeight / 2 - source.y * Laya.Laya.stage.clientScaleY) * ratioY; + out.z = (this.nearPlane - this.farPlane) * (source.z + 1) / 2 - this.nearPlane; + Vector3.transformCoordinate(out, this.transform.worldMatrix, out); + return true; + } + else { + return false; + } + } + destroy(destroyChild = true) { + this._offScreenRenderTexture = null; + this.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onTransformChanged); + super.destroy(destroyChild); + } + addCommandBuffer(event, commandBuffer) { + var commandBufferArray = this._cameraEventCommandBuffer[event]; + if (!commandBufferArray) + commandBufferArray = this._cameraEventCommandBuffer[event] = []; + if (commandBufferArray.indexOf(commandBuffer) < 0) + commandBufferArray.push(commandBuffer); + commandBuffer._camera = this; + } + removeCommandBuffer(event, commandBuffer) { + var commandBufferArray = this._cameraEventCommandBuffer[event]; + if (commandBufferArray) { + var index = commandBufferArray.indexOf(commandBuffer); + if (index != -1) + commandBufferArray.splice(index, 1); + } + else + throw "Camera:unknown event."; + } + removeCommandBuffers(event) { + if (this._cameraEventCommandBuffer[event]) + this._cameraEventCommandBuffer[event].length = 0; + } + _create() { + return new Camera(); + } + } + Camera._tempVector20 = new Vector2(); + Camera._updateMark = 0; + Camera.depthPass = new DepthPass(); + + class Input3D { + constructor() { + this._eventList = []; + this._mouseTouch = new MouseTouch(); + this._touchPool = []; + this._touches = new SimpleSingletonList(); + this._multiTouchEnabled = true; + this._pushEventList = ((e) => { + (e.cancelable) && (e.preventDefault()); + this._eventList.push(e); + }).bind(this); + } + __init__(canvas, scene) { + this._scene = scene; + Physics3D._bullet && (Input3D._tempHitResult0 = new Laya.HitResult()); + canvas.oncontextmenu = function (e) { + return false; + }; + } + _onCanvasEvent(canvas) { + canvas.addEventListener('mousedown', this._pushEventList); + canvas.addEventListener('mouseup', this._pushEventList, true); + canvas.addEventListener('mousemove', this._pushEventList, true); + canvas.addEventListener("touchstart", this._pushEventList); + canvas.addEventListener("touchend", this._pushEventList, true); + canvas.addEventListener("touchmove", this._pushEventList, true); + canvas.addEventListener("touchcancel", this._pushEventList, true); + } + _offCanvasEvent(canvas) { + canvas.removeEventListener('mousedown', this._pushEventList); + canvas.removeEventListener('mouseup', this._pushEventList, true); + canvas.removeEventListener('mousemove', this._pushEventList, true); + canvas.removeEventListener("touchstart", this._pushEventList); + canvas.removeEventListener("touchend", this._pushEventList, true); + canvas.removeEventListener("touchmove", this._pushEventList, true); + canvas.removeEventListener("touchcancel", this._pushEventList, true); + this._eventList.length = 0; + this._touches.clear(); + } + touchCount() { + return this._touches.length; + } + get multiTouchEnabled() { + return this._multiTouchEnabled; + } + set multiTouchEnabled(value) { + this._multiTouchEnabled = value; + } + _getTouch(touchID, type) { + var touch = this._touchPool[touchID]; + if ((type == 0 && touch && touch._getIndexInList() != -1)) + return null; + if (type == 1 && touch && (touch._getIndexInList() == -1)) + return null; + if (!touch) { + touch = new Touch(); + this._touchPool[touchID] = touch; + touch._identifier = touchID; + } + return touch; + } + _mouseTouchDown() { + var touch = this._mouseTouch; + var sprite = touch.sprite; + touch._pressedSprite = sprite; + touch._pressedLoopCount = Laya.Stat.loopCount; + if (sprite) { + var scripts = sprite._scripts; + if (scripts) { + for (var i = 0, n = scripts.length; i < n; i++) + scripts[i].onMouseDown(); + } + } + } + _mouseTouchUp() { + var i, n; + var touch = this._mouseTouch; + var lastPressedSprite = touch._pressedSprite; + touch._pressedSprite = null; + touch._pressedLoopCount = -1; + var sprite = touch.sprite; + if (sprite) { + if (sprite === lastPressedSprite) { + var scripts = sprite._scripts; + if (scripts) { + for (i = 0, n = scripts.length; i < n; i++) + scripts[i].onMouseClick(); + } + } + } + if (lastPressedSprite) { + var lastScripts = lastPressedSprite._scripts; + if (lastScripts) { + for (i = 0, n = lastScripts.length; i < n; i++) + lastScripts[i].onMouseUp(); + } + } + } + _mouseTouchRayCast(cameras) { + if (!Physics3D._bullet && !Physics3D._cannon) + return; + var touchHitResult = Input3D._tempHitResult0; + var touchPos = Input3D._tempVector20; + var touchRay = Input3D._tempRay0; + touchHitResult.succeeded = false; + var x = this._mouseTouch.mousePositionX; + var y = this._mouseTouch.mousePositionY; + touchPos.x = x; + touchPos.y = y; + for (var i = cameras.length - 1; i >= 0; i--) { + var camera = cameras[i]; + var viewport = camera.viewport; + if (touchPos.x >= viewport.x && touchPos.y >= viewport.y && touchPos.x <= viewport.width && touchPos.y <= viewport.height) { + camera.viewportPointToRay(touchPos, touchRay); + var sucess = this._scene._physicsSimulation.rayCast(touchRay, touchHitResult); + if (sucess || (camera.clearFlag === exports.CameraClearFlags.SolidColor || camera.clearFlag === exports.CameraClearFlags.Sky)) + break; + } + } + var touch = this._mouseTouch; + var lastSprite = touch.sprite; + if (touchHitResult.succeeded) { + var touchSprite = touchHitResult.collider.owner; + touch.sprite = touchSprite; + var scripts = touchSprite._scripts; + if (lastSprite !== touchSprite) { + if (scripts) { + for (var j = 0, m = scripts.length; j < m; j++) + scripts[j].onMouseEnter(); + } + } + } + else { + touch.sprite = null; + } + if (lastSprite && (lastSprite !== touchSprite)) { + var outScripts = lastSprite._scripts; + if (outScripts) { + for (j = 0, m = outScripts.length; j < m; j++) + outScripts[j].onMouseOut(); + } + } + } + _changeTouches(changedTouches, flag) { + var offsetX = 0, offsetY = 0; + var lastCount = this._touches.length; + for (var j = 0, m = changedTouches.length; j < m; j++) { + var nativeTouch = changedTouches[j]; + var identifier = nativeTouch.identifier; + if (!this._multiTouchEnabled && this._touches.length !== 0 && flag == 0) + continue; + var touch = this._getTouch(identifier, flag); + if (flag == 1 && !touch) + continue; + var pos = this._touchPool[identifier]._position; + var mousePoint = Input3D._tempPoint; + mousePoint.setTo(nativeTouch.pageX, nativeTouch.pageY); + Laya.ILaya.stage._canvasTransform.invertTransformPoint(mousePoint); + var posX = mousePoint.x; + var posY = mousePoint.y; + switch (flag) { + case 0: + if (!!touch) + this._touches.add(touch); + offsetX += posX; + offsetY += posY; + break; + case 1: + if (!!touch) + this._touches.remove(touch); + offsetX -= posX; + offsetY -= posY; + break; + case 2: + offsetX = posX - pos.x; + offsetY = posY - pos.y; + break; + } + pos.x = posX; + pos.y = posY; + } + var touchCount = this._touches.length; + if (touchCount === 0) { + this._mouseTouch.mousePositionX = 0; + this._mouseTouch.mousePositionY = 0; + } + else { + this._mouseTouch.mousePositionX = (this._mouseTouch.mousePositionX * lastCount + offsetX) / touchCount; + this._mouseTouch.mousePositionY = (this._mouseTouch.mousePositionY * lastCount + offsetY) / touchCount; + } + } + _update() { + var enablePhysics = Physics3D._enablePhysics && !Laya.PhysicsSimulation.disableSimulation; + var i, n, j, m; + n = this._eventList.length; + var cameras = this._scene._cameraPool; + if (n > 0) { + var rayCast = false; + for (i = 0; i < n; i++) { + var e = this._eventList[i]; + switch (e.type) { + case "mousedown": + (enablePhysics) && (this._mouseTouchDown()); + break; + case "mouseup": + (enablePhysics) && (this._mouseTouchUp()); + break; + case "mousemove": + var mousePoint = Input3D._tempPoint; + mousePoint.setTo(e.pageX, e.pageY); + Laya.ILaya.stage._canvasTransform.invertTransformPoint(mousePoint); + this._mouseTouch.mousePositionX = mousePoint.x; + this._mouseTouch.mousePositionY = mousePoint.y; + (enablePhysics) && (rayCast = true); + break; + case "touchstart": + var lastLength = this._touches.length; + this._changeTouches(e.changedTouches, 0); + if (enablePhysics) { + (!Config3D._config.isUseCannonPhysicsEngine) && (this._mouseTouchRayCast(cameras)); + (lastLength === 0) && (this._mouseTouchDown()); + } + break; + case "touchend": + case "touchcancel": + this._changeTouches(e.changedTouches, 1); + (enablePhysics && this._touches.length === 0) && (this._mouseTouchUp()); + break; + case "touchmove": + this._changeTouches(e.changedTouches, 2); + (enablePhysics) && (rayCast = true); + break; + default: + throw "Input3D:unkonwn event type."; + } + } + (rayCast) && (!Config3D._config.isUseCannonPhysicsEngine) && (this._mouseTouchRayCast(cameras)); + this._eventList.length = 0; + } + if (enablePhysics) { + var mouseTouch = this._mouseTouch; + var pressedSprite = mouseTouch._pressedSprite; + if (pressedSprite && (Laya.Stat.loopCount > mouseTouch._pressedLoopCount)) { + var pressedScripts = pressedSprite._scripts; + if (pressedScripts) { + for (j = 0, m = pressedScripts.length; j < m; j++) + pressedScripts[j].onMouseDrag(); + } + } + var touchSprite = mouseTouch.sprite; + if (touchSprite) { + var scripts = touchSprite._scripts; + if (scripts) { + for (j = 0, m = scripts.length; j < m; j++) + scripts[j].onMouseOver(); + } + } + } + } + getTouch(index) { + if (index < this._touches.length) { + return this._touches.elements[index]; + } + else { + return null; + } + } + } + Input3D._tempPoint = new Laya.Point(); + Input3D._tempVector20 = new Vector2(); + Input3D._tempRay0 = new Ray(new Vector3(), new Vector3()); + + class VertexPositionTexture0 { + constructor(position, textureCoordinate0) { + this._position = position; + this._textureCoordinate0 = textureCoordinate0; + } + static get vertexDeclaration() { + return VertexPositionTexture0._vertexDeclaration; + } + static __init__() { + VertexPositionTexture0._vertexDeclaration = new VertexDeclaration(20, [new VertexElement(0, VertexElementFormat.Vector3, VertexMesh.MESH_POSITION0), + new VertexElement(12, VertexElementFormat.Vector2, VertexMesh.MESH_TEXTURECOORDINATE0)]); + } + get position() { + return this._position; + } + get textureCoordinate0() { + return this._textureCoordinate0; + } + get vertexDeclaration() { + return VertexPositionTexture0._vertexDeclaration; + } + } + + class SkyDome extends SkyMesh { + constructor(stacks = 48, slices = 48) { + super(); + var gl = Laya.LayaGL.instance; + this._stacks = stacks; + this._slices = slices; + var vertexDeclaration = VertexPositionTexture0.vertexDeclaration; + var vertexFloatCount = vertexDeclaration.vertexStride / 4; + var numberVertices = (this._stacks + 1) * (this._slices + 1); + var numberIndices = (3 * this._stacks * (this._slices + 1)) * 2; + var vertices = new Float32Array(numberVertices * vertexFloatCount); + var indices = new Uint16Array(numberIndices); + var stackAngle = Math.PI / this._stacks; + var sliceAngle = (Math.PI * 2.0) / this._slices; + var vertexIndex = 0; + var vertexCount = 0; + var indexCount = 0; + for (var stack = 0; stack < (this._stacks + 1); stack++) { + var r = Math.sin(stack * stackAngle); + var y = Math.cos(stack * stackAngle); + for (var slice = 0; slice < (this._slices + 1); slice++) { + var x = r * Math.sin(slice * sliceAngle); + var z = r * Math.cos(slice * sliceAngle); + vertices[vertexCount + 0] = x * SkyDome._radius; + vertices[vertexCount + 1] = y * SkyDome._radius; + vertices[vertexCount + 2] = z * SkyDome._radius; + vertices[vertexCount + 3] = -(slice / this._slices) + 0.75; + vertices[vertexCount + 4] = stack / this._stacks; + vertexCount += vertexFloatCount; + if (stack != (this._stacks - 1)) { + indices[indexCount++] = vertexIndex + 1; + indices[indexCount++] = vertexIndex; + indices[indexCount++] = vertexIndex + (this._slices + 1); + indices[indexCount++] = vertexIndex + (this._slices + 1); + indices[indexCount++] = vertexIndex; + indices[indexCount++] = vertexIndex + (this._slices); + vertexIndex++; + } + } + } + this._vertexBuffer = new VertexBuffer3D(vertices.length * 4, gl.STATIC_DRAW, false); + this._vertexBuffer.vertexDeclaration = vertexDeclaration; + this._indexBuffer = new IndexBuffer3D(exports.IndexFormat.UInt16, indices.length, gl.STATIC_DRAW, false); + this._vertexBuffer.setData(vertices.buffer); + this._indexBuffer.setData(indices); + var bufferState = new BufferState(); + bufferState.bind(); + bufferState.applyVertexBuffer(this._vertexBuffer); + bufferState.applyIndexBuffer(this._indexBuffer); + bufferState.unBind(); + this._bufferState = bufferState; + } + static __init__() { + SkyDome.instance = new SkyDome(); + } + get stacks() { + return this._stacks; + } + get slices() { + return this._slices; + } + _render(state) { + var gl = Laya.LayaGL.instance; + var indexCount = this._indexBuffer.indexCount; + gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 0); + Laya.Stat.trianglesFaces += indexCount / 3; + Laya.Stat.renderBatches++; + } + } + SkyDome._radius = 1; + + (function (TextureCubeFace) { + TextureCubeFace[TextureCubeFace["PositiveX"] = 0] = "PositiveX"; + TextureCubeFace[TextureCubeFace["NegativeX"] = 1] = "NegativeX"; + TextureCubeFace[TextureCubeFace["PositiveY"] = 2] = "PositiveY"; + TextureCubeFace[TextureCubeFace["NegativeY"] = 3] = "NegativeY"; + TextureCubeFace[TextureCubeFace["PositiveZ"] = 4] = "PositiveZ"; + TextureCubeFace[TextureCubeFace["NegativeZ"] = 5] = "NegativeZ"; + })(exports.TextureCubeFace || (exports.TextureCubeFace = {})); + class TextureCube extends Laya.BaseTexture { + constructor(size, format = Laya.TextureFormat.R8G8B8, mipmap = false) { + super(format, mipmap); + this._glTextureType = Laya.LayaGL.instance.TEXTURE_CUBE_MAP; + this._width = size; + this._height = size; + var gl = Laya.LayaGL.instance; + this._setWarpMode(gl.TEXTURE_WRAP_S, this._wrapModeU); + this._setWarpMode(gl.TEXTURE_WRAP_T, this._wrapModeV); + this._setFilterMode(this._filterMode); + this._setAnisotropy(this._anisoLevel); + if (this._mipmap) { + this._mipmapCount = Math.ceil(Math.log2(size)) + 1; + for (var i = 0; i < this._mipmapCount; i++) + this._setPixels([], i, Math.max(size >> i, 1), Math.max(size >> i, 1)); + this._setGPUMemory(size * size * 4 * (1 + 1 / 3) * 6); + } + else { + this._mipmapCount = 1; + this._setGPUMemory(size * size * 4 * 6); + } + } + static get blackTexture() { + return TextureCube._blackTexture; + } + static get grayTexture() { + return TextureCube._grayTexture; + } + static __init__() { + var blackTexture = new TextureCube(1, Laya.TextureFormat.R8G8B8, false); + var grayTexture = new TextureCube(1, Laya.TextureFormat.R8G8B8, false); + var pixels = new Uint8Array(3); + pixels[0] = 0, pixels[1] = 0, pixels[2] = 0; + blackTexture.setSixSidePixels([pixels, pixels, pixels, pixels, pixels, pixels]); + blackTexture.lock = true; + pixels[0] = 128, pixels[1] = 128, pixels[2] = 128; + grayTexture.setSixSidePixels([pixels, pixels, pixels, pixels, pixels, pixels]); + grayTexture.lock = true; + TextureCube._grayTexture = grayTexture; + TextureCube._blackTexture = blackTexture; + } + static _parse(data, propertyParams = null, constructParams = null) { + var texture = constructParams ? new TextureCube(0, constructParams[0], constructParams[1]) : new TextureCube(0); + texture.setSixSideImageSources(data); + return texture; + } + static _parseBin(data, propertyParams = null, constructParams = null) { + var texture = constructParams ? new TextureCube(0, constructParams[0], constructParams[1]) : new TextureCube(0); + texture.setSixSideImageSources(data); + return texture; + } + static load(url, complete) { + var extension = (Laya.LoaderManager.createMap[Laya.Utils.getFilecompatibleExtension(url)]) ? Laya.Utils.getFilecompatibleExtension(url) : Laya.Utils.getFileExtension(url); + var type = Laya.LoaderManager.createMap[extension] ? Laya.LoaderManager.createMap[extension][0] : null; + Laya.ILaya.loader.create(url, complete, null, type); + } + get defaulteTexture() { + return TextureCube.grayTexture; + } + _setPixels(pixels, miplevel, width, height) { + var gl = Laya.LayaGL.instance; + var glFormat = this._getGLFormat(); + Laya.WebGLContext.bindTexture(gl, this._glTextureType, this._glTexture); + if (this.format === Laya.TextureFormat.R8G8B8) { + gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[0]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[1]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[2]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[3]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[4]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[5]); + gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4); + } + else { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[0]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[1]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[2]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[3]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[4]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, miplevel, glFormat, width, height, 0, glFormat, gl.UNSIGNED_BYTE, pixels[5]); + } + } + setSixSideImageSources(source, premultiplyAlpha = false) { + var width; + var height; + for (var i = 0; i < 6; i++) { + var img = source[i]; + if (!img) { + console.log("TextureCube: image Source can't be null."); + return; + } + var nextWidth = img.width; + var nextHeight = img.height; + if (i > 0) { + if (width !== nextWidth) { + console.log("TextureCube: each side image's width and height must same."); + return; + } + } + width = nextWidth; + height = nextHeight; + if (width !== height) { + console.log("TextureCube: each side image's width and height must same."); + return; + } + } + this._width = width; + this._height = height; + var gl = Laya.LayaGL.instance; + Laya.WebGLContext.bindTexture(gl, this._glTextureType, this._glTexture); + var glFormat = this._getGLFormat(); + if (!Laya.Render.isConchApp) { + (premultiplyAlpha) && (gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true)); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glFormat, glFormat, gl.UNSIGNED_BYTE, source[0]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glFormat, glFormat, gl.UNSIGNED_BYTE, source[1]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glFormat, glFormat, gl.UNSIGNED_BYTE, source[2]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glFormat, glFormat, gl.UNSIGNED_BYTE, source[3]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glFormat, glFormat, gl.UNSIGNED_BYTE, source[4]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glFormat, glFormat, gl.UNSIGNED_BYTE, source[5]); + (premultiplyAlpha) && (gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false)); + } + else { + if (premultiplyAlpha == true) { + for (var j = 0; j < 6; j++) + source[j].setPremultiplyAlpha(premultiplyAlpha); + } + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source[0]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source[1]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source[2]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source[3]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source[4]); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source[5]); + } + if (this._mipmap && this._isPot(width) && this._isPot(height)) { + gl.generateMipmap(this._glTextureType); + this._setGPUMemory(width * height * 4 * (1 + 1 / 3) * 6); + } + else { + this._setGPUMemory(width * height * 4 * 6); + } + this._setWarpMode(gl.TEXTURE_WRAP_S, this._wrapModeU); + this._setWarpMode(gl.TEXTURE_WRAP_T, this._wrapModeV); + this._setFilterMode(this._filterMode); + this._readyed = true; + this._activeResource(); + } + setSixSidePixels(pixels, miplevel = 0) { + if (!pixels) + throw new Error("TextureCube:pixels can't be null."); + var width = Math.max(this._width >> miplevel, 1); + var height = Math.max(this._height >> miplevel, 1); + var pixelsCount = width * height * this._getFormatByteCount(); + if (pixels[0].length < pixelsCount) + throw "TextureCube:pixels length should at least " + pixelsCount + "."; + this._setPixels(pixels, miplevel, width, height); + if (miplevel === 0) { + var gl = Laya.LayaGL.instance; + this._setWarpMode(gl.TEXTURE_WRAP_S, this._wrapModeU); + this._setWarpMode(gl.TEXTURE_WRAP_T, this._wrapModeV); + } + this._readyed = true; + this._activeResource(); + } + setImageSource(face, imageSource, miplevel = 0) { + var width = this._width; + var height = this._height; + if (imageSource) { + if (width !== imageSource.width || height !== imageSource.height) { + console.log("TextureCube: imageSource's width and height must same."); + return; + } + } + var gl = Laya.LayaGL.instance; + Laya.WebGLContext.bindTexture(gl, this._glTextureType, this._glTexture); + var glFormat = this._getGLFormat(); + switch (face) { + case exports.TextureCubeFace.NegativeX: + gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, miplevel, glFormat, glFormat, gl.UNSIGNED_BYTE, imageSource); + break; + case exports.TextureCubeFace.PositiveX: + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, miplevel, glFormat, glFormat, gl.UNSIGNED_BYTE, imageSource); + break; + case exports.TextureCubeFace.NegativeY: + gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, miplevel, glFormat, glFormat, gl.UNSIGNED_BYTE, imageSource); + break; + case exports.TextureCubeFace.PositiveY: + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, miplevel, glFormat, glFormat, gl.UNSIGNED_BYTE, imageSource); + break; + case exports.TextureCubeFace.NegativeZ: + gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, miplevel, glFormat, glFormat, gl.UNSIGNED_BYTE, imageSource); + break; + case exports.TextureCubeFace.PositiveZ: + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, miplevel, glFormat, glFormat, gl.UNSIGNED_BYTE, imageSource); + break; + } + if (this._mipmap && this._isPot(width) && this._isPot(height)) { + gl.generateMipmap(this._glTextureType); + this._setGPUMemory(width * height * 4 * (1 + 1 / 3) * 6); + } + else { + this._setGPUMemory(width * height * 4 * 6); + } + this._setWarpMode(gl.TEXTURE_WRAP_S, this._wrapModeU); + this._setWarpMode(gl.TEXTURE_WRAP_T, this._wrapModeV); + this._setFilterMode(this._filterMode); + this._readyed = true; + } + } + TextureCube.TEXTURECUBE = "TEXTURECUBE"; + TextureCube.TEXTURECUBEBIN = "TEXTURECUBEBIN"; + + class LightQueue { + constructor() { + this._length = 0; + this._elements = []; + } + add(light) { + if (this._length === this._elements.length) + this._elements.push(light); + else + this._elements[this._length] = light; + this._length++; + } + remove(light) { + var index = this._elements.indexOf(light); + this._length--; + if (index !== this._length) { + var end = this._elements[this._length]; + this._elements[index] = end; + } + } + shift() { + this._length--; + return this._elements.shift(); + } + getBrightestLight() { + var maxIntIndex; + var maxIntensity = -1; + var elements = this._elements; + for (var i = 0; i < this._length; i++) { + var intensity = elements[i]._intensity; + if (maxIntensity < intensity) { + maxIntensity = intensity; + maxIntIndex = i; + } + } + return maxIntIndex; + } + normalLightOrdering(brightestIndex) { + var firstLight = this._elements[0]; + this._elements[0] = this._elements[brightestIndex]; + this._elements[brightestIndex] = firstLight; + } + } + class AlternateLightQueue extends LightQueue { + remove(light) { + var index = this._elements.indexOf(light); + this._elements.splice(index, 1); + this._length--; + } + } + + class PixelLineMaterial extends Material { + constructor() { + super(); + this.setShaderName("LineShader"); + this._shaderValues.setVector(PixelLineMaterial.COLOR, new Vector4(1.0, 1.0, 1.0, 1.0)); + } + static __initDefine__() { + } + get color() { + return this._shaderValues.getVector(PixelLineMaterial.COLOR); + } + set color(value) { + this._shaderValues.setVector(PixelLineMaterial.COLOR, value); + } + clone() { + var dest = new PixelLineMaterial(); + this.cloneTo(dest); + return dest; + } + } + PixelLineMaterial.COLOR = Shader3D.propertyNameToID("u_Color"); + + class BoundBox { + constructor(min, max) { + this.min = min; + this.max = max; + } + _rotateExtents(extents, rotation, out) { + var extentsX = extents.x; + var extentsY = extents.y; + var extentsZ = extents.z; + var matElements = rotation.elements; + out.x = Math.abs(matElements[0] * extentsX) + Math.abs(matElements[4] * extentsY) + Math.abs(matElements[8] * extentsZ); + out.y = Math.abs(matElements[1] * extentsX) + Math.abs(matElements[5] * extentsY) + Math.abs(matElements[9] * extentsZ); + out.z = Math.abs(matElements[2] * extentsX) + Math.abs(matElements[6] * extentsY) + Math.abs(matElements[10] * extentsZ); + } + getCorners(corners) { + corners.length = 8; + var minX = this.min.x; + var minY = this.min.y; + var minZ = this.min.z; + var maxX = this.max.x; + var maxY = this.max.y; + var maxZ = this.max.z; + corners[0] = new Vector3(minX, maxY, maxZ); + corners[1] = new Vector3(maxX, maxY, maxZ); + corners[2] = new Vector3(maxX, minY, maxZ); + corners[3] = new Vector3(minX, minY, maxZ); + corners[4] = new Vector3(minX, maxY, minZ); + corners[5] = new Vector3(maxX, maxY, minZ); + corners[6] = new Vector3(maxX, minY, minZ); + corners[7] = new Vector3(minX, minY, minZ); + } + getCenter(out) { + Vector3.add(this.min, this.max, out); + Vector3.scale(out, 0.5, out); + } + getExtent(out) { + Vector3.subtract(this.max, this.min, out); + Vector3.scale(out, 0.5, out); + } + setCenterAndExtent(center, extent) { + Vector3.subtract(center, extent, this.min); + Vector3.add(center, extent, this.max); + } + tranform(matrix, out) { + var center = BoundBox._tempVector30; + var extent = BoundBox._tempVector31; + this.getCenter(center); + this.getExtent(extent); + Vector3.transformCoordinate(center, matrix, center); + this._rotateExtents(extent, matrix, extent); + out.setCenterAndExtent(center, extent); + } + toDefault() { + this.min.toDefault(); + this.max.toDefault(); + } + static createfromPoints(points, out) { + if (points == null) + throw new Error("points"); + var min = out.min; + var max = out.max; + min.x = Number.MAX_VALUE; + min.y = Number.MAX_VALUE; + min.z = Number.MAX_VALUE; + max.x = -Number.MAX_VALUE; + max.y = -Number.MAX_VALUE; + max.z = -Number.MAX_VALUE; + for (var i = 0, n = points.length; i < n; ++i) { + Vector3.min(min, points[i], min); + Vector3.max(max, points[i], max); + } + } + static merge(box1, box2, out) { + Vector3.min(box1.min, box2.min, out.min); + Vector3.max(box1.max, box2.max, out.max); + } + cloneTo(destObject) { + var dest = destObject; + this.min.cloneTo(dest.min); + this.max.cloneTo(dest.max); + } + clone() { + var dest = new BoundBox(new Vector3(), new Vector3()); + this.cloneTo(dest); + return dest; + } + } + BoundBox._tempVector30 = new Vector3(); + BoundBox._tempVector31 = new Vector3(); + + class Bounds { + constructor(min, max) { + this._updateFlag = 0; + this._center = new Vector3(); + this._extent = new Vector3(); + this._boundBox = new BoundBox(new Vector3(), new Vector3()); + min.cloneTo(this._boundBox.min); + max.cloneTo(this._boundBox.max); + this._setUpdateFlag(Bounds._UPDATE_CENTER | Bounds._UPDATE_EXTENT, true); + } + setMin(value) { + var min = this._boundBox.min; + if (value !== min) + value.cloneTo(min); + this._setUpdateFlag(Bounds._UPDATE_CENTER | Bounds._UPDATE_EXTENT, true); + this._setUpdateFlag(Bounds._UPDATE_MIN, false); + } + getMin() { + var min = this._boundBox.min; + if (this._getUpdateFlag(Bounds._UPDATE_MIN)) { + this._getMin(this.getCenter(), this.getExtent(), min); + this._setUpdateFlag(Bounds._UPDATE_MIN, false); + } + return min; + } + setMax(value) { + var max = this._boundBox.max; + if (value !== max) + value.cloneTo(max); + this._setUpdateFlag(Bounds._UPDATE_CENTER | Bounds._UPDATE_EXTENT, true); + this._setUpdateFlag(Bounds._UPDATE_MAX, false); + } + getMax() { + var max = this._boundBox.max; + if (this._getUpdateFlag(Bounds._UPDATE_MAX)) { + this._getMax(this.getCenter(), this.getExtent(), max); + this._setUpdateFlag(Bounds._UPDATE_MAX, false); + } + return max; + } + setCenter(value) { + if (value !== this._center) + value.cloneTo(this._center); + this._setUpdateFlag(Bounds._UPDATE_MIN | Bounds._UPDATE_MAX, true); + this._setUpdateFlag(Bounds._UPDATE_CENTER, false); + } + getCenter() { + if (this._getUpdateFlag(Bounds._UPDATE_CENTER)) { + this._getCenter(this.getMin(), this.getMax(), this._center); + this._setUpdateFlag(Bounds._UPDATE_CENTER, false); + } + return this._center; + } + setExtent(value) { + if (value !== this._extent) + value.cloneTo(this._extent); + this._setUpdateFlag(Bounds._UPDATE_MIN | Bounds._UPDATE_MAX, true); + this._setUpdateFlag(Bounds._UPDATE_EXTENT, false); + } + getExtent() { + if (this._getUpdateFlag(Bounds._UPDATE_EXTENT)) { + this._getExtent(this.getMin(), this.getMax(), this._extent); + this._setUpdateFlag(Bounds._UPDATE_EXTENT, false); + } + return this._extent; + } + _getUpdateFlag(type) { + return (this._updateFlag & type) != 0; + } + _setUpdateFlag(type, value) { + if (value) + this._updateFlag |= type; + else + this._updateFlag &= ~type; + } + _getCenter(min, max, out) { + Vector3.add(min, max, out); + Vector3.scale(out, 0.5, out); + } + _getExtent(min, max, out) { + Vector3.subtract(max, min, out); + Vector3.scale(out, 0.5, out); + } + _getMin(center, extent, out) { + Vector3.subtract(center, extent, out); + } + _getMax(center, extent, out) { + Vector3.add(center, extent, out); + } + _rotateExtents(extents, rotation, out) { + var extentsX = extents.x; + var extentsY = extents.y; + var extentsZ = extents.z; + var matE = rotation.elements; + out.x = Math.abs(matE[0] * extentsX) + Math.abs(matE[4] * extentsY) + Math.abs(matE[8] * extentsZ); + out.y = Math.abs(matE[1] * extentsX) + Math.abs(matE[5] * extentsY) + Math.abs(matE[9] * extentsZ); + out.z = Math.abs(matE[2] * extentsX) + Math.abs(matE[6] * extentsY) + Math.abs(matE[10] * extentsZ); + } + _tranform(matrix, out) { + var outCen = out._center; + var outExt = out._extent; + Vector3.transformCoordinate(this.getCenter(), matrix, outCen); + this._rotateExtents(this.getExtent(), matrix, outExt); + out._boundBox.setCenterAndExtent(outCen, outExt); + out._updateFlag = 0; + } + _getBoundBox() { + if (this._updateFlag & Bounds._UPDATE_MIN) { + var min = this._boundBox.min; + this._getMin(this.getCenter(), this.getExtent(), min); + this._setUpdateFlag(Bounds._UPDATE_MIN, false); + } + if (this._updateFlag & Bounds._UPDATE_MAX) { + var max = this._boundBox.max; + this._getMax(this.getCenter(), this.getExtent(), max); + this._setUpdateFlag(Bounds._UPDATE_MAX, false); + } + return this._boundBox; + } + calculateBoundsintersection(bounds) { + var ownMax = this.getMax(); + var ownMin = this.getMin(); + var calMax = bounds.getMax(); + var calMin = bounds.getMin(); + var tempV0 = Bounds.TEMP_VECTOR3_MAX0; + var tempV1 = Bounds.TEMP_VECTOR3_MAX1; + var thisExtends = this.getExtent(); + var boundExtends = bounds.getExtent(); + tempV0.setValue(Math.max(ownMax.x, calMax.x) - Math.min(ownMin.x, calMin.x), Math.max(ownMax.y, calMax.y) - Math.min(ownMin.y, calMin.y), Math.max(ownMax.z, calMax.z) - Math.min(ownMin.z, calMin.z)); + tempV1.setValue((thisExtends.x + boundExtends.x) * 2.0, (thisExtends.y + boundExtends.y) * 2.0, (thisExtends.z + boundExtends.z) * 2.0); + if ((tempV0.x) > (tempV1.x)) + return -1; + if ((tempV0.y) > (tempV1.y)) + return -1; + if ((tempV0.z) > (tempV1.z)) + return -1; + return (tempV1.x - tempV0.x) * (tempV1.y - tempV0.y) * (tempV1.z - tempV0.z); + } + cloneTo(destObject) { + var destBounds = destObject; + this.getMin().cloneTo(destBounds._boundBox.min); + this.getMax().cloneTo(destBounds._boundBox.max); + this.getCenter().cloneTo(destBounds._center); + this.getExtent().cloneTo(destBounds._extent); + destBounds._updateFlag = 0; + } + clone() { + var dest = new Bounds(new Vector3(), new Vector3()); + this.cloneTo(dest); + return dest; + } + } + Bounds._UPDATE_MIN = 0x01; + Bounds._UPDATE_MAX = 0x02; + Bounds._UPDATE_CENTER = 0x04; + Bounds._UPDATE_EXTENT = 0x08; + Bounds.TEMP_VECTOR3_MAX0 = new Vector3(); + Bounds.TEMP_VECTOR3_MAX1 = new Vector3(); + + class GeometryElement { + constructor() { + this._destroyed = false; + } + get destroyed() { + return this._destroyed; + } + _getType() { + throw "GeometryElement:must override it."; + } + _prepareRender(state) { + return true; + } + _render(state) { + throw "GeometryElement:must override it."; + } + destroy() { + if (this._destroyed) + return; + this._destroyed = true; + } + } + GeometryElement._typeCounter = 0; + + class PixelLineVertex { + constructor() { + } + static get vertexDeclaration() { + return PixelLineVertex._vertexDeclaration; + } + static __init__() { + PixelLineVertex._vertexDeclaration = new VertexDeclaration(28, [new VertexElement(0, VertexElementFormat.Vector3, VertexMesh.MESH_POSITION0), + new VertexElement(12, VertexElementFormat.Vector4, VertexMesh.MESH_COLOR0)]); + } + get vertexDeclaration() { + return PixelLineVertex._vertexDeclaration; + } + } + + class PixelLineFilter extends GeometryElement { + constructor(owner, maxLineCount) { + super(); + this._floatCountPerVertices = 7; + this._minUpdate = Number.MAX_VALUE; + this._maxUpdate = Number.MIN_VALUE; + this._bufferState = new BufferState(); + this._floatBound = new Float32Array(6); + this._calculateBound = false; + this._maxLineCount = 0; + this._lineCount = 0; + var pointCount = maxLineCount * 2; + this._owner = owner; + this._maxLineCount = maxLineCount; + this._vertices = new Float32Array(pointCount * this._floatCountPerVertices); + this._vertexBuffer = new VertexBuffer3D(PixelLineVertex.vertexDeclaration.vertexStride * pointCount, Laya.LayaGL.instance.STATIC_DRAW, false); + this._vertexBuffer.vertexDeclaration = PixelLineVertex.vertexDeclaration; + this._bufferState.bind(); + this._bufferState.applyVertexBuffer(this._vertexBuffer); + this._bufferState.unBind(); + var min = PixelLineFilter._tempVector0; + var max = PixelLineFilter._tempVector1; + min.setValue(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE); + max.setValue(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE); + this._bounds = new Bounds(min, max); + } + _getType() { + return PixelLineFilter._type; + } + _resizeLineData(maxCount) { + var pointCount = maxCount * 2; + var lastVertices = this._vertices; + this._vertexBuffer.destroy(); + this._maxLineCount = maxCount; + var vertexCount = pointCount * this._floatCountPerVertices; + this._vertices = new Float32Array(vertexCount); + this._vertexBuffer = new VertexBuffer3D(PixelLineVertex.vertexDeclaration.vertexStride * pointCount, Laya.LayaGL.instance.STATIC_DRAW, false); + this._vertexBuffer.vertexDeclaration = PixelLineVertex.vertexDeclaration; + if (vertexCount < lastVertices.length) { + this._vertices.set(new Float32Array(lastVertices.buffer, 0, vertexCount)); + this._vertexBuffer.setData(this._vertices.buffer, 0, 0, vertexCount * 4); + } + else { + this._vertices.set(lastVertices); + this._vertexBuffer.setData(this._vertices.buffer, 0, 0, lastVertices.length * 4); + } + this._bufferState.bind(); + this._bufferState.applyVertexBuffer(this._vertexBuffer); + this._bufferState.unBind(); + this._minUpdate = Number.MAX_VALUE; + this._maxUpdate = Number.MIN_VALUE; + } + _updateLineVertices(offset, startPosition, endPosition, startColor, endColor) { + if (startPosition) { + this._vertices[offset + 0] = startPosition.x; + this._vertices[offset + 1] = startPosition.y; + this._vertices[offset + 2] = startPosition.z; + } + if (startColor) { + this._vertices[offset + 3] = startColor.r; + this._vertices[offset + 4] = startColor.g; + this._vertices[offset + 5] = startColor.b; + this._vertices[offset + 6] = startColor.a; + } + if (endPosition) { + this._vertices[offset + 7] = endPosition.x; + this._vertices[offset + 8] = endPosition.y; + this._vertices[offset + 9] = endPosition.z; + } + if (endColor) { + this._vertices[offset + 10] = endColor.r; + this._vertices[offset + 11] = endColor.g; + this._vertices[offset + 12] = endColor.b; + this._vertices[offset + 13] = endColor.a; + } + this._minUpdate = Math.min(this._minUpdate, offset); + this._maxUpdate = Math.max(this._maxUpdate, offset + this._floatCountPerVertices * 2); + var bounds = this._bounds; + var floatBound = this._floatBound; + var min = bounds.getMin(), max = bounds.getMax(); + Vector3.min(min, startPosition, min); + Vector3.min(min, endPosition, min); + Vector3.max(max, startPosition, max); + Vector3.max(max, endPosition, max); + bounds.setMin(min); + bounds.setMax(max); + floatBound[0] = min.x, floatBound[1] = min.y, floatBound[2] = min.z; + floatBound[3] = max.x, floatBound[4] = max.y, floatBound[5] = max.z; + } + _reCalculateBound() { + if (this._calculateBound) { + var vertices = this._vertices; + var min = PixelLineFilter._tempVector0; + var max = PixelLineFilter._tempVector1; + min.setValue(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE); + max.setValue(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE); + for (var i = 0; i < this._lineCount * 2; ++i) { + var offset = this._floatCountPerVertices * i; + var x = vertices[offset + 0], y = vertices[offset + 1], z = vertices[offset + 2]; + min.x = Math.min(x, min.x); + min.y = Math.min(y, min.y); + min.z = Math.min(z, min.z); + max.x = Math.max(x, max.x); + max.y = Math.max(y, max.y); + max.z = Math.max(z, max.z); + } + this._bounds.setMin(min); + this._bounds.setMax(max); + var floatBound = this._floatBound; + floatBound[0] = min.x, floatBound[1] = min.y, floatBound[2] = min.z; + floatBound[3] = max.x, floatBound[4] = max.y, floatBound[5] = max.z; + this._calculateBound = false; + } + } + _removeLineData(index) { + var floatCount = this._floatCountPerVertices * 2; + var nextIndex = index + 1; + var offset = index * floatCount; + var vertices = this._vertices; + var rightPartVertices = new Float32Array(vertices.buffer, nextIndex * floatCount * 4, (this._lineCount - nextIndex) * floatCount); + vertices.set(rightPartVertices, offset); + this._minUpdate = Math.min(this._minUpdate, offset); + this._maxUpdate = Math.max(this._maxUpdate, offset + rightPartVertices.length); + this._lineCount--; + var floatBound = this._floatBound; + var startX = vertices[offset], startY = vertices[offset + 1], startZ = vertices[offset + 2]; + var endX = vertices[offset + 7], endY = vertices[offset + 8], endZ = vertices[offset + 9]; + var minX = floatBound[0], minY = floatBound[1], minZ = floatBound[2]; + var maxX = floatBound[3], maxY = floatBound[4], maxZ = floatBound[5]; + if ((startX === minX) || (startX === maxX) || (startY === minY) || (startY === maxY) || (startZ === minZ) || (startZ === maxZ) || + (endX === minX) || (endX === maxX) || (endY === minY) || (endY === maxY) || (endZ === minZ) || (endZ === maxZ)) + this._calculateBound = true; + } + _updateLineData(index, startPosition, endPosition, startColor, endColor) { + var floatCount = this._floatCountPerVertices * 2; + this._updateLineVertices(index * floatCount, startPosition, endPosition, startColor, endColor); + } + _updateLineDatas(index, data) { + var floatCount = this._floatCountPerVertices * 2; + var count = data.length; + for (var i = 0; i < count; i++) { + var line = data[i]; + this._updateLineVertices((index + i) * floatCount, line.startPosition, line.endPosition, line.startColor, line.endColor); + } + } + _getLineData(index, out) { + var startPosition = out.startPosition; + var startColor = out.startColor; + var endPosition = out.endPosition; + var endColor = out.endColor; + var vertices = this._vertices; + var offset = index * this._floatCountPerVertices * 2; + startPosition.x = vertices[offset + 0]; + startPosition.y = vertices[offset + 1]; + startPosition.z = vertices[offset + 2]; + startColor.r = vertices[offset + 3]; + startColor.g = vertices[offset + 4]; + startColor.b = vertices[offset + 5]; + startColor.a = vertices[offset + 6]; + endPosition.x = vertices[offset + 7]; + endPosition.y = vertices[offset + 8]; + endPosition.z = vertices[offset + 9]; + endColor.r = vertices[offset + 10]; + endColor.g = vertices[offset + 11]; + endColor.b = vertices[offset + 12]; + endColor.a = vertices[offset + 13]; + } + _prepareRender(state) { + return true; + } + _render(state) { + if (this._minUpdate !== Number.MAX_VALUE && this._maxUpdate !== Number.MIN_VALUE) { + this._vertexBuffer.setData(this._vertices.buffer, this._minUpdate * 4, this._minUpdate * 4, (this._maxUpdate - this._minUpdate) * 4); + this._minUpdate = Number.MAX_VALUE; + this._maxUpdate = Number.MIN_VALUE; + } + if (this._lineCount > 0) { + this._bufferState.bind(); + var gl = Laya.LayaGL.instance; + gl.drawArrays(gl.LINES, 0, this._lineCount * 2); + Laya.Stat.renderBatches++; + } + } + destroy() { + if (this._destroyed) + return; + super.destroy(); + this._bufferState.destroy(); + this._vertexBuffer.destroy(); + this._bufferState = null; + this._vertexBuffer = null; + this._vertices = null; + } + } + PixelLineFilter._tempVector0 = new Vector3(); + PixelLineFilter._tempVector1 = new Vector3(); + PixelLineFilter._type = GeometryElement._typeCounter++; + + class RenderableSprite3D extends Sprite3D { + constructor(name) { + super(name); + } + static __init__() { + RenderableSprite3D.SHADERDEFINE_RECEIVE_SHADOW = Shader3D.getDefineByName("RECEIVESHADOW"); + RenderableSprite3D.SAHDERDEFINE_LIGHTMAP = Shader3D.getDefineByName("LIGHTMAP"); + RenderableSprite3D.SHADERDEFINE_LIGHTMAP_DIRECTIONAL = Shader3D.getDefineByName("LIGHTMAP_DIRECTIONAL"); + } + _onInActive() { + super._onInActive(); + this._scene._removeRenderObject(this._render); + } + _onActive() { + super._onActive(); + this._scene._addRenderObject(this._render); + } + _onActiveInScene() { + super._onActiveInScene(); + if (ILaya3D.Laya3D._editerEnvironment) { + var scene = this._scene; + var pickColor = new Vector4(); + scene._allotPickColorByID(this.id, pickColor); + scene._pickIdToSprite[this.id] = this; + this._render._shaderValues.setVector(RenderableSprite3D.PICKCOLOR, pickColor); + } + } + _addToInitStaticBatchManager() { + } + _setBelongScene(scene) { + super._setBelongScene(scene); + this._render._setBelongScene(scene); + } + _setUnBelongScene() { + if (!this.destroyed) { + this._render._shaderValues.removeDefine(RenderableSprite3D.SAHDERDEFINE_LIGHTMAP); + this._render._setUnBelongScene(); + super._setUnBelongScene(); + } + } + _changeHierarchyAnimator(animator) { + if (this._hierarchyAnimator) { + var renderableSprites = this._hierarchyAnimator._renderableSprites; + renderableSprites.splice(renderableSprites.indexOf(this), 1); + } + if (animator) + animator._renderableSprites.push(this); + super._changeHierarchyAnimator(animator); + } + destroy(destroyChild = true) { + super.destroy(destroyChild); + this._render._destroy(); + this._render = null; + } + _create() { + return new RenderableSprite3D(this.name); + } + } + RenderableSprite3D.LIGHTMAPSCALEOFFSET = Shader3D.propertyNameToID("u_LightmapScaleOffset"); + RenderableSprite3D.LIGHTMAP = Shader3D.propertyNameToID("u_LightMap"); + RenderableSprite3D.LIGHTMAP_DIRECTION = Shader3D.propertyNameToID("u_LightMapDirection"); + RenderableSprite3D.PICKCOLOR = Shader3D.propertyNameToID("u_PickColor"); + RenderableSprite3D.REFLECTIONTEXTURE = Shader3D.propertyNameToID("u_ReflectTexture"); + RenderableSprite3D.REFLECTIONCUBE_HDR_PARAMS = Shader3D.propertyNameToID("u_ReflectCubeHDRParams"); + RenderableSprite3D.REFLECTIONCUBE_PROBEPOSITION = Shader3D.propertyNameToID("u_SpecCubeProbePosition"); + RenderableSprite3D.REFLECTIONCUBE_PROBEBOXMAX = Shader3D.propertyNameToID("u_SpecCubeBoxMax"); + RenderableSprite3D.REFLECTIONCUBE_PROBEBOXMIN = Shader3D.propertyNameToID("u_SpecCubeBoxMin"); + + class BatchMark { + constructor() { + this.updateMark = -1; + this.indexInList = -1; + this.batched = false; + } + } + + class SubMeshInstanceBatch extends GeometryElement { + constructor() { + super(); + this.instanceWorldMatrixData = new Float32Array(SubMeshInstanceBatch.maxInstanceCount * 16); + this.instanceSimpleAnimatorData = new Float32Array(SubMeshInstanceBatch.maxInstanceCount * 4); + var gl = Laya.LayaGL.instance; + this.instanceWorldMatrixBuffer = new VertexBuffer3D(this.instanceWorldMatrixData.length * 4, gl.DYNAMIC_DRAW); + this.instanceWorldMatrixBuffer.vertexDeclaration = VertexMesh.instanceWorldMatrixDeclaration; + this.instanceSimpleAnimatorBuffer = new VertexBuffer3D(this.instanceSimpleAnimatorData.length * 4, gl.DYNAMIC_DRAW); + this.instanceSimpleAnimatorBuffer.vertexDeclaration = VertexMesh.instanceSimpleAnimatorDeclaration; + } + static __init__() { + SubMeshInstanceBatch.instance = new SubMeshInstanceBatch(); + } + _render(state) { + var gl = Laya.LayaGL.instance; + var element = state.renderElement; + var subMesh = element.instanceSubMesh; + var count = element.instanceBatchElementList.length; + var indexCount = subMesh._indexCount; + subMesh._mesh._instanceBufferState.bind(); + Laya.LayaGL.layaGPUInstance.drawElementsInstanced(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, subMesh._indexStart * 2, count); + Laya.Stat.renderBatches++; + Laya.Stat.savedRenderBatches += count - 1; + Laya.Stat.trianglesFaces += indexCount * count / 3; + } + } + SubMeshInstanceBatch.maxInstanceCount = 1024; + + class RenderElement { + constructor() { + this.renderSubShader = null; + this.renderType = RenderElement.RENDERTYPE_NORMAL; + } + getInvertFront() { + return this._transform._isFrontFaceInvert; + } + setTransform(transform) { + this._transform = transform; + } + setGeometry(geometry) { + this._geometry = geometry; + } + addToOpaqueRenderQueue(context, queue) { + queue.elements.add(this); + } + addToTransparentRenderQueue(context, queue) { + queue.elements.add(this); + queue.lastTransparentBatched = false; + queue.lastTransparentRenderElement = this; + } + _update(scene, context, customShader, replacementTag, subshaderIndex = 0) { + if (this.material) { + var subShader = this.material._shader.getSubShaderAt(0); + this.renderSubShader = null; + if (customShader) { + if (replacementTag) { + var oriTag = subShader.getFlag(replacementTag); + if (oriTag) { + var customSubShaders = customShader._subShaders; + for (var k = 0, p = customSubShaders.length; k < p; k++) { + var customSubShader = customSubShaders[k]; + if (oriTag === customSubShader.getFlag(replacementTag)) { + this.renderSubShader = customSubShader; + break; + } + } + if (!this.renderSubShader) + return; + } + else { + return; + } + } + else { + this.renderSubShader = customShader.getSubShaderAt(subshaderIndex); + } + } + else { + this.renderSubShader = subShader; + } + var renderQueue = scene._getRenderQueue(this.material.renderQueue); + if (renderQueue.isTransparent) + this.addToTransparentRenderQueue(context, renderQueue); + else + this.addToOpaqueRenderQueue(context, renderQueue); + } + } + _render(context) { + var forceInvertFace = context.invertY; + var lastStateMaterial, lastStateShaderInstance, lastStateRender; + var updateMark = Camera._updateMark; + var scene = context.scene; + var cameraShaderValue = context.cameraShaderValue; + var transform = this._transform; + var geometry = this._geometry; + context.renderElement = this; + var updateRender = updateMark !== this.render._updateMark || this.renderType !== this.render._updateRenderType; + if (updateRender) { + this.render._renderUpdate(context, transform); + this.render._renderUpdateWithCamera(context, transform); + this.render._updateMark = updateMark; + this.render._updateRenderType = this.renderType; + } + else { + if (this.renderType == RenderElement.RENDERTYPE_INSTANCEBATCH) { + this.render._renderUpdate(context, transform); + this.render._renderUpdateWithCamera(context, transform); + } + } + var currentPipelineMode = context.pipelineMode; + if (geometry._prepareRender(context)) { + var passes = this.renderSubShader._passes; + for (var j = 0, m = passes.length; j < m; j++) { + var pass = passes[j]; + if (pass._pipelineMode !== currentPipelineMode) + continue; + var comDef = RenderElement._compileDefine; + scene._shaderValues._defineDatas.cloneTo(comDef); + comDef.addDefineDatas(this.render._shaderValues._defineDatas); + comDef.addDefineDatas(this.material._shaderValues._defineDatas); + var shaderIns = context.shader = pass.withCompile(comDef); + var switchShader = shaderIns.bind(); + var switchUpdateMark = (updateMark !== shaderIns._uploadMark); + var uploadScene = (shaderIns._uploadScene !== scene) || switchUpdateMark; + if (uploadScene || switchShader) { + shaderIns.uploadUniforms(shaderIns._sceneUniformParamsMap, scene._shaderValues, uploadScene); + shaderIns._uploadScene = scene; + } + var uploadSprite3D = (shaderIns._uploadRender !== this.render || shaderIns._uploadRenderType !== this.renderType) || switchUpdateMark; + if (uploadSprite3D || switchShader) { + shaderIns.uploadUniforms(shaderIns._spriteUniformParamsMap, this.render._shaderValues, uploadSprite3D); + shaderIns._uploadRender = this.render; + shaderIns._uploadRenderType = this.renderType; + } + var uploadCamera = shaderIns._uploadCameraShaderValue !== cameraShaderValue || switchUpdateMark; + if (uploadCamera || switchShader) { + shaderIns.uploadUniforms(shaderIns._cameraUniformParamsMap, cameraShaderValue, uploadCamera); + shaderIns._uploadCameraShaderValue = cameraShaderValue; + } + var uploadMaterial = (shaderIns._uploadMaterial !== this.material) || switchUpdateMark; + if (uploadMaterial || switchShader) { + shaderIns.uploadUniforms(shaderIns._materialUniformParamsMap, this.material._shaderValues, uploadMaterial); + shaderIns._uploadMaterial = this.material; + } + var matValues = this.material._shaderValues; + if (lastStateMaterial !== this.material || lastStateShaderInstance !== shaderIns) { + shaderIns.uploadRenderStateBlendDepth(matValues); + shaderIns.uploadRenderStateFrontFace(matValues, forceInvertFace, this.getInvertFront()); + lastStateMaterial = this.material; + lastStateShaderInstance = shaderIns; + lastStateRender = this.render; + } + else { + if (lastStateRender !== this.render) { + shaderIns.uploadRenderStateFrontFace(matValues, forceInvertFace, this.getInvertFront()); + lastStateRender = this.render; + } + } + geometry._render(context); + shaderIns._uploadMark = updateMark; + } + } + if (this.renderType !== RenderElement.RENDERTYPE_NORMAL) + this.render._revertBatchRenderUpdate(context); + } + destroy() { + this._transform = null; + this._geometry = null; + this.material = null; + this.render = null; + } + } + RenderElement.RENDERTYPE_NORMAL = 0; + RenderElement.RENDERTYPE_STATICBATCH = 1; + RenderElement.RENDERTYPE_INSTANCEBATCH = 2; + RenderElement.RENDERTYPE_VERTEXBATCH = 3; + RenderElement._compileDefine = new DefineDatas(); + + class SubMeshRenderElement extends RenderElement { + constructor() { + super(); + this._dynamicWorldPositionNormalNeedUpdate = true; + } + _onWorldMatrixChanged() { + this._dynamicWorldPositionNormalNeedUpdate = true; + } + _computeWorldPositionsAndNormals(positionOffset, normalOffset, multiSubMesh, vertexCount) { + if (this._dynamicWorldPositionNormalNeedUpdate) { + var subMesh = this._geometry; + var vertexBuffer = subMesh._vertexBuffer; + var vertexFloatCount = vertexBuffer.vertexDeclaration.vertexStride / 4; + var oriVertexes = vertexBuffer.getFloat32Data(); + var worldMat = this._transform.worldMatrix; + var rotation = this._transform.rotation; + var indices = subMesh._indices; + for (var i = 0; i < vertexCount; i++) { + var index = multiSubMesh ? indices[i] : i; + var oriOffset = index * vertexFloatCount; + var bakeOffset = i * 3; + Utils3D.transformVector3ArrayToVector3ArrayCoordinate(oriVertexes, oriOffset + positionOffset, worldMat, this._dynamicWorldPositions, bakeOffset); + (normalOffset !== -1) && (Utils3D.transformVector3ArrayByQuat(oriVertexes, oriOffset + normalOffset, rotation, this._dynamicWorldNormals, bakeOffset)); + } + this._dynamicWorldPositionNormalNeedUpdate = false; + } + } + setTransform(transform) { + if (this._transform !== transform) { + (this._transform) && (this._transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatrixChanged)); + (transform) && (transform.on(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatrixChanged)); + this._dynamicWorldPositionNormalNeedUpdate = true; + this._transform = transform; + } + } + setGeometry(geometry) { + if (this._geometry !== geometry) { + var subMesh = geometry; + var mesh = subMesh._mesh; + if (mesh) { + var multiSubMesh = mesh._subMeshes.length > 1; + var dynBatVerCount = multiSubMesh ? subMesh._indexCount : mesh._vertexCount; + if (dynBatVerCount <= ILaya3D.SubMeshDynamicBatch.maxAllowVertexCount) { + var length = dynBatVerCount * 3; + this._dynamicVertexBatch = true; + this._dynamicWorldPositions = new Float32Array(length); + this._dynamicWorldNormals = new Float32Array(length); + this._dynamicVertexCount = dynBatVerCount; + this._dynamicMultiSubMesh = multiSubMesh; + } + else { + this._dynamicVertexBatch = false; + } + } + this._geometry = geometry; + } + } + addToOpaqueRenderQueue(context, queue) { + var subMeshStaticBatch = this.staticBatch; + var queueElements = queue.elements; + var elements = queueElements.elements; + if (subMeshStaticBatch && (!this.render._probReflection || this.render._probReflection._isScene) && SubMeshRenderElement.enableStaticBatch) { + var staManager = ILaya3D.MeshRenderStaticBatchManager.instance; + var staBatchMarks = staManager.getBatchOpaquaMark(this.render.lightmapIndex + 1, this.render.receiveShadow, this.material.id, subMeshStaticBatch._batchID); + if (staManager._updateCountMark === staBatchMarks.updateMark) { + var staBatchIndex = staBatchMarks.indexInList; + if (staBatchMarks.batched) { + elements[staBatchIndex].staticBatchElementList.add(this); + } + else { + var staOriElement = elements[staBatchIndex]; + var staOriRender = staOriElement.render; + var staBatchElement = staManager._getBatchRenderElementFromPool(); + staBatchElement.renderType = RenderElement.RENDERTYPE_STATICBATCH; + staBatchElement.setGeometry(subMeshStaticBatch); + staBatchElement.material = staOriElement.material; + var staRootOwner = subMeshStaticBatch.batchOwner; + var staBatchTransform = staRootOwner ? staRootOwner._transform : null; + staBatchElement.setTransform(staBatchTransform); + staBatchElement.render = staOriRender; + staBatchElement.renderSubShader = staOriElement.renderSubShader; + var staBatchList = staBatchElement.staticBatchElementList; + staBatchList.length = 0; + staBatchList.add(staOriElement); + staBatchList.add(this); + elements[staBatchIndex] = staBatchElement; + staBatchMarks.batched = true; + } + } + else { + staBatchMarks.updateMark = staManager._updateCountMark; + staBatchMarks.indexInList = queueElements.length; + staBatchMarks.batched = false; + queueElements.add(this); + } + } + else if (SubMeshRenderElement.enableDynamicBatch && this.renderSubShader._owner._enableInstancing && Laya.LayaGL.layaGPUInstance.supportInstance() && this.render.lightmapIndex < 0 && (!this.render._probReflection || this.render._probReflection._isScene)) { + var subMesh = this._geometry; + var insManager = ILaya3D.MeshRenderDynamicBatchManager.instance; + var insBatchMarks = insManager.getInstanceBatchOpaquaMark(this.render.receiveShadow, this.material.id, subMesh._id, this._transform._isFrontFaceInvert); + if (insManager._updateCountMark === insBatchMarks.updateMark) { + var insBatchIndex = insBatchMarks.indexInList; + if (insBatchMarks.batched) { + var instanceBatchElementList = elements[insBatchIndex].instanceBatchElementList; + if (instanceBatchElementList.length === SubMeshInstanceBatch.maxInstanceCount) { + insBatchMarks.updateMark = insManager._updateCountMark; + insBatchMarks.indexInList = queueElements.length; + insBatchMarks.batched = false; + queueElements.add(this); + } + else { + instanceBatchElementList.add(this); + } + } + else { + var insOriElement = elements[insBatchIndex]; + var insOriRender = insOriElement.render; + var insBatchElement = insManager._getBatchRenderElementFromPool(); + insBatchElement.renderType = RenderElement.RENDERTYPE_INSTANCEBATCH; + insBatchElement.setGeometry(SubMeshInstanceBatch.instance); + insBatchElement.material = insOriElement.material; + insBatchElement.setTransform(null); + insBatchElement.render = insOriRender; + insBatchElement.instanceSubMesh = subMesh; + insBatchElement.renderSubShader = insOriElement.renderSubShader; + var insBatchList = insBatchElement.instanceBatchElementList; + insBatchList.length = 0; + insBatchList.add(insOriElement); + insBatchList.add(this); + elements[insBatchIndex] = insBatchElement; + insBatchMarks.batched = true; + } + } + else { + insBatchMarks.updateMark = insManager._updateCountMark; + insBatchMarks.indexInList = queueElements.length; + insBatchMarks.batched = false; + queueElements.add(this); + } + } + else if (this._dynamicVertexBatch && SubMeshRenderElement.enableDynamicBatch) { + var verDec = this._geometry._vertexBuffer.vertexDeclaration; + var dynManager = ILaya3D.MeshRenderDynamicBatchManager.instance; + var dynBatchMarks = dynManager.getVertexBatchOpaquaMark(this.render.lightmapIndex + 1, this.render.receiveShadow, this.material.id, verDec.id); + if (dynManager._updateCountMark === dynBatchMarks.updateMark) { + var dynBatchIndex = dynBatchMarks.indexInList; + if (dynBatchMarks.batched) { + elements[dynBatchIndex].vertexBatchElementList.add(this); + } + else { + var dynOriElement = elements[dynBatchIndex]; + var dynOriRender = dynOriElement.render; + var dynBatchElement = dynManager._getBatchRenderElementFromPool(); + dynBatchElement.renderType = RenderElement.RENDERTYPE_VERTEXBATCH; + dynBatchElement.setGeometry(ILaya3D.SubMeshDynamicBatch.instance); + dynBatchElement.material = dynOriElement.material; + dynBatchElement.setTransform(null); + dynBatchElement.render = dynOriRender; + dynBatchElement.vertexBatchVertexDeclaration = verDec; + dynBatchElement.renderSubShader = dynOriElement.renderSubShader; + var dynBatchList = dynBatchElement.vertexBatchElementList; + dynBatchList.length = 0; + dynBatchList.add(dynOriElement); + dynBatchList.add(this); + elements[dynBatchIndex] = dynBatchElement; + dynBatchMarks.batched = true; + } + } + else { + dynBatchMarks.updateMark = dynManager._updateCountMark; + dynBatchMarks.indexInList = queueElements.length; + dynBatchMarks.batched = false; + queueElements.add(this); + } + } + else { + queueElements.add(this); + } + } + addToTransparentRenderQueue(context, queue) { + var subMeshStaticBatch = this.staticBatch; + var queueElements = queue.elements; + var elements = queueElements.elements; + if (subMeshStaticBatch && SubMeshRenderElement.enableStaticBatch) { + var staManager = ILaya3D.MeshRenderStaticBatchManager.instance; + var staLastElement = queue.lastTransparentRenderElement; + if (staLastElement) { + var staLastRender = staLastElement.render; + if (staLastElement._geometry._getType() !== this._geometry._getType() || staLastElement.staticBatch !== subMeshStaticBatch || staLastElement.material !== this.material || staLastRender.receiveShadow !== this.render.receiveShadow || staLastRender.lightmapIndex !== this.render.lightmapIndex) { + queueElements.add(this); + queue.lastTransparentBatched = false; + } + else { + if (queue.lastTransparentBatched) { + elements[queueElements.length - 1].staticBatchElementList.add((this)); + } + else { + var staBatchElement = staManager._getBatchRenderElementFromPool(); + staBatchElement.renderType = RenderElement.RENDERTYPE_STATICBATCH; + staBatchElement.setGeometry(subMeshStaticBatch); + staBatchElement.material = staLastElement.material; + var staRootOwner = subMeshStaticBatch.batchOwner; + var staBatchTransform = staRootOwner ? staRootOwner._transform : null; + staBatchElement.setTransform(staBatchTransform); + staBatchElement.render = this.render; + staBatchElement.renderSubShader = staLastElement.renderSubShader; + var staBatchList = staBatchElement.staticBatchElementList; + staBatchList.length = 0; + staBatchList.add(staLastElement); + staBatchList.add(this); + elements[queueElements.length - 1] = staBatchElement; + } + queue.lastTransparentBatched = true; + } + } + else { + queueElements.add(this); + queue.lastTransparentBatched = false; + } + } + else if (SubMeshRenderElement.enableDynamicBatch && this.renderSubShader._owner._enableInstancing && Laya.LayaGL.layaGPUInstance.supportInstance() && this.render.lightmapIndex < 0 && (!this.render._probReflection || this.render._probReflection._isScene)) { + var subMesh = this._geometry; + var insManager = ILaya3D.MeshRenderDynamicBatchManager.instance; + var insLastElement = queue.lastTransparentRenderElement; + if (insLastElement) { + var insLastRender = insLastElement.render; + if (insLastElement._geometry._getType() !== this._geometry._getType() || insLastElement._geometry !== subMesh || insLastElement.material !== this.material || insLastRender.receiveShadow !== this.render.receiveShadow) { + queueElements.add(this); + queue.lastTransparentBatched = false; + } + else { + if (queue.lastTransparentBatched) { + var instanceBatchElementList = elements[queueElements.length - 1].instanceBatchElementList; + if (instanceBatchElementList.length === SubMeshInstanceBatch.maxInstanceCount) { + queueElements.add(this); + queue.lastTransparentBatched = false; + } + else { + instanceBatchElementList.add(this); + queue.lastTransparentBatched = true; + } + } + else { + var insBatchElement = insManager._getBatchRenderElementFromPool(); + insBatchElement.renderType = RenderElement.RENDERTYPE_INSTANCEBATCH; + insBatchElement.setGeometry(SubMeshInstanceBatch.instance); + insBatchElement.material = insLastElement.material; + insBatchElement.setTransform(null); + insBatchElement.render = this.render; + insBatchElement.instanceSubMesh = subMesh; + insBatchElement.renderSubShader = insLastElement.renderSubShader; + var insBatchList = insBatchElement.instanceBatchElementList; + insBatchList.length = 0; + insBatchList.add(insLastElement); + insBatchList.add(this); + elements[queueElements.length - 1] = insBatchElement; + queue.lastTransparentBatched = true; + } + } + } + else { + queueElements.add(this); + queue.lastTransparentBatched = false; + } + } + else if (this._dynamicVertexBatch && SubMeshRenderElement.enableDynamicBatch) { + var verDec = this._geometry._vertexBuffer.vertexDeclaration; + var dynManager = ILaya3D.MeshRenderDynamicBatchManager.instance; + var dynLastElement = queue.lastTransparentRenderElement; + if (dynLastElement) { + var dynLastRender = dynLastElement.render; + if (!dynLastElement._dynamicVertexBatch || dynLastElement._geometry._getType() !== this._geometry._getType() || dynLastElement._geometry._vertexBuffer._vertexDeclaration !== verDec || dynLastElement.material !== this.material || dynLastRender.receiveShadow !== this.render.receiveShadow || dynLastRender.lightmapIndex !== this.render.lightmapIndex) { + queueElements.add(this); + queue.lastTransparentBatched = false; + } + else { + if (queue.lastTransparentBatched) { + elements[queueElements.length - 1].vertexBatchElementList.add((this)); + } + else { + var dynBatchElement = dynManager._getBatchRenderElementFromPool(); + dynBatchElement.renderType = RenderElement.RENDERTYPE_VERTEXBATCH; + dynBatchElement.setGeometry(ILaya3D.SubMeshDynamicBatch.instance); + dynBatchElement.material = dynLastElement.material; + dynBatchElement.setTransform(null); + dynBatchElement.render = this.render; + dynBatchElement.vertexBatchVertexDeclaration = verDec; + dynBatchElement.renderSubShader = dynLastElement.renderSubShader; + var dynBatchList = dynBatchElement.vertexBatchElementList; + dynBatchList.length = 0; + dynBatchList.add(dynLastElement); + dynBatchList.add(this); + elements[queueElements.length - 1] = dynBatchElement; + } + queue.lastTransparentBatched = true; + } + } + else { + queueElements.add(this); + queue.lastTransparentBatched = false; + } + } + else { + queueElements.add(this); + } + queue.lastTransparentRenderElement = this; + } + getInvertFront() { + switch (this.renderType) { + case RenderElement.RENDERTYPE_NORMAL: + return this._transform._isFrontFaceInvert; + case RenderElement.RENDERTYPE_STATICBATCH: + case RenderElement.RENDERTYPE_VERTEXBATCH: + return false; + case RenderElement.RENDERTYPE_INSTANCEBATCH: + return this.instanceBatchElementList.elements[0]._transform._isFrontFaceInvert; + default: + throw "SubMeshRenderElement: unknown renderType"; + } + } + destroy() { + super.destroy(); + this._dynamicWorldPositions = null; + this._dynamicWorldNormals = null; + this.staticBatch = null; + this.staticBatchElementList = null; + this.vertexBatchElementList = null; + this.vertexBatchVertexDeclaration = null; + } + } + SubMeshRenderElement.enableDynamicBatch = true; + SubMeshRenderElement.enableStaticBatch = true; + + class StaticBatchManager { + constructor() { + this._initBatchSprites = []; + this._staticBatches = {}; + this._batchRenderElementPoolIndex = 0; + this._batchRenderElementPool = []; + } + static _addToStaticBatchQueue(sprite3D, renderableSprite3D) { + if (sprite3D instanceof RenderableSprite3D) + renderableSprite3D.push(sprite3D); + for (var i = 0, n = sprite3D.numChildren; i < n; i++) + StaticBatchManager._addToStaticBatchQueue(sprite3D._children[i], renderableSprite3D); + } + static _registerManager(manager) { + StaticBatchManager._managers.push(manager); + } + static combine(staticBatchRoot, renderableSprite3Ds = null) { + if (!renderableSprite3Ds) { + renderableSprite3Ds = []; + if (staticBatchRoot) + StaticBatchManager._addToStaticBatchQueue(staticBatchRoot, renderableSprite3Ds); + } + var batchSpritesCount = renderableSprite3Ds.length; + if (batchSpritesCount > 0) { + for (var i = 0; i < batchSpritesCount; i++) { + var sprite = renderableSprite3Ds[i]; + if (!sprite.destroyed) { + if (sprite._render._isPartOfStaticBatch) + console.warn("StaticBatchManager: Sprite " + sprite.name + " has a part of Static Batch,it will be ignore."); + else + sprite._addToInitStaticBatchManager(); + } + } + for (var k = 0, m = StaticBatchManager._managers.length; k < m; k++) { + var manager = StaticBatchManager._managers[k]; + manager._initStaticBatchs(staticBatchRoot); + } + } + } + _partition(items, left, right) { + var pivot = items[Math.floor((right + left) / 2)]; + while (left <= right) { + while (this._compare(items[left], pivot) < 0) + left++; + while (this._compare(items[right], pivot) > 0) + right--; + if (left < right) { + var temp = items[left]; + items[left] = items[right]; + items[right] = temp; + left++; + right--; + } + else if (left === right) { + left++; + break; + } + } + return left; + } + _quickSort(items, left, right) { + if (items.length > 1) { + var index = this._partition(items, left, right); + var leftIndex = index - 1; + if (left < leftIndex) + this._quickSort(items, left, leftIndex); + if (index < right) + this._quickSort(items, index, right); + } + } + _compare(left, right) { + throw "StaticBatch:must override this function."; + } + _initStaticBatchs(rootSprite) { + throw "StaticBatch:must override this function."; + } + _getBatchRenderElementFromPool() { + throw "StaticBatch:must override this function."; + } + _addBatchSprite(renderableSprite3D) { + this._initBatchSprites.push(renderableSprite3D); + } + _clear() { + this._batchRenderElementPoolIndex = 0; + } + _garbageCollection() { + throw "StaticBatchManager: must override it."; + } + dispose() { + this._staticBatches = null; + } + } + StaticBatchManager._managers = []; + + class SubMeshStaticBatch extends GeometryElement { + constructor(batchOwner, vertexDeclaration) { + super(); + this._bufferState = new BufferState(); + this._batchID = SubMeshStaticBatch._batchIDCounter++; + this._batchElements = []; + this._currentBatchVertexCount = 0; + this._currentBatchIndexCount = 0; + this._vertexDeclaration = vertexDeclaration; + this.batchOwner = batchOwner; + } + _getStaticBatchBakedVertexs(batchVertices, batchOffset, batchOwnerTransform, transform, render, mesh) { + var vertexBuffer = mesh._vertexBuffer; + var vertexDeclaration = vertexBuffer.vertexDeclaration; + var positionOffset = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_POSITION0)._offset / 4; + var normalElement = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_NORMAL0); + var normalOffset = normalElement ? normalElement._offset / 4 : -1; + var colorElement = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_COLOR0); + var colorOffset = colorElement ? colorElement._offset / 4 : -1; + var uv0Element = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_TEXTURECOORDINATE0); + var uv0Offset = uv0Element ? uv0Element._offset / 4 : -1; + var uv1Element = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_TEXTURECOORDINATE1); + var uv1Offset = uv1Element ? uv1Element._offset / 4 : -1; + var tangentElement = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_TANGENT0); + var sTangentOffset = tangentElement ? tangentElement._offset / 4 : -1; + var bakeVertexFloatCount = 18; + var oriVertexFloatCount = vertexDeclaration.vertexStride / 4; + var oriVertexes = vertexBuffer.getFloat32Data(); + var worldMat; + if (batchOwnerTransform) { + var rootMat = batchOwnerTransform.worldMatrix; + rootMat.invert(SubMeshStaticBatch._tempMatrix4x40); + worldMat = SubMeshStaticBatch._tempMatrix4x41; + Matrix4x4.multiply(SubMeshStaticBatch._tempMatrix4x40, transform.worldMatrix, worldMat); + } + else { + worldMat = transform.worldMatrix; + } + var normalMat = SubMeshStaticBatch._tempMatrix4x42; + worldMat.invert(normalMat); + normalMat.transpose(); + var rotation = SubMeshStaticBatch._tempQuaternion0; + worldMat.decomposeTransRotScale(SubMeshStaticBatch._tempVector30, rotation, SubMeshStaticBatch._tempVector31); + var lightmapScaleOffset = render.lightmapScaleOffset; + var vertexCount = mesh.vertexCount; + for (var i = 0; i < vertexCount; i++) { + var oriOffset = i * oriVertexFloatCount; + var bakeOffset = (i + batchOffset) * bakeVertexFloatCount; + Utils3D.transformVector3ArrayToVector3ArrayCoordinate(oriVertexes, oriOffset + positionOffset, worldMat, batchVertices, bakeOffset + 0); + if (normalOffset !== -1) + Utils3D.transformVector3ArrayToVector3ArrayNormal(oriVertexes, oriOffset + normalOffset, normalMat, batchVertices, bakeOffset + 3); + var j, m; + var bakOff = bakeOffset + 6; + if (colorOffset !== -1) { + var oriOff = oriOffset + colorOffset; + for (j = 0, m = 4; j < m; j++) + batchVertices[bakOff + j] = oriVertexes[oriOff + j]; + } + else { + for (j = 0, m = 4; j < m; j++) + batchVertices[bakOff + j] = 1.0; + } + if (uv0Offset !== -1) { + var absUv0Offset = oriOffset + uv0Offset; + batchVertices[bakeOffset + 10] = oriVertexes[absUv0Offset]; + batchVertices[bakeOffset + 11] = oriVertexes[absUv0Offset + 1]; + } + if (lightmapScaleOffset) { + if (uv1Offset !== -1) + Utils3D.transformLightingMapTexcoordArray(oriVertexes, oriOffset + uv1Offset, lightmapScaleOffset, batchVertices, bakeOffset + 12); + else + Utils3D.transformLightingMapTexcoordArray(oriVertexes, oriOffset + uv0Offset, lightmapScaleOffset, batchVertices, bakeOffset + 12); + } + if (sTangentOffset !== -1) { + var absSTanegntOffset = oriOffset + sTangentOffset; + Utils3D.transformVector3ArrayToVector3ArrayNormal(oriVertexes, absSTanegntOffset, normalMat, batchVertices, bakeOffset + 14); + batchVertices[bakeOffset + 17] = oriVertexes[absSTanegntOffset + 3]; + } + } + return vertexCount; + } + addTest(sprite) { + var vertexCount; + var subMeshVertexCount = sprite.meshFilter.sharedMesh.vertexCount; + vertexCount = this._currentBatchVertexCount + subMeshVertexCount; + if (vertexCount > SubMeshStaticBatch.maxBatchVertexCount) + return false; + return true; + } + add(sprite) { + var mesh = sprite.meshFilter.sharedMesh; + var subMeshVertexCount = mesh.vertexCount; + this._batchElements.push(sprite); + var render = sprite._render; + render._isPartOfStaticBatch = true; + render._staticBatch = this; + var renderElements = render._renderElements; + for (var i = 0, n = renderElements.length; i < n; i++) + renderElements[i].staticBatch = this; + this._currentBatchIndexCount += mesh._indexBuffer.indexCount; + this._currentBatchVertexCount += subMeshVertexCount; + } + remove(sprite) { + var mesh = sprite.meshFilter.sharedMesh; + var index = this._batchElements.indexOf(sprite); + if (index !== -1) { + this._batchElements.splice(index, 1); + var renderElements = sprite._render._renderElements; + for (var i = 0, n = renderElements.length; i < n; i++) + renderElements[i].staticBatch = null; + this._currentBatchIndexCount = this._currentBatchIndexCount - mesh._indexBuffer.indexCount; + this._currentBatchVertexCount = this._currentBatchVertexCount - mesh.vertexCount; + sprite._render._isPartOfStaticBatch = false; + } + } + finishInit() { + if (this._vertexBuffer) { + this._vertexBuffer.destroy(); + this._indexBuffer.destroy(); + Laya.Resource._addGPUMemory(-(this._vertexBuffer._byteLength + this._indexBuffer._byteLength)); + } + var gl = Laya.LayaGL.instance; + var batchVertexCount = 0; + var batchIndexCount = 0; + var rootOwner = this.batchOwner; + var floatStride = this._vertexDeclaration.vertexStride / 4; + var vertexDatas = new Float32Array(floatStride * this._currentBatchVertexCount); + var indexDatas = new Uint16Array(this._currentBatchIndexCount); + this._vertexBuffer = new VertexBuffer3D(this._vertexDeclaration.vertexStride * this._currentBatchVertexCount, gl.STATIC_DRAW); + this._vertexBuffer.vertexDeclaration = this._vertexDeclaration; + this._indexBuffer = new IndexBuffer3D(exports.IndexFormat.UInt16, this._currentBatchIndexCount, gl.STATIC_DRAW); + for (var i = 0, n = this._batchElements.length; i < n; i++) { + var sprite = this._batchElements[i]; + var mesh = sprite.meshFilter.sharedMesh; + var meshVerCount = this._getStaticBatchBakedVertexs(vertexDatas, batchVertexCount, rootOwner ? rootOwner._transform : null, sprite._transform, sprite._render, mesh); + var indices = mesh._indexBuffer.getData(); + var indexOffset = batchVertexCount; + var indexEnd = batchIndexCount + indices.length; + var elements = sprite._render._renderElements; + for (var j = 0, m = mesh.subMeshCount; j < m; j++) { + var subMesh = mesh._subMeshes[j]; + var start = batchIndexCount + subMesh._indexStart; + var element = elements[j]; + element.staticBatchIndexStart = start; + element.staticBatchIndexEnd = start + subMesh._indexCount; + } + indexDatas.set(indices, batchIndexCount); + var k; + var isInvert = rootOwner ? (sprite._transform._isFrontFaceInvert !== rootOwner.transform._isFrontFaceInvert) : sprite._transform._isFrontFaceInvert; + if (isInvert) { + for (k = batchIndexCount; k < indexEnd; k += 3) { + indexDatas[k] = indexOffset + indexDatas[k]; + var index1 = indexDatas[k + 1]; + var index2 = indexDatas[k + 2]; + indexDatas[k + 1] = indexOffset + index2; + indexDatas[k + 2] = indexOffset + index1; + } + } + else { + for (k = batchIndexCount; k < indexEnd; k += 3) { + indexDatas[k] = indexOffset + indexDatas[k]; + indexDatas[k + 1] = indexOffset + indexDatas[k + 1]; + indexDatas[k + 2] = indexOffset + indexDatas[k + 2]; + } + } + batchIndexCount += indices.length; + batchVertexCount += meshVerCount; + } + this._vertexBuffer.setData(vertexDatas.buffer); + this._indexBuffer.setData(indexDatas); + var memorySize = this._vertexBuffer._byteLength + this._indexBuffer._byteLength; + Laya.Resource._addGPUMemory(memorySize); + this._bufferState.bind(); + this._bufferState.applyVertexBuffer(this._vertexBuffer); + this._bufferState.applyIndexBuffer(this._indexBuffer); + this._bufferState.unBind(); + } + _render(state) { + this._bufferState.bind(); + var gl = Laya.LayaGL.instance; + var element = state.renderElement; + var staticBatchElementList = element.staticBatchElementList; + var batchElementList = staticBatchElementList.elements; + var from = 0; + var end = 0; + var count = staticBatchElementList.length; + for (var i = 1; i < count; i++) { + var lastElement = batchElementList[i - 1]; + if (lastElement.staticBatchIndexEnd === batchElementList[i].staticBatchIndexStart) { + end++; + continue; + } + else { + var start = batchElementList[from].staticBatchIndexStart; + var indexCount = batchElementList[end].staticBatchIndexEnd - start; + gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, start * 2); + from = ++end; + Laya.Stat.trianglesFaces += indexCount / 3; + } + } + start = batchElementList[from].staticBatchIndexStart; + indexCount = batchElementList[end].staticBatchIndexEnd - start; + gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, start * 2); + Laya.Stat.renderBatches++; + Laya.Stat.savedRenderBatches += count - 1; + Laya.Stat.trianglesFaces += indexCount / 3; + } + dispose() { + var memorySize = this._vertexBuffer._byteLength + this._indexBuffer._byteLength; + Laya.Resource._addGPUMemory(-memorySize); + this._batchElements = null; + this.batchOwner = null; + this._vertexDeclaration = null; + this._bufferState.destroy(); + this._vertexBuffer.destroy(); + this._indexBuffer.destroy(); + this._vertexBuffer = null; + this._indexBuffer = null; + this._bufferState = null; + } + } + SubMeshStaticBatch._tempVector30 = new Vector3(); + SubMeshStaticBatch._tempVector31 = new Vector3(); + SubMeshStaticBatch._tempQuaternion0 = new Quaternion(); + SubMeshStaticBatch._tempMatrix4x40 = new Matrix4x4(); + SubMeshStaticBatch._tempMatrix4x41 = new Matrix4x4(); + SubMeshStaticBatch._tempMatrix4x42 = new Matrix4x4(); + SubMeshStaticBatch.maxBatchVertexCount = 65535; + SubMeshStaticBatch._batchIDCounter = 0; + + class MeshRenderStaticBatchManager extends StaticBatchManager { + constructor() { + super(); + this._opaqueBatchMarks = []; + this._updateCountMark = 0; + } + static __init__() { + MeshRenderStaticBatchManager._verDec = VertexMesh.getVertexDeclaration("POSITION,NORMAL,COLOR,UV,UV1,TANGENT"); + } + _compare(left, right) { + var lRender = left._render, rRender = right._render; + var leftGeo = left.meshFilter.sharedMesh, rightGeo = right.meshFilter.sharedMesh; + var lightOffset = lRender.lightmapIndex - rRender.lightmapIndex; + if (lightOffset === 0) { + var receiveShadowOffset = (lRender.receiveShadow ? 1 : 0) - (rRender.receiveShadow ? 1 : 0); + if (receiveShadowOffset === 0) { + var materialOffset = (lRender.sharedMaterial && rRender.sharedMaterial) ? lRender.sharedMaterial.id - rRender.sharedMaterial.id : 0; + if (materialOffset === 0) { + var verDec = leftGeo._vertexBuffer.vertexDeclaration.id - rightGeo._vertexBuffer.vertexDeclaration.id; + if (verDec === 0) { + return rightGeo._indexBuffer.indexCount - leftGeo._indexBuffer.indexCount; + } + else { + return verDec; + } + } + else { + return materialOffset; + } + } + else { + return receiveShadowOffset; + } + } + else { + return lightOffset; + } + } + _getBatchRenderElementFromPool() { + var renderElement = this._batchRenderElementPool[this._batchRenderElementPoolIndex++]; + if (!renderElement) { + renderElement = new SubMeshRenderElement(); + this._batchRenderElementPool[this._batchRenderElementPoolIndex - 1] = renderElement; + renderElement.staticBatchElementList = new SingletonList(); + } + return renderElement; + } + _getStaticBatch(staticBatches, rootOwner, number) { + var subMeshStaticBatch = staticBatches[number]; + if (!subMeshStaticBatch) { + subMeshStaticBatch = staticBatches[number] = new SubMeshStaticBatch(rootOwner, MeshRenderStaticBatchManager._verDec); + this._staticBatches[subMeshStaticBatch._batchID] = subMeshStaticBatch; + } + return subMeshStaticBatch; + } + _initStaticBatchs(rootOwner) { + var initBatchSprites = this._initBatchSprites; + this._quickSort(initBatchSprites, 0, initBatchSprites.length - 1); + var staticBatches = []; + var lastCanMerage = false; + var curStaticBatch; + var batchNumber = 0; + for (var i = 0, n = initBatchSprites.length; i < n; i++) { + var sprite = initBatchSprites[i]; + if (lastCanMerage) { + if (curStaticBatch.addTest(sprite)) { + curStaticBatch.add(sprite); + } + else { + lastCanMerage = false; + batchNumber++; + } + } + else { + var lastIndex = n - 1; + if (i !== lastIndex) { + curStaticBatch = this._getStaticBatch(staticBatches, rootOwner, batchNumber); + curStaticBatch.add(sprite); + lastCanMerage = true; + } + } + } + for (i = 0, n = staticBatches.length; i < n; i++) { + var staticBatch = staticBatches[i]; + staticBatch && staticBatch.finishInit(); + } + this._initBatchSprites.length = 0; + } + _removeRenderSprite(sprite) { + var render = sprite._render; + var staticBatch = render._staticBatch; + var batchElements = staticBatch._batchElements; + var index = batchElements.indexOf(sprite); + if (index !== -1) { + batchElements.splice(index, 1); + render._staticBatch = null; + var renderElements = render._renderElements; + for (var i = 0, n = renderElements.length; i < n; i++) + renderElements[i].staticBatch = null; + } + if (batchElements.length === 0) { + delete this._staticBatches[staticBatch._batchID]; + staticBatch.dispose(); + } + } + _clear() { + super._clear(); + this._updateCountMark++; + } + _garbageCollection() { + for (var key in this._staticBatches) { + var staticBatch = this._staticBatches[key]; + if (staticBatch._batchElements.length === 0) { + staticBatch.dispose(); + delete this._staticBatches[key]; + } + } + } + getBatchOpaquaMark(lightMapIndex, receiveShadow, materialID, staticBatchID) { + var receiveShadowIndex = receiveShadow ? 1 : 0; + var staLightMapMarks = (this._opaqueBatchMarks[lightMapIndex]) || (this._opaqueBatchMarks[lightMapIndex] = []); + var staReceiveShadowMarks = (staLightMapMarks[receiveShadowIndex]) || (staLightMapMarks[receiveShadowIndex] = []); + var staMaterialMarks = (staReceiveShadowMarks[materialID]) || (staReceiveShadowMarks[materialID] = []); + return (staMaterialMarks[staticBatchID]) || (staMaterialMarks[staticBatchID] = new BatchMark); + } + } + MeshRenderStaticBatchManager.instance = new MeshRenderStaticBatchManager(); + + (function (ReflectionProbeMode) { + ReflectionProbeMode[ReflectionProbeMode["off"] = 0] = "off"; + ReflectionProbeMode[ReflectionProbeMode["simple"] = 1] = "simple"; + })(exports.ReflectionProbeMode || (exports.ReflectionProbeMode = {})); + class ReflectionProbe extends Sprite3D { + constructor() { + super(); + this._boxProjection = false; + this._size = new Vector3(); + this._offset = new Vector3(); + this._reflectionHDRParams = new Vector4(); + this._reflectionDecodeFormat = Laya.TextureDecodeFormat.Normal; + this._isScene = false; + } + get boxProjection() { + return this._boxProjection; + } + set boxProjection(value) { + this._boxProjection = value; + } + get importance() { + return this._importance; + } + set importance(value) { + this._importance = value; + } + get intensity() { + return this._intensity; + } + set intensity(value) { + value = Math.max(Math.min(value, 1.0), 0.0); + this._reflectionHDRParams.x = value; + if (this._reflectionDecodeFormat == Laya.TextureDecodeFormat.RGBM) + this._reflectionHDRParams.x *= 5.0; + this._intensity = value; + } + get reflectionTexture() { + return this._reflectionTexture; + } + set reflectionTexture(value) { + this._reflectionTexture = value; + this._reflectionTexture._addReference(); + } + get bounds() { + return this._bounds; + } + set bounds(value) { + this._bounds = value; + } + get boundsMax() { + return this._bounds.getMax(); + } + get boundsMin() { + return this._bounds.getMin(); + } + get probePosition() { + return this.transform.position; + } + get reflectionHDRParams() { + return this._reflectionHDRParams; + } + set reflectionHDRParams(value) { + this._reflectionHDRParams = value; + } + _parse(data, spriteMap) { + super._parse(data, spriteMap); + this._boxProjection = data.boxProjection; + this._importance = data.importance; + this._reflectionTexture = Laya.Loader.getRes(data.reflection); + var position = this.transform.position; + this._size.fromArray(data.boxSize); + Vector3.scale(this._size, 0.5, ReflectionProbe.TEMPVECTOR3); + this._offset.fromArray(data.boxOffset); + var min = new Vector3(); + var max = new Vector3(); + Vector3.add(position, ReflectionProbe.TEMPVECTOR3, max); + Vector3.add(max, this._offset, max); + Vector3.subtract(position, ReflectionProbe.TEMPVECTOR3, min); + Vector3.add(min, this._offset, min); + this._reflectionDecodeFormat = data.reflectionDecodingFormat; + this.intensity = data.intensity; + if (!this._bounds) + this.bounds = new Bounds(min, max); + else { + this._bounds.setMin(min); + this._bounds.setMax(max); + } + } + _setIndexInReflectionList(value) { + this._indexInReflectProbList = value; + } + _getIndexInReflectionList() { + return this._indexInReflectProbList; + } + _onActive() { + super._onActive(); + if (this._reflectionTexture) + this.scene._reflectionProbeManager.add(this); + } + _onInActive() { + super._onInActive(); + if (this.reflectionTexture) + this.scene._reflectionProbeManager.remove(this); + } + destroy(destroyChild = true) { + if (this.destroyed) + return; + super.destroy(destroyChild); + this._reflectionTexture && this._reflectionTexture._removeReference(); + this._reflectionTexture = null; + this._bounds = null; + } + _cloneTo(destObject, srcRoot, dstRoot) { + var dest = destObject; + dest.bounds = this.bounds; + dest.boxProjection = this.boxProjection; + dest.importance = this.importance; + dest._size = this._size; + dest._offset = this._offset; + dest.intensity = this.intensity; + dest.reflectionHDRParams = this.reflectionHDRParams; + super._cloneTo(destObject, srcRoot, dstRoot); + } + } + ReflectionProbe.TEMPVECTOR3 = new Vector3(); + ReflectionProbe.defaultTextureHDRDecodeValues = new Vector4(1.0, 1.0, 0.0, 0.0); + + class BaseRender extends Laya.EventDispatcher { + constructor(owner) { + super(); + this._lightmapScaleOffset = new Vector4(1, 1, 0, 0); + this._indexInList = -1; + this._indexInCastShadowList = -1; + this._boundsChange = true; + this._castShadow = false; + this._supportOctree = true; + this._sharedMaterials = []; + this._renderMark = -1; + this._indexInOctreeMotionList = -1; + this._reflectionMode = exports.ReflectionProbeMode.simple; + this._updateMark = -1; + this._updateRenderType = -1; + this._isPartOfStaticBatch = false; + this._staticBatch = null; + this._id = ++BaseRender._uniqueIDCounter; + this._indexInCastShadowList = -1; + this._bounds = new Bounds(Vector3._ZERO, Vector3._ZERO); + this._renderElements = []; + this._owner = owner; + this._enable = true; + this._materialsInstance = []; + this._shaderValues = new ShaderData(null); + this.lightmapIndex = -1; + this.receiveShadow = false; + this.sortingFudge = 0.0; + (owner) && (this._owner.transform.on(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange)); + } + get id() { + return this._id; + } + get lightmapIndex() { + return this._lightmapIndex; + } + set lightmapIndex(value) { + this._lightmapIndex = value; + } + get lightmapScaleOffset() { + return this._lightmapScaleOffset; + } + set lightmapScaleOffset(value) { + if (!value) + throw "BaseRender: lightmapScaleOffset can't be null."; + this._lightmapScaleOffset = value; + this._shaderValues.setVector(RenderableSprite3D.LIGHTMAPSCALEOFFSET, value); + } + get enable() { + return this._enable; + } + set enable(value) { + this._enable = !!value; + } + get material() { + var material = this._sharedMaterials[0]; + if (material && !this._materialsInstance[0]) { + var insMat = this._getInstanceMaterial(material, 0); + var renderElement = this._renderElements[0]; + (renderElement) && (renderElement.material = insMat); + } + return this._sharedMaterials[0]; + } + set material(value) { + this.sharedMaterial = value; + this._isSupportReflection(); + } + get materials() { + for (var i = 0, n = this._sharedMaterials.length; i < n; i++) { + if (!this._materialsInstance[i]) { + var insMat = this._getInstanceMaterial(this._sharedMaterials[i], i); + var renderElement = this._renderElements[i]; + (renderElement) && (renderElement.material = insMat); + } + } + return this._sharedMaterials.slice(); + } + set materials(value) { + this.sharedMaterials = value; + this._isSupportReflection(); + } + get sharedMaterial() { + return this._sharedMaterials[0]; + } + set sharedMaterial(value) { + var lastValue = this._sharedMaterials[0]; + if (lastValue !== value) { + this._sharedMaterials[0] = value; + this._materialsInstance[0] = false; + this._changeMaterialReference(lastValue, value); + var renderElement = this._renderElements[0]; + (renderElement) && (renderElement.material = value); + } + this._isSupportReflection(); + } + get sharedMaterials() { + return this._sharedMaterials.slice(); + } + set sharedMaterials(value) { + var materialsInstance = this._materialsInstance; + var sharedMats = this._sharedMaterials; + for (var i = 0, n = sharedMats.length; i < n; i++) { + var lastMat = sharedMats[i]; + (lastMat) && (lastMat._removeReference()); + } + if (value) { + var count = value.length; + materialsInstance.length = count; + sharedMats.length = count; + for (i = 0; i < count; i++) { + lastMat = sharedMats[i]; + var mat = value[i]; + if (lastMat !== mat) { + materialsInstance[i] = false; + var renderElement = this._renderElements[i]; + (renderElement) && (renderElement.material = mat); + } + if (mat) { + mat._addReference(); + } + sharedMats[i] = mat; + } + } + else { + throw new Error("BaseRender: shadredMaterials value can't be null."); + } + this._isSupportReflection(); + } + get bounds() { + if (this._boundsChange) { + this._calculateBoundingBox(); + this._boundsChange = false; + } + return this._bounds; + } + set receiveShadow(value) { + if (this._receiveShadow !== value) { + this._receiveShadow = value; + if (value) + this._shaderValues.addDefine(RenderableSprite3D.SHADERDEFINE_RECEIVE_SHADOW); + else + this._shaderValues.removeDefine(RenderableSprite3D.SHADERDEFINE_RECEIVE_SHADOW); + } + } + get receiveShadow() { + return this._receiveShadow; + } + get castShadow() { + return this._castShadow; + } + set castShadow(value) { + this._castShadow = value; + } + get isPartOfStaticBatch() { + return this._isPartOfStaticBatch; + } + get isRender() { + return this._renderMark == -1 || this._renderMark == (Laya.Stat.loopCount - 1); + } + set reflectionMode(value) { + this._reflectionMode = value; + } + get reflectionMode() { + return this._reflectionMode; + } + _getOctreeNode() { + return this._octreeNode; + } + _setOctreeNode(value) { + if (!value) { + (this._indexInOctreeMotionList !== -1) && (this._octreeNode._octree.removeMotionObject(this)); + } + this._octreeNode = value; + } + _getIndexInMotionList() { + return this._indexInOctreeMotionList; + } + _setIndexInMotionList(value) { + this._indexInOctreeMotionList = value; + } + _changeMaterialReference(lastValue, value) { + (lastValue) && (lastValue._removeReference()); + value._addReference(); + } + _getInstanceMaterial(material, index) { + var insMat = material.clone(); + insMat.name = insMat.name + "(Instance)"; + this._materialsInstance[index] = true; + this._changeMaterialReference(this._sharedMaterials[index], insMat); + this._sharedMaterials[index] = insMat; + return insMat; + } + _isSupportReflection() { + this._surportReflectionProbe = false; + var sharedMats = this._sharedMaterials; + for (var i = 0, n = sharedMats.length; i < n; i++) { + var mat = sharedMats[i]; + this._surportReflectionProbe = (this._surportReflectionProbe || (mat && mat._shader._supportReflectionProbe)); + } + } + _addReflectionProbeUpdate() { + if (this._surportReflectionProbe && this._reflectionMode == 1) { + this._scene && this._scene._reflectionProbeManager.addMotionObject(this); + } + } + _applyLightMapParams() { + var lightMaps = this._scene.lightmaps; + var shaderValues = this._shaderValues; + var lightmapIndex = this._lightmapIndex; + if (lightmapIndex >= 0 && lightmapIndex < lightMaps.length) { + var lightMap = lightMaps[lightmapIndex]; + shaderValues.setTexture(RenderableSprite3D.LIGHTMAP, lightMap.lightmapColor); + shaderValues.addDefine(RenderableSprite3D.SAHDERDEFINE_LIGHTMAP); + if (lightMap.lightmapDirection) { + shaderValues.setTexture(RenderableSprite3D.LIGHTMAP_DIRECTION, lightMap.lightmapDirection); + shaderValues.addDefine(RenderableSprite3D.SHADERDEFINE_LIGHTMAP_DIRECTIONAL); + } + else { + shaderValues.removeDefine(RenderableSprite3D.SHADERDEFINE_LIGHTMAP_DIRECTIONAL); + } + } + else { + shaderValues.removeDefine(RenderableSprite3D.SAHDERDEFINE_LIGHTMAP); + shaderValues.removeDefine(RenderableSprite3D.SHADERDEFINE_LIGHTMAP_DIRECTIONAL); + } + } + _onWorldMatNeedChange(flag) { + this._boundsChange = true; + if (this._octreeNode) { + flag &= Transform3D.TRANSFORM_WORLDPOSITION | Transform3D.TRANSFORM_WORLDQUATERNION | Transform3D.TRANSFORM_WORLDSCALE; + if (flag) { + if (this._indexInOctreeMotionList === -1) + this._octreeNode._octree.addMotionObject(this); + } + } + this._addReflectionProbeUpdate(); + } + _calculateBoundingBox() { + throw ("BaseRender: must override it."); + } + _getIndexInList() { + return this._indexInList; + } + _setIndexInList(index) { + this._indexInList = index; + } + _setBelongScene(scene) { + this._scene = scene; + } + _setUnBelongScene() { + this._scene = null; + } + _needRender(boundFrustum, context) { + return true; + } + _OctreeNoRender() { + } + _renderUpdate(context, transform) { + } + _renderUpdateWithCamera(context, transform) { + } + _revertBatchRenderUpdate(context) { + } + _destroy() { + (this._indexInOctreeMotionList !== -1) && (this._octreeNode._octree.removeMotionObject(this)); + this.offAll(); + var i = 0, n = 0; + for (i = 0, n = this._renderElements.length; i < n; i++) + this._renderElements[i].destroy(); + for (i = 0, n = this._sharedMaterials.length; i < n; i++) + (this._sharedMaterials[i].destroyed) || (this._sharedMaterials[i]._removeReference()); + this._renderElements = null; + this._owner = null; + this._sharedMaterials = null; + this._bounds = null; + this._lightmapScaleOffset = null; + this._scene = null; + } + markAsUnStatic() { + if (this._isPartOfStaticBatch) { + MeshRenderStaticBatchManager.instance._removeRenderSprite(this._owner); + this._isPartOfStaticBatch = false; + } + } + } + BaseRender._tempBoundBoxCorners = [new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3(), new Vector3()]; + BaseRender._uniqueIDCounter = 0; + BaseRender._defaultLightmapScaleOffset = new Vector4(1.0, 1.0, 0.0, 0.0); + + class PixelLineRenderer extends BaseRender { + constructor(owner) { + super(owner); + this._projectionViewWorldMatrix = new Matrix4x4(); + } + _calculateBoundingBox() { + var worldMat = this._owner.transform.worldMatrix; + var lineFilter = this._owner._geometryFilter; + lineFilter._reCalculateBound(); + lineFilter._bounds._tranform(worldMat, this._bounds); + } + _renderUpdateWithCamera(context, transform) { + var projectionView = context.projectionViewMatrix; + var sv = this._shaderValues; + if (transform) { + var worldMat = transform.worldMatrix; + sv.setMatrix4x4(Sprite3D.WORLDMATRIX, worldMat); + Matrix4x4.multiply(projectionView, worldMat, this._projectionViewWorldMatrix); + sv.setMatrix4x4(Sprite3D.MVPMATRIX, this._projectionViewWorldMatrix); + } + else { + sv.setMatrix4x4(Sprite3D.WORLDMATRIX, Matrix4x4.DEFAULT); + sv.setMatrix4x4(Sprite3D.MVPMATRIX, projectionView); + } + } + } + + class PixelLineSprite3D extends RenderableSprite3D { + constructor(maxCount = 2, name = null) { + super(name); + this._isRenderActive = false; + this._isInRenders = false; + this._geometryFilter = new PixelLineFilter(this, maxCount); + this._render = new PixelLineRenderer(this); + this._changeRenderObjects(0, PixelLineMaterial.defaultMaterial); + } + get maxLineCount() { + return this._geometryFilter._maxLineCount; + } + set maxLineCount(value) { + this._geometryFilter._resizeLineData(value); + this._geometryFilter._lineCount = Math.min(this._geometryFilter._lineCount, value); + } + get lineCount() { + return this._geometryFilter._lineCount; + } + set lineCount(value) { + if (value > this.maxLineCount) + throw "PixelLineSprite3D: lineCount can't large than maxLineCount"; + else + this._geometryFilter._lineCount = value; + } + get pixelLineRenderer() { + return this._render; + } + _onInActive() { + Laya.Stat.spriteCount--; + if (this._geometryFilter._lineCount != 0 && this._isRenderActive) { + this._scene._removeRenderObject(this._render); + this._isInRenders = false; + } + this._isRenderActive = false; + } + _onActive() { + Laya.Stat.spriteCount++; + this._isRenderActive = true; + if (this._geometryFilter._lineCount != 0) { + this._scene._addRenderObject(this._render); + this._isInRenders = true; + } + } + _changeRenderObjects(index, material) { + var renderObjects = this._render._renderElements; + (material) || (material = PixelLineMaterial.defaultMaterial); + var renderElement = renderObjects[index]; + (renderElement) || (renderElement = renderObjects[index] = new RenderElement()); + renderElement.setTransform(this._transform); + renderElement.setGeometry(this._geometryFilter); + renderElement.render = this._render; + renderElement.material = material; + } + addLine(startPosition, endPosition, startColor, endColor) { + if (this._geometryFilter._lineCount !== this._geometryFilter._maxLineCount) + this._geometryFilter._updateLineData(this._geometryFilter._lineCount++, startPosition, endPosition, startColor, endColor); + else + throw "PixelLineSprite3D: lineCount has equal with maxLineCount."; + if (this._isRenderActive && !this._isInRenders && this._geometryFilter._lineCount > 0) { + this._scene._addRenderObject(this._render); + this._isInRenders = true; + } + } + addLines(lines) { + var lineCount = this._geometryFilter._lineCount; + var addCount = lines.length; + if (lineCount + addCount > this._geometryFilter._maxLineCount) { + throw "PixelLineSprite3D: lineCount plus lines count must less than maxLineCount."; + } + else { + this._geometryFilter._updateLineDatas(lineCount, lines); + this._geometryFilter._lineCount += addCount; + } + if (this._isRenderActive && !this._isInRenders && this._geometryFilter._lineCount > 0) { + this._scene._addRenderObject(this._render); + this._isInRenders = true; + } + } + removeLine(index) { + if (index < this._geometryFilter._lineCount) + this._geometryFilter._removeLineData(index); + else + throw "PixelLineSprite3D: index must less than lineCount."; + if (this._isRenderActive && this._isInRenders && this._geometryFilter._lineCount == 0) { + this._scene._removeRenderObject(this._render); + this._isInRenders = false; + } + } + setLine(index, startPosition, endPosition, startColor, endColor) { + if (index < this._geometryFilter._lineCount) + this._geometryFilter._updateLineData(index, startPosition, endPosition, startColor, endColor); + else + throw "PixelLineSprite3D: index must less than lineCount."; + } + getLine(index, out) { + if (index < this.lineCount) + this._geometryFilter._getLineData(index, out); + else + throw "PixelLineSprite3D: index must less than lineCount."; + } + clear() { + this._geometryFilter._lineCount = 0; + if (this._isRenderActive && this._isInRenders) { + this._scene._removeRenderObject(this._render); + this._isInRenders = false; + } + } + _create() { + return new PixelLineSprite3D(); + } + } + + class RenderQueue { + constructor(isTransparent = false) { + this.isTransparent = false; + this.elements = new SingletonList(); + this.lastTransparentRenderElement = null; + this.lastTransparentBatched = false; + this.isTransparent = isTransparent; + } + _compare(left, right) { + var renderQueue = left.material.renderQueue - right.material.renderQueue; + if (renderQueue === 0) { + var sort = this.isTransparent ? right.render._distanceForSort - left.render._distanceForSort : left.render._distanceForSort - right.render._distanceForSort; + return sort + right.render.sortingFudge - left.render.sortingFudge; + } + else { + return renderQueue; + } + } + _partitionRenderObject(left, right) { + var elements = this.elements.elements; + var pivot = elements[Math.floor((right + left) / 2)]; + while (left <= right) { + while (this._compare(elements[left], pivot) < 0) + left++; + while (this._compare(elements[right], pivot) > 0) + right--; + if (left < right) { + var temp = elements[left]; + elements[left] = elements[right]; + elements[right] = temp; + left++; + right--; + } + else if (left === right) { + left++; + break; + } + } + return left; + } + _quickSort(left, right) { + if (this.elements.length > 1) { + var index = this._partitionRenderObject(left, right); + var leftIndex = index - 1; + if (left < leftIndex) + this._quickSort(left, leftIndex); + if (index < right) + this._quickSort(index, right); + } + } + _render(context) { + var elements = this.elements.elements; + for (var i = 0, n = this.elements.length; i < n; i++) + elements[i]._render(context); + } + clear() { + this.elements.length = 0; + this.lastTransparentRenderElement = null; + this.lastTransparentBatched = false; + } + } + + class BoundsOctreeNode { + constructor(octree, parent, baseLength, center) { + this._bounds = new BoundBox(new Vector3(), new Vector3()); + this._objects = []; + this._isContaion = false; + this.center = new Vector3(); + this.baseLength = 0.0; + this._setValues(octree, parent, baseLength, center); + } + static _encapsulates(outerBound, innerBound) { + return CollisionUtils.boxContainsBox(outerBound, innerBound) == ContainmentType.Contains; + } + _setValues(octree, parent, baseLength, center) { + this._octree = octree; + this._parent = parent; + this.baseLength = baseLength; + center.cloneTo(this.center); + var min = this._bounds.min; + var max = this._bounds.max; + var halfSize = (octree._looseness * baseLength) / 2; + min.setValue(center.x - halfSize, center.y - halfSize, center.z - halfSize); + max.setValue(center.x + halfSize, center.y + halfSize, center.z + halfSize); + } + _getChildBound(index) { + if (this._children != null && this._children[index]) { + return this._children[index]._bounds; + } + else { + var quarter = this.baseLength / 4; + var halfChildSize = ((this.baseLength / 2) * this._octree._looseness) / 2; + var bounds = BoundsOctreeNode._tempBoundBox; + var min = bounds.min; + var max = bounds.max; + switch (index) { + case 0: + min.x = this.center.x - quarter - halfChildSize; + min.y = this.center.y + quarter - halfChildSize; + min.z = this.center.z - quarter - halfChildSize; + max.x = this.center.x - quarter + halfChildSize; + max.y = this.center.y + quarter + halfChildSize; + max.z = this.center.z - quarter + halfChildSize; + break; + case 1: + min.x = this.center.x + quarter - halfChildSize; + min.y = this.center.y + quarter - halfChildSize; + min.z = this.center.z - quarter - halfChildSize; + max.x = this.center.x + quarter + halfChildSize; + max.y = this.center.y + quarter + halfChildSize; + max.z = this.center.z - quarter + halfChildSize; + break; + case 2: + min.x = this.center.x - quarter - halfChildSize; + min.y = this.center.y + quarter - halfChildSize; + min.z = this.center.z + quarter - halfChildSize; + max.x = this.center.x - quarter + halfChildSize; + max.y = this.center.y + quarter + halfChildSize; + max.z = this.center.z + quarter + halfChildSize; + break; + case 3: + min.x = this.center.x + quarter - halfChildSize; + min.y = this.center.y + quarter - halfChildSize; + min.z = this.center.z + quarter - halfChildSize; + max.x = this.center.x + quarter + halfChildSize; + max.y = this.center.y + quarter + halfChildSize; + max.z = this.center.z + quarter + halfChildSize; + break; + case 4: + min.x = this.center.x - quarter - halfChildSize; + min.y = this.center.y - quarter - halfChildSize; + min.z = this.center.z - quarter - halfChildSize; + max.x = this.center.x - quarter + halfChildSize; + max.y = this.center.y - quarter + halfChildSize; + max.z = this.center.z - quarter + halfChildSize; + break; + case 5: + min.x = this.center.x + quarter - halfChildSize; + min.y = this.center.y - quarter - halfChildSize; + min.z = this.center.z - quarter - halfChildSize; + max.x = this.center.x + quarter + halfChildSize; + max.y = this.center.y - quarter + halfChildSize; + max.z = this.center.z - quarter + halfChildSize; + break; + case 6: + min.x = this.center.x - quarter - halfChildSize; + min.y = this.center.y - quarter - halfChildSize; + min.z = this.center.z + quarter - halfChildSize; + max.x = this.center.x - quarter + halfChildSize; + max.y = this.center.y - quarter + halfChildSize; + max.z = this.center.z + quarter + halfChildSize; + break; + case 7: + min.x = this.center.x + quarter - halfChildSize; + min.y = this.center.y - quarter - halfChildSize; + min.z = this.center.z + quarter - halfChildSize; + max.x = this.center.x + quarter + halfChildSize; + max.y = this.center.y - quarter + halfChildSize; + max.z = this.center.z + quarter + halfChildSize; + break; + } + return bounds; + } + } + _getChildCenter(index) { + if (this._children != null) { + return this._children[index].center; + } + else { + var quarter = this.baseLength / 4; + var childCenter = BoundsOctreeNode._tempVector30; + switch (index) { + case 0: + childCenter.x = this.center.x - quarter; + childCenter.y = this.center.y + quarter; + childCenter.z = this.center.z - quarter; + break; + case 1: + childCenter.x = this.center.x + quarter; + childCenter.y = this.center.y + quarter; + childCenter.z = this.center.z - quarter; + break; + case 2: + childCenter.x = this.center.x - quarter; + childCenter.y = this.center.y + quarter; + childCenter.z = this.center.z + quarter; + break; + case 3: + childCenter.x = this.center.x + quarter; + childCenter.y = this.center.y + quarter; + childCenter.z = this.center.z + quarter; + break; + case 4: + childCenter.x = this.center.x - quarter; + childCenter.y = this.center.y - quarter; + childCenter.z = this.center.z - quarter; + break; + case 5: + childCenter.x = this.center.x + quarter; + childCenter.y = this.center.y - quarter; + childCenter.z = this.center.z - quarter; + break; + case 6: + childCenter.x = this.center.x - quarter; + childCenter.y = this.center.y - quarter; + childCenter.z = this.center.z + quarter; + break; + case 7: + childCenter.x = this.center.x + quarter; + childCenter.y = this.center.y - quarter; + childCenter.z = this.center.z + quarter; + break; + } + return childCenter; + } + } + _getChild(index) { + var quarter = this.baseLength / 4; + this._children || (this._children = []); + switch (index) { + case 0: + return this._children[0] || (this._children[0] = new BoundsOctreeNode(this._octree, this, this.baseLength / 2, new Vector3(this.center.x + -quarter, this.center.y + quarter, this.center.z - quarter))); + case 1: + return this._children[1] || (this._children[1] = new BoundsOctreeNode(this._octree, this, this.baseLength / 2, new Vector3(this.center.x + quarter, this.center.y + quarter, this.center.z - quarter))); + case 2: + return this._children[2] || (this._children[2] = new BoundsOctreeNode(this._octree, this, this.baseLength / 2, new Vector3(this.center.x - quarter, this.center.y + quarter, this.center.z + quarter))); + case 3: + return this._children[3] || (this._children[3] = new BoundsOctreeNode(this._octree, this, this.baseLength / 2, new Vector3(this.center.x + quarter, this.center.y + quarter, this.center.z + quarter))); + case 4: + return this._children[4] || (this._children[4] = new BoundsOctreeNode(this._octree, this, this.baseLength / 2, new Vector3(this.center.x - quarter, this.center.y - quarter, this.center.z - quarter))); + case 5: + return this._children[5] || (this._children[5] = new BoundsOctreeNode(this._octree, this, this.baseLength / 2, new Vector3(this.center.x + quarter, this.center.y - quarter, this.center.z - quarter))); + case 6: + return this._children[6] || (this._children[6] = new BoundsOctreeNode(this._octree, this, this.baseLength / 2, new Vector3(this.center.x - quarter, this.center.y - quarter, this.center.z + quarter))); + case 7: + return this._children[7] || (this._children[7] = new BoundsOctreeNode(this._octree, this, this.baseLength / 2, new Vector3(this.center.x + quarter, this.center.y - quarter, this.center.z + quarter))); + default: + throw "BoundsOctreeNode: unknown index."; + } + } + _shouldMerge() { + var objectCount = this._objects.length; + for (var i = 0; i < 8; i++) { + var child = this._children[i]; + if (child) { + if (child._children != null) + return false; + objectCount += child._objects.length; + } + } + return objectCount <= BoundsOctreeNode._NUM_OBJECTS_ALLOWED; + } + _mergeChildren() { + for (var i = 0; i < 8; i++) { + var child = this._children[i]; + if (child) { + child._parent = null; + var childObjects = child._objects; + for (var j = childObjects.length - 1; j >= 0; j--) { + var childObject = childObjects[j]; + this._objects.push(childObject); + childObject._setOctreeNode(this); + } + } + } + this._children = null; + } + _merge() { + if (this._children === null) { + var parent = this._parent; + if (parent && parent._shouldMerge()) { + parent._mergeChildren(); + parent._merge(); + } + } + } + _checkAddNode(object) { + if (this._children == null) { + if (this._objects.length < BoundsOctreeNode._NUM_OBJECTS_ALLOWED || (this.baseLength / 2) < this._octree._minSize) { + return this; + } + for (var i = this._objects.length - 1; i >= 0; i--) { + var existObject = this._objects[i]; + var fitChildIndex = this._bestFitChild(existObject.bounds.getCenter()); + if (BoundsOctreeNode._encapsulates(this._getChildBound(fitChildIndex), existObject.bounds._getBoundBox())) { + this._objects.splice(this._objects.indexOf(existObject), 1); + this._getChild(fitChildIndex)._add(existObject); + } + } + } + var newFitChildIndex = this._bestFitChild(object.bounds.getCenter()); + if (BoundsOctreeNode._encapsulates(this._getChildBound(newFitChildIndex), object.bounds._getBoundBox())) + return this._getChild(newFitChildIndex)._checkAddNode(object); + else + return this; + } + _add(object) { + var addNode = this._checkAddNode(object); + addNode._objects.push(object); + object._setOctreeNode(addNode); + } + _remove(object) { + var index = this._objects.indexOf(object); + this._objects.splice(index, 1); + object._setOctreeNode(null); + this._merge(); + } + _addUp(object) { + if ((CollisionUtils.boxContainsBox(this._bounds, object.bounds._getBoundBox()) === ContainmentType.Contains)) { + this._add(object); + return true; + } + else { + if (this._parent) + return this._parent._addUp(object); + else + return false; + } + } + _getCollidingWithFrustum(cameraCullInfo, context, testVisible, customShader, replacementTag, isShadowCasterCull) { + var frustum = cameraCullInfo.boundFrustum; + var camPos = cameraCullInfo.position; + var cullMask = cameraCullInfo.cullingMask; + if (testVisible) { + var type = frustum.containsBoundBox(this._bounds); + Laya.Stat.octreeNodeCulling++; + if (type === ContainmentType.Disjoint) { + for (var i = 0, n = this._objects.length; i < n; i++) { + this._objects[i]._OctreeNoRender(); + } + return; + } + testVisible = (type === ContainmentType.Intersects); + } + this._isContaion = !testVisible; + var scene = context.scene; + var loopCount = Laya.Stat.loopCount; + for (var i = 0, n = this._objects.length; i < n; i++) { + var render = this._objects[i]; + var canPass; + if (isShadowCasterCull) + canPass = render._castShadow && render._enable; + else + canPass = (((Math.pow(2, render._owner._layer) & cullMask) != 0)) && render._enable; + if (canPass) { + if (testVisible) { + Laya.Stat.frustumCulling++; + if (!render._needRender(frustum, context)) + continue; + } + render._renderMark = loopCount; + render._distanceForSort = Vector3.distance(render.bounds.getCenter(), camPos); + var elements = render._renderElements; + for (var j = 0, m = elements.length; j < m; j++) { + var element = elements[j]; + element._update(scene, context, customShader, replacementTag); + } + } + } + if (this._children != null) { + for (i = 0; i < 8; i++) { + var child = this._children[i]; + child && child._getCollidingWithFrustum(cameraCullInfo, context, testVisible, customShader, replacementTag, isShadowCasterCull); + } + } + } + _getCollidingWithCastShadowFrustum(cullInfo, context) { + var cullPlaneCount = cullInfo.cullPlaneCount; + var cullPlanes = cullInfo.cullPlanes; + var min = this._bounds.min; + var max = this._bounds.max; + var minX = min.x; + var minY = min.y; + var minZ = min.z; + var maxX = max.x; + var maxY = max.y; + var maxZ = max.z; + var pass = true; + for (var j = 0; j < cullPlaneCount; j++) { + var plane = cullPlanes[j]; + var normal = plane.normal; + if (plane.distance + (normal.x * (normal.x < 0.0 ? minX : maxX)) + (normal.y * (normal.y < 0.0 ? minY : maxY)) + (normal.z * (normal.z < 0.0 ? minZ : maxZ)) < 0.0) { + pass = false; + break; + } + } + if (!pass) + return; + var scene = context.scene; + var loopCount = Laya.Stat.loopCount; + for (var i = 0, n = this._objects.length; i < n; i++) { + var render = this._objects[i]; + var canPass; + let pass = true; + canPass = render._castShadow && render._enable; + if (canPass) { + for (var j = 0; j < cullPlaneCount; j++) { + var plane = cullPlanes[j]; + var normal = plane.normal; + if (plane.distance + (normal.x * (normal.x < 0.0 ? minX : maxX)) + (normal.y * (normal.y < 0.0 ? minY : maxY)) + (normal.z * (normal.z < 0.0 ? minZ : maxZ)) < 0.0) { + pass = false; + break; + } + } + } + if (!pass || !canPass) + continue; + render._renderMark = loopCount; + render._distanceForSort = Vector3.distance(render.bounds.getCenter(), cullInfo.position); + var elements = render._renderElements; + for (var j = 0, m = elements.length; j < m; j++) { + var element = elements[j]; + element._update(scene, context, null, null); + } + } + if (this._children != null) { + for (i = 0; i < 8; i++) { + var child = this._children[i]; + child && child._getCollidingWithCastShadowFrustum(cullInfo, context); + } + } + } + _getCollidingWithBoundBox(checkBound, testVisible, result) { + if (testVisible) { + var type = CollisionUtils.boxContainsBox(this._bounds, checkBound); + if (type === ContainmentType.Disjoint) + return; + testVisible = (type === ContainmentType.Intersects); + } + if (testVisible) { + for (var i = 0, n = this._objects.length; i < n; i++) { + var object = this._objects[i]; + if (CollisionUtils.intersectsBoxAndBox(object.bounds._getBoundBox(), checkBound)) { + result.push(object); + } + } + } + if (this._children != null) { + for (i = 0; i < 8; i++) { + var child = this._children[i]; + child._getCollidingWithBoundBox(checkBound, testVisible, result); + } + } + } + _bestFitChild(boundCenter) { + return (boundCenter.x <= this.center.x ? 0 : 1) + (boundCenter.y >= this.center.y ? 0 : 4) + (boundCenter.z <= this.center.z ? 0 : 2); + } + _update(object) { + if (CollisionUtils.boxContainsBox(this._bounds, object.bounds._getBoundBox()) === ContainmentType.Contains) { + var addNode = this._checkAddNode(object); + if (addNode !== object._getOctreeNode()) { + addNode._objects.push(object); + object._setOctreeNode(addNode); + var index = this._objects.indexOf(object); + this._objects.splice(index, 1); + this._merge(); + } + return true; + } + else { + if (this._parent) { + var sucess = this._parent._addUp(object); + if (sucess) { + index = this._objects.indexOf(object); + this._objects.splice(index, 1); + this._merge(); + } + return sucess; + } + else { + return false; + } + } + } + add(object) { + if (!BoundsOctreeNode._encapsulates(this._bounds, object.bounds._getBoundBox())) + return false; + this._add(object); + return true; + } + remove(object) { + if (object._getOctreeNode() !== this) + return false; + this._remove(object); + return true; + } + update(object) { + if (object._getOctreeNode() !== this) + return false; + return this._update(object); + } + shrinkIfPossible(minLength) { + if (this.baseLength < minLength * 2) + return this; + var bestFit = -1; + for (var i = 0, n = this._objects.length; i < n; i++) { + var object = this._objects[i]; + var newBestFit = this._bestFitChild(object.bounds.getCenter()); + if (i == 0 || newBestFit == bestFit) { + var childBounds = this._getChildBound(newBestFit); + if (BoundsOctreeNode._encapsulates(childBounds, object.bounds._getBoundBox())) + (i == 0) && (bestFit = newBestFit); + else + return this; + } + else { + return this; + } + } + if (this._children != null) { + var childHadContent = false; + for (i = 0, n = this._children.length; i < n; i++) { + var child = this._children[i]; + if (child && child.hasAnyObjects()) { + if (childHadContent) + return this; + if (bestFit >= 0 && bestFit != i) + return this; + childHadContent = true; + bestFit = i; + } + } + } + else { + if (bestFit != -1) { + var childCenter = this._getChildCenter(bestFit); + this._setValues(this._octree, null, this.baseLength / 2, childCenter); + } + return this; + } + if (bestFit != -1) { + var newRoot = this._children[bestFit]; + newRoot._parent = null; + return newRoot; + } + else { + return this; + } + } + hasAnyObjects() { + if (this._objects.length > 0) + return true; + if (this._children != null) { + for (var i = 0; i < 8; i++) { + var child = this._children[i]; + if (child && child.hasAnyObjects()) + return true; + } + } + return false; + } + getCollidingWithBoundBox(checkBound, result) { + this._getCollidingWithBoundBox(checkBound, true, result); + } + getCollidingWithRay(ray, result, maxDistance = Number.MAX_VALUE) { + var distance = CollisionUtils.intersectsRayAndBoxRD(ray, this._bounds); + if (distance == -1 || distance > maxDistance) + return; + for (var i = 0, n = this._objects.length; i < n; i++) { + var object = this._objects[i]; + distance = CollisionUtils.intersectsRayAndBoxRD(ray, object.bounds._getBoundBox()); + if (distance !== -1 && distance <= maxDistance) + result.push(object); + } + if (this._children != null) { + for (i = 0; i < 8; i++) { + var child = this._children[i]; + child.getCollidingWithRay(ray, result, maxDistance); + } + } + } + getCollidingWithFrustum(cameraCullInfo, context, customShader, replacementTag, isShadowCasterCull) { + this._getCollidingWithFrustum(cameraCullInfo, context, true, customShader, replacementTag, isShadowCasterCull); + } + getCollidingWithCastShadowFrustum(cameraCullInfo, contect) { + this._getCollidingWithCastShadowFrustum(cameraCullInfo, contect); + } + isCollidingWithBoundBox(checkBound) { + if (!(CollisionUtils.intersectsBoxAndBox(this._bounds, checkBound))) + return false; + for (var i = 0, n = this._objects.length; i < n; i++) { + var object = this._objects[i]; + if (CollisionUtils.intersectsBoxAndBox(object.bounds._getBoundBox(), checkBound)) + return true; + } + if (this._children != null) { + for (i = 0; i < 8; i++) { + var child = this._children[i]; + if (child.isCollidingWithBoundBox(checkBound)) + return true; + } + } + return false; + } + isCollidingWithRay(ray, maxDistance = Number.MAX_VALUE) { + var distance = CollisionUtils.intersectsRayAndBoxRD(ray, this._bounds); + if (distance == -1 || distance > maxDistance) + return false; + for (var i = 0, n = this._objects.length; i < n; i++) { + var object = this._objects[i]; + distance = CollisionUtils.intersectsRayAndBoxRD(ray, object.bounds._getBoundBox()); + if (distance !== -1 && distance <= maxDistance) + return true; + } + if (this._children != null) { + for (i = 0; i < 8; i++) { + var child = this._children[i]; + if (child.isCollidingWithRay(ray, maxDistance)) + return true; + } + } + return false; + } + getBound() { + return this._bounds; + } + drawAllBounds(debugLine, currentDepth, maxDepth) { + if (this._children === null && this._objects.length == 0) + return; + currentDepth++; + var color = BoundsOctreeNode._tempColor0; + if (this._isContaion) { + color.r = 0.0; + color.g = 0.0; + color.b = 1.0; + } + else { + var tint = maxDepth ? currentDepth / maxDepth : 0; + color.r = 1.0 - tint; + color.g = tint; + color.b = 0.0; + } + color.a = 0.3; + Utils3D._drawBound(debugLine, this._bounds, color); + if (this._children != null) { + for (var i = 0; i < 8; i++) { + var child = this._children[i]; + child && child.drawAllBounds(debugLine, currentDepth, maxDepth); + } + } + } + drawAllObjects(debugLine, currentDepth, maxDepth) { + currentDepth++; + var color = BoundsOctreeNode._tempColor0; + if (this._isContaion) { + color.r = 0.0; + color.g = 0.0; + color.b = 1.0; + } + else { + var tint = maxDepth ? currentDepth / maxDepth : 0; + color.r = 1.0 - tint; + color.g = tint; + color.b = 0.0; + } + color.a = 1.0; + for (var i = 0, n = this._objects.length; i < n; i++) + Utils3D._drawBound(debugLine, this._objects[i].bounds._getBoundBox(), color); + if (this._children != null) { + for (i = 0; i < 8; i++) { + var child = this._children[i]; + child && child.drawAllObjects(debugLine, currentDepth, maxDepth); + } + } + } + } + BoundsOctreeNode._tempVector30 = new Vector3(); + BoundsOctreeNode._tempColor0 = new Color(); + BoundsOctreeNode._tempBoundBox = new BoundBox(new Vector3(), new Vector3()); + BoundsOctreeNode._NUM_OBJECTS_ALLOWED = 8; + + class OctreeMotionList extends SingletonList { + constructor() { + super(); + } + add(element) { + var index = element._getIndexInMotionList(); + if (index !== -1) + throw "OctreeMotionList:element has in PhysicsUpdateList."; + this._add(element); + element._setIndexInMotionList(this.length++); + } + remove(element) { + var index = element._getIndexInMotionList(); + this.length--; + if (index !== this.length) { + var end = this.elements[this.length]; + this.elements[index] = end; + end._setIndexInMotionList(index); + } + element._setIndexInMotionList(-1); + } + } + + class BoundsOctree { + constructor(initialWorldSize, initialWorldPos, minNodeSize, looseness) { + this._motionObjects = new OctreeMotionList(); + this.count = 0; + if (minNodeSize > initialWorldSize) { + console.warn("Minimum node size must be at least as big as the initial world size. Was: " + minNodeSize + " Adjusted to: " + initialWorldSize); + minNodeSize = initialWorldSize; + } + this._initialSize = initialWorldSize; + this._minSize = minNodeSize; + this._looseness = Math.min(Math.max(looseness, 1.0), 2.0); + this._rootNode = new BoundsOctreeNode(this, null, initialWorldSize, initialWorldPos); + } + _getMaxDepth(node, depth) { + depth++; + var children = node._children; + if (children != null) { + var curDepth = depth; + for (var i = 0, n = children.length; i < n; i++) { + var child = children[i]; + child && (depth = Math.max(this._getMaxDepth(child, curDepth), depth)); + } + } + return depth; + } + _grow(growObjectCenter) { + var xDirection = growObjectCenter.x >= 0 ? 1 : -1; + var yDirection = growObjectCenter.y >= 0 ? 1 : -1; + var zDirection = growObjectCenter.z >= 0 ? 1 : -1; + var oldRoot = this._rootNode; + var half = this._rootNode.baseLength / 2; + var newLength = this._rootNode.baseLength * 2; + var rootCenter = this._rootNode.center; + var newCenter = new Vector3(rootCenter.x + xDirection * half, rootCenter.y + yDirection * half, rootCenter.z + zDirection * half); + this._rootNode = new BoundsOctreeNode(this, null, newLength, newCenter); + if (oldRoot.hasAnyObjects()) { + var rootPos = this._rootNode._bestFitChild(oldRoot.center); + var children = []; + for (var i = 0; i < 8; i++) { + if (i == rootPos) { + oldRoot._parent = this._rootNode; + children[i] = oldRoot; + } + } + this._rootNode._children = children; + } + } + add(object) { + var count = 0; + while (!this._rootNode.add(object)) { + var growCenter = BoundsOctree._tempVector30; + Vector3.subtract(object.bounds.getCenter(), this._rootNode.center, growCenter); + this._grow(growCenter); + if (++count > 20) { + throw "Aborted Add operation as it seemed to be going on forever (" + (count - 1) + ") attempts at growing the octree."; + } + } + this.count++; + } + remove(object) { + var removed = object._getOctreeNode().remove(object); + if (removed) { + this.count--; + } + return removed; + } + update(object) { + var count = 0; + var octreeNode = object._getOctreeNode(); + if (octreeNode) { + while (!octreeNode._update(object)) { + var growCenter = BoundsOctree._tempVector30; + Vector3.subtract(object.bounds.getCenter(), this._rootNode.center, growCenter); + this._grow(growCenter); + if (++count > 20) { + throw "Aborted Add operation as it seemed to be going on forever (" + (count - 1) + ") attempts at growing the octree."; + } + } + return true; + } + else { + return false; + } + } + shrinkRootIfPossible() { + this._rootNode = this._rootNode.shrinkIfPossible(this._initialSize); + } + addMotionObject(object) { + this._motionObjects.add(object); + } + removeMotionObject(object) { + this._motionObjects.remove(object); + } + updateMotionObjects() { + var elements = this._motionObjects.elements; + for (var i = 0, n = this._motionObjects.length; i < n; i++) { + var object = elements[i]; + this.update(object); + object._setIndexInMotionList(-1); + } + this._motionObjects.length = 0; + } + isCollidingWithBoundBox(checkBounds) { + return this._rootNode.isCollidingWithBoundBox(checkBounds); + } + isCollidingWithRay(ray, maxDistance = Number.MAX_VALUE) { + return this._rootNode.isCollidingWithRay(ray, maxDistance); + } + getCollidingWithBoundBox(checkBound, result) { + this._rootNode.getCollidingWithBoundBox(checkBound, result); + } + getCollidingWithRay(ray, result, maxDistance = Number.MAX_VALUE) { + this._rootNode.getCollidingWithRay(ray, result, maxDistance); + } + getCollidingWithFrustum(cameraCullInfo, context, shader, replacementTag, isShadowCasterCull) { + this._rootNode.getCollidingWithFrustum(cameraCullInfo, context, shader, replacementTag, isShadowCasterCull); + } + getMaxBounds() { + return this._rootNode.getBound(); + } + drawAllBounds(pixelLine) { + var maxDepth = this._getMaxDepth(this._rootNode, -1); + this._rootNode.drawAllBounds(pixelLine, -1, maxDepth); + } + drawAllObjects(pixelLine) { + var maxDepth = this._getMaxDepth(this._rootNode, -1); + this._rootNode.drawAllObjects(pixelLine, -1, maxDepth); + } + } + BoundsOctree._tempVector30 = new Vector3(); + + class Lightmap { + } + + class BoundSphere { + constructor(center, radius) { + this.center = center; + this.radius = radius; + } + toDefault() { + this.center.toDefault(); + this.radius = 0; + } + static createFromSubPoints(points, start, count, out) { + if (points == null) { + throw new Error("points"); + } + if (start < 0 || start >= points.length) { + throw new Error("start" + start + "Must be in the range [0, " + (points.length - 1) + "]"); + } + if (count < 0 || (start + count) > points.length) { + throw new Error("count" + count + "Must be in the range <= " + points.length + "}"); + } + var upperEnd = start + count; + var center = BoundSphere._tempVector3; + center.x = 0; + center.y = 0; + center.z = 0; + for (var i = start; i < upperEnd; ++i) { + Vector3.add(points[i], center, center); + } + var outCenter = out.center; + Vector3.scale(center, 1 / count, outCenter); + var radius = 0.0; + for (i = start; i < upperEnd; ++i) { + var distance = Vector3.distanceSquared(outCenter, points[i]); + if (distance > radius) + radius = distance; + } + out.radius = Math.sqrt(radius); + } + static createfromPoints(points, out) { + if (points == null) { + throw new Error("points"); + } + BoundSphere.createFromSubPoints(points, 0, points.length, out); + } + intersectsRayDistance(ray) { + return CollisionUtils.intersectsRayAndSphereRD(ray, this); + } + intersectsRayPoint(ray, outPoint) { + return CollisionUtils.intersectsRayAndSphereRP(ray, this, outPoint); + } + cloneTo(destObject) { + var dest = destObject; + this.center.cloneTo(dest.center); + dest.radius = this.radius; + } + clone() { + var dest = new BoundSphere(new Vector3(), 0); + this.cloneTo(dest); + return dest; + } + } + BoundSphere._tempVector3 = new Vector3(); + + class ShadowSliceData { + constructor() { + this.cameraShaderValue = new ShaderData(); + this.position = new Vector3(); + this.viewMatrix = new Matrix4x4(); + this.projectionMatrix = new Matrix4x4(); + this.viewProjectMatrix = new Matrix4x4(); + this.cullPlanes = [new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3())]; + this.splitBoundSphere = new BoundSphere(new Vector3(), 0.0); + } + } + class ShadowSpotData { + constructor() { + this.cameraShaderValue = new ShaderData(); + this.position = new Vector3; + this.viewMatrix = new Matrix4x4(); + this.projectionMatrix = new Matrix4x4(); + this.viewProjectMatrix = new Matrix4x4(); + this.cameraCullInfo = new CameraCullInfo(); + } + } + + (function (ShadowLightType) { + ShadowLightType[ShadowLightType["DirectionLight"] = 0] = "DirectionLight"; + ShadowLightType[ShadowLightType["SpotLight"] = 1] = "SpotLight"; + ShadowLightType[ShadowLightType["PointLight"] = 2] = "PointLight"; + })(exports.ShadowLightType || (exports.ShadowLightType = {})); + class ShadowCasterPass { + constructor() { + this._shadowBias = new Vector4(); + this._shadowParams = new Vector4(); + this._shadowMapSize = new Vector4(); + this._shadowSpotMapSize = new Vector4(); + this._shadowMatrices = new Float32Array(16 * (ShadowCasterPass._maxCascades)); + this._shadowSpotMatrices = new Matrix4x4(); + this._splitBoundSpheres = new Float32Array(ShadowCasterPass._maxCascades * 4); + this._cascadeCount = 0; + this._shadowMapWidth = 0; + this._shadowMapHeight = 0; + this._shadowSliceDatas = [new ShadowSliceData(), new ShadowSliceData(), new ShadowSliceData(), new ShadowSliceData()]; + this._shadowSpotData = new ShadowSpotData(); + this._lightUp = new Vector3(); + this._lightSide = new Vector3(); + this._lightForward = new Vector3(); + this._shadowSpotData.cameraCullInfo.boundFrustum = new BoundFrustum(new Matrix4x4()); + } + _setupShadowCasterShaderValues(context, shaderValues, shadowSliceData, LightParam, shadowparams, shadowBias, lightType) { + shaderValues.setVector(ShadowCasterPass.SHADOW_BIAS, shadowBias); + switch (lightType) { + case exports.LightType.Directional: + shaderValues.setVector3(ShadowCasterPass.SHADOW_LIGHT_DIRECTION, LightParam); + break; + case exports.LightType.Spot: + shaderValues.setVector(ShadowCasterPass.SHADOW_PARAMS, shadowparams); + break; + case exports.LightType.Point: + break; + } + var cameraSV = shadowSliceData.cameraShaderValue; + cameraSV.setMatrix4x4(BaseCamera.VIEWMATRIX, shadowSliceData.viewMatrix); + cameraSV.setMatrix4x4(BaseCamera.PROJECTMATRIX, shadowSliceData.projectionMatrix); + cameraSV.setMatrix4x4(BaseCamera.VIEWPROJECTMATRIX, shadowSliceData.viewProjectMatrix); + context.viewMatrix = shadowSliceData.viewMatrix; + context.projectionMatrix = shadowSliceData.projectionMatrix; + context.projectionViewMatrix = shadowSliceData.viewProjectMatrix; + } + _setupShadowReceiverShaderValues(shaderValues) { + var light = this._light; + if (light.shadowCascadesMode !== exports.ShadowCascadesMode.NoCascades) + shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_CASCADE); + else + shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_CASCADE); + switch (light.shadowMode) { + case exports.ShadowMode.Hard: + shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SOFT_SHADOW_LOW); + shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SOFT_SHADOW_HIGH); + break; + case exports.ShadowMode.SoftLow: + shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SOFT_SHADOW_LOW); + shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SOFT_SHADOW_HIGH); + break; + case exports.ShadowMode.SoftHigh: + shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SOFT_SHADOW_HIGH); + shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SOFT_SHADOW_LOW); + break; + } + shaderValues.setTexture(ShadowCasterPass.SHADOW_MAP, this._shadowDirectLightMap); + shaderValues.setBuffer(ShadowCasterPass.SHADOW_MATRICES, this._shadowMatrices); + shaderValues.setVector(ShadowCasterPass.SHADOW_MAP_SIZE, this._shadowMapSize); + shaderValues.setVector(ShadowCasterPass.SHADOW_PARAMS, this._shadowParams); + shaderValues.setBuffer(ShadowCasterPass.SHADOW_SPLIT_SPHERES, this._splitBoundSpheres); + } + _setupSpotShadowReceiverShaderValues(shaderValues) { + var spotLight = this._light; + switch (spotLight.shadowMode) { + case exports.ShadowMode.Hard: + shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_HIGH); + shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_LOW); + break; + case exports.ShadowMode.SoftLow: + shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_LOW); + shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_HIGH); + break; + case exports.ShadowMode.SoftHigh: + shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_HIGH); + shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_LOW); + break; + } + shaderValues.setTexture(ShadowCasterPass.SHADOW_SPOTMAP, this._shadowSpotLightMap); + shaderValues.setMatrix4x4(ShadowCasterPass.SHADOW_SPOTMATRICES, this._shadowSpotMatrices); + shaderValues.setVector(ShadowCasterPass.SHADOW_SPOTMAP_SIZE, this._shadowSpotMapSize); + shaderValues.setVector(ShadowCasterPass.SHADOW_PARAMS, this._shadowParams); + } + update(camera, light, lightType) { + switch (lightType) { + case exports.ShadowLightType.DirectionLight: + this._light = light; + var lightWorld = ShadowCasterPass._tempMatrix0; + var lightWorldE = lightWorld.elements; + var lightUp = this._lightUp; + var lightSide = this._lightSide; + var lightForward = this._lightForward; + Matrix4x4.createFromQuaternion(light._transform.rotation, lightWorld); + lightSide.setValue(lightWorldE[0], lightWorldE[1], lightWorldE[2]); + lightUp.setValue(lightWorldE[4], lightWorldE[5], lightWorldE[6]); + lightForward.setValue(-lightWorldE[8], -lightWorldE[9], -lightWorldE[10]); + var atlasResolution = light._shadowResolution; + var cascadesMode = light._shadowCascadesMode; + var cascadesCount; + var shadowTileResolution; + var shadowMapWidth, shadowMapHeight; + if (cascadesMode == exports.ShadowCascadesMode.NoCascades) { + cascadesCount = 1; + shadowTileResolution = atlasResolution; + shadowMapWidth = atlasResolution; + shadowMapHeight = atlasResolution; + } + else { + cascadesCount = cascadesMode == exports.ShadowCascadesMode.TwoCascades ? 2 : 4; + shadowTileResolution = ShadowUtils.getMaxTileResolutionInAtlas(atlasResolution, atlasResolution, cascadesCount); + shadowMapWidth = shadowTileResolution * 2; + shadowMapHeight = cascadesMode == exports.ShadowCascadesMode.TwoCascades ? shadowTileResolution : shadowTileResolution * 2; + } + this._cascadeCount = cascadesCount; + this._shadowMapWidth = shadowMapWidth; + this._shadowMapHeight = shadowMapHeight; + var splitDistance = ShadowCasterPass._cascadesSplitDistance; + var frustumPlanes = ShadowCasterPass._frustumPlanes; + var cameraNear = camera.nearPlane; + var shadowFar = Math.min(camera.farPlane, light._shadowDistance); + var shadowMatrices = this._shadowMatrices; + var boundSpheres = this._splitBoundSpheres; + ShadowUtils.getCascadesSplitDistance(light._shadowTwoCascadeSplits, light._shadowFourCascadeSplits, cameraNear, shadowFar, camera.fieldOfView * MathUtils3D.Deg2Rad, camera.aspectRatio, cascadesMode, splitDistance); + ShadowUtils.getCameraFrustumPlanes(camera.projectionViewMatrix, frustumPlanes); + var forward = ShadowCasterPass._tempVector30; + camera._transform.getForward(forward); + Vector3.normalize(forward, forward); + for (var i = 0; i < cascadesCount; i++) { + var sliceData = this._shadowSliceDatas[i]; + sliceData.sphereCenterZ = ShadowUtils.getBoundSphereByFrustum(splitDistance[i], splitDistance[i + 1], camera.fieldOfView * MathUtils3D.Deg2Rad, camera.aspectRatio, camera._transform.position, forward, sliceData.splitBoundSphere); + ShadowUtils.getDirectionLightShadowCullPlanes(frustumPlanes, i, splitDistance, cameraNear, lightForward, sliceData); + ShadowUtils.getDirectionalLightMatrices(lightUp, lightSide, lightForward, i, light._shadowNearPlane, shadowTileResolution, sliceData, shadowMatrices); + if (cascadesCount > 1) + ShadowUtils.applySliceTransform(sliceData, shadowMapWidth, shadowMapHeight, i, shadowMatrices); + } + ShadowUtils.prepareShadowReceiverShaderValues(light, shadowMapWidth, shadowMapHeight, this._shadowSliceDatas, cascadesCount, this._shadowMapSize, this._shadowParams, shadowMatrices, boundSpheres); + break; + case exports.ShadowLightType.SpotLight: + this._light = light; + var lightWorld = ShadowCasterPass._tempMatrix0; + var lightForward = this._lightForward; + var shadowResolution = this._light._shadowResolution; + this._shadowMapWidth = shadowResolution; + this._shadowMapHeight = shadowResolution; + var shadowSpotData = this._shadowSpotData; + ShadowUtils.getSpotLightShadowData(shadowSpotData, this._light, shadowResolution, this._shadowParams, this._shadowSpotMatrices, this._shadowSpotMapSize); + break; + case exports.ShadowLightType.PointLight: + break; + default: + throw ("There is no shadow of this type"); + } + } + render(context, scene, lightType) { + switch (lightType) { + case exports.ShadowLightType.DirectionLight: + var shaderValues = scene._shaderValues; + context.pipelineMode = "ShadowCaster"; + ShaderData.setRuntimeValueMode(false); + var shadowMap = this._shadowDirectLightMap = ShadowUtils.getTemporaryShadowTexture(this._shadowMapWidth, this._shadowMapHeight, Laya.RenderTextureDepthFormat.DEPTH_16); + shadowMap._start(); + var light = this._light; + for (var i = 0, n = this._cascadeCount; i < n; i++) { + var sliceData = this._shadowSliceDatas[i]; + ShadowUtils.getShadowBias(light, sliceData.projectionMatrix, sliceData.resolution, this._shadowBias); + this._setupShadowCasterShaderValues(context, shaderValues, sliceData, this._lightForward, this._shadowParams, this._shadowBias, exports.LightType.Directional); + var shadowCullInfo = FrustumCulling._shadowCullInfo; + shadowCullInfo.position = sliceData.position; + shadowCullInfo.cullPlanes = sliceData.cullPlanes; + shadowCullInfo.cullPlaneCount = sliceData.cullPlaneCount; + shadowCullInfo.cullSphere = sliceData.splitBoundSphere; + shadowCullInfo.direction = this._lightForward; + var needRender = FrustumCulling.cullingShadow(shadowCullInfo, scene, context); + context.cameraShaderValue = sliceData.cameraShaderValue; + Camera._updateMark++; + var gl = Laya.LayaGL.instance; + var resolution = sliceData.resolution; + var offsetX = sliceData.offsetX; + var offsetY = sliceData.offsetY; + gl.enable(gl.SCISSOR_TEST); + gl.viewport(offsetX, offsetY, resolution, resolution); + gl.scissor(offsetX, offsetY, resolution, resolution); + gl.clear(gl.DEPTH_BUFFER_BIT); + if (needRender) { + gl.scissor(offsetX + 1, offsetY + 1, resolution - 2, resolution - 2); + scene._opaqueQueue._render(context); + } + } + shadowMap._end(); + this._setupShadowReceiverShaderValues(shaderValues); + ShaderData.setRuntimeValueMode(true); + context.pipelineMode = context.configPipeLineMode; + break; + case exports.ShadowLightType.SpotLight: + var shaderValues = scene._shaderValues; + context.pipelineMode = "ShadowCaster"; + ShaderData.setRuntimeValueMode(false); + var spotlight = this._light; + var shadowMap = this._shadowSpotLightMap = ShadowUtils.getTemporaryShadowTexture(this._shadowMapWidth, this._shadowMapHeight, Laya.RenderTextureDepthFormat.DEPTH_16); + shadowMap._start(); + var shadowSpotData = this._shadowSpotData; + ShadowUtils.getShadowBias(spotlight, shadowSpotData.projectionMatrix, shadowSpotData.resolution, this._shadowBias); + this._setupShadowCasterShaderValues(context, shaderValues, shadowSpotData, this._light.transform.position, this._shadowParams, this._shadowBias, exports.LightType.Spot); + var needRender = FrustumCulling.cullingSpotShadow(shadowSpotData.cameraCullInfo, scene, context); + context.cameraShaderValue = shadowSpotData.cameraShaderValue; + Camera._updateMark++; + var gl = Laya.LayaGL.instance; + gl.enable(gl.SCISSOR_TEST); + gl.viewport(shadowSpotData.offsetX, shadowSpotData.offsetY, shadowSpotData.resolution, shadowSpotData.resolution); + gl.scissor(shadowSpotData.offsetX, shadowSpotData.offsetY, shadowSpotData.resolution, shadowSpotData.resolution); + gl.clear(gl.DEPTH_BUFFER_BIT); + if (needRender) { + gl.scissor(shadowSpotData.offsetX, shadowSpotData.offsetY, shadowSpotData.resolution, shadowSpotData.resolution); + scene._opaqueQueue._render(context); + } + shadowMap._end(); + this._setupSpotShadowReceiverShaderValues(shaderValues); + ShaderData.setRuntimeValueMode(true); + context.pipelineMode = context.configPipeLineMode; + break; + case exports.ShadowLightType.PointLight: + break; + default: + throw ("There is no shadow of this type"); + } + } + cleanUp() { + this._shadowDirectLightMap && RenderTexture.recoverToPool(this._shadowDirectLightMap); + this._shadowSpotLightMap && RenderTexture.recoverToPool(this._shadowSpotLightMap); + this._shadowDirectLightMap = null; + this._shadowSpotLightMap = null; + this._light = null; + } + } + ShadowCasterPass._tempVector30 = new Vector3(); + ShadowCasterPass._tempMatrix0 = new Matrix4x4(); + ShadowCasterPass.SHADOW_BIAS = Shader3D.propertyNameToID("u_ShadowBias"); + ShadowCasterPass.SHADOW_LIGHT_DIRECTION = Shader3D.propertyNameToID("u_ShadowLightDirection"); + ShadowCasterPass.SHADOW_SPLIT_SPHERES = Shader3D.propertyNameToID("u_ShadowSplitSpheres"); + ShadowCasterPass.SHADOW_MATRICES = Shader3D.propertyNameToID("u_ShadowMatrices"); + ShadowCasterPass.SHADOW_MAP_SIZE = Shader3D.propertyNameToID("u_ShadowMapSize"); + ShadowCasterPass.SHADOW_MAP = Shader3D.propertyNameToID("u_ShadowMap"); + ShadowCasterPass.SHADOW_PARAMS = Shader3D.propertyNameToID("u_ShadowParams"); + ShadowCasterPass.SHADOW_SPOTMAP_SIZE = Shader3D.propertyNameToID("u_SpotShadowMapSize"); + ShadowCasterPass.SHADOW_SPOTMAP = Shader3D.propertyNameToID("u_SpotShadowMap"); + ShadowCasterPass.SHADOW_SPOTMATRICES = Shader3D.propertyNameToID("u_SpotViewProjectMatrix"); + ShadowCasterPass._maxCascades = 4; + ShadowCasterPass._cascadesSplitDistance = new Array(ShadowCasterPass._maxCascades + 1); + ShadowCasterPass._frustumPlanes = new Array(new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3()), new Plane(new Vector3())); + + class DynamicBatchManager { + constructor() { + this._batchRenderElementPool = []; + } + static _registerManager(manager) { + DynamicBatchManager._managers.push(manager); + } + _clear() { + this._batchRenderElementPoolIndex = 0; + } + _getBatchRenderElementFromPool() { + throw "StaticBatch:must override this function."; + } + dispose() { + } + } + DynamicBatchManager._managers = []; + + class ReflectionProbeList extends SingletonList { + constructor() { + super(); + } + add(singleElement) { + this._add(singleElement); + singleElement._setIndexInReflectionList(this.length++); + } + remove(singleElement) { + var index = singleElement._getIndexInReflectionList(); + this.length--; + if (index !== this.length) { + var end = this.elements[this.length]; + this.elements[index] = end; + end._setIndexInReflectionList(index); + } + singleElement._setIndexInReflectionList(-1); + } + } + + class ReflectionProbeManager { + constructor() { + this._reflectionProbes = new ReflectionProbeList(); + this._motionObjects = new SingletonList(); + this._needUpdateAllRender = false; + this._sceneReflectionProbe = new ReflectionProbe(); + this._sceneReflectionProbe.bounds = new Bounds(new Vector3(0, 0, 0), new Vector3(0, 0, 0)); + this._sceneReflectionProbe.boxProjection = false; + this._sceneReflectionProbe._isScene = true; + } + set sceneReflectionProbe(value) { + this._sceneReflectionProbe.reflectionTexture = value; + } + set sceneReflectionCubeHDRParam(value) { + this._sceneReflectionProbe.reflectionHDRParams = value; + } + _updateMotionObjects(baseRender) { + if (this._reflectionProbes.length == 0) { + baseRender._probReflection = this._sceneReflectionProbe; + return; + } + var elements = this._reflectionProbes.elements; + var maxOverlap = 0; + var mainProbe; + var renderBounds = baseRender.bounds; + var overlop; + for (var i = 0, n = this._reflectionProbes.length; i < n; i++) { + var renflectProbe = elements[i]; + if (!mainProbe) { + overlop = renderBounds.calculateBoundsintersection(renflectProbe.bounds); + if (overlop < maxOverlap) + continue; + } + else { + if (mainProbe.importance > renflectProbe.importance) + continue; + overlop = renderBounds.calculateBoundsintersection(renflectProbe.bounds); + if (overlop < maxOverlap && mainProbe.importance == renflectProbe.importance) + continue; + } + mainProbe = renflectProbe; + maxOverlap = overlop; + } + if (!mainProbe && this._sceneReflectionProbe) + mainProbe = this._sceneReflectionProbe; + baseRender._probReflection = mainProbe; + } + add(reflectionProbe) { + this._reflectionProbes.add(reflectionProbe); + this._needUpdateAllRender = true; + } + remove(reflectionProbe) { + this._reflectionProbes.remove(reflectionProbe); + this._needUpdateAllRender = true; + } + addMotionObject(renderObject) { + this._motionObjects.add(renderObject); + } + update() { + var elements = this._motionObjects.elements; + for (var i = 0, n = this._motionObjects.length; i < n; i++) { + this._updateMotionObjects(elements[i]); + } + this.clearMotionObjects(); + } + updateAllRenderObjects(baseRenders) { + var elements = baseRenders.elements; + for (var i = 0, n = baseRenders.length; i < n; i++) { + this._updateMotionObjects(elements[i]); + } + this._needUpdateAllRender = false; + } + clearMotionObjects() { + this._motionObjects.length = 0; + } + destroy() { + } + } + + (function (AmbientMode) { + AmbientMode[AmbientMode["SolidColor"] = 0] = "SolidColor"; + AmbientMode[AmbientMode["SphericalHarmonics"] = 1] = "SphericalHarmonics"; + })(exports.AmbientMode || (exports.AmbientMode = {})); + class Scene3D extends Laya.Sprite { + constructor() { + super(); + this._lightCount = 0; + this._pointLights = new LightQueue(); + this._spotLights = new LightQueue(); + this._directionLights = new LightQueue(); + this._alternateLights = new AlternateLightQueue(); + this._lightmaps = []; + this._skyRenderer = new SkyRenderer(); + this._input = new Input3D(); + this._timer = Laya.ILaya.timer; + this._time = 0; + this._shCoefficients = new Array(7); + this._ambientMode = exports.AmbientMode.SolidColor; + this._ambientSphericalHarmonics = new SphericalHarmonicsL2(); + this._ambientSphericalHarmonicsIntensity = 1.0; + this._reflectionDecodeFormat = Laya.TextureDecodeFormat.Normal; + this._reflectionIntensity = 1.0; + this._collsionTestList = []; + this._renders = new SimpleSingletonList(); + this._opaqueQueue = new RenderQueue(false); + this._transparentQueue = new RenderQueue(true); + this._cameraPool = []; + this._animatorPool = new SimpleSingletonList(); + this._scriptPool = new Array(); + this._tempScriptPool = new Array(); + this._needClearScriptPool = false; + this._reflectionCubeHDRParams = new Vector4(); + this._reflectionProbeManager = new ReflectionProbeManager(); + this.currentCreationLayer = Math.pow(2, 0); + this.enableLight = true; + this._key = new Laya.SubmitKey(); + this._pickIdToSprite = new Object(); + this._reflectionMode = 0; + if (!Config3D._config.isUseCannonPhysicsEngine && Physics3D._bullet) + this._physicsSimulation = new Laya.PhysicsSimulation(Scene3D.physicsSettings); + else if (Physics3D._cannon) { + this._cannonPhysicsSimulation = new Laya.CannonPhysicsSimulation(Scene3D.cannonPhysicsSettings); + } + this._shaderValues = new ShaderData(null); + this.enableFog = false; + this.fogStart = 300; + this.fogRange = 1000; + this.fogColor = new Vector3(0.7, 0.7, 0.7); + this.ambientColor = new Vector3(0.212, 0.227, 0.259); + this.reflectionIntensity = 1.0; + this.reflection = TextureCube.blackTexture; + for (var i = 0; i < 7; i++) + this._shCoefficients[i] = new Vector4(); + this._reflectionProbeManager.sceneReflectionCubeHDRParam = this._reflectionCubeHDRParams; + this._scene = this; + this._input.__init__(Laya.Render.canvas, this); + if (Scene3D.octreeCulling) + this._octree = new BoundsOctree(Scene3D.octreeInitialSize, Scene3D.octreeInitialCenter, Scene3D.octreeMinNodeSize, Scene3D.octreeLooseness); + if (FrustumCulling.debugFrustumCulling) { + this._debugTool = new PixelLineSprite3D(); + var lineMaterial = new PixelLineMaterial(); + lineMaterial.renderQueue = Material.RENDERQUEUE_TRANSPARENT; + lineMaterial.alphaTest = false; + lineMaterial.depthWrite = false; + lineMaterial.cull = RenderState.CULL_BACK; + lineMaterial.blend = RenderState.BLEND_ENABLE_ALL; + lineMaterial.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA; + lineMaterial.blendDst = RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA; + lineMaterial.depthTest = RenderState.DEPTHTEST_LESS; + this._debugTool.pixelLineRenderer.sharedMaterial = lineMaterial; + } + } + static __init__() { + var con = Config3D._config; + var multiLighting = con._multiLighting; + if (multiLighting) { + const width = 4; + var maxLightCount = con.maxLightCount; + var clusterSlices = con.lightClusterCount; + Cluster.instance = new Cluster(clusterSlices.x, clusterSlices.y, clusterSlices.z, Math.min(con.maxLightCount, con._maxAreaLightCountPerClusterAverage)); + Scene3D._lightTexture = Utils3D._createFloatTextureBuffer(width, maxLightCount); + Scene3D._lightTexture.lock = true; + Scene3D._lightPixles = new Float32Array(maxLightCount * width * 4); + } + Scene3DShaderDeclaration.SHADERDEFINE_FOG = Shader3D.getDefineByName("FOG"); + Scene3DShaderDeclaration.SHADERDEFINE_DIRECTIONLIGHT = Shader3D.getDefineByName("DIRECTIONLIGHT"); + Scene3DShaderDeclaration.SHADERDEFINE_POINTLIGHT = Shader3D.getDefineByName("POINTLIGHT"); + Scene3DShaderDeclaration.SHADERDEFINE_SPOTLIGHT = Shader3D.getDefineByName("SPOTLIGHT"); + Scene3DShaderDeclaration.SHADERDEFINE_SHADOW = Shader3D.getDefineByName("SHADOW"); + Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_CASCADE = Shader3D.getDefineByName("SHADOW_CASCADE"); + Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SOFT_SHADOW_LOW = Shader3D.getDefineByName("SHADOW_SOFT_SHADOW_LOW"); + Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SOFT_SHADOW_HIGH = Shader3D.getDefineByName("SHADOW_SOFT_SHADOW_HIGH"); + Scene3DShaderDeclaration.SHADERDEFINE_GI_AMBIENT_SH = Shader3D.getDefineByName("GI_AMBIENT_SH"); + Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT = Shader3D.getDefineByName("SHADOW_SPOT"); + Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_LOW = Shader3D.getDefineByName("SHADOW_SPOT_SOFT_SHADOW_LOW"); + Scene3DShaderDeclaration.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_HIGH = Shader3D.getDefineByName("SHADOW_SPOT_SOFT_SHADOW_HIGH"); + var config = Config3D._config; + var configShaderValue = Scene3D._configDefineValues; + (config._multiLighting) || (configShaderValue.add(Shader3D.SHADERDEFINE_LEGACYSINGALLIGHTING)); + if (Laya.LayaGL.layaGPUInstance._isWebGL2) + configShaderValue.add(Shader3D.SHADERDEFINE_GRAPHICS_API_GLES3); + else + configShaderValue.add(Shader3D.SHADERDEFINE_GRAPHICS_API_GLES2); + switch (config.pbrRenderQuality) { + case exports.PBRRenderQuality.High: + configShaderValue.add(PBRMaterial.SHADERDEFINE_LAYA_PBR_BRDF_HIGH); + break; + case exports.PBRRenderQuality.Low: + configShaderValue.add(PBRMaterial.SHADERDEFINE_LAYA_PBR_BRDF_LOW); + break; + default: + throw "Scene3D:unknown shader quality."; + } + if (config.isUseCannonPhysicsEngine) { + Physics3D._cannon && (Scene3D.cannonPhysicsSettings = new Laya.CannonPhysicsSettings()); + } + else { + Physics3D._bullet && (Scene3D.physicsSettings = new Laya.PhysicsSettings()); + } + } + static load(url, complete) { + Laya.ILaya.loader.create(url, complete, null, Scene3D.HIERARCHY); + } + get url() { + return this._url; + } + get enableFog() { + return this._enableFog; + } + set enableFog(value) { + if (this._enableFog !== value) { + this._enableFog = value; + if (value) { + this._shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_FOG); + } + else + this._shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_FOG); + } + } + get fogColor() { + return this._shaderValues.getVector3(Scene3D.FOGCOLOR); + } + set fogColor(value) { + this._shaderValues.setVector3(Scene3D.FOGCOLOR, value); + } + get fogStart() { + return this._shaderValues.getNumber(Scene3D.FOGSTART); + } + set fogStart(value) { + this._shaderValues.setNumber(Scene3D.FOGSTART, value); + } + get fogRange() { + return this._shaderValues.getNumber(Scene3D.FOGRANGE); + } + set fogRange(value) { + this._shaderValues.setNumber(Scene3D.FOGRANGE, value); + } + get ambientMode() { + return this._ambientMode; + } + set ambientMode(value) { + if (this._ambientMode !== value) { + switch (value) { + case exports.AmbientMode.SolidColor: + this._shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_GI_AMBIENT_SH); + break; + case exports.AmbientMode.SphericalHarmonics: + this._shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_GI_AMBIENT_SH); + break; + default: + throw "Scene3D: unknown ambientMode."; + } + this._ambientMode = value; + } + } + get ambientColor() { + return this._shaderValues.getVector3(Scene3D.AMBIENTCOLOR); + } + set ambientColor(value) { + this._shaderValues.setVector3(Scene3D.AMBIENTCOLOR, value); + } + get ambientSphericalHarmonics() { + return this._ambientSphericalHarmonics; + } + set ambientSphericalHarmonics(value) { + var originalSH = value || SphericalHarmonicsL2._default; + this._applySHCoefficients(originalSH, Math.pow(this._ambientSphericalHarmonicsIntensity, 2.2)); + if (this._ambientSphericalHarmonics != value) + value.cloneTo(this._ambientSphericalHarmonics); + } + get ambientSphericalHarmonicsIntensity() { + return this._ambientSphericalHarmonicsIntensity; + } + set ambientSphericalHarmonicsIntensity(value) { + value = Math.max(Math.min(value, 8.0), 0.0); + if (this._ambientSphericalHarmonicsIntensity !== value) { + var originalSH = this._ambientSphericalHarmonics || SphericalHarmonicsL2._default; + this._applySHCoefficients(originalSH, Math.pow(value, 2.2)); + this._ambientSphericalHarmonicsIntensity = value; + } + } + get reflection() { + return this._reflection; + } + set reflection(value) { + value = value ? value : TextureCube.blackTexture; + if (this._reflection != value) { + value._addReference(); + this._reflectionProbeManager.sceneReflectionProbe = value; + this._reflection = value; + this._reflectionProbeManager._needUpdateAllRender = true; + } + } + get reflectionDecodingFormat() { + return this._reflectionDecodeFormat; + } + set reflectionDecodingFormat(value) { + if (this._reflectionDecodeFormat != value) { + this._reflectionCubeHDRParams.x = this._reflectionIntensity; + if (this._reflectionDecodeFormat == Laya.TextureDecodeFormat.RGBM) + this._reflectionCubeHDRParams.x *= 5.0; + this._reflectionDecodeFormat = value; + this._reflectionProbeManager.sceneReflectionCubeHDRParam = this._reflectionCubeHDRParams; + } + } + get reflectionIntensity() { + return this._reflectionIntensity; + } + set reflectionIntensity(value) { + value = Math.max(Math.min(value, 1.0), 0.0); + this._reflectionCubeHDRParams.x = value; + if (this._reflectionDecodeFormat == Laya.TextureDecodeFormat.RGBM) + this._reflectionCubeHDRParams.x *= 5.0; + this._reflectionIntensity = value; + this._reflectionProbeManager.sceneReflectionCubeHDRParam = this._reflectionCubeHDRParams; + } + get skyRenderer() { + return this._skyRenderer; + } + get physicsSimulation() { + return this._physicsSimulation; + } + get cannonPhysicsSimulation() { + return this._cannonPhysicsSimulation; + } + get timer() { + return this._timer; + } + set timer(value) { + this._timer = value; + } + get input() { + return this._input; + } + get lightmaps() { + return this._lightmaps.slice(); + } + set lightmaps(value) { + var maps = this._lightmaps; + if (maps) { + for (var i = 0, n = maps.length; i < n; i++) { + var map = maps[i]; + map.lightmapColor._removeReference(); + map.lightmapDirection._removeReference(); + } + } + if (value) { + var count = value.length; + maps.length = count; + for (i = 0; i < count; i++) { + var map = value[i]; + map.lightmapColor && map.lightmapColor._addReference(); + map.lightmapDirection && map.lightmapDirection._addReference(); + maps[i] = map; + } + } + else { + maps.length = 0; + } + } + _applySHCoefficients(originalSH, intensity) { + var optSH = this._shCoefficients; + for (var i = 0; i < 3; i++) { + var shaderSHA = optSH[i]; + var shaderSHB = optSH[i + 3]; + shaderSHA.setValue(originalSH.getCoefficient(i, 3) * intensity, originalSH.getCoefficient(i, 1) * intensity, originalSH.getCoefficient(i, 2) * intensity, (originalSH.getCoefficient(i, 0) - originalSH.getCoefficient(i, 6)) * intensity); + shaderSHB.setValue(originalSH.getCoefficient(i, 4) * intensity, originalSH.getCoefficient(i, 5) * intensity, originalSH.getCoefficient(i, 6) * 3 * intensity, originalSH.getCoefficient(i, 7) * intensity); + } + optSH[6].setValue(originalSH.getCoefficient(0, 8) * intensity, originalSH.getCoefficient(1, 8) * intensity, originalSH.getCoefficient(2, 8) * intensity, 1); + var shaderValues = this._shaderValues; + shaderValues.setVector(Scene3D.AMBIENTSHAR, optSH[0]); + shaderValues.setVector(Scene3D.AMBIENTSHAG, optSH[1]); + shaderValues.setVector(Scene3D.AMBIENTSHAB, optSH[2]); + shaderValues.setVector(Scene3D.AMBIENTSHBR, optSH[3]); + shaderValues.setVector(Scene3D.AMBIENTSHBG, optSH[4]); + shaderValues.setVector(Scene3D.AMBIENTSHBB, optSH[5]); + shaderValues.setVector(Scene3D.AMBIENTSHC, optSH[6]); + } + _update() { + Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D); + var delta = this.timer._delta / 1000; + this._time += delta; + this._shaderValues.setNumber(Scene3D.TIME, this._time); + Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS); + var simulation = this._physicsSimulation; + if (Physics3D._enablePhysics && !Laya.PhysicsSimulation.disableSimulation && !Config3D._config.isUseCannonPhysicsEngine) { + simulation._updatePhysicsTransformFromRender(); + Laya.PhysicsComponent._addUpdateList = false; + Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS_SIMULATE); + simulation._simulate(delta); + Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS_SIMULATE); + Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS_CHARACTORCOLLISION); + simulation._updateCharacters(); + Laya.PhysicsComponent._addUpdateList = true; + simulation._updateCollisions(); + Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS_CHARACTORCOLLISION); + Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS_EVENTSCRIPTS); + simulation._eventScripts(); + Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS_EVENTSCRIPTS); + } + if (Physics3D._cannon && Config3D._config.isUseCannonPhysicsEngine) { + var cannonSimulation = this._cannonPhysicsSimulation; + cannonSimulation._updatePhysicsTransformFromRender(); + Laya.CannonPhysicsComponent._addUpdateList = false; + cannonSimulation._simulate(delta); + Laya.CannonPhysicsComponent._addUpdateList = true; + cannonSimulation._updateCollisions(); + cannonSimulation._eventScripts(); + } + Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_PHYSICS); + Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_UPDATESCRIPT); + this._input._update(); + this._clearScript(); + this._updateScript(); + Animator._update(this); + Laya.VideoTexture._update(); + if (this._reflectionProbeManager._needUpdateAllRender) + this._reflectionProbeManager.updateAllRenderObjects(this._renders); + else + this._reflectionProbeManager.update(); + this._lateUpdateScript(); + Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_UPDATESCRIPT); + Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D); + } + _binarySearchIndexInCameraPool(camera) { + var start = 0; + var end = this._cameraPool.length - 1; + var mid; + while (start <= end) { + mid = Math.floor((start + end) / 2); + var midValue = this._cameraPool[mid]._renderingOrder; + if (midValue == camera._renderingOrder) + return mid; + else if (midValue > camera._renderingOrder) + end = mid - 1; + else + start = mid + 1; + } + return start; + } + _allotPickColorByID(id, pickColor) { + var pickColorR = Math.floor(id / (255 * 255)); + id -= pickColorR * 255 * 255; + var pickColorG = Math.floor(id / 255); + id -= pickColorG * 255; + var pickColorB = id; + pickColor.x = pickColorR / 255; + pickColor.y = pickColorG / 255; + pickColor.z = pickColorB / 255; + pickColor.w = 1.0; + } + _searchIDByPickColor(pickColor) { + var id = pickColor.x * 255 * 255 + pickColor.y * 255 + pickColor.z; + return id; + } + onEnable() { + this._input._onCanvasEvent(Laya.Render.canvas); + } + onDisable() { + this._input._offCanvasEvent(Laya.Render.canvas); + } + _setCreateURL(url) { + this._url = Laya.URL.formatURL(url); + } + _getGroup() { + return this._group; + } + _setGroup(value) { + this._group = value; + } + _clearScript() { + if (this._needClearScriptPool) { + var scripts = this._scriptPool; + for (var i = 0, n = scripts.length; i < n; i++) { + var script = scripts[i]; + if (script) { + script._indexInPool = this._tempScriptPool.length; + this._tempScriptPool.push(script); + } + } + this._scriptPool = this._tempScriptPool; + scripts.length = 0; + this._tempScriptPool = scripts; + this._needClearScriptPool = false; + } + } + _updateScript() { + var scripts = this._scriptPool; + for (var i = 0, n = scripts.length; i < n; i++) { + var script = scripts[i]; + (script && script.enabled) && (script.onUpdate()); + } + } + _lateUpdateScript() { + var scripts = this._scriptPool; + for (var i = 0, n = scripts.length; i < n; i++) { + var script = scripts[i]; + (script && script.enabled) && (script.onLateUpdate()); + } + } + _onActive() { + super._onActive(); + Laya.ILaya.stage._scene3Ds.push(this); + } + _onInActive() { + super._onInActive(); + var scenes = Laya.ILaya.stage._scene3Ds; + scenes.splice(scenes.indexOf(this), 1); + } + _prepareSceneToRender() { + var shaderValues = this._shaderValues; + var multiLighting = Config3D._config._multiLighting; + if (multiLighting) { + var ligTex = Scene3D._lightTexture; + var ligPix = Scene3D._lightPixles; + const pixelWidth = ligTex.width; + const floatWidth = pixelWidth * 4; + var curCount = 0; + var dirCount = this._directionLights._length; + var dirElements = this._directionLights._elements; + if (dirCount > 0) { + var sunLightIndex = this._directionLights.getBrightestLight(); + this._mainDirectionLight = dirElements[sunLightIndex]; + this._directionLights.normalLightOrdering(sunLightIndex); + for (var i = 0; i < dirCount; i++, curCount++) { + var dirLight = dirElements[i]; + var dir = dirLight._direction; + var intCor = dirLight._intensityColor; + var off = floatWidth * curCount; + Vector3.scale(dirLight.color, dirLight._intensity, intCor); + dirLight.transform.worldMatrix.getForward(dir); + Vector3.normalize(dir, dir); + ligPix[off] = intCor.x; + ligPix[off + 1] = intCor.y; + ligPix[off + 2] = intCor.z; + ligPix[off + 4] = dir.x; + ligPix[off + 5] = dir.y; + ligPix[off + 6] = dir.z; + if (i == 0) { + shaderValues.setVector3(Scene3D.SUNLIGHTDIRCOLOR, intCor); + shaderValues.setVector3(Scene3D.SUNLIGHTDIRECTION, dir); + } + } + shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_DIRECTIONLIGHT); + } + else { + shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_DIRECTIONLIGHT); + } + var poiCount = this._pointLights._length; + if (poiCount > 0) { + var poiElements = this._pointLights._elements; + var mainPointLightIndex = this._pointLights.getBrightestLight(); + this._mainPointLight = poiElements[mainPointLightIndex]; + this._pointLights.normalLightOrdering(mainPointLightIndex); + for (var i = 0; i < poiCount; i++, curCount++) { + var poiLight = poiElements[i]; + var pos = poiLight.transform.position; + var intCor = poiLight._intensityColor; + var off = floatWidth * curCount; + Vector3.scale(poiLight.color, poiLight._intensity, intCor); + ligPix[off] = intCor.x; + ligPix[off + 1] = intCor.y; + ligPix[off + 2] = intCor.z; + ligPix[off + 3] = poiLight.range; + ligPix[off + 4] = pos.x; + ligPix[off + 5] = pos.y; + ligPix[off + 6] = pos.z; + } + shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_POINTLIGHT); + } + else { + shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_POINTLIGHT); + } + var spoCount = this._spotLights._length; + if (spoCount > 0) { + var spoElements = this._spotLights._elements; + var mainSpotLightIndex = this._spotLights.getBrightestLight(); + this._mainSpotLight = spoElements[mainSpotLightIndex]; + this._spotLights.normalLightOrdering(mainSpotLightIndex); + for (var i = 0; i < spoCount; i++, curCount++) { + var spoLight = spoElements[i]; + var dir = spoLight._direction; + var pos = spoLight.transform.position; + var intCor = spoLight._intensityColor; + var off = floatWidth * curCount; + Vector3.scale(spoLight.color, spoLight._intensity, intCor); + spoLight.transform.worldMatrix.getForward(dir); + Vector3.normalize(dir, dir); + ligPix[off] = intCor.x; + ligPix[off + 1] = intCor.y; + ligPix[off + 2] = intCor.z; + ligPix[off + 3] = spoLight.range; + ligPix[off + 4] = pos.x; + ligPix[off + 5] = pos.y; + ligPix[off + 6] = pos.z; + ligPix[off + 7] = spoLight.spotAngle * Math.PI / 180; + ligPix[off + 8] = dir.x; + ligPix[off + 9] = dir.y; + ligPix[off + 10] = dir.z; + } + shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SPOTLIGHT); + } + else { + shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SPOTLIGHT); + } + (curCount > 0) && (ligTex.setSubPixels(0, 0, pixelWidth, curCount, ligPix, 0)); + shaderValues.setTexture(Scene3D.LIGHTBUFFER, ligTex); + shaderValues.setInt(Scene3D.DIRECTIONLIGHTCOUNT, this._directionLights._length); + shaderValues.setTexture(Scene3D.CLUSTERBUFFER, Cluster.instance._clusterTexture); + } + else { + if (this._directionLights._length > 0) { + var dirLight = this._directionLights._elements[0]; + this._mainDirectionLight = dirLight; + Vector3.scale(dirLight.color, dirLight._intensity, dirLight._intensityColor); + dirLight.transform.worldMatrix.getForward(dirLight._direction); + Vector3.normalize(dirLight._direction, dirLight._direction); + shaderValues.setVector3(Scene3D.LIGHTDIRCOLOR, dirLight._intensityColor); + shaderValues.setVector3(Scene3D.LIGHTDIRECTION, dirLight._direction); + shaderValues.setVector3(Scene3D.SUNLIGHTDIRCOLOR, dirLight._intensityColor); + shaderValues.setVector3(Scene3D.SUNLIGHTDIRECTION, dirLight._direction); + shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_DIRECTIONLIGHT); + } + else { + shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_DIRECTIONLIGHT); + } + if (this._pointLights._length > 0) { + var poiLight = this._pointLights._elements[0]; + this._mainPointLight = poiLight; + Vector3.scale(poiLight.color, poiLight._intensity, poiLight._intensityColor); + shaderValues.setVector3(Scene3D.POINTLIGHTCOLOR, poiLight._intensityColor); + shaderValues.setVector3(Scene3D.POINTLIGHTPOS, poiLight.transform.position); + shaderValues.setNumber(Scene3D.POINTLIGHTRANGE, poiLight.range); + shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_POINTLIGHT); + } + else { + shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_POINTLIGHT); + } + if (this._spotLights._length > 0) { + var spotLight = this._spotLights._elements[0]; + this._mainSpotLight = spotLight; + Vector3.scale(spotLight.color, spotLight._intensity, spotLight._intensityColor); + shaderValues.setVector3(Scene3D.SPOTLIGHTCOLOR, spotLight._intensityColor); + shaderValues.setVector3(Scene3D.SPOTLIGHTPOS, spotLight.transform.position); + spotLight.transform.worldMatrix.getForward(spotLight._direction); + Vector3.normalize(spotLight._direction, spotLight._direction); + shaderValues.setVector3(Scene3D.SPOTLIGHTDIRECTION, spotLight._direction); + shaderValues.setNumber(Scene3D.SPOTLIGHTRANGE, spotLight.range); + shaderValues.setNumber(Scene3D.SPOTLIGHTSPOTANGLE, spotLight.spotAngle * Math.PI / 180); + shaderValues.addDefine(Scene3DShaderDeclaration.SHADERDEFINE_SPOTLIGHT); + } + else { + shaderValues.removeDefine(Scene3DShaderDeclaration.SHADERDEFINE_SPOTLIGHT); + } + } + } + _addScript(script) { + if (script._indexInPool != -1) + return; + var scripts = this._scriptPool; + script._indexInPool = scripts.length; + scripts.push(script); + } + _removeScript(script) { + if (script._indexInPool == -1) + return; + this._scriptPool[script._indexInPool] = null; + script._indexInPool = -1; + this._needClearScriptPool = true; + } + _preRenderScript() { + var scripts = this._scriptPool; + for (var i = 0, n = scripts.length; i < n; i++) { + var script = scripts[i]; + (script && script.enabled) && (script.onPreRender()); + } + } + _postRenderScript() { + var scripts = this._scriptPool; + for (var i = 0, n = scripts.length; i < n; i++) { + var script = scripts[i]; + (script && script.enabled) && (script.onPostRender()); + } + } + _addCamera(camera) { + var index = this._binarySearchIndexInCameraPool(camera); + var order = camera._renderingOrder; + var count = this._cameraPool.length; + while (index < count && this._cameraPool[index]._renderingOrder <= order) + index++; + this._cameraPool.splice(index, 0, camera); + } + _removeCamera(camera) { + this._cameraPool.splice(this._cameraPool.indexOf(camera), 1); + } + _preCulling(context, camera, shader, replacementTag) { + var cameraCullInfo = FrustumCulling._cameraCullInfo; + cameraCullInfo.position = camera._transform.position; + cameraCullInfo.cullingMask = camera.cullingMask; + cameraCullInfo.boundFrustum = camera.boundFrustum; + cameraCullInfo.useOcclusionCulling = camera.useOcclusionCulling; + FrustumCulling.renderObjectCulling(cameraCullInfo, this, context, shader, replacementTag, false); + } + _clear(gl, state) { + var viewport = state.viewport; + var camera = state.camera; + var renderTex = camera._getRenderTexture(); + var vpX, vpY; + var vpW = viewport.width; + var vpH = viewport.height; + if (camera._needInternalRenderTexture()) { + vpX = 0; + vpY = 0; + } + else { + vpX = viewport.x; + vpY = camera._getCanvasHeight() - viewport.y - vpH; + } + gl.viewport(vpX, vpY, vpW, vpH); + var flag; + var clearFlag = camera.clearFlag; + if (clearFlag === exports.CameraClearFlags.Sky && !(camera.skyRenderer._isAvailable() || this._skyRenderer._isAvailable())) + clearFlag = exports.CameraClearFlags.SolidColor; + switch (clearFlag) { + case exports.CameraClearFlags.SolidColor: + var clearColor = camera.clearColor; + gl.enable(gl.SCISSOR_TEST); + gl.scissor(vpX, vpY, vpW, vpH); + if (clearColor) + gl.clearColor(clearColor.x, clearColor.y, clearColor.z, clearColor.w); + else + gl.clearColor(0, 0, 0, 0); + if (renderTex) { + flag = gl.COLOR_BUFFER_BIT; + switch (renderTex.depthStencilFormat) { + case Laya.RenderTextureDepthFormat.DEPTH_16: + flag |= gl.DEPTH_BUFFER_BIT; + break; + case Laya.RenderTextureDepthFormat.STENCIL_8: + flag |= gl.STENCIL_BUFFER_BIT; + break; + case Laya.RenderTextureDepthFormat.DEPTHSTENCIL_24_8: + flag |= gl.DEPTH_BUFFER_BIT; + flag |= gl.STENCIL_BUFFER_BIT; + break; + } + } + else { + flag = gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT; + } + Laya.WebGLContext.setDepthMask(gl, true); + gl.clear(flag); + gl.disable(gl.SCISSOR_TEST); + break; + case exports.CameraClearFlags.Sky: + case exports.CameraClearFlags.DepthOnly: + gl.enable(gl.SCISSOR_TEST); + gl.scissor(vpX, vpY, vpW, vpH); + if (renderTex) { + switch (renderTex.depthStencilFormat) { + case Laya.RenderTextureDepthFormat.DEPTH_16: + flag = gl.DEPTH_BUFFER_BIT; + break; + case Laya.RenderTextureDepthFormat.STENCIL_8: + flag = gl.STENCIL_BUFFER_BIT; + break; + case Laya.RenderTextureDepthFormat.DEPTHSTENCIL_24_8: + flag = gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT; + break; + } + } + else { + flag = gl.DEPTH_BUFFER_BIT; + } + Laya.WebGLContext.setDepthMask(gl, true); + gl.clear(flag); + gl.disable(gl.SCISSOR_TEST); + break; + case exports.CameraClearFlags.Nothing: + break; + default: + throw new Error("Scene3D:camera clearFlag invalid."); + } + } + _renderScene(context, renderFlag) { + var camera = context.camera; + switch (renderFlag) { + case Scene3D.SCENERENDERFLAG_RENDERQPAQUE: + this._opaqueQueue._render(context); + break; + case Scene3D.SCENERENDERFLAG_SKYBOX: + if (camera.clearFlag === exports.CameraClearFlags.Sky) { + if (camera.skyRenderer._isAvailable()) + camera.skyRenderer._render(context); + else if (this._skyRenderer._isAvailable()) + this._skyRenderer._render(context); + } + break; + case Scene3D.SCENERENDERFLAG_RENDERTRANSPARENT: + this._transparentQueue._render(context); + if (FrustumCulling.debugFrustumCulling) { + var renderElements = this._debugTool._render._renderElements; + for (var i = 0, n = renderElements.length; i < n; i++) { + renderElements[i]._update(this, context, null, null); + renderElements[i]._render(context); + } + } + break; + } + } + _parse(data, spriteMap) { + var lightMapsData = data.lightmaps; + if (lightMapsData) { + var lightMapCount = lightMapsData.length; + var lightmaps = new Array(lightMapCount); + for (var i = 0; i < lightMapCount; i++) { + var lightMap = new Lightmap(); + var lightMapData = lightMapsData[i]; + if (lightMapData.path) { + lightMap.lightmapColor = Laya.Loader.getRes(lightMapData.path); + } + else { + lightMap.lightmapColor = Laya.Loader.getRes(lightMapData.color.path); + if (lightMapData.direction) + lightMap.lightmapDirection = Laya.Loader.getRes(lightMapData.direction.path); + } + lightmaps[i] = lightMap; + } + this.lightmaps = lightmaps; + } + var ambientColorData = data.ambientColor; + if (ambientColorData) { + var ambCol = this.ambientColor; + ambCol.fromArray(ambientColorData); + this.ambientColor = ambCol; + } + var skyData = data.sky; + if (skyData) { + this._skyRenderer.material = Laya.Loader.getRes(skyData.material.path); + switch (skyData.mesh) { + case "SkyBox": + this._skyRenderer.mesh = SkyBox.instance; + break; + case "SkyDome": + this._skyRenderer.mesh = SkyDome.instance; + break; + default: + this.skyRenderer.mesh = SkyBox.instance; + } + } + this.enableFog = data.enableFog; + this.fogStart = data.fogStart; + this.fogRange = data.fogRange; + var fogColorData = data.fogColor; + if (fogColorData) { + var fogCol = this.fogColor; + fogCol.fromArray(fogColorData); + this.fogColor = fogCol; + } + var ambientSphericalHarmonicsData = data.ambientSphericalHarmonics; + if (ambientSphericalHarmonicsData) { + var ambientSH = this.ambientSphericalHarmonics; + for (var i = 0; i < 3; i++) { + var off = i * 9; + ambientSH.setCoefficients(i, ambientSphericalHarmonicsData[off], ambientSphericalHarmonicsData[off + 1], ambientSphericalHarmonicsData[off + 2], ambientSphericalHarmonicsData[off + 3], ambientSphericalHarmonicsData[off + 4], ambientSphericalHarmonicsData[off + 5], ambientSphericalHarmonicsData[off + 6], ambientSphericalHarmonicsData[off + 7], ambientSphericalHarmonicsData[off + 8]); + } + this.ambientSphericalHarmonics = ambientSH; + } + var reflectionData = data.reflection; + (reflectionData != undefined) && (this.reflection = Laya.Loader.getRes(reflectionData)); + var reflectionDecodingFormatData = data.reflectionDecodingFormat; + (reflectionDecodingFormatData != undefined) && (this.reflectionDecodingFormat = reflectionDecodingFormatData); + var ambientModeData = data.ambientMode; + (ambientModeData != undefined) && (this.ambientMode = ambientModeData); + var ambientSphericalHarmonicsIntensityData = data.ambientSphericalHarmonicsIntensity; + (ambientSphericalHarmonicsIntensityData != undefined) && (this.ambientSphericalHarmonicsIntensity = ambientSphericalHarmonicsIntensityData); + var reflectionIntensityData = data.reflectionIntensity; + (reflectionIntensityData != undefined) && (this.reflectionIntensity = reflectionIntensityData); + } + _addRenderObject(render) { + if (this._octree && render._supportOctree) { + this._octree.add(render); + } + else { + this._renders.add(render); + } + render._addReflectionProbeUpdate(); + } + _removeRenderObject(render) { + if (this._octree && render._supportOctree) { + this._octree.remove(render); + } + else { + this._renders.remove(render); + } + } + _getRenderQueue(index) { + if (index <= 2500) + return this._opaqueQueue; + else + return this._transparentQueue; + } + _clearRenderQueue() { + this._opaqueQueue.clear(); + this._transparentQueue.clear(); + var staticBatchManagers = StaticBatchManager._managers; + for (var i = 0, n = staticBatchManagers.length; i < n; i++) + staticBatchManagers[i]._clear(); + var dynamicBatchManagers = DynamicBatchManager._managers; + for (var i = 0, n = dynamicBatchManagers.length; i < n; i++) + dynamicBatchManagers[i]._clear(); + } + destroy(destroyChild = true) { + if (this.destroyed) + return; + super.destroy(destroyChild); + this._skyRenderer.destroy(); + this._skyRenderer = null; + this._directionLights = null; + this._pointLights = null; + this._spotLights = null; + this._alternateLights = null; + this._shaderValues = null; + this._renders.clearElement(); + this._animatorPool.clearElement(); + this._renders = null; + this._animatorPool = null; + this._cameraPool = null; + this._octree = null; + this._physicsSimulation && this._physicsSimulation._destroy(); + this._reflection._removeReference(); + this._reflection = null; + var maps = this._lightmaps; + if (maps) { + for (var i = 0, n = maps.length; i < n; i++) { + var map = maps[i]; + map.lightmapColor && map.lightmapColor._removeReference(); + map.lightmapDirection && map.lightmapDirection._removeReference(); + } + } + this._lightmaps = null; + this._reflectionProbeManager.destroy(); + Laya.Loader.clearRes(this.url); + } + render(ctx) { + ctx._curSubmit = Laya.SubmitBase.RENDERBASE; + this._children.length > 0 && ctx.addRenderObject(this); + } + renderSubmit() { + Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D); + this._prepareSceneToRender(); + var i, n, n1; + Laya.PerformancePlugin.begainSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER); + for (i = 0, n = this._cameraPool.length, n1 = n - 1; i < n; i++) { + if (Laya.Render.supportWebGLPlusRendering) + ShaderData.setRuntimeValueMode((i == n1) ? true : false); + var camera = this._cameraPool[i]; + camera.enableRender && camera.render(); + } + Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER); + Laya.Context.set2DRenderConfig(); + Laya.PerformancePlugin.endSample(Laya.PerformancePlugin.PERFORMANCE_LAYA_3D); + return 1; + } + getRenderType() { + return 0; + } + releaseRender() { + } + reUse(context, pos) { + return 0; + } + setGlobalShaderValue(name, shaderDataType, value) { + var shaderOffset = Shader3D.propertyNameToID(name); + switch (shaderDataType) { + case exports.ShaderDataType.Int: + this._shaderValues.setInt(shaderOffset, value); + break; + case exports.ShaderDataType.Number: + this._shaderValues.setNumber(shaderOffset, value); + break; + case exports.ShaderDataType.Bool: + this._shaderValues.setBool(shaderOffset, value); + break; + case exports.ShaderDataType.Matrix4x4: + this._shaderValues.setMatrix4x4(shaderOffset, value); + break; + case exports.ShaderDataType.Quaternion: + this._shaderValues.setQuaternion(shaderOffset, value); + break; + case exports.ShaderDataType.Texture: + this._shaderValues.setTexture(shaderOffset, value); + break; + case exports.ShaderDataType.Vector4: + this._shaderValues.setVector(shaderOffset, value); + break; + case exports.ShaderDataType.Vector2: + this._shaderValues.setVector2(shaderOffset, value); + break; + case exports.ShaderDataType.Vector3: + this._shaderValues.setVector3(shaderOffset, value); + break; + case exports.ShaderDataType.Buffer: + this._shaderValues.setBuffer(shaderOffset, value); + break; + } + } + get customReflection() { + return this._reflection; + } + set customReflection(value) { + if (this._reflection != value) { + value._addReference(); + this._reflectionProbeManager.sceneReflectionProbe = value; + this._reflection = value; + } + } + get reflectionMode() { + return this._reflectionMode; + } + set reflectionMode(value) { + this._reflectionMode = value; + } + setlightmaps(value) { + var maps = this._lightmaps; + for (var i = 0, n = maps.length; i < n; i++) + maps[i].lightmapColor._removeReference(); + if (value) { + var count = value.length; + maps.length = count; + for (i = 0; i < count; i++) { + var lightMap = value[i]; + lightMap._addReference(); + (maps[i]) || (maps[i] = new Lightmap()); + maps[i].lightmapColor = lightMap; + } + } + else { + throw new Error("Scene3D: value value can't be null."); + } + } + getlightmaps() { + var lightmapColors = new Array(this._lightmaps.length); + for (var i = 0; i < this._lightmaps.length; i++) { + lightmapColors[i] = this._lightmaps[i].lightmapColor; + } + return lightmapColors; + } + } + Scene3D._shadowCasterPass = new ShadowCasterPass(); + Scene3D.HIERARCHY = "HIERARCHY"; + Scene3D.octreeCulling = false; + Scene3D.octreeInitialSize = 64.0; + Scene3D.octreeInitialCenter = new Vector3(0, 0, 0); + Scene3D.octreeMinNodeSize = 2.0; + Scene3D.octreeLooseness = 1.25; + Scene3D.REFLECTIONMODE_SKYBOX = 0; + Scene3D.REFLECTIONMODE_CUSTOM = 1; + Scene3D.SCENERENDERFLAG_RENDERQPAQUE = 0; + Scene3D.SCENERENDERFLAG_SKYBOX = 1; + Scene3D.SCENERENDERFLAG_RENDERTRANSPARENT = 2; + Scene3D.FOGCOLOR = Shader3D.propertyNameToID("u_FogColor"); + Scene3D.FOGSTART = Shader3D.propertyNameToID("u_FogStart"); + Scene3D.FOGRANGE = Shader3D.propertyNameToID("u_FogRange"); + Scene3D.DIRECTIONLIGHTCOUNT = Shader3D.propertyNameToID("u_DirationLightCount"); + Scene3D.LIGHTBUFFER = Shader3D.propertyNameToID("u_LightBuffer"); + Scene3D.CLUSTERBUFFER = Shader3D.propertyNameToID("u_LightClusterBuffer"); + Scene3D.SUNLIGHTDIRECTION = Shader3D.propertyNameToID("u_SunLight.direction"); + Scene3D.SUNLIGHTDIRCOLOR = Shader3D.propertyNameToID("u_SunLight.color"); + Scene3D.AMBIENTSHAR = Shader3D.propertyNameToID("u_AmbientSHAr"); + Scene3D.AMBIENTSHAG = Shader3D.propertyNameToID("u_AmbientSHAg"); + Scene3D.AMBIENTSHAB = Shader3D.propertyNameToID("u_AmbientSHAb"); + Scene3D.AMBIENTSHBR = Shader3D.propertyNameToID("u_AmbientSHBr"); + Scene3D.AMBIENTSHBG = Shader3D.propertyNameToID("u_AmbientSHBg"); + Scene3D.AMBIENTSHBB = Shader3D.propertyNameToID("u_AmbientSHBb"); + Scene3D.AMBIENTSHC = Shader3D.propertyNameToID("u_AmbientSHC"); + Scene3D.LIGHTDIRECTION = Shader3D.propertyNameToID("u_DirectionLight.direction"); + Scene3D.LIGHTDIRCOLOR = Shader3D.propertyNameToID("u_DirectionLight.color"); + Scene3D.POINTLIGHTPOS = Shader3D.propertyNameToID("u_PointLight.position"); + Scene3D.POINTLIGHTRANGE = Shader3D.propertyNameToID("u_PointLight.range"); + Scene3D.POINTLIGHTATTENUATION = Shader3D.propertyNameToID("u_PointLight.attenuation"); + Scene3D.POINTLIGHTCOLOR = Shader3D.propertyNameToID("u_PointLight.color"); + Scene3D.SPOTLIGHTPOS = Shader3D.propertyNameToID("u_SpotLight.position"); + Scene3D.SPOTLIGHTDIRECTION = Shader3D.propertyNameToID("u_SpotLight.direction"); + Scene3D.SPOTLIGHTSPOTANGLE = Shader3D.propertyNameToID("u_SpotLight.spot"); + Scene3D.SPOTLIGHTRANGE = Shader3D.propertyNameToID("u_SpotLight.range"); + Scene3D.SPOTLIGHTCOLOR = Shader3D.propertyNameToID("u_SpotLight.color"); + Scene3D.AMBIENTCOLOR = Shader3D.propertyNameToID("u_AmbientColor"); + Scene3D.TIME = Shader3D.propertyNameToID("u_Time"); + Scene3D._configDefineValues = new DefineDatas(); + + class ShaderPass extends Laya.ShaderCompile { + constructor(owner, vs, ps, stateMap) { + super(vs, ps, null); + this._cacheSharders = {}; + this._cacheShaderHierarchy = 1; + this._renderState = new RenderState(); + this._validDefine = new DefineDatas(); + this._tags = {}; + this._owner = owner; + this._stateMap = stateMap; + for (var k in this.defs) + this._validDefine.add(Shader3D.getDefineByName(k)); + } + get renderState() { + return this._renderState; + } + _compileToTree(parent, lines, start, includefiles, defs) { + var node, preNode; + var text, name, fname; + var ofs, words, noUseNode; + var i, n, j; + for (i = start; i < lines.length; i++) { + text = lines[i]; + if (text.length < 1) + continue; + ofs = text.indexOf("//"); + if (ofs === 0) + continue; + if (ofs >= 0) + text = text.substr(0, ofs); + node = noUseNode || new Laya.ShaderNode(includefiles); + noUseNode = null; + node.text = text; + node.noCompile = true; + if ((ofs = text.indexOf("#")) >= 0) { + name = "#"; + for (j = ofs + 1, n = text.length; j < n; j++) { + var c = text.charAt(j); + if (c === ' ' || c === '\t' || c === '?') + break; + name += c; + } + node.name = name; + switch (name) { + case "#ifdef": + case "#ifndef": + node.src = text; + node.noCompile = text.match(/[!&|()=<>]/) != null; + if (!node.noCompile) { + words = text.replace(/^\s*/, '').split(/\s+/); + node.setCondition(words[1], name === "#ifdef" ? Laya.ShaderCompile.IFDEF_YES : Laya.ShaderCompile.IFDEF_ELSE); + node.text = "//" + node.text; + } + else { + console.log("function():Boolean{return " + text.substr(ofs + node.name.length) + "}"); + } + node.setParent(parent); + parent = node; + if (defs) { + words = text.substr(j).split(Laya.ShaderCompile._splitToWordExps3); + for (j = 0; j < words.length; j++) { + text = words[j]; + text.length && (defs[text] = true); + } + } + continue; + case "#if": + case "#elif": + node.src = text; + node.noCompile = true; + if (name == "#elif") { + parent = parent.parent; + preNode = parent.childs[parent.childs.length - 1]; + preNode.text = preNode.src; + preNode.noCompile = true; + preNode.condition = null; + } + node.setParent(parent); + parent = node; + if (defs) { + words = text.substr(j).split(Laya.ShaderCompile._splitToWordExps3); + for (j = 0; j < words.length; j++) { + text = words[j]; + text.length && text != "defined" && (defs[text] = true); + } + } + continue; + case "#else": + node.src = text; + parent = parent.parent; + preNode = parent.childs[parent.childs.length - 1]; + node.noCompile = preNode.noCompile; + if (!node.noCompile) { + node.condition = preNode.condition; + node.conditionType = preNode.conditionType == Laya.ShaderCompile.IFDEF_YES ? Laya.ShaderCompile.IFDEF_ELSE : Laya.ShaderCompile.IFDEF_YES; + node.text = "//" + node.text + " " + preNode.text + " " + node.conditionType; + } + node.setParent(parent); + parent = node; + continue; + case "#endif": + parent = parent.parent; + preNode = parent.childs[parent.childs.length - 1]; + node.noCompile = preNode.noCompile; + if (!node.noCompile) { + node.text = "//" + node.text; + } + node.setParent(parent); + continue; + case "#include": + words = Laya.ShaderCompile.splitToWords(text, null); + var inlcudeFile = Laya.ShaderCompile.includes[words[1]]; + if (!inlcudeFile) { + throw "ShaderCompile error no this include file:" + words[1]; + } + if ((ofs = words[0].indexOf("?")) < 0) { + node.setParent(parent); + text = inlcudeFile.getWith(words[2] == 'with' ? words[3] : null); + this._compileToTree(node, text.split('\n'), 0, includefiles, defs); + node.text = ""; + continue; + } + node.setCondition(words[0].substr(ofs + 1), Laya.ShaderCompile.IFDEF_YES); + node.text = inlcudeFile.getWith(words[2] == 'with' ? words[3] : null); + break; + case "#import": + words = Laya.ShaderCompile.splitToWords(text, null); + fname = words[1]; + includefiles.push({ node: node, file: Laya.ShaderCompile.includes[fname], ofs: node.text.length }); + continue; + } + } + else { + preNode = parent.childs[parent.childs.length - 1]; + if (preNode && !preNode.name) { + includefiles.length > 0 && Laya.ShaderCompile.splitToWords(text, preNode); + noUseNode = node; + preNode.text += "\n" + text; + continue; + } + includefiles.length > 0 && Laya.ShaderCompile.splitToWords(text, node); + } + node.setParent(parent); + } + } + _resizeCacheShaderMap(cacheMap, hierarchy, resizeLength) { + var end = this._cacheShaderHierarchy - 1; + if (hierarchy == end) { + for (var k in cacheMap) { + var shader = cacheMap[k]; + for (var i = 0, n = resizeLength - end; i < n; i++) { + if (i == n - 1) + cacheMap[0] = shader; + else + cacheMap = cacheMap[i == 0 ? k : 0] = {}; + } + } + } + else { + ++hierarchy; + for (var k in cacheMap) + this._resizeCacheShaderMap(cacheMap[k], hierarchy, resizeLength); + } + } + _addDebugShaderVariantCollection(compileDefine, outDebugDefines, outDebugDefineMask) { + var dbugShaderVariantInfo = Shader3D._debugShaderVariantInfo; + var debugSubShader = this._owner; + var debugShader = debugSubShader._owner; + var mask = compileDefine._mask; + Shader3D._getNamesByDefineData(compileDefine, outDebugDefines); + outDebugDefineMask.length = mask.length; + for (var i = 0, n = mask.length; i < n; i++) + outDebugDefineMask[i] = mask[i]; + if (dbugShaderVariantInfo) + dbugShaderVariantInfo.setValue(debugShader, debugShader._subShaders.indexOf(debugSubShader), debugSubShader._passes.indexOf(this), outDebugDefines); + else + Shader3D._debugShaderVariantInfo = dbugShaderVariantInfo = new ShaderVariant(debugShader, debugShader._subShaders.indexOf(debugSubShader), debugSubShader._passes.indexOf(this), outDebugDefines); + Shader3D.debugShaderVariantCollection.add(dbugShaderVariantInfo); + } + withCompile(compileDefine) { + var debugDefineString = ShaderPass._debugDefineString; + var debugDefineMask = ShaderPass._debugDefineMask; + var debugMaskLength; + compileDefine._intersectionDefineDatas(this._validDefine); + if (Shader3D.debugMode) { + debugMaskLength = compileDefine._length; + this._addDebugShaderVariantCollection(compileDefine, debugDefineString, debugDefineMask); + } + compileDefine.addDefineDatas(Scene3D._configDefineValues); + var cacheShaders = this._cacheSharders; + var maskLength = compileDefine._length; + if (maskLength > this._cacheShaderHierarchy) { + this._resizeCacheShaderMap(cacheShaders, 0, maskLength); + this._cacheShaderHierarchy = maskLength; + } + var mask = compileDefine._mask; + var endIndex = compileDefine._length - 1; + var maxEndIndex = this._cacheShaderHierarchy - 1; + for (var i = 0; i < maxEndIndex; i++) { + var subMask = endIndex < i ? 0 : mask[i]; + var subCacheShaders = cacheShaders[subMask]; + (subCacheShaders) || (cacheShaders[subMask] = subCacheShaders = {}); + cacheShaders = subCacheShaders; + } + var cacheKey = endIndex < maxEndIndex ? 0 : mask[maxEndIndex]; + var shader = cacheShaders[cacheKey]; + if (shader) + return shader; + var defineString = ShaderPass._defineString; + Shader3D._getNamesByDefineData(compileDefine, defineString); + var config = Config3D._config; + var clusterSlices = config.lightClusterCount; + var defMap = {}; + var vertexHead; + var fragmentHead; + var defineStr = ""; + if (Laya.WebGL._isWebGL2) { + vertexHead = + `#version 300 es\n + #define attribute in + #define varying out + #define texture2D texture\n`; + fragmentHead = + `#version 300 es\n + #define varying in + out highp vec4 pc_fragColor; + #define gl_FragColor pc_fragColor + #define gl_FragDepthEXT gl_FragDepth + #define texture2D texture + #define textureCube texture + #define texture2DProj textureProj + #define texture2DLodEXT textureLod + #define texture2DProjLodEXT textureProjLod + #define textureCubeLodEXT textureLod + #define texture2DGradEXT textureGrad + #define texture2DProjGradEXT textureProjGrad + #define textureCubeGradEXT textureGrad\n`; + } + else { + vertexHead = ""; + fragmentHead = + `#ifdef GL_EXT_shader_texture_lod + #extension GL_EXT_shader_texture_lod : enable + #endif + #if !defined(GL_EXT_shader_texture_lod) + #define texture1DLodEXT texture1D + #define texture2DLodEXT texture2D + #define texture2DProjLodEXT texture2DProj + #define texture3DLodEXT texture3D + #define textureCubeLodEXT textureCube + #endif\n`; + } + defineStr += "#define MAX_LIGHT_COUNT " + config.maxLightCount + "\n"; + defineStr += "#define MAX_LIGHT_COUNT_PER_CLUSTER " + config._maxAreaLightCountPerClusterAverage + "\n"; + defineStr += "#define CLUSTER_X_COUNT " + clusterSlices.x + "\n"; + defineStr += "#define CLUSTER_Y_COUNT " + clusterSlices.y + "\n"; + defineStr += "#define CLUSTER_Z_COUNT " + clusterSlices.z + "\n"; + defineStr += "#define SHADER_CAPAILITY_LEVEL " + Laya.SystemUtils._shaderCapailityLevel + "\n"; + for (var i = 0, n = defineString.length; i < n; i++) { + var def = defineString[i]; + defineStr += "#define " + def + "\n"; + defMap[def] = true; + } + var vs = this._VS.toscript(defMap, []); + var vsVersion = ''; + if (vs[0].indexOf('#version') == 0) { + vsVersion = vs[0] + '\n'; + vs.shift(); + } + var ps = this._PS.toscript(defMap, []); + var psVersion = ''; + if (ps[0].indexOf('#version') == 0) { + psVersion = ps[0] + '\n'; + ps.shift(); + } + shader = new ShaderInstance(vsVersion + vertexHead + defineStr + vs.join('\n'), psVersion + fragmentHead + defineStr + ps.join('\n'), this._owner._attributeMap, this._owner._uniformMap || this._owner._owner._uniformMap, this); + cacheShaders[cacheKey] = shader; + if (Shader3D.debugMode) { + var defStr = ""; + var defMask = ""; + for (var i = 0, n = debugMaskLength; i < n; i++) + (i == n - 1) ? defMask += debugDefineMask[i] : defMask += debugDefineMask[i] + ","; + for (var i = 0, n = debugDefineString.length; i < n; i++) + (i == n - 1) ? defStr += debugDefineString[i] : defStr += debugDefineString[i] + ","; + console.log("%cLayaAir: Shader Compile Information---ShaderName:" + this._owner._owner._name + " SubShaderIndex:" + this._owner._owner._subShaders.indexOf(this._owner) + " PassIndex:" + this._owner._passes.indexOf(this) + " DefineMask:[" + defMask + "]" + " DefineNames:[" + defStr + "]", "color:green"); + } + return shader; + } + setTag(key, value) { + if (value) + this._tags[key] = value; + else + delete this._tags[key]; + } + getTag(key) { + return this._tags[key]; + } + } + ShaderPass._defineString = []; + ShaderPass._debugDefineString = []; + ShaderPass._debugDefineMask = []; + + class SubShader { + constructor(attributeMap, uniformMap) { + this._flags = {}; + this._passes = []; + this._attributeMap = attributeMap; + this._uniformMap = uniformMap; + } + setFlag(key, value) { + if (value) + this._flags[key] = value; + else + delete this._flags[key]; + } + getFlag(key) { + return this._flags[key]; + } + addShaderPass(vs, ps, stateMap = null, pipelineMode = "Forward") { + var shaderPass = new ShaderPass(this, vs, ps, stateMap); + shaderPass._pipelineMode = pipelineMode; + this._passes.push(shaderPass); + return shaderPass; + } + } + + (function (PBRSpecularSmoothnessSource) { + PBRSpecularSmoothnessSource[PBRSpecularSmoothnessSource["SpecularTextureAlpha"] = 0] = "SpecularTextureAlpha"; + PBRSpecularSmoothnessSource[PBRSpecularSmoothnessSource["AlbedoTextureAlpha"] = 1] = "AlbedoTextureAlpha"; + })(exports.PBRSpecularSmoothnessSource || (exports.PBRSpecularSmoothnessSource = {})); + class PBRSpecularMaterial extends PBRMaterial { + constructor() { + super(); + this.setShaderName("PBRSpecular"); + this._shaderValues.setVector(PBRSpecularMaterial.SPECULARCOLOR, new Vector4(0.2, 0.2, 0.2, 1.0)); + } + static __init__() { + PBRSpecularMaterial.SHADERDEFINE_SPECULARGLOSSTEXTURE = Shader3D.getDefineByName("SPECULARGLOSSTEXTURE"); + PBRSpecularMaterial.SHADERDEFINE_SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA = Shader3D.getDefineByName("SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA"); + var attributeMap = { + 'a_Position': VertexMesh.MESH_POSITION0, + 'a_Normal': VertexMesh.MESH_NORMAL0, + 'a_Tangent0': VertexMesh.MESH_TANGENT0, + 'a_Texcoord0': VertexMesh.MESH_TEXTURECOORDINATE0, + 'a_Texcoord1': VertexMesh.MESH_TEXTURECOORDINATE1, + 'a_BoneWeights': VertexMesh.MESH_BLENDWEIGHT0, + 'a_BoneIndices': VertexMesh.MESH_BLENDINDICES0, + 'a_WorldMat': VertexMesh.MESH_WORLDMATRIX_ROW0, + 'a_SimpleTextureParams': VertexMesh.MESH_SIMPLEANIMATOR + }; + var uniformMap = { + 'u_Bones': Shader3D.PERIOD_CUSTOM, + 'u_MvpMatrix': Shader3D.PERIOD_SPRITE, + 'u_WorldMat': Shader3D.PERIOD_SPRITE, + 'u_LightmapScaleOffset': Shader3D.PERIOD_SPRITE, + 'u_LightMap': Shader3D.PERIOD_SPRITE, + 'u_LightMapDirection': Shader3D.PERIOD_SPRITE, + 'u_SimpleAnimatorTexture': Shader3D.PERIOD_SPRITE, + 'u_SimpleAnimatorParams': Shader3D.PERIOD_SPRITE, + 'u_SimpleAnimatorTextureSize': Shader3D.PERIOD_SPRITE, + 'u_ReflectCubeHDRParams': Shader3D.PERIOD_SPRITE, + 'u_ReflectTexture': Shader3D.PERIOD_SPRITE, + 'u_SpecCubeProbePosition': Shader3D.PERIOD_SPRITE, + 'u_SpecCubeBoxMax': Shader3D.PERIOD_SPRITE, + 'u_SpecCubeBoxMin': Shader3D.PERIOD_SPRITE, + 'u_CameraPos': Shader3D.PERIOD_CAMERA, + 'u_View': Shader3D.PERIOD_CAMERA, + 'u_ProjectionParams': Shader3D.PERIOD_CAMERA, + 'u_Viewport': Shader3D.PERIOD_CAMERA, + 'u_ViewProjection': Shader3D.PERIOD_CAMERA, + 'u_AlphaTestValue': Shader3D.PERIOD_MATERIAL, + 'u_AlbedoColor': Shader3D.PERIOD_MATERIAL, + 'u_EmissionColor': Shader3D.PERIOD_MATERIAL, + 'u_AlbedoTexture': Shader3D.PERIOD_MATERIAL, + 'u_NormalTexture': Shader3D.PERIOD_MATERIAL, + 'u_ParallaxTexture': Shader3D.PERIOD_MATERIAL, + 'u_OcclusionTexture': Shader3D.PERIOD_MATERIAL, + 'u_EmissionTexture': Shader3D.PERIOD_MATERIAL, + 'u_Smoothness': Shader3D.PERIOD_MATERIAL, + 'u_SmoothnessScale': Shader3D.PERIOD_MATERIAL, + 'u_occlusionStrength': Shader3D.PERIOD_MATERIAL, + 'u_NormalScale': Shader3D.PERIOD_MATERIAL, + 'u_ParallaxScale': Shader3D.PERIOD_MATERIAL, + 'u_TilingOffset': Shader3D.PERIOD_MATERIAL, + 'u_SpecGlossTexture': Shader3D.PERIOD_MATERIAL, + 'u_SpecularColor': Shader3D.PERIOD_MATERIAL, + 'u_AmbientColor': Shader3D.PERIOD_SCENE, + 'u_FogStart': Shader3D.PERIOD_SCENE, + 'u_FogRange': Shader3D.PERIOD_SCENE, + 'u_FogColor': Shader3D.PERIOD_SCENE, + 'u_DirationLightCount': Shader3D.PERIOD_SCENE, + 'u_LightBuffer': Shader3D.PERIOD_SCENE, + 'u_LightClusterBuffer': Shader3D.PERIOD_SCENE, + 'u_ShadowBias': Shader3D.PERIOD_SCENE, + 'u_ShadowLightDirection': Shader3D.PERIOD_SCENE, + 'u_ShadowMap': Shader3D.PERIOD_SCENE, + 'u_ShadowParams': Shader3D.PERIOD_SCENE, + 'u_ShadowSplitSpheres': Shader3D.PERIOD_SCENE, + 'u_ShadowMatrices': Shader3D.PERIOD_SCENE, + 'u_ShadowMapSize': Shader3D.PERIOD_SCENE, + 'u_SpotShadowMap': Shader3D.PERIOD_SCENE, + 'u_SpotViewProjectMatrix': Shader3D.PERIOD_SCENE, + 'u_ShadowLightPosition': Shader3D.PERIOD_SCENE, + 'u_AmbientSHAr': Shader3D.PERIOD_SCENE, + 'u_AmbientSHAg': Shader3D.PERIOD_SCENE, + 'u_AmbientSHAb': Shader3D.PERIOD_SCENE, + 'u_AmbientSHBr': Shader3D.PERIOD_SCENE, + 'u_AmbientSHBg': Shader3D.PERIOD_SCENE, + 'u_AmbientSHBb': Shader3D.PERIOD_SCENE, + 'u_AmbientSHC': Shader3D.PERIOD_SCENE, + 'u_DirectionLight.direction': Shader3D.PERIOD_SCENE, + 'u_DirectionLight.color': Shader3D.PERIOD_SCENE, + 'u_PointLight.position': Shader3D.PERIOD_SCENE, + 'u_PointLight.range': Shader3D.PERIOD_SCENE, + 'u_PointLight.color': Shader3D.PERIOD_SCENE, + 'u_SpotLight.position': Shader3D.PERIOD_SCENE, + 'u_SpotLight.direction': Shader3D.PERIOD_SCENE, + 'u_SpotLight.range': Shader3D.PERIOD_SCENE, + 'u_SpotLight.spot': Shader3D.PERIOD_SCENE, + 'u_SpotLight.color': Shader3D.PERIOD_SCENE + }; + var stateMap = { + 's_Cull': Shader3D.RENDER_STATE_CULL, + 's_Blend': Shader3D.RENDER_STATE_BLEND, + 's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC, + 's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST, + 's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST, + 's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE + }; + var shader = Shader3D.add("PBRSpecular", attributeMap, uniformMap, true, true); + var subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + subShader.addShaderPass(PBRVS, PBRPS, stateMap, "Forward"); + subShader.addShaderPass(PBRShadowCasterVS, PBRShadowCasterPS, stateMap, "ShadowCaster"); + subShader.addShaderPass(DepthNormalsTextureVS, DepthNormalsTextureFS, stateMap, "DepthNormal"); + } + get specularTexture() { + return this._shaderValues.getTexture(PBRSpecularMaterial.SPECULARTEXTURE); + } + set specularTexture(value) { + if (value) + this._shaderValues.addDefine(PBRSpecularMaterial.SHADERDEFINE_SPECULARGLOSSTEXTURE); + else + this._shaderValues.removeDefine(PBRSpecularMaterial.SHADERDEFINE_SPECULARGLOSSTEXTURE); + this._shaderValues.setTexture(PBRSpecularMaterial.SPECULARTEXTURE, value); + } + get specularColor() { + return this._shaderValues.getVector(PBRSpecularMaterial.SPECULARCOLOR); + } + set specularColor(value) { + this._shaderValues.setVector(PBRSpecularMaterial.SPECULARCOLOR, value); + } + clone() { + var dest = new PBRSpecularMaterial(); + this.cloneTo(dest); + return dest; + } + } + PBRSpecularMaterial.SPECULARTEXTURE = Shader3D.propertyNameToID("u_SpecGlossTexture"); + PBRSpecularMaterial.SPECULARCOLOR = Shader3D.propertyNameToID("u_SpecularColor"); + + var PBRPS$1 = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n\r\n#include \"Lighting.glsl\";\r\n#include \"Shadow.glsl\"\r\n#include \"PBRFSInput.glsl\";\r\n#include \"LayaPBRBRDF.glsl\";\r\n#include \"GlobalIllumination.glsl\";\r\n#include \"PBRCore.glsl\";\r\n\r\nvoid main()\r\n{\r\n\tfragmentForward();\r\n}"; + + var PBRVS$1 = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n#include \"Lighting.glsl\";\r\n#include \"LayaUtile.glsl\"\r\n#include \"Shadow.glsl\"\r\n#include \"PBRVSInput.glsl\";\r\n#include \"PBRVertex.glsl\";\r\n\r\nvoid main()\r\n{\r\n\tvertexForward();\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}"; + + var PBRShadowCasterPS$1 = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n\r\n#include \"ShadowCasterFS.glsl\"\r\n\r\nvoid main()\r\n{\r\n\tgl_FragColor=shadowCasterFragment();\r\n}"; + + var PBRShadowCasterVS$1 = "#include \"ShadowCasterVS.glsl\"\r\n\r\nvoid main()\r\n{\r\n\tvec4 positionCS = shadowCasterVertex();\r\n\tgl_Position=remapGLPositionZ(positionCS);\r\n}"; + + (function (PBRMetallicSmoothnessSource) { + PBRMetallicSmoothnessSource[PBRMetallicSmoothnessSource["MetallicGlossTextureAlpha"] = 0] = "MetallicGlossTextureAlpha"; + PBRMetallicSmoothnessSource[PBRMetallicSmoothnessSource["AlbedoTextureAlpha"] = 1] = "AlbedoTextureAlpha"; + })(exports.PBRMetallicSmoothnessSource || (exports.PBRMetallicSmoothnessSource = {})); + class PBRStandardMaterial extends PBRMaterial { + constructor() { + super(); + this._smoothnessSource = 0; + this.setShaderName("PBR"); + this._shaderValues.setNumber(PBRStandardMaterial.METALLIC, 0.0); + } + static __init__() { + PBRStandardMaterial.SHADERDEFINE_METALLICGLOSSTEXTURE = Shader3D.getDefineByName("METALLICGLOSSTEXTURE"); + PBRStandardMaterial.SHADERDEFINE_SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA = Shader3D.getDefineByName("SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA"); + var attributeMap = { + 'a_Position': VertexMesh.MESH_POSITION0, + 'a_Normal': VertexMesh.MESH_NORMAL0, + 'a_Tangent0': VertexMesh.MESH_TANGENT0, + 'a_Texcoord0': VertexMesh.MESH_TEXTURECOORDINATE0, + 'a_Texcoord1': VertexMesh.MESH_TEXTURECOORDINATE1, + 'a_BoneWeights': VertexMesh.MESH_BLENDWEIGHT0, + 'a_BoneIndices': VertexMesh.MESH_BLENDINDICES0, + 'a_WorldMat': VertexMesh.MESH_WORLDMATRIX_ROW0, + 'a_SimpleTextureParams': VertexMesh.MESH_SIMPLEANIMATOR + }; + var uniformMap = { + 'u_Bones': Shader3D.PERIOD_CUSTOM, + 'u_MvpMatrix': Shader3D.PERIOD_SPRITE, + 'u_WorldMat': Shader3D.PERIOD_SPRITE, + 'u_LightmapScaleOffset': Shader3D.PERIOD_SPRITE, + 'u_LightMap': Shader3D.PERIOD_SPRITE, + 'u_LightMapDirection': Shader3D.PERIOD_SPRITE, + 'u_SimpleAnimatorTexture': Shader3D.PERIOD_SPRITE, + 'u_SimpleAnimatorParams': Shader3D.PERIOD_SPRITE, + 'u_SimpleAnimatorTextureSize': Shader3D.PERIOD_SPRITE, + 'u_ReflectCubeHDRParams': Shader3D.PERIOD_SPRITE, + 'u_ReflectTexture': Shader3D.PERIOD_SPRITE, + 'u_SpecCubeProbePosition': Shader3D.PERIOD_SPRITE, + 'u_SpecCubeBoxMax': Shader3D.PERIOD_SPRITE, + 'u_SpecCubeBoxMin': Shader3D.PERIOD_SPRITE, + 'u_CameraPos': Shader3D.PERIOD_CAMERA, + 'u_View': Shader3D.PERIOD_CAMERA, + 'u_ProjectionParams': Shader3D.PERIOD_CAMERA, + 'u_Viewport': Shader3D.PERIOD_CAMERA, + 'u_ViewProjection': Shader3D.PERIOD_CAMERA, + 'u_AlphaTestValue': Shader3D.PERIOD_MATERIAL, + 'u_AlbedoColor': Shader3D.PERIOD_MATERIAL, + 'u_EmissionColor': Shader3D.PERIOD_MATERIAL, + 'u_AlbedoTexture': Shader3D.PERIOD_MATERIAL, + 'u_NormalTexture': Shader3D.PERIOD_MATERIAL, + 'u_ParallaxTexture': Shader3D.PERIOD_MATERIAL, + 'u_OcclusionTexture': Shader3D.PERIOD_MATERIAL, + 'u_EmissionTexture': Shader3D.PERIOD_MATERIAL, + 'u_Smoothness': Shader3D.PERIOD_MATERIAL, + 'u_SmoothnessScale': Shader3D.PERIOD_MATERIAL, + 'u_occlusionStrength': Shader3D.PERIOD_MATERIAL, + 'u_NormalScale': Shader3D.PERIOD_MATERIAL, + 'u_ParallaxScale': Shader3D.PERIOD_MATERIAL, + 'u_TilingOffset': Shader3D.PERIOD_MATERIAL, + 'u_MetallicGlossTexture': Shader3D.PERIOD_MATERIAL, + 'u_Metallic': Shader3D.PERIOD_MATERIAL, + 'u_AmbientColor': Shader3D.PERIOD_SCENE, + 'u_FogStart': Shader3D.PERIOD_SCENE, + 'u_FogRange': Shader3D.PERIOD_SCENE, + 'u_FogColor': Shader3D.PERIOD_SCENE, + 'u_DirationLightCount': Shader3D.PERIOD_SCENE, + 'u_LightBuffer': Shader3D.PERIOD_SCENE, + 'u_LightClusterBuffer': Shader3D.PERIOD_SCENE, + 'u_ShadowBias': Shader3D.PERIOD_SCENE, + 'u_ShadowLightDirection': Shader3D.PERIOD_SCENE, + 'u_ShadowMap': Shader3D.PERIOD_SCENE, + 'u_ShadowParams': Shader3D.PERIOD_SCENE, + 'u_ShadowSplitSpheres': Shader3D.PERIOD_SCENE, + 'u_ShadowMatrices': Shader3D.PERIOD_SCENE, + 'u_ShadowMapSize': Shader3D.PERIOD_SCENE, + 'u_SpotShadowMap': Shader3D.PERIOD_SCENE, + 'u_SpotViewProjectMatrix': Shader3D.PERIOD_SCENE, + 'u_ShadowLightPosition': Shader3D.PERIOD_SCENE, + 'u_AmbientSHAr': Shader3D.PERIOD_SCENE, + 'u_AmbientSHAg': Shader3D.PERIOD_SCENE, + 'u_AmbientSHAb': Shader3D.PERIOD_SCENE, + 'u_AmbientSHBr': Shader3D.PERIOD_SCENE, + 'u_AmbientSHBg': Shader3D.PERIOD_SCENE, + 'u_AmbientSHBb': Shader3D.PERIOD_SCENE, + 'u_AmbientSHC': Shader3D.PERIOD_SCENE, + 'u_DirectionLight.direction': Shader3D.PERIOD_SCENE, + 'u_DirectionLight.color': Shader3D.PERIOD_SCENE, + 'u_PointLight.position': Shader3D.PERIOD_SCENE, + 'u_PointLight.range': Shader3D.PERIOD_SCENE, + 'u_PointLight.color': Shader3D.PERIOD_SCENE, + 'u_SpotLight.position': Shader3D.PERIOD_SCENE, + 'u_SpotLight.direction': Shader3D.PERIOD_SCENE, + 'u_SpotLight.range': Shader3D.PERIOD_SCENE, + 'u_SpotLight.spot': Shader3D.PERIOD_SCENE, + 'u_SpotLight.color': Shader3D.PERIOD_SCENE + }; + var stateMap = { + 's_Cull': Shader3D.RENDER_STATE_CULL, + 's_Blend': Shader3D.RENDER_STATE_BLEND, + 's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC, + 's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST, + 's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST, + 's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE + }; + var shader = Shader3D.add("PBR", attributeMap, uniformMap, true, true); + var subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + subShader.addShaderPass(PBRVS$1, PBRPS$1, stateMap, "Forward"); + subShader.addShaderPass(PBRShadowCasterVS$1, PBRShadowCasterPS$1, stateMap, "ShadowCaster"); + subShader.addShaderPass(DepthNormalsTextureVS, DepthNormalsTextureFS, stateMap, "DepthNormal"); + } + get metallicGlossTexture() { + return this._shaderValues.getTexture(PBRStandardMaterial.METALLICGLOSSTEXTURE); + } + set metallicGlossTexture(value) { + if (value) + this._shaderValues.addDefine(PBRStandardMaterial.SHADERDEFINE_METALLICGLOSSTEXTURE); + else + this._shaderValues.removeDefine(PBRStandardMaterial.SHADERDEFINE_METALLICGLOSSTEXTURE); + this._shaderValues.setTexture(PBRStandardMaterial.METALLICGLOSSTEXTURE, value); + } + get metallic() { + return this._shaderValues.getNumber(PBRStandardMaterial.METALLIC); + } + set metallic(value) { + this._shaderValues.setNumber(PBRStandardMaterial.METALLIC, Math.max(0.0, Math.min(1.0, value))); + } + get smoothnessSource() { + return this._smoothnessSource; + } + set smoothnessSource(value) { + if (value) + this._shaderValues.addDefine(PBRStandardMaterial.SHADERDEFINE_SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA); + else + this._shaderValues.removeDefine(PBRStandardMaterial.SHADERDEFINE_SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA); + this._smoothnessSource = value; + } + clone() { + var dest = new PBRStandardMaterial(); + this.cloneTo(dest); + return dest; + } + } + PBRStandardMaterial.METALLICGLOSSTEXTURE = Shader3D.propertyNameToID("u_MetallicGlossTexture"); + PBRStandardMaterial.METALLIC = Shader3D.propertyNameToID("u_Metallic"); + + class SkyBoxMaterial extends Material { + constructor() { + super(); + this.setShaderName("SkyBox"); + this.tintColor = new Vector4(0.5, 0.5, 0.5, 0.5); + this.exposure = 1.0; + this.rotation = 0; + } + static __initDefine__() { + } + get tintColor() { + return this._shaderValues.getVector(SkyBoxMaterial.TINTCOLOR); + } + set tintColor(value) { + this._shaderValues.setVector(SkyBoxMaterial.TINTCOLOR, value); + } + get exposure() { + return this._shaderValues.getNumber(SkyBoxMaterial.EXPOSURE); + } + set exposure(value) { + this._shaderValues.setNumber(SkyBoxMaterial.EXPOSURE, value); + } + get rotation() { + return this._shaderValues.getNumber(SkyBoxMaterial.ROTATION); + } + set rotation(value) { + this._shaderValues.setNumber(SkyBoxMaterial.ROTATION, value); + } + get textureCube() { + return this._shaderValues.getTexture(SkyBoxMaterial.TEXTURECUBE); + } + set textureCube(value) { + this._shaderValues.setTexture(SkyBoxMaterial.TEXTURECUBE, value); + } + clone() { + var dest = new SkyBoxMaterial(); + this.cloneTo(dest); + return dest; + } + } + SkyBoxMaterial.TINTCOLOR = Shader3D.propertyNameToID("u_TintColor"); + SkyBoxMaterial.EXPOSURE = Shader3D.propertyNameToID("u_Exposure"); + SkyBoxMaterial.ROTATION = Shader3D.propertyNameToID("u_Rotation"); + SkyBoxMaterial.TEXTURECUBE = Shader3D.propertyNameToID("u_CubeTexture"); + + class SkyProceduralMaterial extends Material { + constructor() { + super(); + this.setShaderName("SkyBoxProcedural"); + this.sunDisk = SkyProceduralMaterial.SUN_HIGH_QUALITY; + this.sunSize = 0.04; + this.sunSizeConvergence = 5; + this.atmosphereThickness = 1.0; + this.skyTint = new Vector4(0.5, 0.5, 0.5, 1.0); + this.groundTint = new Vector4(0.369, 0.349, 0.341, 1.0); + this.exposure = 1.3; + } + static __initDefine__() { + SkyProceduralMaterial.SHADERDEFINE_SUN_HIGH_QUALITY = Shader3D.getDefineByName("SUN_HIGH_QUALITY"); + SkyProceduralMaterial.SHADERDEFINE_SUN_SIMPLE = Shader3D.getDefineByName("SUN_SIMPLE"); + } + get sunDisk() { + return this._sunDisk; + } + set sunDisk(value) { + switch (value) { + case SkyProceduralMaterial.SUN_HIGH_QUALITY: + this._shaderValues.removeDefine(SkyProceduralMaterial.SHADERDEFINE_SUN_SIMPLE); + this._shaderValues.addDefine(SkyProceduralMaterial.SHADERDEFINE_SUN_HIGH_QUALITY); + break; + case SkyProceduralMaterial.SUN_SIMPLE: + this._shaderValues.removeDefine(SkyProceduralMaterial.SHADERDEFINE_SUN_HIGH_QUALITY); + this._shaderValues.addDefine(SkyProceduralMaterial.SHADERDEFINE_SUN_SIMPLE); + break; + case SkyProceduralMaterial.SUN_NODE: + this._shaderValues.removeDefine(SkyProceduralMaterial.SHADERDEFINE_SUN_HIGH_QUALITY); + this._shaderValues.removeDefine(SkyProceduralMaterial.SHADERDEFINE_SUN_SIMPLE); + break; + default: + throw "SkyBoxProceduralMaterial: unknown sun value."; + } + this._sunDisk = value; + } + get sunSize() { + return this._shaderValues.getNumber(SkyProceduralMaterial.SUNSIZE); + } + set sunSize(value) { + value = Math.min(Math.max(0.0, value), 1.0); + this._shaderValues.setNumber(SkyProceduralMaterial.SUNSIZE, value); + } + get sunSizeConvergence() { + return this._shaderValues.getNumber(SkyProceduralMaterial.SUNSIZECONVERGENCE); + } + set sunSizeConvergence(value) { + value = Math.min(Math.max(0.0, value), 20.0); + this._shaderValues.setNumber(SkyProceduralMaterial.SUNSIZECONVERGENCE, value); + } + get atmosphereThickness() { + return this._shaderValues.getNumber(SkyProceduralMaterial.ATMOSPHERETHICKNESS); + } + set atmosphereThickness(value) { + value = Math.min(Math.max(0.0, value), 5.0); + this._shaderValues.setNumber(SkyProceduralMaterial.ATMOSPHERETHICKNESS, value); + } + get skyTint() { + return this._shaderValues.getVector(SkyProceduralMaterial.SKYTINT); + } + set skyTint(value) { + this._shaderValues.setVector(SkyProceduralMaterial.SKYTINT, value); + } + get groundTint() { + return this._shaderValues.getVector(SkyProceduralMaterial.GROUNDTINT); + } + set groundTint(value) { + this._shaderValues.setVector(SkyProceduralMaterial.GROUNDTINT, value); + } + get exposure() { + return this._shaderValues.getNumber(SkyProceduralMaterial.EXPOSURE); + } + set exposure(value) { + value = Math.min(Math.max(0.0, value), 8.0); + this._shaderValues.setNumber(SkyProceduralMaterial.EXPOSURE, value); + } + clone() { + var dest = new SkyProceduralMaterial(); + this.cloneTo(dest); + return dest; + } + } + SkyProceduralMaterial.SUN_NODE = 0; + SkyProceduralMaterial.SUN_SIMPLE = 1; + SkyProceduralMaterial.SUN_HIGH_QUALITY = 2; + SkyProceduralMaterial.SUNSIZE = Shader3D.propertyNameToID("u_SunSize"); + SkyProceduralMaterial.SUNSIZECONVERGENCE = Shader3D.propertyNameToID("u_SunSizeConvergence"); + SkyProceduralMaterial.ATMOSPHERETHICKNESS = Shader3D.propertyNameToID("u_AtmosphereThickness"); + SkyProceduralMaterial.SKYTINT = Shader3D.propertyNameToID("u_SkyTint"); + SkyProceduralMaterial.GROUNDTINT = Shader3D.propertyNameToID("u_GroundTint"); + SkyProceduralMaterial.EXPOSURE = Shader3D.propertyNameToID("u_Exposure"); + + class UnlitMaterial extends Material { + constructor() { + super(); + this.setShaderName("Unlit"); + this._shaderValues.setVector(UnlitMaterial.ALBEDOCOLOR, new Vector4(1.0, 1.0, 1.0, 1.0)); + this._shaderValues.setVector(UnlitMaterial.TILINGOFFSET, new Vector4(1.0, 1.0, 0.0, 0.0)); + this.renderMode = UnlitMaterial.RENDERMODE_OPAQUE; + this.albedoIntensity = 1.0; + } + static __initDefine__() { + UnlitMaterial.SHADERDEFINE_ALBEDOTEXTURE = Shader3D.getDefineByName("ALBEDOTEXTURE"); + UnlitMaterial.SHADERDEFINE_ENABLEVERTEXCOLOR = Shader3D.getDefineByName("ENABLEVERTEXCOLOR"); + } + get _ColorR() { + return this.albedoColor.x; + } + set _ColorR(value) { + let albedo = this.albedoColor; + albedo.x = value; + this.albedoColor = albedo; + } + get _ColorG() { + return this.albedoColor.y; + } + set _ColorG(value) { + let albedo = this.albedoColor; + albedo.y = value; + this.albedoColor = albedo; + } + get _ColorB() { + return this.albedoColor.z; + } + set _ColorB(value) { + let albedo = this.albedoColor; + albedo.z = value; + this.albedoColor = albedo; + } + get _ColorA() { + return this.albedoColor.w; + } + set _ColorA(value) { + let albedo = this.albedoColor; + albedo.w = value; + this.albedoColor = albedo; + } + get _Color() { + return this._shaderValues.getVector(UnlitMaterial.ALBEDOCOLOR); + } + set _Color(value) { + this.albedoColor = value; + } + get _AlbedoIntensity() { + return this._albedoIntensity; + } + set _AlbedoIntensity(value) { + if (this._albedoIntensity !== value) { + var finalAlbedo = this._shaderValues.getVector(UnlitMaterial.ALBEDOCOLOR); + Vector4.scale(this.albedoColor, value, finalAlbedo); + this._albedoIntensity = value; + this._shaderValues.setVector(UnlitMaterial.ALBEDOCOLOR, finalAlbedo); + } + } + get _MainTex_STX() { + return this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET).x; + } + set _MainTex_STX(x) { + var tilOff = this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET); + tilOff.x = x; + this.tilingOffset = tilOff; + } + get _MainTex_STY() { + return this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET).y; + } + set _MainTex_STY(y) { + var tilOff = this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET); + tilOff.y = y; + this.tilingOffset = tilOff; + } + get _MainTex_STZ() { + return this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET).z; + } + set _MainTex_STZ(z) { + var tilOff = this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET); + tilOff.z = z; + this.tilingOffset = tilOff; + } + get _MainTex_STW() { + return this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET).w; + } + set _MainTex_STW(w) { + var tilOff = this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET); + tilOff.w = w; + this.tilingOffset = tilOff; + } + get _MainTex_ST() { + return this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET); + } + set _MainTex_ST(value) { + this.tilingOffset = value; + } + get _Cutoff() { + return this.alphaTestValue; + } + set _Cutoff(value) { + this.alphaTestValue = value; + } + get albedoColorR() { + return this._ColorR; + } + set albedoColorR(value) { + this._ColorR = value; + } + get albedoColorG() { + return this._ColorG; + } + set albedoColorG(value) { + this._ColorG = value; + } + get albedoColorB() { + return this._ColorB; + } + set albedoColorB(value) { + this._ColorB = value; + } + get albedoColorA() { + return this._ColorA; + } + set albedoColorA(value) { + this._ColorA = value; + } + get albedoColor() { + return this._shaderValues.getVector(UnlitMaterial.ALBEDOCOLOR); + } + set albedoColor(value) { + var finalAlbedo = this._shaderValues.getVector(UnlitMaterial.ALBEDOCOLOR); + Vector4.scale(value, this._albedoIntensity, finalAlbedo); + this._shaderValues.setVector(UnlitMaterial.ALBEDOCOLOR, finalAlbedo); + } + get albedoIntensity() { + return this._albedoIntensity; + } + set albedoIntensity(value) { + this._AlbedoIntensity = value; + } + get albedoTexture() { + return this._shaderValues.getTexture(UnlitMaterial.ALBEDOTEXTURE); + } + set albedoTexture(value) { + if (value) + this._shaderValues.addDefine(UnlitMaterial.SHADERDEFINE_ALBEDOTEXTURE); + else + this._shaderValues.removeDefine(UnlitMaterial.SHADERDEFINE_ALBEDOTEXTURE); + this._shaderValues.setTexture(UnlitMaterial.ALBEDOTEXTURE, value); + } + get tilingOffsetX() { + return this._MainTex_STX; + } + set tilingOffsetX(x) { + this._MainTex_STX = x; + } + get tilingOffsetY() { + return this._MainTex_STY; + } + set tilingOffsetY(y) { + this._MainTex_STY = y; + } + get tilingOffsetZ() { + return this._MainTex_STZ; + } + set tilingOffsetZ(z) { + this._MainTex_STZ = z; + } + get tilingOffsetW() { + return this._MainTex_STW; + } + set tilingOffsetW(w) { + this._MainTex_STW = w; + } + get tilingOffset() { + return this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET); + } + set tilingOffset(value) { + if (value) { + this._shaderValues.setVector(UnlitMaterial.TILINGOFFSET, value); + } + else { + this._shaderValues.getVector(UnlitMaterial.TILINGOFFSET).setValue(1.0, 1.0, 0.0, 0.0); + } + } + get enableVertexColor() { + return this._shaderValues.hasDefine(UnlitMaterial.SHADERDEFINE_ENABLEVERTEXCOLOR); + } + set enableVertexColor(value) { + if (value) + this._shaderValues.addDefine(UnlitMaterial.SHADERDEFINE_ENABLEVERTEXCOLOR); + else + this._shaderValues.removeDefine(UnlitMaterial.SHADERDEFINE_ENABLEVERTEXCOLOR); + } + set renderMode(value) { + switch (value) { + case UnlitMaterial.RENDERMODE_OPAQUE: + this.alphaTest = false; + this.renderQueue = Material.RENDERQUEUE_OPAQUE; + this.depthWrite = true; + this.cull = RenderState.CULL_BACK; + this.blend = RenderState.BLEND_DISABLE; + this.depthTest = RenderState.DEPTHTEST_LESS; + break; + case UnlitMaterial.RENDERMODE_CUTOUT: + this.renderQueue = Material.RENDERQUEUE_ALPHATEST; + this.alphaTest = true; + this.depthWrite = true; + this.cull = RenderState.CULL_BACK; + this.blend = RenderState.BLEND_DISABLE; + this.depthTest = RenderState.DEPTHTEST_LESS; + break; + case UnlitMaterial.RENDERMODE_TRANSPARENT: + this.renderQueue = Material.RENDERQUEUE_TRANSPARENT; + this.alphaTest = false; + this.depthWrite = false; + this.cull = RenderState.CULL_BACK; + this.blend = RenderState.BLEND_ENABLE_ALL; + this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA; + this.blendDst = RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA; + this.depthTest = RenderState.DEPTHTEST_LESS; + break; + default: + throw new Error("UnlitMaterial : renderMode value error."); + } + } + clone() { + var dest = new UnlitMaterial(); + this.cloneTo(dest); + return dest; + } + } + UnlitMaterial.RENDERMODE_OPAQUE = 0; + UnlitMaterial.RENDERMODE_CUTOUT = 1; + UnlitMaterial.RENDERMODE_TRANSPARENT = 2; + UnlitMaterial.RENDERMODE_ADDTIVE = 3; + UnlitMaterial.ALBEDOTEXTURE = Shader3D.propertyNameToID("u_AlbedoTexture"); + UnlitMaterial.ALBEDOCOLOR = Shader3D.propertyNameToID("u_AlbedoColor"); + UnlitMaterial.TILINGOFFSET = Shader3D.propertyNameToID("u_TilingOffset"); + + class WaterPrimaryMaterial extends Material { + constructor() { + super(); + this.setShaderName("WaterPrimary"); + this._shaderValues.setVector(WaterPrimaryMaterial.HORIZONCOLOR, new Vector4(0.172, 0.463, 0.435, 0)); + this._shaderValues.setNumber(WaterPrimaryMaterial.WAVESCALE, 0.15); + this._shaderValues.setVector(WaterPrimaryMaterial.WAVESPEED, new Vector4(19, 9, -16, -7)); + } + static __initDefine__() { + WaterPrimaryMaterial.SHADERDEFINE_MAINTEXTURE = Shader3D.getDefineByName("MAINTEXTURE"); + WaterPrimaryMaterial.SHADERDEFINE_NORMALTEXTURE = Shader3D.getDefineByName("NORMALTEXTURE"); + } + get horizonColor() { + return this._shaderValues.getVector(WaterPrimaryMaterial.HORIZONCOLOR); + } + set horizonColor(value) { + this._shaderValues.setVector(WaterPrimaryMaterial.HORIZONCOLOR, value); + } + get mainTexture() { + return this._shaderValues.getTexture(WaterPrimaryMaterial.MAINTEXTURE); + } + set mainTexture(value) { + if (value) + this._shaderValues.addDefine(WaterPrimaryMaterial.SHADERDEFINE_MAINTEXTURE); + else + this._shaderValues.removeDefine(WaterPrimaryMaterial.SHADERDEFINE_MAINTEXTURE); + this._shaderValues.setTexture(WaterPrimaryMaterial.MAINTEXTURE, value); + } + get normalTexture() { + return this._shaderValues.getTexture(WaterPrimaryMaterial.NORMALTEXTURE); + } + set normalTexture(value) { + if (value) + this._shaderValues.addDefine(WaterPrimaryMaterial.SHADERDEFINE_NORMALTEXTURE); + else + this._shaderValues.removeDefine(WaterPrimaryMaterial.SHADERDEFINE_NORMALTEXTURE); + this._shaderValues.setTexture(WaterPrimaryMaterial.NORMALTEXTURE, value); + } + get waveScale() { + return this._shaderValues.getNumber(WaterPrimaryMaterial.WAVESCALE); + } + set waveScale(value) { + this._shaderValues.setNumber(WaterPrimaryMaterial.WAVESCALE, value); + } + get waveSpeed() { + return this._shaderValues.getVector(WaterPrimaryMaterial.WAVESPEED); + } + set waveSpeed(value) { + this._shaderValues.setVector(WaterPrimaryMaterial.WAVESPEED, value); + } + clone() { + var dest = new WaterPrimaryMaterial(); + this.cloneTo(dest); + return dest; + } + } + WaterPrimaryMaterial.HORIZONCOLOR = Shader3D.propertyNameToID("u_HorizonColor"); + WaterPrimaryMaterial.MAINTEXTURE = Shader3D.propertyNameToID("u_MainTexture"); + WaterPrimaryMaterial.NORMALTEXTURE = Shader3D.propertyNameToID("u_NormalTexture"); + WaterPrimaryMaterial.WAVESCALE = Shader3D.propertyNameToID("u_WaveScale"); + WaterPrimaryMaterial.WAVESPEED = Shader3D.propertyNameToID("u_WaveSpeed"); + + class MeshRenderer extends BaseRender { + constructor(owner) { + super(owner); + this._revertStaticBatchDefineUV1 = false; + this._projectionViewWorldMatrix = new Matrix4x4(); + } + _createRenderElement() { + return new SubMeshRenderElement(); + } + _onMeshChange(mesh) { + if (mesh) { + var count = mesh.subMeshCount; + this._renderElements.length = count; + for (var i = 0; i < count; i++) { + var renderElement = this._renderElements[i]; + if (!renderElement) { + var material = this.sharedMaterials[i]; + renderElement = this._renderElements[i] = this._createRenderElement(); + renderElement.setTransform(this._owner._transform); + renderElement.render = this; + renderElement.material = material ? material : BlinnPhongMaterial.defaultMaterial; + } + renderElement.setGeometry(mesh.getSubMesh(i)); + } + } + else { + this._renderElements.length = 0; + } + this._boundsChange = true; + } + _calculateBoundingBox() { + var sharedMesh = this._owner.meshFilter.sharedMesh; + if (sharedMesh) { + var worldMat = this._owner.transform.worldMatrix; + sharedMesh.bounds._tranform(worldMat, this._bounds); + } + } + _needRender(boundFrustum, context) { + if (boundFrustum) + return boundFrustum.intersects(this.bounds._getBoundBox()); + else + return true; + } + _renderUpdate(context, transform) { + this._applyLightMapParams(); + var element = context.renderElement; + switch (element.renderType) { + case RenderElement.RENDERTYPE_NORMAL: + this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX, transform.worldMatrix); + break; + case RenderElement.RENDERTYPE_STATICBATCH: + if (transform) + this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX, transform.worldMatrix); + else + this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX, Matrix4x4.DEFAULT); + if (!this._shaderValues.hasDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_UV1)) { + this._shaderValues.addDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_UV1); + this._revertStaticBatchDefineUV1 = true; + } + else { + this._revertStaticBatchDefineUV1 = false; + } + this._shaderValues.setVector(RenderableSprite3D.LIGHTMAPSCALEOFFSET, BaseRender._defaultLightmapScaleOffset); + break; + case RenderElement.RENDERTYPE_VERTEXBATCH: + this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX, Matrix4x4.DEFAULT); + break; + case RenderElement.RENDERTYPE_INSTANCEBATCH: + var worldMatrixData = SubMeshInstanceBatch.instance.instanceWorldMatrixData; + var insBatches = element.instanceBatchElementList; + var elements = insBatches.elements; + var count = insBatches.length; + for (var i = 0; i < count; i++) + worldMatrixData.set(elements[i]._transform.worldMatrix.elements, i * 16); + var worldBuffer = SubMeshInstanceBatch.instance.instanceWorldMatrixBuffer; + worldBuffer.orphanStorage(); + worldBuffer.setData(worldMatrixData.buffer, 0, 0, count * 16 * 4); + this._shaderValues.addDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_GPU_INSTANCE); + break; + } + if (!this._probReflection) + return; + if (this._reflectionMode == exports.ReflectionProbeMode.off) { + this._shaderValues.removeDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_SPECCUBE_BOX_PROJECTION); + this._shaderValues.setVector(RenderableSprite3D.REFLECTIONCUBE_HDR_PARAMS, ReflectionProbe.defaultTextureHDRDecodeValues); + this._shaderValues.setTexture(RenderableSprite3D.REFLECTIONTEXTURE, TextureCube.blackTexture); + } + else { + if (!this._probReflection.boxProjection) { + this._shaderValues.removeDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_SPECCUBE_BOX_PROJECTION); + } + else { + this._shaderValues.addDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_SPECCUBE_BOX_PROJECTION); + this._shaderValues.setVector3(RenderableSprite3D.REFLECTIONCUBE_PROBEPOSITION, this._probReflection.probePosition); + this._shaderValues.setVector3(RenderableSprite3D.REFLECTIONCUBE_PROBEBOXMAX, this._probReflection.boundsMax); + this._shaderValues.setVector3(RenderableSprite3D.REFLECTIONCUBE_PROBEBOXMIN, this._probReflection.boundsMin); + } + this._shaderValues.setTexture(RenderableSprite3D.REFLECTIONTEXTURE, this._probReflection.reflectionTexture); + this._shaderValues.setVector(RenderableSprite3D.REFLECTIONCUBE_HDR_PARAMS, this._probReflection.reflectionHDRParams); + } + } + _renderUpdateWithCamera(context, transform) { + var projectionView = context.projectionViewMatrix; + if (projectionView) { + var element = context.renderElement; + switch (element.renderType) { + case RenderElement.RENDERTYPE_NORMAL: + case RenderElement.RENDERTYPE_STATICBATCH: + case RenderElement.RENDERTYPE_VERTEXBATCH: + if (transform) { + Matrix4x4.multiply(projectionView, transform.worldMatrix, this._projectionViewWorldMatrix); + this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX, this._projectionViewWorldMatrix); + } + else { + this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX, projectionView); + } + break; + } + } + } + _revertBatchRenderUpdate(context) { + var element = context.renderElement; + switch (element.renderType) { + case RenderElement.RENDERTYPE_STATICBATCH: + if (this._revertStaticBatchDefineUV1) + this._shaderValues.removeDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_UV1); + this._shaderValues.setVector(RenderableSprite3D.LIGHTMAPSCALEOFFSET, this.lightmapScaleOffset); + break; + case RenderElement.RENDERTYPE_INSTANCEBATCH: + this._shaderValues.removeDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_GPU_INSTANCE); + break; + } + } + _destroy() { + (this._isPartOfStaticBatch) && (MeshRenderStaticBatchManager.instance._removeRenderSprite(this._owner)); + super._destroy(); + } + } + + class MeshFilter { + constructor(owner) { + this._owner = owner; + } + get sharedMesh() { + return this._sharedMesh; + } + set sharedMesh(value) { + if (this._sharedMesh !== value) { + var defineDatas = this._owner._render._shaderValues; + var lastValue = this._sharedMesh; + if (lastValue) { + lastValue._removeReference(); + this._getMeshDefine(lastValue, MeshFilter._meshVerticeDefine); + for (var i = 0, n = MeshFilter._meshVerticeDefine.length; i < n; i++) + defineDatas.removeDefine(MeshFilter._meshVerticeDefine[i]); + } + if (value) { + value._addReference(); + this._getMeshDefine(value, MeshFilter._meshVerticeDefine); + for (var i = 0, n = MeshFilter._meshVerticeDefine.length; i < n; i++) + defineDatas.addDefine(MeshFilter._meshVerticeDefine[i]); + } + this._owner._render._onMeshChange(value); + this._sharedMesh = value; + } + } + _getMeshDefine(mesh, out) { + out.length = 0; + var define; + for (var i = 0, n = mesh._subMeshes.length; i < n; i++) { + var subMesh = mesh.getSubMesh(i); + var vertexElements = subMesh._vertexBuffer._vertexDeclaration._vertexElements; + for (var j = 0, m = vertexElements.length; j < m; j++) { + var vertexElement = vertexElements[j]; + var name = vertexElement._elementUsage; + switch (name) { + case VertexMesh.MESH_COLOR0: + out.push(MeshSprite3DShaderDeclaration.SHADERDEFINE_COLOR); + break; + case VertexMesh.MESH_TEXTURECOORDINATE0: + out.push(MeshSprite3DShaderDeclaration.SHADERDEFINE_UV0); + break; + case VertexMesh.MESH_TEXTURECOORDINATE1: + out.push(MeshSprite3DShaderDeclaration.SHADERDEFINE_UV1); + break; + } + } + } + return define; + } + destroy() { + this._owner = null; + (this._sharedMesh) && (this._sharedMesh._removeReference(), this._sharedMesh = null); + } + } + MeshFilter._meshVerticeDefine = []; + + class SubMeshDynamicBatch extends GeometryElement { + constructor() { + super(); + this._bufferState = new BufferState(); + var gl = Laya.LayaGL.instance; + var maxVerDec = VertexMesh.getVertexDeclaration("POSITION,NORMAL,COLOR,UV,UV1,TANGENT"); + var maxByteCount = maxVerDec.vertexStride * SubMeshDynamicBatch.maxIndicesCount; + this._vertices = new Float32Array(maxByteCount / 4); + this._vertexBuffer = new VertexBuffer3D(maxByteCount, gl.DYNAMIC_DRAW); + this._indices = new Int16Array(SubMeshDynamicBatch.maxIndicesCount); + this._indexBuffer = new IndexBuffer3D(exports.IndexFormat.UInt16, this._indices.length, gl.DYNAMIC_DRAW); + var memorySize = this._vertexBuffer._byteLength + this._indexBuffer._byteLength; + Laya.Resource._addMemory(memorySize, memorySize); + } + static __init__() { + SubMeshDynamicBatch.instance = new SubMeshDynamicBatch(); + } + _getBatchVertices(vertexDeclaration, batchVertices, batchOffset, element, subMesh) { + var vertexFloatCount = vertexDeclaration.vertexStride / 4; + var oriVertexes = subMesh._vertexBuffer.getFloat32Data(); + var multiSubMesh = element._dynamicMultiSubMesh; + var vertexCount = element._dynamicVertexCount; + element._computeWorldPositionsAndNormals(this._positionOffset, this._normalOffset, multiSubMesh, vertexCount); + var worldPositions = element._dynamicWorldPositions; + var worldNormals = element._dynamicWorldNormals; + var indices = subMesh._indices; + for (var i = 0; i < vertexCount; i++) { + var index = multiSubMesh ? indices[i] : i; + var oriOffset = index * vertexFloatCount; + var bakeOffset = (i + batchOffset) * vertexFloatCount; + var oriOff = i * 3; + var bakOff = bakeOffset + this._positionOffset; + batchVertices[bakOff] = worldPositions[oriOff]; + batchVertices[bakOff + 1] = worldPositions[oriOff + 1]; + batchVertices[bakOff + 2] = worldPositions[oriOff + 2]; + if (this._normalOffset !== -1) { + bakOff = bakeOffset + this._normalOffset; + batchVertices[bakOff] = worldNormals[oriOff]; + batchVertices[bakOff + 1] = worldNormals[oriOff + 1]; + batchVertices[bakOff + 2] = worldNormals[oriOff + 2]; + } + if (this._colorOffset !== -1) { + bakOff = bakeOffset + this._colorOffset; + oriOff = oriOffset + this._colorOffset; + batchVertices[bakOff] = oriVertexes[oriOff]; + batchVertices[bakOff + 1] = oriVertexes[oriOff + 1]; + batchVertices[bakOff + 2] = oriVertexes[oriOff + 2]; + batchVertices[bakOff + 3] = oriVertexes[oriOff + 3]; + } + if (this._uv0Offset !== -1) { + bakOff = bakeOffset + this._uv0Offset; + oriOff = oriOffset + this._uv0Offset; + batchVertices[bakOff] = oriVertexes[oriOff]; + batchVertices[bakOff + 1] = oriVertexes[oriOff + 1]; + } + if (this._sTangentOffset !== -1) { + bakOff = bakeOffset + this._sTangentOffset; + oriOff = oriOffset + this._sTangentOffset; + batchVertices[bakOff] = oriVertexes[oriOff]; + batchVertices[bakOff + 1] = oriVertexes[oriOff + 1]; + batchVertices[bakOff + 2] = oriVertexes[oriOff + 2]; + batchVertices[bakOff + 3] = oriVertexes[oriOff + 3]; + bakOff = bakeOffset + this._sTangentOffset; + oriOff = oriOffset + this._sTangentOffset; + batchVertices[bakOff] = oriVertexes[oriOff]; + batchVertices[bakOff + 1] = oriVertexes[oriOff + 1]; + batchVertices[bakOff + 2] = oriVertexes[oriOff + 2]; + batchVertices[bakOff + 3] = oriVertexes[oriOff + 3]; + } + } + } + _getBatchIndices(batchIndices, batchIndexCount, batchVertexCount, transform, subMesh, multiSubMesh) { + var subIndices = subMesh._indices; + var k, m, batchOffset; + var isInvert = transform._isFrontFaceInvert; + if (multiSubMesh) { + if (isInvert) { + for (k = 0, m = subIndices.length; k < m; k += 3) { + batchOffset = batchIndexCount + k; + var index = batchVertexCount + k; + batchIndices[batchOffset] = index; + batchIndices[batchOffset + 1] = index + 2; + batchIndices[batchOffset + 2] = index + 1; + } + } + else { + for (k = 0, m = subIndices.length; k < m; k += 3) { + batchOffset = batchIndexCount + k; + index = batchVertexCount + k; + batchIndices[batchOffset] = index; + batchIndices[batchOffset + 1] = index + 1; + batchIndices[batchOffset + 2] = index + 2; + } + } + } + else { + if (isInvert) { + for (k = 0, m = subIndices.length; k < m; k += 3) { + batchOffset = batchIndexCount + k; + batchIndices[batchOffset] = batchVertexCount + subIndices[k]; + batchIndices[batchOffset + 1] = batchVertexCount + subIndices[k + 2]; + batchIndices[batchOffset + 2] = batchVertexCount + subIndices[k + 1]; + } + } + else { + for (k = 0, m = subIndices.length; k < m; k += 3) { + batchOffset = batchIndexCount + k; + batchIndices[batchOffset] = batchVertexCount + subIndices[k]; + batchIndices[batchOffset + 1] = batchVertexCount + subIndices[k + 1]; + batchIndices[batchOffset + 2] = batchVertexCount + subIndices[k + 2]; + } + } + } + } + _flush(vertexCount, indexCount) { + var gl = Laya.LayaGL.instance; + this._vertexBuffer.setData(this._vertices.buffer, 0, 0, vertexCount * (this._bufferState.vertexDeclaration.vertexStride)); + this._indexBuffer.setData(this._indices, 0, 0, indexCount); + gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 0); + } + _prepareRender(state) { + var element = state.renderElement; + var vertexDeclaration = element.vertexBatchVertexDeclaration; + this._bufferState = ILaya3D.MeshRenderDynamicBatchManager.instance._getBufferState(vertexDeclaration); + this._positionOffset = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_POSITION0)._offset / 4; + var normalElement = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_NORMAL0); + this._normalOffset = normalElement ? normalElement._offset / 4 : -1; + var colorElement = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_COLOR0); + this._colorOffset = colorElement ? colorElement._offset / 4 : -1; + var uv0Element = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_TEXTURECOORDINATE0); + this._uv0Offset = uv0Element ? uv0Element._offset / 4 : -1; + var uv1Element = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_TEXTURECOORDINATE1); + this._uv1Offset = uv1Element ? uv1Element._offset / 4 : -1; + var tangentElement = vertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_TANGENT0); + this._sTangentOffset = tangentElement ? tangentElement._offset / 4 : -1; + return true; + } + _render(context) { + this._bufferState.bind(); + var element = context.renderElement; + var vertexDeclaration = element.vertexBatchVertexDeclaration; + var batchElements = element.vertexBatchElementList; + var batchVertexCount = 0; + var batchIndexCount = 0; + var renderBatchCount = 0; + var elementCount = batchElements.length; + var elements = batchElements.elements; + for (var i = 0; i < elementCount; i++) { + var subElement = elements[i]; + var subMesh = subElement._geometry; + var indexCount = subMesh._indexCount; + if (batchIndexCount + indexCount > SubMeshDynamicBatch.maxIndicesCount) { + this._flush(batchVertexCount, batchIndexCount); + renderBatchCount++; + Laya.Stat.trianglesFaces += batchIndexCount / 3; + batchVertexCount = batchIndexCount = 0; + } + var transform = subElement._transform; + this._getBatchVertices(vertexDeclaration, this._vertices, batchVertexCount, subElement, subMesh); + this._getBatchIndices(this._indices, batchIndexCount, batchVertexCount, transform, subMesh, subElement._dynamicMultiSubMesh); + batchVertexCount += subElement._dynamicVertexCount; + batchIndexCount += indexCount; + } + this._flush(batchVertexCount, batchIndexCount); + renderBatchCount++; + Laya.Stat.renderBatches += renderBatchCount; + Laya.Stat.savedRenderBatches += elementCount - renderBatchCount; + Laya.Stat.trianglesFaces += batchIndexCount / 3; + } + } + SubMeshDynamicBatch.maxAllowVertexCount = 10; + SubMeshDynamicBatch.maxAllowAttribueCount = 900; + SubMeshDynamicBatch.maxIndicesCount = 32000; + + class MeshRenderDynamicBatchManager extends DynamicBatchManager { + constructor() { + super(); + this._instanceBatchOpaqueMarks = []; + this._vertexBatchOpaqueMarks = []; + this._cacheBufferStates = []; + this._updateCountMark = 0; + } + getInstanceBatchOpaquaMark(receiveShadow, materialID, subMeshID, invertFace) { + var instanceReceiveShadowMarks = (this._instanceBatchOpaqueMarks[receiveShadow ? 0 : 1]) || (this._instanceBatchOpaqueMarks[receiveShadow ? 0 : 1] = []); + var instanceMaterialMarks = (instanceReceiveShadowMarks[materialID]) || (instanceReceiveShadowMarks[materialID] = []); + var instancSubMeshMarks = (instanceMaterialMarks[subMeshID]) || (instanceMaterialMarks[subMeshID] = []); + return instancSubMeshMarks[invertFace ? 1 : 0] || (instancSubMeshMarks[invertFace ? 1 : 0] = new BatchMark()); + } + getVertexBatchOpaquaMark(lightMapIndex, receiveShadow, materialID, verDecID) { + var dynLightMapMarks = (this._vertexBatchOpaqueMarks[lightMapIndex]) || (this._vertexBatchOpaqueMarks[lightMapIndex] = []); + var dynReceiveShadowMarks = (dynLightMapMarks[receiveShadow ? 0 : 1]) || (dynLightMapMarks[receiveShadow ? 0 : 1] = []); + var dynMaterialMarks = (dynReceiveShadowMarks[materialID]) || (dynReceiveShadowMarks[materialID] = []); + return dynMaterialMarks[verDecID] || (dynMaterialMarks[verDecID] = new BatchMark()); + } + _getBufferState(vertexDeclaration) { + var bufferState = this._cacheBufferStates[vertexDeclaration.id]; + if (!bufferState) { + var instance = SubMeshDynamicBatch.instance; + bufferState = new BufferState(); + bufferState.bind(); + var vertexBuffer = instance._vertexBuffer; + vertexBuffer.vertexDeclaration = vertexDeclaration; + bufferState.applyVertexBuffer(vertexBuffer); + bufferState.applyIndexBuffer(instance._indexBuffer); + bufferState.unBind(); + this._cacheBufferStates[vertexDeclaration.id] = bufferState; + } + return bufferState; + } + _getBatchRenderElementFromPool() { + var renderElement = this._batchRenderElementPool[this._batchRenderElementPoolIndex++]; + if (!renderElement) { + renderElement = new SubMeshRenderElement(); + this._batchRenderElementPool[this._batchRenderElementPoolIndex - 1] = renderElement; + renderElement.vertexBatchElementList = new SingletonList(); + renderElement.instanceBatchElementList = new SingletonList(); + } + return renderElement; + } + _clear() { + super._clear(); + this._updateCountMark++; + } + } + MeshRenderDynamicBatchManager.instance = new MeshRenderDynamicBatchManager(); + + class MeshSprite3D extends RenderableSprite3D { + constructor(mesh = null, name = null) { + super(name); + this._meshFilter = new MeshFilter(this); + this._render = new MeshRenderer(this); + (mesh) && (this._meshFilter.sharedMesh = mesh); + } + static __init__() { + MeshSprite3DShaderDeclaration.SHADERDEFINE_UV0 = Shader3D.getDefineByName("UV"); + MeshSprite3DShaderDeclaration.SHADERDEFINE_COLOR = Shader3D.getDefineByName("COLOR"); + MeshSprite3DShaderDeclaration.SHADERDEFINE_UV1 = Shader3D.getDefineByName("UV1"); + MeshSprite3DShaderDeclaration.SHADERDEFINE_GPU_INSTANCE = Shader3D.getDefineByName("GPU_INSTANCE"); + MeshSprite3DShaderDeclaration.SHADERDEFINE_SPECCUBE_BOX_PROJECTION = Shader3D.getDefineByName("SPECCUBE_BOX_PROJECTION"); + StaticBatchManager._registerManager(MeshRenderStaticBatchManager.instance); + DynamicBatchManager._registerManager(MeshRenderDynamicBatchManager.instance); + } + get meshFilter() { + return this._meshFilter; + } + get meshRenderer() { + return this._render; + } + _parse(data, spriteMap) { + super._parse(data, spriteMap); + var render = this.meshRenderer; + var lightmapIndex = data.lightmapIndex; + (lightmapIndex != null) && (render.lightmapIndex = lightmapIndex); + var lightmapScaleOffsetArray = data.lightmapScaleOffset; + (lightmapScaleOffsetArray) && (render.lightmapScaleOffset = new Vector4(lightmapScaleOffsetArray[0], lightmapScaleOffsetArray[1], lightmapScaleOffsetArray[2], lightmapScaleOffsetArray[3])); + (data.meshPath != undefined) && (this.meshFilter.sharedMesh = Laya.Loader.getRes(data.meshPath)); + (data.enableRender != undefined) && (render.enable = data.enableRender); + (data.receiveShadows != undefined) && (render.receiveShadow = data.receiveShadows); + (data.castShadow != undefined) && (render.castShadow = data.castShadow); + var materials = data.materials; + if (materials) { + var sharedMaterials = render.sharedMaterials; + var materialCount = materials.length; + sharedMaterials.length = materialCount; + for (var i = 0; i < materialCount; i++) { + sharedMaterials[i] = Laya.Loader.getRes(materials[i].path); + } + render.sharedMaterials = sharedMaterials; + } + } + _addToInitStaticBatchManager() { + if (this.meshFilter.sharedMesh) + MeshRenderStaticBatchManager.instance._addBatchSprite(this); + } + _cloneTo(destObject, rootSprite, dstSprite) { + var meshSprite3D = destObject; + meshSprite3D._meshFilter.sharedMesh = this._meshFilter.sharedMesh; + var meshRender = this._render; + var destMeshRender = meshSprite3D._render; + destMeshRender.enable = meshRender.enable; + destMeshRender.sharedMaterials = meshRender.sharedMaterials; + destMeshRender.castShadow = meshRender.castShadow; + var lightmapScaleOffset = meshRender.lightmapScaleOffset; + lightmapScaleOffset && (destMeshRender.lightmapScaleOffset = lightmapScaleOffset.clone()); + destMeshRender.lightmapIndex = meshRender.lightmapIndex; + destMeshRender.receiveShadow = meshRender.receiveShadow; + destMeshRender.sortingFudge = meshRender.sortingFudge; + super._cloneTo(destObject, rootSprite, dstSprite); + } + destroy(destroyChild = true) { + if (this.destroyed) + return; + super.destroy(destroyChild); + this._meshFilter.destroy(); + } + _create() { + return new MeshSprite3D(); + } + } + + class GradientMode { + } + GradientMode.Blend = 0; + GradientMode.Fixed = 1; + + class Gradient { + constructor(maxColorRGBKeyCount, maxColorAlphaKeyCount) { + this._mode = 0; + this._maxColorRGBKeysCount = 0; + this._maxColorAlphaKeysCount = 0; + this._colorRGBKeysCount = 0; + this._colorAlphaKeysCount = 0; + this._alphaElements = null; + this._rgbElements = null; + this._maxColorRGBKeysCount = maxColorRGBKeyCount; + this._maxColorAlphaKeysCount = maxColorAlphaKeyCount; + this._rgbElements = new Float32Array(maxColorRGBKeyCount * 4); + this._alphaElements = new Float32Array(maxColorAlphaKeyCount * 2); + } + get mode() { + return this._mode; + } + set mode(value) { + this._mode = value; + } + get colorRGBKeysCount() { + return this._colorRGBKeysCount; + } + get colorAlphaKeysCount() { + return this._colorAlphaKeysCount; + } + get maxColorRGBKeysCount() { + return this._maxColorRGBKeysCount; + } + get maxColorAlphaKeysCount() { + return this._maxColorAlphaKeysCount; + } + addColorRGB(key, value) { + if (this._colorRGBKeysCount < this._maxColorRGBKeysCount) { + var offset = this._colorRGBKeysCount * 4; + this._rgbElements[offset] = key; + this._rgbElements[offset + 1] = value.r; + this._rgbElements[offset + 2] = value.g; + this._rgbElements[offset + 3] = value.b; + this._colorRGBKeysCount++; + } + else { + console.warn("Gradient:warning:data count must lessEqual than " + this._maxColorRGBKeysCount); + } + } + addColorAlpha(key, value) { + if (this._colorAlphaKeysCount < this._maxColorAlphaKeysCount) { + var offset = this._colorAlphaKeysCount * 2; + this._alphaElements[offset] = key; + this._alphaElements[offset + 1] = value; + this._colorAlphaKeysCount++; + } + else { + console.warn("Gradient:warning:data count must lessEqual than " + this._maxColorAlphaKeysCount); + } + } + updateColorRGB(index, key, value) { + if (index < this._colorRGBKeysCount) { + var offset = index * 4; + this._rgbElements[offset] = key; + this._rgbElements[offset + 1] = value.r; + this._rgbElements[offset + 2] = value.g; + this._rgbElements[offset + 3] = value.b; + } + else { + console.warn("Gradient:warning:index must lessEqual than colorRGBKeysCount:" + this._colorRGBKeysCount); + } + } + updateColorAlpha(index, key, value) { + if (index < this._colorAlphaKeysCount) { + var offset = index * 2; + this._alphaElements[offset] = key; + this._alphaElements[offset + 1] = value; + } + else { + console.warn("Gradient:warning:index must lessEqual than colorAlphaKeysCount:" + this._colorAlphaKeysCount); + } + } + evaluateColorRGB(lerpFactor, out, startSearchIndex = 0, reverseSearch = false) { + lerpFactor = Math.min(Math.max(lerpFactor, 0.0), 1.0); + var rgbElements = this._rgbElements; + var curIndex = startSearchIndex; + if (reverseSearch) { + for (var i = curIndex; i >= 0; i--) { + var offset = i * 4; + var left = rgbElements[offset]; + if (lerpFactor === left) { + out.r = rgbElements[offset + 1]; + out.g = rgbElements[offset + 2]; + out.b = rgbElements[offset + 3]; + return curIndex; + } + switch (this._mode) { + case GradientMode.Blend: + if (lerpFactor > left) { + var right = rgbElements[offset + 4]; + if (lerpFactor > right) + throw "Gradient:wrong startSearchIndex."; + var diff = right - left; + var y1 = right - lerpFactor; + var y2 = lerpFactor - left; + out.r = (y1 * rgbElements[offset + 1] + y2 * rgbElements[offset + 5]) / diff; + out.g = (y1 * rgbElements[offset + 2] + y2 * rgbElements[offset + 6]) / diff; + out.b = (y1 * rgbElements[offset + 3] + y2 * rgbElements[offset + 7]) / diff; + return curIndex; + } + else { + curIndex--; + continue; + } + case GradientMode.Fixed: + if (lerpFactor > left) { + if (lerpFactor > rgbElements[offset + 4]) + throw "Gradient:wrong startSearchIndex."; + out.r = rgbElements[offset + 5]; + out.g = rgbElements[offset + 6]; + out.b = rgbElements[offset + 7]; + return curIndex; + } + else { + curIndex--; + continue; + } + default: + throw "Gradient:unknown mode."; + } + } + } + else { + for (var i = 0, n = this._rgbElements.length; i < n; i++) { + offset = i * 4; + var right = rgbElements[offset]; + if (lerpFactor === right) { + out.r = rgbElements[offset + 1]; + out.g = rgbElements[offset + 2]; + out.b = rgbElements[offset + 3]; + return curIndex; + } + switch (this._mode) { + case GradientMode.Blend: + if (lerpFactor < right) { + var left = rgbElements[offset - 4]; + if (lerpFactor < left) + throw "Gradient:wrong startSearchIndex."; + var diff = right - left; + var y1 = right - lerpFactor; + var y2 = lerpFactor - left; + out.r = (y1 * rgbElements[offset - 3] + y2 * rgbElements[offset + 1]) / diff; + out.g = (y1 * rgbElements[offset - 2] + y2 * rgbElements[offset + 2]) / diff; + out.b = (y1 * rgbElements[offset - 1] + y2 * rgbElements[offset + 3]) / diff; + return curIndex; + } + else { + curIndex++; + continue; + } + case GradientMode.Fixed: + if (lerpFactor < right) { + if (lerpFactor < rgbElements[offset - 4]) + throw "Gradient:wrong startSearchIndex."; + out.r = rgbElements[offset + 1]; + out.g = rgbElements[offset + 2]; + out.b = rgbElements[offset + 3]; + return curIndex; + } + else { + curIndex++; + continue; + } + default: + throw "Gradient:unknown mode."; + } + } + } + return curIndex; + } + evaluateColorAlpha(lerpFactor, outColor, startSearchIndex = 0, reverseSearch = false) { + lerpFactor = Math.min(Math.max(lerpFactor, 0.0), 1.0); + var alphaElements = this._alphaElements; + var curIndex = startSearchIndex; + if (reverseSearch) { + for (var i = curIndex; i >= 0; i--) { + var offset = i * 2; + var left = alphaElements[offset]; + if (lerpFactor === left) { + outColor.a = alphaElements[offset + 1]; + return curIndex; + } + switch (this._mode) { + case GradientMode.Blend: + if (lerpFactor > left) { + var right = alphaElements[offset + 2]; + if (lerpFactor > right) + throw "Gradient:wrong startSearchIndex."; + var diff = right - left; + var x1 = right - lerpFactor; + var x2 = lerpFactor - left; + outColor.a = (x1 * alphaElements[offset + 1] + x2 * alphaElements[offset + 3]) / diff; + return curIndex; + } + else { + curIndex--; + continue; + } + case GradientMode.Fixed: + if (lerpFactor > left) { + if (lerpFactor > alphaElements[offset + 2]) + throw "Gradient:wrong startSearchIndex."; + outColor.a = alphaElements[offset + 3]; + return curIndex; + } + else { + curIndex--; + continue; + } + default: + throw "Gradient:unknown mode."; + } + } + } + else { + for (var i = curIndex, n = this._alphaElements.length; i < n; i++) { + var offset = i * 2; + var right = alphaElements[offset]; + if (lerpFactor === right) { + outColor.a = alphaElements[offset + 1]; + return curIndex; + } + switch (this._mode) { + case GradientMode.Blend: + if (lerpFactor < right) { + var left = alphaElements[offset - 2]; + if (lerpFactor < left) + throw "Gradient:wrong startSearchIndex."; + var diff = right - left; + var x1 = right - lerpFactor; + var x2 = lerpFactor - left; + outColor.a = (x1 * alphaElements[offset - 1] + x2 * alphaElements[offset + 1]) / diff; + return curIndex; + } + else { + curIndex++; + continue; + } + case GradientMode.Fixed: + if (lerpFactor < right) { + if (lerpFactor < alphaElements[offset - 2]) + throw "Gradient:wrong startSearchIndex."; + outColor.a = alphaElements[offset + 1]; + return curIndex; + } + else { + curIndex++; + continue; + } + default: + throw "Gradient:unknown mode."; + } + } + } + return curIndex; + } + cloneTo(destObject) { + var destGradientDataColor = destObject; + var i, n; + destGradientDataColor._colorAlphaKeysCount = this._colorAlphaKeysCount; + var destAlphaElements = destGradientDataColor._alphaElements; + for (i = 0, n = this._alphaElements.length; i < n; i++) + destAlphaElements[i] = this._alphaElements[i]; + destGradientDataColor._colorRGBKeysCount = this._colorRGBKeysCount; + var destRGBElements = destGradientDataColor._rgbElements; + for (i = 0, n = this._rgbElements.length; i < n; i++) + destRGBElements[i] = this._rgbElements[i]; + } + clone() { + var destGradientDataColor = new Gradient(this._maxColorRGBKeysCount, this._maxColorAlphaKeysCount); + this.cloneTo(destGradientDataColor); + return destGradientDataColor; + } + } + + class Burst { + constructor(time, minCount, maxCount) { + this._time = time; + this._minCount = minCount; + this._maxCount = maxCount; + } + get time() { + return this._time; + } + get minCount() { + return this._minCount; + } + get maxCount() { + return this._maxCount; + } + cloneTo(destObject) { + var destBurst = destObject; + destBurst._time = this._time; + destBurst._minCount = this._minCount; + destBurst._maxCount = this._maxCount; + } + clone() { + var destBurst = new Burst(this._time, this._minCount, this._maxCount); + this.cloneTo(destBurst); + return destBurst; + } + } + + class GradientColor { + constructor() { + this._type = 0; + this._constant = null; + this._constantMin = null; + this._constantMax = null; + this._gradient = null; + this._gradientMin = null; + this._gradientMax = null; + } + static createByConstant(constant) { + var gradientColor = new GradientColor(); + gradientColor._type = 0; + gradientColor._constant = constant; + return gradientColor; + } + static createByGradient(gradient) { + var gradientColor = new GradientColor(); + gradientColor._type = 1; + gradientColor._gradient = gradient; + return gradientColor; + } + static createByRandomTwoConstant(minConstant, maxConstant) { + var gradientColor = new GradientColor(); + gradientColor._type = 2; + gradientColor._constantMin = minConstant; + gradientColor._constantMax = maxConstant; + return gradientColor; + } + static createByRandomTwoGradient(minGradient, maxGradient) { + var gradientColor = new GradientColor(); + gradientColor._type = 3; + gradientColor._gradientMin = minGradient; + gradientColor._gradientMax = maxGradient; + return gradientColor; + } + get type() { + return this._type; + } + get constant() { + return this._constant; + } + get constantMin() { + return this._constantMin; + } + get constantMax() { + return this._constantMax; + } + get gradient() { + return this._gradient; + } + get gradientMin() { + return this._gradientMin; + } + get gradientMax() { + return this._gradientMax; + } + cloneTo(destObject) { + var destGradientColor = destObject; + destGradientColor._type = this._type; + this._constant.cloneTo(destGradientColor._constant); + this._constantMin.cloneTo(destGradientColor._constantMin); + this._constantMax.cloneTo(destGradientColor._constantMax); + this._gradient.cloneTo(destGradientColor._gradient); + this._gradientMin.cloneTo(destGradientColor._gradientMin); + this._gradientMax.cloneTo(destGradientColor._gradientMax); + } + clone() { + var destGradientColor = new GradientColor(); + this.cloneTo(destGradientColor); + return destGradientColor; + } + } + + class ColorOverLifetime { + constructor(color) { + this._color = color; + } + get color() { + return this._color; + } + cloneTo(destObject) { + var destColorOverLifetime = destObject; + this._color.cloneTo(destColorOverLifetime._color); + destColorOverLifetime.enable = this.enable; + } + clone() { + var destColor; + switch (this._color.type) { + case 0: + destColor = GradientColor.createByConstant(this._color.constant.clone()); + break; + case 1: + destColor = GradientColor.createByGradient(this._color.gradient.clone()); + break; + case 2: + destColor = GradientColor.createByRandomTwoConstant(this._color.constantMin.clone(), this._color.constantMax.clone()); + break; + case 3: + destColor = GradientColor.createByRandomTwoGradient(this._color.gradientMin.clone(), this._color.gradientMax.clone()); + break; + } + var destColorOverLifetime = new ColorOverLifetime(destColor); + destColorOverLifetime.enable = this.enable; + return destColorOverLifetime; + } + } + + class FrameOverTime { + constructor() { + this._type = 0; + this._constant = 0; + this._overTime = null; + this._constantMin = 0; + this._constantMax = 0; + this._overTimeMin = null; + this._overTimeMax = null; + } + static createByConstant(constant = 0) { + var rotationOverLifetime = new FrameOverTime(); + rotationOverLifetime._type = 0; + rotationOverLifetime._constant = constant; + return rotationOverLifetime; + } + static createByOverTime(overTime) { + var rotationOverLifetime = new FrameOverTime(); + rotationOverLifetime._type = 1; + rotationOverLifetime._overTime = overTime; + return rotationOverLifetime; + } + static createByRandomTwoConstant(constantMin = 0, constantMax = 0) { + var rotationOverLifetime = new FrameOverTime(); + rotationOverLifetime._type = 2; + rotationOverLifetime._constantMin = constantMin; + rotationOverLifetime._constantMax = constantMax; + return rotationOverLifetime; + } + static createByRandomTwoOverTime(gradientFrameMin, gradientFrameMax) { + var rotationOverLifetime = new FrameOverTime(); + rotationOverLifetime._type = 3; + rotationOverLifetime._overTimeMin = gradientFrameMin; + rotationOverLifetime._overTimeMax = gradientFrameMax; + return rotationOverLifetime; + } + get type() { + return this._type; + } + get constant() { + return this._constant; + } + get frameOverTimeData() { + return this._overTime; + } + get constantMin() { + return this._constantMin; + } + get constantMax() { + return this._constantMax; + } + get frameOverTimeDataMin() { + return this._overTimeMin; + } + get frameOverTimeDataMax() { + return this._overTimeMax; + } + cloneTo(destObject) { + var destFrameOverTime = destObject; + destFrameOverTime._type = this._type; + destFrameOverTime._constant = this._constant; + (this._overTime) && (this._overTime.cloneTo(destFrameOverTime._overTime)); + destFrameOverTime._constantMin = this._constantMin; + destFrameOverTime._constantMax = this._constantMax; + (this._overTimeMin) && (this._overTimeMin.cloneTo(destFrameOverTime._overTimeMin)); + (this._overTimeMax) && (this._overTimeMax.cloneTo(destFrameOverTime._overTimeMax)); + } + clone() { + var destFrameOverTime = new FrameOverTime(); + this.cloneTo(destFrameOverTime); + return destFrameOverTime; + } + } + + class GradientAngularVelocity { + constructor() { + this._type = 0; + this._separateAxes = false; + this._constant = 0; + this._constantSeparate = null; + this._gradient = null; + this._gradientX = null; + this._gradientY = null; + this._gradientZ = null; + this._gradientW = null; + this._constantMin = 0; + this._constantMax = 0; + this._constantMinSeparate = null; + this._constantMaxSeparate = null; + this._gradientMin = null; + this._gradientMax = null; + this._gradientXMin = null; + this._gradientXMax = null; + this._gradientYMin = null; + this._gradientYMax = null; + this._gradientZMin = null; + this._gradientZMax = null; + this._gradientWMin = null; + this._gradientWMax = null; + } + static createByConstant(constant) { + var gradientAngularVelocity = new GradientAngularVelocity(); + gradientAngularVelocity._type = 0; + gradientAngularVelocity._separateAxes = false; + gradientAngularVelocity._constant = constant; + return gradientAngularVelocity; + } + static createByConstantSeparate(separateConstant) { + var gradientAngularVelocity = new GradientAngularVelocity(); + gradientAngularVelocity._type = 0; + gradientAngularVelocity._separateAxes = true; + gradientAngularVelocity._constantSeparate = separateConstant; + return gradientAngularVelocity; + } + static createByGradient(gradient) { + var gradientAngularVelocity = new GradientAngularVelocity(); + gradientAngularVelocity._type = 1; + gradientAngularVelocity._separateAxes = false; + gradientAngularVelocity._gradient = gradient; + return gradientAngularVelocity; + } + static createByGradientSeparate(gradientX, gradientY, gradientZ) { + var gradientAngularVelocity = new GradientAngularVelocity(); + gradientAngularVelocity._type = 1; + gradientAngularVelocity._separateAxes = true; + gradientAngularVelocity._gradientX = gradientX; + gradientAngularVelocity._gradientY = gradientY; + gradientAngularVelocity._gradientZ = gradientZ; + return gradientAngularVelocity; + } + static createByRandomTwoConstant(constantMin, constantMax) { + var gradientAngularVelocity = new GradientAngularVelocity(); + gradientAngularVelocity._type = 2; + gradientAngularVelocity._separateAxes = false; + gradientAngularVelocity._constantMin = constantMin; + gradientAngularVelocity._constantMax = constantMax; + return gradientAngularVelocity; + } + static createByRandomTwoConstantSeparate(separateConstantMin, separateConstantMax) { + var gradientAngularVelocity = new GradientAngularVelocity(); + gradientAngularVelocity._type = 2; + gradientAngularVelocity._separateAxes = true; + gradientAngularVelocity._constantMinSeparate = separateConstantMin; + gradientAngularVelocity._constantMaxSeparate = separateConstantMax; + return gradientAngularVelocity; + } + static createByRandomTwoGradient(gradientMin, gradientMax) { + var gradientAngularVelocity = new GradientAngularVelocity(); + gradientAngularVelocity._type = 3; + gradientAngularVelocity._separateAxes = false; + gradientAngularVelocity._gradientMin = gradientMin; + gradientAngularVelocity._gradientMax = gradientMax; + return gradientAngularVelocity; + } + static createByRandomTwoGradientSeparate(gradientXMin, gradientXMax, gradientYMin, gradientYMax, gradientZMin, gradientZMax, gradientWMin, gradientWMax) { + var gradientAngularVelocity = new GradientAngularVelocity(); + gradientAngularVelocity._type = 3; + gradientAngularVelocity._separateAxes = true; + gradientAngularVelocity._gradientXMin = gradientXMin; + gradientAngularVelocity._gradientXMax = gradientXMax; + gradientAngularVelocity._gradientYMin = gradientYMin; + gradientAngularVelocity._gradientYMax = gradientYMax; + gradientAngularVelocity._gradientZMin = gradientZMin; + gradientAngularVelocity._gradientZMax = gradientZMax; + gradientAngularVelocity._gradientWMin = gradientWMin; + gradientAngularVelocity._gradientWMax = gradientWMax; + return gradientAngularVelocity; + } + get type() { + return this._type; + } + get separateAxes() { + return this._separateAxes; + } + get constant() { + return this._constant; + } + get constantSeparate() { + return this._constantSeparate; + } + get gradient() { + return this._gradient; + } + get gradientX() { + return this._gradientX; + } + get gradientY() { + return this._gradientY; + } + get gradientZ() { + return this._gradientZ; + } + get gradientW() { + return this._gradientW; + } + get constantMin() { + return this._constantMin; + } + get constantMax() { + return this._constantMax; + } + get constantMinSeparate() { + return this._constantMinSeparate; + } + get constantMaxSeparate() { + return this._constantMaxSeparate; + } + get gradientMin() { + return this._gradientMin; + } + get gradientMax() { + return this._gradientMax; + } + get gradientXMin() { + return this._gradientXMin; + } + get gradientXMax() { + return this._gradientXMax; + } + get gradientYMin() { + return this._gradientYMin; + } + get gradientYMax() { + return this._gradientYMax; + } + get gradientZMin() { + return this._gradientZMin; + } + get gradientZMax() { + return this._gradientZMax; + } + get gradientWMin() { + return this._gradientWMin; + } + get gradientWMax() { + return this._gradientWMax; + } + cloneTo(destObject) { + var destGradientAngularVelocity = destObject; + destGradientAngularVelocity._type = this._type; + destGradientAngularVelocity._separateAxes = this._separateAxes; + destGradientAngularVelocity._constant = this._constant; + this._constantSeparate.cloneTo(destGradientAngularVelocity._constantSeparate); + this._gradient.cloneTo(destGradientAngularVelocity._gradient); + this._gradientX.cloneTo(destGradientAngularVelocity._gradientX); + this._gradientY.cloneTo(destGradientAngularVelocity._gradientY); + this._gradientZ.cloneTo(destGradientAngularVelocity._gradientZ); + destGradientAngularVelocity._constantMin = this._constantMin; + destGradientAngularVelocity._constantMax = this._constantMax; + this._constantMinSeparate.cloneTo(destGradientAngularVelocity._constantMinSeparate); + this._constantMaxSeparate.cloneTo(destGradientAngularVelocity._constantMaxSeparate); + this._gradientMin.cloneTo(destGradientAngularVelocity._gradientMin); + this._gradientMax.cloneTo(destGradientAngularVelocity._gradientMax); + this._gradientXMin.cloneTo(destGradientAngularVelocity._gradientXMin); + this._gradientXMax.cloneTo(destGradientAngularVelocity._gradientXMax); + this._gradientYMin.cloneTo(destGradientAngularVelocity._gradientYMin); + this._gradientYMax.cloneTo(destGradientAngularVelocity._gradientYMax); + this._gradientZMin.cloneTo(destGradientAngularVelocity._gradientZMin); + this._gradientZMax.cloneTo(destGradientAngularVelocity._gradientZMax); + } + clone() { + var destGradientAngularVelocity = new GradientAngularVelocity(); + this.cloneTo(destGradientAngularVelocity); + return destGradientAngularVelocity; + } + } + + class GradientDataInt { + constructor() { + this._currentLength = 0; + this._elements = new Float32Array(8); + } + get gradientCount() { + return this._currentLength / 2; + } + add(key, value) { + if (this._currentLength < 8) { + if ((this._currentLength === 6) && ((key !== 1))) { + key = 1; + console.log("Warning:the forth key is be force set to 1."); + } + this._elements[this._currentLength++] = key; + this._elements[this._currentLength++] = value; + } + else { + console.log("Warning:data count must lessEqual than 4"); + } + } + cloneTo(destObject) { + var destGradientDataInt = destObject; + destGradientDataInt._currentLength = this._currentLength; + var destElements = destGradientDataInt._elements; + for (var i = 0, n = this._elements.length; i < n; i++) { + destElements[i] = this._elements[i]; + } + } + clone() { + var destGradientDataInt = new GradientDataInt(); + this.cloneTo(destGradientDataInt); + return destGradientDataInt; + } + } + + class GradientDataNumber { + constructor() { + this._currentLength = 0; + this._elements = new Float32Array(8); + } + get gradientCount() { + return this._currentLength / 2; + } + add(key, value) { + if (this._currentLength < 8) { + if ((this._currentLength === 6) && ((key !== 1))) { + key = 1; + console.log("GradientDataNumber warning:the forth key is be force set to 1."); + } + this._elements[this._currentLength++] = key; + this._elements[this._currentLength++] = value; + } + else { + console.log("GradientDataNumber warning:data count must lessEqual than 4"); + } + } + getKeyByIndex(index) { + return this._elements[index * 2]; + } + getValueByIndex(index) { + return this._elements[index * 2 + 1]; + } + getAverageValue() { + var total = 0; + var count = 0; + for (var i = 0, n = this._currentLength - 2; i < n; i += 2) { + var subValue = this._elements[i + 1]; + subValue += this._elements[i + 3]; + subValue = subValue * (this._elements[i + 2] - this._elements[i]); + total += subValue; + count++; + } + return total / count; + } + cloneTo(destObject) { + var destGradientDataNumber = destObject; + destGradientDataNumber._currentLength = this._currentLength; + var destElements = destGradientDataNumber._elements; + for (var i = 0, n = this._elements.length; i < n; i++) + destElements[i] = this._elements[i]; + } + clone() { + var destGradientDataNumber = new GradientDataNumber(); + this.cloneTo(destGradientDataNumber); + return destGradientDataNumber; + } + } + + class GradientSize { + constructor() { + this._type = 0; + this._separateAxes = false; + this._gradient = null; + this._gradientX = null; + this._gradientY = null; + this._gradientZ = null; + this._constantMin = 0; + this._constantMax = 0; + this._constantMinSeparate = null; + this._constantMaxSeparate = null; + this._gradientMin = null; + this._gradientMax = null; + this._gradientXMin = null; + this._gradientXMax = null; + this._gradientYMin = null; + this._gradientYMax = null; + this._gradientZMin = null; + this._gradientZMax = null; + } + static createByGradient(gradient) { + var gradientSize = new GradientSize(); + gradientSize._type = 0; + gradientSize._separateAxes = false; + gradientSize._gradient = gradient; + return gradientSize; + } + static createByGradientSeparate(gradientX, gradientY, gradientZ) { + var gradientSize = new GradientSize(); + gradientSize._type = 0; + gradientSize._separateAxes = true; + gradientSize._gradientX = gradientX; + gradientSize._gradientY = gradientY; + gradientSize._gradientZ = gradientZ; + return gradientSize; + } + static createByRandomTwoConstant(constantMin, constantMax) { + var gradientSize = new GradientSize(); + gradientSize._type = 1; + gradientSize._separateAxes = false; + gradientSize._constantMin = constantMin; + gradientSize._constantMax = constantMax; + return gradientSize; + } + static createByRandomTwoConstantSeparate(constantMinSeparate, constantMaxSeparate) { + var gradientSize = new GradientSize(); + gradientSize._type = 1; + gradientSize._separateAxes = true; + gradientSize._constantMinSeparate = constantMinSeparate; + gradientSize._constantMaxSeparate = constantMaxSeparate; + return gradientSize; + } + static createByRandomTwoGradient(gradientMin, gradientMax) { + var gradientSize = new GradientSize(); + gradientSize._type = 2; + gradientSize._separateAxes = false; + gradientSize._gradientMin = gradientMin; + gradientSize._gradientMax = gradientMax; + return gradientSize; + } + static createByRandomTwoGradientSeparate(gradientXMin, gradientXMax, gradientYMin, gradientYMax, gradientZMin, gradientZMax) { + var gradientSize = new GradientSize(); + gradientSize._type = 2; + gradientSize._separateAxes = true; + gradientSize._gradientXMin = gradientXMin; + gradientSize._gradientXMax = gradientXMax; + gradientSize._gradientYMin = gradientYMin; + gradientSize._gradientYMax = gradientYMax; + gradientSize._gradientZMin = gradientZMin; + gradientSize._gradientZMax = gradientZMax; + return gradientSize; + } + get type() { + return this._type; + } + get separateAxes() { + return this._separateAxes; + } + get gradient() { + return this._gradient; + } + get gradientX() { + return this._gradientX; + } + get gradientY() { + return this._gradientY; + } + get gradientZ() { + return this._gradientZ; + } + get constantMin() { + return this._constantMin; + } + get constantMax() { + return this._constantMax; + } + get constantMinSeparate() { + return this._constantMinSeparate; + } + get constantMaxSeparate() { + return this._constantMaxSeparate; + } + get gradientMin() { + return this._gradientMin; + } + get gradientMax() { + return this._gradientMax; + } + get gradientXMin() { + return this._gradientXMin; + } + get gradientXMax() { + return this._gradientXMax; + } + get gradientYMin() { + return this._gradientYMin; + } + get gradientYMax() { + return this._gradientYMax; + } + get gradientZMin() { + return this._gradientZMin; + } + get gradientZMax() { + return this._gradientZMax; + } + getMaxSizeInGradient(meshMode = false) { + var i, n; + var maxSize = -Number.MAX_VALUE; + switch (this._type) { + case 0: + if (this._separateAxes) { + for (i = 0, n = this._gradientX.gradientCount; i < n; i++) + maxSize = Math.max(maxSize, this._gradientX.getValueByIndex(i)); + for (i = 0, n = this._gradientY.gradientCount; i < n; i++) + maxSize = Math.max(maxSize, this._gradientY.getValueByIndex(i)); + if (meshMode) { + for (i = 0, n = this._gradientZ.gradientCount; i < n; i++) { + maxSize = Math.max(maxSize, this._gradientZ.getValueByIndex(i)); + } + } + } + else { + for (i = 0, n = this._gradient.gradientCount; i < n; i++) + maxSize = Math.max(maxSize, this._gradient.getValueByIndex(i)); + } + break; + case 1: + if (this._separateAxes) { + maxSize = Math.max(this._constantMinSeparate.x, this._constantMaxSeparate.x); + maxSize = Math.max(maxSize, this._constantMinSeparate.y); + if (meshMode) { + maxSize = maxSize = Math.max(maxSize, this._constantMaxSeparate.z); + } + } + else { + maxSize = Math.max(this._constantMin, this._constantMax); + } + break; + case 2: + if (this._separateAxes) { + for (i = 0, n = this._gradientXMin.gradientCount; i < n; i++) + maxSize = Math.max(maxSize, this._gradientXMin.getValueByIndex(i)); + for (i = 0, n = this._gradientXMax.gradientCount; i < n; i++) + maxSize = Math.max(maxSize, this._gradientXMax.getValueByIndex(i)); + for (i = 0, n = this._gradientYMin.gradientCount; i < n; i++) + maxSize = Math.max(maxSize, this._gradientYMin.getValueByIndex(i)); + for (i = 0, n = this._gradientZMax.gradientCount; i < n; i++) + maxSize = Math.max(maxSize, this._gradientZMax.getValueByIndex(i)); + if (meshMode) { + for (i = 0, n = this._gradientZMin.gradientCount; i < n; i++) { + maxSize = Math.max(maxSize, this._gradientZMin.getValueByIndex(i)); + } + for (i = 0, n = this._gradientZMax.gradientCount; i < n; i++) { + maxSize = Math.max(maxSize, this._gradientZMax.getValueByIndex(i)); + } + } + } + else { + for (i = 0, n = this._gradientMin.gradientCount; i < n; i++) + maxSize = Math.max(maxSize, this._gradientMin.getValueByIndex(i)); + for (i = 0, n = this._gradientMax.gradientCount; i < n; i++) + maxSize = Math.max(maxSize, this._gradientMax.getValueByIndex(i)); + } + break; + } + return maxSize; + } + cloneTo(destObject) { + var destGradientSize = destObject; + destGradientSize._type = this._type; + destGradientSize._separateAxes = this._separateAxes; + this._gradient.cloneTo(destGradientSize._gradient); + this._gradientX.cloneTo(destGradientSize._gradientX); + this._gradientY.cloneTo(destGradientSize._gradientY); + this._gradientZ.cloneTo(destGradientSize._gradientZ); + destGradientSize._constantMin = this._constantMin; + destGradientSize._constantMax = this._constantMax; + this._constantMinSeparate.cloneTo(destGradientSize._constantMinSeparate); + this._constantMaxSeparate.cloneTo(destGradientSize._constantMaxSeparate); + this._gradientMin.cloneTo(destGradientSize._gradientMin); + this._gradientMax.cloneTo(destGradientSize._gradientMax); + this._gradientXMin.cloneTo(destGradientSize._gradientXMin); + this._gradientXMax.cloneTo(destGradientSize._gradientXMax); + this._gradientYMin.cloneTo(destGradientSize._gradientYMin); + this._gradientYMax.cloneTo(destGradientSize._gradientYMax); + this._gradientZMin.cloneTo(destGradientSize._gradientZMin); + this._gradientZMax.cloneTo(destGradientSize._gradientZMax); + } + clone() { + var destGradientSize = new GradientSize(); + this.cloneTo(destGradientSize); + return destGradientSize; + } + } + + class GradientVelocity { + constructor() { + this._type = 0; + this._constant = null; + this._gradientX = null; + this._gradientY = null; + this._gradientZ = null; + this._constantMin = null; + this._constantMax = null; + this._gradientXMin = null; + this._gradientXMax = null; + this._gradientYMin = null; + this._gradientYMax = null; + this._gradientZMin = null; + this._gradientZMax = null; + } + static createByConstant(constant) { + var gradientVelocity = new GradientVelocity(); + gradientVelocity._type = 0; + gradientVelocity._constant = constant; + return gradientVelocity; + } + static createByGradient(gradientX, gradientY, gradientZ) { + var gradientVelocity = new GradientVelocity(); + gradientVelocity._type = 1; + gradientVelocity._gradientX = gradientX; + gradientVelocity._gradientY = gradientY; + gradientVelocity._gradientZ = gradientZ; + return gradientVelocity; + } + static createByRandomTwoConstant(constantMin, constantMax) { + var gradientVelocity = new GradientVelocity(); + gradientVelocity._type = 2; + gradientVelocity._constantMin = constantMin; + gradientVelocity._constantMax = constantMax; + return gradientVelocity; + } + static createByRandomTwoGradient(gradientXMin, gradientXMax, gradientYMin, gradientYMax, gradientZMin, gradientZMax) { + var gradientVelocity = new GradientVelocity(); + gradientVelocity._type = 3; + gradientVelocity._gradientXMin = gradientXMin; + gradientVelocity._gradientXMax = gradientXMax; + gradientVelocity._gradientYMin = gradientYMin; + gradientVelocity._gradientYMax = gradientYMax; + gradientVelocity._gradientZMin = gradientZMin; + gradientVelocity._gradientZMax = gradientZMax; + return gradientVelocity; + } + get type() { + return this._type; + } + get constant() { + return this._constant; + } + get gradientX() { + return this._gradientX; + } + get gradientY() { + return this._gradientY; + } + get gradientZ() { + return this._gradientZ; + } + get constantMin() { + return this._constantMin; + } + get constantMax() { + return this._constantMax; + } + get gradientXMin() { + return this._gradientXMin; + } + get gradientXMax() { + return this._gradientXMax; + } + get gradientYMin() { + return this._gradientYMin; + } + get gradientYMax() { + return this._gradientYMax; + } + get gradientZMin() { + return this._gradientZMin; + } + get gradientZMax() { + return this._gradientZMax; + } + cloneTo(destObject) { + var destGradientVelocity = destObject; + destGradientVelocity._type = this._type; + this._constant.cloneTo(destGradientVelocity._constant); + this._gradientX.cloneTo(destGradientVelocity._gradientX); + this._gradientY.cloneTo(destGradientVelocity._gradientY); + this._gradientZ.cloneTo(destGradientVelocity._gradientZ); + this._constantMin.cloneTo(destGradientVelocity._constantMin); + this._constantMax.cloneTo(destGradientVelocity._constantMax); + this._gradientXMin.cloneTo(destGradientVelocity._gradientXMin); + this._gradientXMax.cloneTo(destGradientVelocity._gradientXMax); + this._gradientYMin.cloneTo(destGradientVelocity._gradientYMin); + this._gradientYMax.cloneTo(destGradientVelocity._gradientYMax); + this._gradientZMin.cloneTo(destGradientVelocity._gradientZMin); + this._gradientZMax.cloneTo(destGradientVelocity._gradientZMax); + } + clone() { + var destGradientVelocity = new GradientVelocity(); + this.cloneTo(destGradientVelocity); + return destGradientVelocity; + } + } + + class RotationOverLifetime { + constructor(angularVelocity) { + this._angularVelocity = angularVelocity; + } + get angularVelocity() { + return this._angularVelocity; + } + cloneTo(destObject) { + var destRotationOverLifetime = destObject; + this._angularVelocity.cloneTo(destRotationOverLifetime._angularVelocity); + destRotationOverLifetime.enable = this.enable; + } + clone() { + var destAngularVelocity; + switch (this._angularVelocity.type) { + case 0: + if (this._angularVelocity.separateAxes) + destAngularVelocity = GradientAngularVelocity.createByConstantSeparate(this._angularVelocity.constantSeparate.clone()); + else + destAngularVelocity = GradientAngularVelocity.createByConstant(this._angularVelocity.constant); + break; + case 1: + if (this._angularVelocity.separateAxes) + destAngularVelocity = GradientAngularVelocity.createByGradientSeparate(this._angularVelocity.gradientX.clone(), this._angularVelocity.gradientY.clone(), this._angularVelocity.gradientZ.clone()); + else + destAngularVelocity = GradientAngularVelocity.createByGradient(this._angularVelocity.gradient.clone()); + break; + case 2: + if (this._angularVelocity.separateAxes) + destAngularVelocity = GradientAngularVelocity.createByRandomTwoConstantSeparate(this._angularVelocity.constantMinSeparate.clone(), this._angularVelocity.constantMaxSeparate.clone()); + else + destAngularVelocity = GradientAngularVelocity.createByRandomTwoConstant(this._angularVelocity.constantMin, this._angularVelocity.constantMax); + break; + case 3: + if (this._angularVelocity.separateAxes) + destAngularVelocity = GradientAngularVelocity.createByRandomTwoGradientSeparate(this._angularVelocity.gradientXMin.clone(), this._angularVelocity.gradientYMin.clone(), this._angularVelocity.gradientZMin.clone(), this._angularVelocity.gradientWMin.clone(), this._angularVelocity.gradientXMax.clone(), this._angularVelocity.gradientYMax.clone(), this._angularVelocity.gradientZMax.clone(), this._angularVelocity.gradientWMax.clone()); + else + destAngularVelocity = GradientAngularVelocity.createByRandomTwoGradient(this._angularVelocity.gradientMin.clone(), this._angularVelocity.gradientMax.clone()); + break; + } + var destRotationOverLifetime = new RotationOverLifetime(destAngularVelocity); + destRotationOverLifetime.enable = this.enable; + return destRotationOverLifetime; + } + } + + (function (ParticleSystemShapeType) { + ParticleSystemShapeType[ParticleSystemShapeType["Box"] = 0] = "Box"; + ParticleSystemShapeType[ParticleSystemShapeType["Circle"] = 1] = "Circle"; + ParticleSystemShapeType[ParticleSystemShapeType["Cone"] = 2] = "Cone"; + ParticleSystemShapeType[ParticleSystemShapeType["Hemisphere"] = 3] = "Hemisphere"; + ParticleSystemShapeType[ParticleSystemShapeType["Sphere"] = 4] = "Sphere"; + })(exports.ParticleSystemShapeType || (exports.ParticleSystemShapeType = {})); + class BaseShape { + constructor() { + this.enable = true; + this.randomDirection = 0; + } + _getShapeBoundBox(boundBox) { + throw new Error("BaseShape: must override it."); + } + _getSpeedBoundBox(boundBox) { + throw new Error("BaseShape: must override it."); + } + generatePositionAndDirection(position, direction, rand = null, randomSeeds = null) { + throw new Error("BaseShape: must override it."); + } + _calculateProceduralBounds(boundBox, emitterPosScale, minMaxBounds) { + this._getShapeBoundBox(boundBox); + var min = boundBox.min; + var max = boundBox.max; + Vector3.multiply(min, emitterPosScale, min); + Vector3.multiply(max, emitterPosScale, max); + var speedBounds = new BoundBox(new Vector3(), new Vector3()); + if (this.randomDirection) { + speedBounds.min = new Vector3(-1, -1, -1); + speedBounds.max = new Vector3(1, 1, 1); + } + else { + this._getSpeedBoundBox(speedBounds); + } + var maxSpeedBound = new BoundBox(new Vector3(), new Vector3()); + var maxSpeedMin = maxSpeedBound.min; + var maxSpeedMax = maxSpeedBound.max; + Vector3.scale(speedBounds.min, minMaxBounds.y, maxSpeedMin); + Vector3.scale(speedBounds.max, minMaxBounds.y, maxSpeedMax); + Vector3.add(boundBox.min, maxSpeedMin, maxSpeedMin); + Vector3.add(boundBox.max, maxSpeedMax, maxSpeedMax); + Vector3.min(boundBox.min, maxSpeedMin, boundBox.min); + Vector3.max(boundBox.max, maxSpeedMin, boundBox.max); + var minSpeedBound = new BoundBox(new Vector3(), new Vector3()); + var minSpeedMin = minSpeedBound.min; + var minSpeedMax = minSpeedBound.max; + Vector3.scale(speedBounds.min, minMaxBounds.x, minSpeedMin); + Vector3.scale(speedBounds.max, minMaxBounds.x, minSpeedMax); + Vector3.min(minSpeedBound.min, minSpeedMax, maxSpeedMin); + Vector3.max(minSpeedBound.min, minSpeedMax, maxSpeedMax); + Vector3.min(boundBox.min, maxSpeedMin, boundBox.min); + Vector3.max(boundBox.max, maxSpeedMin, boundBox.max); + } + cloneTo(destObject) { + var destShape = destObject; + destShape.enable = this.enable; + } + clone() { + var destShape = new BaseShape(); + this.cloneTo(destShape); + return destShape; + } + } + + class ShapeUtils { + static _randomPointUnitArcCircle(arc, out, rand = null) { + var angle; + if (rand) + angle = rand.getFloat() * arc; + else + angle = Math.random() * arc; + out.x = Math.cos(angle); + out.y = Math.sin(angle); + } + static _randomPointInsideUnitArcCircle(arc, out, rand = null) { + ShapeUtils._randomPointUnitArcCircle(arc, out, rand); + var range; + if (rand) + range = Math.pow(rand.getFloat(), 1.0 / 2.0); + else + range = Math.pow(Math.random(), 1.0 / 2.0); + out.x = out.x * range; + out.y = out.y * range; + } + static _randomPointUnitCircle(out, rand = null) { + var angle; + if (rand) + angle = rand.getFloat() * Math.PI * 2; + else + angle = Math.random() * Math.PI * 2; + out.x = Math.cos(angle); + out.y = Math.sin(angle); + } + static _randomPointInsideUnitCircle(out, rand = null) { + ShapeUtils._randomPointUnitCircle(out); + var range; + if (rand) + range = Math.pow(rand.getFloat(), 1.0 / 2.0); + else + range = Math.pow(Math.random(), 1.0 / 2.0); + out.x = out.x * range; + out.y = out.y * range; + } + static _randomPointUnitSphere(out, rand = null) { + var z; + var a; + if (rand) { + z = out.z = rand.getFloat() * 2 - 1.0; + a = rand.getFloat() * Math.PI * 2; + } + else { + z = out.z = Math.random() * 2 - 1.0; + a = Math.random() * Math.PI * 2; + } + var r = Math.sqrt(1.0 - z * z); + out.x = r * Math.cos(a); + out.y = r * Math.sin(a); + } + static _randomPointInsideUnitSphere(out, rand = null) { + ShapeUtils._randomPointUnitSphere(out); + var range; + if (rand) + range = Math.pow(rand.getFloat(), 1.0 / 3.0); + else + range = Math.pow(Math.random(), 1.0 / 3.0); + out.x = out.x * range; + out.y = out.y * range; + out.z = out.z * range; + } + static _randomPointInsideHalfUnitBox(out, rand = null) { + if (rand) { + out.x = (rand.getFloat() - 0.5); + out.y = (rand.getFloat() - 0.5); + out.z = (rand.getFloat() - 0.5); + } + else { + out.x = (Math.random() - 0.5); + out.y = (Math.random() - 0.5); + out.z = (Math.random() - 0.5); + } + } + constructor() { + } + } + + class BoxShape extends BaseShape { + constructor() { + super(); + this.shapeType = exports.ParticleSystemShapeType.Box; + this.x = 1.0; + this.y = 1.0; + this.z = 1.0; + } + _getShapeBoundBox(boundBox) { + var min = boundBox.min; + min.x = -this.x * 0.5; + min.y = -this.y * 0.5; + min.z = -this.z * 0.5; + var max = boundBox.max; + max.x = this.x * 0.5; + max.y = this.y * 0.5; + max.z = this.z * 0.5; + } + _getSpeedBoundBox(boundBox) { + var min = boundBox.min; + min.x = 0.0; + min.y = 0.0; + min.z = 0.0; + var max = boundBox.max; + max.x = 0.0; + max.y = 1.0; + max.z = 0.0; + } + generatePositionAndDirection(position, direction, rand = null, randomSeeds = null) { + if (rand) { + rand.seed = randomSeeds[16]; + ShapeUtils._randomPointInsideHalfUnitBox(position, rand); + randomSeeds[16] = rand.seed; + } + else { + ShapeUtils._randomPointInsideHalfUnitBox(position); + } + position.x = this.x * position.x; + position.y = this.y * position.y; + position.z = this.z * position.z; + if (this.randomDirection) { + if (rand) { + rand.seed = randomSeeds[17]; + ShapeUtils._randomPointUnitSphere(direction, rand); + randomSeeds[17] = rand.seed; + } + else { + ShapeUtils._randomPointUnitSphere(direction); + } + } + else { + direction.x = 0.0; + direction.y = 0.0; + direction.z = 1.0; + } + } + cloneTo(destObject) { + super.cloneTo(destObject); + var destShape = destObject; + destShape.x = this.x; + destShape.y = this.y; + destShape.z = this.z; + destShape.randomDirection = this.randomDirection; + } + clone() { + var destShape = new BoxShape(); + this.cloneTo(destShape); + return destShape; + } + } + + class CircleShape extends BaseShape { + constructor() { + super(); + this.shapeType = exports.ParticleSystemShapeType.Circle; + this.radius = 1.0; + this.arc = 360.0 / 180.0 * Math.PI; + this.emitFromEdge = false; + } + _getShapeBoundBox(boundBox) { + var min = boundBox.min; + min.x = min.z = -this.radius; + min.y = 0; + var max = boundBox.max; + max.x = max.z = this.radius; + max.y = 0; + } + _getSpeedBoundBox(boundBox) { + var min = boundBox.min; + min.x = min.y = -1; + min.z = 0; + var max = boundBox.max; + max.x = max.y = 1; + max.z = 0; + } + generatePositionAndDirection(position, direction, rand = null, randomSeeds = null) { + var positionPoint = CircleShape._tempPositionPoint; + if (rand) { + rand.seed = randomSeeds[16]; + if (this.emitFromEdge) + ShapeUtils._randomPointUnitArcCircle(this.arc, CircleShape._tempPositionPoint, rand); + else + ShapeUtils._randomPointInsideUnitArcCircle(this.arc, CircleShape._tempPositionPoint, rand); + randomSeeds[16] = rand.seed; + } + else { + if (this.emitFromEdge) + ShapeUtils._randomPointUnitArcCircle(this.arc, CircleShape._tempPositionPoint); + else + ShapeUtils._randomPointInsideUnitArcCircle(this.arc, CircleShape._tempPositionPoint); + } + position.x = -positionPoint.x; + position.y = positionPoint.y; + position.z = 0; + Vector3.scale(position, this.radius, position); + if (this.randomDirection) { + if (rand) { + rand.seed = randomSeeds[17]; + ShapeUtils._randomPointUnitSphere(direction, rand); + randomSeeds[17] = rand.seed; + } + else { + ShapeUtils._randomPointUnitSphere(direction); + } + } + else { + position.cloneTo(direction); + } + } + cloneTo(destObject) { + super.cloneTo(destObject); + var destShape = destObject; + destShape.radius = this.radius; + destShape.arc = this.arc; + destShape.emitFromEdge = this.emitFromEdge; + destShape.randomDirection = this.randomDirection; + } + clone() { + var destShape = new CircleShape(); + this.cloneTo(destShape); + return destShape; + } + } + CircleShape._tempPositionPoint = new Vector2(); + + class ConeShape extends BaseShape { + constructor() { + super(); + this.shapeType = exports.ParticleSystemShapeType.Cone; + this.angle = 25.0 / 180.0 * Math.PI; + this.radius = 1.0; + this.length = 5.0; + this.emitType = 0; + } + _getShapeBoundBox(boundBox) { + const coneRadius2 = this.radius + this.length * Math.sin(this.angle); + const coneLength = this.length * Math.cos(this.angle); + var min = boundBox.min; + min.x = min.y = -coneRadius2; + min.z = 0; + var max = boundBox.max; + max.x = max.y = coneRadius2; + max.z = coneLength; + } + _getSpeedBoundBox(boundBox) { + const sinA = Math.sin(this.angle); + var min = boundBox.min; + min.x = min.y = -sinA; + min.z = 0; + var max = boundBox.max; + max.x = max.y = sinA; + max.z = 1; + } + generatePositionAndDirection(position, direction, rand = null, randomSeeds = null) { + var positionPointE = ConeShape._tempPositionPoint; + var positionX; + var positionY; + var directionPointE; + var dirCosA = Math.cos(this.angle); + var dirSinA = Math.sin(this.angle); + switch (this.emitType) { + case 0: + if (rand) { + rand.seed = randomSeeds[16]; + ShapeUtils._randomPointInsideUnitCircle(ConeShape._tempPositionPoint, rand); + randomSeeds[16] = rand.seed; + } + else { + ShapeUtils._randomPointInsideUnitCircle(ConeShape._tempPositionPoint); + } + positionX = positionPointE.x; + positionY = positionPointE.y; + position.x = positionX * this.radius; + position.y = positionY * this.radius; + position.z = 0; + if (this.randomDirection) { + if (rand) { + rand.seed = randomSeeds[17]; + ShapeUtils._randomPointInsideUnitCircle(ConeShape._tempDirectionPoint, rand); + randomSeeds[17] = rand.seed; + } + else { + ShapeUtils._randomPointInsideUnitCircle(ConeShape._tempDirectionPoint); + } + directionPointE = ConeShape._tempDirectionPoint; + direction.x = directionPointE.x * dirSinA; + direction.y = directionPointE.y * dirSinA; + } + else { + direction.x = positionX * dirSinA; + direction.y = positionY * dirSinA; + } + direction.z = dirCosA; + break; + case 1: + if (rand) { + rand.seed = randomSeeds[16]; + ShapeUtils._randomPointUnitCircle(ConeShape._tempPositionPoint, rand); + randomSeeds[16] = rand.seed; + } + else { + ShapeUtils._randomPointUnitCircle(ConeShape._tempPositionPoint); + } + positionX = positionPointE.x; + positionY = positionPointE.y; + position.x = positionX * this.radius; + position.y = positionY * this.radius; + position.z = 0; + if (this.randomDirection) { + if (rand) { + rand.seed = randomSeeds[17]; + ShapeUtils._randomPointInsideUnitCircle(ConeShape._tempDirectionPoint, rand); + randomSeeds[17] = rand.seed; + } + else { + ShapeUtils._randomPointInsideUnitCircle(ConeShape._tempDirectionPoint); + } + directionPointE = ConeShape._tempDirectionPoint; + direction.x = directionPointE.x * dirSinA; + direction.y = directionPointE.y * dirSinA; + } + else { + direction.x = positionX * dirSinA; + direction.y = positionY * dirSinA; + } + direction.z = dirCosA; + break; + case 2: + if (rand) { + rand.seed = randomSeeds[16]; + ShapeUtils._randomPointInsideUnitCircle(ConeShape._tempPositionPoint, rand); + } + else { + ShapeUtils._randomPointInsideUnitCircle(ConeShape._tempPositionPoint); + } + positionX = positionPointE.x; + positionY = positionPointE.y; + position.x = positionX * this.radius; + position.y = positionY * this.radius; + position.z = 0; + direction.x = positionX * dirSinA; + direction.y = positionY * dirSinA; + direction.z = dirCosA; + Vector3.normalize(direction, direction); + if (rand) { + Vector3.scale(direction, this.length * rand.getFloat(), direction); + randomSeeds[16] = rand.seed; + } + else { + Vector3.scale(direction, this.length * Math.random(), direction); + } + Vector3.add(position, direction, position); + if (this.randomDirection) { + if (rand) { + rand.seed = randomSeeds[17]; + ShapeUtils._randomPointUnitSphere(direction, rand); + randomSeeds[17] = rand.seed; + } + else { + ShapeUtils._randomPointUnitSphere(direction); + } + } + break; + case 3: + if (rand) { + rand.seed = randomSeeds[16]; + ShapeUtils._randomPointUnitCircle(ConeShape._tempPositionPoint, rand); + } + else { + ShapeUtils._randomPointUnitCircle(ConeShape._tempPositionPoint); + } + positionX = positionPointE.x; + positionY = positionPointE.y; + position.x = positionX * this.radius; + position.y = positionY * this.radius; + position.z = 0; + direction.x = positionX * dirSinA; + direction.y = positionY * dirSinA; + direction.z = dirCosA; + Vector3.normalize(direction, direction); + if (rand) { + Vector3.scale(direction, this.length * rand.getFloat(), direction); + randomSeeds[16] = rand.seed; + } + else { + Vector3.scale(direction, this.length * Math.random(), direction); + } + Vector3.add(position, direction, position); + if (this.randomDirection) { + if (rand) { + rand.seed = randomSeeds[17]; + ShapeUtils._randomPointUnitSphere(direction, rand); + randomSeeds[17] = rand.seed; + } + else { + ShapeUtils._randomPointUnitSphere(direction); + } + } + break; + default: + throw new Error("ConeShape:emitType is invalid."); + } + } + cloneTo(destObject) { + super.cloneTo(destObject); + var destShape = destObject; + destShape.angle = this.angle; + destShape.radius = this.radius; + destShape.length = this.length; + destShape.emitType = this.emitType; + destShape.randomDirection = this.randomDirection; + } + clone() { + var destShape = new ConeShape(); + this.cloneTo(destShape); + return destShape; + } + } + ConeShape._tempPositionPoint = new Vector2(); + ConeShape._tempDirectionPoint = new Vector2(); + + class HemisphereShape extends BaseShape { + constructor() { + super(); + this.shapeType = exports.ParticleSystemShapeType.Hemisphere; + this.radius = 1.0; + this.emitFromShell = false; + } + _getShapeBoundBox(boundBox) { + var min = boundBox.min; + min.x = min.y = min.z = -this.radius; + var max = boundBox.max; + max.x = max.y = this.radius; + max.z = 0; + } + _getSpeedBoundBox(boundBox) { + var min = boundBox.min; + min.x = min.y = -1; + min.z = 0; + var max = boundBox.max; + max.x = max.y = max.z = 1; + } + generatePositionAndDirection(position, direction, rand = null, randomSeeds = null) { + if (rand) { + rand.seed = randomSeeds[16]; + if (this.emitFromShell) + ShapeUtils._randomPointUnitSphere(position, rand); + else + ShapeUtils._randomPointInsideUnitSphere(position, rand); + randomSeeds[16] = rand.seed; + } + else { + if (this.emitFromShell) + ShapeUtils._randomPointUnitSphere(position); + else + ShapeUtils._randomPointInsideUnitSphere(position); + } + Vector3.scale(position, this.radius, position); + var z = position.z; + (z < 0.0) && (position.z = z * -1.0); + if (this.randomDirection) { + if (rand) { + rand.seed = randomSeeds[17]; + ShapeUtils._randomPointUnitSphere(direction, rand); + randomSeeds[17] = rand.seed; + } + else { + ShapeUtils._randomPointUnitSphere(direction); + } + } + else { + position.cloneTo(direction); + } + } + cloneTo(destObject) { + super.cloneTo(destObject); + var destShape = destObject; + destShape.radius = this.radius; + destShape.emitFromShell = this.emitFromShell; + destShape.randomDirection = this.randomDirection; + } + clone() { + var destShape = new HemisphereShape(); + this.cloneTo(destShape); + return destShape; + } + } + + class SphereShape extends BaseShape { + constructor() { + super(); + this.shapeType = exports.ParticleSystemShapeType.Sphere; + this.radius = 1.0; + this.emitFromShell = false; + } + _getShapeBoundBox(boundBox) { + var min = boundBox.min; + min.x = min.y = min.z = -this.radius; + var max = boundBox.max; + max.x = max.y = max.z = this.radius; + } + _getSpeedBoundBox(boundBox) { + var min = boundBox.min; + min.x = min.y = min.z = -1; + var max = boundBox.max; + max.x = max.y = max.z = 1; + } + generatePositionAndDirection(position, direction, rand = null, randomSeeds = null) { + if (rand) { + rand.seed = randomSeeds[16]; + if (this.emitFromShell) + ShapeUtils._randomPointUnitSphere(position, rand); + else + ShapeUtils._randomPointInsideUnitSphere(position, rand); + randomSeeds[16] = rand.seed; + } + else { + if (this.emitFromShell) + ShapeUtils._randomPointUnitSphere(position); + else + ShapeUtils._randomPointInsideUnitSphere(position); + } + Vector3.scale(position, this.radius, position); + if (this.randomDirection) { + if (rand) { + rand.seed = randomSeeds[17]; + ShapeUtils._randomPointUnitSphere(direction, rand); + randomSeeds[17] = rand.seed; + } + else { + ShapeUtils._randomPointUnitSphere(direction); + } + } + else { + position.cloneTo(direction); + } + } + cloneTo(destObject) { + super.cloneTo(destObject); + var destShape = destObject; + destShape.radius = this.radius; + destShape.emitFromShell = this.emitFromShell; + destShape.randomDirection = this.randomDirection; + } + clone() { + var destShape = new SphereShape(); + this.cloneTo(destShape); + return destShape; + } + } + + class SizeOverLifetime { + constructor(size) { + this._size = size; + } + get size() { + return this._size; + } + cloneTo(destObject) { + var destSizeOverLifetime = destObject; + this._size.cloneTo(destSizeOverLifetime._size); + destSizeOverLifetime.enable = this.enable; + } + clone() { + var destSize; + switch (this._size.type) { + case 0: + if (this._size.separateAxes) + destSize = GradientSize.createByGradientSeparate(this._size.gradientX.clone(), this._size.gradientY.clone(), this._size.gradientZ.clone()); + else + destSize = GradientSize.createByGradient(this._size.gradient.clone()); + break; + case 1: + if (this._size.separateAxes) + destSize = GradientSize.createByRandomTwoConstantSeparate(this._size.constantMinSeparate.clone(), this._size.constantMaxSeparate.clone()); + else + destSize = GradientSize.createByRandomTwoConstant(this._size.constantMin, this._size.constantMax); + break; + case 2: + if (this._size.separateAxes) + destSize = GradientSize.createByRandomTwoGradientSeparate(this._size.gradientXMin.clone(), this._size.gradientYMin.clone(), this._size.gradientZMin.clone(), this._size.gradientXMax.clone(), this._size.gradientYMax.clone(), this._size.gradientZMax.clone()); + else + destSize = GradientSize.createByRandomTwoGradient(this._size.gradientMin.clone(), this._size.gradientMax.clone()); + break; + } + var destSizeOverLifetime = new SizeOverLifetime(destSize); + destSizeOverLifetime.enable = this.enable; + return destSizeOverLifetime; + } + } + + class StartFrame { + constructor() { + this._type = 0; + this._constant = 0; + this._constantMin = 0; + this._constantMax = 0; + } + static createByConstant(constant = 0) { + var rotationOverLifetime = new StartFrame(); + rotationOverLifetime._type = 0; + rotationOverLifetime._constant = constant; + return rotationOverLifetime; + } + static createByRandomTwoConstant(constantMin = 0, constantMax = 0) { + var rotationOverLifetime = new StartFrame(); + rotationOverLifetime._type = 1; + rotationOverLifetime._constantMin = constantMin; + rotationOverLifetime._constantMax = constantMax; + return rotationOverLifetime; + } + get type() { + return this._type; + } + get constant() { + return this._constant; + } + get constantMin() { + return this._constantMin; + } + get constantMax() { + return this._constantMax; + } + cloneTo(destObject) { + var destStartFrame = destObject; + destStartFrame._type = this._type; + destStartFrame._constant = this._constant; + destStartFrame._constantMin = this._constantMin; + destStartFrame._constantMax = this._constantMax; + } + clone() { + var destStartFrame = new StartFrame(); + this.cloneTo(destStartFrame); + return destStartFrame; + } + } + + class TextureSheetAnimation { + constructor(frame, startFrame) { + this.type = 0; + this.randomRow = false; + this.rowIndex = 0; + this.cycles = 0; + this.enableUVChannels = 0; + this.enable = false; + this.tiles = new Vector2(1, 1); + this.type = 0; + this.randomRow = true; + this.rowIndex = 0; + this.cycles = 1; + this.enableUVChannels = 1; + this._frame = frame; + this._startFrame = startFrame; + } + get frame() { + return this._frame; + } + get startFrame() { + return this._startFrame; + } + cloneTo(destObject) { + var destTextureSheetAnimation = destObject; + this.tiles.cloneTo(destTextureSheetAnimation.tiles); + destTextureSheetAnimation.type = this.type; + destTextureSheetAnimation.randomRow = this.randomRow; + destTextureSheetAnimation.rowIndex = this.rowIndex; + destTextureSheetAnimation.cycles = this.cycles; + destTextureSheetAnimation.enableUVChannels = this.enableUVChannels; + destTextureSheetAnimation.enable = this.enable; + this._frame.cloneTo(destTextureSheetAnimation._frame); + this._startFrame.cloneTo(destTextureSheetAnimation._startFrame); + } + clone() { + var destFrame; + switch (this._frame.type) { + case 0: + destFrame = FrameOverTime.createByConstant(this._frame.constant); + break; + case 1: + destFrame = FrameOverTime.createByOverTime(this._frame.frameOverTimeData.clone()); + break; + case 2: + destFrame = FrameOverTime.createByRandomTwoConstant(this._frame.constantMin, this._frame.constantMax); + break; + case 3: + destFrame = FrameOverTime.createByRandomTwoOverTime(this._frame.frameOverTimeDataMin.clone(), this._frame.frameOverTimeDataMax.clone()); + break; + } + var destStartFrame; + switch (this._startFrame.type) { + case 0: + destStartFrame = StartFrame.createByConstant(this._startFrame.constant); + break; + case 1: + destStartFrame = StartFrame.createByRandomTwoConstant(this._startFrame.constantMin, this._startFrame.constantMax); + break; + } + var destTextureSheetAnimation = new TextureSheetAnimation(destFrame, destStartFrame); + this.cloneTo(destTextureSheetAnimation); + return destTextureSheetAnimation; + } + } + + class VelocityOverLifetime { + constructor(velocity) { + this.enable = false; + this.space = 0; + this._velocity = velocity; + } + get velocity() { + return this._velocity; + } + cloneTo(destObject) { + var destVelocityOverLifetime = destObject; + this._velocity.cloneTo(destVelocityOverLifetime._velocity); + destVelocityOverLifetime.enable = this.enable; + destVelocityOverLifetime.space = this.space; + } + clone() { + var destVelocity; + switch (this._velocity.type) { + case 0: + destVelocity = GradientVelocity.createByConstant(this._velocity.constant.clone()); + break; + case 1: + destVelocity = GradientVelocity.createByGradient(this._velocity.gradientX.clone(), this._velocity.gradientY.clone(), this._velocity.gradientZ.clone()); + break; + case 2: + destVelocity = GradientVelocity.createByRandomTwoConstant(this._velocity.constantMin.clone(), this._velocity.constantMax.clone()); + break; + case 3: + destVelocity = GradientVelocity.createByRandomTwoGradient(this._velocity.gradientXMin.clone(), this._velocity.gradientXMax.clone(), this._velocity.gradientYMin.clone(), this._velocity.gradientYMax.clone(), this._velocity.gradientZMin.clone(), this._velocity.gradientZMax.clone()); + break; + } + var destVelocityOverLifetime = new VelocityOverLifetime(destVelocity); + destVelocityOverLifetime.enable = this.enable; + destVelocityOverLifetime.space = this.space; + return destVelocityOverLifetime; + } + } + + class ShuriKenParticle3DShaderDeclaration { + } + ShuriKenParticle3DShaderDeclaration.WORLDPOSITION = Shader3D.propertyNameToID("u_WorldPosition"); + ShuriKenParticle3DShaderDeclaration.WORLDROTATION = Shader3D.propertyNameToID("u_WorldRotation"); + ShuriKenParticle3DShaderDeclaration.POSITIONSCALE = Shader3D.propertyNameToID("u_PositionScale"); + ShuriKenParticle3DShaderDeclaration.SIZESCALE = Shader3D.propertyNameToID("u_SizeScale"); + ShuriKenParticle3DShaderDeclaration.SCALINGMODE = Shader3D.propertyNameToID("u_ScalingMode"); + ShuriKenParticle3DShaderDeclaration.GRAVITY = Shader3D.propertyNameToID("u_Gravity"); + ShuriKenParticle3DShaderDeclaration.THREEDSTARTROTATION = Shader3D.propertyNameToID("u_ThreeDStartRotation"); + ShuriKenParticle3DShaderDeclaration.STRETCHEDBILLBOARDLENGTHSCALE = Shader3D.propertyNameToID("u_StretchedBillboardLengthScale"); + ShuriKenParticle3DShaderDeclaration.STRETCHEDBILLBOARDSPEEDSCALE = Shader3D.propertyNameToID("u_StretchedBillboardSpeedScale"); + ShuriKenParticle3DShaderDeclaration.SIMULATIONSPACE = Shader3D.propertyNameToID("u_SimulationSpace"); + ShuriKenParticle3DShaderDeclaration.CURRENTTIME = Shader3D.propertyNameToID("u_CurrentTime"); + ShuriKenParticle3DShaderDeclaration.VOLVELOCITYCONST = Shader3D.propertyNameToID("u_VOLVelocityConst"); + ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTX = Shader3D.propertyNameToID("u_VOLVelocityGradientX"); + ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTY = Shader3D.propertyNameToID("u_VOLVelocityGradientY"); + ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTZ = Shader3D.propertyNameToID("u_VOLVelocityGradientZ"); + ShuriKenParticle3DShaderDeclaration.VOLVELOCITYCONSTMAX = Shader3D.propertyNameToID("u_VOLVelocityConstMax"); + ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTXMAX = Shader3D.propertyNameToID("u_VOLVelocityGradientMaxX"); + ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTYMAX = Shader3D.propertyNameToID("u_VOLVelocityGradientMaxY"); + ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTZMAX = Shader3D.propertyNameToID("u_VOLVelocityGradientMaxZ"); + ShuriKenParticle3DShaderDeclaration.VOLSPACETYPE = Shader3D.propertyNameToID("u_VOLSpaceType"); + ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTALPHAS = Shader3D.propertyNameToID("u_ColorOverLifeGradientAlphas"); + ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTCOLORS = Shader3D.propertyNameToID("u_ColorOverLifeGradientColors"); + ShuriKenParticle3DShaderDeclaration.MAXCOLOROVERLIFEGRADIENTALPHAS = Shader3D.propertyNameToID("u_MaxColorOverLifeGradientAlphas"); + ShuriKenParticle3DShaderDeclaration.MAXCOLOROVERLIFEGRADIENTCOLORS = Shader3D.propertyNameToID("u_MaxColorOverLifeGradientColors"); + ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENT = Shader3D.propertyNameToID("u_SOLSizeGradient"); + ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTX = Shader3D.propertyNameToID("u_SOLSizeGradientX"); + ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTY = Shader3D.propertyNameToID("u_SOLSizeGradientY"); + ShuriKenParticle3DShaderDeclaration.SOLSizeGradientZ = Shader3D.propertyNameToID("u_SOLSizeGradientZ"); + ShuriKenParticle3DShaderDeclaration.SOLSizeGradientMax = Shader3D.propertyNameToID("u_SOLSizeGradientMax"); + ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTXMAX = Shader3D.propertyNameToID("u_SOLSizeGradientMaxX"); + ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTYMAX = Shader3D.propertyNameToID("u_SOLSizeGradientMaxY"); + ShuriKenParticle3DShaderDeclaration.SOLSizeGradientZMAX = Shader3D.propertyNameToID("u_SOLSizeGradientMaxZ"); + ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONST = Shader3D.propertyNameToID("u_ROLAngularVelocityConst"); + ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONSTSEPRARATE = Shader3D.propertyNameToID("u_ROLAngularVelocityConstSeprarate"); + ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENT = Shader3D.propertyNameToID("u_ROLAngularVelocityGradient"); + ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTX = Shader3D.propertyNameToID("u_ROLAngularVelocityGradientX"); + ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTY = Shader3D.propertyNameToID("u_ROLAngularVelocityGradientY"); + ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTZ = Shader3D.propertyNameToID("u_ROLAngularVelocityGradientZ"); + ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONSTMAX = Shader3D.propertyNameToID("u_ROLAngularVelocityConstMax"); + ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONSTMAXSEPRARATE = Shader3D.propertyNameToID("u_ROLAngularVelocityConstMaxSeprarate"); + ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTMAX = Shader3D.propertyNameToID("u_ROLAngularVelocityGradientMax"); + ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTXMAX = Shader3D.propertyNameToID("u_ROLAngularVelocityGradientMaxX"); + ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTYMAX = Shader3D.propertyNameToID("u_ROLAngularVelocityGradientMaxY"); + ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTZMAX = Shader3D.propertyNameToID("u_ROLAngularVelocityGradientMaxZ"); + ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTWMAX = Shader3D.propertyNameToID("u_ROLAngularVelocityGradientMaxW"); + ShuriKenParticle3DShaderDeclaration.TEXTURESHEETANIMATIONCYCLES = Shader3D.propertyNameToID("u_TSACycles"); + ShuriKenParticle3DShaderDeclaration.TEXTURESHEETANIMATIONSUBUVLENGTH = Shader3D.propertyNameToID("u_TSASubUVLength"); + ShuriKenParticle3DShaderDeclaration.TEXTURESHEETANIMATIONGRADIENTUVS = Shader3D.propertyNameToID("u_TSAGradientUVs"); + ShuriKenParticle3DShaderDeclaration.TEXTURESHEETANIMATIONGRADIENTMAXUVS = Shader3D.propertyNameToID("u_TSAMaxGradientUVs"); + + class ShurikenParticleMaterial extends Material { + constructor() { + super(); + this.setShaderName("PARTICLESHURIKEN"); + this._shaderValues.setVector(ShurikenParticleMaterial.TINTCOLOR, new Vector4(0.5, 0.5, 0.5, 0.5)); + this._shaderValues.setVector(ShurikenParticleMaterial.TILINGOFFSET, new Vector4(1.0, 1.0, 0.0, 0.0)); + this.renderMode = ShurikenParticleMaterial.RENDERMODE_ALPHABLENDED; + } + static __initDefine__() { + ShurikenParticleMaterial.SHADERDEFINE_DIFFUSEMAP = Shader3D.getDefineByName("DIFFUSEMAP"); + ShurikenParticleMaterial.SHADERDEFINE_TINTCOLOR = Shader3D.getDefineByName("TINTCOLOR"); + ShurikenParticleMaterial.SHADERDEFINE_ADDTIVEFOG = Shader3D.getDefineByName("ADDTIVEFOG"); + } + get _TintColor() { + return this.color; + } + set _TintColor(value) { + this.color = value; + } + get _TintColorR() { + return this.color.x; + } + set _TintColorR(value) { + this.color.x = value; + } + get _TintColorG() { + return this.color.y; + } + set _TintColorG(value) { + this.color.y = value; + } + get _TintColorB() { + return this.color.z; + } + set _TintColorB(value) { + this.color.z = value; + } + get _TintColorA() { + return this.color.w; + } + set _TintColorA(value) { + this.color.w = value; + } + get _MainTex_ST() { + return this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET); + } + set _MainTex_ST(value) { + var tilOff = this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET); + tilOff.setValue(value.x, value.y, value.z, value.w); + this.tilingOffset = tilOff; + } + get _MainTex_STX() { + return this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET).x; + } + set _MainTex_STX(x) { + var tilOff = this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET); + tilOff.x = x; + this.tilingOffset = tilOff; + } + get _MainTex_STY() { + return this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET).y; + } + set _MainTex_STY(y) { + var tilOff = this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET); + tilOff.y = y; + this.tilingOffset = tilOff; + } + get _MainTex_STZ() { + return this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET).z; + } + set _MainTex_STZ(z) { + var tilOff = this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET); + tilOff.z = z; + this.tilingOffset = tilOff; + } + get _MainTex_STW() { + return this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET).w; + } + set _MainTex_STW(w) { + var tilOff = this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET); + tilOff.w = w; + this.tilingOffset = tilOff; + } + set renderMode(value) { + switch (value) { + case ShurikenParticleMaterial.RENDERMODE_ADDTIVE: + this.renderQueue = Material.RENDERQUEUE_TRANSPARENT; + this.depthWrite = false; + this.cull = RenderState.CULL_NONE; + this.blend = RenderState.BLEND_ENABLE_ALL; + this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA; + this.blendDst = RenderState.BLENDPARAM_ONE; + this.alphaTest = false; + this._shaderValues.addDefine(ShurikenParticleMaterial.SHADERDEFINE_ADDTIVEFOG); + break; + case ShurikenParticleMaterial.RENDERMODE_ALPHABLENDED: + this.renderQueue = Material.RENDERQUEUE_TRANSPARENT; + this.depthWrite = false; + this.cull = RenderState.CULL_NONE; + this.blend = RenderState.BLEND_ENABLE_ALL; + this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA; + this.blendDst = RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA; + this.alphaTest = false; + this._shaderValues.removeDefine(ShurikenParticleMaterial.SHADERDEFINE_ADDTIVEFOG); + break; + default: + throw new Error("ShurikenParticleMaterial : renderMode value error."); + } + } + get colorR() { + return this._TintColorR; + } + set colorR(value) { + this._TintColorR = value; + } + get colorG() { + return this._TintColorG; + } + set colorG(value) { + this._TintColorG = value; + } + get colorB() { + return this._TintColorB; + } + set colorB(value) { + this._TintColorB = value; + } + get colorA() { + return this._TintColorA; + } + set colorA(value) { + this._TintColorA = value; + } + get color() { + return this._shaderValues.getVector(ShurikenParticleMaterial.TINTCOLOR); + } + set color(value) { + if (value) + this._shaderValues.addDefine(ShurikenParticleMaterial.SHADERDEFINE_TINTCOLOR); + else + this._shaderValues.removeDefine(ShurikenParticleMaterial.SHADERDEFINE_TINTCOLOR); + this._shaderValues.setVector(ShurikenParticleMaterial.TINTCOLOR, value); + } + get tilingOffsetX() { + return this._MainTex_STX; + } + set tilingOffsetX(x) { + this._MainTex_STX = x; + } + get tilingOffsetY() { + return this._MainTex_STY; + } + set tilingOffsetY(y) { + this._MainTex_STY = y; + } + get tilingOffsetZ() { + return this._MainTex_STZ; + } + set tilingOffsetZ(z) { + this._MainTex_STZ = z; + } + get tilingOffsetW() { + return this._MainTex_STW; + } + set tilingOffsetW(w) { + this._MainTex_STW = w; + } + get tilingOffset() { + return this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET); + } + set tilingOffset(value) { + if (value) { + this._shaderValues.setVector(ShurikenParticleMaterial.TILINGOFFSET, value); + } + else { + this._shaderValues.getVector(ShurikenParticleMaterial.TILINGOFFSET).setValue(1.0, 1.0, 0.0, 0.0); + } + } + get texture() { + return this._shaderValues.getTexture(ShurikenParticleMaterial.DIFFUSETEXTURE); + } + set texture(value) { + if (value) + this._shaderValues.addDefine(ShurikenParticleMaterial.SHADERDEFINE_DIFFUSEMAP); + else + this._shaderValues.removeDefine(ShurikenParticleMaterial.SHADERDEFINE_DIFFUSEMAP); + this._shaderValues.setTexture(ShurikenParticleMaterial.DIFFUSETEXTURE, value); + } + clone() { + var dest = new ShurikenParticleMaterial(); + this.cloneTo(dest); + return dest; + } + } + ShurikenParticleMaterial.RENDERMODE_ALPHABLENDED = 0; + ShurikenParticleMaterial.RENDERMODE_ADDTIVE = 1; + ShurikenParticleMaterial.DIFFUSETEXTURE = Shader3D.propertyNameToID("u_texture"); + ShurikenParticleMaterial.TINTCOLOR = Shader3D.propertyNameToID("u_Tintcolor"); + ShurikenParticleMaterial.TILINGOFFSET = Shader3D.propertyNameToID("u_TilingOffset"); + + class Physics3DUtils { + constructor() { + } + static setColliderCollision(collider1, collider2, collsion) { + } + static getIColliderCollision(collider1, collider2) { + return false; + } + } + Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER = 0x1; + Physics3DUtils.COLLISIONFILTERGROUP_STATICFILTER = 0x2; + Physics3DUtils.COLLISIONFILTERGROUP_KINEMATICFILTER = 0x4; + Physics3DUtils.COLLISIONFILTERGROUP_DEBRISFILTER = 0x8; + Physics3DUtils.COLLISIONFILTERGROUP_SENSORTRIGGER = 0x10; + Physics3DUtils.COLLISIONFILTERGROUP_CHARACTERFILTER = 0x20; + Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER1 = 0x40; + Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER2 = 0x80; + Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER3 = 0x100; + Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER4 = 0x200; + Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER5 = 0x400; + Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER6 = 0x800; + Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER7 = 0x1000; + Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER8 = 0x2000; + Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER9 = 0x4000; + Physics3DUtils.COLLISIONFILTERGROUP_CUSTOMFILTER10 = 0x8000; + Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER = -1; + Physics3DUtils.gravity = new Vector3(0, -9.81, 0); + + class ShurikenParticleRenderer extends BaseRender { + constructor(owner) { + super(owner); + this._finalGravity = new Vector3(); + this._mesh = null; + this.stretchedBillboardCameraSpeedScale = 0; + this.stretchedBillboardSpeedScale = 0; + this.stretchedBillboardLengthScale = 2; + this.renderMode = 0; + this._supportOctree = false; + } + get renderMode() { + return this._renderMode; + } + set renderMode(value) { + if (this._renderMode !== value) { + var defineDatas = this._shaderValues; + switch (this._renderMode) { + case 0: + defineDatas.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_BILLBOARD); + break; + case 1: + defineDatas.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_STRETCHEDBILLBOARD); + break; + case 2: + defineDatas.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_HORIZONTALBILLBOARD); + break; + case 3: + defineDatas.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_VERTICALBILLBOARD); + break; + case 4: + defineDatas.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_MESH); + break; + } + this._renderMode = value; + switch (value) { + case 0: + defineDatas.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_BILLBOARD); + break; + case 1: + defineDatas.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_STRETCHEDBILLBOARD); + break; + case 2: + defineDatas.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_HORIZONTALBILLBOARD); + break; + case 3: + defineDatas.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_VERTICALBILLBOARD); + break; + case 4: + defineDatas.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_MESH); + break; + default: + throw new Error("ShurikenParticleRender: unknown renderMode Value."); + } + var parSys = this._owner.particleSystem; + (parSys) && (parSys._initBufferDatas()); + } + } + get mesh() { + return this._mesh; + } + set mesh(value) { + if (this._mesh !== value) { + (this._mesh) && (this._mesh._removeReference()); + this._mesh = value; + (value) && (value._addReference()); + this._owner.particleSystem._initBufferDatas(); + } + } + _calculateBoundingBox() { + var particleSystem = this._owner.particleSystem; + var bounds; + if (particleSystem._useCustomBounds) { + bounds = particleSystem.customBounds; + bounds._tranform(this._owner.transform.worldMatrix, this._bounds); + } + else if (particleSystem._simulationSupported()) { + particleSystem._generateBounds(); + bounds = particleSystem._bounds; + bounds._tranform(this._owner.transform.worldMatrix, this._bounds); + if (particleSystem.gravityModifier != 0) { + var max = this._bounds.getMax(); + var min = this._bounds.getMin(); + var gravityOffset = particleSystem._gravityOffset; + max.y -= gravityOffset.x; + min.y -= gravityOffset.y; + this._bounds.setMax(max); + this._bounds.setMin(min); + } + } + else { + var min = this._bounds.getMin(); + min.setValue(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE); + this._bounds.setMin(min); + var max = this._bounds.getMax(); + max.setValue(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE); + this._bounds.setMax(max); + } + } + _needRender(boundFrustum, context) { + if (boundFrustum) { + if (boundFrustum.intersects(this.bounds._getBoundBox())) { + if (this._owner.particleSystem.isAlive) + return true; + else + return false; + } + else { + return false; + } + } + else { + return true; + } + } + _renderUpdate(context, transfrom) { + var particleSystem = this._owner.particleSystem; + var sv = this._shaderValues; + var transform = this._owner.transform; + switch (particleSystem.simulationSpace) { + case 0: + break; + case 1: + sv.setVector3(ShuriKenParticle3DShaderDeclaration.WORLDPOSITION, transform.position); + sv.setQuaternion(ShuriKenParticle3DShaderDeclaration.WORLDROTATION, transform.rotation); + break; + default: + throw new Error("ShurikenParticleMaterial: SimulationSpace value is invalid."); + } + switch (particleSystem.scaleMode) { + case 0: + var scale = transform.getWorldLossyScale(); + sv.setVector3(ShuriKenParticle3DShaderDeclaration.POSITIONSCALE, scale); + sv.setVector3(ShuriKenParticle3DShaderDeclaration.SIZESCALE, scale); + break; + case 1: + var localScale = transform.localScale; + sv.setVector3(ShuriKenParticle3DShaderDeclaration.POSITIONSCALE, localScale); + sv.setVector3(ShuriKenParticle3DShaderDeclaration.SIZESCALE, localScale); + break; + case 2: + sv.setVector3(ShuriKenParticle3DShaderDeclaration.POSITIONSCALE, transform.getWorldLossyScale()); + sv.setVector3(ShuriKenParticle3DShaderDeclaration.SIZESCALE, Vector3._ONE); + break; + } + Vector3.scale(Physics3DUtils.gravity, particleSystem.gravityModifier, this._finalGravity); + sv.setVector3(ShuriKenParticle3DShaderDeclaration.GRAVITY, this._finalGravity); + sv.setInt(ShuriKenParticle3DShaderDeclaration.SIMULATIONSPACE, particleSystem.simulationSpace); + sv.setBool(ShuriKenParticle3DShaderDeclaration.THREEDSTARTROTATION, particleSystem.threeDStartRotation); + sv.setInt(ShuriKenParticle3DShaderDeclaration.SCALINGMODE, particleSystem.scaleMode); + sv.setNumber(ShuriKenParticle3DShaderDeclaration.STRETCHEDBILLBOARDLENGTHSCALE, this.stretchedBillboardLengthScale); + sv.setNumber(ShuriKenParticle3DShaderDeclaration.STRETCHEDBILLBOARDSPEEDSCALE, this.stretchedBillboardSpeedScale); + sv.setNumber(ShuriKenParticle3DShaderDeclaration.CURRENTTIME, particleSystem._currentTime); + } + get bounds() { + if (this._boundsChange) { + this._calculateBoundingBox(); + this._boundsChange = false; + } + return this._bounds; + } + _destroy() { + super._destroy(); + (this._mesh) && (this._mesh._removeReference(), this._mesh = null); + } + } + + class VertexShuriKenParticle { + constructor() { + } + } + VertexShuriKenParticle.PARTICLE_CORNERTEXTURECOORDINATE0 = 5; + VertexShuriKenParticle.PARTICLE_POSITION0 = 1; + VertexShuriKenParticle.PARTICLE_COLOR0 = 2; + VertexShuriKenParticle.PARTICLE_TEXTURECOORDINATE0 = 3; + VertexShuriKenParticle.PARTICLE_SHAPEPOSITIONSTARTLIFETIME = 4; + VertexShuriKenParticle.PARTICLE_DIRECTIONTIME = 0; + VertexShuriKenParticle.PARTICLE_STARTCOLOR0 = 6; + VertexShuriKenParticle.PARTICLE_ENDCOLOR0 = 7; + VertexShuriKenParticle.PARTICLE_STARTSIZE = 8; + VertexShuriKenParticle.PARTICLE_STARTROTATION = 9; + VertexShuriKenParticle.PARTICLE_STARTSPEED = 10; + VertexShuriKenParticle.PARTICLE_RANDOM0 = 11; + VertexShuriKenParticle.PARTICLE_RANDOM1 = 12; + VertexShuriKenParticle.PARTICLE_SIMULATIONWORLDPOSTION = 13; + VertexShuriKenParticle.PARTICLE_SIMULATIONWORLDROTATION = 14; + + class VertexShurikenParticleBillboard extends VertexShuriKenParticle { + constructor(cornerTextureCoordinate, positionStartLifeTime, velocity, startColor, startSize, startRotation0, startRotation1, startRotation2, ageAddScale, time, startSpeed, randoms0, randoms1, simulationWorldPostion) { + super(); + this._cornerTextureCoordinate = cornerTextureCoordinate; + this._positionStartLifeTime = positionStartLifeTime; + this._velocity = velocity; + this._startColor = startColor; + this._startSize = startSize; + this._startRotation0 = startRotation0; + this._startRotation1 = startRotation1; + this._startRotation2 = startRotation2; + this._startLifeTime = ageAddScale; + this._time = time; + this._startSpeed = startSpeed; + this._randoms0 = randoms0; + this._randoms1 = randoms1; + this._simulationWorldPostion = simulationWorldPostion; + } + static get vertexDeclaration() { + return VertexShurikenParticleBillboard._vertexDeclaration; + } + static __init__() { + VertexShurikenParticleBillboard._vertexDeclaration = new VertexDeclaration(152, [new VertexElement(0, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_CORNERTEXTURECOORDINATE0), + new VertexElement(16, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_SHAPEPOSITIONSTARTLIFETIME), + new VertexElement(32, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_DIRECTIONTIME), + new VertexElement(48, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_STARTCOLOR0), + new VertexElement(64, VertexElementFormat.Vector3, VertexShuriKenParticle.PARTICLE_STARTSIZE), + new VertexElement(76, VertexElementFormat.Vector3, VertexShuriKenParticle.PARTICLE_STARTROTATION), + new VertexElement(88, VertexElementFormat.Single, VertexShuriKenParticle.PARTICLE_STARTSPEED), + new VertexElement(92, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_RANDOM0), + new VertexElement(108, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_RANDOM1), + new VertexElement(124, VertexElementFormat.Vector3, VertexShuriKenParticle.PARTICLE_SIMULATIONWORLDPOSTION), + new VertexElement(136, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_SIMULATIONWORLDROTATION)]); + } + get cornerTextureCoordinate() { + return this._cornerTextureCoordinate; + } + get positionStartLifeTime() { + return this._positionStartLifeTime; + } + get velocity() { + return this._velocity; + } + get startColor() { + return this._startColor; + } + get startSize() { + return this._startSize; + } + get startRotation0() { + return this._startRotation0; + } + get startRotation1() { + return this._startRotation1; + } + get startRotation2() { + return this._startRotation2; + } + get startLifeTime() { + return this._startLifeTime; + } + get time() { + return this._time; + } + get startSpeed() { + return this._startSpeed; + } + get random0() { + return this._randoms0; + } + get random1() { + return this._randoms1; + } + get simulationWorldPostion() { + return this._simulationWorldPostion; + } + } + + class VertexShurikenParticleMesh extends VertexShuriKenParticle { + constructor(cornerTextureCoordinate, positionStartLifeTime, velocity, startColor, startSize, startRotation0, startRotation1, startRotation2, ageAddScale, time, startSpeed, randoms0, randoms1, simulationWorldPostion) { + super(); + this._cornerTextureCoordinate = cornerTextureCoordinate; + this._positionStartLifeTime = positionStartLifeTime; + this._velocity = velocity; + this._startColor = startColor; + this._startSize = startSize; + this._startRotation0 = startRotation0; + this._startRotation1 = startRotation1; + this._startRotation2 = startRotation2; + this._startLifeTime = ageAddScale; + this._time = time; + this._startSpeed = startSpeed; + this._randoms0 = randoms0; + this._randoms1 = randoms1; + this._simulationWorldPostion = simulationWorldPostion; + } + static __init__() { + VertexShurikenParticleMesh._vertexDeclaration = new VertexDeclaration(172, [new VertexElement(0, VertexElementFormat.Vector3, VertexShuriKenParticle.PARTICLE_POSITION0), + new VertexElement(12, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_COLOR0), + new VertexElement(28, VertexElementFormat.Vector2, VertexShuriKenParticle.PARTICLE_TEXTURECOORDINATE0), + new VertexElement(36, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_SHAPEPOSITIONSTARTLIFETIME), + new VertexElement(52, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_DIRECTIONTIME), + new VertexElement(68, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_STARTCOLOR0), + new VertexElement(84, VertexElementFormat.Vector3, VertexShuriKenParticle.PARTICLE_STARTSIZE), + new VertexElement(96, VertexElementFormat.Vector3, VertexShuriKenParticle.PARTICLE_STARTROTATION), + new VertexElement(108, VertexElementFormat.Single, VertexShuriKenParticle.PARTICLE_STARTSPEED), + new VertexElement(112, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_RANDOM0), + new VertexElement(128, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_RANDOM1), + new VertexElement(144, VertexElementFormat.Vector3, VertexShuriKenParticle.PARTICLE_SIMULATIONWORLDPOSTION), + new VertexElement(156, VertexElementFormat.Vector4, VertexShuriKenParticle.PARTICLE_SIMULATIONWORLDROTATION)]); + } + static get vertexDeclaration() { + return VertexShurikenParticleMesh._vertexDeclaration; + } + get cornerTextureCoordinate() { + return this._cornerTextureCoordinate; + } + get position() { + return this._positionStartLifeTime; + } + get velocity() { + return this._velocity; + } + get startColor() { + return this._startColor; + } + get startSize() { + return this._startSize; + } + get startRotation0() { + return this._startRotation0; + } + get startRotation1() { + return this._startRotation1; + } + get startRotation2() { + return this._startRotation2; + } + get startLifeTime() { + return this._startLifeTime; + } + get time() { + return this._time; + } + get startSpeed() { + return this._startSpeed; + } + get random0() { + return this._randoms0; + } + get random1() { + return this._randoms1; + } + get simulationWorldPostion() { + return this._simulationWorldPostion; + } + } + + class Rand { + constructor(seed) { + this._temp = new Uint32Array(1); + this.seeds = new Uint32Array(4); + this.seeds[0] = seed; + this.seeds[1] = this.seeds[0] * 0x6C078965 + 1; + this.seeds[2] = this.seeds[1] * 0x6C078965 + 1; + this.seeds[3] = this.seeds[2] * 0x6C078965 + 1; + } + static getFloatFromInt(v) { + return (v & 0x007FFFFF) * (1.0 / 8388607.0); + } + static getByteFromInt(v) { + return (v & 0x007FFFFF) >>> 15; + } + get seed() { + return this.seeds[0]; + } + set seed(seed) { + this.seeds[0] = seed; + this.seeds[1] = this.seeds[0] * 0x6C078965 + 1; + this.seeds[2] = this.seeds[1] * 0x6C078965 + 1; + this.seeds[3] = this.seeds[2] * 0x6C078965 + 1; + } + getUint() { + this._temp[0] = this.seeds[0] ^ (this.seeds[0] << 11); + this.seeds[0] = this.seeds[1]; + this.seeds[1] = this.seeds[2]; + this.seeds[2] = this.seeds[3]; + this.seeds[3] = (this.seeds[3] ^ (this.seeds[3] >>> 19)) ^ (this._temp[0] ^ (this._temp[0] >>> 8)); + return this.seeds[3]; + } + getFloat() { + this.getUint(); + return (this.seeds[3] & 0x007FFFFF) * (1.0 / 8388607.0); + } + getSignedFloat() { + return this.getFloat() * 2.0 - 1.0; + } + } + + class Emission { + constructor() { + this._emissionRate = 10; + this._destroyed = false; + this._bursts = []; + } + set emissionRate(value) { + if (value < 0) + throw new Error("ParticleBaseShape:emissionRate value must large or equal than 0."); + this._emissionRate = value; + } + get emissionRate() { + return this._emissionRate; + } + get destroyed() { + return this._destroyed; + } + destroy() { + this._bursts = null; + this._destroyed = true; + } + getBurstsCount() { + return this._bursts.length; + } + getBurstByIndex(index) { + return this._bursts[index]; + } + addBurst(burst) { + var burstsCount = this._bursts.length; + if (burstsCount > 0) + for (var i = 0; i < burstsCount; i++) { + if (this._bursts[i].time > burst.time) + this._bursts.splice(i, 0, burst); + } + this._bursts.push(burst); + } + removeBurst(burst) { + var index = this._bursts.indexOf(burst); + if (index !== -1) { + this._bursts.splice(index, 1); + } + } + removeBurstByIndex(index) { + this._bursts.splice(index, 1); + } + clearBurst() { + this._bursts.length = 0; + } + cloneTo(destObject) { + var destEmission = destObject; + var destBursts = destEmission._bursts; + destBursts.length = this._bursts.length; + for (var i = 0, n = this._bursts.length; i < n; i++) { + var destBurst = destBursts[i]; + if (destBurst) + this._bursts[i].cloneTo(destBurst); + else + destBursts[i] = this._bursts[i].clone(); + } + destEmission._emissionRate = this._emissionRate; + destEmission.enable = this.enable; + } + clone() { + var destEmission = new Emission(); + this.cloneTo(destEmission); + return destEmission; + } + } + + class ShurikenParticleData { + constructor() { + } + static _getStartLifetimeFromGradient(startLifeTimeGradient, emissionTime) { + for (var i = 1, n = startLifeTimeGradient.gradientCount; i < n; i++) { + var key = startLifeTimeGradient.getKeyByIndex(i); + if (key >= emissionTime) { + var lastKey = startLifeTimeGradient.getKeyByIndex(i - 1); + var age = (emissionTime - lastKey) / (key - lastKey); + return Laya.MathUtil.lerp(startLifeTimeGradient.getValueByIndex(i - 1), startLifeTimeGradient.getValueByIndex(i), age); + } + } + throw new Error("ShurikenParticleData: can't get value foam startLifeTimeGradient."); + } + static _randomInvertRoationArray(rotatonE, outE, randomizeRotationDirection, rand, randomSeeds) { + var randDic; + if (rand) { + rand.seed = randomSeeds[6]; + randDic = rand.getFloat(); + randomSeeds[6] = rand.seed; + } + else { + randDic = Math.random(); + } + if (randDic < randomizeRotationDirection) { + outE.x = -rotatonE.x; + outE.y = -rotatonE.y; + outE.z = -rotatonE.z; + } + else { + outE.x = rotatonE.x; + outE.y = rotatonE.y; + outE.z = rotatonE.z; + } + } + static _randomInvertRoation(rotaton, randomizeRotationDirection, rand, randomSeeds) { + var randDic; + if (rand) { + rand.seed = randomSeeds[6]; + randDic = rand.getFloat(); + randomSeeds[6] = rand.seed; + } + else { + randDic = Math.random(); + } + if (randDic < randomizeRotationDirection) + rotaton = -rotaton; + return rotaton; + } + static create(particleSystem, particleRender) { + var autoRandomSeed = particleSystem.autoRandomSeed; + var rand = particleSystem._rand; + var randomSeeds = particleSystem._randomSeeds; + switch (particleSystem.startColorType) { + case 0: + var constantStartColor = particleSystem.startColorConstant; + ShurikenParticleData.startColor.x = constantStartColor.x; + ShurikenParticleData.startColor.y = constantStartColor.y; + ShurikenParticleData.startColor.z = constantStartColor.z; + ShurikenParticleData.startColor.w = constantStartColor.w; + break; + case 2: + if (autoRandomSeed) { + Vector4.lerp(particleSystem.startColorConstantMin, particleSystem.startColorConstantMax, Math.random(), ShurikenParticleData.startColor); + } + else { + rand.seed = randomSeeds[3]; + Vector4.lerp(particleSystem.startColorConstantMin, particleSystem.startColorConstantMax, rand.getFloat(), ShurikenParticleData.startColor); + randomSeeds[3] = rand.seed; + } + break; + } + var colorOverLifetime = particleSystem.colorOverLifetime; + if (colorOverLifetime && colorOverLifetime.enable) { + var color = colorOverLifetime.color; + switch (color.type) { + case 0: + ShurikenParticleData.startColor.x = ShurikenParticleData.startColor.x * color.constant.x; + ShurikenParticleData.startColor.y = ShurikenParticleData.startColor.y * color.constant.y; + ShurikenParticleData.startColor.z = ShurikenParticleData.startColor.z * color.constant.z; + ShurikenParticleData.startColor.w = ShurikenParticleData.startColor.w * color.constant.w; + break; + case 2: + var colorRandom; + if (autoRandomSeed) { + colorRandom = Math.random(); + } + else { + rand.seed = randomSeeds[10]; + colorRandom = rand.getFloat(); + randomSeeds[10] = rand.seed; + } + var minConstantColor = color.constantMin; + var maxConstantColor = color.constantMax; + ShurikenParticleData.startColor.x = ShurikenParticleData.startColor.x * Laya.MathUtil.lerp(minConstantColor.x, maxConstantColor.x, colorRandom); + ShurikenParticleData.startColor.y = ShurikenParticleData.startColor.y * Laya.MathUtil.lerp(minConstantColor.y, maxConstantColor.y, colorRandom); + ShurikenParticleData.startColor.z = ShurikenParticleData.startColor.z * Laya.MathUtil.lerp(minConstantColor.z, maxConstantColor.z, colorRandom); + ShurikenParticleData.startColor.w = ShurikenParticleData.startColor.w * Laya.MathUtil.lerp(minConstantColor.w, maxConstantColor.w, colorRandom); + break; + } + } + var particleSize = ShurikenParticleData.startSize; + switch (particleSystem.startSizeType) { + case 0: + if (particleSystem.threeDStartSize) { + var startSizeConstantSeparate = particleSystem.startSizeConstantSeparate; + particleSize[0] = startSizeConstantSeparate.x; + particleSize[1] = startSizeConstantSeparate.y; + particleSize[2] = startSizeConstantSeparate.z; + } + else { + particleSize[0] = particleSize[1] = particleSize[2] = particleSystem.startSizeConstant; + } + break; + case 2: + if (particleSystem.threeDStartSize) { + var startSizeConstantMinSeparate = particleSystem.startSizeConstantMinSeparate; + var startSizeConstantMaxSeparate = particleSystem.startSizeConstantMaxSeparate; + if (autoRandomSeed) { + particleSize[0] = Laya.MathUtil.lerp(startSizeConstantMinSeparate.x, startSizeConstantMaxSeparate.x, Math.random()); + particleSize[1] = Laya.MathUtil.lerp(startSizeConstantMinSeparate.y, startSizeConstantMaxSeparate.y, Math.random()); + particleSize[2] = Laya.MathUtil.lerp(startSizeConstantMinSeparate.z, startSizeConstantMaxSeparate.z, Math.random()); + } + else { + rand.seed = randomSeeds[4]; + particleSize[0] = Laya.MathUtil.lerp(startSizeConstantMinSeparate.x, startSizeConstantMaxSeparate.x, rand.getFloat()); + particleSize[1] = Laya.MathUtil.lerp(startSizeConstantMinSeparate.y, startSizeConstantMaxSeparate.y, rand.getFloat()); + particleSize[2] = Laya.MathUtil.lerp(startSizeConstantMinSeparate.z, startSizeConstantMaxSeparate.z, rand.getFloat()); + randomSeeds[4] = rand.seed; + } + } + else { + if (autoRandomSeed) { + particleSize[0] = particleSize[1] = particleSize[2] = Laya.MathUtil.lerp(particleSystem.startSizeConstantMin, particleSystem.startSizeConstantMax, Math.random()); + } + else { + rand.seed = randomSeeds[4]; + particleSize[0] = particleSize[1] = particleSize[2] = Laya.MathUtil.lerp(particleSystem.startSizeConstantMin, particleSystem.startSizeConstantMax, rand.getFloat()); + randomSeeds[4] = rand.seed; + } + } + break; + } + var sizeOverLifetime = particleSystem.sizeOverLifetime; + if (sizeOverLifetime && sizeOverLifetime.enable && sizeOverLifetime.size.type === 1) { + var size = sizeOverLifetime.size; + if (size.separateAxes) { + if (autoRandomSeed) { + particleSize[0] = particleSize[0] * Laya.MathUtil.lerp(size.constantMinSeparate.x, size.constantMaxSeparate.x, Math.random()); + particleSize[1] = particleSize[1] * Laya.MathUtil.lerp(size.constantMinSeparate.y, size.constantMaxSeparate.y, Math.random()); + particleSize[2] = particleSize[2] * Laya.MathUtil.lerp(size.constantMinSeparate.z, size.constantMaxSeparate.z, Math.random()); + } + else { + rand.seed = randomSeeds[11]; + particleSize[0] = particleSize[0] * Laya.MathUtil.lerp(size.constantMinSeparate.x, size.constantMaxSeparate.x, rand.getFloat()); + particleSize[1] = particleSize[1] * Laya.MathUtil.lerp(size.constantMinSeparate.y, size.constantMaxSeparate.y, rand.getFloat()); + particleSize[2] = particleSize[2] * Laya.MathUtil.lerp(size.constantMinSeparate.z, size.constantMaxSeparate.z, rand.getFloat()); + randomSeeds[11] = rand.seed; + } + } + else { + var randomSize; + if (autoRandomSeed) { + randomSize = Laya.MathUtil.lerp(size.constantMin, size.constantMax, Math.random()); + } + else { + rand.seed = randomSeeds[11]; + randomSize = Laya.MathUtil.lerp(size.constantMin, size.constantMax, rand.getFloat()); + randomSeeds[11] = rand.seed; + } + particleSize[0] = particleSize[0] * randomSize; + particleSize[1] = particleSize[1] * randomSize; + particleSize[2] = particleSize[2] * randomSize; + } + } + var renderMode = particleRender.renderMode; + if (renderMode !== 1) { + switch (particleSystem.startRotationType) { + case 0: + if (particleSystem.threeDStartRotation) { + var startRotationConstantSeparate = particleSystem.startRotationConstantSeparate; + var randomRotationE = ShurikenParticleData._tempVector30; + ShurikenParticleData._randomInvertRoationArray(startRotationConstantSeparate, randomRotationE, particleSystem.randomizeRotationDirection, autoRandomSeed ? null : rand, randomSeeds); + ShurikenParticleData.startRotation[0] = randomRotationE.x; + ShurikenParticleData.startRotation[1] = randomRotationE.y; + if (renderMode !== 4) + ShurikenParticleData.startRotation[2] = -randomRotationE.z; + else + ShurikenParticleData.startRotation[2] = randomRotationE.z; + } + else { + ShurikenParticleData.startRotation[0] = ShurikenParticleData._randomInvertRoation(particleSystem.startRotationConstant, particleSystem.randomizeRotationDirection, autoRandomSeed ? null : rand, randomSeeds); + ShurikenParticleData.startRotation[1] = 0; + ShurikenParticleData.startRotation[2] = 0; + } + break; + case 2: + if (particleSystem.threeDStartRotation) { + var startRotationConstantMinSeparate = particleSystem.startRotationConstantMinSeparate; + var startRotationConstantMaxSeparate = particleSystem.startRotationConstantMaxSeparate; + var lerpRoationE = ShurikenParticleData._tempVector30; + if (autoRandomSeed) { + lerpRoationE.x = Laya.MathUtil.lerp(startRotationConstantMinSeparate.x, startRotationConstantMaxSeparate.x, Math.random()); + lerpRoationE.y = Laya.MathUtil.lerp(startRotationConstantMinSeparate.y, startRotationConstantMaxSeparate.y, Math.random()); + lerpRoationE.z = Laya.MathUtil.lerp(startRotationConstantMinSeparate.z, startRotationConstantMaxSeparate.z, Math.random()); + } + else { + rand.seed = randomSeeds[5]; + lerpRoationE.x = Laya.MathUtil.lerp(startRotationConstantMinSeparate.x, startRotationConstantMaxSeparate.x, rand.getFloat()); + lerpRoationE.y = Laya.MathUtil.lerp(startRotationConstantMinSeparate.y, startRotationConstantMaxSeparate.y, rand.getFloat()); + lerpRoationE.z = Laya.MathUtil.lerp(startRotationConstantMinSeparate.z, startRotationConstantMaxSeparate.z, rand.getFloat()); + randomSeeds[5] = rand.seed; + } + ShurikenParticleData._randomInvertRoationArray(lerpRoationE, lerpRoationE, particleSystem.randomizeRotationDirection, autoRandomSeed ? null : rand, randomSeeds); + ShurikenParticleData.startRotation[0] = lerpRoationE.x; + ShurikenParticleData.startRotation[1] = lerpRoationE.y; + if (renderMode !== 4) + ShurikenParticleData.startRotation[2] = -lerpRoationE.z; + else + ShurikenParticleData.startRotation[2] = lerpRoationE.z; + } + else { + if (autoRandomSeed) { + ShurikenParticleData.startRotation[0] = ShurikenParticleData._randomInvertRoation(Laya.MathUtil.lerp(particleSystem.startRotationConstantMin, particleSystem.startRotationConstantMax, Math.random()), particleSystem.randomizeRotationDirection, autoRandomSeed ? null : rand, randomSeeds); + } + else { + rand.seed = randomSeeds[5]; + ShurikenParticleData.startRotation[0] = ShurikenParticleData._randomInvertRoation(Laya.MathUtil.lerp(particleSystem.startRotationConstantMin, particleSystem.startRotationConstantMax, rand.getFloat()), particleSystem.randomizeRotationDirection, autoRandomSeed ? null : rand, randomSeeds); + randomSeeds[5] = rand.seed; + } + } + break; + } + } + switch (particleSystem.startLifetimeType) { + case 0: + ShurikenParticleData.startLifeTime = particleSystem.startLifetimeConstant; + break; + case 1: + ShurikenParticleData.startLifeTime = ShurikenParticleData._getStartLifetimeFromGradient(particleSystem.startLifeTimeGradient, particleSystem.emissionTime); + break; + case 2: + if (autoRandomSeed) { + ShurikenParticleData.startLifeTime = Laya.MathUtil.lerp(particleSystem.startLifetimeConstantMin, particleSystem.startLifetimeConstantMax, Math.random()); + } + else { + rand.seed = randomSeeds[7]; + ShurikenParticleData.startLifeTime = Laya.MathUtil.lerp(particleSystem.startLifetimeConstantMin, particleSystem.startLifetimeConstantMax, rand.getFloat()); + randomSeeds[7] = rand.seed; + } + break; + case 3: + var emissionTime = particleSystem.emissionTime; + if (autoRandomSeed) { + ShurikenParticleData.startLifeTime = Laya.MathUtil.lerp(ShurikenParticleData._getStartLifetimeFromGradient(particleSystem.startLifeTimeGradientMin, emissionTime), ShurikenParticleData._getStartLifetimeFromGradient(particleSystem.startLifeTimeGradientMax, emissionTime), Math.random()); + } + else { + rand.seed = randomSeeds[7]; + ShurikenParticleData.startLifeTime = Laya.MathUtil.lerp(ShurikenParticleData._getStartLifetimeFromGradient(particleSystem.startLifeTimeGradientMin, emissionTime), ShurikenParticleData._getStartLifetimeFromGradient(particleSystem.startLifeTimeGradientMax, emissionTime), rand.getFloat()); + randomSeeds[7] = rand.seed; + } + break; + } + var textureSheetAnimation = particleSystem.textureSheetAnimation; + var enableSheetAnimation = textureSheetAnimation && textureSheetAnimation.enable; + if (enableSheetAnimation) { + var title = textureSheetAnimation.tiles; + var titleX = title.x, titleY = title.y; + var subU = 1.0 / titleX, subV = 1.0 / titleY; + var startFrameCount; + var startFrame = textureSheetAnimation.startFrame; + switch (startFrame.type) { + case 0: + startFrameCount = startFrame.constant; + break; + case 1: + if (autoRandomSeed) { + startFrameCount = Laya.MathUtil.lerp(startFrame.constantMin, startFrame.constantMax, Math.random()); + } + else { + rand.seed = randomSeeds[14]; + startFrameCount = Laya.MathUtil.lerp(startFrame.constantMin, startFrame.constantMax, rand.getFloat()); + randomSeeds[14] = rand.seed; + } + break; + } + var frame = textureSheetAnimation.frame; + var cycles = textureSheetAnimation.cycles; + switch (frame.type) { + case 0: + startFrameCount += frame.constant * cycles; + break; + case 2: + if (autoRandomSeed) { + startFrameCount += Laya.MathUtil.lerp(frame.constantMin, frame.constantMax, Math.random()) * cycles; + } + else { + rand.seed = randomSeeds[15]; + startFrameCount += Laya.MathUtil.lerp(frame.constantMin, frame.constantMax, rand.getFloat()) * cycles; + randomSeeds[15] = rand.seed; + } + break; + } + var startRow = 0; + switch (textureSheetAnimation.type) { + case 0: + startRow = Math.floor(startFrameCount / titleX); + break; + case 1: + if (textureSheetAnimation.randomRow) { + if (autoRandomSeed) { + startRow = Math.floor(Math.random() * titleY); + } + else { + rand.seed = randomSeeds[13]; + startRow = Math.floor(rand.getFloat() * titleY); + randomSeeds[13] = rand.seed; + } + } + else { + startRow = textureSheetAnimation.rowIndex; + } + break; + } + var startCol = Math.floor(startFrameCount % titleX); + ShurikenParticleData.startUVInfo = ShurikenParticleData.startUVInfo; + ShurikenParticleData.startUVInfo[0] = subU; + ShurikenParticleData.startUVInfo[1] = subV; + ShurikenParticleData.startUVInfo[2] = startCol * subU; + ShurikenParticleData.startUVInfo[3] = startRow * subV; + } + else { + ShurikenParticleData.startUVInfo = ShurikenParticleData.startUVInfo; + ShurikenParticleData.startUVInfo[0] = 1.0; + ShurikenParticleData.startUVInfo[1] = 1.0; + ShurikenParticleData.startUVInfo[2] = 0.0; + ShurikenParticleData.startUVInfo[3] = 0.0; + } + } + } + ShurikenParticleData._tempVector30 = new Vector3(); + ShurikenParticleData.startColor = new Vector4(); + ShurikenParticleData.startSize = new Float32Array(3); + ShurikenParticleData.startRotation = new Float32Array(3); + ShurikenParticleData.startUVInfo = new Float32Array(4); + + class ShurikenParticleSystem extends GeometryElement { + constructor(owner) { + super(); + this._boundingSphere = null; + this._boundingBox = null; + this._boundingBoxCorners = null; + this._bounds = null; + this._gravityOffset = new Vector2(); + this._customBounds = null; + this._useCustomBounds = false; + this._owner = null; + this._ownerRender = null; + this._vertices = null; + this._floatCountPerVertex = 0; + this._startLifeTimeIndex = 0; + this._timeIndex = 0; + this._simulateUpdate = false; + this._firstActiveElement = 0; + this._firstNewElement = 0; + this._firstFreeElement = 0; + this._firstRetiredElement = 0; + this._drawCounter = 0; + this._bufferMaxParticles = 0; + this._emission = null; + this._shape = null; + this._isEmitting = false; + this._isPlaying = false; + this._isPaused = false; + this._playStartDelay = 0; + this._frameRateTime = 0; + this._emissionTime = 0; + this._totalDelayTime = 0; + this._burstsIndex = 0; + this._velocityOverLifetime = null; + this._colorOverLifetime = null; + this._sizeOverLifetime = null; + this._rotationOverLifetime = null; + this._textureSheetAnimation = null; + this._startLifetimeType = 0; + this._startLifetimeConstant = 0; + this._startLifeTimeGradient = null; + this._startLifetimeConstantMin = 0; + this._startLifetimeConstantMax = 0; + this._startLifeTimeGradientMin = null; + this._startLifeTimeGradientMax = null; + this._maxStartLifetime = 0; + this._uvLength = new Vector2(); + this._vertexStride = 0; + this._indexStride = 0; + this._vertexBuffer = null; + this._indexBuffer = null; + this._bufferState = new BufferState(); + this._updateMask = 0; + this._currentTime = 0; + this._startUpdateLoopCount = 0; + this._rand = null; + this._randomSeeds = null; + this.duration = 0; + this.looping = false; + this.prewarm = false; + this.startDelayType = 0; + this.startDelay = 0; + this.startDelayMin = 0; + this.startDelayMax = 0; + this.startSpeedType = 0; + this.startSpeedConstant = 0; + this.startSpeedConstantMin = 0; + this.startSpeedConstantMax = 0; + this.threeDStartSize = false; + this.startSizeType = 0; + this.startSizeConstant = 0; + this.startSizeConstantSeparate = null; + this.startSizeConstantMin = 0; + this.startSizeConstantMax = 0; + this.startSizeConstantMinSeparate = null; + this.startSizeConstantMaxSeparate = null; + this.threeDStartRotation = false; + this.startRotationType = 0; + this.startRotationConstant = 0; + this.startRotationConstantSeparate = null; + this.startRotationConstantMin = 0; + this.startRotationConstantMax = 0; + this.startRotationConstantMinSeparate = null; + this.startRotationConstantMaxSeparate = null; + this.randomizeRotationDirection = 0; + this.startColorType = 0; + this.startColorConstant = new Vector4(1, 1, 1, 1); + this.startColorConstantMin = new Vector4(0, 0, 0, 0); + this.startColorConstantMax = new Vector4(1, 1, 1, 1); + this.gravityModifier = 0; + this.simulationSpace = 0; + this.simulationSpeed = 1.0; + this.scaleMode = 1; + this.playOnAwake = false; + this.randomSeed = null; + this.autoRandomSeed = false; + this.isPerformanceMode = false; + this._firstActiveElement = 0; + this._firstNewElement = 0; + this._firstFreeElement = 0; + this._firstRetiredElement = 0; + this._owner = owner; + this._ownerRender = owner.particleRenderer; + this._boundingBoxCorners = []; + this._boundingSphere = new BoundSphere(new Vector3(), Number.MAX_VALUE); + this._boundingBox = new BoundBox(new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE), new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE)); + this._bounds = new Bounds(this._boundingBox.min, this._boundingBox.max); + this._useCustomBounds = false; + this._currentTime = 0; + this._isEmitting = false; + this._isPlaying = false; + this._isPaused = false; + this._burstsIndex = 0; + this._frameRateTime = 0; + this._emissionTime = 0; + this._totalDelayTime = 0; + this._simulateUpdate = false; + this._bufferMaxParticles = 1; + this.duration = 5.0; + this.looping = true; + this.prewarm = false; + this.startDelayType = 0; + this.startDelay = 0.0; + this.startDelayMin = 0.0; + this.startDelayMax = 0.0; + this._startLifetimeType = 0; + this._startLifetimeConstant = 5.0; + this._startLifeTimeGradient = new GradientDataNumber(); + this._startLifetimeConstantMin = 0.0; + this._startLifetimeConstantMax = 5.0; + this._startLifeTimeGradientMin = new GradientDataNumber(); + this._startLifeTimeGradientMax = new GradientDataNumber(); + this._maxStartLifetime = 5.0; + this.startSpeedType = 0; + this.startSpeedConstant = 5.0; + this.startSpeedConstantMin = 0.0; + this.startSpeedConstantMax = 5.0; + this.threeDStartSize = false; + this.startSizeType = 0; + this.startSizeConstant = 1; + this.startSizeConstantSeparate = new Vector3(1, 1, 1); + this.startSizeConstantMin = 0; + this.startSizeConstantMax = 1; + this.startSizeConstantMinSeparate = new Vector3(0, 0, 0); + this.startSizeConstantMaxSeparate = new Vector3(1, 1, 1); + this.threeDStartRotation = false; + this.startRotationType = 0; + this.startRotationConstant = 0; + this.startRotationConstantSeparate = new Vector3(0, 0, 0); + this.startRotationConstantMin = 0.0; + this.startRotationConstantMax = 0.0; + this.startRotationConstantMinSeparate = new Vector3(0, 0, 0); + this.startRotationConstantMaxSeparate = new Vector3(0, 0, 0); + this.gravityModifier = 0.0; + this.simulationSpace = 1; + this.scaleMode = 1; + this.playOnAwake = true; + this._rand = new Rand(0); + this.autoRandomSeed = true; + this.randomSeed = new Uint32Array(1); + this._randomSeeds = new Uint32Array(ShurikenParticleSystem._RANDOMOFFSET.length); + this.isPerformanceMode = true; + this._emission = new Emission(); + this._emission.enable = true; + } + ; + get maxParticles() { + return this._bufferMaxParticles - 1; + } + set maxParticles(value) { + var newMaxParticles = value + 1; + if (newMaxParticles !== this._bufferMaxParticles) { + this._bufferMaxParticles = newMaxParticles; + this._initBufferDatas(); + } + } + get emission() { + return this._emission; + } + get aliveParticleCount() { + if (this._firstNewElement >= this._firstRetiredElement) + return this._firstNewElement - this._firstRetiredElement; + else + return this._bufferMaxParticles - this._firstRetiredElement + this._firstNewElement; + } + get emissionTime() { + return this._emissionTime > this.duration ? this.duration : this._emissionTime; + } + get shape() { + return this._shape; + } + set shape(value) { + if (this._shape !== value) { + if (value && value.enable) + this._owner._render._shaderValues.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SHAPE); + else + this._owner._render._shaderValues.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SHAPE); + this._shape = value; + } + } + get isAlive() { + if (this._isPlaying || this.aliveParticleCount > 0) + return true; + return false; + } + get isEmitting() { + return this._isEmitting; + } + get isPlaying() { + return this._isPlaying; + } + get isPaused() { + return this._isPaused; + } + get startLifetimeType() { + return this._startLifetimeType; + } + set startLifetimeType(value) { + var i, n; + switch (this.startLifetimeType) { + case 0: + this._maxStartLifetime = this.startLifetimeConstant; + break; + case 1: + this._maxStartLifetime = -Number.MAX_VALUE; + var startLifeTimeGradient = startLifeTimeGradient; + for (i = 0, n = startLifeTimeGradient.gradientCount; i < n; i++) + this._maxStartLifetime = Math.max(this._maxStartLifetime, startLifeTimeGradient.getValueByIndex(i)); + break; + case 2: + this._maxStartLifetime = Math.max(this.startLifetimeConstantMin, this.startLifetimeConstantMax); + break; + case 3: + this._maxStartLifetime = -Number.MAX_VALUE; + var startLifeTimeGradientMin = startLifeTimeGradientMin; + for (i = 0, n = startLifeTimeGradientMin.gradientCount; i < n; i++) + this._maxStartLifetime = Math.max(this._maxStartLifetime, startLifeTimeGradientMin.getValueByIndex(i)); + var startLifeTimeGradientMax = startLifeTimeGradientMax; + for (i = 0, n = startLifeTimeGradientMax.gradientCount; i < n; i++) + this._maxStartLifetime = Math.max(this._maxStartLifetime, startLifeTimeGradientMax.getValueByIndex(i)); + break; + } + this._startLifetimeType = value; + } + get startLifetimeConstant() { + return this._startLifetimeConstant; + } + set startLifetimeConstant(value) { + if (this._startLifetimeType === 0) + this._maxStartLifetime = value; + this._startLifetimeConstant = value; + } + get startLifeTimeGradient() { + return this._startLifeTimeGradient; + } + set startLifeTimeGradient(value) { + if (this._startLifetimeType === 1) { + this._maxStartLifetime = -Number.MAX_VALUE; + for (var i = 0, n = value.gradientCount; i < n; i++) + this._maxStartLifetime = Math.max(this._maxStartLifetime, value.getValueByIndex(i)); + } + this._startLifeTimeGradient = value; + } + get startLifetimeConstantMin() { + return this._startLifetimeConstantMin; + } + set startLifetimeConstantMin(value) { + if (this._startLifetimeType === 2) + this._maxStartLifetime = Math.max(value, this._startLifetimeConstantMax); + this._startLifetimeConstantMin = value; + } + get startLifetimeConstantMax() { + return this._startLifetimeConstantMax; + } + set startLifetimeConstantMax(value) { + if (this._startLifetimeType === 2) + this._maxStartLifetime = Math.max(this._startLifetimeConstantMin, value); + this._startLifetimeConstantMax = value; + } + get startLifeTimeGradientMin() { + return this._startLifeTimeGradientMin; + } + set startLifeTimeGradientMin(value) { + if (this._startLifetimeType === 3) { + var i, n; + this._maxStartLifetime = -Number.MAX_VALUE; + for (i = 0, n = value.gradientCount; i < n; i++) + this._maxStartLifetime = Math.max(this._maxStartLifetime, value.getValueByIndex(i)); + for (i = 0, n = this._startLifeTimeGradientMax.gradientCount; i < n; i++) + this._maxStartLifetime = Math.max(this._maxStartLifetime, this._startLifeTimeGradientMax.getValueByIndex(i)); + } + this._startLifeTimeGradientMin = value; + } + get startLifeTimeGradientMax() { + return this._startLifeTimeGradientMax; + } + set startLifeTimeGradientMax(value) { + if (this._startLifetimeType === 3) { + var i, n; + this._maxStartLifetime = -Number.MAX_VALUE; + for (i = 0, n = this._startLifeTimeGradientMin.gradientCount; i < n; i++) + this._maxStartLifetime = Math.max(this._maxStartLifetime, this._startLifeTimeGradientMin.getValueByIndex(i)); + for (i = 0, n = value.gradientCount; i < n; i++) + this._maxStartLifetime = Math.max(this._maxStartLifetime, value.getValueByIndex(i)); + } + this._startLifeTimeGradientMax = value; + } + get velocityOverLifetime() { + return this._velocityOverLifetime; + } + set velocityOverLifetime(value) { + var shaDat = this._owner._render._shaderValues; + if (value) { + var velocity = value.velocity; + var velocityType = velocity.type; + if (value.enable) { + switch (velocityType) { + case 0: + shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMECONSTANT); + break; + case 1: + shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMECURVE); + break; + case 2: + shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMERANDOMCONSTANT); + break; + case 3: + shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMERANDOMCURVE); + break; + } + } + else { + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMECONSTANT); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMECURVE); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMERANDOMCONSTANT); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMERANDOMCURVE); + } + switch (velocityType) { + case 0: + shaDat.setVector3(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYCONST, velocity.constant); + break; + case 1: + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTX, velocity.gradientX._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTY, velocity.gradientY._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTZ, velocity.gradientZ._elements); + break; + case 2: + shaDat.setVector3(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYCONST, velocity.constantMin); + shaDat.setVector3(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYCONSTMAX, velocity.constantMax); + break; + case 3: + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTX, velocity.gradientXMin._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTXMAX, velocity.gradientXMax._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTY, velocity.gradientYMin._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTYMAX, velocity.gradientYMax._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTZ, velocity.gradientZMin._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.VOLVELOCITYGRADIENTZMAX, velocity.gradientZMax._elements); + break; + } + shaDat.setInt(ShuriKenParticle3DShaderDeclaration.VOLSPACETYPE, value.space); + } + else { + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMECONSTANT); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMECURVE); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMERANDOMCONSTANT); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMERANDOMCURVE); + } + this._velocityOverLifetime = value; + } + get colorOverLifetime() { + return this._colorOverLifetime; + } + set colorOverLifetime(value) { + var shaDat = this._owner._render._shaderValues; + if (value) { + var color = value.color; + if (value.enable) { + switch (color.type) { + case 1: + shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_COLOROVERLIFETIME); + break; + case 3: + shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RANDOMCOLOROVERLIFETIME); + break; + } + } + else { + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_COLOROVERLIFETIME); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RANDOMCOLOROVERLIFETIME); + } + switch (color.type) { + case 1: + var gradientColor = color.gradient; + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTALPHAS, gradientColor._alphaElements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTCOLORS, gradientColor._rgbElements); + break; + case 3: + var minGradientColor = color.gradientMin; + var maxGradientColor = color.gradientMax; + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTALPHAS, minGradientColor._alphaElements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTCOLORS, minGradientColor._rgbElements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.MAXCOLOROVERLIFEGRADIENTALPHAS, maxGradientColor._alphaElements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.MAXCOLOROVERLIFEGRADIENTCOLORS, maxGradientColor._rgbElements); + break; + } + } + else { + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_COLOROVERLIFETIME); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RANDOMCOLOROVERLIFETIME); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTALPHAS, gradientColor._alphaElements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTCOLORS, gradientColor._rgbElements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTALPHAS, minGradientColor._alphaElements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.COLOROVERLIFEGRADIENTCOLORS, minGradientColor._rgbElements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.MAXCOLOROVERLIFEGRADIENTALPHAS, maxGradientColor._alphaElements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.MAXCOLOROVERLIFEGRADIENTCOLORS, maxGradientColor._rgbElements); + } + this._colorOverLifetime = value; + } + get sizeOverLifetime() { + return this._sizeOverLifetime; + } + set sizeOverLifetime(value) { + var shaDat = this._owner._render._shaderValues; + if (value) { + var size = value.size; + var sizeSeparate = size.separateAxes; + var sizeType = size.type; + if (value.enable) { + switch (sizeType) { + case 0: + if (sizeSeparate) + shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMECURVESEPERATE); + else + shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMECURVE); + break; + case 2: + if (sizeSeparate) + shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMERANDOMCURVESSEPERATE); + else + shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMERANDOMCURVES); + break; + } + } + else { + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMECURVE); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMECURVESEPERATE); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMERANDOMCURVES); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMERANDOMCURVESSEPERATE); + } + switch (sizeType) { + case 0: + if (sizeSeparate) { + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTX, size.gradientX._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTY, size.gradientY._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSizeGradientZ, size.gradientZ._elements); + } + else { + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENT, size.gradient._elements); + } + break; + case 2: + if (sizeSeparate) { + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTX, size.gradientXMin._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTXMAX, size.gradientXMax._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTY, size.gradientYMin._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENTYMAX, size.gradientYMax._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSizeGradientZ, size.gradientZMin._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSizeGradientZMAX, size.gradientZMax._elements); + } + else { + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSIZEGRADIENT, size.gradientMin._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.SOLSizeGradientMax, size.gradientMax._elements); + } + break; + } + } + else { + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMECURVE); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMECURVESEPERATE); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMERANDOMCURVES); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMERANDOMCURVESSEPERATE); + } + this._sizeOverLifetime = value; + } + get rotationOverLifetime() { + return this._rotationOverLifetime; + } + set rotationOverLifetime(value) { + var shaDat = this._owner._render._shaderValues; + if (value) { + var rotation = value.angularVelocity; + if (!rotation) + return; + var rotationSeparate = rotation.separateAxes; + var rotationType = rotation.type; + if (value.enable) { + if (rotationSeparate) + shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMESEPERATE); + else + shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIME); + switch (rotationType) { + case 0: + shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMECONSTANT); + break; + case 1: + shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMECURVE); + break; + case 2: + shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMERANDOMCONSTANTS); + break; + case 3: + shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMERANDOMCURVES); + break; + } + } + else { + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIME); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMESEPERATE); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMECONSTANT); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMECURVE); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMERANDOMCONSTANTS); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMERANDOMCURVES); + } + switch (rotationType) { + case 0: + if (rotationSeparate) { + shaDat.setVector3(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONSTSEPRARATE, rotation.constantSeparate); + } + else { + shaDat.setNumber(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONST, rotation.constant); + } + break; + case 1: + if (rotationSeparate) { + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTX, rotation.gradientX._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTY, rotation.gradientY._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTZ, rotation.gradientZ._elements); + } + else { + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENT, rotation.gradient._elements); + } + break; + case 2: + if (rotationSeparate) { + shaDat.setVector3(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONSTSEPRARATE, rotation.constantMinSeparate); + shaDat.setVector3(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONSTMAXSEPRARATE, rotation.constantMaxSeparate); + } + else { + shaDat.setNumber(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONST, rotation.constantMin); + shaDat.setNumber(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYCONSTMAX, rotation.constantMax); + } + break; + case 3: + if (rotationSeparate) { + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTX, rotation.gradientXMin._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTXMAX, rotation.gradientXMax._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTY, rotation.gradientYMin._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTYMAX, rotation.gradientYMax._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTZ, rotation.gradientZMin._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTZMAX, rotation.gradientZMax._elements); + } + else { + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENT, rotation.gradientMin._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.ROLANGULARVELOCITYGRADIENTMAX, rotation.gradientMax._elements); + } + break; + } + } + else { + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIME); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMESEPERATE); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMECONSTANT); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMECURVE); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMERANDOMCONSTANTS); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMERANDOMCURVES); + } + this._rotationOverLifetime = value; + } + get textureSheetAnimation() { + return this._textureSheetAnimation; + } + set textureSheetAnimation(value) { + var shaDat = this._owner._render._shaderValues; + if (value) { + var frameOverTime = value.frame; + var textureAniType = frameOverTime.type; + if (value.enable) { + switch (textureAniType) { + case 1: + shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_TEXTURESHEETANIMATIONCURVE); + break; + case 3: + shaDat.addDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_TEXTURESHEETANIMATIONRANDOMCURVE); + break; + } + } + else { + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_TEXTURESHEETANIMATIONCURVE); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_TEXTURESHEETANIMATIONRANDOMCURVE); + } + if (textureAniType === 1 || textureAniType === 3) { + shaDat.setNumber(ShuriKenParticle3DShaderDeclaration.TEXTURESHEETANIMATIONCYCLES, value.cycles); + var title = value.tiles; + var _uvLengthE = this._uvLength; + _uvLengthE.x = 1.0 / title.x; + _uvLengthE.y = 1.0 / title.y; + shaDat.setVector2(ShuriKenParticle3DShaderDeclaration.TEXTURESHEETANIMATIONSUBUVLENGTH, this._uvLength); + } + switch (textureAniType) { + case 1: + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.TEXTURESHEETANIMATIONGRADIENTUVS, frameOverTime.frameOverTimeData._elements); + break; + case 3: + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.TEXTURESHEETANIMATIONGRADIENTUVS, frameOverTime.frameOverTimeDataMin._elements); + shaDat.setBuffer(ShuriKenParticle3DShaderDeclaration.TEXTURESHEETANIMATIONGRADIENTMAXUVS, frameOverTime.frameOverTimeDataMax._elements); + break; + } + } + else { + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_TEXTURESHEETANIMATIONCURVE); + shaDat.removeDefine(ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_TEXTURESHEETANIMATIONRANDOMCURVE); + } + this._textureSheetAnimation = value; + } + _getVertexBuffer(index = 0) { + if (index === 0) + return this._vertexBuffer; + else + return null; + } + _getIndexBuffer() { + return this._indexBuffer; + } + _generateBoundingSphere() { + var centerE = this._boundingSphere.center; + centerE.x = 0; + centerE.y = 0; + centerE.z = 0; + this._boundingSphere.radius = Number.MAX_VALUE; + } + _generateBounds() { + var particle = this._owner; + var particleRender = particle.particleRenderer; + var boundsMin = this._bounds.getMin(); + var boundsMax = this._bounds.getMax(); + var time = 0; + switch (this.startLifetimeType) { + case 0: + time = this._startLifetimeConstant; + break; + case 2: + time = this._startLifetimeConstantMax; + break; + } + var speedOrigan = 0; + switch (this.startSpeedType) { + case 0: + speedOrigan = this.startSpeedConstant; + break; + case 2: + speedOrigan = this.startSpeedConstantMax; + break; + } + var maxSizeScale = 0; + if (this.threeDStartSize) { + switch (this.startSizeType) { + case 0: + maxSizeScale = Math.max(this.startSizeConstantSeparate.x, this.startSizeConstantSeparate.y, this.startSizeConstantSeparate.z); + break; + case 2: + maxSizeScale = Math.max(this.startSizeConstantMaxSeparate.x, this.startSizeConstantMaxSeparate.y, this.startSizeConstantMaxSeparate.z); + break; + } + } + else { + switch (this.startSizeType) { + case 0: + maxSizeScale = this.startSizeConstant; + break; + case 2: + maxSizeScale = this.startSizeConstantMax; + break; + } + } + var zDirectionSpeed = ShurikenParticleSystem._tempVector30; + var fDirectionSpeed = ShurikenParticleSystem._tempVector31; + var zEmisionOffsetXYZ = ShurikenParticleSystem._tempVector32; + var fEmisionOffsetXYZ = ShurikenParticleSystem._tempVector33; + zDirectionSpeed.setValue(0, 0, 1); + fDirectionSpeed.setValue(0, 0, 0); + zEmisionOffsetXYZ.setValue(0, 0, 0); + fEmisionOffsetXYZ.setValue(0, 0, 0); + if (this.shape && this.shape.enable) { + switch (this.shape.shapeType) { + case exports.ParticleSystemShapeType.Sphere: + var sphere = this.shape; + zDirectionSpeed.setValue(1, 1, 1); + fDirectionSpeed.setValue(1, 1, 1); + zEmisionOffsetXYZ.setValue(sphere.radius, sphere.radius, sphere.radius); + fEmisionOffsetXYZ.setValue(sphere.radius, sphere.radius, sphere.radius); + break; + case exports.ParticleSystemShapeType.Hemisphere: + var hemiShpere = this.shape; + zDirectionSpeed.setValue(1, 1, 1); + fDirectionSpeed.setValue(1, 1, 1); + zEmisionOffsetXYZ.setValue(hemiShpere.radius, hemiShpere.radius, hemiShpere.radius); + fEmisionOffsetXYZ.setValue(hemiShpere.radius, hemiShpere.radius, 0.0); + break; + case exports.ParticleSystemShapeType.Cone: + var cone = this.shape; + if (cone.emitType == 0 || cone.emitType == 1) { + var angle = cone.angle; + var sinAngle = Math.sin(angle); + zDirectionSpeed.setValue(sinAngle, sinAngle, 1.0); + fDirectionSpeed.setValue(sinAngle, sinAngle, 0.0); + zEmisionOffsetXYZ.setValue(cone.radius, cone.radius, 0.0); + fEmisionOffsetXYZ.setValue(cone.radius, cone.radius, 0.0); + break; + } + else if (cone.emitType == 2 || cone.emitType == 3) { + var angle = cone.angle; + var sinAngle = Math.sin(angle); + var coneLength = cone.length; + zDirectionSpeed.setValue(sinAngle, sinAngle, 1.0); + fDirectionSpeed.setValue(sinAngle, sinAngle, 0.0); + var tanAngle = Math.tan(angle); + var rPLCT = cone.radius + coneLength * tanAngle; + zEmisionOffsetXYZ.setValue(rPLCT, rPLCT, coneLength); + fEmisionOffsetXYZ.setValue(rPLCT, rPLCT, 0.0); + } + break; + case exports.ParticleSystemShapeType.Box: + var box = this.shape; + if (this.shape.randomDirection != 0) { + zDirectionSpeed.setValue(1, 1, 1); + fDirectionSpeed.setValue(1, 1, 1); + } + zEmisionOffsetXYZ.setValue(box.x / 2, box.y / 2, box.z / 2); + fEmisionOffsetXYZ.setValue(box.x / 2, box.y / 2, box.z / 2); + break; + case exports.ParticleSystemShapeType.Circle: + var circle = this.shape; + zDirectionSpeed.setValue(1, 1, 1); + fDirectionSpeed.setValue(1, 1, 1); + zEmisionOffsetXYZ.setValue(circle.radius, circle.radius, 0); + fEmisionOffsetXYZ.setValue(circle.radius, circle.radius, 0); + break; + } + } + var meshSize = 0; + var meshMode = particleRender.renderMode == 4; + switch (particleRender.renderMode) { + case 0: + case 1: + case 2: + case 3: + meshSize = ShurikenParticleSystem.halfKSqrtOf2; + break; + case 4: + var meshBounds = particleRender.mesh.bounds; + meshSize = Math.sqrt(Math.pow(meshBounds.getExtent().x, 2.0) + Math.pow(meshBounds.getExtent().y, 2.0) + Math.pow(meshBounds.getExtent().z, 2.0)); + break; + } + var endSizeOffset = ShurikenParticleSystem._tempVector36; + endSizeOffset.setValue(1, 1, 1); + if (this.sizeOverLifetime && this.sizeOverLifetime.enable) { + var gradientSize = this.sizeOverLifetime.size; + var maxSize = gradientSize.getMaxSizeInGradient(meshMode); + endSizeOffset.setValue(maxSize, maxSize, maxSize); + } + var offsetSize = meshSize * maxSizeScale; + Vector3.scale(endSizeOffset, offsetSize, endSizeOffset); + var speedZOffset = ShurikenParticleSystem._tempVector34; + var speedFOffset = ShurikenParticleSystem._tempVector35; + if (speedOrigan > 0) { + Vector3.scale(zDirectionSpeed, speedOrigan, speedZOffset); + Vector3.scale(fDirectionSpeed, speedOrigan, speedFOffset); + } + else { + Vector3.scale(zDirectionSpeed, -speedOrigan, speedFOffset); + Vector3.scale(fDirectionSpeed, -speedOrigan, speedZOffset); + } + if (this.velocityOverLifetime && this.velocityOverLifetime.enable) { + var gradientVelocity = this.velocityOverLifetime.velocity; + var velocitySpeedOffset = ShurikenParticleSystem._tempVector37; + velocitySpeedOffset.setValue(0, 0, 0); + switch (gradientVelocity.type) { + case 0: + gradientVelocity.constant.cloneTo(velocitySpeedOffset); + break; + case 2: + gradientVelocity.constantMax.cloneTo(velocitySpeedOffset); + break; + case 1: + var curveX = gradientVelocity.gradientX.getAverageValue(); + var curveY = gradientVelocity.gradientY.getAverageValue(); + var curveZ = gradientVelocity.gradientZ.getAverageValue(); + velocitySpeedOffset.setValue(curveX, curveY, curveZ); + break; + case 3: + var xMax = gradientVelocity.gradientXMax.getAverageValue(); + var yMax = gradientVelocity.gradientYMax.getAverageValue(); + var zMax = gradientVelocity.gradientZMax.getAverageValue(); + velocitySpeedOffset.setValue(xMax, yMax, zMax); + break; + } + if (this.velocityOverLifetime.space == 1) { + Vector3.transformV3ToV3(velocitySpeedOffset, this._owner.transform.worldMatrix, velocitySpeedOffset); + } + Vector3.add(speedZOffset, velocitySpeedOffset, speedZOffset); + Vector3.subtract(speedFOffset, velocitySpeedOffset, speedFOffset); + Vector3.max(speedZOffset, Vector3._ZERO, speedZOffset); + Vector3.max(speedFOffset, Vector3._ZERO, speedFOffset); + } + Vector3.scale(speedZOffset, time, speedZOffset); + Vector3.scale(speedFOffset, time, speedFOffset); + var gravity = this.gravityModifier; + if (gravity != 0) { + var gravityOffset = 0.5 * ShurikenParticleSystem.g * gravity * time * time; + var speedZOffsetY = speedZOffset.y - gravityOffset; + var speedFOffsetY = speedFOffset.y + gravityOffset; + speedZOffsetY = speedZOffsetY > 0 ? speedZOffsetY : 0; + speedFOffsetY = speedFOffsetY > 0 ? speedFOffsetY : 0; + this._gravityOffset.setValue(speedZOffset.y - speedZOffsetY, speedFOffsetY - speedFOffset.y); + } + Vector3.add(speedZOffset, endSizeOffset, boundsMax); + Vector3.add(boundsMax, zEmisionOffsetXYZ, boundsMax); + Vector3.add(speedFOffset, endSizeOffset, boundsMin); + Vector3.add(boundsMin, fEmisionOffsetXYZ, boundsMin); + Vector3.scale(boundsMin, -1, boundsMin); + this._bounds.setMin(boundsMin); + this._bounds.setMax(boundsMax); + } + get customBounds() { + return this._customBounds; + } + set customBounds(value) { + if (value) { + this._useCustomBounds = true; + } + else { + this._useCustomBounds = false; + } + this._customBounds = value; + } + _simulationSupported() { + if (this.simulationSpace == 0) { + return false; + } + return true; + } + _updateEmission() { + if (!this.isAlive) + return; + if (this._simulateUpdate) { + this._simulateUpdate = false; + } + else { + var elapsedTime = (this._startUpdateLoopCount !== Laya.Stat.loopCount && !this._isPaused) ? this._owner._scene.timer._delta / 1000.0 : 0; + elapsedTime = Math.min(ShurikenParticleSystem._maxElapsedTime, elapsedTime * this.simulationSpeed); + this._updateParticles(elapsedTime); + } + } + _updateParticles(elapsedTime) { + if (this._ownerRender.renderMode === 4 && !this._ownerRender.mesh) + return; + this._currentTime += elapsedTime; + this._retireActiveParticles(); + this._freeRetiredParticles(); + this._totalDelayTime += elapsedTime; + if (this._totalDelayTime < this._playStartDelay) { + return; + } + if (this._emission.enable && this._isEmitting && !this._isPaused) + this._advanceTime(elapsedTime, this._currentTime); + } + _updateParticlesSimulationRestart(time) { + this._firstActiveElement = 0; + this._firstNewElement = 0; + this._firstFreeElement = 0; + this._firstRetiredElement = 0; + this._burstsIndex = 0; + this._frameRateTime = time; + this._emissionTime = 0; + this._totalDelayTime = 0; + this._currentTime = time; + var delayTime = time; + if (delayTime < this._playStartDelay) { + this._totalDelayTime = delayTime; + return; + } + if (this._emission.enable) + this._advanceTime(time, time); + } + _retireActiveParticles() { + const epsilon = 0.0001; + while (this._firstActiveElement != this._firstNewElement) { + var index = this._firstActiveElement * this._floatCountPerVertex * this._vertexStride; + var timeIndex = index + this._timeIndex; + var particleAge = this._currentTime - this._vertices[timeIndex]; + if (particleAge + epsilon < this._vertices[index + this._startLifeTimeIndex]) + break; + this._vertices[timeIndex] = this._drawCounter; + this._firstActiveElement++; + if (this._firstActiveElement >= this._bufferMaxParticles) + this._firstActiveElement = 0; + } + } + _freeRetiredParticles() { + while (this._firstRetiredElement != this._firstActiveElement) { + var age = this._drawCounter - this._vertices[this._firstRetiredElement * this._floatCountPerVertex * this._vertexStride + this._timeIndex]; + this._firstRetiredElement++; + if (this._firstRetiredElement >= this._bufferMaxParticles) + this._firstRetiredElement = 0; + } + } + _burst(fromTime, toTime) { + var totalEmitCount = 0; + var bursts = this._emission._bursts; + for (var n = bursts.length; this._burstsIndex < n; this._burstsIndex++) { + var burst = bursts[this._burstsIndex]; + var burstTime = burst.time; + if (fromTime <= burstTime && burstTime < toTime) { + var emitCount; + if (this.autoRandomSeed) { + emitCount = Laya.MathUtil.lerp(burst.minCount, burst.maxCount, Math.random()); + } + else { + this._rand.seed = this._randomSeeds[0]; + emitCount = Laya.MathUtil.lerp(burst.minCount, burst.maxCount, this._rand.getFloat()); + this._randomSeeds[0] = this._rand.seed; + } + totalEmitCount += emitCount; + } + else { + break; + } + } + return totalEmitCount; + } + _advanceTime(elapsedTime, emitTime) { + var i; + var lastEmissionTime = this._emissionTime; + this._emissionTime += elapsedTime; + var totalEmitCount = 0; + if (this._emissionTime > this.duration) { + if (this.looping) { + totalEmitCount += this._burst(lastEmissionTime, this._emissionTime); + this._emissionTime -= this.duration; + this._burstsIndex = 0; + totalEmitCount += this._burst(0, this._emissionTime); + } + else { + totalEmitCount = Math.min(this.maxParticles - this.aliveParticleCount, totalEmitCount); + for (i = 0; i < totalEmitCount; i++) + this.emit(emitTime); + this._isPlaying = false; + this.stop(); + return; + } + } + else { + totalEmitCount += this._burst(lastEmissionTime, this._emissionTime); + } + totalEmitCount = Math.min(this.maxParticles - this.aliveParticleCount, totalEmitCount); + for (i = 0; i < totalEmitCount; i++) + this.emit(emitTime); + var emissionRate = this.emission.emissionRate; + if (emissionRate > 0) { + var minEmissionTime = 1 / emissionRate; + this._frameRateTime += minEmissionTime; + this._frameRateTime = this._currentTime - (this._currentTime - this._frameRateTime) % this._maxStartLifetime; + while (this._frameRateTime <= emitTime) { + if (this.emit(this._frameRateTime)) + this._frameRateTime += minEmissionTime; + else + break; + } + this._frameRateTime = Math.floor(emitTime / minEmissionTime) * minEmissionTime; + } + } + _initBufferDatas() { + if (this._vertexBuffer) { + var memorySize = this._vertexBuffer._byteLength + this._indexBuffer.indexCount * 2; + this._vertexBuffer.destroy(); + this._indexBuffer.destroy(); + Laya.Resource._addMemory(-memorySize, -memorySize); + } + var gl = Laya.LayaGL.instance; + var render = this._ownerRender; + var renderMode = render.renderMode; + if (renderMode !== -1 && this.maxParticles > 0) { + var indices, i, j, m, indexOffset, perPartOffset, vertexDeclaration; + var vbMemorySize = 0, memorySize = 0; + var mesh = render.mesh; + if (renderMode === 4) { + if (mesh) { + vertexDeclaration = VertexShurikenParticleMesh.vertexDeclaration; + this._floatCountPerVertex = vertexDeclaration.vertexStride / 4; + this._startLifeTimeIndex = 12; + this._timeIndex = 16; + this._vertexStride = mesh._vertexCount; + var totalVertexCount = this._bufferMaxParticles * this._vertexStride; + var vbCount = Math.floor(totalVertexCount / 65535) + 1; + var lastVBVertexCount = totalVertexCount % 65535; + if (vbCount > 1) { + throw new Error("ShurikenParticleSystem:the maxParticleCount multiply mesh vertexCount is large than 65535."); + } + vbMemorySize = vertexDeclaration.vertexStride * lastVBVertexCount; + this._vertexBuffer = new VertexBuffer3D(vbMemorySize, gl.DYNAMIC_DRAW); + this._vertexBuffer.vertexDeclaration = vertexDeclaration; + this._vertices = new Float32Array(this._floatCountPerVertex * lastVBVertexCount); + this._indexStride = mesh._indexBuffer.indexCount; + var indexDatas = mesh._indexBuffer.getData(); + var indexCount = this._bufferMaxParticles * this._indexStride; + this._indexBuffer = new IndexBuffer3D(exports.IndexFormat.UInt16, indexCount, gl.STATIC_DRAW); + indices = new Uint16Array(indexCount); + memorySize = vbMemorySize + indexCount * 2; + indexOffset = 0; + for (i = 0; i < this._bufferMaxParticles; i++) { + var indexValueOffset = i * this._vertexStride; + for (j = 0, m = indexDatas.length; j < m; j++) + indices[indexOffset++] = indexValueOffset + indexDatas[j]; + } + this._indexBuffer.setData(indices); + this._bufferState.bind(); + this._bufferState.applyVertexBuffer(this._vertexBuffer); + this._bufferState.applyIndexBuffer(this._indexBuffer); + this._bufferState.unBind(); + } + } + else { + vertexDeclaration = VertexShurikenParticleBillboard.vertexDeclaration; + this._floatCountPerVertex = vertexDeclaration.vertexStride / 4; + this._startLifeTimeIndex = 7; + this._timeIndex = 11; + this._vertexStride = 4; + vbMemorySize = vertexDeclaration.vertexStride * this._bufferMaxParticles * this._vertexStride; + this._vertexBuffer = new VertexBuffer3D(vbMemorySize, gl.DYNAMIC_DRAW); + this._vertexBuffer.vertexDeclaration = vertexDeclaration; + this._vertices = new Float32Array(this._floatCountPerVertex * this._bufferMaxParticles * this._vertexStride); + for (i = 0; i < this._bufferMaxParticles; i++) { + perPartOffset = i * this._floatCountPerVertex * this._vertexStride; + this._vertices[perPartOffset] = -0.5; + this._vertices[perPartOffset + 1] = -0.5; + this._vertices[perPartOffset + 2] = 0; + this._vertices[perPartOffset + 3] = 1; + perPartOffset += this._floatCountPerVertex; + this._vertices[perPartOffset] = 0.5; + this._vertices[perPartOffset + 1] = -0.5; + this._vertices[perPartOffset + 2] = 1; + this._vertices[perPartOffset + 3] = 1; + perPartOffset += this._floatCountPerVertex; + this._vertices[perPartOffset] = 0.5; + this._vertices[perPartOffset + 1] = 0.5; + this._vertices[perPartOffset + 2] = 1; + this._vertices[perPartOffset + 3] = 0; + perPartOffset += this._floatCountPerVertex; + this._vertices[perPartOffset] = -0.5; + this._vertices[perPartOffset + 1] = 0.5; + this._vertices[perPartOffset + 2] = 0; + this._vertices[perPartOffset + 3] = 0; + } + this._indexStride = 6; + this._indexBuffer = new IndexBuffer3D(exports.IndexFormat.UInt16, this._bufferMaxParticles * 6, gl.STATIC_DRAW); + indices = new Uint16Array(this._bufferMaxParticles * 6); + for (i = 0; i < this._bufferMaxParticles; i++) { + indexOffset = i * 6; + var firstVertex = i * this._vertexStride, secondVertex = firstVertex + 2; + indices[indexOffset++] = firstVertex; + indices[indexOffset++] = secondVertex; + indices[indexOffset++] = firstVertex + 1; + indices[indexOffset++] = firstVertex; + indices[indexOffset++] = firstVertex + 3; + indices[indexOffset++] = secondVertex; + } + this._indexBuffer.setData(indices); + memorySize = vbMemorySize + this._bufferMaxParticles * 6 * 2; + this._bufferState.bind(); + this._bufferState.applyVertexBuffer(this._vertexBuffer); + this._bufferState.applyIndexBuffer(this._indexBuffer); + this._bufferState.unBind(); + } + Laya.Resource._addMemory(memorySize, memorySize); + } + } + destroy() { + super.destroy(); + if (this._vertexBuffer) { + var memorySize = this._vertexBuffer._byteLength; + Laya.Resource._addMemory(-memorySize, -memorySize); + this._vertexBuffer.destroy(); + this._vertexBuffer = null; + } + if (this._indexBuffer) { + var memorySize = this._indexBuffer._byteLength; + Laya.Resource._addMemory(-memorySize, -memorySize); + this._indexBuffer.destroy(); + this._indexBuffer = null; + } + this._bufferState.destroy(); + this._emission.destroy(); + this._boundingBox = null; + this._boundingSphere = null; + this._boundingBoxCorners = null; + this._bounds = null; + this._customBounds = null; + this._bufferState = null; + this._owner = null; + this._vertices = null; + this._indexBuffer = null; + this._emission = null; + this._shape = null; + this.startLifeTimeGradient = null; + this.startLifeTimeGradientMin = null; + this.startLifeTimeGradientMax = null; + this.startSizeConstantSeparate = null; + this.startSizeConstantMinSeparate = null; + this.startSizeConstantMaxSeparate = null; + this.startRotationConstantSeparate = null; + this.startRotationConstantMinSeparate = null; + this.startRotationConstantMaxSeparate = null; + this.startColorConstant = null; + this.startColorConstantMin = null; + this.startColorConstantMax = null; + this._velocityOverLifetime = null; + this._colorOverLifetime = null; + this._sizeOverLifetime = null; + this._rotationOverLifetime = null; + this._textureSheetAnimation = null; + } + emit(time) { + var position = ShurikenParticleSystem._tempPosition; + var direction = ShurikenParticleSystem._tempDirection; + if (this._shape && this._shape.enable) { + if (this.autoRandomSeed) + this._shape.generatePositionAndDirection(position, direction); + else + this._shape.generatePositionAndDirection(position, direction, this._rand, this._randomSeeds); + } + else { + position.x = position.y = position.z = 0; + direction.x = direction.y = 0; + direction.z = 1; + } + return this.addParticle(position, direction, time); + } + addParticle(position, direction, time) { + Vector3.normalize(direction, direction); + var nextFreeParticle = this._firstFreeElement + 1; + if (nextFreeParticle >= this._bufferMaxParticles) + nextFreeParticle = 0; + if (nextFreeParticle === this._firstRetiredElement) + return false; + var transform = this._owner.transform; + ShurikenParticleData.create(this, this._ownerRender); + var particleAge = this._currentTime - time; + if (particleAge >= ShurikenParticleData.startLifeTime) + return true; + var pos, rot; + if (this.simulationSpace == 0) { + pos = transform.position; + rot = transform.rotation; + } + var startSpeed; + switch (this.startSpeedType) { + case 0: + startSpeed = this.startSpeedConstant; + break; + case 2: + if (this.autoRandomSeed) { + startSpeed = Laya.MathUtil.lerp(this.startSpeedConstantMin, this.startSpeedConstantMax, Math.random()); + } + else { + this._rand.seed = this._randomSeeds[8]; + startSpeed = Laya.MathUtil.lerp(this.startSpeedConstantMin, this.startSpeedConstantMax, this._rand.getFloat()); + this._randomSeeds[8] = this._rand.seed; + } + break; + } + var randomVelocityX, randomVelocityY, randomVelocityZ, randomColor, randomSize, randomRotation, randomTextureAnimation; + var needRandomVelocity = this._velocityOverLifetime && this._velocityOverLifetime.enable; + if (needRandomVelocity) { + var velocityType = this._velocityOverLifetime.velocity.type; + if (velocityType === 2 || velocityType === 3) { + if (this.autoRandomSeed) { + randomVelocityX = Math.random(); + randomVelocityY = Math.random(); + randomVelocityZ = Math.random(); + } + else { + this._rand.seed = this._randomSeeds[9]; + randomVelocityX = this._rand.getFloat(); + randomVelocityY = this._rand.getFloat(); + randomVelocityZ = this._rand.getFloat(); + this._randomSeeds[9] = this._rand.seed; + } + } + else { + needRandomVelocity = false; + } + } + else { + needRandomVelocity = false; + } + var needRandomColor = this._colorOverLifetime && this._colorOverLifetime.enable; + if (needRandomColor) { + var colorType = this._colorOverLifetime.color.type; + if (colorType === 3) { + if (this.autoRandomSeed) { + randomColor = Math.random(); + } + else { + this._rand.seed = this._randomSeeds[10]; + randomColor = this._rand.getFloat(); + this._randomSeeds[10] = this._rand.seed; + } + } + else { + needRandomColor = false; + } + } + else { + needRandomColor = false; + } + var needRandomSize = this._sizeOverLifetime && this._sizeOverLifetime.enable; + if (needRandomSize) { + var sizeType = this._sizeOverLifetime.size.type; + if (sizeType === 3) { + if (this.autoRandomSeed) { + randomSize = Math.random(); + } + else { + this._rand.seed = this._randomSeeds[11]; + randomSize = this._rand.getFloat(); + this._randomSeeds[11] = this._rand.seed; + } + } + else { + needRandomSize = false; + } + } + else { + needRandomSize = false; + } + var needRandomRotation = this._rotationOverLifetime && this._rotationOverLifetime.enable; + if (needRandomRotation) { + var rotationType = this._rotationOverLifetime.angularVelocity.type; + if (rotationType === 2 || rotationType === 3) { + if (this.autoRandomSeed) { + randomRotation = Math.random(); + } + else { + this._rand.seed = this._randomSeeds[12]; + randomRotation = this._rand.getFloat(); + this._randomSeeds[12] = this._rand.seed; + } + } + else { + needRandomRotation = false; + } + } + else { + needRandomRotation = false; + } + var needRandomTextureAnimation = this._textureSheetAnimation && this._textureSheetAnimation.enable; + if (needRandomTextureAnimation) { + var textureAnimationType = this._textureSheetAnimation.frame.type; + if (textureAnimationType === 3) { + if (this.autoRandomSeed) { + randomTextureAnimation = Math.random(); + } + else { + this._rand.seed = this._randomSeeds[15]; + randomTextureAnimation = this._rand.getFloat(); + this._randomSeeds[15] = this._rand.seed; + } + } + else { + needRandomTextureAnimation = false; + } + } + else { + needRandomTextureAnimation = false; + } + var startIndex = this._firstFreeElement * this._floatCountPerVertex * this._vertexStride; + var subU = ShurikenParticleData.startUVInfo[0]; + var subV = ShurikenParticleData.startUVInfo[1]; + var startU = ShurikenParticleData.startUVInfo[2]; + var startV = ShurikenParticleData.startUVInfo[3]; + var meshVertices, meshVertexStride, meshPosOffset, meshCorOffset, meshUVOffset, meshVertexIndex; + var render = this._ownerRender; + if (render.renderMode === 4) { + var meshVB = render.mesh._vertexBuffer; + meshVertices = meshVB.getFloat32Data(); + var meshVertexDeclaration = meshVB.vertexDeclaration; + meshPosOffset = meshVertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_POSITION0)._offset / 4; + var colorElement = meshVertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_COLOR0); + meshCorOffset = colorElement ? colorElement._offset / 4 : -1; + var uvElement = meshVertexDeclaration.getVertexElementByUsage(VertexMesh.MESH_TEXTURECOORDINATE0); + meshUVOffset = uvElement ? uvElement._offset / 4 : -1; + meshVertexStride = meshVertexDeclaration.vertexStride / 4; + meshVertexIndex = 0; + } + else { + this._vertices[startIndex + 2] = startU; + this._vertices[startIndex + 3] = startV + subV; + var secondOffset = startIndex + this._floatCountPerVertex; + this._vertices[secondOffset + 2] = startU + subU; + this._vertices[secondOffset + 3] = startV + subV; + var thirdOffset = secondOffset + this._floatCountPerVertex; + this._vertices[thirdOffset + 2] = startU + subU; + this._vertices[thirdOffset + 3] = startV; + var fourthOffset = thirdOffset + this._floatCountPerVertex; + this._vertices[fourthOffset + 2] = startU; + this._vertices[fourthOffset + 3] = startV; + } + for (var i = startIndex, n = startIndex + this._floatCountPerVertex * this._vertexStride; i < n; i += this._floatCountPerVertex) { + var offset; + if (render.renderMode === 4) { + offset = i; + var vertexOffset = meshVertexStride * (meshVertexIndex++); + var meshOffset = vertexOffset + meshPosOffset; + this._vertices[offset++] = meshVertices[meshOffset++]; + this._vertices[offset++] = meshVertices[meshOffset++]; + this._vertices[offset++] = meshVertices[meshOffset]; + if (meshCorOffset === -1) { + this._vertices[offset++] = 1.0; + this._vertices[offset++] = 1.0; + this._vertices[offset++] = 1.0; + this._vertices[offset++] = 1.0; + } + else { + meshOffset = vertexOffset + meshCorOffset; + this._vertices[offset++] = meshVertices[meshOffset++]; + this._vertices[offset++] = meshVertices[meshOffset++]; + this._vertices[offset++] = meshVertices[meshOffset++]; + this._vertices[offset++] = meshVertices[meshOffset]; + } + if (meshUVOffset === -1) { + this._vertices[offset++] = 0.0; + this._vertices[offset++] = 0.0; + } + else { + meshOffset = vertexOffset + meshUVOffset; + this._vertices[offset++] = startU + meshVertices[meshOffset++] * subU; + this._vertices[offset++] = startV + meshVertices[meshOffset] * subV; + } + } + else { + offset = i + 4; + } + this._vertices[offset++] = position.x; + this._vertices[offset++] = position.y; + this._vertices[offset++] = position.z; + this._vertices[offset++] = ShurikenParticleData.startLifeTime; + this._vertices[offset++] = direction.x; + this._vertices[offset++] = direction.y; + this._vertices[offset++] = direction.z; + this._vertices[offset++] = time; + this._vertices[offset++] = ShurikenParticleData.startColor.x; + this._vertices[offset++] = ShurikenParticleData.startColor.y; + this._vertices[offset++] = ShurikenParticleData.startColor.z; + this._vertices[offset++] = ShurikenParticleData.startColor.w; + this._vertices[offset++] = ShurikenParticleData.startSize[0]; + this._vertices[offset++] = ShurikenParticleData.startSize[1]; + this._vertices[offset++] = ShurikenParticleData.startSize[2]; + this._vertices[offset++] = ShurikenParticleData.startRotation[0]; + this._vertices[offset++] = ShurikenParticleData.startRotation[1]; + this._vertices[offset++] = ShurikenParticleData.startRotation[2]; + this._vertices[offset++] = startSpeed; + needRandomColor && (this._vertices[offset + 1] = randomColor); + needRandomSize && (this._vertices[offset + 2] = randomSize); + needRandomRotation && (this._vertices[offset + 3] = randomRotation); + needRandomTextureAnimation && (this._vertices[offset + 4] = randomTextureAnimation); + if (needRandomVelocity) { + this._vertices[offset + 5] = randomVelocityX; + this._vertices[offset + 6] = randomVelocityY; + this._vertices[offset + 7] = randomVelocityZ; + } + switch (this.simulationSpace) { + case 0: + offset += 8; + this._vertices[offset++] = pos.x; + this._vertices[offset++] = pos.y; + this._vertices[offset++] = pos.z; + this._vertices[offset++] = rot.x; + this._vertices[offset++] = rot.y; + this._vertices[offset++] = rot.z; + this._vertices[offset++] = rot.w; + break; + case 1: + break; + default: + throw new Error("ShurikenParticleMaterial: SimulationSpace value is invalid."); + } + } + this._firstFreeElement = nextFreeParticle; + return true; + } + addNewParticlesToVertexBuffer() { + var start; + var byteStride = this._vertexStride * this._floatCountPerVertex * 4; + if (this._firstNewElement < this._firstFreeElement) { + start = this._firstNewElement * byteStride; + this._vertexBuffer.setData(this._vertices.buffer, start, start, (this._firstFreeElement - this._firstNewElement) * byteStride); + } + else { + start = this._firstNewElement * byteStride; + this._vertexBuffer.setData(this._vertices.buffer, start, start, (this._bufferMaxParticles - this._firstNewElement) * byteStride); + if (this._firstFreeElement > 0) { + this._vertexBuffer.setData(this._vertices.buffer, 0, 0, this._firstFreeElement * byteStride); + } + } + this._firstNewElement = this._firstFreeElement; + } + _getType() { + return ShurikenParticleSystem._type; + } + _prepareRender(state) { + if (this._updateMask != Laya.Stat.loopCount) { + this._updateMask = Laya.Stat.loopCount; + this._updateEmission(); + if (this._firstNewElement != this._firstFreeElement) + this.addNewParticlesToVertexBuffer(); + this._drawCounter++; + } + if (this._firstActiveElement != this._firstFreeElement) + return true; + else + return false; + } + _render(state) { + this._bufferState.bind(); + var indexCount; + var gl = Laya.LayaGL.instance; + if (this._firstActiveElement < this._firstFreeElement) { + indexCount = (this._firstFreeElement - this._firstActiveElement) * this._indexStride; + gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 2 * this._firstActiveElement * this._indexStride); + Laya.Stat.trianglesFaces += indexCount / 3; + Laya.Stat.renderBatches++; + } + else { + indexCount = (this._bufferMaxParticles - this._firstActiveElement) * this._indexStride; + gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 2 * this._firstActiveElement * this._indexStride); + Laya.Stat.trianglesFaces += indexCount / 3; + Laya.Stat.renderBatches++; + if (this._firstFreeElement > 0) { + indexCount = this._firstFreeElement * this._indexStride; + gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 0); + Laya.Stat.trianglesFaces += indexCount / 3; + Laya.Stat.renderBatches++; + } + } + } + play() { + this._burstsIndex = 0; + this._isEmitting = true; + this._isPlaying = true; + this._isPaused = false; + this._emissionTime = 0; + this._totalDelayTime = 0; + if (!this.autoRandomSeed) { + for (var i = 0, n = this._randomSeeds.length; i < n; i++) + this._randomSeeds[i] = this.randomSeed[0] + ShurikenParticleSystem._RANDOMOFFSET[i]; + } + switch (this.startDelayType) { + case 0: + this._playStartDelay = this.startDelay; + break; + case 1: + if (this.autoRandomSeed) { + this._playStartDelay = Laya.MathUtil.lerp(this.startDelayMin, this.startDelayMax, Math.random()); + } + else { + this._rand.seed = this._randomSeeds[2]; + this._playStartDelay = Laya.MathUtil.lerp(this.startDelayMin, this.startDelayMax, this._rand.getFloat()); + this._randomSeeds[2] = this._rand.seed; + } + break; + default: + throw new Error("Utils3D: startDelayType is invalid."); + } + this._frameRateTime = this._currentTime + this._playStartDelay; + this._startUpdateLoopCount = Laya.Stat.loopCount; + } + pause() { + this._isPaused = true; + } + simulate(time, restart = true) { + this._simulateUpdate = true; + if (restart) { + this._updateParticlesSimulationRestart(time); + } + else { + this._isPaused = false; + this._updateParticles(time); + } + this.pause(); + } + stop() { + this._burstsIndex = 0; + this._isEmitting = false; + this._emissionTime = 0; + } + cloneTo(destObject) { + var dest = destObject; + dest._useCustomBounds = this._useCustomBounds; + (this._customBounds) && (this._customBounds.cloneTo(dest._customBounds)); + dest.duration = this.duration; + dest.looping = this.looping; + dest.prewarm = this.prewarm; + dest.startDelayType = this.startDelayType; + dest.startDelay = this.startDelay; + dest.startDelayMin = this.startDelayMin; + dest.startDelayMax = this.startDelayMax; + dest._maxStartLifetime = this._maxStartLifetime; + dest.startLifetimeType = this.startLifetimeType; + dest.startLifetimeConstant = this.startLifetimeConstant; + this.startLifeTimeGradient.cloneTo(dest.startLifeTimeGradient); + dest.startLifetimeConstantMin = this.startLifetimeConstantMin; + dest.startLifetimeConstantMax = this.startLifetimeConstantMax; + this.startLifeTimeGradientMin.cloneTo(dest.startLifeTimeGradientMin); + this.startLifeTimeGradientMax.cloneTo(dest.startLifeTimeGradientMax); + dest.startSpeedType = this.startSpeedType; + dest.startSpeedConstant = this.startSpeedConstant; + dest.startSpeedConstantMin = this.startSpeedConstantMin; + dest.startSpeedConstantMax = this.startSpeedConstantMax; + dest.threeDStartSize = this.threeDStartSize; + dest.startSizeType = this.startSizeType; + dest.startSizeConstant = this.startSizeConstant; + this.startSizeConstantSeparate.cloneTo(dest.startSizeConstantSeparate); + dest.startSizeConstantMin = this.startSizeConstantMin; + dest.startSizeConstantMax = this.startSizeConstantMax; + this.startSizeConstantMinSeparate.cloneTo(dest.startSizeConstantMinSeparate); + this.startSizeConstantMaxSeparate.cloneTo(dest.startSizeConstantMaxSeparate); + dest.threeDStartRotation = this.threeDStartRotation; + dest.startRotationType = this.startRotationType; + dest.startRotationConstant = this.startRotationConstant; + this.startRotationConstantSeparate.cloneTo(dest.startRotationConstantSeparate); + dest.startRotationConstantMin = this.startRotationConstantMin; + dest.startRotationConstantMax = this.startRotationConstantMax; + this.startRotationConstantMinSeparate.cloneTo(dest.startRotationConstantMinSeparate); + this.startRotationConstantMaxSeparate.cloneTo(dest.startRotationConstantMaxSeparate); + dest.randomizeRotationDirection = this.randomizeRotationDirection; + dest.startColorType = this.startColorType; + this.startColorConstant.cloneTo(dest.startColorConstant); + this.startColorConstantMin.cloneTo(dest.startColorConstantMin); + this.startColorConstantMax.cloneTo(dest.startColorConstantMax); + dest.gravityModifier = this.gravityModifier; + dest.simulationSpace = this.simulationSpace; + dest.scaleMode = this.scaleMode; + dest.playOnAwake = this.playOnAwake; + dest.autoRandomSeed = this.autoRandomSeed; + dest.randomSeed[0] = this.randomSeed[0]; + dest.maxParticles = this.maxParticles; + (this._emission) && (dest._emission = this._emission.clone()); + (this.shape) && (dest.shape = this.shape.clone()); + (this.velocityOverLifetime) && (dest.velocityOverLifetime = this.velocityOverLifetime.clone()); + (this.colorOverLifetime) && (dest.colorOverLifetime = this.colorOverLifetime.clone()); + (this.sizeOverLifetime) && (dest.sizeOverLifetime = this.sizeOverLifetime.clone()); + (this.rotationOverLifetime) && (dest.rotationOverLifetime = this.rotationOverLifetime.clone()); + (this.textureSheetAnimation) && (dest.textureSheetAnimation = this.textureSheetAnimation.clone()); + dest.isPerformanceMode = this.isPerformanceMode; + dest._isEmitting = this._isEmitting; + dest._isPlaying = this._isPlaying; + dest._isPaused = this._isPaused; + dest._playStartDelay = this._playStartDelay; + dest._frameRateTime = this._frameRateTime; + dest._emissionTime = this._emissionTime; + dest._totalDelayTime = this._totalDelayTime; + dest._burstsIndex = this._burstsIndex; + } + clone() { + var dest = new ShurikenParticleSystem(null); + this.cloneTo(dest); + return dest; + } + } + ShurikenParticleSystem._RANDOMOFFSET = new Uint32Array([0x23571a3e, 0xc34f56fe, 0x13371337, 0x12460f3b, 0x6aed452e, 0xdec4aea1, 0x96aa4de3, 0x8d2c8431, 0xf3857f6f, 0xe0fbd834, 0x13740583, 0x591bc05c, 0x40eb95e4, 0xbc524e5f, 0xaf502044, 0xa614b381, 0x1034e524, 0xfc524e5f]); + ShurikenParticleSystem.halfKSqrtOf2 = 1.42 * 0.5; + ShurikenParticleSystem.g = 9.8; + ShurikenParticleSystem._maxElapsedTime = 1.0 / 3.0; + ShurikenParticleSystem._tempVector30 = new Vector3(); + ShurikenParticleSystem._tempVector31 = new Vector3(); + ShurikenParticleSystem._tempVector32 = new Vector3(); + ShurikenParticleSystem._tempVector33 = new Vector3(); + ShurikenParticleSystem._tempVector34 = new Vector3(); + ShurikenParticleSystem._tempVector35 = new Vector3(); + ShurikenParticleSystem._tempVector36 = new Vector3(); + ShurikenParticleSystem._tempVector37 = new Vector3(); + ShurikenParticleSystem._tempPosition = new Vector3(); + ShurikenParticleSystem._tempDirection = new Vector3(); + ShurikenParticleSystem._type = GeometryElement._typeCounter++; + + class ShuriKenParticle3D extends RenderableSprite3D { + constructor() { + super(null); + this._render = new ShurikenParticleRenderer(this); + this._particleSystem = new ShurikenParticleSystem(this); + var elements = this._render._renderElements; + var element = elements[0] = new RenderElement(); + element.setTransform(this._transform); + element.render = this._render; + element.setGeometry(this._particleSystem); + element.material = ShurikenParticleMaterial.defaultMaterial; + } + static __init__() { + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_BILLBOARD = Shader3D.getDefineByName("SPHERHBILLBOARD"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_STRETCHEDBILLBOARD = Shader3D.getDefineByName("STRETCHEDBILLBOARD"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_HORIZONTALBILLBOARD = Shader3D.getDefineByName("HORIZONTALBILLBOARD"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_VERTICALBILLBOARD = Shader3D.getDefineByName("VERTICALBILLBOARD"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_COLOROVERLIFETIME = Shader3D.getDefineByName("COLOROVERLIFETIME"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RANDOMCOLOROVERLIFETIME = Shader3D.getDefineByName("RANDOMCOLOROVERLIFETIME"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMECONSTANT = Shader3D.getDefineByName("VELOCITYOVERLIFETIMECONSTANT"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMECURVE = Shader3D.getDefineByName("VELOCITYOVERLIFETIMECURVE"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMERANDOMCONSTANT = Shader3D.getDefineByName("VELOCITYOVERLIFETIMERANDOMCONSTANT"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_VELOCITYOVERLIFETIMERANDOMCURVE = Shader3D.getDefineByName("VELOCITYOVERLIFETIMERANDOMCURVE"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_TEXTURESHEETANIMATIONCURVE = Shader3D.getDefineByName("TEXTURESHEETANIMATIONCURVE"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_TEXTURESHEETANIMATIONRANDOMCURVE = Shader3D.getDefineByName("TEXTURESHEETANIMATIONRANDOMCURVE"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIME = Shader3D.getDefineByName("ROTATIONOVERLIFETIME"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMESEPERATE = Shader3D.getDefineByName("ROTATIONOVERLIFETIMESEPERATE"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMECONSTANT = Shader3D.getDefineByName("ROTATIONOVERLIFETIMECONSTANT"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMECURVE = Shader3D.getDefineByName("ROTATIONOVERLIFETIMECURVE"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMERANDOMCONSTANTS = Shader3D.getDefineByName("ROTATIONOVERLIFETIMERANDOMCONSTANTS"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_ROTATIONOVERLIFETIMERANDOMCURVES = Shader3D.getDefineByName("ROTATIONOVERLIFETIMERANDOMCURVES"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMECURVE = Shader3D.getDefineByName("SIZEOVERLIFETIMECURVE"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMECURVESEPERATE = Shader3D.getDefineByName("SIZEOVERLIFETIMECURVESEPERATE"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMERANDOMCURVES = Shader3D.getDefineByName("SIZEOVERLIFETIMERANDOMCURVES"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SIZEOVERLIFETIMERANDOMCURVESSEPERATE = Shader3D.getDefineByName("SIZEOVERLIFETIMERANDOMCURVESSEPERATE"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_RENDERMODE_MESH = Shader3D.getDefineByName("RENDERMODE_MESH"); + ShuriKenParticle3DShaderDeclaration.SHADERDEFINE_SHAPE = Shader3D.getDefineByName("SHAPE"); + } + get particleSystem() { + return this._particleSystem; + } + get particleRenderer() { + return this._render; + } + _parseModule(module, moduleData) { + for (var t in moduleData) { + switch (t) { + case "bases": + var bases = moduleData.bases; + for (var k in bases) + module[k] = bases[k]; + break; + case "vector2s": + var vector2s = moduleData.vector2s; + for (var k in vector2s) { + var vec2 = module[k]; + var vec2Data = vector2s[k]; + vec2.setValue(vec2Data[0], vec2Data[1]); + module[k] = vec2; + } + break; + case "vector3s": + var vector3s = moduleData.vector3s; + for (var k in vector3s) { + var vec3 = module[k]; + var vec3Data = vector3s[k]; + vec3.setValue(vec3Data[0], vec3Data[1], vec3Data[2]); + module[k] = vec3; + } + break; + case "vector4s": + var vector4s = moduleData.vector4s; + for (var k in vector4s) { + var vec4 = module[k]; + var vec4Data = vector4s[k]; + vec4.setValue(vec4Data[0], vec4Data[1], vec4Data[2], vec4Data[3]); + module[k] = vec4; + } + break; + case "gradientDataNumbers": + var gradientDataNumbers = moduleData.gradientDataNumbers; + for (var k in gradientDataNumbers) { + var gradientNumber = module[k]; + var gradientNumberData = moduleData[k]; + for (var i = 0, n = gradientNumberData.length; i < n; i++) { + var valueData = gradientNumberData[i]; + gradientNumber.add(valueData.key, valueData.value); + } + module[k] = gradientNumber; + } + break; + case "resources": + var resources = moduleData.resources; + for (var k in resources) + module[k] = Laya.Loader.getRes(resources[k]); + break; + case "bursts": + var burstsData = moduleData.bursts; + for (var i = 0, n = burstsData.length; i < n; i++) { + var brust = burstsData[i]; + module.addBurst(new Burst(brust.time, brust.min, brust.max)); + } + break; + case "randomSeed": + module.randomSeed[0] = moduleData.randomSeed; + break; + case "shapeType": + case "type": + case "color": + case "size": + case "frame": + case "startFrame": + case "angularVelocity": + case "velocity": + break; + default: + throw "ShurikenParticle3D:unknown type."; + } + } + } + _parse(data, spriteMap) { + super._parse(data, spriteMap); + if (data.main) { + var particleSystem = this.particleSystem; + var particleRender = this.particleRenderer; + this._parseModule(particleRender, data.renderer); + this._parseModule(particleSystem, data.main); + this._parseModule(particleSystem.emission, data.emission); + var shapeData = data.shape; + if (shapeData) { + var shape; + switch (shapeData.shapeType) { + case 0: + shape = new SphereShape(); + break; + case 1: + shape = new HemisphereShape(); + break; + case 2: + shape = new ConeShape(); + break; + case 3: + shape = new BoxShape(); + break; + case 7: + shape = new CircleShape(); + break; + default: + throw "ShuriKenParticle3D:unknown shape type."; + } + this._parseModule(shape, shapeData); + particleSystem.shape = shape; + } + var velocityOverLifetimeData = data.velocityOverLifetime; + if (velocityOverLifetimeData) { + var velocityData = velocityOverLifetimeData.velocity; + var velocity; + switch (velocityData.type) { + case 0: + var constantData = velocityData.constant; + velocity = GradientVelocity.createByConstant(constantData ? new Vector3(constantData[0], constantData[1], constantData[2]) : new Vector3(0, 0, 0)); + break; + case 1: + velocity = GradientVelocity.createByGradient(this._initParticleVelocity(velocityData.gradientX), this._initParticleVelocity(velocityData.gradientY), this._initParticleVelocity(velocityData.gradientZ)); + break; + case 2: + var constantMinData = velocityData.constantMin; + var constantMaxData = velocityData.constantMax; + velocity = GradientVelocity.createByRandomTwoConstant(constantMinData ? new Vector3(constantMinData[0], constantMinData[1], constantMinData[2]) : new Vector3(0, 0, 0), constantMaxData ? new Vector3(constantMaxData[0], constantMaxData[1], constantMaxData[2]) : new Vector3(0, 0, 0)); + break; + case 3: + velocity = GradientVelocity.createByRandomTwoGradient(this._initParticleVelocity(velocityData.gradientXMin), this._initParticleVelocity(velocityData.gradientXMax), this._initParticleVelocity(velocityData.gradientYMin), this._initParticleVelocity(velocityData.gradientYMax), this._initParticleVelocity(velocityData.gradientZMin), this._initParticleVelocity(velocityData.gradientZMax)); + break; + } + var velocityOverLifetime = new VelocityOverLifetime(velocity); + this._parseModule(velocityOverLifetime, velocityOverLifetimeData); + particleSystem.velocityOverLifetime = velocityOverLifetime; + } + var colorOverLifetimeData = data.colorOverLifetime; + if (colorOverLifetimeData) { + var colorData = colorOverLifetimeData.color; + var color; + switch (colorData.type) { + case 0: + var constColorData = colorData.constant; + color = GradientColor.createByConstant(constColorData ? new Vector4(constColorData[0], constColorData[1], constColorData[2], constColorData[3]) : new Vector4(0, 0, 0, 0)); + break; + case 1: + color = GradientColor.createByGradient(this._initParticleColor(colorData.gradient)); + break; + case 2: + var minConstColorData = colorData.constantMin; + var maxConstColorData = colorData.constantMax; + color = GradientColor.createByRandomTwoConstant(minConstColorData ? new Vector4(minConstColorData[0], minConstColorData[1], minConstColorData[2], minConstColorData[3]) : new Vector4(0, 0, 0, 0), minConstColorData ? new Vector4(maxConstColorData[0], maxConstColorData[1], maxConstColorData[2], maxConstColorData[3]) : new Vector4(0, 0, 0, 0)); + break; + case 3: + color = GradientColor.createByRandomTwoGradient(this._initParticleColor(colorData.gradientMin), this._initParticleColor(colorData.gradientMax)); + break; + } + var colorOverLifetime = new ColorOverLifetime(color); + this._parseModule(colorOverLifetime, colorOverLifetimeData); + particleSystem.colorOverLifetime = colorOverLifetime; + } + var sizeOverLifetimeData = data.sizeOverLifetime; + if (sizeOverLifetimeData) { + var sizeData = sizeOverLifetimeData.size; + var size; + switch (sizeData.type) { + case 0: + if (sizeData.separateAxes) { + size = GradientSize.createByGradientSeparate(this._initParticleSize(sizeData.gradientX), this._initParticleSize(sizeData.gradientY), this._initParticleSize(sizeData.gradientZ)); + } + else { + size = GradientSize.createByGradient(this._initParticleSize(sizeData.gradient)); + } + break; + case 1: + if (sizeData.separateAxes) { + var constantMinSeparateData = sizeData.constantMinSeparate; + var constantMaxSeparateData = sizeData.constantMaxSeparate; + size = GradientSize.createByRandomTwoConstantSeparate(constantMinSeparateData ? new Vector3(constantMinSeparateData[0], constantMinSeparateData[1], constantMinSeparateData[2]) : new Vector3(0, 0, 0), constantMaxSeparateData ? new Vector3(constantMaxSeparateData[0], constantMaxSeparateData[1], constantMaxSeparateData[2]) : new Vector3(0, 0, 0)); + } + else { + size = GradientSize.createByRandomTwoConstant(sizeData.constantMin || 0, sizeData.constantMax || 0); + } + break; + case 2: + if (sizeData.separateAxes) { + size = GradientSize.createByRandomTwoGradientSeparate(this._initParticleSize(sizeData.gradientXMin), this._initParticleSize(sizeData.gradientYMin), this._initParticleSize(sizeData.gradientZMin), this._initParticleSize(sizeData.gradientXMax), this._initParticleSize(sizeData.gradientYMax), this._initParticleSize(sizeData.gradientZMax)); + } + else { + size = GradientSize.createByRandomTwoGradient(this._initParticleSize(sizeData.gradientMin), this._initParticleSize(sizeData.gradientMax)); + } + break; + } + var sizeOverLifetime = new SizeOverLifetime(size); + this._parseModule(sizeOverLifetime, sizeOverLifetimeData); + particleSystem.sizeOverLifetime = sizeOverLifetime; + } + var rotationOverLifetimeData = data.rotationOverLifetime; + if (rotationOverLifetimeData) { + var angularVelocityData = rotationOverLifetimeData.angularVelocity; + var angularVelocity; + switch (angularVelocityData.type) { + case 0: + if (angularVelocityData.separateAxes) { + var conSep = angularVelocityData.constantSeparate; + angularVelocity = GradientAngularVelocity.createByConstantSeparate(conSep ? new Vector3(conSep[0], conSep[1], conSep[2]) : new Vector3(0, 0, Math.PI / 4)); + } + else { + angularVelocity = GradientAngularVelocity.createByConstant(angularVelocityData.constant || Math.PI / 4); + } + break; + case 1: + if (angularVelocityData.separateAxes) { + angularVelocity = GradientAngularVelocity.createByGradientSeparate(this._initParticleRotation(angularVelocityData.gradientX), this._initParticleRotation(angularVelocityData.gradientY), this._initParticleRotation(angularVelocityData.gradientZ)); + } + else { + angularVelocity = GradientAngularVelocity.createByGradient(this._initParticleRotation(angularVelocityData.gradient)); + } + break; + case 2: + if (angularVelocityData.separateAxes) { + var minSep = angularVelocityData.constantMinSeparate; + var maxSep = angularVelocityData.constantMaxSeparate; + angularVelocity = GradientAngularVelocity.createByRandomTwoConstantSeparate(minSep ? new Vector3(minSep[0], minSep[1], minSep[2]) : new Vector3(0, 0, 0), maxSep ? new Vector3(maxSep[0], maxSep[1], maxSep[2]) : new Vector3(0, 0, Math.PI / 4)); + } + else { + angularVelocity = GradientAngularVelocity.createByRandomTwoConstant(angularVelocityData.constantMin || 0, angularVelocityData.constantMax || Math.PI / 4); + } + break; + case 3: + if (angularVelocityData.separateAxes) ; + else { + angularVelocity = GradientAngularVelocity.createByRandomTwoGradient(this._initParticleRotation(angularVelocityData.gradientMin), this._initParticleRotation(angularVelocityData.gradientMax)); + } + break; + } + var rotationOverLifetime = new RotationOverLifetime(angularVelocity); + this._parseModule(rotationOverLifetime, rotationOverLifetimeData); + particleSystem.rotationOverLifetime = rotationOverLifetime; + } + var textureSheetAnimationData = data.textureSheetAnimation; + if (textureSheetAnimationData) { + var frameData = textureSheetAnimationData.frame; + var frameOverTime; + switch (frameData.type) { + case 0: + frameOverTime = FrameOverTime.createByConstant(frameData.constant); + break; + case 1: + frameOverTime = FrameOverTime.createByOverTime(this._initParticleFrame(frameData.overTime)); + break; + case 2: + frameOverTime = FrameOverTime.createByRandomTwoConstant(frameData.constantMin, frameData.constantMax); + break; + case 3: + frameOverTime = FrameOverTime.createByRandomTwoOverTime(this._initParticleFrame(frameData.overTimeMin), this._initParticleFrame(frameData.overTimeMax)); + break; + } + var startFrameData = textureSheetAnimationData.startFrame; + var startFrame; + switch (startFrameData.type) { + case 0: + startFrame = StartFrame.createByConstant(startFrameData.constant); + break; + case 1: + startFrame = StartFrame.createByRandomTwoConstant(startFrameData.constantMin, startFrameData.constantMax); + break; + } + var textureSheetAnimation = new TextureSheetAnimation(frameOverTime, startFrame); + this._parseModule(textureSheetAnimation, textureSheetAnimationData); + particleSystem.textureSheetAnimation = textureSheetAnimation; + } + } + else { + this._parseOld(data); + } + } + _activeHierarchy(activeChangeComponents) { + super._activeHierarchy(activeChangeComponents); + (this.particleSystem.playOnAwake) && (this.particleSystem.play()); + } + _inActiveHierarchy(activeChangeComponents) { + super._inActiveHierarchy(activeChangeComponents); + (this.particleSystem.isAlive) && (this.particleSystem.simulate(0, true)); + } + _cloneTo(destObject, srcSprite, dstSprite) { + var destShuriKenParticle3D = destObject; + var destParticleSystem = destShuriKenParticle3D._particleSystem; + this._particleSystem.cloneTo(destParticleSystem); + var destParticleRender = destShuriKenParticle3D._render; + var particleRender = this._render; + destParticleRender.sharedMaterials = particleRender.sharedMaterials; + destParticleRender.enable = particleRender.enable; + destParticleRender.renderMode = particleRender.renderMode; + destParticleRender.mesh = particleRender.mesh; + destParticleRender.stretchedBillboardCameraSpeedScale = particleRender.stretchedBillboardCameraSpeedScale; + destParticleRender.stretchedBillboardSpeedScale = particleRender.stretchedBillboardSpeedScale; + destParticleRender.stretchedBillboardLengthScale = particleRender.stretchedBillboardLengthScale; + destParticleRender.sortingFudge = particleRender.sortingFudge; + super._cloneTo(destObject, srcSprite, dstSprite); + } + destroy(destroyChild = true) { + if (this.destroyed) + return; + super.destroy(destroyChild); + this._particleSystem.destroy(); + this._particleSystem = null; + } + _create() { + return new ShuriKenParticle3D(); + } + _parseOld(data) { + const anglelToRad = Math.PI / 180.0; + var i, n; + var particleRender = this.particleRenderer; + var material; + var materialData = data.material; + (materialData) && (material = Laya.Loader.getRes(materialData.path)); + particleRender.sharedMaterial = material; + var meshPath = data.meshPath; + (meshPath) && (particleRender.mesh = Laya.Loader.getRes(meshPath)); + particleRender.renderMode = data.renderMode; + particleRender.stretchedBillboardCameraSpeedScale = data.stretchedBillboardCameraSpeedScale; + particleRender.stretchedBillboardSpeedScale = data.stretchedBillboardSpeedScale; + particleRender.stretchedBillboardLengthScale = data.stretchedBillboardLengthScale; + particleRender.sortingFudge = data.sortingFudge ? data.sortingFudge : 0.0; + var particleSystem = this.particleSystem; + particleSystem.isPerformanceMode = data.isPerformanceMode; + particleSystem.duration = data.duration; + particleSystem.looping = data.looping; + particleSystem.prewarm = data.prewarm; + particleSystem.startDelayType = data.startDelayType; + particleSystem.startDelay = data.startDelay; + particleSystem.startDelayMin = data.startDelayMin; + particleSystem.startDelayMax = data.startDelayMax; + particleSystem.startLifetimeType = data.startLifetimeType; + particleSystem.startLifetimeConstant = data.startLifetimeConstant; + particleSystem.startLifeTimeGradient = ShuriKenParticle3D._initStartLife(data.startLifetimeGradient); + particleSystem.startLifetimeConstantMin = data.startLifetimeConstantMin; + particleSystem.startLifetimeConstantMax = data.startLifetimeConstantMax; + particleSystem.startLifeTimeGradientMin = ShuriKenParticle3D._initStartLife(data.startLifetimeGradientMin); + particleSystem.startLifeTimeGradientMax = ShuriKenParticle3D._initStartLife(data.startLifetimeGradientMax); + particleSystem.startSpeedType = data.startSpeedType; + particleSystem.startSpeedConstant = data.startSpeedConstant; + particleSystem.startSpeedConstantMin = data.startSpeedConstantMin; + particleSystem.startSpeedConstantMax = data.startSpeedConstantMax; + particleSystem.threeDStartSize = data.threeDStartSize; + particleSystem.startSizeType = data.startSizeType; + particleSystem.startSizeConstant = data.startSizeConstant; + var startSizeConstantSeparateArray = data.startSizeConstantSeparate; + var startSizeConstantSeparateElement = particleSystem.startSizeConstantSeparate; + startSizeConstantSeparateElement.x = startSizeConstantSeparateArray[0]; + startSizeConstantSeparateElement.y = startSizeConstantSeparateArray[1]; + startSizeConstantSeparateElement.z = startSizeConstantSeparateArray[2]; + particleSystem.startSizeConstantMin = data.startSizeConstantMin; + particleSystem.startSizeConstantMax = data.startSizeConstantMax; + var startSizeConstantMinSeparateArray = data.startSizeConstantMinSeparate; + var startSizeConstantMinSeparateElement = particleSystem.startSizeConstantMinSeparate; + startSizeConstantMinSeparateElement.x = startSizeConstantMinSeparateArray[0]; + startSizeConstantMinSeparateElement.y = startSizeConstantMinSeparateArray[1]; + startSizeConstantMinSeparateElement.z = startSizeConstantMinSeparateArray[2]; + var startSizeConstantMaxSeparateArray = data.startSizeConstantMaxSeparate; + var startSizeConstantMaxSeparateElement = particleSystem.startSizeConstantMaxSeparate; + startSizeConstantMaxSeparateElement.x = startSizeConstantMaxSeparateArray[0]; + startSizeConstantMaxSeparateElement.y = startSizeConstantMaxSeparateArray[1]; + startSizeConstantMaxSeparateElement.z = startSizeConstantMaxSeparateArray[2]; + particleSystem.threeDStartRotation = data.threeDStartRotation; + particleSystem.startRotationType = data.startRotationType; + particleSystem.startRotationConstant = data.startRotationConstant * anglelToRad; + var startRotationConstantSeparateArray = data.startRotationConstantSeparate; + var startRotationConstantSeparateElement = particleSystem.startRotationConstantSeparate; + startRotationConstantSeparateElement.x = startRotationConstantSeparateArray[0] * anglelToRad; + startRotationConstantSeparateElement.y = startRotationConstantSeparateArray[1] * anglelToRad; + startRotationConstantSeparateElement.z = startRotationConstantSeparateArray[2] * anglelToRad; + particleSystem.startRotationConstantMin = data.startRotationConstantMin * anglelToRad; + particleSystem.startRotationConstantMax = data.startRotationConstantMax * anglelToRad; + var startRotationConstantMinSeparateArray = data.startRotationConstantMinSeparate; + var startRotationConstantMinSeparateElement = particleSystem.startRotationConstantMinSeparate; + startRotationConstantMinSeparateElement.x = startRotationConstantMinSeparateArray[0] * anglelToRad; + startRotationConstantMinSeparateElement.y = startRotationConstantMinSeparateArray[1] * anglelToRad; + startRotationConstantMinSeparateElement.z = startRotationConstantMinSeparateArray[2] * anglelToRad; + var startRotationConstantMaxSeparateArray = data.startRotationConstantMaxSeparate; + var startRotationConstantMaxSeparateElement = particleSystem.startRotationConstantMaxSeparate; + startRotationConstantMaxSeparateElement.x = startRotationConstantMaxSeparateArray[0] * anglelToRad; + startRotationConstantMaxSeparateElement.y = startRotationConstantMaxSeparateArray[1] * anglelToRad; + startRotationConstantMaxSeparateElement.z = startRotationConstantMaxSeparateArray[2] * anglelToRad; + particleSystem.randomizeRotationDirection = data.randomizeRotationDirection; + particleSystem.startColorType = data.startColorType; + var startColorConstantArray = data.startColorConstant; + var startColorConstantElement = particleSystem.startColorConstant; + startColorConstantElement.x = startColorConstantArray[0]; + startColorConstantElement.y = startColorConstantArray[1]; + startColorConstantElement.z = startColorConstantArray[2]; + startColorConstantElement.w = startColorConstantArray[3]; + var startColorConstantMinArray = data.startColorConstantMin; + var startColorConstantMinElement = particleSystem.startColorConstantMin; + startColorConstantMinElement.x = startColorConstantMinArray[0]; + startColorConstantMinElement.y = startColorConstantMinArray[1]; + startColorConstantMinElement.z = startColorConstantMinArray[2]; + startColorConstantMinElement.w = startColorConstantMinArray[3]; + var startColorConstantMaxArray = data.startColorConstantMax; + var startColorConstantMaxElement = particleSystem.startColorConstantMax; + startColorConstantMaxElement.x = startColorConstantMaxArray[0]; + startColorConstantMaxElement.y = startColorConstantMaxArray[1]; + startColorConstantMaxElement.z = startColorConstantMaxArray[2]; + startColorConstantMaxElement.w = startColorConstantMaxArray[3]; + particleSystem.gravityModifier = data.gravityModifier; + particleSystem.simulationSpace = data.simulationSpace; + (data.simulationSpeed !== undefined) && (particleSystem.simulationSpeed = data.simulationSpeed); + particleSystem.scaleMode = data.scaleMode; + particleSystem.playOnAwake = data.playOnAwake; + particleSystem.maxParticles = data.maxParticles; + var autoRandomSeed = data.autoRandomSeed; + (autoRandomSeed != null) && (particleSystem.autoRandomSeed = autoRandomSeed); + var randomSeed = data.randomSeed; + (randomSeed != null) && (particleSystem.randomSeed[0] = randomSeed); + var emissionData = data.emission; + var emission = particleSystem.emission; + if (emissionData) { + emission.emissionRate = emissionData.emissionRate; + var burstsData = emissionData.bursts; + if (burstsData) + for (i = 0, n = burstsData.length; i < n; i++) { + var brust = burstsData[i]; + emission.addBurst(new Burst(brust.time, brust.min, brust.max)); + } + emission.enable = emissionData.enable; + } + else { + emission.enable = false; + } + var shapeData = data.shape; + if (shapeData) { + var shape; + switch (shapeData.shapeType) { + case 0: + var sphereShape; + shape = sphereShape = new SphereShape(); + sphereShape.radius = shapeData.sphereRadius; + sphereShape.emitFromShell = shapeData.sphereEmitFromShell; + sphereShape.randomDirection = shapeData.sphereRandomDirection; + break; + case 1: + var hemiSphereShape; + shape = hemiSphereShape = new HemisphereShape(); + hemiSphereShape.radius = shapeData.hemiSphereRadius; + hemiSphereShape.emitFromShell = shapeData.hemiSphereEmitFromShell; + hemiSphereShape.randomDirection = shapeData.hemiSphereRandomDirection; + break; + case 2: + var coneShape; + shape = coneShape = new ConeShape(); + coneShape.angle = shapeData.coneAngle * anglelToRad; + coneShape.radius = shapeData.coneRadius; + coneShape.length = shapeData.coneLength; + coneShape.emitType = shapeData.coneEmitType; + coneShape.randomDirection = shapeData.coneRandomDirection; + break; + case 3: + var boxShape; + shape = boxShape = new BoxShape(); + boxShape.x = shapeData.boxX; + boxShape.y = shapeData.boxY; + boxShape.z = shapeData.boxZ; + boxShape.randomDirection = shapeData.boxRandomDirection; + break; + case 7: + var circleShape; + shape = circleShape = new CircleShape(); + circleShape.radius = shapeData.circleRadius; + circleShape.arc = shapeData.circleArc * anglelToRad; + circleShape.emitFromEdge = shapeData.circleEmitFromEdge; + circleShape.randomDirection = shapeData.circleRandomDirection; + break; + default: + var tempShape; + shape = tempShape = new CircleShape(); + tempShape.radius = shapeData.circleRadius; + tempShape.arc = shapeData.circleArc * anglelToRad; + tempShape.emitFromEdge = shapeData.circleEmitFromEdge; + tempShape.randomDirection = shapeData.circleRandomDirection; + break; + } + shape.enable = shapeData.enable; + particleSystem.shape = shape; + } + var velocityOverLifetimeData = data.velocityOverLifetime; + if (velocityOverLifetimeData) { + var velocityData = velocityOverLifetimeData.velocity; + var velocity; + switch (velocityData.type) { + case 0: + var constantData = velocityData.constant; + velocity = GradientVelocity.createByConstant(new Vector3(constantData[0], constantData[1], constantData[2])); + break; + case 1: + velocity = GradientVelocity.createByGradient(this._initParticleVelocity(velocityData.gradientX), this._initParticleVelocity(velocityData.gradientY), this._initParticleVelocity(velocityData.gradientZ)); + break; + case 2: + var constantMinData = velocityData.constantMin; + var constantMaxData = velocityData.constantMax; + velocity = GradientVelocity.createByRandomTwoConstant(new Vector3(constantMinData[0], constantMinData[1], constantMinData[2]), new Vector3(constantMaxData[0], constantMaxData[1], constantMaxData[2])); + break; + case 3: + velocity = GradientVelocity.createByRandomTwoGradient(this._initParticleVelocity(velocityData.gradientXMin), this._initParticleVelocity(velocityData.gradientXMax), this._initParticleVelocity(velocityData.gradientYMin), this._initParticleVelocity(velocityData.gradientYMax), this._initParticleVelocity(velocityData.gradientZMin), this._initParticleVelocity(velocityData.gradientZMax)); + break; + } + var velocityOverLifetime = new VelocityOverLifetime(velocity); + velocityOverLifetime.space = velocityOverLifetimeData.space; + velocityOverLifetime.enable = velocityOverLifetimeData.enable; + particleSystem.velocityOverLifetime = velocityOverLifetime; + } + var colorOverLifetimeData = data.colorOverLifetime; + if (colorOverLifetimeData) { + var colorData = colorOverLifetimeData.color; + var color; + switch (colorData.type) { + case 0: + var constColorData = colorData.constant; + color = GradientColor.createByConstant(new Vector4(constColorData[0], constColorData[1], constColorData[2], constColorData[3])); + break; + case 1: + color = GradientColor.createByGradient(this._initParticleColor(colorData.gradient)); + break; + case 2: + var minConstColorData = colorData.constantMin; + var maxConstColorData = colorData.constantMax; + color = GradientColor.createByRandomTwoConstant(new Vector4(minConstColorData[0], minConstColorData[1], minConstColorData[2], minConstColorData[3]), new Vector4(maxConstColorData[0], maxConstColorData[1], maxConstColorData[2], maxConstColorData[3])); + break; + case 3: + color = GradientColor.createByRandomTwoGradient(this._initParticleColor(colorData.gradientMin), this._initParticleColor(colorData.gradientMax)); + break; + } + var colorOverLifetime = new ColorOverLifetime(color); + colorOverLifetime.enable = colorOverLifetimeData.enable; + particleSystem.colorOverLifetime = colorOverLifetime; + } + var sizeOverLifetimeData = data.sizeOverLifetime; + if (sizeOverLifetimeData) { + var sizeData = sizeOverLifetimeData.size; + var size; + switch (sizeData.type) { + case 0: + if (sizeData.separateAxes) { + size = GradientSize.createByGradientSeparate(this._initParticleSize(sizeData.gradientX), this._initParticleSize(sizeData.gradientY), this._initParticleSize(sizeData.gradientZ)); + } + else { + size = GradientSize.createByGradient(this._initParticleSize(sizeData.gradient)); + } + break; + case 1: + if (sizeData.separateAxes) { + var constantMinSeparateData = sizeData.constantMinSeparate; + var constantMaxSeparateData = sizeData.constantMaxSeparate; + size = GradientSize.createByRandomTwoConstantSeparate(new Vector3(constantMinSeparateData[0], constantMinSeparateData[1], constantMinSeparateData[2]), new Vector3(constantMaxSeparateData[0], constantMaxSeparateData[1], constantMaxSeparateData[2])); + } + else { + size = GradientSize.createByRandomTwoConstant(sizeData.constantMin, sizeData.constantMax); + } + break; + case 2: + if (sizeData.separateAxes) { + size = GradientSize.createByRandomTwoGradientSeparate(this._initParticleSize(sizeData.gradientXMin), this._initParticleSize(sizeData.gradientYMin), this._initParticleSize(sizeData.gradientZMin), this._initParticleSize(sizeData.gradientXMax), this._initParticleSize(sizeData.gradientYMax), this._initParticleSize(sizeData.gradientZMax)); + } + else { + size = GradientSize.createByRandomTwoGradient(this._initParticleSize(sizeData.gradientMin), this._initParticleSize(sizeData.gradientMax)); + } + break; + } + var sizeOverLifetime = new SizeOverLifetime(size); + sizeOverLifetime.enable = sizeOverLifetimeData.enable; + particleSystem.sizeOverLifetime = sizeOverLifetime; + } + var rotationOverLifetimeData = data.rotationOverLifetime; + if (rotationOverLifetimeData) { + var angularVelocityData = rotationOverLifetimeData.angularVelocity; + var angularVelocity; + switch (angularVelocityData.type) { + case 0: + if (angularVelocityData.separateAxes) { + var conSep = angularVelocityData.constantSeparate; + angularVelocity = GradientAngularVelocity.createByConstantSeparate(new Vector3(conSep[0] * anglelToRad, conSep[1] * anglelToRad, conSep[2] * anglelToRad)); + } + else { + angularVelocity = GradientAngularVelocity.createByConstant(angularVelocityData.constant * anglelToRad); + } + break; + case 1: + if (angularVelocityData.separateAxes) { + angularVelocity = GradientAngularVelocity.createByGradientSeparate(this._initParticleRotation(angularVelocityData.gradientX), this._initParticleRotation(angularVelocityData.gradientY), this._initParticleRotation(angularVelocityData.gradientZ)); + } + else { + angularVelocity = GradientAngularVelocity.createByGradient(this._initParticleRotation(angularVelocityData.gradient)); + } + break; + case 2: + if (angularVelocityData.separateAxes) { + var minSep = angularVelocityData.constantMinSeparate; + var maxSep = angularVelocityData.constantMaxSeparate; + angularVelocity = GradientAngularVelocity.createByRandomTwoConstantSeparate(new Vector3(minSep[0] * anglelToRad, minSep[1] * anglelToRad, minSep[2] * anglelToRad), new Vector3(maxSep[0] * anglelToRad, maxSep[1] * anglelToRad, maxSep[2] * anglelToRad)); + } + else { + angularVelocity = GradientAngularVelocity.createByRandomTwoConstant(angularVelocityData.constantMin * anglelToRad, angularVelocityData.constantMax * anglelToRad); + } + break; + case 3: + if (angularVelocityData.separateAxes) ; + else { + angularVelocity = GradientAngularVelocity.createByRandomTwoGradient(this._initParticleRotation(angularVelocityData.gradientMin), this._initParticleRotation(angularVelocityData.gradientMax)); + } + break; + } + var rotationOverLifetime = new RotationOverLifetime(angularVelocity); + rotationOverLifetime.enable = rotationOverLifetimeData.enable; + particleSystem.rotationOverLifetime = rotationOverLifetime; + } + var textureSheetAnimationData = data.textureSheetAnimation; + if (textureSheetAnimationData) { + var frameData = textureSheetAnimationData.frame; + var frameOverTime; + switch (frameData.type) { + case 0: + frameOverTime = FrameOverTime.createByConstant(frameData.constant); + break; + case 1: + frameOverTime = FrameOverTime.createByOverTime(this._initParticleFrame(frameData.overTime)); + break; + case 2: + frameOverTime = FrameOverTime.createByRandomTwoConstant(frameData.constantMin, frameData.constantMax); + break; + case 3: + frameOverTime = FrameOverTime.createByRandomTwoOverTime(this._initParticleFrame(frameData.overTimeMin), this._initParticleFrame(frameData.overTimeMax)); + break; + } + var startFrameData = textureSheetAnimationData.startFrame; + var startFrame; + switch (startFrameData.type) { + case 0: + startFrame = StartFrame.createByConstant(startFrameData.constant); + break; + case 1: + startFrame = StartFrame.createByRandomTwoConstant(startFrameData.constantMin, startFrameData.constantMax); + break; + } + var textureSheetAnimation = new TextureSheetAnimation(frameOverTime, startFrame); + textureSheetAnimation.enable = textureSheetAnimationData.enable; + var tilesData = textureSheetAnimationData.tiles; + textureSheetAnimation.tiles = new Vector2(tilesData[0], tilesData[1]); + textureSheetAnimation.type = textureSheetAnimationData.type; + textureSheetAnimation.randomRow = textureSheetAnimationData.randomRow; + var rowIndex = textureSheetAnimationData.rowIndex; + (rowIndex !== undefined) && (textureSheetAnimation.rowIndex = rowIndex); + textureSheetAnimation.cycles = textureSheetAnimationData.cycles; + particleSystem.textureSheetAnimation = textureSheetAnimation; + } + } + _initParticleColor(gradientColorData) { + var gradientColor = new Gradient(4, 4); + if (!gradientColorData) { + gradientColor.addColorAlpha(0, 1); + gradientColor.addColorAlpha(1, 1); + gradientColor.addColorRGB(0, new Color(1.0, 1.0, 1.0, 1.0)); + gradientColor.addColorRGB(1, new Color(1.0, 1.0, 1.0, 1.0)); + } + else { + var alphasData = gradientColorData.alphas; + var i, n; + if (!alphasData) { + gradientColor.addColorAlpha(0, 1); + gradientColor.addColorAlpha(1, 1); + } + else { + for (i = 0, n = alphasData.length; i < n; i++) { + if (i == 3 && n > 4) { + i = n - 1; + console.warn("GradientDataColor warning:alpha data length is large than 4, will ignore the middle data."); + } + var alphaData = alphasData[i]; + gradientColor.addColorAlpha(alphaData.key, alphaData.value); + } + } + var rgbsData = gradientColorData.rgbs; + if (!rgbsData) { + gradientColor.addColorRGB(0, new Color(1.0, 1.0, 1.0, 1.0)); + gradientColor.addColorRGB(1, new Color(1.0, 1.0, 1.0, 1.0)); + } + else { + for (i = 0, n = rgbsData.length; i < n; i++) { + if (i == 3 && n > 4) { + i = n - 1; + console.warn("GradientDataColor warning:rgb data length is large than 4, will ignore the middle data."); + } + var rgbData = rgbsData[i]; + var rgbValue = rgbData.value; + gradientColor.addColorRGB(rgbData.key, new Color(rgbValue[0], rgbValue[1], rgbValue[2], 1.0)); + } + } + } + return gradientColor; + } + _initParticleFrame(overTimeFramesData) { + var overTimeFrame = new GradientDataInt(); + if (overTimeFramesData) { + var framesData = overTimeFramesData.frames; + for (var i = 0, n = framesData.length; i < n; i++) { + var frameData = framesData[i]; + overTimeFrame.add(frameData.key, frameData.value); + } + } + else { + overTimeFrame.add(0, 0); + overTimeFrame.add(1, 1); + } + return overTimeFrame; + } + static _initStartLife(gradientData) { + var gradient = new GradientDataNumber(); + var startLifetimesData = gradientData.startLifetimes; + for (var i = 0, n = startLifetimesData.length; i < n; i++) { + var valueData = startLifetimesData[i]; + gradient.add(valueData.key, valueData.value); + } + return gradient; + } + _initParticleVelocity(gradientData) { + var gradient = new GradientDataNumber(); + var velocitysData = gradientData.velocitys; + for (var i = 0, n = velocitysData.length; i < n; i++) { + var valueData = velocitysData[i]; + gradient.add(valueData.key, valueData.value); + } + return gradient; + } + _initParticleSize(gradientSizeData) { + var gradientSize = new GradientDataNumber(); + if (gradientSizeData) { + var sizesData = gradientSizeData.sizes; + for (var i = 0, n = sizesData.length; i < n; i++) { + var valueData = sizesData[i]; + gradientSize.add(valueData.key, valueData.value); + } + } + else { + gradientSize.add(0, 0); + gradientSize.add(1, 1); + } + return gradientSize; + } + _initParticleRotation(gradientData) { + var gradient = new GradientDataNumber(); + var angularVelocitysData = gradientData.angularVelocitys; + for (var i = 0, n = angularVelocitysData.length; i < n; i++) { + var valueData = angularVelocitysData[i]; + gradient.add(valueData.key, valueData.value / 180.0 * Math.PI); + } + return gradient; + } + } + + class SkinnedMeshSprite3DShaderDeclaration { + } + + class SkinnedMeshRenderer extends MeshRenderer { + constructor(owner) { + super(owner); + this._bones = []; + this._skinnedDataLoopMarks = []; + this._localBounds = new Bounds(Vector3._ZERO, Vector3._ZERO); + this._cacheAnimationNode = []; + } + get localBounds() { + return this._localBounds; + } + set localBounds(value) { + this._localBounds = value; + } + get rootBone() { + return this._cacheRootBone; + } + set rootBone(value) { + if (this._cacheRootBone != value) { + if (this._cacheRootBone) + this._cacheRootBone.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange); + else + this._owner.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange); + if (value) + value.transform.on(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange); + else + this._owner.transform.on(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange); + this._cacheRootBone = value; + this._onWorldMatNeedChange(Transform3D.TRANSFORM_WORLDPOSITION | Transform3D.TRANSFORM_WORLDQUATERNION | Transform3D.TRANSFORM_WORLDSCALE); + } + } + get bones() { + return this._bones; + } + _computeSkinnedData() { + if (this._cacheMesh && this._cacheAvatar || this._cacheMesh && !this._cacheAvatar) { + var bindPoses = this._cacheMesh._inverseBindPoses; + var pathMarks = this._cacheMesh._skinnedMatrixCaches; + for (var i = 0, n = this._cacheMesh.subMeshCount; i < n; i++) { + var subMeshBoneIndices = this._cacheMesh.getSubMesh(i)._boneIndicesList; + var subData = this._skinnedData[i]; + for (var j = 0, m = subMeshBoneIndices.length; j < m; j++) { + var boneIndices = subMeshBoneIndices[j]; + this._computeSubSkinnedData(bindPoses, boneIndices, subData[j], pathMarks); + } + } + } + } + _computeSubSkinnedData(bindPoses, boneIndices, data, matrixCaches) { + for (var k = 0, q = boneIndices.length; k < q; k++) { + var index = boneIndices[k]; + if (this._skinnedDataLoopMarks[index] === Laya.Stat.loopCount) { + var c = matrixCaches[index]; + var preData = this._skinnedData[c.subMeshIndex][c.batchIndex]; + var srcIndex = c.batchBoneIndex * 16; + var dstIndex = k * 16; + for (var d = 0; d < 16; d++) + data[dstIndex + d] = preData[srcIndex + d]; + } + else { + if (!this._cacheAvatar) { + Utils3D._mulMatrixArray(this._bones[index].transform.worldMatrix.elements, bindPoses[index].elements, 0, data, k * 16); + } + else { + Utils3D._mulMatrixArray(this._cacheAnimationNode[index].transform.getWorldMatrix(), bindPoses[index].elements, 0, data, k * 16); + } + this._skinnedDataLoopMarks[index] = Laya.Stat.loopCount; + } + } + } + _onWorldMatNeedChange(flag) { + this._boundsChange = true; + if (this._octreeNode) { + if (this._cacheAvatar) { + if (this._indexInOctreeMotionList === -1) + this._octreeNode._octree.addMotionObject(this); + } + else { + flag &= Transform3D.TRANSFORM_WORLDPOSITION | Transform3D.TRANSFORM_WORLDQUATERNION | Transform3D.TRANSFORM_WORLDSCALE; + if (flag) { + if (this._indexInOctreeMotionList === -1) + this._octreeNode._octree.addMotionObject(this); + } + } + } + } + _createRenderElement() { + return new RenderElement(); + } + _onMeshChange(value) { + super._onMeshChange(value); + this._cacheMesh = value; + var subMeshCount = value.subMeshCount; + this._skinnedData = []; + this._skinnedDataLoopMarks.length = value._inverseBindPoses.length; + for (var i = 0; i < subMeshCount; i++) { + var subBoneIndices = value.getSubMesh(i)._boneIndicesList; + var subCount = subBoneIndices.length; + var subData = this._skinnedData[i] = []; + for (var j = 0; j < subCount; j++) + subData[j] = new Float32Array(subBoneIndices[j].length * 16); + } + (this._cacheAvatar && value) && (this._getCacheAnimationNodes()); + } + _setCacheAnimator(animator) { + this._cacheAnimator = animator; + this._shaderValues.addDefine(SkinnedMeshSprite3DShaderDeclaration.SHADERDEFINE_BONE); + this._setRootNode(); + } + _calculateBoundingBox() { + if (!this._cacheAvatar) { + if (this._cacheRootBone) + this._localBounds._tranform(this._cacheRootBone.transform.worldMatrix, this._bounds); + else + this._localBounds._tranform(this._owner.transform.worldMatrix, this._bounds); + } + else { + if (this._cacheAnimator && this._rootBone) { + var worldMat = SkinnedMeshRenderer._tempMatrix4x4; + Utils3D.matrix4x4MultiplyMFM(this._cacheAnimator.owner.transform.worldMatrix, this._cacheRootAnimationNode.transform.getWorldMatrix(), worldMat); + this._localBounds._tranform(worldMat, this._bounds); + } + else { + super._calculateBoundingBox(); + } + } + } + _renderUpdate(context, transform) { + if (this._cacheAnimator) { + this._computeSkinnedData(); + if (!this._cacheAvatar) { + this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX, Matrix4x4.DEFAULT); + } + else { + var aniOwnerTrans = this._cacheAnimator.owner._transform; + this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX, aniOwnerTrans.worldMatrix); + } + } + else { + this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX, transform.worldMatrix); + } + if (!this._probReflection) + return; + if (this._reflectionMode == exports.ReflectionProbeMode.off) { + this._shaderValues.removeDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_SPECCUBE_BOX_PROJECTION); + this._shaderValues.setVector(RenderableSprite3D.REFLECTIONCUBE_HDR_PARAMS, ReflectionProbe.defaultTextureHDRDecodeValues); + this._shaderValues.setTexture(RenderableSprite3D.REFLECTIONTEXTURE, TextureCube.blackTexture); + } + else { + if (!this._probReflection.boxProjection) { + this._shaderValues.removeDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_SPECCUBE_BOX_PROJECTION); + } + else { + this._shaderValues.addDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_SPECCUBE_BOX_PROJECTION); + this._shaderValues.setVector3(RenderableSprite3D.REFLECTIONCUBE_PROBEPOSITION, this._probReflection.probePosition); + this._shaderValues.setVector3(RenderableSprite3D.REFLECTIONCUBE_PROBEBOXMAX, this._probReflection.boundsMax); + this._shaderValues.setVector3(RenderableSprite3D.REFLECTIONCUBE_PROBEBOXMIN, this._probReflection.boundsMin); + } + this._shaderValues.setTexture(RenderableSprite3D.REFLECTIONTEXTURE, this._probReflection.reflectionTexture); + this._shaderValues.setVector(RenderableSprite3D.REFLECTIONCUBE_HDR_PARAMS, this._probReflection.reflectionHDRParams); + } + } + _renderUpdateWithCamera(context, transform) { + var projectionView = context.projectionViewMatrix; + if (this._cacheAnimator) { + if (!this._cacheAvatar) { + this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX, projectionView); + } + else { + var aniOwnerTrans = this._cacheAnimator.owner._transform; + Matrix4x4.multiply(projectionView, aniOwnerTrans.worldMatrix, this._projectionViewWorldMatrix); + this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX, this._projectionViewWorldMatrix); + } + } + else { + Matrix4x4.multiply(projectionView, transform.worldMatrix, this._projectionViewWorldMatrix); + this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX, this._projectionViewWorldMatrix); + } + } + _destroy() { + super._destroy(); + if (!this._cacheAvatar) { + if (this._cacheRootBone) + (!this._cacheRootBone.destroyed) && (this._cacheRootBone.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange)); + else + (this._owner && !this._owner.destroyed) && (this._owner.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange)); + } + else { + if (this._cacheRootAnimationNode) + this._cacheRootAnimationNode.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange); + } + } + get bounds() { + if (this._boundsChange || this._cacheAvatar) { + this._calculateBoundingBox(); + this._boundsChange = false; + } + return this._bounds; + } + _setRootBone(name) { + this._rootBone = name; + this._setRootNode(); + } + _setRootNode() { + var rootNode; + if (this._cacheAnimator && this._rootBone && this._cacheAvatar) + rootNode = this._cacheAnimator._avatarNodeMap[this._rootBone]; + else + rootNode = null; + if (this._cacheRootAnimationNode != rootNode) { + this._onWorldMatNeedChange(Transform3D.TRANSFORM_WORLDPOSITION | Transform3D.TRANSFORM_WORLDQUATERNION | Transform3D.TRANSFORM_WORLDSCALE); + this._owner.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange); + if (this._cacheRootAnimationNode) + this._cacheRootAnimationNode.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange); + (rootNode) && (rootNode.transform.on(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange)); + this._cacheRootAnimationNode = rootNode; + } + } + _getCacheAnimationNodes() { + var meshBoneNames = this._cacheMesh._boneNames; + var innerBindPoseCount = this._cacheMesh._inverseBindPoses.length; + this._cacheAnimationNode.length = innerBindPoseCount; + var nodeMap = this._cacheAnimator._avatarNodeMap; + for (var i = 0; i < innerBindPoseCount; i++) { + var node = nodeMap[meshBoneNames[i]]; + this._cacheAnimationNode[i] = node; + } + } + _setCacheAvatar(value) { + if (this._cacheAvatar !== value) { + if (this._cacheMesh) { + this._cacheAvatar = value; + if (value) { + this._shaderValues.addDefine(SkinnedMeshSprite3DShaderDeclaration.SHADERDEFINE_BONE); + this._getCacheAnimationNodes(); + } + } + else { + this._cacheAvatar = value; + } + this._setRootNode(); + } + } + } + SkinnedMeshRenderer._tempMatrix4x4 = new Matrix4x4(); + + class SkinnedMeshSprite3D extends RenderableSprite3D { + constructor(mesh = null, name = null) { + super(name); + this._meshFilter = new MeshFilter(this); + this._render = new SkinnedMeshRenderer(this); + (mesh) && (this._meshFilter.sharedMesh = mesh); + } + static __init__() { + SkinnedMeshSprite3DShaderDeclaration.SHADERDEFINE_BONE = Shader3D.getDefineByName("BONE"); + SkinnedMeshSprite3DShaderDeclaration.SHADERDEFINE_SIMPLEBONE = Shader3D.getDefineByName("SIMPLEBONE"); + } + get meshFilter() { + return this._meshFilter; + } + get skinnedMeshRenderer() { + return this._render; + } + _parse(data, spriteMap) { + super._parse(data, spriteMap); + var render = this.skinnedMeshRenderer; + var lightmapIndex = data.lightmapIndex; + (lightmapIndex != null) && (render.lightmapIndex = lightmapIndex); + var lightmapScaleOffsetArray = data.lightmapScaleOffset; + (lightmapScaleOffsetArray) && (render.lightmapScaleOffset = new Vector4(lightmapScaleOffsetArray[0], lightmapScaleOffsetArray[1], lightmapScaleOffsetArray[2], lightmapScaleOffsetArray[3])); + (data.enableRender != undefined) && (render.enable = data.enableRender); + (data.receiveShadows != undefined) && (render.receiveShadow = data.receiveShadows); + (data.castShadow != undefined) && (render.castShadow = data.castShadow); + var meshPath; + meshPath = data.meshPath; + if (meshPath) { + var mesh = Laya.Loader.getRes(meshPath); + (mesh) && (this.meshFilter.sharedMesh = mesh); + } + var materials = data.materials; + if (materials) { + var sharedMaterials = render.sharedMaterials; + var materialCount = materials.length; + sharedMaterials.length = materialCount; + for (var i = 0; i < materialCount; i++) { + sharedMaterials[i] = Laya.Loader.getRes(materials[i].path); + } + render.sharedMaterials = sharedMaterials; + } + var boundBox = data.boundBox; + var min = boundBox.min; + var max = boundBox.max; + render.localBounds.setMin(new Vector3(min[0], min[1], min[2])); + render.localBounds.setMax(new Vector3(max[0], max[1], max[2])); + if (spriteMap) { + var rootBoneData = data.rootBone; + render.rootBone = spriteMap[rootBoneData]; + var bonesData = data.bones; + var n; + for (i = 0, n = bonesData.length; i < n; i++) + render.bones.push(spriteMap[bonesData[i]]); + } + else { + (data.rootBone) && (render._setRootBone(data.rootBone)); + } + } + _changeHierarchyAnimator(animator) { + super._changeHierarchyAnimator(animator); + this.skinnedMeshRenderer._setCacheAnimator(animator); + } + _changeAnimatorAvatar(avatar) { + this.skinnedMeshRenderer._setCacheAvatar(avatar); + } + _cloneTo(destObject, srcRoot, dstRoot) { + var meshSprite3D = destObject; + meshSprite3D.meshFilter.sharedMesh = this.meshFilter.sharedMesh; + var meshRender = this._render; + var destMeshRender = meshSprite3D._render; + destMeshRender.enable = meshRender.enable; + destMeshRender.sharedMaterials = meshRender.sharedMaterials; + destMeshRender.castShadow = meshRender.castShadow; + var lightmapScaleOffset = meshRender.lightmapScaleOffset; + lightmapScaleOffset && (destMeshRender.lightmapScaleOffset = lightmapScaleOffset.clone()); + destMeshRender.receiveShadow = meshRender.receiveShadow; + destMeshRender.sortingFudge = meshRender.sortingFudge; + destMeshRender._rootBone = meshRender._rootBone; + var bones = meshRender.bones; + var destBones = destMeshRender.bones; + var bonesCount = bones.length; + destBones.length = bonesCount; + var rootBone = meshRender.rootBone; + if (rootBone) { + var pathes = Utils3D._getHierarchyPath(srcRoot, rootBone, SkinnedMeshSprite3D._tempArray0); + if (pathes) + destMeshRender.rootBone = Utils3D._getNodeByHierarchyPath(dstRoot, pathes); + else + destMeshRender.rootBone = rootBone; + } + for (var i = 0; i < bones.length; i++) { + pathes = Utils3D._getHierarchyPath(srcRoot, bones[i], SkinnedMeshSprite3D._tempArray0); + if (pathes) + destBones[i] = Utils3D._getNodeByHierarchyPath(dstRoot, pathes); + else + destBones[i] = bones[i]; + } + var lbb = meshRender.localBounds; + (lbb) && (lbb.cloneTo(destMeshRender.localBounds)); + super._cloneTo(destObject, srcRoot, dstRoot); + } + destroy(destroyChild = true) { + if (this.destroyed) + return; + super.destroy(destroyChild); + this._meshFilter.destroy(); + } + _create() { + return new SkinnedMeshSprite3D(); + } + } + SkinnedMeshSprite3D._tempArray0 = []; + SkinnedMeshSprite3D.BONES = Shader3D.propertyNameToID("u_Bones"); + SkinnedMeshSprite3D.SIMPLE_SIMPLEANIMATORTEXTURE = Shader3D.propertyNameToID("u_SimpleAnimatorTexture"); + SkinnedMeshSprite3D.SIMPLE_SIMPLEANIMATORPARAMS = Shader3D.propertyNameToID("u_SimpleAnimatorParams"); + SkinnedMeshSprite3D.SIMPLE_SIMPLEANIMATORTEXTURESIZE = Shader3D.propertyNameToID("u_SimpleAnimatorTextureSize"); + + class TrailMaterial extends Material { + constructor() { + super(); + this.setShaderName("Trail"); + this._color = new Vector4(1.0, 1.0, 1.0, 1.0); + this._shaderValues.setVector(TrailMaterial.TILINGOFFSET, new Vector4(1.0, 1.0, 0.0, 0.0)); + this._shaderValues.setVector(TrailMaterial.TINTCOLOR, new Vector4(1.0, 1.0, 1.0, 1.0)); + this.renderMode = TrailMaterial.RENDERMODE_ALPHABLENDED; + } + static __initDefine__() { + TrailMaterial.SHADERDEFINE_MAINTEXTURE = Shader3D.getDefineByName("MAINTEXTURE"); + TrailMaterial.SHADERDEFINE_ADDTIVEFOG = Shader3D.getDefineByName("ADDTIVEFOG"); + } + get _TintColorR() { + return this._color.x; + } + set _TintColorR(value) { + this._color.x = value; + this.color = this._color; + } + get _TintColorG() { + return this._color.y; + } + set _TintColorG(value) { + this._color.y = value; + this.color = this._color; + } + get _TintColorB() { + return this._color.z; + } + set _TintColorB(value) { + this._color.z = value; + this.color = this._color; + } + get _TintColorA() { + return this._color.w; + } + set _TintColorA(value) { + this._color.w = value; + this.color = this._color; + } + get _MainTex_STX() { + return this._shaderValues.getVector(TrailMaterial.TILINGOFFSET).x; + } + set _MainTex_STX(x) { + var tilOff = this._shaderValues.getVector(TrailMaterial.TILINGOFFSET); + tilOff.x = x; + this.tilingOffset = tilOff; + } + get _MainTex_STY() { + return this._shaderValues.getVector(TrailMaterial.TILINGOFFSET).y; + } + set _MainTex_STY(y) { + var tilOff = this._shaderValues.getVector(TrailMaterial.TILINGOFFSET); + tilOff.y = y; + this.tilingOffset = tilOff; + } + get _MainTex_STZ() { + return this._shaderValues.getVector(TrailMaterial.TILINGOFFSET).z; + } + set _MainTex_STZ(z) { + var tilOff = this._shaderValues.getVector(TrailMaterial.TILINGOFFSET); + tilOff.z = z; + this.tilingOffset = tilOff; + } + get _MainTex_STW() { + return this._shaderValues.getVector(TrailMaterial.TILINGOFFSET).w; + } + set _MainTex_STW(w) { + var tilOff = this._shaderValues.getVector(TrailMaterial.TILINGOFFSET); + tilOff.w = w; + this.tilingOffset = tilOff; + } + set renderMode(value) { + switch (value) { + case TrailMaterial.RENDERMODE_ADDTIVE: + this.renderQueue = Material.RENDERQUEUE_TRANSPARENT; + this.alphaTest = false; + this.depthWrite = false; + this.cull = RenderState.CULL_NONE; + this.blend = RenderState.BLEND_ENABLE_ALL; + this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA; + this.blendDst = RenderState.BLENDPARAM_ONE; + this.depthTest = RenderState.DEPTHTEST_LESS; + this._shaderValues.addDefine(TrailMaterial.SHADERDEFINE_ADDTIVEFOG); + break; + case TrailMaterial.RENDERMODE_ALPHABLENDED: + this.renderQueue = Material.RENDERQUEUE_TRANSPARENT; + this.alphaTest = false; + this.depthWrite = false; + this.cull = RenderState.CULL_NONE; + this.blend = RenderState.BLEND_ENABLE_ALL; + this.blendSrc = RenderState.BLENDPARAM_SRC_ALPHA; + this.blendDst = RenderState.BLENDPARAM_ONE_MINUS_SRC_ALPHA; + this.depthTest = RenderState.DEPTHTEST_LESS; + this._shaderValues.removeDefine(TrailMaterial.SHADERDEFINE_ADDTIVEFOG); + break; + default: + throw new Error("TrailMaterial : renderMode value error."); + } + } + get colorR() { + return this._TintColorR; + } + set colorR(value) { + this._TintColorR = value; + } + get colorG() { + return this._TintColorG; + } + set colorG(value) { + this._TintColorG = value; + } + get colorB() { + return this._TintColorB; + } + set colorB(value) { + this._TintColorB = value; + } + get colorA() { + return this._TintColorA; + } + set colorA(value) { + this._TintColorA = value; + } + get color() { + return this._shaderValues.getVector(TrailMaterial.TINTCOLOR); + } + set color(value) { + this._shaderValues.setVector(TrailMaterial.TINTCOLOR, value); + } + get texture() { + return this._shaderValues.getTexture(TrailMaterial.MAINTEXTURE); + } + set texture(value) { + if (value) + this._shaderValues.addDefine(TrailMaterial.SHADERDEFINE_MAINTEXTURE); + else + this._shaderValues.removeDefine(TrailMaterial.SHADERDEFINE_MAINTEXTURE); + this._shaderValues.setTexture(TrailMaterial.MAINTEXTURE, value); + } + get tilingOffsetX() { + return this._MainTex_STX; + } + set tilingOffsetX(x) { + this._MainTex_STX = x; + } + get tilingOffsetY() { + return this._MainTex_STY; + } + set tilingOffsetY(y) { + this._MainTex_STY = y; + } + get tilingOffsetZ() { + return this._MainTex_STZ; + } + set tilingOffsetZ(z) { + this._MainTex_STZ = z; + } + get tilingOffsetW() { + return this._MainTex_STW; + } + set tilingOffsetW(w) { + this._MainTex_STW = w; + } + get tilingOffset() { + return this._shaderValues.getVector(TrailMaterial.TILINGOFFSET); + } + set tilingOffset(value) { + if (value) { + this._shaderValues.setVector(TrailMaterial.TILINGOFFSET, value); + } + else { + this._shaderValues.getVector(TrailMaterial.TILINGOFFSET).setValue(1.0, 1.0, 0.0, 0.0); + } + } + clone() { + var dest = new TrailMaterial(); + this.cloneTo(dest); + return dest; + } + } + TrailMaterial.RENDERMODE_ALPHABLENDED = 0; + TrailMaterial.RENDERMODE_ADDTIVE = 1; + TrailMaterial.MAINTEXTURE = Shader3D.propertyNameToID("u_MainTexture"); + TrailMaterial.TINTCOLOR = Shader3D.propertyNameToID("u_MainColor"); + TrailMaterial.TILINGOFFSET = Shader3D.propertyNameToID("u_TilingOffset"); + + class TextureMode { + } + TextureMode.Stretch = 0; + TextureMode.Tile = 1; + + (function (TrailAlignment) { + TrailAlignment[TrailAlignment["View"] = 0] = "View"; + TrailAlignment[TrailAlignment["TransformZ"] = 1] = "TransformZ"; + })(exports.TrailAlignment || (exports.TrailAlignment = {})); + + class VertexTrail { + static get vertexDeclaration1() { + return VertexTrail._vertexDeclaration1; + } + static get vertexDeclaration2() { + return VertexTrail._vertexDeclaration2; + } + get vertexDeclaration() { + return VertexTrail._vertexDeclaration1; + } + static __init__() { + VertexTrail._vertexDeclaration1 = new VertexDeclaration(32, [new VertexElement(0, VertexElementFormat.Vector3, VertexTrail.TRAIL_POSITION0), + new VertexElement(12, VertexElementFormat.Vector3, VertexTrail.TRAIL_OFFSETVECTOR), + new VertexElement(24, VertexElementFormat.Single, VertexTrail.TRAIL_TIME0), + new VertexElement(28, VertexElementFormat.Single, VertexTrail.TRAIL_TEXTURECOORDINATE0Y)]); + VertexTrail._vertexDeclaration2 = new VertexDeclaration(20, [new VertexElement(0, VertexElementFormat.Single, VertexTrail.TRAIL_TEXTURECOORDINATE0X), + new VertexElement(4, VertexElementFormat.Color, VertexTrail.TRAIL_COLOR)]); + } + } + VertexTrail.TRAIL_POSITION0 = 0; + VertexTrail.TRAIL_OFFSETVECTOR = 1; + VertexTrail.TRAIL_TIME0 = 2; + VertexTrail.TRAIL_TEXTURECOORDINATE0Y = 3; + VertexTrail.TRAIL_TEXTURECOORDINATE0X = 4; + VertexTrail.TRAIL_COLOR = 5; + + class TrailGeometry extends GeometryElement { + constructor(owner) { + super(); + this._floatCountPerVertices1 = 8; + this._floatCountPerVertices2 = 5; + this._increaseSegementCount = 16; + this._activeIndex = 0; + this._endIndex = 0; + this._needAddFirstVertex = false; + this._isTempEndVertex = false; + this._vertices1 = null; + this._vertices2 = null; + this._lastFixedVertexPosition = new Vector3(); + this._bufferState = new BufferState(); + this.tmpColor = new Color(); + this._disappearBoundsMode = false; + this._owner = owner; + this._segementCount = this._increaseSegementCount; + this._resizeData(this._segementCount, this._bufferState); + var bounds = this._owner._owner.trailRenderer.bounds; + var sprite3dPosition = this._owner._owner.transform.position; + bounds.setMin(sprite3dPosition); + bounds.setMax(sprite3dPosition); + } + _resizeData(segementCount, bufferState) { + this._subBirthTime = new Float32Array(segementCount); + this._subDistance = new Float64Array(segementCount); + var gl = Laya.LayaGL.instance; + var vertexCount = segementCount * 2; + var vertexDeclaration1 = VertexTrail.vertexDeclaration1; + var vertexDeclaration2 = VertexTrail.vertexDeclaration2; + var vertexBuffers = []; + var vertexbuffer1Size = vertexCount * vertexDeclaration1.vertexStride; + var vertexbuffer2Size = vertexCount * vertexDeclaration2.vertexStride; + var memorySize = vertexbuffer1Size + vertexbuffer2Size; + this._vertices1 = new Float32Array(vertexCount * this._floatCountPerVertices1); + this._vertices2 = new Float32Array(vertexCount * this._floatCountPerVertices2); + this._vertexBuffer1 = new VertexBuffer3D(vertexbuffer1Size, gl.STATIC_DRAW, false); + this._vertexBuffer1.vertexDeclaration = vertexDeclaration1; + this._vertexBuffer2 = new VertexBuffer3D(vertexbuffer2Size, gl.DYNAMIC_DRAW, false); + this._vertexBuffer2.vertexDeclaration = vertexDeclaration2; + vertexBuffers.push(this._vertexBuffer1); + vertexBuffers.push(this._vertexBuffer2); + bufferState.bind(); + bufferState.applyVertexBuffers(vertexBuffers); + bufferState.unBind(); + Laya.Resource._addMemory(memorySize, memorySize); + } + _resetData() { + var count = this._endIndex - this._activeIndex; + var oldVertices1 = new Float32Array(this._vertices1.buffer, this._floatCountPerVertices1 * 2 * this._activeIndex * 4, this._floatCountPerVertices1 * 2 * count); + var oldVertices2 = new Float32Array(this._vertices2.buffer, this._floatCountPerVertices2 * 2 * this._activeIndex * 4, this._floatCountPerVertices2 * 2 * count); + var oldSubDistance = new Float64Array(this._subDistance.buffer, this._activeIndex * 8, count); + var oldSubBirthTime = new Float32Array(this._subBirthTime.buffer, this._activeIndex * 4, count); + if (count === this._segementCount) { + var memorySize = this._vertexBuffer1._byteLength + this._vertexBuffer2._byteLength; + Laya.Resource._addMemory(-memorySize, -memorySize); + this._vertexBuffer1.destroy(); + this._vertexBuffer2.destroy(); + this._segementCount += this._increaseSegementCount; + this._resizeData(this._segementCount, this._bufferState); + } + this._vertices1.set(oldVertices1, 0); + this._vertices2.set(oldVertices2, 0); + this._subDistance.set(oldSubDistance, 0); + this._subBirthTime.set(oldSubBirthTime, 0); + this._endIndex = count; + this._activeIndex = 0; + this._vertexBuffer1.setData(this._vertices1.buffer, 0, this._floatCountPerVertices1 * 2 * this._activeIndex * 4, this._floatCountPerVertices1 * 2 * count * 4); + this._vertexBuffer2.setData(this._vertices2.buffer, 0, this._floatCountPerVertices2 * 2 * this._activeIndex * 4, this._floatCountPerVertices2 * 2 * count * 4); + } + _updateTrail(camera, lastPosition, position) { + if (!Vector3.equals(lastPosition, position)) { + if ((this._endIndex - this._activeIndex) === 0) + this._addTrailByFirstPosition(camera, position); + else + this._addTrailByNextPosition(camera, position); + } + } + _addTrailByFirstPosition(camera, position) { + (this._endIndex === this._segementCount) && (this._resetData()); + this._subDistance[this._endIndex] = 0; + this._subBirthTime[this._endIndex] = this._owner._curtime; + this._endIndex++; + position.cloneTo(this._lastFixedVertexPosition); + this._needAddFirstVertex = true; + } + _addTrailByNextPosition(camera, position) { + var delVector3 = TrailGeometry._tempVector30; + var pointAtoBVector3 = TrailGeometry._tempVector31; + switch (this._owner.alignment) { + case exports.TrailAlignment.View: + var cameraMatrix = camera.viewMatrix; + Vector3.transformCoordinate(position, cameraMatrix, TrailGeometry._tempVector33); + Vector3.transformCoordinate(this._lastFixedVertexPosition, cameraMatrix, TrailGeometry._tempVector34); + Vector3.subtract(TrailGeometry._tempVector33, TrailGeometry._tempVector34, delVector3); + Vector3.cross(TrailGeometry._tempVector33, delVector3, pointAtoBVector3); + break; + case exports.TrailAlignment.TransformZ: + Vector3.subtract(position, this._lastFixedVertexPosition, delVector3); + var forward = TrailGeometry._tempVector32; + this._owner._owner.transform.getForward(forward); + Vector3.cross(delVector3, forward, pointAtoBVector3); + break; + } + Vector3.normalize(pointAtoBVector3, pointAtoBVector3); + Vector3.scale(pointAtoBVector3, this._owner.widthMultiplier / 2, pointAtoBVector3); + var delLength = Vector3.scalarLength(delVector3); + var tempEndIndex; + var offset; + if (this._needAddFirstVertex) { + this._updateVerticesByPositionData(position, pointAtoBVector3, this._endIndex - 1); + this._needAddFirstVertex = false; + } + if (delLength - this._owner.minVertexDistance >= MathUtils3D.zeroTolerance) { + if (this._isTempEndVertex) { + tempEndIndex = this._endIndex - 1; + offset = delLength - this._subDistance[tempEndIndex]; + this._updateVerticesByPosition(position, pointAtoBVector3, delLength, tempEndIndex); + this._owner._totalLength += offset; + } + else { + (this._endIndex === this._segementCount) && (this._resetData()); + this._updateVerticesByPosition(position, pointAtoBVector3, delLength, this._endIndex); + this._owner._totalLength += delLength; + this._endIndex++; + } + position.cloneTo(this._lastFixedVertexPosition); + this._isTempEndVertex = false; + } + else { + if (this._isTempEndVertex) { + tempEndIndex = this._endIndex - 1; + offset = delLength - this._subDistance[tempEndIndex]; + this._updateVerticesByPosition(position, pointAtoBVector3, delLength, tempEndIndex); + this._owner._totalLength += offset; + } + else { + (this._endIndex === this._segementCount) && (this._resetData()); + this._updateVerticesByPosition(position, pointAtoBVector3, delLength, this._endIndex); + this._owner._totalLength += delLength; + this._endIndex++; + } + this._isTempEndVertex = true; + } + } + _updateVerticesByPositionData(position, pointAtoBVector3, index) { + var vertexOffset = this._floatCountPerVertices1 * 2 * index; + var curtime = this._owner._curtime; + this._vertices1[vertexOffset] = position.x; + this._vertices1[vertexOffset + 1] = position.y; + this._vertices1[vertexOffset + 2] = position.z; + this._vertices1[vertexOffset + 3] = -pointAtoBVector3.x; + this._vertices1[vertexOffset + 4] = -pointAtoBVector3.y; + this._vertices1[vertexOffset + 5] = -pointAtoBVector3.z; + this._vertices1[vertexOffset + 6] = curtime; + this._vertices1[vertexOffset + 7] = 1.0; + this._vertices1[vertexOffset + 8] = position.x; + this._vertices1[vertexOffset + 9] = position.y; + this._vertices1[vertexOffset + 10] = position.z; + this._vertices1[vertexOffset + 11] = pointAtoBVector3.x; + this._vertices1[vertexOffset + 12] = pointAtoBVector3.y; + this._vertices1[vertexOffset + 13] = pointAtoBVector3.z; + this._vertices1[vertexOffset + 14] = curtime; + this._vertices1[vertexOffset + 15] = 0.0; + var bounds = this._owner._owner.trailRenderer.bounds; + var min = bounds.getMin(); + var max = bounds.getMax(); + var up = TrailGeometry._tempVector35; + var down = TrailGeometry._tempVector36; + var out = TrailGeometry._tempVector32; + Vector3.add(position, pointAtoBVector3, up); + Vector3.subtract(position, pointAtoBVector3, down); + Vector3.min(down, up, out); + Vector3.min(min, out, min); + bounds.setMin(min); + Vector3.max(up, down, out); + Vector3.max(max, out, max); + bounds.setMax(max); + var floatCount = this._floatCountPerVertices1 * 2; + this._vertexBuffer1.setData(this._vertices1.buffer, vertexOffset * 4, vertexOffset * 4, floatCount * 4); + } + _updateVerticesByPosition(position, pointAtoBVector3, delDistance, index) { + this._updateVerticesByPositionData(position, pointAtoBVector3, index); + this._subDistance[index] = delDistance; + this._subBirthTime[index] = this._owner._curtime; + } + _updateVertexBufferUV() { + var bounds; + var min, max; + if (this._disappearBoundsMode) { + bounds = this._owner._owner.trailRenderer.bounds; + var sprite3dPosition = this._owner._owner.transform.position; + bounds.setMin(sprite3dPosition); + bounds.setMax(sprite3dPosition); + min = bounds.getMin(); + max = bounds.getMax(); + } + var vertexCount = this._endIndex; + var curLength = 0; + var gradient = this._owner.colorGradient; + var startAlphaIndex = gradient.colorAlphaKeysCount - 1; + var startColorIndex = gradient.colorRGBKeysCount - 1; + var totalLength = this._owner._totalLength; + var stride = this._floatCountPerVertices2 * 2; + for (var i = this._activeIndex; i < vertexCount; i++) { + (i !== this._activeIndex) && (curLength += this._subDistance[i]); + var uvX; + var lerpFactor; + if (this._owner.textureMode == TextureMode.Stretch) { + uvX = 1.0 - curLength / totalLength; + lerpFactor = uvX; + } + else { + lerpFactor = 1.0 - curLength / totalLength; + uvX = 1.0 - (totalLength - curLength); + } + startColorIndex = gradient.evaluateColorRGB(lerpFactor, this.tmpColor, startColorIndex, true); + startAlphaIndex = gradient.evaluateColorAlpha(lerpFactor, this.tmpColor, startAlphaIndex, true); + var index = i * stride; + this._vertices2[index + 0] = uvX; + this._vertices2[index + 1] = this.tmpColor.r; + this._vertices2[index + 2] = this.tmpColor.g; + this._vertices2[index + 3] = this.tmpColor.b; + this._vertices2[index + 4] = this.tmpColor.a; + this._vertices2[index + 5] = uvX; + this._vertices2[index + 6] = this.tmpColor.r; + this._vertices2[index + 7] = this.tmpColor.g; + this._vertices2[index + 8] = this.tmpColor.b; + this._vertices2[index + 9] = this.tmpColor.a; + if (this._disappearBoundsMode) { + var posOffset = this._floatCountPerVertices1 * 2 * i; + var pos = TrailGeometry._tempVector32; + var up = TrailGeometry._tempVector33; + var side = TrailGeometry._tempVector34; + pos.setValue(this._vertices1[posOffset + 0], this._vertices1[posOffset + 1], this._vertices1[posOffset + 2]); + up.setValue(this._vertices1[posOffset + 3], this._vertices1[posOffset + 4], this._vertices1[posOffset + 5]); + Vector3.add(pos, up, side); + Vector3.min(side, min, min); + Vector3.max(side, max, max); + Vector3.subtract(pos, up, side); + Vector3.min(side, min, min); + Vector3.max(side, max, max); + } + } + if (this._disappearBoundsMode) { + bounds.setMin(min); + bounds.setMax(max); + this._disappearBoundsMode = false; + } + var offset = this._activeIndex * stride; + this._vertexBuffer2.setData(this._vertices2.buffer, offset * 4, offset * 4, (vertexCount * stride - offset) * 4); + } + _updateDisappear() { + var count = this._endIndex; + for (var i = this._activeIndex; i < count; i++) { + if (this._owner._curtime - this._subBirthTime[i] >= this._owner.time + MathUtils3D.zeroTolerance) { + var nextIndex = i + 1; + if (nextIndex !== count) + this._owner._totalLength -= this._subDistance[nextIndex]; + if (this._isTempEndVertex && (nextIndex === count - 1)) { + var fixedPos = this._lastFixedVertexPosition; + fixedPos.x = this._vertices1[0]; + fixedPos.y = this._vertices1[1]; + fixedPos.z = this._vertices1[2]; + this._isTempEndVertex = false; + } + this._activeIndex++; + this._disappearBoundsMode = true; + } + else { + break; + } + } + } + _getType() { + return TrailGeometry._type; + } + _prepareRender(state) { + return this._endIndex - this._activeIndex > 1; + } + _render(state) { + this._bufferState.bind(); + var gl = Laya.LayaGL.instance; + var start = this._activeIndex * 2; + var count = this._endIndex * 2 - start; + gl.drawArrays(gl.TRIANGLE_STRIP, start, count); + Laya.Stat.renderBatches++; + Laya.Stat.trianglesFaces += count - 2; + } + destroy() { + super.destroy(); + var memorySize = this._vertexBuffer1._byteLength + this._vertexBuffer2._byteLength; + Laya.Resource._addMemory(-memorySize, -memorySize); + this._bufferState.destroy(); + this._vertexBuffer1.destroy(); + this._vertexBuffer2.destroy(); + this._bufferState = null; + this._vertices1 = null; + this._vertexBuffer1 = null; + this._vertices2 = null; + this._vertexBuffer2 = null; + this._subBirthTime = null; + this._subDistance = null; + this._lastFixedVertexPosition = null; + this._disappearBoundsMode = false; + } + clear() { + this._activeIndex = 0; + this._endIndex = 0; + this._disappearBoundsMode = false; + this._subBirthTime.fill(0); + this._subDistance.fill(0); + this._segementCount = 0; + this._isTempEndVertex = false; + this._needAddFirstVertex = false; + this._lastFixedVertexPosition.setValue(0, 0, 0); + } + } + TrailGeometry.ALIGNMENT_VIEW = 0; + TrailGeometry.ALIGNMENT_TRANSFORM_Z = 1; + TrailGeometry._tempVector30 = new Vector3(); + TrailGeometry._tempVector31 = new Vector3(); + TrailGeometry._tempVector32 = new Vector3(); + TrailGeometry._tempVector33 = new Vector3(); + TrailGeometry._tempVector34 = new Vector3(); + TrailGeometry._tempVector35 = new Vector3(); + TrailGeometry._tempVector36 = new Vector3(); + TrailGeometry._type = GeometryElement._typeCounter++; + + class TrailFilter { + constructor(owner) { + this._totalLength = 0; + this._lastPosition = new Vector3(); + this._curtime = 0; + this.alignment = TrailFilter.ALIGNMENT_VIEW; + this._owner = owner; + this._initDefaultData(); + this.addRenderElement(); + } + get time() { + return this._time; + } + set time(value) { + this._time = value; + this._owner._render._shaderValues.setNumber(TrailFilter.LIFETIME, value); + } + get minVertexDistance() { + return this._minVertexDistance; + } + set minVertexDistance(value) { + this._minVertexDistance = value; + } + get widthMultiplier() { + return this._widthMultiplier; + } + set widthMultiplier(value) { + this._widthMultiplier = value; + } + get widthCurve() { + return this._widthCurve; + } + set widthCurve(value) { + this._widthCurve = value; + var widthCurveFloatArray = new Float32Array(value.length * 4); + var i, j, index = 0; + for (i = 0, j = value.length; i < j; i++) { + widthCurveFloatArray[index++] = value[i].time; + widthCurveFloatArray[index++] = value[i].inTangent; + widthCurveFloatArray[index++] = value[i].outTangent; + widthCurveFloatArray[index++] = value[i].value; + } + this._owner._render._shaderValues.setBuffer(TrailFilter.WIDTHCURVE, widthCurveFloatArray); + this._owner._render._shaderValues.setInt(TrailFilter.WIDTHCURVEKEYLENGTH, value.length); + } + get colorGradient() { + return this._colorGradient; + } + set colorGradient(value) { + this._colorGradient = value; + } + get textureMode() { + return this._textureMode; + } + set textureMode(value) { + this._textureMode = value; + } + addRenderElement() { + var render = this._owner._render; + var elements = render._renderElements; + var material = render.sharedMaterials[0]; + (material) || (material = TrailMaterial.defaultMaterial); + var element = new RenderElement(); + element.setTransform(this._owner._transform); + element.render = render; + element.material = material; + this._trialGeometry = new TrailGeometry(this); + element.setGeometry(this._trialGeometry); + elements.push(element); + } + _update(state) { + var render = this._owner._render; + this._curtime += state.scene.timer._delta / 1000; + render._shaderValues.setNumber(TrailFilter.CURTIME, this._curtime); + var curPos = this._owner.transform.position; + var element = render._renderElements[0]._geometry; + element._updateDisappear(); + element._updateTrail(state.camera, this._lastPosition, curPos); + element._updateVertexBufferUV(); + curPos.cloneTo(this._lastPosition); + } + _initDefaultData() { + this.time = 5.0; + this.minVertexDistance = 0.1; + this.widthMultiplier = 1; + this.textureMode = TextureMode.Stretch; + var widthKeyFrames = []; + var widthKeyFrame1 = new FloatKeyframe(); + widthKeyFrame1.time = 0; + widthKeyFrame1.inTangent = 0; + widthKeyFrame1.outTangent = 0; + widthKeyFrame1.value = 1; + widthKeyFrames.push(widthKeyFrame1); + var widthKeyFrame2 = new FloatKeyframe(); + widthKeyFrame2.time = 1; + widthKeyFrame2.inTangent = 0; + widthKeyFrame2.outTangent = 0; + widthKeyFrame2.value = 1; + widthKeyFrames.push(widthKeyFrame2); + this.widthCurve = widthKeyFrames; + var gradient = new Gradient(2, 2); + gradient.mode = GradientMode.Blend; + gradient.addColorRGB(0, Color.WHITE); + gradient.addColorRGB(1, Color.WHITE); + gradient.addColorAlpha(0, 1); + gradient.addColorAlpha(1, 1); + this.colorGradient = gradient; + } + destroy() { + this._trialGeometry.destroy(); + this._trialGeometry = null; + this._widthCurve = null; + this._colorGradient = null; + } + clear() { + this._trialGeometry.clear(); + this._lastPosition.setValue(0, 0, 0); + this._curtime = 0; + this._totalLength = 0; + } + } + TrailFilter.CURTIME = Shader3D.propertyNameToID("u_CurTime"); + TrailFilter.LIFETIME = Shader3D.propertyNameToID("u_LifeTime"); + TrailFilter.WIDTHCURVE = Shader3D.propertyNameToID("u_WidthCurve"); + TrailFilter.WIDTHCURVEKEYLENGTH = Shader3D.propertyNameToID("u_WidthCurveKeyLength"); + TrailFilter.ALIGNMENT_VIEW = 0; + TrailFilter.ALIGNMENT_TRANSFORM_Z = 1; + + class TrailRenderer extends BaseRender { + constructor(owner) { + super(owner); + this._projectionViewWorldMatrix = new Matrix4x4(); + } + _calculateBoundingBox() { + } + _needRender(boundFrustum, context) { + this._owner.trailFilter._update(context); + if (boundFrustum) + return boundFrustum.intersects(this.bounds._getBoundBox()); + else + return true; + } + _updateForNative(context) { + this._owner.trailFilter._update(context); + } + _renderUpdate(state, transform) { + super._renderUpdate(state, transform); + } + _renderUpdateWithCamera(context, transform) { + var projectionView = context.projectionViewMatrix; + if (transform) { + Matrix4x4.multiply(projectionView, transform.worldMatrix, this._projectionViewWorldMatrix); + this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX, this._projectionViewWorldMatrix); + } + else { + this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX, projectionView); + } + } + } + + class TrailSprite3D extends RenderableSprite3D { + constructor(name = null) { + super(name); + this._render = new TrailRenderer(this); + this._geometryFilter = new TrailFilter(this); + } + static __init__() { + } + get trailFilter() { + return this._geometryFilter; + } + get trailRenderer() { + return this._render; + } + _parse(data, spriteMap) { + super._parse(data, spriteMap); + var render = this._render; + var filter = this._geometryFilter; + var i, j; + var materials = data.materials; + if (materials) { + var sharedMaterials = render.sharedMaterials; + var materialCount = materials.length; + sharedMaterials.length = materialCount; + for (i = 0; i < materialCount; i++) + sharedMaterials[i] = Laya.Loader.getRes(materials[i].path); + render.sharedMaterials = sharedMaterials; + } + filter.time = data.time; + filter.minVertexDistance = data.minVertexDistance; + filter.widthMultiplier = data.widthMultiplier; + filter.textureMode = data.textureMode; + (data.alignment != null) && (filter.alignment = data.alignment); + var widthCurve = []; + var widthCurveData = data.widthCurve; + for (i = 0, j = widthCurveData.length; i < j; i++) { + var trailkeyframe = new FloatKeyframe(); + trailkeyframe.time = widthCurveData[i].time; + trailkeyframe.inTangent = widthCurveData[i].inTangent; + trailkeyframe.outTangent = widthCurveData[i].outTangent; + trailkeyframe.value = widthCurveData[i].value; + widthCurve.push(trailkeyframe); + } + filter.widthCurve = widthCurve; + var colorGradientData = data.colorGradient; + var colorKeys = colorGradientData.colorKeys; + var alphaKeys = colorGradientData.alphaKeys; + var colorGradient = new Gradient(colorKeys.length, alphaKeys.length); + colorGradient.mode = colorGradientData.mode; + for (i = 0, j = colorKeys.length; i < j; i++) { + var colorKey = colorKeys[i]; + colorGradient.addColorRGB(colorKey.time, new Color(colorKey.value[0], colorKey.value[1], colorKey.value[2], 1.0)); + } + for (i = 0, j = alphaKeys.length; i < j; i++) { + var alphaKey = alphaKeys[i]; + colorGradient.addColorAlpha(alphaKey.time, alphaKey.value); + } + filter.colorGradient = colorGradient; + } + _onActive() { + super._onActive(); + this._transform.position.cloneTo(this._geometryFilter._lastPosition); + } + _cloneTo(destObject, srcSprite, dstSprite) { + super._cloneTo(destObject, srcSprite, dstSprite); + var i, j; + var destTrailSprite3D = destObject; + var destTrailFilter = destTrailSprite3D.trailFilter; + destTrailFilter.time = this.trailFilter.time; + destTrailFilter.minVertexDistance = this.trailFilter.minVertexDistance; + destTrailFilter.widthMultiplier = this.trailFilter.widthMultiplier; + destTrailFilter.textureMode = this.trailFilter.textureMode; + destTrailFilter.alignment = this.trailFilter.alignment; + var widthCurveData = this.trailFilter.widthCurve; + var widthCurve = []; + for (i = 0, j = widthCurveData.length; i < j; i++) { + var keyFrame = new FloatKeyframe(); + widthCurveData[i].cloneTo(keyFrame); + widthCurve.push(keyFrame); + } + destTrailFilter.widthCurve = widthCurve; + var destColorGradient = new Gradient(this.trailFilter.colorGradient.maxColorRGBKeysCount, this.trailFilter.colorGradient.maxColorAlphaKeysCount); + this.trailFilter.colorGradient.cloneTo(destColorGradient); + destTrailFilter.colorGradient = destColorGradient; + var destTrailRender = destTrailSprite3D.trailRenderer; + destTrailRender.sharedMaterial = this.trailRenderer.sharedMaterial; + } + destroy(destroyChild = true) { + if (this.destroyed) + return; + super.destroy(destroyChild); + this._geometryFilter.destroy(); + this._geometryFilter = null; + } + clear() { + this._geometryFilter.clear(); + } + _create() { + return new TrailSprite3D(); + } + } + + class VertexPositionTerrain { + constructor(position, normal, textureCoord0, textureCoord1) { + this._position = position; + this._normal = normal; + this._textureCoord0 = textureCoord0; + this._textureCoord1 = textureCoord1; + } + static __init__() { + VertexPositionTerrain._vertexDeclaration = new VertexDeclaration(40, [new VertexElement(0, VertexElementFormat.Vector3, VertexPositionTerrain.TERRAIN_POSITION0), + new VertexElement(12, VertexElementFormat.Vector3, VertexPositionTerrain.TERRAIN_NORMAL0), + new VertexElement(24, VertexElementFormat.Vector2, VertexPositionTerrain.TERRAIN_TEXTURECOORDINATE0), + new VertexElement(32, VertexElementFormat.Vector2, VertexPositionTerrain.TERRAIN_TEXTURECOORDINATE1)]); + } + static get vertexDeclaration() { + return VertexPositionTerrain._vertexDeclaration; + } + get position() { + return this._position; + } + get normal() { + return this._normal; + } + get textureCoord0() { + return this._textureCoord0; + } + get textureCoord1() { + return this._textureCoord1; + } + get vertexDeclaration() { + return VertexPositionTerrain._vertexDeclaration; + } + } + VertexPositionTerrain.TERRAIN_POSITION0 = 0; + VertexPositionTerrain.TERRAIN_NORMAL0 = 1; + VertexPositionTerrain.TERRAIN_TEXTURECOORDINATE0 = 2; + VertexPositionTerrain.TERRAIN_TEXTURECOORDINATE1 = 3; + + class SubMesh extends GeometryElement { + constructor(mesh) { + super(); + this._id = ++SubMesh._uniqueIDCounter; + this._mesh = mesh; + this._boneIndicesList = []; + this._subIndexBufferStart = []; + this._subIndexBufferCount = []; + } + get indexCount() { + return this._indexCount; + } + _setIndexRange(indexStart, indexCount, indexFormat = exports.IndexFormat.UInt16) { + this._indexStart = indexStart; + this._indexCount = indexCount; + if (indexFormat == exports.IndexFormat.UInt16) { + this._indices = new Uint16Array(this._indexBuffer.getData().buffer, indexStart * 2, indexCount); + } + else { + this._indices = new Uint32Array(this._indexBuffer.getData().buffer, indexStart * 4, indexCount); + } + } + _getType() { + return SubMesh._type; + } + _prepareRender(state) { + this._mesh._uploadVerticesData(); + return true; + } + _render(state) { + var mesh = this._mesh; + if (mesh.indexFormat === exports.IndexFormat.UInt32 && !Laya.LayaGL.layaGPUInstance.supportElementIndexUint32()) { + console.warn("SubMesh:this device do not support IndexFormat.UInt32."); + return; + } + var gl = Laya.LayaGL.instance; + var skinnedDatas = state.renderElement ? state.renderElement.render._skinnedData : null; + var glIndexFormat; + var byteCount; + switch (mesh.indexFormat) { + case exports.IndexFormat.UInt32: + glIndexFormat = gl.UNSIGNED_INT; + byteCount = 4; + break; + case exports.IndexFormat.UInt16: + glIndexFormat = gl.UNSIGNED_SHORT; + byteCount = 2; + break; + case exports.IndexFormat.UInt8: + glIndexFormat = gl.UNSIGNED_BYTE; + byteCount = 1; + break; + } + mesh._bufferState.bind(); + if (skinnedDatas) { + var subSkinnedDatas = skinnedDatas[this._indexInMesh]; + for (var i = 0, n = this._boneIndicesList.length; i < n; i++) { + state.shader.uploadCustomUniform(SkinnedMeshSprite3D.BONES, subSkinnedDatas[i]); + gl.drawElements(gl.TRIANGLES, this._subIndexBufferCount[i], glIndexFormat, this._subIndexBufferStart[i] * byteCount); + } + } + else { + gl.drawElements(gl.TRIANGLES, this._indexCount, glIndexFormat, this._indexStart * byteCount); + } + Laya.Stat.trianglesFaces += this._indexCount / 3; + Laya.Stat.renderBatches++; + } + getIndices() { + if (this._mesh._isReadable) + return this._indices.slice(); + else + throw "SubMesh:can't get indices on subMesh,mesh's isReadable must be true."; + } + setIndices(indices) { + this._indexBuffer.setData(indices, this._indexStart, 0, this._indexCount); + } + destroy() { + if (this._destroyed) + return; + super.destroy(); + this._indexBuffer.destroy(); + this._indexBuffer = null; + this._mesh = null; + this._boneIndicesList = null; + this._subIndexBufferStart = null; + this._subIndexBufferCount = null; + this._skinAnimationDatas = null; + } + } + SubMesh._uniqueIDCounter = 0; + SubMesh._type = GeometryElement._typeCounter++; + + class skinnedMatrixCache { + constructor(subMeshIndex, batchIndex, batchBoneIndex) { + this.subMeshIndex = subMeshIndex; + this.batchIndex = batchIndex; + this.batchBoneIndex = batchBoneIndex; + } + } + class Mesh extends Laya.Resource { + constructor(isReadable = true) { + super(); + this._tempVector30 = new Vector3(); + this._tempVector31 = new Vector3(); + this._tempVector32 = new Vector3(); + this._minVerticesUpdate = -1; + this._maxVerticesUpdate = -1; + this._needUpdateBounds = true; + this._bounds = new Bounds(new Vector3(), new Vector3()); + this._bufferState = new BufferState(); + this._instanceBufferState = new BufferState(); + this._instanceBufferStateType = 0; + this._vertexBuffer = null; + this._indexBuffer = null; + this._skinnedMatrixCaches = []; + this._vertexCount = 0; + this._indexFormat = exports.IndexFormat.UInt16; + this._isReadable = isReadable; + this._subMeshes = []; + } + static __init__() { + var physics3D = Physics3D._bullet; + if (physics3D) { + Mesh._nativeTempVector30 = physics3D.btVector3_create(0, 0, 0); + Mesh._nativeTempVector31 = physics3D.btVector3_create(0, 0, 0); + Mesh._nativeTempVector32 = physics3D.btVector3_create(0, 0, 0); + } + } + static load(url, complete) { + Laya.ILaya.loader.create(url, complete, null, Mesh.MESH); + } + get inverseAbsoluteBindPoses() { + return this._inverseBindPoses; + } + get vertexCount() { + return this._vertexCount; + } + get indexCount() { + return this._indexBuffer.indexCount; + } + get subMeshCount() { + return this._subMeshes.length; + } + get bounds() { + return this._bounds; + } + set bounds(value) { + if (this._bounds !== value) + value.cloneTo(this._bounds); + } + get indexFormat() { + return this._indexFormat; + } + _getPositionElement(vertexBuffer) { + var vertexElements = vertexBuffer.vertexDeclaration._vertexElements; + for (var i = 0, n = vertexElements.length; i < n; i++) { + var vertexElement = vertexElements[i]; + if (vertexElement._elementFormat === VertexElementFormat.Vector3 && vertexElement._elementUsage === VertexMesh.MESH_POSITION0) + return vertexElement; + } + return null; + } + _getVerticeElementData(data, elementUsage) { + data.length = this._vertexCount; + var verDec = this._vertexBuffer.vertexDeclaration; + var element = verDec.getVertexElementByUsage(elementUsage); + if (element) { + var uint8Vertices = this._vertexBuffer.getUint8Data(); + var floatVertices = this._vertexBuffer.getFloat32Data(); + var uint8VerStr = verDec.vertexStride; + var floatVerStr = uint8VerStr / 4; + var uint8EleOffset = element._offset; + var floatEleOffset = uint8EleOffset / 4; + switch (elementUsage) { + case VertexMesh.MESH_TEXTURECOORDINATE0: + case VertexMesh.MESH_TEXTURECOORDINATE1: + for (var i = 0; i < this._vertexCount; i++) { + var offset = floatVerStr * i + floatEleOffset; + data[i] = new Vector2(floatVertices[offset], floatVertices[offset + 1]); + } + break; + case VertexMesh.MESH_POSITION0: + case VertexMesh.MESH_NORMAL0: + for (var i = 0; i < this._vertexCount; i++) { + var offset = floatVerStr * i + floatEleOffset; + data[i] = new Vector3(floatVertices[offset], floatVertices[offset + 1], floatVertices[offset + 2]); + } + break; + case VertexMesh.MESH_TANGENT0: + case VertexMesh.MESH_BLENDWEIGHT0: + for (var i = 0; i < this._vertexCount; i++) { + var offset = floatVerStr * i + floatEleOffset; + data[i] = new Vector4(floatVertices[offset], floatVertices[offset + 1], floatVertices[offset + 2], floatVertices[offset + 3]); + } + break; + case VertexMesh.MESH_COLOR0: + for (var i = 0; i < this._vertexCount; i++) { + var offset = floatVerStr * i + floatEleOffset; + data[i] = new Color(floatVertices[offset], floatVertices[offset + 1], floatVertices[offset + 2], floatVertices[offset + 3]); + } + break; + case VertexMesh.MESH_BLENDINDICES0: + for (var i = 0; i < this._vertexCount; i++) { + var offset = uint8VerStr * i + uint8EleOffset; + data[i] = new Vector4(uint8Vertices[offset], uint8Vertices[offset + 1], uint8Vertices[offset + 2], uint8Vertices[offset + 3]); + } + break; + default: + throw "Mesh:Unknown elementUsage."; + } + } + } + _setVerticeElementData(data, elementUsage) { + var verDec = this._vertexBuffer.vertexDeclaration; + var element = verDec.getVertexElementByUsage(elementUsage); + if (element) { + var uint8Vertices = this._vertexBuffer.getUint8Data(); + var floatVertices = this._vertexBuffer.getFloat32Data(); + var uint8VerStr = verDec.vertexStride; + var float8VerStr = uint8VerStr / 4; + var uint8EleOffset = element._offset; + var floatEleOffset = uint8EleOffset / 4; + switch (elementUsage) { + case VertexMesh.MESH_TEXTURECOORDINATE0: + case VertexMesh.MESH_TEXTURECOORDINATE1: + for (var i = 0, n = data.length; i < n; i++) { + var offset = float8VerStr * i + floatEleOffset; + var vec2 = data[i]; + floatVertices[offset] = vec2.x; + floatVertices[offset + 1] = vec2.y; + } + break; + case VertexMesh.MESH_POSITION0: + case VertexMesh.MESH_NORMAL0: + for (var i = 0, n = data.length; i < n; i++) { + var offset = float8VerStr * i + floatEleOffset; + var vec3 = data[i]; + floatVertices[offset] = vec3.x; + floatVertices[offset + 1] = vec3.y; + floatVertices[offset + 2] = vec3.z; + } + break; + case VertexMesh.MESH_TANGENT0: + case VertexMesh.MESH_BLENDWEIGHT0: + for (var i = 0, n = data.length; i < n; i++) { + var offset = float8VerStr * i + floatEleOffset; + var vec4 = data[i]; + floatVertices[offset] = vec4.x; + floatVertices[offset + 1] = vec4.y; + floatVertices[offset + 2] = vec4.z; + floatVertices[offset + 3] = vec4.w; + } + break; + case VertexMesh.MESH_COLOR0: + for (var i = 0, n = data.length; i < n; i++) { + var offset = float8VerStr * i + floatEleOffset; + var cor = data[i]; + floatVertices[offset] = cor.r; + floatVertices[offset + 1] = cor.g; + floatVertices[offset + 2] = cor.b; + floatVertices[offset + 3] = cor.a; + } + break; + case VertexMesh.MESH_BLENDINDICES0: + for (var i = 0, n = data.length; i < n; i++) { + var offset = uint8VerStr * i + uint8EleOffset; + var vec4 = data[i]; + uint8Vertices[offset] = vec4.x; + uint8Vertices[offset + 1] = vec4.y; + uint8Vertices[offset + 2] = vec4.z; + uint8Vertices[offset + 3] = vec4.w; + } + break; + default: + throw "Mesh:Unknown elementUsage."; + } + this._minVerticesUpdate = 0; + this._maxVerticesUpdate = Number.MAX_SAFE_INTEGER; + } + else { + console.warn("Mesh: the mesh don't have this VertexElement."); + } + } + _disposeResource() { + for (var i = 0, n = this._subMeshes.length; i < n; i++) + this._subMeshes[i].destroy(); + this._btTriangleMesh && Physics3D._bullet.btStridingMeshInterface_destroy(this._btTriangleMesh); + this._vertexBuffer.destroy(); + this._indexBuffer.destroy(); + this._bufferState.destroy(); + this._instanceBufferState.destroy(); + this._setCPUMemory(0); + this._setGPUMemory(0); + this._bufferState = null; + this._instanceBufferState = null; + this._vertexBuffer = null; + this._indexBuffer = null; + this._subMeshes = null; + this._btTriangleMesh = null; + this._indexBuffer = null; + this._boneNames = null; + this._inverseBindPoses = null; + } + _setSubMeshes(subMeshes) { + this._subMeshes = subMeshes; + for (var i = 0, n = subMeshes.length; i < n; i++) + subMeshes[i]._indexInMesh = i; + } + _setBuffer(vertexBuffer, indexBuffer) { + var bufferState = this._bufferState; + bufferState.bind(); + bufferState.applyVertexBuffer(vertexBuffer); + bufferState.applyIndexBuffer(indexBuffer); + bufferState.unBind(); + } + _setInstanceBuffer(instanceBufferStateType) { + var instanceBufferState = this._instanceBufferState; + instanceBufferState.bind(); + instanceBufferState.applyVertexBuffer(this._vertexBuffer); + instanceBufferState.applyInstanceVertexBuffer(SubMeshInstanceBatch.instance.instanceWorldMatrixBuffer); + switch (instanceBufferStateType) { + case Mesh.MESH_INSTANCEBUFFER_TYPE_SIMPLEANIMATOR: + instanceBufferState.applyInstanceVertexBuffer(SubMeshInstanceBatch.instance.instanceSimpleAnimatorBuffer); + break; + } + instanceBufferState.applyIndexBuffer(this._indexBuffer); + instanceBufferState.unBind(); + } + _getPhysicMesh() { + if (!this._btTriangleMesh) { + var bt = Physics3D._bullet; + var triangleMesh = bt.btTriangleMesh_create(); + var nativePositio0 = Mesh._nativeTempVector30; + var nativePositio1 = Mesh._nativeTempVector31; + var nativePositio2 = Mesh._nativeTempVector32; + var position0 = this._tempVector30; + var position1 = this._tempVector31; + var position2 = this._tempVector32; + var vertexBuffer = this._vertexBuffer; + var positionElement = this._getPositionElement(vertexBuffer); + var verticesData = vertexBuffer.getFloat32Data(); + var floatCount = vertexBuffer.vertexDeclaration.vertexStride / 4; + var posOffset = positionElement._offset / 4; + var indices = this._indexBuffer.getData(); + for (var i = 0, n = indices.length; i < n; i += 3) { + var p0Index = indices[i] * floatCount + posOffset; + var p1Index = indices[i + 1] * floatCount + posOffset; + var p2Index = indices[i + 2] * floatCount + posOffset; + position0.setValue(verticesData[p0Index], verticesData[p0Index + 1], verticesData[p0Index + 2]); + position1.setValue(verticesData[p1Index], verticesData[p1Index + 1], verticesData[p1Index + 2]); + position2.setValue(verticesData[p2Index], verticesData[p2Index + 1], verticesData[p2Index + 2]); + Utils3D._convertToBulletVec3(position0, nativePositio0, true); + Utils3D._convertToBulletVec3(position1, nativePositio1, true); + Utils3D._convertToBulletVec3(position2, nativePositio2, true); + bt.btTriangleMesh_addTriangle(triangleMesh, nativePositio0, nativePositio1, nativePositio2, true); + } + this._btTriangleMesh = triangleMesh; + } + return this._btTriangleMesh; + } + _uploadVerticesData() { + var min = this._minVerticesUpdate; + var max = this._maxVerticesUpdate; + if (min !== -1 && max !== -1) { + var offset = min; + this._vertexBuffer.setData(this._vertexBuffer.getUint8Data().buffer, offset, offset, max - min); + this._minVerticesUpdate = -1; + this._maxVerticesUpdate = -1; + } + } + getSubMesh(index) { + return this._subMeshes[index]; + } + getPositions(positions) { + if (this._isReadable) + this._getVerticeElementData(positions, VertexMesh.MESH_POSITION0); + else + throw "Mesh:can't get positions on mesh,isReadable must be true."; + } + setPositions(positions) { + if (this._isReadable) { + this._setVerticeElementData(positions, VertexMesh.MESH_POSITION0); + this._needUpdateBounds = true; + } + else { + throw "Mesh:setPosition() need isReadable must be true or use setVertices()."; + } + } + getColors(colors) { + if (this._isReadable) + this._getVerticeElementData(colors, VertexMesh.MESH_COLOR0); + else + throw "Mesh:can't get colors on mesh,isReadable must be true."; + } + setColors(colors) { + if (this._isReadable) + this._setVerticeElementData(colors, VertexMesh.MESH_COLOR0); + else + throw "Mesh:setColors() need isReadable must be true or use setVertices()."; + } + getUVs(uvs, channel = 0) { + if (this._isReadable) { + switch (channel) { + case 0: + this._getVerticeElementData(uvs, VertexMesh.MESH_TEXTURECOORDINATE0); + break; + case 1: + this._getVerticeElementData(uvs, VertexMesh.MESH_TEXTURECOORDINATE1); + break; + default: + throw "Mesh:Invalid channel."; + } + } + else { + throw "Mesh:can't get uvs on mesh,isReadable must be true."; + } + } + setUVs(uvs, channel = 0) { + if (this._isReadable) { + switch (channel) { + case 0: + this._setVerticeElementData(uvs, VertexMesh.MESH_TEXTURECOORDINATE0); + break; + case 1: + this._setVerticeElementData(uvs, VertexMesh.MESH_TEXTURECOORDINATE1); + break; + default: + throw "Mesh:Invalid channel."; + } + } + else { + throw "Mesh:setUVs() need isReadable must be true or use setVertices()."; + } + } + getNormals(normals) { + if (this._isReadable) + this._getVerticeElementData(normals, VertexMesh.MESH_NORMAL0); + else + throw "Mesh:can't get colors on mesh,isReadable must be true."; + } + setNormals(normals) { + if (this._isReadable) + this._setVerticeElementData(normals, VertexMesh.MESH_NORMAL0); + else + throw "Mesh:setNormals() need must be true or use setVertices()."; + } + getTangents(tangents) { + if (this._isReadable) + this._getVerticeElementData(tangents, VertexMesh.MESH_TANGENT0); + else + throw "Mesh:can't get colors on mesh,isReadable must be true."; + } + setTangents(tangents) { + if (this._isReadable) + this._setVerticeElementData(tangents, VertexMesh.MESH_TANGENT0); + else + throw "Mesh:setTangents() need isReadable must be true or use setVertices()."; + } + getBoneWeights(boneWeights) { + if (this._isReadable) + this._getVerticeElementData(boneWeights, VertexMesh.MESH_BLENDWEIGHT0); + else + throw "Mesh:can't get boneWeights on mesh,isReadable must be true."; + } + setBoneWeights(boneWeights) { + if (this._isReadable) + this._setVerticeElementData(boneWeights, VertexMesh.MESH_BLENDWEIGHT0); + else + throw "Mesh:setBoneWeights() need isReadable must be true or use setVertices()."; + } + getBoneIndices(boneIndices) { + if (this._isReadable) + this._getVerticeElementData(boneIndices, VertexMesh.MESH_BLENDINDICES0); + else + throw "Mesh:can't get boneIndices on mesh,isReadable must be true."; + } + setBoneIndices(boneIndices) { + if (this._isReadable) + this._setVerticeElementData(boneIndices, VertexMesh.MESH_BLENDINDICES0); + else + throw "Mesh:setBoneIndices() need isReadable must be true or use setVertices()."; + } + markAsUnreadbale() { + this._uploadVerticesData(); + this._vertexBuffer.markAsUnreadbale(); + this._isReadable = false; + } + getVertexDeclaration() { + return this._vertexBuffer._vertexDeclaration; + } + getVertices() { + if (this._isReadable) + return this._vertexBuffer.getUint8Data().buffer.slice(0); + else + throw "Mesh:can't get vertices on mesh,isReadable must be true."; + } + setVertices(vertices) { + this._vertexBuffer.setData(vertices); + this._needUpdateBounds = true; + } + getIndices() { + if (this._isReadable) + return this._indexBuffer.getData().slice(); + else + throw "Mesh:can't get indices on subMesh,mesh's isReadable must be true."; + } + setIndices(indices) { + var format; + if (indices instanceof Uint32Array) + format = exports.IndexFormat.UInt32; + else if (indices instanceof Uint16Array) + format = exports.IndexFormat.UInt16; + else if (indices instanceof Uint8Array) + format = exports.IndexFormat.UInt8; + var indexBuffer = this._indexBuffer; + if (this._indexFormat !== format || indexBuffer.indexCount !== indices.length) { + indexBuffer.destroy(); + this._indexBuffer = indexBuffer = new IndexBuffer3D(format, indices.length, Laya.LayaGL.instance.STATIC_DRAW, this._isReadable); + } + indexBuffer.setData(indices); + this._indexFormat = format; + } + calculateBounds() { + if (this._isReadable) { + if (this._needUpdateBounds) { + var min = this._tempVector30; + var max = this._tempVector31; + min.x = min.y = min.z = Number.MAX_VALUE; + max.x = max.y = max.z = -Number.MAX_VALUE; + var vertexBuffer = this._vertexBuffer; + var positionElement = this._getPositionElement(vertexBuffer); + var verticesData = vertexBuffer.getFloat32Data(); + var floatCount = vertexBuffer.vertexDeclaration.vertexStride / 4; + var posOffset = positionElement._offset / 4; + for (var j = 0, m = verticesData.length; j < m; j += floatCount) { + var ofset = j + posOffset; + var pX = verticesData[ofset]; + var pY = verticesData[ofset + 1]; + var pZ = verticesData[ofset + 2]; + min.x = Math.min(min.x, pX); + min.y = Math.min(min.y, pY); + min.z = Math.min(min.z, pZ); + max.x = Math.max(max.x, pX); + max.y = Math.max(max.y, pY); + max.z = Math.max(max.z, pZ); + } + this._bounds.setMin(min); + this._bounds.setMax(max); + this._needUpdateBounds = false; + } + } + else { + throw "Mesh:can't calculate bounds on subMesh,mesh's isReadable must be true."; + } + } + cloneTo(destObject) { + var destMesh = destObject; + var vb = this._vertexBuffer; + var destVB = new VertexBuffer3D(vb._byteLength, vb.bufferUsage, vb.canRead); + destVB.vertexDeclaration = vb.vertexDeclaration; + destVB.setData(vb.getUint8Data().slice().buffer); + destMesh._vertexBuffer = destVB; + destMesh._vertexCount = this._vertexCount; + var ib = this._indexBuffer; + var destIB = new IndexBuffer3D(exports.IndexFormat.UInt16, ib.indexCount, ib.bufferUsage, ib.canRead); + destIB.setData(ib.getData().slice()); + destMesh._indexBuffer = destIB; + destMesh._setBuffer(destMesh._vertexBuffer, destIB); + destMesh._setInstanceBuffer(this._instanceBufferStateType); + destMesh._setCPUMemory(this.cpuMemory); + destMesh._setGPUMemory(this.gpuMemory); + var i; + var boneNames = this._boneNames; + if (boneNames) { + var destBoneNames = destMesh._boneNames = []; + for (i = 0; i < boneNames.length; i++) + destBoneNames[i] = boneNames[i]; + } + var inverseBindPoses = this._inverseBindPoses; + if (inverseBindPoses) { + var destInverseBindPoses = destMesh._inverseBindPoses = []; + for (i = 0; i < inverseBindPoses.length; i++) + destInverseBindPoses[i] = inverseBindPoses[i]; + } + var cacheLength = this._skinnedMatrixCaches.length; + destMesh._skinnedMatrixCaches.length = cacheLength; + for (i = 0; i < cacheLength; i++) { + var skinnedCache = this._skinnedMatrixCaches[i]; + destMesh._skinnedMatrixCaches[i] = new skinnedMatrixCache(skinnedCache.subMeshIndex, skinnedCache.batchIndex, skinnedCache.batchBoneIndex); + } + for (i = 0; i < this.subMeshCount; i++) { + var subMesh = this._subMeshes[i]; + var subIndexBufferStart = subMesh._subIndexBufferStart; + var subIndexBufferCount = subMesh._subIndexBufferCount; + var boneIndicesList = subMesh._boneIndicesList; + var destSubmesh = new SubMesh(destMesh); + destSubmesh._subIndexBufferStart.length = subIndexBufferStart.length; + destSubmesh._subIndexBufferCount.length = subIndexBufferCount.length; + destSubmesh._boneIndicesList.length = boneIndicesList.length; + for (var j = 0; j < subIndexBufferStart.length; j++) + destSubmesh._subIndexBufferStart[j] = subIndexBufferStart[j]; + for (j = 0; j < subIndexBufferCount.length; j++) + destSubmesh._subIndexBufferCount[j] = subIndexBufferCount[j]; + for (j = 0; j < boneIndicesList.length; j++) + destSubmesh._boneIndicesList[j] = new Uint16Array(boneIndicesList[j]); + destSubmesh._indexBuffer = destIB; + destSubmesh._indexStart = subMesh._indexStart; + destSubmesh._indexCount = subMesh._indexCount; + destSubmesh._indices = new Uint16Array(destIB.getData().buffer, subMesh._indexStart * 2, subMesh._indexCount); + var vertexBuffer = destMesh._vertexBuffer; + destSubmesh._vertexBuffer = vertexBuffer; + destMesh._subMeshes.push(destSubmesh); + } + destMesh._setSubMeshes(destMesh._subMeshes); + } + clone() { + var dest = new Mesh(); + this.cloneTo(dest); + return dest; + } + } + Mesh.MESH = "MESH"; + Mesh.MESH_INSTANCEBUFFER_TYPE_NORMAL = 0; + Mesh.MESH_INSTANCEBUFFER_TYPE_SIMPLEANIMATOR = 1; + + class PrimitiveMesh { + static __init__() { + } + static _createMesh(vertexDeclaration, vertices, indices) { + var gl = Laya.LayaGL.instance; + var mesh = new Mesh(); + var subMesh = new SubMesh(mesh); + var vertexBuffer = new VertexBuffer3D(vertices.length * 4, gl.STATIC_DRAW, true); + vertexBuffer.vertexDeclaration = vertexDeclaration; + vertexBuffer.setData(vertices.buffer); + mesh._vertexBuffer = vertexBuffer; + mesh._vertexCount = vertexBuffer._byteLength / vertexDeclaration.vertexStride; + var indexBuffer = new IndexBuffer3D(exports.IndexFormat.UInt16, indices.length, gl.STATIC_DRAW, true); + indexBuffer.setData(indices); + mesh._indexBuffer = indexBuffer; + mesh._setBuffer(vertexBuffer, indexBuffer); + mesh._setInstanceBuffer(mesh._instanceBufferStateType); + subMesh._vertexBuffer = vertexBuffer; + subMesh._indexBuffer = indexBuffer; + subMesh._setIndexRange(0, indexBuffer.indexCount); + var subIndexBufferStart = subMesh._subIndexBufferStart; + var subIndexBufferCount = subMesh._subIndexBufferCount; + var boneIndicesList = subMesh._boneIndicesList; + subIndexBufferStart.length = 1; + subIndexBufferCount.length = 1; + boneIndicesList.length = 1; + subIndexBufferStart[0] = 0; + subIndexBufferCount[0] = indexBuffer.indexCount; + var subMeshes = []; + subMeshes.push(subMesh); + mesh._setSubMeshes(subMeshes); + mesh.calculateBounds(); + var memorySize = vertexBuffer._byteLength + indexBuffer._byteLength; + mesh._setCPUMemory(memorySize); + mesh._setGPUMemory(memorySize); + return mesh; + } + static createBox(long = 1, height = 1, width = 1) { + var vertexDeclaration = VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV"); + var halfLong = long / 2; + var halfHeight = height / 2; + var halfWidth = width / 2; + var vertices = new Float32Array([ + -halfLong, halfHeight, -halfWidth, 0, 1, 0, 0, 0, halfLong, halfHeight, -halfWidth, 0, 1, 0, 1, 0, halfLong, halfHeight, halfWidth, 0, 1, 0, 1, 1, -halfLong, halfHeight, halfWidth, 0, 1, 0, 0, 1, + -halfLong, -halfHeight, -halfWidth, 0, -1, 0, 0, 1, halfLong, -halfHeight, -halfWidth, 0, -1, 0, 1, 1, halfLong, -halfHeight, halfWidth, 0, -1, 0, 1, 0, -halfLong, -halfHeight, halfWidth, 0, -1, 0, 0, 0, + -halfLong, halfHeight, -halfWidth, -1, 0, 0, 0, 0, -halfLong, halfHeight, halfWidth, -1, 0, 0, 1, 0, -halfLong, -halfHeight, halfWidth, -1, 0, 0, 1, 1, -halfLong, -halfHeight, -halfWidth, -1, 0, 0, 0, 1, + halfLong, halfHeight, -halfWidth, 1, 0, 0, 1, 0, halfLong, halfHeight, halfWidth, 1, 0, 0, 0, 0, halfLong, -halfHeight, halfWidth, 1, 0, 0, 0, 1, halfLong, -halfHeight, -halfWidth, 1, 0, 0, 1, 1, + -halfLong, halfHeight, halfWidth, 0, 0, 1, 0, 0, halfLong, halfHeight, halfWidth, 0, 0, 1, 1, 0, halfLong, -halfHeight, halfWidth, 0, 0, 1, 1, 1, -halfLong, -halfHeight, halfWidth, 0, 0, 1, 0, 1, + -halfLong, halfHeight, -halfWidth, 0, 0, -1, 1, 0, halfLong, halfHeight, -halfWidth, 0, 0, -1, 0, 0, halfLong, -halfHeight, -halfWidth, 0, 0, -1, 0, 1, -halfLong, -halfHeight, -halfWidth, 0, 0, -1, 1, 1 + ]); + var indices = new Uint16Array([ + 0, 1, 2, 2, 3, 0, + 4, 7, 6, 6, 5, 4, + 8, 9, 10, 10, 11, 8, + 12, 15, 14, 14, 13, 12, + 16, 17, 18, 18, 19, 16, + 20, 23, 22, 22, 21, 20 + ]); + return PrimitiveMesh._createMesh(vertexDeclaration, vertices, indices); + } + static createCapsule(radius = 0.5, height = 2, stacks = 16, slices = 32) { + var vertexCount = (stacks + 1) * (slices + 1) * 2 + (slices + 1) * 2; + var indexCount = (3 * stacks * (slices + 1)) * 2 * 2 + 2 * slices * 3; + var vertexDeclaration = VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV"); + var vertexFloatStride = vertexDeclaration.vertexStride / 4; + var vertices = new Float32Array(vertexCount * vertexFloatStride); + var indices = new Uint16Array(indexCount); + var stackAngle = (Math.PI / 2.0) / stacks; + var sliceAngle = (Math.PI * 2.0) / slices; + var hcHeight = height / 2 - radius; + var posX = 0; + var posY = 0; + var posZ = 0; + var vc = 0; + var ic = 0; + var verticeCount = 0; + var stack, slice; + for (stack = 0; stack <= stacks; stack++) { + for (slice = 0; slice <= slices; slice++) { + posX = radius * Math.cos(stack * stackAngle) * Math.cos(slice * sliceAngle + Math.PI); + posY = radius * Math.sin(stack * stackAngle); + posZ = radius * Math.cos(stack * stackAngle) * Math.sin(slice * sliceAngle + Math.PI); + vertices[vc++] = posX; + vertices[vc++] = posY + hcHeight; + vertices[vc++] = posZ; + vertices[vc++] = posX; + vertices[vc++] = posY; + vertices[vc++] = posZ; + vertices[vc++] = 1 - slice / slices; + vertices[vc++] = (1 - stack / stacks) * ((Math.PI * radius / 2) / (height + Math.PI * radius)); + if (stack < stacks) { + indices[ic++] = (stack * (slices + 1)) + slice + (slices + 1); + indices[ic++] = (stack * (slices + 1)) + slice; + indices[ic++] = (stack * (slices + 1)) + slice + 1; + indices[ic++] = (stack * (slices + 1)) + slice + (slices); + indices[ic++] = (stack * (slices + 1)) + slice; + indices[ic++] = (stack * (slices + 1)) + slice + (slices + 1); + } + } + } + verticeCount += (stacks + 1) * (slices + 1); + for (stack = 0; stack <= stacks; stack++) { + for (slice = 0; slice <= slices; slice++) { + posX = radius * Math.cos(stack * stackAngle) * Math.cos(slice * sliceAngle + Math.PI); + posY = radius * Math.sin(-stack * stackAngle); + posZ = radius * Math.cos(stack * stackAngle) * Math.sin(slice * sliceAngle + Math.PI); + vertices[vc++] = posX; + vertices[vc++] = posY - hcHeight; + vertices[vc++] = posZ; + vertices[vc++] = posX; + vertices[vc++] = posY; + vertices[vc++] = posZ; + vertices[vc++] = 1 - slice / slices; + vertices[vc++] = ((stack / stacks) * (Math.PI * radius / 2) + (height + Math.PI * radius / 2)) / (height + Math.PI * radius); + if (stack < stacks) { + indices[ic++] = verticeCount + (stack * (slices + 1)) + slice; + indices[ic++] = verticeCount + (stack * (slices + 1)) + slice + (slices + 1); + indices[ic++] = verticeCount + (stack * (slices + 1)) + slice + 1; + indices[ic++] = verticeCount + (stack * (slices + 1)) + slice; + indices[ic++] = verticeCount + (stack * (slices + 1)) + slice + (slices); + indices[ic++] = verticeCount + (stack * (slices + 1)) + slice + (slices + 1); + } + } + } + verticeCount += (stacks + 1) * (slices + 1); + for (slice = 0; slice <= slices; slice++) { + posX = radius * Math.cos(slice * sliceAngle + Math.PI); + posY = hcHeight; + posZ = radius * Math.sin(slice * sliceAngle + Math.PI); + vertices[vc++] = posX; + vertices[vc + (slices + 1) * 8 - 1] = posX; + vertices[vc++] = posY; + vertices[vc + (slices + 1) * 8 - 1] = -posY; + vertices[vc++] = posZ; + vertices[vc + (slices + 1) * 8 - 1] = posZ; + vertices[vc++] = posX; + vertices[vc + (slices + 1) * 8 - 1] = posX; + vertices[vc++] = 0; + vertices[vc + (slices + 1) * 8 - 1] = 0; + vertices[vc++] = posZ; + vertices[vc + (slices + 1) * 8 - 1] = posZ; + vertices[vc++] = 1 - slice * 1 / slices; + vertices[vc + (slices + 1) * 8 - 1] = 1 - slice * 1 / slices; + vertices[vc++] = (Math.PI * radius / 2) / (height + Math.PI * radius); + vertices[vc + (slices + 1) * 8 - 1] = (Math.PI * radius / 2 + height) / (height + Math.PI * radius); + } + for (slice = 0; slice < slices; slice++) { + indices[ic++] = slice + verticeCount + (slices + 1); + indices[ic++] = slice + verticeCount + 1; + indices[ic++] = slice + verticeCount; + indices[ic++] = slice + verticeCount + (slices + 1); + indices[ic++] = slice + verticeCount + (slices + 1) + 1; + indices[ic++] = slice + verticeCount + 1; + } + verticeCount += 2 * (slices + 1); + return PrimitiveMesh._createMesh(vertexDeclaration, vertices, indices); + } + static createCone(radius = 0.5, height = 1, slices = 32) { + var vertexCount = (slices + 1 + 1) + (slices + 1) * 2; + var indexCount = 6 * slices + 3 * slices; + var vertexDeclaration = VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV"); + var vertexFloatStride = vertexDeclaration.vertexStride / 4; + var vertices = new Float32Array(vertexCount * vertexFloatStride); + var indices = new Uint16Array(indexCount); + var sliceAngle = (Math.PI * 2.0) / slices; + var halfHeight = height / 2; + var curAngle = 0; + var verticeCount = 0; + var posX = 0; + var posY = 0; + var posZ = 0; + var normal = new Vector3(); + var downV3 = new Vector3(0, -1, 0); + var upPoint = new Vector3(0, halfHeight, 0); + var downPoint = new Vector3(); + var v3 = new Vector3(); + var q4 = new Quaternion(); + var rotateAxis = new Vector3(); + var rotateRadius; + var vc = 0; + var ic = 0; + for (var rv = 0; rv <= slices; rv++) { + curAngle = rv * sliceAngle; + posX = Math.cos(curAngle + Math.PI) * radius; + posY = halfHeight; + posZ = Math.sin(curAngle + Math.PI) * radius; + vertices[vc++] = 0; + vertices[vc + (slices + 1) * 8 - 1] = posX; + vertices[vc++] = posY; + vertices[vc + (slices + 1) * 8 - 1] = -posY; + vertices[vc++] = 0; + vertices[vc + (slices + 1) * 8 - 1] = posZ; + normal.x = posX; + normal.y = 0; + normal.z = posZ; + downPoint.x = posX; + downPoint.y = -posY; + downPoint.z = posZ; + Vector3.subtract(downPoint, upPoint, v3); + Vector3.normalize(v3, v3); + rotateRadius = Math.acos(Vector3.dot(downV3, v3)); + Vector3.cross(downV3, v3, rotateAxis); + Vector3.normalize(rotateAxis, rotateAxis); + Quaternion.createFromAxisAngle(rotateAxis, rotateRadius, q4); + Vector3.normalize(normal, normal); + Vector3.transformQuat(normal, q4, normal); + Vector3.normalize(normal, normal); + vertices[vc++] = normal.x; + vertices[vc + (slices + 1) * 8 - 1] = normal.x; + vertices[vc++] = normal.y; + vertices[vc + (slices + 1) * 8 - 1] = normal.y; + vertices[vc++] = normal.z; + vertices[vc + (slices + 1) * 8 - 1] = normal.z; + vertices[vc++] = 1 - rv * 1 / slices; + vertices[vc + (slices + 1) * 8 - 1] = 1 - rv * 1 / slices; + vertices[vc++] = 0; + vertices[vc + (slices + 1) * 8 - 1] = 1; + } + vc += (slices + 1) * 8; + for (var ri = 0; ri < slices; ri++) { + indices[ic++] = ri + verticeCount + (slices + 1); + indices[ic++] = ri + verticeCount + 1; + indices[ic++] = ri + verticeCount; + indices[ic++] = ri + verticeCount + (slices + 1); + indices[ic++] = ri + verticeCount + (slices + 1) + 1; + indices[ic++] = ri + verticeCount + 1; + } + verticeCount += 2 * (slices + 1); + for (var bv = 0; bv <= slices; bv++) { + if (bv === 0) { + vertices[vc++] = 0; + vertices[vc++] = -halfHeight; + vertices[vc++] = 0; + vertices[vc++] = 0; + vertices[vc++] = -1; + vertices[vc++] = 0; + vertices[vc++] = 0.5; + vertices[vc++] = 0.5; + } + curAngle = bv * sliceAngle; + posX = Math.cos(curAngle + Math.PI) * radius; + posY = -halfHeight; + posZ = Math.sin(curAngle + Math.PI) * radius; + vertices[vc++] = posX; + vertices[vc++] = posY; + vertices[vc++] = posZ; + vertices[vc++] = 0; + vertices[vc++] = -1; + vertices[vc++] = 0; + vertices[vc++] = 0.5 + Math.cos(curAngle) * 0.5; + vertices[vc++] = 0.5 + Math.sin(curAngle) * 0.5; + } + for (var bi = 0; bi < slices; bi++) { + indices[ic++] = 0 + verticeCount; + indices[ic++] = bi + 2 + verticeCount; + indices[ic++] = bi + 1 + verticeCount; + } + verticeCount += slices + 1 + 1; + return PrimitiveMesh._createMesh(vertexDeclaration, vertices, indices); + } + static createCylinder(radius = 0.5, height = 2, slices = 32) { + var vertexCount = (slices + 1 + 1) + (slices + 1) * 2 + (slices + 1 + 1); + var indexCount = 3 * slices + 6 * slices + 3 * slices; + var vertexDeclaration = VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV"); + var vertexFloatStride = vertexDeclaration.vertexStride / 4; + var vertices = new Float32Array(vertexCount * vertexFloatStride); + var indices = new Uint16Array(indexCount); + var sliceAngle = (Math.PI * 2.0) / slices; + var halfHeight = height / 2; + var curAngle = 0; + var verticeCount = 0; + var posX = 0; + var posY = 0; + var posZ = 0; + var vc = 0; + var ic = 0; + for (var tv = 0; tv <= slices; tv++) { + if (tv === 0) { + vertices[vc++] = 0; + vertices[vc++] = halfHeight; + vertices[vc++] = 0; + vertices[vc++] = 0; + vertices[vc++] = 1; + vertices[vc++] = 0; + vertices[vc++] = 0.5; + vertices[vc++] = 0.5; + } + curAngle = tv * sliceAngle; + posX = Math.cos(curAngle) * radius; + posY = halfHeight; + posZ = Math.sin(curAngle) * radius; + vertices[vc++] = posX; + vertices[vc++] = posY; + vertices[vc++] = posZ; + vertices[vc++] = 0; + vertices[vc++] = 1; + vertices[vc++] = 0; + vertices[vc++] = 0.5 + Math.cos(curAngle) * 0.5; + vertices[vc++] = 0.5 + Math.sin(curAngle) * 0.5; + } + for (var ti = 0; ti < slices; ti++) { + indices[ic++] = 0; + indices[ic++] = ti + 1; + indices[ic++] = ti + 2; + } + verticeCount += slices + 1 + 1; + for (var rv = 0; rv <= slices; rv++) { + curAngle = rv * sliceAngle; + posX = Math.cos(curAngle + Math.PI) * radius; + posY = halfHeight; + posZ = Math.sin(curAngle + Math.PI) * radius; + vertices[vc++] = posX; + vertices[vc + (slices + 1) * 8 - 1] = posX; + vertices[vc++] = posY; + vertices[vc + (slices + 1) * 8 - 1] = -posY; + vertices[vc++] = posZ; + vertices[vc + (slices + 1) * 8 - 1] = posZ; + vertices[vc++] = posX; + vertices[vc + (slices + 1) * 8 - 1] = posX; + vertices[vc++] = 0; + vertices[vc + (slices + 1) * 8 - 1] = 0; + vertices[vc++] = posZ; + vertices[vc + (slices + 1) * 8 - 1] = posZ; + vertices[vc++] = 1 - rv * 1 / slices; + vertices[vc + (slices + 1) * 8 - 1] = 1 - rv * 1 / slices; + vertices[vc++] = 0; + vertices[vc + (slices + 1) * 8 - 1] = 1; + } + vc += (slices + 1) * 8; + for (var ri = 0; ri < slices; ri++) { + indices[ic++] = ri + verticeCount + (slices + 1); + indices[ic++] = ri + verticeCount + 1; + indices[ic++] = ri + verticeCount; + indices[ic++] = ri + verticeCount + (slices + 1); + indices[ic++] = ri + verticeCount + (slices + 1) + 1; + indices[ic++] = ri + verticeCount + 1; + } + verticeCount += 2 * (slices + 1); + for (var bv = 0; bv <= slices; bv++) { + if (bv === 0) { + vertices[vc++] = 0; + vertices[vc++] = -halfHeight; + vertices[vc++] = 0; + vertices[vc++] = 0; + vertices[vc++] = -1; + vertices[vc++] = 0; + vertices[vc++] = 0.5; + vertices[vc++] = 0.5; + } + curAngle = bv * sliceAngle; + posX = Math.cos(curAngle + Math.PI) * radius; + posY = -halfHeight; + posZ = Math.sin(curAngle + Math.PI) * radius; + vertices[vc++] = posX; + vertices[vc++] = posY; + vertices[vc++] = posZ; + vertices[vc++] = 0; + vertices[vc++] = -1; + vertices[vc++] = 0; + vertices[vc++] = 0.5 + Math.cos(curAngle) * 0.5; + vertices[vc++] = 0.5 + Math.sin(curAngle) * 0.5; + } + for (var bi = 0; bi < slices; bi++) { + indices[ic++] = 0 + verticeCount; + indices[ic++] = bi + 2 + verticeCount; + indices[ic++] = bi + 1 + verticeCount; + } + verticeCount += slices + 1 + 1; + return PrimitiveMesh._createMesh(vertexDeclaration, vertices, indices); + } + static createPlane(long = 10, width = 10, stacks = 10, slices = 10) { + var vertexCount = (stacks + 1) * (slices + 1); + var indexCount = stacks * slices * 2 * 3; + var indices = new Uint16Array(indexCount); + var vertexDeclaration = VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV"); + var vertexFloatStride = vertexDeclaration.vertexStride / 4; + var vertices = new Float32Array(vertexCount * vertexFloatStride); + var halfLong = long / 2; + var halfWidth = width / 2; + var stacksLong = long / stacks; + var slicesWidth = width / slices; + var verticeCount = 0; + for (var i = 0; i <= slices; i++) { + for (var j = 0; j <= stacks; j++) { + vertices[verticeCount++] = j * stacksLong - halfLong; + vertices[verticeCount++] = 0; + vertices[verticeCount++] = i * slicesWidth - halfWidth; + vertices[verticeCount++] = 0; + vertices[verticeCount++] = 1; + vertices[verticeCount++] = 0; + vertices[verticeCount++] = j * 1 / stacks; + vertices[verticeCount++] = i * 1 / slices; + } + } + var indiceIndex = 0; + for (i = 0; i < slices; i++) { + for (j = 0; j < stacks; j++) { + indices[indiceIndex++] = (i + 1) * (stacks + 1) + j; + indices[indiceIndex++] = i * (stacks + 1) + j; + indices[indiceIndex++] = (i + 1) * (stacks + 1) + j + 1; + indices[indiceIndex++] = i * (stacks + 1) + j; + indices[indiceIndex++] = i * (stacks + 1) + j + 1; + indices[indiceIndex++] = (i + 1) * (stacks + 1) + j + 1; + } + } + return PrimitiveMesh._createMesh(vertexDeclaration, vertices, indices); + } + static createQuad(long = 1, width = 1) { + var vertexDeclaration = VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV"); + var halfLong = long / 2; + var halfWidth = width / 2; + var vertices = new Float32Array([-halfLong, halfWidth, 0, 0, 0, 1, 0, 0, halfLong, halfWidth, 0, 0, 0, 1, 1, 0, -halfLong, -halfWidth, 0, 0, 0, 1, 0, 1, halfLong, -halfWidth, 0, 0, 0, 1, 1, 1]); + var indices = new Uint16Array([0, 1, 2, 3, 2, 1]); + return PrimitiveMesh._createMesh(vertexDeclaration, vertices, indices); + } + static createSphere(radius = 0.5, stacks = 32, slices = 32) { + var vertexCount = (stacks + 1) * (slices + 1); + var indexCount = (3 * stacks * (slices + 1)) * 2; + var indices = new Uint16Array(indexCount); + var vertexDeclaration = VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV"); + var vertexFloatStride = vertexDeclaration.vertexStride / 4; + var vertices = new Float32Array(vertexCount * vertexFloatStride); + var stackAngle = Math.PI / stacks; + var sliceAngle = (Math.PI * 2.0) / slices; + var vertexIndex = 0; + vertexCount = 0; + indexCount = 0; + for (var stack = 0; stack < (stacks + 1); stack++) { + var r = Math.sin(stack * stackAngle); + var y = Math.cos(stack * stackAngle); + for (var slice = 0; slice < (slices + 1); slice++) { + var x = r * Math.sin(slice * sliceAngle + Math.PI * 1 / 2); + var z = r * Math.cos(slice * sliceAngle + Math.PI * 1 / 2); + vertices[vertexCount + 0] = x * radius; + vertices[vertexCount + 1] = y * radius; + vertices[vertexCount + 2] = z * radius; + vertices[vertexCount + 3] = x; + vertices[vertexCount + 4] = y; + vertices[vertexCount + 5] = z; + vertices[vertexCount + 6] = slice / slices; + vertices[vertexCount + 7] = stack / stacks; + vertexCount += vertexFloatStride; + if (stack != (stacks - 1)) { + indices[indexCount++] = vertexIndex + (slices + 1); + indices[indexCount++] = vertexIndex; + indices[indexCount++] = vertexIndex + 1; + indices[indexCount++] = vertexIndex + (slices); + indices[indexCount++] = vertexIndex; + indices[indexCount++] = vertexIndex + (slices + 1); + vertexIndex++; + } + } + } + return PrimitiveMesh._createMesh(vertexDeclaration, vertices, indices); + } + } + + var BlitScreenPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\nuniform sampler2D u_MainTex;\r\nvarying vec2 v_Texcoord0;\r\n\r\nvoid main() {\r\n\tgl_FragColor = texture2D(u_MainTex, v_Texcoord0);\r\n}\r\n\r\n"; + + var BlitScreenVS = "#include \"Lighting.glsl\";\r\n#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\nattribute vec4 a_PositionTexcoord;\r\nuniform vec4 u_OffsetScale;\r\nvarying vec2 v_Texcoord0;\r\n\r\nvoid main() {\t\r\n\tgl_Position = vec4(u_OffsetScale.x*2.0-1.0+(a_PositionTexcoord.x+1.0)*u_OffsetScale.z,(1.0-((u_OffsetScale.y*2.0-1.0+(-a_PositionTexcoord.y+1.0)*u_OffsetScale.w)+1.0)/2.0)*2.0-1.0, 0.0, 1.0);\t\r\n\tv_Texcoord0 = a_PositionTexcoord.zw;\r\n\tgl_Position = remapGLPositionZ(gl_Position);\r\n}"; + + var EffectPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#ifdef COLOR\r\n\tvarying vec4 v_Color;\r\n#endif\r\nvarying vec2 v_Texcoord0;\r\n\r\n#ifdef MAINTEXTURE\r\n\tuniform sampler2D u_AlbedoTexture;\r\n#endif\r\n\r\nuniform vec4 u_AlbedoColor;\r\n\r\n#ifdef FOG\r\n\tuniform float u_FogStart;\r\n\tuniform float u_FogRange;\r\n\t#ifdef ADDTIVEFOG\r\n\t#else\r\n\t\tuniform vec3 u_FogColor;\r\n\t#endif\r\n#endif\r\n\r\nvoid main()\r\n{\r\n\tvec4 color = 2.0 * u_AlbedoColor;\r\n\t#ifdef COLOR\r\n\t\tcolor *= v_Color;\r\n\t#endif\r\n\t#ifdef MAINTEXTURE\r\n\t\tcolor *= texture2D(u_AlbedoTexture, v_Texcoord0);\r\n\t#endif\r\n\t\r\n\tgl_FragColor = color;\r\n\t\r\n\t#ifdef FOG\r\n\t\tfloat lerpFact = clamp((1.0 / gl_FragCoord.w - u_FogStart) / u_FogRange, 0.0, 1.0);\r\n\t\t#ifdef ADDTIVEFOG\r\n\t\t\tgl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.0), lerpFact);\r\n\t\t#else\r\n\t\t\tgl_FragColor.rgb = mix(gl_FragColor.rgb, u_FogColor, lerpFact);\r\n\t\t#endif\r\n\t#endif\r\n}\r\n\r\n"; + + var EffectVS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n#include \"Lighting.glsl\";\r\n#include \"LayaUtile.glsl\";\r\n\r\nattribute vec4 a_Position;\r\nattribute vec4 a_Color;\r\nattribute vec2 a_Texcoord0;\r\n\r\n#ifdef GPU_INSTANCE\r\n\tuniform mat4 u_ViewProjection;\r\n\tattribute mat4 a_WorldMat;\r\n#else\r\n\tuniform mat4 u_MvpMatrix;\r\n#endif\r\n\r\n#ifdef COLOR\r\n\tvarying vec4 v_Color;\r\n#endif\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform vec4 u_TilingOffset;\r\n\r\n#ifdef BONE\r\n\tconst int c_MaxBoneCount = 24;\r\n\tattribute vec4 a_BoneIndices;\r\n\tattribute vec4 a_BoneWeights;\r\n\tuniform mat4 u_Bones[c_MaxBoneCount];\r\n#endif\r\n\r\n\r\nvoid main()\r\n{\r\n\tvec4 position;\r\n\t#ifdef BONE\r\n\t\tmat4 skinTransform;\r\n\t \t#ifdef SIMPLEBONE\r\n\t\t\tfloat currentPixelPos;\r\n\t\t\t#ifdef GPU_INSTANCE\r\n\t\t\t\tcurrentPixelPos = a_SimpleTextureParams.x+a_SimpleTextureParams.y;\r\n\t\t\t#else\r\n\t\t\t\tcurrentPixelPos = u_SimpleAnimatorParams.x+u_SimpleAnimatorParams.y;\r\n\t\t\t#endif\r\n\t\t\tfloat offset = 1.0/u_SimpleAnimatorTextureSize;\r\n\t\t\tskinTransform = loadMatFromTexture(currentPixelPos,int(a_BoneIndices.x),offset) * a_BoneWeights.x;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.y),offset) * a_BoneWeights.y;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.z),offset) * a_BoneWeights.z;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.w),offset) * a_BoneWeights.w;\r\n\t\t#else\r\n\t\t\tskinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;\r\n\t\t#endif\r\n\t\tposition=skinTransform*a_Position;\r\n\t #else\r\n\t\tposition=a_Position;\r\n\t#endif\r\n\t#ifdef GPU_INSTANCE\r\n\t\tgl_Position = u_ViewProjection * a_WorldMat * position;\r\n\t#else\r\n\t\tgl_Position = u_MvpMatrix * position;\r\n\t#endif\r\n\t\r\n\tv_Texcoord0=TransformUV(a_Texcoord0,u_TilingOffset);\r\n\t\t\r\n\t#ifdef COLOR\r\n\t\tv_Color = a_Color;\r\n\t#endif\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}"; + + var extendTerrainPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Lighting.glsl\";\r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||defined(FOG)\r\n\tuniform vec3 u_CameraPos;\r\n\tvarying vec3 v_Normal;\r\n\tvarying vec3 v_PositionWorld;\r\n#endif\r\n\r\n#ifdef FOG\r\n\tuniform float u_FogStart;\r\n\tuniform float u_FogRange;\r\n\tuniform vec3 u_FogColor;\r\n#endif\r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t#ifdef LEGACYSINGLELIGHTING\r\n\t\t#ifdef DIRECTIONLIGHT\r\n\t\t\tuniform DirectionLight u_DirectionLight;\r\n\t\t#endif\r\n\t\t#ifdef POINTLIGHT\r\n\t\t\tuniform PointLight u_PointLight;\r\n\t\t#endif\r\n\t\t#ifdef SPOTLIGHT\r\n\t\t\tuniform SpotLight u_SpotLight;\r\n\t\t#endif\r\n\t#else\r\n\t\tuniform mat4 u_View;\r\n\t\tuniform vec4 u_ProjectionParams;\r\n\t\tuniform vec4 u_Viewport;\r\n\t\tuniform int u_DirationLightCount;\r\n\t\tuniform sampler2D u_LightBuffer;\r\n\t\tuniform sampler2D u_LightClusterBuffer;\r\n\t#endif\r\n#endif\r\n\r\n#include \"Shadow.glsl\"\r\n#if defined(CALCULATE_SHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\tvarying vec4 v_ShadowCoord;\r\n#endif\r\nvarying float v_posViewZ;\r\n\r\nuniform vec3 u_AmbientColor;\r\n\r\nuniform sampler2D u_SplatAlphaTexture;\r\n\r\nuniform sampler2D u_DiffuseTexture1;\r\nuniform sampler2D u_DiffuseTexture2;\r\nuniform sampler2D u_DiffuseTexture3;\r\nuniform sampler2D u_DiffuseTexture4;\r\nuniform sampler2D u_DiffuseTexture5;\r\n\r\nuniform vec4 u_DiffuseScaleOffset1;\r\nuniform vec4 u_DiffuseScaleOffset2;\r\nuniform vec4 u_DiffuseScaleOffset3;\r\nuniform vec4 u_DiffuseScaleOffset4;\r\nuniform vec4 u_DiffuseScaleOffset5;\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\n#ifdef LIGHTMAP\r\n\tuniform sampler2D u_LightMap;\r\n\tvarying vec2 v_LightMapUV;\r\n#endif\r\n\r\nvoid main()\r\n{\r\n\tvec4 splatAlpha = vec4(1.0);\r\n\t#ifdef ExtendTerrain_DETAIL_NUM1\r\n\t\tsplatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);\r\n\t\tvec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);\r\n\t\tgl_FragColor.xyz = color1.xyz * splatAlpha.r;\r\n\t#endif\r\n\t#ifdef ExtendTerrain_DETAIL_NUM2\r\n\t\tsplatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);\r\n\t\tvec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);\r\n\t\tvec4 color2 = texture2D(u_DiffuseTexture2, v_Texcoord0 * u_DiffuseScaleOffset2.xy);\r\n\t\tgl_FragColor.xyz = color1.xyz * splatAlpha.r + color2.xyz * (1.0 - splatAlpha.r);\r\n\t#endif\r\n\t#ifdef ExtendTerrain_DETAIL_NUM3\r\n\t\tsplatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);\r\n\t\tvec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);\r\n\t\tvec4 color2 = texture2D(u_DiffuseTexture2, v_Texcoord0 * u_DiffuseScaleOffset2.xy);\r\n\t\tvec4 color3 = texture2D(u_DiffuseTexture3, v_Texcoord0 * u_DiffuseScaleOffset3.xy);\r\n\t\tgl_FragColor.xyz = color1.xyz * splatAlpha.r + color2.xyz * splatAlpha.g + color3.xyz * (1.0 - splatAlpha.r - splatAlpha.g);\r\n\t#endif\r\n\t#ifdef ExtendTerrain_DETAIL_NUM4\r\n\t\tsplatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);\r\n\t\tvec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);\r\n\t\tvec4 color2 = texture2D(u_DiffuseTexture2, v_Texcoord0 * u_DiffuseScaleOffset2.xy);\r\n\t\tvec4 color3 = texture2D(u_DiffuseTexture3, v_Texcoord0 * u_DiffuseScaleOffset3.xy);\r\n\t\tvec4 color4 = texture2D(u_DiffuseTexture4, v_Texcoord0 * u_DiffuseScaleOffset4.xy);\r\n\t\tgl_FragColor.xyz = color1.xyz * splatAlpha.r + color2.xyz * splatAlpha.g + color3.xyz * splatAlpha.b + color4.xyz * (1.0 - splatAlpha.r - splatAlpha.g - splatAlpha.b);\r\n\t#endif\r\n\t#ifdef ExtendTerrain_DETAIL_NUM5\r\n\t\tsplatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);\r\n\t\tvec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);\r\n\t\tvec4 color2 = texture2D(u_DiffuseTexture2, v_Texcoord0 * u_DiffuseScaleOffset2.xy);\r\n\t\tvec4 color3 = texture2D(u_DiffuseTexture3, v_Texcoord0 * u_DiffuseScaleOffset3.xy);\r\n\t\tvec4 color4 = texture2D(u_DiffuseTexture4, v_Texcoord0 * u_DiffuseScaleOffset4.xy);\r\n\t\tvec4 color5 = texture2D(u_DiffuseTexture5, v_Texcoord0 * u_DiffuseScaleOffset5.xy);\r\n\t\tgl_FragColor.xyz = color1.xyz * splatAlpha.r + color2.xyz * splatAlpha.g + color3.xyz * splatAlpha.b + color4.xyz * splatAlpha.a + color5.xyz * (1.0 - splatAlpha.r - splatAlpha.g - splatAlpha.b - splatAlpha.a);\r\n\t#endif\r\n\t\tgl_FragColor.w = splatAlpha.a;\r\n\t\t\r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\tvec3 normal = v_Normal;\r\n\t\tvec3 dif, spe;\r\n\t#endif\r\n\r\n\tvec3 diffuse = vec3(0.0);\r\n\tvec3 specular= vec3(0.0);\r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||defined(FOG)\r\n\t\tvec3 toEye;\r\n\t\t#ifdef FOG\r\n\t\t\ttoEye=u_CameraPos-v_PositionWorld;\r\n\t\t\tfloat toEyeLength=length(toEye);\r\n\t\t\ttoEye/=toEyeLength;\r\n\t\t#else\r\n\t\t\ttoEye=normalize(u_CameraPos-v_PositionWorld);\r\n\t\t#endif\r\n\t#endif\r\n\r\n\t#ifdef LEGACYSINGLELIGHTING\r\n\t\t#ifdef DIRECTIONLIGHT\r\n\t\t\tLayaAirBlinnPhongDiectionLight(vec3(0.0),1.0,normal,vec3(1.0),toEye,u_DirectionLight,dif,spe);\r\n\t\t\tdiffuse+=dif;\r\n\t\t\tspecular+=spe;\r\n\t\t#endif\r\n\t\r\n\t\t#ifdef POINTLIGHT\r\n\t\t\tLayaAirBlinnPhongPointLight(v_PositionWorld,vec3(0.0),1.0,normal,vec3(1.0),toEye,u_PointLight,dif,spe);\r\n\t\t\tdiffuse+=dif;\r\n\t\t\tspecular+=spe;\r\n\t\t#endif\r\n\r\n\t\t#ifdef SPOTLIGHT\r\n\t\t\tLayaAirBlinnPhongSpotLight(v_PositionWorld,vec3(0.0),1.0,normal,vec3(1.0),toEye,u_SpotLight,dif,spe);\r\n\t\t\tdiffuse+=dif;\r\n\t\t\tspecular+=spe;\r\n\t\t#endif\r\n\t#else\r\n\t\t#ifdef DIRECTIONLIGHT\r\n\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t{\r\n\t\t\t\tif(i >= u_DirationLightCount)\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tDirectionLight directionLight = getDirectionLight(u_LightBuffer,i);\r\n\t\t\t\tLayaAirBlinnPhongDiectionLight(vec3(0.0),1.0,normal,vec3(1.0),toEye,directionLight,dif,spe);\r\n\t\t\t\tdiffuse+=dif;\r\n\t\t\t\tspecular+=spe;\r\n\t\t\t}\r\n\t\t#endif\r\n\t\t#if defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\t\tivec4 clusterInfo =getClusterInfo(u_LightClusterBuffer,u_View,u_Viewport, v_PositionWorld,gl_FragCoord,u_ProjectionParams);\r\n\t\t\t#ifdef POINTLIGHT\r\n\t\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t\t{\r\n\t\t\t\t\tif(i >= clusterInfo.x)//PointLightCount\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tPointLight pointLight = getPointLight(u_LightBuffer,u_LightClusterBuffer,clusterInfo,i);\r\n\t\t\t\t\tLayaAirBlinnPhongPointLight(v_PositionWorld,vec3(0.0),1.0,normal,vec3(1.0),toEye,pointLight,dif,spe);\r\n\t\t\t\t\tdiffuse+=dif;\r\n\t\t\t\t\tspecular+=spe;\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t\t#ifdef SPOTLIGHT\r\n\t\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t\t{\r\n\t\t\t\t\tif(i >= clusterInfo.y)//SpotLightCount\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tSpotLight spotLight = getSpotLight(u_LightBuffer,u_LightClusterBuffer,clusterInfo,i);\r\n\t\t\t\t\tLayaAirBlinnPhongSpotLight(v_PositionWorld,vec3(0.0),1.0,normal,vec3(1.0),toEye\t,spotLight,dif,spe);\r\n\t\t\t\t\tdiffuse+=dif;\r\n\t\t\t\t\tspecular+=spe;\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t#endif\r\n\t#endif\r\n\r\nvec3 globalDiffuse = u_AmbientColor;\r\n#ifdef LIGHTMAP\r\n\tglobalDiffuse += decodeHDR(texture2D(u_LightMap, v_LightMapUV),5.0);\r\n#endif\r\n\r\n#if defined(CALCULATE_SHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\tfloat shadowValue = shadowValue = sampleShadowmap(v_ShadowCoord);\r\n\tgl_FragColor = vec4(gl_FragColor.rgb * (globalDiffuse + diffuse) * shadowValue, gl_FragColor.a);\r\n#else\r\n\tgl_FragColor = vec4(gl_FragColor.rgb * (globalDiffuse + diffuse), gl_FragColor.a);\r\n#endif\r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t#if defined(CALCULATE_SHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\tgl_FragColor.rgb += specular * shadowValue;\r\n\t#else\r\n\t\tgl_FragColor.rgb += specular;\r\n\t#endif\r\n#endif\r\n\r\n#ifdef FOG\r\n\tfloat lerpFact=clamp((toEyeLength-u_FogStart)/u_FogRange,0.0,1.0);\r\n\tgl_FragColor.rgb=mix(gl_FragColor.rgb,u_FogColor,lerpFact);\r\n#endif\r\n}\r\n\r\n\r\n\r\n\r\n\r\n"; + + var extendTerrainVS = "#include \"Lighting.glsl\";\r\n\r\nattribute vec4 a_Position;\r\nattribute vec2 a_Texcoord0;\r\n\r\nuniform mat4 u_MvpMatrix;\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||defined(LIGHTMAP)\r\n\tattribute vec3 a_Normal;\r\n\tvarying vec3 v_Normal;\r\n#endif\r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||defined(FOG)||(defined(CALCULATE_SHADOWS)&&defined(SHADOWMAP_PSSM1))\r\n\tuniform mat4 u_WorldMat;\r\n\tvarying vec3 v_PositionWorld;\r\n#endif\r\n\r\n#ifdef LIGHTMAP\r\n\tvarying vec2 v_LightMapUV;\r\n\tuniform vec4 u_LightmapScaleOffset;\r\n#endif\r\n\r\n#if defined(CALCULATE_SHADOWS)//shader���Զ���ĺ겻����ifdef ����ij�if defined\r\n\tvarying vec4 v_ShadowCoord;\r\n#endif\r\n\r\nvoid main()\r\n{\r\n\tgl_Position = u_MvpMatrix * a_Position;\r\n \r\n\tv_Texcoord0 = a_Texcoord0;\r\n \r\n\t#ifdef LIGHTMAP\r\n\t\tv_LightMapUV = vec2(a_Texcoord0.x, 1.0 - a_Texcoord0.y) * u_LightmapScaleOffset.xy + u_LightmapScaleOffset.zw;\r\n\t\tv_LightMapUV.y = 1.0 - v_LightMapUV.y;\r\n\t#endif\r\n \r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\tv_Normal = a_Normal;\r\n\t#endif\r\n\r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||defined(FOG)||(defined(CALCULATE_SHADOWS)&&defined(SHADOWMAP_PSSM1))\r\n\t\tv_PositionWorld=(u_WorldMat*a_Position).xyz;\r\n\t#endif\r\n\r\n\t#if defined(CALCULATE_SHADOWS)//shader���Զ���ĺ겻����ifdef ����ij�if defined\r\n\t\tv_ShadowCoord = getShadowCoord(vec4(v_PositionWorld));\r\n\t#endif\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}"; + + var GlobalIllumination = "struct LayaGIInput\r\n{\r\n\tvec2 lightmapUV;\r\n\tvec3 worldPos;\r\n};\r\n\r\n#define LAYA_SPECCUBE_LOD_STEPS 6.0\r\n\r\nuniform vec3 u_AmbientColor;\r\n\r\n#if defined(GI_AMBIENT_SH)\r\n\tuniform vec4 u_AmbientSHAr;\r\n\tuniform vec4 u_AmbientSHAg;\r\n\tuniform vec4 u_AmbientSHAb;\r\n\tuniform vec4 u_AmbientSHBr;\r\n\tuniform vec4 u_AmbientSHBg;\r\n\tuniform vec4 u_AmbientSHBb;\r\n\tuniform vec4 u_AmbientSHC;\r\n#endif\r\n\r\nuniform samplerCube u_ReflectTexture;\r\nuniform vec4 u_ReflectCubeHDRParams;\r\n\r\n#ifdef SPECCUBE_BOX_PROJECTION\r\n\tuniform vec3 u_SpecCubeProbePosition;\r\n\tuniform vec3 u_SpecCubeBoxMax;\r\n\tuniform vec3 u_SpecCubeBoxMin;\r\n#endif\r\n\r\n\r\n#ifdef GI_AMBIENT_SH\r\n\tmediump vec3 shEvalLinearL0L1(mediump vec4 normal)\r\n\t{\r\n\t\tmediump vec3 x;\r\n\t\t// Linear (L1) + constant (L0) polynomial terms\r\n\t\tx.r = dot(u_AmbientSHAr, normal);\r\n\t\tx.g = dot(u_AmbientSHAg, normal);\r\n\t\tx.b = dot(u_AmbientSHAb, normal);\r\n\t\treturn x;\r\n\t}\r\n\r\n\tmediump vec3 shEvalLinearL2(mediump vec4 normal)\r\n\t{\r\n\t\tmediump vec3 x1,x2;\r\n\t\t// 4 of the quadratic (L2) polynomials\r\n\t\tmediump vec4 vB = normal.xyzz * normal.yzzx;\r\n\t\tx1.r = dot(u_AmbientSHBr, vB);\r\n\t\tx1.g = dot(u_AmbientSHBg, vB);\r\n\t\tx1.b = dot(u_AmbientSHBb, vB);\r\n\r\n\t\t// Final (5th) quadratic (L2) polynomial\r\n\t\tmediump float vC = normal.x*normal.x - normal.y*normal.y;\r\n\t\tx2 = u_AmbientSHC.rgb * vC;\r\n\r\n\t\treturn x1 + x2;\r\n\t}\r\n\t\r\n\tmediump vec3 shadeSHPerPixel(mediump vec3 normal)\r\n\t{\r\n\t\tmediump vec3 ambientContrib;\r\n\t\tmediump vec4 normalV4=vec4(-normal.x,normal.yz, 1.0);//Note:SH Data is left-hand,so x need inverse\r\n\t\tambientContrib = shEvalLinearL0L1(normalV4);\r\n\t\tambientContrib += shEvalLinearL2(normalV4);\r\n\t\tmediump vec3 ambient = max(vec3(0.0), ambientContrib);\r\n\t\tambient = layaLinearToGammaSpace(ambient);\r\n\t\treturn ambient;\r\n\t}\r\n#endif\r\n\r\n\r\n\r\n mediump vec3 BoxProjectedCubemapDirection(mediump vec3 worldRefl,mediump vec3 worldPos,mediump vec3 cubemapCenter,mediump vec3 boxMin,mediump vec3 boxMax){\r\n\t mediump vec3 nrdir = normalize(worldRefl);\r\n\t mediump vec3 rbmax = (boxMax - worldPos);\r\n\t mediump vec3 rbmin = (boxMin - worldPos);\r\n\t mediump vec3 select = step(vec3(0.0), worldRefl);\r\n\t mediump vec3 rbminmax = mix(rbmin, rbmax, select);\r\n\trbminmax = rbminmax / nrdir;\r\n\tmediump float scalar = min(min(rbminmax.x, rbminmax.y), rbminmax.z);\r\n\t mediump vec3 worldChangeRefl = nrdir * scalar + (worldPos - cubemapCenter);\r\n\treturn worldChangeRefl;\r\n}\r\n\r\n\r\nmediump vec3 layaDecodeDirectionalLightmap (mediump vec3 color, lowp vec4 dirTex, mediump vec3 normalWorld)\r\n{\r\n // In directional (non-specular) mode Enlighten bakes dominant light direction\r\n // in a way, that using it for half Lambert and then dividing by a \"rebalancing coefficient\"\r\n // gives a result close to plain diffuse response lightmaps, but normalmapped.\r\n\r\n // Note that dir is not unit length on purpose. Its length is \"directionality\", like\r\n // for the directional specular lightmaps.\r\n\tlowp vec3 directional=dirTex.xyz - 0.5;\r\n\tdirectional.x=-directional.x;//NOTE:because coord System\r\n mediump float halfLambert = dot(normalWorld,directional) + 0.5;\r\n\r\n return color * halfLambert / max(1e-4, dirTex.w);\r\n}\r\n\r\nvec3 layaGIBase(LayaGIInput giInput,mediump float occlusion, mediump vec3 normalWorld)\r\n{\r\n\tvec3 indirectDiffuse;\r\n\t#ifdef LIGHTMAP\t\r\n\t\tmediump vec3 bakedColor =decodeHDR(texture2D(u_LightMap, giInput.lightmapUV),5.0);\r\n\t\t#ifdef LIGHTMAP_DIRECTIONAL\r\n\t\t\tlowp vec4 bakedDirTex = texture2D (u_LightMapDirection, giInput.lightmapUV);\r\n indirectDiffuse = layaDecodeDirectionalLightmap (bakedColor, bakedDirTex, normalWorld);\r\n\t\t#else //unDirectional lightmap\r\n\t\t\tindirectDiffuse = bakedColor;\r\n\t\t#endif\r\n\t#else\r\n\t\t#ifdef GI_AMBIENT_SH\r\n\t\t\tindirectDiffuse = shadeSHPerPixel(normalWorld);\r\n\t\t#else\r\n\t\t\tindirectDiffuse = u_AmbientColor; //already in gamma space\r\n\t\t#endif\r\n\t#endif\r\n\r\n\tindirectDiffuse*=occlusion;\r\n\treturn indirectDiffuse;\r\n}\r\n\r\nmediump vec3 layaGlossyEnvironment(mediump vec4 glossIn)\r\n{\r\n\tmediump float perceptualRoughness = glossIn.a;\r\n\r\n\t// use approximation to solve,below is more reasonable,but maybe slow. \r\n\t// float m = perceptualRoughnessToRoughness(perceptualRoughness); // m is the real roughness parameter\r\n // const float fEps = 1.192092896e-07F; // smallest such that 1.0+FLT_EPSILON != 1.0 (+1e-4h is NOT good here. is visibly very wrong)\r\n // float n = (2.0/max(fEps, m*m))-2.0; // remap to spec power. See eq. 21 in --> https://dl.dropboxusercontent.com/u/55891920/papers/mm_brdf.pdf\r\n // n /= 4; // remap from n_dot_h formulatino to n_dot_r. See section \"Pre-convolved Cube Maps vs Path Tracers\" --> https://s3.amazonaws.com/docs.knaldtech.com/knald/1.0.0/lys_power_drops.html\r\n // perceptualRoughness = pow( 2/(n+2), 0.25); // remap back to square root of real roughness (0.25 include both the sqrt root of the conversion and sqrt for going from roughness to perceptualRoughness)\r\n\tperceptualRoughness = perceptualRoughness * (1.7 - 0.7*perceptualRoughness);//just a approximation,but fast.\r\n \r\n\tmediump float mip = perceptualRoughness * LAYA_SPECCUBE_LOD_STEPS;\r\n\tmediump vec3 uvw = glossIn.rgb;\r\n\tuvw.x=-uvw.x;//Note:reflectCube is left-hand,so x need inverse\r\n\tmediump vec4 rgbm=textureCubeLodEXT(u_ReflectTexture,uvw,mip);\r\n\treturn decodeHDR(rgbm,u_ReflectCubeHDRParams.x);\r\n}\r\n\r\nmediump vec3 layaGIIndirectSpecular(LayaGIInput giInput,mediump float occlusion, vec4 glossIn)\r\n{\r\n\t#ifdef SPECCUBE_BOX_PROJECTION\r\n\t\tvec3 originalReflUVW = glossIn.xyz;\r\n\t\tglossIn.xyz =BoxProjectedCubemapDirection(originalReflUVW,giInput.worldPos,u_SpecCubeProbePosition,u_SpecCubeBoxMin,u_SpecCubeBoxMax);\r\n\t#endif\r\n\tmediump vec3 specular = layaGlossyEnvironment(glossIn);\r\n\treturn specular * occlusion;\r\n}\r\n\r\n\r\nLayaGI layaGlobalIllumination(LayaGIInput giInput,mediump float occlusion, mediump vec3 normalWorld,mediump vec4 uvwRoughness)\r\n{\r\n\tLayaGI gi;\r\n\tgi.diffuse = layaGIBase(giInput,occlusion, normalWorld);\r\n\tgi.specular = layaGIIndirectSpecular(giInput,occlusion, uvwRoughness);\r\n\treturn gi;\r\n}\r\n\r\n\r\n"; + + var LightingGLSL = "#ifdef GRAPHICS_API_GLES3\r\n\t#define INVERSE_MAT(mat) inverse(mat)\r\n#else\r\n\t#define INVERSE_MAT(mat) inverseMat(mat)\r\n#endif\r\n\r\nstruct DirectionLight {\r\n\tvec3 color;\r\n\tvec3 direction;\r\n};\r\n\r\nstruct PointLight {\r\n\tvec3 color;\r\n\tvec3 position;\r\n\tfloat range;\r\n};\r\n\r\nstruct SpotLight {\r\n\tvec3 color;\r\n\tvec3 position;\r\n\tfloat range;\r\n\tvec3 direction;\r\n\tfloat spot;\r\n};\r\n\r\nstruct LayaGI{\r\n\tvec3 diffuse;\r\n\tvec3 specular;\r\n};\r\n\r\nstruct LayaLight{\r\n\tvec3 color;\r\n\tvec3 dir;\r\n};\r\n\r\nconst int c_ClusterBufferWidth = CLUSTER_X_COUNT*CLUSTER_Y_COUNT;\r\nconst int c_ClusterBufferHeight = CLUSTER_Z_COUNT*(1+int(ceil(float(MAX_LIGHT_COUNT_PER_CLUSTER)/4.0)));\r\nconst int c_ClusterBufferFloatWidth = c_ClusterBufferWidth*4;\r\n\r\n#ifndef GRAPHICS_API_GLES3\r\n\tmat2 inverseMat(mat2 m) {\r\n\t\treturn mat2(m[1][1],-m[0][1],\r\n\t\t\t\t-m[1][0], m[0][0]) / (m[0][0]*m[1][1] - m[0][1]*m[1][0]);\r\n\t}\r\n\tmat3 inverseMat(mat3 m) {\r\n\t\tfloat a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];\r\n\t\tfloat a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];\r\n\t\tfloat a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];\r\n\r\n\t\tfloat b01 = a22 * a11 - a12 * a21;\r\n\t\tfloat b11 = -a22 * a10 + a12 * a20;\r\n\t\tfloat b21 = a21 * a10 - a11 * a20;\r\n\r\n\t\tfloat det = a00 * b01 + a01 * b11 + a02 * b21;\r\n\r\n\t\treturn mat3(b01, (-a22 * a01 + a02 * a21), (a12 * a01 - a02 * a11),\r\n\t\t\t\t\tb11, (a22 * a00 - a02 * a20), (-a12 * a00 + a02 * a10),\r\n\t\t\t\t\tb21, (-a21 * a00 + a01 * a20), (a11 * a00 - a01 * a10)) / det;\r\n\t}\r\n\tmat4 inverseMat(mat4 m) {\r\n\t\tfloat\r\n\t\t\ta00 = m[0][0], a01 = m[0][1], a02 = m[0][2], a03 = m[0][3],\r\n\t\t\ta10 = m[1][0], a11 = m[1][1], a12 = m[1][2], a13 = m[1][3],\r\n\t\t\ta20 = m[2][0], a21 = m[2][1], a22 = m[2][2], a23 = m[2][3],\r\n\t\t\ta30 = m[3][0], a31 = m[3][1], a32 = m[3][2], a33 = m[3][3],\r\n\r\n\t\t\tb00 = a00 * a11 - a01 * a10,\r\n\t\t\tb01 = a00 * a12 - a02 * a10,\r\n\t\t\tb02 = a00 * a13 - a03 * a10,\r\n\t\t\tb03 = a01 * a12 - a02 * a11,\r\n\t\t\tb04 = a01 * a13 - a03 * a11,\r\n\t\t\tb05 = a02 * a13 - a03 * a12,\r\n\t\t\tb06 = a20 * a31 - a21 * a30,\r\n\t\t\tb07 = a20 * a32 - a22 * a30,\r\n\t\t\tb08 = a20 * a33 - a23 * a30,\r\n\t\t\tb09 = a21 * a32 - a22 * a31,\r\n\t\t\tb10 = a21 * a33 - a23 * a31,\r\n\t\t\tb11 = a22 * a33 - a23 * a32,\r\n\r\n\t\t\tdet = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;\r\n\r\n\t\treturn mat4(\r\n\t\t\ta11 * b11 - a12 * b10 + a13 * b09,\r\n\t\t\ta02 * b10 - a01 * b11 - a03 * b09,\r\n\t\t\ta31 * b05 - a32 * b04 + a33 * b03,\r\n\t\t\ta22 * b04 - a21 * b05 - a23 * b03,\r\n\t\t\ta12 * b08 - a10 * b11 - a13 * b07,\r\n\t\t\ta00 * b11 - a02 * b08 + a03 * b07,\r\n\t\t\ta32 * b02 - a30 * b05 - a33 * b01,\r\n\t\t\ta20 * b05 - a22 * b02 + a23 * b01,\r\n\t\t\ta10 * b10 - a11 * b08 + a13 * b06,\r\n\t\t\ta01 * b08 - a00 * b10 - a03 * b06,\r\n\t\t\ta30 * b04 - a31 * b02 + a33 * b00,\r\n\t\t\ta21 * b02 - a20 * b04 - a23 * b00,\r\n\t\t\ta11 * b07 - a10 * b09 - a12 * b06,\r\n\t\t\ta00 * b09 - a01 * b07 + a02 * b06,\r\n\t\t\ta31 * b01 - a30 * b03 - a32 * b00,\r\n\t\t\ta20 * b03 - a21 * b01 + a22 * b00) / det;\r\n\t}\r\n#endif\r\n\r\n\t#ifdef THICKNESSMAP\r\n\t\tuniform sampler2D u_ThinknessTexture;\r\n\t#endif\r\n#ifdef ENABLETRANSMISSION\r\n\tuniform float u_TransmissionRate;\r\n\tuniform float u_BackDiffuse;\r\n\tuniform float u_BackScale;\r\n\tuniform vec4 u_TransmissionColor;\r\n\r\n\r\n\tvec3 SubSurfaceIBack(vec3 lightDir,vec3 viewDir,float thinknessFactor){\r\n\t\tvec3 H = normalize(lightDir);\r\n\t\tfloat VdotH = pow(clamp(dot(viewDir,H),0.0,1.0),u_BackDiffuse)*u_BackScale;\r\n\t\tvec3 I;\r\n\t\t#ifdef THICKNESSMAP\r\n\t\t\tI = u_TransmissionColor.rgb*VdotH*thinknessFactor;\r\n\t\t#else\r\n\t\t\tI = u_TransmissionColor.rgb*VdotH;\r\n\t\t#endif\r\n\t\treturn I;\r\n\t}\r\n#endif\r\n\r\nivec4 getClusterInfo(sampler2D clusterBuffer,mat4 viewMatrix,vec4 viewport,vec3 position,vec4 fragCoord,vec4 projectParams)\r\n{\r\n\tvec3 viewPos = vec3(viewMatrix*vec4(position, 1.0)); //position in viewspace\r\n\r\n\tint clusterXIndex = int(floor(fragCoord.x/ (float(viewport.z)/float(CLUSTER_X_COUNT))));\r\n int clusterYIndex = int(floor((viewport.w * (projectParams.z <0.0? 0.0 : 1.0) - fragCoord.y * projectParams.z)/ (float(viewport.w)/float(CLUSTER_Y_COUNT))));//Maybe Flipped ProjectMatrix\r\n\tfloat zSliceParam =float(CLUSTER_Z_COUNT)/log2(projectParams.y / projectParams.x);\r\n \tint clusterZIndex = int(floor(log2(-viewPos.z) * zSliceParam- log2(projectParams.x) * zSliceParam));//projectParams x:cameraNear y:cameraFar\r\n\r\n\tvec2 uv= vec2((float(clusterXIndex + clusterYIndex * CLUSTER_X_COUNT)+0.5)/float(c_ClusterBufferWidth),\r\n\t\t\t\t(float(clusterZIndex)+0.5)/float(c_ClusterBufferHeight));\r\n\tvec4 clusterPixel=texture2D(clusterBuffer, uv);\r\n\treturn ivec4(clusterPixel);//X:Point Count Y:Spot Count Z、W:Light Offset\r\n}\r\n\r\n\r\nint getLightIndex(sampler2D clusterBuffer,int offset,int index) \r\n{\r\n\tint totalOffset=offset+index;\r\n\tint row=totalOffset/c_ClusterBufferFloatWidth;\r\n\tint lastRowFloat=totalOffset-row*c_ClusterBufferFloatWidth;\r\n\tint col=lastRowFloat/4;\r\n\tvec2 uv=vec2((float(col)+0.5)/float(c_ClusterBufferWidth),\r\n\t\t\t\t(float(row)+0.5)/float(c_ClusterBufferHeight));\r\n\tvec4 texel = texture2D(clusterBuffer, uv);\r\n int pixelComponent = lastRowFloat-col*4;\r\n if (pixelComponent == 0) \r\n return int(texel.x);\r\n else if (pixelComponent == 1) \r\n return int(texel.y);\r\n else if (pixelComponent == 2) \r\n return int(texel.z);\r\n else //pixelComponent==3\r\n return int(texel.w);\r\n}\r\n\r\nDirectionLight getDirectionLight(sampler2D lightBuffer,int index) \r\n{\r\n DirectionLight light;\r\n float v = (float(index)+0.5)/ float(MAX_LIGHT_COUNT);\r\n vec4 p1 = texture2D(lightBuffer, vec2(0.125,v));\r\n vec4 p2 = texture2D(lightBuffer, vec2(0.375,v));\r\n\tlight.color=p1.rgb;\r\n light.direction = p2.rgb;\r\n return light;\r\n}\r\n\r\nPointLight getPointLight(sampler2D lightBuffer,sampler2D clusterBuffer,ivec4 clusterInfo,int index) \r\n{\r\n PointLight light;\r\n\tint pointIndex=getLightIndex(clusterBuffer,clusterInfo.z*c_ClusterBufferFloatWidth+clusterInfo.w,index);\r\n float v = (float(pointIndex)+0.5)/ float(MAX_LIGHT_COUNT);\r\n vec4 p1 = texture2D(lightBuffer, vec2(0.125,v));\r\n vec4 p2 = texture2D(lightBuffer, vec2(0.375,v));\r\n\tlight.color=p1.rgb;\r\n\tlight.range = p1.a;\r\n light.position = p2.rgb;\r\n return light;\r\n}\r\n\r\nSpotLight getSpotLight(sampler2D lightBuffer,sampler2D clusterBuffer,ivec4 clusterInfo,int index) \r\n{\r\n SpotLight light;\r\n\tint spoIndex=getLightIndex(clusterBuffer,clusterInfo.z*c_ClusterBufferFloatWidth+clusterInfo.w,clusterInfo.x+index);\r\n float v = (float(spoIndex)+0.5)/ float(MAX_LIGHT_COUNT);\r\n vec4 p1 = texture2D(lightBuffer, vec2(0.125,v));\r\n vec4 p2 = texture2D(lightBuffer, vec2(0.375,v));\r\n\tvec4 p3 = texture2D(lightBuffer, vec2(0.625,v));\r\n light.color = p1.rgb;\r\n\tlight.range=p1.a;\r\n light.position = p2.rgb;\r\n\tlight.spot = p2.a;\r\n\tlight.direction = p3.rgb;\r\n return light;\r\n}\r\n\r\n// Laya中使用衰减纹理\r\nfloat LayaAttenuation(in vec3 L,in float invLightRadius) {\r\n\tfloat fRatio = clamp(length(L) * invLightRadius,0.0,1.0);\r\n\tfRatio *= fRatio;\r\n\treturn 1.0 / (1.0 + 25.0 * fRatio)* clamp(4.0*(1.0 - fRatio),0.0,1.0); //fade to black as if 4 pixel texture\r\n}\r\n\r\n// Same as Just Cause 2 and Crysis 2 (you can read GPU Pro 1 book for more information)\r\nfloat BasicAttenuation(in vec3 L,in float invLightRadius) {\r\n\tvec3 distance = L * invLightRadius;\r\n\tfloat attenuation = clamp(1.0 - dot(distance, distance),0.0,1.0); // Equals float attenuation = saturate(1.0f - dot(L, L) / (lightRadius * lightRadius));\r\n\treturn attenuation * attenuation;\r\n}\r\n\r\n// Inspired on http://fools.slindev.com/viewtopic.php?f=11&t=21&view=unread#unread\r\nfloat NaturalAttenuation(in vec3 L,in float invLightRadius) {\r\n\tfloat attenuationFactor = 30.0;\r\n\tvec3 distance = L * invLightRadius;\r\n\tfloat attenuation = dot(distance, distance); // Equals float attenuation = dot(L, L) / (lightRadius * lightRadius);\r\n\tattenuation = 1.0 / (attenuation * attenuationFactor + 1.0);\r\n\t// Second we move down the function therewith it reaches zero at abscissa 1:\r\n\tattenuationFactor = 1.0 / (attenuationFactor + 1.0); //attenuationFactor contains now the value we have to subtract\r\n\tattenuation = max(attenuation - attenuationFactor, 0.0); // The max fixes a bug.\r\n\t// Finally we expand the equation along the y-axis so that it starts with a function value of 1 again.\r\n\tattenuation /= 1.0 - attenuationFactor;\r\n\treturn attenuation;\r\n}\r\n\r\nvoid LayaAirBlinnPhongLight (in vec3 specColor,in float specColorIntensity,in vec3 normal,in vec3 gloss, in vec3 viewDir,in vec3 lightColor, in vec3 lightVec,out vec3 diffuseColor,out vec3 specularColor) {\r\n\tmediump vec3 h = normalize(viewDir-lightVec);\r\n\tlowp float ln = max (0.0, dot (-lightVec,normal));\r\n\tfloat nh = max (0.0, dot (h,normal));\r\n\tdiffuseColor=lightColor * ln;\r\n\tspecularColor=lightColor *specColor*pow (nh, specColorIntensity*128.0) * gloss;\r\n}\r\n\r\nvoid LayaAirBlinnPhongDiectionLight (in vec3 specColor,in float specColorIntensity,in vec3 normal,in vec3 gloss, in vec3 viewDir, in DirectionLight light,float thinknessFactor,out vec3 diffuseColor,out vec3 specularColor,out vec3 transmisColor) {\r\n\tvec3 lightVec=normalize(light.direction);\r\n\tLayaAirBlinnPhongLight(specColor,specColorIntensity,normal,gloss,viewDir,light.color,lightVec,diffuseColor,specularColor);\r\n\t#ifdef ENABLETRANSMISSION\r\n\t\tdiffuseColor *= u_TransmissionRate;\r\n\t\ttransmisColor = SubSurfaceIBack(lightVec, viewDir,thinknessFactor)*light.color.rgb*(1.0-u_TransmissionRate);\r\n\t#endif\r\n}\r\n\r\n\r\nvoid LayaAirBlinnPhongDiectionLight (in vec3 specColor,in float specColorIntensity,in vec3 normal,in vec3 gloss, in vec3 viewDir, in DirectionLight light,out vec3 diffuseColor,out vec3 specularColor) {\r\n\tvec3 lightVec=normalize(light.direction);\r\n\tLayaAirBlinnPhongLight(specColor,specColorIntensity,normal,gloss,viewDir,light.color,lightVec,diffuseColor,specularColor);\r\n}\r\n\r\n\r\nvoid LayaAirBlinnPhongPointLight (in vec3 pos,in vec3 specColor,in float specColorIntensity,in vec3 normal,in vec3 gloss, in vec3 viewDir, in PointLight light,float thinknessFactor,out vec3 diffuseColor,out vec3 specularColor,out vec3 transmisColor) {\r\n\tvec3 lightVec = pos-light.position;\r\n\tLayaAirBlinnPhongLight(specColor,specColorIntensity,normal,gloss,viewDir,light.color,lightVec/length(lightVec),diffuseColor,specularColor);\r\n\tfloat attenuate = LayaAttenuation(lightVec, 1.0/light.range);\r\n\tdiffuseColor *= attenuate;\r\n\tspecularColor*= attenuate;\r\n\t#ifdef ENABLETRANSMISSION\r\n\t\tdiffuseColor *= u_TransmissionRate;\r\n\t\ttransmisColor = SubSurfaceIBack(lightVec, viewDir,thinknessFactor)*light.color.rgb*(1.0-u_TransmissionRate)*attenuate;\r\n\t#endif\r\n}\r\n\r\nvoid LayaAirBlinnPhongPointLight (in vec3 pos,in vec3 specColor,in float specColorIntensity,in vec3 normal,in vec3 gloss, in vec3 viewDir, in PointLight light,out vec3 diffuseColor,out vec3 specularColor) {\r\n\tvec3 lightVec = pos-light.position;\r\n\tLayaAirBlinnPhongLight(specColor,specColorIntensity,normal,gloss,viewDir,light.color,lightVec/length(lightVec),diffuseColor,specularColor);\r\n\tfloat attenuate = LayaAttenuation(lightVec, 1.0/light.range);\r\n\tdiffuseColor *= attenuate;\r\n\tspecularColor*= attenuate;\r\n}\r\n\r\nvoid LayaAirBlinnPhongSpotLight (in vec3 pos,in vec3 specColor,in float specColorIntensity,in vec3 normal,in vec3 gloss, in vec3 viewDir, in SpotLight light,float thinknessFactor,out vec3 diffuseColor,out vec3 specularColor,out vec3 transmisColor) {\r\n\tvec3 lightVec = pos-light.position;\r\n\tvec3 normalLightVec=lightVec/length(lightVec);\r\n\tLayaAirBlinnPhongLight(specColor,specColorIntensity,normal,gloss,viewDir,light.color,normalLightVec,diffuseColor,specularColor);\r\n\tvec2 cosAngles=cos(vec2(light.spot,light.spot*0.5)*0.5);//ConeAttenuation\r\n\tfloat dl=dot(normalize(light.direction),normalLightVec);\r\n\tdl*=smoothstep(cosAngles[0],cosAngles[1],dl);\r\n\tfloat attenuate = LayaAttenuation(lightVec, 1.0/light.range)*dl;\r\n\tdiffuseColor *=attenuate;\r\n\tspecularColor *=attenuate;\r\n\t#ifdef ENABLETRANSMISSION\r\n\t\tdiffuseColor *= u_TransmissionRate;\r\n\t\ttransmisColor = SubSurfaceIBack(lightVec, viewDir,thinknessFactor)*light.color.rgb*(1.0-u_TransmissionRate)*attenuate;\r\n\t#endif\r\n}\r\n\r\nvoid LayaAirBlinnPhongSpotLight (in vec3 pos,in vec3 specColor,in float specColorIntensity,in vec3 normal,in vec3 gloss, in vec3 viewDir, in SpotLight light,out vec3 diffuseColor,out vec3 specularColor) {\r\n\tvec3 lightVec = pos-light.position;\r\n\tvec3 normalLightVec=lightVec/length(lightVec);\r\n\tLayaAirBlinnPhongLight(specColor,specColorIntensity,normal,gloss,viewDir,light.color,normalLightVec,diffuseColor,specularColor);\r\n\tvec2 cosAngles=cos(vec2(light.spot,light.spot*0.5)*0.5);//ConeAttenuation\r\n\tfloat dl=dot(normalize(light.direction),normalLightVec);\r\n\tdl*=smoothstep(cosAngles[0],cosAngles[1],dl);\r\n\tfloat attenuate = LayaAttenuation(lightVec, 1.0/light.range)*dl;\r\n\tdiffuseColor *=attenuate;\r\n\tspecularColor *=attenuate;\r\n}\r\n\r\n\r\n\r\n\r\nvec3 NormalSampleToWorldSpace(vec3 normalMapSample, vec3 unitNormal, vec3 tangent,vec3 binormal) {\r\n\tvec3 normalT =vec3(2.0*normalMapSample.x - 1.0,1.0-2.0*normalMapSample.y,2.0*normalMapSample.z - 1.0);\r\n\tmediump vec3 N = unitNormal;\r\n\tmediump vec3 T = tangent;\r\n\tmediump vec3 B = binormal;\r\n\tmat3 TBN = mat3(T, B, N);\r\n\r\n\t// Transform from tangent space to world space.\r\n\tvec3 bumpedNormal =normalize(TBN*normalT);\r\n\treturn bumpedNormal;\r\n}\r\n\r\nvec3 NormalSampleToWorldSpace1(vec4 normalMapSample, vec3 tangent, vec3 binormal, vec3 unitNormal) {\r\n\tvec3 normalT;\r\n\tnormalT.x = 2.0 * normalMapSample.x - 1.0;\r\n\tnormalT.y = 1.0 - 2.0 * normalMapSample.y;\r\n\tnormalT.z = sqrt(1.0 - clamp(dot(normalT.xy, normalT.xy), 0.0, 1.0));\r\n\r\n\tvec3 T = normalize(tangent);\r\n\tvec3 B = normalize(binormal);\r\n\tvec3 N = normalize(unitNormal);\r\n\tmat3 TBN = mat3(T, B, N);\r\n\r\n\t// Transform from tangent space to world space.\r\n\tvec3 bumpedNormal = TBN * normalize(normalT);\r\n\r\n\treturn bumpedNormal;\r\n}\r\n\r\nvec3 DecodeLightmap(vec4 color) {\r\n\treturn color.rgb*color.a*5.0;\r\n}\r\n\r\nvec3 decodeHDR(vec4 color,float range) {\r\n\treturn color.rgb*color.a*range;\r\n}\r\n\r\nvec2 TransformUV(vec2 texcoord,vec4 tilingOffset) {\r\n\tvec2 transTexcoord=vec2(texcoord.x,texcoord.y-1.0)*tilingOffset.xy+vec2(tilingOffset.z,-tilingOffset.w);\r\n\ttransTexcoord.y+=1.0;\r\n\treturn transTexcoord;\r\n}\r\n\r\nvec4 remapGLPositionZ(vec4 position) {\r\n\tposition.z=position.z * 2.0 - position.w;\r\n\treturn position;\r\n}\r\n\r\nmediump vec3 layaLinearToGammaSpace (mediump vec3 linRGB)\r\n{\r\n linRGB = max(linRGB, vec3(0.0));\r\n // An almost-perfect approximation from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1\r\n return max(1.055 * pow(linRGB,vec3(0.416666667)) - 0.055, 0.0); \r\n}\r\n\r\nLayaLight layaDirectionLightToLight(in DirectionLight light,in float attenuate)\r\n{\r\n\tLayaLight relight;\r\n\trelight.color = light.color*attenuate;\r\n\trelight.dir = light.direction;\r\n\treturn relight;\r\n}\r\n\r\nLayaLight layaPointLightToLight(in vec3 pos,in vec3 normal, in PointLight light,in float attenuate)\r\n{\r\n\tLayaLight relight;\r\n\tvec3 lightVec = pos-light.position;\r\n\tattenuate *= LayaAttenuation(lightVec, 1.0/light.range);\r\n\trelight.color = light.color*attenuate;\r\n\trelight.dir = normalize(lightVec);\r\n\treturn relight;\r\n}\r\n\r\nLayaLight layaSpotLightToLight(in vec3 pos,in vec3 normal, in SpotLight light,in float attenuate)\r\n{\r\n\tLayaLight relight;\r\n\tvec3 lightVec = pos-light.position;\r\n\tvec3 normalLightVec=lightVec/length(lightVec);\r\n\tvec2 cosAngles=cos(vec2(light.spot,light.spot*0.5)*0.5);//ConeAttenuation\r\n\tfloat dl=dot(normalize(light.direction),normalLightVec);\r\n\tdl*=smoothstep(cosAngles[0],cosAngles[1],dl);\r\n\tattenuate *= LayaAttenuation(lightVec, 1.0/light.range)*dl;\r\n\trelight.dir = normalLightVec;\r\n\trelight.color = light.color*attenuate;\r\n\treturn relight;\r\n}\r\n\r\n\r\n\r\n\r\n"; + + var ShadowSampleTentGLSL = "// ------------------------------------------------------------------\r\n// PCF Filtering Tent Functions\r\n// ------------------------------------------------------------------\r\n\r\n// Assuming a isoceles right angled triangle of height \"triangleHeight\" (as drawn below).\r\n// This function return the area of the triangle above the first texel(in Y the first texel).\r\n//\r\n// |\\ <-- 45 degree slop isosceles right angled triangle\r\n// | \\\r\n// ---- <-- length of this side is \"triangleHeight\"\r\n// _ _ _ _ <-- texels\r\nfloat sampleShadowGetIRTriangleTexelArea(float triangleHeight)\r\n{\r\n return triangleHeight - 0.5;\r\n}\r\n\r\n// Assuming a isoceles triangle of 1.5 texels height and 3 texels wide lying on 4 texels.\r\n// This function return the area of the triangle above each of those texels.\r\n// | <-- offset from -0.5 to 0.5, 0 meaning triangle is exactly in the center\r\n// / \\ <-- 45 degree slop isosceles triangle (ie tent projected in 2D)\r\n// / \\\r\n// _ _ _ _ <-- texels\r\n// X Y Z W <-- result indices (in computedArea.xyzw and computedAreaUncut.xyzw)\r\n// Top point at (right,top) in a texel,left bottom point at (middle,middle) in a texel,right bottom point at (middle,middle) in a texel.\r\nvoid sampleShadowGetTexelAreasTent3x3(float offset, out vec4 computedArea, out vec4 computedAreaUncut)\r\n{\r\n // Compute the exterior areas,a and h is same.\r\n float a = offset + 0.5;\r\n float offsetSquaredHalved = a * a * 0.5;\r\n computedAreaUncut.x = computedArea.x = offsetSquaredHalved - offset;\r\n computedAreaUncut.w = computedArea.w = offsetSquaredHalved;\r\n\r\n // Compute the middle areas\r\n // For Y : We find the area in Y of as if the left section of the isoceles triangle would\r\n // intersect the axis between Y and Z (ie where offset = 0).\r\n computedAreaUncut.y = sampleShadowGetIRTriangleTexelArea(1.5 - offset);\r\n // This area is superior to the one we are looking for if (offset < 0) thus we need to\r\n // subtract the area of the triangle defined by (0,1.5-offset), (0,1.5+offset), (-offset,1.5).\r\n float clampedOffsetLeft = min(offset,0.0);\r\n float areaOfSmallLeftTriangle = clampedOffsetLeft * clampedOffsetLeft;\r\n computedArea.y = computedAreaUncut.y - areaOfSmallLeftTriangle;\r\n\r\n // We do the same for the Z but with the right part of the isoceles triangle\r\n computedAreaUncut.z = sampleShadowGetIRTriangleTexelArea(1.5 + offset);\r\n float clampedOffsetRight = max(offset,0.0);\r\n float areaOfSmallRightTriangle = clampedOffsetRight * clampedOffsetRight;\r\n computedArea.z = computedAreaUncut.z - areaOfSmallRightTriangle;\r\n}\r\n\r\n// Assuming a isoceles triangle of 2.5 texel height and 5 texels wide lying on 6 texels.\r\n// This function return the weight of each texels area relative to the full triangle area.\r\n// / \\\r\n// _ _ _ _ _ _ <-- texels\r\n// 0 1 2 3 4 5 <-- computed area indices (in texelsWeights[])\r\n// Top point at (right,top) in a texel,left bottom point at (middle,middle) in a texel,right bottom point at (middle,middle) in a texel.\r\nvoid sampleShadowGetTexelWeightsTent5x5(float offset, out vec3 texelsWeightsA, out vec3 texelsWeightsB)\r\n{\r\n vec4 areaFrom3texelTriangle;\r\n vec4 areaUncutFrom3texelTriangle;\r\n sampleShadowGetTexelAreasTent3x3(offset, areaFrom3texelTriangle, areaUncutFrom3texelTriangle);\r\n\r\n // Triangle slope is 45 degree thus we can almost reuse the result of the 3 texel wide computation.\r\n // the 5 texel wide triangle can be seen as the 3 texel wide one but shifted up by one unit/texel.\r\n // 0.16 is 1/(the triangle area)\r\n texelsWeightsA.x = 0.16 * (areaFrom3texelTriangle.x);\r\n texelsWeightsA.y = 0.16 * (areaUncutFrom3texelTriangle.y);\r\n texelsWeightsA.z = 0.16 * (areaFrom3texelTriangle.y + 1.0);\r\n texelsWeightsB.x = 0.16 * (areaFrom3texelTriangle.z + 1.0);\r\n texelsWeightsB.y = 0.16 * (areaUncutFrom3texelTriangle.z);\r\n texelsWeightsB.z = 0.16 * (areaFrom3texelTriangle.w);\r\n}\r\n\r\n// 5x5 Tent filter (45 degree sloped triangles in U and V)\r\nvoid sampleShadowComputeSamplesTent5x5(vec4 shadowMapTextureTexelSize, vec2 coord, out float fetchesWeights[9], out vec2 fetchesUV[9])\r\n{\r\n // tent base is 5x5 base thus covering from 25 to 36 texels, thus we need 9 bilinear PCF fetches\r\n vec2 tentCenterInTexelSpace = coord.xy * shadowMapTextureTexelSize.zw;\r\n vec2 centerOfFetchesInTexelSpace = floor(tentCenterInTexelSpace + 0.5);\r\n vec2 offsetFromTentCenterToCenterOfFetches = tentCenterInTexelSpace - centerOfFetchesInTexelSpace;\r\n\r\n // find the weight of each texel based on the area of a 45 degree slop tent above each of them.\r\n vec3 texelsWeightsUA, texelsWeightsUB;\r\n vec3 texelsWeightsVA, texelsWeightsVB;\r\n sampleShadowGetTexelWeightsTent5x5(offsetFromTentCenterToCenterOfFetches.x, texelsWeightsUA, texelsWeightsUB);\r\n sampleShadowGetTexelWeightsTent5x5(offsetFromTentCenterToCenterOfFetches.y, texelsWeightsVA, texelsWeightsVB);\r\n\r\n // each fetch will cover a group of 2x2 texels, the weight of each group is the sum of the weights of the texels\r\n vec3 fetchesWeightsU = vec3(texelsWeightsUA.xz, texelsWeightsUB.y) + vec3(texelsWeightsUA.y, texelsWeightsUB.xz);\r\n vec3 fetchesWeightsV = vec3(texelsWeightsVA.xz, texelsWeightsVB.y) + vec3(texelsWeightsVA.y, texelsWeightsVB.xz);\r\n\r\n // move the PCF bilinear fetches to respect texels weights\r\n vec3 fetchesOffsetsU = vec3(texelsWeightsUA.y, texelsWeightsUB.xz) / fetchesWeightsU.xyz + vec3(-2.5,-0.5,1.5);\r\n vec3 fetchesOffsetsV = vec3(texelsWeightsVA.y, texelsWeightsVB.xz) / fetchesWeightsV.xyz + vec3(-2.5,-0.5,1.5);\r\n fetchesOffsetsU *= shadowMapTextureTexelSize.xxx;\r\n fetchesOffsetsV *= shadowMapTextureTexelSize.yyy;\r\n\r\n vec2 bilinearFetchOrigin = centerOfFetchesInTexelSpace * shadowMapTextureTexelSize.xy;\r\n fetchesUV[0] = bilinearFetchOrigin + vec2(fetchesOffsetsU.x, fetchesOffsetsV.x);\r\n fetchesUV[1] = bilinearFetchOrigin + vec2(fetchesOffsetsU.y, fetchesOffsetsV.x);\r\n fetchesUV[2] = bilinearFetchOrigin + vec2(fetchesOffsetsU.z, fetchesOffsetsV.x);\r\n fetchesUV[3] = bilinearFetchOrigin + vec2(fetchesOffsetsU.x, fetchesOffsetsV.y);\r\n fetchesUV[4] = bilinearFetchOrigin + vec2(fetchesOffsetsU.y, fetchesOffsetsV.y);\r\n fetchesUV[5] = bilinearFetchOrigin + vec2(fetchesOffsetsU.z, fetchesOffsetsV.y);\r\n fetchesUV[6] = bilinearFetchOrigin + vec2(fetchesOffsetsU.x, fetchesOffsetsV.z);\r\n fetchesUV[7] = bilinearFetchOrigin + vec2(fetchesOffsetsU.y, fetchesOffsetsV.z);\r\n fetchesUV[8] = bilinearFetchOrigin + vec2(fetchesOffsetsU.z, fetchesOffsetsV.z);\r\n\r\n fetchesWeights[0] = fetchesWeightsU.x * fetchesWeightsV.x;\r\n fetchesWeights[1] = fetchesWeightsU.y * fetchesWeightsV.x;\r\n fetchesWeights[2] = fetchesWeightsU.z * fetchesWeightsV.x;\r\n fetchesWeights[3] = fetchesWeightsU.x * fetchesWeightsV.y;\r\n fetchesWeights[4] = fetchesWeightsU.y * fetchesWeightsV.y;\r\n fetchesWeights[5] = fetchesWeightsU.z * fetchesWeightsV.y;\r\n fetchesWeights[6] = fetchesWeightsU.x * fetchesWeightsV.z;\r\n fetchesWeights[7] = fetchesWeightsU.y * fetchesWeightsV.z;\r\n fetchesWeights[8] = fetchesWeightsU.z * fetchesWeightsV.z;\r\n}"; + + var LayaUtile = "\r\n\r\n//SimpleSkinnedMesh\r\n#ifdef SIMPLEBONE\r\n\t#ifdef GPU_INSTANCE\r\n\t\tattribute vec4 a_SimpleTextureParams;\r\n\t#else\r\n\t\tuniform vec4 u_SimpleAnimatorParams;\r\n\t#endif\r\n\tuniform sampler2D u_SimpleAnimatorTexture;\r\n\r\n\tuniform float u_SimpleAnimatorTextureSize; \r\n#endif\r\n\r\n\r\n#ifdef SIMPLEBONE\r\n\tmat4 loadMatFromTexture(float FramePos,int boneIndices,float offset)\r\n\t{\r\n\t\tvec2 uv;\r\n\t\tfloat PixelPos = FramePos+float(boneIndices)*4.0;\r\n\t\tfloat halfOffset = offset * 0.5;\r\n\t\tfloat uvoffset = PixelPos/u_SimpleAnimatorTextureSize;\r\n\t\tuv.y = floor(uvoffset)*offset+halfOffset;\r\n\t\tuv.x = mod(float(PixelPos),u_SimpleAnimatorTextureSize)*offset+halfOffset;\r\n\t\tvec4 mat0row = texture2D(u_SimpleAnimatorTexture,uv);\r\n\t\tuv.x+=offset;\r\n\t\tvec4 mat1row = texture2D(u_SimpleAnimatorTexture,uv);\r\n\t\tuv.x+=offset;\r\n\t\tvec4 mat2row = texture2D(u_SimpleAnimatorTexture,uv);\r\n\t\tuv.x+=offset;\r\n\t\tvec4 mat3row = texture2D(u_SimpleAnimatorTexture,uv);\r\n\t\tmat4 m =mat4(mat0row.x,mat0row.y,mat0row.z,mat0row.w,\r\n\t\t\t\tmat1row.x,mat1row.y,mat1row.z,mat1row.w,\r\n\t\t\t\tmat2row.x,mat2row.y,mat2row.z,mat2row.w,\r\n\t\t\t\tmat3row.x,mat3row.y,mat3row.z,mat3row.w);\r\n\t\treturn m;\r\n\t}\r\n#endif\r\n\r\n"; + + var linePS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\nprecision highp float;\r\n#else\r\nprecision mediump float;\r\n#endif\r\n\r\nvarying vec4 v_Color;\r\nuniform vec4 u_Color;\r\n\r\nvoid main()\r\n{\r\n gl_FragColor = v_Color * u_Color; \r\n}\r\n\r\n"; + + var lineVS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\nprecision highp float;\r\n#else\r\nprecision mediump float;\r\n#endif\r\n\r\n#include \"Lighting.glsl\";\r\n\r\nattribute vec4 a_Position;\r\nuniform mat4 u_MvpMatrix;\r\nuniform vec4 u_Color;\r\nattribute vec4 a_Color;\r\nvarying vec4 v_Color;\r\n\r\n\r\nvoid main()\r\n{\r\n\tgl_Position = u_MvpMatrix * a_Position;\r\n\tv_Color=a_Color*u_Color;\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}"; + + var MeshBlinnPhongPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n\r\n\r\n#include \"Lighting.glsl\";\r\n#include \"Shadow.glsl\"\r\n\r\nuniform vec4 u_DiffuseColor;\r\nuniform float u_AlbedoIntensity;\r\n\r\n#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)\r\n\tvarying vec4 v_Color;\r\n#endif\r\n\r\n#ifdef ALPHATEST\r\n\tuniform float u_AlphaTestValue;\r\n#endif\r\n\r\n#ifdef DIFFUSEMAP\r\n\tuniform sampler2D u_DiffuseTexture;\r\n#endif\r\n\r\n\r\n#if defined(DIFFUSEMAP)||defined(THICKNESSMAP)||((defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT))&&(defined(SPECULARMAP)||defined(NORMALMAP)))\r\n\tvarying vec2 v_Texcoord0;\r\n#endif\r\n\r\n#ifdef LIGHTMAP\r\n\tvarying vec2 v_LightMapUV;\r\n\tuniform sampler2D u_LightMap;\r\n\t#ifdef LIGHTMAP_DIRECTIONAL\r\n\t\tuniform sampler2D u_LightMapDirection;\r\n\t#endif\r\n#endif\r\n\r\nvarying vec3 v_Normal;\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\tvarying vec3 v_ViewDir; \r\n\r\n\tuniform vec3 u_MaterialSpecular;\r\n\tuniform float u_Shininess;\r\n\r\n\t#ifdef LEGACYSINGLELIGHTING\r\n\t\t#ifdef DIRECTIONLIGHT\r\n\t\t\tuniform DirectionLight u_DirectionLight;\r\n\t\t#endif\r\n\t\t#ifdef POINTLIGHT\r\n\t\t\tuniform PointLight u_PointLight;\r\n\t\t#endif\r\n\t\t#ifdef SPOTLIGHT\r\n\t\t\tuniform SpotLight u_SpotLight;\r\n\t\t#endif\r\n\t#else\r\n\t\tuniform mat4 u_View;\r\n\t\tuniform vec4 u_ProjectionParams;\r\n\t\tuniform vec4 u_Viewport;\r\n\t\tuniform int u_DirationLightCount;\r\n\t\tuniform sampler2D u_LightBuffer;\r\n\t\tuniform sampler2D u_LightClusterBuffer;\r\n\t#endif\r\n\r\n\t#ifdef SPECULARMAP \r\n\t\tuniform sampler2D u_SpecularTexture;\r\n\t#endif\r\n#endif\r\n\r\n#ifdef NORMALMAP \r\n\tuniform sampler2D u_NormalTexture;\r\n\tvarying vec3 v_Tangent;\r\n\tvarying vec3 v_Binormal;\r\n#endif\r\n\r\n#ifdef FOG\r\n\tuniform float u_FogStart;\r\n\tuniform float u_FogRange;\r\n\tuniform vec3 u_FogColor;\r\n#endif\r\n\r\n#if defined(POINTLIGHT)||defined(SPOTLIGHT)||(defined(CALCULATE_SHADOWS)&&defined(SHADOW_CASCADE))||defined(CALCULATE_SPOTSHADOWS)\r\n\tvarying vec3 v_PositionWorld;\r\n#endif\r\n\r\n\r\n#include \"GlobalIllumination.glsl\";//\"GlobalIllumination.glsl use uniform should at front of this\r\n\r\n#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)\r\n\tvarying vec4 v_ShadowCoord;\r\n#endif\r\n\r\n#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\tvarying vec4 v_SpotShadowCoord;\r\n#endif\r\n\r\n\r\nvoid main()\r\n{\r\n\tvec3 normal;//light and SH maybe use normal\r\n\t#if defined(NORMALMAP)\r\n\t\tvec3 normalMapSample = texture2D(u_NormalTexture, v_Texcoord0).rgb;\r\n\t\tnormal = normalize(NormalSampleToWorldSpace(normalMapSample, v_Normal, v_Tangent,v_Binormal));\r\n\t#else\r\n\t\tnormal = normalize(v_Normal);\r\n\t#endif\r\n\r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\tvec3 viewDir= normalize(v_ViewDir);\r\n\t#endif\r\n\r\n\tLayaGIInput giInput;\r\n\t#ifdef LIGHTMAP\t\r\n\t\tgiInput.lightmapUV=v_LightMapUV;\r\n\t#endif\r\n\tvec3 globalDiffuse=layaGIBase(giInput,1.0,normal);\r\n\t\r\n\tvec4 mainColor = u_DiffuseColor * u_AlbedoIntensity;\r\n\t#ifdef DIFFUSEMAP\r\n\t\tvec4 difTexColor=texture2D(u_DiffuseTexture, v_Texcoord0);\r\n\t\tmainColor=mainColor*difTexColor;\r\n\t#endif \r\n\t#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)\r\n\t\tmainColor=mainColor*v_Color;\r\n\t#endif \r\n \r\n\t#ifdef ALPHATEST\r\n\t\tif(mainColor.a= u_DirationLightCount)\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tDirectionLight directionLight = getDirectionLight(u_LightBuffer,i);\r\n\t\t\t\t#if defined(CALCULATE_SHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\t\t\t\tif(i == 0)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t#ifdef SHADOW_CASCADE\r\n\t\t\t\t\t\t\tvec4 shadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));\r\n\t\t\t\t\t\t#else\r\n\t\t\t\t\t\t\tvec4 shadowCoord = v_ShadowCoord;\r\n\t\t\t\t\t\t#endif\r\n\t\t\t\t\t\tdirectionLight.color *= sampleShadowmap(shadowCoord);\r\n\t\t\t\t\t}\r\n\t\t\t\t#endif\r\n\t\t\t\tLayaAirBlinnPhongDiectionLight(u_MaterialSpecular,u_Shininess,normal,gloss,viewDir,directionLight,transmissionFactor,dif,spe,transmis);\r\n\t\t\t\tdiffuse+=dif;\r\n\t\t\t\tspecular+=spe;\r\n\t\t\t\ttransmissionDiffuse+=transmis;\r\n\t\t\t}\r\n\t\t#endif\r\n\t\t#if defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\t\tivec4 clusterInfo =getClusterInfo(u_LightClusterBuffer,u_View,u_Viewport, v_PositionWorld,gl_FragCoord,u_ProjectionParams);\r\n\t\t\t#ifdef POINTLIGHT\r\n\t\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t\t{\r\n\t\t\t\t\tif(i >= clusterInfo.x)//PointLightCount\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tPointLight pointLight = getPointLight(u_LightBuffer,u_LightClusterBuffer,clusterInfo,i);\r\n\t\t\t\t\tLayaAirBlinnPhongPointLight(v_PositionWorld,u_MaterialSpecular,u_Shininess,normal,gloss,viewDir,pointLight,transmissionFactor,dif,spe,transmis);\r\n\t\t\t\t\tdiffuse+=dif;\r\n\t\t\t\t\tspecular+=spe;\r\n\t\t\t\t\ttransmissionDiffuse+=transmis;\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t\t#ifdef SPOTLIGHT\r\n\t\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t\t{\r\n\t\t\t\t\tif(i >= clusterInfo.y)//SpotLightCount\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tSpotLight spotLight = getSpotLight(u_LightBuffer,u_LightClusterBuffer,clusterInfo,i);\r\n\t\t\t\t\t#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\t\t\t\t\tif(i == 0)\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\tvec4 spotShadowcoord = v_SpotShadowCoord;\r\n\t\t\t\t\t\t\tspotLight.color *= sampleSpotShadowmap(spotShadowcoord);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t#endif\r\n\t\t\t\t\tLayaAirBlinnPhongSpotLight(v_PositionWorld,u_MaterialSpecular,u_Shininess,normal,gloss,viewDir,spotLight,transmissionFactor,dif,spe,transmis);\r\n\t\t\t\t\tdiffuse+=dif;\r\n\t\t\t\t\tspecular+=spe;\r\n\t\t\t\t\ttransmissionDiffuse+=transmis;\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t#endif\r\n\t#endif\r\n\r\n\tgl_FragColor =vec4(mainColor.rgb*(globalDiffuse + diffuse),mainColor.a);\r\n\r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\tgl_FragColor.rgb+=specular;\r\n\t#endif\r\n\r\n\t#ifdef ENABLETRANSMISSION\r\n\t\tgl_FragColor.rgb+= transmissionDiffuse;\r\n\t#endif\r\n\r\n\t \r\n\t#ifdef FOG\r\n\t\tfloat lerpFact=clamp((1.0/gl_FragCoord.w-u_FogStart)/u_FogRange,0.0,1.0);\r\n\t\tgl_FragColor.rgb=mix(gl_FragColor.rgb,u_FogColor,lerpFact);\r\n\t#endif\r\n\r\n\t//gl_FragColor.rgb =transmissionDiffuse;\r\n}\r\n\r\n"; + + var MeshBlinnPhongVS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n#include \"Lighting.glsl\";\r\n#include \"LayaUtile.glsl\"\r\n#include \"Shadow.glsl\";\r\n\r\n\r\nattribute vec4 a_Position;\r\n\r\n#ifdef GPU_INSTANCE\r\n\tuniform mat4 u_ViewProjection;\r\n#else\r\n\tuniform mat4 u_MvpMatrix;\r\n#endif\r\n\r\n#if defined(DIFFUSEMAP)||defined(THICKNESSMAP)||((defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT))&&(defined(SPECULARMAP)||defined(NORMALMAP)))||(defined(LIGHTMAP)&&defined(UV))\r\n\tattribute vec2 a_Texcoord0;\r\n\tvarying vec2 v_Texcoord0;\r\n#endif\r\n\r\n#if defined(LIGHTMAP)&&defined(UV1)\r\n\tattribute vec2 a_Texcoord1;\r\n#endif\r\n\r\n#ifdef LIGHTMAP\r\n\tuniform vec4 u_LightmapScaleOffset;\r\n\tvarying vec2 v_LightMapUV;\r\n#endif\r\n\r\n#ifdef COLOR\r\n\tattribute vec4 a_Color;\r\n\tvarying vec4 v_Color;\r\n#endif\r\n\r\n#ifdef BONE\r\n\tconst int c_MaxBoneCount = 24;\r\n\tattribute vec4 a_BoneIndices;\r\n\tattribute vec4 a_BoneWeights;\r\n\tuniform mat4 u_Bones[c_MaxBoneCount];\r\n#endif\r\n\r\nattribute vec3 a_Normal;\r\nvarying vec3 v_Normal; \r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\tuniform vec3 u_CameraPos;\r\n\tvarying vec3 v_ViewDir; \r\n#endif\r\n\r\n#if defined(NORMALMAP)\r\n\tattribute vec4 a_Tangent0;\r\n\tvarying vec3 v_Tangent;\r\n\tvarying vec3 v_Binormal;\r\n#endif\r\n\r\n#ifdef GPU_INSTANCE\r\n\tattribute mat4 a_WorldMat;\r\n#else\r\n\tuniform mat4 u_WorldMat;\r\n#endif\r\n\r\n#if defined(POINTLIGHT)||defined(SPOTLIGHT)||(defined(CALCULATE_SHADOWS)&&defined(SHADOW_CASCADE))||defined(CALCULATE_SPOTSHADOWS)\r\n\tvarying vec3 v_PositionWorld;\r\n#endif\r\n\r\n#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)\r\n\tvarying vec4 v_ShadowCoord;\r\n#endif\r\n\r\n#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\tvarying vec4 v_SpotShadowCoord;\r\n#endif\r\n\r\nuniform vec4 u_TilingOffset;\r\n\r\nvoid main()\r\n{\r\n\tvec4 position;\r\n\t#ifdef BONE\r\n\t\tmat4 skinTransform;\r\n\t \t#ifdef SIMPLEBONE\r\n\t\t\tfloat currentPixelPos;\r\n\t\t\t#ifdef GPU_INSTANCE\r\n\t\t\t\tcurrentPixelPos = a_SimpleTextureParams.x+a_SimpleTextureParams.y;\r\n\t\t\t#else\r\n\t\t\t\tcurrentPixelPos = u_SimpleAnimatorParams.x+u_SimpleAnimatorParams.y;\r\n\t\t\t#endif\r\n\t\t\tfloat offset = 1.0/u_SimpleAnimatorTextureSize;\r\n\t\t\tskinTransform = loadMatFromTexture(currentPixelPos,int(a_BoneIndices.x),offset) * a_BoneWeights.x;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.y),offset) * a_BoneWeights.y;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.z),offset) * a_BoneWeights.z;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.w),offset) * a_BoneWeights.w;\r\n\t\t#else\r\n\t\t\tskinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;\r\n\t\t#endif\r\n\t\tposition=skinTransform*a_Position;\r\n\t #else\r\n\t\tposition=a_Position;\r\n\t#endif\r\n\r\n\r\n\t\r\n\tmat4 worldMat;\r\n\t#ifdef GPU_INSTANCE\r\n\t\tworldMat = a_WorldMat;\r\n\t#else\r\n\t\tworldMat = u_WorldMat;\r\n\t#endif\r\n\r\n\t#ifdef GPU_INSTANCE\r\n\t\tgl_Position = u_ViewProjection * worldMat * position;\r\n\t#else\r\n\t\tgl_Position = u_MvpMatrix * position;\r\n\t#endif\r\n\r\n\tmat3 worldInvMat;\r\n\t#ifdef BONE\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat*skinTransform));\r\n\t#else\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat));\r\n\t#endif \r\n\tv_Normal=normalize(a_Normal*worldInvMat);\r\n\t#if defined(NORMALMAP)\r\n\t\tv_Tangent=normalize(a_Tangent0.xyz*worldInvMat);\r\n\t\tv_Binormal=cross(v_Normal,v_Tangent)*a_Tangent0.w;\r\n\t#endif\r\n\r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||(defined(CALCULATE_SHADOWS)&&defined(SHADOW_CASCADE))||defined(CALCULATE_SPOTSHADOWS)\r\n\t\tvec3 positionWS=(worldMat*position).xyz;\r\n\t\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\t\tv_ViewDir = u_CameraPos-positionWS;\r\n\t\t#endif\r\n\t\t#if defined(POINTLIGHT)||defined(SPOTLIGHT)||(defined(CALCULATE_SHADOWS)&&defined(SHADOW_CASCADE))||defined(CALCULATE_SPOTSHADOWS)\r\n\t\t\tv_PositionWorld = positionWS;\r\n\t\t#endif\r\n\t#endif\r\n\r\n\t#if defined(DIFFUSEMAP)||defined(THICKNESSMAP)||((defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT))&&(defined(SPECULARMAP)||defined(NORMALMAP)))\r\n\t\tv_Texcoord0=TransformUV(a_Texcoord0,u_TilingOffset);\r\n\t#endif\r\n\r\n\t#ifdef LIGHTMAP\r\n\t\t#ifdef UV1\r\n\t\t\tv_LightMapUV=vec2(a_Texcoord1.x,1.0-a_Texcoord1.y)*u_LightmapScaleOffset.xy+u_LightmapScaleOffset.zw;\r\n\t\t#else\r\n\t\t\tv_LightMapUV=vec2(a_Texcoord0.x,1.0-a_Texcoord0.y)*u_LightmapScaleOffset.xy+u_LightmapScaleOffset.zw;\r\n\t\t#endif \r\n\t\tv_LightMapUV.y=1.0-v_LightMapUV.y;\r\n\t#endif\r\n\r\n\t#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)\r\n\t\tv_Color=a_Color;\r\n\t#endif\r\n\r\n\t#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)\r\n\t\tv_ShadowCoord =getShadowCoord(vec4(positionWS,1.0));\r\n\t#endif\r\n\r\n\t#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\tv_SpotShadowCoord = u_SpotViewProjectMatrix*vec4(positionWS,1.0);\r\n\t#endif\r\n\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}"; + + var MeshBlinnPhongShadowCasterPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n\r\n#include \"ShadowCasterFS.glsl\"\r\n\r\nvoid main()\r\n{\r\n\tgl_FragColor=shadowCasterFragment();\r\n}"; + + var MeshBlinnPhongShadowCasterVS = "#include \"ShadowCasterVS.glsl\"\r\n\r\nvoid main()\r\n{\r\n\tvec4 positionCS = shadowCasterVertex();\r\n\tgl_Position=remapGLPositionZ(positionCS);\r\n}"; + + var ParticleShuriKenPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n precision highp float;\r\n#else\r\n precision mediump float;\r\n#endif\r\n\r\nvarying vec4 v_Color;\r\nvarying vec2 v_TextureCoordinate;\r\nuniform sampler2D u_texture;\r\nuniform vec4 u_Tintcolor;\r\n\r\n#ifdef RENDERMODE_MESH\r\n\tvarying vec4 v_MeshColor;\r\n#endif\r\n\r\n#ifdef FOG\r\n\tuniform float u_FogStart;\r\n\tuniform float u_FogRange;\r\n\t#ifdef ADDTIVEFOG\r\n\t#else\r\n\t\tuniform vec3 u_FogColor;\r\n\t#endif\r\n#endif\r\n\r\n\r\nvoid main()\r\n{\t\r\n\t#ifdef RENDERMODE_MESH\r\n\t\tgl_FragColor=v_MeshColor;\r\n\t#else\r\n\t\tgl_FragColor=vec4(1.0);\t\r\n\t#endif\r\n\t\t\r\n\t#ifdef DIFFUSEMAP\r\n\t\t#ifdef TINTCOLOR\r\n\t\t\tgl_FragColor*=texture2D(u_texture,v_TextureCoordinate)*u_Tintcolor*2.0*v_Color;\r\n\t\t#else\r\n\t\t\tgl_FragColor*=texture2D(u_texture,v_TextureCoordinate)*v_Color;\r\n\t\t#endif\r\n\t#else\r\n\t\t#ifdef TINTCOLOR\r\n\t\t\tgl_FragColor*=u_Tintcolor*2.0*v_Color;\r\n\t\t#else\r\n\t\t\tgl_FragColor*=v_Color;\r\n\t\t#endif\r\n\t#endif\r\n\t\r\n\t#ifdef FOG\r\n\t\tfloat lerpFact=clamp((1.0/gl_FragCoord.w-u_FogStart)/u_FogRange,0.0,1.0);\r\n\t\t#ifdef ADDTIVEFOG\r\n\t\t\tgl_FragColor.rgb=mix(gl_FragColor.rgb,vec3(0.0,0.0,0.0),lerpFact);\r\n\t\t#else\r\n\t\t\tgl_FragColor.rgb=mix(gl_FragColor.rgb,u_FogColor,lerpFact);\r\n\t\t#endif\r\n\t#endif\r\n}"; + + var ParticleShuriKenVS = "// #include \"Lighting.glsl\";\r\n\r\n//修改这里剔除没有用到的光照函数,增加粒子的编译速度\r\nvec2 TransformUV(vec2 texcoord,vec4 tilingOffset) {\r\n\tvec2 transTexcoord=vec2(texcoord.x,texcoord.y-1.0)*tilingOffset.xy+vec2(tilingOffset.z,-tilingOffset.w);\r\n\ttransTexcoord.y+=1.0;\r\n\treturn transTexcoord;\r\n}\r\n\r\nvec4 remapGLPositionZ(vec4 position) {\r\n\tposition.z=position.z * 2.0 - position.w;\r\n\treturn position;\r\n}\r\n\r\n#if defined(GL_FRAGMENT_PRECISION_HIGH)\r\n precision highp float;\r\n#else\r\n precision mediump float;\r\n#endif\r\n\r\n#if defined(SPHERHBILLBOARD)||defined(STRETCHEDBILLBOARD)||defined(HORIZONTALBILLBOARD)||defined(VERTICALBILLBOARD)\r\n\tattribute vec4 a_CornerTextureCoordinate;\r\n#endif\r\n#ifdef RENDERMODE_MESH\r\n\tattribute vec3 a_MeshPosition;\r\n\tattribute vec4 a_MeshColor;\r\n\tattribute vec2 a_MeshTextureCoordinate;\r\n\tvarying vec4 v_MeshColor;\r\n#endif\r\n\r\nattribute vec4 a_ShapePositionStartLifeTime;\r\nattribute vec4 a_DirectionTime;\r\nattribute vec4 a_StartColor;\r\nattribute vec3 a_StartSize;\r\nattribute vec3 a_StartRotation0;\r\nattribute float a_StartSpeed;\r\n#if defined(COLOROVERLIFETIME)||defined(RANDOMCOLOROVERLIFETIME)||defined(SIZEOVERLIFETIMERANDOMCURVES)||defined(SIZEOVERLIFETIMERANDOMCURVESSEPERATE)||defined(ROTATIONOVERLIFETIMERANDOMCONSTANTS)||defined(ROTATIONOVERLIFETIMERANDOMCURVES)\r\n attribute vec4 a_Random0;\r\n#endif\r\n#if defined(TEXTURESHEETANIMATIONRANDOMCURVE)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\n attribute vec4 a_Random1;\r\n#endif\r\nattribute vec3 a_SimulationWorldPostion;\r\nattribute vec4 a_SimulationWorldRotation;\r\n\r\nvarying vec4 v_Color;\r\n#ifdef DIFFUSEMAP\r\n\tvarying vec2 v_TextureCoordinate;\r\n#endif\r\n\r\nuniform float u_CurrentTime;\r\nuniform vec3 u_Gravity;\r\n\r\nuniform vec3 u_WorldPosition;\r\nuniform vec4 u_WorldRotation;\r\nuniform bool u_ThreeDStartRotation;\r\nuniform int u_ScalingMode;\r\nuniform vec3 u_PositionScale;\r\nuniform vec3 u_SizeScale;\r\nuniform mat4 u_View;\r\nuniform mat4 u_Projection;\r\n\r\n#ifdef STRETCHEDBILLBOARD\r\n\tuniform vec3 u_CameraPos;\r\n#endif\r\nuniform vec3 u_CameraDirection;//TODO:只有几种广告牌模式需要用\r\nuniform vec3 u_CameraUp;\r\n\r\nuniform float u_StretchedBillboardLengthScale;\r\nuniform float u_StretchedBillboardSpeedScale;\r\nuniform int u_SimulationSpace;\r\n\r\n#if defined(VELOCITYOVERLIFETIMECONSTANT)||defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\n uniform int u_VOLSpaceType;\r\n#endif\r\n#if defined(VELOCITYOVERLIFETIMECONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)\r\n uniform vec3 u_VOLVelocityConst;\r\n#endif\r\n#if defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\n uniform vec2 u_VOLVelocityGradientX[4];//x为key,y为速度\r\n uniform vec2 u_VOLVelocityGradientY[4];//x为key,y为速度\r\n uniform vec2 u_VOLVelocityGradientZ[4];//x为key,y为速度\r\n#endif\r\n#ifdef VELOCITYOVERLIFETIMERANDOMCONSTANT\r\n uniform vec3 u_VOLVelocityConstMax;\r\n#endif\r\n#ifdef VELOCITYOVERLIFETIMERANDOMCURVE\r\n uniform vec2 u_VOLVelocityGradientMaxX[4];//x为key,y为速度\r\n uniform vec2 u_VOLVelocityGradientMaxY[4];//x为key,y为速度\r\n uniform vec2 u_VOLVelocityGradientMaxZ[4];//x为key,y为速度\r\n#endif\r\n\r\n#ifdef COLOROVERLIFETIME\r\n uniform vec4 u_ColorOverLifeGradientColors[4];//x为key,yzw为Color\r\n uniform vec2 u_ColorOverLifeGradientAlphas[4];//x为key,y为Alpha\r\n#endif\r\n#ifdef RANDOMCOLOROVERLIFETIME\r\n uniform vec4 u_ColorOverLifeGradientColors[4];//x为key,yzw为Color\r\n uniform vec2 u_ColorOverLifeGradientAlphas[4];//x为key,y为Alpha\r\n uniform vec4 u_MaxColorOverLifeGradientColors[4];//x为key,yzw为Color\r\n uniform vec2 u_MaxColorOverLifeGradientAlphas[4];//x为key,y为Alpha\r\n#endif\r\n\r\n\r\n#if defined(SIZEOVERLIFETIMECURVE)||defined(SIZEOVERLIFETIMERANDOMCURVES)\r\n uniform vec2 u_SOLSizeGradient[4];//x为key,y为尺寸\r\n#endif\r\n#ifdef SIZEOVERLIFETIMERANDOMCURVES\r\n uniform vec2 u_SOLSizeGradientMax[4];//x为key,y为尺寸\r\n#endif\r\n#if defined(SIZEOVERLIFETIMECURVESEPERATE)||defined(SIZEOVERLIFETIMERANDOMCURVESSEPERATE)\r\n uniform vec2 u_SOLSizeGradientX[4];//x为key,y为尺寸\r\n uniform vec2 u_SOLSizeGradientY[4];//x为key,y为尺寸\r\n uniform vec2 u_SOLSizeGradientZ[4];//x为key,y为尺寸\r\n#endif\r\n#ifdef SIZEOVERLIFETIMERANDOMCURVESSEPERATE\r\n uniform vec2 u_SOLSizeGradientMaxX[4];//x为key,y为尺寸\r\n uniform vec2 u_SOLSizeGradientMaxY[4];//x为key,y为尺寸\r\n uniform vec2 u_SOLSizeGradientMaxZ[4];//x为key,y为尺寸\r\n#endif\r\n\r\n\r\n#ifdef ROTATIONOVERLIFETIME\r\n #if defined(ROTATIONOVERLIFETIMECONSTANT)||defined(ROTATIONOVERLIFETIMERANDOMCONSTANTS)\r\n uniform float u_ROLAngularVelocityConst;\r\n #endif\r\n #ifdef ROTATIONOVERLIFETIMERANDOMCONSTANTS\r\n uniform float u_ROLAngularVelocityConstMax;\r\n #endif\r\n #if defined(ROTATIONOVERLIFETIMECURVE)||defined(ROTATIONOVERLIFETIMERANDOMCURVES)\r\n uniform vec2 u_ROLAngularVelocityGradient[4];//x为key,y为旋转\r\n #endif\r\n #ifdef ROTATIONOVERLIFETIMERANDOMCURVES\r\n uniform vec2 u_ROLAngularVelocityGradientMax[4];//x为key,y为旋转\r\n #endif\r\n#endif\r\n#ifdef ROTATIONOVERLIFETIMESEPERATE\r\n #if defined(ROTATIONOVERLIFETIMECONSTANT)||defined(ROTATIONOVERLIFETIMERANDOMCONSTANTS)\r\n uniform vec3 u_ROLAngularVelocityConstSeprarate;\r\n #endif\r\n #ifdef ROTATIONOVERLIFETIMERANDOMCONSTANTS\r\n uniform vec3 u_ROLAngularVelocityConstMaxSeprarate;\r\n #endif\r\n #if defined(ROTATIONOVERLIFETIMECURVE)||defined(ROTATIONOVERLIFETIMERANDOMCURVES)\r\n uniform vec2 u_ROLAngularVelocityGradientX[4];\r\n uniform vec2 u_ROLAngularVelocityGradientY[4];\r\n uniform vec2 u_ROLAngularVelocityGradientZ[4];\r\n #endif\r\n #ifdef ROTATIONOVERLIFETIMERANDOMCURVES\r\n uniform vec2 u_ROLAngularVelocityGradientMaxX[4];\r\n uniform vec2 u_ROLAngularVelocityGradientMaxY[4];\r\n uniform vec2 u_ROLAngularVelocityGradientMaxZ[4];\r\n\tuniform vec2 u_ROLAngularVelocityGradientMaxW[4];\r\n #endif\r\n#endif\r\n\r\n#if defined(TEXTURESHEETANIMATIONCURVE)||defined(TEXTURESHEETANIMATIONRANDOMCURVE)\r\n uniform float u_TSACycles;\r\n uniform vec2 u_TSASubUVLength;\r\n uniform vec2 u_TSAGradientUVs[4];//x为key,y为frame\r\n#endif\r\n#ifdef TEXTURESHEETANIMATIONRANDOMCURVE\r\n uniform vec2 u_TSAMaxGradientUVs[4];//x为key,y为frame\r\n#endif\r\n\r\nuniform vec4 u_TilingOffset;\r\n\r\nvec3 rotationByEuler(in vec3 vector,in vec3 rot)\r\n{\r\n\tfloat halfRoll = rot.z * 0.5;\r\n float halfPitch = rot.x * 0.5;\r\n\tfloat halfYaw = rot.y * 0.5;\r\n\r\n\tfloat sinRoll = sin(halfRoll);\r\n\tfloat cosRoll = cos(halfRoll);\r\n\tfloat sinPitch = sin(halfPitch);\r\n\tfloat cosPitch = cos(halfPitch);\r\n\tfloat sinYaw = sin(halfYaw);\r\n\tfloat cosYaw = cos(halfYaw);\r\n\r\n\tfloat quaX = (cosYaw * sinPitch * cosRoll) + (sinYaw * cosPitch * sinRoll);\r\n\tfloat quaY = (sinYaw * cosPitch * cosRoll) - (cosYaw * sinPitch * sinRoll);\r\n\tfloat quaZ = (cosYaw * cosPitch * sinRoll) - (sinYaw * sinPitch * cosRoll);\r\n\tfloat quaW = (cosYaw * cosPitch * cosRoll) + (sinYaw * sinPitch * sinRoll);\r\n\t\r\n\t//vec4 q=vec4(quaX,quaY,quaZ,quaW);\r\n\t//vec3 temp = cross(q.xyz, vector) + q.w * vector;\r\n\t//return (cross(temp, -q.xyz) + dot(q.xyz,vector) * q.xyz + q.w * temp);\r\n\t\r\n\tfloat x = quaX + quaX;\r\n float y = quaY + quaY;\r\n float z = quaZ + quaZ;\r\n float wx = quaW * x;\r\n float wy = quaW * y;\r\n float wz = quaW * z;\r\n\tfloat xx = quaX * x;\r\n float xy = quaX * y;\r\n\tfloat xz = quaX * z;\r\n float yy = quaY * y;\r\n float yz = quaY * z;\r\n float zz = quaZ * z;\r\n\r\n return vec3(((vector.x * ((1.0 - yy) - zz)) + (vector.y * (xy - wz))) + (vector.z * (xz + wy)),\r\n ((vector.x * (xy + wz)) + (vector.y * ((1.0 - xx) - zz))) + (vector.z * (yz - wx)),\r\n ((vector.x * (xz - wy)) + (vector.y * (yz + wx))) + (vector.z * ((1.0 - xx) - yy)));\r\n\t\r\n}\r\n\r\n//假定axis已经归一化\r\nvec3 rotationByAxis(in vec3 vector,in vec3 axis, in float angle)\r\n{\r\n\tfloat halfAngle = angle * 0.5;\r\n\tfloat sin = sin(halfAngle);\r\n\t\r\n\tfloat quaX = axis.x * sin;\r\n\tfloat quaY = axis.y * sin;\r\n\tfloat quaZ = axis.z * sin;\r\n\tfloat quaW = cos(halfAngle);\r\n\t\r\n\t//vec4 q=vec4(quaX,quaY,quaZ,quaW);\r\n\t//vec3 temp = cross(q.xyz, vector) + q.w * vector;\r\n\t//return (cross(temp, -q.xyz) + dot(q.xyz,vector) * q.xyz + q.w * temp);\r\n\t\r\n\tfloat x = quaX + quaX;\r\n float y = quaY + quaY;\r\n float z = quaZ + quaZ;\r\n float wx = quaW * x;\r\n float wy = quaW * y;\r\n float wz = quaW * z;\r\n\tfloat xx = quaX * x;\r\n float xy = quaX * y;\r\n\tfloat xz = quaX * z;\r\n float yy = quaY * y;\r\n float yz = quaY * z;\r\n float zz = quaZ * z;\r\n\r\n return vec3(((vector.x * ((1.0 - yy) - zz)) + (vector.y * (xy - wz))) + (vector.z * (xz + wy)),\r\n ((vector.x * (xy + wz)) + (vector.y * ((1.0 - xx) - zz))) + (vector.z * (yz - wx)),\r\n ((vector.x * (xz - wy)) + (vector.y * (yz + wx))) + (vector.z * ((1.0 - xx) - yy)));\r\n\t\r\n}\r\n\r\nvec3 rotationByQuaternions(in vec3 v,in vec4 q) \r\n{\r\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\r\n}\r\n\r\n \r\n#if defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)||defined(SIZEOVERLIFETIMECURVE)||defined(SIZEOVERLIFETIMECURVESEPERATE)||defined(SIZEOVERLIFETIMERANDOMCURVES)||defined(SIZEOVERLIFETIMERANDOMCURVESSEPERATE)\r\nfloat getCurValueFromGradientFloat(in vec2 gradientNumbers[4],in float normalizedAge)\r\n{\r\n\tfloat curValue;\r\n\tfor(int i=1;i<4;i++)\r\n\t{\r\n\t\tvec2 gradientNumber=gradientNumbers[i];\r\n\t\tfloat key=gradientNumber.x;\r\n\t\tif(key>=normalizedAge)\r\n\t\t{\r\n\t\t\tvec2 lastGradientNumber=gradientNumbers[i-1];\r\n\t\t\tfloat lastKey=lastGradientNumber.x;\r\n\t\t\tfloat age=(normalizedAge-lastKey)/(key-lastKey);\r\n\t\t\tcurValue=mix(lastGradientNumber.y,gradientNumber.y,age);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\treturn curValue;\r\n}\r\n#endif\r\n\r\n#if defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)||defined(ROTATIONOVERLIFETIMECURVE)||defined(ROTATIONOVERLIFETIMERANDOMCURVES)\r\nfloat getTotalValueFromGradientFloat(in vec2 gradientNumbers[4],in float normalizedAge)\r\n{\r\n\tfloat totalValue=0.0;\r\n\tfor(int i=1;i<4;i++)\r\n\t{\r\n\t\tvec2 gradientNumber=gradientNumbers[i];\r\n\t\tfloat key=gradientNumber.x;\r\n\t\tvec2 lastGradientNumber=gradientNumbers[i-1];\r\n\t\tfloat lastValue=lastGradientNumber.y;\r\n\t\t\r\n\t\tif(key>=normalizedAge){\r\n\t\t\tfloat lastKey=lastGradientNumber.x;\r\n\t\t\tfloat age=(normalizedAge-lastKey)/(key-lastKey);\r\n\t\t\ttotalValue+=(lastValue+mix(lastValue,gradientNumber.y,age))/2.0*a_ShapePositionStartLifeTime.w*(normalizedAge-lastKey);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\telse{\r\n\t\t\ttotalValue+=(lastValue+gradientNumber.y)/2.0*a_ShapePositionStartLifeTime.w*(key-lastGradientNumber.x);\r\n\t\t}\r\n\t}\r\n\treturn totalValue;\r\n}\r\n#endif\r\n\r\n#if defined(COLOROVERLIFETIME)||defined(RANDOMCOLOROVERLIFETIME)\r\nvec4 getColorFromGradient(in vec2 gradientAlphas[4],in vec4 gradientColors[4],in float normalizedAge)\r\n{\r\n\tvec4 overTimeColor;\r\n\tfor(int i=1;i<4;i++)\r\n\t{\r\n\t\tvec2 gradientAlpha=gradientAlphas[i];\r\n\t\tfloat alphaKey=gradientAlpha.x;\r\n\t\tif(alphaKey>=normalizedAge)\r\n\t\t{\r\n\t\t\tvec2 lastGradientAlpha=gradientAlphas[i-1];\r\n\t\t\tfloat lastAlphaKey=lastGradientAlpha.x;\r\n\t\t\tfloat age=(normalizedAge-lastAlphaKey)/(alphaKey-lastAlphaKey);\r\n\t\t\toverTimeColor.a=mix(lastGradientAlpha.y,gradientAlpha.y,age);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\t\r\n\tfor(int i=1;i<4;i++)\r\n\t{\r\n\t\tvec4 gradientColor=gradientColors[i];\r\n\t\tfloat colorKey=gradientColor.x;\r\n\t\tif(colorKey>=normalizedAge)\r\n\t\t{\r\n\t\t\tvec4 lastGradientColor=gradientColors[i-1];\r\n\t\t\tfloat lastColorKey=lastGradientColor.x;\r\n\t\t\tfloat age=(normalizedAge-lastColorKey)/(colorKey-lastColorKey);\r\n\t\t\toverTimeColor.rgb=mix(gradientColors[i-1].yzw,gradientColor.yzw,age);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\treturn overTimeColor;\r\n}\r\n#endif\r\n\r\n\r\n#if defined(TEXTURESHEETANIMATIONCURVE)||defined(TEXTURESHEETANIMATIONRANDOMCURVE)\r\nfloat getFrameFromGradient(in vec2 gradientFrames[4],in float normalizedAge)\r\n{\r\n\tfloat overTimeFrame;\r\n\tfor(int i=1;i<4;i++)\r\n\t{\r\n\t\tvec2 gradientFrame=gradientFrames[i];\r\n\t\tfloat key=gradientFrame.x;\r\n\t\tif(key>=normalizedAge)\r\n\t\t{\r\n\t\t\tvec2 lastGradientFrame=gradientFrames[i-1];\r\n\t\t\tfloat lastKey=lastGradientFrame.x;\r\n\t\t\tfloat age=(normalizedAge-lastKey)/(key-lastKey);\r\n\t\t\toverTimeFrame=mix(lastGradientFrame.y,gradientFrame.y,age);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\treturn floor(overTimeFrame);\r\n}\r\n#endif\r\n\r\n#if defined(VELOCITYOVERLIFETIMECONSTANT)||defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\nvec3 computeParticleLifeVelocity(in float normalizedAge)\r\n{\r\n vec3 outLifeVelocity;\r\n #ifdef VELOCITYOVERLIFETIMECONSTANT\r\n\t outLifeVelocity=u_VOLVelocityConst; \r\n #endif\r\n #ifdef VELOCITYOVERLIFETIMECURVE\r\n outLifeVelocity= vec3(getCurValueFromGradientFloat(u_VOLVelocityGradientX,normalizedAge),getCurValueFromGradientFloat(u_VOLVelocityGradientY,normalizedAge),getCurValueFromGradientFloat(u_VOLVelocityGradientZ,normalizedAge));\r\n #endif\r\n #ifdef VELOCITYOVERLIFETIMERANDOMCONSTANT\r\n\t outLifeVelocity=mix(u_VOLVelocityConst,u_VOLVelocityConstMax,vec3(a_Random1.y,a_Random1.z,a_Random1.w)); \r\n #endif\r\n #ifdef VELOCITYOVERLIFETIMERANDOMCURVE\r\n outLifeVelocity=vec3(mix(getCurValueFromGradientFloat(u_VOLVelocityGradientX,normalizedAge),getCurValueFromGradientFloat(u_VOLVelocityGradientMaxX,normalizedAge),a_Random1.y),\r\n\t mix(getCurValueFromGradientFloat(u_VOLVelocityGradientY,normalizedAge),getCurValueFromGradientFloat(u_VOLVelocityGradientMaxY,normalizedAge),a_Random1.z),\r\n\t\t\t\t\t mix(getCurValueFromGradientFloat(u_VOLVelocityGradientZ,normalizedAge),getCurValueFromGradientFloat(u_VOLVelocityGradientMaxZ,normalizedAge),a_Random1.w));\r\n #endif\r\n\t\t\t\t\t\r\n return outLifeVelocity;\r\n} \r\n#endif\r\n\r\nvec3 computeParticlePosition(in vec3 startVelocity, in vec3 lifeVelocity,in float age,in float normalizedAge,vec3 gravityVelocity,vec4 worldRotation)\r\n{\r\n vec3 startPosition;\r\n vec3 lifePosition;\r\n #if defined(VELOCITYOVERLIFETIMECONSTANT)||defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\n\t#ifdef VELOCITYOVERLIFETIMECONSTANT\r\n\t\t startPosition=startVelocity*age;\r\n\t\t lifePosition=lifeVelocity*age;\r\n\t#endif\r\n\t#ifdef VELOCITYOVERLIFETIMECURVE\r\n\t\t startPosition=startVelocity*age;\r\n\t\t lifePosition=vec3(getTotalValueFromGradientFloat(u_VOLVelocityGradientX,normalizedAge),getTotalValueFromGradientFloat(u_VOLVelocityGradientY,normalizedAge),getTotalValueFromGradientFloat(u_VOLVelocityGradientZ,normalizedAge));\r\n\t#endif\r\n\t#ifdef VELOCITYOVERLIFETIMERANDOMCONSTANT\r\n\t\t startPosition=startVelocity*age;\r\n\t\t lifePosition=lifeVelocity*age;\r\n\t#endif\r\n\t#ifdef VELOCITYOVERLIFETIMERANDOMCURVE\r\n\t\t startPosition=startVelocity*age;\r\n\t\t lifePosition=vec3(mix(getTotalValueFromGradientFloat(u_VOLVelocityGradientX,normalizedAge),getTotalValueFromGradientFloat(u_VOLVelocityGradientMaxX,normalizedAge),a_Random1.y)\r\n\t ,mix(getTotalValueFromGradientFloat(u_VOLVelocityGradientY,normalizedAge),getTotalValueFromGradientFloat(u_VOLVelocityGradientMaxY,normalizedAge),a_Random1.z)\r\n\t ,mix(getTotalValueFromGradientFloat(u_VOLVelocityGradientZ,normalizedAge),getTotalValueFromGradientFloat(u_VOLVelocityGradientMaxZ,normalizedAge),a_Random1.w));\r\n\t#endif\r\n\t\r\n\tvec3 finalPosition;\r\n\tif(u_VOLSpaceType==0){\r\n\t if(u_ScalingMode!=2)\r\n\t finalPosition =rotationByQuaternions(u_PositionScale*(a_ShapePositionStartLifeTime.xyz+startPosition+lifePosition),worldRotation);\r\n\t else\r\n\t finalPosition =rotationByQuaternions(u_PositionScale*a_ShapePositionStartLifeTime.xyz+startPosition+lifePosition,worldRotation);\r\n\t}\r\n\telse{\r\n\t if(u_ScalingMode!=2)\r\n\t finalPosition = rotationByQuaternions(u_PositionScale*(a_ShapePositionStartLifeTime.xyz+startPosition),worldRotation)+lifePosition;\r\n\t else\r\n\t finalPosition = rotationByQuaternions(u_PositionScale*a_ShapePositionStartLifeTime.xyz+startPosition,worldRotation)+lifePosition;\r\n\t}\r\n #else\r\n\t startPosition=startVelocity*age;\r\n\t vec3 finalPosition;\r\n\t if(u_ScalingMode!=2)\r\n\t\t\tfinalPosition = rotationByQuaternions(u_PositionScale*(a_ShapePositionStartLifeTime.xyz+startPosition),worldRotation);\r\n\t else\r\n\t \tfinalPosition = rotationByQuaternions(u_PositionScale*a_ShapePositionStartLifeTime.xyz+startPosition,worldRotation);\r\n #endif\r\n \r\n if(u_SimulationSpace==0)\r\n finalPosition=finalPosition+a_SimulationWorldPostion;\r\n else if(u_SimulationSpace==1) \r\n finalPosition=finalPosition+u_WorldPosition;\r\n \r\n finalPosition+=0.5*gravityVelocity*age;\r\n \r\n return finalPosition;\r\n}\r\n\r\n\r\nvec4 computeParticleColor(in vec4 color,in float normalizedAge)\r\n{\r\n\t#ifdef COLOROVERLIFETIME\r\n\t color*=getColorFromGradient(u_ColorOverLifeGradientAlphas,u_ColorOverLifeGradientColors,normalizedAge);\r\n\t#endif\r\n\t\r\n\t#ifdef RANDOMCOLOROVERLIFETIME\r\n\t color*=mix(getColorFromGradient(u_ColorOverLifeGradientAlphas,u_ColorOverLifeGradientColors,normalizedAge),getColorFromGradient(u_MaxColorOverLifeGradientAlphas,u_MaxColorOverLifeGradientColors,normalizedAge),a_Random0.y);\r\n\t#endif\r\n\r\n return color;\r\n}\r\n\r\nvec2 computeParticleSizeBillbard(in vec2 size,in float normalizedAge)\r\n{\r\n\t#ifdef SIZEOVERLIFETIMECURVE\r\n\t\tsize*=getCurValueFromGradientFloat(u_SOLSizeGradient,normalizedAge);\r\n\t#endif\r\n\t#ifdef SIZEOVERLIFETIMERANDOMCURVES\r\n\t size*=mix(getCurValueFromGradientFloat(u_SOLSizeGradient,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMax,normalizedAge),a_Random0.z); \r\n\t#endif\r\n\t#ifdef SIZEOVERLIFETIMECURVESEPERATE\r\n\t\tsize*=vec2(getCurValueFromGradientFloat(u_SOLSizeGradientX,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientY,normalizedAge));\r\n\t#endif\r\n\t#ifdef SIZEOVERLIFETIMERANDOMCURVESSEPERATE\r\n\t size*=vec2(mix(getCurValueFromGradientFloat(u_SOLSizeGradientX,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMaxX,normalizedAge),a_Random0.z)\r\n\t ,mix(getCurValueFromGradientFloat(u_SOLSizeGradientY,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMaxY,normalizedAge),a_Random0.z));\r\n\t#endif\r\n\treturn size;\r\n}\r\n\r\n#ifdef RENDERMODE_MESH\r\nvec3 computeParticleSizeMesh(in vec3 size,in float normalizedAge)\r\n{\r\n\t#ifdef SIZEOVERLIFETIMECURVE\r\n\t\tsize*=getCurValueFromGradientFloat(u_SOLSizeGradient,normalizedAge);\r\n\t#endif\r\n\t#ifdef SIZEOVERLIFETIMERANDOMCURVES\r\n\t size*=mix(getCurValueFromGradientFloat(u_SOLSizeGradient,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMax,normalizedAge),a_Random0.z); \r\n\t#endif\r\n\t#ifdef SIZEOVERLIFETIMECURVESEPERATE\r\n\t\tsize*=vec3(getCurValueFromGradientFloat(u_SOLSizeGradientX,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientY,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientZ,normalizedAge));\r\n\t#endif\r\n\t#ifdef SIZEOVERLIFETIMERANDOMCURVESSEPERATE\r\n\t size*=vec3(mix(getCurValueFromGradientFloat(u_SOLSizeGradientX,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMaxX,normalizedAge),a_Random0.z)\r\n\t ,mix(getCurValueFromGradientFloat(u_SOLSizeGradientY,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMaxY,normalizedAge),a_Random0.z)\r\n\t\t,mix(getCurValueFromGradientFloat(u_SOLSizeGradientZ,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMaxZ,normalizedAge),a_Random0.z));\r\n\t#endif\r\n\treturn size;\r\n}\r\n#endif\r\n\r\nfloat computeParticleRotationFloat(in float rotation,in float age,in float normalizedAge)\r\n{ \r\n\t#ifdef ROTATIONOVERLIFETIME\r\n\t\t#ifdef ROTATIONOVERLIFETIMECONSTANT\r\n\t\t\tfloat ageRot=u_ROLAngularVelocityConst*age;\r\n\t rotation+=ageRot;\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMECURVE\r\n\t\t\trotation+=getTotalValueFromGradientFloat(u_ROLAngularVelocityGradient,normalizedAge);\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCONSTANTS\r\n\t\t\tfloat ageRot=mix(u_ROLAngularVelocityConst,u_ROLAngularVelocityConstMax,a_Random0.w)*age;\r\n\t rotation+=ageRot;\r\n\t #endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCURVES\r\n\t\t\trotation+=mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradient,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientMax,normalizedAge),a_Random0.w);\r\n\t\t#endif\r\n\t#endif\r\n\t#ifdef ROTATIONOVERLIFETIMESEPERATE\r\n\t\t#ifdef ROTATIONOVERLIFETIMECONSTANT\r\n\t\t\tfloat ageRot=u_ROLAngularVelocityConstSeprarate.z*age;\r\n\t rotation+=ageRot;\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMECURVE\r\n\t\t\trotation+=getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientZ,normalizedAge);\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCONSTANTS\r\n\t\t\tfloat ageRot=mix(u_ROLAngularVelocityConstSeprarate.z,u_ROLAngularVelocityConstMaxSeprarate.z,a_Random0.w)*age;\r\n\t rotation+=ageRot;\r\n\t #endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCURVES\r\n\t\t\trotation+=mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientZ,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientMaxZ,normalizedAge),a_Random0.w));\r\n\t\t#endif\r\n\t#endif\r\n\treturn rotation;\r\n}\r\n\r\n#if defined(RENDERMODE_MESH)&&(defined(ROTATIONOVERLIFETIME)||defined(ROTATIONOVERLIFETIMESEPERATE))\r\nvec3 computeParticleRotationVec3(in vec3 rotation,in float age,in float normalizedAge)\r\n{ \r\n\t#ifdef ROTATIONOVERLIFETIME\r\n\t#ifdef ROTATIONOVERLIFETIMECONSTANT\r\n\t\t\tfloat ageRot=u_ROLAngularVelocityConst*age;\r\n\t rotation+=ageRot;\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMECURVE\r\n\t\t\trotation+=getTotalValueFromGradientFloat(u_ROLAngularVelocityGradient,normalizedAge);\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCONSTANTS\r\n\t\t\tfloat ageRot=mix(u_ROLAngularVelocityConst,u_ROLAngularVelocityConstMax,a_Random0.w)*age;\r\n\t rotation+=ageRot;\r\n\t #endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCURVES\r\n\t\t\trotation+=mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradient,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientMax,normalizedAge),a_Random0.w);\r\n\t\t#endif\r\n\t#endif\r\n\t#ifdef ROTATIONOVERLIFETIMESEPERATE\r\n\t\t#ifdef ROTATIONOVERLIFETIMECONSTANT\r\n\t\t\tvec3 ageRot=u_ROLAngularVelocityConstSeprarate*age;\r\n\t rotation+=ageRot;\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMECURVE\r\n\t\t\trotation+=vec3(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientX,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientY,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientZ,normalizedAge));\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCONSTANTS\r\n\t\t\tvec3 ageRot=mix(u_ROLAngularVelocityConstSeprarate,u_ROLAngularVelocityConstMaxSeprarate,a_Random0.w)*age;\r\n\t rotation+=ageRot;\r\n\t #endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCURVES\r\n\t\t\trotation+=vec3(mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientX,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientMaxX,normalizedAge),a_Random0.w)\r\n\t ,mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientY,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientMaxY,normalizedAge),a_Random0.w)\r\n\t ,mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientZ,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientMaxZ,normalizedAge),a_Random0.w));\r\n\t\t#endif\r\n\t#endif\r\n\treturn rotation;\r\n}\r\n#endif\r\n\r\nvec2 computeParticleUV(in vec2 uv,in float normalizedAge)\r\n{ \r\n\t#ifdef TEXTURESHEETANIMATIONCURVE\r\n\t\tfloat cycleNormalizedAge=normalizedAge*u_TSACycles;\r\n\t\tfloat frame=getFrameFromGradient(u_TSAGradientUVs,cycleNormalizedAge-floor(cycleNormalizedAge));\r\n\t\tfloat totalULength=frame*u_TSASubUVLength.x;\r\n\t\tfloat floorTotalULength=floor(totalULength);\r\n\t uv.x+=totalULength-floorTotalULength;\r\n\t\tuv.y+=floorTotalULength*u_TSASubUVLength.y;\r\n #endif\r\n\t#ifdef TEXTURESHEETANIMATIONRANDOMCURVE\r\n\t\tfloat cycleNormalizedAge=normalizedAge*u_TSACycles;\r\n\t\tfloat uvNormalizedAge=cycleNormalizedAge-floor(cycleNormalizedAge);\r\n\t float frame=floor(mix(getFrameFromGradient(u_TSAGradientUVs,uvNormalizedAge),getFrameFromGradient(u_TSAMaxGradientUVs,uvNormalizedAge),a_Random1.x));\r\n\t\tfloat totalULength=frame*u_TSASubUVLength.x;\r\n\t\tfloat floorTotalULength=floor(totalULength);\r\n\t uv.x+=totalULength-floorTotalULength;\r\n\t\tuv.y+=floorTotalULength*u_TSASubUVLength.y;\r\n #endif\r\n\treturn uv;\r\n}\r\n\r\nvoid main()\r\n{\r\n\tfloat age = u_CurrentTime - a_DirectionTime.w;\r\n\tfloat normalizedAge = age/a_ShapePositionStartLifeTime.w;\r\n\tvec3 lifeVelocity;\r\n\tif(normalizedAge<1.0)\r\n\t{ \r\n\t\tvec3 startVelocity=a_DirectionTime.xyz*a_StartSpeed;\r\n\t\t#if defined(VELOCITYOVERLIFETIMECONSTANT)||defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\n\t\t\tlifeVelocity= computeParticleLifeVelocity(normalizedAge);//计算粒子生命周期速度\r\n\t\t#endif \r\n\t\tvec3 gravityVelocity=u_Gravity*age;\r\n\t\t\r\n\t\tvec4 worldRotation;\r\n\t\tif(u_SimulationSpace==0)\r\n\t\t\tworldRotation=a_SimulationWorldRotation;\r\n\t\telse\r\n\t\t\tworldRotation=u_WorldRotation;\r\n\t\t\r\n\t\tvec3 center=computeParticlePosition(startVelocity, lifeVelocity, age, normalizedAge,gravityVelocity,worldRotation);//计算粒子位置\r\n\t\r\n\t\r\n\t\t#ifdef SPHERHBILLBOARD\r\n\t\t\tvec2 corner=a_CornerTextureCoordinate.xy;//Billboard模式z轴无效\r\n\t\t\tvec3 cameraUpVector =normalize(u_CameraUp);//TODO:是否外面归一化\r\n\t\t\tvec3 sideVector = normalize(cross(u_CameraDirection,cameraUpVector));\r\n\t\t\tvec3 upVector = normalize(cross(sideVector,u_CameraDirection));\r\n\t\t\tcorner*=computeParticleSizeBillbard(a_StartSize.xy,normalizedAge);\r\n\t\t\t#if defined(ROTATIONOVERLIFETIME)||defined(ROTATIONOVERLIFETIMESEPERATE)\r\n\t\t\t\tif(u_ThreeDStartRotation){\r\n\t\t\t\t\tvec3 rotation=vec3(a_StartRotation0.xy,computeParticleRotationFloat(a_StartRotation0.z,age,normalizedAge));\r\n\t\t\t\t\tcenter += u_SizeScale.xzy*rotationByEuler(corner.x*sideVector+corner.y*upVector,rotation);\r\n\t\t\t\t}\r\n\t\t\t\telse{\r\n\t\t\t\t\tfloat rot = computeParticleRotationFloat(a_StartRotation0.x, age,normalizedAge);\r\n\t\t\t\t\tfloat c = cos(rot);\r\n\t\t\t\t\tfloat s = sin(rot);\r\n\t\t\t\t\tmat2 rotation= mat2(c, -s, s, c);\r\n\t\t\t\t\tcorner=rotation*corner;\r\n\t\t\t\t\tcenter += u_SizeScale.xzy*(corner.x*sideVector+corner.y*upVector);\r\n\t\t\t\t}\r\n\t\t\t#else\r\n\t\t\t\tif(u_ThreeDStartRotation){\r\n\t\t\t\t\tcenter += u_SizeScale.xzy*rotationByEuler(corner.x*sideVector+corner.y*upVector,a_StartRotation0);\r\n\t\t\t\t}\r\n\t\t\t\telse{\r\n\t\t\t\t\tfloat c = cos(a_StartRotation0.x);\r\n\t\t\t\t\tfloat s = sin(a_StartRotation0.x);\r\n\t\t\t\t\tmat2 rotation= mat2(c, -s, s, c);\r\n\t\t\t\t\tcorner=rotation*corner;\r\n\t\t\t\t\tcenter += u_SizeScale.xzy*(corner.x*sideVector+corner.y*upVector);\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t#endif\r\n\t\r\n\t\t#ifdef STRETCHEDBILLBOARD\r\n\t\t\tvec2 corner=a_CornerTextureCoordinate.xy;//Billboard模式z轴无效\r\n\t\t\tvec3 velocity;\r\n\t\t\t#if defined(VELOCITYOVERLIFETIMECONSTANT)||defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\n\t\t\t\tif(u_VOLSpaceType==0)\r\n\t\t\t\tvelocity=rotationByQuaternions(u_SizeScale*(startVelocity+lifeVelocity),worldRotation)+gravityVelocity;\r\n\t\t\t\telse\r\n\t\t\t\tvelocity=rotationByQuaternions(u_SizeScale*startVelocity,worldRotation)+lifeVelocity+gravityVelocity;\r\n\t\t\t#else\r\n\t\t\t\tvelocity= rotationByQuaternions(u_SizeScale*startVelocity,worldRotation)+gravityVelocity;\r\n\t\t\t#endif\t\r\n\t\t\tvec3 cameraUpVector = normalize(velocity);\r\n\t\t\tvec3 direction = normalize(center-u_CameraPos);\r\n\t\t\tvec3 sideVector = normalize(cross(direction,normalize(velocity)));\r\n\t\t\t\r\n\t\t\tsideVector=u_SizeScale.xzy*sideVector;\r\n\t\t\tcameraUpVector=length(vec3(u_SizeScale.x,0.0,0.0))*cameraUpVector;\r\n\t\t\t\r\n\t\t\tvec2 size=computeParticleSizeBillbard(a_StartSize.xy,normalizedAge);\r\n\t\t\t\r\n\t\t\tconst mat2 rotaionZHalfPI=mat2(0.0, -1.0, 1.0, 0.0);\r\n\t\t\tcorner=rotaionZHalfPI*corner;\r\n\t\t\tcorner.y=corner.y-abs(corner.y);\r\n\t\t\t\r\n\t\t\tfloat speed=length(velocity);//TODO:\r\n\t\t\tcenter +=sign(u_SizeScale.x)*(sign(u_StretchedBillboardLengthScale)*size.x*corner.x*sideVector+(speed*u_StretchedBillboardSpeedScale+size.y*u_StretchedBillboardLengthScale)*corner.y*cameraUpVector);\r\n\t\t#endif\r\n\t\r\n\t\t#ifdef HORIZONTALBILLBOARD\r\n\t\t\tvec2 corner=a_CornerTextureCoordinate.xy;//Billboard模式z轴无效\r\n\t\t\tconst vec3 cameraUpVector=vec3(0.0,0.0,1.0);\r\n\t\t\tconst vec3 sideVector = vec3(-1.0,0.0,0.0);\r\n\t\t\t\r\n\t\t\tfloat rot = computeParticleRotationFloat(a_StartRotation0.x, age,normalizedAge);\r\n\t\t\tfloat c = cos(rot);\r\n\t\t\tfloat s = sin(rot);\r\n\t\t\tmat2 rotation= mat2(c, -s, s, c);\r\n\t\t\tcorner=rotation*corner*cos(0.78539816339744830961566084581988);//TODO:临时缩小cos45,不确定U3D原因\r\n\t\t\tcorner*=computeParticleSizeBillbard(a_StartSize.xy,normalizedAge);\r\n\t\t\tcenter +=u_SizeScale.xzy*(corner.x*sideVector+ corner.y*cameraUpVector);\r\n\t\t#endif\r\n\t\r\n\t\t#ifdef VERTICALBILLBOARD\r\n\t\t\tvec2 corner=a_CornerTextureCoordinate.xy;//Billboard模式z轴无效\r\n\t\t\tconst vec3 cameraUpVector =vec3(0.0,1.0,0.0);\r\n\t\t\tvec3 sideVector = normalize(cross(u_CameraDirection,cameraUpVector));\r\n\t\t\t\r\n\t\t\tfloat rot = computeParticleRotationFloat(a_StartRotation0.x, age,normalizedAge);\r\n\t\t\tfloat c = cos(rot);\r\n\t\t\tfloat s = sin(rot);\r\n\t\t\tmat2 rotation= mat2(c, -s, s, c);\r\n\t\t\tcorner=rotation*corner*cos(0.78539816339744830961566084581988);//TODO:临时缩小cos45,不确定U3D原因\r\n\t\t\tcorner*=computeParticleSizeBillbard(a_StartSize.xy,normalizedAge);\r\n\t\t\tcenter +=u_SizeScale.xzy*(corner.x*sideVector+ corner.y*cameraUpVector);\r\n\t\t#endif\r\n\t\r\n\t\t#ifdef RENDERMODE_MESH\r\n\t\t\tvec3 size=computeParticleSizeMesh(a_StartSize,normalizedAge);\r\n\t\t\t#if defined(ROTATIONOVERLIFETIME)||defined(ROTATIONOVERLIFETIMESEPERATE)\r\n\t\t\t\tif(u_ThreeDStartRotation){\r\n\t\t\t\t\tvec3 rotation=vec3(a_StartRotation0.xy,computeParticleRotationFloat(a_StartRotation0.z, age,normalizedAge));\r\n\t\t\t\t\tcenter+= rotationByQuaternions(u_SizeScale*rotationByEuler(a_MeshPosition*size,rotation),worldRotation);\r\n\t\t\t\t}\r\n\t\t\t\telse{\r\n\t\t\t\t\t#ifdef ROTATIONOVERLIFETIME\r\n\t\t\t\t\t\tfloat angle=computeParticleRotationFloat(a_StartRotation0.x, age,normalizedAge);\r\n\t\t\t\t\t\tif(a_ShapePositionStartLifeTime.x!=0.0||a_ShapePositionStartLifeTime.y!=0.0){\r\n\t\t\t\t\t\t\tcenter+= (rotationByQuaternions(rotationByAxis(u_SizeScale*a_MeshPosition*size,normalize(cross(vec3(0.0,0.0,1.0),vec3(a_ShapePositionStartLifeTime.xy,0.0))),angle),worldRotation));//已验证\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\telse{\r\n\t\t\t\t\t\t\t#ifdef SHAPE\r\n\t\t\t\t\t\t\t\tcenter+= u_SizeScale.xzy*(rotationByQuaternions(rotationByAxis(a_MeshPosition*size,vec3(0.0,-1.0,0.0),angle),worldRotation));\r\n\t\t\t\t\t\t\t#else\r\n\t\t\t\t\t\t\t\tif(u_SimulationSpace==0)\r\n\t\t\t\t\t\t\t\t\tcenter+=rotationByAxis(u_SizeScale*a_MeshPosition*size,vec3(0.0,0.0,-1.0),angle);//已验证\r\n\t\t\t\t\t\t\t\telse if(u_SimulationSpace==1)\r\n\t\t\t\t\t\t\t\t\tcenter+=rotationByQuaternions(u_SizeScale*rotationByAxis(a_MeshPosition*size,vec3(0.0,0.0,-1.0),angle),worldRotation);//已验证\r\n\t\t\t\t\t\t\t#endif\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t#endif\r\n\t\t\t\t\t#ifdef ROTATIONOVERLIFETIMESEPERATE\r\n\t\t\t\t\t\t//TODO:是否应合并if(u_ThreeDStartRotation)分支代码,待测试\r\n\t\t\t\t\t\tvec3 angle=computeParticleRotationVec3(vec3(0.0,0.0,-a_StartRotation0.x), age,normalizedAge);\r\n\t\t\t\t\t\tcenter+= (rotationByQuaternions(rotationByEuler(u_SizeScale*a_MeshPosition*size,vec3(angle.x,angle.y,angle.z)),worldRotation));//已验证\r\n\t\t\t\t\t#endif\t\t\r\n\t\t\t\t}\r\n\t\t\t#else\r\n\t\t\t\tif(u_ThreeDStartRotation){\r\n\t\t\t\t\tcenter+= rotationByQuaternions(u_SizeScale*rotationByEuler(a_MeshPosition*size,a_StartRotation0),worldRotation);//已验证\r\n\t\t\t\t}\r\n\t\t\t\telse{\r\n\t\t\t\t\tif(a_ShapePositionStartLifeTime.x!=0.0||a_ShapePositionStartLifeTime.y!=0.0){\r\n\t\t\t\t\t\tif(u_SimulationSpace==0)\r\n\t\t\t\t\t\t\tcenter+= rotationByAxis(u_SizeScale*a_MeshPosition*size,normalize(cross(vec3(0.0,0.0,1.0),vec3(a_ShapePositionStartLifeTime.xy,0.0))),a_StartRotation0.x);\r\n\t\t\t\t\t\telse if(u_SimulationSpace==1)\r\n\t\t\t\t\t\t\tcenter+= (rotationByQuaternions(u_SizeScale*rotationByAxis(a_MeshPosition*size,normalize(cross(vec3(0.0,0.0,1.0),vec3(a_ShapePositionStartLifeTime.xy,0.0))),a_StartRotation0.x),worldRotation));//已验证\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse{\r\n\t\t\t\t\t\t#ifdef SHAPE\r\n\t\t\t\t\t\t\tif(u_SimulationSpace==0)\r\n\t\t\t\t\t\t\t\tcenter+= u_SizeScale*rotationByAxis(a_MeshPosition*size,vec3(0.0,-1.0,0.0),a_StartRotation0.x);\r\n\t\t\t\t\t\t\telse if(u_SimulationSpace==1)\r\n\t\t\t\t\t\t\t\tcenter+= rotationByQuaternions(u_SizeScale*rotationByAxis(a_MeshPosition*size,vec3(0.0,-1.0,0.0),a_StartRotation0.x),worldRotation);\t\r\n\t\t\t\t\t\t#else\r\n\t\t\t\t\t\t\tif(u_SimulationSpace==0)\r\n\t\t\t\t\t\t\t\tcenter+= rotationByAxis(u_SizeScale*a_MeshPosition*size,vec3(0.0,0.0,-1.0),a_StartRotation0.x);\r\n\t\t\t\t\t\t\telse if(u_SimulationSpace==1)\r\n\t\t\t\t\t\t\t\tcenter+= rotationByQuaternions(u_SizeScale*rotationByAxis(a_MeshPosition*size,vec3(0.0,0.0,-1.0),a_StartRotation0.x),worldRotation);//已验证\r\n\t\t\t\t\t\t#endif\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t\tv_MeshColor=a_MeshColor;\r\n\t\t#endif\r\n\t\r\n\t\tgl_Position=u_Projection*u_View*vec4(center,1.0);\r\n\t\tv_Color = computeParticleColor(a_StartColor, normalizedAge);\r\n\t\t#ifdef DIFFUSEMAP\r\n\t\t\t#if defined(SPHERHBILLBOARD)||defined(STRETCHEDBILLBOARD)||defined(HORIZONTALBILLBOARD)||defined(VERTICALBILLBOARD)\r\n\t\t\t\tv_TextureCoordinate =computeParticleUV(a_CornerTextureCoordinate.zw, normalizedAge);\r\n\t\t\t#endif\r\n\t\t\t#ifdef RENDERMODE_MESH\r\n\t\t\t\tv_TextureCoordinate =computeParticleUV(a_MeshTextureCoordinate, normalizedAge);\r\n\t\t\t#endif\r\n\t\t\t\r\n\t\t\tv_TextureCoordinate=TransformUV(v_TextureCoordinate,u_TilingOffset);\r\n\t\t#endif\r\n \t}\r\n \telse\r\n\t{\r\n\t\tgl_Position=vec4(2.0,2.0,2.0,1.0);//Discard use out of X(-1,1),Y(-1,1),Z(0,1)\r\n\t}\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}\r\n\r\n"; + + var LayaPBRBRDF = "// allow to explicitly override LAYA_BRDF_GI and LAYA_BRDF_LIGHT in custom shader,default is layaBRDFHighGI and layaBRDFHighLight\r\n#if !defined (LAYA_BRDF_GI) \r\n\t#if defined(LAYA_PBR_BRDF_LOW)\r\n\t\t#define LAYA_BRDF_GI layaBRDFLowGI\r\n\t#elif defined(LAYA_PBR_BRDF_HIGH)\r\n\t\t#define LAYA_BRDF_GI layaBRDFHighGI\r\n\t#endif\r\n#endif\r\n#if !defined (LAYA_BRDF_LIGHT)\r\n\t#if defined(LAYA_PBR_BRDF_LOW)\r\n\t\t#define LAYA_BRDF_LIGHT layaBRDFLowLight\r\n\t#elif defined(LAYA_PBR_BRDF_HIGH)\r\n\t\t#define LAYA_BRDF_LIGHT layaBRDFHighLight\r\n\t#endif\r\n#endif\r\n\r\n#define PI 3.14159265359\r\n#define INV_PI 0.31830988618\r\n\r\nmediump float pow4(mediump float x)\r\n{\r\n\treturn x * x * x * x;\r\n}\r\n\r\nmediump float pow5(mediump float x)\r\n{\r\n\treturn x * x * x * x * x;\r\n}\r\n\r\nmediump vec3 fresnelLerp(mediump vec3 F0,mediump vec3 F90,mediump float cosA)\r\n{\r\n\tfloat t = pow5(1.0 - cosA); // ala Schlick interpoliation\r\n\treturn mix(F0, F90, t);\r\n}\r\n\r\nmediump vec3 fresnelTerm(mediump vec3 F0,mediump float cosA)\r\n{\r\n\tfloat t = pow5(1.0 - cosA); // ala Schlick interpoliation\r\n\treturn F0 + (vec3(1.0) - F0) * t;\r\n}\r\n\r\n// approximage Schlick with ^4 instead of ^5\r\nmediump vec3 fresnelLerpFast (mediump vec3 F0, mediump vec3 F90,mediump float cosA)\r\n{\r\n mediump float t = pow4 (1.0 - cosA);\r\n return mix (F0, F90, t);\r\n}\r\n\r\nfloat smoothnessToPerceptualRoughness(float smoothness)\r\n{\r\n return 1.0 - smoothness;\r\n}\r\n\r\nfloat perceptualRoughnessToRoughness(float perceptualRoughness)\r\n{\r\n return perceptualRoughness * perceptualRoughness;\r\n}\r\n\r\nvec3 safeNormalize(vec3 inVec)\r\n{\r\n\tfloat dp3 = max(0.001,dot(inVec,inVec));\r\n\treturn inVec * inversesqrt(dp3);\r\n}\r\n\r\n// Note: Disney diffuse must be multiply by diffuseAlbedo / PI. This is done outside of this function.\r\nmediump float disneyDiffuse(mediump float NdotV,mediump float NdotL,mediump float LdotH,mediump float perceptualRoughness)\r\n{\r\n\t//https://www.cnblogs.com/herenzhiming/articles/5790389.html\r\n\tmediump float fd90 = 0.5 + 2.0 * LdotH * LdotH * perceptualRoughness;\r\n\t// Two schlick fresnel term\r\n\tmediump float lightScatter = (1.0 + (fd90 - 1.0) * pow5(1.0 - NdotL));\r\n\tmediump float viewScatter = (1.0 + (fd90 - 1.0) * pow5(1.0 - NdotV));\r\n\r\n\treturn lightScatter * viewScatter;\r\n}\r\n\r\n// Ref: http://jcgt.org/published/0003/02/03/paper.pdf\r\nfloat smithJointGGXVisibilityTerm(float NdotL, float NdotV, float roughness)\r\n{\r\n\t// Original formulation:\r\n // lambda_v = (-1 + sqrt(a2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5f;\r\n // lambda_l = (-1 + sqrt(a2 * (1 - NdotV2) / NdotV2 + 1)) * 0.5f;\r\n // G = 1 / (1 + lambda_v + lambda_l);\r\n\r\n\t// scientific code implement:\r\n\t// Reorder code to be more optimal\r\n // half a = roughness;\r\n // half a2 = a * a;\r\n\r\n // half lambdaV = NdotL * sqrt((-NdotV * a2 + NdotV) * NdotV + a2);\r\n // half lambdaL = NdotV * sqrt((-NdotL * a2 + NdotL) * NdotL + a2);\r\n\r\n // Simplify visibility term: (2.0f * NdotL * NdotV) / ((4.0f * NdotL * NdotV) * (lambda_v + lambda_l + 1e-5f));\r\n // return 0.5f / (lambdaV + lambdaL + 1e-5f); \r\n\t// This function is not intended to be running on Mobile,therefore epsilon is smaller than can be represented by half\r\n\r\n\t// Approximation of the above formulation (simplify the sqrt, not mathematically correct but close enough)\r\n\tfloat a = roughness;\r\n\tfloat lambdaV = NdotL * (NdotV * (1.0 - a) + a);\r\n\tfloat lambdaL = NdotV * (NdotL * (1.0 - a) + a);\r\n\treturn 0.5 / (lambdaV + lambdaL + 1e-5);\r\n}\r\n\r\nfloat ggxTerm(float NdotH, float roughness)\r\n{\r\n\tfloat a2 = roughness * roughness;\r\n\tfloat d = (NdotH * a2 - NdotH) * NdotH + 1.0; // 2 mad\r\n\treturn INV_PI * a2 / (d * d + 1e-7); // This function is not intended to be running on Mobile,therefore epsilon is smaller than what can be represented by half//返回值小用half来返回\r\n}\r\n\r\n// BRDF1-------------------------------------------------------------------------------------\r\n\r\n// Note: BRDF entry points use smoothness and oneMinusReflectivity for optimization purposes,\r\n// mostly for DX9 SM2.0 level. Most of the math is being done on these (1-x) values, and that saves a few precious ALU slots.\r\n\r\n// Main Physically Based BRDF\r\n// Derived from Disney work and based on Torrance-Sparrow micro-facet model\r\n//\r\n// BRDF = kD / pi + kS * (D * V * F) / 4\r\n// I = BRDF * NdotL\r\n//\r\n// *NDF GGX:\r\n// *Smith for Visiblity term\r\n// *Schlick approximation for Fresnel\r\nmediump vec4 layaBRDFHighLight(mediump vec3 diffColor, mediump vec3 specColor, mediump float oneMinusReflectivity, float perceptualRoughness,float roughness,mediump float nv,vec3 normal, vec3 viewDir,LayaLight light)\r\n{\r\n\tvec3 halfDir = safeNormalize(viewDir-light.dir);\r\n\r\n\tfloat nl = clamp(dot(normal, -light.dir),0.0,1.0);\r\n\tfloat nh = clamp(dot(normal, halfDir),0.0,1.0);\r\n\tmediump float lv = clamp(dot(light.dir, viewDir),0.0,1.0);\r\n\tmediump float lh = clamp(dot(light.dir, -halfDir),0.0,1.0);\r\n\r\n\t// Diffuse term\r\n\tmediump float diffuseTerm = disneyDiffuse(nv, nl, lh, perceptualRoughness) * nl;\r\n\r\n\t// Specular term\r\n // HACK: theoretically we should divide diffuseTerm by Pi and not multiply specularTerm!\r\n // BUT that will make shader look significantly darker than Legacy ones\r\n\r\n\t// GGX with roughtness to 0 would mean no specular at all, using max(roughness, 0.002) here to match HDrenderloop roughtness remapping.\r\n\troughness = max(roughness, 0.002);\r\n\tfloat V = smithJointGGXVisibilityTerm(nl, nv, roughness);\r\n\tfloat D = ggxTerm(nh, roughness);\r\n\r\n\tfloat specularTerm = V * D * PI; // Torrance-Sparrow model, Fresnel is applied later\r\n\r\n\t//#ifdef LAYA_COLORSPACE_GAMMA\r\n\tspecularTerm = sqrt(max(1e-4, specularTerm));\r\n\t//#endif\r\n\tspecularTerm = max(0.0, specularTerm * nl);\r\n\t\t\r\n\tmediump vec3 color = diffColor * light.color * diffuseTerm + specularTerm * light.color * fresnelTerm(specColor, lh);\r\n\treturn vec4(color, 1.0);\r\n}\r\n\r\nvec4 layaBRDFHighGI(mediump vec3 diffColor,mediump vec3 specColor,mediump float oneMinusReflectivity,float smoothness ,float perceptualRoughness,float roughness,mediump float nv,vec3 normal, vec3 viewDir,LayaGI gi)\r\n{\r\n\t// surfaceReduction = Int D(NdotH) * NdotH * Id(NdotL>0) dH = 1/(roughness^2+1)\r\n\tfloat surfaceReduction;\r\n\tsurfaceReduction = 1.0 - 0.28*roughness*perceptualRoughness;// 1-0.28*x^3 as approximation for (1/(x^4+1))^(1/2.2) on the domain [0;1]\r\n\tfloat grazingTerm = clamp(smoothness + (1.0 - oneMinusReflectivity),0.0,1.0);\r\n\tmediump vec3 color =diffColor * gi.diffuse + surfaceReduction * gi.specular * fresnelLerp(specColor,vec3(grazingTerm), nv);\r\n\treturn vec4(color,1.0);\r\n}\r\n// BRDF1-------------------------------------------------------------------------------------\r\n\r\n\r\n// BRDF2-------------------------------------------------------------------------------------\r\n// Based on Minimalist CookTorrance BRDF\r\n// Implementation is slightly different from original derivation: http://www.thetenthplanet.de/archives/255\r\n//\r\n// *NDF [Modified] GGX:\r\n// *Modified Kelemen and Szirmay-​Kalos for Visibility term\r\n// *Fresnel approximated with 1/LdotH\r\nmediump vec4 layaBRDFLowLight (mediump vec3 diffColor, mediump vec3 specColor,mediump float oneMinusReflectivity,float perceptualRoughness,float roughness,mediump float nv,vec3 normal,vec3 viewDir,LayaLight light)\r\n{\r\n vec3 halfDir = safeNormalize (viewDir-light.dir);\r\n mediump float nl = clamp(dot(normal, -light.dir),0.0,1.0);\r\n float nh = clamp(dot(normal, halfDir),0.0,1.0);\r\n float lh = clamp(dot(-light.dir, halfDir),0.0,1.0);\r\n\r\n // GGX Distribution multiplied by combined approximation of Visibility and Fresnel\r\n // See \"Optimizing PBR for Mobile\" from Siggraph 2015 moving mobile graphics course\r\n // https://community.arm.com/events/1155\r\n mediump float a = roughness;\r\n float a2 = a*a;\r\n\r\n float d = nh * nh * (a2 - 1.0) + 1.00001;\r\n\t// #ifdef LAYA_COLORSPACE_GAMMA\r\n\t\t// Tighter approximation for Gamma only rendering mode!\r\n\t\t// DVF = sqrt(DVF);\r\n\t\t// DVF = (a * sqrt(.25)) / (max(sqrt(0.1), lh)*sqrt(roughness + .5) * d);\r\n\t\tfloat specularTerm = a / (max(0.32, lh) * (1.5 + roughness) * d);\r\n\t// #else\r\n\t// \tfloat specularTerm = a2 / (max(0.1f, lh*lh) * (roughness + 0.5f) * (d * d) * 4);\r\n\t// #endif\r\n\r\n // on mobiles (where half actually means something) denominator have risk of overflow\r\n // clamp below was added specifically to \"fix\" that, but dx compiler (we convert bytecode to metal/gles)\r\n // sees that specularTerm have only non-negative terms, so it skips max(0,..) in clamp (leaving only min(100,...))\r\n\r\n\t//#if defined (SHADER_API_MOBILE)\r\n specularTerm = specularTerm - 1e-4;\r\n\t//#endif\r\n\r\n\t// #else\r\n\t\t// // Legacy\r\n\t\t// half specularPower = PerceptualRoughnessToSpecPower(perceptualRoughness);\r\n\t\t// // Modified with approximate Visibility function that takes roughness into account\r\n\t\t// // Original ((n+1)*N.H^n) / (8*Pi * L.H^3) didn't take into account roughness\r\n\t\t// // and produced extremely bright specular at grazing angles\r\n\r\n\t\t// half invV = lh * lh * smoothness + perceptualRoughness * perceptualRoughness; // approx ModifiedKelemenVisibilityTerm(lh, perceptualRoughness);\r\n\t\t// half invF = lh;\r\n\r\n\t\t// half specularTerm = ((specularPower + 1) * pow (nh, specularPower)) / (8 * invV * invF + 1e-4h);\r\n\r\n\t\t// #ifdef LAYA_COLORSPACE_GAMMA\r\n\t\t// \tspecularTerm = sqrt(max(1e-4f, specularTerm));\r\n\t\t// #endif\r\n\t// #endif\r\n\r\n\t// #if defined (SHADER_API_MOBILE)\r\n\t\tspecularTerm = clamp(specularTerm, 0.0, 100.0); // Prevent FP16 overflow on mobiles\r\n\t// #endif\r\n \r\n mediump vec3 color = (diffColor + specularTerm * specColor) * light.color * nl;\r\n\r\n return vec4(color, 1.0);\r\n}\r\n\r\nmediump vec4 layaBRDFLowGI (mediump vec3 diffColor, mediump vec3 specColor,mediump float oneMinusReflectivity,mediump float smoothness,float perceptualRoughness,float roughness,mediump float nv,vec3 normal,vec3 viewDir,LayaGI gi)\r\n{\r\n\t// surfaceReduction = Int D(NdotH) * NdotH * Id(NdotL>0) dH = 1/(realRoughness^2+1)\r\n\r\n // 1-0.28*x^3 as approximation for (1/(x^4+1))^(1/2.2) on the domain [0;1]\r\n // 1-x^3*(0.6-0.08*x) approximation for 1/(x^4+1)\r\n\t// #ifdef LAYA_COLORSPACE_GAMMA\r\n\t\tmediump float surfaceReduction = 0.28;\r\n\t// #else\r\n\t\t// mediump float surfaceReduction = (0.6-0.08*perceptualRoughness);\r\n\t// #endif\r\n\r\n surfaceReduction = 1.0 - roughness*perceptualRoughness*surfaceReduction;\r\n\r\n\tmediump float grazingTerm = clamp(smoothness + (1.0-oneMinusReflectivity),0.0,1.0);\r\n\tmediump vec3 color =gi.diffuse * diffColor+ surfaceReduction * gi.specular * fresnelLerpFast (specColor, vec3(grazingTerm), nv);\r\n\r\n return vec4(color, 1.0);\r\n}\r\n// BRDF2-------------------------------------------------------------------------------------"; + + var PBRCore = "struct FragmentCommonData{\r\n\tvec3 diffColor;\r\n\tvec3 specColor;\r\n\tfloat oneMinusReflectivity;\r\n\tfloat smoothness;\r\n\t//vec3 eyeVec;TODO:maybe can remove\r\n\t//float alpha;\r\n\t//vec3 reflUVW;\r\n};\r\n\r\n#if !defined(SETUP_BRDF_INPUT)//shader内部的宏需要将改成#ifdef改成#if类型 不然会被Laya的shader分析器优化掉\r\n #define SETUP_BRDF_INPUT metallicSetup//default is metallicSetup,also can be other. \r\n#endif\r\n\r\nconst mediump vec4 dielectricSpecularColor = vec4(0.220916301, 0.220916301, 0.220916301, 1.0 - 0.220916301);\r\n\r\nmediump vec3 diffuseAndSpecularFromMetallic(mediump vec3 albedo,mediump float metallic, out mediump vec3 specColor, out mediump float oneMinusReflectivity)\r\n{\r\n\tspecColor = mix(dielectricSpecularColor.rgb, albedo, metallic);\r\n\toneMinusReflectivity= dielectricSpecularColor.a*(1.0-metallic);//diffuse proportion\r\n\treturn albedo * oneMinusReflectivity;\r\n}\r\n\r\nmediump float specularStrength(mediump vec3 specular)\r\n{\r\n return max (max (specular.r, specular.g), specular.b);\r\n}\r\n\r\n// Diffuse/Spec Energy conservation\r\nmediump vec3 energyConservationBetweenDiffuseAndSpecular (mediump vec3 albedo, mediump vec3 specColor, out mediump float oneMinusReflectivity)\r\n{\r\n\toneMinusReflectivity = 1.0 - specularStrength(specColor);\r\n return albedo * (vec3(1.0) - specColor);\r\n}\r\n\r\n#ifdef TRANSPARENTBLEND\r\n\tmediump vec3 preMultiplyAlpha (mediump vec3 diffColor, mediump float alpha, mediump float oneMinusReflectivity,out mediump float modifiedAlpha)\r\n\t{\r\n\t\t// Transparency 'removes' from Diffuse component\r\n\t\tdiffColor *= alpha;\r\n\t\t// Reflectivity 'removes' from the rest of components, including Transparency\r\n\t\t// modifiedAlpha = 1.0-(1.0-alpha)*(1.0-reflectivity) = 1.0-(oneMinusReflectivity - alpha*oneMinusReflectivity) = 1.0-oneMinusReflectivity + alpha*oneMinusReflectivity\r\n\t\tmodifiedAlpha = 1.0 - oneMinusReflectivity + alpha*oneMinusReflectivity;\r\n\t\treturn diffColor;\r\n\t}\r\n#endif\r\n\r\nFragmentCommonData metallicSetup(vec2 uv)\r\n{\r\n\tmediump vec2 metallicGloss = getMetallicGloss(uv);\r\n\tmediump float metallic = metallicGloss.x;\r\n\tmediump float smoothness = metallicGloss.y; // this is 1 minus the square root of real roughness m.\r\n\tmediump float oneMinusReflectivity;\r\n\tmediump vec3 specColor;\r\n\tmediump vec3 diffColor = diffuseAndSpecularFromMetallic(albedo(uv), metallic,/*out*/specColor,/*out*/oneMinusReflectivity);\r\n\r\n\tFragmentCommonData o;\r\n\to.diffColor = diffColor;\r\n\to.specColor = specColor;\r\n\to.oneMinusReflectivity = oneMinusReflectivity;\r\n\to.smoothness = smoothness;\r\n\treturn o;\r\n}\r\n\r\nFragmentCommonData specularSetup(vec2 uv)\r\n{\r\n mediump vec4 specGloss = specularGloss(uv);\r\n mediump vec3 specColor = specGloss.rgb;\r\n mediump float smoothness = specGloss.a;\r\n\r\n mediump float oneMinusReflectivity;\r\n mediump vec3 diffColor = energyConservationBetweenDiffuseAndSpecular (albedo(uv), specColor, /*out*/ oneMinusReflectivity);\r\n\r\n FragmentCommonData o;\r\n o.diffColor = diffColor;\r\n o.specColor = specColor;\r\n o.oneMinusReflectivity = oneMinusReflectivity;\r\n o.smoothness = smoothness;\r\n return o;\r\n}\r\n\r\nLayaGI fragmentGI(float smoothness,vec3 eyeVec,mediump float occlusion,mediump vec2 lightmapUV,vec3 worldnormal,vec3 worldPos)\r\n{\r\n\tLayaGIInput giInput;\r\n\t#ifdef LIGHTMAP\r\n\t\tgiInput.lightmapUV=lightmapUV;\r\n\t#endif\r\n\tgiInput.worldPos = worldPos;\r\n\r\n\tvec3 worldViewDir = -eyeVec;\r\n\tmediump vec4 uvwRoughness;\r\n\tuvwRoughness.rgb = reflect(worldViewDir, worldnormal);//reflectUVW\r\n\tuvwRoughness.a= smoothnessToPerceptualRoughness(smoothness);//perceptualRoughness\r\n\r\n\treturn layaGlobalIllumination(giInput,occlusion, worldnormal, uvwRoughness);\r\n}\r\n\r\n\r\nvec3 perPixelWorldNormal(vec2 uv,vec3 normal,vec3 binormal,vec3 tangent)\r\n{\r\n\t#ifdef NORMALTEXTURE\r\n\t\tmediump vec3 normalTangent=normalInTangentSpace(uv);\r\n\t\tvec3 normalWorld = normalize(tangent * normalTangent.x + binormal * normalTangent.y + normal * normalTangent.z);\r\n\t#else\r\n\t\tvec3 normalWorld = normalize(normal);\r\n\t#endif\r\n\t\treturn normalWorld;\r\n}\r\n\r\nvoid fragmentForward()\r\n{\r\n\tvec2 uv;\r\n\t#if defined(ALBEDOTEXTURE)||defined(METALLICGLOSSTEXTURE)||defined(NORMALTEXTURE)||defined(EMISSIONTEXTURE)||defined(OCCLUSIONTEXTURE)||defined(PARALLAXTEXTURE)\r\n\t\t#ifdef PARALLAXTEXTURE\r\n\t\t\tuv = parallax(v_Texcoord0,normalize(v_ViewDirForParallax));\r\n\t\t#else\r\n\t\t\tuv = v_Texcoord0;\r\n\t\t#endif\r\n\t#endif\r\n\r\n\tmediump float alpha = getAlpha(uv);\r\n\t#ifdef ALPHATEST\r\n\t\tif(alpha= u_DirationLightCount)\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t#if defined(CALCULATE_SHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\t\t\t\tif(i == 0)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t#ifdef SHADOW_CASCADE\r\n\t\t\t\t\t\t\tvec4 shadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));\r\n\t\t\t\t\t\t#else\r\n\t\t\t\t\t\t\tvec4 shadowCoord = v_ShadowCoord;\r\n\t\t\t\t\t\t#endif\r\n\t\t\t\t\t\tshadowAttenuation *= sampleShadowmap(shadowCoord);\r\n\t\t\t\t\t}\r\n\t\t\t\t#endif\r\n\t\t\t\tDirectionLight directionLight = getDirectionLight(u_LightBuffer,i);\r\n\t\t\t\tLayaLight dirLight = layaDirectionLightToLight(directionLight,shadowAttenuation);\r\n\t\t\t \tcolor+=LAYA_BRDF_LIGHT(o.diffColor,o.specColor,o.oneMinusReflectivity,perceptualRoughness,roughness,nv,normalWorld,eyeVec,dirLight);\r\n\t\t\t}\r\n\t \t#endif\r\n\t\t#if defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\t\tivec4 clusterInfo =getClusterInfo(u_LightClusterBuffer,u_View,u_Viewport, v_PositionWorld,gl_FragCoord,u_ProjectionParams);\r\n\t\t\t#ifdef POINTLIGHT\r\n\t\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t\t{\r\n\t\t\t\t\tshadowAttenuation = 1.0;\r\n\t\t\t\t\tif(i >= clusterInfo.x)//PointLightCount\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tPointLight pointLight = getPointLight(u_LightBuffer,u_LightClusterBuffer,clusterInfo,i);\r\n\t\t\t\t\tLayaLight poiLight = layaPointLightToLight(posworld,normalWorld,pointLight,shadowAttenuation);\r\n\t\t\t\t\tcolor+= LAYA_BRDF_LIGHT(o.diffColor,o.specColor,o.oneMinusReflectivity,perceptualRoughness,roughness,nv,normalWorld,eyeVec,poiLight);\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t\t#ifdef SPOTLIGHT\r\n\t\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t\t{\r\n\t\t\t\t\tshadowAttenuation = 1.0;\r\n\t\t\t\t\tif(i >= clusterInfo.y)//SpotLightCount\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\t\t\t\t\tif(i == 0)\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\tvec4 spotShadowcoord = v_SpotShadowCoord;\r\n\t\t\t\t\t\t\tshadowAttenuation= sampleSpotShadowmap(spotShadowcoord);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t#endif\r\n\t\t\t\t\tSpotLight spotLight = getSpotLight(u_LightBuffer,u_LightClusterBuffer,clusterInfo,i);\r\n\t\t\t\t\tLayaLight spoLight = layaSpotLightToLight(posworld,normalWorld,spotLight,shadowAttenuation);\r\n\t\t\t\t\tcolor+= LAYA_BRDF_LIGHT(o.diffColor,o.specColor,o.oneMinusReflectivity,perceptualRoughness,roughness,nv,normalWorld,eyeVec,spoLight);\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t#endif\r\n\t #endif\r\n\r\n\t#ifdef EMISSION\r\n\t\tcolor.rgb += emission(uv);\r\n\t#endif\r\n\r\n\t#ifdef FOG\r\n\t\tfloat lerpFact=clamp((1.0/gl_FragCoord.w-u_FogStart)/u_FogRange,0.0,1.0);\r\n\t\tcolor.rgb=mix(color.rgb,u_FogColor,lerpFact);\r\n\t#endif\r\n\t\r\n\tgl_FragColor=vec4(color.rgb,alpha);\r\n}\r\n\r\n\r\n\r\n"; + + var PBRVSInput = "attribute vec4 a_Position;\r\n\r\n#ifdef GPU_INSTANCE\r\n\tuniform mat4 u_ViewProjection;\r\n\tattribute mat4 a_WorldMat;\r\n#else\r\n\tuniform mat4 u_MvpMatrix;\r\n\tuniform mat4 u_WorldMat;\r\n#endif\r\n\r\n#ifdef BONE\r\n\tconst int c_MaxBoneCount = 24;\r\n\tattribute vec4 a_BoneIndices;\r\n\tattribute vec4 a_BoneWeights;\r\n\tuniform mat4 u_Bones[c_MaxBoneCount];\r\n#endif\r\n\r\nattribute vec3 a_Normal;\r\nvarying vec3 v_Normal; \r\n\r\n#if defined(NORMALTEXTURE)||defined(PARALLAXTEXTURE)\r\n\tattribute vec4 a_Tangent0;\r\n\tvarying vec3 v_Tangent;\r\n\tvarying vec3 v_Binormal;\r\n #ifdef PARALLAXTEXTURE\r\n\t varying vec3 v_ViewDirForParallax;\r\n #endif\r\n#endif\r\n\r\n#if defined(ALBEDOTEXTURE)||defined(METALLICGLOSSTEXTURE)||defined(NORMALTEXTURE)||defined(EMISSIONTEXTURE)||defined(OCCLUSIONTEXTURE)||defined(PARALLAXTEXTURE)||(defined(LIGHTMAP)&&defined(UV))\r\n\tattribute vec2 a_Texcoord0;\r\n\tvarying vec2 v_Texcoord0;\r\n#endif\r\n\r\n#if defined(LIGHTMAP)&&defined(UV1)\r\n\tattribute vec2 a_Texcoord1;\r\n#endif\r\n\r\n#ifdef LIGHTMAP\r\n\tuniform vec4 u_LightmapScaleOffset;\r\n\tvarying vec2 v_LightMapUV;\r\n#endif\r\n\r\nuniform vec3 u_CameraPos;\r\nvarying vec3 v_EyeVec;\r\nvarying vec3 v_PositionWorld;\r\nvarying float v_posViewZ;\r\n\r\n#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)\r\n\tvarying vec4 v_ShadowCoord;\r\n#endif\r\n\r\n#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\tvarying vec4 v_SpotShadowCoord;\r\n#endif\r\n\r\nuniform vec4 u_TilingOffset;\r\n"; + + var PBRFSInput = "#ifdef ALPHATEST\r\n\tuniform float u_AlphaTestValue;\r\n#endif\r\n\r\nuniform vec4 u_AlbedoColor;\r\n\r\n#ifdef NORMALTEXTURE\r\n\tuniform sampler2D u_NormalTexture;\r\n\tuniform float u_NormalScale;\r\n#endif\r\n\r\n#ifdef ALBEDOTEXTURE\r\n\tuniform sampler2D u_AlbedoTexture;\r\n#endif\r\n\r\n#ifdef METALLICGLOSSTEXTURE\r\n\tuniform sampler2D u_MetallicGlossTexture;\r\n#endif\r\nuniform float u_Metallic;\r\n\r\n#ifdef SPECULARGLOSSTEXTURE\r\n\tuniform sampler2D u_SpecGlossTexture;\r\n#endif\r\nuniform vec3 u_SpecularColor;\r\n\r\nuniform float u_Smoothness;\r\nuniform float u_SmoothnessScale;\r\n\r\n#ifdef PARALLAXTEXTURE\r\n\tuniform sampler2D u_ParallaxTexture;\r\n\tuniform float u_ParallaxScale;\r\n\tvarying vec3 v_ViewDirForParallax;\r\n#endif\r\n\r\n#ifdef OCCLUSIONTEXTURE\r\n\tuniform sampler2D u_OcclusionTexture;\r\n\tuniform float u_occlusionStrength;\r\n#endif\r\n\r\n#ifdef EMISSION \r\n\t#ifdef EMISSIONTEXTURE\r\n\t\tuniform sampler2D u_EmissionTexture;\r\n\t#endif\r\n\tuniform vec4 u_EmissionColor;\r\n#endif\r\n\r\n#if defined(ALBEDOTEXTURE)||defined(METALLICGLOSSTEXTURE)||defined(NORMALTEXTURE)||defined(EMISSIONTEXTURE)||defined(OCCLUSIONTEXTURE)||defined(PARALLAXTEXTURE)\r\n\tvarying vec2 v_Texcoord0;\r\n#endif\r\n\r\n#ifdef LIGHTMAP\r\n\tvarying vec2 v_LightMapUV;\r\n\tuniform sampler2D u_LightMap;\r\n\t#ifdef LIGHTMAP_DIRECTIONAL\r\n\t\tuniform sampler2D u_LightMapDirection;\r\n\t#endif\r\n#endif\r\n\r\nvarying vec3 v_Normal; \r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t#ifdef LEGACYSINGLELIGHTING\r\n\t\t#ifdef DIRECTIONLIGHT\r\n\t\t\tuniform DirectionLight u_DirectionLight;\r\n\t\t#endif\r\n\t\t#ifdef POINTLIGHT\r\n\t\t\tuniform PointLight u_PointLight;\r\n\t\t#endif\r\n\t\t#ifdef SPOTLIGHT\r\n\t\t\tuniform SpotLight u_SpotLight;\r\n\t\t#endif\r\n\t#else\r\n\t\tuniform mat4 u_View;\r\n\t\tuniform vec4 u_ProjectionParams;\r\n\t\tuniform vec4 u_Viewport;\r\n\t\tuniform int u_DirationLightCount;\r\n\t\tuniform sampler2D u_LightBuffer;\r\n\t\tuniform sampler2D u_LightClusterBuffer;\r\n\t#endif\r\n#endif\r\n\r\nvarying vec3 v_EyeVec;\r\n\r\n#ifdef NORMALTEXTURE\r\n\tvarying vec3 v_Tangent;\r\n\tvarying vec3 v_Binormal;\r\n#endif\r\n\r\n#ifdef FOG\r\n\tuniform float u_FogStart;\r\n\tuniform float u_FogRange;\r\n\tuniform vec3 u_FogColor;\r\n#endif\r\n\r\n\r\n//后面考虑宏TODO\r\nvarying vec3 v_PositionWorld;\r\n\r\n#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)\r\n\tvarying vec4 v_ShadowCoord;\r\n#endif\r\n\r\n#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\tvarying vec4 v_SpotShadowCoord;\r\n#endif\r\n\r\nmediump float lerpOneTo(mediump float b, mediump float t)\r\n{\r\n mediump float oneMinusT = 1.0 - t;\r\n return oneMinusT + b * t;\r\n}\r\n\r\n#ifdef EMISSION \r\n\tvec3 emission(vec2 uv)\r\n\t{\r\n\t\t#ifdef EMISSIONTEXTURE\r\n\t\t\treturn texture2D(u_EmissionTexture, uv).rgb * u_EmissionColor.rgb;\r\n\t\t#else\r\n\t\t\treturn u_EmissionColor.rgb;\r\n\t\t#endif\r\n\t}\r\n#endif\r\n\r\nmediump float getAlpha(vec2 uv)\r\n{\r\n\t#ifdef SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA\r\n\t\treturn u_AlbedoColor.a;\r\n\t#else\r\n\t\t#ifdef ALBEDOTEXTURE\r\n\t\t\treturn texture2D(u_AlbedoTexture, uv).a * u_AlbedoColor.a;\r\n\t\t#else\r\n\t\t\treturn u_AlbedoColor.a;\r\n\t\t#endif\r\n\t#endif\r\n}\r\n\r\nmediump float getOcclusion(vec2 uv)\r\n{\r\n\t#ifdef OCCLUSIONTEXTURE\r\n\t\tmediump float occ = texture2D(u_OcclusionTexture, uv).g;\r\n\t\treturn lerpOneTo(occ, u_occlusionStrength);\r\n\t#else\r\n\t\treturn 1.0;\r\n\t#endif\r\n}\r\n\r\nmediump vec3 albedo(vec2 uv)\r\n{\r\n\t#ifdef ALBEDOTEXTURE\r\n\t\treturn u_AlbedoColor.rgb * texture2D(u_AlbedoTexture, uv).rgb;\r\n\t#else\r\n\t\treturn u_AlbedoColor.rgb;\r\n\t#endif\r\n\t//TODO:Detail Texture\r\n}\r\n\r\nmediump vec2 getMetallicGloss(vec2 uv)\r\n{\r\n\tmediump vec2 ms;//x is metallic,y is smoothness\r\n\t#ifdef METALLICGLOSSTEXTURE\r\n\t\t#ifdef SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA\r\n\t\t\tms.x = texture2D(u_MetallicGlossTexture, uv).r;\r\n\t\t\t#ifdef ALBEDOTEXTURE\r\n\t\t\t\tms.y = texture2D(u_AlbedoTexture, uv).a*u_SmoothnessScale;\r\n\t\t\t#else\r\n\t\t\t\tms.y = u_SmoothnessScale;\r\n\t\t\t#endif\r\n\t\t#else\r\n\t\t\tms = texture2D(u_MetallicGlossTexture, uv).ra;\r\n\t\t\tms.y *= u_SmoothnessScale;\r\n\t\t#endif\r\n\t#else\r\n\t\tms.x = u_Metallic;\r\n\t\t#ifdef SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA\r\n\t\t\t#ifdef ALBEDOTEXTURE\r\n\t\t\t\tms.y = texture2D(u_AlbedoTexture, uv).a * u_SmoothnessScale;\r\n\t\t\t#else\r\n\t\t\t\tms.y = u_SmoothnessScale;\r\n\t\t\t#endif\r\n\t\t#else\r\n\t\t\tms.y = u_Smoothness;\r\n\t\t#endif\r\n\t#endif\r\n\treturn ms;\r\n}\r\n\r\nmediump vec4 specularGloss(vec2 uv)\r\n{\r\n\tmediump vec4 sg;\r\n\t#ifdef SPECULARGLOSSTEXTURE\r\n\t\t#ifdef SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA\r\n\t\t\tsg.rgb = texture2D(u_SpecGlossTexture, uv).rgb;\r\n\t\t\t#ifdef ALBEDOTEXTURE\r\n\t\t\t\tsg.a = texture2D(u_AlbedoTexture, uv).a*u_SmoothnessScale;\r\n\t\t\t#else\r\n\t\t\t\tsg.a = u_SmoothnessScale;\r\n\t\t\t#endif\r\n\t\t#else\r\n\t\t\tsg = texture2D(u_SpecGlossTexture, uv);\r\n\t\t\tsg.a *= u_SmoothnessScale;\r\n\t\t#endif\r\n\t#else\r\n\t\tsg.rgb = u_SpecularColor.rgb;\r\n\t\t#ifdef SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA\r\n\t\t\t#ifdef ALBEDOTEXTURE\r\n\t\t\t\tsg.a = texture2D(u_AlbedoTexture, uv).a * u_SmoothnessScale;\r\n\t\t\t#else\r\n\t\t\t\tsg.a = u_SmoothnessScale;\r\n\t\t\t#endif\r\n\t\t#else\r\n\t\t\tsg.a = u_Smoothness;\r\n\t\t#endif\r\n\t#endif\r\n\t\treturn sg;\r\n}\r\n\r\n\r\n#ifdef NORMALTEXTURE\r\n\tmediump vec3 unpackScaleNormal(mediump vec3 packednormal, mediump float bumpScale)\r\n\t{\r\n\t\tmediump vec3 normal = packednormal.xyz * 2.0 - 1.0;\r\n\t\tnormal.y=-normal.y;//NOTE:because unity to LayaAir coordSystem.\r\n\t\tnormal.xy *= bumpScale;\r\n\t\treturn normal;\r\n\t}\r\n\t\r\n\tmediump vec3 normalInTangentSpace(vec2 texcoords)\r\n\t{\r\n\t\tmediump vec3 normalTangent = unpackScaleNormal(texture2D(u_NormalTexture, texcoords).rgb,u_NormalScale);\r\n\t\treturn normalTangent;\r\n\t}\r\n#endif\r\n\r\n#ifdef PARALLAXTEXTURE\r\n\tmediump vec2 parallaxOffset1Step(mediump float h, mediump float height, mediump vec3 viewDir)\r\n\t{\r\n\t\th = h * height - height / 2.0;\r\n\t\tviewDir.z += 0.42;\r\n\t\treturn h * (viewDir.xy / viewDir.z);\r\n\t}\r\n\r\n\tvec2 parallax(vec2 texcoords, mediump vec3 viewDir)\r\n\t{\r\n\t\tmediump float h = texture2D(u_ParallaxTexture, texcoords.xy).g;\r\n\t\tvec2 offset = parallaxOffset1Step(h, u_ParallaxScale, viewDir);\r\n\t\treturn texcoords+offset;\r\n\t}\r\n#endif\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n"; + + var PBRVertex = "vec2 transformLightMapUV(in vec2 texcoord,in vec4 lightmapScaleOffset)\r\n{\r\n\tvec2 lightMapUV=vec2(texcoord.x,1.0-texcoord.y)*lightmapScaleOffset.xy+lightmapScaleOffset.zw;\r\n\tlightMapUV.y=1.0-lightMapUV.y;\r\n\treturn lightMapUV; \r\n}\r\n\r\nvoid vertexForward()\r\n{\r\n\tvec4 position;\r\n\t#ifdef BONE\r\n\t\tmat4 skinTransform;\r\n\t \t#ifdef SIMPLEBONE\r\n\t\t\tfloat currentPixelPos;\r\n\t\t\t#ifdef GPU_INSTANCE\r\n\t\t\t\tcurrentPixelPos = a_SimpleTextureParams.x+a_SimpleTextureParams.y;\r\n\t\t\t#else\r\n\t\t\t\tcurrentPixelPos = u_SimpleAnimatorParams.x+u_SimpleAnimatorParams.y;\r\n\t\t\t#endif\r\n\t\t\tfloat offset = 1.0/u_SimpleAnimatorTextureSize;\r\n\t\t\tskinTransform = loadMatFromTexture(currentPixelPos,int(a_BoneIndices.x),offset) * a_BoneWeights.x;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.y),offset) * a_BoneWeights.y;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.z),offset) * a_BoneWeights.z;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.w),offset) * a_BoneWeights.w;\r\n\t\t#else\r\n\t\t\tskinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;\r\n\t\t#endif\r\n\t\tposition=skinTransform*a_Position;\r\n\t #else\r\n\t\tposition=a_Position;\r\n\t#endif\r\n\r\n\tmat4 worldMat;\r\n\t#ifdef GPU_INSTANCE\r\n\t\tworldMat = a_WorldMat;\r\n\t#else\r\n\t\tworldMat = u_WorldMat;\r\n\t#endif\r\n\r\n\t#ifdef GPU_INSTANCE\r\n\t\tgl_Position = u_ViewProjection * worldMat * position;\r\n\t#else\r\n\t\tgl_Position = u_MvpMatrix * position;\r\n\t#endif\r\n\r\n\t\r\n\r\n\tv_PositionWorld=(worldMat*position).xyz;\r\n\r\n\t#if defined(ALBEDOTEXTURE)||defined(METALLICGLOSSTEXTURE)||defined(NORMALTEXTURE)||defined(EMISSIONTEXTURE)||defined(OCCLUSIONTEXTURE)||defined(PARALLAXTEXTURE)\r\n\t\tv_Texcoord0=TransformUV(a_Texcoord0,u_TilingOffset);\r\n\t#endif\r\n\r\n\tv_EyeVec =u_CameraPos-v_PositionWorld;//will normalize per-pixel\r\n\r\n\t#ifdef LIGHTMAP\r\n\t\tvec2 texcoord;\r\n\t\t#ifdef UV1\r\n\t\t\ttexcoord=a_Texcoord1;\r\n\t\t#else\r\n\t\t\ttexcoord=a_Texcoord0;\r\n\t\t#endif\r\n\t\tv_LightMapUV=transformLightMapUV(texcoord,u_LightmapScaleOffset);\r\n\t#endif\r\n\r\n\tmat3 worldInvMat;\r\n\t#ifdef BONE\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat*skinTransform));\r\n\t#else\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat));\r\n\t#endif\r\n\r\n\tv_Normal=normalize(a_Normal*worldInvMat);//if no normalize will cause precision problem.\r\n\r\n\t#ifdef NORMALTEXTURE\r\n\t\tv_Tangent=normalize(a_Tangent0.xyz*worldInvMat);\r\n\t\tv_Binormal=cross(v_Normal,v_Tangent)*a_Tangent0.w;\r\n\t#endif\r\n\r\n\t#ifdef PARALLAXTEXTURE\r\n\t\tvec3 binormal = cross(a_Normal, a_Tangent0.xyz)*a_Tangent0.w;\r\n\t\tmat3 objectTBN = mat3(a_Tangent0.xyz, binormal, a_Normal);\r\n\t\tv_ViewDirForParallax =(u_CameraPos*worldInvMat-position.xyz)*objectTBN;\r\n\t#endif\r\n\r\n\t#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)\r\n\t\tv_ShadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));\r\n\t#endif\r\n\r\n\t#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\tv_SpotShadowCoord = u_SpotViewProjectMatrix*vec4(v_PositionWorld,1.0);\r\n\t#endif\r\n}"; + + var BloomVS = "#include \"Lighting.glsl\";\r\n#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\nattribute vec4 a_PositionTexcoord;\r\nvarying vec2 v_Texcoord0;\r\n\r\nvoid main() {\r\n\tgl_Position = vec4(a_PositionTexcoord.xy, 0.0, 1.0);\r\n\tv_Texcoord0 = a_PositionTexcoord.zw;\r\n\tgl_Position = remapGLPositionZ(gl_Position);\r\n}"; + + var BloomDownsample13PS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Colors.glsl\";\r\n#include \"Sampling.glsl\";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform vec4 u_MainTex_TexelSize;\r\n\r\nvoid fragDownsample13() {\r\n\tmediump vec4 color = downsampleBox13Tap(u_MainTex, v_Texcoord0, u_MainTex_TexelSize.xy);\r\n\tgl_FragColor = color;\r\n}\r\n\r\nvoid main() {\r\n\tfragDownsample13();\r\n}"; + + var BloomDownsample4PS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Colors.glsl\";\r\n#include \"Sampling.glsl\";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform vec4 u_MainTex_TexelSize;\r\n\r\nvoid fragDownsample4() {\r\n\tmediump vec4 color = downsampleBox4Tap(u_MainTex, v_Texcoord0, u_MainTex_TexelSize.xy);\r\n\tgl_FragColor = color;\r\n}\r\n\r\nvoid main() {\r\n\tfragDownsample4();\r\n}"; + + var BloomPrefilter13PS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Colors.glsl\";\r\n#include \"Sampling.glsl\";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform sampler2D u_AutoExposureTex;\r\nuniform vec4 u_MainTex_TexelSize;\r\nuniform vec4 u_Threshold; // x: threshold value (linear), y: threshold - knee, z: knee * 2, w: 0.25 / knee\r\nuniform vec4 u_Params; // x: clamp, yzw: unused\r\n\r\nmediump vec4 prefilter(mediump vec4 color, vec2 uv) {\r\n\tmediump float autoExposure = texture2D(u_AutoExposureTex, uv).r;\r\n\tcolor *= autoExposure;\r\n\tcolor = min(vec4(u_Params.x), color); // clamp to max\r\n\tcolor = quadraticThreshold(color, u_Threshold.x, u_Threshold.yzw);\r\n\treturn color;\r\n}\r\n\r\nvoid fragPrefilter13() {\r\n\tmediump vec4 color = downsampleBox13Tap(u_MainTex, v_Texcoord0, u_MainTex_TexelSize.xy);\r\n\tgl_FragColor = prefilter(safeHDR(color), v_Texcoord0);\r\n}\r\n\r\nvoid main() {\r\n\tfragPrefilter13();\r\n}"; + + var BloomPrefilter4PS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Colors.glsl\";\r\n#include \"Sampling.glsl\";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform sampler2D u_AutoExposureTex;\r\nuniform vec4 u_MainTex_TexelSize;\r\nuniform vec4 u_Threshold; // x: threshold value (linear), y: threshold - knee, z: knee * 2, w: 0.25 / knee\r\nuniform vec4 u_Params; // x: clamp, yzw: unused\r\n\r\nmediump vec4 prefilter(mediump vec4 color, vec2 uv) {\r\n\tmediump float autoExposure = texture2D(u_AutoExposureTex, uv).r;\r\n\tcolor *= autoExposure;\r\n\tcolor = min(vec4(u_Params.x), color); // clamp to max\r\n\tcolor = quadraticThreshold(color, u_Threshold.x, u_Threshold.yzw);\r\n\treturn color;\r\n}\r\n\r\nvoid fragPrefilter4() {\r\n\tmediump vec4 color = downsampleBox4Tap(u_MainTex, v_Texcoord0, u_MainTex_TexelSize.xy);\r\n\tgl_FragColor = prefilter(safeHDR(color), v_Texcoord0);\r\n}\r\n\r\nvoid main() {\r\n\tfragPrefilter4();\r\n}"; + + var BloomUpsampleBoxPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Colors.glsl\";\r\n#include \"Sampling.glsl\";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform sampler2D u_BloomTex;\r\n\r\nuniform vec4 u_MainTex_TexelSize;\r\nuniform float u_SampleScale;\r\n\r\nmediump vec4 combine(mediump vec4 bloom, vec2 uv) {\r\n\tmediump vec4 color = texture2D(u_BloomTex, uv);\r\n\treturn bloom + color;\r\n}\r\n\r\nvoid fragUpsampleBox() {\r\n\tmediump vec4 bloom = upsampleBox(u_MainTex, v_Texcoord0, u_MainTex_TexelSize.xy, vec4(u_SampleScale));\r\n\tgl_FragColor = combine(bloom, v_Texcoord0);\r\n}\r\n\r\nvoid main() {\r\n\tfragUpsampleBox();\r\n}"; + + var BloomUpsampleTentPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Colors.glsl\";\r\n#include \"Sampling.glsl\";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform sampler2D u_BloomTex;\r\n\r\nuniform vec4 u_MainTex_TexelSize;\r\nuniform float u_SampleScale;\r\n\r\nmediump vec4 combine(mediump vec4 bloom, vec2 uv) {\r\n\tmediump vec4 color = texture2D(u_BloomTex, uv);\r\n\treturn bloom + color;\r\n}\r\n\r\nvoid fragUpsampleTent() {\r\n\tmediump vec4 bloom = upsampleTent(u_MainTex, v_Texcoord0, u_MainTex_TexelSize.xy, vec4(u_SampleScale));\r\n\tgl_FragColor = combine(bloom, v_Texcoord0);\r\n}\r\n\r\nvoid main() {\r\n\tfragUpsampleTent();\r\n}"; + + var ColorsGLSL = "#include \"StdLib.glsl\";\r\n\r\n#define EPSILON 1.0e-4\r\n\r\n// Quadratic color thresholding\r\n// curve = (threshold - knee, knee * 2, 0.25 / knee)\r\nmediump vec4 quadraticThreshold(mediump vec4 color, mediump float threshold, mediump vec3 curve) {\r\n\t// Pixel brightness\r\n\tmediump float br = max3(color.r, color.g, color.b);\r\n\r\n\t// Under-threshold part: quadratic curve\r\n\tmediump float rq = clamp(br - curve.x, 0.0, curve.y);\r\n\trq = curve.z * rq * rq;\r\n\r\n\t// Combine and apply the brightness response curve.\r\n\tcolor *= max(rq, br - threshold) / max(br, EPSILON);\r\n\r\n\treturn color;\r\n}\r\n\r\n\r\n\r\n//\r\n// sRGB transfer functions\r\n// Fast path ref: http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1\r\n//\r\nmediump vec3 sRGBToLinear(mediump vec3 c) {\r\n\t#ifdef USE_VERY_FAST_SRGB\r\n\t\treturn c * c;\r\n\t#elif defined(USE_FAST_SRGB)\r\n\t\treturn c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878);\r\n\t#else\r\n\t\tmediump vec3 linearRGBLo = c / 12.92;\r\n\t\tmediump vec3 power=vec3(2.4, 2.4, 2.4);\r\n\t\tmediump vec3 linearRGBHi = positivePow((c + 0.055) / 1.055, power);\r\n\t\tmediump vec3 linearRGB =vec3((c.r<=0.04045) ? linearRGBLo.r : linearRGBHi.r,(c.g<=0.04045) ? linearRGBLo.g : linearRGBHi.g,(c.b<=0.04045) ? linearRGBLo.b : linearRGBHi.b);\r\n\t\treturn linearRGB;\r\n\t#endif\r\n}\r\n\r\nmediump vec4 sRGBToLinear(mediump vec4 c){\r\n return vec4(sRGBToLinear(c.rgb), c.a);\r\n}\r\n\r\n\r\n\r\nmediump vec3 linearToSRGB(mediump vec3 c) {\r\n\t#ifdef USE_VERY_FAST_SRGB\r\n\t\treturn sqrt(c);\r\n\t#elif defined(USE_FAST_SRGB)\r\n\t\treturn max(1.055 * PositivePow(c, 0.416666667) - 0.055, 0.0);\r\n\t#else\r\n\t\tmediump vec3 sRGBLo = c * 12.92;\r\n\t\tmediump vec3 power=vec3(1.0 / 2.4, 1.0 / 2.4, 1.0 / 2.4);\r\n\t\tmediump vec3 sRGBHi = (positivePow(c, power) * 1.055) - 0.055;\r\n\t\tmediump vec3 sRGB =vec3((c.r<=0.0031308) ? sRGBLo.r : sRGBHi.r,(c.g<=0.0031308) ? sRGBLo.g : sRGBHi.g,(c.b<=0.0031308) ? sRGBLo.b : sRGBHi.b);\r\n\t\treturn sRGB;\r\n\t#endif\r\n}\r\n\r\nmediump vec4 linearToSRGB(mediump vec4 c){\r\n return vec4(linearToSRGB(c.rgb), c.a);\r\n}"; + + var CompositePS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Colors.glsl\";\r\n#include \"Sampling.glsl\";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform sampler2D u_BloomTex;\r\n\r\nuniform sampler2D u_AutoExposureTex;\r\nuniform sampler2D u_Bloom_DirtTex;\r\nuniform vec4 u_BloomTex_TexelSize;\r\nuniform vec4 u_Bloom_DirtTileOffset; // xy: tiling, zw: offset\r\nuniform mediump vec3 u_Bloom_Settings;// x: sampleScale, y: intensity, z: dirt intensity\r\nuniform mediump vec3 u_Bloom_Color;\r\n\r\nvoid main() {\r\n\tmediump float autoExposure = texture2D(u_AutoExposureTex, v_Texcoord0).r;\r\n\tmediump vec4 color=vec4(0.0);\r\n\tcolor = texture2D(u_MainTex, v_Texcoord0);\r\n\t\r\n\tcolor = sRGBToLinear(color);\r\n\tcolor.rgb *= autoExposure;\r\n\t\r\n\t#if defined(BLOOM)||defined(BLOOM_LOW)\r\n\t\t#ifdef BLOOM\r\n\t\t\tmediump vec4 bloom = upsampleTent(u_BloomTex, v_Texcoord0, u_BloomTex_TexelSize.xy, vec4(u_Bloom_Settings.x));\r\n\t\t#else\r\n\t\t\tmediump vec4 bloom = upsampleBox(u_BloomTex, v_Texcoord0, u_BloomTex_TexelSize.xy, vec4(u_Bloom_Settings.x));\r\n\t\t#endif\r\n\r\n\t\t// UVs should be Distort(uv * u_Bloom_DirtTileOffset.xy + u_Bloom_DirtTileOffset.zw)\r\n\t\t// but considering we use a cover-style scale on the dirt texture the difference\r\n\t\t// isn't massive so we chose to save a few ALUs here instead in case lens distortion\r\n\t\t// is active\r\n\t\tmediump vec4 dirt =vec4(texture2D(u_Bloom_DirtTex, v_Texcoord0 * u_Bloom_DirtTileOffset.xy + u_Bloom_DirtTileOffset.zw).rgb, 0.0);\r\n\r\n\t\t// Additive bloom (artist friendly)\r\n\t\tbloom *= u_Bloom_Settings.y;\r\n\t\tdirt *= u_Bloom_Settings.z;\r\n\t\tmediump vec4 bloomColor=vec4(u_Bloom_Color, 1.0);\r\n\t\tcolor += bloom * bloomColor;\r\n\t\tcolor += dirt * bloom;\r\n\t#endif\r\n\t\r\n\tmediump vec4 finalColor = color;\r\n\tfinalColor = linearToSRGB(finalColor);\r\n\t//finalColor.rgb = Dither(finalColor.rgb, v_Texcoord0);//TODO:抖动\r\n\tgl_FragColor = finalColor;\r\n}"; + + var CompositeVS = "#include \"Lighting.glsl\";\r\n\r\nattribute vec4 a_PositionTexcoord;\r\nvarying vec2 v_Texcoord0;\r\n\r\nvoid main() {\r\n\tgl_Position = vec4(a_PositionTexcoord.xy, 0.0, 1.0);\r\n\tv_Texcoord0 = a_PositionTexcoord.zw;\r\n\tgl_Position = remapGLPositionZ(gl_Position);\r\n}"; + + var SamplingGLSL = "// Better, temporally stable box filtering\r\n// [Jimenez14] http://goo.gl/eomGso\r\n// . . . . . . .\r\n// . A . B . C .\r\n// . . D . E . .\r\n// . F . G . H .\r\n// . . I . J . .\r\n// . K . L . M .\r\n// . . . . . . .\r\nmediump vec4 downsampleBox13Tap(sampler2D tex, vec2 uv, vec2 texelSize)\r\n{\r\n mediump vec4 A = texture2D(tex, uv + texelSize * vec2(-1.0, -1.0));\r\n mediump vec4 B = texture2D(tex, uv + texelSize * vec2( 0.0, -1.0));\r\n mediump vec4 C = texture2D(tex, uv + texelSize * vec2( 1.0, -1.0));\r\n mediump vec4 D = texture2D(tex, uv + texelSize * vec2(-0.5, -0.5));\r\n mediump vec4 E = texture2D(tex, uv + texelSize * vec2( 0.5, -0.5));\r\n mediump vec4 F = texture2D(tex, uv + texelSize * vec2(-1.0, 0.0));\r\n mediump vec4 G = texture2D(tex, uv);\r\n mediump vec4 H = texture2D(tex, uv + texelSize * vec2( 1.0, 0.0));\r\n mediump vec4 I = texture2D(tex, uv + texelSize * vec2(-0.5, 0.5));\r\n mediump vec4 J = texture2D(tex, uv + texelSize * vec2( 0.5, 0.5));\r\n mediump vec4 K = texture2D(tex, uv + texelSize * vec2(-1.0, 1.0));\r\n mediump vec4 L = texture2D(tex, uv + texelSize * vec2( 0.0, 1.0));\r\n mediump vec4 M = texture2D(tex, uv + texelSize * vec2( 1.0, 1.0));\r\n\r\n\tmediump vec2 scale= vec2(0.5, 0.125);\r\n mediump vec2 div = (1.0 / 4.0) * scale;\r\n\r\n mediump vec4 o = (D + E + I + J) * div.x;\r\n o += (A + B + G + F) * div.y;\r\n o += (B + C + H + G) * div.y;\r\n o += (F + G + L + K) * div.y;\r\n o += (G + H + M + L) * div.y;\r\n\r\n return o;\r\n}\r\n\r\n// Standard box filtering\r\nmediump vec4 downsampleBox4Tap(sampler2D tex, vec2 uv, vec2 texelSize)\r\n{\r\n vec4 d = texelSize.xyxy * vec4(-1.0, -1.0, 1.0, 1.0);\r\n\r\n mediump vec4 s = texture2D(tex, uv + d.xy);\r\n s += texture2D(tex, uv + d.zy);\r\n s += texture2D(tex, uv + d.xw);\r\n s += texture2D(tex, uv + d.zw);\r\n\r\n return s * (1.0 / 4.0);\r\n}\r\n\r\n// 9-tap bilinear upsampler (tent filter)\r\n// . . . . . . .\r\n// . 1 . 2 . 1 .\r\n// . . . . . . .\r\n// . 2 . 4 . 2 .\r\n// . . . . . . .\r\n// . 1 . 2 . 1 .\r\n// . . . . . . .\r\nmediump vec4 upsampleTent(sampler2D tex, vec2 uv, vec2 texelSize, vec4 sampleScale)\r\n{\r\n vec4 d = texelSize.xyxy * vec4(1.0, 1.0, -1.0, 0.0) * sampleScale;\r\n\r\n mediump vec4 s = texture2D(tex, uv - d.xy);\r\n s += texture2D(tex, uv - d.wy) * 2.0;\r\n s += texture2D(tex, uv - d.zy);\r\n\r\n s += texture2D(tex, uv + d.zw) * 2.0;\r\n s += texture2D(tex, uv) * 4.0;\r\n s += texture2D(tex,\tuv + d.xw) * 2.0;\r\n\r\n s += texture2D(tex, uv + d.zy);\r\n s += texture2D(tex, uv + d.wy) * 2.0;\r\n s += texture2D(tex, uv + d.xy);\r\n\r\n return s * (1.0 / 16.0);\r\n}\r\n\r\n// Standard box filtering\r\nmediump vec4 upsampleBox(sampler2D tex, vec2 uv, vec2 texelSize, vec4 sampleScale)\r\n{\r\n vec4 d = texelSize.xyxy * vec4(-1.0, -1.0, 1.0, 1.0) * 0.5 * sampleScale;\r\n\r\n mediump vec4 s = texture2D(tex, uv + d.xy);\r\n s += texture2D(tex, uv + d.zy);\r\n s += texture2D(tex, uv + d.xw);\r\n s += texture2D(tex, uv + d.zw);\r\n\r\n return s * (1.0 / 4.0);\r\n}"; + + var StdLibGLSL = "#define HALF_MAX 65504.0 // (2 - 2^-10) * 2^15\r\n\r\n#define FLT_EPSILON 1.192092896e-07 // Smallest positive number, such that 1.0 + FLT_EPSILON != 1.0\r\n\r\nmediump vec4 safeHDR(mediump vec4 c)\r\n{\r\n return min(c, HALF_MAX);\r\n}\r\n\r\nfloat max3(float a, float b, float c)\r\n{\r\n return max(max(a, b), c);\r\n}\r\n\r\nvec3 positivePow(vec3 base, vec3 power)\r\n{\r\n return pow(max(abs(base), vec3(FLT_EPSILON, FLT_EPSILON, FLT_EPSILON)), power);\r\n}"; + + var ShadowGLSL = "#ifndef GRAPHICS_API_GLES3\r\n\t#define NO_NATIVE_SHADOWMAP\r\n#endif\r\n\r\n#if defined(NO_NATIVE_SHADOWMAP)\r\n\t#define TEXTURE2D_SHADOW(textureName) uniform mediump sampler2D textureName\r\n\t#define SAMPLE_TEXTURE2D_SHADOW(textureName, coord3) (texture2D(textureName,coord3.xy).r 3)// out of shadow range cascadeIndex is 4.\r\n\t\t\t\treturn vec4(0.0);\r\n\t\t\t\r\n\t\t\t#ifdef GRAPHICS_API_GLES3\r\n\t\t\t\treturn u_ShadowMatrices[cascadeIndex] * positionWS;\r\n\t\t\t#else\r\n\t\t\t\tmat4 shadowMat;\r\n\t\t\t\tif(cascadeIndex == 0)\r\n\t\t\t\t\tshadowMat = u_ShadowMatrices[0];\r\n\t\t\t\telse if(cascadeIndex == 1)\r\n\t\t\t\t\tshadowMat = u_ShadowMatrices[1];\r\n\t\t\t\telse if(cascadeIndex == 2)\r\n\t\t\t\t\tshadowMat = u_ShadowMatrices[2];\r\n\t\t\t\telse\r\n\t\t\t\t\tshadowMat = u_ShadowMatrices[3];\r\n\t\t\t\treturn shadowMat * positionWS;\r\n\t\t\t#endif\r\n\t\t#else\r\n\t\t\treturn u_ShadowMatrices[0] * positionWS;\r\n\t\t#endif\r\n\t}\r\n\r\n\tfloat sampleShadowmap(vec4 shadowCoord)\r\n\t{\r\n\t\tshadowCoord.xyz /= shadowCoord.w;\r\n\t\tfloat attenuation = 1.0;\r\n\t\tif(shadowCoord.z > 0.0 && shadowCoord.z < 1.0)\r\n\t\t{\r\n\t\t\t#if defined(SHADOW_SOFT_SHADOW_HIGH)\r\n\t\t\t\tattenuation = sampleShdowMapFiltered9(u_ShadowMap,shadowCoord.xyz,u_ShadowMapSize);\r\n\t\t\t#elif defined(SHADOW_SOFT_SHADOW_LOW)\r\n\t\t\t\tattenuation = sampleShdowMapFiltered4(u_ShadowMap,shadowCoord.xyz,u_ShadowMapSize);\r\n\t\t\t#else\r\n\t\t\t\tattenuation = SAMPLE_TEXTURE2D_SHADOW(u_ShadowMap,shadowCoord.xyz);\r\n\t\t\t#endif\r\n\t\t\tattenuation = mix(1.0,attenuation,u_ShadowParams.x);//shadowParams.x:shadow strength\r\n\t\t}\r\n\t\treturn attenuation;\r\n\t}\r\n#endif\r\n\r\n#if defined(CALCULATE_SPOTSHADOWS)//shader���Զ���ĺ겻����ifdef ����ij�if defined\r\n\tTEXTURE2D_SHADOW(u_SpotShadowMap);\r\n\tuniform mat4 u_SpotViewProjectMatrix;\r\n\tfloat sampleSpotShadowmap(vec4 shadowCoord)\r\n\t{\r\n\t\tshadowCoord.xyz /= shadowCoord.w;\r\n\t\tfloat attenuation = 1.0;\r\n\t\tshadowCoord.xy +=1.0;\r\n\t\tshadowCoord.xy/=2.0; \r\n\t\tif(shadowCoord.z > 0.0 && shadowCoord.z < 1.0)\r\n\t\t{\r\n\t\t\t#if defined(SHADOW_SPOT_SOFT_SHADOW_HIGH)\r\n\t\t\t\tattenuation = sampleShdowMapFiltered9(u_SpotShadowMap,shadowCoord.xyz,u_SpotShadowMapSize);\r\n\t\t\t#elif defined(SHADOW_SPOT_SOFT_SHADOW_LOW)\r\n\t\t\t\tattenuation = sampleShdowMapFiltered4(u_SpotShadowMap,shadowCoord.xyz,u_SpotShadowMapSize);\r\n\t\t\t#else\r\n\t\t\t\tattenuation = SAMPLE_TEXTURE2D_SHADOW(u_SpotShadowMap,shadowCoord.xyz);\r\n\t\t\t#endif\r\n\t\t\tattenuation = mix(1.0,attenuation,u_ShadowParams.y);//shadowParams.y:shadow strength\r\n\t\t}\r\n\t\treturn attenuation;\r\n\t}\r\n#endif\r\n\r\nvec3 applyShadowBias(vec3 positionWS, vec3 normalWS, vec3 lightDirection)\r\n{\r\n float invNdotL = 1.0 - clamp(dot(-lightDirection, normalWS),0.0,1.0);\r\n float scale = invNdotL * u_ShadowBias.y;\r\n\r\n // normal bias is negative since we want to apply an inset normal offset\r\n positionWS += -lightDirection * u_ShadowBias.xxx;\r\n positionWS += normalWS * vec3(scale);\r\n return positionWS;\r\n}\r\n"; + + var ShadowCasterVSGLSL = "#include \"Lighting.glsl\";\r\n#include \"LayaUtile.glsl\"\r\n#include \"Shadow.glsl\"\r\n\r\nattribute vec4 a_Position;\r\nattribute vec3 a_Normal;\r\n\r\n#ifdef BONE\r\n\tconst int c_MaxBoneCount = 24;\r\n\tattribute vec4 a_BoneIndices;\r\n\tattribute vec4 a_BoneWeights;\r\n\tuniform mat4 u_Bones[c_MaxBoneCount];\r\n#endif\r\n\r\n#ifdef GPU_INSTANCE\r\n\tattribute mat4 a_WorldMat;\r\n#else\r\n\tuniform mat4 u_WorldMat;\r\n#endif\r\n\r\nuniform mat4 u_ViewProjection;\r\n\r\n#ifdef SHADOW\r\n\tuniform vec3 u_ShadowLightDirection;\r\n#endif\r\n\r\n\r\nvec4 shadowCasterVertex()\r\n{\r\n\tmat4 worldMat;\r\n\t#ifdef GPU_INSTANCE\r\n\t\tworldMat = a_WorldMat;\r\n\t#else\r\n\t\tworldMat = u_WorldMat;\r\n\t#endif\r\n\t\r\n\t#ifdef BONE\r\n\t\tmat4 skinTransform;\r\n\t \t#ifdef SIMPLEBONE\r\n\t\t\tfloat currentPixelPos;\r\n\t\t\t#ifdef GPU_INSTANCE\r\n\t\t\t\tcurrentPixelPos = a_SimpleTextureParams.x+a_SimpleTextureParams.y;\r\n\t\t\t#else\r\n\t\t\t\tcurrentPixelPos = u_SimpleAnimatorParams.x+u_SimpleAnimatorParams.y;\r\n\t\t\t#endif\r\n\t\t\tfloat offset = 1.0/u_SimpleAnimatorTextureSize;\r\n\t\t\tskinTransform = loadMatFromTexture(currentPixelPos,int(a_BoneIndices.x),offset) * a_BoneWeights.x;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.y),offset) * a_BoneWeights.y;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.z),offset) * a_BoneWeights.z;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.w),offset) * a_BoneWeights.w;\r\n\t\t#else\r\n\t\t\tskinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;\r\n\t\t#endif\r\n\t\tworldMat = worldMat * skinTransform;\r\n\t#endif\r\n\r\n\tvec4 positionWS = worldMat * a_Position;\r\n\tmat3 worldInvMat;\r\n\t#ifdef BONE\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat*skinTransform));\r\n\t#else\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat));\r\n\t#endif \r\n\r\n\tvec3 normalWS = normalize(a_Normal*worldInvMat);//if no normalize will cause precision problem\r\n\tvec4 positionCS = u_ViewProjection * positionWS;\r\n\t#ifdef SHADOW\r\n\t\tpositionWS.xyz = applyShadowBias(positionWS.xyz,normalWS,u_ShadowLightDirection);\r\n\t\tpositionCS.z = max(positionCS.z, 0.0);//min ndc z is 0.0\r\n\t#endif\r\n\r\n\t\r\n\t#ifdef SHADOW_SPOT\r\n\t\tpositionCS.z = positionCS.z-u_ShadowBias.x/positionCS.w;\r\n\t\tpositionCS.z = max(positionCS.z, 0.0);//min ndc z is 0.0\r\n\t#endif\r\n\t\r\n\t\r\n\t// //TODO没考虑UV动画呢\r\n\t// #if defined(DIFFUSEMAP)&&defined(ALPHATEST)\r\n\t// \tv_Texcoord0=a_Texcoord0;\r\n\t// #endif\r\n return positionCS;\r\n}\r\n"; + + var ShadowCasterFSGLSL = "vec4 shadowCasterFragment()\r\n{\r\n return vec4(0.0);\r\n}\r\n"; + + var SkyBoxPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\nprecision highp float;\r\n#else\r\nprecision mediump float;\r\n#endif\r\n\r\nvarying vec3 v_Texcoord;\r\n\r\nuniform samplerCube u_CubeTexture;\r\nuniform float u_Exposure;\r\nuniform vec4 u_TintColor;\r\n\r\n\r\nvoid main()\r\n{\t\r\n\tvec3 color=textureCube(u_CubeTexture, v_Texcoord).rgb*u_TintColor.rgb*u_Exposure*2.0;\r\n\tgl_FragColor=vec4(color,1.0);\r\n}\r\n\r\n"; + + var SkyBoxVS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\nprecision highp float;\r\n#else\r\nprecision mediump float;\r\n#endif\r\n#include \"Lighting.glsl\";\r\n\r\nattribute vec4 a_Position;\r\nuniform mat4 u_ViewProjection;\r\nuniform float u_Rotation;\r\nvarying vec3 v_Texcoord;\r\n\r\n\r\nvec4 rotateAroundYInDegrees (vec4 vertex, float degrees)\r\n{\r\n\tfloat angle = degrees * 3.141593 / 180.0;\r\n\tfloat sina=sin(angle);\r\n\tfloat cosa=cos(angle);\r\n\tmat2 m = mat2(cosa, -sina, sina, cosa);\r\n\treturn vec4(m*vertex.xz, vertex.yw).xzyw;\r\n}\r\n\t\t\r\nvoid main()\r\n{\r\n\tvec4 position=rotateAroundYInDegrees(a_Position,u_Rotation);\r\n\tgl_Position = u_ViewProjection*position;\r\n\tv_Texcoord=vec3(-a_Position.x,a_Position.yz);//转换坐标系\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}\r\n"; + + var SkyBoxProceduralPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Lighting.glsl\";\r\n\r\nconst float MIE_G = -0.990;\r\nconst float MIE_G2 = 0.9801;\r\nconst float SKY_GROUND_THRESHOLD = 0.02;\r\n\r\nuniform float u_SunSize;\r\nuniform float u_SunSizeConvergence;\r\nuniform DirectionLight u_SunLight;\r\n\r\n\r\nvarying vec3 v_GroundColor;\r\nvarying vec3 v_SkyColor;\r\n\r\n\r\n#ifdef SUN_HIGH_QUALITY\r\n\tvarying vec3 v_Vertex;\r\n#elif defined(SUN_SIMPLE)\r\n\tvarying vec3 v_RayDir;\r\n#else\r\n\tvarying float v_SkyGroundFactor;\r\n#endif\r\n\r\n#if defined(SUN_HIGH_QUALITY)||defined(SUN_SIMPLE)\r\n\tvarying vec3 v_SunColor;\r\n#endif\r\n\r\n// Calculates the Mie phase function\r\nfloat getMiePhase(float eyeCos, float eyeCos2) {\r\n\tfloat temp = 1.0 + MIE_G2 - 2.0 * MIE_G * eyeCos;\r\n\ttemp = pow(temp, pow(u_SunSize,0.65) * 10.0);\r\n\ttemp = max(temp,1.0e-4); // prevent division by zero, esp. in half precision\r\n\ttemp = 1.5 * ((1.0 - MIE_G2) / (2.0 + MIE_G2)) * (1.0 + eyeCos2) / temp;\r\n\treturn temp;\r\n}\r\n\r\n// Calculates the sun shape\r\nfloat calcSunAttenuation(vec3 lightPos, vec3 ray) {\r\n\t#ifdef SUN_HIGH_QUALITY\r\n\t\tfloat focusedEyeCos = pow(clamp(dot(lightPos, ray),0.0,1.0), u_SunSizeConvergence);\r\n\t\treturn getMiePhase(-focusedEyeCos, focusedEyeCos * focusedEyeCos);\r\n\t#else //SUN_SIMPLE\r\n\t\tvec3 delta = lightPos - ray;\r\n\t\tfloat dist = length(delta);\r\n\t\tfloat spot = 1.0 - smoothstep(0.0, u_SunSize, dist);\r\n\t\treturn spot * spot;\r\n\t#endif\r\n}\r\n\r\nvoid main() {\r\n\t// if y > 1 [eyeRay.y < -SKY_GROUND_THRESHOLD] - ground\r\n\t// if y >= 0 and < 1 [eyeRay.y <= 0 and > -SKY_GROUND_THRESHOLD] - horizon\r\n\t// if y < 0 [eyeRay.y > 0] - sky\r\n\tvec3 col = vec3(0.0, 0.0, 0.0);\r\n\r\n\t#ifdef SUN_HIGH_QUALITY\r\n\t\tvec3 ray = normalize(v_Vertex);\r\n\t\tfloat y = ray.y / SKY_GROUND_THRESHOLD;\r\n\t#elif defined(SUN_SIMPLE) \r\n\t\tvec3 ray = v_RayDir;\r\n\t\tfloat y = ray.y / SKY_GROUND_THRESHOLD;\t\r\n\t#else\r\n\t\tfloat y = v_SkyGroundFactor;\r\n\t#endif\r\n\r\n\t// if we did precalculate color in vprog: just do lerp between them\r\n\tcol = mix(v_SkyColor, v_GroundColor, clamp(y,0.0,1.0));\r\n\r\n\t#if defined(SUN_HIGH_QUALITY)||defined(SUN_SIMPLE)\r\n\t\tif (y < 0.0)\r\n\t\t\tcol += v_SunColor * calcSunAttenuation(-u_SunLight.direction, -ray);\r\n\t#endif\r\n\r\n\tcol = sqrt(col);//linear space convert to gamma space\r\n\tgl_FragColor=vec4(col,1.0);\r\n}\r\n\r\n"; + + var SkyBoxProceduralVS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Lighting.glsl\";\r\n\r\n#define OUTER_RADIUS 1.025\r\n#define RAYLEIGH (mix(0.0, 0.0025, pow(u_AtmosphereThickness,2.5)))// Rayleigh constant Rayleigh为夜空光和极光亮度单位\r\n#define MIE 0.0010 // Mie constant 米氏散射\r\n#define SUN_BRIGHTNESS 20.0 // Sun brightness\r\n#define MAX_SCATTER 50.0 // Maximum scattering value, to prevent math overflows on Adrenos\r\n\r\nconst float SKY_GROUND_THRESHOLD = 0.02;\r\nconst float outerRadius = OUTER_RADIUS;\r\nconst float outerRadius2 = OUTER_RADIUS*OUTER_RADIUS;\r\nconst float innerRadius = 1.0;\r\nconst float innerRadius2 = 1.0;\r\nconst float cameraHeight = 0.0001;\r\n\r\nconst float HDSundiskIntensityFactor = 15.0;\r\nconst float simpleSundiskIntensityFactor = 27.0;\r\n\r\nconst float sunScale = 400.0 * SUN_BRIGHTNESS;\r\nconst float kmESun = MIE * SUN_BRIGHTNESS;\r\nconst float km4PI = MIE * 4.0 * 3.14159265;\r\nconst float scale = 1.0 / (OUTER_RADIUS - 1.0);\r\nconst float scaleDepth = 0.25;\r\nconst float scaleOverScaleDepth = (1.0 / (OUTER_RADIUS - 1.0)) / 0.25;\r\nconst float samples = 2.0; // THIS IS UNROLLED MANUALLY, DON'T TOUCH\r\n\r\n// RGB wavelengths .35 (.62=158), .43 (.68=174), .525 (.75=190)\r\nconst vec3 c_DefaultScatteringWavelength = vec3(0.65, 0.57, 0.475);//默认散射波长\r\nconst vec3 c_VariableRangeForScatteringWavelength = vec3(0.15, 0.15, 0.15);//散射播放的可变范围\r\n\r\nattribute vec4 a_Position;\r\n\r\nuniform mat4 u_ViewProjection;\r\nuniform vec3 u_SkyTint;\r\nuniform vec3 u_GroundTint;\r\nuniform float u_Exposure;\r\nuniform float u_AtmosphereThickness;\r\nuniform DirectionLight u_SunLight;\r\n\r\nvarying vec3 v_GroundColor;\r\nvarying vec3 v_SkyColor;\r\n\r\n#ifdef SUN_HIGH_QUALITY\r\n\tvarying vec3 v_Vertex;\r\n#elif defined(SUN_SIMPLE)\r\n\tvarying vec3 v_RayDir;\r\n#else\r\n\tvarying float v_SkyGroundFactor;\r\n#endif\r\n\r\n#if defined(SUN_HIGH_QUALITY)||defined(SUN_SIMPLE)\r\n\tvarying vec3 v_SunColor;\r\n#endif\r\n\r\n// Calculates the Rayleigh phase function\r\nfloat getRayleighPhase(vec3 light, vec3 ray) \r\n{\r\n\tfloat eyeCos = dot(light, ray);\r\n\treturn 0.75 + 0.75*eyeCos*eyeCos;\r\n}\r\n\r\nfloat scaleAngle(float inCos)\r\n{\r\n\tfloat x = 1.0 - inCos;\r\n\treturn 0.25 * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));\r\n}\r\n\r\n\r\nvoid main () {\r\n\tgl_Position = u_ViewProjection*a_Position;\r\n\r\n\tvec3 skyTintInGammaSpace = u_SkyTint;//支持非GAMMA空间后要调整\r\n\tvec3 scatteringWavelength = mix(c_DefaultScatteringWavelength-c_VariableRangeForScatteringWavelength,c_DefaultScatteringWavelength+c_VariableRangeForScatteringWavelength,vec3(1.0) - skyTintInGammaSpace); // using Tint in sRGB+ gamma allows for more visually linear interpolation and to keep (0.5) at (128, gray in sRGB) point\r\n\tvec3 invWavelength = 1.0 / pow(scatteringWavelength, vec3(4.0));\r\n\r\n\tfloat krESun = RAYLEIGH * SUN_BRIGHTNESS;\r\n\tfloat kr4PI = RAYLEIGH * 4.0 * 3.14159265;\r\n\r\n\tvec3 cameraPos = vec3(0.0,innerRadius + cameraHeight,0.0); // The camera's current position\r\n\r\n\t// Get the ray from the camera to the vertex and its length (which is the far point of the ray passing through the atmosphere)\r\n\tvec3 eyeRay = normalize(a_Position.xyz);\r\n\r\n\tfloat far = 0.0;\r\n\tvec3 cIn, cOut;\r\n\tif (eyeRay.y >= 0.0) {// Sky\r\n\t\t// Calculate the length of the \"atmosphere\"\r\n\t\tfar = sqrt(outerRadius2 + innerRadius2 * eyeRay.y * eyeRay.y - innerRadius2) - innerRadius * eyeRay.y;\r\n\r\n\t\t// Calculate the ray's starting position, then calculate its scattering offset\r\n\t\tfloat height = innerRadius + cameraHeight;\r\n\t\tfloat depth = exp(scaleOverScaleDepth * -cameraHeight);\r\n\t\tfloat startAngle = dot(eyeRay, cameraPos) / height;\r\n\t\tfloat startOffset = depth*scaleAngle(startAngle);\r\n\r\n\t\t// Initialize the scattering loop variables\r\n\t\tfloat sampleLength = far / samples;\r\n\t\tfloat scaledLength = sampleLength * scale;\r\n\t\tvec3 sampleRay = eyeRay * sampleLength;\r\n\t\tvec3 samplePoint = cameraPos + sampleRay * 0.5;\r\n\r\n\t\tvec3 frontColor = vec3(0.0);\r\n\t\t//unrolling this manually to avoid some platform for loop slow\r\n\t\t{\r\n\t\t\tfloat height = length(samplePoint);\r\n\t\t\tfloat depth = exp(scaleOverScaleDepth * (innerRadius - height));\r\n\t\t\tfloat lightAngle = dot(-u_SunLight.direction, samplePoint) / height;\r\n\t\t\tfloat cameraAngle = dot(eyeRay, samplePoint) / height;\r\n\t\t\tfloat scatter = (startOffset + depth*(scaleAngle(lightAngle) - scaleAngle(cameraAngle)));\r\n\t\t\tvec3 attenuate = exp(-clamp(scatter, 0.0, MAX_SCATTER) * (invWavelength * kr4PI + km4PI));\r\n\r\n\t\t\tfrontColor += attenuate * (depth * scaledLength);\r\n\t\t\tsamplePoint += sampleRay;\r\n\t\t}\r\n\t\t{\r\n\t\t\tfloat height = length(samplePoint);\r\n\t\t\tfloat depth = exp(scaleOverScaleDepth * (innerRadius - height));\r\n\t\t\tfloat lightAngle = dot(-u_SunLight.direction, samplePoint) / height;\r\n\t\t\tfloat cameraAngle = dot(eyeRay, samplePoint) / height;\r\n\t\t\tfloat scatter = (startOffset + depth*(scaleAngle(lightAngle) - scaleAngle(cameraAngle)));\r\n\t\t\tvec3 attenuate = exp(-clamp(scatter, 0.0, MAX_SCATTER) * (invWavelength * kr4PI + km4PI));\r\n\r\n\t\t\tfrontColor += attenuate * (depth * scaledLength);\r\n\t\t\tsamplePoint += sampleRay;\r\n\t\t}\r\n\r\n\t\t// Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader\r\n\t\tcIn = frontColor * (invWavelength * krESun);\r\n\t\tcOut = frontColor * kmESun;\r\n\t} else {// Ground\r\n\t\tfar = (-cameraHeight) / (min(-0.001, eyeRay.y));\r\n\t\tvec3 pos = cameraPos + far * eyeRay;\r\n\r\n\t\t// Calculate the ray's starting position, then calculate its scattering offset\r\n\t\tfloat depth = exp((-cameraHeight) * (1.0/scaleDepth));\r\n\t\tfloat cameraAngle = dot(-eyeRay, pos);\r\n\t\tfloat lightAngle = dot(-u_SunLight.direction, pos);\r\n\t\tfloat cameraScale = scaleAngle(cameraAngle);\r\n\t\tfloat lightScale = scaleAngle(lightAngle);\r\n\t\tfloat cameraOffset = depth*cameraScale;\r\n\t\tfloat temp = lightScale + cameraScale;\r\n\r\n\t\t// Initialize the scattering loop variables\r\n\t\tfloat sampleLength = far / samples;\r\n\t\tfloat scaledLength = sampleLength * scale;\r\n\t\tvec3 sampleRay = eyeRay * sampleLength;\r\n\t\tvec3 samplePoint = cameraPos + sampleRay * 0.5;\r\n\r\n\t\t// Now loop through the sample rays\r\n\t\tvec3 frontColor = vec3(0.0, 0.0, 0.0);\r\n\t\tvec3 attenuate;\r\n\r\n\t\t// Loop removed because we kept hitting SM2.0 temp variable limits. Doesn't affect the image too much.\r\n\t\t{\r\n\t\t\tfloat height = length(samplePoint);\r\n\t\t\tfloat depth = exp(scaleOverScaleDepth * (innerRadius - height));\r\n\t\t\tfloat scatter = depth*temp - cameraOffset;\r\n\t\t\tattenuate = exp(-clamp(scatter, 0.0, MAX_SCATTER) * (invWavelength * kr4PI + km4PI));\r\n\t\t\tfrontColor += attenuate * (depth * scaledLength);\r\n\t\t\tsamplePoint += sampleRay;\r\n\t\t}\r\n\r\n\t\tcIn = frontColor * (invWavelength * krESun + kmESun);\r\n\t\tcOut = clamp(attenuate, 0.0, 1.0);\r\n\t}\r\n\r\n\t#ifdef SUN_HIGH_QUALITY\r\n\t\tv_Vertex = -a_Position.xyz;\r\n\t#elif defined(SUN_SIMPLE) \r\n\t\tv_RayDir = -eyeRay;\r\n\t#else\r\n\t\tv_SkyGroundFactor = -eyeRay.y / SKY_GROUND_THRESHOLD;\r\n\t#endif\r\n\r\n\t// if we want to calculate color in vprog:\r\n\t// in case of linear: multiply by _Exposure in here (even in case of lerp it will be common multiplier, so we can skip mul in fshader)\r\n\tv_GroundColor = u_Exposure * (cIn + u_GroundTint*u_GroundTint * cOut);//u_GroundColor*u_GroundColor is gamma space convert to linear space\r\n\tv_SkyColor = u_Exposure * (cIn * getRayleighPhase(-u_SunLight.direction, -eyeRay));\r\n\r\n\t\r\n\t// The sun should have a stable intensity in its course in the sky. Moreover it should match the highlight of a purely specular material.\r\n\t// This matching was done using the Unity3D standard shader BRDF1 on the 5/31/2017\r\n\t// Finally we want the sun to be always bright even in LDR thus the normalization of the lightColor for low intensity.\r\n\tfloat lightColorIntensity = clamp(length(u_SunLight.color), 0.25, 1.0);\r\n\r\n\t#ifdef SUN_HIGH_QUALITY \r\n\t\tv_SunColor = HDSundiskIntensityFactor * clamp(cOut,0.0,1.0) * u_SunLight.color / lightColorIntensity;\r\n\t#elif defined(SUN_SIMPLE) \r\n\t\tv_SunColor = simpleSundiskIntensityFactor * clamp(cOut * sunScale,0.0,1.0) * u_SunLight.color / lightColorIntensity;\r\n\t#endif\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}\r\n"; + + var TrailPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\nuniform sampler2D u_MainTexture;\r\nuniform vec4 u_MainColor;\r\n\r\nvarying vec2 v_Texcoord0;\r\nvarying vec4 v_Color;\r\n\r\nvoid main()\r\n{\r\n\tvec4 color = 2.0 * u_MainColor * v_Color;\r\n\t#ifdef MAINTEXTURE\r\n\t\tvec4 mainTextureColor = texture2D(u_MainTexture, v_Texcoord0);\r\n\t\tcolor *= mainTextureColor;\r\n\t#endif\r\n\tgl_FragColor = color;\r\n}\r\n\r\n "; + + var TrailVS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n#include \"Lighting.glsl\";\r\n\r\nattribute vec3 a_Position;\r\nattribute vec3 a_OffsetVector;\r\nattribute vec4 a_Color;\r\nattribute float a_Texcoord0X;\r\nattribute float a_Texcoord0Y;\r\nattribute float a_BirthTime;\r\n\r\nuniform mat4 u_View;\r\nuniform mat4 u_Projection;\r\n\r\nuniform vec4 u_TilingOffset;\r\n\r\nuniform float u_CurTime;\r\nuniform float u_LifeTime;\r\nuniform vec4 u_WidthCurve[10];\r\nuniform int u_WidthCurveKeyLength;\r\n\r\nvarying vec2 v_Texcoord0;\r\nvarying vec4 v_Color;\r\n\r\nfloat hermiteInterpolate(float t, float outTangent, float inTangent, float duration, float value1, float value2)\r\n{\r\n\tfloat t2 = t * t;\r\n\tfloat t3 = t2 * t;\r\n\tfloat a = 2.0 * t3 - 3.0 * t2 + 1.0;\r\n\tfloat b = t3 - 2.0 * t2 + t;\r\n\tfloat c = t3 - t2;\r\n\tfloat d = -2.0 * t3 + 3.0 * t2;\r\n\treturn a * value1 + b * outTangent * duration + c * inTangent * duration + d * value2;\r\n}\r\n\r\nfloat getCurWidth(in float normalizeTime)\r\n{\r\n\tfloat width;\r\n\tif(normalizeTime == 0.0){\r\n\t\twidth=u_WidthCurve[0].w;\r\n\t}\r\n\telse if(normalizeTime >= 1.0){\r\n\t\twidth=u_WidthCurve[u_WidthCurveKeyLength - 1].w;\r\n\t}\r\n\telse{\r\n\t\tfor(int i = 0; i < 10; i ++ )\r\n\t\t{\r\n\t\t\tif(normalizeTime == u_WidthCurve[i].x){\r\n\t\t\t\twidth=u_WidthCurve[i].w;\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tvec4 lastFrame = u_WidthCurve[i];\r\n\t\t\tvec4 nextFrame = u_WidthCurve[i + 1];\r\n\t\t\tif(normalizeTime > lastFrame.x && normalizeTime < nextFrame.x)\r\n\t\t\t{\r\n\t\t\t\tfloat duration = nextFrame.x - lastFrame.x;\r\n\t\t\t\tfloat t = (normalizeTime - lastFrame.x) / duration;\r\n\t\t\t\tfloat outTangent = lastFrame.z;\r\n\t\t\t\tfloat inTangent = nextFrame.y;\r\n\t\t\t\tfloat value1 = lastFrame.w;\r\n\t\t\t\tfloat value2 = nextFrame.w;\r\n\t\t\t\twidth=hermiteInterpolate(t, outTangent, inTangent, duration, value1, value2);\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn width;\r\n}\t\r\n\r\nvoid main()\r\n{\r\n\tfloat normalizeTime = (u_CurTime - a_BirthTime) / u_LifeTime;\r\n\t\r\n\tv_Texcoord0 = vec2(a_Texcoord0X, 1.0 - a_Texcoord0Y) * u_TilingOffset.xy + u_TilingOffset.zw;\r\n\t\r\n\tv_Color = a_Color;\r\n\t\r\n\tvec3 cameraPos = (u_View*vec4(a_Position,1.0)).rgb;\r\n\tgl_Position = u_Projection * vec4(cameraPos+a_OffsetVector * getCurWidth(normalizeTime),1.0);\r\n\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}\r\n"; + + var UnlitPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)\r\n\tvarying vec4 v_Color;\r\n#endif\r\n\r\n#ifdef ALBEDOTEXTURE\r\n\tuniform sampler2D u_AlbedoTexture;\r\n\tvarying vec2 v_Texcoord0;\r\n#endif\r\n\r\nuniform vec4 u_AlbedoColor;\r\n\r\n#ifdef ALPHATEST\r\n\tuniform float u_AlphaTestValue;\r\n#endif\r\n\r\n#ifdef FOG\r\n\tuniform float u_FogStart;\r\n\tuniform float u_FogRange;\r\n\t#ifdef ADDTIVEFOG\r\n\t#else\r\n\t\tuniform vec3 u_FogColor;\r\n\t#endif\r\n#endif\r\n\r\nvoid main()\r\n{\r\n\tvec4 color = u_AlbedoColor;\r\n\t#ifdef ALBEDOTEXTURE\r\n\t\tcolor *= texture2D(u_AlbedoTexture, v_Texcoord0);\r\n\t#endif\r\n\t#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)\r\n\t\tcolor *= v_Color;\r\n\t#endif\r\n\t\r\n\t#ifdef ALPHATEST\r\n\t\tif(color.a < u_AlphaTestValue)\r\n\t\t\tdiscard;\r\n\t#endif\r\n\t\r\n\tgl_FragColor = color;\r\n\t\r\n\t#ifdef FOG\r\n\t\tfloat lerpFact = clamp((1.0 / gl_FragCoord.w - u_FogStart) / u_FogRange, 0.0, 1.0);\r\n\t\t#ifdef ADDTIVEFOG\r\n\t\t\tgl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.0), lerpFact);\r\n\t\t#else\r\n\t\t\tgl_FragColor.rgb = mix(gl_FragColor.rgb, u_FogColor, lerpFact);\r\n\t\t#endif\r\n\t#endif\r\n\t\r\n}\r\n\r\n"; + + var UnlitVS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n#include \"Lighting.glsl\";\r\n#include \"LayaUtile.glsl\";\r\n\r\nattribute vec4 a_Position;\r\n\r\nattribute vec2 a_Texcoord0;\r\n\r\n#ifdef GPU_INSTANCE\r\n\tuniform mat4 u_ViewProjection;\r\n\tattribute mat4 a_WorldMat;\r\n#else\r\n\tuniform mat4 u_MvpMatrix;\r\n#endif\r\n\r\nattribute vec4 a_Color;\r\nvarying vec4 v_Color;\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform vec4 u_TilingOffset;\r\n\r\n#ifdef BONE\r\n\tconst int c_MaxBoneCount = 24;\r\n\tattribute vec4 a_BoneIndices;\r\n\tattribute vec4 a_BoneWeights;\r\n\tuniform mat4 u_Bones[c_MaxBoneCount];\r\n#endif\r\n\r\nvoid main() {\r\n\tvec4 position;\r\n\t#ifdef BONE\r\n\t\tmat4 skinTransform;\r\n\t \t#ifdef SIMPLEBONE\r\n\t\t\tfloat currentPixelPos;\r\n\t\t\t#ifdef GPU_INSTANCE\r\n\t\t\t\tcurrentPixelPos = a_SimpleTextureParams.x+a_SimpleTextureParams.y;\r\n\t\t\t#else\r\n\t\t\t\tcurrentPixelPos = u_SimpleAnimatorParams.x+u_SimpleAnimatorParams.y;\r\n\t\t\t#endif\r\n\t\t\tfloat offset = 1.0/u_SimpleAnimatorTextureSize;\r\n\t\t\tskinTransform = loadMatFromTexture(currentPixelPos,int(a_BoneIndices.x),offset) * a_BoneWeights.x;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.y),offset) * a_BoneWeights.y;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.z),offset) * a_BoneWeights.z;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.w),offset) * a_BoneWeights.w;\r\n\t\t#else\r\n\t\t\tskinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;\r\n\t\t#endif\r\n\t\tposition=skinTransform*a_Position;\r\n\t #else\r\n\t\tposition=a_Position;\r\n\t#endif\r\n\t#ifdef GPU_INSTANCE\r\n\t\tgl_Position =u_ViewProjection * a_WorldMat * position;\r\n\t#else\r\n\t\tgl_Position = u_MvpMatrix * position;\r\n\t#endif\r\n\r\n\tv_Texcoord0=TransformUV(a_Texcoord0,u_TilingOffset);\r\n\r\n\t#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)\r\n\t\tv_Color = a_Color;\r\n\t#endif\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}"; + + var WaterPrimaryPS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#ifdef MAINTEXTURE\r\n\tuniform sampler2D u_MainTexture;\r\n#endif\r\n\r\n#ifdef NORMALTEXTURE\r\n\tuniform sampler2D u_NormalTexture;\r\n#endif\r\n\r\nuniform vec4 u_HorizonColor;\r\n\r\nvarying vec3 v_Normal;\r\nvarying vec3 v_Tangent;\r\nvarying vec3 v_Binormal;\r\nvarying vec3 v_ViewDir;\r\nvarying vec2 v_Texcoord0;\r\nvarying vec2 v_Texcoord1;\r\n\r\n\r\n#include \"Lighting.glsl\"\r\n\r\n\r\n\r\nvec3 NormalSampleToWorldSpace(vec4 normalMapSample) {\r\n\tvec3 normalT;\r\n\tnormalT.x = 2.0 * normalMapSample.x - 1.0;\r\n\tnormalT.y = 1.0 - 2.0 * normalMapSample.y;\r\n\tnormalT.z = sqrt(1.0 - clamp(dot(normalT.xy, normalT.xy), 0.0, 1.0));\r\n\r\n\tvec3 bumpedNormal = normalize(normalT);\r\n\r\n\treturn bumpedNormal;\r\n}\r\n\r\n\r\nvoid main()\r\n{\r\n\tvec4 bumpColor1 = texture2D(u_NormalTexture, v_Texcoord0);\r\n\tvec4 bumpColor2 = texture2D(u_NormalTexture, v_Texcoord1);\r\n\r\n\tvec3 normal1 = NormalSampleToWorldSpace(bumpColor1);\r\n\tvec3 normal2 = NormalSampleToWorldSpace(bumpColor2);\r\n\t\r\n\tvec3 normal = normalize((normal1 + normal2) * 0.5);\r\n\tvec3 viewDir = normalize(v_ViewDir);\r\n\tfloat fresnel = dot(viewDir, normal);\r\n\t\r\n\tvec4 waterColor = texture2D(u_MainTexture, vec2(fresnel, fresnel));\r\n\t\r\n\tvec4 color;\r\n\tcolor.rgb = mix(waterColor.rgb, u_HorizonColor.rgb, vec3(waterColor.a));\r\n\tcolor.a = u_HorizonColor.a;\r\n\t\r\n\tgl_FragColor = color;\r\n}\r\n\r\n\r\n"; + + var WaterPrimaryVS = "#include \"Lighting.glsl\";\r\n\r\nattribute vec4 a_Position;\r\nattribute vec3 a_Normal;\r\nattribute vec4 a_Tangent0;\r\n\r\nuniform mat4 u_MvpMatrix;\r\nuniform mat4 u_WorldMat;\r\nuniform vec3 u_CameraPos;\r\nuniform float u_WaveScale;\r\nuniform vec4 u_WaveSpeed;\r\nuniform float u_Time;\r\n\r\nvarying vec3 v_Normal;\r\nvarying vec3 v_Tangent;\r\nvarying vec3 v_Binormal;\r\nvarying vec3 v_ViewDir;\r\nvarying vec2 v_Texcoord0;\r\nvarying vec2 v_Texcoord1;\r\n\r\nvoid main()\r\n{\r\n\tvec4 positionWorld = u_WorldMat * a_Position;\r\n\tvec4 position = u_MvpMatrix * a_Position;\r\n\t\r\n\tvec4 temp = vec4(positionWorld.x, positionWorld.z, positionWorld.x, positionWorld.z) * u_WaveScale + u_WaveSpeed * u_WaveScale * u_Time;\r\n\t\r\n\tv_Texcoord0 = temp.xy * vec2(0.4, 0.45);\r\n\tv_Texcoord1 = temp.wz;\r\n\t\r\n\tmat3 worldMat = mat3(u_WorldMat);\r\n\tv_Normal = worldMat * a_Normal;\r\n\tv_Tangent = worldMat * a_Tangent0.xyz;\r\n\tv_Binormal = cross(v_Normal, v_Tangent) * a_Tangent0.w;\r\n\t\r\n\tv_ViewDir = u_CameraPos - positionWorld.xyz;\r\n\tgl_Position = position;\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}"; + + var DepthNormalUtil = "#define SAMPLE_DEPTH_TEXTURE(textureName,coord2) (texture2D(textureName,coord2).r)\r\n//此方法库用来压缩解析深度贴图,法线深度贴图\r\n\r\n/*camera 传入的Texture以及*/\r\nuniform sampler2D u_CameraDepthTexture;\r\nuniform vec4 u_ZBufferParams;\r\nuniform sampler2D u_CameraDepthNormalsTexture;\r\n\r\n// Encoding/decoding view space normals into 2D 0..1 vector\r\nvec2 EncodeViewNormalStereo( vec3 n )\r\n{\r\n n.z = abs(n.z);\r\n float kScale = 1.7777;\r\n vec2 enc;\r\n enc = n.xy / (n.z+1.0);\r\n enc /= kScale;\r\n enc = enc*0.5+0.5;\r\n return enc;\r\n}\r\n\r\nvec3 DecodeViewNormalStereo( vec4 enc4 )\r\n{\r\n float kScale = 1.7777;\r\n vec3 nn = enc4.xyz*vec3(2.0*kScale,2.0*kScale,0.0) + vec3(-kScale,-kScale,1.0);\r\n float g = 2.0 / dot(nn.xyz,nn.xyz);\r\n vec3 n;\r\n n.xy = g*nn.xy;\r\n n.z = g-1.0;\r\n return n;\r\n}\r\n\r\n\r\n// Encoding/decoding [0..1) floats into 8 bit/channel RG. Note that 1.0 will not be encoded properly.\r\nvec2 EncodeFloatRG( float v )\r\n{\r\n vec2 kEncodeMul = vec2(1.0, 255.0);\r\n float kEncodeBit = 1.0/255.0;\r\n vec2 enc = kEncodeMul * v;\r\n enc = fract(enc);\r\n enc.x -= enc.y * kEncodeBit;\r\n return enc;\r\n}\r\n\r\n\r\n\r\nfloat DecodeFloatRG( vec2 enc )\r\n{\r\n vec2 kDecodeDot = vec2(1.0, 1.0/255.0);\r\n return dot( enc, kDecodeDot );\r\n}\r\n\r\nvec4 EncodeDepthNormal(float depth,vec3 normals){\r\n\tvec4 encode;\r\n\tencode.xy = EncodeViewNormalStereo(normals);\r\n\tencode.zw = EncodeFloatRG(depth);\r\n return encode;\r\n}\r\n\r\nvoid DecodeDepthNormal( vec4 enc, out float depth, out vec3 normal )\r\n{\r\n depth = DecodeFloatRG (enc.zw);\r\n normal = DecodeViewNormalStereo (enc);\r\n}\r\n\r\n\r\n\r\nvec4 depthNormalsFragment(vec4 depthNormal)\r\n{\r\n return EncodeDepthNormal(depthNormal.w,depthNormal.xyz);\r\n}\r\n\r\n\r\n// Z buffer to linear 0..1 depth\r\nfloat Linear01Depth(float z,vec4 zbufferParams)\r\n{\r\n return 1.0 / (zbufferParams.x * z + zbufferParams.y);\r\n}\r\n// Z buffer to linear depth\r\nfloat LinearEyeDepth(float z,vec4 zbufferParams)\r\n{\r\n return 1.0 / (zbufferParams.z * z + zbufferParams.w);\r\n}\r\n"; + + class ShaderInit3D { + constructor() { + } + static __init__() { + Shader3D.SHADERDEFINE_LEGACYSINGALLIGHTING = Shader3D.getDefineByName("LEGACYSINGLELIGHTING"); + Shader3D.SHADERDEFINE_GRAPHICS_API_GLES2 = Shader3D.getDefineByName("GRAPHICS_API_GLES2"); + Shader3D.SHADERDEFINE_GRAPHICS_API_GLES3 = Shader3D.getDefineByName("GRAPHICS_API_GLES3"); + Shader3D.addInclude("Lighting.glsl", LightingGLSL); + Shader3D.addInclude("ShadowSampleTent.glsl", ShadowSampleTentGLSL); + Shader3D.addInclude("GlobalIllumination.glsl", GlobalIllumination); + Shader3D.addInclude("Shadow.glsl", ShadowGLSL); + Shader3D.addInclude("ShadowCasterVS.glsl", ShadowCasterVSGLSL); + Shader3D.addInclude("ShadowCasterFS.glsl", ShadowCasterFSGLSL); + Shader3D.addInclude("Colors.glsl", ColorsGLSL); + Shader3D.addInclude("Sampling.glsl", SamplingGLSL); + Shader3D.addInclude("StdLib.glsl", StdLibGLSL); + Shader3D.addInclude("PBRVSInput.glsl", PBRVSInput); + Shader3D.addInclude("PBRFSInput.glsl", PBRFSInput); + Shader3D.addInclude("LayaPBRBRDF.glsl", LayaPBRBRDF); + Shader3D.addInclude("PBRCore.glsl", PBRCore); + Shader3D.addInclude("PBRVertex.glsl", PBRVertex); + Shader3D.addInclude("LayaUtile.glsl", LayaUtile); + Shader3D.addInclude("DepthNormalUtil.glsl", DepthNormalUtil); + var attributeMap = { + 'a_Position': VertexMesh.MESH_POSITION0, + 'a_Color': VertexMesh.MESH_COLOR0, + 'a_Normal': VertexMesh.MESH_NORMAL0, + 'a_Texcoord0': VertexMesh.MESH_TEXTURECOORDINATE0, + 'a_Texcoord1': VertexMesh.MESH_TEXTURECOORDINATE1, + 'a_BoneWeights': VertexMesh.MESH_BLENDWEIGHT0, + 'a_BoneIndices': VertexMesh.MESH_BLENDINDICES0, + 'a_Tangent0': VertexMesh.MESH_TANGENT0, + 'a_WorldMat': VertexMesh.MESH_WORLDMATRIX_ROW0, + 'a_SimpleTextureParams': VertexMesh.MESH_SIMPLEANIMATOR + }; + var uniformMap = { + 'u_Bones': Shader3D.PERIOD_CUSTOM, + 'u_DiffuseTexture': Shader3D.PERIOD_MATERIAL, + 'u_SpecularTexture': Shader3D.PERIOD_MATERIAL, + 'u_NormalTexture': Shader3D.PERIOD_MATERIAL, + 'u_AlphaTestValue': Shader3D.PERIOD_MATERIAL, + 'u_DiffuseColor': Shader3D.PERIOD_MATERIAL, + 'u_AlbedoIntensity': Shader3D.PERIOD_MATERIAL, + 'u_MaterialSpecular': Shader3D.PERIOD_MATERIAL, + 'u_Shininess': Shader3D.PERIOD_MATERIAL, + 'u_TilingOffset': Shader3D.PERIOD_MATERIAL, + 'u_TransmissionRate': Shader3D.PERIOD_MATERIAL, + 'u_BackDiffuse': Shader3D.PERIOD_MATERIAL, + 'u_BackScale': Shader3D.PERIOD_MATERIAL, + 'u_ThinknessTexture': Shader3D.PERIOD_MATERIAL, + 'u_TransmissionColor': Shader3D.PERIOD_MATERIAL, + 'u_WorldMat': Shader3D.PERIOD_SPRITE, + 'u_MvpMatrix': Shader3D.PERIOD_SPRITE, + 'u_LightmapScaleOffset': Shader3D.PERIOD_SPRITE, + 'u_LightMap': Shader3D.PERIOD_SPRITE, + 'u_LightMapDirection': Shader3D.PERIOD_SPRITE, + 'u_SimpleAnimatorTexture': Shader3D.PERIOD_SPRITE, + 'u_SimpleAnimatorParams': Shader3D.PERIOD_SPRITE, + 'u_SimpleAnimatorTextureSize': Shader3D.PERIOD_SPRITE, + 'u_CameraPos': Shader3D.PERIOD_CAMERA, + 'u_Viewport': Shader3D.PERIOD_CAMERA, + 'u_ProjectionParams': Shader3D.PERIOD_CAMERA, + 'u_View': Shader3D.PERIOD_CAMERA, + 'u_ViewProjection': Shader3D.PERIOD_CAMERA, + 'u_ReflectTexture': Shader3D.PERIOD_SCENE, + 'u_FogStart': Shader3D.PERIOD_SCENE, + 'u_FogRange': Shader3D.PERIOD_SCENE, + 'u_FogColor': Shader3D.PERIOD_SCENE, + 'u_DirationLightCount': Shader3D.PERIOD_SCENE, + 'u_LightBuffer': Shader3D.PERIOD_SCENE, + 'u_LightClusterBuffer': Shader3D.PERIOD_SCENE, + 'u_AmbientColor': Shader3D.PERIOD_SCENE, + 'u_ShadowBias': Shader3D.PERIOD_SCENE, + 'u_ShadowLightDirection': Shader3D.PERIOD_SCENE, + 'u_ShadowMap': Shader3D.PERIOD_SCENE, + 'u_ShadowParams': Shader3D.PERIOD_SCENE, + 'u_ShadowSplitSpheres': Shader3D.PERIOD_SCENE, + 'u_ShadowMatrices': Shader3D.PERIOD_SCENE, + 'u_ShadowMapSize': Shader3D.PERIOD_SCENE, + 'u_SpotShadowMap': Shader3D.PERIOD_SCENE, + 'u_SpotViewProjectMatrix': Shader3D.PERIOD_SCENE, + 'u_ShadowLightPosition': Shader3D.PERIOD_SCENE, + 'u_AmbientSHAr': Shader3D.PERIOD_SCENE, + 'u_AmbientSHAg': Shader3D.PERIOD_SCENE, + 'u_AmbientSHAb': Shader3D.PERIOD_SCENE, + 'u_AmbientSHBr': Shader3D.PERIOD_SCENE, + 'u_AmbientSHBg': Shader3D.PERIOD_SCENE, + 'u_AmbientSHBb': Shader3D.PERIOD_SCENE, + 'u_AmbientSHC': Shader3D.PERIOD_SCENE, + 'u_DirectionLight.color': Shader3D.PERIOD_SCENE, + 'u_DirectionLight.direction': Shader3D.PERIOD_SCENE, + 'u_PointLight.position': Shader3D.PERIOD_SCENE, + 'u_PointLight.range': Shader3D.PERIOD_SCENE, + 'u_PointLight.color': Shader3D.PERIOD_SCENE, + 'u_SpotLight.position': Shader3D.PERIOD_SCENE, + 'u_SpotLight.direction': Shader3D.PERIOD_SCENE, + 'u_SpotLight.range': Shader3D.PERIOD_SCENE, + 'u_SpotLight.spot': Shader3D.PERIOD_SCENE, + 'u_SpotLight.color': Shader3D.PERIOD_SCENE + }; + var stateMap = { + 's_Cull': Shader3D.RENDER_STATE_CULL, + 's_Blend': Shader3D.RENDER_STATE_BLEND, + 's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC, + 's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST, + 's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST, + 's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE + }; + var shader = Shader3D.add("BLINNPHONG", null, null, true); + var subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + subShader.addShaderPass(MeshBlinnPhongVS, MeshBlinnPhongPS, stateMap, "Forward"); + var shaderPass = subShader.addShaderPass(MeshBlinnPhongShadowCasterVS, MeshBlinnPhongShadowCasterPS, stateMap, "ShadowCaster"); + shaderPass = subShader.addShaderPass(DepthNormalsTextureVS, DepthNormalsTextureFS, stateMap, "DepthNormal"); + attributeMap = { + 'a_Position': VertexMesh.MESH_POSITION0, + 'a_Color': VertexMesh.MESH_COLOR0 + }; + uniformMap = { + 'u_MvpMatrix': Shader3D.PERIOD_SPRITE, + 'u_Color': Shader3D.PERIOD_MATERIAL + }; + stateMap = { + 's_Cull': Shader3D.RENDER_STATE_CULL, + 's_Blend': Shader3D.RENDER_STATE_BLEND, + 's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC, + 's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST, + 's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST, + 's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE + }; + shader = Shader3D.add("LineShader"); + subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + subShader.addShaderPass(lineVS, linePS, stateMap); + attributeMap = { + 'a_Position': VertexMesh.MESH_POSITION0, + 'a_Color': VertexMesh.MESH_COLOR0, + 'a_Texcoord0': VertexMesh.MESH_TEXTURECOORDINATE0, + 'a_BoneWeights': VertexMesh.MESH_BLENDWEIGHT0, + 'a_BoneIndices': VertexMesh.MESH_BLENDINDICES0, + 'a_WorldMat': VertexMesh.MESH_WORLDMATRIX_ROW0, + 'a_SimpleTextureParams': VertexMesh.MESH_SIMPLEANIMATOR + }; + uniformMap = { + 'u_Bones': Shader3D.PERIOD_CUSTOM, + 'u_AlbedoTexture': Shader3D.PERIOD_MATERIAL, + 'u_AlbedoColor': Shader3D.PERIOD_MATERIAL, + 'u_TilingOffset': Shader3D.PERIOD_MATERIAL, + 'u_AlphaTestValue': Shader3D.PERIOD_MATERIAL, + 'u_MvpMatrix': Shader3D.PERIOD_SPRITE, + 'u_ViewProjection': Shader3D.PERIOD_CAMERA, + 'u_SimpleAnimatorTexture': Shader3D.PERIOD_SPRITE, + 'u_SimpleAnimatorParams': Shader3D.PERIOD_SPRITE, + 'u_SimpleAnimatorTextureSize': Shader3D.PERIOD_SPRITE, + 'u_FogStart': Shader3D.PERIOD_SCENE, + 'u_FogRange': Shader3D.PERIOD_SCENE, + 'u_FogColor': Shader3D.PERIOD_SCENE + }; + stateMap = { + 's_Cull': Shader3D.RENDER_STATE_CULL, + 's_Blend': Shader3D.RENDER_STATE_BLEND, + 's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC, + 's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST, + 's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST, + 's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE + }; + shader = Shader3D.add("Unlit", null, null, true); + subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + subShader.addShaderPass(UnlitVS, UnlitPS, stateMap); + attributeMap = { + 'a_Position': VertexMesh.MESH_POSITION0, + 'a_Texcoord0': VertexMesh.MESH_TEXTURECOORDINATE0, + 'a_BoneWeights': VertexMesh.MESH_BLENDWEIGHT0, + 'a_BoneIndices': VertexMesh.MESH_BLENDINDICES0, + 'a_WorldMat': VertexMesh.MESH_WORLDMATRIX_ROW0, + 'a_SimpleTextureParams': VertexMesh.MESH_SIMPLEANIMATOR + }; + uniformMap = { + 'u_Bones': Shader3D.PERIOD_CUSTOM, + 'u_AlbedoTexture': Shader3D.PERIOD_MATERIAL, + 'u_AlbedoColor': Shader3D.PERIOD_MATERIAL, + 'u_TilingOffset': Shader3D.PERIOD_MATERIAL, + 'u_AlphaTestValue': Shader3D.PERIOD_MATERIAL, + 'u_ViewProjection': Shader3D.PERIOD_CAMERA, + 'u_MvpMatrix': Shader3D.PERIOD_SPRITE, + 'u_SimpleAnimatorTexture': Shader3D.PERIOD_SPRITE, + 'u_SimpleAnimatorParams': Shader3D.PERIOD_SPRITE, + 'u_SimpleAnimatorTextureSize': Shader3D.PERIOD_SPRITE, + 'u_FogStart': Shader3D.PERIOD_SCENE, + 'u_FogRange': Shader3D.PERIOD_SCENE, + 'u_FogColor': Shader3D.PERIOD_SCENE + }; + stateMap = { + 's_Cull': Shader3D.RENDER_STATE_CULL, + 's_Blend': Shader3D.RENDER_STATE_BLEND, + 's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC, + 's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST, + 's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST, + 's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE + }; + shader = Shader3D.add("Effect", null, null, true); + subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + subShader.addShaderPass(EffectVS, EffectPS, stateMap); + attributeMap = { + 'a_CornerTextureCoordinate': VertexShuriKenParticle.PARTICLE_CORNERTEXTURECOORDINATE0, + 'a_MeshPosition': VertexShuriKenParticle.PARTICLE_POSITION0, + 'a_MeshColor': VertexShuriKenParticle.PARTICLE_COLOR0, + 'a_MeshTextureCoordinate': VertexShuriKenParticle.PARTICLE_TEXTURECOORDINATE0, + 'a_ShapePositionStartLifeTime': VertexShuriKenParticle.PARTICLE_SHAPEPOSITIONSTARTLIFETIME, + 'a_DirectionTime': VertexShuriKenParticle.PARTICLE_DIRECTIONTIME, + 'a_StartColor': VertexShuriKenParticle.PARTICLE_STARTCOLOR0, + 'a_EndColor': VertexShuriKenParticle.PARTICLE_ENDCOLOR0, + 'a_StartSize': VertexShuriKenParticle.PARTICLE_STARTSIZE, + 'a_StartRotation0': VertexShuriKenParticle.PARTICLE_STARTROTATION, + 'a_StartSpeed': VertexShuriKenParticle.PARTICLE_STARTSPEED, + 'a_Random0': VertexShuriKenParticle.PARTICLE_RANDOM0, + 'a_Random1': VertexShuriKenParticle.PARTICLE_RANDOM1, + 'a_SimulationWorldPostion': VertexShuriKenParticle.PARTICLE_SIMULATIONWORLDPOSTION, + 'a_SimulationWorldRotation': VertexShuriKenParticle.PARTICLE_SIMULATIONWORLDROTATION + }; + uniformMap = { + 'u_Tintcolor': Shader3D.PERIOD_MATERIAL, + 'u_TilingOffset': Shader3D.PERIOD_MATERIAL, + 'u_texture': Shader3D.PERIOD_MATERIAL, + 'u_WorldPosition': Shader3D.PERIOD_SPRITE, + 'u_WorldRotation': Shader3D.PERIOD_SPRITE, + 'u_PositionScale': Shader3D.PERIOD_SPRITE, + 'u_SizeScale': Shader3D.PERIOD_SPRITE, + 'u_ScalingMode': Shader3D.PERIOD_SPRITE, + 'u_Gravity': Shader3D.PERIOD_SPRITE, + 'u_ThreeDStartRotation': Shader3D.PERIOD_SPRITE, + 'u_StretchedBillboardLengthScale': Shader3D.PERIOD_SPRITE, + 'u_StretchedBillboardSpeedScale': Shader3D.PERIOD_SPRITE, + 'u_SimulationSpace': Shader3D.PERIOD_SPRITE, + 'u_CurrentTime': Shader3D.PERIOD_SPRITE, + 'u_ColorOverLifeGradientAlphas': Shader3D.PERIOD_SPRITE, + 'u_ColorOverLifeGradientColors': Shader3D.PERIOD_SPRITE, + 'u_MaxColorOverLifeGradientAlphas': Shader3D.PERIOD_SPRITE, + 'u_MaxColorOverLifeGradientColors': Shader3D.PERIOD_SPRITE, + 'u_VOLVelocityConst': Shader3D.PERIOD_SPRITE, + 'u_VOLVelocityGradientX': Shader3D.PERIOD_SPRITE, + 'u_VOLVelocityGradientY': Shader3D.PERIOD_SPRITE, + 'u_VOLVelocityGradientZ': Shader3D.PERIOD_SPRITE, + 'u_VOLVelocityConstMax': Shader3D.PERIOD_SPRITE, + 'u_VOLVelocityGradientMaxX': Shader3D.PERIOD_SPRITE, + 'u_VOLVelocityGradientMaxY': Shader3D.PERIOD_SPRITE, + 'u_VOLVelocityGradientMaxZ': Shader3D.PERIOD_SPRITE, + 'u_VOLSpaceType': Shader3D.PERIOD_SPRITE, + 'u_SOLSizeGradient': Shader3D.PERIOD_SPRITE, + 'u_SOLSizeGradientX': Shader3D.PERIOD_SPRITE, + 'u_SOLSizeGradientY': Shader3D.PERIOD_SPRITE, + 'u_SOLSizeGradientZ': Shader3D.PERIOD_SPRITE, + 'u_SOLSizeGradientMax': Shader3D.PERIOD_SPRITE, + 'u_SOLSizeGradientMaxX': Shader3D.PERIOD_SPRITE, + 'u_SOLSizeGradientMaxY': Shader3D.PERIOD_SPRITE, + 'u_SOLSizeGradientMaxZ': Shader3D.PERIOD_SPRITE, + 'u_ROLAngularVelocityConst': Shader3D.PERIOD_SPRITE, + 'u_ROLAngularVelocityConstSeprarate': Shader3D.PERIOD_SPRITE, + 'u_ROLAngularVelocityGradient': Shader3D.PERIOD_SPRITE, + 'u_ROLAngularVelocityGradientX': Shader3D.PERIOD_SPRITE, + 'u_ROLAngularVelocityGradientY': Shader3D.PERIOD_SPRITE, + 'u_ROLAngularVelocityGradientZ': Shader3D.PERIOD_SPRITE, + 'u_ROLAngularVelocityConstMax': Shader3D.PERIOD_SPRITE, + 'u_ROLAngularVelocityConstMaxSeprarate': Shader3D.PERIOD_SPRITE, + 'u_ROLAngularVelocityGradientMax': Shader3D.PERIOD_SPRITE, + 'u_ROLAngularVelocityGradientMaxX': Shader3D.PERIOD_SPRITE, + 'u_ROLAngularVelocityGradientMaxY': Shader3D.PERIOD_SPRITE, + 'u_ROLAngularVelocityGradientMaxZ': Shader3D.PERIOD_SPRITE, + 'u_ROLAngularVelocityGradientMaxW': Shader3D.PERIOD_SPRITE, + 'u_TSACycles': Shader3D.PERIOD_SPRITE, + 'u_TSASubUVLength': Shader3D.PERIOD_SPRITE, + 'u_TSAGradientUVs': Shader3D.PERIOD_SPRITE, + 'u_TSAMaxGradientUVs': Shader3D.PERIOD_SPRITE, + 'u_CameraPos': Shader3D.PERIOD_CAMERA, + 'u_CameraDirection': Shader3D.PERIOD_CAMERA, + 'u_CameraUp': Shader3D.PERIOD_CAMERA, + 'u_View': Shader3D.PERIOD_CAMERA, + 'u_Projection': Shader3D.PERIOD_CAMERA, + 'u_FogStart': Shader3D.PERIOD_SCENE, + 'u_FogRange': Shader3D.PERIOD_SCENE, + 'u_FogColor': Shader3D.PERIOD_SCENE + }; + stateMap = { + 's_Cull': Shader3D.RENDER_STATE_CULL, + 's_Blend': Shader3D.RENDER_STATE_BLEND, + 's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC, + 's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST, + 's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST, + 's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE + }; + shader = Shader3D.add("PARTICLESHURIKEN"); + subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + subShader.addShaderPass(ParticleShuriKenVS, ParticleShuriKenPS, stateMap); + attributeMap = { + 'a_Position': VertexMesh.MESH_POSITION0 + }; + uniformMap = { + 'u_TintColor': Shader3D.PERIOD_MATERIAL, + 'u_Exposure': Shader3D.PERIOD_MATERIAL, + 'u_Rotation': Shader3D.PERIOD_MATERIAL, + 'u_CubeTexture': Shader3D.PERIOD_MATERIAL, + 'u_ViewProjection': Shader3D.PERIOD_CAMERA + }; + shader = Shader3D.add("SkyBox"); + subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + subShader.addShaderPass(SkyBoxVS, SkyBoxPS); + attributeMap = { + 'a_Position': VertexMesh.MESH_POSITION0 + }; + uniformMap = { + 'u_SunSize': Shader3D.PERIOD_MATERIAL, + 'u_SunSizeConvergence': Shader3D.PERIOD_MATERIAL, + 'u_AtmosphereThickness': Shader3D.PERIOD_MATERIAL, + 'u_SkyTint': Shader3D.PERIOD_MATERIAL, + 'u_GroundTint': Shader3D.PERIOD_MATERIAL, + 'u_Exposure': Shader3D.PERIOD_MATERIAL, + 'u_ViewProjection': Shader3D.PERIOD_CAMERA, + 'u_SunLight.direction': Shader3D.PERIOD_SCENE, + 'u_SunLight.color': Shader3D.PERIOD_SCENE, + }; + shader = Shader3D.add("SkyBoxProcedural"); + subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + subShader.addShaderPass(SkyBoxProceduralVS, SkyBoxProceduralPS); + attributeMap = { + 'a_Position': VertexMesh.MESH_POSITION0, + 'a_Normal': VertexMesh.MESH_NORMAL0, + 'a_Texcoord0': VertexMesh.MESH_TEXTURECOORDINATE0 + }; + uniformMap = { + 'u_MvpMatrix': Shader3D.PERIOD_SPRITE, + 'u_WorldMat': Shader3D.PERIOD_SPRITE, + 'u_CameraPos': Shader3D.PERIOD_CAMERA, + 'u_Viewport': Shader3D.PERIOD_CAMERA, + 'u_ProjectionParams': Shader3D.PERIOD_CAMERA, + 'u_View': Shader3D.PERIOD_CAMERA, + 'u_LightmapScaleOffset': Shader3D.PERIOD_SPRITE, + 'u_LightMap': Shader3D.PERIOD_SPRITE, + 'u_SplatAlphaTexture': Shader3D.PERIOD_MATERIAL, + 'u_DiffuseTexture1': Shader3D.PERIOD_MATERIAL, + 'u_DiffuseTexture2': Shader3D.PERIOD_MATERIAL, + 'u_DiffuseTexture3': Shader3D.PERIOD_MATERIAL, + 'u_DiffuseTexture4': Shader3D.PERIOD_MATERIAL, + 'u_DiffuseTexture5': Shader3D.PERIOD_MATERIAL, + 'u_DiffuseScaleOffset1': Shader3D.PERIOD_MATERIAL, + 'u_DiffuseScaleOffset2': Shader3D.PERIOD_MATERIAL, + 'u_DiffuseScaleOffset3': Shader3D.PERIOD_MATERIAL, + 'u_DiffuseScaleOffset4': Shader3D.PERIOD_MATERIAL, + 'u_DiffuseScaleOffset5': Shader3D.PERIOD_MATERIAL, + 'u_FogStart': Shader3D.PERIOD_SCENE, + 'u_FogRange': Shader3D.PERIOD_SCENE, + 'u_FogColor': Shader3D.PERIOD_SCENE, + 'u_DirationLightCount': Shader3D.PERIOD_SCENE, + 'u_LightBuffer': Shader3D.PERIOD_SCENE, + 'u_LightClusterBuffer': Shader3D.PERIOD_SCENE, + 'u_AmbientColor': Shader3D.PERIOD_SCENE, + 'u_ShadowMap': Shader3D.PERIOD_SCENE, + 'u_shadowMap2': Shader3D.PERIOD_SCENE, + 'u_shadowMap3': Shader3D.PERIOD_SCENE, + 'u_ShadowSplitSpheres': Shader3D.PERIOD_SCENE, + 'u_ShadowMatrices': Shader3D.PERIOD_SCENE, + 'u_ShadowMapSize': Shader3D.PERIOD_SCENE, + 'u_DirectionLight.color': Shader3D.PERIOD_SCENE, + 'u_DirectionLight.direction': Shader3D.PERIOD_SCENE, + 'u_PointLight.position': Shader3D.PERIOD_SCENE, + 'u_PointLight.range': Shader3D.PERIOD_SCENE, + 'u_PointLight.color': Shader3D.PERIOD_SCENE, + 'u_SpotLight.position': Shader3D.PERIOD_SCENE, + 'u_SpotLight.direction': Shader3D.PERIOD_SCENE, + 'u_SpotLight.range': Shader3D.PERIOD_SCENE, + 'u_SpotLight.spot': Shader3D.PERIOD_SCENE, + 'u_SpotLight.color': Shader3D.PERIOD_SCENE + }; + stateMap = { + 's_Cull': Shader3D.RENDER_STATE_CULL, + 's_Blend': Shader3D.RENDER_STATE_BLEND, + 's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC, + 's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST, + 's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST, + 's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE + }; + shader = Shader3D.add("ExtendTerrain"); + subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + subShader.addShaderPass(extendTerrainVS, extendTerrainPS, stateMap); + attributeMap = { + 'a_Position': VertexTrail.TRAIL_POSITION0, + 'a_OffsetVector': VertexTrail.TRAIL_OFFSETVECTOR, + 'a_Texcoord0X': VertexTrail.TRAIL_TEXTURECOORDINATE0X, + 'a_Texcoord0Y': VertexTrail.TRAIL_TEXTURECOORDINATE0Y, + 'a_BirthTime': VertexTrail.TRAIL_TIME0, + 'a_Color': VertexTrail.TRAIL_COLOR + }; + uniformMap = { + 'u_MvpMatrix': Shader3D.PERIOD_SPRITE, + 'u_View': Shader3D.PERIOD_CAMERA, + 'u_Projection': Shader3D.PERIOD_CAMERA, + 'u_TilingOffset': Shader3D.PERIOD_MATERIAL, + 'u_MainTexture': Shader3D.PERIOD_MATERIAL, + 'u_MainColor': Shader3D.PERIOD_MATERIAL, + 'u_CurTime': Shader3D.PERIOD_SPRITE, + 'u_LifeTime': Shader3D.PERIOD_SPRITE, + 'u_WidthCurve': Shader3D.PERIOD_SPRITE, + 'u_WidthCurveKeyLength': Shader3D.PERIOD_SPRITE, + 'u_GradientColorkey': Shader3D.PERIOD_SPRITE, + 'u_GradientAlphakey': Shader3D.PERIOD_SPRITE + }; + stateMap = { + 's_Cull': Shader3D.RENDER_STATE_CULL, + 's_Blend': Shader3D.RENDER_STATE_BLEND, + 's_BlendSrc': Shader3D.RENDER_STATE_BLEND_SRC, + 's_BlendDst': Shader3D.RENDER_STATE_BLEND_DST, + 's_DepthTest': Shader3D.RENDER_STATE_DEPTH_TEST, + 's_DepthWrite': Shader3D.RENDER_STATE_DEPTH_WRITE + }; + shader = Shader3D.add("Trail"); + subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + subShader.addShaderPass(TrailVS, TrailPS, stateMap); + attributeMap = { + 'a_Position': VertexMesh.MESH_POSITION0, + 'a_Normal': VertexMesh.MESH_NORMAL0, + 'a_Tangent0': VertexMesh.MESH_TANGENT0 + }; + uniformMap = { + 'u_MvpMatrix': Shader3D.PERIOD_SPRITE, + 'u_WorldMat': Shader3D.PERIOD_SPRITE, + 'u_CameraPos': Shader3D.PERIOD_CAMERA, + 'u_Time': Shader3D.PERIOD_SCENE, + 'u_MainTexture': Shader3D.PERIOD_MATERIAL, + 'u_NormalTexture': Shader3D.PERIOD_MATERIAL, + 'u_HorizonColor': Shader3D.PERIOD_MATERIAL, + 'u_WaveScale': Shader3D.PERIOD_MATERIAL, + 'u_WaveSpeed': Shader3D.PERIOD_MATERIAL + }; + shader = Shader3D.add("WaterPrimary"); + subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + subShader.addShaderPass(WaterPrimaryVS, WaterPrimaryPS); + attributeMap = { + 'a_PositionTexcoord': VertexMesh.MESH_POSITION0 + }; + uniformMap = { + 'u_MainTex': Shader3D.PERIOD_MATERIAL, + 'u_OffsetScale': Shader3D.PERIOD_MATERIAL + }; + shader = Shader3D.add("BlitScreen"); + subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + var shaderPass = subShader.addShaderPass(BlitScreenVS, BlitScreenPS); + var renderState = shaderPass.renderState; + renderState.depthTest = RenderState.DEPTHTEST_ALWAYS; + renderState.depthWrite = false; + renderState.cull = RenderState.CULL_NONE; + renderState.blend = RenderState.BLEND_DISABLE; + attributeMap = { + 'a_PositionTexcoord': VertexMesh.MESH_POSITION0 + }; + uniformMap = { + 'u_MainTex': Shader3D.PERIOD_MATERIAL, + 'u_BloomTex': Shader3D.PERIOD_MATERIAL, + 'u_AutoExposureTex': Shader3D.PERIOD_MATERIAL, + 'u_MainTex_TexelSize': Shader3D.PERIOD_MATERIAL, + 'u_SampleScale': Shader3D.PERIOD_MATERIAL, + 'u_Threshold': Shader3D.PERIOD_MATERIAL, + 'u_Params': Shader3D.PERIOD_MATERIAL + }; + shader = Shader3D.add("PostProcessBloom"); + subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + shaderPass = subShader.addShaderPass(BloomVS, BloomPrefilter13PS); + renderState = shaderPass.renderState; + renderState.depthTest = RenderState.DEPTHTEST_ALWAYS; + renderState.depthWrite = false; + renderState.cull = RenderState.CULL_NONE; + renderState.blend = RenderState.BLEND_DISABLE; + subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + shaderPass = subShader.addShaderPass(BloomVS, BloomPrefilter4PS); + renderState = shaderPass.renderState; + renderState.depthTest = RenderState.DEPTHTEST_ALWAYS; + renderState.depthWrite = false; + renderState.cull = RenderState.CULL_NONE; + renderState.blend = RenderState.BLEND_DISABLE; + subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + shaderPass = subShader.addShaderPass(BloomVS, BloomDownsample13PS); + renderState = shaderPass.renderState; + renderState.depthTest = RenderState.DEPTHTEST_ALWAYS; + renderState.depthWrite = false; + renderState.cull = RenderState.CULL_NONE; + renderState.blend = RenderState.BLEND_DISABLE; + subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + shaderPass = subShader.addShaderPass(BloomVS, BloomDownsample4PS); + renderState = shaderPass.renderState; + renderState.depthTest = RenderState.DEPTHTEST_ALWAYS; + renderState.depthWrite = false; + renderState.cull = RenderState.CULL_NONE; + renderState.blend = RenderState.BLEND_DISABLE; + subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + shaderPass = subShader.addShaderPass(BloomVS, BloomUpsampleTentPS); + renderState = shaderPass.renderState; + renderState.depthTest = RenderState.DEPTHTEST_ALWAYS; + renderState.depthWrite = false; + renderState.cull = RenderState.CULL_NONE; + renderState.blend = RenderState.BLEND_DISABLE; + subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + shaderPass = subShader.addShaderPass(BloomVS, BloomUpsampleBoxPS); + renderState = shaderPass.renderState; + renderState.depthTest = RenderState.DEPTHTEST_ALWAYS; + renderState.depthWrite = false; + renderState.cull = RenderState.CULL_NONE; + renderState.blend = RenderState.BLEND_DISABLE; + attributeMap = { + 'a_PositionTexcoord': VertexMesh.MESH_POSITION0 + }; + uniformMap = { + 'u_MainTex': Shader3D.PERIOD_MATERIAL, + 'u_BloomTex': Shader3D.PERIOD_MATERIAL, + 'u_AutoExposureTex': Shader3D.PERIOD_MATERIAL, + 'u_Bloom_DirtTileOffset': Shader3D.PERIOD_MATERIAL, + 'u_Bloom_DirtTex': Shader3D.PERIOD_MATERIAL, + 'u_BloomTex_TexelSize': Shader3D.PERIOD_MATERIAL, + 'u_Bloom_Settings': Shader3D.PERIOD_MATERIAL, + 'u_Bloom_Color': Shader3D.PERIOD_MATERIAL + }; + shader = Shader3D.add("PostProcessComposite"); + subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + shaderPass = subShader.addShaderPass(CompositeVS, CompositePS); + renderState = shaderPass.renderState; + renderState.depthTest = RenderState.DEPTHTEST_ALWAYS; + renderState.depthWrite = false; + renderState.cull = RenderState.CULL_NONE; + renderState.blend = RenderState.BLEND_DISABLE; + } + } + + class DirectionLight extends LightSprite { + constructor() { + super(); + this._direction = new Vector3(); + this._shadowCascadesMode = exports.ShadowCascadesMode.NoCascades; + this._shadowTwoCascadeSplits = 1.0 / 3.0; + this._shadowFourCascadeSplits = new Vector3(1.0 / 15, 3.0 / 15.0, 7.0 / 15.0); + this._lightType = exports.LightType.Directional; + } + get shadowCascadesMode() { + return this._shadowCascadesMode; + } + set shadowCascadesMode(value) { + this._shadowCascadesMode = value; + } + get shadowTwoCascadeSplits() { + return this._shadowTwoCascadeSplits; + } + set shadowTwoCascadeSplits(value) { + this._shadowTwoCascadeSplits = value; + } + get shadowFourCascadeSplits() { + return this._shadowFourCascadeSplits; + } + set shadowFourCascadeSplits(value) { + if (value.x > value.y || value.y > value.z || value.z > 1.0) + throw "DiretionLight:Invalid value."; + value.cloneTo(this._shadowFourCascadeSplits); + } + _addToLightQueue() { + this._scene._directionLights.add(this); + } + _removeFromLightQueue() { + this._scene._directionLights.remove(this); + } + _create() { + return new DirectionLight(); + } + } + + class PointLight extends LightSprite { + constructor() { + super(); + this._range = 6.0; + this._lightType = exports.LightType.Point; + } + get range() { + return this._range; + } + set range(value) { + this._range = value; + } + _addToLightQueue() { + this._scene._pointLights.add(this); + } + _removeFromLightQueue() { + this._scene._pointLights.remove(this); + } + _parse(data, spriteMap) { + super._parse(data, spriteMap); + this.range = data.range; + } + _cloneTo(destObject, rootSprite, dstSprite) { + super._cloneTo(destObject, rootSprite, dstSprite); + var pointlight = destObject; + pointlight.range = this.range; + pointlight._lightType = exports.LightType.Point; + } + _create() { + return new PointLight(); + } + } + + class SpotLight extends LightSprite { + constructor() { + super(); + this._spotAngle = 30.0; + this._range = 10.0; + this._direction = new Vector3(); + this._lightType = exports.LightType.Spot; + } + get spotAngle() { + return this._spotAngle; + } + set spotAngle(value) { + this._spotAngle = Math.max(Math.min(value, 179), 0); + } + get range() { + return this._range; + } + set range(value) { + this._range = value; + } + _addToLightQueue() { + this._scene._spotLights.add(this); + } + _removeFromLightQueue() { + this._scene._spotLights.remove(this); + } + _parse(data, spriteMap) { + super._parse(data, spriteMap); + this.range = data.range; + this.spotAngle = data.spotAngle; + } + _cloneTo(destObject, rootSprite, dstSprite) { + super._cloneTo(destObject, rootSprite, dstSprite); + var spotLight = destObject; + spotLight.range = this.range; + spotLight.spotAngle = this.spotAngle; + } + _create() { + return new SpotLight(); + } + } + + class SimpleSkinnedMeshRenderer extends SkinnedMeshRenderer { + constructor(owner) { + super(owner); + this._simpleAnimatorParams = new Vector4(); + this._simpleAnimatorOffset = new Vector2(); + this._shaderValues.addDefine(SkinnedMeshSprite3DShaderDeclaration.SHADERDEFINE_SIMPLEBONE); + this._shaderValues.addDefine(SkinnedMeshSprite3DShaderDeclaration.SHADERDEFINE_BONE); + } + get simpleAnimatorTexture() { + return this._simpleAnimatorTexture; + } + set simpleAnimatorTexture(value) { + this._simpleAnimatorTexture = value; + this._simpleAnimatorTextureSize = value.width; + this._shaderValues.setTexture(SimpleSkinnedMeshRenderer.SIMPLE_SIMPLEANIMATORTEXTURE, value); + value._addReference(); + this._shaderValues.setNumber(SimpleSkinnedMeshRenderer.SIMPLE_SIMPLEANIMATORTEXTURESIZE, this._simpleAnimatorTextureSize); + } + get simpleAnimatorOffset() { + return this._simpleAnimatorOffset; + } + set simpleAnimatorOffset(value) { + value.cloneTo(this._simpleAnimatorOffset); + } + _computeAnimatorParamsData() { + if (this._cacheMesh) { + this._simpleAnimatorParams.x = this._simpleAnimatorOffset.x; + this._simpleAnimatorParams.y = Math.round(this._simpleAnimatorOffset.y) * this._bonesNums * 4; + } + } + _createRenderElement() { + return new SubMeshRenderElement(); + } + _setCacheAnimator(animator) { + this._cacheAnimator = animator; + this._shaderValues.addDefine(SkinnedMeshSprite3DShaderDeclaration.SHADERDEFINE_SIMPLEBONE); + } + _onMeshChange(value) { + super._onMeshChange(value); + this._cacheMesh = value; + } + _renderUpdate(context, transform) { + var element = context.renderElement; + switch (element.renderType) { + case RenderElement.RENDERTYPE_NORMAL: + if (this._cacheAnimator) { + var worldMat = this._cacheAnimator.owner.transform.worldMatrix; + this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX, worldMat); + } + else { + this._shaderValues.setMatrix4x4(Sprite3D.WORLDMATRIX, transform.worldMatrix); + } + this._computeAnimatorParamsData(); + this._shaderValues.setVector(SimpleSkinnedMeshRenderer.SIMPLE_SIMPLEANIMATORPARAMS, this._simpleAnimatorParams); + break; + case RenderElement.RENDERTYPE_INSTANCEBATCH: + var worldMatrixData = SubMeshInstanceBatch.instance.instanceWorldMatrixData; + var insBatches = element.instanceBatchElementList; + var elements = insBatches.elements; + var count = insBatches.length; + if (this._cacheAnimator) { + for (var i = 0; i < count; i++) { + var mat = (elements[i].render)._cacheAnimator.owner._transform.worldMatrix; + worldMatrixData.set(mat.elements, i * 16); + } + } + else { + for (var i = 0; i < count; i++) + worldMatrixData.set(elements[i]._transform.worldMatrix.elements, i * 16); + } + var worldBuffer = SubMeshInstanceBatch.instance.instanceWorldMatrixBuffer; + worldBuffer.orphanStorage(); + worldBuffer.setData(worldMatrixData.buffer, 0, 0, count * 16 * 4); + this._shaderValues.addDefine(MeshSprite3DShaderDeclaration.SHADERDEFINE_GPU_INSTANCE); + var simpleAnimatorData = SubMeshInstanceBatch.instance.instanceSimpleAnimatorData; + if (this._cacheAnimator) { + for (var i = 0; i < count; i++) { + var render = (elements[i].render); + render._computeAnimatorParamsData(); + var simpleAnimatorParams = render._simpleAnimatorParams; + var offset = i * 4; + simpleAnimatorData[offset] = simpleAnimatorParams.x; + simpleAnimatorData[offset + 1] = simpleAnimatorParams.y; + } + } + else { + for (var i = 0; i < count; i++) { + simpleAnimatorData[offset] = 0; + simpleAnimatorData[offset + 1] = 0; + } + } + var simpleAnimatorBuffer = SubMeshInstanceBatch.instance.instanceSimpleAnimatorBuffer; + simpleAnimatorBuffer.orphanStorage(); + simpleAnimatorBuffer.setData(simpleAnimatorData.buffer, 0, 0, count * 4 * 4); + break; + } + } + _renderUpdateWithCamera(context, transform) { + var projectionView = context.projectionViewMatrix; + if (projectionView) { + var element = context.renderElement; + switch (element.renderType) { + case RenderElement.RENDERTYPE_NORMAL: + if (this._cacheAnimator) { + var mat = this._cacheAnimator.owner._transform.worldMatrix; + Matrix4x4.multiply(projectionView, mat, this._projectionViewWorldMatrix); + this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX, this._projectionViewWorldMatrix); + } + else { + Matrix4x4.multiply(projectionView, transform.worldMatrix, this._projectionViewWorldMatrix); + this._shaderValues.setMatrix4x4(Sprite3D.MVPMATRIX, this._projectionViewWorldMatrix); + } + break; + } + } + } + _destroy() { + if (this._cacheRootBone) + (!this._cacheRootBone.destroyed) && (this._cacheRootBone.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onWorldMatNeedChange)); + (this._simpleAnimatorTexture) && this._simpleAnimatorTexture._removeReference(); + this._simpleAnimatorTexture = null; + } + } + + class SimpleSkinnedMeshSprite3D extends RenderableSprite3D { + constructor(mesh = null, name = null) { + super(name); + this._meshFilter = new MeshFilter(this); + this._render = new SimpleSkinnedMeshRenderer(this); + (mesh) && (this._meshFilter.sharedMesh = mesh); + } + static __init__() { + SimpleSkinnedMeshRenderer.SIMPLE_SIMPLEANIMATORPARAMS = SimpleSkinnedMeshSprite3D.SIMPLE_SIMPLEANIMATORPARAMS; + SimpleSkinnedMeshRenderer.SIMPLE_SIMPLEANIMATORTEXTURE = SimpleSkinnedMeshSprite3D.SIMPLE_SIMPLEANIMATORTEXTURE; + SimpleSkinnedMeshRenderer.SIMPLE_SIMPLEANIMATORTEXTURESIZE = SimpleSkinnedMeshSprite3D.SIMPLE_SIMPLEANIMATORTEXTURESIZE; + } + get meshFilter() { + return this._meshFilter; + } + get simpleSkinnedMeshRenderer() { + return this._render; + } + _parse(data, spriteMap) { + super._parse(data, spriteMap); + var render = this.simpleSkinnedMeshRenderer; + var lightmapIndex = data.lightmapIndex; + (lightmapIndex != null) && (render.lightmapIndex = lightmapIndex); + var lightmapScaleOffsetArray = data.lightmapScaleOffset; + (lightmapScaleOffsetArray) && (render.lightmapScaleOffset = new Vector4(lightmapScaleOffsetArray[0], lightmapScaleOffsetArray[1], lightmapScaleOffsetArray[2], lightmapScaleOffsetArray[3])); + (data.enableRender != undefined) && (render.enable = data.enableRender); + (data.receiveShadows != undefined) && (render.receiveShadow = data.receiveShadows); + (data.castShadow != undefined) && (render.castShadow = data.castShadow); + var meshPath; + meshPath = data.meshPath; + if (meshPath) { + var mesh = Laya.Loader.getRes(meshPath); + (mesh) && (this.meshFilter.sharedMesh = mesh); + } + var materials = data.materials; + if (materials) { + var sharedMaterials = render.sharedMaterials; + var materialCount = materials.length; + sharedMaterials.length = materialCount; + for (var i = 0; i < materialCount; i++) { + sharedMaterials[i] = Laya.Loader.getRes(materials[i].path); + } + render.sharedMaterials = sharedMaterials; + } + var boundBox = data.boundBox; + var min = boundBox.min; + var max = boundBox.max; + render.localBounds.setMin(new Vector3(min[0], min[1], min[2])); + render.localBounds.setMax(new Vector3(max[0], max[1], max[2])); + if (spriteMap) { + var rootBoneData = data.rootBone; + render.rootBone = spriteMap[rootBoneData]; + var bonesData = data.bones; + var n; + for (i = 0, n = bonesData.length; i < n; i++) + render.bones.push(spriteMap[bonesData[i]]); + render._bonesNums = data.bonesNums ? data.bonesNums : render.bones.length; + } + else { + (data.rootBone) && (render._setRootBone(data.rootBone)); + } + var animatorTexture = data.animatorTexture; + if (animatorTexture) { + var animatortexture = Laya.Loader.getRes(animatorTexture); + render.simpleAnimatorTexture = animatortexture; + } + } + _changeHierarchyAnimator(animator) { + super._changeHierarchyAnimator(animator); + this.simpleSkinnedMeshRenderer._setCacheAnimator(animator); + } + _cloneTo(destObject, srcRoot, dstRoot) { + var meshSprite3D = destObject; + meshSprite3D.meshFilter.sharedMesh = this.meshFilter.sharedMesh; + var meshRender = this._render; + var destMeshRender = meshSprite3D._render; + destMeshRender.enable = meshRender.enable; + destMeshRender.sharedMaterials = meshRender.sharedMaterials; + destMeshRender.castShadow = meshRender.castShadow; + var lightmapScaleOffset = meshRender.lightmapScaleOffset; + lightmapScaleOffset && (destMeshRender.lightmapScaleOffset = lightmapScaleOffset.clone()); + destMeshRender.receiveShadow = meshRender.receiveShadow; + destMeshRender.sortingFudge = meshRender.sortingFudge; + destMeshRender._rootBone = meshRender._rootBone; + var bones = meshRender.bones; + var destBones = destMeshRender.bones; + var bonesCount = bones.length; + destBones.length = bonesCount; + var rootBone = meshRender.rootBone; + if (rootBone) { + var pathes = Utils3D._getHierarchyPath(srcRoot, rootBone, SimpleSkinnedMeshSprite3D._tempArray0); + if (pathes) + destMeshRender.rootBone = Utils3D._getNodeByHierarchyPath(dstRoot, pathes); + else + destMeshRender.rootBone = rootBone; + } + for (var i = 0; i < bones.length; i++) { + pathes = Utils3D._getHierarchyPath(srcRoot, bones[i], SimpleSkinnedMeshSprite3D._tempArray0); + if (pathes) + destBones[i] = Utils3D._getNodeByHierarchyPath(dstRoot, pathes); + else + destBones[i] = bones[i]; + } + var lbb = meshRender.localBounds; + (lbb) && (lbb.cloneTo(destMeshRender.localBounds)); + destMeshRender.simpleAnimatorOffset = meshRender.simpleAnimatorOffset; + destMeshRender.simpleAnimatorTexture = meshRender.simpleAnimatorTexture; + destMeshRender._bonesNums = meshRender._bonesNums; + super._cloneTo(destObject, srcRoot, dstRoot); + } + destroy(destroyChild = true) { + if (this.destroyed) + return; + super.destroy(destroyChild); + this._meshFilter.destroy(); + } + _create() { + return new SimpleSkinnedMeshSprite3D(); + } + } + SimpleSkinnedMeshSprite3D._tempArray0 = []; + SimpleSkinnedMeshSprite3D.SIMPLE_SIMPLEANIMATORTEXTURE = Shader3D.propertyNameToID("u_SimpleAnimatorTexture"); + SimpleSkinnedMeshSprite3D.SIMPLE_SIMPLEANIMATORPARAMS = Shader3D.propertyNameToID("u_SimpleAnimatorParams"); + SimpleSkinnedMeshSprite3D.SIMPLE_SIMPLEANIMATORTEXTURESIZE = Shader3D.propertyNameToID("u_SimpleAnimatorTextureSize"); + + class Scene3DUtils { + static _createSprite3DInstance(nodeData, spriteMap, outBatchSprites) { + var node; + switch (nodeData.type) { + case "Scene3D": + node = new Scene3D(); + break; + case "Sprite3D": + node = new Sprite3D(); + break; + case "MeshSprite3D": + node = new MeshSprite3D(); + (outBatchSprites && nodeData.props.isStatic) && (outBatchSprites.push(node)); + break; + case "SkinnedMeshSprite3D": + node = new SkinnedMeshSprite3D(); + break; + case "SimpleSkinnedMeshSprite3D": + node = new SimpleSkinnedMeshSprite3D(); + break; + case "ShuriKenParticle3D": + node = new ShuriKenParticle3D(); + break; + case "Camera": + node = new Camera(); + break; + case "DirectionLight": + node = new DirectionLight(); + break; + case "PointLight": + node = new PointLight(); + break; + case "SpotLight": + node = new SpotLight(); + break; + case "TrailSprite3D": + node = new TrailSprite3D(); + break; + case "ReflectionProbe": + node = new ReflectionProbe(); + break; + default: + throw new Error("Utils3D:unidentified class type in (.lh) file."); + } + var childData = nodeData.child; + if (childData) { + for (var i = 0, n = childData.length; i < n; i++) { + var child = Scene3DUtils._createSprite3DInstance(childData[i], spriteMap, outBatchSprites); + node.addChild(child); + } + } + spriteMap[nodeData.instanceID] = node; + return node; + } + static _createComponentInstance(nodeData, spriteMap, interactMap) { + var node = spriteMap[nodeData.instanceID]; + node._parse(nodeData.props, spriteMap); + var childData = nodeData.child; + if (childData) { + for (var i = 0, n = childData.length; i < n; i++) + Scene3DUtils._createComponentInstance(childData[i], spriteMap, interactMap); + } + var componentsData = nodeData.components; + if (componentsData) { + for (var j = 0, m = componentsData.length; j < m; j++) { + var data = componentsData[j]; + var clas = Laya.ClassUtils.getRegClass(data.type); + if (clas) { + var component = node.addComponent(clas); + component._parse(data, interactMap); + } + else { + console.warn("Unkown component type."); + } + } + } + } + static _createNodeByJson02(nodeData, outBatchSprites) { + var spriteMap = {}; + var interactMap = { component: [], data: [] }; + var node = Scene3DUtils._createSprite3DInstance(nodeData, spriteMap, outBatchSprites); + Scene3DUtils._createComponentInstance(nodeData, spriteMap, interactMap); + Scene3DUtils._createInteractInstance(interactMap, spriteMap); + return node; + } + static _createInteractInstance(interatMap, spriteMap) { + var components = interatMap.component; + var data = interatMap.data; + for (var i = 0, n = components.length; i < n; i++) { + components[i]._parseInteractive(data[i], spriteMap); + } + } + static _parse(data, propertyParams = null, constructParams = null) { + var json = data.data; + var outBatchSprits = []; + var sprite; + switch (data.version) { + case "LAYAHIERARCHY:02": + sprite = Scene3DUtils._createNodeByJson02(json, outBatchSprits); + break; + default: + sprite = Scene3DUtils._createNodeByJson(json, outBatchSprits); + } + StaticBatchManager.combine(sprite, outBatchSprits); + return sprite; + } + static _parseScene(data, propertyParams = null, constructParams = null) { + var json = data.data; + var outBatchSprits = []; + var scene; + switch (data.version) { + case "LAYASCENE3D:02": + scene = Scene3DUtils._createNodeByJson02(json, outBatchSprits); + break; + default: + scene = Scene3DUtils._createNodeByJson(json, outBatchSprits); + } + StaticBatchManager.combine(null, outBatchSprits); + return scene; + } + static _createNodeByJson(nodeData, outBatchSprites) { + var node; + switch (nodeData.type) { + case "Scene3D": + node = new Scene3D(); + break; + case "Sprite3D": + node = new Sprite3D(); + break; + case "MeshSprite3D": + node = new MeshSprite3D(); + (outBatchSprites && nodeData.props.isStatic) && (outBatchSprites.push(node)); + break; + case "SkinnedMeshSprite3D": + node = new SkinnedMeshSprite3D(); + break; + case "ShuriKenParticle3D": + node = new ShuriKenParticle3D(); + break; + case "Camera": + node = new Camera(); + break; + case "DirectionLight": + node = new DirectionLight(); + break; + case "PointLight": + node = new PointLight(); + break; + case "SpotLight": + node = new SpotLight(); + break; + case "TrailSprite3D": + node = new TrailSprite3D(); + break; + default: + throw new Error("Utils3D:unidentified class type in (.lh) file."); + } + var childData = nodeData.child; + if (childData) { + for (var i = 0, n = childData.length; i < n; i++) { + var child = Scene3DUtils._createNodeByJson(childData[i], outBatchSprites); + node.addChild(child); + } + } + var componentsData = nodeData.components; + if (componentsData) { + for (var j = 0, m = componentsData.length; j < m; j++) { + var data = componentsData[j]; + var clas = Laya.ClassUtils.getRegClass(data.type); + if (clas) { + var component = node.addComponent(clas); + component._parse(data); + } + else { + console.warn("Unkown component type."); + } + } + } + node._parse(nodeData.props, null); + return node; + } + } + + class LoadModelV04 { + static parse(readData, version, mesh, subMeshes) { + LoadModelV04._mesh = mesh; + LoadModelV04._subMeshes = subMeshes; + LoadModelV04._version = version; + LoadModelV04._readData = readData; + LoadModelV04.READ_DATA(); + LoadModelV04.READ_BLOCK(); + LoadModelV04.READ_STRINGS(); + for (var i = 0, n = LoadModelV04._BLOCK.count; i < n; i++) { + LoadModelV04._readData.pos = LoadModelV04._BLOCK.blockStarts[i]; + var index = LoadModelV04._readData.getUint16(); + var blockName = LoadModelV04._strings[index]; + var fn = LoadModelV04["READ_" + blockName]; + if (fn == null) + throw new Error("model file err,no this function:" + index + " " + blockName); + else + fn.call(null); + } + LoadModelV04._strings.length = 0; + LoadModelV04._readData = null; + LoadModelV04._version = null; + LoadModelV04._mesh = null; + LoadModelV04._subMeshes = null; + } + static _readString() { + return LoadModelV04._strings[LoadModelV04._readData.getUint16()]; + } + static READ_DATA() { + LoadModelV04._DATA.offset = LoadModelV04._readData.getUint32(); + LoadModelV04._DATA.size = LoadModelV04._readData.getUint32(); + } + static READ_BLOCK() { + var count = LoadModelV04._BLOCK.count = LoadModelV04._readData.getUint16(); + var blockStarts = LoadModelV04._BLOCK.blockStarts = []; + var blockLengths = LoadModelV04._BLOCK.blockLengths = []; + for (var i = 0; i < count; i++) { + blockStarts.push(LoadModelV04._readData.getUint32()); + blockLengths.push(LoadModelV04._readData.getUint32()); + } + } + static READ_STRINGS() { + var offset = LoadModelV04._readData.getUint32(); + var count = LoadModelV04._readData.getUint16(); + var prePos = LoadModelV04._readData.pos; + LoadModelV04._readData.pos = offset + LoadModelV04._DATA.offset; + for (var i = 0; i < count; i++) + LoadModelV04._strings[i] = LoadModelV04._readData.readUTFString(); + LoadModelV04._readData.pos = prePos; + } + static READ_MESH() { + var gl = Laya.LayaGL.instance; + var name = LoadModelV04._readString(); + var arrayBuffer = LoadModelV04._readData.__getBuffer(); + var i; + var memorySize = 0; + var vertexBufferCount = LoadModelV04._readData.getInt16(); + var offset = LoadModelV04._DATA.offset; + for (i = 0; i < vertexBufferCount; i++) { + var vbStart = offset + LoadModelV04._readData.getUint32(); + var vbLength = LoadModelV04._readData.getUint32(); + var vbArrayBuffer = arrayBuffer.slice(vbStart, vbStart + vbLength); + var vbDatas = new Float32Array(vbArrayBuffer); + var bufferAttribute = LoadModelV04._readString(); + var vertexDeclaration; + switch (LoadModelV04._version) { + case "LAYAMODEL:0301": + case "LAYAMODEL:0400": + vertexDeclaration = VertexMesh.getVertexDeclaration(bufferAttribute); + break; + case "LAYAMODEL:0401": + vertexDeclaration = VertexMesh.getVertexDeclaration(bufferAttribute, false); + break; + default: + throw new Error("LoadModelV03: unknown version."); + } + if (!vertexDeclaration) + throw new Error("LoadModelV03: unknown vertexDeclaration."); + var vertexBuffer = new VertexBuffer3D(vbDatas.length * 4, gl.STATIC_DRAW, true); + vertexBuffer.vertexDeclaration = vertexDeclaration; + vertexBuffer.setData(vbDatas.buffer); + LoadModelV04._mesh._vertexBuffer = vertexBuffer; + LoadModelV04._mesh._vertexCount += vertexBuffer._byteLength / vertexDeclaration.vertexStride; + memorySize += vbDatas.length * 4; + } + var ibStart = offset + LoadModelV04._readData.getUint32(); + var ibLength = LoadModelV04._readData.getUint32(); + var ibDatas = new Uint16Array(arrayBuffer.slice(ibStart, ibStart + ibLength)); + var indexBuffer = new IndexBuffer3D(exports.IndexFormat.UInt16, ibLength / 2, gl.STATIC_DRAW, true); + indexBuffer.setData(ibDatas); + LoadModelV04._mesh._indexBuffer = indexBuffer; + memorySize += indexBuffer.indexCount * 2; + LoadModelV04._mesh._setBuffer(LoadModelV04._mesh._vertexBuffer, indexBuffer); + LoadModelV04._mesh._setCPUMemory(memorySize); + LoadModelV04._mesh._setGPUMemory(memorySize); + var boneNames = LoadModelV04._mesh._boneNames = []; + var boneCount = LoadModelV04._readData.getUint16(); + boneNames.length = boneCount; + for (i = 0; i < boneCount; i++) + boneNames[i] = LoadModelV04._strings[LoadModelV04._readData.getUint16()]; + LoadModelV04._readData.pos += 8; + var bindPoseDataStart = LoadModelV04._readData.getUint32(); + var bindPoseDataLength = LoadModelV04._readData.getUint32(); + var bindPoseDatas = new Float32Array(arrayBuffer.slice(offset + bindPoseDataStart, offset + bindPoseDataStart + bindPoseDataLength)); + var bindPoseFloatCount = bindPoseDatas.length; + var bindPoseBuffer = LoadModelV04._mesh._inverseBindPosesBuffer = new ArrayBuffer(bindPoseFloatCount * 4); + LoadModelV04._mesh._inverseBindPoses = []; + if (bindPoseFloatCount != 0) + LoadModelV04._mesh._instanceBufferStateType = Mesh.MESH_INSTANCEBUFFER_TYPE_SIMPLEANIMATOR; + else + LoadModelV04._mesh._instanceBufferStateType = Mesh.MESH_INSTANCEBUFFER_TYPE_NORMAL; + LoadModelV04._mesh._setInstanceBuffer(LoadModelV04._mesh._instanceBufferStateType); + for (i = 0; i < bindPoseFloatCount; i += 16) { + var inverseGlobalBindPose = new Matrix4x4(bindPoseDatas[i + 0], bindPoseDatas[i + 1], bindPoseDatas[i + 2], bindPoseDatas[i + 3], bindPoseDatas[i + 4], bindPoseDatas[i + 5], bindPoseDatas[i + 6], bindPoseDatas[i + 7], bindPoseDatas[i + 8], bindPoseDatas[i + 9], bindPoseDatas[i + 10], bindPoseDatas[i + 11], bindPoseDatas[i + 12], bindPoseDatas[i + 13], bindPoseDatas[i + 14], bindPoseDatas[i + 15], new Float32Array(bindPoseBuffer, i * 4, 16)); + LoadModelV04._mesh._inverseBindPoses[i / 16] = inverseGlobalBindPose; + } + return true; + } + static READ_SUBMESH() { + var arrayBuffer = LoadModelV04._readData.__getBuffer(); + var subMesh = new SubMesh(LoadModelV04._mesh); + LoadModelV04._readData.getInt16(); + LoadModelV04._readData.getUint32(); + LoadModelV04._readData.getUint32(); + var ibStart = LoadModelV04._readData.getUint32(); + var ibCount = LoadModelV04._readData.getUint32(); + var indexBuffer = LoadModelV04._mesh._indexBuffer; + subMesh._indexBuffer = indexBuffer; + subMesh._setIndexRange(ibStart, ibCount); + var vertexBuffer = LoadModelV04._mesh._vertexBuffer; + subMesh._vertexBuffer = vertexBuffer; + var offset = LoadModelV04._DATA.offset; + var subIndexBufferStart = subMesh._subIndexBufferStart; + var subIndexBufferCount = subMesh._subIndexBufferCount; + var boneIndicesList = subMesh._boneIndicesList; + var drawCount = LoadModelV04._readData.getUint16(); + subIndexBufferStart.length = drawCount; + subIndexBufferCount.length = drawCount; + boneIndicesList.length = drawCount; + var skinnedCache = LoadModelV04._mesh._skinnedMatrixCaches; + var subMeshIndex = LoadModelV04._subMeshes.length; + skinnedCache.length = LoadModelV04._mesh._inverseBindPoses.length; + for (var i = 0; i < drawCount; i++) { + subIndexBufferStart[i] = LoadModelV04._readData.getUint32(); + subIndexBufferCount[i] = LoadModelV04._readData.getUint32(); + var boneDicofs = LoadModelV04._readData.getUint32(); + var boneDicCount = LoadModelV04._readData.getUint32(); + var boneIndices = boneIndicesList[i] = new Uint16Array(arrayBuffer.slice(offset + boneDicofs, offset + boneDicofs + boneDicCount)); + var boneIndexCount = boneIndices.length; + for (var j = 0; j < boneIndexCount; j++) { + var index = boneIndices[j]; + skinnedCache[index] || (skinnedCache[index] = new skinnedMatrixCache(subMeshIndex, i, j)); + } + } + LoadModelV04._subMeshes.push(subMesh); + return true; + } + } + LoadModelV04._BLOCK = { count: 0 }; + LoadModelV04._DATA = { offset: 0, size: 0 }; + LoadModelV04._strings = []; + + class LoadModelV05 { + static parse(readData, version, mesh, subMeshes) { + LoadModelV05._mesh = mesh; + LoadModelV05._subMeshes = subMeshes; + LoadModelV05._version = version; + LoadModelV05._readData = readData; + LoadModelV05.READ_DATA(); + LoadModelV05.READ_BLOCK(); + LoadModelV05.READ_STRINGS(); + for (var i = 0, n = LoadModelV05._BLOCK.count; i < n; i++) { + LoadModelV05._readData.pos = LoadModelV05._BLOCK.blockStarts[i]; + var index = LoadModelV05._readData.getUint16(); + var blockName = LoadModelV05._strings[index]; + var fn = LoadModelV05["READ_" + blockName]; + if (fn == null) + throw new Error("model file err,no this function:" + index + " " + blockName); + else + fn.call(null); + } + LoadModelV05._strings.length = 0; + LoadModelV05._readData = null; + LoadModelV05._version = null; + LoadModelV05._mesh = null; + LoadModelV05._subMeshes = null; + } + static _readString() { + return LoadModelV05._strings[LoadModelV05._readData.getUint16()]; + } + static READ_DATA() { + LoadModelV05._DATA.offset = LoadModelV05._readData.getUint32(); + LoadModelV05._DATA.size = LoadModelV05._readData.getUint32(); + } + static READ_BLOCK() { + var count = LoadModelV05._BLOCK.count = LoadModelV05._readData.getUint16(); + var blockStarts = LoadModelV05._BLOCK.blockStarts = []; + var blockLengths = LoadModelV05._BLOCK.blockLengths = []; + for (var i = 0; i < count; i++) { + blockStarts.push(LoadModelV05._readData.getUint32()); + blockLengths.push(LoadModelV05._readData.getUint32()); + } + } + static READ_STRINGS() { + var offset = LoadModelV05._readData.getUint32(); + var count = LoadModelV05._readData.getUint16(); + var prePos = LoadModelV05._readData.pos; + LoadModelV05._readData.pos = offset + LoadModelV05._DATA.offset; + for (var i = 0; i < count; i++) + LoadModelV05._strings[i] = LoadModelV05._readData.readUTFString(); + LoadModelV05._readData.pos = prePos; + } + static READ_MESH() { + var gl = Laya.LayaGL.instance; + var i; + var memorySize = 0; + var name = LoadModelV05._readString(); + var reader = LoadModelV05._readData; + var arrayBuffer = reader.__getBuffer(); + var vertexBufferCount = reader.getInt16(); + var offset = LoadModelV05._DATA.offset; + for (i = 0; i < vertexBufferCount; i++) { + var vbStart = offset + reader.getUint32(); + var vertexCount = reader.getUint32(); + var vertexFlag = LoadModelV05._readString(); + var vertexDeclaration = VertexMesh.getVertexDeclaration(vertexFlag, false); + var vertexStride = vertexDeclaration.vertexStride; + var vertexData; + var floatData; + var uint8Data; + var subVertexFlags = vertexFlag.split(","); + var subVertexCount = subVertexFlags.length; + var mesh = LoadModelV05._mesh; + switch (LoadModelV05._version) { + case "LAYAMODEL:05": + case "LAYAMODEL:0501": + vertexData = arrayBuffer.slice(vbStart, vbStart + vertexCount * vertexStride); + floatData = new Float32Array(vertexData); + uint8Data = new Uint8Array(vertexData); + break; + case "LAYAMODEL:COMPRESSION_05": + case "LAYAMODEL:COMPRESSION_0501": + vertexData = new ArrayBuffer(vertexStride * vertexCount); + floatData = new Float32Array(vertexData); + uint8Data = new Uint8Array(vertexData); + var lastPosition = reader.pos; + reader.pos = vbStart; + for (var j = 0; j < vertexCount; j++) { + var subOffset; + var verOffset = j * vertexStride; + for (var k = 0; k < subVertexCount; k++) { + switch (subVertexFlags[k]) { + case "POSITION": + subOffset = verOffset / 4; + floatData[subOffset] = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + floatData[subOffset + 1] = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + floatData[subOffset + 2] = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + verOffset += 12; + break; + case "NORMAL": + subOffset = verOffset / 4; + floatData[subOffset] = reader.getUint8() / 127.5 - 1; + floatData[subOffset + 1] = reader.getUint8() / 127.5 - 1; + floatData[subOffset + 2] = reader.getUint8() / 127.5 - 1; + verOffset += 12; + break; + case "COLOR": + subOffset = verOffset / 4; + floatData[subOffset] = reader.getUint8() / 255; + floatData[subOffset + 1] = reader.getUint8() / 255; + floatData[subOffset + 2] = reader.getUint8() / 255; + floatData[subOffset + 3] = reader.getUint8() / 255; + verOffset += 16; + break; + case "UV": + subOffset = verOffset / 4; + floatData[subOffset] = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + floatData[subOffset + 1] = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + verOffset += 8; + break; + case "UV1": + subOffset = verOffset / 4; + floatData[subOffset] = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + floatData[subOffset + 1] = Laya.HalfFloatUtils.convertToNumber(reader.getUint16()); + verOffset += 8; + break; + case "BLENDWEIGHT": + subOffset = verOffset / 4; + floatData[subOffset] = reader.getUint8() / 255; + floatData[subOffset + 1] = reader.getUint8() / 255; + floatData[subOffset + 2] = reader.getUint8() / 255; + floatData[subOffset + 3] = reader.getUint8() / 255; + verOffset += 16; + break; + case "BLENDINDICES": + uint8Data[verOffset] = reader.getUint8(); + uint8Data[verOffset + 1] = reader.getUint8(); + uint8Data[verOffset + 2] = reader.getUint8(); + uint8Data[verOffset + 3] = reader.getUint8(); + verOffset += 4; + break; + case "TANGENT": + subOffset = verOffset / 4; + floatData[subOffset] = reader.getUint8() / 127.5 - 1; + floatData[subOffset + 1] = reader.getUint8() / 127.5 - 1; + floatData[subOffset + 2] = reader.getUint8() / 127.5 - 1; + floatData[subOffset + 3] = reader.getUint8() / 127.5 - 1; + verOffset += 16; + break; + } + } + } + reader.pos = lastPosition; + break; + } + var vertexBuffer = new VertexBuffer3D(vertexData.byteLength, gl.STATIC_DRAW, true); + vertexBuffer.vertexDeclaration = vertexDeclaration; + vertexBuffer.setData(vertexData); + var vertexCount = vertexBuffer._byteLength / vertexDeclaration.vertexStride; + if (vertexCount > 65535) + mesh._indexFormat = exports.IndexFormat.UInt32; + else + mesh._indexFormat = exports.IndexFormat.UInt16; + mesh._vertexBuffer = vertexBuffer; + mesh._vertexCount += vertexCount; + memorySize += floatData.length * 4; + } + var ibStart = offset + reader.getUint32(); + var ibLength = reader.getUint32(); + var ibDatas; + if (mesh.indexFormat == exports.IndexFormat.UInt32) + ibDatas = new Uint32Array(arrayBuffer.slice(ibStart, ibStart + ibLength)); + else + ibDatas = new Uint16Array(arrayBuffer.slice(ibStart, ibStart + ibLength)); + var indexBuffer = new IndexBuffer3D(mesh.indexFormat, ibDatas.length, gl.STATIC_DRAW, true); + indexBuffer.setData(ibDatas); + mesh._indexBuffer = indexBuffer; + mesh._setBuffer(mesh._vertexBuffer, indexBuffer); + memorySize += indexBuffer.indexCount * 2; + mesh._setCPUMemory(memorySize); + mesh._setGPUMemory(memorySize); + if (LoadModelV05._version == "LAYAMODEL:0501" || LoadModelV05._version == "LAYAMODEL:COMPRESSION_0501") { + var bounds = mesh.bounds; + var min = bounds.getMin(); + var max = bounds.getMax(); + min.setValue(reader.getFloat32(), reader.getFloat32(), reader.getFloat32()); + max.setValue(reader.getFloat32(), reader.getFloat32(), reader.getFloat32()); + bounds.setMin(min); + bounds.setMax(max); + mesh.bounds = bounds; + } + var boneNames = mesh._boneNames = []; + var boneCount = reader.getUint16(); + boneNames.length = boneCount; + for (i = 0; i < boneCount; i++) + boneNames[i] = LoadModelV05._strings[reader.getUint16()]; + var bindPoseDataStart = reader.getUint32(); + var bindPoseDataLength = reader.getUint32(); + var bindPoseDatas = new Float32Array(arrayBuffer.slice(offset + bindPoseDataStart, offset + bindPoseDataStart + bindPoseDataLength)); + var bindPoseFloatCount = bindPoseDatas.length; + var bindPoseBuffer = mesh._inverseBindPosesBuffer = new ArrayBuffer(bindPoseFloatCount * 4); + mesh._inverseBindPoses = []; + if (bindPoseFloatCount != 0) + mesh._instanceBufferStateType = Mesh.MESH_INSTANCEBUFFER_TYPE_SIMPLEANIMATOR; + else + mesh._instanceBufferStateType = Mesh.MESH_INSTANCEBUFFER_TYPE_NORMAL; + mesh._setInstanceBuffer(mesh._instanceBufferStateType); + for (i = 0; i < bindPoseFloatCount; i += 16) { + var inverseGlobalBindPose = new Matrix4x4(bindPoseDatas[i + 0], bindPoseDatas[i + 1], bindPoseDatas[i + 2], bindPoseDatas[i + 3], bindPoseDatas[i + 4], bindPoseDatas[i + 5], bindPoseDatas[i + 6], bindPoseDatas[i + 7], bindPoseDatas[i + 8], bindPoseDatas[i + 9], bindPoseDatas[i + 10], bindPoseDatas[i + 11], bindPoseDatas[i + 12], bindPoseDatas[i + 13], bindPoseDatas[i + 14], bindPoseDatas[i + 15], new Float32Array(bindPoseBuffer, i * 4, 16)); + mesh._inverseBindPoses[i / 16] = inverseGlobalBindPose; + } + return true; + } + static READ_SUBMESH() { + var reader = LoadModelV05._readData; + var arrayBuffer = reader.__getBuffer(); + var subMesh = new SubMesh(LoadModelV05._mesh); + reader.getInt16(); + var ibStart = reader.getUint32(); + var ibCount = reader.getUint32(); + var indexBuffer = LoadModelV05._mesh._indexBuffer; + subMesh._indexBuffer = indexBuffer; + subMesh._setIndexRange(ibStart, ibCount); + var vertexBuffer = LoadModelV05._mesh._vertexBuffer; + subMesh._vertexBuffer = vertexBuffer; + var offset = LoadModelV05._DATA.offset; + var subIndexBufferStart = subMesh._subIndexBufferStart; + var subIndexBufferCount = subMesh._subIndexBufferCount; + var boneIndicesList = subMesh._boneIndicesList; + var drawCount = reader.getUint16(); + subIndexBufferStart.length = drawCount; + subIndexBufferCount.length = drawCount; + boneIndicesList.length = drawCount; + var skinnedCache = LoadModelV05._mesh._skinnedMatrixCaches; + var subMeshIndex = LoadModelV05._subMeshes.length; + skinnedCache.length = LoadModelV05._mesh._inverseBindPoses.length; + for (var i = 0; i < drawCount; i++) { + subIndexBufferStart[i] = reader.getUint32(); + subIndexBufferCount[i] = reader.getUint32(); + var boneDicofs = reader.getUint32(); + var boneDicCount = reader.getUint32(); + var boneIndices = boneIndicesList[i] = new Uint16Array(arrayBuffer.slice(offset + boneDicofs, offset + boneDicofs + boneDicCount)); + for (var j = 0, m = boneIndices.length; j < m; j++) { + var index = boneIndices[j]; + skinnedCache[index] || (skinnedCache[index] = new skinnedMatrixCache(subMeshIndex, i, j)); + } + } + LoadModelV05._subMeshes.push(subMesh); + return true; + } + } + LoadModelV05._BLOCK = { count: 0 }; + LoadModelV05._DATA = { offset: 0, size: 0 }; + LoadModelV05._strings = []; + + class MeshReader { + static _parse(data, propertyParams = null, constructParams = null) { + var mesh = new Mesh(); + MeshReader.read(data, mesh, mesh._subMeshes); + return mesh; + } + static read(data, mesh, subMeshes) { + var readData = new Laya.Byte(data); + readData.pos = 0; + var version = readData.readUTFString(); + switch (version) { + case "LAYAMODEL:0301": + case "LAYAMODEL:0400": + case "LAYAMODEL:0401": + LoadModelV04.parse(readData, version, mesh, subMeshes); + break; + case "LAYAMODEL:05": + case "LAYAMODEL:COMPRESSION_05": + case "LAYAMODEL:0501": + case "LAYAMODEL:COMPRESSION_0501": + LoadModelV05.parse(readData, version, mesh, subMeshes); + break; + default: + throw new Error("MeshReader: unknown mesh version."); + } + mesh._setSubMeshes(subMeshes); + if (version != "LAYAMODEL:0501" && version != "LAYAMODEL:COMPRESSION_0501") + mesh.calculateBounds(); + } + } + + var SkyPanoramicFS = "#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#define PI 3.14159265359\r\n#include \"Lighting.glsl\";\r\n\r\nuniform sampler2D u_Texture;\r\nuniform vec4 u_TextureHDRParams;\r\nuniform vec4 u_TintColor;\r\n\r\nvarying vec3 v_Texcoord;\r\nvarying vec2 v_Image180ScaleAndCutoff;\r\nvarying vec4 v_Layout3DScaleAndOffset;\r\n\r\nvec2 ToRadialCoords(vec3 coords)\r\n{\r\n\tvec3 normalizedCoords = normalize(coords);\r\n\tfloat latitude = acos(normalizedCoords.y);\r\n\tfloat longitude = atan(normalizedCoords.z,normalizedCoords.x);\r\n\tvec2 sphereCoords = vec2(longitude, latitude) * vec2(0.5/PI, 1.0/PI);\r\n\treturn vec2(0.5,1.0) - sphereCoords;\r\n}\r\n\r\n\r\nvoid main()\r\n{\t\r\n\tvec2 tc = ToRadialCoords(v_Texcoord);\r\n\tif (tc.x > v_Image180ScaleAndCutoff.y)\r\n\t\tgl_FragColor=vec4(0,0,0,1);\r\n\ttc.x = mod(tc.x*v_Image180ScaleAndCutoff.x, 1.0);\r\n\ttc = (tc + v_Layout3DScaleAndOffset.xy) * v_Layout3DScaleAndOffset.zw;\r\n\r\n\tmediump vec4 tex = texture2D (u_Texture, tc);\r\n\tmediump vec3 c = decodeHDR (tex, u_TextureHDRParams.x);\r\n\tc = c * u_TintColor.rgb * 2.0;//Gamma Space is 2.0,linear space is 4.59479380\r\n\tgl_FragColor=vec4(c, 1.0);\r\n}\r\n\r\n"; + + var SkyPanoramicVS = "#include \"Lighting.glsl\";\r\n\r\n#define PI 3.14159265359\r\n\r\nattribute vec4 a_Position;\r\n\r\nuniform mat4 u_ViewProjection;\r\nuniform float u_Rotation;\r\n\r\nvarying vec3 v_Texcoord;\r\nvarying vec2 v_Image180ScaleAndCutoff;\r\nvarying vec4 v_Layout3DScaleAndOffset;\r\n\r\nvec4 rotateAroundYInDegrees (vec4 vertex, float degrees)\r\n{\r\n\tfloat angle = degrees * PI / 180.0;\r\n\tfloat sina=sin(angle);\r\n\tfloat cosa=cos(angle);\r\n\tmat2 m = mat2(cosa, -sina, sina, cosa);\r\n\treturn vec4(m*vertex.xz, vertex.yw).xzyw;\r\n}\r\n\r\n\t\t\r\nvoid main()\r\n{\r\n\tvec4 position = rotateAroundYInDegrees(a_Position, u_Rotation);\r\n\tgl_Position = u_ViewProjection*position;\r\n\r\n\tv_Texcoord=vec3(-a_Position.x,-a_Position.y,a_Position.z);// NOTE: -a_Position.x convert coords system\r\n\r\n\t// Calculate constant horizontal scale and cutoff for 180 (vs 360) image type\r\n\tv_Image180ScaleAndCutoff = vec2(1.0, 1.0);// 360 degree mode\r\n\r\n\t// Calculate constant scale and offset for 3D layouts\r\n\tv_Layout3DScaleAndOffset = vec4(0,0,1,1);\r\n}\r\n"; + + class SkyPanoramicMaterial extends Material { + constructor() { + super(); + this._exposure = 1.0; + this._textureDecodeFormat = Laya.TextureDecodeFormat.Normal; + this._textureHDRParams = new Vector4(1.0, 0.0, 0.0, 1.0); + this.setShaderName("SkyPanoramic"); + var shaderValues = this._shaderValues; + shaderValues.setVector(SkyPanoramicMaterial.TINTCOLOR, new Vector4(0.5, 0.5, 0.5, 0.5)); + shaderValues.setNumber(SkyPanoramicMaterial.ROTATION, 0.0); + shaderValues.setVector(SkyPanoramicMaterial.TEXTURE_HDR_PARAMS, this._textureHDRParams); + } + static __init__() { + var attributeMap = { + 'a_Position': VertexMesh.MESH_POSITION0 + }; + var uniformMap = { + 'u_TintColor': Shader3D.PERIOD_MATERIAL, + 'u_TextureHDRParams': Shader3D.PERIOD_MATERIAL, + 'u_Rotation': Shader3D.PERIOD_MATERIAL, + 'u_Texture': Shader3D.PERIOD_MATERIAL, + 'u_ViewProjection': Shader3D.PERIOD_CAMERA + }; + var shader = Shader3D.add("SkyPanoramic"); + var subShader = new SubShader(attributeMap, uniformMap); + shader.addSubShader(subShader); + subShader.addShaderPass(SkyPanoramicVS, SkyPanoramicFS); + } + get tintColor() { + return this._shaderValues.getVector(SkyPanoramicMaterial.TINTCOLOR); + } + set tintColor(value) { + this._shaderValues.setVector(SkyPanoramicMaterial.TINTCOLOR, value); + } + get exposure() { + return this._exposure; + } + set exposure(value) { + if (this._exposure !== value) { + this._exposure = value; + if (this._textureDecodeFormat == Laya.TextureDecodeFormat.RGBM) + this._textureHDRParams.x = value * Laya.BaseTexture._rgbmRange; + else + this._textureHDRParams.x = value; + } + } + get rotation() { + return this._shaderValues.getNumber(SkyPanoramicMaterial.ROTATION); + } + set rotation(value) { + this._shaderValues.setNumber(SkyPanoramicMaterial.ROTATION, value); + } + get panoramicTexture() { + return this._shaderValues.getTexture(SkyPanoramicMaterial.TEXTURE); + } + set panoramicTexture(value) { + this._shaderValues.setTexture(SkyPanoramicMaterial.TEXTURE, value); + } + get panoramicTextureDecodeFormat() { + return this._textureDecodeFormat; + } + set panoramicTextureDecodeFormat(value) { + if (this._textureDecodeFormat !== value) { + this._textureDecodeFormat = value; + if (value == Laya.TextureDecodeFormat.RGBM) + this._textureHDRParams.x = this._exposure * Laya.BaseTexture._rgbmRange; + else + this._textureHDRParams.x = this._exposure; + } + } + } + SkyPanoramicMaterial.TINTCOLOR = Shader3D.propertyNameToID("u_TintColor"); + SkyPanoramicMaterial.EXPOSURE = Shader3D.propertyNameToID("u_Exposure"); + SkyPanoramicMaterial.ROTATION = Shader3D.propertyNameToID("u_Rotation"); + SkyPanoramicMaterial.TEXTURE = Shader3D.propertyNameToID("u_Texture"); + SkyPanoramicMaterial.TEXTURE_HDR_PARAMS = Shader3D.propertyNameToID("u_TextureHDRParams"); + + class Laya3D { + constructor() { + } + static get enablePhysics() { + return Physics3D._enablePhysics; + } + static _cancelLoadByUrl(url) { + Laya.Laya.loader.cancelLoadByUrl(url); + Laya3D._innerFirstLevelLoaderManager.cancelLoadByUrl(url); + Laya3D._innerSecondLevelLoaderManager.cancelLoadByUrl(url); + Laya3D._innerThirdLevelLoaderManager.cancelLoadByUrl(url); + Laya3D._innerFourthLevelLoaderManager.cancelLoadByUrl(url); + } + static _changeWebGLSize(width, height) { + Laya.WebGL.onStageResize(width, height); + RenderContext3D.clientWidth = width; + RenderContext3D.clientHeight = height; + } + static __init__(width, height, config) { + Laya.Config.isAntialias = config.isAntialias; + Laya.Config.isAlpha = config.isAlpha; + Laya.Config.premultipliedAlpha = config.premultipliedAlpha; + Laya.Config.isStencil = config.isStencil; + if (!Laya.WebGL.enable()) { + alert("Laya3D init error,must support webGL!"); + return; + } + Laya.RunDriver.changeWebGLSize = Laya3D._changeWebGLSize; + Laya.Render.is3DMode = true; + Laya.Laya.init(width, height); + if (!Laya.Render.supportWebGLPlusRendering) { + Laya.LayaGL.instance = Laya.WebGLContext.mainContext; + Laya.LayaGL.instance.createCommandEncoder = function (reserveSize = 128, adjustSize = 64, isSyncToRenderThread = false) { + return new Laya.CommandEncoder(this, reserveSize, adjustSize, isSyncToRenderThread); + }; + } + config._multiLighting = config.enableMultiLight && Laya.SystemUtils.supportTextureFormat(Laya.TextureFormat.R32G32B32A32); + ILaya3D.Shader3D = Shader3D; + ILaya3D.Scene3D = Scene3D; + ILaya3D.MeshRenderStaticBatchManager = MeshRenderStaticBatchManager; + ILaya3D.MeshRenderDynamicBatchManager = MeshRenderDynamicBatchManager; + ILaya3D.SubMeshDynamicBatch = SubMeshDynamicBatch; + ILaya3D.Laya3D = Laya3D; + ILaya3D.Matrix4x4 = Matrix4x4; + ILaya3D.Physics3D = Physics3D; + ILaya3D.ShadowLightType = exports.ShadowLightType; + ILaya3D.Camera = Camera; + ILaya3D.CommandBuffer = CommandBuffer; + ILaya3D.RenderElement = RenderElement; + ILaya3D.SubMeshRenderElement = SubMeshRenderElement; + Laya3D.enableNative3D(); + if (config.isUseCannonPhysicsEngine) + Physics3D.__cannoninit__(); + Physics3D.__bulletinit__(); + VertexElementFormat.__init__(); + VertexMesh.__init__(); + VertexShurikenParticleBillboard.__init__(); + VertexShurikenParticleMesh.__init__(); + VertexPositionTexture0.__init__(); + VertexTrail.__init__(); + VertexPositionTerrain.__init__(); + PixelLineVertex.__init__(); + SubMeshInstanceBatch.__init__(); + SubMeshDynamicBatch.__init__(); + ShaderInit3D.__init__(); + ShadowUtils.init(); + PBRMaterial.__init__(); + PBRStandardMaterial.__init__(); + PBRSpecularMaterial.__init__(); + SkyPanoramicMaterial.__init__(); + Mesh.__init__(); + PrimitiveMesh.__init__(); + Sprite3D.__init__(); + RenderableSprite3D.__init__(); + MeshSprite3D.__init__(); + SkinnedMeshSprite3D.__init__(); + SimpleSkinnedMeshSprite3D.__init__(); + ShuriKenParticle3D.__init__(); + TrailSprite3D.__init__(); + PostProcess.__init__(); + Scene3D.__init__(); + MeshRenderStaticBatchManager.__init__(); + Material.__initDefine__(); + BaseMaterial.__initDefine__(); + BlinnPhongMaterial.__initDefine__(); + SkyProceduralMaterial.__initDefine__(); + UnlitMaterial.__initDefine__(); + TrailMaterial.__initDefine__(); + EffectMaterial.__initDefine__(); + WaterPrimaryMaterial.__initDefine__(); + ShurikenParticleMaterial.__initDefine__(); + ExtendTerrainMaterial.__initDefine__(); + PixelLineMaterial.__initDefine__(); + SkyBoxMaterial.__initDefine__(); + Command.__init__(); + Laya.ClassUtils.regClass("Laya.SkyPanoramicMaterial", SkyPanoramicMaterial); + Laya.ClassUtils.regClass("Laya.EffectMaterial", EffectMaterial); + Laya.ClassUtils.regClass("Laya.UnlitMaterial", UnlitMaterial); + Laya.ClassUtils.regClass("Laya.BlinnPhongMaterial", BlinnPhongMaterial); + Laya.ClassUtils.regClass("Laya.SkyProceduralMaterial", SkyProceduralMaterial); + Laya.ClassUtils.regClass("Laya.PBRStandardMaterial", PBRStandardMaterial); + Laya.ClassUtils.regClass("Laya.PBRSpecularMaterial", PBRSpecularMaterial); + Laya.ClassUtils.regClass("Laya.SkyBoxMaterial", SkyBoxMaterial); + Laya.ClassUtils.regClass("Laya.WaterPrimaryMaterial", WaterPrimaryMaterial); + Laya.ClassUtils.regClass("Laya.ExtendTerrainMaterial", ExtendTerrainMaterial); + Laya.ClassUtils.regClass("Laya.ShurikenParticleMaterial", ShurikenParticleMaterial); + Laya.ClassUtils.regClass("Laya.TrailMaterial", TrailMaterial); + Laya.ClassUtils.regClass("Laya.PhysicsCollider", Laya.PhysicsCollider); + Laya.ClassUtils.regClass("Laya.Rigidbody3D", Laya.Rigidbody3D); + Laya.ClassUtils.regClass("Laya.CharacterController", Laya.CharacterController); + Laya.ClassUtils.regClass("Laya.Animator", Animator); + Laya.ClassUtils.regClass("PhysicsCollider", Laya.PhysicsCollider); + Laya.ClassUtils.regClass("CharacterController", Laya.CharacterController); + Laya.ClassUtils.regClass("Animator", Animator); + Laya.ClassUtils.regClass("Rigidbody3D", Laya.Rigidbody3D); + Laya.ClassUtils.regClass("FixedConstraint", Laya.FixedConstraint); + Laya.ClassUtils.regClass("ConfigurableConstraint", Laya.ConfigurableConstraint); + PixelLineMaterial.defaultMaterial = new PixelLineMaterial(); + BlinnPhongMaterial.defaultMaterial = new BlinnPhongMaterial(); + EffectMaterial.defaultMaterial = new EffectMaterial(); + UnlitMaterial.defaultMaterial = new UnlitMaterial(); + ShurikenParticleMaterial.defaultMaterial = new ShurikenParticleMaterial(); + TrailMaterial.defaultMaterial = new TrailMaterial(); + SkyProceduralMaterial.defaultMaterial = new SkyProceduralMaterial(); + SkyBoxMaterial.defaultMaterial = new SkyBoxMaterial(); + WaterPrimaryMaterial.defaultMaterial = new WaterPrimaryMaterial(); + PixelLineMaterial.defaultMaterial.lock = true; + BlinnPhongMaterial.defaultMaterial.lock = true; + EffectMaterial.defaultMaterial.lock = true; + UnlitMaterial.defaultMaterial.lock = true; + ShurikenParticleMaterial.defaultMaterial.lock = true; + TrailMaterial.defaultMaterial.lock = true; + SkyProceduralMaterial.defaultMaterial.lock = true; + SkyBoxMaterial.defaultMaterial.lock = true; + WaterPrimaryMaterial.defaultMaterial.lock = true; + Laya.Texture2D.__init__(); + TextureCube.__init__(); + SkyBox.__init__(); + SkyDome.__init__(); + ScreenQuad.__init__(); + ScreenTriangle.__init__(); + FrustumCulling.__init__(); + Laya.HalfFloatUtils.__init__(); + var createMap = Laya.LoaderManager.createMap; + createMap["lh"] = [Laya3D.HIERARCHY, Scene3DUtils._parse]; + createMap["ls"] = [Laya3D.HIERARCHY, Scene3DUtils._parseScene]; + createMap["lm"] = [Laya3D.MESH, MeshReader._parse]; + createMap["lmat"] = [Laya3D.MATERIAL, Material._parse]; + createMap["jpg"] = [Laya3D.TEXTURE2D, Laya.Texture2D._parse]; + createMap["jpeg"] = [Laya3D.TEXTURE2D, Laya.Texture2D._parse]; + createMap["bmp"] = [Laya3D.TEXTURE2D, Laya.Texture2D._parse]; + createMap["gif"] = [Laya3D.TEXTURE2D, Laya.Texture2D._parse]; + createMap["png"] = [Laya3D.TEXTURE2D, Laya.Texture2D._parse]; + createMap["dds"] = [Laya3D.TEXTURE2D, Laya.Texture2D._parse]; + createMap["ktx"] = [Laya3D.TEXTURE2D, Laya.Texture2D._parse]; + createMap["pvr"] = [Laya3D.TEXTURE2D, Laya.Texture2D._parse]; + createMap["lani"] = [Laya3D.ANIMATIONCLIP, AnimationClip._parse]; + createMap["lav"] = [Laya3D.AVATAR, Avatar._parse]; + createMap["ltc"] = [Laya3D.TEXTURECUBE, TextureCube._parse]; + createMap["ltcb"] = [Laya3D.TEXTURECUBEBIN, TextureCube._parseBin]; + createMap["ltcb.ls"] = [Laya3D.TEXTURECUBEBIN, TextureCube._parseBin]; + createMap["lanit.ls"] = [Laya3D.TEXTURE2D, Laya.Texture2D._SimpleAnimatorTextureParse]; + var parserMap = Laya.Loader.parserMap; + parserMap[Laya3D.HIERARCHY] = Laya3D._loadHierarchy; + parserMap[Laya3D.MESH] = Laya3D._loadMesh; + parserMap[Laya3D.MATERIAL] = Laya3D._loadMaterial; + parserMap[Laya3D.TEXTURECUBE] = Laya3D._loadTextureCube; + parserMap[Laya3D.TEXTURECUBEBIN] = Laya3D._loadTextureCubeBin; + parserMap[Laya3D.TEXTURE2D] = Laya3D._loadTexture2D; + parserMap[Laya3D.ANIMATIONCLIP] = Laya3D._loadAnimationClip; + parserMap[Laya3D.AVATAR] = Laya3D._loadAvatar; + parserMap[Laya3D.SIMPLEANIMATORBIN] = Laya3D._loadSimpleAnimator; + Laya3D._innerFirstLevelLoaderManager.on(Laya.Event.ERROR, null, Laya3D._eventLoadManagerError); + Laya3D._innerSecondLevelLoaderManager.on(Laya.Event.ERROR, null, Laya3D._eventLoadManagerError); + Laya3D._innerThirdLevelLoaderManager.on(Laya.Event.ERROR, null, Laya3D._eventLoadManagerError); + Laya3D._innerFourthLevelLoaderManager.on(Laya.Event.ERROR, null, Laya3D._eventLoadManagerError); + } + static enableNative3D() { + var shaderData = ShaderData; + var shader3D = ShaderInstance; + if (Laya.Render.supportWebGLPlusRendering) { + shaderData.prototype._initData = shaderData.prototype._initDataForNative; + shaderData.prototype.setBool = shaderData.prototype.setBoolForNative; + shaderData.prototype.getBool = shaderData.prototype.getBoolForNative; + shaderData.prototype.setInt = shaderData.prototype.setIntForNative; + shaderData.prototype.getInt = shaderData.prototype.getIntForNative; + shaderData.prototype.setNumber = shaderData.prototype.setNumberForNative; + shaderData.prototype.getNumber = shaderData.prototype.getNumberForNative; + shaderData.prototype.setVector = shaderData.prototype.setVectorForNative; + shaderData.prototype.getVector = shaderData.prototype.getVectorForNative; + shaderData.prototype.setVector2 = shaderData.prototype.setVector2ForNative; + shaderData.prototype.getVector2 = shaderData.prototype.getVector2ForNative; + shaderData.prototype.setVector3 = shaderData.prototype.setVector3ForNative; + shaderData.prototype.getVector3 = shaderData.prototype.getVector3ForNative; + shaderData.prototype.setQuaternion = shaderData.prototype.setQuaternionForNative; + shaderData.prototype.getQuaternion = shaderData.prototype.getQuaternionForNative; + shaderData.prototype.setMatrix4x4 = shaderData.prototype.setMatrix4x4ForNative; + shaderData.prototype.getMatrix4x4 = shaderData.prototype.getMatrix4x4ForNative; + shaderData.prototype.setBuffer = shaderData.prototype.setBufferForNative; + shaderData.prototype.getBuffer = shaderData.prototype.getBufferForNative; + shaderData.prototype.setTexture = shaderData.prototype.setTextureForNative; + shaderData.prototype.getTexture = shaderData.prototype.getTextureForNative; + shaderData.prototype.setAttribute = shaderData.prototype.setAttributeForNative; + shaderData.prototype.getAttribute = shaderData.prototype.getAttributeForNative; + shaderData.prototype.cloneTo = shaderData.prototype.cloneToForNative; + shaderData.prototype.getData = shaderData.prototype.getDataForNative; + shader3D.prototype._uniformMatrix2fv = shader3D.prototype._uniformMatrix2fvForNative; + shader3D.prototype._uniformMatrix3fv = shader3D.prototype._uniformMatrix3fvForNative; + shader3D.prototype._uniformMatrix4fv = shader3D.prototype._uniformMatrix4fvForNative; + Laya.LayaGLRunner.uploadShaderUniforms = Laya.LayaGLRunner.uploadShaderUniformsForNative; + } + } + static formatRelativePath(base, value) { + var path; + path = base + value; + var char1 = value.charAt(0); + if (char1 === ".") { + var parts = path.split("/"); + for (var i = 0, len = parts.length; i < len; i++) { + if (parts[i] == '..') { + var index = i - 1; + if (index > 0 && parts[index] !== '..') { + parts.splice(index, 2); + i -= 2; + } + } + } + path = parts.join('/'); + } + return path; + } + static _endLoad(loader, content = null, subResous = null) { + if (subResous) { + for (var i = 0, n = subResous.length; i < n; i++) { + var resou = Laya.Loader.getRes(subResous[i]); + (resou) && (resou._removeReference()); + } + } + loader.endLoad(content); + } + static _eventLoadManagerError(msg) { + Laya.Laya.loader.event(Laya.Event.ERROR, msg); + } + static _addHierarchyInnerUrls(urls, urlMap, urlVersion, hierarchyBasePath, path, type, constructParams = null, propertyParams = null) { + var formatUrl = Laya3D.formatRelativePath(hierarchyBasePath, path); + (urlVersion) && (formatUrl = formatUrl + urlVersion); + urls.push({ url: formatUrl, type: type, constructParams: constructParams, propertyParams: propertyParams }); + urlMap.push(formatUrl); + return formatUrl; + } + static _getSprite3DHierarchyInnerUrls(node, firstLevelUrls, secondLevelUrls, thirdLevelUrls, fourthLelUrls, subUrls, urlVersion, hierarchyBasePath) { + var i, n; + var props = node.props; + switch (node.type) { + case "Scene3D": + var lightmaps = props.lightmaps; + for (i = 0, n = lightmaps.length; i < n; i++) { + var lightMap = lightmaps[i]; + if (lightMap.path) { + lightMap.path = Laya3D._addHierarchyInnerUrls(fourthLelUrls, subUrls, urlVersion, hierarchyBasePath, lightMap.path, Laya3D.TEXTURE2D, lightMap.constructParams, lightMap.propertyParams); + } + else { + var lightmapColorData = lightMap.color; + lightmapColorData.path = Laya3D._addHierarchyInnerUrls(fourthLelUrls, subUrls, urlVersion, hierarchyBasePath, lightmapColorData.path, Laya3D.TEXTURE2D, lightmapColorData.constructParams, lightmapColorData.propertyParams); + var lightmapDirectionData = lightMap.direction; + if (lightmapDirectionData) + lightmapDirectionData.path = Laya3D._addHierarchyInnerUrls(fourthLelUrls, subUrls, urlVersion, hierarchyBasePath, lightmapDirectionData.path, Laya3D.TEXTURE2D, lightmapDirectionData.constructParams, lightmapDirectionData.propertyParams); + } + } + var reflectionTextureData = props.reflectionTexture; + (reflectionTextureData) && (props.reflection = Laya3D._addHierarchyInnerUrls(thirdLevelUrls, subUrls, urlVersion, hierarchyBasePath, reflectionTextureData, Laya3D.TEXTURECUBE)); + var reflectionData = props.reflection; + (reflectionData) && (props.reflection = Laya3D._addHierarchyInnerUrls(fourthLelUrls, subUrls, urlVersion, hierarchyBasePath, reflectionData, Laya3D.TEXTURECUBEBIN)); + if (props.sky) { + var skyboxMaterial = props.sky.material; + (skyboxMaterial) && (skyboxMaterial.path = Laya3D._addHierarchyInnerUrls(secondLevelUrls, subUrls, urlVersion, hierarchyBasePath, skyboxMaterial.path, Laya3D.MATERIAL)); + } + break; + case "Camera": + var skyboxMatData = props.skyboxMaterial; + (skyboxMatData) && (skyboxMatData.path = Laya3D._addHierarchyInnerUrls(secondLevelUrls, subUrls, urlVersion, hierarchyBasePath, skyboxMatData.path, Laya3D.MATERIAL)); + break; + case "TrailSprite3D": + case "MeshSprite3D": + case "SkinnedMeshSprite3D": + case "SimpleSkinnedMeshSprite3D": + var meshPath = props.meshPath; + (meshPath) && (props.meshPath = Laya3D._addHierarchyInnerUrls(firstLevelUrls, subUrls, urlVersion, hierarchyBasePath, meshPath, Laya3D.MESH)); + var materials = props.materials; + if (materials) + for (i = 0, n = materials.length; i < n; i++) + materials[i].path = Laya3D._addHierarchyInnerUrls(secondLevelUrls, subUrls, urlVersion, hierarchyBasePath, materials[i].path, Laya3D.MATERIAL); + if (node.type == "SimpleSkinnedMeshSprite3D") + if (props.animatorTexture) + props.animatorTexture = Laya3D._addHierarchyInnerUrls(fourthLelUrls, subUrls, urlVersion, hierarchyBasePath, props.animatorTexture, Laya3D.SIMPLEANIMATORBIN); + break; + case "ShuriKenParticle3D": + if (props.main) { + var resources = props.renderer.resources; + var mesh = resources.mesh; + var material = resources.material; + (mesh) && (resources.mesh = Laya3D._addHierarchyInnerUrls(firstLevelUrls, subUrls, urlVersion, hierarchyBasePath, mesh, Laya3D.MESH)); + (material) && (resources.material = Laya3D._addHierarchyInnerUrls(secondLevelUrls, subUrls, urlVersion, hierarchyBasePath, material, Laya3D.MATERIAL)); + } + else { + var parMeshPath = props.meshPath; + (parMeshPath) && (props.meshPath = Laya3D._addHierarchyInnerUrls(firstLevelUrls, subUrls, urlVersion, hierarchyBasePath, parMeshPath, Laya3D.MESH)); + props.material.path = Laya3D._addHierarchyInnerUrls(secondLevelUrls, subUrls, urlVersion, hierarchyBasePath, props.material.path, Laya3D.MATERIAL); + } + break; + case "Terrain": + Laya3D._addHierarchyInnerUrls(fourthLelUrls, subUrls, urlVersion, hierarchyBasePath, props.dataPath, Laya3D.TERRAINRES); + break; + case "ReflectionProbe": + var reflection = props.reflection; + (reflection) && (props.reflection = Laya3D._addHierarchyInnerUrls(firstLevelUrls, subUrls, urlVersion, hierarchyBasePath, reflection, Laya3D.TEXTURECUBEBIN)); + break; + } + var components = node.components; + if (components) { + for (var k = 0, p = components.length; k < p; k++) { + var component = components[k]; + switch (component.type) { + case "Animator": + var avatarPath = component.avatarPath; + var avatarData = component.avatar; + (avatarData) && (avatarData.path = Laya3D._addHierarchyInnerUrls(fourthLelUrls, subUrls, urlVersion, hierarchyBasePath, avatarData.path, Laya3D.AVATAR)); + var clipPaths = component.clipPaths; + if (!clipPaths) { + var layersData = component.layers; + for (i = 0; i < layersData.length; i++) { + var states = layersData[i].states; + for (var j = 0, m = states.length; j < m; j++) { + var clipPath = states[j].clipPath; + (clipPath) && (states[j].clipPath = Laya3D._addHierarchyInnerUrls(fourthLelUrls, subUrls, urlVersion, hierarchyBasePath, clipPath, Laya3D.ANIMATIONCLIP)); + } + } + } + else { + for (i = 0, n = clipPaths.length; i < n; i++) + clipPaths[i] = Laya3D._addHierarchyInnerUrls(fourthLelUrls, subUrls, urlVersion, hierarchyBasePath, clipPaths[i], Laya3D.ANIMATIONCLIP); + } + break; + case "PhysicsCollider": + case "Rigidbody3D": + case "CharacterController": + var shapes = component.shapes; + for (i = 0; i < shapes.length; i++) { + var shape = shapes[i]; + if (shape.type === "MeshColliderShape") { + var mesh = shape.mesh; + (mesh) && (shape.mesh = Laya3D._addHierarchyInnerUrls(firstLevelUrls, subUrls, urlVersion, hierarchyBasePath, mesh, Laya3D.MESH)); + } + } + break; + } + } + } + var children = node.child; + for (i = 0, n = children.length; i < n; i++) + Laya3D._getSprite3DHierarchyInnerUrls(children[i], firstLevelUrls, secondLevelUrls, thirdLevelUrls, fourthLelUrls, subUrls, urlVersion, hierarchyBasePath); + } + static _loadHierarchy(loader) { + loader._originType = loader.type; + loader.on(Laya.Event.LOADED, null, Laya3D._onHierarchylhLoaded, [loader]); + loader.load(loader.url, Laya.Loader.JSON, false, null, true); + } + static _onHierarchylhLoaded(loader, lhData) { + var url = loader.url; + var urlVersion = Utils3D.getURLVerion(url); + var hierarchyBasePath = Laya.URL.getPath(url); + var firstLevUrls = []; + var secondLevUrls = []; + var thirdLevUrls = []; + var forthLevUrls = []; + var subUrls = []; + Laya3D._getSprite3DHierarchyInnerUrls(lhData.data, firstLevUrls, secondLevUrls, thirdLevUrls, forthLevUrls, subUrls, urlVersion, hierarchyBasePath); + var urlCount = firstLevUrls.length + secondLevUrls.length + forthLevUrls.length; + var totalProcessCount = urlCount + 1; + var weight = 1 / totalProcessCount; + Laya3D._onProcessChange(loader, 0, weight, 1.0); + if (forthLevUrls.length > 0) { + var processCeil = urlCount / totalProcessCount; + var processHandler = Laya.Handler.create(null, Laya3D._onProcessChange, [loader, weight, processCeil], false); + Laya3D._innerFourthLevelLoaderManager._create(forthLevUrls, false, Laya.Handler.create(null, Laya3D._onHierarchyInnerForthLevResouLoaded, [loader, processHandler, lhData, subUrls, firstLevUrls, secondLevUrls, thirdLevUrls, weight + processCeil * forthLevUrls.length, processCeil]), processHandler, null, null, null, 1, true); + } + else { + Laya3D._onHierarchyInnerForthLevResouLoaded(loader, null, lhData, subUrls, firstLevUrls, secondLevUrls, thirdLevUrls, weight, processCeil); + } + } + static _onHierarchyInnerForthLevResouLoaded(loader, processHandler, lhData, subUrls, firstLevUrls, secondLevUrls, thirdLevUrls, processOffset, processCeil) { + (processHandler) && (processHandler.recover()); + if (thirdLevUrls.length > 0) { + var process = Laya.Handler.create(null, Laya3D._onProcessChange, [loader, processOffset, processCeil], false); + Laya3D._innerThirdLevelLoaderManager._create(thirdLevUrls, false, Laya.Handler.create(null, Laya3D._onHierarchyInnerThirdLevResouLoaded, [loader, process, lhData, subUrls, firstLevUrls, secondLevUrls, processOffset + processCeil * secondLevUrls.length, processCeil]), processHandler, null, null, null, 1, true); + } + else { + Laya3D._onHierarchyInnerThirdLevResouLoaded(loader, null, lhData, subUrls, firstLevUrls, secondLevUrls, processOffset, processCeil); + } + } + static _onHierarchyInnerThirdLevResouLoaded(loader, processHandler, lhData, subUrls, firstLevUrls, secondLevUrls, processOffset, processCeil) { + (processHandler) && (processHandler.recover()); + if (secondLevUrls.length > 0) { + var process = Laya.Handler.create(null, Laya3D._onProcessChange, [loader, processOffset, processCeil], false); + Laya3D._innerSecondLevelLoaderManager._create(secondLevUrls, false, Laya.Handler.create(null, Laya3D._onHierarchyInnerSecondLevResouLoaded, [loader, process, lhData, subUrls, firstLevUrls, processOffset + processCeil * secondLevUrls.length, processCeil]), processHandler, null, null, null, 1, true); + } + else { + Laya3D._onHierarchyInnerSecondLevResouLoaded(loader, null, lhData, subUrls, firstLevUrls, processOffset, processCeil); + } + } + static _onHierarchyInnerSecondLevResouLoaded(loader, processHandler, lhData, subUrls, firstLevUrls, processOffset, processCeil) { + (processHandler) && (processHandler.recover()); + if (firstLevUrls.length > 0) { + var process = Laya.Handler.create(null, Laya3D._onProcessChange, [loader, processOffset, processCeil], false); + Laya3D._innerFirstLevelLoaderManager._create(firstLevUrls, false, Laya.Handler.create(null, Laya3D._onHierarchyInnerFirstLevResouLoaded, [loader, process, lhData, subUrls]), processHandler, null, null, null, 1, true); + } + else { + Laya3D._onHierarchyInnerFirstLevResouLoaded(loader, null, lhData, subUrls); + } + } + static _onHierarchyInnerFirstLevResouLoaded(loader, processHandler, lhData, subUrls) { + (processHandler) && (processHandler.recover()); + loader._cache = loader._createCache; + var item = lhData.data.type === "Scene3D" ? Scene3DUtils._parseScene(lhData, loader._propertyParams, loader._constructParams) : Scene3DUtils._parse(lhData, loader._propertyParams, loader._constructParams); + Laya3D._endLoad(loader, item, subUrls); + } + static _loadMesh(loader) { + loader.on(Laya.Event.LOADED, null, Laya3D._onMeshLmLoaded, [loader]); + loader.load(loader.url, Laya.Loader.BUFFER, false, null, true); + } + static _onMeshLmLoaded(loader, lmData) { + loader._cache = loader._createCache; + var mesh = MeshReader._parse(lmData, loader._propertyParams, loader._constructParams); + Laya3D._endLoad(loader, mesh); + } + static _loadMaterial(loader) { + loader.on(Laya.Event.LOADED, null, Laya3D._onMaterilLmatLoaded, [loader]); + loader.load(loader.url, Laya.Loader.JSON, false, null, true); + } + static _onMaterilLmatLoaded(loader, lmatData) { + var url = loader.url; + var urlVersion = Utils3D.getURLVerion(url); + var materialBasePath = Laya.URL.getPath(url); + var urls = []; + var subUrls = []; + var customProps = lmatData.customProps; + var formatSubUrl; + var version = lmatData.version; + switch (version) { + case "LAYAMATERIAL:01": + case "LAYAMATERIAL:02": + case "LAYAMATERIAL:03": + var i, n; + var textures = lmatData.props.textures; + if (textures) { + for (i = 0, n = textures.length; i < n; i++) { + var tex2D = textures[i]; + var tex2DPath = tex2D.path; + if (tex2DPath) { + formatSubUrl = Laya3D.formatRelativePath(materialBasePath, tex2DPath); + (urlVersion) && (formatSubUrl = formatSubUrl + urlVersion); + urls.push({ url: formatSubUrl, constructParams: tex2D.constructParams, propertyParams: tex2D.propertyParams }); + subUrls.push(formatSubUrl); + tex2D.path = formatSubUrl; + } + } + } + break; + default: + throw new Error("Laya3D:unkonwn version."); + } + var urlCount = urls.length; + var totalProcessCount = urlCount + 1; + var lmatWeight = 1 / totalProcessCount; + Laya3D._onProcessChange(loader, 0, lmatWeight, 1.0); + if (urlCount > 0) { + var processHandler = Laya.Handler.create(null, Laya3D._onProcessChange, [loader, lmatWeight, urlCount / totalProcessCount], false); + Laya3D._innerFourthLevelLoaderManager._create(urls, false, Laya.Handler.create(null, Laya3D._onMateialTexturesLoaded, [loader, processHandler, lmatData, subUrls]), processHandler, null, null, null, 1, true); + } + else { + Laya3D._onMateialTexturesLoaded(loader, null, lmatData, null); + } + } + static _onMateialTexturesLoaded(loader, processHandler, lmatData, subUrls) { + loader._cache = loader._createCache; + var mat = Material._parse(lmatData, loader._propertyParams, loader._constructParams); + Laya3D._endLoad(loader, mat, subUrls); + (processHandler) && (processHandler.recover()); + } + static _loadAvatar(loader) { + loader.on(Laya.Event.LOADED, null, function (data) { + loader._cache = loader._createCache; + var avatar = Avatar._parse(data, loader._propertyParams, loader._constructParams); + Laya3D._endLoad(loader, avatar); + }); + loader.load(loader.url, Laya.Loader.JSON, false, null, true); + } + static _loadSimpleAnimator(loader) { + loader.on(Laya.Event.LOADED, null, function (data) { + loader._cache = loader._createCache; + var texture = Laya.Texture2D._SimpleAnimatorTextureParse(data, loader._propertyParams, loader._constructParams); + Laya3D._endLoad(loader, texture); + }); + loader.load(loader.url, Laya.Loader.BUFFER, false, null, true); + } + static _loadAnimationClip(loader) { + loader.on(Laya.Event.LOADED, null, function (data) { + loader._cache = loader._createCache; + var clip = AnimationClip._parse(data); + Laya3D._endLoad(loader, clip); + }); + loader.load(loader.url, Laya.Loader.BUFFER, false, null, true); + } + static _loadTexture2D(loader) { + var url = loader.url; + var index = url.lastIndexOf('.') + 1; + var verIndex = url.indexOf('?'); + var endIndex = verIndex == -1 ? url.length : verIndex; + var ext = url.substr(index, endIndex - index); + var type; + switch (ext) { + case "jpg": + case "jpeg": + case "bmp": + case "gif": + case "png": + type = "nativeimage"; + break; + case "dds": + type = Laya.Loader.BUFFER; + break; + case "ktx": + type = Laya.Loader.BUFFER; + (!loader._constructParams) && (loader._constructParams = []); + loader._constructParams[2] = Laya.TextureFormat.KTXTEXTURE; + break; + case "pvr": + type = Laya.Loader.BUFFER; + (!loader._constructParams) && (loader._constructParams = []); + loader._propertyParams[2] = Laya.TextureFormat.PVRTEXTURE; + break; + } + loader.on(Laya.Event.LOADED, null, function (image) { + loader._cache = loader._createCache; + var tex = Laya.Texture2D._parse(image, loader._propertyParams, loader._constructParams); + Laya3D._endLoad(loader, tex); + }); + loader.load(loader.url, type, false, null, true); + } + static _loadTextureCube(loader) { + loader.on(Laya.Event.LOADED, null, Laya3D._onTextureCubeLtcLoaded, [loader]); + loader.load(loader.url, Laya.Loader.JSON, false, null, true); + } + static _loadTextureCubeBin(loader) { + loader.on(Laya.Event.LOADED, null, (data) => { + loader._cache = loader._createCache; + var byte = new Laya.Byte(data); + var version = byte.readUTFString(); + if (version !== "LAYATEXTURECUBE:0000") + throw "Laya3D:unknow version."; + var format = byte.readUint8(); + var mipCount = byte.getUint8(); + var size = byte.readUint16(); + var filterMode = byte.getUint8(); + var warpModeU = byte.getUint8(); + var warpModev = byte.getUint8(); + var anisoLevel = byte.getUint8(); + var cubemap = new TextureCube(size, format, mipCount > 1 ? true : false); + cubemap.filterMode = filterMode; + cubemap.wrapModeU = warpModeU; + cubemap.wrapModeV = warpModev; + cubemap.anisoLevel = anisoLevel; + var pos = byte.pos; + var mipSize = size; + for (var i = 0; i < mipCount; i++) { + var uint8Arrays = new Array(6); + var mipPixelLength = mipSize * mipSize * cubemap._getFormatByteCount(); + for (var j = 0; j < 6; j++) { + uint8Arrays[j] = new Uint8Array(data, pos, mipPixelLength); + pos += mipPixelLength; + } + cubemap.setSixSidePixels(uint8Arrays, i); + mipSize /= 2; + } + Laya3D._endLoad(loader, cubemap); + }); + loader.load(loader.url, Laya.Loader.BUFFER, false, null, true); + } + static _onTextureCubeLtcLoaded(loader, ltcData) { + var ltcBasePath = Laya.URL.getPath(loader.url); + var urls = [Laya3D.formatRelativePath(ltcBasePath, ltcData.front), Laya3D.formatRelativePath(ltcBasePath, ltcData.back), Laya3D.formatRelativePath(ltcBasePath, ltcData.left), Laya3D.formatRelativePath(ltcBasePath, ltcData.right), Laya3D.formatRelativePath(ltcBasePath, ltcData.up), Laya3D.formatRelativePath(ltcBasePath, ltcData.down)]; + var ltcWeight = 1.0 / 7.0; + Laya3D._onProcessChange(loader, 0, ltcWeight, 1.0); + var processHandler = Laya.Handler.create(null, Laya3D._onProcessChange, [loader, ltcWeight, 6 / 7], false); + Laya3D._innerFourthLevelLoaderManager.load(urls, Laya.Handler.create(null, Laya3D._onTextureCubeImagesLoaded, [loader, urls, processHandler]), processHandler, "nativeimage"); + } + static _onTextureCubeImagesLoaded(loader, urls, processHandler) { + var images = new Array(6); + for (var i = 0; i < 6; i++) + images[i] = Laya.Loader.getRes(urls[i]); + loader._cache = loader._createCache; + var tex = TextureCube._parse(images, loader._propertyParams, loader._constructParams); + processHandler.recover(); + for (i = 0; i < 6; i++) + Laya.Loader.clearRes(urls[i]); + Laya3D._endLoad(loader, tex); + } + static _onProcessChange(loader, offset, weight, process) { + process = offset + process * weight; + (process < 1.0) && (loader.event(Laya.Event.PROGRESS, process * 2 / 3 + 1 / 3)); + } + static init(width, height, config = null, compolete = null) { + if (Laya3D._isInit) { + compolete && compolete.run(); + return; + } + Laya3D._isInit = true; + (config) && (config.cloneTo(Config3D._config)); + config = Config3D._config; + FrustumCulling.debugFrustumCulling = config.debugFrustumCulling; + Laya3D._editerEnvironment = config._editerEnvironment; + Scene3D.octreeCulling = config.octreeCulling; + Scene3D.octreeInitialSize = config.octreeInitialSize; + Scene3D.octreeInitialCenter = config.octreeInitialCenter; + Scene3D.octreeMinNodeSize = config.octreeMinNodeSize; + Scene3D.octreeLooseness = config.octreeLooseness; + var physics3D = window.Physics3D; + if (physics3D == null || config.isUseCannonPhysicsEngine) { + Physics3D._enablePhysics = false; + Laya3D.__init__(width, height, config); + compolete && compolete.run(); + } + else { + Physics3D._enablePhysics = true; + physics3D(config.defaultPhysicsMemory * 16, Laya.BulletInteractive._interactive).then(function () { + Laya3D.__init__(width, height, config); + compolete && compolete.run(); + }); + } + } + } + Laya3D.HIERARCHY = "HIERARCHY"; + Laya3D.MESH = "MESH"; + Laya3D.MATERIAL = "MATERIAL"; + Laya3D.TEXTURE2D = "TEXTURE2D"; + Laya3D.TEXTURECUBE = "TEXTURECUBE"; + Laya3D.TEXTURECUBEBIN = "TEXTURECUBEBIN"; + Laya3D.ANIMATIONCLIP = "ANIMATIONCLIP"; + Laya3D.AVATAR = "AVATAR"; + Laya3D.TERRAINHEIGHTDATA = "TERRAINHEIGHTDATA"; + Laya3D.TERRAINRES = "TERRAIN"; + Laya3D.SIMPLEANIMATORBIN = "SIMPLEANIMATOR"; + Laya3D._innerFirstLevelLoaderManager = new Laya.LoaderManager(); + Laya3D._innerSecondLevelLoaderManager = new Laya.LoaderManager(); + Laya3D._innerThirdLevelLoaderManager = new Laya.LoaderManager(); + Laya3D._innerFourthLevelLoaderManager = new Laya.LoaderManager(); + Laya3D._isInit = false; + Laya3D._editerEnvironment = false; + window.Laya3D = Laya3D; + + class CastShadowList extends SingletonList { + constructor() { + super(); + } + add(element) { + var index = element._indexInCastShadowList; + if (index !== -1) + throw "CastShadowList:element has in CastShadowList."; + this._add(element); + element._indexInCastShadowList = this.length++; + } + remove(element) { + var index = element._indexInCastShadowList; + this.length--; + if (index !== this.length) { + var end = this.elements[this.length]; + this.elements[index] = end; + end._indexInCastShadowList = index; + } + element._indexInCastShadowList = -1; + } + } + + class AnimatorStateScript { + constructor() { + } + onStateEnter() { + } + onStateUpdate() { + } + onStateExit() { + } + } + + class Script3D extends Laya.Component { + constructor() { + super(...arguments); + this._indexInPool = -1; + this._enableState = false; + } + get isSingleton() { + return false; + } + _checkProcessTriggers() { + var prototype = Script3D.prototype; + if (this.onTriggerEnter !== prototype.onTriggerEnter) + return true; + if (this.onTriggerStay !== prototype.onTriggerStay) + return true; + if (this.onTriggerExit !== prototype.onTriggerExit) + return true; + return false; + } + _checkProcessCollisions() { + var prototype = Script3D.prototype; + if (this.onCollisionEnter !== prototype.onCollisionEnter) + return true; + if (this.onCollisionStay !== prototype.onCollisionStay) + return true; + if (this.onCollisionExit !== prototype.onCollisionExit) + return true; + return false; + } + _onAwake() { + this.onAwake(); + if (this.onStart !== Script3D.prototype.onStart) + Laya.Laya.startTimer.callLater(this, this.onStart); + } + _onEnable() { + if (this._enableState) + return; + this.owner._scene._addScript(this); + this._enableState = true; + this.onEnable(); + } + _onDisable() { + if (!this._enableState || this._indexInPool == -1) + return; + this.owner._scene._removeScript(this); + this.owner.offAllCaller(this); + this._enableState = false; + this.onDisable(); + } + _onDestroy() { + var scripts = this.owner._scripts; + scripts.splice(scripts.indexOf(this), 1); + var sprite = this.owner; + sprite._needProcessTriggers = false; + for (var i = 0, n = scripts.length; i < n; i++) { + if (scripts[i]._checkProcessTriggers()) { + sprite._needProcessTriggers = true; + break; + } + } + sprite._needProcessCollisions = false; + for (i = 0, n = scripts.length; i < n; i++) { + if (scripts[i]._checkProcessCollisions()) { + sprite._needProcessCollisions = true; + break; + } + } + this.onDestroy(); + } + _isScript() { + return true; + } + _onAdded() { + var sprite = this.owner; + var scripts = sprite._scripts; + scripts || (sprite._scripts = scripts = []); + scripts.push(this); + if (!sprite._needProcessCollisions) + sprite._needProcessCollisions = this._checkProcessCollisions(); + if (!sprite._needProcessTriggers) + sprite._needProcessTriggers = this._checkProcessTriggers(); + } + onAwake() { + } + onEnable() { + } + onStart() { + } + onTriggerEnter(other) { + } + onTriggerStay(other) { + } + onTriggerExit(other) { + } + onCollisionEnter(collision) { + } + onCollisionStay(collision) { + } + onCollisionExit(collision) { + } + onJointBreak() { + } + onMouseDown() { + } + onMouseDrag() { + } + onMouseClick() { + } + onMouseUp() { + } + onMouseEnter() { + } + onMouseOver() { + } + onMouseOut() { + } + onUpdate() { + } + onLateUpdate() { + } + onPreRender() { + } + onPostRender() { + } + onDisable() { + } + onDestroy() { + } + } + + class HeightMap { + constructor(width, height, minHeight, maxHeight) { + this._datas = []; + this._w = width; + this._h = height; + this._minHeight = minHeight; + this._maxHeight = maxHeight; + } + static creatFromMesh(mesh, width, height, outCellSize) { + var vertices = []; + var indexs = []; + var submesheCount = mesh.subMeshCount; + for (var i = 0; i < submesheCount; i++) { + var subMesh = mesh.getSubMesh(i); + var vertexBuffer = subMesh._vertexBuffer; + var verts = vertexBuffer.getFloat32Data(); + var subMeshVertices = []; + for (var j = 0; j < verts.length; j += vertexBuffer.vertexDeclaration.vertexStride / 4) { + var position = new Vector3(verts[j + 0], verts[j + 1], verts[j + 2]); + subMeshVertices.push(position); + } + vertices.push(subMeshVertices); + var ib = subMesh._indexBuffer; + indexs.push(ib.getData()); + } + var bounds = mesh.bounds; + var minX = bounds.getMin().x; + var minZ = bounds.getMin().z; + var maxX = bounds.getMax().x; + var maxZ = bounds.getMax().z; + var minY = bounds.getMin().y; + var maxY = bounds.getMax().y; + var widthSize = maxX - minX; + var heightSize = maxZ - minZ; + var cellWidth = outCellSize.x = widthSize / (width - 1); + var cellHeight = outCellSize.y = heightSize / (height - 1); + var heightMap = new HeightMap(width, height, minY, maxY); + var ray = HeightMap._tempRay; + var rayDir = ray.direction; + rayDir.x = 0; + rayDir.y = -1; + rayDir.z = 0; + const heightOffset = 0.1; + var rayY = maxY + heightOffset; + ray.origin.y = rayY; + for (var h = 0; h < height; h++) { + var posZ = minZ + h * cellHeight; + heightMap._datas[h] = []; + for (var w = 0; w < width; w++) { + var posX = minX + w * cellWidth; + var rayOri = ray.origin; + rayOri.x = posX; + rayOri.z = posZ; + var closestIntersection = HeightMap._getPosition(ray, vertices, indexs); + heightMap._datas[h][w] = (closestIntersection === Number.MAX_VALUE) ? NaN : rayY - closestIntersection; + } + } + return heightMap; + } + static createFromImage(texture, minHeight, maxHeight) { + var textureWidth = texture.width; + var textureHeight = texture.height; + var heightMap = new HeightMap(textureWidth, textureHeight, minHeight, maxHeight); + var compressionRatio = (maxHeight - minHeight) / 254; + var pixelsInfo = texture.getPixels(); + var index = 0; + for (var h = 0; h < textureHeight; h++) { + var colDatas = heightMap._datas[h] = []; + for (var w = 0; w < textureWidth; w++) { + var r = pixelsInfo[index++]; + var g = pixelsInfo[index++]; + var b = pixelsInfo[index++]; + var a = pixelsInfo[index++]; + if (r == 255 && g == 255 && b == 255 && a == 255) + colDatas[w] = NaN; + else { + colDatas[w] = (r + g + b) / 3 * compressionRatio + minHeight; + } + } + } + return heightMap; + } + static _getPosition(ray, vertices, indexs) { + var closestIntersection = Number.MAX_VALUE; + for (var i = 0; i < vertices.length; i++) { + var subMeshVertices = vertices[i]; + var subMeshIndexes = indexs[i]; + for (var j = 0; j < subMeshIndexes.length; j += 3) { + var vertex1 = subMeshVertices[subMeshIndexes[j + 0]]; + var vertex2 = subMeshVertices[subMeshIndexes[j + 1]]; + var vertex3 = subMeshVertices[subMeshIndexes[j + 2]]; + var intersection = Picker.rayIntersectsTriangle(ray, vertex1, vertex2, vertex3); + if (!isNaN(intersection) && intersection < closestIntersection) { + closestIntersection = intersection; + } + } + } + return closestIntersection; + } + get width() { + return this._w; + } + get height() { + return this._h; + } + get maxHeight() { + return this._maxHeight; + } + get minHeight() { + return this._minHeight; + } + _inBounds(row, col) { + return row >= 0 && row < this._h && col >= 0 && col < this._w; + } + getHeight(row, col) { + if (this._inBounds(row, col)) + return this._datas[row][col]; + else + return NaN; + } + } + HeightMap._tempRay = new Ray(new Vector3(), new Vector3()); + + class MeshTerrainSprite3D extends MeshSprite3D { + constructor(mesh, heightMap, name = null) { + super(mesh, name); + this._heightMap = heightMap; + this._cellSize = new Vector2(); + } + static createFromMesh(mesh, heightMapWidth, heightMapHeight, name = null) { + var meshTerrainSprite3D = new MeshTerrainSprite3D(mesh, null, name); + meshTerrainSprite3D._initCreateFromMesh(heightMapWidth, heightMapHeight); + return meshTerrainSprite3D; + } + static createFromMeshAndHeightMap(mesh, texture, minHeight, maxHeight, name = null) { + var meshTerrainSprite3D = new MeshTerrainSprite3D(mesh, null, name); + meshTerrainSprite3D._initCreateFromMeshHeightMap(texture, minHeight, maxHeight); + return meshTerrainSprite3D; + } + get minX() { + var worldMat = this.transform.worldMatrix; + var worldMatE = worldMat.elements; + return this._minX * this._getScaleX() + worldMatE[12]; + } + get minZ() { + var worldMat = this.transform.worldMatrix; + var worldMatE = worldMat.elements; + return this._minZ * this._getScaleZ() + worldMatE[14]; + } + get width() { + return (this._heightMap.width - 1) * this._cellSize.x * this._getScaleX(); + } + get depth() { + return (this._heightMap.height - 1) * this._cellSize.y * this._getScaleZ(); + } + _disableRotation() { + var rotation = this.transform.rotation; + rotation.x = 0; + rotation.y = 0; + rotation.z = 0; + rotation.w = 1; + this.transform.rotation = rotation; + } + _getScaleX() { + var worldMat = this.transform.worldMatrix; + var worldMatE = worldMat.elements; + var m11 = worldMatE[0]; + var m12 = worldMatE[1]; + var m13 = worldMatE[2]; + return Math.sqrt((m11 * m11) + (m12 * m12) + (m13 * m13)); + } + _getScaleZ() { + var worldMat = this.transform.worldMatrix; + var worldMatE = worldMat.elements; + var m31 = worldMatE[8]; + var m32 = worldMatE[9]; + var m33 = worldMatE[10]; + return Math.sqrt((m31 * m31) + (m32 * m32) + (m33 * m33)); + } + _initCreateFromMesh(heightMapWidth, heightMapHeight) { + this._heightMap = HeightMap.creatFromMesh(this.meshFilter.sharedMesh, heightMapWidth, heightMapHeight, this._cellSize); + var boundingBox = this.meshFilter.sharedMesh.bounds; + var min = boundingBox.getMin(); + this._minX = min.x; + this._minZ = min.z; + } + _initCreateFromMeshHeightMap(texture, minHeight, maxHeight) { + var boundingBox = this.meshFilter.sharedMesh.bounds; + this._heightMap = HeightMap.createFromImage(texture, minHeight, maxHeight); + this._computeCellSize(boundingBox); + var min = boundingBox.getMin(); + this._minX = min.x; + this._minZ = min.z; + } + _computeCellSize(boundingBox) { + var min = boundingBox.getMin(); + var max = boundingBox.getMax(); + var minX = min.x; + var minZ = min.z; + var maxX = max.x; + var maxZ = max.z; + var widthSize = maxX - minX; + var heightSize = maxZ - minZ; + this._cellSize.x = widthSize / (this._heightMap.width - 1); + this._cellSize.y = heightSize / (this._heightMap.height - 1); + } + _update(state) { + this._disableRotation(); + } + getHeight(x, z) { + MeshTerrainSprite3D._tempVector3.x = x; + MeshTerrainSprite3D._tempVector3.y = 0; + MeshTerrainSprite3D._tempVector3.z = z; + this._disableRotation(); + var worldMat = this.transform.worldMatrix; + worldMat.invert(MeshTerrainSprite3D._tempMatrix4x4); + Vector3.transformCoordinate(MeshTerrainSprite3D._tempVector3, MeshTerrainSprite3D._tempMatrix4x4, MeshTerrainSprite3D._tempVector3); + x = MeshTerrainSprite3D._tempVector3.x; + z = MeshTerrainSprite3D._tempVector3.z; + var c = (x - this._minX) / this._cellSize.x; + var d = (z - this._minZ) / this._cellSize.y; + var row = Math.floor(d); + var col = Math.floor(c); + var s = c - col; + var t = d - row; + var uy; + var vy; + var worldMatE = worldMat.elements; + var m21 = worldMatE[4]; + var m22 = worldMatE[5]; + var m23 = worldMatE[6]; + var scaleY = Math.sqrt((m21 * m21) + (m22 * m22) + (m23 * m23)); + var translateY = worldMatE[13]; + var h01 = this._heightMap.getHeight(row, col + 1); + var h10 = this._heightMap.getHeight((row + 1), col); + if (isNaN(h01) || isNaN(h10)) + return NaN; + if (s + t <= 1.0) { + var h00 = this._heightMap.getHeight(row, col); + if (isNaN(h00)) + return NaN; + uy = h01 - h00; + vy = h10 - h00; + return (h00 + s * uy + t * vy) * scaleY + translateY; + } + else { + var h11 = this._heightMap.getHeight((row + 1), col + 1); + if (isNaN(h11)) + return NaN; + uy = h10 - h11; + vy = h01 - h11; + return (h11 + (1.0 - s) * uy + (1.0 - t) * vy) * scaleY + translateY; + } + } + } + MeshTerrainSprite3D._tempVector3 = new Vector3(); + MeshTerrainSprite3D._tempMatrix4x4 = new Matrix4x4(); + + class GradientDataVector2 { + constructor() { + this._currentLength = 0; + this._elements = new Float32Array(12); + } + get gradientCount() { + return this._currentLength / 3; + } + add(key, value) { + if (this._currentLength < 8) { + if ((this._currentLength === 6) && ((key !== 1))) { + key = 1; + console.log("GradientDataVector2 warning:the forth key is be force set to 1."); + } + this._elements[this._currentLength++] = key; + this._elements[this._currentLength++] = value.x; + this._elements[this._currentLength++] = value.y; + } + else { + console.log("GradientDataVector2 warning:data count must lessEqual than 4"); + } + } + cloneTo(destObject) { + var destGradientDataVector2 = destObject; + destGradientDataVector2._currentLength = this._currentLength; + var destElements = destGradientDataVector2._elements; + for (var i = 0, n = this._elements.length; i < n; i++) { + destElements[i] = this._elements[i]; + } + } + clone() { + var destGradientDataVector2 = new GradientDataVector2(); + this.cloneTo(destGradientDataVector2); + return destGradientDataVector2; + } + } + + class PixelLineData { + constructor() { + this.startPosition = new Vector3(); + this.endPosition = new Vector3(); + this.startColor = new Color(); + this.endColor = new Color(); + } + cloneTo(destObject) { + this.startPosition.cloneTo(destObject.startPosition); + this.endPosition.cloneTo(destObject.endPosition); + this.startColor.cloneTo(destObject.startColor); + this.endColor.cloneTo(destObject.endColor); + } + } + + class PostProcessEffect { + constructor() { + } + render(context) { + } + } + + class BloomEffect extends PostProcessEffect { + constructor() { + super(); + this._shader = null; + this._shaderData = new ShaderData(); + this._linearColor = new Color(); + this._bloomTextureTexelSize = new Vector4(); + this._shaderThreshold = new Vector4(); + this._shaderParams = new Vector4(); + this._pyramid = null; + this._intensity = 0.0; + this._threshold = 1.0; + this._softKnee = 0.5; + this._diffusion = 7.0; + this._anamorphicRatio = 0.0; + this._dirtIntensity = 0.0; + this._shaderSetting = new Vector4(); + this._dirtTileOffset = new Vector4(); + this.clamp = 65472.0; + this.color = new Color(1.0, 1.0, 1.0, 1.0); + this.fastMode = false; + this.dirtTexture = null; + this._shader = Shader3D.find("PostProcessBloom"); + this._pyramid = new Array(BloomEffect.MAXPYRAMIDSIZE * 2); + } + get intensity() { + return this._intensity; + } + set intensity(value) { + this._intensity = Math.max(value, 0.0); + } + get threshold() { + return this._threshold; + } + set threshold(value) { + this._threshold = Math.max(value, 0.0); + } + get softKnee() { + return this._softKnee; + } + set softKnee(value) { + this._softKnee = Math.min(Math.max(value, 0.0), 1.0); + } + get diffusion() { + return this._diffusion; + } + set diffusion(value) { + this._diffusion = Math.min(Math.max(value, 1), 10); + } + get anamorphicRatio() { + return this._anamorphicRatio; + } + set anamorphicRatio(value) { + this._anamorphicRatio = Math.min(Math.max(value, -1.0), 1.0); + } + get dirtIntensity() { + return this._dirtIntensity; + } + set dirtIntensity(value) { + this._dirtIntensity = Math.max(value, 0.0); + } + render(context) { + var cmd = context.command; + var viewport = context.camera.viewport; + this._shaderData.setTexture(BloomEffect.SHADERVALUE_AUTOEXPOSURETEX, Laya.Texture2D.whiteTexture); + var ratio = this._anamorphicRatio; + var rw = ratio < 0 ? -ratio : 0; + var rh = ratio > 0 ? ratio : 0; + var tw = Math.floor(viewport.width / (2 - rw)); + var th = Math.floor(viewport.height / (2 - rh)); + var s = Math.max(tw, th); + var logs; + logs = Math.log2(s) + this._diffusion - 10; + var logsInt = Math.floor(logs); + var iterations = Math.min(Math.max(logsInt, 1), BloomEffect.MAXPYRAMIDSIZE); + var sampleScale = 0.5 + logs - logsInt; + this._shaderData.setNumber(BloomEffect.SHADERVALUE_SAMPLESCALE, sampleScale); + var lthresh = Color.gammaToLinearSpace(this.threshold); + var knee = lthresh * this._softKnee + 1e-5; + this._shaderThreshold.setValue(lthresh, lthresh - knee, knee * 2, 0.25 / knee); + this._shaderData.setVector(BloomEffect.SHADERVALUE_THRESHOLD, this._shaderThreshold); + var lclamp = Color.gammaToLinearSpace(this.clamp); + this._shaderParams.setValue(lclamp, 0, 0, 0); + this._shaderData.setVector(BloomEffect.SHADERVALUE_PARAMS, this._shaderParams); + var qualityOffset = this.fastMode ? 1 : 0; + var lastDownTexture = context.source; + for (var i = 0; i < iterations; i++) { + var downIndex = i * 2; + var upIndex = downIndex + 1; + var subShader = i == 0 ? BloomEffect.SUBSHADER_PREFILTER13 + qualityOffset : BloomEffect.SUBSHADER_DOWNSAMPLE13 + qualityOffset; + var mipDownTexture = RenderTexture.createFromPool(tw, th, Laya.RenderTextureFormat.R8G8B8, Laya.RenderTextureDepthFormat.DEPTHSTENCIL_NONE); + mipDownTexture.filterMode = Laya.FilterMode.Bilinear; + this._pyramid[downIndex] = mipDownTexture; + if (i !== iterations - 1) { + var mipUpTexture = RenderTexture.createFromPool(tw, th, Laya.RenderTextureFormat.R8G8B8, Laya.RenderTextureDepthFormat.DEPTHSTENCIL_NONE); + mipUpTexture.filterMode = Laya.FilterMode.Bilinear; + this._pyramid[upIndex] = mipUpTexture; + } + cmd.blitScreenTriangle(lastDownTexture, mipDownTexture, null, this._shader, this._shaderData, subShader); + lastDownTexture = mipDownTexture; + tw = Math.max(Math.floor(tw / 2), 1); + th = Math.max(Math.floor(th / 2), 1); + } + var lastUpTexture = this._pyramid[(iterations - 1) * 2]; + for (i = iterations - 2; i >= 0; i--) { + downIndex = i * 2; + upIndex = downIndex + 1; + mipDownTexture = this._pyramid[downIndex]; + mipUpTexture = this._pyramid[upIndex]; + cmd.setShaderDataTexture(this._shaderData, BloomEffect.SHADERVALUE_BLOOMTEX, mipDownTexture); + cmd.blitScreenTriangle(lastUpTexture, mipUpTexture, null, this._shader, this._shaderData, BloomEffect.SUBSHADER_UPSAMPLETENT + qualityOffset); + lastUpTexture = mipUpTexture; + } + var linearColor = this._linearColor; + this.color.toLinear(linearColor); + var intensity = Math.pow(2, this._intensity / 10.0) - 1.0; + var shaderSettings = this._shaderSetting; + this._shaderSetting.setValue(sampleScale, intensity, this._dirtIntensity, iterations); + var dirtTexture = this.dirtTexture ? this.dirtTexture : Laya.Texture2D.blackTexture; + var dirtRatio = dirtTexture.width / dirtTexture.height; + var screenRatio = viewport.width / viewport.height; + var dirtTileOffset = this._dirtTileOffset; + if (dirtRatio > screenRatio) + dirtTileOffset.setValue(screenRatio / dirtRatio, 1.0, (1.0 - dirtTileOffset.x) * 0.5, 0.0); + else if (dirtRatio < screenRatio) + dirtTileOffset.setValue(1.0, dirtRatio / screenRatio, 0.0, (1.0 - dirtTileOffset.y) * 0.5); + var compositeShaderData = context.compositeShaderData; + if (this.fastMode) + compositeShaderData.addDefine(PostProcess.SHADERDEFINE_BLOOM_LOW); + else + compositeShaderData.addDefine(PostProcess.SHADERDEFINE_BLOOM); + this._bloomTextureTexelSize.setValue(1.0 / lastUpTexture.width, 1.0 / lastUpTexture.height, lastUpTexture.width, lastUpTexture.height); + compositeShaderData.setVector(PostProcess.SHADERVALUE_BLOOM_DIRTTILEOFFSET, dirtTileOffset); + compositeShaderData.setVector(PostProcess.SHADERVALUE_BLOOM_SETTINGS, shaderSettings); + compositeShaderData.setVector(PostProcess.SHADERVALUE_BLOOM_COLOR, new Vector4(linearColor.r, linearColor.g, linearColor.b, linearColor.a)); + compositeShaderData.setTexture(PostProcess.SHADERVALUE_BLOOM_DIRTTEX, dirtTexture); + compositeShaderData.setTexture(PostProcess.SHADERVALUE_BLOOMTEX, lastUpTexture); + compositeShaderData.setVector(PostProcess.SHADERVALUE_BLOOMTEX_TEXELSIZE, this._bloomTextureTexelSize); + for (i = 0; i < iterations; i++) { + downIndex = i * 2; + upIndex = downIndex + 1; + RenderTexture.recoverToPool(this._pyramid[downIndex]); + (i !== 0 && i !== iterations - 1) && (RenderTexture.recoverToPool(this._pyramid[upIndex])); + } + context.deferredReleaseTextures.push(lastUpTexture); + } + } + BloomEffect.SHADERVALUE_MAINTEX = Shader3D.propertyNameToID("u_MainTex"); + BloomEffect.SHADERVALUE_AUTOEXPOSURETEX = Shader3D.propertyNameToID("u_AutoExposureTex"); + BloomEffect.SHADERVALUE_SAMPLESCALE = Shader3D.propertyNameToID("u_SampleScale"); + BloomEffect.SHADERVALUE_THRESHOLD = Shader3D.propertyNameToID("u_Threshold"); + BloomEffect.SHADERVALUE_PARAMS = Shader3D.propertyNameToID("u_Params"); + BloomEffect.SHADERVALUE_BLOOMTEX = Shader3D.propertyNameToID("u_BloomTex"); + BloomEffect.SUBSHADER_PREFILTER13 = 0; + BloomEffect.SUBSHADER_PREFILTER4 = 1; + BloomEffect.SUBSHADER_DOWNSAMPLE13 = 2; + BloomEffect.SUBSHADER_DOWNSAMPLE4 = 3; + BloomEffect.SUBSHADER_UPSAMPLETENT = 4; + BloomEffect.SUBSHADER_UPSAMPLEBOX = 5; + BloomEffect.MAXPYRAMIDSIZE = 16; + + class MaterialInstanceProperty { + constructor() { + this._isNeedUpdate = false; + } + createInstanceVertexBuffer3D() { + var gl = Laya.LayaGL.instance; + this._instanceData = new Float32Array(DrawMeshInstancedCMD.maxInstanceCount * this._vertexStride); + this._vertexBuffer = new VertexBuffer3D(this._instanceData.length * 4, gl.DYNAMIC_DRAW); + this._vertexBuffer.vertexDeclaration = this._vertexDeclaration; + } + updateVertexBufferData(drawNums) { + if (!this._isNeedUpdate) + return; + let instanceData = this._instanceData; + let dataValue = this._value; + let datalength = this._value.length; + let data; + let stride = this._vertexStride; + let updateType = 0; + if (!(this._value instanceof Float32Array)) { + updateType = 1; + } + switch (updateType) { + case 0: + instanceData.set(dataValue, 0); + break; + case 1: + for (let i = 0; i < datalength; i++) { + data = dataValue[i]; + data.toArray(instanceData, i * stride); + } + break; + } + this._vertexBuffer.orphanStorage(); + this._vertexBuffer.setData(instanceData.buffer, 0, 0, drawNums * 4 * stride); + } + } + + (function (InstanceLocation) { + InstanceLocation[InstanceLocation["CUSTOME0"] = 12] = "CUSTOME0"; + InstanceLocation[InstanceLocation["CUSTOME1"] = 13] = "CUSTOME1"; + InstanceLocation[InstanceLocation["CUSTOME2"] = 14] = "CUSTOME2"; + InstanceLocation[InstanceLocation["CUSTOME3"] = 15] = "CUSTOME3"; + })(exports.InstanceLocation || (exports.InstanceLocation = {})); + class MaterialInstancePropertyBlock { + constructor() { + this._type = 0; + this._propertyMap = {}; + } + _checkPropertyLegal(vertexElementFormat, propertyName, attributeLocation, prob) { + var vecDec = prob._vertexDeclaration; + if (vecDec._vertexElements[0]._elementFormat !== vertexElementFormat) + throw "Data exists and format does not match"; + if (prob._name !== propertyName) + throw "You cannot add a new property to an existing attributeLocation,Please use another attributeLocation"; + } + _creatProperty(attributeName, arrays, vertexStride, vertexformat, attributeLocation) { + var prob = this._propertyMap[attributeLocation] = new MaterialInstanceProperty(); + prob._name = attributeName; + prob._value = arrays; + prob._vertexDeclaration = new VertexDeclaration(vertexStride, [new VertexElement(0, vertexformat, attributeLocation)]); + prob._isNeedUpdate = true; + prob._vertexStride = vertexStride / 4; + prob.createInstanceVertexBuffer3D(); + } + setVectorArray(attributeName, arrays, attributeLocation) { + var prob = this._propertyMap[attributeLocation]; + if (prob) { + this._checkPropertyLegal(VertexElementFormat.Vector4, attributeName, attributeLocation, prob); + prob._value = arrays; + prob._isNeedUpdate = true; + } + else + this._creatProperty(attributeName, arrays, 16, VertexElementFormat.Vector4, attributeLocation); + } + setVector3Array(attributeName, arrays, attributeLocation) { + var prob = this._propertyMap[attributeLocation]; + if (prob) { + this._checkPropertyLegal(VertexElementFormat.Vector3, attributeName, attributeLocation, prob); + prob._value = arrays; + prob._isNeedUpdate = true; + } + else + this._creatProperty(attributeName, arrays, 12, VertexElementFormat.Vector3, attributeLocation); + } + setVector2Array(attributeName, arrays, attributeLocation) { + var prob = this._propertyMap[attributeLocation]; + if (prob) { + this._checkPropertyLegal(VertexElementFormat.Vector2, attributeName, attributeLocation, prob); + prob._value = arrays; + prob._isNeedUpdate = true; + } + else + this._creatProperty(attributeName, arrays, 8, VertexElementFormat.Vector2, attributeLocation); + } + setNumberArray(attributeName, arrays, attributeLocation) { + var prob = this._propertyMap[attributeLocation]; + if (prob) { + this._checkPropertyLegal(VertexElementFormat.Single, attributeName, attributeLocation, prob); + prob._value = arrays; + prob._isNeedUpdate = true; + } + else + this._creatProperty(attributeName, arrays, 4, VertexElementFormat.Single, attributeLocation); + } + getPropertyArray(attributeLocation) { + var prob = this._propertyMap[attributeLocation]; + return prob ? prob._value : null; + } + clear() { + this._propertyMap = {}; + } + } + MaterialInstancePropertyBlock.INSTANCETYPE_ATTRIBUTE = 0; + MaterialInstancePropertyBlock.INSTANCETYPE_UNIFORMBUFFER = 1; + + class ConchVector4 { + constructor(x = 0, y = 0, z = 0, w = 0) { + var v = this.elements = new Float32Array(4); + v[0] = x; + v[1] = y; + v[2] = z; + v[3] = w; + } + get x() { + return this.elements[0]; + } + set x(value) { + this.elements[0] = value; + } + get y() { + return this.elements[1]; + } + set y(value) { + this.elements[1] = value; + } + get z() { + return this.elements[2]; + } + set z(value) { + this.elements[2] = value; + } + get w() { + return this.elements[3]; + } + set w(value) { + this.elements[3] = value; + } + fromArray(array, offset = 0) { + this.elements[0] = array[offset + 0]; + this.elements[1] = array[offset + 1]; + this.elements[2] = array[offset + 2]; + this.elements[3] = array[offset + 3]; + } + cloneTo(destObject) { + var destVector4 = destObject; + var destE = destVector4.elements; + var s = this.elements; + destE[0] = s[0]; + destE[1] = s[1]; + destE[2] = s[2]; + destE[3] = s[3]; + } + clone() { + var destVector4 = new ConchVector4(); + this.cloneTo(destVector4); + return destVector4; + } + static lerp(a, b, t, out) { + var e = out.elements; + var f = a.elements; + var g = b.elements; + var ax = f[0], ay = f[1], az = f[2], aw = f[3]; + e[0] = ax + t * (g[0] - ax); + e[1] = ay + t * (g[1] - ay); + e[2] = az + t * (g[2] - az); + e[3] = aw + t * (g[3] - aw); + } + static transformByM4x4(vector4, m4x4, out) { + var ve = vector4.elements; + var vx = ve[0]; + var vy = ve[1]; + var vz = ve[2]; + var vw = ve[3]; + var me = m4x4.elements; + var oe = out.elements; + oe[0] = vx * me[0] + vy * me[4] + vz * me[8] + vw * me[12]; + oe[1] = vx * me[1] + vy * me[5] + vz * me[9] + vw * me[13]; + oe[2] = vx * me[2] + vy * me[6] + vz * me[10] + vw * me[14]; + oe[3] = vx * me[3] + vy * me[7] + vz * me[11] + vw * me[15]; + } + static equals(a, b) { + var ae = a.elements; + var be = b.elements; + return MathUtils3D.nearEqual(Math.abs(ae[0]), Math.abs(be[0])) && MathUtils3D.nearEqual(Math.abs(ae[1]), Math.abs(be[1])) && MathUtils3D.nearEqual(Math.abs(ae[2]), Math.abs(be[2])) && MathUtils3D.nearEqual(Math.abs(ae[3]), Math.abs(be[3])); + } + length() { + return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w); + } + lengthSquared() { + return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; + } + static normalize(s, out) { + var se = s.elements; + var oe = out.elements; + var len = s.length(); + if (len > 0) { + oe[0] = se[0] * len; + oe[1] = se[1] * len; + oe[2] = se[2] * len; + oe[3] = se[3] * len; + } + } + static add(a, b, out) { + var oe = out.elements; + var ae = a.elements; + var be = b.elements; + oe[0] = ae[0] + be[0]; + oe[1] = ae[1] + be[1]; + oe[2] = ae[2] + be[2]; + oe[3] = ae[3] + be[3]; + } + static subtract(a, b, out) { + var oe = out.elements; + var ae = a.elements; + var be = b.elements; + oe[0] = ae[0] - be[0]; + oe[1] = ae[1] - be[1]; + oe[2] = ae[2] - be[2]; + oe[3] = ae[3] - be[3]; + } + static multiply(a, b, out) { + var oe = out.elements; + var ae = a.elements; + var be = b.elements; + oe[0] = ae[0] * be[0]; + oe[1] = ae[1] * be[1]; + oe[2] = ae[2] * be[2]; + oe[3] = ae[3] * be[3]; + } + static scale(a, b, out) { + var oe = out.elements; + var ae = a.elements; + oe[0] = ae[0] * b; + oe[1] = ae[1] * b; + oe[2] = ae[2] * b; + oe[3] = ae[3] * b; + } + static Clamp(value, min, max, out) { + var valuee = value.elements; + var x = valuee[0]; + var y = valuee[1]; + var z = valuee[2]; + var w = valuee[3]; + var mine = min.elements; + var mineX = mine[0]; + var mineY = mine[1]; + var mineZ = mine[2]; + var mineW = mine[3]; + var maxe = max.elements; + var maxeX = maxe[0]; + var maxeY = maxe[1]; + var maxeZ = maxe[2]; + var maxeW = maxe[3]; + var oute = out.elements; + x = (x > maxeX) ? maxeX : x; + x = (x < mineX) ? mineX : x; + y = (y > maxeY) ? maxeY : y; + y = (y < mineY) ? mineY : y; + z = (z > maxeZ) ? maxeZ : z; + z = (z < mineZ) ? mineZ : z; + w = (w > maxeW) ? maxeW : w; + w = (w < mineW) ? mineW : w; + oute[0] = x; + oute[1] = y; + oute[2] = z; + oute[3] = w; + } + static distanceSquared(value1, value2) { + var value1e = value1.elements; + var value2e = value2.elements; + var x = value1e[0] - value2e[0]; + var y = value1e[1] - value2e[1]; + var z = value1e[2] - value2e[2]; + var w = value1e[3] - value2e[3]; + return (x * x) + (y * y) + (z * z) + (w * w); + } + static distance(value1, value2) { + var value1e = value1.elements; + var value2e = value2.elements; + var x = value1e[0] - value2e[0]; + var y = value1e[1] - value2e[1]; + var z = value1e[2] - value2e[2]; + var w = value1e[3] - value2e[3]; + return Math.sqrt((x * x) + (y * y) + (z * z) + (w * w)); + } + static dot(a, b) { + var ae = a.elements; + var be = b.elements; + var r = (ae[0] * be[0]) + (ae[1] * be[1]) + (ae[2] * be[2]) + (ae[3] * be[3]); + return r; + } + static min(a, b, out) { + var e = out.elements; + var f = a.elements; + var g = b.elements; + e[0] = Math.min(f[0], g[0]); + e[1] = Math.min(f[1], g[1]); + e[2] = Math.min(f[2], g[2]); + e[3] = Math.min(f[3], g[3]); + } + static max(a, b, out) { + var e = out.elements; + var f = a.elements; + var g = b.elements; + e[0] = Math.max(f[0], g[0]); + e[1] = Math.max(f[1], g[1]); + e[2] = Math.max(f[2], g[2]); + e[3] = Math.max(f[3], g[3]); + } + } + ConchVector4.ZERO = new ConchVector4(); + ConchVector4.ONE = new ConchVector4(1.0, 1.0, 1.0, 1.0); + ConchVector4.UnitX = new ConchVector4(1.0, 0.0, 0.0, 0.0); + ConchVector4.UnitY = new ConchVector4(0.0, 1.0, 0.0, 0.0); + ConchVector4.UnitZ = new ConchVector4(0.0, 0.0, 1.0, 0.0); + ConchVector4.UnitW = new ConchVector4(0.0, 0.0, 0.0, 1.0); + + class ConchVector3 { + constructor(x = 0, y = 0, z = 0, nativeElements = null) { + var v; + if (nativeElements) { + v = nativeElements; + } + else { + v = new Float32Array(3); + } + this.elements = v; + v[0] = x; + v[1] = y; + v[2] = z; + } + static distanceSquared(value1, value2) { + var value1e = value1.elements; + var value2e = value2.elements; + var x = value1e[0] - value2e[0]; + var y = value1e[1] - value2e[1]; + var z = value1e[2] - value2e[2]; + return (x * x) + (y * y) + (z * z); + } + static distance(value1, value2) { + var value1e = value1.elements; + var value2e = value2.elements; + var x = value1e[0] - value2e[0]; + var y = value1e[1] - value2e[1]; + var z = value1e[2] - value2e[2]; + return Math.sqrt((x * x) + (y * y) + (z * z)); + } + static min(a, b, out) { + var e = out.elements; + var f = a.elements; + var g = b.elements; + e[0] = Math.min(f[0], g[0]); + e[1] = Math.min(f[1], g[1]); + e[2] = Math.min(f[2], g[2]); + } + static max(a, b, out) { + var e = out.elements; + var f = a.elements; + var g = b.elements; + e[0] = Math.max(f[0], g[0]); + e[1] = Math.max(f[1], g[1]); + e[2] = Math.max(f[2], g[2]); + } + static transformQuat(source, rotation, out) { + var destination = out.elements; + var se = source.elements; + var re = rotation.elements; + var x = se[0], y = se[1], z = se[2], qx = re[0], qy = re[1], qz = re[2], qw = re[3], ix = qw * x + qy * z - qz * y, iy = qw * y + qz * x - qx * z, iz = qw * z + qx * y - qy * x, iw = -qx * x - qy * y - qz * z; + destination[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy; + destination[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz; + destination[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx; + } + static scalarLength(a) { + var f = a.elements; + var x = f[0], y = f[1], z = f[2]; + return Math.sqrt(x * x + y * y + z * z); + } + static scalarLengthSquared(a) { + var f = a.elements; + var x = f[0], y = f[1], z = f[2]; + return x * x + y * y + z * z; + } + static normalize(s, out) { + var se = s.elements; + var oe = out.elements; + var x = se[0], y = se[1], z = se[2]; + var len = x * x + y * y + z * z; + if (len > 0) { + len = 1 / Math.sqrt(len); + oe[0] = se[0] * len; + oe[1] = se[1] * len; + oe[2] = se[2] * len; + } + } + static multiply(a, b, out) { + var e = out.elements; + var f = a.elements; + var g = b.elements; + e[0] = f[0] * g[0]; + e[1] = f[1] * g[1]; + e[2] = f[2] * g[2]; + } + static scale(a, b, out) { + var e = out.elements; + var f = a.elements; + e[0] = f[0] * b; + e[1] = f[1] * b; + e[2] = f[2] * b; + } + static lerp(a, b, t, out) { + var e = out.elements; + var f = a.elements; + var g = b.elements; + var ax = f[0], ay = f[1], az = f[2]; + e[0] = ax + t * (g[0] - ax); + e[1] = ay + t * (g[1] - ay); + e[2] = az + t * (g[2] - az); + } + static transformV3ToV3(vector, transform, result) { + var intermediate = ConchVector3._tempVector4; + ConchVector3.transformV3ToV4(vector, transform, intermediate); + var intermediateElem = intermediate.elements; + var resultElem = result.elements; + resultElem[0] = intermediateElem[0]; + resultElem[1] = intermediateElem[1]; + resultElem[2] = intermediateElem[2]; + } + static transformV3ToV4(vector, transform, result) { + var vectorElem = vector.elements; + var vectorX = vectorElem[0]; + var vectorY = vectorElem[1]; + var vectorZ = vectorElem[2]; + var transformElem = transform.elements; + var resultElem = result.elements; + resultElem[0] = (vectorX * transformElem[0]) + (vectorY * transformElem[4]) + (vectorZ * transformElem[8]) + transformElem[12]; + resultElem[1] = (vectorX * transformElem[1]) + (vectorY * transformElem[5]) + (vectorZ * transformElem[9]) + transformElem[13]; + resultElem[2] = (vectorX * transformElem[2]) + (vectorY * transformElem[6]) + (vectorZ * transformElem[10]) + transformElem[14]; + resultElem[3] = (vectorX * transformElem[3]) + (vectorY * transformElem[7]) + (vectorZ * transformElem[11]) + transformElem[15]; + } + static TransformNormal(normal, transform, result) { + var normalElem = normal.elements; + var normalX = normalElem[0]; + var normalY = normalElem[1]; + var normalZ = normalElem[2]; + var transformElem = transform.elements; + var resultElem = result.elements; + resultElem[0] = (normalX * transformElem[0]) + (normalY * transformElem[4]) + (normalZ * transformElem[8]); + resultElem[1] = (normalX * transformElem[1]) + (normalY * transformElem[5]) + (normalZ * transformElem[9]); + resultElem[2] = (normalX * transformElem[2]) + (normalY * transformElem[6]) + (normalZ * transformElem[10]); + } + static transformCoordinate(coordinate, transform, result) { + var coordinateElem = coordinate.elements; + var coordinateX = coordinateElem[0]; + var coordinateY = coordinateElem[1]; + var coordinateZ = coordinateElem[2]; + var transformElem = transform.elements; + var w = ((coordinateX * transformElem[3]) + (coordinateY * transformElem[7]) + (coordinateZ * transformElem[11]) + transformElem[15]); + var resultElem = result.elements; + resultElem[0] = (coordinateX * transformElem[0]) + (coordinateY * transformElem[4]) + (coordinateZ * transformElem[8]) + transformElem[12] / w; + resultElem[1] = (coordinateX * transformElem[1]) + (coordinateY * transformElem[5]) + (coordinateZ * transformElem[9]) + transformElem[13] / w; + resultElem[2] = (coordinateX * transformElem[2]) + (coordinateY * transformElem[6]) + (coordinateZ * transformElem[10]) + transformElem[14] / w; + } + static Clamp(value, min, max, out) { + var valuee = value.elements; + var x = valuee[0]; + var y = valuee[1]; + var z = valuee[2]; + var mine = min.elements; + var mineX = mine[0]; + var mineY = mine[1]; + var mineZ = mine[2]; + var maxe = max.elements; + var maxeX = maxe[0]; + var maxeY = maxe[1]; + var maxeZ = maxe[2]; + var oute = out.elements; + x = (x > maxeX) ? maxeX : x; + x = (x < mineX) ? mineX : x; + y = (y > maxeY) ? maxeY : y; + y = (y < mineY) ? mineY : y; + z = (z > maxeZ) ? maxeZ : z; + z = (z < mineZ) ? mineZ : z; + oute[0] = x; + oute[1] = y; + oute[2] = z; + } + static add(a, b, out) { + var e = out.elements; + var f = a.elements; + var g = b.elements; + e[0] = f[0] + g[0]; + e[1] = f[1] + g[1]; + e[2] = f[2] + g[2]; + } + static subtract(a, b, o) { + var oe = o.elements; + var ae = a.elements; + var be = b.elements; + oe[0] = ae[0] - be[0]; + oe[1] = ae[1] - be[1]; + oe[2] = ae[2] - be[2]; + } + static cross(a, b, o) { + var ae = a.elements; + var be = b.elements; + var oe = o.elements; + var ax = ae[0], ay = ae[1], az = ae[2], bx = be[0], by = be[1], bz = be[2]; + oe[0] = ay * bz - az * by; + oe[1] = az * bx - ax * bz; + oe[2] = ax * by - ay * bx; + } + static dot(a, b) { + var ae = a.elements; + var be = b.elements; + var r = (ae[0] * be[0]) + (ae[1] * be[1]) + (ae[2] * be[2]); + return r; + } + static equals(a, b) { + var ae = a.elements; + var be = b.elements; + return MathUtils3D.nearEqual(ae[0], be[0]) && MathUtils3D.nearEqual(ae[1], be[1]) && MathUtils3D.nearEqual(ae[2], be[2]); + } + get x() { + return this.elements[0]; + } + set x(value) { + this.elements[0] = value; + } + get y() { + return this.elements[1]; + } + set y(value) { + this.elements[1] = value; + } + get z() { + return this.elements[2]; + } + set z(value) { + this.elements[2] = value; + } + setValue(x, y, z) { + this.elements[0] = x; + this.elements[1] = y; + this.elements[2] = z; + } + fromArray(array, offset = 0) { + this.elements[0] = array[offset + 0]; + this.elements[1] = array[offset + 1]; + this.elements[2] = array[offset + 2]; + } + cloneTo(destObject) { + var destVector3 = destObject; + var destE = destVector3.elements; + var s = this.elements; + destE[0] = s[0]; + destE[1] = s[1]; + destE[2] = s[2]; + } + clone() { + var destVector3 = new ConchVector3(); + this.cloneTo(destVector3); + return destVector3; + } + toDefault() { + this.elements[0] = 0; + this.elements[1] = 0; + this.elements[2] = 0; + } + } + ConchVector3._tempVector4 = new ConchVector4(); + ConchVector3.ZERO = new ConchVector3(0.0, 0.0, 0.0); + ConchVector3.ONE = new ConchVector3(1.0, 1.0, 1.0); + ConchVector3.NegativeUnitX = new ConchVector3(-1, 0, 0); + ConchVector3.UnitX = new ConchVector3(1, 0, 0); + ConchVector3.UnitY = new ConchVector3(0, 1, 0); + ConchVector3.UnitZ = new ConchVector3(0, 0, 1); + ConchVector3.ForwardRH = new ConchVector3(0, 0, -1); + ConchVector3.ForwardLH = new ConchVector3(0, 0, 1); + ConchVector3.Up = new ConchVector3(0, 1, 0); + ConchVector3.NAN = new ConchVector3(NaN, NaN, NaN); + + class ConchQuaternion { + constructor(x = 0, y = 0, z = 0, w = 1, nativeElements = null) { + var v; + if (nativeElements) { + v = nativeElements; + } + else { + v = new Float32Array(4); + } + v[0] = x; + v[1] = y; + v[2] = z; + v[3] = w; + this.elements = v; + } + static _dotArray(l, r) { + return l[0] * r[0] + l[1] * r[1] + l[2] * r[2] + l[3] * r[3]; + } + static _normalizeArray(f, o) { + var x = f[0], y = f[1], z = f[2], w = f[3]; + var len = x * x + y * y + z * z + w * w; + if (len > 0) { + len = 1 / Math.sqrt(len); + o[0] = x * len; + o[1] = y * len; + o[2] = z * len; + o[3] = w * len; + } + } + static _lerpArray(l, r, amount, o) { + var inverse = 1.0 - amount; + if (ConchQuaternion._dotArray(l, r) >= 0) { + o[0] = (inverse * l[0]) + (amount * r[0]); + o[1] = (inverse * l[1]) + (amount * r[1]); + o[2] = (inverse * l[2]) + (amount * r[2]); + o[3] = (inverse * l[3]) + (amount * r[3]); + } + else { + o[0] = (inverse * l[0]) - (amount * r[0]); + o[1] = (inverse * l[1]) - (amount * r[1]); + o[2] = (inverse * l[2]) - (amount * r[2]); + o[3] = (inverse * l[3]) - (amount * r[3]); + } + ConchQuaternion._normalizeArray(o, o); + } + static createFromYawPitchRoll(yaw, pitch, roll, out) { + var halfRoll = roll * 0.5; + var halfPitch = pitch * 0.5; + var halfYaw = yaw * 0.5; + var sinRoll = Math.sin(halfRoll); + var cosRoll = Math.cos(halfRoll); + var sinPitch = Math.sin(halfPitch); + var cosPitch = Math.cos(halfPitch); + var sinYaw = Math.sin(halfYaw); + var cosYaw = Math.cos(halfYaw); + var oe = out.elements; + oe[0] = (cosYaw * sinPitch * cosRoll) + (sinYaw * cosPitch * sinRoll); + oe[1] = (sinYaw * cosPitch * cosRoll) - (cosYaw * sinPitch * sinRoll); + oe[2] = (cosYaw * cosPitch * sinRoll) - (sinYaw * sinPitch * cosRoll); + oe[3] = (cosYaw * cosPitch * cosRoll) + (sinYaw * sinPitch * sinRoll); + } + static multiply(left, right, out) { + var le = left.elements; + var re = right.elements; + var oe = out.elements; + var lx = le[0]; + var ly = le[1]; + var lz = le[2]; + var lw = le[3]; + var rx = re[0]; + var ry = re[1]; + var rz = re[2]; + var rw = re[3]; + var a = (ly * rz - lz * ry); + var b = (lz * rx - lx * rz); + var c = (lx * ry - ly * rx); + var d = (lx * rx + ly * ry + lz * rz); + oe[0] = (lx * rw + rx * lw) + a; + oe[1] = (ly * rw + ry * lw) + b; + oe[2] = (lz * rw + rz * lw) + c; + oe[3] = lw * rw - d; + } + static arcTanAngle(x, y) { + if (x == 0) { + if (y == 1) + return Math.PI / 2; + return -Math.PI / 2; + } + if (x > 0) + return Math.atan(y / x); + if (x < 0) { + if (y > 0) + return Math.atan(y / x) + Math.PI; + return Math.atan(y / x) - Math.PI; + } + return 0; + } + static angleTo(from, location, angle) { + ConchVector3.subtract(location, from, ConchQuaternion.TEMPVector30); + ConchVector3.normalize(ConchQuaternion.TEMPVector30, ConchQuaternion.TEMPVector30); + angle.elements[0] = Math.asin(ConchQuaternion.TEMPVector30.y); + angle.elements[1] = ConchQuaternion.arcTanAngle(-ConchQuaternion.TEMPVector30.z, -ConchQuaternion.TEMPVector30.x); + } + static createFromAxisAngle(axis, rad, out) { + var e = out.elements; + var f = axis.elements; + rad = rad * 0.5; + var s = Math.sin(rad); + e[0] = s * f[0]; + e[1] = s * f[1]; + e[2] = s * f[2]; + e[3] = Math.cos(rad); + } + static createFromMatrix3x3(sou, out) { + var e = out.elements; + var f = sou.elements; + var fTrace = f[0] + f[4] + f[8]; + var fRoot; + if (fTrace > 0.0) { + fRoot = Math.sqrt(fTrace + 1.0); + e[3] = 0.5 * fRoot; + fRoot = 0.5 / fRoot; + e[0] = (f[5] - f[7]) * fRoot; + e[1] = (f[6] - f[2]) * fRoot; + e[2] = (f[1] - f[3]) * fRoot; + } + else { + var i = 0; + if (f[4] > f[0]) + i = 1; + if (f[8] > f[i * 3 + i]) + i = 2; + var j = (i + 1) % 3; + var k = (i + 2) % 3; + fRoot = Math.sqrt(f[i * 3 + i] - f[j * 3 + j] - f[k * 3 + k] + 1.0); + e[i] = 0.5 * fRoot; + fRoot = 0.5 / fRoot; + e[3] = (f[j * 3 + k] - f[k * 3 + j]) * fRoot; + e[j] = (f[j * 3 + i] + f[i * 3 + j]) * fRoot; + e[k] = (f[k * 3 + i] + f[i * 3 + k]) * fRoot; + } + return; + } + static createFromMatrix4x4(mat, out) { + var me = mat.elements; + var oe = out.elements; + var sqrt; + var half; + var scale = me[0] + me[5] + me[10]; + if (scale > 0.0) { + sqrt = Math.sqrt(scale + 1.0); + oe[3] = sqrt * 0.5; + sqrt = 0.5 / sqrt; + oe[0] = (me[6] - me[9]) * sqrt; + oe[1] = (me[8] - me[2]) * sqrt; + oe[2] = (me[1] - me[4]) * sqrt; + } + else if ((me[0] >= me[5]) && (me[0] >= me[10])) { + sqrt = Math.sqrt(1.0 + me[0] - me[5] - me[10]); + half = 0.5 / sqrt; + oe[0] = 0.5 * sqrt; + oe[1] = (me[1] + me[4]) * half; + oe[2] = (me[2] + me[8]) * half; + oe[3] = (me[6] - me[9]) * half; + } + else if (me[5] > me[10]) { + sqrt = Math.sqrt(1.0 + me[5] - me[0] - me[10]); + half = 0.5 / sqrt; + oe[0] = (me[4] + me[1]) * half; + oe[1] = 0.5 * sqrt; + oe[2] = (me[9] + me[6]) * half; + oe[3] = (me[8] - me[2]) * half; + } + else { + sqrt = Math.sqrt(1.0 + me[10] - me[0] - me[5]); + half = 0.5 / sqrt; + oe[0] = (me[8] + me[2]) * half; + oe[1] = (me[9] + me[6]) * half; + oe[2] = 0.5 * sqrt; + oe[3] = (me[1] - me[4]) * half; + } + } + static slerp(left, right, t, out) { + var a = left.elements; + var b = right.elements; + var oe = out.elements; + var ax = a[0], ay = a[1], az = a[2], aw = a[3], bx = b[0], by = b[1], bz = b[2], bw = b[3]; + var omega, cosom, sinom, scale0, scale1; + cosom = ax * bx + ay * by + az * bz + aw * bw; + if (cosom < 0.0) { + cosom = -cosom; + bx = -bx; + by = -by; + bz = -bz; + bw = -bw; + } + if ((1.0 - cosom) > 0.000001) { + omega = Math.acos(cosom); + sinom = Math.sin(omega); + scale0 = Math.sin((1.0 - t) * omega) / sinom; + scale1 = Math.sin(t * omega) / sinom; + } + else { + scale0 = 1.0 - t; + scale1 = t; + } + oe[0] = scale0 * ax + scale1 * bx; + oe[1] = scale0 * ay + scale1 * by; + oe[2] = scale0 * az + scale1 * bz; + oe[3] = scale0 * aw + scale1 * bw; + return oe; + } + static lerp(left, right, amount, out) { + ConchQuaternion._lerpArray(left.elements, right.elements, amount, out.elements); + } + static add(left, right, out) { + var e = out.elements; + var f = left.elements; + var g = right.elements; + e[0] = f[0] + g[0]; + e[1] = f[1] + g[1]; + e[2] = f[2] + g[2]; + e[3] = f[3] + g[3]; + } + static dot(left, right) { + return ConchQuaternion._dotArray(left.elements, right.elements); + } + get x() { + return this.elements[0]; + } + set x(value) { + this.elements[0] = value; + } + get y() { + return this.elements[1]; + } + set y(value) { + this.elements[1] = value; + } + get z() { + return this.elements[2]; + } + set z(value) { + this.elements[2] = value; + } + get w() { + return this.elements[3]; + } + set w(value) { + this.elements[3] = value; + } + scaling(scaling, out) { + var e = out.elements; + var f = this.elements; + e[0] = f[0] * scaling; + e[1] = f[1] * scaling; + e[2] = f[2] * scaling; + e[3] = f[3] * scaling; + } + normalize(out) { + ConchQuaternion._normalizeArray(this.elements, out.elements); + } + length() { + var f = this.elements; + var x = f[0], y = f[1], z = f[2], w = f[3]; + return Math.sqrt(x * x + y * y + z * z + w * w); + } + rotateX(rad, out) { + var e = out.elements; + var f = this.elements; + rad *= 0.5; + var ax = f[0], ay = f[1], az = f[2], aw = f[3]; + var bx = Math.sin(rad), bw = Math.cos(rad); + e[0] = ax * bw + aw * bx; + e[1] = ay * bw + az * bx; + e[2] = az * bw - ay * bx; + e[3] = aw * bw - ax * bx; + } + rotateY(rad, out) { + var e = out.elements; + var f = this.elements; + rad *= 0.5; + var ax = f[0], ay = f[1], az = f[2], aw = f[3], by = Math.sin(rad), bw = Math.cos(rad); + e[0] = ax * bw - az * by; + e[1] = ay * bw + aw * by; + e[2] = az * bw + ax * by; + e[3] = aw * bw - ay * by; + } + rotateZ(rad, out) { + var e = out.elements; + var f = this.elements; + rad *= 0.5; + var ax = f[0], ay = f[1], az = f[2], aw = f[3], bz = Math.sin(rad), bw = Math.cos(rad); + e[0] = ax * bw + ay * bz; + e[1] = ay * bw - ax * bz; + e[2] = az * bw + aw * bz; + e[3] = aw * bw - az * bz; + } + getYawPitchRoll(out) { + ConchVector3.transformQuat(ConchVector3.ForwardRH, this, ConchQuaternion.TEMPVector31); + ConchVector3.transformQuat(ConchVector3.Up, this, ConchQuaternion.TEMPVector32); + var upe = ConchQuaternion.TEMPVector32.elements; + ConchQuaternion.angleTo(ConchVector3.ZERO, ConchQuaternion.TEMPVector31, ConchQuaternion.TEMPVector33); + var anglee = ConchQuaternion.TEMPVector33.elements; + if (anglee[0] == Math.PI / 2) { + anglee[1] = ConchQuaternion.arcTanAngle(upe[2], upe[0]); + anglee[2] = 0; + } + else if (anglee[0] == -Math.PI / 2) { + anglee[1] = ConchQuaternion.arcTanAngle(-upe[2], -upe[0]); + anglee[2] = 0; + } + else { + Matrix4x4.createRotationY(-anglee[1], ConchQuaternion.TEMPMatrix0); + Matrix4x4.createRotationX(-anglee[0], ConchQuaternion.TEMPMatrix1); + ConchVector3.transformCoordinate(ConchQuaternion.TEMPVector32, ConchQuaternion.TEMPMatrix0, ConchQuaternion.TEMPVector32); + ConchVector3.transformCoordinate(ConchQuaternion.TEMPVector32, ConchQuaternion.TEMPMatrix1, ConchQuaternion.TEMPVector32); + anglee[2] = ConchQuaternion.arcTanAngle(upe[1], -upe[0]); + } + if (anglee[1] <= -Math.PI) + anglee[1] = Math.PI; + if (anglee[2] <= -Math.PI) + anglee[2] = Math.PI; + if (anglee[1] >= Math.PI && anglee[2] >= Math.PI) { + anglee[1] = 0; + anglee[2] = 0; + anglee[0] = Math.PI - anglee[0]; + } + var oe = out.elements; + oe[0] = anglee[1]; + oe[1] = anglee[0]; + oe[2] = anglee[2]; + } + invert(out) { + var e = out.elements; + var f = this.elements; + var a0 = f[0], a1 = f[1], a2 = f[2], a3 = f[3]; + var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3; + var invDot = dot ? 1.0 / dot : 0; + e[0] = -a0 * invDot; + e[1] = -a1 * invDot; + e[2] = -a2 * invDot; + e[3] = a3 * invDot; + } + identity() { + var e = this.elements; + e[0] = 0; + e[1] = 0; + e[2] = 0; + e[3] = 1; + } + fromArray(array, offset = 0) { + this.elements[0] = array[offset + 0]; + this.elements[1] = array[offset + 1]; + this.elements[2] = array[offset + 2]; + this.elements[3] = array[offset + 3]; + } + cloneTo(destObject) { + var i, s, d; + s = this.elements; + d = destObject.elements; + if (s === d) { + return; + } + for (i = 0; i < 4; ++i) { + d[i] = s[i]; + } + } + clone() { + var dest = new ConchQuaternion(); + this.cloneTo(dest); + return dest; + } + equals(b) { + var ae = this.elements; + var be = b.elements; + return MathUtils3D.nearEqual(ae[0], be[0]) && MathUtils3D.nearEqual(ae[1], be[1]) && MathUtils3D.nearEqual(ae[2], be[2]) && MathUtils3D.nearEqual(ae[3], be[3]); + } + static rotationLookAt(forward, up, out) { + ConchQuaternion.lookAt(ConchVector3.ZERO, forward, up, out); + } + static lookAt(eye, target, up, out) { + Matrix3x3.lookAt(eye, target, up, ConchQuaternion._tempMatrix3x3); + ConchQuaternion.rotationMatrix(ConchQuaternion._tempMatrix3x3, out); + } + lengthSquared() { + var x = this.elements[0]; + var y = this.elements[1]; + var z = this.elements[2]; + var w = this.elements[3]; + return (x * x) + (y * y) + (z * z) + (w * w); + } + static invert(value, out) { + var vE = value.elements; + var oE = out.elements; + var lengthSq = value.lengthSquared(); + if (!MathUtils3D.isZero(lengthSq)) { + lengthSq = 1.0 / lengthSq; + oE[0] = -vE[0] * lengthSq; + oE[1] = -vE[1] * lengthSq; + oE[2] = -vE[2] * lengthSq; + oE[3] = vE[3] * lengthSq; + } + } + static rotationMatrix(matrix3x3, out) { + var me = matrix3x3.elements; + var m11 = me[0]; + var m12 = me[1]; + var m13 = me[2]; + var m21 = me[3]; + var m22 = me[4]; + var m23 = me[5]; + var m31 = me[6]; + var m32 = me[7]; + var m33 = me[8]; + var oe = out.elements; + var sqrt, half; + var scale = m11 + m22 + m33; + if (scale > 0) { + sqrt = Math.sqrt(scale + 1); + oe[3] = sqrt * 0.5; + sqrt = 0.5 / sqrt; + oe[0] = (m23 - m32) * sqrt; + oe[1] = (m31 - m13) * sqrt; + oe[2] = (m12 - m21) * sqrt; + } + else if ((m11 >= m22) && (m11 >= m33)) { + sqrt = Math.sqrt(1 + m11 - m22 - m33); + half = 0.5 / sqrt; + oe[0] = 0.5 * sqrt; + oe[1] = (m12 + m21) * half; + oe[2] = (m13 + m31) * half; + oe[3] = (m23 - m32) * half; + } + else if (m22 > m33) { + sqrt = Math.sqrt(1 + m22 - m11 - m33); + half = 0.5 / sqrt; + oe[0] = (m21 + m12) * half; + oe[1] = 0.5 * sqrt; + oe[2] = (m32 + m23) * half; + oe[3] = (m31 - m13) * half; + } + else { + sqrt = Math.sqrt(1 + m33 - m11 - m22); + half = 0.5 / sqrt; + oe[0] = (m31 + m13) * half; + oe[1] = (m32 + m23) * half; + oe[2] = 0.5 * sqrt; + oe[3] = (m12 - m21) * half; + } + } + } + ConchQuaternion.TEMPVector30 = new ConchVector3(); + ConchQuaternion.TEMPVector31 = new ConchVector3(); + ConchQuaternion.TEMPVector32 = new ConchVector3(); + ConchQuaternion.TEMPVector33 = new ConchVector3(); + ConchQuaternion.TEMPMatrix0 = new Matrix4x4(); + ConchQuaternion.TEMPMatrix1 = new Matrix4x4(); + ConchQuaternion._tempMatrix3x3 = new Matrix3x3(); + ConchQuaternion.DEFAULT = new ConchQuaternion(); + ConchQuaternion.NAN = new ConchQuaternion(NaN, NaN, NaN, NaN); + + class RandX { + constructor(seed) { + if (!(seed instanceof Array) || seed.length !== 4) + throw new Error('Rand:Seed must be an array with 4 numbers'); + this._state0U = seed[0] | 0; + this._state0L = seed[1] | 0; + this._state1U = seed[2] | 0; + this._state1L = seed[3] | 0; + } + randomint() { + var s1U = this._state0U, s1L = this._state0L; + var s0U = this._state1U, s0L = this._state1L; + var sumL = (s0L >>> 0) + (s1L >>> 0); + var resU = (s0U + s1U + (sumL / 2 >>> 31)) >>> 0; + var resL = sumL >>> 0; + this._state0U = s0U; + this._state0L = s0L; + var t1U = 0, t1L = 0; + var t2U = 0, t2L = 0; + var a1 = 23; + var m1 = 0xFFFFFFFF << (32 - a1); + t1U = (s1U << a1) | ((s1L & m1) >>> (32 - a1)); + t1L = s1L << a1; + s1U = s1U ^ t1U; + s1L = s1L ^ t1L; + t1U = s1U ^ s0U; + t1L = s1L ^ s0L; + var a2 = 18; + var m2 = 0xFFFFFFFF >>> (32 - a2); + t2U = s1U >>> a2; + t2L = (s1L >>> a2) | ((s1U & m2) << (32 - a2)); + t1U = t1U ^ t2U; + t1L = t1L ^ t2L; + var a3 = 5; + var m3 = 0xFFFFFFFF >>> (32 - a3); + t2U = s0U >>> a3; + t2L = (s0L >>> a3) | ((s0U & m3) << (32 - a3)); + t1U = t1U ^ t2U; + t1L = t1L ^ t2L; + this._state1U = t1U; + this._state1L = t1L; + return [resU, resL]; + } + random() { + var t2 = this.randomint(); + var t2U = t2[0]; + var t2L = t2[1]; + var eU = 0x3FF << (52 - 32); + var eL = 0; + var a1 = 12; + var m1 = 0xFFFFFFFF >>> (32 - a1); + var sU = t2U >>> a1; + var sL = (t2L >>> a1) | ((t2U & m1) << (32 - a1)); + var xU = eU | sU; + var xL = eL | sL; + RandX._CONVERTION_BUFFER.setUint32(0, xU, false); + RandX._CONVERTION_BUFFER.setUint32(4, xL, false); + var d = RandX._CONVERTION_BUFFER.getFloat64(0, false); + return d - 1; + } + } + RandX._CONVERTION_BUFFER = new DataView(new ArrayBuffer(8)); + RandX.defaultRand = new RandX([0, Date.now() / 65536, 0, Date.now() % 65536]); + + class TextMesh { + constructor() { + } + get text() { + return this._text; + } + set text(value) { + this._text = value; + } + get fontSize() { + return this._fontSize; + } + set fontSize(value) { + this._fontSize = value; + } + get color() { + return this._color; + } + set color(value) { + this._color = value; + } + } + + class Size { + constructor(width, height) { + this._width = 0; + this._height = 0; + this._width = width; + this._height = height; + } + static get fullScreen() { + return new Size(-1, -1); + } + get width() { + if (this._width === -1) + return RenderContext3D.clientWidth; + return this._width; + } + get height() { + if (this._height === -1) + return RenderContext3D.clientHeight; + return this._height; + } + } + + exports.AlternateLightQueue = AlternateLightQueue; + exports.AnimationClip = AnimationClip; + exports.AnimationClipParser03 = AnimationClipParser03; + exports.AnimationClipParser04 = AnimationClipParser04; + exports.AnimationEvent = AnimationEvent; + exports.AnimationNode = AnimationNode; + exports.AnimationTransform3D = AnimationTransform3D; + exports.Animator = Animator; + exports.AnimatorControllerLayer = AnimatorControllerLayer; + exports.AnimatorPlayState = AnimatorPlayState; + exports.AnimatorState = AnimatorState; + exports.AnimatorStateScript = AnimatorStateScript; + exports.Avatar = Avatar; + exports.AvatarMask = AvatarMask; + exports.BaseCamera = BaseCamera; + exports.BaseMaterial = BaseMaterial; + exports.BaseRender = BaseRender; + exports.BaseShape = BaseShape; + exports.BatchMark = BatchMark; + exports.BlinnPhongMaterial = BlinnPhongMaterial; + exports.BlitScreenQuadCMD = BlitScreenQuadCMD; + exports.BloomEffect = BloomEffect; + exports.BoundBox = BoundBox; + exports.BoundFrustum = BoundFrustum; + exports.BoundSphere = BoundSphere; + exports.Bounds = Bounds; + exports.BoundsOctree = BoundsOctree; + exports.BoundsOctreeNode = BoundsOctreeNode; + exports.BoxShape = BoxShape; + exports.BufferState = BufferState; + exports.Burst = Burst; + exports.Camera = Camera; + exports.CameraCullInfo = CameraCullInfo; + exports.CastShadowList = CastShadowList; + exports.CircleShape = CircleShape; + exports.ClearRenderTextureCMD = ClearRenderTextureCMD; + exports.Cluster = Cluster; + exports.CollisionUtils = CollisionUtils; + exports.Color = Color; + exports.ColorOverLifetime = ColorOverLifetime; + exports.Command = Command; + exports.CommandBuffer = CommandBuffer; + exports.ConchQuaternion = ConchQuaternion; + exports.ConchVector3 = ConchVector3; + exports.ConchVector4 = ConchVector4; + exports.ConeShape = ConeShape; + exports.Config3D = Config3D; + exports.ContainmentType = ContainmentType; + exports.DefineDatas = DefineDatas; + exports.DepthPass = DepthPass; + exports.DirectionLight = DirectionLight; + exports.DrawMeshCMD = DrawMeshCMD; + exports.DrawMeshInstancedCMD = DrawMeshInstancedCMD; + exports.DrawRenderCMD = DrawRenderCMD; + exports.DynamicBatchManager = DynamicBatchManager; + exports.EffectMaterial = EffectMaterial; + exports.Emission = Emission; + exports.ExtendTerrainMaterial = ExtendTerrainMaterial; + exports.FloatKeyframe = FloatKeyframe; + exports.FrameOverTime = FrameOverTime; + exports.FrustumCulling = FrustumCulling; + exports.GeometryElement = GeometryElement; + exports.Gradient = Gradient; + exports.GradientAngularVelocity = GradientAngularVelocity; + exports.GradientColor = GradientColor; + exports.GradientDataInt = GradientDataInt; + exports.GradientDataNumber = GradientDataNumber; + exports.GradientDataVector2 = GradientDataVector2; + exports.GradientMode = GradientMode; + exports.GradientSize = GradientSize; + exports.GradientVelocity = GradientVelocity; + exports.HeightMap = HeightMap; + exports.HemisphereShape = HemisphereShape; + exports.ILaya3D = ILaya3D; + exports.IndexBuffer3D = IndexBuffer3D; + exports.Input3D = Input3D; + exports.Keyframe = Keyframe; + exports.KeyframeNode = KeyframeNode; + exports.KeyframeNodeList = KeyframeNodeList; + exports.KeyframeNodeOwner = KeyframeNodeOwner; + exports.Laya3D = Laya3D; + exports.LightQueue = LightQueue; + exports.LightSprite = LightSprite; + exports.Lightmap = Lightmap; + exports.LoadModelV04 = LoadModelV04; + exports.LoadModelV05 = LoadModelV05; + exports.Material = Material; + exports.MaterialInstanceProperty = MaterialInstanceProperty; + exports.MaterialInstancePropertyBlock = MaterialInstancePropertyBlock; + exports.MathUtils3D = MathUtils3D; + exports.Matrix3x3 = Matrix3x3; + exports.Matrix4x4 = Matrix4x4; + exports.Mesh = Mesh; + exports.MeshFilter = MeshFilter; + exports.MeshReader = MeshReader; + exports.MeshRenderDynamicBatchManager = MeshRenderDynamicBatchManager; + exports.MeshRenderStaticBatchManager = MeshRenderStaticBatchManager; + exports.MeshRenderer = MeshRenderer; + exports.MeshSprite3D = MeshSprite3D; + exports.MeshSprite3DShaderDeclaration = MeshSprite3DShaderDeclaration; + exports.MeshTerrainSprite3D = MeshTerrainSprite3D; + exports.MouseTouch = MouseTouch; + exports.OctreeMotionList = OctreeMotionList; + exports.PBRMaterial = PBRMaterial; + exports.PBRSpecularMaterial = PBRSpecularMaterial; + exports.PBRStandardMaterial = PBRStandardMaterial; + exports.Physics3D = Physics3D; + exports.Physics3DUtils = Physics3DUtils; + exports.Picker = Picker; + exports.PixelLineData = PixelLineData; + exports.PixelLineFilter = PixelLineFilter; + exports.PixelLineMaterial = PixelLineMaterial; + exports.PixelLineRenderer = PixelLineRenderer; + exports.PixelLineSprite3D = PixelLineSprite3D; + exports.PixelLineVertex = PixelLineVertex; + exports.Plane = Plane; + exports.PointLight = PointLight; + exports.PostProcess = PostProcess; + exports.PostProcessEffect = PostProcessEffect; + exports.PostProcessRenderContext = PostProcessRenderContext; + exports.PrimitiveMesh = PrimitiveMesh; + exports.Quaternion = Quaternion; + exports.QuaternionKeyframe = QuaternionKeyframe; + exports.Rand = Rand; + exports.RandX = RandX; + exports.Ray = Ray; + exports.ReflectionProbe = ReflectionProbe; + exports.ReflectionProbeList = ReflectionProbeList; + exports.ReflectionProbeManager = ReflectionProbeManager; + exports.RenderContext3D = RenderContext3D; + exports.RenderElement = RenderElement; + exports.RenderQueue = RenderQueue; + exports.RenderState = RenderState; + exports.RenderTexture = RenderTexture; + exports.RenderableSprite3D = RenderableSprite3D; + exports.RotationOverLifetime = RotationOverLifetime; + exports.Scene3D = Scene3D; + exports.Scene3DShaderDeclaration = Scene3DShaderDeclaration; + exports.Scene3DUtils = Scene3DUtils; + exports.ScreenQuad = ScreenQuad; + exports.ScreenTriangle = ScreenTriangle; + exports.Script3D = Script3D; + exports.SetGlobalShaderDataCMD = SetGlobalShaderDataCMD; + exports.SetRenderTargetCMD = SetRenderTargetCMD; + exports.SetShaderDataCMD = SetShaderDataCMD; + exports.Shader3D = Shader3D; + exports.ShaderData = ShaderData; + exports.ShaderDefine = ShaderDefine; + exports.ShaderInit3D = ShaderInit3D; + exports.ShaderInstance = ShaderInstance; + exports.ShaderPass = ShaderPass; + exports.ShaderVariable = ShaderVariable; + exports.ShaderVariant = ShaderVariant; + exports.ShaderVariantCollection = ShaderVariantCollection; + exports.ShadowCasterPass = ShadowCasterPass; + exports.ShadowCullInfo = ShadowCullInfo; + exports.ShadowSliceData = ShadowSliceData; + exports.ShadowSpotData = ShadowSpotData; + exports.ShadowUtils = ShadowUtils; + exports.ShapeUtils = ShapeUtils; + exports.ShuriKenParticle3D = ShuriKenParticle3D; + exports.ShuriKenParticle3DShaderDeclaration = ShuriKenParticle3DShaderDeclaration; + exports.ShurikenParticleData = ShurikenParticleData; + exports.ShurikenParticleMaterial = ShurikenParticleMaterial; + exports.ShurikenParticleRenderer = ShurikenParticleRenderer; + exports.ShurikenParticleSystem = ShurikenParticleSystem; + exports.SimpleSingletonList = SimpleSingletonList; + exports.SimpleSkinnedMeshRenderer = SimpleSkinnedMeshRenderer; + exports.SimpleSkinnedMeshSprite3D = SimpleSkinnedMeshSprite3D; + exports.SingletonList = SingletonList; + exports.Size = Size; + exports.SizeOverLifetime = SizeOverLifetime; + exports.SkinnedMeshRenderer = SkinnedMeshRenderer; + exports.SkinnedMeshSprite3D = SkinnedMeshSprite3D; + exports.SkinnedMeshSprite3DShaderDeclaration = SkinnedMeshSprite3DShaderDeclaration; + exports.SkyBox = SkyBox; + exports.SkyBoxMaterial = SkyBoxMaterial; + exports.SkyDome = SkyDome; + exports.SkyMesh = SkyMesh; + exports.SkyPanoramicMaterial = SkyPanoramicMaterial; + exports.SkyProceduralMaterial = SkyProceduralMaterial; + exports.SkyRenderer = SkyRenderer; + exports.SphereShape = SphereShape; + exports.SphericalHarmonicsL2 = SphericalHarmonicsL2; + exports.SpotLight = SpotLight; + exports.Sprite3D = Sprite3D; + exports.StartFrame = StartFrame; + exports.StaticBatchManager = StaticBatchManager; + exports.SubMesh = SubMesh; + exports.SubMeshDynamicBatch = SubMeshDynamicBatch; + exports.SubMeshInstanceBatch = SubMeshInstanceBatch; + exports.SubMeshRenderElement = SubMeshRenderElement; + exports.SubMeshStaticBatch = SubMeshStaticBatch; + exports.SubShader = SubShader; + exports.TextMesh = TextMesh; + exports.TextureCube = TextureCube; + exports.TextureGenerator = TextureGenerator; + exports.TextureMode = TextureMode; + exports.TextureSheetAnimation = TextureSheetAnimation; + exports.Touch = Touch; + exports.TrailFilter = TrailFilter; + exports.TrailGeometry = TrailGeometry; + exports.TrailMaterial = TrailMaterial; + exports.TrailRenderer = TrailRenderer; + exports.TrailSprite3D = TrailSprite3D; + exports.Transform3D = Transform3D; + exports.UnlitMaterial = UnlitMaterial; + exports.Utils3D = Utils3D; + exports.Vector2 = Vector2; + exports.Vector3 = Vector3; + exports.Vector3Keyframe = Vector3Keyframe; + exports.Vector4 = Vector4; + exports.VelocityOverLifetime = VelocityOverLifetime; + exports.VertexBuffer3D = VertexBuffer3D; + exports.VertexDeclaration = VertexDeclaration; + exports.VertexElement = VertexElement; + exports.VertexElementFormat = VertexElementFormat; + exports.VertexMesh = VertexMesh; + exports.VertexPositionTerrain = VertexPositionTerrain; + exports.VertexPositionTexture0 = VertexPositionTexture0; + exports.VertexShuriKenParticle = VertexShuriKenParticle; + exports.VertexShurikenParticleBillboard = VertexShurikenParticleBillboard; + exports.VertexShurikenParticleMesh = VertexShurikenParticleMesh; + exports.VertexTrail = VertexTrail; + exports.Viewport = Viewport; + exports.WaterPrimaryMaterial = WaterPrimaryMaterial; + exports.skinnedMatrixCache = skinnedMatrixCache; + +}(window.Laya = window.Laya || {}, Laya)); diff --git a/examples/layaair/frontend/bin/libs/laya.debugtool.js b/examples/layaair/frontend/bin/libs/laya.debugtool.js new file mode 100644 index 0000000..66a6eb4 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.debugtool.js @@ -0,0 +1,7960 @@ +(function (exports, Laya) { + 'use strict'; + + class StringTool { + constructor() { + } + static toUpCase(str) { + return str.toUpperCase(); + } + static toLowCase(str) { + return str.toLowerCase(); + } + static toUpHead(str) { + var rst; + if (str.length <= 1) + return str.toUpperCase(); + rst = str.charAt(0).toUpperCase() + str.substr(1); + return rst; + } + static toLowHead(str) { + var rst; + if (str.length <= 1) + return str.toLowerCase(); + rst = str.charAt(0).toLowerCase() + str.substr(1); + return rst; + } + static packageToFolderPath(packageName) { + var rst; + rst = packageName.replace(".", "/"); + return rst; + } + static insert(str, iStr, index) { + return str.substring(0, index) + iStr + str.substr(index); + } + static insertAfter(str, iStr, tarStr, isLast = false) { + var i; + if (isLast) { + i = str.lastIndexOf(tarStr); + } + else { + i = str.indexOf(tarStr); + } + if (i >= 0) { + return StringTool.insert(str, iStr, i + tarStr.length); + } + return str; + } + static insertBefore(str, iStr, tarStr, isLast = false) { + var i; + if (isLast) { + i = str.lastIndexOf(tarStr); + } + else { + i = str.indexOf(tarStr); + } + if (i >= 0) { + return StringTool.insert(str, iStr, i); + } + return str; + } + static insertParamToFun(funStr, params) { + var oldParam; + oldParam = StringTool.getParamArr(funStr); + var inserStr; + inserStr = params.join(","); + if (oldParam.length > 0) { + inserStr = "," + inserStr; + } + return StringTool.insertBefore(funStr, inserStr, ")", true); + } + static trim(str, vList = null) { + if (!vList) { + vList = [" ", "\r", "\n", "\t", String.fromCharCode(65279)]; + } + var rst; + var i; + var len; + rst = str; + len = vList.length; + for (i = 0; i < len; i++) { + rst = StringTool.getReplace(rst, vList[i], ""); + } + return rst; + } + static isEmpty(str) { + if (str.length < 1) + return true; + return StringTool.emptyStrDic.hasOwnProperty(str); + } + static trimLeft(str) { + var i; + i = 0; + var len; + len = str.length; + while (StringTool.isEmpty(str.charAt(i)) && i < len) { + i++; + } + if (i < len) { + return str.substr(i); + } + return ""; + } + static trimRight(str) { + var i; + i = str.length - 1; + while (StringTool.isEmpty(str.charAt(i)) && i >= 0) { + i--; + } + var rst; + rst = str.substring(0, i); + if (i >= 0) { + return str.substring(0, i + 1); + } + return ""; + } + static trimSide(str) { + var rst; + rst = StringTool.trimLeft(str); + rst = StringTool.trimRight(rst); + return rst; + } + static isOkFileName(fileName) { + if (StringTool.trimSide(fileName) == "") + return false; + var i, len; + len = fileName.length; + for (i = 0; i < len; i++) { + if (StringTool.specialChars[fileName.charAt(i)]) + return false; + } + return true; + } + static trimButEmpty(str) { + return StringTool.trim(str, ["\r", "\n", "\t"]); + } + static removeEmptyStr(strArr) { + var i; + i = strArr.length - 1; + var str; + for (i = i; i >= 0; i--) { + str = strArr[i]; + str = StringTool.trimSide(str); + if (StringTool.isEmpty(str)) { + strArr.splice(i, 1); + } + else { + strArr[i] = str; + } + } + return strArr; + } + static ifNoAddToTail(str, sign) { + if (str.indexOf(sign) >= 0) { + return str; + } + return str + sign; + } + static trimEmptyLine(str) { + var i; + var tLines; + var tLine; + tLines = str.split("\n"); + for (i = tLines.length - 1; i >= 0; i--) { + tLine = tLines[i]; + if (StringTool.isEmptyLine(tLine)) { + tLines.splice(i, 1); + } + } + return tLines.join("\n"); + } + static isEmptyLine(str) { + str = StringTool.trim(str); + if (str == "") + return true; + return false; + } + static removeCommentLine(lines) { + var rst; + rst = []; + var i; + var tLine; + var adptLine; + i = 0; + var len; + var index; + len = lines.length; + while (i < len) { + adptLine = tLine = lines[i]; + index = tLine.indexOf("/**"); + if (index >= 0) { + adptLine = tLine.substring(0, index - 1); + StringTool.addIfNotEmpty(rst, adptLine); + while (i < len) { + tLine = lines[i]; + index = tLine.indexOf("*/"); + if (index >= 0) { + adptLine = tLine.substring(index + 2); + StringTool.addIfNotEmpty(rst, adptLine); + break; + } + i++; + } + } + else if (tLine.indexOf("//") >= 0) { + if (StringTool.trim(tLine).indexOf("//") == 0) ; + else { + StringTool.addIfNotEmpty(rst, adptLine); + } + } + else { + StringTool.addIfNotEmpty(rst, adptLine); + } + i++; + } + return rst; + } + static addIfNotEmpty(arr, str) { + if (!str) + return; + var tStr; + tStr = StringTool.trim(str); + if (tStr != "") { + arr.push(str); + } + } + static trimExt(str, vars) { + var rst; + rst = StringTool.trim(str); + var i; + var len; + len = vars.length; + for (i = 0; i < len; i++) { + rst = StringTool.getReplace(rst, vars[i], ""); + } + return rst; + } + static getBetween(str, left, right, ifMax = false) { + if (!str) + return ""; + if (!left) + return ""; + if (!right) + return ""; + var lId; + var rId; + lId = str.indexOf(left); + if (lId < 0) + return ""; + if (ifMax) { + rId = str.lastIndexOf(right); + if (rId < lId) + return ""; + } + else { + rId = str.indexOf(right, lId + 1); + } + if (rId < 0) + return ""; + return str.substring(lId + left.length, rId); + } + static getSplitLine(line, split = " ") { + return line.split(split); + } + static getLeft(str, sign) { + var i; + i = str.indexOf(sign); + return str.substr(0, i); + } + static getRight(str, sign) { + var i; + i = str.indexOf(sign); + return str.substr(i + 1); + } + static delelteItem(arr) { + while (arr.length > 0) { + if (arr[0] == "") { + arr.shift(); + } + else { + break; + } + } + } + static getWords(line) { + var rst = StringTool.getSplitLine(line); + StringTool.delelteItem(rst); + return rst; + } + static getLinesI(startLine, endLine, lines) { + var i; + var rst = []; + for (i = startLine; i <= endLine; i++) { + rst.push(lines[i]); + } + return rst; + } + static structfy(str, inWidth = 4, removeEmpty = true) { + if (removeEmpty) { + str = StringTool.trimEmptyLine(str); + } + var lines; + var tIn; + tIn = 0; + var tInStr; + tInStr = StringTool.getEmptyStr(0); + lines = str.split("\n"); + var i; + var len; + var tLineStr; + len = lines.length; + for (i = 0; i < len; i++) { + tLineStr = lines[i]; + tLineStr = StringTool.trimLeft(tLineStr); + tLineStr = StringTool.trimRight(tLineStr); + tIn += StringTool.getPariCount(tLineStr); + if (tLineStr.indexOf("}") >= 0) { + tInStr = StringTool.getEmptyStr(tIn * inWidth); + } + tLineStr = tInStr + tLineStr; + lines[i] = tLineStr; + tInStr = StringTool.getEmptyStr(tIn * inWidth); + } + return lines.join("\n"); + } + static getEmptyStr(width) { + if (!StringTool.emptyDic.hasOwnProperty(width)) { + var i; + var len; + len = width; + var rst; + rst = ""; + for (i = 0; i < len; i++) { + rst += " "; + } + StringTool.emptyDic[width] = rst; + } + return StringTool.emptyDic[width]; + } + static getPariCount(str, inChar = "{", outChar = "}") { + var varDic; + varDic = {}; + varDic[inChar] = 1; + varDic[outChar] = -1; + var i; + var len; + var tChar; + len = str.length; + var rst; + rst = 0; + for (i = 0; i < len; i++) { + tChar = str.charAt(i); + if (varDic.hasOwnProperty(tChar)) { + rst += varDic[tChar]; + } + } + return rst; + } + static readInt(str, startI = 0) { + var rst; + rst = 0; + var tC; + var i; + var isBegin; + isBegin = false; + var len; + len = str.length; + for (i = startI; i < len; i++) { + tC = str.charAt(i); + if (Number(tC) > 0 || tC == "0") { + rst = 10 * rst + Number(tC); + if (rst > 0) + isBegin = true; + } + else { + if (isBegin) + return rst; + } + } + return rst; + } + static getReplace(str, oStr, nStr) { + if (!str) + return ""; + var rst; + rst = str.replace(new RegExp(oStr, "g"), nStr); + return rst; + } + static getWordCount(str, findWord) { + var rg = new RegExp(findWord, "g"); + return str.match(rg).length; + } + static getResolvePath(path, basePath) { + if (StringTool.isAbsPath(path)) { + return path; + } + var tSign; + tSign = "\\"; + if (basePath.indexOf("/") >= 0) { + tSign = "/"; + } + if (basePath.charAt(basePath.length - 1) == tSign) { + basePath = basePath.substr(0, basePath.length - 1); + } + var parentSign; + parentSign = ".." + tSign; + var tISign; + tISign = "." + tSign; + var pCount; + pCount = StringTool.getWordCount(path, parentSign); + path = StringTool.getReplace(path, parentSign, ""); + path = StringTool.getReplace(path, tISign, ""); + var i; + var len; + len = pCount; + for (i = 0; i < len; i++) { + basePath = StringTool.removeLastSign(path, tSign); + } + return basePath + tSign + path; + } + static isAbsPath(path) { + if (path.indexOf(":") >= 0) + return true; + return false; + } + static removeLastSign(str, sign) { + var iPos; + iPos = str.lastIndexOf(sign); + str = str.substring(0, iPos); + return str; + } + static getParamArr(str) { + var paramStr; + paramStr = StringTool.getBetween(str, "(", ")", true); + if (StringTool.trim(paramStr).length < 1) + return []; + return paramStr.split(","); + } + static copyStr(str) { + return str.substring(0); + } + static ArrayToString(arr) { + var rst; + rst = "[{items}]".replace(new RegExp("\\{items\\}", "g"), StringTool.getArrayItems(arr)); + return rst; + } + static getArrayItems(arr) { + var rst; + if (arr.length < 1) + return ""; + rst = StringTool.parseItem(arr[0]); + var i; + var len; + len = arr.length; + for (i = 1; i < len; i++) { + rst += "," + StringTool.parseItem(arr[i]); + } + return rst; + } + static parseItem(item) { + return ""; + } + static initAlphaSign() { + if (StringTool.alphaSigns) + return; + StringTool.alphaSigns = {}; + StringTool.addSign("a", "z", StringTool.alphaSigns); + StringTool.addSign("A", "Z", StringTool.alphaSigns); + StringTool.addSign("0", "9", StringTool.alphaSigns); + } + static addSign(ss, e, tar) { + var i; + var len; + var s; + s = ss.charCodeAt(0); + len = e.charCodeAt(0); + for (i = s; i <= len; i++) { + tar[String.fromCharCode(i)] = true; + console.log("add :" + String.fromCharCode(i)); + } + } + static isPureAlphaNum(str) { + StringTool.initAlphaSign(); + if (!str) + return true; + var i, len; + len = str.length; + for (i = 0; i < len; i++) { + if (!StringTool.alphaSigns[str.charAt(i)]) + return false; + } + return true; + } + } + StringTool.emptyStrDic = { + " ": true, + "\r": true, + "\n": true, + "\t": true + }; + StringTool.specialChars = { "*": true, "&": true, "%": true, "#": true, "?": true }; + StringTool.emptyDic = {}; + StringTool.alphaSigns = null; + + class ObjectTools { + constructor() { + } + static getFlatKey(tKey, aKey) { + if (tKey == "") + return aKey; + return tKey + ObjectTools.sign + aKey; + } + static flatObj(obj, rst = null, tKey = "") { + rst = rst ? rst : {}; + var key; + var tValue; + for (key in obj) { + if (obj[key] instanceof Object) { + ObjectTools.flatObj(obj[key], rst, ObjectTools.getFlatKey(tKey, key)); + } + else { + tValue = obj[key]; + rst[ObjectTools.getFlatKey(tKey, key)] = obj[key]; + } + } + return rst; + } + static recoverObj(obj) { + var rst = {}; + var tKey; + for (tKey in obj) { + ObjectTools.setKeyValue(rst, tKey, obj[tKey]); + } + return rst; + } + static differ(objA, objB) { + var tKey; + objA = ObjectTools.flatObj(objA); + objB = ObjectTools.flatObj(objB); + var rst = {}; + for (tKey in objA) { + if (!objB.hasOwnProperty(tKey)) { + rst[tKey] = "被删除"; + } + } + for (tKey in objB) { + if (objB[tKey] != objA[tKey]) { + rst[tKey] = { "pre": objA[tKey], "now": objB[tKey] }; + } + } + return rst; + } + static traceDifferObj(obj) { + var key; + var tO; + for (key in obj) { + if (obj[key] instanceof String) { + console.log(key + ":", obj[key]); + } + else { + tO = obj[key]; + console.log(key + ":", "now:", tO["now"], "pre:", tO["pre"]); + } + } + } + static setKeyValue(obj, flatKey, value) { + if (flatKey.indexOf(ObjectTools.sign) >= 0) { + var keys = flatKey.split(ObjectTools.sign); + var tKey; + while (keys.length > 1) { + tKey = keys.shift(); + if (!obj[tKey]) { + obj[tKey] = {}; + console.log("addKeyObj:", tKey); + } + obj = obj[tKey]; + if (!obj) { + console.log("wrong flatKey:", flatKey); + return; + } + } + obj[keys.shift()] = value; + } + else { + obj[flatKey] = value; + } + } + static clearObj(obj) { + var key; + for (key in obj) { + delete obj[key]; + } + } + static copyObjFast(obj) { + var jsStr; + jsStr = ObjectTools.getJsonString(obj); + return ObjectTools.getObj(jsStr); + } + static copyObj(obj) { + if (obj instanceof Array) + return ObjectTools.copyArr(obj); + var rst = {}; + var key; + for (key in obj) { + if (obj[key] === null || obj[key] === undefined) { + rst[key] = obj[key]; + } + else if (obj[key] instanceof Array) { + rst[key] = ObjectTools.copyArr(obj[key]); + } + else if (obj[key] instanceof Object) { + rst[key] = ObjectTools.copyObj(obj[key]); + } + else { + rst[key] = obj[key]; + } + } + return rst; + } + static copyArr(arr) { + var rst; + rst = []; + var i, len; + len = arr.length; + for (i = 0; i < len; i++) { + rst.push(ObjectTools.copyObj(arr[i])); + } + return rst; + } + static concatArr(src, a) { + if (!a) + return src; + if (!src) + return a; + var i, len = a.length; + for (i = 0; i < len; i++) { + src.push(a[i]); + } + return src; + } + static insertArrToArr(src, insertArr, pos = 0) { + if (pos < 0) + pos = 0; + if (pos > src.length) + pos = src.length; + var preLen = src.length; + var i, len; + src.length += insertArr.length; + var moveLen; + moveLen = insertArr.length; + for (i = src.length - 1; i >= pos; i--) { + src[i] = src[i - moveLen]; + } + len = insertArr.length; + for (i = 0; i < len; i++) { + src[pos + i] = insertArr[i]; + } + return src; + } + static clearArr(arr) { + if (!arr) + return arr; + arr.length = 0; + return arr; + } + static removeFromArr(arr, item) { + var i, len; + len = arr.length; + for (i = 0; i < len; i++) { + if (arr[i] == item) { + arr[i].splice(i, 1); + return; + } + } + } + static setValueArr(src, v) { + src || (src = []); + src.length = 0; + return ObjectTools.concatArr(src, v); + } + static getFrom(rst, src, count) { + var i; + for (i = 0; i < count; i++) { + rst.push(src[i]); + } + return rst; + } + static getFromR(rst, src, count) { + var i; + for (i = 0; i < count; i++) { + rst.push(src.pop()); + } + return rst; + } + static enableDisplayTree(dis) { + while (dis) { + dis.mouseEnabled = true; + dis = dis.parent; + } + } + static getJsonString(obj) { + var rst; + rst = JSON.stringify(obj); + return rst; + } + static getObj(jsonStr) { + var rst; + rst = JSON.parse(jsonStr); + return rst; + } + static getKeyArr(obj) { + var rst; + var key; + rst = []; + for (key in obj) { + rst.push(key); + } + return rst; + } + static getObjValues(dataList, key) { + var rst; + var i, len; + len = dataList.length; + rst = []; + for (i = 0; i < len; i++) { + rst.push(dataList[i][key]); + } + return rst; + } + static hasKeys(obj, keys) { + var i, len; + len = keys.length; + for (i = 0; i < len; i++) { + if (!obj.hasOwnProperty(keys[i])) + return false; + } + return true; + } + static copyValueByArr(tar, src, keys) { + var i, len = keys.length; + for (i = 0; i < len; i++) { + if (!(src[keys[i]] === null)) + tar[keys[i]] = src[keys[i]]; + } + } + static getNoSameArr(arr) { + var i, len; + var rst; + rst = []; + var tItem; + len = arr.length; + for (i = 0; i < len; i++) { + tItem = arr[i]; + if (rst.indexOf(tItem) < 0) { + rst.push(tItem); + } + } + return rst; + } + static insertValue(tar, src) { + var key; + for (key in src) { + tar[key] = src[key]; + } + } + static replaceValue(obj, replaceO) { + var key; + for (key in obj) { + if (replaceO.hasOwnProperty(obj[key])) { + obj[key] = replaceO[obj[key]]; + } + if (obj[key] instanceof Object) { + ObjectTools.replaceValue(obj[key], replaceO); + } + } + } + static setKeyValues(items, key, value) { + var i, len; + len = items.length; + for (i = 0; i < len; i++) { + items[i][key] = value; + } + } + static findItemPos(items, sign, value) { + var i, len; + len = items.length; + for (i = 0; i < len; i++) { + if (items[i][sign] == value) { + return i; + } + } + return -1; + } + static setObjValue(obj, key, value) { + obj[key] = value; + return obj; + } + static setAutoTypeValue(obj, key, value) { + if (obj.hasOwnProperty(key)) { + if (ObjectTools.isNumber(obj[key])) { + obj[key] = parseFloat(value); + } + else { + obj[key] = value; + } + } + else { + obj[key] = value; + } + return obj; + } + static getAutoValue(value) { + var tFloat = parseFloat(value); + if (typeof (value) == "string") { + if (tFloat + "" === StringTool.trimSide(value)) + return tFloat; + } + return value; + } + static isNumber(value) { + return (parseFloat(value) == value); + } + static isNaNS(value) { + return (value.toString() == "NaN"); + } + static isNaN(value) { + if (typeof (value) == "number") + return false; + if (typeof (value) == "string") { + if (parseFloat(value).toString() != "NaN") { + return false; + } + } + return true; + } + static getStrTypedValue(value) { + if (value == "false") { + return false; + } + else if (value == "true") { + return true; + } + else if (value == "null") { + return null; + } + else if (value == "undefined") { + return null; + } + else { + return ObjectTools.getAutoValue(value); + } + } + static createKeyValueDic(dataList, keySign) { + var rst; + rst = {}; + var i, len; + len = dataList.length; + var tItem; + var tKey; + for (i = 0; i < len; i++) { + tItem = dataList[i]; + tKey = tItem[keySign]; + rst[tKey] = tItem; + } + return rst; + } + } + ObjectTools.sign = "_"; + + class ClassTool { + constructor() { + } + static defineProperty(obj, name, des) { + Object.defineProperty(obj, name, des); + } + static getOwnPropertyDescriptor(obj, name) { + var rst; + rst = Object.getOwnPropertyDescriptor(obj, name); + return rst; + } + static getOwnPropertyDescriptors(obj) { + var rst; + rst = Object.getOwnPropertyDescriptors(obj); + return rst; + } + static getOwnPropertyNames(obj) { + var rst; + rst = Object.getOwnPropertyNames(obj); + return rst; + } + static getObjectGetSetKeys(obj, rst = null) { + if (!rst) + rst = []; + var keys; + keys = ClassTool.getOwnPropertyNames(obj); + var key; + for (key in keys) { + key = keys[key]; + if (key.indexOf("_$get_") >= 0) { + key = key.replace("_$get_", ""); + rst.push(key); + } + } + if (obj["__proto__"]) { + ClassTool.getObjectGetSetKeys(obj["__proto__"], rst); + } + return rst; + } + static getObjectDisplayAbleKeys(obj, rst = null) { + if (!rst) + rst = []; + for (let key in obj) { + let tValue = obj[key]; + let tType = typeof (tValue); + if (key.charAt(0) == "_" || !this.displayTypes[tType]) + continue; + rst.push(key); + } + let temp = obj; + while (temp) { + let descript = Object.getOwnPropertyDescriptors(temp); + for (let element in descript) { + let tValue = descript[element]; + if (!tValue.get) + continue; + rst.push(element); + } + temp = Object.getPrototypeOf(temp); + } + ClassTool.getObjectGetSetKeys(obj, rst); + rst = ObjectTools.getNoSameArr(rst); + return rst; + } + static getClassName(tar) { + if (tar instanceof Function) + return tar.name; + return tar["constructor"].name; + } + static getNodeClassAndName(tar) { + if (!tar) + return "null"; + var rst; + if (tar.name) { + rst = ClassTool.getClassName(tar) + "(" + tar.name + ")"; + } + else { + rst = ClassTool.getClassName(tar); + } + return rst; + } + static getClassNameByClz(clz) { + return clz["name"]; + } + static getClassByName(className) { + var rst; + rst = window["eval"](className); + return rst; + } + static createObjByName(className) { + var clz; + clz = ClassTool.getClassByName(className); + return new clz(); + } + } + ClassTool.displayTypes = { "boolean": true, "number": true, "string": true }; + + class TraceTool { + constructor() { } + static closeAllLog() { + var logFun; + logFun = TraceTool.emptyLog; + Laya.Browser.window.console.log = logFun; + } + static emptyLog() { + } + static traceObj(obj) { + TraceTool.tempArr.length = 0; + var key; + for (key in obj) { + TraceTool.tempArr.push(key + ":" + obj[key]); + } + var rst; + rst = TraceTool.tempArr.join("\n"); + console.log(rst); + return rst; + } + static traceObjR(obj) { + TraceTool.tempArr.length = 0; + var key; + for (key in obj) { + TraceTool.tempArr.push(obj[key] + ":" + key); + } + var rst; + rst = TraceTool.tempArr.join("\n"); + console.log(rst); + return rst; + } + static traceSize(tar) { + TraceTool._debugtrace("Size: x:" + tar.x + " y:" + tar.y + " w:" + tar.width + " h:" + tar.height + " scaleX:" + tar.scaleX + " scaleY:" + tar.scaleY); + } + static traceSplit(msg) { + console.log("---------------------" + msg + "---------------------------"); + } + static group(gName) { + console.group(gName); + } + static groupEnd() { + console.groupEnd(); + } + static getCallStack(life = 1, s = 1) { + var caller; + caller = TraceTool.getCallStack; + caller = caller.caller.caller; + var msg; + msg = ""; + while (caller && life > 0) { + if (s <= 0) { + msg += caller + "<-"; + life--; + } + caller = caller.caller; + s--; + } + return msg; + } + static getCallLoc(index = 2) { + var loc; + try { + TraceTool.Erroer.i++; + } + catch (e) { + var arr; + arr = this.e.stack.replace(/Error\n/).split(/\n/); + if (arr[index]) { + loc = arr[index].replace(/^\s+|\s+$/, ""); + } + else { + loc = "unknow"; + } + } + return loc; + } + static traceCallStack() { + var loc; + try { + TraceTool.Erroer.i++; + } + catch (e) { + loc = this.e.stack; + } + console.log(loc); + return loc; + } + static getPlaceHolder(len) { + if (!TraceTool.holderDic.hasOwnProperty(len)) { + var rst; + rst = ""; + var i; + for (i = 0; i < len; i++) { + rst += "-"; + } + TraceTool.holderDic[len] = rst; + } + return TraceTool.holderDic[len]; + } + static traceTree(tar, depth = 0, isFirst = true) { + if (isFirst) { + console.log("traceTree"); + } + if (!tar) + return; + var i; + var len; + if (tar.numChildren < 1) { + console.log(tar); + return; + } + TraceTool.group(tar); + len = tar.numChildren; + depth++; + for (i = 0; i < len; i++) { + TraceTool.traceTree(tar.getChildAt(i), depth, false); + } + TraceTool.groupEnd(); + } + static getClassName(tar) { + return tar["constructor"].name; + } + static traceSpriteInfo(tar, showBounds = true, showSize = true, showTree = true) { + if (!(tar instanceof Laya.Sprite)) { + console.log("not Sprite"); + return; + } + if (!tar) { + console.log("null Sprite"); + return; + } + TraceTool.traceSplit("traceSpriteInfo"); + TraceTool._debugtrace(TraceTool.getClassName(tar) + ":" + tar.name); + if (showTree) { + TraceTool.traceTree(tar); + } + else { + console.log(tar); + } + if (showSize) { + TraceTool.traceSize(tar); + } + if (showBounds) { + console.log("bounds:" + tar.getBounds()); + } + } + } + TraceTool.tempArr = []; + TraceTool.Erroer = null; + TraceTool.holderDic = {}; + + class CountTool { + constructor() { + this.data = {}; + this.preO = {}; + this.changeO = {}; + } + reset() { + this.data = {}; + this.count = 0; + } + add(name, num = 1) { + this.count++; + if (!this.data.hasOwnProperty(name)) { + this.data[name] = 0; + } + this.data[name] = this.data[name] + num; + } + getKeyCount(key) { + if (!this.data.hasOwnProperty(key)) { + this.data[key] = 0; + } + return this.data[key]; + } + getKeyChange(key) { + if (!this.changeO[key]) + return 0; + return this.changeO[key]; + } + record() { + var key; + for (key in this.changeO) { + this.changeO[key] = 0; + } + for (key in this.data) { + if (!this.preO[key]) + this.preO[key] = 0; + this.changeO[key] = this.data[key] - this.preO[key]; + this.preO[key] = this.data[key]; + } + } + getCount(dataO) { + var rst = 0; + var key; + for (key in dataO) { + rst += dataO[key]; + } + return rst; + } + traceSelf(dataO = null) { + if (!dataO) + dataO = this.data; + var tCount; + tCount = this.getCount(dataO); + console.log("total:" + tCount); + return "total:" + tCount + "\n" + TraceTool.traceObj(dataO); + } + traceSelfR(dataO = null) { + if (!dataO) + dataO = this.data; + var tCount; + tCount = this.getCount(dataO); + console.log("total:" + tCount); + return "total:" + tCount + "\n" + TraceTool.traceObjR(dataO); + } + } + + class RecInfo { + constructor() { + this.oX = 0; + this.oY = 0; + this.hX = 1; + this.hY = 0; + this.vX = 0; + this.vY = 1; + } + get x() { + return this.oX; + } + get y() { + return this.oY; + } + get width() { + return Math.sqrt((this.hX - this.oX) * (this.hX - this.oX) + (this.hY - this.oY) * (this.hY - this.oY)); + } + get height() { + return Math.sqrt((this.vX - this.oX) * (this.vX - this.oX) + (this.vY - this.oY) * (this.vY - this.oY)); + } + get rotation() { + return this.rotationRad / Math.PI * 180; + } + get rotationRad() { + var dx = this.hX - this.oX; + var dy = this.hY - this.oY; + return Math.atan2(dy, dx); + } + get rotationV() { + return this.rotationRadV / Math.PI * 180; + } + get rotationRadV() { + var dx = this.vX - this.oX; + var dy = this.vY - this.oY; + return Math.atan2(dy, dx); + } + initByPoints(oPoint, ePoint, vPoint) { + this.oX = oPoint.x; + this.oY = oPoint.y; + this.hX = ePoint.x; + this.hY = ePoint.y; + this.vX = vPoint.x; + this.vY = vPoint.y; + } + static createByPoints(oPoint, ePoint, vPoint) { + var rst; + rst = new RecInfo(); + rst.initByPoints(oPoint, ePoint, vPoint); + return rst; + } + static getGlobalPoints(sprite, x, y) { + return sprite.localToGlobal(new Laya.Point(x, y)); + } + static getGlobalRecInfo(sprite, x0 = 0, y0 = 0, x1 = 1, y1 = 0, x2 = 0, y2 = 1) { + return RecInfo.createByPoints(RecInfo.getGlobalPoints(sprite, x0, y0), RecInfo.getGlobalPoints(sprite, x1, y1), RecInfo.getGlobalPoints(sprite, x2, y2)); + } + } + + class SimpleResizer { + constructor() { + } + static setResizeAble(clickItem, tar, minWidth = 150, minHeight = 150) { + clickItem.on(Laya.Event.MOUSE_DOWN, null, SimpleResizer.onMouseDown, [tar, minWidth, minHeight]); + } + static onMouseDown(tar, minWidth, minHeight, e) { + SimpleResizer.clearEvents(); + if (!tar) + return; + SimpleResizer.preMousePoint.setTo(Laya.Laya.stage.mouseX, Laya.Laya.stage.mouseY); + SimpleResizer.preTarSize.setTo(tar.width, tar.height); + SimpleResizer.preScale.setTo(1, 1); + var rTar; + rTar = tar; + while (rTar && rTar != Laya.Laya.stage) { + SimpleResizer.preScale.x *= rTar.scaleX; + SimpleResizer.preScale.y *= rTar.scaleY; + rTar = rTar.parent; + } + Laya.Laya.stage.on(Laya.Event.MOUSE_UP, null, SimpleResizer.onMouseMoveEnd); + Laya.Laya.timer.loop(100, null, SimpleResizer.onMouseMoving, [tar, minWidth, minHeight]); + } + static onMouseMoving(tar, minWidth, minHeight, e) { + var tWidth = (Laya.Laya.stage.mouseX - SimpleResizer.preMousePoint.x) / SimpleResizer.preScale.x + SimpleResizer.preTarSize.x; + var tHeight = (Laya.Laya.stage.mouseY - SimpleResizer.preMousePoint.y) / SimpleResizer.preScale.y + SimpleResizer.preTarSize.y; + tar.width = tWidth > minWidth ? tWidth : minWidth; + tar.height = tHeight > minHeight ? tHeight : minHeight; + } + static onMouseMoveEnd(e) { + SimpleResizer.clearEvents(); + } + static clearEvents() { + Laya.Laya.timer.clear(null, SimpleResizer.onMouseMoving); + Laya.Laya.stage.off(Laya.Event.MOUSE_UP, null, SimpleResizer.onMouseMoveEnd); + } + } + SimpleResizer.preMousePoint = new Laya.Point(); + SimpleResizer.preTarSize = new Laya.Point(); + SimpleResizer.preScale = new Laya.Point(); + + class DisControlTool { + constructor() { + } + static getObjectsUnderPoint(sprite, x, y, rst = null, filterFun = null) { + rst = rst ? rst : []; + if (filterFun != null && !filterFun(sprite)) + return rst; + if (sprite.getBounds().contains(x, y)) { + rst.push(sprite); + var tempP = new Laya.Point(); + tempP.setTo(x, y); + tempP = sprite.fromParentPoint(tempP); + x = tempP.x; + y = tempP.y; + for (var i = sprite._children.length - 1; i > -1; i--) { + var child = sprite._children[i]; + if (child instanceof Laya.Sprite) + DisControlTool.getObjectsUnderPoint(child, x, y, rst, filterFun); + } + } + return rst; + } + static getObjectsUnderGlobalPoint(sprite, filterFun = null) { + var point = new Laya.Point(); + point.setTo(Laya.Laya.stage.mouseX, Laya.Laya.stage.mouseY); + if (sprite.parent) + point = sprite.parent.globalToLocal(point); + return DisControlTool.getObjectsUnderPoint(sprite, point.x, point.y, null, filterFun); + } + static findFirstObjectsUnderGlobalPoint() { + var disList; + disList = DisControlTool.getObjectsUnderGlobalPoint(Laya.Laya.stage); + if (!disList) + return null; + var i, len; + var tDis; + len = disList.length; + for (i = len - 1; i >= 0; i--) { + tDis = disList[i]; + if (tDis && tDis.numChildren < 1) { + return tDis; + } + } + return tDis; + } + static visibleAndEnableObjFun(tar) { + return tar.visible && tar.mouseEnabled; + } + static visibleObjFun(tar) { + return tar.visible; + } + static getMousePoint(sprite) { + var point = new Laya.Point(); + point.setTo(Laya.Laya.stage.mouseX, Laya.Laya.stage.mouseY); + point = sprite.globalToLocal(point); + return point; + } + static isChildE(parent, child) { + if (!parent) + return false; + while (child) { + if (child.parent == parent) + return true; + child = child.parent; + } + return false; + } + static isInTree(pNode, child) { + return pNode == child || DisControlTool.isChildE(pNode, child); + } + static setTop(tar) { + if (tar && tar.parent) { + var tParent; + tParent = tar.parent; + tParent.setChildIndex(tar, tParent.numChildren - 1); + } + } + static clearItemRelativeInfo(item) { + var Nan = "NaN"; + item.getLayout().left = Nan; + item.getLayout().right = Nan; + item.getLayout().top = Nan; + item.getLayout().bottom = Nan; + } + static swap(tarA, tarB) { + if (tarA == tarB) + return; + var iA; + iA = tarA.parent.getChildIndex(tarA); + var iB; + iB = tarB.parent.getChildIndex(tarB); + var bP; + bP = tarB.parent; + tarA.parent.addChildAt(tarB, iA); + bP.addChildAt(tarA, iB); + } + static insertToTarParent(tarA, tars, after = false) { + var tIndex; + var parent; + if (!tarA) + return; + parent = tarA.parent; + if (!parent) + return; + tIndex = parent.getChildIndex(tarA); + if (after) + tIndex++; + DisControlTool.insertToParent(parent, tars, tIndex); + } + static insertToParent(parent, tars, index = -1) { + if (!parent) + return; + if (index < 0) + index = parent.numChildren; + var i, len; + len = tars.length; + for (i = 0; i < len; i++) { + DisControlTool.transParent(tars[i], parent); + parent.addChildAt(tars[i], index); + } + } + static transParent(tar, newParent) { + if (!tar || !newParent) + return; + if (!tar.parent) + return; + var preParent; + preParent = tar.parent; + var pos; + pos = new Laya.Point(tar.x, tar.y); + pos = preParent.localToGlobal(pos); + pos = newParent.globalToLocal(pos); + tar.pos(pos.x, pos.y); + } + static transPoint(nowParent, tarParent, point) { + point = nowParent.localToGlobal(point); + point = tarParent.globalToLocal(point); + return point; + } + static removeItems(itemList) { + var i, len; + len = itemList.length; + for (i = 0; i < len; i++) { + itemList[i].removeSelf(); + } + } + static addItems(itemList, parent) { + var i, len; + len = itemList.length; + for (i = 0; i < len; i++) { + parent.addChild(itemList[i]); + } + } + static getAllChild(tar) { + if (!tar) + return []; + var i; + var len; + var rst = []; + len = tar.numChildren; + for (i = 0; i < len; i++) { + rst.push(tar.getChildAt(i)); + } + return rst; + } + static upDis(child) { + if (child && child.parent) { + var tParent; + tParent = child.parent; + var newIndex; + newIndex = tParent.getChildIndex(child) + 1; + if (newIndex >= tParent.numChildren) { + newIndex = tParent.numChildren - 1; + } + console.log("setChildIndex:" + newIndex); + tParent.setChildIndex(child, newIndex); + } + } + static downDis(child) { + if (child && child.parent) { + var tParent; + tParent = child.parent; + var newIndex; + newIndex = tParent.getChildIndex(child) - 1; + if (newIndex < 0) + newIndex = 0; + console.log("setChildIndex:" + newIndex); + tParent.setChildIndex(child, newIndex); + } + } + static setResizeAbleEx(node) { + var clickItem; + clickItem = node.getChildByName("resizeBtn"); + if (clickItem) { + SimpleResizer.setResizeAble(clickItem, node); + } + } + static setResizeAble(node) { + node.on(Laya.Event.CLICK, null, DisControlTool.resizeHandler, [node]); + } + static setDragingItem(dragBar, tar) { + dragBar.on(Laya.Event.MOUSE_DOWN, null, DisControlTool.dragingHandler, [tar]); + tar.on(Laya.Event.DRAG_END, null, DisControlTool.dragingEnd, [tar]); + } + static dragingHandler(tar) { + if (tar) { + tar.startDrag(); + } + } + static dragingEnd(tar) { + DisControlTool.intFyDisPos(tar); + console.log(tar.x, tar.y); + } + static showToStage(dis, offX = 0, offY = 0) { + var rec = dis.getBounds(); + dis.x = Laya.Laya.stage.mouseX + offX; + dis.y = Laya.Laya.stage.mouseY + offY; + if (dis.x + rec.width > Laya.Laya.stage.width) { + dis.x -= rec.width + offX; + } + if (dis.y + rec.height > Laya.Laya.stage.height) { + dis.y -= rec.height + offY; + } + DisControlTool.intFyDisPos(dis); + } + static intFyDisPos(dis) { + if (!dis) + return; + dis.x = Math.round(dis.x); + dis.y = Math.round(dis.y); + } + static showOnly(disList, showItem) { + var i, len; + len = disList.length; + for (i = 0; i < len; i++) { + disList[i].visible = disList[i] == showItem; + } + } + static showOnlyByIndex(disList, index) { + DisControlTool.showOnly(disList, disList[index]); + } + static addOnly(disList, showItem, parent) { + var i, len; + len = disList.length; + for (i = 0; i < len; i++) { + if (disList[i] != showItem) { + disList[i].removeSelf(); + } + else { + parent.addChild(disList[i]); + } + } + } + static addOnlyByIndex(disList, index, parent) { + DisControlTool.addOnly(disList, disList[index], parent); + } + } + DisControlTool.tempP = new Laya.Point(); + + class Rect extends Laya.Sprite { + constructor() { + super(); + this.recWidth = 10; + this.drawMe(); + } + drawMe() { + var g; + g = this.graphics; + g.clear(); + g.drawRect(0, 0, this.recWidth, this.recWidth, "#22ff22"); + this.size(this.recWidth, this.recWidth); + } + posTo(x, y) { + this.x = x - this.recWidth * 0.5; + this.y = y - this.recWidth * 0.5; + } + } + + class ValueChanger { + constructor() { + this.preValue = 0; + } + get value() { + if (this.target) { + this._tValue = this.target[this.key]; + } + return this._tValue; + } + set value(nValue) { + this._tValue = nValue; + if (this.target) { + this.target[this.key] = nValue; + } + } + get dValue() { + return this.value - this.preValue; + } + get scaleValue() { + return this.value / this.preValue; + } + record() { + this.preValue = this.value; + } + showValueByAdd(addValue) { + this.value = this.preValue + addValue; + } + showValueByScale(scale) { + this.value = this.preValue * scale; + } + recover() { + this.value = this.preValue; + } + dispose() { + this.target = null; + } + static create(target, key) { + var rst; + rst = new ValueChanger(); + rst.target = target; + rst.key = key; + return rst; + } + } + + class ArrowLine extends Laya.Sprite { + constructor(sign = "X") { + super(); + this.lineLen = 160; + this.arrowLen = 10; + this.lenControl = new Rect(); + this.rotationControl = new Rect(); + this.sign = "Y"; + this.lenChanger = ValueChanger.create(this, "lineLen"); + this.lenControlXChanger = ValueChanger.create(this.lenControl, "x"); + this._isMoving = false; + this.sign = sign; + this.addChild(this.lenControl); + this.addChild(this.rotationControl); + this.lenControl.on(Laya.Event.MOUSE_DOWN, this, this.controlMouseDown); + this.drawMe(); + } + drawMe() { + var g; + g = this.graphics; + g.clear(); + g.drawLine(0, 0, this.lineLen, 0, "#ffff00"); + g.drawLine(this.lineLen, 0, this.lineLen - this.arrowLen, -this.arrowLen, "#ff0000"); + g.drawLine(this.lineLen, 0, this.lineLen - this.arrowLen, this.arrowLen, "#ff0000"); + g.fillText(this.sign, 50, -5, "", "#ff0000", "left"); + if (this._isMoving && this._targetChanger) { + g.fillText(this._targetChanger.key + ":" + this._targetChanger.value.toFixed(2), this.lineLen - 15, -25, "", "#ffff00", "center"); + } + this.lenControl.posTo(this.lineLen - 15, 0); + this.rotationControl.posTo(this.lineLen + 10, 0); + this.size(this.arrowLen, this.lineLen); + } + set targetChanger(changer) { + if (this._targetChanger) { + this._targetChanger.dispose(); + } + this._targetChanger = changer; + } + get targetChanger() { + return this._targetChanger; + } + clearMoveEvents() { + Laya.Laya.stage.off(Laya.Event.MOUSE_MOVE, this, this.stageMouseMove); + Laya.Laya.stage.off(Laya.Event.MOUSE_UP, this, this.stageMouseUp); + } + controlMouseDown(e) { + this.clearMoveEvents(); + this.lenControlXChanger.record(); + this.lenChanger.record(); + if (this.targetChanger) { + this.targetChanger.record(); + } + this._isMoving = true; + Laya.Laya.stage.on(Laya.Event.MOUSE_MOVE, this, this.stageMouseMove); + Laya.Laya.stage.on(Laya.Event.MOUSE_UP, this, this.stageMouseUp); + } + stageMouseMove(e) { + this.lenControlXChanger.value = this.mouseX; + this.lenChanger.showValueByScale(this.lenControlXChanger.scaleValue); + if (this.targetChanger) { + this.targetChanger.showValueByScale(this.lenControlXChanger.scaleValue); + } + this.drawMe(); + } + stageMouseUp(e) { + this._isMoving = false; + this.noticeChange(); + this.clearMoveEvents(); + this.lenControlXChanger.recover(); + this.lenChanger.recover(); + this.drawMe(); + } + noticeChange() { + var dLen; + dLen = this.lenChanger.dValue; + console.log("lenChange:", dLen); + } + } + + class Axis extends Laya.Sprite { + constructor() { + super(); + this.xAxis = new ArrowLine("X"); + this.yAxis = new ArrowLine("Y"); + this.controlBox = new Rect(); + this._lenType = [["width", "height"], + ["scaleX", "scaleY"]]; + this._type = 1; + this._point = new Laya.Point(); + this.oPoint = new Laya.Point(); + this.myRotationChanger = ValueChanger.create(this, "rotation"); + this.targetRotationChanger = ValueChanger.create(null, "rotation"); + this.stageMouseRotationChanger = new ValueChanger(); + this.mouseEnabled = true; + this.size(1, 1); + this.initMe(); + this.xAxis.rotationControl.on(Laya.Event.MOUSE_DOWN, this, this.controlMouseDown); + this.yAxis.rotationControl.on(Laya.Event.MOUSE_DOWN, this, this.controlMouseDown); + this.controlBox.on(Laya.Event.MOUSE_DOWN, this, this.controlBoxMouseDown); + this.on(Laya.Event.DRAG_MOVE, this, this.dragging); + } + set target(tar) { + this._target = tar; + this.updateChanges(); + } + updateChanges() { + if (this._target) { + var params; + params = this._lenType[this._type]; + this.xAxis.targetChanger = ValueChanger.create(this._target, params[0]); + this.yAxis.targetChanger = ValueChanger.create(this._target, params[1]); + } + } + set type(lenType) { + this._type = lenType; + this.updateChanges(); + } + get type() { + return this._type; + } + switchType() { + this._type++; + this._type = this._type % this._lenType.length; + this.type = this._type; + } + controlBoxMouseDown(e) { + this.startDrag(); + } + dragging() { + if (this._target) { + this._point.setTo(this.x, this.y); + DisControlTool.transPoint(this.parent, this._target.parent, this._point); + this._target.pos(this._point.x, this._point.y); + } + } + get target() { + return this._target; + } + initMe() { + this.addChild(this.xAxis); + this.addChild(this.yAxis); + this.yAxis.rotation = 90; + this.addChild(this.controlBox); + this.controlBox.posTo(0, 0); + } + clearMoveEvents() { + Laya.Laya.stage.off(Laya.Event.MOUSE_MOVE, this, this.stageMouseMove); + Laya.Laya.stage.off(Laya.Event.MOUSE_UP, this, this.stageMouseUp); + } + controlMouseDown(e) { + this.targetRotationChanger.target = this.target; + this.clearMoveEvents(); + this.oPoint.setTo(0, 0); + this.myRotationChanger.record(); + this.oPoint = this.localToGlobal(this.oPoint); + this.stageMouseRotationChanger.value = this.getStageMouseRatation(); + this.stageMouseRotationChanger.record(); + this.targetRotationChanger.record(); + Laya.Laya.stage.on(Laya.Event.MOUSE_MOVE, this, this.stageMouseMove); + Laya.Laya.stage.on(Laya.Event.MOUSE_UP, this, this.stageMouseUp); + } + getStageMouseRatation() { + return Laya.MathUtil.getRotation(this.oPoint.x, this.oPoint.y, Laya.Laya.stage.mouseX, Laya.Laya.stage.mouseY); + } + stageMouseMove(e) { + this.stageMouseRotationChanger.value = this.getStageMouseRatation(); + var dRotation; + dRotation = -this.stageMouseRotationChanger.dValue; + if (this.target) { + this.targetRotationChanger.showValueByAdd(dRotation); + } + else { + this.myRotationChanger.showValueByAdd(dRotation); + } + } + stageMouseUp(e) { + this.noticeChange(); + this.clearMoveEvents(); + } + noticeChange() { + console.log("rotate:", -this.stageMouseRotationChanger.dValue); + } + } + + class DisController { + constructor() { + DisController.init(); + this.arrowAxis = new Axis(); + this.arrowAxis.mouseEnabled = true; + } + static init() { + if (DisController._container) { + DisControlTool.setTop(DisController._container); + return; + } + DisController._container = new Laya.Sprite(); + DisController._container.mouseEnabled = true; + Laya.Laya.stage.addChild(DisController._container); + } + set target(target) { + this._target = target; + if (target) { + DisController._container.addChild(this.arrowAxis); + Laya.Laya.timer.loop(100, this, this.updateMe); + } + else { + this.arrowAxis.removeSelf(); + Laya.Laya.timer.clear(this, this.updateMe); + } + this.arrowAxis.target = target; + this.updateMe(); + } + get target() { + return this._target; + } + set type(lenType) { + this.arrowAxis.type = lenType; + } + get type() { + return this.arrowAxis.type; + } + switchType() { + this.arrowAxis.switchType(); + } + updateMe() { + if (!this._target) + return; + this.recInfo = RecInfo.getGlobalRecInfo(this._target, 0, 0, 1, 0, 0, 1); + console.log("rotation:", this.recInfo.rotation); + console.log("pos:", this.recInfo.x, this.recInfo.y); + console.log("scale:", this.recInfo.width, this.recInfo.height); + this.arrowAxis.x = this.recInfo.x; + this.arrowAxis.y = this.recInfo.y; + this.arrowAxis.rotation = this.recInfo.rotation; + this.arrowAxis.yAxis.rotation = this.recInfo.rotationV - this.recInfo.rotation; + } + static get I() { + if (!DisController._instance) { + DisController._instance = new DisController(); + } + return DisController._instance; + } + static set I(value) { + DisController._instance = value; + } + } + + class DTrace { + constructor() { + } + static getArgArr(arg) { + var rst; + rst = []; + var i, len = arg.length; + for (i = 0; i < len; i++) { + rst.push(arg[i]); + } + return rst; + } + static dTrace(...arg) { + arg = DTrace.getArgArr(arg); + arg.push(TraceTool.getCallLoc(2)); + console.log.apply(console, arg); + var str; + str = arg.join(" "); + } + static timeStart(sign) { + console.time(sign); + } + static timeEnd(sign) { + console.timeEnd(sign); + } + static traceTable(data) { + console.table(data); + } + } + + class RunProfile { + constructor() { + } + static run(funName, callLen = 3) { + var tCount; + if (!RunProfile.infoDic.hasOwnProperty(funName)) { + RunProfile.infoDic[funName] = new CountTool(); + } + tCount = RunProfile.infoDic[funName]; + var msg; + msg = TraceTool.getCallLoc(callLen) + "\n" + TraceTool.getCallStack(1, callLen - 3); + tCount.add(msg); + if (RunProfile._runShowDic[funName]) { + console.log("Create:" + funName); + console.log(msg); + } + } + static showClassCreate(funName) { + RunProfile._runShowDic[funName] = true; + } + static hideClassCreate(funName) { + RunProfile._runShowDic[funName] = false; + } + static getRunInfo(funName) { + var rst; + rst = RunProfile.infoDic[funName]; + return RunProfile.infoDic[funName]; + } + static runTest(fun, count, sign = "runTest") { + DTrace.timeStart(sign); + var i; + for (i = 0; i < count; i++) { + fun(); + } + DTrace.timeEnd(sign); + } + static runTest2(fun, count, sign = "runTest") { + var preTime; + preTime = Laya.Browser.now(); + var i; + for (i = 0; i < count; i++) { + fun(); + } + return Laya.Browser.now() - preTime; + } + } + RunProfile.infoDic = {}; + RunProfile._runShowDic = {}; + + class WalkTools { + constructor() { + } + static walkTarget(target, fun, _this = null) { + fun.apply(_this, [target]); + var i; + var len; + var tChild; + len = target.numChildren; + for (i = 0; i < len; i++) { + tChild = target.getChildAt(i); + WalkTools.walkTarget(tChild, fun, tChild); + } + } + static walkTargetEX(target, fun, _this = null, filterFun = null) { + if (filterFun != null && !filterFun(target)) + return; + fun.apply(_this, [target]); + var i; + var len; + var tChild; + var childs; + childs = target._children; + len = childs.length; + for (i = 0; i < len; i++) { + tChild = childs[i]; + WalkTools.walkTarget(tChild, fun, tChild); + } + } + static walkChildren(target, fun, _this = null) { + if (!target || target.numChildren < 1) + return; + WalkTools.walkArr(DisControlTool.getAllChild(target), fun, _this); + } + static walkArr(arr, fun, _this = null) { + if (!arr) + return; + var i; + var len; + len = arr.length; + for (i = 0; i < len; i++) { + fun.apply(_this, [arr[i], i]); + } + } + } + + class DebugInfoLayer extends Laya.Sprite { + constructor() { + super(); + this.nodeRecInfoLayer = new Laya.Sprite(); + this.lineLayer = new Laya.Sprite(); + this.txtLayer = new Laya.Sprite(); + this.popLayer = new Laya.Sprite(); + this.graphicLayer = new Laya.Sprite(); + this.cacheViewLayer = new Laya.Sprite(); + this.nodeRecInfoLayer.name = "nodeRecInfoLayer"; + this.lineLayer.name = "lineLayer"; + this.txtLayer.name = "txtLayer"; + this.popLayer.name = "popLayer"; + this.graphicLayer.name = "graphicLayer"; + this.cacheViewLayer.name = "cacheViewLayer"; + this.addChild(this.lineLayer); + this.addChild(this.cacheViewLayer); + this.addChild(this.nodeRecInfoLayer); + this.addChild(this.txtLayer); + this.addChild(this.popLayer); + this.addChild(this.graphicLayer); + DebugInfoLayer.I = this; + this.zOrder = 999; + Laya.Laya.stage.on(Laya.Event.DOUBLE_CLICK, this, this.setTop); + } + static init() { + if (!DebugInfoLayer.I) { + new DebugInfoLayer(); + Laya.Laya.stage.addChild(DebugInfoLayer.I); + } + } + setTop() { + DisControlTool.setTop(this); + } + isDebugItem(sprite) { + return DisControlTool.isInTree(this, sprite); + } + } + + class IDTools { + constructor() { + this.tID = 1; + } + getID() { + return this.tID++; + } + static getAID() { + return IDTools._ID.getID(); + } + static idObjE(obj, sign = "default") { + if (obj[IDTools.idSign]) + return obj; + if (!sign) { + sign = "default"; + } + if (!IDTools._idDic[sign]) { + IDTools._idDic[sign] = new IDTools(); + } + obj[IDTools.idSign] = IDTools._idDic[sign].getAID(); + return obj; + } + static setObjID(obj, id) { + obj[IDTools.idSign] = id; + return obj; + } + static idObj(obj) { + if (obj[IDTools.idSign]) + return obj; + obj[IDTools.idSign] = IDTools.getAID(); + return obj; + } + static getObjID(obj) { + if (!obj) + return -1; + return obj[IDTools.idSign]; + } + } + IDTools._ID = new IDTools(); + IDTools._idDic = { "default": new IDTools() }; + IDTools.idSign = "_M_id_"; + + class NodeInfosItem extends Laya.Sprite { + constructor() { + super(); + this._infoTxt = new Laya.Text(); + this._infoTxt.color = "#ff0000"; + this._infoTxt.bgColor = "#00ff00"; + this._infoTxt.fontSize = 12; + } + static init() { + if (!NodeInfosItem.NodeInfoContainer) { + DebugInfoLayer.init(); + NodeInfosItem.NodeInfoContainer = DebugInfoLayer.I; + Laya.Laya.stage.addChild(NodeInfosItem.NodeInfoContainer); + } + } + static getNodeInfoByNode(node) { + IDTools.idObj(node); + var key; + key = IDTools.getObjID(node); + if (!NodeInfosItem._nodeInfoDic[key]) { + NodeInfosItem._nodeInfoDic[key] = new NodeInfosItem(); + } + return NodeInfosItem._nodeInfoDic[key]; + } + static hideAllInfos() { + var key; + var tInfo; + for (key in NodeInfosItem._nodeInfoDic) { + tInfo = NodeInfosItem._nodeInfoDic[key]; + tInfo.removeSelf(); + } + NodeInfosItem.clearRelations(); + } + removeSelf() { + this._infoTxt.removeSelf(); + return super.removeSelf(); + } + showToUI() { + NodeInfosItem.NodeInfoContainer.nodeRecInfoLayer.addChild(this); + this._infoTxt.removeSelf(); + NodeInfosItem.NodeInfoContainer.txtLayer.addChild(this._infoTxt); + this.findOkPos(); + } + randomAPos(r) { + this._infoTxt.x = this.x + Laya.Laya.stage.width * Math.random(); + this._infoTxt.y = this.y + r * Math.random(); + } + findOkPos() { + var len; + len = 20; + this.randomAPos(len); + return; + } + isPosOk() { + var tParent; + tParent = NodeInfosItem.NodeInfoContainer.nodeRecInfoLayer; + var i, len; + var cList; + cList = tParent._children; + len = cList.length; + var tChild; + var mRec; + mRec = this._infoTxt.getBounds(); + if (mRec.x < 0) + return false; + if (mRec.y < 0) + return false; + if (mRec.right > Laya.Laya.stage.width) + return false; + for (i = 0; i < len; i++) { + tChild = cList[i]; + if (tChild == this._infoTxt) + continue; + if (mRec.intersects(tChild.getBounds())) + return false; + } + return true; + } + static showNodeInfo(node) { + var nodeInfo; + nodeInfo = NodeInfosItem.getNodeInfoByNode(node); + nodeInfo.showInfo(node); + nodeInfo.showToUI(); + } + static showDisInfos(node) { + var _node; + _node = node; + if (!node) + return; + while (node) { + NodeInfosItem.showNodeInfo(node); + node = node.parent; + } + DisControlTool.setTop(NodeInfosItem.NodeInfoContainer); + NodeInfosItem.apdtTxtInfoPoss(_node); + NodeInfosItem.updateRelations(); + } + static apdtTxtInfoPoss(node) { + var disList; + disList = []; + while (node) { + disList.push(node); + node = node.parent; + } + var i, len; + var tInfo; + var tTxt; + len = disList.length; + var xPos; + xPos = Laya.Laya.stage.width - 150; + var heightLen; + heightLen = 100; + node = disList[0]; + if (node) { + tInfo = NodeInfosItem.getNodeInfoByNode(node); + if (tInfo) { + tTxt = tInfo._infoTxt; + xPos = Laya.Laya.stage.width - tTxt.width - 10; + heightLen = tTxt.height + 10; + } + } + disList = disList.reverse(); + for (i = 0; i < len; i++) { + node = disList[i]; + tInfo = NodeInfosItem.getNodeInfoByNode(node); + if (tInfo) { + tTxt = tInfo._infoTxt; + tTxt.pos(xPos, heightLen * i); + } + } + } + static clearRelations() { + var g; + g = NodeInfosItem.NodeInfoContainer.lineLayer.graphics; + g.clear(); + } + static updateRelations() { + var g; + g = NodeInfosItem.NodeInfoContainer.lineLayer.graphics; + g.clear(); + var key; + var tInfo; + for (key in NodeInfosItem._nodeInfoDic) { + tInfo = NodeInfosItem._nodeInfoDic[key]; + if (tInfo.parent) { + g.drawLine(tInfo.x, tInfo.y, tInfo._infoTxt.x, tInfo._infoTxt.y, "#0000ff"); + } + } + } + static getNodeValue(node, key) { + var rst; + NodeInfosItem._nodePoint.setTo(0, 0); + switch (key) { + case "x": + rst = node["x"] + " (g:" + node.localToGlobal(NodeInfosItem._nodePoint).x + ")"; + break; + case "y": + rst = node["y"] + " (g:" + node.localToGlobal(NodeInfosItem._nodePoint).y + ")"; + break; + default: + rst = node[key]; + } + return rst; + } + showInfo(node) { + this._tar = node; + if (!node) + return; + NodeInfosItem._txts.length = 0; + var i, len; + var tKey; + len = NodeInfosItem.showValues.length; + if (node.name) { + NodeInfosItem._txts.push(ClassTool.getClassName(node) + "(" + node.name + ")"); + } + else { + NodeInfosItem._txts.push(ClassTool.getClassName(node)); + } + for (i = 0; i < len; i++) { + tKey = NodeInfosItem.showValues[i]; + NodeInfosItem._txts.push(tKey + ":" + NodeInfosItem.getNodeValue(node, tKey)); + } + this._infoTxt.text = NodeInfosItem._txts.join("\n"); + this.graphics.clear(); + var pointList; + pointList = node._getBoundPointsM(true); + if (!pointList || pointList.length < 1) + return; + pointList = Laya.GrahamScan.pListToPointList(pointList, true); + WalkTools.walkArr(pointList, node.localToGlobal, node); + pointList = Laya.GrahamScan.pointListToPlist(pointList); + NodeInfosItem._disBoundRec = Laya.Rectangle._getWrapRec(pointList, NodeInfosItem._disBoundRec); + this.graphics.drawRect(0, 0, NodeInfosItem._disBoundRec.width, NodeInfosItem._disBoundRec.height, null, "#00ffff"); + this.pos(NodeInfosItem._disBoundRec.x, NodeInfosItem._disBoundRec.y); + } + fresh() { + this.showInfo(this._tar); + } + clearMe() { + this._tar = null; + } + recover() { + Laya.Pool.recover("NodeInfosItem", this); + } + } + NodeInfosItem.showValues = ["x", "y", "scaleX", "scaleY", "width", "height", "visible", "mouseEnabled"]; + NodeInfosItem._nodeInfoDic = {}; + NodeInfosItem._disBoundRec = new Laya.Rectangle(); + NodeInfosItem._txts = []; + NodeInfosItem._nodePoint = new Laya.Point(); + + class NodeInfoPanel extends Laya.Sprite { + constructor() { + super(); + this._stateDic = {}; + this.isWorkState = false; + } + static init() { + if (!NodeInfoPanel.I) { + NodeInfoPanel.I = new NodeInfoPanel(); + NodeInfosItem.init(); + } + } + showDisInfo(node) { + this.recoverNodes(); + NodeInfosItem.showDisInfos(node); + this.showOnly(node); + this.isWorkState = true; + } + showOnly(node) { + if (!node) + return; + this.hideBrothers(node); + this.showOnly(node.parent); + } + recoverNodes() { + NodeInfosItem.hideAllInfos(); + var key; + var data; + var tTar; + for (key in this._stateDic) { + data = this._stateDic[key]; + tTar = data["target"]; + if (tTar) { + try { + tTar.visible = data.visible; + } + catch (e) { + } + } + } + this.isWorkState = false; + } + hideOtherChain(node) { + if (!node) + return; + while (node) { + this.hideBrothers(node); + node = node.parent; + } + } + hideChilds(node) { + if (!node) + return; + var i, len; + var cList; + cList = node._children; + len = cList.length; + var tChild; + for (i = 0; i < len; i++) { + tChild = cList[i]; + if (tChild == NodeInfosItem.NodeInfoContainer) + continue; + this.saveNodeInfo(tChild); + tChild.visible = false; + } + } + hideBrothers(node) { + if (!node) + return; + var p; + p = node.parent; + if (!p) + return; + var i, len; + var cList; + cList = p._children; + len = cList.length; + var tChild; + for (i = 0; i < len; i++) { + tChild = cList[i]; + if (tChild == NodeInfosItem.NodeInfoContainer) + continue; + if (tChild != node) { + this.saveNodeInfo(tChild); + tChild.visible = false; + } + } + } + saveNodeInfo(node) { + IDTools.idObj(node); + if (this._stateDic.hasOwnProperty(IDTools.getObjID(node))) + return; + var data; + data = {}; + data.target = node; + data.visible = node.visible; + this._stateDic[IDTools.getObjID(node)] = data; + } + recoverNodeInfo(node) { + IDTools.idObj(node); + if (this._stateDic.hasOwnProperty(IDTools.getObjID(node))) { + var data; + data = this._stateDic[IDTools.getObjID(node)]; + node["visible"] = data.visible; + } + } + } + + class NodeConsts { + constructor() { + } + } + NodeConsts.defaultFitlerStr = "x,y,width,height,scaleX,scaleY,alpha,renderCost"; + NodeConsts.RenderCostMaxTime = 3000; + + class RenderAnalyser { + constructor() { + this.timeDic = {}; + this.resultDic = {}; + this.countDic = {}; + this.resultCountDic = {}; + this.nodeDic = {}; + this.isWorking = false; + this.working = true; + } + static get I() { + if (!RenderAnalyser._instance) { + RenderAnalyser._instance = new RenderAnalyser(); + } + return RenderAnalyser._instance; + } + static set I(value) { + RenderAnalyser._instance = value; + } + render(sprite, time) { + this.addTime(sprite, time); + } + addTime(sprite, time) { + IDTools.idObj(sprite); + var key; + key = IDTools.getObjID(sprite); + if (!this.timeDic.hasOwnProperty(key)) { + this.timeDic[key] = 0; + } + this.timeDic[key] = this.timeDic[key] + time; + if (!this.countDic.hasOwnProperty(key)) { + this.countDic[key] = 0; + } + this.countDic[key] = this.countDic[key] + 1; + this.nodeDic[key] = sprite; + } + getTime(sprite) { + IDTools.idObj(sprite); + var key; + key = IDTools.getObjID(sprite); + if (!this.resultDic[key]) + return 0; + return this.resultDic[key]; + } + getCount(sprite) { + IDTools.idObj(sprite); + var key; + key = IDTools.getObjID(sprite); + return this.resultCountDic[key]; + } + reset() { + var key; + for (key in this.timeDic) { + this.timeDic[key] = 0; + this.countDic[key] = 0; + } + ObjectTools.clearObj(this.nodeDic); + } + updates() { + ObjectTools.clearObj(this.resultDic); + ObjectTools.insertValue(this.resultDic, this.timeDic); + ObjectTools.clearObj(this.resultCountDic); + ObjectTools.insertValue(this.resultCountDic, this.countDic); + this.reset(); + } + set working(v) { + this.isWorking = v; + if (v) { + Laya.Laya.timer.loop(NodeConsts.RenderCostMaxTime, this, this.updates); + } + else { + Laya.Laya.timer.clear(this, this.updates); + } + } + } + + class NodeUtils { + constructor() { + } + static getFilterdTree(sprite, keys) { + if (!keys) + keys = NodeUtils.defaultKeys; + var me; + me = {}; + var key; + var i, len; + len = keys.length; + for (i = 0; i < len; i++) { + key = keys[i]; + me[key] = sprite[key]; + } + var cList; + var tChild; + cList = sprite._children; + len = cList.length; + var mClist; + mClist = []; + for (i = 0; i < len; i++) { + tChild = cList[i]; + mClist.push(NodeUtils.getFilterdTree(tChild, keys)); + } + me.childs = mClist; + return me; + } + static getNodeValue(node, key) { + var rst; + if (node instanceof Laya.Sprite) { + var tNode; + tNode = node; + switch (key) { + case "gRec": + rst = NodeUtils.getGRec(tNode).toString(); + break; + case "gAlpha": + rst = NodeUtils.getGAlpha(tNode) + ""; + break; + case "cmdCount": + rst = NodeUtils.getNodeCmdCount(tNode) + ""; + break; + case "cmdAll": + rst = NodeUtils.getNodeCmdTotalCount(tNode) + ""; + break; + case "nodeAll": + rst = "" + NodeUtils.getNodeCount(tNode); + break; + case "nodeVisible": + rst = "" + NodeUtils.getNodeCount(tNode, true); + break; + case "nodeRender": + rst = "" + NodeUtils.getRenderNodeCount(tNode); + break; + case "nodeReCache": + rst = "" + NodeUtils.getReFreshRenderNodeCount(tNode); + break; + case "renderCost": + rst = "" + RenderAnalyser.I.getTime(tNode); + break; + case "renderCount": + rst = "" + RenderAnalyser.I.getCount(tNode); + break; + default: + rst = node[key] + ""; + } + } + else { + rst = node[key] + ""; + } + return rst; + } + static getPropertyDesO(tValue, keys) { + if (!keys) + keys = NodeUtils.defaultKeys; + var rst = {}; + if (typeof (tValue) == 'object') { + rst.label = "" + ClassTool.getNodeClassAndName(tValue); + } + else { + rst.label = "" + tValue; + } + rst.type = ""; + rst.path = tValue; + rst.childs = []; + rst.isDirectory = false; + var key; + var i, len; + var tChild; + if (tValue instanceof Laya.Node) { + rst.des = ClassTool.getNodeClassAndName(tValue); + rst.isDirectory = true; + len = keys.length; + for (i = 0; i < len; i++) { + key = keys[i]; + tChild = NodeUtils.getPropertyDesO(tValue[key], keys); + if (tValue.hasOwnProperty(key)) { + tChild.label = "" + key + ":" + tChild.des; + } + else { + tChild.label = "" + key + ":" + NodeUtils.getNodeValue(tValue, key); + } + rst.childs.push(tChild); + } + key = "_children"; + tChild = NodeUtils.getPropertyDesO(tValue[key], keys); + tChild.label = "" + key + ":" + tChild.des; + tChild.isChilds = true; + rst.childs.push(tChild); + } + else if (tValue instanceof Array) { + rst.des = "Array[" + tValue.length + "]"; + rst.isDirectory = true; + var tList; + tList = tValue; + len = tList.length; + for (i = 0; i < len; i++) { + tChild = NodeUtils.getPropertyDesO(tList[i], keys); + tChild.label = "" + i + ":" + tChild.des; + rst.childs.push(tChild); + } + } + else if (typeof (tValue) == 'object') { + rst.des = ClassTool.getNodeClassAndName(tValue); + rst.isDirectory = true; + for (key in tValue) { + tChild = NodeUtils.getPropertyDesO(tValue[key], keys); + tChild.label = "" + key + ":" + tChild.des; + rst.childs.push(tChild); + } + } + else { + rst.des = "" + tValue; + } + rst.hasChild = rst.childs.length > 0; + return rst; + } + static adptShowKeys(keys) { + var i, len; + len = keys.length; + for (i = len - 1; i >= 0; i--) { + keys[i] = StringTool.trimSide(keys[i]); + if (keys[i].length < 1) { + keys.splice(i, 1); + } + } + return keys; + } + static getNodeTreeData(sprite, keys) { + NodeUtils.adptShowKeys(keys); + var treeO; + treeO = NodeUtils.getPropertyDesO(sprite, keys); + var treeArr; + treeArr = []; + NodeUtils.getTreeArr(treeO, treeArr); + return treeArr; + } + static getTreeArr(treeO, arr, add = true) { + if (add) + arr.push(treeO); + var tArr = treeO.childs; + var i, len = tArr.length; + for (i = 0; i < len; i++) { + if (!add) { + tArr[i].nodeParent = null; + } + else { + tArr[i].nodeParent = treeO; + } + if (tArr[i].isDirectory) { + NodeUtils.getTreeArr(tArr[i], arr); + } + else { + arr.push(tArr[i]); + } + } + } + static traceStage() { + console.log(NodeUtils.getFilterdTree(Laya.Laya.stage, null)); + console.log("treeArr:", NodeUtils.getNodeTreeData(Laya.Laya.stage, null)); + } + static getNodeCount(node, visibleRequire = false) { + if (visibleRequire) { + if (!node.visible) + return 0; + } + var rst; + rst = 1; + var i, len; + var cList; + cList = node._children; + len = cList.length; + for (i = 0; i < len; i++) { + rst += NodeUtils.getNodeCount(cList[i], visibleRequire); + } + return rst; + } + static getGVisible(node) { + while (node) { + if (!node.visible) + return false; + node = node.parent; + } + return true; + } + static getGAlpha(node) { + var rst; + rst = 1; + while (node) { + rst *= node.alpha; + node = node.parent; + } + return rst; + } + static getGPos(node) { + var point; + point = new Laya.Point(); + node.localToGlobal(point); + return point; + } + static getGRec(node) { + var pointList; + pointList = node._getBoundPointsM(true); + if (!pointList || pointList.length < 1) + return Laya.Rectangle.TEMP.setTo(0, 0, 0, 0); + pointList = Laya.GrahamScan.pListToPointList(pointList, true); + WalkTools.walkArr(pointList, node.localToGlobal, node); + pointList = Laya.GrahamScan.pointListToPlist(pointList); + var _disBoundRec; + _disBoundRec = Laya.Rectangle._getWrapRec(pointList, _disBoundRec); + return _disBoundRec; + } + static getGGraphicRec(node) { + var pointList; + pointList = node.getGraphicBounds()._getBoundPoints(); + if (!pointList || pointList.length < 1) + return Laya.Rectangle.TEMP.setTo(0, 0, 0, 0); + pointList = Laya.GrahamScan.pListToPointList(pointList, true); + WalkTools.walkArr(pointList, node.localToGlobal, node); + pointList = Laya.GrahamScan.pointListToPlist(pointList); + var _disBoundRec; + _disBoundRec = Laya.Rectangle._getWrapRec(pointList, _disBoundRec); + return _disBoundRec; + } + static getNodeCmdCount(node) { + var rst; + if (node.graphics) { + if (node.graphics.cmds) { + rst = node.graphics.cmds.length; + } + else { + if (node.graphics._one) { + rst = 1; + } + else { + rst = 0; + } + } + } + else { + rst = 0; + } + return rst; + } + static getNodeCmdTotalCount(node) { + var rst; + var i, len; + var cList; + cList = node._children; + len = cList.length; + rst = NodeUtils.getNodeCmdCount(node); + for (i = 0; i < len; i++) { + rst += NodeUtils.getNodeCmdTotalCount(cList[i]); + } + return rst; + } + static getRenderNodeCount(node) { + if (node.cacheAs != "none") + return 1; + var rst; + var i, len; + var cList; + cList = node._children; + len = cList.length; + rst = 1; + for (i = 0; i < len; i++) { + rst += NodeUtils.getRenderNodeCount(cList[i]); + } + return rst; + } + static getReFreshRenderNodeCount(node) { + var rst; + var i, len; + var cList; + cList = node._children; + len = cList.length; + rst = 1; + for (i = 0; i < len; i++) { + rst += NodeUtils.getRenderNodeCount(cList[i]); + } + return rst; + } + static showCachedSpriteRecs() { + NodeUtils.g = DebugInfoLayer.I.graphicLayer.graphics; + NodeUtils.g.clear(); + WalkTools.walkTarget(Laya.Laya.stage, NodeUtils.drawCachedBounds, null); + } + static drawCachedBounds(sprite) { + if (sprite.cacheAs == "none") + return; + if (DebugInfoLayer.I.isDebugItem(sprite)) + return; + var rec; + rec = NodeUtils.getGRec(sprite); + NodeUtils.g.drawRect(rec.x, rec.y, rec.width, rec.height, null, "#0000ff", 2); + } + } + NodeUtils.defaultKeys = ["x", "y", "width", "height"]; + + class DifferTool { + constructor(sign = "", autoTrace = true) { + this.autoTrace = true; + this.sign = ""; + this.sign = sign; + this.autoTrace = autoTrace; + } + update(data, msg = null) { + if (msg) { + console.log(msg); + } + var tObj = ObjectTools.copyObj(data); + if (!this.obj) + this.obj = {}; + var rst; + rst = ObjectTools.differ(this.obj, tObj); + this.obj = tObj; + if (this.autoTrace) { + console.log(this.sign + " differ:"); + ObjectTools.traceDifferObj(rst); + } + return rst; + } + static differ(sign, data, msg = null) { + if (!DifferTool._differO[sign]) + DifferTool._differO[sign] = new DifferTool(sign, true); + var tDiffer; + tDiffer = DifferTool._differO[sign]; + return tDiffer.update(data, msg); + } + } + DifferTool._differO = {}; + + class FunHook { + constructor() { + } + static hook(obj, funName, preFun = null, aftFun = null) { + FunHook.hookFuns(obj, funName, [preFun, obj[funName], aftFun], 1); + } + static hookAllFun(obj) { + var key; + var arr; + arr = ClassTool.getOwnPropertyNames(obj); + for (key in arr) { + key = arr[key]; + if (FunHook.special[key]) + continue; + console.log("try hook:", key); + if (obj[key] instanceof Function) { + console.log("hook:", key); + FunHook.hookFuns(obj, key, [FunHook.getTraceMsg("call:" + key), obj[key]], 1); + } + } + if (obj["__proto__"]) { + FunHook.hookAllFun(obj["__proto__"]); + } + else { + console.log("end:", obj); + } + } + static getTraceMsg(msg) { + var rst; + rst = function () { + console.log(msg); + }; + return rst; + } + static hookFuns(obj, funName, funList, rstI = -1) { + var _preFun = obj[funName]; + var newFun; + newFun = function (...args) { + var rst; + var i; + var len; + len = funList.length; + for (i = 0; i < len; i++) { + if (!funList[i]) + continue; + if (i == rstI) { + rst = funList[i].apply(this, args); + } + else { + funList[i].apply(this, args); + } + } + return rst; + }; + newFun["pre"] = _preFun; + obj[funName] = newFun; + } + static removeHook(obj, funName) { + if (obj[funName].pre != null) { + obj[funName] = obj[funName].pre; + } + } + static debugHere() { + debugger; + } + static traceLoc(level = 0, msg = "") { + console.log(msg, "fun loc:", TraceTool.getCallLoc(3 + level)); + } + static getLocFun(level = 0, msg = "") { + level += 1; + var rst; + rst = function () { + FunHook.traceLoc(level, msg); + }; + return rst; + } + } + FunHook.special = { + "length": true, + "name": true, + "arguments": true, + "caller": true, + "prototype": true, + "is": true, + "isExtensible": true, + "isFrozen": true, + "isSealed": true, + "preventExtensions": true, + "seal": true, + "apply": true, + "call": true, + "bind": true, + "freeze": true, + "unobserve": true + }; + + class VarHook { + constructor() { + } + static hookVar(obj, name, setHook = null, getHook = null) { + if (!setHook) + setHook = []; + if (!getHook) + getHook = []; + var preO = obj; + var preValue = obj[name]; + var des; + des = ClassTool.getOwnPropertyDescriptor(obj, name); + var ndes = {}; + var mSet = function (value) { + console.log("var hook set " + name + ":", value); + preValue = value; + }; + var mGet = function () { + console.log("var hook get" + name + ":", preValue); + return preValue; + }; + if (des) { + ndes.set = mSet; + ndes.get = mGet; + ndes.enumerable = des.enumerable; + setHook.push(ndes.set); + getHook.push(ndes.get); + FunHook.hookFuns(ndes, "set", setHook); + FunHook.hookFuns(ndes, "get", getHook, getHook.length - 1); + ClassTool.defineProperty(obj, name, ndes); + return; + } + while (!des && obj["__proto__"]) { + obj = obj["__proto__"]; + des = ClassTool.getOwnPropertyDescriptor(obj, name); + } + if (des) { + ndes.set = des.set ? des.set : mSet; + ndes.get = des.get ? des.get : mGet; + ndes.enumerable = des.enumerable; + setHook.push(ndes.set); + getHook.push(ndes.get); + FunHook.hookFuns(ndes, "set", setHook); + FunHook.hookFuns(ndes, "get", getHook, getHook.length - 1); + ClassTool.defineProperty(preO, name, ndes); + } + if (!des) { + console.log("get des fail add directly"); + ndes.set = mSet; + ndes.get = mGet; + setHook.push(ndes.set); + getHook.push(ndes.get); + FunHook.hookFuns(ndes, "set", setHook); + FunHook.hookFuns(ndes, "get", getHook, getHook.length - 1); + ClassTool.defineProperty(obj, name, ndes); + } + } + static getLocFun(msg = "", level = 0) { + level += 1; + var rst; + rst = function () { + FunHook.traceLoc(level, msg); + }; + return rst; + } + } + + class Watcher { + constructor() { + } + static watch(obj, name, funs) { + VarHook.hookVar(obj, name, funs); + } + static traceChange(obj, name, sign = "var changed:") { + VarHook.hookVar(obj, name, [Watcher.getTraceValueFun(name), VarHook.getLocFun(sign)]); + } + static debugChange(obj, name) { + VarHook.hookVar(obj, name, [VarHook.getLocFun("debug loc"), FunHook.debugHere]); + } + static differChange(obj, name, sign, msg = "") { + VarHook.hookVar(obj, name, [Watcher.getDifferFun(obj, name, sign, msg)]); + } + static getDifferFun(obj, name, sign, msg = "") { + var rst; + rst = function () { + DifferTool.differ(sign, obj[name], msg); + }; + return rst; + } + static traceValue(value) { + console.log("value:", value); + } + static getTraceValueFun(name) { + var rst; + rst = function (value) { + console.log("set " + name + " :", value); + }; + return rst; + } + } + + class DebugTool { + constructor() { + } + static getMenuShowEvent() { + if (Laya.Browser.onMobile) { + return Laya.Event.DOUBLE_CLICK; + } + else { + return Laya.Event.RIGHT_CLICK; + } + } + static initBasicFunctions() { + if (!DebugTool.debugLayer) { + DebugInfoLayer.init(); + DebugTool.debugLayer = DebugInfoLayer.I.graphicLayer; + DebugTool.debugLayer.mouseEnabled = false; + DebugTool.debugLayer.mouseThrough = true; + DebugTool.showStatu = true; + Laya.Laya.stage.on(Laya.Event.KEY_DOWN, null, DebugTool.keyHandler); + DebugTool.export(); + } + } + static dTrace(str) { + if (DebugTool._traceFun != null) { + DebugTool._traceFun(str); + } + console.log(str); + } + static keyHandler(e) { + var key; + key = String.fromCharCode(e.keyCode); + if (!e.altKey) + return; + switch (e.keyCode) { + case 38: + DebugTool.showParent(); + break; + case 40: + DebugTool.showChild(); + break; + case 37: + DebugTool.showBrother(DebugTool.target, 1); + break; + case 39: + DebugTool.showBrother(DebugTool.target, -1); + break; + } + DebugTool.dealCMDKey(key); + } + static dealCMDKey(key) { + switch (key) { + case "上": + DebugTool.showParent(); + break; + case "下": + DebugTool.showChild(); + break; + case "左": + DebugTool.showBrother(DebugTool.target, 1); + break; + case "右": + DebugTool.showBrother(DebugTool.target, -1); + break; + case "B": + DebugTool.showAllBrother(); + break; + case "C": + DebugTool.showAllChild(); + break; + case "E": + DebugTool.traceDisMouseEnable(); + break; + case "S": + DebugTool.traceDisSizeChain(); + break; + case "D": + DisControlTool.downDis(DebugTool.target); + break; + case "U": + DisControlTool.upDis(DebugTool.target); + break; + case "N": + DebugTool.getNodeInfo(); + break; + case "M": + DebugTool.showAllUnderMosue(); + break; + case "I": + break; + case "O": + break; + case "L": + DisController.I.switchType(); + break; + case "Q": + DebugTool.showNodeInfo(); + break; + case "F": + DebugTool.showToolPanel(); + break; + case "P": + DebugTool.showToolFilter(); + break; + case "V": + DebugTool.selectNodeUnderMouse(); + break; + case "A": + break; + case "K": + NodeUtils.traceStage(); + break; + case "T": + DebugTool.switchNodeTree(); + break; + case "R": + break; + case "X": + break; + case "mCMD": + DebugTool.traceCMD(); + break; + case "allCMD": + DebugTool.traceCMDR(); + break; + } + } + static switchNodeTree() { + } + static selectNodeUnderMouse() { + DebugTool.showDisBound(); + return; + } + static showToolPanel() { + } + static showToolFilter() { + } + static showNodeInfo() { + if (NodeInfoPanel.I.isWorkState) { + NodeInfoPanel.I.recoverNodes(); + } + else { + NodeInfoPanel.I.showDisInfo(DebugTool.target); + } + } + static switchDisController() { + if (DisController.I.target) { + DisController.I.target = null; + } + else { + if (DebugTool.target) { + DisController.I.target = DebugTool.target; + } + } + } + static get isThisShow() { + return false; + } + static showParent(sprite = null) { + if (!sprite) + sprite = DebugTool.target; + if (!sprite) { + console.log("no targetAvalible"); + return null; + } + DebugTool.target = sprite.parent; + DebugTool.autoWork(); + } + static showChild(sprite = null) { + if (!sprite) + sprite = DebugTool.target; + if (!sprite) { + console.log("no targetAvalible"); + return null; + } + if (sprite.numChildren > 0) { + DebugTool.target = sprite.getChildAt(0); + DebugTool.autoWork(); + } + } + static showAllChild(sprite = null) { + if (!sprite) + sprite = DebugTool.target; + if (!sprite) { + console.log("no targetAvalible"); + return null; + } + DebugTool.selectedNodes = DisControlTool.getAllChild(sprite); + DebugTool.showSelected(); + } + static showAllUnderMosue() { + DebugTool.selectedNodes = DisControlTool.getObjectsUnderGlobalPoint(Laya.Laya.stage); + DebugTool.showSelected(); + } + static showParentChain(sprite = null) { + if (!sprite) + return; + DebugTool.selectedNodes = []; + var tar; + tar = sprite.parent; + while (tar) { + DebugTool.selectedNodes.push(tar); + tar = tar.parent; + } + DebugTool.showSelected(); + } + static showAllBrother(sprite = null) { + if (!sprite) + sprite = DebugTool.target; + if (!sprite) { + console.log("no targetAvalible"); + return null; + } + if (!sprite.parent) + return; + DebugTool.selectedNodes = DisControlTool.getAllChild(sprite.parent); + DebugTool.showSelected(); + } + static showBrother(sprite, dID = 1) { + if (!sprite) + sprite = DebugTool.target; + if (!sprite) { + console.log("no targetAvalible"); + return null; + } + var p; + p = sprite.parent; + if (!p) + return; + var n; + n = p.getChildIndex(sprite); + n += dID; + if (n < 0) + n += p.numChildren; + if (n >= p.numChildren) + n -= p.numChildren; + DebugTool.target = p.getChildAt(n); + DebugTool.autoWork(); + } + static set showStatu(value) { + if (value) { + Laya.Stat.show(); + } + else { + Laya.Stat.hide(); + DebugTool.clearDebugLayer(); + } + } + static clearDebugLayer() { + if (DebugTool.debugLayer.graphics) + DebugTool.debugLayer.graphics.clear(); + } + static set target(v) { + DebugTool._target = v; + } + static get target() { + return DebugTool._target; + } + static showSelected() { + if (!DebugTool.autoShowSelected) + return; + if (!DebugTool.selectedNodes || DebugTool.selectedNodes.length < 1) + return; + console.log("selected:", DebugTool.selectedNodes); + var i; + var len; + len = DebugTool.selectedNodes.length; + DebugTool.clearDebugLayer(); + for (i = 0; i < len; i++) { + DebugTool.showDisBound(DebugTool.selectedNodes[i], false); + } + } + static getClassCreateInfo(className) { + return RunProfile.getRunInfo(className); + } + static set showBound(value) { + DebugTool._showBound = value; + if (!DebugTool._showBound) { + DebugTool.clearDebugLayer(); + } + } + static get showBound() { + return DebugTool._showBound; + } + static autoWork() { + if (!DebugTool.isThisShow) + return; + if (DebugTool.showBound) + DebugTool.showDisBound(); + if (DebugTool.autoTraceSpriteInfo && DebugTool.target) { + TraceTool.traceSpriteInfo(DebugTool.target, DebugTool.autoTraceBounds, DebugTool.autoTraceSize, DebugTool.autoTraceTree); + } + if (!DebugTool.target) + return; + if (DebugTool.autoTraceCMD) { + DebugTool.traceCMD(); + } + if (DebugTool.autoTraceCMDR) { + DebugTool.traceCMDR(); + } + if (DebugTool.autoTraceEnable) { + DebugTool.traceDisMouseEnable(DebugTool.target); + } + } + static traceDisMouseEnable(tar = null) { + console.log("----------------traceDisMouseEnable--------------------"); + if (!tar) + tar = DebugTool.target; + if (!tar) { + console.log("no targetAvalible"); + return null; + } + var strArr; + strArr = []; + DebugTool.selectedNodes = []; + while (tar) { + strArr.push(ClassTool.getNodeClassAndName(tar) + ": mouseEnabled:" + tar.mouseEnabled + " hitFirst:" + tar.hitTestPrior); + DebugTool.selectedNodes.push(tar); + tar = tar.parent; + } + console.log(strArr.join("\n")); + DebugTool.showSelected(); + return strArr.join("\n"); + } + static traceDisSizeChain(tar = null) { + console.log("---------------------traceDisSizeChain-------------------"); + if (!tar) + tar = DebugTool.target; + if (!tar) { + console.log("no targetAvalible"); + return null; + } + DebugTool.selectedNodes = []; + var strArr; + strArr = []; + while (tar) { + strArr.push(ClassTool.getNodeClassAndName(tar) + ": x:" + tar.x + " y:" + tar.y + " w:" + tar.width + " h:" + tar.height + " scaleX:" + tar.scaleX + " scaleY:" + tar.scaleY); + DebugTool.selectedNodes.push(tar); + tar = tar.parent; + } + console.log(strArr.join("\n")); + DebugTool.showSelected(); + return strArr.join("\n"); + } + static showDisBound(sprite = null, clearPre = true, color = "#ff0000") { + if (!sprite) + sprite = DebugTool.target; + if (!sprite) { + console.log("no targetAvalible"); + return null; + } + if (clearPre) + DebugTool.clearDebugLayer(); + var pointList; + pointList = sprite._getBoundPointsM(true); + if (!pointList || pointList.length < 1) + return; + pointList = Laya.GrahamScan.pListToPointList(pointList, true); + WalkTools.walkArr(pointList, sprite.localToGlobal, sprite); + pointList = Laya.GrahamScan.pointListToPlist(pointList); + DebugTool._disBoundRec = Laya.Rectangle._getWrapRec(pointList, DebugTool._disBoundRec); + DebugTool.debugLayer.graphics.drawRect(DebugTool._disBoundRec.x, DebugTool._disBoundRec.y, DebugTool._disBoundRec.width, DebugTool._disBoundRec.height, null, color); + DebugInfoLayer.I.setTop(); + } + static showDisBoundToSprite(sprite = null, graphicSprite = null, color = "#ff0000", lineWidth = 1) { + var pointList; + pointList = sprite._getBoundPointsM(true); + if (!pointList || pointList.length < 1) + return; + pointList = Laya.GrahamScan.pListToPointList(pointList, true); + WalkTools.walkArr(pointList, sprite.localToGlobal, sprite); + pointList = Laya.GrahamScan.pointListToPlist(pointList); + DebugTool._disBoundRec = Laya.Rectangle._getWrapRec(pointList, DebugTool._disBoundRec); + graphicSprite.graphics.drawRect(DebugTool._disBoundRec.x, DebugTool._disBoundRec.y, DebugTool._disBoundRec.width, DebugTool._disBoundRec.height, null, color, lineWidth); + } + static getNodeInfo() { + DebugTool.counter.reset(); + WalkTools.walkTarget(Laya.Laya.stage, DebugTool.addNodeInfo); + console.log("node info:"); + DebugTool.counter.traceSelf(); + return DebugTool.counter.data; + } + static findByClass(className) { + DebugTool._classList = []; + DebugTool._tFindClass = className; + WalkTools.walkTarget(Laya.Laya.stage, DebugTool.addClassNode); + DebugTool.selectedNodes = DebugTool._classList; + DebugTool.showSelected(); + return DebugTool._classList; + } + static addClassNode(node) { + var type; + type = node["constructor"].name; + if (type == DebugTool._tFindClass) { + DebugTool._classList.push(node); + } + } + static traceCMD(sprite = null) { + if (!sprite) + sprite = DebugTool.target; + if (!sprite) { + console.log("no targetAvalible"); + return null; + } + console.log("self CMDs:"); + console.log(sprite.graphics.cmds); + var renderSprite; + renderSprite = Laya.RenderSprite.renders[sprite._renderType]; + console.log("renderSprite:", renderSprite); + DebugTool._rSpList.length = 0; + while (renderSprite && renderSprite["_sign"] > 0) { + DebugTool._rSpList.push(DebugTool.cmdToTypeO[renderSprite["_sign"]]); + renderSprite = renderSprite._next; + } + console.log("fun:", DebugTool._rSpList.join(",")); + DebugTool.counter.reset(); + DebugTool.addCMDs(sprite.graphics.cmds); + DebugTool.counter.traceSelf(); + return DebugTool.counter.data; + } + static addCMDs(cmds) { + WalkTools.walkArr(cmds, DebugTool.addCMD); + } + static addCMD(cmd) { + DebugTool.counter.add(cmd.callee); + } + static traceCMDR(sprite = null) { + if (!sprite) + sprite = DebugTool.target; + if (!sprite) { + console.log("no targetAvalible"); + return 0; + } + DebugTool.counter.reset(); + WalkTools.walkTarget(sprite, DebugTool.getCMdCount); + console.log("cmds include children"); + DebugTool.counter.traceSelf(); + return DebugTool.counter.data; + } + static getCMdCount(target) { + if (!target) + return 0; + if (!(target instanceof Laya.Sprite)) + return 0; + if (!target.graphics.cmds) + return 0; + DebugTool.addCMDs(target.graphics.cmds); + var rst = target.graphics.cmds.length; + return rst; + } + static addNodeInfo(node) { + var type; + type = node["constructor"].name; + DebugTool.counter.add(type); + } + static find(filter, ifShowSelected = true) { + var rst; + rst = DebugTool.findTarget(Laya.Laya.stage, filter); + DebugTool.selectedNodes = rst; + if (DebugTool.selectedNodes) { + DebugTool.target = DebugTool.selectedNodes[0]; + } + if (ifShowSelected) + DebugTool.showSelected(); + return rst; + } + static findByName(name) { + DebugTool.nameFilter.name = name; + return DebugTool.find(DebugTool.nameFilter); + } + static findNameStartWith(startStr) { + DebugTool.nameFilter.name = DebugTool.getStartWithFun(startStr); + return DebugTool.find(DebugTool.nameFilter); + } + static findNameHas(hasStr, showSelected = true) { + DebugTool.nameFilter.name = DebugTool.getHasFun(hasStr); + return DebugTool.find(DebugTool.nameFilter, showSelected); + } + static getStartWithFun(startStr) { + var rst = function (str) { + if (!str) + return false; + if (str.indexOf(startStr) == 0) + return true; + return false; + }; + return rst; + } + static getHasFun(hasStr) { + var rst = function (str) { + if (!str) + return false; + if (str.indexOf(hasStr) >= 0) + return true; + return false; + }; + return rst; + } + static findTarget(target, filter) { + var rst = []; + if (DebugTool.isFit(target, filter)) + rst.push(target); + var i; + var len; + var tChild; + len = target.numChildren; + for (i = 0; i < len; i++) { + tChild = target.getChildAt(i); + if (tChild instanceof Laya.Sprite) { + rst = rst.concat(DebugTool.findTarget(tChild, filter)); + } + } + return rst; + } + static findClassHas(target, str) { + var rst = []; + if (ClassTool.getClassName(target).indexOf(str) >= 0) + rst.push(target); + var i; + var len; + var tChild; + len = target.numChildren; + for (i = 0; i < len; i++) { + tChild = target.getChildAt(i); + if (tChild instanceof Laya.Sprite) { + rst = rst.concat(DebugTool.findClassHas(tChild, str)); + } + } + return rst; + } + static isFit(tar, filter) { + if (!tar) + return false; + if (!filter) + return true; + if (filter instanceof Function) { + return filter(tar); + } + var key; + for (key in filter) { + if (filter[key] instanceof Function) { + if (!filter[key](tar[key])) + return false; + } + else { + if (tar[key] != filter[key]) + return false; + } + } + return true; + } + static log(...args) { + var arr; + arr = DTrace.getArgArr(args); + if (DebugTool._logFun != null) { + DebugTool._logFun(arr.join(" ")); + } + } + static export() { + var _window; + _window = window; + var key; + for (key in DebugTool._exportsDic) { + _window[key] = DebugTool._exportsDic[key]; + } + } + } + DebugTool.enableCacheAnalyse = false; + DebugTool.enableNodeCreateAnalyse = true; + DebugTool.text = new Laya.Stat(); + DebugTool.selectedNodes = []; + DebugTool.autoShowSelected = true; + DebugTool._showBound = true; + DebugTool.autoTraceEnable = false; + DebugTool.autoTraceBounds = false; + DebugTool.autoTraceSize = false; + DebugTool.autoTraceTree = true; + DebugTool.autoTraceCMD = true; + DebugTool.autoTraceCMDR = false; + DebugTool.autoTraceSpriteInfo = true; + DebugTool.cmdToTypeO = {}; + DebugTool._rSpList = []; + DebugTool.counter = new CountTool(); + DebugTool.nameFilter = { "name": "name" }; + DebugTool._exportsDic = { + "DebugTool": DebugTool, + "Watcher": Watcher + }; + TraceTool._debugtrace = DebugTool.dTrace; + + class ByteEx { + constructor(data = null) { + this._xd_ = true; + this._allocated_ = 8; + this._pos_ = 0; + this._length = 0; + if (data) { + this._u8d_ = new Uint8Array(data); + this._d_ = new DataView(this._u8d_.buffer); + this._length = this._d_.byteLength; + } + else { + this._resizeBuffer(this._allocated_); + } + } + static getSystemEndian() { + if (!ByteEx._sysEndian) { + var buffer = new ArrayBuffer(2); + new DataView(buffer).setInt16(0, 256, true); + ByteEx._sysEndian = (new Int16Array(buffer))[0] === 256 ? ByteEx.LITTLE_ENDIAN : ByteEx.BIG_ENDIAN; + } + return ByteEx._sysEndian; + } + get buffer() { + var rstBuffer = this._d_.buffer; + if (rstBuffer.byteLength === this._length) + return rstBuffer; + return rstBuffer.slice(0, this._length); + } + get endian() { + return this._xd_ ? ByteEx.LITTLE_ENDIAN : ByteEx.BIG_ENDIAN; + } + set endian(value) { + this._xd_ = (value === ByteEx.LITTLE_ENDIAN); + } + set length(value) { + if (this._allocated_ < value) + this._resizeBuffer(this._allocated_ = Math.floor(Math.max(value, this._allocated_ * 2))); + else if (this._allocated_ > value) + this._resizeBuffer(this._allocated_ = value); + this._length = value; + } + get length() { + return this._length; + } + _resizeBuffer(len) { + try { + var newByteView = new Uint8Array(len); + if (this._u8d_ != null) { + if (this._u8d_.length <= len) + newByteView.set(this._u8d_); + else + newByteView.set(this._u8d_.subarray(0, len)); + } + this._u8d_ = newByteView; + this._d_ = new DataView(newByteView.buffer); + } + catch (err) { + throw "Invalid typed array length:" + len; + } + } + getString() { + return this.readString(); + } + readString() { + return this._rUTF(this.getUint16()); + } + getFloat32Array(start, len) { + return this.readFloat32Array(start, len); + } + readFloat32Array(start, len) { + var end = start + len; + end = (end > this._length) ? this._length : end; + var v = new Float32Array(this._d_.buffer.slice(start, end)); + this._pos_ = end; + return v; + } + getUint8Array(start, len) { + return this.readUint8Array(start, len); + } + readUint8Array(start, len) { + var end = start + len; + end = (end > this._length) ? this._length : end; + var v = new Uint8Array(this._d_.buffer.slice(start, end)); + this._pos_ = end; + return v; + } + getInt16Array(start, len) { + return this.readInt16Array(start, len); + } + readInt16Array(start, len) { + var end = start + len; + end = (end > this._length) ? this._length : end; + var v = new Int16Array(this._d_.buffer.slice(start, end)); + this._pos_ = end; + return v; + } + getFloat32() { + return this.readFloat32(); + } + readFloat32() { + if (this._pos_ + 4 > this._length) + throw "getFloat32 error - Out of bounds"; + var v = this._d_.getFloat32(this._pos_, this._xd_); + this._pos_ += 4; + return v; + } + getFloat64() { + return this.readFloat64(); + } + readFloat64() { + if (this._pos_ + 8 > this._length) + throw "getFloat64 error - Out of bounds"; + var v = this._d_.getFloat64(this._pos_, this._xd_); + this._pos_ += 8; + return v; + } + writeFloat32(value) { + this._ensureWrite(this._pos_ + 4); + this._d_.setFloat32(this._pos_, value, this._xd_); + this._pos_ += 4; + } + writeFloat64(value) { + this._ensureWrite(this._pos_ + 8); + this._d_.setFloat64(this._pos_, value, this._xd_); + this._pos_ += 8; + } + getInt32() { + return this.readInt32(); + } + readInt32() { + if (this._pos_ + 4 > this._length) + throw "getInt32 error - Out of bounds"; + var float = this._d_.getInt32(this._pos_, this._xd_); + this._pos_ += 4; + return float; + } + getUint32() { + return this.readUint32(); + } + readUint32() { + if (this._pos_ + 4 > this._length) + throw "getUint32 error - Out of bounds"; + var v = this._d_.getUint32(this._pos_, this._xd_); + this._pos_ += 4; + return v; + } + writeInt32(value) { + this._ensureWrite(this._pos_ + 4); + this._d_.setInt32(this._pos_, value, this._xd_); + this._pos_ += 4; + } + writeUint32(value) { + this._ensureWrite(this._pos_ + 4); + this._d_.setUint32(this._pos_, value, this._xd_); + this._pos_ += 4; + } + getInt16() { + return this.readInt16(); + } + readInt16() { + if (this._pos_ + 2 > this._length) + throw "getInt16 error - Out of bounds"; + var us = this._d_.getInt16(this._pos_, this._xd_); + this._pos_ += 2; + return us; + } + getUint16() { + return this.readUint16(); + } + readUint16() { + if (this._pos_ + 2 > this._length) + throw "getUint16 error - Out of bounds"; + var us = this._d_.getUint16(this._pos_, this._xd_); + this._pos_ += 2; + return us; + } + writeUint16(value) { + this._ensureWrite(this._pos_ + 2); + this._d_.setUint16(this._pos_, value, this._xd_); + this._pos_ += 2; + } + writeInt16(value) { + this._ensureWrite(this._pos_ + 2); + this._d_.setInt16(this._pos_, value, this._xd_); + this._pos_ += 2; + } + getUint8() { + return this.readUint8(); + } + readUint8() { + if (this._pos_ + 1 > this._length) + throw "getUint8 error - Out of bounds"; + return this._d_.getUint8(this._pos_++); + } + writeUint8(value) { + this._ensureWrite(this._pos_ + 1); + this._d_.setUint8(this._pos_, value); + this._pos_++; + } + _getUInt8(pos) { + return this._readUInt8(pos); + } + _readUInt8(pos) { + return this._d_.getUint8(pos); + } + _getUint16(pos) { + return this._readUint16(pos); + } + _readUint16(pos) { + return this._d_.getUint16(pos, this._xd_); + } + _getMatrix() { + return this._readMatrix(); + } + _readMatrix() { + var rst = new Laya.Matrix(this.getFloat32(), this.getFloat32(), this.getFloat32(), this.getFloat32(), this.getFloat32(), this.getFloat32()); + return rst; + } + _rUTF(len) { + var v = "", max = this._pos_ + len, c, c2, c3, f = String.fromCharCode; + var u = this._u8d_; + while (this._pos_ < max) { + c = u[this._pos_++]; + if (c < 0x80) { + if (c != 0) + v += f(c); + } + else if (c < 0xE0) { + v += f(((c & 0x3F) << 6) | (u[this._pos_++] & 0x7F)); + } + else if (c < 0xF0) { + c2 = u[this._pos_++]; + v += f(((c & 0x1F) << 12) | ((c2 & 0x7F) << 6) | (u[this._pos_++] & 0x7F)); + } + else { + c2 = u[this._pos_++]; + c3 = u[this._pos_++]; + v += f(((c & 0x0F) << 18) | ((c2 & 0x7F) << 12) | ((c3 << 6) & 0x7F) | (u[this._pos_++] & 0x7F)); + } + } + return v; + } + getCustomString(len) { + return this.readCustomString(len); + } + readCustomString(len) { + var v = "", ulen = 0, c, c2, f = String.fromCharCode; + var u = this._u8d_; + while (len > 0) { + c = u[this._pos_]; + if (c < 0x80) { + v += f(c); + this._pos_++; + len--; + } + else { + ulen = c - 0x80; + this._pos_++; + len -= ulen; + while (ulen > 0) { + c = u[this._pos_++]; + c2 = u[this._pos_++]; + v += f((c2 << 8) | c); + ulen--; + } + } + } + return v; + } + get pos() { + return this._pos_; + } + set pos(value) { + this._pos_ = value; + } + get bytesAvailable() { + return this._length - this._pos_; + } + clear() { + this._pos_ = 0; + this.length = 0; + } + __getBuffer() { + return this._d_.buffer; + } + writeUTFBytes(value) { + value = value + ""; + for (var i = 0, sz = value.length; i < sz; i++) { + var c = value.charCodeAt(i); + if (c <= 0x7F) { + this.writeByte(c); + } + else if (c <= 0x7FF) { + this._ensureWrite(this._pos_ + 2); + this._u8d_.set([0xC0 | (c >> 6), 0x80 | (c & 0x3F)], this._pos_); + this._pos_ += 2; + } + else if (c <= 0xFFFF) { + this._ensureWrite(this._pos_ + 3); + this._u8d_.set([0xE0 | (c >> 12), 0x80 | ((c >> 6) & 0x3F), 0x80 | (c & 0x3F)], this._pos_); + this._pos_ += 3; + } + else { + this._ensureWrite(this._pos_ + 4); + this._u8d_.set([0xF0 | (c >> 18), 0x80 | ((c >> 12) & 0x3F), 0x80 | ((c >> 6) & 0x3F), 0x80 | (c & 0x3F)], this._pos_); + this._pos_ += 4; + } + } + } + writeUTFString(value) { + var tPos = this.pos; + this.writeUint16(1); + this.writeUTFBytes(value); + var dPos = this.pos - tPos - 2; + this._d_.setUint16(tPos, dPos, this._xd_); + } + readUTFString() { + return this.readUTFBytes(this.getUint16()); + } + getUTFString() { + return this.readUTFString(); + } + readUTFBytes(len = -1) { + if (len === 0) + return ""; + var lastBytes = this.bytesAvailable; + if (len > lastBytes) + throw "readUTFBytes error - Out of bounds"; + len = len > 0 ? len : lastBytes; + return this._rUTF(len); + } + getUTFBytes(len = -1) { + return this.readUTFBytes(len); + } + writeByte(value) { + this._ensureWrite(this._pos_ + 1); + this._d_.setInt8(this._pos_, value); + this._pos_ += 1; + } + readByte() { + if (this._pos_ + 1 > this._length) + throw "readByte error - Out of bounds"; + return this._d_.getInt8(this._pos_++); + } + getByte() { + return this.readByte(); + } + _ensureWrite(lengthToEnsure) { + if (this._length < lengthToEnsure) + this._length = lengthToEnsure; + if (this._allocated_ < lengthToEnsure) + this.length = lengthToEnsure; + } + writeArrayBuffer(arraybuffer, offset = 0, length = 0) { + if (offset < 0 || length < 0) + throw "writeArrayBuffer error - Out of bounds"; + if (length == 0) + length = arraybuffer.byteLength - offset; + this._ensureWrite(this._pos_ + length); + var uint8array = new Uint8Array(arraybuffer); + this._u8d_.set(uint8array.subarray(offset, offset + length), this._pos_); + this._pos_ += length; + } + } + ByteEx.BIG_ENDIAN = "bigEndian"; + ByteEx.LITTLE_ENDIAN = "littleEndian"; + ByteEx._sysEndian = null; + + class Base64Tool { + constructor() { + } + static init() { + if (Base64Tool.lookup) + return; + Base64Tool.lookup = new Uint8Array(256); + for (var i = 0; i < Base64Tool.chars.length; i++) { + Base64Tool.lookup[Base64Tool.chars.charCodeAt(i)] = i; + } + } + static encode(arraybuffer) { + var bytes = new Uint8Array(arraybuffer), i, len = bytes["length"], base64 = ""; + for (i = 0; i < len; i += 3) { + base64 += Base64Tool.chars[bytes[i] >> 2]; + base64 += Base64Tool.chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)]; + base64 += Base64Tool.chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)]; + base64 += Base64Tool.chars[bytes[i + 2] & 63]; + } + if ((len % 3) === 2) { + base64 = base64.substring(0, base64.length - 1) + "="; + } + else if (len % 3 === 1) { + base64 = base64.substring(0, base64.length - 2) + "=="; + } + return base64; + } + static encodeStr(str) { + var byte; + byte = new ByteEx(); + byte.writeUTFString(str); + return Base64Tool.encodeByte(byte); + } + static encodeStr2(str) { + var byte; + byte = new ByteEx(); + byte.writeUTFBytes(str); + return Base64Tool.encodeByte(byte); + } + static encodeByte(byte, start = 0, end = -1) { + if (end < 0) { + end = byte.length; + } + return Base64Tool.encode(byte.buffer.slice(start, end)); + } + static decodeToByte(base64) { + return new ByteEx(Base64Tool.decode(base64)); + } + static decode(base64) { + Base64Tool.init(); + var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4; + if (base64[base64.length - 1] === "=") { + bufferLength--; + if (base64[base64.length - 2] === "=") { + bufferLength--; + } + } + var arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer); + for (i = 0; i < len; i += 4) { + encoded1 = Base64Tool.lookup[base64.charCodeAt(i)]; + encoded2 = Base64Tool.lookup[base64.charCodeAt(i + 1)]; + encoded3 = Base64Tool.lookup[base64.charCodeAt(i + 2)]; + encoded4 = Base64Tool.lookup[base64.charCodeAt(i + 3)]; + bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); + bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); + bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); + } + return arraybuffer; + } + ; + } + Base64Tool.chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + Base64Tool.lookup = null; + + class DivScripts { + constructor() { + } + static init() { + var script; + script = Base64Tool.decodeToByte(DivScripts.data).readUTFBytes(); + window["eval"](script); + } + } + DivScripts.data = "ZnVuY3Rpb24gZGh0bWx4RXZlbnQoZSx0LGkpe2UuYWRkRXZlbnRMaXN0ZW5lcj9lLmFkZEV2ZW50TGlzdGVuZXIodCxpLCExKTplLmF0dGFjaEV2ZW50JiZlLmF0dGFjaEV2ZW50KCJvbiIrdCxpKX1mdW5jdGlvbiBkaHRtbFhUcmVlT2JqZWN0KGUsdCxpLG4pe2lmKGRodG1seEV2ZW50LmluaXRUb3VjaCYmZGh0bWx4RXZlbnQuaW5pdFRvdWNoKCksX2lzSUUpdHJ5e2RvY3VtZW50LmV4ZWNDb21tYW5kKCJCYWNrZ3JvdW5kSW1hZ2VDYWNoZSIsITEsITApfWNhdGNoKG8pe310aGlzLnBhcmVudE9iamVjdD0ib2JqZWN0IiE9dHlwZW9mIGU/ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZSk6ZSx0aGlzLnBhcmVudE9iamVjdC5zdHlsZS5vdmVyZmxvdz0iaGlkZGVuIix0aGlzLl9pdGltX2RnPSEwLHRoaXMuZGxtdHI9IiwiLHRoaXMuZHJvcExvd2VyPSExLHRoaXMuZW5hYmxlSUVJbWFnZUZpeCghMCksdGhpcy54bWxzdGF0ZT0wLHRoaXMubXl0eXBlPSJ0cmVlIix0aGlzLnNtY2hlY2s9ITAsdGhpcy53aWR0aD10LHRoaXMuaGVpZ2h0PWksdGhpcy5yb290SWQ9bix0aGlzLmNoaWxkQ2FsYz1udWxsLHRoaXMuZGVmX2ltZ194PSIxOHB4Iix0aGlzLmRlZl9pbWdfeT0iMThweCIsdGhpcy5kZWZfbGluZV9pbWdfeD0iMThweCIsdGhpcy5kZWZfbGluZV9pbWdfeT0iMjRweCIsdGhpcy5fZHJhZ2dlZD1uZXcgQXJyYXksdGhpcy5fc2VsZWN0ZWQ9bmV3IEFycmF5LHRoaXMuc3R5bGVfcG9pbnRlcj0icG9pbnRlciIsdGhpcy5fYWltZ3M9ITAsdGhpcy5odG1sY0E9IiBbIix0aGlzLmh0bWxjQj0iXSIsdGhpcy5sV2luPXdpbmRvdyx0aGlzLmNNZW51PTAsdGhpcy5tbGl0ZW1zPTAsdGhpcy5pY29uVVJMPSIiLHRoaXMuZGFkbW9kZT0wLHRoaXMuc2xvd1BhcnNlPSExLHRoaXMuYXV0b1Njcm9sbD0hMCx0aGlzLmhmTW9kZT0wLHRoaXMubm9kZUN1dD1uZXcgQXJyYXksdGhpcy5YTUxzb3VyY2U9MCx0aGlzLlhNTGxvYWRpbmdXYXJuaW5nPTAsdGhpcy5faWRwdWxsPXt9LHRoaXMuX3B1bGxTaXplPTAsdGhpcy50cmVlTGluZXNPbj0hMCx0aGlzLnRzY2hlY2s9ITEsdGhpcy50aW1nZW49ITAsdGhpcy5kcGNweT0hMSx0aGlzLl9sZF9pZD1udWxsLHRoaXMuX2R5bkRlbGV0ZUJyYW5jaGVzPXt9LHRoaXMuX29pZV9vblhMRT1bXSx0aGlzLmltUGF0aD13aW5kb3cuZGh4X2dsb2JhbEltZ1BhdGh8fCIiLHRoaXMuY2hlY2tBcnJheT1uZXcgQXJyYXkoImljb25VbmNoZWNrQWxsLmdpZiIsImljb25DaGVja0FsbC5naWYiLCJpY29uQ2hlY2tHcmF5LmdpZiIsImljb25VbmNoZWNrRGlzLmdpZiIsImljb25DaGVja0Rpcy5naWYiLCJpY29uQ2hlY2tEaXMuZ2lmIiksdGhpcy5yYWRpb0FycmF5PW5ldyBBcnJheSgicmFkaW9fb2ZmLmdpZiIsInJhZGlvX29uLmdpZiIsInJhZGlvX29uLmdpZiIsInJhZGlvX29mZi5naWYiLCJyYWRpb19vbi5naWYiLCJyYWRpb19vbi5naWYiKSx0aGlzLmxpbmVBcnJheT1uZXcgQXJyYXkoImxpbmUyLmdpZiIsImxpbmUzLmdpZiIsImxpbmU0LmdpZiIsYmxhbmtfYmFzZTY0LGJsYW5rX2Jhc2U2NCwibGluZTEuZ2lmIiksdGhpcy5taW51c0FycmF5PW5ldyBBcnJheSgibWludXMyLmdpZiIsIm1pbnVzMy5naWYiLCJtaW51czQuZ2lmIiwiZGF0YTppbWFnZS9naWY7YmFzZTY0LFIwbEdPRGxoRWdBWUFKRUNBTEd2clo2ZG5mVDA5QUFBQUNINUJBRUFBQUlBTEFBQUFBQVNBQmdBQUFJY2xJK3B5KzBQbzV5MFdoc0NEV0IzbUdYZnd3SG1oYWJxeXJaVEFRQTciLCJtaW51czUuZ2lmIiksdGhpcy5wbHVzQXJyYXk9bmV3IEFycmF5KCJwbHVzMi5naWYiLCJwbHVzMy5naWYiLCJwbHVzNC5naWYiLCJkYXRhOmltYWdlL2dpZjtiYXNlNjQsUjBsR09EbGhFZ0FZQUpFQ0FLR2duN0d2cmZUMDlBQUFBQ0g1QkFFQUFBSUFMQUFBQUFBU0FCZ0FBQUljbEkrcHkrMFBvNXkwVW5CRHlIc0NMUUZmT0U2ZGhhYnF5clpKQVFBNyIsInBsdXM1LmdpZiIpLHRoaXMuaW1hZ2VBcnJheT1uZXcgQXJyYXkoImRhdGE6aW1hZ2UvZ2lmO2Jhc2U2NCxSMGxHT0RsaEVnQVNBS0VDQUplWGw3R3ZyZi8vLy8vLy95SDVCQUVLQUFJQUxBQUFBQUFTQUJJQUFBSXpsSStwQXUyOURBaTAxamlUWFJuTm0zVEhCNDVCYUoyZXVsQm94TENTL0s2d09OODBYcHQ2citCOUhrU2FJSVdFS1EwRkFEcz0iLCJkYXRhOmltYWdlL2dpZjtiYXNlNjQsUjBsR09EbGhFZ0FTQUtFQ0FKZVhsN0d2cmYvLy8vLy8veUg1QkFFS0FBSUFMQUFBQUFBU0FCSUFBQUl6bEkrcHl3Y1BtM21oV2drQ3NqQk92VmtpbUVsRzlabENCbFhkKzJYampMS2c1R3FvZVpYcXZzT1FYSy9palVaVEtWVUZBRHM9IiwiZGF0YTppbWFnZS9naWY7YmFzZTY0LFIwbEdPRGxoRWdBU0FLRUNBSmVYbDdHdnJmLy8vLy8vL3lINUJBRUtBQUlBTEFBQUFBQVNBQklBQUFJd2xJK3B5d2NQbTNtaFdna0NzakJPdlZraW1FbEc5WmxDdVlJWTZUWXMrNmJtSERPNGlnZmREM0dOaGhlVjBWUUFBRHM9IiksdGhpcy5jdXRJbWc9bmV3IEFycmF5KDAsMCwwKSx0aGlzLmN1dEltYWdlPSJidXRfY3V0LmdpZiIsZGh4NC5fZXZlbnRhYmxlKHRoaXMpLHRoaXMuaHRtbE5vZGU9bmV3IGRodG1sWFRyZWVJdGVtT2JqZWN0KHRoaXMucm9vdElkLCIiLDAsdGhpcyksdGhpcy5odG1sTm9kZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXNbMF0uc3R5bGUuZGlzcGxheT0ibm9uZSIsdGhpcy5odG1sTm9kZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXNbMF0uY2hpbGROb2Rlc1swXS5jbGFzc05hbWU9ImhpZGRlblJvdyIsdGhpcy5hbGxUcmVlPXRoaXMuX2NyZWF0ZVNlbGYoKSx0aGlzLmFsbFRyZWUuYXBwZW5kQ2hpbGQodGhpcy5odG1sTm9kZS5odG1sTm9kZSksZGh0bWx4LiRjdXN0b21TY3JvbGwmJmRodG1seC5DdXN0b21TY3JvbGwuZW5hYmxlKHRoaXMpLF9pc0ZGJiYodGhpcy5hbGxUcmVlLmNoaWxkTm9kZXNbMF0ud2lkdGg9IjEwMCUiLHRoaXMuYWxsVHJlZS5jaGlsZE5vZGVzWzBdLnN0eWxlLm92ZXJmbG93PSJoaWRkZW4iKTt2YXIgcj10aGlzO2lmKHRoaXMuYWxsVHJlZS5vbnNlbGVjdHN0YXJ0PW5ldyBGdW5jdGlvbigicmV0dXJuIGZhbHNlOyIpLF9pc01hY09TJiYodGhpcy5hbGxUcmVlLm9uY29udGV4dG1lbnU9ZnVuY3Rpb24oZSl7cmV0dXJuIHIuX2RvQ29udENsaWNrKGV8fHdpbmRvdy5ldmVudCwhMCl9KSx0aGlzLmFsbFRyZWUub25tb3VzZWRvd249ZnVuY3Rpb24oZSl7cmV0dXJuIHIuX2RvQ29udENsaWNrKGV8fHdpbmRvdy5ldmVudCl9LHRoaXMuWE1MTG9hZGVyPXRoaXMuX3BhcnNlWE1MVHJlZSxfaXNJRSYmdGhpcy5wcmV2ZW50SUVDYXNoaW5nKCEwKSx0aGlzLnNlbGVjdGlvbkJhcj1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJESVYiKSx0aGlzLnNlbGVjdGlvbkJhci5jbGFzc05hbWU9InNlbGVjdGlvbkJhciIsdGhpcy5zZWxlY3Rpb25CYXIuaW5uZXJIVE1MPSImbmJzcDsiLHRoaXMuc2VsZWN0aW9uQmFyLnN0eWxlLmRpc3BsYXk9Im5vbmUiLHRoaXMuYWxsVHJlZS5hcHBlbmRDaGlsZCh0aGlzLnNlbGVjdGlvbkJhciksd2luZG93LmFkZEV2ZW50TGlzdGVuZXImJndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJ1bmxvYWQiLGZ1bmN0aW9uKCl7dHJ5e3IuZGVzdHJ1Y3RvcigpfWNhdGNoKGUpe319LCExKSx3aW5kb3cuYXR0YWNoRXZlbnQmJndpbmRvdy5hdHRhY2hFdmVudCgib251bmxvYWQiLGZ1bmN0aW9uKCl7dHJ5e3IuZGVzdHJ1Y3RvcigpfWNhdGNoKGUpe319KSx0aGlzLnNldEltYWdlc1BhdGg9dGhpcy5zZXRJbWFnZVBhdGgsdGhpcy5zZXRJY29uc1BhdGg9dGhpcy5zZXRJY29uUGF0aCx0aGlzLnNldFNraW4oIm1hdGVyaWFsIiksZGh0bWx4LmltYWdlX3BhdGgpe3ZhciBsPWRodG1seC5pbWFnZV9wYXRoLHM9dGhpcy5wYXJlbnRPYmplY3QuY2xhc3NOYW1lLm1hdGNoKC9kaHh0cmVlX2RoeF8oW2Etel9dKikvaSk7bnVsbCE9cyYmbnVsbCE9c1sxXSYmKGwrPSJkaHh0cmVlXyIrc1sxXSsiLyIpLHRoaXMuc2V0SW1hZ2VQYXRoKGwpfXJldHVybiB0aGlzfWZ1bmN0aW9uIGNPYmplY3QoKXtyZXR1cm4gdGhpc31mdW5jdGlvbiBkaHRtbFhUcmVlSXRlbU9iamVjdChlLHQsaSxuLG8scil7cmV0dXJuIHRoaXMuaHRtbE5vZGU9IiIsdGhpcy5hY29sb3I9IiIsdGhpcy5zY29sb3I9IiIsdGhpcy50cj0wLHRoaXMuY2hpbGRzQ291bnQ9MCx0aGlzLnRlbXBET01NPTAsdGhpcy50ZW1wRE9NVT0wLHRoaXMuZHJhZ1NwYW49MCx0aGlzLmRyYWdNb3ZlPTAsdGhpcy5zcGFuPTAsdGhpcy5jbG9zZWJsZT0xLHRoaXMuY2hpbGROb2Rlcz1uZXcgQXJyYXksdGhpcy51c2VyRGF0YT1uZXcgY09iamVjdCx0aGlzLmNoZWNrc3RhdGU9MCx0aGlzLnRyZWVOb2Q9bix0aGlzLmxhYmVsPXQsdGhpcy5wYXJlbnRPYmplY3Q9aSx0aGlzLmFjdGlvbkhhbmRsZXI9byx0aGlzLmltYWdlcz1uZXcgQXJyYXkobi5pbWFnZUFycmF5WzBdLG4uaW1hZ2VBcnJheVsxXSxuLmltYWdlQXJyYXlbMl0pLHRoaXMuaWQ9bi5fZ2xvYmFsSWRTdG9yYWdlQWRkKGUsdGhpcyksdGhpcy5odG1sTm9kZT10aGlzLnRyZWVOb2QuY2hlY2tCb3hPZmY/dGhpcy50cmVlTm9kLl9jcmVhdGVJdGVtKDEsdGhpcyxyKTp0aGlzLnRyZWVOb2QuX2NyZWF0ZUl0ZW0oMCx0aGlzLHIpLHRoaXMuaHRtbE5vZGUub2JqQmVsb25nPXRoaXMsdGhpc31mdW5jdGlvbiBqc29uUG9pbnRlcihlLHQpe3RoaXMuZD1lLHRoaXMuZHA9dH1mdW5jdGlvbiBkaHhfaW5pdF90cmVlcygpe2Zvcih2YXIgZT1kb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZGl2IiksdD0wO3Q8ZS5sZW5ndGg7dCsrKSJkaHRtbHhUcmVlIj09ZVt0XS5jbGFzc05hbWUmJmRodG1sWFRyZWVGcm9tSFRNTChlW3RdKX12YXIgYmxhbmtfYmFzZTY0PSJkYXRhOmltYWdlL2dpZjtiYXNlNjQsUjBsR09EbGhFZ0FTQUlBQUFQLy8vLy8vL3lINUJBVVVBQUVBTEFBQUFBQVNBQklBQUFJUGpJK3B5KzBQbzV5MDJvdXozcHdYQURzPSI7InVuZGVmaW5lZCI9PXR5cGVvZiB3aW5kb3cuZGh4JiYod2luZG93LmRoeD13aW5kb3cuZGh4ND17dmVyc2lvbjoiNS4wIixza2luOm51bGwsbGFzdElkOjEsbmV3SWQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5sYXN0SWQrK30semltOntkYXRhOnt9LHN0ZXA6NSxmaXJzdDpmdW5jdGlvbigpe3JldHVybiAxMDB9LGxhc3Q6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLmZpcnN0KCk7Zm9yKHZhciB0IGluIHRoaXMuZGF0YSllPU1hdGgubWF4KGUsdGhpcy5kYXRhW3RdKTtyZXR1cm4gZX0scmVzZXJ2ZTpmdW5jdGlvbihlKXtyZXR1cm4gdGhpcy5kYXRhW2VdPXRoaXMubGFzdCgpK3RoaXMuc3RlcCx0aGlzLmRhdGFbZV19LGNsZWFyOmZ1bmN0aW9uKGUpe251bGwhPXRoaXMuZGF0YVtlXSYmKHRoaXMuZGF0YVtlXT1udWxsLGRlbGV0ZSB0aGlzLmRhdGFbZV0pfX0sczJiOmZ1bmN0aW9uKGUpe3JldHVybiJzdHJpbmciPT10eXBlb2YgZSYmKGU9ZS50b0xvd2VyQ2FzZSgpKSwxPT1lfHwxPT1lfHwidHJ1ZSI9PWV8fCIxIj09ZXx8InllcyI9PWV8fCJ5Ij09ZXx8Im9uIj09ZX0sczJqOmZ1bmN0aW9uKHMpe3ZhciBvYmo9bnVsbDtkaHg0LnRlbXA9bnVsbDt0cnl7ZXZhbCgiZGh4NC50ZW1wPSIrcyl9Y2F0Y2goZSl7ZGh4NC50ZW1wPW51bGx9cmV0dXJuIG9iaj1kaHg0LnRlbXAsZGh4NC50ZW1wPW51bGwsb2JqfSxhYnNMZWZ0OmZ1bmN0aW9uKGUpe3JldHVybiJzdHJpbmciPT10eXBlb2YgZSYmKGU9ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZSkpLHRoaXMuZ2V0T2Zmc2V0KGUpLmxlZnR9LGFic1RvcDpmdW5jdGlvbihlKXtyZXR1cm4ic3RyaW5nIj09dHlwZW9mIGUmJihlPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGUpKSx0aGlzLmdldE9mZnNldChlKS50b3B9LF9hT2ZzOmZ1bmN0aW9uKGUpe2Zvcih2YXIgdD0wLGk9MDtlOyl0Kz1wYXJzZUludChlLm9mZnNldFRvcCksaSs9cGFyc2VJbnQoZS5vZmZzZXRMZWZ0KSxlPWUub2Zmc2V0UGFyZW50O3JldHVybnt0b3A6dCxsZWZ0Oml9fSxfYU9mc1JlY3Q6ZnVuY3Rpb24oZSl7dmFyIHQ9ZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxpPWRvY3VtZW50LmJvZHksbj1kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsbz13aW5kb3cucGFnZVlPZmZzZXR8fG4uc2Nyb2xsVG9wfHxpLnNjcm9sbFRvcCxyPXdpbmRvdy5wYWdlWE9mZnNldHx8bi5zY3JvbGxMZWZ0fHxpLnNjcm9sbExlZnQsbD1uLmNsaWVudFRvcHx8aS5jbGllbnRUb3B8fDAscz1uLmNsaWVudExlZnR8fGkuY2xpZW50TGVmdHx8MCxhPXQudG9wK28tbCxkPXQubGVmdCtyLXM7cmV0dXJue3RvcDpNYXRoLnJvdW5kKGEpLGxlZnQ6TWF0aC5yb3VuZChkKX19LGdldE9mZnNldDpmdW5jdGlvbihlKXtyZXR1cm4gZS5nZXRCb3VuZGluZ0NsaWVudFJlY3Q/dGhpcy5fYU9mc1JlY3QoZSk6dGhpcy5fYU9mcyhlKX0sX2lzT2JqOmZ1bmN0aW9uKGUpe3JldHVybiBudWxsIT1lJiYib2JqZWN0Ij09dHlwZW9mIGUmJiJ1bmRlZmluZWQiPT10eXBlb2YgZS5sZW5ndGh9LF9jb3B5T2JqOmZ1bmN0aW9uKGUpe2lmKHRoaXMuX2lzT2JqKGUpKXt2YXIgdD17fTtmb3IodmFyIGkgaW4gZSl0W2ldPSJvYmplY3QiPT10eXBlb2YgZVtpXSYmbnVsbCE9ZVtpXT90aGlzLl9jb3B5T2JqKGVbaV0pOmVbaV19ZWxzZSBmb3IodmFyIHQ9W10saT0wO2k8ZS5sZW5ndGg7aSsrKXRbaV09Im9iamVjdCI9PXR5cGVvZiBlW2ldJiZudWxsIT1lW2ldP3RoaXMuX2NvcHlPYmooZVtpXSk6ZVtpXTtyZXR1cm4gdH19LHdpbmRvdy5kaHg0LmlzSUU9bmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJNU0lFIik+PTB8fG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiVHJpZGVudCIpPj0wLHdpbmRvdy5kaHg0LmlzSUU2PW51bGw9PXdpbmRvdy5YTUxIdHRwUmVxdWVzdCYmbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJNU0lFIik+PTAsd2luZG93LmRoeDQuaXNJRTc9bmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJNU0lFIDcuMCIpPj0wJiZuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoIlRyaWRlbnQiKTwwLHdpbmRvdy5kaHg0LmlzSUU4PW5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiTVNJRSA4LjAiKT49MCYmbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJUcmlkZW50Iik+PTAsd2luZG93LmRoeDQuaXNJRTk9bmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJNU0lFIDkuMCIpPj0wJiZuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoIlRyaWRlbnQiKT49MCx3aW5kb3cuZGh4NC5pc0lFMTA9bmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJNU0lFIDEwLjAiKT49MCYmbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJUcmlkZW50Iik+PTAmJjEhPXdpbmRvdy5uYXZpZ2F0b3IucG9pbnRlckVuYWJsZWQsd2luZG93LmRoeDQuaXNJRTExPW5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiVHJpZGVudCIpPj0wJiYxPT13aW5kb3cubmF2aWdhdG9yLnBvaW50ZXJFbmFibGVkLHdpbmRvdy5kaHg0LmlzRWRnZT1uYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoIkVkZ2UiKT49MCx3aW5kb3cuZGh4NC5pc09wZXJhPW5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiT3BlcmEiKT49MCx3aW5kb3cuZGh4NC5pc0Nocm9tZT1uYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoIkNocm9tZSIpPj0wJiYhd2luZG93LmRoeDQuaXNFZGdlLHdpbmRvdy5kaHg0LmlzS0hUTUw9KG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiU2FmYXJpIik+PTB8fG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiS29ucXVlcm9yIik+PTApJiYhd2luZG93LmRoeDQuaXNFZGdlLHdpbmRvdy5kaHg0LmlzRkY9bmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJGaXJlZm94Iik+PTAsd2luZG93LmRoeDQuaXNJUGFkPW5hdmlnYXRvci51c2VyQWdlbnQuc2VhcmNoKC9pUGFkL2dpKT49MCx3aW5kb3cuZGh4NC5kbmQ9e2V2czp7fSxwX2VuOih3aW5kb3cuZGh4NC5pc0lFfHx3aW5kb3cuZGh4NC5pc0VkZ2UpJiYod2luZG93Lm5hdmlnYXRvci5wb2ludGVyRW5hYmxlZHx8d2luZG93Lm5hdmlnYXRvci5tc1BvaW50ZXJFbmFibGVkKSxfbVRvdWNoOmZ1bmN0aW9uKGUpe3JldHVybiB3aW5kb3cuZGh4NC5pc0lFMTAmJmUucG9pbnRlclR5cGU9PWUuTVNQT0lOVEVSX1RZUEVfTU9VU0V8fHdpbmRvdy5kaHg0LmlzSUUxMSYmIm1vdXNlIj09ZS5wb2ludGVyVHlwZXx8d2luZG93LmRoeDQuaXNFZGdlJiYibW91c2UiPT1lLnBvaW50ZXJUeXBlfSxfdG91Y2hPbjpmdW5jdGlvbihlKXtudWxsPT1lJiYoZT1kb2N1bWVudC5ib2R5KSxlLnN0eWxlLnRvdWNoQWN0aW9uPWUuc3R5bGUubXNUb3VjaEFjdGlvbj0iIixlPW51bGx9LF90b3VjaE9mZjpmdW5jdGlvbihlKXtudWxsPT1lJiYoZT1kb2N1bWVudC5ib2R5KSxlLnN0eWxlLnRvdWNoQWN0aW9uPWUuc3R5bGUubXNUb3VjaEFjdGlvbj0ibm9uZSIsZT1udWxsfX0sMT09d2luZG93Lm5hdmlnYXRvci5wb2ludGVyRW5hYmxlZD93aW5kb3cuZGh4NC5kbmQuZXZzPXtzdGFydDoicG9pbnRlcmRvd24iLG1vdmU6InBvaW50ZXJtb3ZlIixlbmQ6InBvaW50ZXJ1cCJ9OjE9PXdpbmRvdy5uYXZpZ2F0b3IubXNQb2ludGVyRW5hYmxlZD93aW5kb3cuZGh4NC5kbmQuZXZzPXtzdGFydDoiTVNQb2ludGVyRG93biIsbW92ZToiTVNQb2ludGVyTW92ZSIsZW5kOiJNU1BvaW50ZXJVcCJ9OiJ1bmRlZmluZWQiIT10eXBlb2Ygd2luZG93LmFkZEV2ZW50TGlzdGVuZXImJih3aW5kb3cuZGh4NC5kbmQuZXZzPXtzdGFydDoidG91Y2hzdGFydCIsbW92ZToidG91Y2htb3ZlIixlbmQ6InRvdWNoZW5kIn0pKSwidW5kZWZpbmVkIj09dHlwZW9mIHdpbmRvdy5kaHg0Ll9ldmVudGFibGUmJih3aW5kb3cuZGh4NC5fZXZlbnRhYmxlPWZ1bmN0aW9uKGUsdCl7cmV0dXJuImNsZWFyIj09dD8oZS5kZXRhY2hBbGxFdmVudHMoKSxlLmRoeGV2cz1udWxsLGUuYXR0YWNoRXZlbnQ9bnVsbCxlLmRldGFjaEV2ZW50PW51bGwsZS5jaGVja0V2ZW50PW51bGwsZS5jYWxsRXZlbnQ9bnVsbCxlLmRldGFjaEFsbEV2ZW50cz1udWxsLGU9bnVsbCx2b2lkIDApOihlLmRoeGV2cz17ZGF0YTp7fX0sZS5hdHRhY2hFdmVudD1mdW5jdGlvbihlLHQpe2U9U3RyaW5nKGUpLnRvTG93ZXJDYXNlKCksdGhpcy5kaHhldnMuZGF0YVtlXXx8KHRoaXMuZGh4ZXZzLmRhdGFbZV09e30pO3ZhciBpPXdpbmRvdy5kaHg0Lm5ld0lkKCk7cmV0dXJuIHRoaXMuZGh4ZXZzLmRhdGFbZV1baV09dCxpfSxlLmRldGFjaEV2ZW50PWZ1bmN0aW9uKGUpe2Zvcih2YXIgdCBpbiB0aGlzLmRoeGV2cy5kYXRhKXt2YXIgaT0wO2Zvcih2YXIgbiBpbiB0aGlzLmRoeGV2cy5kYXRhW3RdKW49PWU/KHRoaXMuZGh4ZXZzLmRhdGFbdF1bbl09bnVsbCxkZWxldGUgdGhpcy5kaHhldnMuZGF0YVt0XVtuXSk6aSsrOzA9PWkmJih0aGlzLmRoeGV2cy5kYXRhW3RdPW51bGwsZGVsZXRlIHRoaXMuZGh4ZXZzLmRhdGFbdF0pfX0sZS5jaGVja0V2ZW50PWZ1bmN0aW9uKGUpe3JldHVybiBlPVN0cmluZyhlKS50b0xvd2VyQ2FzZSgpLG51bGwhPXRoaXMuZGh4ZXZzLmRhdGFbZV19LGUuY2FsbEV2ZW50PWZ1bmN0aW9uKGUsdCl7aWYoZT1TdHJpbmcoZSkudG9Mb3dlckNhc2UoKSxudWxsPT10aGlzLmRoeGV2cy5kYXRhW2VdKXJldHVybiEwO3ZhciBpPSEwO2Zvcih2YXIgbiBpbiB0aGlzLmRoeGV2cy5kYXRhW2VdKWk9dGhpcy5kaHhldnMuZGF0YVtlXVtuXS5hcHBseSh0aGlzLHQpJiZpO3JldHVybiBpfSxlLmRldGFjaEFsbEV2ZW50cz1mdW5jdGlvbigpe2Zvcih2YXIgZSBpbiB0aGlzLmRoeGV2cy5kYXRhKXtmb3IodmFyIHQgaW4gdGhpcy5kaHhldnMuZGF0YVtlXSl0aGlzLmRoeGV2cy5kYXRhW2VdW3RdPW51bGwsZGVsZXRlIHRoaXMuZGh4ZXZzLmRhdGFbZV1bdF07dGhpcy5kaHhldnMuZGF0YVtlXT1udWxsLGRlbGV0ZSB0aGlzLmRoeGV2cy5kYXRhW2VdfX0sZT1udWxsLHZvaWQgMCl9LGRoeDQuX2V2ZW50YWJsZShkaHg0KSksInVuZGVmaW5lZCI9PXR5cGVvZiB3aW5kb3cuZGh0bWx4JiYod2luZG93LmRodG1seD17ZXh0ZW5kOmZ1bmN0aW9uKGUsdCl7Zm9yKHZhciBpIGluIHQpZVtpXXx8KGVbaV09dFtpXSk7cmV0dXJuIGV9LGV4dGVuZF9hcGk6ZnVuY3Rpb24oZSx0LGkpe3ZhciBuPXdpbmRvd1tlXTtuJiYod2luZG93W2VdPWZ1bmN0aW9uKGUpe2lmKGUmJiJvYmplY3QiPT10eXBlb2YgZSYmIWUudGFnTmFtZSl7dmFyIGk9bi5hcHBseSh0aGlzLHQuX2luaXQ/dC5faW5pdChlKTphcmd1bWVudHMpO2Zvcih2YXIgbyBpbiBkaHRtbHgpdFtvXSYmdGhpc1t0W29dXShkaHRtbHhbb10pO2Zvcih2YXIgbyBpbiBlKXRbb10/dGhpc1t0W29dXShlW29dKTowPT09by5pbmRleE9mKCJvbiIpJiZ0aGlzLmF0dGFjaEV2ZW50KG8sZVtvXSl9ZWxzZSB2YXIgaT1uLmFwcGx5KHRoaXMsYXJndW1lbnRzKTtyZXR1cm4gdC5fcGF0Y2gmJnQuX3BhdGNoKHRoaXMpLGl8fHRoaXN9LHdpbmRvd1tlXS5wcm90b3R5cGU9bi5wcm90b3R5cGUsaSYmZGh0bWx4LmV4dGVuZCh3aW5kb3dbZV0ucHJvdG90eXBlLGkpKX0sdXJsOmZ1bmN0aW9uKGUpe3JldHVybi0xIT1lLmluZGV4T2YoIj8iKT8iJiI6Ij8ifX0pLF9pc0ZGPSExLF9pc0lFPSExLF9pc09wZXJhPSExLF9pc0tIVE1MPSExLF9pc01hY09TPSExLF9pc0Nocm9tZT0hMSxfRkZydj0hMSxfS0hUTUxydj0hMSxfT3BlcmFSdj0hMSwtMSE9bmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJNYWNpbnRvc2giKSYmKF9pc01hY09TPSEwKSxuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkuaW5kZXhPZigiY2hyb21lIik+LTEmJihfaXNDaHJvbWU9ITApLC0xIT1uYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoIlNhZmFyaSIpfHwtMSE9bmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJLb25xdWVyb3IiKT8oX0tIVE1McnY9cGFyc2VGbG9hdChuYXZpZ2F0b3IudXNlckFnZW50LnN1YnN0cihuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoIlNhZmFyaSIpKzcsNSkpLF9LSFRNTHJ2PjUyNT8oX2lzRkY9ITAsX0ZGcnY9MS45KTpfaXNLSFRNTD0hMCk6LTEhPW5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiT3BlcmEiKT8oX2lzT3BlcmE9ITAsX09wZXJhUnY9cGFyc2VGbG9hdChuYXZpZ2F0b3IudXNlckFnZW50LnN1YnN0cihuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoIk9wZXJhIikrNiwzKSkpOi0xIT1uYXZpZ2F0b3IuYXBwTmFtZS5pbmRleE9mKCJNaWNyb3NvZnQiKT8oX2lzSUU9ITAsKC0xIT1uYXZpZ2F0b3IuYXBwVmVyc2lvbi5pbmRleE9mKCJNU0lFIDguMCIpfHwtMSE9bmF2aWdhdG9yLmFwcFZlcnNpb24uaW5kZXhPZigiTVNJRSA5LjAiKXx8LTEhPW5hdmlnYXRvci5hcHBWZXJzaW9uLmluZGV4T2YoIk1TSUUgMTAuMCIpfHxkb2N1bWVudC5kb2N1bWVudE1vZGU+NykmJiJCYWNrQ29tcGF0IiE9ZG9jdW1lbnQuY29tcGF0TW9kZSYmKF9pc0lFPTgpKToiTmV0c2NhcGUiPT1uYXZpZ2F0b3IuYXBwTmFtZSYmLTEhPW5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiVHJpZGVudCIpP19pc0lFPTg6KF9pc0ZGPSEwLF9GRnJ2PXBhcnNlRmxvYXQobmF2aWdhdG9yLnVzZXJBZ2VudC5zcGxpdCgicnY6IilbMV0pKSwidW5kZWZpbmVkIj09dHlwZW9mIHdpbmRvdy5kaHRtbHhFdmVudCxudWxsPT1kaHRtbHhFdmVudC50b3VjaERlbGF5JiYoZGh0bWx4RXZlbnQudG91Y2hEZWxheT0yZTMpLCJ1bmRlZmluZWQiPT10eXBlb2YgZGh0bWx4RXZlbnQuaW5pdFRvdWNoJiYoZGh0bWx4RXZlbnQuaW5pdFRvdWNoPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gZSgpe2lmKGkpe3ZhciBlPWRvY3VtZW50LmNyZWF0ZUV2ZW50KCJIVE1MRXZlbnRzIik7ZS5pbml0RXZlbnQoImRibGNsaWNrIiwhMCwhMCksaS5kaXNwYXRjaEV2ZW50KGUpLHQ9aT1udWxsfX12YXIgdCxpLG4sbztkaHRtbHhFdmVudChkb2N1bWVudC5ib2R5LCJ0b3VjaHN0YXJ0IixmdW5jdGlvbihyKXtpPXIudG91Y2hlc1swXS50YXJnZXQsbj1yLnRvdWNoZXNbMF0uY2xpZW50WCxvPXIudG91Y2hlc1swXS5jbGllbnRZLHQ9d2luZG93LnNldFRpbWVvdXQoZSxkaHRtbHhFdmVudC50b3VjaERlbGF5KX0pLGRodG1seEV2ZW50KGRvY3VtZW50LmJvZHksInRvdWNobW92ZSIsZnVuY3Rpb24oZSl7dCYmKE1hdGguYWJzKGUudG91Y2hlc1swXS5jbGllbnRYLW4pPjUwfHxNYXRoLmFicyhlLnRvdWNoZXNbMF0uY2xpZW50WS1vKT41MCkmJih3aW5kb3cuY2xlYXJUaW1lb3V0KHQpLHQ9aT0hMSl9KSxkaHRtbHhFdmVudChkb2N1bWVudC5ib2R5LCJ0b3VjaGVuZCIsZnVuY3Rpb24oKXt0JiYod2luZG93LmNsZWFyVGltZW91dCh0KSx0PWk9ITEpfSksZGh0bWx4RXZlbnQuaW5pdFRvdWNoPWZ1bmN0aW9uKCl7fX0pLGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl9kb0NvbnRDbGljaz1mdW5jdGlvbihlLHQpe2lmKCF0JiYyIT1lLmJ1dHRvbilyZXR1cm4gdGhpcy5fYWNNZW51JiYodGhpcy5fYWNNZW51LmhpZGVDb250ZXh0TWVudT90aGlzLl9hY01lbnUuaGlkZUNvbnRleHRNZW51KCk6dGhpcy5jTWVudS5fY29udGV4dEVuZCgpKSwhMDtmb3IodmFyIGk9X2lzSUU/ZS5zcmNFbGVtZW50OmUudGFyZ2V0O2kmJiJCT0RZIiE9aS50YWdOYW1lJiYhaS5wYXJlbnRPYmplY3Q7KWk9aS5wYXJlbnROb2RlO2lmKCFpfHwhaS5wYXJlbnRPYmplY3QpcmV0dXJuITA7dmFyIG49aS5wYXJlbnRPYmplY3Q7aWYodGhpcy5jYWxsRXZlbnQoIm9uUmlnaHRDbGljayIsW24uaWQsZV0pfHwoKGUuc3JjRWxlbWVudHx8ZS50YXJnZXQpLm9uY29udGV4dG1lbnU9ZnVuY3Rpb24oZSl7cmV0dXJuKGV8fGV2ZW50KS5jYW5jZWxCdWJibGU9ITAsITF9KSx0aGlzLl9hY01lbnU9bi5jTWVudXx8dGhpcy5jTWVudSx0aGlzLl9hY01lbnUpe2lmKCF0aGlzLmNhbGxFdmVudCgib25CZWZvcmVDb250ZXh0TWVudSIsW24uaWRdKSlyZXR1cm4hMDtpZihfaXNNYWNPU3x8KChlLnNyY0VsZW1lbnR8fGUudGFyZ2V0KS5vbmNvbnRleHRtZW51PWZ1bmN0aW9uKGUpe3JldHVybihlfHxldmVudCkuY2FuY2VsQnViYmxlPSEwLCExfSksdGhpcy5fYWNNZW51LnNob3dDb250ZXh0TWVudSl7dmFyIG89d2luZG93LmRvY3VtZW50LmRvY3VtZW50RWxlbWVudCxyPXdpbmRvdy5kb2N1bWVudC5ib2R5LGw9bmV3IEFycmF5KG8uc2Nyb2xsTGVmdHx8ci5zY3JvbGxMZWZ0LG8uc2Nyb2xsVG9wfHxyLnNjcm9sbFRvcCk7aWYoX2lzSUUpdmFyIHM9ZS5jbGllbnRYK2xbMF0sYT1lLmNsaWVudFkrbFsxXTtlbHNlIHZhciBzPWUucGFnZVgsYT1lLnBhZ2VZO3RoaXMuX2FjTWVudS5zaG93Q29udGV4dE1lbnUocy0xLGEtMSksdGhpcy5jb250ZXh0SUQ9bi5pZCxlLmNhbmNlbEJ1YmJsZT0hMCx0aGlzLl9hY01lbnUuX3NraXBfaGlkZT0hMH1lbHNlIGkuY29udGV4dE1lbnVJZD1uLmlkLGkuY29udGV4dE1lbnU9dGhpcy5fYWNNZW51LGkuYT10aGlzLl9hY01lbnUuX2NvbnRleHRTdGFydCxpLmEoaSxlKSxpLmE9bnVsbDtyZXR1cm4hMX1yZXR1cm4hMH0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuZW5hYmxlSUVJbWFnZUZpeD1mdW5jdGlvbihlKXtlPyh0aGlzLl9nZXRJbWc9ZnVuY3Rpb24oKXt2YXIgZT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJESVYiKTtyZXR1cm4gZS5pbm5lckhUTUw9IiZuYnNwOyIsZS5jbGFzc05hbWU9ImRoeF9iZ19pbWdfZml4IixlfSx0aGlzLl9zZXRTcmM9ZnVuY3Rpb24oZSx0KXtlLnN0eWxlLmJhY2tncm91bmRJbWFnZT0idXJsKCIrdCsiKSJ9LHRoaXMuX2dldFNyYz1mdW5jdGlvbihlKXt2YXIgdD1lLnN0eWxlLmJhY2tncm91bmRJbWFnZTtyZXR1cm4gdC5zdWJzdHIoNCx0Lmxlbmd0aC01KS5yZXBsYWNlKC8oXiIpfCgiJCkvZywiIil9KToodGhpcy5fZ2V0SW1nPWZ1bmN0aW9uKGUpe3JldHVybiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGU9PXRoaXMucm9vdElkPyJkaXYiOiJpbWciKX0sdGhpcy5fc2V0U3JjPWZ1bmN0aW9uKGUsdCl7ZS5zcmM9dH0sdGhpcy5fZ2V0U3JjPWZ1bmN0aW9uKGUpe3JldHVybiBlLnNyY30pfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5kZXN0cnVjdG9yPWZ1bmN0aW9uKCl7Zm9yKHZhciBlIGluIHRoaXMuX2lkcHVsbCl7dmFyIHQ9dGhpcy5faWRwdWxsW2VdO3QmJih0LnBhcmVudE9iamVjdD1udWxsLHQudHJlZU5vZD1udWxsLHQuY2hpbGROb2Rlcz1udWxsLHQuc3Bhbj1udWxsLHQudHIubm9kZW09bnVsbCx0LnRyPW51bGwsdC5odG1sTm9kZS5vYmpCZWxvbmc9bnVsbCx0Lmh0bWxOb2RlPW51bGwsdGhpcy5faWRwdWxsW2VdPW51bGwpfXRoaXMucGFyZW50T2JqZWN0LmlubmVySFRNTD0iIix0aGlzLmFsbFRyZWUub25zZWxlY3RzdGFydD1udWxsLHRoaXMuYWxsVHJlZS5vbmNvbnRleHRtZW51PW51bGwsdGhpcy5hbGxUcmVlLm9ubW91c2Vkb3duPW51bGw7Zm9yKHZhciBlIGluIHRoaXMpdGhpc1tlXT1udWxsfSxjT2JqZWN0LnByb3RvdHlwZT1uZXcgT2JqZWN0LGNPYmplY3QucHJvdG90eXBlLmNsb25lPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gZSgpe31yZXR1cm4gZS5wcm90b3R5cGU9dGhpcyxuZXcgZX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX2dsb2JhbElkU3RvcmFnZUFkZD1mdW5jdGlvbihlLHQpe3JldHVybiB0aGlzLl9nbG9iYWxJZFN0b3JhZ2VGaW5kKGUsMSwxKT8oZT1lKyJfIisobmV3IERhdGUpLnZhbHVlT2YoKSx0aGlzLl9nbG9iYWxJZFN0b3JhZ2VBZGQoZSx0KSk6KHRoaXMuX2lkcHVsbFtlXT10LHRoaXMuX3B1bGxTaXplKyssZSl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl9nbG9iYWxJZFN0b3JhZ2VTdWI9ZnVuY3Rpb24oZSl7dGhpcy5faWRwdWxsW2VdJiYodGhpcy5fdW5zZWxlY3RJdGVtKHRoaXMuX2lkcHVsbFtlXSksdGhpcy5faWRwdWxsW2VdPW51bGwsdGhpcy5fcHVsbFNpemUtLSksdGhpcy5fbG9ja2VyJiZ0aGlzLl9sb2NrZXJbZV0mJih0aGlzLl9sb2NrZXJbZV09ITEpfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5fZ2xvYmFsSWRTdG9yYWdlRmluZD1mdW5jdGlvbihlLHQsaSxuKXt2YXIgbz10aGlzLl9pZHB1bGxbZV07aWYobyl7aWYoby51blBhcnNlZCYmIWkmJnRoaXMucmVQYXJzZShvLDApLHRoaXMuX3NybmQmJiFvLmh0bWxOb2RlJiZ0aGlzLl9idWlsZFNSTkQobyxpKSxuJiZ0aGlzLl9lZHNicHNBKWZvcih2YXIgcj0wO3I8dGhpcy5fZWRzYnBzQS5sZW5ndGg7cisrKWlmKHRoaXMuX2Vkc2Jwc0Fbcl1bMl09PWUpcmV0dXJuIGRoeDQuY2FsbEV2ZW50KCJvbmdldEl0ZW1FcnJvciIsWyJSZXF1ZXN0ZWQgaXRlbSBzdGlsbCBpbiBwYXJzaW5nIHByb2Nlc3MuIixlXSksbnVsbDtyZXR1cm4gb31yZXR1cm4gdGhpcy5zbG93UGFyc2UmJjAhPWUmJiF0P3RoaXMucHJlUGFyc2UoZSk6bnVsbH0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX2RyYXdOZXdUcj1mdW5jdGlvbihlKXt2YXIgdD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJ0ciIpLGk9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGQiKSxuPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInRkIik7cmV0dXJuIGkuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoIiAiKSksbi5jb2xTcGFuPTMsbi5hcHBlbmRDaGlsZChlKSx0LmFwcGVuZENoaWxkKGkpLHQuYXBwZW5kQ2hpbGQobiksdH0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUucGFyc2U9ZnVuY3Rpb24oZSx0LGkpe2lmKCJzdHJpbmciPT10eXBlb2YgdCYmKGk9dCx0PW51bGwpLCJqc29uIj09PWkpcmV0dXJuIHRoaXMuX2xvYWRKU09OT2JqZWN0KGUsdCk7aWYoImNzdiI9PT1pKXJldHVybiB0aGlzLl9sb2FkQ1NWU3RyaW5nKGUsdCk7aWYoImpzYXJyYXkiPT09aSlyZXR1cm4gdGhpcy5fbG9hZEpTQXJyYXkoZSx0KTt2YXIgbj10aGlzO3RoaXMucGFyc0NvdW50fHx0aGlzLmNhbGxFdmVudCgib25YTFMiLFtuLG51bGxdKSx0aGlzLnhtbHN0YXRlPTEsdGhpcy5YTUxMb2FkZXIoe3Jlc3BvbnNlWE1MOmRoeDQuYWpheC5wYXJzZShlKX0sdCl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl9hdHRhY2hDaGlsZE5vZGU9ZnVuY3Rpb24oZSx0LGksbixvLHIsbCxzLGEsZCxoKXtkJiZkLnBhcmVudE9iamVjdCYmKGU9ZC5wYXJlbnRPYmplY3QpLDA9PWUuWE1MbG9hZCYmdGhpcy5YTUxzb3VyY2UmJiF0aGlzLlhNTGxvYWRpbmdXYXJuaW5nJiYoZS5YTUxsb2FkPTEsdGhpcy5fbG9hZER5blhNTChlLmlkKSk7dmFyIGM9ZS5jaGlsZHNDb3VudCx1PWUuY2hpbGROb2RlcztpZihoJiZoLnRyLnByZXZpb3VzU2libGluZyYmKGgudHIucHJldmlvdXNTaWJsaW5nLnByZXZpb3VzU2libGluZz9kPWgudHIucHJldmlvdXNTaWJsaW5nLm5vZGVtOnM9cy5yZXBsYWNlKCJUT1AiLCIiKSsiLFRPUCIpLGQpe3ZhciBwLF87Zm9yKHA9MDtjPnA7cCsrKWlmKHVbcF09PWQpe2ZvcihfPWM7XyE9cDtfLS0pdVsxK19dPXVbX107YnJlYWt9cCsrLGM9cH1pZihzKWZvcih2YXIgbT1zLnNwbGl0KCIsIiksZz0wO2c8bS5sZW5ndGg7ZysrKXN3aXRjaChtW2ddKXtjYXNlIlRPUCI6Zm9yKGUuY2hpbGRzQ291bnQ+MCYmKGQ9bmV3IE9iamVjdCxkLnRyPWUuY2hpbGROb2Rlc1swXS50ci5wcmV2aW91c1NpYmxpbmcpLGUuX2hhc190b3A9ITAscD1jO3A+MDtwLS0pdVtwXT11W3AtMV07Yz0wfXZhciBmOyhmPXRoaXMuX2lkcHVsbFt0XSkmJi0xPT1mLnNwYW58fChmPXVbY109bmV3IGRodG1sWFRyZWVJdGVtT2JqZWN0KHQsaSxlLHRoaXMsbiwxKSx0PXVbY10uaWQsZS5jaGlsZHNDb3VudCsrKSxmLmh0bWxOb2RlfHwoZi5sYWJlbD1pLGYuaHRtbE5vZGU9dGhpcy5fY3JlYXRlSXRlbSh0aGlzLmNoZWNrQm94T2ZmPzE6MCxmKSxmLmh0bWxOb2RlLm9iakJlbG9uZz1mKSxvJiYoZi5pbWFnZXNbMF09byksciYmKGYuaW1hZ2VzWzFdPXIpLGwmJihmLmltYWdlc1syXT1sKTt2YXIgYj10aGlzLl9kcmF3TmV3VHIoZi5odG1sTm9kZSk7aWYoKHRoaXMuWE1MbG9hZGluZ1dhcm5pbmd8fHRoaXMuX2hBZEkpJiYoZi5odG1sTm9kZS5wYXJlbnROb2RlLnBhcmVudE5vZGUuc3R5bGUuZGlzcGxheT0ibm9uZSIpLGQmJmQudHImJmQudHIubmV4dFNpYmxpbmc/ZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmluc2VydEJlZm9yZShiLGQudHIubmV4dFNpYmxpbmcpOnRoaXMucGFyc2luZ09uPT1lLmlkP3RoaXMucGFyc2VkQXJyYXlbdGhpcy5wYXJzZWRBcnJheS5sZW5ndGhdPWI6ZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmFwcGVuZENoaWxkKGIpLGQmJiFkLnNwYW4mJihkPW51bGwpLHRoaXMuWE1Mc291cmNlJiYoZi5YTUxsb2FkPWEmJjAhPWE/MDoxKSxmLnRyPWIsYi5ub2RlbT1mLDA9PWUuaXRlbUlkJiYoYi5jaGlsZE5vZGVzWzBdLmNsYXNzTmFtZT0iaGlkZGVuUm93IiksKGUuX3JfbG9naWN8fHRoaXMuX2ZyYnRyKSYmdGhpcy5fc2V0U3JjKGYuaHRtbE5vZGUuY2hpbGROb2Rlc1swXS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXNbMV0uY2hpbGROb2Rlc1swXSx0aGlzLmltUGF0aCt0aGlzLnJhZGlvQXJyYXlbMF0pLHMpZm9yKHZhciBtPXMuc3BsaXQoIiwiKSxnPTA7ZzxtLmxlbmd0aDtnKyspc3dpdGNoKG1bZ10pe2Nhc2UiU0VMRUNUIjp0aGlzLnNlbGVjdEl0ZW0odCwhMSk7YnJlYWs7Y2FzZSJDQUxMIjp0aGlzLnNlbGVjdEl0ZW0odCwhMCk7YnJlYWs7Y2FzZSJDSElMRCI6Zi5YTUxsb2FkPTA7YnJlYWs7Y2FzZSJDSEVDS0VEIjp0aGlzLlhNTGxvYWRpbmdXYXJuaW5nP3RoaXMuc2V0Q2hlY2tMaXN0Kz10aGlzLmRsbXRyK3Q6dGhpcy5zZXRDaGVjayh0LDEpO2JyZWFrO2Nhc2UiSENIRUNLRUQiOnRoaXMuX3NldENoZWNrKGYsInVuc3VyZSIpO2JyZWFrO2Nhc2UiT1BFTiI6Zi5vcGVuTWU9MX1pZighdGhpcy5YTUxsb2FkaW5nV2FybmluZyYmKHRoaXMuX2dldE9wZW5TdGF0ZShlKTwwJiYhdGhpcy5faEFkSSYmdGhpcy5vcGVuSXRlbShlLmlkKSxkJiYodGhpcy5fY29ycmVjdFBsdXMoZCksdGhpcy5fY29ycmVjdExpbmUoZCkpLHRoaXMuX2NvcnJlY3RQbHVzKGUpLHRoaXMuX2NvcnJlY3RMaW5lKGUpLHRoaXMuX2NvcnJlY3RQbHVzKGYpLGUuY2hpbGRzQ291bnQ+PTImJih0aGlzLl9jb3JyZWN0UGx1cyh1W2UuY2hpbGRzQ291bnQtMl0pLHRoaXMuX2NvcnJlY3RMaW5lKHVbZS5jaGlsZHNDb3VudC0yXSkpLDIhPWUuY2hpbGRzQ291bnQmJnRoaXMuX2NvcnJlY3RQbHVzKHVbMF0pLHRoaXMudHNjaGVjayYmdGhpcy5fY29ycmVjdENoZWNrU3RhdGVzKGUpLHRoaXMuX29ucmFkaCkpaWYoMT09dGhpcy54bWxzdGF0ZSl7dmFyIHY9dGhpcy5vblhMRTt0aGlzLm9uWExFPWZ1bmN0aW9uKGUpe3RoaXMuX29ucmFkaCh0KSx2JiZ2KGUpfX1lbHNlIHRoaXMuX29ucmFkaCh0KTtyZXR1cm4gZn0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX3BhcnNlSXRlbT1mdW5jdGlvbihlLHQsaSxuKXt2YXIgbztpZih0aGlzLl9zcm5kJiYoIXRoaXMuX2lkcHVsbFtvPWUuZ2V0KCJpZCIpXXx8IXRoaXMuX2lkcHVsbFtvXS5zcGFuKSlyZXR1cm4gdGhpcy5fYWRkSXRlbVNSTkQodC5pZCxvLGUpLHZvaWQgMDt2YXIgcj1lLmdldF9hbGwoKTtpZigib2JqZWN0Ij09dHlwZW9mIHRoaXMud2FpdFVwZGF0ZVhNTCYmIXRoaXMud2FpdFVwZGF0ZVhNTFtyLmlkXSlyZXR1cm4gdGhpcy5fcGFyc2UoZSxyLmlkLDEpLHZvaWQgMDsobnVsbD09PXIudGV4dHx8InVuZGVmaW5lZCI9PXR5cGVvZiByLnRleHQpJiYoci50ZXh0PWUuc3ViKCJpdGVtdGV4dCIpLHIudGV4dCYmKHIudGV4dD1yLnRleHQuY29udGVudCgpKSk7dmFyIGw9W107aWYoci5zZWxlY3QmJmwucHVzaCgiU0VMRUNUIiksci50b3AmJmwucHVzaCgiVE9QIiksci5jYWxsJiYodGhpcy5ub2RlQXNraW5nQ2FsbD1yLmlkKSwtMT09ci5jaGVja2VkP2wucHVzaCgiSENIRUNLRUQiKTpyLmNoZWNrZWQmJmwucHVzaCgiQ0hFQ0tFRCIpLHIub3BlbiYmbC5wdXNoKCJPUEVOIiksdGhpcy53YWl0VXBkYXRlWE1MKWlmKHRoaXMuX2dsb2JhbElkU3RvcmFnZUZpbmQoci5pZCkpdmFyIHM9dGhpcy51cGRhdGVJdGVtKHIuaWQsci50ZXh0LHIuaW0wLHIuaW0xLHIuaW0yLHIuY2hlY2tlZCxyLmNoaWxkKTtlbHNlezA9PXRoaXMubnBsP2wucHVzaCgiVE9QIik6aT10LmNoaWxkTm9kZXNbdGhpcy5ucGxdO3ZhciBzPXRoaXMuX2F0dGFjaENoaWxkTm9kZSh0LHIuaWQsci50ZXh0LDAsci5pbTAsci5pbTEsci5pbTIsbC5qb2luKCIsIiksci5jaGlsZCwwLGkpO3IuaWQ9cy5pZCxpPW51bGx9ZWxzZSB2YXIgcz10aGlzLl9hdHRhY2hDaGlsZE5vZGUodCxyLmlkLHIudGV4dCwwLHIuaW0wLHIuaW0xLHIuaW0yLGwuam9pbigiLCIpLHIuY2hpbGQsbnx8MCxpKTtpZihyLnRvb2x0aXAmJihzLnNwYW4ucGFyZW50Tm9kZS5wYXJlbnROb2RlLnRpdGxlPXIudG9vbHRpcCksci5zdHlsZSYmKHMuc3Bhbi5zdHlsZS5jc3NUZXh0P3Muc3Bhbi5zdHlsZS5jc3NUZXh0Kz0iOyIrci5zdHlsZTpzLnNwYW4uc2V0QXR0cmlidXRlKCJzdHlsZSIscy5zcGFuLmdldEF0dHJpYnV0ZSgic3R5bGUiKSsiOyAiK3Iuc3R5bGUpKSxyLnJhZGlvJiYocy5fcl9sb2dpYz0hMCksci5ub2NoZWNrYm94KXt2YXIgYT1zLnNwYW4ucGFyZW50Tm9kZS5wcmV2aW91c1NpYmxpbmcucHJldmlvdXNTaWJsaW5nO2Euc3R5bGUuZGlzcGxheT0ibm9uZSIscy5ub2NoZWNrYm94PSEwfXIuZGlzYWJsZWQmJihudWxsIT1yLmNoZWNrZWQmJnRoaXMuX3NldENoZWNrKHMsci5jaGVja2VkKSx0aGlzLmRpc2FibGVDaGVja2JveChzLDEpKSxzLl9hY2M9ci5jaGlsZHx8MCx0aGlzLnBhcnNlckV4dGVuc2lvbiYmdGhpcy5wYXJzZXJFeHRlbnNpb24uX3BhcnNlRXh0ZW5zaW9uLmNhbGwodGhpcyxlLHIsdD90LmlkOjApLHRoaXMuc2V0SXRlbUNvbG9yKHMsci5hQ29sLHIuc0NvbCksIjEiPT1yLmxvY2tlZCYmdGhpcy5sb2NrSXRlbShzLmlkLCEwLCEwKSwoci5pbXdpZHRofHxyLmltaGVpZ2h0KSYmdGhpcy5zZXRJY29uU2l6ZShyLmltd2lkdGgsci5pbWhlaWdodCxzKSwoIjAiPT1yLmNsb3NlYWJsZXx8IjEiPT1yLmNsb3NlYWJsZSkmJnRoaXMuc2V0SXRlbUNsb3NlYWJsZShzLHIuY2xvc2VhYmxlKTt2YXIgZD0iIjtyLnRvcG9mZnNldCYmdGhpcy5zZXRJdGVtVG9wT2Zmc2V0KHMsci50b3BvZmZzZXQpLHRoaXMuc2xvd1BhcnNlJiYib2JqZWN0IiE9dHlwZW9mIHRoaXMud2FpdFVwZGF0ZVhNTD8oIXMuY2hpbGRzQ291bnQmJmUuc3ViX2V4aXN0cygiaXRlbSIpJiYocy51blBhcnNlZD1lLmNsb25lKCkpLGUuZWFjaCgidXNlcmRhdGEiLGZ1bmN0aW9uKGUpe3RoaXMuc2V0VXNlckRhdGEoci5pZCxlLmdldCgibmFtZSIpLGUuY29udGVudCgpKX0sdGhpcykpOmUuc3ViX2V4aXN0cygiaXRlbSIpJiYoZD10aGlzLl9wYXJzZShlLHIuaWQsMSkpLCIiIT1kJiYodGhpcy5ub2RlQXNraW5nQ2FsbD1kKSxlLmVhY2goInVzZXJkYXRhIixmdW5jdGlvbih0KXt0aGlzLnNldFVzZXJEYXRhKGUuZ2V0KCJpZCIpLHQuZ2V0KCJuYW1lIiksdC5jb250ZW50KCkpfSx0aGlzKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX3BhcnNlPWZ1bmN0aW9uKGUsdCxpLG4pe2lmKHRoaXMuX3NybmQmJiF0aGlzLnBhcmVudE9iamVjdC5vZmZzZXRIZWlnaHQpe3ZhciBvPXRoaXM7cmV0dXJuIHdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7by5fcGFyc2UoZSx0LGksbil9LDEwMCl9aWYoZS5leGlzdHMoKSl7aWYodGhpcy5za2lwTG9jaz0hMCwhdCl7dD1lLmdldCgiaWQiKSx0aGlzLl9keW5EZWxldGVCcmFuY2hlc1t0XSYmKHRoaXMuZGVsZXRlQ2hpbGRJdGVtcyh0KSx0aGlzLl9keW5EZWxldGVCcmFuY2hlc1t0XS0tLHRoaXMuX2R5bkRlbGV0ZUJyYW5jaGVzW3RdfHxkZWxldGUgdGhpcy5fZHluRGVsZXRlQnJhbmNoZXNbdF0pO3ZhciByPWUuZ2V0KCJkaHhfc2VjdXJpdHkiKTtyJiYoZGh0bWx4LnNlY3VyaXR5X2tleT1yKSxlLmdldCgicmFkaW8iKSYmKHRoaXMuaHRtbE5vZGUuX3JfbG9naWM9ITApLHRoaXMucGFyc2luZ09uPXQsdGhpcy5wYXJzZWRBcnJheT1uZXcgQXJyYXksdGhpcy5zZXRDaGVja0xpc3Q9IiIsdGhpcy5ub2RlQXNraW5nQ2FsbD0iIn12YXIgbD10aGlzLl9nbG9iYWxJZFN0b3JhZ2VGaW5kKHQpO2lmKCFsKXJldHVybiBkaHg0LmNhbGxFdmVudCgib25EYXRhU3RydWN0dXJlRXJyb3IiLFsiWE1MIHJlZmVycyB0byBub3QgZXhpc3RpbmcgcGFyZW50Il0pO2lmKHRoaXMucGFyc0NvdW50PXRoaXMucGFyc0NvdW50P3RoaXMucGFyc0NvdW50KzE6MSx0aGlzLlhNTGxvYWRpbmdXYXJuaW5nPTEsIWwuY2hpbGRzQ291bnR8fG58fHRoaXMuX2Vkc2Jwc3x8bC5faGFzX3RvcCl2YXIgcz0wO2Vsc2UgdmFyIHM9MDtpZih0aGlzLm5wbD0wLGUuZWFjaCgiaXRlbSIsZnVuY3Rpb24obixvKXtyZXR1cm4gbC5YTUxsb2FkPTEsdGhpcy5fcGFyc2VJdGVtKG4sbCwwLHMpLHRoaXMuX2Vkc2JwcyYmdGhpcy5ucGw9PXRoaXMuX2Vkc2Jwc0M/KHRoaXMuX2Rpc3RyaWJ1dGVkU3RhcnQoZSxvKzEsdCxpLGwuY2hpbGRzQ291bnQpLC0xKToodGhpcy5ucGwrKyx2b2lkIDApfSx0aGlzLG4pLCFpKXtpZihlLmVhY2goInVzZXJkYXRhIixmdW5jdGlvbih0KXt0aGlzLnNldFVzZXJEYXRhKGUuZ2V0KCJpZCIpLHQuZ2V0KCJuYW1lIiksdC5jb250ZW50KCkpfSx0aGlzKSxsLlhNTGxvYWQ9MSx0aGlzLndhaXRVcGRhdGVYTUwpe3RoaXMud2FpdFVwZGF0ZVhNTD0hMTtmb3IodmFyIGE9bC5jaGlsZHNDb3VudC0xO2E+PTA7YS0tKWwuY2hpbGROb2Rlc1thXS5fZG1hcmsmJnRoaXMuZGVsZXRlSXRlbShsLmNoaWxkTm9kZXNbYV0uaWQpfWZvcih2YXIgYT0odGhpcy5fZ2xvYmFsSWRTdG9yYWdlRmluZCh0aGlzLnBhcnNpbmdPbiksMCk7YTx0aGlzLnBhcnNlZEFycmF5Lmxlbmd0aDthKyspbC5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmFwcGVuZENoaWxkKHRoaXMucGFyc2VkQXJyYXlbYV0pO3RoaXMucGFyc2VkQXJyYXk9W10sdGhpcy5sYXN0TG9hZGVkWE1MSWQ9dCx0aGlzLlhNTGxvYWRpbmdXYXJuaW5nPTA7Zm9yKHZhciBkPXRoaXMuc2V0Q2hlY2tMaXN0LnNwbGl0KHRoaXMuZGxtdHIpLGg9MDtoPGQubGVuZ3RoO2grKylkW2hdJiZ0aGlzLnNldENoZWNrKGRbaF0sMSk7dGhpcy5YTUxzb3VyY2UmJnRoaXMudHNjaGVjayYmdGhpcy5zbWNoZWNrJiZsLmlkIT10aGlzLnJvb3RJZCYmKDA9PT1sLmNoZWNrc3RhdGU/dGhpcy5fc2V0U3ViQ2hlY2tlZCgwLGwpOjE9PT1sLmNoZWNrc3RhdGUmJnRoaXMuX3NldFN1YkNoZWNrZWQoMSxsKSksdGhpcy5fcmVkcmF3RnJvbSh0aGlzLG51bGwsbiksZS5nZXQoIm9yZGVyIikmJiJub25lIiE9ZS5nZXQoIm9yZGVyIikmJnRoaXMuX3Jlb3JkZXJCcmFuY2gobCxlLmdldCgib3JkZXIiKSwhMCksIiIhPXRoaXMubm9kZUFza2luZ0NhbGwmJnRoaXMuY2FsbEV2ZW50KCJvbkNsaWNrIixbdGhpcy5ub2RlQXNraW5nQ2FsbCx0aGlzLmdldFNlbGVjdGVkSXRlbUlkKCldKSx0aGlzLl9icmFuY2hVcGRhdGUmJnRoaXMuX2JyYW5jaFVwZGF0ZU5leHQoZSl9aWYoMT09dGhpcy5wYXJzQ291bnQpe2lmKHRoaXMucGFyc2luZ09uPW51bGwsdGhpcy5fc3JuZCYmbC5pZCE9dGhpcy5yb290SWQmJih0aGlzLnByZXBhcmVTUihsLmlkKSx0aGlzLlhNTHNvdXJjZSYmdGhpcy5vcGVuSXRlbShsLmlkKSksZS50aHJvdWdoKCJpdGVtIiwib3BlbiIsbnVsbCxmdW5jdGlvbihlKXt0aGlzLm9wZW5JdGVtKGUuZ2V0KCJpZCIpKX0sdGhpcyksIXRoaXMuX2Vkc2Jwc3x8IXRoaXMuX2Vkc2Jwc0EubGVuZ3RoKXt2YXIgYz10aGlzO3dpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7Yy5jYWxsRXZlbnQoIm9uWExFIixbYyx0XSl9LDEpLHRoaXMueG1sc3RhdGU9MH10aGlzLnNraXBMb2NrPSExfXRoaXMucGFyc0NvdW50LS07dmFyIGM9dGhpcztyZXR1cm4gdGhpcy5fZWRzYnBzJiZ3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbigpe2MuX2Rpc3RyaWJ1dGVkU3RlcCh0KX0sdGhpcy5fZWRzYnBzRCksIWkmJnRoaXMub25YTEUmJnRoaXMub25YTEUodGhpcyx0KSx0aGlzLm5vZGVBc2tpbmdDYWxsfX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX3JlZHJhd0Zyb209ZnVuY3Rpb24oZSx0LGksbil7aWYodClvPXQ7ZWxzZXt2YXIgbz1lLl9nbG9iYWxJZFN0b3JhZ2VGaW5kKGUubGFzdExvYWRlZFhNTElkKTtpZihlLmxhc3RMb2FkZWRYTUxJZD0tMSwhbylyZXR1cm4gMH1mb3IodmFyIHI9MCxsPWk/aS0xOjA7bDxvLmNoaWxkc0NvdW50O2wrKylpZih0aGlzLl9icmFuY2hVcGRhdGUmJjEhPXRoaXMuX2dldE9wZW5TdGF0ZShvKXx8dCYmMSE9bnx8KG8uY2hpbGROb2Rlc1tsXS5odG1sTm9kZS5wYXJlbnROb2RlLnBhcmVudE5vZGUuc3R5bGUuZGlzcGxheT0iIiksMT09by5jaGlsZE5vZGVzW2xdLm9wZW5NZSYmKHRoaXMuX29wZW5JdGVtKG8uY2hpbGROb2Rlc1tsXSksby5jaGlsZE5vZGVzW2xdLm9wZW5NZT0wKSxlLl9yZWRyYXdGcm9tKGUsby5jaGlsZE5vZGVzW2xdKSxudWxsIT10aGlzLmNoaWxkQ2FsYyl7aWYoKG8uY2hpbGROb2Rlc1tsXS51blBhcnNlZHx8IW8uY2hpbGROb2Rlc1tsXS5YTUxsb2FkJiZ0aGlzLlhNTHNvdXJjZSkmJihvLmNoaWxkTm9kZXNbbF0uc3Bhbi5pbm5lckhUTUw9by5jaGlsZE5vZGVzW2xdLl9hY2M/by5jaGlsZE5vZGVzW2xdLmxhYmVsK3RoaXMuaHRtbGNBK28uY2hpbGROb2Rlc1tsXS5fYWNjK3RoaXMuaHRtbGNCOm8uY2hpbGROb2Rlc1tsXS5sYWJlbCksby5jaGlsZE5vZGVzW2xdLmNoaWxkTm9kZXMubGVuZ3RoJiZ0aGlzLmNoaWxkQ2FsYyl7aWYoMT09dGhpcy5jaGlsZENhbGMmJihvLmNoaWxkTm9kZXNbbF0uc3Bhbi5pbm5lckhUTUw9by5jaGlsZE5vZGVzW2xdLmxhYmVsK3RoaXMuaHRtbGNBK28uY2hpbGROb2Rlc1tsXS5jaGlsZHNDb3VudCt0aGlzLmh0bWxjQiksMj09dGhpcy5jaGlsZENhbGMpe3ZhciBzPW8uY2hpbGROb2Rlc1tsXS5jaGlsZHNDb3VudC0oby5jaGlsZE5vZGVzW2xdLnB1cmVDaGlsZHN8fDApO3MmJihvLmNoaWxkTm9kZXNbbF0uc3Bhbi5pbm5lckhUTUw9by5jaGlsZE5vZGVzW2xdLmxhYmVsK3RoaXMuaHRtbGNBK3MrdGhpcy5odG1sY0IpLG8ucHVyZUNoaWxkcz9vLnB1cmVDaGlsZHMrKzpvLnB1cmVDaGlsZHM9MX1pZigzPT10aGlzLmNoaWxkQ2FsYyYmKG8uY2hpbGROb2Rlc1tsXS5zcGFuLmlubmVySFRNTD1vLmNoaWxkTm9kZXNbbF0ubGFiZWwrdGhpcy5odG1sY0Erby5jaGlsZE5vZGVzW2xdLl9hY2MrdGhpcy5odG1sY0IpLDQ9PXRoaXMuY2hpbGRDYWxjKXt2YXIgcz1vLmNoaWxkTm9kZXNbbF0uX2FjYztzJiYoby5jaGlsZE5vZGVzW2xdLnNwYW4uaW5uZXJIVE1MPW8uY2hpbGROb2Rlc1tsXS5sYWJlbCt0aGlzLmh0bWxjQStzK3RoaXMuaHRtbGNCKX19ZWxzZSA0PT10aGlzLmNoaWxkQ2FsYyYmcisrO3IrPW8uY2hpbGROb2Rlc1tsXS5fYWNjLDM9PXRoaXMuY2hpbGRDYWxjJiZyKyt9by51blBhcnNlZHx8IW8uWE1MbG9hZCYmdGhpcy5YTUxzb3VyY2V8fChvLl9hY2M9ciksZS5fY29ycmVjdExpbmUobyksZS5fY29ycmVjdFBsdXMobyksdGhpcy5jaGlsZENhbGMmJiF0JiZlLl9maXhDaGlsZENvdW50TGFiZWwobyl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl9jcmVhdGVTZWxmPWZ1bmN0aW9uKCl7dmFyIGU9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2Iik7cmV0dXJuIGUuY2xhc3NOYW1lPSJjb250YWluZXJUYWJsZVN0eWxlIixlLnN0eWxlLndpZHRoPXRoaXMud2lkdGgsZS5zdHlsZS5oZWlnaHQ9dGhpcy5oZWlnaHQsdGhpcy5wYXJlbnRPYmplY3QuYXBwZW5kQ2hpbGQoZSksZX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX3hjbG9zZUFsbD1mdW5jdGlvbihlKXtpZighZS51blBhcnNlZCl7aWYodGhpcy5yb290SWQhPWUuaWQpe2lmKCFlLmh0bWxOb2RlKXJldHVybjtmb3IodmFyIHQ9ZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXMsaT10Lmxlbmd0aCxuPTE7aT5uO24rKyl0W25dLnN0eWxlLmRpc3BsYXk9Im5vbmUiO3RoaXMuX2NvcnJlY3RQbHVzKGUpfWZvcih2YXIgbj0wO248ZS5jaGlsZHNDb3VudDtuKyspZS5jaGlsZE5vZGVzW25dLmNoaWxkc0NvdW50JiZ0aGlzLl94Y2xvc2VBbGwoZS5jaGlsZE5vZGVzW25dKX19LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl94b3BlbkFsbD1mdW5jdGlvbihlKXt0aGlzLl9IaWRlU2hvdyhlLDIpO2Zvcih2YXIgdD0wO3Q8ZS5jaGlsZHNDb3VudDt0KyspdGhpcy5feG9wZW5BbGwoZS5jaGlsZE5vZGVzW3RdKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX2NvcnJlY3RQbHVzPWZ1bmN0aW9uKGUpe2lmKGUuaHRtbE5vZGUpe3ZhciB0PWUuaHRtbE5vZGUuY2hpbGROb2Rlc1swXS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXNbMF0ubGFzdENoaWxkLGk9ZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXNbMF0uY2hpbGROb2Rlc1syXS5jaGlsZE5vZGVzWzBdLG49dGhpcy5saW5lQXJyYXk7aWYodGhpcy5YTUxzb3VyY2UmJiFlLlhNTGxvYWQpe3ZhciBuPXRoaXMucGx1c0FycmF5O2lmKHRoaXMuX3NldFNyYyhpLHRoaXMuaWNvblVSTCtlLmltYWdlc1syXSksdGhpcy5fdHh0aW1nKXJldHVybiB0LmlubmVySFRNTD0iWytdIn1lbHNlIGlmKGUuY2hpbGRzQ291bnR8fGUudW5QYXJzZWQpaWYoZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXNbMV0mJiJub25lIiE9ZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXNbMV0uc3R5bGUuZGlzcGxheSl7aWYoIWUud3NpZ24pdmFyIG49dGhpcy5taW51c0FycmF5O2lmKHRoaXMuX3NldFNyYyhpLHRoaXMuaWNvblVSTCtlLmltYWdlc1sxXSksdGhpcy5fdHh0aW1nKXJldHVybiB0LmlubmVySFRNTD0iWy1dIn1lbHNle2lmKCFlLndzaWduKXZhciBuPXRoaXMucGx1c0FycmF5O2lmKHRoaXMuX3NldFNyYyhpLHRoaXMuaWNvblVSTCtlLmltYWdlc1syXSksdGhpcy5fdHh0aW1nKXJldHVybiB0LmlubmVySFRNTD0iWytdIn1lbHNlIHRoaXMuX3NldFNyYyhpLHRoaXMuaWNvblVSTCtlLmltYWdlc1swXSk7dmFyIG89MjtlLnRyZWVOb2QudHJlZUxpbmVzT24/KGUucGFyZW50T2JqZWN0JiYobz10aGlzLl9nZXRDb3VudFN0YXR1cyhlLmlkLGUucGFyZW50T2JqZWN0KSksdGhpcy5fc2V0U3JjKHQsdGhpcy5pbVBhdGgrbltvXSkpOnRoaXMuX3NldFNyYyh0LHRoaXMuaW1QYXRoK25bM10pfX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX2NvcnJlY3RMaW5lPWZ1bmN0aW9uKGUpe2lmKGUuaHRtbE5vZGUpe3ZhciB0PWUucGFyZW50T2JqZWN0O2lmKHQpaWYoMCE9dGhpcy5fZ2V0TGluZVN0YXR1cyhlLmlkLHQpJiZ0aGlzLnRyZWVMaW5lc09uKWZvcih2YXIgaT0xO2k8PWUuY2hpbGRzQ291bnQmJmUuaHRtbE5vZGUuY2hpbGROb2Rlc1swXS5jaGlsZE5vZGVzW2ldO2krKyllLmh0bWxOb2RlLmNoaWxkTm9kZXNbMF0uY2hpbGROb2Rlc1tpXS5jaGlsZE5vZGVzWzBdLnN0eWxlLmJhY2tncm91bmRJbWFnZT0idXJsKCIrdGhpcy5pbVBhdGgrdGhpcy5saW5lQXJyYXlbNV0rIikiLGUuaHRtbE5vZGUuY2hpbGROb2Rlc1swXS5jaGlsZE5vZGVzW2ldLmNoaWxkTm9kZXNbMF0uc3R5bGUuYmFja2dyb3VuZFJlcGVhdD0icmVwZWF0LXkiO2Vsc2UgZm9yKHZhciBpPTE7aTw9ZS5jaGlsZHNDb3VudCYmZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXNbaV07aSsrKWUuaHRtbE5vZGUuY2hpbGROb2Rlc1swXS5jaGlsZE5vZGVzW2ldLmNoaWxkTm9kZXNbMF0uc3R5bGUuYmFja2dyb3VuZEltYWdlPSIiLGUuaHRtbE5vZGUuY2hpbGROb2Rlc1swXS5jaGlsZE5vZGVzW2ldLmNoaWxkTm9kZXNbMF0uc3R5bGUuYmFja2dyb3VuZFJlcGVhdD0iIn19LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl9nZXRMaW5lU3RhdHVzPWZ1bmN0aW9uKGUsdCl7cmV0dXJuIHQuY2hpbGROb2Rlc1t0LmNoaWxkc0NvdW50LTFdLmlkPT1lPzA6MX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX0hpZGVTaG93PWZ1bmN0aW9uKGUsdCl7aWYoIXRoaXMuX2xvY2tlcnx8dGhpcy5za2lwTG9ja3x8IXRoaXMuX2xvY2tlcltlLmlkXSl7aWYodGhpcy5YTUxzb3VyY2UmJiFlLlhNTGxvYWQpe2lmKDE9PXQpcmV0dXJuO3JldHVybiBlLlhNTGxvYWQ9MSx0aGlzLl9sb2FkRHluWE1MKGUuaWQpLHZvaWQgMH1lLnVuUGFyc2VkJiZ0aGlzLnJlUGFyc2UoZSk7dmFyIGk9ZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXMsbj1pLmxlbmd0aDtpZihuPjEpeyJub25lIj09aVsxXS5zdHlsZS5kaXNwbGF5JiYxIT10fHwyPT10P25vZGVzdHlsZT0iIjoodGhpcy5hbGxUcmVlLmNoaWxkTm9kZXNbMF0uYm9yZGVyPSIxIix0aGlzLmFsbFRyZWUuY2hpbGROb2Rlc1swXS5ib3JkZXI9IjAiLG5vZGVzdHlsZT0ibm9uZSIpO2Zvcih2YXIgbz0xO24+bztvKyspaVtvXS5zdHlsZS5kaXNwbGF5PW5vZGVzdHlsZX10aGlzLl9jb3JyZWN0UGx1cyhlKX19LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl9nZXRPcGVuU3RhdGU9ZnVuY3Rpb24oZSl7aWYoIWUuaHRtbE5vZGUpcmV0dXJuIDA7dmFyIHQ9ZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXM7cmV0dXJuIHQubGVuZ3RoPD0xPzA6Im5vbmUiIT10WzFdLnN0eWxlLmRpc3BsYXk/MTotMX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUub25Sb3dDbGljazI9ZnVuY3Rpb24oKXt2YXIgZT10aGlzLnBhcmVudE9iamVjdC50cmVlTm9kO3JldHVybiBlLmNhbGxFdmVudCgib25EYmxDbGljayIsW3RoaXMucGFyZW50T2JqZWN0LmlkLGVdKT8odGhpcy5wYXJlbnRPYmplY3QuY2xvc2VibGUmJiIwIiE9dGhpcy5wYXJlbnRPYmplY3QuY2xvc2VibGU/ZS5fSGlkZVNob3codGhpcy5wYXJlbnRPYmplY3QpOmUuX0hpZGVTaG93KHRoaXMucGFyZW50T2JqZWN0LDIpLGUuY2hlY2tFdmVudCgib25PcGVuRW5kIikmJihlLnhtbHN0YXRlPyhlLl9vaWVfb25YTEUucHVzaChlLm9uWExFKSxlLm9uWExFPWUuX2VwbkZIZSk6ZS5jYWxsRXZlbnQoIm9uT3BlbkVuZCIsW3RoaXMucGFyZW50T2JqZWN0LmlkLGUuX2dldE9wZW5TdGF0ZSh0aGlzLnBhcmVudE9iamVjdCldKSksITEpOiExfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5vblJvd0NsaWNrPWZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5wYXJlbnRPYmplY3QudHJlZU5vZDtyZXR1cm4gZS5jYWxsRXZlbnQoIm9uT3BlblN0YXJ0IixbdGhpcy5wYXJlbnRPYmplY3QuaWQsZS5fZ2V0T3BlblN0YXRlKHRoaXMucGFyZW50T2JqZWN0KV0pPyh0aGlzLnBhcmVudE9iamVjdC5jbG9zZWJsZSYmIjAiIT10aGlzLnBhcmVudE9iamVjdC5jbG9zZWJsZT9lLl9IaWRlU2hvdyh0aGlzLnBhcmVudE9iamVjdCk6ZS5fSGlkZVNob3codGhpcy5wYXJlbnRPYmplY3QsMiksZS5jaGVja0V2ZW50KCJvbk9wZW5FbmQiKSYmKGUueG1sc3RhdGU/KGUuX29pZV9vblhMRS5wdXNoKGUub25YTEUpLGUub25YTEU9ZS5fZXBuRkhlKTplLmNhbGxFdmVudCgib25PcGVuRW5kIixbdGhpcy5wYXJlbnRPYmplY3QuaWQsZS5fZ2V0T3BlblN0YXRlKHRoaXMucGFyZW50T2JqZWN0KV0pKSx2b2lkIDApOjB9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLmdldFNlbGVjdGVkSXRlbUlkPWZ1bmN0aW9uKCl7Zm9yKHZhciBlPW5ldyBBcnJheSx0PTA7dDx0aGlzLl9zZWxlY3RlZC5sZW5ndGg7dCsrKWVbdF09dGhpcy5fc2VsZWN0ZWRbdF0uaWQ7cmV0dXJuIGUuam9pbih0aGlzLmRsbXRyKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX3NlbGVjdEl0ZW09ZnVuY3Rpb24oZSx0KXtpZih0aGlzLmNoZWNrRXZlbnQoIm9uU2VsZWN0IikmJih0aGlzLl9vblNTQ0ZvbGQ9dGhpcy5nZXRTZWxlY3RlZEl0ZW1JZCgpKSx0aGlzLl9hbXNlbCYmdCYmKHQuY3RybEtleXx8dC5tZXRhS2V5fHx0LnNoaWZ0S2V5KXx8dGhpcy5fdW5zZWxlY3RJdGVtcygpLGUuaV9zZWwmJnRoaXMuX2Ftc2VsJiZ0JiYodC5jdHJsS2V5fHx0Lm1ldGFLZXkpKXRoaXMuX3Vuc2VsZWN0SXRlbShlKTtlbHNlIGlmKCEoZS5pX3NlbHx8dGhpcy5fYW1zZWxTJiYwIT10aGlzLl9zZWxlY3RlZC5sZW5ndGgmJnRoaXMuX3NlbGVjdGVkWzBdLnBhcmVudE9iamVjdCE9ZS5wYXJlbnRPYmplY3QpKWlmKHRoaXMuX2Ftc2VsJiZ0JiZ0LnNoaWZ0S2V5JiYwIT10aGlzLl9zZWxlY3RlZC5sZW5ndGgmJnRoaXMuX3NlbGVjdGVkW3RoaXMuX3NlbGVjdGVkLmxlbmd0aC0xXS5wYXJlbnRPYmplY3Q9PWUucGFyZW50T2JqZWN0KXt2YXIgaT10aGlzLl9nZXRJbmRleCh0aGlzLl9zZWxlY3RlZFt0aGlzLl9zZWxlY3RlZC5sZW5ndGgtMV0pLG49dGhpcy5fZ2V0SW5kZXgoZSk7aWYoaT5uKXt2YXIgbz1pO2k9bixuPW99Zm9yKHZhciByPWk7bj49cjtyKyspZS5wYXJlbnRPYmplY3QuY2hpbGROb2Rlc1tyXS5pX3NlbHx8dGhpcy5fbWFya0l0ZW0oZS5wYXJlbnRPYmplY3QuY2hpbGROb2Rlc1tyXSl9ZWxzZSB0aGlzLl9tYXJrSXRlbShlKTtpZih0aGlzLmNoZWNrRXZlbnQoIm9uU2VsZWN0Iikpe3ZhciBsPXRoaXMuZ2V0U2VsZWN0ZWRJdGVtSWQoKTtsIT10aGlzLl9vblNTQ0ZvbGQmJnRoaXMuY2FsbEV2ZW50KCJvblNlbGVjdCIsW2xdKX19LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl9tYXJrSXRlbT1mdW5jdGlvbihlKXtlLnNjb2xvciYmKGUuc3Bhbi5zdHlsZS5jb2xvcj1lLnNjb2xvciksZS5zcGFuLmNsYXNzTmFtZT0ic2VsZWN0ZWRUcmVlUm93IixlLnNwYW4ucGFyZW50Tm9kZS5wYXJlbnROb2RlLmNsYXNzTmFtZT0ic2VsZWN0ZWRUcmVlUm93RnVsbCIsZS5pX3NlbD0hMCx0aGlzLl9zZWxlY3RlZFt0aGlzLl9zZWxlY3RlZC5sZW5ndGhdPWV9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLmdldEluZGV4QnlJZD1mdW5jdGlvbihlKXt2YXIgdD10aGlzLl9nbG9iYWxJZFN0b3JhZ2VGaW5kKGUpO3JldHVybiB0P3RoaXMuX2dldEluZGV4KHQpOm51bGx9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl9nZXRJbmRleD1mdW5jdGlvbihlKXtmb3IodmFyIHQ9ZS5wYXJlbnRPYmplY3QsaT0wO2k8dC5jaGlsZHNDb3VudDtpKyspaWYodC5jaGlsZE5vZGVzW2ldPT1lKXJldHVybiBpfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5fdW5zZWxlY3RJdGVtPWZ1bmN0aW9uKGUpe2lmKGUmJmUuaV9zZWwpe2Uuc3Bhbi5jbGFzc05hbWU9InN0YW5kYXJ0VHJlZVJvdyIsZS5zcGFuLnBhcmVudE5vZGUucGFyZW50Tm9kZS5jbGFzc05hbWU9IiIsZS5hY29sb3ImJihlLnNwYW4uc3R5bGUuY29sb3I9ZS5hY29sb3IpLGUuaV9zZWw9ITE7Zm9yKHZhciB0PTA7dDx0aGlzLl9zZWxlY3RlZC5sZW5ndGg7dCsrKWlmKCF0aGlzLl9zZWxlY3RlZFt0XS5pX3NlbCl7dGhpcy5fc2VsZWN0ZWQuc3BsaWNlKHQsMSk7YnJlYWt9fX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX3Vuc2VsZWN0SXRlbXM9ZnVuY3Rpb24oKXtmb3IodmFyIGU9MDtlPHRoaXMuX3NlbGVjdGVkLmxlbmd0aDtlKyspe3ZhciB0PXRoaXMuX3NlbGVjdGVkW2VdO3Quc3Bhbi5jbGFzc05hbWU9InN0YW5kYXJ0VHJlZVJvdyIsdC5zcGFuLnBhcmVudE5vZGUucGFyZW50Tm9kZS5jbGFzc05hbWU9IiIsdC5hY29sb3ImJih0LnNwYW4uc3R5bGUuY29sb3I9dC5hY29sb3IpLHQuaV9zZWw9ITF9dGhpcy5fc2VsZWN0ZWQ9bmV3IEFycmF5fSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5vblJvd1NlbGVjdD1mdW5jdGlvbihlLHQsaSl7ZT1lfHx3aW5kb3cuZXZlbnQ7dmFyIG49dGhpcy5wYXJlbnRPYmplY3Q7dCYmKG49dC5wYXJlbnRPYmplY3QpO3ZhciBvPW4udHJlZU5vZCxyPW8uZ2V0U2VsZWN0ZWRJdGVtSWQoKTtlJiZlLnNraXBVblNlbHx8by5fc2VsZWN0SXRlbShuLGUpLGl8fChuLmFjdGlvbkhhbmRsZXI/bi5hY3Rpb25IYW5kbGVyKG4uaWQscik6by5jYWxsRXZlbnQoIm9uQ2xpY2siLFtuLmlkLHJdKSl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl9jcmVhdGVJdGVtPWZ1bmN0aW9uKGUsdCxpKXt2YXIgbj1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJ0YWJsZSIpO24uY2VsbFNwYWNpbmc9MCxuLmNlbGxQYWRkaW5nPTAsbi5ib3JkZXI9MCx0aGlzLmhmTW9kZSYmKG4uc3R5bGUudGFibGVMYXlvdXQ9ImZpeGVkIiksbi5zdHlsZS5tYXJnaW49MCxuLnN0eWxlLnBhZGRpbmc9MDt2YXIgbz1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJ0Ym9keSIpLHI9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidHIiKSxsPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInRkIik7aWYobC5jbGFzc05hbWU9InN0YW5kYXJ0VHJlZUltYWdlIix0aGlzLl90eHRpbWcpe3ZhciBzPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpO2wuYXBwZW5kQ2hpbGQocykscy5jbGFzc05hbWU9ImRoeF90cmVlX3RleHRTaWduIn1lbHNle3ZhciBzPXRoaXMuX2dldEltZyh0LmlkKTtzLmJvcmRlcj0iMCIsIklNRyI9PXMudGFnTmFtZSYmKHMuYWxpZ249ImFic21pZGRsZSIpLGwuYXBwZW5kQ2hpbGQocykscy5zdHlsZS5wYWRkaW5nPTAscy5zdHlsZS5tYXJnaW49MCxzLnN0eWxlLndpZHRoPXRoaXMuZGVmX2xpbmVfaW1nX3h9dmFyIGE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGQiKSxkPXRoaXMuX2dldEltZyh0aGlzLmNCUk9mP3RoaXMucm9vdElkOnQuaWQpO2QuY2hlY2tlZD0wLHRoaXMuX3NldFNyYyhkLHRoaXMuaW1QYXRoK3RoaXMuY2hlY2tBcnJheVswXSksZC5zdHlsZS53aWR0aD0iMThweCIsZC5zdHlsZS5oZWlnaHQ9IjE4cHgiLGV8fChhLnN0eWxlLmRpc3BsYXk9Im5vbmUiKSxhLmFwcGVuZENoaWxkKGQpLHRoaXMuY0JST2Z8fCJJTUciIT1kLnRhZ05hbWV8fChkLmFsaWduPSJhYnNtaWRkbGUiKSxkLm9uY2xpY2s9dGhpcy5vbkNoZWNrQm94Q2xpY2ssZC50cmVlTm9kPXRoaXMsZC5wYXJlbnRPYmplY3Q9dCxhLndpZHRoPXdpbmRvdy5fS0hUTUxydj8iMTZweCI6IjIwcHgiO3ZhciBoPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInRkIik7aC5jbGFzc05hbWU9InN0YW5kYXJ0VHJlZUltYWdlIjt2YXIgYz10aGlzLl9nZXRJbWcodGhpcy50aW1nZW4/dC5pZDp0aGlzLnJvb3RJZCk7Yy5vbm1vdXNlZG93bj10aGlzLl9wcmV2ZW50TnNEcmFnLGMub25kcmFnc3RhcnQ9dGhpcy5fcHJldmVudE5zRHJhZyxjLmJvcmRlcj0iMCIsdGhpcy5fYWltZ3MmJihjLnBhcmVudE9iamVjdD10LCJJTUciPT1jLnRhZ05hbWUmJihjLmFsaWduPSJhYnNtaWRkbGUiKSxjLm9uY2xpY2s9dGhpcy5vblJvd1NlbGVjdCksaXx8dGhpcy5fc2V0U3JjKGMsdGhpcy5pY29uVVJMK3RoaXMuaW1hZ2VBcnJheVswXSksaC5hcHBlbmRDaGlsZChjKSxjLnN0eWxlLnBhZGRpbmc9MCxjLnN0eWxlLm1hcmdpbj0wLHRoaXMudGltZ2VuPyhoLnN0eWxlLndpZHRoPWMuc3R5bGUud2lkdGg9dGhpcy5kZWZfaW1nX3gsYy5zdHlsZS5oZWlnaHQ9dGhpcy5kZWZfaW1nX3kpOihjLnN0eWxlLndpZHRoPSIwcHgiLGMuc3R5bGUuaGVpZ2h0PSIwcHgiLChfaXNPcGVyYXx8d2luZG93Ll9LSFRNTHJ2KSYmKGguc3R5bGUuZGlzcGxheT0ibm9uZSIpKTsKdmFyIHU9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGQiKTtyZXR1cm4gdS5jbGFzc05hbWU9ImRoeFRleHRDZWxsIHN0YW5kYXJ0VHJlZVJvdyIsdC5zcGFuPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNwYW4iKSx0LnNwYW4uY2xhc3NOYW1lPSJzdGFuZGFydFRyZWVSb3ciLHRoaXMubWxpdGVtcz8odC5zcGFuLnN0eWxlLndpZHRoPXRoaXMubWxpdGVtcyx0LnNwYW4uc3R5bGUuZGlzcGxheT0iYmxvY2siKTp1Lm5vV3JhcD0hMCxkaHg0LmlzSUU4P3Uuc3R5bGUud2lkdGg9Ijk5OTk5cHgiOndpbmRvdy5fS0hUTUxydnx8KHUuc3R5bGUud2lkdGg9IjEwMCUiKSx0LnNwYW4uaW5uZXJIVE1MPXQubGFiZWwsdS5hcHBlbmRDaGlsZCh0LnNwYW4pLHUucGFyZW50T2JqZWN0PXQsbC5wYXJlbnRPYmplY3Q9dCx1Lm9uY2xpY2s9dGhpcy5vblJvd1NlbGVjdCxsLm9uY2xpY2s9dGhpcy5vblJvd0NsaWNrLHUub25kYmxjbGljaz10aGlzLm9uUm93Q2xpY2syLHRoaXMuZXR0aXAmJihyLnRpdGxlPXQubGFiZWwpLHRoaXMuZHJhZ0FuZERyb3BPZmYmJih0aGlzLl9haW1ncyYmKHRoaXMuZHJhZ2dlci5hZGREcmFnZ2FibGVJdGVtKGgsdGhpcyksaC5wYXJlbnRPYmplY3Q9dCksdGhpcy5kcmFnZ2VyLmFkZERyYWdnYWJsZUl0ZW0odSx0aGlzKSksdC5zcGFuLnN0eWxlLnBhZGRpbmdMZWZ0PSI1cHgiLHQuc3Bhbi5zdHlsZS5wYWRkaW5nUmlnaHQ9IjVweCIsdS5zdHlsZS52ZXJ0aWNhbEFsaWduPSIiLHUuc3R5bGUuZm9udFNpemU9IjEwcHQiLHUuc3R5bGUuY3Vyc29yPXRoaXMuc3R5bGVfcG9pbnRlcixyLmFwcGVuZENoaWxkKGwpLHIuYXBwZW5kQ2hpbGQoYSksci5hcHBlbmRDaGlsZChoKSxyLmFwcGVuZENoaWxkKHUpLG8uYXBwZW5kQ2hpbGQociksbi5hcHBlbmRDaGlsZChvKSwodGhpcy5laGx0fHx0aGlzLmNoZWNrRXZlbnQoIm9uTW91c2VJbiIpfHx0aGlzLmNoZWNrRXZlbnQoIm9uTW91c2VPdXQiKSkmJihyLm9ubW91c2Vtb3ZlPXRoaXMuX2l0ZW1Nb3VzZUluLHJbX2lzSUU/Im9ubW91c2VsZWF2ZSI6Im9ubW91c2VvdXQiXT10aGlzLl9pdGVtTW91c2VPdXQpLG59LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLnNldE9uUmlnaHRDbGlja0hhbmRsZXI9ZnVuY3Rpb24oZSl7dGhpcy5hdHRhY2hFdmVudCgib25SaWdodENsaWNrIixlKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuc2V0T25DbGlja0hhbmRsZXI9ZnVuY3Rpb24oZSl7dGhpcy5hdHRhY2hFdmVudCgib25DbGljayIsZSl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLnNldE9uU2VsZWN0U3RhdGVDaGFuZ2U9ZnVuY3Rpb24oZSl7dGhpcy5hdHRhY2hFdmVudCgib25TZWxlY3QiLGUpfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5zZXRYTUxBdXRvTG9hZGluZz1mdW5jdGlvbihlKXt0aGlzLlhNTHNvdXJjZT1lfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5zZXRPbkNoZWNrSGFuZGxlcj1mdW5jdGlvbihlKXt0aGlzLmF0dGFjaEV2ZW50KCJvbkNoZWNrIixlKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuc2V0T25PcGVuSGFuZGxlcj1mdW5jdGlvbihlKXt0aGlzLmF0dGFjaEV2ZW50KCJvbk9wZW5TdGFydCIsZSl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLnNldE9uT3BlblN0YXJ0SGFuZGxlcj1mdW5jdGlvbihlKXt0aGlzLmF0dGFjaEV2ZW50KCJvbk9wZW5TdGFydCIsZSl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLnNldE9uT3BlbkVuZEhhbmRsZXI9ZnVuY3Rpb24oZSl7dGhpcy5hdHRhY2hFdmVudCgib25PcGVuRW5kIixlKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuc2V0T25EYmxDbGlja0hhbmRsZXI9ZnVuY3Rpb24oZSl7dGhpcy5hdHRhY2hFdmVudCgib25EYmxDbGljayIsZSl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLm9wZW5BbGxJdGVtcz1mdW5jdGlvbihlKXt2YXIgdD10aGlzLl9nbG9iYWxJZFN0b3JhZ2VGaW5kKGUpO3JldHVybiB0Pyh0aGlzLl94b3BlbkFsbCh0KSx2b2lkIDApOjB9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLmdldE9wZW5TdGF0ZT1mdW5jdGlvbihlKXt2YXIgdD10aGlzLl9nbG9iYWxJZFN0b3JhZ2VGaW5kKGUpO3JldHVybiB0P3RoaXMuX2dldE9wZW5TdGF0ZSh0KToiIn0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuY2xvc2VBbGxJdGVtcz1mdW5jdGlvbihlKXtlPT09d2luZG93LnVuZGVmaW5lZCYmKGU9dGhpcy5yb290SWQpO3ZhciB0PXRoaXMuX2dsb2JhbElkU3RvcmFnZUZpbmQoZSk7cmV0dXJuIHQ/KHRoaXMuX3hjbG9zZUFsbCh0KSx0aGlzLmFsbFRyZWUuY2hpbGROb2Rlc1swXS5ib3JkZXI9IjEiLHRoaXMuYWxsVHJlZS5jaGlsZE5vZGVzWzBdLmJvcmRlcj0iMCIsdm9pZCAwKTowfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5zZXRVc2VyRGF0YT1mdW5jdGlvbihlLHQsaSl7dmFyIG49dGhpcy5fZ2xvYmFsSWRTdG9yYWdlRmluZChlLDAsITApO24mJigiaGludCI9PXQmJihuLmh0bWxOb2RlLmNoaWxkTm9kZXNbMF0uY2hpbGROb2Rlc1swXS50aXRsZT1pKSwidW5kZWZpbmVkIj09dHlwZW9mIG4udXNlckRhdGFbInRfIit0XSYmKG4uX3VzZXJkYXRhbGlzdD9uLl91c2VyZGF0YWxpc3QrPSIsIit0Om4uX3VzZXJkYXRhbGlzdD10KSxuLnVzZXJEYXRhWyJ0XyIrdF09aSl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLmdldFVzZXJEYXRhPWZ1bmN0aW9uKGUsdCl7dmFyIGk9dGhpcy5fZ2xvYmFsSWRTdG9yYWdlRmluZChlLDAsITApO2lmKGkpcmV0dXJuIGkudXNlckRhdGFbInRfIit0XX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuZ2V0SXRlbUNvbG9yPWZ1bmN0aW9uKGUpe3ZhciB0PXRoaXMuX2dsb2JhbElkU3RvcmFnZUZpbmQoZSk7aWYoIXQpcmV0dXJuIDA7dmFyIGk9bmV3IE9iamVjdDtyZXR1cm4gdC5hY29sb3ImJihpLmFjb2xvcj10LmFjb2xvciksdC5zY29sb3ImJihpLnNjb2xvcj10LnNjb2xvciksaX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuc2V0SXRlbUNvbG9yPWZ1bmN0aW9uKGUsdCxpKXtpZihlJiZlLnNwYW4pdmFyIG49ZTtlbHNlIHZhciBuPXRoaXMuX2dsb2JhbElkU3RvcmFnZUZpbmQoZSk7cmV0dXJuIG4/KG4uaV9zZWw/KGl8fHQpJiYobi5zcGFuLnN0eWxlLmNvbG9yPWl8fHQpOnQmJihuLnNwYW4uc3R5bGUuY29sb3I9dCksaSYmKG4uc2NvbG9yPWkpLHQmJihuLmFjb2xvcj10KSx2b2lkIDApOjB9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLnNldE9uTW91c2VJbkhhbmRsZXI9ZnVuY3Rpb24oZSl7dGhpcy5laGx0PSEwLHRoaXMuYXR0YWNoRXZlbnQoIm9uTW91c2VJbiIsZSl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLnNldE9uTW91c2VPdXRIYW5kbGVyPWZ1bmN0aW9uKGUpe3RoaXMuZWhsdD0hMCx0aGlzLmF0dGFjaEV2ZW50KCJvbk1vdXNlT3V0IixlKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuZW5hYmxlVHJlZUxpbmVzPWZ1bmN0aW9uKGUpe3RoaXMudHJlZUxpbmVzT249ZGh4NC5zMmIoZSl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLm9wZW5JdGVtPWZ1bmN0aW9uKGUpe3RoaXMuc2tpcExvY2s9ITA7dmFyIHQ9dGhpcy5fZ2xvYmFsSWRTdG9yYWdlRmluZChlKTtyZXR1cm4gdD90aGlzLl9vcGVuSXRlbSh0KTowfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5fb3Blbkl0ZW09ZnVuY3Rpb24oZSl7dmFyIHQ9dGhpcy5fZ2V0T3BlblN0YXRlKGUpO2lmKDA+dHx8dGhpcy5YTUxzb3VyY2UmJiFlLlhNTGxvYWQpe2lmKCF0aGlzLmNhbGxFdmVudCgib25PcGVuU3RhcnQiLFtlLmlkLHRdKSlyZXR1cm4gMDt0aGlzLl9IaWRlU2hvdyhlLDIpLHRoaXMuY2hlY2tFdmVudCgib25PcGVuRW5kIikmJih0aGlzLm9uWExFPT10aGlzLl9lcG5GSGUmJnRoaXMuX2VwbkZIZSh0aGlzLGUuaWQsITApLHRoaXMueG1sc3RhdGUmJnRoaXMuWE1Mc291cmNlPyh0aGlzLl9vaWVfb25YTEUucHVzaCh0aGlzLm9uWExFKSx0aGlzLm9uWExFPXRoaXMuX2VwbkZIZSk6dGhpcy5jYWxsRXZlbnQoIm9uT3BlbkVuZCIsW2UuaWQsdGhpcy5fZ2V0T3BlblN0YXRlKGUpXSkpfWVsc2UgdGhpcy5fc3JuZCYmdGhpcy5fSGlkZVNob3coZSwyKTtlLnBhcmVudE9iamVjdCYmIXRoaXMuX3NraXBfb3Blbl9wYXJlbnQmJnRoaXMuX29wZW5JdGVtKGUucGFyZW50T2JqZWN0KX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX2dldEFsbEZhdEl0ZW1zPWZ1bmN0aW9uKGUpe2Zvcih2YXIgdD0iIixpPTA7aTxlLmNoaWxkc0NvdW50O2krKylpZihlLmNoaWxkTm9kZXNbaV0udW5QYXJzZWR8fGUuY2hpbGROb2Rlc1tpXS5jaGlsZHNDb3VudD4wKXtpZih0P3QrPXRoaXMuZGxtdHIrZS5jaGlsZE5vZGVzW2ldLmlkOnQ9IiIrZS5jaGlsZE5vZGVzW2ldLmlkLGUuY2hpbGROb2Rlc1tpXS51blBhcnNlZCl2YXIgbj10aGlzLl9nZXRBbGxGYXRJdGVtc1hNTChlLmNoaWxkTm9kZXNbaV0udW5QYXJzZWQsMSk7ZWxzZSB2YXIgbj10aGlzLl9nZXRBbGxGYXRJdGVtcyhlLmNoaWxkTm9kZXNbaV0pO24mJih0Kz10aGlzLmRsbXRyK24pfXJldHVybiB0fSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5zZWxlY3RJdGVtPWZ1bmN0aW9uKGUsdCxpKXt0PWRoeDQuczJiKHQpO3ZhciBuPXRoaXMuX2dsb2JhbElkU3RvcmFnZUZpbmQoZSk7aWYoIW58fCFuLnBhcmVudE9iamVjdClyZXR1cm4gMDt0aGlzLlhNTGxvYWRpbmdXYXJuaW5nP24ucGFyZW50T2JqZWN0Lm9wZW5NZT0xOnRoaXMuX29wZW5JdGVtKG4ucGFyZW50T2JqZWN0KTt2YXIgbz1udWxsO2kmJihvPW5ldyBPYmplY3Qsby5jdHJsS2V5PSEwLG4uaV9zZWwmJihvLnNraXBVblNlbD0hMCkpLHQ/dGhpcy5vblJvd1NlbGVjdChvLG4uaHRtbE5vZGUuY2hpbGROb2Rlc1swXS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXNbM10sITEpOnRoaXMub25Sb3dTZWxlY3QobyxuLmh0bWxOb2RlLmNoaWxkTm9kZXNbMF0uY2hpbGROb2Rlc1swXS5jaGlsZE5vZGVzWzNdLCEwKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX2NvbXByZXNzQ2hpbGRMaXN0PWZ1bmN0aW9uKGUsdCl7ZS0tO2Zvcih2YXIgaT0wO2U+aTtpKyspMD09dFtpXSYmKHRbaV09dFtpKzFdLHRbaSsxXT0wKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX2RlbGV0ZU5vZGU9ZnVuY3Rpb24oZSx0LGkpe2lmKCF0fHwhdC5wYXJlbnRPYmplY3QpcmV0dXJuIDA7dmFyIG49MCxvPTA7dC50ci5uZXh0U2libGluZyYmKG49dC50ci5uZXh0U2libGluZy5ub2RlbSksdC50ci5wcmV2aW91c1NpYmxpbmcmJihvPXQudHIucHJldmlvdXNTaWJsaW5nLm5vZGVtKTtmb3IodmFyIHI9dC5wYXJlbnRPYmplY3QsbD1yLmNoaWxkc0NvdW50LHM9ci5jaGlsZE5vZGVzLGE9MDtsPmE7YSsrKWlmKHNbYV0uaWQ9PWUpe2l8fHIuaHRtbE5vZGUuY2hpbGROb2Rlc1swXS5yZW1vdmVDaGlsZChzW2FdLnRyKSxzW2FdPTA7YnJlYWt9dGhpcy5fY29tcHJlc3NDaGlsZExpc3QobCxzKSxpfHxyLmNoaWxkc0NvdW50LS0sbiYmKHRoaXMuX2NvcnJlY3RQbHVzKG4pLHRoaXMuX2NvcnJlY3RMaW5lKG4pKSxvJiYodGhpcy5fY29ycmVjdFBsdXMobyksdGhpcy5fY29ycmVjdExpbmUobykpLHRoaXMudHNjaGVjayYmdGhpcy5fY29ycmVjdENoZWNrU3RhdGVzKHIpLGl8fHRoaXMuX2dsb2JhbElkU3RvcmFnZVJlY1N1Yih0KX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuZGVsZXRlQ2hpbGRJdGVtcz1mdW5jdGlvbihlKXt2YXIgdD10aGlzLl9nbG9iYWxJZFN0b3JhZ2VGaW5kKGUpO2lmKHQpZm9yKHZhciBpPXQuY2hpbGRzQ291bnQsbj0wO2k+bjtuKyspdGhpcy5fZGVsZXRlTm9kZSh0LmNoaWxkTm9kZXNbMF0uaWQsdC5jaGlsZE5vZGVzWzBdKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX2dsb2JhbElkU3RvcmFnZVJlY1N1Yj1mdW5jdGlvbihlKXtmb3IodmFyIHQ9MDt0PGUuY2hpbGRzQ291bnQ7dCsrKXRoaXMuX2dsb2JhbElkU3RvcmFnZVJlY1N1YihlLmNoaWxkTm9kZXNbdF0pLHRoaXMuX2dsb2JhbElkU3RvcmFnZVN1YihlLmNoaWxkTm9kZXNbdF0uaWQpO3RoaXMuX2dsb2JhbElkU3RvcmFnZVN1YihlLmlkKTt2YXIgaT1lO2kuc3Bhbj1udWxsLGkudHIubm9kZW09bnVsbCxpLnRyPW51bGwsaS5odG1sTm9kZT1udWxsfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5fYXV0b1Njcm9sbD1mdW5jdGlvbihlLHQsaSl7dGhpcy5hdXRvU2Nyb2xsJiYoZSYmKHQ9ZGh4NC5hYnNUb3AoZSksaT1kaHg0LmFic1RvcCh0aGlzLmFsbFRyZWUpLXRoaXMuYWxsVHJlZS5zY3JvbGxUb3ApLHQtaS1wYXJzZUludCh0aGlzLmFsbFRyZWUuc2Nyb2xsVG9wKT5wYXJzZUludCh0aGlzLmFsbFRyZWUub2Zmc2V0SGVpZ2h0KS01MCYmKHRoaXMuYWxsVHJlZS5zY3JvbGxUb3A9cGFyc2VJbnQodGhpcy5hbGxUcmVlLnNjcm9sbFRvcCkrMjApLHQtaTxwYXJzZUludCh0aGlzLmFsbFRyZWUuc2Nyb2xsVG9wKSszMCYmKHRoaXMuYWxsVHJlZS5zY3JvbGxUb3A9cGFyc2VJbnQodGhpcy5hbGxUcmVlLnNjcm9sbFRvcCktMjApKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuZW5hYmxlVGV4dFNpZ25zPWZ1bmN0aW9uKGUpe3RoaXMuX3R4dGltZz1kaHg0LnMyYihlKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUucHJldmVudElFQ2FjaGluZz1mdW5jdGlvbihlKXtkaHg0LmFqYXguY2FjaGU9IWV9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLnByZXZlbnRJRUNhc2hpbmc9ZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUucHJldmVudElFQ2FjaGluZyxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5zZXRJY29uU2l6ZT1mdW5jdGlvbihlLHQsaSl7aWYoaSl7aWYoaSYmaS5zcGFuKXZhciBuPWk7ZWxzZSB2YXIgbj10aGlzLl9nbG9iYWxJZFN0b3JhZ2VGaW5kKGkpO2lmKCFuKXJldHVybiAwO3ZhciBvPW4uc3Bhbi5wYXJlbnROb2RlLnByZXZpb3VzU2libGluZy5jaGlsZE5vZGVzWzBdO2UmJihvLnN0eWxlLndpZHRoPWUrInB4Iix3aW5kb3cuX0tIVE1McnYmJihvLnBhcmVudE5vZGUuc3R5bGUud2lkdGg9ZSsicHgiKSksdCYmKG8uc3R5bGUuaGVpZ2h0PXQrInB4Iix3aW5kb3cuX0tIVE1McnYmJihvLnBhcmVudE5vZGUuc3R5bGUuaGVpZ2h0PXQrInB4IikpfWVsc2UgdGhpcy5kZWZfaW1nX3g9ZSsicHgiLHRoaXMuZGVmX2ltZ195PXQrInB4In0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuZW5hYmxlU2luZ2xlUmFkaW9Nb2RlPWZ1bmN0aW9uKGUpe3RoaXMuX2ZyYnRycz1kaHg0LnMyYihlKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUub3Blbk9uSXRlbUFkZGVkPWZ1bmN0aW9uKGUpe3RoaXMuX2hBZEk9IWRoeDQuczJiKGUpfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5vcGVuT25JdGVtQWRkaW5nPWZ1bmN0aW9uKGUpe3RoaXMuX2hBZEk9IWRoeDQuczJiKGUpfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5nZXRBbGxJdGVtc1dpdGhLaWRzPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX2dldEFsbEZhdEl0ZW1zKHRoaXMuaHRtbE5vZGUpfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5zZXRTa2luPWZ1bmN0aW9uKGUpe3ZhciB0PXRoaXMucGFyZW50T2JqZWN0LmNsYXNzTmFtZS5yZXBsYWNlKC9kaHh0cmVlX1teIF0qL2dpLCIiKTt0aGlzLnBhcmVudE9iamVjdC5jbGFzc05hbWU9dCsiIGRoeHRyZWVfIitlLCgiZGh4X3RlcnJhY2UiPT1lfHwiZGh4X3dlYiI9PWV8fCJtYXRlcmlhbCI9PWUpJiZ0aGlzLmVuYWJsZVRyZWVMaW5lcyghMSksIm1hdGVyaWFsIj09ZSYmdGhpcy5zZXRJY29uU2l6ZSgiMjUiLCIyNSIpfSxqc29uUG9pbnRlci5wcm90b3R5cGU9e3RleHQ6ZnVuY3Rpb24oKXt2YXIgZT1mdW5jdGlvbihlKXtmb3IodmFyIGk9W10sbj0wO248ZS5sZW5ndGg7bisrKWkucHVzaCgieyIrdChlW25dKSsifSIpO3JldHVybiBpLmpvaW4oIiwiKX0sdD1mdW5jdGlvbihpKXt2YXIgbj1bXTtmb3IodmFyIG8gaW4gaSkib2JqZWN0Ij09dHlwZW9mIGlbb10/by5sZW5ndGg/bi5wdXNoKCciJytvKyciOlsnK2UoaVtvXSkrIl0iKTpuLnB1c2goJyInK28rJyI6eycrdChpW29dKSsifSIpOm4ucHVzaCgnIicrbysnIjoiJytpW29dKyciJyk7cmV0dXJuIG4uam9pbigiLCIpfTtyZXR1cm4ieyIrdCh0aGlzLmQpKyJ9In0sZ2V0OmZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLmRbZV19LGV4aXN0czpmdW5jdGlvbigpe3JldHVybiEhdGhpcy5kfSxjb250ZW50OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZC5jb250ZW50fSxlYWNoOmZ1bmN0aW9uKGUsdCxpKXt2YXIgbj10aGlzLmRbZV0sbz1uZXcganNvblBvaW50ZXI7aWYobilmb3IodmFyIHI9MDtyPG4ubGVuZ3RoO3IrKylvLmQ9bltyXSx0LmFwcGx5KGksW28scl0pfSxnZXRfYWxsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sc3ViOmZ1bmN0aW9uKGUpe3JldHVybiBuZXcganNvblBvaW50ZXIodGhpcy5kW2VdLHRoaXMuZCl9LHN1Yl9leGlzdHM6ZnVuY3Rpb24oZSl7cmV0dXJuISF0aGlzLmRbZV19LGVhY2hfeDpmdW5jdGlvbihlLHQsaSxuLG8pe3ZhciByPXRoaXMuZFtlXSxsPW5ldyBqc29uUG9pbnRlcigwLHRoaXMuZCk7aWYocilmb3Iobz1vfHwwO288ci5sZW5ndGg7bysrKWlmKHJbb11bdF0mJihsLmQ9cltvXSwtMT09aS5hcHBseShuLFtsLG9dKSkpcmV0dXJufSx1cDpmdW5jdGlvbigpe3JldHVybiBuZXcganNvblBvaW50ZXIodGhpcy5kcCx0aGlzLmQpfSxzZXQ6ZnVuY3Rpb24oZSx0KXt0aGlzLmRbZV09dH0sY2xvbmU6ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IGpzb25Qb2ludGVyKHRoaXMuZCx0aGlzLmRwKX0sdGhyb3VnaDpmdW5jdGlvbihlLHQsaSxuLG8pe3ZhciByPXRoaXMuZFtlXTtpZihyLmxlbmd0aClmb3IodmFyIGw9MDtsPHIubGVuZ3RoO2wrKyl7aWYobnVsbCE9cltsXVt0XSYmIiIhPXJbbF1bdF0mJighaXx8cltsXVt0XT09aSkpe3ZhciBzPW5ldyBqc29uUG9pbnRlcihyW2xdLHRoaXMuZCk7bi5hcHBseShvLFtzLGxdKX12YXIgYT10aGlzLmQ7dGhpcy5kPXJbbF0sdGhpcy5zdWJfZXhpc3RzKGUpJiZ0aGlzLnRocm91Z2goZSx0LGksbixvKSx0aGlzLmQ9YX19fSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5sb2FkSlNPTk9iamVjdD1mdW5jdGlvbihlLHQpe3JldHVybiB3aW5kb3cuY29uc29sZSYmd2luZG93LmNvbnNvbGUuaW5mbyYmd2luZG93LmNvbnNvbGUuaW5mbygibG9hZEpTT05PYmplY3Qgd2FzIGRlcHJlY2F0ZWQiLCJodHRwOi8vZG9jcy5kaHRtbHguY29tL21pZ3JhdGlvbl9faW5kZXguaHRtbCNtaWdyYXRpb25mcm9tNDN0bzQ0IiksdGhpcy5fbG9hZEpTT05PYmplY3QoZSx0KX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX2xvYWRKU09OT2JqZWN0PWZ1bmN0aW9uKGUsdCl7dGhpcy5wYXJzQ291bnR8fHRoaXMuY2FsbEV2ZW50KCJvblhMUyIsW3RoaXMsbnVsbF0pLHRoaXMueG1sc3RhdGU9MTt2YXIgaT1uZXcganNvblBvaW50ZXIoZSk7dGhpcy5fcGFyc2UoaSksdGhpcy5fcD1pLHQmJnQoKX0sd2luZG93LmFkZEV2ZW50TGlzdGVuZXI/d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLGRoeF9pbml0X3RyZWVzLCExKTp3aW5kb3cuYXR0YWNoRXZlbnQmJndpbmRvdy5hdHRhY2hFdmVudCgib25sb2FkIixkaHhfaW5pdF90cmVlcyk7dmFyIHN0eWxlPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInN0eWxlIik7c3R5bGUuaW5uZXJIVE1MPSdAa2V5ZnJhbWVzIGRoeF9sb2FkZXJfcm90YXRlezEwMCV7dHJhbnNmb3JtOnJvdGF0ZSgzNjBkZWcpO319QGtleWZyYW1lcyBkaHhfbG9hZGVyX2Rhc2h7MCV7c3Ryb2tlLWRhc2hhcnJheToxLDIwMDtzdHJva2UtZGFzaG9mZnNldDowO301MCV7c3Ryb2tlLWRhc2hhcnJheTo4OSwyMDA7c3Ryb2tlLWRhc2hvZmZzZXQ6LTM1cHg7fTEwMCV7c3Ryb2tlLWRhc2hhcnJheTo4OSwyMDA7c3Ryb2tlLWRhc2hvZmZzZXQ6LTEyNHB4O319LmRodG1seE1lbnVfbWF0ZXJpYWxfTWlkZGxle3Bvc2l0aW9uOnJlbGF0aXZlO2hlaWdodDoyOHB4O2xpbmUtaGVpZ2h0OjI4cHg7YmFja2dyb3VuZC1jb2xvcjojZjVmNWY1O292ZXJmbG93OmhpZGRlbjtib3JkZXI6bm9uZTtmb250LXNpemU6MTRweDtmb250LWZhbWlseTpSb2JvdG8sQXJpYWwsSGVsdmV0aWNhO2NvbG9yOiM0MDQwNDA7LXdlYmtpdC11c2VyLXNlbGVjdDpub25lOy1raHRtbC11c2VyLXNlbGVjdDpub25lOy1tb3otdXNlci1zZWxlY3Q6bm9uZTstbXMtdXNlci1zZWxlY3Q6bm9uZTstby11c2VyLXNlbGVjdDpub25lO3VzZXItc2VsZWN0Om5vbmU7fS5kaHRtbHhNZW51X21hdGVyaWFsX01pZGRsZSBkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9Ub3BMZXZlbF9JdGVtX05vcm1hbCwuZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfVG9wTGV2ZWxfSXRlbV9EaXNhYmxlZCwuZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfVG9wTGV2ZWxfSXRlbV9TZWxlY3RlZHtwb3NpdGlvbjpyZWxhdGl2ZTtmbG9hdDpsZWZ0O2ZvbnQ6aW5oZXJpdDtoZWlnaHQ6MjhweDtsaW5lLWhlaWdodDoyOHB4O21hcmdpbjowO3BhZGRpbmc6MCA4cHg7Y3Vyc29yOmRlZmF1bHQ7d2hpdGUtc3BhY2U6bm93cmFwOy13ZWJraXQtdXNlci1zZWxlY3Q6bm9uZTsta2h0bWwtdXNlci1zZWxlY3Q6bm9uZTstbW96LXVzZXItc2VsZWN0Om5vbmU7LW1zLXVzZXItc2VsZWN0Om5vbmU7LW8tdXNlci1zZWxlY3Q6bm9uZTt1c2VyLXNlbGVjdDpub25lO30uZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfVG9wTGV2ZWxfSXRlbV9Ob3JtYWwgZGl2LnRvcF9sZXZlbF90ZXh0LC5kaHRtbHhNZW51X21hdGVyaWFsX01pZGRsZSBkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9Ub3BMZXZlbF9JdGVtX0Rpc2FibGVkIGRpdi50b3BfbGV2ZWxfdGV4dCwuZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfVG9wTGV2ZWxfSXRlbV9TZWxlY3RlZCBkaXYudG9wX2xldmVsX3RleHR7ZmxvYXQ6bGVmdDttYXJnaW46MCAzcHg7fS5kaHRtbHhNZW51X21hdGVyaWFsX01pZGRsZSBkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9Ub3BMZXZlbF9JdGVtX05vcm1hbCBpLC5kaHRtbHhNZW51X21hdGVyaWFsX01pZGRsZSBkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9Ub3BMZXZlbF9JdGVtX0Rpc2FibGVkIGksLmRodG1seE1lbnVfbWF0ZXJpYWxfTWlkZGxlIGRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1RvcExldmVsX0l0ZW1fU2VsZWN0ZWQgaXtoZWlnaHQ6aW5oZXJpdDtsaW5lLWhlaWdodDppbmhlcml0O2Zsb2F0OmxlZnQ7Y29sb3I6aW5oZXJpdDttYXJnaW46MCA0cHg7Zm9udC1zaXplOjEuMmVtO30uZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfVG9wTGV2ZWxfSXRlbV9EaXNhYmxlZHtjb2xvcjojYTZhNmE2O30uZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfVG9wTGV2ZWxfSXRlbV9TZWxlY3RlZHtiYWNrZ3JvdW5kLWNvbG9yOiNlYmViZWI7fS5kaHRtbHhNZW51X21hdGVyaWFsX01pZGRsZSBpbWcuZGh0bWx4TWVudV9Ub3BMZXZlbF9JdGVtX0ljb257ZmxvYXQ6bGVmdDttYXJnaW46NXB4IDNweCAwIDNweDt3aWR0aDoxOHB4O2hlaWdodDoxOHB4O2N1cnNvcjpkZWZhdWx0O30uZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LnRvcF9zZXB7cG9zaXRpb246cmVsYXRpdmU7ZmxvYXQ6bGVmdDtoZWlnaHQ6MjJweDt3aWR0aDowO2JvcmRlci1sZWZ0OjFweCBzb2xpZCAjZGZkZmRmO21hcmdpbjozcHggOHB4IDAgOHB4O2ZvbnQtc2l6ZToxcHg7b3ZlcmZsb3c6aGlkZGVuO2N1cnNvcjpkZWZhdWx0Oy13ZWJraXQtdXNlci1zZWxlY3Q6bm9uZTsta2h0bWwtdXNlci1zZWxlY3Q6bm9uZTstbW96LXVzZXItc2VsZWN0Om5vbmU7LW1zLXVzZXItc2VsZWN0Om5vbmU7LW8tdXNlci1zZWxlY3Q6bm9uZTt1c2VyLXNlbGVjdDpub25lO30uZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LmRodG1seE1lbnVfVG9wTGV2ZWxfVGV4dF9yaWdodCwuZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LmRodG1seE1lbnVfVG9wTGV2ZWxfVGV4dF9sZWZ0e3Bvc2l0aW9uOmFic29sdXRlO3RvcDowO2hlaWdodDoyOHB4O2xpbmUtaGVpZ2h0OjI4cHg7Y3Vyc29yOmRlZmF1bHQ7Zm9udC1zaXplOjE0cHg7Zm9udC1mYW1pbHk6Um9ib3RvLEFyaWFsLEhlbHZldGljYTtjb2xvcjojNDA0MDQwOy13ZWJraXQtdXNlci1zZWxlY3Q6bm9uZTsta2h0bWwtdXNlci1zZWxlY3Q6bm9uZTstbW96LXVzZXItc2VsZWN0Om5vbmU7LW1zLXVzZXItc2VsZWN0Om5vbmU7LW8tdXNlci1zZWxlY3Q6bm9uZTt1c2VyLXNlbGVjdDpub25lO30uZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LmRodG1seE1lbnVfVG9wTGV2ZWxfVGV4dF9yaWdodHtyaWdodDo2cHg7fS5kaHRtbHhNZW51X21hdGVyaWFsX01pZGRsZSBkaXYuZGh0bWx4TWVudV9Ub3BMZXZlbF9UZXh0X2xlZnR7bGVmdDo2cHg7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29ue3Bvc2l0aW9uOmFic29sdXRlO3BhZGRpbmc6NXB4IDA7YmFja2dyb3VuZC1jb2xvcjojZmFmYWZhO292ZXJmbG93OmhpZGRlbjtjdXJzb3I6ZGVmYXVsdDtsaW5lLWhlaWdodDpub3JtYWw7b3ZlcmZsb3cteTphdXRvOy13ZWJraXQtb3ZlcmZsb3ctc2Nyb2xsaW5nOnRvdWNoOy13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjpyZ2JhKDAsMCwwLDApO2JveC1zaGFkb3c6MCAxcHggM3B4IHJnYmEoMCwwLDAsMC4xMiksMCAxcHggMnB4IHJnYmEoMCwwLDAsMC4yNCk7LXdlYmtpdC11c2VyLXNlbGVjdDpub25lOy1raHRtbC11c2VyLXNlbGVjdDpub25lOy1tb3otdXNlci1zZWxlY3Q6bm9uZTstbXMtdXNlci1zZWxlY3Q6bm9uZTstby11c2VyLXNlbGVjdDpub25lO3VzZXItc2VsZWN0Om5vbmU7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRke3BhZGRpbmc6MDttYXJnaW46MDtsaW5lLWhlaWdodDpub3JtYWw7d2hpdGUtc3BhY2U6bm93cmFwO2ZvbnQtc2l6ZToxNHB4O2ZvbnQtZmFtaWx5OlJvYm90byxBcmlhbCxIZWx2ZXRpY2E7Y29sb3I6IzQwNDA0MDt9ZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gdGQuc3ViX2l0ZW1faWNvbnt3aWR0aDoxOHB4O3RleHQtYWxpZ246Y2VudGVyO31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ZC5zdWJfaXRlbV9pY29uIGltZy5zdWJfaWNvbnttYXJnaW46NHB4IDZweCAwIDZweDt3aWR0aDoxOHB4O2hlaWdodDoxOHB4O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ZC5zdWJfaXRlbV9pY29uIGl7d2lkdGg6MThweDtoZWlnaHQ6MzBweDtsaW5lLWhlaWdodDoyOXB4O21hcmdpbjowIDZweDtmb250LXNpemU6MS4yZW07dGV4dC1hbGlnbjpjZW50ZXI7Y29sb3I6aW5oZXJpdDt9ZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gdGQuc3ViX2l0ZW1faWNvbiBkaXYuc3ViX2ljb257bWFyZ2luOjAgNnB4O3dpZHRoOjE4cHg7aGVpZ2h0OjMwcHg7bGluZS1oZWlnaHQ6MzBweDtiYWNrZ3JvdW5kLXBvc2l0aW9uOjAgNXB4O2JhY2tncm91bmQtcmVwZWF0Om5vLXJlcGVhdDtiYWNrZ3JvdW5kLWltYWdlOnVybCgiaW1ncy9kaHhtZW51X21hdGVyaWFsL2RoeG1lbnVfY2hyZC5wbmciKTt9ZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gdGQuc3ViX2l0ZW1faWNvbiBkaXYuc3ViX2ljb24uY2hieF8we2JhY2tncm91bmQtcG9zaXRpb246MCA1cHg7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRkLnN1Yl9pdGVtX2ljb24gZGl2LnN1Yl9pY29uLmNoYnhfMXtiYWNrZ3JvdW5kLXBvc2l0aW9uOi0xOHB4IDVweDt9ZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gdGQuc3ViX2l0ZW1faWNvbiBkaXYuc3ViX2ljb24ucmRidF8we2JhY2tncm91bmQtcG9zaXRpb246LTcycHggNXB4O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ZC5zdWJfaXRlbV9pY29uIGRpdi5zdWJfaWNvbi5yZGJ0XzF7YmFja2dyb3VuZC1wb3NpdGlvbjotOTBweCA1cHg7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRkLnN1Yl9pdGVtX3RleHQgZGl2LnN1Yl9pdGVtX3RleHR7cG9zaXRpb246cmVsYXRpdmU7aGVpZ2h0OjMwcHg7bGluZS1oZWlnaHQ6MzBweDtwYWRkaW5nOjAgMjJweCAwIDFweDtvdmVyZmxvdzpoaWRkZW47fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRkLnN1Yl9pdGVtX2hre3BhZGRpbmc6MCAxMHB4IDAgOHB4O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ZC5zdWJfaXRlbV9oayBkaXYuc3ViX2l0ZW1faGt7Y29sb3I6IzhkOGQ4ZDtmb250LXNpemU6MTJweDt0ZXh0LWFsaWduOnJpZ2h0O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ZCBkaXYuY29tcGxleF9hcnJvd3tmbG9hdDpyaWdodDt3aWR0aDoxMHB4O21hcmdpbjowIDFweCAwIDExcHg7aGVpZ2h0OjMwcHg7bGluZS1oZWlnaHQ6MzBweDtiYWNrZ3JvdW5kLWltYWdlOnVybCgiaW1ncy9kaHhtZW51X21hdGVyaWFsL2RoeG1lbnVfc3ViYXIucG5nIik7YmFja2dyb3VuZC1yZXBlYXQ6bm8tcmVwZWF0O2JhY2tncm91bmQtcG9zaXRpb246MCAxMHB4O292ZXJmbG93OmhpZGRlbjtmb250LXNpemU6MXB4O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ZCBkaXYuY29tcGxleF9hcnJvd19sb2FkaW5ne3dpZHRoOjE2cHg7aGVpZ2h0OjMwcHg7bGluZS1oZWlnaHQ6MzBweDtiYWNrZ3JvdW5kLXBvc2l0aW9uOmNlbnRlciBjZW50ZXI7YmFja2dyb3VuZC1yZXBlYXQ6bm8tcmVwZWF0O2JhY2tncm91bmQtaW1hZ2U6dXJsKCJpbWdzL2RoeG1lbnVfbWF0ZXJpYWwvZGh4bWVudV9sb2FkZXIuZ2lmIik7ZmxvYXQ6cmlnaHQ7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRyLnN1Yl9pdGVtX3NlbGVjdGVkIHRke2JhY2tncm91bmQtY29sb3I6I2ViZWJlYjt9ZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gdHIuc3ViX2l0ZW1fc2VsZWN0ZWQgdGQgZGl2LmNvbXBsZXhfYXJyb3d7YmFja2dyb3VuZC1wb3NpdGlvbjotMTBweCAxMHB4O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ci5zdWJfaXRlbV9kaXMgdGQuc3ViX2l0ZW1faGsgZGl2LnN1Yl9pdGVtX2hre2NvbG9yOiNjMGMwYzA7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRyLnN1Yl9pdGVtX2RpcyB0ZCBkaXYuc3ViX2l0ZW1fdGV4dCxkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ci5zdWJfaXRlbV9kaXMgdGQgdGQuc3ViX2l0ZW1faWNvbiBpe2NvbG9yOiNhNmE2YTY7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRyLnN1Yl9pdGVtX2RpcyB0ZCBkaXYuY29tcGxleF9hcnJvd3tiYWNrZ3JvdW5kLXBvc2l0aW9uOi0yMHB4IDEwcHg7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRyLnN1Yl9pdGVtX2RpcyB0ZCBkaXYuc3ViX2ljb24uY2hieF8we2JhY2tncm91bmQtcG9zaXRpb246LTM2cHggNXB4O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ci5zdWJfaXRlbV9kaXMgdGQgZGl2LnN1Yl9pY29uLmNoYnhfMXtiYWNrZ3JvdW5kLXBvc2l0aW9uOi01NHB4IDVweDt9ZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gdHIuc3ViX2l0ZW1fZGlzIHRkIGRpdi5zdWJfaWNvbi5yZGJ0XzB7YmFja2dyb3VuZC1wb3NpdGlvbjotMTA4cHggNXB4O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ci5zdWJfaXRlbV9kaXMgdGQgZGl2LnN1Yl9pY29uLnJkYnRfMXtiYWNrZ3JvdW5kLXBvc2l0aW9uOi0xMjZweCA1cHg7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRyLnN1Yl9pdGVtX2RpcyB0ZCBpe2NvbG9yOiNhNmE2YTY7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRyLnN1Yl9zZXAgdGR7cGFkZGluZzo1cHggM3B4O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ci5zdWJfc2VwIHRkIGRpdi5zdWJfc2Vwe3Bvc2l0aW9uOnJlbGF0aXZlO2ZvbnQtc2l6ZToxcHg7bGluZS1oZWlnaHQ6MXB4O2hlaWdodDowO3dpZHRoOjEwMCU7Ym9yZGVyLXRvcDoxcHggc29saWQgI2RmZGZkZjt9ZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX0Fycm93VXAsZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX0Fycm93VXBfT3ZlcixkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiBkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfQXJyb3dVcF9EaXNhYmxlZHtwb3NpdGlvbjpyZWxhdGl2ZTtmb250LXNpemU6MXB4O2JvcmRlci1ib3R0b206MXB4IHNvbGlkICNkZmRmZGY7YmFja2dyb3VuZC1pbWFnZTp1cmwoImltZ3MvZGh4bWVudV9tYXRlcmlhbC9kaHhtZW51X2Fycm93X3VwLnBuZyIpO2JhY2tncm91bmQtcmVwZWF0Om5vLXJlcGVhdDtiYWNrZ3JvdW5kLXBvc2l0aW9uOmNlbnRlciAycHg7cGFkZGluZzo4cHggMDttYXJnaW4tYm90dG9tOjNweDt9ZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX0Fycm93VXBfRGlzYWJsZWR7YmFja2dyb3VuZC1pbWFnZTp1cmwoImltZ3MvZGh4bWVudV9tYXRlcmlhbC9kaHhtZW51X2Fycm93X3VwX2Rpcy5wbmciKTt9ZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX0Fycm93RG93bixkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiBkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfQXJyb3dEb3duX092ZXIsZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX0Fycm93RG93bl9EaXNhYmxlZHtwb3NpdGlvbjpyZWxhdGl2ZTtmb250LXNpemU6MXB4O2JvcmRlci10b3A6MXB4IHNvbGlkICNkZmRmZGY7YmFja2dyb3VuZC1pbWFnZTp1cmwoImltZ3MvZGh4bWVudV9tYXRlcmlhbC9kaHhtZW51X2Fycm93X2Rvd24ucG5nIik7YmFja2dyb3VuZC1yZXBlYXQ6bm8tcmVwZWF0O2JhY2tncm91bmQtcG9zaXRpb246Y2VudGVyIDZweDtwYWRkaW5nOjhweCAwO21hcmdpbi10b3A6M3B4O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiBkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfQXJyb3dEb3duX0Rpc2FibGVke2JhY2tncm91bmQtaW1hZ2U6dXJsKCJpbWdzL2RoeG1lbnVfbWF0ZXJpYWwvZGh4bWVudV9hcnJvd19kb3duX2Rpcy5wbmciKTt9aWZyYW1lLmRodG1seE1lbnVfSUU2Q292ZXJGaXhfbWF0ZXJpYWx7cG9zaXRpb246YWJzb2x1dGU7Ym9yZGVyOm5vbmU7YmFja2dyb3VuZDojMDAwO2ZpbHRlcjpwcm9naWQ6RFhJbWFnZVRyYW5zZm9ybS5NaWNyb3NvZnQuQWxwaGEob3BhY2l0eT0xMDApO30uZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUuZGlyX2xlZnQgZGl2LmFsaWduX2xlZnR7ZmxvYXQ6bGVmdDt9LmRodG1seE1lbnVfbWF0ZXJpYWxfTWlkZGxlLmRpcl9sZWZ0IGRpdi5hbGlnbl9yaWdodHtmbG9hdDpyaWdodDt9LmRoeG1lbnVfc2tpbl9kZXRlY3R7cG9zaXRpb246YWJzb2x1dGU7bGVmdDowO3RvcDotMTAwcHg7bWFyZ2luOjA7cGFkZGluZzowO2JvcmRlcjowIHNvbGlkIHdoaXRlO3dpZHRoOjQwcHg7aGVpZ2h0OjEwcHg7b3ZlcmZsb3c6aGlkZGVuO31Aa2V5ZnJhbWVzIGRoeF9sb2FkZXJfcm90YXRlezEwMCV7dHJhbnNmb3JtOnJvdGF0ZSgzNjBkZWcpO319QGtleWZyYW1lcyBkaHhfbG9hZGVyX2Rhc2h7MCV7c3Ryb2tlLWRhc2hhcnJheToxLDIwMDtzdHJva2UtZGFzaG9mZnNldDowO301MCV7c3Ryb2tlLWRhc2hhcnJheTo4OSwyMDA7c3Ryb2tlLWRhc2hvZmZzZXQ6LTM1cHg7fTEwMCV7c3Ryb2tlLWRhc2hhcnJheTo4OSwyMDA7c3Ryb2tlLWRhc2hvZmZzZXQ6LTEyNHB4O319LmRlZmF1bHRUcmVlVGFibGV7bWFyZ2luOjA7cGFkZGluZzowO2JvcmRlcjowO30uY29udGFpbmVyVGFibGVTdHlsZXtvdmVyZmxvdzphdXRvOy13ZWJraXQtb3ZlcmZsb3ctc2Nyb2xsaW5nOnRvdWNoO3Bvc2l0aW9uOnJlbGF0aXZlO3RvcDowO2ZvbnQtc2l6ZToxMnB4Oy1raHRtbC11c2VyLXNlbGVjdDpub25lO30uY29udGFpbmVyVGFibGVTdHlsZVJUTCBzcGFue2RpcmVjdGlvbjpydGw7dW5pY29kZS1iaWRpOmJpZGktb3ZlcnJpZGU7fS5jb250YWluZXJUYWJsZVN0eWxlUlRMe2RpcmVjdGlvbjpydGw7b3ZlcmZsb3c6YXV0bztwb3NpdGlvbjpyZWxhdGl2ZTt0b3A6MDtmb250LXNpemU6MTJweDt9LnN0YW5kYXJ0VHJlZVJvd3tmb250LWZhbWlseTpSb2JvdG8sQXJpYWwsSGVsdmV0aWNhO2ZvbnQtc2l6ZTo7LW1vei11c2VyLXNlbGVjdDpub25lO2xpbmUtaGVpZ2h0OjI0cHg7fS5zZWxlY3RlZFRyZWVSb3d7Zm9udC1mYW1pbHk6Um9ib3RvLEFyaWFsLEhlbHZldGljYTtmb250LXNpemU6Oy1tb3otdXNlci1zZWxlY3Q6bm9uZTtiYWNrZ3JvdW5kLWNvbG9yOiNlZWU7Y29sb3I6IzM5Yzt9LmRoeHRyZWVfbWF0ZXJpYWwgLnNlbGVjdGVkVHJlZVJvd0Z1bGwgLmRoeFRleHRDZWxse2JhY2tncm91bmQtY29sb3I6I2VlZTtjb2xvcjojMzljO30uZHJhZ0FuZERyb3BSb3d7Y29sb3I6IzM5Yzt9LnN0YW5kYXJ0VHJlZVJvd19sb3J7dGV4dC1kZWNvcmF0aW9uOnVuZGVybGluZTtiYWNrZ3JvdW5kLWNvbG9yOjtmb250LWZhbWlseTpSb2JvdG8sQXJpYWwsSGVsdmV0aWNhO2ZvbnQtc2l6ZTo7LW1vei11c2VyLXNlbGVjdDpub25lO30uc3RhbmRhcnRUcmVlSW1hZ2V7aGVpZ2h0OjI0cHg7b3ZlcmZsb3c6aGlkZGVuO2JvcmRlcjowO3BhZGRpbmc6MDttYXJnaW46MDtmb250LXNpemU6MXB4O30uc3RhbmRhcnRUcmVlSW1hZ2UgaW1ne3dpZHRoOjE4cHg7aGVpZ2h0OjI0cHg7YmFja2dyb3VuZC1wb3NpdGlvbjpjZW50ZXIgY2VudGVyO2JhY2tncm91bmQtcmVwZWF0Om5vLXJlcGVhdDtib3JkZXI6MDtwYWRkaW5nOjA7bWFyZ2luOjA7Zm9udC1zaXplOjFweDstd2Via2l0LXVzZXItc2VsZWN0Om5vbmU7LWtodG1sLXVzZXItc2VsZWN0Om5vbmU7LW1vei11c2VyLXNlbGVjdDpub25lOy1tcy11c2VyLXNlbGVjdDpub25lOy1vLXVzZXItc2VsZWN0Om5vbmU7dXNlci1zZWxlY3Q6bm9uZTt9LmhpZGRlblJvd3t3aWR0aDoxcHg7b3ZlcmZsb3c6aGlkZGVuO30uZHJhZ1NwYW5EaXYsLmRyYWdTcGFuRGl2IHRke2ZvbnQtZmFtaWx5OlJvYm90byxBcmlhbCxIZWx2ZXRpY2E7Zm9udC1zaXplOjtsaW5lLWhlaWdodDo7dmVydGljYWwtYWxpZ246Y2VudGVyO2JhY2tncm91bmQtY29sb3I6d2hpdGU7ei1pbmRleDo5OTk7fS5kcmFnU3BhbkRpdiB0ZHtwYWRkaW5nOjVweDt9LmFfZGh4X2hpZGRlbl9pbnB1dHtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6LTFweDtsZWZ0Oi0xcHg7d2lkdGg6MXB4O2hlaWdodDoxcHg7Ym9yZGVyOm5vbmU7YmFja2dyb3VuZDpub25lO30uYV9kaHhfaGlkZGVuX2lucHV0e3Bvc2l0aW9uOmFic29sdXRlO3RvcDotMXB4O2xlZnQ6LTFweDt3aWR0aDoxcHg7aGVpZ2h0OjFweDtib3JkZXI6bm9uZTtiYWNrZ3JvdW5kOm5vbmU7fS5zZWxlY3Rpb25CYXJ7dG9wOjA7YmFja2dyb3VuZC1jb2xvcjpibGFjaztwb3NpdGlvbjphYnNvbHV0ZTtvdmVyZmxvdzpoaWRkZW47aGVpZ2h0OjJweDt6LWluZGV4OjExO30uaW50cmVlZWRpdFJvd3tmb250LXNpemU6OHB0O2hlaWdodDoxNnB4O2JvcmRlcjoxcHggc29saWQgc2lsdmVyO3BhZGRpbmc6MDttYXJnaW46MDttYXJnaW4tbGVmdDo0cHg7LW1vei11c2VyLXNlbGVjdDp0ZXh0Oy1raHRtbC11c2VyLXNlbGVjdDp0ZXh0O30uZGh4X3RyZWVfdGV4dFNpZ257Zm9udC1zaXplOjhwdDtmb250LWZhbWlseTptb25vc3BhY2U7d2lkdGg6MjFweDtjb2xvcjo7cGFkZGluZzowO21hcmdpbjowO2N1cnNvcjpwb2ludGVyO3RleHQtYWxpZ246Y2VudGVyO30uZGh4X3RyZWVfb3BhY2l0eXtvcGFjaXR5OjA7ZmlsdGVyOnByb2dpZDpEWEltYWdlVHJhbnNmb3JtLk1pY3Jvc29mdC5BbHBoYShvcGFjaXR5PTApOy13ZWJraXQtdXNlci1zZWxlY3Q6bm9uZTsta2h0bWwtdXNlci1zZWxlY3Q6bm9uZTstbW96LXVzZXItc2VsZWN0Om5vbmU7LW1zLXVzZXItc2VsZWN0Om5vbmU7LW8tdXNlci1zZWxlY3Q6bm9uZTt1c2VyLXNlbGVjdDpub25lO30uZGh4X2JnX2ltZ19maXh7d2lkdGg6MThweDtoZWlnaHQ6MjRweDtiYWNrZ3JvdW5kLXJlcGVhdDpuby1yZXBlYXQ7YmFja2dyb3VuZC1wb3NpdGlvbjpjZW50ZXI7YmFja2dyb3VuZC1wb3NpdGlvbi14OmNlbnRlcjtiYWNrZ3JvdW5kLXBvc2l0aW9uLXk6Y2VudGVyO30uZGh4dHJlZV9za2luX2RldGVjdHtwb3NpdGlvbjphYnNvbHV0ZTtsZWZ0OjA7dG9wOi0xMDBweDttYXJnaW46MDtwYWRkaW5nOjA7Ym9yZGVyOjAgc29saWQgd2hpdGU7d2lkdGg6NDBweDtoZWlnaHQ6MTBweDtvdmVyZmxvdzpoaWRkZW47fScsZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzdHlsZSk7dmFyIGxheWFhaXJfZGVidWdfdmlldz17fTt3aW5kb3cubGF5YWFpcl9kZWJ1Z192aWV3PWxheWFhaXJfZGVidWdfdmlldyxsYXlhYWlyX2RlYnVnX3ZpZXcuaW5pdExheWFBaXJEZWJ1Z1ZpZXc9ZnVuY3Rpb24oZSl7ZS5zdHlsZS5ib3JkZXI9IjFweCBzb2xpZCBibGFjayI7dmFyIHQ9TWF0aC5taW4oMjUwLC4zKmUub2Zmc2V0V2lkdGgpLGk9JzxkaXYgY2xhc3M9InRvcC1iYW5uZXIiPlxuPC9kaXY+XG48ZGl2PlxuPGRpdiBzdHlsZT0ib3ZlcmZsb3c6aGlkZGVuOyBib3JkZXItYm90dG9tOjFweCBzb2xpZCAjNDQ0OyBwYWRkaW5nOjVweCI+XG48ZGl2IHN0eWxlPSJmbG9hdDpsZWZ0Ij5cbjxidXR0b24gaWQ9Im5vZGVfZnVuY3Rpb25hbGl0eV9jb250cm9sIj7lrqHmn6XlhYPntKA8L2J1dHRvbj5cbjxidXR0b24gaWQ9InJlZnJlc2hfY29udHJvbCI+5Yi35pawPC9idXR0b24+XG48L2Rpdj5cbjxkaXYgc3R5bGU9ImZsb2F0OnJpZ2h0Ij5cbjxpbnB1dCB0eXBlPSJjaGVja2JveCIgaWQ9InNob3dfY3VycmVudF9jYWNoZV9jb250cm9sIj7mmL7npLpjYWNoZemHjee7mDwvaW5wdXQ+XG48aW5wdXQgdHlwZT0iY2hlY2tib3giIGlkPSJzaG93X2FsbF9jYWNoZV9jb250cm9sIj7mmL7npLpjYWNoZeWMuuWfnzwvaW5wdXQ+XG48aW5wdXQgdHlwZT0iY2hlY2tib3giIGlkPSJzaG93X2F0bGFzX2NvbnRyb2wiPuaYvuekuuaWh+Wtl+WbvumbhjwvaW5wdXQ+XG48L2Rpdj5cbjwvZGl2PlxuPGRpdiBjbGFzcz0iaGdyb3VwIj5cbjxkaXYgc3R5bGU9ImZsb2F0OmxlZnQ7d2lkdGg6Jyt0KydweDsgYm9yZGVyLXJpZ2h0OjFweCBzb2xpZCBibGFjayIgaWQ9InRyZWVfY29udGFpbmVyIj48L2Rpdj5cbjxkaXYgc3R5bGU9Im92ZXJmbG93OmhpZGRlbiI+XG48ZGl2IGlkPSJjb250ZW50X3Rvb2xiYXIiIHN0eWxlPSJ3aWR0aDoxMDAlO21hcmdpbjoxMHB4Ij48aW5wdXQgdHlwZT0iY2hlY2tib3giIGlkPSJ2aXNpYmlsaXR5X2NvbnRyb2wiPuWPr+ingTwvaW5wdXQ+XG48aW5wdXQgdHlwZT0iY2hlY2tib3giIGlkPSJzaG93X2JvcmRlcl9jb250cm9sIj7mmL7npLrovrnmoYY8L2lucHV0PlxuPGJ1dHRvbiBpZD0ibG9nX2luZm9fY29udHJvbCI+5omT5Y2w5Yiw5o6n5Yi25Y+wPC9idXR0b24+XG48YnV0dG9uIGlkPSJlbmFibGVkX25vZGVfY2hhaW5fY29udHJvbCI+ZW5hYmxl6ZO+PC9idXR0b24+XG48YnV0dG9uIGlkPSJzaXplX2NoYWluX2NvbnRyb2wiPnNpemXpk748L2J1dHRvbj5cbjwvZGl2PjxkaXYgc3R5bGU9Im92ZXJmbG93OmF1dG8iPjx0YWJsZSBpZD0iY29udGVudF90YWJsZSIgc3R5bGU9ImJvcmRlcjoxcHggc29saWQgI2NjY2NjYztib3JkZXItY29sbGFwc2U6Y29sbGFwc2UiPjwvdGFibGU+XG48L2Rpdj48L2Rpdj5cbjwvZGl2PlxuPC9kaXY+JztlLmlubmVySFRNTD1pLHRoaXMuY29udGFpbmVyPWUsdGhpcy50cmVlPW5ldyBkaHRtbFhUcmVlT2JqZWN0KHRyZWVfY29udGFpbmVyLCIxMDAlIiwiMTAwJSIsMCksbm9kZV9mdW5jdGlvbmFsaXR5X2NvbnRyb2wub25jbGljaz1mdW5jdGlvbihlKXtlLnN0b3BQcm9wYWdhdGlvbigpLGxheWFhaXJfZGVidWdfdmlldy5vbl9pbnNwZWN0X2VsZW1lbnRfY2FsbGJhY2soKSxub2RlX2Z1bmN0aW9uYWxpdHlfY29udHJvbC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3I9IiNGRkYiLG5vZGVfZnVuY3Rpb25hbGl0eV9jb250cm9sLnN0eWxlLmNvbG9yPSJyZ2IoMTA3LCAxNjMsIDI1NSkifX0sbGF5YWFpcl9kZWJ1Z192aWV3LnNldFRyZWU9ZnVuY3Rpb24oZSl7Zm9yKHZhciB0PXRoaXMudHJlZS5nZXRBbGxJdGVtc1dpdGhLaWRzKCkuc3BsaXQoIiwiKSxpPVtdLG49MDtuPHQubGVuZ3RoO24rKyl7dmFyIG89dFtuXSxyPXRoaXMudHJlZS5nZXRPcGVuU3RhdGUobyk7MT09ciYmaS5wdXNoKG8pfXRoaXMudHJlZS5kZWxldGVDaGlsZEl0ZW1zKDApLHRoaXMudHJlZS5wYXJzZShlLCJqc29uIik7Zm9yKHZhciBuPTA7bjxpLmxlbmd0aDtuKyspdGhpcy50cmVlLm9wZW5JdGVtKGlbbl0pfSxsYXlhYWlyX2RlYnVnX3ZpZXcucmVzaXplPWZ1bmN0aW9uKGUsdCl7dGhpcy5jb250YWluZXIuc3R5bGUud2lkdGg9ZSsicHgiLHRoaXMuY29udGFpbmVyLnN0eWxlLmhlaWdodD10KyJweCI7dmFyIGk9dGhpcy5jb250YWluZXIub2Zmc2V0SGVpZ2h0LXRyZWVfY29udGFpbmVyLm9mZnNldFRvcDt0cmVlX2NvbnRhaW5lci5zdHlsZS5oZWlnaHQ9aSsicHgiLGNvbnRlbnRfdG9vbGJhci5zdHlsZS53aWR0aD1lLXRyZWVfY29udGFpbmVyLm9mZnNldFdpZHRoKyJweCIsY29udGVudF90YWJsZS5wYXJlbnRFbGVtZW50LnN0eWxlLmhlaWdodD1pLWNvbnRlbnRfdG9vbGJhci5vZmZzZXRIZWlnaHQtMjErInB4Iixjb250ZW50X3RhYmxlLnN0eWxlLndpZHRoPWUtdHJlZV9jb250YWluZXIub2Zmc2V0V2lkdGgtMTYrInB4In0sbGF5YWFpcl9kZWJ1Z192aWV3LmJvdW5jZVVwSW5zcGVjdEJ1dHRvbj1mdW5jdGlvbigpe25vZGVfZnVuY3Rpb25hbGl0eV9jb250cm9sLnN0eWxlLmJhY2tncm91bmRDb2xvcj0iYnV0dG9uZmFjZSIsbm9kZV9mdW5jdGlvbmFsaXR5X2NvbnRyb2wuc3R5bGUuY29sb3I9ImJsYWNrIn0sbGF5YWFpcl9kZWJ1Z192aWV3LnNldFZhbHVlSW5wdXRIYW5kbGVyPWZ1bmN0aW9uKGUpe3RoaXMudmFsdWVfaW5wdXRfY2FsbGJhY2s9ZX0sbGF5YWFpcl9kZWJ1Z192aWV3LnNldFZhbHVlQ2hhbmdlSGFuZGxlcj1mdW5jdGlvbihlKXt0aGlzLnZhbHVlX2NoYW5nZV9jYWxsYmFjaz1lfSxsYXlhYWlyX2RlYnVnX3ZpZXcuYWRkQ29udGVudD1mdW5jdGlvbihlKXt2YXIgdD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJ0ciIpO3QuaW5uZXJIVE1MPSc8dGQgc3R5bGU9IndpZHRoOjEwMHB4O2ZvbnQtc2l6ZToxM3B4O2JvcmRlcjoxcHggc29saWQgI0NDQztwYWRkaW5nLWxlZnQ6MTBweCI+JytlLmtleSsnPC90ZD5cbjx0ZCBzdHlsZT0id2lkdGg6MjAwcHg7Ym9yZGVyOjFweCBzb2xpZCAjQ0NDOyI+PGlucHV0IHN0eWxlPSJib3JkZXI6bm9uZTt3aWR0aDoxMDAlO2hlaWdodDoyNXB4O3BhZGRpbmctbGVmdDoxMHB4OyIgdmFsdWU9JytlLnZhbHVlKyI+PC90ZD4iLGNvbnRlbnRfdGFibGUuYXBwZW5kQ2hpbGQodCk7dmFyIGk9dC5sYXN0RWxlbWVudENoaWxkLmxhc3RFbGVtZW50Q2hpbGQ7aS5kYXRhPWUsaS5vbmlucHV0PWZ1bmN0aW9uKGUpe3RoaXMudmFsdWVfaW5wdXRfY2FsbGJhY2smJnRoaXMudmFsdWVfaW5wdXRfY2FsbGJhY2soZS50YXJnZXQuZGF0YSxlLnRhcmdldC52YWx1ZSl9LmJpbmQodGhpcyksaS5vbmNoYW5nZT1mdW5jdGlvbihlKXt0aGlzLnZhbHVlX2NoYW5nZV9jYWxsYmFjayYmdGhpcy52YWx1ZV9jaGFuZ2VfY2FsbGJhY2soZS50YXJnZXQuZGF0YSxlLnRhcmdldC52YWx1ZSl9LmJpbmQodGhpcyl9LGxheWFhaXJfZGVidWdfdmlldy5zZXRDb250ZW50cz1mdW5jdGlvbihlKXtjb250ZW50X3RhYmxlLmlubmVySFRNTD0iIjtmb3IodmFyIHQ9MDt0PGUubGVuZ3RoO3QrKyl7dmFyIGk9ZVt0XTt0aGlzLmFkZENvbnRlbnQoaSl9fSxsYXlhYWlyX2RlYnVnX3ZpZXcuY2hhbmdlVmFsdWVBdD1mdW5jdGlvbihlLHQpe2NvbnRlbnRfdGFibGUuY2hpbGRyZW5bZV0ubGFzdEVsZW1lbnRDaGlsZC5maXJzdEVsZW1lbnRDaGlsZC52YWx1ZT10fSxsYXlhYWlyX2RlYnVnX3ZpZXcuY2hhbmdlVmFsdWVCeUxhYmVsPWZ1bmN0aW9uKGUsdCl7Zm9yKHZhciBpPWNvbnRlbnRfdGFibGUuY2hpbGRyZW4ubGVuZ3RoLTE7aT49MDtpLS0paWYoY29udGVudF90YWJsZS5jaGlsZHJlbltpXS5maXJzdEVsZW1lbnRDaGlsZC5pbm5lclRleHQ9PWUpe2NvbnRlbnRfdGFibGUuY2hpbGRyZW5baV0ubGFzdEVsZW1lbnRDaGlsZC5maXJzdEVsZW1lbnRDaGlsZC52YWx1ZT10O2JyZWFrfX0sbGF5YWFpcl9kZWJ1Z192aWV3LnNldFZpc2liaWxpdHk9ZnVuY3Rpb24oZSl7dmlzaWJpbGl0eV9jb250cm9sLmNoZWNrZWQ9ISFlfSxsYXlhYWlyX2RlYnVnX3ZpZXcuc2V0U2hvd0RlYnVnQm9yZGVyPWZ1bmN0aW9uKGUpe3Nob3dfYm9yZGVyX2NvbnRyb2wuY2hlY2tlZD0hIWV9LGxheWFhaXJfZGVidWdfdmlldy5nZXRWaXNpYmlsaXR5PWZ1bmN0aW9uKCl7cmV0dXJuIHZpc2liaWxpdHlfY29udHJvbC5jaGVja2VkfSxsYXlhYWlyX2RlYnVnX3ZpZXcuZ2V0U2hvd0RlYnVnQm9yZGVyPWZ1bmN0aW9uKCl7cmV0dXJuIHNob3dfYm9yZGVyX2NvbnRyb2wuY2hlY2tlZH0sbGF5YWFpcl9kZWJ1Z192aWV3LmdldFNob3dDdXJyZW50Q2FjaGU9ZnVuY3Rpb24oKXtyZXR1cm4gc2hvd19jdXJyZW50X2NhY2hlX2NvbnRyb2wuY2hlY2tlZH0sbGF5YWFpcl9kZWJ1Z192aWV3LmdldFNob3dBbGxDYWNoZT1mdW5jdGlvbigpe3JldHVybiBzaG93X2FsbF9jYWNoZV9jb250cm9sLmNoZWNrZWR9LGxheWFhaXJfZGVidWdfdmlldy5nZXRTaG93QXRsYXM9ZnVuY3Rpb24oKXtyZXR1cm4gc2hvd19hdGxhc19jb250cm9sLmNoZWNrZWR9LGxheWFhaXJfZGVidWdfdmlldy5vbkluc3BlY3RFbGVtZW50PWZ1bmN0aW9uKGUpe3RoaXMub25faW5zcGVjdF9lbGVtZW50X2NhbGxiYWNrPWV9LGxheWFhaXJfZGVidWdfdmlldy5vbkxvZ0luZm89ZnVuY3Rpb24oZSl7bG9nX2luZm9fY29udHJvbC5vbmNsaWNrPWV9LGxheWFhaXJfZGVidWdfdmlldy5vblJlZnJlc2g9ZnVuY3Rpb24oZSl7cmVmcmVzaF9jb250cm9sLm9uY2xpY2s9ZX0sbGF5YWFpcl9kZWJ1Z192aWV3Lm9uUHJpbnRFbmFibGVkTm9kZUNoYWluPWZ1bmN0aW9uKGUpe2VuYWJsZWRfbm9kZV9jaGFpbl9jb250cm9sLm9uY2xpY2s9ZX0sbGF5YWFpcl9kZWJ1Z192aWV3Lm9uUHJpbnRTaXplQ2hhaW49ZnVuY3Rpb24oZSl7c2l6ZV9jaGFpbl9jb250cm9sLm9uY2xpY2s9ZX0sbGF5YWFpcl9kZWJ1Z192aWV3Lm9uVG9nZ2xlVmlzaWJpbGl0eT1mdW5jdGlvbihlKXt2aXNpYmlsaXR5X2NvbnRyb2wub25jaGFuZ2U9ZX0sbGF5YWFpcl9kZWJ1Z192aWV3Lm9uVG9nZ2xlRGVidWdCb3JkZXI9ZnVuY3Rpb24oZSl7c2hvd19ib3JkZXJfY29udHJvbC5vbmNoYW5nZT1lfSxsYXlhYWlyX2RlYnVnX3ZpZXcub25Ub2dnbGVTaG93Q3VycmVudENhY2hlPWZ1bmN0aW9uKGUpe3Nob3dfY3VycmVudF9jYWNoZV9jb250cm9sLm9uY2hhbmdlPWV9LGxheWFhaXJfZGVidWdfdmlldy5vblRvZ2dsZVNob3dBbGxDYWNoZT1mdW5jdGlvbihlKXtzaG93X2FsbF9jYWNoZV9jb250cm9sLm9uY2hhbmdlPWV9LGxheWFhaXJfZGVidWdfdmlldy5vblRvZ2dsZVNob3dBdGxhcz1mdW5jdGlvbihlKXtzaG93X2F0bGFzX2NvbnRyb2wub25jaGFuZ2U9ZX07"; + + class AtlasTools { + constructor() { + this.mIndex = 0; + this.mTextureDic = {}; + } + static getInstance() { + return AtlasTools.mInstance = AtlasTools.mInstance || new AtlasTools(); + } + start() { + if (this.mSprite == null) { + this.mSprite = new Laya.Sprite(); + } + Laya.Laya.stage.addChild(this.mSprite); + this.showNext(); + } + end() { + if (this.mSprite) { + Laya.Laya.stage.removeChild(this.mSprite); + } + } + showNext() { + if (this.mSprite == null) { + this.mSprite = new Laya.Sprite(); + } + Laya.Laya.stage.addChild(this.mSprite); + this.mIndex++; + var tTexture; + if (this.mTextureDic[this.mIndex]) { + tTexture = this.mTextureDic[this.mIndex]; + } + } + } + + class ObjTimeCountTool { + constructor() { + this.timeDic = {}; + this.resultDic = {}; + this.countDic = {}; + this.resultCountDic = {}; + this.nodeDic = {}; + this.resultNodeDic = {}; + } + addTime(sprite, time) { + IDTools.idObj(sprite); + var key; + key = IDTools.getObjID(sprite); + if (!this.timeDic.hasOwnProperty(key)) { + this.timeDic[key] = 0; + } + this.timeDic[key] = this.timeDic[key] + time; + if (!this.countDic.hasOwnProperty(key)) { + this.countDic[key] = 0; + } + this.countDic[key] = this.countDic[key] + 1; + this.nodeDic[key] = sprite; + } + getTime(sprite) { + IDTools.idObj(sprite); + var key; + key = IDTools.getObjID(sprite); + if (!this.resultDic[key]) + return 0; + return this.resultDic[key]; + } + getCount(sprite) { + IDTools.idObj(sprite); + var key; + key = IDTools.getObjID(sprite); + return this.resultCountDic[key]; + } + reset() { + var key; + for (key in this.timeDic) { + this.timeDic[key] = 0; + this.countDic[key] = 0; + } + ObjectTools.clearObj(this.nodeDic); + } + updates() { + ObjectTools.clearObj(this.resultDic); + ObjectTools.insertValue(this.resultDic, this.timeDic); + ObjectTools.clearObj(this.resultCountDic); + ObjectTools.insertValue(this.resultCountDic, this.countDic); + ObjectTools.insertValue(this.resultNodeDic, this.nodeDic); + this.reset(); + } + } + + class DebugConsts { + constructor() { + } + } + DebugConsts.CLICK_SELECT_COLOR = "#ff0000"; + DebugConsts.CANVAS_REC_COLOR = "#FF00FF"; + DebugConsts.RECACHE_REC_COLOR = "#00ff00"; + DebugConsts.SPRITE_REC_COLOR = "#ff0000"; + DebugConsts.SPRITE_REC_LINEWIDTH = 2; + + class NodeRecInfo extends Laya.Sprite { + constructor() { + super(); + this.recColor = "#00ff00"; + this.txt = new Laya.Text(); + this.txt.color = "#ff0000"; + this.txt.bgColor = "#00ff00"; + this.txt.fontSize = 12; + this.addChild(this.txt); + } + setInfo(str) { + this.txt.text = str; + } + setTarget(tar) { + this._tar = tar; + } + showInfo(node) { + this._tar = node; + if (!node) + return; + if (node.destroyed) + return; + this.graphics.clear(); + var pointList; + pointList = node._getBoundPointsM(true); + if (!pointList || pointList.length < 1) + return; + pointList = Laya.GrahamScan.pListToPointList(pointList, true); + WalkTools.walkArr(pointList, node.localToGlobal, node); + pointList = Laya.GrahamScan.pointListToPlist(pointList); + NodeRecInfo._disBoundRec = Laya.Rectangle._getWrapRec(pointList, NodeRecInfo._disBoundRec); + this.graphics.drawRect(0, 0, NodeRecInfo._disBoundRec.width, NodeRecInfo._disBoundRec.height, null, DebugConsts.RECACHE_REC_COLOR, 2); + this.pos(NodeRecInfo._disBoundRec.x, NodeRecInfo._disBoundRec.y); + } + fresh() { + this.showInfo(this._tar); + } + clearMe() { + this._tar = null; + } + } + NodeRecInfo._disBoundRec = new Laya.Rectangle(); + + class ReCacheRecInfo extends NodeRecInfo { + constructor() { + super(); + this.isWorking = false; + this.mTime = 0; + this.txt.fontSize = 12; + } + addCount(time = 0) { + this.count++; + this.mTime += time; + if (!this.isWorking) { + this.working = true; + } + } + updates() { + if (!this._tar["displayedInStage"]) { + this.working = false; + this.removeSelf(); + } + this.txt.text = ClassTool.getNodeClassAndName(this._tar) + "\n" + "reCache:" + this.count + "\ntime:" + this.mTime; + if (this.count > 0) { + this.fresh(); + Laya.Laya.timer.clear(this, this.removeSelfLater); + } + else { + this.working = false; + Laya.Laya.timer.once(ReCacheRecInfo.showTime, this, this.removeSelfLater); + } + this.count = 0; + this.mTime = 0; + } + removeSelfLater() { + this.working = false; + this.removeSelf(); + } + set working(v) { + this.isWorking = v; + if (v) { + Laya.Laya.timer.loop(1000, this, this.updates); + } + else { + Laya.Laya.timer.clear(this, this.updates); + } + } + } + ReCacheRecInfo.showTime = 3000; + + class CacheAnalyser { + constructor() { + } + static renderLoopBegin() { + DebugInfoLayer.I.cacheViewLayer.graphics.clear(); + } + static get I() { + if (!CacheAnalyser._instance) { + CacheAnalyser._instance = new CacheAnalyser(); + } + return CacheAnalyser._instance; + } + static set I(value) { + CacheAnalyser._instance = value; + } + static getNodeInfoByNode(node) { + IDTools.idObj(node); + var key; + key = IDTools.getObjID(node); + if (!CacheAnalyser._nodeInfoDic[key]) { + CacheAnalyser._nodeInfoDic[key] = new ReCacheRecInfo(); + } + CacheAnalyser._nodeInfoDic[key].setTarget(node); + return CacheAnalyser._nodeInfoDic[key]; + } + renderCanvas(sprite, time = 0) { + if (!CacheAnalyser.showCacheSprite) + return; + if (DebugInfoLayer.I.isDebugItem(sprite)) + return; + DebugTool.showDisBoundToSprite(sprite, DebugInfoLayer.I.cacheViewLayer, DebugConsts.CANVAS_REC_COLOR, 4); + } + reCacheCanvas(sprite, time = 0) { + if (!CacheAnalyser.showRecacheSprite) + return; + if (DebugInfoLayer.I.isDebugItem(sprite)) + return; + var info; + info = CacheAnalyser.getNodeInfoByNode(sprite); + info.addCount(time); + CacheAnalyser.counter.addTime(sprite, time); + if (!info.parent) { + DebugInfoLayer.I.nodeRecInfoLayer.addChild(info); + } + } + } + CacheAnalyser.counter = new ObjTimeCountTool(); + CacheAnalyser._nodeInfoDic = {}; + CacheAnalyser.showCacheSprite = false; + CacheAnalyser.showRecacheSprite = true; + + class Notice extends Laya.EventDispatcher { + constructor() { super(); } + static get I() { + if (!Notice._instance) { + Notice._instance = new Notice(); + } + return Notice._instance; + } + static set I(value) { + Notice._instance = value; + } + static notify(type, data = null) { + Notice.I.event(type, data); + } + static listen(type, _scope, fun, args = null, cancelBefore = false) { + if (cancelBefore) + Notice.cancel(type, _scope, fun); + Notice.I.on(type, _scope, fun, args); + } + static cancel(type, _scope, fun) { + Notice.I.off(type, _scope, fun); + } + } + + class DButton extends Laya.Text { + constructor() { + super(); + this.bgColor = "#ffff00"; + this.wordWrap = false; + this.mouseEnabled = true; + } + } + + class DisplayHook { + constructor() { + this._matrix = new Laya.Matrix(); + this._point = new Laya.Point(); + this._rect = new Laya.Rectangle(); + this._event = Laya.Event.EMPTY; + this.isGetting = false; + this._stage = Laya.Laya.stage; + this.init(Laya.Render.context.canvas); + } + static initMe() { + if (!DisplayHook.instance) { + DisplayHook.instance = new DisplayHook(); + DisplayHook.selectNodeUnderMouse = DebugTool.selectNodeUnderMouse; + DebugTool.selectNodeUnderMouse = () => { + DisplayHook.instance.selectDisUnderMouse(); + DisplayHook.selectNodeUnderMouse(); + }; + } + } + init(canvas) { + if (window.navigator.msPointerEnabled) { + canvas.style['-ms-content-zooming'] = 'none'; + canvas.style['-ms-touch-action'] = 'none'; + } + var _this = this; + document.addEventListener('mousedown', (e) => { + this._event._stoped = false; + DisplayHook.isFirst = true; + _this.check(_this._stage, e.offsetX, e.offsetY, _this.onMouseDown, true, false); + }, true); + document.addEventListener('touchstart', (e) => { + this._event._stoped = false; + DisplayHook.isFirst = true; + var touches = e.changedTouches; + for (var i = 0, n = touches.length; i < n; i++) { + var touch = touches[i]; + initEvent(touch, e); + _this.check(_this._stage, _this.mouseX, _this.mouseY, _this.onMouseDown, true, false); + } + }, true); + function initEvent(e, event = null) { + _this._event._stoped = false; + _this._event.nativeEvent = event || e; + _this._target = null; + if (e.offsetX) { + _this.mouseX = e.offsetX; + _this.mouseY = e.offsetY; + } + else { + _this.mouseX = e.clientX - Laya.Laya.stage.offset.x; + _this.mouseY = e.clientY - Laya.Laya.stage.offset.y; + } + } + } + onMouseMove(ele, hit) { + this.sendEvent(ele, Laya.Event.MOUSE_MOVE); + return; + } + onMouseUp(ele, hit) { + hit && this.sendEvent(ele, Laya.Event.MOUSE_UP); + } + onMouseDown(ele, hit) { + if (hit) { + ele.$_MOUSEDOWN = true; + this.sendEvent(ele, Laya.Event.MOUSE_DOWN); + } + } + sendEvent(ele, type) { + if (!this._event._stoped) { + ele.event(type, this._event.setTo(type, ele, ele)); + if (type === Laya.Event.MOUSE_UP && ele.$_MOUSEDOWN) { + ele.$_MOUSEDOWN = false; + ele.event(Laya.Event.CLICK, this._event.setTo(Laya.Event.CLICK, ele, ele)); + } + } + } + selectDisUnderMouse() { + DisplayHook.isFirst = true; + this.check(Laya.Laya.stage, Laya.Laya.stage.mouseX, Laya.Laya.stage.mouseY, null, true, false); + } + getDisUnderMouse() { + this.isGetting = true; + DisplayHook.isFirst = true; + DebugTool.target = null; + this.check(Laya.Laya.stage, Laya.Laya.stage.mouseX, Laya.Laya.stage.mouseY, null, true, false); + this.isGetting = false; + return DebugTool.target; + } + check(sp, mouseX, mouseY, callBack, hitTest, mouseEnable) { + if (sp == DebugTool.debugLayer) + return false; + if (sp == DebugInfoLayer.I) + return false; + if (this.isGetting && sp == DebugInfoLayer.I) + return false; + if (!sp.visible || sp.getSelfBounds().width <= 0) + return false; + var isHit = false; + mouseEnable = true; + if (mouseEnable) { + var graphicHit = false; + if (hitTest) { + this._rect = sp.getBounds(); + isHit = this._rect.contains(mouseX, mouseY); + this._point.setTo(mouseX, mouseY); + sp.fromParentPoint(this._point); + mouseX = this._point.x; + mouseY = this._point.y; + } + if (isHit) { + var flag = false; + for (var i = sp._children.length - 1; i > -1; i--) { + var child = sp._children[i]; + (flag = this.check(child, mouseX, mouseY, callBack, hitTest, true)); + if (flag) + break; + } + graphicHit = sp.getGraphicBounds().contains(mouseX, mouseY); + isHit = flag || graphicHit; + if (isHit && !flag && DisplayHook.isFirst) { + DisplayHook.isFirst = false; + if (!(sp instanceof DButton)) { + DebugTool.target = sp; + if (!this.isGetting) { + DebugTool.autoWork(); + Notice.notify(DisplayHook.ITEM_CLICKED, sp); + } + } + } + } + } + return isHit; + } + } + DisplayHook.ITEM_CLICKED = "ItemClicked"; + DisplayHook.isFirst = false; + + class ClickSelectTool { + constructor() { + this._selectTip = new Laya.Sprite(); + this._selectTip.setSelfBounds(new Laya.Rectangle(0, 0, 0, 0)); + Notice.listen(DisplayHook.ITEM_CLICKED, this, this.itemClicked); + } + static get I() { + if (!ClickSelectTool._I) + ClickSelectTool._I = new ClickSelectTool(); + return ClickSelectTool._I; + } + beginClickSelect(complete = null) { + this.completeHandler = complete; + ClickSelectTool.isClickSelectState = true; + this.clickSelectChange(); + } + clickSelectChange() { + if (!Laya.Browser.onPC) + return; + this.tSelectTar = null; + this.clearSelectTip(); + if (ClickSelectTool.isClickSelectState) { + Laya.Laya.timer.loop(200, this, this.updateSelectTar, null, true); + } + else { + Laya.Laya.timer.clear(this, this.updateSelectTar); + } + } + clearSelectTip() { + this._selectTip.removeSelf(); + } + updateSelectTar() { + this.clearSelectTip(); + this.tSelectTar = DisplayHook.instance.getDisUnderMouse(); + if (!this.tSelectTar) { + return; + } + if (DebugInfoLayer.I.isDebugItem(this.tSelectTar)) + return; + var g; + g = this._selectTip.graphics; + g.clear(); + var rec; + rec = NodeUtils.getGRec(this.tSelectTar); + DebugInfoLayer.I.popLayer.addChild(this._selectTip); + g.drawRect(0, 0, rec.width, rec.height, null, DebugConsts.CLICK_SELECT_COLOR, 2); + this._selectTip.pos(rec.x, rec.y); + } + itemClicked(tar) { + if (!ClickSelectTool.isClickSelectState) + return; + if (ClickSelectTool.ignoreDebugTool) { + if (DebugInfoLayer.I.isDebugItem(tar)) + return; + } + DebugTool.showDisBound(tar); + if (this.completeHandler) { + this.completeHandler.runWith(tar); + } + ClickSelectTool.isClickSelectState = false; + this.clickSelectChange(); + } + } + ClickSelectTool.isClickSelectState = false; + ClickSelectTool.ignoreDebugTool = false; + + class RenderSpriteHook { + constructor() { + } + static init() { + if (RenderSpriteHook._oldCanvas) + return; + RenderSpriteHook._oldCanvas = Laya.RenderSprite["prototype"]["_canvas"]; + Laya.RenderSprite["prototype"]["_canvas"] = RenderSpriteHook["prototype"]["_canvas"]; + } + _canvas(sprite, context, x, y) { + var _cacheStyle = sprite._cacheStyle; + var _next = this._next; + var _repaint; + if (!_cacheStyle.enableCanvasRender) { + RenderSpriteHook._oldCanvas.call(this, sprite, context, x, y); + return; + } + if (sprite._needRepaint() || (!_cacheStyle.canvas)) { + _repaint = true; + } + else { + _repaint = false; + } + var preTime; + preTime = Laya.Browser.now(); + RenderSpriteHook._oldCanvas.call(this, sprite, context, x, y); + if (_repaint) { + CacheAnalyser.I.reCacheCanvas(sprite, Laya.Browser.now() - preTime); + } + else { + CacheAnalyser.I.renderCanvas(sprite, Laya.Browser.now() - preTime); + } + } + } + RenderSpriteHook.IMAGE = 0x01; + RenderSpriteHook.FILTERS = 0x02; + RenderSpriteHook.ALPHA = 0x04; + RenderSpriteHook.TRANSFORM = 0x08; + RenderSpriteHook.CANVAS = 0x10; + RenderSpriteHook.BLEND = 0x20; + RenderSpriteHook.CLIP = 0x40; + RenderSpriteHook.STYLE = 0x80; + RenderSpriteHook.GRAPHICS = 0x100; + RenderSpriteHook.CUSTOM = 0x200; + RenderSpriteHook.ENABLERENDERMERGE = 0x400; + RenderSpriteHook.CHILDS = 0x800; + RenderSpriteHook.INIT = 0x11111; + RenderSpriteHook.renders = []; + + class SpriteRenderHook { + constructor() { + this._repaint = 1; + this._renderType = 1; + } + static init() { + if (SpriteRenderHook.I) + return; + SpriteRenderHook.I = new SpriteRenderHook(); + SpriteRenderHook.setRenderHook(); + } + static setRenderHook() { + Laya.Sprite["prototype"]["render"] = SpriteRenderHook.I.render; + } + static showDisplayBorder(sprite, ifShowBorder = true) { + sprite[SpriteRenderHook.ShowBorderSign] = ifShowBorder; + } + static isDisplayShowBorder(sprite) { + return sprite[SpriteRenderHook.ShowBorderSign]; + } + render(context, x, y) { + if (this == Laya.Laya.stage) { + CacheAnalyser.renderLoopBegin(); + } + var preTime; + preTime = Laya.Browser.now(); + if (this[SpriteRenderHook.ShowBorderSign]) { + DebugTool.showDisBoundToSprite(this, DebugInfoLayer.I.cacheViewLayer, DebugConsts.SPRITE_REC_COLOR, DebugConsts.SPRITE_REC_LINEWIDTH); + } + Laya.RenderSprite.renders[this._renderType]._fun(this, context, x + this._x, y + this._y); + this._repaint = 0; + RenderAnalyser.I.render(this, Laya.Browser.now() - preTime); + } + } + SpriteRenderHook.ShowBorderSign = "ShowBorderSign"; + + class JSTools { + constructor() { + } + static showToBody(el, x = 0, y = 0) { + Laya.Browser.document.body.appendChild(el); + var style; + style = el.style; + style.position = "absolute"; + style.top = y + "px"; + style.left = x + "px"; + } + static showToParent(el, x = 0, y = 0, parent = null) { + parent.appendChild(el); + var style; + style = el.style; + style.position = "absolute"; + style.top = y + "px"; + style.left = x + "px"; + } + static addToBody(el) { + Laya.Browser.document.body.appendChild(el); + } + static setPos(el, x, y) { + var style; + style = el.style; + style.top = y + "px"; + style.left = x + "px"; + } + static setSize(el, width, height) { + var style; + style = el.style; + style.width = width + "px"; + style.height = height + "px"; + } + static setTransform(el, mat) { + var style; + style = el.style; + style.transformOrigin = style.webkitTransformOrigin = style.msTransformOrigin = style.mozTransformOrigin = style.oTransformOrigin = "0px 0px 0px"; + style.transform = style.webkitTransform = style.msTransform = style.mozTransform = style.oTransform = "matrix(" + mat.toString() + ")"; + } + static noMouseEvent(el) { + var style; + style = el.style; + style["pointer-events"] = "none"; + } + static setMouseEnable(el, enable) { + var style; + style = el.style; + style["pointer-events"] = enable ? "auto" : "none"; + } + static setZIndex(el, zIndex) { + var style; + style = el.style; + style["z-index"] = zIndex; + } + static showAboveSprite(el, sprite, dx = 0, dy = 0) { + var pos; + pos = new Laya.Point(); + pos = sprite.localToGlobal(pos); + pos.x += dx; + pos.y += dy; + pos.x += Laya.Laya.stage.offset.x; + pos.y += Laya.Laya.stage.offset.y; + JSTools.showToBody(el, pos.x, pos.y); + } + static removeElement(el) { + Laya.Browser.removeElement(el); + } + static isElementInDom(el) { + return el && el.parentNode; + } + static getImageSpriteByFile(file, width = 0, height = 0) { + var reader; + reader = new FileReader(); + reader.readAsDataURL(file); + var sprite; + sprite = new Laya.Sprite(); + reader.onload = function (e) { + var txt; + txt = new Laya.Texture(); + txt.load(reader.result); + sprite.graphics.drawTexture(txt, 0, 0, width, height); + }; + return sprite; + } + static getPixelRatio() { + if (JSTools._pixelRatio > 0) + return JSTools._pixelRatio; + var canvas = Laya.Browser.createElement("canvas"); + var context = canvas.getContext('2d'); + var devicePixelRatio = Laya.Browser.window.devicePixelRatio || 1; + var backingStoreRatio = context.webkitBackingStorePixelRatio || + context.mozBackingStorePixelRatio || + context.msBackingStorePixelRatio || + context.oBackingStorePixelRatio || + context.backingStorePixelRatio || 1; + var ratio = devicePixelRatio / backingStoreRatio; + console.log("pixelRatioc:", ratio); + JSTools._pixelRatio = ratio; + return ratio; + } + } + JSTools._pixelRatio = -1; + + class DebugPanel { + constructor() { + this.preValueO = {}; + this.height = 300; + this.width = 600; + this.dragArea = 10; + this.fromMe = false; + this._init(); + } + static enable(underGame = true, bgColor = "#ffffff") { + if (!DebugPanel._enable && !DebugPanel.I) { + DebugPanel._enable = true; + DebugPanel.overlay = !underGame; + DivScripts.init(); + DisplayHook.initMe(); + DebugTool.initBasicFunctions(); + RenderSpriteHook.init(); + SpriteRenderHook.init(); + DebugPanel.I = new DebugPanel(); + DebugPanel.I.setRoot(Laya.Laya.stage); + CacheAnalyser.showRecacheSprite = false; + if (bgColor) { + DebugPanel.I.div.style.background = bgColor; + } + } + } + static getSpriteTreeArr(sprite) { + var rst; + rst = {}; + rst[DebugPanel.LabelSign] = "" + ClassTool.getNodeClassAndName(sprite); + rst.target = sprite; + IDTools.idObj(sprite); + rst.id = IDTools.getObjID(sprite); + var childs; + childs = sprite._children; + var i, len; + len = childs.length; + var childsList; + childsList = []; + rst[DebugPanel.ChildrenSign] = childsList; + for (i = 0; i < len; i++) { + childsList.push(DebugPanel.getSpriteTreeArr(childs[i])); + } + return rst; + } + removeNoDisplayKeys(arr) { + var i; + for (i = arr.length - 1; i >= 0; i--) { + if (DebugPanel.noDisplayKeys[arr[i]]) { + arr.splice(i, 1); + } + } + } + updateShowKeys() { + DebugPanel.tObjKeys.length = 0; + if (!this.tShowObj) + return; + DebugPanel.tObjKeys = ClassTool.getObjectDisplayAbleKeys(this.tShowObj, DebugPanel.tObjKeys); + if (this.tShowObj == Laya.Laya.stage) { + this.removeNoDisplayKeys(DebugPanel.tObjKeys); + } + DebugPanel.tObjKeys.sort(Laya.MathUtil.sortSmallFirst); + } + static getObjectData(data) { + var dataList; + var tData; + var key; + var tValue; + var tType; + dataList = []; + var keys; + keys = DebugPanel.tObjKeys; + var i, len; + len = keys.length; + for (i = 0; i < len; i++) { + key = keys[i]; + tValue = data[key]; + tType = typeof (tValue); + if (key.charAt(0) == "_") + continue; + if (DebugPanel.displayTypes[tType]) { + tData = {}; + tData["key"] = key; + tData["value"] = tValue; + tData["type"] = tType; + dataList.push(tData); + } + } + return dataList; + } + _init() { + this.div = Laya.Browser.document.createElement('div'); + Laya.Browser.document.body.appendChild(this.div); + this.clickedHandler = new Laya.Handler(this, this.onClickSelected); + this.debug_view = Laya.Browser.window.layaair_debug_view; + this.debug_view.initLayaAirDebugView(this.div); + this.debug_view.tree.attachEvent("onSelect", (id) => { + var dataO; + dataO = this.getDataByID(id, this._treeDataList[0]); + if (dataO.target) { + DebugTool.showDisBound(dataO.target); + this.showTargetInfo(dataO.target); + } + }); + this.debug_view.setValueChangeHandler((data, new_value) => { + this.onValueChange(data, new_value); + }); + this.debug_view.onRefresh(() => { + DebugPanel.I.setRoot(Laya.Laya.stage); + }); + this.debug_view.onInspectElement(() => { + ClickSelectTool.I.beginClickSelect(this.clickedHandler); + }); + this.debug_view.onLogInfo(() => { + console.log(this.tShowObj); + }); + this.debug_view.onPrintEnabledNodeChain(() => { + DebugTool.traceDisMouseEnable(this.tShowObj); + }); + this.debug_view.onPrintSizeChain(() => { + DebugTool.traceDisSizeChain(this.tShowObj); + }); + this.debug_view.onToggleVisibility((selectd) => { + if (this.tShowObj) { + this.tShowObj.visible = this.debug_view.getVisibility(); + } + }); + this.debug_view.onToggleDebugBorder((selectd) => { + if (!this.tShowObj) + return; + SpriteRenderHook.showDisplayBorder(this.tShowObj, this.debug_view.getShowDebugBorder()); + }); + this.debug_view.onToggleShowCurrentCache((selectd) => { + CacheAnalyser.showRecacheSprite = this.debug_view.getShowCurrentCache(); + }); + this.debug_view.onToggleShowAllCache((selectd) => { + CacheAnalyser.showCacheSprite = this.debug_view.getShowAllCache(); + }); + this.debug_view.onToggleShowAtlas((selectd) => { + console.log("toggle show atlas:", this.debug_view.getShowAtlas()); + if (this.debug_view.getShowAtlas()) { + AtlasTools.getInstance().start(); + } + else { + AtlasTools.getInstance().end(); + } + }); + JSTools.showToBody(this.div, 0, 0); + this.initNewDivs(); + this.initDragWork(); + this.initTreeWidthDrag(); + Laya.Laya.stage.on(Laya.Event.RESIZE, this, this.adptPos); + this.adptPos(); + } + initNewDivs() { + var parentNode; + parentNode = Laya.Browser.document.getElementById("show_current_cache_control").parentNode; + var switchNode; + switchNode = Laya.Browser.createElement("input"); + switchNode.type = "checkbox"; + parentNode.appendChild(switchNode); + parentNode.append("右侧"); + function onSwitchChange(e) { + if (e.target.checked) { + DebugPanel.sideType = DebugPanel.Right; + } + else { + DebugPanel.sideType = DebugPanel.Bottom; + } + this.adptPos(); + } + switchNode.addEventListener("change", onSwitchChange.bind(this)); + } + static getOffset(e, sign) { + var target; + target = e.target; + var cTarget; + cTarget = e.currentTarget; + var kSign; + if (sign == "X") { + kSign = "offsetLeft"; + } + else { + kSign = "offsetTop"; + } + var value; + value = e["offset" + sign]; + while (target && target != cTarget) { + value += target[kSign]; + target = target.offsetParent; + } + return value; + } + initTreeWidthDrag() { + var leftDiv; + var rightDiv; + leftDiv = Laya.Browser.document.getElementById("tree_container"); + var parentNode; + parentNode = leftDiv.parentNode; + rightDiv = parentNode.children[1]; + var isMouseDown = false; + function onDivMouseMove(e) { + var abs; + abs = Math.abs(DebugPanel.getOffset(e, "X") - leftDiv.clientWidth); + if (abs < this.dragArea) { + this.div.style.cursor = "e-resize"; + } + else { + this.div.style.cursor = "auto"; + } + } + function onDivMouseDown(e) { + var abs; + abs = Math.abs(DebugPanel.getOffset(e, "X") - leftDiv.clientWidth); + if (abs < this.dragArea) { + this.div.style.cursor = "e-resize"; + isMouseDown = true; + } + else { + isMouseDown = false; + return; + } + e.stopPropagation(); + } + function onBodyMouseMove(e) { + if (!isMouseDown) + return; + leftDiv.style.width = DebugPanel.getOffset(e, "X") + "px"; + e.stopPropagation(); + } + function onDivMouseUp(e) { + if (!isMouseDown) + return; + isMouseDown = false; + e.stopPropagation(); + } + parentNode.addEventListener("mousedown", onDivMouseDown.bind(this), true); + parentNode.addEventListener("mousemove", onDivMouseMove.bind(this), true); + Laya.Browser.document.body.addEventListener("mousemove", onBodyMouseMove.bind(this)); + Laya.Browser.document.body.addEventListener("mouseup", onDivMouseUp.bind(this)); + } + initDragWork() { + var isMouseDown = false; + var preX; + var preY; + function onDivMouseMove(e) { + if (DebugPanel.sideType == DebugPanel.Bottom) { + if (DebugPanel.getOffset(e, "Y") < this.dragArea) { + this.div.style.cursor = "n-resize"; + } + else { + this.div.style.cursor = "auto"; + } + } + else { + if (DebugPanel.getOffset(e, "X") < this.dragArea) { + this.div.style.cursor = "e-resize"; + } + else { + this.div.style.cursor = "auto"; + } + } + } + function onDivMouseDown(e) { + if (DebugPanel.sideType == DebugPanel.Bottom) { + if (DebugPanel.getOffset(e, "Y") > this.dragArea) + return; + } + else { + if (DebugPanel.getOffset(e, "X") > this.dragArea) + return; + } + isMouseDown = true; + preX = e.pageX; + preY = e.pageY; + e.stopPropagation(); + } + function onBodyMouseMove(e) { + if (!isMouseDown) + return; + var curX; + var curY; + var dX; + var dY; + curX = e.pageX; + curY = e.pageY; + dX = curX - preX; + dY = curY - preY; + if (DebugPanel.sideType == DebugPanel.Bottom) { + this.height -= dY; + } + else { + this.width -= dX; + } + this.adptPos(); + preX = curX; + preY = curY; + e.stopPropagation(); + } + function onDivMouseUp(e) { + if (!isMouseDown) + return; + isMouseDown = false; + e.stopPropagation(); + } + this.div.addEventListener("mousedown", onDivMouseDown.bind(this), true); + this.div.addEventListener("mousemove", onDivMouseMove.bind(this), true); + Laya.Browser.document.body.addEventListener("mousemove", onBodyMouseMove.bind(this)); + Laya.Browser.document.body.addEventListener("mouseup", onDivMouseUp.bind(this)); + } + onClickSelected(target) { + if (!this._treeDataList) + return; + this.debug_view.tree.selectItem(IDTools.getObjID(target)); + this.debug_view.bounceUpInspectButton(); + } + updateLoop() { + if (this.tShowObj) { + this.showTargetInfo(this.tShowObj); + } + } + onSelectItem(obj) { + var tTarget; + tTarget = obj.target; + this.showTargetInfo(tTarget); + } + static mParseFloat(v) { + var rst; + rst = parseFloat(v); + if (isNaN(rst)) + return 0; + return rst; + } + onValueChange(obj, newValue) { + if (obj["type"] == "number") { + newValue = DebugPanel.mParseFloat(newValue); + } + if (obj["type"] == "boolean") { + newValue = newValue.toString() == "true"; + } + if (this.tShowObj) { + var key; + key = obj["key"]; + this.tShowObj[key] = this.preValueO[key] = newValue; + } + } + showTargetInfo(tTarget) { + if (!tTarget) + return; + this.debug_view.setVisibility(tTarget.visible); + this.debug_view.setShowDebugBorder(SpriteRenderHook.isDisplayShowBorder(tTarget)); + var i, len; + len = DebugPanel.tObjKeys.length; + var key; + if (this.tShowObj == tTarget) { + for (i = 0; i < len; i++) { + key = DebugPanel.tObjKeys[i]; + if (this.preValueO[key] != tTarget[key]) { + this.debug_view.changeValueByLabel(key, tTarget[key]); + } + } + } + else { + this.tShowObj = tTarget; + this.updateShowKeys(); + var dataList; + dataList = DebugPanel.getObjectData(tTarget); + this.debug_view.setContents(dataList); + } + for (i = 0; i < len; i++) { + key = DebugPanel.tObjKeys[i]; + if (key !== "__proto__") { + this.preValueO[key] = tTarget[key]; + } + } + } + adptPos() { + if (this.fromMe) + return; + this.fromMe = true; + if (DebugPanel.sideType == DebugPanel.Bottom) { + JSTools.setPos(this.div, 0, Laya.Browser.clientHeight - this.height); + this.debug_view.resize(Laya.Browser.clientWidth, this.height); + if (!DebugPanel.overlay) { + Laya.Laya.stage.setScreenSize(Laya.Browser.clientWidth * Laya.Browser.pixelRatio, (Laya.Browser.clientHeight - this.height) * Laya.Browser.pixelRatio); + } + } + else { + JSTools.setPos(this.div, Laya.Browser.clientWidth - this.width, 0); + this.debug_view.resize(this.width, Laya.Browser.clientHeight); + if (!DebugPanel.overlay) { + let newWidth = 0; + if (Laya.Browser.clientWidth > this.width) { + newWidth = (Laya.Browser.clientWidth - this.width) * Laya.Browser.pixelRatio; + } + Laya.Laya.stage.setScreenSize(newWidth, Laya.Browser.clientHeight * Laya.Browser.pixelRatio); + } + } + this.fromMe = false; + } + setRoot(sprite) { + var mtreeo; + mtreeo = DebugPanel.getSpriteTreeArr(sprite); + this._treeDataList = [mtreeo]; + var wraped; + wraped = {}; + wraped.id = 0; + wraped.item = [mtreeo]; + this.debug_view.setTree(wraped); + Laya.Laya.timer.loop(500, this, this.updateLoop); + } + getDataByID(targetID, nodeO) { + if (!nodeO) + return null; + if (targetID == nodeO.id) + return nodeO; + var childs; + childs = nodeO[DebugPanel.ChildrenSign]; + if (!childs) + return null; + var i, len; + len = childs.length; + var tRst; + for (i = 0; i < len; i++) { + tRst = this.getDataByID(targetID, childs[i]); + if (tRst) + return tRst; + } + return null; + } + getDataByTarget(target, nodeO) { + if (!nodeO) + return null; + if (target == nodeO.target) + return nodeO; + var childs; + childs = nodeO[DebugPanel.ChildrenSign]; + if (!childs) + return null; + var i, len; + len = childs.length; + var tRst; + for (i = 0; i < len; i++) { + tRst = this.getDataByTarget(target, childs[i]); + if (tRst) + return tRst; + } + return null; + } + } + DebugPanel._enable = false; + DebugPanel.ChildrenSign = "item"; + DebugPanel.LabelSign = "text"; + DebugPanel.displayTypes = { "boolean": true, "number": true, "string": true }; + DebugPanel.displayKeys = [["x", "number"], ["y", "number"], ["width", "number"], ["width", "number"], ["width", "number"], ["width", "number"], ["width", "number"], ["width", "number"], ["width", "number"], ["width", "number"], ["width", "number"]]; + DebugPanel.tObjKeys = []; + DebugPanel.noDisplayKeys = { "desginWidth": true, "desginHeight": true }; + DebugPanel.Bottom = "bottom"; + DebugPanel.Right = "right"; + DebugPanel.sideType = DebugPanel.Bottom; + + class Base64ImageTool { + constructor() { + } + static getCanvasPic(img) { + img = img.bitmap; + var canvas = Laya.Browser.createElement("canvas"); + var ctx = canvas.getContext('2d'); + canvas.height = img.height; + canvas.width = img.width; + ctx.drawImage(img.bitmap, 0, 0); + return canvas; + } + static getBase64Pic(img) { + return Base64ImageTool.getCanvasPic(img).toDataURL("image/png"); + } + static getPreloads(base64Data) { + var rst; + rst = []; + var key; + for (key in base64Data) { + rst.push({ url: base64Data[key], type: Laya.Loader.IMAGE }); + } + return rst; + } + } + + class Base64Atlas { + constructor(data, idKey = null) { + this.data = data; + if (!idKey) + idKey = Math.random() + "key"; + this.idKey = idKey; + this.init(); + } + init() { + this.replaceO = {}; + var key; + for (key in this.data) { + this.replaceO[key] = this.idKey + "/" + key; + } + } + getAdptUrl(url) { + return this.replaceO[url]; + } + preLoad(completeHandler = null) { + this._loadedHandler = completeHandler; + Laya.Laya.loader.load(Base64ImageTool.getPreloads(this.data), new Laya.Handler(this, this.preloadEnd)); + } + preloadEnd() { + var key; + for (key in this.data) { + var tx; + tx = Laya.Laya.loader.getRes(this.data[key]); + Laya.Loader.cacheRes(this.replaceO[key], tx); + } + if (this._loadedHandler) { + this._loadedHandler.run(); + } + } + replaceRes(uiObj) { + ObjectTools.replaceValue(uiObj, this.replaceO); + } + } + + class Base64AtlasManager { + constructor() { + } + static replaceRes(uiO) { + Base64AtlasManager.base64.replaceRes(uiO); + } + } + Base64AtlasManager.dataO = { "comp/button1.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGIAAABRCAYAAAApS3MNAAABSUlEQVR4Xu3a0QmFMADFUJ1JXM0h3moPZ6qg4AoNeLqAIenFn65jjLE40w2sQkxvcAMI0eggRKSDEEJUDEQ4/COEiBiIYFiEEBEDEQyLECJiIIJhEUJEDEQwLEKIiIEIhkUIETEQwbAIISIGIhgWIUTEQATDIoSIGIhgWIQQEQMRDIsQImIggnEvYvv9IzjfxDiP/XlgJsTcCyDEXP/v14UQImIggmERQkQMRDAsQoiIgQiGRQgRMRDBsAghIgYiGBYhRMRABMMihIgYiGBYhBARAxEMixAiYiCCYRFCRAxEMCxCiIiBCMa7iAjPpzG8fY3kF0KIiIEIhkUIETEQwbAIISIGIhgWIUTEQATDIoSIGIhgWIQQEQMRDIsQImIggmERQkQMRDAsQoiIgQiGRQgRMRDBsAghIgYiGBYhRMRABMMihIgYiGBcGJiOHTRZjZAAAAAASUVORK5CYII=", "comp/line2.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAAG0lEQVQYV2NkoDJgpLJ5DIxtra3/qWko1V0IAJvgApS1libIAAAAAElFTkSuQmCC", "view/create.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAkCAYAAAC9itu8AAAAdElEQVQ4T2NkwAIWLFjwH5t4QkICIyM2CXQxmAHka/j///9mXDYxMjL6YtgwBDUg+w8crIT8MBQ0oEca55JvWNPS9xgu4tISzADyNfz///8MnrRkgmHDENSALWng9fRQ0DA40xLecglbWhpqGoZCMUNKUQkANAHAJVkE5XwAAAAASUVORK5CYII=", "view/rendertime.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAkCAYAAAC9itu8AAABeUlEQVQ4T+2Uv0tCURSAvyNdcwiXBlsaaomWFgeHlqAtCPsDJHwIiUtDSxERtErtmQ6CjkHo4FpDBQ0tbVFR0BYE0eQvOnFF7T17QlOTd3m88873OD8+rtA9uVzOBIPBlIisAwvd8B1QajQahXQ63bIx6QHFYrEEJHrv7qeqZhzHOfYA+Xw+Yow5B+YHoGwymdxW1QAQEFWNAk8i8uEDuZM3gUcLZIEJYNcNqWrVcZyd7p9t8jLwYIFTYBx47UHlcjmcSCQ+B5JtpU0LnAFj3br7kE+yTalb4BCYczVqoT3AjteW4T73FlgFNgY+1IGQz4hPLGCAI2DGbweu2Auw1Vmcqk4C+8DsEOgZOBCR9/6mVdU2vgIsAdOuIVwANRFpezatuahpTYVSop1m+y6pasm8NQqSvvW61KwslkSHuCRkgvErr0taiUXaal1Sr0siWRO/9HfpF+RN9nfpB/qqmrXrv7mktVhYVm5GLo1cct9LI5e8d84/3UvfAgdlKH0EO7MAAAAASUVORK5CYII=", "view/cache.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAkCAYAAABSSLCCAAAAcElEQVQ4T2NcsGDB/4SEBEYGBgYGYtmMxCpENhhsA6mA8f///5tHNTEwkBcQpIYcSD15kUtWigi51vR/jVYdOGUQy2YkViGywWSnvTOkhiAonkY1gZIRqSEHTntkRe4g10RWQIyWe5Bgo2O5R7dkBADztyP+yFzirAAAAABJRU5ErkJggg==", "comp/clip_selectBox.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAoCAYAAAAIeF9DAAAAsElEQVRoQ+3ZQQ0AMQzEwAuqEgh/Sj2pKObhIrBsrfLonHPu12MMTEGYFg+kIFaPgmA9ClIQzQDG0w0pCGYAw2khBcEMYDgtpCCYAQynhRQEM4DhtJCCYAYwnBZSEMwAhtNCCoIZwHBmd/tTh6IUBIrx/tRbiFWkIFaPFoL1KEhBNAMYTzekIJgBDKeFFAQzgOG0kIJgBjCcFlIQzACG00IKghnAcFpIQTADGE4LwYL8U/BE1dCJ3PsAAAAASUVORK5CYII=", "comp/label.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAASCAYAAACQCxruAAAAmElEQVRoQ+3aMQqAQBBDUef+hx4Zq1mrbPnhWylECHmghVZ397OOqqp97TlugdNzgEXFIaaFuwROt0LmBEay5aXb920+FjIpMJItLy1wvhUyKTCSLS8tcL4VMikwki0vLXC+FTIpMJItLy1wvhUyKTCSLS89wPP1Qeh8M0zy+84gMMbruqjA15OxbtjAu7mPa5bj0fb/A8cLgD4n/wQKNiIAAAAASUVORK5CYII=", "comp/clip_tree_arrow.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAQCAYAAAArij59AAAAwUlEQVQoU5WRPRKCMBCFWUt6vYQeB06RUDpoBbFDa7yDwm30FGi9dHnOMiQDBgvT5c3b7+0PRVEUlVV9A3NmzL6T//SRfMz5CgCdtVafjlmzaHAigAbM2tE8YVo1pf0yvABoc9D3wACgBbMKIgD4qqDJsqqlMV8VGL5n/88geCJKlijSMBXFZUNx/CSi9WwX1r7R99thzKKqkxXRbMUWSE2u2sEwHsxHCbrMVSq6N4xRD9HAvJstylEkarhurlqnfQC58YP5+CvQNwAAAABJRU5ErkJggg==", "view/bg_panel.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAMUlEQVRYR+3QQREAAAjDMGZk/l2CDD6pgl7SduexGCBAgAABAgQIECBAgAABAgS+BQ4oyStBhXcy5AAAAABJRU5ErkJggg==", "view/bg_top.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAMUlEQVRYR+3QQREAAAjDMKZp/rWBDD6pgl7SduexGCBAgAABAgQIECBAgAABAgS+BQ6WyDMhXMLeQgAAAABJRU5ErkJggg==", "view/clickselect.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAqCAYAAACDdWrxAAACfElEQVRIS8WVO2iTYRSGn5OWqpMOurg0VRBdVVCsg7GgDjpZECyirl4GEYfSgBlaB5VSpApdxCJIoeKgg7dKC21ALahIiyiKKUjxAiI4qCH1lRP/hPhfAnHpGZPv+c4573nP95ukO/xHmINmtq8RtswsPiipB/gAPAFem5nCbcSWKukIsD84/A2YBh4DL8ysWLkk0qOkDcD5GLF+Ac+Ap35ZHGjAdWB5gtJvgZFYVSWdBHaFwBlg1Mw8K0ngFiAbAm+a2XBij/6HpBbgBrAEmAVeAZ1AFU40QDCWrcBZL0/S4Vq4HtgB7DWzU5XyauDBMhhWz70ryVVdb2ZuhGpI2g1MODjfiMFrxZk3s9WNwJ6snHFxQUlXgXfAPeC5mf2O2Y5oqZLcMceCw1+AseCSSTP7mSiOpM3A7RixfvgYgAd+WUQcSSnfPWBlgtIvgf5YVSVdBA6GQF/mS2bmWcvbERmHJF+payFw0MzO1TWApKXBViwL3h5/Pk4AVTjRAMFY9njJXl6wLccrcD3wAHDUzBwuRw18JtbkbkFJruomM7sf2o4u4Jals/mFRgxeFcfBQm97UyOwM+WMiwums/k3QnMps+HWpuLIRC5TCrcRW2pbT35MRiY4XDRsVmiU5uJQIZfxb0k5Ij229eQPySJ287MLGO8Rd1M0XY6AO3LjzYVSy3fAH+VICL4a6o9VtTWbnzbYGKI+IrtQ6Ns2EFuq/5jOTnWD9f4DikeFvvbqhyg2Yzo3voJSy2fAjfEJMYPRQQ2caAAfC7AW2WkvrzU79dCwnRW4Hjgg6JrrbV9VKbkKw1Csyd2Ca7on1y2krHOub3t16//2n79SarbsH7BKtfejoCjmAAAAAElFTkSuQmCC", "view/resize.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAqCAYAAACDdWrxAAABeUlEQVRIS+2UvUpdURCFvxXRKJpIEBURsVAIiiBoaaGCjY2VLyH4MBaCPoWlnQlpI6SxsQmkURQL5eK/6JK57iuRnMPZtxAkuOFUhzWz96xvjcg8tluAT5LOQqJMHba/AgPAD0nOEtruAOaB6Lon6U+ucAoYTLe7Bb5XCm1/BCaAXqAVOAHyOkYn27PA5/TGWmXHxvBeT2i7TVIM4MUp7ZhGPlY3V/pVKUxEjAIjyac74LIAjK70PwCoyfYXYDJwyqDoHtiRdFOfql0naBgIrILF/ZIi1yH6h1XbYXCPpKOq7s34GEX7JB00m445YBzYlPSQ1dF2N7CaWN2W9DNXuJxAj1uGVeuVQtvh32LyuR34DexWCv+CfAXoBzYkHb8Boe1OSRcFkBdfNY18IQiUtFUpTJjNAPEFHVfAaQFyjZ3zNBzbQ8BSWkZViEbk1uIpjXR8AKbT7jwEvpVUqEk6L0pHLN5hSWWxeq7XjI/v6Sgz0vZ7Ov7DdDwCkcb1m86tSukAAAAASUVORK5CYII=", "view/clickanalyse.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAqCAYAAACDdWrxAAAC7UlEQVRIS5WWT2hUZxTFfyfGFolkoUVKrHQiEaX+IfgHa54UQzUqpWYhLbQU6ULNwgYXuog6yiiTgK2LgtAu6yqbFkpRBEURQzJEBN200NqKkxoDLnQhFUrizJU7vje8SSbzZr7FwDy+c75z7z3nfU80uMxMDin9JC0zewvYAHwIrAH65wWaWQuwOdy8CVgUHnBd0sUKoJktBbYC24B1QHMVNeck3ZWZrYhtXpUg/3/gS0kzDnT2/cDqpFqBUUnnK5pjZutDgo01Tr0g6XbVrprZypBgO9AUU/EK+ErSyzLQzC5XkTkCfBR7fl/Smeh/qasOlPRp9DAkOgp8H5P9o6SriUAnMrOzgNdswNeSntcL9IYNAQ8kHYuXU5Y6u8ZIupldAO5I+nkOsNb8wjk/ljTZKFCSvMbSMrPSiOpNx9uAz3UP4IbfWSsdrcDH4eZuYHF46LCk47PT8S6wG9gbJmRhlfoPSLrhJvdERJs7E+S73dZKmnagsx8JB50UEHdY3+x0dIUEO2qcekTSr/OlY21I4N5dEJMwA6yX9CKejqkqGn8DemPPb0v6YrZXpyS1xYbsRD3AtZjsk5IuJQKdyMyGAa/ZnbNR0tN6gd6wXwAP8SfV0jGnxki6mV1xyf4ubdTkPue/Jf3TEJCMNZFRMQLtyNwqvaTrSkdHZry1MFM8bLLPgY5U8/SyeYHvncotb5b1A/t8c2QGg3sT2WBLBbD95PiGogr9Ej0Gbap8r4ZJ5kR+MPhW7WdGd5npEFaa15IE+YWW5uklf2S6/1N7OnfasG+Ad5KiAfyVzwYfVDQnlc71YTaA8Ntrvtq/y2eDgapdTZ0a60UMhjdvmcCgWDClJge7npSBqfRYYY5M6U/M/NqO1mQ+G7xf4VUH5rNBOXtviLQfzH0afizop0fZroOJQCdKpcfyUKrZFhTpfDgU/F4nMNcH9gPwLJ8Nls3xarUaI+mp9NhTg5GJbPBZQyb3OReayP17rutmHPga1PpCOk+zrlEAAAAASUVORK5CYII=", "view/res.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAoCAYAAAD6xArmAAADwUlEQVRIS+3WT2gcdRQH8O/b2SwNC7l4MAEPvbilUkoPOUmLjSDrZn4hxYKH/kGwyB4tQogiu/N+GymyoWguhVBQKKkHQTHsW9fUQwqKp4AgtMXkInhILl4CkoTdmSe/6XZp2pntLli8uMedt9/3mze/33yW8Jw+9Jxy0TeYmV8FcFVVTxPRiwA6AP5U1TvZbHapUqn8nrawxGBVJWvtNVWdJ6K05h1V/dhaW08KT/wRM1sAVQCRqn5JRLdyudw9Iora7faJKIrKqnrBNSWiahAEC0+GHwpm5utEdD+KopsuBMDbzPxt0oqstRdV9Za7lslkzlar1Z8erzsUHATBJhG93C34fmJi4ly5XG6nzTEIgjoRzanqkrX2amowM98F8Fq3wK34PWb+Ii14cXExv7e3V6hWq78+axQrANwt/kVEl5j5h0G2IzMfUdWCtfa3R/VPzvhTAG8AOM/MfwwYehTANwB+ZOYPE4ODIDhJRJvMvD9IqLW2GEXRbSJ6AcBtZr6UGPzoS2Y+lc/nt+bm5v5Oa2CtvaKqywC8bs06M7+eGszMn7nTBqDOzPNpwcvLyyPb29vfAZh2Naq6Za0tpAbXarUzURS53eGKL1trv0oKZ+a3AHytqplMJlOOoui4tfaDvqOw1lZUtabubBOtqOqN0dHRB/v7++62XwHwDoB33dkAUGPmoO92e/yitXZeVT8BkE1acbdpPQiCj4hIBw52hQsLC8c6nc77AN4E8FK3yQ4R/Qzgc2b+Je0ZDPU+fjiZp1eXFD5U8CB7u+/DGybgXxnFMA3/m1GISGwegNMAeuYBuON53lKpVBrePBG5RkTuSPc1b2ZmZnDzRKRnHoDYvIODg3u5XM69/E8AKAO40G1aNcb0N6/ZbF5X1fsAbjpInXnGmETzGo3GRdew+0DPGmPSzRORTQA988bHx89NTk6mmtdoNGLziGjJ9/1085rN5l1VPWSeMSbVvLW1tXwYhoXp6en+5olIbB6A2Dzf9wcyb319/cju7m5hdnY22TwRic3zPO98qVQayLxWq3U0DMPYPGNMsnmrq6snx8bGNqempgYyT0SKzjoAsXnGmP7mNZvNU9lsdqtYLKaaJyJXABwyzxiTbp6IxOYRUd33/VTzNjY2RnZ2dnrmAdgyxqSbJyJnAMTmEdFl3/cTzROR2DzHk6qWiei4Maa/eSJScZY99FRXPM+7MTIy8iAMQ6/dbsfmEVHPPGPM4OaJiBtDqnmuqfuL4Pv+8Oa1Wq1jYRg+ZR6A2DxjzP/mPRupfwAf56Q4urCh6QAAAABJRU5ErkJggg==", "view/tab_panel.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAABICAYAAADyMAW8AAAAcUlEQVRYR+3WsQ3AMAhE0TCMeyTvP1tShRQo7lxYegxA8fUPLuac97VhwuKXKhTlFxRQ9GPDClawYvGEDwxIZu7pFRZXr4ACinY1ghWsYMX/NxWQr22edyvGGHt6hcV1NqGAon8QVrCCFYteISDnBuQB3xJuQcDkEngAAAAASUVORK5CYII=", "view/btn_close.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAqCAYAAACz+XvQAAACmUlEQVRIS7WWS0/bUBCFz7mJmyZxENm06mNVoVZC7LqGn9FNqy55/BSWSEhs2/4uuqFVoA150JLKJvGdaiIH2TfXNoKQpeP5PHPO3GMTK/5xxTwsAUWkBeBZ+qAByb/Zh4pIA8CL9NqY5Dj7vw9YA/ABwDsAfwB8ITnUIhF5CuATgNcAfgH4RnJSCkwLl6AA/lXBtLZQQxFxoTr6q6LOFl2WmuJAtcY7ZuXIixsczfRyTlPfhpSN7BpwBeBtFdQLFJE2gI8AXi7GBBBl3Fdnv5L87XbpWxuFfQbw3NXM0dQLLdrDIH3ylGTiLLYB8CS9lpCc3tmU+xzL1Z9lEXl/n06KavjowCiK1uM4fqMd1Ov1s3a7fZntZjabtSeTiQYHgiC4aLVavZwpbofT6TQYDAaH1tod3bMwDHc7nc5PLZrNZmG/3z8WkS1jzGm32z1oNBqjUqD+6YM2m81xFWyeNkUaulAAlyKyWdTZbdqUmZKFakEVrLRDV7P5zY6m3rQp6tA1AMC5tXY7he51Op0fdwbGcdwdDodHWc2MMdcL9wGM1tbW9sMw/L6UNm6HChuNRifW2g1XM0dTL3TJZS1KkkTDFbVaLQqCIJcm6k0URRpxuvg39Xo9rtzDh5zt1Z/lXq+32rR5dKC1dt0YM08bAGd65BxN1ZB52ojIBcl82rgdWmsDkocAdgDoW22X5DxtSIZJkhyT3AJwCuCAZD5tfCP7oMaYcRVs/tAiDT1QHX2zqLPbtCkzxYFqjXfM3GKXAR3NtC6nqTccioAeA84BbCuU5B4Af9r4gCLSBXCU1UxErjPuj0Rk3xiznDYuMIWdANhwNXM09UKXXNai9LtQ9y4yxuS/XUijr9L0lXBDMp82j370HhJdWvsftiHJYFPSIqEAAAAASUVORK5CYII=", "comp/combobox.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFsAAABCCAYAAAA476rKAAACfElEQVR4Xu3bMYsTURQF4PMmExgIWkgEU5hskyJYxGYKY5VS7NzCylL8Bftj3NbKQjuxTBWbaUwhKdIYLCJotlACA5m8kQTZZZkkeN9dbuNJOXPPu/DN5ZHkMa7dbpfgx0TAEdvEedeE2HbWxDa0JjaxLQUMe3HPJrahQECrNE3RarUOJheLBbIsq9znZAdgJ0mC4XCIer1eSa/Xa4xGI+R5TuwA272RTqeDfr9fuTeZTDCfz/dmONkK/cFggGazebnCcrnEeDw+uCKxFdiNRmO3nURRBO/9bvtYrVbEVpgejXa7XfR6PUynU8xms6O1nGzlU3DO7fbu7V5dlsf/0yO2ElsSJ7ZES1lLbCWgJE5siZaylthKQEmc2BItZS2xlYCSOLElWspaYisBJXFiS7SUtcRWAkrixJZoKWuJrQSUxIkt0VLWElsJKIkTW6L1t5an6wFooRGerofKBeZ4uh4IFxrj6XqoXECOp+sBaJoIT9c1esIsT9eFYFbl/J5tJc13agyliU1sWwHDbtyziW0oYNiKk22JfXJ6xnfXjcDdFttnb43a/b9tovQ5iG30/IltBL1tQ2xiGwoYtuJkE9tQILBV/ugl4rh2MF1sPJJP59fuc7IDsTe37mHz8Bki+MoKHhFqn9+j9vs7sQN9K7G89xRx837levHzG5Lph8p1TrZK3iF//ApxdLVI4YFk/BpA9Uc5sVXYwObOCfyDJ3AoUcIh+vIRtYuve1clthJ7G8/7p4hv30Xx6weSybuDKxL7BrARxcjTF0iyN4AviH0Tpto1ONlaQUGe2AIsbSmxtYKCPLEFWNpSYmsFBXliC7C0pZfY2oWY/zeBP8uaLni/AFTVAAAAAElFTkSuQmCC", "comp/textinput.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFsAAAAWCAYAAACv8OArAAAAZElEQVRYR+3UQQkAMAwEwcZI/LtsoSL2NTGwMByZ3b3HJQIDO3H+EdidNezQGjbsUiBs+dmwQ4EwZdmwQ4EwZdmwQ4EwZdmwQ4EwZdmwQ4EwZdmwQ4EwZdmwQ4EwZdmwQ4Ew9QBe0R29X9x+dwAAAABJRU5ErkJggg==", "comp/vscroll.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAhCAYAAAA/F0BXAAAAOklEQVRIS2N8+OzVf2YWFgYmJiYGcgHjqCEYQTcaJpipaTRMRsOEmDJmNJ2MppPRdEJMCIymE2JCCQAYonwDuu2VMAAAAABJRU5ErkJggg==", "comp/vscroll$down.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAzCAYAAABxCePHAAAC/klEQVRIS+2WS0wTURSG/zszBcrLFVvjio0LiAqRRDAmGpRodFE1MQQQkOKGqBujRo3ExLjB4MaKgDzUaGQhvoJGYwAjYoioERcuDGxYEIwPkBY6nWvObXuLnXZaSklYOIu5M/fxzZn/nvPPsInJKa5qGhRFQaIH+w8xSbcymtTd+gBFYXAdyjM9sf7ORxgGR0t5/j9jpkhq2t5B0xQwBrgqNsnJ9V0j4BzQdQNtNYXWkKz0NDiaXkBTFTCFoaWmCHVtQ+AGh+4z0HNiO2bmPNYQGiXQvkuPoaqqiIgi8Pl8eHBqtwlA86MKS6Cy8z1gjIFzjqcXHBEBlpBgRNuOd+HVlYqogJiQIChcg/BtW5k8SaSSkxPJ5PRPTttHfkI7kcghIpn8NYfp33NLXp+TnYG1OWvA3ox9499nPSjdkCsgHJxOIjc43VMrugL9dEUD4Oj/PA4CsUfDX/jOjbmisHTDCCzi4t4QgLDrQF+qTYOmqhgYGw9BvLpv0ZNjQwieaU9b7ZCDriFhSt3VBSZNartHA6aUJ7SK+jqO5n5pSp1HiqSw1e3Di0ypwBpiU1XsudwnTanraDEqrg2GmZLbGkJh2jQVZY29JlPqPe03JX/uxLE7Nk3DjjP3pCn1Ne7HrNsjdYoLQsmWYtNQ3NCBgeZKzLrn/foEoogbQgvSUmz4454P7VQikGhpHzGSZdVOUqqYTGli6gemZ9yJ+0lSTalk/TrxtQOYaBnESbTinokev4UG+p+9/xoyJQKQn8x7vf7JjEFZ1FJBBvuC12RINIdAwtkIQuksnxgHhKBUZ6scQtLSNyiWJpav47z9STjbjfJ8k5iVN0eEs911bhZjUTWpbR+RztZ6uFBERNCq1rfS2e43lFhDsjPscDS9lM7W4dyCquuvpbM9PFkq0iHm7mSl2yP+bj05uxdeXZe5FHOL6Xdr17nQ79bziwew4NXFqwUTMiaEtKBPwtZjnRi8WgXPglfqsyQITc60pwpAeNpH1GRZtRM0pWVVcTJM6S+dYaRsIf025wAAAABJRU5ErkJggg==", "comp/vscroll$bar.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAA/CAYAAAAGyyO8AAABYElEQVRYR+2Wv0sDMRTH30tarCg6dRWnQnFT6OiqoP+tk+Cig+AiHayDiNSlg+jgD47K1US+Lwm5s4o/mkElN1xy73KfcF/efTi+Ht3Y0X1Btw8FffdoLy3QSnuZ+HhwZe+exrS13hGGJYsTWSszN0rJ1zHDDbJ0eDYkgHjv5Nxub3TIGEsTY/xDVq6NAN7MfW2u2aCG1nQ0GEZIOXmp7Pw5BPDF+VaGIGQfbM6k0ng5kw8/wF/eJzP5JInZkjg2CSS8zk6vCys7Wb8r5qqsncAP+pdR1Lu9rvgVT4uYg+3F+PCtAzjzu/taKdKKBSS2/wkEMBg/Q+rB50zqzZb7ZPoD/GeZ1HySxGxJHJsEEl5nc22VmCFalpFJTjLKNUtFxlDfP72IogYAP8PPZekWM5OqjErFWpjjbxprABJRA/JYjOOOX4Bgo6bWGYKsfMg5k+lmy5n8uUxm8kkSs6Vw7Cstibc9Fv5vWQAAAABJRU5ErkJggg==", "comp/vscroll$up.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAzCAYAAABxCePHAAADF0lEQVRIS92WTUhUURTHz31vPv0KKmkXrtxUGNomkCANLdCUpEatJFuIClIEFRl9kGH0BYWQElLpotGKEJXAtKQooYUFpi1axLQZMCyyZJqv926cM2/uTM288emoUHfx3v16v3fuuef+72Hume/c7/cBAwaLKWaLBZjLPc0Zk0CSJGBs4SDOObDP7i9ckuXkIbLJRJDFFrJk2SGNvZNwy7ExoZEJLWnqfQ+4SlUFaHNs0gXpQhq6x0GWGe0Y7oCicGivyYsLigup7XgFJlkCJjFwNm2HqrZR4CqHoKLC3fr8GFAMpPLqEJhMoZjpay6Bnx4vpKfYoLx1kCwKBlXoOV78BygGsudCH1nwtNVBgHBBUFFzL1n0+Gx5YghOxhINiAbFG1uZODESxf+bJShKrulv8HUusp1G/IBz1qTZIGvdamBjU584Aopzs+lbDhwfFFgc2/imLq0fazgAHF5MumBtuh3YwJsPfGdeNqgY1qqqfcSprRLgr7rWZzWbwCTL8HLKFYEEgkrUn+eHIDzNbltBSG33O+jcnxNZmrYcw5Yc7hoXotRenRPyz0IgBzrGYkTp9qEtxiEV10eEKD08Wgh7bzwTonSvIV/soK5jd53rE6I0eGY3/PL5wWYxQ+nFgShRKqK6LqTwhJNEafRKNQHCcWK3WmDHqR5NlMoSQzAWUV+9vkBMsKXYLCSbs3Oe+SGqqupGrIL3h3YclifYkjo7yZ7izIzUUGrhnvXAzA+PURkR8xCwPnMVsCUVpW0bsiCUKOH9S0980JvaLJSQUTal9Q+9/RgRJQSgnvgCgdBkxkCKektSpC9cR0HCOQgiZUMI3njijwYg+COzLP9rkLr7E3Dn4Gbhp7BPDC+n0TkhlK2zJpccuSBIfVdsutVdt9U4pLbjtVC2B0cKYN/N50LZHh0rFGGguztV14aFsvWfLiVhSrVboaSlXyjbk/NlBNKFVLT0k7INX3KAx+sXfkBlKzjpJItGLlcmhmSkptAB83h9MTuCICxBRUkMwUmY5+uFPY7LmJ7GW05SZycsSos9xUsmSr8BfgGeWI6+BgEAAAAASUVORK5CYII=", "comp/button.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAE0AAABFCAYAAAAPWmvdAAABA0lEQVR4Xu3ZMRGDUBRFwXwfKSgxFhfRgAbUxEakkCEO3qmX+p9m5w7NW9v7cz18I4EFbeT1fwxtbgYtmEGDVgRC458GLQiExNKgBYGQWBq0IBASS4MWBEJiadCCQEgsDVoQCImlQQsCIbE0aEEgJJZW0Pbj64Q3hFvQhmL3CQ8atLlAKCwNWhAIiaVBCwIhsTRoQSAklgYtCITE0qAFgZBYGrQgEBJLgxYEQmJp0IJASCwNWhAIiaUVtOfrdMIbwi1oQ7H7hAcN2lwgFJYGLQiExNKgBYGQWBq0IBASS4MWBEJiadCCQEgsDVoQCImlQQsCIbE0aEEgJJYGLQiExNIC2g/MxaMp6CSauwAAAABJRU5ErkJggg==", "view/bg_tool.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAMklEQVRYR+3QQREAAAjDMCYG/DsEGXxSBb2ke7YeiwECBAgQIECAAAECBAgQIEDgW+AAAeIuAVS/mngAAAAASUVORK5CYII=", "comp/minBtn.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAA8CAYAAAB1odqiAAAArUlEQVRYR+3X0QmAMAwE0GQN19B9nM193CmiIH7ZXOAoRc/fpjl8jVDdOj/eOc8USBcXqUjLAtDQRMSOdHb3JatTYCZUXodIy10bGxTI1Lx6/YA0Ima6W2tKFcjmdpGKtCow7NBAdxozy+804Gfx/cDqbLzWDzs0ekNY4B9nOMEehMKTVIEEyKeFSKmc18+MppRtipJuYPCa1SkwEyqvo6Tlxm8bFEijvBt9n/QA/fOPydLHcUIAAAAASUVORK5CYII=", "view/zoom_out.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAoCAYAAAD6xArmAAACy0lEQVRIS92WQU8TQRTH/28oQkj0CL0QOMAJQkz4DkS6A+GA+A00Hrhj0uy8NiTwEdBPAOrB0Fnq3U8g6gkOSjxUjpCQCu08M5u2qaVAt7YmOqfNZPa3b9/+Z35L6NOgPnHx98Gbm5sTlUplA0AGQBpACcBBKpXazmaz3+5607YVM/MjEXlNRPdbASJyTkRrzPz+Nvg1MDNPAvgI4AGA10qpvHPuSCk17ZwLAazV4HPM/PUmeDvwSwBPAbxl5sf+RmYWZo7XMvOehwPYYebnScAnAMaVUrNhGH5pBefz+Rnn3GcAJ8w8kQT8E8A9AEMA/HXrqM9fMrO/bjvataJvFdd7/IaZfS9/67ExZpeIngB4xczPklQ8KSKHPmoispdKpXKjo6PHp6enU5VKxXhoV6moVXhnjpVS5wDOwjD81K7qG7e033lXV1cviMjvvDEAP0TkYHBwcKtarT4UkXcALolo1RhTaIV3dVYYY9aIyOfZDw9fMcYUm+FdgWvtYgCmBisrpRbCMPxQh3cNbgM3zJzvCdhDcrncuojMA8gy8/eegTvO8U0Lk87/UY9ve9h/BI6iyJ+1GyLScB4RHQDYDoKgO+dFURSfFQCuOQ9A7LwgCJI5r1gsTlar1YbznHP5crl8NDw8PK2Uip3n4QMDA3OLi4udO89a23Ce1jp2nrVWtNbxh7bWxs4jop0gCDp3XhRFJyIy7pybXV5ejp3XDN7f359RSsXO01p37jxrbey8i4uLoZGRkWvOa5q/1Fp37rx+VtxwntY6dl5zK6Io2hWR2Hla686dV0vFoY+aP8xFJJdOp49LpdIUEZkaNHkqfIWd5JiIzkXkLAiCZM7zO09EYueJyBgRxc4joi0ADeeJyOrS0lJvnBdFkf8xbDhPKbWSyWR647xCocC+53XnAVjQWvfGeS1wo7XunfOstesA5pVS2Uwm8w877xeHf444cscwYAAAAABJRU5ErkJggg==", "view/refresh2.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAA/CAYAAAAPIIPGAAAEIElEQVRYR+2XTUhjVxTH/+fGpBrGT/xoBQdFFMMQLNLNbLooLbaFzqKMUhCSZwsuhGG6KCNd6DuRLgqzmGVxUd8LUrpoYWZTKO1yNi2F1oVtceEHflSLqNEav8bklPuqgsl75sUPSsucTQj33v895+R/7y+XcA1B16CJ/6GoYRiDItKfzWZjExMTv5/XtoLlx2Kxm0qp1wH0AHgTwC4RfWRZ1mdewp6ig4ODN9Lp9CMieh+AchH41Lbtj92EXUUHBgaCh4eH3wJ4zSObGSLqtSzrZ9+ihmF8CODR8YIflFL3MplMNxF9IiJWIBC4Pz4+/ldR5RuG8QuAlwGsAWi3bTsVj8dvAWhOJpPfFPK2a/mGYewDeAHAV7Zt9+aK9PX1VYRCoVcApNxa4CX6J4B6AE9t2341V9QwjO8AvAFg27btytxxL9EvAbynJxNRj2VZX58sjMfjd4joyT9D9NiyrHf9iup+/gggBCALQPfxVwARAO8cWywD4LZt2z/5EtWT+vv774rIBIBSlx/mmT5dyWTyC9+WOpkYi8XalVIPRKQbwItEpHv9PRE9tCzrt6IsVcgyhcYLnv1CAkWXfxFBxzEXXXipq+8imz7P9CJdO3+N754y86A+vYFAIDY8PHw58DHzTQB54DNNs3jwMfONY6R4go+Z/YNvbGwsuLKyci74APQys3/wMfMZ8InIPaVUt4g44AuHw/eHhoaKAx8znwEfM6dGR0dviUizaZoXA59pmvtE5ICPmfPAx8wVABzwubXA1VLM7IBPRJ4mEok88DHzKfiY2R/4mPkUfCLSk0gkTsHHzHdE5Immnog8TiQS/sDHzK7gE5EIEZ2CTyl1e2RkxD/4TNO8S0Su4BORZ0qpftM0iwefaZrtAB4QkQM+AA74ADxk5ufgc78CfV99xdy61yMajUbfAvA5gJeKycZj7gqADygajf5xRYIn+6xoUbmCDM9I/LuidXV1qK2txdzcHPb39ZPAOwpmGgqFUFFRgerqauczm81iaWkJa2v64eLhU6+eKqXQ1NTkZOcWq6urWF5edh1zzZSI0NbWhvLyctdFBwcHmJ2dxe7urn/R+vp6J0sd6XQaCwsLqKysRGNjI9bX17G4uIhMRr8jiig/EokgHA7j6OgIU1NTjkBZWRl0f7e2tgo60LX8rq4u/UjC5uamU2ZuBAIBZ1O9mVsLXEU7OztRUlKCnZ0dTE9P54nqfmsnaNHJycm8cVfRlpYW1NTUOJN1pjrjk6iqqkJra6vzNZVKYWZmxp+oLq2jo8NpgQ7dx729PZSWlkKL6hARpwr9Q+aGp/m12Zubm6H9mhtacH5+HhsbG/4tdTJTZ9bQ0OD0LxgMOm7Y3t6GNv55R7XgMS3oH5cJ/y3Rq775V3X5bx8zSv8DuWzoa2vgb5tumbHGlerDAAAAAElFTkSuQmCC", "view/settings2.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAA/CAYAAAAPIIPGAAAD2ElEQVRYR+1Xz08bRxT+ZjAGYQoH4rS9IBJBQJEsUC8VKNdQtamUE0fLayqhKHeOaGbFkT8gFVLZtXzk1qqKSs4NUg8RXCIQVoOQ2jRFHHCwBRj2VW+zttY/14BXVaPOyR7NfPN9771536xACEOEgImPDHRhYaHv/Pz8kEMVjUbjq6urxVZhayo/lUo9chzndTabfWMYxkMAGx7QrG3bL5LJ5B0p5f1MJvNz7QENQdPp9LdE9CMAZrcHYAaoxJ8AvARwD8AtAI9t2/7JD9wQdH5+/q7jOLzx04DqeCelnFlbW/s9EJQXGIbxq8eQ//4mhPieiJjlEwBf8qQQYtOyLFZRNeqYJpPJWCQSeUBEzz3JrwqFwvT6+vo575ybm4vGYrFNAF8AICnlbKlU2sxms4Uych2oYRh5AJ9UFggxb1mW5aeSTqfTRLTmm3tv2/bAVUCfWpb1zA9qGAaHwD/XGjQU+WVGHU0Ug4ZSUjXFnwMwXVP8nP1RAPG2i5/Z+q9pKpWaFUL8wvNE9FUmk9m48jWtLWavofztNZTb124oN2neH1mTvmoo/pcfHDGtdZ9nLbw4rrW+nvGZpvlISvl6aWnpjWmaD4nINT4hxKxS6sXy8vIdx3HuK6XaMz6ttWt8QohDInKNTwjhJtWzlJdCiHtEdEtK+VgpFWx8Wuu7RMQbWxofEb0TQsxordszPq11Q+MjoidCCNf4AGxqrYONb2VlJVYsFh84jvPck/yKW5/W2jU+rXWUwdj4OBQcYzbCxcXF5sanlMoLIaqMTylVZXymaVYZHxG9N02zufE1AH2qlKoyPqUUh6AyFwgaivzyVehoorxkdL6k/MUPIEdE0/7i5zcUGx8Rxdsufmbrv6ZKqSrjM01z48rXtLbFeA3FNT4At6/dUIJ7V/MV/6HOn0gkvgbwA4DPbyLZ2/sWwHcikUj82SHAMqe3DMrv+I6Ofw9USonJyUlXzfb2NhzHaamsKdPBwUGcnp7i7OwMAwMDGBsbc4H29vaQz+fR09OD3t5eHB8f1x3QEJQBR0dHcXFx4QL39/dXbTw5OXEBI5EIcrlcHXBDUGYxPj6O7u7uljJLpRJ2d3ddNf7RVD6DlhkWCgUcHrof0YjH44jFYu5vnt/Z2QmWz0lhsHIMi8Wiu/HDF6T7mMDExAT6+vjR8iHGHA5/8uqYTk1Noaurq3L6/v4+jo6OqtgMDQ1hZGSkMnd5eYmtra3K/0DQg4ODivTyLg7B8PBw+6ChyC8f39FEMWgoJRVK8TPbjl/T2mruWEO5SYMNo/P/xaDfeB712U3YeXv/ALDwD+TbY8Dbd9BBAAAAAElFTkSuQmCC", "view/setting.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAkCAYAAAC9itu8AAACAklEQVQ4T5XUS4iOcRTH8c9xCeVeiiiXhSJRJFIusRO2lEtZKFlgY6GxZDUrk2TFwii22JJLlERRLKRQJmXBkHIb8+hM/2d6ememed93957n93v+55zf9/mHll9VVTNxopTPR8T3piTyT1VVs7AL9zEd+4roOn5gK25HxLfacAjL8A8TWw6ta28jorc2LMLhIu7Ds2Jah4XlRVci4mNUVTUDadiLFF/G5GL4iyOYjxsYMnQ1BDfxujk0VmJPecFAO4bV2Nk05Bqzz3Za6ut86JJDx2vN4Hbj3hjBbcOt4eCaQZXUj5daT4pGoNFimI1zpdYVEf2jsTQX+5MX5NaOFdFFJHzJ2bWI+FJv6SRWYACTWliqa68ioqc2LMWpwtJ7PCymzVhSWOqOiHeZdPachqNIcXdBJV/2B6cLa5cwZLjQYOkqnuNsOeEM1uJgE43xDBsaH9QQfJ21VNBoHfpBaWHLiKGLoeO1ZnAHkpcxgkvOeoeDa0FjTnNLEfF1PJamYkcR3YmIX6OxNA35Kb7BFKwvoqf4jeV4GRE/azQ2Yh4GMaGFpbr2OSKe1Ibse1MRJ84fimkxMqc0Pc55MrjsOYvZRoofNW6/vPUSwEQ+2+tPQ14h9fX4Ap+aQ2MB1pQTB9sx5K24qmnorKWCRvtDF0PHa+0suBaW0ry91O5mus3n/wHmQwUTIH+tVgAAAABJRU5ErkJggg==", "view/refresh.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAkCAYAAAC9itu8AAACiElEQVQ4T4WVS4iPYRTGf4/7/X6XcivXcktEUhTKQkqyYCOKjWyUhezFThbIlJ3LYrIRkoWGUhhhTMko4zJujYRpxgxHj9737/P3zfh239c57/uc5/zO+UQ3T0QsBRYCtZI+5jBVx0fEcGA6MA+YCXQCVyXddWwlISL6ARuARcXvhQPrJF3/nRARvYHtwLRuFLYCFyW15ITl6XTHvwIuJzlrgHrgiqSOiqSI2ANMAL4BxyW1R8RYYKSkp8Vb8w2HgD7AE0kXSozoD0wC2nPCAWAw0CyppiRhBzAD6MgJW4D5KdDFNeSkiJgFbEvONeYE698N2K0ArPsDMAZwguN+AmeKfZgLbAb6llj7A7gk6eFfnY6I0cDKpNc1tQFNwG1JvvFPp0sKXQ2sAGokveuJpVHAHGBJ4ul76vLNapbs9dYk6R8oU7driyztA2Z3w5L1n5LUnBPWptMd/xw4l+RscsHAeeNSZMloTAG+AIcltUXERPdB0qMylk4klu5LOlni2ABgqm3Oko4BQ4Fnko6WJOxPzlXg2wV4hv2czuOYhmsBsDf1rD7fYP0HkyyzZN0twHjACZmlI0WWFgM7e2DprKQ71SyNA9YDBnFYcq0RuOZ5/h9LdsVS6yV97YmlgYDn2X3wjUa7QdKLapY8015ePrWMJVtembhewLI0YWU4eZvck/Q525pXo4M/AY+TLMP40u+SuooseVjsitm/IakzItz5QcXhKSZsBCyrpdjlwuZwfSO8mLOkdYAHqFXSrRKWvErtXFdOcJcnp0AX96ZwuldQ5uxtTrD+VUmWWXqfujwk8eQ4f68rsuRG+d/gZVb9eIk9kPS6miXvIv91rNc12TXPc5MkTyO/AFhJCujHqZlCAAAAAElFTkSuQmCC", "comp/checkbox.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAqCAYAAACDdWrxAAABbUlEQVRIS+2TP0gCURzHv88GRYsrExyOo5cEQVEtWdQQpE4N0R+HxmirXXCrKYigqMF2IRqCQByaLJqNIFpyUIzu4rIwpExODy88ITD/cJ603Rsf7/OGz+/zI5TSEAE20cZRgBMySKni8XrbwICrWAwG2ESZIadFS53J0R25brCyHZNud1vbcRuPV7fDAOu9GXJatNSZHN2R6wb/PfJCrxOZCR8Gbk6hWc6Xg8PrcgBETMIVPdIGSjYG/NoOSHcfkLqDK3qsBSRIrgRAuBF1quUPEUPhYGMwb2dhywrqQ3F0Dt++jSokJMBdhmDO52pB2WwFP7OK8rgH9os99IgppNf3QWwMFP4RNHKALrmoflIj53l6CaWpRcBkgiIkYHl6gDTrh5JJg57v/kJ1YOUixw7jfWELxMpAKUmAXAR7tg3LZ7am3IbjKDBOvPiDqkUmcoj+9H1d7k3nmHdweBubB70ON9wRzQH8pVVQb+Q/zZAEfpwDCU4AAAAASUVORK5CYII=", "comp/btn_close.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAA8CAYAAAB1odqiAAAE6UlEQVRYR+3Y30+bVRgH8G/T0t/0Jy0USrIsC0E2GMKAVYcRpmSbEzIGZhqyxCxeceGVF3pjvJl/wYyJWZYY4hZBFnBuBBUW2ewYAxlsSMiyLKH8aEt/0vZtSxvM+562We15C6jlxr53zfO8z+ec5z2nOTmCk598tY19fAQs+Hlvz76QX1zpAwd+1NMNXzieU1QtFeKbvn4CXvqgC95wLKegRirC1e8GCPjh+53wMnRwedkG54aLG4yhSI/ycnPawHaKJ5M1MhGuXR8k4MX3OnjBx3NPcLX3DPfepSu3odfrYC4r5X7bVlbhcrnT4kdrjlA7xYLffj9EwJ6udnhCW9TEJ08XUgWTqE6n5XLdbk9G7MjhKmodrbwAfQPDBLxw7h1ecH3dDq/Xm1GYrZqceXIgGo0GJSXFvOCNmz8RsLv9NNyhKO+icTqc8Pl8acDLyWyr1Wo1DEYDbw2dXIz+4TsE7DzbBneQH2SruDZc8Pv9GSiLqVQq6Iv0WVe5TiHG4K1RAnaceguuYCTrCx63G4FAgAoqlUpodbqs7+sVEgyN/ELAs20t2Ajwgz6vF6FgMGtL5QoF1BoNL1qklODW6DgBT518gxcM+P1gQqFdLRqZXA6lSkVFWXDk198I2NZyAs7NMDXR7XRmYBKZjMuNMEzmljHQF46hUIrR8XsEbG228IJ+T/rGFkskkMoVHBgOBRGNRNI2vkpL/5YsODZhJeCbJ47D4WeoM4wyDLai5PsWiCUQJ2aXTN4pnswzqmS4e+8BAZstDbxg1qW3hyALTlinCPh6Uz1C0Rg2w/S/tz3UpaYWSgsgF4twf3IagvOXr297PR5YGuv+bd2s71sfzkCj1ULQe+3u9vraGlg0lw+LlZhMEIzUNu7vmYYFmz/9LJeTS9We+PIymaGl6wLizo2cokJDEawDNxLg+W7EHTkGjUWw/tBPwOMdnYg7nNQZep4/Q2B9jYspS0zQHjyUlrdTPJksNBrwYGiQgE3vtiNup4O2SSuOzk5y7z2ubYKyuBiaAwe5394XzxGw29Pi5iYLdeDCYgMmfxxOgKfPIG53UBNt049SBVNo4g864HRmxMz1x3hAIybv3CZg49ttiK/bqYneFRuCLldGYTY5OfPkQBR6PTRl6cfIVEtLivHw51ECNrS2Ir62zrtKfWtrCHo8acDLyWyrFVot1CYTbw2hqQRTY2MJsLk5K8hW8TkcCPp8GSiHqdVQG41ZtxUHTkwQ8NhrFsRXyUrke3wuF0L+TSooVxVCrc9+iBKWmvDodysB65saEFtZ5cX8Hi+YQDBrS2VKBVRa/jONqKwU05NTBKyrexWxlRUquOnfBBNidrVoZHIZClWF1DqisjLMzPxBwNraasRsdHDD6c7ApDIJVzTMRDJiRQb6EUNkLsPs7DwBa6qrELPZqCNzu/1pG1siEUOhkHK5wWAYkUg0La7T0U9tIrMZc/MLBKw+XImtZTrIMBFEouQkIBEXQJaYXXJ0O8WTeQXlZsw/XSRg1SsVvGDWpbuHIAsu/LlEwMrKCsQDAcQ93j2U2H2qUKuBUKnE4uISBF9f/Hj7wJwVhyordl/hH2Q+W1zCixoLOdNUj98Ei+byYbH5lnPkmJhL6O+18/c0/1m38/c0qVbm72nYVuTvadgu5O9pUtsif0+Tv6dhF8P/657mLz4NfQVdLmZiAAAAAElFTkSuQmCC", "comp/textarea.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFsAAAAXCAYAAABkrDOOAAAA4klEQVRoQ+3ZvQrCMBiF4e9rU+sPOErRqxDRe/KG9Fp0EAc3VzuIg1ML4uDmlkaaquDenMUTyJoDD+8W3ZyKlaoshSeogHOy1m1euOmoI1EU+auqQUf/8XHnnBzLp3jsWdaVJEnEGEPsADXU2Ifro8Gej/uSpqnHruvmaVegqirZX+4N9mIy8Nh13XEct7vE18RaK7vzjdiIFoiNUH5vEJvYQAHgFMsmNlAAOMWyiQ0UAE6xbGIDBYBTLJvYQAHgFMsmNlAAOMWyiQ0UAE79lM2fmrDy358a/q6Hhf68ng175QueKdEXxUGVVwAAAABJRU5ErkJggg==", "view/re.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAoCAYAAAD6xArmAAACpklEQVRIS+WWPUgcQRiG3+8O70QEUwTB1EJgsTGdRRrhOMjOtEtSRbBIBMFKuCtkZleES2uRQoWQJggKKW7Of7GyTRvBLkVShhS73OXMfWGOU85Es7uXs0m2XeZh+OZ95xnCHX10R1ykBvu+P5fP59+VSqVvf9pUarBS6jWAR0Q0rbWOboP3BCaiOQAHAKTW+vtN8L8BW96W4zjPPM/78Ss8FlypVEYajYbHzALAJIAHALJdoDWl1Esi4m74rWBmpiAI5pk5AHAvJj0VrXU5Fmyhvu+/AfA8YRxfaa1LsWDf92eZeSMJlJnXtdYvEo1Ca30G4GEH/ImI1lqt1nE+nz9vNBrLnVTY39uO4zxNdHgrKytjzWbzs13FzKfDw8PFxcXF8HL3Nscd8BEAN3HcgiCYbLVaHyyIiGaUUm+7R9JzQZRSo0T0BUCGmRd831/tBttK53K5zXK5/DV1pZVSG0Q0C2BXa/0kySEmKojWeoiZD4hoKpvNTiwtLX1MC7+1IFrrQWZeJaJxx3EKN5186lF0LwiC4DEz31dKvU+z69i7Ig0stnm9wv4zsDGm7bxCodBf5xlj2s5j5mkpZf+c1wHPEdFBGIbS87z+OO8S3EnAVhRFvTnv8PBwpF6ve0QkiGiSmX9znuu66ZxXq9XmAcQ6j5krUspkzqvVaqmcJ4SId54xxl6ZiZwHYN113WTOq1arZ0R05TwAa5lM5rher5/ncrllAPYl1HZeFEXJnLe3tzd2cXHRdh6A04GBgWKxWLxyXlcqjqIochPHbWdn58p5AGaEENec13NB9vf3R5vNZtt5RLTguu4159lKA9gUQqR3njHGHpx9tOxKKfvnvGq1OmQrC2AKwIQQon/OOzk5GQzD0I5hPIqi/jvPGNN2npTyH3feTzoJOzgswwlqAAAAAElFTkSuQmCC", "view/search.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAqCAYAAABcOxDuAAABX0lEQVRIS+3VsUrEQBAG4H9HiDZiJQg+gJVaiKAoWClYXWeZ7D6CtbWFr5Ai2ayQxkLQRgsLGwtBUQsRC6sDCxHxEIvIZSRwxRGSu83pNUe23c0H+89kR2AISwzBxAiinuctCSH2AawD+AFwRkR7QRC85CO0ur5SaoOZzwGM54A3IlrJw1aolPIewEJJUY+01jvde31RKeUMgNceXdLSWk9VQl3XnSWiZhnKzF9RFE1WQrPDUsonAHNFsBDiJAzDRmXUdd1tIjoFMJaDW0KI1TAMH61RpdQ0Mx8z8zMzHxLRAYBlAG0Al2ma7hpjHqxbqgNeAJgHcKW1XutEMeE4Ttv3/axXC1dh9XPgbZqmW8aYd9t3ohCVUt4BWARwkyTJZhzHH7Zgdq4MvQbw7ThOw/f9zypgKVoVsS7UX+C+v+kgeI0Oklrvb0Yw03rwlZW8Hnz14OvqjXrw1e/pPyfwCww91CttlMG7AAAAAElFTkSuQmCC", "view/save.png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAoCAYAAAD6xArmAAAA1klEQVRIS+2VzQ3DIAyFwxwdoMMAA/VQ8ZByyEBhmA7QOVxxKLIaOcIoSZUfrlifHw/wM91Ky6zE7SZgANTaDEDhzYJ5odSMC7nA5U7+b4X2dVQr3ic4hHCTlMcY33xPZUUGcwBvdEJwjcfGGIQQ4rd2qenWA3hyAUuABwCP31NtN+i1v02qP4DicRybM885J2ceB/NCyUupfuLxBS4WbmKF9rNUv4p9gq21d0l5SunF91RWZDAH8EYnBNd4nDPPWitnXst0I6Leez+feVowEQ3e+wNk3ge7C/Qp3GfwkgAAAABJRU5ErkJggg==" }; + Base64AtlasManager.base64 = new Base64Atlas(Base64AtlasManager.dataO); + + class CallLaterTool { + constructor() { + } + static initCallLaterRecorder() { + if (CallLaterTool.oldCallLater) + return; + CallLaterTool.oldCallLater = Laya.Laya.timer["callLater"]; + Laya.Laya.timer["callLater"] = CallLaterTool["prototype"]["callLater"]; + } + static beginRecordCallLater() { + CallLaterTool.initCallLaterRecorder(); + CallLaterTool._isRecording = true; + } + static runRecordedCallLaters() { + CallLaterTool._isRecording = false; + var timer; + timer = Laya.Laya.timer; + var laters = timer["_laters"]; + laters = CallLaterTool._recordedCallLaters; + for (var i = 0, n = laters.length - 1; i <= n; i++) { + var handler = laters[i]; + if (CallLaterTool._recordedCallLaters.indexOf(handler) < 0) + continue; + handler.method !== null && handler.run(false); + timer["_recoverHandler"](handler); + laters.splice(i, 1); + } + CallLaterTool._recordedCallLaters.length = 0; + } + callLater(caller, method, args = null) { + if (this._getHandler(caller, method) == null) { + CallLaterTool.oldCallLater.call(this, caller, method, args); + if (CallLaterTool._isRecording) { + CallLaterTool._recordedCallLaters.push(this._laters[this._laters.length - 1]); + } + } + } + } + CallLaterTool._recordedCallLaters = []; + CallLaterTool._isRecording = false; + + class CanvasTools { + constructor() { + } + static createCanvas(width, height) { + return null; + } + static renderSpriteToCanvas(sprite, canvas, offsetX, offsetY) { + Laya.RenderSprite.renders[sprite._renderType]._fun(sprite, canvas.context, offsetX, offsetY); + } + static getImageDataFromCanvas(canvas, x = 0, y = 0, width = 0, height = 0) { + if (width <= 0) + width = canvas.width; + if (height <= 0) + height = canvas.height; + var imgdata = canvas.context.getImageData(x, y, width, height); + return imgdata; + } + static getImageDataFromCanvasByRec(canvas, rec) { + var imgdata = canvas.context.getImageData(rec.x, rec.y, rec.width, rec.height); + return imgdata; + } + static getDifferCount(imageData1, imageData2) { + var data1 = imageData1.data; + var data2 = imageData2.data; + var differCount; + differCount = 0; + CanvasTools.walkImageData(imageData1, myWalkFun); + return differCount; + function myWalkFun(i, j, tarPos, data) { + if (!CanvasTools.isPoinSame(tarPos, data1, data2)) + differCount++; + } + } + static getDifferRate(imageData1, imageData2) { + return CanvasTools.getDifferCount(imageData1, imageData2) / (imageData1.width * imageData1.height); + } + static getCanvasDisRec(canvas) { + var rst; + rst = new Laya.Rectangle; + var imgdata; + imgdata = CanvasTools.getImageDataFromCanvas(canvas, 0, 0); + var maxX; + var minX; + var maxY; + var minY; + maxX = maxY = 0; + minX = imgdata.width; + minY = imgdata.height; + var i, iLen; + var j, jLen; + iLen = imgdata.width; + jLen = imgdata.height; + var data; + data = imgdata.data; + var tarPos = 0; + for (j = 0; j < jLen; j++) { + for (i = 0; i < iLen; i++) { + if (!CanvasTools.isEmptyPoint(data, tarPos)) { + if (minX > i) + minX = i; + if (maxX < i) + maxX = i; + if (minY > j) + minY = j; + if (maxY < j) + maxY = j; + } + tarPos += 4; + } + } + rst.setTo(minX, minY, maxX - minX + 1, maxY - minY + 1); + return rst; + } + static fillCanvasRec(canvas, rec, color) { + var ctx = canvas.context; + ctx.fillStyle = color; + ctx.fillRect(rec.x, rec.y, rec.width, rec.height); + } + static isEmptyPoint(data, pos) { + if (data[pos] == 0 && data[pos + 1] == 0 && data[pos + 2] == 0 && data[pos + 3] == 0) { + return true; + } + else { + return false; + } + } + static isPoinSame(pos, data1, data2) { + if (data1[pos] == data2[pos] && data1[pos + 1] == data2[pos + 1] && data1[pos + 2] == data2[pos + 2] && data1[pos + 3] == data2[pos + 3]) { + return true; + } + else { + return false; + } + } + static walkImageData(imgdata, walkFun) { + var i, iLen; + var j, jLen; + iLen = imgdata.width; + jLen = imgdata.height; + var tarPos = 0; + var data = imgdata.data; + for (i = 0; i < iLen; i++) { + for (j = 0; j < jLen; j++) { + walkFun(i, j, tarPos, data); + tarPos += 4; + } + } + } + static renderSpritesToCanvas(canvas, sprites, offx = 0, offy = 0, startIndex = 0) { + var i, len; + len = sprites.length; + for (i = startIndex; i < len; i++) { + CanvasTools.renderSpriteToCanvas(sprites[i], canvas, offx, offy); + } + } + static clearCanvas(canvas) { + var preWidth; + var preHeight; + preWidth = canvas.width; + preHeight = canvas.height; + canvas.size(preWidth + 1, preHeight); + canvas.size(preWidth, preHeight); + } + static getImagePixels(x, y, width, data, colorLen = 4) { + var pos; + pos = (x * width + y) * colorLen; + var i, len; + var rst; + rst = []; + len = colorLen; + for (i = 0; i < len; i++) { + rst.push(data[pos + i]); + } + return rst; + } + } + + class MathTools { + constructor() { + } + static sortBigFirst(a, b) { + if (a == b) + return 0; + return b > a ? 1 : -1; + } + static sortSmallFirst(a, b) { + if (a == b) + return 0; + return b > a ? -1 : 1; + } + static sortNumBigFirst(a, b) { + return parseFloat(b) - parseFloat(a); + } + static sortNumSmallFirst(a, b) { + return parseFloat(a) - parseFloat(b); + } + static sortByKey(key, bigFirst = false, forceNum = true) { + var _sortFun; + if (bigFirst) { + _sortFun = forceNum ? MathTools.sortNumBigFirst : MathTools.sortBigFirst; + } + else { + _sortFun = forceNum ? MathTools.sortNumSmallFirst : MathTools.sortSmallFirst; + } + return function (a, b) { + return _sortFun(a[key], b[key]); + }; + } + } + + class ColorTool { + constructor() { + } + static toHexColor(color) { + return Laya.Utils.toHexColor(color); + } + static getRGBByRGBStr(str) { + str.charAt(0) == '#' && (str = str.substr(1)); + var color = parseInt(str, 16); + var flag = (str.length == 8); + var _color; + _color = [((0x00FF0000 & color) >> 16), ((0x0000FF00 & color) >> 8), (0x000000FF & color)]; + return _color; + } + static getColorBit(value) { + var rst; + rst = Math.floor(value).toString(16); + rst = rst.length > 1 ? rst : "0" + rst; + return rst; + } + static getRGBStr(rgb, coefficient = 1) { + return "#" + ColorTool.getColorBit(rgb[0] * coefficient) + ColorTool.getColorBit(rgb[1] * coefficient) + ColorTool.getColorBit(rgb[2] * coefficient); + } + static traseHSB(hsb) { + console.log("hsb:", hsb[0], hsb[1], hsb[2]); + } + static rgb2hsb(rgbR, rgbG, rgbB) { + var rgb = [rgbR, rgbG, rgbB]; + rgb.sort(MathTools.sortNumSmallFirst); + var max = rgb[2]; + var min = rgb[0]; + var hsbB = max / 255.0; + var hsbS = max == 0 ? 0 : (max - min) / max; + var hsbH = 0; + if (max == min) { + hsbH = 1; + } + else if (rgbR == 0 && rgbG == 0 && rgbB == 0) ; + else if (max == rgbR && rgbG >= rgbB) { + hsbH = (rgbG - rgbB) * 60 / (max - min) + 0; + } + else if (max == rgbR && rgbG < rgbB) { + hsbH = (rgbG - rgbB) * 60 / (max - min) + 360; + } + else if (max == rgbG) { + hsbH = (rgbB - rgbR) * 60 / (max - min) + 120; + } + else if (max == rgbB) { + hsbH = (rgbR - rgbG) * 60 / (max - min) + 240; + } + return [hsbH, hsbS, hsbB]; + } + static hsb2rgb(h, s, v) { + var r = 0, g = 0, b = 0; + var i = Math.floor((h / 60) % 6); + var f = (h / 60) - i; + var p = v * (1 - s); + var q = v * (1 - f * s); + var t = v * (1 - (1 - f) * s); + switch (i) { + case 0: + r = v; + g = t; + b = p; + break; + case 1: + r = q; + g = v; + b = p; + break; + case 2: + r = p; + g = v; + b = t; + break; + case 3: + r = p; + g = q; + b = v; + break; + case 4: + r = t; + g = p; + b = v; + break; + case 5: + r = v; + g = p; + b = q; + break; + } + return [Math.floor(r * 255.0), Math.floor(g * 255.0), Math.floor(b * 255.0)]; + } + } + + class CommonTools { + constructor() { + } + static bind(fun, scope) { + var rst; + rst = fun.bind(scope); + return rst; + } + static insertP(tar, x, y, scaleX, scaleY, rotation) { + var nSp; + nSp = new Laya.Sprite(); + tar.parent.addChild(nSp); + nSp.x = x; + nSp.y = y; + nSp.scaleX = scaleX; + nSp.scaleY = scaleY; + nSp.rotation = rotation; + nSp.addChild(tar); + CommonTools.count++; + nSp.name = "insertP:" + CommonTools.count; + } + static insertChild(tar, x, y, scaleX, scaleY, rotation, color = "#ff00ff") { + var nSp; + nSp = new Laya.Sprite(); + tar.addChild(nSp); + nSp.x = x; + nSp.y = y; + nSp.scaleX = scaleX; + nSp.scaleY = scaleY; + nSp.rotation = rotation; + nSp.graphics.drawRect(0, 0, 20, 20, color); + nSp.name = "child:" + tar.numChildren; + return nSp; + } + static createSprite(width, height, color = "#ff0000") { + var sp; + sp = new Laya.Sprite(); + sp.graphics.drawRect(0, 0, width, height, color); + sp.size(width, height); + return sp; + } + static createBtn(txt, width = 100, height = 40) { + var sp; + sp = new Laya.Sprite(); + sp.size(width, height); + sp.graphics.drawRect(0, 0, sp.width, sp.height, "#ff0000"); + sp.graphics.fillText(txt, sp.width * 0.5, sp.height * 0.5, null, "#ffff00", "center"); + return sp; + } + } + CommonTools.count = 0; + + class DebugTxt { + constructor() { + } + static init() { + if (DebugTxt._txt) + return; + DebugTxt._txt = new Laya.Text(); + DebugTxt._txt.pos(100, 100); + DebugTxt._txt.color = "#ff00ff"; + DebugTxt._txt.zOrder = 999; + DebugTxt._txt.fontSize = 24; + DebugTxt._txt.text = "debugTxt inited"; + Laya.Laya.stage.addChild(DebugTxt._txt); + } + static getArgArr(arg) { + var rst; + rst = []; + var i, len = arg.length; + for (i = 0; i < len; i++) { + rst.push(arg[i]); + } + return rst; + } + static dTrace(...arg) { + arg = DebugTxt.getArgArr(arg); + var str; + str = arg.join(" "); + if (DebugTxt._txt) { + DebugTxt._txt.text = str + "\n" + DebugTxt._txt.text; + } + } + static getTimeStr() { + var dateO = new Date(); + return dateO.toTimeString(); + } + static traceTime(msg) { + DebugTxt.dTrace(DebugTxt.getTimeStr()); + DebugTxt.dTrace(msg); + } + static show(...arg) { + arg = DebugTxt.getArgArr(arg); + var str; + str = arg.join(" "); + if (DebugTxt._txt) { + DebugTxt._txt.text = str; + } + } + } + + class DisEditor { + constructor() { + this.rec = new Laya.Sprite(); + this.rootContainer = new Laya.Sprite(); + } + setTarget(target) { + this.tar = target; + var g; + g = this.rec.graphics; + g.clear(); + var bounds; + bounds = this.tar.getSelfBounds(); + g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height, null, "#00ff00"); + this.createSameDisChain(); + Laya.Laya.stage.addChild(this.rootContainer); + } + createSameDisChain() { + var tParent; + var cpParent; + var preTar; + preTar = this.rec; + tParent = this.tar; + while (tParent && tParent != Laya.Laya.stage) { + cpParent = new Laya.Sprite(); + cpParent.addChild(preTar); + cpParent.x = tParent.x; + cpParent.y = tParent.y; + cpParent.scaleX = tParent.scaleX; + cpParent.scaleY = tParent.scaleY; + cpParent.rotation = tParent.rotation; + cpParent.scrollRect = tParent.scrollRect; + preTar = cpParent; + tParent = tParent.parent; + } + this.rootContainer.removeChildren(); + this.rootContainer.addChild(preTar); + } + } + + class DisPool { + constructor() { + } + static getDis(clz) { + var clzName; + clzName = ClassTool.getClassNameByClz(clz); + if (!DisPool._objDic[clzName]) { + DisPool._objDic[clzName] = []; + } + var disList; + disList = DisPool._objDic[clzName]; + var i, len; + len = disList.length; + for (i = 0; i < len; i++) { + if (!disList[i].parent) { + return disList[i]; + } + } + disList.push(new clz()); + return disList[disList.length - 1]; + } + } + DisPool._objDic = {}; + + class DragBox extends Laya.Sprite { + constructor(type) { + super(); + this._left = this.drawBlock(); + this._right = this.drawBlock(); + this._top = this.drawBlock(); + this._bottom = this.drawBlock(); + this._topLeft = this.drawBlock(); + this._topRight = this.drawBlock(); + this._bottomLeft = this.drawBlock(); + this._bottomRight = this.drawBlock(); + this._lastPoint = new Laya.Point(); + this._type = type = 3; + this.addChild(this._box = this.drawBorder(0, 0, 0xff0000)); + if (type == 1 || type == 3) { + this.addChild(this._left); + this.addChild(this._right); + } + if (type == 2 || type == 3) { + this.addChild(this._top); + this.addChild(this._bottom); + } + if (type == 3) { + this.addChild(this._topLeft); + this.addChild(this._topRight); + this.addChild(this._bottomLeft); + this.addChild(this._bottomRight); + } + this.on(Laya.Event.MOUSE_DOWN, this, this.onMouseDown); + this.mouseThrough = true; + } + onMouseDown(e) { + this._currDir = e.target; + if (e.nativeEvent.shiftKey) { + this.initFixScale(); + } + if (this._currDir != this) { + this._lastPoint.x = Laya.Laya.stage.mouseX; + this._lastPoint.y = Laya.Laya.stage.mouseY; + Laya.Laya.stage.on(Laya.Event.MOUSE_MOVE, this, this.onMouseMove); + Laya.Laya.stage.on(Laya.Event.MOUSE_UP, this, this.onMouseUp); + e.stopPropagation(); + } + } + onMouseUp(e) { + Laya.Laya.stage.off(Laya.Event.MOUSE_MOVE, this, this.onMouseMove); + Laya.Laya.stage.off(Laya.Event.MOUSE_UP, this, this.onMouseUp); + } + initFixScale() { + this.fixScale = this._target.height / this._target.width; + } + onMouseMove(e) { + var scale = 1; + var tx = (Laya.Laya.stage.mouseX - this._lastPoint.x) / scale; + var ty = (Laya.Laya.stage.mouseY - this._lastPoint.y) / scale; + var sameScale = false; + var adptX; + var adptY; + if (e.nativeEvent.shiftKey) { + if (this.fixScale < 0) + this.initFixScale(); + adptY = tx * this.fixScale; + adptX = ty / this.fixScale; + sameScale = true; + switch (this._currDir) { + case this._topLeft: + case this._bottomLeft: + this._currDir = this._left; + break; + case this._topRight: + case this._bottomRight: + this._currDir = this._right; + break; + } + } + if (tx != 0 || ty != 0) { + this._lastPoint.x += tx * scale; + this._lastPoint.y += ty * scale; + var tw = tx / this._target.scaleX; + var th = ty / this._target.scaleY; + if (this._currDir == this._left) { + this._target.x += tx; + this._target.width -= tw; + if (sameScale) { + this._target.height = this._target.width * this.fixScale; + } + } + else if (this._currDir == this._right) { + this._target.width += tw; + if (sameScale) { + this._target.height = this._target.width * this.fixScale; + } + } + else if (this._currDir == this._top) { + this._target.y += ty; + this._target.height -= th; + if (sameScale) { + this._target.width = this._target.height / this.fixScale; + } + } + else if (this._currDir == this._bottom) { + this._target.height += th; + if (sameScale) { + this._target.width = this._target.height / this.fixScale; + } + } + else if (this._currDir == this._topLeft) { + this._target.x += tx; + this._target.y += ty; + this._target.width -= tw; + this._target.height -= th; + } + else if (this._currDir == this._topRight) { + this._target.y += ty; + this._target.width += tw; + this._target.height -= th; + } + else if (this._currDir == this._bottomLeft) { + this._target.x += tx; + this._target.width -= tw; + this._target.height += th; + } + else if (this._currDir == this._bottomRight) { + this._target.width += tw; + this._target.height += th; + } + if (this._target.width < 1) { + this._target.width = 1; + } + if (this._target.height < 1) { + this._target.height = 1; + } + this._target.width = Math.round(this._target.width); + this._target.x = Math.round(this._target.x); + this._target.y = Math.round(this._target.y); + this._target.height = Math.round(this._target.height); + this.refresh(); + } + } + drawBorder(width, height, color, alpha = 1) { + var box = new Laya.Sprite(); + var g = box.graphics; + g.clear(); + g.drawRect(0, 0, width, height, null, "#" + color); + return box; + } + drawBlock() { + var box = new Laya.Sprite(); + var g = box.graphics; + g.clear(); + box.width = DragBox.BLOCK_WIDTH; + box.height = DragBox.BLOCK_WIDTH; + g.drawRect(-DragBox.BLOCK_WIDTH * 0.5, -DragBox.BLOCK_WIDTH * 0.5, DragBox.BLOCK_WIDTH, DragBox.BLOCK_WIDTH, "#ffffff", "#ff0000", 1); + box.mouseEnabled = true; + box.mouseThrough = true; + return box; + } + setTarget(target) { + this._target = target; + this.refresh(); + } + refresh() { + this.changePoint(); + this.changeSize(); + } + changePoint() { + var p = this._target.localToGlobal(new Laya.Point()); + var np = this.parent.globalToLocal(p); + this.x = np.x; + this.y = np.y; + } + changeSize() { + var width = this._target.width * this._target.scaleX; + var height = this._target.height * this._target.scaleY; + console.log("change size"); + this.rotation = this._target.rotation; + if (this._box.width != width || this._box.height != height) { + this._box.graphics.clear(); + this._box.graphics.drawRect(0, 0, Math.abs(width), Math.abs(height), null, "#ff0000"); + this._box.size(width, height); + this.size(width, height); + this._box.scaleX = Math.abs(this._box.scaleX) * (this._target.scaleX > 0 ? 1 : -1); + this._box.scaleY = Math.abs(this._box.scaleY) * (this._target.scaleY > 0 ? 1 : -1); + this._left.x = 0; + this._left.y = height * 0.5; + this._right.x = width; + this._right.y = height * 0.5; + this._top.x = width * 0.5; + this._top.y = 0; + this._bottom.x = width * 0.5; + this._bottom.y = height; + this._topLeft.x = this._topLeft.y = 0; + this._topRight.x = width; + this._topRight.y = 0; + this._bottomLeft.x = 0; + this._bottomLeft.y = height; + this._bottomRight.x = width; + this._bottomRight.y = height; + } + } + } + DragBox.BLOCK_WIDTH = 6; + + class FilterTool { + constructor() { + } + static getArrByFilter(arr, filterFun) { + var i, len = arr.length; + var rst = []; + for (i = 0; i < len; i++) { + if (filterFun(arr[i])) + rst.push(arr[i]); + } + return rst; + } + static getArr(arr, sign, value) { + var i, len = arr.length; + var rst = []; + for (i = 0; i < len; i++) { + if (arr[i][sign] == value) + rst.push(arr[i]); + } + return rst; + } + } + + class GetSetProfile { + static removeNoDisplayKeys(arr) { + var i; + for (i = arr.length - 1; i >= 0; i--) { + if (GetSetProfile.noDisplayKeys[arr[i]]) { + arr.splice(i, 1); + } + } + } + static getClassCount(className) { + return GetSetProfile.countDic[className]; + } + static addClassCount(className) { + if (!GetSetProfile.countDic[className]) { + GetSetProfile.countDic[className] = 1; + } + else { + GetSetProfile.countDic[className] = GetSetProfile.countDic[className] + 1; + } + } + static init() { + if (GetSetProfile._inited) + return; + GetSetProfile._inited = true; + var createFun = function (sp) { + GetSetProfile.classCreated(sp); + }; + FunHook.hook(Node, "call", null, createFun); + GetSetProfile.handlerO = {}; + GetSetProfile.handlerO["get"] = function (target, key, receiver) { + console.log("get", target, key, receiver); + return Reflect.get(target, key, receiver); + }; + GetSetProfile.handlerO["set"] = function (target, key, value, receiver) { + console.log("set", target, key, value, receiver); + return Reflect.set(target, key, value, receiver); + }; + } + static classCreated(obj, oClas = null) { + if (GetSetProfile.fromMe) + return; + var className; + className = ClassTool.getClassName(obj); + GetSetProfile.addClassCount(className); + GetSetProfile.addClassCount(GetSetProfile.ALL); + IDTools.idObj(obj); + var classDes; + classDes = GetSetProfile.hookClassDic[className]; + if (!classDes) { + GetSetProfile.profileClass(obj["constructor"]); + classDes = GetSetProfile.hookClassDic[className]; + if (!classDes) + return; + } + GetSetProfile.hookObj2(obj, classDes); + } + static hookObj(obj, keys) { + var handler = GetSetProfile.handlerO; + new Proxy(obj, handler); + } + static hookObj2(obj, keys) { + var i, len; + len = keys.length; + for (i = 0; i < len; i++) { + GetSetProfile.hookVar(obj, keys[i]); + } + } + static profileClass(clz) { + var className; + className = ClassTool.getClassName(clz); + GetSetProfile.fromMe = true; + var tO = new clz(); + GetSetProfile.fromMe = false; + var keys; + keys = ClassTool.getObjectDisplayAbleKeys(tO); + keys = ObjectTools.getNoSameArr(keys); + var i, len; + len = keys.length; + var tV; + var key; + for (i = len - 1; i >= 0; i--) { + key = keys[i]; + tV = tO[key]; + if (tV instanceof Function) { + keys.splice(i, 1); + } + } + len = keys.length; + GetSetProfile.removeNoDisplayKeys(keys); + GetSetProfile.hookClassDic[className] = keys; + } + static hookPrototype(tO, key) { + console.log("hook:", key); + try { + GetSetProfile.hookVar(tO, key); + } + catch (e) { + console.log("fail", key); + } + } + static reportCall(obj, name, type) { + IDTools.idObj(obj); + var objID; + objID = IDTools.getObjID(obj); + var className; + className = ClassTool.getClassName(obj); + GetSetProfile.recordInfo(className, name, type, objID); + GetSetProfile.recordInfo(GetSetProfile.ALL, name, type, objID); + } + static recordInfo(className, name, type, objID) { + var propCallsDic; + if (!GetSetProfile.infoDic[className]) { + GetSetProfile.infoDic[className] = {}; + } + propCallsDic = GetSetProfile.infoDic[className]; + var propCalls; + if (!propCallsDic[name]) { + propCallsDic[name] = {}; + } + propCalls = propCallsDic[name]; + var propCallO; + if (!propCalls[type]) { + propCalls[type] = {}; + } + propCallO = propCalls[type]; + if (!propCallO[objID]) { + propCallO[objID] = 1; + if (!propCallO["objCount"]) { + propCallO["objCount"] = 1; + } + else { + propCallO["objCount"] = propCallO["objCount"] + 1; + } + } + else { + propCallO[objID] = propCallO[objID] + 1; + } + if (!propCallO["count"]) { + propCallO["count"] = 1; + } + else { + propCallO["count"] = propCallO["count"] + 1; + } + } + static showInfo() { + var rstO; + rstO = {}; + var rstO1; + rstO1 = {}; + var arr; + arr = []; + var arr1; + arr1 = []; + var className; + var keyName; + var type; + for (className in GetSetProfile.infoDic) { + var tClassO; + var tClassO1; + tClassO = GetSetProfile.infoDic[className]; + rstO[className] = tClassO1 = {}; + for (keyName in tClassO) { + var tKeyO; + var tKeyO1; + tKeyO = tClassO[keyName]; + tClassO1[keyName] = tKeyO1 = {}; + for (type in tKeyO) { + var tDataO; + tDataO = tKeyO[type]; + tDataO["rate"] = tDataO["objCount"] / GetSetProfile.getClassCount(className); + tKeyO1[type] = tDataO["rate"]; + var tSKey; + tSKey = className + "_" + keyName + "_" + type; + rstO1[tSKey] = tDataO["rate"]; + if (className == GetSetProfile.ALL) { + if (type == "get") { + arr.push([tSKey, tDataO["rate"], tDataO["count"]]); + } + else { + arr1.push([tSKey, tDataO["rate"], tDataO["count"]]); + } + } + } + } + } + console.log(GetSetProfile.infoDic); + console.log(GetSetProfile.countDic); + console.log(rstO); + console.log(rstO1); + console.log("nodeCount:", GetSetProfile.getClassCount(GetSetProfile.ALL)); + console.log("sort by rate"); + GetSetProfile.showStaticInfo(arr, arr1, "1"); + console.log("sort by count"); + GetSetProfile.showStaticInfo(arr, arr1, "2"); + } + static showStaticInfo(arr, arr1, sortKey) { + console.log("get:"); + GetSetProfile.showStaticArray(arr, sortKey); + console.log("set:"); + GetSetProfile.showStaticArray(arr1, sortKey); + } + static showStaticArray(arr, sortKey = "1") { + arr.sort(Laya.MathUtil.sortByKey(sortKey, true, true)); + var i, len; + len = arr.length; + var tArr; + for (i = 0; i < len; i++) { + tArr = arr[i]; + console.log(tArr[0], Math.floor(tArr[1] * 100), tArr[2]); + } + } + static hookVar(obj, name, setHook = null, getHook = null) { + if (!setHook) + setHook = []; + if (!getHook) + getHook = []; + var preO = obj; + var preValue; + var des; + des = ClassTool.getOwnPropertyDescriptor(obj, name); + var ndes = {}; + var mSet = function (value) { + preValue = value; + }; + var mGet = function () { + return preValue; + }; + var mSet1 = function (value) { + var _t = this; + GetSetProfile.reportCall(_t, name, "set"); + }; + var mGet1 = function () { + var _t = this; + GetSetProfile.reportCall(_t, name, "get"); + return preValue; + }; + getHook.push(mGet1); + setHook.push(mSet1); + while (!des && obj["__proto__"]) { + obj = obj["__proto__"]; + des = ClassTool.getOwnPropertyDescriptor(obj, name); + } + if (des) { + ndes.set = des.set ? des.set : mSet; + ndes.get = des.get ? des.get : mGet; + if (!des.get) { + preValue = preO[name]; + } + ndes.enumerable = des.enumerable; + setHook.push(ndes.set); + getHook.push(ndes.get); + FunHook.hookFuns(ndes, "set", setHook); + FunHook.hookFuns(ndes, "get", getHook, getHook.length - 1); + ClassTool.defineProperty(preO, name, ndes); + } + if (!des) { + ndes.set = mSet; + ndes.get = mGet; + preValue = preO[name]; + setHook.push(ndes.set); + getHook.push(ndes.get); + FunHook.hookFuns(ndes, "set", setHook); + FunHook.hookFuns(ndes, "get", getHook, getHook.length - 1); + ClassTool.defineProperty(preO, name, ndes); + } + } + } + GetSetProfile._inited = false; + GetSetProfile.noDisplayKeys = { "conchModel": true }; + GetSetProfile.ALL = "ALL"; + GetSetProfile.countDic = {}; + GetSetProfile.fromMe = false; + GetSetProfile.hookClassDic = {}; + GetSetProfile.infoDic = {}; + + class JsonTool { + constructor() { + this.meta = { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"': '\\"', + '\\': '\\\\' + }; + } + static getJsonString(obj, singleLine = true, split = "\n", depth = 0, Width = 4) { + var preStr = ""; + preStr = JsonTool.getEmptyStr(depth * Width); + var rst; + var keyValues; + keyValues = {}; + var tKey; + var tValue; + var keys; + keys = []; + for (tKey in obj) { + keys.push(tKey); + tValue = obj[tKey]; + if (JsonTool.singleLineKey[tKey]) { + keyValues[tKey] = JsonTool.getValueStr(tValue, true, split, depth + 1, Width); + } + else { + keyValues[tKey] = JsonTool.getValueStr(tValue, singleLine, split, depth + 1, Width); + } + } + var i, len; + len = keys.length; + keys.sort(); + keys = keys.reverse(); + var keyPreStr; + keyPreStr = JsonTool.getEmptyStr((depth + 1) * Width); + if (singleLine) { + split = ""; + preStr = ""; + keyPreStr = ""; + } + var keyValueStrArr; + keyValueStrArr = []; + for (i = 0; i < len; i++) { + tKey = keys[i]; + keyValueStrArr.push(keyPreStr + JsonTool.wrapValue(tKey) + ":" + keyValues[tKey]); + } + rst = "{" + split + keyValueStrArr.join("," + split) + split + preStr + "}"; + return rst; + } + static wrapValue(value, wraper = "\"") { + return wraper + value + wraper; + } + static getArrStr(arr, singleLine = true, split = "\n", depth = 0, Width = 4) { + var rst; + var i, len; + len = arr.length; + var valueStrArr; + valueStrArr = []; + for (i = 0; i < len; i++) { + valueStrArr.push(JsonTool.getValueStr(arr[i], singleLine, split, depth + 1, Width)); + } + var preStr = ""; + preStr = JsonTool.getEmptyStr((depth + 1) * Width); + if (singleLine) { + split = ""; + preStr = ""; + } + rst = "[" + split + preStr + valueStrArr.join("," + split + preStr) + "]"; + return rst; + } + static quote(string) { + JsonTool.escapable.lastIndex = 0; + return JsonTool.escapable.test(string) ? '"' + string.replace(JsonTool.escapable, function (a) { + var c = this.meta[a]; + return typeof c === 'string' ? c : + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + static getValueStr(tValue, singleLine = true, split = "\n", depth = 0, Width = 0) { + var rst; + if (typeof (tValue) == 'string') { + rst = JsonTool.quote(tValue); + } + else if (tValue == null) { + rst = "null"; + } + else if (typeof (tValue) == 'number' || typeof (tValue) == 'number' || tValue instanceof Boolean) { + rst = tValue; + } + else if (tValue instanceof Array) { + rst = JsonTool.getArrStr(tValue, singleLine, split, depth, Width); + } + else if (typeof (tValue) == 'object') { + rst = JsonTool.getJsonString(tValue, singleLine, split, depth, Width); + } + else { + rst = tValue; + } + return rst; + } + static getEmptyStr(width) { + if (!JsonTool.emptyDic.hasOwnProperty(width)) { + var i; + var len; + len = width; + var rst; + rst = ""; + for (i = 0; i < len; i++) { + rst += " "; + } + JsonTool.emptyDic[width] = rst; + } + return JsonTool.emptyDic[width]; + } + } + JsonTool.singleLineKey = { + "props": true + }; + JsonTool.escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + JsonTool.emptyDic = {}; + + class LayoutTools { + constructor() { + } + static layoutToXCount(items, xCount = 1, dx = 0, dY = 0, sx = 0, sy = 0) { + var tX, tY; + var tItem; + var i, len; + var tCount; + var maxHeight; + tCount = 0; + maxHeight = 0; + tX = sx; + tY = sy; + len = items.length; + for (i = 0; i < len; i++) { + tItem = items[i]; + tItem.x = tX; + tItem.y = tY; + if (tItem.height > maxHeight) { + maxHeight = tItem.height; + } + tCount++; + if (tCount >= xCount) { + tCount = tCount % xCount; + tItem.y += maxHeight + dY; + maxHeight = 0; + } + else { + tX += tItem.width + dx; + } + } + } + static layoutToWidth(items, width, dX, dY, sx, sy) { + var tX, tY; + var tItem; + var i, len; + tX = sx; + tY = sy; + len = items.length; + for (i = 0; i < len; i++) { + tItem = items[i]; + if (tX + tItem.width + dX > width) { + tX = sx; + tY += dY + tItem.height; + } + tItem.x = tX; + tItem.y = tY; + tX += dX + tItem.width; + } + } + } + + class MouseEventAnalyser { + constructor() { + } + static analyseNode(node) { + DebugTool.showDisBound(node, true); + var _node; + _node = node; + ObjectTools.clearObj(MouseEventAnalyser.infoO); + ObjectTools.clearObj(MouseEventAnalyser.nodeO); + ObjectTools.clearObj(MouseEventAnalyser.hitO); + var nodeList; + nodeList = []; + while (node) { + IDTools.idObj(node); + MouseEventAnalyser.nodeO[IDTools.getObjID(node)] = node; + nodeList.push(node); + node = node.parent; + } + MouseEventAnalyser.check(Laya.Laya.stage, Laya.Laya.stage.mouseX, Laya.Laya.stage.mouseY, null); + var canStr; + if (MouseEventAnalyser.hitO[IDTools.getObjID(_node)]) { + console.log("can hit"); + canStr = "can hit"; + } + else { + console.log("can't hit"); + canStr = "can't hit"; + } + var i, len; + nodeList = nodeList.reverse(); + len = nodeList.length; + var rstTxts; + rstTxts = ["[分析对象]:" + ClassTool.getNodeClassAndName(_node) + ":" + canStr]; + for (i = 0; i < len; i++) { + node = nodeList[i]; + if (MouseEventAnalyser.hitO[IDTools.getObjID(node)]) { + console.log("can hit:", ClassTool.getNodeClassAndName(node)); + console.log("原因:", MouseEventAnalyser.infoO[IDTools.getObjID(node)]); + rstTxts.push("can hit:" + " " + ClassTool.getNodeClassAndName(node)); + rstTxts.push("原因:" + " " + MouseEventAnalyser.infoO[IDTools.getObjID(node)]); + } + else { + console.log("can't hit:" + ClassTool.getNodeClassAndName(node)); + console.log("原因:", MouseEventAnalyser.infoO[IDTools.getObjID(node)] ? MouseEventAnalyser.infoO[IDTools.getObjID(node)] : "鼠标事件在父级已停止派发"); + rstTxts.push("can't hit:" + " " + ClassTool.getNodeClassAndName(node)); + rstTxts.push("原因:" + " " + (MouseEventAnalyser.infoO[IDTools.getObjID(node)] ? MouseEventAnalyser.infoO[IDTools.getObjID(node)] : "鼠标事件在父级已停止派发")); + } + } + var rstStr; + rstStr = rstTxts.join("\n"); + } + static check(sp, mouseX, mouseY, callBack) { + IDTools.idObj(sp); + var isInAnlyseChain; + isInAnlyseChain = MouseEventAnalyser.nodeO[IDTools.getObjID(sp)]; + MouseEventAnalyser._point.setTo(mouseX, mouseY); + sp.fromParentPoint(MouseEventAnalyser._point); + mouseX = MouseEventAnalyser._point.x; + mouseY = MouseEventAnalyser._point.y; + var scrollRect = sp.scrollRect; + if (scrollRect) { + MouseEventAnalyser._rect.setTo(scrollRect.x, scrollRect.y, scrollRect.width, scrollRect.height); + var isHit = MouseEventAnalyser._rect.contains(mouseX, mouseY); + if (!isHit) { + if (isInAnlyseChain) { + MouseEventAnalyser.infoO[IDTools.getObjID(sp)] = "scrollRect没有包含鼠标" + MouseEventAnalyser._rect.toString() + ":" + mouseX + "," + mouseY; + } + return false; + } + } + var i, len; + var cList; + cList = sp._children; + len = cList.length; + var child; + var childInChain; + childInChain = null; + for (i = 0; i < len; i++) { + child = cList[i]; + IDTools.idObj(child); + if (MouseEventAnalyser.nodeO[IDTools.getObjID(child)]) { + childInChain = child; + break; + } + } + var coverByOthers; + coverByOthers = childInChain ? true : false; + var flag = false; + if (sp.hitTestPrior && !sp.mouseThrough && !MouseEventAnalyser.hitTest(sp, mouseX, mouseY)) { + MouseEventAnalyser.infoO[IDTools.getObjID(sp)] = "hitTestPrior=true,宽高区域不包含鼠标:" + ":" + mouseX + "," + mouseY + " size:" + sp.width + "," + sp.height; + return false; + } + for (i = sp._children.length - 1; i > -1; i--) { + child = sp._children[i]; + if (child == childInChain) { + if (!childInChain.mouseEnabled) { + MouseEventAnalyser.infoO[IDTools.getObjID(childInChain)] = "mouseEnabled=false"; + } + if (!childInChain.visible) { + MouseEventAnalyser.infoO[IDTools.getObjID(childInChain)] = "visible=false"; + } + coverByOthers = false; + } + if (child.mouseEnabled && child.visible) { + flag = MouseEventAnalyser.check(child, mouseX, mouseY, callBack); + if (flag) { + MouseEventAnalyser.hitO[IDTools.getObjID(sp)] = true; + MouseEventAnalyser.infoO[IDTools.getObjID(sp)] = "子对象被击中"; + if (child == childInChain) { + MouseEventAnalyser.infoO[IDTools.getObjID(sp)] = "子对象被击中," + "击中对象在分析链中"; + } + else { + MouseEventAnalyser.infoO[IDTools.getObjID(sp)] = "子对象被击中," + "击中对象不在分析链中"; + if (coverByOthers) { + MouseEventAnalyser.infoO[IDTools.getObjID(childInChain)] = "被兄弟节点挡住,兄弟节点信息:" + ClassTool.getNodeClassAndName(child) + "," + child.getBounds().toString(); + DebugTool.showDisBound(child, false, "#ffff00"); + } + } + return true; + } + else { + if (child == childInChain) { + coverByOthers = false; + } + } + } + } + var mHitRect = new Laya.Rectangle(); + var graphicHit = false; + graphicHit = sp.getGraphicBounds().contains(mouseX, mouseY); + if (sp.width > 0 && sp.height > 0) { + var hitRect = MouseEventAnalyser._rect; + if (!sp.mouseThrough) { + if (sp.hitArea) + hitRect = sp.hitArea; + else + hitRect.setTo(0, 0, sp.width, sp.height); + mHitRect.copyFrom(hitRect); + isHit = hitRect.contains(mouseX, mouseY); + } + else { + isHit = graphicHit; + mHitRect.copyFrom(sp.getGraphicBounds()); + } + if (isHit) { + MouseEventAnalyser.hitO[IDTools.getObjID(sp)] = true; + } + } + if (!isHit) { + if (graphicHit) { + MouseEventAnalyser.infoO[IDTools.getObjID(sp)] = "子对象未包含鼠标,实际绘图区域包含鼠标,设置的宽高区域不包含鼠标:" + ":" + mouseX + "," + mouseY + " hitRec:" + mHitRect.toString() + " graphicBounds:" + sp.getGraphicBounds().toString() + ",设置mouseThrough=true或将宽高设置到实际绘图区域可解决问题"; + } + else { + MouseEventAnalyser.infoO[IDTools.getObjID(sp)] = "子对象未包含鼠标,实际绘图区域不包含鼠标,设置的宽高区域不包含鼠标:" + ":" + mouseX + "," + mouseY + " hitRec:" + mHitRect.toString() + " graphicBounds:" + sp.getGraphicBounds().toString(); + } + } + else { + MouseEventAnalyser.infoO[IDTools.getObjID(sp)] = "自身区域被击中"; + } + return isHit; + } + static hitTest(sp, mouseX, mouseY) { + var isHit = false; + if (sp.hitArea instanceof Laya.HitArea) { + return Laya.MouseManager.instance.hitTest(sp, mouseX, mouseY); + } + if (sp.width > 0 && sp.height > 0 || sp.mouseThrough || sp.hitArea) { + var hitRect = MouseEventAnalyser._rect; + if (!sp.mouseThrough) { + if (sp.hitArea) + hitRect = sp.hitArea; + else + hitRect.setTo(0, 0, sp.width, sp.height); + isHit = hitRect.contains(mouseX, mouseY); + } + else { + isHit = sp.getGraphicBounds().contains(mouseX, mouseY); + } + } + return isHit; + } + } + MouseEventAnalyser.infoO = {}; + MouseEventAnalyser.nodeO = {}; + MouseEventAnalyser.hitO = {}; + MouseEventAnalyser._matrix = new Laya.Matrix(); + MouseEventAnalyser._point = new Laya.Point(); + MouseEventAnalyser._rect = new Laya.Rectangle(); + DebugTool.analyseMouseHit = () => { + if (DebugTool.target) + MouseEventAnalyser.analyseNode(DebugTool.target); + }; + + class ResTools { + constructor() { + } + static getCachedResList() { + return ResTools.getWebGlResList(); + } + static getWebGlResList() { + var rst; + rst = []; + return rst; + } + static getCanvasResList() { + var picDic; + picDic = {}; + var dataO; + dataO = Laya.Loader.loadedMap; + ResTools.collectPics(dataO, picDic); + return ResTools.getArrFromDic(picDic); + } + static getArrFromDic(dic) { + var key; + var rst; + rst = []; + for (key in dic) { + rst.push(key); + } + return rst; + } + static collectPics(dataO, picDic) { + if (!dataO) + return; + var key; + var tTexture; + for (key in dataO) { + tTexture = dataO[key]; + if (tTexture) { + if (tTexture.bitmap && tTexture.bitmap.src) { + var url = tTexture.bitmap.src; + if (url.indexOf("data:image/png;base64") < 0) + picDic[tTexture.bitmap.src] = true; + } + } + } + } + } + + class SingleTool { + constructor() { + this._objDic = {}; + } + static get I() { + if (!SingleTool._instance) { + SingleTool._instance = new SingleTool(); + } + return SingleTool._instance; + } + static set I(value) { + SingleTool._instance = value; + } + getArr(sign) { + var dic; + dic = this.getTypeDic("Array"); + if (!dic[sign]) + dic[sign] = []; + return dic[sign]; + } + getObject(sign) { + var dic; + dic = this.getTypeDic("Object"); + if (!dic[sign]) + dic[sign] = {}; + return dic[sign]; + } + getByClass(sign, clzSign, clz) { + var dic; + dic = this.getTypeDic(clzSign); + if (!dic[sign]) + dic[sign] = new clz(); + return dic[sign]; + } + getTypeDic(type) { + if (!this._objDic[type]) + this._objDic[type] = {}; + return this._objDic[type]; + } + } + + class TimeTool { + constructor() { + } + static getTime(sign, update = true) { + if (!TimeTool.timeDic[sign]) { + TimeTool.timeDic[sign] = 0; + } + var tTime; + tTime = Laya.Browser.now(); + var rst; + rst = tTime - TimeTool.timeDic[sign]; + TimeTool.timeDic[sign] = tTime; + return rst; + } + static runAllCallLater() { + if (TimeTool._deep > 0) + debugger; + TimeTool._deep++; + var timer; + timer = Laya.Laya.timer; + var laters = timer["_laters"]; + for (var i = 0, n = laters.length - 1; i <= n; i++) { + var handler = laters[i]; + if (handler) { + handler.method !== null && handler.run(false); + timer["_recoverHandler"](handler); + } + else { + debugger; + } + i === n && (n = laters.length - 1); + } + laters.length = 0; + TimeTool._deep--; + } + } + TimeTool.timeDic = {}; + TimeTool._deep = 0; + + class TimerControlTool { + constructor() { + } + static now() { + if (TimerControlTool._timeRate != 1) + return TimerControlTool.getRatedNow(); + return Date.now(); + } + static getRatedNow() { + var dTime; + dTime = TimerControlTool.getNow() - TimerControlTool._startTime; + return dTime * TimerControlTool._timeRate + TimerControlTool._startTime; + } + static getNow() { + return Date.now(); + } + static setTimeRate(rate) { + if (TimerControlTool._browerNow == null) + TimerControlTool._browerNow = Laya.Browser["now"]; + TimerControlTool._startTime = TimerControlTool.getNow(); + TimerControlTool._timeRate = rate; + if (rate != 1) { + Laya.Browser["now"] = TimerControlTool.now; + } + else { + if (TimerControlTool._browerNow != null) + Laya.Browser["now"] = TimerControlTool._browerNow; + } + } + static recoverRate() { + TimerControlTool.setTimeRate(1); + } + } + TimerControlTool._timeRate = 1; + + class TouchDebugTools { + constructor() { + } + static getTouchIDs(events) { + var rst; + rst = []; + var i, len; + len = events.length; + for (i = 0; i < len; i++) { + rst.push(events[i].identifier || 0); + } + return rst; + } + static traceTouchIDs(msg, events) { + DebugTxt.dTrace(msg + ":" + TouchDebugTools.getTouchIDs(events).join(",")); + } + } + + class UVTools { + constructor() { + } + static getUVByRec(x, y, width, height) { + return [x, y, x + width, y, x + width, y + height, x, y + height]; + } + static getRecFromUV(uv) { + var rst; + rst = new Laya.Rectangle(uv[0], uv[1], uv[2] - uv[0], uv[5] - uv[1]); + return rst; + } + static isUVRight(uv) { + if (uv[0] != uv[6]) + return false; + if (uv[1] != uv[3]) + return false; + if (uv[2] != uv[4]) + return false; + if (uv[5] != uv[7]) + return false; + return true; + } + static getTextureRec(texture) { + var rst; + rst = UVTools.getRecFromUV((texture.uv)); + rst.x *= texture.bitmap.width; + rst.y *= texture.bitmap.height; + rst.width *= texture.bitmap.width; + rst.height *= texture.bitmap.height; + return rst; + } + } + + class VisibleAnalyser { + constructor() { + } + static analyseTarget(node) { + var isInstage; + isInstage = node.displayedInStage; + var gRec; + gRec = NodeUtils.getGRec(node); + var stageRec = new Laya.Rectangle(); + stageRec.setTo(0, 0, Laya.Laya.stage.width, Laya.Laya.stage.height); + var isInVisibleRec; + var visibleRec; + visibleRec = stageRec.intersection(gRec); + if (visibleRec.width > 0 && visibleRec.height > 0) { + isInVisibleRec = true; + } + else { + isInVisibleRec = false; + } + var gAlpha; + gAlpha = NodeUtils.getGAlpha(node); + var gVisible; + gVisible = NodeUtils.getGVisible(node); + var msg; + msg = ""; + msg += "isInstage:" + isInstage + "\n"; + msg += "isInVisibleRec:" + isInVisibleRec + "\n"; + msg += "gVisible:" + gVisible + "\n"; + msg += "gAlpha:" + gAlpha + "\n"; + if (isInstage && isInVisibleRec && gVisible && gAlpha > 0) { + VisibleAnalyser.anlyseRecVisible(node); + msg += "coverRate:" + VisibleAnalyser.coverRate + "\n"; + if (VisibleAnalyser._coverList.length > 0) { + Laya.Laya.timer.once(1000, null, VisibleAnalyser.showListLater); + } + } + console.log(msg); + } + static showListLater() { + } + static isCoverByBrother(node) { + var parent = node.parent; + if (!parent) + return; + var _childs = parent._children; + var index; + index = _childs.indexOf(node); + if (index < 0) + return; + var rec; + rec = parent.getSelfBounds(); + if (rec.width <= 0 || rec.height <= 0) + return; + } + static anlyseRecVisible(node) { + VisibleAnalyser.isNodeWalked = false; + VisibleAnalyser._analyseTarget = node; + if (!VisibleAnalyser.mainCanvas) + VisibleAnalyser.mainCanvas = CanvasTools.createCanvas(Laya.Laya.stage.width, Laya.Laya.stage.height); + CanvasTools.clearCanvas(VisibleAnalyser.mainCanvas); + VisibleAnalyser.tColor = 1; + VisibleAnalyser.resetCoverList(); + WalkTools.walkTargetEX(Laya.Laya.stage, VisibleAnalyser.recVisibleWalker, null, VisibleAnalyser.filterFun); + if (!VisibleAnalyser.isTarRecOK) { + VisibleAnalyser.coverRate = 0; + } + else { + VisibleAnalyser.coverRate = CanvasTools.getDifferRate(VisibleAnalyser.preImageData, VisibleAnalyser.tarImageData); + } + console.log("coverRate:", VisibleAnalyser.coverRate); + } + static getRecArea(rec) { + return rec.width * rec.height; + } + static addCoverNode(node, coverRate) { + var data; + data = {}; + data.path = node; + data.label = ClassTool.getNodeClassAndName(node) + ":" + coverRate; + data.coverRate = coverRate; + VisibleAnalyser._coverList.push(data); + console.log("coverByNode:", node, coverRate); + } + static resetCoverList() { + VisibleAnalyser._coverList.length = 0; + } + static recVisibleWalker(node) { + if (node == VisibleAnalyser._analyseTarget) { + VisibleAnalyser.isNodeWalked = true; + VisibleAnalyser.tarRec.copyFrom(NodeUtils.getGRec(node)); + console.log("tarRec:", VisibleAnalyser.tarRec.toString()); + if (VisibleAnalyser.tarRec.width > 0 && VisibleAnalyser.tarRec.height > 0) { + VisibleAnalyser.isTarRecOK = true; + VisibleAnalyser.tColor++; + CanvasTools.fillCanvasRec(VisibleAnalyser.mainCanvas, VisibleAnalyser.tarRec, ColorTool.toHexColor(VisibleAnalyser.tColor)); + VisibleAnalyser.preImageData = CanvasTools.getImageDataFromCanvasByRec(VisibleAnalyser.mainCanvas, VisibleAnalyser.tarRec); + VisibleAnalyser.tarImageData = CanvasTools.getImageDataFromCanvasByRec(VisibleAnalyser.mainCanvas, VisibleAnalyser.tarRec); + } + else { + console.log("tarRec Not OK:", VisibleAnalyser.tarRec); + } + } + else { + if (VisibleAnalyser.isTarRecOK) { + var tRec; + tRec = NodeUtils.getGRec(node); + VisibleAnalyser.interRec = VisibleAnalyser.tarRec.intersection(tRec, VisibleAnalyser.interRec); + if (VisibleAnalyser.interRec && VisibleAnalyser.interRec.width > 0 && VisibleAnalyser.interRec.height > 0) { + VisibleAnalyser.tColor++; + CanvasTools.fillCanvasRec(VisibleAnalyser.mainCanvas, tRec, ColorTool.toHexColor(VisibleAnalyser.tColor)); + VisibleAnalyser.tImageData = CanvasTools.getImageDataFromCanvasByRec(VisibleAnalyser.mainCanvas, VisibleAnalyser.tarRec); + var dRate; + dRate = CanvasTools.getDifferRate(VisibleAnalyser.preImageData, VisibleAnalyser.tImageData); + VisibleAnalyser.preImageData = VisibleAnalyser.tImageData; + VisibleAnalyser.addCoverNode(node, dRate); + } + } + } + } + static filterFun(node) { + if (node.visible == false) + return false; + if (node.alpha < 0) + return false; + if (DebugInfoLayer.I.isDebugItem(node)) + return false; + return true; + } + } + VisibleAnalyser.tarRec = new Laya.Rectangle(); + VisibleAnalyser.interRec = new Laya.Rectangle(); + VisibleAnalyser._coverList = []; + + class XML2Object { + static parse(node, isFirst = true) { + var obj = {}; + if (isFirst) + obj.Name = node.localName; + var numOfChilds = node.children.length; + var childs = []; + var children = {}; + obj.c = children; + obj.cList = childs; + for (var i = 0; i < numOfChilds; i++) { + var childNode = node.children[i]; + var childNodeName = childNode.localName; + var value; + var numOfAttributes; + value = XML2Object.parse(childNode, true); + childs.push(value); + if (children[childNodeName]) { + if (XML2Object.getTypeof(children[childNodeName]) == "array") { + children[childNodeName].push(value); + } + else { + children[childNodeName] = [children[childNodeName], value]; + } + } + else if (XML2Object.isArray(childNodeName)) { + children[childNodeName] = [value]; + } + else { + children[childNodeName] = value; + } + } + numOfAttributes = 0; + if (node.attributes) { + numOfAttributes = node.attributes.length; + var prop = {}; + obj.p = prop; + for (i = 0; i < numOfAttributes; i++) { + prop[node.attributes[i].name.toString()] = String(node.attributes[i].nodeValue); + } + } + if (numOfChilds == 0) { + if (numOfAttributes == 0) { + obj = ""; + } + } + return obj; + } + static getArr(v) { + if (!v) + return []; + if (XML2Object.getTypeof(v) == "array") + return v; + return [v]; + } + static get arrays() { + if (!XML2Object._arrays) { + XML2Object._arrays = []; + } + return XML2Object._arrays; + } + static set arrays(a) { + XML2Object._arrays = a; + } + static isArray(nodeName) { + var numOfArrays = XML2Object._arrays ? XML2Object._arrays.length : 0; + for (var i = 0; i < numOfArrays; i++) { + if (nodeName == XML2Object._arrays[i]) { + return true; + } + } + return false; + } + static getTypeof(o) { + if (typeof (o) == "object") { + if (o.length == null) { + return "object"; + } + else if (typeof (o.length) == "number") { + return "array"; + } + else { + return "object"; + } + } + else { + return typeof (o); + } + } + } + + class XML2ObjectNodejs { + static parse(node, isFirst = true) { + var obj = {}; + if (isFirst) + obj.Name = node.localName; + var numOfChilds = node[XML2ObjectNodejs.ChildrenSign] ? node[XML2ObjectNodejs.ChildrenSign].length : 0; + var childs = []; + var children = {}; + obj.c = children; + obj.cList = childs; + for (var i = 0; i < numOfChilds; i++) { + var childNode = node[XML2ObjectNodejs.ChildrenSign][i]; + var childNodeName = childNode.localName; + var value; + var numOfAttributes; + if (!childNodeName) + continue; + value = XML2ObjectNodejs.parse(childNode, true); + childs.push(value); + if (children[childNodeName]) { + if (XML2ObjectNodejs.getTypeof(children[childNodeName]) == "array") { + children[childNodeName].push(value); + } + else { + children[childNodeName] = [children[childNodeName], value]; + } + } + else if (XML2ObjectNodejs.isArray(childNodeName)) { + children[childNodeName] = [value]; + } + else { + children[childNodeName] = value; + } + } + numOfAttributes = 0; + if (node.attributes) { + numOfAttributes = node.attributes.length; + var prop = {}; + obj.p = prop; + for (i = 0; i < numOfAttributes; i++) { + prop[node.attributes[i].name.toString()] = String(node.attributes[i].nodeValue); + } + } + return obj; + } + static getArr(v) { + if (!v) + return []; + if (XML2ObjectNodejs.getTypeof(v) == "array") + return v; + return [v]; + } + static get arrays() { + if (!XML2ObjectNodejs._arrays) { + XML2ObjectNodejs._arrays = []; + } + return XML2ObjectNodejs._arrays; + } + static set arrays(a) { + XML2ObjectNodejs._arrays = a; + } + static isArray(nodeName) { + var numOfArrays = XML2ObjectNodejs._arrays ? XML2ObjectNodejs._arrays.length : 0; + for (var i = 0; i < numOfArrays; i++) { + if (nodeName == XML2ObjectNodejs._arrays[i]) { + return true; + } + } + return false; + } + static getTypeof(o) { + if (typeof (o) == "object") { + if (o.length == null) { + return "object"; + } + else if (typeof (o.length) == "number") { + return "array"; + } + else { + return "object"; + } + } + else { + return typeof (o); + } + } + } + XML2ObjectNodejs.ChildrenSign = "childNodes"; + + class Arrow extends Laya.Sprite { + constructor() { + super(); + this.drawMe(); + } + drawMe() { + var g; + g = this.graphics; + g.clear(); + g.drawLine(0, 0, -1, -1, "#ff0000"); + g.drawLine(0, 0, 1, -1, "#ff0000"); + } + } + + class AutoSizeRec extends Laya.Sprite { + constructor(type) { + super(); + this._color = "#ffffff"; + } + set height(value) { + super.height = value; + this.changeSize(); + } + set width(value) { + super.width = value; + this.changeSize(); + } + setColor(color) { + this._color = color; + this.reRender(); + } + changeSize() { + this.reRender(); + } + reRender() { + var g = this.graphics; + g.clear(); + g.drawRect(0, 0, this.width, this.height, this._color); + } + record() { + this.preX = this.x; + this.preY = this.y; + } + getDx() { + return this.x - this.preX; + } + getDy() { + return this.y - this.preY; + } + } + + class DInput extends Laya.Input { + constructor() { + super(); + this.bgColor = "#11ff00"; + } + } + + class ClassCreateHook { + constructor() { + this.createInfo = {}; + } + static get I() { + if (!ClassCreateHook._instance) { + ClassCreateHook._instance = new ClassCreateHook(); + } + return ClassCreateHook._instance; + } + static set I(value) { + ClassCreateHook._instance = value; + } + hookClass(clz) { + if (ClassCreateHook.isInited) + return; + ClassCreateHook.isInited = true; + var createFun = function (sp) { + this.classCreated(sp, clz); + }; + FunHook.hook(clz, "call", createFun); + } + classCreated(clz, oClass) { + var key; + key = ClassTool.getNodeClassAndName(clz); + var depth = 0; + var tClz; + tClz = clz; + while (tClz && tClz != oClass) { + tClz = tClz.prototype; + depth++; + } + if (!ClassCreateHook.I.createInfo[key]) { + ClassCreateHook.I.createInfo[key] = 0; + } + ClassCreateHook.I.createInfo[key] = ClassCreateHook.I.createInfo[key] + 1; + RunProfile.run(key, depth + 6); + } + getClassCreateInfo(clz) { + var key; + key = ClassTool.getClassName(clz); + return RunProfile.getRunInfo(key); + } + } + ClassCreateHook.isInited = false; + + class FunctionTimeHook { + constructor() { + } + static hookFun(obj, funName) { + if (!obj) + return; + if (obj.timeHooked) + return; + var myKey; + FunctionTimeHook.HookID++; + myKey = ClassTool.getNodeClassAndName(obj) + "." + funName + "():" + FunctionTimeHook.HookID; + var timePreFun = function (...args) { + FunctionTimeHook.funBegin(myKey); + }; + var timeEndFun = function (...args) { + FunctionTimeHook.funEnd(myKey); + }; + obj.timeHooked = true; + FunHook.hook(obj, funName, timePreFun, timeEndFun); + } + static funBegin(funKey) { + FunctionTimeHook.funPre[funKey] = Laya.Browser.now(); + } + static funEnd(funKey) { + if (!FunctionTimeHook.funPre[funKey]) + FunctionTimeHook.funPre[funKey] = 0; + FunctionTimeHook.counter.add(funKey, Laya.Browser.now() - FunctionTimeHook.funPre[funKey]); + } + static fresh() { + FunctionTimeHook.funEnd(FunctionTimeHook.TotalSign); + FunctionTimeHook.counter.record(); + FunctionTimeHook.funBegin(FunctionTimeHook.TotalSign); + } + } + FunctionTimeHook.HookID = 1; + FunctionTimeHook.counter = new CountTool(); + FunctionTimeHook.funPre = {}; + FunctionTimeHook.TotalSign = "TotalSign"; + + class LoaderHook extends Laya.LoaderManager { + constructor() { + super(); + } + static init() { + if (LoaderHook.isInited) + return; + LoaderHook.isInited = true; + Laya.Laya.loader = new LoaderHook(); + Laya.Laya.loader.on(Laya.Event.ERROR, null, LoaderHook.onFail); + LoaderHook.preFails = Laya.LocalStorage.getJSON(LoaderHook.FailSign); + if (!LoaderHook.preFails) + LoaderHook.preFails = {}; + } + static onFail(failFile) { + LoaderHook.nowFails[failFile] = true; + Laya.LocalStorage.setJSON(LoaderHook.FailSign, LoaderHook.nowFails); + } + static resetFails() { + LoaderHook.nowFails = {}; + Laya.LocalStorage.setJSON(LoaderHook.FailSign, LoaderHook.nowFails); + } + checkUrls(url) { + var tarUrl; + if (typeof (url) == 'string') { + tarUrl = url; + } + else { + tarUrl = url.url; + } + if (LoaderHook.preFails[tarUrl]) { + if (LoaderHook.enableFailDebugger) { + debugger; + } + } + } + chekUrlList(urls) { + var i, len; + len = urls.length; + for (i = 0; i < len; i++) { + this.checkUrls(urls[i]); + } + } + load(url, complete = null, progress = null, type = null, priority = 1, cache = true, group = null, ignoreCache = false, useWorkerLoader = false) { + if (url instanceof Array) { + this.chekUrlList(url); + } + else { + this.checkUrls(url); + } + return super.load(url, complete, progress, type, priority, cache, group, ignoreCache, useWorkerLoader); + } + } + LoaderHook.preFails = {}; + LoaderHook.nowFails = {}; + LoaderHook.enableFailDebugger = true; + LoaderHook.FailSign = "LoadFailItems"; + LoaderHook.isInited = false; + + class Observer { + constructor() { + } + static observe(obj, callBack) { + } + static unobserve(obj, callBack) { + } + static observeDiffer(obj, sign, msg = "obDiffer") { + var differFun = function () { + DifferTool.differ(sign, obj, msg); + }; + Observer.observe(obj, differFun); + } + } + + class Watch { + constructor() { + } + static watch(obj, name, callBack) { + obj.watch(name, callBack); + } + static unwatch(obj, name, callBack) { + obj.unwatch(name, callBack); + } + } + + class Layouter { + constructor() { + this._sX = 0; + this._width = 0; + } + layout() { + this.layoutFun(this._width, this._items, this.data, this._sX); + } + set items(arr) { + this._items = arr; + this.calSize(); + } + get items() { + return this._items; + } + set x(v) { + this._sX = v; + this.changed(); + } + get x() { + return this._sX; + } + set width(v) { + this._width = v; + this.changed(); + } + get width() { + return this._width; + } + changed() { + Laya.Laya.timer.callLater(this, this.layout); + } + calSize() { + var i, len; + var tItem; + tItem = this.items[0]; + this._sX = tItem.x; + var maxX; + maxX = this._sX + tItem.width; + len = this.items.length; + for (i = 1; i < len; i++) { + tItem = this.items[i]; + if (this._sX > tItem.x) { + this._sX = tItem.x; + } + if (maxX < tItem.x + tItem.width) { + maxX = tItem.x + tItem.width; + } + } + this._width = maxX - this._sX; + } + } + + class LayoutFuns { + constructor() { + } + static sameWidth(totalWidth, items, data = null, sX = 0) { + var dWidth = 0; + if (data && data.dWidth) + dWidth = data.dWidth; + var perWidth; + perWidth = (totalWidth - (items.length - 1) * dWidth) / items.length; + var tItem; + var i, len; + var tX; + tX = sX; + len = items.length; + for (i = 0; i < len; i++) { + tItem = items[i]; + tItem.x = tX; + tItem.width = perWidth; + tX += dWidth + perWidth; + } + } + static getSameWidthLayout(items, dWidth) { + var data; + data = {}; + data.dWidth = dWidth; + return LayoutFuns.getLayouter(items, data, LayoutFuns.sameWidth); + } + static getLayouter(items, data, fun) { + var layouter; + layouter = new Layouter(); + layouter.items = items; + layouter.data = data; + layouter.layoutFun = fun; + return layouter; + } + static sameDis(totalWidth, items, data = null, sX = 0) { + var dWidth; + dWidth = totalWidth; + var tItem; + var i, len; + len = items.length; + LayoutFuns.prepareForLayoutWidth(totalWidth, items); + for (i = 0; i < len; i++) { + tItem = items[i]; + dWidth -= tItem.width; + } + if (items.length > 1) + dWidth = dWidth / (items.length - 1); + var tX; + tX = sX; + len = items.length; + for (i = 0; i < len; i++) { + tItem = items[i]; + tItem.x = tX; + tX += dWidth + tItem.width; + } + } + static getSameDisLayout(items, rateSame = false) { + var data; + data = {}; + if (rateSame) { + var i, len; + len = items.length; + var tItem; + var totalWidth; + totalWidth = 0; + for (i = 0; i < len; i++) { + tItem = items[i]; + totalWidth += tItem.width; + } + totalWidth = tItem.x + tItem.width; + for (i = 0; i < len; i++) { + tItem = items[i]; + LayoutFuns.setItemRate(tItem, tItem.width / totalWidth); + } + } + return LayoutFuns.getLayouter(items, data, LayoutFuns.sameDis); + } + static fullFill(totalWidth, items, data = null, sX = 0) { + var dL = 0, dR = 0; + if (data) { + if (data.dL) + dL = data.dL; + if (data.dR) + dR = data.dR; + } + var item; + var i, len; + len = items.length; + for (i = 0; i < len; i++) { + item = items[i]; + item.x = sX + dL; + item.width = totalWidth - dL - dR; + } + } + static getFullFillLayout(items, dL = 0, dR = 0) { + var data; + data = {}; + data.dL = dL; + data.dR = dR; + return LayoutFuns.getLayouter(items, data, LayoutFuns.fullFill); + } + static fixPos(totalWidth, items, data = null, sX = 0) { + var dLen = 0; + var poss = []; + var isRate = false; + if (data) { + if (data.dLen) + dLen = data.dLen; + if (data.poss) + poss = data.poss; + if (data.isRate) + isRate = data.isRate; + } + var item; + var i, len; + len = poss.length; + var tValue; + var preItem; + preItem = null; + for (i = 0; i < len; i++) { + item = items[i]; + tValue = sX + poss[i]; + if (isRate) { + tValue = sX + poss[i] * totalWidth; + } + item.x = tValue; + if (preItem) { + preItem.width = item.x - dLen - preItem.x; + } + preItem = item; + } + var lastItem; + lastItem = items[items.length - 1]; + lastItem.width = sX + totalWidth - dLen - lastItem.x; + } + static getFixPos(items, dLen = 0, isRate = false, poss = null) { + var data; + data = {}; + var layout; + layout = LayoutFuns.getLayouter(items, data, LayoutFuns.fixPos); + var i, len; + var sX; + var totalWidth; + sX = layout.x; + totalWidth = layout.width; + if (!poss) { + poss = []; + len = items.length; + var tValue; + for (i = 0; i < len; i++) { + tValue = items[i].x - sX; + if (isRate) { + tValue = tValue / totalWidth; + } + poss.push(tValue); + } + } + data.dLen = dLen; + data.poss = poss; + data.isRate = isRate; + return layout; + } + static clearItemsRelativeInfo(items) { + var i, len; + len = items.length; + for (i = 0; i < len; i++) { + LayoutFuns.clearItemRelativeInfo(items[i]); + } + } + static clearItemRelativeInfo(item) { + var Nan = "NaN"; + item.left = Nan; + item.right = Nan; + } + static prepareForLayoutWidth(totalWidth, items) { + var i, len; + len = items.length; + for (i = 0; i < len; i++) { + LayoutFuns.prepareItemForLayoutWidth(totalWidth, items[i]); + } + } + static getSumWidth(items) { + var sum; + sum = 0; + var i, len; + len = items.length; + for (i = 0; i < len; i++) { + sum += items[i].width; + } + return sum; + } + static prepareItemForLayoutWidth(totalWidth, item) { + if (LayoutFuns.getItemRate(item) > 0) { + item.width = totalWidth * LayoutFuns.getItemRate(item); + } + } + static setItemRate(item, rate) { + item[LayoutFuns.RateSign] = rate; + } + static getItemRate(item) { + return item[LayoutFuns.RateSign] ? item[LayoutFuns.RateSign] : -1; + } + static setItemFreeSize(item, free = true) { + item[LayoutFuns.FreeSizeSign] = free; + } + static isItemFreeSize(item) { + return item[LayoutFuns.FreeSizeSign]; + } + static lockedDis(totalWidth, items, data = null, sX = 0) { + var dists; + dists = data.dists; + var sumDis; + sumDis = data.sumDis; + var sumWidth; + var i, len; + var tItem; + var preItem; + LayoutFuns.prepareForLayoutWidth(totalWidth, items); + sumWidth = LayoutFuns.getSumWidth(items); + var dWidth; + dWidth = totalWidth - sumDis - sumWidth; + var freeItem; + freeItem = LayoutFuns.getFreeItem(items); + if (freeItem) { + freeItem.width += dWidth; + } + preItem = items[0]; + preItem.x = sX; + len = items.length; + for (i = 1; i < len; i++) { + tItem = items[i]; + tItem.x = preItem.x + preItem.width + dists[i - 1]; + preItem = tItem; + } + } + static getFreeItem(items) { + var i, len; + len = items.length; + for (i = 0; i < len; i++) { + if (LayoutFuns.isItemFreeSize(items[i])) { + return items[i]; + } + } + return null; + } + static getLockedDis(items) { + var data; + data = {}; + var dists; + var i, len; + var tItem; + var preItem; + var sumDis; + sumDis = 0; + var tDis; + preItem = items[0]; + dists = []; + len = items.length; + for (i = 1; i < len; i++) { + tItem = items[i]; + tDis = tItem.x - preItem.x - preItem.width; + dists.push(tDis); + sumDis += tDis; + preItem = tItem; + } + data.dists = dists; + data.sumDis = sumDis; + return LayoutFuns.getLayouter(items, data, LayoutFuns.lockedDis); + } + } + LayoutFuns.RateSign = "layoutRate"; + LayoutFuns.FreeSizeSign = "layoutFreeSize"; + + class AutoFillRec extends Laya.Sprite { + constructor(type) { + super(); + } + set width(value) { + super.width = value; + this.changeSize(); + } + set height(value) { + super.height = value; + this.changeSize(); + } + changeSize() { + var g = this.graphics; + g.clear(); + g.drawRect(0, 0, this.width, this.height, "#33c5f5"); + } + record() { + this.preX = this.x; + this.preY = this.y; + } + getDx() { + return this.x - this.preX; + } + getDy() { + return this.y - this.preY; + } + } + + class DisResizer { + constructor() { } + static init() { + if (DisResizer._up) + return; + DisResizer._up = new AutoFillRec("T"); + DisResizer._up.height = DisResizer.barWidth; + DisResizer._up.type = DisResizer.Horizon; + DisResizer._down = new AutoFillRec("T"); + DisResizer._down.height = DisResizer.barWidth; + DisResizer._down.type = DisResizer.Horizon; + DisResizer._left = new AutoFillRec("R"); + DisResizer._left.width = DisResizer.barWidth; + DisResizer._left.type = DisResizer.Vertical; + DisResizer._right = new AutoFillRec("R"); + DisResizer._right.width = DisResizer.barWidth; + DisResizer._right.type = DisResizer.Vertical; + DisResizer._barList = [DisResizer._up, DisResizer._down, DisResizer._left, DisResizer._right]; + DisResizer.addEvent(); + } + static stageDown(e) { + var target; + target = e.target; + if (DisResizer._tar && DisControlTool.isInTree(DisResizer._tar, target)) { + return; + } + DisResizer.clear(); + } + static clear() { + DisResizer._tar = null; + Laya.Laya.stage.off(Laya.Event.MOUSE_UP, null, DisResizer.stageDown); + DisControlTool.removeItems(DisResizer._barList); + DisResizer.clearDragEvents(); + } + static addEvent() { + var i, len; + var tBar; + len = DisResizer._barList.length; + for (i = 0; i < len; i++) { + tBar = DisResizer._barList[i]; + tBar.on(Laya.Event.MOUSE_DOWN, null, DisResizer.barDown); + } + } + static barDown(e) { + DisResizer.clearDragEvents(); + DisResizer.tBar = e.target; + if (!DisResizer.tBar) + return; + var area; + area = new Laya.Rectangle(); + if (DisResizer.tBar.type == DisResizer.Horizon) { + area.x = DisResizer.tBar.x; + area.width = 0; + area.y = DisResizer.tBar.y - 200; + area.height = 400; + } + else { + area.x = DisResizer.tBar.x - 200; + area.width = 400; + area.y = 0; + area.height = 0; + } + var option; + option = {}; + option.area = area; + DisResizer.tBar.record(); + DisResizer.tBar.startDrag(area); + DisResizer.tBar.on(Laya.Event.DRAG_MOVE, null, DisResizer.draging); + DisResizer.tBar.on(Laya.Event.DRAG_END, null, DisResizer.dragEnd); + } + static draging(e) { + console.log("draging"); + if (!DisResizer.tBar) + return; + if (!DisResizer._tar) + return; + switch (DisResizer.tBar) { + case DisResizer._left: + DisResizer._tar.x += DisResizer.tBar.getDx(); + DisResizer._tar.width -= DisResizer.tBar.getDx(); + DisResizer._up.width -= DisResizer.tBar.getDx(); + DisResizer._down.width -= DisResizer.tBar.getDx(); + DisResizer._right.x -= DisResizer.tBar.getDx(); + DisResizer.tBar.x -= DisResizer.tBar.getDx(); + break; + case DisResizer._right: + DisResizer._tar.width += DisResizer.tBar.getDx(); + DisResizer._up.width += DisResizer.tBar.getDx(); + DisResizer._down.width += DisResizer.tBar.getDx(); + break; + case DisResizer._up: + DisResizer._tar.y += DisResizer.tBar.getDy(); + DisResizer._tar.height -= DisResizer.tBar.getDy(); + DisResizer._right.height -= DisResizer.tBar.getDy(); + DisResizer._left.height -= DisResizer.tBar.getDy(); + DisResizer._down.y -= DisResizer.tBar.getDy(); + DisResizer.tBar.y -= DisResizer.tBar.getDy(); + break; + case DisResizer._down: + DisResizer._tar.height += DisResizer.tBar.getDy(); + DisResizer._right.height += DisResizer.tBar.getDy(); + DisResizer._left.height += DisResizer.tBar.getDy(); + break; + } + DisResizer.tBar.record(); + } + static dragEnd(e) { + console.log("dragEnd"); + DisResizer.clearDragEvents(); + DisResizer.updates(); + } + static clearDragEvents() { + if (!DisResizer.tBar) + return; + DisResizer.tBar.off(Laya.Event.DRAG_MOVE, null, DisResizer.draging); + DisResizer.tBar.off(Laya.Event.DRAG_END, null, DisResizer.dragEnd); + } + static setUp(dis, force = false) { + if (force && dis == DisResizer._tar) { + return; + } + DisControlTool.removeItems(DisResizer._barList); + if (DisResizer._tar == dis) { + DisResizer._tar = null; + DisResizer.clearDragEvents(); + if (!force) + return; + } + DisResizer._tar = dis; + DisResizer.updates(); + DisControlTool.addItems(DisResizer._barList, dis); + Laya.Laya.stage.off(Laya.Event.MOUSE_UP, null, DisResizer.stageDown); + Laya.Laya.stage.on(Laya.Event.MOUSE_UP, null, DisResizer.stageDown); + } + static updates() { + var dis; + dis = DisResizer._tar; + if (!dis) + return; + var bounds; + bounds = new Laya.Rectangle(0, 0, dis.width, dis.height); + DisResizer._up.x = bounds.x; + DisResizer._up.y = bounds.y; + DisResizer._up.width = bounds.width; + DisResizer._down.x = bounds.x; + DisResizer._down.y = bounds.y + bounds.height - DisResizer.barWidth; + DisResizer._down.width = bounds.width; + DisResizer._left.x = bounds.x; + DisResizer._left.y = bounds.y; + DisResizer._left.height = bounds.height; + DisResizer._right.x = bounds.x + bounds.width - DisResizer.barWidth; + DisResizer._right.y = bounds.y; + DisResizer._right.height = bounds.height; + } + } + DisResizer.Side = 2; + DisResizer.Vertical = 1; + DisResizer.Horizon = 0; + DisResizer.barWidth = 2; + DisResizer.useGetBounds = false; + DisControlTool.resizeHandler = DisResizer.setUp; + + class StyleConsts { + constructor() { + } + static setViewScale(view) { + view.scaleX = view.scaleY = StyleConsts.PanelScale; + } + } + StyleConsts.PanelScale = Laya.Browser.onPC ? 1 : Laya.Browser.pixelRatio; + + exports.Arrow = Arrow; + exports.ArrowLine = ArrowLine; + exports.AtlasTools = AtlasTools; + exports.AutoFillRec = AutoFillRec; + exports.AutoSizeRec = AutoSizeRec; + exports.Axis = Axis; + exports.Base64Atlas = Base64Atlas; + exports.Base64AtlasManager = Base64AtlasManager; + exports.Base64ImageTool = Base64ImageTool; + exports.Base64Tool = Base64Tool; + exports.ByteEx = ByteEx; + exports.CacheAnalyser = CacheAnalyser; + exports.CallLaterTool = CallLaterTool; + exports.CanvasTools = CanvasTools; + exports.ClassCreateHook = ClassCreateHook; + exports.ClassTool = ClassTool; + exports.ClickSelectTool = ClickSelectTool; + exports.ColorTool = ColorTool; + exports.CommonTools = CommonTools; + exports.CountTool = CountTool; + exports.DButton = DButton; + exports.DInput = DInput; + exports.DTrace = DTrace; + exports.DebugConsts = DebugConsts; + exports.DebugInfoLayer = DebugInfoLayer; + exports.DebugPanel = DebugPanel; + exports.DebugTool = DebugTool; + exports.DebugTxt = DebugTxt; + exports.DifferTool = DifferTool; + exports.DisControlTool = DisControlTool; + exports.DisController = DisController; + exports.DisEditor = DisEditor; + exports.DisPool = DisPool; + exports.DisResizer = DisResizer; + exports.DisplayHook = DisplayHook; + exports.DivScripts = DivScripts; + exports.DragBox = DragBox; + exports.FilterTool = FilterTool; + exports.FunHook = FunHook; + exports.FunctionTimeHook = FunctionTimeHook; + exports.GetSetProfile = GetSetProfile; + exports.IDTools = IDTools; + exports.JSTools = JSTools; + exports.JsonTool = JsonTool; + exports.LayoutFuns = LayoutFuns; + exports.LayoutTools = LayoutTools; + exports.Layouter = Layouter; + exports.LoaderHook = LoaderHook; + exports.MathTools = MathTools; + exports.MouseEventAnalyser = MouseEventAnalyser; + exports.NodeConsts = NodeConsts; + exports.NodeInfoPanel = NodeInfoPanel; + exports.NodeInfosItem = NodeInfosItem; + exports.NodeRecInfo = NodeRecInfo; + exports.NodeUtils = NodeUtils; + exports.Notice = Notice; + exports.ObjTimeCountTool = ObjTimeCountTool; + exports.ObjectTools = ObjectTools; + exports.Observer = Observer; + exports.ReCacheRecInfo = ReCacheRecInfo; + exports.RecInfo = RecInfo; + exports.Rect = Rect; + exports.RenderAnalyser = RenderAnalyser; + exports.RenderSpriteHook = RenderSpriteHook; + exports.ResTools = ResTools; + exports.RunProfile = RunProfile; + exports.SimpleResizer = SimpleResizer; + exports.SingleTool = SingleTool; + exports.SpriteRenderHook = SpriteRenderHook; + exports.StringTool = StringTool; + exports.StyleConsts = StyleConsts; + exports.TimeTool = TimeTool; + exports.TimerControlTool = TimerControlTool; + exports.TouchDebugTools = TouchDebugTools; + exports.TraceTool = TraceTool; + exports.UVTools = UVTools; + exports.ValueChanger = ValueChanger; + exports.VarHook = VarHook; + exports.VisibleAnalyser = VisibleAnalyser; + exports.WalkTools = WalkTools; + exports.Watch = Watch; + exports.Watcher = Watcher; + exports.XML2Object = XML2Object; + exports.XML2ObjectNodejs = XML2ObjectNodejs; + +}(window.Laya = window.Laya || {}, Laya)); diff --git a/examples/layaair/frontend/bin/libs/laya.device.js b/examples/layaair/frontend/bin/libs/laya.device.js new file mode 100644 index 0000000..72866de --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.device.js @@ -0,0 +1,678 @@ +(function (exports, Laya) { + 'use strict'; + + class AccelerationInfo { + constructor() { + } + } + + class RotationInfo { + constructor() { + } + } + + class Accelerator extends Laya.EventDispatcher { + constructor(singleton) { + super(); + this.onDeviceOrientationChange = this.onDeviceOrientationChange.bind(this); + } + static get instance() { + Accelerator._instance = Accelerator._instance || new Accelerator(0); + return Accelerator._instance; + } + on(type, caller, listener, args = null) { + super.on(type, caller, listener, args); + Laya.ILaya.Browser.window.addEventListener('devicemotion', this.onDeviceOrientationChange); + return this; + } + off(type, caller, listener, onceOnly = false) { + if (!this.hasListener(type)) + Laya.ILaya.Browser.window.removeEventListener('devicemotion', this.onDeviceOrientationChange); + return super.off(type, caller, listener, onceOnly); + } + onDeviceOrientationChange(e) { + var interval = e.interval; + Accelerator.acceleration.x = e.acceleration.x; + Accelerator.acceleration.y = e.acceleration.y; + Accelerator.acceleration.z = e.acceleration.z; + Accelerator.accelerationIncludingGravity.x = e.accelerationIncludingGravity.x; + Accelerator.accelerationIncludingGravity.y = e.accelerationIncludingGravity.y; + Accelerator.accelerationIncludingGravity.z = e.accelerationIncludingGravity.z; + Accelerator.rotationRate.alpha = e.rotationRate.gamma * -1; + Accelerator.rotationRate.beta = e.rotationRate.alpha * -1; + Accelerator.rotationRate.gamma = e.rotationRate.beta; + if (Laya.ILaya.Browser.onAndroid) { + if (Laya.ILaya.Browser.userAgent.indexOf("Chrome") > -1) { + Accelerator.rotationRate.alpha *= 180 / Math.PI; + Accelerator.rotationRate.beta *= 180 / Math.PI; + Accelerator.rotationRate.gamma *= 180 / Math.PI; + } + Accelerator.acceleration.x *= -1; + Accelerator.accelerationIncludingGravity.x *= -1; + } + else if (Laya.ILaya.Browser.onIOS) { + Accelerator.acceleration.y *= -1; + Accelerator.acceleration.z *= -1; + Accelerator.accelerationIncludingGravity.y *= -1; + Accelerator.accelerationIncludingGravity.z *= -1; + interval *= 1000; + } + this.event(Laya.Event.CHANGE, [Accelerator.acceleration, Accelerator.accelerationIncludingGravity, Accelerator.rotationRate, interval]); + } + static getTransformedAcceleration(acceleration) { + Accelerator.transformedAcceleration = Accelerator.transformedAcceleration || new AccelerationInfo(); + Accelerator.transformedAcceleration.z = acceleration.z; + if (Laya.ILaya.Browser.window.orientation == 90) { + Accelerator.transformedAcceleration.x = acceleration.y; + Accelerator.transformedAcceleration.y = -acceleration.x; + } + else if (Laya.ILaya.Browser.window.orientation == -90) { + Accelerator.transformedAcceleration.x = -acceleration.y; + Accelerator.transformedAcceleration.y = acceleration.x; + } + else if (!Laya.ILaya.Browser.window.orientation) { + Accelerator.transformedAcceleration.x = acceleration.x; + Accelerator.transformedAcceleration.y = acceleration.y; + } + else if (Laya.ILaya.Browser.window.orientation == 180) { + Accelerator.transformedAcceleration.x = -acceleration.x; + Accelerator.transformedAcceleration.y = -acceleration.y; + } + var tx; + if (Laya.ILaya.stage.canvasDegree == -90) { + tx = Accelerator.transformedAcceleration.x; + Accelerator.transformedAcceleration.x = -Accelerator.transformedAcceleration.y; + Accelerator.transformedAcceleration.y = tx; + } + else if (Laya.ILaya.stage.canvasDegree == 90) { + tx = Accelerator.transformedAcceleration.x; + Accelerator.transformedAcceleration.x = Accelerator.transformedAcceleration.y; + Accelerator.transformedAcceleration.y = -tx; + } + return Accelerator.transformedAcceleration; + } + } + Accelerator.acceleration = new AccelerationInfo(); + Accelerator.accelerationIncludingGravity = new AccelerationInfo(); + Accelerator.rotationRate = new RotationInfo(); + + class Shake extends Laya.EventDispatcher { + constructor() { + super(); + } + static get instance() { + Shake._instance = Shake._instance || new Shake(); + return Shake._instance; + } + start(throushold, interval) { + this.throushold = throushold; + this.shakeInterval = interval; + this.lastX = this.lastY = this.lastZ = NaN; + Accelerator.instance.on(Laya.Event.CHANGE, this, this.onShake); + } + stop() { + Accelerator.instance.off(Laya.Event.CHANGE, this, this.onShake); + } + onShake(acceleration, accelerationIncludingGravity, rotationRate, interval) { + if (isNaN(this.lastX)) { + this.lastX = accelerationIncludingGravity.x; + this.lastY = accelerationIncludingGravity.y; + this.lastZ = accelerationIncludingGravity.z; + this.lastMillSecond = Laya.ILaya.Browser.now(); + return; + } + var deltaX = Math.abs(this.lastX - accelerationIncludingGravity.x); + var deltaY = Math.abs(this.lastY - accelerationIncludingGravity.y); + var deltaZ = Math.abs(this.lastZ - accelerationIncludingGravity.z); + if (this.isShaked(deltaX, deltaY, deltaZ)) { + var deltaMillSecond = Laya.ILaya.Browser.now() - this.lastMillSecond; + if (deltaMillSecond > this.shakeInterval) { + this.event(Laya.Event.CHANGE); + this.lastMillSecond = Laya.ILaya.Browser.now(); + } + } + this.lastX = accelerationIncludingGravity.x; + this.lastY = accelerationIncludingGravity.y; + this.lastZ = accelerationIncludingGravity.z; + } + isShaked(deltaX, deltaY, deltaZ) { + return (deltaX > this.throushold && deltaY > this.throushold) || + (deltaX > this.throushold && deltaZ > this.throushold) || + (deltaY > this.throushold && deltaZ > this.throushold); + } + } + + class GeolocationInfo { + setPosition(pos) { + this.pos = pos; + this.coords = pos.coords; + } + get latitude() { + return this.coords.latitude; + } + get longitude() { + return this.coords.longitude; + } + get altitude() { + return this.coords.altitude; + } + get accuracy() { + return this.coords.accuracy; + } + get altitudeAccuracy() { + return this.coords.altitudeAccuracy; + } + get heading() { + return this.coords.heading; + } + get speed() { + return this.coords.speed; + } + get timestamp() { + return this.pos.timestamp; + } + } + + class Geolocation { + constructor() { + } + static getCurrentPosition(onSuccess, onError = null) { + Geolocation.navigator.geolocation.getCurrentPosition(function (pos) { + Geolocation.position.setPosition(pos); + onSuccess.runWith(Geolocation.position); + }, function (error) { + onError.runWith(error); + }, { + enableHighAccuracy: Geolocation.enableHighAccuracy, + timeout: Geolocation.timeout, + maximumAge: Geolocation.maximumAge + }); + } + static watchPosition(onSuccess, onError) { + return Geolocation.navigator.geolocation.watchPosition(function (pos) { + Geolocation.position.setPosition(pos); + onSuccess.runWith(Geolocation.position); + }, function (error) { + onError.runWith(error); + }, { + enableHighAccuracy: Geolocation.enableHighAccuracy, + timeout: Geolocation.timeout, + maximumAge: Geolocation.maximumAge + }); + } + static clearWatch(id) { + Geolocation.navigator.geolocation.clearWatch(id); + } + } + Geolocation.navigator = navigator; + Geolocation.position = new GeolocationInfo(); + Geolocation.PERMISSION_DENIED = 1; + Geolocation.POSITION_UNAVAILABLE = 2; + Geolocation.TIMEOUT = 3; + Geolocation.supported = !!Geolocation.navigator.geolocation; + Geolocation.enableHighAccuracy = false; + Geolocation.timeout = 1E10; + Geolocation.maximumAge = 0; + + class HtmlVideo extends Laya.Bitmap { + constructor() { + super(); + this._w = 0; + this._h = 0; + this._width = 1; + this._height = 1; + this.createDomElement(); + } + createDomElement() { + this._source = this.video = Laya.ILaya.Browser.createElement("video"); + var style = this.video.style; + style.position = 'absolute'; + style.top = '0px'; + style.left = '0px'; + this.video.addEventListener("loadedmetadata", () => { + this._w = this.video.videoWidth; + this._h = this.video.videoHeight; + }); + } + setSource(url, extension) { + while (this.video.childElementCount) + this.video.firstChild.remove(); + if (extension & 1) + this.appendSource(url, "video/mp4"); + if (extension & 2) + this.appendSource(url + ".ogg", "video/ogg"); + } + appendSource(source, type) { + var sourceElement = Laya.ILaya.Browser.createElement("source"); + sourceElement.src = source; + sourceElement.type = type; + this.video.appendChild(sourceElement); + } + getVideo() { + return this.video; + } + _getSource() { + return this._source; + } + destroy() { + super.destroy(); + var isConchApp = Laya.ILaya.Render.isConchApp; + if (isConchApp) { + this.video._destroy(); + } + } + } + HtmlVideo.create = function () { + return new HtmlVideo(); + }; + + class Media { + constructor() { + } + static supported() { + return !!Laya.ILaya.Browser.window.navigator.getUserMedia; + } + static getMedia(options, onSuccess, onError) { + if (Laya.ILaya.Browser.window.navigator.getUserMedia) { + Laya.ILaya.Browser.window.navigator.getUserMedia(options, function (stream) { + onSuccess.runWith(Laya.ILaya.Browser.window.URL.createObjectURL(stream)); + }, function (err) { + onError.runWith(err); + }); + } + } + } + + class WebGLVideo extends HtmlVideo { + constructor() { + super(); + var gl = Laya.LayaGL.instance; + this.gl = Laya.ILaya.Render.isConchApp ? window.LayaGLContext.instance : Laya.WebGLContext.mainContext; + this._source = this.gl.createTexture(); + Laya.WebGLContext.bindTexture(this.gl, gl.TEXTURE_2D, this._source); + this.gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + this.gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + this.gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + this.gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + Laya.WebGLContext.bindTexture(this.gl, gl.TEXTURE_2D, null); + } + updateTexture() { + var gl = Laya.LayaGL.instance; + Laya.WebGLContext.bindTexture(this.gl, gl.TEXTURE_2D, this._source); + this.gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); + this.gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, this.video); + this.gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + WebGLVideo.curBindSource = this._source; + } + get _glTexture() { + return this._source; + } + destroy() { + if (this._source) { + this.gl = Laya.ILaya.Render.isConchApp ? window.LayaGLContext.instance : Laya.WebGLContext.mainContext; + if (this.gl) { + if (WebGLVideo.curBindSource == this._source) { + Laya.WebGLContext.bindTexture(this.gl, this.gl.TEXTURE_2D, null); + WebGLVideo.curBindSource = null; + } + this.gl.deleteTexture(this._source); + } + } + super.destroy(); + } + } + + class Video extends Laya.Sprite { + constructor(width = 320, height = 240) { + super(); + this.htmlVideo = new WebGLVideo(); + this.videoElement = this.htmlVideo.getVideo(); + this.videoElement.layaTarget = this; + this.internalTexture = new Laya.Texture(this.htmlVideo); + this.videoElement.addEventListener("abort", Video.onAbort); + this.videoElement.addEventListener("canplay", Video.onCanplay); + this.videoElement.addEventListener("canplaythrough", Video.onCanplaythrough); + this.videoElement.addEventListener("durationchange", Video.onDurationchange); + this.videoElement.addEventListener("emptied", Video.onEmptied); + this.videoElement.addEventListener("error", Video.onError); + this.videoElement.addEventListener("loadeddata", Video.onLoadeddata); + this.videoElement.addEventListener("loadedmetadata", Video.onLoadedmetadata); + this.videoElement.addEventListener("loadstart", Video.onLoadstart); + this.videoElement.addEventListener("pause", Video.onPause); + this.videoElement.addEventListener("play", Video.onPlay); + this.videoElement.addEventListener("playing", Video.onPlaying); + this.videoElement.addEventListener("progress", Video.onProgress); + this.videoElement.addEventListener("ratechange", Video.onRatechange); + this.videoElement.addEventListener("seeked", Video.onSeeked); + this.videoElement.addEventListener("seeking", Video.onSeeking); + this.videoElement.addEventListener("stalled", Video.onStalled); + this.videoElement.addEventListener("suspend", Video.onSuspend); + this.videoElement.addEventListener("timeupdate", Video.onTimeupdate); + this.videoElement.addEventListener("volumechange", Video.onVolumechange); + this.videoElement.addEventListener("waiting", Video.onWaiting); + this.videoElement.addEventListener("ended", this.onPlayComplete['bind'](this)); + this.size(width, height); + if (Laya.ILaya.Browser.onMobile) { + this.videoElement["x5-playsInline"] = true; + this.videoElement["x5-playsinline"] = true; + this.videoElement.x5PlaysInline = true; + this.videoElement.playsInline = true; + this.videoElement["webkit-playsInline"] = true; + this.videoElement["webkit-playsinline"] = true; + this.videoElement.webkitPlaysInline = true; + this.videoElement.playsinline = true; + this.videoElement.style.playsInline = true; + this.videoElement.crossOrigin = "anonymous"; + this.videoElement.setAttribute('crossorigin', "anonymous"); + this.videoElement.setAttribute('playsinline', 'true'); + this.videoElement.setAttribute('x5-playsinline', 'true'); + this.videoElement.setAttribute('webkit-playsinline', 'true'); + this.videoElement.autoplay = true; + this._clickhandle = this.onDocumentClick.bind(this); + Laya.ILaya.Browser.document.addEventListener("touchend", this._clickhandle); + } + } + static onAbort(e) { e.target.layaTarget.event("abort"); } + static onCanplay(e) { e.target.layaTarget.event("canplay"); } + static onCanplaythrough(e) { e.target.layaTarget.event("canplaythrough"); } + static onDurationchange(e) { e.target.layaTarget.event("durationchange"); } + static onEmptied(e) { e.target.layaTarget.event("emptied"); } + static onError(e) { e.target.layaTarget.event("error"); } + static onLoadeddata(e) { e.target.layaTarget.event("loadeddata"); } + static onLoadedmetadata(e) { e.target.layaTarget.event("loadedmetadata"); } + static onLoadstart(e) { e.target.layaTarget.event("loadstart"); } + static onPause(e) { e.target.layaTarget.event("pause"); } + static onPlay(e) { e.target.layaTarget.event("play"); } + static onPlaying(e) { e.target.layaTarget.event("playing"); } + static onProgress(e) { e.target.layaTarget.event("progress"); } + static onRatechange(e) { e.target.layaTarget.event("ratechange"); } + static onSeeked(e) { e.target.layaTarget.event("seeked"); } + static onSeeking(e) { e.target.layaTarget.event("seeking"); } + static onStalled(e) { e.target.layaTarget.event("stalled"); } + static onSuspend(e) { e.target.layaTarget.event("suspend"); } + static onTimeupdate(e) { e.target.layaTarget.event("timeupdate"); } + static onVolumechange(e) { e.target.layaTarget.event("volumechange"); } + static onWaiting(e) { e.target.layaTarget.event("waiting"); } + onPlayComplete(e) { + if (!Laya.ILaya.Render.isConchApp || !this.videoElement || !this.videoElement.loop) + Laya.ILaya.timer.clear(this, this.renderCanvas); + this.event("ended"); + } + load(url) { + if (url.indexOf("blob:") == 0) + this.videoElement.src = url; + else + this.htmlVideo.setSource(url, 1); + } + play() { + this.videoElement.play(); + Laya.ILaya.timer.frameLoop(1, this, this.renderCanvas); + } + pause() { + this.videoElement.pause(); + Laya.ILaya.timer.clear(this, this.renderCanvas); + } + reload() { + this.videoElement.load(); + } + canPlayType(type) { + var typeString; + switch (type) { + case 1: + typeString = "video/mp4"; + break; + case 2: + typeString = "video/ogg"; + break; + case 8: + typeString = "video/webm"; + break; + } + return this.videoElement.canPlayType(typeString); + } + renderCanvas() { + if (this.readyState === 0) + return; + this.htmlVideo['updateTexture'](); + this.graphics.clear(); + this.graphics.drawTexture(this.internalTexture, 0, 0, this.width, this.height); + } + onDocumentClick() { + if (!this.videoElement || this.videoElement != 0) + return; + if (Laya.Browser.onIOS) { + this.videoElement.load(); + } + else { + this.videoElement.play(); + this.videoElement.pause(); + } + Laya.ILaya.Browser.document.removeEventListener("touchend", this._clickhandle); + } + get buffered() { + return this.videoElement.buffered; + } + get currentSrc() { + return this.videoElement.currentSrc; + } + get currentTime() { + return this.videoElement.currentTime; + } + set currentTime(value) { + this.videoElement.currentTime = value; + this.renderCanvas(); + } + set volume(value) { + this.videoElement.volume = value; + } + get volume() { + return this.videoElement.volume; + } + get readyState() { + return this.videoElement.readyState; + } + get videoWidth() { + return this.videoElement.videoWidth; + } + get videoHeight() { + return this.videoElement.videoHeight; + } + get duration() { + return this.videoElement.duration; + } + get ended() { + return this.videoElement.ended; + } + get error() { + return this.videoElement.error; + } + get loop() { + return this.videoElement.loop; + } + set loop(value) { + this.videoElement.loop = value; + } + set x(val) { + super.x = val; + if (Laya.ILaya.Render.isConchApp) { + var transform = Laya.ILaya.Utils.getTransformRelativeToWindow(this, 0, 0); + this.videoElement.style.left = transform.x; + } + } + get x() { + return super.x; + } + set y(val) { + super.y = val; + if (Laya.ILaya.Render.isConchApp) { + var transform = Laya.ILaya.Utils.getTransformRelativeToWindow(this, 0, 0); + this.videoElement.style.top = transform.y; + } + } + get y() { + return super.y; + } + get playbackRate() { + return this.videoElement.playbackRate; + } + set playbackRate(value) { + this.videoElement.playbackRate = value; + } + get muted() { + return this.videoElement.muted; + } + set muted(value) { + this.videoElement.muted = value; + } + get paused() { + return this.videoElement.paused; + } + get preload() { + return this.videoElement.preload; + } + set preload(value) { + this.videoElement.preload = value; + } + get seekable() { + return this.videoElement.seekable; + } + get seeking() { + return this.videoElement.seeking; + } + size(width, height) { + super.size(width, height); + if (Laya.ILaya.Render.isConchApp) { + var transform = Laya.ILaya.Utils.getTransformRelativeToWindow(this, 0, 0); + this.videoElement.width = width * transform.scaleX; + } + else { + this.videoElement.width = width / Laya.ILaya.Browser.pixelRatio; + this.videoElement.height = height / Laya.Browser.pixelRatio; + } + if (this.paused) + this.renderCanvas(); + return this; + } + set width(value) { + if (Laya.ILaya.Render.isConchApp) { + var transform = Laya.ILaya.Utils.getTransformRelativeToWindow(this, 0, 0); + this.videoElement.width = value * transform.scaleX; + } + else { + this.videoElement.width = this.width / Laya.ILaya.Browser.pixelRatio; + } + super.width = value; + if (this.paused) + this.renderCanvas(); + } + get width() { + return super.width; + } + set height(value) { + if (Laya.ILaya.Render.isConchApp) { + var transform = Laya.ILaya.Utils.getTransformRelativeToWindow(this, 0, 0); + this.videoElement.height = value * transform.scaleY; + } + else { + this.videoElement.height = this.height / Laya.ILaya.Browser.pixelRatio; + } + super.height = value; + } + get height() { + return super.height; + } + destroy(detroyChildren = true) { + super.destroy(detroyChildren); + this.videoElement.removeEventListener("abort", Video.onAbort); + this.videoElement.removeEventListener("canplay", Video.onCanplay); + this.videoElement.removeEventListener("canplaythrough", Video.onCanplaythrough); + this.videoElement.removeEventListener("durationchange", Video.onDurationchange); + this.videoElement.removeEventListener("emptied", Video.onEmptied); + this.videoElement.removeEventListener("error", Video.onError); + this.videoElement.removeEventListener("loadeddata", Video.onLoadeddata); + this.videoElement.removeEventListener("loadedmetadata", Video.onLoadedmetadata); + this.videoElement.removeEventListener("loadstart", Video.onLoadstart); + this.videoElement.removeEventListener("pause", Video.onPause); + this.videoElement.removeEventListener("play", Video.onPlay); + this.videoElement.removeEventListener("playing", Video.onPlaying); + this.videoElement.removeEventListener("progress", Video.onProgress); + this.videoElement.removeEventListener("ratechange", Video.onRatechange); + this.videoElement.removeEventListener("seeked", Video.onSeeked); + this.videoElement.removeEventListener("seeking", Video.onSeeking); + this.videoElement.removeEventListener("stalled", Video.onStalled); + this.videoElement.removeEventListener("suspend", Video.onSuspend); + this.videoElement.removeEventListener("timeupdate", Video.onTimeupdate); + this.videoElement.removeEventListener("volumechange", Video.onVolumechange); + this.videoElement.removeEventListener("waiting", Video.onWaiting); + this.videoElement.removeEventListener("ended", this.onPlayComplete); + this.pause(); + this.videoElement.layaTarget = null; + this.videoElement = null; + this.htmlVideo.destroy(); + } + syncVideoPosition() { + var stage = Laya.ILaya.stage; + var rec; + rec = Laya.ILaya.Utils.getGlobalPosAndScale(this); + var a = stage._canvasTransform.a, d = stage._canvasTransform.d; + var x = rec.x * stage.clientScaleX * a + stage.offset.x; + var y = rec.y * stage.clientScaleY * d + stage.offset.y; + this.videoElement.style.left = x + 'px'; + this.videoElement.style.top = y + 'px'; + this.videoElement.width = this.width / Laya.ILaya.Browser.pixelRatio; + this.videoElement.height = this.height / Laya.ILaya.Browser.pixelRatio; + } + } + Video.MP4 = 1; + Video.OGG = 2; + Video.CAMERA = 4; + Video.WEBM = 8; + Video.SUPPORT_PROBABLY = "probably"; + Video.SUPPORT_MAYBY = "maybe"; + Video.SUPPORT_NO = ""; + + class Gyroscope extends Laya.EventDispatcher { + constructor(singleton) { + super(); + this.onDeviceOrientationChange = this.onDeviceOrientationChange.bind(this); + } + static get instance() { + Gyroscope._instance = Gyroscope._instance || new Gyroscope(0); + return Gyroscope._instance; + } + on(type, caller, listener, args = null) { + super.on(type, caller, listener, args); + Laya.ILaya.Browser.window.addEventListener('deviceorientation', this.onDeviceOrientationChange); + return this; + } + off(type, caller, listener, onceOnly = false) { + if (!this.hasListener(type)) + Laya.ILaya.Browser.window.removeEventListener('deviceorientation', this.onDeviceOrientationChange); + return super.off(type, caller, listener, onceOnly); + } + onDeviceOrientationChange(e) { + Gyroscope.info.alpha = e.alpha; + Gyroscope.info.beta = e.beta; + Gyroscope.info.gamma = e.gamma; + if (e.webkitCompassHeading) { + Gyroscope.info.alpha = e.webkitCompassHeading * -1; + Gyroscope.info.compassAccuracy = e.webkitCompassAccuracy; + } + this.event(Laya.Event.CHANGE, [e.absolute, Gyroscope.info]); + } + } + Gyroscope.info = new RotationInfo(); + + exports.AccelerationInfo = AccelerationInfo; + exports.Accelerator = Accelerator; + exports.Geolocation = Geolocation; + exports.GeolocationInfo = GeolocationInfo; + exports.Gyroscope = Gyroscope; + exports.HtmlVideo = HtmlVideo; + exports.Media = Media; + exports.RotationInfo = RotationInfo; + exports.Shake = Shake; + exports.Video = Video; + exports.WebGLVideo = WebGLVideo; + +}(window.Laya = window.Laya || {}, Laya)); diff --git a/examples/layaair/frontend/bin/libs/laya.gltf.js b/examples/layaair/frontend/bin/libs/laya.gltf.js new file mode 100644 index 0000000..706647d --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.gltf.js @@ -0,0 +1,1339 @@ +(function (exports, Laya) { + 'use strict'; + + class glTFBase64Tool { + constructor() { + } + static init() { + if (glTFBase64Tool.lookup) + return; + glTFBase64Tool.lookup = new Uint8Array(256); + for (var i = 0; i < glTFBase64Tool.chars.length; i++) { + glTFBase64Tool.lookup[glTFBase64Tool.chars.charCodeAt(i)] = i; + } + } + static isBase64String(str) { + return glTFBase64Tool.reg.test(str); + } + static encode(arraybuffer) { + var bytes = new Uint8Array(arraybuffer), i, len = bytes["length"], base64 = ""; + for (i = 0; i < len; i += 3) { + base64 += glTFBase64Tool.chars[bytes[i] >> 2]; + base64 += glTFBase64Tool.chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)]; + base64 += glTFBase64Tool.chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)]; + base64 += glTFBase64Tool.chars[bytes[i + 2] & 63]; + } + if ((len % 3) === 2) { + base64 = base64.substring(0, base64.length - 1) + "="; + } + else if (len % 3 === 1) { + base64 = base64.substring(0, base64.length - 2) + "=="; + } + return base64; + } + static decode(base64) { + glTFBase64Tool.init(); + var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4; + if (base64[base64.length - 1] === "=") { + bufferLength--; + if (base64[base64.length - 2] === "=") { + bufferLength--; + } + } + var arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer); + for (i = 0; i < len; i += 4) { + encoded1 = glTFBase64Tool.lookup[base64.charCodeAt(i)]; + encoded2 = glTFBase64Tool.lookup[base64.charCodeAt(i + 1)]; + encoded3 = glTFBase64Tool.lookup[base64.charCodeAt(i + 2)]; + encoded4 = glTFBase64Tool.lookup[base64.charCodeAt(i + 3)]; + bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); + bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); + bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); + } + return arraybuffer; + } + ; + } + glTFBase64Tool.chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + glTFBase64Tool.reg = /^\s*data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)?)?(;base64)?,([a-z0-9!$&',()*+;=\-._~:@\/?%\s]*?)\s*$/i; + glTFBase64Tool.reghead = /^\s*data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)?)?(;base64)?,/i; + glTFBase64Tool.lookup = null; + + class glTFTextureEditor { + static PixelArrayToBase64(pixelArray, width, height) { + let clampedArray = new Uint8ClampedArray(pixelArray); + let imageData = new ImageData(clampedArray, width, height); + let canvas = new Laya.HTMLCanvas(true); + let ctx = canvas.source.getContext("2d"); + canvas.source.width = width; + canvas.source.height = height; + ctx.putImageData(imageData, 0, 0); + let base64 = canvas.source.toDataURL(); + return base64; + } + static GenerateTexture2DWithPixel(pixelArray, width, height, format, mipmap) { + let tex = new Laya.Texture2D(width, height, format, mipmap, true); + tex.setPixels(pixelArray); + if (mipmap) { + let gl = Laya.LayaGL.instance; + Laya.WebGLContext.bindTexture(gl, tex._glTextureType, tex._glTexture); + gl.generateMipmap(tex._glTextureType); + Laya.WebGLContext.bindTexture(gl, tex._glTextureType, null); + } + return tex; + } + static glTFOcclusionTrans(glTFOcclusion) { + let gltfTexPixels = glTFOcclusion.getPixels(); + let layaTexPixels = new Uint8Array(gltfTexPixels.length); + let pixelCount = gltfTexPixels.length / 4; + let r = 0, g = 1; + for (let index = 0; index < pixelCount; index++) { + let offset = index * 4; + let occlusion = gltfTexPixels[offset + r]; + layaTexPixels[offset + g] = occlusion; + } + let layaTex = glTFTextureEditor.GenerateTexture2DWithPixel(layaTexPixels, glTFOcclusion.width, glTFOcclusion.height, Laya.TextureFormat.R8G8B8A8, glTFOcclusion.mipmap); + return layaTex; + } + static glTFMetallicGlossTrans(glTFMetallicGloss, metallicFactor, roughnessFactor) { + let gltfTexPixels = glTFMetallicGloss.getPixels(); + let layaTexPixels = new Uint8Array(gltfTexPixels.length); + let pixelCount = glTFMetallicGloss.width * glTFMetallicGloss.height; + let r = 0, g = 1, b = 2, a = 3; + for (let index = 0; index < pixelCount; index++) { + let offset = index * 4; + let metallic = gltfTexPixels[offset + b] * metallicFactor; + let smooth = 255 - (gltfTexPixels[offset + g] * roughnessFactor); + layaTexPixels[offset + r] = metallic; + layaTexPixels[offset + a] = smooth; + } + let layaTex = glTFTextureEditor.GenerateTexture2DWithPixel(layaTexPixels, glTFMetallicGloss.width, glTFMetallicGloss.height, Laya.TextureFormat.R8G8B8A8, glTFMetallicGloss.mipmap); + return layaTex; + } + } + + class PrimitiveSubMesh { + constructor() { + } + } + class ClipNode { + constructor() { + } + } + class glTFUtils { + static _parse(glTFData, propertyParams = null, constructParams = null) { + glTFUtils._initData(glTFData); + if (!glTFUtils._checkglTFVersion(this._glTF.asset)) { + console.warn("glTF version wrong!"); + return new Laya.Sprite3D(); + } + glTFUtils._initBufferData(glTFData.buffers); + glTFUtils._initTextureData(glTFData.images); + glTFUtils._loadMaterials(glTFData.materials); + glTFUtils._loadNodes(glTFData.nodes); + glTFUtils.buildHierarchy(glTFData.nodes); + glTFUtils._loadScenes(glTFData.scenes); + glTFUtils._loadAnimations(glTFData.animations); + let defaultSceneIndex = (glTFData.scene != undefined) ? glTFData.scene : 0; + let defaultScene = glTFUtils._glTFScenes[defaultSceneIndex]; + glTFUtils._clearData(); + return defaultScene; + } + static _initData(glTFData) { + glTFUtils._glTF = glTFData; + (glTFData.buffers) && (glTFUtils._glTFBuffers.length = glTFData.buffers.length); + (glTFData.textures) && (glTFUtils._glTFTextures.length = glTFData.textures.length); + (glTFData.materials) && (glTFUtils._glTFMaterials.length = glTFData.materials.length); + (glTFData.nodes) && (glTFUtils._glTFNodes.length = glTFData.nodes.length); + (glTFData.scenes) && (glTFUtils._glTFScenes.length = glTFData.scenes.length); + } + static _clearData() { + glTFUtils._glTF = null; + glTFUtils._glTFBuffers.length = 0; + glTFUtils._glTFTextures.length = 0; + glTFUtils._glTFMaterials.length = 0; + glTFUtils._glTFNodes.length = 0; + glTFUtils._glTFScenes.length = 0; + glTFUtils.NAMEID = 0; + } + static _checkglTFVersion(asset) { + if (asset.version !== "2.0") { + return false; + } + return true; + } + static RegisterExtra(context, extraName, handler) { + let extra = glTFUtils.Extras[context] || (glTFUtils.Extras[context] = {}); + extra[extraName] = handler; + } + static UnRegisterExtra(context, extraName, recoverHandler = true) { + let extra = glTFUtils.Extras[context] || (glTFUtils.Extras[context] = {}); + if (recoverHandler) { + let extraHandler = extra[extraName]; + extraHandler && extraHandler.recover(); + } + delete extra[extraName]; + } + static ExecuteExtras(context, glTFExtra, createHandler, params) { + let contextExtra = glTFUtils.Extras[context]; + let extraRes = null; + if (contextExtra) { + for (const key in glTFExtra) { + let extraHandler = contextExtra[key]; + extraRes = extraHandler ? extraHandler.runWith([...params, createHandler]) : extraRes; + } + } + extraRes = extraRes || createHandler.runWith(params); + createHandler.recover(); + return extraRes; + } + static getNodeRandomName(context) { + return `${context}_${glTFUtils.NAMEID++}`; + } + static _initBufferData(buffers) { + if (!buffers) + return; + buffers.forEach((buffer, index) => { + glTFUtils._glTFBuffers[index] = Laya.Loader.getRes(buffer.uri); + }); + } + static getAccessorComponentsNum(type) { + switch (type) { + case "SCALAR": return 1; + case "VEC2": return 2; + case "VEC3": return 3; + case "VEC4": return 4; + case "MAT2": return 4; + case "MAT3": return 9; + case "MAT4": return 16; + default: return 0; + } + } + static getAttributeNum(attriStr) { + switch (attriStr) { + case "POSITION": return 3; + case "NORMAL": return 3; + case "COLOR": return 4; + case "UV": return 2; + case "UV1": return 2; + case "BLENDWEIGHT": return 4; + case "BLENDINDICES": return 4; + case "TANGENT": return 4; + default: return 0; + } + } + static _getTypedArrayConstructor(componentType) { + switch (componentType) { + case 5120: return Int8Array; + case 5121: return Uint8Array; + case 5122: return Int16Array; + case 5123: return Uint16Array; + case 5125: return Uint32Array; + case 5126: return Float32Array; + } + } + static getBufferwithAccessorIndex(accessorIndex) { + let accessor = glTFUtils._glTF.accessors[accessorIndex]; + if (!accessor) + return null; + let bufferView = glTFUtils._glTF.bufferViews[accessor.bufferView]; + let buffer = glTFUtils._glTFBuffers[bufferView.buffer]; + let count = accessor.count; + let contentStride = glTFUtils.getAccessorComponentsNum(accessor.type); + let byteOffset = (bufferView.byteOffset || 0) + (accessor.byteOffset || 0); + let byteLength = count * contentStride; + const constructor = glTFUtils._getTypedArrayConstructor(accessor.componentType); + return new constructor(buffer, byteOffset, byteLength); + } + static _initTextureData(images) { + if (!images) + return; + images.forEach((image, index) => { + glTFUtils._glTFTextures[index] = Laya.Loader.getRes(image.uri); + }); + } + static getTextureMipmap(glTFSampler) { + if (glTFSampler) + return glTFSampler.minFilter === 9729 || + glTFSampler.minFilter === 9728; + else + return true; + } + static getTextureFormat(glTFImage) { + if (glTFImage.mimeType === "image/png") { + return 1; + } + else { + return 0; + } + } + static getTextureFilterMode(glTFSampler) { + if (!glTFSampler) { + return 1; + } + if (glTFSampler.magFilter === 9728) { + return 0; + } + else if (glTFUtils.getTextureMipmap(glTFSampler)) { + if (glTFSampler.minFilter === 9987) + return 2; + return 1; + } + return 1; + } + static getTextureWrapMode(mode) { + if (mode === 33071) { + return 1; + } + return 0; + } + static getTextureConstructParams(glTFImage, glTFSampler) { + let constructParams = []; + constructParams[0] = 0; + constructParams[1] = 0; + constructParams[2] = glTFUtils.getTextureFormat(glTFImage); + constructParams[3] = glTFUtils.getTextureMipmap(glTFSampler); + constructParams[4] = true; + return constructParams; + } + static getTexturePropertyParams(glTFSampler) { + let propertyParams = {}; + if (!glTFSampler) { + return null; + } + propertyParams.filterMode = glTFUtils.getTextureFilterMode(glTFSampler); + propertyParams.wrapModeU = glTFUtils.getTextureWrapMode(glTFSampler.wrapS); + propertyParams.wrapModeV = glTFUtils.getTextureWrapMode(glTFSampler.wrapT); + propertyParams.anisoLevel = 16; + return propertyParams; + } + static getTexturewithInfo(glTFTextureInfo) { + if (glTFTextureInfo.texCoord) { + console.warn("glTF Loader: non 0 uv channel unsupported."); + } + let glTFImage = glTFUtils._glTF.textures[glTFTextureInfo.index]; + return glTFUtils._glTFTextures[glTFImage.source]; + } + static _loadMaterials(glTFMaterials) { + if (!glTFMaterials) + return; + glTFMaterials.forEach((glTFMaterial, index) => { + glTFUtils._glTFMaterials[index] = glTFUtils._loadMaterial(glTFMaterial); + }); + } + static _loadMaterial(glTFMaterial) { + if (glTFMaterial.extras) { + let createHandler = Laya.Handler.create(this, glTFUtils._createdefaultMaterial, null, false); + return glTFUtils.ExecuteExtras("MATERIAL", glTFMaterial.extras, createHandler, [glTFMaterial]); + } + return glTFUtils._createdefaultMaterial(glTFMaterial); + } + static _createdefaultMaterial(glTFMaterial) { + let layaPBRMaterial = new Laya.PBRStandardMaterial(); + layaPBRMaterial.name = glTFMaterial.name ? glTFMaterial.name : ""; + if (glTFMaterial.pbrMetallicRoughness) { + glTFUtils.applyPBRMetallicRoughness(glTFMaterial.pbrMetallicRoughness, layaPBRMaterial); + } + if (glTFMaterial.normalTexture) { + layaPBRMaterial.normalTexture = glTFUtils.getTexturewithInfo(glTFMaterial.normalTexture); + if (glTFMaterial.normalTexture.scale != undefined) { + layaPBRMaterial.normalTextureScale = glTFMaterial.normalTexture.scale; + } + } + if (glTFMaterial.occlusionTexture) { + let occlusionTexture = glTFUtils.getTexturewithInfo(glTFMaterial.occlusionTexture); + layaPBRMaterial.occlusionTexture = glTFTextureEditor.glTFOcclusionTrans(occlusionTexture); + if (glTFMaterial.occlusionTexture.strength != undefined) { + layaPBRMaterial.occlusionTextureStrength = glTFMaterial.occlusionTexture.strength; + } + } + if (glTFMaterial.emissiveTexture) { + layaPBRMaterial.emissionTexture = glTFUtils.getTexturewithInfo(glTFMaterial.emissiveTexture); + if (layaPBRMaterial.emissionTexture) { + layaPBRMaterial.enableEmission = true; + } + } + if (glTFMaterial.emissiveFactor) { + layaPBRMaterial.emissionColor.fromArray(glTFMaterial.emissiveFactor); + layaPBRMaterial.emissionColor.w = 1.0; + layaPBRMaterial.enableEmission = true; + } + let renderMode = glTFMaterial.alphaMode || "OPAQUE"; + switch (renderMode) { + case "OPAQUE": { + layaPBRMaterial.renderMode = Laya.PBRRenderMode.Opaque; + break; + } + case "BLEND": { + layaPBRMaterial.renderMode = Laya.PBRRenderMode.Transparent; + break; + } + case "MASK": { + layaPBRMaterial.renderMode = Laya.PBRRenderMode.Cutout; + break; + } + } + if (glTFMaterial.alphaCutoff != undefined) { + layaPBRMaterial.alphaTestValue = glTFMaterial.alphaCutoff; + } + if (glTFMaterial.doubleSided) { + layaPBRMaterial.cull = Laya.RenderState.CULL_NONE; + } + return layaPBRMaterial; + } + static applyPBRMetallicRoughness(pbrMetallicRoughness, layaPBRMaterial) { + if (pbrMetallicRoughness.baseColorFactor) { + layaPBRMaterial.albedoColor.fromArray(pbrMetallicRoughness.baseColorFactor); + } + if (pbrMetallicRoughness.baseColorTexture) { + layaPBRMaterial.albedoTexture = glTFUtils.getTexturewithInfo(pbrMetallicRoughness.baseColorTexture); + } + let metallicFactor = layaPBRMaterial.metallic = 1.0; + if (pbrMetallicRoughness.metallicFactor != undefined) { + metallicFactor = layaPBRMaterial.metallic = pbrMetallicRoughness.metallicFactor; + } + let roughnessFactor = 1.0; + layaPBRMaterial.smoothness = 0.0; + if (pbrMetallicRoughness.roughnessFactor != undefined) { + roughnessFactor = pbrMetallicRoughness.roughnessFactor; + layaPBRMaterial.smoothness = 1.0 - pbrMetallicRoughness.roughnessFactor; + } + if (pbrMetallicRoughness.metallicRoughnessTexture) { + let metallicGlossTexture = glTFUtils.getTexturewithInfo(pbrMetallicRoughness.metallicRoughnessTexture); + layaPBRMaterial.metallicGlossTexture = glTFTextureEditor.glTFMetallicGlossTrans(metallicGlossTexture, metallicFactor, roughnessFactor); + } + } + static pickMeshMaterials(glTFMesh) { + let materials = []; + glTFMesh.primitives.forEach(primitive => { + if (primitive.material != undefined) { + let material = glTFUtils._glTFMaterials[primitive.material]; + materials.push(material); + } + else { + let material = new Laya.PBRStandardMaterial(); + materials.push(material); + glTFUtils._glTFMaterials.push(material); + primitive.material = glTFUtils._glTFMaterials.indexOf(material); + } + }); + return materials; + } + static _loadScenes(glTFScenes) { + if (!glTFScenes) + return; + glTFScenes.forEach((glTFScene, index) => { + glTFUtils._glTFScenes[index] = glTFUtils._loadScene(glTFScene); + }); + } + static _loadScene(glTFScene) { + return glTFUtils._createSceneNode(glTFScene); + } + static _createSceneNode(glTFScene) { + let glTFSceneNode = new Laya.Sprite3D(glTFScene.name || "glTF_Scene_node"); + glTFScene.nodes.forEach(nodeIndex => { + let sprite = glTFUtils._glTFNodes[nodeIndex]; + glTFSceneNode.addChild(sprite); + }); + return glTFSceneNode; + } + static applyTransform(glTFNode, sprite) { + if (glTFNode.matrix) { + let localMatrix = sprite.transform.localMatrix; + localMatrix.elements.set(glTFNode.matrix); + sprite.transform.localMatrix = localMatrix; + } + else { + let localPosition = sprite.transform.localPosition; + let localRotation = sprite.transform.localRotation; + let localScale = sprite.transform.localScale; + glTFNode.translation && localPosition.fromArray(glTFNode.translation); + glTFNode.rotation && localRotation.fromArray(glTFNode.rotation); + glTFNode.scale && localScale.fromArray(glTFNode.scale); + sprite.transform.localPosition = localPosition; + sprite.transform.localRotation = localRotation; + sprite.transform.localScale = localScale; + } + } + static buildHierarchy(glTFNodes) { + glTFNodes.forEach((glTFNode, index) => { + let sprite = glTFUtils._glTFNodes[index]; + if (glTFNode.children) { + glTFNode.children.forEach((childIndex) => { + let child = glTFUtils._glTFNodes[childIndex]; + sprite.addChild(child); + }); + } + }); + glTFNodes.forEach((glTFNode, index) => { + let sprite = glTFUtils._glTFNodes[index]; + if (sprite instanceof Laya.SkinnedMeshSprite3D) { + glTFUtils.fixSkinnedSprite(glTFNode, sprite); + } + }); + } + static _loadNodes(glTFNodes) { + if (!glTFNodes) { + return; + } + glTFNodes.forEach((glTFNode, index) => { + glTFNode.name = glTFNode.name || glTFUtils.getNodeRandomName("node"); + }); + glTFNodes.forEach((glTFNode, index) => { + glTFUtils._glTFNodes[index] = glTFUtils._loadNode(glTFNode); + }); + } + static _loadNode(glTFNode) { + return glTFUtils._createSprite3D(glTFNode); + } + static _createSprite3D(glTFNode) { + glTFNode.name = glTFNode.name; + if (glTFNode.skin != undefined) { + let sprite = glTFUtils._createSkinnedMeshSprite3D(glTFNode); + glTFUtils.applyTransform(glTFNode, sprite); + return sprite; + } + else if (glTFNode.mesh != undefined) { + let sprite = glTFUtils._createMeshSprite3D(glTFNode); + glTFUtils.applyTransform(glTFNode, sprite); + return sprite; + } + else { + let sprite = new Laya.Sprite3D(glTFNode.name); + glTFUtils.applyTransform(glTFNode, sprite); + return sprite; + } + } + static _createMeshSprite3D(glTFNode) { + let glTFMesh = glTFUtils._glTF.meshes[glTFNode.mesh]; + let mesh = glTFUtils._loadMesh(glTFMesh); + let materials = glTFUtils.pickMeshMaterials(glTFMesh); + let sprite = new Laya.MeshSprite3D(mesh, glTFNode.name); + sprite.meshRenderer.sharedMaterials = materials; + return sprite; + } + static _createSkinnedMeshSprite3D(glTFNode) { + let glTFMesh = glTFUtils._glTF.meshes[glTFNode.mesh]; + let glTFSkin = glTFUtils._glTF.skins[glTFNode.skin]; + let mesh = glTFUtils._loadMesh(glTFMesh, glTFSkin); + let materials = glTFUtils.pickMeshMaterials(glTFMesh); + let sprite = new Laya.SkinnedMeshSprite3D(mesh, glTFNode.name); + sprite.skinnedMeshRenderer.sharedMaterials = materials; + return sprite; + } + static getArrributeBuffer(attributeAccessorIndex, layaDeclarStr, attributeMap, vertexDeclarArr) { + let attributeBuffer = glTFUtils.getBufferwithAccessorIndex(attributeAccessorIndex); + if (!attributeBuffer) + return null; + vertexDeclarArr.push(layaDeclarStr); + let res = attributeBuffer; + attributeMap.set(layaDeclarStr, res); + return res; + } + static getIndexBuffer(attributeAccessorIndex, vertexCount) { + let indexBuffer = glTFUtils.getBufferwithAccessorIndex(attributeAccessorIndex); + if (indexBuffer) { + return new Uint32Array(indexBuffer).reverse(); + } + else { + let indices = new Uint32Array(vertexCount); + for (let i = 0; i < vertexCount; i++) { + indices[i] = i; + } + return indices; + } + } + static parseMeshwithSubMeshData(subDatas, layaMesh) { + let vertexCount = 0; + let indexCount = 0; + let vertexDecler = undefined; + subDatas.forEach(subData => { + vertexCount += subData.vertexCount; + indexCount += subData.indices.length; + vertexDecler = vertexDecler || subData.vertexDecler; + }); + let vertexDeclaration = Laya.VertexMesh.getVertexDeclaration(vertexDecler, false); + let vertexByteStride = vertexDeclaration.vertexStride; + let vertexFloatStride = vertexByteStride / 4; + let vertexArray = new Float32Array(vertexFloatStride * vertexCount); + let indexArray; + let ibFormat = Laya.IndexFormat.UInt32; + if (vertexCount < 65536) { + indexArray = new Uint16Array(indexCount); + ibFormat = Laya.IndexFormat.UInt16; + } + else { + indexArray = new Uint32Array(indexCount); + } + glTFUtils.fillMeshBuffers(subDatas, vertexArray, indexArray, vertexFloatStride); + glTFUtils.generatMesh(vertexArray, indexArray, vertexDeclaration, ibFormat, subDatas, layaMesh); + } + static fillMeshBuffers(subDatas, vertexArray, indexArray, vertexFloatStride) { + let ibPosOffset = 0; + let ibVertexOffset = 0; + let vbPosOffset = 0; + subDatas.forEach((subData) => { + let iAOffset = ibPosOffset; + let vertexCount = subData.vertexCount; + let subIb = subData.indices; + for (let index = 0; index < subIb.length; index++) { + indexArray[iAOffset + index] = subIb[index] + ibVertexOffset; + } + ibPosOffset += subIb.length; + ibVertexOffset += vertexCount; + const fillAttributeBuffer = (value, attriOffset, attriFloatCount = 0) => { + let startOffset = vbPosOffset + attriOffset; + for (let index = 0; index < vertexCount; index++) { + for (let ac = 0; ac < attriFloatCount; ac++) { + vertexArray[startOffset + index * vertexFloatStride + ac] = value[index * attriFloatCount + ac]; + } + } + }; + let attriOffset = 0; + let attributeMap = subData.attributeMap; + let position = attributeMap.get("POSITION"); + (position) && (fillAttributeBuffer(position, attriOffset, 3), attriOffset += 3); + let normal = attributeMap.get("NORMAL"); + (normal) && (fillAttributeBuffer(normal, attriOffset, 3), attriOffset += 3); + let color = attributeMap.get("COLOR"); + (color) && (fillAttributeBuffer(color, attriOffset, 4), attriOffset += 4); + let uv = attributeMap.get("UV"); + (uv) && (fillAttributeBuffer(uv, attriOffset, 2), attriOffset += 2); + let uv1 = attributeMap.get("UV1"); + (uv1) && (fillAttributeBuffer(uv1, attriOffset, 2), attriOffset += 2); + let blendWeight = attributeMap.get("BLENDWEIGHT"); + (blendWeight) && (fillAttributeBuffer(blendWeight, attriOffset, 4), attriOffset += 4); + let blendIndices = attributeMap.get("BLENDINDICES"); + if (blendIndices) { + let blendIndicesUint8 = new Uint8Array(blendIndices); + let blendIndicesFloat32 = new Float32Array(blendIndicesUint8.buffer); + fillAttributeBuffer(blendIndicesFloat32, attriOffset, 1), attriOffset += 1; + } + let tangent = attributeMap.get("TANGENT"); + (tangent) && (fillAttributeBuffer(tangent, attriOffset, 4), attriOffset += 4); + vbPosOffset += vertexCount * vertexFloatStride; + }); + } + static splitSubMeshByBonesCount(attributeMap, indexArray, boneIndicesList, subIndexStartArray, subIndexCountArray) { + let maxSubBoneCount = glTFUtils.maxSubBoneCount; + let start = 0; + let subIndexSet = new Set(); + let boneIndexArray = attributeMap.get("BLENDINDICES"); + let vertexCount = boneIndexArray.length / 4; + let resArray = new Float32Array(boneIndexArray.length); + let flagArray = new Array(vertexCount).fill(false); + for (let i = 0, n = indexArray.length; i < n; i += 3) { + let triangleSet = new Set(); + for (let j = i; j < i + 3; j++) { + let ibIndex = indexArray[j]; + let boneIndexOffset = ibIndex * 4; + for (let k = 0; k < 4; k++) { + triangleSet.add(boneIndexArray[boneIndexOffset + k]); + } + } + let tempSet = new Set([...subIndexSet, ...triangleSet]); + if (tempSet.size > maxSubBoneCount) { + let count = i - start; + subIndexStartArray.push(start); + subIndexCountArray.push(count); + let curBoneList = Array.from(subIndexSet); + boneIndicesList.push(new Uint16Array(curBoneList)); + start = i; + subIndexSet = new Set(triangleSet); + } + else { + subIndexSet = tempSet; + } + if (i == n - 3) { + let count = i - start + 3; + subIndexStartArray.push(start); + subIndexCountArray.push(count); + start = i; + let curBoneList = Array.from(subIndexSet); + boneIndicesList.push(new Uint16Array(curBoneList)); + } + } + let drawCount = boneIndicesList.length; + let newAttributeMap = new Map(); + attributeMap.forEach((value, key) => { + let array = new Array(); + newAttributeMap.set(key, array); + }); + let curMaxIndex = vertexCount - 1; + for (let d = 0; d < drawCount; d++) { + let k = subIndexStartArray[d]; + let l = subIndexCountArray[d]; + let bl = boneIndicesList[d]; + let batchFlag = new Array(vertexCount).fill(false); + let batchMap = new Map(); + for (let area = 0; area < l; area++) { + let ci = indexArray[area + k]; + let biStart = 4 * ci; + for (let cbi = biStart; cbi < biStart + 4; cbi++) { + let oldBoneIndex = boneIndexArray[cbi]; + let newBoneIndex = bl.indexOf(oldBoneIndex); + newBoneIndex = newBoneIndex == -1 ? 0 : newBoneIndex; + if (flagArray[ci] && !batchFlag[ci]) { + newAttributeMap.get("BLENDINDICES").push(newBoneIndex); + } + else if (flagArray[ci] && batchFlag[ci]) ; + else { + resArray[cbi] = newBoneIndex; + } + } + if (!flagArray[ci] && !batchFlag[ci]) { + batchFlag[ci] = true; + batchMap.set(ci, ci); + } + else if (!flagArray[ci] && batchFlag[ci]) { + indexArray[area + k] = batchMap.get(ci); + } + else if (flagArray[ci] && !batchFlag[ci]) { + batchFlag[ci] = true; + curMaxIndex++; + batchMap.set(ci, curMaxIndex); + indexArray[area + k] = curMaxIndex; + newAttributeMap.forEach((value, key) => { + let attOffset = glTFUtils.getAttributeNum(key); + let oldArray = attributeMap.get(key); + if (key !== "BLENDINDICES") { + for (let index = 0; index < attOffset; index++) { + value.push(oldArray[index + ci * attOffset]); + } + } + }); + } + else if (flagArray[ci] && batchFlag[ci]) { + indexArray[area + k] = batchMap.get(ci); + } + } + batchFlag.forEach((value, index) => { + flagArray[index] = value || flagArray[index]; + }); + } + newAttributeMap.forEach((value, key) => { + let oldFloatArray = attributeMap.get(key); + if (key == "BLENDINDICES") { + oldFloatArray = resArray; + } + let newLength = oldFloatArray.length + value.length; + let newFloatArray = new Float32Array(newLength); + newFloatArray.set(oldFloatArray, 0); + newFloatArray.set(value, oldFloatArray.length); + attributeMap.set(key, newFloatArray); + }); + boneIndexArray = null; + } + static generatMesh(vertexArray, indexArray, vertexDeclaration, ibFormat, subDatas, layaMesh) { + let gl = Laya.LayaGL.instance; + let vertexBuffer = new Laya.VertexBuffer3D(vertexArray.byteLength, gl.STATIC_DRAW, true); + vertexBuffer.vertexDeclaration = vertexDeclaration; + vertexBuffer.setData(vertexArray.buffer); + let indexBuffer = new Laya.IndexBuffer3D(ibFormat, indexArray.length, gl.STATIC_DRAW, true); + indexBuffer.setData(indexArray); + layaMesh._indexFormat = ibFormat; + layaMesh._indexBuffer = indexBuffer; + layaMesh._vertexBuffer = vertexBuffer; + layaMesh._setBuffer(vertexBuffer, indexBuffer); + layaMesh._vertexCount = vertexBuffer._byteLength / vertexDeclaration.vertexStride; + let subMeshOffset = 0; + let subMeshCount = subDatas.length; + let subMeshes = new Array(subMeshCount); + for (let index = 0; index < subMeshCount; index++) { + let subData = subDatas[index]; + let subMesh = new Laya.SubMesh(layaMesh); + subMeshes[index] = subMesh; + subMesh._vertexBuffer = vertexBuffer; + subMesh._indexBuffer = indexBuffer; + let subIndexStart = subMeshOffset; + subMeshOffset += subData.indices.length; + let subIndexCount = subData.indices.length; + subMesh._setIndexRange(subIndexStart, subIndexCount, ibFormat); + subMesh._boneIndicesList = subData.boneIndicesList; + subMesh._subIndexBufferStart = subData.subIndexStartArray; + subMesh._subIndexBufferCount = subData.subIndexCountArray; + for (let subIndex = 0; subIndex < subMesh._subIndexBufferStart.length; subIndex++) { + subMesh._subIndexBufferStart[subIndex] += subIndexStart; + } + } + layaMesh._setSubMeshes(subMeshes); + layaMesh.calculateBounds(); + layaMesh._setInstanceBuffer(Laya.Mesh.MESH_INSTANCEBUFFER_TYPE_NORMAL); + let memorySize = vertexBuffer._byteLength + indexBuffer._byteLength; + layaMesh._setCPUMemory(memorySize); + layaMesh._setGPUMemory(memorySize); + } + static applyglTFSkinData(mesh, subDatas, glTFSkin) { + if (!glTFSkin) + return; + let joints = glTFSkin.joints; + let inverseBindMatricesArray = new Float32Array(glTFUtils.getBufferwithAccessorIndex(glTFSkin.inverseBindMatrices)); + let boneCount = joints.length; + let boneNames = mesh._boneNames = []; + joints.forEach(nodeIndex => { + let node = glTFUtils._glTF.nodes[nodeIndex]; + boneNames.push(node.name); + }); + mesh._inverseBindPoses = []; + mesh._inverseBindPosesBuffer = inverseBindMatricesArray.buffer; + for (let index = 0; index < boneCount; index++) { + let bindPosesArrayOffset = 16 * index; + let matElement = inverseBindMatricesArray.slice(bindPosesArrayOffset, bindPosesArrayOffset + 16); + mesh._inverseBindPoses[index] = new Laya.Matrix4x4(matElement[0], matElement[1], matElement[2], matElement[3], matElement[4], matElement[5], matElement[6], matElement[7], matElement[8], matElement[9], matElement[10], matElement[11], matElement[12], matElement[13], matElement[14], matElement[15], matElement); + } + let subCount = subDatas.length; + let skinnedCache = mesh._skinnedMatrixCaches; + skinnedCache.length = mesh._inverseBindPoses.length; + for (let subIndex = 0; subIndex < subCount; subIndex++) { + let submesh = mesh.getSubMesh(subIndex); + let drawCount = submesh._subIndexBufferStart.length; + for (let drawIndex = 0; drawIndex < drawCount; drawIndex++) { + let boneIndices = submesh._boneIndicesList[drawIndex]; + for (let bni = 0; bni < boneIndices.length; bni++) { + let bn = boneIndices[bni]; + skinnedCache[bn] || (skinnedCache[bn] = new Laya.skinnedMatrixCache(subIndex, drawIndex, bni)); + } + } + } + for (let index = 0; index < skinnedCache.length; index++) { + if (!skinnedCache[index]) { + skinnedCache[index] = new Laya.skinnedMatrixCache(0, 0, 0); + } + } + } + static _loadMesh(glTFMesh, glTFSkin) { + if (glTFMesh.extras) { + let createHandler = Laya.Handler.create(this, glTFUtils._createMesh, null, false); + return glTFUtils.ExecuteExtras("MESH", glTFMesh.extras, createHandler, [glTFMesh, glTFSkin]); + } + let mesh = glTFUtils._createMesh(glTFMesh, glTFSkin); + return mesh; + } + static _createMesh(glTFMesh, glTFSkin) { + let layaMesh = new Laya.Mesh(); + let glTFMeshPrimitives = glTFMesh.primitives; + let morphWeights = glTFMesh.weights; + let boneCount = (glTFSkin) ? glTFSkin.joints.length : 0; + let subDatas = []; + glTFMeshPrimitives.forEach((glTFMeshPrimitive) => { + let mode = glTFMeshPrimitive.mode; + if (mode == undefined) + mode = 4; + if (4 != mode) { + console.warn("glTF Loader: only support gl.TRIANGLES."); + debugger; + } + let vertexDeclarArr = []; + let attributeMap = new Map(); + let attributes = glTFMeshPrimitive.attributes; + let position = glTFUtils.getArrributeBuffer(attributes.POSITION, "POSITION", attributeMap, vertexDeclarArr); + let normal = glTFUtils.getArrributeBuffer(attributes.NORMAL, "NORMAL", attributeMap, vertexDeclarArr); + let color = glTFUtils.getArrributeBuffer(attributes.COLOR_0, "COLOR", attributeMap, vertexDeclarArr); + let uv = glTFUtils.getArrributeBuffer(attributes.TEXCOORD_0, "UV", attributeMap, vertexDeclarArr); + let uv1 = glTFUtils.getArrributeBuffer(attributes.TEXCOORD_1, "UV1", attributeMap, vertexDeclarArr); + let blendWeight = glTFUtils.getArrributeBuffer(attributes.WEIGHTS_0, "BLENDWEIGHT", attributeMap, vertexDeclarArr); + let blendIndices = glTFUtils.getArrributeBuffer(attributes.JOINTS_0, "BLENDINDICES", attributeMap, vertexDeclarArr); + let tangent = glTFUtils.getArrributeBuffer(attributes.TANGENT, "TANGENT", attributeMap, vertexDeclarArr); + let targets = glTFMeshPrimitive.targets; + (targets) && targets.forEach((target, index) => { + let weight = morphWeights[index]; + let morphPosition = glTFUtils.getBufferwithAccessorIndex(target.POSITION); + let morphNormal = glTFUtils.getBufferwithAccessorIndex(target.NORMAL); + let morphTangent = glTFUtils.getBufferwithAccessorIndex(target.TANGENT); + (morphPosition) && morphPosition.forEach((value, index) => { + position[index] += value * weight; + }); + (morphNormal) && morphNormal.forEach((value, index) => { + normal[index] += value * weight; + }); + (morphTangent) && morphTangent.forEach((value, index) => { + tangent[index] += value * weight; + }); + }); + let vertexCount = position.length / 3; + let indexArray = glTFUtils.getIndexBuffer(glTFMeshPrimitive.indices, vertexCount); + let boneIndicesList = new Array(); + let subIndexStartArray = []; + let subIndexCountArray = []; + if (glTFSkin) { + if (boneCount > glTFUtils.maxSubBoneCount) { + glTFUtils.splitSubMeshByBonesCount(attributeMap, indexArray, boneIndicesList, subIndexStartArray, subIndexCountArray); + vertexCount = attributeMap.get("POSITION").length / 3; + } + else { + subIndexStartArray[0] = 0; + subIndexCountArray[0] = indexArray.length; + boneIndicesList[0] = new Uint16Array(boneCount); + for (let bi = 0; bi < boneCount; bi++) { + boneIndicesList[0][bi] = bi; + } + } + } + else { + subIndexStartArray[0] = 0; + subIndexCountArray[0] = indexArray.length; + } + let vertexDeclaration = vertexDeclarArr.toString(); + let subData = new PrimitiveSubMesh(); + subDatas.push(subData); + subData.attributeMap = attributeMap; + subData.indices = indexArray; + subData.vertexCount = vertexCount; + subData.vertexDecler = vertexDeclaration; + subData.boneIndicesList = boneIndicesList; + subData.subIndexStartArray = subIndexStartArray; + subData.subIndexCountArray = subIndexCountArray; + }); + glTFUtils.parseMeshwithSubMeshData(subDatas, layaMesh); + glTFUtils.applyglTFSkinData(layaMesh, subDatas, glTFSkin); + return layaMesh; + } + static calSkinnedSpriteLocalBounds(skinned) { + let render = skinned.skinnedMeshRenderer; + let mesh = skinned.meshFilter.sharedMesh; + let rootBone = render.rootBone; + let oriRootMatrix = rootBone.transform.worldMatrix; + let invertRootMatrix = new Laya.Matrix4x4(); + oriRootMatrix.invert(invertRootMatrix); + let indices = mesh.getIndices(); + let positions = []; + let boneIndices = []; + let boneWeights = []; + mesh.getPositions(positions); + mesh.getBoneIndices(boneIndices); + mesh.getBoneWeights(boneWeights); + let oriBoneIndeices = []; + mesh._subMeshes.forEach((subMesh, index) => { + let bonelists = subMesh._boneIndicesList; + bonelists.forEach((bonelist, listIndex) => { + let start = subMesh._subIndexBufferStart[listIndex]; + let count = subMesh._subIndexBufferCount[listIndex]; + let endIndex = count + start; + for (let iindex = start; iindex < endIndex; iindex++) { + let ii = indices[iindex]; + let boneIndex = boneIndices[ii]; + let x = bonelist[boneIndex.x]; + let y = bonelist[boneIndex.y]; + let z = bonelist[boneIndex.z]; + let w = bonelist[boneIndex.w]; + oriBoneIndeices[ii] = new Laya.Vector4(x, y, z, w); + } + }); + }); + let inverseBindPoses = mesh._inverseBindPoses; + let bones = render.bones; + let ubones = []; + let tempMat = new Laya.Matrix4x4(); + bones.forEach((bone, index) => { + ubones[index] = new Laya.Matrix4x4(); + Laya.Matrix4x4.multiply(invertRootMatrix, bone.transform.worldMatrix, tempMat); + Laya.Matrix4x4.multiply(tempMat, inverseBindPoses[index], ubones[index]); + }); + let skinTransform = new Laya.Matrix4x4; + let resPos = new Laya.Vector3(); + let min = new Laya.Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE); + let max = new Laya.Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE); + for (let index = 0; index < positions.length; index++) { + let pos = positions[index]; + let boneIndex = oriBoneIndeices[index]; + let boneWeight = boneWeights[index]; + if (!(boneIndex && boneWeight)) { + continue; + } + for (let ei = 0; ei < 16; ei++) { + skinTransform.elements[ei] = ubones[boneIndex.x].elements[ei] * boneWeight.x; + skinTransform.elements[ei] += ubones[boneIndex.y].elements[ei] * boneWeight.y; + skinTransform.elements[ei] += ubones[boneIndex.z].elements[ei] * boneWeight.z; + skinTransform.elements[ei] += ubones[boneIndex.w].elements[ei] * boneWeight.w; + } + Laya.Vector3.transformV3ToV3(pos, skinTransform, resPos); + Laya.Vector3.min(min, resPos, min); + Laya.Vector3.max(max, resPos, max); + } + positions = null; + boneIndices = boneWeights = oriBoneIndeices = null; + indices = null; + ubones = null; + render.localBounds.setMin(min); + render.localBounds.setMax(max); + } + static fixSkinnedSprite(glTFNode, skinned) { + let skin = glTFUtils._glTF.skins[glTFNode.skin]; + let skinnedMeshRenderer = skinned.skinnedMeshRenderer; + skin.joints.forEach(nodeIndex => { + let bone = glTFUtils._glTFNodes[nodeIndex]; + skinnedMeshRenderer.bones.push(bone); + }); + if (skin.skeleton == undefined) { + skin.skeleton = skin.joints[0]; + } + skinnedMeshRenderer.rootBone = glTFUtils._glTFNodes[skin.skeleton]; + glTFUtils.calSkinnedSpriteLocalBounds(skinned); + } + static getAnimationRoot(channels) { + const isContainNode = (nodeArr, findNodeIndex) => { + if (!nodeArr) + return false; + if (nodeArr.indexOf(findNodeIndex) == -1) { + for (let index = 0; index < nodeArr.length; index++) { + let glTFNode = glTFUtils._glTF.nodes[nodeArr[index]]; + if (isContainNode(glTFNode.children, findNodeIndex)) { + return true; + } + } + } + return true; + }; + let target = channels[0].target; + let spriteIndex = target.node; + for (let index = 0; index < glTFUtils._glTF.scenes.length; index++) { + let glTFScene = glTFUtils._glTF.scenes[index]; + if (isContainNode(glTFScene.nodes, spriteIndex)) { + return glTFUtils._glTFScenes[index]; + } + } + return null; + } + static getAnimationPath(root, curSprite) { + let paths = []; + if (root == curSprite) + return paths; + let sprite = curSprite; + while (sprite.parent != root) { + sprite = sprite.parent; + paths.push(sprite.name); + } + paths = paths.reverse(); + paths.push(curSprite.name); + return paths; + } + static _loadAnimations(animations) { + if (!animations) + return; + animations.forEach((animation, index) => { + glTFUtils._loadAnimation(animation); + }); + } + static _loadAnimation(animation) { + return glTFUtils._createAnimator(animation); + } + static _createAnimator(animation) { + let channels = animation.channels; + let samplers = animation.samplers; + let animatorRoot = glTFUtils.getAnimationRoot(channels); + if (!animatorRoot) { + return null; + } + let animator = animatorRoot.getComponent(Laya.Animator); + if (!animator) { + animator = animatorRoot.addComponent(Laya.Animator); + let animatorLayer = new Laya.AnimatorControllerLayer("glTF_AnimatorLayer"); + animator.addControllerLayer(animatorLayer); + animatorLayer.defaultWeight = 1.0; + } + let clip = glTFUtils._createAnimatorClip(animation, animatorRoot); + let animatorLayer = animator.getControllerLayer(); + let animationName = clip.name; + let stateMap = animatorLayer._statesMap; + if (stateMap[animationName]) { + animationName = clip.name = glTFUtils.getNodeRandomName(animationName); + } + let animatorState = new Laya.AnimatorState(); + animatorState.name = animationName; + animatorState.clip = clip; + animatorLayer.addState(animatorState); + animatorLayer.defaultState = animatorState; + animatorLayer.playOnWake = true; + return animator; + } + static _createAnimatorClip(animation, animatorRoot) { + let clip = new Laya.AnimationClip(); + let duration = 0; + let channels = animation.channels; + let samplers = animation.samplers; + let clipNodes = new Array(channels.length); + channels.forEach((channel, index) => { + let target = channel.target; + let sampler = samplers[channel.sampler]; + let clipNode = clipNodes[index] = new ClipNode(); + let sprite = glTFUtils._glTFNodes[target.node]; + let timeBuffer = glTFUtils.getBufferwithAccessorIndex(sampler.input); + let outBuffer = glTFUtils.getBufferwithAccessorIndex(sampler.output); + clipNode.timeArray = new Float32Array(timeBuffer); + clipNode.valueArray = new Float32Array(outBuffer); + clipNode.paths = glTFUtils.getAnimationPath(animatorRoot, sprite); + clipNode.propertyOwner = "transform"; + clipNode.propertyLength = 1; + clipNode.propertise = []; + let targetPath = target.path; + switch (targetPath) { + case "translation": + clipNode.propertise.push("localPosition"); + clipNode.type = 1; + break; + case "rotation": + clipNode.propertise.push("localRotation"); + clipNode.type = 2; + break; + case "scale": + clipNode.propertise.push("localScale"); + clipNode.type = 3; + break; + } + clipNode.duration = clipNode.timeArray[clipNode.timeArray.length - 1]; + duration = Math.max(duration, clipNode.duration); + }); + clip.name = animation.name ? animation.name : glTFUtils.getNodeRandomName("glTF_Animation"); + clip._duration = duration; + clip.islooping = true; + clip._frameRate = 30; + let nodeCount = clipNodes.length; + let nodes = clip._nodes; + nodes.count = nodeCount; + let nodesMap = clip._nodesMap = {}; + let nodesDic = clip._nodesDic = {}; + for (let i = 0; i < nodeCount; i++) { + let node = new Laya.KeyframeNode(); + let gLTFClipNode = clipNodes[i]; + nodes.setNodeByIndex(i, node); + node._indexInList = i; + let type = node.type = gLTFClipNode.type; + let pathLength = gLTFClipNode.paths.length; + node._setOwnerPathCount(pathLength); + let tempPath = gLTFClipNode.paths; + for (let j = 0; j < pathLength; j++) { + node._setOwnerPathByIndex(j, tempPath[j]); + } + let nodePath = node._joinOwnerPath("/"); + let mapArray = nodesMap[nodePath]; + (mapArray) || (nodesMap[nodePath] = mapArray = []); + mapArray.push(node); + node.propertyOwner = gLTFClipNode.propertyOwner; + let propertyLength = gLTFClipNode.propertyLength; + node._setPropertyCount(propertyLength); + for (let j = 0; j < propertyLength; j++) { + node._setPropertyByIndex(j, gLTFClipNode.propertise[j]); + } + let fullPath = nodePath + "." + node.propertyOwner + "." + node._joinProperty("."); + nodesDic[fullPath] = fullPath; + node.fullPath = fullPath; + let keyframeCount = gLTFClipNode.timeArray.length; + for (let j = 0; j < keyframeCount; j++) { + switch (type) { + case 0: + break; + case 1: + case 3: + case 4: + let floatArrayKeyframe = new Laya.Vector3Keyframe(); + node._setKeyframeByIndex(j, floatArrayKeyframe); + let startTimev3 = floatArrayKeyframe.time = gLTFClipNode.timeArray[j]; + let inTangent = floatArrayKeyframe.inTangent; + let outTangent = floatArrayKeyframe.outTangent; + let value = floatArrayKeyframe.value; + inTangent.setValue(0, 0, 0); + outTangent.setValue(0, 0, 0); + value.setValue(gLTFClipNode.valueArray[3 * j], gLTFClipNode.valueArray[3 * j + 1], gLTFClipNode.valueArray[3 * j + 2]); + break; + case 2: + let quaternionKeyframe = new Laya.QuaternionKeyframe(); + node._setKeyframeByIndex(j, quaternionKeyframe); + let startTimeQu = quaternionKeyframe.time = gLTFClipNode.timeArray[j]; + let inTangentQua = quaternionKeyframe.inTangent; + let outTangentQua = quaternionKeyframe.outTangent; + let valueQua = quaternionKeyframe.value; + inTangentQua.setValue(0, 0, 0, 0); + outTangentQua.setValue(0, 0, 0, 0); + valueQua.x = gLTFClipNode.valueArray[4 * j]; + valueQua.y = gLTFClipNode.valueArray[4 * j + 1]; + valueQua.z = gLTFClipNode.valueArray[4 * j + 2]; + valueQua.w = gLTFClipNode.valueArray[4 * j + 3]; + break; + } + } + } + return clip; + } + } + glTFUtils.NAMEID = 0; + glTFUtils.maxSubBoneCount = 24; + glTFUtils.Extensions = {}; + glTFUtils.Extras = {}; + glTFUtils._glTFBuffers = []; + glTFUtils._glTFTextures = []; + glTFUtils._glTFMaterials = []; + glTFUtils._glTFNodes = []; + glTFUtils._glTFScenes = []; + + class glTFLoader { + static init() { + let createMap = Laya.LoaderManager.createMap; + createMap["gltf"] = [glTFLoader.GLTF, glTFUtils._parse]; + let parseMap = Laya.Loader.parserMap; + parseMap[glTFLoader.GLTF] = glTFLoader._loadglTF; + parseMap[glTFLoader.GLTFBASE64TEX] = glTFLoader._loadBase64Texture; + glTFLoader._innerBufferLoaderManager.on(Laya.Event.ERROR, null, glTFLoader._eventLoadManagerError); + glTFLoader._innerTextureLoaderManager.on(Laya.Event.ERROR, null, glTFLoader._eventLoadManagerError); + } + static _loadglTF(loader) { + loader._originType = loader.type; + loader.on(Laya.Event.LOADED, null, glTFLoader._onglTFLoaded, [loader]); + loader.load(loader.url, Laya.Loader.JSON, false, null, true); + } + static _loadBase64Texture(loader) { + let url = loader.url; + let type = "nativeimage"; + loader.on(Laya.Event.LOADED, null, function (image) { + loader._cache = loader._createCache; + let tex = Laya.Texture2D._parse(image, loader._propertyParams, loader._constructParams); + glTFLoader._endLoad(loader, tex); + }); + loader.load(url, type, false, null, true); + } + static formatRelativePath(base, value) { + let path; + path = base + value; + let char1 = value.charAt(0); + if (char1 === ".") { + let parts = path.split("/"); + for (let i = 0, len = parts.length; i < len; i++) { + if (parts[i] == '..') { + let index = i - 1; + if (index > 0 && parts[index] !== '..') { + parts.splice(index, 2); + i -= 2; + } + } + } + path = parts.join('/'); + } + return path; + } + static _addglTFInnerUrls(urls, urlMap, urlVersion, glTFBasePath, path, type, constructParams = null, propertyParams = null) { + let formatUrl = glTFLoader.formatRelativePath(glTFBasePath, path); + (urlVersion) && (formatUrl = formatUrl + urlVersion); + urls.push({ url: formatUrl, type: type, constructParams: constructParams, propertyParams: propertyParams }); + (urlMap) && (urlMap.push(formatUrl)); + return formatUrl; + } + static _getglTFInnerUrlsCount(glTFData) { + let urlCount = 0; + if (glTFData.buffers) { + glTFData.buffers.forEach(buffer => { + if (glTFBase64Tool.isBase64String(buffer.uri)) ; + else { + urlCount++; + } + }); + } + if (glTFData.textures) { + urlCount += glTFData.textures.length; + } + return urlCount; + } + static _getglTFBufferUrls(glTFData, bufferUrls, urlVersion, glTFBasePath) { + if (glTFData.buffers) { + glTFData.buffers.forEach(buffer => { + if (glTFBase64Tool.isBase64String(buffer.uri)) { + let bin = glTFBase64Tool.decode(buffer.uri.replace(glTFBase64Tool.reghead, "")); + Laya.Loader.cacheRes(buffer.uri, bin); + } + else { + buffer.uri = glTFLoader._addglTFInnerUrls(bufferUrls, null, urlVersion, glTFBasePath, buffer.uri, Laya.Loader.BUFFER); + } + }); + } + } + static _getglTFTextureUrls(glTFData, textureUrls, subUrls, urlVersion, glTFBasePath) { + if (glTFData.textures) { + glTFData.textures.forEach(glTFTexture => { + let glTFImage = glTFData.images[glTFTexture.source]; + let glTFSampler = glTFData.samplers ? glTFData.samplers[glTFTexture.sampler] : undefined; + let constructParams = glTFUtils.getTextureConstructParams(glTFImage, glTFSampler); + let propertyParams = glTFUtils.getTexturePropertyParams(glTFSampler); + if (glTFImage.bufferView != undefined || glTFImage.bufferView != null) { + let bufferView = glTFData.bufferViews[glTFImage.bufferView]; + let glTFBuffer = glTFData.buffers[bufferView.buffer]; + let buffer = Laya.Loader.getRes(glTFBuffer.uri); + let byteOffset = (bufferView.byteOffset || 0); + let byteLength = bufferView.byteLength; + let arraybuffer = buffer.slice(byteOffset, byteOffset + byteLength); + let base64 = glTFBase64Tool.encode(arraybuffer); + let base64url = `data:${glTFImage.mimeType};base64,${base64}`; + glTFImage.uri = glTFLoader._addglTFInnerUrls(textureUrls, subUrls, urlVersion, "", base64url, glTFLoader.GLTFBASE64TEX, constructParams, propertyParams); + } + else if (glTFBase64Tool.isBase64String(glTFImage.uri)) { + glTFImage.uri = glTFLoader._addglTFInnerUrls(textureUrls, subUrls, urlVersion, "", glTFImage.uri, glTFLoader.GLTFBASE64TEX, constructParams, propertyParams); + } + else { + glTFImage.uri = glTFLoader._addglTFInnerUrls(textureUrls, subUrls, urlVersion, glTFBasePath, glTFImage.uri, Laya.Loader.TEXTURE2D, constructParams, propertyParams); + } + }); + } + } + static _onglTFLoaded(loader, glTFData) { + let url = loader.url; + let urlVersion = Laya.Utils3D.getURLVerion(url); + let glTFBasePath = Laya.URL.getPath(url); + let bufferUrls = []; + glTFLoader._getglTFBufferUrls(glTFData, bufferUrls, urlVersion, glTFBasePath); + let urlCount = glTFLoader._getglTFInnerUrlsCount(glTFData); + let totalProcessCount = urlCount + 1; + let weight = 1 / totalProcessCount; + glTFLoader._onProcessChange(loader, 0, weight, 1.0); + let processCeil = urlCount / totalProcessCount; + if (bufferUrls.length > 0) { + let processHandler = Laya.Handler.create(null, glTFLoader._onProcessChange, [loader, weight, processCeil], false); + glTFLoader._innerBufferLoaderManager._create(bufferUrls, false, Laya.Handler.create(null, glTFLoader._onglTFBufferResourceLoaded, [loader, processHandler, glTFData, urlVersion, glTFBasePath, weight + processCeil * bufferUrls.length, processCeil]), processHandler, null, null, null, 1, true); + } + else { + glTFLoader._onglTFBufferResourceLoaded(loader, null, glTFData, urlVersion, glTFBasePath, weight, processCeil); + } + } + static _onglTFBufferResourceLoaded(loader, processHandler, glTFData, urlVersion, glTFBasePath, processOffset, processCeil) { + (processHandler) && (processHandler.recover()); + let textureUrls = []; + let subUrls = []; + glTFLoader._getglTFTextureUrls(glTFData, textureUrls, subUrls, urlVersion, glTFBasePath); + if (textureUrls.length > 0) { + let process = Laya.Handler.create(null, glTFLoader._onProcessChange, [loader, processOffset, processCeil], false); + glTFLoader._innerTextureLoaderManager._create(textureUrls, false, Laya.Handler.create(null, glTFLoader._onglTFTextureResourceLoaded, [loader, process, glTFData, subUrls]), processHandler, null, null, null, 1, true); + } + else { + glTFLoader._onglTFTextureResourceLoaded(loader, processHandler, glTFData, subUrls); + } + } + static _onglTFTextureResourceLoaded(loader, processHandler, glTFData, subUrls) { + (processHandler) && (processHandler.recover()); + loader._cache = loader._createCache; + let item = glTFUtils._parse(glTFData, loader._propertyParams, loader._constructParams); + glTFLoader._endLoad(loader, item, subUrls); + } + static _eventLoadManagerError(msg) { + Laya.Laya.loader.event(Laya.Event.ERROR, msg); + } + static _onProcessChange(loader, offset, weight, process) { + process = offset + process * weight; + (process < 1.0) && (loader.event(Laya.Event.PROGRESS, process * 2 / 3 + 1 / 3)); + } + static _endLoad(loader, content = null, subResource = null) { + if (subResource) { + for (let i = 0; i < subResource.length; i++) { + let resource = Laya.Loader.getRes(subResource[i]); + (resource) && (resource._removeReference()); + } + } + loader.endLoad(content); + } + } + glTFLoader.GLTF = "GLTF"; + glTFLoader.GLTFBASE64TEX = "GLTFBASE64TEX"; + glTFLoader._innerBufferLoaderManager = new Laya.LoaderManager(); + glTFLoader._innerTextureLoaderManager = new Laya.LoaderManager(); + + exports.glTFBase64Tool = glTFBase64Tool; + exports.glTFLoader = glTFLoader; + exports.glTFTextureEditor = glTFTextureEditor; + exports.glTFUtils = glTFUtils; + +}(window.Laya = window.Laya || {}, Laya)); diff --git a/examples/layaair/frontend/bin/libs/laya.html.js b/examples/layaair/frontend/bin/libs/laya.html.js new file mode 100644 index 0000000..e91db3a --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.html.js @@ -0,0 +1,1561 @@ +(function (exports, Laya) { + 'use strict'; + + class HTMLExtendStyle { + constructor() { + this.reset(); + } + reset() { + this.stroke = 0; + this.strokeColor = "#000000"; + this.leading = 0; + this.lineHeight = 0; + this.letterSpacing = 0; + this.href = null; + return this; + } + recover() { + if (this == HTMLExtendStyle.EMPTY) + return; + Laya.Pool.recover("HTMLExtendStyle", this.reset()); + } + static create() { + return Laya.Pool.getItemByClass("HTMLExtendStyle", HTMLExtendStyle); + } + } + HTMLExtendStyle.EMPTY = new HTMLExtendStyle(); + Laya.ClassUtils.regClass("laya.html.utils.HTMLExtendStyle", HTMLExtendStyle); + Laya.ClassUtils.regClass("Laya.HTMLExtendStyle", HTMLExtendStyle); + + class HTMLStyle { + constructor() { + this.padding = HTMLStyle._PADDING; + this.reset(); + } + _getExtendStyle() { + if (this._extendStyle === HTMLExtendStyle.EMPTY) + this._extendStyle = HTMLExtendStyle.create(); + return this._extendStyle; + } + get href() { + return this._extendStyle.href; + } + set href(value) { + if (value === this._extendStyle.href) + return; + this._getExtendStyle().href = value; + } + get stroke() { + return this._extendStyle.stroke; + } + set stroke(value) { + if (this._extendStyle.stroke === value) + return; + this._getExtendStyle().stroke = value; + } + get strokeColor() { + return this._extendStyle.strokeColor; + } + set strokeColor(value) { + if (this._extendStyle.strokeColor === value) + return; + this._getExtendStyle().strokeColor = value; + } + get leading() { + return this._extendStyle.leading; + } + set leading(value) { + if (this._extendStyle.leading === value) + return; + this._getExtendStyle().leading = value; + } + get lineHeight() { + return this._extendStyle.lineHeight; + } + set lineHeight(value) { + if (this._extendStyle.lineHeight === value) + return; + this._getExtendStyle().lineHeight = value; + } + set align(v) { + if (!(v in HTMLStyle.alignVDic)) + return; + this._type &= (~HTMLStyle._ALIGN); + this._type |= HTMLStyle.alignVDic[v]; + } + get align() { + var v = this._type & HTMLStyle._ALIGN; + return HTMLStyle.align_Value[v]; + } + set valign(v) { + if (!(v in HTMLStyle.alignVDic)) + return; + this._type &= (~HTMLStyle._VALIGN); + this._type |= HTMLStyle.alignVDic[v]; + } + get valign() { + var v = this._type & HTMLStyle._VALIGN; + return HTMLStyle.vAlign_Value[v]; + } + set font(value) { + var strs = value.split(' '); + for (var i = 0, n = strs.length; i < n; i++) { + var str = strs[i]; + switch (str) { + case 'italic': + this.italic = true; + continue; + case 'bold': + this.bold = true; + continue; + } + if (str.indexOf('px') > 0) { + this.fontSize = parseInt(str); + this.family = strs[i + 1]; + i++; + continue; + } + } + } + get font() { + return (this.italic ? "italic " : "") + (this.bold ? "bold " : "") + this.fontSize + "px " + (Laya.ILaya.Browser.onIPhone ? (Laya.ILaya.Text.fontFamilyMap[this.family] || this.family) : this.family); + } + set block(value) { + value ? (this._type |= HTMLStyle._CSS_BLOCK) : (this._type &= (~HTMLStyle._CSS_BLOCK)); + } + get block() { + return (this._type & HTMLStyle._CSS_BLOCK) != 0; + } + reset() { + this.ower = null; + this._type = 0; + this.wordWrap = true; + this.fontSize = Laya.ILaya.Text.defaultFontSize; + this.family = Laya.ILaya.Text.defaultFont; + this.color = "#000000"; + this.valign = HTMLStyle.VALIGN_TOP; + this.padding = HTMLStyle._PADDING; + this.bold = false; + this.italic = false; + this.align = HTMLStyle.ALIGN_LEFT; + this.textDecoration = null; + this.bgColor = null; + this.borderColor = null; + if (this._extendStyle) + this._extendStyle.recover(); + this._extendStyle = HTMLExtendStyle.EMPTY; + return this; + } + recover() { + Laya.Pool.recover("HTMLStyle", this.reset()); + } + static create() { + return Laya.Pool.getItemByClass("HTMLStyle", HTMLStyle); + } + inherit(src) { + var i, len; + var props; + props = HTMLStyle._inheritProps; + len = props.length; + var key; + for (i = 0; i < len; i++) { + key = props[i]; + this[key] = src[key]; + } + } + get wordWrap() { + return (this._type & HTMLStyle._NOWARP) === 0; + } + set wordWrap(value) { + value ? (this._type &= ~HTMLStyle._NOWARP) : (this._type |= HTMLStyle._NOWARP); + } + get bold() { + return (this._type & HTMLStyle._BOLD) != 0; + } + set bold(value) { + value ? (this._type |= HTMLStyle._BOLD) : (this._type &= ~HTMLStyle._BOLD); + } + get fontWeight() { + return (this._type & HTMLStyle._BOLD) ? "bold" : "none"; + } + set fontWeight(value) { + value == "bold" ? (this._type |= HTMLStyle._BOLD) : (this._type &= ~HTMLStyle._BOLD); + } + get italic() { + return (this._type & HTMLStyle._ITALIC) != 0; + } + set italic(value) { + value ? (this._type |= HTMLStyle._ITALIC) : (this._type &= ~HTMLStyle._ITALIC); + } + _widthAuto() { + return (this._type & HTMLStyle._WIDTHAUTO) !== 0; + } + widthed(sprite) { + return (this._type & HTMLStyle._WIDTH_SET) != 0; + } + set whiteSpace(type) { + type === "nowrap" && (this._type |= HTMLStyle._NOWARP); + type === "none" && (this._type &= ~HTMLStyle._NOWARP); + } + get whiteSpace() { + return (this._type & HTMLStyle._NOWARP) ? "nowrap" : ""; + } + _calculation(type, value) { + return false; + } + set width(w) { + this._type |= HTMLStyle._WIDTH_SET; + if (typeof (w) == 'string') { + var offset = w.indexOf('auto'); + if (offset >= 0) { + this._type |= HTMLStyle._WIDTHAUTO; + w = w.substr(0, offset); + } + if (this._calculation("width", w)) + return; + w = parseInt(w); + } + this.size(w, -1); + } + set height(h) { + this._type |= HTMLStyle._HEIGHT_SET; + if (typeof (h) == 'string') { + if (this._calculation("height", h)) + return; + h = parseInt(h); + } + this.size(-1, h); + } + heighted(sprite) { + return (this._type & HTMLStyle._HEIGHT_SET) != 0; + } + size(w, h) { + var ower = this.ower; + var resize = false; + if (w !== -1 && w != ower.width) { + this._type |= HTMLStyle._WIDTH_SET; + ower.width = w; + resize = true; + } + if (h !== -1 && h != ower.height) { + this._type |= HTMLStyle._HEIGHT_SET; + ower.height = h; + resize = true; + } + if (resize) { + ower._layoutLater(); + } + } + getLineElement() { + return (this._type & HTMLStyle._LINE_ELEMENT) != 0; + } + setLineElement(value) { + value ? (this._type |= HTMLStyle._LINE_ELEMENT) : (this._type &= (~HTMLStyle._LINE_ELEMENT)); + } + _enableLayout() { + return (this._type & HTMLStyle._DISPLAY_NONE) === 0 && (this._type & HTMLStyle._ABSOLUTE) === 0; + } + get letterSpacing() { + return this._extendStyle.letterSpacing; + } + set letterSpacing(d) { + (typeof (d) == 'string') && (d = parseInt(d + "")); + if (d == this._extendStyle.letterSpacing) + return; + this._getExtendStyle().letterSpacing = d; + } + cssText(text) { + this.attrs(HTMLStyle.parseOneCSS(text, ';')); + } + attrs(attrs) { + if (attrs) { + for (var i = 0, n = attrs.length; i < n; i++) { + var attr = attrs[i]; + this[attr[0]] = attr[1]; + } + } + } + set position(value) { + value === "absolute" ? (this._type |= HTMLStyle._ABSOLUTE) : (this._type &= ~HTMLStyle._ABSOLUTE); + } + get position() { + return (this._type & HTMLStyle._ABSOLUTE) ? "absolute" : ""; + } + get absolute() { + return (this._type & HTMLStyle._ABSOLUTE) !== 0; + } + get paddingLeft() { + return this.padding[3]; + } + get paddingTop() { + return this.padding[0]; + } + static parseOneCSS(text, clipWord) { + var out = []; + var attrs = text.split(clipWord); + var valueArray; + for (var i = 0, n = attrs.length; i < n; i++) { + var attr = attrs[i]; + var ofs = attr.indexOf(':'); + var name = attr.substr(0, ofs).replace(/^\s+|\s+$/g, ''); + if (name.length === 0) + continue; + var value = attr.substr(ofs + 1).replace(/^\s+|\s+$/g, ''); + var one = [name, value]; + switch (name) { + case 'italic': + case 'bold': + one[1] = value == "true"; + break; + case "font-weight": + if (value == "bold") { + one[1] = true; + one[0] = "bold"; + } + break; + case 'line-height': + one[0] = 'lineHeight'; + one[1] = parseInt(value); + break; + case 'font-size': + one[0] = 'fontSize'; + one[1] = parseInt(value); + break; + case 'stroke': + one[0] = 'stroke'; + one[1] = parseInt(value); + break; + case 'padding': + valueArray = value.split(' '); + valueArray.length > 1 || (valueArray[1] = valueArray[2] = valueArray[3] = valueArray[0]); + one[1] = [parseInt(valueArray[0]), parseInt(valueArray[1]), parseInt(valueArray[2]), parseInt(valueArray[3])]; + break; + default: + (one[0] = HTMLStyle._CSSTOVALUE[name]) || (one[0] = name); + } + out.push(one); + } + return out; + } + static parseCSS(text, uri) { + var one; + while ((one = HTMLStyle._parseCSSRegExp.exec(text)) != null) { + HTMLStyle.styleSheets[one[1]] = HTMLStyle.parseOneCSS(one[2], ';'); + } + } + } + HTMLStyle._CSSTOVALUE = { 'letter-spacing': 'letterSpacing', 'white-space': 'whiteSpace', 'line-height': 'lineHeight', 'font-family': 'family', 'vertical-align': 'valign', 'text-decoration': 'textDecoration', 'background-color': 'bgColor', 'border-color': 'borderColor' }; + HTMLStyle._parseCSSRegExp = new RegExp("([\.\#]\\w+)\\s*{([\\s\\S]*?)}", "g"); + HTMLStyle._inheritProps = ["italic", "align", "valign", "leading", "letterSpacing", "stroke", "strokeColor", "bold", "fontWeight", "fontSize", "lineHeight", "wordWrap", "color"]; + HTMLStyle.ALIGN_LEFT = "left"; + HTMLStyle.ALIGN_CENTER = "center"; + HTMLStyle.ALIGN_RIGHT = "right"; + HTMLStyle.VALIGN_TOP = "top"; + HTMLStyle.VALIGN_MIDDLE = "middle"; + HTMLStyle.VALIGN_BOTTOM = "bottom"; + HTMLStyle.styleSheets = {}; + HTMLStyle.ADDLAYOUTED = 0x200; + HTMLStyle._PADDING = [0, 0, 0, 0]; + HTMLStyle._HEIGHT_SET = 0x2000; + HTMLStyle._LINE_ELEMENT = 0x10000; + HTMLStyle._NOWARP = 0x20000; + HTMLStyle._WIDTHAUTO = 0x40000; + HTMLStyle._BOLD = 0x400; + HTMLStyle._ITALIC = 0x800; + HTMLStyle._CSS_BLOCK = 0x1; + HTMLStyle._DISPLAY_NONE = 0x2; + HTMLStyle._ABSOLUTE = 0x4; + HTMLStyle._WIDTH_SET = 0x8; + HTMLStyle.alignVDic = { "left": 0, "center": 0x10, "right": 0x20, "top": 0, "middle": 0x40, "bottom": 0x80 }; + HTMLStyle.align_Value = { 0: "left", 0x10: "center", 0x20: "right" }; + HTMLStyle.vAlign_Value = { 0: "top", 0x40: "middle", 0x80: "bottom" }; + HTMLStyle._ALIGN = 0x30; + HTMLStyle._VALIGN = 0xc0; + Laya.ClassUtils.regClass("laya.html.utils.HTMLStyle", HTMLStyle); + Laya.ClassUtils.regClass("Laya.HTMLStyle", HTMLStyle); + + class HTMLDocument { + constructor() { + this.all = {}; + this.styleSheets = HTMLStyle.styleSheets; + } + getElementById(id) { + return this.all[id]; + } + setElementById(id, e) { + this.all[id] = e; + } + } + HTMLDocument.document = new HTMLDocument(); + Laya.ClassUtils.regClass("laya.html.dom.HTMLDocument", HTMLDocument); + Laya.ClassUtils.regClass("Laya.HTMLDocument", HTMLDocument); + + class HTMLHitRect { + constructor() { + this.rec = new Laya.Rectangle(); + this.reset(); + } + reset() { + this.rec.reset(); + this.href = null; + return this; + } + recover() { + Laya.Pool.recover("HTMLHitRect", this.reset()); + } + static create() { + return Laya.Pool.getItemByClass("HTMLHitRect", HTMLHitRect); + } + } + Laya.ClassUtils.regClass("laya.html.dom.HTMLHitRect", HTMLHitRect); + Laya.ClassUtils.regClass("Laya.HTMLHitRect", HTMLHitRect); + + class IHtml { + } + IHtml.HTMLDivElement = null; + IHtml.HTMLImageElement = null; + IHtml.HTMLBrElement = null; + IHtml.HTMLDivParser = null; + IHtml.HTMLParse = null; + IHtml.HTMLElementType = null; + + class LayoutLine { + constructor() { + this.elements = []; + this.x = 0; + this.y = 0; + this.w = 0; + this.h = 0; + this.wordStartIndex = 0; + this.minTextHeight = 99999; + this.mWidth = 0; + } + updatePos(left, width, lineNum, dy, align, valign, lineHeight) { + var w = 0; + var one; + if (this.elements.length > 0) { + one = this.elements[this.elements.length - 1]; + w = one.x + one.width - this.elements[0].x; + } + lineHeight = lineHeight || this.h; + var dx = 0, ddy; + if (align === HTMLStyle.ALIGN_CENTER) + dx = (width - w) / 2; + if (align === HTMLStyle.ALIGN_RIGHT) + dx = (width - w); + for (var i = 0, n = this.elements.length; i < n; i++) { + one = this.elements[i]; + var tCSSStyle = one._getCSSStyle(); + dx !== 0 && (one.x += dx); + switch (tCSSStyle.valign) { + case "top": + one.y = dy; + break; + case "middle": + var tMinTextHeight = 0; + if (this.minTextHeight != 99999) + tMinTextHeight = this.minTextHeight; + var tBottomLineY = (tMinTextHeight + lineHeight) / 2; + tBottomLineY = Math.max(tBottomLineY, this.h); + if (one.eletype == IHtml.HTMLElementType.IMAGE) + ddy = dy + tBottomLineY - one.height; + else + ddy = dy + tBottomLineY - one.height; + one.y = ddy; + break; + case "bottom": + one.y = dy + (lineHeight - one.height); + break; + } + } + } + } + Laya.ClassUtils.regClass("laya.html.utils.LayoutLine", LayoutLine); + Laya.ClassUtils.regClass("Laya.LayoutLine", LayoutLine); + + class Layout { + static later(element) { + if (Layout._will == null) { + Layout._will = []; + Laya.ILaya.stage.frameLoop(1, null, function () { + if (Layout._will.length < 1) + return; + for (var i = 0; i < Layout._will.length; i++) { + Layout.layout(Layout._will[i]); + } + Layout._will.length = 0; + }); + } + Layout._will.push(element); + } + static layout(element) { + if (!element || !element._style) + return null; + var style = element._style; + if ((style._type & HTMLStyle.ADDLAYOUTED) === 0) + return null; + element.style._type &= ~HTMLStyle.ADDLAYOUTED; + var arr = Layout._multiLineLayout(element); + return arr; + } + static _multiLineLayout(element) { + var elements = []; + element._addChildsToLayout(elements); + var i, n = elements.length; + var style = element._getCSSStyle(); + var letterSpacing = style.letterSpacing; + var leading = style.leading; + var lineHeight = style.lineHeight; + var widthAuto = style._widthAuto() || !style.wordWrap; + var width = widthAuto ? 999999 : element.width; + var height = element.height; + var maxWidth = 0; + var exWidth = style.italic ? style.fontSize / 3 : 0; + var align = style.align; + var valign = style.valign; + var endAdjust = valign !== HTMLStyle.VALIGN_TOP || align !== HTMLStyle.ALIGN_LEFT || lineHeight != 0; + var oneLayout; + var x = 0; + var y = 0; + var w = 0; + var h = 0; + var lines = []; + var curStyle; + var curPadding; + var curLine = lines[0] = new LayoutLine(); + var newLine, nextNewline = false; + var htmlWord; + var sprite; + curLine.h = 0; + if (style.italic) + width -= style.fontSize / 3; + var tWordWidth = 0; + var tLineFirstKey = true; + function addLine() { + curLine.y = y; + y += curLine.h + leading; + curLine.mWidth = tWordWidth; + tWordWidth = 0; + curLine = new LayoutLine(); + lines.push(curLine); + curLine.h = 0; + x = 0; + tLineFirstKey = true; + newLine = false; + } + for (i = 0; i < n; i++) { + oneLayout = elements[i]; + if (oneLayout == null) { + if (!tLineFirstKey) { + x += Layout.DIV_ELEMENT_PADDING; + } + curLine.wordStartIndex = curLine.elements.length; + continue; + } + tLineFirstKey = false; + if (oneLayout instanceof IHtml.HTMLBrElement) { + addLine(); + curLine.y = y; + curLine.h = lineHeight; + continue; + } + else if (oneLayout._isChar()) { + htmlWord = oneLayout; + w = htmlWord.width + htmlWord.style.letterSpacing; + h = htmlWord.height; + if (!htmlWord.isWord) { + if (lines.length > 0 && (x + w) > width && curLine.wordStartIndex > 0) { + var tLineWord = 0; + tLineWord = curLine.elements.length - curLine.wordStartIndex + 1; + curLine.elements.length = curLine.wordStartIndex; + i -= tLineWord; + addLine(); + continue; + } + newLine = false; + tWordWidth += htmlWord.width; + } + else { + newLine = nextNewline || (htmlWord.char === '\n'); + curLine.wordStartIndex = curLine.elements.length; + } + nextNewline = false; + newLine = newLine || ((x + w) > width); + newLine && addLine(); + curLine.minTextHeight = Math.min(curLine.minTextHeight, oneLayout.height); + } + else { + curStyle = oneLayout._getCSSStyle(); + sprite = oneLayout; + curPadding = curStyle.padding; + newLine = nextNewline || curStyle.getLineElement(); + w = sprite.width + curPadding[1] + curPadding[3] + curStyle.letterSpacing; + h = sprite.height + curPadding[0] + curPadding[2]; + nextNewline = curStyle.getLineElement(); + newLine = newLine || ((x + w) > width && curStyle.wordWrap); + newLine && addLine(); + } + curLine.elements.push(oneLayout); + curLine.h = Math.max(curLine.h, h); + oneLayout.x = x; + oneLayout.y = y; + x += w; + curLine.w = x - letterSpacing; + curLine.y = y; + maxWidth = Math.max(x + exWidth, maxWidth); + } + y = curLine.y + curLine.h; + if (endAdjust) { + var tY = 0; + var tWidth = width; + if (widthAuto && element.width > 0) { + tWidth = element.width; + } + for (i = 0, n = lines.length; i < n; i++) { + lines[i].updatePos(0, tWidth, i, tY, align, valign, lineHeight); + tY += Math.max(lineHeight, lines[i].h + leading); + } + y = tY; + } + widthAuto && (element.width = maxWidth); + (y > element.height) && (element.height = y); + return [maxWidth, y]; + } + } + Layout.DIV_ELEMENT_PADDING = 0; + Laya.ClassUtils.regClass("laya.html.utils.Layout", Layout); + Laya.ClassUtils.regClass("Laya.Layout", Layout); + + (function (HTMLElementType) { + HTMLElementType[HTMLElementType["BASE"] = 0] = "BASE"; + HTMLElementType[HTMLElementType["IMAGE"] = 1] = "IMAGE"; + })(exports.HTMLElementType || (exports.HTMLElementType = {})); + class HTMLElement { + constructor() { + this.eletype = exports.HTMLElementType.BASE; + this._creates(); + this.reset(); + } + static formatURL1(url, basePath = null) { + if (!url) + return "null path"; + if (!basePath) + basePath = Laya.URL.basePath; + if (url.indexOf(":") > 0) + return url; + if (Laya.URL.customFormat != null) + url = Laya.URL.customFormat(url); + if (url.indexOf(":") > 0) + return url; + var char1 = url.charAt(0); + if (char1 === ".") { + return Laya.URL._formatRelativePath(basePath + url); + } + else if (char1 === '~') { + return Laya.URL.rootPath + url.substring(1); + } + else if (char1 === "d") { + if (url.indexOf("data:image") === 0) + return url; + } + else if (char1 === "/") { + return url; + } + return basePath + url; + } + _creates() { + this._style = HTMLStyle.create(); + } + reset() { + this.URI = null; + this.parent = null; + this._style.reset(); + this._style.ower = this; + this._style.valign = "middle"; + if (this._text && this._text.words) { + var words = this._text.words; + var i, len; + len = words.length; + var tChar; + for (i = 0; i < len; i++) { + tChar = words[i]; + if (tChar) + tChar.recover(); + } + } + this._text = HTMLElement._EMPTYTEXT; + if (this._children) + this._children.length = 0; + this._x = this._y = this._width = this._height = 0; + return this; + } + _getCSSStyle() { + return this._style; + } + _addChildsToLayout(out) { + var words = this._getWords(); + if (words == null && (!this._children || this._children.length == 0)) + return false; + if (words) { + for (var i = 0, n = words.length; i < n; i++) { + out.push(words[i]); + } + } + if (this._children) + this._children.forEach(function (o, index, array) { + var _style = o._style; + _style._enableLayout && _style._enableLayout() && o._addToLayout(out); + }); + return true; + } + _addToLayout(out) { + if (!this._style) + return; + var style = this._style; + if (style.absolute) + return; + style.block ? out.push(this) : (this._addChildsToLayout(out) && (this.x = this.y = 0)); + } + set id(value) { + HTMLDocument.document.setElementById(value, this); + } + repaint(recreate = false) { + this.parentRepaint(recreate); + } + parentRepaint(recreate = false) { + if (this.parent) + this.parent.repaint(recreate); + } + set innerTEXT(value) { + if (this._text === HTMLElement._EMPTYTEXT) { + this._text = { text: value, words: null }; + } + else { + this._text.text = value; + this._text.words && (this._text.words.length = 0); + } + this.repaint(); + } + get innerTEXT() { + return this._text.text; + } + _setParent(value) { + if (value instanceof HTMLElement) { + var p = value; + this.URI || (this.URI = p.URI); + if (this.style) + this.style.inherit(p.style); + } + } + appendChild(c) { + return this.addChild(c); + } + addChild(c) { + if (c.parent) + c.parent.removeChild(c); + if (!this._children) + this._children = []; + this._children.push(c); + c.parent = this; + c._setParent(this); + this.repaint(); + return c; + } + removeChild(c) { + if (!this._children) + return null; + var i, len; + len = this._children.length; + for (i = 0; i < len; i++) { + if (this._children[i] == c) { + this._children.splice(i, 1); + return c; + } + } + return null; + } + static getClassName(tar) { + if (tar instanceof Function) + return tar.name; + return tar["constructor"].name; + } + destroy() { + if (this._children) { + this.destroyChildren(); + this._children.length = 0; + } + Laya.Pool.recover(HTMLElement.getClassName(this), this.reset()); + } + destroyChildren() { + if (this._children) { + for (var i = this._children.length - 1; i > -1; i--) { + this._children[i].destroy(); + } + this._children.length = 0; + } + } + get style() { + return this._style; + } + _getWords() { + if (!this._text) + return null; + var txt = this._text.text; + if (!txt || txt.length === 0) + return null; + var words = this._text.words; + if (words && words.length === txt.length) + return words; + words === null && (this._text.words = words = []); + words.length = txt.length; + var size; + var style = this.style; + var fontStr = style.font; + for (var i = 0, n = txt.length; i < n; i++) { + size = Laya.ILaya.Browser.measureText(txt.charAt(i), fontStr); + words[i] = Laya.HTMLChar.create().setData(txt.charAt(i), size.width, size.height || style.fontSize, style); + } + return words; + } + _isChar() { + return false; + } + _layoutLater() { + var style = this.style; + if ((style._type & HTMLStyle.ADDLAYOUTED)) + return; + if (style.widthed(this) && ((this._children && this._children.length > 0) || this._getWords() != null) && style.block) { + Layout.later(this); + style._type |= HTMLStyle.ADDLAYOUTED; + } + else { + this.parent && this.parent._layoutLater(); + } + } + set x(v) { + if (this._x != v) { + this._x = v; + this.parentRepaint(); + } + } + get x() { + return this._x; + } + set y(v) { + if (this._y != v) { + this._y = v; + this.parentRepaint(); + } + } + get y() { + return this._y; + } + get width() { + return this._width; + } + set width(value) { + if (this._width !== value) { + this._width = value; + this.repaint(); + } + } + get height() { + return this._height; + } + set height(value) { + if (this._height !== value) { + this._height = value; + this.repaint(); + } + } + _setAttributes(name, value) { + switch (name) { + case 'style': + this.style.cssText(value); + break; + case 'class': + this.className = value; + break; + case 'x': + this.x = parseFloat(value); + break; + case 'y': + this.y = parseFloat(value); + break; + case 'width': + this.width = parseFloat(value); + break; + case 'height': + this.height = parseFloat(value); + break; + default: + this[name] = value; + } + } + set href(url) { + if (!this._style) + return; + if (url != this._style.href) { + this._style.href = url; + this.repaint(); + } + } + get href() { + if (!this._style) + return null; + return this._style.href; + } + formatURL(url) { + if (!this.URI) + return url; + return HTMLElement.formatURL1(url, this.URI ? this.URI.path : null); + } + set color(value) { + this.style.color = value; + } + set className(value) { + this.style.attrs(HTMLDocument.document.styleSheets['.' + value]); + } + drawToGraphic(graphic, gX, gY, recList) { + gX += this.x; + gY += this.y; + var cssStyle = this.style; + if (cssStyle.paddingLeft) { + gX += cssStyle.paddingLeft; + } + if (cssStyle.paddingTop) { + gY += cssStyle.paddingTop; + } + if (cssStyle.bgColor != null || cssStyle.borderColor) { + graphic.drawRect(gX, gY, this.width, this.height, cssStyle.bgColor, cssStyle.borderColor, 1); + } + this.renderSelfToGraphic(graphic, gX, gY, recList); + var i, len; + var tChild; + if (this._children && this._children.length > 0) { + len = this._children.length; + for (i = 0; i < len; i++) { + tChild = this._children[i]; + if (tChild.drawToGraphic != null) + tChild.drawToGraphic(graphic, gX, gY, recList); + } + } + } + renderSelfToGraphic(graphic, gX, gY, recList) { + var cssStyle = this.style; + var words = this._getWords(); + var len; + if (words) { + len = words.length; + if (cssStyle) { + var font = cssStyle.font; + var color = cssStyle.color; + if (cssStyle.stroke) { + var stroke = cssStyle.stroke; + stroke = parseInt(stroke); + var strokeColor = cssStyle.strokeColor; + graphic.fillBorderWords(words, gX, gY, font, color, strokeColor, stroke); + } + else { + graphic.fillWords(words, gX, gY, font, color); + } + if (this.href) { + var lastIndex = words.length - 1; + var lastWords = words[lastIndex]; + var lineY = lastWords.y + lastWords.height; + if (lastWords.y == words[0].y) { + if (cssStyle.textDecoration != "none") + graphic.drawLine(words[0].x, lineY, lastWords.x + lastWords.width, lineY, color, 1); + var hitRec = HTMLHitRect.create(); + hitRec.rec.setTo(words[0].x, lastWords.y, lastWords.x + lastWords.width - words[0].x, lastWords.height); + hitRec.href = this.href; + recList.push(hitRec); + } + else { + this.workLines(words, graphic, recList); + } + } + } + } + } + workLines(wordList, g, recList) { + var cssStyle = this.style; + var hasLine; + hasLine = cssStyle.textDecoration != "none"; + var i = 0, len; + len = wordList.length; + var tStartWord; + tStartWord = wordList[i]; + var tEndWord; + tEndWord = tStartWord; + if (!tStartWord) + return; + var tword; + for (i = 1; i < len; i++) { + tword = wordList[i]; + if (tword.y != tStartWord.y) { + this.createOneLine(tStartWord, tEndWord, hasLine, g, recList); + tStartWord = tword; + tEndWord = tword; + } + else { + tEndWord = tword; + } + } + this.createOneLine(tStartWord, tEndWord, hasLine, g, recList); + } + createOneLine(startWord, lastWords, hasLine, graphic, recList) { + var lineY = lastWords.y + lastWords.height; + if (hasLine) + graphic.drawLine(startWord.x, lineY, lastWords.x + lastWords.width, lineY, this.style.color, 1); + var hitRec = HTMLHitRect.create(); + hitRec.rec.setTo(startWord.x, lastWords.y, lastWords.x + lastWords.width - startWord.x, lastWords.height); + hitRec.href = this.href; + recList.push(hitRec); + } + } + HTMLElement._EMPTYTEXT = { text: null, words: null }; + Laya.ILaya.regClass(HTMLElement); + IHtml.HTMLElementType = exports.HTMLElementType; + Laya.ClassUtils.regClass("laya.html.dom.HTMLElement", HTMLElement); + Laya.ClassUtils.regClass("Laya.HTMLElement", HTMLElement); + + class HTMLBrElement { + _addToLayout(out) { + out.push(this); + } + reset() { + return this; + } + destroy() { + Laya.Pool.recover(HTMLElement.getClassName(this), this.reset()); + } + _setParent(value) { + } + set parent(value) { + } + set URI(value) { + } + set href(value) { + } + _getCSSStyle() { + if (!HTMLBrElement.brStyle) { + HTMLBrElement.brStyle = new HTMLStyle(); + HTMLBrElement.brStyle.setLineElement(true); + HTMLBrElement.brStyle.block = true; + } + return HTMLBrElement.brStyle; + } + renderSelfToGraphic(graphic, gX, gY, recList) { + } + } + IHtml.HTMLBrElement = HTMLBrElement; + Laya.ILaya.regClass(HTMLBrElement); + Laya.ClassUtils.regClass("laya.html.dom.HTMLBrElement", HTMLBrElement); + Laya.ClassUtils.regClass("Laya.HTMLBrElement", HTMLBrElement); + + class HTMLStyleElement extends HTMLElement { + _creates() { + } + drawToGraphic(graphic, gX, gY, recList) { + } + reset() { + return this; + } + set innerTEXT(value) { + HTMLStyle.parseCSS(value, null); + } + get innerTEXT() { + return super.innerTEXT; + } + } + Laya.ILaya.regClass(HTMLStyleElement); + Laya.ClassUtils.regClass("laya.html.dom.HTMLStyleElement", HTMLStyleElement); + Laya.ClassUtils.regClass("Laya.HTMLStyleElement", HTMLStyleElement); + + class HTMLLinkElement extends HTMLElement { + _creates() { + } + drawToGraphic(graphic, gX, gY, recList) { + } + reset() { + if (this._loader) + this._loader.off(Laya.Event.COMPLETE, this, this._onload); + this._loader = null; + return this; + } + _onload(data) { + if (this._loader) + this._loader = null; + switch (this.type) { + case 'text/css': + HTMLStyle.parseCSS(data, this.URI); + break; + } + this.repaint(true); + } + set href(url) { + if (!url) + return; + url = this.formatURL(url); + this.URI = new Laya.URL(url); + if (this._loader) + this._loader.off(Laya.Event.COMPLETE, this, this._onload); + if (Laya.Loader.getRes(url)) { + if (this.type == "text/css") { + HTMLStyle.parseCSS(Laya.Loader.getRes(url), this.URI); + } + return; + } + this._loader = new Laya.Loader(); + this._loader.once(Laya.Event.COMPLETE, this, this._onload); + this._loader.load(url, Laya.Loader.TEXT); + } + get href() { + return super.href; + } + } + HTMLLinkElement._cuttingStyle = new RegExp("((@keyframes[\\s\\t]+|)(.+))[\\t\\n\\r\\\s]*{", "g"); + Laya.ILaya.regClass(HTMLLinkElement); + Laya.ClassUtils.regClass("laya.html.dom.HTMLLinkElement", HTMLLinkElement); + Laya.ClassUtils.regClass("Laya.HTMLLinkElement", HTMLLinkElement); + + class HTMLDivParser extends HTMLElement { + constructor() { + super(...arguments); + this.repaintHandler = null; + } + reset() { + super.reset(); + this._style.block = true; + this._style.setLineElement(true); + this._style.width = 200; + this._style.height = 200; + this.repaintHandler = null; + this.contextHeight = 0; + this.contextWidth = 0; + return this; + } + set innerHTML(text) { + this.destroyChildren(); + this.appendHTML(text); + } + set width(value) { + var changed; + if (value === 0) { + changed = value != this._width; + } + else { + changed = value != this.width; + } + super.width = value; + if (changed) + this.layout(); + } + appendHTML(text) { + IHtml.HTMLParse.parse(this, text, this.URI); + this.layout(); + } + _addChildsToLayout(out) { + var words = this._getWords(); + if (words == null && (!this._children || this._children.length == 0)) + return false; + words && words.forEach(function (o) { + out.push(o); + }); + var tFirstKey = true; + for (var i = 0, len = this._children.length; i < len; i++) { + var o = this._children[i]; + if (tFirstKey) { + tFirstKey = false; + } + else { + out.push(null); + } + o._addToLayout(out); + } + return true; + } + _addToLayout(out) { + this.layout(); + !this.style.absolute && out.push(this); + } + getBounds() { + if (!this._htmlBounds) + return null; + if (!this._boundsRec) + this._boundsRec = Laya.Rectangle.create(); + return this._boundsRec.copyFrom(this._htmlBounds); + } + parentRepaint(recreate = false) { + super.parentRepaint(); + if (this.repaintHandler) + this.repaintHandler.runWith(recreate); + } + layout() { + this.style._type |= HTMLStyle.ADDLAYOUTED; + var tArray = Layout.layout(this); + if (tArray) { + if (!this._htmlBounds) + this._htmlBounds = Laya.Rectangle.create(); + var tRectangle = this._htmlBounds; + tRectangle.x = tRectangle.y = 0; + tRectangle.width = this.contextWidth = tArray[0]; + tRectangle.height = this.contextHeight = tArray[1]; + } + } + get height() { + if (this._height) + return this._height; + return this.contextHeight; + } + set height(value) { + super.height = value; + } + get width() { + if (this._width) + return this._width; + return this.contextWidth; + } + } + IHtml.HTMLDivParser = HTMLDivParser; + Laya.ILaya.regClass(HTMLDivParser); + Laya.ClassUtils.regClass("laya.html.dom.HTMLDivParser", HTMLDivParser); + Laya.ClassUtils.regClass("Laya.HTMLDivParser", HTMLDivParser); + + class HTMLImageElement extends HTMLElement { + constructor() { + super(); + this.eletype = exports.HTMLElementType.IMAGE; + } + reset() { + super.reset(); + if (this._tex) { + this._tex.off(Laya.Event.LOADED, this, this.onloaded); + } + this._tex = null; + this._url = null; + return this; + } + set src(url) { + url = this.formatURL(url); + if (this._url === url) + return; + this._url = url; + var tex = this._tex = Laya.Loader.getRes(url); + if (!tex) { + this._tex = tex = new Laya.Texture(); + tex.load(url); + Laya.Loader.cacheTexture(url, tex); + } + tex.getIsReady() ? this.onloaded() : tex.once(Laya.Event.READY, this, this.onloaded); + } + onloaded() { + if (!this._style) + return; + var style = this._style; + var w = style.widthed(this) ? -1 : this._tex.width; + var h = style.heighted(this) ? -1 : this._tex.height; + if (!style.widthed(this) && this._width != this._tex.width) { + this.width = this._tex.width; + this.parent && this.parent._layoutLater(); + } + if (!style.heighted(this) && this._height != this._tex.height) { + this.height = this._tex.height; + this.parent && this.parent._layoutLater(); + } + this.repaint(); + } + _addToLayout(out) { + var style = this._style; + !style.absolute && out.push(this); + } + renderSelfToGraphic(graphic, gX, gY, recList) { + if (!this._tex) + return; + graphic.drawImage(this._tex, gX, gY, this.width || this._tex.width, this.height || this._tex.height); + } + } + IHtml.HTMLImageElement = HTMLImageElement; + Laya.ILaya.regClass(HTMLImageElement); + Laya.ClassUtils.regClass("laya.html.dom.HTMLImageElement", HTMLImageElement); + Laya.ClassUtils.regClass("Laya.HTMLImageElement", HTMLImageElement); + + class HTMLParse { + static getInstance(type) { + var rst = Laya.Pool.getItem(HTMLParse._htmlClassMapShort[type]); + if (!rst) { + rst = Laya.ClassUtils.getInstance(type); + } + return rst; + } + static parse(ower, xmlString, url) { + xmlString = xmlString.replace(/
/g, "
"); + xmlString = "" + xmlString + ""; + xmlString = xmlString.replace(HTMLParse.spacePattern, HTMLParse.char255); + var xml = Laya.Utils.parseXMLFromString(xmlString); + HTMLParse._parseXML(ower, xml.childNodes[0].childNodes, url); + } + static _parseXML(parent, xml, url, href = null) { + var i, n; + if (xml.join || xml.item) { + for (i = 0, n = xml.length; i < n; ++i) { + HTMLParse._parseXML(parent, xml[i], url, href); + } + } + else { + var node; + var nodeName; + if (xml.nodeType == 3) { + var txt; + if (parent instanceof IHtml.HTMLDivParser) { + if (xml.nodeName == null) { + xml.nodeName = "#text"; + } + nodeName = xml.nodeName.toLowerCase(); + txt = xml.textContent.replace(/^\s+|\s+$/g, ''); + if (txt.length > 0) { + node = HTMLParse.getInstance(nodeName); + if (node) { + parent.addChild(node); + (node.innerTEXT = txt.replace(HTMLParse.char255AndOneSpacePattern, " ")); + } + } + } + else { + txt = xml.textContent.replace(/^\s+|\s+$/g, ''); + if (txt.length > 0) { + var containNode = parent; + if (parent instanceof HTMLElement && parent.innerTEXT && parent.innerTEXT.length > 0) { + let cnode = HTMLParse.getInstance('p'); + if (cnode) { + parent.addChild(cnode); + containNode = cnode; + } + } + containNode.innerTEXT = txt.replace(HTMLParse.char255AndOneSpacePattern, " "); + } + } + return; + } + else { + nodeName = xml.nodeName.toLowerCase(); + if (nodeName == "#comment") + return; + node = HTMLParse.getInstance(nodeName); + if (node) { + if (nodeName == "p") { + parent.addChild(HTMLParse.getInstance("br")); + node = parent.addChild(node); + parent.addChild(HTMLParse.getInstance("br")); + } + else { + node = parent.addChild(node); + } + node.URI = url; + node.href = href; + var attributes = xml.attributes; + if (attributes && attributes.length > 0) { + for (i = 0, n = attributes.length; i < n; ++i) { + var attribute = attributes[i]; + var attrName = attribute.nodeName; + var value = attribute.value; + node._setAttributes(attrName, value); + } + } + HTMLParse._parseXML(node, xml.childNodes, url, node.href); + } + else { + HTMLParse._parseXML(parent, xml.childNodes, url, href); + } + } + } + } + } + HTMLParse.char255 = String.fromCharCode(255); + HTMLParse.spacePattern = / | /g; + HTMLParse.char255AndOneSpacePattern = new RegExp(String.fromCharCode(255) + "|(\\s+)", "g"); + HTMLParse._htmlClassMapShort = { + 'div': HTMLDivParser, + 'p': HTMLElement, + 'img': HTMLImageElement, + 'span': HTMLElement, + 'br': HTMLBrElement, + 'style': HTMLStyleElement, + 'font': HTMLElement, + 'a': HTMLElement, + '#text': HTMLElement, + 'link': HTMLLinkElement + }; + IHtml.HTMLParse = HTMLParse; + Laya.ClassUtils.regClass('div', HTMLDivParser); + Laya.ClassUtils.regClass('p', HTMLElement); + Laya.ClassUtils.regClass('img', HTMLImageElement); + Laya.ClassUtils.regClass('span', HTMLElement); + Laya.ClassUtils.regClass('br', HTMLBrElement); + Laya.ClassUtils.regClass('style', HTMLStyleElement); + Laya.ClassUtils.regClass('font', HTMLElement); + Laya.ClassUtils.regClass('a', HTMLElement); + Laya.ClassUtils.regClass('#text', HTMLElement); + Laya.ClassUtils.regClass('link', HTMLLinkElement); + Laya.ClassUtils.regClass("laya.html.utils.HTMLParse", HTMLParse); + Laya.ClassUtils.regClass("Laya.HTMLParse", HTMLParse); + + class HTMLDivElement extends Laya.Sprite { + constructor() { + super(); + this._recList = []; + this._repaintState = 0; + this._element = new HTMLDivParser(); + this._element.repaintHandler = new Laya.Handler(this, this._htmlDivRepaint); + this.mouseEnabled = true; + this.on(Laya.Event.CLICK, this, this._onMouseClick); + } + destroy(destroyChild = true) { + if (this._element) + this._element.reset(); + this._element = null; + this._doClears(); + super.destroy(destroyChild); + } + _htmlDivRepaint(recreate = false) { + if (recreate) { + if (this._repaintState < 2) + this._repaintState = 2; + } + else { + if (this._repaintState < 1) + this._repaintState = 1; + } + if (this._repaintState > 0) + this._setGraphicDirty(); + } + _updateGraphicWork() { + switch (this._repaintState) { + case 1: + this._updateGraphic(); + break; + case 2: + this._refresh(); + break; + } + } + _setGraphicDirty() { + this.callLater(this._updateGraphicWork); + } + _doClears() { + if (!this._recList) + return; + var i, len = this._recList.length; + var tRec; + for (i = 0; i < len; i++) { + tRec = this._recList[i]; + tRec.recover(); + } + this._recList.length = 0; + } + _updateGraphic() { + this._doClears(); + this.graphics.clear(true); + this._repaintState = 0; + this._element.drawToGraphic(this.graphics, -this._element.x, -this._element.y, this._recList); + var bounds = this._element.getBounds(); + if (bounds) + this.setSelfBounds(bounds); + this.size(bounds.width, bounds.height); + } + get style() { + return this._element.style; + } + set innerHTML(text) { + if (this._innerHTML == text) + return; + this._repaintState = 1; + this._innerHTML = text; + this._element.innerHTML = text; + this._setGraphicDirty(); + } + _refresh() { + this._repaintState = 1; + if (this._innerHTML) + this._element.innerHTML = this._innerHTML; + this._setGraphicDirty(); + } + set width(value) { + this._element.width = value; + } + get width() { + return this._element.width; + } + set height(value) { + this._element.height = value; + } + get height() { + return this._element.height; + } + get contextWidth() { + return this._element.contextWidth; + } + get contextHeight() { + return this._element.contextHeight; + } + _onMouseClick() { + var tX = this.mouseX; + var tY = this.mouseY; + var i, len; + var tHit; + len = this._recList.length; + for (i = 0; i < len; i++) { + tHit = this._recList[i]; + if (tHit.rec.contains(tX, tY)) { + this._eventLink(tHit.href); + } + } + } + _eventLink(href) { + this.event(Laya.Event.LINK, [href]); + } + } + IHtml.HTMLDivElement = HTMLDivElement; + IHtml.HTMLParse = HTMLParse; + Laya.ClassUtils.regClass("laya.html.dom.HTMLDivElement", HTMLDivElement); + Laya.ClassUtils.regClass("Laya.HTMLDivElement", HTMLDivElement); + + class HTMLIframeElement extends HTMLDivElement { + constructor() { + super(); + this._element._getCSSStyle().valign = "middle"; + } + set href(url) { + url = this._element.formatURL(url); + var l = new Laya.Loader(); + l.once(Laya.Event.COMPLETE, null, (data) => { + var pre = this._element.URI; + this._element.URI = new Laya.URL(url); + this.innerHTML = data; + !pre || (this._element.URI = pre); + }); + l.load(url, Laya.Loader.TEXT); + } + } + Laya.ClassUtils.regClass("laya.html.dom.HTMLIframeElement", HTMLIframeElement); + Laya.ClassUtils.regClass("Laya.HTMLIframeElement", HTMLIframeElement); + + exports.HTMLBrElement = HTMLBrElement; + exports.HTMLDivElement = HTMLDivElement; + exports.HTMLDivParser = HTMLDivParser; + exports.HTMLDocument = HTMLDocument; + exports.HTMLElement = HTMLElement; + exports.HTMLExtendStyle = HTMLExtendStyle; + exports.HTMLHitRect = HTMLHitRect; + exports.HTMLIframeElement = HTMLIframeElement; + exports.HTMLImageElement = HTMLImageElement; + exports.HTMLLinkElement = HTMLLinkElement; + exports.HTMLParse = HTMLParse; + exports.HTMLStyle = HTMLStyle; + exports.HTMLStyleElement = HTMLStyleElement; + exports.IHtml = IHtml; + exports.Layout = Layout; + exports.LayoutLine = LayoutLine; + +}(window.Laya = window.Laya || {}, Laya)); diff --git a/examples/layaair/frontend/bin/libs/laya.hwmini.js b/examples/layaair/frontend/bin/libs/laya.hwmini.js new file mode 100644 index 0000000..631fd35 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.hwmini.js @@ -0,0 +1,1508 @@ +window.hwMiniGame = function (exports, Laya) { + 'use strict'; + + class MiniFileMgr { + static isLocalNativeFile(url) { + for (var i = 0, sz = HWMiniAdapter.nativefiles.length; i < sz; i++) { + if (url.indexOf(HWMiniAdapter.nativefiles[i]) != -1) + return true; + } + return false; + } + static isNetFile(url) { + return (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) && url.indexOf(HWMiniAdapter.window.hbs.env.USER_DATA_PATH) == -1; + } + static getFileInfo(fileUrl) { + var fileNativePath = fileUrl; + var fileObj = MiniFileMgr.fakeObj[fileNativePath]; + if (fileObj == null) + return null; + else + return fileObj; + } + static read(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "") { + var fileUrl; + if (readyUrl != "" && (readyUrl.indexOf("http://") != -1 || readyUrl.indexOf("https://") != -1)) { + fileUrl = MiniFileMgr.getFileNativePath(filePath); + } + else { + fileUrl = filePath; + } + fileUrl = Laya.URL.getAdptedFilePath(fileUrl); + MiniFileMgr.fs.readFile({ filePath: fileUrl, encoding: encoding, success: function (data) { + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data && readyUrl != "") + MiniFileMgr.downFiles(HWMiniAdapter.safeEncodeURI(readyUrl), encoding, callBack, readyUrl, isSaveFile, fileType); + else + callBack != null && callBack.runWith([1]); + } }); + } + static isFile(url) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(url); + } + catch (err) { + return false; + } + return stat.isFile(); + } + static downFiles(fileUrl, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + var downloadTask = MiniFileMgr.hbsdown({ url: fileUrl, success: function (data) { + if (data.statusCode === 200) + MiniFileMgr.readFile(data.tempFilePath, encoding, callBack, readyUrl, isSaveFile, fileType, isAutoClear); + else if (data.statusCode === 403) { + callBack != null && callBack.runWith([0, fileUrl]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + downloadTask.onProgressUpdate(function (data) { + callBack != null && callBack.runWith([2, data.progress]); + }); + } + static readFile(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + filePath = Laya.URL.getAdptedFilePath(filePath); + MiniFileMgr.fs.readFile({ filePath: filePath, encoding: encoding, success: function (data) { + if ((filePath.indexOf("http://") != -1 || filePath.indexOf("https://") != -1) && filePath.indexOf(HWMiniAdapter.window.hbs.env.USER_DATA_PATH) == -1) { + if (HWMiniAdapter.AutoCacheDownFile || isSaveFile) { + callBack != null && callBack.runWith([0, data]); + MiniFileMgr.copyTOCache(filePath, readyUrl, null, encoding, isAutoClear); + } + else + callBack != null && callBack.runWith([0, data]); + } + else + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data) + callBack != null && callBack.runWith([1, data]); + } }); + } + static downOtherFiles(fileUrl, callBack = null, readyUrl = "", isSaveFile = false, isAutoClear = true) { + MiniFileMgr.hbsdown({ url: fileUrl, success: function (data) { + if (data.statusCode === 200) { + if ((HWMiniAdapter.autoCacheFile || isSaveFile) && readyUrl.indexOf(".php") == -1) { + callBack != null && callBack.runWith([0, data.tempFilePath]); + MiniFileMgr.copyTOCache(data.tempFilePath, readyUrl, null, "", isAutoClear); + } + else + callBack != null && callBack.runWith([0, data.tempFilePath]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static copyFile(src, dest, complete = null) { + MiniFileMgr.fs.copyFile({ + srcPath: src, + destPath: dest, + success: function () { + complete && complete.runWith(0); + }, + fail: function (err) { + complete && complete.runWith([1, err]); + } + }); + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + if (!('hbs' in window)) { + Laya.Laya.loader.load(fileUrl, callBack); + } + else { + if (fileType == Laya.Loader.IMAGE || fileType == Laya.Loader.SOUND) + MiniFileMgr.downOtherFiles(HWMiniAdapter.safeEncodeURI(fileUrl), callBack, fileUrl, true, false); + else + MiniFileMgr.downFiles(HWMiniAdapter.safeEncodeURI(fileUrl), encoding, callBack, fileUrl, true, fileType, false); + } + } + static copyTOCache(tempFilePath, readyUrl, callBack, encoding = "", isAutoClear = true) { + var temp = tempFilePath.split("/"); + var tempFileName = temp[temp.length - 1]; + var fileurlkey = readyUrl; + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fakeObj[fileurlkey] = { md5: tempFileName, readyUrl: readyUrl, size: 0, times: Laya.Browser.now(), encoding: encoding, tempFilePath: tempFilePath }; + var totalSize = HWMiniAdapter.sizeLimit; + var chaSize = 4 * 1024 * 1024; + var fileUseSize = MiniFileMgr.getCacheUseSize(); + if (fileObj) { + if (fileObj.readyUrl != readyUrl) { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > HWMiniAdapter.minClearSize) + HWMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.deleteFile(tempFilePath, readyUrl, callBack, encoding, data.size); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + else + callBack != null && callBack.runWith([0]); + } + else { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > HWMiniAdapter.minClearSize) + HWMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.fs.copyFile({ srcPath: tempFilePath, destPath: saveFilePath, success: function (data2) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, data.size); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + } + static onClearCacheRes() { + var memSize = HWMiniAdapter.minClearSize; + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + MiniFileMgr.sortOn(tempFileListArr, "times", MiniFileMgr.NUMERIC); + var clearSize = 0; + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + if (clearSize >= memSize) + break; + clearSize += fileObj.size; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + } + static sortOn(array, name, options = 0) { + if (options == MiniFileMgr.NUMERIC) + return array.sort(function (a, b) { return a[name] - b[name]; }); + if (options == (MiniFileMgr.NUMERIC | MiniFileMgr.DESCENDING)) + return array.sort(function (a, b) { return b[name] - a[name]; }); + return array.sort(function (a, b) { return a[name] - b[name]; }); + } + static getFileNativePath(fileName) { + return MiniFileMgr.fileNativeDir + "/" + fileName; + } + static deleteFile(tempFileName, readyUrl = "", callBack = null, encoding = "", fileSize = 0) { + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var deleteFileUrl = MiniFileMgr.getFileNativePath(fileObj.md5); + MiniFileMgr.fs.unlink({ filePath: deleteFileUrl, success: function (data) { + if (tempFileName != "") { + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fs.copyFile({ srcPath: tempFileName, destPath: saveFilePath, success: function (data) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, fileSize); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + else { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, false, encoding, callBack, fileSize); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static deleteAll() { + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj.fileUsedSize) { + MiniFileMgr.filesListObj.fileUsedSize = 0; + } + MiniFileMgr.writeFilesList("", JSON.stringify({}), false); + } + static onSaveFile(readyUrl, md5Name, isAdd = true, encoding = "", callBack = null, fileSize = 0) { + var fileurlkey = readyUrl; + if (MiniFileMgr.filesListObj['fileUsedSize'] == null) + MiniFileMgr.filesListObj['fileUsedSize'] = 0; + if (isAdd) { + var fileNativeName = MiniFileMgr.getFileNativePath(md5Name); + MiniFileMgr.filesListObj[fileurlkey] = { md5: md5Name, readyUrl: readyUrl, size: fileSize, times: Laya.Browser.now(), encoding: encoding, tempFilePath: fileNativeName }; + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) + fileSize; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), true); + callBack != null && callBack.runWith([0]); + } + else { + if (MiniFileMgr.filesListObj[fileurlkey]) { + var deletefileSize = parseInt(MiniFileMgr.filesListObj[fileurlkey].size); + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) - deletefileSize; + if (MiniFileMgr.fakeObj[fileurlkey].md5 == MiniFileMgr.filesListObj[fileurlkey].md5) { + delete MiniFileMgr.fakeObj[fileurlkey]; + } + delete MiniFileMgr.filesListObj[fileurlkey]; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), false); + callBack != null && callBack.runWith([0]); + } + } + } + static writeFilesList(fileurlkey, filesListStr, isAdd) { + var listFilesPath = MiniFileMgr.fileNativeDir + "/" + MiniFileMgr.fileListName; + MiniFileMgr.fs.writeFile({ + filePath: listFilesPath, + encoding: 'utf8', + data: filesListStr, + success: function (data) { + }, + fail: function (data) { + } + }); + } + static getCacheUseSize() { + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj['fileUsedSize']) + return MiniFileMgr.filesListObj['fileUsedSize']; + return 0; + } + static getCacheList(dirPath, cb) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(dirPath); + } + catch (err) { + stat = null; + } + if (stat) { + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", cb); + } + else { + MiniFileMgr.fs.mkdirSync(dirPath, true); + cb && cb.runWith([1]); + } + } + static existDir(dirPath, callBack) { + MiniFileMgr.fs.mkdir({ dirPath: dirPath, success: function (data) { + callBack != null && callBack.runWith([0, { data: JSON.stringify({}) }]); + }, fail: function (data) { + if (data.errMsg.indexOf("file already exists") != -1) + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", callBack); + else + callBack != null && callBack.runWith([1, data]); + } }); + } + static readSync(filePath, encoding = "utf8", callBack = null, readyUrl = "") { + var fileUrl = MiniFileMgr.getFileNativePath(filePath); + var filesListStr; + try { + filesListStr = MiniFileMgr.fs.readFileSync(fileUrl, encoding); + callBack != null && callBack.runWith([0, { data: filesListStr }]); + } + catch (error) { + callBack != null && callBack.runWith([1]); + } + } + static setNativeFileDir(value) { + MiniFileMgr.fileNativeDir = HWMiniAdapter.window.hbs.env.USER_DATA_PATH + value; + } + } + MiniFileMgr.fs = window.hbs.getFileSystemManager(); + MiniFileMgr.hbsdown = window.hbs.downloadFile; + MiniFileMgr.filesListObj = {}; + MiniFileMgr.fakeObj = {}; + MiniFileMgr.fileListName = "layaairfiles.txt"; + MiniFileMgr.loadPath = ""; + MiniFileMgr.DESCENDING = 2; + MiniFileMgr.NUMERIC = 16; + + class MiniSoundChannel extends Laya.SoundChannel { + constructor(audio, miniSound) { + super(); + this._audio = audio; + this._miniSound = miniSound; + this._onEnd = MiniSoundChannel.bindToThis(this.__onEnd, this); + audio.onEnded(this._onEnd); + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + __onEnd() { + if (this.loops == 1) { + if (this.completeHandler) { + Laya.Laya.systemTimer.once(10, this, this.__runComplete, [this.completeHandler], false); + this.completeHandler = null; + } + this.stop(); + this.event(Laya.Event.COMPLETE); + return; + } + if (this.loops > 0) { + this.loops--; + } + this.startTime = 0; + this.play(); + } + play() { + this.isStopped = false; + Laya.SoundManager.addChannel(this); + this._audio.play(); + } + set startTime(time) { + if (this._audio) { + this._audio.startTime = time; + } + } + set autoplay(value) { + this._audio.autoplay = value; + } + get autoplay() { + return this._audio.autoplay; + } + get position() { + if (!this._audio) + return 0; + return this._audio.currentTime; + } + get duration() { + if (!this._audio) + return 0; + return this._audio.duration; + } + stop() { + this.isStopped = true; + Laya.SoundManager.removeChannel(this); + this.completeHandler = null; + if (!this._audio) + return; + this._audio.stop(); + if (!this.loop) { + this._audio.offEnded(null); + this._miniSound.dispose(); + this._audio = null; + this._miniSound = null; + this._onEnd = null; + } + } + pause() { + this.isStopped = true; + this._audio.pause(); + } + get loop() { + return this._audio.loop; + } + set loop(value) { + this._audio.loop = value; + } + resume() { + if (!this._audio) + return; + this.isStopped = false; + Laya.SoundManager.addChannel(this); + this._audio.play(); + } + set volume(v) { + if (!this._audio) + return; + this._audio.volume = v; + } + get volume() { + if (!this._audio) + return 1; + return this._audio.volume; + } + } + + class MiniSound extends Laya.EventDispatcher { + constructor() { + super(); + this.loaded = false; + } + static _createSound() { + MiniSound._id++; + return HWMiniAdapter.window.hbs.createInnerAudioContext(); + } + load(url) { + if (!MiniSound._musicAudio) + MiniSound._musicAudio = MiniSound._createSound(); + if (!MiniFileMgr.isLocalNativeFile(url)) { + url = Laya.URL.formatURL(url); + } + else { + if (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + if (tempStr != "") + url = url.split(tempStr)[1]; + } + } + } + this.url = url; + this.readyUrl = url; + if (MiniSound._audioCache[this.readyUrl]) { + this.event(Laya.Event.COMPLETE); + return; + } + if (HWMiniAdapter.autoCacheFile && MiniFileMgr.getFileInfo(url)) { + this.onDownLoadCallBack(url, 0); + } + else { + if (!HWMiniAdapter.autoCacheFile) { + this.onDownLoadCallBack(url, 0); + } + else { + if (MiniFileMgr.isLocalNativeFile(url)) { + tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + if (HWMiniAdapter.subNativeFiles && HWMiniAdapter.subNativeheads.length == 0) { + for (var key in HWMiniAdapter.subNativeFiles) { + var tempArr = HWMiniAdapter.subNativeFiles[key]; + HWMiniAdapter.subNativeheads = HWMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + HWMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (HWMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && HWMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = HWMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + this.onDownLoadCallBack(url, 0); + } + else { + if (!MiniFileMgr.isLocalNativeFile(url) && (url.indexOf("http://") == -1 && url.indexOf("https://") == -1) || (url.indexOf("http://usr/") != -1)) { + this.onDownLoadCallBack(url, 0); + } + else { + MiniFileMgr.downOtherFiles(encodeURI(url), Laya.Handler.create(this, this.onDownLoadCallBack, [url]), url); + } + } + } + } + } + onDownLoadCallBack(sourceUrl, errorCode, tempFilePath = null) { + if (!errorCode) { + var fileNativeUrl; + if (HWMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = sourceUrl; + if (tempStr != "" && (sourceUrl.indexOf("http://") != -1 || sourceUrl.indexOf("https://") != -1)) + fileNativeUrl = sourceUrl.split(tempStr)[1]; + if (!fileNativeUrl) { + fileNativeUrl = tempUrl; + } + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + var fileMd5Name = fileObj.md5; + fileNativeUrl = MiniFileMgr.getFileNativePath(fileMd5Name); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + if (this.url != Laya.SoundManager._bgMusic) { + this._sound = MiniSound._createSound(); + this._sound.src = this.url = fileNativeUrl; + } + else { + this._sound = MiniSound._musicAudio; + this._sound.src = this.url = fileNativeUrl; + } + } + else { + if (this.url != Laya.SoundManager._bgMusic) { + this._sound = MiniSound._createSound(); + this._sound.src = sourceUrl; + } + else { + this._sound = MiniSound._musicAudio; + this._sound.src = sourceUrl; + } + } + this._sound.onCanplay(MiniSound.bindToThis(this.onCanPlay, this)); + this._sound.onError(MiniSound.bindToThis(this.onError, this)); + } + else { + this.event(Laya.Event.ERROR); + } + } + onError(error) { + try { + console.log("-----1---------------minisound-----id:" + MiniSound._id); + console.log(error); + } + catch (error) { + console.log("-----2---------------minisound-----id:" + MiniSound._id); + console.log(error); + } + this.event(Laya.Event.ERROR); + this._sound.offError(null); + } + onCanPlay() { + this.loaded = true; + this.event(Laya.Event.COMPLETE); + this._sound.offCanplay(null); + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + play(startTime = 0, loops = 0) { + var tSound; + if (this.url == Laya.SoundManager._bgMusic) { + if (!MiniSound._musicAudio) + MiniSound._musicAudio = MiniSound._createSound(); + tSound = MiniSound._musicAudio; + } + else { + if (MiniSound._audioCache[this.readyUrl]) { + tSound = MiniSound._audioCache[this.readyUrl]._sound; + } + else { + tSound = MiniSound._createSound(); + } + } + if (!tSound) + return null; + if (HWMiniAdapter.autoCacheFile && MiniFileMgr.getFileInfo(this.url)) { + var fileObj = MiniFileMgr.getFileInfo(this.url); + var fileMd5Name = fileObj.md5; + tSound.src = this.url = MiniFileMgr.getFileNativePath(fileMd5Name); + } + else { + tSound.src = this.url; + } + var channel = new MiniSoundChannel(tSound, this); + channel.url = this.url; + channel.loops = loops; + channel.loop = (loops === 0 ? true : false); + channel.startTime = startTime; + channel.play(); + Laya.SoundManager.addChannel(channel); + return channel; + } + get duration() { + return this._sound.duration; + } + dispose() { + var ad = MiniSound._audioCache[this.readyUrl]; + if (ad) { + ad.src = ""; + if (ad._sound) { + ad._sound.destroy(); + ad._sound = null; + ad = null; + } + delete MiniSound._audioCache[this.readyUrl]; + } + if (this._sound) { + this._sound.destroy(); + this._sound = null; + this.readyUrl = this.url = null; + } + } + } + MiniSound._id = 0; + MiniSound._audioCache = {}; + + class MiniInput { + constructor() { + } + static _createInputElement() { + Laya.Input['_initInput'](Laya.Input['area'] = Laya.Browser.createElement("textarea")); + Laya.Input['_initInput'](Laya.Input['input'] = Laya.Browser.createElement("input")); + Laya.Input['inputContainer'] = Laya.Browser.createElement("div"); + Laya.Input['inputContainer'].style.position = "absolute"; + Laya.Input['inputContainer'].style.zIndex = 1E5; + Laya.Browser.container.appendChild(Laya.Input['inputContainer']); + Laya.Laya.stage.on("resize", null, MiniInput._onStageResize); + HWMiniAdapter.window.hbs.onWindowResize && HWMiniAdapter.window.hbs.onWindowResize(function (res) { + }); + Laya.SoundManager._soundClass = MiniSound; + Laya.SoundManager._musicClass = MiniSound; + var model = HWMiniAdapter.systemInfo.model; + var system = HWMiniAdapter.systemInfo.system; + if (model.indexOf("iPhone") != -1) { + Laya.Browser.onIPhone = true; + Laya.Browser.onIOS = true; + Laya.Browser.onIPad = true; + Laya.Browser.onAndroid = false; + } + if (system.indexOf("Android") != -1 || system.indexOf("Adr") != -1) { + Laya.Browser.onAndroid = true; + Laya.Browser.onIPhone = false; + Laya.Browser.onIOS = false; + Laya.Browser.onIPad = false; + } + } + static _onStageResize() { + var ts = Laya.Laya.stage._canvasTransform.identity(); + ts.scale((Laya.Browser.width / Laya.Render.canvas.width / Laya.Browser.pixelRatio), Laya.Browser.height / Laya.Render.canvas.height / Laya.Browser.pixelRatio); + } + static inputFocus(e) { + var _inputTarget = Laya.Input['inputElement'].target; + if (_inputTarget && !_inputTarget.editable) { + return; + } + HWMiniAdapter.window.hbs.offKeyboardConfirm(); + HWMiniAdapter.window.hbs.offKeyboardInput(); + HWMiniAdapter.window.hbs.showKeyboard({ defaultValue: _inputTarget.text, maxLength: _inputTarget.maxChars, multiple: _inputTarget.multiline, confirmHold: true, confirmType: _inputTarget["confirmType"] || 'done', success: function (res) { + }, fail: function (res) { + } }); + HWMiniAdapter.window.hbs.onKeyboardConfirm(function (res) { + var str = res ? res.value : ""; + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + MiniInput.inputEnter(); + _inputTarget.event("confirm"); + }); + HWMiniAdapter.window.hbs.onKeyboardInput(function (res) { + var str = res ? res.value : ""; + if (!_inputTarget.multiline) { + if (str.indexOf("\n") != -1) { + MiniInput.inputEnter(); + return; + } + } + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + }); + } + static inputEnter() { + Laya.Input['inputElement'].target.focus = false; + } + static inputblur() { + MiniInput.hideKeyboard(); + } + static hideKeyboard() { + HWMiniAdapter.window.hbs.offKeyboardConfirm(); + HWMiniAdapter.window.hbs.offKeyboardInput(); + HWMiniAdapter.window.hbs.hideKeyboard({ success: function (res) { + console.log('隐藏键盘'); + }, fail: function (res) { + console.log("隐藏键盘出错:" + (res ? res.errMsg : "")); + } }); + } + } + + class MiniLoader extends Laya.EventDispatcher { + constructor() { + super(); + } + _loadResourceFilter(type, url) { + var thisLoader = this; + this.sourceUrl = Laya.URL.formatURL(url); + if (MiniFileMgr.isNetFile(url)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (HWMiniAdapter.subNativeFiles && HWMiniAdapter.subNativeheads.length == 0) { + for (var key in HWMiniAdapter.subNativeFiles) { + var tempArr = HWMiniAdapter.subNativeFiles[key]; + HWMiniAdapter.subNativeheads = HWMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + HWMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (HWMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && HWMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = HWMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + switch (type) { + case Laya.Loader.IMAGE: + case "htmlimage": + case "nativeimage": + MiniLoader._transformImgUrl(url, type, thisLoader); + break; + case Laya.Loader.SOUND: + thisLoader._loadSound(url); + break; + default: + thisLoader._loadResource(type, url); + } + } + _loadSound(url) { + var thisLoader = this; + if (!HWMiniAdapter.autoCacheFile) { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + else { + var tempurl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downOtherFiles(HWMiniAdapter.safeEncodeURI(tempurl), Laya.Handler.create(MiniLoader, MiniLoader.onDownLoadCallBack, [tempurl, thisLoader]), tempurl); + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + } + static onDownLoadCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = null) { + if (!errorCode) { + var fileNativeUrl; + if (HWMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + fileNativeUrl = sourceUrl; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + } + sourceUrl = fileNativeUrl; + var sound = (new Laya.SoundManager._soundClass()); + sound.load(HWMiniAdapter.safeEncodeURI(sourceUrl)); + thisLoader.onLoaded(sound); + } + else { + thisLoader.event(Laya.Event.ERROR, "Load sound failed"); + } + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + complete(data) { + if (data instanceof Laya.Resource) { + data._setCreateURL(this.sourceUrl); + } + else if ((data instanceof Laya.Texture) && (data.bitmap instanceof Laya.Resource)) { + data.bitmap._setCreateURL(this.sourceUrl); + } + this.originComplete(data); + } + _loadHttpRequestWhat(url, contentType) { + var thisLoader = this; + var encoding = HWMiniAdapter.getUrlEncode(url, contentType); + if (Laya.Loader.preLoadedMap[url]) + thisLoader.onLoaded(Laya.Loader.preLoadedMap[url]); + else { + var tempurl = Laya.URL.formatURL(url); + if (!HWMiniAdapter.AutoCacheDownFile) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downFiles(HWMiniAdapter.safeEncodeURI(tempurl), encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), tempurl, true); + } + else + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + else { + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downFiles(HWMiniAdapter.safeEncodeURI(tempurl), encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), tempurl, true); + } + else { + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + else { + var tempUrl = url; + var fileObj = MiniFileMgr.getFileInfo(tempurl); + if (fileObj && fileObj.md5) { + tempUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + MiniFileMgr.readFile(tempUrl, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + } + } + static onReadNativeCallBack(url, type = null, thisLoader = null, errorCode = 0, data = null) { + if (!errorCode) { + var tempData; + if (type == Laya.Loader.JSON || type == Laya.Loader.ATLAS || type == Laya.Loader.PREFAB || type == Laya.Loader.PLF) { + tempData = HWMiniAdapter.getJson(data.data); + } + else if (type == Laya.Loader.XML) { + tempData = Laya.Utils.parseXMLFromString(data.data); + } + else { + tempData = data.data; + } + thisLoader.onLoaded(tempData); + } + else if (errorCode == 1) { + thisLoader._loadHttpRequest(url, type, thisLoader, thisLoader.onLoaded, thisLoader, thisLoader.onProgress, thisLoader, thisLoader.onError); + } + } + static _transformImgUrl(url, type, thisLoader) { + if (MiniFileMgr.isLocalNativeFile(url)) { + thisLoader._loadImage(url, false); + return; + } + if (!HWMiniAdapter.autoCacheFile) { + thisLoader._loadImage(HWMiniAdapter.safeEncodeURI(url)); + return; + } + if (!HWMiniAdapter.autoCacheFile) { + thisLoader._loadImage(HWMiniAdapter.safeEncodeURI(url)); + } + else { + var tempUrl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempUrl)) { + if (MiniFileMgr.isNetFile(tempUrl)) { + MiniFileMgr.downOtherFiles(HWMiniAdapter.safeEncodeURI(tempUrl), new Laya.Handler(MiniLoader, MiniLoader.onDownImgCallBack, [url, thisLoader]), tempUrl); + } + else { + MiniLoader.onCreateImage(url, thisLoader, true); + } + } + else { + MiniLoader.onCreateImage(url, thisLoader); + } + } + } + static onDownImgCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = "") { + if (!errorCode) + MiniLoader.onCreateImage(sourceUrl, thisLoader, false, tempFilePath); + else { + thisLoader.onError(null); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (HWMiniAdapter.autoCacheFile) { + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + var fileObj = MiniFileMgr.getFileInfo(Laya.URL.formatURL(sourceUrl)); + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + } + else + fileNativeUrl = sourceUrl; + } + else { + if (!isLocal) + fileNativeUrl = tempFilePath; + else + fileNativeUrl = sourceUrl; + } + thisLoader._loadImage(fileNativeUrl, false); + } + } + + function ImageDataPolyfill() { + let width, height, data; + if (arguments.length == 3) { + if (arguments[0] instanceof Uint8ClampedArray) { + if (arguments[0].length % 4 !== 0) { + throw new Error("Failed to construct 'ImageData': The input data length is not a multiple of 4."); + } + if (arguments[0].length !== arguments[1] * arguments[2] * 4) { + throw new Error("Failed to construct 'ImageData': The input data length is not equal to (4 * width * height)."); + } + else { + data = arguments[0]; + width = arguments[1]; + height = arguments[2]; + } + } + else { + throw new Error("Failed to construct 'ImageData': parameter 1 is not of type 'Uint8ClampedArray'."); + } + } + else if (arguments.length == 2) { + width = arguments[0]; + height = arguments[1]; + data = new Uint8ClampedArray(arguments[0] * arguments[1] * 4); + } + else if (arguments.length < 2) { + throw new Error("Failed to construct 'ImageData': 2 arguments required, but only " + arguments.length + " present."); + } + let imgdata = Laya.Browser.canvas.getContext("2d").getImageData(0, 0, width, height); + for (let i = 0; i < data.length; i += 4) { + imgdata.data[i] = data[i]; + imgdata.data[i + 1] = data[i + 1]; + imgdata.data[i + 2] = data[i + 2]; + imgdata.data[i + 3] = data[i + 3]; + } + return imgdata; + } + + class HWMiniAdapter { + static getJson(data) { + return JSON.parse(data); + } + static enable() { + HWMiniAdapter.init(); + } + static init() { + if (HWMiniAdapter._inited) + return; + HWMiniAdapter._inited = true; + HWMiniAdapter.window = window; + if (!HWMiniAdapter.window.hasOwnProperty("hbs")) + return; + HWMiniAdapter.EnvConfig = {}; + MiniFileMgr.setNativeFileDir("/layaairGame"); + MiniFileMgr.getCacheList(MiniFileMgr.fileNativeDir, Laya.Handler.create(HWMiniAdapter, HWMiniAdapter.onMkdirCallBack)); + HWMiniAdapter.systemInfo = HWMiniAdapter.window.hbs.getSystemInfoSync(); + HWMiniAdapter.window.focus = function () { + }; + Laya.Laya['_getUrlPath'] = function () { + return ""; + }; + HWMiniAdapter.window.logtime = function (str) { + }; + HWMiniAdapter.window.alertTimeLog = function (str) { + }; + HWMiniAdapter.window.resetShareInfo = function () { + }; + Laya.HttpRequest._urlEncode = HWMiniAdapter.safeEncodeURI; + HWMiniAdapter._preCreateElement = Laya.Browser.createElement; + Laya.Browser.createElement = HWMiniAdapter.createElement; + Laya.RunDriver.createShaderCondition = HWMiniAdapter.createShaderCondition; + Laya.Input['_createInputElement'] = MiniInput['_createInputElement']; + if (!window.ImageData) { + window.ImageData = ImageDataPolyfill; + } + Laya.Loader.prototype._loadResourceFilter = MiniLoader.prototype._loadResourceFilter; + Laya.Loader.prototype._loadSound = MiniLoader.prototype._loadSound; + Laya.Loader.prototype.originComplete = Laya.Loader.prototype.complete; + Laya.Loader.prototype.complete = MiniLoader.prototype.complete; + Laya.Loader.prototype._loadHttpRequestWhat = MiniLoader.prototype._loadHttpRequestWhat; + Laya.Config.useRetinalCanvas = true; + } + static getUrlEncode(url, type) { + if (type == "arraybuffer") + return "binary"; + return "utf8"; + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + var fileObj = MiniFileMgr.getFileInfo(fileUrl); + if (!fileObj) + MiniFileMgr.downLoadFile(HWMiniAdapter.safeEncodeURI(fileUrl), fileType, callBack, encoding); + else { + callBack != null && callBack.runWith([0]); + } + } + static remove(fileUrl, callBack = null) { + MiniFileMgr.deleteFile("", fileUrl, callBack, "", 0); + } + static removeAll() { + MiniFileMgr.deleteAll(); + } + static hasNativeFile(fileUrl) { + return MiniFileMgr.isLocalNativeFile(fileUrl); + } + static getFileInfo(fileUrl) { + return MiniFileMgr.getFileInfo(fileUrl); + } + static getFileList() { + return MiniFileMgr.filesListObj; + } + static exitMiniProgram() { + HWMiniAdapter.window["hbs"].exitMiniProgram(); + } + static onMkdirCallBack(errorCode, data) { + if (!errorCode) { + MiniFileMgr.filesListObj = JSON.parse(data.data) || {}; + MiniFileMgr.fakeObj = JSON.parse(data.data) || {}; + } + else { + MiniFileMgr.fakeObj = {}; + MiniFileMgr.filesListObj = {}; + } + let files = MiniFileMgr.fs.readdirSync(MiniFileMgr.fileNativeDir); + if (!files || !files.length) + return; + var tempMd5ListObj = {}; + var fileObj; + for (let key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") { + fileObj = MiniFileMgr.filesListObj[key]; + tempMd5ListObj[fileObj.md5] = fileObj.readyUrl; + } + } + var fileName; + for (let i = 0, sz = files.length; i < sz; i++) { + fileName = files[i]; + if (fileName == MiniFileMgr.fileListName) + continue; + if (!tempMd5ListObj[fileName]) { + let deleteFileUrl = MiniFileMgr.getFileNativePath(fileName); + MiniFileMgr.fs.unlink({ + filePath: deleteFileUrl, + success: function (data) { + console.log("删除无引用的磁盘文件:" + fileName); + } + }); + } + delete tempMd5ListObj[fileName]; + } + for (let key in tempMd5ListObj) { + delete MiniFileMgr.filesListObj[tempMd5ListObj[key]]; + delete MiniFileMgr.fakeObj[tempMd5ListObj[key]]; + console.log("删除错误记录:", tempMd5ListObj[key]); + } + } + static pixelRatio() { + if (!HWMiniAdapter.EnvConfig.pixelRatioInt) { + try { + HWMiniAdapter.EnvConfig.pixelRatioInt = HWMiniAdapter.systemInfo.pixelRatio; + return HWMiniAdapter.systemInfo.pixelRatio; + } + catch (error) { + } + } + return HWMiniAdapter.EnvConfig.pixelRatioInt; + } + static createElement(type) { + if (type == "textarea" || type == "input") { + return HWMiniAdapter.onCreateInput(type); + } + else if (type == "div") { + var node = HWMiniAdapter._preCreateElement(type); + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + else { + return HWMiniAdapter._preCreateElement(type); + } + } + static onCreateInput(type) { + var node = HWMiniAdapter._preCreateElement(type); + node.focus = MiniInput.inputFocus; + node.blur = MiniInput.inputblur; + node.style = {}; + node.value = 0; + node.parentElement = {}; + node.placeholder = {}; + node.type = {}; + node.setColor = function (value) { + }; + node.setType = function (value) { + }; + node.setFontFace = function (value) { + }; + node.addEventListener = function (value) { + }; + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + static createShaderCondition(conditionScript) { + var func = function () { + return this[conditionScript.replace("this.", "")]; + }; + return func; + } + } + HWMiniAdapter.IGNORE = new RegExp("[-_.!~*'();/?:@&=+$,#%]|[0-9|A-Z|a-z]"); + HWMiniAdapter.safeEncodeURI = function (str) { + var strTemp = ""; + var length = str.length; + for (var i = 0; i < length; i++) { + var word = str[i]; + if (HWMiniAdapter.IGNORE.test(word)) { + strTemp += word; + } + else { + try { + strTemp += encodeURI(word); + } + catch (e) { + console.log("errorInfo", ">>>" + word); + } + } + } + return strTemp; + }; + HWMiniAdapter._inited = false; + HWMiniAdapter.autoCacheFile = true; + HWMiniAdapter.minClearSize = (5 * 1024 * 1024); + HWMiniAdapter.sizeLimit = (50 * 1024 * 1024); + HWMiniAdapter.nativefiles = ["layaNativeDir", "wxlocal"]; + HWMiniAdapter.subNativeFiles = []; + HWMiniAdapter.subNativeheads = []; + HWMiniAdapter.subMaps = []; + HWMiniAdapter.AutoCacheDownFile = false; + + class MiniAccelerator extends Laya.EventDispatcher { + constructor() { + super(); + } + static __init__() { + try { + var Acc; + Acc = Laya.Accelerator; + if (!Acc) + return; + Acc["prototype"]["on"] = MiniAccelerator["prototype"]["on"]; + Acc["prototype"]["off"] = MiniAccelerator["prototype"]["off"]; + } + catch (e) { + } + } + static startListen(callBack) { + MiniAccelerator._callBack = callBack; + if (MiniAccelerator._isListening) + return; + MiniAccelerator._isListening = true; + try { + HWMiniAdapter.window.hbs.onAccelerometerChange(MiniAccelerator.onAccelerometerChange); + } + catch (e) { } + } + static stopListen() { + MiniAccelerator._isListening = false; + try { + HWMiniAdapter.window.hbs.stopAccelerometer({}); + } + catch (e) { } + } + static onAccelerometerChange(res) { + var e; + e = {}; + e.acceleration = res; + e.accelerationIncludingGravity = res; + e.rotationRate = {}; + if (MiniAccelerator._callBack != null) { + MiniAccelerator._callBack(e); + } + } + on(type, caller, listener, args = null) { + super.on(type, caller, listener, args); + MiniAccelerator.startListen(this["onDeviceOrientationChange"]); + return this; + } + off(type, caller, listener, onceOnly = false) { + if (!this.hasListener(type)) + MiniAccelerator.stopListen(); + return super.off(type, caller, listener, onceOnly); + } + } + MiniAccelerator._isListening = false; + + class MiniLocation { + constructor() { + } + static __init__() { + HWMiniAdapter.window.navigator.geolocation.getCurrentPosition = MiniLocation.getCurrentPosition; + HWMiniAdapter.window.navigator.geolocation.watchPosition = MiniLocation.watchPosition; + HWMiniAdapter.window.navigator.geolocation.clearWatch = MiniLocation.clearWatch; + } + static getCurrentPosition(success = null, error = null, options = null) { + var paramO; + paramO = {}; + paramO.success = getSuccess; + paramO.fail = error; + HWMiniAdapter.window.hbs.getLocation(paramO); + function getSuccess(res) { + if (success != null) { + success(res); + } + } + } + static watchPosition(success = null, error = null, options = null) { + MiniLocation._curID++; + var curWatchO; + curWatchO = {}; + curWatchO.success = success; + curWatchO.error = error; + MiniLocation._watchDic[MiniLocation._curID] = curWatchO; + Laya.Laya.systemTimer.loop(1000, null, MiniLocation._myLoop); + return MiniLocation._curID; + } + static clearWatch(id) { + delete MiniLocation._watchDic[id]; + if (!MiniLocation._hasWatch()) { + Laya.Laya.systemTimer.clear(null, MiniLocation._myLoop); + } + } + static _hasWatch() { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key]) + return true; + } + return false; + } + static _myLoop() { + MiniLocation.getCurrentPosition(MiniLocation._mySuccess, MiniLocation._myError); + } + static _mySuccess(res) { + var rst = {}; + rst.coords = res; + rst.timestamp = Laya.Browser.now(); + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].success) { + MiniLocation._watchDic[key].success(rst); + } + } + } + static _myError(res) { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].error) { + MiniLocation._watchDic[key].error(res); + } + } + } + } + MiniLocation._watchDic = {}; + MiniLocation._curID = 0; + + class MiniVideo { + constructor(width = 320, height = 240) { + this.videoend = false; + this.videourl = ""; + this.videoElement = HWMiniAdapter.window.hbs.createVideo({ width: width, height: height, autoplay: true }); + } + static __init__() { + } + on(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.onPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.onEnded = this.onEndedFunction.bind(this); + } + this.videoElement.onTimeUpdate = this.onTimeUpdateFunc.bind(this); + } + onTimeUpdateFunc(data) { + this.position = data.position; + this._duration = data.duration; + } + get duration() { + return this._duration; + } + onPlayFunction() { + if (this.videoElement) + this.videoElement.readyState = 200; + console.log("=====视频加载完成========"); + this.onPlayFunc != null && this.onPlayFunc(); + } + onEndedFunction() { + if (!this.videoElement) + return; + this.videoend = true; + console.log("=====视频播放完毕========"); + this.onEndedFunC != null && this.onEndedFunC(); + } + off(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.offPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.offEnded = this.onEndedFunction.bind(this); + } + } + load(url) { + if (!this.videoElement) + return; + this.videoElement.src = url; + } + play() { + if (!this.videoElement) + return; + this.videoend = false; + this.videoElement.play(); + } + pause() { + if (!this.videoElement) + return; + this.videoend = true; + this.videoElement.pause(); + } + get currentTime() { + if (!this.videoElement) + return 0; + return this.videoElement.initialTime; + } + set currentTime(value) { + if (!this.videoElement) + return; + this.videoElement.initialTime = value; + } + get videoWidth() { + if (!this.videoElement) + return 0; + return this.videoElement.width; + } + get videoHeight() { + if (!this.videoElement) + return 0; + return this.videoElement.height; + } + get ended() { + return this.videoend; + } + get loop() { + if (!this.videoElement) + return false; + return this.videoElement.loop; + } + set loop(value) { + if (!this.videoElement) + return; + this.videoElement.loop = value; + } + get playbackRate() { + if (!this.videoElement) + return 0; + return this.videoElement.playbackRate; + } + set playbackRate(value) { + if (!this.videoElement) + return; + this.videoElement.playbackRate = value; + } + get muted() { + if (!this.videoElement) + return false; + return this.videoElement.muted; + } + set muted(value) { + if (!this.videoElement) + return; + this.videoElement.muted = value; + } + get paused() { + if (!this.videoElement) + return false; + return this.videoElement.paused; + } + size(width, height) { + if (!this.videoElement) + return; + this.videoElement.width = width; + this.videoElement.height = height; + } + get x() { + if (!this.videoElement) + return 0; + return this.videoElement.x; + } + set x(value) { + if (!this.videoElement) + return; + this.videoElement.x = value; + } + get y() { + if (!this.videoElement) + return 0; + return this.videoElement.y; + } + set y(value) { + if (!this.videoElement) + return; + this.videoElement.y = value; + } + get currentSrc() { + return this.videoElement.src; + } + destroy() { + if (this.videoElement) + this.videoElement.destroy(); + this.videoElement = null; + this.onEndedFunC = null; + this.onPlayFunc = null; + this.videoend = false; + this.videourl = null; + } + reload() { + if (!this.videoElement) + return; + this.videoElement.src = this.videourl; + } + } + + exports.HWMiniAdapter = HWMiniAdapter; + exports.ImageDataPolyfill = ImageDataPolyfill; + exports.MiniAccelerator = MiniAccelerator; + exports.MiniFileMgr = MiniFileMgr; + exports.MiniInput = MiniInput; + exports.MiniLoader = MiniLoader; + exports.MiniLocation = MiniLocation; + exports.MiniSound = MiniSound; + exports.MiniSoundChannel = MiniSoundChannel; + exports.MiniVideo = MiniVideo; + +} diff --git a/examples/layaair/frontend/bin/libs/laya.particle.js b/examples/layaair/frontend/bin/libs/laya.particle.js new file mode 100644 index 0000000..558ecbc --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.particle.js @@ -0,0 +1,635 @@ +(function (exports, Laya) { + 'use strict'; + + class ParticleSetting { + constructor() { + this.textureName = null; + this.textureCount = 1; + this.maxPartices = 100; + this.duration = 1; + this.ageAddScale = 0; + this.emitterVelocitySensitivity = 1; + this.minStartSize = 100; + this.maxStartSize = 100; + this.minEndSize = 100; + this.maxEndSize = 100; + this.minHorizontalVelocity = 0; + this.maxHorizontalVelocity = 0; + this.minVerticalVelocity = 0; + this.maxVerticalVelocity = 0; + this.endVelocity = 1; + this.gravity = new Float32Array([0, 0, 0]); + this.minRotateSpeed = 0; + this.maxRotateSpeed = 0; + this.minStartRadius = 0; + this.maxStartRadius = 0; + this.minEndRadius = 0; + this.maxEndRadius = 0; + this.minHorizontalStartRadian = 0; + this.maxHorizontalStartRadian = 0; + this.minVerticalStartRadian = 0; + this.maxVerticalStartRadian = 0; + this.useEndRadian = true; + this.minHorizontalEndRadian = 0; + this.maxHorizontalEndRadian = 0; + this.minVerticalEndRadian = 0; + this.maxVerticalEndRadian = 0; + this.minStartColor = new Float32Array([1, 1, 1, 1]); + this.maxStartColor = new Float32Array([1, 1, 1, 1]); + this.minEndColor = new Float32Array([1, 1, 1, 1]); + this.maxEndColor = new Float32Array([1, 1, 1, 1]); + this.colorComponentInter = false; + this.disableColor = false; + this.blendState = 0; + this.emitterType = "null"; + this.emissionRate = 0; + this.pointEmitterPosition = new Float32Array([0, 0, 0]); + this.pointEmitterPositionVariance = new Float32Array([0, 0, 0]); + this.pointEmitterVelocity = new Float32Array([0, 0, 0]); + this.pointEmitterVelocityAddVariance = new Float32Array([0, 0, 0]); + this.boxEmitterCenterPosition = new Float32Array([0, 0, 0]); + this.boxEmitterSize = new Float32Array([0, 0, 0]); + this.boxEmitterVelocity = new Float32Array([0, 0, 0]); + this.boxEmitterVelocityAddVariance = new Float32Array([0, 0, 0]); + this.sphereEmitterCenterPosition = new Float32Array([0, 0, 0]); + this.sphereEmitterRadius = 1; + this.sphereEmitterVelocity = 0; + this.sphereEmitterVelocityAddVariance = 0; + this.ringEmitterCenterPosition = new Float32Array([0, 0, 0]); + this.ringEmitterRadius = 30; + this.ringEmitterVelocity = 0; + this.ringEmitterVelocityAddVariance = 0; + this.ringEmitterUp = 2; + this.positionVariance = new Float32Array([0, 0, 0]); + } + static checkSetting(setting) { + var key; + for (key in ParticleSetting._defaultSetting) { + if (!(key in setting)) { + setting[key] = ParticleSetting._defaultSetting[key]; + } + } + setting.endVelocity = +setting.endVelocity; + setting.gravity[0] = +setting.gravity[0]; + setting.gravity[1] = +setting.gravity[1]; + setting.gravity[2] = +setting.gravity[2]; + } + } + ParticleSetting._defaultSetting = new ParticleSetting(); + + class ParticleTemplateBase { + constructor() { + } + addParticleArray(position, velocity) { + } + } + + class ParticleData { + constructor() { + } + static Create(settings, position, velocity, time) { + var particleData = new ParticleData(); + particleData.position = position; + Laya.MathUtil.scaleVector3(velocity, settings.emitterVelocitySensitivity, ParticleData._tempVelocity); + var horizontalVelocity = Laya.MathUtil.lerp(settings.minHorizontalVelocity, settings.maxHorizontalVelocity, Math.random()); + var horizontalAngle = Math.random() * Math.PI * 2; + ParticleData._tempVelocity[0] += horizontalVelocity * Math.cos(horizontalAngle); + ParticleData._tempVelocity[2] += horizontalVelocity * Math.sin(horizontalAngle); + ParticleData._tempVelocity[1] += Laya.MathUtil.lerp(settings.minVerticalVelocity, settings.maxVerticalVelocity, Math.random()); + particleData.velocity = ParticleData._tempVelocity; + particleData.startColor = ParticleData._tempStartColor; + particleData.endColor = ParticleData._tempEndColor; + var i; + if (settings.disableColor) { + for (i = 0; i < 3; i++) { + particleData.startColor[i] = 1; + particleData.endColor[i] = 1; + } + particleData.startColor[i] = Laya.MathUtil.lerp(settings.minStartColor[i], settings.maxStartColor[i], Math.random()); + particleData.endColor[i] = Laya.MathUtil.lerp(settings.minEndColor[i], settings.maxEndColor[i], Math.random()); + } + else { + if (settings.colorComponentInter) { + for (i = 0; i < 4; i++) { + particleData.startColor[i] = Laya.MathUtil.lerp(settings.minStartColor[i], settings.maxStartColor[i], Math.random()); + particleData.endColor[i] = Laya.MathUtil.lerp(settings.minEndColor[i], settings.maxEndColor[i], Math.random()); + } + } + else { + Laya.MathUtil.lerpVector4(settings.minStartColor, settings.maxStartColor, Math.random(), particleData.startColor); + Laya.MathUtil.lerpVector4(settings.minEndColor, settings.maxEndColor, Math.random(), particleData.endColor); + } + } + particleData.sizeRotation = ParticleData._tempSizeRotation; + var sizeRandom = Math.random(); + particleData.sizeRotation[0] = Laya.MathUtil.lerp(settings.minStartSize, settings.maxStartSize, sizeRandom); + particleData.sizeRotation[1] = Laya.MathUtil.lerp(settings.minEndSize, settings.maxEndSize, sizeRandom); + particleData.sizeRotation[2] = Laya.MathUtil.lerp(settings.minRotateSpeed, settings.maxRotateSpeed, Math.random()); + particleData.radius = ParticleData._tempRadius; + var radiusRandom = Math.random(); + particleData.radius[0] = Laya.MathUtil.lerp(settings.minStartRadius, settings.maxStartRadius, radiusRandom); + particleData.radius[1] = Laya.MathUtil.lerp(settings.minEndRadius, settings.maxEndRadius, radiusRandom); + particleData.radian = ParticleData._tempRadian; + particleData.radian[0] = Laya.MathUtil.lerp(settings.minHorizontalStartRadian, settings.maxHorizontalStartRadian, Math.random()); + particleData.radian[1] = Laya.MathUtil.lerp(settings.minVerticalStartRadian, settings.maxVerticalStartRadian, Math.random()); + var useEndRadian = settings.useEndRadian; + particleData.radian[2] = useEndRadian ? Laya.MathUtil.lerp(settings.minHorizontalEndRadian, settings.maxHorizontalEndRadian, Math.random()) : particleData.radian[0]; + particleData.radian[3] = useEndRadian ? Laya.MathUtil.lerp(settings.minVerticalEndRadian, settings.maxVerticalEndRadian, Math.random()) : particleData.radian[1]; + particleData.durationAddScale = settings.ageAddScale * Math.random(); + particleData.time = time; + return particleData; + } + } + ParticleData._tempVelocity = new Float32Array(3); + ParticleData._tempStartColor = new Float32Array(4); + ParticleData._tempEndColor = new Float32Array(4); + ParticleData._tempSizeRotation = new Float32Array(3); + ParticleData._tempRadius = new Float32Array(2); + ParticleData._tempRadian = new Float32Array(4); + + class ParticleTemplateWebGL extends ParticleTemplateBase { + constructor(parSetting) { + super(); + this._floatCountPerVertex = 29; + this._firstActiveElement = 0; + this._firstNewElement = 0; + this._firstFreeElement = 0; + this._firstRetiredElement = 0; + this._currentTime = 0; + this.settings = parSetting; + } + reUse(context, pos) { + return 0; + } + initialize() { + var floatStride = 0; + this._vertices = this._mesh._vb.getFloat32Array(); + floatStride = this._mesh._stride / 4; + var bufi = 0; + var bufStart = 0; + for (var i = 0; i < this.settings.maxPartices; i++) { + var random = Math.random(); + var cornerYSegement = this.settings.textureCount ? 1.0 / this.settings.textureCount : 1.0; + var cornerY; + for (cornerY = 0; cornerY < this.settings.textureCount; cornerY += cornerYSegement) { + if (random < cornerY + cornerYSegement) + break; + } + this._vertices[bufi++] = -1; + this._vertices[bufi++] = -1; + this._vertices[bufi++] = 0; + this._vertices[bufi++] = cornerY; + bufi = (bufStart += floatStride); + this._vertices[bufi++] = 1; + this._vertices[bufi++] = -1; + this._vertices[bufi++] = 1; + this._vertices[bufi++] = cornerY; + bufi = bufStart += floatStride; + this._vertices[bufi++] = 1; + this._vertices[bufi++] = 1; + this._vertices[bufi++] = 1; + this._vertices[bufi++] = cornerY + cornerYSegement; + bufi = bufStart += floatStride; + this._vertices[bufi++] = -1; + this._vertices[bufi++] = 1; + this._vertices[bufi++] = 0; + this._vertices[bufi++] = cornerY + cornerYSegement; + bufi = bufStart += floatStride; + } + } + update(elapsedTime) { + this._currentTime += elapsedTime / 1000; + this.retireActiveParticles(); + this.freeRetiredParticles(); + if (this._firstActiveElement == this._firstFreeElement) + this._currentTime = 0; + if (this._firstRetiredElement == this._firstActiveElement) + this._drawCounter = 0; + } + retireActiveParticles() { + const epsilon = 0.0001; + var particleDuration = this.settings.duration; + while (this._firstActiveElement != this._firstNewElement) { + var offset = this._firstActiveElement * this._floatCountPerVertex * 4; + var index = offset + 28; + var particleAge = this._currentTime - this._vertices[index]; + particleAge *= (1.0 + this._vertices[offset + 27]); + if (particleAge + epsilon < particleDuration) + break; + this._vertices[index] = this._drawCounter; + this._firstActiveElement++; + if (this._firstActiveElement >= this.settings.maxPartices) + this._firstActiveElement = 0; + } + } + freeRetiredParticles() { + while (this._firstRetiredElement != this._firstActiveElement) { + var age = this._drawCounter - this._vertices[this._firstRetiredElement * this._floatCountPerVertex * 4 + 28]; + if (age < 3) + break; + this._firstRetiredElement++; + if (this._firstRetiredElement >= this.settings.maxPartices) + this._firstRetiredElement = 0; + } + } + addNewParticlesToVertexBuffer() { + } + addParticleArray(position, velocity) { + var nextFreeParticle = this._firstFreeElement + 1; + if (nextFreeParticle >= this.settings.maxPartices) + nextFreeParticle = 0; + if (nextFreeParticle === this._firstRetiredElement) + return; + var particleData = ParticleData.Create(this.settings, position, velocity, this._currentTime); + var startIndex = this._firstFreeElement * this._floatCountPerVertex * 4; + for (var i = 0; i < 4; i++) { + var j, offset; + for (j = 0, offset = 4; j < 3; j++) + this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.position[j]; + for (j = 0, offset = 7; j < 3; j++) + this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.velocity[j]; + for (j = 0, offset = 10; j < 4; j++) + this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.startColor[j]; + for (j = 0, offset = 14; j < 4; j++) + this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.endColor[j]; + for (j = 0, offset = 18; j < 3; j++) + this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.sizeRotation[j]; + for (j = 0, offset = 21; j < 2; j++) + this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.radius[j]; + for (j = 0, offset = 23; j < 4; j++) + this._vertices[startIndex + i * this._floatCountPerVertex + offset + j] = particleData.radian[j]; + this._vertices[startIndex + i * this._floatCountPerVertex + 27] = particleData.durationAddScale; + this._vertices[startIndex + i * this._floatCountPerVertex + 28] = particleData.time; + } + this._firstFreeElement = nextFreeParticle; + } + } + + var parvs = "attribute vec4 a_CornerTextureCoordinate;\r\nattribute vec3 a_Position;\r\nattribute vec3 a_Velocity;\r\nattribute vec4 a_StartColor;\r\nattribute vec4 a_EndColor;\r\nattribute vec3 a_SizeRotation;\r\nattribute vec2 a_Radius;\r\nattribute vec4 a_Radian;\r\nattribute float a_AgeAddScale;\r\nattribute float a_Time;\r\n\r\nvarying vec4 v_Color;\r\nvarying vec2 v_TextureCoordinate;\r\n\r\nuniform float u_CurrentTime;\r\nuniform float u_Duration;\r\nuniform float u_EndVelocity;\r\nuniform vec3 u_Gravity;\r\n\r\nuniform vec2 size;\r\nuniform mat4 u_mmat;\r\n\r\nvec4 ComputeParticlePosition(in vec3 position, in vec3 velocity,in float age,in float normalizedAge)\r\n{\r\n\r\n float startVelocity = length(velocity);//起始标量速度\r\n float endVelocity = startVelocity * u_EndVelocity;//结束标量速度\r\n\r\n float velocityIntegral = startVelocity * normalizedAge +(endVelocity - startVelocity) * normalizedAge *normalizedAge/2.0;//计算当前速度的标量(单位空间),vt=v0*t+(1/2)*a*(t^2)\r\n \r\n vec3 addPosition = normalize(velocity) * velocityIntegral * u_Duration;//计算受自身速度影响的位置,转换标量到矢量 \r\n addPosition += u_Gravity * age * normalizedAge;//计算受重力影响的位置\r\n \r\n float radius=mix(a_Radius.x, a_Radius.y, normalizedAge); //计算粒子受半径和角度影响(无需计算角度和半径时,可用宏定义优化屏蔽此计算)\r\n float radianHorizontal =mix(a_Radian.x,a_Radian.z,normalizedAge);\r\n float radianVertical =mix(a_Radian.y,a_Radian.w,normalizedAge);\r\n \r\n float r =cos(radianVertical)* radius;\r\n addPosition.y += sin(radianVertical) * radius;\r\n\t\r\n addPosition.x += cos(radianHorizontal) *r;\r\n addPosition.z += sin(radianHorizontal) *r;\r\n \r\n addPosition.y=-addPosition.y;//2D粒子位置更新需要取负,2D粒子坐标系Y轴正向朝上\r\n position+=addPosition;\r\n return vec4(position,1.0);\r\n}\r\n\r\nfloat ComputeParticleSize(in float startSize,in float endSize, in float normalizedAge)\r\n{ \r\n float size = mix(startSize, endSize, normalizedAge);\r\n return size;\r\n}\r\n\r\nmat2 ComputeParticleRotation(in float rot,in float age)\r\n{ \r\n float rotation =rot * age;\r\n //计算2x2旋转矩阵.\r\n float c = cos(rotation);\r\n float s = sin(rotation);\r\n return mat2(c, -s, s, c);\r\n}\r\n\r\nvec4 ComputeParticleColor(in vec4 startColor,in vec4 endColor,in float normalizedAge)\r\n{\r\n\tvec4 color=mix(startColor,endColor,normalizedAge);\r\n //硬编码设置,使粒子淡入很快,淡出很慢,6.7的缩放因子把置归一在0到1之间,可以谷歌x*(1-x)*(1-x)*6.7的制图表\r\n color.a *= normalizedAge * (1.0-normalizedAge) * (1.0-normalizedAge) * 6.7;\r\n \r\n return color;\r\n}\r\n\r\nvoid main()\r\n{\r\n float age = u_CurrentTime - a_Time;\r\n age *= 1.0 + a_AgeAddScale;\r\n float normalizedAge = clamp(age / u_Duration,0.0,1.0);\r\n gl_Position = ComputeParticlePosition(a_Position, a_Velocity, age, normalizedAge);//计算粒子位置\r\n float pSize = ComputeParticleSize(a_SizeRotation.x,a_SizeRotation.y, normalizedAge);\r\n mat2 rotation = ComputeParticleRotation(a_SizeRotation.z, age);\r\n\t\r\n mat4 mat=u_mmat;\r\n gl_Position=vec4((mat*gl_Position).xy,0.0,1.0);\r\n gl_Position.xy += (rotation*a_CornerTextureCoordinate.xy) * pSize*vec2(mat[0][0],mat[1][1]);\r\n gl_Position=vec4((gl_Position.x/size.x-0.5)*2.0,(0.5-gl_Position.y/size.y)*2.0,0.0,1.0);\r\n \r\n v_Color = ComputeParticleColor(a_StartColor,a_EndColor, normalizedAge);\r\n v_TextureCoordinate =a_CornerTextureCoordinate.zw;\r\n}\r\n\r\n"; + + var parps = "#if defined(GL_FRAGMENT_PRECISION_HIGH)\r\nprecision highp float;\r\n#else\r\nprecision mediump float;\r\n#endif\r\n\r\nvarying vec4 v_Color;\r\nvarying vec2 v_TextureCoordinate;\r\nuniform sampler2D u_texture;\r\n\r\nvoid main()\r\n{\t\r\n\tgl_FragColor=texture2D(u_texture,v_TextureCoordinate)*v_Color;\r\n\tgl_FragColor.xyz *= v_Color.w;\r\n}"; + + class ParticleShader extends Laya.Shader { + constructor() { + super(parvs, parps, "ParticleShader", null, ['a_CornerTextureCoordinate', 0, 'a_Position', 1, 'a_Velocity', 2, 'a_StartColor', 3, + 'a_EndColor', 4, 'a_SizeRotation', 5, 'a_Radius', 6, 'a_Radian', 7, 'a_AgeAddScale', 8, 'a_Time', 9]); + } + } + ParticleShader.vs = parvs; + ParticleShader.ps = parps; + + class ParticleShaderValue extends Laya.Value2D { + constructor() { + super(0, 0); + if (!ParticleShaderValue.pShader) { + ParticleShaderValue.pShader = new ParticleShader(); + } + } + upload() { + var size = this.size; + size[0] = Laya.RenderState2D.width; + size[1] = Laya.RenderState2D.height; + this.alpha = this.ALPHA * Laya.RenderState2D.worldAlpha; + ParticleShaderValue.pShader.upload(this); + } + } + ParticleShaderValue.pShader = null; + + class ParticleTemplate2D extends ParticleTemplateWebGL { + constructor(parSetting) { + super(parSetting); + this.x = 0; + this.y = 0; + this.sv = new ParticleShaderValue(); + this._key = {}; + var _this = this; + Laya.ILaya.loader.load(this.settings.textureName, Laya.Handler.create(null, function (texture) { + _this.texture = texture; + }), null, Laya.Loader.IMAGE); + this.sv.u_Duration = this.settings.duration; + this.sv.u_Gravity = this.settings.gravity; + this.sv.u_EndVelocity = this.settings.endVelocity; + this._blendFn = Laya.BlendMode.fns[parSetting.blendState]; + this._mesh = Laya.MeshParticle2D.getAMesh(this.settings.maxPartices); + this.initialize(); + } + getRenderType() { return -111; } + releaseRender() { } + addParticleArray(position, velocity) { + position[0] += this.x; + position[1] += this.y; + super.addParticleArray(position, velocity); + } + addNewParticlesToVertexBuffer() { + var _vertexBuffer2D = this._mesh._vb; + _vertexBuffer2D.clear(); + _vertexBuffer2D.append(this._vertices); + var start; + if (this._firstNewElement < this._firstFreeElement) { + start = this._firstNewElement * 4 * this._floatCountPerVertex * 4; + _vertexBuffer2D.subUpload(start, start, start + (this._firstFreeElement - this._firstNewElement) * 4 * this._floatCountPerVertex * 4); + } + else { + start = this._firstNewElement * 4 * this._floatCountPerVertex * 4; + _vertexBuffer2D.subUpload(start, start, start + (this.settings.maxPartices - this._firstNewElement) * 4 * this._floatCountPerVertex * 4); + if (this._firstFreeElement > 0) { + _vertexBuffer2D.setNeedUpload(); + _vertexBuffer2D.subUpload(0, 0, this._firstFreeElement * 4 * this._floatCountPerVertex * 4); + } + } + this._firstNewElement = this._firstFreeElement; + } + renderSubmit() { + if (this.texture && this.texture.getIsReady()) { + this.update(Laya.ILaya.timer._delta); + this.sv.u_CurrentTime = this._currentTime; + if (this._firstNewElement != this._firstFreeElement) { + this.addNewParticlesToVertexBuffer(); + } + this.blend(); + if (this._firstActiveElement != this._firstFreeElement) { + var gl = Laya.WebGLContext.mainContext; + this._mesh.useMesh(gl); + this.sv.u_texture = this.texture._getSource(); + this.sv.upload(); + if (this._firstActiveElement < this._firstFreeElement) { + gl.drawElements(gl.TRIANGLES, (this._firstFreeElement - this._firstActiveElement) * 6, gl.UNSIGNED_SHORT, this._firstActiveElement * 6 * 2); + } + else { + Laya.WebGLContext.mainContext.drawElements(gl.TRIANGLES, (this.settings.maxPartices - this._firstActiveElement) * 6, gl.UNSIGNED_SHORT, this._firstActiveElement * 6 * 2); + if (this._firstFreeElement > 0) + gl.drawElements(gl.TRIANGLES, this._firstFreeElement * 6, gl.UNSIGNED_SHORT, 0); + } + Laya.Stat.renderBatches++; + } + this._drawCounter++; + } + return 1; + } + updateParticleForNative() { + if (this.texture && this.texture.getIsReady()) { + this.update(Laya.ILaya.timer._delta); + this.sv.u_CurrentTime = this._currentTime; + if (this._firstNewElement != this._firstFreeElement) { + this._firstNewElement = this._firstFreeElement; + } + } + } + getMesh() { + return this._mesh; + } + getConchMesh() { + return this._conchMesh; + } + getFirstNewElement() { + return this._firstNewElement; + } + getFirstFreeElement() { + return this._firstFreeElement; + } + getFirstActiveElement() { + return this._firstActiveElement; + } + getFirstRetiredElement() { + return this._firstRetiredElement; + } + setFirstFreeElement(_value) { + this._firstFreeElement = _value; + } + setFirstNewElement(_value) { + this._firstNewElement = _value; + } + addDrawCounter() { + this._drawCounter++; + } + blend() { + if (Laya.BlendMode.activeBlendFunction !== this._blendFn) { + var gl = Laya.WebGLContext.mainContext; + gl.enable(gl.BLEND); + this._blendFn(gl); + Laya.BlendMode.activeBlendFunction = this._blendFn; + } + } + dispose() { + this._mesh.releaseMesh(); + } + } + ParticleTemplate2D.activeBlendType = -1; + + class EmitterBase { + constructor() { + this._frameTime = 0; + this._emissionRate = 60; + this._emissionTime = 0; + this.minEmissionTime = 1 / 60; + } + set particleTemplate(particleTemplate) { + this._particleTemplate = particleTemplate; + } + set emissionRate(_emissionRate) { + if (_emissionRate <= 0) + return; + this._emissionRate = _emissionRate; + (_emissionRate > 0) && (this.minEmissionTime = 1 / _emissionRate); + } + get emissionRate() { + return this._emissionRate; + } + start(duration = Number.MAX_VALUE) { + if (this._emissionRate != 0) + this._emissionTime = duration; + } + stop() { + this._emissionTime = 0; + } + clear() { + this._emissionTime = 0; + } + emit() { + } + advanceTime(passedTime = 1) { + this._emissionTime -= passedTime; + if (this._emissionTime < 0) + return; + this._frameTime += passedTime; + if (this._frameTime < this.minEmissionTime) + return; + while (this._frameTime > this.minEmissionTime) { + this._frameTime -= this.minEmissionTime; + this.emit(); + } + } + } + + class Emitter2D extends EmitterBase { + constructor(_template) { + super(); + this.template = _template; + } + set template(template) { + this._particleTemplate = template; + if (!template) { + this._emitFun = null; + this.setting = null; + this._posRange = null; + } + this.setting = template.settings; + this._posRange = this.setting.positionVariance; + if (this._particleTemplate instanceof ParticleTemplate2D) { + this._emitFun = this.webGLEmit; + } + } + get template() { + return this._particleTemplate; + } + emit() { + super.emit(); + if (this._emitFun != null) + this._emitFun(); + } + getRandom(value) { + return (Math.random() * 2 - 1) * value; + } + webGLEmit() { + var pos = new Float32Array(3); + pos[0] = this.getRandom(this._posRange[0]); + pos[1] = this.getRandom(this._posRange[1]); + pos[2] = this.getRandom(this._posRange[2]); + var v = new Float32Array(3); + v[0] = 0; + v[1] = 0; + v[2] = 0; + this._particleTemplate.addParticleArray(pos, v); + } + canvasEmit() { + var pos = new Float32Array(3); + pos[0] = this.getRandom(this._posRange[0]); + pos[1] = this.getRandom(this._posRange[1]); + pos[2] = this.getRandom(this._posRange[2]); + var v = new Float32Array(3); + v[0] = 0; + v[1] = 0; + v[2] = 0; + this._particleTemplate.addParticleArray(pos, v); + } + } + + class Particle2D extends Laya.Sprite { + constructor(setting) { + super(); + this._matrix4 = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); + this.autoPlay = true; + this.customRenderEnable = true; + if (setting) + this.setParticleSetting(setting); + } + set url(url) { + this.load(url); + } + load(url) { + Laya.ILaya.loader.load(url, Laya.Handler.create(this, this.setParticleSetting), null, Laya.ILaya.Loader.JSON); + } + setParticleSetting(setting) { + if (!setting) + return this.stop(); + ParticleSetting.checkSetting(setting); + this.customRenderEnable = true; + this._particleTemplate = new ParticleTemplate2D(setting); + this.graphics._saveToCmd(null, Laya.DrawParticleCmd.create(this._particleTemplate)); + if (!this._emitter) { + this._emitter = new Emitter2D(this._particleTemplate); + } + else { + this._emitter.template = this._particleTemplate; + } + if (this.autoPlay) { + this.emitter.start(); + this.play(); + } + } + get emitter() { + return this._emitter; + } + play() { + Laya.ILaya.timer.frameLoop(1, this, this._loop); + } + stop() { + Laya.ILaya.timer.clear(this, this._loop); + } + _loop() { + this.advanceTime(1 / 60); + } + advanceTime(passedTime = 1) { + if (this._canvasTemplate) { + this._canvasTemplate.advanceTime(passedTime); + } + if (this._emitter) { + this._emitter.advanceTime(passedTime); + } + } + customRender(context, x, y) { + this._matrix4[0] = context._curMat.a; + this._matrix4[1] = context._curMat.b; + this._matrix4[4] = context._curMat.c; + this._matrix4[5] = context._curMat.d; + this._matrix4[12] = context._curMat.tx; + this._matrix4[13] = context._curMat.ty; + var sv = this._particleTemplate.sv; + sv.u_mmat = this._matrix4; + if (this._canvasTemplate) { + this._canvasTemplate.render(context, x, y); + } + } + destroy(destroyChild = true) { + if (this._particleTemplate instanceof ParticleTemplate2D) + this._particleTemplate.dispose(); + super.destroy(destroyChild); + } + } + Laya.ClassUtils.regClass("laya.particle.Particle2D", Particle2D); + Laya.ClassUtils.regClass("Laya.Particle2D", Particle2D); + Laya.ILaya.regClass(Particle2D); + + class ParticleEmitter { + constructor(templet, particlesPerSecond, initialPosition) { + this._timeLeftOver = 0; + this._tempVelocity = new Float32Array([0, 0, 0]); + this._tempPosition = new Float32Array([0, 0, 0]); + this._templet = templet; + this._timeBetweenParticles = 1.0 / particlesPerSecond; + this._previousPosition = initialPosition; + } + update(elapsedTime, newPosition) { + elapsedTime = elapsedTime / 1000; + if (elapsedTime > 0) { + Laya.MathUtil.subtractVector3(newPosition, this._previousPosition, this._tempVelocity); + Laya.MathUtil.scaleVector3(this._tempVelocity, 1 / elapsedTime, this._tempVelocity); + var timeToSpend = this._timeLeftOver + elapsedTime; + var currentTime = -this._timeLeftOver; + while (timeToSpend > this._timeBetweenParticles) { + currentTime += this._timeBetweenParticles; + timeToSpend -= this._timeBetweenParticles; + Laya.MathUtil.lerpVector3(this._previousPosition, newPosition, currentTime / elapsedTime, this._tempPosition); + this._templet.addParticleArray(this._tempPosition, this._tempVelocity); + } + this._timeLeftOver = timeToSpend; + } + this._previousPosition[0] = newPosition[0]; + this._previousPosition[1] = newPosition[1]; + this._previousPosition[2] = newPosition[2]; + } + } + + exports.Emitter2D = Emitter2D; + exports.EmitterBase = EmitterBase; + exports.Particle2D = Particle2D; + exports.ParticleData = ParticleData; + exports.ParticleEmitter = ParticleEmitter; + exports.ParticleSetting = ParticleSetting; + exports.ParticleShader = ParticleShader; + exports.ParticleShaderValue = ParticleShaderValue; + exports.ParticleTemplate2D = ParticleTemplate2D; + exports.ParticleTemplateBase = ParticleTemplateBase; + exports.ParticleTemplateWebGL = ParticleTemplateWebGL; + +}(window.Laya = window.Laya || {}, Laya)); diff --git a/examples/layaair/frontend/bin/libs/laya.performancetool.js b/examples/layaair/frontend/bin/libs/laya.performancetool.js new file mode 100644 index 0000000..1c4ba2a --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.performancetool.js @@ -0,0 +1,790 @@ +(function (exports, Laya) { + 'use strict'; + + const defaultOptions = { + autoRetryConnnect: true, + retryConnnectCount: 0, + retryConnnectDelay: 10000 + }; + let WebSocketCls = window.WebSocket; + class SocketManager { + constructor(host, port, name, type, options) { + this.clientId = 0; + this.socket = null; + this.isSupport = false; + this.status = 0; + this.retryConnnectCount = 0; + this.onClose = (ev) => { + let { onClose, autoRetryConnnect, retryConnnectCount } = this.options; + retryConnnectCount = retryConnnectCount || 0; + if (onClose) { + onClose(ev); + } + if (this.status === 0) { + if (autoRetryConnnect && + (retryConnnectCount == 0 || this.retryConnnectCount < retryConnnectCount)) { + this.delayRetryConnnect(); + } + } + }; + this._delayRetryConnnectTimer = 0; + this._delayRetryConnnect = () => { + clearTimeout(this._delayRetryConnnectTimer); + this.retryConnnectCount++; + this.reConnect(); + }; + this.onMessage = (ev) => { + const { onMessage } = this.options; + if (onMessage) { + onMessage(ev); + } + }; + this.onError = (ev) => { + const { onError } = this.options; + if (onError) { + onError(ev); + } + }; + this.onOpen = (ev) => { + const { onOpen } = this.options; + if (onOpen) { + onOpen(ev); + } + this.retryConnnectCount = 0; + clearTimeout(this._delayRetryConnnectTimer); + }; + this.url = 'ws://' + host + ":" + port + '?type=' + type + '&name=' + name; + if (options) { + Object.assign(options, defaultOptions); + this.options = options; + } + else { + this.options = defaultOptions; + } + WebSocketCls = window.WebSocket; + this.isSupport = (typeof WebSocketCls != 'undefined'); + if (this.isSupport) { + this.reConnect(); + } + else { + console.log('not support websocket'); + } + } + closeConnect() { + this.retryConnnectCount = 0; + if (this.socket) { + let socket = this.socket; + socket.onclose = null; + socket.onmessage = null; + socket.onerror = null; + socket.onopen = null; + socket.close(); + this.socket = null; + } + this.status = 0; + } + delayRetryConnnect() { + clearTimeout(this._delayRetryConnnectTimer); + if (ProfileHelper.enable) { + this._delayRetryConnnectTimer = setTimeout(this._delayRetryConnnect, this.options.retryConnnectDelay); + } + } + reConnect() { + let socket = new WebSocketCls(this.url); + this.socket = socket; + socket.onclose = this.onClose; + socket.onmessage = this.onMessage; + socket.onerror = this.onError; + socket.onopen = this.onOpen; + } + dispose() { + this.closeConnect(); + } + send(msg) { + if (this.socket && this.socket.readyState === 1) { + this.socket.send(msg); + return true; + } + return false; + } + } + const getParameterByName = function (name, url) { + name = name.replace(/[\[\]]/g, '\\$&'); + var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'), results = regex.exec(url); + if (!results) + return null; + if (!results[2]) + return ''; + return decodeURIComponent(results[2].replace(/\+/g, ' ')); + }; + const idIsInList = (id, list) => { + for (let i = 0; i < list.length; i++) { + let info = list[i]; + if (info.id == id) { + return true; + } + } + return false; + }; + class ProfileHelper { + constructor() { + this.socketManager = null; + this.selectPlayerId = 0; + this.active = 0; + this.selectPlayerStatus = 0; + this.sendMsg = (type, data, toId = 0) => { + this.socketManager.send(JSON.stringify({ + type: type, + data: data, + toId: toId + })); + }; + this.sendInternalMsg = (type, data, toId = 0) => { + this.socketManager.send(JSON.stringify({ + type: type, + data: data, + toId: toId + })); + }; + this.frameDataList = []; + this.sendFramData = (data) => { + if (!this.active) { + return; + } + this.frameDataList.push(data); + if (this.frameDataList.length >= 30) { + this.sendFramDataList(this.frameDataList); + this.frameDataList.length = 0; + } + }; + this.sendConfigData = (data = null) => { + let configData = this.performanceDataTool.getPathInfo(); + this.sendInternalMsg('getPerformanceConf_back', configData); + }; + this.sendFramDataList = (dataList) => { + let list = dataList.map((data) => { + return { + type: "frameData", + data: data + }; + }); + this.sendInternalMsg("msgList", list); + }; + } + static set enable(value) { + if (ProfileHelper._enable === value) { + return; + } + ProfileHelper._enable = value; + if (value) { + const initOption = ProfileHelper.initOption; + if (!initOption) { + throw new Error('没有执行初始化init'); + } + const { type, performanceDataTool, onOpen, onMessage, retryConnectCount, retryConnnectDelay } = initOption; + ProfileHelper.init(type, performanceDataTool, onOpen, onMessage, retryConnectCount, retryConnnectDelay); + } + else { + ProfileHelper.dispose(); + } + } + static get enable() { + return ProfileHelper._enable; + } + init(type, performanceDataTool, onOpen, onMessage, retryConnectCount, retryConnnectDelay) { + this.frameDataList = []; + if (type === 'player' && !performanceDataTool) { + throw new Error("type为player时,performanceDataTool不为空"); + } + var host = ''; + var url = ''; + var href = ''; + if (window && window.location && window.location.href) { + href = window.location.href; + } + var name = getParameterByName('profileName', href) || ''; + var port = getParameterByName('profilePort', href) || '1050'; + if (ProfileHelper.Host || getParameterByName('profileHost', href)) { + host = ProfileHelper.Host || getParameterByName('profileHost', href); + } + else { + if (href.startsWith('http')) { + var index1 = href.indexOf('//'); + var index2 = href.indexOf('/', index1 + 3); + if (index2 === -1) { + index2 = href.length; + } + url = href.substring(index1 + 2, index2); + index2 = url.indexOf(':'); + if (index2 >= 0) { + url = url.substring(0, index2); + } + host = url; + } + else { + host = 'localhost'; + } + } + this.performanceDataTool = performanceDataTool; + this.heartIntervalHandler = setInterval(() => { + this.sendInternalMsg('heart', {}); + }, 1000 * 10); + this.socketManager = new SocketManager(host, port, name, type, { + retryConnectCount: retryConnectCount || defaultOptions.retryConnnectCount, + retryConnnectDelay: retryConnnectDelay || defaultOptions.retryConnnectDelay, + onMessage: (ev) => { + if (!this.socketManager) { + return; + } + if (typeof ev.data == 'string') { + let data = JSON.parse(ev.data); + let msgList = [data]; + if (data.type === 'msgList') { + msgList = data.data; + } + msgList.forEach((eventData) => { + switch (eventData.type) { + case 'onSelectMe': + this.sendInternalMsg('onSelectMe_back', eventData.data); + break; + case 'getPerformanceConf': + this.sendConfigData(); + break; + case 'selectPlayer_back': + this.selectPlayerId = eventData.data.selectPlayer; + this.selectPlayerStatus = 0; + break; + case 'onReady': + this.socketManager.clientId = eventData.data.id; + this.sendInternalMsg('start', {}); + break; + case 'active': + this.active = eventData.data.active; + break; + case 'playerList': + if (this.selectPlayerId) { + if (!idIsInList(this.selectPlayerId, eventData.data)) { + this.selectPlayerId = 0; + this.selectPlayerStatus = 0; + } + } + if (this.selectPlayerId && eventData.data.length > 0 && this.selectPlayerStatus == 0) { + let playerId = eventData.data[0].id; + this.selectPlayerStatus = 1; + this.sendMsg('selectPlayer', { id: playerId }); + } + break; + } + }); + if (onMessage) { + msgList.forEach((msgData) => { + onMessage(msgData); + }); + } + } + }, + onOpen: (ev) => { + if (onOpen) { + onOpen(ev); + } + }, + onError: (ev) => { + }, + onClose: (ev) => { + } + }); + } + dispose() { + clearInterval(this.heartIntervalHandler); + if (this.socketManager) { + this.socketManager.dispose(); + this.socketManager = null; + } + this.performanceDataTool = null; + } + static init(type, performanceDataTool, onOpen, onMessage, retryConnectCount, retryConnnectDelay) { + if (ProfileHelper.instance) { + ProfileHelper.instance.dispose(); + } + ProfileHelper.initOption = { + type, + performanceDataTool, + onOpen, + onMessage, + retryConnectCount, + retryConnnectDelay + }; + if (!ProfileHelper._enable) { + return; + } + ProfileHelper.instance = new ProfileHelper(); + ProfileHelper.instance.init(type, performanceDataTool, onOpen, onMessage, retryConnectCount, retryConnnectDelay); + } + } + ProfileHelper.sendFramData = (data) => { + if (!ProfileHelper._enable) { + return; + } + if (ProfileHelper.instance) { + ProfileHelper.instance.sendFramData(data); + } + }; + ProfileHelper.sendConfigData = (data) => { + if (!ProfileHelper._enable) { + return; + } + if (ProfileHelper.instance) { + ProfileHelper.instance.sendConfigData(data); + } + }; + ProfileHelper.dispose = () => { + if (ProfileHelper.instance) { + ProfileHelper.instance.dispose(); + } + ProfileHelper.instance = null; + }; + + class PerformanceDataTool { + constructor() { + this._enable = false; + this._AllPathMap = {}; + this._pathColor = {}; + this._pathCount = 0; + this._runtimeShowPathIndex = -1; + this._nodeList = []; + this.samplerFramStep = 6; + this._memoryDataMap = {}; + this.pointArray = []; + this.fpsArray = []; + } + static InitLayaPerformanceInfo() { + PerformanceDataTool.instance.InitLayaPerformanceInfo(); + } + InitLayaPerformanceInfo() { + this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_2D, [255, 128, 128, 255]); + this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D, [255, 255, 128, 255]); + this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER, [128, 255, 128, 255]); + this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_UPDATESCRIPT, [128, 255, 255, 255]); + this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_PHYSICS, [0, 128, 255, 255]); + this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_PHYSICS_SIMULATE, [255, 0, 0, 255]); + this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_PHYSICS_CHARACTORCOLLISION, [255, 128, 0, 255]); + this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_PHYSICS_EVENTSCRIPTS, [128, 0, 0, 255]); + this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER, [64, 128, 128, 255]); + this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_SHADOWMAP, [192, 192, 192, 255]); + this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_CLUSTER, [128, 64, 64, 255]); + this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_CULLING, [0, 64, 128, 255]); + this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_RENDERDEPTHMDOE, [128, 0, 64, 255]); + this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_RENDEROPAQUE, [128, 0, 255, 255]); + this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_RENDERCOMMANDBUFFER, [128, 128, 64, 255]); + this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_RENDERTRANSPARENT, [128, 0, 255, 255]); + this.setPathDataColor(PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_POSTPROCESS, [0, 255, 0, 255]); + } + set enable(value) { + if (value) { + this._startFram = Laya.Stat.loopCount; + this.resetReCordData(); + this._sp = new Laya.Sprite(); + this._sp.pos(0, 400).zOrder = 99; + Laya.Laya.stage.addChild(this._sp); + } + else { + Laya.Laya.stage.removeChild(this._sp); + } + this._enable = value; + } + get enable() { + return this._enable; + } + get enableDataExport() { + return this._enableDataExport; + } + set enableDataExport(value) { + if (value) { + ProfileHelper.init('player', this); + ProfileHelper.enable = value; + this.samplerFramStep = 1; + } + else { + ProfileHelper.enable = value; + } + this._enableDataExport = value; + } + set runtimeShowPath(path) { + let showPathIndex = this._AllPathMap[path]; + for (let i in this.pointArray) { + delete this.pointArray[i]; + delete PerformanceDataTool.stepLengthArrayMap[i]; + } + if (showPathIndex != null) + this._runtimeShowPathIndex = showPathIndex; + else + this._runtimeShowPathIndex = -1; + } + getNodePathIndex(path) { + var id; + if (this._AllPathMap[path] != null) + id = this._AllPathMap[path]; + else { + id = this._pathCount++; + this._AllPathMap[path] = id; + ProfileHelper.sendConfigData(this.getPathInfo()); + } + return id; + } + getPathInfo() { + let pathInfo = {}; + if (Object.keys(this._pathColor).length == 0) { + this.InitLayaPerformanceInfo(); + } + pathInfo["_pathColor"] = this._pathColor; + pathInfo["_AllPathMap"] = this._AllPathMap; + return pathInfo; + } + exportPerformanceFile(fromProfiler = false) { + PerformanceDataTool.InitLayaPerformanceInfo(); + if (!fromProfiler) { + this.enable = false; + } + let blockstr = []; + let blockStart = []; + let blocklength = []; + let tempNum = 0; + let blockStartPos; + let tempStartPos; + let tempEndPos; + let dataByte = new Laya.Byte(); + dataByte.pos = 0; + dataByte.writeUTFString(PerformanceDataTool.VERSION); + blockstr.push("DataInfo01", "Color", "NodeInfo"); + dataByte.writeUint16(blockstr.length); + for (let i = 0; i < blockstr.length; i++) { + dataByte.writeUTFString(blockstr[i]); + } + blockStart.length = blockstr.length; + blocklength.length = blockstr.length; + blockStartPos = dataByte.pos; + for (let i = 0; i < blockstr.length; i++) { + dataByte.writeInt32(0); + dataByte.writeInt32(0); + } + blockStart[0] = dataByte.pos; + dataByte.writeInt32(this._nodeList.length); + dataByte.writeInt32(this.samplerFramStep); + dataByte.writeInt32(this._pathCount); + for (let j in this._AllPathMap) { + dataByte.writeUTFString(j); + } + tempStartPos = dataByte.pos; + dataByte.writeInt32(0); + for (let k in this._memoryDataMap) { + dataByte.writeUTFString(k); + tempNum++; + } + tempEndPos = dataByte.pos; + dataByte.pos = tempStartPos; + dataByte.writeInt32(tempNum); + dataByte.pos = tempEndPos; + blocklength[0] = dataByte.pos - blockStart[0]; + blockStart[1] = dataByte.pos; + tempStartPos = dataByte.pos; + tempNum = 0; + dataByte.writeInt32(0); + for (let l in this._pathColor) { + var vec4 = this._pathColor[l]; + dataByte.writeUTFString(l); + dataByte.writeUint32(vec4[0]); + dataByte.writeUint32(vec4[1]); + dataByte.writeUint32(vec4[2]); + dataByte.writeUint32(vec4[3]); + tempNum++; + } + tempEndPos = dataByte.pos; + dataByte.pos = tempStartPos; + dataByte.writeInt32(tempNum); + dataByte.pos = tempEndPos; + blocklength[1] = dataByte.pos - blockStart[1]; + blockStart[2] = dataByte.pos; + for (let n = 0; n < this._nodeList.length; n++) { + let node = this._nodeList[n]; + dataByte.writeInt32(node.nodeNum); + for (var ii = 0; ii < node.nodeNum; ii++) { + dataByte.writeFloat32(node.nodeDelty[ii] ? node.nodeDelty[ii] : 0); + } + } + blocklength[2] = dataByte.pos - blockStart[2]; + dataByte.pos = blockStartPos; + for (let v = 0; v < blockstr.length; v++) { + dataByte.writeInt32(blockStart[v]); + dataByte.writeInt32(blocklength[v]); + } + return dataByte; + } + BegainSample(samplePath) { + if (!this.enable) + return; + this.update(); + this._runtimeNode.getFunStart(this.getNodePathIndex(samplePath)); + } + EndSample(samplePath) { + if (!this.enable) + return 0; + return this._runtimeNode.getFunEnd(this.getNodePathIndex(samplePath)); + } + AddMemory(memoryPath, size) { + this._memoryDataMap[memoryPath] = this._memoryDataMap[memoryPath] ? (this._memoryDataMap[memoryPath] + size) : size; + } + setPathDataColor(path, color) { + this._pathColor[path] = color; + } + resetReCordData() { + this._nodeList.forEach(element => { + PerforManceNode.revert(element); + }); + this._nodeList = []; + this._runtimeNode = null; + this._AllPathMap = {}; + this._memoryDataMap = {}; + this._pathColor = {}; + this._pathCount = 0; + } + exportFrontNode(ob, pathIndex) { + if (!ob || !ob.nodeDelty || pathIndex == -1) { + return; + } + const width = PerformanceDataTool.DrawWidth; + const height = PerformanceDataTool.DrawHeight; + const stepLength = PerformanceDataTool.StepLength; + const fullStepTime = 33; + const bgColor = "rgba(150, 150, 150, 0.8)"; + let array, value, percent; + this._sp.graphics.clear(); + this._sp.graphics.drawRect(0, 0, width, height, bgColor); + for (let i = 0, len = ob.nodeDelty.length; i < len; i++) { + if (i != pathIndex && i != this.getNodePathIndex(PerformanceDataTool.PERFORMANCE_DELTYTIME)) { + continue; + } + value = ob.nodeDelty[i]; + percent = value / fullStepTime; + if (!this.pointArray[i]) { + this.pointArray[i] = []; + } + array = this.pointArray[i]; + if (array.length >= stepLength) { + array.shift(); + } + array.push(percent); + let color = i.toString(16); + let fillColor = `#${color}${color}C4${color}${color}`; + if (i == this.getNodePathIndex(PerformanceDataTool.PERFORMANCE_DELTYTIME)) { + fillColor = "#FFFFFF"; + } + if (!PerformanceDataTool.stepLengthArrayMap[i]) { + PerformanceDataTool.stepLengthArrayMap[i] = new Array(PerformanceDataTool.StepLength * 2); + } + this.updatelineChart(width, height, stepLength, array, fillColor, 1, PerformanceDataTool.stepLengthArrayMap[i]); + } + this._sp.graphics.drawLine(0, height / 2, width, height / 2, "green", 1); + this._sp.graphics.drawLine(0, height / 4 * 3, width, height / 4 * 3, "red", 1); + } + updatelineChart(width, height, stepLength, array, fillColor, style, drawArray) { + switch (style) { + case 1: + let copy = drawArray; + for (let i = 0, len = array.length; i < len; i++) { + copy[i * 2] = width / stepLength * i; + copy[i * 2 + 1] = Math.max(height - array[i] * height / this.samplerFramStep, 0); + } + this._sp.graphics.drawLines(0, 0, copy, fillColor, 1); + break; + case 2: + let widthStep = width / stepLength; + for (let i = 0, len = array.length; i < len; i++) { + this._sp.graphics.drawRect(width / stepLength * i, height, widthStep, -Math.min(array[i] * height, height), fillColor); + } + } + } + update() { + let currentFrame = Laya.Stat.loopCount; + let nodelenth = ((currentFrame - this._startFram) / this.samplerFramStep) | 0; + if (!nodelenth) { + this._runtimeNode = PerforManceNode.create(this._pathCount); + this._runtimeNode.nodeDelty[this.getNodePathIndex(PerformanceDataTool.PERFORMANCE_STARTTIME)] = performance.now(); + return; + } + if (nodelenth != this._nodeList.length) { + for (let i in this._memoryDataMap) { + this._runtimeNode.setMemory(this.getNodePathIndex(i), this._memoryDataMap[i]); + } + if (this._runtimeNode) { + this._runtimeNode.nodeDelty[this.getNodePathIndex(PerformanceDataTool.PERFORMANCE_DELTYTIME)] = performance.now() - this._runtimeNode.nodeDelty[this.getNodePathIndex(PerformanceDataTool.PERFORMANCE_STARTTIME)]; + this.exportFrontNode(this._runtimeNode, this._runtimeShowPathIndex); + ProfileHelper.sendFramData(this._runtimeNode); + } + this._runtimeNode = PerforManceNode.create(this._pathCount); + this._runtimeNode.nodeDelty[this.getNodePathIndex(PerformanceDataTool.PERFORMANCE_STARTTIME)] = performance.now(); + this._nodeList.push(this._runtimeNode); + } + } + static showMemoryData(memoryPath) { + } + static showFunSampleGroup(groupPath) { + } + showFunSampleFun(samplePath) { + this.runtimeShowPath = samplePath; + } + } + PerformanceDataTool.VERSION = "PERFORMANCEDATA:01"; + PerformanceDataTool.instance = new PerformanceDataTool(); + PerformanceDataTool.PERFORMANCE_DELTYTIME = "deltyTime"; + PerformanceDataTool.PERFORMANCE_STARTTIME = "startTime"; + PerformanceDataTool.PERFORMANCE_LAYA = "Laya"; + PerformanceDataTool.PERFORMANCE_LAYA_3D = "Laya/3D"; + PerformanceDataTool.PERFORMANCE_LAYA_2D = "Laya/2D"; + PerformanceDataTool.PERFORMANCE_LAYA_3D_PRERENDER = "Laya/3D/PreRender"; + PerformanceDataTool.PERFORMANCE_LAYA_3D_UPDATESCRIPT = "Laya/3D/UpdateScript"; + PerformanceDataTool.PERFORMANCE_LAYA_3D_PHYSICS = "Laya/3D/Physics"; + PerformanceDataTool.PERFORMANCE_LAYA_3D_PHYSICS_SIMULATE = "Laya/3D/Physics/simulate"; + PerformanceDataTool.PERFORMANCE_LAYA_3D_PHYSICS_CHARACTORCOLLISION = "Laya/3D/Physics/updataCharacters&Collisions"; + PerformanceDataTool.PERFORMANCE_LAYA_3D_PHYSICS_EVENTSCRIPTS = "Laya/3D/Physics/eventScripts"; + PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER = "Laya/3D/Render"; + PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_SHADOWMAP = "Laya/3D/Render/ShadowMap"; + PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_CLUSTER = "Laya/3D/Render/Cluster"; + PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_CULLING = "Laya/3D/Render/Culling"; + PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_RENDERDEPTHMDOE = "Laya/3D/Render/RenderDepthMode"; + PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_RENDEROPAQUE = "Laya/3D/Render/RenderOpaque"; + PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_RENDERCOMMANDBUFFER = "Laya/3D/Render/RenderCommandBuffer"; + PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_RENDERTRANSPARENT = "Laya/3D/Render/RenderTransparent"; + PerformanceDataTool.PERFORMANCE_LAYA_3D_RENDER_POSTPROCESS = "Laya/3D/Render/PostProcess"; + PerformanceDataTool._surpport = false; + PerformanceDataTool.DrawWidth = 250; + PerformanceDataTool.DrawHeight = 250; + PerformanceDataTool.StepLength = 250; + PerformanceDataTool.stepLengthArrayMap = new Array(); + class PerforManceNode { + constructor() { + this.inPool = false; + this.nodeNum = 0; + this.nodeStart = []; + this.nodeDelty = []; + this.applyCount = 0; + } + static create(nodeNum) { + let perNode; + perNode = this._pool.length > 0 ? this._pool.pop() : new PerforManceNode(); + perNode.resetData(nodeNum); + perNode.inPool = false; + return perNode; + } + static revert(node) { + node.inPool = true; + this._pool.push(node); + node.clearData(); + } + clearData() { + this.nodeStart.length = 0; + this.nodeDelty.length = 0; + } + resetData(nodeNum) { + this.nodeNum = nodeNum; + this.nodeStart.length = nodeNum; + this.nodeDelty.length = nodeNum; + } + getFunStart(index) { + this.applyCount++; + this.nodeStart[index] = performance.now(); + } + getFunEnd(index) { + if (this.nodeDelty[index]) + this.nodeDelty[index] += (this.nodeStart[index] != 0) ? (performance.now() - this.nodeStart[index]) : 0; + else { + this.nodeDelty[index] = (this.nodeStart[index] != 0) ? (performance.now() - this.nodeStart[index]) : 0; + this.nodeNum = this.nodeDelty.length; + } + return this.nodeDelty[index]; + } + setMemory(index, value) { + this.nodeDelty[index] = value; + } + getPathData(index) { + return this.nodeDelty[index]; + } + } + PerforManceNode._pool = []; + + class PerformanceNodeParse { + static parsePerformanceFile(performance, outData) { + performance.pos = 0; + PerformanceNodeParse.performanceData = outData; + PerformanceNodeParse._readData = performance; + PerformanceNodeParse.READ_DATA(); + for (let i = 0, n = PerformanceNodeParse._blockStr.length; i < n; i++) { + var blockName = PerformanceNodeParse._blockStr[i]; + var fn = PerformanceNodeParse["READ_" + blockName]; + if (fn == null) + throw new Error("model file err,no this function:" + blockName); + else { + PerformanceNodeParse._readData.pos = PerformanceNodeParse._blockStart[i]; + fn.call(null); + } + } + } + static READ_DATA() { + let data = PerformanceNodeParse._readData; + let version = data.readUTFString(); + if (version != "PERFORMANCEDATA:01") { + throw version + "is not standard Version"; + } + let blocklenth = PerformanceNodeParse._blockStr.length = data.readUint16(); + for (let i = 0; i < blocklenth; i++) { + PerformanceNodeParse._blockStr[i] = data.readUTFString(); + } + for (let j = 0; j < blocklenth; j++) { + PerformanceNodeParse._blockStart[j] = data.readInt32(); + PerformanceNodeParse._blocklength[j] = data.readInt32(); + } + } + static READ_DataInfo01() { + let data = PerformanceNodeParse._readData; + let performanceData = PerformanceNodeParse.performanceData; + PerformanceNodeParse._nodeNums = data.readInt32(); + performanceData.samplerFramStep = data.readInt32(); + let pathCount = data.readInt32(); + for (let i = 0; i < pathCount; i++) { + performanceData.getNodePathIndex(data.readUTFString()); + } + let memoryPath = data.readInt32(); + for (let j = 0; j < memoryPath; j++) { + performanceData._memoryDataMap[data.readUTFString()] = 1; + } + } + static READ_Color() { + let data = PerformanceNodeParse._readData; + let performanceData = PerformanceNodeParse.performanceData; + let colorlength = data.readInt32(); + for (let i = 0; i < colorlength; i++) + performanceData.setPathDataColor(data.readUTFString(), [data.readUint32(), data.readUint32(), data.readUint32(), data.readUint32()]); + } + static READ_NodeInfo() { + let data = PerformanceNodeParse._readData; + let performanceData = PerformanceNodeParse.performanceData; + let perNode; + let length; + for (let i = 0; i < PerformanceNodeParse._nodeNums; i++) { + length = data.readInt32(); + perNode = PerforManceNode.create(length); + for (let l = 0, n = length; l < n; l++) + perNode.nodeDelty[l] = data.readFloat32(); + performanceData._nodeList[i] = perNode; + } + } + } + PerformanceNodeParse._blockStr = []; + PerformanceNodeParse._blockStart = []; + PerformanceNodeParse._blocklength = []; + PerformanceNodeParse.performanceData = new PerformanceDataTool(); + + exports.PerforManceNode = PerforManceNode; + exports.PerformanceDataTool = PerformanceDataTool; + exports.PerformanceNodeParse = PerformanceNodeParse; + +}(window.Laya = window.Laya || {}, Laya)); diff --git a/examples/layaair/frontend/bin/libs/laya.physics.js b/examples/layaair/frontend/bin/libs/laya.physics.js new file mode 100644 index 0000000..e2a5e92 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.physics.js @@ -0,0 +1,17873 @@ +var box2d = window.box2d = (function (exports) { + 'use strict'; + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + class b2BlockAllocator { + } + + /* + * Copyright (c) 2011 Erin Catto http://box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// Color for debug drawing. Each value has the range [0,1]. + class b2Color { + constructor(r = 0.5, g = 0.5, b = 0.5, a = 1.0) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + Clone() { + return new b2Color().Copy(this); + } + Copy(other) { + this.r = other.r; + this.g = other.g; + this.b = other.b; + this.a = other.a; + return this; + } + IsEqual(color) { + return (this.r === color.r) && (this.g === color.g) && (this.b === color.b) && (this.a === color.a); + } + IsZero() { + return (this.r === 0) && (this.g === 0) && (this.b === 0) && (this.a === 0); + } + Set(r, g, b, a = this.a) { + this.SetRGBA(r, g, b, a); + } + SetByteRGB(r, g, b) { + this.r = r / 0xff; + this.g = g / 0xff; + this.b = b / 0xff; + return this; + } + SetByteRGBA(r, g, b, a) { + this.r = r / 0xff; + this.g = g / 0xff; + this.b = b / 0xff; + this.a = a / 0xff; + return this; + } + SetRGB(rr, gg, bb) { + this.r = rr; + this.g = gg; + this.b = bb; + return this; + } + SetRGBA(rr, gg, bb, aa) { + this.r = rr; + this.g = gg; + this.b = bb; + this.a = aa; + return this; + } + SelfAdd(color) { + this.r += color.r; + this.g += color.g; + this.b += color.b; + this.a += color.a; + return this; + } + Add(color, out) { + out.r = this.r + color.r; + out.g = this.g + color.g; + out.b = this.b + color.b; + out.a = this.a + color.a; + return out; + } + SelfSub(color) { + this.r -= color.r; + this.g -= color.g; + this.b -= color.b; + this.a -= color.a; + return this; + } + Sub(color, out) { + out.r = this.r - color.r; + out.g = this.g - color.g; + out.b = this.b - color.b; + out.a = this.a - color.a; + return out; + } + SelfMul(s) { + this.r *= s; + this.g *= s; + this.b *= s; + this.a *= s; + return this; + } + Mul(s, out) { + out.r = this.r * s; + out.g = this.g * s; + out.b = this.b * s; + out.a = this.a * s; + return out; + } + Mix(mixColor, strength) { + b2Color.MixColors(this, mixColor, strength); + } + static MixColors(colorA, colorB, strength) { + const dr = (strength * (colorB.r - colorA.r)); + const dg = (strength * (colorB.g - colorA.g)); + const db = (strength * (colorB.b - colorA.b)); + const da = (strength * (colorB.a - colorA.a)); + colorA.r += dr; + colorA.g += dg; + colorA.b += db; + colorA.a += da; + colorB.r -= dr; + colorB.g -= dg; + colorB.b -= db; + colorB.a -= da; + } + MakeStyleString(alpha = this.a) { + return b2Color.MakeStyleString(this.r, this.g, this.b, alpha); + } + static MakeStyleString(r, g, b, a = 1.0) { + // function clamp(x: number, lo: number, hi: number) { return x < lo ? lo : hi < x ? hi : x; } + r *= 255; // r = clamp(r, 0, 255); + g *= 255; // g = clamp(g, 0, 255); + b *= 255; // b = clamp(b, 0, 255); + // a = clamp(a, 0, 1); + if (a < 1) { + return `rgba(${r},${g},${b},${a})`; + } + else { + return `rgb(${r},${g},${b})`; + } + } + } + b2Color.ZERO = new b2Color(0, 0, 0, 0); + b2Color.RED = new b2Color(1, 0, 0); + b2Color.GREEN = new b2Color(0, 1, 0); + b2Color.BLUE = new b2Color(0, 0, 1); + exports.b2DrawFlags = void 0; + (function (b2DrawFlags) { + b2DrawFlags[b2DrawFlags["e_none"] = 0] = "e_none"; + b2DrawFlags[b2DrawFlags["e_shapeBit"] = 1] = "e_shapeBit"; + b2DrawFlags[b2DrawFlags["e_jointBit"] = 2] = "e_jointBit"; + b2DrawFlags[b2DrawFlags["e_aabbBit"] = 4] = "e_aabbBit"; + b2DrawFlags[b2DrawFlags["e_pairBit"] = 8] = "e_pairBit"; + b2DrawFlags[b2DrawFlags["e_centerOfMassBit"] = 16] = "e_centerOfMassBit"; + b2DrawFlags[b2DrawFlags["e_all"] = 63] = "e_all"; + })(exports.b2DrawFlags || (exports.b2DrawFlags = {})); + /// Implement and register this class with a b2World to provide debug drawing of physics + /// entities in your game. + class b2Draw { + constructor() { + this.m_drawFlags = 0; + } + SetFlags(flags) { + this.m_drawFlags = flags; + } + GetFlags() { + return this.m_drawFlags; + } + AppendFlags(flags) { + this.m_drawFlags |= flags; + } + ClearFlags(flags) { + this.m_drawFlags &= ~flags; + } + } + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + // import { b2_lengthUnitsPerMeter } from "./b2_settings.js"; + function b2Assert(condition, ...args) { + if (!condition) { + // debugger; + throw new Error(...args); + } + } + function b2Maybe(value, def) { + return value !== undefined ? value : def; + } + const b2_maxFloat = 1E+37; // FLT_MAX instead of Number.MAX_VALUE; + const b2_epsilon = 1E-5; // FLT_EPSILON instead of Number.EPSILON; + const b2_epsilon_sq = (b2_epsilon * b2_epsilon); + const b2_pi = 3.14159265359; // Math.PI; + /// @file + /// Global tuning constants based on meters-kilograms-seconds (MKS) units. + /// + // Tunable Constants + /// You can use this to change the length scale used by your game. + /// For example for inches you could use 39.4. + const b2_lengthUnitsPerMeter = 1.0; + /// The maximum number of vertices on a convex polygon. You cannot increase + /// this too much because b2BlockAllocator has a maximum object size. + const b2_maxPolygonVertices = 8; + // Collision + /// The maximum number of contact points between two convex shapes. Do + /// not change this value. + const b2_maxManifoldPoints = 2; + /// This is used to fatten AABBs in the dynamic tree. This allows proxies + /// to move by a small amount without triggering a tree adjustment. + /// This is in meters. + const b2_aabbExtension = 0.1 * b2_lengthUnitsPerMeter; + /// This is used to fatten AABBs in the dynamic tree. This is used to predict + /// the future position based on the current displacement. + /// This is a dimensionless multiplier. + const b2_aabbMultiplier = 4; + /// A small length used as a collision and constraint tolerance. Usually it is + /// chosen to be numerically significant, but visually insignificant. + const b2_linearSlop = 0.005 * b2_lengthUnitsPerMeter; + /// A small angle used as a collision and constraint tolerance. Usually it is + /// chosen to be numerically significant, but visually insignificant. + const b2_angularSlop = 2 / 180 * b2_pi; + /// The radius of the polygon/edge shape skin. This should not be modified. Making + /// this smaller means polygons will have an insufficient buffer for continuous collision. + /// Making it larger may create artifacts for vertex collision. + const b2_polygonRadius = 2 * b2_linearSlop; + /// Maximum number of sub-steps per contact in continuous physics simulation. + const b2_maxSubSteps = 8; + // Dynamics + /// Maximum number of contacts to be handled to solve a TOI impact. + const b2_maxTOIContacts = 32; + /// The maximum linear position correction used when solving constraints. This helps to + /// prevent overshoot. + const b2_maxLinearCorrection = 0.2 * b2_lengthUnitsPerMeter; + /// The maximum angular position correction used when solving constraints. This helps to + /// prevent overshoot. + const b2_maxAngularCorrection = 8 / 180 * b2_pi; + /// The maximum linear velocity of a body. This limit is very large and is used + /// to prevent numerical problems. You shouldn't need to adjust this. + const b2_maxTranslation = 2 * b2_lengthUnitsPerMeter; + const b2_maxTranslationSquared = b2_maxTranslation * b2_maxTranslation; + /// The maximum angular velocity of a body. This limit is very large and is used + /// to prevent numerical problems. You shouldn't need to adjust this. + const b2_maxRotation = 0.5 * b2_pi; + const b2_maxRotationSquared = b2_maxRotation * b2_maxRotation; + /// This scale factor controls how fast overlap is resolved. Ideally this would be 1 so + /// that overlap is removed in one time step. However using values close to 1 often lead + /// to overshoot. + const b2_baumgarte = 0.2; + const b2_toiBaumgarte = 0.75; + // Sleep + /// The time that a body must be still before it will go to sleep. + const b2_timeToSleep = 0.5; + /// A body cannot sleep if its linear velocity is above this tolerance. + const b2_linearSleepTolerance = 0.01 * b2_lengthUnitsPerMeter; + /// A body cannot sleep if its angular velocity is above this tolerance. + const b2_angularSleepTolerance = 2 / 180 * b2_pi; + // FILE* b2_dumpFile = nullptr; + // void b2OpenDump(const char* fileName) + // { + // b2Assert(b2_dumpFile == nullptr); + // b2_dumpFile = fopen(fileName, "w"); + // } + // void b2Dump(const char* string, ...) + // { + // if (b2_dumpFile == nullptr) + // { + // return; + // } + // va_list args; + // va_start(args, string); + // vfprintf(b2_dumpFile, string, args); + // va_end(args); + // } + // void b2CloseDump() + // { + // fclose(b2_dumpFile); + // b2_dumpFile = nullptr; + // } + /// Version numbering scheme. + /// See http://en.wikipedia.org/wiki/Software_versioning + class b2Version { + constructor(major = 0, minor = 0, revision = 0) { + this.major = 0; ///< significant changes + this.minor = 0; ///< incremental changes + this.revision = 0; ///< bug fixes + this.major = major; + this.minor = minor; + this.revision = revision; + } + toString() { + return this.major + "." + this.minor + "." + this.revision; + } + } + /// Current version. + const b2_version = new b2Version(2, 4, 1); + const b2_branch = "master"; + const b2_commit = "9ebbbcd960ad424e03e5de6e66a40764c16f51bc"; + function b2ParseInt(v) { + return parseInt(v, 10); + } + function b2ParseUInt(v) { + return Math.abs(parseInt(v, 10)); + } + function b2MakeArray(length, init) { + const a = new Array(length); + for (let i = 0; i < length; ++i) { + a[i] = init(i); + } + return a; + } + function b2MakeNullArray(length) { + const a = new Array(length); + for (let i = 0; i < length; ++i) { + a[i] = null; + } + return a; + } + function b2MakeNumberArray(length, init = 0) { + const a = new Array(length); + for (let i = 0; i < length; ++i) { + a[i] = init; + } + return a; + } + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// @file + /// Settings that can be overriden for your application + /// + // Tunable Constants + /// You can use this to change the length scale used by your game. + /// For example for inches you could use 39.4. + // export const b2_lengthUnitsPerMeter: number = 1.0; + /// The maximum number of vertices on a convex polygon. You cannot increase + /// this too much because b2BlockAllocator has a maximum object size. + // export const b2_maxPolygonVertices: number = 8; + // Memory Allocation + /// Implement this function to use your own memory allocator. + function b2Alloc(size) { + return null; + } + /// If you implement b2Alloc, you should also implement this function. + function b2Free(mem) { + } + /// Logging function. + function b2Log(message, ...args) { + // console.log(message, ...args); + } + + /* + * Copyright (c) 2010 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// This is a growable LIFO stack with an initial capacity of N. + /// If the stack size exceeds the initial capacity, the heap is used + /// to increase the size of the stack. + class b2GrowableStack { + constructor(N) { + this.m_stack = []; + this.m_count = 0; + this.m_stack = b2MakeArray(N, (index) => null); + this.m_count = 0; + } + Reset() { + this.m_count = 0; + return this; + } + Push(element) { + this.m_stack[this.m_count] = element; + this.m_count++; + } + Pop() { + // DEBUG: b2Assert(this.m_count > 0); + this.m_count--; + const element = this.m_stack[this.m_count]; + this.m_stack[this.m_count] = null; + return element; + } + GetCount() { + return this.m_count; + } + } + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + const b2_pi_over_180 = b2_pi / 180; + const b2_180_over_pi = 180 / b2_pi; + const b2_two_pi = 2 * b2_pi; + const b2Abs = Math.abs; + function b2Min(a, b) { return a < b ? a : b; } + function b2Max(a, b) { return a > b ? a : b; } + function b2Clamp(a, lo, hi) { + return (a < lo) ? (lo) : ((a > hi) ? (hi) : (a)); + } + function b2Swap(a, b) { + // DEBUG: b2Assert(false); + const tmp = a[0]; + a[0] = b[0]; + b[0] = tmp; + } + /// This function is used to ensure that a floating point number is + /// not a NaN or infinity. + const b2IsValid = isFinite; + function b2Sq(n) { + return n * n; + } + /// This is a approximate yet fast inverse square-root. + function b2InvSqrt(n) { + return 1 / Math.sqrt(n); + } + const b2Sqrt = Math.sqrt; + const b2Pow = Math.pow; + function b2DegToRad(degrees) { + return degrees * b2_pi_over_180; + } + function b2RadToDeg(radians) { + return radians * b2_180_over_pi; + } + const b2Cos = Math.cos; + const b2Sin = Math.sin; + const b2Acos = Math.acos; + const b2Asin = Math.asin; + const b2Atan2 = Math.atan2; + function b2NextPowerOfTwo(x) { + x |= (x >> 1) & 0x7FFFFFFF; + x |= (x >> 2) & 0x3FFFFFFF; + x |= (x >> 4) & 0x0FFFFFFF; + x |= (x >> 8) & 0x00FFFFFF; + x |= (x >> 16) & 0x0000FFFF; + return x + 1; + } + function b2IsPowerOfTwo(x) { + return x > 0 && (x & (x - 1)) === 0; + } + function b2Random() { + return Math.random() * 2 - 1; + } + function b2RandomRange(lo, hi) { + return (hi - lo) * Math.random() + lo; + } + /// A 2D column vector. + class b2Vec2 { + constructor(x = 0, y = 0) { + this.x = x; + this.y = y; + } + Clone() { + return new b2Vec2(this.x, this.y); + } + SetZero() { + this.x = 0; + this.y = 0; + return this; + } + Set(x, y) { + this.x = x; + this.y = y; + return this; + } + Copy(other) { + this.x = other.x; + this.y = other.y; + return this; + } + SelfAdd(v) { + this.x += v.x; + this.y += v.y; + return this; + } + SelfAddXY(x, y) { + this.x += x; + this.y += y; + return this; + } + SelfSub(v) { + this.x -= v.x; + this.y -= v.y; + return this; + } + SelfSubXY(x, y) { + this.x -= x; + this.y -= y; + return this; + } + SelfMul(s) { + this.x *= s; + this.y *= s; + return this; + } + SelfMulAdd(s, v) { + this.x += s * v.x; + this.y += s * v.y; + return this; + } + SelfMulSub(s, v) { + this.x -= s * v.x; + this.y -= s * v.y; + return this; + } + Dot(v) { + return this.x * v.x + this.y * v.y; + } + Cross(v) { + return this.x * v.y - this.y * v.x; + } + Length() { + const x = this.x, y = this.y; + return Math.sqrt(x * x + y * y); + } + LengthSquared() { + const x = this.x, y = this.y; + return (x * x + y * y); + } + Normalize() { + const length = this.Length(); + if (length >= b2_epsilon) { + const inv_length = 1 / length; + this.x *= inv_length; + this.y *= inv_length; + } + return length; + } + SelfNormalize() { + const length = this.Length(); + if (length >= b2_epsilon) { + const inv_length = 1 / length; + this.x *= inv_length; + this.y *= inv_length; + } + return this; + } + SelfRotate(radians) { + const c = Math.cos(radians); + const s = Math.sin(radians); + const x = this.x; + this.x = c * x - s * this.y; + this.y = s * x + c * this.y; + return this; + } + SelfRotateCosSin(c, s) { + const x = this.x; + this.x = c * x - s * this.y; + this.y = s * x + c * this.y; + return this; + } + IsValid() { + return isFinite(this.x) && isFinite(this.y); + } + SelfCrossVS(s) { + const x = this.x; + this.x = s * this.y; + this.y = -s * x; + return this; + } + SelfCrossSV(s) { + const x = this.x; + this.x = -s * this.y; + this.y = s * x; + return this; + } + SelfMinV(v) { + this.x = b2Min(this.x, v.x); + this.y = b2Min(this.y, v.y); + return this; + } + SelfMaxV(v) { + this.x = b2Max(this.x, v.x); + this.y = b2Max(this.y, v.y); + return this; + } + SelfAbs() { + this.x = b2Abs(this.x); + this.y = b2Abs(this.y); + return this; + } + SelfNeg() { + this.x = (-this.x); + this.y = (-this.y); + return this; + } + SelfSkew() { + const x = this.x; + this.x = -this.y; + this.y = x; + return this; + } + static MakeArray(length) { + return b2MakeArray(length, (i) => new b2Vec2()); + } + static AbsV(v, out) { + out.x = b2Abs(v.x); + out.y = b2Abs(v.y); + return out; + } + static MinV(a, b, out) { + out.x = b2Min(a.x, b.x); + out.y = b2Min(a.y, b.y); + return out; + } + static MaxV(a, b, out) { + out.x = b2Max(a.x, b.x); + out.y = b2Max(a.y, b.y); + return out; + } + static ClampV(v, lo, hi, out) { + out.x = b2Clamp(v.x, lo.x, hi.x); + out.y = b2Clamp(v.y, lo.y, hi.y); + return out; + } + static RotateV(v, radians, out) { + const v_x = v.x, v_y = v.y; + const c = Math.cos(radians); + const s = Math.sin(radians); + out.x = c * v_x - s * v_y; + out.y = s * v_x + c * v_y; + return out; + } + static DotVV(a, b) { + return a.x * b.x + a.y * b.y; + } + static CrossVV(a, b) { + return a.x * b.y - a.y * b.x; + } + static CrossVS(v, s, out) { + const v_x = v.x; + out.x = s * v.y; + out.y = -s * v_x; + return out; + } + static CrossVOne(v, out) { + const v_x = v.x; + out.x = v.y; + out.y = -v_x; + return out; + } + static CrossSV(s, v, out) { + const v_x = v.x; + out.x = -s * v.y; + out.y = s * v_x; + return out; + } + static CrossOneV(v, out) { + const v_x = v.x; + out.x = -v.y; + out.y = v_x; + return out; + } + static AddVV(a, b, out) { out.x = a.x + b.x; out.y = a.y + b.y; return out; } + static SubVV(a, b, out) { out.x = a.x - b.x; out.y = a.y - b.y; return out; } + static MulSV(s, v, out) { out.x = v.x * s; out.y = v.y * s; return out; } + static MulVS(v, s, out) { out.x = v.x * s; out.y = v.y * s; return out; } + static AddVMulSV(a, s, b, out) { out.x = a.x + (s * b.x); out.y = a.y + (s * b.y); return out; } + static SubVMulSV(a, s, b, out) { out.x = a.x - (s * b.x); out.y = a.y - (s * b.y); return out; } + static AddVCrossSV(a, s, v, out) { + const v_x = v.x; + out.x = a.x - (s * v.y); + out.y = a.y + (s * v_x); + return out; + } + static MidVV(a, b, out) { out.x = (a.x + b.x) * 0.5; out.y = (a.y + b.y) * 0.5; return out; } + static ExtVV(a, b, out) { out.x = (b.x - a.x) * 0.5; out.y = (b.y - a.y) * 0.5; return out; } + static IsEqualToV(a, b) { + return a.x === b.x && a.y === b.y; + } + static DistanceVV(a, b) { + const c_x = a.x - b.x; + const c_y = a.y - b.y; + return Math.sqrt(c_x * c_x + c_y * c_y); + } + static DistanceSquaredVV(a, b) { + const c_x = a.x - b.x; + const c_y = a.y - b.y; + return (c_x * c_x + c_y * c_y); + } + static NegV(v, out) { out.x = -v.x; out.y = -v.y; return out; } + } + b2Vec2.ZERO = new b2Vec2(0, 0); + b2Vec2.UNITX = new b2Vec2(1, 0); + b2Vec2.UNITY = new b2Vec2(0, 1); + b2Vec2.s_t0 = new b2Vec2(); + b2Vec2.s_t1 = new b2Vec2(); + b2Vec2.s_t2 = new b2Vec2(); + b2Vec2.s_t3 = new b2Vec2(); + const b2Vec2_zero = new b2Vec2(0, 0); + /// A 2D column vector with 3 elements. + class b2Vec3 { + constructor(...args) { + if (args[0] instanceof Float32Array) { + if (args[0].length !== 3) { + throw new Error(); + } + this.data = args[0]; + } + else { + const x = typeof args[0] === "number" ? args[0] : 0; + const y = typeof args[1] === "number" ? args[1] : 0; + const z = typeof args[2] === "number" ? args[2] : 0; + this.data = new Float32Array([x, y, z]); + } + } + get x() { return this.data[0]; } + set x(value) { this.data[0] = value; } + get y() { return this.data[1]; } + set y(value) { this.data[1] = value; } + get z() { return this.data[2]; } + set z(value) { this.data[2] = value; } + Clone() { + return new b2Vec3(this.x, this.y, this.z); + } + SetZero() { + this.x = 0; + this.y = 0; + this.z = 0; + return this; + } + SetXYZ(x, y, z) { + this.x = x; + this.y = y; + this.z = z; + return this; + } + Copy(other) { + this.x = other.x; + this.y = other.y; + this.z = other.z; + return this; + } + SelfNeg() { + this.x = (-this.x); + this.y = (-this.y); + this.z = (-this.z); + return this; + } + SelfAdd(v) { + this.x += v.x; + this.y += v.y; + this.z += v.z; + return this; + } + SelfAddXYZ(x, y, z) { + this.x += x; + this.y += y; + this.z += z; + return this; + } + SelfSub(v) { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z; + return this; + } + SelfSubXYZ(x, y, z) { + this.x -= x; + this.y -= y; + this.z -= z; + return this; + } + SelfMul(s) { + this.x *= s; + this.y *= s; + this.z *= s; + return this; + } + static DotV3V3(a, b) { + return a.x * b.x + a.y * b.y + a.z * b.z; + } + static CrossV3V3(a, b, out) { + const a_x = a.x, a_y = a.y, a_z = a.z; + const b_x = b.x, b_y = b.y, b_z = b.z; + out.x = a_y * b_z - a_z * b_y; + out.y = a_z * b_x - a_x * b_z; + out.z = a_x * b_y - a_y * b_x; + return out; + } + } + b2Vec3.ZERO = new b2Vec3(0, 0, 0); + b2Vec3.s_t0 = new b2Vec3(); + /// A 2-by-2 matrix. Stored in column-major order. + class b2Mat22 { + constructor() { + // public readonly data: Float32Array = new Float32Array([ 1, 0, 0, 1 ]); + // public readonly ex: b2Vec2 = new b2Vec2(this.data.subarray(0, 2)); + // public readonly ey: b2Vec2 = new b2Vec2(this.data.subarray(2, 4)); + this.ex = new b2Vec2(1, 0); + this.ey = new b2Vec2(0, 1); + } + Clone() { + return new b2Mat22().Copy(this); + } + static FromVV(c1, c2) { + return new b2Mat22().SetVV(c1, c2); + } + static FromSSSS(r1c1, r1c2, r2c1, r2c2) { + return new b2Mat22().SetSSSS(r1c1, r1c2, r2c1, r2c2); + } + static FromAngle(radians) { + return new b2Mat22().SetAngle(radians); + } + SetSSSS(r1c1, r1c2, r2c1, r2c2) { + this.ex.Set(r1c1, r2c1); + this.ey.Set(r1c2, r2c2); + return this; + } + SetVV(c1, c2) { + this.ex.Copy(c1); + this.ey.Copy(c2); + return this; + } + SetAngle(radians) { + const c = Math.cos(radians); + const s = Math.sin(radians); + this.ex.Set(c, s); + this.ey.Set(-s, c); + return this; + } + Copy(other) { + this.ex.Copy(other.ex); + this.ey.Copy(other.ey); + return this; + } + SetIdentity() { + this.ex.Set(1, 0); + this.ey.Set(0, 1); + return this; + } + SetZero() { + this.ex.SetZero(); + this.ey.SetZero(); + return this; + } + GetAngle() { + return Math.atan2(this.ex.y, this.ex.x); + } + GetInverse(out) { + const a = this.ex.x; + const b = this.ey.x; + const c = this.ex.y; + const d = this.ey.y; + let det = a * d - b * c; + if (det !== 0) { + det = 1 / det; + } + out.ex.x = det * d; + out.ey.x = (-det * b); + out.ex.y = (-det * c); + out.ey.y = det * a; + return out; + } + Solve(b_x, b_y, out) { + const a11 = this.ex.x, a12 = this.ey.x; + const a21 = this.ex.y, a22 = this.ey.y; + let det = a11 * a22 - a12 * a21; + if (det !== 0) { + det = 1 / det; + } + out.x = det * (a22 * b_x - a12 * b_y); + out.y = det * (a11 * b_y - a21 * b_x); + return out; + } + SelfAbs() { + this.ex.SelfAbs(); + this.ey.SelfAbs(); + return this; + } + SelfInv() { + this.GetInverse(this); + return this; + } + SelfAddM(M) { + this.ex.SelfAdd(M.ex); + this.ey.SelfAdd(M.ey); + return this; + } + SelfSubM(M) { + this.ex.SelfSub(M.ex); + this.ey.SelfSub(M.ey); + return this; + } + static AbsM(M, out) { + const M_ex = M.ex, M_ey = M.ey; + out.ex.x = b2Abs(M_ex.x); + out.ex.y = b2Abs(M_ex.y); + out.ey.x = b2Abs(M_ey.x); + out.ey.y = b2Abs(M_ey.y); + return out; + } + static MulMV(M, v, out) { + const M_ex = M.ex, M_ey = M.ey; + const v_x = v.x, v_y = v.y; + out.x = M_ex.x * v_x + M_ey.x * v_y; + out.y = M_ex.y * v_x + M_ey.y * v_y; + return out; + } + static MulTMV(M, v, out) { + const M_ex = M.ex, M_ey = M.ey; + const v_x = v.x, v_y = v.y; + out.x = M_ex.x * v_x + M_ex.y * v_y; + out.y = M_ey.x * v_x + M_ey.y * v_y; + return out; + } + static AddMM(A, B, out) { + const A_ex = A.ex, A_ey = A.ey; + const B_ex = B.ex, B_ey = B.ey; + out.ex.x = A_ex.x + B_ex.x; + out.ex.y = A_ex.y + B_ex.y; + out.ey.x = A_ey.x + B_ey.x; + out.ey.y = A_ey.y + B_ey.y; + return out; + } + static MulMM(A, B, out) { + const A_ex_x = A.ex.x, A_ex_y = A.ex.y; + const A_ey_x = A.ey.x, A_ey_y = A.ey.y; + const B_ex_x = B.ex.x, B_ex_y = B.ex.y; + const B_ey_x = B.ey.x, B_ey_y = B.ey.y; + out.ex.x = A_ex_x * B_ex_x + A_ey_x * B_ex_y; + out.ex.y = A_ex_y * B_ex_x + A_ey_y * B_ex_y; + out.ey.x = A_ex_x * B_ey_x + A_ey_x * B_ey_y; + out.ey.y = A_ex_y * B_ey_x + A_ey_y * B_ey_y; + return out; + } + static MulTMM(A, B, out) { + const A_ex_x = A.ex.x, A_ex_y = A.ex.y; + const A_ey_x = A.ey.x, A_ey_y = A.ey.y; + const B_ex_x = B.ex.x, B_ex_y = B.ex.y; + const B_ey_x = B.ey.x, B_ey_y = B.ey.y; + out.ex.x = A_ex_x * B_ex_x + A_ex_y * B_ex_y; + out.ex.y = A_ey_x * B_ex_x + A_ey_y * B_ex_y; + out.ey.x = A_ex_x * B_ey_x + A_ex_y * B_ey_y; + out.ey.y = A_ey_x * B_ey_x + A_ey_y * B_ey_y; + return out; + } + } + b2Mat22.IDENTITY = new b2Mat22(); + /// A 3-by-3 matrix. Stored in column-major order. + class b2Mat33 { + constructor() { + this.data = new Float32Array([1, 0, 0, 0, 1, 0, 0, 0, 1]); + this.ex = new b2Vec3(this.data.subarray(0, 3)); + this.ey = new b2Vec3(this.data.subarray(3, 6)); + this.ez = new b2Vec3(this.data.subarray(6, 9)); + } + Clone() { + return new b2Mat33().Copy(this); + } + SetVVV(c1, c2, c3) { + this.ex.Copy(c1); + this.ey.Copy(c2); + this.ez.Copy(c3); + return this; + } + Copy(other) { + this.ex.Copy(other.ex); + this.ey.Copy(other.ey); + this.ez.Copy(other.ez); + return this; + } + SetIdentity() { + this.ex.SetXYZ(1, 0, 0); + this.ey.SetXYZ(0, 1, 0); + this.ez.SetXYZ(0, 0, 1); + return this; + } + SetZero() { + this.ex.SetZero(); + this.ey.SetZero(); + this.ez.SetZero(); + return this; + } + SelfAddM(M) { + this.ex.SelfAdd(M.ex); + this.ey.SelfAdd(M.ey); + this.ez.SelfAdd(M.ez); + return this; + } + Solve33(b_x, b_y, b_z, out) { + const a11 = this.ex.x, a21 = this.ex.y, a31 = this.ex.z; + const a12 = this.ey.x, a22 = this.ey.y, a32 = this.ey.z; + const a13 = this.ez.x, a23 = this.ez.y, a33 = this.ez.z; + let det = a11 * (a22 * a33 - a32 * a23) + a21 * (a32 * a13 - a12 * a33) + a31 * (a12 * a23 - a22 * a13); + if (det !== 0) { + det = 1 / det; + } + out.x = det * (b_x * (a22 * a33 - a32 * a23) + b_y * (a32 * a13 - a12 * a33) + b_z * (a12 * a23 - a22 * a13)); + out.y = det * (a11 * (b_y * a33 - b_z * a23) + a21 * (b_z * a13 - b_x * a33) + a31 * (b_x * a23 - b_y * a13)); + out.z = det * (a11 * (a22 * b_z - a32 * b_y) + a21 * (a32 * b_x - a12 * b_z) + a31 * (a12 * b_y - a22 * b_x)); + return out; + } + Solve22(b_x, b_y, out) { + const a11 = this.ex.x, a12 = this.ey.x; + const a21 = this.ex.y, a22 = this.ey.y; + let det = a11 * a22 - a12 * a21; + if (det !== 0) { + det = 1 / det; + } + out.x = det * (a22 * b_x - a12 * b_y); + out.y = det * (a11 * b_y - a21 * b_x); + return out; + } + GetInverse22(M) { + const a = this.ex.x, b = this.ey.x, c = this.ex.y, d = this.ey.y; + let det = a * d - b * c; + if (det !== 0) { + det = 1 / det; + } + M.ex.x = det * d; + M.ey.x = -det * b; + M.ex.z = 0; + M.ex.y = -det * c; + M.ey.y = det * a; + M.ey.z = 0; + M.ez.x = 0; + M.ez.y = 0; + M.ez.z = 0; + } + GetSymInverse33(M) { + let det = b2Vec3.DotV3V3(this.ex, b2Vec3.CrossV3V3(this.ey, this.ez, b2Vec3.s_t0)); + if (det !== 0) { + det = 1 / det; + } + const a11 = this.ex.x, a12 = this.ey.x, a13 = this.ez.x; + const a22 = this.ey.y, a23 = this.ez.y; + const a33 = this.ez.z; + M.ex.x = det * (a22 * a33 - a23 * a23); + M.ex.y = det * (a13 * a23 - a12 * a33); + M.ex.z = det * (a12 * a23 - a13 * a22); + M.ey.x = M.ex.y; + M.ey.y = det * (a11 * a33 - a13 * a13); + M.ey.z = det * (a13 * a12 - a11 * a23); + M.ez.x = M.ex.z; + M.ez.y = M.ey.z; + M.ez.z = det * (a11 * a22 - a12 * a12); + } + static MulM33V3(A, v, out) { + const v_x = v.x, v_y = v.y, v_z = v.z; + out.x = A.ex.x * v_x + A.ey.x * v_y + A.ez.x * v_z; + out.y = A.ex.y * v_x + A.ey.y * v_y + A.ez.y * v_z; + out.z = A.ex.z * v_x + A.ey.z * v_y + A.ez.z * v_z; + return out; + } + static MulM33XYZ(A, x, y, z, out) { + out.x = A.ex.x * x + A.ey.x * y + A.ez.x * z; + out.y = A.ex.y * x + A.ey.y * y + A.ez.y * z; + out.z = A.ex.z * x + A.ey.z * y + A.ez.z * z; + return out; + } + static MulM33V2(A, v, out) { + const v_x = v.x, v_y = v.y; + out.x = A.ex.x * v_x + A.ey.x * v_y; + out.y = A.ex.y * v_x + A.ey.y * v_y; + return out; + } + static MulM33XY(A, x, y, out) { + out.x = A.ex.x * x + A.ey.x * y; + out.y = A.ex.y * x + A.ey.y * y; + return out; + } + } + b2Mat33.IDENTITY = new b2Mat33(); + /// Rotation + class b2Rot { + constructor(angle = 0) { + this.s = 0; + this.c = 1; + if (angle) { + this.s = Math.sin(angle); + this.c = Math.cos(angle); + } + } + Clone() { + return new b2Rot().Copy(this); + } + Copy(other) { + this.s = other.s; + this.c = other.c; + return this; + } + SetAngle(angle) { + this.s = Math.sin(angle); + this.c = Math.cos(angle); + return this; + } + SetIdentity() { + this.s = 0; + this.c = 1; + return this; + } + GetAngle() { + return Math.atan2(this.s, this.c); + } + GetXAxis(out) { + out.x = this.c; + out.y = this.s; + return out; + } + GetYAxis(out) { + out.x = -this.s; + out.y = this.c; + return out; + } + static MulRR(q, r, out) { + // [qc -qs] * [rc -rs] = [qc*rc-qs*rs -qc*rs-qs*rc] + // [qs qc] [rs rc] [qs*rc+qc*rs -qs*rs+qc*rc] + // s = qs * rc + qc * rs + // c = qc * rc - qs * rs + const q_c = q.c, q_s = q.s; + const r_c = r.c, r_s = r.s; + out.s = q_s * r_c + q_c * r_s; + out.c = q_c * r_c - q_s * r_s; + return out; + } + static MulTRR(q, r, out) { + // [ qc qs] * [rc -rs] = [qc*rc+qs*rs -qc*rs+qs*rc] + // [-qs qc] [rs rc] [-qs*rc+qc*rs qs*rs+qc*rc] + // s = qc * rs - qs * rc + // c = qc * rc + qs * rs + const q_c = q.c, q_s = q.s; + const r_c = r.c, r_s = r.s; + out.s = q_c * r_s - q_s * r_c; + out.c = q_c * r_c + q_s * r_s; + return out; + } + static MulRV(q, v, out) { + const q_c = q.c, q_s = q.s; + const v_x = v.x, v_y = v.y; + out.x = q_c * v_x - q_s * v_y; + out.y = q_s * v_x + q_c * v_y; + return out; + } + static MulTRV(q, v, out) { + const q_c = q.c, q_s = q.s; + const v_x = v.x, v_y = v.y; + out.x = q_c * v_x + q_s * v_y; + out.y = -q_s * v_x + q_c * v_y; + return out; + } + } + b2Rot.IDENTITY = new b2Rot(); + /// A transform contains translation and rotation. It is used to represent + /// the position and orientation of rigid frames. + class b2Transform { + constructor() { + this.p = new b2Vec2(); + this.q = new b2Rot(); + } + Clone() { + return new b2Transform().Copy(this); + } + Copy(other) { + this.p.Copy(other.p); + this.q.Copy(other.q); + return this; + } + SetIdentity() { + this.p.SetZero(); + this.q.SetIdentity(); + return this; + } + SetPositionRotation(position, q) { + this.p.Copy(position); + this.q.Copy(q); + return this; + } + SetPositionAngle(pos, a) { + this.p.Copy(pos); + this.q.SetAngle(a); + return this; + } + SetPosition(position) { + this.p.Copy(position); + return this; + } + SetPositionXY(x, y) { + this.p.Set(x, y); + return this; + } + SetRotation(rotation) { + this.q.Copy(rotation); + return this; + } + SetRotationAngle(radians) { + this.q.SetAngle(radians); + return this; + } + GetPosition() { + return this.p; + } + GetRotation() { + return this.q; + } + GetRotationAngle() { + return this.q.GetAngle(); + } + GetAngle() { + return this.q.GetAngle(); + } + static MulXV(T, v, out) { + // float32 x = (T.q.c * v.x - T.q.s * v.y) + T.p.x; + // float32 y = (T.q.s * v.x + T.q.c * v.y) + T.p.y; + // return b2Vec2(x, y); + const T_q_c = T.q.c, T_q_s = T.q.s; + const v_x = v.x, v_y = v.y; + out.x = (T_q_c * v_x - T_q_s * v_y) + T.p.x; + out.y = (T_q_s * v_x + T_q_c * v_y) + T.p.y; + return out; + } + static MulTXV(T, v, out) { + // float32 px = v.x - T.p.x; + // float32 py = v.y - T.p.y; + // float32 x = (T.q.c * px + T.q.s * py); + // float32 y = (-T.q.s * px + T.q.c * py); + // return b2Vec2(x, y); + const T_q_c = T.q.c, T_q_s = T.q.s; + const p_x = v.x - T.p.x; + const p_y = v.y - T.p.y; + out.x = (T_q_c * p_x + T_q_s * p_y); + out.y = (-T_q_s * p_x + T_q_c * p_y); + return out; + } + static MulXX(A, B, out) { + b2Rot.MulRR(A.q, B.q, out.q); + b2Vec2.AddVV(b2Rot.MulRV(A.q, B.p, out.p), A.p, out.p); + return out; + } + static MulTXX(A, B, out) { + b2Rot.MulTRR(A.q, B.q, out.q); + b2Rot.MulTRV(A.q, b2Vec2.SubVV(B.p, A.p, out.p), out.p); + return out; + } + } + b2Transform.IDENTITY = new b2Transform(); + /// This describes the motion of a body/shape for TOI computation. + /// Shapes are defined with respect to the body origin, which may + /// no coincide with the center of mass. However, to support dynamics + /// we must interpolate the center of mass position. + class b2Sweep { + constructor() { + this.localCenter = new b2Vec2(); + this.c0 = new b2Vec2(); + this.c = new b2Vec2(); + this.a0 = 0; + this.a = 0; + this.alpha0 = 0; + } + Clone() { + return new b2Sweep().Copy(this); + } + Copy(other) { + this.localCenter.Copy(other.localCenter); + this.c0.Copy(other.c0); + this.c.Copy(other.c); + this.a0 = other.a0; + this.a = other.a; + this.alpha0 = other.alpha0; + return this; + } + // https://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/ + GetTransform(xf, beta) { + xf.p.x = (1.0 - beta) * this.c0.x + beta * this.c.x; + xf.p.y = (1.0 - beta) * this.c0.y + beta * this.c.y; + const angle = (1.0 - beta) * this.a0 + beta * this.a; + xf.q.SetAngle(angle); + xf.p.SelfSub(b2Rot.MulRV(xf.q, this.localCenter, b2Vec2.s_t0)); + return xf; + } + Advance(alpha) { + // DEBUG: b2Assert(this.alpha0 < 1); + const beta = (alpha - this.alpha0) / (1 - this.alpha0); + this.c0.SelfMulAdd(beta, this.c.Clone().SelfSub(this.c0)); + this.a0 += beta * (this.a - this.a0); + this.alpha0 = alpha; + } + Normalize() { + const d = b2_two_pi * Math.floor(this.a0 / b2_two_pi); + this.a0 -= d; + this.a -= d; + } + } + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + class b2StackAllocator { + } + + /* + * Copyright (c) 2011 Erin Catto http://box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// Timer for profiling. This has platform specific code and may + /// not work on every platform. + class b2Timer { + constructor() { + this.m_start = Date.now(); + } + /// Reset the timer. + Reset() { + this.m_start = Date.now(); + return this; + } + /// Get the time since construction or the last reset. + GetMilliseconds() { + return Date.now() - this.m_start; + } + } + class b2Counter { + constructor() { + this.m_count = 0; + this.m_min_count = 0; + this.m_max_count = 0; + } + GetCount() { + return this.m_count; + } + GetMinCount() { + return this.m_min_count; + } + GetMaxCount() { + return this.m_max_count; + } + ResetCount() { + const count = this.m_count; + this.m_count = 0; + return count; + } + ResetMinCount() { + this.m_min_count = 0; + } + ResetMaxCount() { + this.m_max_count = 0; + } + Increment() { + this.m_count++; + if (this.m_max_count < this.m_count) { + this.m_max_count = this.m_count; + } + } + Decrement() { + this.m_count--; + if (this.m_min_count > this.m_count) { + this.m_min_count = this.m_count; + } + } + } + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// This holds the mass data computed for a shape. + class b2MassData { + constructor() { + /// The mass of the shape, usually in kilograms. + this.mass = 0; + /// The position of the shape's centroid relative to the shape's origin. + this.center = new b2Vec2(0, 0); + /// The rotational inertia of the shape about the local origin. + this.I = 0; + } + } + exports.b2ShapeType = void 0; + (function (b2ShapeType) { + b2ShapeType[b2ShapeType["e_unknown"] = -1] = "e_unknown"; + b2ShapeType[b2ShapeType["e_circleShape"] = 0] = "e_circleShape"; + b2ShapeType[b2ShapeType["e_edgeShape"] = 1] = "e_edgeShape"; + b2ShapeType[b2ShapeType["e_polygonShape"] = 2] = "e_polygonShape"; + b2ShapeType[b2ShapeType["e_chainShape"] = 3] = "e_chainShape"; + b2ShapeType[b2ShapeType["e_shapeTypeCount"] = 4] = "e_shapeTypeCount"; + })(exports.b2ShapeType || (exports.b2ShapeType = {})); + /// A shape is used for collision detection. You can create a shape however you like. + /// Shapes used for simulation in b2World are created automatically when a b2Fixture + /// is created. Shapes may encapsulate a one or more child shapes. + class b2Shape { + constructor(type, radius) { + this.m_type = exports.b2ShapeType.e_unknown; + /// Radius of a shape. For polygonal shapes this must be b2_polygonRadius. There is no support for + /// making rounded polygons. + this.m_radius = 0; + this.m_type = type; + this.m_radius = radius; + } + Copy(other) { + // DEBUG: b2Assert(this.m_type === other.m_type); + this.m_radius = other.m_radius; + return this; + } + /// Get the type of this shape. You can use this to down cast to the concrete shape. + /// @return the shape type. + GetType() { + return this.m_type; + } + } + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// A distance proxy is used by the GJK algorithm. + /// It encapsulates any shape. + class b2DistanceProxy { + constructor() { + this.m_buffer = b2Vec2.MakeArray(2); + this.m_vertices = this.m_buffer; + this.m_count = 0; + this.m_radius = 0; + } + Copy(other) { + if (other.m_vertices === other.m_buffer) { + this.m_vertices = this.m_buffer; + this.m_buffer[0].Copy(other.m_buffer[0]); + this.m_buffer[1].Copy(other.m_buffer[1]); + } + else { + this.m_vertices = other.m_vertices; + } + this.m_count = other.m_count; + this.m_radius = other.m_radius; + return this; + } + Reset() { + this.m_vertices = this.m_buffer; + this.m_count = 0; + this.m_radius = 0; + return this; + } + SetShape(shape, index) { + shape.SetupDistanceProxy(this, index); + } + SetVerticesRadius(vertices, count, radius) { + this.m_vertices = vertices; + this.m_count = count; + this.m_radius = radius; + } + Set(...args) { + if (args[0] instanceof b2Shape) { + this.SetShape(args[0], args[1]); + } + else { + this.SetVerticesRadius(args[0], args[1], args[2]); + } + } + GetSupport(d) { + let bestIndex = 0; + let bestValue = b2Vec2.DotVV(this.m_vertices[0], d); + for (let i = 1; i < this.m_count; ++i) { + const value = b2Vec2.DotVV(this.m_vertices[i], d); + if (value > bestValue) { + bestIndex = i; + bestValue = value; + } + } + return bestIndex; + } + GetSupportVertex(d) { + let bestIndex = 0; + let bestValue = b2Vec2.DotVV(this.m_vertices[0], d); + for (let i = 1; i < this.m_count; ++i) { + const value = b2Vec2.DotVV(this.m_vertices[i], d); + if (value > bestValue) { + bestIndex = i; + bestValue = value; + } + } + return this.m_vertices[bestIndex]; + } + GetVertexCount() { + return this.m_count; + } + GetVertex(index) { + // DEBUG: b2Assert(0 <= index && index < this.m_count); + return this.m_vertices[index]; + } + } + class b2SimplexCache { + constructor() { + this.metric = 0; + this.count = 0; + this.indexA = [0, 0, 0]; + this.indexB = [0, 0, 0]; + } + Reset() { + this.metric = 0; + this.count = 0; + return this; + } + } + class b2DistanceInput { + constructor() { + this.proxyA = new b2DistanceProxy(); + this.proxyB = new b2DistanceProxy(); + this.transformA = new b2Transform(); + this.transformB = new b2Transform(); + this.useRadii = false; + } + Reset() { + this.proxyA.Reset(); + this.proxyB.Reset(); + this.transformA.SetIdentity(); + this.transformB.SetIdentity(); + this.useRadii = false; + return this; + } + } + class b2DistanceOutput { + constructor() { + this.pointA = new b2Vec2(); + this.pointB = new b2Vec2(); + this.distance = 0; + this.iterations = 0; ///< number of GJK iterations used + } + Reset() { + this.pointA.SetZero(); + this.pointB.SetZero(); + this.distance = 0; + this.iterations = 0; + return this; + } + } + /// Input parameters for b2ShapeCast + class b2ShapeCastInput { + constructor() { + this.proxyA = new b2DistanceProxy(); + this.proxyB = new b2DistanceProxy(); + this.transformA = new b2Transform(); + this.transformB = new b2Transform(); + this.translationB = new b2Vec2(); + } + } + /// Output results for b2ShapeCast + class b2ShapeCastOutput { + constructor() { + this.point = new b2Vec2(); + this.normal = new b2Vec2(); + this.lambda = 0.0; + this.iterations = 0; + } + } + exports.b2_gjkCalls = 0; + exports.b2_gjkIters = 0; + exports.b2_gjkMaxIters = 0; + function b2_gjk_reset() { + exports.b2_gjkCalls = 0; + exports.b2_gjkIters = 0; + exports.b2_gjkMaxIters = 0; + } + class b2SimplexVertex { + constructor() { + this.wA = new b2Vec2(); // support point in proxyA + this.wB = new b2Vec2(); // support point in proxyB + this.w = new b2Vec2(); // wB - wA + this.a = 0; // barycentric coordinate for closest point + this.indexA = 0; // wA index + this.indexB = 0; // wB index + } + Copy(other) { + this.wA.Copy(other.wA); // support point in proxyA + this.wB.Copy(other.wB); // support point in proxyB + this.w.Copy(other.w); // wB - wA + this.a = other.a; // barycentric coordinate for closest point + this.indexA = other.indexA; // wA index + this.indexB = other.indexB; // wB index + return this; + } + } + class b2Simplex { + constructor() { + this.m_v1 = new b2SimplexVertex(); + this.m_v2 = new b2SimplexVertex(); + this.m_v3 = new b2SimplexVertex(); + this.m_vertices = [ /*3*/]; + this.m_count = 0; + this.m_vertices[0] = this.m_v1; + this.m_vertices[1] = this.m_v2; + this.m_vertices[2] = this.m_v3; + } + ReadCache(cache, proxyA, transformA, proxyB, transformB) { + // DEBUG: b2Assert(0 <= cache.count && cache.count <= 3); + // Copy data from cache. + this.m_count = cache.count; + const vertices = this.m_vertices; + for (let i = 0; i < this.m_count; ++i) { + const v = vertices[i]; + v.indexA = cache.indexA[i]; + v.indexB = cache.indexB[i]; + const wALocal = proxyA.GetVertex(v.indexA); + const wBLocal = proxyB.GetVertex(v.indexB); + b2Transform.MulXV(transformA, wALocal, v.wA); + b2Transform.MulXV(transformB, wBLocal, v.wB); + b2Vec2.SubVV(v.wB, v.wA, v.w); + v.a = 0; + } + // Compute the new simplex metric, if it is substantially different than + // old metric then flush the simplex. + if (this.m_count > 1) { + const metric1 = cache.metric; + const metric2 = this.GetMetric(); + if (metric2 < 0.5 * metric1 || 2 * metric1 < metric2 || metric2 < b2_epsilon) { + // Reset the simplex. + this.m_count = 0; + } + } + // If the cache is empty or invalid ... + if (this.m_count === 0) { + const v = vertices[0]; + v.indexA = 0; + v.indexB = 0; + const wALocal = proxyA.GetVertex(0); + const wBLocal = proxyB.GetVertex(0); + b2Transform.MulXV(transformA, wALocal, v.wA); + b2Transform.MulXV(transformB, wBLocal, v.wB); + b2Vec2.SubVV(v.wB, v.wA, v.w); + v.a = 1; + this.m_count = 1; + } + } + WriteCache(cache) { + cache.metric = this.GetMetric(); + cache.count = this.m_count; + const vertices = this.m_vertices; + for (let i = 0; i < this.m_count; ++i) { + cache.indexA[i] = vertices[i].indexA; + cache.indexB[i] = vertices[i].indexB; + } + } + GetSearchDirection(out) { + switch (this.m_count) { + case 1: + return b2Vec2.NegV(this.m_v1.w, out); + case 2: { + const e12 = b2Vec2.SubVV(this.m_v2.w, this.m_v1.w, out); + const sgn = b2Vec2.CrossVV(e12, b2Vec2.NegV(this.m_v1.w, b2Vec2.s_t0)); + if (sgn > 0) { + // Origin is left of e12. + return b2Vec2.CrossOneV(e12, out); + } + else { + // Origin is right of e12. + return b2Vec2.CrossVOne(e12, out); + } + } + default: + // DEBUG: b2Assert(false); + return out.SetZero(); + } + } + GetClosestPoint(out) { + switch (this.m_count) { + case 0: + // DEBUG: b2Assert(false); + return out.SetZero(); + case 1: + return out.Copy(this.m_v1.w); + case 2: + return out.Set(this.m_v1.a * this.m_v1.w.x + this.m_v2.a * this.m_v2.w.x, this.m_v1.a * this.m_v1.w.y + this.m_v2.a * this.m_v2.w.y); + case 3: + return out.SetZero(); + default: + // DEBUG: b2Assert(false); + return out.SetZero(); + } + } + GetWitnessPoints(pA, pB) { + switch (this.m_count) { + case 0: + // DEBUG: b2Assert(false); + break; + case 1: + pA.Copy(this.m_v1.wA); + pB.Copy(this.m_v1.wB); + break; + case 2: + pA.x = this.m_v1.a * this.m_v1.wA.x + this.m_v2.a * this.m_v2.wA.x; + pA.y = this.m_v1.a * this.m_v1.wA.y + this.m_v2.a * this.m_v2.wA.y; + pB.x = this.m_v1.a * this.m_v1.wB.x + this.m_v2.a * this.m_v2.wB.x; + pB.y = this.m_v1.a * this.m_v1.wB.y + this.m_v2.a * this.m_v2.wB.y; + break; + case 3: + pB.x = pA.x = this.m_v1.a * this.m_v1.wA.x + this.m_v2.a * this.m_v2.wA.x + this.m_v3.a * this.m_v3.wA.x; + pB.y = pA.y = this.m_v1.a * this.m_v1.wA.y + this.m_v2.a * this.m_v2.wA.y + this.m_v3.a * this.m_v3.wA.y; + break; + } + } + GetMetric() { + switch (this.m_count) { + case 0: + // DEBUG: b2Assert(false); + return 0; + case 1: + return 0; + case 2: + return b2Vec2.DistanceVV(this.m_v1.w, this.m_v2.w); + case 3: + return b2Vec2.CrossVV(b2Vec2.SubVV(this.m_v2.w, this.m_v1.w, b2Vec2.s_t0), b2Vec2.SubVV(this.m_v3.w, this.m_v1.w, b2Vec2.s_t1)); + default: + // DEBUG: b2Assert(false); + return 0; + } + } + Solve2() { + const w1 = this.m_v1.w; + const w2 = this.m_v2.w; + const e12 = b2Vec2.SubVV(w2, w1, b2Simplex.s_e12); + // w1 region + const d12_2 = (-b2Vec2.DotVV(w1, e12)); + if (d12_2 <= 0) { + // a2 <= 0, so we clamp it to 0 + this.m_v1.a = 1; + this.m_count = 1; + return; + } + // w2 region + const d12_1 = b2Vec2.DotVV(w2, e12); + if (d12_1 <= 0) { + // a1 <= 0, so we clamp it to 0 + this.m_v2.a = 1; + this.m_count = 1; + this.m_v1.Copy(this.m_v2); + return; + } + // Must be in e12 region. + const inv_d12 = 1 / (d12_1 + d12_2); + this.m_v1.a = d12_1 * inv_d12; + this.m_v2.a = d12_2 * inv_d12; + this.m_count = 2; + } + Solve3() { + const w1 = this.m_v1.w; + const w2 = this.m_v2.w; + const w3 = this.m_v3.w; + // Edge12 + // [1 1 ][a1] = [1] + // [w1.e12 w2.e12][a2] = [0] + // a3 = 0 + const e12 = b2Vec2.SubVV(w2, w1, b2Simplex.s_e12); + const w1e12 = b2Vec2.DotVV(w1, e12); + const w2e12 = b2Vec2.DotVV(w2, e12); + const d12_1 = w2e12; + const d12_2 = (-w1e12); + // Edge13 + // [1 1 ][a1] = [1] + // [w1.e13 w3.e13][a3] = [0] + // a2 = 0 + const e13 = b2Vec2.SubVV(w3, w1, b2Simplex.s_e13); + const w1e13 = b2Vec2.DotVV(w1, e13); + const w3e13 = b2Vec2.DotVV(w3, e13); + const d13_1 = w3e13; + const d13_2 = (-w1e13); + // Edge23 + // [1 1 ][a2] = [1] + // [w2.e23 w3.e23][a3] = [0] + // a1 = 0 + const e23 = b2Vec2.SubVV(w3, w2, b2Simplex.s_e23); + const w2e23 = b2Vec2.DotVV(w2, e23); + const w3e23 = b2Vec2.DotVV(w3, e23); + const d23_1 = w3e23; + const d23_2 = (-w2e23); + // Triangle123 + const n123 = b2Vec2.CrossVV(e12, e13); + const d123_1 = n123 * b2Vec2.CrossVV(w2, w3); + const d123_2 = n123 * b2Vec2.CrossVV(w3, w1); + const d123_3 = n123 * b2Vec2.CrossVV(w1, w2); + // w1 region + if (d12_2 <= 0 && d13_2 <= 0) { + this.m_v1.a = 1; + this.m_count = 1; + return; + } + // e12 + if (d12_1 > 0 && d12_2 > 0 && d123_3 <= 0) { + const inv_d12 = 1 / (d12_1 + d12_2); + this.m_v1.a = d12_1 * inv_d12; + this.m_v2.a = d12_2 * inv_d12; + this.m_count = 2; + return; + } + // e13 + if (d13_1 > 0 && d13_2 > 0 && d123_2 <= 0) { + const inv_d13 = 1 / (d13_1 + d13_2); + this.m_v1.a = d13_1 * inv_d13; + this.m_v3.a = d13_2 * inv_d13; + this.m_count = 2; + this.m_v2.Copy(this.m_v3); + return; + } + // w2 region + if (d12_1 <= 0 && d23_2 <= 0) { + this.m_v2.a = 1; + this.m_count = 1; + this.m_v1.Copy(this.m_v2); + return; + } + // w3 region + if (d13_1 <= 0 && d23_1 <= 0) { + this.m_v3.a = 1; + this.m_count = 1; + this.m_v1.Copy(this.m_v3); + return; + } + // e23 + if (d23_1 > 0 && d23_2 > 0 && d123_1 <= 0) { + const inv_d23 = 1 / (d23_1 + d23_2); + this.m_v2.a = d23_1 * inv_d23; + this.m_v3.a = d23_2 * inv_d23; + this.m_count = 2; + this.m_v1.Copy(this.m_v3); + return; + } + // Must be in triangle123 + const inv_d123 = 1 / (d123_1 + d123_2 + d123_3); + this.m_v1.a = d123_1 * inv_d123; + this.m_v2.a = d123_2 * inv_d123; + this.m_v3.a = d123_3 * inv_d123; + this.m_count = 3; + } + } + b2Simplex.s_e12 = new b2Vec2(); + b2Simplex.s_e13 = new b2Vec2(); + b2Simplex.s_e23 = new b2Vec2(); + const b2Distance_s_simplex = new b2Simplex(); + const b2Distance_s_saveA = [0, 0, 0]; + const b2Distance_s_saveB = [0, 0, 0]; + const b2Distance_s_p = new b2Vec2(); + const b2Distance_s_d = new b2Vec2(); + const b2Distance_s_normal = new b2Vec2(); + const b2Distance_s_supportA = new b2Vec2(); + const b2Distance_s_supportB = new b2Vec2(); + function b2Distance(output, cache, input) { + ++exports.b2_gjkCalls; + const proxyA = input.proxyA; + const proxyB = input.proxyB; + const transformA = input.transformA; + const transformB = input.transformB; + // Initialize the simplex. + const simplex = b2Distance_s_simplex; + simplex.ReadCache(cache, proxyA, transformA, proxyB, transformB); + // Get simplex vertices as an array. + const vertices = simplex.m_vertices; + const k_maxIters = 20; + // These store the vertices of the last simplex so that we + // can check for duplicates and prevent cycling. + const saveA = b2Distance_s_saveA; + const saveB = b2Distance_s_saveB; + let saveCount = 0; + // Main iteration loop. + let iter = 0; + while (iter < k_maxIters) { + // Copy simplex so we can identify duplicates. + saveCount = simplex.m_count; + for (let i = 0; i < saveCount; ++i) { + saveA[i] = vertices[i].indexA; + saveB[i] = vertices[i].indexB; + } + switch (simplex.m_count) { + case 1: + break; + case 2: + simplex.Solve2(); + break; + case 3: + simplex.Solve3(); + break; + } + // If we have 3 points, then the origin is in the corresponding triangle. + if (simplex.m_count === 3) { + break; + } + // Get search direction. + const d = simplex.GetSearchDirection(b2Distance_s_d); + // Ensure the search direction is numerically fit. + if (d.LengthSquared() < b2_epsilon_sq) { + // The origin is probably contained by a line segment + // or triangle. Thus the shapes are overlapped. + // We can't return zero here even though there may be overlap. + // In case the simplex is a point, segment, or triangle it is difficult + // to determine if the origin is contained in the CSO or very close to it. + break; + } + // Compute a tentative new simplex vertex using support points. + const vertex = vertices[simplex.m_count]; + vertex.indexA = proxyA.GetSupport(b2Rot.MulTRV(transformA.q, b2Vec2.NegV(d, b2Vec2.s_t0), b2Distance_s_supportA)); + b2Transform.MulXV(transformA, proxyA.GetVertex(vertex.indexA), vertex.wA); + vertex.indexB = proxyB.GetSupport(b2Rot.MulTRV(transformB.q, d, b2Distance_s_supportB)); + b2Transform.MulXV(transformB, proxyB.GetVertex(vertex.indexB), vertex.wB); + b2Vec2.SubVV(vertex.wB, vertex.wA, vertex.w); + // Iteration count is equated to the number of support point calls. + ++iter; + ++exports.b2_gjkIters; + // Check for duplicate support points. This is the main termination criteria. + let duplicate = false; + for (let i = 0; i < saveCount; ++i) { + if (vertex.indexA === saveA[i] && vertex.indexB === saveB[i]) { + duplicate = true; + break; + } + } + // If we found a duplicate support point we must exit to avoid cycling. + if (duplicate) { + break; + } + // New vertex is ok and needed. + ++simplex.m_count; + } + exports.b2_gjkMaxIters = b2Max(exports.b2_gjkMaxIters, iter); + // Prepare output. + simplex.GetWitnessPoints(output.pointA, output.pointB); + output.distance = b2Vec2.DistanceVV(output.pointA, output.pointB); + output.iterations = iter; + // Cache the simplex. + simplex.WriteCache(cache); + // Apply radii if requested. + if (input.useRadii) { + const rA = proxyA.m_radius; + const rB = proxyB.m_radius; + if (output.distance > (rA + rB) && output.distance > b2_epsilon) { + // Shapes are still no overlapped. + // Move the witness points to the outer surface. + output.distance -= rA + rB; + const normal = b2Vec2.SubVV(output.pointB, output.pointA, b2Distance_s_normal); + normal.Normalize(); + output.pointA.SelfMulAdd(rA, normal); + output.pointB.SelfMulSub(rB, normal); + } + else { + // Shapes are overlapped when radii are considered. + // Move the witness points to the middle. + const p = b2Vec2.MidVV(output.pointA, output.pointB, b2Distance_s_p); + output.pointA.Copy(p); + output.pointB.Copy(p); + output.distance = 0; + } + } + } + /// Perform a linear shape cast of shape B moving and shape A fixed. Determines the hit point, normal, and translation fraction. + // GJK-raycast + // Algorithm by Gino van den Bergen. + // "Smooth Mesh Contacts with GJK" in Game Physics Pearls. 2010 + // bool b2ShapeCast(b2ShapeCastOutput* output, const b2ShapeCastInput* input); + const b2ShapeCast_s_n = new b2Vec2(); + const b2ShapeCast_s_simplex = new b2Simplex(); + const b2ShapeCast_s_wA = new b2Vec2(); + const b2ShapeCast_s_wB = new b2Vec2(); + const b2ShapeCast_s_v = new b2Vec2(); + const b2ShapeCast_s_p = new b2Vec2(); + const b2ShapeCast_s_pointA = new b2Vec2(); + const b2ShapeCast_s_pointB = new b2Vec2(); + function b2ShapeCast(output, input) { + output.iterations = 0; + output.lambda = 1.0; + output.normal.SetZero(); + output.point.SetZero(); + // const b2DistanceProxy* proxyA = &input.proxyA; + const proxyA = input.proxyA; + // const b2DistanceProxy* proxyB = &input.proxyB; + const proxyB = input.proxyB; + // float32 radiusA = b2Max(proxyA.m_radius, b2_polygonRadius); + const radiusA = b2Max(proxyA.m_radius, b2_polygonRadius); + // float32 radiusB = b2Max(proxyB.m_radius, b2_polygonRadius); + const radiusB = b2Max(proxyB.m_radius, b2_polygonRadius); + // float32 radius = radiusA + radiusB; + const radius = radiusA + radiusB; + // b2Transform xfA = input.transformA; + const xfA = input.transformA; + // b2Transform xfB = input.transformB; + const xfB = input.transformB; + // b2Vec2 r = input.translationB; + const r = input.translationB; + // b2Vec2 n(0.0f, 0.0f); + const n = b2ShapeCast_s_n.Set(0.0, 0.0); + // float32 lambda = 0.0f; + let lambda = 0.0; + // Initial simplex + const simplex = b2ShapeCast_s_simplex; + simplex.m_count = 0; + // Get simplex vertices as an array. + // b2SimplexVertex* vertices = &simplex.m_v1; + const vertices = simplex.m_vertices; + // Get support point in -r direction + // int32 indexA = proxyA.GetSupport(b2MulT(xfA.q, -r)); + let indexA = proxyA.GetSupport(b2Rot.MulTRV(xfA.q, b2Vec2.NegV(r, b2Vec2.s_t1), b2Vec2.s_t0)); + // b2Vec2 wA = b2Mul(xfA, proxyA.GetVertex(indexA)); + let wA = b2Transform.MulXV(xfA, proxyA.GetVertex(indexA), b2ShapeCast_s_wA); + // int32 indexB = proxyB.GetSupport(b2MulT(xfB.q, r)); + let indexB = proxyB.GetSupport(b2Rot.MulTRV(xfB.q, r, b2Vec2.s_t0)); + // b2Vec2 wB = b2Mul(xfB, proxyB.GetVertex(indexB)); + let wB = b2Transform.MulXV(xfB, proxyB.GetVertex(indexB), b2ShapeCast_s_wB); + // b2Vec2 v = wA - wB; + const v = b2Vec2.SubVV(wA, wB, b2ShapeCast_s_v); + // Sigma is the target distance between polygons + // float32 sigma = b2Max(b2_polygonRadius, radius - b2_polygonRadius); + const sigma = b2Max(b2_polygonRadius, radius - b2_polygonRadius); + // const float32 tolerance = 0.5f * b2_linearSlop; + const tolerance = 0.5 * b2_linearSlop; + // Main iteration loop. + // const int32 k_maxIters = 20; + const k_maxIters = 20; + // int32 iter = 0; + let iter = 0; + // while (iter < k_maxIters && v.Length() - sigma > tolerance) + while (iter < k_maxIters && v.Length() - sigma > tolerance) { + // DEBUG: b2Assert(simplex.m_count < 3); + output.iterations += 1; + // Support in direction -v (A - B) + // indexA = proxyA.GetSupport(b2MulT(xfA.q, -v)); + indexA = proxyA.GetSupport(b2Rot.MulTRV(xfA.q, b2Vec2.NegV(v, b2Vec2.s_t1), b2Vec2.s_t0)); + // wA = b2Mul(xfA, proxyA.GetVertex(indexA)); + wA = b2Transform.MulXV(xfA, proxyA.GetVertex(indexA), b2ShapeCast_s_wA); + // indexB = proxyB.GetSupport(b2MulT(xfB.q, v)); + indexB = proxyB.GetSupport(b2Rot.MulTRV(xfB.q, v, b2Vec2.s_t0)); + // wB = b2Mul(xfB, proxyB.GetVertex(indexB)); + wB = b2Transform.MulXV(xfB, proxyB.GetVertex(indexB), b2ShapeCast_s_wB); + // b2Vec2 p = wA - wB; + const p = b2Vec2.SubVV(wA, wB, b2ShapeCast_s_p); + // -v is a normal at p + v.Normalize(); + // Intersect ray with plane + const vp = b2Vec2.DotVV(v, p); + const vr = b2Vec2.DotVV(v, r); + if (vp - sigma > lambda * vr) { + if (vr <= 0.0) { + return false; + } + lambda = (vp - sigma) / vr; + if (lambda > 1.0) { + return false; + } + // n = -v; + n.Copy(v).SelfNeg(); + simplex.m_count = 0; + } + // Reverse simplex since it works with B - A. + // Shift by lambda * r because we want the closest point to the current clip point. + // Note that the support point p is not shifted because we want the plane equation + // to be formed in unshifted space. + // b2SimplexVertex* vertex = vertices + simplex.m_count; + const vertex = vertices[simplex.m_count]; + vertex.indexA = indexB; + // vertex.wA = wB + lambda * r; + vertex.wA.Copy(wB).SelfMulAdd(lambda, r); + vertex.indexB = indexA; + // vertex.wB = wA; + vertex.wB.Copy(wA); + // vertex.w = vertex.wB - vertex.wA; + vertex.w.Copy(vertex.wB).SelfSub(vertex.wA); + vertex.a = 1.0; + simplex.m_count += 1; + switch (simplex.m_count) { + case 1: + break; + case 2: + simplex.Solve2(); + break; + case 3: + simplex.Solve3(); + break; + // DEBUG: b2Assert(false); + } + // If we have 3 points, then the origin is in the corresponding triangle. + if (simplex.m_count === 3) { + // Overlap + return false; + } + // Get search direction. + // v = simplex.GetClosestPoint(); + simplex.GetClosestPoint(v); + // Iteration count is equated to the number of support point calls. + ++iter; + } + if (iter === 0) { + // Initial overlap + return false; + } + // Prepare output. + const pointA = b2ShapeCast_s_pointA; + const pointB = b2ShapeCast_s_pointB; + simplex.GetWitnessPoints(pointA, pointB); + if (v.LengthSquared() > 0.0) { + // n = -v; + n.Copy(v).SelfNeg(); + n.Normalize(); + } + // output.point = pointA + radiusA * n; + output.normal.Copy(n); + output.lambda = lambda; + output.iterations = iter; + return true; + } + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// @file + /// Structures and functions used for computing contact points, distance + /// queries, and TOI queries. + exports.b2ContactFeatureType = void 0; + (function (b2ContactFeatureType) { + b2ContactFeatureType[b2ContactFeatureType["e_vertex"] = 0] = "e_vertex"; + b2ContactFeatureType[b2ContactFeatureType["e_face"] = 1] = "e_face"; + })(exports.b2ContactFeatureType || (exports.b2ContactFeatureType = {})); + /// The features that intersect to form the contact point + /// This must be 4 bytes or less. + class b2ContactFeature { + constructor() { + this._key = 0; + this._key_invalid = false; + this._indexA = 0; + this._indexB = 0; + this._typeA = 0; + this._typeB = 0; + } + get key() { + if (this._key_invalid) { + this._key_invalid = false; + this._key = this._indexA | (this._indexB << 8) | (this._typeA << 16) | (this._typeB << 24); + } + return this._key; + } + set key(value) { + this._key = value; + this._key_invalid = false; + this._indexA = this._key & 0xff; + this._indexB = (this._key >> 8) & 0xff; + this._typeA = (this._key >> 16) & 0xff; + this._typeB = (this._key >> 24) & 0xff; + } + get indexA() { + return this._indexA; + } + set indexA(value) { + this._indexA = value; + this._key_invalid = true; + } + get indexB() { + return this._indexB; + } + set indexB(value) { + this._indexB = value; + this._key_invalid = true; + } + get typeA() { + return this._typeA; + } + set typeA(value) { + this._typeA = value; + this._key_invalid = true; + } + get typeB() { + return this._typeB; + } + set typeB(value) { + this._typeB = value; + this._key_invalid = true; + } + } + /// Contact ids to facilitate warm starting. + class b2ContactID { + constructor() { + this.cf = new b2ContactFeature(); + } + Copy(o) { + this.key = o.key; + return this; + } + Clone() { + return new b2ContactID().Copy(this); + } + get key() { + return this.cf.key; + } + set key(value) { + this.cf.key = value; + } + } + /// A manifold point is a contact point belonging to a contact + /// manifold. It holds details related to the geometry and dynamics + /// of the contact points. + /// The local point usage depends on the manifold type: + /// -e_circles: the local center of circleB + /// -e_faceA: the local center of cirlceB or the clip point of polygonB + /// -e_faceB: the clip point of polygonA + /// This structure is stored across time steps, so we keep it small. + /// Note: the impulses are used for internal caching and may not + /// provide reliable contact forces, especially for high speed collisions. + class b2ManifoldPoint { + constructor() { + this.localPoint = new b2Vec2(); ///< usage depends on manifold type + this.normalImpulse = 0; ///< the non-penetration impulse + this.tangentImpulse = 0; ///< the friction impulse + this.id = new b2ContactID(); ///< uniquely identifies a contact point between two shapes + } + static MakeArray(length) { + return b2MakeArray(length, (i) => new b2ManifoldPoint()); + } + Reset() { + this.localPoint.SetZero(); + this.normalImpulse = 0; + this.tangentImpulse = 0; + this.id.key = 0; + } + Copy(o) { + this.localPoint.Copy(o.localPoint); + this.normalImpulse = o.normalImpulse; + this.tangentImpulse = o.tangentImpulse; + this.id.Copy(o.id); + return this; + } + } + exports.b2ManifoldType = void 0; + (function (b2ManifoldType) { + b2ManifoldType[b2ManifoldType["e_unknown"] = -1] = "e_unknown"; + b2ManifoldType[b2ManifoldType["e_circles"] = 0] = "e_circles"; + b2ManifoldType[b2ManifoldType["e_faceA"] = 1] = "e_faceA"; + b2ManifoldType[b2ManifoldType["e_faceB"] = 2] = "e_faceB"; + })(exports.b2ManifoldType || (exports.b2ManifoldType = {})); + /// A manifold for two touching convex shapes. + /// Box2D supports multiple types of contact: + /// - clip point versus plane with radius + /// - point versus point with radius (circles) + /// The local point usage depends on the manifold type: + /// -e_circles: the local center of circleA + /// -e_faceA: the center of faceA + /// -e_faceB: the center of faceB + /// Similarly the local normal usage: + /// -e_circles: not used + /// -e_faceA: the normal on polygonA + /// -e_faceB: the normal on polygonB + /// We store contacts in this way so that position correction can + /// account for movement, which is critical for continuous physics. + /// All contact scenarios must be expressed in one of these types. + /// This structure is stored across time steps, so we keep it small. + class b2Manifold { + constructor() { + this.points = b2ManifoldPoint.MakeArray(b2_maxManifoldPoints); + this.localNormal = new b2Vec2(); + this.localPoint = new b2Vec2(); + this.type = exports.b2ManifoldType.e_unknown; + this.pointCount = 0; + } + Reset() { + for (let i = 0; i < b2_maxManifoldPoints; ++i) { + // DEBUG: b2Assert(this.points[i] instanceof b2ManifoldPoint); + this.points[i].Reset(); + } + this.localNormal.SetZero(); + this.localPoint.SetZero(); + this.type = exports.b2ManifoldType.e_unknown; + this.pointCount = 0; + } + Copy(o) { + this.pointCount = o.pointCount; + for (let i = 0; i < b2_maxManifoldPoints; ++i) { + // DEBUG: b2Assert(this.points[i] instanceof b2ManifoldPoint); + this.points[i].Copy(o.points[i]); + } + this.localNormal.Copy(o.localNormal); + this.localPoint.Copy(o.localPoint); + this.type = o.type; + return this; + } + Clone() { + return new b2Manifold().Copy(this); + } + } + class b2WorldManifold { + constructor() { + this.normal = new b2Vec2(); + this.points = b2Vec2.MakeArray(b2_maxManifoldPoints); + this.separations = b2MakeNumberArray(b2_maxManifoldPoints); + } + Initialize(manifold, xfA, radiusA, xfB, radiusB) { + if (manifold.pointCount === 0) { + return; + } + switch (manifold.type) { + case exports.b2ManifoldType.e_circles: { + this.normal.Set(1, 0); + const pointA = b2Transform.MulXV(xfA, manifold.localPoint, b2WorldManifold.Initialize_s_pointA); + const pointB = b2Transform.MulXV(xfB, manifold.points[0].localPoint, b2WorldManifold.Initialize_s_pointB); + if (b2Vec2.DistanceSquaredVV(pointA, pointB) > b2_epsilon_sq) { + b2Vec2.SubVV(pointB, pointA, this.normal).SelfNormalize(); + } + const cA = b2Vec2.AddVMulSV(pointA, radiusA, this.normal, b2WorldManifold.Initialize_s_cA); + const cB = b2Vec2.SubVMulSV(pointB, radiusB, this.normal, b2WorldManifold.Initialize_s_cB); + b2Vec2.MidVV(cA, cB, this.points[0]); + this.separations[0] = b2Vec2.DotVV(b2Vec2.SubVV(cB, cA, b2Vec2.s_t0), this.normal); // b2Dot(cB - cA, normal); + break; + } + case exports.b2ManifoldType.e_faceA: { + b2Rot.MulRV(xfA.q, manifold.localNormal, this.normal); + const planePoint = b2Transform.MulXV(xfA, manifold.localPoint, b2WorldManifold.Initialize_s_planePoint); + for (let i = 0; i < manifold.pointCount; ++i) { + const clipPoint = b2Transform.MulXV(xfB, manifold.points[i].localPoint, b2WorldManifold.Initialize_s_clipPoint); + const s = radiusA - b2Vec2.DotVV(b2Vec2.SubVV(clipPoint, planePoint, b2Vec2.s_t0), this.normal); + const cA = b2Vec2.AddVMulSV(clipPoint, s, this.normal, b2WorldManifold.Initialize_s_cA); + const cB = b2Vec2.SubVMulSV(clipPoint, radiusB, this.normal, b2WorldManifold.Initialize_s_cB); + b2Vec2.MidVV(cA, cB, this.points[i]); + this.separations[i] = b2Vec2.DotVV(b2Vec2.SubVV(cB, cA, b2Vec2.s_t0), this.normal); // b2Dot(cB - cA, normal); + } + break; + } + case exports.b2ManifoldType.e_faceB: { + b2Rot.MulRV(xfB.q, manifold.localNormal, this.normal); + const planePoint = b2Transform.MulXV(xfB, manifold.localPoint, b2WorldManifold.Initialize_s_planePoint); + for (let i = 0; i < manifold.pointCount; ++i) { + const clipPoint = b2Transform.MulXV(xfA, manifold.points[i].localPoint, b2WorldManifold.Initialize_s_clipPoint); + const s = radiusB - b2Vec2.DotVV(b2Vec2.SubVV(clipPoint, planePoint, b2Vec2.s_t0), this.normal); + const cB = b2Vec2.AddVMulSV(clipPoint, s, this.normal, b2WorldManifold.Initialize_s_cB); + const cA = b2Vec2.SubVMulSV(clipPoint, radiusA, this.normal, b2WorldManifold.Initialize_s_cA); + b2Vec2.MidVV(cA, cB, this.points[i]); + this.separations[i] = b2Vec2.DotVV(b2Vec2.SubVV(cA, cB, b2Vec2.s_t0), this.normal); // b2Dot(cA - cB, normal); + } + // Ensure normal points from A to B. + this.normal.SelfNeg(); + break; + } + } + } + } + b2WorldManifold.Initialize_s_pointA = new b2Vec2(); + b2WorldManifold.Initialize_s_pointB = new b2Vec2(); + b2WorldManifold.Initialize_s_cA = new b2Vec2(); + b2WorldManifold.Initialize_s_cB = new b2Vec2(); + b2WorldManifold.Initialize_s_planePoint = new b2Vec2(); + b2WorldManifold.Initialize_s_clipPoint = new b2Vec2(); + /// This is used for determining the state of contact points. + exports.b2PointState = void 0; + (function (b2PointState) { + b2PointState[b2PointState["b2_nullState"] = 0] = "b2_nullState"; + b2PointState[b2PointState["b2_addState"] = 1] = "b2_addState"; + b2PointState[b2PointState["b2_persistState"] = 2] = "b2_persistState"; + b2PointState[b2PointState["b2_removeState"] = 3] = "b2_removeState"; + })(exports.b2PointState || (exports.b2PointState = {})); + /// Compute the point states given two manifolds. The states pertain to the transition from manifold1 + /// to manifold2. So state1 is either persist or remove while state2 is either add or persist. + function b2GetPointStates(state1, state2, manifold1, manifold2) { + // Detect persists and removes. + let i; + for (i = 0; i < manifold1.pointCount; ++i) { + const id = manifold1.points[i].id; + const key = id.key; + state1[i] = exports.b2PointState.b2_removeState; + for (let j = 0, jct = manifold2.pointCount; j < jct; ++j) { + if (manifold2.points[j].id.key === key) { + state1[i] = exports.b2PointState.b2_persistState; + break; + } + } + } + for (; i < b2_maxManifoldPoints; ++i) { + state1[i] = exports.b2PointState.b2_nullState; + } + // Detect persists and adds. + for (i = 0; i < manifold2.pointCount; ++i) { + const id = manifold2.points[i].id; + const key = id.key; + state2[i] = exports.b2PointState.b2_addState; + for (let j = 0, jct = manifold1.pointCount; j < jct; ++j) { + if (manifold1.points[j].id.key === key) { + state2[i] = exports.b2PointState.b2_persistState; + break; + } + } + } + for (; i < b2_maxManifoldPoints; ++i) { + state2[i] = exports.b2PointState.b2_nullState; + } + } + /// Used for computing contact manifolds. + class b2ClipVertex { + constructor() { + this.v = new b2Vec2(); + this.id = new b2ContactID(); + } + static MakeArray(length) { + return b2MakeArray(length, (i) => new b2ClipVertex()); + } + Copy(other) { + this.v.Copy(other.v); + this.id.Copy(other.id); + return this; + } + } + /// Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1). + class b2RayCastInput { + constructor() { + this.p1 = new b2Vec2(); + this.p2 = new b2Vec2(); + this.maxFraction = 1; + } + Copy(o) { + this.p1.Copy(o.p1); + this.p2.Copy(o.p2); + this.maxFraction = o.maxFraction; + return this; + } + } + /// Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2 + /// come from b2RayCastInput. + class b2RayCastOutput { + constructor() { + this.normal = new b2Vec2(); + this.fraction = 0; + } + Copy(o) { + this.normal.Copy(o.normal); + this.fraction = o.fraction; + return this; + } + } + /// An axis aligned bounding box. + class b2AABB { + constructor() { + this.lowerBound = new b2Vec2(); ///< the lower vertex + this.upperBound = new b2Vec2(); ///< the upper vertex + this.m_cache_center = new b2Vec2(); // access using GetCenter() + this.m_cache_extent = new b2Vec2(); // access using GetExtents() + } + Copy(o) { + this.lowerBound.Copy(o.lowerBound); + this.upperBound.Copy(o.upperBound); + return this; + } + /// Verify that the bounds are sorted. + IsValid() { + if (!this.lowerBound.IsValid()) { + return false; + } + if (!this.upperBound.IsValid()) { + return false; + } + if (this.upperBound.x < this.lowerBound.x) { + return false; + } + if (this.upperBound.y < this.lowerBound.y) { + return false; + } + return true; + } + /// Get the center of the AABB. + GetCenter() { + return b2Vec2.MidVV(this.lowerBound, this.upperBound, this.m_cache_center); + } + /// Get the extents of the AABB (half-widths). + GetExtents() { + return b2Vec2.ExtVV(this.lowerBound, this.upperBound, this.m_cache_extent); + } + /// Get the perimeter length + GetPerimeter() { + const wx = this.upperBound.x - this.lowerBound.x; + const wy = this.upperBound.y - this.lowerBound.y; + return 2 * (wx + wy); + } + /// Combine an AABB into this one. + Combine1(aabb) { + this.lowerBound.x = b2Min(this.lowerBound.x, aabb.lowerBound.x); + this.lowerBound.y = b2Min(this.lowerBound.y, aabb.lowerBound.y); + this.upperBound.x = b2Max(this.upperBound.x, aabb.upperBound.x); + this.upperBound.y = b2Max(this.upperBound.y, aabb.upperBound.y); + return this; + } + /// Combine two AABBs into this one. + Combine2(aabb1, aabb2) { + this.lowerBound.x = b2Min(aabb1.lowerBound.x, aabb2.lowerBound.x); + this.lowerBound.y = b2Min(aabb1.lowerBound.y, aabb2.lowerBound.y); + this.upperBound.x = b2Max(aabb1.upperBound.x, aabb2.upperBound.x); + this.upperBound.y = b2Max(aabb1.upperBound.y, aabb2.upperBound.y); + return this; + } + static Combine(aabb1, aabb2, out) { + out.Combine2(aabb1, aabb2); + return out; + } + /// Does this aabb contain the provided AABB. + Contains(aabb) { + let result = true; + result = result && this.lowerBound.x <= aabb.lowerBound.x; + result = result && this.lowerBound.y <= aabb.lowerBound.y; + result = result && aabb.upperBound.x <= this.upperBound.x; + result = result && aabb.upperBound.y <= this.upperBound.y; + return result; + } + // From Real-time Collision Detection, p179. + RayCast(output, input) { + let tmin = (-b2_maxFloat); + let tmax = b2_maxFloat; + const p_x = input.p1.x; + const p_y = input.p1.y; + const d_x = input.p2.x - input.p1.x; + const d_y = input.p2.y - input.p1.y; + const absD_x = b2Abs(d_x); + const absD_y = b2Abs(d_y); + const normal = output.normal; + if (absD_x < b2_epsilon) { + // Parallel. + if (p_x < this.lowerBound.x || this.upperBound.x < p_x) { + return false; + } + } + else { + const inv_d = 1 / d_x; + let t1 = (this.lowerBound.x - p_x) * inv_d; + let t2 = (this.upperBound.x - p_x) * inv_d; + // Sign of the normal vector. + let s = (-1); + if (t1 > t2) { + const t3 = t1; + t1 = t2; + t2 = t3; + s = 1; + } + // Push the min up + if (t1 > tmin) { + normal.x = s; + normal.y = 0; + tmin = t1; + } + // Pull the max down + tmax = b2Min(tmax, t2); + if (tmin > tmax) { + return false; + } + } + if (absD_y < b2_epsilon) { + // Parallel. + if (p_y < this.lowerBound.y || this.upperBound.y < p_y) { + return false; + } + } + else { + const inv_d = 1 / d_y; + let t1 = (this.lowerBound.y - p_y) * inv_d; + let t2 = (this.upperBound.y - p_y) * inv_d; + // Sign of the normal vector. + let s = (-1); + if (t1 > t2) { + const t3 = t1; + t1 = t2; + t2 = t3; + s = 1; + } + // Push the min up + if (t1 > tmin) { + normal.x = 0; + normal.y = s; + tmin = t1; + } + // Pull the max down + tmax = b2Min(tmax, t2); + if (tmin > tmax) { + return false; + } + } + // Does the ray start inside the box? + // Does the ray intersect beyond the max fraction? + if (tmin < 0 || input.maxFraction < tmin) { + return false; + } + // Intersection. + output.fraction = tmin; + return true; + } + TestContain(point) { + if (point.x < this.lowerBound.x || this.upperBound.x < point.x) { + return false; + } + if (point.y < this.lowerBound.y || this.upperBound.y < point.y) { + return false; + } + return true; + } + TestOverlap(other) { + if (this.upperBound.x < other.lowerBound.x) { + return false; + } + if (this.upperBound.y < other.lowerBound.y) { + return false; + } + if (other.upperBound.x < this.lowerBound.x) { + return false; + } + if (other.upperBound.y < this.lowerBound.y) { + return false; + } + return true; + } + } + function b2TestOverlapAABB(a, b) { + if (a.upperBound.x < b.lowerBound.x) { + return false; + } + if (a.upperBound.y < b.lowerBound.y) { + return false; + } + if (b.upperBound.x < a.lowerBound.x) { + return false; + } + if (b.upperBound.y < a.lowerBound.y) { + return false; + } + return true; + } + /// Clipping for contact manifolds. + function b2ClipSegmentToLine(vOut, vIn, normal, offset, vertexIndexA) { + // Start with no output points + let count = 0; + const vIn0 = vIn[0]; + const vIn1 = vIn[1]; + // Calculate the distance of end points to the line + const distance0 = b2Vec2.DotVV(normal, vIn0.v) - offset; + const distance1 = b2Vec2.DotVV(normal, vIn1.v) - offset; + // If the points are behind the plane + if (distance0 <= 0) { + vOut[count++].Copy(vIn0); + } + if (distance1 <= 0) { + vOut[count++].Copy(vIn1); + } + // If the points are on different sides of the plane + if (distance0 * distance1 < 0) { + // Find intersection point of edge and plane + const interp = distance0 / (distance0 - distance1); + const v = vOut[count].v; + v.x = vIn0.v.x + interp * (vIn1.v.x - vIn0.v.x); + v.y = vIn0.v.y + interp * (vIn1.v.y - vIn0.v.y); + // VertexA is hitting edgeB. + const id = vOut[count].id; + id.cf.indexA = vertexIndexA; + id.cf.indexB = vIn0.id.cf.indexB; + id.cf.typeA = exports.b2ContactFeatureType.e_vertex; + id.cf.typeB = exports.b2ContactFeatureType.e_face; + ++count; + // b2Assert(count === 2); + } + return count; + } + /// Determine if two generic shapes overlap. + const b2TestOverlapShape_s_input = new b2DistanceInput(); + const b2TestOverlapShape_s_simplexCache = new b2SimplexCache(); + const b2TestOverlapShape_s_output = new b2DistanceOutput(); + function b2TestOverlapShape(shapeA, indexA, shapeB, indexB, xfA, xfB) { + const input = b2TestOverlapShape_s_input.Reset(); + input.proxyA.SetShape(shapeA, indexA); + input.proxyB.SetShape(shapeB, indexB); + input.transformA.Copy(xfA); + input.transformB.Copy(xfB); + input.useRadii = true; + const simplexCache = b2TestOverlapShape_s_simplexCache.Reset(); + simplexCache.count = 0; + const output = b2TestOverlapShape_s_output.Reset(); + b2Distance(output, simplexCache, input); + return output.distance < 10 * b2_epsilon; + } + + /* + * Copyright (c) 2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + function verify(value) { + if (value === null) { + throw new Error(); + } + return value; + } + /// A node in the dynamic tree. The client does not interact with this directly. + class b2TreeNode { + constructor(id = 0) { + this.m_id = 0; + this.aabb = new b2AABB(); + this._userData = null; + this.parent = null; // or next + this.child1 = null; + this.child2 = null; + this.height = 0; // leaf = 0, free node = -1 + this.moved = false; + this.m_id = id; + } + get userData() { + if (this._userData === null) { + throw new Error(); + } + return this._userData; + } + set userData(value) { + if (this._userData !== null) { + throw new Error(); + } + this._userData = value; + } + Reset() { + this._userData = null; + } + IsLeaf() { + return this.child1 === null; + } + } + class b2DynamicTree { + constructor() { + this.m_root = null; + // b2TreeNode* public m_nodes; + // int32 public m_nodeCount; + // int32 public m_nodeCapacity; + this.m_freeList = null; + this.m_insertionCount = 0; + this.m_stack = new b2GrowableStack(256); + } + Query(...args) { + let aabb, callback; + if (args[0] instanceof b2AABB) { + aabb = args[0]; + callback = args[1]; + } + else { + aabb = args[1]; + callback = args[0]; + } + const stack = this.m_stack.Reset(); + stack.Push(this.m_root); + while (stack.GetCount() > 0) { + const node = stack.Pop(); + if (node === null) { + continue; + } + if (node.aabb.TestOverlap(aabb)) { + if (node.IsLeaf()) { + const proceed = callback(node); + if (!proceed) { + return; + } + } + else { + stack.Push(node.child1); + stack.Push(node.child2); + } + } + } + } + QueryPoint(point, callback) { + const stack = this.m_stack.Reset(); + stack.Push(this.m_root); + while (stack.GetCount() > 0) { + const node = stack.Pop(); + if (node === null) { + continue; + } + if (node.aabb.TestContain(point)) { + if (node.IsLeaf()) { + const proceed = callback(node); + if (!proceed) { + return; + } + } + else { + stack.Push(node.child1); + stack.Push(node.child2); + } + } + } + } + RayCast(...args) { + let callback, input; + if (args[0] instanceof b2RayCastInput) { + input = args[0]; + callback = args[1]; + } + else { + input = args[1]; + callback = args[0]; + } + const p1 = input.p1; + const p2 = input.p2; + const r = b2Vec2.SubVV(p2, p1, b2DynamicTree.s_r); + // DEBUG: b2Assert(r.LengthSquared() > 0); + r.Normalize(); + // v is perpendicular to the segment. + const v = b2Vec2.CrossOneV(r, b2DynamicTree.s_v); + const abs_v = b2Vec2.AbsV(v, b2DynamicTree.s_abs_v); + // Separating axis for segment (Gino, p80). + // |dot(v, p1 - c)| > dot(|v|, h) + let maxFraction = input.maxFraction; + // Build a bounding box for the segment. + const segmentAABB = b2DynamicTree.s_segmentAABB; + let t_x = p1.x + maxFraction * (p2.x - p1.x); + let t_y = p1.y + maxFraction * (p2.y - p1.y); + segmentAABB.lowerBound.x = b2Min(p1.x, t_x); + segmentAABB.lowerBound.y = b2Min(p1.y, t_y); + segmentAABB.upperBound.x = b2Max(p1.x, t_x); + segmentAABB.upperBound.y = b2Max(p1.y, t_y); + const stack = this.m_stack.Reset(); + stack.Push(this.m_root); + while (stack.GetCount() > 0) { + const node = stack.Pop(); + if (node === null) { + continue; + } + if (!b2TestOverlapAABB(node.aabb, segmentAABB)) { + continue; + } + // Separating axis for segment (Gino, p80). + // |dot(v, p1 - c)| > dot(|v|, h) + const c = node.aabb.GetCenter(); + const h = node.aabb.GetExtents(); + const separation = b2Abs(b2Vec2.DotVV(v, b2Vec2.SubVV(p1, c, b2Vec2.s_t0))) - b2Vec2.DotVV(abs_v, h); + if (separation > 0) { + continue; + } + if (node.IsLeaf()) { + const subInput = b2DynamicTree.s_subInput; + subInput.p1.Copy(input.p1); + subInput.p2.Copy(input.p2); + subInput.maxFraction = maxFraction; + const value = callback(subInput, node); + if (value === 0) { + // The client has terminated the ray cast. + return; + } + if (value > 0) { + // Update segment bounding box. + maxFraction = value; + t_x = p1.x + maxFraction * (p2.x - p1.x); + t_y = p1.y + maxFraction * (p2.y - p1.y); + segmentAABB.lowerBound.x = b2Min(p1.x, t_x); + segmentAABB.lowerBound.y = b2Min(p1.y, t_y); + segmentAABB.upperBound.x = b2Max(p1.x, t_x); + segmentAABB.upperBound.y = b2Max(p1.y, t_y); + } + } + else { + stack.Push(node.child1); + stack.Push(node.child2); + } + } + } + AllocateNode() { + // Expand the node pool as needed. + if (this.m_freeList !== null) { + const node = this.m_freeList; + this.m_freeList = node.parent; // this.m_freeList = node.next; + node.parent = null; + node.child1 = null; + node.child2 = null; + node.height = 0; + node.moved = false; + return node; + } + return new b2TreeNode(b2DynamicTree.s_node_id++); + } + FreeNode(node) { + node.parent = this.m_freeList; // node.next = this.m_freeList; + node.child1 = null; + node.child2 = null; + node.height = -1; + node.Reset(); + this.m_freeList = node; + } + CreateProxy(aabb, userData) { + const node = this.AllocateNode(); + // Fatten the aabb. + const r_x = b2_aabbExtension; + const r_y = b2_aabbExtension; + node.aabb.lowerBound.x = aabb.lowerBound.x - r_x; + node.aabb.lowerBound.y = aabb.lowerBound.y - r_y; + node.aabb.upperBound.x = aabb.upperBound.x + r_x; + node.aabb.upperBound.y = aabb.upperBound.y + r_y; + node.userData = userData; + node.height = 0; + node.moved = true; + this.InsertLeaf(node); + return node; + } + DestroyProxy(node) { + // DEBUG: b2Assert(node.IsLeaf()); + this.RemoveLeaf(node); + this.FreeNode(node); + } + MoveProxy(node, aabb, displacement) { + // DEBUG: b2Assert(node.IsLeaf()); + // Extend AABB + const fatAABB = b2DynamicTree.MoveProxy_s_fatAABB; + const r_x = b2_aabbExtension; + const r_y = b2_aabbExtension; + fatAABB.lowerBound.x = aabb.lowerBound.x - r_x; + fatAABB.lowerBound.y = aabb.lowerBound.y - r_y; + fatAABB.upperBound.x = aabb.upperBound.x + r_x; + fatAABB.upperBound.y = aabb.upperBound.y + r_y; + // Predict AABB movement + const d_x = b2_aabbMultiplier * displacement.x; + const d_y = b2_aabbMultiplier * displacement.y; + if (d_x < 0.0) { + fatAABB.lowerBound.x += d_x; + } + else { + fatAABB.upperBound.x += d_x; + } + if (d_y < 0.0) { + fatAABB.lowerBound.y += d_y; + } + else { + fatAABB.upperBound.y += d_y; + } + const treeAABB = node.aabb; // m_nodes[proxyId].aabb; + if (treeAABB.Contains(aabb)) { + // The tree AABB still contains the object, but it might be too large. + // Perhaps the object was moving fast but has since gone to sleep. + // The huge AABB is larger than the new fat AABB. + const hugeAABB = b2DynamicTree.MoveProxy_s_hugeAABB; + hugeAABB.lowerBound.x = fatAABB.lowerBound.x - 4.0 * r_x; + hugeAABB.lowerBound.y = fatAABB.lowerBound.y - 4.0 * r_y; + hugeAABB.upperBound.x = fatAABB.upperBound.x + 4.0 * r_x; + hugeAABB.upperBound.y = fatAABB.upperBound.y + 4.0 * r_y; + if (hugeAABB.Contains(treeAABB)) { + // The tree AABB contains the object AABB and the tree AABB is + // not too large. No tree update needed. + return false; + } + // Otherwise the tree AABB is huge and needs to be shrunk + } + this.RemoveLeaf(node); + node.aabb.Copy(fatAABB); // m_nodes[proxyId].aabb = fatAABB; + this.InsertLeaf(node); + node.moved = true; + return true; + } + InsertLeaf(leaf) { + ++this.m_insertionCount; + if (this.m_root === null) { + this.m_root = leaf; + this.m_root.parent = null; + return; + } + // Find the best sibling for this node + const leafAABB = leaf.aabb; + let sibling = this.m_root; + while (!sibling.IsLeaf()) { + const child1 = verify(sibling.child1); + const child2 = verify(sibling.child2); + const area = sibling.aabb.GetPerimeter(); + const combinedAABB = b2DynamicTree.s_combinedAABB; + combinedAABB.Combine2(sibling.aabb, leafAABB); + const combinedArea = combinedAABB.GetPerimeter(); + // Cost of creating a new parent for this node and the new leaf + const cost = 2 * combinedArea; + // Minimum cost of pushing the leaf further down the tree + const inheritanceCost = 2 * (combinedArea - area); + // Cost of descending into child1 + let cost1; + const aabb = b2DynamicTree.s_aabb; + let oldArea; + let newArea; + if (child1.IsLeaf()) { + aabb.Combine2(leafAABB, child1.aabb); + cost1 = aabb.GetPerimeter() + inheritanceCost; + } + else { + aabb.Combine2(leafAABB, child1.aabb); + oldArea = child1.aabb.GetPerimeter(); + newArea = aabb.GetPerimeter(); + cost1 = (newArea - oldArea) + inheritanceCost; + } + // Cost of descending into child2 + let cost2; + if (child2.IsLeaf()) { + aabb.Combine2(leafAABB, child2.aabb); + cost2 = aabb.GetPerimeter() + inheritanceCost; + } + else { + aabb.Combine2(leafAABB, child2.aabb); + oldArea = child2.aabb.GetPerimeter(); + newArea = aabb.GetPerimeter(); + cost2 = newArea - oldArea + inheritanceCost; + } + // Descend according to the minimum cost. + if (cost < cost1 && cost < cost2) { + break; + } + // Descend + if (cost1 < cost2) { + sibling = child1; + } + else { + sibling = child2; + } + } + // Create a parent for the siblings. + const oldParent = sibling.parent; + const newParent = this.AllocateNode(); + newParent.parent = oldParent; + newParent.aabb.Combine2(leafAABB, sibling.aabb); + newParent.height = sibling.height + 1; + if (oldParent !== null) { + // The sibling was not the root. + if (oldParent.child1 === sibling) { + oldParent.child1 = newParent; + } + else { + oldParent.child2 = newParent; + } + newParent.child1 = sibling; + newParent.child2 = leaf; + sibling.parent = newParent; + leaf.parent = newParent; + } + else { + // The sibling was the root. + newParent.child1 = sibling; + newParent.child2 = leaf; + sibling.parent = newParent; + leaf.parent = newParent; + this.m_root = newParent; + } + // Walk back up the tree fixing heights and AABBs + let node = leaf.parent; + while (node !== null) { + node = this.Balance(node); + const child1 = verify(node.child1); + const child2 = verify(node.child2); + node.height = 1 + b2Max(child1.height, child2.height); + node.aabb.Combine2(child1.aabb, child2.aabb); + node = node.parent; + } + // this.Validate(); + } + RemoveLeaf(leaf) { + if (leaf === this.m_root) { + this.m_root = null; + return; + } + const parent = verify(leaf.parent); + const grandParent = parent && parent.parent; + const sibling = verify(parent.child1 === leaf ? parent.child2 : parent.child1); + if (grandParent !== null) { + // Destroy parent and connect sibling to grandParent. + if (grandParent.child1 === parent) { + grandParent.child1 = sibling; + } + else { + grandParent.child2 = sibling; + } + sibling.parent = grandParent; + this.FreeNode(parent); + // Adjust ancestor bounds. + let index = grandParent; + while (index !== null) { + index = this.Balance(index); + const child1 = verify(index.child1); + const child2 = verify(index.child2); + index.aabb.Combine2(child1.aabb, child2.aabb); + index.height = 1 + b2Max(child1.height, child2.height); + index = index.parent; + } + } + else { + this.m_root = sibling; + sibling.parent = null; + this.FreeNode(parent); + } + // this.Validate(); + } + Balance(A) { + // DEBUG: b2Assert(A !== null); + if (A.IsLeaf() || A.height < 2) { + return A; + } + const B = verify(A.child1); + const C = verify(A.child2); + const balance = C.height - B.height; + // Rotate C up + if (balance > 1) { + const F = verify(C.child1); + const G = verify(C.child2); + // Swap A and C + C.child1 = A; + C.parent = A.parent; + A.parent = C; + // A's old parent should point to C + if (C.parent !== null) { + if (C.parent.child1 === A) { + C.parent.child1 = C; + } + else { + // DEBUG: b2Assert(C.parent.child2 === A); + C.parent.child2 = C; + } + } + else { + this.m_root = C; + } + // Rotate + if (F.height > G.height) { + C.child2 = F; + A.child2 = G; + G.parent = A; + A.aabb.Combine2(B.aabb, G.aabb); + C.aabb.Combine2(A.aabb, F.aabb); + A.height = 1 + b2Max(B.height, G.height); + C.height = 1 + b2Max(A.height, F.height); + } + else { + C.child2 = G; + A.child2 = F; + F.parent = A; + A.aabb.Combine2(B.aabb, F.aabb); + C.aabb.Combine2(A.aabb, G.aabb); + A.height = 1 + b2Max(B.height, F.height); + C.height = 1 + b2Max(A.height, G.height); + } + return C; + } + // Rotate B up + if (balance < -1) { + const D = verify(B.child1); + const E = verify(B.child2); + // Swap A and B + B.child1 = A; + B.parent = A.parent; + A.parent = B; + // A's old parent should point to B + if (B.parent !== null) { + if (B.parent.child1 === A) { + B.parent.child1 = B; + } + else { + // DEBUG: b2Assert(B.parent.child2 === A); + B.parent.child2 = B; + } + } + else { + this.m_root = B; + } + // Rotate + if (D.height > E.height) { + B.child2 = D; + A.child1 = E; + E.parent = A; + A.aabb.Combine2(C.aabb, E.aabb); + B.aabb.Combine2(A.aabb, D.aabb); + A.height = 1 + b2Max(C.height, E.height); + B.height = 1 + b2Max(A.height, D.height); + } + else { + B.child2 = E; + A.child1 = D; + D.parent = A; + A.aabb.Combine2(C.aabb, D.aabb); + B.aabb.Combine2(A.aabb, E.aabb); + A.height = 1 + b2Max(C.height, D.height); + B.height = 1 + b2Max(A.height, E.height); + } + return B; + } + return A; + } + GetHeight() { + if (this.m_root === null) { + return 0; + } + return this.m_root.height; + } + static GetAreaNode(node) { + if (node === null) { + return 0; + } + if (node.IsLeaf()) { + return 0; + } + let area = node.aabb.GetPerimeter(); + area += b2DynamicTree.GetAreaNode(node.child1); + area += b2DynamicTree.GetAreaNode(node.child2); + return area; + } + GetAreaRatio() { + if (this.m_root === null) { + return 0; + } + const root = this.m_root; + const rootArea = root.aabb.GetPerimeter(); + const totalArea = b2DynamicTree.GetAreaNode(this.m_root); + /* + float32 totalArea = 0.0; + for (int32 i = 0; i < m_nodeCapacity; ++i) { + const b2TreeNode* node = m_nodes + i; + if (node.height < 0) { + // Free node in pool + continue; + } + + totalArea += node.aabb.GetPerimeter(); + } + */ + return totalArea / rootArea; + } + static ComputeHeightNode(node) { + if (node === null) { + return 0; + } + if (node.IsLeaf()) { + return 0; + } + const height1 = b2DynamicTree.ComputeHeightNode(node.child1); + const height2 = b2DynamicTree.ComputeHeightNode(node.child2); + return 1 + b2Max(height1, height2); + } + ComputeHeight() { + const height = b2DynamicTree.ComputeHeightNode(this.m_root); + return height; + } + ValidateStructure(node) { + if (node === null) { + return; + } + if (node === this.m_root) ; + if (node.IsLeaf()) { + // DEBUG: b2Assert(node.child1 === null); + // DEBUG: b2Assert(node.child2 === null); + // DEBUG: b2Assert(node.height === 0); + return; + } + const child1 = verify(node.child1); + const child2 = verify(node.child2); + // DEBUG: b2Assert(child1.parent === index); + // DEBUG: b2Assert(child2.parent === index); + this.ValidateStructure(child1); + this.ValidateStructure(child2); + } + ValidateMetrics(node) { + if (node === null) { + return; + } + if (node.IsLeaf()) { + // DEBUG: b2Assert(node.child1 === null); + // DEBUG: b2Assert(node.child2 === null); + // DEBUG: b2Assert(node.height === 0); + return; + } + const child1 = verify(node.child1); + const child2 = verify(node.child2); + // DEBUG: const height1: number = child1.height; + // DEBUG: const height2: number = child2.height; + // DEBUG: const height: number = 1 + b2Max(height1, height2); + // DEBUG: b2Assert(node.height === height); + const aabb = b2DynamicTree.s_aabb; + aabb.Combine2(child1.aabb, child2.aabb); + // DEBUG: b2Assert(aabb.lowerBound === node.aabb.lowerBound); + // DEBUG: b2Assert(aabb.upperBound === node.aabb.upperBound); + this.ValidateMetrics(child1); + this.ValidateMetrics(child2); + } + Validate() { + // DEBUG: this.ValidateStructure(this.m_root); + // DEBUG: this.ValidateMetrics(this.m_root); + // let freeCount: number = 0; + // let freeIndex: b2TreeNode | null = this.m_freeList; + // while (freeIndex !== null) { + // freeIndex = freeIndex.parent; // freeIndex = freeIndex.next; + // ++freeCount; + // } + // DEBUG: b2Assert(this.GetHeight() === this.ComputeHeight()); + // b2Assert(this.m_nodeCount + freeCount === this.m_nodeCapacity); + } + static GetMaxBalanceNode(node, maxBalance) { + if (node === null) { + return maxBalance; + } + if (node.height <= 1) { + return maxBalance; + } + // DEBUG: b2Assert(!node.IsLeaf()); + const child1 = verify(node.child1); + const child2 = verify(node.child2); + const balance = b2Abs(child2.height - child1.height); + return b2Max(maxBalance, balance); + } + GetMaxBalance() { + const maxBalance = b2DynamicTree.GetMaxBalanceNode(this.m_root, 0); + /* + int32 maxBalance = 0; + for (int32 i = 0; i < m_nodeCapacity; ++i) { + const b2TreeNode* node = m_nodes + i; + if (node.height <= 1) { + continue; + } + + b2Assert(!node.IsLeaf()); + + int32 child1 = node.child1; + int32 child2 = node.child2; + int32 balance = b2Abs(m_nodes[child2].height - m_nodes[child1].height); + maxBalance = b2Max(maxBalance, balance); + } + */ + return maxBalance; + } + RebuildBottomUp() { + /* + int32* nodes = (int32*)b2Alloc(m_nodeCount * sizeof(int32)); + int32 count = 0; + + // Build array of leaves. Free the rest. + for (int32 i = 0; i < m_nodeCapacity; ++i) { + if (m_nodes[i].height < 0) { + // free node in pool + continue; + } + + if (m_nodes[i].IsLeaf()) { + m_nodes[i].parent = b2_nullNode; + nodes[count] = i; + ++count; + } else { + FreeNode(i); + } + } + + while (count > 1) { + float32 minCost = b2_maxFloat; + int32 iMin = -1, jMin = -1; + for (int32 i = 0; i < count; ++i) { + b2AABB aabbi = m_nodes[nodes[i]].aabb; + + for (int32 j = i + 1; j < count; ++j) { + b2AABB aabbj = m_nodes[nodes[j]].aabb; + b2AABB b; + b.Combine(aabbi, aabbj); + float32 cost = b.GetPerimeter(); + if (cost < minCost) { + iMin = i; + jMin = j; + minCost = cost; + } + } + } + + int32 index1 = nodes[iMin]; + int32 index2 = nodes[jMin]; + b2TreeNode* child1 = m_nodes + index1; + b2TreeNode* child2 = m_nodes + index2; + + int32 parentIndex = AllocateNode(); + b2TreeNode* parent = m_nodes + parentIndex; + parent.child1 = index1; + parent.child2 = index2; + parent.height = 1 + b2Max(child1.height, child2.height); + parent.aabb.Combine(child1.aabb, child2.aabb); + parent.parent = b2_nullNode; + + child1.parent = parentIndex; + child2.parent = parentIndex; + + nodes[jMin] = nodes[count-1]; + nodes[iMin] = parentIndex; + --count; + } + + m_root = nodes[0]; + b2Free(nodes); + */ + this.Validate(); + } + static ShiftOriginNode(node, newOrigin) { + if (node === null) { + return; + } + if (node.height <= 1) { + return; + } + // DEBUG: b2Assert(!node.IsLeaf()); + const child1 = node.child1; + const child2 = node.child2; + b2DynamicTree.ShiftOriginNode(child1, newOrigin); + b2DynamicTree.ShiftOriginNode(child2, newOrigin); + node.aabb.lowerBound.SelfSub(newOrigin); + node.aabb.upperBound.SelfSub(newOrigin); + } + ShiftOrigin(newOrigin) { + b2DynamicTree.ShiftOriginNode(this.m_root, newOrigin); + /* + // Build array of leaves. Free the rest. + for (int32 i = 0; i < m_nodeCapacity; ++i) { + m_nodes[i].aabb.lowerBound -= newOrigin; + m_nodes[i].aabb.upperBound -= newOrigin; + } + */ + } + } + b2DynamicTree.s_r = new b2Vec2(); + b2DynamicTree.s_v = new b2Vec2(); + b2DynamicTree.s_abs_v = new b2Vec2(); + b2DynamicTree.s_segmentAABB = new b2AABB(); + b2DynamicTree.s_subInput = new b2RayCastInput(); + b2DynamicTree.s_combinedAABB = new b2AABB(); + b2DynamicTree.s_aabb = new b2AABB(); + b2DynamicTree.s_node_id = 0; + b2DynamicTree.MoveProxy_s_fatAABB = new b2AABB(); + b2DynamicTree.MoveProxy_s_hugeAABB = new b2AABB(); + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + class b2Pair { + constructor(proxyA, proxyB) { + this.proxyA = proxyA; + this.proxyB = proxyB; + } + } + /// The broad-phase is used for computing pairs and performing volume queries and ray casts. + /// This broad-phase does not persist pairs. Instead, this reports potentially new pairs. + /// It is up to the client to consume the new pairs and to track subsequent overlap. + class b2BroadPhase { + constructor() { + this.m_tree = new b2DynamicTree(); + this.m_proxyCount = 0; + // public m_moveCapacity: number = 16; + this.m_moveCount = 0; + this.m_moveBuffer = []; + // public m_pairCapacity: number = 16; + this.m_pairCount = 0; + this.m_pairBuffer = []; + } + // public m_queryProxyId: number = 0; + /// Create a proxy with an initial AABB. Pairs are not reported until + /// UpdatePairs is called. + CreateProxy(aabb, userData) { + const proxy = this.m_tree.CreateProxy(aabb, userData); + ++this.m_proxyCount; + this.BufferMove(proxy); + return proxy; + } + /// Destroy a proxy. It is up to the client to remove any pairs. + DestroyProxy(proxy) { + this.UnBufferMove(proxy); + --this.m_proxyCount; + this.m_tree.DestroyProxy(proxy); + } + /// Call MoveProxy as many times as you like, then when you are done + /// call UpdatePairs to finalized the proxy pairs (for your time step). + MoveProxy(proxy, aabb, displacement) { + const buffer = this.m_tree.MoveProxy(proxy, aabb, displacement); + if (buffer) { + this.BufferMove(proxy); + } + } + /// Call to trigger a re-processing of it's pairs on the next call to UpdatePairs. + TouchProxy(proxy) { + this.BufferMove(proxy); + } + /// Get the fat AABB for a proxy. + // public GetFatAABB(proxy: b2TreeNode): b2AABB { + // return this.m_tree.GetFatAABB(proxy); + // } + /// Get user data from a proxy. Returns NULL if the id is invalid. + // public GetUserData(proxy: b2TreeNode): T { + // return this.m_tree.GetUserData(proxy); + // } + /// Test overlap of fat AABBs. + // public TestOverlap(proxyA: b2TreeNode, proxyB: b2TreeNode): boolean { + // const aabbA: b2AABB = this.m_tree.GetFatAABB(proxyA); + // const aabbB: b2AABB = this.m_tree.GetFatAABB(proxyB); + // return b2TestOverlapAABB(aabbA, aabbB); + // } + /// Get the number of proxies. + GetProxyCount() { + return this.m_proxyCount; + } + /// Update the pairs. This results in pair callbacks. This can only add pairs. + UpdatePairs(callback) { + // Reset pair buffer + this.m_pairCount = 0; + // Perform tree queries for all moving proxies. + for (let i = 0; i < this.m_moveCount; ++i) { + const queryProxy = this.m_moveBuffer[i]; + if (queryProxy === null) { + continue; + } + // This is called from b2.DynamicTree::Query when we are gathering pairs. + // boolean b2BroadPhase::QueryCallback(int32 proxyId); + // We have to query the tree with the fat AABB so that + // we don't fail to create a pair that may touch later. + const fatAABB = queryProxy.aabb; // this.m_tree.GetFatAABB(queryProxy); + // Query tree, create pairs and add them pair buffer. + this.m_tree.Query(fatAABB, (proxy) => { + // A proxy cannot form a pair with itself. + if (proxy.m_id === queryProxy.m_id) { + return true; + } + const moved = proxy.moved; // this.m_tree.WasMoved(proxy); + if (moved && proxy.m_id > queryProxy.m_id) { + // Both proxies are moving. Avoid duplicate pairs. + return true; + } + // const proxyA = proxy < queryProxy ? proxy : queryProxy; + // const proxyB = proxy >= queryProxy ? proxy : queryProxy; + let proxyA; + let proxyB; + if (proxy.m_id < queryProxy.m_id) { + proxyA = proxy; + proxyB = queryProxy; + } + else { + proxyA = queryProxy; + proxyB = proxy; + } + // Grow the pair buffer as needed. + if (this.m_pairCount === this.m_pairBuffer.length) { + this.m_pairBuffer[this.m_pairCount] = new b2Pair(proxyA, proxyB); + } + else { + const pair = this.m_pairBuffer[this.m_pairCount]; + pair.proxyA = proxyA; + pair.proxyB = proxyB; + } + ++this.m_pairCount; + return true; + }); + } + // Send pairs to caller + for (let i = 0; i < this.m_pairCount; ++i) { + const primaryPair = this.m_pairBuffer[i]; + const userDataA = primaryPair.proxyA.userData; // this.m_tree.GetUserData(primaryPair.proxyA); + const userDataB = primaryPair.proxyB.userData; // this.m_tree.GetUserData(primaryPair.proxyB); + callback(userDataA, userDataB); + } + // Clear move flags + for (let i = 0; i < this.m_moveCount; ++i) { + const proxy = this.m_moveBuffer[i]; + if (proxy === null) { + continue; + } + proxy.moved = false; // this.m_tree.ClearMoved(proxy); + } + // Reset move buffer + this.m_moveCount = 0; + } + Query(...args) { + this.m_tree.Query(args[0], args[1]); + } + QueryPoint(point, callback) { + this.m_tree.QueryPoint(point, callback); + } + /// Ray-cast against the proxies in the tree. This relies on the callback + /// to perform a exact ray-cast in the case were the proxy contains a shape. + /// The callback also performs the any collision filtering. This has performance + /// roughly equal to k * log(n), where k is the number of collisions and n is the + /// number of proxies in the tree. + /// @param input the ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1). + /// @param callback a callback class that is called for each proxy that is hit by the ray. + RayCast(input, callback) { + this.m_tree.RayCast(input, callback); + } + /// Get the height of the embedded tree. + GetTreeHeight() { + return this.m_tree.GetHeight(); + } + /// Get the balance of the embedded tree. + GetTreeBalance() { + return this.m_tree.GetMaxBalance(); + } + /// Get the quality metric of the embedded tree. + GetTreeQuality() { + return this.m_tree.GetAreaRatio(); + } + /// Shift the world origin. Useful for large worlds. + /// The shift formula is: position -= newOrigin + /// @param newOrigin the new origin with respect to the old origin + ShiftOrigin(newOrigin) { + this.m_tree.ShiftOrigin(newOrigin); + } + BufferMove(proxy) { + this.m_moveBuffer[this.m_moveCount] = proxy; + ++this.m_moveCount; + } + UnBufferMove(proxy) { + for (let i = 0; i < this.m_moveCount; i++) { + if (this.m_moveBuffer[i] == proxy) { + this.m_moveBuffer[i] = null; + } + } + } + } + + /* + * Copyright (c) 2006-2010 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// A line segment (edge) shape. These can be connected in chains or loops + /// to other edge shapes. Edges created independently are two-sided and do + /// no provide smooth movement across junctions. + class b2EdgeShape extends b2Shape { + constructor() { + super(exports.b2ShapeType.e_edgeShape, b2_polygonRadius); + this.m_vertex1 = new b2Vec2(); + this.m_vertex2 = new b2Vec2(); + this.m_vertex0 = new b2Vec2(); + this.m_vertex3 = new b2Vec2(); + /// Uses m_vertex0 and m_vertex3 to create smooth collision. + this.m_oneSided = false; + } + /// Set this as a part of a sequence. Vertex v0 precedes the edge and vertex v3 + /// follows. These extra vertices are used to provide smooth movement + /// across junctions. This also makes the collision one-sided. The edge + /// normal points to the right looking from v1 to v2. + // void SetOneSided(const b2Vec2& v0, const b2Vec2& v1,const b2Vec2& v2, const b2Vec2& v3); + SetOneSided(v0, v1, v2, v3) { + this.m_vertex0.Copy(v0); + this.m_vertex1.Copy(v1); + this.m_vertex2.Copy(v2); + this.m_vertex3.Copy(v3); + this.m_oneSided = true; + return this; + } + /// Set this as an isolated edge. Collision is two-sided. + SetTwoSided(v1, v2) { + this.m_vertex1.Copy(v1); + this.m_vertex2.Copy(v2); + this.m_oneSided = false; + return this; + } + /// Implement b2Shape. + Clone() { + return new b2EdgeShape().Copy(this); + } + Copy(other) { + super.Copy(other); + // DEBUG: b2Assert(other instanceof b2EdgeShape); + this.m_vertex1.Copy(other.m_vertex1); + this.m_vertex2.Copy(other.m_vertex2); + this.m_vertex0.Copy(other.m_vertex0); + this.m_vertex3.Copy(other.m_vertex3); + this.m_oneSided = other.m_oneSided; + return this; + } + /// @see b2Shape::GetChildCount + GetChildCount() { + return 1; + } + /// @see b2Shape::TestPoint + TestPoint(xf, p) { + return false; + } + RayCast(output, input, xf, childIndex) { + // Put the ray into the edge's frame of reference. + const p1 = b2Transform.MulTXV(xf, input.p1, b2EdgeShape.RayCast_s_p1); + const p2 = b2Transform.MulTXV(xf, input.p2, b2EdgeShape.RayCast_s_p2); + const d = b2Vec2.SubVV(p2, p1, b2EdgeShape.RayCast_s_d); + const v1 = this.m_vertex1; + const v2 = this.m_vertex2; + const e = b2Vec2.SubVV(v2, v1, b2EdgeShape.RayCast_s_e); + // Normal points to the right, looking from v1 at v2 + const normal = output.normal.Set(e.y, -e.x).SelfNormalize(); + // q = p1 + t * d + // dot(normal, q - v1) = 0 + // dot(normal, p1 - v1) + t * dot(normal, d) = 0 + const numerator = b2Vec2.DotVV(normal, b2Vec2.SubVV(v1, p1, b2Vec2.s_t0)); + if (this.m_oneSided && numerator > 0.0) { + return false; + } + const denominator = b2Vec2.DotVV(normal, d); + if (denominator === 0) { + return false; + } + const t = numerator / denominator; + if (t < 0 || input.maxFraction < t) { + return false; + } + const q = b2Vec2.AddVMulSV(p1, t, d, b2EdgeShape.RayCast_s_q); + // q = v1 + s * r + // s = dot(q - v1, r) / dot(r, r) + const r = b2Vec2.SubVV(v2, v1, b2EdgeShape.RayCast_s_r); + const rr = b2Vec2.DotVV(r, r); + if (rr === 0) { + return false; + } + const s = b2Vec2.DotVV(b2Vec2.SubVV(q, v1, b2Vec2.s_t0), r) / rr; + if (s < 0 || 1 < s) { + return false; + } + output.fraction = t; + b2Rot.MulRV(xf.q, output.normal, output.normal); + if (numerator > 0) { + output.normal.SelfNeg(); + } + return true; + } + ComputeAABB(aabb, xf, childIndex) { + const v1 = b2Transform.MulXV(xf, this.m_vertex1, b2EdgeShape.ComputeAABB_s_v1); + const v2 = b2Transform.MulXV(xf, this.m_vertex2, b2EdgeShape.ComputeAABB_s_v2); + b2Vec2.MinV(v1, v2, aabb.lowerBound); + b2Vec2.MaxV(v1, v2, aabb.upperBound); + const r = this.m_radius; + aabb.lowerBound.SelfSubXY(r, r); + aabb.upperBound.SelfAddXY(r, r); + } + /// @see b2Shape::ComputeMass + ComputeMass(massData, density) { + massData.mass = 0; + b2Vec2.MidVV(this.m_vertex1, this.m_vertex2, massData.center); + massData.I = 0; + } + SetupDistanceProxy(proxy, index) { + proxy.m_vertices = proxy.m_buffer; + proxy.m_vertices[0].Copy(this.m_vertex1); + proxy.m_vertices[1].Copy(this.m_vertex2); + proxy.m_count = 2; + proxy.m_radius = this.m_radius; + } + ComputeSubmergedArea(normal, offset, xf, c) { + c.SetZero(); + return 0; + } + Dump(log) { + log(" const shape: b2EdgeShape = new b2EdgeShape();\n"); + log(" shape.m_radius = %.15f;\n", this.m_radius); + log(" shape.m_vertex0.Set(%.15f, %.15f);\n", this.m_vertex0.x, this.m_vertex0.y); + log(" shape.m_vertex1.Set(%.15f, %.15f);\n", this.m_vertex1.x, this.m_vertex1.y); + log(" shape.m_vertex2.Set(%.15f, %.15f);\n", this.m_vertex2.x, this.m_vertex2.y); + log(" shape.m_vertex3.Set(%.15f, %.15f);\n", this.m_vertex3.x, this.m_vertex3.y); + log(" shape.m_oneSided = %s;\n", this.m_oneSided); + } + } + /// Implement b2Shape. + // p = p1 + t * d + // v = v1 + s * e + // p1 + t * d = v1 + s * e + // s * e - t * d = p1 - v1 + b2EdgeShape.RayCast_s_p1 = new b2Vec2(); + b2EdgeShape.RayCast_s_p2 = new b2Vec2(); + b2EdgeShape.RayCast_s_d = new b2Vec2(); + b2EdgeShape.RayCast_s_e = new b2Vec2(); + b2EdgeShape.RayCast_s_q = new b2Vec2(); + b2EdgeShape.RayCast_s_r = new b2Vec2(); + /// @see b2Shape::ComputeAABB + b2EdgeShape.ComputeAABB_s_v1 = new b2Vec2(); + b2EdgeShape.ComputeAABB_s_v2 = new b2Vec2(); + + /* + * Copyright (c) 2006-2010 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// A chain shape is a free form sequence of line segments. + /// The chain has one-sided collision, with the surface normal pointing to the right of the edge. + /// This provides a counter-clockwise winding like the polygon shape. + /// Connectivity information is used to create smooth collisions. + /// @warning the chain will not collide properly if there are self-intersections. + class b2ChainShape extends b2Shape { + constructor() { + super(exports.b2ShapeType.e_chainShape, b2_polygonRadius); + this.m_vertices = []; + this.m_count = 0; + this.m_prevVertex = new b2Vec2(); + this.m_nextVertex = new b2Vec2(); + } + CreateLoop(...args) { + if (typeof args[0][0] === "number") { + const vertices = args[0]; + if (vertices.length % 2 !== 0) { + throw new Error(); + } + return this._CreateLoop((index) => ({ x: vertices[index * 2], y: vertices[index * 2 + 1] }), vertices.length / 2); + } + else { + const vertices = args[0]; + const count = args[1] || vertices.length; + return this._CreateLoop((index) => vertices[index], count); + } + } + _CreateLoop(vertices, count) { + // DEBUG: b2Assert(count >= 3); + if (count < 3) { + return this; + } + // DEBUG: for (let i: number = 1; i < count; ++i) { + // DEBUG: const v1 = vertices[start + i - 1]; + // DEBUG: const v2 = vertices[start + i]; + // DEBUG: // If the code crashes here, it means your vertices are too close together. + // DEBUG: b2Assert(b2Vec2.DistanceSquaredVV(v1, v2) > b2_linearSlop * b2_linearSlop); + // DEBUG: } + this.m_count = count + 1; + this.m_vertices = b2Vec2.MakeArray(this.m_count); + for (let i = 0; i < count; ++i) { + this.m_vertices[i].Copy(vertices(i)); + } + this.m_vertices[count].Copy(this.m_vertices[0]); + this.m_prevVertex.Copy(this.m_vertices[this.m_count - 2]); + this.m_nextVertex.Copy(this.m_vertices[1]); + return this; + } + CreateChain(...args) { + if (typeof args[0][0] === "number") { + const vertices = args[0]; + const prevVertex = args[1]; + const nextVertex = args[2]; + if (vertices.length % 2 !== 0) { + throw new Error(); + } + return this._CreateChain((index) => ({ x: vertices[index * 2], y: vertices[index * 2 + 1] }), vertices.length / 2, prevVertex, nextVertex); + } + else { + const vertices = args[0]; + const count = args[1] || vertices.length; + const prevVertex = args[2]; + const nextVertex = args[3]; + return this._CreateChain((index) => vertices[index], count, prevVertex, nextVertex); + } + } + _CreateChain(vertices, count, prevVertex, nextVertex) { + // DEBUG: b2Assert(count >= 2); + // DEBUG: for (let i: number = 1; i < count; ++i) { + // DEBUG: const v1 = vertices[start + i - 1]; + // DEBUG: const v2 = vertices[start + i]; + // DEBUG: // If the code crashes here, it means your vertices are too close together. + // DEBUG: b2Assert(b2Vec2.DistanceSquaredVV(v1, v2) > b2_linearSlop * b2_linearSlop); + // DEBUG: } + this.m_count = count; + this.m_vertices = b2Vec2.MakeArray(count); + for (let i = 0; i < count; ++i) { + this.m_vertices[i].Copy(vertices(i)); + } + this.m_prevVertex.Copy(prevVertex); + this.m_nextVertex.Copy(nextVertex); + return this; + } + /// Implement b2Shape. Vertices are cloned using b2Alloc. + Clone() { + return new b2ChainShape().Copy(this); + } + Copy(other) { + super.Copy(other); + // DEBUG: b2Assert(other instanceof b2ChainShape); + this._CreateChain((index) => other.m_vertices[index], other.m_count, other.m_prevVertex, other.m_nextVertex); + this.m_prevVertex.Copy(other.m_prevVertex); + this.m_nextVertex.Copy(other.m_nextVertex); + return this; + } + /// @see b2Shape::GetChildCount + GetChildCount() { + // edge count = vertex count - 1 + return this.m_count - 1; + } + /// Get a child edge. + GetChildEdge(edge, index) { + // DEBUG: b2Assert(0 <= index && index < this.m_count - 1); + edge.m_radius = this.m_radius; + edge.m_vertex1.Copy(this.m_vertices[index]); + edge.m_vertex2.Copy(this.m_vertices[index + 1]); + edge.m_oneSided = true; + if (index > 0) { + edge.m_vertex0.Copy(this.m_vertices[index - 1]); + } + else { + edge.m_vertex0.Copy(this.m_prevVertex); + } + if (index < this.m_count - 2) { + edge.m_vertex3.Copy(this.m_vertices[index + 2]); + } + else { + edge.m_vertex3.Copy(this.m_nextVertex); + } + } + /// This always return false. + /// @see b2Shape::TestPoint + TestPoint(xf, p) { + return false; + } + RayCast(output, input, xf, childIndex) { + // DEBUG: b2Assert(childIndex < this.m_count); + const edgeShape = b2ChainShape.RayCast_s_edgeShape; + edgeShape.m_vertex1.Copy(this.m_vertices[childIndex]); + edgeShape.m_vertex2.Copy(this.m_vertices[(childIndex + 1) % this.m_count]); + return edgeShape.RayCast(output, input, xf, 0); + } + ComputeAABB(aabb, xf, childIndex) { + // DEBUG: b2Assert(childIndex < this.m_count); + const vertexi1 = this.m_vertices[childIndex]; + const vertexi2 = this.m_vertices[(childIndex + 1) % this.m_count]; + const v1 = b2Transform.MulXV(xf, vertexi1, b2ChainShape.ComputeAABB_s_v1); + const v2 = b2Transform.MulXV(xf, vertexi2, b2ChainShape.ComputeAABB_s_v2); + const lower = b2Vec2.MinV(v1, v2, b2ChainShape.ComputeAABB_s_lower); + const upper = b2Vec2.MaxV(v1, v2, b2ChainShape.ComputeAABB_s_upper); + aabb.lowerBound.x = lower.x - this.m_radius; + aabb.lowerBound.y = lower.y - this.m_radius; + aabb.upperBound.x = upper.x + this.m_radius; + aabb.upperBound.y = upper.y + this.m_radius; + } + /// Chains have zero mass. + /// @see b2Shape::ComputeMass + ComputeMass(massData, density) { + massData.mass = 0; + massData.center.SetZero(); + massData.I = 0; + } + SetupDistanceProxy(proxy, index) { + // DEBUG: b2Assert(0 <= index && index < this.m_count); + proxy.m_vertices = proxy.m_buffer; + proxy.m_vertices[0].Copy(this.m_vertices[index]); + if (index + 1 < this.m_count) { + proxy.m_vertices[1].Copy(this.m_vertices[index + 1]); + } + else { + proxy.m_vertices[1].Copy(this.m_vertices[0]); + } + proxy.m_count = 2; + proxy.m_radius = this.m_radius; + } + ComputeSubmergedArea(normal, offset, xf, c) { + c.SetZero(); + return 0; + } + Dump(log) { + log(" const shape: b2ChainShape = new b2ChainShape();\n"); + log(" const vs: b2Vec2[] = [];\n"); + for (let i = 0; i < this.m_count; ++i) { + log(" vs[%d] = new bVec2(%.15f, %.15f);\n", i, this.m_vertices[i].x, this.m_vertices[i].y); + } + log(" shape.CreateChain(vs, %d);\n", this.m_count); + log(" shape.m_prevVertex.Set(%.15f, %.15f);\n", this.m_prevVertex.x, this.m_prevVertex.y); + log(" shape.m_nextVertex.Set(%.15f, %.15f);\n", this.m_nextVertex.x, this.m_nextVertex.y); + } + } + /// Implement b2Shape. + b2ChainShape.RayCast_s_edgeShape = new b2EdgeShape(); + /// @see b2Shape::ComputeAABB + b2ChainShape.ComputeAABB_s_v1 = new b2Vec2(); + b2ChainShape.ComputeAABB_s_v2 = new b2Vec2(); + b2ChainShape.ComputeAABB_s_lower = new b2Vec2(); + b2ChainShape.ComputeAABB_s_upper = new b2Vec2(); + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// A solid circle shape + class b2CircleShape extends b2Shape { + constructor(radius = 0) { + super(exports.b2ShapeType.e_circleShape, radius); + this.m_p = new b2Vec2(); + } + Set(position, radius = this.m_radius) { + this.m_p.Copy(position); + this.m_radius = radius; + return this; + } + /// Implement b2Shape. + Clone() { + return new b2CircleShape().Copy(this); + } + Copy(other) { + super.Copy(other); + // DEBUG: b2Assert(other instanceof b2CircleShape); + this.m_p.Copy(other.m_p); + return this; + } + /// @see b2Shape::GetChildCount + GetChildCount() { + return 1; + } + TestPoint(transform, p) { + const center = b2Transform.MulXV(transform, this.m_p, b2CircleShape.TestPoint_s_center); + const d = b2Vec2.SubVV(p, center, b2CircleShape.TestPoint_s_d); + return b2Vec2.DotVV(d, d) <= b2Sq(this.m_radius); + } + RayCast(output, input, transform, childIndex) { + const position = b2Transform.MulXV(transform, this.m_p, b2CircleShape.RayCast_s_position); + const s = b2Vec2.SubVV(input.p1, position, b2CircleShape.RayCast_s_s); + const b = b2Vec2.DotVV(s, s) - b2Sq(this.m_radius); + // Solve quadratic equation. + const r = b2Vec2.SubVV(input.p2, input.p1, b2CircleShape.RayCast_s_r); + const c = b2Vec2.DotVV(s, r); + const rr = b2Vec2.DotVV(r, r); + const sigma = c * c - rr * b; + // Check for negative discriminant and short segment. + if (sigma < 0 || rr < b2_epsilon) { + return false; + } + // Find the point of intersection of the line with the circle. + let a = (-(c + b2Sqrt(sigma))); + // Is the intersection point on the segment? + if (0 <= a && a <= input.maxFraction * rr) { + a /= rr; + output.fraction = a; + b2Vec2.AddVMulSV(s, a, r, output.normal).SelfNormalize(); + return true; + } + return false; + } + ComputeAABB(aabb, transform, childIndex) { + const p = b2Transform.MulXV(transform, this.m_p, b2CircleShape.ComputeAABB_s_p); + aabb.lowerBound.Set(p.x - this.m_radius, p.y - this.m_radius); + aabb.upperBound.Set(p.x + this.m_radius, p.y + this.m_radius); + } + /// @see b2Shape::ComputeMass + ComputeMass(massData, density) { + const radius_sq = b2Sq(this.m_radius); + massData.mass = density * b2_pi * radius_sq; + massData.center.Copy(this.m_p); + // inertia about the local origin + massData.I = massData.mass * (0.5 * radius_sq + b2Vec2.DotVV(this.m_p, this.m_p)); + } + SetupDistanceProxy(proxy, index) { + proxy.m_vertices = proxy.m_buffer; + proxy.m_vertices[0].Copy(this.m_p); + proxy.m_count = 1; + proxy.m_radius = this.m_radius; + } + ComputeSubmergedArea(normal, offset, xf, c) { + const p = b2Transform.MulXV(xf, this.m_p, new b2Vec2()); + const l = (-(b2Vec2.DotVV(normal, p) - offset)); + if (l < (-this.m_radius) + b2_epsilon) { + // Completely dry + return 0; + } + if (l > this.m_radius) { + // Completely wet + c.Copy(p); + return b2_pi * this.m_radius * this.m_radius; + } + // Magic + const r2 = this.m_radius * this.m_radius; + const l2 = l * l; + const area = r2 * (b2Asin(l / this.m_radius) + b2_pi / 2) + l * b2Sqrt(r2 - l2); + const com = (-2 / 3 * b2Pow(r2 - l2, 1.5) / area); + c.x = p.x + normal.x * com; + c.y = p.y + normal.y * com; + return area; + } + Dump(log) { + log(" const shape: b2CircleShape = new b2CircleShape();\n"); + log(" shape.m_radius = %.15f;\n", this.m_radius); + log(" shape.m_p.Set(%.15f, %.15f);\n", this.m_p.x, this.m_p.y); + } + } + /// Implement b2Shape. + b2CircleShape.TestPoint_s_center = new b2Vec2(); + b2CircleShape.TestPoint_s_d = new b2Vec2(); + /// Implement b2Shape. + /// @note because the circle is solid, rays that start inside do not hit because the normal is + /// not defined. + // Collision Detection in Interactive 3D Environments by Gino van den Bergen + // From Section 3.1.2 + // x = s + a * r + // norm(x) = radius + b2CircleShape.RayCast_s_position = new b2Vec2(); + b2CircleShape.RayCast_s_s = new b2Vec2(); + b2CircleShape.RayCast_s_r = new b2Vec2(); + /// @see b2Shape::ComputeAABB + b2CircleShape.ComputeAABB_s_p = new b2Vec2(); + + const b2CollideCircles_s_pA = new b2Vec2(); + const b2CollideCircles_s_pB = new b2Vec2(); + function b2CollideCircles(manifold, circleA, xfA, circleB, xfB) { + manifold.pointCount = 0; + const pA = b2Transform.MulXV(xfA, circleA.m_p, b2CollideCircles_s_pA); + const pB = b2Transform.MulXV(xfB, circleB.m_p, b2CollideCircles_s_pB); + const distSqr = b2Vec2.DistanceSquaredVV(pA, pB); + const radius = circleA.m_radius + circleB.m_radius; + if (distSqr > radius * radius) { + return; + } + manifold.type = exports.b2ManifoldType.e_circles; + manifold.localPoint.Copy(circleA.m_p); + manifold.localNormal.SetZero(); + manifold.pointCount = 1; + manifold.points[0].localPoint.Copy(circleB.m_p); + manifold.points[0].id.key = 0; + } + const b2CollidePolygonAndCircle_s_c = new b2Vec2(); + const b2CollidePolygonAndCircle_s_cLocal = new b2Vec2(); + const b2CollidePolygonAndCircle_s_faceCenter = new b2Vec2(); + function b2CollidePolygonAndCircle(manifold, polygonA, xfA, circleB, xfB) { + manifold.pointCount = 0; + // Compute circle position in the frame of the polygon. + const c = b2Transform.MulXV(xfB, circleB.m_p, b2CollidePolygonAndCircle_s_c); + const cLocal = b2Transform.MulTXV(xfA, c, b2CollidePolygonAndCircle_s_cLocal); + // Find the min separating edge. + let normalIndex = 0; + let separation = (-b2_maxFloat); + const radius = polygonA.m_radius + circleB.m_radius; + const vertexCount = polygonA.m_count; + const vertices = polygonA.m_vertices; + const normals = polygonA.m_normals; + for (let i = 0; i < vertexCount; ++i) { + const s = b2Vec2.DotVV(normals[i], b2Vec2.SubVV(cLocal, vertices[i], b2Vec2.s_t0)); + if (s > radius) { + // Early out. + return; + } + if (s > separation) { + separation = s; + normalIndex = i; + } + } + // Vertices that subtend the incident face. + const vertIndex1 = normalIndex; + const vertIndex2 = (vertIndex1 + 1) % vertexCount; + const v1 = vertices[vertIndex1]; + const v2 = vertices[vertIndex2]; + // If the center is inside the polygon ... + if (separation < b2_epsilon) { + manifold.pointCount = 1; + manifold.type = exports.b2ManifoldType.e_faceA; + manifold.localNormal.Copy(normals[normalIndex]); + b2Vec2.MidVV(v1, v2, manifold.localPoint); + manifold.points[0].localPoint.Copy(circleB.m_p); + manifold.points[0].id.key = 0; + return; + } + // Compute barycentric coordinates + const u1 = b2Vec2.DotVV(b2Vec2.SubVV(cLocal, v1, b2Vec2.s_t0), b2Vec2.SubVV(v2, v1, b2Vec2.s_t1)); + const u2 = b2Vec2.DotVV(b2Vec2.SubVV(cLocal, v2, b2Vec2.s_t0), b2Vec2.SubVV(v1, v2, b2Vec2.s_t1)); + if (u1 <= 0) { + if (b2Vec2.DistanceSquaredVV(cLocal, v1) > radius * radius) { + return; + } + manifold.pointCount = 1; + manifold.type = exports.b2ManifoldType.e_faceA; + b2Vec2.SubVV(cLocal, v1, manifold.localNormal).SelfNormalize(); + manifold.localPoint.Copy(v1); + manifold.points[0].localPoint.Copy(circleB.m_p); + manifold.points[0].id.key = 0; + } + else if (u2 <= 0) { + if (b2Vec2.DistanceSquaredVV(cLocal, v2) > radius * radius) { + return; + } + manifold.pointCount = 1; + manifold.type = exports.b2ManifoldType.e_faceA; + b2Vec2.SubVV(cLocal, v2, manifold.localNormal).SelfNormalize(); + manifold.localPoint.Copy(v2); + manifold.points[0].localPoint.Copy(circleB.m_p); + manifold.points[0].id.key = 0; + } + else { + const faceCenter = b2Vec2.MidVV(v1, v2, b2CollidePolygonAndCircle_s_faceCenter); + const separation = b2Vec2.DotVV(b2Vec2.SubVV(cLocal, faceCenter, b2Vec2.s_t1), normals[vertIndex1]); + if (separation > radius) { + return; + } + manifold.pointCount = 1; + manifold.type = exports.b2ManifoldType.e_faceA; + manifold.localNormal.Copy(normals[vertIndex1]).SelfNormalize(); + manifold.localPoint.Copy(faceCenter); + manifold.points[0].localPoint.Copy(circleB.m_p); + manifold.points[0].id.key = 0; + } + } + + // DEBUG: import { b2Assert } from "../common/b2_settings.js"; + const b2CollideEdgeAndCircle_s_Q = new b2Vec2(); + const b2CollideEdgeAndCircle_s_e = new b2Vec2(); + const b2CollideEdgeAndCircle_s_d = new b2Vec2(); + const b2CollideEdgeAndCircle_s_e1 = new b2Vec2(); + const b2CollideEdgeAndCircle_s_e2 = new b2Vec2(); + const b2CollideEdgeAndCircle_s_P = new b2Vec2(); + const b2CollideEdgeAndCircle_s_n = new b2Vec2(); + const b2CollideEdgeAndCircle_s_id = new b2ContactID(); + function b2CollideEdgeAndCircle(manifold, edgeA, xfA, circleB, xfB) { + manifold.pointCount = 0; + // Compute circle in frame of edge + const Q = b2Transform.MulTXV(xfA, b2Transform.MulXV(xfB, circleB.m_p, b2Vec2.s_t0), b2CollideEdgeAndCircle_s_Q); + const A = edgeA.m_vertex1; + const B = edgeA.m_vertex2; + const e = b2Vec2.SubVV(B, A, b2CollideEdgeAndCircle_s_e); + // Normal points to the right for a CCW winding + // b2Vec2 n(e.y, -e.x); + // const n: b2Vec2 = b2CollideEdgeAndCircle_s_n.Set(-e.y, e.x); + const n = b2CollideEdgeAndCircle_s_n.Set(e.y, -e.x); + // float offset = b2Dot(n, Q - A); + const offset = b2Vec2.DotVV(n, b2Vec2.SubVV(Q, A, b2Vec2.s_t0)); + const oneSided = edgeA.m_oneSided; + if (oneSided && offset < 0.0) { + return; + } + // Barycentric coordinates + const u = b2Vec2.DotVV(e, b2Vec2.SubVV(B, Q, b2Vec2.s_t0)); + const v = b2Vec2.DotVV(e, b2Vec2.SubVV(Q, A, b2Vec2.s_t0)); + const radius = edgeA.m_radius + circleB.m_radius; + // const cf: b2ContactFeature = new b2ContactFeature(); + const id = b2CollideEdgeAndCircle_s_id; + id.cf.indexB = 0; + id.cf.typeB = exports.b2ContactFeatureType.e_vertex; + // Region A + if (v <= 0) { + const P = A; + const d = b2Vec2.SubVV(Q, P, b2CollideEdgeAndCircle_s_d); + const dd = b2Vec2.DotVV(d, d); + if (dd > radius * radius) { + return; + } + // Is there an edge connected to A? + if (edgeA.m_oneSided) { + const A1 = edgeA.m_vertex0; + const B1 = A; + const e1 = b2Vec2.SubVV(B1, A1, b2CollideEdgeAndCircle_s_e1); + const u1 = b2Vec2.DotVV(e1, b2Vec2.SubVV(B1, Q, b2Vec2.s_t0)); + // Is the circle in Region AB of the previous edge? + if (u1 > 0) { + return; + } + } + id.cf.indexA = 0; + id.cf.typeA = exports.b2ContactFeatureType.e_vertex; + manifold.pointCount = 1; + manifold.type = exports.b2ManifoldType.e_circles; + manifold.localNormal.SetZero(); + manifold.localPoint.Copy(P); + manifold.points[0].id.Copy(id); + // manifold.points[0].id.key = 0; + // manifold.points[0].id.cf = cf; + manifold.points[0].localPoint.Copy(circleB.m_p); + return; + } + // Region B + if (u <= 0) { + const P = B; + const d = b2Vec2.SubVV(Q, P, b2CollideEdgeAndCircle_s_d); + const dd = b2Vec2.DotVV(d, d); + if (dd > radius * radius) { + return; + } + // Is there an edge connected to B? + if (edgeA.m_oneSided) { + const B2 = edgeA.m_vertex3; + const A2 = B; + const e2 = b2Vec2.SubVV(B2, A2, b2CollideEdgeAndCircle_s_e2); + const v2 = b2Vec2.DotVV(e2, b2Vec2.SubVV(Q, A2, b2Vec2.s_t0)); + // Is the circle in Region AB of the next edge? + if (v2 > 0) { + return; + } + } + id.cf.indexA = 1; + id.cf.typeA = exports.b2ContactFeatureType.e_vertex; + manifold.pointCount = 1; + manifold.type = exports.b2ManifoldType.e_circles; + manifold.localNormal.SetZero(); + manifold.localPoint.Copy(P); + manifold.points[0].id.Copy(id); + // manifold.points[0].id.key = 0; + // manifold.points[0].id.cf = cf; + manifold.points[0].localPoint.Copy(circleB.m_p); + return; + } + // Region AB + const den = b2Vec2.DotVV(e, e); + // DEBUG: b2Assert(den > 0); + const P = b2CollideEdgeAndCircle_s_P; + P.x = (1 / den) * (u * A.x + v * B.x); + P.y = (1 / den) * (u * A.y + v * B.y); + const d = b2Vec2.SubVV(Q, P, b2CollideEdgeAndCircle_s_d); + const dd = b2Vec2.DotVV(d, d); + if (dd > radius * radius) { + return; + } + if (offset < 0) { + n.Set(-n.x, -n.y); + } + n.Normalize(); + id.cf.indexA = 0; + id.cf.typeA = exports.b2ContactFeatureType.e_face; + manifold.pointCount = 1; + manifold.type = exports.b2ManifoldType.e_faceA; + manifold.localNormal.Copy(n); + manifold.localPoint.Copy(A); + manifold.points[0].id.Copy(id); + // manifold.points[0].id.key = 0; + // manifold.points[0].id.cf = cf; + manifold.points[0].localPoint.Copy(circleB.m_p); + } + var b2EPAxisType; + (function (b2EPAxisType) { + b2EPAxisType[b2EPAxisType["e_unknown"] = 0] = "e_unknown"; + b2EPAxisType[b2EPAxisType["e_edgeA"] = 1] = "e_edgeA"; + b2EPAxisType[b2EPAxisType["e_edgeB"] = 2] = "e_edgeB"; + })(b2EPAxisType || (b2EPAxisType = {})); + class b2EPAxis { + constructor() { + this.normal = new b2Vec2(); + this.type = b2EPAxisType.e_unknown; + this.index = 0; + this.separation = 0; + } + } + class b2TempPolygon { + constructor() { + this.vertices = []; + this.normals = []; + this.count = 0; + } + } + class b2ReferenceFace { + constructor() { + this.i1 = 0; + this.i2 = 0; + this.v1 = new b2Vec2(); + this.v2 = new b2Vec2(); + this.normal = new b2Vec2(); + this.sideNormal1 = new b2Vec2(); + this.sideOffset1 = 0; + this.sideNormal2 = new b2Vec2(); + this.sideOffset2 = 0; + } + } + // static b2EPAxis b2ComputeEdgeSeparation(const b2TempPolygon& polygonB, const b2Vec2& v1, const b2Vec2& normal1) + const b2ComputeEdgeSeparation_s_axis = new b2EPAxis(); + const b2ComputeEdgeSeparation_s_axes = [new b2Vec2(), new b2Vec2()]; + function b2ComputeEdgeSeparation(polygonB, v1, normal1) { + // b2EPAxis axis; + const axis = b2ComputeEdgeSeparation_s_axis; + axis.type = b2EPAxisType.e_edgeA; + axis.index = -1; + axis.separation = -Number.MAX_VALUE; // -FLT_MAX; + axis.normal.SetZero(); + // b2Vec2 axes[2] = { normal1, -normal1 }; + const axes = b2ComputeEdgeSeparation_s_axes; + axes[0].Copy(normal1); + axes[1].Copy(normal1).SelfNeg(); + // Find axis with least overlap (min-max problem) + for (let j = 0; j < 2; ++j) { + let sj = Number.MAX_VALUE; // FLT_MAX; + // Find deepest polygon vertex along axis j + for (let i = 0; i < polygonB.count; ++i) { + // float si = b2Dot(axes[j], polygonB.vertices[i] - v1); + const si = b2Vec2.DotVV(axes[j], b2Vec2.SubVV(polygonB.vertices[i], v1, b2Vec2.s_t0)); + if (si < sj) { + sj = si; + } + } + if (sj > axis.separation) { + axis.index = j; + axis.separation = sj; + axis.normal.Copy(axes[j]); + } + } + return axis; + } + // static b2EPAxis b2ComputePolygonSeparation(const b2TempPolygon& polygonB, const b2Vec2& v1, const b2Vec2& v2) + const b2ComputePolygonSeparation_s_axis = new b2EPAxis(); + const b2ComputePolygonSeparation_s_n = new b2Vec2(); + function b2ComputePolygonSeparation(polygonB, v1, v2) { + const axis = b2ComputePolygonSeparation_s_axis; + axis.type = b2EPAxisType.e_unknown; + axis.index = -1; + axis.separation = -Number.MAX_VALUE; // -FLT_MAX; + axis.normal.SetZero(); + for (let i = 0; i < polygonB.count; ++i) { + // b2Vec2 n = -polygonB.normals[i]; + const n = b2Vec2.NegV(polygonB.normals[i], b2ComputePolygonSeparation_s_n); + // float s1 = b2Dot(n, polygonB.vertices[i] - v1); + const s1 = b2Vec2.DotVV(n, b2Vec2.SubVV(polygonB.vertices[i], v1, b2Vec2.s_t0)); + // float s2 = b2Dot(n, polygonB.vertices[i] - v2); + const s2 = b2Vec2.DotVV(n, b2Vec2.SubVV(polygonB.vertices[i], v2, b2Vec2.s_t0)); + // float s = b2Min(s1, s2); + const s = b2Min(s1, s2); + if (s > axis.separation) { + axis.type = b2EPAxisType.e_edgeB; + axis.index = i; + axis.separation = s; + axis.normal.Copy(n); + } + } + return axis; + } + const b2CollideEdgeAndPolygon_s_xf = new b2Transform(); + const b2CollideEdgeAndPolygon_s_centroidB = new b2Vec2(); + const b2CollideEdgeAndPolygon_s_edge1 = new b2Vec2(); + const b2CollideEdgeAndPolygon_s_normal1 = new b2Vec2(); + const b2CollideEdgeAndPolygon_s_edge0 = new b2Vec2(); + const b2CollideEdgeAndPolygon_s_normal0 = new b2Vec2(); + const b2CollideEdgeAndPolygon_s_edge2 = new b2Vec2(); + const b2CollideEdgeAndPolygon_s_normal2 = new b2Vec2(); + const b2CollideEdgeAndPolygon_s_tempPolygonB = new b2TempPolygon(); + const b2CollideEdgeAndPolygon_s_ref = new b2ReferenceFace(); + const b2CollideEdgeAndPolygon_s_clipPoints = [new b2ClipVertex(), new b2ClipVertex()]; + const b2CollideEdgeAndPolygon_s_clipPoints1 = [new b2ClipVertex(), new b2ClipVertex()]; + const b2CollideEdgeAndPolygon_s_clipPoints2 = [new b2ClipVertex(), new b2ClipVertex()]; + function b2CollideEdgeAndPolygon(manifold, edgeA, xfA, polygonB, xfB) { + manifold.pointCount = 0; + // b2Transform xf = b2MulT(xfA, xfB); + const xf = b2Transform.MulTXX(xfA, xfB, b2CollideEdgeAndPolygon_s_xf); + // b2Vec2 centroidB = b2Mul(xf, polygonB.m_centroid); + const centroidB = b2Transform.MulXV(xf, polygonB.m_centroid, b2CollideEdgeAndPolygon_s_centroidB); + // b2Vec2 v1 = edgeA.m_vertex1; + const v1 = edgeA.m_vertex1; + // b2Vec2 v2 = edgeA.m_vertex2; + const v2 = edgeA.m_vertex2; + // b2Vec2 edge1 = v2 - v1; + const edge1 = b2Vec2.SubVV(v2, v1, b2CollideEdgeAndPolygon_s_edge1); + edge1.Normalize(); + // Normal points to the right for a CCW winding + // b2Vec2 normal1(edge1.y, -edge1.x); + const normal1 = b2CollideEdgeAndPolygon_s_normal1.Set(edge1.y, -edge1.x); + // float offset1 = b2Dot(normal1, centroidB - v1); + const offset1 = b2Vec2.DotVV(normal1, b2Vec2.SubVV(centroidB, v1, b2Vec2.s_t0)); + const oneSided = edgeA.m_oneSided; + if (oneSided && offset1 < 0.0) { + return; + } + // Get polygonB in frameA + // b2TempPolygon tempPolygonB; + const tempPolygonB = b2CollideEdgeAndPolygon_s_tempPolygonB; + tempPolygonB.count = polygonB.m_count; + for (let i = 0; i < polygonB.m_count; ++i) { + if (tempPolygonB.vertices.length <= i) { + tempPolygonB.vertices.push(new b2Vec2()); + } + if (tempPolygonB.normals.length <= i) { + tempPolygonB.normals.push(new b2Vec2()); + } + // tempPolygonB.vertices[i] = b2Mul(xf, polygonB.m_vertices[i]); + b2Transform.MulXV(xf, polygonB.m_vertices[i], tempPolygonB.vertices[i]); + // tempPolygonB.normals[i] = b2Mul(xf.q, polygonB.m_normals[i]); + b2Rot.MulRV(xf.q, polygonB.m_normals[i], tempPolygonB.normals[i]); + } + const radius = polygonB.m_radius + edgeA.m_radius; + // b2EPAxis edgeAxis = b2ComputeEdgeSeparation(tempPolygonB, v1, normal1); + const edgeAxis = b2ComputeEdgeSeparation(tempPolygonB, v1, normal1); + if (edgeAxis.separation > radius) { + return; + } + // b2EPAxis polygonAxis = b2ComputePolygonSeparation(tedge0.y, -edge0.xempPolygonB, v1, v2); + const polygonAxis = b2ComputePolygonSeparation(tempPolygonB, v1, v2); + if (polygonAxis.separation > radius) { + return; + } + // Use hysteresis for jitter reduction. + const k_relativeTol = 0.98; + const k_absoluteTol = 0.001; + // b2EPAxis primaryAxis; + let primaryAxis; + if (polygonAxis.separation - radius > k_relativeTol * (edgeAxis.separation - radius) + k_absoluteTol) { + primaryAxis = polygonAxis; + } + else { + primaryAxis = edgeAxis; + } + if (oneSided) { + // Smooth collision + // See https://box2d.org/posts/2020/06/ghost-collisions/ + // b2Vec2 edge0 = v1 - edgeA.m_vertex0; + const edge0 = b2Vec2.SubVV(v1, edgeA.m_vertex0, b2CollideEdgeAndPolygon_s_edge0); + edge0.Normalize(); + // b2Vec2 normal0(edge0.y, -edge0.x); + const normal0 = b2CollideEdgeAndPolygon_s_normal0.Set(edge0.y, -edge0.x); + const convex1 = b2Vec2.CrossVV(edge0, edge1) >= 0.0; + // b2Vec2 edge2 = edgeA.m_vertex3 - v2; + const edge2 = b2Vec2.SubVV(edgeA.m_vertex3, v2, b2CollideEdgeAndPolygon_s_edge2); + edge2.Normalize(); + // b2Vec2 normal2(edge2.y, -edge2.x); + const normal2 = b2CollideEdgeAndPolygon_s_normal2.Set(edge2.y, -edge2.x); + const convex2 = b2Vec2.CrossVV(edge1, edge2) >= 0.0; + const sinTol = 0.1; + const side1 = b2Vec2.DotVV(primaryAxis.normal, edge1) <= 0.0; + // Check Gauss Map + if (side1) { + if (convex1) { + if (b2Vec2.CrossVV(primaryAxis.normal, normal0) > sinTol) { + // Skip region + return; + } + // Admit region + } + else { + // Snap region + primaryAxis = edgeAxis; + } + } + else { + if (convex2) { + if (b2Vec2.CrossVV(normal2, primaryAxis.normal) > sinTol) { + // Skip region + return; + } + // Admit region + } + else { + // Snap region + primaryAxis = edgeAxis; + } + } + } + // b2ClipVertex clipPoints[2]; + const clipPoints = b2CollideEdgeAndPolygon_s_clipPoints; + // b2ReferenceFace ref; + const ref = b2CollideEdgeAndPolygon_s_ref; + if (primaryAxis.type === b2EPAxisType.e_edgeA) { + manifold.type = exports.b2ManifoldType.e_faceA; + // Search for the polygon normal that is most anti-parallel to the edge normal. + let bestIndex = 0; + let bestValue = b2Vec2.DotVV(primaryAxis.normal, tempPolygonB.normals[0]); + for (let i = 1; i < tempPolygonB.count; ++i) { + const value = b2Vec2.DotVV(primaryAxis.normal, tempPolygonB.normals[i]); + if (value < bestValue) { + bestValue = value; + bestIndex = i; + } + } + const i1 = bestIndex; + const i2 = i1 + 1 < tempPolygonB.count ? i1 + 1 : 0; + clipPoints[0].v.Copy(tempPolygonB.vertices[i1]); + clipPoints[0].id.cf.indexA = 0; + clipPoints[0].id.cf.indexB = i1; + clipPoints[0].id.cf.typeA = exports.b2ContactFeatureType.e_face; + clipPoints[0].id.cf.typeB = exports.b2ContactFeatureType.e_vertex; + clipPoints[1].v.Copy(tempPolygonB.vertices[i2]); + clipPoints[1].id.cf.indexA = 0; + clipPoints[1].id.cf.indexB = i2; + clipPoints[1].id.cf.typeA = exports.b2ContactFeatureType.e_face; + clipPoints[1].id.cf.typeB = exports.b2ContactFeatureType.e_vertex; + ref.i1 = 0; + ref.i2 = 1; + ref.v1.Copy(v1); + ref.v2.Copy(v2); + ref.normal.Copy(primaryAxis.normal); + ref.sideNormal1.Copy(edge1).SelfNeg(); // ref.sideNormal1 = -edge1; + ref.sideNormal2.Copy(edge1); + } + else { + manifold.type = exports.b2ManifoldType.e_faceB; + clipPoints[0].v.Copy(v2); + clipPoints[0].id.cf.indexA = 1; + clipPoints[0].id.cf.indexB = primaryAxis.index; + clipPoints[0].id.cf.typeA = exports.b2ContactFeatureType.e_vertex; + clipPoints[0].id.cf.typeB = exports.b2ContactFeatureType.e_face; + clipPoints[1].v.Copy(v1); + clipPoints[1].id.cf.indexA = 0; + clipPoints[1].id.cf.indexB = primaryAxis.index; + clipPoints[1].id.cf.typeA = exports.b2ContactFeatureType.e_vertex; + clipPoints[1].id.cf.typeB = exports.b2ContactFeatureType.e_face; + ref.i1 = primaryAxis.index; + ref.i2 = ref.i1 + 1 < tempPolygonB.count ? ref.i1 + 1 : 0; + ref.v1.Copy(tempPolygonB.vertices[ref.i1]); + ref.v2.Copy(tempPolygonB.vertices[ref.i2]); + ref.normal.Copy(tempPolygonB.normals[ref.i1]); + // CCW winding + ref.sideNormal1.Set(ref.normal.y, -ref.normal.x); + ref.sideNormal2.Copy(ref.sideNormal1).SelfNeg(); // ref.sideNormal2 = -ref.sideNormal1; + } + ref.sideOffset1 = b2Vec2.DotVV(ref.sideNormal1, ref.v1); + ref.sideOffset2 = b2Vec2.DotVV(ref.sideNormal2, ref.v2); + // Clip incident edge against reference face side planes + // b2ClipVertex clipPoints1[2]; + const clipPoints1 = b2CollideEdgeAndPolygon_s_clipPoints1; // [new b2ClipVertex(), new b2ClipVertex()]; + // b2ClipVertex clipPoints2[2]; + const clipPoints2 = b2CollideEdgeAndPolygon_s_clipPoints2; // [new b2ClipVertex(), new b2ClipVertex()]; + // int32 np; + let np; + // Clip to side 1 + np = b2ClipSegmentToLine(clipPoints1, clipPoints, ref.sideNormal1, ref.sideOffset1, ref.i1); + if (np < b2_maxManifoldPoints) { + return; + } + // Clip to side 2 + np = b2ClipSegmentToLine(clipPoints2, clipPoints1, ref.sideNormal2, ref.sideOffset2, ref.i2); + if (np < b2_maxManifoldPoints) { + return; + } + // Now clipPoints2 contains the clipped points. + if (primaryAxis.type === b2EPAxisType.e_edgeA) { + manifold.localNormal.Copy(ref.normal); + manifold.localPoint.Copy(ref.v1); + } + else { + manifold.localNormal.Copy(polygonB.m_normals[ref.i1]); + manifold.localPoint.Copy(polygonB.m_vertices[ref.i1]); + } + let pointCount = 0; + for (let i = 0; i < b2_maxManifoldPoints; ++i) { + const separation = b2Vec2.DotVV(ref.normal, b2Vec2.SubVV(clipPoints2[i].v, ref.v1, b2Vec2.s_t0)); + if (separation <= radius) { + const cp = manifold.points[pointCount]; + if (primaryAxis.type === b2EPAxisType.e_edgeA) { + b2Transform.MulTXV(xf, clipPoints2[i].v, cp.localPoint); // cp.localPoint = b2MulT(xf, clipPoints2[i].v); + cp.id.Copy(clipPoints2[i].id); + } + else { + cp.localPoint.Copy(clipPoints2[i].v); + cp.id.cf.typeA = clipPoints2[i].id.cf.typeB; + cp.id.cf.typeB = clipPoints2[i].id.cf.typeA; + cp.id.cf.indexA = clipPoints2[i].id.cf.indexB; + cp.id.cf.indexB = clipPoints2[i].id.cf.indexA; + } + ++pointCount; + } + } + manifold.pointCount = pointCount; + } + + // MIT License + // Find the max separation between poly1 and poly2 using edge normals from poly1. + const b2FindMaxSeparation_s_xf = new b2Transform(); + const b2FindMaxSeparation_s_n = new b2Vec2(); + const b2FindMaxSeparation_s_v1 = new b2Vec2(); + function b2FindMaxSeparation(edgeIndex, poly1, xf1, poly2, xf2) { + const count1 = poly1.m_count; + const count2 = poly2.m_count; + const n1s = poly1.m_normals; + const v1s = poly1.m_vertices; + const v2s = poly2.m_vertices; + const xf = b2Transform.MulTXX(xf2, xf1, b2FindMaxSeparation_s_xf); + let bestIndex = 0; + let maxSeparation = -b2_maxFloat; + for (let i = 0; i < count1; ++i) { + // Get poly1 normal in frame2. + const n = b2Rot.MulRV(xf.q, n1s[i], b2FindMaxSeparation_s_n); + const v1 = b2Transform.MulXV(xf, v1s[i], b2FindMaxSeparation_s_v1); + // Find deepest point for normal i. + let si = b2_maxFloat; + for (let j = 0; j < count2; ++j) { + const sij = b2Vec2.DotVV(n, b2Vec2.SubVV(v2s[j], v1, b2Vec2.s_t0)); + if (sij < si) { + si = sij; + } + } + if (si > maxSeparation) { + maxSeparation = si; + bestIndex = i; + } + } + edgeIndex[0] = bestIndex; + return maxSeparation; + } + const b2FindIncidentEdge_s_normal1 = new b2Vec2(); + function b2FindIncidentEdge(c, poly1, xf1, edge1, poly2, xf2) { + const normals1 = poly1.m_normals; + const count2 = poly2.m_count; + const vertices2 = poly2.m_vertices; + const normals2 = poly2.m_normals; + // DEBUG: b2Assert(0 <= edge1 && edge1 < poly1.m_count); + // Get the normal of the reference edge in poly2's frame. + const normal1 = b2Rot.MulTRV(xf2.q, b2Rot.MulRV(xf1.q, normals1[edge1], b2Vec2.s_t0), b2FindIncidentEdge_s_normal1); + // Find the incident edge on poly2. + let index = 0; + let minDot = b2_maxFloat; + for (let i = 0; i < count2; ++i) { + const dot = b2Vec2.DotVV(normal1, normals2[i]); + if (dot < minDot) { + minDot = dot; + index = i; + } + } + // Build the clip vertices for the incident edge. + const i1 = index; + const i2 = i1 + 1 < count2 ? i1 + 1 : 0; + const c0 = c[0]; + b2Transform.MulXV(xf2, vertices2[i1], c0.v); + const cf0 = c0.id.cf; + cf0.indexA = edge1; + cf0.indexB = i1; + cf0.typeA = exports.b2ContactFeatureType.e_face; + cf0.typeB = exports.b2ContactFeatureType.e_vertex; + const c1 = c[1]; + b2Transform.MulXV(xf2, vertices2[i2], c1.v); + const cf1 = c1.id.cf; + cf1.indexA = edge1; + cf1.indexB = i2; + cf1.typeA = exports.b2ContactFeatureType.e_face; + cf1.typeB = exports.b2ContactFeatureType.e_vertex; + } + // Find edge normal of max separation on A - return if separating axis is found + // Find edge normal of max separation on B - return if separation axis is found + // Choose reference edge as min(minA, minB) + // Find incident edge + // Clip + // The normal points from 1 to 2 + const b2CollidePolygons_s_incidentEdge = [new b2ClipVertex(), new b2ClipVertex()]; + const b2CollidePolygons_s_clipPoints1 = [new b2ClipVertex(), new b2ClipVertex()]; + const b2CollidePolygons_s_clipPoints2 = [new b2ClipVertex(), new b2ClipVertex()]; + const b2CollidePolygons_s_edgeA = [0]; + const b2CollidePolygons_s_edgeB = [0]; + const b2CollidePolygons_s_localTangent = new b2Vec2(); + const b2CollidePolygons_s_localNormal = new b2Vec2(); + const b2CollidePolygons_s_planePoint = new b2Vec2(); + const b2CollidePolygons_s_normal = new b2Vec2(); + const b2CollidePolygons_s_tangent = new b2Vec2(); + const b2CollidePolygons_s_ntangent = new b2Vec2(); + const b2CollidePolygons_s_v11 = new b2Vec2(); + const b2CollidePolygons_s_v12 = new b2Vec2(); + function b2CollidePolygons(manifold, polyA, xfA, polyB, xfB) { + manifold.pointCount = 0; + const totalRadius = polyA.m_radius + polyB.m_radius; + const edgeA = b2CollidePolygons_s_edgeA; + edgeA[0] = 0; + const separationA = b2FindMaxSeparation(edgeA, polyA, xfA, polyB, xfB); + if (separationA > totalRadius) { + return; + } + const edgeB = b2CollidePolygons_s_edgeB; + edgeB[0] = 0; + const separationB = b2FindMaxSeparation(edgeB, polyB, xfB, polyA, xfA); + if (separationB > totalRadius) { + return; + } + let poly1; // reference polygon + let poly2; // incident polygon + let xf1, xf2; + let edge1 = 0; // reference edge + let flip = 0; + const k_tol = 0.1 * b2_linearSlop; + if (separationB > separationA + k_tol) { + poly1 = polyB; + poly2 = polyA; + xf1 = xfB; + xf2 = xfA; + edge1 = edgeB[0]; + manifold.type = exports.b2ManifoldType.e_faceB; + flip = 1; + } + else { + poly1 = polyA; + poly2 = polyB; + xf1 = xfA; + xf2 = xfB; + edge1 = edgeA[0]; + manifold.type = exports.b2ManifoldType.e_faceA; + flip = 0; + } + const incidentEdge = b2CollidePolygons_s_incidentEdge; + b2FindIncidentEdge(incidentEdge, poly1, xf1, edge1, poly2, xf2); + const count1 = poly1.m_count; + const vertices1 = poly1.m_vertices; + const iv1 = edge1; + const iv2 = edge1 + 1 < count1 ? edge1 + 1 : 0; + const local_v11 = vertices1[iv1]; + const local_v12 = vertices1[iv2]; + const localTangent = b2Vec2.SubVV(local_v12, local_v11, b2CollidePolygons_s_localTangent); + localTangent.Normalize(); + const localNormal = b2Vec2.CrossVOne(localTangent, b2CollidePolygons_s_localNormal); + const planePoint = b2Vec2.MidVV(local_v11, local_v12, b2CollidePolygons_s_planePoint); + const tangent = b2Rot.MulRV(xf1.q, localTangent, b2CollidePolygons_s_tangent); + const normal = b2Vec2.CrossVOne(tangent, b2CollidePolygons_s_normal); + const v11 = b2Transform.MulXV(xf1, local_v11, b2CollidePolygons_s_v11); + const v12 = b2Transform.MulXV(xf1, local_v12, b2CollidePolygons_s_v12); + // Face offset. + const frontOffset = b2Vec2.DotVV(normal, v11); + // Side offsets, extended by polytope skin thickness. + const sideOffset1 = -b2Vec2.DotVV(tangent, v11) + totalRadius; + const sideOffset2 = b2Vec2.DotVV(tangent, v12) + totalRadius; + // Clip incident edge against extruded edge1 side edges. + const clipPoints1 = b2CollidePolygons_s_clipPoints1; + const clipPoints2 = b2CollidePolygons_s_clipPoints2; + let np; + // Clip to box side 1 + const ntangent = b2Vec2.NegV(tangent, b2CollidePolygons_s_ntangent); + np = b2ClipSegmentToLine(clipPoints1, incidentEdge, ntangent, sideOffset1, iv1); + if (np < 2) { + return; + } + // Clip to negative box side 1 + np = b2ClipSegmentToLine(clipPoints2, clipPoints1, tangent, sideOffset2, iv2); + if (np < 2) { + return; + } + // Now clipPoints2 contains the clipped points. + manifold.localNormal.Copy(localNormal); + manifold.localPoint.Copy(planePoint); + let pointCount = 0; + for (let i = 0; i < b2_maxManifoldPoints; ++i) { + const cv = clipPoints2[i]; + const separation = b2Vec2.DotVV(normal, cv.v) - frontOffset; + if (separation <= totalRadius) { + const cp = manifold.points[pointCount]; + b2Transform.MulTXV(xf2, cv.v, cp.localPoint); + cp.id.Copy(cv.id); + if (flip) { + // Swap features + const cf = cp.id.cf; + cp.id.cf.indexA = cf.indexB; + cp.id.cf.indexB = cf.indexA; + cp.id.cf.typeA = cf.typeB; + cp.id.cf.typeB = cf.typeA; + } + ++pointCount; + } + } + manifold.pointCount = pointCount; + } + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// A solid convex polygon. It is assumed that the interior of the polygon is to + /// the left of each edge. + /// In most cases you should not need many vertices for a convex polygon. + class b2PolygonShape extends b2Shape { + constructor() { + super(exports.b2ShapeType.e_polygonShape, b2_polygonRadius); + this.m_centroid = new b2Vec2(0, 0); + this.m_vertices = []; + this.m_normals = []; + this.m_count = 0; + } + /// Implement b2Shape. + Clone() { + return new b2PolygonShape().Copy(this); + } + Copy(other) { + super.Copy(other); + // DEBUG: b2Assert(other instanceof b2PolygonShape); + this.m_centroid.Copy(other.m_centroid); + this.m_count = other.m_count; + this.m_vertices = b2Vec2.MakeArray(this.m_count); + this.m_normals = b2Vec2.MakeArray(this.m_count); + for (let i = 0; i < this.m_count; ++i) { + this.m_vertices[i].Copy(other.m_vertices[i]); + this.m_normals[i].Copy(other.m_normals[i]); + } + return this; + } + /// @see b2Shape::GetChildCount + GetChildCount() { + return 1; + } + Set(...args) { + if (typeof args[0][0] === "number") { + const vertices = args[0]; + if (vertices.length % 2 !== 0) { + throw new Error(); + } + return this._Set((index) => ({ x: vertices[index * 2], y: vertices[index * 2 + 1] }), vertices.length / 2); + } + else { + const vertices = args[0]; + const count = args[1] || vertices.length; + return this._Set((index) => vertices[index], count); + } + } + _Set(vertices, count) { + // DEBUG: b2Assert(3 <= count); + if (count < 3) { + return this.SetAsBox(1, 1); + } + let n = count; + // Perform welding and copy vertices into local buffer. + const ps = []; + for (let i = 0; i < n; ++i) { + const /*b2Vec2*/ v = vertices(i); + let /*bool*/ unique = true; + for (let /*int32*/ j = 0; j < ps.length; ++j) { + if (b2Vec2.DistanceSquaredVV(v, ps[j]) < ((0.5 * b2_linearSlop) * (0.5 * b2_linearSlop))) { + unique = false; + break; + } + } + if (unique) { + ps.push(v); + } + } + n = ps.length; + if (n < 3) { + // Polygon is degenerate. + // DEBUG: b2Assert(false); + return this.SetAsBox(1.0, 1.0); + } + // Create the convex hull using the Gift wrapping algorithm + // http://en.wikipedia.org/wiki/Gift_wrapping_algorithm + // Find the right most point on the hull + let i0 = 0; + let x0 = ps[0].x; + for (let i = 1; i < n; ++i) { + const x = ps[i].x; + if (x > x0 || (x === x0 && ps[i].y < ps[i0].y)) { + i0 = i; + x0 = x; + } + } + const hull = []; + let m = 0; + let ih = i0; + for (;;) { + hull[m] = ih; + let ie = 0; + for (let j = 1; j < n; ++j) { + if (ie === ih) { + ie = j; + continue; + } + const r = b2Vec2.SubVV(ps[ie], ps[hull[m]], b2PolygonShape.Set_s_r); + const v = b2Vec2.SubVV(ps[j], ps[hull[m]], b2PolygonShape.Set_s_v); + const c = b2Vec2.CrossVV(r, v); + if (c < 0) { + ie = j; + } + // Collinearity check + if (c === 0 && v.LengthSquared() > r.LengthSquared()) { + ie = j; + } + } + ++m; + ih = ie; + if (ie === i0) { + break; + } + } + this.m_count = m; + this.m_vertices = b2Vec2.MakeArray(this.m_count); + this.m_normals = b2Vec2.MakeArray(this.m_count); + // Copy vertices. + for (let i = 0; i < m; ++i) { + this.m_vertices[i].Copy(ps[hull[i]]); + } + // Compute normals. Ensure the edges have non-zero length. + for (let i = 0; i < m; ++i) { + const vertexi1 = this.m_vertices[i]; + const vertexi2 = this.m_vertices[(i + 1) % m]; + const edge = b2Vec2.SubVV(vertexi2, vertexi1, b2Vec2.s_t0); // edge uses s_t0 + // DEBUG: b2Assert(edge.LengthSquared() > b2_epsilon_sq); + b2Vec2.CrossVOne(edge, this.m_normals[i]).SelfNormalize(); + } + // Compute the polygon centroid. + b2PolygonShape.ComputeCentroid(this.m_vertices, m, this.m_centroid); + return this; + } + /// Build vertices to represent an axis-aligned box or an oriented box. + /// @param hx the half-width. + /// @param hy the half-height. + /// @param center the center of the box in local coordinates. + /// @param angle the rotation of the box in local coordinates. + SetAsBox(hx, hy, center, angle = 0) { + this.m_count = 4; + this.m_vertices = b2Vec2.MakeArray(this.m_count); + this.m_normals = b2Vec2.MakeArray(this.m_count); + this.m_vertices[0].Set((-hx), (-hy)); + this.m_vertices[1].Set(hx, (-hy)); + this.m_vertices[2].Set(hx, hy); + this.m_vertices[3].Set((-hx), hy); + this.m_normals[0].Set(0, (-1)); + this.m_normals[1].Set(1, 0); + this.m_normals[2].Set(0, 1); + this.m_normals[3].Set((-1), 0); + this.m_centroid.SetZero(); + if (center) { + this.m_centroid.Copy(center); + const xf = new b2Transform(); + xf.SetPosition(center); + xf.SetRotationAngle(angle); + // Transform vertices and normals. + for (let i = 0; i < this.m_count; ++i) { + b2Transform.MulXV(xf, this.m_vertices[i], this.m_vertices[i]); + b2Rot.MulRV(xf.q, this.m_normals[i], this.m_normals[i]); + } + } + return this; + } + TestPoint(xf, p) { + const pLocal = b2Transform.MulTXV(xf, p, b2PolygonShape.TestPoint_s_pLocal); + for (let i = 0; i < this.m_count; ++i) { + const dot = b2Vec2.DotVV(this.m_normals[i], b2Vec2.SubVV(pLocal, this.m_vertices[i], b2Vec2.s_t0)); + if (dot > 0) { + return false; + } + } + return true; + } + RayCast(output, input, xf, childIndex) { + // Put the ray into the polygon's frame of reference. + const p1 = b2Transform.MulTXV(xf, input.p1, b2PolygonShape.RayCast_s_p1); + const p2 = b2Transform.MulTXV(xf, input.p2, b2PolygonShape.RayCast_s_p2); + const d = b2Vec2.SubVV(p2, p1, b2PolygonShape.RayCast_s_d); + let lower = 0, upper = input.maxFraction; + let index = -1; + for (let i = 0; i < this.m_count; ++i) { + // p = p1 + a * d + // dot(normal, p - v) = 0 + // dot(normal, p1 - v) + a * dot(normal, d) = 0 + const numerator = b2Vec2.DotVV(this.m_normals[i], b2Vec2.SubVV(this.m_vertices[i], p1, b2Vec2.s_t0)); + const denominator = b2Vec2.DotVV(this.m_normals[i], d); + if (denominator === 0) { + if (numerator < 0) { + return false; + } + } + else { + // Note: we want this predicate without division: + // lower < numerator / denominator, where denominator < 0 + // Since denominator < 0, we have to flip the inequality: + // lower < numerator / denominator <==> denominator * lower > numerator. + if (denominator < 0 && numerator < lower * denominator) { + // Increase lower. + // The segment enters this half-space. + lower = numerator / denominator; + index = i; + } + else if (denominator > 0 && numerator < upper * denominator) { + // Decrease upper. + // The segment exits this half-space. + upper = numerator / denominator; + } + } + // The use of epsilon here causes the assert on lower to trip + // in some cases. Apparently the use of epsilon was to make edge + // shapes work, but now those are handled separately. + // if (upper < lower - b2_epsilon) + if (upper < lower) { + return false; + } + } + // DEBUG: b2Assert(0 <= lower && lower <= input.maxFraction); + if (index >= 0) { + output.fraction = lower; + b2Rot.MulRV(xf.q, this.m_normals[index], output.normal); + return true; + } + return false; + } + ComputeAABB(aabb, xf, childIndex) { + const lower = b2Transform.MulXV(xf, this.m_vertices[0], aabb.lowerBound); + const upper = aabb.upperBound.Copy(lower); + for (let i = 0; i < this.m_count; ++i) { + const v = b2Transform.MulXV(xf, this.m_vertices[i], b2PolygonShape.ComputeAABB_s_v); + b2Vec2.MinV(v, lower, lower); + b2Vec2.MaxV(v, upper, upper); + } + const r = this.m_radius; + lower.SelfSubXY(r, r); + upper.SelfAddXY(r, r); + } + ComputeMass(massData, density) { + // Polygon mass, centroid, and inertia. + // Let rho be the polygon density in mass per unit area. + // Then: + // mass = rho * int(dA) + // centroid.x = (1/mass) * rho * int(x * dA) + // centroid.y = (1/mass) * rho * int(y * dA) + // I = rho * int((x*x + y*y) * dA) + // + // We can compute these integrals by summing all the integrals + // for each triangle of the polygon. To evaluate the integral + // for a single triangle, we make a change of variables to + // the (u,v) coordinates of the triangle: + // x = x0 + e1x * u + e2x * v + // y = y0 + e1y * u + e2y * v + // where 0 <= u && 0 <= v && u + v <= 1. + // + // We integrate u from [0,1-v] and then v from [0,1]. + // We also need to use the Jacobian of the transformation: + // D = cross(e1, e2) + // + // Simplification: triangle centroid = (1/3) * (p1 + p2 + p3) + // + // The rest of the derivation is handled by computer algebra. + // DEBUG: b2Assert(this.m_count >= 3); + const center = b2PolygonShape.ComputeMass_s_center.SetZero(); + let area = 0; + let I = 0; + // Get a reference point for forming triangles. + // Use the first vertex to reduce round-off errors. + const s = b2PolygonShape.ComputeMass_s_s.Copy(this.m_vertices[0]); + const k_inv3 = 1 / 3; + for (let i = 0; i < this.m_count; ++i) { + // Triangle vertices. + const e1 = b2Vec2.SubVV(this.m_vertices[i], s, b2PolygonShape.ComputeMass_s_e1); + const e2 = b2Vec2.SubVV(this.m_vertices[(i + 1) % this.m_count], s, b2PolygonShape.ComputeMass_s_e2); + const D = b2Vec2.CrossVV(e1, e2); + const triangleArea = 0.5 * D; + area += triangleArea; + // Area weighted centroid + center.SelfAdd(b2Vec2.MulSV(triangleArea * k_inv3, b2Vec2.AddVV(e1, e2, b2Vec2.s_t0), b2Vec2.s_t1)); + const ex1 = e1.x; + const ey1 = e1.y; + const ex2 = e2.x; + const ey2 = e2.y; + const intx2 = ex1 * ex1 + ex2 * ex1 + ex2 * ex2; + const inty2 = ey1 * ey1 + ey2 * ey1 + ey2 * ey2; + I += (0.25 * k_inv3 * D) * (intx2 + inty2); + } + // Total mass + massData.mass = density * area; + // Center of mass + // DEBUG: b2Assert(area > b2_epsilon); + center.SelfMul(1 / area); + b2Vec2.AddVV(center, s, massData.center); + // Inertia tensor relative to the local origin (point s). + massData.I = density * I; + // Shift to center of mass then to original body origin. + massData.I += massData.mass * (b2Vec2.DotVV(massData.center, massData.center) - b2Vec2.DotVV(center, center)); + } + Validate() { + for (let i = 0; i < this.m_count; ++i) { + const i1 = i; + const i2 = (i + 1) % this.m_count; + const p = this.m_vertices[i1]; + const e = b2Vec2.SubVV(this.m_vertices[i2], p, b2PolygonShape.Validate_s_e); + for (let j = 0; j < this.m_count; ++j) { + if (j === i1 || j === i2) { + continue; + } + const v = b2Vec2.SubVV(this.m_vertices[j], p, b2PolygonShape.Validate_s_v); + const c = b2Vec2.CrossVV(e, v); + if (c < 0) { + return false; + } + } + } + return true; + } + SetupDistanceProxy(proxy, index) { + proxy.m_vertices = this.m_vertices; + proxy.m_count = this.m_count; + proxy.m_radius = this.m_radius; + } + ComputeSubmergedArea(normal, offset, xf, c) { + // Transform plane into shape co-ordinates + const normalL = b2Rot.MulTRV(xf.q, normal, b2PolygonShape.ComputeSubmergedArea_s_normalL); + const offsetL = offset - b2Vec2.DotVV(normal, xf.p); + const depths = []; + let diveCount = 0; + let intoIndex = -1; + let outoIndex = -1; + let lastSubmerged = false; + for (let i = 0; i < this.m_count; ++i) { + depths[i] = b2Vec2.DotVV(normalL, this.m_vertices[i]) - offsetL; + const isSubmerged = depths[i] < (-b2_epsilon); + if (i > 0) { + if (isSubmerged) { + if (!lastSubmerged) { + intoIndex = i - 1; + diveCount++; + } + } + else { + if (lastSubmerged) { + outoIndex = i - 1; + diveCount++; + } + } + } + lastSubmerged = isSubmerged; + } + switch (diveCount) { + case 0: + if (lastSubmerged) { + // Completely submerged + const md = b2PolygonShape.ComputeSubmergedArea_s_md; + this.ComputeMass(md, 1); + b2Transform.MulXV(xf, md.center, c); + return md.mass; + } + else { + // Completely dry + return 0; + } + case 1: + if (intoIndex === (-1)) { + intoIndex = this.m_count - 1; + } + else { + outoIndex = this.m_count - 1; + } + break; + } + const intoIndex2 = ((intoIndex + 1) % this.m_count); + const outoIndex2 = ((outoIndex + 1) % this.m_count); + const intoLamdda = (0 - depths[intoIndex]) / (depths[intoIndex2] - depths[intoIndex]); + const outoLamdda = (0 - depths[outoIndex]) / (depths[outoIndex2] - depths[outoIndex]); + const intoVec = b2PolygonShape.ComputeSubmergedArea_s_intoVec.Set(this.m_vertices[intoIndex].x * (1 - intoLamdda) + this.m_vertices[intoIndex2].x * intoLamdda, this.m_vertices[intoIndex].y * (1 - intoLamdda) + this.m_vertices[intoIndex2].y * intoLamdda); + const outoVec = b2PolygonShape.ComputeSubmergedArea_s_outoVec.Set(this.m_vertices[outoIndex].x * (1 - outoLamdda) + this.m_vertices[outoIndex2].x * outoLamdda, this.m_vertices[outoIndex].y * (1 - outoLamdda) + this.m_vertices[outoIndex2].y * outoLamdda); + // Initialize accumulator + let area = 0; + const center = b2PolygonShape.ComputeSubmergedArea_s_center.SetZero(); + let p2 = this.m_vertices[intoIndex2]; + let p3; + // An awkward loop from intoIndex2+1 to outIndex2 + let i = intoIndex2; + while (i !== outoIndex2) { + i = (i + 1) % this.m_count; + if (i === outoIndex2) { + p3 = outoVec; + } + else { + p3 = this.m_vertices[i]; + } + const triangleArea = 0.5 * ((p2.x - intoVec.x) * (p3.y - intoVec.y) - (p2.y - intoVec.y) * (p3.x - intoVec.x)); + area += triangleArea; + // Area weighted centroid + center.x += triangleArea * (intoVec.x + p2.x + p3.x) / 3; + center.y += triangleArea * (intoVec.y + p2.y + p3.y) / 3; + p2 = p3; + } + // Normalize and transform centroid + center.SelfMul(1 / area); + b2Transform.MulXV(xf, center, c); + return area; + } + Dump(log) { + log(" const shape: b2PolygonShape = new b2PolygonShape();\n"); + log(" const vs: b2Vec2[] = [];\n"); + for (let i = 0; i < this.m_count; ++i) { + log(" vs[%d] = new b2Vec2(%.15f, %.15f);\n", i, this.m_vertices[i].x, this.m_vertices[i].y); + } + log(" shape.Set(vs, %d);\n", this.m_count); + } + static ComputeCentroid(vs, count, out) { + // DEBUG: b2Assert(count >= 3); + const c = out; + c.SetZero(); + let area = 0; + // Get a reference point for forming triangles. + // Use the first vertex to reduce round-off errors. + const s = b2PolygonShape.ComputeCentroid_s_s.Copy(vs[0]); + const inv3 = 1 / 3; + for (let i = 0; i < count; ++i) { + // Triangle vertices. + const p1 = b2Vec2.SubVV(vs[0], s, b2PolygonShape.ComputeCentroid_s_p1); + const p2 = b2Vec2.SubVV(vs[i], s, b2PolygonShape.ComputeCentroid_s_p2); + const p3 = b2Vec2.SubVV(vs[(i + 1) % count], s, b2PolygonShape.ComputeCentroid_s_p3); + const e1 = b2Vec2.SubVV(p2, p1, b2PolygonShape.ComputeCentroid_s_e1); + const e2 = b2Vec2.SubVV(p3, p1, b2PolygonShape.ComputeCentroid_s_e2); + const D = b2Vec2.CrossVV(e1, e2); + const triangleArea = 0.5 * D; + area += triangleArea; + // Area weighted centroid + c.x += triangleArea * inv3 * (p1.x + p2.x + p3.x); + c.y += triangleArea * inv3 * (p1.y + p2.y + p3.y); + } + // Centroid + // DEBUG: b2Assert(area > b2_epsilon); + // c = (1.0f / area) * c + s; + c.x = (1 / area) * c.x + s.x; + c.y = (1 / area) * c.y + s.y; + return c; + } + } + /// Create a convex hull from the given array of points. + /// @warning the points may be re-ordered, even if they form a convex polygon + /// @warning collinear points are handled but not removed. Collinear points + /// may lead to poor stacking behavior. + b2PolygonShape.Set_s_r = new b2Vec2(); + b2PolygonShape.Set_s_v = new b2Vec2(); + /// @see b2Shape::TestPoint + b2PolygonShape.TestPoint_s_pLocal = new b2Vec2(); + /// Implement b2Shape. + /// @note because the polygon is solid, rays that start inside do not hit because the normal is + /// not defined. + b2PolygonShape.RayCast_s_p1 = new b2Vec2(); + b2PolygonShape.RayCast_s_p2 = new b2Vec2(); + b2PolygonShape.RayCast_s_d = new b2Vec2(); + /// @see b2Shape::ComputeAABB + b2PolygonShape.ComputeAABB_s_v = new b2Vec2(); + /// @see b2Shape::ComputeMass + b2PolygonShape.ComputeMass_s_center = new b2Vec2(); + b2PolygonShape.ComputeMass_s_s = new b2Vec2(); + b2PolygonShape.ComputeMass_s_e1 = new b2Vec2(); + b2PolygonShape.ComputeMass_s_e2 = new b2Vec2(); + b2PolygonShape.Validate_s_e = new b2Vec2(); + b2PolygonShape.Validate_s_v = new b2Vec2(); + b2PolygonShape.ComputeSubmergedArea_s_normalL = new b2Vec2(); + b2PolygonShape.ComputeSubmergedArea_s_md = new b2MassData(); + b2PolygonShape.ComputeSubmergedArea_s_intoVec = new b2Vec2(); + b2PolygonShape.ComputeSubmergedArea_s_outoVec = new b2Vec2(); + b2PolygonShape.ComputeSubmergedArea_s_center = new b2Vec2(); + b2PolygonShape.ComputeCentroid_s_s = new b2Vec2(); + b2PolygonShape.ComputeCentroid_s_p1 = new b2Vec2(); + b2PolygonShape.ComputeCentroid_s_p2 = new b2Vec2(); + b2PolygonShape.ComputeCentroid_s_p3 = new b2Vec2(); + b2PolygonShape.ComputeCentroid_s_e1 = new b2Vec2(); + b2PolygonShape.ComputeCentroid_s_e2 = new b2Vec2(); + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + exports.b2_toiTime = 0; + exports.b2_toiMaxTime = 0; + exports.b2_toiCalls = 0; + exports.b2_toiIters = 0; + exports.b2_toiMaxIters = 0; + exports.b2_toiRootIters = 0; + exports.b2_toiMaxRootIters = 0; + function b2_toi_reset() { + exports.b2_toiTime = 0; + exports.b2_toiMaxTime = 0; + exports.b2_toiCalls = 0; + exports.b2_toiIters = 0; + exports.b2_toiMaxIters = 0; + exports.b2_toiRootIters = 0; + exports.b2_toiMaxRootIters = 0; + } + const b2TimeOfImpact_s_xfA = new b2Transform(); + const b2TimeOfImpact_s_xfB = new b2Transform(); + const b2TimeOfImpact_s_pointA = new b2Vec2(); + const b2TimeOfImpact_s_pointB = new b2Vec2(); + const b2TimeOfImpact_s_normal = new b2Vec2(); + const b2TimeOfImpact_s_axisA = new b2Vec2(); + const b2TimeOfImpact_s_axisB = new b2Vec2(); + /// Input parameters for b2TimeOfImpact + class b2TOIInput { + constructor() { + this.proxyA = new b2DistanceProxy(); + this.proxyB = new b2DistanceProxy(); + this.sweepA = new b2Sweep(); + this.sweepB = new b2Sweep(); + this.tMax = 0; // defines sweep interval [0, tMax] + } + } + /// Output parameters for b2TimeOfImpact. + exports.b2TOIOutputState = void 0; + (function (b2TOIOutputState) { + b2TOIOutputState[b2TOIOutputState["e_unknown"] = 0] = "e_unknown"; + b2TOIOutputState[b2TOIOutputState["e_failed"] = 1] = "e_failed"; + b2TOIOutputState[b2TOIOutputState["e_overlapped"] = 2] = "e_overlapped"; + b2TOIOutputState[b2TOIOutputState["e_touching"] = 3] = "e_touching"; + b2TOIOutputState[b2TOIOutputState["e_separated"] = 4] = "e_separated"; + })(exports.b2TOIOutputState || (exports.b2TOIOutputState = {})); + class b2TOIOutput { + constructor() { + this.state = exports.b2TOIOutputState.e_unknown; + this.t = 0; + } + } + exports.b2SeparationFunctionType = void 0; + (function (b2SeparationFunctionType) { + b2SeparationFunctionType[b2SeparationFunctionType["e_unknown"] = -1] = "e_unknown"; + b2SeparationFunctionType[b2SeparationFunctionType["e_points"] = 0] = "e_points"; + b2SeparationFunctionType[b2SeparationFunctionType["e_faceA"] = 1] = "e_faceA"; + b2SeparationFunctionType[b2SeparationFunctionType["e_faceB"] = 2] = "e_faceB"; + })(exports.b2SeparationFunctionType || (exports.b2SeparationFunctionType = {})); + class b2SeparationFunction { + constructor() { + this.m_sweepA = new b2Sweep(); + this.m_sweepB = new b2Sweep(); + this.m_type = exports.b2SeparationFunctionType.e_unknown; + this.m_localPoint = new b2Vec2(); + this.m_axis = new b2Vec2(); + } + Initialize(cache, proxyA, sweepA, proxyB, sweepB, t1) { + this.m_proxyA = proxyA; + this.m_proxyB = proxyB; + const count = cache.count; + // DEBUG: b2Assert(0 < count && count < 3); + this.m_sweepA.Copy(sweepA); + this.m_sweepB.Copy(sweepB); + const xfA = b2TimeOfImpact_s_xfA; + const xfB = b2TimeOfImpact_s_xfB; + this.m_sweepA.GetTransform(xfA, t1); + this.m_sweepB.GetTransform(xfB, t1); + if (count === 1) { + this.m_type = exports.b2SeparationFunctionType.e_points; + const localPointA = this.m_proxyA.GetVertex(cache.indexA[0]); + const localPointB = this.m_proxyB.GetVertex(cache.indexB[0]); + const pointA = b2Transform.MulXV(xfA, localPointA, b2TimeOfImpact_s_pointA); + const pointB = b2Transform.MulXV(xfB, localPointB, b2TimeOfImpact_s_pointB); + b2Vec2.SubVV(pointB, pointA, this.m_axis); + const s = this.m_axis.Normalize(); + return s; + } + else if (cache.indexA[0] === cache.indexA[1]) { + // Two points on B and one on A. + this.m_type = exports.b2SeparationFunctionType.e_faceB; + const localPointB1 = this.m_proxyB.GetVertex(cache.indexB[0]); + const localPointB2 = this.m_proxyB.GetVertex(cache.indexB[1]); + b2Vec2.CrossVOne(b2Vec2.SubVV(localPointB2, localPointB1, b2Vec2.s_t0), this.m_axis).SelfNormalize(); + const normal = b2Rot.MulRV(xfB.q, this.m_axis, b2TimeOfImpact_s_normal); + b2Vec2.MidVV(localPointB1, localPointB2, this.m_localPoint); + const pointB = b2Transform.MulXV(xfB, this.m_localPoint, b2TimeOfImpact_s_pointB); + const localPointA = this.m_proxyA.GetVertex(cache.indexA[0]); + const pointA = b2Transform.MulXV(xfA, localPointA, b2TimeOfImpact_s_pointA); + let s = b2Vec2.DotVV(b2Vec2.SubVV(pointA, pointB, b2Vec2.s_t0), normal); + if (s < 0) { + this.m_axis.SelfNeg(); + s = -s; + } + return s; + } + else { + // Two points on A and one or two points on B. + this.m_type = exports.b2SeparationFunctionType.e_faceA; + const localPointA1 = this.m_proxyA.GetVertex(cache.indexA[0]); + const localPointA2 = this.m_proxyA.GetVertex(cache.indexA[1]); + b2Vec2.CrossVOne(b2Vec2.SubVV(localPointA2, localPointA1, b2Vec2.s_t0), this.m_axis).SelfNormalize(); + const normal = b2Rot.MulRV(xfA.q, this.m_axis, b2TimeOfImpact_s_normal); + b2Vec2.MidVV(localPointA1, localPointA2, this.m_localPoint); + const pointA = b2Transform.MulXV(xfA, this.m_localPoint, b2TimeOfImpact_s_pointA); + const localPointB = this.m_proxyB.GetVertex(cache.indexB[0]); + const pointB = b2Transform.MulXV(xfB, localPointB, b2TimeOfImpact_s_pointB); + let s = b2Vec2.DotVV(b2Vec2.SubVV(pointB, pointA, b2Vec2.s_t0), normal); + if (s < 0) { + this.m_axis.SelfNeg(); + s = -s; + } + return s; + } + } + FindMinSeparation(indexA, indexB, t) { + const xfA = b2TimeOfImpact_s_xfA; + const xfB = b2TimeOfImpact_s_xfB; + this.m_sweepA.GetTransform(xfA, t); + this.m_sweepB.GetTransform(xfB, t); + switch (this.m_type) { + case exports.b2SeparationFunctionType.e_points: { + const axisA = b2Rot.MulTRV(xfA.q, this.m_axis, b2TimeOfImpact_s_axisA); + const axisB = b2Rot.MulTRV(xfB.q, b2Vec2.NegV(this.m_axis, b2Vec2.s_t0), b2TimeOfImpact_s_axisB); + indexA[0] = this.m_proxyA.GetSupport(axisA); + indexB[0] = this.m_proxyB.GetSupport(axisB); + const localPointA = this.m_proxyA.GetVertex(indexA[0]); + const localPointB = this.m_proxyB.GetVertex(indexB[0]); + const pointA = b2Transform.MulXV(xfA, localPointA, b2TimeOfImpact_s_pointA); + const pointB = b2Transform.MulXV(xfB, localPointB, b2TimeOfImpact_s_pointB); + const separation = b2Vec2.DotVV(b2Vec2.SubVV(pointB, pointA, b2Vec2.s_t0), this.m_axis); + return separation; + } + case exports.b2SeparationFunctionType.e_faceA: { + const normal = b2Rot.MulRV(xfA.q, this.m_axis, b2TimeOfImpact_s_normal); + const pointA = b2Transform.MulXV(xfA, this.m_localPoint, b2TimeOfImpact_s_pointA); + const axisB = b2Rot.MulTRV(xfB.q, b2Vec2.NegV(normal, b2Vec2.s_t0), b2TimeOfImpact_s_axisB); + indexA[0] = -1; + indexB[0] = this.m_proxyB.GetSupport(axisB); + const localPointB = this.m_proxyB.GetVertex(indexB[0]); + const pointB = b2Transform.MulXV(xfB, localPointB, b2TimeOfImpact_s_pointB); + const separation = b2Vec2.DotVV(b2Vec2.SubVV(pointB, pointA, b2Vec2.s_t0), normal); + return separation; + } + case exports.b2SeparationFunctionType.e_faceB: { + const normal = b2Rot.MulRV(xfB.q, this.m_axis, b2TimeOfImpact_s_normal); + const pointB = b2Transform.MulXV(xfB, this.m_localPoint, b2TimeOfImpact_s_pointB); + const axisA = b2Rot.MulTRV(xfA.q, b2Vec2.NegV(normal, b2Vec2.s_t0), b2TimeOfImpact_s_axisA); + indexB[0] = -1; + indexA[0] = this.m_proxyA.GetSupport(axisA); + const localPointA = this.m_proxyA.GetVertex(indexA[0]); + const pointA = b2Transform.MulXV(xfA, localPointA, b2TimeOfImpact_s_pointA); + const separation = b2Vec2.DotVV(b2Vec2.SubVV(pointA, pointB, b2Vec2.s_t0), normal); + return separation; + } + default: + // DEBUG: b2Assert(false); + indexA[0] = -1; + indexB[0] = -1; + return 0; + } + } + Evaluate(indexA, indexB, t) { + const xfA = b2TimeOfImpact_s_xfA; + const xfB = b2TimeOfImpact_s_xfB; + this.m_sweepA.GetTransform(xfA, t); + this.m_sweepB.GetTransform(xfB, t); + switch (this.m_type) { + case exports.b2SeparationFunctionType.e_points: { + const localPointA = this.m_proxyA.GetVertex(indexA); + const localPointB = this.m_proxyB.GetVertex(indexB); + const pointA = b2Transform.MulXV(xfA, localPointA, b2TimeOfImpact_s_pointA); + const pointB = b2Transform.MulXV(xfB, localPointB, b2TimeOfImpact_s_pointB); + const separation = b2Vec2.DotVV(b2Vec2.SubVV(pointB, pointA, b2Vec2.s_t0), this.m_axis); + return separation; + } + case exports.b2SeparationFunctionType.e_faceA: { + const normal = b2Rot.MulRV(xfA.q, this.m_axis, b2TimeOfImpact_s_normal); + const pointA = b2Transform.MulXV(xfA, this.m_localPoint, b2TimeOfImpact_s_pointA); + const localPointB = this.m_proxyB.GetVertex(indexB); + const pointB = b2Transform.MulXV(xfB, localPointB, b2TimeOfImpact_s_pointB); + const separation = b2Vec2.DotVV(b2Vec2.SubVV(pointB, pointA, b2Vec2.s_t0), normal); + return separation; + } + case exports.b2SeparationFunctionType.e_faceB: { + const normal = b2Rot.MulRV(xfB.q, this.m_axis, b2TimeOfImpact_s_normal); + const pointB = b2Transform.MulXV(xfB, this.m_localPoint, b2TimeOfImpact_s_pointB); + const localPointA = this.m_proxyA.GetVertex(indexA); + const pointA = b2Transform.MulXV(xfA, localPointA, b2TimeOfImpact_s_pointA); + const separation = b2Vec2.DotVV(b2Vec2.SubVV(pointA, pointB, b2Vec2.s_t0), normal); + return separation; + } + default: + // DEBUG: b2Assert(false); + return 0; + } + } + } + const b2TimeOfImpact_s_timer = new b2Timer(); + const b2TimeOfImpact_s_cache = new b2SimplexCache(); + const b2TimeOfImpact_s_distanceInput = new b2DistanceInput(); + const b2TimeOfImpact_s_distanceOutput = new b2DistanceOutput(); + const b2TimeOfImpact_s_fcn = new b2SeparationFunction(); + const b2TimeOfImpact_s_indexA = [0]; + const b2TimeOfImpact_s_indexB = [0]; + const b2TimeOfImpact_s_sweepA = new b2Sweep(); + const b2TimeOfImpact_s_sweepB = new b2Sweep(); + function b2TimeOfImpact(output, input) { + const timer = b2TimeOfImpact_s_timer.Reset(); + ++exports.b2_toiCalls; + output.state = exports.b2TOIOutputState.e_unknown; + output.t = input.tMax; + const proxyA = input.proxyA; + const proxyB = input.proxyB; + const maxVertices = b2Max(b2_maxPolygonVertices, b2Max(proxyA.m_count, proxyB.m_count)); + const sweepA = b2TimeOfImpact_s_sweepA.Copy(input.sweepA); + const sweepB = b2TimeOfImpact_s_sweepB.Copy(input.sweepB); + // Large rotations can make the root finder fail, so we normalize the + // sweep angles. + sweepA.Normalize(); + sweepB.Normalize(); + const tMax = input.tMax; + const totalRadius = proxyA.m_radius + proxyB.m_radius; + const target = b2Max(b2_linearSlop, totalRadius - 3 * b2_linearSlop); + const tolerance = 0.25 * b2_linearSlop; + // DEBUG: b2Assert(target > tolerance); + let t1 = 0; + const k_maxIterations = 20; // TODO_ERIN b2Settings + let iter = 0; + // Prepare input for distance query. + const cache = b2TimeOfImpact_s_cache; + cache.count = 0; + const distanceInput = b2TimeOfImpact_s_distanceInput; + distanceInput.proxyA.Copy(input.proxyA); + distanceInput.proxyB.Copy(input.proxyB); + distanceInput.useRadii = false; + // The outer loop progressively attempts to compute new separating axes. + // This loop terminates when an axis is repeated (no progress is made). + for (;;) { + const xfA = b2TimeOfImpact_s_xfA; + const xfB = b2TimeOfImpact_s_xfB; + sweepA.GetTransform(xfA, t1); + sweepB.GetTransform(xfB, t1); + // Get the distance between shapes. We can also use the results + // to get a separating axis. + distanceInput.transformA.Copy(xfA); + distanceInput.transformB.Copy(xfB); + const distanceOutput = b2TimeOfImpact_s_distanceOutput; + b2Distance(distanceOutput, cache, distanceInput); + // If the shapes are overlapped, we give up on continuous collision. + if (distanceOutput.distance <= 0) { + // Failure! + output.state = exports.b2TOIOutputState.e_overlapped; + output.t = 0; + break; + } + if (distanceOutput.distance < target + tolerance) { + // Victory! + output.state = exports.b2TOIOutputState.e_touching; + output.t = t1; + break; + } + // Initialize the separating axis. + const fcn = b2TimeOfImpact_s_fcn; + fcn.Initialize(cache, proxyA, sweepA, proxyB, sweepB, t1); + /* + #if 0 + // Dump the curve seen by the root finder { + const int32 N = 100; + float32 dx = 1.0f / N; + float32 xs[N+1]; + float32 fs[N+1]; + + float32 x = 0.0f; + + for (int32 i = 0; i <= N; ++i) { + sweepA.GetTransform(&xfA, x); + sweepB.GetTransform(&xfB, x); + float32 f = fcn.Evaluate(xfA, xfB) - target; + + printf("%g %g\n", x, f); + + xs[i] = x; + fs[i] = f; + + x += dx; + } + } + #endif + */ + // Compute the TOI on the separating axis. We do this by successively + // resolving the deepest point. This loop is bounded by the number of vertices. + let done = false; + let t2 = tMax; + let pushBackIter = 0; + for (;;) { + // Find the deepest point at t2. Store the witness point indices. + const indexA = b2TimeOfImpact_s_indexA; + const indexB = b2TimeOfImpact_s_indexB; + let s2 = fcn.FindMinSeparation(indexA, indexB, t2); + // Is the final configuration separated? + if (s2 > (target + tolerance)) { + // Victory! + output.state = exports.b2TOIOutputState.e_separated; + output.t = tMax; + done = true; + break; + } + // Has the separation reached tolerance? + if (s2 > (target - tolerance)) { + // Advance the sweeps + t1 = t2; + break; + } + // Compute the initial separation of the witness points. + let s1 = fcn.Evaluate(indexA[0], indexB[0], t1); + // Check for initial overlap. This might happen if the root finder + // runs out of iterations. + if (s1 < (target - tolerance)) { + output.state = exports.b2TOIOutputState.e_failed; + output.t = t1; + done = true; + break; + } + // Check for touching + if (s1 <= (target + tolerance)) { + // Victory! t1 should hold the TOI (could be 0.0). + output.state = exports.b2TOIOutputState.e_touching; + output.t = t1; + done = true; + break; + } + // Compute 1D root of: f(x) - target = 0 + let rootIterCount = 0; + let a1 = t1; + let a2 = t2; + for (;;) { + // Use a mix of the secant rule and bisection. + let t = 0; + if (rootIterCount & 1) { + // Secant rule to improve convergence. + t = a1 + (target - s1) * (a2 - a1) / (s2 - s1); + } + else { + // Bisection to guarantee progress. + t = 0.5 * (a1 + a2); + } + ++rootIterCount; + ++exports.b2_toiRootIters; + const s = fcn.Evaluate(indexA[0], indexB[0], t); + if (b2Abs(s - target) < tolerance) { + // t2 holds a tentative value for t1 + t2 = t; + break; + } + // Ensure we continue to bracket the root. + if (s > target) { + a1 = t; + s1 = s; + } + else { + a2 = t; + s2 = s; + } + if (rootIterCount === 50) { + break; + } + } + exports.b2_toiMaxRootIters = b2Max(exports.b2_toiMaxRootIters, rootIterCount); + ++pushBackIter; + if (pushBackIter === maxVertices) { + break; + } + } + ++iter; + ++exports.b2_toiIters; + if (done) { + break; + } + if (iter === k_maxIterations) { + // Root finder got stuck. Semi-victory. + output.state = exports.b2TOIOutputState.e_failed; + output.t = t1; + break; + } + } + exports.b2_toiMaxIters = b2Max(exports.b2_toiMaxIters, iter); + const time = timer.GetMilliseconds(); + exports.b2_toiMaxTime = b2Max(exports.b2_toiMaxTime, time); + exports.b2_toiTime += time; + } + + /* + * Copyright (c) 2006-2007 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + exports.b2JointType = void 0; + (function (b2JointType) { + b2JointType[b2JointType["e_unknownJoint"] = 0] = "e_unknownJoint"; + b2JointType[b2JointType["e_revoluteJoint"] = 1] = "e_revoluteJoint"; + b2JointType[b2JointType["e_prismaticJoint"] = 2] = "e_prismaticJoint"; + b2JointType[b2JointType["e_distanceJoint"] = 3] = "e_distanceJoint"; + b2JointType[b2JointType["e_pulleyJoint"] = 4] = "e_pulleyJoint"; + b2JointType[b2JointType["e_mouseJoint"] = 5] = "e_mouseJoint"; + b2JointType[b2JointType["e_gearJoint"] = 6] = "e_gearJoint"; + b2JointType[b2JointType["e_wheelJoint"] = 7] = "e_wheelJoint"; + b2JointType[b2JointType["e_weldJoint"] = 8] = "e_weldJoint"; + b2JointType[b2JointType["e_frictionJoint"] = 9] = "e_frictionJoint"; + b2JointType[b2JointType["e_ropeJoint"] = 10] = "e_ropeJoint"; + b2JointType[b2JointType["e_motorJoint"] = 11] = "e_motorJoint"; + b2JointType[b2JointType["e_areaJoint"] = 12] = "e_areaJoint"; + })(exports.b2JointType || (exports.b2JointType = {})); + class b2Jacobian { + constructor() { + this.linear = new b2Vec2(); + this.angularA = 0; + this.angularB = 0; + } + SetZero() { + this.linear.SetZero(); + this.angularA = 0; + this.angularB = 0; + return this; + } + Set(x, a1, a2) { + this.linear.Copy(x); + this.angularA = a1; + this.angularB = a2; + return this; + } + } + /// A joint edge is used to connect bodies and joints together + /// in a joint graph where each body is a node and each joint + /// is an edge. A joint edge belongs to a doubly linked list + /// maintained in each attached body. Each joint has two joint + /// nodes, one for each attached body. + class b2JointEdge { + constructor(joint) { + this._other = null; ///< provides quick access to the other body attached. + this.prev = null; ///< the previous joint edge in the body's joint list + this.next = null; ///< the next joint edge in the body's joint list + this.joint = joint; + } + get other() { + if (this._other === null) { + throw new Error(); + } + return this._other; + } + set other(value) { + if (this._other !== null) { + throw new Error(); + } + this._other = value; + } + Reset() { + this._other = null; + this.prev = null; + this.next = null; + } + } + /// Joint definitions are used to construct joints. + class b2JointDef { + constructor(type) { + /// The joint type is set automatically for concrete joint types. + this.type = exports.b2JointType.e_unknownJoint; + /// Use this to attach application specific data to your joints. + this.userData = null; + /// Set this flag to true if the attached bodies should collide. + this.collideConnected = false; + this.type = type; + } + } + /// Utility to compute linear stiffness values from frequency and damping ratio + // void b2LinearStiffness(float& stiffness, float& damping, + // float frequencyHertz, float dampingRatio, + // const b2Body* bodyA, const b2Body* bodyB); + // kylin: 这里是合理的,需要修改def的值;C++中为引用传递 + function b2LinearStiffness(def, frequencyHertz, dampingRatio, bodyA, bodyB) { + const massA = bodyA.GetMass(); + const massB = bodyB.GetMass(); + let mass; + if (massA > 0.0 && massB > 0.0) { + mass = massA * massB / (massA + massB); + } + else if (massA > 0.0) { + mass = massA; + } + else { + mass = massB; + } + const omega = 2.0 * b2_pi * frequencyHertz; + def.stiffness = mass * omega * omega; + def.damping = 2.0 * mass * dampingRatio * omega; + } + /// Utility to compute rotational stiffness values frequency and damping ratio + // void b2AngularStiffness(float& stiffness, float& damping, + // float frequencyHertz, float dampingRatio, + // const b2Body* bodyA, const b2Body* bodyB); + function b2AngularStiffness(def, frequencyHertz, dampingRatio, bodyA, bodyB) { + const IA = bodyA.GetInertia(); + const IB = bodyB.GetInertia(); + let I; + if (IA > 0.0 && IB > 0.0) { + I = IA * IB / (IA + IB); + } + else if (IA > 0.0) { + I = IA; + } + else { + I = IB; + } + const omega = 2.0 * b2_pi * frequencyHertz; + def.stiffness = I * omega * omega; + def.damping = 2.0 * I * dampingRatio * omega; + } + /// The base joint class. Joints are used to constraint two bodies together in + /// various fashions. Some joints also feature limits and motors. + class b2Joint { + constructor(def) { + // DEBUG: b2Assert(def.bodyA !== def.bodyB); + this.m_type = exports.b2JointType.e_unknownJoint; + this.m_prev = null; + this.m_next = null; + this.m_edgeA = new b2JointEdge(this); + this.m_edgeB = new b2JointEdge(this); + this.m_index = 0; + this.m_islandFlag = false; + this.m_collideConnected = false; + this.m_userData = null; + this.m_type = def.type; + this.m_edgeA.other = def.bodyB; + this.m_edgeB.other = def.bodyA; + this.m_bodyA = def.bodyA; + this.m_bodyB = def.bodyB; + this.m_collideConnected = b2Maybe(def.collideConnected, false); + this.m_userData = b2Maybe(def.userData, null); + } + /// Get the type of the concrete joint. + GetType() { + return this.m_type; + } + /// Get the first body attached to this joint. + GetBodyA() { + return this.m_bodyA; + } + /// Get the second body attached to this joint. + GetBodyB() { + return this.m_bodyB; + } + /// Get the next joint the world joint list. + GetNext() { + return this.m_next; + } + /// Get the user data pointer. + GetUserData() { + return this.m_userData; + } + /// Set the user data pointer. + SetUserData(data) { + this.m_userData = data; + } + /// Short-cut function to determine if either body is inactive. + IsEnabled() { + return this.m_bodyA.IsEnabled() && this.m_bodyB.IsEnabled(); + } + /// Get collide connected. + /// Note: modifying the collide connect flag won't work correctly because + /// the flag is only checked when fixture AABBs begin to overlap. + GetCollideConnected() { + return this.m_collideConnected; + } + /// Dump this joint to the log file. + Dump(log) { + log("// Dump is not supported for this joint type.\n"); + } + /// Shift the origin for any points stored in world coordinates. + ShiftOrigin(newOrigin) { } + Draw(draw) { + const xf1 = this.m_bodyA.GetTransform(); + const xf2 = this.m_bodyB.GetTransform(); + const x1 = xf1.p; + const x2 = xf2.p; + const p1 = this.GetAnchorA(b2Joint.Draw_s_p1); + const p2 = this.GetAnchorB(b2Joint.Draw_s_p2); + const color = b2Joint.Draw_s_color.SetRGB(0.5, 0.8, 0.8); + switch (this.m_type) { + case exports.b2JointType.e_distanceJoint: + draw.DrawSegment(p1, p2, color); + break; + case exports.b2JointType.e_pulleyJoint: + { + const pulley = this; + const s1 = pulley.GetGroundAnchorA(); + const s2 = pulley.GetGroundAnchorB(); + draw.DrawSegment(s1, p1, color); + draw.DrawSegment(s2, p2, color); + draw.DrawSegment(s1, s2, color); + } + break; + case exports.b2JointType.e_mouseJoint: + { + const c = b2Joint.Draw_s_c; + c.Set(0.0, 1.0, 0.0); + draw.DrawPoint(p1, 4.0, c); + draw.DrawPoint(p2, 4.0, c); + c.Set(0.8, 0.8, 0.8); + draw.DrawSegment(p1, p2, c); + } + break; + default: + draw.DrawSegment(x1, p1, color); + draw.DrawSegment(p1, p2, color); + draw.DrawSegment(x2, p2, color); + } + } + } + /// Debug draw this joint + b2Joint.Draw_s_p1 = new b2Vec2(); + b2Joint.Draw_s_p2 = new b2Vec2(); + b2Joint.Draw_s_color = new b2Color(0.5, 0.8, 0.8); + b2Joint.Draw_s_c = new b2Color(); + + /* + * Copyright (c) 2006-2007 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// Distance joint definition. This requires defining an + /// anchor point on both bodies and the non-zero length of the + /// distance joint. The definition uses local anchor points + /// so that the initial configuration can violate the constraint + /// slightly. This helps when saving and loading a game. + /// @warning Do not use a zero or short length. + class b2DistanceJointDef extends b2JointDef { + constructor() { + super(exports.b2JointType.e_distanceJoint); + this.localAnchorA = new b2Vec2(); + this.localAnchorB = new b2Vec2(); + this.length = 1; + this.minLength = 0; + this.maxLength = b2_maxFloat; // FLT_MAX; + this.stiffness = 0; + this.damping = 0; + } + Initialize(b1, b2, anchor1, anchor2) { + this.bodyA = b1; + this.bodyB = b2; + this.bodyA.GetLocalPoint(anchor1, this.localAnchorA); + this.bodyB.GetLocalPoint(anchor2, this.localAnchorB); + this.length = b2Max(b2Vec2.DistanceVV(anchor1, anchor2), b2_linearSlop); + this.minLength = this.length; + this.maxLength = this.length; + } + } + class b2DistanceJoint extends b2Joint { + constructor(def) { + super(def); + this.m_stiffness = 0; + this.m_damping = 0; + this.m_bias = 0; + this.m_length = 0; + this.m_minLength = 0; + this.m_maxLength = 0; + // Solver shared + this.m_localAnchorA = new b2Vec2(); + this.m_localAnchorB = new b2Vec2(); + this.m_gamma = 0; + this.m_impulse = 0; + this.m_lowerImpulse = 0; + this.m_upperImpulse = 0; + // Solver temp + this.m_indexA = 0; + this.m_indexB = 0; + this.m_u = new b2Vec2(); + this.m_rA = new b2Vec2(); + this.m_rB = new b2Vec2(); + this.m_localCenterA = new b2Vec2(); + this.m_localCenterB = new b2Vec2(); + this.m_currentLength = 0; + this.m_invMassA = 0; + this.m_invMassB = 0; + this.m_invIA = 0; + this.m_invIB = 0; + this.m_softMass = 0; + this.m_mass = 0; + this.m_qA = new b2Rot(); + this.m_qB = new b2Rot(); + this.m_lalcA = new b2Vec2(); + this.m_lalcB = new b2Vec2(); + this.m_localAnchorA.Copy(b2Maybe(def.localAnchorA, b2Vec2.ZERO)); + this.m_localAnchorB.Copy(b2Maybe(def.localAnchorB, b2Vec2.ZERO)); + this.m_length = b2Max(b2Maybe(def.length, this.GetCurrentLength()), b2_linearSlop); + this.m_minLength = b2Max(b2Maybe(def.minLength, this.m_length), b2_linearSlop); + this.m_maxLength = b2Max(b2Maybe(def.maxLength, this.m_length), this.m_minLength); + this.m_stiffness = b2Maybe(def.stiffness, 0); + this.m_damping = b2Maybe(def.damping, 0); + } + GetAnchorA(out) { + return this.m_bodyA.GetWorldPoint(this.m_localAnchorA, out); + } + GetAnchorB(out) { + return this.m_bodyB.GetWorldPoint(this.m_localAnchorB, out); + } + GetReactionForce(inv_dt, out) { + // b2Vec2 F = inv_dt * (m_impulse + m_lowerImpulse - m_upperImpulse) * m_u; + out.x = inv_dt * (this.m_impulse + this.m_lowerImpulse - this.m_upperImpulse) * this.m_u.x; + out.y = inv_dt * (this.m_impulse + this.m_lowerImpulse - this.m_upperImpulse) * this.m_u.y; + return out; + } + GetReactionTorque(inv_dt) { + return 0; + } + GetLocalAnchorA() { return this.m_localAnchorA; } + GetLocalAnchorB() { return this.m_localAnchorB; } + SetLength(length) { + this.m_impulse = 0; + this.m_length = b2Max(b2_linearSlop, length); + return this.m_length; + } + GetLength() { + return this.m_length; + } + SetMinLength(minLength) { + this.m_lowerImpulse = 0; + this.m_minLength = b2Clamp(minLength, b2_linearSlop, this.m_maxLength); + return this.m_minLength; + } + SetMaxLength(maxLength) { + this.m_upperImpulse = 0; + this.m_maxLength = b2Max(maxLength, this.m_minLength); + return this.m_maxLength; + } + GetCurrentLength() { + const pA = this.m_bodyA.GetWorldPoint(this.m_localAnchorA, new b2Vec2()); + const pB = this.m_bodyB.GetWorldPoint(this.m_localAnchorB, new b2Vec2()); + return b2Vec2.DistanceVV(pA, pB); + } + SetStiffness(stiffness) { + this.m_stiffness = stiffness; + } + GetStiffness() { + return this.m_stiffness; + } + SetDamping(damping) { + this.m_damping = damping; + } + GetDamping() { + return this.m_damping; + } + Dump(log) { + const indexA = this.m_bodyA.m_islandIndex; + const indexB = this.m_bodyB.m_islandIndex; + log(" const jd: b2DistanceJointDef = new b2DistanceJointDef();\n"); + log(" jd.bodyA = bodies[%d];\n", indexA); + log(" jd.bodyB = bodies[%d];\n", indexB); + log(" jd.collideConnected = %s;\n", (this.m_collideConnected) ? ("true") : ("false")); + log(" jd.localAnchorA.Set(%.15f, %.15f);\n", this.m_localAnchorA.x, this.m_localAnchorA.y); + log(" jd.localAnchorB.Set(%.15f, %.15f);\n", this.m_localAnchorB.x, this.m_localAnchorB.y); + log(" jd.length = %.15f;\n", this.m_length); + log(" jd.minLength = %.15f;\n", this.m_minLength); + log(" jd.maxLength = %.15f;\n", this.m_maxLength); + log(" jd.stiffness = %.15f;\n", this.m_stiffness); + log(" jd.damping = %.15f;\n", this.m_damping); + log(" joints[%d] = this.m_world.CreateJoint(jd);\n", this.m_index); + } + InitVelocityConstraints(data) { + this.m_indexA = this.m_bodyA.m_islandIndex; + this.m_indexB = this.m_bodyB.m_islandIndex; + this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter); + this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter); + this.m_invMassA = this.m_bodyA.m_invMass; + this.m_invMassB = this.m_bodyB.m_invMass; + this.m_invIA = this.m_bodyA.m_invI; + this.m_invIB = this.m_bodyB.m_invI; + const cA = data.positions[this.m_indexA].c; + const aA = data.positions[this.m_indexA].a; + const vA = data.velocities[this.m_indexA].v; + let wA = data.velocities[this.m_indexA].w; + const cB = data.positions[this.m_indexB].c; + const aB = data.positions[this.m_indexB].a; + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + // const qA: b2Rot = new b2Rot(aA), qB: b2Rot = new b2Rot(aB); + const qA = this.m_qA.SetAngle(aA), qB = this.m_qB.SetAngle(aB); + // m_rA = b2Mul(qA, m_localAnchorA - m_localCenterA); + b2Vec2.SubVV(this.m_localAnchorA, this.m_localCenterA, this.m_lalcA); + b2Rot.MulRV(qA, this.m_lalcA, this.m_rA); + // m_rB = b2Mul(qB, m_localAnchorB - m_localCenterB); + b2Vec2.SubVV(this.m_localAnchorB, this.m_localCenterB, this.m_lalcB); + b2Rot.MulRV(qB, this.m_lalcB, this.m_rB); + // m_u = cB + m_rB - cA - m_rA; + this.m_u.x = cB.x + this.m_rB.x - cA.x - this.m_rA.x; + this.m_u.y = cB.y + this.m_rB.y - cA.y - this.m_rA.y; + // Handle singularity. + this.m_currentLength = this.m_u.Length(); + if (this.m_currentLength > b2_linearSlop) { + this.m_u.SelfMul(1 / this.m_currentLength); + } + else { + this.m_u.SetZero(); + this.m_mass = 0; + this.m_impulse = 0; + this.m_lowerImpulse = 0; + this.m_upperImpulse = 0; + } + // float32 crAu = b2Cross(m_rA, m_u); + const crAu = b2Vec2.CrossVV(this.m_rA, this.m_u); + // float32 crBu = b2Cross(m_rB, m_u); + const crBu = b2Vec2.CrossVV(this.m_rB, this.m_u); + // float32 invMass = m_invMassA + m_invIA * crAu * crAu + m_invMassB + m_invIB * crBu * crBu; + let invMass = this.m_invMassA + this.m_invIA * crAu * crAu + this.m_invMassB + this.m_invIB * crBu * crBu; + this.m_mass = invMass !== 0 ? 1 / invMass : 0; + if (this.m_stiffness > 0 && this.m_minLength < this.m_maxLength) { + // soft + const C = this.m_currentLength - this.m_length; + const d = this.m_damping; + const k = this.m_stiffness; + // magic formulas + const h = data.step.dt; + // gamma = 1 / (h * (d + h * k)) + // the extra factor of h in the denominator is since the lambda is an impulse, not a force + this.m_gamma = h * (d + h * k); + this.m_gamma = this.m_gamma !== 0 ? 1 / this.m_gamma : 0; + this.m_bias = C * h * k * this.m_gamma; + invMass += this.m_gamma; + this.m_softMass = invMass !== 0 ? 1 / invMass : 0; + } + else { + // rigid + this.m_gamma = 0; + this.m_bias = 0; + this.m_softMass = this.m_mass; + } + if (data.step.warmStarting) { + // Scale the impulse to support a variable time step. + this.m_impulse *= data.step.dtRatio; + this.m_lowerImpulse *= data.step.dtRatio; + this.m_upperImpulse *= data.step.dtRatio; + const P = b2Vec2.MulSV(this.m_impulse + this.m_lowerImpulse - this.m_upperImpulse, this.m_u, b2DistanceJoint.InitVelocityConstraints_s_P); + vA.SelfMulSub(this.m_invMassA, P); + wA -= this.m_invIA * b2Vec2.CrossVV(this.m_rA, P); + vB.SelfMulAdd(this.m_invMassB, P); + wB += this.m_invIB * b2Vec2.CrossVV(this.m_rB, P); + } + else { + this.m_impulse = 0; + } + // data.velocities[this.m_indexA].v = vA; + data.velocities[this.m_indexA].w = wA; + // data.velocities[this.m_indexB].v = vB; + data.velocities[this.m_indexB].w = wB; + } + SolveVelocityConstraints(data) { + const vA = data.velocities[this.m_indexA].v; + let wA = data.velocities[this.m_indexA].w; + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + if (this.m_minLength < this.m_maxLength) { + if (this.m_stiffness > 0) { + // Cdot = dot(u, v + cross(w, r)) + const vpA = b2Vec2.AddVCrossSV(vA, wA, this.m_rA, b2DistanceJoint.SolveVelocityConstraints_s_vpA); + const vpB = b2Vec2.AddVCrossSV(vB, wB, this.m_rB, b2DistanceJoint.SolveVelocityConstraints_s_vpB); + const Cdot = b2Vec2.DotVV(this.m_u, b2Vec2.SubVV(vpB, vpA, b2Vec2.s_t0)); + const impulse = -this.m_softMass * (Cdot + this.m_bias + this.m_gamma * this.m_impulse); + this.m_impulse += impulse; + const P = b2Vec2.MulSV(impulse, this.m_u, b2DistanceJoint.SolveVelocityConstraints_s_P); + vA.SelfMulSub(this.m_invMassA, P); + wA -= this.m_invIA * b2Vec2.CrossVV(this.m_rA, P); + vB.SelfMulAdd(this.m_invMassB, P); + wB += this.m_invIB * b2Vec2.CrossVV(this.m_rB, P); + } + // lower + { + const C = this.m_currentLength - this.m_minLength; + const bias = b2Max(0, C) * data.step.inv_dt; + const vpA = b2Vec2.AddVCrossSV(vA, wA, this.m_rA, b2DistanceJoint.SolveVelocityConstraints_s_vpA); + const vpB = b2Vec2.AddVCrossSV(vB, wB, this.m_rB, b2DistanceJoint.SolveVelocityConstraints_s_vpB); + const Cdot = b2Vec2.DotVV(this.m_u, b2Vec2.SubVV(vpB, vpA, b2Vec2.s_t0)); + let impulse = -this.m_mass * (Cdot + bias); + const oldImpulse = this.m_lowerImpulse; + this.m_lowerImpulse = b2Max(0, this.m_lowerImpulse + impulse); + impulse = this.m_lowerImpulse - oldImpulse; + const P = b2Vec2.MulSV(impulse, this.m_u, b2DistanceJoint.SolveVelocityConstraints_s_P); + vA.SelfMulSub(this.m_invMassA, P); + wA -= this.m_invIA * b2Vec2.CrossVV(this.m_rA, P); + vB.SelfMulAdd(this.m_invMassB, P); + wB += this.m_invIB * b2Vec2.CrossVV(this.m_rB, P); + } + // upper + { + const C = this.m_maxLength - this.m_currentLength; + const bias = b2Max(0, C) * data.step.inv_dt; + const vpA = b2Vec2.AddVCrossSV(vA, wA, this.m_rA, b2DistanceJoint.SolveVelocityConstraints_s_vpA); + const vpB = b2Vec2.AddVCrossSV(vB, wB, this.m_rB, b2DistanceJoint.SolveVelocityConstraints_s_vpB); + const Cdot = b2Vec2.DotVV(this.m_u, b2Vec2.SubVV(vpA, vpB, b2Vec2.s_t0)); + let impulse = -this.m_mass * (Cdot + bias); + const oldImpulse = this.m_upperImpulse; + this.m_upperImpulse = b2Max(0, this.m_upperImpulse + impulse); + impulse = this.m_upperImpulse - oldImpulse; + const P = b2Vec2.MulSV(-impulse, this.m_u, b2DistanceJoint.SolveVelocityConstraints_s_P); + vA.SelfMulSub(this.m_invMassA, P); + wA -= this.m_invIA * b2Vec2.CrossVV(this.m_rA, P); + vB.SelfMulAdd(this.m_invMassB, P); + wB += this.m_invIB * b2Vec2.CrossVV(this.m_rB, P); + } + } + else { + // Equal limits + // Cdot = dot(u, v + cross(w, r)) + const vpA = b2Vec2.AddVCrossSV(vA, wA, this.m_rA, b2DistanceJoint.SolveVelocityConstraints_s_vpA); + const vpB = b2Vec2.AddVCrossSV(vB, wB, this.m_rB, b2DistanceJoint.SolveVelocityConstraints_s_vpB); + const Cdot = b2Vec2.DotVV(this.m_u, b2Vec2.SubVV(vpB, vpA, b2Vec2.s_t0)); + const impulse = -this.m_mass * Cdot; + this.m_impulse += impulse; + const P = b2Vec2.MulSV(impulse, this.m_u, b2DistanceJoint.SolveVelocityConstraints_s_P); + vA.SelfMulSub(this.m_invMassA, P); + wA -= this.m_invIA * b2Vec2.CrossVV(this.m_rA, P); + vB.SelfMulAdd(this.m_invMassB, P); + wB += this.m_invIB * b2Vec2.CrossVV(this.m_rB, P); + } + // data.velocities[this.m_indexA].v = vA; + data.velocities[this.m_indexA].w = wA; + // data.velocities[this.m_indexB].v = vB; + data.velocities[this.m_indexB].w = wB; + } + SolvePositionConstraints(data) { + const cA = data.positions[this.m_indexA].c; + let aA = data.positions[this.m_indexA].a; + const cB = data.positions[this.m_indexB].c; + let aB = data.positions[this.m_indexB].a; + // const qA: b2Rot = new b2Rot(aA), qB: b2Rot = new b2Rot(aB); + const qA = this.m_qA.SetAngle(aA), qB = this.m_qB.SetAngle(aB); + // b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); + const rA = b2Rot.MulRV(qA, this.m_lalcA, this.m_rA); // use m_rA + // b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); + const rB = b2Rot.MulRV(qB, this.m_lalcB, this.m_rB); // use m_rB + // b2Vec2 u = cB + rB - cA - rA; + const u = this.m_u; // use m_u + u.x = cB.x + rB.x - cA.x - rA.x; + u.y = cB.y + rB.y - cA.y - rA.y; + const length = this.m_u.Normalize(); + let C; + if (this.m_minLength == this.m_maxLength) { + C = length - this.m_minLength; + } + else if (length < this.m_minLength) { + C = length - this.m_minLength; + } + else if (this.m_maxLength < length) { + C = length - this.m_maxLength; + } + else { + return true; + } + const impulse = -this.m_mass * C; + const P = b2Vec2.MulSV(impulse, u, b2DistanceJoint.SolvePositionConstraints_s_P); + cA.SelfMulSub(this.m_invMassA, P); + aA -= this.m_invIA * b2Vec2.CrossVV(rA, P); + cB.SelfMulAdd(this.m_invMassB, P); + aB += this.m_invIB * b2Vec2.CrossVV(rB, P); + // data.positions[this.m_indexA].c = cA; + data.positions[this.m_indexA].a = aA; + // data.positions[this.m_indexB].c = cB; + data.positions[this.m_indexB].a = aB; + return b2Abs(C) < b2_linearSlop; + } + Draw(draw) { + const xfA = this.m_bodyA.GetTransform(); + const xfB = this.m_bodyB.GetTransform(); + const pA = b2Transform.MulXV(xfA, this.m_localAnchorA, b2DistanceJoint.Draw_s_pA); + const pB = b2Transform.MulXV(xfB, this.m_localAnchorB, b2DistanceJoint.Draw_s_pB); + const axis = b2Vec2.SubVV(pB, pA, b2DistanceJoint.Draw_s_axis); + axis.Normalize(); + const c1 = b2DistanceJoint.Draw_s_c1; // b2Color c1(0.7f, 0.7f, 0.7f); + const c2 = b2DistanceJoint.Draw_s_c2; // b2Color c2(0.3f, 0.9f, 0.3f); + const c3 = b2DistanceJoint.Draw_s_c3; // b2Color c3(0.9f, 0.3f, 0.3f); + const c4 = b2DistanceJoint.Draw_s_c4; // b2Color c4(0.4f, 0.4f, 0.4f); + draw.DrawSegment(pA, pB, c4); + // b2Vec2 pRest = pA + this.m_length * axis; + const pRest = b2Vec2.AddVMulSV(pA, this.m_length, axis, b2DistanceJoint.Draw_s_pRest); + draw.DrawPoint(pRest, 8.0, c1); + if (this.m_minLength != this.m_maxLength) { + if (this.m_minLength > b2_linearSlop) { + // b2Vec2 pMin = pA + this.m_minLength * axis; + const pMin = b2Vec2.AddVMulSV(pA, this.m_minLength, axis, b2DistanceJoint.Draw_s_pMin); + draw.DrawPoint(pMin, 4.0, c2); + } + if (this.m_maxLength < b2_maxFloat) { + // b2Vec2 pMax = pA + this.m_maxLength * axis; + const pMax = b2Vec2.AddVMulSV(pA, this.m_maxLength, axis, b2DistanceJoint.Draw_s_pMax); + draw.DrawPoint(pMax, 4.0, c3); + } + } + } + } + b2DistanceJoint.InitVelocityConstraints_s_P = new b2Vec2(); + b2DistanceJoint.SolveVelocityConstraints_s_vpA = new b2Vec2(); + b2DistanceJoint.SolveVelocityConstraints_s_vpB = new b2Vec2(); + b2DistanceJoint.SolveVelocityConstraints_s_P = new b2Vec2(); + b2DistanceJoint.SolvePositionConstraints_s_P = new b2Vec2(); + b2DistanceJoint.Draw_s_pA = new b2Vec2(); + b2DistanceJoint.Draw_s_pB = new b2Vec2(); + b2DistanceJoint.Draw_s_axis = new b2Vec2(); + b2DistanceJoint.Draw_s_c1 = new b2Color(0.7, 0.7, 0.7); + b2DistanceJoint.Draw_s_c2 = new b2Color(0.3, 0.9, 0.3); + b2DistanceJoint.Draw_s_c3 = new b2Color(0.9, 0.3, 0.3); + b2DistanceJoint.Draw_s_c4 = new b2Color(0.4, 0.4, 0.4); + b2DistanceJoint.Draw_s_pRest = new b2Vec2(); + b2DistanceJoint.Draw_s_pMin = new b2Vec2(); + b2DistanceJoint.Draw_s_pMax = new b2Vec2(); + + // DEBUG: import { b2Assert } from "../common/b2_settings.js"; + class b2AreaJointDef extends b2JointDef { + constructor() { + super(exports.b2JointType.e_areaJoint); + this.bodies = []; + this.stiffness = 0; + this.damping = 0; + } + AddBody(body) { + this.bodies.push(body); + if (this.bodies.length === 1) { + this.bodyA = body; + } + else if (this.bodies.length === 2) { + this.bodyB = body; + } + } + } + class b2AreaJoint extends b2Joint { + constructor(def) { + super(def); + this.m_stiffness = 0; + this.m_damping = 0; + // Solver shared + this.m_impulse = 0; + this.m_targetArea = 0; + this.m_delta = new b2Vec2(); + // DEBUG: b2Assert(def.bodies.length >= 3, "You cannot create an area joint with less than three bodies."); + this.m_bodies = def.bodies; + this.m_stiffness = b2Maybe(def.stiffness, 0); + this.m_damping = b2Maybe(def.damping, 0); + this.m_targetLengths = b2MakeNumberArray(def.bodies.length); + this.m_normals = b2Vec2.MakeArray(def.bodies.length); + this.m_joints = []; // b2MakeNullArray(def.bodies.length); + this.m_deltas = b2Vec2.MakeArray(def.bodies.length); + const djd = new b2DistanceJointDef(); + djd.stiffness = this.m_stiffness; + djd.damping = this.m_damping; + this.m_targetArea = 0; + for (let i = 0; i < this.m_bodies.length; ++i) { + const body = this.m_bodies[i]; + const next = this.m_bodies[(i + 1) % this.m_bodies.length]; + const body_c = body.GetWorldCenter(); + const next_c = next.GetWorldCenter(); + this.m_targetLengths[i] = b2Vec2.DistanceVV(body_c, next_c); + this.m_targetArea += b2Vec2.CrossVV(body_c, next_c); + djd.Initialize(body, next, body_c, next_c); + this.m_joints[i] = body.GetWorld().CreateJoint(djd); + } + this.m_targetArea *= 0.5; + } + GetAnchorA(out) { + return out; + } + GetAnchorB(out) { + return out; + } + GetReactionForce(inv_dt, out) { + return out; + } + GetReactionTorque(inv_dt) { + return 0; + } + SetStiffness(stiffness) { + this.m_stiffness = stiffness; + for (let i = 0; i < this.m_joints.length; ++i) { + this.m_joints[i].SetStiffness(stiffness); + } + } + GetStiffness() { + return this.m_stiffness; + } + SetDamping(damping) { + this.m_damping = damping; + for (let i = 0; i < this.m_joints.length; ++i) { + this.m_joints[i].SetDamping(damping); + } + } + GetDamping() { + return this.m_damping; + } + Dump(log) { + log("Area joint dumping is not supported.\n"); + } + InitVelocityConstraints(data) { + for (let i = 0; i < this.m_bodies.length; ++i) { + const prev = this.m_bodies[(i + this.m_bodies.length - 1) % this.m_bodies.length]; + const next = this.m_bodies[(i + 1) % this.m_bodies.length]; + const prev_c = data.positions[prev.m_islandIndex].c; + const next_c = data.positions[next.m_islandIndex].c; + const delta = this.m_deltas[i]; + b2Vec2.SubVV(next_c, prev_c, delta); + } + if (data.step.warmStarting) { + this.m_impulse *= data.step.dtRatio; + for (let i = 0; i < this.m_bodies.length; ++i) { + const body = this.m_bodies[i]; + const body_v = data.velocities[body.m_islandIndex].v; + const delta = this.m_deltas[i]; + body_v.x += body.m_invMass * delta.y * 0.5 * this.m_impulse; + body_v.y += body.m_invMass * -delta.x * 0.5 * this.m_impulse; + } + } + else { + this.m_impulse = 0; + } + } + SolveVelocityConstraints(data) { + let dotMassSum = 0; + let crossMassSum = 0; + for (let i = 0; i < this.m_bodies.length; ++i) { + const body = this.m_bodies[i]; + const body_v = data.velocities[body.m_islandIndex].v; + const delta = this.m_deltas[i]; + dotMassSum += delta.LengthSquared() / body.GetMass(); + crossMassSum += b2Vec2.CrossVV(body_v, delta); + } + const lambda = -2 * crossMassSum / dotMassSum; + // lambda = b2Clamp(lambda, -b2_maxLinearCorrection, b2_maxLinearCorrection); + this.m_impulse += lambda; + for (let i = 0; i < this.m_bodies.length; ++i) { + const body = this.m_bodies[i]; + const body_v = data.velocities[body.m_islandIndex].v; + const delta = this.m_deltas[i]; + body_v.x += body.m_invMass * delta.y * 0.5 * lambda; + body_v.y += body.m_invMass * -delta.x * 0.5 * lambda; + } + } + SolvePositionConstraints(data) { + let perimeter = 0; + let area = 0; + for (let i = 0; i < this.m_bodies.length; ++i) { + const body = this.m_bodies[i]; + const next = this.m_bodies[(i + 1) % this.m_bodies.length]; + const body_c = data.positions[body.m_islandIndex].c; + const next_c = data.positions[next.m_islandIndex].c; + const delta = b2Vec2.SubVV(next_c, body_c, this.m_delta); + let dist = delta.Length(); + if (dist < b2_epsilon) { + dist = 1; + } + this.m_normals[i].x = delta.y / dist; + this.m_normals[i].y = -delta.x / dist; + perimeter += dist; + area += b2Vec2.CrossVV(body_c, next_c); + } + area *= 0.5; + const deltaArea = this.m_targetArea - area; + const toExtrude = 0.5 * deltaArea / perimeter; + let done = true; + for (let i = 0; i < this.m_bodies.length; ++i) { + const body = this.m_bodies[i]; + const body_c = data.positions[body.m_islandIndex].c; + const next_i = (i + 1) % this.m_bodies.length; + const delta = b2Vec2.AddVV(this.m_normals[i], this.m_normals[next_i], this.m_delta); + delta.SelfMul(toExtrude); + const norm_sq = delta.LengthSquared(); + if (norm_sq > b2Sq(b2_maxLinearCorrection)) { + delta.SelfMul(b2_maxLinearCorrection / b2Sqrt(norm_sq)); + } + if (norm_sq > b2Sq(b2_linearSlop)) { + done = false; + } + body_c.x += delta.x; + body_c.y += delta.y; + } + return done; + } + } + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// This holds contact filtering data. + class b2Filter { + constructor() { + /// The collision category bits. Normally you would just set one bit. + this.categoryBits = 0x0001; + /// The collision mask bits. This states the categories that this + /// shape would accept for collision. + this.maskBits = 0xFFFF; + /// Collision groups allow a certain group of objects to never collide (negative) + /// or always collide (positive). Zero means no collision group. Non-zero group + /// filtering always wins against the mask bits. + this.groupIndex = 0; + } + Clone() { + return new b2Filter().Copy(this); + } + Copy(other) { + // DEBUG: b2Assert(this !== other); + this.categoryBits = other.categoryBits; + this.maskBits = other.maskBits; + this.groupIndex = other.groupIndex || 0; + return this; + } + } + b2Filter.DEFAULT = new b2Filter(); + /// A fixture definition is used to create a fixture. This class defines an + /// abstract fixture definition. You can reuse fixture definitions safely. + class b2FixtureDef { + constructor() { + /// Use this to store application specific fixture data. + this.userData = null; + /// The friction coefficient, usually in the range [0,1]. + this.friction = 0.2; + /// The restitution (elasticity) usually in the range [0,1]. + this.restitution = 0; + /// Restitution velocity threshold, usually in m/s. Collisions above this + /// speed have restitution applied (will bounce). + this.restitutionThreshold = 1.0 * b2_lengthUnitsPerMeter; + /// The density, usually in kg/m^2. + this.density = 0; + /// A sensor shape collects contact information but never generates a collision + /// response. + this.isSensor = false; + /// Contact filtering data. + this.filter = new b2Filter(); + } + } + /// This proxy is used internally to connect fixtures to the broad-phase. + class b2FixtureProxy { + constructor(fixture, childIndex) { + this.aabb = new b2AABB(); + this.childIndex = 0; + this.fixture = fixture; + this.childIndex = childIndex; + this.fixture.m_shape.ComputeAABB(this.aabb, this.fixture.m_body.GetTransform(), childIndex); + this.treeNode = this.fixture.m_body.m_world.m_contactManager.m_broadPhase.CreateProxy(this.aabb, this); + } + Reset() { + this.fixture.m_body.m_world.m_contactManager.m_broadPhase.DestroyProxy(this.treeNode); + } + Touch() { + this.fixture.m_body.m_world.m_contactManager.m_broadPhase.TouchProxy(this.treeNode); + } + Synchronize(transform1, transform2) { + if (transform1 === transform2) { + this.fixture.m_shape.ComputeAABB(this.aabb, transform1, this.childIndex); + this.fixture.m_body.m_world.m_contactManager.m_broadPhase.MoveProxy(this.treeNode, this.aabb, b2Vec2.ZERO); + } + else { + // Compute an AABB that covers the swept shape (may miss some rotation effect). + const aabb1 = b2FixtureProxy.Synchronize_s_aabb1; + const aabb2 = b2FixtureProxy.Synchronize_s_aabb2; + this.fixture.m_shape.ComputeAABB(aabb1, transform1, this.childIndex); + this.fixture.m_shape.ComputeAABB(aabb2, transform2, this.childIndex); + this.aabb.Combine2(aabb1, aabb2); + const displacement = b2FixtureProxy.Synchronize_s_displacement; + displacement.Copy(aabb2.GetCenter()).SelfSub(aabb1.GetCenter()); + this.fixture.m_body.m_world.m_contactManager.m_broadPhase.MoveProxy(this.treeNode, this.aabb, displacement); + } + } + } + b2FixtureProxy.Synchronize_s_aabb1 = new b2AABB(); + b2FixtureProxy.Synchronize_s_aabb2 = new b2AABB(); + b2FixtureProxy.Synchronize_s_displacement = new b2Vec2(); + /// A fixture is used to attach a shape to a body for collision detection. A fixture + /// inherits its transform from its parent. Fixtures hold additional non-geometric data + /// such as friction, collision filters, etc. + /// Fixtures are created via b2Body::CreateFixture. + /// @warning you cannot reuse fixtures. + class b2Fixture { + constructor(body, def) { + this.m_density = 0; + this.m_next = null; + this.m_friction = 0; + this.m_restitution = 0; + this.m_restitutionThreshold = 1.0 * b2_lengthUnitsPerMeter; + this.m_proxies = []; + this.m_filter = new b2Filter(); + this.m_isSensor = false; + this.m_userData = null; + this.m_body = body; + this.m_shape = def.shape.Clone(); + this.m_userData = b2Maybe(def.userData, null); + this.m_friction = b2Maybe(def.friction, 0.2); + this.m_restitution = b2Maybe(def.restitution, 0); + this.m_restitutionThreshold = b2Maybe(def.restitutionThreshold, 0); + this.m_filter.Copy(b2Maybe(def.filter, b2Filter.DEFAULT)); + this.m_isSensor = b2Maybe(def.isSensor, false); + this.m_density = b2Maybe(def.density, 0); + } + get m_proxyCount() { return this.m_proxies.length; } + // 为了避免引擎/项目报错增加到空方法;通过 body.CreateFixture 以及 body.DestroyFixture 方法执行时不需要这两个方法的 + Create(allocator, body, def) { + } + Destroy() { + } + Reset() { + // The proxies must be destroyed before calling this. + // DEBUG: b2Assert(this.m_proxyCount === 0); + } + /// Get the type of the child shape. You can use this to down cast to the concrete shape. + /// @return the shape type. + GetType() { + return this.m_shape.GetType(); + } + /// Get the child shape. You can modify the child shape, however you should not change the + /// number of vertices because this will crash some collision caching mechanisms. + /// Manipulating the shape may lead to non-physical behavior. + GetShape() { + return this.m_shape; + } + /// Set if this fixture is a sensor. + SetSensor(sensor) { + if (sensor !== this.m_isSensor) { + this.m_body.SetAwake(true); + this.m_isSensor = sensor; + } + } + /// Is this fixture a sensor (non-solid)? + /// @return the true if the shape is a sensor. + IsSensor() { + return this.m_isSensor; + } + /// Set the contact filtering data. This will not update contacts until the next time + /// step when either parent body is active and awake. + /// This automatically calls Refilter. + SetFilterData(filter) { + this.m_filter.Copy(filter); + this.Refilter(); + } + /// Get the contact filtering data. + GetFilterData() { + return this.m_filter; + } + /// Call this if you want to establish collision that was previously disabled by b2ContactFilter::ShouldCollide. + Refilter() { + // Flag associated contacts for filtering. + let edge = this.m_body.GetContactList(); + while (edge) { + const contact = edge.contact; + const fixtureA = contact.GetFixtureA(); + const fixtureB = contact.GetFixtureB(); + if (fixtureA === this || fixtureB === this) { + contact.FlagForFiltering(); + } + edge = edge.next; + } + // Touch each proxy so that new pairs may be created + this.TouchProxies(); + } + /// Get the parent body of this fixture. This is NULL if the fixture is not attached. + /// @return the parent body. + GetBody() { + return this.m_body; + } + /// Get the next fixture in the parent body's fixture list. + /// @return the next shape. + GetNext() { + return this.m_next; + } + /// Get the user data that was assigned in the fixture definition. Use this to + /// store your application specific data. + GetUserData() { + return this.m_userData; + } + /// Set the user data. Use this to store your application specific data. + SetUserData(data) { + this.m_userData = data; + } + /// Test a point for containment in this fixture. + /// @param p a point in world coordinates. + TestPoint(p) { + return this.m_shape.TestPoint(this.m_body.GetTransform(), p); + } + /// Cast a ray against this shape. + /// @param output the ray-cast results. + /// @param input the ray-cast input parameters. + RayCast(output, input, childIndex) { + return this.m_shape.RayCast(output, input, this.m_body.GetTransform(), childIndex); + } + /// Get the mass data for this fixture. The mass data is based on the density and + /// the shape. The rotational inertia is about the shape's origin. This operation + /// may be expensive. + GetMassData(massData = new b2MassData()) { + this.m_shape.ComputeMass(massData, this.m_density); + return massData; + } + /// Set the density of this fixture. This will _not_ automatically adjust the mass + /// of the body. You must call b2Body::ResetMassData to update the body's mass. + SetDensity(density) { + this.m_density = density; + } + /// Get the density of this fixture. + GetDensity() { + return this.m_density; + } + /// Get the coefficient of friction. + GetFriction() { + return this.m_friction; + } + /// Set the coefficient of friction. This will _not_ change the friction of + /// existing contacts. + SetFriction(friction) { + this.m_friction = friction; + } + /// Get the coefficient of restitution. + GetRestitution() { + return this.m_restitution; + } + /// Set the coefficient of restitution. This will _not_ change the restitution of + /// existing contacts. + SetRestitution(restitution) { + this.m_restitution = restitution; + } + /// Get the restitution velocity threshold. + GetRestitutionThreshold() { + return this.m_restitutionThreshold; + } + /// Set the restitution threshold. This will _not_ change the restitution threshold of + /// existing contacts. + SetRestitutionThreshold(threshold) { + this.m_restitutionThreshold = threshold; + } + /// Get the fixture's AABB. This AABB may be enlarge and/or stale. + /// If you need a more accurate AABB, compute it using the shape and + /// the body transform. + GetAABB(childIndex) { + // DEBUG: b2Assert(0 <= childIndex && childIndex < this.m_proxyCount); + return this.m_proxies[childIndex].aabb; + } + /// Dump this fixture to the log file. + Dump(log, bodyIndex) { + log(" const fd: b2FixtureDef = new b2FixtureDef();\n"); + log(" fd.friction = %.15f;\n", this.m_friction); + log(" fd.restitution = %.15f;\n", this.m_restitution); + log(" fd.restitutionThreshold = %.15f;\n", this.m_restitutionThreshold); + log(" fd.density = %.15f;\n", this.m_density); + log(" fd.isSensor = %s;\n", (this.m_isSensor) ? ("true") : ("false")); + log(" fd.filter.categoryBits = %d;\n", this.m_filter.categoryBits); + log(" fd.filter.maskBits = %d;\n", this.m_filter.maskBits); + log(" fd.filter.groupIndex = %d;\n", this.m_filter.groupIndex); + this.m_shape.Dump(log); + log("\n"); + log(" fd.shape = shape;\n"); + log("\n"); + log(" bodies[%d].CreateFixture(fd);\n", bodyIndex); + } + // These support body activation/deactivation. + CreateProxies() { + if (this.m_proxies.length !== 0) { + throw new Error(); + } + // Create proxies in the broad-phase. + for (let i = 0; i < this.m_shape.GetChildCount(); ++i) { + this.m_proxies[i] = new b2FixtureProxy(this, i); + } + } + DestroyProxies() { + // Destroy proxies in the broad-phase. + for (const proxy of this.m_proxies) { + proxy.Reset(); + } + this.m_proxies.length = 0; + } + TouchProxies() { + for (const proxy of this.m_proxies) { + proxy.Touch(); + } + } + Synchronize(broadPhase, transform1, transform2) { + this.SynchronizeProxies(transform1, transform2); + } + SynchronizeProxies(transform1, transform2) { + for (const proxy of this.m_proxies) { + proxy.Synchronize(transform1, transform2); + } + } + } + + /* + * Copyright (c) 2006-2011 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// The body type. + /// static: zero mass, zero velocity, may be manually moved + /// kinematic: zero mass, non-zero velocity set by user, moved by solver + /// dynamic: positive mass, non-zero velocity determined by forces, moved by solver + exports.b2BodyType = void 0; + (function (b2BodyType) { + b2BodyType[b2BodyType["b2_unknown"] = -1] = "b2_unknown"; + b2BodyType[b2BodyType["b2_staticBody"] = 0] = "b2_staticBody"; + b2BodyType[b2BodyType["b2_kinematicBody"] = 1] = "b2_kinematicBody"; + b2BodyType[b2BodyType["b2_dynamicBody"] = 2] = "b2_dynamicBody"; + // TODO_ERIN + // b2_bulletBody = 3 + })(exports.b2BodyType || (exports.b2BodyType = {})); + /// A body definition holds all the data needed to construct a rigid body. + /// You can safely re-use body definitions. Shapes are added to a body after construction. + class b2BodyDef { + constructor() { + /// The body type: static, kinematic, or dynamic. + /// Note: if a dynamic body would have zero mass, the mass is set to one. + this.type = exports.b2BodyType.b2_staticBody; + /// The world position of the body. Avoid creating bodies at the origin + /// since this can lead to many overlapping shapes. + /// kylin: C++版本的b2Vec2重载了大量的运算符,为了避免开发者错误操作,设置为 readonly 是合理的 + this.position = new b2Vec2(0, 0); + /// The world angle of the body in radians. + this.angle = 0; + /// The linear velocity of the body's origin in world co-ordinates. + this.linearVelocity = new b2Vec2(0, 0); + /// The angular velocity of the body. + this.angularVelocity = 0; + /// Linear damping is use to reduce the linear velocity. The damping parameter + /// can be larger than 1.0f but the damping effect becomes sensitive to the + /// time step when the damping parameter is large. + this.linearDamping = 0; + /// Angular damping is use to reduce the angular velocity. The damping parameter + /// can be larger than 1.0f but the damping effect becomes sensitive to the + /// time step when the damping parameter is large. + this.angularDamping = 0; + /// Set this flag to false if this body should never fall asleep. Note that + /// this increases CPU usage. + this.allowSleep = true; + /// Is this body initially awake or sleeping? + this.awake = true; + /// Should this body be prevented from rotating? Useful for characters. + this.fixedRotation = false; + /// Is this a fast moving body that should be prevented from tunneling through + /// other moving bodies? Note that all bodies are prevented from tunneling through + /// kinematic and static bodies. This setting is only considered on dynamic bodies. + /// @warning You should use this flag sparingly since it increases processing time. + this.bullet = false; + /// Does this body start out enabled? + this.enabled = true; + /// Use this to store application specific body data. + this.userData = null; + /// Scale the gravity applied to this body. + this.gravityScale = 1; + } + } + /// A rigid body. These are created via b2World::CreateBody. + class b2Body { + constructor(bd, world) { + this.m_type = exports.b2BodyType.b2_staticBody; + this.m_islandFlag = false; + this.m_awakeFlag = false; + this.m_autoSleepFlag = false; + this.m_bulletFlag = false; + this.m_fixedRotationFlag = false; + this.m_enabledFlag = false; + this.m_toiFlag = false; + this.m_islandIndex = 0; + this.m_xf = new b2Transform(); // the body origin transform + this.m_sweep = new b2Sweep(); // the swept motion for CCD + this.m_linearVelocity = new b2Vec2(); + this.m_angularVelocity = 0; + this.m_force = new b2Vec2(); + this.m_torque = 0; + this.m_prev = null; + this.m_next = null; + this.m_fixtureList = null; + this.m_fixtureCount = 0; + this.m_jointList = null; + this.m_contactList = null; + this.m_mass = 1; + this.m_invMass = 1; + // Rotational inertia about the center of mass. + this.m_I = 0; + this.m_invI = 0; + this.m_linearDamping = 0; + this.m_angularDamping = 0; + this.m_gravityScale = 1; + this.m_sleepTime = 0; + this.m_userData = null; + this.m_bulletFlag = b2Maybe(bd.bullet, false); + this.m_fixedRotationFlag = b2Maybe(bd.fixedRotation, false); + this.m_autoSleepFlag = b2Maybe(bd.allowSleep, true); + // this.m_awakeFlag = b2Maybe(bd.awake, true); + if (b2Maybe(bd.awake, false) && b2Maybe(bd.type, exports.b2BodyType.b2_staticBody) !== exports.b2BodyType.b2_staticBody) { + this.m_awakeFlag = true; + } + this.m_enabledFlag = b2Maybe(bd.enabled, true); + this.m_world = world; + this.m_xf.p.Copy(b2Maybe(bd.position, b2Vec2.ZERO)); + // DEBUG: b2Assert(this.m_xf.p.IsValid()); + this.m_xf.q.SetAngle(b2Maybe(bd.angle, 0)); + // DEBUG: b2Assert(b2IsValid(this.m_xf.q.GetAngle())); + this.m_sweep.localCenter.SetZero(); + this.m_sweep.c0.Copy(this.m_xf.p); + this.m_sweep.c.Copy(this.m_xf.p); + this.m_sweep.a0 = this.m_sweep.a = this.m_xf.q.GetAngle(); + this.m_sweep.alpha0 = 0; + this.m_linearVelocity.Copy(b2Maybe(bd.linearVelocity, b2Vec2.ZERO)); + // DEBUG: b2Assert(this.m_linearVelocity.IsValid()); + this.m_angularVelocity = b2Maybe(bd.angularVelocity, 0); + // DEBUG: b2Assert(b2IsValid(this.m_angularVelocity)); + this.m_linearDamping = b2Maybe(bd.linearDamping, 0); + this.m_angularDamping = b2Maybe(bd.angularDamping, 0); + this.m_gravityScale = b2Maybe(bd.gravityScale, 1); + // DEBUG: b2Assert(b2IsValid(this.m_gravityScale) && this.m_gravityScale >= 0); + // DEBUG: b2Assert(b2IsValid(this.m_angularDamping) && this.m_angularDamping >= 0); + // DEBUG: b2Assert(b2IsValid(this.m_linearDamping) && this.m_linearDamping >= 0); + this.m_force.SetZero(); + this.m_torque = 0; + this.m_sleepTime = 0; + this.m_type = b2Maybe(bd.type, exports.b2BodyType.b2_staticBody); + this.m_mass = 0; + this.m_invMass = 0; + this.m_I = 0; + this.m_invI = 0; + this.m_userData = bd.userData; + this.m_fixtureList = null; + this.m_fixtureCount = 0; + } + CreateFixture(a, b = 0) { + if (a instanceof b2Shape) { + return this.CreateFixtureShapeDensity(a, b); + } + else { + return this.CreateFixtureDef(a); + } + } + /// Creates a fixture and attach it to this body. Use this function if you need + /// to set some fixture parameters, like friction. Otherwise you can create the + /// fixture directly from a shape. + /// If the density is non-zero, this function automatically updates the mass of the body. + /// Contacts are not created until the next time step. + /// @param def the fixture definition. + /// @warning This function is locked during callbacks. + CreateFixtureDef(def) { + if (this.m_world.IsLocked()) { + throw new Error(); + } + const fixture = new b2Fixture(this, def); + if (this.m_enabledFlag) { + fixture.CreateProxies(); + } + fixture.m_next = this.m_fixtureList; + this.m_fixtureList = fixture; + ++this.m_fixtureCount; + // fixture.m_body = this; + // Adjust mass properties if needed. + if (fixture.m_density > 0) { + this.ResetMassData(); + } + // Let the world know we have a new fixture. This will cause new contacts + // to be created at the beginning of the next time step. + this.m_world.m_newContacts = true; + return fixture; + } + CreateFixtureShapeDensity(shape, density = 0) { + const def = b2Body.CreateFixtureShapeDensity_s_def; + def.shape = shape; + def.density = density; + return this.CreateFixtureDef(def); + } + /// Destroy a fixture. This removes the fixture from the broad-phase and + /// destroys all contacts associated with this fixture. This will + /// automatically adjust the mass of the body if the body is dynamic and the + /// fixture has positive density. + /// All fixtures attached to a body are implicitly destroyed when the body is destroyed. + /// @param fixture the fixture to be removed. + /// @warning This function is locked during callbacks. + DestroyFixture(fixture) { + if (this.m_world.IsLocked()) { + throw new Error(); + } + // DEBUG: b2Assert(fixture.m_body === this); + // Remove the fixture from this body's singly linked list. + // DEBUG: b2Assert(this.m_fixtureCount > 0); + let node = this.m_fixtureList; + let ppF = null; + // DEBUG: let found: boolean = false; + while (node !== null) { + if (node === fixture) { + if (ppF) { + ppF.m_next = fixture.m_next; + } + else { + this.m_fixtureList = fixture.m_next; + } + // DEBUG: found = true; + break; + } + ppF = node; + node = node.m_next; + } + // You tried to remove a shape that is not attached to this body. + // DEBUG: b2Assert(found); + // Destroy any contacts associated with the fixture. + let edge = this.m_contactList; + while (edge) { + const c = edge.contact; + edge = edge.next; + const fixtureA = c.GetFixtureA(); + const fixtureB = c.GetFixtureB(); + if (fixture === fixtureA || fixture === fixtureB) { + // This destroys the contact and removes it from + // this body's contact list. + this.m_world.m_contactManager.Destroy(c); + } + } + if (this.m_enabledFlag) { + fixture.DestroyProxies(); + } + // fixture.m_body = null; + fixture.m_next = null; + fixture.Reset(); + --this.m_fixtureCount; + // Reset the mass data. + this.ResetMassData(); + } + /// Set the position of the body's origin and rotation. + /// This breaks any contacts and wakes the other bodies. + /// Manipulating a body's transform may cause non-physical behavior. + /// @param position the world position of the body's local origin. + /// @param angle the world rotation in radians. + SetTransformVec(position, angle) { + this.SetTransformXY(position.x, position.y, angle); + } + SetTransformXY(x, y, angle) { + if (this.m_world.IsLocked()) { + throw new Error(); + } + this.m_xf.q.SetAngle(angle); + this.m_xf.p.Set(x, y); + b2Transform.MulXV(this.m_xf, this.m_sweep.localCenter, this.m_sweep.c); + this.m_sweep.a = angle; + this.m_sweep.c0.Copy(this.m_sweep.c); + this.m_sweep.a0 = angle; + for (let f = this.m_fixtureList; f; f = f.m_next) { + f.SynchronizeProxies(this.m_xf, this.m_xf); + } + // Check for new contacts the next step + this.m_world.m_newContacts = true; + } + SetTransform(position, angle) { + this.SetTransformXY(position.x, position.y, angle); + } + /// Get the body transform for the body's origin. + /// @return the world transform of the body's origin. + GetTransform() { + return this.m_xf; + } + /// Get the world body origin position. + /// @return the world position of the body's origin. + GetPosition() { + return this.m_xf.p; + } + SetPosition(position) { + this.SetTransformVec(position, this.GetAngle()); + } + SetPositionXY(x, y) { + this.SetTransformXY(x, y, this.GetAngle()); + } + /// Get the angle in radians. + /// @return the current world rotation angle in radians. + GetAngle() { + return this.m_sweep.a; + } + SetAngle(angle) { + this.SetTransformVec(this.GetPosition(), angle); + } + /// Get the world position of the center of mass. + GetWorldCenter() { + return this.m_sweep.c; + } + /// Get the local position of the center of mass. + GetLocalCenter() { + return this.m_sweep.localCenter; + } + /// Set the linear velocity of the center of mass. + /// @param v the new linear velocity of the center of mass. + SetLinearVelocity(v) { + if (this.m_type === exports.b2BodyType.b2_staticBody) { + return; + } + if (b2Vec2.DotVV(v, v) > 0) { + this.SetAwake(true); + } + this.m_linearVelocity.Copy(v); + } + /// Get the linear velocity of the center of mass. + /// @return the linear velocity of the center of mass. + GetLinearVelocity() { + return this.m_linearVelocity; + } + /// Set the angular velocity. + /// @param omega the new angular velocity in radians/second. + SetAngularVelocity(w) { + if (this.m_type === exports.b2BodyType.b2_staticBody) { + return; + } + if (w * w > 0) { + this.SetAwake(true); + } + this.m_angularVelocity = w; + } + /// Get the angular velocity. + /// @return the angular velocity in radians/second. + GetAngularVelocity() { + return this.m_angularVelocity; + } + GetDefinition(bd) { + bd.type = this.GetType(); + bd.allowSleep = this.m_autoSleepFlag; + bd.angle = this.GetAngle(); + bd.angularDamping = this.m_angularDamping; + bd.gravityScale = this.m_gravityScale; + bd.angularVelocity = this.m_angularVelocity; + bd.fixedRotation = this.m_fixedRotationFlag; + bd.bullet = this.m_bulletFlag; + bd.awake = this.m_awakeFlag; + bd.linearDamping = this.m_linearDamping; + bd.linearVelocity.Copy(this.GetLinearVelocity()); + bd.position.Copy(this.GetPosition()); + bd.userData = this.GetUserData(); + return bd; + } + /// Apply a force at a world point. If the force is not + /// applied at the center of mass, it will generate a torque and + /// affect the angular velocity. This wakes up the body. + /// @param force the world force vector, usually in Newtons (N). + /// @param point the world position of the point of application. + /// @param wake also wake up the body + ApplyForce(force, point, wake = true) { + if (this.m_type !== exports.b2BodyType.b2_dynamicBody) { + return; + } + if (wake && !this.m_awakeFlag) { + this.SetAwake(true); + } + // Don't accumulate a force if the body is sleeping. + if (this.m_awakeFlag) { + this.m_force.x += force.x; + this.m_force.y += force.y; + this.m_torque += ((point.x - this.m_sweep.c.x) * force.y - (point.y - this.m_sweep.c.y) * force.x); + } + } + /// Apply a force to the center of mass. This wakes up the body. + /// @param force the world force vector, usually in Newtons (N). + /// @param wake also wake up the body + ApplyForceToCenter(force, wake = true) { + if (this.m_type !== exports.b2BodyType.b2_dynamicBody) { + return; + } + if (wake && !this.m_awakeFlag) { + this.SetAwake(true); + } + // Don't accumulate a force if the body is sleeping. + if (this.m_awakeFlag) { + this.m_force.x += force.x; + this.m_force.y += force.y; + } + } + /// Apply a torque. This affects the angular velocity + /// without affecting the linear velocity of the center of mass. + /// @param torque about the z-axis (out of the screen), usually in N-m. + /// @param wake also wake up the body + ApplyTorque(torque, wake = true) { + if (this.m_type !== exports.b2BodyType.b2_dynamicBody) { + return; + } + if (wake && !this.m_awakeFlag) { + this.SetAwake(true); + } + // Don't accumulate a force if the body is sleeping. + if (this.m_awakeFlag) { + this.m_torque += torque; + } + } + /// Apply an impulse at a point. This immediately modifies the velocity. + /// It also modifies the angular velocity if the point of application + /// is not at the center of mass. This wakes up the body. + /// @param impulse the world impulse vector, usually in N-seconds or kg-m/s. + /// @param point the world position of the point of application. + /// @param wake also wake up the body + ApplyLinearImpulse(impulse, point, wake = true) { + if (this.m_type !== exports.b2BodyType.b2_dynamicBody) { + return; + } + if (wake && !this.m_awakeFlag) { + this.SetAwake(true); + } + // Don't accumulate a force if the body is sleeping. + if (this.m_awakeFlag) { + this.m_linearVelocity.x += this.m_invMass * impulse.x; + this.m_linearVelocity.y += this.m_invMass * impulse.y; + this.m_angularVelocity += this.m_invI * ((point.x - this.m_sweep.c.x) * impulse.y - (point.y - this.m_sweep.c.y) * impulse.x); + } + } + /// Apply an impulse at the center of gravity. This immediately modifies the velocity. + /// @param impulse the world impulse vector, usually in N-seconds or kg-m/s. + /// @param wake also wake up the body + ApplyLinearImpulseToCenter(impulse, wake = true) { + if (this.m_type !== exports.b2BodyType.b2_dynamicBody) { + return; + } + if (wake && !this.m_awakeFlag) { + this.SetAwake(true); + } + // Don't accumulate a force if the body is sleeping. + if (this.m_awakeFlag) { + this.m_linearVelocity.x += this.m_invMass * impulse.x; + this.m_linearVelocity.y += this.m_invMass * impulse.y; + } + } + /// Apply an angular impulse. + /// @param impulse the angular impulse in units of kg*m*m/s + /// @param wake also wake up the body + ApplyAngularImpulse(impulse, wake = true) { + if (this.m_type !== exports.b2BodyType.b2_dynamicBody) { + return; + } + if (wake && !this.m_awakeFlag) { + this.SetAwake(true); + } + // Don't accumulate a force if the body is sleeping. + if (this.m_awakeFlag) { + this.m_angularVelocity += this.m_invI * impulse; + } + } + /// Get the total mass of the body. + /// @return the mass, usually in kilograms (kg). + GetMass() { + return this.m_mass; + } + /// Get the rotational inertia of the body about the local origin. + /// @return the rotational inertia, usually in kg-m^2. + GetInertia() { + return this.m_I + this.m_mass * b2Vec2.DotVV(this.m_sweep.localCenter, this.m_sweep.localCenter); + } + /// Get the mass data of the body. + /// @return a struct containing the mass, inertia and center of the body. + GetMassData(data) { + data.mass = this.m_mass; + data.I = this.m_I + this.m_mass * b2Vec2.DotVV(this.m_sweep.localCenter, this.m_sweep.localCenter); + data.center.Copy(this.m_sweep.localCenter); + return data; + } + SetMassData(massData) { + if (this.m_world.IsLocked()) { + throw new Error(); + } + if (this.m_type !== exports.b2BodyType.b2_dynamicBody) { + return; + } + this.m_invMass = 0; + this.m_I = 0; + this.m_invI = 0; + this.m_mass = massData.mass; + if (this.m_mass <= 0) { + this.m_mass = 1; + } + this.m_invMass = 1 / this.m_mass; + if (massData.I > 0 && !this.m_fixedRotationFlag) { + this.m_I = massData.I - this.m_mass * b2Vec2.DotVV(massData.center, massData.center); + // DEBUG: b2Assert(this.m_I > 0); + this.m_invI = 1 / this.m_I; + } + // Move center of mass. + const oldCenter = b2Body.SetMassData_s_oldCenter.Copy(this.m_sweep.c); + this.m_sweep.localCenter.Copy(massData.center); + b2Transform.MulXV(this.m_xf, this.m_sweep.localCenter, this.m_sweep.c); + this.m_sweep.c0.Copy(this.m_sweep.c); + // Update center of mass velocity. + b2Vec2.AddVCrossSV(this.m_linearVelocity, this.m_angularVelocity, b2Vec2.SubVV(this.m_sweep.c, oldCenter, b2Vec2.s_t0), this.m_linearVelocity); + } + ResetMassData() { + // Compute mass data from shapes. Each shape has its own density. + this.m_mass = 0; + this.m_invMass = 0; + this.m_I = 0; + this.m_invI = 0; + this.m_sweep.localCenter.SetZero(); + // Static and kinematic bodies have zero mass. + if (this.m_type === exports.b2BodyType.b2_staticBody || this.m_type === exports.b2BodyType.b2_kinematicBody) { + this.m_sweep.c0.Copy(this.m_xf.p); + this.m_sweep.c.Copy(this.m_xf.p); + this.m_sweep.a0 = this.m_sweep.a; + return; + } + // DEBUG: b2Assert(this.m_type === b2BodyType.b2_dynamicBody); + // Accumulate mass over all fixtures. + const localCenter = b2Body.ResetMassData_s_localCenter.SetZero(); + for (let f = this.m_fixtureList; f; f = f.m_next) { + if (f.m_density === 0) { + continue; + } + const massData = f.GetMassData(b2Body.ResetMassData_s_massData); + this.m_mass += massData.mass; + localCenter.x += massData.center.x * massData.mass; + localCenter.y += massData.center.y * massData.mass; + this.m_I += massData.I; + } + // Compute center of mass. + if (this.m_mass > 0) { + this.m_invMass = 1 / this.m_mass; + localCenter.x *= this.m_invMass; + localCenter.y *= this.m_invMass; + } + if (this.m_I > 0 && !this.m_fixedRotationFlag) { + // Center the inertia about the center of mass. + this.m_I -= this.m_mass * b2Vec2.DotVV(localCenter, localCenter); + // DEBUG: b2Assert(this.m_I > 0); + this.m_invI = 1 / this.m_I; + } + else { + this.m_I = 0; + this.m_invI = 0; + } + // Move center of mass. + const oldCenter = b2Body.ResetMassData_s_oldCenter.Copy(this.m_sweep.c); + this.m_sweep.localCenter.Copy(localCenter); + b2Transform.MulXV(this.m_xf, this.m_sweep.localCenter, this.m_sweep.c); + this.m_sweep.c0.Copy(this.m_sweep.c); + // Update center of mass velocity. + b2Vec2.AddVCrossSV(this.m_linearVelocity, this.m_angularVelocity, b2Vec2.SubVV(this.m_sweep.c, oldCenter, b2Vec2.s_t0), this.m_linearVelocity); + } + /// Get the world coordinates of a point given the local coordinates. + /// @param localPoint a point on the body measured relative the the body's origin. + /// @return the same point expressed in world coordinates. + GetWorldPoint(localPoint, out) { + return b2Transform.MulXV(this.m_xf, localPoint, out); + } + /// Get the world coordinates of a vector given the local coordinates. + /// @param localVector a vector fixed in the body. + /// @return the same vector expressed in world coordinates. + GetWorldVector(localVector, out) { + return b2Rot.MulRV(this.m_xf.q, localVector, out); + } + /// Gets a local point relative to the body's origin given a world point. + /// @param a point in world coordinates. + /// @return the corresponding local point relative to the body's origin. + GetLocalPoint(worldPoint, out) { + return b2Transform.MulTXV(this.m_xf, worldPoint, out); + } + /// Gets a local vector given a world vector. + /// @param a vector in world coordinates. + /// @return the corresponding local vector. + GetLocalVector(worldVector, out) { + return b2Rot.MulTRV(this.m_xf.q, worldVector, out); + } + /// Get the world linear velocity of a world point attached to this body. + /// @param a point in world coordinates. + /// @return the world velocity of a point. + GetLinearVelocityFromWorldPoint(worldPoint, out) { + return b2Vec2.AddVCrossSV(this.m_linearVelocity, this.m_angularVelocity, b2Vec2.SubVV(worldPoint, this.m_sweep.c, b2Vec2.s_t0), out); + } + /// Get the world velocity of a local point. + /// @param a point in local coordinates. + /// @return the world velocity of a point. + GetLinearVelocityFromLocalPoint(localPoint, out) { + return this.GetLinearVelocityFromWorldPoint(this.GetWorldPoint(localPoint, out), out); + } + /// Get the linear damping of the body. + GetLinearDamping() { + return this.m_linearDamping; + } + /// Set the linear damping of the body. + SetLinearDamping(linearDamping) { + this.m_linearDamping = linearDamping; + } + /// Get the angular damping of the body. + GetAngularDamping() { + return this.m_angularDamping; + } + /// Set the angular damping of the body. + SetAngularDamping(angularDamping) { + this.m_angularDamping = angularDamping; + } + /// Get the gravity scale of the body. + GetGravityScale() { + return this.m_gravityScale; + } + /// Set the gravity scale of the body. + SetGravityScale(scale) { + this.m_gravityScale = scale; + } + /// Set the type of this body. This may alter the mass and velocity. + SetType(type) { + if (this.m_world.IsLocked()) { + throw new Error(); + } + if (this.m_type === type) { + return; + } + this.m_type = type; + this.ResetMassData(); + if (this.m_type === exports.b2BodyType.b2_staticBody) { + this.m_linearVelocity.SetZero(); + this.m_angularVelocity = 0; + this.m_sweep.a0 = this.m_sweep.a; + this.m_sweep.c0.Copy(this.m_sweep.c); + this.m_awakeFlag = false; + this.SynchronizeFixtures(); + } + this.SetAwake(true); + this.m_force.SetZero(); + this.m_torque = 0; + // Delete the attached contacts. + let ce = this.m_contactList; + while (ce) { + const ce0 = ce; + ce = ce.next; + this.m_world.m_contactManager.Destroy(ce0.contact); + } + this.m_contactList = null; + // Touch the proxies so that new contacts will be created (when appropriate) + for (let f = this.m_fixtureList; f; f = f.m_next) { + f.TouchProxies(); + } + } + /// Get the type of this body. + GetType() { + return this.m_type; + } + /// Should this body be treated like a bullet for continuous collision detection? + SetBullet(flag) { + this.m_bulletFlag = flag; + } + /// Is this body treated like a bullet for continuous collision detection? + IsBullet() { + return this.m_bulletFlag; + } + /// You can disable sleeping on this body. If you disable sleeping, the + /// body will be woken. + SetSleepingAllowed(flag) { + this.m_autoSleepFlag = flag; + if (!flag) { + this.SetAwake(true); + } + } + /// Is this body allowed to sleep + IsSleepingAllowed() { + return this.m_autoSleepFlag; + } + /// Set the sleep state of the body. A sleeping body has very + /// low CPU cost. + /// @param flag set to true to wake the body, false to put it to sleep. + SetAwake(flag) { + if (this.m_type === exports.b2BodyType.b2_staticBody) { + return; + } + if (flag) { + this.m_awakeFlag = true; + this.m_sleepTime = 0; + } + else { + this.m_awakeFlag = false; + this.m_sleepTime = 0; + this.m_linearVelocity.SetZero(); + this.m_angularVelocity = 0; + this.m_force.SetZero(); + this.m_torque = 0; + } + } + /// Get the sleeping state of this body. + /// @return true if the body is sleeping. + IsAwake() { + return this.m_awakeFlag; + } + /// Allow a body to be disabled. A disabled body is not simulated and cannot + /// be collided with or woken up. + /// If you pass a flag of true, all fixtures will be added to the broad-phase. + /// If you pass a flag of false, all fixtures will be removed from the + /// broad-phase and all contacts will be destroyed. + /// Fixtures and joints are otherwise unaffected. You may continue + /// to create/destroy fixtures and joints on disabled bodies. + /// Fixtures on a disabled body are implicitly disabled and will + /// not participate in collisions, ray-casts, or queries. + /// Joints connected to a disabled body are implicitly disabled. + /// An diabled body is still owned by a b2World object and remains + /// in the body list. + SetEnabled(flag) { + if (this.m_world.IsLocked()) { + throw new Error(); + } + if (flag === this.IsEnabled()) { + return; + } + this.m_enabledFlag = flag; + if (flag) { + // Create all proxies. + for (let f = this.m_fixtureList; f; f = f.m_next) { + f.CreateProxies(); + } + // Contacts are created at the beginning of the next + this.m_world.m_newContacts = true; + } + else { + // Destroy all proxies. + for (let f = this.m_fixtureList; f; f = f.m_next) { + f.DestroyProxies(); + } + // Destroy the attached contacts. + let ce = this.m_contactList; + while (ce) { + const ce0 = ce; + ce = ce.next; + this.m_world.m_contactManager.Destroy(ce0.contact); + } + this.m_contactList = null; + } + } + /// Get the active state of the body. + IsEnabled() { + return this.m_enabledFlag; + } + /// Set this body to have fixed rotation. This causes the mass + /// to be reset. + SetFixedRotation(flag) { + if (this.m_fixedRotationFlag === flag) { + return; + } + this.m_fixedRotationFlag = flag; + this.m_angularVelocity = 0; + this.ResetMassData(); + } + /// Does this body have fixed rotation? + IsFixedRotation() { + return this.m_fixedRotationFlag; + } + /// Get the list of all fixtures attached to this body. + GetFixtureList() { + return this.m_fixtureList; + } + /// Get the list of all joints attached to this body. + GetJointList() { + return this.m_jointList; + } + /// Get the list of all contacts attached to this body. + /// @warning this list changes during the time step and you may + /// miss some collisions if you don't use b2ContactListener. + GetContactList() { + return this.m_contactList; + } + /// Get the next body in the world's body list. + GetNext() { + return this.m_next; + } + /// Get the user data pointer that was provided in the body definition. + GetUserData() { + return this.m_userData; + } + /// Set the user data. Use this to store your application specific data. + SetUserData(data) { + this.m_userData = data; + } + /// Get the parent world of this body. + GetWorld() { + return this.m_world; + } + /// Dump this body to a file + Dump(log) { + const bodyIndex = this.m_islandIndex; + log("{\n"); + log(" const bd: b2BodyDef = new b2BodyDef();\n"); + let type_str = ""; + switch (this.m_type) { + case exports.b2BodyType.b2_staticBody: + type_str = "b2BodyType.b2_staticBody"; + break; + case exports.b2BodyType.b2_kinematicBody: + type_str = "b2BodyType.b2_kinematicBody"; + break; + case exports.b2BodyType.b2_dynamicBody: + type_str = "b2BodyType.b2_dynamicBody"; + break; + } + log(" bd.type = %s;\n", type_str); + log(" bd.position.Set(%.15f, %.15f);\n", this.m_xf.p.x, this.m_xf.p.y); + log(" bd.angle = %.15f;\n", this.m_sweep.a); + log(" bd.linearVelocity.Set(%.15f, %.15f);\n", this.m_linearVelocity.x, this.m_linearVelocity.y); + log(" bd.angularVelocity = %.15f;\n", this.m_angularVelocity); + log(" bd.linearDamping = %.15f;\n", this.m_linearDamping); + log(" bd.angularDamping = %.15f;\n", this.m_angularDamping); + log(" bd.allowSleep = %s;\n", (this.m_autoSleepFlag) ? ("true") : ("false")); + log(" bd.awake = %s;\n", (this.m_awakeFlag) ? ("true") : ("false")); + log(" bd.fixedRotation = %s;\n", (this.m_fixedRotationFlag) ? ("true") : ("false")); + log(" bd.bullet = %s;\n", (this.m_bulletFlag) ? ("true") : ("false")); + log(" bd.active = %s;\n", (this.m_enabledFlag) ? ("true") : ("false")); + log(" bd.gravityScale = %.15f;\n", this.m_gravityScale); + log("\n"); + log(" bodies[%d] = this.m_world.CreateBody(bd);\n", this.m_islandIndex); + log("\n"); + for (let f = this.m_fixtureList; f; f = f.m_next) { + log(" {\n"); + f.Dump(log, bodyIndex); + log(" }\n"); + } + log("}\n"); + } + SynchronizeFixtures() { + if (this.m_awakeFlag) { + const xf1 = b2Body.SynchronizeFixtures_s_xf1; + xf1.q.SetAngle(this.m_sweep.a0); + b2Rot.MulRV(xf1.q, this.m_sweep.localCenter, xf1.p); + b2Vec2.SubVV(this.m_sweep.c0, xf1.p, xf1.p); + for (let f = this.m_fixtureList; f; f = f.m_next) { + f.SynchronizeProxies(xf1, this.m_xf); + } + } + else { + for (let f = this.m_fixtureList; f; f = f.m_next) { + f.SynchronizeProxies(this.m_xf, this.m_xf); + } + } + } + SynchronizeTransform() { + this.m_xf.q.SetAngle(this.m_sweep.a); + b2Rot.MulRV(this.m_xf.q, this.m_sweep.localCenter, this.m_xf.p); + b2Vec2.SubVV(this.m_sweep.c, this.m_xf.p, this.m_xf.p); + } + // This is used to prevent connected bodies from colliding. + // It may lie, depending on the collideConnected flag. + ShouldCollide(other) { + // At least one body should be dynamic or kinematic. + if (this.m_type === exports.b2BodyType.b2_staticBody && other.m_type === exports.b2BodyType.b2_staticBody) { + return false; + } + return this.ShouldCollideConnected(other); + } + ShouldCollideConnected(other) { + // Does a joint prevent collision? + for (let jn = this.m_jointList; jn; jn = jn.next) { + if (jn.other === other) { + if (!jn.joint.m_collideConnected) { + return false; + } + } + } + return true; + } + Advance(alpha) { + // Advance to the new safe time. This doesn't sync the broad-phase. + this.m_sweep.Advance(alpha); + this.m_sweep.c.Copy(this.m_sweep.c0); + this.m_sweep.a = this.m_sweep.a0; + this.m_xf.q.SetAngle(this.m_sweep.a); + b2Rot.MulRV(this.m_xf.q, this.m_sweep.localCenter, this.m_xf.p); + b2Vec2.SubVV(this.m_sweep.c, this.m_xf.p, this.m_xf.p); + } + } + /// Creates a fixture from a shape and attach it to this body. + /// This is a convenience function. Use b2FixtureDef if you need to set parameters + /// like friction, restitution, user data, or filtering. + /// If the density is non-zero, this function automatically updates the mass of the body. + /// @param shape the shape to be cloned. + /// @param density the shape density (set to zero for static bodies). + /// @warning This function is locked during callbacks. + b2Body.CreateFixtureShapeDensity_s_def = new b2FixtureDef(); + /// Set the mass properties to override the mass properties of the fixtures. + /// Note that this changes the center of mass position. + /// Note that creating or destroying fixtures can also alter the mass. + /// This function has no effect if the body isn't dynamic. + /// @param massData the mass properties. + b2Body.SetMassData_s_oldCenter = new b2Vec2(); + /// This resets the mass properties to the sum of the mass properties of the fixtures. + /// This normally does not need to be called unless you called SetMassData to override + /// the mass and you later want to reset the mass. + b2Body.ResetMassData_s_localCenter = new b2Vec2(); + b2Body.ResetMassData_s_oldCenter = new b2Vec2(); + b2Body.ResetMassData_s_massData = new b2MassData(); + b2Body.SynchronizeFixtures_s_xf1 = new b2Transform(); + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// Friction mixing law. The idea is to allow either fixture to drive the friction to zero. + /// For example, anything slides on ice. + function b2MixFriction(friction1, friction2) { + return b2Sqrt(friction1 * friction2); + } + /// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface. + /// For example, a superball bounces on anything. + function b2MixRestitution(restitution1, restitution2) { + return restitution1 > restitution2 ? restitution1 : restitution2; + } + /// Restitution mixing law. This picks the lowest value. + function b2MixRestitutionThreshold(threshold1, threshold2) { + return threshold1 < threshold2 ? threshold1 : threshold2; + } + class b2ContactEdge { + constructor(contact) { + this._other = null; ///< provides quick access to the other body attached. + this.prev = null; ///< the previous contact edge in the body's contact list + this.next = null; ///< the next contact edge in the body's contact list + this.contact = contact; + } + get other() { + if (this._other === null) { + throw new Error(); + } + return this._other; + } + set other(value) { + if (this._other !== null) { + throw new Error(); + } + this._other = value; + } + Reset() { + this._other = null; + this.prev = null; + this.next = null; + } + } + class b2Contact { + constructor() { + this.m_islandFlag = false; /// Used when crawling contact graph when forming islands. + this.m_touchingFlag = false; /// Set when the shapes are touching. + this.m_enabledFlag = false; /// This contact can be disabled (by user) + this.m_filterFlag = false; /// This contact needs filtering because a fixture filter was changed. + this.m_bulletHitFlag = false; /// This bullet contact had a TOI event + this.m_toiFlag = false; /// This contact has a valid TOI in m_toi + this.m_prev = null; + this.m_next = null; + this.m_nodeA = new b2ContactEdge(this); + this.m_nodeB = new b2ContactEdge(this); + this.m_indexA = 0; + this.m_indexB = 0; + this.m_manifold = new b2Manifold(); // TODO: readonly + this.m_toiCount = 0; + this.m_toi = 0; + this.m_friction = 0; + this.m_restitution = 0; + this.m_restitutionThreshold = 0; + this.m_tangentSpeed = 0; + this.m_oldManifold = new b2Manifold(); // TODO: readonly + } + GetManifold() { + return this.m_manifold; + } + GetWorldManifold(worldManifold) { + const bodyA = this.m_fixtureA.GetBody(); + const bodyB = this.m_fixtureB.GetBody(); + const shapeA = this.GetShapeA(); + const shapeB = this.GetShapeB(); + worldManifold.Initialize(this.m_manifold, bodyA.GetTransform(), shapeA.m_radius, bodyB.GetTransform(), shapeB.m_radius); + } + IsTouching() { + return this.m_touchingFlag; + } + SetEnabled(flag) { + this.m_enabledFlag = flag; + } + IsEnabled() { + return this.m_enabledFlag; + } + GetNext() { + return this.m_next; + } + GetFixtureA() { + return this.m_fixtureA; + } + GetChildIndexA() { + return this.m_indexA; + } + GetShapeA() { + return this.m_fixtureA.GetShape(); + } + GetFixtureB() { + return this.m_fixtureB; + } + GetChildIndexB() { + return this.m_indexB; + } + GetShapeB() { + return this.m_fixtureB.GetShape(); + } + FlagForFiltering() { + this.m_filterFlag = true; + } + SetFriction(friction) { + this.m_friction = friction; + } + GetFriction() { + return this.m_friction; + } + ResetFriction() { + this.m_friction = b2MixFriction(this.m_fixtureA.m_friction, this.m_fixtureB.m_friction); + } + SetRestitution(restitution) { + this.m_restitution = restitution; + } + GetRestitution() { + return this.m_restitution; + } + ResetRestitution() { + this.m_restitution = b2MixRestitution(this.m_fixtureA.m_restitution, this.m_fixtureB.m_restitution); + } + /// Override the default restitution velocity threshold mixture. You can call this in b2ContactListener::PreSolve. + /// The value persists until you set or reset. + SetRestitutionThreshold(threshold) { + this.m_restitutionThreshold = threshold; + } + /// Get the restitution threshold. + GetRestitutionThreshold() { + return this.m_restitutionThreshold; + } + /// Reset the restitution threshold to the default value. + ResetRestitutionThreshold() { + this.m_restitutionThreshold = b2MixRestitutionThreshold(this.m_fixtureA.m_restitutionThreshold, this.m_fixtureB.m_restitutionThreshold); + } + SetTangentSpeed(speed) { + this.m_tangentSpeed = speed; + } + GetTangentSpeed() { + return this.m_tangentSpeed; + } + Reset(fixtureA, indexA, fixtureB, indexB) { + this.m_islandFlag = false; + this.m_touchingFlag = false; + this.m_enabledFlag = true; + this.m_filterFlag = false; + this.m_bulletHitFlag = false; + this.m_toiFlag = false; + this.m_fixtureA = fixtureA; + this.m_fixtureB = fixtureB; + this.m_indexA = indexA; + this.m_indexB = indexB; + this.m_manifold.pointCount = 0; + this.m_prev = null; + this.m_next = null; + this.m_nodeA.Reset(); + this.m_nodeB.Reset(); + this.m_toiCount = 0; + this.m_friction = b2MixFriction(this.m_fixtureA.m_friction, this.m_fixtureB.m_friction); + this.m_restitution = b2MixRestitution(this.m_fixtureA.m_restitution, this.m_fixtureB.m_restitution); + this.m_restitutionThreshold = b2MixRestitutionThreshold(this.m_fixtureA.m_restitutionThreshold, this.m_fixtureB.m_restitutionThreshold); + } + Update(listener) { + const tManifold = this.m_oldManifold; + this.m_oldManifold = this.m_manifold; + this.m_manifold = tManifold; + // Re-enable this contact. + this.m_enabledFlag = true; + let touching = false; + const wasTouching = this.m_touchingFlag; + const sensorA = this.m_fixtureA.IsSensor(); + const sensorB = this.m_fixtureB.IsSensor(); + const sensor = sensorA || sensorB; + const bodyA = this.m_fixtureA.GetBody(); + const bodyB = this.m_fixtureB.GetBody(); + const xfA = bodyA.GetTransform(); + const xfB = bodyB.GetTransform(); + // Is this contact a sensor? + if (sensor) { + const shapeA = this.GetShapeA(); + const shapeB = this.GetShapeB(); + touching = b2TestOverlapShape(shapeA, this.m_indexA, shapeB, this.m_indexB, xfA, xfB); + // Sensors don't generate manifolds. + this.m_manifold.pointCount = 0; + } + else { + this.Evaluate(this.m_manifold, xfA, xfB); + touching = this.m_manifold.pointCount > 0; + // Match old contact ids to new contact ids and copy the + // stored impulses to warm start the solver. + for (let i = 0; i < this.m_manifold.pointCount; ++i) { + const mp2 = this.m_manifold.points[i]; + mp2.normalImpulse = 0; + mp2.tangentImpulse = 0; + const id2 = mp2.id; + for (let j = 0; j < this.m_oldManifold.pointCount; ++j) { + const mp1 = this.m_oldManifold.points[j]; + if (mp1.id.key === id2.key) { + mp2.normalImpulse = mp1.normalImpulse; + mp2.tangentImpulse = mp1.tangentImpulse; + break; + } + } + } + if (touching !== wasTouching) { + bodyA.SetAwake(true); + bodyB.SetAwake(true); + } + } + this.m_touchingFlag = touching; + if (!wasTouching && touching && listener) { + listener.BeginContact(this); + } + if (wasTouching && !touching && listener) { + listener.EndContact(this); + } + if (!sensor && touching && listener) { + listener.PreSolve(this, this.m_oldManifold); + } + } + ComputeTOI(sweepA, sweepB) { + const input = b2Contact.ComputeTOI_s_input; + input.proxyA.SetShape(this.GetShapeA(), this.m_indexA); + input.proxyB.SetShape(this.GetShapeB(), this.m_indexB); + input.sweepA.Copy(sweepA); + input.sweepB.Copy(sweepB); + input.tMax = b2_linearSlop; + const output = b2Contact.ComputeTOI_s_output; + b2TimeOfImpact(output, input); + return output.t; + } + } + b2Contact.ComputeTOI_s_input = new b2TOIInput(); + b2Contact.ComputeTOI_s_output = new b2TOIOutput(); + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + class b2ChainAndCircleContact extends b2Contact { + static Create() { + return new b2ChainAndCircleContact(); + } + static Destroy(contact) { + } + Evaluate(manifold, xfA, xfB) { + const edge = b2ChainAndCircleContact.Evaluate_s_edge; + this.GetShapeA().GetChildEdge(edge, this.m_indexA); + b2CollideEdgeAndCircle(manifold, edge, xfA, this.GetShapeB(), xfB); + } + } + b2ChainAndCircleContact.Evaluate_s_edge = new b2EdgeShape(); + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + class b2ChainAndPolygonContact extends b2Contact { + static Create() { + return new b2ChainAndPolygonContact(); + } + static Destroy(contact) { + } + Evaluate(manifold, xfA, xfB) { + const edge = b2ChainAndPolygonContact.Evaluate_s_edge; + this.GetShapeA().GetChildEdge(edge, this.m_indexA); + b2CollideEdgeAndPolygon(manifold, edge, xfA, this.GetShapeB(), xfB); + } + } + b2ChainAndPolygonContact.Evaluate_s_edge = new b2EdgeShape(); + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + class b2CircleContact extends b2Contact { + static Create() { + return new b2CircleContact(); + } + static Destroy(contact) { + } + Evaluate(manifold, xfA, xfB) { + b2CollideCircles(manifold, this.GetShapeA(), xfA, this.GetShapeB(), xfB); + } + } + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + class b2PolygonContact extends b2Contact { + static Create() { + return new b2PolygonContact(); + } + static Destroy(contact) { + } + Evaluate(manifold, xfA, xfB) { + b2CollidePolygons(manifold, this.GetShapeA(), xfA, this.GetShapeB(), xfB); + } + } + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + class b2PolygonAndCircleContact extends b2Contact { + static Create() { + return new b2PolygonAndCircleContact(); + } + static Destroy(contact) { + } + Evaluate(manifold, xfA, xfB) { + b2CollidePolygonAndCircle(manifold, this.GetShapeA(), xfA, this.GetShapeB(), xfB); + } + } + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + class b2EdgeAndCircleContact extends b2Contact { + static Create() { + return new b2EdgeAndCircleContact(); + } + static Destroy(contact) { + } + Evaluate(manifold, xfA, xfB) { + b2CollideEdgeAndCircle(manifold, this.GetShapeA(), xfA, this.GetShapeB(), xfB); + } + } + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + class b2EdgeAndPolygonContact extends b2Contact { + static Create() { + return new b2EdgeAndPolygonContact(); + } + static Destroy(contact) { + } + Evaluate(manifold, xfA, xfB) { + b2CollideEdgeAndPolygon(manifold, this.GetShapeA(), xfA, this.GetShapeB(), xfB); + } + } + + // DEBUG: import { b2Assert } from "../common/b2_settings.js"; + class b2ContactRegister { + constructor() { + this.pool = []; + this.createFcn = null; + this.destroyFcn = null; + this.primary = false; + } + } + class b2ContactFactory { + constructor() { + this.m_registers = []; + this.InitializeRegisters(); + } + AddType(createFcn, destroyFcn, typeA, typeB) { + const pool = []; + function poolCreateFcn() { + return pool.pop() || createFcn(); + } + function poolDestroyFcn(contact) { + pool.push(contact); + } + this.m_registers[typeA][typeB].pool = pool; + this.m_registers[typeA][typeB].createFcn = poolCreateFcn; // createFcn; + this.m_registers[typeA][typeB].destroyFcn = poolDestroyFcn; // destroyFcn; + this.m_registers[typeA][typeB].primary = true; + if (typeA !== typeB) { + this.m_registers[typeB][typeA].pool = pool; + this.m_registers[typeB][typeA].createFcn = poolCreateFcn; // createFcn; + this.m_registers[typeB][typeA].destroyFcn = poolDestroyFcn; // destroyFcn; + this.m_registers[typeB][typeA].primary = false; + } + } + InitializeRegisters() { + for (let i = 0; i < exports.b2ShapeType.e_shapeTypeCount; i++) { + this.m_registers[i] = []; + for (let j = 0; j < exports.b2ShapeType.e_shapeTypeCount; j++) { + this.m_registers[i][j] = new b2ContactRegister(); + } + } + this.AddType(b2CircleContact.Create, b2CircleContact.Destroy, exports.b2ShapeType.e_circleShape, exports.b2ShapeType.e_circleShape); + this.AddType(b2PolygonAndCircleContact.Create, b2PolygonAndCircleContact.Destroy, exports.b2ShapeType.e_polygonShape, exports.b2ShapeType.e_circleShape); + this.AddType(b2PolygonContact.Create, b2PolygonContact.Destroy, exports.b2ShapeType.e_polygonShape, exports.b2ShapeType.e_polygonShape); + this.AddType(b2EdgeAndCircleContact.Create, b2EdgeAndCircleContact.Destroy, exports.b2ShapeType.e_edgeShape, exports.b2ShapeType.e_circleShape); + this.AddType(b2EdgeAndPolygonContact.Create, b2EdgeAndPolygonContact.Destroy, exports.b2ShapeType.e_edgeShape, exports.b2ShapeType.e_polygonShape); + this.AddType(b2ChainAndCircleContact.Create, b2ChainAndCircleContact.Destroy, exports.b2ShapeType.e_chainShape, exports.b2ShapeType.e_circleShape); + this.AddType(b2ChainAndPolygonContact.Create, b2ChainAndPolygonContact.Destroy, exports.b2ShapeType.e_chainShape, exports.b2ShapeType.e_polygonShape); + } + Create(fixtureA, indexA, fixtureB, indexB) { + const typeA = fixtureA.GetType(); + const typeB = fixtureB.GetType(); + // DEBUG: b2Assert(0 <= typeA && typeA < b2ShapeType.e_shapeTypeCount); + // DEBUG: b2Assert(0 <= typeB && typeB < b2ShapeType.e_shapeTypeCount); + const reg = this.m_registers[typeA][typeB]; + if (reg.createFcn) { + const c = reg.createFcn(); + if (reg.primary) { + c.Reset(fixtureA, indexA, fixtureB, indexB); + } + else { + c.Reset(fixtureB, indexB, fixtureA, indexA); + } + return c; + } + else { + return null; + } + } + Destroy(contact) { + const typeA = contact.m_fixtureA.GetType(); + const typeB = contact.m_fixtureB.GetType(); + // DEBUG: b2Assert(0 <= typeA && typeB < b2ShapeType.e_shapeTypeCount); + // DEBUG: b2Assert(0 <= typeA && typeB < b2ShapeType.e_shapeTypeCount); + const reg = this.m_registers[typeA][typeB]; + if (reg.destroyFcn) { + reg.destroyFcn(contact); + } + } + } + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// Joints and fixtures are destroyed when their associated + /// body is destroyed. Implement this listener so that you + /// may nullify references to these joints and shapes. + class b2DestructionListener { + /// Called when any joint is about to be destroyed due + /// to the destruction of one of its attached bodies. + SayGoodbyeJoint(joint) { } + /// Called when any fixture is about to be destroyed due + /// to the destruction of its parent body. + SayGoodbyeFixture(fixture) { } + } + /// Implement this class to provide collision filtering. In other words, you can implement + /// this class if you want finer control over contact creation. + class b2ContactFilter { + /// Return true if contact calculations should be performed between these two shapes. + /// @warning for performance reasons this is only called when the AABBs begin to overlap. + ShouldCollide(fixtureA, fixtureB) { + const bodyA = fixtureA.GetBody(); + const bodyB = fixtureB.GetBody(); + // At least one body should be dynamic or kinematic. + if (bodyB.GetType() === exports.b2BodyType.b2_staticBody && bodyA.GetType() === exports.b2BodyType.b2_staticBody) { + return false; + } + // Does a joint prevent collision? + if (!bodyB.ShouldCollideConnected(bodyA)) { + return false; + } + const filter1 = fixtureA.GetFilterData(); + const filter2 = fixtureB.GetFilterData(); + if (filter1.groupIndex === filter2.groupIndex && filter1.groupIndex !== 0) { + return (filter1.groupIndex > 0); + } + const collide = (((filter1.maskBits & filter2.categoryBits) !== 0) && ((filter1.categoryBits & filter2.maskBits) !== 0)); + return collide; + } + } + b2ContactFilter.b2_defaultFilter = new b2ContactFilter(); + /// Contact impulses for reporting. Impulses are used instead of forces because + /// sub-step forces may approach infinity for rigid body collisions. These + /// match up one-to-one with the contact points in b2Manifold. + class b2ContactImpulse { + constructor() { + this.normalImpulses = b2MakeNumberArray(b2_maxManifoldPoints); + this.tangentImpulses = b2MakeNumberArray(b2_maxManifoldPoints); + this.count = 0; + } + } + /// Implement this class to get contact information. You can use these results for + /// things like sounds and game logic. You can also get contact results by + /// traversing the contact lists after the time step. However, you might miss + /// some contacts because continuous physics leads to sub-stepping. + /// Additionally you may receive multiple callbacks for the same contact in a + /// single time step. + /// You should strive to make your callbacks efficient because there may be + /// many callbacks per time step. + /// @warning You cannot create/destroy Box2D entities inside these callbacks. + class b2ContactListener { + /// Called when two fixtures begin to touch. + BeginContact(contact) { } + /// Called when two fixtures cease to touch. + EndContact(contact) { } + /// This is called after a contact is updated. This allows you to inspect a + /// contact before it goes to the solver. If you are careful, you can modify the + /// contact manifold (e.g. disable contact). + /// A copy of the old manifold is provided so that you can detect changes. + /// Note: this is called only for awake bodies. + /// Note: this is called even when the number of contact points is zero. + /// Note: this is not called for sensors. + /// Note: if you set the number of contact points to zero, you will not + /// get an EndContact callback. However, you may get a BeginContact callback + /// the next step. + PreSolve(contact, oldManifold) { } + /// This lets you inspect a contact after the solver is finished. This is useful + /// for inspecting impulses. + /// Note: the contact manifold does not include time of impact impulses, which can be + /// arbitrarily large if the sub-step is small. Hence the impulse is provided explicitly + /// in a separate data structure. + /// Note: this is only called for contacts that are touching, solid, and awake. + PostSolve(contact, impulse) { } + } + b2ContactListener.b2_defaultListener = new b2ContactListener(); + /// Callback class for AABB queries. + /// See b2World::Query + class b2QueryCallback { + /// Called for each fixture found in the query AABB. + /// @return false to terminate the query. + ReportFixture(fixture) { + return true; + } + } + /// Callback class for ray casts. + /// See b2World::RayCast + class b2RayCastCallback { + /// Called for each fixture found in the query. You control how the ray cast + /// proceeds by returning a float: + /// return -1: ignore this fixture and continue + /// return 0: terminate the ray cast + /// return fraction: clip the ray to this point + /// return 1: don't clip the ray and continue + /// @param fixture the fixture hit by the ray + /// @param point the point of initial intersection + /// @param normal the normal vector at the point of intersection + /// @return -1 to filter, 0 to terminate, fraction to clip the ray for + /// closest hit, 1 to continue + ReportFixture(fixture, point, normal, fraction) { + return fraction; + } + } + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + // Delegate of b2World. + class b2ContactManager { + constructor() { + this.m_broadPhase = new b2BroadPhase(); + this.m_contactList = null; + this.m_contactCount = 0; + this.m_contactFilter = b2ContactFilter.b2_defaultFilter; + this.m_contactListener = b2ContactListener.b2_defaultListener; + this.m_contactFactory = new b2ContactFactory(); + } + // Broad-phase callback. + AddPair(proxyA, proxyB) { + // DEBUG: b2Assert(proxyA instanceof b2FixtureProxy); + // DEBUG: b2Assert(proxyB instanceof b2FixtureProxy); + let fixtureA = proxyA.fixture; + let fixtureB = proxyB.fixture; + let indexA = proxyA.childIndex; + let indexB = proxyB.childIndex; + let bodyA = fixtureA.GetBody(); + let bodyB = fixtureB.GetBody(); + // Are the fixtures on the same body? + if (bodyA === bodyB) { + return; + } + // TODO_ERIN use a hash table to remove a potential bottleneck when both + // bodies have a lot of contacts. + // Does a contact already exist? + let edge = bodyB.GetContactList(); + while (edge) { + if (edge.other === bodyA) { + const fA = edge.contact.GetFixtureA(); + const fB = edge.contact.GetFixtureB(); + const iA = edge.contact.GetChildIndexA(); + const iB = edge.contact.GetChildIndexB(); + if (fA === fixtureA && fB === fixtureB && iA === indexA && iB === indexB) { + // A contact already exists. + return; + } + if (fA === fixtureB && fB === fixtureA && iA === indexB && iB === indexA) { + // A contact already exists. + return; + } + } + edge = edge.next; + } + // Check user filtering. + if (this.m_contactFilter && !this.m_contactFilter.ShouldCollide(fixtureA, fixtureB)) { + return; + } + // Call the factory. + const c = this.m_contactFactory.Create(fixtureA, indexA, fixtureB, indexB); + if (c === null) { + return; + } + // Contact creation may swap fixtures. + fixtureA = c.GetFixtureA(); + fixtureB = c.GetFixtureB(); + indexA = c.GetChildIndexA(); + indexB = c.GetChildIndexB(); + bodyA = fixtureA.m_body; + bodyB = fixtureB.m_body; + // Insert into the world. + c.m_prev = null; + c.m_next = this.m_contactList; + if (this.m_contactList !== null) { + this.m_contactList.m_prev = c; + } + this.m_contactList = c; + // Connect to island graph. + // Connect to body A + c.m_nodeA.other = bodyB; + c.m_nodeA.prev = null; + c.m_nodeA.next = bodyA.m_contactList; + if (bodyA.m_contactList !== null) { + bodyA.m_contactList.prev = c.m_nodeA; + } + bodyA.m_contactList = c.m_nodeA; + // Connect to body B + c.m_nodeB.other = bodyA; + c.m_nodeB.prev = null; + c.m_nodeB.next = bodyB.m_contactList; + if (bodyB.m_contactList !== null) { + bodyB.m_contactList.prev = c.m_nodeB; + } + bodyB.m_contactList = c.m_nodeB; + ++this.m_contactCount; + } + FindNewContacts() { + this.m_broadPhase.UpdatePairs((proxyA, proxyB) => { + this.AddPair(proxyA, proxyB); + }); + } + Destroy(c) { + const fixtureA = c.GetFixtureA(); + const fixtureB = c.GetFixtureB(); + const bodyA = fixtureA.GetBody(); + const bodyB = fixtureB.GetBody(); + if (this.m_contactListener && c.IsTouching()) { + this.m_contactListener.EndContact(c); + } + // Remove from the world. + if (c.m_prev) { + c.m_prev.m_next = c.m_next; + } + if (c.m_next) { + c.m_next.m_prev = c.m_prev; + } + if (c === this.m_contactList) { + this.m_contactList = c.m_next; + } + // Remove from body 1 + if (c.m_nodeA.prev) { + c.m_nodeA.prev.next = c.m_nodeA.next; + } + if (c.m_nodeA.next) { + c.m_nodeA.next.prev = c.m_nodeA.prev; + } + if (c.m_nodeA === bodyA.m_contactList) { + bodyA.m_contactList = c.m_nodeA.next; + } + // Remove from body 2 + if (c.m_nodeB.prev) { + c.m_nodeB.prev.next = c.m_nodeB.next; + } + if (c.m_nodeB.next) { + c.m_nodeB.next.prev = c.m_nodeB.prev; + } + if (c.m_nodeB === bodyB.m_contactList) { + bodyB.m_contactList = c.m_nodeB.next; + } + // moved this from b2ContactFactory:Destroy + if (c.m_manifold.pointCount > 0 && + !fixtureA.IsSensor() && + !fixtureB.IsSensor()) { + fixtureA.GetBody().SetAwake(true); + fixtureB.GetBody().SetAwake(true); + } + // Call the factory. + this.m_contactFactory.Destroy(c); + --this.m_contactCount; + } + // This is the top level collision call for the time step. Here + // all the narrow phase collision is processed for the world + // contact list. + Collide() { + // Update awake contacts. + let c = this.m_contactList; + while (c) { + const fixtureA = c.GetFixtureA(); + const fixtureB = c.GetFixtureB(); + const indexA = c.GetChildIndexA(); + const indexB = c.GetChildIndexB(); + const bodyA = fixtureA.GetBody(); + const bodyB = fixtureB.GetBody(); + // Is this contact flagged for filtering? + if (c.m_filterFlag) { + // Check user filtering. + if (this.m_contactFilter && !this.m_contactFilter.ShouldCollide(fixtureA, fixtureB)) { + const cNuke = c; + c = cNuke.m_next; + this.Destroy(cNuke); + continue; + } + // Clear the filtering flag. + c.m_filterFlag = false; + } + const activeA = bodyA.IsAwake() && bodyA.m_type !== exports.b2BodyType.b2_staticBody; + const activeB = bodyB.IsAwake() && bodyB.m_type !== exports.b2BodyType.b2_staticBody; + // At least one body must be awake and it must be dynamic or kinematic. + if (!activeA && !activeB) { + c = c.m_next; + continue; + } + const treeNodeA = fixtureA.m_proxies[indexA].treeNode; + const treeNodeB = fixtureB.m_proxies[indexB].treeNode; + const overlap = b2TestOverlapAABB(treeNodeA.aabb, treeNodeB.aabb); + // Here we destroy contacts that cease to overlap in the broad-phase. + if (!overlap) { + const cNuke = c; + c = cNuke.m_next; + this.Destroy(cNuke); + continue; + } + // The contact persists. + c.Update(this.m_contactListener); + c = c.m_next; + } + } + } + + /* + * Copyright (c) 2006-2011 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// Profiling data. Times are in milliseconds. + class b2Profile { + constructor() { + this.step = 0; + this.collide = 0; + this.solve = 0; + this.solveInit = 0; + this.solveVelocity = 0; + this.solvePosition = 0; + this.broadphase = 0; + this.solveTOI = 0; + } + Reset() { + this.step = 0; + this.collide = 0; + this.solve = 0; + this.solveInit = 0; + this.solveVelocity = 0; + this.solvePosition = 0; + this.broadphase = 0; + this.solveTOI = 0; + return this; + } + } + /// This is an internal structure. + class b2TimeStep { + constructor() { + this.dt = 0; // time step + this.inv_dt = 0; // inverse time step (0 if dt == 0). + this.dtRatio = 0; // dt * inv_dt0 + this.velocityIterations = 0; + this.positionIterations = 0; + this.warmStarting = false; + } + Copy(step) { + this.dt = step.dt; + this.inv_dt = step.inv_dt; + this.dtRatio = step.dtRatio; + this.positionIterations = step.positionIterations; + this.velocityIterations = step.velocityIterations; + this.warmStarting = step.warmStarting; + return this; + } + } + class b2Position { + constructor() { + this.c = new b2Vec2(); + this.a = 0; + } + static MakeArray(length) { + return b2MakeArray(length, (i) => new b2Position()); + } + } + class b2Velocity { + constructor() { + this.v = new b2Vec2(); + this.w = 0; + } + static MakeArray(length) { + return b2MakeArray(length, (i) => new b2Velocity()); + } + } + class b2SolverData { + constructor() { + this.step = new b2TimeStep(); + } + } + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + // Solver debugging is normally disabled because the block solver sometimes has to deal with a poorly conditioned effective mass matrix. + // #define B2_DEBUG_SOLVER 0 + exports.g_blockSolve = true; + function get_g_blockSolve() { return exports.g_blockSolve; } + function set_g_blockSolve(value) { exports.g_blockSolve = value; } + class b2VelocityConstraintPoint { + constructor() { + this.rA = new b2Vec2(); + this.rB = new b2Vec2(); + this.normalImpulse = 0; + this.tangentImpulse = 0; + this.normalMass = 0; + this.tangentMass = 0; + this.velocityBias = 0; + } + static MakeArray(length) { + return b2MakeArray(length, (i) => new b2VelocityConstraintPoint()); + } + } + class b2ContactVelocityConstraint { + constructor() { + this.points = b2VelocityConstraintPoint.MakeArray(b2_maxManifoldPoints); + this.normal = new b2Vec2(); + this.tangent = new b2Vec2(); + this.normalMass = new b2Mat22(); + this.K = new b2Mat22(); + this.indexA = 0; + this.indexB = 0; + this.invMassA = 0; + this.invMassB = 0; + this.invIA = 0; + this.invIB = 0; + this.friction = 0; + this.restitution = 0; + this.threshold = 0; + this.tangentSpeed = 0; + this.pointCount = 0; + this.contactIndex = 0; + } + static MakeArray(length) { + return b2MakeArray(length, (i) => new b2ContactVelocityConstraint()); + } + } + class b2ContactPositionConstraint { + constructor() { + this.localPoints = b2Vec2.MakeArray(b2_maxManifoldPoints); + this.localNormal = new b2Vec2(); + this.localPoint = new b2Vec2(); + this.indexA = 0; + this.indexB = 0; + this.invMassA = 0; + this.invMassB = 0; + this.localCenterA = new b2Vec2(); + this.localCenterB = new b2Vec2(); + this.invIA = 0; + this.invIB = 0; + this.type = exports.b2ManifoldType.e_unknown; + this.radiusA = 0; + this.radiusB = 0; + this.pointCount = 0; + } + static MakeArray(length) { + return b2MakeArray(length, (i) => new b2ContactPositionConstraint()); + } + } + class b2ContactSolverDef { + constructor() { + this.step = new b2TimeStep(); + this.count = 0; + } + } + class b2PositionSolverManifold { + constructor() { + this.normal = new b2Vec2(); + this.point = new b2Vec2(); + this.separation = 0; + } + Initialize(pc, xfA, xfB, index) { + const pointA = b2PositionSolverManifold.Initialize_s_pointA; + const pointB = b2PositionSolverManifold.Initialize_s_pointB; + const planePoint = b2PositionSolverManifold.Initialize_s_planePoint; + const clipPoint = b2PositionSolverManifold.Initialize_s_clipPoint; + // DEBUG: b2Assert(pc.pointCount > 0); + switch (pc.type) { + case exports.b2ManifoldType.e_circles: { + // b2Vec2 pointA = b2Mul(xfA, pc->localPoint); + b2Transform.MulXV(xfA, pc.localPoint, pointA); + // b2Vec2 pointB = b2Mul(xfB, pc->localPoints[0]); + b2Transform.MulXV(xfB, pc.localPoints[0], pointB); + // normal = pointB - pointA; + // normal.Normalize(); + b2Vec2.SubVV(pointB, pointA, this.normal).SelfNormalize(); + // point = 0.5f * (pointA + pointB); + b2Vec2.MidVV(pointA, pointB, this.point); + // separation = b2Dot(pointB - pointA, normal) - pc->radius; + this.separation = b2Vec2.DotVV(b2Vec2.SubVV(pointB, pointA, b2Vec2.s_t0), this.normal) - pc.radiusA - pc.radiusB; + break; + } + case exports.b2ManifoldType.e_faceA: { + // normal = b2Mul(xfA.q, pc->localNormal); + b2Rot.MulRV(xfA.q, pc.localNormal, this.normal); + // b2Vec2 planePoint = b2Mul(xfA, pc->localPoint); + b2Transform.MulXV(xfA, pc.localPoint, planePoint); + // b2Vec2 clipPoint = b2Mul(xfB, pc->localPoints[index]); + b2Transform.MulXV(xfB, pc.localPoints[index], clipPoint); + // separation = b2Dot(clipPoint - planePoint, normal) - pc->radius; + this.separation = b2Vec2.DotVV(b2Vec2.SubVV(clipPoint, planePoint, b2Vec2.s_t0), this.normal) - pc.radiusA - pc.radiusB; + // point = clipPoint; + this.point.Copy(clipPoint); + break; + } + case exports.b2ManifoldType.e_faceB: { + // normal = b2Mul(xfB.q, pc->localNormal); + b2Rot.MulRV(xfB.q, pc.localNormal, this.normal); + // b2Vec2 planePoint = b2Mul(xfB, pc->localPoint); + b2Transform.MulXV(xfB, pc.localPoint, planePoint); + // b2Vec2 clipPoint = b2Mul(xfA, pc->localPoints[index]); + b2Transform.MulXV(xfA, pc.localPoints[index], clipPoint); + // separation = b2Dot(clipPoint - planePoint, normal) - pc->radius; + this.separation = b2Vec2.DotVV(b2Vec2.SubVV(clipPoint, planePoint, b2Vec2.s_t0), this.normal) - pc.radiusA - pc.radiusB; + // point = clipPoint; + this.point.Copy(clipPoint); + // Ensure normal points from A to B + // normal = -normal; + this.normal.SelfNeg(); + break; + } + } + } + } + b2PositionSolverManifold.Initialize_s_pointA = new b2Vec2(); + b2PositionSolverManifold.Initialize_s_pointB = new b2Vec2(); + b2PositionSolverManifold.Initialize_s_planePoint = new b2Vec2(); + b2PositionSolverManifold.Initialize_s_clipPoint = new b2Vec2(); + class b2ContactSolver { + constructor() { + this.m_step = new b2TimeStep(); + this.m_positionConstraints = b2ContactPositionConstraint.MakeArray(1024); // TODO: b2Settings + this.m_velocityConstraints = b2ContactVelocityConstraint.MakeArray(1024); // TODO: b2Settings + this.m_count = 0; + } + Initialize(def) { + this.m_step.Copy(def.step); + this.m_count = def.count; + // TODO: + if (this.m_positionConstraints.length < this.m_count) { + const new_length = b2Max(this.m_positionConstraints.length * 2, this.m_count); + while (this.m_positionConstraints.length < new_length) { + this.m_positionConstraints[this.m_positionConstraints.length] = new b2ContactPositionConstraint(); + } + } + // TODO: + if (this.m_velocityConstraints.length < this.m_count) { + const new_length = b2Max(this.m_velocityConstraints.length * 2, this.m_count); + while (this.m_velocityConstraints.length < new_length) { + this.m_velocityConstraints[this.m_velocityConstraints.length] = new b2ContactVelocityConstraint(); + } + } + this.m_positions = def.positions; + this.m_velocities = def.velocities; + this.m_contacts = def.contacts; + // Initialize position independent portions of the constraints. + for (let i = 0; i < this.m_count; ++i) { + const contact = this.m_contacts[i]; + const fixtureA = contact.m_fixtureA; + const fixtureB = contact.m_fixtureB; + const shapeA = fixtureA.GetShape(); + const shapeB = fixtureB.GetShape(); + const radiusA = shapeA.m_radius; + const radiusB = shapeB.m_radius; + const bodyA = fixtureA.GetBody(); + const bodyB = fixtureB.GetBody(); + const manifold = contact.GetManifold(); + const pointCount = manifold.pointCount; + // DEBUG: b2Assert(pointCount > 0); + const vc = this.m_velocityConstraints[i]; + vc.friction = contact.m_friction; + vc.restitution = contact.m_restitution; + vc.threshold = contact.m_restitutionThreshold; + vc.tangentSpeed = contact.m_tangentSpeed; + vc.indexA = bodyA.m_islandIndex; + vc.indexB = bodyB.m_islandIndex; + vc.invMassA = bodyA.m_invMass; + vc.invMassB = bodyB.m_invMass; + vc.invIA = bodyA.m_invI; + vc.invIB = bodyB.m_invI; + vc.contactIndex = i; + vc.pointCount = pointCount; + vc.K.SetZero(); + vc.normalMass.SetZero(); + const pc = this.m_positionConstraints[i]; + pc.indexA = bodyA.m_islandIndex; + pc.indexB = bodyB.m_islandIndex; + pc.invMassA = bodyA.m_invMass; + pc.invMassB = bodyB.m_invMass; + pc.localCenterA.Copy(bodyA.m_sweep.localCenter); + pc.localCenterB.Copy(bodyB.m_sweep.localCenter); + pc.invIA = bodyA.m_invI; + pc.invIB = bodyB.m_invI; + pc.localNormal.Copy(manifold.localNormal); + pc.localPoint.Copy(manifold.localPoint); + pc.pointCount = pointCount; + pc.radiusA = radiusA; + pc.radiusB = radiusB; + pc.type = manifold.type; + for (let j = 0; j < pointCount; ++j) { + const cp = manifold.points[j]; + const vcp = vc.points[j]; + if (this.m_step.warmStarting) { + vcp.normalImpulse = this.m_step.dtRatio * cp.normalImpulse; + vcp.tangentImpulse = this.m_step.dtRatio * cp.tangentImpulse; + } + else { + vcp.normalImpulse = 0; + vcp.tangentImpulse = 0; + } + vcp.rA.SetZero(); + vcp.rB.SetZero(); + vcp.normalMass = 0; + vcp.tangentMass = 0; + vcp.velocityBias = 0; + pc.localPoints[j].Copy(cp.localPoint); + } + } + return this; + } + InitializeVelocityConstraints() { + const xfA = b2ContactSolver.InitializeVelocityConstraints_s_xfA; + const xfB = b2ContactSolver.InitializeVelocityConstraints_s_xfB; + const worldManifold = b2ContactSolver.InitializeVelocityConstraints_s_worldManifold; + const k_maxConditionNumber = 1000; + for (let i = 0; i < this.m_count; ++i) { + const vc = this.m_velocityConstraints[i]; + const pc = this.m_positionConstraints[i]; + const radiusA = pc.radiusA; + const radiusB = pc.radiusB; + const manifold = this.m_contacts[vc.contactIndex].GetManifold(); + const indexA = vc.indexA; + const indexB = vc.indexB; + const mA = vc.invMassA; + const mB = vc.invMassB; + const iA = vc.invIA; + const iB = vc.invIB; + const localCenterA = pc.localCenterA; + const localCenterB = pc.localCenterB; + const cA = this.m_positions[indexA].c; + const aA = this.m_positions[indexA].a; + const vA = this.m_velocities[indexA].v; + const wA = this.m_velocities[indexA].w; + const cB = this.m_positions[indexB].c; + const aB = this.m_positions[indexB].a; + const vB = this.m_velocities[indexB].v; + const wB = this.m_velocities[indexB].w; + // DEBUG: b2Assert(manifold.pointCount > 0); + xfA.q.SetAngle(aA); + xfB.q.SetAngle(aB); + b2Vec2.SubVV(cA, b2Rot.MulRV(xfA.q, localCenterA, b2Vec2.s_t0), xfA.p); + b2Vec2.SubVV(cB, b2Rot.MulRV(xfB.q, localCenterB, b2Vec2.s_t0), xfB.p); + worldManifold.Initialize(manifold, xfA, radiusA, xfB, radiusB); + vc.normal.Copy(worldManifold.normal); + b2Vec2.CrossVOne(vc.normal, vc.tangent); // compute from normal + const pointCount = vc.pointCount; + for (let j = 0; j < pointCount; ++j) { + const vcp = vc.points[j]; + // vcp->rA = worldManifold.points[j] - cA; + b2Vec2.SubVV(worldManifold.points[j], cA, vcp.rA); + // vcp->rB = worldManifold.points[j] - cB; + b2Vec2.SubVV(worldManifold.points[j], cB, vcp.rB); + const rnA = b2Vec2.CrossVV(vcp.rA, vc.normal); + const rnB = b2Vec2.CrossVV(vcp.rB, vc.normal); + const kNormal = mA + mB + iA * rnA * rnA + iB * rnB * rnB; + vcp.normalMass = kNormal > 0 ? 1 / kNormal : 0; + // b2Vec2 tangent = b2Cross(vc->normal, 1.0f); + const tangent = vc.tangent; // precomputed from normal + const rtA = b2Vec2.CrossVV(vcp.rA, tangent); + const rtB = b2Vec2.CrossVV(vcp.rB, tangent); + const kTangent = mA + mB + iA * rtA * rtA + iB * rtB * rtB; + vcp.tangentMass = kTangent > 0 ? 1 / kTangent : 0; + // Setup a velocity bias for restitution. + vcp.velocityBias = 0; + // float32 vRel = b2Dot(vc->normal, vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA)); + const vRel = b2Vec2.DotVV(vc.normal, b2Vec2.SubVV(b2Vec2.AddVCrossSV(vB, wB, vcp.rB, b2Vec2.s_t0), b2Vec2.AddVCrossSV(vA, wA, vcp.rA, b2Vec2.s_t1), b2Vec2.s_t0)); + if (vRel < -vc.threshold) { + vcp.velocityBias += (-vc.restitution * vRel); + } + } + // If we have two points, then prepare the block solver. + if (vc.pointCount === 2 && exports.g_blockSolve) { + const vcp1 = vc.points[0]; + const vcp2 = vc.points[1]; + const rn1A = b2Vec2.CrossVV(vcp1.rA, vc.normal); + const rn1B = b2Vec2.CrossVV(vcp1.rB, vc.normal); + const rn2A = b2Vec2.CrossVV(vcp2.rA, vc.normal); + const rn2B = b2Vec2.CrossVV(vcp2.rB, vc.normal); + const k11 = mA + mB + iA * rn1A * rn1A + iB * rn1B * rn1B; + const k22 = mA + mB + iA * rn2A * rn2A + iB * rn2B * rn2B; + const k12 = mA + mB + iA * rn1A * rn2A + iB * rn1B * rn2B; + // Ensure a reasonable condition number. + // float32 k_maxConditionNumber = 1000.0f; + if (k11 * k11 < k_maxConditionNumber * (k11 * k22 - k12 * k12)) { + // K is safe to invert. + vc.K.ex.Set(k11, k12); + vc.K.ey.Set(k12, k22); + vc.K.GetInverse(vc.normalMass); + } + else { + // The constraints are redundant, just use one. + // TODO_ERIN use deepest? + vc.pointCount = 1; + } + } + } + } + WarmStart() { + const P = b2ContactSolver.WarmStart_s_P; + // Warm start. + for (let i = 0; i < this.m_count; ++i) { + const vc = this.m_velocityConstraints[i]; + const indexA = vc.indexA; + const indexB = vc.indexB; + const mA = vc.invMassA; + const iA = vc.invIA; + const mB = vc.invMassB; + const iB = vc.invIB; + const pointCount = vc.pointCount; + const vA = this.m_velocities[indexA].v; + let wA = this.m_velocities[indexA].w; + const vB = this.m_velocities[indexB].v; + let wB = this.m_velocities[indexB].w; + const normal = vc.normal; + // b2Vec2 tangent = b2Cross(normal, 1.0f); + const tangent = vc.tangent; // precomputed from normal + for (let j = 0; j < pointCount; ++j) { + const vcp = vc.points[j]; + // b2Vec2 P = vcp->normalImpulse * normal + vcp->tangentImpulse * tangent; + b2Vec2.AddVV(b2Vec2.MulSV(vcp.normalImpulse, normal, b2Vec2.s_t0), b2Vec2.MulSV(vcp.tangentImpulse, tangent, b2Vec2.s_t1), P); + // wA -= iA * b2Cross(vcp->rA, P); + wA -= iA * b2Vec2.CrossVV(vcp.rA, P); + // vA -= mA * P; + vA.SelfMulSub(mA, P); + // wB += iB * b2Cross(vcp->rB, P); + wB += iB * b2Vec2.CrossVV(vcp.rB, P); + // vB += mB * P; + vB.SelfMulAdd(mB, P); + } + // this.m_velocities[indexA].v = vA; + this.m_velocities[indexA].w = wA; + // this.m_velocities[indexB].v = vB; + this.m_velocities[indexB].w = wB; + } + } + SolveVelocityConstraints() { + const dv = b2ContactSolver.SolveVelocityConstraints_s_dv; + const dv1 = b2ContactSolver.SolveVelocityConstraints_s_dv1; + const dv2 = b2ContactSolver.SolveVelocityConstraints_s_dv2; + const P = b2ContactSolver.SolveVelocityConstraints_s_P; + const a = b2ContactSolver.SolveVelocityConstraints_s_a; + const b = b2ContactSolver.SolveVelocityConstraints_s_b; + const x = b2ContactSolver.SolveVelocityConstraints_s_x; + const d = b2ContactSolver.SolveVelocityConstraints_s_d; + const P1 = b2ContactSolver.SolveVelocityConstraints_s_P1; + const P2 = b2ContactSolver.SolveVelocityConstraints_s_P2; + const P1P2 = b2ContactSolver.SolveVelocityConstraints_s_P1P2; + for (let i = 0; i < this.m_count; ++i) { + const vc = this.m_velocityConstraints[i]; + const indexA = vc.indexA; + const indexB = vc.indexB; + const mA = vc.invMassA; + const iA = vc.invIA; + const mB = vc.invMassB; + const iB = vc.invIB; + const pointCount = vc.pointCount; + const vA = this.m_velocities[indexA].v; + let wA = this.m_velocities[indexA].w; + const vB = this.m_velocities[indexB].v; + let wB = this.m_velocities[indexB].w; + // b2Vec2 normal = vc->normal; + const normal = vc.normal; + // b2Vec2 tangent = b2Cross(normal, 1.0f); + const tangent = vc.tangent; // precomputed from normal + const friction = vc.friction; + // DEBUG: b2Assert(pointCount === 1 || pointCount === 2); + // Solve tangent constraints first because non-penetration is more important + // than friction. + for (let j = 0; j < pointCount; ++j) { + const vcp = vc.points[j]; + // Relative velocity at contact + // b2Vec2 dv = vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA); + b2Vec2.SubVV(b2Vec2.AddVCrossSV(vB, wB, vcp.rB, b2Vec2.s_t0), b2Vec2.AddVCrossSV(vA, wA, vcp.rA, b2Vec2.s_t1), dv); + // Compute tangent force + // float32 vt = b2Dot(dv, tangent) - vc->tangentSpeed; + const vt = b2Vec2.DotVV(dv, tangent) - vc.tangentSpeed; + let lambda = vcp.tangentMass * (-vt); + // b2Clamp the accumulated force + const maxFriction = friction * vcp.normalImpulse; + const newImpulse = b2Clamp(vcp.tangentImpulse + lambda, (-maxFriction), maxFriction); + lambda = newImpulse - vcp.tangentImpulse; + vcp.tangentImpulse = newImpulse; + // Apply contact impulse + // b2Vec2 P = lambda * tangent; + b2Vec2.MulSV(lambda, tangent, P); + // vA -= mA * P; + vA.SelfMulSub(mA, P); + // wA -= iA * b2Cross(vcp->rA, P); + wA -= iA * b2Vec2.CrossVV(vcp.rA, P); + // vB += mB * P; + vB.SelfMulAdd(mB, P); + // wB += iB * b2Cross(vcp->rB, P); + wB += iB * b2Vec2.CrossVV(vcp.rB, P); + } + // Solve normal constraints + if (vc.pointCount === 1 || exports.g_blockSolve === false) { + for (let j = 0; j < pointCount; ++j) { + const vcp = vc.points[j]; + // Relative velocity at contact + // b2Vec2 dv = vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA); + b2Vec2.SubVV(b2Vec2.AddVCrossSV(vB, wB, vcp.rB, b2Vec2.s_t0), b2Vec2.AddVCrossSV(vA, wA, vcp.rA, b2Vec2.s_t1), dv); + // Compute normal impulse + // float32 vn = b2Dot(dv, normal); + const vn = b2Vec2.DotVV(dv, normal); + let lambda = (-vcp.normalMass * (vn - vcp.velocityBias)); + // b2Clamp the accumulated impulse + // float32 newImpulse = b2Max(vcp->normalImpulse + lambda, 0.0f); + const newImpulse = b2Max(vcp.normalImpulse + lambda, 0); + lambda = newImpulse - vcp.normalImpulse; + vcp.normalImpulse = newImpulse; + // Apply contact impulse + // b2Vec2 P = lambda * normal; + b2Vec2.MulSV(lambda, normal, P); + // vA -= mA * P; + vA.SelfMulSub(mA, P); + // wA -= iA * b2Cross(vcp->rA, P); + wA -= iA * b2Vec2.CrossVV(vcp.rA, P); + // vB += mB * P; + vB.SelfMulAdd(mB, P); + // wB += iB * b2Cross(vcp->rB, P); + wB += iB * b2Vec2.CrossVV(vcp.rB, P); + } + } + else { + // Block solver developed in collaboration with Dirk Gregorius (back in 01/07 on Box2D_Lite). + // Build the mini LCP for this contact patch + // + // vn = A * x + b, vn >= 0, x >= 0 and vn_i * x_i = 0 with i = 1..2 + // + // A = J * W * JT and J = ( -n, -r1 x n, n, r2 x n ) + // b = vn0 - velocityBias + // + // The system is solved using the "Total enumeration method" (s. Murty). The complementary constraint vn_i * x_i + // implies that we must have in any solution either vn_i = 0 or x_i = 0. So for the 2D contact problem the cases + // vn1 = 0 and vn2 = 0, x1 = 0 and x2 = 0, x1 = 0 and vn2 = 0, x2 = 0 and vn1 = 0 need to be tested. The first valid + // solution that satisfies the problem is chosen. + // + // In order to account of the accumulated impulse 'a' (because of the iterative nature of the solver which only requires + // that the accumulated impulse is clamped and not the incremental impulse) we change the impulse variable (x_i). + // + // Substitute: + // + // x = a + d + // + // a := old total impulse + // x := new total impulse + // d := incremental impulse + // + // For the current iteration we extend the formula for the incremental impulse + // to compute the new total impulse: + // + // vn = A * d + b + // = A * (x - a) + b + // = A * x + b - A * a + // = A * x + b' + // b' = b - A * a; + const cp1 = vc.points[0]; + const cp2 = vc.points[1]; + // b2Vec2 a(cp1->normalImpulse, cp2->normalImpulse); + a.Set(cp1.normalImpulse, cp2.normalImpulse); + // DEBUG: b2Assert(a.x >= 0 && a.y >= 0); + // Relative velocity at contact + // b2Vec2 dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA); + b2Vec2.SubVV(b2Vec2.AddVCrossSV(vB, wB, cp1.rB, b2Vec2.s_t0), b2Vec2.AddVCrossSV(vA, wA, cp1.rA, b2Vec2.s_t1), dv1); + // b2Vec2 dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA); + b2Vec2.SubVV(b2Vec2.AddVCrossSV(vB, wB, cp2.rB, b2Vec2.s_t0), b2Vec2.AddVCrossSV(vA, wA, cp2.rA, b2Vec2.s_t1), dv2); + // Compute normal velocity + // float32 vn1 = b2Dot(dv1, normal); + let vn1 = b2Vec2.DotVV(dv1, normal); + // float32 vn2 = b2Dot(dv2, normal); + let vn2 = b2Vec2.DotVV(dv2, normal); + // b2Vec2 b; + b.x = vn1 - cp1.velocityBias; + b.y = vn2 - cp2.velocityBias; + // Compute b' + // b -= b2Mul(vc->K, a); + b.SelfSub(b2Mat22.MulMV(vc.K, a, b2Vec2.s_t0)); + /* + #if B2_DEBUG_SOLVER === 1 + const k_errorTol: number = 0.001; + #endif + */ + for (;;) { + // + // Case 1: vn = 0 + // + // 0 = A * x + b' + // + // Solve for x: + // + // x = - inv(A) * b' + // + // b2Vec2 x = - b2Mul(vc->normalMass, b); + b2Mat22.MulMV(vc.normalMass, b, x).SelfNeg(); + if (x.x >= 0 && x.y >= 0) { + // Get the incremental impulse + // b2Vec2 d = x - a; + b2Vec2.SubVV(x, a, d); + // Apply incremental impulse + // b2Vec2 P1 = d.x * normal; + b2Vec2.MulSV(d.x, normal, P1); + // b2Vec2 P2 = d.y * normal; + b2Vec2.MulSV(d.y, normal, P2); + b2Vec2.AddVV(P1, P2, P1P2); + // vA -= mA * (P1 + P2); + vA.SelfMulSub(mA, P1P2); + // wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2)); + wA -= iA * (b2Vec2.CrossVV(cp1.rA, P1) + b2Vec2.CrossVV(cp2.rA, P2)); + // vB += mB * (P1 + P2); + vB.SelfMulAdd(mB, P1P2); + // wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2)); + wB += iB * (b2Vec2.CrossVV(cp1.rB, P1) + b2Vec2.CrossVV(cp2.rB, P2)); + // Accumulate + cp1.normalImpulse = x.x; + cp2.normalImpulse = x.y; + /* + #if B2_DEBUG_SOLVER === 1 + // Postconditions + dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA); + dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA); + + // Compute normal velocity + vn1 = b2Dot(dv1, normal); + vn2 = b2Dot(dv2, normal); + + b2Assert(b2Abs(vn1 - cp1->velocityBias) < k_errorTol); + b2Assert(b2Abs(vn2 - cp2->velocityBias) < k_errorTol); + #endif + */ + break; + } + // + // Case 2: vn1 = 0 and x2 = 0 + // + // 0 = a11 * x1 + a12 * 0 + b1' + // vn2 = a21 * x1 + a22 * 0 + b2' + // + x.x = (-cp1.normalMass * b.x); + x.y = 0; + vn1 = 0; + vn2 = vc.K.ex.y * x.x + b.y; + if (x.x >= 0 && vn2 >= 0) { + // Get the incremental impulse + // b2Vec2 d = x - a; + b2Vec2.SubVV(x, a, d); + // Apply incremental impulse + // b2Vec2 P1 = d.x * normal; + b2Vec2.MulSV(d.x, normal, P1); + // b2Vec2 P2 = d.y * normal; + b2Vec2.MulSV(d.y, normal, P2); + b2Vec2.AddVV(P1, P2, P1P2); + // vA -= mA * (P1 + P2); + vA.SelfMulSub(mA, P1P2); + // wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2)); + wA -= iA * (b2Vec2.CrossVV(cp1.rA, P1) + b2Vec2.CrossVV(cp2.rA, P2)); + // vB += mB * (P1 + P2); + vB.SelfMulAdd(mB, P1P2); + // wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2)); + wB += iB * (b2Vec2.CrossVV(cp1.rB, P1) + b2Vec2.CrossVV(cp2.rB, P2)); + // Accumulate + cp1.normalImpulse = x.x; + cp2.normalImpulse = x.y; + /* + #if B2_DEBUG_SOLVER === 1 + // Postconditions + dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA); + + // Compute normal velocity + vn1 = b2Dot(dv1, normal); + + b2Assert(b2Abs(vn1 - cp1->velocityBias) < k_errorTol); + #endif + */ + break; + } + // + // Case 3: vn2 = 0 and x1 = 0 + // + // vn1 = a11 * 0 + a12 * x2 + b1' + // 0 = a21 * 0 + a22 * x2 + b2' + // + x.x = 0; + x.y = (-cp2.normalMass * b.y); + vn1 = vc.K.ey.x * x.y + b.x; + vn2 = 0; + if (x.y >= 0 && vn1 >= 0) { + // Resubstitute for the incremental impulse + // b2Vec2 d = x - a; + b2Vec2.SubVV(x, a, d); + // Apply incremental impulse + // b2Vec2 P1 = d.x * normal; + b2Vec2.MulSV(d.x, normal, P1); + // b2Vec2 P2 = d.y * normal; + b2Vec2.MulSV(d.y, normal, P2); + b2Vec2.AddVV(P1, P2, P1P2); + // vA -= mA * (P1 + P2); + vA.SelfMulSub(mA, P1P2); + // wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2)); + wA -= iA * (b2Vec2.CrossVV(cp1.rA, P1) + b2Vec2.CrossVV(cp2.rA, P2)); + // vB += mB * (P1 + P2); + vB.SelfMulAdd(mB, P1P2); + // wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2)); + wB += iB * (b2Vec2.CrossVV(cp1.rB, P1) + b2Vec2.CrossVV(cp2.rB, P2)); + // Accumulate + cp1.normalImpulse = x.x; + cp2.normalImpulse = x.y; + /* + #if B2_DEBUG_SOLVER === 1 + // Postconditions + dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA); + + // Compute normal velocity + vn2 = b2Dot(dv2, normal); + + b2Assert(b2Abs(vn2 - cp2->velocityBias) < k_errorTol); + #endif + */ + break; + } + // + // Case 4: x1 = 0 and x2 = 0 + // + // vn1 = b1 + // vn2 = b2; + x.x = 0; + x.y = 0; + vn1 = b.x; + vn2 = b.y; + if (vn1 >= 0 && vn2 >= 0) { + // Resubstitute for the incremental impulse + // b2Vec2 d = x - a; + b2Vec2.SubVV(x, a, d); + // Apply incremental impulse + // b2Vec2 P1 = d.x * normal; + b2Vec2.MulSV(d.x, normal, P1); + // b2Vec2 P2 = d.y * normal; + b2Vec2.MulSV(d.y, normal, P2); + b2Vec2.AddVV(P1, P2, P1P2); + // vA -= mA * (P1 + P2); + vA.SelfMulSub(mA, P1P2); + // wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2)); + wA -= iA * (b2Vec2.CrossVV(cp1.rA, P1) + b2Vec2.CrossVV(cp2.rA, P2)); + // vB += mB * (P1 + P2); + vB.SelfMulAdd(mB, P1P2); + // wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2)); + wB += iB * (b2Vec2.CrossVV(cp1.rB, P1) + b2Vec2.CrossVV(cp2.rB, P2)); + // Accumulate + cp1.normalImpulse = x.x; + cp2.normalImpulse = x.y; + break; + } + // No solution, give up. This is hit sometimes, but it doesn't seem to matter. + break; + } + } + // this.m_velocities[indexA].v = vA; + this.m_velocities[indexA].w = wA; + // this.m_velocities[indexB].v = vB; + this.m_velocities[indexB].w = wB; + } + } + StoreImpulses() { + for (let i = 0; i < this.m_count; ++i) { + const vc = this.m_velocityConstraints[i]; + const manifold = this.m_contacts[vc.contactIndex].GetManifold(); + for (let j = 0; j < vc.pointCount; ++j) { + manifold.points[j].normalImpulse = vc.points[j].normalImpulse; + manifold.points[j].tangentImpulse = vc.points[j].tangentImpulse; + } + } + } + SolvePositionConstraints() { + const xfA = b2ContactSolver.SolvePositionConstraints_s_xfA; + const xfB = b2ContactSolver.SolvePositionConstraints_s_xfB; + const psm = b2ContactSolver.SolvePositionConstraints_s_psm; + const rA = b2ContactSolver.SolvePositionConstraints_s_rA; + const rB = b2ContactSolver.SolvePositionConstraints_s_rB; + const P = b2ContactSolver.SolvePositionConstraints_s_P; + let minSeparation = 0; + for (let i = 0; i < this.m_count; ++i) { + const pc = this.m_positionConstraints[i]; + const indexA = pc.indexA; + const indexB = pc.indexB; + const localCenterA = pc.localCenterA; + const mA = pc.invMassA; + const iA = pc.invIA; + const localCenterB = pc.localCenterB; + const mB = pc.invMassB; + const iB = pc.invIB; + const pointCount = pc.pointCount; + const cA = this.m_positions[indexA].c; + let aA = this.m_positions[indexA].a; + const cB = this.m_positions[indexB].c; + let aB = this.m_positions[indexB].a; + // Solve normal constraints + for (let j = 0; j < pointCount; ++j) { + xfA.q.SetAngle(aA); + xfB.q.SetAngle(aB); + b2Vec2.SubVV(cA, b2Rot.MulRV(xfA.q, localCenterA, b2Vec2.s_t0), xfA.p); + b2Vec2.SubVV(cB, b2Rot.MulRV(xfB.q, localCenterB, b2Vec2.s_t0), xfB.p); + psm.Initialize(pc, xfA, xfB, j); + const normal = psm.normal; + const point = psm.point; + const separation = psm.separation; + // b2Vec2 rA = point - cA; + b2Vec2.SubVV(point, cA, rA); + // b2Vec2 rB = point - cB; + b2Vec2.SubVV(point, cB, rB); + // Track max constraint error. + minSeparation = b2Min(minSeparation, separation); + // Prevent large corrections and allow slop. + const C = b2Clamp(b2_baumgarte * (separation + b2_linearSlop), (-b2_maxLinearCorrection), 0); + // Compute the effective mass. + // float32 rnA = b2Cross(rA, normal); + const rnA = b2Vec2.CrossVV(rA, normal); + // float32 rnB = b2Cross(rB, normal); + const rnB = b2Vec2.CrossVV(rB, normal); + // float32 K = mA + mB + iA * rnA * rnA + iB * rnB * rnB; + const K = mA + mB + iA * rnA * rnA + iB * rnB * rnB; + // Compute normal impulse + const impulse = K > 0 ? -C / K : 0; + // b2Vec2 P = impulse * normal; + b2Vec2.MulSV(impulse, normal, P); + // cA -= mA * P; + cA.SelfMulSub(mA, P); + // aA -= iA * b2Cross(rA, P); + aA -= iA * b2Vec2.CrossVV(rA, P); + // cB += mB * P; + cB.SelfMulAdd(mB, P); + // aB += iB * b2Cross(rB, P); + aB += iB * b2Vec2.CrossVV(rB, P); + } + // this.m_positions[indexA].c = cA; + this.m_positions[indexA].a = aA; + // this.m_positions[indexB].c = cB; + this.m_positions[indexB].a = aB; + } + // We can't expect minSpeparation >= -b2_linearSlop because we don't + // push the separation above -b2_linearSlop. + return minSeparation > (-3 * b2_linearSlop); + } + SolveTOIPositionConstraints(toiIndexA, toiIndexB) { + const xfA = b2ContactSolver.SolveTOIPositionConstraints_s_xfA; + const xfB = b2ContactSolver.SolveTOIPositionConstraints_s_xfB; + const psm = b2ContactSolver.SolveTOIPositionConstraints_s_psm; + const rA = b2ContactSolver.SolveTOIPositionConstraints_s_rA; + const rB = b2ContactSolver.SolveTOIPositionConstraints_s_rB; + const P = b2ContactSolver.SolveTOIPositionConstraints_s_P; + let minSeparation = 0; + for (let i = 0; i < this.m_count; ++i) { + const pc = this.m_positionConstraints[i]; + const indexA = pc.indexA; + const indexB = pc.indexB; + const localCenterA = pc.localCenterA; + const localCenterB = pc.localCenterB; + const pointCount = pc.pointCount; + let mA = 0; + let iA = 0; + if (indexA === toiIndexA || indexA === toiIndexB) { + mA = pc.invMassA; + iA = pc.invIA; + } + let mB = 0; + let iB = 0; + if (indexB === toiIndexA || indexB === toiIndexB) { + mB = pc.invMassB; + iB = pc.invIB; + } + const cA = this.m_positions[indexA].c; + let aA = this.m_positions[indexA].a; + const cB = this.m_positions[indexB].c; + let aB = this.m_positions[indexB].a; + // Solve normal constraints + for (let j = 0; j < pointCount; ++j) { + xfA.q.SetAngle(aA); + xfB.q.SetAngle(aB); + b2Vec2.SubVV(cA, b2Rot.MulRV(xfA.q, localCenterA, b2Vec2.s_t0), xfA.p); + b2Vec2.SubVV(cB, b2Rot.MulRV(xfB.q, localCenterB, b2Vec2.s_t0), xfB.p); + psm.Initialize(pc, xfA, xfB, j); + const normal = psm.normal; + const point = psm.point; + const separation = psm.separation; + // b2Vec2 rA = point - cA; + b2Vec2.SubVV(point, cA, rA); + // b2Vec2 rB = point - cB; + b2Vec2.SubVV(point, cB, rB); + // Track max constraint error. + minSeparation = b2Min(minSeparation, separation); + // Prevent large corrections and allow slop. + const C = b2Clamp(b2_toiBaumgarte * (separation + b2_linearSlop), (-b2_maxLinearCorrection), 0); + // Compute the effective mass. + // float32 rnA = b2Cross(rA, normal); + const rnA = b2Vec2.CrossVV(rA, normal); + // float32 rnB = b2Cross(rB, normal); + const rnB = b2Vec2.CrossVV(rB, normal); + // float32 K = mA + mB + iA * rnA * rnA + iB * rnB * rnB; + const K = mA + mB + iA * rnA * rnA + iB * rnB * rnB; + // Compute normal impulse + const impulse = K > 0 ? -C / K : 0; + // b2Vec2 P = impulse * normal; + b2Vec2.MulSV(impulse, normal, P); + // cA -= mA * P; + cA.SelfMulSub(mA, P); + // aA -= iA * b2Cross(rA, P); + aA -= iA * b2Vec2.CrossVV(rA, P); + // cB += mB * P; + cB.SelfMulAdd(mB, P); + // aB += iB * b2Cross(rB, P); + aB += iB * b2Vec2.CrossVV(rB, P); + } + // this.m_positions[indexA].c = cA; + this.m_positions[indexA].a = aA; + // this.m_positions[indexB].c = cB; + this.m_positions[indexB].a = aB; + } + // We can't expect minSpeparation >= -b2_linearSlop because we don't + // push the separation above -b2_linearSlop. + return minSeparation >= -1.5 * b2_linearSlop; + } + } + b2ContactSolver.InitializeVelocityConstraints_s_xfA = new b2Transform(); + b2ContactSolver.InitializeVelocityConstraints_s_xfB = new b2Transform(); + b2ContactSolver.InitializeVelocityConstraints_s_worldManifold = new b2WorldManifold(); + b2ContactSolver.WarmStart_s_P = new b2Vec2(); + b2ContactSolver.SolveVelocityConstraints_s_dv = new b2Vec2(); + b2ContactSolver.SolveVelocityConstraints_s_dv1 = new b2Vec2(); + b2ContactSolver.SolveVelocityConstraints_s_dv2 = new b2Vec2(); + b2ContactSolver.SolveVelocityConstraints_s_P = new b2Vec2(); + b2ContactSolver.SolveVelocityConstraints_s_a = new b2Vec2(); + b2ContactSolver.SolveVelocityConstraints_s_b = new b2Vec2(); + b2ContactSolver.SolveVelocityConstraints_s_x = new b2Vec2(); + b2ContactSolver.SolveVelocityConstraints_s_d = new b2Vec2(); + b2ContactSolver.SolveVelocityConstraints_s_P1 = new b2Vec2(); + b2ContactSolver.SolveVelocityConstraints_s_P2 = new b2Vec2(); + b2ContactSolver.SolveVelocityConstraints_s_P1P2 = new b2Vec2(); + b2ContactSolver.SolvePositionConstraints_s_xfA = new b2Transform(); + b2ContactSolver.SolvePositionConstraints_s_xfB = new b2Transform(); + b2ContactSolver.SolvePositionConstraints_s_psm = new b2PositionSolverManifold(); + b2ContactSolver.SolvePositionConstraints_s_rA = new b2Vec2(); + b2ContactSolver.SolvePositionConstraints_s_rB = new b2Vec2(); + b2ContactSolver.SolvePositionConstraints_s_P = new b2Vec2(); + b2ContactSolver.SolveTOIPositionConstraints_s_xfA = new b2Transform(); + b2ContactSolver.SolveTOIPositionConstraints_s_xfB = new b2Transform(); + b2ContactSolver.SolveTOIPositionConstraints_s_psm = new b2PositionSolverManifold(); + b2ContactSolver.SolveTOIPositionConstraints_s_rA = new b2Vec2(); + b2ContactSolver.SolveTOIPositionConstraints_s_rB = new b2Vec2(); + b2ContactSolver.SolveTOIPositionConstraints_s_P = new b2Vec2(); + + /* + * Copyright (c) 2006-2007 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// Friction joint definition. + class b2FrictionJointDef extends b2JointDef { + constructor() { + super(exports.b2JointType.e_frictionJoint); + this.localAnchorA = new b2Vec2(); + this.localAnchorB = new b2Vec2(); + this.maxForce = 0; + this.maxTorque = 0; + } + Initialize(bA, bB, anchor) { + this.bodyA = bA; + this.bodyB = bB; + this.bodyA.GetLocalPoint(anchor, this.localAnchorA); + this.bodyB.GetLocalPoint(anchor, this.localAnchorB); + } + } + class b2FrictionJoint extends b2Joint { + constructor(def) { + super(def); + this.m_localAnchorA = new b2Vec2(); + this.m_localAnchorB = new b2Vec2(); + // Solver shared + this.m_linearImpulse = new b2Vec2(); + this.m_angularImpulse = 0; + this.m_maxForce = 0; + this.m_maxTorque = 0; + // Solver temp + this.m_indexA = 0; + this.m_indexB = 0; + this.m_rA = new b2Vec2(); + this.m_rB = new b2Vec2(); + this.m_localCenterA = new b2Vec2(); + this.m_localCenterB = new b2Vec2(); + this.m_invMassA = 0; + this.m_invMassB = 0; + this.m_invIA = 0; + this.m_invIB = 0; + this.m_linearMass = new b2Mat22(); + this.m_angularMass = 0; + this.m_qA = new b2Rot(); + this.m_qB = new b2Rot(); + this.m_lalcA = new b2Vec2(); + this.m_lalcB = new b2Vec2(); + this.m_K = new b2Mat22(); + this.m_localAnchorA.Copy(b2Maybe(def.localAnchorA, b2Vec2.ZERO)); + this.m_localAnchorB.Copy(b2Maybe(def.localAnchorB, b2Vec2.ZERO)); + this.m_linearImpulse.SetZero(); + this.m_maxForce = b2Maybe(def.maxForce, 0); + this.m_maxTorque = b2Maybe(def.maxTorque, 0); + this.m_linearMass.SetZero(); + } + InitVelocityConstraints(data) { + this.m_indexA = this.m_bodyA.m_islandIndex; + this.m_indexB = this.m_bodyB.m_islandIndex; + this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter); + this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter); + this.m_invMassA = this.m_bodyA.m_invMass; + this.m_invMassB = this.m_bodyB.m_invMass; + this.m_invIA = this.m_bodyA.m_invI; + this.m_invIB = this.m_bodyB.m_invI; + // const cA: b2Vec2 = data.positions[this.m_indexA].c; + const aA = data.positions[this.m_indexA].a; + const vA = data.velocities[this.m_indexA].v; + let wA = data.velocities[this.m_indexA].w; + // const cB: b2Vec2 = data.positions[this.m_indexB].c; + const aB = data.positions[this.m_indexB].a; + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + // const qA: b2Rot = new b2Rot(aA), qB: b2Rot = new b2Rot(aB); + const qA = this.m_qA.SetAngle(aA), qB = this.m_qB.SetAngle(aB); + // Compute the effective mass matrix. + // m_rA = b2Mul(qA, m_localAnchorA - m_localCenterA); + b2Vec2.SubVV(this.m_localAnchorA, this.m_localCenterA, this.m_lalcA); + const rA = b2Rot.MulRV(qA, this.m_lalcA, this.m_rA); + // m_rB = b2Mul(qB, m_localAnchorB - m_localCenterB); + b2Vec2.SubVV(this.m_localAnchorB, this.m_localCenterB, this.m_lalcB); + const rB = b2Rot.MulRV(qB, this.m_lalcB, this.m_rB); + // J = [-I -r1_skew I r2_skew] + // [ 0 -1 0 1] + // r_skew = [-ry; rx] + // Matlab + // K = [ mA+r1y^2*iA+mB+r2y^2*iB, -r1y*iA*r1x-r2y*iB*r2x, -r1y*iA-r2y*iB] + // [ -r1y*iA*r1x-r2y*iB*r2x, mA+r1x^2*iA+mB+r2x^2*iB, r1x*iA+r2x*iB] + // [ -r1y*iA-r2y*iB, r1x*iA+r2x*iB, iA+iB] + const mA = this.m_invMassA, mB = this.m_invMassB; + const iA = this.m_invIA, iB = this.m_invIB; + const K = this.m_K; // new b2Mat22(); + K.ex.x = mA + mB + iA * rA.y * rA.y + iB * rB.y * rB.y; + K.ex.y = -iA * rA.x * rA.y - iB * rB.x * rB.y; + K.ey.x = K.ex.y; + K.ey.y = mA + mB + iA * rA.x * rA.x + iB * rB.x * rB.x; + K.GetInverse(this.m_linearMass); + this.m_angularMass = iA + iB; + if (this.m_angularMass > 0) { + this.m_angularMass = 1 / this.m_angularMass; + } + if (data.step.warmStarting) { + // Scale impulses to support a variable time step. + // m_linearImpulse *= data.step.dtRatio; + this.m_linearImpulse.SelfMul(data.step.dtRatio); + this.m_angularImpulse *= data.step.dtRatio; + // const P: b2Vec2(m_linearImpulse.x, m_linearImpulse.y); + const P = this.m_linearImpulse; + // vA -= mA * P; + vA.SelfMulSub(mA, P); + // wA -= iA * (b2Cross(m_rA, P) + m_angularImpulse); + wA -= iA * (b2Vec2.CrossVV(this.m_rA, P) + this.m_angularImpulse); + // vB += mB * P; + vB.SelfMulAdd(mB, P); + // wB += iB * (b2Cross(m_rB, P) + m_angularImpulse); + wB += iB * (b2Vec2.CrossVV(this.m_rB, P) + this.m_angularImpulse); + } + else { + this.m_linearImpulse.SetZero(); + this.m_angularImpulse = 0; + } + // data.velocities[this.m_indexA].v = vA; + data.velocities[this.m_indexA].w = wA; + // data.velocities[this.m_indexB].v = vB; + data.velocities[this.m_indexB].w = wB; + } + SolveVelocityConstraints(data) { + const vA = data.velocities[this.m_indexA].v; + let wA = data.velocities[this.m_indexA].w; + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + const mA = this.m_invMassA, mB = this.m_invMassB; + const iA = this.m_invIA, iB = this.m_invIB; + const h = data.step.dt; + // Solve angular friction + { + const Cdot = wB - wA; + let impulse = (-this.m_angularMass * Cdot); + const oldImpulse = this.m_angularImpulse; + const maxImpulse = h * this.m_maxTorque; + this.m_angularImpulse = b2Clamp(this.m_angularImpulse + impulse, (-maxImpulse), maxImpulse); + impulse = this.m_angularImpulse - oldImpulse; + wA -= iA * impulse; + wB += iB * impulse; + } + // Solve linear friction + { + // b2Vec2 Cdot = vB + b2Cross(wB, m_rB) - vA - b2Cross(wA, m_rA); + const Cdot_v2 = b2Vec2.SubVV(b2Vec2.AddVCrossSV(vB, wB, this.m_rB, b2Vec2.s_t0), b2Vec2.AddVCrossSV(vA, wA, this.m_rA, b2Vec2.s_t1), b2FrictionJoint.SolveVelocityConstraints_s_Cdot_v2); + // b2Vec2 impulse = -b2Mul(m_linearMass, Cdot); + const impulseV = b2Mat22.MulMV(this.m_linearMass, Cdot_v2, b2FrictionJoint.SolveVelocityConstraints_s_impulseV).SelfNeg(); + // b2Vec2 oldImpulse = m_linearImpulse; + const oldImpulseV = b2FrictionJoint.SolveVelocityConstraints_s_oldImpulseV.Copy(this.m_linearImpulse); + // m_linearImpulse += impulse; + this.m_linearImpulse.SelfAdd(impulseV); + const maxImpulse = h * this.m_maxForce; + if (this.m_linearImpulse.LengthSquared() > maxImpulse * maxImpulse) { + this.m_linearImpulse.Normalize(); + this.m_linearImpulse.SelfMul(maxImpulse); + } + // impulse = m_linearImpulse - oldImpulse; + b2Vec2.SubVV(this.m_linearImpulse, oldImpulseV, impulseV); + // vA -= mA * impulse; + vA.SelfMulSub(mA, impulseV); + // wA -= iA * b2Cross(m_rA, impulse); + wA -= iA * b2Vec2.CrossVV(this.m_rA, impulseV); + // vB += mB * impulse; + vB.SelfMulAdd(mB, impulseV); + // wB += iB * b2Cross(m_rB, impulse); + wB += iB * b2Vec2.CrossVV(this.m_rB, impulseV); + } + // data.velocities[this.m_indexA].v = vA; + data.velocities[this.m_indexA].w = wA; + // data.velocities[this.m_indexB].v = vB; + data.velocities[this.m_indexB].w = wB; + } + SolvePositionConstraints(data) { + return true; + } + GetAnchorA(out) { + return this.m_bodyA.GetWorldPoint(this.m_localAnchorA, out); + } + GetAnchorB(out) { + return this.m_bodyB.GetWorldPoint(this.m_localAnchorB, out); + } + GetReactionForce(inv_dt, out) { + out.x = inv_dt * this.m_linearImpulse.x; + out.y = inv_dt * this.m_linearImpulse.y; + return out; + } + GetReactionTorque(inv_dt) { + return inv_dt * this.m_angularImpulse; + } + GetLocalAnchorA() { return this.m_localAnchorA; } + GetLocalAnchorB() { return this.m_localAnchorB; } + SetMaxForce(force) { + this.m_maxForce = force; + } + GetMaxForce() { + return this.m_maxForce; + } + SetMaxTorque(torque) { + this.m_maxTorque = torque; + } + GetMaxTorque() { + return this.m_maxTorque; + } + Dump(log) { + const indexA = this.m_bodyA.m_islandIndex; + const indexB = this.m_bodyB.m_islandIndex; + log(" const jd: b2FrictionJointDef = new b2FrictionJointDef();\n"); + log(" jd.bodyA = bodies[%d];\n", indexA); + log(" jd.bodyB = bodies[%d];\n", indexB); + log(" jd.collideConnected = %s;\n", (this.m_collideConnected) ? ("true") : ("false")); + log(" jd.localAnchorA.Set(%.15f, %.15f);\n", this.m_localAnchorA.x, this.m_localAnchorA.y); + log(" jd.localAnchorB.Set(%.15f, %.15f);\n", this.m_localAnchorB.x, this.m_localAnchorB.y); + log(" jd.maxForce = %.15f;\n", this.m_maxForce); + log(" jd.maxTorque = %.15f;\n", this.m_maxTorque); + log(" joints[%d] = this.m_world.CreateJoint(jd);\n", this.m_index); + } + } + b2FrictionJoint.SolveVelocityConstraints_s_Cdot_v2 = new b2Vec2(); + b2FrictionJoint.SolveVelocityConstraints_s_impulseV = new b2Vec2(); + b2FrictionJoint.SolveVelocityConstraints_s_oldImpulseV = new b2Vec2(); + + /* + * Copyright (c) 2006-2011 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// Gear joint definition. This definition requires two existing + /// revolute or prismatic joints (any combination will work). + class b2GearJointDef extends b2JointDef { + constructor() { + super(exports.b2JointType.e_gearJoint); + this.ratio = 1; + } + } + class b2GearJoint extends b2Joint { + constructor(def) { + super(def); + this.m_typeA = exports.b2JointType.e_unknownJoint; + this.m_typeB = exports.b2JointType.e_unknownJoint; + // Solver shared + this.m_localAnchorA = new b2Vec2(); + this.m_localAnchorB = new b2Vec2(); + this.m_localAnchorC = new b2Vec2(); + this.m_localAnchorD = new b2Vec2(); + this.m_localAxisC = new b2Vec2(); + this.m_localAxisD = new b2Vec2(); + this.m_referenceAngleA = 0; + this.m_referenceAngleB = 0; + this.m_constant = 0; + this.m_ratio = 0; + this.m_impulse = 0; + // Solver temp + this.m_indexA = 0; + this.m_indexB = 0; + this.m_indexC = 0; + this.m_indexD = 0; + this.m_lcA = new b2Vec2(); + this.m_lcB = new b2Vec2(); + this.m_lcC = new b2Vec2(); + this.m_lcD = new b2Vec2(); + this.m_mA = 0; + this.m_mB = 0; + this.m_mC = 0; + this.m_mD = 0; + this.m_iA = 0; + this.m_iB = 0; + this.m_iC = 0; + this.m_iD = 0; + this.m_JvAC = new b2Vec2(); + this.m_JvBD = new b2Vec2(); + this.m_JwA = 0; + this.m_JwB = 0; + this.m_JwC = 0; + this.m_JwD = 0; + this.m_mass = 0; + this.m_qA = new b2Rot(); + this.m_qB = new b2Rot(); + this.m_qC = new b2Rot(); + this.m_qD = new b2Rot(); + this.m_lalcA = new b2Vec2(); + this.m_lalcB = new b2Vec2(); + this.m_lalcC = new b2Vec2(); + this.m_lalcD = new b2Vec2(); + this.m_joint1 = def.joint1; + this.m_joint2 = def.joint2; + this.m_typeA = this.m_joint1.GetType(); + this.m_typeB = this.m_joint2.GetType(); + // DEBUG: b2Assert(this.m_typeA === b2JointType.e_revoluteJoint || this.m_typeA === b2JointType.e_prismaticJoint); + // DEBUG: b2Assert(this.m_typeB === b2JointType.e_revoluteJoint || this.m_typeB === b2JointType.e_prismaticJoint); + let coordinateA, coordinateB; + // TODO_ERIN there might be some problem with the joint edges in b2Joint. + this.m_bodyC = this.m_joint1.GetBodyA(); + this.m_bodyA = this.m_joint1.GetBodyB(); + // Body B on joint1 must be dynamic + // b2Assert(this.m_bodyA.m_type === b2_dynamicBody); + // Get geometry of joint1 + const xfA = this.m_bodyA.m_xf; + const aA = this.m_bodyA.m_sweep.a; + const xfC = this.m_bodyC.m_xf; + const aC = this.m_bodyC.m_sweep.a; + if (this.m_typeA === exports.b2JointType.e_revoluteJoint) { + const revolute = def.joint1; + this.m_localAnchorC.Copy(revolute.m_localAnchorA); + this.m_localAnchorA.Copy(revolute.m_localAnchorB); + this.m_referenceAngleA = revolute.m_referenceAngle; + this.m_localAxisC.SetZero(); + coordinateA = aA - aC - this.m_referenceAngleA; + } + else { + const prismatic = def.joint1; + this.m_localAnchorC.Copy(prismatic.m_localAnchorA); + this.m_localAnchorA.Copy(prismatic.m_localAnchorB); + this.m_referenceAngleA = prismatic.m_referenceAngle; + this.m_localAxisC.Copy(prismatic.m_localXAxisA); + // b2Vec2 pC = m_localAnchorC; + const pC = this.m_localAnchorC; + // b2Vec2 pA = b2MulT(xfC.q, b2Mul(xfA.q, m_localAnchorA) + (xfA.p - xfC.p)); + const pA = b2Rot.MulTRV(xfC.q, b2Vec2.AddVV(b2Rot.MulRV(xfA.q, this.m_localAnchorA, b2Vec2.s_t0), b2Vec2.SubVV(xfA.p, xfC.p, b2Vec2.s_t1), b2Vec2.s_t0), b2Vec2.s_t0); // pA uses s_t0 + // coordinateA = b2Dot(pA - pC, m_localAxisC); + coordinateA = b2Vec2.DotVV(b2Vec2.SubVV(pA, pC, b2Vec2.s_t0), this.m_localAxisC); + } + this.m_bodyD = this.m_joint2.GetBodyA(); + this.m_bodyB = this.m_joint2.GetBodyB(); + // Body B on joint2 must be dynamic + // b2Assert(this.m_bodyB.m_type === b2_dynamicBody); + // Get geometry of joint2 + const xfB = this.m_bodyB.m_xf; + const aB = this.m_bodyB.m_sweep.a; + const xfD = this.m_bodyD.m_xf; + const aD = this.m_bodyD.m_sweep.a; + if (this.m_typeB === exports.b2JointType.e_revoluteJoint) { + const revolute = def.joint2; + this.m_localAnchorD.Copy(revolute.m_localAnchorA); + this.m_localAnchorB.Copy(revolute.m_localAnchorB); + this.m_referenceAngleB = revolute.m_referenceAngle; + this.m_localAxisD.SetZero(); + coordinateB = aB - aD - this.m_referenceAngleB; + } + else { + const prismatic = def.joint2; + this.m_localAnchorD.Copy(prismatic.m_localAnchorA); + this.m_localAnchorB.Copy(prismatic.m_localAnchorB); + this.m_referenceAngleB = prismatic.m_referenceAngle; + this.m_localAxisD.Copy(prismatic.m_localXAxisA); + // b2Vec2 pD = m_localAnchorD; + const pD = this.m_localAnchorD; + // b2Vec2 pB = b2MulT(xfD.q, b2Mul(xfB.q, m_localAnchorB) + (xfB.p - xfD.p)); + const pB = b2Rot.MulTRV(xfD.q, b2Vec2.AddVV(b2Rot.MulRV(xfB.q, this.m_localAnchorB, b2Vec2.s_t0), b2Vec2.SubVV(xfB.p, xfD.p, b2Vec2.s_t1), b2Vec2.s_t0), b2Vec2.s_t0); // pB uses s_t0 + // coordinateB = b2Dot(pB - pD, m_localAxisD); + coordinateB = b2Vec2.DotVV(b2Vec2.SubVV(pB, pD, b2Vec2.s_t0), this.m_localAxisD); + } + this.m_ratio = b2Maybe(def.ratio, 1); + this.m_constant = coordinateA + this.m_ratio * coordinateB; + this.m_impulse = 0; + } + InitVelocityConstraints(data) { + this.m_indexA = this.m_bodyA.m_islandIndex; + this.m_indexB = this.m_bodyB.m_islandIndex; + this.m_indexC = this.m_bodyC.m_islandIndex; + this.m_indexD = this.m_bodyD.m_islandIndex; + this.m_lcA.Copy(this.m_bodyA.m_sweep.localCenter); + this.m_lcB.Copy(this.m_bodyB.m_sweep.localCenter); + this.m_lcC.Copy(this.m_bodyC.m_sweep.localCenter); + this.m_lcD.Copy(this.m_bodyD.m_sweep.localCenter); + this.m_mA = this.m_bodyA.m_invMass; + this.m_mB = this.m_bodyB.m_invMass; + this.m_mC = this.m_bodyC.m_invMass; + this.m_mD = this.m_bodyD.m_invMass; + this.m_iA = this.m_bodyA.m_invI; + this.m_iB = this.m_bodyB.m_invI; + this.m_iC = this.m_bodyC.m_invI; + this.m_iD = this.m_bodyD.m_invI; + const aA = data.positions[this.m_indexA].a; + const vA = data.velocities[this.m_indexA].v; + let wA = data.velocities[this.m_indexA].w; + const aB = data.positions[this.m_indexB].a; + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + const aC = data.positions[this.m_indexC].a; + const vC = data.velocities[this.m_indexC].v; + let wC = data.velocities[this.m_indexC].w; + const aD = data.positions[this.m_indexD].a; + const vD = data.velocities[this.m_indexD].v; + let wD = data.velocities[this.m_indexD].w; + // b2Rot qA(aA), qB(aB), qC(aC), qD(aD); + const qA = this.m_qA.SetAngle(aA), qB = this.m_qB.SetAngle(aB), qC = this.m_qC.SetAngle(aC), qD = this.m_qD.SetAngle(aD); + this.m_mass = 0; + if (this.m_typeA === exports.b2JointType.e_revoluteJoint) { + this.m_JvAC.SetZero(); + this.m_JwA = 1; + this.m_JwC = 1; + this.m_mass += this.m_iA + this.m_iC; + } + else { + // b2Vec2 u = b2Mul(qC, m_localAxisC); + const u = b2Rot.MulRV(qC, this.m_localAxisC, b2GearJoint.InitVelocityConstraints_s_u); + // b2Vec2 rC = b2Mul(qC, m_localAnchorC - m_lcC); + b2Vec2.SubVV(this.m_localAnchorC, this.m_lcC, this.m_lalcC); + const rC = b2Rot.MulRV(qC, this.m_lalcC, b2GearJoint.InitVelocityConstraints_s_rC); + // b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_lcA); + b2Vec2.SubVV(this.m_localAnchorA, this.m_lcA, this.m_lalcA); + const rA = b2Rot.MulRV(qA, this.m_lalcA, b2GearJoint.InitVelocityConstraints_s_rA); + // m_JvAC = u; + this.m_JvAC.Copy(u); + // m_JwC = b2Cross(rC, u); + this.m_JwC = b2Vec2.CrossVV(rC, u); + // m_JwA = b2Cross(rA, u); + this.m_JwA = b2Vec2.CrossVV(rA, u); + this.m_mass += this.m_mC + this.m_mA + this.m_iC * this.m_JwC * this.m_JwC + this.m_iA * this.m_JwA * this.m_JwA; + } + if (this.m_typeB === exports.b2JointType.e_revoluteJoint) { + this.m_JvBD.SetZero(); + this.m_JwB = this.m_ratio; + this.m_JwD = this.m_ratio; + this.m_mass += this.m_ratio * this.m_ratio * (this.m_iB + this.m_iD); + } + else { + // b2Vec2 u = b2Mul(qD, m_localAxisD); + const u = b2Rot.MulRV(qD, this.m_localAxisD, b2GearJoint.InitVelocityConstraints_s_u); + // b2Vec2 rD = b2Mul(qD, m_localAnchorD - m_lcD); + b2Vec2.SubVV(this.m_localAnchorD, this.m_lcD, this.m_lalcD); + const rD = b2Rot.MulRV(qD, this.m_lalcD, b2GearJoint.InitVelocityConstraints_s_rD); + // b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_lcB); + b2Vec2.SubVV(this.m_localAnchorB, this.m_lcB, this.m_lalcB); + const rB = b2Rot.MulRV(qB, this.m_lalcB, b2GearJoint.InitVelocityConstraints_s_rB); + // m_JvBD = m_ratio * u; + b2Vec2.MulSV(this.m_ratio, u, this.m_JvBD); + // m_JwD = m_ratio * b2Cross(rD, u); + this.m_JwD = this.m_ratio * b2Vec2.CrossVV(rD, u); + // m_JwB = m_ratio * b2Cross(rB, u); + this.m_JwB = this.m_ratio * b2Vec2.CrossVV(rB, u); + this.m_mass += this.m_ratio * this.m_ratio * (this.m_mD + this.m_mB) + this.m_iD * this.m_JwD * this.m_JwD + this.m_iB * this.m_JwB * this.m_JwB; + } + // Compute effective mass. + this.m_mass = this.m_mass > 0 ? 1 / this.m_mass : 0; + if (data.step.warmStarting) { + // vA += (m_mA * m_impulse) * m_JvAC; + vA.SelfMulAdd(this.m_mA * this.m_impulse, this.m_JvAC); + wA += this.m_iA * this.m_impulse * this.m_JwA; + // vB += (m_mB * m_impulse) * m_JvBD; + vB.SelfMulAdd(this.m_mB * this.m_impulse, this.m_JvBD); + wB += this.m_iB * this.m_impulse * this.m_JwB; + // vC -= (m_mC * m_impulse) * m_JvAC; + vC.SelfMulSub(this.m_mC * this.m_impulse, this.m_JvAC); + wC -= this.m_iC * this.m_impulse * this.m_JwC; + // vD -= (m_mD * m_impulse) * m_JvBD; + vD.SelfMulSub(this.m_mD * this.m_impulse, this.m_JvBD); + wD -= this.m_iD * this.m_impulse * this.m_JwD; + } + else { + this.m_impulse = 0; + } + // data.velocities[this.m_indexA].v = vA; + data.velocities[this.m_indexA].w = wA; + // data.velocities[this.m_indexB].v = vB; + data.velocities[this.m_indexB].w = wB; + // data.velocities[this.m_indexC].v = vC; + data.velocities[this.m_indexC].w = wC; + // data.velocities[this.m_indexD].v = vD; + data.velocities[this.m_indexD].w = wD; + } + SolveVelocityConstraints(data) { + const vA = data.velocities[this.m_indexA].v; + let wA = data.velocities[this.m_indexA].w; + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + const vC = data.velocities[this.m_indexC].v; + let wC = data.velocities[this.m_indexC].w; + const vD = data.velocities[this.m_indexD].v; + let wD = data.velocities[this.m_indexD].w; + // float32 Cdot = b2Dot(m_JvAC, vA - vC) + b2Dot(m_JvBD, vB - vD); + let Cdot = b2Vec2.DotVV(this.m_JvAC, b2Vec2.SubVV(vA, vC, b2Vec2.s_t0)) + + b2Vec2.DotVV(this.m_JvBD, b2Vec2.SubVV(vB, vD, b2Vec2.s_t0)); + Cdot += (this.m_JwA * wA - this.m_JwC * wC) + (this.m_JwB * wB - this.m_JwD * wD); + const impulse = -this.m_mass * Cdot; + this.m_impulse += impulse; + // vA += (m_mA * impulse) * m_JvAC; + vA.SelfMulAdd((this.m_mA * impulse), this.m_JvAC); + wA += this.m_iA * impulse * this.m_JwA; + // vB += (m_mB * impulse) * m_JvBD; + vB.SelfMulAdd((this.m_mB * impulse), this.m_JvBD); + wB += this.m_iB * impulse * this.m_JwB; + // vC -= (m_mC * impulse) * m_JvAC; + vC.SelfMulSub((this.m_mC * impulse), this.m_JvAC); + wC -= this.m_iC * impulse * this.m_JwC; + // vD -= (m_mD * impulse) * m_JvBD; + vD.SelfMulSub((this.m_mD * impulse), this.m_JvBD); + wD -= this.m_iD * impulse * this.m_JwD; + // data.velocities[this.m_indexA].v = vA; + data.velocities[this.m_indexA].w = wA; + // data.velocities[this.m_indexB].v = vB; + data.velocities[this.m_indexB].w = wB; + // data.velocities[this.m_indexC].v = vC; + data.velocities[this.m_indexC].w = wC; + // data.velocities[this.m_indexD].v = vD; + data.velocities[this.m_indexD].w = wD; + } + SolvePositionConstraints(data) { + const cA = data.positions[this.m_indexA].c; + let aA = data.positions[this.m_indexA].a; + const cB = data.positions[this.m_indexB].c; + let aB = data.positions[this.m_indexB].a; + const cC = data.positions[this.m_indexC].c; + let aC = data.positions[this.m_indexC].a; + const cD = data.positions[this.m_indexD].c; + let aD = data.positions[this.m_indexD].a; + // b2Rot qA(aA), qB(aB), qC(aC), qD(aD); + const qA = this.m_qA.SetAngle(aA), qB = this.m_qB.SetAngle(aB), qC = this.m_qC.SetAngle(aC), qD = this.m_qD.SetAngle(aD); + const linearError = 0; + let coordinateA, coordinateB; + const JvAC = this.m_JvAC, JvBD = this.m_JvBD; + let JwA, JwB, JwC, JwD; + let mass = 0; + if (this.m_typeA === exports.b2JointType.e_revoluteJoint) { + JvAC.SetZero(); + JwA = 1; + JwC = 1; + mass += this.m_iA + this.m_iC; + coordinateA = aA - aC - this.m_referenceAngleA; + } + else { + // b2Vec2 u = b2Mul(qC, m_localAxisC); + const u = b2Rot.MulRV(qC, this.m_localAxisC, b2GearJoint.SolvePositionConstraints_s_u); + // b2Vec2 rC = b2Mul(qC, m_localAnchorC - m_lcC); + const rC = b2Rot.MulRV(qC, this.m_lalcC, b2GearJoint.SolvePositionConstraints_s_rC); + // b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_lcA); + const rA = b2Rot.MulRV(qA, this.m_lalcA, b2GearJoint.SolvePositionConstraints_s_rA); + // JvAC = u; + JvAC.Copy(u); + // JwC = b2Cross(rC, u); + JwC = b2Vec2.CrossVV(rC, u); + // JwA = b2Cross(rA, u); + JwA = b2Vec2.CrossVV(rA, u); + mass += this.m_mC + this.m_mA + this.m_iC * JwC * JwC + this.m_iA * JwA * JwA; + // b2Vec2 pC = m_localAnchorC - m_lcC; + const pC = this.m_lalcC; + // b2Vec2 pA = b2MulT(qC, rA + (cA - cC)); + const pA = b2Rot.MulTRV(qC, b2Vec2.AddVV(rA, b2Vec2.SubVV(cA, cC, b2Vec2.s_t0), b2Vec2.s_t0), b2Vec2.s_t0); // pA uses s_t0 + // coordinateA = b2Dot(pA - pC, m_localAxisC); + coordinateA = b2Vec2.DotVV(b2Vec2.SubVV(pA, pC, b2Vec2.s_t0), this.m_localAxisC); + } + if (this.m_typeB === exports.b2JointType.e_revoluteJoint) { + JvBD.SetZero(); + JwB = this.m_ratio; + JwD = this.m_ratio; + mass += this.m_ratio * this.m_ratio * (this.m_iB + this.m_iD); + coordinateB = aB - aD - this.m_referenceAngleB; + } + else { + // b2Vec2 u = b2Mul(qD, m_localAxisD); + const u = b2Rot.MulRV(qD, this.m_localAxisD, b2GearJoint.SolvePositionConstraints_s_u); + // b2Vec2 rD = b2Mul(qD, m_localAnchorD - m_lcD); + const rD = b2Rot.MulRV(qD, this.m_lalcD, b2GearJoint.SolvePositionConstraints_s_rD); + // b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_lcB); + const rB = b2Rot.MulRV(qB, this.m_lalcB, b2GearJoint.SolvePositionConstraints_s_rB); + // JvBD = m_ratio * u; + b2Vec2.MulSV(this.m_ratio, u, JvBD); + // JwD = m_ratio * b2Cross(rD, u); + JwD = this.m_ratio * b2Vec2.CrossVV(rD, u); + // JwB = m_ratio * b2Cross(rB, u); + JwB = this.m_ratio * b2Vec2.CrossVV(rB, u); + mass += this.m_ratio * this.m_ratio * (this.m_mD + this.m_mB) + this.m_iD * JwD * JwD + this.m_iB * JwB * JwB; + // b2Vec2 pD = m_localAnchorD - m_lcD; + const pD = this.m_lalcD; + // b2Vec2 pB = b2MulT(qD, rB + (cB - cD)); + const pB = b2Rot.MulTRV(qD, b2Vec2.AddVV(rB, b2Vec2.SubVV(cB, cD, b2Vec2.s_t0), b2Vec2.s_t0), b2Vec2.s_t0); // pB uses s_t0 + // coordinateB = b2Dot(pB - pD, m_localAxisD); + coordinateB = b2Vec2.DotVV(b2Vec2.SubVV(pB, pD, b2Vec2.s_t0), this.m_localAxisD); + } + const C = (coordinateA + this.m_ratio * coordinateB) - this.m_constant; + let impulse = 0; + if (mass > 0) { + impulse = -C / mass; + } + // cA += m_mA * impulse * JvAC; + cA.SelfMulAdd(this.m_mA * impulse, JvAC); + aA += this.m_iA * impulse * JwA; + // cB += m_mB * impulse * JvBD; + cB.SelfMulAdd(this.m_mB * impulse, JvBD); + aB += this.m_iB * impulse * JwB; + // cC -= m_mC * impulse * JvAC; + cC.SelfMulSub(this.m_mC * impulse, JvAC); + aC -= this.m_iC * impulse * JwC; + // cD -= m_mD * impulse * JvBD; + cD.SelfMulSub(this.m_mD * impulse, JvBD); + aD -= this.m_iD * impulse * JwD; + // data.positions[this.m_indexA].c = cA; + data.positions[this.m_indexA].a = aA; + // data.positions[this.m_indexB].c = cB; + data.positions[this.m_indexB].a = aB; + // data.positions[this.m_indexC].c = cC; + data.positions[this.m_indexC].a = aC; + // data.positions[this.m_indexD].c = cD; + data.positions[this.m_indexD].a = aD; + // TODO_ERIN not implemented + return linearError < b2_linearSlop; + } + GetAnchorA(out) { + return this.m_bodyA.GetWorldPoint(this.m_localAnchorA, out); + } + GetAnchorB(out) { + return this.m_bodyB.GetWorldPoint(this.m_localAnchorB, out); + } + GetReactionForce(inv_dt, out) { + // b2Vec2 P = m_impulse * m_JvAC; + // return inv_dt * P; + return b2Vec2.MulSV(inv_dt * this.m_impulse, this.m_JvAC, out); + } + GetReactionTorque(inv_dt) { + // float32 L = m_impulse * m_JwA; + // return inv_dt * L; + return inv_dt * this.m_impulse * this.m_JwA; + } + GetJoint1() { return this.m_joint1; } + GetJoint2() { return this.m_joint2; } + GetRatio() { + return this.m_ratio; + } + SetRatio(ratio) { + // DEBUG: b2Assert(b2IsValid(ratio)); + this.m_ratio = ratio; + } + Dump(log) { + const indexA = this.m_bodyA.m_islandIndex; + const indexB = this.m_bodyB.m_islandIndex; + const index1 = this.m_joint1.m_index; + const index2 = this.m_joint2.m_index; + log(" const jd: b2GearJointDef = new b2GearJointDef();\n"); + log(" jd.bodyA = bodies[%d];\n", indexA); + log(" jd.bodyB = bodies[%d];\n", indexB); + log(" jd.collideConnected = %s;\n", (this.m_collideConnected) ? ("true") : ("false")); + log(" jd.joint1 = joints[%d];\n", index1); + log(" jd.joint2 = joints[%d];\n", index2); + log(" jd.ratio = %.15f;\n", this.m_ratio); + log(" joints[%d] = this.m_world.CreateJoint(jd);\n", this.m_index); + } + } + b2GearJoint.InitVelocityConstraints_s_u = new b2Vec2(); + b2GearJoint.InitVelocityConstraints_s_rA = new b2Vec2(); + b2GearJoint.InitVelocityConstraints_s_rB = new b2Vec2(); + b2GearJoint.InitVelocityConstraints_s_rC = new b2Vec2(); + b2GearJoint.InitVelocityConstraints_s_rD = new b2Vec2(); + b2GearJoint.SolvePositionConstraints_s_u = new b2Vec2(); + b2GearJoint.SolvePositionConstraints_s_rA = new b2Vec2(); + b2GearJoint.SolvePositionConstraints_s_rB = new b2Vec2(); + b2GearJoint.SolvePositionConstraints_s_rC = new b2Vec2(); + b2GearJoint.SolvePositionConstraints_s_rD = new b2Vec2(); + + /* + * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /* + Position Correction Notes + ========================= + I tried the several algorithms for position correction of the 2D revolute joint. + I looked at these systems: + - simple pendulum (1m diameter sphere on massless 5m stick) with initial angular velocity of 100 rad/s. + - suspension bridge with 30 1m long planks of length 1m. + - multi-link chain with 30 1m long links. + + Here are the algorithms: + + Baumgarte - A fraction of the position error is added to the velocity error. There is no + separate position solver. + + Pseudo Velocities - After the velocity solver and position integration, + the position error, Jacobian, and effective mass are recomputed. Then + the velocity constraints are solved with pseudo velocities and a fraction + of the position error is added to the pseudo velocity error. The pseudo + velocities are initialized to zero and there is no warm-starting. After + the position solver, the pseudo velocities are added to the positions. + This is also called the First Order World method or the Position LCP method. + + Modified Nonlinear Gauss-Seidel (NGS) - Like Pseudo Velocities except the + position error is re-computed for each constraint and the positions are updated + after the constraint is solved. The radius vectors (aka Jacobians) are + re-computed too (otherwise the algorithm has horrible instability). The pseudo + velocity states are not needed because they are effectively zero at the beginning + of each iteration. Since we have the current position error, we allow the + iterations to terminate early if the error becomes smaller than b2_linearSlop. + + Full NGS or just NGS - Like Modified NGS except the effective mass are re-computed + each time a constraint is solved. + + Here are the results: + Baumgarte - this is the cheapest algorithm but it has some stability problems, + especially with the bridge. The chain links separate easily close to the root + and they jitter as they struggle to pull together. This is one of the most common + methods in the field. The big drawback is that the position correction artificially + affects the momentum, thus leading to instabilities and false bounce. I used a + bias factor of 0.2. A larger bias factor makes the bridge less stable, a smaller + factor makes joints and contacts more spongy. + + Pseudo Velocities - the is more stable than the Baumgarte method. The bridge is + stable. However, joints still separate with large angular velocities. Drag the + simple pendulum in a circle quickly and the joint will separate. The chain separates + easily and does not recover. I used a bias factor of 0.2. A larger value lead to + the bridge collapsing when a heavy cube drops on it. + + Modified NGS - this algorithm is better in some ways than Baumgarte and Pseudo + Velocities, but in other ways it is worse. The bridge and chain are much more + stable, but the simple pendulum goes unstable at high angular velocities. + + Full NGS - stable in all tests. The joints display good stiffness. The bridge + still sags, but this is better than infinite forces. + + Recommendations + Pseudo Velocities are not really worthwhile because the bridge and chain cannot + recover from joint separation. In other cases the benefit over Baumgarte is small. + + Modified NGS is not a robust method for the revolute joint due to the violent + instability seen in the simple pendulum. Perhaps it is viable with other constraint + types, especially scalar constraints where the effective mass is a scalar. + + This leaves Baumgarte and Full NGS. Baumgarte has small, but manageable instabilities + and is very fast. I don't think we can escape Baumgarte, especially in highly + demanding cases where high constraint fidelity is not needed. + + Full NGS is robust and easy on the eyes. I recommend this as an option for + higher fidelity simulation and certainly for suspension bridges and long chains. + Full NGS might be a good choice for ragdolls, especially motorized ragdolls where + joint separation can be problematic. The number of NGS iterations can be reduced + for better performance without harming robustness much. + + Each joint in a can be handled differently in the position solver. So I recommend + a system where the user can select the algorithm on a per joint basis. I would + probably default to the slower Full NGS and let the user select the faster + Baumgarte method in performance critical scenarios. + */ + /* + Cache Performance + + The Box2D solvers are dominated by cache misses. Data structures are designed + to increase the number of cache hits. Much of misses are due to random access + to body data. The constraint structures are iterated over linearly, which leads + to few cache misses. + + The bodies are not accessed during iteration. Instead read only data, such as + the mass values are stored with the constraints. The mutable data are the constraint + impulses and the bodies velocities/positions. The impulses are held inside the + constraint structures. The body velocities/positions are held in compact, temporary + arrays to increase the number of cache hits. Linear and angular velocity are + stored in a single array since multiple arrays lead to multiple misses. + */ + /* + 2D Rotation + + R = [cos(theta) -sin(theta)] + [sin(theta) cos(theta) ] + + thetaDot = omega + + Let q1 = cos(theta), q2 = sin(theta). + R = [q1 -q2] + [q2 q1] + + q1Dot = -thetaDot * q2 + q2Dot = thetaDot * q1 + + q1_new = q1_old - dt * w * q2 + q2_new = q2_old + dt * w * q1 + then normalize. + + This might be faster than computing sin+cos. + However, we can compute sin+cos of the same angle fast. + */ + class b2Island { + constructor() { + this.m_bodies = [ /*1024*/]; // TODO: b2Settings + this.m_contacts = [ /*1024*/]; // TODO: b2Settings + this.m_joints = [ /*1024*/]; // TODO: b2Settings + this.m_positions = b2Position.MakeArray(1024); // TODO: b2Settings + this.m_velocities = b2Velocity.MakeArray(1024); // TODO: b2Settings + this.m_bodyCount = 0; + this.m_jointCount = 0; + this.m_contactCount = 0; + this.m_bodyCapacity = 0; + this.m_contactCapacity = 0; + this.m_jointCapacity = 0; + } + Initialize(bodyCapacity, contactCapacity, jointCapacity, listener) { + this.m_bodyCapacity = bodyCapacity; + this.m_contactCapacity = contactCapacity; + this.m_jointCapacity = jointCapacity; + this.m_bodyCount = 0; + this.m_contactCount = 0; + this.m_jointCount = 0; + this.m_listener = listener; + // TODO: + // while (this.m_bodies.length < bodyCapacity) { + // this.m_bodies[this.m_bodies.length] = null; + // } + // TODO: + // while (this.m_contacts.length < contactCapacity) { + // this.m_contacts[this.m_contacts.length] = null; + // } + // TODO: + // while (this.m_joints.length < jointCapacity) { + // this.m_joints[this.m_joints.length] = null; + // } + // TODO: + if (this.m_positions.length < bodyCapacity) { + const new_length = b2Max(this.m_positions.length * 2, bodyCapacity); + while (this.m_positions.length < new_length) { + this.m_positions[this.m_positions.length] = new b2Position(); + } + } + // TODO: + if (this.m_velocities.length < bodyCapacity) { + const new_length = b2Max(this.m_velocities.length * 2, bodyCapacity); + while (this.m_velocities.length < new_length) { + this.m_velocities[this.m_velocities.length] = new b2Velocity(); + } + } + } + Clear() { + this.m_bodyCount = 0; + this.m_contactCount = 0; + this.m_jointCount = 0; + } + AddBody(body) { + // DEBUG: b2Assert(this.m_bodyCount < this.m_bodyCapacity); + body.m_islandIndex = this.m_bodyCount; + this.m_bodies[this.m_bodyCount++] = body; + } + AddContact(contact) { + // DEBUG: b2Assert(this.m_contactCount < this.m_contactCapacity); + this.m_contacts[this.m_contactCount++] = contact; + } + AddJoint(joint) { + // DEBUG: b2Assert(this.m_jointCount < this.m_jointCapacity); + this.m_joints[this.m_jointCount++] = joint; + } + Solve(profile, step, gravity, allowSleep) { + const timer = b2Island.s_timer.Reset(); + const h = step.dt; + // Integrate velocities and apply damping. Initialize the body state. + for (let i = 0; i < this.m_bodyCount; ++i) { + const b = this.m_bodies[i]; + // const c: b2Vec2 = + this.m_positions[i].c.Copy(b.m_sweep.c); + const a = b.m_sweep.a; + const v = this.m_velocities[i].v.Copy(b.m_linearVelocity); + let w = b.m_angularVelocity; + // Store positions for continuous collision. + b.m_sweep.c0.Copy(b.m_sweep.c); + b.m_sweep.a0 = b.m_sweep.a; + if (b.m_type === exports.b2BodyType.b2_dynamicBody) { + // Integrate velocities. + // v += h * b->m_invMass * (b->m_gravityScale * b->m_mass * gravity + b->m_force); + v.x += h * b.m_invMass * (b.m_gravityScale * b.m_mass * gravity.x + b.m_force.x); + v.y += h * b.m_invMass * (b.m_gravityScale * b.m_mass * gravity.y + b.m_force.y); + w += h * b.m_invI * b.m_torque; + // Apply damping. + // ODE: dv/dt + c * v = 0 + // Solution: v(t) = v0 * exp(-c * t) + // Time step: v(t + dt) = v0 * exp(-c * (t + dt)) = v0 * exp(-c * t) * exp(-c * dt) = v * exp(-c * dt) + // v2 = exp(-c * dt) * v1 + // Pade approximation: + // v2 = v1 * 1 / (1 + c * dt) + v.SelfMul(1.0 / (1.0 + h * b.m_linearDamping)); + w *= 1.0 / (1.0 + h * b.m_angularDamping); + } + // this.m_positions[i].c = c; + this.m_positions[i].a = a; + // this.m_velocities[i].v = v; + this.m_velocities[i].w = w; + } + timer.Reset(); + // Solver data + const solverData = b2Island.s_solverData; + solverData.step.Copy(step); + solverData.positions = this.m_positions; + solverData.velocities = this.m_velocities; + // Initialize velocity constraints. + const contactSolverDef = b2Island.s_contactSolverDef; + contactSolverDef.step.Copy(step); + contactSolverDef.contacts = this.m_contacts; + contactSolverDef.count = this.m_contactCount; + contactSolverDef.positions = this.m_positions; + contactSolverDef.velocities = this.m_velocities; + const contactSolver = b2Island.s_contactSolver.Initialize(contactSolverDef); + contactSolver.InitializeVelocityConstraints(); + if (step.warmStarting) { + contactSolver.WarmStart(); + } + for (let i = 0; i < this.m_jointCount; ++i) { + this.m_joints[i].InitVelocityConstraints(solverData); + } + profile.solveInit = timer.GetMilliseconds(); + // Solve velocity constraints. + timer.Reset(); + for (let i = 0; i < step.velocityIterations; ++i) { + for (let j = 0; j < this.m_jointCount; ++j) { + this.m_joints[j].SolveVelocityConstraints(solverData); + } + contactSolver.SolveVelocityConstraints(); + } + // Store impulses for warm starting + contactSolver.StoreImpulses(); + profile.solveVelocity = timer.GetMilliseconds(); + // Integrate positions. + for (let i = 0; i < this.m_bodyCount; ++i) { + const c = this.m_positions[i].c; + let a = this.m_positions[i].a; + const v = this.m_velocities[i].v; + let w = this.m_velocities[i].w; + // Check for large velocities + const translation = b2Vec2.MulSV(h, v, b2Island.s_translation); + if (b2Vec2.DotVV(translation, translation) > b2_maxTranslationSquared) { + const ratio = b2_maxTranslation / translation.Length(); + v.SelfMul(ratio); + } + const rotation = h * w; + if (rotation * rotation > b2_maxRotationSquared) { + const ratio = b2_maxRotation / b2Abs(rotation); + w *= ratio; + } + // Integrate + c.x += h * v.x; + c.y += h * v.y; + a += h * w; + // this.m_positions[i].c = c; + this.m_positions[i].a = a; + // this.m_velocities[i].v = v; + this.m_velocities[i].w = w; + } + // Solve position constraints + timer.Reset(); + let positionSolved = false; + for (let i = 0; i < step.positionIterations; ++i) { + const contactsOkay = contactSolver.SolvePositionConstraints(); + let jointsOkay = true; + for (let j = 0; j < this.m_jointCount; ++j) { + const jointOkay = this.m_joints[j].SolvePositionConstraints(solverData); + jointsOkay = jointsOkay && jointOkay; + } + if (contactsOkay && jointsOkay) { + // Exit early if the position errors are small. + positionSolved = true; + break; + } + } + // Copy state buffers back to the bodies + for (let i = 0; i < this.m_bodyCount; ++i) { + const body = this.m_bodies[i]; + body.m_sweep.c.Copy(this.m_positions[i].c); + body.m_sweep.a = this.m_positions[i].a; + body.m_linearVelocity.Copy(this.m_velocities[i].v); + body.m_angularVelocity = this.m_velocities[i].w; + body.SynchronizeTransform(); + } + profile.solvePosition = timer.GetMilliseconds(); + this.Report(contactSolver.m_velocityConstraints); + if (allowSleep) { + let minSleepTime = b2_maxFloat; + const linTolSqr = b2_linearSleepTolerance * b2_linearSleepTolerance; + const angTolSqr = b2_angularSleepTolerance * b2_angularSleepTolerance; + for (let i = 0; i < this.m_bodyCount; ++i) { + const b = this.m_bodies[i]; + if (b.GetType() === exports.b2BodyType.b2_staticBody) { + continue; + } + if (!b.m_autoSleepFlag || + b.m_angularVelocity * b.m_angularVelocity > angTolSqr || + b2Vec2.DotVV(b.m_linearVelocity, b.m_linearVelocity) > linTolSqr) { + b.m_sleepTime = 0; + minSleepTime = 0; + } + else { + b.m_sleepTime += h; + minSleepTime = b2Min(minSleepTime, b.m_sleepTime); + } + } + if (minSleepTime >= b2_timeToSleep && positionSolved) { + for (let i = 0; i < this.m_bodyCount; ++i) { + const b = this.m_bodies[i]; + b.SetAwake(false); + } + } + } + } + SolveTOI(subStep, toiIndexA, toiIndexB) { + // DEBUG: b2Assert(toiIndexA < this.m_bodyCount); + // DEBUG: b2Assert(toiIndexB < this.m_bodyCount); + // Initialize the body state. + for (let i = 0; i < this.m_bodyCount; ++i) { + const b = this.m_bodies[i]; + this.m_positions[i].c.Copy(b.m_sweep.c); + this.m_positions[i].a = b.m_sweep.a; + this.m_velocities[i].v.Copy(b.m_linearVelocity); + this.m_velocities[i].w = b.m_angularVelocity; + } + const contactSolverDef = b2Island.s_contactSolverDef; + contactSolverDef.contacts = this.m_contacts; + contactSolverDef.count = this.m_contactCount; + contactSolverDef.step.Copy(subStep); + contactSolverDef.positions = this.m_positions; + contactSolverDef.velocities = this.m_velocities; + const contactSolver = b2Island.s_contactSolver.Initialize(contactSolverDef); + // Solve position constraints. + for (let i = 0; i < subStep.positionIterations; ++i) { + const contactsOkay = contactSolver.SolveTOIPositionConstraints(toiIndexA, toiIndexB); + if (contactsOkay) { + break; + } + } + /* + #if 0 + // Is the new position really safe? + for (int32 i = 0; i < this.m_contactCount; ++i) { + b2Contact* c = this.m_contacts[i]; + b2Fixture* fA = c.GetFixtureA(); + b2Fixture* fB = c.GetFixtureB(); + + b2Body* bA = fA.GetBody(); + b2Body* bB = fB.GetBody(); + + int32 indexA = c.GetChildIndexA(); + int32 indexB = c.GetChildIndexB(); + + b2DistanceInput input; + input.proxyA.Set(fA.GetShape(), indexA); + input.proxyB.Set(fB.GetShape(), indexB); + input.transformA = bA.GetTransform(); + input.transformB = bB.GetTransform(); + input.useRadii = false; + + b2DistanceOutput output; + b2SimplexCache cache; + cache.count = 0; + b2Distance(&output, &cache, &input); + + if (output.distance === 0 || cache.count === 3) { + cache.count += 0; + } + } + #endif + */ + // Leap of faith to new safe state. + this.m_bodies[toiIndexA].m_sweep.c0.Copy(this.m_positions[toiIndexA].c); + this.m_bodies[toiIndexA].m_sweep.a0 = this.m_positions[toiIndexA].a; + this.m_bodies[toiIndexB].m_sweep.c0.Copy(this.m_positions[toiIndexB].c); + this.m_bodies[toiIndexB].m_sweep.a0 = this.m_positions[toiIndexB].a; + // No warm starting is needed for TOI events because warm + // starting impulses were applied in the discrete solver. + contactSolver.InitializeVelocityConstraints(); + // Solve velocity constraints. + for (let i = 0; i < subStep.velocityIterations; ++i) { + contactSolver.SolveVelocityConstraints(); + } + // Don't store the TOI contact forces for warm starting + // because they can be quite large. + const h = subStep.dt; + // Integrate positions + for (let i = 0; i < this.m_bodyCount; ++i) { + const c = this.m_positions[i].c; + let a = this.m_positions[i].a; + const v = this.m_velocities[i].v; + let w = this.m_velocities[i].w; + // Check for large velocities + const translation = b2Vec2.MulSV(h, v, b2Island.s_translation); + if (b2Vec2.DotVV(translation, translation) > b2_maxTranslationSquared) { + const ratio = b2_maxTranslation / translation.Length(); + v.SelfMul(ratio); + } + const rotation = h * w; + if (rotation * rotation > b2_maxRotationSquared) { + const ratio = b2_maxRotation / b2Abs(rotation); + w *= ratio; + } + // Integrate + c.SelfMulAdd(h, v); + a += h * w; + // this.m_positions[i].c = c; + this.m_positions[i].a = a; + // this.m_velocities[i].v = v; + this.m_velocities[i].w = w; + // Sync bodies + const body = this.m_bodies[i]; + body.m_sweep.c.Copy(c); + body.m_sweep.a = a; + body.m_linearVelocity.Copy(v); + body.m_angularVelocity = w; + body.SynchronizeTransform(); + } + this.Report(contactSolver.m_velocityConstraints); + } + Report(constraints) { + if (this.m_listener === null) { + return; + } + for (let i = 0; i < this.m_contactCount; ++i) { + const c = this.m_contacts[i]; + if (!c) { + continue; + } + const vc = constraints[i]; + const impulse = b2Island.s_impulse; + impulse.count = vc.pointCount; + for (let j = 0; j < vc.pointCount; ++j) { + impulse.normalImpulses[j] = vc.points[j].normalImpulse; + impulse.tangentImpulses[j] = vc.points[j].tangentImpulse; + } + this.m_listener.PostSolve(c, impulse); + } + } + } + b2Island.s_timer = new b2Timer(); + b2Island.s_solverData = new b2SolverData(); + b2Island.s_contactSolverDef = new b2ContactSolverDef(); + b2Island.s_contactSolver = new b2ContactSolver(); + b2Island.s_translation = new b2Vec2(); + b2Island.s_impulse = new b2ContactImpulse(); + + /* + * Copyright (c) 2006-2012 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + class b2MotorJointDef extends b2JointDef { + constructor() { + super(exports.b2JointType.e_motorJoint); + this.linearOffset = new b2Vec2(0, 0); + this.angularOffset = 0; + this.maxForce = 1; + this.maxTorque = 1; + this.correctionFactor = 0.3; + } + Initialize(bA, bB) { + this.bodyA = bA; + this.bodyB = bB; + // b2Vec2 xB = bodyB->GetPosition(); + // linearOffset = bodyA->GetLocalPoint(xB); + this.bodyA.GetLocalPoint(this.bodyB.GetPosition(), this.linearOffset); + const angleA = this.bodyA.GetAngle(); + const angleB = this.bodyB.GetAngle(); + this.angularOffset = angleB - angleA; + } + } + class b2MotorJoint extends b2Joint { + constructor(def) { + super(def); + // Solver shared + this.m_linearOffset = new b2Vec2(); + this.m_angularOffset = 0; + this.m_linearImpulse = new b2Vec2(); + this.m_angularImpulse = 0; + this.m_maxForce = 0; + this.m_maxTorque = 0; + this.m_correctionFactor = 0.3; + // Solver temp + this.m_indexA = 0; + this.m_indexB = 0; + this.m_rA = new b2Vec2(); + this.m_rB = new b2Vec2(); + this.m_localCenterA = new b2Vec2(); + this.m_localCenterB = new b2Vec2(); + this.m_linearError = new b2Vec2(); + this.m_angularError = 0; + this.m_invMassA = 0; + this.m_invMassB = 0; + this.m_invIA = 0; + this.m_invIB = 0; + this.m_linearMass = new b2Mat22(); + this.m_angularMass = 0; + this.m_qA = new b2Rot(); + this.m_qB = new b2Rot(); + this.m_K = new b2Mat22(); + this.m_linearOffset.Copy(b2Maybe(def.linearOffset, b2Vec2.ZERO)); + this.m_angularOffset = b2Maybe(def.angularOffset, 0); + this.m_linearImpulse.SetZero(); + this.m_maxForce = b2Maybe(def.maxForce, 0); + this.m_maxTorque = b2Maybe(def.maxTorque, 0); + this.m_correctionFactor = b2Maybe(def.correctionFactor, 0.3); + } + GetAnchorA(out) { + const pos = this.m_bodyA.GetPosition(); + out.x = pos.x; + out.y = pos.y; + return out; + } + GetAnchorB(out) { + const pos = this.m_bodyB.GetPosition(); + out.x = pos.x; + out.y = pos.y; + return out; + } + GetReactionForce(inv_dt, out) { + // return inv_dt * m_linearImpulse; + return b2Vec2.MulSV(inv_dt, this.m_linearImpulse, out); + } + GetReactionTorque(inv_dt) { + return inv_dt * this.m_angularImpulse; + } + SetLinearOffset(linearOffset) { + if (!b2Vec2.IsEqualToV(linearOffset, this.m_linearOffset)) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_linearOffset.Copy(linearOffset); + } + } + GetLinearOffset() { + return this.m_linearOffset; + } + SetAngularOffset(angularOffset) { + if (angularOffset !== this.m_angularOffset) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_angularOffset = angularOffset; + } + } + GetAngularOffset() { + return this.m_angularOffset; + } + SetMaxForce(force) { + // DEBUG: b2Assert(b2IsValid(force) && force >= 0); + this.m_maxForce = force; + } + GetMaxForce() { + return this.m_maxForce; + } + SetMaxTorque(torque) { + // DEBUG: b2Assert(b2IsValid(torque) && torque >= 0); + this.m_maxTorque = torque; + } + GetMaxTorque() { + return this.m_maxTorque; + } + InitVelocityConstraints(data) { + this.m_indexA = this.m_bodyA.m_islandIndex; + this.m_indexB = this.m_bodyB.m_islandIndex; + this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter); + this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter); + this.m_invMassA = this.m_bodyA.m_invMass; + this.m_invMassB = this.m_bodyB.m_invMass; + this.m_invIA = this.m_bodyA.m_invI; + this.m_invIB = this.m_bodyB.m_invI; + const cA = data.positions[this.m_indexA].c; + const aA = data.positions[this.m_indexA].a; + const vA = data.velocities[this.m_indexA].v; + let wA = data.velocities[this.m_indexA].w; + const cB = data.positions[this.m_indexB].c; + const aB = data.positions[this.m_indexB].a; + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + const qA = this.m_qA.SetAngle(aA), qB = this.m_qB.SetAngle(aB); + // Compute the effective mass matrix. + // this.m_rA = b2Mul(qA, m_linearOffset - this.m_localCenterA); + const rA = b2Rot.MulRV(qA, b2Vec2.SubVV(this.m_linearOffset, this.m_localCenterA, b2Vec2.s_t0), this.m_rA); + // this.m_rB = b2Mul(qB, -this.m_localCenterB); + const rB = b2Rot.MulRV(qB, b2Vec2.NegV(this.m_localCenterB, b2Vec2.s_t0), this.m_rB); + // J = [-I -r1_skew I r2_skew] + // r_skew = [-ry; rx] + // Matlab + // K = [ mA+r1y^2*iA+mB+r2y^2*iB, -r1y*iA*r1x-r2y*iB*r2x, -r1y*iA-r2y*iB] + // [ -r1y*iA*r1x-r2y*iB*r2x, mA+r1x^2*iA+mB+r2x^2*iB, r1x*iA+r2x*iB] + // [ -r1y*iA-r2y*iB, r1x*iA+r2x*iB, iA+iB] + const mA = this.m_invMassA, mB = this.m_invMassB; + const iA = this.m_invIA, iB = this.m_invIB; + // Upper 2 by 2 of K for point to point + const K = this.m_K; + K.ex.x = mA + mB + iA * rA.y * rA.y + iB * rB.y * rB.y; + K.ex.y = -iA * rA.x * rA.y - iB * rB.x * rB.y; + K.ey.x = K.ex.y; + K.ey.y = mA + mB + iA * rA.x * rA.x + iB * rB.x * rB.x; + // this.m_linearMass = K.GetInverse(); + K.GetInverse(this.m_linearMass); + this.m_angularMass = iA + iB; + if (this.m_angularMass > 0) { + this.m_angularMass = 1 / this.m_angularMass; + } + // this.m_linearError = cB + rB - cA - rA; + b2Vec2.SubVV(b2Vec2.AddVV(cB, rB, b2Vec2.s_t0), b2Vec2.AddVV(cA, rA, b2Vec2.s_t1), this.m_linearError); + this.m_angularError = aB - aA - this.m_angularOffset; + if (data.step.warmStarting) { + // Scale impulses to support a variable time step. + // this.m_linearImpulse *= data.step.dtRatio; + this.m_linearImpulse.SelfMul(data.step.dtRatio); + this.m_angularImpulse *= data.step.dtRatio; + // b2Vec2 P(this.m_linearImpulse.x, this.m_linearImpulse.y); + const P = this.m_linearImpulse; + // vA -= mA * P; + vA.SelfMulSub(mA, P); + wA -= iA * (b2Vec2.CrossVV(rA, P) + this.m_angularImpulse); + // vB += mB * P; + vB.SelfMulAdd(mB, P); + wB += iB * (b2Vec2.CrossVV(rB, P) + this.m_angularImpulse); + } + else { + this.m_linearImpulse.SetZero(); + this.m_angularImpulse = 0; + } + // data.velocities[this.m_indexA].v = vA; // vA is a reference + data.velocities[this.m_indexA].w = wA; + // data.velocities[this.m_indexB].v = vB; // vB is a reference + data.velocities[this.m_indexB].w = wB; + } + SolveVelocityConstraints(data) { + const vA = data.velocities[this.m_indexA].v; + let wA = data.velocities[this.m_indexA].w; + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + const mA = this.m_invMassA, mB = this.m_invMassB; + const iA = this.m_invIA, iB = this.m_invIB; + const h = data.step.dt; + const inv_h = data.step.inv_dt; + // Solve angular friction + { + const Cdot = wB - wA + inv_h * this.m_correctionFactor * this.m_angularError; + let impulse = -this.m_angularMass * Cdot; + const oldImpulse = this.m_angularImpulse; + const maxImpulse = h * this.m_maxTorque; + this.m_angularImpulse = b2Clamp(this.m_angularImpulse + impulse, -maxImpulse, maxImpulse); + impulse = this.m_angularImpulse - oldImpulse; + wA -= iA * impulse; + wB += iB * impulse; + } + // Solve linear friction + { + const rA = this.m_rA; + const rB = this.m_rB; + // b2Vec2 Cdot = vB + b2Vec2.CrossSV(wB, rB) - vA - b2Vec2.CrossSV(wA, rA) + inv_h * this.m_correctionFactor * this.m_linearError; + const Cdot_v2 = b2Vec2.AddVV(b2Vec2.SubVV(b2Vec2.AddVV(vB, b2Vec2.CrossSV(wB, rB, b2Vec2.s_t0), b2Vec2.s_t0), b2Vec2.AddVV(vA, b2Vec2.CrossSV(wA, rA, b2Vec2.s_t1), b2Vec2.s_t1), b2Vec2.s_t2), b2Vec2.MulSV(inv_h * this.m_correctionFactor, this.m_linearError, b2Vec2.s_t3), b2MotorJoint.SolveVelocityConstraints_s_Cdot_v2); + // b2Vec2 impulse = -b2Mul(this.m_linearMass, Cdot); + const impulse_v2 = b2Mat22.MulMV(this.m_linearMass, Cdot_v2, b2MotorJoint.SolveVelocityConstraints_s_impulse_v2).SelfNeg(); + // b2Vec2 oldImpulse = this.m_linearImpulse; + const oldImpulse_v2 = b2MotorJoint.SolveVelocityConstraints_s_oldImpulse_v2.Copy(this.m_linearImpulse); + // this.m_linearImpulse += impulse; + this.m_linearImpulse.SelfAdd(impulse_v2); + const maxImpulse = h * this.m_maxForce; + if (this.m_linearImpulse.LengthSquared() > maxImpulse * maxImpulse) { + this.m_linearImpulse.Normalize(); + // this.m_linearImpulse *= maxImpulse; + this.m_linearImpulse.SelfMul(maxImpulse); + } + // impulse = this.m_linearImpulse - oldImpulse; + b2Vec2.SubVV(this.m_linearImpulse, oldImpulse_v2, impulse_v2); + // vA -= mA * impulse; + vA.SelfMulSub(mA, impulse_v2); + // wA -= iA * b2Vec2.CrossVV(rA, impulse); + wA -= iA * b2Vec2.CrossVV(rA, impulse_v2); + // vB += mB * impulse; + vB.SelfMulAdd(mB, impulse_v2); + // wB += iB * b2Vec2.CrossVV(rB, impulse); + wB += iB * b2Vec2.CrossVV(rB, impulse_v2); + } + // data.velocities[this.m_indexA].v = vA; // vA is a reference + data.velocities[this.m_indexA].w = wA; + // data.velocities[this.m_indexB].v = vB; // vB is a reference + data.velocities[this.m_indexB].w = wB; + } + SolvePositionConstraints(data) { + return true; + } + Dump(log) { + const indexA = this.m_bodyA.m_islandIndex; + const indexB = this.m_bodyB.m_islandIndex; + log(" const jd: b2MotorJointDef = new b2MotorJointDef();\n"); + log(" jd.bodyA = bodies[%d];\n", indexA); + log(" jd.bodyB = bodies[%d];\n", indexB); + log(" jd.collideConnected = %s;\n", (this.m_collideConnected) ? ("true") : ("false")); + log(" jd.linearOffset.Set(%.15f, %.15f);\n", this.m_linearOffset.x, this.m_linearOffset.y); + log(" jd.angularOffset = %.15f;\n", this.m_angularOffset); + log(" jd.maxForce = %.15f;\n", this.m_maxForce); + log(" jd.maxTorque = %.15f;\n", this.m_maxTorque); + log(" jd.correctionFactor = %.15f;\n", this.m_correctionFactor); + log(" joints[%d] = this.m_world.CreateJoint(jd);\n", this.m_index); + } + } + b2MotorJoint.SolveVelocityConstraints_s_Cdot_v2 = new b2Vec2(); + b2MotorJoint.SolveVelocityConstraints_s_impulse_v2 = new b2Vec2(); + b2MotorJoint.SolveVelocityConstraints_s_oldImpulse_v2 = new b2Vec2(); + + /* + * Copyright (c) 2006-2007 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// Mouse joint definition. This requires a world target point, + /// tuning parameters, and the time step. + class b2MouseJointDef extends b2JointDef { + constructor() { + super(exports.b2JointType.e_mouseJoint); + this.target = new b2Vec2(); + this.maxForce = 0; + this.stiffness = 5; + this.damping = 0.7; + } + } + class b2MouseJoint extends b2Joint { + constructor(def) { + super(def); + this.m_localAnchorB = new b2Vec2(); + this.m_targetA = new b2Vec2(); + this.m_stiffness = 0; + this.m_damping = 0; + this.m_beta = 0; + // Solver shared + this.m_impulse = new b2Vec2(); + this.m_maxForce = 0; + this.m_gamma = 0; + // Solver temp + this.m_indexA = 0; + this.m_indexB = 0; + this.m_rB = new b2Vec2(); + this.m_localCenterB = new b2Vec2(); + this.m_invMassB = 0; + this.m_invIB = 0; + this.m_mass = new b2Mat22(); + this.m_C = new b2Vec2(); + this.m_qB = new b2Rot(); + this.m_lalcB = new b2Vec2(); + this.m_K = new b2Mat22(); + this.m_targetA.Copy(b2Maybe(def.target, b2Vec2.ZERO)); + // DEBUG: b2Assert(this.m_targetA.IsValid()); + b2Transform.MulTXV(this.m_bodyB.GetTransform(), this.m_targetA, this.m_localAnchorB); + this.m_maxForce = b2Maybe(def.maxForce, 0); + // DEBUG: b2Assert(b2IsValid(this.m_maxForce) && this.m_maxForce >= 0); + this.m_impulse.SetZero(); + this.m_stiffness = b2Maybe(def.stiffness, 0); + // DEBUG: b2Assert(b2IsValid(this.m_stiffness) && this.m_stiffness >= 0); + this.m_damping = b2Maybe(def.damping, 0); + // DEBUG: b2Assert(b2IsValid(this.m_damping) && this.m_damping >= 0); + this.m_beta = 0; + this.m_gamma = 0; + } + SetTarget(target) { + if (!this.m_bodyB.IsAwake()) { + this.m_bodyB.SetAwake(true); + } + this.m_targetA.Copy(target); + } + GetTarget() { + return this.m_targetA; + } + SetMaxForce(maxForce) { + this.m_maxForce = maxForce; + } + GetMaxForce() { + return this.m_maxForce; + } + SetStiffness(stiffness) { + this.m_stiffness = stiffness; + } + GetStiffness() { + return this.m_stiffness; + } + SetDamping(damping) { + this.m_damping = damping; + } + GetDamping() { + return this.m_damping; + } + InitVelocityConstraints(data) { + this.m_indexB = this.m_bodyB.m_islandIndex; + this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter); + this.m_invMassB = this.m_bodyB.m_invMass; + this.m_invIB = this.m_bodyB.m_invI; + const cB = data.positions[this.m_indexB].c; + const aB = data.positions[this.m_indexB].a; + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + const qB = this.m_qB.SetAngle(aB); + const mass = this.m_bodyB.GetMass(); + // Frequency + const omega = 2 * b2_pi * this.m_stiffness; + // Damping coefficient + const d = 2 * mass * this.m_damping * omega; + // Spring stiffness + const k = mass * (omega * omega); + // magic formulas + // gamma has units of inverse mass. + // beta has units of inverse time. + const h = data.step.dt; + this.m_gamma = h * (d + h * k); + if (this.m_gamma !== 0) { + this.m_gamma = 1 / this.m_gamma; + } + this.m_beta = h * k * this.m_gamma; + // Compute the effective mass matrix. + b2Vec2.SubVV(this.m_localAnchorB, this.m_localCenterB, this.m_lalcB); + b2Rot.MulRV(qB, this.m_lalcB, this.m_rB); + // K = [(1/m1 + 1/m2) * eye(2) - skew(r1) * invI1 * skew(r1) - skew(r2) * invI2 * skew(r2)] + // = [1/m1+1/m2 0 ] + invI1 * [r1.y*r1.y -r1.x*r1.y] + invI2 * [r1.y*r1.y -r1.x*r1.y] + // [ 0 1/m1+1/m2] [-r1.x*r1.y r1.x*r1.x] [-r1.x*r1.y r1.x*r1.x] + const K = this.m_K; + K.ex.x = this.m_invMassB + this.m_invIB * this.m_rB.y * this.m_rB.y + this.m_gamma; + K.ex.y = -this.m_invIB * this.m_rB.x * this.m_rB.y; + K.ey.x = K.ex.y; + K.ey.y = this.m_invMassB + this.m_invIB * this.m_rB.x * this.m_rB.x + this.m_gamma; + K.GetInverse(this.m_mass); + // m_C = cB + m_rB - m_targetA; + this.m_C.x = cB.x + this.m_rB.x - this.m_targetA.x; + this.m_C.y = cB.y + this.m_rB.y - this.m_targetA.y; + // m_C *= m_beta; + this.m_C.SelfMul(this.m_beta); + // Cheat with some damping + wB *= 0.98; + if (data.step.warmStarting) { + this.m_impulse.SelfMul(data.step.dtRatio); + // vB += m_invMassB * m_impulse; + vB.x += this.m_invMassB * this.m_impulse.x; + vB.y += this.m_invMassB * this.m_impulse.y; + wB += this.m_invIB * b2Vec2.CrossVV(this.m_rB, this.m_impulse); + } + else { + this.m_impulse.SetZero(); + } + // data.velocities[this.m_indexB].v = vB; + data.velocities[this.m_indexB].w = wB; + } + SolveVelocityConstraints(data) { + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + // Cdot = v + cross(w, r) + // b2Vec2 Cdot = vB + b2Cross(wB, m_rB); + const Cdot = b2Vec2.AddVCrossSV(vB, wB, this.m_rB, b2MouseJoint.SolveVelocityConstraints_s_Cdot); + // b2Vec2 impulse = b2Mul(m_mass, -(Cdot + m_C + m_gamma * m_impulse)); + const impulse = b2Mat22.MulMV(this.m_mass, b2Vec2.AddVV(Cdot, b2Vec2.AddVV(this.m_C, b2Vec2.MulSV(this.m_gamma, this.m_impulse, b2Vec2.s_t0), b2Vec2.s_t0), b2Vec2.s_t0).SelfNeg(), b2MouseJoint.SolveVelocityConstraints_s_impulse); + // b2Vec2 oldImpulse = m_impulse; + const oldImpulse = b2MouseJoint.SolveVelocityConstraints_s_oldImpulse.Copy(this.m_impulse); + // m_impulse += impulse; + this.m_impulse.SelfAdd(impulse); + const maxImpulse = data.step.dt * this.m_maxForce; + if (this.m_impulse.LengthSquared() > maxImpulse * maxImpulse) { + this.m_impulse.SelfMul(maxImpulse / this.m_impulse.Length()); + } + // impulse = m_impulse - oldImpulse; + b2Vec2.SubVV(this.m_impulse, oldImpulse, impulse); + // vB += m_invMassB * impulse; + vB.SelfMulAdd(this.m_invMassB, impulse); + wB += this.m_invIB * b2Vec2.CrossVV(this.m_rB, impulse); + // data.velocities[this.m_indexB].v = vB; + data.velocities[this.m_indexB].w = wB; + } + SolvePositionConstraints(data) { + return true; + } + GetAnchorA(out) { + out.x = this.m_targetA.x; + out.y = this.m_targetA.y; + return out; + } + GetAnchorB(out) { + return this.m_bodyB.GetWorldPoint(this.m_localAnchorB, out); + } + GetReactionForce(inv_dt, out) { + return b2Vec2.MulSV(inv_dt, this.m_impulse, out); + } + GetReactionTorque(inv_dt) { + return 0; + } + Dump(log) { + log("Mouse joint dumping is not supported.\n"); + } + ShiftOrigin(newOrigin) { + this.m_targetA.SelfSub(newOrigin); + } + } + b2MouseJoint.SolveVelocityConstraints_s_Cdot = new b2Vec2(); + b2MouseJoint.SolveVelocityConstraints_s_impulse = new b2Vec2(); + b2MouseJoint.SolveVelocityConstraints_s_oldImpulse = new b2Vec2(); + + /* + * Copyright (c) 2006-2011 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// Prismatic joint definition. This requires defining a line of + /// motion using an axis and an anchor point. The definition uses local + /// anchor points and a local axis so that the initial configuration + /// can violate the constraint slightly. The joint translation is zero + /// when the local anchor points coincide in world space. Using local + /// anchors and a local axis helps when saving and loading a game. + class b2PrismaticJointDef extends b2JointDef { + constructor() { + super(exports.b2JointType.e_prismaticJoint); + this.localAnchorA = new b2Vec2(); + this.localAnchorB = new b2Vec2(); + this.localAxisA = new b2Vec2(1, 0); + this.referenceAngle = 0; + this.enableLimit = false; + this.lowerTranslation = 0; + this.upperTranslation = 0; + this.enableMotor = false; + this.maxMotorForce = 0; + this.motorSpeed = 0; + } + Initialize(bA, bB, anchor, axis) { + this.bodyA = bA; + this.bodyB = bB; + this.bodyA.GetLocalPoint(anchor, this.localAnchorA); + this.bodyB.GetLocalPoint(anchor, this.localAnchorB); + this.bodyA.GetLocalVector(axis, this.localAxisA); + this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle(); + } + } + // Linear constraint (point-to-line) + // d = p2 - p1 = x2 + r2 - x1 - r1 + // C = dot(perp, d) + // Cdot = dot(d, cross(w1, perp)) + dot(perp, v2 + cross(w2, r2) - v1 - cross(w1, r1)) + // = -dot(perp, v1) - dot(cross(d + r1, perp), w1) + dot(perp, v2) + dot(cross(r2, perp), v2) + // J = [-perp, -cross(d + r1, perp), perp, cross(r2,perp)] + // + // Angular constraint + // C = a2 - a1 + a_initial + // Cdot = w2 - w1 + // J = [0 0 -1 0 0 1] + // + // K = J * invM * JT + // + // J = [-a -s1 a s2] + // [0 -1 0 1] + // a = perp + // s1 = cross(d + r1, a) = cross(p2 - x1, a) + // s2 = cross(r2, a) = cross(p2 - x2, a) + // Motor/Limit linear constraint + // C = dot(ax1, d) + // Cdot = -dot(ax1, v1) - dot(cross(d + r1, ax1), w1) + dot(ax1, v2) + dot(cross(r2, ax1), v2) + // J = [-ax1 -cross(d+r1,ax1) ax1 cross(r2,ax1)] + // Predictive limit is applied even when the limit is not active. + // Prevents a constraint speed that can lead to a constraint error in one time step. + // Want C2 = C1 + h * Cdot >= 0 + // Or: + // Cdot + C1/h >= 0 + // I do not apply a negative constraint error because that is handled in position correction. + // So: + // Cdot + max(C1, 0)/h >= 0 + // Block Solver + // We develop a block solver that includes the angular and linear constraints. This makes the limit stiffer. + // + // The Jacobian has 2 rows: + // J = [-uT -s1 uT s2] // linear + // [0 -1 0 1] // angular + // + // u = perp + // s1 = cross(d + r1, u), s2 = cross(r2, u) + // a1 = cross(d + r1, v), a2 = cross(r2, v) + class b2PrismaticJoint extends b2Joint { + constructor(def) { + super(def); + this.m_localAnchorA = new b2Vec2(); + this.m_localAnchorB = new b2Vec2(); + this.m_localXAxisA = new b2Vec2(); + this.m_localYAxisA = new b2Vec2(); + this.m_referenceAngle = 0; + this.m_impulse = new b2Vec2(0, 0); + this.m_motorImpulse = 0; + this.m_lowerImpulse = 0; + this.m_upperImpulse = 0; + this.m_lowerTranslation = 0; + this.m_upperTranslation = 0; + this.m_maxMotorForce = 0; + this.m_motorSpeed = 0; + this.m_enableLimit = false; + this.m_enableMotor = false; + // Solver temp + this.m_indexA = 0; + this.m_indexB = 0; + this.m_localCenterA = new b2Vec2(); + this.m_localCenterB = new b2Vec2(); + this.m_invMassA = 0; + this.m_invMassB = 0; + this.m_invIA = 0; + this.m_invIB = 0; + this.m_axis = new b2Vec2(0, 0); + this.m_perp = new b2Vec2(0, 0); + this.m_s1 = 0; + this.m_s2 = 0; + this.m_a1 = 0; + this.m_a2 = 0; + this.m_K = new b2Mat22(); + this.m_K3 = new b2Mat33(); + this.m_K2 = new b2Mat22(); + this.m_translation = 0; + this.m_axialMass = 0; + this.m_qA = new b2Rot(); + this.m_qB = new b2Rot(); + this.m_lalcA = new b2Vec2(); + this.m_lalcB = new b2Vec2(); + this.m_rA = new b2Vec2(); + this.m_rB = new b2Vec2(); + this.m_localAnchorA.Copy(b2Maybe(def.localAnchorA, b2Vec2.ZERO)); + this.m_localAnchorB.Copy(b2Maybe(def.localAnchorB, b2Vec2.ZERO)); + this.m_localXAxisA.Copy(b2Maybe(def.localAxisA, new b2Vec2(1, 0))).SelfNormalize(); + b2Vec2.CrossOneV(this.m_localXAxisA, this.m_localYAxisA); + this.m_referenceAngle = b2Maybe(def.referenceAngle, 0); + this.m_lowerTranslation = b2Maybe(def.lowerTranslation, 0); + this.m_upperTranslation = b2Maybe(def.upperTranslation, 0); + // b2Assert(this.m_lowerTranslation <= this.m_upperTranslation); + this.m_maxMotorForce = b2Maybe(def.maxMotorForce, 0); + this.m_motorSpeed = b2Maybe(def.motorSpeed, 0); + this.m_enableLimit = b2Maybe(def.enableLimit, false); + this.m_enableMotor = b2Maybe(def.enableMotor, false); + } + InitVelocityConstraints(data) { + this.m_indexA = this.m_bodyA.m_islandIndex; + this.m_indexB = this.m_bodyB.m_islandIndex; + this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter); + this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter); + this.m_invMassA = this.m_bodyA.m_invMass; + this.m_invMassB = this.m_bodyB.m_invMass; + this.m_invIA = this.m_bodyA.m_invI; + this.m_invIB = this.m_bodyB.m_invI; + const cA = data.positions[this.m_indexA].c; + const aA = data.positions[this.m_indexA].a; + const vA = data.velocities[this.m_indexA].v; + let wA = data.velocities[this.m_indexA].w; + const cB = data.positions[this.m_indexB].c; + const aB = data.positions[this.m_indexB].a; + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + const qA = this.m_qA.SetAngle(aA), qB = this.m_qB.SetAngle(aB); + // Compute the effective masses. + // b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); + b2Vec2.SubVV(this.m_localAnchorA, this.m_localCenterA, this.m_lalcA); + const rA = b2Rot.MulRV(qA, this.m_lalcA, this.m_rA); + // b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); + b2Vec2.SubVV(this.m_localAnchorB, this.m_localCenterB, this.m_lalcB); + const rB = b2Rot.MulRV(qB, this.m_lalcB, this.m_rB); + // b2Vec2 d = (cB - cA) + rB - rA; + const d = b2Vec2.AddVV(b2Vec2.SubVV(cB, cA, b2Vec2.s_t0), b2Vec2.SubVV(rB, rA, b2Vec2.s_t1), b2PrismaticJoint.InitVelocityConstraints_s_d); + const mA = this.m_invMassA, mB = this.m_invMassB; + const iA = this.m_invIA, iB = this.m_invIB; + // Compute motor Jacobian and effective mass. + { + // m_axis = b2Mul(qA, m_localXAxisA); + b2Rot.MulRV(qA, this.m_localXAxisA, this.m_axis); + // m_a1 = b2Cross(d + rA, m_axis); + this.m_a1 = b2Vec2.CrossVV(b2Vec2.AddVV(d, rA, b2Vec2.s_t0), this.m_axis); + // m_a2 = b2Cross(rB, m_axis); + this.m_a2 = b2Vec2.CrossVV(rB, this.m_axis); + this.m_axialMass = mA + mB + iA * this.m_a1 * this.m_a1 + iB * this.m_a2 * this.m_a2; + if (this.m_axialMass > 0) { + this.m_axialMass = 1 / this.m_axialMass; + } + } + // Prismatic constraint. + { + // m_perp = b2Mul(qA, m_localYAxisA); + b2Rot.MulRV(qA, this.m_localYAxisA, this.m_perp); + // m_s1 = b2Cross(d + rA, m_perp); + this.m_s1 = b2Vec2.CrossVV(b2Vec2.AddVV(d, rA, b2Vec2.s_t0), this.m_perp); + // m_s2 = b2Cross(rB, m_perp); + this.m_s2 = b2Vec2.CrossVV(rB, this.m_perp); + // float32 k11 = mA + mB + iA * m_s1 * m_s1 + iB * m_s2 * m_s2; + this.m_K.ex.x = mA + mB + iA * this.m_s1 * this.m_s1 + iB * this.m_s2 * this.m_s2; + // float32 k12 = iA * m_s1 + iB * m_s2; + this.m_K.ex.y = iA * this.m_s1 + iB * this.m_s2; + this.m_K.ey.x = this.m_K.ex.y; + // float32 k22 = iA + iB; + this.m_K.ey.y = iA + iB; + if (this.m_K.ey.y === 0) { + // For bodies with fixed rotation. + this.m_K.ey.y = 1; + } + // m_K.ex.Set(k11, k12); + // m_K.ey.Set(k12, k22); + } + // Compute motor and limit terms. + if (this.m_enableLimit) { + this.m_translation = b2Vec2.DotVV(this.m_axis, d); + } + else { + this.m_lowerImpulse = 0.0; + this.m_upperImpulse = 0.0; + } + if (!this.m_enableMotor) { + this.m_motorImpulse = 0; + } + if (data.step.warmStarting) { + // Account for variable time step. + // m_impulse *= data.step.dtRatio; + this.m_impulse.SelfMul(data.step.dtRatio); + this.m_motorImpulse *= data.step.dtRatio; + this.m_lowerImpulse *= data.step.dtRatio; + this.m_upperImpulse *= data.step.dtRatio; + const axialImpulse = this.m_motorImpulse + this.m_lowerImpulse - this.m_upperImpulse; + // b2Vec2 P = m_impulse.x * m_perp + axialImpulse * m_axis; + const P = b2Vec2.AddVV(b2Vec2.MulSV(this.m_impulse.x, this.m_perp, b2Vec2.s_t0), b2Vec2.MulSV(axialImpulse, this.m_axis, b2Vec2.s_t1), b2PrismaticJoint.InitVelocityConstraints_s_P); + // float LA = m_impulse.x * m_s1 + m_impulse.y + axialImpulse * m_a1; + const LA = this.m_impulse.x * this.m_s1 + this.m_impulse.y + axialImpulse * this.m_a1; + // float LB = m_impulse.x * m_s2 + m_impulse.y + axialImpulse * m_a2; + const LB = this.m_impulse.x * this.m_s2 + this.m_impulse.y + axialImpulse * this.m_a2; + // vA -= mA * P; + vA.SelfMulSub(mA, P); + wA -= iA * LA; + // vB += mB * P; + vB.SelfMulAdd(mB, P); + wB += iB * LB; + } + else { + this.m_impulse.SetZero(); + this.m_motorImpulse = 0.0; + this.m_lowerImpulse = 0.0; + this.m_upperImpulse = 0.0; + } + // data.velocities[this.m_indexA].v = vA; + data.velocities[this.m_indexA].w = wA; + // data.velocities[this.m_indexB].v = vB; + data.velocities[this.m_indexB].w = wB; + } + SolveVelocityConstraints(data) { + const vA = data.velocities[this.m_indexA].v; + let wA = data.velocities[this.m_indexA].w; + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + const mA = this.m_invMassA, mB = this.m_invMassB; + const iA = this.m_invIA, iB = this.m_invIB; + // Solve linear motor constraint. + if (this.m_enableMotor) { + // float32 Cdot = b2Dot(m_axis, vB - vA) + m_a2 * wB - m_a1 * wA; + const Cdot = b2Vec2.DotVV(this.m_axis, b2Vec2.SubVV(vB, vA, b2Vec2.s_t0)) + this.m_a2 * wB - this.m_a1 * wA; + let impulse = this.m_axialMass * (this.m_motorSpeed - Cdot); + const oldImpulse = this.m_motorImpulse; + const maxImpulse = data.step.dt * this.m_maxMotorForce; + this.m_motorImpulse = b2Clamp(this.m_motorImpulse + impulse, (-maxImpulse), maxImpulse); + impulse = this.m_motorImpulse - oldImpulse; + // b2Vec2 P = impulse * m_axis; + const P = b2Vec2.MulSV(impulse, this.m_axis, b2PrismaticJoint.SolveVelocityConstraints_s_P); + const LA = impulse * this.m_a1; + const LB = impulse * this.m_a2; + // vA -= mA * P; + vA.SelfMulSub(mA, P); + wA -= iA * LA; + // vB += mB * P; + vB.SelfMulAdd(mB, P); + wB += iB * LB; + } + if (this.m_enableLimit) { + // Lower limit + { + const C = this.m_translation - this.m_lowerTranslation; + const Cdot = b2Vec2.DotVV(this.m_axis, b2Vec2.SubVV(vB, vA, b2Vec2.s_t0)) + this.m_a2 * wB - this.m_a1 * wA; + let impulse = -this.m_axialMass * (Cdot + b2Max(C, 0.0) * data.step.inv_dt); + const oldImpulse = this.m_lowerImpulse; + this.m_lowerImpulse = b2Max(this.m_lowerImpulse + impulse, 0.0); + impulse = this.m_lowerImpulse - oldImpulse; + // b2Vec2 P = impulse * this.m_axis; + const P = b2Vec2.MulSV(impulse, this.m_axis, b2PrismaticJoint.SolveVelocityConstraints_s_P); + const LA = impulse * this.m_a1; + const LB = impulse * this.m_a2; + // vA -= mA * P; + vA.SelfMulSub(mA, P); + wA -= iA * LA; + // vB += mB * P; + vB.SelfMulAdd(mB, P); + wB += iB * LB; + } + // Upper limit + // Note: signs are flipped to keep C positive when the constraint is satisfied. + // This also keeps the impulse positive when the limit is active. + { + const C = this.m_upperTranslation - this.m_translation; + const Cdot = b2Vec2.DotVV(this.m_axis, b2Vec2.SubVV(vA, vB, b2Vec2.s_t0)) + this.m_a1 * wA - this.m_a2 * wB; + let impulse = -this.m_axialMass * (Cdot + b2Max(C, 0.0) * data.step.inv_dt); + const oldImpulse = this.m_upperImpulse; + this.m_upperImpulse = b2Max(this.m_upperImpulse + impulse, 0.0); + impulse = this.m_upperImpulse - oldImpulse; + // b2Vec2 P = impulse * this.m_axis; + const P = b2Vec2.MulSV(impulse, this.m_axis, b2PrismaticJoint.SolveVelocityConstraints_s_P); + const LA = impulse * this.m_a1; + const LB = impulse * this.m_a2; + // vA += mA * P; + vA.SelfMulAdd(mA, P); + wA += iA * LA; + // vB -= mB * P; + vB.SelfMulSub(mB, P); + wB -= iB * LB; + } + } + // Solve the prismatic constraint in block form. + { + // b2Vec2 Cdot; + // Cdot.x = b2Dot(m_perp, vB - vA) + m_s2 * wB - m_s1 * wA; + const Cdot_x = b2Vec2.DotVV(this.m_perp, b2Vec2.SubVV(vB, vA, b2Vec2.s_t0)) + this.m_s2 * wB - this.m_s1 * wA; + // Cdot.y = wB - wA; + const Cdot_y = wB - wA; + // b2Vec2 df = m_K.Solve(-Cdot); + const df = this.m_K.Solve(-Cdot_x, -Cdot_y, b2PrismaticJoint.SolveVelocityConstraints_s_df); + // m_impulse += df; + this.m_impulse.SelfAdd(df); + // b2Vec2 P = df.x * m_perp; + const P = b2Vec2.MulSV(df.x, this.m_perp, b2PrismaticJoint.SolveVelocityConstraints_s_P); + // float32 LA = df.x * m_s1 + df.y; + const LA = df.x * this.m_s1 + df.y; + // float32 LB = df.x * m_s2 + df.y; + const LB = df.x * this.m_s2 + df.y; + // vA -= mA * P; + vA.SelfMulSub(mA, P); + wA -= iA * LA; + // vB += mB * P; + vB.SelfMulAdd(mB, P); + wB += iB * LB; + } + // data.velocities[this.m_indexA].v = vA; + data.velocities[this.m_indexA].w = wA; + // data.velocities[this.m_indexB].v = vB; + data.velocities[this.m_indexB].w = wB; + } + SolvePositionConstraints(data) { + const cA = data.positions[this.m_indexA].c; + let aA = data.positions[this.m_indexA].a; + const cB = data.positions[this.m_indexB].c; + let aB = data.positions[this.m_indexB].a; + const qA = this.m_qA.SetAngle(aA), qB = this.m_qB.SetAngle(aB); + const mA = this.m_invMassA, mB = this.m_invMassB; + const iA = this.m_invIA, iB = this.m_invIB; + // b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); + const rA = b2Rot.MulRV(qA, this.m_lalcA, this.m_rA); + // b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); + const rB = b2Rot.MulRV(qB, this.m_lalcB, this.m_rB); + // b2Vec2 d = cB + rB - cA - rA; + const d = b2Vec2.SubVV(b2Vec2.AddVV(cB, rB, b2Vec2.s_t0), b2Vec2.AddVV(cA, rA, b2Vec2.s_t1), b2PrismaticJoint.SolvePositionConstraints_s_d); + // b2Vec2 axis = b2Mul(qA, m_localXAxisA); + const axis = b2Rot.MulRV(qA, this.m_localXAxisA, this.m_axis); + // float32 a1 = b2Cross(d + rA, axis); + const a1 = b2Vec2.CrossVV(b2Vec2.AddVV(d, rA, b2Vec2.s_t0), axis); + // float32 a2 = b2Cross(rB, axis); + const a2 = b2Vec2.CrossVV(rB, axis); + // b2Vec2 perp = b2Mul(qA, m_localYAxisA); + const perp = b2Rot.MulRV(qA, this.m_localYAxisA, this.m_perp); + // float32 s1 = b2Cross(d + rA, perp); + const s1 = b2Vec2.CrossVV(b2Vec2.AddVV(d, rA, b2Vec2.s_t0), perp); + // float32 s2 = b2Cross(rB, perp); + const s2 = b2Vec2.CrossVV(rB, perp); + // b2Vec3 impulse; + let impulse = b2PrismaticJoint.SolvePositionConstraints_s_impulse; + // b2Vec2 C1; + // C1.x = b2Dot(perp, d); + const C1_x = b2Vec2.DotVV(perp, d); + // C1.y = aB - aA - m_referenceAngle; + const C1_y = aB - aA - this.m_referenceAngle; + let linearError = b2Abs(C1_x); + const angularError = b2Abs(C1_y); + let active = false; + let C2 = 0; + if (this.m_enableLimit) { + // float32 translation = b2Dot(axis, d); + const translation = b2Vec2.DotVV(axis, d); + if (b2Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2 * b2_linearSlop) { + C2 = translation; + linearError = b2Max(linearError, b2Abs(translation)); + active = true; + } + else if (translation <= this.m_lowerTranslation) { + C2 = b2Min(translation - this.m_lowerTranslation, 0.0); + linearError = b2Max(linearError, this.m_lowerTranslation - translation); + active = true; + } + else if (translation >= this.m_upperTranslation) { + C2 = b2Max(translation - this.m_upperTranslation, 0.0); + linearError = b2Max(linearError, translation - this.m_upperTranslation); + active = true; + } + } + if (active) { + // float32 k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2; + const k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2; + // float32 k12 = iA * s1 + iB * s2; + const k12 = iA * s1 + iB * s2; + // float32 k13 = iA * s1 * a1 + iB * s2 * a2; + const k13 = iA * s1 * a1 + iB * s2 * a2; + // float32 k22 = iA + iB; + let k22 = iA + iB; + if (k22 === 0) { + // For fixed rotation + k22 = 1; + } + // float32 k23 = iA * a1 + iB * a2; + const k23 = iA * a1 + iB * a2; + // float32 k33 = mA + mB + iA * a1 * a1 + iB * a2 * a2; + const k33 = mA + mB + iA * a1 * a1 + iB * a2 * a2; + // b2Mat33 K; + const K = this.m_K3; + // K.ex.Set(k11, k12, k13); + K.ex.SetXYZ(k11, k12, k13); + // K.ey.Set(k12, k22, k23); + K.ey.SetXYZ(k12, k22, k23); + // K.ez.Set(k13, k23, k33); + K.ez.SetXYZ(k13, k23, k33); + // b2Vec3 C; + // C.x = C1.x; + // C.y = C1.y; + // C.z = C2; + // impulse = K.Solve33(-C); + impulse = K.Solve33((-C1_x), (-C1_y), (-C2), impulse); + } + else { + // float32 k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2; + const k11 = mA + mB + iA * s1 * s1 + iB * s2 * s2; + // float32 k12 = iA * s1 + iB * s2; + const k12 = iA * s1 + iB * s2; + // float32 k22 = iA + iB; + let k22 = iA + iB; + if (k22 === 0) { + k22 = 1; + } + // b2Mat22 K; + const K2 = this.m_K2; + // K.ex.Set(k11, k12); + K2.ex.Set(k11, k12); + // K.ey.Set(k12, k22); + K2.ey.Set(k12, k22); + // b2Vec2 impulse1 = K.Solve(-C1); + const impulse1 = K2.Solve((-C1_x), (-C1_y), b2PrismaticJoint.SolvePositionConstraints_s_impulse1); + impulse.x = impulse1.x; + impulse.y = impulse1.y; + impulse.z = 0; + } + // b2Vec2 P = impulse.x * perp + impulse.z * axis; + const P = b2Vec2.AddVV(b2Vec2.MulSV(impulse.x, perp, b2Vec2.s_t0), b2Vec2.MulSV(impulse.z, axis, b2Vec2.s_t1), b2PrismaticJoint.SolvePositionConstraints_s_P); + // float32 LA = impulse.x * s1 + impulse.y + impulse.z * a1; + const LA = impulse.x * s1 + impulse.y + impulse.z * a1; + // float32 LB = impulse.x * s2 + impulse.y + impulse.z * a2; + const LB = impulse.x * s2 + impulse.y + impulse.z * a2; + // cA -= mA * P; + cA.SelfMulSub(mA, P); + aA -= iA * LA; + // cB += mB * P; + cB.SelfMulAdd(mB, P); + aB += iB * LB; + // data.positions[this.m_indexA].c = cA; + data.positions[this.m_indexA].a = aA; + // data.positions[this.m_indexB].c = cB; + data.positions[this.m_indexB].a = aB; + return linearError <= b2_linearSlop && angularError <= b2_angularSlop; + } + GetAnchorA(out) { + return this.m_bodyA.GetWorldPoint(this.m_localAnchorA, out); + } + GetAnchorB(out) { + return this.m_bodyB.GetWorldPoint(this.m_localAnchorB, out); + } + GetReactionForce(inv_dt, out) { + out.x = inv_dt * (this.m_impulse.x * this.m_perp.x + (this.m_motorImpulse + this.m_lowerImpulse - this.m_upperImpulse) * this.m_axis.x); + out.y = inv_dt * (this.m_impulse.y * this.m_perp.y + (this.m_motorImpulse + this.m_lowerImpulse - this.m_upperImpulse) * this.m_axis.y); + return out; + } + GetReactionTorque(inv_dt) { + return inv_dt * this.m_impulse.y; + } + GetLocalAnchorA() { return this.m_localAnchorA; } + GetLocalAnchorB() { return this.m_localAnchorB; } + GetLocalAxisA() { return this.m_localXAxisA; } + GetReferenceAngle() { return this.m_referenceAngle; } + GetJointTranslation() { + // b2Vec2 pA = m_bodyA.GetWorldPoint(m_localAnchorA); + const pA = this.m_bodyA.GetWorldPoint(this.m_localAnchorA, b2PrismaticJoint.GetJointTranslation_s_pA); + // b2Vec2 pB = m_bodyB.GetWorldPoint(m_localAnchorB); + const pB = this.m_bodyB.GetWorldPoint(this.m_localAnchorB, b2PrismaticJoint.GetJointTranslation_s_pB); + // b2Vec2 d = pB - pA; + const d = b2Vec2.SubVV(pB, pA, b2PrismaticJoint.GetJointTranslation_s_d); + // b2Vec2 axis = m_bodyA.GetWorldVector(m_localXAxisA); + const axis = this.m_bodyA.GetWorldVector(this.m_localXAxisA, b2PrismaticJoint.GetJointTranslation_s_axis); + // float32 translation = b2Dot(d, axis); + const translation = b2Vec2.DotVV(d, axis); + return translation; + } + GetJointSpeed() { + const bA = this.m_bodyA; + const bB = this.m_bodyB; + // b2Vec2 rA = b2Mul(bA->m_xf.q, m_localAnchorA - bA->m_sweep.localCenter); + b2Vec2.SubVV(this.m_localAnchorA, bA.m_sweep.localCenter, this.m_lalcA); + const rA = b2Rot.MulRV(bA.m_xf.q, this.m_lalcA, this.m_rA); + // b2Vec2 rB = b2Mul(bB->m_xf.q, m_localAnchorB - bB->m_sweep.localCenter); + b2Vec2.SubVV(this.m_localAnchorB, bB.m_sweep.localCenter, this.m_lalcB); + const rB = b2Rot.MulRV(bB.m_xf.q, this.m_lalcB, this.m_rB); + // b2Vec2 pA = bA->m_sweep.c + rA; + const pA = b2Vec2.AddVV(bA.m_sweep.c, rA, b2Vec2.s_t0); // pA uses s_t0 + // b2Vec2 pB = bB->m_sweep.c + rB; + const pB = b2Vec2.AddVV(bB.m_sweep.c, rB, b2Vec2.s_t1); // pB uses s_t1 + // b2Vec2 d = pB - pA; + const d = b2Vec2.SubVV(pB, pA, b2Vec2.s_t2); // d uses s_t2 + // b2Vec2 axis = b2Mul(bA.m_xf.q, m_localXAxisA); + const axis = bA.GetWorldVector(this.m_localXAxisA, this.m_axis); + const vA = bA.m_linearVelocity; + const vB = bB.m_linearVelocity; + const wA = bA.m_angularVelocity; + const wB = bB.m_angularVelocity; + // float32 speed = b2Dot(d, b2Cross(wA, axis)) + b2Dot(axis, vB + b2Cross(wB, rB) - vA - b2Cross(wA, rA)); + const speed = b2Vec2.DotVV(d, b2Vec2.CrossSV(wA, axis, b2Vec2.s_t0)) + + b2Vec2.DotVV(axis, b2Vec2.SubVV(b2Vec2.AddVCrossSV(vB, wB, rB, b2Vec2.s_t0), b2Vec2.AddVCrossSV(vA, wA, rA, b2Vec2.s_t1), b2Vec2.s_t0)); + return speed; + } + IsLimitEnabled() { + return this.m_enableLimit; + } + EnableLimit(flag) { + if (flag !== this.m_enableLimit) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_enableLimit = flag; + this.m_lowerImpulse = 0.0; + this.m_upperImpulse = 0.0; + } + } + GetLowerLimit() { + return this.m_lowerTranslation; + } + GetUpperLimit() { + return this.m_upperTranslation; + } + SetLimits(lower, upper) { + if (lower !== this.m_lowerTranslation || upper !== this.m_upperTranslation) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_lowerTranslation = lower; + this.m_upperTranslation = upper; + this.m_lowerImpulse = 0.0; + this.m_upperImpulse = 0.0; + } + } + IsMotorEnabled() { + return this.m_enableMotor; + } + EnableMotor(flag) { + if (flag !== this.m_enableMotor) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_enableMotor = flag; + } + } + SetMotorSpeed(speed) { + if (speed !== this.m_motorSpeed) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_motorSpeed = speed; + } + } + GetMotorSpeed() { + return this.m_motorSpeed; + } + SetMaxMotorForce(force) { + if (force !== this.m_maxMotorForce) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_maxMotorForce = force; + } + } + GetMaxMotorForce() { return this.m_maxMotorForce; } + GetMotorForce(inv_dt) { + return inv_dt * this.m_motorImpulse; + } + Dump(log) { + const indexA = this.m_bodyA.m_islandIndex; + const indexB = this.m_bodyB.m_islandIndex; + log(" const jd: b2PrismaticJointDef = new b2PrismaticJointDef();\n"); + log(" jd.bodyA = bodies[%d];\n", indexA); + log(" jd.bodyB = bodies[%d];\n", indexB); + log(" jd.collideConnected = %s;\n", (this.m_collideConnected) ? ("true") : ("false")); + log(" jd.localAnchorA.Set(%.15f, %.15f);\n", this.m_localAnchorA.x, this.m_localAnchorA.y); + log(" jd.localAnchorB.Set(%.15f, %.15f);\n", this.m_localAnchorB.x, this.m_localAnchorB.y); + log(" jd.localAxisA.Set(%.15f, %.15f);\n", this.m_localXAxisA.x, this.m_localXAxisA.y); + log(" jd.referenceAngle = %.15f;\n", this.m_referenceAngle); + log(" jd.enableLimit = %s;\n", (this.m_enableLimit) ? ("true") : ("false")); + log(" jd.lowerTranslation = %.15f;\n", this.m_lowerTranslation); + log(" jd.upperTranslation = %.15f;\n", this.m_upperTranslation); + log(" jd.enableMotor = %s;\n", (this.m_enableMotor) ? ("true") : ("false")); + log(" jd.motorSpeed = %.15f;\n", this.m_motorSpeed); + log(" jd.maxMotorForce = %.15f;\n", this.m_maxMotorForce); + log(" joints[%d] = this.m_world.CreateJoint(jd);\n", this.m_index); + } + Draw(draw) { + const xfA = this.m_bodyA.GetTransform(); + const xfB = this.m_bodyB.GetTransform(); + const pA = b2Transform.MulXV(xfA, this.m_localAnchorA, b2PrismaticJoint.Draw_s_pA); + const pB = b2Transform.MulXV(xfB, this.m_localAnchorB, b2PrismaticJoint.Draw_s_pB); + // b2Vec2 axis = b2Mul(xfA.q, m_localXAxisA); + const axis = b2Rot.MulRV(xfA.q, this.m_localXAxisA, b2PrismaticJoint.Draw_s_axis); + const c1 = b2PrismaticJoint.Draw_s_c1; // b2Color c1(0.7f, 0.7f, 0.7f); + const c2 = b2PrismaticJoint.Draw_s_c2; // b2Color c2(0.3f, 0.9f, 0.3f); + const c3 = b2PrismaticJoint.Draw_s_c3; // b2Color c3(0.9f, 0.3f, 0.3f); + const c4 = b2PrismaticJoint.Draw_s_c4; // b2Color c4(0.3f, 0.3f, 0.9f); + const c5 = b2PrismaticJoint.Draw_s_c5; // b2Color c5(0.4f, 0.4f, 0.4f); + draw.DrawSegment(pA, pB, c5); + if (this.m_enableLimit) { + // b2Vec2 lower = pA + m_lowerTranslation * axis; + const lower = b2Vec2.AddVMulSV(pA, this.m_lowerTranslation, axis, b2PrismaticJoint.Draw_s_lower); + // b2Vec2 upper = pA + m_upperTranslation * axis; + const upper = b2Vec2.AddVMulSV(pA, this.m_upperTranslation, axis, b2PrismaticJoint.Draw_s_upper); + // b2Vec2 perp = b2Mul(xfA.q, m_localYAxisA); + const perp = b2Rot.MulRV(xfA.q, this.m_localYAxisA, b2PrismaticJoint.Draw_s_perp); + draw.DrawSegment(lower, upper, c1); + // draw.DrawSegment(lower - 0.5 * perp, lower + 0.5 * perp, c2); + draw.DrawSegment(b2Vec2.AddVMulSV(lower, -0.5, perp, b2Vec2.s_t0), b2Vec2.AddVMulSV(lower, 0.5, perp, b2Vec2.s_t1), c2); + // draw.DrawSegment(upper - 0.5 * perp, upper + 0.5 * perp, c3); + draw.DrawSegment(b2Vec2.AddVMulSV(upper, -0.5, perp, b2Vec2.s_t0), b2Vec2.AddVMulSV(upper, 0.5, perp, b2Vec2.s_t1), c3); + } + else { + // draw.DrawSegment(pA - 1.0 * axis, pA + 1.0 * axis, c1); + draw.DrawSegment(b2Vec2.AddVMulSV(pA, -1.0, axis, b2Vec2.s_t0), b2Vec2.AddVMulSV(pA, 1.0, axis, b2Vec2.s_t1), c1); + } + draw.DrawPoint(pA, 5.0, c1); + draw.DrawPoint(pB, 5.0, c4); + } + } + b2PrismaticJoint.InitVelocityConstraints_s_d = new b2Vec2(); + b2PrismaticJoint.InitVelocityConstraints_s_P = new b2Vec2(); + b2PrismaticJoint.SolveVelocityConstraints_s_P = new b2Vec2(); + // private static SolveVelocityConstraints_s_f2r = new b2Vec2(); + // private static SolveVelocityConstraints_s_f1 = new b2Vec3(); + // private static SolveVelocityConstraints_s_df3 = new b2Vec3(); + b2PrismaticJoint.SolveVelocityConstraints_s_df = new b2Vec2(); + // A velocity based solver computes reaction forces(impulses) using the velocity constraint solver.Under this context, + // the position solver is not there to resolve forces.It is only there to cope with integration error. + // + // Therefore, the pseudo impulses in the position solver do not have any physical meaning.Thus it is okay if they suck. + // + // We could take the active state from the velocity solver.However, the joint might push past the limit when the velocity + // solver indicates the limit is inactive. + b2PrismaticJoint.SolvePositionConstraints_s_d = new b2Vec2(); + b2PrismaticJoint.SolvePositionConstraints_s_impulse = new b2Vec3(); + b2PrismaticJoint.SolvePositionConstraints_s_impulse1 = new b2Vec2(); + b2PrismaticJoint.SolvePositionConstraints_s_P = new b2Vec2(); + b2PrismaticJoint.GetJointTranslation_s_pA = new b2Vec2(); + b2PrismaticJoint.GetJointTranslation_s_pB = new b2Vec2(); + b2PrismaticJoint.GetJointTranslation_s_d = new b2Vec2(); + b2PrismaticJoint.GetJointTranslation_s_axis = new b2Vec2(); + b2PrismaticJoint.Draw_s_pA = new b2Vec2(); + b2PrismaticJoint.Draw_s_pB = new b2Vec2(); + b2PrismaticJoint.Draw_s_axis = new b2Vec2(); + b2PrismaticJoint.Draw_s_c1 = new b2Color(0.7, 0.7, 0.7); + b2PrismaticJoint.Draw_s_c2 = new b2Color(0.3, 0.9, 0.3); + b2PrismaticJoint.Draw_s_c3 = new b2Color(0.9, 0.3, 0.3); + b2PrismaticJoint.Draw_s_c4 = new b2Color(0.3, 0.3, 0.9); + b2PrismaticJoint.Draw_s_c5 = new b2Color(0.4, 0.4, 0.4); + b2PrismaticJoint.Draw_s_lower = new b2Vec2(); + b2PrismaticJoint.Draw_s_upper = new b2Vec2(); + b2PrismaticJoint.Draw_s_perp = new b2Vec2(); + + /* + * Copyright (c) 2006-2011 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + const b2_minPulleyLength = 2; + /// Pulley joint definition. This requires two ground anchors, + /// two dynamic body anchor points, and a pulley ratio. + class b2PulleyJointDef extends b2JointDef { + constructor() { + super(exports.b2JointType.e_pulleyJoint); + this.groundAnchorA = new b2Vec2(-1, 1); + this.groundAnchorB = new b2Vec2(1, 1); + this.localAnchorA = new b2Vec2(-1, 0); + this.localAnchorB = new b2Vec2(1, 0); + this.lengthA = 0; + this.lengthB = 0; + this.ratio = 1; + this.collideConnected = true; + } + Initialize(bA, bB, groundA, groundB, anchorA, anchorB, r) { + this.bodyA = bA; + this.bodyB = bB; + this.groundAnchorA.Copy(groundA); + this.groundAnchorB.Copy(groundB); + this.bodyA.GetLocalPoint(anchorA, this.localAnchorA); + this.bodyB.GetLocalPoint(anchorB, this.localAnchorB); + this.lengthA = b2Vec2.DistanceVV(anchorA, groundA); + this.lengthB = b2Vec2.DistanceVV(anchorB, groundB); + this.ratio = r; + // DEBUG: b2Assert(this.ratio > b2_epsilon); + } + } + class b2PulleyJoint extends b2Joint { + constructor(def) { + super(def); + this.m_groundAnchorA = new b2Vec2(); + this.m_groundAnchorB = new b2Vec2(); + this.m_lengthA = 0; + this.m_lengthB = 0; + // Solver shared + this.m_localAnchorA = new b2Vec2(); + this.m_localAnchorB = new b2Vec2(); + this.m_constant = 0; + this.m_ratio = 0; + this.m_impulse = 0; + // Solver temp + this.m_indexA = 0; + this.m_indexB = 0; + this.m_uA = new b2Vec2(); + this.m_uB = new b2Vec2(); + this.m_rA = new b2Vec2(); + this.m_rB = new b2Vec2(); + this.m_localCenterA = new b2Vec2(); + this.m_localCenterB = new b2Vec2(); + this.m_invMassA = 0; + this.m_invMassB = 0; + this.m_invIA = 0; + this.m_invIB = 0; + this.m_mass = 0; + this.m_qA = new b2Rot(); + this.m_qB = new b2Rot(); + this.m_lalcA = new b2Vec2(); + this.m_lalcB = new b2Vec2(); + this.m_groundAnchorA.Copy(b2Maybe(def.groundAnchorA, new b2Vec2(-1, 1))); + this.m_groundAnchorB.Copy(b2Maybe(def.groundAnchorB, new b2Vec2(1, 0))); + this.m_localAnchorA.Copy(b2Maybe(def.localAnchorA, new b2Vec2(-1, 0))); + this.m_localAnchorB.Copy(b2Maybe(def.localAnchorB, new b2Vec2(1, 0))); + this.m_lengthA = b2Maybe(def.lengthA, 0); + this.m_lengthB = b2Maybe(def.lengthB, 0); + // DEBUG: b2Assert(b2Maybe(def.ratio, 1) !== 0); + this.m_ratio = b2Maybe(def.ratio, 1); + this.m_constant = b2Maybe(def.lengthA, 0) + this.m_ratio * b2Maybe(def.lengthB, 0); + this.m_impulse = 0; + } + InitVelocityConstraints(data) { + this.m_indexA = this.m_bodyA.m_islandIndex; + this.m_indexB = this.m_bodyB.m_islandIndex; + this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter); + this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter); + this.m_invMassA = this.m_bodyA.m_invMass; + this.m_invMassB = this.m_bodyB.m_invMass; + this.m_invIA = this.m_bodyA.m_invI; + this.m_invIB = this.m_bodyB.m_invI; + const cA = data.positions[this.m_indexA].c; + const aA = data.positions[this.m_indexA].a; + const vA = data.velocities[this.m_indexA].v; + let wA = data.velocities[this.m_indexA].w; + const cB = data.positions[this.m_indexB].c; + const aB = data.positions[this.m_indexB].a; + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + // b2Rot qA(aA), qB(aB); + const qA = this.m_qA.SetAngle(aA), qB = this.m_qB.SetAngle(aB); + // m_rA = b2Mul(qA, m_localAnchorA - m_localCenterA); + b2Vec2.SubVV(this.m_localAnchorA, this.m_localCenterA, this.m_lalcA); + b2Rot.MulRV(qA, this.m_lalcA, this.m_rA); + // m_rB = b2Mul(qB, m_localAnchorB - m_localCenterB); + b2Vec2.SubVV(this.m_localAnchorB, this.m_localCenterB, this.m_lalcB); + b2Rot.MulRV(qB, this.m_lalcB, this.m_rB); + // Get the pulley axes. + // m_uA = cA + m_rA - m_groundAnchorA; + this.m_uA.Copy(cA).SelfAdd(this.m_rA).SelfSub(this.m_groundAnchorA); + // m_uB = cB + m_rB - m_groundAnchorB; + this.m_uB.Copy(cB).SelfAdd(this.m_rB).SelfSub(this.m_groundAnchorB); + const lengthA = this.m_uA.Length(); + const lengthB = this.m_uB.Length(); + if (lengthA > 10 * b2_linearSlop) { + this.m_uA.SelfMul(1 / lengthA); + } + else { + this.m_uA.SetZero(); + } + if (lengthB > 10 * b2_linearSlop) { + this.m_uB.SelfMul(1 / lengthB); + } + else { + this.m_uB.SetZero(); + } + // Compute effective mass. + const ruA = b2Vec2.CrossVV(this.m_rA, this.m_uA); + const ruB = b2Vec2.CrossVV(this.m_rB, this.m_uB); + const mA = this.m_invMassA + this.m_invIA * ruA * ruA; + const mB = this.m_invMassB + this.m_invIB * ruB * ruB; + this.m_mass = mA + this.m_ratio * this.m_ratio * mB; + if (this.m_mass > 0) { + this.m_mass = 1 / this.m_mass; + } + if (data.step.warmStarting) { + // Scale impulses to support variable time steps. + this.m_impulse *= data.step.dtRatio; + // Warm starting. + // b2Vec2 PA = -(m_impulse) * m_uA; + const PA = b2Vec2.MulSV(-(this.m_impulse), this.m_uA, b2PulleyJoint.InitVelocityConstraints_s_PA); + // b2Vec2 PB = (-m_ratio * m_impulse) * m_uB; + const PB = b2Vec2.MulSV((-this.m_ratio * this.m_impulse), this.m_uB, b2PulleyJoint.InitVelocityConstraints_s_PB); + // vA += m_invMassA * PA; + vA.SelfMulAdd(this.m_invMassA, PA); + wA += this.m_invIA * b2Vec2.CrossVV(this.m_rA, PA); + // vB += m_invMassB * PB; + vB.SelfMulAdd(this.m_invMassB, PB); + wB += this.m_invIB * b2Vec2.CrossVV(this.m_rB, PB); + } + else { + this.m_impulse = 0; + } + // data.velocities[this.m_indexA].v = vA; + data.velocities[this.m_indexA].w = wA; + // data.velocities[this.m_indexB].v = vB; + data.velocities[this.m_indexB].w = wB; + } + SolveVelocityConstraints(data) { + const vA = data.velocities[this.m_indexA].v; + let wA = data.velocities[this.m_indexA].w; + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + // b2Vec2 vpA = vA + b2Cross(wA, m_rA); + const vpA = b2Vec2.AddVCrossSV(vA, wA, this.m_rA, b2PulleyJoint.SolveVelocityConstraints_s_vpA); + // b2Vec2 vpB = vB + b2Cross(wB, m_rB); + const vpB = b2Vec2.AddVCrossSV(vB, wB, this.m_rB, b2PulleyJoint.SolveVelocityConstraints_s_vpB); + const Cdot = -b2Vec2.DotVV(this.m_uA, vpA) - this.m_ratio * b2Vec2.DotVV(this.m_uB, vpB); + const impulse = -this.m_mass * Cdot; + this.m_impulse += impulse; + // b2Vec2 PA = -impulse * m_uA; + const PA = b2Vec2.MulSV(-impulse, this.m_uA, b2PulleyJoint.SolveVelocityConstraints_s_PA); + // b2Vec2 PB = -m_ratio * impulse * m_uB; + const PB = b2Vec2.MulSV(-this.m_ratio * impulse, this.m_uB, b2PulleyJoint.SolveVelocityConstraints_s_PB); + // vA += m_invMassA * PA; + vA.SelfMulAdd(this.m_invMassA, PA); + wA += this.m_invIA * b2Vec2.CrossVV(this.m_rA, PA); + // vB += m_invMassB * PB; + vB.SelfMulAdd(this.m_invMassB, PB); + wB += this.m_invIB * b2Vec2.CrossVV(this.m_rB, PB); + // data.velocities[this.m_indexA].v = vA; + data.velocities[this.m_indexA].w = wA; + // data.velocities[this.m_indexB].v = vB; + data.velocities[this.m_indexB].w = wB; + } + SolvePositionConstraints(data) { + const cA = data.positions[this.m_indexA].c; + let aA = data.positions[this.m_indexA].a; + const cB = data.positions[this.m_indexB].c; + let aB = data.positions[this.m_indexB].a; + // b2Rot qA(aA), qB(aB); + const qA = this.m_qA.SetAngle(aA), qB = this.m_qB.SetAngle(aB); + // b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); + b2Vec2.SubVV(this.m_localAnchorA, this.m_localCenterA, this.m_lalcA); + const rA = b2Rot.MulRV(qA, this.m_lalcA, this.m_rA); + // b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); + b2Vec2.SubVV(this.m_localAnchorB, this.m_localCenterB, this.m_lalcB); + const rB = b2Rot.MulRV(qB, this.m_lalcB, this.m_rB); + // Get the pulley axes. + // b2Vec2 uA = cA + rA - m_groundAnchorA; + const uA = this.m_uA.Copy(cA).SelfAdd(rA).SelfSub(this.m_groundAnchorA); + // b2Vec2 uB = cB + rB - m_groundAnchorB; + const uB = this.m_uB.Copy(cB).SelfAdd(rB).SelfSub(this.m_groundAnchorB); + const lengthA = uA.Length(); + const lengthB = uB.Length(); + if (lengthA > 10 * b2_linearSlop) { + uA.SelfMul(1 / lengthA); + } + else { + uA.SetZero(); + } + if (lengthB > 10 * b2_linearSlop) { + uB.SelfMul(1 / lengthB); + } + else { + uB.SetZero(); + } + // Compute effective mass. + const ruA = b2Vec2.CrossVV(rA, uA); + const ruB = b2Vec2.CrossVV(rB, uB); + const mA = this.m_invMassA + this.m_invIA * ruA * ruA; + const mB = this.m_invMassB + this.m_invIB * ruB * ruB; + let mass = mA + this.m_ratio * this.m_ratio * mB; + if (mass > 0) { + mass = 1 / mass; + } + const C = this.m_constant - lengthA - this.m_ratio * lengthB; + const linearError = b2Abs(C); + const impulse = -mass * C; + // b2Vec2 PA = -impulse * uA; + const PA = b2Vec2.MulSV(-impulse, uA, b2PulleyJoint.SolvePositionConstraints_s_PA); + // b2Vec2 PB = -m_ratio * impulse * uB; + const PB = b2Vec2.MulSV(-this.m_ratio * impulse, uB, b2PulleyJoint.SolvePositionConstraints_s_PB); + // cA += m_invMassA * PA; + cA.SelfMulAdd(this.m_invMassA, PA); + aA += this.m_invIA * b2Vec2.CrossVV(rA, PA); + // cB += m_invMassB * PB; + cB.SelfMulAdd(this.m_invMassB, PB); + aB += this.m_invIB * b2Vec2.CrossVV(rB, PB); + // data.positions[this.m_indexA].c = cA; + data.positions[this.m_indexA].a = aA; + // data.positions[this.m_indexB].c = cB; + data.positions[this.m_indexB].a = aB; + return linearError < b2_linearSlop; + } + GetAnchorA(out) { + return this.m_bodyA.GetWorldPoint(this.m_localAnchorA, out); + } + GetAnchorB(out) { + return this.m_bodyB.GetWorldPoint(this.m_localAnchorB, out); + } + GetReactionForce(inv_dt, out) { + // b2Vec2 P = m_impulse * m_uB; + // return inv_dt * P; + out.x = inv_dt * this.m_impulse * this.m_uB.x; + out.y = inv_dt * this.m_impulse * this.m_uB.y; + return out; + } + GetReactionTorque(inv_dt) { + return 0; + } + GetGroundAnchorA() { + return this.m_groundAnchorA; + } + GetGroundAnchorB() { + return this.m_groundAnchorB; + } + GetLengthA() { + return this.m_lengthA; + } + GetLengthB() { + return this.m_lengthB; + } + GetRatio() { + return this.m_ratio; + } + GetCurrentLengthA() { + // b2Vec2 p = m_bodyA->GetWorldPoint(m_localAnchorA); + // b2Vec2 s = m_groundAnchorA; + // b2Vec2 d = p - s; + // return d.Length(); + const p = this.m_bodyA.GetWorldPoint(this.m_localAnchorA, b2PulleyJoint.GetCurrentLengthA_s_p); + const s = this.m_groundAnchorA; + return b2Vec2.DistanceVV(p, s); + } + GetCurrentLengthB() { + // b2Vec2 p = m_bodyB->GetWorldPoint(m_localAnchorB); + // b2Vec2 s = m_groundAnchorB; + // b2Vec2 d = p - s; + // return d.Length(); + const p = this.m_bodyB.GetWorldPoint(this.m_localAnchorB, b2PulleyJoint.GetCurrentLengthB_s_p); + const s = this.m_groundAnchorB; + return b2Vec2.DistanceVV(p, s); + } + Dump(log) { + const indexA = this.m_bodyA.m_islandIndex; + const indexB = this.m_bodyB.m_islandIndex; + log(" const jd: b2PulleyJointDef = new b2PulleyJointDef();\n"); + log(" jd.bodyA = bodies[%d];\n", indexA); + log(" jd.bodyB = bodies[%d];\n", indexB); + log(" jd.collideConnected = %s;\n", (this.m_collideConnected) ? ("true") : ("false")); + log(" jd.groundAnchorA.Set(%.15f, %.15f);\n", this.m_groundAnchorA.x, this.m_groundAnchorA.y); + log(" jd.groundAnchorB.Set(%.15f, %.15f);\n", this.m_groundAnchorB.x, this.m_groundAnchorB.y); + log(" jd.localAnchorA.Set(%.15f, %.15f);\n", this.m_localAnchorA.x, this.m_localAnchorA.y); + log(" jd.localAnchorB.Set(%.15f, %.15f);\n", this.m_localAnchorB.x, this.m_localAnchorB.y); + log(" jd.lengthA = %.15f;\n", this.m_lengthA); + log(" jd.lengthB = %.15f;\n", this.m_lengthB); + log(" jd.ratio = %.15f;\n", this.m_ratio); + log(" joints[%d] = this.m_world.CreateJoint(jd);\n", this.m_index); + } + ShiftOrigin(newOrigin) { + this.m_groundAnchorA.SelfSub(newOrigin); + this.m_groundAnchorB.SelfSub(newOrigin); + } + } + b2PulleyJoint.InitVelocityConstraints_s_PA = new b2Vec2(); + b2PulleyJoint.InitVelocityConstraints_s_PB = new b2Vec2(); + b2PulleyJoint.SolveVelocityConstraints_s_vpA = new b2Vec2(); + b2PulleyJoint.SolveVelocityConstraints_s_vpB = new b2Vec2(); + b2PulleyJoint.SolveVelocityConstraints_s_PA = new b2Vec2(); + b2PulleyJoint.SolveVelocityConstraints_s_PB = new b2Vec2(); + b2PulleyJoint.SolvePositionConstraints_s_PA = new b2Vec2(); + b2PulleyJoint.SolvePositionConstraints_s_PB = new b2Vec2(); + b2PulleyJoint.GetCurrentLengthA_s_p = new b2Vec2(); + b2PulleyJoint.GetCurrentLengthB_s_p = new b2Vec2(); + + /* + * Copyright (c) 2006-2011 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// Revolute joint definition. This requires defining an anchor point where the + /// bodies are joined. The definition uses local anchor points so that the + /// initial configuration can violate the constraint slightly. You also need to + /// specify the initial relative angle for joint limits. This helps when saving + /// and loading a game. + /// The local anchor points are measured from the body's origin + /// rather than the center of mass because: + /// 1. you might not know where the center of mass will be. + /// 2. if you add/remove shapes from a body and recompute the mass, + /// the joints will be broken. + class b2RevoluteJointDef extends b2JointDef { + constructor() { + super(exports.b2JointType.e_revoluteJoint); + this.localAnchorA = new b2Vec2(0, 0); + this.localAnchorB = new b2Vec2(0, 0); + this.referenceAngle = 0; + this.enableLimit = false; + this.lowerAngle = 0; + this.upperAngle = 0; + this.enableMotor = false; + this.motorSpeed = 0; + this.maxMotorTorque = 0; + } + Initialize(bA, bB, anchor) { + this.bodyA = bA; + this.bodyB = bB; + this.bodyA.GetLocalPoint(anchor, this.localAnchorA); + this.bodyB.GetLocalPoint(anchor, this.localAnchorB); + this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle(); + } + } + class b2RevoluteJoint extends b2Joint { + constructor(def) { + super(def); + // Solver shared + this.m_localAnchorA = new b2Vec2(); + this.m_localAnchorB = new b2Vec2(); + this.m_impulse = new b2Vec2(); + this.m_motorImpulse = 0; + this.m_lowerImpulse = 0; + this.m_upperImpulse = 0; + this.m_enableMotor = false; + this.m_maxMotorTorque = 0; + this.m_motorSpeed = 0; + this.m_enableLimit = false; + this.m_referenceAngle = 0; + this.m_lowerAngle = 0; + this.m_upperAngle = 0; + // Solver temp + this.m_indexA = 0; + this.m_indexB = 0; + this.m_rA = new b2Vec2(); + this.m_rB = new b2Vec2(); + this.m_localCenterA = new b2Vec2(); + this.m_localCenterB = new b2Vec2(); + this.m_invMassA = 0; + this.m_invMassB = 0; + this.m_invIA = 0; + this.m_invIB = 0; + this.m_K = new b2Mat22(); + this.m_angle = 0; + this.m_axialMass = 0; + this.m_qA = new b2Rot(); + this.m_qB = new b2Rot(); + this.m_lalcA = new b2Vec2(); + this.m_lalcB = new b2Vec2(); + this.m_localAnchorA.Copy(b2Maybe(def.localAnchorA, b2Vec2.ZERO)); + this.m_localAnchorB.Copy(b2Maybe(def.localAnchorB, b2Vec2.ZERO)); + this.m_referenceAngle = b2Maybe(def.referenceAngle, 0); + this.m_impulse.SetZero(); + this.m_motorImpulse = 0; + this.m_lowerAngle = b2Maybe(def.lowerAngle, 0); + this.m_upperAngle = b2Maybe(def.upperAngle, 0); + this.m_maxMotorTorque = b2Maybe(def.maxMotorTorque, 0); + this.m_motorSpeed = b2Maybe(def.motorSpeed, 0); + this.m_enableLimit = b2Maybe(def.enableLimit, false); + this.m_enableMotor = b2Maybe(def.enableMotor, false); + } + InitVelocityConstraints(data) { + this.m_indexA = this.m_bodyA.m_islandIndex; + this.m_indexB = this.m_bodyB.m_islandIndex; + this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter); + this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter); + this.m_invMassA = this.m_bodyA.m_invMass; + this.m_invMassB = this.m_bodyB.m_invMass; + this.m_invIA = this.m_bodyA.m_invI; + this.m_invIB = this.m_bodyB.m_invI; + const aA = data.positions[this.m_indexA].a; + const vA = data.velocities[this.m_indexA].v; + let wA = data.velocities[this.m_indexA].w; + const aB = data.positions[this.m_indexB].a; + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + // b2Rot qA(aA), qB(aB); + const qA = this.m_qA.SetAngle(aA), qB = this.m_qB.SetAngle(aB); + // m_rA = b2Mul(qA, m_localAnchorA - m_localCenterA); + b2Vec2.SubVV(this.m_localAnchorA, this.m_localCenterA, this.m_lalcA); + b2Rot.MulRV(qA, this.m_lalcA, this.m_rA); + // m_rB = b2Mul(qB, m_localAnchorB - m_localCenterB); + b2Vec2.SubVV(this.m_localAnchorB, this.m_localCenterB, this.m_lalcB); + b2Rot.MulRV(qB, this.m_lalcB, this.m_rB); + // J = [-I -r1_skew I r2_skew] + // r_skew = [-ry; rx] + // Matlab + // K = [ mA+r1y^2*iA+mB+r2y^2*iB, -r1y*iA*r1x-r2y*iB*r2x] + // [ -r1y*iA*r1x-r2y*iB*r2x, mA+r1x^2*iA+mB+r2x^2*iB] + const mA = this.m_invMassA, mB = this.m_invMassB; + const iA = this.m_invIA, iB = this.m_invIB; + this.m_K.ex.x = mA + mB + this.m_rA.y * this.m_rA.y * iA + this.m_rB.y * this.m_rB.y * iB; + this.m_K.ey.x = -this.m_rA.y * this.m_rA.x * iA - this.m_rB.y * this.m_rB.x * iB; + this.m_K.ex.y = this.m_K.ey.x; + this.m_K.ey.y = mA + mB + this.m_rA.x * this.m_rA.x * iA + this.m_rB.x * this.m_rB.x * iB; + this.m_axialMass = iA + iB; + let fixedRotation; + if (this.m_axialMass > 0.0) { + this.m_axialMass = 1.0 / this.m_axialMass; + fixedRotation = false; + } + else { + fixedRotation = true; + } + this.m_angle = aB - aA - this.m_referenceAngle; + if (this.m_enableLimit === false || fixedRotation) { + this.m_lowerImpulse = 0.0; + this.m_upperImpulse = 0.0; + } + if (this.m_enableMotor === false || fixedRotation) { + this.m_motorImpulse = 0.0; + } + if (data.step.warmStarting) { + // Scale impulses to support a variable time step. + this.m_impulse.SelfMul(data.step.dtRatio); + this.m_motorImpulse *= data.step.dtRatio; + this.m_lowerImpulse *= data.step.dtRatio; + this.m_upperImpulse *= data.step.dtRatio; + const axialImpulse = this.m_motorImpulse + this.m_lowerImpulse - this.m_upperImpulse; + // b2Vec2 P(m_impulse.x, m_impulse.y); + const P = b2RevoluteJoint.InitVelocityConstraints_s_P.Set(this.m_impulse.x, this.m_impulse.y); + // vA -= mA * P; + vA.SelfMulSub(mA, P); + wA -= iA * (b2Vec2.CrossVV(this.m_rA, P) + axialImpulse); + // vB += mB * P; + vB.SelfMulAdd(mB, P); + wB += iB * (b2Vec2.CrossVV(this.m_rB, P) + axialImpulse); + } + else { + this.m_impulse.SetZero(); + this.m_motorImpulse = 0; + this.m_lowerImpulse = 0; + this.m_upperImpulse = 0; + } + // data.velocities[this.m_indexA].v = vA; + data.velocities[this.m_indexA].w = wA; + // data.velocities[this.m_indexB].v = vB; + data.velocities[this.m_indexB].w = wB; + } + SolveVelocityConstraints(data) { + const vA = data.velocities[this.m_indexA].v; + let wA = data.velocities[this.m_indexA].w; + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + const mA = this.m_invMassA, mB = this.m_invMassB; + const iA = this.m_invIA, iB = this.m_invIB; + const fixedRotation = (iA + iB === 0); + // Solve motor constraint. + if (this.m_enableMotor && !fixedRotation) { + const Cdot = wB - wA - this.m_motorSpeed; + let impulse = -this.m_axialMass * Cdot; + const oldImpulse = this.m_motorImpulse; + const maxImpulse = data.step.dt * this.m_maxMotorTorque; + this.m_motorImpulse = b2Clamp(this.m_motorImpulse + impulse, -maxImpulse, maxImpulse); + impulse = this.m_motorImpulse - oldImpulse; + wA -= iA * impulse; + wB += iB * impulse; + } + // Solve limit constraint. + if (this.m_enableLimit && !fixedRotation) { + // Lower limit + { + const C = this.m_angle - this.m_lowerAngle; + const Cdot = wB - wA; + let impulse = -this.m_axialMass * (Cdot + b2Max(C, 0.0) * data.step.inv_dt); + const oldImpulse = this.m_lowerImpulse; + this.m_lowerImpulse = b2Max(this.m_lowerImpulse + impulse, 0.0); + impulse = this.m_lowerImpulse - oldImpulse; + wA -= iA * impulse; + wB += iB * impulse; + } + // Upper limit + // Note: signs are flipped to keep C positive when the constraint is satisfied. + // This also keeps the impulse positive when the limit is active. + { + const C = this.m_upperAngle - this.m_angle; + const Cdot = wA - wB; + let impulse = -this.m_axialMass * (Cdot + b2Max(C, 0.0) * data.step.inv_dt); + const oldImpulse = this.m_upperImpulse; + this.m_upperImpulse = b2Max(this.m_upperImpulse + impulse, 0.0); + impulse = this.m_upperImpulse - oldImpulse; + wA += iA * impulse; + wB -= iB * impulse; + } + } + // Solve point-to-point constraint + { + // b2Vec2 Cdot = vB + b2Cross(wB, m_rB) - vA - b2Cross(wA, m_rA); + const Cdot_v2 = b2Vec2.SubVV(b2Vec2.AddVCrossSV(vB, wB, this.m_rB, b2Vec2.s_t0), b2Vec2.AddVCrossSV(vA, wA, this.m_rA, b2Vec2.s_t1), b2RevoluteJoint.SolveVelocityConstraints_s_Cdot_v2); + // b2Vec2 impulse = m_K.Solve(-Cdot); + const impulse_v2 = this.m_K.Solve(-Cdot_v2.x, -Cdot_v2.y, b2RevoluteJoint.SolveVelocityConstraints_s_impulse_v2); + this.m_impulse.x += impulse_v2.x; + this.m_impulse.y += impulse_v2.y; + // vA -= mA * impulse; + vA.SelfMulSub(mA, impulse_v2); + wA -= iA * b2Vec2.CrossVV(this.m_rA, impulse_v2); + // vB += mB * impulse; + vB.SelfMulAdd(mB, impulse_v2); + wB += iB * b2Vec2.CrossVV(this.m_rB, impulse_v2); + } + // data.velocities[this.m_indexA].v = vA; + data.velocities[this.m_indexA].w = wA; + // data.velocities[this.m_indexB].v = vB; + data.velocities[this.m_indexB].w = wB; + } + SolvePositionConstraints(data) { + const cA = data.positions[this.m_indexA].c; + let aA = data.positions[this.m_indexA].a; + const cB = data.positions[this.m_indexB].c; + let aB = data.positions[this.m_indexB].a; + // b2Rot qA(aA), qB(aB); + const qA = this.m_qA.SetAngle(aA), qB = this.m_qB.SetAngle(aB); + let angularError = 0; + let positionError = 0; + const fixedRotation = (this.m_invIA + this.m_invIB === 0); + // Solve angular limit constraint. + if (this.m_enableLimit && !fixedRotation) { + const angle = aB - aA - this.m_referenceAngle; + let C = 0.0; + if (b2Abs(this.m_upperAngle - this.m_lowerAngle) < 2.0 * b2_angularSlop) { + // Prevent large angular corrections + C = b2Clamp(angle - this.m_lowerAngle, -b2_maxAngularCorrection, b2_maxAngularCorrection); + } + else if (angle <= this.m_lowerAngle) { + // Prevent large angular corrections and allow some slop. + C = b2Clamp(angle - this.m_lowerAngle + b2_angularSlop, -b2_maxAngularCorrection, 0.0); + } + else if (angle >= this.m_upperAngle) { + // Prevent large angular corrections and allow some slop. + C = b2Clamp(angle - this.m_upperAngle - b2_angularSlop, 0.0, b2_maxAngularCorrection); + } + const limitImpulse = -this.m_axialMass * C; + aA -= this.m_invIA * limitImpulse; + aB += this.m_invIB * limitImpulse; + angularError = b2Abs(C); + } + // Solve point-to-point constraint. + { + qA.SetAngle(aA); + qB.SetAngle(aB); + // b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); + b2Vec2.SubVV(this.m_localAnchorA, this.m_localCenterA, this.m_lalcA); + const rA = b2Rot.MulRV(qA, this.m_lalcA, this.m_rA); + // b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); + b2Vec2.SubVV(this.m_localAnchorB, this.m_localCenterB, this.m_lalcB); + const rB = b2Rot.MulRV(qB, this.m_lalcB, this.m_rB); + // b2Vec2 C = cB + rB - cA - rA; + const C_v2 = b2Vec2.SubVV(b2Vec2.AddVV(cB, rB, b2Vec2.s_t0), b2Vec2.AddVV(cA, rA, b2Vec2.s_t1), b2RevoluteJoint.SolvePositionConstraints_s_C_v2); + // positionError = C.Length(); + positionError = C_v2.Length(); + const mA = this.m_invMassA, mB = this.m_invMassB; + const iA = this.m_invIA, iB = this.m_invIB; + const K = this.m_K; + K.ex.x = mA + mB + iA * rA.y * rA.y + iB * rB.y * rB.y; + K.ex.y = -iA * rA.x * rA.y - iB * rB.x * rB.y; + K.ey.x = K.ex.y; + K.ey.y = mA + mB + iA * rA.x * rA.x + iB * rB.x * rB.x; + // b2Vec2 impulse = -K.Solve(C); + const impulse = K.Solve(C_v2.x, C_v2.y, b2RevoluteJoint.SolvePositionConstraints_s_impulse).SelfNeg(); + // cA -= mA * impulse; + cA.SelfMulSub(mA, impulse); + aA -= iA * b2Vec2.CrossVV(rA, impulse); + // cB += mB * impulse; + cB.SelfMulAdd(mB, impulse); + aB += iB * b2Vec2.CrossVV(rB, impulse); + } + // data.positions[this.m_indexA].c = cA; + data.positions[this.m_indexA].a = aA; + // data.positions[this.m_indexB].c = cB; + data.positions[this.m_indexB].a = aB; + return positionError <= b2_linearSlop && angularError <= b2_angularSlop; + } + GetAnchorA(out) { + return this.m_bodyA.GetWorldPoint(this.m_localAnchorA, out); + } + GetAnchorB(out) { + return this.m_bodyB.GetWorldPoint(this.m_localAnchorB, out); + } + GetReactionForce(inv_dt, out) { + // b2Vec2 P(this.m_impulse.x, this.m_impulse.y); + // return inv_dt * P; + out.x = inv_dt * this.m_impulse.x; + out.y = inv_dt * this.m_impulse.y; + return out; + } + GetReactionTorque(inv_dt) { + return inv_dt * (this.m_lowerImpulse - this.m_upperImpulse); + } + GetLocalAnchorA() { return this.m_localAnchorA; } + GetLocalAnchorB() { return this.m_localAnchorB; } + GetReferenceAngle() { return this.m_referenceAngle; } + GetJointAngle() { + // b2Body* bA = this.m_bodyA; + // b2Body* bB = this.m_bodyB; + // return bB.this.m_sweep.a - bA.this.m_sweep.a - this.m_referenceAngle; + return this.m_bodyB.m_sweep.a - this.m_bodyA.m_sweep.a - this.m_referenceAngle; + } + GetJointSpeed() { + // b2Body* bA = this.m_bodyA; + // b2Body* bB = this.m_bodyB; + // return bB.this.m_angularVelocity - bA.this.m_angularVelocity; + return this.m_bodyB.m_angularVelocity - this.m_bodyA.m_angularVelocity; + } + IsMotorEnabled() { + return this.m_enableMotor; + } + EnableMotor(flag) { + if (flag !== this.m_enableMotor) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_enableMotor = flag; + } + } + GetMotorTorque(inv_dt) { + return inv_dt * this.m_motorImpulse; + } + GetMotorSpeed() { + return this.m_motorSpeed; + } + SetMaxMotorTorque(torque) { + if (torque !== this.m_maxMotorTorque) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_maxMotorTorque = torque; + } + } + GetMaxMotorTorque() { return this.m_maxMotorTorque; } + IsLimitEnabled() { + return this.m_enableLimit; + } + EnableLimit(flag) { + if (flag !== this.m_enableLimit) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_enableLimit = flag; + this.m_lowerImpulse = 0.0; + this.m_upperImpulse = 0.0; + } + } + GetLowerLimit() { + return this.m_lowerAngle; + } + GetUpperLimit() { + return this.m_upperAngle; + } + SetLimits(lower, upper) { + if (lower !== this.m_lowerAngle || upper !== this.m_upperAngle) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_lowerImpulse = 0.0; + this.m_upperImpulse = 0.0; + this.m_lowerAngle = lower; + this.m_upperAngle = upper; + } + } + SetMotorSpeed(speed) { + if (speed !== this.m_motorSpeed) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_motorSpeed = speed; + } + } + Dump(log) { + const indexA = this.m_bodyA.m_islandIndex; + const indexB = this.m_bodyB.m_islandIndex; + log(" const jd: b2RevoluteJointDef = new b2RevoluteJointDef();\n"); + log(" jd.bodyA = bodies[%d];\n", indexA); + log(" jd.bodyB = bodies[%d];\n", indexB); + log(" jd.collideConnected = %s;\n", (this.m_collideConnected) ? ("true") : ("false")); + log(" jd.localAnchorA.Set(%.15f, %.15f);\n", this.m_localAnchorA.x, this.m_localAnchorA.y); + log(" jd.localAnchorB.Set(%.15f, %.15f);\n", this.m_localAnchorB.x, this.m_localAnchorB.y); + log(" jd.referenceAngle = %.15f;\n", this.m_referenceAngle); + log(" jd.enableLimit = %s;\n", (this.m_enableLimit) ? ("true") : ("false")); + log(" jd.lowerAngle = %.15f;\n", this.m_lowerAngle); + log(" jd.upperAngle = %.15f;\n", this.m_upperAngle); + log(" jd.enableMotor = %s;\n", (this.m_enableMotor) ? ("true") : ("false")); + log(" jd.motorSpeed = %.15f;\n", this.m_motorSpeed); + log(" jd.maxMotorTorque = %.15f;\n", this.m_maxMotorTorque); + log(" joints[%d] = this.m_world.CreateJoint(jd);\n", this.m_index); + } + Draw(draw) { + const xfA = this.m_bodyA.GetTransform(); + const xfB = this.m_bodyB.GetTransform(); + const pA = b2Transform.MulXV(xfA, this.m_localAnchorA, b2RevoluteJoint.Draw_s_pA); + const pB = b2Transform.MulXV(xfB, this.m_localAnchorB, b2RevoluteJoint.Draw_s_pB); + const c1 = b2RevoluteJoint.Draw_s_c1; // b2Color c1(0.7f, 0.7f, 0.7f); + const c2 = b2RevoluteJoint.Draw_s_c2; // b2Color c2(0.3f, 0.9f, 0.3f); + const c3 = b2RevoluteJoint.Draw_s_c3; // b2Color c3(0.9f, 0.3f, 0.3f); + const c4 = b2RevoluteJoint.Draw_s_c4; // b2Color c4(0.3f, 0.3f, 0.9f); + const c5 = b2RevoluteJoint.Draw_s_c5; // b2Color c5(0.4f, 0.4f, 0.4f); + draw.DrawPoint(pA, 5.0, c4); + draw.DrawPoint(pB, 5.0, c5); + const aA = this.m_bodyA.GetAngle(); + const aB = this.m_bodyB.GetAngle(); + const angle = aB - aA - this.m_referenceAngle; + const L = 0.5; + // b2Vec2 r = L * b2Vec2(Math.cos(angle), Math.sin(angle)); + const r = b2RevoluteJoint.Draw_s_r.Set(L * Math.cos(angle), L * Math.sin(angle)); + // draw.DrawSegment(pB, pB + r, c1); + draw.DrawSegment(pB, b2Vec2.AddVV(pB, r, b2Vec2.s_t0), c1); + draw.DrawCircle(pB, L, c1); + if (this.m_enableLimit) { + // b2Vec2 rlo = L * b2Vec2(Math.cos(m_lowerAngle), Math.sin(m_lowerAngle)); + const rlo = b2RevoluteJoint.Draw_s_rlo.Set(L * Math.cos(this.m_lowerAngle), L * Math.sin(this.m_lowerAngle)); + // b2Vec2 rhi = L * b2Vec2(Math.cos(m_upperAngle), Math.sin(m_upperAngle)); + const rhi = b2RevoluteJoint.Draw_s_rhi.Set(L * Math.cos(this.m_upperAngle), L * Math.sin(this.m_upperAngle)); + // draw.DrawSegment(pB, pB + rlo, c2); + draw.DrawSegment(pB, b2Vec2.AddVV(pB, rlo, b2Vec2.s_t0), c2); + // draw.DrawSegment(pB, pB + rhi, c3); + draw.DrawSegment(pB, b2Vec2.AddVV(pB, rhi, b2Vec2.s_t0), c3); + } + const color = b2RevoluteJoint.Draw_s_color_; // b2Color color(0.5f, 0.8f, 0.8f); + draw.DrawSegment(xfA.p, pA, color); + draw.DrawSegment(pA, pB, color); + draw.DrawSegment(xfB.p, pB, color); + } + } + b2RevoluteJoint.InitVelocityConstraints_s_P = new b2Vec2(); + // private static SolveVelocityConstraints_s_P: b2Vec2 = new b2Vec2(); + b2RevoluteJoint.SolveVelocityConstraints_s_Cdot_v2 = new b2Vec2(); + // private static SolveVelocityConstraints_s_Cdot1: b2Vec2 = new b2Vec2(); + // private static SolveVelocityConstraints_s_impulse_v3: b2Vec3 = new b2Vec3(); + // private static SolveVelocityConstraints_s_reduced_v2: b2Vec2 = new b2Vec2(); + b2RevoluteJoint.SolveVelocityConstraints_s_impulse_v2 = new b2Vec2(); + b2RevoluteJoint.SolvePositionConstraints_s_C_v2 = new b2Vec2(); + b2RevoluteJoint.SolvePositionConstraints_s_impulse = new b2Vec2(); + b2RevoluteJoint.Draw_s_pA = new b2Vec2(); + b2RevoluteJoint.Draw_s_pB = new b2Vec2(); + b2RevoluteJoint.Draw_s_c1 = new b2Color(0.7, 0.7, 0.7); + b2RevoluteJoint.Draw_s_c2 = new b2Color(0.3, 0.9, 0.3); + b2RevoluteJoint.Draw_s_c3 = new b2Color(0.9, 0.3, 0.3); + b2RevoluteJoint.Draw_s_c4 = new b2Color(0.3, 0.3, 0.9); + b2RevoluteJoint.Draw_s_c5 = new b2Color(0.4, 0.4, 0.4); + b2RevoluteJoint.Draw_s_color_ = new b2Color(0.5, 0.8, 0.8); + b2RevoluteJoint.Draw_s_r = new b2Vec2(); + b2RevoluteJoint.Draw_s_rlo = new b2Vec2(); + b2RevoluteJoint.Draw_s_rhi = new b2Vec2(); + + /* + * Copyright (c) 2006-2011 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// Weld joint definition. You need to specify local anchor points + /// where they are attached and the relative body angle. The position + /// of the anchor points is important for computing the reaction torque. + class b2WeldJointDef extends b2JointDef { + constructor() { + super(exports.b2JointType.e_weldJoint); + this.localAnchorA = new b2Vec2(); + this.localAnchorB = new b2Vec2(); + this.referenceAngle = 0; + this.stiffness = 0; + this.damping = 0; + } + Initialize(bA, bB, anchor) { + this.bodyA = bA; + this.bodyB = bB; + this.bodyA.GetLocalPoint(anchor, this.localAnchorA); + this.bodyB.GetLocalPoint(anchor, this.localAnchorB); + this.referenceAngle = this.bodyB.GetAngle() - this.bodyA.GetAngle(); + } + } + class b2WeldJoint extends b2Joint { + constructor(def) { + super(def); + this.m_stiffness = 0; + this.m_damping = 0; + this.m_bias = 0; + // Solver shared + this.m_localAnchorA = new b2Vec2(); + this.m_localAnchorB = new b2Vec2(); + this.m_referenceAngle = 0; + this.m_gamma = 0; + this.m_impulse = new b2Vec3(0, 0, 0); + // Solver temp + this.m_indexA = 0; + this.m_indexB = 0; + this.m_rA = new b2Vec2(); + this.m_rB = new b2Vec2(); + this.m_localCenterA = new b2Vec2(); + this.m_localCenterB = new b2Vec2(); + this.m_invMassA = 0; + this.m_invMassB = 0; + this.m_invIA = 0; + this.m_invIB = 0; + this.m_mass = new b2Mat33(); + this.m_qA = new b2Rot(); + this.m_qB = new b2Rot(); + this.m_lalcA = new b2Vec2(); + this.m_lalcB = new b2Vec2(); + this.m_K = new b2Mat33(); + this.m_stiffness = b2Maybe(def.stiffness, 0); + this.m_damping = b2Maybe(def.damping, 0); + this.m_localAnchorA.Copy(b2Maybe(def.localAnchorA, b2Vec2.ZERO)); + this.m_localAnchorB.Copy(b2Maybe(def.localAnchorB, b2Vec2.ZERO)); + this.m_referenceAngle = b2Maybe(def.referenceAngle, 0); + this.m_impulse.SetZero(); + } + InitVelocityConstraints(data) { + this.m_indexA = this.m_bodyA.m_islandIndex; + this.m_indexB = this.m_bodyB.m_islandIndex; + this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter); + this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter); + this.m_invMassA = this.m_bodyA.m_invMass; + this.m_invMassB = this.m_bodyB.m_invMass; + this.m_invIA = this.m_bodyA.m_invI; + this.m_invIB = this.m_bodyB.m_invI; + const aA = data.positions[this.m_indexA].a; + const vA = data.velocities[this.m_indexA].v; + let wA = data.velocities[this.m_indexA].w; + const aB = data.positions[this.m_indexB].a; + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + const qA = this.m_qA.SetAngle(aA), qB = this.m_qB.SetAngle(aB); + // m_rA = b2Mul(qA, m_localAnchorA - m_localCenterA); + b2Vec2.SubVV(this.m_localAnchorA, this.m_localCenterA, this.m_lalcA); + b2Rot.MulRV(qA, this.m_lalcA, this.m_rA); + // m_rB = b2Mul(qB, m_localAnchorB - m_localCenterB); + b2Vec2.SubVV(this.m_localAnchorB, this.m_localCenterB, this.m_lalcB); + b2Rot.MulRV(qB, this.m_lalcB, this.m_rB); + // J = [-I -r1_skew I r2_skew] + // [ 0 -1 0 1] + // r_skew = [-ry; rx] + // Matlab + // K = [ mA+r1y^2*iA+mB+r2y^2*iB, -r1y*iA*r1x-r2y*iB*r2x, -r1y*iA-r2y*iB] + // [ -r1y*iA*r1x-r2y*iB*r2x, mA+r1x^2*iA+mB+r2x^2*iB, r1x*iA+r2x*iB] + // [ -r1y*iA-r2y*iB, r1x*iA+r2x*iB, iA+iB] + const mA = this.m_invMassA, mB = this.m_invMassB; + const iA = this.m_invIA, iB = this.m_invIB; + const K = this.m_K; + K.ex.x = mA + mB + this.m_rA.y * this.m_rA.y * iA + this.m_rB.y * this.m_rB.y * iB; + K.ey.x = -this.m_rA.y * this.m_rA.x * iA - this.m_rB.y * this.m_rB.x * iB; + K.ez.x = -this.m_rA.y * iA - this.m_rB.y * iB; + K.ex.y = K.ey.x; + K.ey.y = mA + mB + this.m_rA.x * this.m_rA.x * iA + this.m_rB.x * this.m_rB.x * iB; + K.ez.y = this.m_rA.x * iA + this.m_rB.x * iB; + K.ex.z = K.ez.x; + K.ey.z = K.ez.y; + K.ez.z = iA + iB; + if (this.m_stiffness > 0) { + K.GetInverse22(this.m_mass); + let invM = iA + iB; + const C = aB - aA - this.m_referenceAngle; + // Damping coefficient + const d = this.m_damping; + // Spring stiffness + const k = this.m_stiffness; + // magic formulas + const h = data.step.dt; + this.m_gamma = h * (d + h * k); + this.m_gamma = this.m_gamma !== 0 ? 1 / this.m_gamma : 0; + this.m_bias = C * h * k * this.m_gamma; + invM += this.m_gamma; + this.m_mass.ez.z = invM !== 0 ? 1 / invM : 0; + } + else { + K.GetSymInverse33(this.m_mass); + this.m_gamma = 0; + this.m_bias = 0; + } + if (data.step.warmStarting) { + // Scale impulses to support a variable time step. + this.m_impulse.SelfMul(data.step.dtRatio); + // b2Vec2 P(m_impulse.x, m_impulse.y); + const P = b2WeldJoint.InitVelocityConstraints_s_P.Set(this.m_impulse.x, this.m_impulse.y); + // vA -= mA * P; + vA.SelfMulSub(mA, P); + wA -= iA * (b2Vec2.CrossVV(this.m_rA, P) + this.m_impulse.z); + // vB += mB * P; + vB.SelfMulAdd(mB, P); + wB += iB * (b2Vec2.CrossVV(this.m_rB, P) + this.m_impulse.z); + } + else { + this.m_impulse.SetZero(); + } + // data.velocities[this.m_indexA].v = vA; + data.velocities[this.m_indexA].w = wA; + // data.velocities[this.m_indexB].v = vB; + data.velocities[this.m_indexB].w = wB; + } + SolveVelocityConstraints(data) { + const vA = data.velocities[this.m_indexA].v; + let wA = data.velocities[this.m_indexA].w; + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + const mA = this.m_invMassA, mB = this.m_invMassB; + const iA = this.m_invIA, iB = this.m_invIB; + if (this.m_stiffness > 0) { + const Cdot2 = wB - wA; + const impulse2 = -this.m_mass.ez.z * (Cdot2 + this.m_bias + this.m_gamma * this.m_impulse.z); + this.m_impulse.z += impulse2; + wA -= iA * impulse2; + wB += iB * impulse2; + // b2Vec2 Cdot1 = vB + b2Vec2.CrossSV(wB, this.m_rB) - vA - b2Vec2.CrossSV(wA, this.m_rA); + const Cdot1 = b2Vec2.SubVV(b2Vec2.AddVCrossSV(vB, wB, this.m_rB, b2Vec2.s_t0), b2Vec2.AddVCrossSV(vA, wA, this.m_rA, b2Vec2.s_t1), b2WeldJoint.SolveVelocityConstraints_s_Cdot1); + // b2Vec2 impulse1 = -b2Mul22(m_mass, Cdot1); + const impulse1 = b2Mat33.MulM33XY(this.m_mass, Cdot1.x, Cdot1.y, b2WeldJoint.SolveVelocityConstraints_s_impulse1).SelfNeg(); + this.m_impulse.x += impulse1.x; + this.m_impulse.y += impulse1.y; + // b2Vec2 P = impulse1; + const P = impulse1; + // vA -= mA * P; + vA.SelfMulSub(mA, P); + // wA -= iA * b2Cross(m_rA, P); + wA -= iA * b2Vec2.CrossVV(this.m_rA, P); + // vB += mB * P; + vB.SelfMulAdd(mB, P); + // wB += iB * b2Cross(m_rB, P); + wB += iB * b2Vec2.CrossVV(this.m_rB, P); + } + else { + // b2Vec2 Cdot1 = vB + b2Cross(wB, this.m_rB) - vA - b2Cross(wA, this.m_rA); + const Cdot1 = b2Vec2.SubVV(b2Vec2.AddVCrossSV(vB, wB, this.m_rB, b2Vec2.s_t0), b2Vec2.AddVCrossSV(vA, wA, this.m_rA, b2Vec2.s_t1), b2WeldJoint.SolveVelocityConstraints_s_Cdot1); + const Cdot2 = wB - wA; + // b2Vec3 const Cdot(Cdot1.x, Cdot1.y, Cdot2); + // b2Vec3 impulse = -b2Mul(m_mass, Cdot); + const impulse = b2Mat33.MulM33XYZ(this.m_mass, Cdot1.x, Cdot1.y, Cdot2, b2WeldJoint.SolveVelocityConstraints_s_impulse).SelfNeg(); + this.m_impulse.SelfAdd(impulse); + // b2Vec2 P(impulse.x, impulse.y); + const P = b2WeldJoint.SolveVelocityConstraints_s_P.Set(impulse.x, impulse.y); + // vA -= mA * P; + vA.SelfMulSub(mA, P); + wA -= iA * (b2Vec2.CrossVV(this.m_rA, P) + impulse.z); + // vB += mB * P; + vB.SelfMulAdd(mB, P); + wB += iB * (b2Vec2.CrossVV(this.m_rB, P) + impulse.z); + } + // data.velocities[this.m_indexA].v = vA; + data.velocities[this.m_indexA].w = wA; + // data.velocities[this.m_indexB].v = vB; + data.velocities[this.m_indexB].w = wB; + } + SolvePositionConstraints(data) { + const cA = data.positions[this.m_indexA].c; + let aA = data.positions[this.m_indexA].a; + const cB = data.positions[this.m_indexB].c; + let aB = data.positions[this.m_indexB].a; + const qA = this.m_qA.SetAngle(aA), qB = this.m_qB.SetAngle(aB); + const mA = this.m_invMassA, mB = this.m_invMassB; + const iA = this.m_invIA, iB = this.m_invIB; + // b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); + b2Vec2.SubVV(this.m_localAnchorA, this.m_localCenterA, this.m_lalcA); + const rA = b2Rot.MulRV(qA, this.m_lalcA, this.m_rA); + // b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); + b2Vec2.SubVV(this.m_localAnchorB, this.m_localCenterB, this.m_lalcB); + const rB = b2Rot.MulRV(qB, this.m_lalcB, this.m_rB); + let positionError, angularError; + const K = this.m_K; + K.ex.x = mA + mB + rA.y * rA.y * iA + rB.y * rB.y * iB; + K.ey.x = -rA.y * rA.x * iA - rB.y * rB.x * iB; + K.ez.x = -rA.y * iA - rB.y * iB; + K.ex.y = K.ey.x; + K.ey.y = mA + mB + rA.x * rA.x * iA + rB.x * rB.x * iB; + K.ez.y = rA.x * iA + rB.x * iB; + K.ex.z = K.ez.x; + K.ey.z = K.ez.y; + K.ez.z = iA + iB; + if (this.m_stiffness > 0) { + // b2Vec2 C1 = cB + rB - cA - rA; + const C1 = b2Vec2.SubVV(b2Vec2.AddVV(cB, rB, b2Vec2.s_t0), b2Vec2.AddVV(cA, rA, b2Vec2.s_t1), b2WeldJoint.SolvePositionConstraints_s_C1); + positionError = C1.Length(); + angularError = 0; + // b2Vec2 P = -K.Solve22(C1); + const P = K.Solve22(C1.x, C1.y, b2WeldJoint.SolvePositionConstraints_s_P).SelfNeg(); + // cA -= mA * P; + cA.SelfMulSub(mA, P); + aA -= iA * b2Vec2.CrossVV(rA, P); + // cB += mB * P; + cB.SelfMulAdd(mB, P); + aB += iB * b2Vec2.CrossVV(rB, P); + } + else { + // b2Vec2 C1 = cB + rB - cA - rA; + const C1 = b2Vec2.SubVV(b2Vec2.AddVV(cB, rB, b2Vec2.s_t0), b2Vec2.AddVV(cA, rA, b2Vec2.s_t1), b2WeldJoint.SolvePositionConstraints_s_C1); + const C2 = aB - aA - this.m_referenceAngle; + positionError = C1.Length(); + angularError = b2Abs(C2); + // b2Vec3 C(C1.x, C1.y, C2); + // b2Vec3 impulse = -K.Solve33(C); + const impulse = K.Solve33(C1.x, C1.y, C2, b2WeldJoint.SolvePositionConstraints_s_impulse).SelfNeg(); + // b2Vec2 P(impulse.x, impulse.y); + const P = b2WeldJoint.SolvePositionConstraints_s_P.Set(impulse.x, impulse.y); + // cA -= mA * P; + cA.SelfMulSub(mA, P); + aA -= iA * (b2Vec2.CrossVV(this.m_rA, P) + impulse.z); + // cB += mB * P; + cB.SelfMulAdd(mB, P); + aB += iB * (b2Vec2.CrossVV(this.m_rB, P) + impulse.z); + } + // data.positions[this.m_indexA].c = cA; + data.positions[this.m_indexA].a = aA; + // data.positions[this.m_indexB].c = cB; + data.positions[this.m_indexB].a = aB; + return positionError <= b2_linearSlop && angularError <= b2_angularSlop; + } + GetAnchorA(out) { + return this.m_bodyA.GetWorldPoint(this.m_localAnchorA, out); + } + GetAnchorB(out) { + return this.m_bodyB.GetWorldPoint(this.m_localAnchorB, out); + } + GetReactionForce(inv_dt, out) { + // b2Vec2 P(this.m_impulse.x, this.m_impulse.y); + // return inv_dt * P; + out.x = inv_dt * this.m_impulse.x; + out.y = inv_dt * this.m_impulse.y; + return out; + } + GetReactionTorque(inv_dt) { + return inv_dt * this.m_impulse.z; + } + GetLocalAnchorA() { return this.m_localAnchorA; } + GetLocalAnchorB() { return this.m_localAnchorB; } + GetReferenceAngle() { return this.m_referenceAngle; } + SetStiffness(stiffness) { this.m_stiffness = stiffness; } + GetStiffness() { return this.m_stiffness; } + SetDamping(damping) { this.m_damping = damping; } + GetDamping() { return this.m_damping; } + Dump(log) { + const indexA = this.m_bodyA.m_islandIndex; + const indexB = this.m_bodyB.m_islandIndex; + log(" const jd: b2WeldJointDef = new b2WeldJointDef();\n"); + log(" jd.bodyA = bodies[%d];\n", indexA); + log(" jd.bodyB = bodies[%d];\n", indexB); + log(" jd.collideConnected = %s;\n", (this.m_collideConnected) ? ("true") : ("false")); + log(" jd.localAnchorA.Set(%.15f, %.15f);\n", this.m_localAnchorA.x, this.m_localAnchorA.y); + log(" jd.localAnchorB.Set(%.15f, %.15f);\n", this.m_localAnchorB.x, this.m_localAnchorB.y); + log(" jd.referenceAngle = %.15f;\n", this.m_referenceAngle); + log(" jd.stiffness = %.15f;\n", this.m_stiffness); + log(" jd.damping = %.15f;\n", this.m_damping); + log(" joints[%d] = this.m_world.CreateJoint(jd);\n", this.m_index); + } + } + b2WeldJoint.InitVelocityConstraints_s_P = new b2Vec2(); + b2WeldJoint.SolveVelocityConstraints_s_Cdot1 = new b2Vec2(); + b2WeldJoint.SolveVelocityConstraints_s_impulse1 = new b2Vec2(); + b2WeldJoint.SolveVelocityConstraints_s_impulse = new b2Vec3(); + b2WeldJoint.SolveVelocityConstraints_s_P = new b2Vec2(); + b2WeldJoint.SolvePositionConstraints_s_C1 = new b2Vec2(); + b2WeldJoint.SolvePositionConstraints_s_P = new b2Vec2(); + b2WeldJoint.SolvePositionConstraints_s_impulse = new b2Vec3(); + + /* + * Copyright (c) 2006-2011 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// Wheel joint definition. This requires defining a line of + /// motion using an axis and an anchor point. The definition uses local + /// anchor points and a local axis so that the initial configuration + /// can violate the constraint slightly. The joint translation is zero + /// when the local anchor points coincide in world space. Using local + /// anchors and a local axis helps when saving and loading a game. + class b2WheelJointDef extends b2JointDef { + constructor() { + super(exports.b2JointType.e_wheelJoint); + this.localAnchorA = new b2Vec2(0, 0); + this.localAnchorB = new b2Vec2(0, 0); + this.localAxisA = new b2Vec2(1, 0); + this.enableLimit = false; + this.lowerTranslation = 0; + this.upperTranslation = 0; + this.enableMotor = false; + this.maxMotorTorque = 0; + this.motorSpeed = 0; + this.stiffness = 0; + this.damping = 0; + } + Initialize(bA, bB, anchor, axis) { + this.bodyA = bA; + this.bodyB = bB; + this.bodyA.GetLocalPoint(anchor, this.localAnchorA); + this.bodyB.GetLocalPoint(anchor, this.localAnchorB); + this.bodyA.GetLocalVector(axis, this.localAxisA); + } + } + class b2WheelJoint extends b2Joint { + constructor(def) { + super(def); + this.m_localAnchorA = new b2Vec2(); + this.m_localAnchorB = new b2Vec2(); + this.m_localXAxisA = new b2Vec2(); + this.m_localYAxisA = new b2Vec2(); + this.m_impulse = 0; + this.m_motorImpulse = 0; + this.m_springImpulse = 0; + this.m_lowerImpulse = 0; + this.m_upperImpulse = 0; + this.m_translation = 0; + this.m_lowerTranslation = 0; + this.m_upperTranslation = 0; + this.m_maxMotorTorque = 0; + this.m_motorSpeed = 0; + this.m_enableLimit = false; + this.m_enableMotor = false; + this.m_stiffness = 0; + this.m_damping = 0; + // Solver temp + this.m_indexA = 0; + this.m_indexB = 0; + this.m_localCenterA = new b2Vec2(); + this.m_localCenterB = new b2Vec2(); + this.m_invMassA = 0; + this.m_invMassB = 0; + this.m_invIA = 0; + this.m_invIB = 0; + this.m_ax = new b2Vec2(); + this.m_ay = new b2Vec2(); + this.m_sAx = 0; + this.m_sBx = 0; + this.m_sAy = 0; + this.m_sBy = 0; + this.m_mass = 0; + this.m_motorMass = 0; + this.m_axialMass = 0; + this.m_springMass = 0; + this.m_bias = 0; + this.m_gamma = 0; + this.m_qA = new b2Rot(); + this.m_qB = new b2Rot(); + this.m_lalcA = new b2Vec2(); + this.m_lalcB = new b2Vec2(); + this.m_rA = new b2Vec2(); + this.m_rB = new b2Vec2(); + this.m_localAnchorA.Copy(b2Maybe(def.localAnchorA, b2Vec2.ZERO)); + this.m_localAnchorB.Copy(b2Maybe(def.localAnchorB, b2Vec2.ZERO)); + this.m_localXAxisA.Copy(b2Maybe(def.localAxisA, b2Vec2.UNITX)); + b2Vec2.CrossOneV(this.m_localXAxisA, this.m_localYAxisA); + this.m_lowerTranslation = b2Maybe(def.lowerTranslation, 0); + this.m_upperTranslation = b2Maybe(def.upperTranslation, 0); + this.m_enableLimit = b2Maybe(def.enableLimit, false); + this.m_maxMotorTorque = b2Maybe(def.maxMotorTorque, 0); + this.m_motorSpeed = b2Maybe(def.motorSpeed, 0); + this.m_enableMotor = b2Maybe(def.enableMotor, false); + this.m_ax.SetZero(); + this.m_ay.SetZero(); + this.m_stiffness = b2Maybe(def.stiffness, 0); + this.m_damping = b2Maybe(def.damping, 0); + } + GetMotorSpeed() { + return this.m_motorSpeed; + } + GetMaxMotorTorque() { + return this.m_maxMotorTorque; + } + SetStiffness(hz) { + this.m_stiffness = hz; + } + GetStiffness() { + return this.m_stiffness; + } + SetDamping(ratio) { + this.m_damping = ratio; + } + GetDamping() { + return this.m_damping; + } + InitVelocityConstraints(data) { + this.m_indexA = this.m_bodyA.m_islandIndex; + this.m_indexB = this.m_bodyB.m_islandIndex; + this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter); + this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter); + this.m_invMassA = this.m_bodyA.m_invMass; + this.m_invMassB = this.m_bodyB.m_invMass; + this.m_invIA = this.m_bodyA.m_invI; + this.m_invIB = this.m_bodyB.m_invI; + const mA = this.m_invMassA, mB = this.m_invMassB; + const iA = this.m_invIA, iB = this.m_invIB; + const cA = data.positions[this.m_indexA].c; + const aA = data.positions[this.m_indexA].a; + const vA = data.velocities[this.m_indexA].v; + let wA = data.velocities[this.m_indexA].w; + const cB = data.positions[this.m_indexB].c; + const aB = data.positions[this.m_indexB].a; + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + const qA = this.m_qA.SetAngle(aA), qB = this.m_qB.SetAngle(aB); + // Compute the effective masses. + // b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); + b2Vec2.SubVV(this.m_localAnchorA, this.m_localCenterA, this.m_lalcA); + const rA = b2Rot.MulRV(qA, this.m_lalcA, this.m_rA); + // b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); + b2Vec2.SubVV(this.m_localAnchorB, this.m_localCenterB, this.m_lalcB); + const rB = b2Rot.MulRV(qB, this.m_lalcB, this.m_rB); + // b2Vec2 d = cB + rB - cA - rA; + const d = b2Vec2.SubVV(b2Vec2.AddVV(cB, rB, b2Vec2.s_t0), b2Vec2.AddVV(cA, rA, b2Vec2.s_t1), b2WheelJoint.InitVelocityConstraints_s_d); + // Point to line constraint + { + // m_ay = b2Mul(qA, m_localYAxisA); + b2Rot.MulRV(qA, this.m_localYAxisA, this.m_ay); + // m_sAy = b2Cross(d + rA, m_ay); + this.m_sAy = b2Vec2.CrossVV(b2Vec2.AddVV(d, rA, b2Vec2.s_t0), this.m_ay); + // m_sBy = b2Cross(rB, m_ay); + this.m_sBy = b2Vec2.CrossVV(rB, this.m_ay); + this.m_mass = mA + mB + iA * this.m_sAy * this.m_sAy + iB * this.m_sBy * this.m_sBy; + if (this.m_mass > 0) { + this.m_mass = 1 / this.m_mass; + } + } + // Spring constraint + b2Rot.MulRV(qA, this.m_localXAxisA, this.m_ax); // m_ax = b2Mul(qA, m_localXAxisA); + this.m_sAx = b2Vec2.CrossVV(b2Vec2.AddVV(d, rA, b2Vec2.s_t0), this.m_ax); + this.m_sBx = b2Vec2.CrossVV(rB, this.m_ax); + const invMass = mA + mB + iA * this.m_sAx * this.m_sAx + iB * this.m_sBx * this.m_sBx; + if (invMass > 0.0) { + this.m_axialMass = 1.0 / invMass; + } + else { + this.m_axialMass = 0.0; + } + this.m_springMass = 0; + this.m_bias = 0; + this.m_gamma = 0; + if (this.m_stiffness > 0.0 && invMass > 0.0) { + this.m_springMass = 1.0 / invMass; + const C = b2Vec2.DotVV(d, this.m_ax); + // magic formulas + const h = data.step.dt; + this.m_gamma = h * (this.m_damping + h * this.m_stiffness); + if (this.m_gamma > 0.0) { + this.m_gamma = 1.0 / this.m_gamma; + } + this.m_bias = C * h * this.m_stiffness * this.m_gamma; + this.m_springMass = invMass + this.m_gamma; + if (this.m_springMass > 0.0) { + this.m_springMass = 1.0 / this.m_springMass; + } + } + else { + this.m_springImpulse = 0.0; + } + if (this.m_enableLimit) { + this.m_translation = b2Vec2.DotVV(this.m_ax, d); + } + else { + this.m_lowerImpulse = 0.0; + this.m_upperImpulse = 0.0; + } + if (this.m_enableMotor) { + this.m_motorMass = iA + iB; + if (this.m_motorMass > 0) { + this.m_motorMass = 1 / this.m_motorMass; + } + } + else { + this.m_motorMass = 0; + this.m_motorImpulse = 0; + } + if (data.step.warmStarting) { + // Account for variable time step. + this.m_impulse *= data.step.dtRatio; + this.m_springImpulse *= data.step.dtRatio; + this.m_motorImpulse *= data.step.dtRatio; + const axialImpulse = this.m_springImpulse + this.m_lowerImpulse - this.m_upperImpulse; + // b2Vec2 P = m_impulse * m_ay + m_springImpulse * m_ax; + const P = b2Vec2.AddVV(b2Vec2.MulSV(this.m_impulse, this.m_ay, b2Vec2.s_t0), b2Vec2.MulSV(axialImpulse, this.m_ax, b2Vec2.s_t1), b2WheelJoint.InitVelocityConstraints_s_P); + // float32 LA = m_impulse * m_sAy + m_springImpulse * m_sAx + m_motorImpulse; + const LA = this.m_impulse * this.m_sAy + axialImpulse * this.m_sAx + this.m_motorImpulse; + // float32 LB = m_impulse * m_sBy + m_springImpulse * m_sBx + m_motorImpulse; + const LB = this.m_impulse * this.m_sBy + axialImpulse * this.m_sBx + this.m_motorImpulse; + // vA -= m_invMassA * P; + vA.SelfMulSub(this.m_invMassA, P); + wA -= this.m_invIA * LA; + // vB += m_invMassB * P; + vB.SelfMulAdd(this.m_invMassB, P); + wB += this.m_invIB * LB; + } + else { + this.m_impulse = 0; + this.m_springImpulse = 0; + this.m_motorImpulse = 0; + this.m_lowerImpulse = 0; + this.m_upperImpulse = 0; + } + // data.velocities[this.m_indexA].v = vA; + data.velocities[this.m_indexA].w = wA; + // data.velocities[this.m_indexB].v = vB; + data.velocities[this.m_indexB].w = wB; + } + SolveVelocityConstraints(data) { + const mA = this.m_invMassA, mB = this.m_invMassB; + const iA = this.m_invIA, iB = this.m_invIB; + const vA = data.velocities[this.m_indexA].v; + let wA = data.velocities[this.m_indexA].w; + const vB = data.velocities[this.m_indexB].v; + let wB = data.velocities[this.m_indexB].w; + // Solve spring constraint + { + const Cdot = b2Vec2.DotVV(this.m_ax, b2Vec2.SubVV(vB, vA, b2Vec2.s_t0)) + this.m_sBx * wB - this.m_sAx * wA; + const impulse = -this.m_springMass * (Cdot + this.m_bias + this.m_gamma * this.m_springImpulse); + this.m_springImpulse += impulse; + // b2Vec2 P = impulse * m_ax; + const P = b2Vec2.MulSV(impulse, this.m_ax, b2WheelJoint.SolveVelocityConstraints_s_P); + const LA = impulse * this.m_sAx; + const LB = impulse * this.m_sBx; + // vA -= mA * P; + vA.SelfMulSub(mA, P); + wA -= iA * LA; + // vB += mB * P; + vB.SelfMulAdd(mB, P); + wB += iB * LB; + } + // Solve rotational motor constraint + { + const Cdot = wB - wA - this.m_motorSpeed; + let impulse = -this.m_motorMass * Cdot; + const oldImpulse = this.m_motorImpulse; + const maxImpulse = data.step.dt * this.m_maxMotorTorque; + this.m_motorImpulse = b2Clamp(this.m_motorImpulse + impulse, -maxImpulse, maxImpulse); + impulse = this.m_motorImpulse - oldImpulse; + wA -= iA * impulse; + wB += iB * impulse; + } + if (this.m_enableLimit) { + // Lower limit + { + const C = this.m_translation - this.m_lowerTranslation; + const Cdot = b2Vec2.DotVV(this.m_ax, b2Vec2.SubVV(vB, vA, b2Vec2.s_t0)) + this.m_sBx * wB - this.m_sAx * wA; + let impulse = -this.m_axialMass * (Cdot + b2Max(C, 0.0) * data.step.inv_dt); + const oldImpulse = this.m_lowerImpulse; + this.m_lowerImpulse = b2Max(this.m_lowerImpulse + impulse, 0.0); + impulse = this.m_lowerImpulse - oldImpulse; + // b2Vec2 P = impulse * this.m_ax; + const P = b2Vec2.MulSV(impulse, this.m_ax, b2WheelJoint.SolveVelocityConstraints_s_P); + const LA = impulse * this.m_sAx; + const LB = impulse * this.m_sBx; + // vA -= mA * P; + vA.SelfMulSub(mA, P); + wA -= iA * LA; + // vB += mB * P; + vB.SelfMulAdd(mB, P); + wB += iB * LB; + } + // Upper limit + // Note: signs are flipped to keep C positive when the constraint is satisfied. + // This also keeps the impulse positive when the limit is active. + { + const C = this.m_upperTranslation - this.m_translation; + const Cdot = b2Vec2.DotVV(this.m_ax, b2Vec2.SubVV(vA, vB, b2Vec2.s_t0)) + this.m_sAx * wA - this.m_sBx * wB; + let impulse = -this.m_axialMass * (Cdot + b2Max(C, 0.0) * data.step.inv_dt); + const oldImpulse = this.m_upperImpulse; + this.m_upperImpulse = b2Max(this.m_upperImpulse + impulse, 0.0); + impulse = this.m_upperImpulse - oldImpulse; + // b2Vec2 P = impulse * this.m_ax; + const P = b2Vec2.MulSV(impulse, this.m_ax, b2WheelJoint.SolveVelocityConstraints_s_P); + const LA = impulse * this.m_sAx; + const LB = impulse * this.m_sBx; + // vA += mA * P; + vA.SelfMulAdd(mA, P); + wA += iA * LA; + // vB -= mB * P; + vB.SelfMulSub(mB, P); + wB -= iB * LB; + } + } + // Solve point to line constraint + { + const Cdot = b2Vec2.DotVV(this.m_ay, b2Vec2.SubVV(vB, vA, b2Vec2.s_t0)) + this.m_sBy * wB - this.m_sAy * wA; + const impulse = -this.m_mass * Cdot; + this.m_impulse += impulse; + // b2Vec2 P = impulse * m_ay; + const P = b2Vec2.MulSV(impulse, this.m_ay, b2WheelJoint.SolveVelocityConstraints_s_P); + const LA = impulse * this.m_sAy; + const LB = impulse * this.m_sBy; + // vA -= mA * P; + vA.SelfMulSub(mA, P); + wA -= iA * LA; + // vB += mB * P; + vB.SelfMulAdd(mB, P); + wB += iB * LB; + } + // data.velocities[this.m_indexA].v = vA; + data.velocities[this.m_indexA].w = wA; + // data.velocities[this.m_indexB].v = vB; + data.velocities[this.m_indexB].w = wB; + } + SolvePositionConstraints(data) { + const cA = data.positions[this.m_indexA].c; + let aA = data.positions[this.m_indexA].a; + const cB = data.positions[this.m_indexB].c; + let aB = data.positions[this.m_indexB].a; + // const qA: b2Rot = this.m_qA.SetAngle(aA), qB: b2Rot = this.m_qB.SetAngle(aB); + // // b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); + // b2Vec2.SubVV(this.m_localAnchorA, this.m_localCenterA, this.m_lalcA); + // const rA: b2Vec2 = b2Rot.MulRV(qA, this.m_lalcA, this.m_rA); + // // b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); + // b2Vec2.SubVV(this.m_localAnchorB, this.m_localCenterB, this.m_lalcB); + // const rB: b2Vec2 = b2Rot.MulRV(qB, this.m_lalcB, this.m_rB); + // // b2Vec2 d = (cB - cA) + rB - rA; + // const d: b2Vec2 = b2Vec2.AddVV( + // b2Vec2.SubVV(cB, cA, b2Vec2.s_t0), + // b2Vec2.SubVV(rB, rA, b2Vec2.s_t1), + // b2WheelJoint.SolvePositionConstraints_s_d); + // // b2Vec2 ay = b2Mul(qA, m_localYAxisA); + // const ay: b2Vec2 = b2Rot.MulRV(qA, this.m_localYAxisA, this.m_ay); + // // float32 sAy = b2Cross(d + rA, ay); + // const sAy = b2Vec2.CrossVV(b2Vec2.AddVV(d, rA, b2Vec2.s_t0), ay); + // // float32 sBy = b2Cross(rB, ay); + // const sBy = b2Vec2.CrossVV(rB, ay); + // // float32 C = b2Dot(d, ay); + // const C: number = b2Vec2.DotVV(d, this.m_ay); + // const k: number = this.m_invMassA + this.m_invMassB + this.m_invIA * this.m_sAy * this.m_sAy + this.m_invIB * this.m_sBy * this.m_sBy; + // let impulse: number; + // if (k !== 0) { + // impulse = - C / k; + // } else { + // impulse = 0; + // } + // // b2Vec2 P = impulse * ay; + // const P: b2Vec2 = b2Vec2.MulSV(impulse, ay, b2WheelJoint.SolvePositionConstraints_s_P); + // const LA: number = impulse * sAy; + // const LB: number = impulse * sBy; + // // cA -= m_invMassA * P; + // cA.SelfMulSub(this.m_invMassA, P); + // aA -= this.m_invIA * LA; + // // cB += m_invMassB * P; + // cB.SelfMulAdd(this.m_invMassB, P); + // aB += this.m_invIB * LB; + let linearError = 0.0; + if (this.m_enableLimit) { + // b2Rot qA(aA), qB(aB); + const qA = this.m_qA.SetAngle(aA), qB = this.m_qB.SetAngle(aB); + // b2Vec2 rA = b2Mul(qA, this.m_localAnchorA - this.m_localCenterA); + // b2Vec2 rB = b2Mul(qB, this.m_localAnchorB - this.m_localCenterB); + // b2Vec2 d = (cB - cA) + rB - rA; + // b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); + b2Vec2.SubVV(this.m_localAnchorA, this.m_localCenterA, this.m_lalcA); + const rA = b2Rot.MulRV(qA, this.m_lalcA, this.m_rA); + // b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); + b2Vec2.SubVV(this.m_localAnchorB, this.m_localCenterB, this.m_lalcB); + const rB = b2Rot.MulRV(qB, this.m_lalcB, this.m_rB); + // b2Vec2 d = (cB - cA) + rB - rA; + const d = b2Vec2.AddVV(b2Vec2.SubVV(cB, cA, b2Vec2.s_t0), b2Vec2.SubVV(rB, rA, b2Vec2.s_t1), b2WheelJoint.SolvePositionConstraints_s_d); + // b2Vec2 ax = b2Mul(qA, this.m_localXAxisA); + const ax = b2Rot.MulRV(qA, this.m_localXAxisA, this.m_ax); + // float sAx = b2Cross(d + rA, this.m_ax); + const sAx = b2Vec2.CrossVV(b2Vec2.AddVV(d, rA, b2Vec2.s_t0), this.m_ax); + // float sBx = b2Cross(rB, this.m_ax); + const sBx = b2Vec2.CrossVV(rB, this.m_ax); + let C = 0.0; + const translation = b2Vec2.DotVV(ax, d); + if (b2Abs(this.m_upperTranslation - this.m_lowerTranslation) < 2.0 * b2_linearSlop) { + C = translation; + } + else if (translation <= this.m_lowerTranslation) { + C = b2Min(translation - this.m_lowerTranslation, 0.0); + } + else if (translation >= this.m_upperTranslation) { + C = b2Max(translation - this.m_upperTranslation, 0.0); + } + if (C !== 0.0) { + const invMass = this.m_invMassA + this.m_invMassB + this.m_invIA * sAx * sAx + this.m_invIB * sBx * sBx; + let impulse = 0.0; + if (invMass !== 0.0) { + impulse = -C / invMass; + } + const P = b2Vec2.MulSV(impulse, ax, b2WheelJoint.SolvePositionConstraints_s_P); + const LA = impulse * sAx; + const LB = impulse * sBx; + // cA -= m_invMassA * P; + cA.SelfMulSub(this.m_invMassA, P); + aA -= this.m_invIA * LA; + // cB += m_invMassB * P; + cB.SelfMulAdd(this.m_invMassB, P); + // aB += m_invIB * LB; + aB += this.m_invIB * LB; + linearError = b2Abs(C); + } + } + // Solve perpendicular constraint + { + // b2Rot qA(aA), qB(aB); + const qA = this.m_qA.SetAngle(aA), qB = this.m_qB.SetAngle(aB); + // b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); + // b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); + // b2Vec2 d = (cB - cA) + rB - rA; + // b2Vec2 rA = b2Mul(qA, m_localAnchorA - m_localCenterA); + b2Vec2.SubVV(this.m_localAnchorA, this.m_localCenterA, this.m_lalcA); + const rA = b2Rot.MulRV(qA, this.m_lalcA, this.m_rA); + // b2Vec2 rB = b2Mul(qB, m_localAnchorB - m_localCenterB); + b2Vec2.SubVV(this.m_localAnchorB, this.m_localCenterB, this.m_lalcB); + const rB = b2Rot.MulRV(qB, this.m_lalcB, this.m_rB); + // b2Vec2 d = (cB - cA) + rB - rA; + const d = b2Vec2.AddVV(b2Vec2.SubVV(cB, cA, b2Vec2.s_t0), b2Vec2.SubVV(rB, rA, b2Vec2.s_t1), b2WheelJoint.SolvePositionConstraints_s_d); + // b2Vec2 ay = b2Mul(qA, m_localYAxisA); + const ay = b2Rot.MulRV(qA, this.m_localYAxisA, this.m_ay); + // float sAy = b2Cross(d + rA, ay); + const sAy = b2Vec2.CrossVV(b2Vec2.AddVV(d, rA, b2Vec2.s_t0), ay); + // float sBy = b2Cross(rB, ay); + const sBy = b2Vec2.CrossVV(rB, ay); + // float C = b2Dot(d, ay); + const C = b2Vec2.DotVV(d, ay); + const invMass = this.m_invMassA + this.m_invMassB + this.m_invIA * this.m_sAy * this.m_sAy + this.m_invIB * this.m_sBy * this.m_sBy; + let impulse = 0.0; + if (invMass !== 0.0) { + impulse = -C / invMass; + } + // b2Vec2 P = impulse * ay; + // const LA: number = impulse * sAy; + // const LB: number = impulse * sBy; + const P = b2Vec2.MulSV(impulse, ay, b2WheelJoint.SolvePositionConstraints_s_P); + const LA = impulse * sAy; + const LB = impulse * sBy; + // cA -= m_invMassA * P; + cA.SelfMulSub(this.m_invMassA, P); + aA -= this.m_invIA * LA; + // cB += m_invMassB * P; + cB.SelfMulAdd(this.m_invMassB, P); + aB += this.m_invIB * LB; + linearError = b2Max(linearError, b2Abs(C)); + } + // data.positions[this.m_indexA].c = cA; + data.positions[this.m_indexA].a = aA; + // data.positions[this.m_indexB].c = cB; + data.positions[this.m_indexB].a = aB; + return linearError <= b2_linearSlop; + } + GetDefinition(def) { + // DEBUG: b2Assert(false); // TODO + return def; + } + GetAnchorA(out) { + return this.m_bodyA.GetWorldPoint(this.m_localAnchorA, out); + } + GetAnchorB(out) { + return this.m_bodyB.GetWorldPoint(this.m_localAnchorB, out); + } + GetReactionForce(inv_dt, out) { + out.x = inv_dt * (this.m_impulse * this.m_ay.x + (this.m_springImpulse + this.m_lowerImpulse - this.m_upperImpulse) * this.m_ax.x); + out.y = inv_dt * (this.m_impulse * this.m_ay.y + (this.m_springImpulse + this.m_lowerImpulse - this.m_upperImpulse) * this.m_ax.y); + return out; + } + GetReactionTorque(inv_dt) { + return inv_dt * this.m_motorImpulse; + } + GetLocalAnchorA() { return this.m_localAnchorA; } + GetLocalAnchorB() { return this.m_localAnchorB; } + GetLocalAxisA() { return this.m_localXAxisA; } + GetJointTranslation() { + return this.GetPrismaticJointTranslation(); + } + GetJointLinearSpeed() { + return this.GetPrismaticJointSpeed(); + } + GetJointAngle() { + return this.GetRevoluteJointAngle(); + } + GetJointAngularSpeed() { + return this.GetRevoluteJointSpeed(); + } + GetPrismaticJointTranslation() { + const bA = this.m_bodyA; + const bB = this.m_bodyB; + const pA = bA.GetWorldPoint(this.m_localAnchorA, new b2Vec2()); + const pB = bB.GetWorldPoint(this.m_localAnchorB, new b2Vec2()); + const d = b2Vec2.SubVV(pB, pA, new b2Vec2()); + const axis = bA.GetWorldVector(this.m_localXAxisA, new b2Vec2()); + const translation = b2Vec2.DotVV(d, axis); + return translation; + } + GetPrismaticJointSpeed() { + const bA = this.m_bodyA; + const bB = this.m_bodyB; + // b2Vec2 rA = b2Mul(bA.m_xf.q, m_localAnchorA - bA.m_sweep.localCenter); + b2Vec2.SubVV(this.m_localAnchorA, bA.m_sweep.localCenter, this.m_lalcA); + const rA = b2Rot.MulRV(bA.m_xf.q, this.m_lalcA, this.m_rA); + // b2Vec2 rB = b2Mul(bB.m_xf.q, m_localAnchorB - bB.m_sweep.localCenter); + b2Vec2.SubVV(this.m_localAnchorB, bB.m_sweep.localCenter, this.m_lalcB); + const rB = b2Rot.MulRV(bB.m_xf.q, this.m_lalcB, this.m_rB); + // b2Vec2 pA = bA.m_sweep.c + rA; + const pA = b2Vec2.AddVV(bA.m_sweep.c, rA, b2Vec2.s_t0); // pA uses s_t0 + // b2Vec2 pB = bB.m_sweep.c + rB; + const pB = b2Vec2.AddVV(bB.m_sweep.c, rB, b2Vec2.s_t1); // pB uses s_t1 + // b2Vec2 d = pB - pA; + const d = b2Vec2.SubVV(pB, pA, b2Vec2.s_t2); // d uses s_t2 + // b2Vec2 axis = b2Mul(bA.m_xf.q, m_localXAxisA); + const axis = bA.GetWorldVector(this.m_localXAxisA, new b2Vec2()); + const vA = bA.m_linearVelocity; + const vB = bB.m_linearVelocity; + const wA = bA.m_angularVelocity; + const wB = bB.m_angularVelocity; + // float32 speed = b2Dot(d, b2Cross(wA, axis)) + b2Dot(axis, vB + b2Cross(wB, rB) - vA - b2Cross(wA, rA)); + const speed = b2Vec2.DotVV(d, b2Vec2.CrossSV(wA, axis, b2Vec2.s_t0)) + + b2Vec2.DotVV(axis, b2Vec2.SubVV(b2Vec2.AddVCrossSV(vB, wB, rB, b2Vec2.s_t0), b2Vec2.AddVCrossSV(vA, wA, rA, b2Vec2.s_t1), b2Vec2.s_t0)); + return speed; + } + GetRevoluteJointAngle() { + // b2Body* bA = this.m_bodyA; + // b2Body* bB = this.m_bodyB; + // return bB.this.m_sweep.a - bA.this.m_sweep.a; + return this.m_bodyB.m_sweep.a - this.m_bodyA.m_sweep.a; + } + GetRevoluteJointSpeed() { + const wA = this.m_bodyA.m_angularVelocity; + const wB = this.m_bodyB.m_angularVelocity; + return wB - wA; + } + IsMotorEnabled() { + return this.m_enableMotor; + } + EnableMotor(flag) { + if (flag !== this.m_enableMotor) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_enableMotor = flag; + } + } + SetMotorSpeed(speed) { + if (speed !== this.m_motorSpeed) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_motorSpeed = speed; + } + } + SetMaxMotorTorque(force) { + if (force !== this.m_maxMotorTorque) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_maxMotorTorque = force; + } + } + GetMotorTorque(inv_dt) { + return inv_dt * this.m_motorImpulse; + } + /// Is the joint limit enabled? + IsLimitEnabled() { + return this.m_enableLimit; + } + /// Enable/disable the joint translation limit. + EnableLimit(flag) { + if (flag !== this.m_enableLimit) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_enableLimit = flag; + this.m_lowerImpulse = 0.0; + this.m_upperImpulse = 0.0; + } + } + /// Get the lower joint translation limit, usually in meters. + GetLowerLimit() { + return this.m_lowerTranslation; + } + /// Get the upper joint translation limit, usually in meters. + GetUpperLimit() { + return this.m_upperTranslation; + } + /// Set the joint translation limits, usually in meters. + SetLimits(lower, upper) { + // b2Assert(lower <= upper); + if (lower !== this.m_lowerTranslation || upper !== this.m_upperTranslation) { + this.m_bodyA.SetAwake(true); + this.m_bodyB.SetAwake(true); + this.m_lowerTranslation = lower; + this.m_upperTranslation = upper; + this.m_lowerImpulse = 0.0; + this.m_upperImpulse = 0.0; + } + } + Dump(log) { + const indexA = this.m_bodyA.m_islandIndex; + const indexB = this.m_bodyB.m_islandIndex; + log(" const jd: b2WheelJointDef = new b2WheelJointDef();\n"); + log(" jd.bodyA = bodies[%d];\n", indexA); + log(" jd.bodyB = bodies[%d];\n", indexB); + log(" jd.collideConnected = %s;\n", (this.m_collideConnected) ? ("true") : ("false")); + log(" jd.localAnchorA.Set(%.15f, %.15f);\n", this.m_localAnchorA.x, this.m_localAnchorA.y); + log(" jd.localAnchorB.Set(%.15f, %.15f);\n", this.m_localAnchorB.x, this.m_localAnchorB.y); + log(" jd.localAxisA.Set(%.15f, %.15f);\n", this.m_localXAxisA.x, this.m_localXAxisA.y); + log(" jd.enableMotor = %s;\n", (this.m_enableMotor) ? ("true") : ("false")); + log(" jd.motorSpeed = %.15f;\n", this.m_motorSpeed); + log(" jd.maxMotorTorque = %.15f;\n", this.m_maxMotorTorque); + log(" jd.stiffness = %.15f;\n", this.m_stiffness); + log(" jd.damping = %.15f;\n", this.m_damping); + log(" joints[%d] = this.m_world.CreateJoint(jd);\n", this.m_index); + } + Draw(draw) { + const xfA = this.m_bodyA.GetTransform(); + const xfB = this.m_bodyB.GetTransform(); + const pA = b2Transform.MulXV(xfA, this.m_localAnchorA, b2WheelJoint.Draw_s_pA); + const pB = b2Transform.MulXV(xfB, this.m_localAnchorB, b2WheelJoint.Draw_s_pB); + // b2Vec2 axis = b2Mul(xfA.q, m_localXAxisA); + const axis = b2Rot.MulRV(xfA.q, this.m_localXAxisA, b2WheelJoint.Draw_s_axis); + const c1 = b2WheelJoint.Draw_s_c1; // b2Color c1(0.7f, 0.7f, 0.7f); + const c2 = b2WheelJoint.Draw_s_c2; // b2Color c2(0.3f, 0.9f, 0.3f); + const c3 = b2WheelJoint.Draw_s_c3; // b2Color c3(0.9f, 0.3f, 0.3f); + const c4 = b2WheelJoint.Draw_s_c4; // b2Color c4(0.3f, 0.3f, 0.9f); + const c5 = b2WheelJoint.Draw_s_c5; // b2Color c5(0.4f, 0.4f, 0.4f); + draw.DrawSegment(pA, pB, c5); + if (this.m_enableLimit) { + // b2Vec2 lower = pA + m_lowerTranslation * axis; + const lower = b2Vec2.AddVMulSV(pA, this.m_lowerTranslation, axis, b2WheelJoint.Draw_s_lower); + // b2Vec2 upper = pA + m_upperTranslation * axis; + const upper = b2Vec2.AddVMulSV(pA, this.m_upperTranslation, axis, b2WheelJoint.Draw_s_upper); + // b2Vec2 perp = b2Mul(xfA.q, m_localYAxisA); + const perp = b2Rot.MulRV(xfA.q, this.m_localYAxisA, b2WheelJoint.Draw_s_perp); + // draw.DrawSegment(lower, upper, c1); + draw.DrawSegment(lower, upper, c1); + // draw.DrawSegment(lower - 0.5f * perp, lower + 0.5f * perp, c2); + draw.DrawSegment(b2Vec2.AddVMulSV(lower, -0.5, perp, b2Vec2.s_t0), b2Vec2.AddVMulSV(lower, 0.5, perp, b2Vec2.s_t1), c2); + // draw.DrawSegment(upper - 0.5f * perp, upper + 0.5f * perp, c3); + draw.DrawSegment(b2Vec2.AddVMulSV(upper, -0.5, perp, b2Vec2.s_t0), b2Vec2.AddVMulSV(upper, 0.5, perp, b2Vec2.s_t1), c3); + } + else { + // draw.DrawSegment(pA - 1.0f * axis, pA + 1.0f * axis, c1); + draw.DrawSegment(b2Vec2.AddVMulSV(pA, -1.0, axis, b2Vec2.s_t0), b2Vec2.AddVMulSV(pA, 1.0, axis, b2Vec2.s_t1), c1); + } + draw.DrawPoint(pA, 5.0, c1); + draw.DrawPoint(pB, 5.0, c4); + } + } + b2WheelJoint.InitVelocityConstraints_s_d = new b2Vec2(); + b2WheelJoint.InitVelocityConstraints_s_P = new b2Vec2(); + b2WheelJoint.SolveVelocityConstraints_s_P = new b2Vec2(); + b2WheelJoint.SolvePositionConstraints_s_d = new b2Vec2(); + b2WheelJoint.SolvePositionConstraints_s_P = new b2Vec2(); + /// + b2WheelJoint.Draw_s_pA = new b2Vec2(); + b2WheelJoint.Draw_s_pB = new b2Vec2(); + b2WheelJoint.Draw_s_axis = new b2Vec2(); + b2WheelJoint.Draw_s_c1 = new b2Color(0.7, 0.7, 0.7); + b2WheelJoint.Draw_s_c2 = new b2Color(0.3, 0.9, 0.3); + b2WheelJoint.Draw_s_c3 = new b2Color(0.9, 0.3, 0.3); + b2WheelJoint.Draw_s_c4 = new b2Color(0.3, 0.3, 0.9); + b2WheelJoint.Draw_s_c5 = new b2Color(0.4, 0.4, 0.4); + b2WheelJoint.Draw_s_lower = new b2Vec2(); + b2WheelJoint.Draw_s_upper = new b2Vec2(); + b2WheelJoint.Draw_s_perp = new b2Vec2(); + + /* + * Copyright (c) 2006-2011 Erin Catto http://www.box2d.org + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + /// The world class manages all physics entities, dynamic simulation, + /// and asynchronous queries. The world also contains efficient memory + /// management facilities. + class b2World { + /// Construct a world object. + /// @param gravity the world gravity vector. + constructor(gravity) { + this.m_contactManager = new b2ContactManager(); + this.m_bodyList = null; + this.m_jointList = null; + this.m_bodyCount = 0; + this.m_jointCount = 0; + this.m_gravity = new b2Vec2(); + this.m_allowSleep = true; + this.m_destructionListener = null; + this.m_debugDraw = null; + // This is used to compute the time step ratio to + // support a variable time step. + this.m_inv_dt0 = 0; + this.m_newContacts = false; + this.m_locked = false; + this.m_clearForces = true; + // These are for debugging the solver. + this.m_warmStarting = true; + this.m_continuousPhysics = true; + this.m_subStepping = false; + this.m_stepComplete = true; + this.m_profile = new b2Profile(); + this.m_island = new b2Island(); + this.s_stack = []; + this.m_gravity.Copy(gravity); + } + /// Register a destruction listener. The listener is owned by you and must + /// remain in scope. + SetDestructionListener(listener) { + this.m_destructionListener = listener; + } + /// Register a contact filter to provide specific control over collision. + /// Otherwise the default filter is used (b2_defaultFilter). The listener is + /// owned by you and must remain in scope. + SetContactFilter(filter) { + this.m_contactManager.m_contactFilter = filter; + } + /// Register a contact event listener. The listener is owned by you and must + /// remain in scope. + SetContactListener(listener) { + this.m_contactManager.m_contactListener = listener; + } + /// Register a routine for debug drawing. The debug draw functions are called + /// inside with b2World::DebugDraw method. The debug draw object is owned + /// by you and must remain in scope. + SetDebugDraw(debugDraw) { + this.m_debugDraw = debugDraw; + } + /// Create a rigid body given a definition. No reference to the definition + /// is retained. + /// @warning This function is locked during callbacks. + CreateBody(def = {}) { + if (this.IsLocked()) { + throw new Error(); + } + const b = new b2Body(def, this); + // Add to world doubly linked list. + b.m_prev = null; + b.m_next = this.m_bodyList; + if (this.m_bodyList) { + this.m_bodyList.m_prev = b; + } + this.m_bodyList = b; + ++this.m_bodyCount; + return b; + } + /// Destroy a rigid body given a definition. No reference to the definition + /// is retained. This function is locked during callbacks. + /// @warning This automatically deletes all associated shapes and joints. + /// @warning This function is locked during callbacks. + DestroyBody(b) { + // DEBUG: b2Assert(this.m_bodyCount > 0); + if (this.IsLocked()) { + throw new Error(); + } + // Delete the attached joints. + let je = b.m_jointList; + while (je) { + const je0 = je; + je = je.next; + if (this.m_destructionListener) { + this.m_destructionListener.SayGoodbyeJoint(je0.joint); + } + this.DestroyJoint(je0.joint); + b.m_jointList = je; + } + b.m_jointList = null; + // Delete the attached contacts. + let ce = b.m_contactList; + while (ce) { + const ce0 = ce; + ce = ce.next; + this.m_contactManager.Destroy(ce0.contact); + } + b.m_contactList = null; + // Delete the attached fixtures. This destroys broad-phase proxies. + let f = b.m_fixtureList; + while (f) { + const f0 = f; + f = f.m_next; + if (this.m_destructionListener) { + this.m_destructionListener.SayGoodbyeFixture(f0); + } + f0.DestroyProxies(); + f0.Reset(); + b.m_fixtureList = f; + b.m_fixtureCount -= 1; + } + b.m_fixtureList = null; + b.m_fixtureCount = 0; + // Remove world body list. + if (b.m_prev) { + b.m_prev.m_next = b.m_next; + } + if (b.m_next) { + b.m_next.m_prev = b.m_prev; + } + if (b === this.m_bodyList) { + this.m_bodyList = b.m_next; + } + --this.m_bodyCount; + } + static _Joint_Create(def) { + switch (def.type) { + case exports.b2JointType.e_distanceJoint: return new b2DistanceJoint(def); + case exports.b2JointType.e_mouseJoint: return new b2MouseJoint(def); + case exports.b2JointType.e_prismaticJoint: return new b2PrismaticJoint(def); + case exports.b2JointType.e_revoluteJoint: return new b2RevoluteJoint(def); + case exports.b2JointType.e_pulleyJoint: return new b2PulleyJoint(def); + case exports.b2JointType.e_gearJoint: return new b2GearJoint(def); + case exports.b2JointType.e_wheelJoint: return new b2WheelJoint(def); + case exports.b2JointType.e_weldJoint: return new b2WeldJoint(def); + case exports.b2JointType.e_frictionJoint: return new b2FrictionJoint(def); + case exports.b2JointType.e_motorJoint: return new b2MotorJoint(def); + case exports.b2JointType.e_areaJoint: return new b2AreaJoint(def); + } + throw new Error(); + } + static _Joint_Destroy(joint) { + } + CreateJoint(def) { + if (this.IsLocked()) { + throw new Error(); + } + const j = b2World._Joint_Create(def); + // Connect to the world list. + j.m_prev = null; + j.m_next = this.m_jointList; + if (this.m_jointList) { + this.m_jointList.m_prev = j; + } + this.m_jointList = j; + ++this.m_jointCount; + // Connect to the bodies' doubly linked lists. + // j.m_edgeA.other = j.m_bodyB; // done in b2Joint constructor + j.m_edgeA.prev = null; + j.m_edgeA.next = j.m_bodyA.m_jointList; + if (j.m_bodyA.m_jointList) { + j.m_bodyA.m_jointList.prev = j.m_edgeA; + } + j.m_bodyA.m_jointList = j.m_edgeA; + // j.m_edgeB.other = j.m_bodyA; // done in b2Joint constructor + j.m_edgeB.prev = null; + j.m_edgeB.next = j.m_bodyB.m_jointList; + if (j.m_bodyB.m_jointList) { + j.m_bodyB.m_jointList.prev = j.m_edgeB; + } + j.m_bodyB.m_jointList = j.m_edgeB; + const bodyA = j.m_bodyA; + const bodyB = j.m_bodyB; + const collideConnected = j.m_collideConnected; + // If the joint prevents collisions, then flag any contacts for filtering. + if (!collideConnected) { + let edge = bodyB.GetContactList(); + while (edge) { + if (edge.other === bodyA) { + // Flag the contact for filtering at the next time step (where either + // body is awake). + edge.contact.FlagForFiltering(); + } + edge = edge.next; + } + } + // Note: creating a joint doesn't wake the bodies. + return j; + } + /// Destroy a joint. This may cause the connected bodies to begin colliding. + /// @warning This function is locked during callbacks. + DestroyJoint(j) { + if (this.IsLocked()) { + throw new Error(); + } + // Remove from the doubly linked list. + if (j.m_prev) { + j.m_prev.m_next = j.m_next; + } + if (j.m_next) { + j.m_next.m_prev = j.m_prev; + } + if (j === this.m_jointList) { + this.m_jointList = j.m_next; + } + // Disconnect from island graph. + const bodyA = j.m_bodyA; + const bodyB = j.m_bodyB; + const collideConnected = j.m_collideConnected; + // Wake up connected bodies. + bodyA.SetAwake(true); + bodyB.SetAwake(true); + // Remove from body 1. + if (j.m_edgeA.prev) { + j.m_edgeA.prev.next = j.m_edgeA.next; + } + if (j.m_edgeA.next) { + j.m_edgeA.next.prev = j.m_edgeA.prev; + } + if (j.m_edgeA === bodyA.m_jointList) { + bodyA.m_jointList = j.m_edgeA.next; + } + j.m_edgeA.Reset(); + // Remove from body 2 + if (j.m_edgeB.prev) { + j.m_edgeB.prev.next = j.m_edgeB.next; + } + if (j.m_edgeB.next) { + j.m_edgeB.next.prev = j.m_edgeB.prev; + } + if (j.m_edgeB === bodyB.m_jointList) { + bodyB.m_jointList = j.m_edgeB.next; + } + j.m_edgeB.Reset(); + b2World._Joint_Destroy(j); + // DEBUG: b2Assert(this.m_jointCount > 0); + --this.m_jointCount; + // If the joint prevents collisions, then flag any contacts for filtering. + if (!collideConnected) { + let edge = bodyB.GetContactList(); + while (edge) { + if (edge.other === bodyA) { + // Flag the contact for filtering at the next time step (where either + // body is awake). + edge.contact.FlagForFiltering(); + } + edge = edge.next; + } + } + } + Step(dt, velocityIterations, positionIterations) { + const stepTimer = b2World.Step_s_stepTimer.Reset(); + // If new fixtures were added, we need to find the new contacts. + if (this.m_newContacts) { + this.m_contactManager.FindNewContacts(); + this.m_newContacts = false; + } + this.m_locked = true; + const step = b2World.Step_s_step; + step.dt = dt; + step.velocityIterations = velocityIterations; + step.positionIterations = positionIterations; + if (dt > 0) { + step.inv_dt = 1 / dt; + } + else { + step.inv_dt = 0; + } + step.dtRatio = this.m_inv_dt0 * dt; + step.warmStarting = this.m_warmStarting; + // Update contacts. This is where some contacts are destroyed. + const timer = b2World.Step_s_timer.Reset(); + this.m_contactManager.Collide(); + this.m_profile.collide = timer.GetMilliseconds(); + // Integrate velocities, solve velocity constraints, and integrate positions. + if (this.m_stepComplete && step.dt > 0) { + const timer = b2World.Step_s_timer.Reset(); + this.Solve(step); + this.m_profile.solve = timer.GetMilliseconds(); + } + // Handle TOI events. + if (this.m_continuousPhysics && step.dt > 0) { + const timer = b2World.Step_s_timer.Reset(); + this.SolveTOI(step); + this.m_profile.solveTOI = timer.GetMilliseconds(); + } + if (step.dt > 0) { + this.m_inv_dt0 = step.inv_dt; + } + if (this.m_clearForces) { + this.ClearForces(); + } + this.m_locked = false; + this.m_profile.step = stepTimer.GetMilliseconds(); + } + /// Manually clear the force buffer on all bodies. By default, forces are cleared automatically + /// after each call to Step. The default behavior is modified by calling SetAutoClearForces. + /// The purpose of this function is to support sub-stepping. Sub-stepping is often used to maintain + /// a fixed sized time step under a variable frame-rate. + /// When you perform sub-stepping you will disable auto clearing of forces and instead call + /// ClearForces after all sub-steps are complete in one pass of your game loop. + /// @see SetAutoClearForces + ClearForces() { + for (let body = this.m_bodyList; body; body = body.m_next) { + body.m_force.SetZero(); + body.m_torque = 0; + } + } + DebugDraw() { + if (this.m_debugDraw === null) { + return; + } + const flags = this.m_debugDraw.GetFlags(); + const color = b2World.DebugDraw_s_color.SetRGB(0, 0, 0); + if (flags & exports.b2DrawFlags.e_shapeBit) { + for (let b = this.m_bodyList; b; b = b.m_next) { + const xf = b.m_xf; + this.m_debugDraw.PushTransform(xf); + for (let f = b.GetFixtureList(); f; f = f.m_next) { + if (b.GetType() === exports.b2BodyType.b2_dynamicBody && b.m_mass === 0.0) { + // Bad body + this.DrawShape(f, new b2Color(1.0, 0.0, 0.0)); + } + else if (!b.IsEnabled()) { + color.SetRGB(0.5, 0.5, 0.3); + this.DrawShape(f, color); + } + else if (b.GetType() === exports.b2BodyType.b2_staticBody) { + color.SetRGB(0.5, 0.9, 0.5); + this.DrawShape(f, color); + } + else if (b.GetType() === exports.b2BodyType.b2_kinematicBody) { + color.SetRGB(0.5, 0.5, 0.9); + this.DrawShape(f, color); + } + else if (!b.IsAwake()) { + color.SetRGB(0.6, 0.6, 0.6); + this.DrawShape(f, color); + } + else { + color.SetRGB(0.9, 0.7, 0.7); + this.DrawShape(f, color); + } + } + this.m_debugDraw.PopTransform(xf); + } + } + if (flags & exports.b2DrawFlags.e_jointBit) { + for (let j = this.m_jointList; j; j = j.m_next) { + j.Draw(this.m_debugDraw); + } + } + if (flags & exports.b2DrawFlags.e_pairBit) { + color.SetRGB(0.3, 0.9, 0.9); + for (let contact = this.m_contactManager.m_contactList; contact; contact = contact.m_next) { + const fixtureA = contact.GetFixtureA(); + const fixtureB = contact.GetFixtureB(); + const indexA = contact.GetChildIndexA(); + const indexB = contact.GetChildIndexB(); + const cA = fixtureA.GetAABB(indexA).GetCenter(); + const cB = fixtureB.GetAABB(indexB).GetCenter(); + this.m_debugDraw.DrawSegment(cA, cB, color); + } + } + if (flags & exports.b2DrawFlags.e_aabbBit) { + color.SetRGB(0.9, 0.3, 0.9); + const vs = b2World.DebugDraw_s_vs; + for (let b = this.m_bodyList; b; b = b.m_next) { + if (!b.IsEnabled()) { + continue; + } + for (let f = b.GetFixtureList(); f; f = f.m_next) { + for (let i = 0; i < f.m_proxyCount; ++i) { + const proxy = f.m_proxies[i]; + const aabb = proxy.treeNode.aabb; + vs[0].Set(aabb.lowerBound.x, aabb.lowerBound.y); + vs[1].Set(aabb.upperBound.x, aabb.lowerBound.y); + vs[2].Set(aabb.upperBound.x, aabb.upperBound.y); + vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y); + this.m_debugDraw.DrawPolygon(vs, 4, color); + } + } + } + } + if (flags & exports.b2DrawFlags.e_centerOfMassBit) { + for (let b = this.m_bodyList; b; b = b.m_next) { + const xf = b2World.DebugDraw_s_xf; + xf.q.Copy(b.m_xf.q); + xf.p.Copy(b.GetWorldCenter()); + this.m_debugDraw.DrawTransform(xf); + } + } + } + QueryAABB(...args) { + if (args[0] instanceof b2QueryCallback) { + this._QueryAABB(args[0], args[1]); + } + else { + this._QueryAABB(null, args[0], args[1]); + } + } + _QueryAABB(callback, aabb, fn) { + this.m_contactManager.m_broadPhase.Query(aabb, (proxy) => { + const fixture_proxy = proxy.userData; + // DEBUG: b2Assert(fixture_proxy instanceof b2FixtureProxy); + const fixture = fixture_proxy.fixture; + if (callback) { + return callback.ReportFixture(fixture); + } + else if (fn) { + return fn(fixture); + } + return true; + }); + } + QueryAllAABB(aabb, out = []) { + this.QueryAABB(aabb, (fixture) => { out.push(fixture); return true; }); + return out; + } + QueryPointAABB(...args) { + if (args[0] instanceof b2QueryCallback) { + this._QueryPointAABB(args[0], args[1]); + } + else { + this._QueryPointAABB(null, args[0], args[1]); + } + } + _QueryPointAABB(callback, point, fn) { + this.m_contactManager.m_broadPhase.QueryPoint(point, (proxy) => { + const fixture_proxy = proxy.userData; + // DEBUG: b2Assert(fixture_proxy instanceof b2FixtureProxy); + const fixture = fixture_proxy.fixture; + if (callback) { + return callback.ReportFixture(fixture); + } + else if (fn) { + return fn(fixture); + } + return true; + }); + } + QueryAllPointAABB(point, out = []) { + this.QueryPointAABB(point, (fixture) => { out.push(fixture); return true; }); + return out; + } + QueryFixtureShape(...args) { + if (args[0] instanceof b2QueryCallback) { + this._QueryFixtureShape(args[0], args[1], args[2], args[3]); + } + else { + this._QueryFixtureShape(null, args[0], args[1], args[2], args[3]); + } + } + _QueryFixtureShape(callback, shape, index, transform, fn) { + const aabb = b2World.QueryFixtureShape_s_aabb; + shape.ComputeAABB(aabb, transform, index); + this.m_contactManager.m_broadPhase.Query(aabb, (proxy) => { + const fixture_proxy = proxy.userData; + // DEBUG: b2Assert(fixture_proxy instanceof b2FixtureProxy); + const fixture = fixture_proxy.fixture; + if (b2TestOverlapShape(shape, index, fixture.GetShape(), fixture_proxy.childIndex, transform, fixture.GetBody().GetTransform())) { + if (callback) { + return callback.ReportFixture(fixture); + } + else if (fn) { + return fn(fixture); + } + } + return true; + }); + } + QueryAllFixtureShape(shape, index, transform, out = []) { + this.QueryFixtureShape(shape, index, transform, (fixture) => { out.push(fixture); return true; }); + return out; + } + QueryFixturePoint(...args) { + if (args[0] instanceof b2QueryCallback) { + this._QueryFixturePoint(args[0], args[1]); + } + else { + this._QueryFixturePoint(null, args[0], args[1]); + } + } + _QueryFixturePoint(callback, point, fn) { + this.m_contactManager.m_broadPhase.QueryPoint(point, (proxy) => { + const fixture_proxy = proxy.userData; + // DEBUG: b2Assert(fixture_proxy instanceof b2FixtureProxy); + const fixture = fixture_proxy.fixture; + if (fixture.TestPoint(point)) { + if (callback) { + return callback.ReportFixture(fixture); + } + else if (fn) { + return fn(fixture); + } + } + return true; + }); + } + QueryAllFixturePoint(point, out = []) { + this.QueryFixturePoint(point, (fixture) => { out.push(fixture); return true; }); + return out; + } + RayCast(...args) { + if (args[0] instanceof b2RayCastCallback) { + this._RayCast(args[0], args[1], args[2]); + } + else { + this._RayCast(null, args[0], args[1], args[2]); + } + } + _RayCast(callback, point1, point2, fn) { + const input = b2World.RayCast_s_input; + input.maxFraction = 1; + input.p1.Copy(point1); + input.p2.Copy(point2); + this.m_contactManager.m_broadPhase.RayCast(input, (input, proxy) => { + const fixture_proxy = proxy.userData; + // DEBUG: b2Assert(fixture_proxy instanceof b2FixtureProxy); + const fixture = fixture_proxy.fixture; + const index = fixture_proxy.childIndex; + const output = b2World.RayCast_s_output; + const hit = fixture.RayCast(output, input, index); + if (hit) { + const fraction = output.fraction; + const point = b2World.RayCast_s_point; + point.Set((1 - fraction) * point1.x + fraction * point2.x, (1 - fraction) * point1.y + fraction * point2.y); + if (callback) { + return callback.ReportFixture(fixture, point, output.normal, fraction); + } + else if (fn) { + return fn(fixture, point, output.normal, fraction); + } + } + return input.maxFraction; + }); + } + RayCastOne(point1, point2) { + let result = null; + let min_fraction = 1; + this.RayCast(point1, point2, (fixture, point, normal, fraction) => { + if (fraction < min_fraction) { + min_fraction = fraction; + result = fixture; + } + return min_fraction; + }); + return result; + } + RayCastAll(point1, point2, out = []) { + this.RayCast(point1, point2, (fixture, point, normal, fraction) => { + out.push(fixture); + return 1; + }); + return out; + } + /// Get the world body list. With the returned body, use b2Body::GetNext to get + /// the next body in the world list. A NULL body indicates the end of the list. + /// @return the head of the world body list. + GetBodyList() { + return this.m_bodyList; + } + /// Get the world joint list. With the returned joint, use b2Joint::GetNext to get + /// the next joint in the world list. A NULL joint indicates the end of the list. + /// @return the head of the world joint list. + GetJointList() { + return this.m_jointList; + } + /// Get the world contact list. With the returned contact, use b2Contact::GetNext to get + /// the next contact in the world list. A NULL contact indicates the end of the list. + /// @return the head of the world contact list. + /// @warning contacts are created and destroyed in the middle of a time step. + /// Use b2ContactListener to avoid missing contacts. + GetContactList() { + return this.m_contactManager.m_contactList; + } + /// Enable/disable sleep. + SetAllowSleeping(flag) { + if (flag === this.m_allowSleep) { + return; + } + this.m_allowSleep = flag; + if (!this.m_allowSleep) { + for (let b = this.m_bodyList; b; b = b.m_next) { + b.SetAwake(true); + } + } + } + GetAllowSleeping() { + return this.m_allowSleep; + } + /// Enable/disable warm starting. For testing. + SetWarmStarting(flag) { + this.m_warmStarting = flag; + } + GetWarmStarting() { + return this.m_warmStarting; + } + /// Enable/disable continuous physics. For testing. + SetContinuousPhysics(flag) { + this.m_continuousPhysics = flag; + } + GetContinuousPhysics() { + return this.m_continuousPhysics; + } + /// Enable/disable single stepped continuous physics. For testing. + SetSubStepping(flag) { + this.m_subStepping = flag; + } + GetSubStepping() { + return this.m_subStepping; + } + /// Get the number of broad-phase proxies. + GetProxyCount() { + return this.m_contactManager.m_broadPhase.GetProxyCount(); + } + /// Get the number of bodies. + GetBodyCount() { + return this.m_bodyCount; + } + /// Get the number of joints. + GetJointCount() { + return this.m_jointCount; + } + /// Get the number of contacts (each may have 0 or more contact points). + GetContactCount() { + return this.m_contactManager.m_contactCount; + } + /// Get the height of the dynamic tree. + GetTreeHeight() { + return this.m_contactManager.m_broadPhase.GetTreeHeight(); + } + /// Get the balance of the dynamic tree. + GetTreeBalance() { + return this.m_contactManager.m_broadPhase.GetTreeBalance(); + } + /// Get the quality metric of the dynamic tree. The smaller the better. + /// The minimum is 1. + GetTreeQuality() { + return this.m_contactManager.m_broadPhase.GetTreeQuality(); + } + /// Change the global gravity vector. + SetGravity(gravity, wake = true) { + if (!b2Vec2.IsEqualToV(this.m_gravity, gravity)) { + this.m_gravity.Copy(gravity); + if (wake) { + for (let b = this.m_bodyList; b; b = b.m_next) { + b.SetAwake(true); + } + } + } + } + /// Get the global gravity vector. + GetGravity() { + return this.m_gravity; + } + /// Is the world locked (in the middle of a time step). + IsLocked() { + return this.m_locked; + } + /// Set flag to control automatic clearing of forces after each time step. + SetAutoClearForces(flag) { + this.m_clearForces = flag; + } + /// Get the flag that controls automatic clearing of forces after each time step. + GetAutoClearForces() { + return this.m_clearForces; + } + /// Shift the world origin. Useful for large worlds. + /// The body shift formula is: position -= newOrigin + /// @param newOrigin the new origin with respect to the old origin + ShiftOrigin(newOrigin) { + if (this.IsLocked()) { + throw new Error(); + } + for (let b = this.m_bodyList; b; b = b.m_next) { + b.m_xf.p.SelfSub(newOrigin); + b.m_sweep.c0.SelfSub(newOrigin); + b.m_sweep.c.SelfSub(newOrigin); + } + for (let j = this.m_jointList; j; j = j.m_next) { + j.ShiftOrigin(newOrigin); + } + this.m_contactManager.m_broadPhase.ShiftOrigin(newOrigin); + } + /// Get the contact manager for testing. + GetContactManager() { + return this.m_contactManager; + } + /// Get the current profile. + GetProfile() { + return this.m_profile; + } + /// Dump the world into the log file. + /// @warning this should be called outside of a time step. + Dump(log) { + if (this.m_locked) { + return; + } + // b2OpenDump("box2d_dump.inl"); + log("const g: b2Vec2 = new b2Vec2(%.15f, %.15f);\n", this.m_gravity.x, this.m_gravity.y); + log("this.m_world.SetGravity(g);\n"); + log("const bodies: b2Body[] = [];\n"); + log("const joints: b2Joint[] = [];\n"); + let i = 0; + for (let b = this.m_bodyList; b; b = b.m_next) { + b.m_islandIndex = i; + b.Dump(log); + ++i; + } + i = 0; + for (let j = this.m_jointList; j; j = j.m_next) { + j.m_index = i; + ++i; + } + // First pass on joints, skip gear joints. + for (let j = this.m_jointList; j; j = j.m_next) { + if (j.m_type === exports.b2JointType.e_gearJoint) { + continue; + } + log("{\n"); + j.Dump(log); + log("}\n"); + } + // Second pass on joints, only gear joints. + for (let j = this.m_jointList; j; j = j.m_next) { + if (j.m_type !== exports.b2JointType.e_gearJoint) { + continue; + } + log("{\n"); + j.Dump(log); + log("}\n"); + } + // b2CloseDump(); + } + DrawShape(fixture, color) { + if (this.m_debugDraw === null) { + return; + } + const shape = fixture.GetShape(); + switch (shape.m_type) { + case exports.b2ShapeType.e_circleShape: { + const circle = shape; + const center = circle.m_p; + const radius = circle.m_radius; + const axis = b2Vec2.UNITX; + this.m_debugDraw.DrawSolidCircle(center, radius, axis, color); + break; + } + case exports.b2ShapeType.e_edgeShape: { + const edge = shape; + const v1 = edge.m_vertex1; + const v2 = edge.m_vertex2; + this.m_debugDraw.DrawSegment(v1, v2, color); + if (edge.m_oneSided === false) { + this.m_debugDraw.DrawPoint(v1, 4.0, color); + this.m_debugDraw.DrawPoint(v2, 4.0, color); + } + break; + } + case exports.b2ShapeType.e_chainShape: { + const chain = shape; + const count = chain.m_count; + const vertices = chain.m_vertices; + let v1 = vertices[0]; + for (let i = 1; i < count; ++i) { + const v2 = vertices[i]; + this.m_debugDraw.DrawSegment(v1, v2, color); + v1 = v2; + } + break; + } + case exports.b2ShapeType.e_polygonShape: { + const poly = shape; + const vertexCount = poly.m_count; + const vertices = poly.m_vertices; + this.m_debugDraw.DrawSolidPolygon(vertices, vertexCount, color); + break; + } + } + } + Solve(step) { + this.m_profile.solveInit = 0; + this.m_profile.solveVelocity = 0; + this.m_profile.solvePosition = 0; + // Size the island for the worst case. + const island = this.m_island; + island.Initialize(this.m_bodyCount, this.m_contactManager.m_contactCount, this.m_jointCount, this.m_contactManager.m_contactListener); + // Clear all the island flags. + for (let b = this.m_bodyList; b; b = b.m_next) { + b.m_islandFlag = false; + } + for (let c = this.m_contactManager.m_contactList; c; c = c.m_next) { + c.m_islandFlag = false; + } + for (let j = this.m_jointList; j; j = j.m_next) { + j.m_islandFlag = false; + } + // Build and simulate all awake islands. + // DEBUG: const stackSize: number = this.m_bodyCount; + const stack = this.s_stack; + for (let seed = this.m_bodyList; seed; seed = seed.m_next) { + if (seed.m_islandFlag) { + continue; + } + if (!seed.IsAwake() || !seed.IsEnabled()) { + continue; + } + // The seed can be dynamic or kinematic. + if (seed.GetType() === exports.b2BodyType.b2_staticBody) { + continue; + } + // Reset island and stack. + island.Clear(); + let stackCount = 0; + stack[stackCount++] = seed; + seed.m_islandFlag = true; + // Perform a depth first search (DFS) on the constraint graph. + while (stackCount > 0) { + // Grab the next body off the stack and add it to the island. + const b = stack[--stackCount]; + if (!b) { + throw new Error(); + } + // DEBUG: b2Assert(b.IsEnabled()); + island.AddBody(b); + // To keep islands as small as possible, we don't + // propagate islands across static bodies. + if (b.GetType() === exports.b2BodyType.b2_staticBody) { + continue; + } + // Make sure the body is awake. (without resetting sleep timer). + b.m_awakeFlag = true; + // Search all contacts connected to this body. + for (let ce = b.m_contactList; ce; ce = ce.next) { + const contact = ce.contact; + // Has this contact already been added to an island? + if (contact.m_islandFlag) { + continue; + } + // Is this contact solid and touching? + if (!contact.IsEnabled() || !contact.IsTouching()) { + continue; + } + // Skip sensors. + const sensorA = contact.m_fixtureA.m_isSensor; + const sensorB = contact.m_fixtureB.m_isSensor; + if (sensorA || sensorB) { + continue; + } + island.AddContact(contact); + contact.m_islandFlag = true; + const other = ce.other; + // Was the other body already added to this island? + if (other.m_islandFlag) { + continue; + } + // DEBUG: b2Assert(stackCount < stackSize); + stack[stackCount++] = other; + other.m_islandFlag = true; + } + // Search all joints connect to this body. + for (let je = b.m_jointList; je; je = je.next) { + if (je.joint.m_islandFlag) { + continue; + } + const other = je.other; + // Don't simulate joints connected to disabled bodies. + if (!other.IsEnabled()) { + continue; + } + island.AddJoint(je.joint); + je.joint.m_islandFlag = true; + if (other.m_islandFlag) { + continue; + } + // DEBUG: b2Assert(stackCount < stackSize); + stack[stackCount++] = other; + other.m_islandFlag = true; + } + } + const profile = new b2Profile(); + island.Solve(profile, step, this.m_gravity, this.m_allowSleep); + this.m_profile.solveInit += profile.solveInit; + this.m_profile.solveVelocity += profile.solveVelocity; + this.m_profile.solvePosition += profile.solvePosition; + // Post solve cleanup. + for (let i = 0; i < island.m_bodyCount; ++i) { + // Allow static bodies to participate in other islands. + const b = island.m_bodies[i]; + if (b.GetType() === exports.b2BodyType.b2_staticBody) { + b.m_islandFlag = false; + } + } + } + for (let i = 0; i < stack.length; ++i) { + if (!stack[i]) { + break; + } + stack[i] = null; + } + const timer = new b2Timer(); + // Synchronize fixtures, check for out of range bodies. + for (let b = this.m_bodyList; b; b = b.m_next) { + // If a body was not in an island then it did not move. + if (!b.m_islandFlag) { + continue; + } + if (b.GetType() === exports.b2BodyType.b2_staticBody) { + continue; + } + // Update fixtures (for broad-phase). + b.SynchronizeFixtures(); + } + // Look for new contacts. + this.m_contactManager.FindNewContacts(); + this.m_profile.broadphase = timer.GetMilliseconds(); + } + SolveTOI(step) { + const island = this.m_island; + island.Initialize(2 * b2_maxTOIContacts, b2_maxTOIContacts, 0, this.m_contactManager.m_contactListener); + if (this.m_stepComplete) { + for (let b = this.m_bodyList; b; b = b.m_next) { + b.m_islandFlag = false; + b.m_sweep.alpha0 = 0; + } + for (let c = this.m_contactManager.m_contactList; c; c = c.m_next) { + // Invalidate TOI + c.m_toiFlag = false; + c.m_islandFlag = false; + c.m_toiCount = 0; + c.m_toi = 1; + } + } + // Find TOI events and solve them. + for (;;) { + // Find the first TOI. + let minContact = null; + let minAlpha = 1; + for (let c = this.m_contactManager.m_contactList; c; c = c.m_next) { + // Is this contact disabled? + if (!c.IsEnabled()) { + continue; + } + // Prevent excessive sub-stepping. + if (c.m_toiCount > b2_maxSubSteps) { + continue; + } + let alpha = 1; + if (c.m_toiFlag) { + // This contact has a valid cached TOI. + alpha = c.m_toi; + } + else { + const fA = c.GetFixtureA(); + const fB = c.GetFixtureB(); + // Is there a sensor? + if (fA.IsSensor() || fB.IsSensor()) { + continue; + } + const bA = fA.GetBody(); + const bB = fB.GetBody(); + const typeA = bA.m_type; + const typeB = bB.m_type; + // DEBUG: b2Assert(typeA !== b2BodyType.b2_staticBody || typeB !== b2BodyType.b2_staticBody); + const activeA = bA.IsAwake() && typeA !== exports.b2BodyType.b2_staticBody; + const activeB = bB.IsAwake() && typeB !== exports.b2BodyType.b2_staticBody; + // Is at least one body active (awake and dynamic or kinematic)? + if (!activeA && !activeB) { + continue; + } + const collideA = bA.IsBullet() || typeA !== exports.b2BodyType.b2_dynamicBody; + const collideB = bB.IsBullet() || typeB !== exports.b2BodyType.b2_dynamicBody; + // Are these two non-bullet dynamic bodies? + if (!collideA && !collideB) { + continue; + } + // Compute the TOI for this contact. + // Put the sweeps onto the same time interval. + let alpha0 = bA.m_sweep.alpha0; + if (bA.m_sweep.alpha0 < bB.m_sweep.alpha0) { + alpha0 = bB.m_sweep.alpha0; + bA.m_sweep.Advance(alpha0); + } + else if (bB.m_sweep.alpha0 < bA.m_sweep.alpha0) { + alpha0 = bA.m_sweep.alpha0; + bB.m_sweep.Advance(alpha0); + } + // DEBUG: b2Assert(alpha0 < 1); + const indexA = c.GetChildIndexA(); + const indexB = c.GetChildIndexB(); + // Compute the time of impact in interval [0, minTOI] + const input = b2World.SolveTOI_s_toi_input; + input.proxyA.SetShape(fA.GetShape(), indexA); + input.proxyB.SetShape(fB.GetShape(), indexB); + input.sweepA.Copy(bA.m_sweep); + input.sweepB.Copy(bB.m_sweep); + input.tMax = 1; + const output = b2World.SolveTOI_s_toi_output; + b2TimeOfImpact(output, input); + // Beta is the fraction of the remaining portion of the . + const beta = output.t; + if (output.state === exports.b2TOIOutputState.e_touching) { + alpha = b2Min(alpha0 + (1 - alpha0) * beta, 1); + } + else { + alpha = 1; + } + c.m_toi = alpha; + c.m_toiFlag = true; + } + if (alpha < minAlpha) { + // This is the minimum TOI found so far. + minContact = c; + minAlpha = alpha; + } + } + if (minContact === null || 1 - 10 * b2_epsilon < minAlpha) { + // No more TOI events. Done! + this.m_stepComplete = true; + break; + } + // Advance the bodies to the TOI. + const fA = minContact.GetFixtureA(); + const fB = minContact.GetFixtureB(); + const bA = fA.GetBody(); + const bB = fB.GetBody(); + const backup1 = b2World.SolveTOI_s_backup1.Copy(bA.m_sweep); + const backup2 = b2World.SolveTOI_s_backup2.Copy(bB.m_sweep); + bA.Advance(minAlpha); + bB.Advance(minAlpha); + // The TOI contact likely has some new contact points. + minContact.Update(this.m_contactManager.m_contactListener); + minContact.m_toiFlag = false; + ++minContact.m_toiCount; + // Is the contact solid? + if (!minContact.IsEnabled() || !minContact.IsTouching()) { + // Restore the sweeps. + minContact.SetEnabled(false); + bA.m_sweep.Copy(backup1); + bB.m_sweep.Copy(backup2); + bA.SynchronizeTransform(); + bB.SynchronizeTransform(); + continue; + } + bA.SetAwake(true); + bB.SetAwake(true); + // Build the island + island.Clear(); + island.AddBody(bA); + island.AddBody(bB); + island.AddContact(minContact); + bA.m_islandFlag = true; + bB.m_islandFlag = true; + minContact.m_islandFlag = true; + // Get contacts on bodyA and bodyB. + // const bodies: b2Body[] = [bA, bB]; + for (let i = 0; i < 2; ++i) { + const body = (i === 0) ? (bA) : (bB); // bodies[i]; + if (body.m_type === exports.b2BodyType.b2_dynamicBody) { + for (let ce = body.m_contactList; ce; ce = ce.next) { + if (island.m_bodyCount === island.m_bodyCapacity) { + break; + } + if (island.m_contactCount === island.m_contactCapacity) { + break; + } + const contact = ce.contact; + // Has this contact already been added to the island? + if (contact.m_islandFlag) { + continue; + } + // Only add static, kinematic, or bullet bodies. + const other = ce.other; + if (other.m_type === exports.b2BodyType.b2_dynamicBody && + !body.IsBullet() && !other.IsBullet()) { + continue; + } + // Skip sensors. + const sensorA = contact.m_fixtureA.m_isSensor; + const sensorB = contact.m_fixtureB.m_isSensor; + if (sensorA || sensorB) { + continue; + } + // Tentatively advance the body to the TOI. + const backup = b2World.SolveTOI_s_backup.Copy(other.m_sweep); + if (!other.m_islandFlag) { + other.Advance(minAlpha); + } + // Update the contact points + contact.Update(this.m_contactManager.m_contactListener); + // Was the contact disabled by the user? + if (!contact.IsEnabled()) { + other.m_sweep.Copy(backup); + other.SynchronizeTransform(); + continue; + } + // Are there contact points? + if (!contact.IsTouching()) { + other.m_sweep.Copy(backup); + other.SynchronizeTransform(); + continue; + } + // Add the contact to the island + contact.m_islandFlag = true; + island.AddContact(contact); + // Has the other body already been added to the island? + if (other.m_islandFlag) { + continue; + } + // Add the other body to the island. + other.m_islandFlag = true; + if (other.m_type !== exports.b2BodyType.b2_staticBody) { + other.SetAwake(true); + } + island.AddBody(other); + } + } + } + const subStep = b2World.SolveTOI_s_subStep; + subStep.dt = (1 - minAlpha) * step.dt; + subStep.inv_dt = 1 / subStep.dt; + subStep.dtRatio = 1; + subStep.positionIterations = 20; + subStep.velocityIterations = step.velocityIterations; + subStep.warmStarting = false; + island.SolveTOI(subStep, bA.m_islandIndex, bB.m_islandIndex); + // Reset island flags and synchronize broad-phase proxies. + for (let i = 0; i < island.m_bodyCount; ++i) { + const body = island.m_bodies[i]; + body.m_islandFlag = false; + if (body.m_type !== exports.b2BodyType.b2_dynamicBody) { + continue; + } + body.SynchronizeFixtures(); + // Invalidate all contact TOIs on this displaced body. + for (let ce = body.m_contactList; ce; ce = ce.next) { + ce.contact.m_toiFlag = false; + ce.contact.m_islandFlag = false; + } + } + // Commit fixture proxy movements to the broad-phase so that new contacts are created. + // Also, some contacts can be destroyed. + this.m_contactManager.FindNewContacts(); + if (this.m_subStepping) { + this.m_stepComplete = false; + break; + } + } + } + } + /// Take a time step. This performs collision detection, integration, + /// and constraint solution. + /// @param timeStep the amount of time to simulate, this should not vary. + /// @param velocityIterations for the velocity constraint solver. + /// @param positionIterations for the position constraint solver. + b2World.Step_s_step = new b2TimeStep(); + b2World.Step_s_stepTimer = new b2Timer(); + b2World.Step_s_timer = new b2Timer(); + /// Call this to draw shapes and other debug draw data. + b2World.DebugDraw_s_color = new b2Color(0, 0, 0); + b2World.DebugDraw_s_vs = b2Vec2.MakeArray(4); + b2World.DebugDraw_s_xf = new b2Transform(); + b2World.QueryFixtureShape_s_aabb = new b2AABB(); + b2World.RayCast_s_input = new b2RayCastInput(); + b2World.RayCast_s_output = new b2RayCastOutput(); + b2World.RayCast_s_point = new b2Vec2(); + b2World.SolveTOI_s_subStep = new b2TimeStep(); + b2World.SolveTOI_s_backup = new b2Sweep(); + b2World.SolveTOI_s_backup1 = new b2Sweep(); + b2World.SolveTOI_s_backup2 = new b2Sweep(); + b2World.SolveTOI_s_toi_input = new b2TOIInput(); + b2World.SolveTOI_s_toi_output = new b2TOIOutput(); + + // MIT License + exports.b2StretchingModel = void 0; + (function (b2StretchingModel) { + b2StretchingModel[b2StretchingModel["b2_pbdStretchingModel"] = 0] = "b2_pbdStretchingModel"; + b2StretchingModel[b2StretchingModel["b2_xpbdStretchingModel"] = 1] = "b2_xpbdStretchingModel"; + })(exports.b2StretchingModel || (exports.b2StretchingModel = {})); + exports.b2BendingModel = void 0; + (function (b2BendingModel) { + b2BendingModel[b2BendingModel["b2_springAngleBendingModel"] = 0] = "b2_springAngleBendingModel"; + b2BendingModel[b2BendingModel["b2_pbdAngleBendingModel"] = 1] = "b2_pbdAngleBendingModel"; + b2BendingModel[b2BendingModel["b2_xpbdAngleBendingModel"] = 2] = "b2_xpbdAngleBendingModel"; + b2BendingModel[b2BendingModel["b2_pbdDistanceBendingModel"] = 3] = "b2_pbdDistanceBendingModel"; + b2BendingModel[b2BendingModel["b2_pbdHeightBendingModel"] = 4] = "b2_pbdHeightBendingModel"; + b2BendingModel[b2BendingModel["b2_pbdTriangleBendingModel"] = 5] = "b2_pbdTriangleBendingModel"; + })(exports.b2BendingModel || (exports.b2BendingModel = {})); + /// + class b2RopeTuning { + constructor() { + this.stretchingModel = exports.b2StretchingModel.b2_pbdStretchingModel; + this.bendingModel = exports.b2BendingModel.b2_pbdAngleBendingModel; + this.damping = 0.0; + this.stretchStiffness = 1.0; + this.stretchHertz = 0.0; + this.stretchDamping = 0.0; + this.bendStiffness = 0.5; + this.bendHertz = 1.0; + this.bendDamping = 0.0; + this.isometric = false; + this.fixedEffectiveMass = false; + this.warmStart = false; + } + Copy(other) { + this.stretchingModel = other.stretchingModel; + this.bendingModel = other.bendingModel; + this.damping = other.damping; + this.stretchStiffness = other.stretchStiffness; + this.stretchHertz = other.stretchHertz; + this.stretchDamping = other.stretchDamping; + this.bendStiffness = other.bendStiffness; + this.bendHertz = other.bendHertz; + this.bendDamping = other.bendDamping; + this.isometric = other.isometric; + this.fixedEffectiveMass = other.fixedEffectiveMass; + this.warmStart = other.warmStart; + return this; + } + } + /// + class b2RopeDef { + constructor() { + this.position = new b2Vec2(); + // b2Vec2* vertices; + this.vertices = []; + // int32 count; + this.count = 0; + // float* masses; + this.masses = []; + // b2Vec2 gravity; + this.gravity = new b2Vec2(); + // b2RopeTuning tuning; + this.tuning = new b2RopeTuning(); + } + } + class b2RopeStretch { + constructor() { + this.i1 = 0; + this.i2 = 0; + this.invMass1 = 0.0; + this.invMass2 = 0.0; + this.L = 0.0; + this.lambda = 0.0; + this.spring = 0.0; + this.damper = 0.0; + } + } + class b2RopeBend { + constructor() { + this.i1 = 0; + this.i2 = 0; + this.i3 = 0; + this.invMass1 = 0.0; + this.invMass2 = 0.0; + this.invMass3 = 0.0; + this.invEffectiveMass = 0.0; + this.lambda = 0.0; + this.L1 = 0.0; + this.L2 = 0.0; + this.alpha1 = 0.0; + this.alpha2 = 0.0; + this.spring = 0.0; + this.damper = 0.0; + } + } + /// + class b2Rope { + constructor() { + this.m_position = new b2Vec2(); + this.m_count = 0; + this.m_stretchCount = 0; + this.m_bendCount = 0; + // b2RopeStretch* m_stretchConstraints; + this.m_stretchConstraints = []; + // b2RopeBend* m_bendConstraints; + this.m_bendConstraints = []; + // b2Vec2* m_bindPositions; + this.m_bindPositions = []; + // b2Vec2* m_ps; + this.m_ps = []; + // b2Vec2* m_p0s; + this.m_p0s = []; + // b2Vec2* m_vs; + this.m_vs = []; + // float* m_invMasses; + this.m_invMasses = []; + // b2Vec2 m_gravity; + this.m_gravity = new b2Vec2(); + this.m_tuning = new b2RopeTuning(); + } + Create(def) { + // b2Assert(def.count >= 3); + this.m_position.Copy(def.position); + this.m_count = def.count; + function make_array(array, count, make) { + for (let index = 0; index < count; ++index) { + array[index] = make(index); + } + } + // this.m_bindPositions = (b2Vec2*)b2Alloc(this.m_count * sizeof(b2Vec2)); + make_array(this.m_bindPositions, this.m_count, () => new b2Vec2()); + // this.m_ps = (b2Vec2*)b2Alloc(this.m_count * sizeof(b2Vec2)); + make_array(this.m_ps, this.m_count, () => new b2Vec2()); + // this.m_p0s = (b2Vec2*)b2Alloc(this.m_count * sizeof(b2Vec2)); + make_array(this.m_p0s, this.m_count, () => new b2Vec2()); + // this.m_vs = (b2Vec2*)b2Alloc(this.m_count * sizeof(b2Vec2)); + make_array(this.m_vs, this.m_count, () => new b2Vec2()); + // this.m_invMasses = (float*)b2Alloc(this.m_count * sizeof(float)); + make_array(this.m_invMasses, this.m_count, () => 0.0); + for (let i = 0; i < this.m_count; ++i) { + this.m_bindPositions[i].Copy(def.vertices[i]); + // this.m_ps[i] = def.vertices[i] + this.m_position; + this.m_ps[i].Copy(def.vertices[i]).SelfAdd(this.m_position); + // this.m_p0s[i] = def.vertices[i] + this.m_position; + this.m_p0s[i].Copy(def.vertices[i]).SelfAdd(this.m_position); + this.m_vs[i].SetZero(); + const m = def.masses[i]; + if (m > 0.0) { + this.m_invMasses[i] = 1.0 / m; + } + else { + this.m_invMasses[i] = 0.0; + } + } + this.m_stretchCount = this.m_count - 1; + this.m_bendCount = this.m_count - 2; + // this.m_stretchConstraints = (b2RopeStretch*)b2Alloc(this.m_stretchCount * sizeof(b2RopeStretch)); + make_array(this.m_stretchConstraints, this.m_stretchCount, () => new b2RopeStretch()); + // this.m_bendConstraints = (b2RopeBend*)b2Alloc(this.m_bendCount * sizeof(b2RopeBend)); + make_array(this.m_bendConstraints, this.m_bendCount, () => new b2RopeBend()); + for (let i = 0; i < this.m_stretchCount; ++i) { + const c = this.m_stretchConstraints[i]; + const p1 = this.m_ps[i]; + const p2 = this.m_ps[i + 1]; + c.i1 = i; + c.i2 = i + 1; + c.L = b2Vec2.DistanceVV(p1, p2); + c.invMass1 = this.m_invMasses[i]; + c.invMass2 = this.m_invMasses[i + 1]; + c.lambda = 0.0; + c.damper = 0.0; + c.spring = 0.0; + } + for (let i = 0; i < this.m_bendCount; ++i) { + const c = this.m_bendConstraints[i]; + const p1 = this.m_ps[i]; + const p2 = this.m_ps[i + 1]; + const p3 = this.m_ps[i + 2]; + c.i1 = i; + c.i2 = i + 1; + c.i3 = i + 2; + c.invMass1 = this.m_invMasses[i]; + c.invMass2 = this.m_invMasses[i + 1]; + c.invMass3 = this.m_invMasses[i + 2]; + c.invEffectiveMass = 0.0; + c.L1 = b2Vec2.DistanceVV(p1, p2); + c.L2 = b2Vec2.DistanceVV(p2, p3); + c.lambda = 0.0; + // Pre-compute effective mass (TODO use flattened config) + const e1 = b2Vec2.SubVV(p2, p1, new b2Vec2()); + const e2 = b2Vec2.SubVV(p3, p2, new b2Vec2()); + const L1sqr = e1.LengthSquared(); + const L2sqr = e2.LengthSquared(); + if (L1sqr * L2sqr === 0.0) { + continue; + } + // b2Vec2 Jd1 = (-1.0 / L1sqr) * e1.Skew(); + const Jd1 = new b2Vec2().Copy(e1).SelfSkew().SelfMul(-1.0 / L1sqr); + // b2Vec2 Jd2 = (1.0 / L2sqr) * e2.Skew(); + const Jd2 = new b2Vec2().Copy(e2).SelfSkew().SelfMul(1.0 / L2sqr); + // b2Vec2 J1 = -Jd1; + const J1 = Jd1.Clone().SelfNeg(); + // b2Vec2 J2 = Jd1 - Jd2; + const J2 = Jd1.Clone().SelfSub(Jd2); + // b2Vec2 J3 = Jd2; + const J3 = Jd2.Clone(); + c.invEffectiveMass = c.invMass1 * b2Vec2.DotVV(J1, J1) + c.invMass2 * b2Vec2.DotVV(J2, J2) + c.invMass3 * b2Vec2.DotVV(J3, J3); + // b2Vec2 r = p3 - p1; + const r = b2Vec2.SubVV(p3, p1, new b2Vec2()); + const rr = r.LengthSquared(); + if (rr === 0.0) { + continue; + } + // a1 = h2 / (h1 + h2) + // a2 = h1 / (h1 + h2) + c.alpha1 = b2Vec2.DotVV(e2, r) / rr; + c.alpha2 = b2Vec2.DotVV(e1, r) / rr; + } + this.m_gravity.Copy(def.gravity); + this.SetTuning(def.tuning); + } + SetTuning(tuning) { + this.m_tuning.Copy(tuning); + // Pre-compute spring and damper values based on tuning + const bendOmega = 2.0 * b2_pi * this.m_tuning.bendHertz; + for (let i = 0; i < this.m_bendCount; ++i) { + const c = this.m_bendConstraints[i]; + const L1sqr = c.L1 * c.L1; + const L2sqr = c.L2 * c.L2; + if (L1sqr * L2sqr === 0.0) { + c.spring = 0.0; + c.damper = 0.0; + continue; + } + // Flatten the triangle formed by the two edges + const J2 = 1.0 / c.L1 + 1.0 / c.L2; + const sum = c.invMass1 / L1sqr + c.invMass2 * J2 * J2 + c.invMass3 / L2sqr; + if (sum === 0.0) { + c.spring = 0.0; + c.damper = 0.0; + continue; + } + const mass = 1.0 / sum; + c.spring = mass * bendOmega * bendOmega; + c.damper = 2.0 * mass * this.m_tuning.bendDamping * bendOmega; + } + const stretchOmega = 2.0 * b2_pi * this.m_tuning.stretchHertz; + for (let i = 0; i < this.m_stretchCount; ++i) { + const c = this.m_stretchConstraints[i]; + const sum = c.invMass1 + c.invMass2; + if (sum === 0.0) { + continue; + } + const mass = 1.0 / sum; + c.spring = mass * stretchOmega * stretchOmega; + c.damper = 2.0 * mass * this.m_tuning.stretchDamping * stretchOmega; + } + } + Step(dt, iterations, position) { + if (dt === 0.0) { + return; + } + const inv_dt = 1.0 / dt; + const d = Math.exp(-dt * this.m_tuning.damping); + // Apply gravity and damping + for (let i = 0; i < this.m_count; ++i) { + if (this.m_invMasses[i] > 0.0) { + // this.m_vs[i] *= d; + this.m_vs[i].x *= d; + this.m_vs[i].y *= d; + // this.m_vs[i] += dt * this.m_gravity; + this.m_vs[i].x += dt * this.m_gravity.x; + this.m_vs[i].y += dt * this.m_gravity.y; + } + else { + // this.m_vs[i] = inv_dt * (this.m_bindPositions[i] + position - this.m_p0s[i]); + this.m_vs[i].x = inv_dt * (this.m_bindPositions[i].x + position.x - this.m_p0s[i].x); + this.m_vs[i].y = inv_dt * (this.m_bindPositions[i].y + position.y - this.m_p0s[i].y); + } + } + // Apply bending spring + if (this.m_tuning.bendingModel === exports.b2BendingModel.b2_springAngleBendingModel) { + this.ApplyBendForces(dt); + } + for (let i = 0; i < this.m_bendCount; ++i) { + this.m_bendConstraints[i].lambda = 0.0; + } + for (let i = 0; i < this.m_stretchCount; ++i) { + this.m_stretchConstraints[i].lambda = 0.0; + } + // Update position + for (let i = 0; i < this.m_count; ++i) { + // this.m_ps[i] += dt * this.m_vs[i]; + this.m_ps[i].x += dt * this.m_vs[i].x; + this.m_ps[i].y += dt * this.m_vs[i].y; + } + // Solve constraints + for (let i = 0; i < iterations; ++i) { + if (this.m_tuning.bendingModel === exports.b2BendingModel.b2_pbdAngleBendingModel) { + this.SolveBend_PBD_Angle(); + } + else if (this.m_tuning.bendingModel === exports.b2BendingModel.b2_xpbdAngleBendingModel) { + this.SolveBend_XPBD_Angle(dt); + } + else if (this.m_tuning.bendingModel === exports.b2BendingModel.b2_pbdDistanceBendingModel) { + this.SolveBend_PBD_Distance(); + } + else if (this.m_tuning.bendingModel === exports.b2BendingModel.b2_pbdHeightBendingModel) { + this.SolveBend_PBD_Height(); + } + else if (this.m_tuning.bendingModel === exports.b2BendingModel.b2_pbdTriangleBendingModel) { + this.SolveBend_PBD_Triangle(); + } + if (this.m_tuning.stretchingModel === exports.b2StretchingModel.b2_pbdStretchingModel) { + this.SolveStretch_PBD(); + } + else if (this.m_tuning.stretchingModel === exports.b2StretchingModel.b2_xpbdStretchingModel) { + this.SolveStretch_XPBD(dt); + } + } + // Constrain velocity + for (let i = 0; i < this.m_count; ++i) { + // this.m_vs[i] = inv_dt * (this.m_ps[i] - this.m_p0s[i]); + this.m_vs[i].x = inv_dt * (this.m_ps[i].x - this.m_p0s[i].x); + this.m_vs[i].y = inv_dt * (this.m_ps[i].y - this.m_p0s[i].y); + this.m_p0s[i].Copy(this.m_ps[i]); + } + } + Reset(position) { + this.m_position.Copy(position); + for (let i = 0; i < this.m_count; ++i) { + // this.m_ps[i] = this.m_bindPositions[i] + this.m_position; + this.m_ps[i].x = this.m_bindPositions[i].x + this.m_position.x; + this.m_ps[i].y = this.m_bindPositions[i].y + this.m_position.y; + // this.m_p0s[i] = this.m_bindPositions[i] + this.m_position; + this.m_p0s[i].x = this.m_bindPositions[i].x + this.m_position.x; + this.m_p0s[i].y = this.m_bindPositions[i].y + this.m_position.y; + this.m_vs[i].SetZero(); + } + for (let i = 0; i < this.m_bendCount; ++i) { + this.m_bendConstraints[i].lambda = 0.0; + } + for (let i = 0; i < this.m_stretchCount; ++i) { + this.m_stretchConstraints[i].lambda = 0.0; + } + } + Draw(draw) { + const c = new b2Color(0.4, 0.5, 0.7); + const pg = new b2Color(0.1, 0.8, 0.1); + const pd = new b2Color(0.7, 0.2, 0.4); + for (let i = 0; i < this.m_count - 1; ++i) { + draw.DrawSegment(this.m_ps[i], this.m_ps[i + 1], c); + const pc = this.m_invMasses[i] > 0.0 ? pd : pg; + draw.DrawPoint(this.m_ps[i], 5.0, pc); + } + const pc = this.m_invMasses[this.m_count - 1] > 0.0 ? pd : pg; + draw.DrawPoint(this.m_ps[this.m_count - 1], 5.0, pc); + } + SolveStretch_PBD() { + const stiffness = this.m_tuning.stretchStiffness; + for (let i = 0; i < this.m_stretchCount; ++i) { + const c = this.m_stretchConstraints[i]; + const p1 = this.m_ps[c.i1].Clone(); + const p2 = this.m_ps[c.i2].Clone(); + // b2Vec2 d = p2 - p1; + const d = p2.Clone().SelfSub(p1); + const L = d.Normalize(); + const sum = c.invMass1 + c.invMass2; + if (sum === 0.0) { + continue; + } + const s1 = c.invMass1 / sum; + const s2 = c.invMass2 / sum; + // p1 -= stiffness * s1 * (c.L - L) * d; + p1.x -= stiffness * s1 * (c.L - L) * d.x; + p1.y -= stiffness * s1 * (c.L - L) * d.y; + // p2 += stiffness * s2 * (c.L - L) * d; + p2.x += stiffness * s2 * (c.L - L) * d.x; + p2.y += stiffness * s2 * (c.L - L) * d.y; + this.m_ps[c.i1].Copy(p1); + this.m_ps[c.i2].Copy(p2); + } + } + SolveStretch_XPBD(dt) { + // b2Assert(dt > 0.0); + for (let i = 0; i < this.m_stretchCount; ++i) { + const c = this.m_stretchConstraints[i]; + const p1 = this.m_ps[c.i1].Clone(); + const p2 = this.m_ps[c.i2].Clone(); + const dp1 = p1.Clone().SelfSub(this.m_p0s[c.i1]); + const dp2 = p2.Clone().SelfSub(this.m_p0s[c.i2]); + // b2Vec2 u = p2 - p1; + const u = p2.Clone().SelfSub(p1); + const L = u.Normalize(); + // b2Vec2 J1 = -u; + const J1 = u.Clone().SelfNeg(); + // b2Vec2 J2 = u; + const J2 = u; + const sum = c.invMass1 + c.invMass2; + if (sum === 0.0) { + continue; + } + const alpha = 1.0 / (c.spring * dt * dt); // 1 / kg + const beta = dt * dt * c.damper; // kg * s + const sigma = alpha * beta / dt; // non-dimensional + const C = L - c.L; + // This is using the initial velocities + const Cdot = b2Vec2.DotVV(J1, dp1) + b2Vec2.DotVV(J2, dp2); + const B = C + alpha * c.lambda + sigma * Cdot; + const sum2 = (1.0 + sigma) * sum + alpha; + const impulse = -B / sum2; + // p1 += (c.invMass1 * impulse) * J1; + p1.x += (c.invMass1 * impulse) * J1.x; + p1.y += (c.invMass1 * impulse) * J1.y; + // p2 += (c.invMass2 * impulse) * J2; + p2.x += (c.invMass2 * impulse) * J2.x; + p2.y += (c.invMass2 * impulse) * J2.y; + this.m_ps[c.i1].Copy(p1); + this.m_ps[c.i2].Copy(p2); + c.lambda += impulse; + } + } + SolveBend_PBD_Angle() { + const stiffness = this.m_tuning.bendStiffness; + for (let i = 0; i < this.m_bendCount; ++i) { + const c = this.m_bendConstraints[i]; + const p1 = this.m_ps[c.i1]; + const p2 = this.m_ps[c.i2]; + const p3 = this.m_ps[c.i3]; + // b2Vec2 d1 = p2 - p1; + const d1 = p2.Clone().SelfSub(p1); + // b2Vec2 d2 = p3 - p2; + const d2 = p3.Clone().SelfSub(p2); + const a = b2Vec2.CrossVV(d1, d2); + const b = b2Vec2.DotVV(d1, d2); + const angle = b2Atan2(a, b); + let L1sqr = 0.0, L2sqr = 0.0; + if (this.m_tuning.isometric) { + L1sqr = c.L1 * c.L1; + L2sqr = c.L2 * c.L2; + } + else { + L1sqr = d1.LengthSquared(); + L2sqr = d2.LengthSquared(); + } + if (L1sqr * L2sqr === 0.0) { + continue; + } + // b2Vec2 Jd1 = (-1.0 / L1sqr) * d1.Skew(); + const Jd1 = new b2Vec2().Copy(d1).SelfSkew().SelfMul(-1.0 / L1sqr); + // b2Vec2 Jd2 = (1.0 / L2sqr) * d2.Skew(); + const Jd2 = new b2Vec2().Copy(d2).SelfSkew().SelfMul(1.0 / L2sqr); + // b2Vec2 J1 = -Jd1; + const J1 = Jd1.Clone().SelfNeg(); + // b2Vec2 J2 = Jd1 - Jd2; + const J2 = Jd1.Clone().SelfSub(Jd2); + // b2Vec2 J3 = Jd2; + const J3 = Jd2; + let sum = 0.0; + if (this.m_tuning.fixedEffectiveMass) { + sum = c.invEffectiveMass; + } + else { + sum = c.invMass1 * b2Vec2.DotVV(J1, J1) + c.invMass2 * b2Vec2.DotVV(J2, J2) + c.invMass3 * b2Vec2.DotVV(J3, J3); + } + if (sum === 0.0) { + sum = c.invEffectiveMass; + } + const impulse = -stiffness * angle / sum; + // p1 += (c.invMass1 * impulse) * J1; + p1.x += (c.invMass1 * impulse) * J1.x; + p1.y += (c.invMass1 * impulse) * J1.y; + // p2 += (c.invMass2 * impulse) * J2; + p2.x += (c.invMass2 * impulse) * J2.x; + p2.y += (c.invMass2 * impulse) * J2.y; + // p3 += (c.invMass3 * impulse) * J3; + p3.x += (c.invMass3 * impulse) * J3.x; + p3.y += (c.invMass3 * impulse) * J3.y; + this.m_ps[c.i1].Copy(p1); + this.m_ps[c.i2].Copy(p2); + this.m_ps[c.i3].Copy(p3); + } + } + SolveBend_XPBD_Angle(dt) { + // b2Assert(dt > 0.0); + for (let i = 0; i < this.m_bendCount; ++i) { + const c = this.m_bendConstraints[i]; + const p1 = this.m_ps[c.i1]; + const p2 = this.m_ps[c.i2]; + const p3 = this.m_ps[c.i3]; + const dp1 = p1.Clone().SelfSub(this.m_p0s[c.i1]); + const dp2 = p2.Clone().SelfSub(this.m_p0s[c.i2]); + const dp3 = p3.Clone().SelfSub(this.m_p0s[c.i3]); + // b2Vec2 d1 = p2 - p1; + const d1 = p2.Clone().SelfSub(p1); + // b2Vec2 d2 = p3 - p2; + const d2 = p3.Clone().SelfSub(p2); + let L1sqr, L2sqr; + if (this.m_tuning.isometric) { + L1sqr = c.L1 * c.L1; + L2sqr = c.L2 * c.L2; + } + else { + L1sqr = d1.LengthSquared(); + L2sqr = d2.LengthSquared(); + } + if (L1sqr * L2sqr === 0.0) { + continue; + } + const a = b2Vec2.CrossVV(d1, d2); + const b = b2Vec2.DotVV(d1, d2); + const angle = b2Atan2(a, b); + // b2Vec2 Jd1 = (-1.0 / L1sqr) * d1.Skew(); + // b2Vec2 Jd2 = (1.0 / L2sqr) * d2.Skew(); + // b2Vec2 J1 = -Jd1; + // b2Vec2 J2 = Jd1 - Jd2; + // b2Vec2 J3 = Jd2; + // b2Vec2 Jd1 = (-1.0 / L1sqr) * d1.Skew(); + const Jd1 = new b2Vec2().Copy(d1).SelfSkew().SelfMul(-1.0 / L1sqr); + // b2Vec2 Jd2 = (1.0 / L2sqr) * d2.Skew(); + const Jd2 = new b2Vec2().Copy(d2).SelfSkew().SelfMul(1.0 / L2sqr); + // b2Vec2 J1 = -Jd1; + const J1 = Jd1.Clone().SelfNeg(); + // b2Vec2 J2 = Jd1 - Jd2; + const J2 = Jd1.Clone().SelfSub(Jd2); + // b2Vec2 J3 = Jd2; + const J3 = Jd2; + let sum; + if (this.m_tuning.fixedEffectiveMass) { + sum = c.invEffectiveMass; + } + else { + sum = c.invMass1 * b2Vec2.DotVV(J1, J1) + c.invMass2 * b2Vec2.DotVV(J2, J2) + c.invMass3 * b2Vec2.DotVV(J3, J3); + } + if (sum === 0.0) { + continue; + } + const alpha = 1.0 / (c.spring * dt * dt); + const beta = dt * dt * c.damper; + const sigma = alpha * beta / dt; + const C = angle; + // This is using the initial velocities + const Cdot = b2Vec2.DotVV(J1, dp1) + b2Vec2.DotVV(J2, dp2) + b2Vec2.DotVV(J3, dp3); + const B = C + alpha * c.lambda + sigma * Cdot; + const sum2 = (1.0 + sigma) * sum + alpha; + const impulse = -B / sum2; + // p1 += (c.invMass1 * impulse) * J1; + p1.x += (c.invMass1 * impulse) * J1.x; + p1.y += (c.invMass1 * impulse) * J1.y; + // p2 += (c.invMass2 * impulse) * J2; + p2.x += (c.invMass2 * impulse) * J2.x; + p2.y += (c.invMass2 * impulse) * J2.y; + // p3 += (c.invMass3 * impulse) * J3; + p3.x += (c.invMass3 * impulse) * J3.x; + p3.y += (c.invMass3 * impulse) * J3.y; + this.m_ps[c.i1].Copy(p1); + this.m_ps[c.i2].Copy(p2); + this.m_ps[c.i3].Copy(p3); + c.lambda += impulse; + } + } + SolveBend_PBD_Distance() { + const stiffness = this.m_tuning.bendStiffness; + for (let i = 0; i < this.m_bendCount; ++i) { + const c = this.m_bendConstraints[i]; + const i1 = c.i1; + const i2 = c.i3; + const p1 = this.m_ps[i1].Clone(); + const p2 = this.m_ps[i2].Clone(); + // b2Vec2 d = p2 - p1; + const d = p2.Clone().SelfSub(p1); + const L = d.Normalize(); + const sum = c.invMass1 + c.invMass3; + if (sum === 0.0) { + continue; + } + const s1 = c.invMass1 / sum; + const s2 = c.invMass3 / sum; + // p1 -= stiffness * s1 * (c.L1 + c.L2 - L) * d; + p1.x -= stiffness * s1 * (c.L1 + c.L2 - L) * d.x; + p1.y -= stiffness * s1 * (c.L1 + c.L2 - L) * d.y; + // p2 += stiffness * s2 * (c.L1 + c.L2 - L) * d; + p2.x += stiffness * s2 * (c.L1 + c.L2 - L) * d.x; + p2.y += stiffness * s2 * (c.L1 + c.L2 - L) * d.y; + this.m_ps[i1].Copy(p1); + this.m_ps[i2].Copy(p2); + } + } + SolveBend_PBD_Height() { + const stiffness = this.m_tuning.bendStiffness; + for (let i = 0; i < this.m_bendCount; ++i) { + const c = this.m_bendConstraints[i]; + const p1 = this.m_ps[c.i1].Clone(); + const p2 = this.m_ps[c.i2].Clone(); + const p3 = this.m_ps[c.i3].Clone(); + // Barycentric coordinates are held constant + const d = new b2Vec2(); + // b2Vec2 d = c.alpha1 * p1 + c.alpha2 * p3 - p2; + d.x = c.alpha1 * p1.x + c.alpha2 * p3.x - p2.x; + d.y = c.alpha1 * p1.y + c.alpha2 * p3.y - p2.y; + const dLen = d.Length(); + if (dLen === 0.0) { + continue; + } + // b2Vec2 dHat = (1.0 / dLen) * d; + const dHat = d.Clone().SelfMul(1.0 / dLen); + // b2Vec2 J1 = c.alpha1 * dHat; + const J1 = dHat.Clone().SelfMul(c.alpha1); + // b2Vec2 J2 = -dHat; + const J2 = dHat.Clone().SelfNeg(); + // b2Vec2 J3 = c.alpha2 * dHat; + const J3 = dHat.Clone().SelfMul(c.alpha2); + const sum = c.invMass1 * c.alpha1 * c.alpha1 + c.invMass2 + c.invMass3 * c.alpha2 * c.alpha2; + if (sum === 0.0) { + continue; + } + const C = dLen; + const mass = 1.0 / sum; + const impulse = -stiffness * mass * C; + // p1 += (c.invMass1 * impulse) * J1; + p1.x += (c.invMass1 * impulse) * J1.x; + p1.y += (c.invMass1 * impulse) * J1.y; + // p2 += (c.invMass2 * impulse) * J2; + p2.x += (c.invMass2 * impulse) * J2.x; + p2.y += (c.invMass2 * impulse) * J2.y; + // p3 += (c.invMass3 * impulse) * J3; + p3.x += (c.invMass3 * impulse) * J3.x; + p3.y += (c.invMass3 * impulse) * J3.y; + this.m_ps[c.i1].Copy(p1); + this.m_ps[c.i2].Copy(p2); + this.m_ps[c.i3].Copy(p3); + } + } + // M. Kelager: A Triangle Bending Constraint Model for PBD + SolveBend_PBD_Triangle() { + const stiffness = this.m_tuning.bendStiffness; + for (let i = 0; i < this.m_bendCount; ++i) { + const c = this.m_bendConstraints[i]; + const b0 = this.m_ps[c.i1].Clone(); + const v = this.m_ps[c.i2].Clone(); + const b1 = this.m_ps[c.i3].Clone(); + const wb0 = c.invMass1; + const wv = c.invMass2; + const wb1 = c.invMass3; + const W = wb0 + wb1 + 2.0 * wv; + const invW = stiffness / W; + const d = new b2Vec2(); + d.x = v.x - (1.0 / 3.0) * (b0.x + v.x + b1.x); + d.y = v.y - (1.0 / 3.0) * (b0.y + v.y + b1.y); + const db0 = new b2Vec2(); + db0.x = 2.0 * wb0 * invW * d.x; + db0.y = 2.0 * wb0 * invW * d.y; + const dv = new b2Vec2(); + dv.x = -4.0 * wv * invW * d.x; + dv.y = -4.0 * wv * invW * d.y; + const db1 = new b2Vec2(); + db1.x = 2.0 * wb1 * invW * d.x; + db1.y = 2.0 * wb1 * invW * d.y; + b0.SelfAdd(db0); + v.SelfAdd(dv); + b1.SelfAdd(db1); + this.m_ps[c.i1].Copy(b0); + this.m_ps[c.i2].Copy(v); + this.m_ps[c.i3].Copy(b1); + } + } + ApplyBendForces(dt) { + // omega = 2 * pi * hz + const omega = 2.0 * b2_pi * this.m_tuning.bendHertz; + for (let i = 0; i < this.m_bendCount; ++i) { + const c = this.m_bendConstraints[i]; + const p1 = this.m_ps[c.i1].Clone(); + const p2 = this.m_ps[c.i2].Clone(); + const p3 = this.m_ps[c.i3].Clone(); + const v1 = this.m_vs[c.i1]; + const v2 = this.m_vs[c.i2]; + const v3 = this.m_vs[c.i3]; + // b2Vec2 d1 = p2 - p1; + const d1 = p1.Clone().SelfSub(p1); + // b2Vec2 d2 = p3 - p2; + const d2 = p3.Clone().SelfSub(p2); + let L1sqr, L2sqr; + if (this.m_tuning.isometric) { + L1sqr = c.L1 * c.L1; + L2sqr = c.L2 * c.L2; + } + else { + L1sqr = d1.LengthSquared(); + L2sqr = d2.LengthSquared(); + } + if (L1sqr * L2sqr === 0.0) { + continue; + } + const a = b2Vec2.CrossVV(d1, d2); + const b = b2Vec2.DotVV(d1, d2); + const angle = b2Atan2(a, b); + // b2Vec2 Jd1 = (-1.0 / L1sqr) * d1.Skew(); + // b2Vec2 Jd2 = (1.0 / L2sqr) * d2.Skew(); + // b2Vec2 J1 = -Jd1; + // b2Vec2 J2 = Jd1 - Jd2; + // b2Vec2 J3 = Jd2; + // b2Vec2 Jd1 = (-1.0 / L1sqr) * d1.Skew(); + const Jd1 = new b2Vec2().Copy(d1).SelfSkew().SelfMul(-1.0 / L1sqr); + // b2Vec2 Jd2 = (1.0 / L2sqr) * d2.Skew(); + const Jd2 = new b2Vec2().Copy(d2).SelfSkew().SelfMul(1.0 / L2sqr); + // b2Vec2 J1 = -Jd1; + const J1 = Jd1.Clone().SelfNeg(); + // b2Vec2 J2 = Jd1 - Jd2; + const J2 = Jd1.Clone().SelfSub(Jd2); + // b2Vec2 J3 = Jd2; + const J3 = Jd2; + let sum = 0.0; + if (this.m_tuning.fixedEffectiveMass) { + sum = c.invEffectiveMass; + } + else { + sum = c.invMass1 * b2Vec2.DotVV(J1, J1) + c.invMass2 * b2Vec2.DotVV(J2, J2) + c.invMass3 * b2Vec2.DotVV(J3, J3); + } + if (sum === 0.0) { + continue; + } + const mass = 1.0 / sum; + const spring = mass * omega * omega; + const damper = 2.0 * mass * this.m_tuning.bendDamping * omega; + const C = angle; + const Cdot = b2Vec2.DotVV(J1, v1) + b2Vec2.DotVV(J2, v2) + b2Vec2.DotVV(J3, v3); + const impulse = -dt * (spring * C + damper * Cdot); + // this.m_vs[c.i1] += (c.invMass1 * impulse) * J1; + this.m_vs[c.i1].x += (c.invMass1 * impulse) * J1.x; + this.m_vs[c.i1].y += (c.invMass1 * impulse) * J1.y; + // this.m_vs[c.i2] += (c.invMass2 * impulse) * J2; + this.m_vs[c.i2].x += (c.invMass2 * impulse) * J2.x; + this.m_vs[c.i2].y += (c.invMass2 * impulse) * J2.y; + // this.m_vs[c.i3] += (c.invMass3 * impulse) * J3; + this.m_vs[c.i3].x += (c.invMass3 * impulse) * J3.x; + this.m_vs[c.i3].y += (c.invMass3 * impulse) * J3.y; + } + } + } + + const staticBody = exports.b2BodyType.b2_staticBody; + const kinematicBody = exports.b2BodyType.b2_kinematicBody; + const dynamicBody = exports.b2BodyType.b2_dynamicBody; + const springAngleBendingModel = exports.b2BendingModel.b2_springAngleBendingModel; + const pbdAngleBendingModel = exports.b2BendingModel.b2_pbdAngleBendingModel; + const xpbdAngleBendingModel = exports.b2BendingModel.b2_xpbdAngleBendingModel; + const pbdDistanceBendingModel = exports.b2BendingModel.b2_pbdDistanceBendingModel; + const pbdHeightBendingModel = exports.b2BendingModel.b2_pbdHeightBendingModel; + const pbdTriangleBendingModel = exports.b2BendingModel.b2_pbdTriangleBendingModel; + const pbdStretchingModel = exports.b2StretchingModel.b2_pbdStretchingModel; + const xpbdStretchingModel = exports.b2StretchingModel.b2_xpbdStretchingModel; + + exports.b2AABB = b2AABB; + exports.b2Abs = b2Abs; + exports.b2Acos = b2Acos; + exports.b2Alloc = b2Alloc; + exports.b2AngularStiffness = b2AngularStiffness; + exports.b2AreaJoint = b2AreaJoint; + exports.b2AreaJointDef = b2AreaJointDef; + exports.b2Asin = b2Asin; + exports.b2Assert = b2Assert; + exports.b2Atan2 = b2Atan2; + exports.b2BlockAllocator = b2BlockAllocator; + exports.b2Body = b2Body; + exports.b2BodyDef = b2BodyDef; + exports.b2BroadPhase = b2BroadPhase; + exports.b2ChainAndCircleContact = b2ChainAndCircleContact; + exports.b2ChainAndPolygonContact = b2ChainAndPolygonContact; + exports.b2ChainShape = b2ChainShape; + exports.b2CircleContact = b2CircleContact; + exports.b2CircleShape = b2CircleShape; + exports.b2Clamp = b2Clamp; + exports.b2ClipSegmentToLine = b2ClipSegmentToLine; + exports.b2ClipVertex = b2ClipVertex; + exports.b2CollideCircles = b2CollideCircles; + exports.b2CollideEdgeAndCircle = b2CollideEdgeAndCircle; + exports.b2CollideEdgeAndPolygon = b2CollideEdgeAndPolygon; + exports.b2CollidePolygonAndCircle = b2CollidePolygonAndCircle; + exports.b2CollidePolygons = b2CollidePolygons; + exports.b2Color = b2Color; + exports.b2Contact = b2Contact; + exports.b2ContactEdge = b2ContactEdge; + exports.b2ContactFactory = b2ContactFactory; + exports.b2ContactFeature = b2ContactFeature; + exports.b2ContactFilter = b2ContactFilter; + exports.b2ContactID = b2ContactID; + exports.b2ContactImpulse = b2ContactImpulse; + exports.b2ContactListener = b2ContactListener; + exports.b2ContactManager = b2ContactManager; + exports.b2ContactPositionConstraint = b2ContactPositionConstraint; + exports.b2ContactRegister = b2ContactRegister; + exports.b2ContactSolver = b2ContactSolver; + exports.b2ContactSolverDef = b2ContactSolverDef; + exports.b2ContactVelocityConstraint = b2ContactVelocityConstraint; + exports.b2Cos = b2Cos; + exports.b2Counter = b2Counter; + exports.b2DegToRad = b2DegToRad; + exports.b2DestructionListener = b2DestructionListener; + exports.b2Distance = b2Distance; + exports.b2DistanceInput = b2DistanceInput; + exports.b2DistanceJoint = b2DistanceJoint; + exports.b2DistanceJointDef = b2DistanceJointDef; + exports.b2DistanceOutput = b2DistanceOutput; + exports.b2DistanceProxy = b2DistanceProxy; + exports.b2Draw = b2Draw; + exports.b2DynamicTree = b2DynamicTree; + exports.b2EdgeAndCircleContact = b2EdgeAndCircleContact; + exports.b2EdgeAndPolygonContact = b2EdgeAndPolygonContact; + exports.b2EdgeShape = b2EdgeShape; + exports.b2Filter = b2Filter; + exports.b2Fixture = b2Fixture; + exports.b2FixtureDef = b2FixtureDef; + exports.b2FixtureProxy = b2FixtureProxy; + exports.b2Free = b2Free; + exports.b2FrictionJoint = b2FrictionJoint; + exports.b2FrictionJointDef = b2FrictionJointDef; + exports.b2GearJoint = b2GearJoint; + exports.b2GearJointDef = b2GearJointDef; + exports.b2GetPointStates = b2GetPointStates; + exports.b2GrowableStack = b2GrowableStack; + exports.b2InvSqrt = b2InvSqrt; + exports.b2IsPowerOfTwo = b2IsPowerOfTwo; + exports.b2IsValid = b2IsValid; + exports.b2Island = b2Island; + exports.b2Jacobian = b2Jacobian; + exports.b2Joint = b2Joint; + exports.b2JointDef = b2JointDef; + exports.b2JointEdge = b2JointEdge; + exports.b2LinearStiffness = b2LinearStiffness; + exports.b2Log = b2Log; + exports.b2MakeArray = b2MakeArray; + exports.b2MakeNullArray = b2MakeNullArray; + exports.b2MakeNumberArray = b2MakeNumberArray; + exports.b2Manifold = b2Manifold; + exports.b2ManifoldPoint = b2ManifoldPoint; + exports.b2MassData = b2MassData; + exports.b2Mat22 = b2Mat22; + exports.b2Mat33 = b2Mat33; + exports.b2Max = b2Max; + exports.b2Maybe = b2Maybe; + exports.b2Min = b2Min; + exports.b2MixFriction = b2MixFriction; + exports.b2MixRestitution = b2MixRestitution; + exports.b2MixRestitutionThreshold = b2MixRestitutionThreshold; + exports.b2MotorJoint = b2MotorJoint; + exports.b2MotorJointDef = b2MotorJointDef; + exports.b2MouseJoint = b2MouseJoint; + exports.b2MouseJointDef = b2MouseJointDef; + exports.b2NextPowerOfTwo = b2NextPowerOfTwo; + exports.b2Pair = b2Pair; + exports.b2ParseInt = b2ParseInt; + exports.b2ParseUInt = b2ParseUInt; + exports.b2PolygonAndCircleContact = b2PolygonAndCircleContact; + exports.b2PolygonContact = b2PolygonContact; + exports.b2PolygonShape = b2PolygonShape; + exports.b2Position = b2Position; + exports.b2PositionSolverManifold = b2PositionSolverManifold; + exports.b2Pow = b2Pow; + exports.b2PrismaticJoint = b2PrismaticJoint; + exports.b2PrismaticJointDef = b2PrismaticJointDef; + exports.b2Profile = b2Profile; + exports.b2PulleyJoint = b2PulleyJoint; + exports.b2PulleyJointDef = b2PulleyJointDef; + exports.b2QueryCallback = b2QueryCallback; + exports.b2RadToDeg = b2RadToDeg; + exports.b2Random = b2Random; + exports.b2RandomRange = b2RandomRange; + exports.b2RayCastCallback = b2RayCastCallback; + exports.b2RayCastInput = b2RayCastInput; + exports.b2RayCastOutput = b2RayCastOutput; + exports.b2RevoluteJoint = b2RevoluteJoint; + exports.b2RevoluteJointDef = b2RevoluteJointDef; + exports.b2Rope = b2Rope; + exports.b2RopeDef = b2RopeDef; + exports.b2RopeTuning = b2RopeTuning; + exports.b2Rot = b2Rot; + exports.b2SeparationFunction = b2SeparationFunction; + exports.b2Shape = b2Shape; + exports.b2ShapeCast = b2ShapeCast; + exports.b2ShapeCastInput = b2ShapeCastInput; + exports.b2ShapeCastOutput = b2ShapeCastOutput; + exports.b2Simplex = b2Simplex; + exports.b2SimplexCache = b2SimplexCache; + exports.b2SimplexVertex = b2SimplexVertex; + exports.b2Sin = b2Sin; + exports.b2SolverData = b2SolverData; + exports.b2Sq = b2Sq; + exports.b2Sqrt = b2Sqrt; + exports.b2StackAllocator = b2StackAllocator; + exports.b2Swap = b2Swap; + exports.b2Sweep = b2Sweep; + exports.b2TOIInput = b2TOIInput; + exports.b2TOIOutput = b2TOIOutput; + exports.b2TestOverlapAABB = b2TestOverlapAABB; + exports.b2TestOverlapShape = b2TestOverlapShape; + exports.b2TimeOfImpact = b2TimeOfImpact; + exports.b2TimeStep = b2TimeStep; + exports.b2Timer = b2Timer; + exports.b2Transform = b2Transform; + exports.b2TreeNode = b2TreeNode; + exports.b2Vec2 = b2Vec2; + exports.b2Vec2_zero = b2Vec2_zero; + exports.b2Vec3 = b2Vec3; + exports.b2Velocity = b2Velocity; + exports.b2VelocityConstraintPoint = b2VelocityConstraintPoint; + exports.b2Version = b2Version; + exports.b2WeldJoint = b2WeldJoint; + exports.b2WeldJointDef = b2WeldJointDef; + exports.b2WheelJoint = b2WheelJoint; + exports.b2WheelJointDef = b2WheelJointDef; + exports.b2World = b2World; + exports.b2WorldManifold = b2WorldManifold; + exports.b2_180_over_pi = b2_180_over_pi; + exports.b2_aabbExtension = b2_aabbExtension; + exports.b2_aabbMultiplier = b2_aabbMultiplier; + exports.b2_angularSleepTolerance = b2_angularSleepTolerance; + exports.b2_angularSlop = b2_angularSlop; + exports.b2_baumgarte = b2_baumgarte; + exports.b2_branch = b2_branch; + exports.b2_commit = b2_commit; + exports.b2_epsilon = b2_epsilon; + exports.b2_epsilon_sq = b2_epsilon_sq; + exports.b2_gjk_reset = b2_gjk_reset; + exports.b2_lengthUnitsPerMeter = b2_lengthUnitsPerMeter; + exports.b2_linearSleepTolerance = b2_linearSleepTolerance; + exports.b2_linearSlop = b2_linearSlop; + exports.b2_maxAngularCorrection = b2_maxAngularCorrection; + exports.b2_maxFloat = b2_maxFloat; + exports.b2_maxLinearCorrection = b2_maxLinearCorrection; + exports.b2_maxManifoldPoints = b2_maxManifoldPoints; + exports.b2_maxPolygonVertices = b2_maxPolygonVertices; + exports.b2_maxRotation = b2_maxRotation; + exports.b2_maxRotationSquared = b2_maxRotationSquared; + exports.b2_maxSubSteps = b2_maxSubSteps; + exports.b2_maxTOIContacts = b2_maxTOIContacts; + exports.b2_maxTranslation = b2_maxTranslation; + exports.b2_maxTranslationSquared = b2_maxTranslationSquared; + exports.b2_minPulleyLength = b2_minPulleyLength; + exports.b2_pi = b2_pi; + exports.b2_pi_over_180 = b2_pi_over_180; + exports.b2_polygonRadius = b2_polygonRadius; + exports.b2_timeToSleep = b2_timeToSleep; + exports.b2_toiBaumgarte = b2_toiBaumgarte; + exports.b2_toi_reset = b2_toi_reset; + exports.b2_two_pi = b2_two_pi; + exports.b2_version = b2_version; + exports.dynamicBody = dynamicBody; + exports.get_g_blockSolve = get_g_blockSolve; + exports.kinematicBody = kinematicBody; + exports.pbdAngleBendingModel = pbdAngleBendingModel; + exports.pbdDistanceBendingModel = pbdDistanceBendingModel; + exports.pbdHeightBendingModel = pbdHeightBendingModel; + exports.pbdStretchingModel = pbdStretchingModel; + exports.pbdTriangleBendingModel = pbdTriangleBendingModel; + exports.set_g_blockSolve = set_g_blockSolve; + exports.springAngleBendingModel = springAngleBendingModel; + exports.staticBody = staticBody; + exports.xpbdAngleBendingModel = xpbdAngleBendingModel; + exports.xpbdStretchingModel = xpbdStretchingModel; + + Object.defineProperty(exports, '__esModule', { value: true }); + + return exports; + +}({})); + +(function (exports, Laya) { + 'use strict'; + + class IPhysics { + } + IPhysics.RigidBody = null; + IPhysics.Physics = null; + + class ColliderBase extends Laya.Component { + constructor() { + super(...arguments); + this._isSensor = false; + this._density = 10; + this._friction = 0.2; + this._restitution = 0; + } + getDef() { + if (!this._def) { + var def = new window.box2d.b2FixtureDef(); + def.density = this.density; + def.friction = this.friction; + def.isSensor = this.isSensor; + def.restitution = this.restitution; + def.shape = this._shape; + this._def = def; + } + return this._def; + } + _onEnable() { + if (this.rigidBody) { + this.refresh(); + } + else { + Laya.Laya.systemTimer.callLater(this, this._checkRigidBody); + } + } + _checkRigidBody() { + if (!this.rigidBody) { + var comp = this.owner.getComponent(IPhysics.RigidBody); + if (comp) { + this.rigidBody = comp; + this.refresh(); + } + } + } + _onDestroy() { + if (this.rigidBody) { + if (this.fixture) { + if (this.fixture.GetBody() == this.rigidBody._getOriBody()) { + this.rigidBody.body.DestroyFixture(this.fixture); + } + this.fixture = null; + } + this.rigidBody = null; + this._shape = null; + this._def = null; + } + } + get isSensor() { + return this._isSensor; + } + set isSensor(value) { + this._isSensor = value; + if (this._def) { + this._def.isSensor = value; + this.refresh(); + } + } + get density() { + return this._density; + } + set density(value) { + this._density = value; + if (this._def) { + this._def.density = value; + this.refresh(); + } + } + get friction() { + return this._friction; + } + set friction(value) { + this._friction = value; + if (this._def) { + this._def.friction = value; + this.refresh(); + } + } + get restitution() { + return this._restitution; + } + set restitution(value) { + this._restitution = value; + if (this._def) { + this._def.restitution = value; + this.refresh(); + } + } + refresh() { + if (this.enabled && this.rigidBody) { + var body = this.rigidBody.body; + if (this.fixture) { + if (this.fixture.GetBody() == this.rigidBody.body) { + this.rigidBody.body.DestroyFixture(this.fixture); + } + this.fixture.Destroy(); + this.fixture = null; + } + var def = this.getDef(); + def.filter.groupIndex = this.rigidBody.group; + def.filter.categoryBits = this.rigidBody.category; + def.filter.maskBits = this.rigidBody.mask; + this.fixture = body.CreateFixture(def); + this.fixture.collider = this; + } + } + resetShape(re = true) { + } + get isSingleton() { + return false; + } + } + Laya.ClassUtils.regClass("laya.physics.ColliderBase", ColliderBase); + Laya.ClassUtils.regClass("Laya.ColliderBase", ColliderBase); + + class RigidBody extends Laya.Component { + constructor() { + super(...arguments); + this._type = "dynamic"; + this._allowSleep = true; + this._angularVelocity = 0; + this._angularDamping = 0; + this._linearVelocity = { x: 0, y: 0 }; + this._linearDamping = 0; + this._bullet = false; + this._allowRotation = true; + this._gravityScale = 1; + this.group = 0; + this.category = 1; + this.mask = -1; + this.label = "RigidBody"; + } + _createBody() { + if (this._body || !this.owner) + return; + var sp = this.owner; + var box2d = window.box2d; + var def = new box2d.b2BodyDef(); + var point = sp.localToGlobal(Laya.Point.TEMP.setTo(0, 0), false, IPhysics.Physics.I.worldRoot); + def.position.Set(point.x / IPhysics.Physics.PIXEL_RATIO, point.y / IPhysics.Physics.PIXEL_RATIO); + def.angle = Laya.Utils.toRadian(sp.rotation); + def.allowSleep = this._allowSleep; + def.angularDamping = this._angularDamping; + def.angularVelocity = this._angularVelocity; + def.bullet = this._bullet; + def.fixedRotation = !this._allowRotation; + def.gravityScale = this._gravityScale; + def.linearDamping = this._linearDamping; + var obj = this._linearVelocity; + if (obj && obj.x != 0 || obj.y != 0) { + def.linearVelocity = new box2d.b2Vec2(obj.x, obj.y); + } + def.type = box2d.b2BodyType["b2_" + this._type + "Body"]; + this._body = IPhysics.Physics.I._createBody(def); + this.resetCollider(false); + } + _onAwake() { + this._createBody(); + } + _onEnable() { + var _$this = this; + this._createBody(); + Laya.Laya.physicsTimer.frameLoop(1, this, this._sysPhysicToNode); + var sp = this.owner; + if (this.accessGetSetFunc(sp, "x", "set") && !sp._changeByRigidBody) { + sp._changeByRigidBody = true; + function setX(value) { + _$this.accessGetSetFunc(sp, "x", "set")(value); + _$this._sysPosToPhysic(); + } + this._overSet(sp, "x", setX); + function setY(value) { + _$this.accessGetSetFunc(sp, "y", "set")(value); + _$this._sysPosToPhysic(); + } + this._overSet(sp, "y", setY); + function setRotation(value) { + _$this.accessGetSetFunc(sp, "rotation", "set")(value); + _$this._sysNodeToPhysic(); + } + this._overSet(sp, "rotation", setRotation); + function setScaleX(value) { + _$this.accessGetSetFunc(sp, "scaleX", "set")(value); + _$this.resetCollider(true); + } + this._overSet(sp, "scaleX", setScaleX); + function setScaleY(value) { + _$this.accessGetSetFunc(sp, "scaleY", "set")(value); + _$this.resetCollider(true); + } + this._overSet(sp, "scaleY", setScaleY); + } + } + accessGetSetFunc(obj, prop, accessor) { + if (["get", "set"].indexOf(accessor) === -1) { + return; + } + let privateProp = `_$${accessor}_${prop}`; + if (obj[privateProp]) { + return obj[privateProp]; + } + let ObjConstructor = obj.constructor; + let des; + while (ObjConstructor) { + des = Object.getOwnPropertyDescriptor(ObjConstructor.prototype, prop); + if (des && des[accessor]) { + obj[privateProp] = des[accessor].bind(obj); + break; + } + ObjConstructor = Object.getPrototypeOf(ObjConstructor); + } + return obj[privateProp]; + } + resetCollider(resetShape) { + var comps = this.owner.getComponents(ColliderBase); + if (comps) { + for (var i = 0, n = comps.length; i < n; i++) { + var collider = comps[i]; + collider.rigidBody = this; + if (resetShape) + collider.resetShape(); + else + collider.refresh(); + } + } + } + _sysPhysicToNode() { + if (this.type != "static" && this._body.IsAwake()) { + var pos = this._body.GetPosition(); + var ang = this._body.GetAngle(); + var sp = this.owner; + this.accessGetSetFunc(sp, "rotation", "set")(Laya.Utils.toAngle(ang) - sp.parent.globalRotation); + var point = sp.globalToLocal(Laya.Point.TEMP.setTo(pos.x * IPhysics.Physics.PIXEL_RATIO, pos.y * IPhysics.Physics.PIXEL_RATIO), false, IPhysics.Physics.I.worldRoot); + point.x += sp.pivotX; + point.y += sp.pivotY; + point = sp.toParentPoint(point); + this.accessGetSetFunc(sp, "x", "set")(point.x); + this.accessGetSetFunc(sp, "y", "set")(point.y); + } + } + _sysNodeToPhysic() { + var sp = this.owner; + this._body.SetAngle(Laya.Utils.toRadian(sp.rotation)); + var p = sp.localToGlobal(Laya.Point.TEMP.setTo(0, 0), false, IPhysics.Physics.I.worldRoot); + this._body.SetPositionXY(p.x / IPhysics.Physics.PIXEL_RATIO, p.y / IPhysics.Physics.PIXEL_RATIO); + } + _sysPosToPhysic() { + var sp = this.owner; + var p = sp.localToGlobal(Laya.Point.TEMP.setTo(0, 0), false, IPhysics.Physics.I.worldRoot); + this._body.SetPositionXY(p.x / IPhysics.Physics.PIXEL_RATIO, p.y / IPhysics.Physics.PIXEL_RATIO); + } + _overSet(sp, prop, getfun) { + Object.defineProperty(sp, prop, { get: this.accessGetSetFunc(sp, prop, "get"), set: getfun, enumerable: false, configurable: true }); + } + _onDisable() { + Laya.Laya.physicsTimer.clear(this, this._sysPhysicToNode); + this._body && IPhysics.Physics.I._removeBody(this._body); + this._body = null; + var owner = this.owner; + if (owner._changeByRigidBody) { + this._overSet(owner, "x", this.accessGetSetFunc(owner, "x", "set")); + this._overSet(owner, "y", this.accessGetSetFunc(owner, "y", "set")); + this._overSet(owner, "rotation", this.accessGetSetFunc(owner, "rotation", "set")); + this._overSet(owner, "scaleX", this.accessGetSetFunc(owner, "scaleX", "set")); + this._overSet(owner, "scaleY", this.accessGetSetFunc(owner, "scaleY", "set")); + owner._changeByRigidBody = false; + } + } + getBody() { + if (!this._body) + this._onAwake(); + return this._body; + } + _getOriBody() { + return this._body; + } + get body() { + if (!this._body) + this._onAwake(); + return this._body; + } + applyForce(position, force) { + if (!this._body) + this._onAwake(); + this._body.ApplyForce(force, position); + } + applyForceToCenter(force) { + if (!this._body) + this._onAwake(); + this._body.ApplyForceToCenter(force); + } + applyLinearImpulse(position, impulse) { + if (!this._body) + this._onAwake(); + this._body.ApplyLinearImpulse(impulse, position); + } + applyLinearImpulseToCenter(impulse) { + if (!this._body) + this._onAwake(); + this._body.ApplyLinearImpulseToCenter(impulse); + } + applyTorque(torque) { + if (!this._body) + this._onAwake(); + this._body.ApplyTorque(torque); + } + setVelocity(velocity) { + if (!this._body) + this._onAwake(); + this._body.SetLinearVelocity(velocity); + } + setAngle(value) { + if (!this._body) + this._onAwake(); + this._body.SetAngle(value); + this._body.SetAwake(true); + } + getMass() { + return this._body ? this._body.GetMass() : 0; + } + getCenter() { + if (!this._body) + this._onAwake(); + var p = this._body.GetLocalCenter(); + p.x = p.x * IPhysics.Physics.PIXEL_RATIO; + p.y = p.y * IPhysics.Physics.PIXEL_RATIO; + return p; + } + getWorldCenter() { + if (!this._body) + this._onAwake(); + var p = this._body.GetWorldCenter(); + p.x = p.x * IPhysics.Physics.PIXEL_RATIO; + p.y = p.y * IPhysics.Physics.PIXEL_RATIO; + return p; + } + get type() { + return this._type; + } + set type(value) { + this._type = value; + if (this._body) + this._body.SetType(window.box2d.b2BodyType["b2_" + this._type + "Body"]); + } + get gravityScale() { + return this._gravityScale; + } + set gravityScale(value) { + this._gravityScale = value; + if (this._body) + this._body.SetGravityScale(value); + } + get allowRotation() { + return this._allowRotation; + } + set allowRotation(value) { + this._allowRotation = value; + if (this._body) + this._body.SetFixedRotation(!value); + } + get allowSleep() { + return this._allowSleep; + } + set allowSleep(value) { + this._allowSleep = value; + if (this._body) + this._body.SetSleepingAllowed(value); + } + get angularDamping() { + return this._angularDamping; + } + set angularDamping(value) { + this._angularDamping = value; + if (this._body) + this._body.SetAngularDamping(value); + } + get angularVelocity() { + if (this._body) + return this._body.GetAngularVelocity(); + return this._angularVelocity; + } + set angularVelocity(value) { + this._angularVelocity = value; + if (this._body) + this._body.SetAngularVelocity(value); + } + get linearDamping() { + return this._linearDamping; + } + set linearDamping(value) { + this._linearDamping = value; + if (this._body) + this._body.SetLinearDamping(value); + } + get linearVelocity() { + if (this._body) { + var vec = this._body.GetLinearVelocity(); + return { x: vec.x, y: vec.y }; + } + return this._linearVelocity; + } + set linearVelocity(value) { + if (!value) + return; + if (value instanceof Array) { + value = { x: value[0], y: value[1] }; + } + this._linearVelocity = value; + if (this._body) + this._body.SetLinearVelocity(new window.box2d.b2Vec2(value.x, value.y)); + } + get bullet() { + return this._bullet; + } + set bullet(value) { + this._bullet = value; + if (this._body) + this._body.SetBullet(value); + } + } + Laya.ClassUtils.regClass("laya.physics.RigidBody", RigidBody); + Laya.ClassUtils.regClass("Laya.RigidBody", RigidBody); + + class DestructionListener { + SayGoodbyeJoint(params) { + params.m_userData && (params.m_userData.isDestroy = true); + } + SayGoodbyeFixture(params) { + } + SayGoodbyeParticleGroup(params) { + } + SayGoodbyeParticle(params) { + } + } + + class Physics extends Laya.EventDispatcher { + constructor() { + super(); + this.box2d = window.box2d; + this.velocityIterations = 8; + this.positionIterations = 3; + this._eventList = []; + } + static get I() { + return Physics._I || (Physics._I = new Physics()); + } + static enable(options = null) { + Physics.I.start(options); + IPhysics.RigidBody = RigidBody; + IPhysics.Physics = this; + } + start(options = null) { + if (!this._enabled) { + this._enabled = true; + options || (options = {}); + var box2d = window.box2d; + if (box2d == null) { + console.error("Can not find box2d libs, you should request box2d.js first."); + return; + } + var gravity = new box2d.b2Vec2(0, options.gravity || 500 / Physics.PIXEL_RATIO); + this.world = new box2d.b2World(gravity); + this.world.SetDestructionListener(new DestructionListener()); + this.world.SetContactListener(new ContactListener()); + this.allowSleeping = options.allowSleeping == null ? true : options.allowSleeping; + if (!options.customUpdate) + Laya.Laya.physicsTimer.frameLoop(1, this, this._update); + this._emptyBody = this._createBody(new window.box2d.b2BodyDef()); + } + } + _update() { + var delta = Laya.Laya.timer.delta / 1000; + if (delta > .033) { + delta = .033; + } + this.world.Step(delta, this.velocityIterations, this.positionIterations, 3); + var len = this._eventList.length; + if (len > 0) { + for (var i = 0; i < len; i += 2) { + this._sendEvent(this._eventList[i], this._eventList[i + 1]); + } + this._eventList.length = 0; + } + } + _sendEvent(type, contact) { + var colliderA = contact.GetFixtureA().collider; + var colliderB = contact.GetFixtureB().collider; + var ownerA = colliderA.owner; + var ownerB = colliderB.owner; + contact.getHitInfo = function () { + var manifold = new this.box2d.b2WorldManifold(); + this.GetWorldManifold(manifold); + var p = manifold.points[0]; + p.x *= Physics.PIXEL_RATIO; + p.y *= Physics.PIXEL_RATIO; + return manifold; + }; + if (ownerA) { + var args = [colliderB, colliderA, contact]; + if (type === 0) { + ownerA.event(Laya.Event.TRIGGER_ENTER, args); + if (!ownerA["_triggered"]) { + ownerA["_triggered"] = true; + } + else { + ownerA.event(Laya.Event.TRIGGER_STAY, args); + } + } + else { + ownerA["_triggered"] = false; + ownerA.event(Laya.Event.TRIGGER_EXIT, args); + } + } + if (ownerB) { + args = [colliderA, colliderB, contact]; + if (type === 0) { + ownerB.event(Laya.Event.TRIGGER_ENTER, args); + if (!ownerB["_triggered"]) { + ownerB["_triggered"] = true; + } + else { + ownerB.event(Laya.Event.TRIGGER_STAY, args); + } + } + else { + ownerB["_triggered"] = false; + ownerB.event(Laya.Event.TRIGGER_EXIT, args); + } + } + } + _createBody(def) { + if (this.world) { + return this.world.CreateBody(def); + } + else { + console.error('The physical engine should be initialized first.use "Physics.enable()"'); + return null; + } + } + _removeBody(body) { + if (this.world) { + this.world.DestroyBody(body); + } + else { + console.error('The physical engine should be initialized first.use "Physics.enable()"'); + } + } + _createJoint(def) { + if (this.world) { + let joint = this.world.CreateJoint(def); + joint.m_userData = {}; + joint.m_userData.isDestroy = false; + return joint; + } + else { + console.error('The physical engine should be initialized first.use "Physics.enable()"'); + return null; + } + } + _removeJoint(joint) { + if (this.world) { + this.world.DestroyJoint(joint); + } + else { + console.error('The physical engine should be initialized first.use "Physics.enable()"'); + } + } + stop() { + Laya.Laya.physicsTimer.clear(this, this._update); + } + get allowSleeping() { + return this.world.GetAllowSleeping(); + } + set allowSleeping(value) { + this.world.SetAllowSleeping(value); + } + get gravity() { + return this.world.GetGravity(); + } + set gravity(value) { + this.world.SetGravity(value); + } + getBodyCount() { + return this.world.GetBodyCount(); + } + getContactCount() { + return this.world.GetContactCount(); + } + getJointCount() { + return this.world.GetJointCount(); + } + get worldRoot() { + return this._worldRoot || Laya.Laya.stage; + } + set worldRoot(value) { + this._worldRoot = value; + if (value) { + var p = value.localToGlobal(Laya.Point.TEMP.setTo(0, 0)); + this.world.ShiftOrigin({ x: -p.x / Physics.PIXEL_RATIO, y: -p.y / Physics.PIXEL_RATIO }); + } + } + updatePhysicsByWorldRoot() { + if (!!this.worldRoot) { + var p = this.worldRoot.localToGlobal(Laya.Point.TEMP.setTo(0, 0)); + this.world.ShiftOrigin({ x: -p.x / Physics.PIXEL_RATIO, y: -p.y / Physics.PIXEL_RATIO }); + } + } + } + Physics.PIXEL_RATIO = 50; + Laya.ClassUtils.regClass("laya.physics.Physics", Physics); + Laya.ClassUtils.regClass("Laya.Physics", Physics); + class ContactListener { + BeginContact(contact) { + Physics.I._eventList.push(0, contact); + } + EndContact(contact) { + Physics.I._eventList.push(1, contact); + } + PreSolve(contact, oldManifold) { + } + PostSolve(contact, impulse) { + } + } + + class BoxCollider extends ColliderBase { + constructor() { + super(...arguments); + this._x = 0; + this._y = 0; + this._width = 100; + this._height = 100; + } + getDef() { + if (!this._shape) { + this._shape = new window.box2d.b2PolygonShape(); + this._setShape(false); + } + this.label = (this.label || "BoxCollider"); + return super.getDef(); + } + _setShape(re = true) { + var scaleX = (this.owner["scaleX"] || 1); + var scaleY = (this.owner["scaleY"] || 1); + this._shape.SetAsBox(this._width / 2 / Physics.PIXEL_RATIO * scaleX, this._height / 2 / Physics.PIXEL_RATIO * scaleY, new window.box2d.b2Vec2((this._width / 2 + this._x) / Physics.PIXEL_RATIO * scaleX, (this._height / 2 + this._y) / Physics.PIXEL_RATIO * scaleY)); + if (re) + this.refresh(); + } + get x() { + return this._x; + } + set x(value) { + this._x = value; + if (this._shape) + this._setShape(); + } + get y() { + return this._y; + } + set y(value) { + this._y = value; + if (this._shape) + this._setShape(); + } + get width() { + return this._width; + } + set width(value) { + if (value <= 0) + throw "BoxCollider size cannot be less than 0"; + this._width = value; + if (this._shape) + this._setShape(); + } + get height() { + return this._height; + } + set height(value) { + if (value <= 0) + throw "BoxCollider size cannot be less than 0"; + this._height = value; + if (this._shape) + this._setShape(); + } + resetShape(re = true) { + this._setShape(); + } + } + Laya.ClassUtils.regClass("laya.physics.BoxCollider", BoxCollider); + Laya.ClassUtils.regClass("Laya.BoxCollider", BoxCollider); + + class ChainCollider extends ColliderBase { + constructor() { + super(...arguments); + this._x = 0; + this._y = 0; + this._points = "0,0,100,0"; + this._loop = false; + } + getDef() { + if (!this._shape) { + this._shape = new window.box2d.b2ChainShape(); + this._setShape(false); + } + this.label = (this.label || "ChainCollider"); + return super.getDef(); + } + _setShape(re = true) { + var arr = this._points.split(","); + var len = arr.length; + if (len % 2 == 1) + throw "ChainCollider points lenth must a multiplier of 2"; + var ps = []; + for (var i = 0, n = len; i < n; i += 2) { + ps.push(new window.box2d.b2Vec2((this._x + parseInt(arr[i])) / Physics.PIXEL_RATIO, (this._y + parseInt(arr[i + 1])) / Physics.PIXEL_RATIO)); + } + this._loop ? this._shape.CreateLoop(ps, len / 2) : this._shape.CreateChain(ps, len / 2, new window.box2d.b2Vec2(0, 0), new window.box2d.b2Vec2(0, 0)); + if (re) + this.refresh(); + } + get x() { + return this._x; + } + set x(value) { + this._x = value; + if (this._shape) + this._setShape(); + } + get y() { + return this._y; + } + set y(value) { + this._y = value; + if (this._shape) + this._setShape(); + } + get points() { + return this._points; + } + set points(value) { + if (!value) + throw "ChainCollider points cannot be empty"; + this._points = value; + if (this._shape) + this._setShape(); + } + get loop() { + return this._loop; + } + set loop(value) { + this._loop = value; + if (this._shape) + this._setShape(); + } + } + Laya.ClassUtils.regClass("laya.physics.ChainCollider", ChainCollider); + Laya.ClassUtils.regClass("Laya.ChainCollider", ChainCollider); + + class CircleCollider extends ColliderBase { + constructor() { + super(...arguments); + this._x = 0; + this._y = 0; + this._radius = 50; + } + getDef() { + if (!this._shape) { + this._shape = new window.box2d.b2CircleShape(); + this._setShape(false); + } + this.label = (this.label || "CircleCollider"); + return super.getDef(); + } + _setShape(re = true) { + var scale = this.owner["scaleX"] || 1; + this._shape.m_radius = this._radius / Physics.PIXEL_RATIO * scale; + this._shape.m_p.Set((this._radius + this._x) / Physics.PIXEL_RATIO * scale, (this._radius + this._y) / Physics.PIXEL_RATIO * scale); + if (re) + this.refresh(); + } + get x() { + return this._x; + } + set x(value) { + this._x = value; + if (this._shape) + this._setShape(); + } + get y() { + return this._y; + } + set y(value) { + this._y = value; + if (this._shape) + this._setShape(); + } + get radius() { + return this._radius; + } + set radius(value) { + if (value <= 0) + throw "CircleCollider radius cannot be less than 0"; + this._radius = value; + if (this._shape) + this._setShape(); + } + resetShape(re = true) { + this._setShape(); + } + } + Laya.ClassUtils.regClass("laya.physics.CircleCollider", CircleCollider); + Laya.ClassUtils.regClass("Laya.CircleCollider", CircleCollider); + + class EdgeCollider extends ColliderBase { + constructor() { + super(...arguments); + this._x = 0; + this._y = 0; + this._points = "0,0,100,0"; + } + getDef() { + if (!this._shape) { + this._shape = new window.box2d.b2EdgeShape(); + this._setShape(false); + } + this.label = (this.label || "EdgeCollider"); + return super.getDef(); + } + _setShape(re = true) { + var arr = this._points.split(","); + var len = arr.length; + if (len % 2 == 1) + throw "EdgeCollider points lenth must a multiplier of 2"; + var ps = []; + for (var i = 0, n = len; i < n; i += 2) { + ps.push(new window.box2d.b2Vec2((this._x + parseInt(arr[i])) / Physics.PIXEL_RATIO, (this._y + parseInt(arr[i + 1])) / Physics.PIXEL_RATIO)); + } + this._shape.SetTwoSided(ps[0], ps[1]); + if (re) + this.refresh(); + } + get x() { + return this._x; + } + set x(value) { + this._x = value; + if (this._shape) + this._setShape(); + } + get y() { + return this._y; + } + set y(value) { + this._y = value; + if (this._shape) + this._setShape(); + } + get points() { + return this._points; + } + set points(value) { + if (!value) + throw "EdgeCollider points cannot be empty"; + this._points = value; + if (this._shape) + this._setShape(); + } + } + Laya.ClassUtils.regClass("laya.physics.EdgeCollider", EdgeCollider); + Laya.ClassUtils.regClass("Laya.EdgeCollider", EdgeCollider); + + class PhysicsDebugDraw extends Laya.Sprite { + constructor() { + super(); + this.m_drawFlags = 99; + if (!PhysicsDebugDraw._inited) { + PhysicsDebugDraw._inited = true; + PhysicsDebugDraw.init(); + } + this._camera = {}; + this._camera.m_center = new PhysicsDebugDraw.box2d.b2Vec2(0, 0); + this._camera.m_extent = 25; + this._camera.m_zoom = 1; + this._camera.m_width = 1280; + this._camera.m_height = 800; + this._mG = new Laya.Graphics(); + this.graphics = this._mG; + this._textSp = new Laya.Sprite(); + this._textG = this._textSp.graphics; + this.addChild(this._textSp); + } + static init() { + PhysicsDebugDraw.box2d = Laya.Browser.window.box2d; + PhysicsDebugDraw.DrawString_s_color = new PhysicsDebugDraw.box2d.b2Color(0.9, 0.6, 0.6); + PhysicsDebugDraw.DrawStringWorld_s_p = new PhysicsDebugDraw.box2d.b2Vec2(); + PhysicsDebugDraw.DrawStringWorld_s_cc = new PhysicsDebugDraw.box2d.b2Vec2(); + PhysicsDebugDraw.DrawStringWorld_s_color = new PhysicsDebugDraw.box2d.b2Color(0.5, 0.9, 0.5); + } + render(ctx, x, y) { + this._renderToGraphic(); + super.render(ctx, x, y); + } + _renderToGraphic() { + if (this.world) { + this._textG.clear(); + this._mG.clear(); + this._mG.save(); + this._mG.scale(Physics.PIXEL_RATIO, Physics.PIXEL_RATIO); + this.lineWidth = 1 / Physics.PIXEL_RATIO; + if (this.world.DebugDraw) + this.world.DebugDraw(); + else + this.world.DrawDebugData(); + this._mG.restore(); + } + } + SetFlags(flags) { + this.m_drawFlags = flags; + } + GetFlags() { + return this.m_drawFlags; + } + AppendFlags(flags) { + this.m_drawFlags |= flags; + } + ClearFlags(flags) { + this.m_drawFlags &= ~flags; + } + PushTransform(xf) { + this._mG.save(); + this._mG.translate(xf.p.x, xf.p.y); + this._mG.rotate(xf.q.GetAngle()); + } + PopTransform(xf) { + this._mG.restore(); + } + DrawPolygon(vertices, vertexCount, color) { + var i, len; + len = vertices.length; + var points; + points = []; + for (i = 0; i < vertexCount; i++) { + points.push(vertices[i].x, vertices[i].y); + } + this._mG.drawPoly(0, 0, points, null, color.MakeStyleString(1), this.lineWidth); + } + DrawSolidPolygon(vertices, vertexCount, color) { + var i, len; + len = vertices.length; + var points; + points = []; + for (i = 0; i < vertexCount; i++) { + points.push(vertices[i].x, vertices[i].y); + } + this._mG.drawPoly(0, 0, points, color.MakeStyleString(0.5), color.MakeStyleString(1), this.lineWidth); + } + DrawCircle(center, radius, color) { + this._mG.drawCircle(center.x, center.y, radius, null, color.MakeStyleString(1), this.lineWidth); + } + DrawSolidCircle(center, radius, axis, color) { + var cx = center.x; + var cy = center.y; + this._mG.drawCircle(cx, cy, radius, color.MakeStyleString(0.5), color.MakeStyleString(1), this.lineWidth); + this._mG.drawLine(cx, cy, (cx + axis.x * radius), (cy + axis.y * radius), color.MakeStyleString(1), this.lineWidth); + } + DrawParticles(centers, radius, colors, count) { + if (colors !== null) { + for (var i = 0; i < count; ++i) { + var center = centers[i]; + var color = colors[i]; + this._mG.drawCircle(center.x, center.y, radius, color.MakeStyleString(), null, this.lineWidth); + } + } + else { + for (i = 0; i < count; ++i) { + center = centers[i]; + this._mG.drawCircle(center.x, center.y, radius, "#ffff00", null, this.lineWidth); + } + } + } + DrawSegment(p1, p2, color) { + this._mG.drawLine(p1.x, p1.y, p2.x, p2.y, color.MakeStyleString(1), this.lineWidth); + } + DrawTransform(xf) { + this.PushTransform(xf); + this._mG.drawLine(0, 0, 1, 0, PhysicsDebugDraw.box2d.b2Color.RED.MakeStyleString(1), this.lineWidth); + this._mG.drawLine(0, 0, 0, 1, PhysicsDebugDraw.box2d.b2Color.GREEN.MakeStyleString(1), this.lineWidth); + this.PopTransform(xf); + } + DrawPoint(p, size, color) { + size *= this._camera.m_zoom; + size /= this._camera.m_extent; + var hsize = size / 2; + this._mG.drawRect(p.x - hsize, p.y - hsize, size, size, color.MakeStyleString(), null); + } + DrawString(x, y, message) { + this._textG.fillText(message, x, y, "15px DroidSans", PhysicsDebugDraw.DrawString_s_color.MakeStyleString(), "left"); + } + DrawStringWorld(x, y, message) { + this.DrawString(x, y, message); + } + DrawAABB(aabb, color) { + var x = aabb.lowerBound.x; + var y = aabb.lowerBound.y; + var w = aabb.upperBound.x - aabb.lowerBound.x; + var h = aabb.upperBound.y - aabb.lowerBound.y; + this._mG.drawRect(x, y, w, h, null, color.MakeStyleString(), this.lineWidth); + } + static enable(flags = 99) { + if (!PhysicsDebugDraw.I) { + var debug = new PhysicsDebugDraw(); + debug.world = Physics.I.world; + debug.world.SetDebugDraw(debug); + debug.zOrder = 1000; + debug.m_drawFlags = flags; + Laya.Laya.stage.addChild(debug); + PhysicsDebugDraw.I = debug; + } + return debug; + } + } + PhysicsDebugDraw._inited = false; + Laya.ClassUtils.regClass("laya.physics.PhysicsDebugDraw", PhysicsDebugDraw); + Laya.ClassUtils.regClass("Laya.PhysicsDebugDraw", PhysicsDebugDraw); + + class PolygonCollider extends ColliderBase { + constructor() { + super(...arguments); + this._x = 0; + this._y = 0; + this._points = "50,0,100,100,0,100"; + } + getDef() { + if (!this._shape) { + this._shape = new window.box2d.b2PolygonShape(); + this._setShape(false); + } + this.label = (this.label || "PolygonCollider"); + return super.getDef(); + } + _setShape(re = true) { + var arr = this._points.split(","); + var len = arr.length; + if (len < 6) + throw "PolygonCollider points must be greater than 3"; + if (len % 2 == 1) + throw "PolygonCollider points lenth must a multiplier of 2"; + var ps = []; + for (var i = 0, n = len; i < n; i += 2) { + ps.push(new window.box2d.b2Vec2((this._x + parseInt(arr[i])) / Physics.PIXEL_RATIO, (this._y + parseInt(arr[i + 1])) / Physics.PIXEL_RATIO)); + } + this._shape.Set(ps, len / 2); + if (re) + this.refresh(); + } + get x() { + return this._x; + } + set x(value) { + this._x = value; + if (this._shape) + this._setShape(); + } + get y() { + return this._y; + } + set y(value) { + this._y = value; + if (this._shape) + this._setShape(); + } + get points() { + return this._points; + } + set points(value) { + if (!value) + throw "PolygonCollider points cannot be empty"; + this._points = value; + if (this._shape) + this._setShape(); + } + } + Laya.ClassUtils.regClass("laya.physics.PolygonCollider", PolygonCollider); + Laya.ClassUtils.regClass("Laya.PolygonCollider", PolygonCollider); + + class JointBase extends Laya.Component { + get joint() { + if (!this._joint) + this._createJoint(); + return this._joint; + } + _onEnable() { + this._createJoint(); + } + _onAwake() { + this._createJoint(); + } + _createJoint() { + } + _onDisable() { + if (this._joint && this._joint.m_userData && !this._joint.m_userData.isDestroy) { + Physics.I._removeJoint(this._joint); + } + this._joint = null; + } + get isSingleton() { + return false; + } + } + Laya.ClassUtils.regClass("laya.physics.joint.JointBase", JointBase); + Laya.ClassUtils.regClass("Laya.JointBase", JointBase); + + class DistanceJoint extends JointBase { + constructor() { + super(...arguments); + this.selfAnchor = [0, 0]; + this.otherAnchor = [0, 0]; + this.collideConnected = false; + this._length = 0; + this._maxLength = -1; + this._minLength = -1; + this._frequency = 1; + this._dampingRatio = 0; + } + _createJoint() { + if (!this._joint) { + this.selfBody = this.selfBody || this.owner.getComponent(RigidBody); + if (!this.selfBody) + throw "selfBody can not be empty"; + var box2d = window.box2d; + var def = DistanceJoint._temp || (DistanceJoint._temp = new box2d.b2DistanceJointDef()); + def.bodyA = this.otherBody ? this.otherBody.getBody() : Physics.I._emptyBody; + def.bodyB = this.selfBody.getBody(); + def.localAnchorA.Set(this.otherAnchor[0] / Physics.PIXEL_RATIO, this.otherAnchor[1] / Physics.PIXEL_RATIO); + def.localAnchorB.Set(this.selfAnchor[0] / Physics.PIXEL_RATIO, this.selfAnchor[1] / Physics.PIXEL_RATIO); + box2d.b2LinearStiffness(def, this._frequency, this._dampingRatio, def.bodyA, def.bodyB); + def.collideConnected = this.collideConnected; + var p1 = def.bodyA.GetWorldPoint(def.localAnchorA, new box2d.b2Vec2()); + var p2 = def.bodyB.GetWorldPoint(def.localAnchorB, new box2d.b2Vec2()); + def.length = this._length / Physics.PIXEL_RATIO || box2d.b2Vec2.SubVV(p2, p1, new box2d.b2Vec2()).Length(); + def.maxLength = box2d.b2_maxFloat; + def.minLength = 0; + if (this._maxLength >= 0) + def.maxLength = this._maxLength / Physics.PIXEL_RATIO; + if (this._minLength >= 0) + def.minLength = this._minLength / Physics.PIXEL_RATIO; + this._joint = Physics.I._createJoint(def); + } + } + get length() { + return this._length; + } + set length(value) { + this._length = value; + if (this._joint) + this._joint.SetLength(value / Physics.PIXEL_RATIO); + } + get minLength() { + return this._minLength; + } + set minLength(value) { + this._minLength = value; + if (this._joint) + this._joint.SetMinLength(value / Physics.PIXEL_RATIO); + } + get maxLength() { + return this._maxLength; + } + set maxLength(value) { + this._maxLength = value; + if (this._joint) + this._joint.SetMaxLength(value / Physics.PIXEL_RATIO); + } + get frequency() { + return this._frequency; + } + set frequency(value) { + this._frequency = value; + if (this._joint) { + let out = {}; + let box2d = window.box2d; + let bodyA = this.otherBody ? this.otherBody.getBody() : Physics.I._emptyBody; + let bodyB = this.selfBody.getBody(); + box2d.b2LinearStiffness(out, this._frequency, this._dampingRatio, bodyA, bodyB); + this._joint.SetStiffness(out.stiffness); + this._joint.SetDamping(out.damping); + } + } + get damping() { + return this._dampingRatio; + } + set damping(value) { + this._dampingRatio = value; + if (this._joint) { + let out = {}; + let box2d = window.box2d; + let bodyA = this.otherBody ? this.otherBody.getBody() : Physics.I._emptyBody; + let bodyB = this.selfBody.getBody(); + box2d.b2LinearStiffness(out, this._frequency, this._dampingRatio, bodyA, bodyB); + this._joint.SetDamping(out.damping); + } + } + } + Laya.ClassUtils.regClass("laya.physics.joint.DistanceJoint", DistanceJoint); + Laya.ClassUtils.regClass("Laya.DistanceJoint", DistanceJoint); + + class GearJoint extends JointBase { + constructor() { + super(...arguments); + this.collideConnected = false; + this._ratio = 1; + } + _createJoint() { + if (!this._joint) { + if (!this.joint1) + throw "Joint1 can not be empty"; + if (!this.joint2) + throw "Joint2 can not be empty"; + var box2d = window.box2d; + var def = GearJoint._temp || (GearJoint._temp = new box2d.b2GearJointDef()); + def.bodyA = this.joint1.owner.getComponent(RigidBody).getBody(); + def.bodyB = this.joint2.owner.getComponent(RigidBody).getBody(); + def.joint1 = this.joint1.joint; + def.joint2 = this.joint2.joint; + def.ratio = this._ratio; + def.collideConnected = this.collideConnected; + this._joint = Physics.I._createJoint(def); + } + } + get ratio() { + return this._ratio; + } + set ratio(value) { + this._ratio = value; + if (this._joint) + this._joint.SetRatio(value); + } + } + Laya.ClassUtils.regClass("laya.physics.joint.GearJoint", GearJoint); + Laya.ClassUtils.regClass("Laya.GearJoint", GearJoint); + + class MotorJoint extends JointBase { + constructor() { + super(...arguments); + this.collideConnected = false; + this._linearOffset = [0, 0]; + this._angularOffset = 0; + this._maxForce = 1000; + this._maxTorque = 1000; + this._correctionFactor = 0.3; + } + _createJoint() { + if (!this._joint) { + if (!this.otherBody) + throw "otherBody can not be empty"; + this.selfBody = this.selfBody || this.owner.getComponent(RigidBody); + if (!this.selfBody) + throw "selfBody can not be empty"; + var box2d = window.box2d; + var def = MotorJoint._temp || (MotorJoint._temp = new box2d.b2MotorJointDef()); + def.Initialize(this.otherBody.getBody(), this.selfBody.getBody()); + def.linearOffset = new box2d.b2Vec2(this._linearOffset[0] / Physics.PIXEL_RATIO, this._linearOffset[1] / Physics.PIXEL_RATIO); + def.angularOffset = this._angularOffset; + def.maxForce = this._maxForce; + def.maxTorque = this._maxTorque; + def.correctionFactor = this._correctionFactor; + def.collideConnected = this.collideConnected; + this._joint = Physics.I._createJoint(def); + } + } + get linearOffset() { + return this._linearOffset; + } + set linearOffset(value) { + this._linearOffset = value; + if (this._joint) + this._joint.SetLinearOffset(new window.box2d.b2Vec2(value[0] / Physics.PIXEL_RATIO, value[1] / Physics.PIXEL_RATIO)); + } + get angularOffset() { + return this._angularOffset; + } + set angularOffset(value) { + this._angularOffset = value; + if (this._joint) + this._joint.SetAngularOffset(value); + } + get maxForce() { + return this._maxForce; + } + set maxForce(value) { + this._maxForce = value; + if (this._joint) + this._joint.SetMaxForce(value); + } + get maxTorque() { + return this._maxTorque; + } + set maxTorque(value) { + this._maxTorque = value; + if (this._joint) + this._joint.SetMaxTorque(value); + } + get correctionFactor() { + return this._correctionFactor; + } + set correctionFactor(value) { + this._correctionFactor = value; + if (this._joint) + this._joint.SetCorrectionFactor(value); + } + } + Laya.ClassUtils.regClass("laya.physics.joint.MotorJoint", MotorJoint); + Laya.ClassUtils.regClass("Laya.MotorJoint", MotorJoint); + + class MouseJoint extends JointBase { + constructor() { + super(...arguments); + this._maxForce = 10000; + this._frequency = 5; + this._dampingRatio = 0.7; + } + _onEnable() { + this.owner.on(Laya.Event.MOUSE_DOWN, this, this.onMouseDown); + } + _onAwake() { + } + onMouseDown() { + this._createJoint(); + Laya.Laya.stage.on(Laya.Event.MOUSE_MOVE, this, this.onMouseMove); + Laya.Laya.stage.once(Laya.Event.MOUSE_UP, this, this.onStageMouseUp); + Laya.Laya.stage.once(Laya.Event.MOUSE_OUT, this, this.onStageMouseUp); + } + _createJoint() { + if (!this._joint) { + this.selfBody = this.selfBody || this.owner.getComponent(RigidBody); + if (!this.selfBody) + throw "selfBody can not be empty"; + var box2d = window.box2d; + var def = MouseJoint._temp || (MouseJoint._temp = new box2d.b2MouseJointDef()); + if (this.anchor) { + var anchorPos = this.selfBody.owner.localToGlobal(Laya.Point.TEMP.setTo(this.anchor[0], this.anchor[1]), false, Physics.I.worldRoot); + } + else { + anchorPos = Physics.I.worldRoot.globalToLocal(Laya.Point.TEMP.setTo(Laya.Laya.stage.mouseX, Laya.Laya.stage.mouseY)); + } + var anchorVec = new box2d.b2Vec2(anchorPos.x / Physics.PIXEL_RATIO, anchorPos.y / Physics.PIXEL_RATIO); + def.bodyA = Physics.I._emptyBody; + def.bodyB = this.selfBody.getBody(); + def.target = anchorVec; + box2d.b2LinearStiffness(def, this._frequency, this._dampingRatio, def.bodyA, def.bodyB); + def.maxForce = this._maxForce; + this._joint = Physics.I._createJoint(def); + } + } + onStageMouseUp() { + Laya.Laya.stage.off(Laya.Event.MOUSE_MOVE, this, this.onMouseMove); + Laya.Laya.stage.off(Laya.Event.MOUSE_UP, this, this.onStageMouseUp); + Laya.Laya.stage.off(Laya.Event.MOUSE_OUT, this, this.onStageMouseUp); + super._onDisable(); + } + onMouseMove() { + this._joint.SetTarget(new window.box2d.b2Vec2(Physics.I.worldRoot.mouseX / Physics.PIXEL_RATIO, Physics.I.worldRoot.mouseY / Physics.PIXEL_RATIO)); + } + _onDisable() { + this.owner.off(Laya.Event.MOUSE_DOWN, this, this.onMouseDown); + super._onDisable(); + } + get maxForce() { + return this._maxForce; + } + set maxForce(value) { + this._maxForce = value; + if (this._joint) + this._joint.SetMaxForce(value); + } + get frequency() { + return this._frequency; + } + set frequency(value) { + this._frequency = value; + if (this._joint) { + let out = {}; + let box2d = window.box2d; + let bodyA = Physics.I._emptyBody; + let bodyB = this.selfBody.getBody(); + box2d.b2LinearStiffness(out, this._frequency, this._dampingRatio, bodyA, bodyB); + this._joint.SetStiffness(out.stiffness); + this._joint.SetDamping(out.damping); + } + } + get damping() { + return this._dampingRatio; + } + set damping(value) { + this._dampingRatio = value; + if (this._joint) { + let out = {}; + let box2d = window.box2d; + let bodyA = Physics.I._emptyBody; + let bodyB = this.selfBody.getBody(); + box2d.b2LinearStiffness(out, this._frequency, this._dampingRatio, bodyA, bodyB); + this._joint.SetDamping(out.damping); + } + } + } + Laya.ClassUtils.regClass("laya.physics.joint.MouseJoint", MouseJoint); + Laya.ClassUtils.regClass("Laya.MouseJoint", MouseJoint); + + class PrismaticJoint extends JointBase { + constructor() { + super(...arguments); + this.anchor = [0, 0]; + this.axis = [1, 0]; + this.collideConnected = false; + this._enableMotor = false; + this._motorSpeed = 0; + this._maxMotorForce = 10000; + this._enableLimit = false; + this._lowerTranslation = 0; + this._upperTranslation = 0; + } + _createJoint() { + if (!this._joint) { + this.selfBody = this.selfBody || this.owner.getComponent(RigidBody); + if (!this.selfBody) + throw "selfBody can not be empty"; + var box2d = window.box2d; + var def = PrismaticJoint._temp || (PrismaticJoint._temp = new box2d.b2PrismaticJointDef()); + var anchorPos = this.selfBody.owner.localToGlobal(Laya.Point.TEMP.setTo(this.anchor[0], this.anchor[1]), false, Physics.I.worldRoot); + var anchorVec = new box2d.b2Vec2(anchorPos.x / Physics.PIXEL_RATIO, anchorPos.y / Physics.PIXEL_RATIO); + def.Initialize(this.otherBody ? this.otherBody.getBody() : Physics.I._emptyBody, this.selfBody.getBody(), anchorVec, new box2d.b2Vec2(this.axis[0], this.axis[1])); + def.enableMotor = this._enableMotor; + def.motorSpeed = this._motorSpeed; + def.maxMotorForce = this._maxMotorForce; + def.enableLimit = this._enableLimit; + def.lowerTranslation = this._lowerTranslation / Physics.PIXEL_RATIO; + def.upperTranslation = this._upperTranslation / Physics.PIXEL_RATIO; + def.collideConnected = this.collideConnected; + this._joint = Physics.I._createJoint(def); + } + } + get enableMotor() { + return this._enableMotor; + } + set enableMotor(value) { + this._enableMotor = value; + if (this._joint) + this._joint.EnableMotor(value); + } + get motorSpeed() { + return this._motorSpeed; + } + set motorSpeed(value) { + this._motorSpeed = value; + if (this._joint) + this._joint.SetMotorSpeed(value); + } + get maxMotorForce() { + return this._maxMotorForce; + } + set maxMotorForce(value) { + this._maxMotorForce = value; + if (this._joint) + this._joint.SetMaxMotorForce(value); + } + get enableLimit() { + return this._enableLimit; + } + set enableLimit(value) { + this._enableLimit = value; + if (this._joint) + this._joint.EnableLimit(value); + } + get lowerTranslation() { + return this._lowerTranslation; + } + set lowerTranslation(value) { + this._lowerTranslation = value; + if (this._joint) + this._joint.SetLimits(value, this._upperTranslation); + } + get upperTranslation() { + return this._upperTranslation; + } + set upperTranslation(value) { + this._upperTranslation = value; + if (this._joint) + this._joint.SetLimits(this._lowerTranslation, value); + } + } + Laya.ClassUtils.regClass("laya.physics.joint.PrismaticJoint", PrismaticJoint); + Laya.ClassUtils.regClass("Laya.PrismaticJoint", PrismaticJoint); + + class PulleyJoint extends JointBase { + constructor() { + super(...arguments); + this.selfAnchor = [0, 0]; + this.otherAnchor = [0, 0]; + this.selfGroundPoint = [0, 0]; + this.otherGroundPoint = [0, 0]; + this.ratio = 1.5; + this.collideConnected = false; + } + _createJoint() { + if (!this._joint) { + if (!this.otherBody) + throw "otherBody can not be empty"; + this.selfBody = this.selfBody || this.owner.getComponent(RigidBody); + if (!this.selfBody) + throw "selfBody can not be empty"; + var box2d = window.box2d; + var def = PulleyJoint._temp || (PulleyJoint._temp = new box2d.b2PulleyJointDef()); + var posA = this.otherBody.owner.localToGlobal(Laya.Point.TEMP.setTo(this.otherAnchor[0], this.otherAnchor[1]), false, Physics.I.worldRoot); + var anchorVecA = new box2d.b2Vec2(posA.x / Physics.PIXEL_RATIO, posA.y / Physics.PIXEL_RATIO); + var posB = this.selfBody.owner.localToGlobal(Laya.Point.TEMP.setTo(this.selfAnchor[0], this.selfAnchor[1]), false, Physics.I.worldRoot); + var anchorVecB = new box2d.b2Vec2(posB.x / Physics.PIXEL_RATIO, posB.y / Physics.PIXEL_RATIO); + var groundA = this.otherBody.owner.localToGlobal(Laya.Point.TEMP.setTo(this.otherGroundPoint[0], this.otherGroundPoint[1]), false, Physics.I.worldRoot); + var groundVecA = new box2d.b2Vec2(groundA.x / Physics.PIXEL_RATIO, groundA.y / Physics.PIXEL_RATIO); + var groundB = this.selfBody.owner.localToGlobal(Laya.Point.TEMP.setTo(this.selfGroundPoint[0], this.selfGroundPoint[1]), false, Physics.I.worldRoot); + var groundVecB = new box2d.b2Vec2(groundB.x / Physics.PIXEL_RATIO, groundB.y / Physics.PIXEL_RATIO); + def.Initialize(this.otherBody.getBody(), this.selfBody.getBody(), groundVecA, groundVecB, anchorVecA, anchorVecB, this.ratio); + def.collideConnected = this.collideConnected; + this._joint = Physics.I._createJoint(def); + } + } + } + Laya.ClassUtils.regClass("laya.physics.joint.PulleyJoint", PulleyJoint); + Laya.ClassUtils.regClass("Laya.PulleyJoint", PulleyJoint); + + class RevoluteJoint extends JointBase { + constructor() { + super(...arguments); + this.anchor = [0, 0]; + this.collideConnected = false; + this._enableMotor = false; + this._motorSpeed = 0; + this._maxMotorTorque = 10000; + this._enableLimit = false; + this._lowerAngle = 0; + this._upperAngle = 0; + } + _createJoint() { + if (!this._joint) { + this.selfBody = this.selfBody || this.owner.getComponent(RigidBody); + if (!this.selfBody) + throw "selfBody can not be empty"; + var box2d = window.box2d; + var def = RevoluteJoint._temp || (RevoluteJoint._temp = new box2d.b2RevoluteJointDef()); + var anchorPos = this.selfBody.owner.localToGlobal(Laya.Point.TEMP.setTo(this.anchor[0], this.anchor[1]), false, Physics.I.worldRoot); + var anchorVec = new box2d.b2Vec2(anchorPos.x / Physics.PIXEL_RATIO, anchorPos.y / Physics.PIXEL_RATIO); + def.Initialize(this.otherBody ? this.otherBody.getBody() : Physics.I._emptyBody, this.selfBody.getBody(), anchorVec); + def.enableMotor = this._enableMotor; + def.motorSpeed = this._motorSpeed; + def.maxMotorTorque = this._maxMotorTorque; + def.enableLimit = this._enableLimit; + def.lowerAngle = this._lowerAngle; + def.upperAngle = this._upperAngle; + def.collideConnected = this.collideConnected; + this._joint = Physics.I._createJoint(def); + } + } + get enableMotor() { + return this._enableMotor; + } + set enableMotor(value) { + this._enableMotor = value; + if (this._joint) + this._joint.EnableMotor(value); + } + get motorSpeed() { + return this._motorSpeed; + } + set motorSpeed(value) { + this._motorSpeed = value; + if (this._joint) + this._joint.SetMotorSpeed(value); + } + get maxMotorTorque() { + return this._maxMotorTorque; + } + set maxMotorTorque(value) { + this._maxMotorTorque = value; + if (this._joint) + this._joint.SetMaxMotorTorque(value); + } + get enableLimit() { + return this._enableLimit; + } + set enableLimit(value) { + this._enableLimit = value; + if (this._joint) + this._joint.EnableLimit(value); + } + get lowerAngle() { + return this._lowerAngle; + } + set lowerAngle(value) { + this._lowerAngle = value; + if (this._joint) + this._joint.SetLimits(value, this._upperAngle); + } + get upperAngle() { + return this._upperAngle; + } + set upperAngle(value) { + this._upperAngle = value; + if (this._joint) + this._joint.SetLimits(this._lowerAngle, value); + } + } + Laya.ClassUtils.regClass("laya.physics.joint.RevoluteJoint", RevoluteJoint); + Laya.ClassUtils.regClass("Laya.RevoluteJoint", RevoluteJoint); + + class WeldJoint extends JointBase { + constructor() { + super(...arguments); + this.anchor = [0, 0]; + this.collideConnected = false; + this._frequency = 5; + this._dampingRatio = 0.7; + } + _createJoint() { + if (!this._joint) { + if (!this.otherBody) + throw "otherBody can not be empty"; + this.selfBody = this.selfBody || this.owner.getComponent(RigidBody); + if (!this.selfBody) + throw "selfBody can not be empty"; + var box2d = window.box2d; + var def = WeldJoint._temp || (WeldJoint._temp = new box2d.b2WeldJointDef()); + var anchorPos = this.selfBody.owner.localToGlobal(Laya.Point.TEMP.setTo(this.anchor[0], this.anchor[1]), false, Physics.I.worldRoot); + var anchorVec = new box2d.b2Vec2(anchorPos.x / Physics.PIXEL_RATIO, anchorPos.y / Physics.PIXEL_RATIO); + def.Initialize(this.otherBody.getBody(), this.selfBody.getBody(), anchorVec); + box2d.b2AngularStiffness(def, this._frequency, this._dampingRatio, def.bodyA, def.bodyB); + def.collideConnected = this.collideConnected; + this._joint = Physics.I._createJoint(def); + } + } + get frequency() { + return this._frequency; + } + set frequency(value) { + this._frequency = value; + if (this._joint) { + let out = {}; + let box2d = window.box2d; + let bodyA = this.otherBody ? this.otherBody.getBody() : Physics.I._emptyBody; + let bodyB = this.selfBody.getBody(); + box2d.b2AngularStiffness(out, this._frequency, this._dampingRatio, bodyA, bodyB); + this._joint.SetStiffness(out.stiffness); + this._joint.SetDamping(out.damping); + } + } + get damping() { + return this._dampingRatio; + } + set damping(value) { + this._dampingRatio = value; + if (this._joint) { + let out = {}; + let box2d = window.box2d; + let bodyA = this.otherBody ? this.otherBody.getBody() : Physics.I._emptyBody; + let bodyB = this.selfBody.getBody(); + box2d.b2AngularStiffness(out, this._frequency, this._dampingRatio, bodyA, bodyB); + this._joint.SetDamping(out.damping); + } + } + } + Laya.ClassUtils.regClass("laya.physics.joint.WeldJoint", WeldJoint); + Laya.ClassUtils.regClass("Laya.WeldJoint", WeldJoint); + + class WheelJoint extends JointBase { + constructor() { + super(...arguments); + this.anchor = [0, 0]; + this.collideConnected = false; + this.axis = [1, 0]; + this._frequency = 5; + this._dampingRatio = 0.7; + this._enableMotor = false; + this._motorSpeed = 0; + this._maxMotorTorque = 10000; + this._enableLimit = true; + this._lowerTranslation = 0; + this._upperTranslation = 0; + } + _createJoint() { + if (!this._joint) { + if (!this.otherBody) + throw "otherBody can not be empty"; + this.selfBody = this.selfBody || this.owner.getComponent(RigidBody); + if (!this.selfBody) + throw "selfBody can not be empty"; + var box2d = window.box2d; + var def = WheelJoint._temp || (WheelJoint._temp = new box2d.b2WheelJointDef()); + var anchorPos = this.selfBody.owner.localToGlobal(Laya.Point.TEMP.setTo(this.anchor[0], this.anchor[1]), false, Physics.I.worldRoot); + var anchorVec = new box2d.b2Vec2(anchorPos.x / Physics.PIXEL_RATIO, anchorPos.y / Physics.PIXEL_RATIO); + def.Initialize(this.otherBody.getBody(), this.selfBody.getBody(), anchorVec, new box2d.b2Vec2(this.axis[0], this.axis[1])); + def.enableMotor = this._enableMotor; + def.motorSpeed = this._motorSpeed; + def.maxMotorTorque = this._maxMotorTorque; + box2d.b2LinearStiffness(def, this._frequency, this._dampingRatio, def.bodyA, def.bodyB); + def.collideConnected = this.collideConnected; + def.enableLimit = this._enableLimit; + def.lowerTranslation = this._lowerTranslation / Physics.PIXEL_RATIO; + def.upperTranslation = this._upperTranslation / Physics.PIXEL_RATIO; + this._joint = Physics.I._createJoint(def); + } + } + get frequency() { + return this._frequency; + } + set frequency(value) { + this._frequency = value; + if (this._joint) { + let out = {}; + let box2d = window.box2d; + let bodyA = this.otherBody ? this.otherBody.getBody() : Physics.I._emptyBody; + let bodyB = this.selfBody.getBody(); + box2d.b2LinearStiffness(out, this._frequency, this._dampingRatio, bodyA, bodyB); + this._joint.SetStiffness(out.stiffness); + this._joint.SetDamping(out.damping); + } + } + get damping() { + return this._dampingRatio; + } + set damping(value) { + this._dampingRatio = value; + if (this._joint) { + let out = {}; + let box2d = window.box2d; + let bodyA = this.otherBody ? this.otherBody.getBody() : Physics.I._emptyBody; + let bodyB = this.selfBody.getBody(); + box2d.b2LinearStiffness(out, this._frequency, this._dampingRatio, bodyA, bodyB); + this._joint.SetDamping(out.damping); + } + } + get enableMotor() { + return this._enableMotor; + } + set enableMotor(value) { + this._enableMotor = value; + if (this._joint) + this._joint.EnableMotor(value); + } + get motorSpeed() { + return this._motorSpeed; + } + set motorSpeed(value) { + this._motorSpeed = value; + if (this._joint) + this._joint.SetMotorSpeed(value); + } + get maxMotorTorque() { + return this._maxMotorTorque; + } + set maxMotorTorque(value) { + this._maxMotorTorque = value; + if (this._joint) + this._joint.SetMaxMotorTorque(value); + } + get enableLimit() { + return this._enableLimit; + } + set enableLimit(value) { + this._enableLimit = value; + if (this._joint) + this._joint.EnableLimit(value); + } + get lowerTranslation() { + return this._lowerTranslation; + } + set lowerTranslation(value) { + this._lowerTranslation = value; + if (this._joint) + this._joint.SetLimits(value, this._upperTranslation); + } + get upperTranslation() { + return this._upperTranslation; + } + set upperTranslation(value) { + this._upperTranslation = value; + if (this._joint) + this._joint.SetLimits(this._lowerTranslation, value); + } + } + Laya.ClassUtils.regClass("laya.physics.joint.WheelJoint", WheelJoint); + Laya.ClassUtils.regClass("Laya.WheelJoint", WheelJoint); + + exports.BoxCollider = BoxCollider; + exports.ChainCollider = ChainCollider; + exports.CircleCollider = CircleCollider; + exports.ColliderBase = ColliderBase; + exports.DestructionListener = DestructionListener; + exports.DistanceJoint = DistanceJoint; + exports.EdgeCollider = EdgeCollider; + exports.GearJoint = GearJoint; + exports.IPhysics = IPhysics; + exports.JointBase = JointBase; + exports.MotorJoint = MotorJoint; + exports.MouseJoint = MouseJoint; + exports.Physics = Physics; + exports.PhysicsDebugDraw = PhysicsDebugDraw; + exports.PolygonCollider = PolygonCollider; + exports.PrismaticJoint = PrismaticJoint; + exports.PulleyJoint = PulleyJoint; + exports.RevoluteJoint = RevoluteJoint; + exports.RigidBody = RigidBody; + exports.WeldJoint = WeldJoint; + exports.WheelJoint = WheelJoint; + +}(window.Laya = window.Laya || {}, Laya)); diff --git a/examples/layaair/frontend/bin/libs/laya.physics3D.js b/examples/layaair/frontend/bin/libs/laya.physics3D.js new file mode 100644 index 0000000..57772ba --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.physics3D.js @@ -0,0 +1,3053 @@ +window.Physics3D=function(A,e){var r=window.Physics3D={};return r.then=(A=>{A(r)}),function(A,e,r){var i=e.getWorldTransform,f=e.setWorldTransform;window.atob||(window.atob=function(A){var e=String(A).replace(/[=]+$/,"");if(e.length%4==1)throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded.");for(var r,i,f=0,t=0,n="";i=e.charAt(t++);~i&&(r=f%4?64*r+i:i,f++%4)?n+=String.fromCharCode(255&r>>(-2*f&6)):0)i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(i);return n});var t=new ArrayBuffer(8),n=new Int32Array(t),a=new Float32Array(t),o=new Float64Array(t);function c(A){return n[A]}function b(A,e){n[A]=e}function l(){return o[0]}function u(A){o[0]=A}function s(A){a[0]=A}function k(){return a[0]}var v=new ArrayBuffer(A),d=function(A){var e=new Uint8Array(A);return function(A,r){var i,f;if("undefined"==typeof Buffer)for(i=atob(r),f=0;f>2]),Y=i+16|0,f}function I(A){var e=0;return e=a[A+60>>2],a[A+60>>2]=e+-1|e,e=a[A>>2],8&e?(a[A>>2]=32|e,-1):(a[A+4>>2]=0,a[A+8>>2]=0,e=a[A+40>>2],a[A+24>>2]=e,a[A+20>>2]=e,a[A+16>>2]=e+a[A+44>>2],0)}function J(A,e,r){var i=0,t=0,n=0,c=0,b=0,l=0,u=0;A:if(!r|!(3&e))i=r;else for(;;){if(f[0|A]=o[0|e],i=r+-1|0,A=A+1|0,e=e+1|0,1==(0|r))break A;if(r=i,!(3&e))break}r=3&A;A:{if(!r){if(i>>>0<16)r=i;else for(r=i+-16|0;a[A>>2]=a[e>>2],a[A+4>>2]=a[e+4>>2],a[A+8>>2]=a[e+8>>2],a[A+12>>2]=a[e+12>>2],A=A+16|0,e=e+16|0,i=i+-16|0,i>>>0>15;);if(8&r&&(i=a[e+4>>2],a[A>>2]=a[e>>2],a[A+4>>2]=i,e=e+8|0,A=A+8|0),4&r&&(a[A>>2]=a[e>>2],e=e+4|0,A=A+4|0),2&r&&(f[0|A]=o[0|e],f[A+1|0]=o[e+1|0],e=e+2|0,A=A+2|0),!(1&r))break A;return void(f[0|A]=o[0|e])}e:if(!(i>>>0<32||(r=r+-1|0,r>>>0>2))){switch(r-1|0){default:for(f[A+1|0]=o[e+1|0],t=a[e>>2],f[0|A]=t,f[A+2|0]=o[e+2|0],b=i+-3|0,l=A+3|0,u=i+-20&-16,r=0;A=r+l|0,c=e+r|0,n=a[c+4>>2],a[A>>2]=n<<8|t>>>24,t=a[c+8>>2],a[A+4>>2]=t<<8|n>>>24,n=a[c+12>>2],a[A+8>>2]=n<<8|t>>>24,t=a[c+16>>2],a[A+12>>2]=t<<8|n>>>24,r=r+16|0,b=b+-16|0,b>>>0>16;);A=r+l|0,e=3+(e+r|0)|0,i=(i-u|0)-19|0;break e;case 0:for(t=a[e>>2],f[0|A]=t,f[A+1|0]=o[e+1|0],b=i+-2|0,l=A+2|0,u=i+-20&-16,r=0;A=r+l|0,c=e+r|0,n=a[c+4>>2],a[A>>2]=n<<16|t>>>16,t=a[c+8>>2],a[A+4>>2]=t<<16|n>>>16,n=a[c+12>>2],a[A+8>>2]=n<<16|t>>>16,t=a[c+16>>2],a[A+12>>2]=t<<16|n>>>16,r=r+16|0,b=b+-16|0,b>>>0>17;);A=r+l|0,e=2+(e+r|0)|0,i=(i-u|0)-18|0;break e;case 1:}for(t=a[e>>2],f[0|A]=t,b=i+-1|0,l=A+1|0,u=i+-20&-16,r=0;A=r+l|0,c=e+r|0,n=a[c+4>>2],a[A>>2]=n<<24|t>>>8,t=a[c+8>>2],a[A+4>>2]=t<<24|n>>>8,n=a[c+12>>2],a[A+8>>2]=n<<24|t>>>8,t=a[c+16>>2],a[A+12>>2]=t<<24|n>>>8,r=r+16|0,b=b+-16|0,b>>>0>18;);A=r+l|0,e=1+(e+r|0)|0,i=(i-u|0)-17|0}16&i&&(r=o[0|e]|o[e+1|0]<<8,f[0|A]=r,f[A+1|0]=r>>>8,f[A+2|0]=o[e+2|0],f[A+3|0]=o[e+3|0],f[A+4|0]=o[e+4|0],f[A+5|0]=o[e+5|0],f[A+6|0]=o[e+6|0],f[A+7|0]=o[e+7|0],f[A+8|0]=o[e+8|0],f[A+9|0]=o[e+9|0],f[A+10|0]=o[e+10|0],f[A+11|0]=o[e+11|0],f[A+12|0]=o[e+12|0],f[A+13|0]=o[e+13|0],f[A+14|0]=o[e+14|0],f[A+15|0]=o[e+15|0],e=e+16|0,A=A+16|0),8&i&&(f[0|A]=o[0|e],f[A+1|0]=o[e+1|0],f[A+2|0]=o[e+2|0],f[A+3|0]=o[e+3|0],f[A+4|0]=o[e+4|0],f[A+5|0]=o[e+5|0],f[A+6|0]=o[e+6|0],f[A+7|0]=o[e+7|0],e=e+8|0,A=A+8|0),4&i&&(f[0|A]=o[0|e],f[A+1|0]=o[e+1|0],f[A+2|0]=o[e+2|0],f[A+3|0]=o[e+3|0],e=e+4|0,A=A+4|0),2&i&&(f[0|A]=o[0|e],f[A+1|0]=o[e+1|0],e=e+2|0,A=A+2|0),1&i&&(f[0|A]=o[0|e])}}function x(A,e,r){var i=0,f=0,t=0,n=0,c=0;i=a[r+16>>2];A:{if(!i){if(I(r))break A;i=a[r+16>>2]}if(t=a[r+20>>2],i-t>>>0>>0)return void Qt[a[r+32>>2]](r,A,e);e:if(!(a[r+64>>2]<0)){for(i=A;;){if((0|e)==(0|f))break e;if(f=f+1|0,c=e+i|0,n=i+-1|0,i=n,10==o[c+-1|0])break}if(i=A,A=1+(e-f|0)|0,Qt[a[r+32>>2]](r,i,A)>>>0>>0)break A;A=1+(e+n|0)|0,t=a[r+20>>2],e=f+-1|0}J(t,A,e),a[r+20>>2]=a[r+20>>2]+e}}function U(A){var e=0,r=0,i=0;a[265]||(a[265]=1036);A:{e:{for(;;){if((0|A)!=o[e+3024|0]){if(r=77,e=e+1|0,77!=(0|e))continue;break e}break}if(r=e,!e){A=3104;break A}}for(e=3104;i=o[0|e],A=e+1|0,e=A,i||(e=A,r=r+-1|0,r););}return A}function M(A,e){var r=0,i=0;i=0!=(0|e);A:{e:{r:if(e)if(3&A)for(;;){if(!o[0|A]){r=e;break e}if(i=1!=(0|e),r=e+-1|0,A=A+1|0,1==(0|e))break r;if(e=r,!(3&A))break}else r=e;else r=e;if(!i)break A}e:if(!(!o[0|A]|r>>>0<4))for(;;){if(e=a[A>>2],(-1^e)&e+-16843009&-2139062144)break e;if(A=A+4|0,r=r+-4|0,!(r>>>0>3))break}if(r)for(;;){if(!o[0|A])return A;if(A=A+1|0,r=r+-1|0,!r)break}}return 0}function S(A,e){return A?function(A,e){if(A){if(e>>>0<=127)return f[0|A]=e,1;A:{if(!a[259]){if(57216!=(-128&e))break A;return f[0|A]=e,1}if(e>>>0<=2047)return f[A+1|0]=63&e|128,f[0|A]=e>>>6|192,2;if(!(57344!=(-8192&e)&&e>>>0>=55296))return f[A+2|0]=63&e|128,f[0|A]=e>>>12|224,f[A+1|0]=e>>>6&63|128,3;if(e+-65536>>>0<=1048575)return f[A+3|0]=63&e|128,f[0|A]=e>>>18|240,f[A+2|0]=e>>>6&63|128,f[A+1|0]=e>>>12&63|128,4}a[256]=25,A=-1}else A=1;return A}(A,e):0}function X(A,e,r){var i=0,t=0,n=0,o=0;if(r&&(f[0|A]=e,i=A+r|0,f[i+-1|0]=e,!(r>>>0<3||(f[A+2|0]=e,f[A+1|0]=e,f[i+-3|0]=e,f[i+-2|0]=e,r>>>0<7||(f[A+3|0]=e,f[i+-4|0]=e,r>>>0<9||(i=0-A&3,t=i+A|0,e=B(255&e,16843009),a[t>>2]=e,r=r-i&-4,i=r+t|0,a[i+-4>>2]=e,r>>>0<9||(a[t+8>>2]=e,a[t+4>>2]=e,a[i+-8>>2]=e,a[i+-12>>2]=e,r>>>0<25||(a[t+24>>2]=e,a[t+20>>2]=e,a[t+16>>2]=e,a[t+12>>2]=e,a[i+-16>>2]=e,a[i+-20>>2]=e,a[i+-24>>2]=e,a[i+-28>>2]=e,o=4&t|24,r=r-o|0,r>>>0<32))))))))for(i=e,n=e,e=t+o|0;a[e>>2]=n,a[e+4>>2]=i,t=e+24|0,a[t>>2]=n,a[t+4>>2]=i,t=e+16|0,a[t>>2]=n,a[t+4>>2]=i,t=e+8|0,a[t>>2]=n,a[t+4>>2]=i,e=e+32|0,r=r+-32|0,r>>>0>31;);return A}function T(A,e){var r,i,f=0;if(u(+A),f=0|c(1),r=0|c(0),i=f,f=f>>>20&2047,2047!=(0|f)){if(!f)return 0==A?(a[e>>2]=0,A):(A=T(0x10000000000000000*A,e),a[e>>2]=a[e>>2]+-64,A);a[e>>2]=f+-1022,b(0,0|r),b(1,-2146435073&i|1071644672),A=+l()}return A}function j(A,e,r){var i,f=0,t=0;if(i=Y-208|0,Y=i,a[i+204>>2]=r,f=i+192|0,a[f>>2]=0,a[f+4>>2]=0,f=i+184|0,a[f>>2]=0,a[f+4>>2]=0,f=i+176|0,a[f>>2]=0,a[f+4>>2]=0,a[i+168>>2]=0,a[i+172>>2]=0,a[i+160>>2]=0,a[i+164>>2]=0,a[i+200>>2]=r,(0|O(0,e,i+200|0,i+80|0,i+160|0))>=0){t=a[A>>2],a[A+60>>2]<=0&&(a[A>>2]=-33&t);A:{e:{if(a[A+44>>2]){if(f=0,a[A+16>>2])break e}else a[A+44>>2]=80,a[A+24>>2]=0,a[A+16>>2]=0,a[A+20>>2]=0,f=a[A+40>>2],a[A+40>>2]=i;if(r=-1,I(A))break A}r=O(A,e,i+200|0,i+80|0,i+160|0)}f&&(Qt[a[A+32>>2]](A,0,0),a[A+44>>2]=0,a[A+40>>2]=f,a[A+24>>2]=0,a[A+16>>2]=0,a[A+20>>2]=0,r=0),a[A>>2]=a[A>>2]|32&t}Y=i+208|0}function O(A,e,r,i,n){var b,l,s,k,v,d,C,_,R,Q=0,h=0,G=0,y=0,p=0,W=0,w=0,D=0,E=0,Z=0,N=0,I=0,J=0,j=0,O=0,z=0,P=0,K=0,L=0,q=0,$=0,AA=0,eA=0,rA=0,iA=0,fA=0,tA=0,nA=0,aA=0,oA=0;b=Y-880|0,Y=b,d=b+336|8,C=b+55|0,_=-338-b|0,k=b+336|9,R=b+656|0,s=b+336|0,v=0-(b+336|0)|0,l=b+56|0;A:{e:{r:for(;;){i:if(y=e,!((0|Q)>(2147483647-K|0))){K=Q+K|0;f:{t:{n:{if(Q=o[0|y],Q)for(;;){a:{h=255&Q;o:if(h){if(37!=(0|h))break a;for(h=e,Q=h;;){if(37!=o[Q+1|0]){e=Q;break o}if(h=h+1|0,G=o[Q+2|0],e=Q+2|0,Q=e,37!=(0|G))break}}else h=e;if(Q=h-y|0,P=2147483647-K|0,(0|Q)>(0|P))break i;if(!A|32&o[0|A]||x(y,Q,A),Q)continue r;Q=e+1|0,W=f[e+1|0],h=W+-48|0,Z=-1,h>>>0>9||(G=36==o[e+2|0],Q=G?e+3|0:Q,AA=G?1:AA,W=f[(G?3:1)+e|0],Z=G?h:-1),p=0,e=W+-32|0;o:if(!(e>>>0>31)&&(e=1<>>0>=32)break o;if(G=Q+1|0,e=1<>>0>9)w=Q;else{for(e=0;N=-1,h=f[Q+1|0],w=Q+1|0,Q=w,e>>>0<=214748364&&(e=B(e,10),N=(0|G)>(2147483647-e|0)?-1:e+G|0),e=N,G=h+-48|0,G>>>0<10;);if((0|N)<0)break i}else{if(e=f[Q+1|0]+-48|0,36!=o[Q+2|0]|e>>>0>9){if(AA)break n;if(w=Q+1|0,!A){AA=0,N=0;break o}e=a[r>>2],a[r>>2]=e+4,AA=0,N=a[e>>2]}else a[(e<<2)+n>>2]=10,w=Q+3|0,AA=1,N=a[((f[Q+1|0]<<3)+i|0)-384>>2];if((0|N)>-1)break o;N=0-N|0,p|=8192}if(Q=0,W=-1,46==o[0|w])if(h=f[w+1|0],42!=(0|h))if(e=w+1|0,E=h+-48|0,E>>>0>9)D=1,W=0;else for(w=0,G=e;W=-1,w>>>0<=214748364&&(e=B(w,10),W=(0|E)>(2147483647-e|0)?-1:e+E|0),D=1,h=f[G+1|0],e=G+1|0,G=e,w=W,E=h+-48|0,E>>>0<10;);else{if(e=f[w+2|0]+-48|0,36!=o[w+3|0]|e>>>0>9){if(AA)break n;e=w+2|0,W=0,A&&(h=a[r>>2],a[r>>2]=h+4,W=a[h>>2])}else a[(e<<2)+n>>2]=10,e=w+4|0,W=a[((f[w+2|0]<<3)+i|0)-384>>2];D=(-1^W)>>>31}else e=w,D=0;for(;;){if(G=Q,h=f[0|e]+-65|0,h>>>0>57)break n;if(e=e+1|0,Q=o[4704+(h+B(G,58)|0)|0],!(Q+-1>>>0<8))break}if(!Q)break n;o:{c:{b:{if(27==(0|Q)){if((0|Z)<=-1)break b;break n}if((0|Z)<0)break c;a[(Z<<2)+n>>2]=Q,Q=(Z<<3)+i|0,h=a[Q+4>>2],a[b+56>>2]=a[Q>>2],a[b+60>>2]=h}if(Q=0,!A)continue r;break o}if(!A){K=0;break A}H(b+56|0,Q,r)}h=-65537&p,Z=8192&p?h:p;o:{c:{b:if(Q=f[e+-1|0],q=G&&3==(15&Q)?-33&Q:Q,Q=q+-65|0,!(Q>>>0>55)){l:{u:{s:{k:{v:{d:{C:{g:{B:{_:{m:{R:switch(Q-1|0){case 51:E=0,p=a[b+56>>2],Q=a[b+60>>2],O=4678;break m;case 44:if(Q=0,h=255&G,h>>>0>7)continue r;switch(h-1|0){default:case 0:a[a[b+56>>2]>>2]=K;continue r;case 1:h=a[b+56>>2],a[h>>2]=K,a[h+4>>2]=K>>31;continue r;case 2:t[a[b+56>>2]>>1]=K;continue r;case 3:f[a[b+56>>2]]=K;continue r;case 5:a[a[b+56>>2]>>2]=K;continue r;case 4:continue r;case 6:}h=a[b+56>>2],a[h>>2]=K,a[h+4>>2]=K>>31;continue r;case 46:W=W>>>0>8?W:8,Z|=8,q=120;case 22:case 54:if(E=0,O=4678,h=a[b+60>>2],Q=h,p=a[b+56>>2],!(Q|p)){y=l;break _}for(h=32&q,y=l;y=y+-1|0,f[0|y]=h|o[5312+(15&p)|0],p=(15&Q)<<28|p>>>4,Q>>>=4,p|Q;);if(!(8&Z)|!(a[b+56>>2]|a[b+60>>2]))break _;O=4678+(q>>4)|0,E=2;break _;case 45:if(y=l,h=a[b+60>>2],Q=h,p=a[b+56>>2],Q|p)for(;y=y+-1|0,f[0|y]=7&p|48,p=(7&Q)<<29|p>>>3,Q>>>=3,p|Q;);if(E=0,O=4678,!(8&Z))break _;h=l-y|0,W=(0|W)>(0|h)?W:h+1|0;break _;case 0:case 2:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 18:case 19:case 20:case 21:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 32:case 38:case 40:case 41:case 42:case 47:case 48:case 50:case 52:case 53:break b;case 1:break k;case 17:break v;case 49:break C;case 43:break g;case 33:break B;case 34:case 39:break R;default:break l}h=a[b+60>>2],Q=h,p=a[b+56>>2],(0|Q)>-1||(0|Q)>=-1&&!(p>>>0<=4294967295)?2048&Z?(E=1,O=4679):(E=1&Z,O=E?4680:4678):(Q=0-((0

>>0)+Q|0)|0,p=0-p|0,a[b+56>>2]=p,a[b+60>>2]=Q,E=1,O=4678)}if(1==(0|Q)&p>>>0>=0|Q>>>0>1)for(y=l;h=mt(p,Q,10),w=V,G=w,y=y+-1|0,iA=y,fA=p-_t(h,G,10,0)|48,f[0|iA]=fA,w=9==(0|Q)&p>>>0>4294967295|Q>>>0>9,p=h,Q=G,w;);else h=p,y=l;if(Q=h,Q)for(;y=y+-1|0,h=(Q>>>0)/10|0,f[0|y]=Q-B(h,10)|48,G=Q>>>0>9,Q=h,G;);}if((0|W)<0&&D)break i;if(Z=D?-65537&Z:Z,Q=a[b+56>>2],h=a[b+60>>2],!(!!(Q|h)|W)){y=l,Q=y,W=0;break f}h=!(Q|h)+(l-y|0)|0,W=(0|W)>(0|h)?W:h;break c}f[b+55|0]=a[b+56>>2],E=0,O=4678,W=1,y=C,Q=l,Z=h;break f}y=U(a[256]);break d}Q=a[b+56>>2],y=Q||4688}if(E=0,G=(0|W)<0?2147483647:W,Q=M(y,G),G=Q?Q-y|0:G,Q=G+y|0,O=4678,(0|W)<=-1)break o;Z=h,W=G;break f}if(y=a[b+56>>2],h=y,W)break s;Q=0;break u}a[b+12>>2]=0,a[b+8>>2]=a[b+56>>2],a[b+56>>2]=b+8,W=-1,h=b+8|0}y=h,Q=0,h=y;s:{for(;;){if(G=a[h>>2],!G)break s;if(p=S(b+4|0,G),G=(0|p)<0,!(G|p>>>0>W-Q>>>0)){if(h=h+4|0,Q=Q+p|0,W>>>0>Q>>>0)continue;break s}break}if(G)break e}if((0|Q)<0)break i}w=73728&Z;u:if(!(w|(0|N)<=(0|Q))){if(E=N-Q|0,G=E>>>0<256,X(b- -64|0,32,G?E:256),W=a[A>>2],h=32&W,G){if(h)break u}else{for(h=!h,G=E;1&h&&(x(b- -64|0,256,A),W=a[A>>2]),p=32&W,h=!p,G=G+-256|0,G>>>0>255;);if(p)break u;E&=255}x(b- -64|0,E,A)}u:if(Q)for(h=0;;){if(G=a[y>>2],!G)break u;if(G=S(b+4|0,G),h=G+h|0,h>>>0>Q>>>0)break u;if(32&o[0|A]||x(b+4|0,G,A),y=y+4|0,!(h>>>0>>0))break}u:if(!(8192!=(0|w)|(0|N)<=(0|Q))){if(p=N-Q|0,G=p>>>0<256,X(b- -64|0,32,G?p:256),y=a[A>>2],h=32&y,G){if(h)break u}else{for(h=!h,G=p;1&h&&(x(b- -64|0,256,A),y=a[A>>2]),w=32&y,h=!w,G=G+-256|0,G>>>0>255;);if(w)break u;p&=255}x(b- -64|0,p,A)}Q=(0|N)>(0|Q)?N:Q;continue r}if(D&&(0|W)<=-1)break i;I=g[b+56>>3],a[b+364>>2]=0,u(+I),h=0|c(1),iA=1,nA=c(0)>>>0<=4294967295?0:1,aA=0,oA=(0|h)>=-1,fA=oA?nA:aA,tA=(0|h)>-1,(tA?iA:fA)?2048&Z?($=1,eA=5331):($=1&Z,eA=$?5334:5329):(I=-I,$=1,eA=5328),L=m(I);l:if(L!=F&L==L)if(L=T(I,b+364|0),I=L+L,0!=I&&(a[b+364>>2]=a[b+364>>2]+-1),z=32|q,97!=(0|z)){for(h=(0|W)<0,0!=I?(y=a[b+364>>2]+-28|0,a[b+364>>2]=y,I*=268435456):y=a[b+364>>2],D=h?6:W,P=(0|y)<0?b+368|0:R,G=P;h=I<4294967296&I>=0?~~I>>>0:0,a[G>>2]=h,G=G+4|0,I=1e9*(I-+(h>>>0)),0!=I;);if((0|y)<1)Q=G,h=P;else for(h=P;;){if(E=(0|y)<29?y:29,Q=G+-4|0,!(Q>>>0>>0)){for(W=E,p=0;y=Q,J=a[Q>>2],j=31&W,32<=(63&W)>>>0?(w=J<>>32-j,j=J<>>0

>>0?w+1|0:w,1e9),iA=y,fA=J-_t(p,V,1e9,0)|0,a[iA>>2]=fA,Q=Q+-4|0,Q>>>0>=h>>>0;);p&&(h=h+-4|0,a[h>>2]=p)}for(;Q=G,Q>>>0>h>>>0&&(G=Q+-4|0,!a[G>>2]););if(y=a[b+364>>2]-E|0,a[b+364>>2]=y,G=Q,!((0|y)>0))break}if((0|y)<=-1)for(E=1+((D+25>>>0)/9|0)|0;;){if(G=0-y|0,J=(0|G)<9?G:9,h>>>0>=Q>>>0)h=a[h>>2]?h:h+4|0;else{for(W=1e9>>>J,w=-1<>2],a[G>>2]=y+(p>>>J),y=B(W,p&w),G=G+4|0,G>>>0>>0;);h=a[h>>2]?h:h+4|0,y&&(a[Q>>2]=y,Q=Q+4|0)}if(y=J+a[b+364>>2]|0,a[b+364>>2]=y,G=102==(0|z)?P:h,Q=Q-G>>2>(0|E)?G+(E<<2)|0:Q,!((0|y)<0))break}if(G=0,!(h>>>0>=Q>>>0||(G=B(P-h>>2,9),p=a[h>>2],p>>>0<10)))for(y=10;G=G+1|0,y=B(y,10),p>>>0>=y>>>0;);if(j=102==(0|z)?0:G,z=103==(0|z),J=z&0!=(0|D),y=(D-j|0)-J|0,(0|y)<(B(Q-P>>2,9)+-9|0)){if(W=y+9216|0,w=(0|W)/9|0,E=P+(w<<2)|0,p=E+-4092|0,y=10,w=B(w,9),(1+(W-w|0)|0)<=8)for(W=((J+(w+j|0)|0)-D|0)-9208|0;y=B(y,10),W=W+-1|0,W;);if(J=a[p>>2],w=(J>>>0)/(y>>>0)|0,W=p+4|0,j=J-B(y,w)|0,(j||(0|Q)!=(0|W))&&(!(1&w)&&(I=9007199254740992,!(1&f[p+-4|0])|1e9!=(0|y)|p>>>0<=h>>>0)||(I=9007199254740994),L=.5,w=y>>>1,j>>>0>=w>>>0&&(L=(0|Q)==(0|W)&&(0|w)==(0|j)?1:1.5),!$|45!=o[0|eA]||(I=-I,L=-L),w=J-j|0,a[p>>2]=w,I+L!=I)){if(G=y+w|0,a[p>>2]=G,G>>>0>=1e9){for(G=E+-4096|0;a[G+4>>2]=0,G>>>0>>0&&(h=h+-4|0,a[h>>2]=0),y=a[G>>2]+1|0,a[G>>2]=y,G=G+-4|0,y>>>0>999999999;);p=G+4|0}if(G=B(P-h>>2,9),w=a[h>>2],!(w>>>0<10))for(y=10;G=G+1|0,y=B(y,10),w>>>0>=y>>>0;);}y=p+4|0,Q=Q>>>0>y>>>0?y:Q}u:{for(;;){if(W=Q,j=0,Q>>>0<=h>>>0)break u;if(Q=W+-4|0,a[Q>>2])break}j=1}if(z){if(y=D||1,Q=(0|y)>(0|G)&(0|G)>-5,D=(Q?-1^G:-1)+y|0,q=(Q?-1:-2)+q|0,E=8&Z,!E){if(Q=9,j&&(p=a[W+-4>>2],p&&(Q=0,!((p>>>0)%10))))for(y=10;Q=Q+1|0,y=B(y,10),!((p>>>0)%(y>>>0)););y=B(W-P>>2,9)+-9|0,102!=(32|q)?(E=0,Q=(G+y|0)-Q|0,Q=(0|Q)>0?Q:0,D=(0|D)<(0|Q)?D:Q):(E=0,Q=y-Q|0,Q=(0|Q)>0?Q:0,D=(0|D)<(0|Q)?D:Q)}}else E=8&Z;if(Q=-1,z=D|E,!((0|D)>(0|(z?2147483645:2147483646)))){if(O=1+((0!=(0|z))+D|0)|0,J=102!=(32|q),J){if(y=s,Q=G>>31,Q^=Q+G,Q)for(;y=y+-1|0,p=(Q>>>0)/10|0,f[0|y]=Q-B(p,10)|48,w=Q>>>0>9,Q=p,w;);if((s-y|0)<=1){for(Q=y+-1|0;f[0|Q]=48,p=s-Q|0,y=Q+-1|0,Q=y,(0|p)<2;);y=y+1|0}if(rA=y+-2|0,f[0|rA]=q,Q=-1,f[y+-1|0]=(0|G)<0?45:43,G=s-rA|0,(0|G)>(2147483647-O|0))break l}else{if((0|G)>(2147483647-O|0))break l;G=(0|G)>0?G:0}if(G=G+O|0,!((0|G)>(2147483647^$))){Z&=73728,O=G+$|0;u:if(!(Z|(0|N)<=(0|O))){if(w=N-O|0,G=w>>>0<256,X(b- -64|0,32,G?w:256),y=a[A>>2],Q=32&y,G){if(Q)break u}else{for(Q=!Q,G=w;1&Q&&(x(b- -64|0,256,A),y=a[A>>2]),p=32&y,Q=!p,G=G+-256|0,G>>>0>255;);if(p)break u;w&=255}x(b- -64|0,w,A)}32&o[0|A]||x(eA,$,A);u:if(!(65536!=(0|Z)|(0|N)<=(0|O))){if(w=N-O|0,G=w>>>0<256,X(b- -64|0,48,G?w:256),y=a[A>>2],Q=32&y,G){if(Q)break u}else{for(Q=!Q,G=w;1&Q&&(x(b- -64|0,256,A),y=a[A>>2]),p=32&y,Q=!p,G=G+-256|0,G>>>0>255;);if(p)break u;w&=255}x(b- -64|0,w,A)}u:if(J){s:if(!((0|D)<=-1)){for(W=j?W:h+4|0,p=h;;){y=k,Q=a[p>>2];k:{if(Q){for(G=0;y=(Q>>>0)/10|0,f[344+(G+b|0)|0]=Q-B(y,10)|48,G=G+-1|0,w=Q>>>0>9,Q=y,w;);if(y=345+(G+b|0)|0,G)break k}y=y+-1|0,f[0|y]=48}k:if((0|h)==(0|p))32&o[0|A]||x(y,1,A),y=y+1|0,32&o[0|A]|((0|D)<1?!E:0)||x(5363,1,A);else{if(y>>>0<=b+336>>>0)break k;for(X(b+336|0,48,y+v|0);y=y+-1|0,y>>>0>b+336>>>0;);}if(Q=k-y|0,32&o[0|A]||x(y,(0|D)>(0|Q)?Q:D,A),p=p+4|0,D=D-Q|0,!((0|D)>-1&&p>>>0>>0))break}if(!((0|D)<1)){if(h=D>>>0<256,X(b- -64|0,48,h?D:256),G=a[A>>2],Q=32&G,h){if(Q)break s}else{for(Q=!Q,h=D;1&Q&&(x(b- -64|0,256,A),G=a[A>>2]),y=32&G,Q=!y,h=h+-256|0,h>>>0>255;);if(y)break s;D&=255}x(b- -64|0,D,A)}}32&o[0|A]||x(rA,s-rA|0,A)}else{for(w=h>>>0>P>>>0?P:h,p=w;;){if(Q=a[p>>2],Q)for(h=0;G=(Q>>>0)/10|0,f[h+d|0]=Q-B(G,10)|48,h=h+-1|0,y=Q>>>0>9,Q=G,y;);else h=0;Q=h+k|0;s:if((0|p)==(0|w))h||(Q=Q+-1|0,f[0|Q]=48);else{if(Q>>>0<=b+336>>>0)break s;X(b+336|0,48,h+9|0),Q=b+336|0}if(32&o[0|A]||x(Q,k-Q|0,A),p=p+4|0,!(p>>>0<=P>>>0))break}!z|32&o[0|A]||x(5363,1,A);s:if(!((0|D)<1|p>>>0>=W>>>0))for(;;){Q=k,h=a[p>>2];k:{if(h){for(;Q=Q+-1|0,G=(h>>>0)/10|0,f[0|Q]=h-B(G,10)|48,y=h>>>0>9,h=G,y;);if(Q>>>0<=b+336>>>0)break k}for(X(b+336|0,48,Q+v|0);Q=Q+-1|0,Q>>>0>b+336>>>0;);}if(32&o[0|A]||x(Q,(0|D)<9?D:9,A),D=D+-9|0,(0|D)<1)break s;if(p=p+4|0,!(p>>>0>>0))break}if((0|D)<1)break u;if(h=D>>>0<256,X(b- -64|0,48,h?D:256),G=a[A>>2],Q=32&G,h){if(Q)break u}else{for(Q=!Q,h=D;1&Q&&(x(b- -64|0,256,A),G=a[A>>2]),y=32&G,Q=!y,h=h+-256|0,h>>>0>255;);if(y)break u;D&=255}x(b- -64|0,D,A)}u:if(!(8192!=(0|Z)|(0|N)<=(0|O))){if(W=N-O|0,Q=W>>>0<256,X(b- -64|0,32,Q?W:256),G=a[A>>2],h=32&G,Q){if(h)break u}else{for(Q=!h,h=W;1&Q&&(x(b- -64|0,256,A),G=a[A>>2]),y=32&G,Q=!y,h=h+-256|0,h>>>0>255;);if(y)break u;W&=255}x(b- -64|0,W,A)}Q=(0|N)>(0|O)?N:O}}}else{if(p=32&q,J=p?eA+9|0:eA,!(!(12-W)|W>>>0>11)){for(Q=W+-12|0,L=16;L*=16,h=Q+1|0,G=h>>>0>=Q>>>0,Q=h,G;);I=45!=o[0|J]?I+L-L:-(L+(-I-L))}G=s,w=a[b+364>>2],h=w>>31,Q=h^h+w;u:{if(Q){for(h=0;G=(Q>>>0)/10|0,f[335+(h+b|0)|0]=Q-B(G,10)|48,h=h+-1|0,y=Q>>>0>9,Q=G,y;);if(G=336+(h+b|0)|0,h)break u}G=G+-1|0,f[0|G]=48}for(E=2|$,P=G+-2|0,f[0|P]=q+15,f[G+-1|0]=(0|w)<0?45:43,y=8&Z,h=b+336|0;Q=h,G=m(I)<2147483648?~~I:-2147483648,f[0|Q]=p|o[G+5312|0],h=Q+1|0,I=16*(I-+(0|G)),1!=(h-(b+336|0)|0)|(0==I?!((0|W)>0|y):0)||(f[Q+1|0]=46,h=Q+2|0),0!=I;);if(Q=-1,w=s-P|0,G=w+E|0,(2147483645-G|0)<(0|W))break l;D=73728&Z,z=h-(b+336|0)|0,p=W&&(h+_|0)<(0|W)?W+2|0:z,W=p+G|0;u:if(!(D|(0|N)<=(0|W))){if(Z=N-W|0,Q=Z>>>0<256,X(b- -64|0,32,Q?Z:256),G=a[A>>2],h=32&G,Q){if(h)break u}else{for(Q=!h,h=Z;1&Q&&(x(b- -64|0,256,A),G=a[A>>2]),y=32&G,Q=!y,h=h+-256|0,h>>>0>255;);if(y)break u;Z&=255}x(b- -64|0,Z,A)}32&o[0|A]||x(J,E,A);u:if(!(65536!=(0|D)|(0|N)<=(0|W))){if(E=N-W|0,Q=E>>>0<256,X(b- -64|0,48,Q?E:256),G=a[A>>2],h=32&G,Q){if(h)break u}else{for(Q=!h,h=E;1&Q&&(x(b- -64|0,256,A),G=a[A>>2]),y=32&G,Q=!y,h=h+-256|0,h>>>0>255;);if(y)break u;E&=255}x(b- -64|0,E,A)}32&o[0|A]||x(b+336|0,z,A),p=p-z|0;u:if(!((0|p)<1)){if(h=p>>>0<256,X(b- -64|0,48,h?p:256),G=a[A>>2],Q=32&G,h){if(Q)break u}else{for(Q=!Q,h=p;1&Q&&(x(b- -64|0,256,A),G=a[A>>2]),y=32&G,Q=!y,h=h+-256|0,h>>>0>255;);if(y)break u;p&=255}x(b- -64|0,p,A)}32&o[0|A]||x(P,w,A);u:if(!(8192!=(0|D)|(0|N)<=(0|W))){if(p=N-W|0,Q=p>>>0<256,X(b- -64|0,32,Q?p:256),G=a[A>>2],h=32&G,Q){if(h)break u}else{for(Q=!h,h=p;1&Q&&(x(b- -64|0,256,A),G=a[A>>2]),y=32&G,Q=!y,h=h+-256|0,h>>>0>255;);if(y)break u;p&=255}x(b- -64|0,p,A)}Q=(0|N)>(0|W)?N:W}else{w=$+3|0;u:if(!(8192&Z|(0|N)<=(0|w))){if(p=N-w|0,Q=p>>>0<256,X(b- -64|0,32,Q?p:256),G=a[A>>2],h=32&G,Q){if(h)break u}else{for(Q=!h,h=p;1&Q&&(x(b- -64|0,256,A),G=a[A>>2]),y=32&G,Q=!y,h=h+-256|0,h>>>0>255;);if(y)break u;p&=255}x(b- -64|0,p,A)}h=a[A>>2],32&h||(x(eA,$,A),h=a[A>>2]),32&h||(h=(32&q)>>>5,x(I!=I?h?5355:5359:h?5347:5351,3,A));u:if(!(8192!=(73728&Z)|(0|N)<=(0|w))){if(p=N-w|0,Q=p>>>0<256,X(b- -64|0,32,Q?p:256),G=a[A>>2],h=32&G,Q){if(h)break u}else{for(Q=!h,h=p;1&Q&&(x(b- -64|0,256,A),G=a[A>>2]),y=32&G,Q=!y,h=h+-256|0,h>>>0>255;);if(y)break u;p&=255}x(b- -64|0,p,A)}Q=(0|N)>(0|w)?N:w}if((0|Q)>=0)continue r;break i}E=0,O=4678}Q=l;break f}if(Z=h,W=G,!o[0|Q])break f;break i}Q=o[e+1|0],e=e+1|0}if(A)break A;if(!AA){K=0;break A}if(A=a[n+4>>2],e=1,A&&(H(i+8|0,A,r),A=a[n+8>>2],e=2,A&&(H(i+16|0,A,r),A=a[n+12>>2],e=3,A&&(H(i+24|0,A,r),A=a[n+16>>2],e=4,A&&(H(i+32|0,A,r),A=a[n+20>>2],e=5,A&&(H(i+40|0,A,r),A=a[n+24>>2],e=6,A&&(H(i+48|0,A,r),A=a[n+28>>2],e=7,A&&(H(i+56|0,A,r),A=a[n+32>>2],e=8,A)))))))){if(H(i- -64|0,A,r),A=a[n+36>>2],A)break t;e=9}for(e<<=2;;){if(a[e+n>>2])break n;if(e=e+4|0,40==(0|e))break}K=1;break A}a[256]=28;break e}H(i+72|0,A,r),K=1;break A}if(z=Q-y|0,J=(0|W)<(0|z)?z:W,!((0|J)>(2147483647-E|0)||(j=E+J|0,Q=(0|N)<(0|j)?j:N,(0|Q)>(0|P)))){Z&=73728;f:if(!(Z|(0|j)>=(0|N))){if(D=Q-j|0,G=D>>>0<256,X(b- -64|0,32,G?D:256),p=a[A>>2],h=32&p,G){if(h)break f}else{for(h=!h,G=D;1&h&&(x(b- -64|0,256,A),p=a[A>>2]),w=32&p,h=!w,G=G+-256|0,G>>>0>255;);if(w)break f;D&=255}x(b- -64|0,D,A)}32&o[0|A]||x(O,E,A);f:if(!(65536!=(0|Z)|(0|j)>=(0|N))){if(E=Q-j|0,G=E>>>0<256,X(b- -64|0,48,G?E:256),p=a[A>>2],h=32&p,G){if(h)break f}else{for(h=!h,G=E;1&h&&(x(b- -64|0,256,A),p=a[A>>2]),w=32&p,h=!w,G=G+-256|0,G>>>0>255;);if(w)break f;E&=255}x(b- -64|0,E,A)}f:if(!((0|z)>=(0|W))){if(w=J-z|0,G=w>>>0<256,X(b- -64|0,48,G?w:256),W=a[A>>2],h=32&W,G){if(h)break f}else{for(h=!h,G=w;1&h&&(x(b- -64|0,256,A),W=a[A>>2]),p=32&W,h=!p,G=G+-256|0,G>>>0>255;);if(p)break f;w&=255}x(b- -64|0,w,A)}if(32&o[0|A]||x(y,z,A),8192!=(0|Z)|(0|j)>=(0|N))continue;if(W=Q-j|0,G=W>>>0<256,X(b- -64|0,32,G?W:256),y=a[A>>2],h=32&y,G){if(h)continue}else{for(h=!h,G=W;1&h&&(x(b- -64|0,256,A),y=a[A>>2]),p=32&y,h=!p,G=G+-256|0,G>>>0>255;);if(p)continue;W&=255}x(b- -64|0,W,A);continue}}break}a[256]=61}K=-1}return Y=b+880|0,K}function H(A,e,r){A:{e:{r:{i:{f:{if(e=e+-9|0,e>>>0<=17){switch(e-1|0){case 5:e=a[r>>2],a[r>>2]=e+4,e=t[e>>1],a[A>>2]=e;break e;case 6:e=a[r>>2],a[r>>2]=e+4,a[A>>2]=v[e>>1];break A;case 7:e=a[r>>2],a[r>>2]=e+4,e=f[0|e],a[A>>2]=e;break e;case 8:e=a[r>>2],a[r>>2]=e+4,a[A>>2]=o[0|e];break A;case 16:A=function(){var A=0,e=0,r=0;t:{n:{a:if(A=5168,3&A){if(!o[5168])return 0;for(A=5169;;){if(!(3&A))break a;if(e=o[0|A],r=A+1|0,A=r,!e)break}break n}for(A=A+-4|0;A=A+4|0,e=a[A>>2],!((-1^e)&e+-16843009&-2139062144););if(!(255&e))return A-5168|0;for(;r=o[A+1|0],e=A+1|0,A=e,r;);break t}e=r+-1|0}return e-5168|0}(),function(A){var e,r=0,i=0,f=0,t=0,n=0,c=0,b=0;n=5168,e=A,r=a[716];t:{if(!r){if(r=0,I(2848))break t;r=a[716]}if(f=a[717],r-f>>>0>>0)r=0|Qt[a[720]](2848,5168,e);else{i=e;n:if(!(a[728]<0)){for(c=e+5168|0,r=0;;){if(i=e,!(r+e))break n;if(b=r+c|0,i=r+-1|0,r=i,10==o[b+-1|0])break}if(t=1+(e+i|0)|0,r=0|Qt[a[720]](2848,5168,t),r>>>0>>0)break t;n=1+(i+c|0)|0,f=a[717],i^=-1}r=i,J(f,n,r),a[717]=a[717]+r,r=r+t|0}}}(A),p();case 0:case 3:case 13:break f;case 1:case 4:case 10:case 14:break i;case 2:case 9:case 11:case 12:case 15:break r}e=a[r>>2],a[r>>2]=e+4,a[A>>2]=a[e>>2]}return}e=a[r>>2],a[r>>2]=e+4,e=a[e>>2],a[A>>2]=e;break e}e=a[r>>2],a[r>>2]=e+4,a[A>>2]=a[e>>2];break A}return e=a[r>>2]+7&-8,a[r>>2]=e+8,r=a[e+4>>2],a[A>>2]=a[e>>2],void(a[A+4>>2]=r)}return void(a[A+4>>2]=e>>31)}a[A+4>>2]=0}function z(){var A;A=Y-16|0,Y=A,a[A+12>>2]=5367,a[A+8>>2]=0,j(a[752],a[A+12>>2],a[A+8>>2]),function(A){var e;e=Y-16|0,Y=e,a[e+12>>2]=0,j(A,5365,0),Y=e+16|0}(a[752]),p()}function P(e){return e?65535&e|(0|e)<=-1?void p():(e=function(e){e|=0;var n=0|ht(),c=n+e|0;if(n>>16),-1==(0|e)?(a[256]=48,-1):e<<16):ht()<<16}function K(A){var e,r=0,i=0,f=0,t=0,n=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0;if(e=Y-16|0,Y=e,!(a[272]||(r=P(0)-90864|0,r>>>0<89))){for(i=a[384],i||(a[387]=-1,a[388]=-1,a[385]=65536,a[386]=65536,i=e+8&-16^1431655768,a[384]=i,a[389]=0,a[377]=0),a[379]=r,a[378]=90864,a[270]=90864,a[275]=i,a[274]=-1;i=f+1104|0,a[f+1112>>2]=i,a[f+1116>>2]=i,f=f+8|0,256!=(0|f););i=r+-64|0,a[22719]=1|i,a[273]=a[388],a[272]=90872,a[269]=i,a[r+90812>>2]=56}A:{e:{r:{i:{f:{t:{n:{a:{o:{c:{b:{if(A>>>0<=236){if(n=a[266],b=A>>>0<11?16:A+19&-16,A=b>>>3,r=n>>>A,3&r){r=1^(A|1&r),t=r<<3,A=a[t+1112>>2],f=A+8|0,i=a[A+8>>2],t=t+1104|0,(0|i)!=(0|t)?(a[t+8>>2]=i,a[i+12>>2]=t):(k=1064,v=Rt(r)&n,a[k>>2]=v),r<<=3,a[A+4>>2]=3|r,A=A+r|0,a[A+4>>2]=1|a[A+4>>2];break A}if(l=a[268],b>>>0<=l>>>0)break b;if(r){r<<=A,A=2<>>12&16,i=r,A>>>=r,r=A>>>5&8,i|=r,A>>>=r,r=A>>>2&4,i|=r,A>>>=r,r=A>>>1&2,i|=r,A>>>=r,r=A>>>1&1,r=(i|r)+(A>>>r)|0,f=r<<3,A=a[f+1112>>2],i=a[A+8>>2],f=f+1104|0,(0|i)!=(0|f)?(a[f+8>>2]=i,a[i+12>>2]=f):(n=Rt(r)&n,a[266]=n),f=A+8|0,a[A+4>>2]=3|b,r<<=3,i=r-b|0,a[A+r>>2]=i,b=A+b|0,a[b+4>>2]=1|i,l&&(t=l>>>3,A=1104+(t<<3)|0,r=a[271],t=1<>2]:(a[266]=t|n,t=A),a[t+12>>2]=r,a[A+8>>2]=r,a[r+12>>2]=A,a[r+8>>2]=t),a[271]=b,a[268]=i;break A}if(s=a[267],!s)break b;for(A=(s&0-s)-1|0,r=A>>>12&16,i=r,A>>>=r,r=A>>>5&8,i|=r,A>>>=r,r=A>>>2&4,i|=r,A>>>=r,r=A>>>1&2,i|=r,A>>>=r,r=A>>>1&1,r=a[1368+((i|r)+(A>>>r)<<2)>>2],i=(-8&a[r+4>>2])-b|0,A=r;f=a[A+16>>2],f||(f=a[A+20>>2],f);)t=(-8&a[f+4>>2])-b|0,A=t>>>0>>0,i=A?t:i,r=A?f:r,A=f;if(u=a[r+24>>2],t=a[r+12>>2],(0|r)!=(0|t)){A=a[r+8>>2],d[270],a[t+8>>2]=A,a[A+12>>2]=t;break e}if(A=r+20|0,f=a[A>>2],!f){if(f=a[r+16>>2],!f)break c;A=r+16|0}for(;c=A,t=f,A=f+20|0,f=a[A>>2],f||(A=t+16|0,f=a[t+16>>2],f););a[c>>2]=0;break e}if(b=-1,!(A>>>0>4294967231)&&(A=A+19|0,b=-16&A,l=a[267],l)){A>>>=8,c=0,A&&(c=31,b>>>0>16777215||(i=A+1048320>>>16&8,r=A<>>16&4,f=r<>>16&2,A=(f<>>15)-(r|A|i)|0,c=28+(A<<1|b>>>A+21&1)|0)),A=0-b|0,i=a[1368+(c<<2)>>2];l:{u:{if(i)for(r=b<<(31==(0|c)?0:25-(c>>>1)|0),f=0;;){if(n=(-8&a[i+4>>2])-b|0,!(n>>>0>=A>>>0||(t=i,A=n,A))){A=0,f=i;break u}if(n=a[i+20>>2],i=a[16+((r>>>29&4)+i|0)>>2],f=n?(0|n)==(0|i)?f:n:f,r<<=0!=(0|i),!i)break}else f=0;if(!(f|t)){if(r=2<>>12&16,f=i,r>>>=i,i=r>>>5&8,f|=i,r>>>=i,i=r>>>2&4,f|=i,r>>>=i,i=r>>>1&2,f|=i,r>>>=i,i=r>>>1&1,f=a[1368+((f|i)+(r>>>i)<<2)>>2]}if(!f)break l}for(;n=(-8&a[f+4>>2])-b|0,r=n>>>0>>0,A=r?n:A,t=r?f:t,i=a[f+16>>2],i||(i=a[f+20>>2]),f=i,f;);}if(!(!t|A>>>0>=a[268]-b>>>0)){if(c=a[t+24>>2],r=a[t+12>>2],(0|r)!=(0|t)){i=a[t+8>>2],d[270],a[r+8>>2]=i,a[i+12>>2]=r;break r}if(i=t+20|0,f=a[i>>2],!f){if(f=a[t+16>>2],!f)break o;i=t+16|0}for(;n=i,r=f,i=r+20|0,f=a[i>>2],f||(i=r+16|0,f=a[r+16>>2],f););a[n>>2]=0;break r}}}if(r=a[268],r>>>0>=b>>>0){A=a[271],i=r-b|0,i>>>0>=16?(f=A+b|0,a[f+4>>2]=1|i,a[268]=i,a[271]=f,a[A+r>>2]=i,a[A+4>>2]=3|b):(a[A+4>>2]=3|r,r=A+r|0,a[r+4>>2]=1|a[r+4>>2],a[271]=0,a[268]=0),f=A+8|0;break A}if(r=a[269],r>>>0>b>>>0){A=a[272],i=A+b|0,r=r-b|0,a[i+4>>2]=1|r,a[269]=r,a[272]=i,a[A+4>>2]=3|b,f=A+8|0;break A}if(f=0,a[384]?i=a[386]:(a[387]=-1,a[388]=-1,a[385]=65536,a[386]=65536,a[384]=e+12&-16^1431655768,a[389]=0,a[377]=0,i=65536),t=b+71|0,n=i+t|0,c=0-i|0,A=n&c,A>>>0<=b>>>0){a[256]=48;break A}if(i=a[376],i&&(f=a[374],l=f+A|0,!(l>>>0<=i>>>0&&l>>>0>f>>>0))){f=0,a[256]=48;break A}if(4&o[1508])break t;b:{l:{if(i=a[272],i)for(f=1512;;){if(l=a[f>>2],l+a[f+4>>2]>>>0>i>>>0&&l>>>0<=i>>>0)break l;if(f=a[f+8>>2],!f)break}if(r=P(0),-1==(0|r))break n;if(n=A,i=a[385],f=i+-1|0,f&r&&(n=(A-r|0)+(r+f&0-i)|0),n>>>0<=b>>>0|n>>>0>2147483646)break n;if(i=a[376],i&&(f=a[374],c=f+n|0,c>>>0<=f>>>0|c>>>0>i>>>0))break n;if(f=P(n),(0|r)!=(0|f))break b;break f}if(n=c&n-r,n>>>0>2147483646)break n;if(r=P(n),(0|r)==(a[f>>2]+a[f+4>>2]|0))break a;f=r}if(r=f,!(b+72>>>0<=n>>>0|n>>>0>2147483646|-1==(0|r))){if(i=a[386],i=i+(t-n|0)&0-i,i>>>0>2147483646)break f;if(-1!=(0|P(i))){n=i+n|0;break f}P(0-n|0);break n}if(-1!=(0|r))break f;break n}t=0;break e}r=0;break r}if(-1!=(0|r))break f}a[377]=4|a[377]}if(A>>>0>2147483646)break i;if(r=P(A),A=P(0),r>>>0>=A>>>0|-1==(0|r)|-1==(0|A))break i;if(n=A-r|0,n>>>0<=b+56>>>0)break i}A=a[374]+n|0,a[374]=A,A>>>0>d[375]&&(a[375]=A);f:{t:{n:{if(i=a[272],i){for(f=1512;;){if(A=a[f>>2],t=a[f+4>>2],(A+t|0)==(0|r))break n;if(f=a[f+8>>2],!f)break}break t}for(A=a[270],r>>>0>=A>>>0&&A||(a[270]=r),f=0,a[379]=n,a[378]=r,a[274]=-1,a[275]=a[384],a[381]=0;A=f+1104|0,a[f+1112>>2]=A,a[f+1116>>2]=A,f=f+8|0,256!=(0|f););A=r+8&15?-8-r&15:0,i=A+r|0,f=n+-56|0,A=f-A|0,a[i+4>>2]=1|A,a[273]=a[388],a[269]=A,a[272]=i,a[4+(r+f|0)>>2]=56;break f}if(!(8&o[f+12|0]|r>>>0<=i>>>0|A>>>0>i>>>0)){A=i+8&15?-8-i&15:0,r=A+i|0,c=a[269]+n|0,A=c-A|0,a[r+4>>2]=1|A,a[f+4>>2]=t+n,a[273]=a[388],a[269]=A,a[272]=r,a[4+(i+c|0)>>2]=56;break f}}t=a[270],r>>>0>>0&&(a[270]=r,t=r),A=r+n|0,f=1512;t:{n:{a:{o:{c:{b:{for(;;){if(a[f>>2]!=(0|A)){if(f=a[f+8>>2],f)continue;break b}break}if(!(8&o[f+12|0]))break c}for(f=1512;;){if(A=a[f>>2],A>>>0<=i>>>0&&(t=A+a[f+4>>2]|0,t>>>0>i>>>0))break o;f=a[f+8>>2]}}if(a[f>>2]=r,a[f+4>>2]=a[f+4>>2]+n,u=(r+8&15?-8-r&15:0)+r|0,a[u+4>>2]=3|b,r=A+(A+8&15?-8-A&15:0)|0,f=(r-u|0)-b|0,c=b+u|0,(0|r)==(0|i)){a[272]=c,A=a[269]+f|0,a[269]=A,a[c+4>>2]=1|A;break n}if((0|r)==a[271]){a[271]=c,A=a[268]+f|0,a[268]=A,a[c+4>>2]=1|A,a[A+c>>2]=A;break n}if(i=a[r+4>>2],1==(3&i)){s=-8&i;c:if(i>>>0<=255){if(A=a[r+12>>2],t=a[r+8>>2],i>>>=3,b=1104+(i<<3)|0,(0|A)==(0|t)){k=1064,v=a[266]&Rt(i),a[k>>2]=v;break c}a[A+8>>2]=t,a[t+12>>2]=A}else{if(l=a[r+24>>2],n=a[r+12>>2],(0|n)==(0|r))if(i=r+20|0,b=a[i>>2],b||(i=r+16|0,b=a[i>>2],b)){for(;A=i,n=b,i=n+20|0,b=a[i>>2],b||(i=n+16|0,b=a[n+16>>2],b););a[A>>2]=0}else n=0;else A=a[r+8>>2],a[n+8>>2]=A,a[A+12>>2]=n;if(l){A=a[r+28>>2],i=1368+(A<<2)|0;b:{if((0|r)==a[i>>2]){if(a[i>>2]=n,n)break b;k=1068,v=a[267]&Rt(A),a[k>>2]=v;break c}if(a[l+(a[l+16>>2]==(0|r)?16:20)>>2]=n,!n)break c}a[n+24>>2]=l,A=a[r+16>>2],A&&(a[n+16>>2]=A,a[A+24>>2]=n),A=a[r+20>>2],A&&(a[n+20>>2]=A,a[A+24>>2]=n)}}f=f+s|0,r=r+s|0}if(a[r+4>>2]=-2&a[r+4>>2],a[f+c>>2]=f,a[c+4>>2]=1|f,f>>>0<=255){r=f>>>3,A=1104+(r<<3)|0,i=a[266],r=1<>2]:(a[266]=r|i,i=A),a[i+12>>2]=c,a[A+8>>2]=c,a[c+12>>2]=A,a[c+8>>2]=i;break n}if(n=c,A=f>>>8,i=0,A&&(i=31,f>>>0>16777215||(i=A+1048320>>>16&8,r=A<>>16&4,t=r<>>16&2,A=(t<>>15)-(r|A|i)|0,i=28+(A<<1|f>>>A+21&1)|0)),a[n+28>>2]=i,a[c+16>>2]=0,a[c+20>>2]=0,A=1368+(i<<2)|0,r=a[267],t=1<>2]=c,a[267]=r|t,a[c+24>>2]=A,a[c+8>>2]=c,a[c+12>>2]=c;break n}for(i=f<<(31==(0|i)?0:25-(i>>>1)|0),r=a[A>>2];;){if(A=r,(-8&a[A+4>>2])==(0|f))break a;if(r=i>>>29,i<<=1,t=16+(A+(4&r)|0)|0,r=a[t>>2],!r)break}a[t>>2]=c,a[c+24>>2]=A,a[c+12>>2]=c,a[c+8>>2]=c;break n}for(A=r+8&15?-8-r&15:0,f=A+r|0,c=n+-56|0,l=c-A|0,a[f+4>>2]=1|l,a[4+(r+c|0)>>2]=56,A=(t+(t+-55&15?55-t&15:0)|0)-63|0,A=A>>>0>>0?i:A,a[A+4>>2]=35,a[273]=a[388],a[269]=l,a[272]=f,c=a[381],f=A+16|0,a[f>>2]=a[380],a[f+4>>2]=c,f=a[379],a[A+8>>2]=a[378],a[A+12>>2]=f,a[380]=A+8,a[379]=n,a[378]=r,a[381]=0,f=A+36|0;a[f>>2]=7,f=f+4|0,f>>>0>>0;);if((0|A)==(0|i))break f;if(a[A+4>>2]=-2&a[A+4>>2],t=A-i|0,a[A>>2]=t,a[i+4>>2]=1|t,t>>>0<=255){A=t>>>3,r=1104+(A<<3)|0,f=a[266],A=1<>2]:(a[266]=A|f,A=r),a[A+12>>2]=i,a[r+8>>2]=i,a[i+12>>2]=r,a[i+8>>2]=A;break f}if(a[i+16>>2]=0,a[i+20>>2]=0,c=i+28|0,A=t>>>8,f=0,A&&(f=31,t>>>0>16777215||(f=A+1048320>>>16&8,r=A<>>16&4,n=r<>>16&2,A=(n<>>15)-(r|A|f)|0,f=28+(A<<1|t>>>A+21&1)|0)),a[c>>2]=f,A=1368+(f<<2)|0,r=a[267],n=1<>2]=i,a[267]=r|n,a[i+24>>2]=A,a[i+8>>2]=i,a[i+12>>2]=i;break f}for(f=t<<(31==(0|f)?0:25-(f>>>1)|0),r=a[A>>2];;){if(A=r,(0|t)==(-8&a[A+4>>2]))break t;if(r=f>>>29,f<<=1,n=16+(A+(4&r)|0)|0,r=a[n>>2],!r)break}a[n>>2]=i,a[i+24>>2]=A,a[i+12>>2]=i,a[i+8>>2]=i;break f}r=a[A+8>>2],a[A+8>>2]=c,a[r+12>>2]=c,a[c+24>>2]=0,a[c+8>>2]=r,a[c+12>>2]=A}f=u+8|0;break A}r=a[A+8>>2],a[A+8>>2]=i,a[r+12>>2]=i,a[i+24>>2]=0,a[i+8>>2]=r,a[i+12>>2]=A}if(r=a[269],!(r>>>0<=b>>>0)){A=a[272],i=A+b|0,r=r-b|0,a[i+4>>2]=1|r,a[269]=r,a[272]=i,a[A+4>>2]=3|b,f=A+8|0;break A}}f=0,a[256]=48;break A}r:if(c){i=a[t+28>>2],f=1368+(i<<2)|0;i:{if((0|t)==a[f>>2]){if(a[f>>2]=r,r)break i;l=Rt(i)&l,a[267]=l;break r}if(a[c+(a[c+16>>2]==(0|t)?16:20)>>2]=r,!r)break r}a[r+24>>2]=c,i=a[t+16>>2],i&&(a[r+16>>2]=i,a[i+24>>2]=r),i=a[t+20>>2],i&&(a[r+20>>2]=i,a[i+24>>2]=r)}r:if(A>>>0<=15)A=A+b|0,a[t+4>>2]=3|A,A=A+t|0,a[A+4>>2]=1|a[A+4>>2];else if(n=t+b|0,a[n+4>>2]=1|A,a[t+4>>2]=3|b,a[A+n>>2]=A,A>>>0<=255)r=A>>>3,A=1104+(r<<3)|0,i=a[266],r=1<>2]:(a[266]=r|i,i=A),a[i+12>>2]=n,a[A+8>>2]=n,a[n+12>>2]=A,a[n+8>>2]=i;else if(c=n,r=A>>>8,f=0,r&&(f=31,A>>>0>16777215||(f=r+1048320>>>16&8,i=r<>>16&4,b=i<>>16&2,r=(b<>>15)-(i|r|f)|0,f=28+(r<<1|A>>>r+21&1)|0)),a[c+28>>2]=f,a[n+16>>2]=0,a[n+20>>2]=0,r=1368+(f<<2)|0,i=1<>>1)|0),b=a[r>>2];i:{for(;;){if(r=b,(-8&a[r+4>>2])==(0|A))break i;if(i=f>>>29,f<<=1,i=16+(r+(4&i)|0)|0,b=a[i>>2],!b)break}a[i>>2]=n,a[n+24>>2]=r,a[n+12>>2]=n,a[n+8>>2]=n;break r}A=a[r+8>>2],a[r+8>>2]=n,a[A+12>>2]=n,a[n+24>>2]=0,a[n+8>>2]=A,a[n+12>>2]=r}else a[r>>2]=n,a[267]=i|l,a[n+24>>2]=r,a[n+8>>2]=n,a[n+12>>2]=n;f=t+8|0;break A}e:if(u){A=a[r+28>>2],f=1368+(A<<2)|0;r:{if((0|r)==a[f>>2]){if(a[f>>2]=t,t)break r;k=1068,v=Rt(A)&s,a[k>>2]=v;break e}if(a[(a[u+16>>2]==(0|r)?16:20)+u>>2]=t,!t)break e}a[t+24>>2]=u,A=a[r+16>>2],A&&(a[t+16>>2]=A,a[A+24>>2]=t),A=a[r+20>>2],A&&(a[t+20>>2]=A,a[A+24>>2]=t)}i>>>0<=15?(A=i+b|0,a[r+4>>2]=3|A,A=A+r|0,a[A+4>>2]=1|a[A+4>>2]):(c=r+b|0,a[c+4>>2]=1|i,a[r+4>>2]=3|b,a[i+c>>2]=i,l&&(t=l>>>3,A=1104+(t<<3)|0,f=a[271],t=1<>2]:(a[266]=t|n,t=A),a[t+12>>2]=f,a[A+8>>2]=f,a[f+12>>2]=A,a[f+8>>2]=t),a[271]=c,a[268]=i),f=r+8|0}return Y=e+16|0,f}function L(A){var e=0,r=0,i=0,f=0,t=0,n=0,o=0,c=0,b=0;A:if(A){i=A+-8|0,r=a[A+-4>>2],A=-8&r,t=i+A|0;e:if(!(1&r)){if(!(3&r))break A;if(e=a[i>>2],i=i-e|0,f=a[270],i>>>0>>0)break A;if(A=A+e|0,(0|i)==a[271]){if(r=a[t+4>>2],3==(3&r))return a[t+4>>2]=-2&r,a[268]=A,a[A+i>>2]=A,void(a[i+4>>2]=1|A)}else{if(e>>>0<=255){if(r=a[i+12>>2],f=a[i+8>>2],e>>>=3,n=1104+(e<<3)|0,(0|r)==(0|f)){c=1064,b=a[266]&Rt(e),a[c>>2]=b;break e}a[r+8>>2]=f,a[f+12>>2]=r;break e}if(o=a[i+24>>2],r=a[i+12>>2],(0|i)==(0|r))if(e=i+20|0,f=a[e>>2],f||(e=i+16|0,f=a[e>>2],f)){for(;n=e,r=f,e=r+20|0,f=a[e>>2],f||(e=r+16|0,f=a[r+16>>2],f););a[n>>2]=0}else r=0;else e=a[i+8>>2],a[r+8>>2]=e,a[e+12>>2]=r;if(!o)break e;e=a[i+28>>2],f=1368+(e<<2)|0;r:{if((0|i)==a[f>>2]){if(a[f>>2]=r,r)break r;c=1068,b=a[267]&Rt(e),a[c>>2]=b;break e}if(a[o+(a[o+16>>2]==(0|i)?16:20)>>2]=r,!r)break e}if(a[r+24>>2]=o,e=a[i+16>>2],e&&(a[r+16>>2]=e,a[e+24>>2]=r),e=a[i+20>>2],!e)break e;a[r+20>>2]=e,a[e+24>>2]=r}}if(!(t>>>0<=i>>>0)&&(r=a[t+4>>2],1&r)){e:{if(!(2&r)){if(a[272]==(0|t)){if(a[272]=i,A=a[269]+A|0,a[269]=A,a[i+4>>2]=1|A,a[271]!=(0|i))break A;return a[268]=0,void(a[271]=0)}if(a[271]==(0|t))return a[271]=i,A=a[268]+A|0,a[268]=A,a[i+4>>2]=1|A,void(a[A+i>>2]=A);A=(-8&r)+A|0;r:if(r>>>0<=255){if(e=a[t+12>>2],f=a[t+8>>2],r>>>=3,n=1104+(r<<3)|0,(0|e)==(0|f)){c=1064,b=a[266]&Rt(r),a[c>>2]=b;break r}a[e+8>>2]=f,a[f+12>>2]=e}else{if(o=a[t+24>>2],r=a[t+12>>2],(0|r)==(0|t))if(e=t+20|0,f=a[e>>2],f||(e=t+16|0,f=a[e>>2],f)){for(;n=e,r=f,e=r+20|0,f=a[e>>2],f||(e=r+16|0,f=a[r+16>>2],f););a[n>>2]=0}else r=0;else e=a[t+8>>2],d[270],a[r+8>>2]=e,a[e+12>>2]=r;if(o){e=a[t+28>>2],f=1368+(e<<2)|0;i:{if(a[f>>2]==(0|t)){if(a[f>>2]=r,r)break i;c=1068,b=a[267]&Rt(e),a[c>>2]=b;break r}if(a[o+((0|t)==a[o+16>>2]?16:20)>>2]=r,!r)break r}a[r+24>>2]=o,e=a[t+16>>2],e&&(a[r+16>>2]=e,a[e+24>>2]=r),e=a[t+20>>2],e&&(a[r+20>>2]=e,a[e+24>>2]=r)}}if(a[A+i>>2]=A,a[i+4>>2]=1|A,a[271]!=(0|i))break e;return void(a[268]=A)}a[t+4>>2]=-2&r,a[A+i>>2]=A,a[i+4>>2]=1|A}if(A>>>0<=255)return r=A>>>3,A=1104+(r<<3)|0,e=a[266],r=1<>2]:(a[266]=r|e,e=A),a[e+12>>2]=i,a[A+8>>2]=i,a[i+12>>2]=A,void(a[i+8>>2]=e);a[i+16>>2]=0,a[i+20>>2]=0,t=i+28|0,r=A>>>8,e=0,r&&(e=31,A>>>0>16777215||(f=r+1048320>>>16&8,e=r<>>16&4,n=e<>>16&2,r=(n<>>15)-(e|r|f)|0,e=28+(r<<1|A>>>r+21&1)|0)),a[t>>2]=e,r=1368+(e<<2)|0,f=a[267],n=1<>>1)|0),r=a[r>>2];r:{for(;;){if(f=r,(-8&a[r+4>>2])==(0|A))break r;if(r=e>>>29,e<<=1,n=16+(f+(4&r)|0)|0,r=a[n>>2],!r)break}a[n>>2]=i,a[i+12>>2]=i,a[i+24>>2]=f,a[i+8>>2]=i;break e}A=a[f+8>>2],a[f+8>>2]=i,a[A+12>>2]=i,a[i+24>>2]=0,a[i+8>>2]=A,a[i+12>>2]=f}else a[r>>2]=i,a[267]=f|n,a[i+24>>2]=r,a[i+8>>2]=i,a[i+12>>2]=i;if(A=a[274]+-1|0,a[274]=A,!A){for(i=1520;A=a[i>>2],i=A+8|0,A;);a[274]=-1}}}}function q(A){var e;for(e=Y-16|0,Y=e,a[e+12>>2]=A,a[e+12>>2]||(a[e+12>>2]=1);A=K(a[e+12>>2]),a[e+8>>2]=A,!A&&(A=Y-16|0,a[A+12>>2]=1560,a[A+8>>2]=2,a[e+4>>2]=a[a[A+12>>2]>>2],a[e+4>>2]);)Qt[a[e+4>>2]]();return Y=e+16|0,a[e+8>>2]}function $(A){var e;e=Y-16|0,Y=e,a[e+12>>2]=A,L(a[e+12>>2]),Y=e+16|0}function AA(A,e){var r=0,i=0;r=o[0|A],i=o[0|e];A:if(!(!r|(0|i)!=(0|r)))for(A=A+1|0,e=e+1|0;;){if(i=o[0|e],r=o[0|A],!r)break A;if(A=A+1|0,e=e+1|0,(0|r)!=(0|i))break}return r-i|0}function eA(A){A|=0,a[12+(Y-16|0)>>2]=A}function rA(A){var e;return A|=0,e=Y-16|0,Y=e,a[e+12>>2]=A,A=a[e+12>>2],function(A){var e;e=Y-16|0,Y=e,a[e+12>>2]=A,a[12+(Y-16|0)>>2]=a[e+12>>2],Y=e+16|0}(A),Y=e+16|0,0|A}function iA(A){var e;return A|=0,e=Y-16|0,Y=e,a[e+12>>2]=A,A=a[e+12>>2],rA(A),Y=e+16|0,0|A}function fA(A,e,r){var i,t=0,n=0;return i=Y-16|0,Y=i,a[i+8>>2]=A,a[i+4>>2]=e,f[i+3|0]=r,1&f[i+3|0]?(A=1,e=i,a[i+8>>2]!=a[i+4>>2]&&(A=!AA(tA(a[i+8>>2]),tA(a[i+4>>2]))),f[e+15|0]=A):(t=i,n=1&function(A,e){var r=0;return r=Y-16|0,Y=r,a[r+4>>2]=A,a[r>>2]=e,A=a[a[r>>2]+4>>2],a[r+12>>2]=a[a[r+4>>2]+4>>2],a[r+8>>2]=A,A=1,a[r+12>>2]!=a[r+8>>2]&&(A=!AA(a[r+12>>2],a[r+8>>2])),Y=r+16|0,A}(a[i+8>>2],a[i+4>>2]),f[t+15|0]=n),Y=i+16|0,1&f[i+15|0]}function tA(A){var e;return e=Y-16|0,a[e+8>>2]=A,a[e+12>>2]=a[a[e+8>>2]+4>>2],a[e+12>>2]}function nA(A,e,r,i){var t;t=Y-16|0,a[t+12>>2]=A,a[t+8>>2]=e,a[t+4>>2]=r,a[t>>2]=i,a[a[t+8>>2]+16>>2]?a[a[t+8>>2]+16>>2]!=a[t+4>>2]?(A=a[t+8>>2],a[A+36>>2]=a[A+36>>2]+1,a[a[t+8>>2]+24>>2]=2,f[a[t+8>>2]+54|0]=1):2==a[a[t+8>>2]+24>>2]&&(a[a[t+8>>2]+24>>2]=a[t>>2]):(a[a[t+8>>2]+16>>2]=a[t+4>>2],a[a[t+8>>2]+24>>2]=a[t>>2],a[a[t+8>>2]+36>>2]=1)}function aA(A,e,r,i){var f,t;f=Y-32|0,Y=f,a[f+28>>2]=A,a[f+24>>2]=e,a[f+20>>2]=r,a[f+16>>2]=i,A=a[f+28>>2],a[f+12>>2]=0,a[f+20>>2]&&(a[f+12>>2]=a[A+4>>2]>>8,1&a[A+4>>2]&&(a[f+8>>2]=a[a[f+20>>2]>>2],a[f+12>>2]=a[a[f+8>>2]+a[f+12>>2]>>2])),e=a[A>>2],r=e,i=a[f+24>>2],t=a[f+20>>2]+a[f+12>>2]|0,A=2&a[A+4>>2]?a[f+16>>2]:2,Qt[a[a[e>>2]+28>>2]](r,i,t,A),Y=f+32|0}function oA(A,e,r,i,t){var n;n=Y-32|0,a[n+28>>2]=A,a[n+24>>2]=e,a[n+20>>2]=r,a[n+16>>2]=i,a[n+12>>2]=t,f[a[n+24>>2]+53|0]=1,a[n+16>>2]==a[a[n+24>>2]+4>>2]&&(f[a[n+24>>2]+52|0]=1,a[a[n+24>>2]+16>>2]?a[a[n+24>>2]+16>>2]!=a[n+20>>2]?(A=a[n+24>>2],a[A+36>>2]=a[A+36>>2]+1,f[a[n+24>>2]+54|0]=1):(2==a[a[n+24>>2]+24>>2]&&(a[a[n+24>>2]+24>>2]=a[n+12>>2]),1!=a[a[n+24>>2]+48>>2]|1!=a[a[n+24>>2]+24>>2]||(f[a[n+24>>2]+54|0]=1)):(a[a[n+24>>2]+16>>2]=a[n+20>>2],a[a[n+24>>2]+24>>2]=a[n+12>>2],a[a[n+24>>2]+36>>2]=1,1!=a[a[n+24>>2]+48>>2]|1!=a[a[n+24>>2]+24>>2]||(f[a[n+24>>2]+54|0]=1)))}function cA(A,e,r,i){var f;f=Y-16|0,a[f+12>>2]=A,a[f+8>>2]=e,a[f+4>>2]=r,a[f>>2]=i,a[f+4>>2]==a[a[f+8>>2]+4>>2]&&1!=a[a[f+8>>2]+28>>2]&&(a[a[f+8>>2]+28>>2]=a[f>>2])}function bA(A,e,r,i,t,n){var o;o=Y-32|0,Y=o,a[o+28>>2]=A,a[o+24>>2]=e,a[o+20>>2]=r,a[o+16>>2]=i,a[o+12>>2]=t,f[o+11|0]=n,A=a[o+28>>2],a[o+4>>2]=a[A+4>>2]>>8,1&a[A+4>>2]&&(a[o>>2]=a[a[o+16>>2]>>2],a[o+4>>2]=a[a[o>>2]+a[o+4>>2]>>2]),e=a[A>>2],r=e,i=a[o+24>>2],t=a[o+20>>2],n=a[o+16>>2]+a[o+4>>2]|0,A=2&a[A+4>>2]?a[o+12>>2]:2,Qt[a[a[e>>2]+20>>2]](r,i,t,n,A,1&f[o+11|0]),Y=o+32|0}function lA(A,e,r,i,t){var n;n=Y-32|0,Y=n,a[n+28>>2]=A,a[n+24>>2]=e,a[n+20>>2]=r,a[n+16>>2]=i,f[n+15|0]=t,A=a[n+28>>2],a[n+8>>2]=a[A+4>>2]>>8,1&a[A+4>>2]&&(a[n+4>>2]=a[a[n+20>>2]>>2],a[n+8>>2]=a[a[n+4>>2]+a[n+8>>2]>>2]),e=a[A>>2],r=e,i=a[n+24>>2],t=a[n+20>>2]+a[n+8>>2]|0,A=2&a[A+4>>2]?a[n+16>>2]:2,Qt[a[a[e>>2]+24>>2]](r,i,t,A,1&f[n+15|0]),Y=n+32|0}function uA(A,e){a[A>>2]=5748,a[A+4>>2]=a[e>>2]}function sA(A){return A|=0,0|A}function kA(A){p()}function vA(A,e){uA(A,e),a[A>>2]=5776}function dA(A){return a[391]=a[391]+1,0|Qt[a[740]](A,16)}function CA(A){A&&(a[392]=a[392]+1,Qt[a[741]](A))}function gA(A,e,r,i){var f,n,o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=0,k=0,v=_(0),d=0,g=_(0),m=0,R=_(0),Q=_(0),h=0,G=_(0),y=0;if(f=Y-32|0,Y=f,n=a[A>>2],a[A>>2]=n+1,s=i-r|0,1!=(0|s)){if(y=function(A,e,r,i){var f,t,n=0,o=0,c=0,b=0,l=0,u=0,s=_(0),k=0,v=0,d=0,g=_(0),m=_(0),R=_(0),Q=0,h=0,G=0,y=0,p=0,F=0,W=0,w=0;if(f=Y+-64|0,o=f+24|0,a[o>>2]=0,a[o+4>>2]=0,a[f+16>>2]=0,a[f+20>>2]=0,n=(0|r)<=(0|e),!n){for(u=r-e|0,o=24+(a[A+12>>2]+B(e,36)|0)|0;s=_(_(_(C[o+-4>>2]+C[o+-20>>2])*_(.5))+s),g=_(_(_(C[o+-8>>2]+C[o+-24>>2])*_(.5))+g),m=_(_(_(C[o>>2]+C[o+-16>>2])*_(.5))+m),o=o+36|0,u=u+-1|0,u;);C[f+24>>2]=m,C[f+20>>2]=s,C[f+16>>2]=g}if(t=r-e|0,R=_(_(1)/_(0|t)),C[f+24>>2]=R*m,C[f+20>>2]=R*s,C[f+16>>2]=R*g,o=e,!n)for(i<<=2,s=C[i+(f+16|0)>>2],u=B(e,36)+16|0,p=i+f|0,k=f+48|0,i=t;a[f+12>>2]=0,l=a[A+12>>2],n=l+u|0,b=n+8|0,C[f+8>>2]=_(C[b>>2]+C[n+-8>>2])*_(.5),C[f+4>>2]=_(C[n+4>>2]+C[n+-12>>2])*_(.5),c=n+-16|0,C[f>>2]=_(C[n>>2]+C[c>>2])*_(.5),C[p>>2]>s&&(F=a[c>>2],W=a[c+4>>2],y=B(o,36),l=l+y|0,Q=a[l+4>>2],a[c>>2]=a[l>>2],a[c+4>>2]=Q,w=a[n>>2],Q=a[n+4>>2],v=l+16|0,h=a[v+4>>2],a[n>>2]=a[v>>2],a[n+4>>2]=h,v=a[b>>2],h=a[b+4>>2],d=l+24|0,G=a[d+4>>2],a[b>>2]=a[d>>2],a[b+4>>2]=G,n=n+16|0,b=a[n>>2],a[n>>2]=a[l+32>>2],n=c+8|0,d=a[n>>2],G=a[n+4>>2],c=l+8|0,l=a[c+4>>2],a[n>>2]=a[c>>2],a[n+4>>2]=l,a[k>>2]=w,a[k+4>>2]=Q,n=k+8|0,a[n>>2]=v,a[n+4>>2]=h,c=f+40|0,n=c,a[n>>2]=d,a[n+4>>2]=G,n=a[A+12>>2]+y|0,a[n+32>>2]=b,a[f+32>>2]=F,a[f+36>>2]=W,b=a[f+36>>2],a[n>>2]=a[f+32>>2],a[n+4>>2]=b,b=a[c+4>>2],l=n+8|0,a[l>>2]=a[c>>2],a[l+4>>2]=b,c=a[k+4>>2],b=n+16|0,a[b>>2]=a[k>>2],a[b+4>>2]=c,c=f+56|0,b=a[c+4>>2],n=n+24|0,a[n>>2]=a[c>>2],a[n+4>>2]=b,o=o+1|0),u=u+36|0,i=i+-1|0,i;);return A=(0|t)/3|0,(0|o)<((-1^A)+r|0)&&(0|o)>(A+e|0)||(o=(t>>1)+e|0),o}(e,r,i,function(A,e,r){var i,f=0,t=_(0),n=_(0),o=_(0),c=_(0),b=0,l=_(0),u=_(0),s=_(0),k=_(0);i=r-e|0;A:{e:{if((0|r)<=(0|e))o=_(0|i);else{for(f=24+(a[A+12>>2]+B(e,36)|0)|0,b=i;t=_(t+_(_(C[f+-4>>2]+C[f+-20>>2])*_(.5))),u=_(u+_(_(C[f+-8>>2]+C[f+-24>>2])*_(.5))),n=_(n+_(_(C[f>>2]+C[f+-16>>2])*_(.5))),f=f+36|0,b=b+-1|0,b;);if(o=_(0|i),(0|r)>(0|e))break e}n=_(0),t=_(0);break A}for(c=_(_(1)/o),s=_(c*n),k=_(c*t),u=_(c*u),b=r-e|0,f=24+(a[A+12>>2]+B(e,36)|0)|0,t=_(0),n=_(0),c=_(0);l=n,n=_(_(_(C[f+-4>>2]+C[f+-20>>2])*_(.5))-k),n=_(l+_(n*n)),l=c,c=_(_(_(C[f+-8>>2]+C[f+-24>>2])*_(.5))-u),c=_(l+_(c*c)),l=t,t=_(_(_(C[f>>2]+C[f+-16>>2])*_(.5))-s),t=_(l+_(t*t)),f=f+36|0,b=b+-1|0,b;);}return o=_(_(1)/_(o+_(-1))),n=_(o*n),t=_(o*t),o=_(o*c),o>2]=-8388609,a[f+16>>2]=-8388609,a[f+20>>2]=-8388609,a[f+8>>2]=2139095039,a[f>>2]=2139095039,a[f+4>>2]=2139095039,(0|i)<=(0|r))o=_(3.4028234663852886e38),c=_(-3.4028234663852886e38),u=_(-3.4028234663852886e38),l=_(-3.4028234663852886e38),g=_(3.4028234663852886e38),v=_(3.4028234663852886e38);else for(h=f+16|0,k=16+(a[e+12>>2]+B(r,36)|0)|0,o=_(3.4028234663852886e38),c=_(-3.4028234663852886e38),u=_(-3.4028234663852886e38),l=_(-3.4028234663852886e38),g=_(3.4028234663852886e38),v=_(3.4028234663852886e38);m=k+-16|0,b=C[m>>2],v=v>b?b:v,C[f>>2]=v,d=g>C[k+-12>>2]?m:f,g=C[d+4>>2],a[f+4>>2]=a[d+4>>2],m=o>C[k+-8>>2]?m:f,o=C[m+8>>2],a[f+8>>2]=a[m+8>>2],b=C[k>>2],l=l>2]=l,m=u>2]?k:h,u=C[m+4>>2],a[f+20>>2]=a[m+4>>2],m=c>2]?k:h,c=C[m+8>>2],a[f+24>>2]=a[m+8>>2],k=k+36|0,s=s+-1|0,s;);m=n<<4,h=A+16|0,k=m+a[h>>2]|0,s=k,Q=C[A+56>>2],R=C[A+40>>2],b=C[A+24>>2],l=l=_(0)?~~l>>>0:0,t[s+6>>1]=d,s=k,l=v=_(0)?~~l>>>0:0,t[s>>1]=d,s=k+10|0,R=C[A- -64>>2],v=C[A+48>>2],l=C[A+32>>2],c=c=_(0)?~~c>>>0:0,t[s>>1]=d,s=k+8|0,Q=C[A+60>>2],b=C[A+44>>2],c=C[A+28>>2],u=u=_(0)?~~u>>>0:0,t[s>>1]=d,s=k,o=o=_(0)?~~o>>>0:0,t[s+4>>1]=d,o=g=_(0)?~~o>>>0:0,t[k+2>>1]=s,gA(A,e,r,y),gA(A,e,y,i),a[12+(m+a[h>>2]|0)>>2]=n-a[A>>2]}else g=C[A+48>>2],o=C[A+32>>2],e=a[e+12>>2]+B(r,36)|0,c=C[e+8>>2],c=c>2],c=_(_(_((g=_(0)?~~c>>>0:0,b=C[e>>2],u=C[e+4>>2],r=a[A+16>>2]+(n<<4)|0,t[r+4>>1]=s,i=r,l=C[A+44>>2],c=C[A+28>>2],u=u>2],u=_(_(_((l=_(0)?~~u>>>0:0,t[i+2>>1]=k,i=r,v=C[A+40>>2],u=C[A+24>>2],b=b>2],b=_(_(_((v=_(0)?~~b>>>0:0,t[i>>1]=A,b=C[e+24>>2],b=b=_(0)?~~o>>>0:0,o=C[e+16>>2],g=C[e+20>>2],t[r+10>>1]=s,A=r+8|0,g=g=_(0)?~~c>>>0:0,t[A>>1]=i,A=r,o=o=_(0)?~~o>>>0:0,t[A+6>>1]=i,a[r+12>>2]=a[e+32>>2];Y=f+32|0}function BA(A,e){var r,i,t=0,n=0,c=0,b=0,l=0,u=0,s=0,k=0;if(r=Y-16|0,Y=r,function(A,e){var r,i,f=0,t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=0,k=0,v=0;if(r=Y-32|0,a[r+24>>2]=-8388609,a[r+16>>2]=-8388609,a[r+20>>2]=-8388609,a[r+8>>2]=2139095039,a[r>>2]=2139095039,a[r+4>>2]=2139095039,i=a[e+4>>2],(0|i)<1)o=_(3.4028234663852886e38),c=_(-3.4028234663852886e38),b=_(-3.4028234663852886e38),t=_(-3.4028234663852886e38),l=_(3.4028234663852886e38),n=_(3.4028234663852886e38);else for(s=r+16|0,e=a[e+12>>2]+16|0,o=_(3.4028234663852886e38),c=_(-3.4028234663852886e38),b=_(-3.4028234663852886e38),t=_(-3.4028234663852886e38),l=_(3.4028234663852886e38),n=_(3.4028234663852886e38);f=e+-16|0,u=C[f>>2],n=n>u?u:n,C[r>>2]=n,k=l>C[e+-12>>2]?f:r,l=C[k+4>>2],a[r+4>>2]=a[k+4>>2],f=o>C[e+-8>>2]?f:r,o=C[f+8>>2],a[r+8>>2]=a[f+8>>2],u=C[e>>2],t=t>2]=t,f=b>2]?e:s,b=C[f+4>>2],a[r+20>>2]=a[f+4>>2],f=c>2]?e:s,c=C[f+8>>2],a[r+24>>2]=a[f+8>>2],e=e+36|0,v=v+1|0,(0|v)<(0|i););a[A+68>>2]=0,a[A+52>>2]=0,c=_(c+_(1)),C[A+48>>2]=c,b=_(b+_(1)),C[A+44>>2]=b,t=_(t+_(1)),C[A+40>>2]=t,a[A+36>>2]=0,o=_(o-_(1)),C[A+32>>2]=o,l=_(l-_(1)),C[A+28>>2]=l,n=_(n-_(1)),C[A+24>>2]=n,C[A- -64>>2]=_(65535)/_(c-o),C[A+60>>2]=_(65535)/_(b-l),C[A+56>>2]=_(65535)/_(t-n)}(A,e),a[A>>2]=0,t=a[A+8>>2],c=a[e+4>>2],i=c<<1,(0|t)<(0|i)){if(a[A+12>>2]<(0|i)){if(c?(k=dA(c<<5),n=a[A+8>>2]):n=t,(0|n)>=1)for(;u=a[A+16>>2]+b|0,s=a[u+4>>2],l=b+k|0,a[l>>2]=a[u>>2],a[l+4>>2]=s,u=u+8|0,s=a[u+4>>2],l=l+8|0,a[l>>2]=a[u>>2],a[l+4>>2]=s,b=b+16|0,n=n+-1|0,n;);n=a[A+16>>2],n&&(o[A+20|0]&&CA(n),a[A+16>>2]=0),a[A+16>>2]=k,a[A+12>>2]=i,f[A+20|0]=1}for(b=t<<4,n=t-(c<<1)|0;c=a[r+4>>2],t=a[A+16>>2]+b|0,a[t>>2]=a[r>>2],a[t+4>>2]=c,a[t+8>>2]=a[r+8>>2],a[t+12>>2]=0,b=b+16|0,t=n+1|0,c=t>>>0>=n>>>0,n=t,c;);c=a[e+4>>2]}a[A+8>>2]=i,gA(A,e,0,c),Y=r+16|0}function _A(A,e,r){var i,t=_(0),n=_(0),c=_(0),b=_(0),l=0,u=0,s=_(0),k=0,d=0,g=0,B=0,m=0,R=0,Q=_(0),h=0,G=_(0),y=0,p=0,F=0,W=0,w=0,D=0,E=0;if(Q=C[A- -64>>2],c=C[A+48>>2],t=C[A+32>>2],n=C[e+24>>2],n=n=_(0)?~~n>>>0:0,G=C[A+60>>2],s=C[A+44>>2],n=C[A+28>>2],b=C[e+20>>2],b=b=_(0)?~~b>>>0:0,b=C[e+8>>2],b=b=_(0)?~~t>>>0:0,t=C[e+4>>2],t=t=_(0)?~~t>>>0:0,s=C[A+56>>2],n=C[A+40>>2],t=C[A+24>>2],c=C[e+16>>2],c=c=_(0)?~~c>>>0:0,c=C[e>>2],c=c=_(0)?~~t>>>0:0,i=a[A>>2],(0|i)>=1)for(e=0;;){if(w=e<<4,l=w+a[A+16>>2]|0,v[l+4>>1]<=h>>>0&&!(v[l>>1]>F>>>0|v[l+6>>1]>>0|v[l+8>>1]

>>0|v[l+2>>1]>y>>>0)){if(g=a[l+12>>2],D=(0|g)>-1,l=v[l+10>>1],E=l>>>0>=d>>>0,!((0|g)<0|l>>>0>>0)){if(u=a[r+4>>2],(0|u)==a[r+8>>2]&&(k=u?u<<1:1,!((0|u)>=(0|k)))){k?(l=dA(k<<2),u=a[r+4>>2]):l=0,B=a[r+12>>2];A:{if((0|u)>=1)for(m=l,R=B;a[m>>2]=a[R>>2],m=m+4|0,R=R+4|0,u=u+-1|0,u;);else if(!B)break A;o[r+16|0]&&CA(B),a[r+12>>2]=0,u=a[r+4>>2]}a[r+12>>2]=l,f[r+16|0]=1,a[r+8>>2]=k}a[a[r+12>>2]+(u<<2)>>2]=g,a[r+4>>2]=a[r+4>>2]+1}}else D=a[l+12>>2]>-1,E=0;if(e=D||E?e+1|0:e-a[12+(a[A+16>>2]+w|0)>>2]|0,!((0|e)<(0|i)))break}}function mA(A,e,r,i,t){var n;n=Y-112|0,Y=n,!a[A>>2]|!a[r>>2]||(function(A,e,r){var i=_(0),f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),Y=_(0),V=_(0),N=_(0);g=C[e+52>>2],B=C[e+56>>2],R=C[r+52>>2],Q=C[r+56>>2],o=C[e+20>>2],c=C[e+36>>2],i=C[r+20>>2],f=C[r+36>>2],t=C[r+24>>2],b=C[e+24>>2],h=C[r+40>>2],l=C[e+40>>2],N=C[e+48>>2],G=C[r+48>>2],u=C[e+4>>2],y=C[r+4>>2],p=C[r+8>>2],s=C[e+8>>2],n=C[r+32>>2],k=C[e+32>>2],F=C[r>>2],v=C[e>>2],W=C[r+16>>2],d=C[e+16>>2],a[A+60>>2]=0,a[A+44>>2]=0,a[A+28>>2]=0,a[A+12>>2]=0,w=_(_(_(v*F)+_(d*W))+_(k*n)),C[A+16>>2]=w,D=_(_(_(s*p)+_(b*t))+_(l*h)),C[A+56>>2]=D,E=_(_(_(s*y)+_(b*i))+_(l*f)),C[A+52>>2]=E,Z=_(_(_(s*F)+_(b*W))+_(l*n)),C[A+48>>2]=Z,Y=_(_(_(u*p)+_(o*t))+_(c*h)),C[A+40>>2]=Y,V=_(_(_(u*y)+_(o*i))+_(c*f)),C[A+36>>2]=V,n=_(_(_(u*F)+_(o*W))+_(c*n)),C[A+32>>2]=n,t=_(_(_(v*p)+_(d*t))+_(k*h)),C[A+24>>2]=t,f=_(_(_(v*y)+_(d*i))+_(k*f)),C[A+20>>2]=f,C[A+64>>2]=_(m(w))+_(9.999999974752427e-7),i=_(-N),C[A+8>>2]=_(_(_(s*i)-_(b*g))-_(l*B))+_(_(_(s*G)+_(b*R))+_(l*Q)),C[A+4>>2]=_(_(_(u*i)-_(o*g))-_(c*B))+_(_(_(u*G)+_(o*R))+_(c*Q)),C[A>>2]=_(_(_(v*i)-_(d*g))-_(k*B))+_(_(_(v*G)+_(d*R))+_(k*Q)),C[A+104>>2]=_(m(D))+_(9.999999974752427e-7),C[A+100>>2]=_(m(E))+_(9.999999974752427e-7),C[A+96>>2]=_(m(Z))+_(9.999999974752427e-7),C[A+88>>2]=_(m(Y))+_(9.999999974752427e-7),C[A+84>>2]=_(m(V))+_(9.999999974752427e-7),C[A+80>>2]=_(m(n))+_(9.999999974752427e-7),C[A+72>>2]=_(m(t))+_(9.999999974752427e-7),C[A+68>>2]=_(m(f))+_(9.999999974752427e-7)}(n,e,i),function A(e,r,i,t,n,c,b){var l=0,u=0,s=0,k=0,d=0,g=0,B=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=0;u=Y+-64|0,Y=u,d=n<<4,l=d+a[e+16>>2]|0,k=v[l>>1],s=v[l+2>>1],g=v[l+4>>1],a[u+44>>2]=0,B=C[e- -64>>2],R=C[e+32>>2],C[u+40>>2]=_(_(g>>>0)/B)+R,Q=C[e+60>>2],h=C[e+28>>2],C[u+36>>2]=_(_(s>>>0)/Q)+h,G=C[e+56>>2],y=C[e+24>>2],C[u+32>>2]=_(_(k>>>0)/G)+y,k=v[l+6>>1],s=v[l+10>>1],l=v[l+8>>1],a[u+60>>2]=0,C[u+52>>2]=h+_(_(l>>>0)/Q),C[u+56>>2]=R+_(_(s>>>0)/B),C[u+48>>2]=y+_(_(k>>>0)/G),k=c<<4,l=k+a[r+16>>2]|0,s=v[l>>1],g=v[l+2>>1],p=v[l+4>>1],a[u+12>>2]=0,B=C[r- -64>>2],R=C[r+32>>2],C[u+8>>2]=_(_(p>>>0)/B)+R,Q=C[r+60>>2],h=C[r+28>>2],C[u+4>>2]=_(_(g>>>0)/Q)+h,G=C[r+56>>2],y=C[r+24>>2],C[u>>2]=_(_(s>>>0)/G)+y,s=v[l+6>>1],g=v[l+10>>1],l=v[l+8>>1],a[u+28>>2]=0,C[u+20>>2]=h+_(_(l>>>0)/Q),C[u+24>>2]=R+_(_(g>>>0)/B),C[u+16>>2]=y+_(_(s>>>0)/G);A:if(function(A,e,r,i){var f=_(0),t=_(0),n=_(0),a=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0);e:{if(a=C[e+16>>2],t=_(_(a+C[e>>2])*_(.5)),G=C[r+16>>2],o=C[e+20>>2],f=_(_(o+C[e+4>>2])*_(.5)),y=C[r+20>>2],c=C[e+24>>2],n=_(_(c+C[e+8>>2])*_(.5)),p=C[r+24>>2],b=C[A+16>>2],l=_(_(b+C[A>>2])*_(.5)),s=_(_(C[r>>2]+_(_(_(t*G)+_(f*y))+_(n*p)))-l),b=_(b-l),a=_(a-t),v=C[r+64>>2],o=_(o-f),d=C[r+68>>2],c=_(c-n),g=C[r+72>>2],!(_(m(s))>_(b+_(_(_(a*v)+_(o*d))+_(c*g)))||(F=C[r+32>>2],W=C[r+36>>2],w=C[r+40>>2],u=C[A+20>>2],k=_(_(u+C[A+4>>2])*_(.5)),l=_(_(C[r+4>>2]+_(_(_(t*F)+_(f*W))+_(n*w)))-k),u=_(u-k),k=C[r+80>>2],B=C[r+84>>2],R=C[r+88>>2],_(m(l))>_(u+_(_(_(a*k)+_(o*B))+_(c*R)))||(D=C[r+48>>2],E=C[r+52>>2],Z=C[r+56>>2],t=_(C[r+8>>2]+_(_(_(t*D)+_(f*E))+_(n*Z))),f=C[A+24>>2],n=_(_(f+C[A+8>>2])*_(.5)),t=_(t-n),f=_(f-n),n=C[r+96>>2],Q=C[r+100>>2],h=C[r+104>>2],_(m(t))>_(f+_(_(_(a*n)+_(o*Q))+_(c*h)))|_(m(_(_(_(s*G)+_(l*F))+_(t*D))))>_(a+_(_(_(b*v)+_(u*k))+_(f*n)))|_(m(_(_(_(s*y)+_(l*W))+_(t*E))))>_(o+_(_(_(b*d)+_(u*B))+_(f*Q))))))){if(A=_(m(_(_(_(s*p)+_(l*w))+_(t*Z))))>_(c+_(_(_(b*g)+_(u*R))+_(f*h))),r=1^A,!i|A)break e;if(!(!!(_(m(_(_(t*W)-_(l*E))))>_(_(_(_(u*Q)+_(f*B))+_(a*g))+_(c*v)))|_(m(_(_(t*F)-_(l*D))))>_(_(_(_(u*n)+_(f*k))+_(o*g))+_(c*d))|_(m(_(_(t*w)-_(l*Z))))>_(_(_(_(u*h)+_(f*R))+_(a*d))+_(o*v))|_(m(_(_(s*D)-_(t*G))))>_(_(_(_(b*n)+_(f*v))+_(o*R))+_(c*B))||_(m(_(_(s*E)-_(t*y))))>_(_(_(_(b*Q)+_(f*d))+_(a*R))+_(c*k))|_(m(_(_(s*Z)-_(t*p))))>_(_(_(_(b*h)+_(f*g))+_(a*B))+_(o*k))|_(m(_(_(l*G)-_(s*F))))>_(_(_(_(b*k)+_(u*v))+_(o*h))+_(c*Q))|_(m(_(_(l*y)-_(s*W))))>_(_(_(_(b*B)+_(u*d))+_(a*h))+_(c*n)))){if(r=0,_(m(_(_(l*p)-_(s*w))))>_(_(_(_(b*R)+_(u*g))+_(a*Q))+_(o*n)))break e;return 1}}r=0}return r}(u+32|0,u,t,b))if(l=a[12+(a[r+16>>2]+k|0)>>2],k=a[12+(a[e+16>>2]+d|0)>>2],(0|k)>=0){if((0|l)>=0){if(t=a[i+4>>2],(0|t)==a[i+8>>2]&&(d=t?t<<1:1,!((0|t)>=(0|d)))){d?(n=dA(d<<3),t=a[i+4>>2]):n=0,c=a[i+12>>2];e:{if((0|t)>=1)for(r=c,e=n,b=t;s=a[r+4>>2],a[e>>2]=a[r>>2],a[e+4>>2]=s,r=r+8|0,e=e+8|0,b=b+-1|0,b;);else if(!c)break e;o[i+16|0]&&(CA(c),t=a[i+4>>2]),a[i+12>>2]=0}a[i+12>>2]=n,f[i+16|0]=1,a[i+8>>2]=d}a[i+4>>2]=t+1,e=a[i+12>>2]+(t<<3)|0,a[e+4>>2]=l,a[e>>2]=k;break A}b=c+1|0,A(e,r,i,t,n,b,0),s=e,e=a[12+(a[r+16>>2]+(b<<4)|0)>>2],A(s,r,i,t,n,(0|e)>-1?c+2|0:b-e|0,0)}else b=n+1|0,(0|l)>=0?(A(e,r,i,t,b,c,0),s=e,e=a[12+(a[e+16>>2]+(b<<4)|0)>>2],A(s,r,i,t,(0|e)>-1?n+2|0:b-e|0,c,0)):(l=c+1|0,A(e,r,i,t,b,l,0),c=c+2|0,d=l<<4,k=a[12+(d+a[r+16>>2]|0)>>2],A(e,r,i,t,b,(0|k)>-1?c:l-k|0,0),n=n+2|0,k=b<<4,s=a[12+(k+a[e+16>>2]|0)>>2],A(e,r,i,t,(0|s)>-1?n:b-s|0,l,0),s=e,e=a[12+(k+a[e+16>>2]|0)>>2],n=(0|e)>-1?n:b-e|0,e=a[12+(d+a[r+16>>2]|0)>>2],A(s,r,i,t,n,(0|e)>-1?c:l-e|0,0));Y=u- -64|0}(A,r,t,n,0,0,1)),Y=n+112|0}function RA(A,e,r,i,f,t){var n=_(0),o=_(0),b=_(0),l=_(0),u=0,k=0,v=0,d=0,g=0,B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0);Qt[a[a[A>>2]+8>>2]](A,e,f,t),n=C[r+8>>2],o=C[r+4>>2],l=C[f+8>>2],e=a[f+8>>2],B=C[f+4>>2],u=a[f+4>>2],m=C[f>>2],k=a[f>>2],R=C[t+8>>2],v=a[t+8>>2],Q=C[t+4>>2],d=a[t+4>>2],h=C[t>>2],g=a[t>>2],b=C[r>>2],b>_(0)?(s(_(b+h)),g=c(0)):(s(_(b+m)),k=c(0)),o>_(0)?(s(_(o+Q)),d=c(0)):(s(_(o+B)),u=c(0)),n>_(0)?(s(_(n+R)),v=c(0)):(s(_(n+l)),e=c(0)),n=C[i+8>>2],o=C[i>>2],b=C[i+4>>2],l=_(Qt[a[a[A>>2]+16>>2]](A)),a[f+12>>2]=0,a[f+8>>2]=e,a[f+4>>2]=u,a[f>>2]=k,a[t+12>>2]=0,a[t+8>>2]=v,a[t+4>>2]=d,a[t>>2]=g,n=_(l*_(y(_(_(_(o*o)+_(b*b))+_(n*n))))),C[f>>2]=C[f>>2]-n,C[f+4>>2]=C[f+4>>2]-n,C[f+8>>2]=C[f+8>>2]-n,C[t>>2]=n+C[t>>2],C[t+4>>2]=n+C[t+4>>2],C[t+8>>2]=n+C[t+8>>2]}function QA(A,e,r){var i,f;return A|=0,e|=0,r|=0,i=0|Qt[a[a[r>>2]+40>>2]](r,A),f=0|Qt[a[a[r>>2]+28>>2]](r,i),a[e>>2]=f,f&&Qt[a[a[r>>2]+48>>2]](r,i),A=a[A+4>>2],a[e+8>>2]=0,a[e+4>>2]=A,5872}function hA(A,e,r){A|=0,e|=0,r|=0;var i,f=_(0),t=0,n=_(0),o=_(0),c=0,b=_(0),l=0,u=_(0),s=_(0),k=0,v=_(0),d=_(0),g=0;i=Y-48|0,Y=i;A:{e:if(t=a[e+4>>2],!(t>>>0>13)){switch(t-1|0){case 7:a[A>>2]=0,a[A+4>>2]=0,A=A+8|0,a[A>>2]=0,a[A+4>>2]=0;break A;default:a[A+12>>2]=0,f=C[e+32>>2],C[A>>2]=C[r>>2]>=_(0)?f:_(-f),f=C[e+40>>2],C[A+8>>2]=C[r+8>>2]>=_(0)?f:_(-f),f=C[e+36>>2],C[A+4>>2]=C[r+4>>2]>=_(0)?f:_(-f);break A;case 0:a[A+12>>2]=0,f=C[r>>2],o=C[r+4>>2],n=C[r+8>>2],b=_(_(_(f*C[e+76>>2])+_(o*C[e+80>>2]))+_(n*C[e+84>>2])),u=_(_(_(f*C[e+92>>2])+_(o*C[e+96>>2]))+_(n*C[e+100>>2])),r=e+60|0,f=_(_(_(f*C[r>>2])+_(o*C[e- -64>>2]))+_(n*C[e+68>>2])),e=((f>2]=a[e+8>>2],r=a[e+4>>2],a[A>>2]=a[e>>2],a[A+4>>2]=r;break A;case 12:c=e+40|0,l=a[c+4>>2],t=i+40|0,a[t>>2]=a[c>>2],a[t+4>>2]=l,t=a[e+36>>2],a[i+32>>2]=a[e+32>>2],a[i+36>>2]=t,t=0,a[i+28>>2]=0,a[i+16>>2]=a[r>>2],o=C[r+4>>2],a[i+20>>2]=a[r+4>>2],f=C[r+8>>2],a[i+24>>2]=a[r+8>>2],r=1,c=a[e+56>>2],e=c+-1|0,l=2,e>>>0>1||(e-1?(r=0,t=1,l=2):(f=o,r=0,t=2,l=1)),e=l,o=C[(i+32|0)+(c<<2)>>2],c=r<<2,b=C[(c|i+32)>>2],u=C[(c|i+16)>>2],s=_(y(_(_(u*u)+_(f*f)))),s==_(0)?(C[(r<<2|i)>>2]=b,r=t<<2,C[r+i>>2]=C[r+(i+16|0)>>2]<_(0)?_(-o):o):(n=_(b/s),C[(r<<2|i)>>2]=u*n,r=t<<2,C[r+i>>2]=C[r+(i+16|0)>>2]<_(0)?_(-o):o,n=_(f*n)),C[(e<<2)+i>>2]=n,a[A+12>>2]=0,a[A>>2]=a[i>>2],e=a[i+8>>2],a[A+4>>2]=a[i+4>>2],a[A+8>>2]=e;break A;case 9:c=e,g=a[e+56>>2],e=g<<2,s=C[32+(c+e|0)>>2],f=C[r>>2],o=C[r+4>>2],n=C[r+8>>2],b=_(_(_(f*f)+_(o*o))+_(n*n)),b<_(1.4210854715202004e-14)?(b=_(0),n=_(1)):(u=n,n=_(_(1)/_(y(b))),u=_(u*n),b=_(o*n),n=_(f*n)),a[i+40>>2]=0,a[i+44>>2]=0,a[i+32>>2]=0,a[i+36>>2]=0,C[e+(i+32|0)>>2]=s,f=_(-0xde0b6b000000000),e=0,r=0,t=0,c=a[i+32>>2],l=a[i+36>>2],k=a[i+40>>2],o=_(_(_(n*C[i+32>>2])+_(b*C[i+36>>2]))+_(u*C[i+40>>2])),o>_(-0xde0b6b000000000)&&(t=k,r=l,f=o,e=c),a[i+40>>2]=0,a[i+44>>2]=0,a[i+32>>2]=0,a[i+36>>2]=0,C[(i+32|0)+(g<<2)>>2]=-s,c=a[i+32>>2],l=a[i+36>>2],k=a[i+40>>2],_(_(_(n*C[i+32>>2])+_(b*C[i+36>>2]))+_(u*C[i+40>>2]))>f&&(t=k,r=l,e=c),a[A+12>>2]=0,a[A+8>>2]=t,a[A+4>>2]=r,a[A>>2]=e;break A;case 4:if(o=C[e+24>>2],n=C[e+20>>2],b=C[e+16>>2],c=a[e+96>>2],k=a[e+100>>2],(0|k)<1)t=-1;else for(u=_(C[r+8>>2]*o),s=_(C[r+4>>2]*n),d=_(C[r>>2]*b),r=0,t=-1,f=_(-3.4028234663852886e38),e=c;v=_(_(_(d*C[e>>2])+_(s*C[e+4>>2]))+_(u*C[e+8>>2])),l=v>f,f=l?v:f,t=l?r:t,e=e+16|0,r=r+1|0,(0|k)!=(0|r););a[A+12>>2]=0,e=c+(t<<4)|0,C[A+8>>2]=o*C[e+8>>2],C[A+4>>2]=n*C[e+4>>2],C[A>>2]=b*C[e>>2];break A;case 1:case 2:case 5:case 6:case 8:case 10:case 11:break e;case 3:}if(o=C[e+24>>2],n=C[e+20>>2],b=C[e+16>>2],c=a[e+108>>2],k=a[e+100>>2],(0|k)<1)t=-1;else for(u=_(C[r+8>>2]*o),s=_(C[r+4>>2]*n),d=_(C[r>>2]*b),r=0,t=-1,f=_(-3.4028234663852886e38),e=c;v=_(_(_(d*C[e>>2])+_(s*C[e+4>>2]))+_(u*C[e+8>>2])),l=v>f,f=l?v:f,t=l?r:t,e=e+16|0,r=r+1|0,(0|k)!=(0|r););a[A+12>>2]=0,e=c+(t<<4)|0,C[A+8>>2]=o*C[e+8>>2],C[A+4>>2]=n*C[e+4>>2],C[A>>2]=b*C[e>>2];break A}Qt[a[a[e>>2]+68>>2]](A,e,r)}Y=i+48|0}function GA(A){var e=0;A:if(e=a[A+4>>2],!(e>>>0>13)){switch(e-2|0){case 6:return _(C[A+32>>2]*C[A+16>>2]);case 0:case 1:case 4:case 5:case 7:case 10:break A}return C[A+48>>2]}return _(Qt[a[a[A>>2]+48>>2]](A))}function yA(A){return 12}function pA(A){A|=0,CA(A)}function FA(A,e){var r;A|=0,e|=0,a[A>>2]=0,a[A+4>>2]=0,r=A+8|0,a[r>>2]=0,a[r+4>>2]=0,a[(a[e+56>>2]<<2)+A>>2]=1065353216}function WA(A,e){e=_(e)}function wA(A){return 60}function DA(A){var e;a[A+12>>2]=-1,a[A+4>>2]=35,a[A+8>>2]=0,a[A>>2]=5928,a[A+48>>2]=1025758986,e=A+24|0,a[e>>2]=1065353216,a[e+4>>2]=0,a[A+16>>2]=1065353216,a[A+20>>2]=1065353216,a[A>>2]=6924}function EA(A,e){A|=0,e|=0;var r=_(0),i=_(0),f=_(0);r=C[e>>2],i=C[e+4>>2],f=C[e+8>>2],a[A+28>>2]=0,C[A+24>>2]=m(f),C[A+20>>2]=m(i),C[A+16>>2]=m(r)}function ZA(A){A|=0;var e=0,r=0,i=0,t=0,n=0,c=0;if(a[A>>2]=7060,e=a[A+56>>2],e&&(o[A+60|0]&&CA(e),a[A+56>>2]=0),a[A+56>>2]=0,a[A+48>>2]=0,a[A+52>>2]=0,f[A+60|0]=1,r=a[A+28>>2],(0|r)>=1)for(i=8;e=a[A+36>>2]+i|0,c=e+-4|0,t=e+4|0,n=a[t>>2],n&&(o[e+8|0]&&CA(n),a[t>>2]=0),a[c>>2]=0,a[t>>2]=0,a[e>>2]=0,f[e+8|0]=1,i=i+36|0,r=r+-1|0,r;);return e=a[A+36>>2],e&&(o[A+40|0]&&CA(e),a[A+36>>2]=0),a[A+36>>2]=0,a[A+28>>2]=0,a[A+32>>2]=0,f[A+40|0]=1,e=a[A+16>>2],e&&(o[A+20|0]&&CA(e),a[A+16>>2]=0),a[A+16>>2]=0,a[A+8>>2]=0,a[A+12>>2]=0,f[A+20|0]=1,0|A}function YA(A){var e,r,i=_(0),f=_(0),t=_(0),n=0,o=0,c=0,b=0;for(e=a[A+28>>2],r=(0|e)<1;;){A:if(!(o>>>0>7)){switch(o-1|0){default:i=_(C[A+88>>2]+C[A+72>>2]),f=_(C[A+84>>2]+C[A+68>>2]),t=_(C[A+80>>2]+C[A+64>>2]);break A;case 0:i=_(C[A+72>>2]-C[A+88>>2]),f=_(C[A+84>>2]+C[A+68>>2]),t=_(C[A+80>>2]+C[A+64>>2]);break A;case 1:i=_(C[A+88>>2]+C[A+72>>2]),f=_(C[A+68>>2]-C[A+84>>2]),t=_(C[A+80>>2]+C[A+64>>2]);break A;case 2:i=_(C[A+72>>2]-C[A+88>>2]),f=_(C[A+68>>2]-C[A+84>>2]),t=_(C[A+80>>2]+C[A+64>>2]);break A;case 3:i=_(C[A+88>>2]+C[A+72>>2]),f=_(C[A+84>>2]+C[A+68>>2]),t=_(C[A+64>>2]-C[A+80>>2]);break A;case 4:i=_(C[A+72>>2]-C[A+88>>2]),f=_(C[A+84>>2]+C[A+68>>2]),t=_(C[A+64>>2]-C[A+80>>2]);break A;case 5:i=_(C[A+88>>2]+C[A+72>>2]),f=_(C[A+68>>2]-C[A+84>>2]),t=_(C[A+64>>2]-C[A+80>>2]);break A;case 6:}i=_(C[A+72>>2]-C[A+88>>2]),f=_(C[A+68>>2]-C[A+84>>2]),t=_(C[A+64>>2]-C[A+80>>2])}A:{if(!r)for(n=a[A+36>>2]+20|0,b=0,c=0;;){if(_(C[n+12>>2]+_(_(_(t*C[n>>2])+_(f*C[n+4>>2]))+_(i*C[n+8>>2])))>_(0))break A;if(n=n+36|0,c=c+1|0,!((0|c)<(0|e)))break}if(b=1,o=o+1|0,8!=(0|o))continue}break}return b}function VA(A){var e,r=0,i=_(0),n=0,b=0,l=_(0),u=0,k=_(0),g=0,R=_(0),Q=0,h=0,G=_(0),p=_(0),F=0,W=0,w=0,D=_(0),E=_(0),Z=_(0),V=_(0),N=0,I=0,J=0,x=0,U=0,M=0,S=_(0),X=_(0),T=_(0),j=_(0),O=_(0),H=_(0),z=_(0),P=_(0),K=_(0),L=_(0);if(e=Y-96|0,Y=e,a[A+64>>2]=0,a[A+68>>2]=0,f[e+52|0]=1,a[e+48>>2]=0,f[e+72|0]=1,r=e+40|0,a[r>>2]=0,a[r+4>>2]=0,a[e+68>>2]=0,f[e+92|0]=1,r=e+60|0,a[r>>2]=0,a[r+4>>2]=0,a[e+88>>2]=0,r=e+80|0,a[r>>2]=0,a[r+4>>2]=0,r=A+72|0,a[r>>2]=0,a[r+4>>2]=0,a[e+28>>2]=0,f[e+32|0]=1,a[e+20>>2]=0,a[e+24>>2]=0,F=a[A+28>>2],!((0|F)<1)){for(;;){if(n=a[A+36>>2],N=B(w,36),I=a[4+(n+N|0)>>2],(0|I)>=1){for(U=0;;){r=a[12+(n+N|0)>>2],g=a[r+(U<<2)>>2],t[e+8>>1]=g,U=U+1|0,F=(0|I)==(0|U),b=a[r+((F?0:U)<<2)>>2],t[e+10>>1]=b,M=0,r=b<<16>>16,u=g<<16>>16,(0|r)>(0|u)&&(t[e+10>>1]=g,t[e+8>>1]=b,u=b,r=g),J=r<<16,h=u<<16>>16,b=J+h&a[e+64>>2]+-1;A:if(!(b>>>0>=d[e+20>>2])&&(n=a[a[e+28>>2]+(b<<2)>>2],-1!=(0|n))){for(Q=a[e+48>>2],g=a[e+88>>2];;){if(x=n<<2,b=x+g|0,v[b+2>>1]!=(65535&r)||v[b>>1]!=(65535&u)){if(n=a[Q+x>>2],-1!=(0|n))continue;break A}break}M=x+a[e+68>>2]|0}r=a[A+16>>2],b=r+(J>>16<<4)|0,r=r+(h<<4)|0,i=_(C[b+8>>2]-C[r+8>>2]),R=i,l=_(C[b>>2]-C[r>>2]),k=_(C[b+4>>2]-C[r+4>>2]),i=_(_(1)/_(y(_(_(_(l*l)+_(k*k))+_(i*i))))),R=_(R*i),G=_(k*i),p=_(l*i),u=a[A+48>>2];A:{if((0|u)>=1)for(n=a[A+56>>2],W=0;;){if(l=C[n+8>>2],i=C[n>>2],k=C[n+4>>2],(+_(m(_(l-R)))>1e-6^1?!(+_(m(_(i-p)))>1e-6|+_(m(_(k-G)))>1e-6):0)|(+_(m(_(R+l)))>1e-6^1?!(+_(m(_(p+i)))>1e-6|+_(m(_(G+k)))>1e-6):0))break A;if(n=n+16|0,W=W+1|0,!((0|W)<(0|u)))break}if(a[A+52>>2]==(0|u)&&(Q=u?u<<1:1,!((0|u)>=(0|Q)))){if(Q?(h=dA(Q<<4),u=a[A+48>>2]):h=0,(0|u)>=1)for(n=0;b=a[A+56>>2]+n|0,r=a[b+4>>2],g=n+h|0,a[g>>2]=a[b>>2],a[g+4>>2]=r,b=b+8|0,r=a[b+4>>2],g=g+8|0,a[g>>2]=a[b>>2],a[g+4>>2]=r,n=n+16|0,u=u+-1|0,u;);r=a[A+56>>2],r&&(o[A+60|0]&&CA(r),a[A+56>>2]=0),a[A+56>>2]=h,f[A+60|0]=1,a[A+52>>2]=Q,u=a[A+48>>2]}r=a[A+56>>2]+(u<<4)|0,a[r+12>>2]=0,C[r+8>>2]=R,C[r+4>>2]=G,C[r>>2]=p,a[A+48>>2]=a[A+48>>2]+1}if(M?t[M+2>>1]=w:(t[e>>1]=w,t[e+2>>1]=65535,NA(e+16|0,e+8|0,e)),F)break;n=a[A+36>>2]}F=a[A+28>>2]}if(w=w+1|0,!((0|w)<(0|F)))break}if(x=0,!((0|F)<1))for(x=(0|F)>0,N=a[A+16>>2],g=a[A+36>>2],w=0;;){if(r=g+B(w,36)|0,I=a[r+4>>2],(0|I)>=3)for(J=a[r+12>>2],n=J+4|0,h=N+(a[J>>2]<<4)|0,b=h+8|0,r=h+4|0,D=C[A+72>>2],E=C[A+68>>2],Z=C[A+64>>2],W=2;Q=N+(a[n>>2]<<4)|0,j=C[Q+8>>2],u=N+(a[J+((0|W)%(0|I)<<2)>>2]<<4)|0,O=C[u+8>>2],S=C[h>>2],H=C[Q>>2],z=_(S-H),X=C[r>>2],P=C[u+4>>2],R=_(X-P),G=C[Q+4>>2],i=_(X-G),p=C[u>>2],l=_(S-p),K=_(_(z*R)-_(i*l)),T=C[b>>2],k=_(T-O),L=_(i*k),i=_(T-j),R=_(L-_(i*R)),i=_(_(i*l)-_(z*k)),i=_(_(y(_(_(K*K)+_(_(R*R)+_(i*i)))))*_(.5)),D=_(D+_(_(_(_(T+j)+O)*_(.3333333432674408))*i)),C[A+72>>2]=D,E=_(E+_(_(_(P+_(X+G))*_(.3333333432674408))*i)),C[A+68>>2]=E,Z=_(Z+_(_(_(p+_(S+H))*_(.3333333432674408))*i)),C[A+64>>2]=Z,V=_(V+i),n=n+4|0,W=W+1|0,(0|I)!=(0|W););if(w=w+1|0,(0|w)==(0|F))break}}if(a[A+96>>2]=2139095039,i=_(_(1)/V),R=_(i*C[A+64>>2]),C[A+64>>2]=R,G=_(i*C[A+68>>2]),C[A+68>>2]=G,p=_(i*C[A+72>>2]),C[A+72>>2]=p,l=_(3.4028234663852886e38),k=_(3.4028234663852886e38),x)for(n=a[A+36>>2]+20|0;i=_(m(_(C[n+12>>2]+_(_(_(R*C[n>>2])+_(G*C[n+4>>2]))+_(p*C[n+8>>2]))))),i>2]=i,k=i),n=n+36|0,F=F+-1|0,F;);if(r=a[A+8>>2],(0|r)<1)R=_(-3.4028234663852886e38),D=_(3.4028234663852886e38),E=_(-3.4028234663852886e38),Z=_(-3.4028234663852886e38),V=_(3.4028234663852886e38);else for(n=a[A+16>>2],Z=_(-3.4028234663852886e38),W=0,V=_(3.4028234663852886e38),E=_(-3.4028234663852886e38),R=_(-3.4028234663852886e38),D=_(3.4028234663852886e38);i=C[n+8>>2],Z=i>Z?i:Z,D=i>2],E=i>E?i:E,l=i>2],R=i>R?i:R,V=i>2]=0,G=_(Z-D),C[A+124>>2]=G,p=_(E-l),C[A+120>>2]=p,i=_(R-V),C[A+116>>2]=i,a[A+112>>2]=0,C[A+108>>2]=D+Z,C[A+104>>2]=l+E,C[A+100>>2]=R+V,b=i>2],l=_(k/_(1.7320507764816284)),C[A+88>>2]=l,C[A+80>>2]=l,C[A+84>>2]=l,r=r+(A+80|0)|0,k=_(i*_(.5)),C[r>>2]=k,i=_(_(k-l)*_(.0009765625)),n=1024;A:{e:{for(;;){if(YA(A))break e;if(k=_(k-i),C[r>>2]=k,n=n+-1|0,!n)break}C[A+84>>2]=l,C[A+88>>2]=l,C[A+80>>2]=l;break A}if(r=A+80|0,b=1<>2],g=r+(b<<2)|0,r=g,b=a[r>>2],k=_(_(C[A+96>>2]-l)*_(.0009765625)),C[r>>2]=k+C[r>>2],l=_(k+C[Q>>2]),C[Q>>2]=l,YA(A)){for(u=1024;;){if(i=l,u=u+-1|0,!u)break A;if(b=a[g>>2],C[g>>2]=k+C[g>>2],l=_(k+C[Q>>2]),C[Q>>2]=l,!YA(A))break}s(i),h=c(0)}a[g>>2]=b,a[Q>>2]=h}A=a[e+88>>2],A&&(o[e+92|0]&&CA(A),a[e+88>>2]=0),a[e+88>>2]=0,f[e+92|0]=1,a[e+80>>2]=0,a[e+84>>2]=0,A=a[e+68>>2],A&&(o[e+72|0]&&CA(A),a[e+68>>2]=0),a[e+68>>2]=0,f[e+72|0]=1,a[e+60>>2]=0,a[e+64>>2]=0,A=a[e+48>>2],A&&(o[e+52|0]&&CA(A),a[e+48>>2]=0),a[e+48>>2]=0,f[e+52|0]=1,a[e+40>>2]=0,a[e+44>>2]=0,A=a[e+28>>2],A&&(o[e+32|0]&&CA(A),a[e+28>>2]=0),Y=e+96|0}function NA(A,e,r){var i=0,n=0,c=0,b=0,l=0,u=0,s=0,k=0,C=0;A:{if(c=t[e>>1],n=v[e+2>>1],s=a[A+48>>2],C=c+(n<<16)&s+-1,!(C>>>0>=d[A+4>>2])&&(i=a[a[A+12>>2]+(C<<2)>>2],-1!=(0|i)))for(l=a[A+72>>2],c&=65535;;){if(u=i<<2,b=u+l|0,v[b+2>>1]==(0|n)&&v[b>>1]==(0|c))break A;if(i=a[u+a[A+32>>2]>>2],-1==(0|i))break}if(u=a[A+44>>2],i=u,(0|i)==(0|s)&&(i=s,l=i?i<<1:1,!((0|i)>=(0|l)))){if(l?(c=dA(l<<2),i=a[A+44>>2]):(c=0,i=s),n=i,(0|n)>=1)for(i=0;b=i+c|0,k=a[A+52>>2]+i|0,k=v[k>>1]|v[k+2>>1]<<16,t[b>>1]=k,t[b+2>>1]=k>>>16,i=i+4|0,n=n+-1|0,n;);i=a[A+52>>2],i&&(o[A+56|0]&&CA(i),a[A+52>>2]=0),a[A+52>>2]=c,a[A+48>>2]=l,f[A+56|0]=1,i=a[A+44>>2]}if(i=a[A+52>>2]+(i<<2)|0,r=v[r>>1]|v[r+2>>1]<<16,t[i>>1]=r,t[i+2>>1]=r>>>16,a[A+44>>2]=a[A+44>>2]+1,n=a[A- -64>>2],(0|n)==a[A+68>>2]&&(r=n?n<<1:1,!((0|n)>=(0|r)))){if(r?(c=dA(r<<2),n=a[A+64>>2]):c=0,(0|n)>=1)for(i=0;l=i+c|0,b=a[A+72>>2]+i|0,b=v[b>>1]|v[b+2>>1]<<16,t[l>>1]=b,t[l+2>>1]=b>>>16,i=i+4|0,n=n+-1|0,n;);i=a[A+72>>2],i&&(o[A+76|0]&&CA(i),a[A+72>>2]=0),a[A+72>>2]=c,a[A+68>>2]=r,f[A+76|0]=1,n=a[A+64>>2]}return r=a[A+72>>2]+(n<<2)|0,i=v[e>>1]|v[e+2>>1]<<16,t[r>>1]=i,t[r+2>>1]=i>>>16,a[A+64>>2]=a[A+64>>2]+1,(0|s)>2]&&(function(A){var e=0,r=0,i=0,n=0,c=0,b=0,l=0,u=0,s=0;if(l=a[A+4>>2],i=a[A+48>>2],!((0|l)>=(0|i))){if(a[A+8>>2]>=(0|i))n=a[A+12>>2];else{i?(n=dA(i<<2),r=a[A+4>>2]):r=l,b=a[A+12>>2];e:{if((0|r)>=1)for(c=n,e=b;a[c>>2]=a[e>>2],c=c+4|0,e=e+4|0,r=r+-1|0,r;);else if(!b)break e;o[A+16|0]&&CA(b)}a[A+12>>2]=n,f[A+16|0]=1,a[A+8>>2]=i}if(e=l<<2,u=i<<2,X(e+n|0,0,u-e|0),a[A+4>>2]=i,s=a[A+24>>2],(0|s)<(0|i)){e:if(a[A+28>>2]>=(0|i))n=a[A+32>>2];else{if(i?(n=dA(u),r=a[A+24>>2]):(n=0,r=s),b=a[A+32>>2],(0|r)>=1)for(c=n,e=b;a[c>>2]=a[e>>2],c=c+4|0,e=e+4|0,r=r+-1|0,r;);else if(!b){a[A+32>>2]=n,a[A+28>>2]=i,f[A+36|0]=1;break e}o[A+36|0]&&CA(b),a[A+32>>2]=n,f[A+36|0]=1,a[A+28>>2]=i}e=s<<2,X(e+n|0,0,u-e|0)}if(a[A+24>>2]=i,(0|i)>=1&&(X(a[A+12>>2],255,u),X(a[A+32>>2],255,u)),!((0|l)<1))for(e=a[A+32>>2],c=a[A+72>>2],b=a[A+12>>2],r=0;n=b+((t[c>>1]+(v[c+2>>1]<<16)&a[A+48>>2]+-1)<<2)|0,a[e>>2]=a[n>>2],a[n>>2]=r,c=c+4|0,e=e+4|0,r=r+1|0,(0|r)!=(0|l););}}(A),C=t[e>>1]+(v[e+2>>1]<<16)&a[A+48>>2]+-1),e=a[A+32>>2]+(u<<2)|0,A=a[A+12>>2]+(C<<2)|0,a[e>>2]=a[A>>2],void(a[A>>2]=u)}A=a[A+52>>2]+(i<<2)|0,e=v[r>>1]|v[r+2>>1]<<16,t[A>>1]=e,t[A+2>>1]=e>>>16}function IA(A,e,r,i,f,t,n){var o=_(0),c=0,b=_(0),l=0,u=0,s=_(0),k=_(0),v=_(0);if(a[i>>2]=2139095039,c=-8388609,a[f>>2]=-8388609,l=a[A+8>>2],o=_(-3.4028234663852886e38),!((0|l)<1)){for(c=4;u=a[A+16>>2]+c|0,o=C[u+-4>>2],b=C[u>>2],s=C[u+4>>2],k=_(_(_(_(o*C[e>>2])+_(b*C[e+4>>2]))+_(s*C[e+8>>2]))+C[e+48>>2]),v=_(_(_(_(o*C[e+16>>2])+_(b*C[e+20>>2]))+_(s*C[e+24>>2]))+C[e+52>>2]),b=_(_(_(_(o*C[e+32>>2])+_(b*C[e+36>>2]))+_(s*C[e+40>>2]))+C[e+56>>2]),o=_(_(_(k*C[r>>2])+_(v*C[r+4>>2]))+_(b*C[r+8>>2])),o>2]&&(C[i>>2]=o,a[t+12>>2]=0,C[t+8>>2]=b,C[t+4>>2]=v,C[t>>2]=k),o>C[f>>2]&&(C[f>>2]=o,a[n+12>>2]=0,C[n+8>>2]=b,C[n+4>>2]=v,C[n>>2]=k),c=c+16|0,l=l+-1|0,l;);c=a[f>>2],o=C[f>>2]}b=C[i>>2],b>o&&(a[i>>2]=c,C[f>>2]=b,A=t+8|0,r=a[A>>2],i=a[A+4>>2],e=n+8|0,c=a[e+4>>2],a[A>>2]=a[e>>2],a[A+4>>2]=c,A=a[t>>2],f=a[t+4>>2],c=a[n+4>>2],a[t>>2]=a[n>>2],a[t+4>>2]=c,a[n>>2]=A,a[n+4>>2]=f,a[e>>2]=r,a[e+4>>2]=i)}function JA(A,e){var r,i,f=0,t=0,n=0,o=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0,C=0;return r=a[A+16>>2],t=a[e+16>>2],(0|r)!=(0|t)?r-t|0:r?(d=-1,c=a[A+4>>2],b=a[e+8>>2],l=a[e+12>>2],v=a[A>>2],s=_t(l,0,v,0),u=V,l=_t(l,n,c,0),f=l+u|0,t=V+o|0,o=f,f=f>>>0>>0?t+1|0:t,l=0,c=_t(b,l,c,n),t=o,o=V,n=t+o|0,n>>>0>>0&&(f=f+1|0),t=n,o=f,n=0,f=c+s|0,f>>>0>>0&&(n=n+1|0),s=n,n=n+t|0,t=o,t=n>>>0>>0?t+1|0:t,o=n,n=f,s=0,b=_t(b,l,v,C),c=s+b|0,f=V+f|0,f=c>>>0>>0?f+1|0:f,i=c,b=c,c=f,n=(0|n)==(0|f)&b>>>0>>0|f>>>0>>0,f=o+n|0,f>>>0>>0&&(t=t+1|0),s=f,b=t,l=f,v=t,n=a[A+8>>2],A=a[A+12>>2],f=a[e>>2],u=a[e+4>>2],t=0,C=n,o=_t(u,t,n,0),e=V,k=A,n=0,u=_t(u,t,A,n),A=e+u|0,t=V,t=A>>>0>>0?t+1|0:t,e=A,u=f,A=_t(f,0,k,n),k=V,e=k+e|0,f=t,f=e>>>0>>0?f+1|0:f,n=f,t=0,f=A+o|0,f>>>0>>0&&(t=t+1|0),k=t,o=t+e|0,t=n,e=o,n=e>>>0>>0?t+1|0:t,k=e,e=0,o=_t(u,0,C,0),A=e+o|0,t=f,f=f+V|0,f=A>>>0>>0?f+1|0:f,o=A,A=f,e=(0|t)==(0|f)&o>>>0>>0|f>>>0>>0,t=k+e|0,t>>>0>>0&&(n=n+1|0),f=t,e=n,(0|n)==(0|v)&l>>>0>>0|v>>>0>>0||(d=1,(0|e)==(0|b)&s>>>0>t>>>0|b>>>0>e>>>0||(d=-1,(0|A)==(0|c)&i>>>0>>0|c>>>0>>0||(d=(0|A)==(0|c)&i>>>0>o>>>0|c>>>0>A>>>0))),B(d,r)):0}function xA(A,e,r){var i=0,f=0,t=0,n=0,o=0,c=0,b=0,l=0;if(n=a[A+56>>2],!(n||(i=a[A+52>>2],i?a[A+52>>2]=a[i+8>>2]:(i=dA(12),a[i+8>>2]=0,f=a[A+60>>2],a[i+4>>2]=f,b=i,l=dA(B(f,24)),a[b>>2]=l,f=a[A+48>>2],a[A+48>>2]=i,a[i+8>>2]=f),n=a[i>>2],t=a[i+4>>2],(0|t)<1)))for(i=0,f=n;o=f,f=f+24|0,i=i+1|0,a[o>>2]=(0|i)<(0|t)?f:0,(0|i)!=(0|t););if(a[A+56>>2]=a[n>>2],f=n+8|0,a[f>>2]=0,a[f+4>>2]=0,f=n+16|0,a[f>>2]=0,a[f+4>>2]=0,a[n>>2]=0,a[n+4>>2]=0,t=a[A+56>>2],!(t||(i=a[A+52>>2],i?a[A+52>>2]=a[i+8>>2]:(i=dA(12),a[i+8>>2]=0,f=a[A+60>>2],a[i+4>>2]=f,b=i,l=dA(B(f,24)),a[b>>2]=l,f=a[A+48>>2],a[A+48>>2]=i,a[i+8>>2]=f),t=a[i>>2],c=a[i+4>>2],(0|c)<1)))for(i=0,f=t;o=f,f=f+24|0,i=i+1|0,a[o>>2]=(0|i)<(0|c)?f:0,(0|i)!=(0|c););return a[A+56>>2]=a[t>>2],a[t>>2]=0,a[t+4>>2]=0,a[n+8>>2]=t,a[n+12>>2]=r,a[n+16>>2]=0,r=a[A+100>>2],a[n+20>>2]=r,a[t+8>>2]=n,a[t+12>>2]=e,a[t+16>>2]=0,a[t+20>>2]=r,e=a[A+116>>2],r=e+1|0,a[A+116>>2]=r,(0|e)>=a[A+120>>2]&&(a[A+120>>2]=r),n}function UA(A,e,r,i){var f,t=0,n=0,o=0,c=0,b=0,l=0,u=0;f=Y-16|0,Y=f,t=r-e|0;A:if(t>>>0<=2){switch(t-1|0){default:a[i>>2]=0,a[i+4>>2]=0,A=i+8|0,a[A>>2]=0,a[A+4>>2]=0;break A;case 1:if(r=a[a[A+92>>2]+(e<<2)>>2],t=a[r+204>>2],c=a[r+88>>2],o=a[r+200>>2],n=a[r+92>>2],(0|c)!=(0|o)|(0|n)!=(0|t)||(t=n,a[r+96>>2]!=a[r+208>>2])){e=r+112|0,t=n-t|0,n=c-o|0,t|n?(a[r+4>>2]=e,a[r>>2]=e,a[r+116>>2]=r,a[r+112>>2]=r,c=(0|t)<0,b=c&!n,n=(0|n)<0,o=b|n,a[i+4>>2]=o?e:r,a[i>>2]=o?r:e,n&!t||c?(a[i+8>>2]=r,t=e):(a[i+8>>2]=e,t=r)):(n=a[r+96>>2]>a[r+208>>2],t=n?e:r,a[i+8>>2]=t,a[i+4>>2]=t,a[i>>2]=t,a[t+4>>2]=t,a[t>>2]=t,e=n?r:e,r=t),a[i+12>>2]=t,A=xA(A,r,e),a[r+8>>2]=A,r=e,e=a[A+8>>2],a[r+8>>2]=e,a[A+4>>2]=A,a[A>>2]=A,a[e+4>>2]=e,a[e>>2]=e;break A}a[r+8>>2]=0,a[i+12>>2]=r,a[i+8>>2]=r,a[i+4>>2]=r,a[i>>2]=r,a[r+4>>2]=r,a[r>>2]=r;break A;case 0:}A=a[a[A+92>>2]+(e<<2)>>2],a[A+8>>2]=0,a[i+12>>2]=A,a[i+8>>2]=A,a[i+4>>2]=A,a[i>>2]=A,a[A+4>>2]=A,a[A>>2]=A}else{o=(0|t)/2|0,c=o+e|0,n=c;e:if(!((0|n)>=(0|r))){for(n=a[A+92>>2],t=a[(n+(c<<2)|0)-4>>2],l=a[t+88>>2],u=a[t+96>>2],b=a[t+92>>2],t=n+(e+o<<2)|0,n=c;;){if(o=a[t>>2],(0|l)!=a[o+88>>2]|a[o+92>>2]!=(0|b)|a[o+96>>2]!=(0|u))break e;if(t=t+4|0,n=n+1|0,(0|n)==(0|r))break}n=r}UA(A,e,c,i),e=f+8|0,a[e>>2]=0,a[e+4>>2]=0,a[f>>2]=0,a[f+4>>2]=0,UA(A,n,r,f),function(A,e,r){var i=0,f=0,t=0,n=0,o=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0,C=0,g=0,_=0,m=0,R=0,Q=0,h=0,G=0,y=0,p=0,F=0,W=0,w=0,D=0,E=0,Z=0,N=0,I=0,J=0,x=0;f=Y-128|0,Y=f;e:if(a[r+4>>2])if(a[e+4>>2]){if(a[A+100>>2]=a[A+100>>2]+-1,a[f+124>>2]=0,a[f+120>>2]=0,e=function(A,e,r,i){var f=0,t=0,n=0,o=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0,C=0,g=0,_=0,m=0,R=0,Q=0,h=0;n=a[A+12>>2],u=a[e+8>>2];r:{if(!(a[n+88>>2]!=a[u+88>>2]|a[n+92>>2]!=a[u+92>>2])){if(f=a[u+4>>2],(0|u)==(0|f)){if(a[r>>2]=n,A=a[u+8>>2],e=0,!A)break r;return a[i>>2]=a[A+12>>2],0}n=a[u>>2],a[n+4>>2]=f,a[f>>2]=n,(0|u)==a[e>>2]&&(b=e,s=n,t=a[n+88>>2],o=a[f+88>>2],(0|t)<(0|o)|(a[n+92>>2]>2]?(0|t)==(0|o):0)||(s=f),a[b>>2]=s),a[e+4>>2]==(0|u)&&(t=a[n+88>>2],o=a[f+88>>2],(0|t)!=(0|o)|a[n+92>>2]<=a[f+92>>2]&&(0|t)<=(0|o)?a[e+4>>2]=f:a[e+4>>2]=n)}for(m=a[e>>2],Q=a[A>>2],h=a[A+4>>2],o=h,R=a[e+4>>2],t=R,u=0,s=1;;){v=a[o+88>>2],f=B(a[t+88>>2]-v|0,s);i:if((0|f)>=1)for(b=o;;){for(n=t,c=a[t+92>>2],o=f;t=a[b+92>>2],v=c-t|0,l=!d<<2,f=a[l+b>>2],!((0|f)==(0|b)||(k=a[f+92>>2]-t|0,(0|k)>0||(C=a[f+88>>2],t=B(C-a[b+88>>2]|0,s),(0|t)>-1|(0|B(o,k))>(0|B(t,v))&&t)));)o=B(a[n+88>>2]-C|0,s),b=f;if(t=a[n+l>>2],(0|n)==(0|t))break i;if(l=a[t+92>>2]-c|0,(0|l)>-1)break i;if(c=a[t+88>>2],f=B(c-a[b+88>>2]|0,s),(0|f)<1)break i;if(c=B(c-a[n+88>>2]|0,s),c){if((0|c)>-1)break i;if(!((0|B(o,l))<(0|B(c,v))))break}}else if((0|f)<=-1){f:for(;;){for(v=a[t+92>>2],C=(0!=(0|d))<<2,n=a[C+t>>2];;){if(c=f,b=o,k=a[o+92>>2],l=v-k|0,(0|t)!=(0|n)&&(o=a[n+92>>2]-v|0,!((0|o)<0||(g=a[n+88>>2],f=B(g-a[t+88>>2]|0,s),(0|f)>-1|(0|B(o,c))>(0|B(f,l))&&f)))){f=B(g-a[b+88>>2]|0,s),t=n,o=b;continue f}if(o=a[b+C>>2],(0|b)==(0|o)){n=t;break i}if(g=a[o+92>>2]-k|0,(0|g)<1){n=t;break i}if(k=a[o+88>>2],f=B(a[t+88>>2]-k|0,s),(0|f)>-1){n=t;break i}if(k=B(k-a[b+88>>2]|0,s),k){if((0|k)>-1){n=t;break i}if(!((0|B(c,g))<(0|B(l,k))))break}}break}n=t}else{n=a[o+92>>2];f:if(d)for(f=o;;){if(b=f,f=a[f>>2],(0|o)==(0|f)|(0|v)!=a[f+88>>2])break f;if(c=a[f+92>>2],l=(0|c)>(0|n),n=c,l)break}else for(f=o;;){if(b=f,f=a[f+4>>2],(0|o)==(0|f)|(0|v)!=a[f+88>>2])break f;if(c=a[f+92>>2],l=(0|c)<=(0|n),n=c,!l)break}if(o=a[t+92>>2],d)for(f=t;;){if(n=f,f=a[f+4>>2],(0|f)==(0|t)|(0|v)!=a[f+88>>2])break i;if(c=a[f+92>>2],l=(0|c)<(0|o),o=c,l)break}else for(f=t;;){if(n=f,f=a[f>>2],(0|f)==(0|t)|(0|v)!=a[f+88>>2])break i;if(c=a[f+92>>2],l=(0|c)>=(0|o),o=c,!l)break}}if(o=d?b:Q,t=d?n:m,_=d?_:b,u=d?u:n,s=d?s:-1,d=d+1|0,2==(0|d))break}a[t>>2]=o,a[o+4>>2]=t,a[_>>2]=u,a[u+4>>2]=_,a[m+88>>2]>2]&&(a[A>>2]=m),a[R+88>>2]>=a[h+88>>2]&&(a[A+4>>2]=R),a[A+12>>2]=a[e+12>>2],a[r>>2]=_,e=1}return A=e,a[i>>2]=u,A}(e,r,f+124|0,f+120|0),g=a[f+120>>2],e){if(G=a[f+124>>2],D=a[G+96>>2],E=a[g+96>>2],W=a[G+92>>2],C=a[g+92>>2],i=a[G+8>>2],_=a[G+88>>2],Z=a[g+88>>2],a[f+80>>2]=0,e=E-D|0,t=e,n=e>>31,e=C-W|0,R=e,Q=e>>31,N=_t(t,n,e,Q),I=V,r=Z-_|0,e=0-r|0,F=e,y=e>>31,e=_t(e,y,r,r>>31),o=V,r=_t(R,Q,R,Q),J=e-r|0,d=o-(V+(e>>>0>>0)|0)|0,e=_t(F,y,t,n),v=0-e|0,p=0-(V+(0>>0)|0)|0,i){for(r=i;;){l=a[r+12>>2],s=a[l+92>>2],e=s-W|0,c=e,b=e>>31,e=_t(e,b,F,y),o=V,w=e,k=a[l+88>>2],e=k-_|0,t=e,n=e>>31,e=_t(R,Q,e,n);r:if(!((0|w)!=(0-e|0)|(0-(V+(0>>0)|0)|0)!=(0|o)||(e=_t(N,I,c,b),o=V,c=e,e=_t(t,n,v,p),n=c+e|0,t=V+o|0,t=n>>>0>>0?t+1|0:t,o=a[l+96>>2],e=o-D|0,e=_t(J,d,e,e>>31),n=e+n|0,t=V+t|0,t=n>>>0>>0?t+1|0:t,(0|t)<0||(0|t)<=0&&!(n>>>0>=1)))){i:if(u){if(e=a[u+4>>2],(0|r)==a[u>>2]){if((0|e)!=(0|r))break r;if(c=a[a[r+8>>2]+12>>2],e=a[c+96>>2],b=o-e|0,t=a[u+12>>2],n=a[t+96>>2]-e|0,e=a[c+92>>2],e=B(b,a[t+92>>2]-e|0)-B(n,s-e|0)|0,e=_t(e,e>>31,R,Q),o=V,s=e,e=a[c+88>>2],e=B(n,k-e|0)-B(b,a[t+88>>2]-e|0)|0,e=_t(e,e>>31,F,y),n=s+e|0,t=V+o|0,t=n>>>0>>0?t+1|0:t,(0|t)<0||(0|t)<=0&&!(n>>>0>0))break i;break r}if((0|e)!=(0|r))break r}u=r}if(r=a[r>>2],(0|i)==(0|r))break}a[f+80>>2]=u}if(e=a[g+8>>2],k=0,a[f+56>>2]=0,e){for(r=e;;){_=a[r+12>>2],l=a[_+92>>2],i=l-C|0,s=i,c=i>>31,i=_t(i,c,F,y),o=V,W=i,b=a[_+88>>2],i=b-Z|0,t=i,n=i>>31,i=_t(R,Q,i,n);r:if(!((0|W)!=(0-i|0)|(0-(V+(0>>0)|0)|0)!=(0|o)||(i=_t(N,I,s,c),o=V,c=i,i=_t(t,n,v,p),n=c+i|0,t=V+o|0,t=n>>>0>>0?t+1|0:t,o=a[_+96>>2],i=o-E|0,i=_t(J,d,i,i>>31),n=i+n|0,t=V+t|0,t=n>>>0>>0?t+1|0:t,(0|t)<0||(0|t)<=0&&!(n>>>0>=1)))){if(k){if(a[k>>2]!=(0|r))break r;if(a[k+4>>2]==(0|r)&&(s=a[a[r+8>>2]+12>>2],i=a[s+96>>2],c=o-i|0,t=a[k+12>>2],n=a[t+96>>2]-i|0,i=a[s+92>>2],i=B(c,a[t+92>>2]-i|0)-B(n,l-i|0)|0,i=_t(i,i>>31,R,Q),o=V,l=i,i=a[s+88>>2],i=B(n,b-i|0)-B(c,a[t+88>>2]-i|0)|0,i=_t(i,i>>31,F,y),n=l+i|0,o=V+o|0,o=n>>>0>>0?o+1|0:o,(0|o)<0||(0|o)<=0&&!(n>>>0>=1)))break r}k=r}if(r=a[r>>2],(0|e)==(0|r))break}a[f+56>>2]=k}u|k&&(MA(A,G,g,f+80|0,f+56|0),e=a[f+80>>2],e&&(G=a[e+12>>2],a[f+124>>2]=G),e=a[f+56>>2],e&&(g=a[e+12>>2],a[f+120>>2]=g)),w=a[g+96>>2]+1|0,x=a[g+92>>2],R=a[g+88>>2]}else w=a[g+96>>2],x=a[g+92>>2],G=a[f+124>>2],R=a[g+88>>2]+1|0;for(k=G,n=g,t=0,e=0,p=0,D=1,l=0,u=0,_=0;;){a[f+116>>2]=-1,Z=n+92|0,N=k+92|0,b=a[N>>2],i=a[Z>>2]-b|0,a[f+108>>2]=i,I=n+96|0,J=k+96|0,o=a[J>>2],c=a[I>>2]-o|0,a[f+112>>2]=c,v=a[k+88>>2],r=a[n+88>>2]-v|0,a[f+104>>2]=r,s=x-b|0,b=w-o|0,o=B(s,c)-B(b,i)|0,Q=o>>31,E=o,a[f+80>>2]=o,a[f+84>>2]=Q,o=B(r,b),b=R-v|0,o=o-B(b,c)|0,F=o>>31,W=o,a[f+88>>2]=o,a[f+92>>2]=F,o=B(i,b)-B(r,s)|0,y=o>>31,C=o,a[f+96>>2]=o,a[f+100>>2]=y,b=r,d=r>>31,r=_t(W,F,r,d),s=V,o=i,v=i>>31,i=_t(E,Q,i,v),a[f+72>>2]=r-i,a[f+76>>2]=s-(V+(r>>>0>>0)|0),i=c,s=i>>31,r=_t(E,Q,i,s),c=V,b=_t(C,y,b,d),a[f+64>>2]=r-b,a[f+68>>2]=c-(V+(r>>>0>>0)|0),r=_t(C,y,o,v),o=V,i=_t(W,F,i,s),a[f+56>>2]=r-i,a[f+60>>2]=o-(V+(r>>>0>>0)|0),a[f+48>>2]=0,r=f+40|0,a[r>>2]=0,a[r+4>>2]=0,a[f+32>>2]=0,a[f+36>>2]=0,C=SA(A,0,k,f+104|0,f+80|0,f+56|0,f+32|0),a[f+24>>2]=0,r=f+16|0,a[r>>2]=0,a[r+4>>2]=0,a[f+8>>2]=0,a[f+12>>2]=0,v=SA(A,1,n,f+104|0,f+80|0,f+56|0,f+8|0);r:if(v|C){d=C?-1:1,!C|!v||(d=JA(f+32|0,f+8|0));i:{f:if(!D){t:{if((0|d)>=0){if(a[f+24>>2]>-1)break f;if(!(a[f+16>>2]|a[f+20>>2]))break t;break f}if(a[f+40>>2]|a[f+44>>2]|a[f+48>>2]>-1)break f}c=t,i=e,s=l,o=u;break i}s=xA(A,k,n),o=s,l&&(a[l+4>>2]=s,o=u),a[s>>2]=l,c=a[s+8>>2],i=c,t&&(a[t>>2]=c,i=e),a[c+4>>2]=t}if(a[f+4>>2]=C,a[f>>2]=v,t=v,d||(MA(A,k,n,f+4|0,f),t=a[f>>2]),!t|(0|d)<0)u=n,t=c;else{if(m&&(r=a[m>>2],(0|v)!=(0|r)))for(;l=a[r+8>>2],b=0,u=0,e=a[r>>2],(0|r)!=(0|e)&&(a[e+4>>2]=a[r+4>>2],a[a[r+4>>2]>>2]=e,u=e),a[a[l+12>>2]+8>>2]=u,u=a[l>>2],(0|l)!=(0|u)&&(a[u+4>>2]=a[l+4>>2],a[a[l+4>>2]>>2]=u,b=u),a[a[r+12>>2]+8>>2]=b,a[r+12>>2]=0,a[r+16>>2]=0,a[r+4>>2]=0,a[r+8>>2]=0,a[r>>2]=a[A+56>>2],a[A+56>>2]=r,r=l+12|0,a[r>>2]=0,a[r+4>>2]=0,a[l+4>>2]=0,a[l+8>>2]=0,a[l>>2]=a[A+56>>2],a[A+56>>2]=l,a[A+116>>2]=a[A+116>>2]+-1,r=e,(0|v)!=(0|e););c?(m||(m=a[v+4>>2],p=i),a[m>>2]=i,a[i+4>>2]=m,a[v+4>>2]=c,a[c>>2]=v,i=0):p=m?p:v,u=a[t+12>>2],a[f+120>>2]=u,w=a[I>>2],x=a[Z>>2],m=a[t+8>>2],R=a[n+88>>2],t=0}if((0|d)>0||(l=a[f+4>>2],!l))e=k;else{if(h&&(e=a[h+4>>2],(0|C)!=(0|e)))for(;v=e+4|0,d=a[e+8>>2],b=a[e+4>>2],n=0,r=0,c=a[e>>2],(0|e)!=(0|c)&&(a[c+4>>2]=b,a[a[v>>2]>>2]=c,r=c),a[a[d+12>>2]+8>>2]=r,r=a[d>>2],(0|d)!=(0|r)&&(a[r+4>>2]=a[d+4>>2],a[a[d+4>>2]>>2]=r,n=r),a[a[e+12>>2]+8>>2]=n,r=v+8|0,a[r>>2]=0,a[r+4>>2]=0,a[v>>2]=0,a[v+4>>2]=0,a[e>>2]=a[A+56>>2],a[A+56>>2]=e,e=d+12|0,a[e>>2]=0,a[e+4>>2]=0,a[d+4>>2]=0,a[d+8>>2]=0,a[d>>2]=a[A+56>>2],a[A+56>>2]=d,a[A+116>>2]=a[A+116>>2]+-1,e=b,(0|C)!=(0|e););s?(h||(h=a[C>>2],_=o),a[h+4>>2]=o,a[o>>2]=h,a[s+4>>2]=C,a[C>>2]=s,o=0):_=h?_:C,e=a[l+12>>2],a[f+124>>2]=e,w=a[J>>2],x=a[N>>2],h=a[l+8>>2],R=a[k+88>>2],s=0}if(l=s,r=1,(0|e)!=(0|G)|(0|u)!=(0|g))D=0;else{if(h){if(e=a[h+4>>2],(0|e)!=(0|_))for(;b=e+4|0,c=a[e+8>>2],u=a[e+4>>2],n=0,r=0,k=a[e>>2],(0|e)!=(0|k)&&(a[k+4>>2]=u,a[a[b>>2]>>2]=k,r=k),a[a[c+12>>2]+8>>2]=r,r=a[c>>2],(0|c)!=(0|r)&&(a[r+4>>2]=a[c+4>>2],a[a[c+4>>2]>>2]=r,n=r),a[a[e+12>>2]+8>>2]=n,r=b+8|0,a[r>>2]=0,a[r+4>>2]=0,a[b>>2]=0,a[b+4>>2]=0,a[e>>2]=a[A+56>>2],a[A+56>>2]=e,e=c+12|0,a[e>>2]=0,a[e+4>>2]=0,a[c+4>>2]=0,a[c+8>>2]=0,a[c>>2]=a[A+56>>2],a[A+56>>2]=c,a[A+116>>2]=a[A+116>>2]+-1,e=u,(0|_)!=(0|e););l&&(a[h+4>>2]=o,a[o>>2]=h,a[l+4>>2]=_,a[_>>2]=l)}else a[l+4>>2]=o,a[o>>2]=l,a[e+8>>2]=l;if(!m){a[t>>2]=i,a[i+4>>2]=t,a[a[f+120>>2]+8>>2]=t,m=0,e=i,u=o,r=0;break r}if(r=a[m>>2],(0|r)!=(0|p))for(;n=a[r+8>>2],b=0,u=0,e=a[r>>2],(0|r)!=(0|e)&&(a[e+4>>2]=a[r+4>>2],a[a[r+4>>2]>>2]=e,u=e),a[a[n+12>>2]+8>>2]=u,u=a[n>>2],(0|n)!=(0|u)&&(a[u+4>>2]=a[n+4>>2],a[a[n+4>>2]>>2]=u,b=u),a[a[r+12>>2]+8>>2]=b,a[r+12>>2]=0,a[r+16>>2]=0,a[r+4>>2]=0,a[r+8>>2]=0,a[r>>2]=a[A+56>>2],a[A+56>>2]=r,r=n+12|0,a[r>>2]=0,a[r+4>>2]=0,a[n+4>>2]=0,a[n+8>>2]=0,a[n>>2]=a[A+56>>2],a[A+56>>2]=n,a[A+116>>2]=a[A+116>>2]+-1,r=e,(0|p)!=(0|e););r=0,t?(a[i+4>>2]=m,a[m>>2]=i,a[p+4>>2]=t,a[t>>2]=p):t=0}e=i,u=o}else i=xA(A,k,n),a[k+8>>2]=i,r=a[i+8>>2],a[n+8>>2]=r,a[i+4>>2]=i,a[i>>2]=i,a[r+4>>2]=r,a[r>>2]=r,r=0;if(!r)break e;k=a[f+124>>2],n=a[f+120>>2]}}else A=a[r+4>>2],a[e>>2]=a[r>>2],a[e+4>>2]=A,i=e+8|0,e=r+8|0,A=a[e+4>>2],a[i>>2]=a[e>>2],a[i+4>>2]=A;Y=f+128|0}(A,i,f)}Y=f+16|0}function MA(A,e,r,i,f){var t,n,o,c,b,l,u,s,k,v,d,C,g,_,m,R,Q=0,h=0,G=0,y=0,p=0,F=0,W=0,w=0,D=0,E=0,Z=0,N=0,I=0,J=0,x=0,U=0,M=0,S=0,X=0,T=0,j=0,O=0,H=0,z=0,P=0,K=0;if(t=Y-48|0,Y=t,x=e,O=a[i>>2],O&&(x=a[O+12>>2]),X=a[x+96>>2],T=a[x+92>>2],x=a[x+88>>2],j=a[f>>2],h=j?a[j+12>>2]:r,Q=a[e+96>>2],s=a[r+96>>2]-Q|0,F=a[(O||j)+12>>2],G=a[e+92>>2],y=a[F+92>>2]-G|0,k=a[r+92>>2]-G|0,N=a[F+96>>2]-Q|0,p=B(s,y)-B(k,N)|0,_=p,d=p>>31,U=s>>31,p=_t(p,d,s,U),M=V,e=a[e+88>>2],F=a[F+88>>2]-e|0,v=a[r+88>>2]-e|0,r=B(F,k)-B(y,v)|0,m=r,C=r>>31,y=v>>31,r=_t(r,C,v,y),n=p-r|0,o=M-(V+(p>>>0>>0)|0)|0,p=_t(n,o,T,T>>31),M=V,J=k>>31,r=_t(m,C,k,J),D=V,F=B(N,v)-B(F,s)|0,R=F,g=F>>31,F=_t(F,g,s,U),c=r-F|0,b=D-(V+(r>>>0>>0)|0)|0,N=_t(c,b,x,x>>31),F=N+p|0,p=V+M|0,r=_t(R,g,v,y),y=V,U=_t(_,d,k,J),l=r-U|0,u=y-(V+(r>>>0>>0)|0)|0,y=_t(l,u,X,X>>31),U=F+y|0,r=U,F=V+(F>>>0>>0?p+1|0:p)|0,F=r>>>0>>0?F+1|0:F,e=_t(_,d,e,e>>31),p=V,y=_t(m,C,Q,Q>>31),e=y+e|0,Q=V+p|0,G=_t(R,g,G,G>>31),p=G+e|0,E=p,e=V+(e>>>0>>0?Q+1|0:Q)|0,J=p>>>0>>0?e+1|0:e,N=a[h+96>>2],U=a[h+92>>2],M=a[h+88>>2],e=j,O&&(e=j,a[O+12>>2])){e=a[a[O+8>>2]+4>>2],G=a[e+12>>2],Q=a[G+92>>2],h=Q,p=Q>>31,y=_t(Q,p,R,g),D=V,w=a[G+88>>2],Q=w,W=Q>>31,I=_t(Q,W,_,d),w=y+I|0,Z=V+D|0,G=a[G+96>>2],y=G,D=G>>31,G=_t(G,D,m,C),S=w+G|0,w=V+(w>>>0>>0?Z+1|0:Z)|0,G=S>>>0>>0?w+1|0:w;A:if(!((0|G)<(0|J)||(0|G)<=(0|J)&&!(S>>>0>=E>>>0))){for(w=e+12|0;;){if(a[e+20>>2]==a[A+100>>2])break A;if(h=_t(n,o,h,p),G=V,p=_t(c,b,Q,W),Q=p+h|0,G=V+G|0,y=_t(l,u,y,D),D=y+Q|0,h=D,Q=V+(Q>>>0

>>0?G+1|0:G)|0,G=h>>>0>>0?Q+1|0:Q,Q=G,(0|Q)<(0|F)||(0|Q)<=(0|F)&&!(h>>>0>r>>>0))break A;if(a[i>>2]=e,r=a[w>>2],X=a[r+96>>2],T=a[r+92>>2],x=a[r+88>>2],!r)break;if(e=a[a[e+8>>2]+4>>2],w=e+12|0,r=h,F=Q,G=a[e+12>>2],Q=a[G+92>>2],h=Q,p=Q>>31,y=_t(Q,p,R,g),D=V,W=a[G+88>>2],Q=W,W=Q>>31,S=_t(Q,W,_,d),Z=y+S|0,I=V+D|0,G=a[G+96>>2],y=G,D=G>>31,G=_t(G,D,m,C),H=G+Z|0,Z=V+(Z>>>0>>0?I+1|0:I)|0,G=H>>>0>>0?Z+1|0:Z,(0|G)<(0|J)||(0|G)<=(0|J)&&!(H>>>0>=E>>>0))break A}r=h,F=Q}e=a[f>>2]}h=_t(n,o,U,U>>31),G=V,p=_t(c,b,M,M>>31),Q=p+h|0,G=V+G|0,y=_t(l,u,N,N>>31),D=y+Q|0,h=D,Q=V+(Q>>>0

>>0?G+1|0:G)|0,p=h>>>0>>0?Q+1|0:Q;A:if(e){if(a[e+12>>2]&&(w=a[a[e+8>>2]>>2],G=a[w+12>>2],y=a[G+92>>2],Q=y,W=Q>>31,Z=_t(Q,W,R,g),I=V,D=a[G+88>>2],y=D,D=y>>31,z=_t(y,D,_,d),Z=Z+z|0,I=V+I|0,G=a[G+96>>2],S=G,H=G>>31,G=_t(G,H,m,C),P=G+Z|0,Z=V+(Z>>>0>>0?I+1|0:I)|0,G=P>>>0>>0?Z+1|0:Z,!((0|G)<(0|J)||(0|G)<=(0|J)&&!(P>>>0>=E>>>0)))){for(Z=w+12|0;;){if(G=w,a[G+20>>2]==a[A+100>>2])break A;if(Q=_t(n,o,Q,W),w=V,W=_t(c,b,y,D),y=W+Q|0,D=V+w|0,w=_t(l,u,S,H),Q=w+y|0,y=V+(y>>>0>>0?D+1|0:D)|0,y=Q>>>0>>0?y+1|0:y,(0|y)<(0|p)||(0|y)<=(0|p)&&!(Q>>>0>h>>>0))break A;if(a[f>>2]=G,e=a[Z>>2],N=a[e+96>>2],U=a[e+92>>2],M=a[e+88>>2],!e)break;if(w=a[a[G+8>>2]>>2],Z=w+12|0,h=Q,p=y,e=G,G=a[w+12>>2],y=a[G+92>>2],Q=y,W=Q>>31,I=_t(Q,W,R,g),S=V,D=a[G+88>>2],y=D,D=y>>31,P=_t(y,D,_,d),I=I+P|0,z=V+S|0,G=a[G+96>>2],S=G,H=G>>31,G=_t(G,H,m,C),K=I+G|0,I=V+(I>>>0

>>0?z+1|0:z)|0,G=K>>>0>>0?I+1|0:I,(0|G)<(0|J)||(0|G)<=(0|J)&&!(K>>>0>=E>>>0))break A}e=G,h=Q,p=y}}else e=0;A:{if(F=p-((h>>>0>>0)+F|0)|0,r=h-r|0,!((0|F)<0||(0|F)<=0&&!(r>>>0>=1)))for(;;){w=(B(U-T|0,k)+B(M-x|0,v)|0)+B(N-X|0,s)|0,e=w,G=e,D=e>>31;e:if(j=a[i>>2],!(!j|!a[j+12>>2]||(Z=a[a[j>>2]+8>>2],a[Z+20>>2]<=a[A+100>>2]))){h=a[Z+12>>2],e=a[h+92>>2],Q=e-T|0,y=a[h+88>>2],p=y-x|0,J=a[h+96>>2],W=J-X|0,h=(B(Q,k)+B(p,v)|0)+B(W,s)|0,Q=_t(n,o,Q,Q>>31),E=V,I=_t(c,b,p,p>>31),Q=I+Q|0,E=V+E|0,W=_t(l,u,W,W>>31),p=W+Q|0,Q=V+(Q>>>0>>0?E+1|0:E)|0,Q=p>>>0>>0?Q+1|0:Q,E=Q;r:{if(!(0!=(0|p)|0!=(0|Q))){if((0|h)<0)break r;break e}if((0|E)>-1||(0|E)>=-1&&!(p>>>0<=4294967295))break e;if(Q=h,W=Q>>31,S=t,(0|Q)>=1?(a[t+40>>2]=1,h=-1):(0|h)<=-1?(a[t+40>>2]=-1,Q=0-Q|0,W=0-((0>>0)+W|0)|0,h=1):(a[t+40>>2]=0,Q=0,W=0,h=0),a[S+40>>2]=h,a[t+24>>2]=Q,a[t+28>>2]=W,a[t+32>>2]=0-p,a[t+36>>2]=0-((0

>>0)+E|0),(0|w)>=1?(a[t+16>>2]=1,h=G,p=D,Q=-1):(0|w)<=-1?(a[t+16>>2]=-1,h=0-G|0,p=0-((0>>0)+D|0)|0,Q=1):(a[t+16>>2]=0,h=0,p=0,Q=0),a[t>>2]=h,a[t+4>>2]=p,h=r,p=F,(0|F)>0||(0|F)>=0&&!(h>>>0<=0)||(h=0,p=0,(0|F)>-1||(0|F)>=-1&&!(r>>>0<=4294967295)||(a[t+16>>2]=Q,h=0-r|0,p=0-((0>>0)+F|0)|0)),Q=p,a[t+8>>2]=h,a[t+12>>2]=Q,(0|JA(t+24|0,t))<=-1)break e}a[i>>2]=(0|j)==(0|O)?0:Z,r=U-e|0,r=_t(n,o,r,r>>31),Q=V,h=M-y|0,F=_t(c,b,h,h>>31),h=r+F|0,Q=V+Q|0,r=N-J|0,G=_t(l,u,r,r>>31),p=h+G|0,r=p,h=V+(h>>>0>>0?Q+1|0:Q)|0,F=r>>>0>>0?h+1|0:h,x=y,T=e,X=J;continue}if(e=a[f>>2],!e|!a[e+12>>2])break A;if(J=a[a[e+8>>2]>>2],a[J+20>>2]<=a[A+100>>2])break A;if(e=a[J+12>>2],p=a[e+92>>2],y=p-U|0,h=y,U=h,W=h>>31,h=_t(h,W,R,g),Q=V,j=a[e+88>>2],M=j-M|0,E=M,Z=E,E>>=31,I=_t(Z,E,_,d),h=h+I|0,Q=V+Q|0,e=a[e+96>>2],N=e-N|0,H=N,S=N>>31,z=_t(m,C,N,S),(0-z|0)!=(0|h)|(0-(V+(0>>0)|0)|0)!=(0|(h>>>0>>0?Q+1|0:Q)))break A;if(h=p-T|0,h=_t(n,o,h,h>>31),Q=V,p=j-x|0,p=_t(c,b,p,p>>31),h=h+p|0,Q=V+Q|0,e=e-X|0,j=_t(l,u,e,e>>31),e=h+j|0,h=V+(h>>>0

>>0?Q+1|0:Q)|0,h=e>>>0>>0?h+1|0:h,p=h,(0|h)<0||(0|h)<=0&&!(e>>>0>=1))break A;h=(B(y,k)+B(M,v)|0)+B(N,s)|0,Q=_t(n,o,U,W),y=V,U=_t(c,b,Z,E),Q=U+Q|0,N=V+y|0,M=_t(l,u,H,S),y=M+Q|0,Q=V+(Q>>>0>>0?N+1|0:N)|0,Q=y>>>0>>0?Q+1|0:Q,N=Q;e:{if(!(0!=(0|y)|0!=(0|Q))){if((0|h)<0)break e;break A}if((0|N)>-1||(0|N)>=-1&&!(y>>>0<=4294967295))break A;if(Q=h,W=Q>>31,E=t,(0|Q)>=1?(a[t+40>>2]=1,h=-1):(0|h)<=-1?(a[t+40>>2]=-1,Q=0-Q|0,W=0-((0>>0)+W|0)|0,h=1):(a[t+40>>2]=0,Q=0,W=0,h=0),a[E+40>>2]=h,a[t+24>>2]=Q,a[t+28>>2]=W,a[t+32>>2]=0-y,a[t+36>>2]=0-((0>>0)+N|0),(0|w)>=1?(a[t+16>>2]=1,Q=-1):(0|w)<=-1?(a[t+16>>2]=-1,h=G,G=0-h|0,D=0-((0>>0)+D|0)|0,Q=1):(a[t+16>>2]=0,G=0,D=0,Q=0),a[t>>2]=G,a[t+4>>2]=D,(0|F)<0||(0|F)<=0&&!(r>>>0>0)?(h=0,y=0,(0|F)>-1||(0|F)>=-1&&!(r>>>0<=4294967295)||(a[t+16>>2]=Q,h=0-r|0,y=0-((0>>0)+F|0)|0)):(h=r,y=F),r=y,a[t+8>>2]=h,a[t+12>>2]=r,(0|JA(t+24|0,t))<=0)break A}a[f>>2]=J,r=a[J+12>>2],N=a[r+96>>2],U=a[r+92>>2],M=a[r+88>>2],r=e,F=p}if(!((0|F)>-1||(0|F)>=-1&&!(r>>>0<=4294967295)))for(;;){O=(B(U-T|0,k)+B(M-x|0,v)|0)+B(N-X|0,s)|0,h=O,G=h,D=h>>31;e:if(!(!e|!a[e+12>>2]||(Z=a[a[e+4>>2]+8>>2],a[Z+20>>2]<=a[A+100>>2]))){h=a[Z+12>>2],p=a[h+92>>2],Q=p-U|0,y=a[h+88>>2],w=y-M|0,J=a[h+96>>2],W=J-N|0,h=(B(Q,k)+B(w,v)|0)+B(W,s)|0,Q=_t(n,o,Q,Q>>31),E=V,I=_t(c,b,w,w>>31),Q=I+Q|0,E=V+E|0,W=_t(l,u,W,W>>31),w=W+Q|0,Q=V+(Q>>>0>>0?E+1|0:E)|0,Q=w>>>0>>0?Q+1|0:Q,E=Q;r:{if(!(0!=(0|w)|0!=(0|Q))){if((0|h)>0)break r;break e}if((0|E)>-1||(0|E)>=-1&&!(w>>>0<=4294967295))break e;if(Q=h,W=Q>>31,S=t,(0|Q)>=1?(a[t+40>>2]=1,h=-1):(0|h)<=-1?(a[t+40>>2]=-1,Q=0-Q|0,W=0-((0>>0)+W|0)|0,h=1):(a[t+40>>2]=0,Q=0,W=0,h=0),a[S+40>>2]=h,a[t+24>>2]=Q,a[t+28>>2]=W,a[t+32>>2]=0-w,a[t+36>>2]=0-((0>>0)+E|0),(0|O)>=1?(a[t+16>>2]=1,w=-1,h=G,Q=D):(0|O)<=-1?(a[t+16>>2]=-1,h=0-G|0,w=1,Q=0-((0>>0)+D|0)|0):(w=0,a[t+16>>2]=0,h=0,Q=0),a[t>>2]=h,a[t+4>>2]=Q,h=r,Q=F,(0|F)>0||(0|F)>=0&&!(h>>>0<=0)||(h=0,Q=0,(0|F)>-1||(0|F)>=-1&&!(r>>>0<=4294967295)||(a[t+16>>2]=w,h=0-r|0,Q=0-((0>>0)+F|0)|0)),a[t+8>>2]=h,a[t+12>>2]=Q,(0|JA(t+24|0,t))>=1)break e}e=(0|e)==(0|j)?0:Z,a[f>>2]=e,r=p-T|0,r=_t(n,o,r,r>>31),Q=V,h=y-x|0,F=_t(c,b,h,h>>31),h=r+F|0,Q=V+Q|0,r=J-X|0,G=_t(l,u,r,r>>31),N=h+G|0,r=N,h=V+(h>>>0>>0?Q+1|0:Q)|0,F=r>>>0>>0?h+1|0:h,M=y,U=p,N=J;continue}if(e=a[i>>2],!e|!a[e+12>>2])break A;if(J=a[a[e+8>>2]+4>>2],a[J+20>>2]<=a[A+100>>2])break A;if(e=a[J+12>>2],p=a[e+92>>2],T=p-T|0,h=T,w=h,W=h>>31,h=_t(h,W,R,g),Q=V,y=a[e+88>>2],x=y-x|0,E=x,Z=E,E>>=31,I=_t(Z,E,_,d),h=h+I|0,Q=V+Q|0,S=a[e+96>>2],X=S-X|0,e=X,H=e,z=e>>31,e=_t(m,C,e,z),(0|h)!=(0-e|0)|(0-(V+(0>>0)|0)|0)!=(0|(h>>>0>>0?Q+1|0:Q)))break A;if(e=U-p|0,e=_t(n,o,e,e>>31),h=V,Q=M-y|0,Q=_t(c,b,Q,Q>>31),e=e+Q|0,h=V+h|0,p=N-S|0,y=_t(l,u,p,p>>31),p=e+y|0,e=V+(e>>>0>>0?h+1|0:h)|0,e=p>>>0>>0?e+1|0:e,y=e,(0|e)>-1||(0|e)>=-1&&!(p>>>0<=4294967295))break A;if(e=(B(T,k)+B(x,v)|0)+B(X,s)|0,h=_t(n,o,w,W),x=V,X=_t(c,b,Z,E),Q=X+h|0,x=V+x|0,T=_t(l,u,H,z),h=T+Q|0,Q=V+(Q>>>0>>0?x+1|0:x)|0,Q=h>>>0>>0?Q+1|0:Q,x=Q,0!=(0|h)|0!=(0|Q)){if((0|x)>-1||(0|x)>=-1&&!(h>>>0<=4294967295))break A;if(Q=e,W=Q>>31,E=t,(0|Q)>=1?(a[t+40>>2]=1,e=-1):(0|e)<=-1?(a[t+40>>2]=-1,Q=0-Q|0,W=0-((0>>0)+W|0)|0,e=1):(a[t+40>>2]=0,Q=0,W=0,e=0),a[E+40>>2]=e,a[t+24>>2]=Q,a[t+28>>2]=W,a[t+32>>2]=0-h,a[t+36>>2]=0-((0>>0)+x|0),(0|O)>=1?(a[t+16>>2]=1,e=-1):(0|O)<=-1?(a[t+16>>2]=-1,e=G,G=0-e|0,D=0-((0>>0)+D|0)|0,e=1):(a[t+16>>2]=0,G=0,D=0,e=0),a[t>>2]=G,a[t+4>>2]=D,(0|F)<0||(0|F)<=0&&!(r>>>0>0)?(h=0,Q=0,(0|F)>-1||(0|F)>=-1&&!(r>>>0<=4294967295)||(a[t+16>>2]=e,h=0-r|0,Q=0-((0>>0)+F|0)|0)):(h=r,Q=F),e=Q,a[t+8>>2]=h,a[t+12>>2]=e,(0|JA(t+24|0,t))>=0)break A}else if((0|e)<=0)break A;a[i>>2]=J,r=a[J+12>>2],X=a[r+96>>2],T=a[r+92>>2],e=a[f>>2],x=a[r+88>>2],r=p,F=y}}Y=t+48|0}function SA(A,e,r,i,f,t,n){var o,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0,C=0,g=0,B=0,_=0;if(o=Y-48|0,Y=o,c=a[r+8>>2],c)for(d=c;;){if(a[d+20>>2]>a[A+100>>2]){a[o+44>>2]=-1,c=a[d+12>>2],l=a[c+96>>2]-a[r+96>>2]|0,a[o+40>>2]=l,b=a[c+92>>2]-a[r+92>>2]|0,a[o+36>>2]=b,u=a[c+88>>2]-a[r+88>>2]|0,a[o+32>>2]=u,c=f,k=b,B=b>>31,b=_t(a[c+8>>2],a[c+12>>2],b,B),v=V,C=b,b=u,_=b>>31,g=_t(a[c>>2],a[c+4>>2],b,_),u=C+g|0,c=V+v|0,c=u>>>0>>0?c+1|0:c,v=u,u=l,g=l>>31,C=_t(a[f+16>>2],a[f+20>>2],l,g),v=v+C|0,l=V+c|0,l=v>>>0>>0?l+1|0:l,c=t,k=_t(a[c+8>>2],a[c+12>>2],k,B),B=V,C=k,k=_t(a[c>>2],a[c+4>>2],b,_),b=C+k|0,c=V+B|0,c=b>>>0>>0?c+1|0:c,u=_t(a[t+16>>2],a[t+20>>2],u,g),b=u+b|0,c=V+c|0,c=b>>>0>>0?c+1|0:c,u=c,(0|c)<0||(0|c)<=0&&!(b>>>0>=1)?(0|u)>-1||(0|u)>=-1&&!(b>>>0<=4294967295)?(a[o+24>>2]=0,b=0,u=0,k=0,c=0):(a[o+24>>2]=-1,k=b,b=0-b|0,u=0-((0>>0)+u|0)|0,k=1,c=-1):(a[o+24>>2]=1,k=-1,c=-1),a[o+8>>2]=b,a[o+12>>2]=u;A:{e:{r:{if(!((0|l)>0||(0|l)>=0&&!(v>>>0<=0))){if((0|l)>-1||(0|l)>=-1&&!(v>>>0<=4294967295))break r;a[o+24>>2]=k,c=v,v=0-c|0,l=0-((0>>0)+l|0)|0}a[o+16>>2]=v,a[o+20>>2]=l;break e}if(a[o+16>>2]=0,a[o+20>>2]=0,!c)break A}s?(c=JA(o+8|0,n),(0|c)<=-1?(s=a[o+12>>2],a[n>>2]=a[o+8>>2],a[n+4>>2]=s,a[n+16>>2]=a[o+24>>2],c=o+16|0,l=a[c+4>>2],s=n+8|0,a[s>>2]=a[c>>2],a[s+4>>2]=l,s=d):c||(s=2!=(0|XA(s,d,i,o+32|0))^e?d:s)):(s=a[o+12>>2],a[n>>2]=a[o+8>>2],a[n+4>>2]=s,a[n+16>>2]=a[o+24>>2],c=o+16|0,l=a[c+4>>2],s=n+8|0,a[s>>2]=a[c>>2],a[s+4>>2]=l,s=d)}c=a[r+8>>2]}if(d=a[d>>2],(0|d)==(0|c))break}return Y=o+48|0,s}function XA(A,e,r,i){var f=0,t=0,n=0,o=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0;t=a[A+4>>2];A:{if((0|e)==a[A>>2]){if(f=2,(0|e)!=(0|t))break A;return t=a[e+12>>2],e=a[a[e+8>>2]+12>>2],o=a[e+96>>2],s=a[t+96>>2]-o|0,A=a[A+12>>2],f=a[e+92>>2],c=a[A+92>>2]-f|0,f=a[t+92>>2]-f|0,o=a[A+96>>2]-o|0,b=B(s,c)-B(f,o)|0,n=b,u=b>>31,b=a[r+8>>2],k=a[i+4>>2],v=a[r+4>>2],d=a[i+8>>2],l=B(b,k)-B(v,d)|0,l=_t(n,u,l,l>>31),u=V,n=f,f=a[A+88>>2],A=a[e+88>>2],f=f-A|0,t=a[t+88>>2]-A|0,A=B(n,f)-B(t,c)|0,e=A,n=A>>31,i=a[i>>2],r=a[r>>2],A=B(i,v)-B(r,k)|0,c=_t(e,n,A,A>>31),e=c+l|0,A=V+u|0,A=e>>>0>>0?A+1|0:A,n=e,e=B(t,o)-B(f,s)|0,f=e,t=e>>31,e=B(r,d)-B(i,b)|0,r=_t(f,t,e,e>>31),e=n+r|0,A=V+A|0,A=e>>>0>>0?A+1|0:A,(0|A)>0||(0|A)>=0&&!(e>>>0<=0)?2:1}f=(0|e)==(0|t)}return f}function TA(A,e,r){var i,t=0,n=0,c=0,l=0,u=0,s=0,v=_(0),d=_(0),g=0,R=_(0),Q=0,h=_(0),G=0,y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=0,E=0,Z=0,V=0;if(i=Y-48|0,Y=i,(0|r)<1)t=1900671690,c=-246811958,s=-246811958,n=-246811958,g=1900671690,Q=1900671690;else for(n=-246811958,Q=1900671690,G=r,u=e,g=1900671690,t=1900671690,s=-246811958,c=-246811958;l=u+8|0,D=a[l>>2],v=C[l>>2],b(0,n),n=k()>2],d=C[l>>2],b(0,s),s=k()>2],v=C[u>>2],b(0,c),c=k()>2]=t,c=G?(1^u)<<1:n?1:2,(0|c)==(0|t)&&(c=(t+1>>>0)%3|0),a[A+104>>2]=c,n=(3^t)-c|0,a[A+108>>2]=n,v=_(v*_(9788566967472434e-20)),d=_(d*_(9788566967472434e-20)),h=_(h*_(9788566967472434e-20)),a[A+12>>2]=0,((n+1|0)%3|0)!=(0|t)&&(d=_(-d),h=_(-h),v=_(-v)),C[A+8>>2]=v,C[A+4>>2]=d,C[A>>2]=h,a[A+28>>2]=0,C[A+24>>2]=_(F+R)*_(.5),C[A+20>>2]=_(y+p)*_(.5),C[A+16>>2]=_(W+w)*_(.5),a[i+36>>2]=0,a[i+28>>2]=0,a[i+32>>2]=0,u=v!=_(0),y=_(_(1)/v),G=d!=_(0),p=_(_(1)/d),g=h!=_(0),F=_(_(1)/h),f[i+40|0]=1,!((0|r)<1)&&(t=dA(r<<4),a[i+36>>2]=t,a[i+32>>2]=r,f[i+40|0]=1,n=i+16|0,c=a[n+4>>2],Q=t+8|0,a[Q>>2]=a[n>>2],a[Q+4>>2]=c,c=a[i+12>>2],a[t>>2]=a[i+8>>2],a[t+4>>2]=c,1!=(0|r)))for(c=r+-1|0,t=16;Q=a[i+12>>2],s=a[i+36>>2]+t|0,l=s,a[l>>2]=a[i+8>>2],a[l+4>>2]=Q,Q=a[n+4>>2],s=l+8|0,a[s>>2]=a[n>>2],a[s+4>>2]=Q,t=t+16|0,c=c+-1|0,c;);if(v=u?y:v,d=G?p:d,h=g?F:h,a[i+28>>2]=r,!((0|r)<1)){for(t=a[i+36>>2]+8|0,n=(i+8|0)+(a[A+104>>2]<<2)|0,u=(i+8|0)+(a[A+112>>2]<<2)|0,G=(i+8|0)+(a[A+108>>2]<<2)|0,y=C[A+24>>2],p=C[A+20>>2],F=C[A+16>>2],c=0;R=C[e+4>>2],W=C[e+8>>2],w=C[e>>2],a[i+20>>2]=0,C[i+8>>2]=h*_(w-F),C[i+16>>2]=v*_(W-y),C[i+12>>2]=d*_(R-p),a[t+4>>2]=c,s=t+-8|0,R=C[G>>2],l=_(m(R))<_(2147483648)?~~R:-2147483648,a[s>>2]=l,s=t+-4|0,R=C[u>>2],l=_(m(R))<_(2147483648)?~~R:-2147483648,a[s>>2]=l,s=t,R=C[n>>2],l=_(m(R))<_(2147483648)?~~R:-2147483648,a[s>>2]=l,t=t+16|0,e=e+16|0,c=c+1|0,(0|c)!=(0|r););(0|r)<2||function A(e,r,i,f){var t=0,n=0,o=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0,C=0;for(u=Y-16|0,Y=u,c=a[e+12>>2],o=c+((i+f|0)/2<<4)|0,C=a[o+8>>2],v=a[o+4>>2],d=a[o>>2],o=i,l=f;;){for(t=(o<<4)+c|0;;){A:{if(n=a[t+4>>2],!((0|n)<(0|v))){if((0|n)!=(0|v))break A;if(n=a[t>>2],!((0|n)<(0|d))&&(0|n)!=(0|d)|a[t+8>>2]>=(0|C))break A}t=t+16|0,o=o+1|0;continue}break}for(s=l<<4;;){A:{if(n=c+s|0,b=a[n+4>>2],!((0|v)<(0|b))){if((0|b)!=(0|v))break A;if(b=a[n>>2],!((0|d)<(0|b))&&(0|b)!=(0|d)|(0|C)>=a[n+8>>2])break A}s=s+-16|0,l=l+-1|0;continue}break}if((0|o)<=(0|l)&&(b=t+8|0,k=a[b+4>>2],c=u+8|0,a[c>>2]=a[b>>2],a[c+4>>2]=k,k=a[t+4>>2],a[u>>2]=a[t>>2],a[u+4>>2]=k,k=a[n+4>>2],a[t>>2]=a[n>>2],a[t+4>>2]=k,t=n+8|0,n=a[t+4>>2],a[b>>2]=a[t>>2],a[b+4>>2]=n,t=a[e+12>>2]+s|0,s=a[u+4>>2],a[t>>2]=a[u>>2],a[t+4>>2]=s,n=a[c+4>>2],t=t+8|0,a[t>>2]=a[c>>2],a[t+4>>2]=n,l=l+-1|0,o=o+1|0),!((0|o)<=(0|l)))break;c=a[e+12>>2]}(0|l)>(0|i)&&A(e,r,i,l),(0|o)<(0|f)&&A(e,r,o,f),Y=u+16|0}(i+24|0,i+8|0,0,r+-1|0)}if(a[A+44>>2]=r,a[A+40>>2]=0,a[A+36>>2]=a[A+32>>2],n=a[A+84>>2],(0|n)<(0|r)){if(a[A+88>>2]<(0|r)){if(r?(c=dA(r<<2),t=a[A+84>>2]):(c=0,t=n),(0|t)>=1)for(e=0;a[e+c>>2]=a[a[A+92>>2]+e>>2],e=e+4|0,t=t+-1|0,t;);e=a[A+92>>2],e&&(o[A+96|0]&&CA(e),a[A+92>>2]=0),a[A+92>>2]=c,a[A+88>>2]=r,f[A+96|0]=1}for(e=n<<2,t=r-n|0;a[a[A+92>>2]+e>>2]=0,e=e+4|0,t=t+-1|0,t;);}if(a[A+84>>2]=r,(0|r)>=1)for(g=0;;){if(n=a[A+40>>2],!(n||(e=a[A+36>>2],e?a[A+36>>2]=a[e+8>>2]:(e=dA(12),a[e+8>>2]=0,t=a[A+44>>2],a[e+4>>2]=t,Z=e,V=dA(B(t,112)),a[Z>>2]=V,t=a[A+32>>2],a[A+32>>2]=e,a[e+8>>2]=t),n=a[e>>2],u=a[e+4>>2],(0|u)<1)))for(e=0,t=n;s=t,t=t+112|0,e=e+1|0,a[s>>2]=(0|e)<(0|u)?t:0,(0|e)!=(0|u););if(a[A+40>>2]=a[n>>2],e=n+8|0,a[e>>2]=0,a[e+4>>2]=0,a[n+16>>2]=0,a[n>>2]=0,a[n+4>>2]=0,a[n+104>>2]=-1,a[e>>2]=0,e=a[i+36>>2]+(g<<4)|0,t=a[e+4>>2],a[n+88>>2]=a[e>>2],a[n+92>>2]=t,e=e+8|0,t=a[e+4>>2],u=n+96|0,a[u>>2]=a[e>>2],a[u+4>>2]=t,a[n+104>>2]=-1,a[a[A+92>>2]+(g<<2)>>2]=n,g=g+1|0,(0|g)==(0|r))break}e=a[i+36>>2],e&&(o[i+40|0]&&CA(e),a[i+36>>2]=0),a[A+116>>2]=0,a[A+120>>2]=0,a[A+100>>2]=-3,a[A+60>>2]=B(r,6),a[A+56>>2]=0,a[A+52>>2]=a[A+48>>2],a[i+36>>2]=0,f[i+40|0]=1,a[i+28>>2]=0,a[i+32>>2]=0,e=i+16|0,a[e>>2]=0,a[e+4>>2]=0,a[i+8>>2]=0,a[i+12>>2]=0,UA(A,0,r,i+8|0),a[A+124>>2]=a[i+8>>2],A=a[i+36>>2],A&&(o[i+40|0]&&CA(A),a[i+36>>2]=0),Y=i+48|0}function jA(A,e,r){var i,f=_(0),t=_(0),n=0;i=Y-16|0,Y=i;A:{e:{r:{i:{if(a[r+100>>2]>=0)C[(a[e+108>>2]<<2)+i>>2]=a[r+88>>2];else if(f=OA(r+24|0),n=r+72|0,t=OA(n),C[(a[e+108>>2]<<2)+i>>2]=f/t,a[r+100>>2]<0)break i;C[(a[e+112>>2]<<2)+i>>2]=a[r+92>>2];break r}if(f=OA(r+40|0),t=OA(n),C[(a[e+112>>2]<<2)+i>>2]=f/t,a[r+100>>2]<0)break e}f=_(a[r+96>>2]);break A}f=_(OA(r+56|0)/OA(r+72|0))}C[(a[e+104>>2]<<2)+i>>2]=f,a[A+12>>2]=0,C[A+8>>2]=_(C[i+8>>2]*C[e+8>>2])+C[e+24>>2],C[A+4>>2]=_(C[i+4>>2]*C[e+4>>2])+C[e+20>>2],C[A>>2]=_(C[i>>2]*C[e>>2])+C[e+16>>2],Y=i+16|0}function OA(A){var e,r,i=0,f=0,t=0,n=_(0);return e=Y-16|0,Y=e,i=a[A+12>>2],f=i,r=a[A+8>>2],(0|i)<0||(0|i)<=0&&!(r>>>0>=0)?(t=a[A+4>>2],i=a[A>>2],A=i,a[e>>2]=0-A,a[e+4>>2]=0-(t+(0>>0)|0),f^=-1,A=!(A|t),t=-1^r,i=A+t|0,i>>>0>>0&&(f=f+1|0),A=e,a[A+8>>2]=i,a[A+12>>2]=f,n=_(-OA(A))):n=_(_(_(+(r>>>0)+4294967296*+(f>>>0))*_(0x10000000000000000))+_(+d[A>>2]+4294967296*+d[A+4>>2])),Y=e+16|0,n}function HA(A,e,r){var i,t=0,n=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0,C=0,g=0,_=0,m=0,R=0,Q=0;i=Y-144|0,Y=i;A:if((0|r)<=0)e=a[A+12>>2],e&&(o[A+16|0]&&CA(e),a[A+12>>2]=0),a[A+12>>2]=0,f[A+16|0]=1,a[A+4>>2]=0,a[A+8>>2]=0,e=a[A+32>>2],e&&(o[A+36|0]&&CA(e),a[A+32>>2]=0),a[A+32>>2]=0,a[A+24>>2]=0,a[A+28>>2]=0,f[A+36|0]=1,e=a[A+52>>2],e&&(o[A+56|0]&&CA(e),a[A+52>>2]=0),a[A+52>>2]=0,a[A+44>>2]=0,a[A+48>>2]=0,f[A+56|0]=1;else{if(f[i+112|0]=1,t=i+88|0,a[t>>2]=0,a[t+4>>2]=256,t=i+72|0,a[t>>2]=0,a[t+4>>2]=256,t=i+56|0,a[t>>2]=0,a[t+4>>2]=256,a[i+108>>2]=0,t=i+100|0,a[t>>2]=0,a[t+4>>2]=0,a[i+80>>2]=0,a[i+84>>2]=0,a[i+64>>2]=0,a[i+68>>2]=0,a[i+48>>2]=0,a[i+52>>2]=0,TA(i+16|0,e,r),r=a[A+4>>2],(0|r)<=-1)for(a[A+8>>2]<=-1&&(e=a[A+12>>2],e&&(o[A+16|0]&&CA(e),a[A+12>>2]=0),f[A+16|0]=1,a[A+8>>2]=0,a[A+12>>2]=0),e=r<<4;t=a[i+4>>2],u=a[A+12>>2]+e|0,b=u,a[b>>2]=a[i>>2],a[b+4>>2]=t,t=i+8|0,b=a[t+4>>2],u=u+8|0,a[u>>2]=a[t>>2],a[u+4>>2]=b,e=e+16|0,t=r+1|0,u=t>>>0>=r>>>0,r=t,u;);if(a[A+4>>2]=0,a[i+8>>2]=0,a[i>>2]=0,a[i+4>>2]=0,r=a[A+24>>2],(0|r)<=-1)for(a[A+28>>2]<=-1&&(e=a[A+32>>2],e&&(o[A+36|0]&&CA(e),a[A+32>>2]=0),a[A+28>>2]=0,a[A+32>>2]=0,f[A+36|0]=1),e=B(r,12);u=a[i+4>>2],t=a[A+32>>2]+e|0,a[t>>2]=a[i>>2],a[t+4>>2]=u,a[t+8>>2]=a[i+8>>2],e=e+12|0,t=r+1|0,u=t>>>0>=r>>>0,r=t,u;);if(a[A+24>>2]=0,r=a[A+44>>2],(0|r)<=-1&&(e=a[A+52>>2],a[A+48>>2]<=-1?(!e|!o[A+56|0]||CA(e),f[A+56|0]=1,a[A+48>>2]=0,a[A+52>>2]=0,t=0):t=e,e=r<<2,X(t+e|0,0,0-e|0)),a[A+44>>2]=0,e=a[i+140>>2],!(a[e+104>>2]>-1)){for(a[e+104>>2]=0,k=dA(4),a[k>>2]=e,t=1,b=1,u=k;;){if(C=a[(m<<2)+k>>2],jA(i,i+16|0,C),e=a[A+4>>2],(0|e)==a[A+8>>2]&&(n=e?e<<1:1,!((0|e)>=(0|n)))){if(n?(c=dA(n<<4),e=a[A+4>>2]):c=0,(0|e)>=1)for(r=0;l=a[A+12>>2]+r|0,v=a[l+4>>2],d=r+c|0,a[d>>2]=a[l>>2],a[d+4>>2]=v,l=l+8|0,v=a[l+4>>2],d=d+8|0,a[d>>2]=a[l>>2],a[d+4>>2]=v,r=r+16|0,e=e+-1|0,e;);e=a[A+12>>2],e&&(o[A+16|0]&&CA(e),a[A+12>>2]=0),a[A+12>>2]=c,f[A+16|0]=1,a[A+8>>2]=n,e=a[A+4>>2]}if(r=a[i+4>>2],e=a[A+12>>2]+(e<<4)|0,a[e>>2]=a[i>>2],a[e+4>>2]=r,R=i+8|0,r=R,n=a[r+4>>2],e=e+8|0,a[e>>2]=a[r>>2],a[e+4>>2]=n,a[A+4>>2]=a[A+4>>2]+1,d=a[C+8>>2],d){for(C=-1,l=d,v=-1;;){if(r=a[l+20>>2],(0|r)<=-1){if(c=a[A+24>>2],a[R>>2]=0,a[i>>2]=0,a[i+4>>2]=0,r=c,(0|r)==a[A+28>>2]&&(s=r?c<<1:1,!((0|r)>=(0|s)))){if(s?(n=dA(B(s,12)),e=a[A+24>>2]):(n=0,e=c),(0|e)>=1)for(r=0;g=a[A+32>>2]+r|0,Q=a[g+4>>2],_=r+n|0,a[_>>2]=a[g>>2],a[_+4>>2]=Q,a[_+8>>2]=a[g+8>>2],r=r+12|0,e=e+-1|0,e;);e=a[A+32>>2],e&&(o[A+36|0]&&CA(e),a[A+32>>2]=0),a[A+32>>2]=n,f[A+36|0]=1,a[A+28>>2]=s,r=a[A+24>>2]}if(e=a[A+32>>2]+B(r,12)|0,r=a[i+4>>2],a[e>>2]=a[i>>2],a[e+4>>2]=r,a[e+8>>2]=a[R>>2],e=a[A+24>>2]+1|0,a[A+24>>2]=e,a[R>>2]=0,a[i>>2]=0,a[i+4>>2]=0,a[A+28>>2]==(0|e)&&(s=e?e<<1:1,!((0|e)>=(0|s)))){if(s?(n=dA(B(s,12)),e=a[A+24>>2]):n=0,(0|e)>=1)for(r=0;g=a[A+32>>2]+r|0,Q=a[g+4>>2],_=r+n|0,a[_>>2]=a[g>>2],a[_+4>>2]=Q,a[_+8>>2]=a[g+8>>2],r=r+12|0,e=e+-1|0,e;);e=a[A+32>>2],e&&(o[A+36|0]&&CA(e),a[A+32>>2]=0),a[A+32>>2]=n,f[A+36|0]=1,a[A+28>>2]=s,e=a[A+24>>2]}if(r=a[i+4>>2],e=a[A+32>>2]+B(e,12)|0,a[e>>2]=a[i>>2],a[e+4>>2]=r,a[e+8>>2]=a[R>>2],a[A+24>>2]=a[A+24>>2]+1,a[l+20>>2]=c,g=c+1|0,a[a[l+8>>2]+20>>2]=g,_=a[A+32>>2],s=_+B(c,12)|0,a[s+4>>2]=1,a[s+16>>2]=-1,c=a[l+12>>2],e=a[c+104>>2],(0|e)>-1)c=t,t=e;else{if(a[c+104>>2]=t,(0|t)!=(0|b)||(n=b?b<<1:1,(0|b)>=(0|n)))e=u,n=b;else{e=n?dA(n<<2):0;e:{if((0|b)>=1)for(r=e;a[r>>2]=a[k>>2],r=r+4|0,k=k+4|0,b=b+-1|0,b;);else if(!k)break e;CA(u)}k=e}a[(t<<2)+k>>2]=c,c=t+1|0,u=e,b=n}a[8+(_+B(g,12)|0)>>2]=m,a[s+8>>2]=t,t=c,r=a[l+20>>2]}if(e=r,(0|C)>=0&&(a[a[A+32>>2]+B(r,12)>>2]=C-r,e=v),C=r,v=e,l=a[l>>2],(0|d)==(0|l))break}a[a[A+32>>2]+B(e,12)>>2]=r-e}if(m=m+1|0,!((0|m)<(0|t)))break}for(b=0;;){if(c=a[a[(b<<2)+k>>2]+8>>2],c)for(e=c;;){if(r=a[e+20>>2],(0|r)>=0){if(t=a[A+44>>2],(0|t)==a[A+48>>2]&&(v=t?t<<1:1,!((0|t)>=(0|v)))){v?(C=dA(v<<2),t=a[A+44>>2]):C=0,n=a[A+52>>2];e:{if((0|t)>=1)for(r=C,l=n;a[r>>2]=a[l>>2],r=r+4|0,l=l+4|0,t=t+-1|0,t;);else if(!n)break e;o[A+56|0]&&CA(n),a[A+52>>2]=0,t=a[A+44>>2]}a[A+48>>2]=v,a[A+52>>2]=C,f[A+56|0]=1,r=a[e+20>>2]}for(a[a[A+52>>2]+(t<<2)>>2]=r,a[A+44>>2]=a[A+44>>2]+1,r=e;a[r+20>>2]=-1,r=a[a[r+8>>2]+4>>2],(0|r)!=(0|e););}if(e=a[e>>2],(0|c)==(0|e))break}if(b=b+1|0,(0|b)==(0|m))break}k&&CA(u)}for(A=a[i+108>>2],A&&(o[i+112|0]&&CA(A),a[i+108>>2]=0),a[i+108>>2]=0,f[i+112|0]=1,a[i+100>>2]=0,a[i+104>>2]=0;A=a[i+80>>2],A;)a[i+80>>2]=a[A+8>>2],CA(a[A>>2]),CA(A);for(;A=a[i+64>>2],A;)a[i+64>>2]=a[A+8>>2],CA(a[A>>2]),CA(A);for(;;){if(A=a[i+48>>2],!A)break A;a[i+48>>2]=a[A+8>>2],CA(a[A>>2]),CA(A)}}Y=i+144|0}function zA(A){return DA(A),a[A+56>>2]=0,a[A>>2]=7108,A}function PA(A,e){var r=0,i=0,t=0,n=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0,C=0,g=0,_=0,m=0;if(a[A+8>>2]<(0|e)){if(s=e?dA(B(e,36)):0,C=a[A+4>>2],!((0|C)<1)){for(;;){if(r=B(k,36),t=r+s|0,a[t+4>>2]=0,a[t+8>>2]=0,f[t+16|0]=1,a[t+12>>2]=0,v=t+4|0,l=r+a[A+12>>2]|0,b=a[l+4>>2],(0|b)>=1){m=t+8|0,g=t+16|0,_=b<<2,n=dA(_),d=t+12|0,u=a[d>>2],c=a[v>>2];A:{if((0|c)>=1)for(i=n,r=u;a[i>>2]=a[r>>2],i=i+4|0,r=r+4|0,c=c+-1|0,c;);else if(!u)break A;o[0|g]&&CA(u)}for(a[d>>2]=n,f[0|g]=1,a[m>>2]=b,X(n,0,_),a[v>>2]=b,i=a[l+12>>2],r=a[d>>2];a[r>>2]=a[i>>2],r=r+4|0,i=i+4|0,b=b+-1|0,b;);}else a[v>>2]=b;if(r=a[l+24>>2],a[t+20>>2]=a[l+20>>2],a[t+24>>2]=r,i=l+28|0,n=a[i+4>>2],r=t+28|0,a[r>>2]=a[i>>2],a[r+4>>2]=n,k=k+1|0,(0|k)==(0|C))break}if(c=a[A+4>>2],!((0|c)<1))for(r=8;i=a[A+12>>2]+r|0,u=i+-4|0,n=i+4|0,t=a[n>>2],t&&(o[i+8|0]&&CA(t),a[n>>2]=0),a[u>>2]=0,a[n>>2]=0,a[i>>2]=0,f[i+8|0]=1,r=r+36|0,c=c+-1|0,c;);}r=a[A+12>>2],r&&(o[A+16|0]&&CA(r),a[A+12>>2]=0),a[A+12>>2]=s,f[A+16|0]=1,a[A+8>>2]=e}}function KA(A,e,r){var i,t=0,n=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=_(0),g=0,R=_(0),Q=_(0),h=_(0),G=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),V=_(0),N=0,I=_(0);i=Y-32|0,Y=i,d=C[r+8>>2],_(m(d))>_(.7071067690849304)?(Q=C[r+4>>2],h=_(_(d*d)+_(Q*Q)),R=_(_(1)/_(y(h))),F=_(h*R),p=C[r>>2],h=_(-_(d*R)),w=_(p*h),Q=_(Q*R),G=_(-_(p*Q)),p=_(0)):(h=C[r>>2],Q=C[r+4>>2],p=_(_(h*h)+_(Q*Q)),R=_(_(1)/_(y(p))),w=_(p*R),p=_(-_(Q*R)),G=_(d*p),h=_(h*R),F=_(-_(d*h)),Q=_(0)),c=a[A+4>>2];A:if((0|c)>=2){for(n=a[A+12>>2];t=n+u|0,l=t+8|0,_(_(_(p*C[t>>2])+_(h*C[t+4>>2]))+_(Q*C[l>>2]))<_(_(_(p*C[n>>2])+_(h*C[n+4>>2]))+_(Q*C[n+8>>2]))&&(s=n+16|0,v=a[s+4>>2],c=i+24|0,a[c>>2]=a[s>>2],a[c+4>>2]=v,g=n+8|0,v=a[g+4>>2],k=i+16|0,a[k>>2]=a[g>>2],a[k+4>>2]=v,v=a[n+4>>2],a[i+8>>2]=a[n>>2],a[i+12>>2]=v,v=a[t+4>>2],a[n>>2]=a[t>>2],a[n+4>>2]=v,n=a[l+4>>2],a[g>>2]=a[l>>2],a[g+4>>2]=n,n=t+16|0,t=a[n+4>>2],a[s>>2]=a[n>>2],a[s+4>>2]=t,l=a[i+12>>2],n=a[A+12>>2]+u|0,t=n,a[t>>2]=a[i+8>>2],a[t+4>>2]=l,l=a[c+4>>2],t=t+16|0,a[t>>2]=a[c>>2],a[t+4>>2]=l,t=a[k+4>>2],n=n+8|0,a[n>>2]=a[k>>2],a[n+4>>2]=t,n=a[A+12>>2],c=a[A+4>>2]),u=u+24|0,b=b+1|0,(0|b)<(0|c););if(a[n+16>>2]=-246811958,(0|c)>=2)for(u=c+-1|0,t=n+40|0,D=C[n+8>>2],E=C[n>>2],V=C[n+4>>2];R=_(0),g=t,d=_(C[t+-16>>2]-E),Z=_(C[t+-12>>2]-V),I=_(C[t+-8>>2]-D),W=_(_(_(F*d)+_(G*Z))+_(w*I)),d=_(_(_(p*d)+_(h*Z))+_(Q*I)),_(_(W*W)+_(d*d))<_(1.1920928955078125e-7)||(R=_(m(W)),d>=_(0)?(d=_(_(d-R)/_(d+R)),R=_(.7853981852531433)):(d=_(_(d+R)/_(R-d)),R=_(2.356194496154785)),d=_(R+_(d*_(-.7853981852531433))),R=W<_(0)?_(-d):d),C[g>>2]=R,t=t+24|0,u=u+-1|0,u;);if(b=n+8|0,u=a[b+4>>2],t=i+16|0,a[t>>2]=a[b>>2],a[t+4>>2]=u,t=a[n+4>>2],a[i+8>>2]=a[n>>2],a[i+12>>2]=t,function A(e,r,i,f){var t=_(0),n=0,o=0,c=0,b=_(0),l=0,u=0,s=0,k=0,v=0,d=_(0),g=0,m=_(0),R=_(0),Q=_(0),h=_(0),G=0,y=0,p=0,F=0,W=_(0),w=_(0),D=_(0),E=0;for(s=Y-32|0,Y=s,l=a[e+12>>2],o=l+B((i+f|0)/2|0,24)|0,F=a[o+20>>2],m=C[o+16>>2],W=C[o+8>>2],w=C[o+4>>2],D=C[o>>2],o=i,u=f;;){for(R=C[r>>2],b=_(D-R),t=_(b*b),Q=C[r+4>>2],b=_(w-Q),t=_(t+_(b*b)),h=C[r+8>>2],b=_(W-h),b=_(t+_(b*b)),n=20+(B(o,24)+l|0)|0;;){e:{t=C[n+-4>>2];r:if(t==m){if(t=_(C[n+-20>>2]-R),d=_(t*t),t=_(C[n+-16>>2]-Q),d=_(d+_(t*t)),t=_(C[n+-12>>2]-h),t=_(d+_(t*t)),t!=b){if(t>2]>=(0|F))break e}else if(!(t>2];r:if(m==t){if(t=_(C[c>>2]-R),d=_(t*t),t=_(C[c+4>>2]-Q),d=_(d+_(t*t)),t=_(C[c+8>>2]-h),t=_(d+_(t*t)),b!=t){if(b=a[c+20>>2])break e}else if(!(m>2],l=s+24|0,a[l>>2]=a[g>>2],a[l+4>>2]=v,g=n+8|0,E=a[g+4>>2],p=s+16|0,v=p,a[v>>2]=a[g>>2],a[v+4>>2]=E,v=a[n+4>>2],a[s+8>>2]=a[n>>2],a[s+12>>2]=v,v=a[c+4>>2],a[n>>2]=a[c>>2],a[n+4>>2]=v,n=c+8|0,c=a[n+4>>2],a[g>>2]=a[n>>2],a[g+4>>2]=c,n=a[G+4>>2],a[y>>2]=a[G>>2],a[y+4>>2]=n,n=a[e+12>>2]+k|0,k=a[s+12>>2],a[n>>2]=a[s+8>>2],a[n+4>>2]=k,k=a[l+4>>2],c=n+16|0,a[c>>2]=a[l>>2],a[c+4>>2]=k,c=a[p+4>>2],n=n+8|0,a[n>>2]=a[p>>2],a[n+4>>2]=c,u=u+-1|0,o=o+1|0),!((0|o)<=(0|u)))break;l=a[e+12>>2]}(0|u)>(0|i)&&A(e,r,i,u),(0|o)<(0|f)&&A(e,r,o,f),Y=s+32|0}(A,i+8|0,1,c+-1|0),t=a[A+12>>2],b=a[e+4>>2],(0|b)==a[e+8>>2]&&(u=b?b<<1:1,!((0|b)>=(0|u)))){if(u?(c=dA(B(u,24)),b=a[e+4>>2]):c=0,(0|b)>=1)for(n=0;g=a[e+12>>2]+n|0,s=g,v=a[s+4>>2],l=n+c|0,a[l>>2]=a[s>>2],a[l+4>>2]=v,s=s+16|0,v=a[s+4>>2],k=l+16|0,a[k>>2]=a[s>>2],a[k+4>>2]=v,s=g+8|0,k=a[s+4>>2],l=l+8|0,a[l>>2]=a[s>>2],a[l+4>>2]=k,n=n+24|0,b=b+-1|0,b;);n=a[e+12>>2],n&&(o[e+16|0]&&CA(n),a[e+12>>2]=0),a[e+12>>2]=c,f[e+16|0]=1,a[e+8>>2]=u,b=a[e+4>>2]}if(n=a[e+12>>2]+B(b,24)|0,b=a[t+4>>2],a[n>>2]=a[t>>2],a[n+4>>2]=b,b=t+16|0,u=a[b+4>>2],c=n+16|0,a[c>>2]=a[b>>2],a[c+4>>2]=u,t=t+8|0,c=a[t+4>>2],n=n+8|0,a[n>>2]=a[t>>2],a[n+4>>2]=c,t=a[e+4>>2]+1|0,a[e+4>>2]=t,b=a[A+12>>2]+24|0,a[e+8>>2]==(0|t)&&(u=t?t<<1:1,!((0|t)>=(0|u)))){if(u?(c=dA(B(u,24)),t=a[e+4>>2]):c=0,(0|t)>=1)for(n=0;g=a[e+12>>2]+n|0,s=g,v=a[s+4>>2],l=n+c|0,a[l>>2]=a[s>>2],a[l+4>>2]=v,s=s+16|0,v=a[s+4>>2],k=l+16|0,a[k>>2]=a[s>>2],a[k+4>>2]=v,s=g+8|0,k=a[s+4>>2],l=l+8|0,a[l>>2]=a[s>>2],a[l+4>>2]=k,n=n+24|0,t=t+-1|0,t;);n=a[e+12>>2],n&&(o[e+16|0]&&CA(n),a[e+12>>2]=0),a[e+12>>2]=c,f[e+16|0]=1,a[e+8>>2]=u,t=a[e+4>>2]}if(c=a[b+4>>2],n=a[e+12>>2]+B(t,24)|0,t=n,a[t>>2]=a[b>>2],a[t+4>>2]=c,c=b+16|0,u=a[c+4>>2],t=t+16|0,a[t>>2]=a[c>>2],a[t+4>>2]=u,t=b+8|0,c=a[t+4>>2],n=n+8|0,a[n>>2]=a[t>>2],a[n+4>>2]=c,t=a[e+4>>2]+1|0,a[e+4>>2]=t,2==a[A+4>>2])break A;for(s=2;;){e:if(!((0|t)<2)){for(b=B(t,48),u=t<<1,k=a[e+12>>2],n=(k+B(t,24)|0)-48|0,l=a[A+12>>2]+B(s,24)|0,d=C[l+8>>2],R=C[l+4>>2],h=C[l>>2],Q=C[r+8>>2],p=C[r+4>>2],W=C[r>>2];;){if(F=C[n>>2],w=_(F-C[n+24>>2]),G=C[n+4>>2],D=_(G-R),G=_(G-C[n+28>>2]),F=_(F-h),Z=_(_(_(w*D)-_(G*F))*Q),V=G,G=C[n+8>>2],E=_(G-d),G=_(G-C[n+32>>2]),!(_(Z+_(_(W*_(_(V*E)-_(G*D)))+_(p*_(_(G*F)-_(w*E)))))>_(0))){if(t=t+-1|0,a[e+4>>2]=t,n=n+-24|0,b=b+-48|0,u=u+-2|0,(0|t)>1)continue;break e}break}if(!(a[e+8>>2]!=(0|t)|(0|t)>=(0|u))){if(k=dA(b),c=a[e+4>>2],(0|c)>=1)for(n=0;v=a[e+12>>2]+n|0,b=v,N=a[b+4>>2],t=n+k|0,a[t>>2]=a[b>>2],a[t+4>>2]=N,b=b+16|0,N=a[b+4>>2],g=t+16|0,a[g>>2]=a[b>>2],a[g+4>>2]=N,b=v+8|0,g=a[b+4>>2],t=t+8|0,a[t>>2]=a[b>>2],a[t+4>>2]=g,n=n+24|0,c=c+-1|0,c;);n=a[e+12>>2],n&&(o[e+16|0]&&CA(n),a[e+12>>2]=0),a[e+12>>2]=k,f[e+16|0]=1,a[e+8>>2]=u,t=a[e+4>>2]}c=a[l+4>>2],n=B(t,24)+k|0,t=n,a[t>>2]=a[l>>2],a[t+4>>2]=c,c=l+16|0,b=a[c+4>>2],t=t+16|0,a[t>>2]=a[c>>2],a[t+4>>2]=b,t=l+8|0,c=a[t+4>>2],n=n+8|0,a[n>>2]=a[t>>2],a[n+4>>2]=c,t=a[e+4>>2]+1|0,a[e+4>>2]=t}if(1==(0|t)){if(t=a[A+12>>2]+B(s,24)|0,n=1,1==a[e+8>>2]){if(c=dA(48),b=a[e+4>>2],(0|b)>=1)for(n=0;g=a[e+12>>2]+n|0,l=g,v=a[l+4>>2],u=n+c|0,a[u>>2]=a[l>>2],a[u+4>>2]=v,l=l+16|0,v=a[l+4>>2],k=u+16|0,a[k>>2]=a[l>>2],a[k+4>>2]=v,l=g+8|0,k=a[l+4>>2],u=u+8|0,a[u>>2]=a[l>>2],a[u+4>>2]=k,n=n+24|0,b=b+-1|0,b;);n=a[e+12>>2],n&&(o[e+16|0]&&CA(n),a[e+12>>2]=0),a[e+12>>2]=c,f[e+16|0]=1,a[e+8>>2]=2,n=a[e+4>>2]}b=a[t+4>>2],n=a[e+12>>2]+B(n,24)|0,a[n>>2]=a[t>>2],a[n+4>>2]=b,b=t+16|0,u=a[b+4>>2],c=n+16|0,a[c>>2]=a[b>>2],a[c+4>>2]=u,t=t+8|0,c=a[t+4>>2],n=n+8|0,a[n>>2]=a[t>>2],a[n+4>>2]=c,t=a[e+4>>2]+1|0,a[e+4>>2]=t}if(s=s+1|0,(0|s)==a[A+4>>2])break}}else if(1==(0|c))for(t=a[e+4>>2];;){if(r=a[A+12>>2],a[e+8>>2]==(0|t)&&(b=t?t<<1:1,!((0|t)>=(0|b)))){if(b?(c=dA(B(b,24)),t=a[e+4>>2]):c=0,(0|t)>=1)for(n=0;g=a[e+12>>2]+n|0,s=g,v=a[s+4>>2],l=n+c|0,a[l>>2]=a[s>>2],a[l+4>>2]=v,s=s+16|0,v=a[s+4>>2],k=l+16|0,a[k>>2]=a[s>>2],a[k+4>>2]=v,s=g+8|0,k=a[s+4>>2],l=l+8|0,a[l>>2]=a[s>>2],a[l+4>>2]=k,n=n+24|0,t=t+-1|0,t;);n=a[e+12>>2],n&&(o[e+16|0]&&CA(n),a[e+12>>2]=0),a[e+12>>2]=c,f[e+16|0]=1,a[e+8>>2]=b,t=a[e+4>>2]}if(c=a[r+4>>2],n=a[e+12>>2]+B(t,24)|0,t=n,a[t>>2]=a[r>>2],a[t+4>>2]=c,c=r+16|0,b=a[c+4>>2],t=t+16|0,a[t>>2]=a[c>>2],a[t+4>>2]=b,r=r+8|0,t=a[r+4>>2],n=n+8|0,a[n>>2]=a[r>>2],a[n+4>>2]=t,t=a[e+4>>2]+1|0,a[e+4>>2]=t,u=u+1|0,!((0|u)>2]))break}Y=i+32|0}function LA(A,e){var r,i,t=0,n=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0,C=0;if(u=a[A+4>>2],(0|u)==a[A+8>>2]&&(PA(A,u?u<<1:1),u=a[A+4>>2]),i=a[A+12>>2],t=i+B(u,36)|0,a[t+4>>2]=0,a[t+8>>2]=0,f[t+16|0]=1,a[t+12>>2]=0,r=t+4|0,c=a[e+4>>2],(0|c)>=1){C=t+8|0,v=t+16|0,d=c<<2,n=dA(d),k=t+12|0,t=a[k>>2],s=a[r>>2];A:{if((0|s)>=1)for(b=n,l=t;a[b>>2]=a[l>>2],b=b+4|0,l=l+4|0,s=s+-1|0,s;);else if(!t)break A;o[0|v]&&CA(t)}for(a[k>>2]=n,f[0|v]=1,a[C>>2]=c,X(n,0,d),a[r>>2]=c,b=a[e+12>>2],l=a[k>>2];a[l>>2]=a[b>>2],l=l+4|0,b=b+4|0,c=c+-1|0,c;);}else a[r>>2]=c;t=a[e+24>>2],n=B(u,36)+i|0,a[n+20>>2]=a[e+20>>2],a[n+24>>2]=t,t=e+28|0,e=a[t+4>>2],n=n+28|0,a[n>>2]=a[t>>2],a[n+4>>2]=e,a[A+4>>2]=a[A+4>>2]+1}function qA(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0);f=_(Qt[a[a[A>>2]+48>>2]](A)),F=C[e+52>>2],o=C[e+24>>2],c=C[e+20>>2],b=C[e+56>>2],l=C[e+40>>2],u=C[A+68>>2],d=C[A+84>>2],g=C[e+36>>2],t=C[A- -64>>2],B=C[A+80>>2],W=C[e+48>>2],R=C[e+8>>2],Q=C[e>>2],h=C[e+4>>2],G=C[e+16>>2],y=C[e+32>>2],n=C[A+60>>2],p=C[A+76>>2],a[r+12>>2]=0,s=b,b=_(_(p+n)*_(.5)),k=_(_(B+t)*_(.5)),v=_(_(d+u)*_(.5)),s=_(s+_(_(_(y*b)+_(g*k))+_(l*v))),n=_(f+_(_(p-n)*_(.5))),t=_(f+_(_(B-t)*_(.5))),f=_(f+_(_(d-u)*_(.5))),l=_(_(_(n*_(m(y)))+_(t*_(m(g))))+_(f*_(m(l)))),C[r+8>>2]=s-l,u=_(F+_(_(_(b*G)+_(k*c))+_(v*o))),o=_(_(_(n*_(m(G)))+_(t*_(m(c))))+_(f*_(m(o)))),C[r+4>>2]=u-o,c=_(W+_(_(_(b*Q)+_(k*h))+_(v*R))),f=_(_(_(n*_(m(Q)))+_(t*_(m(h))))+_(f*_(m(R)))),C[r>>2]=c-f,a[i+12>>2]=0,C[i+8>>2]=l+s,C[i+4>>2]=o+u,C[i>>2]=f+c}function $A(A,e,r,i){A|=0,e|=0,r|=0,i|=0,Qt[a[a[A>>2]+80>>2]](A,e,r,i)}function Ae(A){var e;return A|=0,a[A>>2]=7108,e=a[A+56>>2],e&&(Qt[a[a[e>>2]>>2]](e),CA(a[A+56>>2])),0|A}function ee(A,e){var r=_(0),i=_(0),f=_(0),t=_(0),n=_(0),a=0;return r=C[A+48>>2],i=C[A+52>>2],f=C[A+56>>2],t=C[A+60>>2],n=_(C[A+64>>2]+C[e+64>>2]),!(_(_(_(_(_(C[e>>2]*r)+_(C[e+4>>2]*i))+_(C[e+8>>2]*f))-t)-n)>_(0)^1|_(_(_(_(_(r*C[e+16>>2])+_(i*C[e+20>>2]))+_(f*C[e+24>>2]))-t)-n)>_(0)^1)&&(a=0,_(_(_(_(_(r*C[e+32>>2])+_(i*C[e+36>>2]))+_(f*C[e+40>>2]))-t)-n)>_(0))||(r=C[e+48>>2],i=C[e+52>>2],f=C[e+56>>2],t=C[e+60>>2],a=_(_(_(_(_(C[A>>2]*r)+_(C[A+4>>2]*i))+_(C[A+8>>2]*f))-t)-n)>_(0)^1|_(_(_(_(_(r*C[A+16>>2])+_(i*C[A+20>>2]))+_(f*C[A+24>>2]))-t)-n)>_(0)^1|_(_(_(_(_(r*C[A+32>>2])+_(i*C[A+36>>2]))+_(f*C[A+40>>2]))-t)-n)>_(0)^1),a}function re(A,e,r){var i,f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=0;return i=Y-528|0,Y=i,b=C[A+20>>2],n=_(b-C[A+4>>2]),t=C[A+56>>2],l=C[A+24>>2],o=_(l-C[A+8>>2]),c=C[A+52>>2],f=_(_(n*t)-_(o*c)),v=f,u=C[A+16>>2],s=_(u-C[A>>2]),k=_(s*c),c=C[A+48>>2],n=_(k-_(n*c)),k=_(f*f),f=_(_(o*c)-_(s*t)),t=_(_(1)/_(y(_(_(n*n)+_(k+_(f*f)))))),o=_(v*t),C[i+256>>2]=o,f=_(f*t),C[i+260>>2]=f,n=_(n*t),C[i+264>>2]=n,C[i+268>>2]=_(l*n)+_(_(u*o)+_(b*f)),e=function(A,e,r,i,f){var t=0,n=_(0),o=_(0),c=_(0),b=0,l=_(0),u=0,s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=0,m=_(0),R=0;s=C[e>>2],n=C[A>>2],o=C[A+4>>2],c=C[A+8>>2],l=C[A+12>>2],k=_(_(_(_(s*n)+_(C[e+4>>2]*o))+_(C[e+8>>2]*c))-l),b=k>_(1.1920928955078125e-7),b||(t=a[e+4>>2],a[f>>2]=a[e>>2],a[f+4>>2]=t,u=e+8|0,B=a[u+4>>2],t=f+8|0,a[t>>2]=a[u>>2],a[t+4>>2]=B,l=C[A+12>>2],c=C[A+8>>2],o=C[A+4>>2],n=C[A>>2],t=1),v=C[r>>2],d=C[r+4>>2],g=C[r+8>>2],n=_(_(_(_(v*n)+_(d*o))+_(g*c))-l),(n>_(1.1920928955078125e-7)|0)!=(0|b)&&(l=C[e+4>>2],m=C[e+8>>2],b=(t<<4)+f|0,a[b+12>>2]=0,o=_(_(-k)/_(n-k)),c=_(_(1)-o),C[b+8>>2]=_(g*o)+_(m*c),C[b+4>>2]=_(d*o)+_(c*l),C[b>>2]=_(v*o)+_(s*c),t=t+1|0),b=n>_(1.1920928955078125e-7),b||(R=a[r+4>>2],u=(t<<4)+f|0,a[u>>2]=a[r>>2],a[u+4>>2]=R,B=r+8|0,R=a[B+4>>2],u=u+8|0,a[u>>2]=a[B>>2],a[u+4>>2]=R,t=t+1|0),l=C[i>>2],s=C[i+4>>2],v=C[i+8>>2],o=_(_(_(_(l*C[A>>2])+_(s*C[A+4>>2]))+_(v*C[A+8>>2]))-C[A+12>>2]),(o>_(1.1920928955078125e-7)|0)!=(0|b)&&(d=C[r>>2],g=C[r+4>>2],m=C[r+8>>2],A=(t<<4)+f|0,a[A+12>>2]=0,n=_(_(-n)/_(o-n)),c=_(_(1)-n),C[A+8>>2]=_(v*n)+_(m*c),C[A+4>>2]=_(s*n)+_(c*g),C[A>>2]=_(l*n)+_(c*d),t=t+1|0);A:{e:{r:{if(!(o>_(1.1920928955078125e-7))){if(r=a[i+4>>2],A=(t<<4)+f|0,a[A>>2]=a[i>>2],a[A+4>>2]=r,r=i+8|0,b=a[r+4>>2],A=A+8|0,a[A>>2]=a[r>>2],a[A+4>>2]=b,t=t+1|0,k>_(1.1920928955078125e-7))break r;break e}if(k>_(1.1920928955078125e-7))break A}if(c=C[i>>2],l=C[e>>2],s=C[i+4>>2],v=C[e+4>>2],n=C[i+8>>2],d=C[e+8>>2],A=(t<<4)+f|0,a[A+12>>2]=0,g=n,n=_(_(-o)/_(k-o)),o=_(_(1)-n),C[A+8>>2]=_(g*o)+_(n*d),C[A+4>>2]=_(o*s)+_(n*v),C[A>>2]=_(o*c)+_(n*l),t=t+1|0,k>_(1.1920928955078125e-7))break A}r=a[e+4>>2],A=(t<<4)+f|0,a[A>>2]=a[e>>2],a[A+4>>2]=r,e=e+8|0,r=a[e+4>>2],A=A+8|0,a[A>>2]=a[e>>2],a[A+4>>2]=r,t=t+1|0}return t}(i+256|0,e,e+16|0,e+32|0,i+272|0),d=0,e&&(b=C[A+40>>2],t=_(b-C[A+24>>2]),n=C[A+48>>2],l=C[A+32>>2],o=_(l-C[A+16>>2]),c=C[A+56>>2],f=_(_(t*n)-_(o*c)),v=f,k=o,o=C[A+52>>2],u=C[A+36>>2],s=_(u-C[A+20>>2]),n=_(_(k*o)-_(s*n)),t=_(_(s*c)-_(t*o)),f=_(_(1)/_(y(_(_(n*n)+_(_(t*t)+_(f*f)))))),o=_(v*f),C[i+260>>2]=o,t=_(t*f),C[i+256>>2]=t,f=_(n*f),C[i+264>>2]=f,C[i+268>>2]=_(b*f)+_(_(l*t)+_(u*o)),e=ie(i+256|0,i+272|0,e,i),d=0,e&&(b=C[A+8>>2],t=_(b-C[A+40>>2]),n=C[A+48>>2],l=C[A>>2],o=_(l-C[A+32>>2]),c=C[A+56>>2],f=_(_(t*n)-_(o*c)),v=f,k=o,o=C[A+52>>2],u=C[A+4>>2],s=_(u-C[A+36>>2]),n=_(_(k*o)-_(s*n)),t=_(_(s*c)-_(t*o)),f=_(_(1)/_(y(_(_(n*n)+_(_(t*t)+_(f*f)))))),o=_(v*f),C[i+260>>2]=o,t=_(t*f),C[i+256>>2]=t,f=_(n*f),C[i+264>>2]=f,C[i+268>>2]=_(b*f)+_(_(l*t)+_(u*o)),d=ie(i+256|0,i,e,r))),A=d,Y=i+528|0,A}function ie(A,e,r,i){var f=0,t=0,n=_(0),o=_(0),c=_(0),b=0,l=0,u=_(0),s=_(0),k=_(0),v=_(0),d=0,g=0,B=_(0),m=_(0),R=_(0);if(c=_(_(_(_(C[e>>2]*C[A>>2])+_(C[e+4>>2]*C[A+4>>2]))+_(C[e+8>>2]*C[A+8>>2]))-C[A+12>>2]),c>_(1.1920928955078125e-7)||(f=a[e+4>>2],a[i>>2]=a[e>>2],a[i+4>>2]=f,b=e+8|0,t=a[b+4>>2],f=i+8|0,a[f>>2]=a[b>>2],a[f+4>>2]=t,t=1),(0|r)<2)n=c;else for(d=r+-1|0,f=e,o=c;b=f+16|0,s=C[b>>2],k=C[f+20>>2],g=f+24|0,v=C[g>>2],n=_(_(_(_(s*C[A>>2])+_(k*C[A+4>>2]))+_(v*C[A+8>>2]))-C[A+12>>2]),l=n>_(1.1920928955078125e-7),(0|l)!=(o>_(1.1920928955078125e-7)|0)&&(B=C[f+4>>2],m=C[f+8>>2],R=C[f>>2],f=(t<<4)+i|0,a[f+12>>2]=0,o=_(_(-o)/_(n-o)),u=_(_(1)-o),C[f+8>>2]=_(v*o)+_(m*u),C[f+4>>2]=_(k*o)+_(u*B),C[f>>2]=_(s*o)+_(u*R),t=t+1|0),l||(l=a[b+4>>2],f=(t<<4)+i|0,a[f>>2]=a[b>>2],a[f+4>>2]=l,l=a[g+4>>2],f=f+8|0,a[f>>2]=a[g>>2],a[f+4>>2]=l,t=t+1|0),f=b,o=n,d=d+-1|0,d;);return f=c>_(1.1920928955078125e-7),(0|f)!=(n>_(1.1920928955078125e-7)|0)&&(A=(r+-1<<4)+e|0,o=C[A>>2],u=C[A+4>>2],s=C[A+8>>2],k=C[e>>2],v=C[e+4>>2],B=C[e+8>>2],A=(t<<4)+i|0,a[A+12>>2]=0,n=_(_(-n)/_(c-n)),c=_(_(1)-n),C[A+8>>2]=_(s*c)+_(n*B),C[A+4>>2]=_(c*u)+_(n*v),C[A>>2]=_(c*o)+_(n*k),t=t+1|0),f||(r=a[e+4>>2],A=(t<<4)+i|0,a[A>>2]=a[e>>2],a[A+4>>2]=r,e=e+8|0,r=a[e+4>>2],A=A+8|0,a[A>>2]=a[e>>2],a[A+4>>2]=r,t=t+1|0),t}function fe(A,e,r){var i,f=0,t=0,n=0,o=0,c=_(0),b=_(0),l=0,u=0,s=0,k=0,v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0);if(i=Y-880|0,Y=i,b=C[e+64>>2],c=C[A+64>>2],u=A+56|0,t=a[u+4>>2],o=i+296|0,a[o>>2]=a[u>>2],a[o+4>>2]=t,t=a[A+52>>2],a[i+288>>2]=a[A+48>>2],a[i+292>>2]=t,t=re(A,e,i+560|0),f=0,t&&(a[i+280>>2]=-998637568,a[i+284>>2]=0,f=0,!((0|t)<=0))){for(m=_(c+b),u=i+288|0,d=C[i+300>>2],g=C[i+296>>2],B=C[i+292>>2],o=0,v=_(-1e3),f=i+560|0,b=C[i+288>>2];c=_(m-_(_(_(_(C[f>>2]*b)+_(C[f+4>>2]*B))+_(C[f+8>>2]*g))-d)),c>=_(0)&&(c>v?(a[i+816>>2]=n,o=1,v=c):_(c+_(1.1920928955078125e-7))>=v&&(a[(i+816|0)+(o<<2)>>2]=n,o=o+1|0)),f=f+16|0,n=n+1|0,(0|t)!=(0|n););if(C[i+280>>2]=v,a[i+284>>2]=o,(0|o)>=1)for(f=i+304|0,n=i+816|0,t=o;s=(i+560|0)+(a[n>>2]<<4)|0,l=a[s+4>>2],a[f>>2]=a[s>>2],a[f+4>>2]=l,l=a[s+12>>2],k=f+8|0,a[k>>2]=a[s+8>>2],a[k+4>>2]=l,n=n+4|0,f=f+16|0,t=t+-1|0,t;);if(f=0,o&&(t=i+292|0,C[t>>2]=-C[t>>2],t=i+296|0,C[t>>2]=-C[t>>2],C[i+288>>2]=-C[i+288>>2],l=e+56|0,t=a[l+4>>2],k=i+16|0,a[k>>2]=a[l>>2],a[k+4>>2]=t,t=a[e+52>>2],a[i+8>>2]=a[e+48>>2],a[i+12>>2]=t,e=re(e,A,i+560|0),f=0,e&&(a[i>>2]=-998637568,a[i+4>>2]=0,f=0,!((0|e)<=0)))){for(A=i+8|0,R=C[i+20>>2],d=C[i+16>>2],g=C[i+12>>2],t=0,b=_(-1e3),f=i+560|0,B=C[i+8>>2],n=0;c=_(m-_(_(_(_(C[f>>2]*B)+_(C[f+4>>2]*g))+_(C[f+8>>2]*d))-R)),c>=_(0)&&(c>b?(a[i+816>>2]=n,t=1,b=c):_(c+_(1.1920928955078125e-7))>=b&&(a[(i+816|0)+(t<<2)>>2]=n,t=t+1|0)),f=f+16|0,n=n+1|0,(0|e)!=(0|n););if(C[i>>2]=b,a[i+4>>2]=t,(0|t)>=1)for(f=i+24|0,n=i+816|0,e=t;s=(i+560|0)+(a[n>>2]<<4)|0,l=a[s+4>>2],a[f>>2]=a[s>>2],a[f+4>>2]=l,l=a[s+12>>2],k=f+8|0,a[k>>2]=a[s+8>>2],a[k+4>>2]=l,n=n+4|0,f=f+16|0,e=e+-1|0,e;);if(f=0,t){if(b>2]=b,a[r+4>>2]=t,e=a[A+4>>2],a[r+8>>2]=a[A>>2],a[r+12>>2]=e,e=A+8|0,A=a[e+4>>2],u=r+16|0,a[u>>2]=a[e>>2],a[u+4>>2]=A,A=t<<4,f=A+(r+8|0)|0,n=8+(A+i|0)|0;A=a[n+4>>2],a[f>>2]=a[n>>2],a[f+4>>2]=A,e=n+8|0,A=a[e+4>>2],r=f+8|0,a[r>>2]=a[e>>2],a[r+4>>2]=A,n=n+-16|0,f=f+-16|0,t=t+-1|0,t;);else for(C[r>>2]=v,a[r+4>>2]=o,A=a[u+4>>2],a[r+8>>2]=a[u>>2],a[r+12>>2]=A,e=u+8|0,A=a[e+4>>2],t=r+16|0,a[t>>2]=a[e>>2],a[t+4>>2]=A,A=o<<4,f=A+(r+8|0)|0,n=288+(A+i|0)|0;A=a[n+4>>2],a[f>>2]=a[n>>2],a[f+4>>2]=A,e=n+8|0,A=a[e+4>>2],r=f+8|0,a[r>>2]=a[e>>2],a[r+4>>2]=A,n=n+-16|0,f=f+-16|0,o=o+-1|0,o;);f=1}}}return Y=i+880|0,f}function te(A){!function(A){var e=0;DA(A),f[A+92|0]=0,a[A+88>>2]=0,e=A+80|0,a[e>>2]=-1082130432,a[e+4>>2]=-1082130432,e=A+72|0,a[e>>2]=0,a[e+4>>2]=-1082130432,e=A- -64|0,a[e>>2]=1065353216,a[e+4>>2]=1065353216,a[A>>2]=7240,a[A+56>>2]=0,a[A+60>>2]=1065353216}(A),a[A+96>>2]=0,a[A>>2]=7464,a[A+4>>2]=2}function ne(A){return A|=0,a[A+96>>2]}function ae(A,e,r,i){}function oe(A,e){return 0}function ce(A){A|=0,Ae(A),CA(A)}function be(A){var e=0;a[A>>2]=1025,e=A+120|0,a[e>>2]=0,a[e+4>>2]=0,e=A+128|0,a[e>>2]=0,a[e+4>>2]=0,e=A+136|0,a[e>>2]=0,a[e+4>>2]=0,e=A+144|0,a[e>>2]=0,a[e+4>>2]=0,e=A+152|0,a[e>>2]=0,a[e+4>>2]=0,a[A+160>>2]=0,e=A+312|0,a[e>>2]=0,a[e+4>>2]=0,e=A+320|0,a[e>>2]=0,a[e+4>>2]=0,e=A+328|0,a[e>>2]=0,a[e+4>>2]=0,e=A+336|0,a[e>>2]=0,a[e+4>>2]=0,e=A+344|0,a[e>>2]=0,a[e+4>>2]=0,a[A+352>>2]=0,e=A+504|0,a[e>>2]=0,a[e+4>>2]=0,e=A+512|0,a[e>>2]=0,a[e+4>>2]=0,e=A+520|0,a[e>>2]=0,a[e+4>>2]=0,e=A+528|0,a[e>>2]=0,a[e+4>>2]=0,e=A+536|0,a[e>>2]=0,a[e+4>>2]=0,a[A+544>>2]=0,a[A+736>>2]=0,e=A+728|0,a[e>>2]=0,a[e+4>>2]=0,e=A+720|0,a[e>>2]=0,a[e+4>>2]=0,e=A+712|0,a[e>>2]=0,a[e+4>>2]=0,e=A+704|0,a[e>>2]=0,a[e+4>>2]=0,e=A+696|0,a[e>>2]=0,a[e+4>>2]=0,a[A+772>>2]=0,a[A+776>>2]=0,a[A+800>>2]=0,a[A+780>>2]=0}function le(A){var e,r=0;e=a[A+116>>2],e&&(r=a[421],r&&(Qt[r](e),a[A+116>>2]=0))}function ue(A,e){var r=0,i=0,f=0,t=0;r=a[A+780>>2];A:if(4!=(0|r))a[A+780>>2]=r+1;else{if(r=function(A,e){var r,i=_(0),f=_(0),t=_(0),n=_(0),a=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),R=_(0),Q=_(0),h=0,G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),Y=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=0,U=_(0),M=_(0),S=_(0),X=_(0),T=_(0),j=_(0);i=C[A+84>>2],n=C[e+80>>2],h=i>2],i=h?i:n,h=l>2],i=h?l:i,h=n>2]<(h?n:i),h=x?3:h?2:r,c=C[e>>2];e:{r:{i:{f:{if(o[2980]){if(!h){d=C[A+588>>2],g=C[A+396>>2],i=_(d-g),R=C[A+584>>2],B=C[A+392>>2],n=_(R-B),f=C[A+580>>2],p=C[A+388>>2],l=_(f-p),t=C[e+8>>2],b=C[e+4>>2];break f}if(a=C[A+196>>2],u=_(c-a),R=C[A+584>>2],B=C[A+392>>2],n=_(R-B),b=C[e+4>>2],Q=C[A+200>>2],i=_(b-Q),f=C[A+580>>2],p=C[A+388>>2],l=_(f-p),t=_(_(u*n)-_(i*l)),k=_(t*t),s=i,d=C[A+588>>2],g=C[A+396>>2],i=_(d-g),t=C[e+8>>2],G=C[A+204>>2],F=_(t-G),W=_(_(s*i)-_(F*n)),u=_(_(F*l)-_(u*i)),j=_(k+_(_(W*W)+_(u*u))),1!=(0|h))break f;c=_(c-C[A+4>>2]),t=_(t-C[A+12>>2]),b=_(b-C[A+8>>2]),l=_(0);break i}F=C[e+8>>2],W=C[e+4>>2];t:{n:{if(h){if(Z=C[A+196>>2],R=_(c-Z),g=C[A+392>>2],b=C[A+584>>2],w=_(g-b),Y=C[A+200>>2],d=_(W-Y),B=C[A+388>>2],u=C[A+580>>2],D=_(B-u),i=_(_(R*w)-_(d*D)),n=_(i*i),a=C[A+396>>2],t=C[A+588>>2],l=_(a-t),f=C[A+204>>2],p=_(F-f),i=_(_(d*l)-_(p*w)),s=_(i*i),i=_(_(p*D)-_(R*l)),n=_(n+_(s+_(i*i))),Q=_(c-B),E=_(Y-b),G=_(W-g),U=_(Z-u),i=_(_(Q*E)-_(G*U)),s=_(i*i),M=_(f-t),i=_(F-a),k=_(_(G*M)-_(i*E)),v=_(k*k),k=_(_(i*U)-_(Q*M)),k=_(s+_(v+_(k*k))),k=n>k?n:k,n=_(Y-g),I=_(c-u),v=_(Z-B),N=_(W-b),y=_(_(n*I)-_(v*N)),V=_(y*y),y=_(f-a),s=n,n=_(F-t),s=_(_(y*N)-_(s*n)),v=_(_(v*n)-_(y*I)),v=_(V+_(_(s*s)+_(v*v))),j=k>v?k:v,1==(0|h)){k=C[A+4>>2],S=_(k-u),s=_(c-k),v=C[A+12>>2],X=_(v-t),y=C[A+8>>2],T=_(y-b),V=_(F-v),J=_(W-y),l=_(0);break n}}else a=C[A+396>>2],t=C[A+588>>2],l=_(a-t),g=C[A+392>>2],b=C[A+584>>2],w=_(g-b),B=C[A+388>>2],u=C[A+580>>2],D=_(B-u),n=_(F-t),N=_(W-b),I=_(c-u),i=_(F-a),G=_(W-g),Q=_(c-B);if(k=C[A+4>>2],s=_(c-k),y=C[A+8>>2],J=_(W-y),f=_(_(s*w)-_(J*D)),d=_(f*f),v=C[A+12>>2],V=_(F-v),f=_(_(J*l)-_(V*w)),l=_(_(V*D)-_(s*l)),l=_(d+_(_(f*f)+_(l*l))),T=_(y-b),S=_(k-u),f=_(_(Q*T)-_(G*S)),d=_(f*f),X=_(v-t),f=_(_(G*X)-_(i*T)),R=_(f*f),f=_(_(i*S)-_(Q*X)),f=_(d+_(R+_(f*f))),l=l>f?l:f,w=_(y-g),D=_(k-B),f=_(_(w*I)-_(D*N)),d=_(f*f),E=_(v-a),f=_(_(E*N)-_(w*n)),R=_(f*f),f=_(_(D*n)-_(E*I)),f=_(d+_(R+_(f*f))),l=l>f?l:f,f=C[A+204>>2],p=_(F-f),Y=C[A+200>>2],d=_(W-Y),Z=C[A+196>>2],R=_(c-Z),2==(0|h)){t=_(v-f),b=_(y-Y),u=_(k-Z),n=_(0);break t}M=_(f-t),E=_(Y-b),U=_(Z-u)}if(i=_(_(s*E)-_(J*U)),b=_(i*i),i=_(_(J*M)-_(V*E)),t=_(i*i),i=_(_(V*U)-_(s*M)),i=_(b+_(t+_(i*i))),t=_(_(R*T)-_(d*S)),b=_(t*t),t=_(_(d*X)-_(p*T)),u=_(t*t),t=_(_(p*S)-_(R*X)),t=_(b+_(u+_(t*t))),i=i>t?i:t,b=_(y-Y),u=_(k-Z),t=_(_(b*I)-_(u*N)),G=_(t*t),t=_(v-f),Q=_(_(t*N)-_(b*n)),n=_(_(u*n)-_(t*I)),n=_(G+_(_(Q*Q)+_(n*n))),n=i>n?i:n,i=_(0),x)break e;E=_(v-a),w=_(y-g),D=_(k-B),i=_(F-a),G=_(W-g),Q=_(c-B)}c=_(Y-g),g=_(Z-B),B=_(_(s*c)-_(J*g)),a=_(f-a),c=_(_(J*a)-_(V*c)),f=_(c*c),c=_(_(V*g)-_(s*a)),c=_(_(B*B)+_(f+_(c*c))),a=_(_(R*w)-_(d*D)),s=_(a*a),a=_(_(d*E)-_(p*w)),f=_(a*a),a=_(_(p*D)-_(R*E)),a=_(s+_(f+_(a*a))),c=c>a?c:a,a=_(_(b*Q)-_(u*G)),s=_(a*a),a=_(_(t*G)-_(b*i)),i=_(_(u*i)-_(t*Q)),i=_(s+_(_(a*a)+_(i*i))),i=c>i?c:i;break e}if(c=_(c-C[A+4>>2]),b=_(b-C[A+8>>2]),a=_(_(c*n)-_(b*l)),t=_(t-C[A+12>>2]),n=_(_(b*i)-_(t*n)),i=_(_(t*l)-_(c*i)),l=_(_(a*a)+_(_(n*n)+_(i*i))),G=C[A+204>>2],Q=C[A+200>>2],a=C[A+196>>2],n=_(0),2==(0|h))break r}if(i=_(R-Q),n=_(f-a),u=_(_(c*i)-_(b*n)),s=_(u*u),u=_(d-G),i=_(_(b*u)-_(t*i)),f=_(i*i),i=_(_(t*n)-_(c*u)),n=_(s+_(f+_(i*i))),i=_(0),x)break e}i=_(B-Q),a=_(p-a),u=_(_(c*i)-_(b*a)),s=b,b=_(g-G),i=_(_(s*b)-_(t*i)),s=_(i*i),i=_(_(t*a)-_(c*b)),i=_(_(u*u)+_(s+_(i*i)))}return c=_(m(j)),A=c>_(-0xde0b6b000000000),e=A?0:-1,l=_(m(l)),c=A?c:_(-0xde0b6b000000000),A=l>c,e=A?1:e,n=_(m(n)),l=A?l:c,A=n>l,_(m(i))>(A?n:l)?3:A?2:e}(A,e),i=120+(B(r,192)+A|0)|0,f=a[i>>2],!f)break A;if(t=a[421],!t)break A;Qt[t](f),a[i>>2]=0}return r=(0|r)>0?r:0,J(4+(A+B(r,192)|0)|0,e,192),r}function se(A,e,r){var i,f=0,t=_(0),n=0,o=_(0),c=_(0),b=0,l=0,u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0);if(i=Y-16|0,Y=i,l=a[A+780>>2],!((0|l)<1)){for(f=(B(l,192)+A|0)-188|0,n=l;v=C[e+48>>2],m=C[e+8>>2],R=C[e+4>>2],Q=C[e>>2],d=C[e+52>>2],h=C[e+24>>2],u=C[e+20>>2],G=C[e+16>>2],t=C[e+56>>2],o=C[e+40>>2],c=C[e+36>>2],g=C[e+32>>2],a[f+60>>2]=0,k=t,t=C[f>>2],y=c,c=C[f+4>>2],s=o,o=C[f+8>>2],g=_(k+_(_(_(g*t)+_(y*c))+_(s*o))),C[f+56>>2]=g,d=_(d+_(_(_(t*G)+_(c*u))+_(o*h))),C[f+52>>2]=d,v=_(v+_(_(_(t*Q)+_(c*R))+_(o*m))),C[f+48>>2]=v,m=C[r+56>>2],R=C[r+40>>2],Q=C[r+32>>2],h=C[r+36>>2],u=C[r+52>>2],G=C[r+24>>2],p=C[r+16>>2],F=C[r+20>>2],t=C[r+48>>2],o=C[r+8>>2],c=C[r>>2],s=C[r+4>>2],a[f+44>>2]=0,k=t,t=C[f+16>>2],W=_(c*t),c=C[f+20>>2],y=o,o=C[f+24>>2],s=_(k+_(_(W+_(s*c))+_(y*o))),C[f+32>>2]=s,u=_(u+_(_(_(t*p)+_(c*F))+_(o*G))),C[f+36>>2]=u,t=_(m+_(_(_(t*Q)+_(c*h))+_(o*R))),C[f+40>>2]=t,C[f+80>>2]=_(_(_(v-s)*C[f- -64>>2])+_(_(d-u)*C[f+68>>2]))+_(_(g-t)*C[f+72>>2]),b=f+156|0,a[b>>2]=a[b>>2]+1,f=f+-192|0,n=n+-1|0,(0|n)>0;);if(!((0|l)<1))for(e=B(l,192);;){l=l+-1|0,r=A+e|0,n=r+-188|0,t=C[r+-108>>2],c=C[A+784>>2];A:if(t<=c)if(o=_(C[r+-156>>2]-_(C[r+-140>>2]-_(C[r+-124>>2]*t))),k=_(o*o),o=_(C[r+-152>>2]-_(C[r+-136>>2]-_(t*C[r+-120>>2]))),t=_(C[r+-148>>2]-_(C[r+-132>>2]-_(t*C[r+-116>>2]))),_(_(k+_(o*o))+_(t*t))>_(c*c)){if(r=r+-72|0,f=a[r>>2],f&&(b=a[421],b&&(Qt[b](f),a[r>>2]=0)),b=A,f=a[A+780>>2],r=f+-1|0,(0|l)!=(0|r)&&(r=B(r,192)+A|0,J(n,r+4|0,192),n=r+120|0,a[n>>2]=0,a[n+4>>2]=0,a[r+160>>2]=0,n=r+128|0,a[n>>2]=0,a[n+4>>2]=0,a[r+136>>2]=0,f=a[A+780>>2]),r=f+-1|0,a[b+780>>2]=r,r)break A;if(r=a[424],!r)break A;a[i+8>>2]=A,Qt[r](i+8|0)}else r=a[422],r&&Qt[r](n,a[A+772>>2],a[A+776>>2]);else{if(r=r+-72|0,f=a[r>>2],f&&(b=a[421],b&&(Qt[b](f),a[r>>2]=0)),b=A,f=a[A+780>>2],r=f+-1|0,(0|l)!=(0|r)&&(r=B(r,192)+A|0,J(n,r+4|0,192),n=r+120|0,a[n>>2]=0,a[n+4>>2]=0,a[r+160>>2]=0,n=r+128|0,a[n>>2]=0,a[n+4>>2]=0,a[r+136>>2]=0,f=a[A+780>>2]),r=f+-1|0,a[b+780>>2]=r,r)break A;if(r=a[424],!r)break A;a[i+12>>2]=A,Qt[r](i+12|0)}if(e=e+-192|0,!((0|l)>0))break}}Y=i+16|0}function ke(A,e){return _(C[A+232>>2]*C[e+232>>2])}function ve(A){A|=0,$(A)}function de(A,e,r){a[76+((B(e,144)+A|0)+(r<<2)|0)>>2]=1708}function Ce(A){return A|=0,a[A+72>>2]}function ge(A,e,r){var i=0,f=0;i=a[A+12>>2],i||(i=a[A+4>>2],i=0|Qt[a[a[i>>2]+12>>2]](i,a[e+8>>2],a[r+8>>2]),a[A+12>>2]=i),a[a[A+16>>2]+4>>2]=i,f=a[A+4>>2],i=0|Qt[a[a[f>>2]+8>>2]](f,e,r,i,1),f=a[A+16>>2],Qt[a[a[f>>2]+8>>2]](f,a[A+28>>2],a[A+24>>2]),f=a[A+16>>2],Qt[a[a[f>>2]+12>>2]](f,a[A+36>>2],a[A+32>>2]),Qt[a[a[i>>2]+8>>2]](i,e,r,a[A+20>>2],a[A+16>>2]),Qt[a[a[i>>2]>>2]](i),A=a[A+4>>2],Qt[a[a[A>>2]+60>>2]](A,i)}function Be(A,e,r,i,f){var t,n=0;t=Y-48|0,Y=t,n=a[A+16>>2],Qt[a[a[n>>2]+8>>2]](n,a[A+28>>2],a[A+24>>2]),n=a[A+16>>2],Qt[a[a[n>>2]+12>>2]](n,a[A+36>>2],a[A+32>>2]),a[t+28>>2]=i,a[t+44>>2]=a[A+24>>2],a[t+40>>2]=a[A+28>>2],a[t+24>>2]=e,a[t+36>>2]=a[e+12>>2],e=a[e+8>>2],a[t+32>>2]=e,a[t+4>>2]=f,a[t+20>>2]=a[A+32>>2],a[t+16>>2]=a[A+36>>2],a[t>>2]=r,a[t+12>>2]=a[r+12>>2],i=a[r+8>>2],a[t+8>>2]=i,r=a[A+8>>2],r||(r=a[A+12>>2],r||(r=a[A+4>>2],r=0|Qt[a[a[r>>2]+12>>2]](r,e,i),a[A+12>>2]=r),a[a[A+16>>2]+4>>2]=r,e=a[A+4>>2],r=0|Qt[a[a[e>>2]+8>>2]](e,t+24|0,t,r,1),a[A+8>>2]=r),Qt[a[a[r>>2]+8>>2]](r,t+24|0,t,a[A+20>>2],a[A+16>>2]),Y=t+48|0}function _e(A,e,r,i,t){var n,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0,g=0,B=0,m=0,R=_(0),Q=_(0),h=_(0),G=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=0,Z=0,V=0,N=0,I=_(0),J=_(0),x=_(0),U=_(0),M=_(0),S=_(0),X=_(0),T=_(0),j=_(0),O=_(0),H=_(0),z=_(0),P=0,K=0,L=_(0),q=_(0),$=_(0),AA=0,eA=0,rA=0,iA=0,fA=0,tA=0,nA=0;n=Y-976|0,Y=n;A:if(2!=(0|Qt[a[a[i>>2]+80>>2]](i)))if(2!=(0|Qt[a[a[t>>2]+80>>2]](t))){if(c=a[e+12>>2],b=c+8|0,d=a[b>>2],b=a[b+4>>2],Z=a[c>>2],V=a[c+4>>2],k=c+24|0,v=a[k+4>>2],l=n+936|0,a[l>>2]=a[k>>2],a[l+4>>2]=v,l=n+920|0,a[l>>2]=d,a[l+4>>2]=b,b=a[c+16>>2],d=a[c+20>>2],k=c+40|0,v=a[k+4>>2],l=n+952|0,a[l>>2]=a[k>>2],a[l+4>>2]=v,l=a[c+32>>2],k=a[c+36>>2],B=c+56|0,m=a[B+4>>2],v=n+968|0,a[v>>2]=a[B>>2],a[v+4>>2]=m,a[n+912>>2]=Z,a[n+916>>2]=V,a[n+928>>2]=b,a[n+932>>2]=d,a[n+944>>2]=l,a[n+948>>2]=k,b=a[c+52>>2],a[n+960>>2]=a[c+48>>2],a[n+964>>2]=b,c=a[r+12>>2],b=c+8|0,d=a[b>>2],b=a[b+4>>2],Z=a[c>>2],V=a[c+4>>2],k=c+24|0,v=a[k+4>>2],l=n+872|0,a[l>>2]=a[k>>2],a[l+4>>2]=v,l=n+856|0,a[l>>2]=d,a[l+4>>2]=b,b=a[c+16>>2],d=a[c+20>>2],k=c+40|0,v=a[k+4>>2],l=n+888|0,a[l>>2]=a[k>>2],a[l+4>>2]=v,l=a[c+32>>2],k=a[c+36>>2],B=c+56|0,m=a[B+4>>2],v=n+904|0,a[v>>2]=a[B>>2],a[v+4>>2]=m,a[n+848>>2]=Z,a[n+852>>2]=V,a[n+864>>2]=b,a[n+868>>2]=d,a[n+880>>2]=l,a[n+884>>2]=k,b=a[c+52>>2],a[n+896>>2]=a[c+48>>2],a[n+900>>2]=b,a[n+828>>2]=0,tA=n,nA=dA(256),a[tA+836>>2]=nA,f[n+840|0]=1,a[n+832>>2]=32,function(A,e,r,i,t){var n,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0,g=0,B=0,_=0,m=0;if(n=Y+-64|0,Y=n,!a[r+72>>2]|!a[i+72>>2]){if(b=0|Qt[a[a[r>>2]+88>>2]](r),b)for(B=n+16|0,_=n+48|0;;){if(b=b+-1|0,Qt[a[a[r>>2]+120>>2]](r,b,A,n+32|0,_),l=0|Qt[a[a[i>>2]+88>>2]](i),l)for(;;){if(Qt[a[a[i>>2]+120>>2]](i,b,e,n,B),l=l+-1|0,!(C[n+16>>2]>2]|C[n>>2]>C[n+48>>2]|C[n+20>>2]>2]|C[n+4>>2]>C[n+52>>2]|C[n+24>>2]>2]|C[n+8>>2]>C[n+56>>2])){if(c=a[t+4>>2],(0|c)==a[t+8>>2]&&(u=c?c<<1:1,!((0|c)>=(0|u)))){u?(v=dA(u<<3),c=a[t+4>>2]):v=0,d=a[t+12>>2];e:{if((0|c)>=1)for(s=d,k=v,g=c;m=a[s+4>>2],a[k>>2]=a[s>>2],a[k+4>>2]=m,s=s+8|0,k=k+8|0,g=g+-1|0,g;);else if(!d)break e;o[t+16|0]&&(CA(d),c=a[t+4>>2]),a[t+12>>2]=0}a[t+12>>2]=v,f[t+16|0]=1,a[t+8>>2]=u}a[t+4>>2]=c+1,c=a[t+12>>2]+(c<<3)|0,a[c+4>>2]=l,a[c>>2]=b}if(!l)break}if(!b)break}}else mA(r+72|0,A,i+72|0,e,t);Y=n- -64|0}(n+912|0,n+848|0,i,t,n+824|0),a[n+828>>2])if(1!=(0|Qt[a[a[i>>2]+80>>2]](i))||1!=(0|Qt[a[a[t>>2]+80>>2]](t))){if(Qt[a[a[i>>2]+112>>2]](i),Qt[a[a[t>>2]+112>>2]](t),zA(n+520|4),c=n+584|0,a[c>>2]=0,a[c+4>>2]=0,a[n+528>>2]=1,c=n+592|0,a[c>>2]=0,a[c+4>>2]=0,c=n+600|0,a[c>>2]=0,a[c+4>>2]=0,c=n+608|0,a[c>>2]=0,a[c+4>>2]=0,c=n+616|0,a[c>>2]=0,a[c+4>>2]=0,c=n+624|0,a[c>>2]=0,a[c+4>>2]=0,a[n+524>>2]=8128,te(n+632|0),a[n+728>>2]=4,a[n+812>>2]=8708,a[n+804>>2]=8628,a[n+796>>2]=8556,a[n+632>>2]=8364,a[n+520>>2]=i,c=n+804|0,Qt[a[a[i>>2]+96>>2]](i)||(c=a[n+520>>2],c=0|Qt[a[a[c>>2]+100>>2]](c)?n+812|0:n+796|0),a[c+4>>2]=n+520,a[n+820>>2]=c,zA(n+216|4),c=n+280|0,a[c>>2]=0,a[c+4>>2]=0,a[n+224>>2]=1,c=n+288|0,a[c>>2]=0,a[c+4>>2]=0,c=n+296|0,a[c>>2]=0,a[c+4>>2]=0,c=n+304|0,a[c>>2]=0,a[c+4>>2]=0,c=n+312|0,a[c>>2]=0,a[c+4>>2]=0,c=n+320|0,a[c>>2]=0,a[c+4>>2]=0,a[n+220>>2]=8128,te(n+328|0),a[n+424>>2]=4,a[n+508>>2]=8708,a[n+500>>2]=8628,a[n+492>>2]=8556,a[n+328>>2]=8364,a[n+216>>2]=t,c=n+500|0,Qt[a[a[t>>2]+96>>2]](t)||(c=a[n+216>>2],c=0|Qt[a[a[c>>2]+100>>2]](c)?n+508|0:n+492|0),a[c+4>>2]=n+216,a[n+516>>2]=c,rA=0|Qt[a[a[i>>2]+92>>2]](i),iA=0|Qt[a[a[t>>2]+92>>2]](t),b=a[n+828>>2],b)for(d=(b<<3)-4|0,Z=n+136|0,V=n+120|0,l=n+104|0,k=n+200|0,v=n+184|0,B=n+168|0;c=a[n+836>>2]+d|0,a[A+32>>2]=a[c>>2],c=a[c+-4>>2],a[A+24>>2]=c,m=a[n+820>>2],m=0|Qt[a[a[m>>2]>>2]](m,c),c=a[n+516>>2],AA=0|Qt[a[a[c>>2]>>2]](c,a[A+32>>2]),c=a[e+12>>2],s=c+8|0,g=a[s>>2],s=a[s+4>>2],P=a[c>>2],K=a[c+4>>2],N=c+24|0,E=a[N+4>>2],u=B+8|0,a[u>>2]=a[N>>2],a[u+4>>2]=E,u=n+160|0,a[u>>2]=g,a[u+4>>2]=s,s=a[c+16>>2],g=a[c+20>>2],u=a[c+36>>2],a[v>>2]=a[c+32>>2],a[v+4>>2]=u,u=c+40|0,N=a[u>>2],u=a[u+4>>2],eA=c+56|0,fA=a[eA+4>>2],E=k+8|0,a[E>>2]=a[eA>>2],a[E+4>>2]=fA,E=a[c+52>>2],a[k>>2]=a[c+48>>2],a[k+4>>2]=E,c=v+8|0,a[c>>2]=N,a[c+4>>2]=u,a[B>>2]=s,a[B+4>>2]=g,a[n+152>>2]=P,a[n+156>>2]=K,c=a[r+12>>2],s=c+8|0,g=a[s>>2],s=a[s+4>>2],P=a[c>>2],K=a[c+4>>2],N=c+24|0,E=a[N+4>>2],u=l+8|0,a[u>>2]=a[N>>2],a[u+4>>2]=E,u=a[c+20>>2],a[l>>2]=a[c+16>>2],a[l+4>>2]=u,u=n+96|0,a[u>>2]=g,a[u+4>>2]=s,g=c+40|0,u=a[g+4>>2],s=V+8|0,a[s>>2]=a[g>>2],a[s+4>>2]=u,s=a[c+36>>2],a[V>>2]=a[c+32>>2],a[V+4>>2]=s,g=c+56|0,u=a[g+4>>2],s=Z+8|0,a[s>>2]=a[g>>2],a[s+4>>2]=u,s=a[c+52>>2],a[Z>>2]=a[c+48>>2],a[Z+4>>2]=s,a[n+88>>2]=P,a[n+92>>2]=K,rA&&(Qt[a[a[i>>2]+132>>2]](n+24|0,i,a[A+24>>2]),L=C[n+960>>2],q=C[n+964>>2],$=C[n+968>>2],I=C[n+80>>2],J=C[n+72>>2],x=C[n+76>>2],R=C[n+920>>2],Q=C[n+912>>2],h=C[n+916>>2],G=C[n+936>>2],p=C[n+928>>2],F=C[n+932>>2],U=C[n+56>>2],M=C[n+24>>2],S=C[n+40>>2],X=C[n+60>>2],T=C[n+28>>2],j=C[n+44>>2],W=C[n+952>>2],O=C[n+64>>2],w=C[n+944>>2],H=C[n+32>>2],D=C[n+948>>2],z=C[n+48>>2],a[n+212>>2]=0,a[n+196>>2]=0,a[n+180>>2]=0,a[n+164>>2]=0,C[n+192>>2]=_(_(H*w)+_(z*D))+_(O*W),C[n+188>>2]=_(_(T*w)+_(j*D))+_(X*W),C[n+184>>2]=_(_(M*w)+_(S*D))+_(U*W),C[n+176>>2]=_(_(H*p)+_(z*F))+_(O*G),C[n+172>>2]=_(_(T*p)+_(j*F))+_(X*G),C[n+168>>2]=_(_(M*p)+_(S*F))+_(U*G),C[n+160>>2]=_(_(Q*H)+_(h*z))+_(R*O),C[n+156>>2]=_(_(Q*T)+_(h*j))+_(R*X),C[n+152>>2]=_(_(M*Q)+_(S*h))+_(U*R),C[n+208>>2]=$+_(_(_(w*J)+_(D*x))+_(W*I)),C[n+204>>2]=q+_(_(_(p*J)+_(F*x))+_(G*I)),C[n+200>>2]=L+_(_(_(Q*J)+_(h*x))+_(R*I))),b=b+-1|0,iA&&(Qt[a[a[t>>2]+132>>2]](n+24|0,t,a[A+32>>2]),L=C[n+896>>2],q=C[n+900>>2],$=C[n+904>>2],I=C[n+80>>2],J=C[n+72>>2],x=C[n+76>>2],R=C[n+856>>2],Q=C[n+848>>2],h=C[n+852>>2],G=C[n+872>>2],p=C[n+864>>2],F=C[n+868>>2],U=C[n+56>>2],M=C[n+24>>2],S=C[n+40>>2],X=C[n+60>>2],T=C[n+28>>2],j=C[n+44>>2],W=C[n+888>>2],O=C[n+64>>2],w=C[n+880>>2],H=C[n+32>>2],D=C[n+884>>2],z=C[n+48>>2],a[n+148>>2]=0,a[n+132>>2]=0,a[n+116>>2]=0,a[n+100>>2]=0,C[n+128>>2]=_(_(H*w)+_(z*D))+_(O*W),C[n+124>>2]=_(_(T*w)+_(j*D))+_(X*W),C[n+120>>2]=_(_(M*w)+_(S*D))+_(U*W),C[n+112>>2]=_(_(H*p)+_(z*F))+_(O*G),C[n+108>>2]=_(_(T*p)+_(j*F))+_(X*G),C[n+104>>2]=_(_(M*p)+_(S*F))+_(U*G),C[n+96>>2]=_(_(Q*H)+_(h*z))+_(R*O),C[n+92>>2]=_(_(Q*T)+_(h*j))+_(R*X),C[n+88>>2]=_(_(M*Q)+_(S*h))+_(U*R),C[n+144>>2]=$+_(_(_(w*J)+_(D*x))+_(W*I)),C[n+140>>2]=q+_(_(_(p*J)+_(F*x))+_(G*I)),C[n+136>>2]=L+_(_(_(Q*J)+_(h*x))+_(R*I))),a[n+28>>2]=m,a[n+44>>2]=a[A+24>>2],a[n+40>>2]=a[A+28>>2],a[n+24>>2]=e,a[n+32>>2]=a[e+8>>2],a[n+36>>2]=n+152,a[n+4>>2]=AA,a[n+20>>2]=a[A+32>>2],a[n+16>>2]=a[A+36>>2],a[n>>2]=r,a[n+8>>2]=a[r+8>>2],a[n+12>>2]=n+88,Be(A,n+24|0,n,m,AA),d=d+-8|0,b;);Qt[a[a[i>>2]+116>>2]](i),Qt[a[a[t>>2]+116>>2]](t),Ae(n+328|0),Ae(n+216|4),Ae(n+632|0),Ae(n+520|4)}else!function(A,e,r,i,f,t,n){var o,c=_(0),b=0,l=_(0),u=0,s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=0,p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0),U=_(0),M=_(0),S=_(0),X=_(0),T=_(0),j=_(0),O=_(0),H=_(0),z=_(0),P=_(0),K=_(0),L=_(0),q=_(0),$=_(0),AA=_(0),eA=_(0),rA=_(0),iA=_(0),fA=_(0),tA=0,nA=0,aA=_(0);if(o=Y-432|0,Y=o,u=a[r+12>>2],V=C[u+56>>2],N=C[u+52>>2],I=C[u+40>>2],J=C[u+36>>2],x=C[u+24>>2],U=C[u+20>>2],b=a[e+12>>2],M=C[b+56>>2],S=C[b+52>>2],X=C[b+40>>2],T=C[b+36>>2],j=C[b+24>>2],O=C[b+20>>2],H=C[u+48>>2],z=C[u+32>>2],P=C[u+16>>2],K=C[u+8>>2],L=C[u+4>>2],q=C[u>>2],$=C[b+48>>2],AA=C[b+32>>2],eA=C[b+16>>2],rA=C[b+8>>2],iA=C[b+4>>2],fA=C[b>>2],a[o+424>>2]=1008981770,a[o+352>>2]=1008981770,Qt[a[a[i>>2]+112>>2]](i),Qt[a[a[f>>2]+112>>2]](f),n)for(nA=o+16|0;;){if(u=a[t>>2],a[A+24>>2]=u,a[A+32>>2]=a[t+4>>2],b=0|Qt[a[a[i>>2]+84>>2]](i),Qt[a[a[b>>2]+20>>2]](b,u,o+360|0),u=a[A+32>>2],b=0|Qt[a[a[f>>2]+84>>2]](f),Qt[a[a[b>>2]+20>>2]](b,u,o+288|0),a[o+372>>2]=0,a[o+388>>2]=0,a[o+404>>2]=0,m=C[o+376>>2],R=C[o+380>>2],c=C[o+384>>2],aA=_(S+_(_(_(eA*m)+_(O*R))+_(j*c))),C[o+380>>2]=aA,Q=C[o+360>>2],h=C[o+364>>2],v=C[o+368>>2],p=_(S+_(_(_(eA*Q)+_(O*h))+_(j*v))),C[o+364>>2]=p,s=C[o+392>>2],k=C[o+396>>2],l=C[o+400>>2],F=_(S+_(_(_(eA*s)+_(O*k))+_(j*l))),C[o+396>>2]=F,d=_(M+_(_(_(AA*m)+_(T*R))+_(X*c))),C[o+384>>2]=d,g=_($+_(_(_(fA*s)+_(iA*k))+_(rA*l))),C[o+392>>2]=g,W=_($+_(_(_(fA*Q)+_(iA*h))+_(rA*v))),C[o+360>>2]=W,c=_($+_(_(_(fA*m)+_(iA*R))+_(rA*c))),C[o+376>>2]=c,w=_(M+_(_(_(AA*Q)+_(T*h))+_(X*v))),C[o+368>>2]=w,l=_(M+_(_(_(AA*s)+_(T*k))+_(X*l))),C[o+400>>2]=l,v=C[o+296>>2],s=C[o+288>>2],k=C[o+292>>2],a[o+300>>2]=0,D=_(N+_(_(_(P*s)+_(U*k))+_(x*v))),C[o+292>>2]=D,E=_(V+_(_(_(z*s)+_(J*k))+_(I*v))),C[o+296>>2]=E,Z=_(H+_(_(_(q*s)+_(L*k))+_(K*v))),C[o+288>>2]=Z,v=C[o+312>>2],s=C[o+304>>2],k=C[o+308>>2],a[o+316>>2]=0,m=_(N+_(_(_(P*s)+_(U*k))+_(x*v))),C[o+308>>2]=m,R=_(V+_(_(_(z*s)+_(J*k))+_(I*v))),C[o+312>>2]=R,Q=_(H+_(_(_(q*s)+_(L*k))+_(K*v))),C[o+304>>2]=Q,B=C[o+328>>2],s=C[o+320>>2],k=C[o+324>>2],a[o+332>>2]=0,h=_(N+_(_(_(P*s)+_(U*k))+_(x*B))),C[o+324>>2]=h,v=_(H+_(_(_(q*s)+_(L*k))+_(K*B))),C[o+320>>2]=v,s=_(V+_(_(_(z*s)+_(J*k))+_(I*B))),C[o+328>>2]=s,k=_(d-w),d=_(g-W),c=_(c-W),g=_(l-w),B=_(_(k*d)-_(c*g)),l=_(F-p),F=_(c*l),c=_(aA-p),d=_(F-_(c*d)),l=_(_(c*g)-_(k*l)),c=_(_(1)/_(y(_(_(d*d)+_(_(l*l)+_(B*B)))))),g=_(B*c),C[o+412>>2]=g,l=_(l*c),C[o+408>>2]=l,c=_(d*c),C[o+416>>2]=c,C[o+420>>2]=_(w*c)+_(_(W*l)+_(p*g)),k=_(R-E),d=_(v-Z),c=_(Q-Z),g=_(s-E),s=_(_(k*d)-_(c*g)),l=_(h-D),v=_(c*l),c=_(m-D),d=_(v-_(c*d)),l=_(_(c*g)-_(k*l)),c=_(_(1)/_(y(_(_(d*d)+_(_(l*l)+_(s*s)))))),g=_(s*c),C[o+340>>2]=g,l=_(l*c),C[o+336>>2]=l,c=_(d*c),C[o+344>>2]=c,C[o+348>>2]=_(E*c)+_(_(Z*l)+_(D*g)),n=n+-1|0,ee(o+360|0,o+288|0)&&fe(o+360|0,o+288|0,o+8|0)&&(G=a[o+12>>2],G))for(tA=(G<<4)+nA|0;c=C[o+8>>2],b=a[A+16>>2],Qt[a[a[b>>2]+8>>2]](b,a[A+28>>2],a[A+24>>2]),b=a[A+16>>2],Qt[a[a[b>>2]+12>>2]](b,a[A+36>>2],a[A+32>>2]),G=G+-1|0,c=_(-c),u=a[A+12>>2],u||(b=a[A+4>>2],u=0|Qt[a[a[b>>2]+12>>2]](b,a[e+8>>2],a[r+8>>2]),a[A+12>>2]=u),b=a[A+16>>2],a[b+4>>2]=u,Qt[a[a[b>>2]+16>>2]](b,nA,tA,c),tA=tA+-16|0,G;);if(t=t+8|0,!n)break}Qt[a[a[i>>2]+116>>2]](i),Qt[a[a[f>>2]+116>>2]](f),Y=o+432|0}(A,e,r,i,t,a[n+836>>2],a[n+828>>2]);A=a[n+836>>2],A&&(o[n+840|0]&&CA(A),a[n+836>>2]=0)}else{if(b=a[t+156>>2],c=b+-1|0,a[A+36>>2]=c,!b)break A;for(;_e(A,e,r,i,a[a[t+164>>2]+(c<<2)>>2]),b=a[A+36>>2],c=b+-1|0,a[A+36>>2]=c,b;);}else{if(b=a[i+156>>2],c=b+-1|0,a[A+28>>2]=c,!b)break A;for(;_e(A,e,r,a[a[i+164>>2]+(c<<2)>>2],t),b=a[A+28>>2],c=b+-1|0,a[A+28>>2]=c,b;);}Y=n+976|0}function me(A,e,r,i,t,n){var c,b=0,l=0,u=0,s=0,k=0,v=0,d=0,R=0,Q=0,h=0;c=Y-528|0,Y=c;A:if(2!=(0|Qt[a[a[i>>2]+80>>2]](i)))if(l=1!=(0|Qt[a[a[i>>2]+80>>2]](i)),b=a[t+4>>2],l|28!=(0|b))if(31!=(0|b))if(b+-21>>>0<=8)!function(A,e,r,i,t,n){var o=0,c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),V=_(0),N=0,I=_(0);o=Y-128|0,Y=o,f[o+116|0]=n,a[o+112>>2]=i,a[o+100>>2]=A,a[o+96>>2]=8784,a[o+104>>2]=e,a[o+108>>2]=r,N=o,I=_(Qt[a[a[t>>2]+48>>2]](t)),C[N+120>>2]=I,A=a[r+12>>2],m=C[A+52>>2],R=C[A+56>>2],e=a[e+12>>2],Q=C[e+52>>2],h=C[e+56>>2],c=C[A+20>>2],b=C[A+36>>2],G=C[e+20>>2],y=C[e+36>>2],p=C[e+24>>2],l=C[A+24>>2],F=C[e+40>>2],u=C[A+40>>2],W=C[e+32>>2],s=C[A+32>>2],w=C[e>>2],k=C[A>>2],D=C[e+16>>2],v=C[A+16>>2],d=C[A+48>>2],E=C[e+48>>2],g=C[A+4>>2],Z=C[e+4>>2],V=C[e+8>>2],B=C[A+8>>2],a[o+92>>2]=0,a[o+76>>2]=0,a[o+60>>2]=0,C[o+72>>2]=_(_(B*V)+_(l*p))+_(u*F),C[o+68>>2]=_(_(B*Z)+_(l*G))+_(u*y),C[o+56>>2]=_(_(g*V)+_(c*p))+_(b*F),C[o+52>>2]=_(_(g*Z)+_(c*G))+_(b*y),d=_(-d),C[o+88>>2]=_(_(_(B*d)-_(l*m))-_(u*R))+_(_(_(B*E)+_(l*Q))+_(u*h)),C[o+84>>2]=_(_(_(g*d)-_(c*m))-_(b*R))+_(_(_(g*E)+_(c*Q))+_(b*h)),a[o+44>>2]=0,C[o+32>>2]=_(_(k*w)+_(v*D))+_(s*W),C[o+64>>2]=_(_(B*w)+_(l*D))+_(u*W),C[o+48>>2]=_(_(g*w)+_(c*D))+_(b*W),C[o+40>>2]=_(_(k*V)+_(v*p))+_(s*F),C[o+36>>2]=_(_(k*Z)+_(v*G))+_(s*y),C[o+80>>2]=_(_(_(k*d)-_(v*m))-_(s*R))+_(_(_(k*E)+_(v*Q))+_(s*h)),Qt[a[a[i>>2]+8>>2]](i,o+32|0,o+16|0,o),Qt[a[a[t>>2]+64>>2]](t,o+96|0,o+16|0,o),Y=o+128|0}(A,e,r,i,t,n);else{if(b=a[e+12>>2],u=b+8|0,l=a[u>>2],u=a[u+4>>2],d=a[b>>2],Q=a[b+4>>2],k=b+24|0,v=a[k+4>>2],s=c+488|0,a[s>>2]=a[k>>2],a[s+4>>2]=v,s=c+472|0,a[s>>2]=l,a[s+4>>2]=u,u=a[b+16>>2],l=a[b+20>>2],k=b+40|0,v=a[k+4>>2],s=c+504|0,a[s>>2]=a[k>>2],a[s+4>>2]=v,s=a[b+32>>2],k=a[b+36>>2],R=b+56|0,h=a[R+4>>2],v=c+520|0,a[v>>2]=a[R>>2],a[v+4>>2]=h,a[c+464>>2]=d,a[c+468>>2]=Q,a[c+480>>2]=u,a[c+484>>2]=l,a[c+496>>2]=s,a[c+500>>2]=k,u=a[b+52>>2],a[c+512>>2]=a[b+48>>2],a[c+516>>2]=u,b=a[r+12>>2],u=b+8|0,l=a[u>>2],u=a[u+4>>2],d=a[b>>2],Q=a[b+4>>2],k=b+24|0,v=a[k+4>>2],s=c+424|0,a[s>>2]=a[k>>2],a[s+4>>2]=v,s=c+408|0,a[s>>2]=l,a[s+4>>2]=u,u=a[b+16>>2],l=a[b+20>>2],k=b+40|0,v=a[k+4>>2],s=c+440|0,a[s>>2]=a[k>>2],a[s+4>>2]=v,s=a[b+32>>2],k=a[b+36>>2],R=b+56|0,h=a[R+4>>2],v=c+456|0,a[v>>2]=a[R>>2],a[v+4>>2]=h,a[c+400>>2]=d,a[c+404>>2]=Q,a[c+416>>2]=u,a[c+420>>2]=l,a[c+432>>2]=s,a[c+436>>2]=k,u=a[b+52>>2],a[c+448>>2]=a[b+48>>2],a[c+452>>2]=u,a[c+388>>2]=0,f[c+392|0]=1,a[c+380>>2]=0,a[c+384>>2]=0,function(A,e,r,i,t){var n,c=0,b=0,l=0,u=_(0),s=_(0),k=_(0),v=0,d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=0,y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=0,E=_(0),Z=_(0),V=_(0);if(n=Y-96|0,Y=n,a[r+72>>2])l=A+20|0,R=C[l>>2],v=n+20|0,a[v>>2]=a[l>>2],c=A+36|0,Q=C[c>>2],l=n+24|0,a[l>>2]=a[c>>2],a[n+12>>2]=0,h=C[A+4>>2],a[n+16>>2]=a[A+4>>2],p=C[A+32>>2],a[n+8>>2]=a[A+32>>2],F=C[A+16>>2],a[n+4>>2]=a[A+16>>2],W=C[A>>2],a[n>>2]=a[A>>2],d=C[A+52>>2],g=C[A+56>>2],c=A+24|0,u=C[c>>2],b=a[c>>2],s=C[A+8>>2],G=a[A+8>>2],k=C[A+48>>2],c=A+40|0,y=C[c>>2],A=n+40|0,a[A>>2]=a[c>>2],c=n+36|0,a[c>>2]=b,b=n+28|0,a[b>>2]=0,D=n+44|0,a[D>>2]=0,a[n+60>>2]=0,k=_(-k),w=_(_(_(s*k)-_(d*u))-_(g*y)),B=C[e+48>>2],m=_(B*s),s=C[e+52>>2],m=_(m+_(s*u)),u=C[e+56>>2],C[n+56>>2]=w+_(m+_(u*y)),C[n+52>>2]=_(_(_(h*k)-_(d*R))-_(g*Q))+_(_(_(B*h)+_(s*R))+_(u*Q)),a[n+32>>2]=G,C[n+48>>2]=_(_(_(W*k)-_(d*F))-_(g*p))+_(_(_(B*W)+_(s*F))+_(u*p)),d=C[e+36>>2],g=C[e+20>>2],R=C[e+40>>2],Q=C[e+24>>2],h=C[e+32>>2],u=C[e>>2],s=C[e+16>>2],y=C[l>>2],k=C[v>>2],B=C[e+4>>2],w=C[A>>2],m=C[e+8>>2],E=C[c>>2],Z=C[n+16>>2],V=C[n+32>>2],a[D>>2]=0,C[A>>2]=_(_(m*V)+_(Q*E))+_(R*w),C[c>>2]=_(_(B*V)+_(g*E))+_(d*w),a[b>>2]=0,C[l>>2]=_(_(m*Z)+_(Q*k))+_(R*y),C[v>>2]=_(_(B*Z)+_(g*k))+_(d*y),C[n+32>>2]=_(_(u*V)+_(s*E))+_(h*w),C[n+16>>2]=_(_(u*Z)+_(s*k))+_(h*y),a[n+12>>2]=0,C[n+8>>2]=_(_(m*W)+_(Q*F))+_(R*p),C[n+4>>2]=_(_(B*W)+_(g*F))+_(d*p),C[n>>2]=_(_(u*W)+_(s*F))+_(h*p),Qt[a[a[i>>2]+8>>2]](i,n,n- -64|0,n+80|0),_A(r+72|0,n- -64|0,t);else if(Qt[a[a[i>>2]+8>>2]](i,e,n- -64|0,n+80|0),e=0|Qt[a[a[r>>2]+88>>2]](r),e)for(D=n+16|0;;){if(e=e+-1|0,Qt[a[a[r>>2]+120>>2]](r,e,A,n,D),!(C[n+80>>2]>2]|C[n+64>>2]>C[n+16>>2]|C[n+84>>2]>2]|C[n+68>>2]>C[n+20>>2]|C[n+88>>2]>2]|C[n+72>>2]>C[n+24>>2])){if(b=a[t+4>>2],(0|b)==a[t+8>>2]&&(G=b?b<<1:1,!((0|b)>=(0|G)))){G?(i=dA(G<<2),b=a[t+4>>2]):i=0,v=a[t+12>>2];e:{if((0|b)>=1)for(l=i,c=v;a[l>>2]=a[c>>2],l=l+4|0,c=c+4|0,b=b+-1|0,b;);else if(!v)break e;o[t+16|0]&&CA(v),a[t+12>>2]=0,b=a[t+4>>2]}a[t+12>>2]=i,f[t+16|0]=1,a[t+8>>2]=G}a[a[t+12>>2]+(b<<2)>>2]=e,a[t+4>>2]=a[t+4>>2]+1}if(!e)break}Y=n+96|0}(c+464|0,c+400|0,i,t,c+376|0),a[c+380>>2]){if(Qt[a[a[i>>2]+112>>2]](i),zA(c+72|4),t=c+136|0,a[t>>2]=0,a[t+4>>2]=0,a[c+80>>2]=1,t=c+144|0,a[t>>2]=0,a[t+4>>2]=0,t=c+152|0,a[t>>2]=0,a[t+4>>2]=0,t=c+160|0,a[t>>2]=0,a[t+4>>2]=0,t=c+168|0,a[t>>2]=0,a[t+4>>2]=0,t=c+176|0,a[t>>2]=0,a[t+4>>2]=0,a[c+76>>2]=8128,te(c+184|0),a[c+280>>2]=4,a[c+364>>2]=8708,a[c+356>>2]=8628,a[c+348>>2]=8556,a[c+184>>2]=8364,a[c+72>>2]=i,t=c+356|0,Qt[a[a[i>>2]+96>>2]](i)||(t=a[c+72>>2],t=0|Qt[a[a[t>>2]+100>>2]](t)?c+364|0:c+348|0),a[t+4>>2]=c+72,a[c+372>>2]=t,u=0|Qt[a[a[i>>2]+92>>2]](i),t=a[c+380>>2],t)if(n)for(b=(t<<2)-4|0;n=a[a[c+388>>2]+b>>2],a[A+32>>2]=n,l=a[c+372>>2],l=0|Qt[a[a[l>>2]>>2]](l,n),u&&Qt[a[a[i>>2]+132>>2]](c+8|0,i,n),a[c+8>>2]=e,a[c+20>>2]=a[e+12>>2],d=a[e+8>>2],a[c+16>>2]=d,a[c+12>>2]=l,a[c+28>>2]=a[A+24>>2],a[c+24>>2]=a[A+28>>2],l=a[A+16>>2],n=a[l+8>>2],a[((0|d)==a[n+8>>2]?8:12)+l>>2]=c+8,ge(A,r,c+8|0),a[a[A+16>>2]+8>>2]=n,b=b+-4|0,t=t+-1|0,t;);else for(b=(t<<2)-4|0;n=a[a[c+388>>2]+b>>2],a[A+24>>2]=n,l=a[c+372>>2],l=0|Qt[a[a[l>>2]>>2]](l,n),u&&Qt[a[a[i>>2]+132>>2]](c+8|0,i,n),a[c+8>>2]=e,a[c+20>>2]=a[e+12>>2],d=a[e+8>>2],a[c+16>>2]=d,a[c+12>>2]=l,a[c+28>>2]=a[A+24>>2],a[c+24>>2]=a[A+28>>2],l=a[A+16>>2],n=a[l+8>>2],a[((0|d)==a[n+8>>2]?8:12)+l>>2]=c+8,ge(A,c+8|0,r),a[a[A+16>>2]+8>>2]=n,b=b+-4|0,t=t+-1|0,t;);Qt[a[a[i>>2]+116>>2]](i),Ae(c+184|0),Ae(c+72|4)}A=a[c+388>>2],A&&(o[c+392|0]&&CA(A),a[c+388>>2]=0)}else!function(A,e,r,i,f,t){var n=0,o=0,c=0,b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=0,y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=0,Z=0,V=0,N=0,I=_(0),J=_(0),x=_(0);if(o=Y-96|0,Y=o,c=a[f+20>>2],c)for(n=a[r+12>>2],I=C[n+56>>2],J=C[n+52>>2],s=C[n+40>>2],k=C[n+36>>2],v=C[n+24>>2],d=C[n+20>>2],x=C[n+48>>2],g=C[n+32>>2],m=C[n+16>>2],R=C[n+8>>2],Q=C[n+4>>2],h=C[n>>2],G=c+-1|0,c=B(c,80)+-80|0;n=a[f+28>>2]+c|0,V=a[n- -64>>2],a[o+92>>2]=0,a[o+76>>2]=0,a[o+60>>2]=0,a[o+44>>2]=0,b=C[n+8>>2],l=C[n+24>>2],u=C[n+40>>2],C[o+72>>2]=_(_(g*b)+_(k*l))+_(s*u),y=C[n+4>>2],p=C[n+20>>2],F=C[n+36>>2],C[o+68>>2]=_(_(g*y)+_(k*p))+_(s*F),W=C[n>>2],w=C[n+16>>2],D=C[n+32>>2],C[o+64>>2]=_(_(g*W)+_(k*w))+_(s*D),C[o+56>>2]=_(_(m*b)+_(d*l))+_(v*u),C[o+52>>2]=_(_(m*y)+_(d*p))+_(v*F),C[o+48>>2]=_(_(m*W)+_(d*w))+_(v*D),C[o+40>>2]=_(_(h*b)+_(Q*l))+_(R*u),C[o+36>>2]=_(_(h*y)+_(Q*p))+_(R*F),C[o+32>>2]=_(_(h*W)+_(Q*w))+_(R*D),b=C[n+48>>2],l=C[n+52>>2],u=C[n+56>>2],C[o+88>>2]=I+_(_(_(g*b)+_(k*l))+_(s*u)),C[o+84>>2]=J+_(_(_(m*b)+_(d*l))+_(v*u)),C[o+80>>2]=x+_(_(_(h*b)+_(Q*l))+_(R*u)),a[o+8>>2]=r,N=a[r+8>>2],a[o+16>>2]=N,a[o+12>>2]=V,a[o+28>>2]=G,a[o+24>>2]=-1,n=a[A+16>>2],a[o+20>>2]=o+32,E=a[n+8>>2],Z=n+8|0,a[E+8>>2]!=(0|N)&&(E=a[n+12>>2],Z=n+12|0),a[Z>>2]=o+8,me(A,e,o+8|0,i,V,t),n=a[A+16>>2],a[(a[a[n+8>>2]+8>>2]==a[o+16>>2]?8:12)+n>>2]=E,c=c+-80|0,G=G+-1|0,-1!=(0|G););Y=o+96|0}(A,e,r,i,t,n);else!function(A,e,r,i,f,t){var n=0,o=0,c=_(0),b=_(0),l=0,u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),R=_(0),Q=_(0),h=0,G=0,y=_(0),p=0,F=0,W=0,w=0,D=_(0),E=0,Z=0,V=_(0),N=_(0);if(o=Y-144|0,Y=o,n=a[e+12>>2],p=n+8|0,h=a[p+4>>2],l=o+88|0,a[l>>2]=a[p>>2],a[l+4>>2]=h,l=a[n>>2],p=a[n+4>>2],F=n+24|0,G=a[F+4>>2],h=o+104|0,a[h>>2]=a[F>>2],a[h+4>>2]=G,h=a[n+16>>2],F=a[n+20>>2],W=n+40|0,w=a[W+4>>2],G=o+120|0,a[G>>2]=a[W>>2],a[G+4>>2]=w,G=a[n+32>>2],W=a[n+36>>2],E=n+56|0,Z=a[E+4>>2],w=o+136|0,a[w>>2]=a[E>>2],a[w+4>>2]=Z,a[o+80>>2]=l,a[o+84>>2]=p,a[o+96>>2]=h,a[o+100>>2]=F,a[o+112>>2]=G,a[o+116>>2]=W,l=a[n+52>>2],a[o+128>>2]=a[n+48>>2],a[o+132>>2]=l,n=a[r+12>>2],d=C[n+20>>2],s=C[n+24>>2],k=C[n+36>>2],v=C[n+40>>2],R=C[n+8>>2],Q=C[n>>2],D=C[n+4>>2],V=C[n+16>>2],N=C[n+32>>2],c=C[f+52>>2],b=C[f+56>>2],u=C[f+60>>2],y=_(_(_(_(C[n+48>>2]*c)+_(C[n+52>>2]*b))+_(C[n+56>>2]*u))+C[f+68>>2]),C[o+76>>2]=y,k=_(_(_(N*c)+_(k*b))+_(v*u)),C[o+72>>2]=k,d=_(_(_(V*c)+_(d*b))+_(s*u)),C[o+68>>2]=d,s=_(_(_(Q*c)+_(D*b))+_(R*u)),C[o+64>>2]=s,Qt[a[a[i>>2]+8>>2]](i,o+80|0,o+32|0,o+48|0),c=_(Qt[a[a[f>>2]+48>>2]](f)),n=o+52|0,b=_(c+C[n>>2]),C[n>>2]=b,n=o+56|0,u=_(c+C[n>>2]),C[n>>2]=u,R=_(C[o+36>>2]-c),C[o+36>>2]=R,v=_(c+C[o+48>>2]),C[o+48>>2]=v,Q=_(C[o+32>>2]-c),C[o+32>>2]=Q,c=_(C[o+40>>2]-c),C[o+40>>2]=c,Q=_(_(Q+v)*_(.5)),R=_(_(R+b)*_(.5)),c=_(_(c+u)*_(.5)),D=_(_(_(Q*s)+_(R*d))+_(c*k)),c=_(_(_(_(v-Q)*_(m(s)))+_(_(b-R)*_(m(d))))+_(_(u-c)*_(m(k)))),!(y>_(_(D+c)+_(9.999999974752427e-7))|_(y+_(9.999999974752427e-7))>=_(D-c)^1)){if(Qt[a[a[i>>2]+112>>2]](i),c=_(Qt[a[a[i>>2]+48>>2]](i)),b=_(Qt[a[a[f>>2]+48>>2]](f)),f=a[i+188>>2],f)for(d=_(c+b),f=f+-1|0;n=a[i+184>>2]+B(a[i+196>>2],f)|0,1!=a[i+192>>2]?(c=_(C[n>>2]*C[i+160>>2]),C[o+16>>2]=c,b=_(C[n+4>>2]*C[i+164>>2]),C[o+20>>2]=b,u=_(C[n+8>>2]*C[i+168>>2])):(c=_(g[n>>3]*+C[i+160>>2]),C[o+16>>2]=c,b=_(g[n+8>>3]*+C[i+164>>2]),C[o+20>>2]=b,u=_(g[n+16>>3]*+C[i+168>>2])),a[o+28>>2]=0,s=_(_(_(_(c*C[o+96>>2])+_(b*C[o+100>>2]))+_(u*C[o+104>>2]))+C[o+132>>2]),C[o+20>>2]=s,y=C[o+68>>2],v=_(_(_(_(c*C[o+80>>2])+_(b*C[o+84>>2]))+_(u*C[o+88>>2]))+C[o+128>>2]),C[o+16>>2]=v,k=C[o+64>>2],c=_(_(_(_(c*C[o+112>>2])+_(b*C[o+116>>2]))+_(u*C[o+120>>2]))+C[o+136>>2]),C[o+24>>2]=c,b=C[o+72>>2],c=_(_(_(_(_(v*k)+_(s*y))+_(c*b))-C[o+76>>2])-d),c<_(0)&&(t?(a[o+12>>2]=0,C[o+8>>2]=-b,C[o+4>>2]=-y,C[o>>2]=-k,n=a[A+16>>2],Qt[a[a[n>>2]+8>>2]](n,a[A+28>>2],a[A+24>>2]),n=a[A+16>>2],Qt[a[a[n>>2]+12>>2]](n,a[A+36>>2],a[A+32>>2]),n=a[A+12>>2],n||(n=a[A+4>>2],n=0|Qt[a[a[n>>2]+12>>2]](n,a[r+8>>2],a[e+8>>2]),a[A+12>>2]=n),l=a[A+16>>2],a[l+4>>2]=n,Qt[a[a[l>>2]+16>>2]](l,o,o+16|0,c)):(n=a[A+16>>2],Qt[a[a[n>>2]+8>>2]](n,a[A+28>>2],a[A+24>>2]),n=a[A+16>>2],Qt[a[a[n>>2]+12>>2]](n,a[A+36>>2],a[A+32>>2]),n=a[A+12>>2],n||(n=a[A+4>>2],n=0|Qt[a[a[n>>2]+12>>2]](n,a[e+8>>2],a[r+8>>2]),a[A+12>>2]=n),l=a[A+16>>2],a[l+4>>2]=n,Qt[a[a[l>>2]+16>>2]](l,o- -64|0,o+16|0,c))),f=f+-1|0,-1!=(0|f););Qt[a[a[i>>2]+116>>2]](i)}Y=o+144|0}(A,e,r,i,t,n);else{if(u=(n?36:28)+A|0,l=a[i+156>>2],b=l+-1|0,a[u>>2]=b,!l)break A;for(;me(A,e,r,a[a[i+164>>2]+(b<<2)>>2],t,n),l=a[u>>2],b=l+-1|0,a[u>>2]=b,l;);}Y=c+528|0}function Re(A,e,r,i,f){return _(_(1))}function Qe(A){return A|=0,A+16|0}function he(A,e,r){A|=0,e=_(e),r|=0,a[r>>2]=0,a[r+4>>2]=0,A=r+8|0,a[A>>2]=0,a[A+4>>2]=0}function Ge(A,e){A|=0,e=_(e),C[A+48>>2]=e}function ye(A){return 52}function pe(A){return 2}function Fe(A){return 3}function We(A){return 1}function we(A){return 0}function De(A,e,r){}function Ee(A){var e=0;a[A+132>>2]=0,a[A+136>>2]=0,a[A>>2]=8964,a[A+188>>2]=0,a[A+192>>2]=0,a[A+180>>2]=0,a[A+184>>2]=1566444395,a[A+164>>2]=1065353216,a[A+168>>2]=1065353216,a[A+276>>2]=0,a[A+280>>2]=0,a[A+268>>2]=1065353216,a[A+272>>2]=0,a[A+260>>2]=-1,a[A+264>>2]=-1,a[A+252>>2]=1,a[A+256>>2]=0,a[A+244>>2]=1036831949,a[A+248>>2]=1176256512,a[A+236>>2]=0,a[A+240>>2]=0,a[A+228>>2]=1056964608,a[A+232>>2]=0,a[A+220>>2]=1,a[A+224>>2]=0,a[A+212>>2]=-1,a[A+216>>2]=-1,a[A+204>>2]=1,a[A+208>>2]=-1,e=A+140|0,a[e>>2]=0,a[e+4>>2]=0,e=A+148|0,a[e>>2]=0,a[e+4>>2]=0,e=A+156|0,a[e>>2]=0,a[e+4>>2]=0,e=A+172|0,a[e>>2]=1065353216,a[e+4>>2]=0,e=A+196|0,a[e>>2]=0,a[e+4>>2]=0,f[A+300|0]=1,a[A+304>>2]=0,a[A+296>>2]=0,e=A+288|0,a[e>>2]=0,a[e+4>>2]=0,e=A+8|0,a[e>>2]=0,a[e+4>>2]=0,a[A+4>>2]=1065353216,e=A+16|0,a[e>>2]=0,a[e+4>>2]=0,e=A+28|0,a[e>>2]=0,a[e+4>>2]=0,a[A+24>>2]=1065353216,e=A+36|0,a[e>>2]=0,a[e+4>>2]=0,e=A+48|0,a[e>>2]=0,a[e+4>>2]=0,a[A+44>>2]=1065353216,e=A+56|0,a[e>>2]=0,a[e+4>>2]=0,e=A+72|0,a[e>>2]=0,a[e+4>>2]=0,e=A- -64|0,a[e>>2]=0,a[e+4>>2]=1065353216,e=A+80|0,a[e>>2]=0,a[e+4>>2]=0,a[A+88>>2]=1065353216,e=A+100|0,a[e>>2]=0,a[e+4>>2]=0,e=A+92|0,a[e>>2]=0,a[e+4>>2]=0,a[A+128>>2]=0,a[A+108>>2]=1065353216,e=A+120|0,a[e>>2]=0,a[e+4>>2]=0,A=A+112|0,a[A>>2]=0,a[A+4>>2]=0}function Ze(A){var e;return A|=0,a[A>>2]=8964,e=a[A+296>>2],e&&(o[A+300|0]&&CA(e),a[A+296>>2]=0),a[A+296>>2]=0,a[A+288>>2]=0,a[A+292>>2]=0,f[A+300|0]=1,0|A}function Ye(A,e){4!=(-2&a[A+220>>2])&&(a[A+220>>2]=e)}function Ve(A,e){3&o[A+204|0]&&!e||(4!=(-2&a[A+220>>2])&&(a[A+220>>2]=1),a[A+224>>2]=0)}function Ne(A,e,r){A|=0,e|=0,r|=0;var i=0,f=0;return a[e+16>>2]=a[A+4>>2],a[e+20>>2]=a[A+8>>2],a[e+24>>2]=a[A+12>>2],a[e+28>>2]=a[A+16>>2],a[e+32>>2]=a[A+20>>2],a[e+36>>2]=a[A+24>>2],a[e+40>>2]=a[A+28>>2],a[e+44>>2]=a[A+32>>2],a[e+48>>2]=a[A+36>>2],a[e+52>>2]=a[A+40>>2],a[e+56>>2]=a[A+44>>2],a[e+60>>2]=a[A+48>>2],a[e+64>>2]=a[A+52>>2],a[e+68>>2]=a[A+56>>2],a[e+72>>2]=a[A+60>>2],a[e+76>>2]=a[A- -64>>2],a[e+80>>2]=a[A+68>>2],a[e+84>>2]=a[A+72>>2],a[e+88>>2]=a[A+76>>2],a[e+92>>2]=a[A+80>>2],a[e+96>>2]=a[A+84>>2],a[e+100>>2]=a[A+88>>2],a[e+104>>2]=a[A+92>>2],a[e+108>>2]=a[A+96>>2],a[e+112>>2]=a[A+100>>2],a[e+116>>2]=a[A+104>>2],a[e+120>>2]=a[A+108>>2],a[e+124>>2]=a[A+112>>2],a[e+128>>2]=a[A+116>>2],a[e+132>>2]=a[A+120>>2],a[e+136>>2]=a[A+124>>2],a[e+140>>2]=a[A+128>>2],a[e+144>>2]=a[A+132>>2],a[e+148>>2]=a[A+136>>2],a[e+152>>2]=a[A+140>>2],a[e+156>>2]=a[A+144>>2],a[e+160>>2]=a[A+148>>2],a[e+164>>2]=a[A+152>>2],a[e+168>>2]=a[A+156>>2],a[e+172>>2]=a[A+160>>2],a[e+176>>2]=a[A+164>>2],a[e+180>>2]=a[A+168>>2],a[e+184>>2]=a[A+172>>2],a[e+188>>2]=a[A+176>>2],a[e+232>>2]=a[A+180>>2],a[e+192>>2]=a[A+184>>2],a[e>>2]=0,i=0|Qt[a[a[r>>2]+28>>2]](r,a[A+192>>2]),f=a[A+228>>2],a[e+196>>2]=a[A+224>>2],a[e+200>>2]=f,f=a[A+212>>2],a[e+240>>2]=a[A+208>>2],a[e+244>>2]=f,a[e+8>>2]=0,a[e+4>>2]=i,a[e+236>>2]=a[A+204>>2],a[e+248>>2]=a[A+220>>2],a[e+204>>2]=a[A+236>>2],a[e+208>>2]=a[A+244>>2],a[e+212>>2]=a[A+248>>2],a[e+216>>2]=a[A+232>>2],a[e+252>>2]=a[A+252>>2],i=0|Qt[a[a[r>>2]+40>>2]](r,A),f=0|Qt[a[a[r>>2]+28>>2]](r,i),a[e+12>>2]=f,f&&Qt[a[a[r>>2]+48>>2]](r,i),a[e+220>>2]=a[A+268>>2],r=a[A+280>>2],i=a[A+276>>2],A=a[A+272>>2],a[e+260>>2]=0,a[e+224>>2]=A,a[e+228>>2]=i,a[e+256>>2]=r,8992}function Ie(A,e){A|=0,e=_(e);var r,i,f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0);f=_(Qt[a[a[A>>2]+48>>2]](A)),t=_(Qt[a[a[A>>2]+48>>2]](A)),n=_(Qt[a[a[A>>2]+48>>2]](A)),C[A+48>>2]=e,r=A+40|0,e=C[r>>2],i=A+36|0,o=C[i>>2],c=C[A+32>>2],b=_(Qt[a[a[A>>2]+48>>2]](A)),l=_(Qt[a[a[A>>2]+48>>2]](A)),u=_(Qt[a[a[A>>2]+48>>2]](A)),a[A+44>>2]=0,C[i>>2]=_(t+o)-l,C[A+32>>2]=_(f+c)-b,C[r>>2]=_(n+e)-u}function Je(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),R=_(0),Q=_(0);f=_(Qt[a[a[A>>2]+48>>2]](A)),b=C[e+52>>2],o=C[e+20>>2],s=C[e+24>>2],l=C[e+56>>2],c=C[e+36>>2],t=C[A+36>>2],k=C[e+40>>2],v=C[A+40>>2],u=C[e+48>>2],d=C[e>>2],g=C[e+4>>2],B=C[e+8>>2],R=C[e+16>>2],Q=C[e+32>>2],n=C[A+32>>2],a[r+12>>2]=0,n=_(f+n),t=_(f+t),f=_(f+v),c=_(_(_(n*_(m(Q)))+_(t*_(m(c))))+_(f*_(m(k)))),C[r+8>>2]=l-c,o=_(_(_(n*_(m(R)))+_(t*_(m(o))))+_(f*_(m(s)))),C[r+4>>2]=b-o,f=_(_(_(n*_(m(d)))+_(t*_(m(g))))+_(f*_(m(B)))),C[r>>2]=u-f,a[i+12>>2]=0,C[i+8>>2]=l+c,C[i+4>>2]=o+b,C[i>>2]=f+u}function xe(A,e){A|=0,e|=0;var r,i,f,t,n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0);n=_(Qt[a[a[A>>2]+48>>2]](A)),o=_(Qt[a[a[A>>2]+48>>2]](A)),c=_(Qt[a[a[A>>2]+48>>2]](A)),r=A+20|0,b=C[r>>2],i=A+36|0,l=C[i>>2],f=A+24|0,u=C[f>>2],t=A+40|0,s=C[t>>2],k=C[A+16>>2],v=C[A+32>>2],EA(A,e),a[A+44>>2]=0,C[t>>2]=_(_(_(c+s)/u)*C[f>>2])-c,C[i>>2]=_(_(_(o+l)/b)*C[r>>2])-o,C[A+32>>2]=_(_(_(n+v)/k)*C[A+16>>2])-n}function Ue(A){return 6}function Me(A){A|=0;var e=_(0),r=_(0);return e=C[A+32>>2],r=_(Qt[a[a[A>>2]+48>>2]](A)),_(Qt[a[a[A>>2]+48>>2]](A)),_(Qt[a[a[A>>2]+48>>2]](A)),_(_(e+r))}function Se(A,e,r,i,f,t){var n,o=_(0),c=_(0),b=_(0),l=_(0),u=0,s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=0,m=0,R=_(0),Q=0,h=0,G=_(0),p=_(0),F=0,W=_(0),w=0,D=_(0),E=_(0),Z=_(0),V=_(0),N=_(0),I=_(0),J=0,x=0,U=0,M=0,S=0,X=0,T=0,j=0,O=0;n=Y-32|0,Y=n;A:if(!(a[A+56>>2]<1))for(c=C[i>>2],k=C[r>>2],l=_(c-k),b=C[i+4>>2],v=C[r+4>>2],s=_(b-v),o=C[i+8>>2],d=C[r+8>>2],g=_(o-d),R=_(_(1)/_(y(_(_(_(l*l)+_(s*s))+_(g*g))))),G=g,g=_(g*R),p=l,l=_(l*R),W=s,s=_(s*R),W=_(_(G*g)+_(_(p*l)+_(W*s))),R=C[t+8>>2],D=_((d>2],E=_((v>2],Z=_((k>2],V=_(d+o),v=b>2],N=_(v+b),k=c>2],I=_(k+c),i=a[A+96>>2],k=g==_(0)?_(0xde0b6b000000000):_(_(1)/g),B=k<_(0),J=(B<<4)+n|8,v=s==_(0)?_(0xde0b6b000000000):_(_(1)/s),h=v<_(0),x=(h<<4)+n|4,U=((1^B)<<4)+n|8,M=((1^h)<<4)+n|4,d=l==_(0)?_(0xde0b6b000000000):_(_(1)/l),B=d<_(0),S=(B<<4)+n|0,X=((1^B)<<4)+n|0,h=n+16|0,B=1;;){u=i+8|0,Q=a[u>>2],m=a[u+4>>2],T=a[i>>2],j=a[i+4>>2],u=a[i+20>>2],a[h>>2]=a[i+16>>2],a[h+4>>2]=u,u=i+24|0,O=a[u+4>>2],w=h+8|0,a[w>>2]=a[u>>2],a[w+4>>2]=O,a[n>>2]=T,a[n+4>>2]=j,a[n+8>>2]=Q,a[n+12>>2]=m,C[n>>2]=C[n>>2]-p,C[n+4>>2]=C[n+4>>2]-G,C[n+16>>2]=C[n+16>>2]-c,C[n+20>>2]=C[n+20>>2]-b,C[n+8>>2]=C[n+8>>2]-R,C[n+24>>2]=C[n+24>>2]-o;e:{r:{i:{f:{if(Q=E>2]|N>C[i+20>>2],m=0,I>C[i+16>>2]||(m=0,Z>2]||(m=1)),!(Q|1^(D>2]|V>C[u>>2]?0:m)||(l=C[r+4>>2],c=_(v*_(C[x>>2]-l)),o=C[r>>2],b=_(d*_(C[X>>2]-o)),c>b||(o=_(d*_(C[S>>2]-o)),l=_(v*_(C[M>>2]-l)),o>l||(g=C[r+8>>2],s=_(k*_(C[J>>2]-g)),b=lb||(c=c>o?c:o,o=_(k*_(C[U>>2]-g)),c>o)))))){if(m=a[i+32>>2],u=-1==(0|m),Q=(s>c?s:c)_(0),1!=(0|Q)|-1!=(0|m))break f;Qt[a[a[e>>2]+8>>2]](e,a[i+36>>2],a[i+40>>2]);break i}u=-1==a[i+32>>2],Q=0}if(!u&&!Q)break r}F=F+1|0,i=i- -64|0;break e}u=a[i+32>>2],F=u+F|0,i=(u<<6)+i|0}if((0|F)>=a[A+56>>2])break A;B=B+1|0,o=C[f+8>>2],b=C[f+4>>2],c=C[f>>2],R=C[t+8>>2],G=C[t+4>>2],p=C[t>>2]}a[430]<(0|B)&&(a[430]=B),Y=n+32|0}function Xe(A,e,r,i,f,t,n){var o,c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),d=_(0),g=0,B=_(0),m=_(0),R=_(0),Q=0,h=_(0),G=0,p=_(0),F=_(0),W=0,w=0,D=0,E=0,Z=_(0),V=_(0),N=_(0),I=0,J=0,x=0,U=0,M=0,S=0,X=0,T=0,j=0,O=0,H=0,z=0,P=0,K=0;if(o=Y-32|0,Y=o,s=C[r+4>>2],k=C[i+4>>2],d=C[r>>2],u=C[i>>2],R=C[A+28>>2],c=C[A+12>>2],m=C[i+8>>2],h=C[r+8>>2],b=_((m>2]),b=b>2],b=_(_((R=_(0)?~~b>>>0:0,p=C[A+24>>2],b=C[A+8>>2],l=_((k>2]),l=l>2],l=_(_((p=_(0)?~~l>>>0:0,F=C[A+20>>2],l=C[A+4>>2],B=_((u>2]),B=B>2],B=_(_((F=_(0)?~~B>>>0:0,B=_((h>2]),B=B=_(0)?~~c>>>0:0,c=_((s>2]),c=c=_(0)?~~c>>>0:0,c=_((d>2]),c=c=_(0)?~~c>>>0:0,0<(0|n))for(d=_(u-d),s=_(k-s),k=_(m-h),u=_(_(1)/_(y(_(_(_(d*d)+_(s*s))+_(k*k))))),c=k,k=_(k*u),b=d,d=_(d*u),l=s,s=_(s*u),h=_(_(c*k)+_(_(b*d)+_(l*s))),U=65534&i,M=65534&g,S=65534&G,W|=1,w|=1,D|=1,i=a[A+136>>2],k=k==_(0)?_(0xde0b6b000000000):_(_(1)/k),Q=k<_(0),X=(Q<<4)+o|8,s=s==_(0)?_(0xde0b6b000000000):_(_(1)/s),g=s<_(0),T=(g<<4)+o|4,j=((1^Q)<<4)+o|8,O=((1^g)<<4)+o|4,d=d==_(0)?_(0xde0b6b000000000):_(_(1)/d),Q=d<_(0),H=(Q<<4)+o|0,z=((1^Q)<<4)+o|0,Q=0;;){G=a[i+12>>2],g=0;A:{e:{r:{i:if(!(S>>>0>v[i+6>>1]||(I=v[i>>1],D>>>0>>0|U>>>0>v[i+10>>1]||(J=v[i+4>>1],W>>>0>>0|M>>>0>v[i+8>>1]||(x=v[i+2>>1],w>>>0>>0))))){if(a[o+12>>2]=0,g=v[i+10>>1],P=v[i+8>>1],K=v[i+6>>1],a[o+28>>2]=0,u=C[A+36>>2],c=C[A+4>>2],C[o>>2]=_(_(_(I>>>0)/u)+c)-C[t>>2],b=C[A+40>>2],l=C[A+8>>2],C[o+4>>2]=_(_(_(x>>>0)/b)+l)-C[t+4>>2],m=C[A+44>>2],R=C[A+12>>2],C[o+8>>2]=_(_(_(J>>>0)/m)+R)-C[t+8>>2],C[o+16>>2]=_(c+_(_(K>>>0)/u))-C[f>>2],C[o+20>>2]=_(l+_(_(P>>>0)/b))-C[f+4>>2],C[o+24>>2]=_(R+_(_(g>>>0)/m))-C[f+8>>2],l=C[r+4>>2],u=_(s*_(C[T>>2]-l)),b=C[r>>2],c=_(d*_(C[z>>2]-b)),!(u>c||(b=_(d*_(C[H>>2]-b)),l=_(s*_(C[O>>2]-l)),b>l||(R=C[r+8>>2],m=_(k*_(C[X>>2]-R)),c=lc||(u=u>b?u:b,b=_(k*_(C[j>>2]-R)),u>b))))){if(g=(m>u?m:u)_(0),!g|(0|G)<0)break i;g=a[i+12>>2],Qt[a[a[e>>2]+8>>2]](e,g>>21,2097151&g);break r}g=0}if(!((0|G)>-1||g))break e}E=E+1|0,i=i+16|0;break A}g=a[i+12>>2],E=E-g|0,i=i-(g<<4)|0}if(Q=Q+1|0,!((0|E)<(0|n)))break}a[430]<(0|Q)&&(a[430]=Q),Y=o+32|0}function Te(A,e,r,i){var f;f=Y-16|0,Y=f,a[f+8>>2]=e,a[f>>2]=9988,a[f+4>>2]=a[A+52>>2],function(A,e,r,i){var f,t=0;f=Y-32|0,Y=f,t=f+24|0,a[t>>2]=0,a[t+4>>2]=0,a[f+16>>2]=0,a[f+20>>2]=0,t=f+8|0,a[t>>2]=0,a[t+4>>2]=0,a[f>>2]=0,a[f+4>>2]=0,o[A+60|0]?Xe(A,e,r,i,f+16|0,f,a[A+56>>2]):Se(A,e,r,i,f+16|0,f),Y=f+32|0}(a[A+56>>2],f,r,i),Y=f+16|0}function je(A,e,r,i,f,t){var n;n=Y-16|0,Y=n,a[n+8>>2]=e,a[n>>2]=10156,a[n+4>>2]=a[A+52>>2],function(A,e,r,i,f,t){o[A+60|0]?Xe(A,e,r,i,f,t,a[A+56>>2]):Se(A,e,r,i,f,t)}(a[A+56>>2],n,r,i,f,t),Y=n+16|0}function Oe(A,e,r){A|=0,e|=0,r|=0;var i,f,t,n,o,c=0,b=_(0),l=_(0),u=_(0),s=0,k=0,d=_(0);i=Y-80|0,Y=i,c=a[A+4>>2],Qt[a[a[c>>2]+16>>2]](c,i+28|0,i+24|0,i+20|0,i+16|0,i+12|0,i+8|0,i+4|0,i,e),f=a[A+4>>2],s=f+12|0,t=a[i+12>>2]+B(a[i+8>>2],r)|0,n=a[i+28>>2],o=a[i+20>>2];A:{e:{r:{i:{f:{t:{n:{if(3!=a[i>>2]){if(k=a[i+16>>2],c=B(k,a[t+8>>2])+n|0,o)break n;l=_(C[c+4>>2]*C[f+8>>2]),u=_(C[c>>2]*C[f+4>>2]),b=C[f+12>>2],c=c+8|0;break t}if(k=a[i+16>>2],c=B(k,v[t+4>>1])+n|0,o?(l=_(C[f+8>>2]*_(g[c+8>>3])),u=_(C[f+4>>2]*_(g[c>>3])),b=_(g[c+16>>3]),c=s):(l=_(C[c+4>>2]*C[f+8>>2]),u=_(C[c>>2]*C[f+4>>2]),b=C[f+12>>2],c=c+8|0),d=C[c>>2],a[i+76>>2]=0,C[i+68>>2]=l,C[i+72>>2]=d*b,C[i+64>>2]=u,c=B(k,v[t+2>>1])+n|0,!o)break f;l=_(C[f+8>>2]*_(g[c+8>>3])),u=_(C[f+4>>2]*_(g[c>>3])),b=_(g[c+16>>3]),c=s;break i}l=_(C[f+8>>2]*_(g[c+8>>3])),u=_(C[f+4>>2]*_(g[c>>3])),b=_(g[c+16>>3]),c=s}if(d=C[c>>2],a[i+76>>2]=0,C[i+68>>2]=l,C[i+72>>2]=d*b,C[i+64>>2]=u,c=B(k,a[t+4>>2])+n|0,!o)break r;l=_(C[f+8>>2]*_(g[c+8>>3])),u=_(C[f+4>>2]*_(g[c>>3])),b=_(g[c+16>>3]),c=s;break e}l=_(C[c+4>>2]*C[f+8>>2]),u=_(C[c>>2]*C[f+4>>2]),b=C[f+12>>2],c=c+8|0}d=C[c>>2],a[i+60>>2]=0,C[i+52>>2]=l,C[i+56>>2]=d*b,C[i+48>>2]=u,c=B(k,v[t>>1])+n|0,o?(l=_(C[f+8>>2]*_(g[c+8>>3])),u=_(C[f+4>>2]*_(g[c>>3])),b=_(g[c+16>>3])):(s=c+8|0,l=_(C[c+4>>2]*C[f+8>>2]),u=_(C[c>>2]*C[f+4>>2]),b=C[f+12>>2]),b=_(C[s>>2]*b);break A}l=_(C[c+4>>2]*C[f+8>>2]),u=_(C[c>>2]*C[f+4>>2]),b=C[f+12>>2],c=c+8|0}d=C[c>>2],a[i+60>>2]=0,C[i+52>>2]=l,C[i+56>>2]=d*b,C[i+48>>2]=u,c=B(k,a[t>>2])+n|0,o?(l=_(C[f+8>>2]*_(g[c+8>>3])),u=_(C[f+4>>2]*_(g[c>>3])),b=_(g[c+16>>3])):(s=c+8|0,l=_(C[c+4>>2]*C[f+8>>2]),u=_(C[c>>2]*C[f+4>>2]),b=C[f+12>>2]),b=_(C[s>>2]*b)}a[i+44>>2]=0,C[i+40>>2]=b,C[i+36>>2]=l,C[i+32>>2]=u,c=a[A+8>>2],Qt[a[a[c>>2]+8>>2]](c,i+32|0,e,r),A=a[A+4>>2],Qt[a[a[A>>2]+24>>2]](A,e),Y=i+80|0}function He(A){a[A+4>>2]=35,a[A+8>>2]=0,a[A+12>>2]=-1,a[A+16>>2]=0,a[A>>2]=10304}function ze(A){return A|=0,A+72|0}function Pe(A,e,r){var i=0;He(A),a[A+88>>2]=0,f[A+92|0]=1,i=A+80|0,a[i>>2]=0,a[i+4>>2]=0,a[A+72>>2]=0,i=A- -64|0,a[i>>2]=1065353216,a[i+4>>2]=0,a[A+56>>2]=1065353216,a[A+60>>2]=1065353216,f[A+52|0]=1,a[A+44>>2]=-8388609,i=A+36|0,a[i>>2]=-8388609,a[i+4>>2]=-8388609,a[A+28>>2]=2139095039,a[A+20>>2]=2139095039,a[A+24>>2]=2139095039,a[A+4>>2]=25,a[A+188>>2]=0,i=A+180|0,a[i>>2]=0,a[i+4>>2]=0,i=A+168|0,a[i>>2]=1065353216,a[i+4>>2]=0,i=A+160|0,a[i>>2]=1065353216,a[i+4>>2]=1065353216,a[A+152>>2]=1008981770,a[A+148>>2]=11168,a[A>>2]=10560,i=A+204|0,a[i>>2]=0,a[i+4>>2]=0,i=A+196|0,a[i>>2]=0,a[i+4>>2]=0,a[A+156>>2]=e,a[A+176>>2]=r,a[A+144>>2]=A+148}function Ke(A){var e;return A|=0,a[A>>2]=11012,e=a[A+88>>2],e&&(o[A+92|0]&&CA(e),a[A+88>>2]=0),a[A+88>>2]=0,a[A+80>>2]=0,a[A+84>>2]=0,f[A+92|0]=1,0|A}function Le(A){return A|=0,A+56|0}function qe(A){}function $e(A){A|=0;var e=0,r=0,i=0,t=0;if(a[A>>2]=10820,e=a[A+164>>2],r=a[A+156>>2],r)for(i=(r<<2)-4|0;r=r+-1|0,t=a[e+i>>2],t&&(Qt[a[a[t>>2]+4>>2]](t),e=a[A+164>>2]),i=i+-4|0,r;);return e&&(o[A+168|0]&&CA(e),a[A+164>>2]=0),a[A+164>>2]=0,a[A+156>>2]=0,a[A+160>>2]=0,a[A>>2]=11012,f[A+168|0]=1,e=a[A+88>>2],e&&(o[A+92|0]&&CA(e),a[A+88>>2]=0),a[A+88>>2]=0,a[A+80>>2]=0,a[A+84>>2]=0,f[A+92|0]=1,0|A}function Ar(A,e,r,i,f){}function er(A){a[A+16>>2]=0,a[A+8>>2]=-1,a[A+12>>2]=0,a[A>>2]=0,a[A+4>>2]=0,a[A+32>>2]=0,f[A+36|0]=1,A=A+24|0,a[A>>2]=0,a[A+4>>2]=0}function rr(A){var e=0;e=a[A>>2],e&&ir(A,e),CA(a[A+4>>2]),a[A+4>>2]=0,a[A+8>>2]=-1,e=a[A+32>>2],e&&(o[A+36|0]&&CA(e),a[A+32>>2]=0),a[A+16>>2]=0,a[A+32>>2]=0,a[A+24>>2]=0,a[A+28>>2]=0,f[A+36|0]=1}function ir(A,e){a[e+40>>2]&&(ir(A,a[e+36>>2]),ir(A,a[e+40>>2])),(0|e)==a[A>>2]&&(a[A>>2]=0),CA(a[A+4>>2]),a[A+4>>2]=e}function fr(A){var e=0;e=a[A>>2],e&&ir(A,e),CA(a[A+4>>2]),a[A+4>>2]=0,a[A+8>>2]=-1,e=a[A+32>>2],e&&(o[A+36|0]&&CA(e),a[A+32>>2]=0),a[A+32>>2]=0,a[A+24>>2]=0,a[A+28>>2]=0,a[A+16>>2]=0,f[A+36|0]=1}function tr(A,e){var r,i=0,f=0,t=0,n=0,o=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0,C=0,g=0,B=0,_=0;r=Y-32|0,Y=r;A:if(e=(0|e)<=-1?a[A+12>>2]:e,!((0|e)<1)&&(i=a[A>>2],i))for(;;){if(c=i+40|0,a[c>>2])for(v=0;t=a[i+32>>2],t>>>0<=i>>>0?t=i:(n=a[t+40>>2],o=(0|n)==(0|i),l=((0|i)!=(0|n))<<2,u=a[36+(l+t|0)>>2],f=a[t+32>>2],b=A,f&&(b=36+(f+((a[f+40>>2]==(0|t))<<2)|0)|0),a[b>>2]=i,a[u+32>>2]=i,a[t+32>>2]=i,a[i+32>>2]=f,a[t+36>>2]=a[i+36>>2],a[t+40>>2]=a[c>>2],a[a[i+36>>2]+32>>2]=t,a[a[c>>2]+32>>2]=t,n=i+36|0,a[n+(o<<2)>>2]=t,a[n+l>>2]=u,n=t+24|0,c=a[n+4>>2],f=r+24|0,C=a[n>>2],a[f>>2]=C,a[f+4>>2]=c,f=t+16|0,u=a[f+4>>2],o=r+16|0,g=a[f>>2],a[o>>2]=g,a[o+4>>2]=u,o=t+8|0,l=a[o+4>>2],s=r+8|0,B=a[o>>2],a[s>>2]=B,a[s+4>>2]=l,s=a[t+4>>2],_=a[t>>2],a[r>>2]=_,a[r+4>>2]=s,d=i+24|0,b=d,k=a[b+4>>2],a[n>>2]=a[b>>2],a[n+4>>2]=k,n=i+16|0,k=a[n+4>>2],a[f>>2]=a[n>>2],a[f+4>>2]=k,f=i+8|0,k=a[f+4>>2],a[o>>2]=a[f>>2],a[o+4>>2]=k,o=a[i+4>>2],a[t>>2]=a[i>>2],a[t+4>>2]=o,a[d>>2]=C,a[d+4>>2]=c,a[n>>2]=g,a[n+4>>2]=u,a[f>>2]=B,a[f+4>>2]=l,a[i>>2]=_,a[i+4>>2]=s),i=a[A+16>>2]>>>v,v=v+1&31,i=a[36+(((1&i)<<2)+t|0)>>2],c=i+40|0,a[c>>2];);if(b=A,f=0,nr(A,i)&&(f=a[A>>2]),ar(b,f,i),a[A+16>>2]=a[A+16>>2]+1,e=e+-1|0,!e)break A;i=a[A>>2]}Y=r+32|0}function nr(A,e){var r=0,i=0,f=_(0),t=_(0),n=_(0),o=0,c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0);if((0|e)==a[A>>2])return a[A>>2]=0,0;r=a[e+32>>2],i=a[36+(((a[r+40>>2]!=(0|e))<<2)+r|0)>>2],e=a[r+32>>2];A:{if(e)for(a[36+((((0|r)==a[e+40>>2])<<2)+e|0)>>2]=i,a[i+32>>2]=e,CA(a[A+4>>2]),a[A+4>>2]=r;;){if(B=C[e>>2],r=a[e+36>>2],f=C[r>>2],i=a[e+40>>2],u=C[i>>2],f=f>2]=f,u=C[e+16>>2],t=C[r+16>>2],s=C[i+16>>2],t=t>s?t:s,C[e+16>>2]=t,s=C[e+4>>2],n=C[r+4>>2],k=C[i+4>>2],n=n>2]=n,o=e+20|0,k=C[o>>2],c=C[r+20>>2],v=C[i+20>>2],c=c>v?c:v,C[o>>2]=c,v=C[e+8>>2],b=C[r+8>>2],d=C[i+8>>2],b=b>2]=b,o=e+24|0,d=C[o>>2],l=C[r+24>>2],g=C[i+24>>2],l=l>g?l:g,C[o>>2]=l,!(k!=c|u!=t|B!=f|s!=n)&&v==b&&d==l)break A;if(e=a[e+32>>2],!e)break}else a[i+32>>2]=0,a[A>>2]=i,CA(a[A+4>>2]),a[A+4>>2]=r;e=a[A>>2]}return e}function ar(A,e,r){var i=0,f=_(0),t=_(0),n=_(0),o=0,c=0;if(!a[A>>2])return a[r+32>>2]=0,void(a[A>>2]=r);if(i=a[e+40>>2],i)for(t=_(C[r>>2]+C[r+16>>2]),f=_(C[r+8>>2]+C[r+24>>2]),n=_(C[r+4>>2]+C[r+20>>2]);c=e+36|0,e=a[e+36>>2],e=a[c+((_(_(_(m(_(t-_(C[e>>2]+C[e+16>>2]))))+_(m(_(n-_(C[e+4>>2]+C[e+20>>2])))))+_(m(_(f-_(C[e+8>>2]+C[e+24>>2])))))<_(_(_(m(_(t-_(C[i>>2]+C[i+16>>2]))))+_(m(_(n-_(C[i+4>>2]+C[i+20>>2])))))+_(m(_(f-_(C[i+8>>2]+C[i+24>>2])))))^1)<<2)>>2],i=a[e+40>>2],i;);c=a[e+32>>2],i=a[A+4>>2],i?a[A+4>>2]=0:(i=dA(44),a[i>>2]=0,a[i+4>>2]=0,a[i+40>>2]=0,o=i+32|0,a[o>>2]=0,a[o+4>>2]=0,o=i+24|0,a[o>>2]=0,a[o+4>>2]=0,o=i+16|0,a[o>>2]=0,a[o+4>>2]=0,o=i+8|0,a[o>>2]=0,a[o+4>>2]=0),a[i+36>>2]=0,a[i+40>>2]=0,t=C[r>>2],f=C[e>>2],C[i>>2]=t>2],f=C[e+16>>2],C[i+16>>2]=t>f?t:f,t=C[r+4>>2],f=C[e+4>>2],C[i+4>>2]=t>2],f=C[e+20>>2],C[i+20>>2]=t>f?t:f,t=C[r+8>>2],f=C[e+8>>2],C[i+8>>2]=t>2]=c,t=C[r+24>>2],f=C[e+24>>2],C[i+24>>2]=t>f?t:f;A:if(c)for(a[36+(((a[a[e+32>>2]+40>>2]==(0|e))<<2)+c|0)>>2]=i,a[i+36>>2]=e,a[e+32>>2]=i,a[i+40>>2]=r,a[r+32>>2]=i,t=C[i>>2];;){if(A=i,i=c,!(C[i>>2]<=t^1|C[i+4>>2]<=C[A+4>>2]^1|C[i+8>>2]<=C[A+8>>2]^1|C[i+16>>2]>=C[A+16>>2]^1)&&C[i+20>>2]>=C[A+20>>2]&&C[i+24>>2]>=C[A+24>>2])break A;if(A=a[i+36>>2],t=C[A>>2],e=a[i+40>>2],f=C[e>>2],t=t>2]=t,f=C[A+16>>2],n=C[e+16>>2],C[i+16>>2]=f>n?f:n,f=C[A+4>>2],n=C[e+4>>2],C[i+4>>2]=f>2],n=C[e+20>>2],C[i+20>>2]=f>n?f:n,f=C[A+8>>2],n=C[e+8>>2],C[i+8>>2]=f>2],n=C[e+24>>2],C[i+24>>2]=f>n?f:n,c=a[i+32>>2],!c)break}else a[i+36>>2]=e,a[e+32>>2]=i,a[i+40>>2]=r,a[A>>2]=i,a[r+32>>2]=i}function or(A,e,r){var i=0,f=0,t=0;return f=a[A+4>>2],f?a[A+4>>2]=0:(f=dA(44),i=f,a[i>>2]=0,a[i+4>>2]=0,a[i+40>>2]=0,i=i+32|0,a[i>>2]=0,a[i+4>>2]=0,i=f+24|0,a[i>>2]=0,a[i+4>>2]=0,i=f+16|0,a[i>>2]=0,a[i+4>>2]=0,i=f+8|0,a[i>>2]=0,a[i+4>>2]=0),a[f+36>>2]=r,a[f+32>>2]=0,a[f+40>>2]=0,r=a[e+4>>2],a[f>>2]=a[e>>2],a[f+4>>2]=r,i=e+8|0,t=a[i+4>>2],r=f+8|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,i=e+16|0,t=a[i+4>>2],r=f+16|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,e=e+24|0,i=a[e+4>>2],r=f+24|0,a[r>>2]=a[e>>2],a[r+4>>2]=i,ar(A,a[A>>2],f),a[A+12>>2]=a[A+12>>2]+1,f}function cr(A,e,r){var i=0,f=0,t=0,n=0;t=nr(A,e);A:if(t)if(i=a[A+8>>2],(0|i)>=0){if(!i)break A;for(;;){if(f=a[t+32>>2],!f)break A;if(t=f,i=i+-1|0,!i)break}}else t=a[A>>2];else t=0;f=a[r+4>>2],a[e>>2]=a[r>>2],a[e+4>>2]=f,i=r+24|0,f=a[i+4>>2],n=e+24|0,a[n>>2]=a[i>>2],a[n+4>>2]=f,i=r+16|0,f=a[i+4>>2],n=e+16|0,a[n>>2]=a[i>>2],a[n+4>>2]=f,f=r+8|0,r=a[f+4>>2],i=e+8|0,a[i>>2]=a[f>>2],a[i+4>>2]=r,ar(A,t,e)}function br(A,e){nr(A,e),CA(a[A+4>>2]),a[A+4>>2]=e,a[A+12>>2]=a[A+12>>2]+-1}function lr(A,e){return 1}function ur(A){var e,r;return e=A*A,r=e*A,_(r*(e*e)*(2718311493989822e-21*e-.00019839334836096632)+(r*(.008333329385889463*e-.16666666641626524)+A))}function sr(A){var e;return A*=A,e=A*A,_(-.499999997251031*A+1+.04166662332373906*e+A*e*(2439044879627741e-20*A-.001388676377460993))}function kr(A,e){var r=0;A:if((0|e)>=1024){if(A*=8.98846567431158e307,r=e+-1023|0,(0|r)<1024){e=r;break A}A*=8.98846567431158e307,e=((0|e)<3069?e:3069)+-2046|0}else(0|e)>-1023||(A*=2.004168360008973e-292,r=e+969|0,(0|r)>-1023?e=r:(A*=2.004168360008973e-292,e=((0|e)>-2960?e:-2960)+1938|0));return b(0,0),b(1,e+1023<<20),A*+l()}function vr(A,e){var r,i=0,f=0,t=0,n=0,o=0;r=Y-16|0,Y=r,s(A),t=c(0),i=2147483647&t;A:if(i>>>0<=1305022426){if(n=+A,f=.6366197723675814*n+6755399441055744-6755399441055744,g[e>>3]=n+-1.5707963109016418*f+-1.5893254773528196e-8*f,m(f)<2147483648){i=~~f;break A}i=-2147483648}else i>>>0>=2139095040?(g[e>>3]=_(A-A),i=0):(o=i,i=(i>>>23)-150|0,g[r+8>>3]=(b(0,o-(i<<23)|0),k()),i=function(A,e,r){var i,f,t,n,o,c,b,l,u=0,s=0,k=0,v=0,d=0,C=0,_=0,R=0,Q=0,h=0,y=0,p=0,F=0;if(i=Y-560|0,Y=i,v=(r+-3|0)/24|0,t=(0|v)>0?v:0,h=r+B(t,-24)|0,f=a[2840],(0|f)>=0)for(v=f+1|0,r=t,d=11376+(r<<2)|0,s=i+320|0;g[s>>3]=(0|r)<0?0:+a[d>>2],s=s+8|0,d=d+4|0,r=r+1|0,v=v+-1|0,v;);for(R=h+-24|0,v=i+320|0;;){for(u=0,r=A,d=1,s=v;u+=g[r>>3]*g[s>>3],r=r+8|0,s=s+-8|0,d=d+-1|0,d;);if(g[(k<<3)+i>>3]=u,v=v+8|0,r=(0|k)<(0|f),k=k+1|0,!r)break}o=23-R|0,n=24-R|0,c=476+(i+(f<<2)|0)|0,b=i+476|0,l=i+-8|0,k=f;e:{for(;;){if(r=k<<3,u=g[r+i>>3],v=(0|k)<1,!v)for(r=r+l|0,s=i+480|0,d=k;C=s,y=u,u*=5.960464477539063e-8,_=m(u)<2147483648?~~u:-2147483648,u=+(0|_),y+=-16777216*u,_=m(y)<2147483648?~~y:-2147483648,a[C>>2]=_,s=s+4|0,u=g[r>>3]+u,r=r+-8|0,d=d+-1|0,d;);u=kr(u,R),u+=-8*G(.125*u),_=m(u)<2147483648?~~u:-2147483648,u-=+(0|_);r:{i:{f:{if(d=(0|R)<1,d){if(R)break f;Q=a[476+(i+(k<<2)|0)>>2]>>23}else s=476+(i+(k<<2)|0)|0,C=a[s>>2],r=C>>n,Q=s,s=C-(r<>2]=s,_=r+_|0,Q=s>>o;if((0|Q)<1)break r;break i}if(Q=2,!(u>=.5)){Q=0;break r}}if(v)C=0;else for(C=0,r=i+480|0,v=k;;){s=a[r>>2];i:{f:{if(F=r,C)p=16777215;else{if(!s)break f;C=1,p=16777216}a[F>>2]=p-s;break i}C=0}if(r=r+4|0,v=v+-1|0,!v)break}d||(r=R+-1|0,r>>>0>1||(r-1?(r=476+(i+(k<<2)|0)|0,a[r>>2]=8388607&a[r>>2]):(r=476+(i+(k<<2)|0)|0,a[r>>2]=4194303&a[r>>2]))),_=_+1|0,2==(0|Q)&&(u=1-u,Q=2,C&&(u-=kr(1,R)))}if(0!=u)break;if(!((0|k)<=(0|f))){for(r=(k<<2)+b|0,s=0,d=k;s=a[r>>2]|s,r=r+-4|0,d=d+-1|0,(0|d)>(0|f););if(s){for(r=476+(i+(k<<2)|0)|0,h=R;k=k+-1|0,h=h+-24|0,A=a[r>>2],r=r+-4|0,!A;);break e}}for(r=c,v=k;v=v+1|0,s=a[r>>2],r=r+-4|0,!s;);for(C=328+((k<<3)+i|0)|0;;){for(r=328+((k<<3)+i|0)|0,k=k+1|0,g[r>>3]=a[11376+(t+k<<2)>>2],u=0,r=A,s=C,d=1;u+=g[r>>3]*g[s>>3],r=r+8|0,s=s+-8|0,d=d+-1|0,d;);if(g[(k<<3)+i>>3]=u,C=C+8|0,!((0|k)<(0|v)))break}k=v}u=kr(u,0-R|0),u>=16777216?(A=(i+480|0)+(k<<2)|0,y=u,u*=5.960464477539063e-8,r=m(u)<2147483648?~~u:-2147483648,u=y+-16777216*+(0|r),v=m(u)<2147483648?~~u:-2147483648,a[A>>2]=v,k=k+1|0):(r=m(u)<2147483648?~~u:-2147483648,h=R),a[(i+480|0)+(k<<2)>>2]=r}if(!((0|k)<0)){for(d=k+1|0,u=kr(1,h),r=(i+480|0)+(k<<2)|0,s=(k<<3)+i|0;g[s>>3]=u*+a[r>>2],r=r+-4|0,s=s+-8|0,u*=5.960464477539063e-8,d=d+-1|0,(0|d)>0;);if(!((0|k)<0))for(v=(k<<3)+i|0,r=k;;){for(A=r,d=k-r|0,u=0,r=0,s=0;u+=g[r+14144>>3]*g[r+v>>3],!((0|s)>=(0|f))&&(r=r+8|0,R=s>>>0>>0,s=s+1|0,R););if(g[(i+160|0)+(d<<3)>>3]=u,v=v+-8|0,r=A+-1|0,!((0|A)>0))break}}if((0|k)<0)u=0;else for(s=k+1|0,r=(i+160|0)+(k<<3)|0,u=0;u+=g[r>>3],r=r+-8|0,s=s+-1|0,(0|s)>0;);return g[e>>3]=Q?-u:u,Y=i+560|0,7&_}(r+8|0,r,i),f=g[r>>3],(0|t)<=-1?(g[e>>3]=-f,i=0-i|0):g[e>>3]=f);return Y=r+16|0,i}function dr(A){var e,r=0,i=0,f=0;e=Y-16|0,Y=e,s(A),i=c(0),r=2147483647&i;A:if(r>>>0<=1061752794){if(r>>>0<964689920)break A;A=ur(+A)}else if(i>>>=31,r>>>0<=1081824209){if(f=+A,r>>>0<=1075235811){if(i){A=_(-sr(f+1.5707963267948966));break A}A=sr(f+-1.5707963267948966);break A}A=ur(-((i?3.141592653589793:-3.141592653589793)+f))}else if(r>>>0<=1088565717){if(f=+A,r>>>0<=1085271519){if(i){A=sr(f+4.71238898038469);break A}A=_(-sr(f+-4.71238898038469));break A}A=ur((i?6.283185307179586:-6.283185307179586)+f)}else if(r>>>0>=2139095040)A=_(A-A);else if(r=3&vr(A,e+8|0),r>>>0<=2){switch(r-1|0){default:A=ur(g[e+8>>3]);break A;case 0:A=sr(g[e+8>>3]);break A;case 1:}A=ur(-g[e+8>>3])}else A=_(-sr(g[e+8>>3]));return Y=e+16|0,A}function Cr(A){var e,r=_(0),i=0,f=0,t=0;e=Y-16|0,Y=e,s(A),f=c(0),i=2147483647&f;A:if(i>>>0<=1061752794){if(r=_(1),i>>>0<964689920)break A;r=sr(+A)}else if(f>>>=31,i>>>0<=1081824209){if(t=+A,i>>>0>=1075235812){r=_(-sr((f?3.141592653589793:-3.141592653589793)+t));break A}if(f){r=ur(t+1.5707963267948966);break A}r=ur(1.5707963267948966-t)}else if(i>>>0<=1088565717){if(i>>>0>=1085271520){r=sr(+A+(f?6.283185307179586:-6.283185307179586));break A}if(f){r=ur(-4.71238898038469-+A);break A}r=ur(+A-4.71238898038469)}else if(r=_(A-A),!(i>>>0>=2139095040))if(i=3&vr(A,e+8|0),i>>>0<=2){switch(i-1|0){default:r=sr(g[e+8>>3]);break A;case 0:r=ur(-g[e+8>>3]);break A;case 1:}r=_(-sr(g[e+8>>3]))}else r=ur(g[e+8>>3]);return A=r,Y=e+16|0,A}function gr(A,e,r){var i,t=0,n=_(0),c=0,b=0,l=0,u=_(0),s=0;i=Y-144|0,Y=i,a[A+72>>2]=a[A+72>>2]+1,c=e+8|0,b=a[c+4>>2],t=i+72|0,a[t>>2]=a[c>>2],a[t+4>>2]=b,c=e+24|0,b=a[c+4>>2],t=i+88|0,a[t>>2]=a[c>>2],a[t+4>>2]=b,c=e+40|0,b=a[c+4>>2],t=i+104|0,a[t>>2]=a[c>>2],a[t+4>>2]=b,c=e+56|0,b=a[c+4>>2],t=i+120|0,a[t>>2]=a[c>>2],a[t+4>>2]=b,a[i+140>>2]=0,a[i+128>>2]=r,t=a[e+4>>2],a[i+64>>2]=a[e>>2],a[i+68>>2]=t,t=a[e+20>>2],a[i+80>>2]=a[e+16>>2],a[i+84>>2]=t,t=a[e+36>>2],a[i+96>>2]=a[e+32>>2],a[i+100>>2]=t,t=a[e+52>>2],a[i+112>>2]=a[e+48>>2],a[i+116>>2]=t,a[i+132>>2]=a[r+4>>2],l=i,u=_(Qt[a[a[r>>2]+48>>2]](r)),C[l+136>>2]=u,Qt[a[a[r>>2]+8>>2]](r,e,i+48|0,i+32|0),n=C[i+48>>2],C[A+36>>2]>n&&(C[A+36>>2]=n),n=C[i+32>>2],C[A+52>>2]>2]=n),n=C[i+52>>2],C[A+40>>2]>n&&(C[A+40>>2]=n),n=C[i+36>>2],C[A+56>>2]>2]=n),n=C[i+56>>2],C[A+44>>2]>n&&(C[A+44>>2]=n),n=C[i+40>>2],C[A+60>>2]>2]=n),e=a[A+68>>2],e&&(t=i+56|0,c=a[t+4>>2],r=i+8|0,a[r>>2]=a[t>>2],a[r+4>>2]=c,t=i+40|0,c=a[t+4>>2],r=i+24|0,a[r>>2]=a[t>>2],a[r+4>>2]=c,r=a[i+52>>2],a[i>>2]=a[i+48>>2],a[i+4>>2]=r,r=a[i+36>>2],a[i+16>>2]=a[i+32>>2],a[i+20>>2]=r,l=i,s=or(e,i,a[A+20>>2]),a[l+140>>2]=s),function(A,e){var r=0,i=0,t=0,n=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0;if(i=a[A+4>>2],(0|i)==a[A+8>>2]&&(k=i?i<<1:1,!((0|i)>=(0|k)))){if(k&&(v=dA(B(k,80)),i=a[A+4>>2]),(0|i)>=1)for(l=64;t=a[A+12>>2]+l|0,n=t+-64|0,u=a[n+4>>2],r=l+v|0,c=r+-64|0,a[c>>2]=a[n>>2],a[c+4>>2]=u,n=n+8|0,b=a[n+4>>2],c=c+8|0,a[c>>2]=a[n>>2],a[c+4>>2]=b,c=t+-48|0,u=c+8|0,s=a[u+4>>2],n=r+-48|0,b=n+8|0,a[b>>2]=a[u>>2],a[b+4>>2]=s,b=a[c+4>>2],a[n>>2]=a[c>>2],a[n+4>>2]=b,c=t+-32|0,u=c+8|0,s=a[u+4>>2],n=r+-32|0,b=n+8|0,a[b>>2]=a[u>>2],a[b+4>>2]=s,b=a[c+4>>2],a[n>>2]=a[c>>2],a[n+4>>2]=b,c=t+-16|0,u=c+8|0,s=a[u+4>>2],n=r+-16|0,b=n+8|0,a[b>>2]=a[u>>2],a[b+4>>2]=s,b=a[c+4>>2],a[n>>2]=a[c>>2],a[n+4>>2]=b,n=a[t+4>>2],a[r>>2]=a[t>>2],a[r+4>>2]=n,t=t+8|0,n=a[t+4>>2],r=r+8|0,a[r>>2]=a[t>>2],a[r+4>>2]=n,l=l+80|0,i=i+-1|0,i;);i=a[A+12>>2],i&&(o[A+16|0]&&CA(i),a[A+12>>2]=0),a[A+12>>2]=v,f[A+16|0]=1,a[A+8>>2]=k,i=a[A+4>>2]}t=a[e+4>>2],i=a[A+12>>2]+B(i,80)|0,r=i,a[r>>2]=a[e>>2],a[r+4>>2]=t,t=e+8|0,l=a[t+4>>2],r=r+8|0,a[r>>2]=a[t>>2],a[r+4>>2]=l,t=e+24|0,l=a[t+4>>2],r=i+24|0,a[r>>2]=a[t>>2],a[r+4>>2]=l,r=a[e+20>>2],a[i+16>>2]=a[e+16>>2],a[i+20>>2]=r,t=e+40|0,l=a[t+4>>2],r=i+40|0,a[r>>2]=a[t>>2],a[r+4>>2]=l,r=a[e+36>>2],a[i+32>>2]=a[e+32>>2],a[i+36>>2]=r,t=e+56|0,l=a[t+4>>2],r=i+56|0,a[r>>2]=a[t>>2],a[r+4>>2]=l,r=a[e+52>>2],a[i+48>>2]=a[e+48>>2],a[i+52>>2]=r,t=e+72|0,l=a[t+4>>2],r=i+72|0,a[r>>2]=a[t>>2],a[r+4>>2]=l,r=a[e+68>>2],a[i+64>>2]=a[e+64>>2],a[i+68>>2]=r,a[A+4>>2]=a[A+4>>2]+1}(A+16|0,i- -64|0),Y=i+144|0}function Br(A,e){var r,i,f,t,n,o,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0,C=0,g=0,_=0,m=0;r=Y-80|0,Y=r,a[A+72>>2]=a[A+72>>2]+1,c=a[A+68>>2],c&&br(c,a[76+(a[A+28>>2]+B(e,80)|0)>>2]),b=a[A+20>>2],n=A+28|0,g=a[n>>2],o=B(e,80),c=g+o|0,l=c+8|0,k=a[l+4>>2],s=r+8|0,a[s>>2]=a[l>>2],a[s+4>>2]=k,v=c+24|0,_=a[v+4>>2],f=r+24|0,k=f,a[k>>2]=a[v>>2],a[k+4>>2]=_,t=c+40|0,d=t,C=a[d+4>>2],k=r+40|0,a[k>>2]=a[d>>2],a[k+4>>2]=C,d=c+56|0,u=a[d+4>>2],_=r+56|0,C=_,a[C>>2]=a[d>>2],a[C+4>>2]=u,i=c+72|0,m=a[i+4>>2],C=r+72|0,u=C,a[u>>2]=a[i>>2],a[u+4>>2]=m,u=a[c+4>>2],a[r>>2]=a[c>>2],a[r+4>>2]=u,u=a[c+20>>2],a[r+16>>2]=a[c+16>>2],a[r+20>>2]=u,u=a[c+36>>2],a[r+32>>2]=a[c+32>>2],a[r+36>>2]=u,u=a[c+52>>2],a[r+48>>2]=a[c+48>>2],a[r+52>>2]=u,u=a[c+68>>2],a[r+64>>2]=a[c+64>>2],a[r+68>>2]=u,u=g,g=B(b,80)+-80|0,b=u+g|0,u=b+8|0,m=a[u+4>>2],a[l>>2]=a[u>>2],a[l+4>>2]=m,l=a[b+4>>2],a[c>>2]=a[b>>2],a[c+4>>2]=l,l=b+24|0,u=a[l+4>>2],a[v>>2]=a[l>>2],a[v+4>>2]=u,l=a[b+20>>2],a[c+16>>2]=a[b+16>>2],a[c+20>>2]=l,l=b+40|0,v=a[l+4>>2],a[t>>2]=a[l>>2],a[t+4>>2]=v,l=a[b+36>>2],a[c+32>>2]=a[b+32>>2],a[c+36>>2]=l,l=b+56|0,v=a[l+4>>2],a[d>>2]=a[l>>2],a[d+4>>2]=v,l=a[b+52>>2],a[c+48>>2]=a[b+48>>2],a[c+52>>2]=l,l=a[b+68>>2],a[c+64>>2]=a[b+64>>2],a[c+68>>2]=l,c=b+72|0,b=a[c+4>>2],a[i>>2]=a[c>>2],a[i+4>>2]=b,l=a[r+4>>2],c=a[n>>2]+g|0,a[c>>2]=a[r>>2],a[c+4>>2]=l,l=a[s+4>>2],b=c+8|0,a[b>>2]=a[s>>2],a[b+4>>2]=l,b=a[r+20>>2],a[c+16>>2]=a[r+16>>2],a[c+20>>2]=b,s=a[f+4>>2],b=c+24|0,a[b>>2]=a[f>>2],a[b+4>>2]=s,b=a[r+36>>2],a[c+32>>2]=a[r+32>>2],a[c+36>>2]=b,s=a[k+4>>2],b=c+40|0,a[b>>2]=a[k>>2],a[b+4>>2]=s,b=a[r+52>>2],a[c+48>>2]=a[r+48>>2],a[c+52>>2]=b,s=a[_+4>>2],b=c+56|0,a[b>>2]=a[_>>2],a[b+4>>2]=s,s=a[C+4>>2],b=c+72|0,a[b>>2]=a[C>>2],a[b+4>>2]=s,b=a[r+68>>2],a[c+64>>2]=a[r+64>>2],a[c+68>>2]=b,a[A+68>>2]&&(a[a[76+(a[A+28>>2]+o|0)>>2]+36>>2]=e),a[A+20>>2]=a[A+20>>2]+-1,Y=r+80|0}function _r(A){var e;return A|=0,a[A>>2]=14564,e=a[A+32>>2],e&&(o[A+36|0]&&CA(e),a[A+32>>2]=0),a[A+32>>2]=0,a[A+24>>2]=0,a[A+28>>2]=0,f[A+36|0]=1,0|A}function mr(A,e,r,i,f,t,n,o,c,b){A|=0,e|=0,r|=0,i|=0,f|=0,t|=0,n|=0,o|=0,c|=0,b|=0,A=a[A+32>>2]+(b<<5)|0,a[r>>2]=a[A+12>>2],a[f>>2]=a[A+20>>2],a[e>>2]=a[A+16>>2],a[i>>2]=a[A+28>>2],a[o>>2]=a[A>>2],a[t>>2]=a[A+4>>2],a[c>>2]=a[A+24>>2],a[n>>2]=a[A+8>>2]}function Rr(A,e){}function Qr(A,e){var r=0,i=0,n=0,c=0,b=0,l=0,u=0;if(o[A+164|0]){if(r=a[A+128>>2],(0|r)==a[A+132>>2]&&(c=r?r<<1:1,!((0|r)>=(0|c)))){c&&(i=dA(c<<2),r=a[A+128>>2]),l=a[A+136>>2];A:{if((0|r)>=1)for(n=i,b=l;a[n>>2]=a[b>>2],n=n+4|0,b=b+4|0,r=r+-1|0,r;);else if(!l)break A;o[A+140|0]&&CA(l),a[A+136>>2]=0,r=a[A+128>>2]}a[A+136>>2]=i,a[A+132>>2]=c,f[A+140|0]=1}return n=a[A+136>>2],a[n+(r<<2)>>2]=e,a[a[A+32>>2]+4>>2]=n,void(a[A+128>>2]=a[A+128>>2]+1)}if(i=a[A+148>>2],(0|i)==a[A+152>>2]&&(u=i?i<<1:1,!((0|i)>=(0|u)))){u&&(l=dA(u<<1),i=a[A+148>>2]),c=a[A+156>>2];A:{if((0|i)>=1)for(n=l,b=c,r=i;t[n>>1]=v[b>>1],n=n+2|0,b=b+2|0,r=r+-1|0,r;);else if(!c)break A;o[A+160|0]&&(CA(c),i=a[A+148>>2]),a[A+156>>2]=0}a[A+156>>2]=l,a[A+152>>2]=u,f[A+160|0]=1}a[A+148>>2]=i+1,n=a[A+32>>2],A=a[A+156>>2],a[n+4>>2]=A,t[A+(i<<1)>>1]=e}function hr(A,e,r){var i=0,t=0,n=0,c=0,b=0,l=0,u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0);A:{if(o[A+165|0]){if(n=a[A+88>>2],!(!r|(0|n)<1))for(r=a[A+96>>2],k=C[A+168>>2],v=C[e+8>>2],d=C[e+4>>2],g=C[e>>2];;){if(u=_(C[r>>2]-g),s=_(u*u),u=_(C[r+4>>2]-d),s=_(s+_(u*u)),u=_(C[r+8>>2]-v),_(s+_(u*u))<=k)break A;if(r=r+16|0,c=c+1|0,!((0|c)<(0|n)))break}if(r=a[A+32>>2],a[r+12>>2]=a[r+12>>2]+1,a[A+92>>2]==(0|n)&&(c=n?n<<1:1,!((0|n)>=(0|c)))){if(c&&(i=dA(c<<4),n=a[A+88>>2]),(0|n)>=1)for(r=0;t=a[A+96>>2]+r|0,l=a[t+4>>2],b=r+i|0,a[b>>2]=a[t>>2],a[b+4>>2]=l,t=t+8|0,l=a[t+4>>2],b=b+8|0,a[b>>2]=a[t>>2],a[b+4>>2]=l,r=r+16|0,n=n+-1|0,n;);r=a[A+96>>2],r&&(o[A+100|0]&&CA(r),a[A+96>>2]=0),a[A+96>>2]=i,a[A+92>>2]=c,f[A+100|0]=1,n=a[A+88>>2]}return r=a[e+4>>2],l=A+96|0,i=a[l>>2]+(n<<4)|0,a[i>>2]=a[e>>2],a[i+4>>2]=r,r=e+8|0,e=a[r+4>>2],i=i+8|0,a[i>>2]=a[r>>2],a[i+4>>2]=e,a[a[A+32>>2]+16>>2]=a[l>>2],e=A,A=a[A+88>>2],a[e+88>>2]=A+1,A}if(t=a[A+108>>2],!(!r|(0|t)<1))for(r=a[A+116>>2],k=C[A+168>>2],v=C[e+8>>2],d=C[e+4>>2],g=C[e>>2];;){if(u=_(C[r>>2]-g),s=_(u*u),u=_(C[r+4>>2]-d),s=_(s+_(u*u)),u=_(C[r+8>>2]-v),_(s+_(u*u))<=k)break A;if(r=r+12|0,c=c+1|0,n=n+3|0,!((0|n)<(0|t)))break}if(i=a[A+112>>2],(0|t)==(0|i))if(i=t?t<<1:1,(0|t)>=(0|i))i=t;else{i&&(l=dA(i<<2),t=a[A+108>>2]),b=a[A+116>>2];e:{if((0|t)>=1)for(r=l,c=b,n=t;a[r>>2]=a[c>>2],r=r+4|0,c=c+4|0,n=n+-1|0,n;);else if(!b)break e;o[A+120|0]&&(CA(b),t=a[A+108>>2]),a[A+116>>2]=0}a[A+116>>2]=l,a[A+112>>2]=i,f[A+120|0]=1}if(r=t+1|0,a[A+108>>2]=r,b=a[A+116>>2],a[b+(t<<2)>>2]=a[e>>2],(0|r)==(0|i))if(t=i?i<<1:1,(0|i)>=(0|t))l=b,t=i;else{t?(l=dA(t<<2),b=a[A+116>>2],i=a[A+108>>2]):l=0;e:{if((0|i)>=1)for(r=l,c=b,n=i;a[r>>2]=a[c>>2],r=r+4|0,c=c+4|0,n=n+-1|0,n;);else if(!b)break e;o[A+120|0]&&(CA(b),i=a[A+108>>2]),a[A+116>>2]=0}a[A+116>>2]=l,a[A+112>>2]=t,f[A+120|0]=1}else l=b,t=i,i=r;if(r=i+1|0,a[A+108>>2]=r,a[(i<<2)+l>>2]=a[e+4>>2],(0|r)==(0|t))if(b=t?t<<1:1,(0|t)>=(0|b))i=l;else{b?(i=dA(b<<2),l=a[A+116>>2],t=a[A+108>>2]):i=0;e:{if((0|t)>=1)for(r=i,c=l,n=t;a[r>>2]=a[c>>2],r=r+4|0,c=c+4|0,n=n+-1|0,n;);else if(!l)break e;o[A+120|0]&&(CA(l),t=a[A+108>>2]),a[A+116>>2]=0}a[A+116>>2]=i,a[A+112>>2]=b,f[A+120|0]=1}else i=l,t=r;r=t+1|0,a[A+108>>2]=r,a[(t<<2)+i>>2]=a[e+8>>2],A=a[A+32>>2],a[A+16>>2]=i,a[A+12>>2]=a[A+12>>2]+1,c=((0|r)/3|0)-1|0}return c}function Gr(A){A|=0;var e=0;return a[A>>2]=14676,e=a[A+156>>2],e&&(o[A+160|0]&&CA(e),a[A+156>>2]=0),a[A+156>>2]=0,a[A+148>>2]=0,a[A+152>>2]=0,f[A+160|0]=1,e=a[A+136>>2],e&&(o[A+140|0]&&CA(e),a[A+136>>2]=0),a[A+136>>2]=0,a[A+128>>2]=0,a[A+132>>2]=0,f[A+140|0]=1,e=a[A+116>>2],e&&(o[A+120|0]&&CA(e),a[A+116>>2]=0),a[A+116>>2]=0,a[A+108>>2]=0,a[A+112>>2]=0,f[A+120|0]=1,e=a[A+96>>2],e&&(o[A+100|0]&&CA(e),a[A+96>>2]=0),a[A+96>>2]=0,a[A+88>>2]=0,a[A+92>>2]=0,f[A+100|0]=1,_r(A),0|A}function yr(A,e,r){var i,f,t,n=0,o=0,c=_(0),b=_(0),l=0,u=0,s=_(0),k=_(0),v=0,d=_(0),g=_(0),m=0,R=_(0),Q=0,h=0,G=0,p=0,F=0,W=_(0),w=_(0),D=_(0),E=_(0),Z=0;i=Y-96|0,Y=i,a[A+376>>2]=0,a[A+364>>2]=4,a[A+368>>2]=0,l=A+316|0,a[A+360>>2]=l,a[A+356>>2]=A+284,a[A+352>>2]=A+252,a[A+348>>2]=A+220,o=a[e+4>>2],a[A>>2]=a[e>>2],a[A+4>>2]=o,n=e+16|0,u=a[n+4>>2],o=A+16|0,a[o>>2]=a[n>>2],a[o+4>>2]=u,o=a[e+12>>2],a[A+8>>2]=a[e+8>>2],a[A+12>>2]=o,n=e+32|0,u=a[n+4>>2],o=A+32|0,a[o>>2]=a[n>>2],a[o+4>>2]=u,n=e+24|0,u=a[n+4>>2],o=A+24|0,a[o>>2]=a[n>>2],a[o+4>>2]=u,n=e+48|0,u=a[n+4>>2],o=A+48|0,a[o>>2]=a[n>>2],a[o+4>>2]=u,n=e+40|0,u=a[n+4>>2],o=A+40|0,a[o>>2]=a[n>>2],a[o+4>>2]=u,n=e- -64|0,u=a[n+4>>2],o=A- -64|0,a[o>>2]=a[n>>2],a[o+4>>2]=u,o=a[e+60>>2],a[A+56>>2]=a[e+56>>2],a[A+60>>2]=o,n=e+80|0,u=a[n+4>>2],o=A+80|0,a[o>>2]=a[n>>2],a[o+4>>2]=u,n=e+72|0,u=a[n+4>>2],o=A+72|0,a[o>>2]=a[n>>2],a[o+4>>2]=u,n=e+96|0,u=a[n+4>>2],o=A+96|0,a[o>>2]=a[n>>2],a[o+4>>2]=u,n=e+88|0,u=a[n+4>>2],o=A+88|0,a[o>>2]=a[n>>2],a[o+4>>2]=u,n=e+104|0,u=a[n+4>>2],o=A+104|0,a[o>>2]=a[n>>2],a[o+4>>2]=u,n=e+112|0,u=a[n+4>>2],o=A+112|0,a[o>>2]=a[n>>2],a[o+4>>2]=u,o=a[e+120>>2],e=a[e+124>>2],a[A+180>>2]=0,a[A+144>>2]=0,a[A+120>>2]=o,a[A+124>>2]=e,n=r+8|0,u=a[n+4>>2],e=A+136|0,a[e>>2]=a[n>>2],a[e+4>>2]=u,o=a[r+4>>2],a[A+128>>2]=a[r>>2],a[A+132>>2]=o,o=A+128|0,c=C[A+128>>2],s=C[A+132>>2],k=C[e>>2],g=_(_(_(c*c)+_(s*s))+_(k*k)),g>_(0)?(C[i+40>>2]=-k,C[i+36>>2]=-s,C[i+32>>2]=-c):(a[i+40>>2]=0,a[i+32>>2]=1065353216,a[i+36>>2]=0),a[A+364>>2]=3,a[A+180>>2]=1,a[A+148>>2]=l,e=A+164|0,a[e>>2]=0,a[i+44>>2]=0,pr(A,i+32|0,l),a[e>>2]=1065353216,e=a[A+148>>2],r=a[e+20>>2],a[o>>2]=a[e+16>>2],a[o+4>>2]=r,l=e+24|0,n=a[l+4>>2],f=o+8|0,r=f,a[r>>2]=a[l>>2],a[r+4>>2]=n,r=a[l+4>>2],u=i+88|0,n=a[l>>2],a[u>>2]=n,a[u+4>>2]=r,l=i+72|0,a[l>>2]=n,a[l+4>>2]=r,l=i+56|0,a[l>>2]=n,a[l+4>>2]=r,l=a[e+20>>2],e=a[e+16>>2],a[i+80>>2]=e,a[i+84>>2]=l,a[i+64>>2]=e,a[i+68>>2]=l,a[i+48>>2]=e,a[i+52>>2]=l,a[i+32>>2]=e,a[i+36>>2]=l,a[i+40>>2]=n,a[i+44>>2]=r,t=A+148|0,l=a[A+368>>2],c=C[A+136>>2],s=C[A+132>>2],k=C[A+128>>2],u=0;A:{e:{r:{for(;;){if(R=_(y(_(_(_(k*k)+_(s*s))+_(c*c)))),R<_(9999999747378752e-20)){a[A+376>>2]=1;break r}if(v=a[A+364>>2]+-1|0,a[A+364>>2]=v,Q=B(l,36),e=Q+A|0,n=e+180|0,r=a[n>>2],a[n>>2]=r+1,m=r<<2,r=e+148|0,m=m+r|0,v=a[348+((v<<2)+A|0)>>2],a[m>>2]=v,a[m+16>>2]=0,a[i+28>>2]=0,C[i+24>>2]=-c,C[i+20>>2]=-s,C[i+16>>2]=-k,pr(A,i+16|0,v),G=a[n>>2],v=a[(r+(G<<2)|0)-4>>2],c=C[v+16>>2],s=_(c-C[i+32>>2]),b=_(s*s),s=C[v+20>>2],k=_(s-C[i+36>>2]),d=_(b+_(k*k)),k=C[v+24>>2],b=_(k-C[i+40>>2]),!(_(d+_(b*b))<_(9999999747378752e-20)||(b=_(c-C[i+48>>2]),d=_(b*b),b=_(s-C[i+52>>2]),d=_(d+_(b*b)),b=_(k-C[i+56>>2]),_(d+_(b*b))<_(9999999747378752e-20)||(b=_(c-C[i+64>>2]),d=_(b*b),b=_(s-C[i+68>>2]),d=_(d+_(b*b)),b=_(k-C[i+72>>2]),_(d+_(b*b))<_(9999999747378752e-20)||(b=_(c-C[i+80>>2]),d=_(b*b),b=_(s-C[i+84>>2]),d=_(d+_(b*b)),b=_(k-C[i+88>>2]),_(d+_(b*b))<_(9999999747378752e-20)))))){if(v=v+16|0,h=v+8|0,p=a[h+4>>2],Z=Z+1&3,m=(i+32|0)+(Z<<4)|0,a[m+8>>2]=a[h>>2],a[m+12>>2]=p,F=a[v+4>>2],a[m>>2]=a[v>>2],a[m+4>>2]=F,c=_(_(_(_(C[A+128>>2]*c)+_(C[A+132>>2]*s))+_(C[A+136>>2]*k))/R),W=c>W?c:W,_(_(R-W)+_(R*_(-9999999747378752e-20)))<=_(0)){r=a[A+364>>2],a[A+364>>2]=r+1,l=a[A+368>>2],o=B(l,36)+A|0,n=o+180|0,e=a[n>>2]+-1|0,a[n>>2]=e,a[348+((r<<2)+A|0)>>2]=a[148+(o+(e<<2)|0)>>2];break r}a[i+12>>2]=0;i:{f:{v=G+-2|0;t:if(!(v>>>0>2)){switch(v-1|0){default:if(e=a[e+152>>2],w=C[e+16>>2],r=a[r>>2],g=C[r+16>>2],R=_(w-g),D=C[e+20>>2],s=C[r+20>>2],b=_(D-s),E=C[e+24>>2],k=C[r+24>>2],d=_(E-k),c=_(_(_(R*R)+_(b*b))+_(d*d)),!(c>_(0)))break f;if(c=_(_(-_(_(_(g*R)+_(s*b))+_(k*d)))/c),c>=_(1)){a[i+16>>2]=0,a[i+20>>2]=1065353216,a[i+12>>2]=2,g=_(_(_(w*w)+_(D*D))+_(E*E));break t}if(c<=_(0)){a[i+16>>2]=1065353216,a[i+20>>2]=0,a[i+12>>2]=1,g=_(_(_(g*g)+_(s*s))+_(k*k));break t}a[i+12>>2]=3,C[i+20>>2]=c,C[i+16>>2]=_(1)-c,k=_(k+_(d*c)),g=_(g+_(R*c)),c=_(s+_(b*c)),g=_(_(k*k)+_(_(g*g)+_(c*c)));break t;case 0:g=Fr(a[r>>2]+16|0,a[e+152>>2]+16|0,a[e+156>>2]+16|0,i+16|0,i+12|0);break t;case 1:}g=Wr(a[r>>2]+16|0,a[e+152>>2]+16|0,a[e+156>>2]+16|0,a[e+160>>2]+16|0,i+16|0,i+12|0)}if(g>=_(0)){if(l=1-l|0,G=B(l,36)+A|0,v=G+180|0,a[v>>2]=0,a[f>>2]=0,a[f+4>>2]=0,a[o>>2]=0,a[o+4>>2]=0,a[A+368>>2]=l,m=a[i+12>>2],F=a[n>>2],!F){c=_(0),s=_(0),k=_(0);break i}for(e=Q+t|0,r=0,c=_(0),n=i+16|0,s=_(0),k=_(0);Q=a[e>>2],1<>2],p=(h<<2)+G|0,a[p+148>>2]=Q,c=C[n>>2],a[p+164>>2]=a[n>>2],a[v>>2]=h+1,Q=a[e>>2],R=C[Q+24>>2],s=C[Q+20>>2],k=_(_(C[Q+16>>2]*c)+C[A+128>>2]),C[A+128>>2]=k,s=_(_(s*c)+C[A+132>>2]),C[A+132>>2]=s,c=_(_(R*c)+C[A+136>>2]),C[A+136>>2]=c):(h=a[A+364>>2],a[A+364>>2]=h+1,a[348+((h<<2)+A|0)>>2]=Q),e=e+4|0,n=n+4|0,r=r+1|0,(0|r)!=(0|F););break i}}r=a[A+364>>2],a[A+364>>2]=r+1,l=a[A+368>>2],o=B(l,36)+A|0,n=o+180|0,e=a[n>>2]+-1|0,a[n>>2]=e,a[348+((r<<2)+A|0)>>2]=a[148+(o+(e<<2)|0)>>2];break r}if(15==(0|m)&&(a[A+376>>2]=1),127==(0|u)){e=2,a[A+376>>2]=2,a[A+372>>2]=148+(B(l,36)+A|0);break A}if(u=u+1|0,e=a[A+376>>2],!e)continue;break e}break}r=a[A+364>>2],a[A+364>>2]=r+1,l=a[A+368>>2],o=B(l,36)+A|0,n=o+180|0,e=a[n>>2]+-1|0,a[n>>2]=e,a[348+((r<<2)+A|0)>>2]=a[148+(o+(e<<2)|0)>>2]}e=a[A+376>>2]}a[A+372>>2]=148+(B(l,36)+A|0),e>>>0>1||(e-1?(c=C[A+128>>2],s=_(c*c),c=C[A+132>>2],s=_(s+_(c*c)),c=C[A+136>>2],C[A+144>>2]=y(_(s+_(c*c))),e=0):(a[A+144>>2]=0,e=1))}return Y=i+96|0,e}function pr(A,e,r){var i,f,t,n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0);i=Y-48|0,Y=i,n=C[e+8>>2],o=C[e>>2],c=C[e+4>>2],a[r+12>>2]=0,b=n,n=_(_(1)/_(y(_(_(_(o*o)+_(c*c))+_(n*n))))),C[r+8>>2]=b*n,C[r+4>>2]=c*n,C[r>>2]=o*n,e=a[A+120>>2],f=a[A+124>>2],t=a[A>>2]+(f>>1)|0,Qt[1&f?a[a[t>>2]+e>>2]:e](i+32|0,t,r),a[i+12>>2]=0,C[i+8>>2]=-C[r+8>>2],C[i+4>>2]=-C[r+4>>2],C[i>>2]=-C[r>>2],function(A,e,r){var i=0,f=_(0),t=_(0),n=_(0),o=0,c=0,b=0;i=Y-32|0,Y=i,c=a[e+124>>2],b=a[e+4>>2]+(c>>1)|0,o=a[e+120>>2],o=1&c?a[a[b>>2]+o>>2]:o,a[i+12>>2]=0,f=C[r>>2],t=C[r+4>>2],n=C[r+8>>2],C[i+8>>2]=_(_(f*C[e+40>>2])+_(t*C[e+44>>2]))+_(n*C[e+48>>2]),C[i+4>>2]=_(_(f*C[e+24>>2])+_(t*C[e+28>>2]))+_(n*C[e+32>>2]),C[i>>2]=_(_(f*C[e+8>>2])+_(t*C[e+12>>2]))+_(n*C[e+16>>2]),Qt[o](i+16|0,b,i),a[A+12>>2]=0,f=C[i+16>>2],t=C[i+20>>2],n=C[i+24>>2],C[A+8>>2]=_(_(_(f*C[e+88>>2])+_(t*C[e+92>>2]))+_(n*C[e+96>>2]))+C[e+112>>2],C[A+4>>2]=_(_(_(f*C[e+72>>2])+_(t*C[e+76>>2]))+_(n*C[e+80>>2]))+C[e+108>>2],C[A>>2]=_(_(_(f*C[e+56>>2])+_(t*C[e+60>>2]))+_(n*C[e- -64>>2]))+C[e+104>>2],Y=i+32|0}(i+16|0,A,i),n=C[i+16>>2],o=C[i+32>>2],c=C[i+20>>2],b=C[i+36>>2],l=C[i+24>>2],u=C[i+40>>2],a[r+28>>2]=0,C[r+24>>2]=u-l,C[r+20>>2]=b-c,C[r+16>>2]=o-n,Y=i+48|0}function Fr(A,e,r,i,f){var t=_(0),n=_(0),o=_(0),b=_(0),l=_(0),u=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=0,p=_(0),F=_(0),W=0,w=0,D=_(0),E=_(0),Z=_(0),Y=_(0),V=_(0);return n=_(-1),l=C[A>>2],b=C[e>>2],t=_(l-b),o=C[e+4>>2],h=C[r+4>>2],E=_(o-h),R=C[A+4>>2],B=_(R-o),p=C[r>>2],Z=_(b-p),k=_(_(t*E)-_(B*Z)),u=C[e+8>>2],F=C[r+8>>2],Y=_(u-F),Q=C[A+8>>2],v=_(Q-u),d=_(_(B*Y)-_(v*E)),g=_(_(v*Z)-_(t*Y)),V=_(_(k*k)+_(_(d*d)+_(g*g))),V>_(0)&&(_(_(_(l*_(_(k*B)-_(g*v)))+_(R*_(_(d*v)-_(k*t))))+_(_(_(g*t)-_(d*B))*Q))>_(0)?(B=_(b-l),v=_(o-R),m=_(u-Q),n=_(_(_(B*B)+_(v*v))+_(m*m)),t=_(-1),n>_(0)&&(n=_(_(-_(_(_(l*B)+_(R*v))+_(Q*m)))/n),n>=_(1)?(W=1065353216,G=2,t=_(_(_(b*b)+_(o*o))+_(u*u))):(G=1,n<=_(0)?(w=1065353216,t=_(_(_(l*l)+_(R*R))+_(Q*Q))):(s(_(_(1)-n)),w=c(0),s(n),W=c(0),G=3,t=_(Q+_(m*n)),b=_(t*t),t=_(l+_(B*n)),o=_(t*t),t=_(R+_(v*n)),t=_(b+_(o+_(t*t)))))),a[i+8>>2]=0,a[i+4>>2]=W,a[i>>2]=w,a[f>>2]=G,u=C[e+8>>2],o=C[e+4>>2],b=C[e>>2]):t=_(-1),Q=_(F-Q),R=_(h-R),B=_(p-l),_(_(_(b*_(_(k*E)-_(g*Y)))+_(o*_(_(d*Y)-_(k*Z))))+_(_(_(g*Z)-_(d*E))*u))>_(0)?(p=C[r>>2],v=_(p-b),F=C[r+4>>2],m=_(F-o),D=C[r+8>>2],h=_(D-u),l=_(_(_(v*v)+_(m*m))+_(h*h)),n=_(-1),l>_(0)&&(l=_(_(-_(_(_(b*v)+_(o*m))+_(u*h)))/l),l>=_(1)?(W=1065353216,w=0,G=2,n=_(_(_(p*p)+_(F*F))+_(D*D))):(G=1,l<=_(0)?(W=0,w=1065353216,n=_(_(_(b*b)+_(o*o))+_(u*u))):(s(_(_(1)-l)),w=c(0),s(l),W=c(0),G=3,n=_(u+_(h*l)),u=_(n*n),n=_(b+_(v*l)),b=_(n*n),n=_(o+_(m*l)),n=_(u+_(b+_(n*n)))))),!!(n>2]=W,a[i+4>>2]=w,a[i>>2]=0,a[f>>2]=G<<1):n=t):n=t,o=C[r>>2],u=C[r+4>>2],l=C[r+8>>2],_(_(_(o*_(_(k*R)-_(g*Q)))+_(u*_(_(d*Q)-_(k*B))))+_(_(_(g*B)-_(d*R))*l))>_(0)&&(p=C[A>>2],v=_(p-o),F=C[A+4>>2],m=_(F-u),D=C[A+8>>2],h=_(D-l),b=_(_(_(v*v)+_(m*m))+_(h*h)),t=_(-1),b>_(0)&&(b=_(_(-_(_(_(o*v)+_(u*m))+_(l*h)))/b),b>=_(1)?(W=1065353216,w=0,G=2,t=_(_(_(p*p)+_(F*F))+_(D*D))):b<=_(0)?(W=0,w=1065353216,G=1,t=_(_(_(o*o)+_(u*u))+_(l*l))):(s(_(_(1)-b)),w=c(0),s(b),W=c(0),G=3,t=_(l+_(h*b)),l=_(t*t),t=_(o+_(v*b)),o=_(t*t),t=_(u+_(m*b)),t=_(l+_(o+_(t*t))))),t>2]=w,a[i+4>>2]=0,a[i>>2]=W,a[f>>2]=5&(G<<2|G>>>1),n=t)),n<_(0)&&(b=_(_(_(_(d*C[A>>2])+_(g*C[A+4>>2]))+_(k*C[A+8>>2]))/V),n=_(g*b),o=_(C[e+4>>2]-n),t=_(d*b),u=_(C[e>>2]-t),d=_(_(Z*o)-_(E*u)),b=_(k*b),k=_(C[e+8>>2]-b),o=_(_(E*k)-_(Y*o)),l=_(o*o),o=_(_(Y*u)-_(Z*k)),l=_(y(_(_(d*d)+_(l+_(o*o))))),o=_(y(V)),u=_(l/o),C[i>>2]=u,a[f>>2]=7,k=_(C[r+4>>2]-n),d=_(C[r>>2]-t),g=_(_(B*k)-_(R*d)),l=_(g*g),g=_(C[r+8>>2]-b),k=_(_(R*g)-_(Q*k)),v=_(k*k),k=_(_(Q*d)-_(B*g)),o=_(_(y(_(l+_(v+_(k*k)))))/o),C[i+4>>2]=o,C[i+8>>2]=_(1)-_(u+o),n=_(_(b*b)+_(_(t*t)+_(n*n))))),n}function Wr(A,e,r,i,f,t){var n,o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=0,m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0);return n=Y-96|0,Y=n,a[n+92>>2]=i,a[n+88>>2]=r,a[n+84>>2]=e,a[n+80>>2]=A,a[n+60>>2]=0,G=C[e+8>>2],Q=C[i+8>>2],u=_(G-Q),C[n+56>>2]=u,y=C[e+4>>2],h=C[i+4>>2],p=_(y-h),C[n+52>>2]=p,a[n+44>>2]=0,F=C[A+8>>2],v=_(F-Q),C[n+40>>2]=v,E=C[A+4>>2],g=_(E-h),C[n+36>>2]=g,Z=C[A>>2],D=C[i>>2],m=_(Z-D),C[n+32>>2]=m,W=C[e>>2],o=_(W-D),C[n+48>>2]=o,w=C[r>>2],s=C[r+4>>2],V=C[r+8>>2],a[n+76>>2]=0,c=_(V-Q),C[n+72>>2]=c,l=_(s-h),C[n+68>>2]=l,k=_(w-D),C[n+64>>2]=k,b=_(-1),N=_(m*p),I=_(g*u),J=_(v*o),x=_(m*u),R=_(g*o),p=_(v*p),u=_(_(_(N*c)+_(_(_(_(I*k)+_(J*l))-_(x*l))-_(R*c)))-_(p*k)),u==_(0)|u!=u||(d=_(E-y),w=_(W-w),W=_(Z-W),y=_(y-s),s=_(F*_(_(d*w)-_(W*y))),F=_(F-G),G=_(G-V),_(u*_(s+_(_(Z*_(_(F*y)-_(d*G)))+_(E*_(_(W*G)-_(F*w))))))<=_(0)&&(a[n+24>>2]=0,a[n+16>>2]=0,a[n+20>>2]=0,a[n+12>>2]=0,_(u*_(_(_(_(I-p)*D)+_(h*_(J-x)))+_(_(N-R)*Q)))>_(0)&&(b=Fr(a[n+80>>2],a[n+84>>2],i,n+16|0,n+12|0),a[f+8>>2]=0,B=a[n+20>>2],a[f>>2]=a[n+16>>2],a[f+4>>2]=B,a[f+12>>2]=a[n+24>>2],B=a[n+12>>2],a[t>>2]=2&B|B<<1&8|1&B),Q=C[n+52>>2],h=C[n+56>>2],_(u*_(_(_(_(_(Q*c)-_(h*l))*C[i>>2])+_(C[i+4>>2]*_(_(h*k)-_(c*o))))+_(_(_(l*o)-_(Q*k))*C[i+8>>2])))>_(0)&&(o=Fr(a[n+84>>2],a[n+88>>2],i,n+16|0,n+12|0),o>2]=a[n+16>>2],a[f>>2]=0,B=a[n+24>>2],a[f+8>>2]=a[n+20>>2],a[f+12>>2]=B,a[t>>2]=a[n+12>>2]<<1&14,b=o)),_(u*_(_(_(_(_(l*v)-_(c*g))*C[i>>2])+_(C[i+4>>2]*_(_(c*m)-_(v*k))))+_(_(_(g*k)-_(l*m))*C[i+8>>2])))>_(0)&&(o=Fr(a[n+88>>2],a[n+80>>2],i,n+16|0,n+12|0),o>2]=a[n+16>>2],a[f+4>>2]=0,a[f>>2]=a[n+20>>2],a[f+12>>2]=a[n+24>>2],B=a[n+12>>2],a[t>>2]=B>>>1&1|B<<1&8|B<<2&4,b=o)),b<_(0)&&(b=C[r+4>>2],o=C[e+8>>2],c=C[i>>2],l=C[r+8>>2],k=C[e>>2],v=C[i+4>>2],R=_(_(_(b*o)*c)+_(_(l*k)*v)),s=o,o=C[r>>2],d=_(b*k),b=C[i+8>>2],d=_(_(R-_(v*_(s*o)))-_(d*b)),s=b,b=C[e+4>>2],b=_(_(_(d+_(s*_(o*b)))-_(c*_(l*b)))/u),C[f>>2]=b,o=C[A+4>>2],c=C[r+8>>2],l=C[i>>2],k=C[A+8>>2],v=C[r>>2],g=C[i+4>>2],R=_(_(_(o*c)*l)+_(_(k*v)*g)),s=c,c=C[A>>2],d=_(o*v),o=C[i+8>>2],d=_(_(R-_(g*_(s*c)))-_(d*o)),s=o,o=C[r+4>>2],o=_(_(_(d+_(s*_(c*o)))-_(l*_(k*o)))/u),C[f+4>>2]=o,a[t>>2]=15,c=C[e+4>>2],l=C[A+8>>2],k=C[i>>2],v=C[e+8>>2],g=C[A>>2],m=C[i+4>>2],R=_(_(_(c*l)*k)+_(_(v*g)*m)),s=l,l=C[e>>2],d=_(c*g),c=C[i+8>>2],d=_(_(R-_(m*_(s*l)))-_(d*c)),s=c,c=C[A+4>>2],u=_(_(_(d+_(s*_(l*c)))-_(k*_(v*c)))/u),C[f+8>>2]=u,C[f+12>>2]=_(1)-_(_(b+o)+u),b=_(0)))),Y=n+96|0,b}function wr(A,e,r,i,t,n){var c,b,l=_(0),u=_(0),s=_(0),k=_(0),v=0,g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0),U=_(0),M=0;c=Y-19040|0,Y=c,a[n>>2]=0,a[n+4>>2]=0,a[n+32>>2]=0,v=n+24|0,a[v>>2]=0,a[v+4>>2]=0,v=n+16|0,a[v>>2]=0,a[v+4>>2]=0,v=n+8|0,a[v>>2]=0,a[v+4>>2]=0,a[c+18916>>2]=r,a[c+18912>>2]=A,l=C[i+20>>2],u=C[i+36>>2],A=e+20|0,s=C[A>>2],r=e+36|0,k=C[r>>2],v=e+24|0,m=C[v>>2],g=C[i+24>>2],b=e+40|0,R=C[b>>2],B=C[i+40>>2],Q=C[i+32>>2],h=C[i>>2],G=C[i+16>>2],p=C[i+4>>2],F=C[e+32>>2],W=C[e>>2],w=C[e+16>>2],Z=C[e+4>>2],E=C[e+8>>2],D=C[i+8>>2],a[c+18964>>2]=0,a[c+18948>>2]=0,a[c+18932>>2]=0,V=_(_(_(E*D)+_(m*g))+_(R*B)),C[c+18960>>2]=V,N=_(_(_(Z*D)+_(s*g))+_(k*B)),C[c+18956>>2]=N,g=_(_(_(W*D)+_(w*g))+_(F*B)),C[c+18952>>2]=g,B=_(_(_(E*p)+_(m*l))+_(R*u)),C[c+18944>>2]=B,D=_(_(_(Z*p)+_(s*l))+_(k*u)),C[c+18940>>2]=D,l=_(_(_(W*p)+_(w*l))+_(F*u)),C[c+18936>>2]=l,u=_(_(_(h*E)+_(G*m))+_(Q*R)),C[c+18928>>2]=u,s=_(_(_(h*Z)+_(G*s))+_(Q*k)),C[c+18924>>2]=s,k=_(_(_(h*W)+_(G*w))+_(Q*F)),C[c+18920>>2]=k,m=C[A>>2],R=C[r>>2],Q=C[v>>2],h=C[i+52>>2],G=C[e+52>>2],p=C[b>>2],F=C[i+56>>2],W=C[e+56>>2],w=C[e>>2],Z=C[e+16>>2],E=C[e+32>>2],I=C[e+4>>2],J=C[e+8>>2],x=C[i+48>>2],U=C[e+48>>2],a[c+19036>>2]=0,a[c+19028>>2]=0,a[c+19012>>2]=0,C[c+19008>>2]=V,C[c+19004>>2]=B,C[c+19e3>>2]=u,a[c+18996>>2]=0,C[c+18992>>2]=N,C[c+18988>>2]=D,C[c+18984>>2]=s,a[c+18980>>2]=0,C[c+18976>>2]=g,C[c+18972>>2]=l,l=_(x-U),u=_(h-G),s=_(F-W),C[c+19024>>2]=_(_(J*l)+_(Q*u))+_(p*s),C[c+19020>>2]=_(_(l*I)+_(u*m))+_(s*R),C[c+19016>>2]=_(_(l*w)+_(u*Z))+_(s*E),a[c+19032>>2]=349,C[c+18968>>2]=k,A=c+18664|0,a[A>>2]=0,a[A+4>>2]=0,a[c+18656>>2]=0,a[c+18660>>2]=0,a[c+18892>>2]=0,a[c+18896>>2]=0,a[c+18904>>2]=2,a[c+18672>>2]=0,a[c+28>>2]=0,C[c+24>>2]=-C[t+8>>2],C[c+20>>2]=-C[t+4>>2],C[c+16>>2]=-C[t>>2],A=yr(c+18528|0,c+18912|0,c+16|0)+-1|0;A:if(!(A>>>0>1)){e:{if(A-1){for(A=c+18520|0,a[A>>2]=0,a[A+4>>2]=0,A=c- -64|0,a[A>>2]=0,a[A+4>>2]=0,a[c+72>>2]=0,a[c+18512>>2]=0,a[c+18516>>2]=0,a[c+18508>>2]=0,a[c+16>>2]=9,a[c+56>>2]=0,a[c+60>>2]=0,i=14336;A=(c+16|0)+i|0,a[A+4144>>2]=0,r=a[c+18520>>2],a[A+4148>>2]=r,A=A+4100|0,r&&(a[r+44>>2]=A),a[c+18520>>2]=A,i=i+-56|0,i;);if(a[c+18524>>2]=256,a[c+12>>2]=0,C[c+8>>2]=-C[t+8>>2],C[c+4>>2]=-C[t+4>>2],C[c>>2]=-C[t>>2],9!=(0|function(A,e,r){var i=0,t=0,n=_(0),c=_(0),b=0,l=0,u=0,s=_(0),k=_(0),v=_(0),g=_(0),B=_(0),m=0,R=0,Q=_(0),h=_(0),G=0,p=0,F=_(0),W=0,w=_(0);G=Y-16|0,Y=G;r:{if(u=a[e+372>>2],!(d[u+32>>2]<2)&&function A(e){var r=0,i=0,f=0,t=0,n=0,o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0);f=Y-32|0,Y=f;i:{f:{r=a[e+372>>2],i=a[r+32>>2]+-1|0;t:if(!(i>>>0>3)){n:{switch(i-1|0){default:if(a[f+28>>2]=0,a[r+32>>2]=2,a[r+20>>2]=0,i=a[e+364>>2]+-1|0,a[e+364>>2]=i,a[f+20>>2]=0,a[f+24>>2]=0,t=r,r=a[348+((i<<2)+e|0)>>2],a[t+4>>2]=r,a[f+16>>2]=1065353216,pr(e,f+16|0,r),A(e))break f;if(t=a[e+364>>2],r=a[e+372>>2],n=a[r+32>>2]+-1|0,i=a[(n<<2)+r>>2],a[348+((t<<2)+e|0)>>2]=i,a[r+32>>2]=n,r=a[e+372>>2],a[e+364>>2]=t,t=a[r+32>>2],a[r+32>>2]=t+1,r=r+(t<<2)|0,a[r>>2]=i,a[f+12>>2]=0,C[f+8>>2]=-C[f+24>>2],C[f+4>>2]=-C[f+20>>2],C[f>>2]=-C[f+16>>2],a[r+16>>2]=0,pr(e,f,i),A(e))break f;if(r=a[e+372>>2],i=a[r+32>>2]+-1|0,a[r+32>>2]=i,t=a[e+364>>2],r=a[r+(i<<2)>>2],a[348+((t<<2)+e|0)>>2]=r,i=f+24|0,a[i>>2]=0,a[i+4>>2]=0,a[e+364>>2]=t,i=a[e+372>>2],t=a[i+32>>2],a[i+32>>2]=t+1,a[f+16>>2]=0,a[f+20>>2]=0,i=i+(t<<2)|0,a[i>>2]=r,a[f+20>>2]=1065353216,a[i+16>>2]=0,pr(e,f+16|0,r),!A(e))break n;break f;case 0:if(i=a[r>>2],c=C[i+20>>2],t=a[r+4>>2],o=C[t+20>>2],b=C[i+24>>2],l=C[t+24>>2],k=C[i+16>>2],u=C[t+16>>2],a[f+28>>2]=0,v=_(o-c),c=_(v*_(0)),l=_(l-b),o=_(l*_(0)),s=_(c-o),C[f+16>>2]=s,k=_(u-k),b=_(k*_(0)),u=_(l-b),C[f+20>>2]=u,d=_(b-v),C[f+24>>2]=d,_(_(d*d)+_(_(s*s)+_(u*u)))>_(0)){if(a[r+32>>2]=3,a[r+24>>2]=0,i=a[e+364>>2]+-1|0,a[e+364>>2]=i,t=r,r=a[348+((i<<2)+e|0)>>2],a[t+8>>2]=r,pr(e,f+16|0,r),A(e))break f;if(t=a[e+364>>2],r=a[e+372>>2],n=a[r+32>>2]+-1|0,i=a[(n<<2)+r>>2],a[348+((t<<2)+e|0)>>2]=i,a[r+32>>2]=n,r=a[e+372>>2],a[e+364>>2]=t,t=a[r+32>>2],a[r+32>>2]=t+1,r=r+(t<<2)|0,a[r>>2]=i,a[f+12>>2]=0,C[f+8>>2]=-C[f+24>>2],C[f+4>>2]=-C[f+20>>2],C[f>>2]=-C[f+16>>2],a[r+16>>2]=0,pr(e,f,i),A(e))break f;t=a[e+364>>2],a[e+364>>2]=t+1,r=a[e+372>>2],i=a[r+32>>2]+-1|0,a[r+32>>2]=i,a[348+((t<<2)+e|0)>>2]=a[r+(i<<2)>>2]}if(a[f+28>>2]=0,s=_(o-b),C[f+20>>2]=s,l=_(c-l),C[f+16>>2]=l,u=_(k-c),C[f+24>>2]=u,_(_(u*u)+_(_(l*l)+_(s*s)))>_(0)){if(t=a[e+364>>2]+-1|0,a[e+364>>2]=t,r=a[e+372>>2],i=a[r+32>>2],a[r+32>>2]=i+1,r=r+(i<<2)|0,a[r+16>>2]=0,i=r,r=a[348+((t<<2)+e|0)>>2],a[i>>2]=r,pr(e,f+16|0,r),A(e))break f;if(t=a[e+364>>2],r=a[e+372>>2],n=a[r+32>>2]+-1|0,i=a[(n<<2)+r>>2],a[348+((t<<2)+e|0)>>2]=i,a[r+32>>2]=n,r=a[e+372>>2],a[e+364>>2]=t,t=a[r+32>>2],a[r+32>>2]=t+1,r=r+(t<<2)|0,a[r>>2]=i,a[f+12>>2]=0,C[f+8>>2]=-C[f+24>>2],C[f+4>>2]=-C[f+20>>2],C[f>>2]=-C[f+16>>2],a[r+16>>2]=0,pr(e,f,i),A(e))break f;t=a[e+364>>2],a[e+364>>2]=t+1,r=a[e+372>>2],i=a[r+32>>2]+-1|0,a[r+32>>2]=i,a[348+((t<<2)+e|0)>>2]=a[r+(i<<2)>>2]}if(a[f+28>>2]=0,l=_(o-k),C[f+20>>2]=l,o=_(v-o),C[f+16>>2]=o,c=_(b-c),C[f+24>>2]=c,!(_(_(c*c)+_(_(o*o)+_(l*l)))>_(0)))break t;if(t=a[e+364>>2]+-1|0,a[e+364>>2]=t,r=a[e+372>>2],i=a[r+32>>2],a[r+32>>2]=i+1,r=r+(i<<2)|0,a[r+16>>2]=0,i=r,r=a[348+((t<<2)+e|0)>>2],a[i>>2]=r,pr(e,f+16|0,r),A(e))break f;if(t=a[e+364>>2],r=a[e+372>>2],n=a[r+32>>2]+-1|0,i=a[(n<<2)+r>>2],a[348+((t<<2)+e|0)>>2]=i,a[r+32>>2]=n,r=a[e+372>>2],a[e+364>>2]=t,t=a[r+32>>2],a[r+32>>2]=t+1,r=r+(t<<2)|0,a[r>>2]=i,a[f+12>>2]=0,C[f+8>>2]=-C[f+24>>2],C[f+4>>2]=-C[f+20>>2],C[f>>2]=-C[f+16>>2],a[r+16>>2]=0,pr(e,f,i),A(e))break f;t=a[e+364>>2],a[e+364>>2]=t+1,r=a[e+372>>2],i=a[r+32>>2]+-1|0,a[r+32>>2]=i,a[348+((t<<2)+e|0)>>2]=a[r+(i<<2)>>2];break t;case 1:if(a[f+28>>2]=0,i=a[r+4>>2],t=a[r>>2],c=C[t+20>>2],b=_(C[i+20>>2]-c),n=a[r+8>>2],o=C[t+24>>2],v=_(C[n+24>>2]-o),o=_(C[i+24>>2]-o),l=_(C[n+20>>2]-c),c=_(_(b*v)-_(o*l)),C[f+16>>2]=c,u=o,o=C[t+16>>2],s=_(C[n+16>>2]-o),k=_(C[i+16>>2]-o),o=_(_(u*s)-_(k*v)),C[f+20>>2]=o,b=_(_(k*l)-_(b*s)),C[f+24>>2]=b,!(_(_(b*b)+_(_(c*c)+_(o*o)))>_(0)))break t;if(i=r+28|0,a[i>>2]=0,a[i+4>>2]=4,i=a[e+364>>2]+-1|0,a[e+364>>2]=i,t=r,r=a[348+((i<<2)+e|0)>>2],a[t+12>>2]=r,pr(e,f+16|0,r),A(e))break f;if(i=a[e+364>>2],r=a[e+372>>2],n=a[r+32>>2]+-1|0,t=a[(n<<2)+r>>2],a[348+((i<<2)+e|0)>>2]=t,a[r+32>>2]=n,r=a[e+372>>2],a[e+364>>2]=i,n=a[r+32>>2],a[r+32>>2]=n+1,r=r+(n<<2)|0,a[r>>2]=t,a[f+12>>2]=0,C[f+8>>2]=-C[f+24>>2],C[f+4>>2]=-C[f+20>>2],C[f>>2]=-C[f+16>>2],a[r+16>>2]=0,pr(e,f,t),i=1,A(e))break i;t=a[e+364>>2],a[e+364>>2]=t+1,r=a[e+372>>2],i=a[r+32>>2]+-1|0,a[r+32>>2]=i,a[348+((t<<2)+e|0)>>2]=a[r+(i<<2)>>2];break t;case 2:}if(e=a[r>>2],t=a[r+12>>2],c=C[t+16>>2],v=_(C[e+16>>2]-c),n=a[r+4>>2],o=C[t+20>>2],l=_(C[n+20>>2]-o),r=a[r+8>>2],b=C[t+24>>2],s=_(C[r+24>>2]-b),k=_(C[e+20>>2]-o),u=_(C[n+24>>2]-b),d=_(C[r+16>>2]-c),b=_(C[e+24>>2]-b),c=_(C[n+16>>2]-c),o=_(C[r+20>>2]-o),c=_(_(_(_(v*l)*s)+_(_(_(_(_(k*u)*d)+_(_(b*c)*o))-_(_(v*u)*o))-_(_(k*c)*s)))-_(_(b*l)*d)),i=1,c!=_(0)&c==c)break i;break t}if(t=a[e+364>>2],r=a[e+372>>2],n=a[r+32>>2]+-1|0,i=a[(n<<2)+r>>2],a[348+((t<<2)+e|0)>>2]=i,a[r+32>>2]=n,r=a[e+372>>2],a[e+364>>2]=t,t=a[r+32>>2],a[r+32>>2]=t+1,r=r+(t<<2)|0,a[r>>2]=i,a[f+12>>2]=0,C[f+8>>2]=-C[f+24>>2],C[f+4>>2]=-C[f+20>>2],C[f>>2]=-C[f+16>>2],a[r+16>>2]=0,pr(e,f,i),A(e))break f;if(r=a[e+372>>2],i=a[r+32>>2]+-1|0,a[r+32>>2]=i,t=a[e+364>>2],r=a[r+(i<<2)>>2],a[348+((t<<2)+e|0)>>2]=r,i=f+24|0,a[i>>2]=0,a[i+4>>2]=0,a[i>>2]=1065353216,a[e+364>>2]=t,i=a[e+372>>2],t=a[i+32>>2],a[i+32>>2]=t+1,a[f+16>>2]=0,a[f+20>>2]=0,i=i+(t<<2)|0,a[i>>2]=r,a[i+16>>2]=0,pr(e,f+16|0,r),A(e))break f;if(t=a[e+364>>2],r=a[e+372>>2],n=a[r+32>>2]+-1|0,i=a[(n<<2)+r>>2],a[348+((t<<2)+e|0)>>2]=i,a[r+32>>2]=n,r=a[e+372>>2],a[e+364>>2]=t,t=a[r+32>>2],a[r+32>>2]=t+1,r=r+(t<<2)|0,a[r>>2]=i,a[f+12>>2]=0,C[f+8>>2]=-C[f+24>>2],C[f+4>>2]=-C[f+20>>2],C[f>>2]=-C[f+16>>2],a[r+16>>2]=0,pr(e,f,i),A(e))break f;t=a[e+364>>2],a[e+364>>2]=t+1,r=a[e+372>>2],i=a[r+32>>2]+-1|0,a[r+32>>2]=i,a[348+((t<<2)+e|0)>>2]=a[r+(i<<2)>>2]}i=0;break i}i=1}return Y=f+32|0,i}(e)){if(i=a[A+18496>>2],i){for(t=a[A+18508>>2],l=a[A+18500>>2];b=a[i+48>>2],b&&(a[b+44>>2]=a[i+44>>2]),b=a[i+44>>2],b&&(a[b+48>>2]=a[i+48>>2]),(0|i)==a[A+18496>>2]&&(a[A+18496>>2]=a[i+48>>2]),a[i+44>>2]=0,a[i+48>>2]=a[A+18504>>2],b=a[A+18504>>2],b&&(a[b+44>>2]=i),l=l+-1|0,a[A+18504>>2]=i,t=t+1|0,i=a[A+18496>>2],i;);a[A+18508>>2]=t,a[A+18500>>2]=l}if(a[A+18492>>2]=0,a[A>>2]=0,t=a[u>>2],l=a[u+12>>2],n=C[l+16>>2],B=_(C[t+16>>2]-n),i=a[u+4>>2],c=C[l+20>>2],k=_(C[i+20>>2]-c),b=a[u+8>>2],s=C[l+24>>2],v=_(C[b+24>>2]-s),g=_(C[t+20>>2]-c),Q=_(C[i+24>>2]-s),h=_(C[b+16>>2]-n),s=_(C[t+24>>2]-s),n=_(C[i+16>>2]-n),c=_(C[b+20>>2]-c),_(_(_(_(B*k)*v)+_(_(_(_(_(g*Q)*h)+_(_(s*n)*c))-_(_(B*Q)*c))-_(_(g*n)*v)))-_(_(s*k)*h))<_(0)?(a[u+4>>2]=t,a[u>>2]=i,l=a[u+16>>2],m=u+20|0,a[u+16>>2]=a[m>>2],a[m>>2]=l,l=t):(l=i,i=t),l=Dr(A,i,l,b,1),b=Dr(A,a[u+4>>2],a[u>>2],a[u+12>>2],1),R=Dr(A,a[u+8>>2],a[u+4>>2],a[u+12>>2],1),m=Dr(A,a[u>>2],a[u+8>>2],a[u+12>>2],1),4==a[A+18500>>2]){if(t=a[A+18496>>2],n=C[t+16>>2],i=a[t+48>>2],i){for(n=_(n*n);c=C[i+16>>2],c=_(c*c),r=c>2],i;);n=C[t+16>>2]}for(r=a[t+28>>2],u=a[t+24>>2],p=a[t+20>>2],k=C[t+12>>2],B=C[t+8>>2],s=C[t+4>>2],c=C[t>>2],a[l+32>>2]=b,f[l+52|0]=0,a[b+32>>2]=l,f[b+52|0]=0,a[l+36>>2]=R,f[l+53|0]=0,a[R+32>>2]=l,f[R+52|0]=1,a[l+40>>2]=m,f[l+54|0]=0,a[m+32>>2]=l,f[m+52|0]=2,a[b+36>>2]=m,f[b+53|0]=2,a[m+40>>2]=b,f[m+54|0]=1,a[b+40>>2]=R,f[b+54|0]=1,a[R+36>>2]=b,i=R+53|0,f[0|i]=258,f[i+1|0]=1,a[R+40>>2]=m,f[m+53|0]=2,a[m+36>>2]=R,a[A>>2]=0,b=0;;){i:{f:{if(i=a[A+18492>>2],!(i>>>0<=127)){a[A>>2]=6;break i}if(a[A+18492>>2]=i+1,b=b+1|0,f[t+55|0]=b,a[G+8>>2]=0,a[G>>2]=0,a[G+4>>2]=0,i=(i<<5)+A|0,m=i+60|0,pr(e,t,m),!(_(_(_(_(C[t>>2]*C[i+76>>2])+_(C[t+4>>2]*C[i+80>>2]))+_(C[t+8>>2]*C[i+84>>2]))-C[t+16>>2])>_(9999999747378752e-20))){a[A>>2]=7;break i}for(l=t+32|0,i=52;;){if(R=Er(A,b,m,a[l>>2],o[t+i|0],G),!R)break f;if(W=i+-51|0,l=l+4|0,i=i+1|0,!(W>>>0<3))break}}if(R&d[G+8>>2]>2){if(r=a[G>>2],f[r+53|0]=2,i=a[G+4>>2],a[r+36>>2]=i,a[i+40>>2]=r,f[i+54|0]=1,r=a[t+48>>2],r&&(a[r+44>>2]=a[t+44>>2]),r=a[t+44>>2],r&&(a[r+48>>2]=a[t+48>>2]),(0|t)==a[A+18496>>2]&&(a[A+18496>>2]=a[t+48>>2]),a[t+44>>2]=0,a[t+48>>2]=a[A+18504>>2],a[A+18500>>2]=a[A+18500>>2]+-1,r=a[A+18504>>2],r&&(a[r+44>>2]=t),a[A+18504>>2]=t,a[A+18508>>2]=a[A+18508>>2]+1,t=a[A+18496>>2],n=C[t+16>>2],i=a[t+48>>2],i){for(n=_(n*n);c=C[i+16>>2],c=_(c*c),r=c>2],i;);n=C[t+16>>2]}if(r=a[t+28>>2],u=a[t+24>>2],p=a[t+20>>2],k=C[t+12>>2],B=C[t+8>>2],s=C[t+4>>2],c=C[t>>2],255!=(0|b))continue}else a[A>>2]=4}break}C[A+56>>2]=n,C[A+40>>2]=c,C[A+52>>2]=k,C[A+48>>2]=B,C[A+44>>2]=s,e=A+20|0,c=_(c*n),k=_(C[u+16>>2]-c),i=r+20|0,s=_(s*n),v=_(C[i>>2]-s),t=u+20|0,g=_(C[t>>2]-s),Q=_(C[r+16>>2]-c),h=_(_(k*v)-_(g*Q)),l=r+24|0,n=_(B*n),B=_(C[l>>2]-n),F=_(g*B),b=u+24|0,g=_(C[b>>2]-n),v=_(F-_(g*v)),B=_(_(g*Q)-_(k*B)),B=_(y(_(_(h*h)+_(_(v*v)+_(B*B))))),C[e>>2]=B,m=A+24|0,k=_(C[r+16>>2]-c),R=p+20|0,v=_(C[R>>2]-s),g=_(C[i>>2]-s),Q=_(C[p+16>>2]-c),h=_(_(k*v)-_(g*Q)),w=_(h*h),F=g,i=p+24|0,g=_(C[i>>2]-n),h=_(C[l>>2]-n),v=_(_(F*g)-_(h*v)),k=_(_(h*Q)-_(k*g)),k=_(y(_(w+_(_(v*v)+_(k*k))))),C[m>>2]=k,a[A+4>>2]=p,a[A+36>>2]=3,a[A+12>>2]=r,a[A+8>>2]=u,v=_(C[p+16>>2]-c),g=_(C[t>>2]-s),s=_(C[R>>2]-s),c=_(C[u+16>>2]-c),Q=_(_(v*g)-_(s*c)),F=s,s=_(C[b>>2]-n),n=_(C[i>>2]-n),g=_(_(F*s)-_(n*g)),n=_(_(n*c)-_(v*s)),c=_(y(_(_(Q*Q)+_(_(g*g)+_(n*n))))),n=_(c+_(B+k)),C[A+28>>2]=c/n,C[m>>2]=k/n,C[e>>2]=B/n,i=a[A>>2];break r}}a[A>>2]=8,n=C[r+8>>2],c=C[r+4>>2],s=C[r>>2],a[A+52>>2]=0,B=_(-s),C[A+40>>2]=B,k=_(-c),C[A+44>>2]=k,v=_(-n),C[A+48>>2]=v,n=_(y(_(_(_(s*s)+_(c*c))+_(n*n)))),n>_(0)?(n=_(_(1)/n),C[A+48>>2]=n*v,C[A+44>>2]=n*k,C[A+40>>2]=n*B):(a[A+48>>2]=0,a[A+40>>2]=1065353216,a[A+44>>2]=0),a[A+52>>2]=0,a[A+56>>2]=0,a[A+36>>2]=1,a[A+20>>2]=1065353216,a[A+4>>2]=a[u>>2],i=8}return Y=G+16|0,i}(c+16|0,c+18528|0,c))){if(!a[c+52>>2]){l=_(0),u=_(0),s=_(0);break e}for(i=c+36|0,s=_(0),t=0,u=_(0),l=_(0);A=a[c+19036>>2],r=a[c+18912>>2]+(A>>1)|0,v=a[c+19032>>2],Qt[1&A?a[v+a[r>>2]>>2]:v](c,r,a[i+-16>>2]),k=C[i>>2],s=_(s+_(k*C[c+8>>2])),u=_(u+_(k*C[c+4>>2])),l=_(l+_(C[c>>2]*k)),i=i+4|0,t=t+1|0,t>>>0>2];);break e}a[n>>2]=3;break A}a[n>>2]=2;break A}k=C[e+48>>2],m=C[e+8>>2],g=C[e>>2],R=C[e+4>>2],B=C[e+52>>2],Q=C[e+24>>2],h=C[e+16>>2],G=C[e+20>>2],p=C[e+56>>2],F=C[e+40>>2],W=C[e+32>>2],w=C[e+36>>2],a[n+16>>2]=0,C[n+12>>2]=p+_(_(_(l*W)+_(u*w))+_(s*F)),C[n+8>>2]=B+_(_(_(l*h)+_(u*G))+_(s*Q)),C[n+4>>2]=k+_(_(_(l*g)+_(u*R))+_(s*m)),M=1,a[n>>2]=1,m=C[e+56>>2],g=C[e+40>>2],R=C[e+32>>2],B=C[e+36>>2],Q=C[e+52>>2],h=C[e+24>>2],G=C[e+16>>2],p=C[e+20>>2],F=C[e+48>>2],W=C[e+8>>2],w=C[e>>2],Z=C[e+4>>2],a[n+32>>2]=0,a[n+48>>2]=0,E=C[c+56>>2],C[n+36>>2]=-E,D=C[c+60>>2],C[n+40>>2]=-D,V=C[c- -64>>2],C[n+44>>2]=-V,k=C[c+72>>2],C[n+52>>2]=-k,l=_(l-_(E*k)),u=_(u-_(k*D)),s=_(s-_(k*V)),C[n+20>>2]=F+_(_(_(w*l)+_(Z*u))+_(W*s)),C[n+24>>2]=Q+_(_(_(l*G)+_(u*p))+_(s*h)),C[n+28>>2]=m+_(_(_(l*R)+_(u*B))+_(s*g))}return Y=c+19040|0,M}function Dr(A,e,r,i,t){var n,o=0,c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=0,g=_(0),B=_(0);if(n=a[A+18504>>2],n){if(o=a[n+48>>2],o&&(a[o+44>>2]=a[n+44>>2]),o=a[n+44>>2],o&&(a[o+48>>2]=a[n+48>>2]),(0|n)==a[A+18504>>2]&&(a[A+18504>>2]=a[n+48>>2]),a[n+44>>2]=0,a[n+48>>2]=a[A+18496>>2],o=A+18508|0,a[o>>2]=a[o>>2]+-1,o=a[A+18496>>2],o&&(a[o+44>>2]=n),a[A+18496>>2]=n,o=A+18500|0,a[o>>2]=a[o>>2]+1,f[n+55|0]=0,a[n+28>>2]=i,a[n+24>>2]=r,a[n+20>>2]=e,s=C[r+20>>2],k=C[i+24>>2],u=C[r+24>>2],c=C[e+24>>2],l=C[e+20>>2],v=C[i+20>>2],g=C[i+16>>2],B=C[r+16>>2],b=C[e+16>>2],a[n+12>>2]=0,s=_(s-l),k=_(k-c),u=_(u-c),v=_(v-l),c=_(_(s*k)-_(u*v)),C[n>>2]=c,l=u,u=_(g-b),b=_(B-b),l=_(_(l*u)-_(b*k)),C[n+4>>2]=l,b=_(_(b*v)-_(s*u)),C[n+8>>2]=b,d=2,c=_(y(_(_(_(c*c)+_(l*l))+_(b*b)))),c>_(9999999747378752e-20)){if(o=n+16|0,Zr(n,e,r,o)||Zr(n,r,i,o)||Zr(n,i,e,o)||(C[n+16>>2]=_(_(_(C[e+16>>2]*C[n>>2])+_(C[e+20>>2]*C[n+4>>2]))+_(C[e+24>>2]*C[n+8>>2]))/c),c=_(_(1)/c),C[n>>2]=c*C[n>>2],C[n+4>>2]=c*C[n+4>>2],C[n+8>>2]=c*C[n+8>>2],t)return n;if(d=3,C[o>>2]>=_(-9999999747378752e-21))return n}return a[A>>2]=d,e=a[n+48>>2],e&&(a[e+44>>2]=a[n+44>>2]),e=a[n+44>>2],e&&(a[e+48>>2]=a[n+48>>2]),(0|n)==a[A+18496>>2]&&(a[A+18496>>2]=a[n+48>>2]),a[n+44>>2]=0,a[n+48>>2]=a[A+18504>>2],a[A+18500>>2]=a[A+18500>>2]+-1,e=a[A+18504>>2],e&&(a[e+44>>2]=n),a[A+18504>>2]=n,a[A+18508>>2]=a[A+18508>>2]+1,0}return a[A>>2]=5,0}function Er(A,e,r,i,t,n){var c=0,b=0,l=0;A:if(o[i+55|0]!=(0|e)){if(c=t<<2,b=a[c+14768>>2],_(_(_(_(C[i>>2]*C[r+16>>2])+_(C[i+4>>2]*C[r+20>>2]))+_(C[i+8>>2]*C[r+24>>2]))-C[i+16>>2])<_(-9999999747378752e-21)){if(e=A,A=i+20|0,A=Dr(e,a[A+(b<<2)>>2],a[A+c>>2],r,0),!A)break A;return a[A+32>>2]=i,f[A+52|0]=t,f[52+(i+t|0)|0]=0,a[32+((t<<2)+i|0)>>2]=A,e=a[n>>2],e?(a[e+36>>2]=A,f[e+53|0]=2,a[A+40>>2]=e,f[A+54|0]=1):a[n+4>>2]=A,a[n>>2]=A,a[n+8>>2]=a[n+8>>2]+1,1}f[i+55|0]=e,Er(A,e,r,a[32+((b<<2)+i|0)>>2],o[52+(i+b|0)|0],n)&&(t=e,e=a[c+14780>>2],Er(A,t,r,a[32+((e<<2)+i|0)>>2],o[52+(e+i|0)|0],n)&&(e=a[i+48>>2],e&&(a[e+44>>2]=a[i+44>>2]),e=a[i+44>>2],e&&(a[e+48>>2]=a[i+48>>2]),(0|i)==a[A+18496>>2]&&(a[A+18496>>2]=a[i+48>>2]),a[i+44>>2]=0,a[i+48>>2]=a[A+18504>>2],e=A+18500|0,a[e>>2]=a[e>>2]+-1,e=a[A+18504>>2],e&&(a[e+44>>2]=i),a[A+18504>>2]=i,l=1,A=A+18508|0,a[A>>2]=a[A>>2]+1))}return l}function Zr(A,e,r,i){var f=_(0),t=_(0),n=_(0),a=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0);return o=C[r+24>>2],f=C[e+24>>2],l=_(o-f),c=C[r+16>>2],n=C[e+16>>2],u=_(c-n),t=C[A+4>>2],b=C[r+20>>2],a=C[e+20>>2],s=_(b-a),k=C[A>>2],v=C[A+8>>2],A=0,_(_(f*_(_(u*t)-_(s*k)))+_(_(n*_(_(s*v)-_(l*t)))+_(a*_(_(l*k)-_(u*v)))))<_(0)&&(t=_(_(_(n*n)+_(a*a))+_(f*f)),_(_(_(n*u)+_(a*s))+_(f*l))>_(0)||(t=_(_(_(c*c)+_(b*b))+_(o*o)),_(_(_(c*u)+_(b*s))+_(o*l))<_(0)||(t=_(_(_(_(c*c)+_(b*b))+_(o*o))*_(_(_(n*n)+_(a*a))+_(f*f))),f=_(_(_(c*n)+_(b*a))+_(o*f)),f=_(_(t-_(f*f))/_(_(_(u*u)+_(s*s))+_(l*l))),t=f>_(0)?f:_(0))),C[i>>2]=y(t),A=1),A}function Yr(A){var e=0;f[A+356|0]=1,a[A>>2]=0,f[A+312|0]=0,a[A+292>>2]=1566444395,a[A+296>>2]=1566444395,e=A+336|0,a[e>>2]=0,a[e+4>>2]=0,e=A+300|0,a[e>>2]=1566444395,a[e+4>>2]=0,e=A+344|0,a[e>>2]=0,a[e+4>>2]=0,f[A+352|0]=0,A=A+332|0,f[0|A]=240&o[0|A]}function Vr(A,e,r,i){var t,n=0,o=0,c=0;n=a[e+4>>2],a[A+292>>2]=a[e>>2],a[A+296>>2]=n,n=e+8|0,c=a[n+4>>2],o=A+300|0,a[o>>2]=a[n>>2],a[o+4>>2]=c,f[A+356|0]=1,t=a[n+4>>2],o=(a[A>>2]<<4)+A|0,c=o+12|0,a[c>>2]=a[n>>2],a[c+4>>2]=t,n=o+4|0,o=a[e+4>>2],a[n>>2]=a[e>>2],a[n+4>>2]=o,o=r+8|0,c=a[o+4>>2],e=(a[A>>2]<<4)+A|0,n=e+92|0,a[n>>2]=a[o>>2],a[n+4>>2]=c,n=a[r+4>>2],e=e+84|0,a[e>>2]=a[r>>2],a[e+4>>2]=n,n=a[i+4>>2],e=(a[A>>2]<<4)+A|0,r=e+164|0,a[r>>2]=a[i>>2],a[r+4>>2]=n,r=i+8|0,i=a[r+4>>2],e=e+172|0,a[e>>2]=a[r>>2],a[e+4>>2]=i,a[A>>2]=a[A>>2]+1}function Nr(A){var e,r=0,i=0,t=0,n=0,c=0,b=0,l=_(0),u=0,s=0,k=_(0),v=0,d=0,g=_(0),B=_(0),m=0,R=_(0),Q=0,h=0,G=_(0),y=_(0),p=0,F=_(0),W=_(0),w=0,D=0,E=_(0),Z=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0),U=0;e=Y-16|0,Y=e;A:if(o[A+356|0]){f[A+356|0]=0,f[A+352|0]=0,r=A+344|0,a[r>>2]=0,a[r+4>>2]=0,D=A+336|0,r=D,a[r>>2]=0,a[r+4>>2]=0,n=A+332|0,r=-16&o[0|n],f[0|n]=r,n=a[A>>2];e:if(!(n>>>0>4)){i=A+316|0;r:{i:{switch(n-1|0){case 1:n=A,R=C[A+4>>2],l=_(C[A+20>>2]-R),G=C[A+8>>2],g=_(C[A+24>>2]-G),y=C[A+12>>2],B=_(C[A+28>>2]-y),R=_(_(_(_(_(0)-R)*l)+_(_(_(0)-G)*g))+_(_(_(0)-y)*B));f:if(R>_(0)){if(k=_(_(_(l*l)+_(g*g))+_(B*B)),R>2]=0,a[r+4>>2]=0,C[A+340>>2]=k,R=_(_(1)-k),C[A+336>>2]=R,a[A+256>>2]=0,l=C[A+92>>2],G=_(l+_(k*_(C[A+108>>2]-l))),C[A+252>>2]=G,l=C[A+88>>2],y=_(l+_(k*_(C[A+104>>2]-l))),C[A+248>>2]=y,l=C[A+84>>2],F=_(l+_(k*_(C[A+100>>2]-l))),C[A+244>>2]=F,W=C[A+180>>2],E=C[A+184>>2],l=C[A+168>>2],Z=C[A+188>>2],g=C[A+172>>2],B=C[A+164>>2],a[A+288>>2]=0,g=_(g+_(k*_(Z-g))),C[A+284>>2]=G-g,l=_(l+_(k*_(E-l))),C[A+280>>2]=y-l,B=_(B+_(k*_(W-B))),C[A+276>>2]=F-B,a[A+272>>2]=0,C[A+268>>2]=g,C[A+264>>2]=l,C[A+260>>2]=B,n=1,2&i||(a[A>>2]=1,n=0),1&i||(a[A>>2]=n,i=(n<<4)+A|0,r=i+12|0,n=a[r>>2],r=a[r+4>>2],u=i+4|0,c=a[u>>2],u=a[u+4>>2],v=i+84|0,h=a[v+4>>2],t=A+84|0,a[t>>2]=a[v>>2],a[t+4>>2]=h,b=i+92|0,v=a[b+4>>2],t=t+8|0,a[t>>2]=a[b>>2],a[t+4>>2]=v,v=i+164|0,h=a[v+4>>2],t=A+164|0,a[t>>2]=a[v>>2],a[t+4>>2]=h,i=i+172|0,b=a[i+4>>2],t=t+8|0,a[t>>2]=a[i>>2],a[t+4>>2]=b,i=A+4|0,a[i>>2]=c,a[i+4>>2]=u,i=i+8|0,a[i>>2]=n,a[i+4>>2]=r),i=k>=_(0)&R>=_(0);break e;case 2:r=e+8|0,a[r>>2]=0,a[r+4>>2]=0,a[e>>2]=0,a[e+4>>2]=0,u=A+4|0,c=A+20|0,t=A+36|0,Ir(e,u,c,t,i),a[A+256>>2]=0,g=C[A+336>>2],k=C[A+340>>2],l=C[A+344>>2],B=_(_(_(g*C[A+92>>2])+_(k*C[A+108>>2]))+_(l*C[A+124>>2])),C[A+252>>2]=B,R=_(_(_(g*C[A+88>>2])+_(k*C[A+104>>2]))+_(l*C[A+120>>2])),C[A+248>>2]=R,b=A+100|0,v=A+116|0,G=_(_(_(g*C[A+84>>2])+_(k*C[b>>2]))+_(l*C[v>>2])),C[A+244>>2]=G,h=A+180|0,y=C[h>>2],m=A+196|0,F=C[m>>2],W=C[A+168>>2],E=C[A+184>>2],Z=C[A+200>>2],N=C[A+172>>2],I=C[A+188>>2],J=C[A+204>>2],x=C[A+164>>2],a[A+288>>2]=0,V=B,B=_(_(_(g*N)+_(k*I))+_(l*J)),C[A+284>>2]=V-B,V=R,R=_(_(_(g*W)+_(k*E))+_(l*Z)),C[A+280>>2]=V-R,g=_(_(_(g*x)+_(k*y))+_(l*F)),C[A+276>>2]=G-g,a[A+272>>2]=0,C[A+268>>2]=B,C[A+264>>2]=R,C[A+260>>2]=g;f:{t:{n:{a:{o:{r=a[A>>2];c:if((0|r)>=4){if(n=o[A+332|0],8&n){i=r;break c}i=r+-1|0,a[A>>2]=i,r=(i<<4)+A|0,d=r+12|0,Q=a[d+4>>2],s=A+60|0,a[s>>2]=a[d>>2],a[s+4>>2]=Q,d=r+4|0,Q=a[d+4>>2],s=A+52|0,a[s>>2]=a[d>>2],a[s+4>>2]=Q,d=r+92|0,Q=a[d+4>>2],s=A+140|0,a[s>>2]=a[d>>2],a[s+4>>2]=Q,d=r+84|0,Q=a[d+4>>2],s=A+132|0,a[s>>2]=a[d>>2],a[s+4>>2]=Q,d=r+164|0,Q=a[d+4>>2],s=A+212|0,a[s>>2]=a[d>>2],a[s+4>>2]=Q,r=r+172|0,d=a[r+4>>2],s=A+220|0,a[s>>2]=a[r>>2],a[s+4>>2]=d}else{if(i=3,3!=(0|r))break o;n=o[A+332|0]}if(4&n)break a;i=i+-1|0,a[A>>2]=i,r=(i<<4)+A|0,d=r+12|0,Q=a[d+4>>2],s=t+8|0,a[s>>2]=a[d>>2],a[s+4>>2]=Q,s=r+4|0,d=a[s+4>>2],a[t>>2]=a[s>>2],a[t+4>>2]=d,s=r+92|0,d=a[s+4>>2],t=v+8|0,a[t>>2]=a[s>>2],a[t+4>>2]=d,t=r+84|0,s=a[t+4>>2],a[v>>2]=a[t>>2],a[v+4>>2]=s,t=r+164|0,v=a[t+4>>2],a[m>>2]=a[t>>2],a[m+4>>2]=v,r=r+172|0,v=a[r+4>>2],t=m+8|0,a[t>>2]=a[r>>2],a[t+4>>2]=v;break a}if(i=2,(0|r)<2)break n;n=o[A+332|0]}if(2&n)break t;i=i+-1|0,a[A>>2]=i,r=(i<<4)+A|0,v=r+12|0,m=a[v+4>>2],t=c+8|0,a[t>>2]=a[v>>2],a[t+4>>2]=m,t=r+4|0,v=a[t+4>>2],a[c>>2]=a[t>>2],a[c+4>>2]=v,t=r+92|0,v=a[t+4>>2],c=b+8|0,a[c>>2]=a[t>>2],a[c+4>>2]=v,c=r+84|0,t=a[c+4>>2],a[b>>2]=a[c>>2],a[b+4>>2]=t,c=r+164|0,t=a[c+4>>2],a[h>>2]=a[c>>2],a[h+4>>2]=t,r=r+172|0,t=a[r+4>>2],c=h+8|0,a[c>>2]=a[r>>2],a[c+4>>2]=t;break t}if(i=1,1!=(0|r))break f;n=o[A+332|0]}1&n||(i=i+-1|0,a[A>>2]=i,i=(i<<4)+A|0,n=i+12|0,c=a[n+4>>2],r=u+8|0,a[r>>2]=a[n>>2],a[r+4>>2]=c,r=i+4|0,n=a[r+4>>2],a[u>>2]=a[r>>2],a[u+4>>2]=n,u=i+92|0,c=a[u+4>>2],r=A+84|0,n=r+8|0,a[n>>2]=a[u>>2],a[n+4>>2]=c,n=i+84|0,u=a[n+4>>2],a[r>>2]=a[n>>2],a[r+4>>2]=u,u=i+164|0,c=a[u+4>>2],r=A+164|0,a[r>>2]=a[u>>2],a[r+4>>2]=c,i=i+172|0,n=a[i+4>>2],r=r+8|0,a[r>>2]=a[i>>2],a[r+4>>2]=n)}if(i=0,C[D>>2]>=_(0)^1|k>=_(0)^1|l>=_(0)^1)break e;i=C[A+348>>2]>=_(0);break e;case 3:if(r=e+8|0,a[r>>2]=0,a[r+4>>2]=0,a[e>>2]=0,a[e+4>>2]=0,u=A+4|0,c=A+20|0,t=A+36|0,b=A+52|0,function(A,e,r,i,t,n){var c=_(0),b=0,l=_(0),u=_(0),s=_(0),k=_(0),v=0,d=0,g=_(0),B=_(0),m=_(0),R=_(0),Q=0,h=_(0),G=_(0),y=0,p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),V=_(0),N=0,I=0,J=_(0),x=_(0),U=_(0),M=_(0),S=_(0),X=_(0);return b=Y-48|0,Y=b,v=a[A+4>>2],a[n>>2]=a[A>>2],a[n+4>>2]=v,v=A+8|0,d=a[v+4>>2],v=a[v>>2],f[n+16|0]=15|o[n+16|0],y=n+8|0,a[y>>2]=v,a[y+4>>2]=d,f[b+24|0]=0,v=-1,d=-1,J=C[t>>2],k=C[e>>2],s=_(J-k),g=C[r+4>>2],c=C[e+4>>2],m=_(g-c),x=C[i+8>>2],u=C[e+8>>2],l=_(x-u),p=C[r+8>>2],R=_(p-u),U=C[i+4>>2],h=_(U-c),F=_(_(m*l)-_(R*h)),M=C[t+4>>2],G=_(M-c),S=C[i>>2],W=_(S-k),w=C[r>>2],D=_(w-k),E=_(_(R*W)-_(D*l)),Z=_(_(D*h)-_(m*W)),X=C[t+8>>2],V=_(X-u),B=_(_(_(s*F)+_(G*E))+_(Z*V)),_(B*B)<_(9.99999905104687e-9)||(d=_(B*_(_(_(F*_(C[A>>2]-k))+_(E*_(C[A+4>>2]-c)))+_(Z*_(C[A+8>>2]-u))))<_(0)),F=_(_(W*G)-_(h*s)),E=_(_(h*V)-_(l*G)),Z=_(_(l*s)-_(W*V)),B=_(_(R*F)+_(_(D*E)+_(m*Z))),_(B*B)<_(9.99999905104687e-9)||(v=_(B*_(_(_(E*_(C[A>>2]-k))+_(Z*_(C[A+4>>2]-c)))+_(F*_(C[A+8>>2]-u))))<_(0)),y=-1,I=-1,B=l,l=_(_(m*s)-_(D*G)),m=_(_(R*G)-_(m*V)),R=_(_(D*V)-_(R*s)),s=_(_(B*l)+_(_(W*m)+_(h*R))),_(s*s)<_(9.99999905104687e-9)||(I=_(s*_(_(_(m*_(C[A>>2]-k))+_(R*_(C[A+4>>2]-c)))+_(l*_(C[A+8>>2]-u))))<_(0)),h=_(u-p),u=_(U-g),s=_(J-w),m=_(S-w),l=_(M-g),R=_(_(u*s)-_(m*l)),G=_(k-w),k=_(x-p),B=u,u=_(X-p),l=_(_(k*l)-_(B*u)),B=_(c-g),c=_(_(m*u)-_(k*s)),k=_(_(h*R)+_(_(G*l)+_(B*c))),_(k*k)<_(9.99999905104687e-9)||(y=_(k*_(_(_(l*_(C[A>>2]-w))+_(c*_(C[A+4>>2]-g)))+_(R*_(C[A+8>>2]-p))))<_(0)),N=d|v|I|y,(0|N)<=-1?(f[n+36|0]=1,Q=0):(Q=0,N&&(l=_(3.4028234663852886e38),d&&(Ir(A,e,r,i,b+8|0),k=C[b+8>>2],c=_(k-C[A>>2]),l=_(c*c),c=C[b+12>>2],u=_(c-C[A+4>>2]),l=_(l+_(u*u)),u=C[b+16>>2],s=_(u-C[A+8>>2]),s=_(l+_(s*s)),l=_(3.4028234663852886e38),s<_(3.4028234663852886e38)&&(a[n+12>>2]=a[b+20>>2],C[n+8>>2]=u,C[n+4>>2]=c,C[n>>2]=k,d=a[b+32>>2],a[n+20>>2]=a[b+28>>2],a[n+24>>2]=d,a[n+32>>2]=0,a[n+28>>2]=a[b+36>>2],d=o[b+24|0],f[n+16|0]=1&d|240&o[n+16|0]|2&d|4&d,l=s)),k=l,v&&(Ir(A,e,i,t,b+8|0),u=C[b+8>>2],c=_(u-C[A>>2]),l=_(c*c),s=C[b+12>>2],c=_(s-C[A+4>>2]),l=_(l+_(c*c)),g=C[b+16>>2],c=_(g-C[A+8>>2]),c=_(l+_(c*c)),c>2]=a[b+20>>2],C[n+8>>2]=g,C[n+4>>2]=s,C[n>>2]=u,a[n+20>>2]=a[b+28>>2],a[n+24>>2]=0,v=b+32|0,d=a[v+4>>2],N=n+28|0,a[N>>2]=a[v>>2],a[N+4>>2]=d,v=o[b+24|0],d=v<<1,f[n+16|0]=8&d|4&d|1&v|240&o[n+16|0],k=c)),I&&(Ir(A,e,t,r,b+8|0),u=C[b+8>>2],c=_(u-C[A>>2]),l=_(c*c),s=C[b+12>>2],c=_(s-C[A+4>>2]),l=_(l+_(c*c)),g=C[b+16>>2],c=_(g-C[A+8>>2]),c=_(l+_(c*c)),c>2]=a[b+20>>2],C[n+8>>2]=g,C[n+4>>2]=s,C[n>>2]=u,a[n+20>>2]=a[b+28>>2],a[n+28>>2]=0,a[n+32>>2]=a[b+32>>2],a[n+24>>2]=a[b+36>>2],e=o[b+24|0],f[n+16|0]=1&e|240&o[n+16|0]|e>>>1&2|e<<2&8,k=c)),Q=1,y&&(Ir(A,r,t,i,b+8|0),c=C[b+8>>2],u=_(c-C[A>>2]),l=_(u*u),u=C[b+12>>2],s=_(u-C[A+4>>2]),l=_(l+_(s*s)),s=C[b+16>>2],g=_(s-C[A+8>>2]),Q=1,_(l+_(g*g))>2]=a[b+20>>2],C[n+8>>2]=s,C[n+4>>2]=u,C[n>>2]=c,a[n+20>>2]=0,a[n+24>>2]=a[b+28>>2],a[n+32>>2]=a[b+32>>2],a[n+28>>2]=a[b+36>>2],A=o[b+24|0],f[n+16|0]=4&A|240&o[n+16|0]|A<<1&2|A<<2&8,Q=1)))),A=Q,Y=b+48|0,A}(e,u,c,t,b,i)){a[A+256>>2]=0,l=C[A+336>>2],g=C[A+340>>2],B=C[A+344>>2],k=C[A+348>>2],R=_(_(_(_(l*C[A+92>>2])+_(g*C[A+108>>2]))+_(B*C[A+124>>2]))+_(k*C[A+140>>2])),C[A+252>>2]=R,G=_(_(_(_(l*C[A+88>>2])+_(g*C[A+104>>2]))+_(B*C[A+120>>2]))+_(k*C[A+136>>2])),C[A+248>>2]=G,v=A+100|0,h=A+116|0,m=A+132|0,y=_(_(_(_(l*C[A+84>>2])+_(g*C[v>>2]))+_(B*C[h>>2]))+_(k*C[m>>2])),C[A+244>>2]=y,a[A+288>>2]=0,a[A+272>>2]=0,s=A+180|0,d=A+196|0,Q=A+212|0,F=_(_(_(_(l*C[A+164>>2])+_(g*C[s>>2]))+_(B*C[d>>2]))+_(k*C[Q>>2])),C[A+260>>2]=F,W=_(_(_(_(l*C[A+168>>2])+_(g*C[A+184>>2]))+_(B*C[A+200>>2]))+_(k*C[A+216>>2])),C[A+264>>2]=W,l=_(_(_(_(l*C[A+172>>2])+_(g*C[A+188>>2]))+_(B*C[A+204>>2]))+_(k*C[A+220>>2])),C[A+268>>2]=l,C[A+276>>2]=y-F,C[A+280>>2]=G-W,C[A+284>>2]=R-l;f:{t:{n:{a:{o:{r=a[A>>2];c:if((0|r)>=4){if(n=o[A+332|0],8&n){i=r;break c}i=r+-1|0,a[A>>2]=i,r=(i<<4)+A|0,w=r+12|0,U=a[w+4>>2],p=b+8|0,a[p>>2]=a[w>>2],a[p+4>>2]=U,p=r+4|0,w=a[p+4>>2],a[b>>2]=a[p>>2],a[b+4>>2]=w,p=r+92|0,w=a[p+4>>2],b=m+8|0,a[b>>2]=a[p>>2],a[b+4>>2]=w,b=r+84|0,p=a[b+4>>2],a[m>>2]=a[b>>2],a[m+4>>2]=p,b=r+164|0,m=a[b+4>>2],a[Q>>2]=a[b>>2],a[Q+4>>2]=m,r=r+172|0,m=a[r+4>>2],b=Q+8|0,a[b>>2]=a[r>>2],a[b+4>>2]=m}else{if(i=3,3!=(0|r))break o;n=o[A+332|0]}if(4&n)break a;i=i+-1|0,a[A>>2]=i,r=(i<<4)+A|0,m=r+12|0,Q=a[m+4>>2],b=t+8|0,a[b>>2]=a[m>>2],a[b+4>>2]=Q,b=r+4|0,m=a[b+4>>2],a[t>>2]=a[b>>2],a[t+4>>2]=m,b=r+92|0,m=a[b+4>>2],t=h+8|0,a[t>>2]=a[b>>2],a[t+4>>2]=m,t=r+84|0,b=a[t+4>>2],a[h>>2]=a[t>>2],a[h+4>>2]=b,t=r+164|0,b=a[t+4>>2],a[d>>2]=a[t>>2],a[d+4>>2]=b,r=r+172|0,b=a[r+4>>2],t=d+8|0,a[t>>2]=a[r>>2],a[t+4>>2]=b;break a}if(i=2,(0|r)<2)break n;n=o[A+332|0]}if(2&n)break t;i=i+-1|0,a[A>>2]=i,r=(i<<4)+A|0,b=r+12|0,h=a[b+4>>2],t=c+8|0,a[t>>2]=a[b>>2],a[t+4>>2]=h,t=r+4|0,b=a[t+4>>2],a[c>>2]=a[t>>2],a[c+4>>2]=b,t=r+92|0,b=a[t+4>>2],c=v+8|0,a[c>>2]=a[t>>2],a[c+4>>2]=b,c=r+84|0,t=a[c+4>>2],a[v>>2]=a[c>>2],a[v+4>>2]=t,c=r+164|0,t=a[c+4>>2],a[s>>2]=a[c>>2],a[s+4>>2]=t,r=r+172|0,t=a[r+4>>2],c=s+8|0,a[c>>2]=a[r>>2],a[c+4>>2]=t;break t}if(i=1,1!=(0|r))break f;n=o[A+332|0]}1&n||(i=i+-1|0,a[A>>2]=i,i=(i<<4)+A|0,n=i+12|0,c=a[n+4>>2],r=u+8|0,a[r>>2]=a[n>>2],a[r+4>>2]=c,r=i+4|0,n=a[r+4>>2],a[u>>2]=a[r>>2],a[u+4>>2]=n,u=i+92|0,c=a[u+4>>2],r=A+84|0,n=r+8|0,a[n>>2]=a[u>>2],a[n+4>>2]=c,n=i+84|0,u=a[n+4>>2],a[r>>2]=a[n>>2],a[r+4>>2]=u,u=i+164|0,c=a[u+4>>2],r=A+164|0,a[r>>2]=a[u>>2],a[r+4>>2]=c,i=i+172|0,n=a[i+4>>2],r=r+8|0,a[r>>2]=a[i>>2],a[r+4>>2]=n)}if(i=0,C[D>>2]>=_(0)^1|C[A+340>>2]>=_(0)^1|C[A+344>>2]>=_(0)^1)break e;i=k>=_(0);break e}if(!o[A+352|0])break i;break;case 0:break r}i=0;break e}a[A+276>>2]=0,a[A+280>>2]=0,i=1,f[A+312|0]=1,A=A+284|0,a[A>>2]=0,a[A+4>>2]=0;break A}i=a[A+168>>2],a[A+260>>2]=a[A+164>>2],a[A+264>>2]=i,i=a[A+88>>2],a[A+244>>2]=a[A+84>>2],a[A+248>>2]=i,u=A+172|0,c=a[u+4>>2],n=A+268|0,i=n,a[i>>2]=a[u>>2],a[i+4>>2]=c,u=A+92|0,c=a[u+4>>2],i=A+252|0,a[i>>2]=a[u>>2],a[i+4>>2]=c,f[A+352|0]=0,a[A+288>>2]=0,C[A+280>>2]=C[A+248>>2]-C[A+264>>2],C[A+276>>2]=C[A+244>>2]-C[A+260>>2],C[A+284>>2]=C[i>>2]-C[n>>2],i=A+344|0,a[i>>2]=0,a[i+4>>2]=0,a[A+336>>2]=1065353216,a[A+340>>2]=0,f[A+332|0]=r,i=1}f[A+312|0]=i}else i=o[A+312|0];return Y=e+16|0,0!=(255&i)}function Ir(A,e,r,i,t){var n,c,b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),Y=_(0),V=_(0);n=-16&o[t+16|0],f[t+16|0]=n,Z=C[i>>2],d=C[e>>2],Q=_(Z-d),v=C[A>>2],b=_(v-d),Y=C[i+4>>2],g=C[e+4>>2],h=_(Y-g),s=C[A+4>>2],l=_(s-g),V=C[i+8>>2],B=C[e+8>>2],G=_(V-B),m=C[A+8>>2],u=_(m-B),k=_(_(_(Q*b)+_(h*l))+_(G*u)),c=t,W=C[r>>2],y=_(W-d),w=C[r+4>>2],p=_(w-g),D=C[r+8>>2],F=_(D-B),l=_(_(_(y*b)+_(p*l))+_(F*u)),l<=_(0)^1|k<=_(0)^1?(b=_(v-W),u=_(s-w),R=_(m-D),E=_(_(_(Q*b)+_(h*u))+_(G*R)),u=_(_(_(y*b)+_(p*u))+_(F*R)),u>=_(0)^1|E<=u^1?(R=_(_(l*E)-_(u*k)),u<=_(0)^1|l>=_(0)^1||(b=_(0),!(R<=_(0)))?(b=_(v-Z),s=_(s-Y),m=_(m-V),v=_(_(_(y*b)+_(p*s))+_(F*m)),b=_(_(_(Q*b)+_(h*s))+_(G*m)),b>=_(0)^1|v<=b^1?(s=_(_(v*k)-_(l*b)),b<=_(0)^1|k>=_(0)^1||(l=_(0),!(s<=_(0)))?(k=_(_(u*b)-_(v*E)),k<=_(0)&&(l=_(E-u),l>=_(0)&&(b=_(v-b),b>=_(0)))?(a[t+12>>2]=0,f[t+16|0]=6|n,b=_(l/_(l+b)),C[t+8>>2]=D+_(_(V-D)*b),C[t+4>>2]=w+_(_(Y-w)*b),C[t>>2]=W+_(_(Z-W)*b),l=_(_(1)-b),u=_(0)):(a[t+12>>2]=0,f[t+16|0]=7|n,l=_(_(1)/_(R+_(k+s))),b=_(R*l),l=_(s*l),C[t+8>>2]=_(G*b)+_(B+_(F*l)),C[t+4>>2]=_(h*b)+_(g+_(p*l)),C[t>>2]=_(Q*b)+_(d+_(y*l)),u=_(_(_(1)-l)-b))):(a[t+12>>2]=0,f[t+16|0]=5|n,b=_(k/_(k-b)),C[t+8>>2]=B+_(G*b),C[t+4>>2]=g+_(h*b),C[t>>2]=d+_(Q*b),u=_(_(1)-b))):(A=a[i+4>>2],a[t>>2]=a[i>>2],a[t+4>>2]=A,A=i+8|0,e=a[A+4>>2],r=t+8|0,a[r>>2]=a[A>>2],a[r+4>>2]=e,f[t+16|0]=4|n,b=_(1),l=_(0),u=_(0))):(a[t+12>>2]=0,f[t+16|0]=3|n,l=_(l/_(l-u)),C[t+8>>2]=B+_(F*l),C[t+4>>2]=g+_(p*l),C[t>>2]=d+_(y*l),u=_(_(1)-l))):(A=a[r+4>>2],a[t>>2]=a[r>>2],a[t+4>>2]=A,A=r+8|0,e=a[A+4>>2],r=t+8|0,a[r>>2]=a[A>>2],a[r+4>>2]=e,f[t+16|0]=2|n,l=_(1),b=_(0),u=_(0))):(A=a[e+4>>2],a[t>>2]=a[e>>2],a[t+4>>2]=A,A=e+8|0,e=a[A+4>>2],r=t+8|0,a[r>>2]=a[A>>2],a[r+4>>2]=e,f[t+16|0]=1|n,l=_(0),b=_(0),u=_(1)),C[c+20>>2]=u,a[t+32>>2]=0,C[t+28>>2]=b,C[t+24>>2]=l}function Jr(A,e){var r,i,f,t=0;return i=Nr(A),r=A+284|0,f=a[r+4>>2],t=e+8|0,a[t>>2]=a[r>>2],a[t+4>>2]=f,t=a[A+280>>2],a[e>>2]=a[A+276>>2],a[e+4>>2]=t,i}function xr(A,e){var r=0,i=_(0),f=0,t=0,n=_(0),o=_(0),c=_(0),b=_(0),l=_(0);t=a[A>>2],f=0;A:if(!((0|t)<1)){for(r=A+8|0,o=C[A+308>>2],c=C[e+8>>2],b=C[e+4>>2],l=C[e>>2];;){if(i=_(l-C[r+-4>>2]),n=_(i*i),i=_(b-C[r>>2]),n=_(n+_(i*i)),i=_(c-C[r+4>>2]),f=1,_(n+_(i*i))<=o)break A;if(r=r+16|0,t=t+-1|0,!t)break}f=0}return r=f,C[e+12>>2]!=C[A+304>>2]|C[e+8>>2]!=C[A+300>>2]|C[e+4>>2]!=C[A+296>>2]|C[e>>2]!=C[A+292>>2]||(r=1),r}function Ur(A,e,r){var i=0,f=0;Nr(A),i=a[A+248>>2],a[e>>2]=a[A+244>>2],a[e+4>>2]=i,i=A+252|0,f=a[i+4>>2],e=e+8|0,a[e>>2]=a[i>>2],a[e+4>>2]=f,i=A+268|0,f=a[i+4>>2],e=r+8|0,a[e>>2]=a[i>>2],a[e+4>>2]=f,e=a[A+264>>2],a[r>>2]=a[A+260>>2],a[r+4>>2]=e}function Mr(A,e,r,i,t){var n,o=_(0),c=_(0);return a[A>>2]=14908,a[A+32>>2]=r,a[A+28>>2]=e,a[A+24>>2]=i,a[A+20>>2]=t,a[A+4>>2]=0,a[A+8>>2]=1065353216,i=A+12|0,a[i>>2]=0,a[i+4>>2]=0,a[A+36>>2]=a[e+4>>2],a[A+40>>2]=a[r+4>>2],n=A,c=_(Qt[a[a[e>>2]+48>>2]](e)),C[n+44>>2]=c,o=_(Qt[a[a[r>>2]+48>>2]](r)),a[A+72>>2]=1,a[A+76>>2]=1,a[A+60>>2]=-1,f[A+52|0]=0,C[A+48>>2]=o,A}function Sr(A,e,r,i,f){A|=0,e|=0,r|=0,i|=0,function(A,e,r,i){var f=0,t=0,n=_(0),c=_(0),b=0,l=_(0),u=_(0),s=_(0),k=0,v=0,d=_(0),g=_(0),B=_(0),m=_(0),R=0,Q=_(0),h=_(0),G=0,p=_(0),F=_(0),W=_(0),w=_(0),D=0,E=_(0),Z=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0),U=_(0),M=_(0),S=_(0),X=_(0),T=_(0),j=_(0),O=_(0),H=_(0),z=_(0),P=_(0),K=_(0),L=_(0),q=_(0),$=_(0),AA=_(0),eA=_(0);for(f=Y-272|0,Y=f,a[A+56>>2]=0,k=f+264|0,a[k>>2]=0,a[k+4>>2]=0,a[f+256>>2]=0,a[f+260>>2]=0,t=e+8|0,b=a[t+4>>2],k=f+168|0,a[k>>2]=a[t>>2],a[k+4>>2]=b,t=e+24|0,b=a[t+4>>2],k=f+184|0,a[k>>2]=a[t>>2],a[k+4>>2]=b,t=e+40|0,b=a[t+4>>2],k=f+200|0,a[k>>2]=a[t>>2],a[k+4>>2]=b,b=e+56|0,v=a[b+4>>2],k=f+216|0,t=k,a[t>>2]=a[b>>2],a[t+4>>2]=v,t=a[e+4>>2],a[f+160>>2]=a[e>>2],a[f+164>>2]=t,t=a[e+20>>2],a[f+176>>2]=a[e+16>>2],a[f+180>>2]=t,t=a[e+36>>2],a[f+192>>2]=a[e+32>>2],a[f+196>>2]=t,t=a[e+52>>2],a[f+208>>2]=a[e+48>>2],a[f+212>>2]=t,v=e+120|0,R=a[v+4>>2],t=f+152|0,a[t>>2]=a[v>>2],a[t+4>>2]=R,v=e+72|0,R=a[v+4>>2],b=f+104|0,a[b>>2]=a[v>>2],a[b+4>>2]=R,v=e+88|0,R=a[v+4>>2],b=f+120|0,a[b>>2]=a[v>>2],a[b+4>>2]=R,v=e+104|0,R=a[v+4>>2],b=f+136|0,a[b>>2]=a[v>>2],a[b+4>>2]=R,b=a[e+68>>2],a[f+96>>2]=a[e+64>>2],a[f+100>>2]=b,b=e+80|0,v=a[b+4>>2],a[f+112>>2]=a[b>>2],a[f+116>>2]=v,b=e+96|0,v=a[b+4>>2],a[f+128>>2]=a[b>>2],a[f+132>>2]=v,b=e+112|0,v=a[b+4>>2],a[f+144>>2]=a[b>>2],a[f+148>>2]=v,b=f+148|0,n=C[b>>2],v=f+212|0,c=C[v>>2],l=C[f+144>>2],u=C[f+208>>2],g=C[k>>2],s=C[t>>2],F=_(_(g+s)*_(.5)),C[k>>2]=g-F,W=_(_(c+n)*_(.5)),C[v>>2]=c-W,w=_(_(u+l)*_(.5)),C[f+208>>2]=u-w,C[t>>2]=s-F,C[b>>2]=n-W,C[f+144>>2]=l-w,v=0,v=a[a[A+28>>2]+4>>2]+-17>>>0<=1?a[a[A+32>>2]+4>>2]+-17>>>0<2:v,a[A+68>>2]=0,a[A+4>>2]=0,a[A+8>>2]=1065353216,a[A+60>>2]=-1,a[A+64>>2]=0,k=A+12|0,a[k>>2]=0,a[k+4>>2]=0,a[432]=a[432]+1,d=C[A+44>>2],n=C[A+48>>2],R=o[A+52|0],Yr(a[A+24>>2]),g=R?_(0):n,k=A+4|0,c=_(0xde0b6b000000000),b=0;;){a[f+252>>2]=0,u=C[A+4>>2],s=_(-u),n=C[A+8>>2],l=C[A+12>>2],C[f+248>>2]=_(_(C[e+8>>2]*s)-_(C[e+24>>2]*n))-_(C[e+40>>2]*l),C[f+244>>2]=_(_(C[e+4>>2]*s)-_(n*C[e+20>>2]))-_(l*C[e+36>>2]),C[f+240>>2]=_(_(C[e>>2]*s)-_(n*C[e+16>>2]))-_(l*C[e+32>>2]),a[f+236>>2]=0,C[f+232>>2]=_(_(u*C[e+72>>2])+_(n*C[e+88>>2]))+_(l*C[e+104>>2]),C[f+228>>2]=_(_(u*C[e+68>>2])+_(n*C[e+84>>2]))+_(l*C[e+100>>2]),C[f+224>>2]=_(_(u*C[e+64>>2])+_(n*C[e+80>>2]))+_(l*C[e+96>>2]),hA(f+80|0,a[A+28>>2],f+240|0),hA(f- -64|0,a[A+32>>2],f+224|0),a[f+60>>2]=0,n=C[f+80>>2],u=C[f+84>>2],s=C[f+88>>2],l=_(_(_(_(n*C[f+192>>2])+_(u*C[f+196>>2]))+_(s*C[f+200>>2]))+C[f+216>>2]),C[f+56>>2]=l,m=_(_(_(_(n*C[f+176>>2])+_(u*C[f+180>>2]))+_(s*C[f+184>>2]))+C[f+212>>2]),C[f+52>>2]=m,h=_(_(_(_(n*C[f+160>>2])+_(u*C[f+164>>2]))+_(s*C[f+168>>2]))+C[f+208>>2]),C[f+48>>2]=h,a[f+44>>2]=0,n=C[f+64>>2],s=C[f+68>>2],B=C[f+72>>2],u=_(_(_(_(n*C[f+128>>2])+_(s*C[f+132>>2]))+_(B*C[f+136>>2]))+C[f+152>>2]),C[f+40>>2]=u,Q=_(_(_(_(n*C[f+112>>2])+_(s*C[f+116>>2]))+_(B*C[f+120>>2]))+C[f+148>>2]),C[f+36>>2]=Q,n=_(_(_(_(n*C[f+96>>2])+_(s*C[f+100>>2]))+_(B*C[f+104>>2]))+C[f+144>>2]),C[f+32>>2]=n,v&&(a[f+40>>2]=0,a[f+56>>2]=0,u=_(0),l=_(0)),a[f+28>>2]=0,s=_(m-Q),C[f+20>>2]=s,B=C[A+8>>2],n=_(h-n),C[f+16>>2]=n,m=C[A+4>>2],l=_(l-u),C[f+24>>2]=l;A:{if(n=_(_(_(n*m)+_(s*B))+_(l*C[A+12>>2])),n>_(0)^1|_(n*n)>_(c*C[e+128>>2])^1){if(xr(a[A+24>>2],f+16|0)){b=1,a[A+68>>2]=1,t=2;break A}if(n=_(c-n),n<=_(c*_(9.999999974752427e-7))){t=2,a[A+68>>2]=n<=_(0)?2:11,b=1;break A}if(Vr(a[A+24>>2],f+16|0,f+48|0,f+32|0),Jr(a[A+24>>2],f)){if(n=C[f>>2],l=_(n*n),n=C[f+4>>2],l=_(l+_(n*n)),n=C[f+8>>2],n=_(l+_(n*n)),!(n<_(9.999999974752427e-7))){_(c-n)<=_(c*_(1.1920928955078125e-7))?(a[A+68>>2]=12,b=1,t=2):(t=a[f+4>>2],a[k>>2]=a[f>>2],a[k+4>>2]=t,G=f+8|0,D=a[G+4>>2],t=k+8|0,a[t>>2]=a[G>>2],a[t+4>>2]=D,G=a[A+64>>2],a[A+64>>2]=G+1,t=2,(0|G)>1e3||(4==a[a[A+24>>2]>>2]?a[A+68>>2]=13:t=0)),c=n;break A}t=a[f+4>>2],a[k>>2]=a[f>>2],a[k+4>>2]=t,a[A+68>>2]=6,b=f+8|0,G=a[b+4>>2],t=k+8|0,a[t>>2]=a[b>>2],a[t+4>>2]=G}else a[A+68>>2]=3}else a[A+68>>2]=10;b=1,t=2}if(t)break}n=_(0),l=R?_(0):d,u=_(l+g),v=0,t=0,1&b&&(Ur(a[A+24>>2],f+240|0,f+224|0),b=k+8|0,R=a[b+4>>2],t=f+264|0,a[t>>2]=a[b>>2],a[t+4>>2]=R,t=a[k+4>>2],a[f+256>>2]=a[k>>2],a[f+260>>2]=t,n=C[A+4>>2],s=C[A+8>>2],B=C[A+12>>2],d=_(_(_(n*n)+_(s*s))+_(B*B)),d<_(9.999999974752427e-7)&&(a[A+68>>2]=5),b=1,d>_(1.4210854715202004e-14)?(d=_(_(1)/_(y(d))),C[f+256>>2]=d*C[f+256>>2],C[f+260>>2]=d*C[f+260>>2],C[f+264>>2]=d*C[f+264>>2],m=_(y(c)),c=_(l/m),C[f+240>>2]=C[f+240>>2]-_(c*n),C[f+244>>2]=C[f+244>>2]-_(c*s),C[f+248>>2]=C[f+248>>2]-_(c*B),c=_(g/m),C[f+224>>2]=_(c*n)+C[f+224>>2],C[f+228>>2]=_(c*s)+C[f+228>>2],C[f+232>>2]=_(c*B)+C[f+232>>2],t=1,n=_(_(_(1)/d)-u)):(t=0,b=2,n=_(0)),a[A+60>>2]=b),!a[A+68>>2]|!a[A+72>>2]|!a[A+20>>2]||(v=_(u+n)>2],v)){if(a[k>>2]=0,a[k+4>>2]=0,R=k+8|0,a[R>>2]=0,a[R+4>>2]=0,a[431]=a[431]+1,Qt[a[a[v>>2]+8>>2]](v,a[A+24>>2],a[A+28>>2],a[A+32>>2],f+160|0,f+96|0,k,f+80|0,f- -64|0,i)){if(B=_(0),c=C[f+64>>2],d=C[f+80>>2],g=_(c-d),m=C[f+68>>2],h=C[f+84>>2],s=_(m-h),Q=C[f+72>>2],p=C[f+88>>2],l=_(Q-p),u=_(_(_(g*g)+_(s*s))+_(l*l)),u<=_(1.4210854715202004e-14)&&(B=C[A+16>>2],g=C[A+4>>2],s=C[A+8>>2],l=C[A+12>>2],u=_(_(_(g*g)+_(s*s))+_(l*l))),u>_(1.4210854715202004e-14)){if(a[A+60>>2]=3,c=_(d-c),d=_(c*c),c=_(h-m),d=_(d+_(c*c)),c=_(p-Q),c=_(-_(y(_(d+_(c*c))))),!((n>c^-1)&(1^b))){t=f+88|0,b=a[t+4>>2],i=f+248|0,a[i>>2]=a[t>>2],a[i+4>>2]=b,t=f+72|0,b=a[t+4>>2],i=f+232|0,a[i>>2]=a[t>>2],a[i+4>>2]=b,i=a[f+84>>2],a[f+240>>2]=a[f+80>>2],a[f+244>>2]=i,i=a[f+68>>2],a[f+224>>2]=a[f+64>>2],a[f+228>>2]=i,C[f+268>>2]=B,n=_(_(1)/_(y(u))),C[f+264>>2]=l*n,C[f+260>>2]=s*n,C[f+256>>2]=g*n,n=c;break e}if(a[A+60>>2]=8,t)break e;break A}if(a[A+60>>2]=9,t)break e;break A}if(s=C[A+4>>2],B=C[A+8>>2],d=C[A+12>>2],_(_(_(s*s)+_(B*B))+_(d*d))>_(0)){if(c=_(C[f+80>>2]-C[f+64>>2]),m=_(c*c),c=_(C[f+84>>2]-C[f+68>>2]),m=_(m+_(c*c)),c=_(C[f+88>>2]-C[f+72>>2]),c=_(_(y(_(m+_(c*c))))-u),!((c>2],t=f+248|0,a[t>>2]=a[b>>2],a[t+4>>2]=v,b=f+72|0,v=a[b+4>>2],i=f+232|0,a[i>>2]=a[b>>2],a[i+4>>2]=v,C[t>>2]=C[t>>2]-_(l*d),C[i>>2]=_(g*d)+C[i>>2],i=a[f+68>>2],a[f+224>>2]=a[f+64>>2],a[f+228>>2]=i,i=a[f+84>>2],a[f+240>>2]=a[f+80>>2],a[f+244>>2]=i,C[f+224>>2]=_(g*s)+C[f+224>>2],C[f+228>>2]=_(g*B)+C[f+228>>2],C[f+240>>2]=C[f+240>>2]-_(l*s),C[f+244>>2]=C[f+244>>2]-_(l*B),b=k+8|0,v=a[b+4>>2],i=f+264|0,t=i,a[t>>2]=a[b>>2],a[t+4>>2]=v,t=a[k+4>>2],a[f+256>>2]=a[k>>2],a[f+260>>2]=t,l=C[f+256>>2],u=C[f+260>>2],g=C[i>>2],n=_(_(1)/_(y(_(_(_(l*l)+_(u*u))+_(g*g))))),C[i>>2]=g*n,C[f+260>>2]=u*n,C[f+256>>2]=l*n,a[A+60>>2]=6,n=c;break e}a[A+60>>2]=5}}if(!t)break A}_(n*n)>2]^1&&!(n<_(0))||(i=a[f+260>>2],a[k>>2]=a[f+256>>2],a[k+4>>2]=i,C[A+56>>2]=n,i=f+264|0,t=a[i+4>>2],k=k+8|0,a[k>>2]=a[i>>2],a[k+4>>2]=t,a[f+92>>2]=0,u=C[f+256>>2],c=C[f+260>>2],l=C[i>>2],C[f+88>>2]=_(_(u*C[e+8>>2])+_(c*C[e+24>>2]))+_(l*C[e+40>>2]),C[f+84>>2]=_(_(u*C[e+4>>2])+_(c*C[e+20>>2]))+_(l*C[e+36>>2]),C[f+80>>2]=_(_(u*C[e>>2])+_(c*C[e+16>>2]))+_(l*C[e+32>>2]),a[f+76>>2]=0,u=_(-u),C[f+72>>2]=_(_(C[e+72>>2]*u)-_(c*C[e+88>>2]))-_(l*C[e+104>>2]),C[f+68>>2]=_(_(C[e+68>>2]*u)-_(c*C[e+84>>2]))-_(l*C[e+100>>2]),C[f+64>>2]=_(_(C[e+64>>2]*u)-_(c*C[e+80>>2]))-_(l*C[e+96>>2]),hA(f+48|0,a[A+28>>2],f+80|0),hA(f+32|0,a[A+32>>2],f- -64|0),c=C[i>>2],p=C[f+216>>2],E=C[f+200>>2],Z=C[f+192>>2],V=C[f+196>>2],N=C[f+152>>2],I=C[f+136>>2],J=C[f+128>>2],x=C[f+132>>2],U=C[f+208>>2],M=C[f+168>>2],S=C[f+160>>2],X=C[f+164>>2],T=C[f+144>>2],j=C[f+104>>2],O=C[f+96>>2],H=C[f+100>>2],z=C[f+212>>2],P=C[f+184>>2],g=C[f+56>>2],K=C[f+176>>2],s=C[f+48>>2],L=C[f+180>>2],B=C[f+52>>2],q=C[f+148>>2],$=C[f+120>>2],d=C[f+40>>2],AA=C[f+112>>2],m=C[f+32>>2],eA=C[f+116>>2],h=C[f+36>>2],u=C[f+256>>2],l=C[f+260>>2],a[f+92>>2]=0,Q=_(-u),C[f+88>>2]=_(_(C[e+8>>2]*Q)-_(l*C[e+24>>2]))-_(c*C[e+40>>2]),C[f+84>>2]=_(_(C[e+4>>2]*Q)-_(l*C[e+20>>2]))-_(c*C[e+36>>2]),C[f+80>>2]=_(_(C[e>>2]*Q)-_(l*C[e+16>>2]))-_(c*C[e+32>>2]),a[f+76>>2]=0,C[f+72>>2]=_(_(u*C[e+72>>2])+_(l*C[e+88>>2]))+_(c*C[e+104>>2]),C[f+68>>2]=_(_(u*C[e+68>>2])+_(l*C[e+84>>2]))+_(c*C[e+100>>2]),C[f+64>>2]=_(_(u*C[e+64>>2])+_(l*C[e+80>>2]))+_(c*C[e+96>>2]),hA(f+48|0,a[A+28>>2],f+80|0),hA(f+32|0,a[A+32>>2],f- -64|0),h=_(_(_(_(_(U+_(_(_(s*S)+_(B*X))+_(g*M)))-_(T+_(_(_(m*O)+_(h*H))+_(d*j))))*Q)-_(l*_(_(z+_(_(_(s*K)+_(B*L))+_(g*P)))-_(q+_(_(_(m*AA)+_(h*eA))+_(d*$))))))-_(c*_(_(p+_(_(_(s*Z)+_(B*V))+_(g*E)))-_(N+_(_(_(m*J)+_(h*x))+_(d*I)))))),c=C[f+48>>2],l=C[f+52>>2],u=C[f+56>>2],g=C[f+32>>2],s=C[f+36>>2],B=C[f+40>>2],d=C[f+256>>2],m=C[f+260>>2],Q=_(_(_(_(_(_(_(c*C[f+160>>2])+_(l*C[f+164>>2]))+_(u*C[f+168>>2]))+C[f+208>>2])-_(_(_(_(g*C[f+96>>2])+_(s*C[f+100>>2]))+_(B*C[f+104>>2]))+C[f+144>>2]))*d)+_(_(_(_(_(_(c*C[f+176>>2])+_(l*C[f+180>>2]))+_(u*C[f+184>>2]))+C[f+212>>2])-_(_(_(_(g*C[f+112>>2])+_(s*C[f+116>>2]))+_(B*C[f+120>>2]))+C[f+148>>2]))*m)),l=_(_(_(_(_(c*C[f+192>>2])+_(l*C[f+196>>2]))+_(u*C[f+200>>2]))+C[f+216>>2])-_(_(_(_(g*C[f+128>>2])+_(s*C[f+132>>2]))+_(B*C[f+136>>2]))+C[f+152>>2])),c=C[i>>2],h>_(Q+_(l*c))&&(a[A+60>>2]=10,C[f+264>>2]=-c,C[f+260>>2]=-m,C[f+256>>2]=-d),a[f+92>>2]=0,C[f+88>>2]=F+C[f+232>>2],C[f+84>>2]=W+C[f+228>>2],C[f+80>>2]=w+C[f+224>>2],Qt[a[a[r>>2]+16>>2]](r,f+256|0,f+80|0,n))}Y=f+272|0}(A,e,r,i)}function Xr(){o[2736]||(a[602]=1062847606,a[603]=0,a[600]=1042701022,a[601]=1056964440,a[598]=1062847606,a[599]=0,a[596]=-1093024784,a[597]=1050556081,a[594]=1062847606,a[595]=0,a[592]=-1093024784,a[593]=-1096927567,a[590]=1062847606,a[591]=0,a[588]=1042701022,a[589]=-1090519208,a[586]=1062847572,a[587]=0,a[584]=1057396286,a[585]=0,a[582]=1057396386,a[583]=0,a[580]=1060121912,a[581]=1056964507,a[578]=1057396420,a[579]=0,a[576]=-1098475836,a[577]=1062148969,a[574]=1057396386,a[575]=0,a[572]=-1084636143,a[573]=0,a[570]=1057396420,a[571]=0,a[568]=-1098475836,a[569]=-1085334679,a[566]=1057396386,a[567]=0,a[564]=1060121912,a[565]=-1090519141,a[562]=-2147483648,a[563]=0,a[560]=1058437413,a[561]=1062149053,a[558]=-2147483648,a[559]=0,a[556]=-2147483648,a[557]=1065353216,a[554]=-2147483648,a[555]=0,a[552]=-1089046235,a[553]=1062149053,a[550]=-2147483648,a[551]=0,a[548]=-1082951543,a[549]=1050556148,a[546]=-2147483648,a[547]=0,a[544]=-1082951543,a[545]=-1096927500,a[542]=0,a[543]=0,a[540]=-1089046235,a[541]=-1085334595,a[538]=0,a[539]=0,a[536]=0,a[537]=-1082130432,a[534]=0,a[535]=0,a[532]=1058437413,a[533]=-1085334595,a[530]=0,a[531]=0,a[528]=1064532105,a[529]=-1096927500,a[526]=0,a[527]=0,a[524]=1064532105,a[525]=1050556148,a[522]=-1090087228,a[523]=0,a[520]=1049007812,a[521]=1062148969,a[518]=-1090087262,a[519]=0,a[516]=-1087361736,a[517]=1056964507,a[514]=-1084636042,a[515]=0,a[512]=-1104782626,a[513]=1056964440,a[510]=-1090087262,a[511]=0,a[508]=-1087361736,a[509]=-1090519141,a[506]=-1084636076,a[507]=0,a[504]=-1090087362,a[505]=-2147483648,a[502]=-1090087262,a[503]=0,a[500]=1062847505,a[501]=-2147483648,a[498]=-1084636042,a[499]=0,a[496]=1054458864,a[497]=1050556081,a[494]=-1090087228,a[495]=0,a[492]=1049007812,a[493]=-1085334679,a[490]=-1084636042,a[491]=0,a[488]=-1104782626,a[489]=-1090519208,a[486]=-1084636042,a[487]=0,a[484]=1054458864,a[485]=-1096927567,a[482]=1065353216,a[483]=0,a[480]=-2147483648,a[481]=0,a[478]=1055193471,a[479]=0,a[476]=1063581978,a[477]=0,a[474]=1055193572,a[475]=0,a[472]=1049461434,a[473]=1062847522,a[470]=1055193572,a[471]=0,a[468]=-1086767520,a[469]=1057396202,a[466]=1055193572,a[467]=0,a[464]=-1086767520,a[465]=-1090087446,a[462]=1055193605,a[463]=0,a[460]=1049461434,a[461]=-1084636126,a[458]=-1092290076,a[459]=0,a[456]=1060716128,a[457]=1057396202,a[454]=-1092290043,a[455]=0,a[452]=-1098022214,a[453]=1062847522,a[450]=-1092290177,a[451]=0,a[448]=-1083901670,a[449]=-2147483648,a[446]=-1092290076,a[447]=0,a[444]=-1098022214,a[445]=-1084636126,a[442]=-1092290076,a[443]=0,a[440]=1060716128,a[441]=-1090087446,a[438]=-1082130432,a[439]=0,a[436]=0,a[437]=-2147483648,f[2736]=1)}function Tr(A,e,r,i){var t=0,n=0,c=0,b=0,l=_(0),u=0,s=0,k=0,v=_(0),d=_(0),g=0,B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=0,y=_(0),p=_(0),F=_(0),W=0;A:if(G=a[A+4>>2],!((0|G)<2))for(b=a[A+12>>2],t=(b+(G<<4)|0)-16|0,B=C[t>>2],y=C[r>>2],v=C[t+4>>2],p=C[r+4>>2],d=C[t+8>>2],F=C[r+8>>2],l=_(_(_(_(B*y)+_(v*p))+_(d*F))+i);;){t=(W<<4)+b|0,m=C[t>>2],R=C[t+4>>2],Q=C[t+8>>2],h=_(_(_(_(m*y)+_(R*p))+_(Q*F))+i),g=a[t+12>>2];e:{r:if(l<_(0)){if(h<_(0)){if(t=a[e+4>>2],(0|t)==a[e+8>>2]&&(u=t?t<<1:1,!((0|t)>=(0|u)))){if(u?(s=dA(u<<4),t=a[e+4>>2]):s=0,(0|t)>=1)for(b=0;n=a[e+12>>2]+b|0,k=a[n+4>>2],c=b+s|0,a[c>>2]=a[n>>2],a[c+4>>2]=k,n=n+8|0,k=a[n+4>>2],c=c+8|0,a[c>>2]=a[n>>2],a[c+4>>2]=k,b=b+16|0,t=t+-1|0,t;);t=a[e+12>>2],t&&(o[e+16|0]&&CA(t),a[e+12>>2]=0),a[e+12>>2]=s,f[e+16|0]=1,a[e+8>>2]=u,t=a[e+4>>2]}t=a[e+12>>2]+(t<<4)|0,a[t+12>>2]=g,C[t+8>>2]=Q,C[t+4>>2]=R,C[t>>2]=m;break r}if(l=_(l/_(l-h)),d=_(d+_(_(Q-d)*l)),v=_(v+_(_(R-v)*l)),l=_(B+_(_(m-B)*l)),t=a[e+4>>2],(0|t)==a[e+8>>2]&&(s=t?t<<1:1,!((0|t)>=(0|s)))){if(s?(u=dA(s<<4),t=a[e+4>>2]):u=0,(0|t)>=1)for(b=0;g=a[e+12>>2]+b|0,k=a[g+4>>2],n=b+u|0,a[n>>2]=a[g>>2],a[n+4>>2]=k,g=g+8|0,c=a[g+4>>2],n=n+8|0,a[n>>2]=a[g>>2],a[n+4>>2]=c,b=b+16|0,t=t+-1|0,t;);t=a[e+12>>2],t&&(o[e+16|0]&&CA(t),a[e+12>>2]=0),a[e+12>>2]=u,f[e+16|0]=1,a[e+8>>2]=s,t=a[e+4>>2]}t=a[e+12>>2]+(t<<4)|0,a[t+12>>2]=0,C[t+8>>2]=d,C[t+4>>2]=v,C[t>>2]=l}else{if(!(h<_(0)))break e;if(l=_(l/_(l-h)),d=_(d+_(_(Q-d)*l)),v=_(v+_(_(R-v)*l)),l=_(B+_(_(m-B)*l)),t=a[e+4>>2],(0|t)==a[e+8>>2]&&(u=t?t<<1:1,!((0|t)>=(0|u)))){if(u?(s=dA(u<<4),t=a[e+4>>2]):s=0,(0|t)>=1)for(b=0;n=a[e+12>>2]+b|0,k=a[n+4>>2],c=b+s|0,a[c>>2]=a[n>>2],a[c+4>>2]=k,n=n+8|0,k=a[n+4>>2],c=c+8|0,a[c>>2]=a[n>>2],a[c+4>>2]=k,b=b+16|0,t=t+-1|0,t;);t=a[e+12>>2],t&&(o[e+16|0]&&CA(t),a[e+12>>2]=0),a[e+12>>2]=s,f[e+16|0]=1,a[e+8>>2]=u,t=a[e+4>>2]}if(t=a[e+12>>2]+(t<<4)|0,a[t+12>>2]=0,C[t+8>>2]=d,C[t+4>>2]=v,C[t>>2]=l,t=a[e+4>>2]+1|0,a[e+4>>2]=t,a[e+8>>2]==(0|t)&&(u=t?t<<1:1,!((0|t)>=(0|u)))){if(u?(s=dA(u<<4),t=a[e+4>>2]):s=0,(0|t)>=1)for(b=0;n=a[e+12>>2]+b|0,k=a[n+4>>2],c=b+s|0,a[c>>2]=a[n>>2],a[c+4>>2]=k,n=n+8|0,k=a[n+4>>2],c=c+8|0,a[c>>2]=a[n>>2],a[c+4>>2]=k,b=b+16|0,t=t+-1|0,t;);t=a[e+12>>2],t&&(o[e+16|0]&&CA(t),a[e+12>>2]=0),a[e+12>>2]=s,f[e+16|0]=1,a[e+8>>2]=u,t=a[e+4>>2]}t=a[e+12>>2]+(t<<4)|0,a[t+12>>2]=g,C[t+8>>2]=Q,C[t+4>>2]=R,C[t>>2]=m}a[e+4>>2]=a[e+4>>2]+1}if(W=W+1|0,(0|W)==(0|G))break A;F=C[r+8>>2],p=C[r+4>>2],y=C[r>>2],b=a[A+12>>2],l=h,d=Q,v=R,B=m}}function jr(A,e,r,i,f,t,n){var a=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0);return a=C[i>>2],b=C[i+4>>2],l=C[i+8>>2],s=_(_(_(C[r>>2]*a)+_(C[r+4>>2]*b))+_(C[r+8>>2]*l)),o=_(_(_(a*C[A>>2])+_(b*C[A+16>>2]))+_(l*C[A+32>>2])),c=C[f+80>>2],u=_(o*(o<_(0)?_(-c):c)),o=_(_(_(a*C[A+4>>2])+_(b*C[A+20>>2]))+_(l*C[A+36>>2])),c=C[f+84>>2],u=_(u+_(o*(o<_(0)?_(-c):c))),o=_(_(_(a*C[A+8>>2])+_(b*C[A+24>>2]))+_(l*C[A+40>>2])),c=C[f+88>>2],o=_(u+_(o*(o<_(0)?_(-c):c))),c=C[f+96>>2],u=o>c?o:c,o=_(_(_(a*C[e>>2])+_(b*C[e+16>>2]))+_(l*C[e+32>>2])),c=C[t+80>>2],k=_(o*(o<_(0)?_(-c):c)),o=_(_(_(a*C[e+4>>2])+_(b*C[e+20>>2]))+_(l*C[e+36>>2])),c=C[t+84>>2],a=_(_(_(a*C[e+8>>2])+_(b*C[e+24>>2]))+_(l*C[e+40>>2])),b=C[t+88>>2],a=_(_(k+_(o*(o<_(0)?_(-c):c)))+_(a*(a<_(0)?_(-b):b))),b=C[t+96>>2],a=_(u+(a>b?a:b)),b=_(s+a),a=_(a-s),(bn^1}function Or(A,e,r,i,t,n,c,b){var l,u=0,s=0,k=0,v=0,d=0,g=_(0),m=_(0),R=_(0),Q=_(0),h=0,G=_(0),y=_(0),p=_(0),F=_(0),W=0,w=_(0),D=_(0),E=_(0),Z=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0),U=_(0),M=0,S=0,X=0,T=_(0),j=_(0),O=_(0),H=_(0),z=_(0),P=0,K=0,L=0,q=_(0),$=_(0),AA=_(0);if(l=Y-32|0,Y=l,u=a[t+4>>2],(0|u)<=-1)for(a[t+8>>2]<=-1&&(s=a[t+12>>2],s&&(o[t+16|0]&&CA(s),a[t+12>>2]=0),f[t+16|0]=1,a[t+8>>2]=0,a[t+12>>2]=0),k=u<<4;v=a[l+20>>2],s=a[t+12>>2]+k|0,a[s>>2]=a[l+16>>2],a[s+4>>2]=v,d=l+24|0,v=a[d+4>>2],s=s+8|0,a[s>>2]=a[d>>2],a[s+4>>2]=v,k=k+16|0,s=u+1|0,d=s>>>0>=u>>>0,u=s,d;);if(s=0,a[t+4>>2]=0,d=a[i+4>>2],a[t+8>>2]<(0|d)){if(d&&(s=dA(d<<4),k=a[t+4>>2],!((0|k)<1)))for(u=0;v=a[t+12>>2]+u|0,S=a[v+4>>2],h=u+s|0,a[h>>2]=a[v>>2],a[h+4>>2]=S,v=v+8|0,M=a[v+4>>2],h=h+8|0,a[h>>2]=a[v>>2],a[h+4>>2]=M,u=u+16|0,k=k+-1|0,k;);u=a[t+12>>2],u&&(o[t+16|0]&&CA(u),a[t+12>>2]=0),a[t+12>>2]=s,f[t+16|0]=1,a[t+8>>2]=d}if(v=a[e+28>>2],!((0|v)<1)){for(u=a[e+36>>2]+20|0,p=C[r+40>>2],w=C[r+36>>2],Q=C[r+24>>2],D=C[r+20>>2],F=C[A+8>>2],E=C[A+4>>2],Z=C[A>>2],V=C[r+32>>2],N=C[r+16>>2],I=C[r+8>>2],J=C[r+4>>2],G=C[r>>2],k=0,R=_(3.4028234663852886e38),d=-1;m=C[u>>2],g=C[u+4>>2],y=C[u+8>>2],m=_(_(_(_(_(_(m*G)+_(g*J))+_(y*I))*Z)+_(_(_(_(m*N)+_(g*D))+_(y*Q))*E))+_(_(_(_(m*V)+_(g*w))+_(y*p))*F)),s=m>2]+B(d,36)|0,M=a[v+4>>2],(0|M)<1)s=i;else for(S=v+28|0,P=v+24|0,K=v+20|0,L=v+12|0,u=0;;){if(s=t,d=u+1|0,h=(0|d)==(0|M),W=a[e+16>>2],k=a[L>>2],t=W+(a[k+((h?0:d)<<2)>>2]<<4)|0,x=C[t+8>>2],G=C[t>>2],U=C[t+4>>2],t=W+(a[k+(u<<2)>>2]<<4)|0,R=C[t+8>>2],m=C[t>>2],g=C[t+4>>2],q=C[r+56>>2],$=C[r+48>>2],AA=C[r+52>>2],y=C[r+40>>2],p=C[r+32>>2],w=C[r+36>>2],Q=C[S>>2],D=C[r+8>>2],F=C[K>>2],E=C[r>>2],Z=C[P>>2],V=C[r+4>>2],N=C[r+24>>2],I=C[r+16>>2],J=C[r+20>>2],a[l+28>>2]=0,G=_(m-G),U=_(g-U),x=_(R-x),T=_(_(_(E*G)+_(V*U))+_(D*x)),j=_(_(_(I*F)+_(J*Z))+_(N*Q)),O=_(_(_(G*I)+_(U*J))+_(x*N)),H=_(_(_(E*F)+_(V*Z))+_(D*Q)),z=_(_(T*j)-_(O*H)),C[l+24>>2]=-z,G=_(_(_(G*p)+_(U*w))+_(x*y)),Q=_(_(_(p*F)+_(w*Z))+_(y*Q)),F=_(_(G*H)-_(T*Q)),C[l+20>>2]=-F,Q=_(-_(_(O*Q)-_(G*j))),C[l+16>>2]=Q,t=i,Tr(t,s,l+16|0,_(-_(_(_(_($+_(_(_(m*E)+_(g*V))+_(R*D)))*Q)-_(_(AA+_(_(_(m*I)+_(g*J))+_(R*N)))*F))-_(_(q+_(_(_(m*p)+_(g*w))+_(R*y)))*z)))),u=a[t+4>>2],(0|u)<=-1)for(a[t+8>>2]<=-1&&(i=a[t+12>>2],i&&(o[t+16|0]&&CA(i),a[t+12>>2]=0),f[t+16|0]=1,a[t+8>>2]=0,a[t+12>>2]=0),k=u<<4;X=a[l+4>>2],i=a[t+12>>2]+k|0,a[i>>2]=a[l>>2],a[i+4>>2]=X,W=l+8|0,X=a[W+4>>2],i=i+8|0,a[i>>2]=a[W>>2],a[i+4>>2]=X,k=k+16|0,i=u+1|0,W=i>>>0>=u>>>0,u=i,W;);if(a[t+4>>2]=0,u=d,i=s,h)break}if(i=a[s+4>>2],!((0|i)<1))for(R=C[v+20>>2],m=C[v+24>>2],g=C[v+28>>2],y=_(_(_(R*C[r>>2])+_(m*C[r+4>>2]))+_(g*C[r+8>>2])),p=_(_(_(R*C[r+16>>2])+_(m*C[r+20>>2]))+_(g*C[r+24>>2])),R=_(_(_(R*C[r+32>>2])+_(m*C[r+36>>2]))+_(g*C[r+40>>2])),m=_(C[v+32>>2]-_(_(_(y*C[r+48>>2])+_(p*C[r+52>>2]))+_(R*C[r+56>>2]))),k=0,d=0;e=a[s+12>>2]+k|0,r=e+8|0,g=_(m+_(_(_(y*C[e>>2])+_(p*C[e+4>>2]))+_(R*C[r>>2]))),g=g<=n?n:g,g<=c&&(t=a[r+4>>2],i=l+24|0,a[i>>2]=a[r>>2],a[i+4>>2]=t,r=a[e+4>>2],a[l+16>>2]=a[e>>2],a[l+20>>2]=r,Qt[a[a[b>>2]+16>>2]](b,A,l+16|0,g),i=a[s+4>>2]),k=k+16|0,d=d+1|0,(0|d)<(0|i););}}Y=l+32|0}function Hr(A,e,r,i){return a[A+12>>2]=r,a[A+8>>2]=e,a[A+4>>2]=i,a[A>>2]=15312,A}function zr(A,e,r,i,t,n){A|=0,e|=0,r|=0,i|=0,t|=0,n|=0;var c,l,u=0,s=0,v=_(0),d=_(0),g=0,B=_(0),m=0,R=_(0),Q=_(0),h=_(0),G=0,y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0);c=Y-288|0,Y=c,Yr(a[A+4>>2]),v=C[e+52>>2],d=C[r+52>>2],B=C[i+52>>2],R=C[t+52>>2],u=e+56|0,Q=C[u>>2],h=C[r+56>>2],g=i+56|0,y=C[g>>2],p=C[t+56>>2],F=C[e+48>>2],W=C[r+48>>2],w=C[i+48>>2],D=C[t+48>>2],f[c+264|0]=0,a[c+260>>2]=1566444395,a[c+224>>2]=15364,l=Mr(c+144|0,a[A+8>>2],a[A+12>>2],a[A+4>>2],0),s=e+8|0,m=a[s+4>>2],A=c+16|0,a[A>>2]=a[s>>2],a[A+4>>2]=m,s=e+24|0,m=a[s+4>>2],A=c+32|0,a[A>>2]=a[s>>2],a[A+4>>2]=m,s=e+40|0,m=a[s+4>>2],A=c+48|0,a[A>>2]=a[s>>2],a[A+4>>2]=m,s=a[u+4>>2],A=c- -64|0,a[A>>2]=a[u>>2],a[A+4>>2]=s,u=i+8|0,s=a[u+4>>2],A=c+80|0,a[A>>2]=a[u>>2],a[A+4>>2]=s,a[c+136>>2]=1566444395,A=a[e+4>>2],a[c+8>>2]=a[e>>2],a[c+12>>2]=A,A=a[e+20>>2],a[c+24>>2]=a[e+16>>2],a[c+28>>2]=A,A=a[e+36>>2],a[c+40>>2]=a[e+32>>2],a[c+44>>2]=A,A=a[e+52>>2],a[c+56>>2]=a[e+48>>2],a[c+60>>2]=A,A=a[i+4>>2],a[c+72>>2]=a[i>>2],a[c+76>>2]=A,u=i+24|0,s=a[u+4>>2],A=c+96|0,a[A>>2]=a[u>>2],a[A+4>>2]=s,u=a[i+20>>2],A=c+88|0,a[A>>2]=a[i+16>>2],a[A+4>>2]=u,u=i+40|0,s=a[u+4>>2],A=c+112|0,a[A>>2]=a[u>>2],a[A+4>>2]=s,u=a[i+36>>2],A=c+104|0,a[A>>2]=a[i+32>>2],a[A+4>>2]=u,u=a[g+4>>2],A=c+128|0,a[A>>2]=a[g>>2],a[A+4>>2]=u,u=a[i+52>>2],A=c+120|0,a[A>>2]=a[i+48>>2],a[A+4>>2]=u,Sr(l,c+8|0,c+224|0,0),u=c+252|0,g=a[u+4>>2],A=c+280|0,a[A>>2]=a[u>>2],a[A+4>>2]=g,A=a[c+248>>2],a[c+272>>2]=a[c+244>>2],a[c+276>>2]=A,u=0;A:if(o[c+264|0]){Q=_(_(h-Q)-_(p-y)),R=_(_(d-v)-_(R-B)),h=_(_(W-F)-_(D-w)),A=a[c+232>>2],s=a[c+236>>2],m=a[c+228>>2],B=C[c+260>>2];e:{if(B>_(.0010000000474974513)){for(g=c+244|0,G=33,d=_(0);;){if(G=G+-1|0,u=0,!G)break A;if(v=_(d-_(B/_(_(Q*(b(0,s),k()))+_(_(R*(b(0,A),k()))+_(h*(b(0,m),k())))))),u=0,v<=d)break A;if(u=0,v<_(0))break A;if(u=0,v>_(1))break A;if(Qt[a[a[n>>2]>>2]](n,v),d=_(_(1)-v),C[c+56>>2]=_(d*C[e+48>>2])+_(v*C[r+48>>2]),C[c+60>>2]=_(d*C[e+52>>2])+_(v*C[r+52>>2]),C[c+64>>2]=_(d*C[e+56>>2])+_(v*C[r+56>>2]),C[c+120>>2]=_(d*C[i+48>>2])+_(v*C[t+48>>2]),C[c+124>>2]=_(d*C[i+52>>2])+_(v*C[t+52>>2]),C[c+128>>2]=_(d*C[i+56>>2])+_(v*C[t+56>>2]),Sr(l,c+8|0,c+224|0,0),u=0,!o[c+264|0])break A;if(B=C[c+260>>2],B<_(0)){C[n+164>>2]=v,A=a[c+232>>2],a[n+132>>2]=a[c+228>>2],a[n+136>>2]=A,e=a[c+240>>2],A=n+140|0,a[A>>2]=a[c+236>>2],a[A+4>>2]=e,A=a[g+4>>2],a[n+148>>2]=a[g>>2],a[n+152>>2]=A,e=g+8|0,r=a[e+4>>2],A=n+156|0,a[A>>2]=a[e>>2],a[A+4>>2]=r;break e}if(u=g+8|0,s=a[u+4>>2],A=c+280|0,a[A>>2]=a[u>>2],a[A+4>>2]=s,A=a[g+4>>2],a[c+272>>2]=a[g>>2],a[c+276>>2]=A,m=a[c+228>>2],A=a[c+232>>2],s=a[c+236>>2],d=v,!(B>_(.0010000000474974513)))break}B=C[c+240>>2]}else v=_(0),B=C[c+240>>2];if(u=0,_(_(Q*(b(0,s),k()))+_(_(R*(b(0,A),k()))+_(h*(b(0,m),k()))))>=_(-C[n+172>>2]))break A;a[n+132>>2]=m,C[n+164>>2]=v,e=a[c+276>>2],a[n+148>>2]=a[c+272>>2],a[n+152>>2]=e,C[n+144>>2]=B,a[n+140>>2]=s,a[n+136>>2]=A,e=c+280|0,r=a[e+4>>2],A=n+156|0,a[A>>2]=a[e>>2],a[A+4>>2]=r}u=1}return Y=c+288|0,0|u}function Pr(A,e,r,i,f,t,n,o,c,b,l){var u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),p=_(0),F=_(0),W=_(0);o=(o<<2)+b|0,B=C[o>>2],R=_(C[b+48>>2]-C[c+48>>2]),G=C[o+16>>2],p=_(C[b+52>>2]-C[c+52>>2]),F=C[o+32>>2],W=_(C[b+56>>2]-C[c+56>>2]),k=_(_(_(B*R)+_(G*p))+_(F*W)),n=(n<<2)+c|0,Q=C[n>>2],v=C[n+16>>2],g=C[n+32>>2],h=_(_(_(Q*R)+_(v*p))+_(g*W)),d=_(_(_(Q*B)+_(v*G))+_(g*F)),s=_(_(1)-_(d*d)),s!=_(0)&&(s=_(_(h-_(d*k))/s),u=_(-r),sr&&(u=r))),s=_(_(d*u)-k),k=_(-f);A:{if(sr)){s=k,u=f;break A}f=k}else{if(!(s>f))break A;if(k=_(_(d*f)+h),u=_(-r),kr)){s=f,u=k;break A}}s=f,u=r}if(k=_(F*s),r=_(k+_(W-_(g*u))),d=_(B*s),f=_(d+_(R-_(Q*u))),h=_(G*s),s=_(h+_(p-_(v*u))),u=_(_(r*r)+_(_(f*f)+_(s*s))),B=_(y(u)),R=_(_(B-i)-t),!(R>l)){A:if(u<=_(1.4210854715202004e-14)){if(_(m(g))>_(.7071067690849304)){a[A>>2]=0,i=_(_(1)/_(y(_(_(v*v)+_(g*g))))),r=_(v*i),C[A+8>>2]=r,u=_(-_(g*i)),C[A+4>>2]=u,i=_(0);break A}a[A+8>>2]=0,r=_(_(1)/_(y(_(_(Q*Q)+_(v*v))))),u=_(Q*r),C[A+4>>2]=u,i=_(-_(v*r)),C[A>>2]=i,r=_(0)}else a[A+12>>2]=0,i=_(_(-1)/B),r=_(r*i),C[A+8>>2]=r,u=_(s*i),C[A+4>>2]=u,i=_(f*i),C[A>>2]=i;f=C[b+48>>2],l=C[b+52>>2],s=C[b+56>>2],a[e+12>>2]=0,C[e+8>>2]=_(k+s)+_(r*t),C[e+4>>2]=_(h+l)+_(u*t),C[e>>2]=_(d+f)+_(i*t)}return R}function Kr(A,e,r,i){i=_(i)}function Lr(A,e){return Qt[a[748]](e),A}function qr(){Qt[a[749]]()}function $r(A,e,r,i){return a[A+12>>2]=r,a[A+8>>2]=e,a[A+4>>2]=i,a[A>>2]=16060,A}function Ai(A,e,r,i,f,t){A|=0,e|=0,r|=0,i|=0,f|=0,t|=0;var n,o,c,b,l,u,s,k,v,d,g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),p=0,F=0,W=_(0),w=_(0),D=0,E=_(0),Z=_(0),V=_(0),N=0,I=_(0),J=_(0),x=_(0),U=_(0),M=_(0),S=_(0),X=_(0),T=_(0),j=_(0),O=_(0),H=_(0),z=_(0),P=_(0),K=_(0),L=_(0),q=_(0),$=_(0),AA=_(0),eA=_(0),rA=_(0),iA=_(0),fA=_(0),tA=_(0),nA=_(0),aA=_(0),oA=_(0),cA=0;n=Y-96|0,Y=n,Yr(a[A+4>>2]),p=i+40|0,$=C[p>>2],D=i+36|0,AA=C[D>>2],F=i+24|0,eA=C[F>>2],o=i+20|0,rA=C[o>>2],c=e+20|0,I=C[c>>2],b=e+36|0,J=C[b>>2],l=e+24|0,x=C[l>>2],u=e+52|0,U=C[u>>2],Q=C[r+52>>2],s=i+52|0,M=C[s>>2],h=C[f+52>>2],k=e+40|0,S=C[k>>2],v=e+56|0,X=C[v>>2],g=C[r+56>>2],d=i+56|0,T=C[d>>2],R=C[f+56>>2],iA=C[i+32>>2],fA=C[i+16>>2],tA=C[i+8>>2],nA=C[i+4>>2],aA=C[i>>2],j=C[e>>2],O=C[e+16>>2],H=C[e+32>>2],z=C[e+4>>2],P=C[e+8>>2],K=C[e+48>>2],B=C[r+48>>2],L=C[i+48>>2],m=C[f+48>>2],N=a[A+8>>2],a[n+60>>2]=0,E=_(_(B-K)-_(m-L)),B=_(-E),W=_(_(Q-U)-_(h-M)),w=_(_(g-X)-_(R-T)),C[n+56>>2]=_(_(P*B)-_(x*W))-_(S*w),C[n+52>>2]=_(_(z*B)-_(I*W))-_(J*w),C[n+48>>2]=_(_(j*B)-_(O*W))-_(H*w),Qt[a[a[N>>2]+64>>2]](n+80|0,N,n+48|0),a[n+76>>2]=0,B=C[n+80>>2],Q=C[n+84>>2],h=C[n+88>>2],C[n+72>>2]=_(_(_(B*C[e+32>>2])+_(Q*C[b>>2]))+_(h*C[k>>2]))+C[v>>2],C[n+68>>2]=_(_(_(B*C[e+16>>2])+_(Q*C[c>>2]))+_(h*C[l>>2]))+C[u>>2],C[n+64>>2]=_(_(_(B*C[e>>2])+_(Q*C[e+4>>2]))+_(h*C[e+8>>2]))+C[e+48>>2],N=a[A+12>>2],a[n+28>>2]=0,C[n+24>>2]=_(_(E*C[i+8>>2])+_(W*C[F>>2]))+_(w*C[p>>2]),C[n+20>>2]=_(_(E*C[i+4>>2])+_(W*C[o>>2]))+_(w*C[D>>2]),C[n+16>>2]=_(_(E*C[i>>2])+_(W*C[i+16>>2]))+_(w*C[i+32>>2]),Qt[a[a[N>>2]+64>>2]](n+32|0,N,n+16|0),a[n+60>>2]=0,B=C[n+32>>2],Q=C[n+36>>2],h=C[n+40>>2],m=_(_(_(_(B*C[i+32>>2])+_(Q*C[D>>2]))+_(h*C[p>>2]))+C[d>>2]),C[n+56>>2]=m,R=_(_(_(_(B*C[i>>2])+_(Q*C[i+4>>2]))+_(h*C[i+8>>2]))+C[i+48>>2]),C[n+48>>2]=R,B=_(_(_(_(B*C[i+16>>2])+_(Q*C[o>>2]))+_(h*C[F>>2]))+C[s>>2]),C[n+52>>2]=B,a[n+92>>2]=0,g=_(C[n+68>>2]-B),C[n+84>>2]=g,R=_(C[n+64>>2]-R),C[n+80>>2]=R,m=_(C[n+72>>2]-m),C[n+88>>2]=m,B=_(0),Q=_(0),h=_(0);A:{e:if(_(_(_(R*R)+_(g*g))+_(m*m))>_(9999999747378752e-20))for(p=-33;;){if(D=p+1|0,D>>>0

>>0)break e;if(F=a[A+8>>2],p=0,a[n+12>>2]=0,g=_(-C[n+80>>2]),R=C[n+84>>2],m=C[n+88>>2],C[n+8>>2]=_(_(P*g)-_(x*R))-_(S*m),C[n+4>>2]=_(_(z*g)-_(I*R))-_(J*m),C[n>>2]=_(_(j*g)-_(O*R))-_(H*m),Qt[a[a[F>>2]+64>>2]](n+16|0,F,n),a[n+76>>2]=0,g=C[n+16>>2],R=C[n+20>>2],m=C[n+24>>2],C[n+72>>2]=X+_(_(_(H*g)+_(J*R))+_(S*m)),C[n+68>>2]=U+_(_(_(O*g)+_(I*R))+_(x*m)),C[n+64>>2]=K+_(_(_(j*g)+_(z*R))+_(P*m)),F=a[A+12>>2],a[n+12>>2]=0,g=C[n+80>>2],R=C[n+84>>2],m=C[n+88>>2],C[n+8>>2]=_(_(tA*g)+_(eA*R))+_($*m),C[n+4>>2]=_(_(nA*g)+_(rA*R))+_(AA*m),C[n>>2]=_(_(aA*g)+_(fA*R))+_(iA*m),Qt[a[a[F>>2]+64>>2]](n+16|0,F,n),a[n+60>>2]=0,a[n+44>>2]=0,g=C[n+16>>2],R=C[n+20>>2],m=C[n+24>>2],Z=_(T+_(_(_(iA*g)+_(AA*R))+_($*m))),C[n+56>>2]=Z,Z=_(C[n+72>>2]-Z),C[n+40>>2]=Z,V=_(M+_(_(_(fA*g)+_(rA*R))+_(eA*m))),C[n+52>>2]=V,V=_(C[n+68>>2]-V),C[n+36>>2]=V,g=_(L+_(_(_(aA*g)+_(nA*R))+_(tA*m))),C[n+48>>2]=g,q=_(C[n+64>>2]-g),C[n+32>>2]=q,G>_(1))break A;if(g=C[n+80>>2],R=C[n+84>>2],m=C[n+88>>2],oA=_(_(_(q*g)+_(V*R))+_(Z*m)),oA>_(0)){if(B=_(_(_(E*g)+_(W*R))+_(w*m)),B>=_(-1.4210854715202004e-14))break A;a[n+44>>2]=0,C[n+40>>2]=Z,C[n+36>>2]=V,C[n+32>>2]=q,G=_(G-_(oA/B)),B=_(_(1)-G),T=_(_(B*C[i+56>>2])+_(G*C[f+56>>2])),M=_(_(B*C[i+52>>2])+_(G*C[f+52>>2])),L=_(_(B*C[i+48>>2])+_(G*C[f+48>>2])),X=_(_(B*C[e+56>>2])+_(G*C[r+56>>2])),U=_(_(B*C[e+52>>2])+_(G*C[r+52>>2])),K=_(_(B*C[e+48>>2])+_(G*C[r+48>>2])),cA=a[n+92>>2],Q=R,h=m,B=g}if(xr(a[A+4>>2],n+32|0)||Vr(a[A+4>>2],n+32|0,n- -64|0,n+48|0),!Jr(a[A+4>>2],n+80|0))break e;if(p=D,g=C[n+80>>2],m=_(g*g),g=C[n+84>>2],m=_(m+_(g*g)),g=C[n+88>>2],!(_(m+_(g*g))>_(9999999747378752e-20)))break}C[t+164>>2]=G,g=_(_(_(B*B)+_(Q*Q))+_(h*h)),g>=_(1.4210854715202004e-14)?(a[t+144>>2]=cA,m=h,h=_(_(1)/_(y(g))),G=_(m*h),C[t+140>>2]=G,Q=_(Q*h),C[t+136>>2]=Q,B=_(B*h),C[t+132>>2]=B):(a[t+132>>2]=0,a[t+136>>2]=0,e=t+140|0,a[e>>2]=0,a[e+4>>2]=0,G=_(0),Q=_(0),B=_(0)),p=0,_(_(_(E*B)+_(W*Q))+_(w*G))>=_(-C[t+172>>2])||(Ur(a[A+4>>2],n+16|0,n),e=n+8|0,r=a[e+4>>2],A=t+156|0,a[A>>2]=a[e>>2],a[A+4>>2]=r,A=a[n+4>>2],a[t+148>>2]=a[n>>2],a[t+152>>2]=A,p=1)}return Y=n+96|0,0|p}function ei(A,e,r,i,t){var n;vA(A,e),a[A>>2]=16120,a[A+8>>2]=16148,a[A+60>>2]=0,n=t?r:i,a[A+48>>2]=n,r=t?i:r,a[A+44>>2]=r,i=A+56|0,e=a[e>>2],a[i>>2]=e,e=0|Qt[a[a[e>>2]+12>>2]](e,a[r+8>>2],a[n+8>>2]),a[A+72>>2]=e,r=a[i>>2],Qt[a[a[r>>2]+20>>2]](r,e),f[A+76|0]=t}function ri(A,e,r,i,t){var n=0;vA(A,e),f[A+24|0]=1,a[A>>2]=16696,a[A+20>>2]=0,f[A+44|0]=1,n=A+12|0,a[n>>2]=0,a[n+4>>2]=0,a[A+40>>2]=0,f[A- -64|0]=1,n=A+32|0,a[n>>2]=0,a[n+4>>2]=0,a[A+60>>2]=0,f[A+68|0]=t,n=A+52|0,a[n>>2]=0,a[n+4>>2]=0,f[A+76|0]=0,a[A+72>>2]=a[e+4>>2],a[A+80>>2]=a[a[(t?i:r)+4>>2]+72>>2],ii(A,r,i)}function ii(A,e,r){var i,t,n,c,b,l=0,u=0,s=0,k=0;if(i=Y-32|0,Y=i,k=a[A+52>>2],b=o[A+68|0],n=b?r:e,c=a[n+4>>2],t=a[c+20>>2],(0|k)<(0|t)){if(a[A+56>>2]<(0|t)){if(t?(s=dA(t<<2),l=a[A+52>>2]):l=k,(0|l)>=1)for(;a[u+s>>2]=a[a[A+60>>2]+u>>2],u=u+4|0,l=l+-1|0,l;);l=a[A+60>>2],l&&(o[A- -64|0]&&CA(l),a[A+60>>2]=0),a[A+60>>2]=s,a[A+56>>2]=t,f[A- -64|0]=1}for(u=k<<2,l=t-k|0;a[a[A+60>>2]+u>>2]=0,u=u+4|0,l=l+-1|0,l;);}if(a[A+52>>2]=t,(0|t)>=1)for(e=b?e:r,l=64,u=0,s=0;a[c+68>>2]?a[a[A+60>>2]+u>>2]=0:(r=a[a[c+28>>2]+l>>2],a[i+28>>2]=s,a[i+24>>2]=-1,a[i+8>>2]=n,k=a[n+12>>2],a[i+16>>2]=a[n+8>>2],a[i+20>>2]=k,a[i+12>>2]=r,r=a[A+4>>2],r=0|Qt[a[a[r>>2]+8>>2]](r,i+8|0,e,a[A+72>>2],1),a[a[A+60>>2]+u>>2]=r),l=l+80|0,u=u+4|0,s=s+1|0,(0|s)!=(0|t););Y=i+32|0}function fi(A){A|=0;var e=0,r=0,i=0;if(a[A>>2]=16696,i=a[A+52>>2],(0|i)>=1)for(;r=a[a[A+60>>2]+e>>2],r&&(Qt[a[a[r>>2]>>2]](r),r=a[A+4>>2],Qt[a[a[r>>2]+60>>2]](r,a[a[A+60>>2]+e>>2])),e=e+4|0,i=i+-1|0,i;);return e=a[A+60>>2],e&&(o[A- -64|0]&&CA(e),a[A+60>>2]=0),a[A+60>>2]=0,a[A+52>>2]=0,a[A+56>>2]=0,f[A- -64|0]=1,e=a[A+40>>2],e&&(o[A+44|0]&&CA(e),a[A+40>>2]=0),a[A+40>>2]=0,a[A+32>>2]=0,a[A+36>>2]=0,f[A+44|0]=1,e=a[A+20>>2],e&&(o[A+24|0]&&CA(e),a[A+20>>2]=0),a[A+20>>2]=0,a[A+12>>2]=0,a[A+16>>2]=0,f[A+24|0]=1,0|A}function ti(A,e,r,i,t){A|=0,e|=0,r|=0,i|=0,t|=0;var n,c,b,l=0,u=0,s=0,k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=0,y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0),U=_(0),M=_(0),S=0,X=0,T=0,j=0;if(n=Y-176|0,Y=n,G=o[A+68|0],b=G?r:e,c=a[b+4>>2],a[c+72>>2]!=a[A+80>>2]){if(s=a[A+52>>2],(0|s)>=1)for(;u=a[a[A+60>>2]+l>>2],u&&(Qt[a[a[u>>2]>>2]](u),u=a[A+4>>2],Qt[a[a[u>>2]+60>>2]](u,a[a[A+60>>2]+l>>2])),l=l+4|0,s=s+-1|0,s;);ii(A,e,r),a[A+80>>2]=a[c+72>>2]}if(u=a[A+52>>2],u){if(s=a[c+68>>2],a[n+164>>2]=t,a[n+160>>2]=i,G=G?e:r,a[n+152>>2]=G,a[n+148>>2]=b,a[n+144>>2]=16768,a[n+172>>2]=a[A+72>>2],a[n+168>>2]=a[A+60>>2],a[n+156>>2]=a[A+4>>2],l=a[A+32>>2],(0|l)<=-1){for(a[A+36>>2]<=-1&&(e=a[A+40>>2],e&&(o[A+44|0]&&CA(e),a[A+40>>2]=0),a[A+36>>2]=0,a[A+40>>2]=0,f[A+44|0]=1),u=l<<2;a[a[A+40>>2]+u>>2]=0,u=u+4|0,e=l+1|0,r=e>>>0>=l>>>0,l=e,r;);u=a[A+52>>2]}if(a[A+32>>2]=0,(0|u)>=1)for(T=A+28|0,r=0;;){if(e=a[a[A+60>>2]+(r<<2)>>2],e){if(Qt[a[a[e>>2]+16>>2]](e,T),l=a[A+32>>2],(0|l)>=1)for(u=0,e=0;i=a[a[A+40>>2]+u>>2],a[i+780>>2]&&(a[t+4>>2]=i,S=a[i+772>>2],X=a[a[t+8>>2]+8>>2],l=(0|S)==(0|X),j=i,i=a[a[t+12>>2]+8>>2],se(j,(l?S:i)+4|0,(l?i:X)+4|0),a[t+4>>2]=0,l=a[A+32>>2]),u=u+4|0,e=e+1|0,(0|e)<(0|l););if((0|l)<=-1)for(a[A+36>>2]<=-1&&(e=a[A+40>>2],e&&(o[A+44|0]&&CA(e),a[A+40>>2]=0),f[A+44|0]=1,a[A+36>>2]=0,a[A+40>>2]=0),u=l<<2;a[a[A+40>>2]+u>>2]=0,u=u+4|0,e=l+1|0,i=e>>>0>=l>>>0,l=e,i;);a[A+32>>2]=0,u=a[A+52>>2]}if(r=r+1|0,!((0|r)<(0|u)))break}A:if(s)e=a[b+12>>2],y=C[e+52>>2],p=C[e+56>>2],r=a[G+12>>2],F=C[r+52>>2],W=C[r+56>>2],k=C[e+20>>2],v=C[e+36>>2],w=C[r+20>>2],D=C[r+36>>2],E=C[r+24>>2],d=C[e+24>>2],Z=C[r+40>>2],g=C[e+40>>2],V=C[r+32>>2],B=C[e+32>>2],N=C[r>>2],m=C[e>>2],I=C[r+16>>2],R=C[e+16>>2],J=C[e+48>>2],x=C[r+48>>2],Q=C[e+4>>2],U=C[r+4>>2],M=C[r+8>>2],h=C[e+8>>2],a[n+108>>2]=0,a[n+92>>2]=0,a[n+76>>2]=0,C[n+88>>2]=_(_(h*M)+_(d*E))+_(g*Z),C[n+84>>2]=_(_(h*U)+_(d*w))+_(g*D),C[n+72>>2]=_(_(Q*M)+_(k*E))+_(v*Z),C[n+68>>2]=_(_(Q*U)+_(k*w))+_(v*D),J=_(-J),C[n+104>>2]=_(_(_(h*J)-_(d*y))-_(g*p))+_(_(_(h*x)+_(d*F))+_(g*W)),C[n+100>>2]=_(_(_(Q*J)-_(k*y))-_(v*p))+_(_(_(Q*x)+_(k*F))+_(v*W)),a[n+60>>2]=0,C[n+48>>2]=_(_(m*N)+_(R*I))+_(B*V),C[n+80>>2]=_(_(h*N)+_(d*I))+_(g*V),C[n+64>>2]=_(_(Q*N)+_(k*I))+_(v*V),C[n+56>>2]=_(_(m*M)+_(R*E))+_(B*Z),C[n+52>>2]=_(_(m*U)+_(R*w))+_(B*D),C[n+96>>2]=_(_(_(m*J)-_(R*y))-_(B*p))+_(_(_(m*x)+_(R*F))+_(B*W)),e=a[G+4>>2],Qt[a[a[e>>2]+8>>2]](e,n+48|0,n+128|0,n+112|0),k=C[t+32>>2],C[n+128>>2]=C[n+128>>2]-k,C[n+132>>2]=C[n+132>>2]-k,C[n+136>>2]=C[n+136>>2]-k,C[n+112>>2]=k+C[n+112>>2],C[n+116>>2]=k+C[n+116>>2],C[n+120>>2]=k+C[n+120>>2],r=a[n+140>>2],e=n+24|0,a[e>>2]=a[n+136>>2],a[e+4>>2]=r,r=a[n+124>>2],e=n+40|0,a[e>>2]=a[n+120>>2],a[e+4>>2]=r,e=a[n+116>>2],a[n+32>>2]=a[n+112>>2],a[n+36>>2]=e,e=a[n+132>>2],a[n+16>>2]=a[n+128>>2],a[n+20>>2]=e,function(A,e,r,i){var t=0,n=0,c=0,b=0,l=0,u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0);if(A){if(u=C[e+24>>2],s=C[e+20>>2],n=a[r+8>>2],k=C[e+16>>2],v=C[e+8>>2],d=C[e+4>>2],g=C[e>>2],e=a[r+4>>2],(0|e)<=-1)for((0|n)<=-1&&(t=a[r+12>>2],t&&(o[r+16|0]&&CA(t),a[r+12>>2]=0),f[r+16|0]=1,a[r+8>>2]=0,a[r+12>>2]=0,n=0),t=e<<2;a[a[r+12>>2]+t>>2]=0,t=t+4|0,c=e+1|0,b=c>>>0>=e>>>0,e=c,b;);if(c=0,a[r+4>>2]=0,(0|n)<=63){if(n=dA(256),c=a[r+4>>2],(0|c)>=1)for(e=0,t=c;a[e+n>>2]=a[a[r+12>>2]+e>>2],e=e+4|0,t=t+-1|0,t;);e=a[r+12>>2],e&&(o[r+16|0]&&(CA(e),c=a[r+4>>2]),a[r+12>>2]=0),a[r+12>>2]=n,f[r+16|0]=1,a[r+8>>2]=64,n=64}if((0|n)==(0|c))if(l=n<<1,(0|n)>=(0|l))c=n;else{e=0;e:{if(n){if(b=dA(n<<3),c=a[r+4>>2],(0|c)<1)break e}else b=0,c=n;for(t=c;a[e+b>>2]=a[a[r+12>>2]+e>>2],e=e+4|0,t=t+-1|0,t;);}e=a[r+12>>2],e&&(o[r+16|0]&&(CA(e),c=a[r+4>>2]),a[r+12>>2]=0),a[r+12>>2]=b,f[r+16|0]=1,a[r+8>>2]=l}for(e=c+1|0,a[r+4>>2]=e,a[a[r+12>>2]+(c<<2)>>2]=A;;){if(t=e+-1|0,a[r+4>>2]=t,c=a[r+12>>2],b=a[c+(t<<2)>>2],C[b>>2]<=k)if(C[b+16>>2]>=g)if(C[b+4>>2]<=s)if(C[b+20>>2]>=d)if(C[b+8>>2]<=u)if(C[b+24>>2]>=v)if(a[b+40>>2]){if(l=a[b+36>>2],A=a[r+8>>2],(0|t)==(0|A))if(A=t?t<<1:1,(0|e)>(0|A))A=t;else{if(A?(c=dA(A<<2),t=a[r+4>>2]):c=0,(0|t)>=1)for(e=0,n=t;a[e+c>>2]=a[a[r+12>>2]+e>>2],e=e+4|0,n=n+-1|0,n;);e=a[r+12>>2],e&&(o[r+16|0]&&(CA(e),t=a[r+4>>2]),a[r+12>>2]=0),a[r+12>>2]=c,f[r+16|0]=1,a[r+8>>2]=A}if(n=t+1|0,a[r+4>>2]=n,a[(t<<2)+c>>2]=l,l=a[b+40>>2],(0|A)==(0|n))if(c=A?A<<1:1,(0|A)>=(0|c))n=A;else{if(c?(b=dA(c<<2),A=a[r+4>>2]):b=0,n=A,(0|n)>=1)for(e=0,t=n;a[e+b>>2]=a[a[r+12>>2]+e>>2],e=e+4|0,t=t+-1|0,t;);A=a[r+12>>2],A&&(o[r+16|0]&&(CA(A),n=a[r+4>>2]),a[r+12>>2]=0),a[r+12>>2]=b,f[r+16|0]=1,a[r+8>>2]=c}e=n+1|0,a[r+4>>2]=e,a[a[r+12>>2]+(n<<2)>>2]=l}else Qt[a[a[i>>2]+12>>2]](i,b),e=a[r+4>>2];else e=t;else e=t;else e=t;else e=t;else e=t;else e=t;if(!((0|e)>0))break}}}(a[s>>2],n+16|0,A+8|0,n+144|0);else{if((0|u)<1)break A;for(l=0,s=64;ni(n+144|0,a[a[c+28>>2]+s>>2],l),s=s+80|0,l=l+1|0,(0|u)!=(0|l););}if(e=a[A+52>>2],l=a[A+32>>2],(0|l)<=-1)for(a[A+36>>2]<=-1&&(r=a[A+40>>2],r&&(o[A+44|0]&&CA(r),a[A+40>>2]=0),a[A+36>>2]=0,a[A+40>>2]=0,f[A+44|0]=1),u=l<<2;a[a[A+40>>2]+u>>2]=0,u=u+4|0,r=l+1|0,i=r>>>0>=l>>>0,l=r,i;);if(a[A+32>>2]=0,!((0|e)<1))for(t=64,s=0;a[a[A+60>>2]+s>>2]&&(r=a[c+28>>2]+t|0,l=a[r>>2],i=a[b+12>>2],U=C[i+52>>2],M=C[i+56>>2],y=C[r+-16>>2],p=C[r+-12>>2],F=C[r+-8>>2],k=C[i+20>>2],v=C[i+24>>2],W=C[r+-64>>2],w=C[r+-48>>2],D=C[r+-32>>2],E=C[r+-60>>2],Z=C[r+-44>>2],V=C[r+-28>>2],N=C[r+-56>>2],d=C[i+36>>2],I=C[r+-40>>2],g=C[i+40>>2],x=C[r+-24>>2],J=C[i+48>>2],B=C[i+8>>2],m=C[i>>2],R=C[i+4>>2],Q=C[i+16>>2],h=C[i+32>>2],u=0,a[n+108>>2]=0,a[n+92>>2]=0,a[n+76>>2]=0,a[n+60>>2]=0,C[n+88>>2]=_(_(h*N)+_(d*I))+_(g*x),C[n+84>>2]=_(_(h*E)+_(d*Z))+_(g*V),C[n+80>>2]=_(_(h*W)+_(d*w))+_(g*D),C[n+72>>2]=_(_(Q*N)+_(k*I))+_(v*x),C[n+68>>2]=_(_(Q*E)+_(k*Z))+_(v*V),C[n+64>>2]=_(_(Q*W)+_(k*w))+_(v*D),C[n+56>>2]=_(_(m*N)+_(R*I))+_(B*x),C[n+52>>2]=_(_(m*E)+_(R*Z))+_(B*V),C[n+48>>2]=_(_(m*W)+_(R*w))+_(B*D),C[n+104>>2]=M+_(_(_(h*y)+_(d*p))+_(g*F)),C[n+100>>2]=U+_(_(_(Q*y)+_(k*p))+_(v*F)),C[n+96>>2]=J+_(_(_(m*y)+_(R*p))+_(B*F)),Qt[a[a[l>>2]+8>>2]](l,n+48|0,n+16|0,n+128|0),r=a[G+4>>2],Qt[a[a[r>>2]+8>>2]](r,a[G+12>>2],n+112|0,n),l=0,C[n+16>>2]>C[n>>2]||(l=0,C[n+128>>2]>2]||(l=1)),u=C[n+136>>2]>2]|C[n+24>>2]>C[n+8>>2]?u:l,(1^u||C[n+132>>2]>2]|C[n+20>>2]>C[n+4>>2])&&(r=a[a[A+60>>2]+s>>2],Qt[a[a[r>>2]>>2]](r),r=a[A+4>>2],Qt[a[a[r>>2]+60>>2]](r,a[a[A+60>>2]+s>>2]),a[a[A+60>>2]+s>>2]=0)),t=t+80|0,s=s+4|0,e=e+-1|0,e;);}Y=n+176|0}function ni(A,e,r){var i,f,t=0,n=0,o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0);i=Y-160|0,Y=i,t=a[A+4>>2],n=a[t+12>>2],m=C[n+52>>2],u=C[n+56>>2],o=C[n+24>>2],s=C[n+20>>2],c=C[n+40>>2],b=C[n+36>>2],t=a[a[t+4>>2]+28>>2],D=C[n+48>>2],k=C[n+8>>2],v=C[n>>2],d=C[n+4>>2],g=C[n+16>>2],l=C[n+32>>2],n=0,a[i+156>>2]=0,a[i+140>>2]=0,a[i+124>>2]=0,t=t+B(r,80)|0,R=C[t+8>>2],Q=C[t+24>>2],h=C[t+40>>2],C[i+136>>2]=_(_(l*R)+_(b*Q))+_(c*h),G=C[t+4>>2],y=C[t+20>>2],p=C[t+36>>2],C[i+132>>2]=_(_(l*G)+_(b*y))+_(c*p),C[i+120>>2]=_(_(g*R)+_(s*Q))+_(o*h),C[i+116>>2]=_(_(g*G)+_(s*y))+_(o*p),F=u,u=C[t+48>>2],W=C[t+52>>2],w=C[t+56>>2],C[i+152>>2]=F+_(_(_(l*u)+_(b*W))+_(c*w)),C[i+148>>2]=m+_(_(_(g*u)+_(s*W))+_(o*w)),a[i+108>>2]=0,F=l,l=C[t>>2],m=b,b=C[t+16>>2],E=c,c=C[t+32>>2],C[i+128>>2]=_(_(F*l)+_(m*b))+_(E*c),C[i+112>>2]=_(_(g*l)+_(s*b))+_(o*c),C[i+96>>2]=_(_(v*l)+_(d*b))+_(k*c),C[i+104>>2]=_(_(v*R)+_(d*Q))+_(k*h),C[i+100>>2]=_(_(v*G)+_(d*y))+_(k*p),C[i+144>>2]=D+_(_(_(v*u)+_(d*W))+_(k*w)),Qt[a[a[e>>2]+8>>2]](e,i+96|0,i+80|0,i- -64|0),o=C[a[A+20>>2]+32>>2],C[i+80>>2]=C[i+80>>2]-o,C[i+84>>2]=C[i+84>>2]-o,C[i+88>>2]=C[i+88>>2]-o,C[i+64>>2]=o+C[i+64>>2],C[i+68>>2]=o+C[i+68>>2],C[i+72>>2]=o+C[i+72>>2],t=a[A+8>>2],f=a[t+4>>2],Qt[a[a[f>>2]+8>>2]](f,a[t+12>>2],i+48|0,i+32|0),t=a[689],t&&!Qt[t](a[a[A+8>>2]+4>>2],e)||(n=C[i+64>>2]>2]|C[i+80>>2]>C[i+32>>2]?n:1,t=0,t=C[i+72>>2]>2]|C[i+88>>2]>C[i+40>>2]?t:n,C[i+68>>2]>2]|C[i+84>>2]>C[i+36>>2]|1^t||(a[i+28>>2]=r,a[i+24>>2]=-1,a[i+12>>2]=e,e=a[A+4>>2],a[i+8>>2]=e,a[i+16>>2]=a[e+8>>2],o=C[a[A+20>>2]+32>>2],a[i+20>>2]=i+96,o>_(0)?(e=a[A+12>>2],e=0|Qt[a[a[e>>2]+8>>2]](e,i+8|0,a[A+8>>2],0,2)):(n=r<<2,e=a[n+a[A+24>>2]>>2],e||(e=a[A+12>>2],e=0|Qt[a[a[e>>2]+8>>2]](e,i+8|0,a[A+8>>2],a[A+28>>2],1),a[n+a[A+24>>2]>>2]=e,e=a[n+a[A+24>>2]>>2])),n=a[A+20>>2],t=a[n+8>>2],a[t+8>>2]!=a[a[A+4>>2]+8>>2]?(t=a[n+12>>2],a[n+12>>2]=i+8,Qt[a[a[n>>2]+12>>2]](n,-1,r)):(a[n+8>>2]=i+8,Qt[a[a[n>>2]+8>>2]](n,-1,r)),Qt[a[a[e>>2]+8>>2]](e,i+8|0,a[A+8>>2],a[A+16>>2],a[A+20>>2]),e=a[A+20>>2],a[(a[a[e+8>>2]+8>>2]==a[a[A+4>>2]+8>>2]?8:12)+e>>2]=t)),Y=i+160|0}function ai(A){var e,r,i=0,t=0,n=0,c=0,b=0,l=0,u=0;if(r=a[A+28>>2],e=a[A+12>>2],!((0|r)>=(0|e))){A:if(a[A+32>>2]>=(0|e))n=a[A+36>>2];else{if(e?(n=dA(e<<2),t=a[A+28>>2]):t=r,i=a[A+36>>2],(0|t)>=1)for(c=n,b=i;a[c>>2]=a[b>>2],c=c+4|0,b=b+4|0,t=t+-1|0,t;);else if(!i){a[A+36>>2]=n,a[A+32>>2]=e,f[A+40|0]=1;break A}o[A+40|0]&&CA(i),a[A+36>>2]=n,f[A+40|0]=1,a[A+32>>2]=e}if(t=r<<2,l=e<<2,X(t+n|0,0,l-t|0),a[A+28>>2]=e,u=a[A+48>>2],(0|u)<(0|e)){A:if(a[A+52>>2]>=(0|e))n=a[A+56>>2];else{if(e?(n=dA(l),t=a[A+48>>2]):(n=0,t=u),i=a[A+56>>2],(0|t)>=1)for(c=n,b=i;a[c>>2]=a[b>>2],c=c+4|0,b=b+4|0,t=t+-1|0,t;);else if(!i){a[A+56>>2]=n,a[A+52>>2]=e,f[A+60|0]=1;break A}o[A+60|0]&&CA(i),a[A+56>>2]=n,f[A+60|0]=1,a[A+52>>2]=e}t=u<<2,X(t+n|0,0,l-t|0)}if(a[A+48>>2]=e,(0|e)>=1&&(X(a[A+36>>2],255,l),X(a[A+56>>2],255,l)),!((0|r)<1))for(b=a[A+56>>2],c=a[A+16>>2],n=a[A+36>>2],t=0;i=a[c>>2]|a[c+4>>2]<<16,i=(i<<15^-1)+i|0,i=B(i>>>10^i,9),i^=i>>>6,i=(i<<11^-1)+i|0,i=n+((a[A+12>>2]+-1&(i>>>16^i))<<2)|0,a[b>>2]=a[i>>2],a[i>>2]=t,c=c+12|0,b=b+4|0,t=t+1|0,(0|t)!=(0|r););}}function oi(A){var e=0,r=0,i=0,t=0,n=0,c=0;if(e=a[A+16>>2],e&&(o[A+20|0]&&CA(e),a[A+16>>2]=0),a[A+16>>2]=0,a[A+8>>2]=0,a[A+12>>2]=0,f[A+20|0]=1,e=a[A+36>>2],e&&(o[A+40|0]&&CA(e),a[A+36>>2]=0),a[A+36>>2]=0,a[A+28>>2]=0,a[A+32>>2]=0,f[A+40|0]=1,e=a[A+56>>2],e&&(o[A+60|0]&&CA(e),a[A+56>>2]=0),a[A+56>>2]=0,a[A+48>>2]=0,a[A+52>>2]=0,f[A+60|0]=1,a[A+12>>2]<=1){if(n=dA(24),r=a[A+8>>2],(0|r)>=1)for(e=0;i=a[A+16>>2]+e|0,c=a[i+4>>2],t=e+n|0,a[t>>2]=a[i>>2],a[t+4>>2]=c,a[t+8>>2]=a[i+8>>2],e=e+12|0,r=r+-1|0,r;);e=a[A+16>>2],e&&(o[A+20|0]&&CA(e),a[A+16>>2]=0),a[A+16>>2]=n,f[A+20|0]=1,a[A+12>>2]=2}ai(A)}function ci(A){return A|=0,a[A+16>>2]}function bi(A,e,r,i){ri(A,e,r,i,0),f[A+104|0]=1,a[A>>2]=16908,a[A+100>>2]=0,e=A+92|0,a[e>>2]=0,a[e+4>>2]=0,e=dA(64),function(A){var e=0,r=0,i=0,t=0,n=0,c=0;if(a[A>>2]=16844,f[A+20|0]=1,a[A+16>>2]=0,f[A+40|0]=1,r=A+8|0,e=r,a[e>>2]=0,a[e+4>>2]=0,a[A+36>>2]=0,f[A+60|0]=1,e=A+28|0,a[e>>2]=0,a[e+4>>2]=0,a[A+56>>2]=0,e=A+48|0,a[e>>2]=0,a[e+4>>2]=0,e=dA(24),r=a[r>>2],(0|r)>=1)for(;t=a[A+16>>2]+i|0,c=a[t+4>>2],n=e+i|0,a[n>>2]=a[t>>2],a[n+4>>2]=c,a[n+8>>2]=a[t+8>>2],i=i+12|0,r=r+-1|0,r;);i=a[A+16>>2],i&&(o[A+20|0]&&CA(i),a[A+16>>2]=0),a[A+16>>2]=e,f[A+20|0]=1,a[A+12>>2]=2,ai(A)}(e),a[A+84>>2]=e,a[A+108>>2]=a[a[r+4>>2]+72>>2],a[A+112>>2]=a[a[i+4>>2]+72>>2]}function li(A){A|=0;var e=0,r=0,i=0,t=0,n=0;if(a[A>>2]=16908,e=8,r=a[A+84>>2],i=a[r+8>>2],(0|i)>=1){for(;t=a[a[r+16>>2]+e>>2],t&&(Qt[a[a[t>>2]>>2]](t),n=a[A+4>>2],Qt[a[a[n>>2]+60>>2]](n,t)),e=e+12|0,i=i+-1|0,i;);r=a[A+84>>2]}return oi(r),e=a[A+84>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+84>>2]),e=a[A+100>>2],e&&(o[A+104|0]&&CA(e),a[A+100>>2]=0),a[A+100>>2]=0,a[A+92>>2]=0,a[A+96>>2]=0,f[A+104|0]=1,fi(A),0|A}function ui(A,e){A|=0,e|=0;var r=0,i=0,t=0,n=0,c=0;if(i=a[A+12>>2],!(!i|!o[A+8|0])){if(r=a[e+4>>2],(0|r)==a[e+8>>2]&&(n=r?r<<1:1,!((0|r)>=(0|n)))){if(n&&(c=dA(n<<2),r=a[e+4>>2]),(0|r)>=1)for(i=0,t=r;a[i+c>>2]=a[a[e+12>>2]+i>>2],i=i+4|0,t=t+-1|0,t;);t=a[e+12>>2],t&&(o[e+16|0]&&(CA(t),r=a[e+4>>2]),a[e+12>>2]=0),a[e+12>>2]=c,f[e+16|0]=1,a[e+8>>2]=n,i=a[A+12>>2]}a[e+4>>2]=r+1,a[a[e+12>>2]+(r<<2)>>2]=i}}function si(A,e,r,i,f){A|=0,e|=0,r|=0,i|=0,f|=0;var t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0);i=Y-144|0,Y=i,a[i+108>>2]=0,t=C[e+80>>2],n=C[e+96>>2],B=C[e+120>>2],w=C[e+56>>2],h=C[e+112>>2],G=C[e+116>>2],D=C[e+52>>2],o=C[e+68>>2],b=C[e+84>>2],l=C[e+100>>2],c=C[e+20>>2],d=C[e+36>>2],u=C[e+72>>2],s=C[e+88>>2],g=C[e+24>>2],k=C[e+104>>2],m=C[e+40>>2],v=C[e+64>>2],R=C[e+32>>2],Q=C[e>>2],p=C[e+16>>2],E=C[e+48>>2],F=C[e+4>>2],W=C[e+8>>2],a[i+100>>2]=0,a[i+84>>2]=0,a[i+68>>2]=0,C[i+80>>2]=_(_(W*u)+_(g*s))+_(m*k),C[i+76>>2]=_(_(F*u)+_(c*s))+_(d*k),C[i- -64>>2]=_(_(W*o)+_(g*b))+_(m*l),C[i+60>>2]=_(_(F*o)+_(c*b))+_(d*l),h=_(E-h),G=_(D-G),B=_(w-B),C[i+96>>2]=_(_(u*h)+_(s*G))+_(k*B),C[i+92>>2]=_(_(h*o)+_(G*b))+_(B*l),a[i+52>>2]=0,C[i+72>>2]=_(_(Q*u)+_(p*s))+_(R*k),C[i+56>>2]=_(_(Q*o)+_(p*b))+_(R*l),C[i+48>>2]=_(_(v*W)+_(t*g))+_(n*m),C[i+44>>2]=_(_(v*F)+_(t*c))+_(n*d),C[i+40>>2]=_(_(v*Q)+_(t*p))+_(n*R),C[i+88>>2]=_(_(h*v)+_(G*t))+_(B*n),function(A,e,r,i,f,t){var n=_(0),o=_(0),c=_(0),b=0,l=0,u=_(0),s=_(0),k=0,v=_(0),d=_(0),g=_(0),B=_(0),m=0,R=_(0),Q=_(0),h=_(0),G=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=0;b=Y-32|0,Y=b,l=a[A+8>>2],o=C[l+60>>2],n=_(C[l+76>>2]-o),d=C[l- -64>>2],c=_(C[l+96>>2]-d),u=_(C[l+80>>2]-d),v=_(C[l+92>>2]-o),g=_(_(n*c)-_(u*v)),R=u,B=C[l+68>>2],u=_(C[l+100>>2]-B),s=_(C[l+84>>2]-B),c=_(_(R*u)-_(s*c)),v=_(_(s*v)-_(n*u)),u=_(_(g*g)+_(_(c*c)+_(v*v)));A:if(u>=_(1.4210854715202004e-14)&&(m=a[A+4>>2],R=_(C[m+32>>2]*C[m+16>>2]),n=_(R+t),t=_(_(1)/_(y(u))),u=_(c*t),c=C[e>>2],v=_(v*t),s=C[e+4>>2],Q=_(_(u*_(c-o))+_(v*_(s-d))),d=_(g*t),o=C[e+8>>2],t=_(Q+_(d*_(o-B))),t<_(0)&&(d=_(-d),v=_(-v),u=_(-u),t=_(-t)),t>2],E=b+24|0,a[E>>2]=a[k>>2],a[E+4>>2]=m,k=a[e+4>>2],a[b+16>>2]=a[e>>2],a[b+20>>2]=k,k=0,a[b+12>>2]=0,C[b+8>>2]=d,C[b+4>>2]=v,C[b>>2]=u,function(A,e,r){var i=_(0),f=_(0),t=_(0),n=_(0),a=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0);return b=C[A+40>>2],o=C[A+24>>2],s=_(b-o),l=C[r+8>>2],v=C[A+32>>2],f=C[A+16>>2],a=_(v-f),t=C[e+4>>2],d=C[A+36>>2],c=C[A+20>>2],n=_(d-c),u=C[e>>2],k=_(_(l-o)*_(_(a*t)-_(n*u))),g=C[r>>2],i=n,n=C[e+8>>2],B=C[r+4>>2],s=_(k+_(_(_(g-f)*_(_(i*n)-_(s*t)))+_(_(B-c)*_(_(s*u)-_(a*n))))),i=o,o=C[A+8>>2],a=_(i-o),i=f,f=C[A>>2],k=_(i-f),i=c,c=C[A+4>>2],i=_(i-c),a=_(_(_(l-o)*_(_(k*t)-_(i*u)))+_(_(_(g-f)*_(_(i*n)-_(a*t)))+_(_(B-c)*_(_(a*u)-_(k*n))))),A=1,i=_(l-b),l=_(f-v),f=_(c-d),b=_(o-b),t=_(_(i*_(_(l*t)-_(f*u)))+_(_(_(g-v)*_(_(f*n)-_(b*t)))+_(_(B-d)*_(_(b*u)-_(l*n))))),(!(s>_(0))||t>_(0)^1|a>_(0)^1)&&(A=a<=_(0)&s<=_(0)&t<=_(0)),A}(l+60|0,b,b+16|0))h=_(o-_(t*d)),G=_(s-_(t*v)),p=_(c-_(t*u)),Q=_(n*n);else{if((0|Qt[a[a[l>>2]+100>>2]](l))<1)break A;for(Q=_(n*n),m=0,l=0;k=a[A+8>>2],Qt[a[a[k>>2]+104>>2]](k,l,b+16|0,b),n=_(0),F=C[b+16>>2],t=_(C[e>>2]-F),s=_(C[b>>2]-F),W=C[b+20>>2],o=_(C[e+4>>2]-W),g=_(C[b+4>>2]-W),w=C[b+24>>2],c=_(C[e+8>>2]-w),B=_(C[b+8>>2]-w),D=_(_(_(t*s)+_(o*g))+_(c*B)),D>_(0)&&(n=_(_(_(s*s)+_(g*g))+_(B*B)),D>2],(0|l)<(0|Qt[a[a[k>>2]+100>>2]](k)););if(k=0,!m)break A;o=C[e+8>>2],s=C[e+4>>2],c=C[e>>2]}t=_(c-p),c=_(s-G),o=_(o-h),n=_(_(_(t*t)+_(c*c))+_(o*o)),n_(1.1920928955078125e-7)?(u=o,n=_(y(n)),o=_(_(1)/n),C[i+8>>2]=u*o,C[i+4>>2]=c*o,C[i>>2]=t*o,R=_(R-n)):(C[i+8>>2]=d,C[i+4>>2]=v,C[i>>2]=u),a[i+12>>2]=0,a[r+12>>2]=0,C[r+8>>2]=h,C[r+4>>2]=G,C[r>>2]=p,C[f>>2]=-R,k=1)}return Y=b+32|0,k}(A,i+88|0,i+128|0,i+112|0,i+108|0,C[A+12>>2])&&(f?(b=C[e+72>>2],l=C[e+64>>2],u=C[e+68>>2],s=C[e+88>>2],k=C[e+80>>2],v=C[e+84>>2],c=C[e+104>>2],d=C[e+96>>2],g=C[e+100>>2],t=C[i+120>>2],n=C[i+112>>2],o=C[i+116>>2],a[i+36>>2]=0,m=_(_(_(n*d)+_(o*g))+_(t*c)),C[i+32>>2]=-m,R=_(_(_(n*k)+_(o*v))+_(t*s)),C[i+28>>2]=-R,Q=_(_(_(l*n)+_(u*o))+_(b*t)),C[i+24>>2]=-Q,a[i+20>>2]=0,n=C[i+128>>2],o=C[i+132>>2],B=c,c=C[i+136>>2],t=C[i+108>>2],C[i+16>>2]=_(_(_(_(d*n)+_(g*o))+_(B*c))+C[e+120>>2])+_(m*t),C[i+12>>2]=_(_(_(_(n*k)+_(o*v))+_(c*s))+C[e+116>>2])+_(R*t),C[i+8>>2]=_(_(_(_(n*l)+_(o*u))+_(c*b))+C[e+112>>2])+_(Q*t),Qt[a[a[r>>2]+16>>2]](r,i+24|0,i+8|0,t)):(a[i+36>>2]=0,t=C[i+112>>2],b=C[e+96>>2],n=C[i+116>>2],l=C[e+100>>2],o=C[i+120>>2],u=C[e+104>>2],C[i+32>>2]=_(_(t*b)+_(n*l))+_(o*u),s=C[e+80>>2],k=C[e+84>>2],v=C[e+88>>2],C[i+28>>2]=_(_(t*s)+_(n*k))+_(o*v),c=C[e+64>>2],d=C[e+68>>2],g=C[e+72>>2],C[i+24>>2]=_(_(t*c)+_(n*d))+_(o*g),a[i+20>>2]=0,t=C[i+128>>2],n=C[i+132>>2],o=C[i+136>>2],C[i+16>>2]=_(_(_(b*t)+_(l*n))+_(u*o))+C[e+120>>2],C[i+12>>2]=_(_(_(t*s)+_(n*k))+_(o*v))+C[e+116>>2],C[i+8>>2]=_(_(_(t*c)+_(n*d))+_(o*g))+C[e+112>>2],Qt[a[a[r>>2]+16>>2]](r,i+24|0,i+8|0,C[i+108>>2]))),Y=i+144|0}function ki(A){var e,r=0,i=_(0),f=0,t=_(0),n=_(0);s(A),r=c(0),e=r>>>31,r&=2147483647;A:{if(r>>>0>=1283457024){if(A!=A)break A;return _(e?-1.570796251296997:1.570796251296997)}e:{if(r>>>0<=1054867455){if(f=-1,r>>>0>=964689920)break e;break A}if(A=_(m(A)),r>>>0<=1066926079){if(r>>>0<=1060110335){A=_(_(_(A+A)+_(-1))/_(A+_(2))),f=0;break e}A=_(_(A+_(-1))/_(A+_(1))),f=1}else r>>>0<=1075576831?(A=_(_(A+_(-1.5))/_(_(A*_(1.5))+_(1))),f=2):(A=_(_(-1)/A),f=3)}if(r=f,t=_(A*A),i=_(t*t),n=_(i*_(_(i*_(-.106480173766613))+_(-.19999158382415771))),i=_(t*_(_(i*_(_(i*_(.06168760731816292))+_(.14253635704517365)))+_(.333333283662796))),(0|r)<=-1)return _(A-_(A*_(n+i)));r<<=2,A=_(C[r+17392>>2]-_(_(_(A*_(n+i))-C[r+17408>>2])-A)),A=e?_(-A):A}return A}function vi(A,e){var r,i,f,t=0,n=0,a=_(0);if(!(e==e&A==A))return _(A+e);if(s(e),t=c(0),1065353216==(0|t))return ki(A);f=t>>>30&2,s(A),n=c(0),i=n>>>31,r=f|i;A:{e:{r:{if(n&=2147483647,!n){i:switch(r-2|0){case 0:break r;case 1:break i;default:break e}return _(-3.1415927410125732)}if(t&=2147483647,2139095040!=(0|t)){if(!t)return _(i?-1.5707963705062866:1.5707963705062866);if(!(t+218103808>>>0>=n>>>0&&2139095040!=(0|n)))return _(i?-1.5707963705062866:1.5707963705062866);if(n+218103808>>>0>>0&&(a=_(0),f)||(a=ki(_(m(_(A/e))))),e=a,r>>>0<=2){A=e;i:switch(r-1|0){case 0:return _(-e);case 1:break i;default:break e}return _(_(3.1415927410125732)-_(e+_(8.742277657347586e-8)))}return _(_(e+_(8.742277657347586e-8))+_(-3.1415927410125732))}if(2139095040==(0|n))break A;return C[17440+(r<<2)>>2]}A=_(3.1415927410125732)}return A}return C[17424+(r<<2)>>2]}function di(A,e,r,i,f,t,n,o,c,b){var l,u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),R=_(0),Q=0,h=_(0),G=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),V=_(0),N=_(0),I=_(0),x=0,U=_(0),M=_(0),S=_(0),X=_(0),T=0,j=_(0),O=_(0),H=_(0),z=_(0),P=_(0),K=_(0),L=_(0),q=_(0),$=_(0),AA=_(0),eA=_(0),rA=_(0),iA=_(0),fA=_(0),tA=_(0),nA=_(0),aA=_(0),oA=_(0),cA=_(0),bA=_(0),lA=_(0),uA=0,sA=0,kA=0,vA=0,dA=0,CA=0,gA=0;l=Y-368|0,Y=l,z=_(C[r>>2]*_(.5)),C[l+356>>2]=z,U=C[e+36>>2],uA=e+4|0,M=C[uA>>2],W=C[e+20>>2],AA=C[e+40>>2],T=e+8|0,eA=C[T>>2],S=C[e+24>>2],R=C[e+16>>2],G=C[e+32>>2],g=C[A>>2],h=C[i>>2],v=C[A+4>>2],s=C[i+4>>2],u=C[A+8>>2],k=C[i+8>>2],lA=C[e>>2],P=_(C[r+4>>2]*_(.5)),C[l+360>>2]=P,O=_(C[r+8>>2]*_(.5)),C[l+364>>2]=O,H=_(C[t>>2]*_(.5)),C[l+344>>2]=H,K=_(C[t+4>>2]*_(.5)),C[l+348>>2]=K,L=_(C[t+8>>2]*_(.5)),C[l+352>>2]=L,d=_(h-g),p=_(s-v),E=_(k-u),rA=_(_(_(lA*d)+_(R*p))+_(G*E)),j=C[f>>2],q=C[f+16>>2],s=C[f+32>>2],fA=_(_(_(lA*j)+_(R*q))+_(G*s)),g=_(m(fA)),$=C[f+4>>2],Z=C[f+20>>2],V=C[f+36>>2],tA=_(_(_(lA*$)+_(R*Z))+_(G*V)),h=_(m(tA)),N=C[f+8>>2],F=C[f+24>>2],D=C[f+40>>2],nA=_(_(_(lA*N)+_(R*F))+_(G*D)),v=_(m(nA)),u=_(_(m(rA))-_(_(_(z+_(H*g))+_(K*h))+_(L*v)));A:if(!(u>_(0)||(aA=_(_(_(M*N)+_(W*F))+_(U*D)),X=_(m(aA)),oA=_(_(_(M*$)+_(W*Z))+_(U*V)),I=_(m(oA)),cA=_(_(_(M*j)+_(W*q))+_(U*s)),w=_(m(cA)),k=_(-3.4028234663852886e38),r=0,u>_(-3.4028234663852886e38)&&(x=rA<_(0),k=u,Q=e,r=1),iA=_(_(_(d*M)+_(p*W))+_(E*U)),u=_(_(m(iA))-_(_(_(P+_(H*w))+_(K*I))+_(L*X))),u>_(0)||(bA=_(_(_(eA*N)+_(S*F))+_(AA*D)),W=_(m(bA)),U=_(_(_(eA*$)+_(S*Z))+_(AA*V)),R=_(m(U)),M=_(_(_(eA*j)+_(S*q))+_(AA*s)),G=_(m(M)),u>k&&(x=iA<_(0),k=u,Q=uA,r=2),S=_(_(_(d*eA)+_(p*S))+_(E*AA)),u=_(_(m(S))-_(_(_(O+_(H*G))+_(K*R))+_(L*W))),u>_(0)||(u>k&&(x=S<_(0),k=u,Q=T,r=3),s=_(_(_(d*j)+_(p*q))+_(E*s)),u=_(_(m(s))-_(H+_(_(O*G)+_(_(z*g)+_(P*w))))),u>_(0)||(u>k&&(x=s<_(0),k=u,Q=f,r=4),s=_(_(_(d*$)+_(p*Z))+_(E*V)),u=_(_(m(s))-_(K+_(_(O*R)+_(_(z*h)+_(P*I))))),u>_(0)||(u>k&&(Q=f+4|0,x=s<_(0),k=u,r=5),s=_(_(_(d*N)+_(p*F))+_(E*D)),u=_(_(m(s))-_(L+_(_(O*W)+_(_(z*v)+_(P*X))))),u>_(0)||(u>k&&(Q=f+8|0,x=s<_(0),k=u,r=6),s=_(_(S*cA)-_(iA*M)),V=_(h+_(9999999747378752e-21)),N=_(G+_(9999999747378752e-21)),F=_(w+_(9999999747378752e-21)),D=_(v+_(9999999747378752e-21)),u=_(_(m(s))-_(_(L*V)+_(_(_(P*N)+_(O*F))+_(K*D)))),u>_(1.1920928955078125e-7)||(j=_(R+_(9999999747378752e-21)),q=_(I+_(9999999747378752e-21)),$=_(g+_(9999999747378752e-21)),E=_(0),w=_(cA*cA),h=_(_(M*M)+_(0)),v=_(y(_(w+h))),v>_(1.1920928955078125e-7)?(p=_(0),u=_(u/v),d=_(0),_(u*_(1.0499999523162842))>k&&(x=s<_(0),p=_(cA/v),E=_(_(0)/v),Q=0,r=7,k=u,d=_(_(-M)/v))):(p=_(0),d=_(0)),s=_(_(S*oA)-_(iA*U)),u=_(_(m(s))-_(_(L*$)+_(_(_(P*j)+_(O*q))+_(H*D)))),u>_(1.1920928955078125e-7)||(Z=_(W+_(9999999747378752e-21)),I=_(X+_(9999999747378752e-21)),W=_(oA*oA),v=_(_(U*U)+_(0)),g=_(y(_(W+v))),g>_(1.1920928955078125e-7)&&(u=_(u/g),_(u*_(1.0499999523162842))>k&&(x=s<_(0),p=_(oA/g),d=_(_(-U)/g),E=_(_(0)/g),Q=0,r=8,k=u)),s=_(_(S*aA)-_(iA*bA)),u=_(_(m(s))-_(_(K*$)+_(_(H*V)+_(_(P*Z)+_(O*I))))),u>_(1.1920928955078125e-7)||(R=_(aA*aA),G=_(_(bA*bA)+_(0)),g=_(y(_(R+G))),g>_(1.1920928955078125e-7)&&(u=_(u/g),_(u*_(1.0499999523162842))>k&&(x=s<_(0),p=_(aA/g),d=_(_(-bA)/g),E=_(_(0)/g),Q=0,r=9,k=u)),s=_(_(rA*M)-_(S*fA)),u=_(_(m(s))-_(_(L*q)+_(_(_(z*N)+_(O*$))+_(K*I)))),u>_(1.1920928955078125e-7)||(g=_(fA*fA),h=_(y(_(g+h))),h>_(1.1920928955078125e-7)&&(u=_(u/h),_(u*_(1.0499999523162842))>k&&(x=s<_(0),p=_(_(-fA)/h),d=_(_(0)/h),E=_(M/h),Q=0,r=10,k=u)),s=_(_(rA*U)-_(S*tA)),u=_(_(m(s))-_(_(L*F)+_(_(_(z*j)+_(O*V))+_(H*I)))),u>_(1.1920928955078125e-7)||(h=_(tA*tA),v=_(y(_(h+v))),v>_(1.1920928955078125e-7)&&(u=_(u/v),_(u*_(1.0499999523162842))>k&&(x=s<_(0),p=_(_(-tA)/v),d=_(_(0)/v),E=_(U/v),Q=0,r=11,k=u)),s=_(_(rA*bA)-_(S*nA)),u=_(_(m(s))-_(_(K*F)+_(_(H*q)+_(_(z*Z)+_(O*D))))),u>_(1.1920928955078125e-7)||(v=_(nA*nA),G=_(y(_(v+G))),G>_(1.1920928955078125e-7)&&(u=_(u/G),_(u*_(1.0499999523162842))>k&&(x=s<_(0),p=_(_(-nA)/G),d=_(_(0)/G),E=_(bA/G),Q=0,r=12,k=u)),s=_(_(iA*fA)-_(rA*cA)),u=_(_(m(s))-_(_(L*j)+_(_(_(z*F)+_(P*$))+_(K*Z)))),u>_(1.1920928955078125e-7)||(g=_(y(_(_(w+g)+_(0)))),g>_(1.1920928955078125e-7)&&(u=_(u/g),_(u*_(1.0499999523162842))>k&&(x=s<_(0),p=_(_(0)/g),d=_(fA/g),E=_(_(-cA)/g),Q=0,r=13,k=u)),s=_(_(iA*tA)-_(rA*oA)),u=_(_(m(s))-_(_(L*N)+_(_(_(z*q)+_(P*V))+_(H*Z)))),u>_(1.1920928955078125e-7)||(h=_(y(_(_(W+h)+_(0)))),h>_(1.1920928955078125e-7)&&(u=_(u/h),_(u*_(1.0499999523162842))>k&&(x=s<_(0),p=_(_(0)/h),d=_(tA/h),E=_(_(-oA)/h),Q=0,r=14,k=u)),s=_(_(iA*nA)-_(rA*aA)),u=_(_(m(s))-_(_(K*N)+_(_(H*j)+_(_(z*I)+_(P*D))))),u>_(1.1920928955078125e-7))))))))))))))))){e:{r:{if(v=_(y(_(_(R+v)+_(0)))),v>_(1.1920928955078125e-7)&&(u=_(u/v),_(u*_(1.0499999523162842))>k))x=s<_(0),p=_(_(0)/v),d=_(nA/v),E=_(_(-aA)/v),r=15;else{if(!r)break A;if(Q)break r;u=k}v=_(_(_(lA*E)+_(d*C[e+4>>2]))+_(p*C[e+8>>2])),C[n>>2]=v,R=_(_(_(E*C[e+16>>2])+_(d*C[e+20>>2]))+_(p*C[e+24>>2])),C[n+4>>2]=R,d=_(_(_(E*C[e+32>>2])+_(d*C[e+36>>2]))+_(p*C[e+40>>2])),C[n+8>>2]=d;break e}v=C[Q>>2],a[n>>2]=a[Q>>2],R=C[Q+16>>2],a[n+4>>2]=a[Q+16>>2],d=C[Q+32>>2],a[n+8>>2]=a[Q+32>>2],u=k}if(x&&(C[n+8>>2]=-d,C[n+4>>2]=-R,C[n>>2]=-v),C[o>>2]=-u,(0|r)>=7)Q=l+120|0,a[Q>>2]=a[A+8>>2],t=a[A+4>>2],a[l+112>>2]=a[A>>2],a[l+116>>2]=t,k=_(0),D=C[l+112>>2],w=C[l+116>>2],Z=C[n>>2],W=C[e>>2],o=n+4|0,X=C[o>>2],R=C[e+16>>2],t=n+8|0,I=C[t>>2],s=C[e+32>>2],V=_((_(_(_(Z*W)+_(X*R))+_(I*s))>_(0)?_(1):_(-1))*C[l+356>>2]),d=_(C[Q>>2]+_(V*s)),G=C[e+4>>2],g=C[e+20>>2],s=C[e+36>>2],N=_((_(_(_(Z*G)+_(X*g))+_(I*s))>_(0)?_(1):_(-1))*C[l+360>>2]),d=_(d+_(N*s)),h=C[e+8>>2],v=C[e+24>>2],s=C[e+40>>2],F=_((_(_(_(Z*h)+_(X*v))+_(I*s))>_(0)?_(1):_(-1))*O),C[Q>>2]=d+_(F*s),C[l+116>>2]=_(_(w+_(V*R))+_(N*g))+_(F*v),C[l+112>>2]=_(_(D+_(V*W))+_(N*G))+_(F*h),A=l+216|0,a[A>>2]=a[i+8>>2],W=C[f>>2],R=C[f+16>>2],s=C[f+32>>2],F=_((_(_(_(Z*W)+_(X*R))+_(I*s))>_(0)?_(-1):_(1))*H),d=_(C[A>>2]+_(F*s)),G=C[f+4>>2],g=C[f+20>>2],s=C[f+36>>2],D=_((_(_(_(Z*G)+_(X*g))+_(I*s))>_(0)?_(-1):_(1))*C[l+348>>2]),d=_(d+_(D*s)),h=C[f+8>>2],v=C[f+24>>2],s=C[f+40>>2],w=_((_(_(_(Z*h)+_(X*v))+_(I*s))>_(0)?_(-1):_(1))*C[l+352>>2]),V=_(d+_(w*s)),C[A>>2]=V,A=a[i+4>>2],a[l+208>>2]=a[i>>2],a[l+212>>2]=A,N=_(_(_(C[l+208>>2]+_(F*W))+_(D*G))+_(w*h)),C[l+208>>2]=N,F=_(_(_(C[l+212>>2]+_(F*R))+_(D*g))+_(w*v)),C[l+212>>2]=F,i=r+-7|0,A=(0|i)/3|0,e=e+(A<<2)|0,s=C[e>>2],A=(i-B(A,3)<<2)+f|0,D=C[A>>2],G=C[e+16>>2],w=C[A+16>>2],g=C[e+32>>2],W=C[A+32>>2],R=_(_(_(s*D)+_(G*w))+_(g*W)),h=_(_(1)-_(R*R)),h<=_(9999999747378752e-20)||(v=_(N-C[l+112>>2]),d=_(v*s),s=_(F-C[l+116>>2]),k=_(V-C[Q>>2]),k=_(_(_(_(_(d+_(s*G))+_(k*g))*R)-_(_(_(v*D)+_(s*w))+_(k*W)))*_(_(1)/h))),C[l+216>>2]=V+_(k*W),C[l+212>>2]=F+_(k*w),C[l+208>>2]=N+_(k*D),a[l+284>>2]=0,C[l+280>>2]=-C[t>>2],C[l+276>>2]=-C[o>>2],C[l+272>>2]=-C[n>>2],Qt[a[a[b>>2]+16>>2]](b,l+272|0,l+208|0,u),a[c>>2]=r;else{U=C[n>>2],(0|r)<=3?(M=C[n+8>>2],AA=C[n+4>>2],x=l+356|0,Q=f,T=l+344|0):(U=_(-U),M=_(-C[n+8>>2]),AA=_(-C[n+4>>2]),t=i,x=l+344|0,i=A,A=t,Q=e,e=f,T=l+356|0),s=_(_(_(U*C[Q>>2])+_(AA*C[Q+16>>2]))+_(M*C[Q+32>>2])),C[l+328>>2]=s,u=_(_(_(U*C[Q+4>>2])+_(AA*C[Q+20>>2]))+_(M*C[Q+36>>2])),C[l+332>>2]=u,k=_(_(_(U*C[Q+8>>2])+_(AA*C[Q+24>>2]))+_(M*C[Q+40>>2])),C[l+336>>2]=k,v=_(m(k)),u=_(m(u)),k=_(m(s)),u>k?(o=u>v,f=o?1:2,t=0):(o=k>v,f=(1^o)<<1,t=o),dA=t,f<<=2,s=C[f+T>>2],u=_(s*C[f+Q>>2]),k=_(C[i>>2]-C[A>>2]),CA=o?2:1,t=l,C[f+(l+328|0)>>2]<_(0)?(d=_(k+u),C[l+312>>2]=d,u=_(_(C[i+4>>2]-C[A+4>>2])+_(s*C[(16|f)+Q>>2])),C[l+316>>2]=u,X=_(_(C[i+8>>2]-C[A+8>>2])+_(s*C[(32|f)+Q>>2]))):(d=_(k-u),C[l+312>>2]=d,u=_(_(C[i+4>>2]-C[A+4>>2])-_(s*C[(16|f)+Q>>2])),C[l+316>>2]=u,X=_(_(C[i+8>>2]-C[A+8>>2])-_(s*C[(32|f)+Q>>2]))),C[t+320>>2]=X,o=1,vA=((0|r)<4?-1:-4)+r|0;e:{if(vA>>>0<=1){if(f=2,vA-1)break e}else f=1;o=0}i=2,t=f<<2,f=t+e|0,g=C[f>>2],h=C[f+16>>2],v=C[f+32>>2],eA=_(_(_(d*g)+_(u*h))+_(X*v)),f=dA<<2,sA=f+Q|0,D=C[sA>>2],w=C[sA+16>>2],s=C[sA+32>>2],I=_(_(_(g*D)+_(h*w))+_(v*s)),k=C[f+T>>2],W=_(I*k),R=_(eA+W),f=CA<<2,kA=f+Q|0,G=C[kA>>2],p=_(g*G),g=C[kA+16>>2],p=_(p+_(h*g)),h=C[kA+32>>2],V=_(p+_(v*h)),v=C[f+T>>2],Z=_(V*v),C[l+300>>2]=R-Z,f=o<<2,e=f+e|0,N=C[e>>2],F=C[e+16>>2],d=_(_(d*N)+_(u*F)),u=C[e+32>>2],S=_(d+_(X*u)),w=_(_(_(N*D)+_(F*w))+_(u*s)),s=_(k*w),k=_(S+s),h=_(_(_(N*G)+_(F*g))+_(u*h)),g=_(v*h),C[l+296>>2]=k-g,C[l+292>>2]=R+Z,p=_(k+g),C[l+288>>2]=p,u=_(eA-W),v=_(u+Z),C[l+284>>2]=v,k=_(S-s),d=_(k+g),C[l+280>>2]=d,u=_(u-Z),C[l+276>>2]=u,R=_(k-g),C[l+272>>2]=R,e=t+x|0,g=C[e>>2],gA=a[e>>2],e=f+x|0,uA=a[e>>2],G=C[e>>2],s=_(-G);e:{r:{i:{E=_(-R),f=G>E;f:{if(!f){if(t=0,i=1,e=l+208|0,k=_(-d),o=G>k,f^o)break f;break i}if(C[l+212>>2]=u,C[l+208>>2]=R,e=l+208|8,t=1,k=_(-d),o=G>k,(0|f)==(0|o))break i}if(C[e>>2]=s,C[e+4>>2]=u+_(_(s-R)*_(_(v-u)/_(d-R))),e=e+8|0,o)break r;t=i;break e}if(i=t,!o)break e}C[e+4>>2]=v,C[e>>2]=d,t=i+1|0,e=e+8|0,d=C[l+280>>2],k=_(-d),p=C[l+288>>2]}e:{if((k_(-p)|0)){if(k=C[l+292>>2],u=C[l+284>>2],C[e>>2]=s,C[e+4>>2]=u+_(_(s-d)*_(_(k-u)/_(p-d))),t=t+1|0,8&t)break e;e=e+8|0}if(d=C[l+288>>2],v=_(-d),G>v){if(C[e>>2]=d,a[e+4>>2]=a[l+292>>2],t=t+1|0,8&t)break e;d=C[l+288>>2],v=_(-d),e=e+8|0}if(i=v>2],p=_(-v),(0|i)!=(G>p|0)){if(k=C[l+300>>2],u=C[l+292>>2],C[e>>2]=s,C[e+4>>2]=u+_(_(s-d)*_(_(k-u)/_(v-d))),t=t+1|0,8&t)break e;v=C[l+296>>2],p=_(-v),e=e+8|0}if(p>2]=v,a[e+4>>2]=a[l+300>>2],t=t+1|0,8&t)break e;R=C[l+272>>2],E=_(-R),v=C[l+296>>2],p=_(-v),e=e+8|0}r:{i:{if((p=1)){t=0;break i}}else if(k=C[l+276>>2],u=C[l+300>>2],C[e>>2]=s,C[e+4>>2]=u+_(_(s-v)*_(_(k-u)/_(R-v))),t=t+1|0,8&t)break e;for(e=l+208|0,f=l+112|0,i=0;;){if(R=C[e>>2],R>2]=R,a[f+4>>2]=a[e+4>>2],i=i+1|0,8&i){t=i;break i}R=C[e>>2],f=f+8|0}if(o=e+8|0,T=(0|t)>1?o:l+208|0,u=C[T>>2],(R>2],k=C[T+4>>2],a[f>>2]=uA,C[f+4>>2]=s+_(_(G-R)*_(_(k-s)/_(u-R))),i=i+1|0,8&i){t=i;break i}f=f+8|0}if(e=o,t=t+-1|0,!((0|t)>0))break}if((0|i)<1)t=0;else{for(v=_(-g),f=l+208|0,e=l+112|0,o=0;;){if(t=e+4|0,d=C[t>>2],R=_(-d),g>R){if(a[f>>2]=a[e>>2],a[f+4>>2]=a[t>>2],o=o+1|0,8&o){t=o;break r}d=C[t>>2],R=_(-d),f=f+8|0}if(t=e+8|0,T=(0|i)>1?t:l+112|0,u=C[T+4>>2],(R_(-u)|0)){if(k=C[T>>2],s=C[e>>2],C[f+4>>2]=v,C[f>>2]=s+_(_(v-d)*_(_(k-s)/_(u-d))),o=o+1|0,8&o){t=o;break r}f=f+8|0}if(e=t,i=i+-1|0,!((0|i)>0))break}if((0|o)<1)t=0;else for(e=l+208|0,f=l+112|0,t=0;;){if(i=e+4|0,R=C[i>>2],R>2]=a[e>>2],a[f+4>>2]=a[i>>2],t=t+1|0,8&t)break i;R=C[i>>2],f=f+8|0}if(i=e+8|0,T=(0|o)>1?i:l+208|0,u=C[T+4>>2],(R>2],s=C[e>>2],a[f+4>>2]=gA,C[f>>2]=s+_(_(g-R)*_(_(k-s)/_(u-R))),t=t+1|0,8&t)break i;f=f+8|0}if(e=i,o=o+-1|0,!((0|o)>0))break}}}J(l+208|0,l+112|0,t<<3)}if(!((0|t)>=1))break A}for(k=_(_(1)/_(_(w*V)-_(I*h))),q=_(V*k),$=_(I*k),Z=_(h*k),X=_(w*k),I=C[(vA<<2)+x>>2],i=CA<<2,V=C[(32|i)+Q>>2],e=dA<<2,N=C[(32|e)+Q>>2],F=C[(16|i)+Q>>2],D=C[(16|e)+Q>>2],w=C[kA>>2],W=C[sA>>2],f=0,e=l+208|0,R=C[l+320>>2],G=C[l+316>>2],g=C[l+312>>2];i=(l+112|0)+B(f,12)|0,h=C[e>>2],u=_(h-S),v=C[e+4>>2],k=_(v-eA),j=_(_(q*u)-_(Z*k)),k=_(_(X*k)-_($*u)),s=_(_(G+_(j*D))+_(k*F)),C[i+4>>2]=s,u=_(_(g+_(j*W))+_(k*w)),C[i>>2]=u,k=_(_(R+_(j*N))+_(k*V)),C[i+8>>2]=k,k=_(I-_(_(_(U*u)+_(AA*s))+_(M*k))),C[(l+80|0)+(f<<2)>>2]=k,k>=_(0)&&(i=f<<3,C[i+(l+208|0)>>2]=h,C[(l+208|0)+(4|i)>>2]=v,f=f+1|0),e=e+8|0,t=t+-1|0,t;);if(!((0|f)<1)){e=(0|f)<4?f:4,t=(0|e)>1?e:1;e:if((0|f)<=(0|t)){if((0|r)>=4){for(i=l+80|0,e=l+112|0,t=f;s=C[n>>2],v=C[i>>2],C[l+32>>2]=_(C[e>>2]+C[A>>2])-_(s*v),u=C[n+4>>2],C[l+36>>2]=_(C[e+4>>2]+C[A+4>>2])-_(v*u),k=C[n+8>>2],C[l+40>>2]=_(C[e+8>>2]+C[A+8>>2])-_(v*k),a[l+76>>2]=0,C[l+72>>2]=-k,C[l+68>>2]=-u,C[l+64>>2]=-s,Qt[a[a[b>>2]+16>>2]](b,l- -64|0,l+32|0,_(-v)),e=e+12|0,i=i+4|0,t=t+-1|0,t;);break e}for(i=l+80|0,e=l+112|0,t=f;C[l+32>>2]=C[e>>2]+C[A>>2],C[l+36>>2]=C[e+4>>2]+C[A+4>>2],C[l+40>>2]=C[e+8>>2]+C[A+8>>2],a[l+76>>2]=0,C[l+72>>2]=-C[n+8>>2],C[l+68>>2]=-C[n+4>>2],C[l+64>>2]=-C[n>>2],Qt[a[a[b>>2]+16>>2]](b,l- -64|0,l+32|0,_(-C[i>>2])),e=e+12|0,i=i+4|0,t=t+-1|0,t;);}else{if(Q=0,(0|f)>=2)for(e=l+80|4,v=C[l+80>>2],i=1;k=C[e>>2],o=k>v,v=o?k:v,Q=o?i:Q,e=e+4|0,i=i+1|0,(0|f)!=(0|i););if(function(A,e,r,i,f){var t,n=0,o=0,c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=0,B=_(0),R=0,Q=0,h=_(0);t=Y+-64|0,Y=t;r:{i:{f:{t:{n:{if(o=A+-1|0,!(o>>>0<=1)){if((0|o)>=1)break n;break t}if(o-1)break f;l=_(_(C[e+4>>2]+C[e+12>>2])*_(.5)),c=_(_(C[e>>2]+C[e+8>>2])*_(.5));break i}for(n=e;k=l,l=C[n+12>>2],b=C[n+4>>2],d=_(l+b),s=C[n>>2],n=n+8|0,v=C[n>>2],b=_(_(s*l)-_(v*b)),l=_(k+_(d*b)),c=_(c+b),u=_(u+_(_(s+v)*b)),o=o+-1|0,o;);}if(b=_(0xde0b6b000000000),k=c,n=(A<<3)+e|0,s=C[n+-8>>2],v=C[e+4>>2],B=C[e>>2],d=C[n+-4>>2],c=_(_(s*v)-_(B*d)),k=_(k+c),_(m(k))>_(1.1920928955078125e-7)&&(b=_(_(1)/_(k*_(3)))),o=0,(0|A)<=0)break r;l=_(_(l+_(_(v+d)*c))*b),c=_(_(u+_(_(s+B)*c))*b);break i}l=C[e+4>>2],c=C[e>>2]}for(n=t+32|0,o=A;Q=n,h=vi(_(C[e+4>>2]-l),_(C[e>>2]-c)),C[Q>>2]=h,e=e+8|0,n=n+4|0,o=o+-1|0,o;);for(e=t,n=A;o=1,a[e>>2]=1,e=e+4|0,n=n+-1|0,n;);}if(a[f>>2]=i,e=i<<2,n=e+t|0,a[n>>2]=0,!((0|r)<2))if(f=f+4|0,o)for(l=_(_(6.2831854820251465)/_(0|r)),b=C[e+(t+32|0)>>2],g=1;;){for(a[f>>2]=i,c=_(_(l*_(0|g))+b),s=c>_(3.1415927410125732)?_(c+_(-6.2831854820251465)):c,c=_(1e9),n=t+32|0,e=t,R=i,o=0;a[e>>2]&&(u=_(m(_(C[n>>2]-s))),u=u>_(3.1415927410125732)?_(_(6.2831854820251465)-u):u,u>2]=o,R=o,c=u)),e=e+4|0,n=n+4|0,o=o+1|0,(0|o)!=(0|A););if(a[(R<<2)+t>>2]=0,f=f+4|0,g=g+1|0,(0|g)==(0|r))break}else for(e=r+-1|0;a[f>>2]=i,a[n>>2]=0,f=f+4|0,e=e+-1|0,e;);Y=t- -64|0}(f,l+208|0,t,Q,l+32|0),(0|r)>=4)for(e=l+32|0,i=0;f=a[e>>2],o=(l+112|0)+B(f,12)|0,g=_(C[o>>2]+C[A>>2]),C[l+64>>2]=g,h=_(C[o+4>>2]+C[A+4>>2]),C[l+68>>2]=h,v=_(C[o+8>>2]+C[A+8>>2]),C[l+72>>2]=v,a[l+28>>2]=0,s=C[n+8>>2],C[l+24>>2]=-s,u=C[n+4>>2],C[l+20>>2]=-u,k=C[n>>2],C[l+16>>2]=-k,a[l+12>>2]=0,d=s,s=C[(l+80|0)+(f<<2)>>2],C[l+8>>2]=v-_(d*s),C[l+4>>2]=h-_(u*s),C[l>>2]=g-_(k*s),Qt[a[a[b>>2]+16>>2]](b,l+16|0,l,_(-s)),e=e+4|0,i=i+1|0,i>>>0>>0;);else for(e=l+32|0,i=0;f=a[e>>2],o=(l+112|0)+B(f,12)|0,C[l+64>>2]=C[o>>2]+C[A>>2],C[l+68>>2]=C[o+4>>2]+C[A+4>>2],C[l+72>>2]=C[o+8>>2]+C[A+8>>2],a[l+28>>2]=0,C[l+24>>2]=-C[n+8>>2],C[l+20>>2]=-C[n+4>>2],C[l+16>>2]=-C[n>>2],Qt[a[a[b>>2]+16>>2]](b,l+16|0,l- -64|0,_(-C[(l+80|0)+(f<<2)>>2])),e=e+4|0,i=i+1|0,i>>>0>>0;);}a[c>>2]=r}}}Y=l+368|0}function Ci(A,e,r,i,f){A|=0,e|=0,r|=0,i|=0,f|=0;var t=_(0),n=_(0),o=0,c=_(0),b=_(0),l=_(0),u=_(0);i=Y-160|0,Y=i,a[i+112>>2]=a[e>>2],a[i+64>>2]=a[e+64>>2],f=a[e+8>>2],a[i+116>>2]=a[e+4>>2],a[i+120>>2]=f,f=e+68|0,o=a[f+4>>2],a[i+68>>2]=a[f>>2],a[i+72>>2]=o,f=a[e+20>>2],a[i+128>>2]=a[e+16>>2],a[i+132>>2]=f,f=e+80|0,o=a[f+4>>2],a[i+80>>2]=a[f>>2],a[i+84>>2]=o,a[i+136>>2]=a[e+24>>2],a[i+88>>2]=a[e+88>>2],a[i+144>>2]=a[e+32>>2],a[i+96>>2]=a[e+96>>2],a[i+100>>2]=a[e+100>>2],f=e+36|0,o=a[f+4>>2],a[i+148>>2]=a[f>>2],a[i+152>>2]=o,a[i+104>>2]=a[e+104>>2],f=a[A+4>>2],n=C[f+40>>2],t=C[f+36>>2],c=C[f+32>>2],b=_(Qt[a[a[f>>2]+48>>2]](f)),l=_(Qt[a[a[f>>2]+48>>2]](f)),u=_(Qt[a[a[f>>2]+48>>2]](f)),a[i+36>>2]=0,t=_(t+l),C[i+28>>2]=t+t,t=_(c+b),C[i+24>>2]=t+t,n=_(n+u),C[i+32>>2]=n+n,A=a[A+8>>2],n=C[A+40>>2],t=C[A+36>>2],c=C[A+32>>2],b=_(Qt[a[a[A>>2]+48>>2]](A)),l=_(Qt[a[a[A>>2]+48>>2]](A)),u=_(Qt[a[a[A>>2]+48>>2]](A)),a[i+20>>2]=0,t=_(t+l),C[i+12>>2]=t+t,t=_(c+b),C[i+8>>2]=t+t,n=_(n+u),C[i+16>>2]=n+n,di(e+48|0,i+112|0,i+24|0,e+112|0,i- -64|0,i+8|0,i+48|0,i+44|0,i+40|0,r),Y=i+160|0}function gi(A,e,r,i,f){var t,n=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=0,v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=0,D=_(0),E=_(0),Z=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0),U=_(0),M=_(0),S=0,X=_(0),T=_(0),j=_(0),O=_(0),H=_(0),z=_(0),P=_(0),K=_(0),L=_(0),q=_(0),$=_(0),AA=_(0),eA=_(0),rA=_(0),iA=_(0),fA=_(0);t=Y-48|0,Y=t,w=o[A+16|0],S=w?i:r,k=a[S+12>>2],P=C[k+56>>2],K=C[k+52>>2],L=C[k+48>>2],w=w?r:i,r=a[w+12>>2],q=C[r+56>>2],X=C[r+48>>2],$=C[r+52>>2],S=a[S+4>>2],g=C[r+40>>2],l=C[r+8>>2],u=C[r+24>>2],s=C[r+32>>2],Q=C[r>>2],h=C[r+16>>2],i=a[w+4>>2],y=C[r+36>>2],E=C[k+40>>2],Z=C[k+32>>2],V=C[k+36>>2],p=C[r+4>>2],N=C[k+8>>2],I=C[k>>2],J=C[k+4>>2],F=C[r+20>>2],x=C[k+24>>2],U=C[k+16>>2],M=C[k+20>>2],b=C[e+12>>2],v=C[e+8>>2],n=C[e>>2],c=C[e+4>>2],a[t+28>>2]=0,B=_(_(2)/_(_(_(_(n*n)+_(c*c))+_(v*v))+_(b*b))),d=_(v*B),T=_(n*d),m=_(c*B),j=_(b*m),G=_(T+j),D=_(c*d),R=_(n*B),O=_(b*R),B=_(D-O),H=_(n*R),z=_(c*m),c=_(_(1)-_(H+z)),R=_(_(_(Z*G)+_(V*B))+_(E*c)),W=_(_(_(I*G)+_(J*B))+_(N*c)),c=_(_(_(U*G)+_(M*B))+_(x*c)),B=_(-C[i+52>>2]),r=i+56|0,G=C[r>>2],AA=_(_(_(_(s*R)+_(_(Q*W)+_(h*c)))*B)-_(_(_(y*R)+_(_(p*W)+_(F*c)))*G)),R=_(_(g*R)+_(_(l*W)+_(u*c))),k=i+60|0,c=C[k>>2],C[t+24>>2]=AA-_(R*c),R=_(D+O),m=_(n*m),W=_(b*d),n=_(m-W),D=_(v*d),b=_(_(1)-_(H+D)),v=_(_(E*R)+_(_(Z*n)+_(V*b))),d=_(_(N*R)+_(_(I*n)+_(J*b))),n=_(_(x*R)+_(_(U*n)+_(M*b))),C[t+20>>2]=_(_(_(_(s*v)+_(_(Q*d)+_(h*n)))*B)-_(G*_(_(y*v)+_(_(p*d)+_(F*n)))))-_(c*_(_(g*v)+_(_(l*d)+_(u*n)))),n=_(T-j),b=_(m+W),v=_(_(1)-_(z+D)),d=_(_(E*n)+_(_(V*b)+_(Z*v))),m=_(_(N*n)+_(_(J*b)+_(I*v))),n=_(_(x*n)+_(_(M*b)+_(U*v))),C[t+16>>2]=_(_(_(_(s*d)+_(_(Q*m)+_(h*n)))*B)-_(G*_(_(y*d)+_(_(p*m)+_(F*n)))))-_(c*_(_(g*d)+_(_(l*m)+_(u*n)))),Qt[a[a[S>>2]+64>>2]](t+32|0,S,t+16|0),e=a[w+12>>2],G=C[e+48>>2],R=C[e+32>>2],W=C[e+16>>2],T=C[e+8>>2],j=C[e+4>>2],D=C[e>>2],O=C[e+56>>2],H=C[e+52>>2],z=C[e+40>>2],AA=C[e+36>>2],eA=C[e+24>>2],rA=C[e+20>>2],iA=C[i+68>>2],v=C[k>>2],d=C[i+52>>2],B=C[r>>2],n=C[t+40>>2],b=C[t+32>>2],c=C[t+36>>2],fA=C[a[A+12>>2]+784>>2],a[f+4>>2]=a[A+12>>2],m=_(-X),X=_(_(_(_(_(L*l)+_(K*u))+_(P*g))+_(_(_(l*m)-_(u*$))-_(g*q)))+_(_(_(b*_(_(_(I*l)+_(U*u))+_(Z*g)))+_(c*_(_(_(J*l)+_(M*u))+_(V*g))))+_(n*_(_(_(N*l)+_(x*u))+_(E*g))))),Q=_(_(_(_(_(L*Q)+_(K*h))+_(P*s))+_(_(_(Q*m)-_(h*$))-_(s*q)))+_(_(_(b*_(_(_(I*Q)+_(U*h))+_(Z*s)))+_(c*_(_(_(J*Q)+_(M*h))+_(V*s))))+_(n*_(_(_(N*Q)+_(x*h))+_(E*s))))),h=_(_(_(_(_(L*p)+_(K*F))+_(P*y))+_(_(_(p*m)-_(F*$))-_(y*q)))+_(_(_(b*_(_(_(I*p)+_(U*F))+_(Z*y)))+_(c*_(_(_(J*p)+_(M*F))+_(V*y))))+_(n*_(_(_(N*p)+_(x*F))+_(E*y))))),g=_(_(_(v*X)+_(_(d*Q)+_(B*h)))-iA),g>2]=0,A=a[w+12>>2],l=C[i+52>>2],u=C[i+56>>2],s=C[i+60>>2],C[t+16>>2]=_(_(C[A>>2]*l)+_(C[A+4>>2]*u))+_(C[A+8>>2]*s),C[t+24>>2]=_(_(l*C[A+32>>2])+_(u*C[A+36>>2]))+_(s*C[A+40>>2]),C[t+20>>2]=_(_(l*C[A+16>>2])+_(u*C[A+20>>2]))+_(s*C[A+24>>2]),a[t+12>>2]=0,l=_(Q-_(d*g)),u=_(h-_(B*g)),s=_(X-_(v*g)),C[t+8>>2]=_(_(_(l*R)+_(u*AA))+_(s*z))+O,C[t+4>>2]=_(_(_(l*W)+_(u*rA))+_(s*eA))+H,C[t>>2]=_(_(T*s)+_(_(D*l)+_(j*u)))+G,Qt[a[a[f>>2]+16>>2]](f,t+16|0,t,g)),Y=t+48|0}function Bi(A,e){var r,i=0,t=0,n=0,o=0,c=0;if(a[A>>2]=17664,t=a[e+20>>2],i=dA(4),a[A+24>>2]=i,a[i>>2]=t?14800:15008,i=dA(20),function(A,e){a[A+12>>2]=0,a[A+16>>2]=3,a[A>>2]=15424,f[A+4|0]=0,a[A+8>>2]=e}(i,a[A+24>>2]),a[A+28>>2]=i,i=dA(8),a[i>>2]=17780,f[i+4|0]=0,a[A+32>>2]=i,i=dA(8),a[i>>2]=17864,f[i+4|0]=0,a[A+36>>2]=i,i=dA(8),a[i>>2]=17956,f[i+4|0]=0,a[A+40>>2]=i,i=dA(8),a[i>>2]=18036,f[i+4|0]=0,a[A+44>>2]=i,i=dA(8),a[i>>2]=18124,f[i+4|0]=0,a[A+48>>2]=i,i=dA(8),a[i>>2]=18208,f[i+4|0]=0,a[A+52>>2]=i,i=dA(8),a[i>>2]=18276,f[i+4|0]=0,a[A+56>>2]=i,i=dA(8),a[i>>2]=18360,f[i+4|0]=0,a[A+72>>2]=i,i=dA(8),a[A+76>>2]=i,a[i>>2]=18360,f[i+4|0]=1,i=dA(8),a[i>>2]=18444,f[i+4|0]=0,a[A+68>>2]=i,i=dA(16),a[i+8>>2]=1,a[i+12>>2]=0,a[i>>2]=18520,f[i+4|0]=0,a[A+84>>2]=i,i=dA(16),a[i+8>>2]=1,a[i+12>>2]=0,a[i>>2]=18520,a[A+80>>2]=i,f[i+4|0]=1,r=a[e+16>>2],i=a[e>>2],i)a[A+8>>2]=i,f[A+12|0]=0;else{if(f[A+12|0]=1,o=dA(24),a[o+20>>2]=0,a[o>>2]=804,i=a[e+8>>2],a[o+4>>2]=i,t=dA(B(i,804)),a[o+12>>2]=t,a[o+16>>2]=t,i=a[o+4>>2],a[o+8>>2]=i,c=i+-1|0,c)for(n=a[o>>2];i=t+n|0,a[t>>2]=i,t=i,c=c+-1|0,c;);else i=t;a[i>>2]=0,a[A+8>>2]=o}if(i=a[e+4>>2],i)return a[A+16>>2]=i,void(f[A+20|0]=0);if(f[A+20|0]=1,n=dA(24),a[n+20>>2]=0,i=(0|r)>80?r:80,i=(0|i)>116?i+16&-16:128,a[n>>2]=i,e=a[e+12>>2],a[n+4>>2]=e,t=dA(B(e,i)),a[n+12>>2]=t,a[n+16>>2]=t,e=a[n+4>>2],a[n+8>>2]=e,c=e+-1|0,c)for(e=a[n>>2];i=e+t|0,a[t>>2]=i,t=i,c=c+-1|0,c;);else i=t;a[i>>2]=0,a[A+16>>2]=n}function _i(A){A|=0;var e=0;return a[A>>2]=17664,o[A+20|0]&&(CA(a[a[A+16>>2]+16>>2]),CA(a[A+16>>2])),o[A+12|0]&&(CA(a[a[A+8>>2]+16>>2]),CA(a[A+8>>2])),e=a[A+28>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+28>>2]),e=a[A+32>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+32>>2]),e=a[A+36>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+36>>2]),e=a[A+40>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+40>>2]),e=a[A+44>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+44>>2]),e=a[A+48>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+48>>2]),e=a[A+52>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+52>>2]),e=a[A+56>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+56>>2]),e=a[A+72>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+72>>2]),e=a[A+76>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+76>>2]),e=a[A+68>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+68>>2]),e=a[A+84>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+84>>2]),e=a[A+80>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+80>>2]),e=a[A+24>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+24>>2]),0|A}function mi(A){return A|=0,a[A+8>>2]}function Ri(A){var e=0,r=0,i=0,t=0,n=0,c=0,b=0,l=0;if(a[A>>2]=18600,a[A+24>>2]=0,a[A+68>>2]=0,f[A+20|0]=1,a[A+16>>2]=0,f[A+44|0]=1,r=A+8|0,e=r,a[e>>2]=0,a[e+4>>2]=0,a[A+40>>2]=0,f[A- -64|0]=1,e=A+32|0,a[e>>2]=0,a[e+4>>2]=0,a[A+60>>2]=0,e=A+52|0,a[e>>2]=0,a[e+4>>2]=0,e=dA(32),i=a[r>>2],(0|i)>=1)for(r=12;t=r+e|0,n=a[A+16>>2]+r|0,a[t+-12>>2]=a[n+-12>>2],c=n+-8|0,l=a[c+4>>2],b=t+-8|0,a[b>>2]=a[c>>2],a[b+4>>2]=l,a[t>>2]=a[n>>2],r=r+16|0,i=i+-1|0,i;);r=a[A+16>>2],r&&(o[A+20|0]&&CA(r),a[A+16>>2]=0),a[A+16>>2]=e,f[A+20|0]=1,a[A+12>>2]=2,Qi(A)}function Qi(A){var e,r,i=0,t=0,n=0,c=0,b=0,l=0,u=0;if(r=a[A+32>>2],e=a[A+12>>2],!((0|r)>=(0|e))){A:if(a[A+36>>2]>=(0|e))n=a[A+40>>2];else{if(e?(n=dA(e<<2),t=a[A+32>>2]):t=r,i=a[A+40>>2],(0|t)>=1)for(c=n,b=i;a[c>>2]=a[b>>2],c=c+4|0,b=b+4|0,t=t+-1|0,t;);else if(!i){a[A+40>>2]=n,a[A+36>>2]=e,f[A+44|0]=1;break A}o[A+44|0]&&CA(i),a[A+40>>2]=n,f[A+44|0]=1,a[A+36>>2]=e}if(t=r<<2,l=e<<2,X(t+n|0,0,l-t|0),a[A+32>>2]=e,u=a[A+52>>2],(0|u)<(0|e)){A:if(a[A+56>>2]>=(0|e))n=a[A+60>>2];else{if(e?(n=dA(l),t=a[A+52>>2]):(n=0,t=u),i=a[A+60>>2],(0|t)>=1)for(c=n,b=i;a[c>>2]=a[b>>2],c=c+4|0,b=b+4|0,t=t+-1|0,t;);else if(!i){a[A+60>>2]=n,a[A+56>>2]=e,f[A- -64|0]=1;break A}o[A- -64|0]&&CA(i),a[A+60>>2]=n,f[A+64|0]=1,a[A+56>>2]=e}t=u<<2,X(t+n|0,0,l-t|0)}if(a[A+52>>2]=e,(0|e)>=1&&(X(a[A+40>>2],255,l),X(a[A+60>>2],255,l)),!((0|r)<1))for(b=a[A+60>>2],c=a[A+16>>2],n=a[A+40>>2],t=0;i=a[a[c>>2]+12>>2]|a[a[c+4>>2]+12>>2]<<16,i=(i<<15^-1)+i|0,i=B(i>>>10^i,9),i^=i>>>6,i=(i<<11^-1)+i|0,i=n+((a[A+12>>2]+-1&(i>>>16^i))<<2)|0,a[b>>2]=a[i>>2],a[i>>2]=t,c=c+16|0,b=b+4|0,t=t+1|0,(0|t)!=(0|r););}}function hi(A){return A|=0,A+4|0}function Gi(A,e){A|=0,e|=0,a[A+24>>2]=e}function yi(A){var e,r=0,i=0,t=0,n=0,c=0,b=0;if(e=Y-32|0,Y=e,a[A>>2]=19124,er(A+4|0),er(A+44|0),a[A+168>>2]=0,f[A+172|0]=1,r=A+160|0,a[r>>2]=0,a[r+4>>2]=0,f[A+153|0]=256,f[A+154|0]=1,f[A+152|0]=1,a[A+124>>2]=0,a[A+100>>2]=0,a[A+104>>2]=0,a[A+136>>2]=0,a[A+128>>2]=0,a[A+132>>2]=0,a[A+116>>2]=10,a[A+120>>2]=1,a[A+108>>2]=1,a[A+112>>2]=0,i=dA(72),Ri(i),r=a[A+160>>2],a[A+148>>2]=0,a[A+96>>2]=i,a[A+140>>2]=0,a[A+144>>2]=0,i=A+84|0,a[i>>2]=0,a[i+4>>2]=0,a[A+92>>2]=0,a[e+20>>2]=0,f[e+24|0]=1,a[e+12>>2]=0,a[e+16>>2]=0,(0|r)>=2)for(t=r+-1|0,r=36;i=a[A+168>>2]+r|0,b=i+-12|0,n=i+-4|0,c=a[n>>2],c&&(o[0|i]&&CA(c),a[n>>2]=0),a[n>>2]=0,a[b>>2]=0,f[0|i]=1,a[i+-8>>2]=0,r=r+20|0,t=t+-1|0,t;);else if(1!=(0|r))for(function(A){var e=0,r=0,i=0,t=0,n=0,c=0,b=0;if(a[A+8>>2]<1){if(n=dA(20),e=a[A+4>>2],!((0|e)<1)){for(;pi(r+n|0,a[A+12>>2]+r|0),r=r+20|0,e=e+-1|0,e;);if(i=a[A+4>>2],!((0|i)<1))for(e=8;r=a[A+12>>2]+e|0,b=r+-4|0,t=r+4|0,c=a[t>>2],c&&(o[r+8|0]&&CA(c),a[t>>2]=0),a[b>>2]=0,a[t>>2]=0,a[r>>2]=0,f[r+8|0]=1,e=e+20|0,i=i+-1|0,i;);}e=a[A+12>>2],e&&(o[A+16|0]&&CA(e),a[A+12>>2]=0),a[A+12>>2]=n,f[A+16|0]=1,a[A+8>>2]=1}}(A+156|0),t=B(r,20),r=r+-1|0;pi(a[A+168>>2]+t|0,e+8|0),t=t+20|0,i=r+1|0,n=i>>>0>=r>>>0,r=i,n;);a[A+160>>2]=1,A=a[e+20>>2],A&&(o[e+24|0]&&CA(A),a[e+20>>2]=0),Y=e+32|0}function pi(A,e){var r=0,i=0,t=0,n=0;if(a[A+4>>2]=0,a[A+8>>2]=0,a[A+12>>2]=0,f[A+16|0]=1,t=a[e+4>>2],(0|t)<=0)a[A+4>>2]=t;else{if(n=dA(t<<2),i=a[A+4>>2],(0|i)>=1)for(;a[r+n>>2]=a[a[A+12>>2]+r>>2],r=r+4|0,i=i+-1|0,i;);for(i=a[A+12>>2],i&&(o[A+16|0]&&CA(i),a[A+12>>2]=0),a[A+12>>2]=n,f[A+16|0]=1,a[A+8>>2]=t,r=0,i=t;a[r+n>>2]=0,r=r+4|0,n=a[A+12>>2],i=i+-1|0,i;);if(a[A+4>>2]=t,(0|t)>=1)for(r=0;a[r+n>>2]=a[a[e+12>>2]+r>>2],r=r+4|0,t=t+-1|0,t;);}}function Fi(A){A|=0;var e=0,r=0,i=0,t=0,n=0,c=0;if(a[A>>2]=19124,o[A+152|0]&&(e=a[A+96>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+96>>2])),r=a[A+160>>2],(0|r)>=1)for(i=8;e=a[A+168>>2]+i|0,c=e+-4|0,t=e+4|0,n=a[t>>2],n&&(o[e+8|0]&&CA(n),a[t>>2]=0),a[c>>2]=0,a[t>>2]=0,a[e>>2]=0,f[e+8|0]=1,i=i+20|0,r=r+-1|0,r;);return e=a[A+168>>2],e&&(o[A+172|0]&&CA(e),a[A+168>>2]=0),a[A+168>>2]=0,a[A+160>>2]=0,a[A+164>>2]=0,f[A+172|0]=1,rr(A+44|0),rr(A+4|0),0|A}function Wi(A,e,r,i){var f,t=0,n=0,o=0,c=0,b=0,l=0,u=0,s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=0;if(f=Y-256|0,Y=f,e){for(s=C[r+24>>2],k=C[r+20>>2],v=C[r+16>>2],d=C[r+8>>2],g=C[r+4>>2],B=C[r>>2],a[f>>2]=e,t=64,A=f,r=1;;){A:{e:{r:{if(e=r+-1|0,u=e<<2,n=a[u+A>>2],!(C[n>>2]<=v^1|C[n+16>>2]>=B^1|C[n+4>>2]<=k^1|C[n+20>>2]>=g^1||C[n+8>>2]<=s^1|C[n+24>>2]>=d^1)){if(a[n+40>>2]){if(m=a[n+36>>2],(0|e)!=(0|t))break r;if(e=t?t<<1:1,(0|r)>(0|e))break r;o=e?dA(e<<2):0;i:{f:{if((0|t)>=1){for(c=o,b=A;a[c>>2]=a[b>>2],c=c+4|0,b=b+4|0,t=t+-1|0,t;);if(l)break f;break i}if(!A|!l)break i}CA(A)}l=1;break e}Qt[a[a[i>>2]+12>>2]](i,n)}break A}e=t,o=A}if(a[o+u>>2]=m,n=a[n+40>>2],(0|e)==(0|r))if(t=r?r<<1:1,(0|r)>=(0|t))t=r,A=o;else{A=t?dA(t<<2):0;e:{r:{if((0|r)>=1){for(e=A,c=o,b=r;a[e>>2]=a[c>>2],e=e+4|0,c=c+4|0,b=b+-1|0,b;);if(l)break r;break e}if(!o|!l)break e}CA(o)}l=1}else t=e,A=o;a[(r<<2)+A>>2]=n,e=r+1|0}if(r=e,!((0|r)>0))break}!A|!l||CA(A)}Y=f+256|0}function wi(A,e,r,i,t,n,c,b,l,u){var s,k=0,v=0,d=0,g=_(0),B=0,m=_(0),R=_(0),Q=_(0),h=0,G=_(0),y=_(0),p=0,F=_(0);if(s=Y-32|0,Y=s,e){if(v=a[l+4>>2],(0|v)<=127){if(a[l+8>>2]<=127){if(d=dA(512),A=a[l+4>>2],(0|A)>=1)for(;a[k+d>>2]=a[a[l+12>>2]+k>>2],k=k+4|0,A=A+-1|0,A;);A=a[l+12>>2],A&&(o[l+16|0]&&CA(A),a[l+12>>2]=0),a[l+12>>2]=d,f[l+16|0]=1,a[l+8>>2]=128}for(k=v<<2,A=v+-128|0;a[a[l+12>>2]+k>>2]=0,k=k+4|0,v=A+1|0,d=v>>>0>=A>>>0,A=v,d;);}for(a[l+4>>2]=128,a[a[l+12>>2]>>2]=e,k=126,A=1;;){a[s+12>>2]=0,d=a[l+12>>2],e=A+-1|0,p=e<<2,v=a[d+p>>2],C[s+8>>2]=C[v+8>>2]-C[b+8>>2],C[s+4>>2]=C[v+4>>2]-C[b+4>>2],C[s>>2]=C[v>>2]-C[b>>2],m=C[v+24>>2],R=C[v+16>>2],g=C[c+8>>2],Q=C[c>>2],C[s+20>>2]=C[v+20>>2]-C[c+4>>2],C[s+16>>2]=R-Q,C[s+24>>2]=m-g,a[s+28>>2]=0,B=a[t+4>>2],Q=C[r+4>>2],G=C[i+4>>2],m=_(_(C[4+((B<<4)+s|0)>>2]-Q)*G),g=C[i>>2],h=a[t>>2],y=C[r>>2],R=_(g*_(C[(1-h<<4)+s>>2]-y));A:{if(!(m>R||(g=_(_(C[(h<<4)+s>>2]-y)*g),Q=_(G*_(C[4+((1-B<<4)+s|0)>>2]-Q)),g>Q||(B=a[t+8>>2],y=C[r+8>>2],F=C[i+8>>2],G=_(_(C[8+((B<<4)+s|0)>>2]-y)*F),R=QR||(m=m>g?m:g,g=_(F*_(C[8+((1-B<<4)+s|0)>>2]-y)),m>g|(G>m?G:m)_(0)^1))))){if(a[v+40>>2]){if((0|e)>(0|k)){if(e=a[l+4>>2],B=e<<1,(0|e)<(0|B)){if(a[l+8>>2]<(0|B)){if(e){if(d=dA(e<<3),h=a[l+4>>2],!((0|h)<1))for(k=0;a[k+d>>2]=a[a[l+12>>2]+k>>2],k=k+4|0,h=h+-1|0,h;);}else d=0;k=a[l+12>>2],k&&(o[l+16|0]&&CA(k),a[l+12>>2]=0),a[l+12>>2]=d,f[l+16|0]=1,a[l+8>>2]=B}for(k=e<<2;a[k+d>>2]=0,k=k+4|0,d=a[l+12>>2],e=e+-1|0,e;);}a[l+4>>2]=B,k=B+-2|0}a[d+p>>2]=a[v+36>>2],a[a[l+12>>2]+(A<<2)>>2]=a[v+40>>2],A=A+1|0;break A}Qt[a[a[u>>2]+12>>2]](u,v)}A=e}if(!A)break}}Y=s+32|0}function Di(A,e,r,i){var t=0,n=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0;if(!(!e|!r)){if(!(a[A+24>>2]>127|a[A+28>>2]>127)){if(l=dA(1024),t=a[A+24>>2],(0|t)>=1)for(;b=a[A+32>>2]+c|0,u=a[b+4>>2],n=c+l|0,a[n>>2]=a[b>>2],a[n+4>>2]=u,c=c+8|0,t=t+-1|0,t;);t=a[A+32>>2],t&&(o[A+36|0]&&CA(t),a[A+32>>2]=0),a[A+32>>2]=l,a[A+28>>2]=128,f[A+36|0]=1}for(a[A+24>>2]=128,l=a[A+32>>2],a[l+4>>2]=r,a[l>>2]=e,r=124,e=1;;){if(b=a[A+32>>2],l=e,e=e+-1|0,s=e<<3,t=b+s|0,n=a[t+4>>2],t=a[t>>2],(0|e)>(0|r)){if(r=a[A+24>>2],u=r<<1,!((0|r)>=(0|u)|a[A+28>>2]>=(0|u))){if(r){if(b=dA(r<<4),r=a[A+24>>2],!((0|r)<1))for(c=0;k=a[A+32>>2]+c|0,d=a[k+4>>2],v=c+b|0,a[v>>2]=a[k>>2],a[v+4>>2]=d,c=c+8|0,r=r+-1|0,r;);}else b=0;r=a[A+32>>2],r&&(o[A+36|0]&&CA(r),a[A+32>>2]=0),a[A+32>>2]=b,f[A+36|0]=1,a[A+28>>2]=u}a[A+24>>2]=u,r=u+-4|0}A:if((0|t)!=(0|n)){if(!(C[t>>2]<=C[n+16>>2]^1|C[t+16>>2]>=C[n>>2]^1|C[t+4>>2]<=C[n+20>>2]^1|C[t+20>>2]>=C[n+4>>2]^1||C[t+8>>2]<=C[n+24>>2]^1|C[t+24>>2]>=C[n+8>>2]^1))if(c=a[n+40>>2],a[t+40>>2]){if(e=a[t+36>>2],c){c=b+s|0,a[c+4>>2]=a[n+36>>2],a[c>>2]=e,c=a[t+40>>2],e=l<<3,b=e+a[A+32>>2]|0,a[b+4>>2]=a[n+36>>2],a[b>>2]=c,c=a[t+36>>2],b=e+a[A+32>>2]|0,a[b+12>>2]=a[n+40>>2],a[b+8>>2]=c,t=a[t+40>>2],e=e+a[A+32>>2]|0,a[e+20>>2]=a[n+40>>2],a[e+16>>2]=t,e=l+3|0;break A}c=b+s|0,a[c+4>>2]=n,a[c>>2]=e,e=a[t+40>>2],t=a[A+32>>2]+(l<<3)|0,a[t+4>>2]=n,a[t>>2]=e,e=l+1|0}else c?(e=b+s|0,a[e+4>>2]=a[n+36>>2],a[e>>2]=t,e=a[A+32>>2]+(l<<3)|0,a[e+4>>2]=a[n+40>>2],a[e>>2]=t,e=l+1|0):Qt[a[a[i>>2]+8>>2]](i,t,n)}else{if(!a[t+40>>2])break A;e=b+s|0,n=a[t+36>>2],a[e+4>>2]=n,a[e>>2]=n,e=l<<3,n=e+a[A+32>>2]|0,c=a[t+40>>2],a[n+4>>2]=c,a[n>>2]=c,n=a[t+40>>2],e=8+(e+a[A+32>>2]|0)|0,a[e>>2]=a[t+36>>2],a[e+4>>2]=n,e=l+2|0}if(!e)break}}}function Ei(A,e,r,i){for(var f=0,t=0,n=0,o=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,C=0,g=0,B=0;;){for(g=r,s=a[A+12>>2],l=s+((r+i|0)/2<<4)|0,C=a[l+8>>2],u=a[l+4>>2],v=a[l>>2],l=i;;){A:{if(!v)for(b=(r<<4)+s|0;;){o=-1,f=-1,t=a[b>>2],t&&(f=a[t+12>>2]),n=a[b+4>>2],n&&(o=a[n+12>>2]),c=u?a[u+12>>2]:-1;e:if(!((0|f)>-1)){if(!(t|(0|o)>(0|c))){if((0|n)!=(0|u))break A;if(d[b+8>>2]>C>>>0)break e;break A}if((0|o)<=(0|c)|t)break A}b=b+16|0,r=r+1|0}for(b=(r<<4)+s|0,k=a[v+12>>2];;){if(o=-1,f=-1,t=a[b>>2],t&&(f=a[t+12>>2]),n=a[b+4>>2],n&&(o=a[n+12>>2]),c=u?a[u+12>>2]:-1,!((0|f)>(0|k)))if((0|t)!=(0|v)|(0|o)>(0|c)){if((0|t)!=(0|v)|(0|o)<=(0|c))break A}else if((0|n)!=(0|u)|d[b+8>>2]<=C>>>0)break A;b=b+16|0,r=r+1|0}}A:{if(!v)for(f=(l<<4)+s|0;;){c=-1,o=-1,n=a[f>>2],n&&(o=a[n+12>>2]),c=u?a[u+12>>2]:c,k=a[f+4>>2],t=-1,k&&(t=a[k+12>>2]);e:if(!((0|o)<-1)){if(!(n|(0|c)>(0|t))){if((0|u)!=(0|k))break A;if(d[f+8>>2]>>0)break e;break A}if((0|c)<=(0|t)|n)break A}f=f+-16|0,l=l+-1|0}for(f=(l<<4)+s|0,B=a[v+12>>2];;){if(c=-1,o=-1,n=a[f>>2],n&&(o=a[n+12>>2]),c=u?a[u+12>>2]:c,k=a[f+4>>2],t=-1,k&&(t=a[k+12>>2]),!((0|B)>(0|o)))if((0|n)!=(0|v)|(0|c)>(0|t)){if((0|n)!=(0|v)|(0|c)<=(0|t))break A}else if((0|u)!=(0|k)|d[f+8>>2]>=C>>>0)break A;f=f+-16|0,l=l+-1|0}}if((0|r)<=(0|l)&&(o=(r<<4)+s|0,c=a[o+4>>2],t=a[o+8>>2],o=a[o+12>>2],s=a[b>>2],n=a[f+4>>2],a[b>>2]=a[f>>2],a[b+4>>2]=n,f=f+8|0,n=a[f+4>>2],b=b+8|0,a[b>>2]=a[f>>2],a[b+4>>2]=n,f=a[A+12>>2]+(l<<4)|0,a[f+12>>2]=o,a[f+4>>2]=c,a[f+8>>2]=t,a[f>>2]=s,l=l+-1|0,r=r+1|0),!((0|r)<=(0|l)))break;s=a[A+12>>2]}if((0|l)>(0|g)&&Ei(A,e,g,l),!((0|r)<(0|i)))break}}function Zi(A,e){A|=0,e|=0,A=a[A+4>>2],Qt[a[a[A>>2]+8>>2]](A,a[e+36>>2])}function Yi(A,e){return _((A?_(-e):e)*e)}function Vi(A,e){var r,i=0,f=0,t=0,n=0,o=0,v=_(0),d=0,C=0;s(e),t=c(0),o=t<<1,r=o+-1|0;A:{e:{r:{i:{s(A),i=c(0);f:{if(i+-8388608>>>0<=2130706431){if(r>>>0>4278190078)break f;break r}if(r>>>0<4278190079)break i}if(v=_(1),!o|1065353216==(0|i))break e;if(i<<=1,!(o>>>0<4278190081&&i>>>0<=4278190080))return _(A+e);if(2130706432==(0|i))break e;return _((-1^t)>>>31==(i>>>0<2130706432|0)?0:e*e)}if((i<<1)-1>>>0>=4278190079){if(v=_(A*A),(0|i)>-1||(i=t>>>23&255,i+-127>>>0>23||(i=1<<150-i,v=i&t?i+-1&t?v:_(-v):v)),(0|t)>-1)break e;return _(_(1)/v)}if((0|i)<=-1){if(n=t>>>23&255,n>>>0<127)break A;i:{if(n>>>0<=150){if(n=1<<150-n,n+-1&t)break A;if(o=65536,t&n)break i}o=0}n=o,i&=2147483647}i>>>0>8388607||(i=(2147483647&(s(_(A*_(8388608))),c(0)))-192937984|0)}if(t=i+-1060306944|0,o=t>>>15&240,f=g[o+19464>>3]*(b(0,i-(-8388608&t)|0),+k())-1,d=f*f,f=((g[2466]+g[2465]*f)*(d*d)+(d*(g[2468]+g[2467]*f)+(g[o+19472>>3]+ +(t>>23)+f*g[2469])))*+e,u(+f),i=0|c(1),c(0),i&=2147450880,!(1079967744==(0|i)|i>>>0<1079967744)){if(f>127.99999995700433)return Yi(n,_(1.5845632502852868e29));if(f<=-150)return Yi(n,_(2.524354896707238e-29))}C=f,f=g[2502],d=C+f,f=C-(d-f),f=f*f*(g[2504]+g[2503]*f)+(f*g[2505]+1),u(+d),c(1),i=0|c(0),t=n+i<<15,n=19760+((31&i)<<3)|0,o=a[n>>2],i=o,t=a[n+4>>2]+t|0,b(0,0|i),b(1,0|(i>>>0>>0?t+1|0:t)),v=_(f*+l())}return v}return A=_(A-A),_(A/A)}function Ni(A){var e,r=_(0),i=0,f=_(0);if(s(A),i=c(0),e=2147483647&i,e>>>0>=1065353216)return _(1065353216==(0|e)?(0|i)<0?3.141592502593994:0:_(0)/_(A-A));A:{if(e>>>0<=1056964607){if(r=_(1.570796251296997),e>>>0<847249409)break A;return r=_(A*A),_(_(_(_(7.549789415861596e-8)-_(_(_(r*_(_(r*_(_(r*_(-.008656363002955914))+_(-.04274342209100723)))+_(.16666586697101593)))/_(_(r*_(-.7066296339035034))+_(1)))*A))-A)+_(1.570796251296997))}if((0|i)<=-1)return A=_(_(A+_(1))*_(.5)),r=_(y(A)),A=_(_(1.570796251296997)-_(r+_(_(r*_(_(A*_(_(A*_(_(A*_(-.008656363002955914))+_(-.04274342209100723)))+_(.16666586697101593)))/_(_(A*_(-.7066296339035034))+_(1))))+_(-7.549789415861596e-8)))),_(A+A);A=_(_(_(1)-A)*_(.5)),f=_(y(A)),b(0,-4096&(s(f),c(0))),r=k(),A=_(_(_(f*_(_(A*_(_(A*_(_(A*_(-.008656363002955914))+_(-.04274342209100723)))+_(.16666586697101593)))/_(_(A*_(-.7066296339035034))+_(1))))+_(_(A-_(r*r))/_(f+r)))+r),r=_(A+A)}return r}function Ii(A,e){var r;Ee(A),f[A+560|0]=1,a[A>>2]=20096,a[A+556>>2]=0,r=A+548|0,a[r>>2]=0,a[r+4>>2]=0,function(A,e){var r=0,i=0,t=0,n=_(0),c=0,b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=0;c=Y-16|0,Y=c,a[A+372>>2]=0,a[A+376>>2]=0,a[A+252>>2]=2,a[A+604>>2]=1065353216,a[A+608>>2]=1065353216,a[A+408>>2]=1065353216,a[A+412>>2]=1065353216,a[A+472>>2]=0,a[A+476>>2]=0,r=A+380|0,a[r>>2]=0,a[r+4>>2]=0,r=A+388|0,a[r>>2]=0,a[r+4>>2]=0,r=A+396|0,a[r>>2]=0,a[r+4>>2]=0,r=A+612|0,a[r>>2]=1065353216,a[r+4>>2]=0,r=A+420|0,a[r>>2]=0,a[r+4>>2]=0,a[A+416>>2]=1065353216,r=A+428|0,a[r>>2]=0,a[r+4>>2]=0,r=A+436|0,a[r>>2]=0,a[r+4>>2]=0,r=A+444|0,a[r>>2]=0,a[r+4>>2]=0,a[A+452>>2]=0,r=A+480|0,a[r>>2]=0,a[r+4>>2]=0,r=A+488|0,a[r>>2]=0,a[r+4>>2]=0,r=A+496|0,a[r>>2]=0,a[r+4>>2]=0,b=C[e+96>>2],n=C[e+92>>2],C[c+12>>2]=n,C[c+8>>2]=b,a[c+4>>2]=0,a[c>>2]=1065353216,a[A+504>>2]=a[(n<_(0)?c+4|0:n>_(1)?c:c+12|0)>>2],a[c+4>>2]=0,a[c>>2]=1065353216,a[A+508>>2]=a[(b<_(0)?c+4|0:b>_(1)?c:c+8|0)>>2],a[A+668>>2]=0,a[A+672>>2]=0,r=a[e+120>>2],a[A+532>>2]=a[e+116>>2],a[A+536>>2]=r,i=a[e+4>>2],a[A+540>>2]=i,f[A+512|0]=o[e+124|0],r=a[e+132>>2],a[A+516>>2]=a[e+128>>2],a[A+520>>2]=r,r=a[e+140>>2],a[A+524>>2]=a[e+136>>2],a[A+528>>2]=r,i?(r=A+4|0,Qt[a[a[i>>2]+8>>2]](i,r)):(r=a[e+12>>2],a[A+4>>2]=a[e+8>>2],a[A+8>>2]=r,i=e+16|0,t=a[i+4>>2],r=A+12|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,i=e+32|0,t=a[i+4>>2],r=A+28|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,i=e+24|0,t=a[i+4>>2],r=A+20|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,i=e+40|0,t=a[i+4>>2],r=A+36|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,i=e+48|0,t=a[i+4>>2],r=A+44|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,i=e- -64|0,t=a[i+4>>2],r=A+60|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,i=e+56|0,t=a[i+4>>2],r=A+52|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,r=A+4|0),a[A+132>>2]=0,a[A+136>>2]=0,i=a[r+4>>2],a[A+68>>2]=a[r>>2],a[A+72>>2]=i,i=A+156|0,a[i>>2]=0,a[i+4>>2]=0,i=A+148|0,a[i>>2]=0,a[i+4>>2]=0,i=A+140|0,a[i>>2]=0,a[i+4>>2]=0,t=A+20|0,p=a[t+4>>2],i=A+84|0,a[i>>2]=a[t>>2],a[i+4>>2]=p,r=r+8|0,t=a[r+4>>2],i=A+76|0,a[i>>2]=a[r>>2],a[i+4>>2]=t,i=A+28|0,t=a[i+4>>2],r=A+92|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,i=A+36|0,t=a[i+4>>2],r=A+100|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,i=A+44|0,t=a[i+4>>2],r=A+108|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,i=A+52|0,t=a[i+4>>2],r=A+116|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,i=A+60|0,t=a[i+4>>2],r=A+124|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,a[A+228>>2]=a[e+100>>2],a[A+236>>2]=a[e+104>>2],a[A+240>>2]=a[e+108>>2],a[A+232>>2]=a[e+112>>2],Qt[a[a[A>>2]+8>>2]](A,a[e+72>>2]),r=a[699],a[A+568>>2]=r,a[699]=r+1,b=_(0),r=a[A+204>>2],n=C[e>>2],n!=_(0)?(a[A+204>>2]=-2&r,b=_(_(1)/n)):a[A+204>>2]=1|r,a[A+436>>2]=0,C[A+404>>2]=b,C[A+432>>2]=n*C[A+448>>2],C[A+428>>2]=n*C[A+444>>2],C[A+424>>2]=n*C[A+440>>2],n=C[e+84>>2],l=C[e+80>>2],B=C[e+76>>2],C[A+620>>2]=b*C[A+408>>2],r=A+624|0,C[r>>2]=b*C[A+412>>2],i=A+628|0,C[i>>2]=b*C[A+416>>2],e=A+632|0,a[e>>2]=0,a[A+468>>2]=0,m=B!=_(0)?_(_(1)/B):_(0),C[A+456>>2]=m,R=l!=_(0)?_(_(1)/l):_(0),C[A+460>>2]=R,Q=n!=_(0)?_(_(1)/n):_(0),C[A+464>>2]=Q,n=C[A+12>>2],l=C[A+8>>2],B=C[A+28>>2],h=C[A+20>>2],G=C[A+24>>2],v=C[A+44>>2],d=C[A+36>>2],g=C[A+40>>2],y=C[A+4>>2],a[A+564>>2]=8,a[A+368>>2]=0,a[A+352>>2]=0,a[A+336>>2]=0,u=_(m*d),s=_(R*g),k=_(Q*v),C[A+364>>2]=_(_(d*u)+_(g*s))+_(v*k),C[A+360>>2]=_(_(h*u)+_(G*s))+_(B*k),C[A+356>>2]=_(_(y*u)+_(l*s))+_(n*k),u=_(m*h),s=_(R*G),k=_(Q*B),C[A+348>>2]=_(_(d*u)+_(g*s))+_(v*k),C[A+344>>2]=_(_(h*u)+_(G*s))+_(B*k),C[A+340>>2]=_(_(y*u)+_(l*s))+_(n*k),u=d,d=_(m*y),s=g,g=_(R*l),k=v,v=_(Q*n),C[A+332>>2]=_(_(u*d)+_(s*g))+_(k*v),C[A+328>>2]=_(_(d*h)+_(g*G))+_(v*B),C[A+324>>2]=_(_(y*d)+_(l*g))+_(n*v),t=A+596|0,a[t>>2]=0,a[t+4>>2]=0,t=A+588|0,a[t>>2]=0,a[t+4>>2]=0,t=A+580|0,a[t>>2]=0,a[t+4>>2]=0,a[A+572>>2]=0,a[A+576>>2]=0,n=C[A+408>>2],l=C[A+412>>2],C[i>>2]=b*C[A+416>>2],C[r>>2]=b*l,C[A+620>>2]=b*n,a[A+664>>2]=0,r=A+656|0,a[r>>2]=0,a[r+4>>2]=0,r=A+648|0,a[r>>2]=0,a[r+4>>2]=0,A=A+640|0,a[A>>2]=0,a[A+4>>2]=0,a[e>>2]=0,a[e+4>>2]=0,Y=c+16|0}(A,e)}function Ji(A,e,r){xi(A+4|0,A+372|0,A+388|0,e,r)}function xi(A,e,r,i,f){var t,n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=0;t=Y-16|0,Y=t,n=C[A+52>>2],o=C[A+56>>2],b=C[A+48>>2],c=C[e>>2],l=C[e+4>>2],u=C[e+8>>2],a[f+60>>2]=0,C[f+56>>2]=o+_(u*i),C[f+52>>2]=n+_(l*i),C[f+48>>2]=b+_(c*i),b=C[r>>2],s=C[r+4>>2],k=C[r+8>>2],n=_(_(_(b*b)+_(s*s))+_(k*k)),n=n>_(1.1920928955078125e-7)?_(y(n)):_(0),o=_(n*i)>_(.7853981852531433)?_(_(.7853981852531433)/i):n,n=o<_(.0010000000474974513)?_(_(i*_(.5))+_(o*_(_(_(_(i*i)*i)*_(-.02083333395421505))*o))):_(dr(_(_(o*_(.5))*i))/o),tt(A,t),c=C[t+12>>2],l=Cr(_(_(o*i)*_(.5))),u=_(b*n),v=C[t>>2],s=_(s*n),d=C[t+4>>2],n=_(k*n),k=C[t+8>>2],o=_(_(_(_(c*l)-_(u*v))-_(s*d))-_(n*k)),b=_(_(_(_(n*c)+_(l*k))+_(u*d))-_(s*v)),i=_(_(_(_(l*v)+_(u*c))+_(s*k))-_(n*d)),n=_(_(_(n*v)+_(_(s*c)+_(l*d)))-_(u*k)),c=_(_(o*o)+_(_(b*b)+_(_(i*i)+_(n*n)))),c>_(1.1920928955078125e-7)&&(c=_(_(1)/_(y(c))),o=_(o*c),b=_(b*c),n=_(n*c),i=_(i*c),c=_(_(o*o)+_(_(b*b)+_(_(n*n)+_(i*i))))),c>_(1.1920928955078125e-7)?(a[f+12>>2]=0,a[f+44>>2]=0,a[f+28>>2]=0,l=_(_(2)/c),c=_(b*l),u=_(n*c),v=_(i*l),s=_(o*v),C[f+36>>2]=u+s,d=_(i*c),l=_(n*l),k=_(o*l),C[f+32>>2]=d-k,C[f+24>>2]=u-s,u=_(i*l),o=_(o*c),C[f+16>>2]=u+o,C[f+8>>2]=d+k,C[f+4>>2]=u-o,i=_(i*v),n=_(n*l),C[f+40>>2]=_(1)-_(i+n),o=i,i=_(b*c),C[f+20>>2]=_(1)-_(o+i),C[f>>2]=_(1)-_(n+i)):(e=a[A+4>>2],a[f>>2]=a[A>>2],a[f+4>>2]=e,r=A+8|0,g=a[r+4>>2],e=f+8|0,a[e>>2]=a[r>>2],a[e+4>>2]=g,e=a[A+20>>2],a[f+16>>2]=a[A+16>>2],a[f+20>>2]=e,r=A+24|0,g=a[r+4>>2],e=f+24|0,a[e>>2]=a[r>>2],a[e+4>>2]=g,e=a[A+36>>2],a[f+32>>2]=a[A+32>>2],a[f+36>>2]=e,A=A+40|0,r=a[A+4>>2],e=f+40|0,a[e>>2]=a[A>>2],a[e+4>>2]=r),Y=t+16|0}function Ui(A,e){var r,i=0,f=0,t=0,n=0,o=0,c=0,b=0,l=_(0),u=0;r=Y-32|0,Y=r,e!=_(0)&&(i=a[A+540>>2],i&&Qt[a[a[i>>2]+8>>2]](i,A+4|0),a[A+384>>2]=0,i=A+380|0,e=_(_(1)/e),n=A+60|0,o=A+124|0,C[i>>2]=e*_(C[n>>2]-C[o>>2]),C[A+376>>2]=e*_(C[A+56>>2]-C[A+120>>2]),c=A+52|0,b=A+116|0,C[A+372>>2]=e*_(C[c>>2]-C[b>>2]),Mi(A+68|0,A+4|0,r+16|0,r+12|0),a[A+400>>2]=0,f=A+396|0,l=C[r+12>>2],C[f>>2]=e*_(l*C[r+24>>2]),C[A+392>>2]=e*_(l*C[r+20>>2]),C[A+388>>2]=e*_(l*C[r+16>>2]),u=a[i+4>>2],t=A+140|0,a[t>>2]=a[i>>2],a[t+4>>2]=u,i=a[A+376>>2],a[A+132>>2]=a[A+372>>2],a[A+136>>2]=i,i=a[A+392>>2],a[A+148>>2]=a[A+388>>2],a[A+152>>2]=i,t=a[f+4>>2],i=A+156|0,a[i>>2]=a[f>>2],a[i+4>>2]=t,i=a[A+8>>2],a[A+68>>2]=a[A+4>>2],a[A+72>>2]=i,f=A+12|0,t=a[f+4>>2],i=A+76|0,a[i>>2]=a[f>>2],a[i+4>>2]=t,f=A+20|0,t=a[f+4>>2],i=A+84|0,a[i>>2]=a[f>>2],a[i+4>>2]=t,f=A+28|0,t=a[f+4>>2],i=A+92|0,a[i>>2]=a[f>>2],a[i+4>>2]=t,f=A+44|0,t=a[f+4>>2],i=A+108|0,a[i>>2]=a[f>>2],a[i+4>>2]=t,i=A+100|0,A=A+36|0,f=a[A+4>>2],a[i>>2]=a[A>>2],a[i+4>>2]=f,A=a[n+4>>2],a[o>>2]=a[n>>2],a[o+4>>2]=A,A=a[c+4>>2],a[b>>2]=a[c>>2],a[b+4>>2]=A),Y=r+32|0}function Mi(A,e,r,i){var f,t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),G=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0);f=Y+-64|0,Y=f,d=C[e+24>>2],g=C[e+20>>2],B=C[e+40>>2],m=C[e+36>>2],b=C[A+40>>2],l=C[A+20>>2],k=C[A+36>>2],u=C[A+24>>2],R=C[e+8>>2],G=C[e>>2],p=C[e+4>>2],F=C[e+16>>2],W=C[e+32>>2],n=C[A+8>>2],o=C[A+4>>2],v=C[A+32>>2],s=C[A+16>>2],c=C[A>>2],a[f+60>>2]=0,a[f+44>>2]=0,D=_(_(l*b)-_(u*k)),E=_(_(u*v)-_(b*s)),Z=_(_(k*s)-_(l*v)),t=_(_(1)/_(_(_(c*D)+_(o*E))+_(n*Z))),w=_(_(_(u*o)-_(l*n))*t),u=_(_(_(s*n)-_(u*c))*t),l=_(_(_(l*c)-_(s*o))*t),C[f+56>>2]=_(_(W*w)+_(m*u))+_(B*l),s=_(_(_(k*n)-_(b*o))*t),n=_(_(_(b*c)-_(v*n))*t),o=_(_(_(v*o)-_(k*c))*t),C[f+52>>2]=_(_(W*s)+_(m*n))+_(B*o),C[f+40>>2]=_(_(w*F)+_(u*g))+_(l*d),C[f+36>>2]=_(_(s*F)+_(n*g))+_(o*d),a[f+28>>2]=0,c=_(D*t),b=_(E*t),t=_(Z*t),C[f+48>>2]=_(_(W*c)+_(m*b))+_(B*t),C[f+32>>2]=_(_(c*F)+_(b*g))+_(t*d),C[f+24>>2]=_(R*l)+_(_(G*w)+_(p*u)),C[f+20>>2]=_(R*o)+_(_(G*s)+_(p*n)),C[f+16>>2]=_(R*t)+_(_(G*c)+_(p*b)),tt(f+16|0,f),c=C[f>>2],o=C[f+4>>2],n=C[f+8>>2],b=C[f+12>>2],t=_(_(1)/_(y(_(_(_(_(c*c)+_(o*o))+_(n*n))+_(b*b))))),n=_(n*t),C[f+8>>2]=n,o=_(o*t),C[f+4>>2]=o,c=_(c*t),C[f>>2]=c,t=_(b*t),C[f+12>>2]=t,t=Ni(_(Q(_(h(t,_(-1))),_(1)))),C[i>>2]=t+t,a[r+12>>2]=0,C[r+8>>2]=n,C[r+4>>2]=o,C[r>>2]=c,t=_(_(_(c*c)+_(o*o))+_(n*n)),t<_(1.4210854715202004e-14)?(a[r+8>>2]=0,a[r+12>>2]=0,a[r>>2]=1065353216,a[r+4>>2]=0):(t=_(_(1)/_(y(t))),C[r+8>>2]=n*t,C[r+4>>2]=o*t,C[r>>2]=c*t),Y=f- -64|0}function Si(A,e){var r=_(0),i=0,f=_(0),t=_(0),n=_(0);r=C[A+404>>2],r!=_(0)&&(f=C[e>>2],t=C[e+4>>2],n=C[e+8>>2],a[A+436>>2]=0,r=_(_(1)/r),C[A+432>>2]=n*r,C[A+428>>2]=r*t,C[A+424>>2]=r*f),i=a[e+4>>2],a[A+440>>2]=a[e>>2],a[A+444>>2]=i,e=e+8|0,i=a[e+4>>2],A=A+448|0,a[A>>2]=a[e>>2],a[A+4>>2]=i}function Xi(A,e){var r=0,i=_(0),f=_(0),t=_(0),n=_(0),c=_(0),b=_(0),l=_(0),u=_(0);if(l=C[A+504>>2],f=Vi(_(_(1)-l),e),n=_(f*C[A+372>>2]),C[A+372>>2]=n,r=A+376|0,i=_(f*C[r>>2]),C[r>>2]=i,r=A+380|0,f=_(f*C[r>>2]),C[r>>2]=f,u=C[A+508>>2],t=Vi(_(_(1)-u),e),e=_(t*C[A+388>>2]),C[A+388>>2]=e,r=A+392|0,c=_(t*C[r>>2]),C[r>>2]=c,r=A+396|0,t=_(t*C[r>>2]),C[r>>2]=t,o[A+512|0]&&(_(_(_(e*e)+_(c*c))+_(t*t))>2]^1|_(_(_(n*n)+_(i*i))+_(f*f))>2]^1||(b=C[A+516>>2],t=_(t*b),C[A+396>>2]=t,c=_(c*b),C[A+392>>2]=c,e=_(e*b),C[A+388>>2]=e,f=_(f*b),C[A+380>>2]=f,i=_(i*b),C[A+376>>2]=i,n=_(n*b),C[A+372>>2]=n),b=_(y(_(_(_(n*n)+_(i*i))+_(f*f)))),b_(.004999999888241291)?(l=f,f=_(_(1)/b),C[A+380>>2]=l-_(_(l*f)*_(.004999999888241291)),C[A+376>>2]=i-_(_(i*f)*_(.004999999888241291)),C[A+372>>2]=n-_(_(n*f)*_(.004999999888241291))):(r=A+372|0,a[r>>2]=0,a[r+4>>2]=0,r=r+8|0,a[r>>2]=0,a[r+4>>2]=0)),i=_(y(_(_(_(e*e)+_(c*c))+_(t*t)))),i_(.004999999888241291))return i=_(_(1)/i),C[A+396>>2]=t-_(_(t*i)*_(.004999999888241291)),C[A+392>>2]=c-_(_(c*i)*_(.004999999888241291)),void(C[A+388>>2]=e-_(_(e*i)*_(.004999999888241291)));A=A+388|0,a[A>>2]=0,a[A+4>>2]=0,A=A+8|0,a[A>>2]=0,a[A+4>>2]=0}}function Ti(A){var e=0;3&o[A+204|0]||(C[A+472>>2]=_(C[A+424>>2]*C[A+408>>2])+C[A+472>>2],e=A+476|0,C[e>>2]=_(C[A+428>>2]*C[A+412>>2])+C[e>>2],e=A+480|0,C[e>>2]=_(C[A+432>>2]*C[A+416>>2])+C[e>>2])}function ji(A,e){!function(A,e){var r=0,i=0,f=0,t=0,n=0,c=_(0),b=_(0),l=_(0),u=0,s=_(0),k=_(0),v=_(0),d=0,g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=0;2&o[A+204|0]?(r=a[A+8>>2],a[A+68>>2]=a[A+4>>2],a[A+72>>2]=r,i=A+12|0,f=a[i+4>>2],r=A+76|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,i=A+20|0,f=a[i+4>>2],r=A+84|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,i=A+28|0,f=a[i+4>>2],r=A+92|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,i=A+36|0,f=a[i+4>>2],r=A+100|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,i=A+44|0,f=a[i+4>>2],r=A+108|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,i=A+52|0,f=a[i+4>>2],r=A+116|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,i=A+60|0,f=a[i+4>>2],r=A+124|0,a[r>>2]=a[i>>2],a[r+4>>2]=f):(r=a[e+4>>2],a[A+68>>2]=a[e>>2],a[A+72>>2]=r,i=e+8|0,f=a[i+4>>2],r=A+76|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,i=e+24|0,f=a[i+4>>2],r=A+92|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,i=a[e+20>>2],r=A+84|0,a[r>>2]=a[e+16>>2],a[r+4>>2]=i,i=a[e+36>>2],r=A+100|0,a[r>>2]=a[e+32>>2],a[r+4>>2]=i,i=e+40|0,f=a[i+4>>2],r=A+108|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,i=e+56|0,f=a[i+4>>2],r=A+124|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,i=a[e+52>>2],r=A+116|0,a[r>>2]=a[e+48>>2],a[r+4>>2]=i),r=a[A+392>>2],a[A+148>>2]=a[A+388>>2],a[A+152>>2]=r,r=a[A+376>>2],a[A+132>>2]=a[A+372>>2],a[A+136>>2]=r,i=A+396|0,f=a[i+4>>2],r=A+156|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,i=A+380|0,f=a[i+4>>2],r=A+140|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,f=e+8|0,d=a[f+4>>2],r=A+12|0,a[r>>2]=a[f>>2],a[r+4>>2]=d,i=a[e+4>>2],a[A+4>>2]=a[e>>2],a[A+8>>2]=i,d=e+24|0,n=a[d+4>>2],i=A+28|0,a[i>>2]=a[d>>2],a[i+4>>2]=n,n=a[e+20>>2],f=A+20|0,a[f>>2]=a[e+16>>2],a[f+4>>2]=n,t=e+40|0,u=a[t+4>>2],d=A+44|0,n=d,a[n>>2]=a[t>>2],a[n+4>>2]=u,u=a[e+36>>2],n=A+36|0,t=n,a[t>>2]=a[e+32>>2],a[t+4>>2]=u,u=e+56|0,F=a[u+4>>2],t=A+60|0,a[t>>2]=a[u>>2],a[t+4>>2]=F,u=a[e+52>>2],t=A+52|0,a[t>>2]=a[e+48>>2],a[t+4>>2]=u,g=C[A+8>>2],B=C[r>>2],m=C[i>>2],R=C[f>>2],Q=C[A+24>>2],s=C[d>>2],G=C[A+464>>2],k=C[n>>2],v=C[A+40>>2],y=C[A+460>>2],h=C[A+4>>2],p=C[A+456>>2],a[A+368>>2]=0,a[A+352>>2]=0,a[A+336>>2]=0,c=_(p*k),b=_(y*v),l=_(G*s),C[A+364>>2]=_(_(k*c)+_(v*b))+_(s*l),C[A+360>>2]=_(_(R*c)+_(Q*b))+_(m*l),C[A+356>>2]=_(_(h*c)+_(g*b))+_(B*l),c=_(p*R),b=_(y*Q),l=_(G*m),C[A+348>>2]=_(_(k*c)+_(v*b))+_(s*l),C[A+344>>2]=_(_(R*c)+_(Q*b))+_(m*l),C[A+340>>2]=_(_(h*c)+_(g*b))+_(B*l),c=k,k=_(h*p),b=v,v=_(g*y),l=s,s=_(B*G),C[A+332>>2]=_(_(c*k)+_(b*v))+_(l*s),C[A+328>>2]=_(_(k*R)+_(v*Q))+_(s*m),C[A+324>>2]=_(_(h*k)+_(g*v))+_(B*s)}(A,e)}function Oi(A,e,r){var i=_(0),f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0);a[A+12>>2]=0,f=C[e+388>>2],i=C[e+456>>2],k=i!=_(0)?_(_(1)/i):_(0),v=C[e+20>>2],t=_(k*v),c=C[e+4>>2],i=C[e+460>>2],R=i!=_(0)?_(_(1)/i):_(0),d=C[e+24>>2],b=_(R*d),l=C[e+8>>2],i=C[e+464>>2],Q=i!=_(0)?_(_(1)/i):_(0),g=C[e+28>>2],u=_(Q*g),B=C[e+12>>2],i=C[e+392>>2],s=_(_(f*_(_(_(t*c)+_(b*l))+_(u*B)))+_(_(_(_(t*v)+_(b*d))+_(u*g))*i)),m=C[e+36>>2],n=b,b=C[e+40>>2],o=u,u=C[e+44>>2],n=_(_(_(t*m)+_(n*b))+_(o*u)),t=C[e+396>>2],h=_(s+_(n*t)),o=_(k*c),s=_(R*l),n=_(Q*B),s=_(_(_(_(_(_(o*c)+_(s*l))+_(n*B))*f)+_(i*_(_(_(o*v)+_(s*d))+_(n*g))))+_(_(_(_(o*m)+_(s*b))+_(n*u))*t)),o=_(_(f*h)-_(i*s)),C[A+8>>2]=o,n=f,f=_(k*m),k=_(c*f),c=_(R*b),k=_(k+_(l*c)),l=_(Q*u),v=_(_(_(n*_(k+_(B*l)))+_(i*_(_(_(f*v)+_(c*d))+_(l*g))))+_(t*_(_(_(f*m)+_(c*b))+_(l*u)))),f=_(_(t*s)-_(n*v)),C[A+4>>2]=f,i=_(_(i*v)-_(t*h)),C[A>>2]=i,t=_(_(o*o)+_(_(i*i)+_(f*f))),t>_(r*r)&&(r=_(_(_(1)/_(y(t)))*r),C[A+8>>2]=o*r,C[A+4>>2]=f*r,C[A>>2]=i*r)}function Hi(A,e,r){var i,f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),V=_(0),N=_(0);i=Y-16|0,Y=i,b=C[e+464>>2],f=C[e+460>>2],h=C[e+396>>2],G=C[e+392>>2],o=C[e+456>>2],y=C[e+388>>2],tt(e+4|0,i),a[A+12>>2]=0,l=C[i+12>>2],u=C[i+4>>2],s=C[i+8>>2],n=_(_(_(y*l)-_(h*u))+_(G*s)),k=C[i>>2],B=_(_(_(G*u)+_(y*k))+_(h*s)),c=_(_(_(h*l)-_(G*k))+_(y*u)),R=_(_(_(G*l)-_(y*s))+_(h*k)),t=_(_(_(u*n)+_(_(s*B)+_(l*c)))-_(k*R)),d=_(t*_(0)),v=_(_(_(s*R)+_(_(k*B)+_(l*n)))-_(u*c)),Q=_(v*_(0)),f=f!=_(0)?_(_(1)/f):_(0),n=_(_(_(k*c)+_(_(u*B)+_(l*R)))-_(s*n)),B=_(d+_(Q+_(f*n))),o=o!=_(0)?_(_(1)/o):_(0),Z=_(_(_(_(_(Q-_(o*n))+_(0))+_(B+_(0)))*r)+_(0)),c=b!=_(0)?_(_(1)/b):_(0),g=_(n*_(0)),R=_(_(t*c)+_(Q+g)),w=_(d+_(_(o*v)+g)),b=_(_(_(t*w)-_(v*R))*r),p=_(t*_(-0)),V=_(o+_(_(g+_(_(o*_(0))+p))*r)),F=_(n*_(-0)),D=_(_(_(_(_(F+_(f*v))+_(0))-w)*r)+_(0)),g=_(_(_(_(g+_(_(0)-_(f*t)))+R)*r)+_(0)),E=_(_(_(_(_(d+_(0))-_(c*v))+w)*r)+_(0)),W=_(v*_(-0)),f=_(f+_(_(W+_(_(f*_(0))+d))*r)),d=_(_(_(_(_(c*n)+_(p+_(0)))-B)*r)+_(0)),p=_(_(g*E)-_(f*d)),c=_(c+_(_(_(c*_(0))+_(F+Q))*r)),F=_(_(f*c)-_(D*E)),Q=_(_(_(_(W+_(_(o*t)+_(0)))-R)*r)+_(0)),W=_(_(D*d)-_(c*g)),o=_(_(Z*p)+_(_(V*F)+_(Q*W))),o=_(m(o))>_(1.1920928955078125e-7)?_(_(1)/o):o,N=t,t=_(_(_(n*R)-_(t*B))*r),r=_(_(_(v*B)-_(n*w))*r),f=_(N-_(_(_(Z*_(_(g*b)-_(f*t)))+_(_(V*_(_(f*r)-_(D*b)))+_(Q*_(_(D*t)-_(g*r)))))*o)),n=_(n-_(_(_(Z*_(_(E*t)-_(d*b)))+_(_(V*_(_(c*b)-_(E*r)))+_(Q*_(_(d*r)-_(c*t)))))*o)),r=_(v-_(_(_(r*p)+_(_(t*F)+_(b*W)))*o)),t=_(_(_(l*f)+_(k*n))-_(u*r)),v=_(_(_(-_(k*r))-_(u*n))-_(s*f)),b=_(_(_(l*r)+_(u*f))-_(s*n)),r=_(_(_(s*r)+_(l*n))-_(k*f)),C[A+8>>2]=_(_(_(_(l*t)-_(v*s))-_(b*u))+_(r*k))-h,C[A+4>>2]=_(_(_(_(l*r)-_(v*u))-_(t*k))+_(b*s))-G,C[A>>2]=_(_(_(_(l*b)-_(v*k))-_(r*s))+_(t*u))-y,Y=i+16|0}function zi(A,e,r){var i=_(0),f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0);a[A+12>>2]=0,i=C[e+456>>2],p=i!=_(0)?_(_(1)/i):_(0),s=C[e+36>>2],G=_(p*s),k=C[e+4>>2],i=C[e+460>>2],o=i!=_(0)?_(_(1)/i):_(0),B=C[e+40>>2],F=_(o*B),t=C[e+8>>2],i=C[e+464>>2],v=i!=_(0)?_(_(1)/i):_(0),c=C[e+44>>2],w=_(v*c),f=C[e+12>>2],n=_(_(_(G*k)+_(F*t))+_(w*f)),i=C[e+388>>2],b=C[e+20>>2],R=_(p*b),l=C[e+24>>2],y=_(o*l),u=C[e+28>>2],Q=_(v*u),W=_(_(_(R*k)+_(y*t))+_(Q*f)),D=_(i*W),d=C[e+392>>2],h=_(_(_(R*b)+_(y*l))+_(Q*u)),g=C[e+396>>2],y=_(_(_(R*s)+_(y*B))+_(Q*c)),Z=_(g*y),R=_(_(D+_(d*h))+Z),E=D,Q=_(p*k),D=_(o*t),v=_(v*f),t=_(_(_(Q*k)+_(D*t))+_(v*f)),p=_(n+_(_(_(_(n*_(0))+_(E-_(t*d)))+R)*r)),o=_(_(_(Q*b)+_(D*l))+_(v*u)),E=_(i*n),l=_(_(_(G*b)+_(F*l))+_(w*u)),b=_(d*l),f=_(_(_(G*s)+_(F*B))+_(w*c)),k=_(_(E+b)+_(g*f)),b=_(o+_(_(k+_(b+_(_(o*_(0))-_(h*g))))*r)),w=_(d*o),c=_(_(_(Q*s)+_(D*B))+_(v*c)),u=_(g*c),s=_(_(_(i*t)+w)+u),F=_(r*_(0)),B=_(_(R+_(_(_(g*s)-_(i*k))*r))-_(F+R)),u=_(y+_(_(s+_(_(_(y*_(0))+u)-_(f*i)))*r)),o=_(h+_(_(_(_(h*_(0))+_(g*o))-_(l*i))*r)),G=_(c+_(_(_(_(d*f)+_(_(c*_(0))-Z))-R)*r)),Q=_(_(b*u)-_(o*G)),v=_(t+_(_(_(d*n)+_(_(t*_(0))-_(W*g)))*r)),f=_(f+_(_(_(f*_(0))+_(_(i*y)-_(c*d)))*r)),h=_(l+_(_(_(_(l*_(0))+_(_(i*h)-w))-s)*r)),l=_(_(o*f)-_(h*u)),c=_(W+_(_(_(_(_(W*_(0))+_(g*t))-E)-k)*r)),W=_(_(h*G)-_(b*f)),n=_(_(p*Q)+_(_(v*l)+_(c*W))),t=_(m(n))>_(1.1920928955078125e-7)?_(_(1)/n):n,n=_(_(s+_(_(_(d*k)-_(g*R))*r))-_(F+s)),r=_(_(k+_(_(_(i*R)-_(d*s))*r))-_(F+k)),C[A+8>>2]=_(g-_(_(_(p*_(_(b*B)-_(o*n)))+_(_(v*_(_(o*r)-_(h*B)))+_(c*_(_(h*n)-_(b*r)))))*t))-g,C[A+4>>2]=_(d-_(_(_(p*_(_(u*n)-_(G*B)))+_(_(v*_(_(f*B)-_(u*r)))+_(c*_(_(G*r)-_(f*n)))))*t))-d,C[A>>2]=_(i-_(_(_(r*Q)+_(_(n*l)+_(B*W)))*t))-i}function Pi(A,e){var r=0,i=0,t=0,n=0,c=0;i=a[A+548>>2];A:{e:if(!((0|i)<1)){for(t=a[A+556>>2],r=i;;){if((0|e)!=a[t>>2]){if(t=t+4|0,r=r+-1|0,r)continue;break e}break}if(r)break A}if(a[A+552>>2]==(0|i)&&(n=i?i<<1:1,!((0|i)>=(0|n)))){if(n&&(c=dA(n<<2),i=a[A+548>>2]),(0|i)>=1)for(t=0,r=i;a[t+c>>2]=a[a[A+556>>2]+t>>2],t=t+4|0,r=r+-1|0,r;);r=a[A+556>>2],r&&(o[A+560|0]&&(CA(r),i=a[A+548>>2]),a[A+556>>2]=0),a[A+556>>2]=c,a[A+552>>2]=n,f[A+560|0]=1}a[a[A+556>>2]+(i<<2)>>2]=e,a[A+548>>2]=i+1,r=a[e+32>>2],c=a[e+28>>2];e:if((0|A)!=(0|c)){if(e=a[r+288>>2],(0|e)==a[r+292>>2]&&(n=e?e<<1:1,!((0|e)>=(0|n)))){if(n?(i=dA(n<<2),e=a[r+288>>2]):i=0,(0|e)>=1)for(t=0,A=e;a[i+t>>2]=a[a[r+296>>2]+t>>2],t=t+4|0,A=A+-1|0,A;);A=a[r+296>>2],A&&(o[r+300|0]&&(CA(A),e=a[r+288>>2]),a[r+296>>2]=0),a[r+296>>2]=i,a[r+292>>2]=n,f[r+300|0]=1}A=r,r=c}else{if(e=a[A+288>>2],(0|e)!=a[A+292>>2])break e;if(n=e?e<<1:1,(0|e)>=(0|n))break e;if(n?(c=dA(n<<2),e=a[A+288>>2]):c=0,(0|e)>=1)for(t=0,i=e;a[t+c>>2]=a[a[A+296>>2]+t>>2],t=t+4|0,i=i+-1|0,i;);i=a[A+296>>2],i&&(o[A+300|0]&&(CA(i),e=a[A+288>>2]),a[A+296>>2]=0),a[A+296>>2]=c,a[A+292>>2]=n,f[A+300|0]=1}a[A+288>>2]=e+1,a[A+280>>2]=(-1^e)>>>31,a[a[A+296>>2]+(e<<2)>>2]=r}}function Ki(A,e){var r=0,i=0,f=0,t=0,n=0;t=a[A+548>>2];A:if(!((0|t)<1)){for(f=a[A+556>>2],i=f;;){if((0|e)!=a[i>>2]){if(i=i+4|0,r=r+1|0,(0|t)!=(0|r))continue;break A}break}if(!((0|r)>=(0|t))){r=0,i=f;e:{for(;;){if((0|e)!=a[i>>2]){if(i=i+4|0,r=r+1|0,(0|t)!=(0|r))continue;break e}break}(0|t)<=(0|r)||(n=i,r=f,i=t+-1|0,f=i<<2,a[n>>2]=a[r+f>>2],a[A+548>>2]=i,a[f+a[A+556>>2]>>2]=e)}if(t=a[e+32>>2],f=a[e+28>>2],(0|A)==(0|f)){e=a[A+288>>2];e:if(!((0|e)<1)){for(r=0,f=a[A+296>>2],i=f;;){if(a[i>>2]!=(0|t)){if(i=i+4|0,r=r+1|0,(0|r)!=(0|e))continue;break e}break}(0|e)<=(0|r)||(r=f,e=e+-1|0,f=e<<2,a[i>>2]=a[r+f>>2],a[A+288>>2]=e,a[f+a[A+296>>2]>>2]=t)}return void(a[A+280>>2]=(0|e)>0)}e=a[t+288>>2];e:if(!((0|e)<1)){for(r=0,A=a[t+296>>2],i=A;;){if(a[i>>2]!=(0|f)){if(i=i+4|0,r=r+1|0,(0|r)!=(0|e))continue;break e}break}(0|e)<=(0|r)||(r=A,e=e+-1|0,A=e<<2,a[i>>2]=a[r+A>>2],a[t+288>>2]=e,a[A+a[t+296>>2]>>2]=f)}a[t+280>>2]=(0|e)>0}}}function Li(A){var e=0;a[A>>2]=20180,f[A+20|0]=1,a[A+16>>2]=0,f[A+40|0]=1,e=A+8|0,a[e>>2]=0,a[e+4>>2]=0,a[A+36>>2]=0,f[A+60|0]=1,e=A+28|0,a[e>>2]=0,a[e+4>>2]=0,a[A+56>>2]=0,f[A+80|0]=1,e=A+48|0,a[e>>2]=0,a[e+4>>2]=0,a[A+76>>2]=0,f[A+100|0]=1,e=A+68|0,a[e>>2]=0,a[e+4>>2]=0,a[A+96>>2]=0,f[A+120|0]=1,e=A+88|0,a[e>>2]=0,a[e+4>>2]=0,a[A+116>>2]=0,f[A+140|0]=1,e=A+108|0,a[e>>2]=0,a[e+4>>2]=0,a[A+136>>2]=0,e=A+128|0,a[e>>2]=0,a[e+4>>2]=0,f[A+160|0]=1,a[A+156>>2]=0,e=A+148|0,a[e>>2]=0,a[e+4>>2]=0,f[A+180|0]=1,a[A+176>>2]=0,e=A+168|0,a[e>>2]=0,a[e+4>>2]=0,f[A+208|0]=1,a[A+232>>2]=0,a[A+204>>2]=0,e=A+196|0,a[e>>2]=0,a[e+4>>2]=0,a[A+224>>2]=0,a[A+212>>2]=534,a[A+216>>2]=535,a[A+220>>2]=536}function qi(A){A|=0;var e=0;return a[A>>2]=20180,e=a[A+204>>2],e&&(o[A+208|0]&&CA(e),a[A+204>>2]=0),a[A+204>>2]=0,a[A+196>>2]=0,a[A+200>>2]=0,f[A+208|0]=1,e=a[A+176>>2],e&&(o[A+180|0]&&CA(e),a[A+176>>2]=0),a[A+176>>2]=0,a[A+168>>2]=0,a[A+172>>2]=0,f[A+180|0]=1,e=a[A+156>>2],e&&(o[A+160|0]&&CA(e),a[A+156>>2]=0),a[A+156>>2]=0,a[A+148>>2]=0,a[A+152>>2]=0,f[A+160|0]=1,e=a[A+136>>2],e&&(o[A+140|0]&&CA(e),a[A+136>>2]=0),a[A+136>>2]=0,a[A+128>>2]=0,a[A+132>>2]=0,f[A+140|0]=1,e=a[A+116>>2],e&&(o[A+120|0]&&CA(e),a[A+116>>2]=0),a[A+116>>2]=0,a[A+108>>2]=0,a[A+112>>2]=0,f[A+120|0]=1,e=a[A+96>>2],e&&(o[A+100|0]&&CA(e),a[A+96>>2]=0),a[A+96>>2]=0,a[A+88>>2]=0,a[A+92>>2]=0,f[A+100|0]=1,e=a[A+76>>2],e&&(o[A+80|0]&&CA(e),a[A+76>>2]=0),a[A+76>>2]=0,a[A+68>>2]=0,a[A+72>>2]=0,f[A+80|0]=1,e=a[A+56>>2],e&&(o[A+60|0]&&CA(e),a[A+56>>2]=0),a[A+56>>2]=0,a[A+48>>2]=0,a[A+52>>2]=0,f[A+60|0]=1,e=a[A+36>>2],e&&(o[A+40|0]&&CA(e),a[A+36>>2]=0),a[A+36>>2]=0,a[A+28>>2]=0,a[A+32>>2]=0,f[A+40|0]=1,e=a[A+16>>2],e&&(o[A+20|0]&&CA(e),a[A+16>>2]=0),a[A+16>>2]=0,a[A+8>>2]=0,a[A+12>>2]=0,f[A+20|0]=1,0|A}function $i(A,e,r,i,t,n,c,b,l,u,s,k){var v=0,d=0,g=0,m=0,R=0;if(d=a[A+68>>2],v=d,(0|d)==a[A+72>>2]&&(v=d,g=d?d<<1:1,!((0|d)>=(0|g)))){if(g?(R=dA(B(g,152)),v=a[A+68>>2]):v=d,m=v,(0|m)>=1)for(v=0;J(v+R|0,a[A+76>>2]+v|0,152),v=v+152|0,m=m+-1|0,m;);v=a[A+76>>2],v&&(o[A+80|0]&&CA(v),a[A+76>>2]=0),a[A+76>>2]=R,a[A+72>>2]=g,f[A+80|0]=1,v=a[A+68>>2]}a[A+68>>2]=v+1,d=a[A+76>>2]+B(d,152)|0,a[d+140>>2]=t,function(A,e,r,i,f,t,n,c,b,l,u,s){var k,v,d,g=0,m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=0,D=_(0),E=_(0),Z=_(0),Y=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0),U=_(0),M=_(0),S=_(0),X=_(0),T=_(0),j=0,O=_(0),H=_(0),z=_(0),P=_(0),K=_(0);a[e+148>>2]=f,a[e+144>>2]=i,a[e+96>>2]=0,a[e+100>>2]=0,T=C[t+84>>2],d=a[t+84>>2],a[e+104>>2]=d,v=a[A+16>>2],A=a[240+(v+B(f,244)|0)>>2],k=a[240+(B(i,244)+v|0)>>2],a[e+132>>2]=0,g=e+16|0,k?(w=a[r+4>>2],a[g>>2]=a[r>>2],a[g+4>>2]=w,w=r+8|0,j=a[w+4>>2],g=g+8|0,a[g>>2]=a[w>>2],a[g+4>>2]=j,h=C[n+8>>2],G=C[n>>2],y=C[n+4>>2],a[e+12>>2]=0,Y=C[e+20>>2],D=C[e+16>>2],N=_(_(G*Y)-_(y*D)),C[e+8>>2]=N,E=C[e+24>>2],G=_(_(h*D)-_(G*E)),C[e+4>>2]=G,h=_(_(y*E)-_(h*Y)),C[e>>2]=h,y=C[k+612>>2],R=C[k+364>>2],Q=C[k+356>>2],m=C[k+360>>2],I=C[k+608>>2],J=C[k+348>>2],x=C[k+340>>2],p=C[k+344>>2],F=C[k+332>>2],U=C[k+328>>2],Z=C[k+604>>2],W=C[k+324>>2],a[e+76>>2]=0,F=_(Z*_(_(_(h*W)+_(G*U))+_(N*F))),C[e+64>>2]=F,U=_(I*_(_(_(h*x)+_(G*p))+_(N*J))),C[e+68>>2]=U,Z=_(y*_(_(_(h*Q)+_(G*m))+_(N*R))),C[e+72>>2]=Z):(a[e+64>>2]=0,a[e+68>>2]=0,a[e>>2]=0,a[e+4>>2]=0,w=e+72|0,a[w>>2]=0,a[w+4>>2]=0,w=e+8|0,a[w>>2]=0,a[w+4>>2]=0,a[g>>2]=0,a[g+4>>2]=0,g=e+24|0,a[g>>2]=0,a[g+4>>2]=0),A?(R=C[r>>2],Q=C[r+4>>2],m=C[r+8>>2],a[e+60>>2]=0,I=_(-m),C[e+56>>2]=I,J=_(-Q),C[e+52>>2]=J,x=_(-R),C[e+48>>2]=x,p=C[c+8>>2],V=C[c+4>>2],W=C[c>>2],a[e+44>>2]=0,y=_(_(V*R)-_(W*Q)),C[e+40>>2]=y,R=_(_(W*m)-_(p*R)),C[e+36>>2]=R,Q=_(_(p*Q)-_(V*m)),C[e+32>>2]=Q,V=C[A+332>>2],W=C[A+328>>2],p=C[A+608>>2],S=C[A+348>>2],M=C[A+340>>2],X=C[A+344>>2],m=C[A+612>>2],O=C[A+364>>2],H=C[A+356>>2],z=C[A+360>>2],P=C[A+604>>2],K=C[A+324>>2],a[e+92>>2]=0,m=_(m*_(_(_(Q*H)+_(R*z))+_(y*O))),C[e+88>>2]=m,p=_(p*_(_(_(Q*M)+_(R*X))+_(y*S))),C[e+84>>2]=p,V=_(P*_(_(_(Q*K)+_(R*W))+_(y*V))),C[e+80>>2]=V):(a[e+80>>2]=0,a[e+84>>2]=0,a[e+32>>2]=0,a[e+36>>2]=0,g=e+88|0,a[g>>2]=0,a[g+4>>2]=0,g=e+40|0,a[g>>2]=0,a[g+4>>2]=0,g=e+48|0,a[g>>2]=0,a[g+4>>2]=0,g=e+56|0,a[g>>2]=0,a[g+4>>2]=0,y=_(0),R=_(0),Q=_(0),I=_(0),J=_(0),x=_(0),m=_(0),p=_(0)),g=e,S=b,k?(b=C[n+8>>2],W=C[n+4>>2],X=_(_(_(U*b)-_(Z*W))*C[r>>2]),M=Z,Z=C[n>>2],b=_(C[k+404>>2]+_(_(X+_(_(_(M*Z)-_(b*F))*C[r+4>>2]))+_(_(_(W*F)-_(U*Z))*C[r+8>>2])))):b=_(0),Z=b,A?(b=C[c+4>>2],F=C[c+8>>2],M=_(_(_(b*m)-_(F*p))*C[r>>2]),W=_(F*V),F=C[c>>2],b=_(C[A+404>>2]+_(_(M+_(_(W-_(F*m))*C[r+4>>2]))+_(_(_(F*p)-_(b*V))*C[r+8>>2])))):b=_(0),b=_(S/_(Z+b)),C[g+108>>2]=b,k?(i=B(i,244)+v|0,Y=_(_(_(_(C[i+176>>2]+C[i+208>>2])*D)+_(_(C[i+180>>2]+C[i+212>>2])*Y))+_(_(C[i+184>>2]+C[i+216>>2])*E)),m=C[i+192>>2],E=C[i+200>>2],D=C[i+196>>2]):(m=_(0),Y=_(_(_(D*_(0))+_(Y*_(0)))+_(E*_(0))),E=_(0),D=_(0)),Y=_(Y+_(_(_(m*h)+_(D*G))+_(E*N))),A?(A=B(f,244)+v|0,h=_(_(_(_(C[A+176>>2]+C[A+208>>2])*x)+_(_(C[A+180>>2]+C[A+212>>2])*J))+_(_(C[A+184>>2]+C[A+216>>2])*I)),D=C[A+192>>2],G=C[A+200>>2],E=C[A+196>>2]):(G=_(0),h=_(_(_(x*_(0))+_(J*_(0)))+_(I*_(0))),D=_(0),E=_(0)),N=16&o[t+120|0]?_(b*_(_(-_(C[l+44>>2]*_(_(_(_(C[t+48>>2]-C[t+32>>2])*C[r>>2])+_(_(C[t+52>>2]-C[t+36>>2])*C[r+4>>2]))+_(_(C[t+56>>2]-C[t+40>>2])*C[r+8>>2]))))/C[l+12>>2])):_(0),a[e+128>>2]=0,a[e+124>>2]=d,C[e+116>>2]=s,C[e+112>>2]=_(b*_(u-_(Y+_(h+_(_(_(D*Q)+_(E*R))+_(G*y))))))+N,C[e+120>>2]=-T}(A,d,e,r,i,n,c,b,l,u,s,k)}function Af(A,e,r,i,t,n){var b=0,l=0,u=0,k=0,v=0;if(l=a[A+88>>2],b=l,(0|l)==a[A+92>>2]&&(b=l,u=l?l<<1:1,!((0|l)>=(0|u)))){if(u?(v=dA(B(u,152)),b=a[A+88>>2]):b=l,k=b,(0|k)>=1)for(b=0;J(b+v|0,a[A+96>>2]+b|0,152),b=b+152|0,k=k+-1|0,k;);b=a[A+96>>2],b&&(o[A+100|0]&&CA(b),a[A+96>>2]=0),a[A+96>>2]=v,a[A+92>>2]=u,f[A+100|0]=1,b=a[A+88>>2]}a[A+88>>2]=b+1,l=a[A+96>>2]+B(l,152)|0,a[l+140>>2]=t,function(A,e,r,i,f,t){var n,o,b=0,l=_(0),u=_(0),k=_(0),v=_(0),d=_(0),g=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=0,y=_(0),p=0,F=0,W=0,w=0,D=_(0),E=_(0),Z=_(0);a[e+48>>2]=-2147483648,a[e+52>>2]=-2147483648,a[e+16>>2]=0,a[e+20>>2]=0,b=e+56|0,a[b>>2]=-2147483648,a[b+4>>2]=0,b=e+24|0,a[b>>2]=0,a[b+4>>2]=0,C[e+104>>2]=t,a[e+96>>2]=0,a[e+100>>2]=0,n=a[A+16>>2],A=a[240+(n+B(i,244)|0)>>2],b=a[240+(B(f,244)+n|0)>>2],a[e+132>>2]=0,a[e+148>>2]=f,a[e+144>>2]=i,k=C[r>>2],v=C[r+4>>2],d=C[r+8>>2],a[e+12>>2]=0,l=_(-d),C[e+8>>2]=l,g=_(-v),C[e+4>>2]=g,u=_(-k),C[e>>2]=u,o=e,A?(s(_(_(_(_(C[A+356>>2]*u)+_(C[A+360>>2]*g))+_(C[A+364>>2]*l))*C[A+612>>2])),p=c(0),s(_(_(_(_(C[A+340>>2]*u)+_(C[A+344>>2]*g))+_(C[A+348>>2]*l))*C[A+608>>2])),F=c(0),s(_(_(_(_(C[A+324>>2]*u)+_(C[A+328>>2]*g))+_(C[A+332>>2]*l))*C[A+604>>2])),G=c(0)):G=0,a[o+64>>2]=G,a[e+76>>2]=0,a[e+72>>2]=p,a[e+68>>2]=F,k=C[r>>2],v=C[r+4>>2],d=C[r+8>>2],a[e+44>>2]=a[r+12>>2],C[e+40>>2]=d,C[e+36>>2]=v,C[e+32>>2]=k,r=0,b&&(s(_(_(_(_(k*C[b+356>>2])+_(v*C[b+360>>2]))+_(d*C[b+364>>2]))*C[b+612>>2])),W=c(0),s(_(_(_(_(k*C[b+324>>2])+_(v*C[b+328>>2]))+_(d*C[b+332>>2]))*C[b+604>>2])),w=c(0),s(_(_(_(_(k*C[b+340>>2])+_(v*C[b+344>>2]))+_(d*C[b+348>>2]))*C[b+608>>2])),r=c(0)),a[e+80>>2]=w,a[e+92>>2]=0,a[e+88>>2]=W,a[e+84>>2]=r,r=e,A?(R=_(_(_(C[A+356>>2]*u)+_(C[A+360>>2]*g))+_(C[A+364>>2]*l)),m=_(_(_(C[A+340>>2]*u)+_(C[A+344>>2]*g))+_(C[A+348>>2]*l)),y=_(_(_(C[A+324>>2]*u)+_(C[A+328>>2]*g))+_(C[A+332>>2]*l))):y=_(0),R=_(_(_(_(y*u)+_(m*g))+_(R*l))+_(0)),b?(Q=_(_(_(k*C[b+356>>2])+_(v*C[b+360>>2]))+_(d*C[b+364>>2])),D=_(_(_(k*C[b+340>>2])+_(v*C[b+344>>2]))+_(d*C[b+348>>2])),m=_(_(_(C[b+324>>2]*k)+_(C[b+328>>2]*v))+_(C[b+332>>2]*d))):m=_(0),Q=_(_(1)/_(R+_(_(_(m*k)+_(D*v))+_(Q*d)))),C[r+108>>2]=Q,m=_(0),R=_(0),A&&(A=B(i,244)+n|0,h=_(_(_(_(C[A+176>>2]+C[A+208>>2])*_(0))+_(_(C[A+180>>2]+C[A+212>>2])*_(0)))+_(_(C[A+184>>2]+C[A+216>>2])*_(0))),m=C[A+196>>2],E=C[A+200>>2],R=C[A+192>>2]),g=_(h+_(_(E*l)+_(_(m*g)+_(R*u)))),b?(A=B(f,244)+n|0,l=_(_(_(_(C[A+176>>2]+C[A+208>>2])*_(-0))+_(_(C[A+180>>2]+C[A+212>>2])*_(-0)))+_(_(C[A+184>>2]+C[A+216>>2])*_(-0))),h=C[A+192>>2],Z=C[A+200>>2],u=C[A+196>>2]):(l=_(-0),h=_(0),u=_(0)),C[e+124>>2]=t,C[e+116>>2]=0,C[e+120>>2]=-t,C[e+112>>2]=Q*_(_(0)-_(g+_(l+_(_(d*Z)+_(_(v*u)+_(k*h))))))}(A,l,e,r,i,n)}function ef(A,e,r){var i,f=0;return i=Y-256|0,Y=i,f=a[e+212>>2],(0|f)>-1||(f=a[e+252>>2],2&f&&(f=f<<30>>31&e,2&o[f+204|0]||C[f+404>>2]!=_(0))?(f=a[A+8>>2],X(i+8|0,0,244),function(A,e,r){var i=0,f=0,t=0,n=_(0),o=_(0),c=_(0),b=_(0),l=0,u=_(0),s=_(0),k=_(0),v=_(0),d=_(0);e=e?a[e+252>>2]<<30>>31&e:0,a[A+64>>2]=0,a[A+68>>2]=0,a[A+144>>2]=0,a[A+148>>2]=0,i=A+88|0,a[i>>2]=0,a[i+4>>2]=0,i=A+80|0,a[i>>2]=0,a[i+4>>2]=0,i=A+72|0,a[i>>2]=0,a[i+4>>2]=0,i=A+152|0,a[i>>2]=0,a[i+4>>2]=0,i=A+160|0,a[i>>2]=0,a[i+4>>2]=0,i=A+168|0,a[i>>2]=0,a[i+4>>2]=0,e?(i=a[e+8>>2],a[A>>2]=a[e+4>>2],a[A+4>>2]=i,i=e+12|0,f=a[i+4>>2],t=A+8|0,a[t>>2]=a[i>>2],a[t+4>>2]=f,i=e+28|0,f=a[i+4>>2],t=A+24|0,a[t>>2]=a[i>>2],a[t+4>>2]=f,i=e+20|0,f=a[i+4>>2],a[A+16>>2]=a[i>>2],a[A+20>>2]=f,i=e+44|0,f=a[i+4>>2],t=A+40|0,a[t>>2]=a[i>>2],a[t+4>>2]=f,i=e+36|0,f=a[i+4>>2],a[A+32>>2]=a[i>>2],a[A+36>>2]=f,i=e+52|0,f=a[i+4>>2],a[A+48>>2]=a[i>>2],a[A+52>>2]=f,i=e+60|0,f=a[i+4>>2],t=A+56|0,a[t>>2]=a[i>>2],a[t+4>>2]=f,o=C[e+412>>2],i=e+416|0,c=C[i>>2],b=C[e+408>>2],n=C[e+404>>2],a[A+140>>2]=0,C[A+136>>2]=n*c,C[A+132>>2]=n*o,C[A+128>>2]=n*b,a[A+240>>2]=e,f=e+612|0,t=a[f+4>>2],l=A+104|0,a[l>>2]=a[f>>2],a[l+4>>2]=t,f=a[e+608>>2],a[A+96>>2]=a[e+604>>2],a[A+100>>2]=f,f=a[i+4>>2],t=A+120|0,a[t>>2]=a[i>>2],a[t+4>>2]=f,i=a[e+412>>2],a[A+112>>2]=a[e+408>>2],a[A+116>>2]=i,i=e+380|0,f=a[i+4>>2],t=A+184|0,a[t>>2]=a[i>>2],a[t+4>>2]=f,i=a[e+376>>2],a[A+176>>2]=a[e+372>>2],a[A+180>>2]=i,i=a[e+392>>2],a[A+192>>2]=a[e+388>>2],a[A+196>>2]=i,i=e+396|0,f=a[i+4>>2],t=A+200|0,a[t>>2]=a[i>>2],a[t+4>>2]=f,o=C[e+476>>2],c=C[e+480>>2],b=C[e+472>>2],n=C[e+404>>2],a[A+220>>2]=0,C[A+216>>2]=_(n*c)*r,C[A+212>>2]=_(n*o)*r,C[A+208>>2]=_(n*b)*r,b=C[e+340>>2],u=C[e+356>>2],s=C[e+328>>2],k=C[e+344>>2],v=C[e+360>>2],d=C[e+324>>2],n=C[e+488>>2],o=C[e+492>>2],c=C[e+496>>2],C[A+232>>2]=_(_(_(n*C[e+332>>2])+_(o*C[e+348>>2]))+_(c*C[e+364>>2]))*r,C[A+228>>2]=_(_(_(n*s)+_(o*k))+_(c*v))*r,C[A+224>>2]=_(_(_(d*n)+_(b*o))+_(u*c))*r):(a[A+4>>2]=0,a[A+8>>2]=0,a[A>>2]=1065353216,a[A+32>>2]=0,a[A+36>>2]=0,a[A+240>>2]=0,a[A+128>>2]=0,a[A+132>>2]=0,a[A+112>>2]=1065353216,a[A+116>>2]=1065353216,a[A+96>>2]=1065353216,a[A+100>>2]=1065353216,a[A+176>>2]=0,a[A+180>>2]=0,e=A+12|0,a[e>>2]=0,a[e+4>>2]=0,e=A+24|0,a[e>>2]=0,a[e+4>>2]=0,a[A+20>>2]=1065353216,e=A+44|0,a[e>>2]=0,a[e+4>>2]=0,a[A+40>>2]=1065353216,e=A+52|0,a[e>>2]=0,a[e+4>>2]=0,a[A+60>>2]=0,e=A+136|0,a[e>>2]=0,a[e+4>>2]=0,e=A+120|0,a[e>>2]=1065353216,a[e+4>>2]=0,e=A+104|0,a[e>>2]=1065353216,a[e+4>>2]=0,a[A+232>>2]=0,e=A+224|0,a[e>>2]=0,a[e+4>>2]=0,e=A+216|0,a[e>>2]=0,a[e+4>>2]=0,e=A+208|0,a[e>>2]=0,a[e+4>>2]=0,e=A+200|0,a[e>>2]=0,a[e+4>>2]=0,e=A+192|0,a[e>>2]=0,a[e+4>>2]=0,e=A+184|0,a[e>>2]=0,a[e+4>>2]=0),a[A+236>>2]=0}(rf(A+4|0,i+8|0),e,r),a[e+212>>2]=f):(f=a[A+188>>2],(0|f)>-1||(a[A+188>>2]=a[A+8>>2],X(i+8|0,0,244),e=rf(A+4|0,i+8|0),f=e+88|0,a[f>>2]=0,a[f+4>>2]=0,f=e+80|0,a[f>>2]=0,a[f+4>>2]=0,f=e+72|0,a[f>>2]=0,a[f+4>>2]=0,a[e+64>>2]=0,a[e+68>>2]=0,a[e+144>>2]=0,a[e+148>>2]=0,f=e+152|0,a[f>>2]=0,a[f+4>>2]=0,f=e+160|0,a[f>>2]=0,a[f+4>>2]=0,f=e+168|0,a[f>>2]=0,a[f+4>>2]=0,a[e+4>>2]=0,a[e+8>>2]=0,a[e>>2]=1065353216,f=e+12|0,a[f>>2]=0,a[f+4>>2]=0,f=e+24|0,a[f>>2]=0,a[f+4>>2]=0,a[e+20>>2]=1065353216,a[e+32>>2]=0,a[e+36>>2]=0,f=e+44|0,a[f>>2]=0,a[f+4>>2]=0,a[e+40>>2]=1065353216,f=e+52|0,a[f>>2]=0,a[f+4>>2]=0,a[e+60>>2]=0,f=e+136|0,a[f>>2]=0,a[f+4>>2]=0,a[e+128>>2]=0,a[e+132>>2]=0,f=e+120|0,a[f>>2]=1065353216,a[f+4>>2]=0,a[e+112>>2]=1065353216,a[e+116>>2]=1065353216,f=e+104|0,a[f>>2]=1065353216,a[f+4>>2]=0,a[e+96>>2]=1065353216,a[e+100>>2]=1065353216,f=e+232|0,a[f>>2]=0,a[f+4>>2]=0,f=e+224|0,a[f>>2]=0,a[f+4>>2]=0,f=e+216|0,a[f>>2]=0,a[f+4>>2]=0,f=e+208|0,a[f>>2]=0,a[f+4>>2]=0,f=e+200|0,a[f>>2]=0,a[f+4>>2]=0,f=e+192|0,a[f>>2]=0,a[f+4>>2]=0,f=e+184|0,a[f>>2]=0,a[f+4>>2]=0,a[e+176>>2]=0,a[e+180>>2]=0,a[e+240>>2]=0,f=a[A+188>>2]))),Y=i+256|0,f}function rf(A,e){var r=0,i=0,t=0,n=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0;if(t=a[A+4>>2],b=t,(0|t)==a[A+8>>2]&&(b=t,k=t?t<<1:1,!((0|t)>=(0|k)))){if(k?(d=dA(B(k,244)),b=a[A+4>>2]):b=t,(0|b)>=1)for(r=64;l=a[A+12>>2]+r|0,n=l+-64|0,s=a[n+4>>2],c=r+d|0,i=c+-64|0,a[i>>2]=a[n>>2],a[i+4>>2]=s,n=n+8|0,u=a[n+4>>2],i=i+8|0,a[i>>2]=a[n>>2],a[i+4>>2]=u,i=l+-48|0,s=i+8|0,v=a[s+4>>2],n=c+-48|0,u=n+8|0,a[u>>2]=a[s>>2],a[u+4>>2]=v,u=a[i+4>>2],a[n>>2]=a[i>>2],a[n+4>>2]=u,i=l+-32|0,s=i+8|0,v=a[s+4>>2],n=c+-32|0,u=n+8|0,a[u>>2]=a[s>>2],a[u+4>>2]=v,u=a[i+4>>2],a[n>>2]=a[i>>2],a[n+4>>2]=u,n=l+-16|0,s=a[n+4>>2],i=c+-16|0,a[i>>2]=a[n>>2],a[i+4>>2]=s,n=n+8|0,u=a[n+4>>2],i=i+8|0,a[i>>2]=a[n>>2],a[i+4>>2]=u,J(c,l,180),r=r+244|0,b=b+-1|0,b;);b=a[A+12>>2],b&&(o[A+16|0]&&CA(b),a[A+12>>2]=0),a[A+12>>2]=d,f[A+16|0]=1,a[A+8>>2]=k,b=a[A+4>>2]}return a[A+4>>2]=b+1,c=e+8|0,l=a[c+4>>2],b=B(t,244),t=b+a[A+12>>2]|0,r=t+8|0,a[r>>2]=a[c>>2],a[r+4>>2]=l,r=a[e+4>>2],a[t>>2]=a[e>>2],a[t+4>>2]=r,c=e+24|0,l=a[c+4>>2],r=t+24|0,a[r>>2]=a[c>>2],a[r+4>>2]=l,r=a[e+20>>2],a[t+16>>2]=a[e+16>>2],a[t+20>>2]=r,r=a[e+36>>2],a[t+32>>2]=a[e+32>>2],a[t+36>>2]=r,c=e+40|0,l=a[c+4>>2],r=t+40|0,a[r>>2]=a[c>>2],a[r+4>>2]=l,r=a[e+52>>2],a[t+48>>2]=a[e+48>>2],a[t+52>>2]=r,c=e+56|0,l=a[c+4>>2],r=t+56|0,a[r>>2]=a[c>>2],a[r+4>>2]=l,J(t- -64|0,e- -64|0,180),b+a[A+12>>2]|0}function ff(A,e,r,i,f,t,n,c,b){var l,u,s,k,v=_(0),d=_(0),g=_(0),R=_(0),Q=_(0),G=_(0),y=_(0),p=0,F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),Y=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0),U=0,M=_(0);a[n>>2]=a[t+28>>2],u=a[A+16>>2],s=u+B(i,244)|0,A=a[s+240>>2],k=B(r,244)+u|0,l=a[k+240>>2],D=C[t+12>>2],x=C[t+36>>2],G=C[t+40>>2],p=a[f+120>>2];A:if(6&p){if(G=2&p?C[f+144>>2]:G,!(4&p))break A;x=C[f+148>>2]}else 8&p&&(d=_(D*C[f+144>>2]),v=_(h(_(d+C[f+148>>2]),_(1.1920928955078125e-7))),x=_(d/v),G=_(_(1)/v));v=C[f+68>>2],d=C[c>>2],R=C[c+4>>2],g=C[f+64>>2],F=_(_(v*d)-_(R*g)),Q=C[c+8>>2],W=_(Q*g),g=C[f+72>>2],y=_(W-_(g*d)),w=_(_(R*g)-_(Q*v)),Q=_(0),v=_(0),d=_(0),l&&(Z=_(_(_(_(w*C[l+356>>2])+_(y*C[l+360>>2]))+_(F*C[l+364>>2]))*C[l+612>>2]),d=_(_(_(_(w*C[l+340>>2])+_(y*C[l+344>>2]))+_(F*C[l+348>>2]))*C[l+608>>2]),v=_(_(_(_(w*C[l+324>>2])+_(y*C[l+328>>2]))+_(F*C[l+332>>2]))*C[l+604>>2])),C[e+64>>2]=v,a[e+76>>2]=0,C[e+72>>2]=Z,C[e+68>>2]=d,R=C[f+68>>2],g=C[b>>2],W=C[b+4>>2],E=C[f+64>>2],V=_(_(R*g)-_(W*E)),I=C[b+8>>2],N=C[f+72>>2],E=_(_(I*E)-_(N*g)),N=_(_(W*N)-_(I*R)),R=_(0),g=_(0),I=_(_(1)/D),A&&(Q=_(-N),g=_(_(_(_(C[A+356>>2]*Q)-_(C[A+360>>2]*E))-_(C[A+364>>2]*V))*C[A+612>>2]),R=_(_(_(_(C[A+340>>2]*Q)-_(C[A+344>>2]*E))-_(C[A+348>>2]*V))*C[A+608>>2]),Q=_(_(_(_(C[A+324>>2]*Q)-_(C[A+328>>2]*E))-_(C[A+332>>2]*V))*C[A+604>>2])),C[e+80>>2]=Q,a[e+92>>2]=0,C[e+88>>2]=g,C[e+84>>2]=R,D=_(0),W=_(0),l&&(W=C[c+8>>2],J=C[c+4>>2],M=_(_(_(d*W)-_(Z*J))*C[f+64>>2]),Y=Z,Z=C[c>>2],W=_(C[l+404>>2]+_(_(M+_(_(_(Y*Z)-_(W*v))*C[f+68>>2]))+_(_(_(J*v)-_(d*Z))*C[f+72>>2])))),p=e,J=C[n>>2],Z=_(I*G),Y=Z,A&&(v=C[b+4>>2],d=C[b+8>>2],D=_(_(_(v*g)-_(d*R))*C[f+64>>2]),G=_(d*Q),d=C[b>>2],D=_(C[A+404>>2]+_(_(D+_(_(G-_(d*g))*C[f+68>>2]))+_(_(_(d*R)-_(v*Q))*C[f+72>>2])))),C[p+108>>2]=J/_(Y+_(W+D)),n=e+16|0,l?(p=f- -64|0,U=a[p+4>>2],a[n>>2]=a[p>>2],a[n+4>>2]=U,p=p+8|0,U=a[p+4>>2],n=n+8|0,a[n>>2]=a[p>>2],a[n+4>>2]=U,a[e+12>>2]=0,C[e+8>>2]=F,C[e+4>>2]=y,C[e>>2]=w):(a[e>>2]=0,a[e+4>>2]=0,p=e+24|0,a[p>>2]=0,a[p+4>>2]=0,a[n>>2]=0,a[n+4>>2]=0,n=e+8|0,a[n>>2]=0,a[n+4>>2]=0),A?(v=C[f+64>>2],d=C[f+68>>2],R=C[f+72>>2],a[e+60>>2]=0,a[e+44>>2]=0,C[e+40>>2]=-V,C[e+36>>2]=-E,C[e+32>>2]=-N,C[e+56>>2]=-R,C[e+52>>2]=-d,C[e+48>>2]=-v):(a[e+32>>2]=0,a[e+36>>2]=0,n=e+56|0,a[n>>2]=0,a[n+4>>2]=0,n=e+48|0,a[n>>2]=0,a[n+4>>2]=0,n=e+40|0,a[n>>2]=0,a[n+4>>2]=0),D=C[t+64>>2],W=C[f+80>>2],Q=_(0),v=_(0),d=_(0),R=_(0),l&&(v=C[c+4>>2],d=C[l+388>>2],g=C[l+392>>2],G=C[c>>2],R=_(_(_(v*d)-_(g*G))+C[l+380>>2]),F=C[l+396>>2],Y=_(F*G),G=C[c+8>>2],d=_(C[l+376>>2]+_(Y-_(G*d))),v=_(_(_(g*G)-_(F*v))+C[l+372>>2])),g=_(0),F=_(0),A&&(G=C[b+4>>2],g=C[A+388>>2],Q=C[A+392>>2],y=C[b>>2],F=_(_(_(G*g)-_(Q*y))+C[A+380>>2]),w=C[A+396>>2],Y=_(w*y),y=C[b+8>>2],g=_(C[A+376>>2]+_(Y-_(y*g))),Q=_(_(_(Q*y)-_(w*G))+C[A+372>>2])),n=s+240|0,c=k+240|0,G=C[f+72>>2],y=C[f+64>>2],w=C[f+68>>2],a[e+104>>2]=a[f+84>>2],v=_(_(_(y*_(v-Q))+_(w*_(d-g)))+_(G*_(R-F))),G=_(m(v))>2]?_(0):_(-_(v*C[f+96>>2]));A:if(4&o[t+72|0]){if(v=_(C[f+124>>2]*C[t+68>>2]),C[e+100>>2]=v,!l|!a[c>>2]||(d=C[l+416>>2],R=C[e+24>>2],g=C[l+412>>2],Q=C[e+20>>2],f=B(r,244)+u|0,C[f+64>>2]=_(C[f+112>>2]*_(v*_(_(C[e+16>>2]*C[f+128>>2])*C[l+408>>2])))+C[f+64>>2],b=f+68|0,C[b>>2]=_(_(v*_(g*_(Q*C[f+132>>2])))*C[f+116>>2])+C[b>>2],b=f+72|0,C[b>>2]=_(_(v*_(d*_(R*C[f+136>>2])))*C[f+120>>2])+C[b>>2],d=C[e+72>>2],R=C[e+68>>2],C[f+80>>2]=_(_(v*C[f+96>>2])*C[e+64>>2])+C[f+80>>2],g=C[f+104>>2],b=f+84|0,C[b>>2]=_(R*_(v*C[f+100>>2]))+C[b>>2],f=f+88|0,C[f>>2]=_(d*_(v*g))+C[f>>2]),!A|!a[n>>2])break A;d=C[A+416>>2],R=C[e+56>>2],g=C[A+412>>2],Q=C[e+52>>2],F=C[e+88>>2],y=C[e+84>>2],w=C[e+80>>2],f=B(i,244)+u|0,v=C[e+100>>2],C[f+64>>2]=_(C[f+112>>2]*_(v*_(_(C[e+48>>2]*C[f+128>>2])*C[A+408>>2])))+C[f+64>>2],A=f+68|0,C[A>>2]=_(_(v*_(g*_(Q*C[f+132>>2])))*C[f+116>>2])+C[A>>2],A=f+72|0,C[A>>2]=_(_(v*_(d*_(R*C[f+136>>2])))*C[f+120>>2])+C[A>>2],v=_(-v),C[f+80>>2]=C[f+80>>2]-_(w*_(C[f+96>>2]*v)),d=C[f+104>>2],A=f+84|0,C[A>>2]=C[A>>2]-_(y*_(C[f+100>>2]*v)),A=f+88|0,C[A>>2]=C[A>>2]-_(F*_(d*v))}else a[e+100>>2]=0;f=G<=_(0),a[e+96>>2]=0,d=_(0),R=_(0),g=_(0),F=_(0),y=_(0),w=_(0),V=_(0),a[c>>2]&&(A=B(r,244)+u|0,V=C[A+224>>2],F=C[A+208>>2],y=C[A+232>>2],w=C[A+228>>2],g=C[A+212>>2],R=C[A+216>>2]),Q=_(W+D),N=f?_(0):G,v=_(0),E=_(0),G=_(0),D=_(0),W=_(0),a[n>>2]&&(A=B(i,244)+u|0,W=C[A+224>>2],d=C[A+208>>2],G=C[A+232>>2],D=C[A+228>>2],E=C[A+216>>2],v=C[A+212>>2]),A=B(r,244)+u|0,Y=_(_(_(_(_(F+C[A+176>>2])*C[e+16>>2])+_(_(g+C[A+180>>2])*C[e+20>>2]))+_(_(R+C[A+184>>2])*C[e+24>>2]))+_(_(_(_(V+C[A+192>>2])*C[e>>2])+_(_(w+C[A+196>>2])*C[e+4>>2]))+_(_(y+C[A+200>>2])*C[e+8>>2]))),A=B(i,244)+u|0,v=_(N-_(Y+_(_(_(_(_(d+C[A+176>>2])*C[e+48>>2])+_(_(v+C[A+180>>2])*C[e+52>>2]))+_(_(E+C[A+184>>2])*C[e+56>>2]))+_(_(_(_(W+C[A+192>>2])*C[e+32>>2])+_(_(D+C[A+196>>2])*C[e+36>>2]))+_(_(G+C[A+200>>2])*C[e+40>>2]))))),d=_(0),Q>_(0)?v=_(v-_(I*Q)):d=_(-_(I*_(x*Q))),R=C[e+108>>2],v=_(v*R),d=_(d*R),Q>C[t+56>>2]^1&&a[t+52>>2]||(v=_(d+v),d=_(0)),C[e+128>>2]=d,C[e+112>>2]=v,a[e+120>>2]=0,a[e+124>>2]=1343554297,C[e+116>>2]=Z*R}function tf(A,e,r,i,f,t){var n,o,c,b,l,u,s,k=_(0),v=_(0),d=0,g=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0);c=a[A+16>>2],n=a[240+(c+B(i,244)|0)>>2],o=a[240+(B(r,244)+c|0)>>2],b=a[A+76>>2],l=a[e+140>>2],u=a[t+72>>2],s=4&u;A:if(s){if(e=B(l,152)+b|0,k=_(C[f+128>>2]*C[t+68>>2]),C[e+100>>2]=k,o&&(g=C[o+416>>2],m=C[e+24>>2],R=C[o+412>>2],Q=C[e+20>>2],A=B(r,244)+c|0,v=C[o+404>>2],C[A+64>>2]=_(_(k*_(_(v*C[e+16>>2])*C[o+408>>2]))*C[A+112>>2])+C[A+64>>2],d=A+68|0,C[d>>2]=_(_(k*_(R*_(v*Q)))*C[A+116>>2])+C[d>>2],d=A+72|0,C[d>>2]=_(_(k*_(g*_(v*m)))*C[A+120>>2])+C[d>>2],v=C[e+72>>2],g=C[e+68>>2],C[A+80>>2]=_(_(k*C[A+96>>2])*C[e+64>>2])+C[A+80>>2],m=C[A+104>>2],d=A+84|0,C[d>>2]=_(g*_(k*C[A+100>>2]))+C[d>>2],A=A+88|0,C[A>>2]=_(v*_(k*m))+C[A>>2]),!n)break A;d=B(l,152)+b|0,g=C[d+88>>2],m=C[d+84>>2],R=C[d+80>>2],Q=C[n+416>>2],h=C[d+56>>2],G=C[n+412>>2],y=C[d+52>>2],A=B(i,244)+c|0,v=C[n+404>>2],k=C[e+100>>2],C[A+64>>2]=_(_(_(_(C[d+48>>2]*v)*C[n+408>>2])*k)*C[A+112>>2])+C[A+64>>2],e=A+68|0,C[e>>2]=_(_(k*_(G*_(y*v)))*C[A+116>>2])+C[e>>2],e=A+72|0,C[e>>2]=_(_(k*_(Q*_(h*v)))*C[A+120>>2])+C[e>>2],C[A+80>>2]=C[A+80>>2]+_(R*_(k*C[A+96>>2])),v=C[A+104>>2],e=A+84|0,C[e>>2]=C[e>>2]+_(m*_(k*C[A+100>>2])),A=A+88|0,C[A>>2]=C[A>>2]+_(g*_(v*k))}else a[100+(B(l,152)+b|0)>>2]=0;A:if(16&u){if(d=l+1|0,s){if(e=B(d,152)+b|0,k=_(C[f+132>>2]*C[t+68>>2]),C[e+100>>2]=k,o&&(g=C[e+24>>2],m=C[e+20>>2],A=B(r,244)+c|0,v=C[o+404>>2],C[A+64>>2]=_(_(k*_(v*C[e+16>>2]))*C[A+112>>2])+C[A+64>>2],r=A+68|0,C[r>>2]=_(_(k*_(v*m))*C[A+116>>2])+C[r>>2],r=A+72|0,C[r>>2]=_(_(k*_(v*g))*C[A+120>>2])+C[r>>2],v=C[e+72>>2],g=C[e+68>>2],C[A+80>>2]=_(_(k*C[A+96>>2])*C[e+64>>2])+C[A+80>>2],m=C[A+104>>2],r=A+84|0,C[r>>2]=_(g*_(k*C[A+100>>2]))+C[r>>2],A=A+88|0,C[A>>2]=_(v*_(k*m))+C[A>>2]),!n)break A;return r=B(d,152)+b|0,g=C[r+88>>2],m=C[r+84>>2],R=C[r+56>>2],Q=C[r+52>>2],h=C[r+48>>2],v=C[n+404>>2],A=B(i,244)+c|0,k=C[e+100>>2],C[A+80>>2]=C[A+80>>2]+_(C[r+80>>2]*_(C[A+96>>2]*k)),C[A+64>>2]=_(_(k*_(h*v))*C[A+112>>2])+C[A+64>>2],e=A+68|0,C[e>>2]=_(_(k*_(Q*v))*C[A+116>>2])+C[e>>2],e=A+72|0,C[e>>2]=_(_(k*_(R*v))*C[A+120>>2])+C[e>>2],v=C[A+104>>2],e=A+84|0,C[e>>2]=C[e>>2]+_(m*_(k*C[A+100>>2])),A=A+88|0,void(C[A>>2]=C[A>>2]+_(g*_(v*k)))}a[100+(B(d,152)+b|0)>>2]=0}}function nf(A,e,r){var i,t,n,c,b,l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),R=_(0),Q=0,h=_(0),G=_(0),p=0,F=_(0),W=0,w=0,D=_(0),E=_(0),Z=_(0),V=_(0),N=_(0),I=0,x=0,U=_(0),M=0,S=_(0),X=_(0),T=_(0),j=_(0),O=_(0),H=_(0),z=_(0),P=0,K=0,L=0,q=0,$=_(0),AA=0,eA=0,rA=0,iA=0,fA=0,tA=0,nA=0,aA=0,oA=0,cA=0,bA=0,lA=0,uA=0,sA=0,kA=0,vA=0,gA=0,BA=0,_A=0,mA=0,RA=0,QA=0,hA=0,GA=0,yA=0,pA=0,FA=0,WA=0,wA=_(0);if(n=Y-80|0,Y=n,i=a[e+776>>2],t=a[e+772>>2],c=ef(A,t,C[r+12>>2]),b=ef(A,i,C[r+12>>2]),w=a[A+16>>2],Q=w+B(c,244)|0,l=C[Q+128>>2],g=_(l*l),l=C[Q+132>>2],g=_(g+_(l*l)),l=C[Q+136>>2],!(_(g+_(l*l))<_(1.4210854715202004e-14)&&(Q=w+B(b,244)|0,l=C[Q+128>>2],g=_(l*l),l=C[Q+132>>2],g=_(g+_(l*l)),l=C[Q+136>>2],_(g+_(l*l))<_(1.4210854715202004e-14))||(p=a[e+780>>2],(0|p)<1)))for(Q=w+B(b,244)|0,rA=Q+232|0,iA=Q+200|0,fA=Q+228|0,tA=Q+196|0,nA=Q+224|0,aA=Q+192|0,oA=Q+216|0,cA=Q+184|0,bA=Q+212|0,lA=Q+180|0,uA=Q+208|0,sA=Q+176|0,kA=Q+240|0,Q=w+B(c,244)|0,vA=Q+232|0,gA=Q+200|0,BA=Q+228|0,_A=Q+196|0,mA=Q+224|0,RA=Q+192|0,QA=Q+216|0,hA=Q+184|0,GA=Q+212|0,yA=Q+180|0,pA=Q+208|0,FA=Q+176|0,WA=Q+240|0;;){if(W=B(AA,192)+e|0,C[W+84>>2]<=C[e+788>>2]){if(K=W+4|0,Q=a[A+28>>2],p=Q,(0|Q)==a[A+32>>2]&&(p=Q,I=Q?Q<<1:1,!((0|Q)>=(0|I)))){if(I?(x=dA(B(I,152)),w=a[A+28>>2]):(x=0,w=Q),(0|w)>=1)for(p=0;J(p+x|0,a[A+36>>2]+p|0,152),p=p+152|0,w=w+-1|0,w;);p=a[A+36>>2],p&&(o[A+40|0]&&CA(p),a[A+36>>2]=0),a[A+36>>2]=x,f[A+40|0]=1,a[A+32>>2]=I,p=a[A+28>>2]}a[A+28>>2]=p+1,q=a[A+36>>2]+B(Q,152)|0,a[q+132>>2]=K,a[q+148>>2]=b,a[q+144>>2]=c,a[n+76>>2]=0,l=_(C[W+60>>2]-C[t+60>>2]),C[n+72>>2]=l,u=_(C[W+56>>2]-C[t+56>>2]),C[n+68>>2]=u,s=_(C[W+52>>2]-C[t+52>>2]),C[n+64>>2]=s,d=C[W+36>>2],v=C[W+40>>2],k=C[W+44>>2],R=C[i+52>>2],h=C[i+56>>2],g=C[i+60>>2],a[n+60>>2]=0,k=_(k-g),C[n+56>>2]=k,v=_(v-h),C[n+52>>2]=v,d=_(d-R),C[n+48>>2]=d,g=_(0),F=_(0),D=_(0),G=_(0),a[WA>>2]&&(R=_(C[RA>>2]+C[mA>>2]),h=_(C[_A>>2]+C[BA>>2]),G=_(_(C[hA>>2]+C[QA>>2])+_(_(u*R)-_(s*h))),F=s,s=_(C[gA>>2]+C[vA>>2]),D=_(_(C[yA>>2]+C[GA>>2])+_(_(F*s)-_(l*R))),F=_(_(C[FA>>2]+C[pA>>2])+_(_(l*h)-_(u*s)))),U=_(0),N=_(0),a[kA>>2]&&(l=_(C[aA>>2]+C[nA>>2]),u=_(C[tA>>2]+C[fA>>2]),N=_(_(C[cA>>2]+C[oA>>2])+_(_(v*l)-_(d*u))),s=_(C[iA>>2]+C[rA>>2]),U=_(_(C[lA>>2]+C[bA>>2])+_(_(d*s)-_(k*l))),g=_(_(C[sA>>2]+C[uA>>2])+_(_(k*u)-_(v*s)))),P=W+76|0,V=C[P>>2],x=W+68|0,$=C[x>>2],M=W+72|0,wA=C[M>>2],ff(A,q,c,b,K,r,n+44|0,n- -64|0,n+48|0),a[q+140>>2]=a[A+68>>2],p=W+92|0,C[p>>2]>_(0)&&(Af(A,x,c,b,Q,C[W+96>>2]),s=C[P>>2],_(m(s))>_(.7071067690849304)?(a[n+24>>2]=0,l=C[M>>2],k=_(_(s*s)+_(l*l)),u=_(_(1)/_(y(k))),l=_(l*u),C[n+32>>2]=l,v=_(k*u),C[n+8>>2]=v,u=_(-_(s*u)),C[n+28>>2]=u,s=C[x>>2],d=_(-_(s*l)),C[n+12>>2]=d,R=_(s*u),k=_(0)):(a[n+32>>2]=0,u=C[x>>2],k=C[M>>2],R=_(_(u*u)+_(k*k)),l=_(_(1)/_(y(R))),u=_(u*l),C[n+28>>2]=u,k=_(-_(k*l)),C[n+24>>2]=k,d=_(s*k),C[n+12>>2]=d,v=_(-_(s*u)),C[n+8>>2]=v,R=_(R*l),l=_(0)),h=_(_(1)/_(y(_(_(_(k*k)+_(u*u))+_(l*l))))),l=_(l*h),C[n+32>>2]=l,s=_(u*h),C[n+28>>2]=s,k=_(k*h),C[n+24>>2]=k,u=R,R=_(_(1)/_(y(_(_(R*R)+_(_(v*v)+_(d*d)))))),u=_(u*R),C[n+16>>2]=u,d=_(d*R),C[n+12>>2]=d,v=_(v*R),C[n+8>>2]=v,w=2&a[t+180>>2],w&&(a[n+36>>2]=0,S=C[t+4>>2],X=C[t+20>>2],T=C[t+36>>2],R=_(_(_(_(k*S)+_(s*X))+_(l*T))*C[t+164>>2]),j=C[t+8>>2],O=C[t+24>>2],H=C[t+40>>2],h=_(_(_(_(k*j)+_(s*O))+_(l*H))*C[t+168>>2]),z=C[t+12>>2],E=s,s=C[t+28>>2],Z=l,l=C[t+44>>2],k=_(_(_(_(k*z)+_(E*s))+_(Z*l))*C[t+172>>2]),l=_(_(_(T*R)+_(H*h))+_(l*k)),C[n+32>>2]=l,s=_(_(_(X*R)+_(O*h))+_(s*k)),C[n+28>>2]=s,k=_(_(_(S*R)+_(j*h))+_(z*k)),C[n+24>>2]=k),I=2&a[i+180>>2],I&&(a[n+36>>2]=0,S=C[i+4>>2],X=C[i+20>>2],T=C[i+36>>2],R=_(_(_(_(S*k)+_(X*s))+_(T*l))*C[i+164>>2]),j=C[i+8>>2],O=C[i+24>>2],H=C[i+40>>2],h=_(_(_(_(k*j)+_(s*O))+_(l*H))*C[i+168>>2]),z=C[i+12>>2],E=s,s=C[i+28>>2],Z=l,l=C[i+44>>2],k=_(_(_(_(k*z)+_(E*s))+_(Z*l))*C[i+172>>2]),l=_(_(_(T*R)+_(H*h))+_(l*k)),C[n+32>>2]=l,s=_(_(_(X*R)+_(O*h))+_(s*k)),C[n+28>>2]=s,k=_(_(_(S*R)+_(j*h))+_(z*k)),C[n+24>>2]=k),w&&(a[n+20>>2]=0,S=C[t+4>>2],X=C[t+20>>2],T=C[t+36>>2],R=_(_(_(_(v*S)+_(d*X))+_(u*T))*C[t+164>>2]),j=C[t+8>>2],O=C[t+24>>2],H=C[t+40>>2],h=_(_(_(_(v*j)+_(d*O))+_(u*H))*C[t+168>>2]),z=C[t+12>>2],E=d,d=C[t+28>>2],Z=u,u=C[t+44>>2],v=_(_(_(_(v*z)+_(E*d))+_(Z*u))*C[t+172>>2]),u=_(_(_(T*R)+_(H*h))+_(u*v)),C[n+16>>2]=u,d=_(_(_(X*R)+_(O*h))+_(d*v)),C[n+12>>2]=d,v=_(_(_(S*R)+_(j*h))+_(z*v)),C[n+8>>2]=v),I&&(a[n+20>>2]=0,S=C[i+4>>2],X=C[i+20>>2],T=C[i+36>>2],R=_(_(_(_(S*v)+_(X*d))+_(T*u))*C[i+164>>2]),j=C[i+8>>2],O=C[i+24>>2],H=C[i+40>>2],h=_(_(_(_(v*j)+_(d*O))+_(u*H))*C[i+168>>2]),z=C[i+12>>2],E=d,d=C[i+28>>2],Z=u,u=C[i+44>>2],v=_(_(_(_(v*z)+_(E*d))+_(Z*u))*C[i+172>>2]),u=_(_(_(T*R)+_(H*h))+_(u*v)),C[n+16>>2]=u,d=_(_(_(X*R)+_(O*h))+_(d*v)),C[n+12>>2]=d,v=_(_(_(S*R)+_(j*h))+_(z*v)),C[n+8>>2]=v),+_(y(_(_(_(k*k)+_(s*s))+_(l*l))))>.001&&Af(A,n+24|0,c,b,Q,C[p>>2]),+_(y(_(_(_(v*v)+_(d*d))+_(u*u))))>.001&&Af(A,n+8|0,c,b,Q,C[p>>2]));A:if(1&f[W+124|0]&&32&o[r+72|0])l=C[n+44>>2],p=W+156|0,$i(A,W+164|0,c,b,Q,K,n- -64|0,n+48|0,l,r,C[W+140>>2],C[p>>2]),16&o[r+72|0]&&$i(A,W+180|0,c,b,Q,K,n- -64|0,n+48|0,l,r,C[W+144>>2],C[p>>2]);else{if(L=W+176|0,a[L>>2]=0,s=_(F-g),u=_(D-U),k=_(G-N),l=_(_(_(s*$)+_(u*wA))+_(k*V)),w=W+172|0,g=k,k=C[P>>2],v=_(g-_(l*k)),C[w>>2]=v,I=W+168|0,g=u,u=C[M>>2],d=_(g-_(l*u)),C[I>>2]=d,p=W+164|0,g=s,s=C[x>>2],l=_(g-_(l*s)),C[p>>2]=l,!(64&o[r+72|0])&&(R=_(_(_(l*l)+_(d*d))+_(v*v)),R>_(1.1920928955078125e-7))){if(u=_(_(1)/_(y(R))),s=_(d*u),C[I>>2]=s,l=_(l*u),C[p>>2]=l,u=_(v*u),C[w>>2]=u,1&f[t+180|0]&&(U=C[t+172>>2],k=C[t+44>>2],v=C[t+12>>2],d=C[t+28>>2],N=C[t+164>>2],R=C[t+36>>2],h=C[t+4>>2],g=C[t+20>>2],V=C[t+168>>2],F=C[t+40>>2],D=C[t+8>>2],G=C[t+24>>2],a[L>>2]=0,E=g,g=_(N*_(_(_(l*h)+_(s*g))+_(u*R))),Z=G,G=_(V*_(_(_(l*D)+_(s*G))+_(u*F))),u=_(U*_(_(_(l*v)+_(s*d))+_(u*k))),s=_(_(_(E*g)+_(Z*G))+_(d*u)),C[I>>2]=s,l=_(_(_(h*g)+_(D*G))+_(v*u)),C[p>>2]=l,u=_(_(_(R*g)+_(F*G))+_(k*u)),C[w>>2]=u),1&f[i+180|0]&&(U=C[i+172>>2],k=C[i+44>>2],v=C[i+12>>2],d=C[i+28>>2],N=C[i+164>>2],R=C[i+36>>2],h=C[i+4>>2],g=C[i+20>>2],V=C[i+168>>2],F=C[i+40>>2],D=C[i+8>>2],G=C[i+24>>2],a[L>>2]=0,E=g,g=_(N*_(_(_(h*l)+_(g*s))+_(R*u))),Z=G,G=_(V*_(_(_(l*D)+_(s*G))+_(u*F))),l=_(U*_(_(_(l*v)+_(s*d))+_(u*k))),C[I>>2]=_(_(E*g)+_(Z*G))+_(d*l),C[p>>2]=_(_(h*g)+_(D*G))+_(v*l),C[w>>2]=_(_(R*g)+_(F*G))+_(k*l)),U=C[n+44>>2],$i(A,p,c,b,Q,K,n- -64|0,n+48|0,U,r,_(0),_(0)),!(16&o[r+72|0]))break A;L=W+192|0,a[L>>2]=0,eA=W+188|0,u=C[M>>2],k=C[p>>2],s=C[I>>2],v=C[x>>2],l=_(_(u*k)-_(s*v)),d=C[P>>2],R=C[w>>2],s=_(_(s*d)-_(R*u)),u=_(_(R*v)-_(d*k)),k=_(_(1)/_(y(_(_(_(s*s)+_(u*u))+_(l*l))))),l=_(l*k),C[eA>>2]=l,w=W+184|0,u=_(u*k),C[w>>2]=u,p=W+180|0,s=_(s*k),C[p>>2]=s,1&f[t+180|0]&&(N=C[t+172>>2],k=C[t+44>>2],v=C[t+12>>2],d=C[t+28>>2],V=C[t+164>>2],R=C[t+36>>2],h=C[t+4>>2],g=C[t+20>>2],$=C[t+168>>2],F=C[t+40>>2],D=C[t+8>>2],G=C[t+24>>2],a[L>>2]=0,E=g,g=_(V*_(_(_(s*h)+_(u*g))+_(l*R))),Z=G,G=_($*_(_(_(s*D)+_(u*G))+_(l*F))),l=_(N*_(_(_(s*v)+_(u*d))+_(l*k))),u=_(_(_(E*g)+_(Z*G))+_(d*l)),C[w>>2]=u,s=_(_(_(h*g)+_(D*G))+_(v*l)),C[p>>2]=s,l=_(_(_(R*g)+_(F*G))+_(k*l)),C[eA>>2]=l),1&f[i+180|0]&&(N=C[i+172>>2],k=C[i+44>>2],v=C[i+12>>2],d=C[i+28>>2],V=C[i+164>>2],R=C[i+36>>2],h=C[i+4>>2],g=C[i+20>>2],$=C[i+168>>2],F=C[i+40>>2],D=C[i+8>>2],G=C[i+24>>2],a[L>>2]=0,E=g,g=_(V*_(_(_(h*s)+_(g*u))+_(R*l))),Z=G,G=_($*_(_(_(s*D)+_(u*G))+_(l*F))),l=_(N*_(_(_(s*v)+_(u*d))+_(l*k))),C[w>>2]=_(_(E*g)+_(Z*G))+_(d*l),C[p>>2]=_(_(h*g)+_(D*G))+_(v*l),C[eA>>2]=_(_(R*g)+_(F*G))+_(k*l)),$i(A,p,c,b,Q,K,n- -64|0,n+48|0,U,r,_(0),_(0));break A}if(x=W+180|0,_(m(k))>_(.7071067690849304)?(a[p>>2]=0,d=_(_(u*u)+_(k*k)),v=_(_(1)/_(y(d))),u=_(u*v),C[w>>2]=u,l=_(-_(k*v)),C[I>>2]=l,k=_(d*v),d=_(s*l),v=_(-_(s*u)),s=_(0)):(a[w>>2]=0,d=_(_(s*s)+_(u*u)),v=_(_(1)/_(y(d))),l=_(s*v),C[I>>2]=l,s=_(-_(u*v)),C[p>>2]=s,d=_(d*v),v=_(k*s),k=_(-_(k*l)),u=_(0)),C[x>>2]=k,M=W+188|0,C[M>>2]=d,P=W+184|0,C[P>>2]=v,1&f[t+180|0]&&(U=C[t+172>>2],k=C[t+44>>2],v=C[t+12>>2],d=C[t+28>>2],N=C[t+164>>2],R=C[t+36>>2],h=C[t+4>>2],g=C[t+20>>2],V=C[t+168>>2],F=C[t+40>>2],D=C[t+8>>2],G=C[t+24>>2],a[L>>2]=0,E=g,g=_(N*_(_(_(h*s)+_(g*l))+_(R*u))),Z=G,G=_(V*_(_(_(s*D)+_(l*G))+_(u*F))),u=_(U*_(_(_(s*v)+_(l*d))+_(u*k))),l=_(_(_(E*g)+_(Z*G))+_(d*u)),C[I>>2]=l,s=_(_(_(h*g)+_(D*G))+_(v*u)),C[p>>2]=s,u=_(_(_(R*g)+_(F*G))+_(k*u)),C[w>>2]=u),1&f[i+180|0]&&(U=C[i+172>>2],k=C[i+44>>2],v=C[i+12>>2],d=C[i+28>>2],N=C[i+164>>2],R=C[i+36>>2],h=C[i+4>>2],g=C[i+20>>2],V=C[i+168>>2],F=C[i+40>>2],D=C[i+8>>2],G=C[i+24>>2],a[L>>2]=0,E=g,g=_(N*_(_(_(h*s)+_(g*l))+_(R*u))),Z=G,G=_(V*_(_(_(s*D)+_(l*G))+_(u*F))),l=_(U*_(_(_(s*v)+_(l*d))+_(u*k))),C[I>>2]=_(_(E*g)+_(Z*G))+_(d*l),C[p>>2]=_(_(h*g)+_(D*G))+_(v*l),C[w>>2]=_(_(R*g)+_(F*G))+_(k*l)),U=C[n+44>>2],$i(A,p,c,b,Q,K,n- -64|0,n+48|0,U,r,_(0),_(0)),w=a[r+72>>2],16&w&&(1&f[t+180|0]&&(N=C[t+172>>2],l=C[t+44>>2],u=C[t+12>>2],s=C[t+28>>2],F=C[t+164>>2],k=C[t+36>>2],v=C[t+4>>2],d=C[t+20>>2],V=C[t+168>>2],R=C[t+40>>2],h=C[t+8>>2],g=C[t+24>>2],a[W+192>>2]=0,E=v,G=F,v=C[x>>2],F=C[P>>2],D=C[M>>2],G=_(G*_(_(_(E*v)+_(d*F))+_(k*D))),Z=h,h=_(V*_(_(_(v*h)+_(F*g))+_(D*R))),V=u,u=_(N*_(_(_(v*u)+_(F*s))+_(D*l))),C[x>>2]=_(_(E*G)+_(Z*h))+_(V*u),C[P>>2]=_(_(d*G)+_(g*h))+_(s*u),C[M>>2]=_(_(k*G)+_(R*h))+_(l*u)),1&f[i+180|0]&&(N=C[i+172>>2],l=C[i+44>>2],u=C[i+12>>2],s=C[i+28>>2],F=C[i+164>>2],k=C[i+36>>2],v=C[i+4>>2],d=C[i+20>>2],V=C[i+168>>2],R=C[i+40>>2],h=C[i+8>>2],g=C[i+24>>2],a[W+192>>2]=0,E=v,G=F,v=C[x>>2],F=C[P>>2],D=C[M>>2],G=_(G*_(_(_(E*v)+_(d*F))+_(k*D))),Z=h,h=_(V*_(_(_(v*h)+_(F*g))+_(D*R))),V=u,u=_(N*_(_(_(v*u)+_(F*s))+_(D*l))),C[x>>2]=_(_(E*G)+_(Z*h))+_(V*u),C[P>>2]=_(_(d*G)+_(g*h))+_(s*u),C[M>>2]=_(_(k*G)+_(R*h))+_(l*u)),$i(A,x,c,b,Q,K,n- -64|0,n+48|0,U,r,_(0),_(0)),w=a[r+72>>2]),80!=(80&w))break A;Q=W+124|0,a[Q>>2]=1|a[Q>>2]}tf(A,q,c,b,K,r),p=a[e+780>>2]}if(AA=AA+1|0,!((0|AA)<(0|p)))break}Y=n+80|0}function af(A,e,r){var i,f=0,t=0,n=0;i=Y-80|0,Y=i,a[A+240>>2]&&(C[A+176>>2]=C[A+64>>2]+C[A+176>>2],C[A+192>>2]=C[A+80>>2]+C[A+192>>2],f=A+180|0,C[f>>2]=C[A+68>>2]+C[f>>2],f=A+184|0,C[f>>2]=C[A+72>>2]+C[f>>2],f=A+196|0,C[f>>2]=C[A+84>>2]+C[f>>2],f=A+200|0,C[f>>2]=C[A+88>>2]+C[f>>2],(C[A+144>>2]!=_(0)|C[A+148>>2]!=_(0)|C[A+152>>2]!=_(0)|C[A+160>>2]!=_(0)||C[A+164>>2]!=_(0)||C[A+168>>2]!=_(0))&&(a[i+12>>2]=0,C[i>>2]=C[A+160>>2]*r,C[i+8>>2]=C[A+168>>2]*r,C[i+4>>2]=C[A+164>>2]*r,xi(A,A+144|0,i,e,i+16|0),t=i+24|0,n=a[t+4>>2],f=A+8|0,a[f>>2]=a[t>>2],a[f+4>>2]=n,f=a[i+20>>2],a[A>>2]=a[i+16>>2],a[A+4>>2]=f,f=a[i+36>>2],a[A+16>>2]=a[i+32>>2],a[A+20>>2]=f,t=i+40|0,n=a[t+4>>2],f=A+24|0,a[f>>2]=a[t>>2],a[f+4>>2]=n,f=a[i+52>>2],a[A+32>>2]=a[i+48>>2],a[A+36>>2]=f,t=i+56|0,n=a[t+4>>2],f=A+40|0,a[f>>2]=a[t>>2],a[f+4>>2]=n,f=a[i+68>>2],a[A+48>>2]=a[i+64>>2],a[A+52>>2]=f,f=i+72|0,t=a[f+4>>2],A=A+56|0,a[A>>2]=a[f>>2],a[A+4>>2]=t)),Y=i+80|0}function of(A,e,r,i,f){return a[A+20>>2]=0,a[A+16>>2]=r,a[A+12>>2]=e,a[A+8>>2]=f,a[A+4>>2]=i,a[A>>2]=20396,A}function cf(A,e,r,i){var t,n=0,o=0,c=0,b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),V=_(0),N=0,I=0,J=_(0),x=_(0),U=_(0),M=_(0),S=0,X=0,T=0,j=_(0),O=_(0),H=_(0),z=_(0),P=_(0),K=_(0);t=Y-240|0,Y=t,a[A+16>>2]?(Yr(a[A+4>>2]),n=a[A+12>>2],o=a[n+4>>2],c=a[A+16>>2],N=a[c+4>>2],I=n,h=_(Qt[a[a[n>>2]+48>>2]](n)),n=a[A+16>>2],A=function(A,e,r,i,t,n,o,c,b){return a[A+72>>2]=1,a[A+76>>2]=1,a[A+60>>2]=-1,f[A+52|0]=0,C[A+48>>2]=o,C[A+44>>2]=n,a[A+40>>2]=t,a[A+36>>2]=i,a[A+32>>2]=r,a[A+28>>2]=e,a[A+24>>2]=c,a[A+20>>2]=b,a[A+4>>2]=0,a[A+8>>2]=1065353216,a[A>>2]=14908,e=A+12|0,a[e>>2]=0,a[e+4>>2]=0,A}(t+160|0,I,c,o,N,h,_(Qt[a[a[n>>2]+48>>2]](n)),a[A+4>>2],a[A+8>>2]),o=e+8|0,c=a[o+4>>2],n=t+32|0,a[n>>2]=a[o>>2],a[n+4>>2]=c,o=e+24|0,c=a[o+4>>2],n=t+48|0,a[n>>2]=a[o>>2],a[n+4>>2]=c,o=e+40|0,c=a[o+4>>2],n=t- -64|0,a[n>>2]=a[o>>2],a[n+4>>2]=c,o=e+56|0,c=a[o+4>>2],n=t+80|0,a[n>>2]=a[o>>2],a[n+4>>2]=c,o=r+8|0,c=a[o+4>>2],n=t+96|0,a[n>>2]=a[o>>2],a[n+4>>2]=c,a[t+152>>2]=1566444395,n=a[e+4>>2],a[t+24>>2]=a[e>>2],a[t+28>>2]=n,n=a[e+20>>2],a[t+40>>2]=a[e+16>>2],a[t+44>>2]=n,n=a[e+36>>2],a[t+56>>2]=a[e+32>>2],a[t+60>>2]=n,n=a[e+52>>2],a[t+72>>2]=a[e+48>>2],a[t+76>>2]=n,e=a[r+4>>2],a[t+88>>2]=a[r>>2],a[t+92>>2]=e,n=r+24|0,o=a[n+4>>2],e=t+112|0,a[e>>2]=a[n>>2],a[e+4>>2]=o,n=a[r+20>>2],e=t+104|0,a[e>>2]=a[r+16>>2],a[e+4>>2]=n,n=r+40|0,o=a[n+4>>2],e=t+128|0,a[e>>2]=a[n>>2],a[e+4>>2]=o,n=a[r+36>>2],e=t+120|0,a[e>>2]=a[r+32>>2],a[e+4>>2]=n,n=r+56|0,o=a[n+4>>2],e=t+144|0,a[e>>2]=a[n>>2],a[e+4>>2]=o,n=a[r+52>>2],e=t+136|0,a[e>>2]=a[r+48>>2],a[e+4>>2]=n,Sr(A,t+24|0,i,0)):(F=C[e+52>>2],W=C[e+56>>2],o=r+52|0,J=C[o>>2],c=r+56|0,x=C[c>>2],g=C[e+20>>2],B=C[e+36>>2],N=r+20|0,d=C[N>>2],S=r+36|0,u=C[S>>2],X=r+24|0,s=C[X>>2],l=C[e+24>>2],T=r+40|0,b=C[T>>2],G=C[e+40>>2],U=C[e+48>>2],K=C[r+48>>2],n=a[A+12>>2],y=C[e+32>>2],p=C[e+16>>2],w=C[e>>2],D=C[e+4>>2],v=C[r+32>>2],m=C[r+16>>2],k=C[r>>2],R=C[r+4>>2],A=a[A+20>>2],Q=C[r+8>>2],E=C[e+8>>2],a[t+172>>2]=0,j=_(_(_(E*k)+_(l*m))+_(G*v)),Z=_(-C[A+52>>2]),O=_(_(_(E*R)+_(l*d))+_(G*u)),e=A+56|0,V=C[e>>2],E=_(_(_(E*Q)+_(l*s))+_(G*b)),I=A+60|0,l=C[I>>2],C[t+168>>2]=_(_(j*Z)-_(O*V))-_(E*l),H=_(_(_(D*k)+_(g*m))+_(B*v)),z=_(_(_(D*R)+_(g*d))+_(B*u)),D=_(_(_(D*Q)+_(g*s))+_(B*b)),C[t+164>>2]=_(_(H*Z)-_(V*z))-_(l*D),P=_(_(_(w*k)+_(p*m))+_(y*v)),h=_(P*Z),Z=_(_(_(w*R)+_(p*d))+_(y*u)),w=_(_(_(w*Q)+_(p*s))+_(y*b)),C[t+160>>2]=_(h-_(V*Z))-_(l*w),Qt[a[a[n>>2]+64>>2]](t+24|0,n,t+160|0),g=C[e>>2],B=C[I>>2],V=C[A+68>>2],l=C[A+52>>2],G=C[t+24>>2],y=C[t+28>>2],p=C[t+32>>2],a[t+172>>2]=0,M=_(_(_(U*k)+_(F*m))+_(W*v)),h=k,k=_(-K),v=_(_(M+_(_(_(h*k)-_(m*J))-_(v*x)))+_(_(_(P*G)+_(H*y))+_(j*p))),b=_(_(_(_(_(U*Q)+_(F*s))+_(W*b))+_(_(_(Q*k)-_(s*J))-_(b*x)))+_(_(_(w*G)+_(D*y))+_(E*p))),s=_(_(_(_(_(U*R)+_(F*d))+_(W*u))+_(_(_(R*k)-_(d*J))-_(u*x)))+_(_(_(Z*G)+_(z*y))+_(O*p))),d=_(_(_(B*b)+_(_(l*v)+_(g*s)))-V),u=_(v-_(l*d)),v=C[r+32>>2],s=_(s-_(g*d)),m=C[S>>2],b=_(b-_(B*d)),k=C[T>>2],C[t+168>>2]=_(_(_(u*v)+_(s*m))+_(b*k))+C[c>>2],R=C[r+16>>2],Q=C[N>>2],F=C[X>>2],C[t+164>>2]=_(_(_(u*R)+_(s*Q))+_(b*F))+C[o>>2],W=C[r+8>>2],M=_(W*b),b=C[r>>2],h=_(b*u),u=C[r+4>>2],C[t+160>>2]=_(M+_(h+_(u*s)))+C[r+48>>2],a[t+20>>2]=0,C[t+16>>2]=_(_(l*v)+_(g*m))+_(B*k),C[t+12>>2]=_(_(l*R)+_(g*Q))+_(B*F),C[t+8>>2]=_(_(b*l)+_(u*g))+_(W*B),Qt[a[a[i>>2]+16>>2]](i,t+8|0,t+160|0,d)),Y=t+240|0}function bf(A,e,r,i,t,n){A|=0,e|=0,r|=0,i|=0,t|=0,n|=0;var c,l=_(0),u=_(0),s=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=0,R=0,Q=0,h=0,G=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=0,E=_(0),Z=_(0),V=0;c=Y-304|0,Y=c,a[c+300>>2]=0,g=_(C[r+56>>2]-C[e+56>>2]),C[c+296>>2]=g,G=_(C[r+52>>2]-C[e+52>>2]),C[c+292>>2]=G,p=_(C[r+48>>2]-C[e+48>>2]),C[c+288>>2]=p,Mi(e,r,c+112|0,c+48|0),a[c+284>>2]=0,u=C[c+48>>2],l=_(u*C[c+120>>2]),C[c+280>>2]=l,s=_(u*C[c+116>>2]),C[c+276>>2]=s,v=_(u*C[c+112>>2]),C[c+272>>2]=v,a[c+268>>2]=0,F=_(C[t+56>>2]-C[i+56>>2]),C[c+264>>2]=F,W=_(C[t+52>>2]-C[i+52>>2]),C[c+260>>2]=W,w=_(C[t+48>>2]-C[i+48>>2]),C[c+256>>2]=w,Mi(i,t,c+112|0,c+48|0),a[c+252>>2]=0,u=C[c+48>>2],d=_(u*C[c+120>>2]),C[c+248>>2]=d,B=_(u*C[c+116>>2]),C[c+244>>2]=B,u=_(u*C[c+112>>2]),C[c+240>>2]=u,r=a[A+12>>2],E=_(Qt[a[a[r>>2]+16>>2]](r)),r=a[A+16>>2],r&&(Z=_(Qt[a[a[r>>2]+16>>2]](r)),g=C[c+296>>2],F=C[c+264>>2],G=C[c+292>>2],W=C[c+260>>2],p=C[c+288>>2],w=C[c+256>>2],d=C[c+248>>2],B=C[c+244>>2],u=C[c+240>>2],s=C[c+276>>2],v=C[c+272>>2],l=C[c+280>>2]),B=_(_(E*_(y(_(_(_(v*v)+_(s*s))+_(l*l)))))+_(Z*_(y(_(_(_(u*u)+_(B*B))+_(d*d)))))),s=_(w-p),v=_(W-G),d=_(F-g);A:if(_(B+_(y(_(_(_(s*s)+_(v*v))+_(d*d)))))!=_(0)&&(f[c+216|0]=0,a[c+212>>2]=1566444395,a[c+176>>2]=15364,cf(A,e,i,c+176|0),t=c+204|0,m=a[t+4>>2],r=c+232|0,a[r>>2]=a[t>>2],a[r+4>>2]=m,r=a[c+200>>2],a[c+224>>2]=a[c+196>>2],a[c+228>>2]=r,o[c+216|0]&&(r=a[c+180>>2],t=c+184|0,m=a[t>>2],Q=c+188|0,h=a[Q>>2],!(_(B+_(_(_(s*C[c+180>>2])+_(v*C[t>>2]))+_(d*C[Q>>2])))<=_(1.1920928955078125e-7))))){R=1;e:{if(g=_(C[c+212>>2]+C[n+172>>2]),g>_(.0010000000474974513)){for(Q=c+20|0,V=c+160|0,t=0,u=_(0);;){if(D=a[n+168>>2],D&&(a[c+120>>2]=1065353216,a[c+124>>2]=0,a[c+112>>2]=1065353216,a[c+116>>2]=1065353216,Qt[a[a[D>>2]+28>>2]](D,c+224|0,_(.20000000298023224),c+112|0)),l=_(B+_(_(_(s*(b(0,r),k()))+_(v*(b(0,m),k())))+_(d*(b(0,h),k())))),l<=_(1.1920928955078125e-7)){R=0;break A}if(l=_(u+_(g/l)),l<=u){R=0;break A}if(l<_(0)){R=0;break A}if(l>_(1)){R=0;break A}if(xi(e,c+288|0,c+272|0,l,c+112|0),xi(i,c+256|0,c+240|0,l,c+48|0),r=a[n+168>>2],r&&(a[c+8>>2]=0,a[c+12>>2]=0,a[c>>2]=1065353216,a[c+4>>2]=0,Qt[a[a[r>>2]+28>>2]](r,V,_(.20000000298023224),c)),Qt[a[a[n>>2]>>2]](n,l),f[c+40|0]=0,a[c+36>>2]=1566444395,a[c>>2]=15364,cf(A,c+112|0,c+48|0,c),!o[c+40|0])break e;if(m=Q+8|0,h=a[m+4>>2],r=c+232|0,a[r>>2]=a[m>>2],a[r+4>>2]=h,r=a[Q+4>>2],a[c+224>>2]=a[Q>>2],a[c+228>>2]=r,t>>>0>63){Qt[a[a[n>>2]+8>>2]](n,-2,t+1|0),R=0;break A}if(t=t+1|0,r=a[c+4>>2],m=a[c+8>>2],h=a[c+12>>2],u=l,g=_(C[c+36>>2]+C[n+172>>2]),!(g>_(.0010000000474974513)))break}s=C[c+16>>2]}else l=_(0),s=C[c+192>>2];a[n+132>>2]=r,C[n+164>>2]=l,A=a[c+228>>2],a[n+148>>2]=a[c+224>>2],a[n+152>>2]=A,C[n+144>>2]=s,a[n+140>>2]=h,a[n+136>>2]=m,e=c+232|0,r=a[e+4>>2],A=n+156|0,a[A>>2]=a[e>>2],a[A+4>>2]=r;break A}Qt[a[a[n>>2]+8>>2]](n,-1,t),R=0}return Y=c+304|0,0|R}function lf(A,e,r,i){var f,t=0;a[A>>2]=20460,t=a[e+4>>2],a[A+4>>2]=a[e>>2],a[A+8>>2]=t,e=e+8|0,t=a[e+4>>2],f=A+12|0,a[f>>2]=a[e>>2],a[f+4>>2]=t,e=a[r+4>>2],a[A+20>>2]=a[r>>2],a[A+24>>2]=e,e=r+8|0,r=a[e+4>>2],t=A+28|0,a[t>>2]=a[e>>2],a[t+4>>2]=r,a[A+40>>2]=1065353216,a[A+36>>2]=i}function uf(A,e,r,i,f,t){var n=0,o=0;a[A+4>>2]=e,a[A>>2]=20484,e=r+8|0,n=a[e+4>>2],o=A+16|0,a[o>>2]=a[e>>2],a[o+4>>2]=n,e=a[r+4>>2],a[A+8>>2]=a[r>>2],a[A+12>>2]=e,e=r+24|0,n=a[e+4>>2],o=A+32|0,a[o>>2]=a[e>>2],a[o+4>>2]=n,e=a[r+20>>2],n=A+24|0,a[n>>2]=a[r+16>>2],a[n+4>>2]=e,e=r+40|0,n=a[e+4>>2],o=A+48|0,a[o>>2]=a[e>>2],a[o+4>>2]=n,e=a[r+36>>2],n=A+40|0,a[n>>2]=a[r+32>>2],a[n+4>>2]=e,e=r+56|0,n=a[e+4>>2],o=A- -64|0,a[o>>2]=a[e>>2],a[o+4>>2]=n,e=a[r+52>>2],n=A+56|0,a[n>>2]=a[r+48>>2],a[n+4>>2]=e,e=i+8|0,r=a[e+4>>2],n=A+80|0,a[n>>2]=a[e>>2],a[n+4>>2]=r,e=a[i+4>>2],a[A+72>>2]=a[i>>2],a[A+76>>2]=e,e=i+24|0,r=a[e+4>>2],n=A+96|0,a[n>>2]=a[e>>2],a[n+4>>2]=r,e=a[i+20>>2],r=A+88|0,a[r>>2]=a[i+16>>2],a[r+4>>2]=e,e=i+40|0,r=a[e+4>>2],n=A+112|0,a[n>>2]=a[e>>2],a[n+4>>2]=r,e=a[i+36>>2],r=A+104|0,a[r>>2]=a[i+32>>2],a[r+4>>2]=e,e=i+56|0,r=a[e+4>>2],n=A+128|0,a[n>>2]=a[e>>2],a[n+4>>2]=r,e=a[i+52>>2],r=A+120|0,a[r>>2]=a[i+48>>2],a[r+4>>2]=e,e=f+8|0,r=a[e+4>>2],i=A+144|0,a[i>>2]=a[e>>2],a[i+4>>2]=r,e=a[f+4>>2],a[A+136>>2]=a[f>>2],a[A+140>>2]=e,e=f+24|0,r=a[e+4>>2],i=A+160|0,a[i>>2]=a[e>>2],a[i+4>>2]=r,e=a[f+20>>2],r=A+152|0,a[r>>2]=a[f+16>>2],a[r+4>>2]=e,e=f+40|0,r=a[e+4>>2],i=A+176|0,a[i>>2]=a[e>>2],a[i+4>>2]=r,e=a[f+36>>2],r=A+168|0,a[r>>2]=a[f+32>>2],a[r+4>>2]=e,e=f+56|0,r=a[e+4>>2],i=A+192|0,a[i>>2]=a[e>>2],a[i+4>>2]=r,e=a[f+52>>2],r=A+184|0,a[r>>2]=a[f+48>>2],a[r+4>>2]=e,a[A+208>>2]=0,C[A+204>>2]=t,a[A+200>>2]=1065353216}function sf(A){A|=0;var e=0,r=0,i=0,t=0,n=0,c=0;if(a[A>>2]=20592,e=a[A+16>>2],r=a[A+8>>2],(0|r)>=1)for(;n=a[e+t>>2],i=a[n+188>>2],i&&(e=a[A+68>>2],e=0|Qt[a[a[e>>2]+36>>2]](e),Qt[a[a[e>>2]+40>>2]](e,i,a[A+24>>2]),e=a[A+68>>2],Qt[a[a[e>>2]+12>>2]](e,i,a[A+24>>2]),a[n+188>>2]=0,r=a[A+8>>2],e=a[A+16>>2]),t=t+4|0,c=c+1|0,(0|c)<(0|r););return e&&(o[A+20|0]&&CA(e),a[A+16>>2]=0),a[A+16>>2]=0,a[A+8>>2]=0,a[A+12>>2]=0,f[A+20|0]=1,0|A}function kf(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var t,n,c,b=0,l=0,u=0,s=0,k=0;if(t=Y-96|0,Y=t,b=a[A+8>>2],a[e+216>>2]=b,a[A+12>>2]==(0|b)&&(s=b?b<<1:1,!((0|b)>=(0|s)))){if(s&&(k=dA(s<<2),b=a[A+8>>2]),(0|b)>=1)for(l=b;a[u+k>>2]=a[a[A+16>>2]+u>>2],u=u+4|0,l=l+-1|0,l;);l=a[A+16>>2],l&&(o[A+20|0]&&(CA(l),b=a[A+8>>2]),a[A+16>>2]=0),a[A+16>>2]=k,a[A+12>>2]=s,f[A+20|0]=1}a[A+8>>2]=b+1,a[a[A+16>>2]+(b<<2)>>2]=e,l=e+12|0,u=a[l+4>>2],b=t+40|0,a[b>>2]=a[l>>2],a[b+4>>2]=u,l=e+28|0,u=a[l+4>>2],b=t+56|0,a[b>>2]=a[l>>2],a[b+4>>2]=u,l=e+44|0,u=a[l+4>>2],b=t+72|0,a[b>>2]=a[l>>2],a[b+4>>2]=u,l=e+60|0,u=a[l+4>>2],b=t+88|0,a[b>>2]=a[l>>2],a[b+4>>2]=u,b=a[e+8>>2],a[t+32>>2]=a[e+4>>2],a[t+36>>2]=b,b=e+20|0,l=a[b+4>>2],a[t+48>>2]=a[b>>2],a[t+52>>2]=l,b=e+36|0,l=a[b+4>>2],a[t+64>>2]=a[b>>2],a[t+68>>2]=l,b=e+52|0,l=a[b+4>>2],a[t+80>>2]=a[b>>2],a[t+84>>2]=l,b=a[e+192>>2],Qt[a[a[b>>2]+8>>2]](b,t+32|0,t+16|0,t),b=a[A+68>>2],n=e,c=0|Qt[a[a[b>>2]+8>>2]](b,t+16|0,t,a[a[e+192>>2]+4>>2],e,r,i,a[A+24>>2]),a[n+188>>2]=c,Y=t+96|0}function vf(A,e){var r,i=_(0),t=_(0),n=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=0;r=Y+-64|0,Y=r,s=a[e+192>>2],Qt[a[a[s>>2]+8>>2]](s,e+4|0,r+48|0,r+32|0),i=C[744],n=_(C[r+48>>2]-i),C[r+48>>2]=n,c=_(C[r+52>>2]-i),C[r+52>>2]=c,b=_(C[r+56>>2]-i),C[r+56>>2]=b,t=_(i+C[r+32>>2]),C[r+32>>2]=t,l=_(i+C[r+36>>2]),C[r+36>>2]=l,u=_(i+C[r+40>>2]),C[r+40>>2]=u,3&o[e+204|0]|!o[A+44|0]|2!=a[e+252>>2]||(s=a[e+192>>2],Qt[a[a[s>>2]+8>>2]](s,e+68|0,r+16|0,r),c=_(C[r+16>>2]-i),C[r+16>>2]=c,b=_(C[r+20>>2]-i),C[r+20>>2]=b,t=_(C[r+24>>2]-i),C[r+24>>2]=t,l=_(i+C[r>>2]),C[r>>2]=l,u=_(i+C[r+4>>2]),C[r+4>>2]=u,i=_(i+C[r+8>>2]),C[r+8>>2]=i,n=C[r+48>>2],c>2]=c,n=c),c=C[r+52>>2],b>2]=b,c=b),b=C[r+56>>2],t>2]=t,b=t),t=C[r+28>>2],t>2]&&(C[r+60>>2]=t),t=C[r+32>>2],t>2]=l,t=l),l=C[r+36>>2],l>2]=u,l=u),u=C[r+40>>2],u>2]=i,u=i),i=C[r+12>>2],C[r+44>>2]>2]=i)),s=a[A+68>>2],1&f[e+204|0]||(n=_(t-n),t=_(n*n),n=_(l-c),t=_(t+_(n*n)),n=_(u-b),_(t+_(n*n))<_(999999995904))?Qt[a[a[s>>2]+16>>2]](s,a[e+188>>2],r+48|0,r+32|0,a[A+24>>2]):(Ye(e,5),o[2804]||(e=a[A+72>>2],e&&(f[2804]=1,Qt[a[a[e>>2]+44>>2]](e,20644),e=a[A+72>>2],Qt[a[a[e>>2]+44>>2]](e,20693),e=a[A+72>>2],Qt[a[a[e>>2]+44>>2]](e,20761),A=a[A+72>>2],Qt[a[a[A>>2]+44>>2]](A,20826)))),Y=r- -64|0}function df(A,e){A|=0,e|=0;var r=0,i=0,f=0,t=0,n=0,o=0,c=0,b=0;i=a[e+188>>2],i&&(r=a[A+68>>2],r=0|Qt[a[a[r>>2]+36>>2]](r),Qt[a[a[r>>2]+40>>2]](r,i,a[A+24>>2]),r=a[A+68>>2],Qt[a[a[r>>2]+12>>2]](r,i,a[A+24>>2]),a[e+188>>2]=0),r=a[e+216>>2],i=a[A+8>>2];A:if((0|r)<0|(0|r)>=(0|i)){if(!((0|i)<1)){for(f=a[A+16>>2],r=f;;){if((0|e)!=a[r>>2]){if(r=r+4|0,t=t+1|0,(0|i)!=(0|t))continue;break A}break}(0|i)<=(0|t)||(n=r,i=i+-1|0,r=i<<2,a[n>>2]=a[r+f>>2],a[A+8>>2]=i,a[r+a[A+16>>2]>>2]=e)}}else{if(t=A+16|0,f=a[t>>2],o=r<<2,c=f+o|0,b=a[c>>2],n=f,i=i+-1|0,f=i<<2,a[c>>2]=a[n+f>>2],a[A+8>>2]=i,a[f+a[t>>2]>>2]=b,(0|r)>=(0|i))break A;a[a[a[A+16>>2]+o>>2]+216>>2]=r}a[e+216>>2]=-1}function Cf(A,e,r,i){var t,n=0,o=_(0),c=_(0),b=_(0),l=_(0),u=0,s=_(0),k=0,v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=0,Q=_(0),h=_(0),G=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),V=_(0),N=_(0),I=0,J=_(0),x=_(0),U=_(0),M=_(0),S=_(0),T=0,j=0,O=0;t=Y-704|0,Y=t,DA(t+624|0),n=t+652|0,a[n>>2]=0,a[n+4>>2]=0,n=t+660|0,a[n>>2]=0,a[n+4>>2]=0,n=t+668|0,a[n>>2]=0,a[n+4>>2]=0,a[t+676>>2]=0,a[t+648>>2]=1065353216,a[t+640>>2]=1065353216,a[t+644>>2]=1065353216,a[t+628>>2]=8,a[t+624>>2]=9852,n=a[r+12>>2];A:if(u=a[r+4>>2],R=a[u+4>>2],(0|R)<=19)a[t+616>>2]=0,a[t+620>>2]=0,a[t+448>>2]=15992,a[t+612>>2]=a[i+4>>2],f[t+420|0]=0,a[t+396>>2]=953267991,R=$r(t+680|0,t+624|0,u,t+88|0),T=Hr(t+72|0,t+624|0,u,t+88|0),j=R,O=8&a[i+20>>2],u=O?T:j,Qt[a[a[u>>2]+8>>2]](u,A,e,n,n,t+448|0)&&(o=C[t+580>>2],b=C[t+584>>2],c=C[t+588>>2],l=_(_(_(o*o)+_(b*b))+_(c*c)),l>_(9999999747378752e-20)&&(s=C[t+612>>2],s>2]&&(d=c,c=_(_(1)/_(y(l))),C[t+588>>2]=d*c,C[t+584>>2]=b*c,C[t+580>>2]=o*c,A=t+580|0,e=A+8|0,n=a[e+4>>2],u=t+56|0,a[u>>2]=a[e>>2],a[u+4>>2]=n,C[t+64>>2]=s,e=a[A+4>>2],a[t+48>>2]=a[A>>2],a[t+52>>2]=e,a[t+44>>2]=0,a[t+40>>2]=a[r+8>>2],_(Qt[a[a[i>>2]+12>>2]](i,t+40|0,1)))));else if(R+-21>>>0<=8){if(g=C[n+20>>2],B=C[n+36>>2],s=C[n+24>>2],b=C[n+52>>2],d=C[n+40>>2],R=n+56|0,p=C[R>>2],m=C[n+32>>2],Q=C[n>>2],h=C[n+16>>2],G=C[n+4>>2],l=C[n+48>>2],F=C[n+8>>2],a[t+460>>2]=0,D=_(-b),w=_(s*D),E=_(-p),V=_(d*E),v=_(_(w-_(F*l))+V),o=C[A+48>>2],c=C[A+52>>2],N=_(s*c),W=C[A+56>>2],J=_(d*W),C[t+456>>2]=v+_(_(_(F*o)+N)+J),l=_(-l),x=_(B*E),Z=_(_(_(G*l)-_(g*b))+x),M=_(B*W),C[t+452>>2]=Z+_(_(_(G*o)+_(g*c))+M),p=_(_(_(Q*l)-_(h*b))-_(m*p)),C[t+448>>2]=p+_(_(_(Q*o)+_(h*c))+_(m*W)),a[t+52>>2]=0,U=v,b=C[e+48>>2],S=_(F*b),v=s,s=C[e+52>>2],F=_(v*s),v=d,d=C[e+56>>2],v=_(v*d),C[t+48>>2]=U+_(_(S+F)+v),U=Z,Z=_(B*d),C[t+44>>2]=U+_(_(_(G*b)+_(g*s))+Z),C[t+40>>2]=p+_(_(_(Q*b)+_(h*s))+_(m*d)),A=n+32|0,e=n+16|0,21==a[u+4>>2]){r=a[r+8>>2],lf(t+88|0,t+448|0,t+40|0,a[i+20>>2]),a[t+140>>2]=u,a[t+136>>2]=r,a[t+132>>2]=i,a[t+88>>2]=21004,r=n+8|0,k=a[r+4>>2],I=t+152|0,a[I>>2]=a[r>>2],a[I+4>>2]=k,r=a[n+4>>2],a[t+144>>2]=a[n>>2],a[t+148>>2]=r,r=e+8|0,k=a[r+4>>2],I=t+168|0,a[I>>2]=a[r>>2],a[I+4>>2]=k,r=a[e+4>>2],k=t+160|0,a[k>>2]=a[e>>2],a[k+4>>2]=r,e=A+8|0,r=a[e+4>>2],k=t+184|0,a[k>>2]=a[e>>2],a[k+4>>2]=r,e=a[A+4>>2],r=t+176|0,a[r>>2]=a[A>>2],a[r+4>>2]=e,A=a[R+4>>2],e=t+200|0,a[e>>2]=a[R>>2],a[e+4>>2]=A,A=a[n+52>>2],e=t+192|0,a[e>>2]=a[n+48>>2],a[e+4>>2]=A,a[t+128>>2]=a[i+4>>2],Te(u,t+88|0,t+448|0,t+40|0);break A}g=C[n+32>>2],B=C[n>>2],m=C[n+16>>2],Q=C[n+4>>2],h=C[n+20>>2],G=C[n+8>>2],a[t+692>>2]=0,p=_(_(_(G*l)+w)+V),C[t+688>>2]=_(_(_(o*G)+N)+J)+p,w=_(_(_(Q*l)+_(h*D))+x),C[t+684>>2]=_(_(_(o*Q)+_(c*h))+M)+w,c=_(_(_(o*B)+_(c*m))+_(W*g)),o=_(_(_(B*l)+_(m*D))+_(g*E)),C[t+680>>2]=c+o,a[t+84>>2]=0,C[t+80>>2]=_(_(_(b*G)+F)+v)+p,C[t+76>>2]=_(_(_(b*Q)+_(s*h))+Z)+w,C[t+72>>2]=_(_(_(b*B)+_(s*m))+_(d*g))+o,r=a[r+8>>2],lf(t+88|0,t+680|0,t+72|0,a[i+20>>2]),a[t+140>>2]=u,a[t+136>>2]=r,a[t+132>>2]=i,a[t+88>>2]=21188,r=a[n+12>>2],k=t+152|0,a[k>>2]=a[n+8>>2],a[k+4>>2]=r,r=a[n+4>>2],a[t+144>>2]=a[n>>2],a[t+148>>2]=r,r=a[e+4>>2],k=t+160|0,a[k>>2]=a[e>>2],a[k+4>>2]=r,e=e+8|0,r=a[e+4>>2],k=t+168|0,a[k>>2]=a[e>>2],a[k+4>>2]=r,e=A+8|0,r=a[e+4>>2],k=t+184|0,a[k>>2]=a[e>>2],a[k+4>>2]=r,e=a[A+4>>2],r=t+176|0,a[r>>2]=a[A>>2],a[r+4>>2]=e,A=a[n+52>>2],e=t+192|0,a[e>>2]=a[n+48>>2],a[e+4>>2]=A,A=a[R+4>>2],e=t+200|0,a[e>>2]=a[R>>2],a[e+4>>2]=A,a[t+128>>2]=a[i+4>>2],A=a[t+692>>2],e=t+32|0,a[e>>2]=a[t+688>>2],a[e+4>>2]=A,A=a[t+684>>2],a[t+24>>2]=a[t+680>>2],a[t+28>>2]=A,o=C[t+72>>2],o>2]&&(C[t+24>>2]=o),b=C[t+76>>2],b>2]&&(C[t+28>>2]=b),c=C[t+80>>2],c>2]&&(C[t+32>>2]=c),l=C[t+84>>2],l>2]&&(C[t+36>>2]=l),A=t+688|0,e=a[A+4>>2],r=t+16|0,a[r>>2]=a[A>>2],a[r+4>>2]=e,A=a[t+684>>2],a[t+8>>2]=a[t+680>>2],a[t+12>>2]=A,C[t+8>>2]>2]=o),C[t+12>>2]>2]=b),C[t+16>>2]>2]=c),C[t+20>>2]>2]=l),Qt[a[a[u>>2]+64>>2]](u,t+88|0,t+24|0,t+8|0)}else if(31==(0|R))if(R=a[u+68>>2],a[t+64>>2]=i,a[t+60>>2]=e,a[t+56>>2]=A,a[t+52>>2]=n,a[t+48>>2]=u,a[t+40>>2]=21376,a[t+44>>2]=a[r+8>>2],R)l=C[n>>2],s=C[n+4>>2],o=C[n+8>>2],a[t+100>>2]=0,v=o,g=C[n+48>>2],o=_(C[A+48>>2]-g),B=C[n+52>>2],b=_(C[A+52>>2]-B),d=C[n+24>>2],m=C[n+56>>2],c=_(C[A+56>>2]-m),Q=C[n+40>>2],C[t+96>>2]=_(_(v*o)+_(b*d))+_(c*Q),v=_(o*s),s=C[n+20>>2],h=C[n+36>>2],C[t+92>>2]=_(v+_(b*s))+_(c*h),o=_(o*l),l=C[n+16>>2],G=C[n+32>>2],C[t+88>>2]=_(o+_(b*l))+_(c*G),F=C[n>>2],W=C[n+4>>2],o=C[n+8>>2],a[t+460>>2]=0,v=o,o=_(C[e+48>>2]-g),b=_(C[e+52>>2]-B),c=_(C[e+56>>2]-m),C[t+456>>2]=_(_(v*o)+_(d*b))+_(Q*c),C[t+452>>2]=_(_(o*W)+_(b*s))+_(c*h),C[t+448>>2]=_(_(o*F)+_(b*l))+_(c*G),function(A,e,r,i){var f=0,t=_(0),n=_(0),o=_(0),c=_(0),b=0,l=_(0),u=_(0),s=0,k=0,v=0,d=0,g=0,B=_(0),m=_(0),R=0,Q=0,h=_(0),G=0,p=0,F=_(0),W=0,w=0,D=0,E=0,Z=0,V=0,N=0;if(f=Y-544|0,Y=f,A){for(t=C[e+8>>2],c=C[r+8>>2],l=C[e>>2],n=C[r>>2],u=C[e+4>>2],o=C[r+4>>2],a[f+32>>2]=A,n=_(n-l),o=_(o-u),t=_(c-t),c=_(_(1)/_(y(_(_(_(n*n)+_(o*o))+_(t*t))))),B=t,t=_(t*c),m=n,n=_(n*c),h=o,o=_(o*c),h=_(_(B*t)+_(_(m*n)+_(h*o))),t=t==_(0)?_(0xde0b6b000000000):_(_(1)/t),A=t<_(0),W=(A<<4)+f|8,o=o==_(0)?_(0xde0b6b000000000):_(_(1)/o),r=o<_(0),w=(r<<4)+f|4,D=((1^A)<<4)+f|8,E=((1^r)<<4)+f|4,n=n==_(0)?_(0xde0b6b000000000):_(_(1)/n),A=n<_(0),Z=(A<<4)+f|0,V=((1^A)<<4)+f|0,G=f+16|0,g=126,s=128,d=f+32|0,k=128,Q=1;;){A=Q+-1|0,p=A<<2,v=a[p+d>>2],r=a[v+20>>2],a[G>>2]=a[v+16>>2],a[G+4>>2]=r,b=v+24|0,N=a[b+4>>2],r=G+8|0,a[r>>2]=a[b>>2],a[r+4>>2]=N,r=a[v+4>>2],a[f>>2]=a[v>>2],a[f+4>>2]=r,r=v+8|0,b=a[r+4>>2],a[f+8>>2]=a[r>>2],a[f+12>>2]=b;e:{r:{i:{f:{t:{n:{a:{o:{if(c=_(o*_(C[w>>2]-u)),B=_(n*_(C[V>>2]-l)),!(c>B||(l=_(n*_(C[Z>>2]-l)),u=_(o*_(C[E>>2]-u)),l>u||(F=C[e+8>>2],m=_(t*_(C[W>>2]-F)),u=uu||(l=c>l?c:l,c=_(t*_(C[D>>2]-F)),l>c|(m>l?m:l)_(0)^1))))){if(a[v+40>>2]){if((0|A)<=(0|g)){r=d,b=k;break r}if(b=k<<1,(0|k)>=(0|b)){r=d;break i}if((0|s)>=(0|b)){r=d;break f}if(!k){r=0;break o}if(r=dA(k<<3),(0|k)<1)break o;for(A=r,g=d,s=k;a[A>>2]=a[g>>2],A=A+4|0,g=g+4|0,s=s+-1|0,s;);if(!R)break n;break a}Qt[a[a[i>>2]+12>>2]](i,v)}r=d,b=k;break e}if(A=R,R=1,s=R,!A)break t;if(s=b,!d)break f}CA(d)}s=1}R=s,s=b}A=k<<2,X(A+r|0,0,A)}g=b+-2|0}a[r+p>>2]=a[v+36>>2],a[(Q<<2)+r>>2]=a[v+40>>2],A=Q+1|0}if(!A)break;u=C[e+4>>2],l=C[e>>2],d=r,k=b,Q=A}!R|!r||CA(r)}Y=f+544|0}(a[R>>2],t+88|0,t+448|0,t+40|0);else if(A=a[u+20>>2],!((0|A)<1))for(e=A+-1|0,i=64,r=0;;){if(A=a[u+28>>2]+i|0,u=a[A>>2],J=C[n+52>>2],x=C[n+56>>2],Q=C[A+-16>>2],h=C[A+-12>>2],G=C[A+-8>>2],o=C[n+20>>2],b=C[n+24>>2],F=C[A+-64>>2],W=C[A+-48>>2],p=C[A+-32>>2],D=C[A+-60>>2],E=C[A+-44>>2],w=C[A+-28>>2],V=C[A+-56>>2],c=C[n+36>>2],v=C[A+-40>>2],l=C[n+40>>2],N=C[A+-24>>2],Z=C[n+48>>2],s=C[n+8>>2],g=C[n>>2],B=C[n+4>>2],d=C[n+16>>2],m=C[n+32>>2],a[t+148>>2]=0,a[t+132>>2]=0,a[t+116>>2]=0,a[t+100>>2]=0,C[t+128>>2]=_(_(V*m)+_(v*c))+_(N*l),C[t+124>>2]=_(_(D*m)+_(E*c))+_(w*l),C[t+120>>2]=_(_(F*m)+_(W*c))+_(p*l),C[t+112>>2]=_(_(V*d)+_(v*o))+_(N*b),C[t+108>>2]=_(_(D*d)+_(E*o))+_(w*b),C[t+104>>2]=_(_(F*d)+_(W*o))+_(p*b),C[t+96>>2]=_(_(g*V)+_(B*v))+_(s*N),C[t+92>>2]=_(_(g*D)+_(B*E))+_(s*w),C[t+88>>2]=_(_(F*g)+_(W*B))+_(p*s),C[t+144>>2]=x+_(_(_(m*Q)+_(c*h))+_(l*G)),C[t+140>>2]=J+_(_(_(d*Q)+_(o*h))+_(b*G)),C[t+136>>2]=Z+_(_(_(g*Q)+_(B*h))+_(s*G)),a[t+700>>2]=r,a[t+696>>2]=-1,a[t+688>>2]=a[t+44>>2],a[t+684>>2]=u,a[t+680>>2]=0,a[t+692>>2]=t+88,a[t+452>>2]=1065353216,a[t+464>>2]=-1,a[t+468>>2]=0,a[t+456>>2]=0,a[t+460>>2]=1,a[t+476>>2]=r,a[t+448>>2]=21552,A=a[t+64>>2],a[t+472>>2]=A,a[t+452>>2]=a[A+4>>2],a[t+468>>2]=a[A+20>>2],Cf(a[t+56>>2],a[t+60>>2],t+680|0,t+448|0),(0|e)==(0|r))break A;r=r+1|0,i=i+80|0,n=a[t+52>>2],u=a[t+48>>2]}Y=t+704|0}function gf(A,e,r,i,f,t,n,o){var c;c=Y-32|0,Y=c,a[c+24>>2]=-1,a[c+28>>2]=-1,a[c+20>>2]=t,a[c+16>>2]=i,a[c+12>>2]=f,a[c+8>>2]=0,Bf(A,e,r,c+8|0,n,o),Y=c+32|0}function Bf(A,e,r,i,t,n){var o,c,b=0,l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=0,Z=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0),U=0,M=_(0),S=_(0),X=0,T=0,j=0,O=0,H=0,z=0,P=0,K=0,L=0,q=0,$=0,AA=0,eA=0,rA=_(0);o=Y-688|0,Y=o,b=a[i+12>>2],c=a[i+4>>2],E=a[c+4>>2];A:if((0|E)<=19)C[o+660>>2]=n,a[o+656>>2]=0,a[o+488>>2]=15992,a[o+652>>2]=a[t+4>>2],f[o+460|0]=0,a[o+436>>2]=953267991,a[o+64>>2]=14800,A=of(o+664|0,A,c,o+128|0,o- -64|0),Qt[a[a[A>>2]+8>>2]](A,e,r,b,b,o+488|0)&&(n=C[o+620>>2],l=C[o+624>>2],u=C[o+628>>2],s=_(_(_(n*n)+_(l*l))+_(u*u)),s>_(9999999747378752e-20)&&(k=C[o+652>>2],k>2]&&(v=u,u=_(_(1)/_(y(s))),C[o+628>>2]=v*u,C[o+624>>2]=l*u,C[o+620>>2]=n*u,A=o+644|0,e=a[A+4>>2],r=o+112|0,a[r>>2]=a[A>>2],a[r+4>>2]=e,A=o+620|0,e=A+8|0,r=a[e+4>>2],b=o+96|0,a[b>>2]=a[e>>2],a[b+4>>2]=r,e=a[o+640>>2],a[o+104>>2]=a[o+636>>2],a[o+108>>2]=e,C[o+120>>2]=k,e=a[A+4>>2],a[o+88>>2]=a[A>>2],a[o+92>>2]=e,a[o+84>>2]=0,a[o+80>>2]=a[i+8>>2],_(Qt[a[a[t>>2]+12>>2]](t,o+80|0,1)))));else if(U=E+-21|0,U>>>0<=8){e:if(!(U>>>0>7)){switch(U-1|0){default:l=C[b+20>>2],u=C[b+36>>2],g=C[b+52>>2],s=C[b+24>>2],B=C[b+56>>2],k=C[b+40>>2],d=C[b+32>>2],R=C[b>>2],Q=C[b+16>>2],m=C[b+4>>2],v=C[b+8>>2],h=C[b+48>>2],a[o+92>>2]=0,h=_(-h),W=_(_(_(v*h)-_(s*g))-_(k*B)),p=C[e+48>>2],G=C[e+52>>2],F=C[e+56>>2],C[o+88>>2]=W+_(_(_(v*p)+_(s*G))+_(k*F)),w=_(_(_(m*h)-_(l*g))-_(u*B)),C[o+84>>2]=w+_(_(_(m*p)+_(l*G))+_(u*F)),Z=_(_(_(R*h)-_(Q*g))-_(d*B)),C[o+80>>2]=Z+_(_(_(R*p)+_(Q*G))+_(d*F)),a[o+676>>2]=0,g=C[r+48>>2],B=C[r+52>>2],h=C[r+56>>2],C[o+672>>2]=W+_(_(_(v*g)+_(s*B))+_(k*h)),C[o+668>>2]=w+_(_(_(m*g)+_(l*B))+_(u*h)),C[o+664>>2]=Z+_(_(_(R*g)+_(Q*B))+_(d*h)),a[o+516>>2]=0,g=C[r+8>>2],B=C[r+24>>2],h=C[r+40>>2],C[o+528>>2]=_(_(v*g)+_(s*B))+_(k*h),p=C[r+4>>2],G=C[r+20>>2],F=C[r+36>>2],C[o+524>>2]=_(_(v*p)+_(s*G))+_(k*F),C[o+512>>2]=_(_(m*g)+_(l*B))+_(u*h),C[o+508>>2]=_(_(m*p)+_(l*G))+_(u*F),a[o+500>>2]=0,Z=v,v=C[r>>2],D=s,s=C[r+16>>2],V=k,k=C[r+32>>2],C[o+520>>2]=_(_(Z*v)+_(D*s))+_(V*k),C[o+504>>2]=_(_(m*v)+_(l*s))+_(u*k),C[o+496>>2]=_(_(R*g)+_(Q*B))+_(d*h),C[o+492>>2]=_(_(R*p)+_(Q*G))+_(d*F),C[o+488>>2]=_(_(R*v)+_(Q*s))+_(d*k),a[o+548>>2]=0,E=o+540|0,a[E>>2]=0,a[E+4>>2]=0,E=o+532|0,a[E>>2]=0,a[E+4>>2]=0,i=a[i+8>>2],uf(o+128|0,A,e,r,b,_(Qt[a[a[c>>2]+48>>2]](c))),a[o+348>>2]=c,a[o+344>>2]=i,a[o+128>>2]=21724,C[o+336>>2]=n,a[o+340>>2]=t,a[o+328>>2]=a[t+4>>2],Qt[a[a[A>>2]+8>>2]](A,o+488|0,o- -64|0,o+48|0),je(c,o+128|0,o+80|0,o+664|0,o- -64|0,o+48|0);break A;case 0:case 1:case 2:case 3:case 4:case 5:break e;case 6:}C[o+300>>2]=n,a[o+296>>2]=0,a[o+128>>2]=15992,a[o+292>>2]=a[t+4>>2],A=function(A,e,r){return a[A+20>>2]=r,a[A+16>>2]=0,a[A+12>>2]=e,a[A+4>>2]=0,a[A+8>>2]=0,a[A>>2]=20396,A}(o+80|0,A,c),Qt[a[a[A>>2]+8>>2]](A,e,r,b,b,o+128|0)&&(n=C[o+260>>2],l=C[o+264>>2],u=C[o+268>>2],s=_(_(_(n*n)+_(l*l))+_(u*u)),s>_(9999999747378752e-20)&&(k=C[o+292>>2],k>2]&&(v=u,u=_(_(1)/_(y(s))),C[o+268>>2]=v*u,C[o+264>>2]=l*u,C[o+260>>2]=n*u,A=o+284|0,e=a[A+4>>2],r=o+520|0,a[r>>2]=a[A>>2],a[r+4>>2]=e,A=o+260|0,e=A+8|0,r=a[e+4>>2],b=o+504|0,a[b>>2]=a[e>>2],a[b+4>>2]=r,e=a[o+280>>2],a[o+512>>2]=a[o+276>>2],a[o+516>>2]=e,C[o+528>>2]=k,e=a[A+4>>2],a[o+496>>2]=a[A>>2],a[o+500>>2]=e,a[o+492>>2]=0,a[o+488>>2]=a[i+8>>2],_(Qt[a[a[t>>2]+12>>2]](t,o+488|0,1)))));break A}h=C[r+52>>2],p=C[r+56>>2],u=C[b+52>>2],G=C[b+56>>2],F=C[e+52>>2],W=C[e+56>>2],k=C[b+20>>2],d=C[b+36>>2],m=C[b+24>>2],v=C[b+40>>2],w=C[r+48>>2],rA=C[b+48>>2],Z=C[e+48>>2],s=C[b+32>>2],R=C[b>>2],Q=C[b+16>>2],g=C[b+4>>2],B=C[b+8>>2],a[o+516>>2]=0,l=C[r+8>>2],D=C[r+24>>2],V=C[r+40>>2],C[o+528>>2]=_(_(B*l)+_(m*D))+_(v*V),I=C[r+4>>2],J=C[r+20>>2],x=C[r+36>>2],C[o+524>>2]=_(_(B*I)+_(m*J))+_(v*x),C[o+512>>2]=_(_(g*l)+_(k*D))+_(d*V),C[o+508>>2]=_(_(g*I)+_(k*J))+_(d*x),a[o+500>>2]=0,N=C[r>>2],M=C[r+16>>2],S=C[r+32>>2],C[o+520>>2]=_(_(B*N)+_(m*M))+_(v*S),C[o+504>>2]=_(_(g*N)+_(k*M))+_(d*S),C[o+496>>2]=_(_(R*l)+_(Q*D))+_(s*V),C[o+492>>2]=_(_(R*I)+_(Q*J))+_(s*x),C[o+488>>2]=_(_(R*N)+_(Q*M))+_(s*S),a[o+548>>2]=0,E=o+540|0,a[E>>2]=0,a[E+4>>2]=0,E=o+532|0,a[E>>2]=0,a[E+4>>2]=0,i=a[i+8>>2],uf(o+128|0,A,e,r,b,_(Qt[a[a[c>>2]+48>>2]](c))),a[o+348>>2]=c,a[o+344>>2]=i,a[o+128>>2]=21936,C[o+336>>2]=n,a[o+340>>2]=t,a[o+328>>2]=a[t+4>>2],Qt[a[a[A>>2]+8>>2]](A,o+488|0,o+80|0,o+664|0),a[o+76>>2]=0,D=_(-rA),V=_(_(_(B*D)-_(m*u))-_(v*G)),n=_(V+_(_(_(B*Z)+_(m*F))+_(v*W))),C[o+72>>2]=n,I=_(_(_(g*D)-_(k*u))-_(d*G)),l=_(I+_(_(_(g*Z)+_(k*F))+_(d*W))),C[o+68>>2]=l,G=_(_(_(R*D)-_(Q*u))-_(s*G)),u=_(G+_(_(_(R*Z)+_(Q*F))+_(s*W))),C[o+64>>2]=u,s=_(G+_(_(_(R*w)+_(Q*h))+_(s*p))),R=u,s>2]=s,R=s),Q=l,k=_(I+_(_(_(g*w)+_(k*h))+_(d*p))),k>2]=k,Q=k),d=_(V+_(_(_(B*w)+_(m*h))+_(v*p))),m=n,d>2]=d,m=d),a[o+60>>2]=0,C[o+56>>2]=n,C[o+52>>2]=l,C[o+48>>2]=u,u>2]=s,u=s),l>2]=k,l=k),n>2]=d,n=d),C[o+64>>2]=C[o+80>>2]+R,C[o+68>>2]=C[o+84>>2]+Q,C[o+72>>2]=C[o+88>>2]+m,C[o+48>>2]=C[o+664>>2]+u,C[o+52>>2]=C[o+668>>2]+l,C[o+56>>2]=C[o+672>>2]+n,Qt[a[a[c>>2]+64>>2]](c,o+128|0,o- -64|0,o+48|0)}else if(31==(0|E)){Lr(o+40|0,20933),E=b+52|0,g=C[E>>2],U=b+56|0,B=C[U>>2],h=C[e+52>>2],p=C[e+56>>2],X=b+20|0,l=C[X>>2],T=b+36|0,u=C[T>>2],G=C[e+20>>2],F=C[e+36>>2],W=C[e+24>>2],j=b+24|0,s=C[j>>2],w=C[e+40>>2],O=b+40|0,k=C[O>>2],d=C[b+32>>2],R=C[b>>2],Q=C[b+16>>2],Z=C[e+32>>2],D=C[e>>2],V=C[e+16>>2],N=C[b+48>>2],I=C[e+48>>2],m=C[b+4>>2],J=C[e+4>>2],x=C[e+8>>2],v=C[b+8>>2],H=o+188|0,a[H>>2]=0,z=o+172|0,a[z>>2]=0,P=o+156|0,a[P>>2]=0,K=o+168|0,C[K>>2]=_(_(v*x)+_(s*W))+_(k*w),L=o+164|0,C[L>>2]=_(_(v*J)+_(s*G))+_(k*F),q=o+152|0,C[q>>2]=_(_(m*x)+_(l*W))+_(u*w),$=o+148|0,C[$>>2]=_(_(m*J)+_(l*G))+_(u*F),AA=o+184|0,N=_(-N),C[AA>>2]=_(_(_(v*N)-_(s*g))-_(k*B))+_(_(_(v*I)+_(s*h))+_(k*p)),eA=o+180|0,C[eA>>2]=_(_(_(m*N)-_(l*g))-_(u*B))+_(_(_(m*I)+_(l*h))+_(u*p)),a[o+140>>2]=0,C[o+160>>2]=_(_(v*D)+_(s*V))+_(k*Z),C[o+144>>2]=_(_(m*D)+_(l*V))+_(u*Z),C[o+136>>2]=_(_(R*x)+_(Q*W))+_(d*w),C[o+176>>2]=_(_(_(R*N)-_(Q*g))-_(d*B))+_(_(_(R*I)+_(Q*h))+_(d*p)),C[o+132>>2]=_(_(R*J)+_(Q*G))+_(d*F),C[o+128>>2]=_(_(R*D)+_(Q*V))+_(d*Z),Qt[a[a[A>>2]+8>>2]](A,o+128|0,o- -64|0,o+48|0),g=C[E>>2],B=C[U>>2],h=C[r+52>>2],p=C[r+56>>2],l=C[X>>2],u=C[T>>2],G=C[r+20>>2],F=C[r+36>>2],W=C[r+24>>2],s=C[j>>2],w=C[r+40>>2],k=C[O>>2],d=C[b+32>>2],R=C[b>>2],Q=C[b+16>>2],Z=C[r+32>>2],D=C[r>>2],V=C[r+16>>2],N=C[b+48>>2],I=C[r+48>>2],m=C[b+4>>2],J=C[r+4>>2],x=C[r+8>>2],v=C[b+8>>2],a[H>>2]=0,a[z>>2]=0,a[P>>2]=0,C[K>>2]=_(_(v*x)+_(s*W))+_(k*w),C[L>>2]=_(_(v*J)+_(s*G))+_(k*F),C[q>>2]=_(_(m*x)+_(l*W))+_(u*w),C[$>>2]=_(_(m*J)+_(l*G))+_(u*F),N=_(-N),C[AA>>2]=_(_(_(v*N)-_(s*g))-_(k*B))+_(_(_(v*I)+_(s*h))+_(k*p)),C[eA>>2]=_(_(_(m*N)-_(l*g))-_(u*B))+_(_(_(m*I)+_(l*h))+_(u*p)),a[o+140>>2]=0,C[o+160>>2]=_(_(v*D)+_(s*V))+_(k*Z),C[o+144>>2]=_(_(m*D)+_(l*V))+_(u*Z),C[o+136>>2]=_(_(R*x)+_(Q*W))+_(d*w),C[o+176>>2]=_(_(_(R*N)-_(Q*g))-_(d*B))+_(_(_(R*I)+_(Q*h))+_(d*p)),C[o+132>>2]=_(_(R*J)+_(Q*G))+_(d*F),C[o+128>>2]=_(_(R*D)+_(Q*V))+_(d*Z),Qt[a[a[A>>2]+8>>2]](A,o+128|0,o+24|0,o+8|0),l=C[o+24>>2],l>2]&&(C[o+64>>2]=l),l=C[o+28>>2],l>2]&&(C[o+68>>2]=l),l=C[o+32>>2],l>2]&&(C[o+72>>2]=l),l=C[o+36>>2],l>2]&&(C[o+76>>2]=l),l=C[o+8>>2],C[o+48>>2]>2]=l),l=C[o+12>>2],C[o+52>>2]>2]=l),l=C[o+16>>2],C[o+56>>2]>2]=l),l=C[o+20>>2],C[o+60>>2]>2]=l),a[o+520>>2]=t,a[o+516>>2]=b,C[o+508>>2]=n,a[o+504>>2]=r,a[o+500>>2]=e,a[o+496>>2]=A,a[o+492>>2]=i,a[o+488>>2]=22152,a[o+512>>2]=c,A=a[c+68>>2];e:{if(!A){if(a[c+20>>2]<1)break e;for(i=64,e=1;;){if(A=a[c+28>>2]+i|0,r=a[A>>2],n=C[A+-16>>2],l=C[A+-12>>2],u=C[A+-8>>2],s=C[A+-64>>2],k=C[A+-48>>2],d=C[A+-32>>2],R=C[A+-60>>2],Q=C[A+-44>>2],m=C[A+-28>>2],v=C[A+-56>>2],g=C[A+-40>>2],B=C[A+-24>>2],a[o+188>>2]=0,a[o+172>>2]=0,a[o+156>>2]=0,a[o+140>>2]=0,h=C[b+32>>2],p=C[b+36>>2],G=C[b+40>>2],C[o+168>>2]=_(_(v*h)+_(g*p))+_(B*G),C[o+164>>2]=_(_(R*h)+_(Q*p))+_(m*G),C[o+160>>2]=_(_(s*h)+_(k*p))+_(d*G),F=C[b+16>>2],W=C[b+20>>2],w=C[b+24>>2],C[o+152>>2]=_(_(v*F)+_(g*W))+_(B*w),C[o+148>>2]=_(_(R*F)+_(Q*W))+_(m*w),C[o+144>>2]=_(_(s*F)+_(k*W))+_(d*w),Z=v,v=C[b>>2],D=g,g=C[b+4>>2],V=B,B=C[b+8>>2],C[o+136>>2]=_(_(Z*v)+_(D*g))+_(V*B),C[o+132>>2]=_(_(R*v)+_(Q*g))+_(m*B),C[o+128>>2]=_(_(s*v)+_(k*g))+_(d*B),C[o+184>>2]=_(_(_(n*h)+_(l*p))+_(u*G))+C[b+56>>2],C[o+180>>2]=_(_(_(n*F)+_(l*W))+_(u*w))+C[b+52>>2],C[o+176>>2]=_(_(_(n*v)+_(l*g))+_(u*B))+C[b+48>>2],a[o+84>>2]=1065353216,a[o+88>>2]=1,a[o+92>>2]=-1,A=e+-1|0,a[o+100>>2]=A,t=a[o+520>>2],a[o+96>>2]=t,a[o+80>>2]=22368,a[o+84>>2]=a[t+4>>2],a[o+684>>2]=A,a[o+680>>2]=-1,a[o+668>>2]=r,A=a[o+492>>2],a[o+664>>2]=A,a[o+672>>2]=a[A+8>>2],a[o+676>>2]=o+128,Bf(a[o+496>>2],a[o+500>>2],a[o+504>>2],o+664|0,o+80|0,C[o+508>>2]),(0|e)>=a[c+20>>2])break e;i=i+80|0,e=e+1|0,b=a[o+516>>2]}}e=o+72|0,r=a[e+4>>2],i=o+136|0,a[i>>2]=a[e>>2],a[i+4>>2]=r,e=o+56|0,r=a[e+4>>2],i=o+152|0,a[i>>2]=a[e>>2],a[i+4>>2]=r,e=a[o+52>>2],a[o+144>>2]=a[o+48>>2],a[o+148>>2]=e,e=a[o+68>>2],a[o+128>>2]=a[o+64>>2],a[o+132>>2]=e,Wi(A,a[A>>2],o+128|0,o+488|0)}qr()}Y=o+688|0}function _f(A,e,r,i,f,t){var n,o,c=0,b=0,l=0,u=0,s=0,k=0,v=_(0),d=_(0),g=0,B=_(0),m=_(0),R=_(0),Q=_(0),h=0,G=_(0),p=0,F=_(0),W=0,w=0,D=_(0);n=Y-400|0,Y=n,Lr(n+392|0,20953),u=r+8|0,l=u,c=a[l+4>>2],g=n+336|0,a[g>>2]=a[l>>2],a[g+4>>2]=c,g=r+24|0,c=g,s=a[c+4>>2],l=n+352|0,a[l>>2]=a[c>>2],a[l+4>>2]=s,l=r+40|0,k=a[l+4>>2],c=n+368|0,a[c>>2]=a[l>>2],a[c+4>>2]=k,c=r+56|0,p=a[c+4>>2],s=n+384|0,a[s>>2]=a[c>>2],a[s+4>>2]=p,s=i+8|0,h=a[s+4>>2],k=n+272|0,a[k>>2]=a[s>>2],a[k+4>>2]=h,k=a[r+4>>2],a[n+328>>2]=a[r>>2],a[n+332>>2]=k,k=a[r+20>>2],a[n+344>>2]=a[r+16>>2],a[n+348>>2]=k,k=a[r+36>>2],a[n+360>>2]=a[r+32>>2],a[n+364>>2]=k,k=a[r+52>>2],a[n+376>>2]=a[r+48>>2],a[n+380>>2]=k,k=a[i+4>>2],a[n+264>>2]=a[i>>2],a[n+268>>2]=k,k=i+24|0,b=a[k+4>>2],p=n+288|0,a[p>>2]=a[k>>2],a[p+4>>2]=b,p=i+40|0,b=p,W=a[b+4>>2],h=n+304|0,a[h>>2]=a[b>>2],a[h+4>>2]=W,h=i+56|0,w=a[h+4>>2],b=n+320|0,a[b>>2]=a[h>>2],a[b+4>>2]=w,b=a[i+20>>2],a[n+280>>2]=a[i+16>>2],a[n+284>>2]=b,b=a[i+36>>2],a[n+296>>2]=a[i+32>>2],a[n+300>>2]=b,b=a[i+52>>2],a[n+312>>2]=a[i+48>>2],a[n+316>>2]=b,Mi(n+328|0,n+264|0,n,n+248|0),a[n+228>>2]=0,v=C[n+248>>2],C[n+224>>2]=v*C[n+8>>2],C[n+220>>2]=v*C[n+4>>2],C[n+216>>2]=v*C[n>>2],b=n+208|0,a[b>>2]=0,a[b+4>>2]=0,a[n+200>>2]=0,a[n+204>>2]=0,b=n+56|0,a[b>>2]=0,a[b+4>>2]=0,b=n+48|0,a[b>>2]=0,a[b+4>>2]=0,tt(n+328|0,n+248|0),b=n+44|0,a[b>>2]=0,W=n+28|0,a[W>>2]=0,v=C[n+248>>2],d=C[n+252>>2],B=C[n+256>>2],R=C[n+260>>2],m=_(_(2)/_(_(_(_(v*v)+_(d*d))+_(B*B))+_(R*R))),F=_(B*m),Q=_(d*F),G=_(v*m),D=_(R*G),C[n+36>>2]=Q+D,w=n+24|0,C[w>>2]=Q-D,Q=_(v*G),G=d,d=_(d*m),m=_(G*d),C[n+40>>2]=_(1)-_(Q+m),B=_(B*F),C[n+20>>2]=_(1)-_(Q+B),a[n+12>>2]=0,Q=_(v*F),G=_(R*d),C[n+32>>2]=Q-G,v=_(v*d),d=_(R*F),C[n+16>>2]=v+d,C[n+8>>2]=Q+G,C[n+4>>2]=v-d,C[n>>2]=_(1)-_(m+B),RA(e,n,n+200|0,n+216|0,n+248|0,n+232|0),o=a[u+4>>2],a[b>>2]=a[u>>2],a[b+4>>2]=o,b=a[r+20>>2],u=n+52|0,a[u>>2]=a[r+16>>2],a[u+4>>2]=b,b=a[g+4>>2],u=n+60|0,a[u>>2]=a[g>>2],a[u+4>>2]=b,g=a[r+36>>2],u=n+68|0,a[u>>2]=a[r+32>>2],a[u+4>>2]=g,g=a[l+4>>2],u=n+76|0,a[u>>2]=a[l>>2],a[u+4>>2]=g,l=a[r+52>>2],u=n+84|0,a[u>>2]=a[r+48>>2],a[u+4>>2]=l,b=a[c+4>>2],g=n+92|0,l=g,a[l>>2]=a[c>>2],a[l+4>>2]=b,c=a[s+4>>2],l=n+108|0,a[l>>2]=a[s>>2],a[l+4>>2]=c,a[n>>2]=22756,l=a[r+4>>2],a[n+36>>2]=a[r>>2],a[n+40>>2]=l,r=a[i+4>>2],a[n+100>>2]=a[i>>2],a[n+104>>2]=r,c=a[i+52>>2],r=n+148|0,a[r>>2]=a[i+48>>2],a[r+4>>2]=c,s=a[h+4>>2],l=n+156|0,c=l,a[c>>2]=a[h>>2],a[c+4>>2]=s,s=a[k+4>>2],c=n+124|0,a[c>>2]=a[k>>2],a[c+4>>2]=s,s=a[i+20>>2],c=n+116|0,a[c>>2]=a[i+16>>2],a[c+4>>2]=s,s=a[p+4>>2],c=n+140|0,a[c>>2]=a[p>>2],a[c+4>>2]=s,s=a[i+36>>2],c=n+132|0,a[c>>2]=a[i+32>>2],a[c+4>>2]=s,a[n+184>>2]=f,C[n+188>>2]=t,a[n+192>>2]=e,v=C[n+88>>2],d=C[n+152>>2],t=C[u>>2],R=C[r>>2],B=C[g>>2],m=C[l>>2],a[n+180>>2]=A,t=_(R-t),v=_(d-v),d=_(m-B),R=_(_(1)/_(y(_(_(_(t*t)+_(v*v))+_(d*d))))),B=_(d*R),F=B==_(0)?_(0xde0b6b000000000):_(_(1)/B),a[W>>2]=F<_(0),m=_(v*R),Q=m==_(0)?_(0xde0b6b000000000):_(_(1)/m),a[w>>2]=Q<_(0),C[n+12>>2]=F,C[n+8>>2]=Q,G=t,t=_(t*R),C[n+32>>2]=_(d*B)+_(_(G*t)+_(v*m)),t=t==_(0)?_(0xde0b6b000000000):_(_(1)/t),C[n+4>>2]=t,a[n+20>>2]=t<_(0),A=a[A+68>>2],Qt[a[a[A>>2]+24>>2]](A,n+376|0,n+312|0,n,n+248|0,n+232|0),qr(),Y=n+400|0}function mf(A){A|=0;var e,r=0,i=0,t=0,n=_(0),c=0,b=0,l=0,u=0,s=0,k=_(0),v=0,d=0,g=_(0),B=_(0),m=_(0),R=_(0),Q=0;if(e=Y-192|0,Y=e,Qt[a[a[A>>2]+20>>2]](A)){if(i=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[i>>2]+100>>2]](i),i=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[i>>2]+8>>2]](e+80|0,i),i=0|Qt[a[a[A>>2]+20>>2]](A),8&Qt[a[a[i>>2]+56>>2]](i)&&(i=a[A+24>>2],i&&(u=0|Qt[a[a[i>>2]+36>>2]](i),!((0|u)<1))))for(v=e+176|0,i=0;;){if(c=a[A+24>>2],c=0|Qt[a[a[c>>2]+40>>2]](c,i),l=a[c+780>>2],(0|l)>=1)for(c=c+160|0;s=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[s>>2]+40>>2]](s,c+-124|0,c+-92|0,C[c+-76>>2],a[c>>2],v),c=c+192|0,l=l+-1|0,l;);if(i=i+1|0,(0|u)==(0|i))break}if(i=0|Qt[a[a[A>>2]+20>>2]](A),!(!(3&Qt[a[a[i>>2]+56>>2]](i))|a[A+8>>2]<1))for(l=e+160|0,u=e+96|0,v=e+112|0,s=e+128|0,d=e+144|0,c=0;;){if(i=a[a[A+16>>2]+c>>2],!(32&o[i+204|0])){if(Qt[a[a[A>>2]+20>>2]](A)&&(r=0|Qt[a[a[A>>2]+20>>2]](A),1&Qt[a[a[r>>2]+56>>2]](r))){a[e+72>>2]=1053609165,a[e+76>>2]=0,a[e+64>>2]=1053609165,a[e+68>>2]=1053609165,r=a[i+220>>2]+-1|0;A:if(r>>>0<=4){switch(r-1|0){default:t=e+88|0,b=a[t+4>>2],r=e+72|0,a[r>>2]=a[t>>2],a[r+4>>2]=b,r=a[e+84>>2],a[e+64>>2]=a[e+80>>2],a[e+68>>2]=r;break A;case 0:t=u+8|0,b=a[t+4>>2],r=e+72|0,a[r>>2]=a[t>>2],a[r+4>>2]=b,r=a[u+4>>2],a[e+64>>2]=a[u>>2],a[e+68>>2]=r;break A;case 1:t=v+8|0,b=a[t+4>>2],r=e+72|0,a[r>>2]=a[t>>2],a[r+4>>2]=b,r=a[v+4>>2],a[e+64>>2]=a[v>>2],a[e+68>>2]=r;break A;case 2:t=s+8|0,b=a[t+4>>2],r=e+72|0,a[r>>2]=a[t>>2],a[r+4>>2]=b,r=a[s+4>>2],a[e+64>>2]=a[s>>2],a[e+68>>2]=r;break A;case 3:}t=d+8|0,b=a[t+4>>2],r=e+72|0,a[r>>2]=a[t>>2],a[r+4>>2]=b,r=a[d+4>>2],a[e+64>>2]=a[d>>2],a[e+68>>2]=r}else a[e+72>>2]=1050253722,a[e+76>>2]=0,a[e+64>>2]=1050253722,a[e+68>>2]=1050253722;1&f[i+205|0]&&(t=i+316|0,b=a[t+4>>2],r=e+72|0,a[r>>2]=a[t>>2],a[r+4>>2]=b,r=a[i+312>>2],a[e+64>>2]=a[i+308>>2],a[e+68>>2]=r),Qt[a[a[A>>2]+28>>2]](A,i+4|0,a[i+192>>2],e- -64|0)}r=a[A+72>>2],r&&2&Qt[a[a[r>>2]+56>>2]](r)&&(t=l+8|0,b=a[t+4>>2],r=e+40|0,a[r>>2]=a[t>>2],a[r+4>>2]=b,r=a[l+4>>2],a[e+32>>2]=a[l>>2],a[e+36>>2]=r,r=a[i+192>>2],Qt[a[a[r>>2]+8>>2]](r,i+4|0,e- -64|0,e+48|0),n=C[744],C[e+64>>2]=C[e+64>>2]-n,C[e+68>>2]=C[e+68>>2]-n,C[e+72>>2]=C[e+72>>2]-n,C[e+48>>2]=n+C[e+48>>2],C[e+52>>2]=n+C[e+52>>2],C[e+56>>2]=n+C[e+56>>2],3&o[i+204|0]|!o[A+44|0]|2!=a[i+252>>2]||(r=a[i+192>>2],Qt[a[a[r>>2]+8>>2]](r,i+68|0,e+16|0,e),k=_(C[e+16>>2]-n),C[e+16>>2]=k,g=_(C[e+20>>2]-n),C[e+20>>2]=g,B=_(C[e+24>>2]-n),C[e+24>>2]=B,m=_(n+C[e>>2]),C[e>>2]=m,R=_(n+C[e+4>>2]),C[e+4>>2]=R,n=_(n+C[e+8>>2]),C[e+8>>2]=n,k>2]&&(C[e+64>>2]=k),g>2]&&(C[e+68>>2]=g),B>2]&&(C[e+72>>2]=B),k=C[e+28>>2],k>2]&&(C[e+76>>2]=k),C[e+48>>2]>2]=m),C[e+52>>2]>2]=R),C[e+56>>2]>2]=n),n=C[e+12>>2],C[e+60>>2]>2]=n)),i=a[A+72>>2],Qt[a[a[i>>2]+60>>2]](i,e- -64|0,e+48|0,e+32|0))}if(c=c+4|0,Q=Q+1|0,!((0|Q)>2]))break}}Y=e+192|0}function Rf(A,e){var r,i=0,t=0,n=0,c=0,b=0,l=0;if(r=Y-96|0,Y=r,f[r+52|0]=1,a[r+48>>2]=0,f[r+72|0]=1,i=r+40|0,a[i>>2]=0,a[i+4>>2]=0,a[r+68>>2]=0,f[r+92|0]=1,i=r+60|0,a[i>>2]=0,a[i+4>>2]=0,a[r+88>>2]=0,i=r+80|0,a[i>>2]=0,a[i+4>>2]=0,a[r+28>>2]=0,f[r+32|0]=1,a[r+20>>2]=0,a[r+24>>2]=0,i=a[A+8>>2],!((0|i)<1)){for(;;){c=a[a[a[A+16>>2]+(l<<2)>>2]+192>>2],a[r+12>>2]=c,n=c+(c<<15^-1)|0,n=B(n>>>10^n,9),n^=n>>>6,n=(n<<11^-1)+n|0,b=b+-1&(n>>>16^n);A:{e:if(!(b>>>0>=t>>>0)&&(t=a[a[r+28>>2]+(b<<2)>>2],-1!=(0|t))){for(b=a[r+48>>2],n=a[r+88>>2];;){if(a[n+(t<<3)>>2]!=(0|c)){if(t=a[b+(t<<2)>>2],-1!=(0|t))continue;break e}break}if(a[r+68>>2]+(t<<2))break A}a[r>>2]=c,Qf(r+16|0,r,r+12|0),t=a[r+12>>2],Qt[a[a[t>>2]+60>>2]](t,e),i=a[A+8>>2]}if(l=l+1|0,!((0|l)<(0|i)))break;t=a[r+20>>2],b=a[r+64>>2]}if(!((0|i)<1))for(t=0,c=0;l=a[a[A+16>>2]+t>>2],b=a[l+252>>2],1!=(0|b)&&64!=(0|b)||(Qt[a[a[l>>2]+24>>2]](l,e),i=a[A+8>>2]),t=t+4|0,c=c+1|0,(0|c)<(0|i););}A=a[r+88>>2],A&&(o[r+92|0]&&CA(A),a[r+88>>2]=0),a[r+88>>2]=0,f[r+92|0]=1,a[r+80>>2]=0,a[r+84>>2]=0,A=a[r+68>>2],A&&(o[r+72|0]&&CA(A),a[r+68>>2]=0),a[r+68>>2]=0,f[r+72|0]=1,a[r+60>>2]=0,a[r+64>>2]=0,A=a[r+48>>2],A&&(o[r+52|0]&&CA(A),a[r+48>>2]=0),a[r+48>>2]=0,f[r+52|0]=1,a[r+40>>2]=0,a[r+44>>2]=0,A=a[r+28>>2],A&&(o[r+32|0]&&CA(A),a[r+28>>2]=0),Y=r+96|0}function Qf(A,e,r){var i=0,t=0,n=0,c=0,b=0,l=0,u=0,s=0,k=0;A:{if(i=a[e>>2],n=(i<<15^-1)+i|0,n=B(n>>>10^n,9),n^=n>>>6,n=(n<<11^-1)+n|0,t=n>>>16^n,n=a[A+48>>2],u=t&n+-1,!(u>>>0>=d[A+4>>2])&&(c=a[a[A+12>>2]+(u<<2)>>2],-1!=(0|c)))for(t=a[A+72>>2];;){if((0|i)==a[t+(c<<3)>>2])break A;if(c=a[a[A+32>>2]+(c<<2)>>2],-1==(0|c))break}if(s=a[A+44>>2],i=s,(0|i)==(0|n)&&(i=n,b=i?i<<1:1,!((0|i)>=(0|b)))){if(b?(l=dA(b<<2),i=a[A+44>>2]):i=n,(0|i)>=1)for(c=0,t=i;a[c+l>>2]=a[a[A+52>>2]+c>>2],c=c+4|0,t=t+-1|0,t;);t=a[A+52>>2],t&&(o[A+56|0]&&(CA(t),i=a[A+44>>2]),a[A+52>>2]=0),a[A+52>>2]=l,a[A+48>>2]=b,f[A+56|0]=1}if(a[A+44>>2]=i+1,a[a[A+52>>2]+(i<<2)>>2]=a[r>>2],t=a[A- -64>>2],(0|t)==a[A+68>>2]&&(r=t?t<<1:1,!((0|t)>=(0|r)))){if(r?(l=dA(r<<3),t=a[A+64>>2]):l=0,(0|t)>=1)for(c=0;b=a[A+72>>2]+c|0,k=a[b+4>>2],i=c+l|0,a[i>>2]=a[b>>2],a[i+4>>2]=k,c=c+8|0,t=t+-1|0,t;);i=a[A+72>>2],i&&(o[A+76|0]&&CA(i),a[A+72>>2]=0),a[A+72>>2]=l,a[A+68>>2]=r,f[A+76|0]=1,t=a[A+64>>2]}return i=a[e+4>>2],r=a[A+72>>2]+(t<<3)|0,a[r>>2]=a[e>>2],a[r+4>>2]=i,a[A+64>>2]=a[A+64>>2]+1,(0|n)>2]&&(function(A){var e=0,r=0,i=0,t=0,n=0,c=0,b=0,l=0,u=0;if(b=a[A+4>>2],t=a[A+48>>2],!((0|b)>=(0|t))){if(a[A+8>>2]>=(0|t))e=a[A+12>>2];else{t?(e=dA(t<<2),i=a[A+4>>2]):i=b,c=a[A+12>>2];e:{if((0|i)>=1)for(n=e,r=c;a[n>>2]=a[r>>2],n=n+4|0,r=r+4|0,i=i+-1|0,i;);else if(!c)break e;o[A+16|0]&&CA(c)}a[A+12>>2]=e,f[A+16|0]=1,a[A+8>>2]=t}if(r=b<<2,l=t<<2,X(r+e|0,0,l-r|0),a[A+4>>2]=t,u=a[A+24>>2],(0|u)<(0|t)){e:if(a[A+28>>2]>=(0|t))e=a[A+32>>2];else{if(t?(e=dA(l),i=a[A+24>>2]):(e=0,i=u),c=a[A+32>>2],(0|i)>=1)for(n=e,r=c;a[n>>2]=a[r>>2],n=n+4|0,r=r+4|0,i=i+-1|0,i;);else if(!c){a[A+32>>2]=e,a[A+28>>2]=t,f[A+36|0]=1;break e}o[A+36|0]&&CA(c),a[A+32>>2]=e,f[A+36|0]=1,a[A+28>>2]=t}r=u<<2,X(r+e|0,0,l-r|0)}if(a[A+24>>2]=t,(0|t)>=1&&(X(a[A+12>>2],255,l),X(a[A+32>>2],255,l)),!((0|b)<1))for(n=a[A+32>>2],r=a[A+72>>2],c=a[A+12>>2],i=0;e=a[r>>2],e=(e<<15^-1)+e|0,e=B(e>>>10^e,9),e^=e>>>6,e=(e<<11^-1)+e|0,e=c+((a[A+48>>2]+-1&(e>>>16^e))<<2)|0,a[n>>2]=a[e>>2],a[e>>2]=i,r=r+8|0,n=n+4|0,i=i+1|0,(0|i)!=(0|b););}}(A),e=a[e>>2],e=(e<<15^-1)+e|0,e=B(e>>>10^e,9),e^=e>>>6,e=(e<<11^-1)+e|0,u=a[A+48>>2]+-1&(e>>>16^e)),e=a[A+32>>2]+(s<<2)|0,A=a[A+12>>2]+(u<<2)|0,a[e>>2]=a[A>>2],void(a[A>>2]=s)}a[a[A+52>>2]+(c<<2)>>2]=a[r>>2]}function hf(A,e,r,i,f){A|=0,e|=0,r=_(r),i|=0,f|=0;var t,n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0);return t=Y-48|0,Y=t,a[t+44>>2]=f,a[t+40>>2]=i,b=C[A- -64>>2],l=C[A+60>>2],u=C[A+80>>2],s=C[A+72>>2],k=C[A+76>>2],v=C[A+96>>2],d=C[A+88>>2],g=C[A+92>>2],B=C[A+56>>2],n=C[e+8>>2],o=C[e>>2],c=C[e+4>>2],a[t+28>>2]=0,C[t+24>>2]=_(_(o*d)+_(c*g))+_(n*v),C[t+20>>2]=_(_(o*s)+_(c*k))+_(n*u),C[t+16>>2]=_(_(B*o)+_(l*c))+_(b*n),C[t+32>>2]=r,a[t+8>>2]=a[A+48>>2],a[t+12>>2]=t+40,A=a[A+44>>2],r=_(Qt[a[a[A>>2]+12>>2]](A,t+8|0,1)),Y=t+48|0,_(r)}function Gf(A,e,r,i,f,t){A|=0,e|=0,r|=0,i=_(i),f|=0,t|=0;var n,o=0,c=0;return n=Y+-64|0,Y=n,a[n+60>>2]=t,a[n+56>>2]=f,f=a[A+212>>2],C[f+4>>2]>=i&&(o=r+8|0,c=a[o+4>>2],t=n+40|0,a[t>>2]=a[o>>2],a[t+4>>2]=c,o=e+8|0,c=a[o+4>>2],t=n+24|0,a[t>>2]=a[o>>2],a[t+4>>2]=c,t=a[r+4>>2],a[n+32>>2]=a[r>>2],a[n+36>>2]=t,r=a[e+4>>2],a[n+16>>2]=a[e>>2],a[n+20>>2]=r,C[n+48>>2]=i,a[n+8>>2]=a[A+216>>2],a[n+12>>2]=n+56,i=_(Qt[a[a[f>>2]+12>>2]](f,n+8|0,1))),Y=n- -64|0,_(i)}function yf(A){var e;e=a[A+12>>2],e&&(o[A+16|0]&&CA(e),a[A+12>>2]=0),a[A+12>>2]=0,f[A+16|0]=1,a[A+4>>2]=0,a[A+8>>2]=0}function pf(A){var e,r,i=0,f=0,t=0,n=0,o=0,c=0;if(r=Y-16|0,Y=r,e=a[A+4>>2],!((0|e)<=0)){for(t=a[A+12>>2];;){if(i=n,o=(i<<3)+t|0,f=a[o>>2],(0|i)!=(0|f))for(c=o;i=(f<<3)+t|0,a[c>>2]=a[i>>2],i=a[i>>2],c=(i<<3)+t|0,f=a[c>>2],(0|i)!=(0|f););if(a[o>>2]=i,n=n+1|0,(0|e)==(0|n))break}(0|e)<2||function A(e,r,i,f){for(var t=0,n=0,o=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0;;){for(s=i,b=a[e+12>>2],k=a[b+((i+f|0)/2<<3)>>2],o=i,c=f;;){for(n=((o<<3)+b|0)-8|0;o=o+1|0,n=n+8|0,a[n>>2]<(0|k););for(i=o+-1|0,t=8+(c<<3)|0;c=c+-1|0,l=t+b|0,u=t+-8|0,t=u,a[l+-8>>2]>(0|k););if(t=c+1|0,(0|i)<=(0|t)&&(v=a[n>>2],l=a[n+4>>2],t=b+u|0,i=a[t+4>>2],a[n>>2]=a[t>>2],a[n+4>>2]=i,i=a[e+12>>2]+u|0,a[i>>2]=v,a[i+4>>2]=l,t=c,i=o),!((0|i)<=(0|t)))break;b=a[e+12>>2],o=i,c=t}if((0|t)>(0|s)&&A(e,r,s,t),!((0|i)<(0|f)))break}}(A,r+8|0,0,e+-1|0)}Y=r+16|0}function Ff(A,e,r,i){var t,n,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0,C=0,g=0,B=0;if(n=Y-16|0,Y=n,function(A,e,r){var i,t,n=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0,C=0,g=0,B=0;if(i=Y-16|0,Y=i,Lr(i+8|0,22924),n=a[A+28>>2],(0|n)<=-1)for(a[A+32>>2]<=-1&&(c=a[A+36>>2],c&&(o[A+40|0]&&CA(c),a[A+36>>2]=0),a[A+32>>2]=0,a[A+36>>2]=0,f[A+40|0]=1),u=n<<2;a[a[A+36>>2]+u>>2]=0,u=u+4|0,c=n+1|0,b=c>>>0>=n>>>0,n=c,b;);if(a[A+28>>2]=0,pf(A+4|0),t=a[A+8>>2],(0|t)>=1)for(c=0;;){for(l=a[A+16>>2],b=c,C=c<<3,s=l+C|0,n=s+8|0,k=a[s>>2];u=c,c=c+1|0,(0|c)<(0|t)&&(v=a[n>>2],n=n+8|0,(0|k)==(0|v)););A:if(v=(0|b)>(0|u),!v){for(g=b+-1|0,n=s+4|0,B=a[r+16>>2],s=1;d=a[(a[n>>2]<<2)+B>>2],a[d+208>>2]==(0|k)&&(d=a[d+220>>2],s&=4!=(0|d)&1!=(0|d)),n=n+8|0,g=g+1|0,(0|g)<(0|u););if(!(1&s)){if(v)break A;for(n=4|C;;){if(l=a[a[r+16>>2]+(a[n+l>>2]<<2)>>2],(0|k)!=a[l+208>>2]|2!=a[l+220>>2]||(Ye(l,3),a[l+224>>2]=0),(0|b)>=(0|u))break A;n=n+8|0,b=b+1|0,l=a[A+16>>2]}}if(!v)for(n=4|C;;){if(l=a[a[r+16>>2]+(a[n+l>>2]<<2)>>2],a[l+208>>2]==(0|k)&&Ye(l,2),(0|b)>=(0|u))break A;n=n+8|0,b=b+1|0,l=a[A+16>>2]}}if(!((0|c)<(0|t)))break}if(s=0|Qt[a[a[e>>2]+36>>2]](e),(0|s)>=1)for(u=0;;){k=0|Qt[a[a[e>>2]+40>>2]](e,u),r=a[k+776>>2],c=a[k+772>>2];A:{e:{r:{if(!(!c|2==a[c+220>>2])){if(b=a[c+204>>2],2&b)break r;break e}if(!r|2==a[r+220>>2])break A;if(b=a[c+204>>2],!(2&b)|2==a[c+220>>2])break e}4&b||Ve(r,0)}if(n=a[r+204>>2],!(2&n)|4&n|2==a[r+220>>2]||Ve(c,0),o[A+64|0]&&Qt[a[a[e>>2]+28>>2]](e,c,r)){if(r=a[A+28>>2],(0|r)==a[A+32>>2]&&(l=r?r<<1:1,!((0|r)>=(0|l)))){if(l?(b=dA(l<<2),r=a[A+28>>2]):b=0,(0|r)>=1)for(n=0,c=r;a[n+b>>2]=a[a[A+36>>2]+n>>2],n=n+4|0,c=c+-1|0,c;);c=a[A+36>>2],c&&(o[A+40|0]&&(CA(c),r=a[A+28>>2]),a[A+36>>2]=0),a[A+36>>2]=b,f[A+40|0]=1,a[A+32>>2]=l}a[A+28>>2]=r+1,a[a[A+36>>2]+(r<<2)>>2]=k}}if(u=u+1|0,(0|s)==(0|u))break}qr(),Y=i+16|0}(A,e,r),t=a[A+8>>2],Lr(n+8|0,22952),o[A+64|0]){if(v=a[A+28>>2],(0|v)>=2&&function A(e,r,i,f){for(var t=0,n=0,o=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0;;){for(k=i,n=a[e+12>>2],s=a[n+((i+f|0)/2<<2)>>2],t=f;;){if(l=a[a[s+772>>2]+208>>2],c=(0|l)<0,c)for(b=i+-1|0,o=((i<<2)+n|0)-4|0,u=a[a[s+776>>2]+208>>2];b=b+1|0,o=o+4|0,v=a[o>>2],i=a[a[v+772>>2]+208>>2],(0|i)<=-1&&(i=a[a[v+776>>2]+208>>2]),(0|i)<(0|u););else for(b=i+-1|0,o=((i<<2)+n|0)-4|0;b=b+1|0,o=o+4|0,u=a[o>>2],i=a[a[u+772>>2]+208>>2],(0|i)<=-1&&(i=a[a[u+776>>2]+208>>2]),(0|i)<(0|l););if(c){for(i=t+1|0,t=(t<<2)+n|0,l=a[a[s+776>>2]+208>>2];c=a[t>>2],n=a[a[c+772>>2]+208>>2],(0|n)<=-1&&(n=a[a[c+776>>2]+208>>2]),t=t+-4|0,i=i+-1|0,(0|l)<(0|n););t=t+4|0}else{for(i=t+1|0,t=(t<<2)+n|0;c=a[t>>2],n=a[a[c+772>>2]+208>>2],(0|n)<=-1&&(n=a[a[c+776>>2]+208>>2]),t=t+-4|0,i=i+-1|0,(0|l)<(0|n););t=t+4|0}if((0|b)>(0|i)?(t=i,i=b):(n=a[o>>2],a[o>>2]=a[t>>2],a[a[e+12>>2]+(i<<2)>>2]=n,t=i+-1|0,i=b+1|0),!((0|i)<=(0|t)))break;n=a[e+12>>2]}if((0|t)>(0|k)&&A(e,r,k,t),!((0|i)<(0|f)))break}}(A+24|0,n,0,v+-1|0),!((0|t)<1))for(g=1;;){e=a[A+16>>2],d=a[e+(u<<3)>>2],B=1;A:if(!((0|u)>=(0|t)))for(;;){if(s=a[a[r+16>>2]+(a[4+((u<<3)+e|0)>>2]<<2)>>2],c=a[A+48>>2],(0|c)==a[A+52>>2]&&(k=c?c<<1:1,!((0|c)>=(0|k)))){if(k?(b=dA(k<<2),c=a[A+48>>2]):b=0,(0|c)>=1)for(e=0,l=c;a[e+b>>2]=a[a[A+56>>2]+e>>2],e=e+4|0,l=l+-1|0,l;);e=a[A+56>>2],e&&(o[A+60|0]&&(CA(e),c=a[A+48>>2]),a[A+56>>2]=0),a[A+56>>2]=b,f[A+60|0]=1,a[A+52>>2]=k}if(a[A+48>>2]=c+1,a[a[A+56>>2]+(c<<2)>>2]=s,e=a[s+220>>2],B&=5==(0|e)|2==(0|e),u=u+1|0,(0|t)==(0|u)){u=t;break A}if(e=a[A+16>>2],a[e+(u<<3)>>2]!=(0|d))break}if(s=0,e=0,!((0|C)>=(0|v))&&(k=a[A+36>>2],b=C<<2,c=k+b|0,e=a[c>>2],l=a[a[e+772>>2]+208>>2],(0|l)<=-1&&(l=a[a[e+776>>2]+208>>2]),e=0,(0|l)==(0|d))){for(e=4+(b+k|0)|0,b=1;s=b,g=b+C|0,!((0|g)>=(0|v)||(b=a[e>>2],l=a[a[b+772>>2]+208>>2],(0|l)<=-1&&(l=a[a[b+776>>2]+208>>2]),e=e+4|0,b=s+1|0,(0|l)!=(0|d))););e=c}if(B||Qt[a[a[i>>2]+8>>2]](i,a[A+56>>2],a[A+48>>2],e,s,d),e=a[A+48>>2],(0|e)<=-1)for(a[A+52>>2]<=-1&&(c=a[A+56>>2],c&&(o[A+60|0]&&CA(c),a[A+56>>2]=0),f[A+60|0]=1,a[A+52>>2]=0,a[A+56>>2]=0),l=e<<2;a[a[A+56>>2]+l>>2]=0,l=l+4|0,c=e+1|0,b=c>>>0>=e>>>0,e=c,b;);if(C=s?g:C,a[A+48>>2]=0,!((0|u)<(0|t)))break}}else c=0|Qt[a[a[e>>2]+44>>2]](e),A=0|Qt[a[a[e>>2]+36>>2]](e),Qt[a[a[i>>2]+8>>2]](i,a[r+16>>2],a[r+8>>2],c,A,-1);qr(),Y=n+16|0}function Wf(A){var e=0,r=0,i=0,f=0,t=0;if(s(A),i=c(0),r=i>>>23&255,255==(0|r))return A=_(A*_(6.2831854820251465)),_(A/A);if(e=i<<1,e>>>0>2173837238){if(r)e=8388607&i|8388608;else{if(r=0,e=i<<9,(0|e)>=0)for(;r=r+-1|0,e<<=1,(0|e)>-1;);e=i<<1-r}if(f=e-13176795|0,t=(0|f)>-1,(0|r)>129)for(;;){if(t&&(e=f,!e))return _(A*_(0));if(e<<=1,f=e-13176795|0,t=(0|f)>-1,r=r+-1|0,!((0|r)>129))break}if(t&&(e=f,!e))return _(A*_(0));if(e>>>0<=8388607)for(;r=r+-1|0,e<<=1,e>>>0<8388608;);return b(0,-2147483648&i|((0|r)>=1?e+-8388608|r<<23:e>>>1-r)),k()}return-2121130058==(0|e)?_(A*_(0)):A}function wf(A,e,r,i,f){var t=_(0);if(t=_(1),!(e>r)&&(t=_(0),e!=r)){if(i=_(i/f),i<_(0))return A>=e^1|_(e-i)>A^1?_(A_(0)){if(!(A<=r^1|_(r-i)r?0:1)}}return t}function Df(A,e,r){A|=0,e|=0,r|=0;var i=0,f=0,t=0,n=0;if(t=e,n=0|Qt[a[a[r>>2]+28>>2]](r,a[A+28>>2]),a[t>>2]=n,t=e,n=0|Qt[a[a[r>>2]+28>>2]](r,a[A+32>>2]),a[t+4>>2]=n,i=0|Qt[a[a[r>>2]+40>>2]](r,A),f=0|Qt[a[a[r>>2]+28>>2]](r,i),a[e+8>>2]=f,f&&Qt[a[a[r>>2]+48>>2]](r,i),a[e+12>>2]=a[A+4>>2],a[e+24>>2]=o[A+21|0],a[e+40>>2]=a[A+24>>2],a[e+44>>2]=a[A+16>>2],a[e+48>>2]=o[A+20|0],r=a[A+12>>2],i=a[A+40>>2],a[e+28>>2]=a[A+36>>2],a[e+32>>2]=i,a[e+20>>2]=r,i=0,a[e+36>>2]=0,a[e+16>>2]=a[A+8>>2],r=a[A+28>>2],f=a[r+548>>2],(0|f)>=1)for(r=a[r+556>>2];(0|A)==a[r>>2]&&(a[e+36>>2]=1),r=r+4|0,i=i+1|0,(0|i)<(0|f););if(r=a[A+32>>2],f=a[r+548>>2],(0|f)>=1)for(r=a[r+556>>2],i=0;(0|A)==a[r>>2]&&(a[e+36>>2]=1),r=r+4|0,i=i+1|0,(0|i)<(0|f););return 23056}function Ef(A){return A|=0,a[A>>2]=23012,0|A}function Zf(A,e,r,i){var f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0);t=Cr(r),n=C[e+444>>2],r=dr(r),_(m(t))>_(1.1920928955078125e-7)?(f=_(r*r),b=_(t*t),o=_(f/b),c=C[e+448>>2],n=_(y(_(_(o+_(1))/_(_(_(1)/_(c*c))+_(o/_(n*n))))))):(f=_(r*r),b=_(t*t)),a[A+12>>2]=0,o=_(n*_(.5)),f=_(dr(o)/_(y(_(f+_(b+_(0)))))),r=_(r*f),n=_(f*_(0)),t=_(t*f),c=_(t*_(0)),l=_(r*_(-0)),b=_(_(_(-_(n*i))-c)-l),f=Cr(o),u=_(f*_(0)),s=_(n*_(0)),o=_(_(u+s)-_(t*i)),c=_(_(_(f*i)+c)-l),i=_(_(u-_(r*i))-s),C[A+8>>2]=_(_(_(r*b)+_(f*o))-_(c*t))+_(i*n),C[A+4>>2]=_(_(_(f*i)-_(b*t))-_(o*n))-_(r*c),C[A>>2]=_(_(r*i)+_(_(f*c)-_(b*n)))+_(o*t)}function Yf(A){var e=0,r=0,i=_(0),f=0;A:{e:{if(s(A),f=c(0),r=2147483647&f,r>>>0>=1065353216){if(1065353216!=(0|r))break e;return _(1.5707963267948966*+A+7.52316384526264e-37)}if(r>>>0<=1056964607){if(r+-8388608>>>0<956301312)break A;return i=_(A*A),_(_(_(_(i*_(_(i*_(_(i*_(-.008656363002955914))+_(-.04274342209100723)))+_(.16666586697101593)))/_(_(i*_(-.7066296339035034))+_(1)))*A)+A)}return A=_(_(_(1)-_(m(A)))*_(.5)),e=y(+A),e+=e*+_(_(A*_(_(A*_(_(A*_(-.008656363002955914))+_(-.04274342209100723)))+_(.16666586697101593)))/_(_(A*_(-.7066296339035034))+_(1))),A=_(1.5707963267948966-(e+e)),(0|f)<0?_(-A):A}A=_(_(0)/_(A-A))}return A}function Vf(A,e){return C[1192+((e<<2)+A|0)>>2]}function Nf(A,e,r,i){var n;!function(A,e,r){a[A>>2]=20592,f[A+76|0]=1,a[A+72>>2]=0,a[A+68>>2]=r,a[A+28>>2]=0,a[A+32>>2]=0,a[A+24>>2]=e,f[A+20|0]=1,a[A+16>>2]=0,a[A- -64>>2]=0,f[A+60|0]=0,a[A+56>>2]=1025758986,f[A+54|0]=1,t[A+52>>1]=256,a[A+48>>2]=0,f[A+44|0]=1,e=A+36|0,a[e>>2]=1,a[e+4>>2]=1065353216,A=A+8|0,a[A>>2]=0,a[A+4>>2]=0}(A,e,r),r=A+100|0,a[r>>2]=1050253722,a[r+4>>2]=1015580809,a[A+92>>2]=1058642330,a[A+96>>2]=1065353216,a[A+88>>2]=0,a[A+80>>2]=0,a[A+84>>2]=0,r=A+132|0,a[r>>2]=0,a[r+4>>2]=1045220557,r=A+124|0,a[r>>2]=1045220557,a[r+4>>2]=1045220557,r=A+108|0,a[r>>2]=0,a[r+4>>2]=10,r=A+184|0,a[r>>2]=0,a[r+4>>2]=1045220557,r=A+176|0,a[r>>2]=1120403456,a[r+4>>2]=1900671690,a[A+172>>2]=128,r=A+164|0,a[r>>2]=260,a[r+4>>2]=2,r=A+156|0,a[r>>2]=0,a[r+4>>2]=1062836634,r=A+148|0,a[r>>2]=-1121724662,a[r+4>>2]=1036831949,r=A+140|0,a[r>>2]=0,a[r+4>>2]=1,r=A+116|0,a[r>>2]=1101004800,a[r+4>>2]=1065353216,a[A>>2]=23160,f[A+208|0]=1,a[A+204>>2]=0,f[A+240|0]=1,a[A+216>>2]=i,a[A+212>>2]=0,r=A+196|0,a[r>>2]=0,a[r+4>>2]=0,a[A+236>>2]=0,r=A+228|0,a[r>>2]=0,a[r+4>>2]=0,f[A+260|0]=1,t[A+290>>1]=0,a[A+256>>2]=0,r=A+248|0,a[r>>2]=0,a[r+4>>2]=0,a[A+264>>2]=0,a[A+268>>2]=-1054867456,r=A+272|0,a[r>>2]=0,a[r+4>>2]=0,r=A+280|0,a[r>>2]=0,a[r+4>>2]=0,f[A+308|0]=1,a[A+312>>2]=0,a[A+304>>2]=0,r=A+296|0,a[r>>2]=0,a[r+4>>2]=0,f[A+336|0]=1,f[A+316|0]=1,r=A+324|0,a[r>>2]=0,a[r+4>>2]=0,a[A+332>>2]=0,a[A+340>>2]=0,n=A,i?r=0:(r=dA(236),Li(r),a[A+216>>2]=r,r=1),f[n+289|0]=r,r=dA(68),function(A){var e=0;a[A>>2]=22908,e=A+4|0,a[e+12>>2]=0,f[e+16|0]=1,a[e+4>>2]=0,a[e+8>>2]=0,a[A+36>>2]=0,f[A+40|0]=1,f[A+60|0]=1,e=A+28|0,a[e>>2]=0,a[e+4>>2]=0,a[A+56>>2]=0,f[A+64|0]=1,A=A+48|0,a[A>>2]=0,a[A+4>>2]=0}(r),f[A+288|0]=1,a[A+220>>2]=r,r=dA(88),a[r+72>>2]=0,a[r+76>>2]=0,f[r+44|0]=1,a[r+24>>2]=e,a[r+20>>2]=0,a[r+12>>2]=0,a[r+16>>2]=0,a[r+4>>2]=0,a[r>>2]=23768,a[r+40>>2]=0,f[r+64|0]=1,a[r+32>>2]=0,a[r+36>>2]=0,a[r+60>>2]=0,f[r+84|0]=1,a[r+52>>2]=0,a[r+56>>2]=0,a[r+80>>2]=0,a[r+8>>2]=a[A+216>>2],a[A+212>>2]=r}function If(A){A|=0;var e=0;return a[A>>2]=23160,o[A+288|0]&&(e=a[A+220>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+220>>2])),e=a[A+212>>2],e&&(Qt[a[a[e>>2]>>2]](e),CA(a[A+212>>2])),o[A+289|0]&&(e=a[A+216>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+216>>2])),e=a[A+332>>2],e&&(o[A+336|0]&&CA(e),a[A+332>>2]=0),a[A+332>>2]=0,a[A+324>>2]=0,a[A+328>>2]=0,f[A+336|0]=1,e=a[A+304>>2],e&&(o[A+308|0]&&CA(e),a[A+304>>2]=0),a[A+304>>2]=0,a[A+296>>2]=0,a[A+300>>2]=0,f[A+308|0]=1,e=a[A+256>>2],e&&(o[A+260|0]&&CA(e),a[A+256>>2]=0),a[A+256>>2]=0,a[A+248>>2]=0,a[A+252>>2]=0,f[A+260|0]=1,e=a[A+236>>2],e&&(o[A+240|0]&&CA(e),a[A+236>>2]=0),a[A+236>>2]=0,a[A+228>>2]=0,a[A+232>>2]=0,f[A+240|0]=1,e=a[A+204>>2],e&&(o[A+208|0]&&CA(e),a[A+204>>2]=0),a[A+204>>2]=0,a[A+196>>2]=0,a[A+200>>2]=0,f[A+208|0]=1,sf(A),0|A}function Jf(A,e){A|=0,e|=0,Qt[a[a[A>>2]+64>>2]](A,e)}function xf(A,e){A|=0,e|=0,Qt[a[a[A>>2]+68>>2]](A,e)}function Uf(A){var e,r,i,t=0,n=0,c=0,b=0,l=0;if(n=a[A+8>>2],e=n,b=a[A+32>>2],b&&(c=a[A+40>>2]),r=c,c=a[A+52>>2],c&&(t=a[A+60>>2]),i=t,t=a[A+72>>2],l=0,t&&(l=a[A+80>>2]),_(Qt[a[a[n>>2]+12>>2]](e,r,b,i,c,l,t,a[A+4>>2],a[A+20>>2],a[A+24>>2])),t=a[A+32>>2],(0|t)<=-1)for(a[A+36>>2]<=-1&&(n=a[A+40>>2],n&&(o[A+44|0]&&CA(n),a[A+40>>2]=0),a[A+36>>2]=0,a[A+40>>2]=0,f[A+44|0]=1),c=t<<2;a[a[A+40>>2]+c>>2]=0,c=c+4|0,n=t+1|0,b=n>>>0>=t>>>0,t=n,b;);if(a[A+32>>2]=0,t=a[A+52>>2],(0|t)<=-1)for(a[A+56>>2]<=-1&&(n=a[A+60>>2],n&&(o[A- -64|0]&&CA(n),a[A+60>>2]=0),a[A+56>>2]=0,a[A+60>>2]=0,f[A- -64|0]=1),c=t<<2;a[a[A+60>>2]+c>>2]=0,c=c+4|0,n=t+1|0,b=n>>>0>=t>>>0,t=n,b;);if(a[A+52>>2]=0,t=a[A+72>>2],(0|t)<=-1)for(a[A+76>>2]<=-1&&(n=a[A+80>>2],n&&(o[A+84|0]&&CA(n),a[A+80>>2]=0),a[A+76>>2]=0,a[A+80>>2]=0,f[A+84|0]=1),c=t<<2;a[a[A+80>>2]+c>>2]=0,c=c+4|0,n=t+1|0,b=n>>>0>=t>>>0,t=n,b;);a[A+72>>2]=0}function Mf(A,e){return A|=0,e|=0,a[a[A+236>>2]+(e<<2)>>2]}function Sf(A,e,r,i,f,t){var n,o=0,c=0,b=0,l=0,u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=0,R=_(0),Q=_(0);if(n=Y-272|0,Y=n,b=r+8|0,c=a[b+4>>2],o=n+216|0,a[o>>2]=a[b>>2],a[o+4>>2]=c,b=r+24|0,c=a[b+4>>2],o=n+232|0,a[o>>2]=a[b>>2],a[o+4>>2]=c,b=r+40|0,c=a[b+4>>2],o=n+248|0,a[o>>2]=a[b>>2],a[o+4>>2]=c,c=r+56|0,l=a[c+4>>2],b=n+264|0,o=b,a[o>>2]=a[c>>2],a[o+4>>2]=l,c=i+8|0,l=a[c+4>>2],o=n+152|0,a[o>>2]=a[c>>2],a[o+4>>2]=l,o=r,c=a[o+4>>2],a[n+208>>2]=a[o>>2],a[n+212>>2]=c,c=a[o+20>>2],a[n+224>>2]=a[o+16>>2],a[n+228>>2]=c,c=a[o+36>>2],a[n+240>>2]=a[o+32>>2],a[n+244>>2]=c,c=a[o+52>>2],a[n+256>>2]=a[o+48>>2],a[n+260>>2]=c,o=a[i+4>>2],a[n+144>>2]=a[i>>2],a[n+148>>2]=o,c=i+24|0,l=a[c+4>>2],o=n+168|0,a[o>>2]=a[c>>2],a[o+4>>2]=l,c=i+40|0,l=a[c+4>>2],o=n+184|0,a[o>>2]=a[c>>2],a[o+4>>2]=l,l=i+56|0,m=a[l+4>>2],o=n+200|0,a[o>>2]=a[l>>2],a[o+4>>2]=m,c=a[i+20>>2],a[n+160>>2]=a[i+16>>2],a[n+164>>2]=c,c=a[i+36>>2],a[n+176>>2]=a[i+32>>2],a[n+180>>2]=c,c=a[i+52>>2],a[n+192>>2]=a[i+48>>2],a[n+196>>2]=c,a[n+108>>2]=0,C[n+104>>2]=C[o>>2]-C[b>>2],C[n+100>>2]=C[n+196>>2]-C[n+260>>2],C[n+96>>2]=C[n+192>>2]-C[n+256>>2],Mi(n+208|0,n+144|0,n+16|0,n+128|0),a[n+92>>2]=0,u=C[n+128>>2],C[n+88>>2]=u*C[n+24>>2],C[n+84>>2]=u*C[n+20>>2],C[n+80>>2]=u*C[n+16>>2],o=n+72|0,a[o>>2]=0,a[o+4>>2]=0,o=n- -64|0,a[o>>2]=0,a[o+4>>2]=0,tt(n+208|0,n+128|0),a[n+60>>2]=0,a[n+44>>2]=0,u=C[n+128>>2],s=C[n+132>>2],v=C[n+136>>2],B=C[n+140>>2],g=_(_(2)/_(_(_(_(u*u)+_(s*s))+_(v*v))+_(B*B))),R=_(v*g),k=_(s*R),d=_(u*g),Q=_(B*d),C[n+52>>2]=k+Q,C[n+40>>2]=k-Q,k=_(u*d),d=s,s=_(s*g),g=_(d*s),C[n+56>>2]=_(1)-_(k+g),v=_(v*R),C[n+36>>2]=_(1)-_(k+v),a[n+28>>2]=0,k=_(u*R),d=_(B*s),C[n+48>>2]=k-d,u=_(u*s),s=_(B*R),C[n+32>>2]=u+s,C[n+24>>2]=k+d,C[n+20>>2]=u-s,C[n+16>>2]=_(1)-_(g+v),RA(e,n+16|0,n+96|0,n+80|0,n+128|0,n+112|0),a[A+328>>2]>=1)for(b=i+48|0,c=r+48|0,i=0,o=0;r=a[a[A+336>>2]+i>>2],Qt[a[a[f>>2]+8>>2]](f,a[r+188>>2])&&(l=a[r+192>>2],m=r+4|0,Qt[a[a[l>>2]+8>>2]](l,m,n+16|0,n+96|0),a[n+28>>2]=0,a[n+108>>2]=0,C[n+24>>2]=C[n+24>>2]+C[n+136>>2],C[n+20>>2]=C[n+20>>2]+C[n+132>>2],C[n+16>>2]=C[n+16>>2]+C[n+128>>2],C[n+96>>2]=C[n+96>>2]+C[n+112>>2],C[n+100>>2]=C[n+100>>2]+C[n+116>>2],C[n+104>>2]=C[n+104>>2]+C[n+120>>2],a[n+12>>2]=1065353216,Xf(c,b,n+16|0,n+96|0,n+12|0,n+80|0)&&gf(e,n+208|0,n+144|0,r,a[r+192>>2],m,f,t)),i=i+4|0,o=o+1|0,(0|o)>2];);Y=n+272|0}function Xf(A,e,r,i,f,t){var n,o,c,b,l,u,s,k,v,d=_(0),g=_(0),B=_(0),m=_(0),R=0,Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0);if(n=Y-16|0,B=C[i>>2],d=C[r>>2],Q=_(_(B+d)*_(.5)),g=_(C[e>>2]-Q),B=_(B-d),F=_(B*_(.5)),o=g>F,B=_(B*_(-.5)),c=g>2],m=C[r+4>>2],h=_(_(d+m)*_(.5)),G=_(C[e+4>>2]-h),d=_(d-m),p=_(d*_(-.5)),b=GW,d=C[i+8>>2],m=C[r+8>>2],D=_(_(d+m)*_(.5)),y=_(C[e+8>>2]-D),d=_(d-m),E=_(d*_(-.5)),e=yw)<<5,Q=_(C[A>>2]-Q),i=Q>F,u=Q>2]-h),s=mW,h=_(C[A+8>>2]-D),A=hw)<<5,R=0,!(r&v)){B=C[f>>2],R=n+8|0,a[R>>2]=0,a[R+4>>2]=0,a[n>>2]=0,a[n+4>>2]=0,p=_(g-Q);A:if(u){if(g=_(_(_(-Q)-F)/p),!(g>=_(0))){g=_(0);break A}a[n+12>>2]=0,a[n+4>>2]=0,a[n+8>>2]=0,a[n>>2]=1065353216}else g=_(0),c&&(d=_(_(_(-Q)-F)/p),d>2]=0,a[R+4>>2]=0,a[n>>2]=0,a[n+4>>2]=1065353216;break A}b&&(d=_(_(_(-m)-W)/G),d>2]=1065353216,a[A+4>>2]=0,a[n>>2]=0,a[n+4>>2]=0;break A}e&&(g=_(_(_(-h)-w)/y),g>2]=0,a[n+4>>2]=0,a[n+8>>2]=0,a[n>>2]=-1082130432;break A}o&&(d=_(_(F-Q)/p),d>2]=0,a[A+4>>2]=0,a[n>>2]=0,a[n+4>>2]=-1082130432;break A}l&&(g=_(_(W-m)/G),g>2]=-1082130432,a[A+4>>2]=0,a[n>>2]=0,a[n+4>>2]=0;break A}32&r&&(d=_(_(w-h)/y),d>2]=d,A=a[n+4>>2],a[t>>2]=a[n>>2],a[t+4>>2]=A,e=n+8|0,r=a[e+4>>2],A=t+8|0,a[A>>2]=a[e>>2],a[A+4>>2]=r,R=1)}return R}function Tf(A,e){var r,i=0,f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=0,v=0,d=_(0),g=0,B=_(0),R=0,Q=0,h=0,G=_(0),p=0,F=0,W=0,w=0,D=0,E=0,Z=0,V=0;if(r=Y-80|0,Y=r,i=A+256|0,f=C[e+12>>2],s=C[A+264>>2],c=C[e+8>>2],(C[A+268>>2]!=f|s!=c|C[A+260>>2]!=C[e+4>>2]||C[i>>2]!=C[e>>2])&&(b=C[A+260>>2],d=C[A+256>>2],t=C[e>>2],n=C[e+4>>2],o=_(_(_(t*t)+_(n*n))+_(c*c)),o>_(0)?(C[A+268>>2]=f,f=_(_(1)/_(y(o))),l=_(c*f),C[A+264>>2]=l,c=_(n*f),C[A+260>>2]=c,u=_(t*f),C[A+256>>2]=u):(a[i>>2]=0,a[i+4>>2]=0,e=i+8|0,a[e>>2]=0,a[e+4>>2]=0,c=_(0)),i=a[A+8>>2],i)){B=_(_(_(u*u)+_(c*c))+_(l*l));A:if(B!=_(0)&&(G=_(_(_(d*d)+_(b*b))+_(s*s)),G!=_(0)))if(f=_(_(1)/_(y(B))),o=_(l*f),C[A+264>>2]=o,t=_(c*f),C[A+260>>2]=t,n=_(u*f),C[A+256>>2]=n,f=_(_(1)/_(y(G))),s=_(s*f),c=_(b*f),l=_(d*f),f=_(_(s*o)+_(_(c*t)+_(l*n))),f<_(-.9999998807907104)){if(_(m(o))>_(.7071067690849304)){b=t,t=_(_(1)/_(y(_(_(t*t)+_(o*o))))),f=_(b*t),n=_(-_(o*t)),t=_(0),o=_(0);break A}f=_(_(1)/_(y(_(_(t*t)+_(n*n))))),n=_(n*f),t=_(-_(t*f)),f=_(0),o=_(0)}else f=_(f+_(1)),b=_(y(_(f+f))),u=_(_(1)/b),f=_(_(_(c*n)-_(l*t))*u),n=_(_(_(l*o)-_(s*n))*u),t=_(_(_(s*t)-_(c*o))*u),o=_(b*_(.5));k=i+12|0,g=a[k+4>>2],v=r+24|0,e=v,a[e>>2]=a[k>>2],a[e+4>>2]=g,e=i+20|0,R=a[e>>2],F=a[e+4>>2],e=i+36|0,W=a[e>>2],w=a[e+4>>2],e=i+28|0,Q=a[e>>2],e=a[e+4>>2],k=i+44|0,g=a[k>>2],D=a[k+4>>2],E=a[i+4>>2],Z=a[i+8>>2],p=i+60|0,V=a[p+4>>2],h=r+72|0,k=h,a[k>>2]=a[p>>2],a[k+4>>2]=V,k=r+56|0,a[k>>2]=g,a[k+4>>2]=D,g=r+40|0,a[g>>2]=Q,a[g+4>>2]=e,a[r+16>>2]=E,a[r+20>>2]=Z,i=i+52|0,Q=a[i+4>>2],e=r,a[e+64>>2]=a[i>>2],a[e+68>>2]=Q,a[e+48>>2]=W,a[e+52>>2]=w,a[e+32>>2]=R,a[e+36>>2]=F,tt(e+16|0,e),l=C[e>>2],u=C[e+12>>2],b=C[e+8>>2],d=C[e+4>>2],s=_(_(_(_(o*l)-_(u*t))-_(b*n))+_(d*f)),c=_(_(_(_(o*u)+_(l*t))+_(d*n))+_(b*f)),B=_(_(_(_(o*b)-_(u*f))-_(d*t))+_(l*n)),f=_(_(_(_(o*d)-_(u*n))-_(l*f))+_(b*t)),t=_(_(2)/_(_(c*c)+_(_(B*B)+_(_(s*s)+_(f*f))))),n=_(B*t),l=_(s*n),o=_(f*t),u=_(c*o),C[v>>2]=l+u,a[e+60>>2]=0,a[e+44>>2]=0,b=_(f*n),t=_(s*t),d=_(c*t),C[e+52>>2]=b+d,C[g>>2]=b-d,t=_(s*t),f=_(f*o),C[k>>2]=_(1)-_(t+f),b=t,t=_(B*n),C[e+36>>2]=_(1)-_(b+t),a[e+28>>2]=0,C[e+48>>2]=l-u,o=_(s*o),n=_(c*n),C[e+32>>2]=o+n,C[e+20>>2]=o-n,R=a[v+4>>2],A=a[A+8>>2],i=A+12|0,a[i>>2]=a[v>>2],a[i+4>>2]=R,C[e+16>>2]=_(1)-_(f+t),i=a[e+20>>2],a[A+4>>2]=a[e+16>>2],a[A+8>>2]=i,v=a[e+36>>2],i=A+20|0,a[i>>2]=a[e+32>>2],a[i+4>>2]=v,v=a[g+4>>2],i=A+28|0,a[i>>2]=a[g>>2],a[i+4>>2]=v,a[A+304>>2]=a[A+304>>2]+1,v=a[e+52>>2],i=A+36|0,a[i>>2]=a[e+48>>2],a[i+4>>2]=v,v=a[k+4>>2],i=A+44|0,a[i>>2]=a[k>>2],a[i+4>>2]=v,v=a[h+4>>2],i=A+60|0,a[i>>2]=a[h>>2],a[i+4>>2]=v,i=a[e+68>>2],A=A+52|0,a[A>>2]=a[e+64>>2],a[A+4>>2]=i}Y=r+80|0}function jf(A,e){var r,i=0,t=0,n=0,c=0,b=0,l=0,u=0,s=0,k=0,v=_(0),d=_(0),g=0,B=_(0),m=_(0),R=_(0),Q=0;if(r=Y-96|0,Y=r,i=a[A+12>>2],Qt[a[a[i>>2]+8>>2]](i,a[A+8>>2]+4|0,r+80|0,r- -64|0),i=a[e+68>>2],Qt[a[a[i>>2]+16>>2]](i,a[a[A+8>>2]+188>>2],r+80|0,r- -64|0,a[e+24>>2]),i=a[e+24>>2],Qt[a[a[i>>2]+32>>2]](i,a[a[A+8>>2]+344>>2],e+28|0,i),e=a[A+8>>2],i=e+52|0,t=a[i+4>>2],a[A+132>>2]=a[i>>2],a[A+136>>2]=t,t=e+60|0,c=a[t+4>>2],i=A+140|0,a[i>>2]=a[t>>2],a[i+4>>2]=c,c=A+132|0,e=a[e+344>>2],!((0|Qt[a[a[e>>2]+36>>2]](e))<1))for(k=A+200|0;;){if(e=a[A+204>>2],(0|e)<=-1)for(a[A+208>>2]<=-1&&(i=a[A+212>>2],i&&(o[A+216|0]&&CA(i),a[A+212>>2]=0),f[A+216|0]=1,a[A+208>>2]=0,a[A+212>>2]=0),t=e<<2;a[a[A+212>>2]+t>>2]=0,t=t+4|0,i=e+1|0,b=i>>>0>=e>>>0,e=i,b;);if(a[A+204>>2]=0,e=a[a[A+8>>2]+344>>2],i=a[12+(0|Qt[a[a[e>>2]+28>>2]](e))>>2]+(u<<4)|0,e=a[a[i+4>>2]>>2],t=a[a[i>>2]>>2],!((4&o[t+204|0]?t:0)|(4&o[e+204|0]?e:0))&&Qt[a[a[A>>2]+56>>2]](A,t,e)&&(e=a[i+8>>2],e&&Qt[a[a[e>>2]+16>>2]](e,k),b=a[A+204>>2],!((0|b)<1)))for(s=a[A+8>>2],n=a[A+212>>2],i=0;;){if(e=a[n+(i<<2)>>2],l=a[e+780>>2],(0|l)>=1)for(d=(0|s)==a[e+772>>2]?_(-1):_(1),e=e+84|0,B=_(-C[A+16>>2]),t=0;v=C[e>>2],v>2],R=C[e+-12>>2],C[A+132>>2]=_(_(v*_(d*C[e+-16>>2]))*_(.20000000298023224))+C[A+132>>2],C[A+136>>2]=_(_(v*_(d*R))*_(.20000000298023224))+C[A+136>>2],C[A+140>>2]=_(_(v*_(d*m))*_(.20000000298023224))+C[A+140>>2],Q=1),e=e+192|0,t=t+1|0,(0|t)<(0|l););if(i=i+1|0,!((0|i)<(0|b)))break}if(u=u+1|0,e=a[a[A+8>>2]+344>>2],!((0|u)<(0|Qt[a[a[e>>2]+36>>2]](e))))break}return t=c+8|0,u=a[t+4>>2],e=r+56|0,a[e>>2]=a[t>>2],a[e+4>>2]=u,A=a[A+8>>2],t=A+12|0,b=a[t+4>>2],i=r+8|0,a[i>>2]=a[t>>2],a[i+4>>2]=b,k=A+28|0,s=k,n=a[s+4>>2],u=r+24|0,b=u,a[b>>2]=a[s>>2],a[b+4>>2]=n,s=A+44|0,l=s,g=a[l+4>>2],b=r+40|0,n=b,a[n>>2]=a[l>>2],a[n+4>>2]=g,n=a[c+4>>2],c=a[c>>2],a[A+304>>2]=a[A+304>>2]+1,a[r+48>>2]=c,a[r+52>>2]=n,c=a[A+8>>2],a[r>>2]=a[A+4>>2],a[r+4>>2]=c,c=A+20|0,n=c,l=a[n+4>>2],a[r+16>>2]=a[n>>2],a[r+20>>2]=l,n=A+36|0,g=a[n+4>>2],a[r+32>>2]=a[n>>2],a[r+36>>2]=g,l=a[r+4>>2],a[A+4>>2]=a[r>>2],a[A+8>>2]=l,l=a[i+4>>2],a[t>>2]=a[i>>2],a[t+4>>2]=l,i=a[u+4>>2],a[k>>2]=a[u>>2],a[k+4>>2]=i,i=a[r+20>>2],a[c>>2]=a[r+16>>2],a[c+4>>2]=i,i=a[b+4>>2],a[s>>2]=a[b>>2],a[s+4>>2]=i,i=a[r+36>>2],a[n>>2]=a[r+32>>2],a[n+4>>2]=i,t=a[e+4>>2],i=A+60|0,a[i>>2]=a[e>>2],a[i+4>>2]=t,e=a[r+52>>2],A=A+52|0,a[A>>2]=a[r+48>>2],a[A+4>>2]=e,Y=r+96|0,Q}function Of(A,e){var r=_(0),i=_(0),f=_(0),t=_(0),n=_(0),o=0,c=_(0),b=_(0),l=_(0),u=_(0),s=0,k=_(0);r=_(C[A+152>>2]-C[A+132>>2]),f=_(C[A+156>>2]-C[A+136>>2]),i=_(C[A+160>>2]-C[A+140>>2]),c=_(y(_(_(_(r*r)+_(f*f))+_(i*i)))),c>_(1.1920928955078125e-7)&&(l=C[e+8>>2],n=C[e>>2],u=C[e+4>>2],e=A+132|0,s=a[e+4>>2],o=A+152|0,a[o>>2]=a[e>>2],a[o+4>>2]=s,e=e+8|0,s=a[e+4>>2],o=o+8|0,a[o>>2]=a[e>>2],a[o+4>>2]=s,t=r,r=_(_(1)/c),t=_(t*r),b=t,k=_(t*n),t=_(f*r),i=_(i*r),r=_(_(k+_(t*u))+_(i*l)),r=_(r+r),f=_(b-_(n*r)),b=f,i=_(i-_(l*r)),r=_(t-_(u*r)),f=_(_(1)/_(y(_(_(i*i)+_(_(f*f)+_(r*r)))))),t=_(b*f),b=n,i=_(i*f),r=_(r*f),n=_(_(l*i)+_(_(n*t)+_(u*r))),C[A+152>>2]=_(c*_(t-_(b*n)))+C[A+152>>2],C[A+156>>2]=_(c*_(r-_(u*n)))+C[A+156>>2],C[A+160>>2]=_(c*_(i-_(l*n)))+C[A+160>>2])}function Hf(A,e,r){var i,f,t,n,c,b,l,u=0,s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=0,h=0,G=_(0),p=0,F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),V=_(0),N=_(0),I=_(0);for(i=Y-240|0,Y=i,Q=i+188|0,a[Q>>2]=0,a[Q+4>>2]=0,Q=i+200|0,a[Q>>2]=0,a[Q+4>>2]=0,a[i+196>>2]=1065353216,a[i+216>>2]=1065353216,s=C[r>>2],k=C[r+4>>2],v=C[r+8>>2],a[A+164>>2]=0,C[A+160>>2]=v+C[A+140>>2],C[A+156>>2]=k+C[A+136>>2],C[A+152>>2]=s+C[A+132>>2],a[i+180>>2]=0,a[i+184>>2]=0,a[i+176>>2]=1065353216,a[i+208>>2]=0,a[i+212>>2]=0,a[i+236>>2]=0,r=i+228|0,a[r>>2]=0,a[r+4>>2]=0,r=i+220|0,a[r>>2]=0,a[r+4>>2]=0,a[i+112>>2]=1065353216,r=i+124|0,a[r>>2]=0,a[r+4>>2]=0,a[i+116>>2]=0,a[i+120>>2]=0,a[i+132>>2]=1065353216,r=i+136|0,a[r>>2]=0,a[r+4>>2]=0,a[i+144>>2]=0,a[i+148>>2]=0,a[i+152>>2]=1065353216,a[i+172>>2]=0,r=i+164|0,a[r>>2]=0,a[r+4>>2]=0,r=i+156|0,a[r>>2]=0,a[r+4>>2]=0,f=A+152|0,t=A+132|0,l=i+48|0,n=i+16|0,c=i+160|0,b=i+224|0,r=-11,w=_(1);;){Q=r+1|0;A:if(!(Q>>>0>>0)){r=a[t+4>>2],a[b>>2]=a[t>>2],a[b+4>>2]=r,r=a[f+4>>2],a[c>>2]=a[f>>2],a[c+4>>2]=r,r=t+8|0,u=r,p=a[u+4>>2],h=b+8|0,a[h>>2]=a[u>>2],a[h+4>>2]=p,h=f+8|0,p=a[h+4>>2],u=c+8|0,a[u>>2]=a[h>>2],a[u+4>>2]=p,D=C[A+132>>2],E=C[A+152>>2],Z=C[A+136>>2],V=C[A+156>>2],N=C[A+140>>2],I=C[A+160>>2],k=C[A+180>>2],d=C[A+176>>2],s=C[A+168>>2],v=C[A+172>>2],a[i+220>>2]=0,a[i+204>>2]=0,a[i+188>>2]=0,a[i+156>>2]=0,a[i+140>>2]=0,a[i+124>>2]=0,B=_(_(2)/_(_(_(_(s*s)+_(v*v))+_(d*d))+_(k*k))),g=_(d*B),m=_(v*g),G=_(s*B),R=_(k*G),C[i+212>>2]=m+R,F=_(s*g),B=_(v*B),W=_(k*B),C[i+208>>2]=F-W,C[i+200>>2]=m-R,m=_(s*B),k=_(k*g),C[i+192>>2]=m+k,C[i+184>>2]=F+W,C[i+180>>2]=m-k,s=_(s*G),k=_(v*B),C[i+216>>2]=_(1)-_(s+k),v=s,s=_(d*g),C[i+196>>2]=_(1)-_(v+s),C[i+176>>2]=_(1)-_(k+s),s=C[A+184>>2],k=C[A+188>>2],d=C[A+192>>2],v=C[A+196>>2],g=_(_(2)/_(_(_(_(s*s)+_(k*k))+_(d*d))+_(v*v))),m=_(k*g),G=_(s*m),B=_(d*g),R=_(v*B),C[i+116>>2]=G-R,F=_(s*B),W=_(v*m),C[i+120>>2]=F+W,C[i+128>>2]=G+R,G=_(k*B),R=v,v=_(s*g),g=_(R*v),C[i+136>>2]=G-g,C[i+144>>2]=F-W,C[i+148>>2]=G+g,k=_(k*m),d=_(d*B),C[i+112>>2]=_(1)-_(k+d),s=_(s*v),C[i+132>>2]=_(1)-_(s+d),C[i+152>>2]=_(1)-_(s+k),u=n+24|0,a[u>>2]=0,a[u+4>>2]=0,u=n+16|0,a[u>>2]=0,a[u+4>>2]=0,u=n+8|0,a[u>>2]=0,a[u+4>>2]=0,a[n>>2]=0,a[n+4>>2]=0,a[i+100>>2]=0,a[i+104>>2]=0,C[i+96>>2]=N-I,C[i+92>>2]=Z-V,C[i+88>>2]=D-E,a[i+80>>2]=0,a[i+4>>2]=1065353216,a[i>>2]=24320,u=a[A+8>>2],a[i+84>>2]=u,u=a[u+188>>2],p=a[u+8>>2],a[i+8>>2]=a[u+4>>2],a[i+12>>2]=p,u=a[A+12>>2],s=_(Qt[a[a[u>>2]+48>>2]](u)),u=a[A+12>>2],Qt[a[a[u>>2]+44>>2]](u,_(s+C[A+64>>2])),(C[i+176>>2]!=C[i+112>>2]|C[i+192>>2]!=C[i+128>>2]|C[i+208>>2]!=C[i+144>>2]|C[i+180>>2]!=C[i+116>>2]||C[i+196>>2]!=C[i+132>>2]|C[i+212>>2]!=C[i+148>>2]|C[i+184>>2]!=C[i+120>>2]|C[i+200>>2]!=C[i+136>>2]||C[i+216>>2]!=C[i+152>>2]|C[i+236>>2]!=C[i+172>>2]|C[i+232>>2]!=C[i+168>>2]|C[i+228>>2]!=C[i+164>>2]||C[i+224>>2]!=C[i+160>>2])&&(o[A+250|0]?Sf(a[A+8>>2],a[A+12>>2],i+176|0,i+112|0,i,C[e+56>>2]):_f(e,a[A+12>>2],i+176|0,i+112|0,i,C[e+56>>2])),u=a[A+12>>2],Qt[a[a[u>>2]+44>>2]](u,s);e:{if(s=C[i+4>>2],s<_(1)&&(u=a[A+8>>2],!(4&o[u+204|0])&&Qt[a[a[A>>2]+56>>2]](A,u,a[i+80>>2]))){if(Of(A,l),k=_(C[A+152>>2]-C[A+132>>2]),v=_(C[A+156>>2]-C[A+136>>2]),d=_(C[A+160>>2]-C[A+140>>2]),g=_(_(_(k*k)+_(v*v))+_(d*d)),!(g>_(1.1920928955078125e-7)))break A;if(R=k,k=_(_(1)/_(y(g))),!(_(_(_(_(R*k)*C[A+84>>2])+_(_(v*k)*C[A+88>>2]))+_(_(d*k)*C[A+92>>2]))<=_(0)))break e;break A}u=a[f+4>>2],a[t>>2]=a[f>>2],a[t+4>>2]=u,u=a[h+4>>2],a[r>>2]=a[h>>2],a[r+4>>2]=u}if(r=Q,w=_(w-s),w>_(.009999999776482582))continue}break}Y=i+240|0}function zf(A){return A|=0,0|Qt[a[a[A>>2]+48>>2]](A)}function Pf(A,e,r,i,n,o){var c=0;return function(A,e,r){a[A+44>>2]=0,a[A+36>>2]=0,a[A+40>>2]=1028443341,a[A+32>>2]=r,a[A+28>>2]=e,a[A+24>>2]=-1,t[A+20>>1]=1,a[A+16>>2]=2139095039,a[A+8>>2]=-1,a[A+12>>2]=-1,a[A>>2]=23012,a[A+4>>2]=12}(A,e,r),a[A>>2]=24404,r=i+8|0,c=a[r+4>>2],e=A+56|0,a[e>>2]=a[r>>2],a[e+4>>2]=c,e=a[i+4>>2],a[A+48>>2]=a[i>>2],a[A+52>>2]=e,r=i+24|0,c=a[r+4>>2],e=A+72|0,a[e>>2]=a[r>>2],a[e+4>>2]=c,r=a[i+20>>2],e=A- -64|0,a[e>>2]=a[i+16>>2],a[e+4>>2]=r,r=i+40|0,c=a[r+4>>2],e=A+88|0,a[e>>2]=a[r>>2],a[e+4>>2]=c,r=a[i+36>>2],e=A+80|0,a[e>>2]=a[i+32>>2],a[e+4>>2]=r,r=i+56|0,c=a[r+4>>2],e=A+104|0,a[e>>2]=a[r>>2],a[e+4>>2]=c,r=a[i+52>>2],e=A+96|0,a[e>>2]=a[i+48>>2],a[e+4>>2]=r,r=n+8|0,i=a[r+4>>2],e=A+120|0,a[e>>2]=a[r>>2],a[e+4>>2]=i,e=a[n+4>>2],a[A+112>>2]=a[n>>2],a[A+116>>2]=e,r=a[n+20>>2],e=A+128|0,a[e>>2]=a[n+16>>2],a[e+4>>2]=r,r=n+24|0,i=a[r+4>>2],e=A+136|0,a[e>>2]=a[r>>2],a[e+4>>2]=i,r=a[n+36>>2],e=A+144|0,a[e>>2]=a[n+32>>2],a[e+4>>2]=r,r=n+40|0,i=a[r+4>>2],e=A+152|0,a[e>>2]=a[r>>2],a[e+4>>2]=i,r=a[n+52>>2],e=A+160|0,a[e>>2]=a[n+48>>2],a[e+4>>2]=r,r=n+56|0,i=a[r+4>>2],e=A+168|0,a[e>>2]=a[r>>2],a[e+4>>2]=i,a[A+680>>2]=0,a[A+684>>2]=0,e=A+688|0,a[e>>2]=0,a[e+4>>2]=0,e=A+696|0,a[e>>2]=0,a[e+4>>2]=0,e=A+704|0,a[e>>2]=0,a[e+4>>2]=0,e=A+712|0,a[e>>2]=0,a[e+4>>2]=0,e=A+720|0,a[e>>2]=0,a[e+4>>2]=0,a[A+736>>2]=1045220557,e=A+728|0,a[e>>2]=1045220557,a[e+4>>2]=1045220557,a[A+756>>2]=0,e=A+748|0,a[e>>2]=0,a[e+4>>2]=0,e=A+740|0,a[e>>2]=0,a[e+4>>2]=0,a[A+768>>2]=1063675494,e=A+760|0,a[e>>2]=1063675494,a[e+4>>2]=1063675494,a[A+812>>2]=0,e=A+804|0,a[e>>2]=0,a[e+4>>2]=0,a[A+828>>2]=0,e=A+820|0,a[e>>2]=0,a[e+4>>2]=0,f[A+838|0]=0,e=A+836|0,f[0|e]=0,f[e+1|0]=0,a[A+848>>2]=0,e=A+840|0,a[e>>2]=0,a[e+4>>2]=0,f[A+858|0]=0,e=A+856|0,f[0|e]=0,f[e+1|0]=0,a[A+868>>2]=0,e=A+860|0,a[e>>2]=0,a[e+4>>2]=0,a[A+884>>2]=0,e=A+876|0,a[e>>2]=0,a[e+4>>2]=0,a[A+900>>2]=0,e=A+892|0,a[e>>2]=0,a[e+4>>2]=0,e=A+793|0,f[0|e]=0,f[e+1|0]=0,f[e+2|0]=0,f[e+3|0]=0,f[e+4|0]=0,f[e+5|0]=0,f[e+6|0]=0,f[e+7|0]=0,e=A+788|0,a[e>>2]=0,a[e+4>>2]=0,e=A+780|0,a[e>>2]=0,a[e+4>>2]=0,e=A+772|0,a[e>>2]=0,a[e+4>>2]=0,a[A+964>>2]=0,e=A+956|0,a[e>>2]=0,a[e+4>>2]=0,e=A+948|0,a[e>>2]=0,a[e+4>>2]=0,e=A+940|0,a[e>>2]=0,a[e+4>>2]=0,e=A+932|0,a[e>>2]=0,a[e+4>>2]=0,e=A+924|0,a[e>>2]=0,a[e+4>>2]=0,e=A+916|0,a[e>>2]=0,a[e+4>>2]=0,e=A+908|0,a[e>>2]=0,a[e+4>>2]=0,f[A+1032|0]=0,a[A+1028>>2]=0,f[A+1024|0]=0,a[A+1020>>2]=0,f[A+1016|0]=0,a[A+1012>>2]=0,f[A+1008|0]=0,e=A+1e3|0,a[e>>2]=0,a[e+4>>2]=1036831949,f[A+996|0]=0,a[A+992>>2]=0,e=A+984|0,a[e>>2]=0,a[e+4>>2]=1063675494,e=A+976|0,a[e>>2]=0,a[e+4>>2]=1045220557,a[A+968>>2]=1065353216,a[A+972>>2]=-1082130432,a[A+1052>>2]=0,e=A+1044|0,a[e>>2]=0,a[e+4>>2]=0,e=A+1036|0,a[e>>2]=0,a[e+4>>2]=0,f[A+1120|0]=0,a[A+1116>>2]=0,f[A+1112|0]=0,a[A+1108>>2]=0,f[A+1104|0]=0,a[A+1100>>2]=0,f[A+1096|0]=0,e=A+1088|0,a[e>>2]=0,a[e+4>>2]=1036831949,f[A+1084|0]=0,a[A+1080>>2]=0,e=A+1072|0,a[e>>2]=0,a[e+4>>2]=1063675494,e=A+1064|0,a[e>>2]=0,a[e+4>>2]=1045220557,e=A+1056|0,a[e>>2]=1065353216,a[e+4>>2]=-1082130432,a[A+1140>>2]=0,e=A+1132|0,a[e>>2]=0,a[e+4>>2]=0,e=A+1124|0,a[e>>2]=0,a[e+4>>2]=0,f[A+1208|0]=0,a[A+1204>>2]=0,f[A+1200|0]=0,a[A+1196>>2]=0,f[A+1192|0]=0,a[A+1188>>2]=0,f[A+1184|0]=0,e=A+1176|0,a[e>>2]=0,a[e+4>>2]=1036831949,f[A+1172|0]=0,a[A+1168>>2]=0,e=A+1160|0,a[e>>2]=0,a[e+4>>2]=1063675494,e=A+1152|0,a[e>>2]=0,a[e+4>>2]=1045220557,e=A+1144|0,a[e>>2]=1065353216,a[e+4>>2]=-1082130432,a[A+1228>>2]=0,e=A+1220|0,a[e>>2]=0,a[e+4>>2]=0,e=A+1212|0,a[e>>2]=0,a[e+4>>2]=0,a[A+1456>>2]=0,a[A+1232>>2]=o,Kf(A,a[A+28>>2]+4|0,a[A+32>>2]+4|0),A}function Kf(A,e,r){var i=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),G=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0);E=C[e+52>>2],Z=C[e+56>>2],k=C[A+96>>2],v=C[A+100>>2],d=C[A+104>>2],i=C[e+20>>2],t=C[e+24>>2],g=C[A- -64>>2],B=C[A+80>>2],m=C[A+52>>2],R=C[A+68>>2],G=C[A+84>>2],p=C[A+56>>2],n=C[e+36>>2],F=C[A+72>>2],o=C[e+40>>2],W=C[A+88>>2],D=C[e+48>>2],c=C[e+8>>2],b=C[e>>2],l=C[e+4>>2],u=C[e+16>>2],w=C[A+48>>2],s=C[e+32>>2],a[A+1296>>2]=0,a[A+1280>>2]=0,a[A+1264>>2]=0,a[A+1248>>2]=0,C[A+1276>>2]=_(_(p*s)+_(F*n))+_(W*o),C[A+1272>>2]=_(_(m*s)+_(R*n))+_(G*o),C[A+1268>>2]=_(_(w*s)+_(g*n))+_(B*o),C[A+1260>>2]=_(_(p*u)+_(F*i))+_(W*t),C[A+1256>>2]=_(_(m*u)+_(R*i))+_(G*t),C[A+1252>>2]=_(_(w*u)+_(g*i))+_(B*t),C[A+1244>>2]=_(_(b*p)+_(l*F))+_(c*W),C[A+1240>>2]=_(_(b*m)+_(l*R))+_(c*G),C[A+1236>>2]=_(_(w*b)+_(g*l))+_(B*c),C[A+1292>>2]=Z+_(_(_(s*k)+_(n*v))+_(o*d)),C[A+1288>>2]=E+_(_(_(u*k)+_(i*v))+_(t*d)),C[A+1284>>2]=D+_(_(_(b*k)+_(l*v))+_(c*d)),E=C[r+52>>2],Z=C[r+56>>2],k=C[A+160>>2],v=C[A+164>>2],d=C[A+168>>2],i=C[r+20>>2],t=C[r+24>>2],g=C[A+128>>2],B=C[A+144>>2],m=C[A+116>>2],R=C[A+132>>2],G=C[A+148>>2],p=C[A+120>>2],F=C[A+136>>2],n=C[r+36>>2],W=C[A+152>>2],o=C[r+40>>2],D=C[r+48>>2],c=C[r+8>>2],b=C[r>>2],l=C[r+4>>2],u=C[r+16>>2],w=C[A+112>>2],s=C[r+32>>2],a[A+1360>>2]=0,a[A+1344>>2]=0,a[A+1328>>2]=0,a[A+1312>>2]=0,C[A+1340>>2]=_(_(p*s)+_(F*n))+_(W*o),C[A+1336>>2]=_(_(m*s)+_(R*n))+_(G*o),C[A+1332>>2]=_(_(w*s)+_(g*n))+_(B*o),C[A+1324>>2]=_(_(p*u)+_(F*i))+_(W*t),C[A+1320>>2]=_(_(m*u)+_(R*i))+_(G*t),C[A+1316>>2]=_(_(w*u)+_(g*i))+_(B*t),C[A+1308>>2]=_(_(b*p)+_(l*F))+_(c*W),C[A+1304>>2]=_(_(b*m)+_(l*R))+_(c*G),C[A+1300>>2]=_(_(w*b)+_(g*l))+_(B*c),C[A+1356>>2]=Z+_(_(_(s*k)+_(n*v))+_(o*d)),C[A+1352>>2]=E+_(_(_(u*k)+_(i*v))+_(t*d)),C[A+1348>>2]=D+_(_(_(b*k)+_(l*v))+_(c*d)),function(A){var e=_(0),r=_(0),i=_(0),f=_(0),t=0,n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=0,v=_(0),d=_(0),g=_(0),B=_(0),m=_(0);a[A+1440>>2]=0,o=C[A+1256>>2],c=C[A+1276>>2],b=C[A+1260>>2],l=C[A+1272>>2],B=_(_(o*c)-_(b*l)),r=C[A+1236>>2],i=C[A+1240>>2],u=C[A+1268>>2],s=C[A+1252>>2],m=_(_(b*u)-_(c*s)),n=_(_(l*s)-_(o*u)),f=C[A+1244>>2],e=_(_(1)/_(_(_(B*r)+_(i*m))+_(n*f))),v=_(C[A+1356>>2]-C[A+1292>>2]),d=_(C[A+1348>>2]-C[A+1284>>2]),g=_(C[A+1352>>2]-C[A+1288>>2]),n=_(_(v*_(_(_(o*r)-_(s*i))*e))+_(_(d*_(n*e))+_(g*_(_(_(u*i)-_(l*r))*e)))),C[A+1436>>2]=n,r=_(_(v*_(_(_(s*f)-_(b*r))*e))+_(_(d*_(m*e))+_(g*_(_(_(c*r)-_(u*f))*e)))),C[A+1432>>2]=r,e=_(_(v*_(_(_(b*i)-_(o*f))*e))+_(_(d*_(B*e))+_(g*_(_(_(l*f)-_(c*i))*e)))),C[A+1428>>2]=e,C[A+940>>2]=e,i=C[A+680>>2],f=C[A+696>>2],i>f?a[A+908>>2]=0:(C[A+908>>2]=e-i,t=3,i!=f&&(C[A+924>>2]=e-f,t=4)),C[A+944>>2]=r,a[A+956>>2]=t,e=C[A+684>>2],i=C[A+700>>2];A:if(e>i)a[A+912>>2]=0,t=0;else{if(C[A+912>>2]=r-e,t=3,e==i)break A;C[A+928>>2]=r-i,t=4}C[A+948>>2]=n,a[A+960>>2]=t,t=A+964|0,e=C[A+688>>2],r=C[A+704>>2];A:if(e>r)a[A+916>>2]=0,k=0;else{if(C[A+916>>2]=n-e,k=3,e==r)break A;C[A+932>>2]=n-r,k=4}a[t>>2]=k}(A),function(A){var e=_(0),r=_(0),i=_(0),f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=0,k=_(0),v=_(0),d=0,g=_(0),B=_(0),m=_(0),R=_(0),G=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=0;s=Y-48|0,Y=s,u=C[A+1332>>2],g=C[A+1316>>2],B=C[A+1336>>2],m=C[A+1304>>2],R=C[A+1320>>2],G=C[A+1340>>2],p=C[A+1308>>2],F=C[A+1324>>2],o=C[A+1244>>2],c=C[A+1256>>2],n=C[A+1272>>2],f=C[A+1240>>2],i=C[A+1268>>2],b=C[A+1260>>2],t=C[A+1252>>2],l=C[A+1276>>2],W=C[A+1300>>2],e=C[A+1236>>2],a[s+44>>2]=0,a[s+28>>2]=0,E=_(_(c*l)-_(b*n)),k=_(_(b*i)-_(l*t)),v=_(_(n*t)-_(c*i)),r=_(_(1)/_(_(_(e*E)+_(f*k))+_(v*o))),v=_(v*r),w=_(_(_(i*f)-_(n*e))*r),D=_(_(_(c*e)-_(t*f))*r),C[s+40>>2]=_(_(p*v)+_(F*w))+_(G*D),C[s+36>>2]=_(_(m*v)+_(w*R))+_(D*B),k=_(k*r),i=_(_(_(l*e)-_(i*o))*r),e=_(_(_(t*o)-_(b*e))*r),C[s+24>>2]=_(_(p*k)+_(F*i))+_(G*e),C[s+20>>2]=_(_(m*k)+_(i*R))+_(e*B),a[s+12>>2]=0,C[s+32>>2]=_(u*D)+_(_(W*v)+_(g*w)),C[s+16>>2]=_(u*e)+_(_(W*k)+_(g*i)),e=_(E*r),n=_(_(_(n*o)-_(l*f))*r),r=_(_(_(b*f)-_(c*o))*r),C[s+8>>2]=_(_(p*e)+_(F*n))+_(G*r),C[s+4>>2]=_(_(e*m)+_(n*R))+_(r*B),C[s>>2]=_(u*r)+_(_(W*e)+_(g*n)),Z=A;A:{e:{r:{i:{f:{t:{n:{a:{if(d=a[A+1232>>2],d>>>0<=5){o:{switch(d-1|0){default:!function(A,e){var r=_(0),i=_(0),f=0,t=_(0);if(r=C[A+32>>2],r<_(1)){if(r>_(-1))return f=e,t=vi(_(-C[A+36>>2]),C[A+40>>2]),C[f>>2]=t,f=e,t=Yf(_(Q(_(h(C[A+32>>2],_(-1))),_(1)))),C[f+4>>2]=t,f=e,t=vi(_(-C[A+16>>2]),C[A>>2]),void(C[f+8>>2]=t);r=C[A+20>>2],i=C[A+4>>2],a[e+4>>2]=-1077342245,f=e,t=_(-vi(i,r)),C[f>>2]=t}else r=C[A+20>>2],i=C[A+4>>2],a[e+4>>2]=1070141403,f=e,t=vi(i,r),C[f>>2]=t;C[e+8>>2]=0}(s,A+1364|0);break o;case 0:!function(A,e){var r=_(0),i=_(0),f=0,t=_(0);if(r=C[A+16>>2],r<_(1))return r>_(-1)?(f=e,t=vi(C[A+24>>2],C[A+20>>2]),C[f>>2]=t,f=e,t=vi(C[A+32>>2],C[A>>2]),C[f+4>>2]=t,f=e,t=Yf(_(Q(_(h(_(-C[A+16>>2]),_(-1))),_(1)))),void(C[f+8>>2]=t)):(r=C[A+40>>2],i=C[A+8>>2],a[e+4>>2]=0,f=e,t=_(-vi(_(-i),r)),C[f>>2]=t,void(C[e+8>>2]=1.5707963705062866));r=C[A+40>>2],i=C[A+8>>2],a[e+4>>2]=0,f=e,t=vi(_(-i),r),C[f>>2]=t,C[e+8>>2]=-1.5707963705062866}(s,A+1364|0);break o;case 1:!function(A,e){var r=_(0),i=0,f=_(0);if(r=C[A+36>>2],r<_(1)){if(r>_(-1))return i=e,f=Yf(_(Q(_(h(_(-r),_(-1))),_(1)))),C[i>>2]=f,i=e,f=vi(C[A+32>>2],C[A+40>>2]),C[i+4>>2]=f,i=e,f=vi(C[A+4>>2],C[A+20>>2]),void(C[i+8>>2]=f);a[e>>2]=1070141403,i=e,f=_(-vi(_(-C[A+16>>2]),C[A>>2])),C[i+4>>2]=f}else a[e>>2]=-1077342245,i=e,f=vi(_(-C[A+16>>2]),C[A>>2]),C[i+4>>2]=f;C[e+8>>2]=0}(s,A+1364|0);break o;case 2:!function(A,e){var r=_(0),i=0,f=_(0);if(r=C[A+4>>2],r<_(1))return r>_(-1)?(i=e,f=vi(_(-C[A+36>>2]),C[A+20>>2]),C[i>>2]=f,i=e,f=vi(_(-C[A+8>>2]),C[A>>2]),C[i+4>>2]=f,i=e,f=Yf(_(Q(_(h(C[A+4>>2],_(-1))),_(1)))),void(C[i+8>>2]=f)):(a[e>>2]=0,i=e,f=_(-vi(C[A+24>>2],C[A+40>>2])),C[i+4>>2]=f,void(C[e+8>>2]=-1.5707963705062866));a[e>>2]=0,i=e,f=vi(C[A+24>>2],C[A+40>>2]),C[i+4>>2]=f,C[e+8>>2]=1.5707963705062866}(s,A+1364|0);break o;case 3:!function(A,e){var r=_(0),i=0,f=0,t=_(0);if(i=e,r=C[A+24>>2],r<_(1)){if(r>_(-1))return f=e,t=Yf(_(Q(_(h(r,_(-1))),_(1)))),C[f>>2]=t,f=e,t=vi(_(-C[A+8>>2]),C[A+40>>2]),C[f+4>>2]=t,f=e,t=vi(_(-C[A+16>>2]),C[A+20>>2]),void(C[f+8>>2]=t);a[e>>2]=-1077342245,a[e+4>>2]=0,r=_(-vi(C[A+32>>2],C[A>>2]))}else a[e>>2]=1070141403,a[e+4>>2]=0,r=vi(C[A+32>>2],C[A>>2]);C[i+8>>2]=r}(s,A+1364|0);break o;case 4:}!function(A,e){var r=_(0),i=0,f=0,t=_(0);if(i=e,r=C[A+8>>2],r<_(1)){if(r>_(-1))return f=e,t=vi(C[A+24>>2],C[A+40>>2]),C[f>>2]=t,f=e,t=Yf(_(Q(_(h(_(-C[A+8>>2]),_(-1))),_(1)))),C[f+4>>2]=t,f=e,t=vi(C[A+4>>2],C[A>>2]),void(C[f+8>>2]=t);a[e>>2]=0,a[e+4>>2]=1070141403,r=_(-vi(C[A+16>>2],C[A+32>>2]))}else a[e>>2]=0,a[e+4>>2]=-1077342245,r=vi(_(-C[A+16>>2]),_(-C[A+32>>2]));C[i+8>>2]=r}(s,A+1364|0)}d=a[A+1232>>2]}if(d>>>0<=5)switch(d-1|0){case 4:break r;case 3:break i;case 2:break f;case 1:break t;case 0:break n;default:break a}o=C[A+1420>>2],f=C[A+1416>>2],e=C[A+1412>>2],c=C[A+1404>>2],n=C[A+1400>>2],i=C[A+1396>>2],b=C[A+1388>>2],t=C[A+1384>>2],r=C[A+1380>>2];break A}a[A+1408>>2]=0,a[A+1424>>2]=0,a[A+1392>>2]=0,r=C[A+1316>>2],t=C[A+1244>>2],f=C[A+1300>>2],l=C[A+1260>>2],c=_(_(r*t)-_(f*l)),C[A+1404>>2]=c,u=C[A+1276>>2],e=C[A+1332>>2],n=_(_(f*u)-_(t*e)),C[A+1400>>2]=n,i=_(_(e*l)-_(r*u)),C[A+1396>>2]=i,o=_(_(f*n)-_(r*i)),C[A+1420>>2]=o,f=_(_(e*i)-_(f*c)),C[A+1416>>2]=f,e=_(_(r*c)-_(e*n)),C[A+1412>>2]=e,b=_(_(l*i)-_(t*n)),C[A+1388>>2]=b,t=_(_(t*c)-_(u*i)),C[A+1384>>2]=t,r=_(_(u*n)-_(l*c));break e}a[A+1424>>2]=0,a[A+1408>>2]=0,a[A+1392>>2]=0,r=C[A+1300>>2],l=C[A+1256>>2],i=C[A+1316>>2],t=C[A+1240>>2],o=_(_(r*l)-_(i*t)),C[A+1420>>2]=o,b=C[A+1332>>2],u=C[A+1272>>2],f=_(_(t*b)-_(r*u)),C[A+1416>>2]=f,e=_(_(i*u)-_(b*l)),C[A+1412>>2]=e,c=_(_(i*e)-_(r*f)),C[A+1404>>2]=c,n=_(_(r*o)-_(b*e)),C[A+1400>>2]=n,i=_(_(b*f)-_(i*o)),C[A+1396>>2]=i,b=_(_(t*f)-_(l*e)),C[A+1388>>2]=b,t=_(_(u*e)-_(t*o)),C[A+1384>>2]=t,r=_(_(l*o)-_(u*f));break e}a[A+1424>>2]=0,a[A+1408>>2]=0,a[A+1392>>2]=0,f=C[A+1304>>2],i=C[A+1260>>2],e=C[A+1320>>2],n=C[A+1244>>2],b=_(_(f*i)-_(e*n)),C[A+1388>>2]=b,c=C[A+1336>>2],l=C[A+1276>>2],t=_(_(n*c)-_(f*l)),C[A+1384>>2]=t,r=_(_(e*l)-_(c*i)),C[A+1380>>2]=r,o=_(_(e*r)-_(f*t)),C[A+1420>>2]=o,f=_(_(f*b)-_(c*r)),C[A+1416>>2]=f,e=_(_(c*t)-_(e*b)),C[A+1412>>2]=e,c=_(_(n*t)-_(i*r)),C[A+1404>>2]=c,n=_(_(l*r)-_(n*b)),C[A+1400>>2]=n,i=_(_(i*b)-_(l*t)),C[A+1396>>2]=i;break A}a[A+1424>>2]=0,a[A+1408>>2]=0,a[A+1392>>2]=0,r=C[A+1236>>2],l=C[A+1320>>2],i=C[A+1252>>2],t=C[A+1304>>2],o=_(_(r*l)-_(i*t)),C[A+1420>>2]=o,b=C[A+1268>>2],u=C[A+1336>>2],f=_(_(t*b)-_(r*u)),C[A+1416>>2]=f,e=_(_(i*u)-_(b*l)),C[A+1412>>2]=e,c=_(_(i*e)-_(r*f)),C[A+1404>>2]=c,n=_(_(r*o)-_(b*e)),C[A+1400>>2]=n,i=_(_(b*f)-_(i*o)),C[A+1396>>2]=i,b=_(_(t*f)-_(l*e)),C[A+1388>>2]=b,t=_(_(u*e)-_(t*o)),C[A+1384>>2]=t,r=_(_(l*o)-_(u*f));break e}a[A+1424>>2]=0,a[A+1408>>2]=0,a[A+1392>>2]=0,f=C[A+1240>>2],i=C[A+1324>>2],e=C[A+1256>>2],n=C[A+1308>>2],b=_(_(f*i)-_(e*n)),C[A+1388>>2]=b,c=C[A+1272>>2],l=C[A+1340>>2],t=_(_(n*c)-_(f*l)),C[A+1384>>2]=t,r=_(_(e*l)-_(c*i)),C[A+1380>>2]=r,o=_(_(e*r)-_(f*t)),C[A+1420>>2]=o,f=_(_(f*b)-_(c*r)),C[A+1416>>2]=f,e=_(_(c*t)-_(e*b)),C[A+1412>>2]=e,c=_(_(n*t)-_(i*r)),C[A+1404>>2]=c,n=_(_(l*r)-_(n*b)),C[A+1400>>2]=n,i=_(_(i*b)-_(l*t)),C[A+1396>>2]=i;break A}a[A+1408>>2]=0,a[A+1424>>2]=0,a[A+1392>>2]=0,r=C[A+1252>>2],t=C[A+1308>>2],f=C[A+1236>>2],l=C[A+1324>>2],c=_(_(r*t)-_(f*l)),C[A+1404>>2]=c,u=C[A+1340>>2],e=C[A+1268>>2],n=_(_(f*u)-_(t*e)),C[A+1400>>2]=n,i=_(_(e*l)-_(r*u)),C[A+1396>>2]=i,o=_(_(f*n)-_(r*i)),C[A+1420>>2]=o,f=_(_(e*i)-_(f*c)),C[A+1416>>2]=f,e=_(_(r*c)-_(e*n)),C[A+1412>>2]=e,b=_(_(l*i)-_(t*n)),C[A+1388>>2]=b,t=_(_(t*c)-_(u*i)),C[A+1384>>2]=t,r=_(_(u*n)-_(l*c))}C[Z+1380>>2]=r}l=o,o=_(_(1)/_(y(_(_(_(e*e)+_(f*f))+_(o*o))))),C[A+1420>>2]=l*o,C[A+1416>>2]=f*o,C[A+1412>>2]=e*o,o=_(_(1)/_(y(_(_(_(i*i)+_(n*n))+_(c*c))))),C[A+1404>>2]=c*o,C[A+1400>>2]=n*o,C[A+1396>>2]=i*o,o=_(_(1)/_(y(_(_(_(r*r)+_(t*t))+_(b*b))))),C[A+1388>>2]=b*o,C[A+1384>>2]=t*o,C[A+1380>>2]=r*o,Y=s+48|0}(A),t=C[a[A+28>>2]+404>>2],i=C[a[A+32>>2]+404>>2],f[A+1452|0]=t<_(1.1920928955078125e-7)|i<_(1.1920928955078125e-7),D=i,i=_(t+i),i=i>_(0)?_(D/i):_(.5),C[A+1444>>2]=i,C[A+1448>>2]=_(1)-i}function Lf(A,e){var r,i=_(0),f=_(0),t=_(0),n=_(0),o=_(0);if(f=C[1364+((e<<2)+A|0)>>2],r=B(e,88)+A|0,t=C[r+968>>2],n=C[r+972>>2],t>=n||(f_(3.1415927410125732)&&(i=_(i+_(-6.2831854820251465))),o=_(m(i)),i=Wf(_(n-f)),i<_(-3.1415927410125732)?i=_(i+_(6.2831854820251465)):i>_(3.1415927410125732)&&(i=_(i+_(-6.2831854820251465))),f=o<_(m(i))?f:_(f+_(6.2831854820251465))):f>n&&(i=Wf(_(f-n)),i<_(-3.1415927410125732)?i=_(i+_(6.2831854820251465)):i>_(3.1415927410125732)&&(i=_(i+_(-6.2831854820251465))),o=_(m(i)),i=Wf(_(f-t)),i<_(-3.1415927410125732)?i=_(i+_(6.2831854820251465)):i>_(3.1415927410125732)&&(i=_(i+_(-6.2831854820251465))),f=_(m(i))>2]=f,t>n)return A=B(e,88)+A|0,a[A+1040>>2]=0,void(a[A+1052>>2]=0);A=B(e,88)+A|0,C[A+1040>>2]=f-t,t!=n?(a[A+1052>>2]=4,C[A+1044>>2]=f-n):a[A+1052>>2]=3}function qf(A,e,r,i,f,t,n,c,b,l,u,s,k){var v=_(0),d=_(0),g=_(0),m=0,R=0,G=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0);if(l=B(a[b+24>>2],l),m=a[e+84>>2]+-3|0,m>>>0>1)m=0;else{if(m-1)$f(A,r,i,b,l,u,s,k),R=l<<2,C[R+a[b+28>>2]>>2]=_(_(C[b>>2]*C[e+12>>2])*C[e+72>>2])*_(0|(s?-1:1)),a[R+a[b+36>>2]>>2]=-8388609,a[R+a[b+40>>2]>>2]=2139095039,R=e+16|0,m=1;else{s?(v=C[u>>2],g=C[u+4>>2],d=_(_(C[n>>2]*v)+_(C[n+4>>2]*g)),G=C[u+8>>2],F=_(C[n+8>>2]*G),R=s,m=c):(v=C[u>>2],g=C[u+4>>2],d=_(_(C[f>>2]*v)+_(C[f+4>>2]*g)),G=C[u+8>>2],F=_(C[f+8>>2]*G),m=t),w=C[m+8>>2],D=C[m>>2],W=C[m+4>>2],$f(A,r,i,b,l,u,R,k),m=a[b+28>>2]+(l<<2)|0,E=_(0|(s?-1:1)),p=_(_(_(C[b>>2]*C[e+12>>2])*C[e+72>>2])*E),C[m>>2]=p,v=_(_(d+F)-_(_(_(v*D)+_(g*W))+_(G*w))),d=_(p-_(v*C[e+12>>2]));A:if(s){if(!(d>_(0)))break A;if(d=_(-_(v*C[e+8>>2])),!(p>2]=d}else d<_(0)&&(d=_(-_(v*C[e+8>>2])),p>d&&(C[m>>2]=d));m=l<<2,C[m+a[b+36>>2]>>2]=_(s?0:-3.4028234663852886e38),C[m+a[b+40>>2]>>2]=_(s?3.4028234663852886e38:0),a[m+a[b+32>>2]>>2]=a[e+16>>2],l=a[b+24>>2]+l|0,$f(A,r,i,b,l,u,s,k),m=a[b+28>>2]+(l<<2)|0,d=_(_(_(C[b>>2]*C[e+12>>2])*C[e+76>>2])*E),C[m>>2]=d,g=_(d-_(v*C[e+12>>2])),R=e+16|0;A:if(s){if(!(g<_(0)))break A;if(v=_(-_(v*C[e+8>>2])),!(d>v))break A;C[m>>2]=v}else g>_(0)&&(v=_(-_(v*C[e+8>>2])),d>2]=v));m=l<<2,C[m+a[b+36>>2]>>2]=_(s?-3.4028234663852886e38:0),C[a[b+40>>2]+m>>2]=_(s?0:3.4028234663852886e38),m=2}a[a[b+32>>2]+(l<<2)>>2]=a[R>>2],l=a[b+24>>2]+l|0}return o[e+28|0]&&(!o[e+40|0]&&($f(A,r,i,b,l,u,s,k),v=C[e+32>>2],v=wf(C[e+80>>2],C[e>>2],C[e+4>>2],s?v:_(-v),_(C[b>>2]*C[e+20>>2])),R=l<<2,C[R+a[b+28>>2]>>2]=v*C[e+32>>2],C[R+a[b+36>>2]>>2]=-C[e+36>>2],a[R+a[b+40>>2]>>2]=a[e+36>>2],a[R+a[b+32>>2]>>2]=a[e+24>>2],m=m+1|0,l=a[b+24>>2]+l|0,!o[e+28|0]|!o[e+40|0])||(d=C[e+44>>2],v=_(C[e+80>>2]-d),s&&(R=v>_(3.1415927410125732),d=R?_(d+_(6.2831854820251465)):d,v=R?_(v+_(-6.2831854820251465)):v,v<_(-3.1415927410125732)&&(d=_(d+_(-6.2831854820251465)),v=_(v+_(6.2831854820251465)))),$f(A,r,i,b,l,u,s,k),g=_(0),G=C[e+32>>2],p=v<_(0)?_(-G):G,v!=_(0)&&(F=_(-p),W=C[e+80>>2],g=C[e>>2],G=C[e+4>>2],g>G?(G=v<_(0)?d:_(3.4028234663852886e38),v=v>_(0)?d:_(-3.4028234663852886e38)):(G=v<_(0)&&d_(0)&&d>g?d:g),g=wf(W,v,G,F,_(C[b>>2]*C[e+20>>2]))),R=l<<2,C[R+a[b+28>>2]>>2]=_(p*g)*_(0|(s?-1:1)),C[R+a[b+36>>2]>>2]=-C[e+36>>2],a[R+a[b+40>>2]>>2]=a[e+36>>2],a[R+a[b+32>>2]>>2]=a[e+24>>2],m=m+1|0,l=a[b+24>>2]+l|0)),o[e+48|0]&&(W=C[e+68>>2],E=C[e+80>>2],$f(A,r,i,b,l,u,s,k),v=C[b>>2],d=C[e+52>>2],G=C[e+60>>2],W=_(E-W),s?(w=C[u+8>>2],D=_(C[n+8>>2]*w),g=C[u>>2],p=C[u+4>>2],F=_(_(C[n>>2]*g)+_(C[n+4>>2]*p))):(w=C[u+8>>2],D=_(C[f+8>>2]*w),c=t,g=C[u>>2],p=C[u+4>>2],F=_(_(C[f>>2]*g)+_(C[f+4>>2]*p))),p=_(_(F+D)-_(_(_(g*C[c>>2])+_(p*C[c+4>>2]))+_(w*C[c+8>>2]))),v=_(_(1)/v),g=_(_(1)/C[a[A+32>>2]+404>>2]),F=_(_(1)/C[a[A+28>>2]+404>>2]),g=F>g?g:F,!o[e+56|0]|_(v*_(y(_(d/g))))>_(.25)^1||(d=_(_(_(_(_(1)/v)/v)*_(.0625))*g)),A=l<<2,F=_(v*_(W*d)),d=_(0|(s?-1:1)),g=_(v*_(_(p*(_(G*v)>g&&o[e+64|0]?_(g/v):G))*d)),v=_(F-g),C[A+a[b+28>>2]>>2]=p+_(v*d),g=_(-g),e=v>2]>>2]=Q(_(-d),_(0)),d=_(-v)):C[A+a[b+36>>2]>>2]=Q(v,_(0)),A=l<<2,C[A+a[b+40>>2]>>2]=h(d,_(0)),a[A+a[b+32>>2]>>2]=0,m=m+1|0),m}function $f(A,e,r,i,f,t,n,c){var b,l,u,s,k,v,d=_(0),g=_(0),B=_(0),m=0,R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0);b=Y-16|0,l=f<<2,m=a[(n?12:8)+i>>2],a[l+m>>2]=a[t>>2],u=f+1|0,s=u<<2,a[m+s>>2]=a[t+4>>2],k=f+2|0,v=k<<2,a[m+v>>2]=a[t+8>>2],m=a[(n?20:16)+i>>2],C[m+l>>2]=-C[t>>2],C[m+s>>2]=-C[t+4>>2],C[m+v>>2]=-C[t+8>>2],n||(a[b+12>>2]=0,d=_(C[A+1284>>2]-C[e+48>>2]),g=C[t+4>>2],R=_(C[A+1288>>2]-C[e+52>>2]),B=C[t>>2],G=_(_(d*g)-_(R*B)),C[b+8>>2]=G,Q=_(C[A+1292>>2]-C[e+56>>2]),h=d,d=C[t+8>>2],y=_(_(B*Q)-_(h*d)),C[b+4>>2]=y,Q=_(_(R*d)-_(Q*g)),C[b>>2]=Q,p=_(C[A+1352>>2]-C[r+52>>2]),F=_(C[A+1356>>2]-C[r+56>>2]),R=_(_(d*p)-_(g*F)),h=_(C[A+1348>>2]-C[r+48>>2]),g=_(_(g*h)-_(p*B)),B=_(_(F*B)-_(h*d)),!o[A+1452|0]|c||(d=C[A+1444>>2],C[b+8>>2]=G*d,C[b+4>>2]=y*d,C[b>>2]=Q*d,d=C[A+1448>>2],g=_(g*d),R=_(R*d),B=_(B*d)),e=a[b+4>>2],r=f<<2,A=r+a[i+12>>2]|0,a[A>>2]=a[b>>2],a[A+4>>2]=e,a[A+8>>2]=a[b+8>>2],A=a[i+20>>2],C[A+r>>2]=-R,C[A+(u<<2)>>2]=-B,C[A+(k<<2)>>2]=-g)}function At(A){A|=0,a[A>>2]=23012,CA(A)}function et(A){return A|=0,_(C[A>>2])}function rt(A){return A|=0,_(C[A+4>>2])}function it(A){return A|=0,_(C[A+8>>2])}function ft(A){return A|=0,A+48|0}function tt(A,e){var r,i=_(0),f=0,t=0,n=_(0),o=0,b=_(0),l=0,u=0,k=_(0),v=0;r=Y-16|0,i=C[A>>2],b=C[A+20>>2],n=C[A+40>>2],k=_(_(i+b)+n),k>_(0)?(b=_(y(_(k+_(1)))),i=_(_(.5)/b),n=_(i*_(C[A+16>>2]-C[A+4>>2])),C[r+8>>2]=n,s(n),f=c(0),n=_(i*_(C[A+8>>2]-C[A+32>>2])),C[r+4>>2]=n,i=_(i*_(C[A+36>>2]-C[A+24>>2])),C[r>>2]=i,s(i),A=c(0),i=_(b*_(.5)),C[r+12>>2]=i,s(i),t=c(0),s(n),o=c(0)):(f=i>>0)%3|0,u=(t<<4)+A|0,t<<=2,v=A,A=(f+2>>>0)%3|0,f=v+(A<<4)|0,A<<=2,i=_(y(_(_(_(C[o+l>>2]-C[u+t>>2])-C[f+A>>2])+_(1)))),C[(o|r)>>2]=i*_(.5),i=_(_(.5)/i),C[r+12>>2]=_(C[f+t>>2]-C[A+u>>2])*i,C[(r|t)>>2]=i*_(C[o+u>>2]+C[t+l>>2]),C[(A|r)>>2]=i*_(C[f+o>>2]+C[A+l>>2]),t=a[r+12>>2],f=a[r+8>>2],A=a[r>>2],o=a[r+4>>2]),a[e+12>>2]=t,a[e+8>>2]=f,a[e+4>>2]=o,a[e>>2]=A}function nt(A){A|=0,A&&Qt[a[a[A>>2]+4>>2]](A)}function at(A,e){A|=0,e|=0,a[A+12>>2]=e}function ot(A,e){A|=0,e=_(e),C[A+4>>2]=e}function ct(A,e){A|=0,e|=0,a[A+8>>2]=e}function bt(A){return A|=0,A+24|0}function lt(A){var e;A|=0,e=a[A+12>>2],e&&(o[A+16|0]&&CA(e),a[A+12>>2]=0),a[A+12>>2]=0,f[A+16|0]=1,a[A+4>>2]=0,a[A+8>>2]=0}function ut(A){return A|=0,A+32|0}function st(A){return A|=0,A- -64|0}function kt(A){return A|=0,0|Qt[a[a[A>>2]+36>>2]](A)}function vt(A,e){A|=0,e|=0,Qt[a[a[A>>2]+60>>2]](A,e)}function dt(A,e,r){var i=_(0),f=_(0),t=_(0),n=_(0),a=0,o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0);i=C[A+404>>2],i!=_(0)&&(t=C[e+8>>2],f=C[e+4>>2],n=C[A+408>>2],C[A+372>>2]=_(i*_(C[e>>2]*n))+C[A+372>>2],a=A+376|0,o=f,f=C[A+412>>2],C[a>>2]=_(i*_(o*f))+C[a>>2],a=A+380|0,o=i,i=C[A+416>>2],C[a>>2]=_(o*_(t*i))+C[a>>2],l=C[A+612>>2],u=C[A+364>>2],s=C[A+356>>2],k=C[A+360>>2],v=C[A+608>>2],d=C[A+348>>2],g=C[A+340>>2],B=C[A+344>>2],b=C[r+4>>2],t=_(i*C[e+8>>2]),f=_(f*C[e+4>>2]),c=C[r+8>>2],i=_(_(b*t)-_(f*c)),n=_(n*C[e>>2]),o=_(n*c),c=C[r>>2],t=_(o-_(t*c)),f=_(_(f*c)-_(n*b)),C[A+388>>2]=_(_(_(_(C[A+324>>2]*i)+_(C[A+328>>2]*t))+_(f*C[A+332>>2]))*C[A+604>>2])+C[A+388>>2],e=A+392|0,C[e>>2]=_(v*_(_(_(i*g)+_(t*B))+_(f*d)))+C[e>>2],A=A+396|0,C[A>>2]=_(l*_(_(_(i*s)+_(t*k))+_(f*u)))+C[A>>2])}function Ct(A){A|=0;var e=0;return a[A>>2]=24920,e=a[A+128>>2],e&&(o[A+132|0]&&CA(e),a[A+128>>2]=0),a[A+128>>2]=0,a[A+120>>2]=0,a[A+124>>2]=0,f[A+132|0]=1,e=a[A+108>>2],e&&(o[A+112|0]&&CA(e),a[A+108>>2]=0),a[A+108>>2]=0,a[A+100>>2]=0,a[A+104>>2]=0,f[A+112|0]=1,e=a[A+88>>2],e&&(o[A+92|0]&&CA(e),a[A+88>>2]=0),a[A+88>>2]=0,a[A+80>>2]=0,a[A+84>>2]=0,f[A+92|0]=1,e=a[A+36>>2],e&&(o[A+40|0]&&CA(e),a[A+36>>2]=0),a[A+36>>2]=0,a[A+28>>2]=0,a[A+32>>2]=0,f[A+40|0]=1,0|A}function gt(A){A|=0;var e=0;return a[A>>2]=25144,e=a[A+120>>2],e&&(o[A+124|0]&&CA(e),a[A+120>>2]=0),a[A+120>>2]=0,a[A+112>>2]=0,a[A+116>>2]=0,f[A+124|0]=1,e=a[A+100>>2],e&&(o[A+104|0]&&CA(e),a[A+100>>2]=0),a[A+100>>2]=0,a[A+92>>2]=0,a[A+96>>2]=0,f[A+104|0]=1,e=a[A+80>>2],e&&(o[A+84|0]&&CA(e),a[A+80>>2]=0),a[A+80>>2]=0,a[A+72>>2]=0,a[A+76>>2]=0,f[A+84|0]=1,e=a[A+28>>2],e&&(o[A+32|0]&&CA(e),a[A+28>>2]=0),a[A+28>>2]=0,a[A+20>>2]=0,a[A+24>>2]=0,f[A+32|0]=1,0|A}function Bt(A,e){!function(A,e){n[0]=A,n[1]=e}(0|A,0|e)}function _t(A,e,r,i){return A=function(A,e,r,i){var f,t,n,a,o=0,c=0;return o=r>>>16,c=A>>>16,a=B(o,c),f=65535&r,t=65535&A,n=B(f,t),c=(n>>>16)+B(c,f)|0,o=(65535&c)+B(o,t)|0,A=(((B(e,r)+a|0)+B(A,i)|0)+(c>>>16)|0)+(o>>>16)|0,e=65535&n|o<<16,V=A,e}(A,e,r,i),A}function mt(A,e,r){return function(A,e,r){var i=0,f=0,t=0,n=0,a=0,o=0,c=0,b=0,l=0;A:{e:{r:{i:{f:{t:{n:{a:{o:{if(f=e,f){if(i=r,!i)break o;break a}return e=A,A=(A>>>0)/(r>>>0)|0,Bt(e-B(A,r)|0,0),V=0,A}if(!A)break n;break t}if(n=i+-1|0,!(n&i))break f;n=(R(i)+33|0)-R(f)|0,a=0-n|0;break r}return A=(f>>>0)/0|0,Bt(0,f-B(A,0)|0),V=0,A}if(i=32-R(f)|0,i>>>0<31)break i;break e}if(Bt(A&n,0),1==(0|i))break A;return i=i?31-R(i+-1^i)|0:32,r=31&i,32<=(63&i)>>>0?(f=0,A=e>>>r):(f=e>>>r,A=((1<>>r),V=f,A}n=i+1|0,a=63-i|0}if(i=e,f=63&n,t=31&f,32<=f>>>0?(f=0,t=i>>>t):(f=i>>>t,t=((1<>>t),a&=63,i=31&a,32<=a>>>0?(e=A<>>32-i|e<>>0<4294967295&&(i=0);o=t<<1|e>>>31,c=o,f=f<<1|t>>>31,o=i-(f+(a>>>0>>0)|0)>>31,b=r&o,t=c-b|0,f=f-(c>>>0>>0)|0,e=e<<1|A>>>31,A=l|A<<1,o&=1,l=o,n=n+-1|0,n;);return Bt(t,f),V=e<<1|A>>>31,o|A<<1}Bt(A,e),A=0,e=0}return V=e,A}(A,e,r)}function Rt(A){var e;return e=31&A,A=0-A&31,(-1>>>e&-2)<>>A}var Qt=[null,function(A){A|=0;var e=0;return A=0|W(a[A+56>>2]),e=0,A&&(a[256]=A,e=-1),0|e},function(A,e,r){A|=0,e|=0,r|=0;var i,f=0,t=0,n=0,o=0,c=0;i=Y-16|0,Y=i,a[i+12>>2]=r,a[i+8>>2]=e,e=a[A+24>>2],a[i>>2]=e,e=a[A+20>>2]-e|0,a[i+4>>2]=e,n=2,o=e+r|0,f=N(a[A+56>>2],i,2);A:{if((0|o)!=(0|f))for(e=i;;){if((0|f)<=-1){if(a[A+24>>2]=0,a[A+16>>2]=0,a[A+20>>2]=0,a[A>>2]=32|a[A>>2],A=0,2==(0|n))break A;A=r-a[e+4>>2]|0;break A}if(t=a[e+4>>2],c=f>>>0>t>>>0,e=c?e+8|0:e,t=f-(c?t:0)|0,a[e>>2]=t+a[e>>2],a[e+4>>2]=a[e+4>>2]-t,o=o-f|0,n=n-c|0,f=N(a[A+56>>2],e,n),(0|o)==(0|f))break}e=a[A+40>>2],a[A+24>>2]=e,a[A+20>>2]=e,a[A+16>>2]=e+a[A+44>>2],A=r}return f=A,Y=i+16|0,0|f},function(A,e,r,i){return A|=0,e|=0,r|=0,i|=0,A=function(A,e,r,i){var f;return f=Y-16|0,Y=f,A=0|Z(0|A,0|e,0|r,255&i,f+8|0),A?(a[256]=76==(0|A)?70:A,r=-1,A=-1):(r=a[f+12>>2],A=a[f+8>>2]),Y=f+16|0,V=r,A}(a[A+56>>2],e,r,i),0|A},rA,iA,iA,function(A){var e;A|=0,e=Y-16|0,Y=e,a[e+12>>2]=A,A=a[e+12>>2],rA(A),$(A),Y=e+16|0},eA,eA,function(A,e,r){var i;return A|=0,e|=0,r|=0,i=Y-80|0,Y=i,a[i+72>>2]=A,a[i+68>>2]=e,a[i+64>>2]=r,e=a[i+72>>2],1&fA(e,a[i+68>>2],0)?f[i+79|0]=1:(r=i,A=a[i+68>>2],A=A?function(A){var e=0;if(e=Y-96|0,Y=e,a[e+92>>2]=A,a[e+88>>2]=5456,a[e+84>>2]=5504,a[e+80>>2]=0,a[e+76>>2]=a[a[e+92>>2]>>2],a[e+72>>2]=a[a[e+76>>2]+-8>>2],a[e+68>>2]=a[e+92>>2]+a[e+72>>2],a[e+64>>2]=a[a[e+76>>2]+-4>>2],a[e+60>>2]=0,a[e>>2]=a[e+84>>2],a[e+4>>2]=a[e+92>>2],a[e+8>>2]=a[e+88>>2],a[e+12>>2]=a[e+80>>2],a[e+16>>2]=0,a[e+20>>2]=0,a[e+24>>2]=0,a[e+28>>2]=0,a[e+32>>2]=0,a[e+36>>2]=0,a[e+40>>2]=0,a[e+44>>2]=0,a[e+48>>2]=0,f[e+52|0]=0,f[e+53|0]=0,f[e+54|0]=0,1&fA(a[e+64>>2],a[e+84>>2],0))a[e+48>>2]=1,A=a[e+64>>2],Qt[a[a[A>>2]+20>>2]](A,e,a[e+68>>2],a[e+68>>2],1,0),1==a[e+24>>2]&&(a[e+60>>2]=a[e+68>>2]);else{A=a[e+64>>2],Qt[a[a[A>>2]+24>>2]](A,e,a[e+68>>2],1,0),A=a[e+36>>2];A:if(!(A>>>0>1))if(A-1){if(1!=a[e+40>>2]|1!=a[e+28>>2]|1!=a[e+32>>2])break A;a[e+60>>2]=a[e+20>>2]}else a[e+40>>2]|1!=a[e+28>>2]|1!=a[e+32>>2]&&1!=a[e+24>>2]||(a[e+60>>2]=a[e+16>>2])}return Y=e+96|0,a[e+60>>2]}(A):0,a[r+60>>2]=A,a[i+60>>2]?(a[i>>2]=a[i+60>>2],a[i+4>>2]=0,a[i+8>>2]=e,a[i+12>>2]=-1,a[i+16>>2]=0,a[i+20>>2]=0,a[i+24>>2]=0,a[i+28>>2]=0,a[i+32>>2]=0,a[i+36>>2]=0,a[i+40>>2]=0,a[i+44>>2]=0,a[i+48>>2]=0,f[i+52|0]=0,f[i+53|0]=0,f[i+54|0]=0,a[i+48>>2]=1,A=a[i+60>>2],Qt[a[a[A>>2]+28>>2]](A,i,a[a[i+64>>2]>>2],1),1!=a[i+24>>2]?f[i+79|0]=0:(a[a[i+64>>2]>>2]=a[i+16>>2],f[i+79|0]=1)):f[i+79|0]=0),Y=i+80|0,1&f[i+79|0]},function(A,e,r,i,t,n){var o;A|=0,e|=0,r|=0,i|=0,t|=0,n|=0,o=Y-32|0,Y=o,a[o+28>>2]=A,a[o+24>>2]=e,a[o+20>>2]=r,a[o+16>>2]=i,a[o+12>>2]=t,f[o+11|0]=n,A=a[o+28>>2],1&fA(A,a[a[o+24>>2]+8>>2],1&f[o+11|0])&&oA(A,a[o+24>>2],a[o+20>>2],a[o+16>>2],a[o+12>>2]),Y=o+32|0},function(A,e,r,i,t){var n;A|=0,e|=0,r|=0,i|=0,t|=0,n=Y-32|0,Y=n,a[n+28>>2]=A,a[n+24>>2]=e,a[n+20>>2]=r,a[n+16>>2]=i,f[n+15|0]=t,A=a[n+28>>2],1&fA(A,a[a[n+24>>2]+8>>2],1&f[n+15|0])?cA(A,a[n+24>>2],a[n+20>>2],a[n+16>>2]):1&fA(A,a[a[n+24>>2]>>2],1&f[n+15|0])&&(a[n+20>>2]!=a[a[n+24>>2]+20>>2]&&a[n+20>>2]!=a[a[n+24>>2]+16>>2]?(a[a[n+24>>2]+32>>2]=a[n+16>>2],a[a[n+24>>2]+20>>2]=a[n+20>>2],A=a[n+24>>2],a[A+40>>2]=a[A+40>>2]+1,1!=a[a[n+24>>2]+36>>2]|2!=a[a[n+24>>2]+24>>2]||(f[a[n+24>>2]+54|0]=1),a[a[n+24>>2]+44>>2]=4):1==a[n+16>>2]&&(a[a[n+24>>2]+32>>2]=1)),Y=n+32|0},function(A,e,r,i){var f;A|=0,e|=0,r|=0,i|=0,f=Y-16|0,Y=f,a[f+12>>2]=A,a[f+8>>2]=e,a[f+4>>2]=r,a[f>>2]=i,A=a[f+12>>2],1&fA(A,a[a[f+8>>2]+8>>2],0)&&nA(A,a[f+8>>2],a[f+4>>2],a[f>>2]),Y=f+16|0},function(A){var e;A|=0,e=Y-16|0,Y=e,a[e+12>>2]=A,A=a[e+12>>2],iA(A),$(A),Y=e+16|0},function(A,e,r,i,t,n){var o;A|=0,e|=0,r|=0,i|=0,t|=0,n|=0,o=Y-32|0,Y=o,a[o+28>>2]=A,a[o+24>>2]=e,a[o+20>>2]=r,a[o+16>>2]=i,a[o+12>>2]=t,f[o+11|0]=n,A=a[o+28>>2],1&fA(A,a[a[o+24>>2]+8>>2],1&f[o+11|0])?oA(A,a[o+24>>2],a[o+20>>2],a[o+16>>2],a[o+12>>2]):(A=a[A+8>>2],Qt[a[a[A>>2]+20>>2]](A,a[o+24>>2],a[o+20>>2],a[o+16>>2],a[o+12>>2],1&f[o+11|0])),Y=o+32|0},function(A,e,r,i,t){var n;if(A|=0,e|=0,r|=0,i|=0,t|=0,n=Y-32|0,Y=n,a[n+28>>2]=A,a[n+24>>2]=e,a[n+20>>2]=r,a[n+16>>2]=i,f[n+15|0]=t,A=a[n+28>>2],1&fA(A,a[a[n+24>>2]+8>>2],1&f[n+15|0]))cA(A,a[n+24>>2],a[n+20>>2],a[n+16>>2]);else A:if(1&fA(A,a[a[n+24>>2]>>2],1&f[n+15|0])){if(a[n+20>>2]==a[a[n+24>>2]+20>>2]||a[n+20>>2]==a[a[n+24>>2]+16>>2]){1==a[n+16>>2]&&(a[a[n+24>>2]+32>>2]=1);break A}a[a[n+24>>2]+32>>2]=a[n+16>>2],f[n+14|0]=0,4!=a[a[n+24>>2]+44>>2]&&(f[n+13|0]=0,f[a[n+24>>2]+52|0]=0,f[a[n+24>>2]+53|0]=0,A=a[A+8>>2],Qt[a[a[A>>2]+20>>2]](A,a[n+24>>2],a[n+20>>2],a[n+20>>2],1,1&f[n+15|0]),1&f[a[n+24>>2]+53|0]&&(f[n+13|0]=1,1&f[a[n+24>>2]+52|0]&&(f[n+14|0]=1)),1&f[n+13|0]?a[a[n+24>>2]+44>>2]=3:a[a[n+24>>2]+44>>2]=4),1&f[n+14|0]||(a[a[n+24>>2]+20>>2]=a[n+20>>2],A=a[n+24>>2],a[A+40>>2]=a[A+40>>2]+1,1!=a[a[n+24>>2]+36>>2]|2!=a[a[n+24>>2]+24>>2]||(f[a[n+24>>2]+54|0]=1))}else A=a[A+8>>2],Qt[a[a[A>>2]+24>>2]](A,a[n+24>>2],a[n+20>>2],a[n+16>>2],1&f[n+15|0]);Y=n+32|0},function(A,e,r,i){var f;A|=0,e|=0,r|=0,i|=0,f=Y-16|0,Y=f,a[f+12>>2]=A,a[f+8>>2]=e,a[f+4>>2]=r,a[f>>2]=i,A=a[f+12>>2],1&fA(A,a[a[f+8>>2]+8>>2],0)?nA(A,a[f+8>>2],a[f+4>>2],a[f>>2]):(A=a[A+8>>2],Qt[a[a[A>>2]+28>>2]](A,a[f+8>>2],a[f+4>>2],a[f>>2])),Y=f+16|0},function(A){var e;A|=0,e=Y-16|0,Y=e,a[e+12>>2]=A,A=a[e+12>>2],iA(A),$(A),Y=e+16|0},function(A,e,r,i,t,n){var o;if(A|=0,e|=0,r|=0,i|=0,t|=0,n|=0,o=Y-32|0,Y=o,a[o+28>>2]=A,a[o+24>>2]=e,a[o+20>>2]=r,a[o+16>>2]=i,a[o+12>>2]=t,f[o+11|0]=n,A=a[o+28>>2],1&fA(A,a[a[o+24>>2]+8>>2],1&f[o+11|0]))oA(A,a[o+24>>2],a[o+20>>2],a[o+16>>2],a[o+12>>2]);else{if(f[o+10|0]=1&f[a[o+24>>2]+52|0],f[o+9|0]=1&f[a[o+24>>2]+53|0],a[o+4>>2]=(A+16|0)+(a[A+12>>2]<<3),a[o>>2]=A+16,f[a[o+24>>2]+52|0]=0,f[a[o+24>>2]+53|0]=0,bA(a[o>>2],a[o+24>>2],a[o+20>>2],a[o+16>>2],a[o+12>>2],1&f[o+11|0]),f[o+10|0]=0!=(1&f[o+10|0]|1&f[a[o+24>>2]+52|0]),f[o+9|0]=0!=(1&f[o+9|0]|1&f[a[o+24>>2]+53|0]),e=a[o>>2]+8|0,a[o>>2]=e,e>>>0>2])for(;;){A:if(!(1&f[a[o+24>>2]+54|0])){if(1&f[a[o+24>>2]+52|0]){if(!(2&a[A+8>>2])|1==a[a[o+24>>2]+24>>2])break A}else if(!(1&a[A+8>>2])&&1&f[a[o+24>>2]+53|0])break A;if(f[a[o+24>>2]+52|0]=0,f[a[o+24>>2]+53|0]=0,bA(a[o>>2],a[o+24>>2],a[o+20>>2],a[o+16>>2],a[o+12>>2],1&f[o+11|0]),f[o+10|0]=0!=(1&f[o+10|0]|1&f[a[o+24>>2]+52|0]),f[o+9|0]=0!=(1&f[o+9|0]|1&f[a[o+24>>2]+53|0]),e=a[o>>2]+8|0,a[o>>2]=e,e>>>0>2])continue}break}f[a[o+24>>2]+52|0]=1&f[o+10|0],f[a[o+24>>2]+53|0]=1&f[o+9|0]}Y=o+32|0},function(A,e,r,i,t){var n;if(A|=0,e|=0,r|=0,i|=0,t|=0,n=Y-48|0,Y=n,a[n+44>>2]=A,a[n+40>>2]=e,a[n+36>>2]=r,a[n+32>>2]=i,f[n+31|0]=t,A=a[n+44>>2],1&fA(A,a[a[n+40>>2]+8>>2],1&f[n+31|0]))cA(A,a[n+40>>2],a[n+36>>2],a[n+32>>2]);else A:if(1&fA(A,a[a[n+40>>2]>>2],1&f[n+31|0])){if(a[n+36>>2]==a[a[n+40>>2]+20>>2]||a[n+36>>2]==a[a[n+40>>2]+16>>2]){1==a[n+32>>2]&&(a[a[n+40>>2]+32>>2]=1);break A}if(a[a[n+40>>2]+32>>2]=a[n+32>>2],f[n+30|0]=0,4!=a[a[n+40>>2]+44>>2]){for(f[n+29|0]=0,a[n+24>>2]=(A+16|0)+(a[A+12>>2]<<3),a[n+20>>2]=A+16;;){e:if(!(d[n+20>>2]>=d[n+24>>2]||(f[a[n+40>>2]+52|0]=0,f[a[n+40>>2]+53|0]=0,bA(a[n+20>>2],a[n+40>>2],a[n+36>>2],a[n+36>>2],1,1&f[n+31|0]),1&f[a[n+40>>2]+54|0]))){if(1&f[a[n+40>>2]+53|0])if(f[n+29|0]=1,1&f[a[n+40>>2]+52|0]){if(f[n+30|0]=1,!(2&a[A+8>>2])|1==a[a[n+40>>2]+24>>2])break e}else if(!(1&a[A+8>>2]))break e;a[n+20>>2]=a[n+20>>2]+8;continue}break}1&f[n+29|0]?a[a[n+40>>2]+44>>2]=3:a[a[n+40>>2]+44>>2]=4}1&f[n+30|0]||(a[a[n+40>>2]+20>>2]=a[n+36>>2],A=a[n+40>>2],a[A+40>>2]=a[A+40>>2]+1,1!=a[a[n+40>>2]+36>>2]|2!=a[a[n+40>>2]+24>>2]||(f[a[n+40>>2]+54|0]=1))}else if(a[n+16>>2]=(A+16|0)+(a[A+12>>2]<<3),a[n+12>>2]=A+16,lA(a[n+12>>2],a[n+40>>2],a[n+36>>2],a[n+32>>2],1&f[n+31|0]),e=a[n+12>>2]+8|0,a[n+12>>2]=e,e>>>0>2])if(1==a[a[n+40>>2]+36>>2]||2&a[A+8>>2])for(;!(1&f[a[n+40>>2]+54|0])&&(lA(a[n+12>>2],a[n+40>>2],a[n+36>>2],a[n+32>>2],1&f[n+31|0]),A=a[n+12>>2]+8|0,a[n+12>>2]=A,A>>>0>2]););else if(1&a[A+8>>2])for(;!(!!(1&f[a[n+40>>2]+54|0])|!(1!=a[a[n+40>>2]+36>>2]|1!=a[a[n+40>>2]+24>>2]))&&(lA(a[n+12>>2],a[n+40>>2],a[n+36>>2],a[n+32>>2],1&f[n+31|0]),A=a[n+12>>2]+8|0,a[n+12>>2]=A,A>>>0>2]););else for(;!(!!(1&f[a[n+40>>2]+54|0])|1==a[a[n+40>>2]+36>>2])&&(lA(a[n+12>>2],a[n+40>>2],a[n+36>>2],a[n+32>>2],1&f[n+31|0]),A=a[n+12>>2]+8|0,a[n+12>>2]=A,A>>>0>2]););Y=n+48|0},function(A,e,r,i){var t;if(A|=0,e|=0,r|=0,i|=0,t=Y-32|0,Y=t,a[t+28>>2]=A,a[t+24>>2]=e,a[t+20>>2]=r,a[t+16>>2]=i,A=a[t+28>>2],1&fA(A,a[a[t+24>>2]+8>>2],0))nA(A,a[t+24>>2],a[t+20>>2],a[t+16>>2]);else if(a[t+12>>2]=(A+16|0)+(a[A+12>>2]<<3),a[t+8>>2]=A+16,aA(a[t+8>>2],a[t+24>>2],a[t+20>>2],a[t+16>>2]),A=a[t+8>>2]+8|0,a[t+8>>2]=A,A>>>0>2])for(;aA(a[t+8>>2],a[t+24>>2],a[t+20>>2],a[t+16>>2]),!(1&f[a[t+24>>2]+54|0])&&(A=a[t+8>>2]+8|0,a[t+8>>2]=A,A>>>0>2]););Y=t+32|0},sA,kA,function(){z(),p()},sA,kA,function(A,e){A|=0,e|=0;var r=0;return A=0|Qt[a[742]](3+(A+e|0)|0),A&&(r=3+(A+e|0)&0-e,a[r+-4>>2]=A),0|r},function(A){A|=0,A&&Qt[a[743]](a[A+-4>>2])},function(A){return A|=0,0|K(A)},function(A){A|=0,L(A)},sA,kA,function(A,e,r){A|=0,e|=0,r|=0;var i,f=0,t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0);i=Y-96|0,Y=i,f=i+44|0,a[f>>2]=0,a[f+4>>2]=0,f=i+56|0,a[f>>2]=0,a[f+4>>2]=0,a[i+52>>2]=1065353216,f=i+76|0,a[f>>2]=0,a[f+4>>2]=0,a[i+72>>2]=1065353216,f=i+84|0,a[f>>2]=0,a[f+4>>2]=0,a[i+92>>2]=0,a[i+36>>2]=0,a[i+40>>2]=0,a[i+32>>2]=1065353216,a[i+64>>2]=0,a[i+68>>2]=0,Qt[a[a[A>>2]+8>>2]](A,i+32|0,i+16|0,i),c=C[i>>2],b=C[i+16>>2],t=_(c-b),o=_(t*t),t=C[i+4>>2],l=C[i+20>>2],n=_(t-l),s=_(o+_(n*n)),n=C[i+8>>2],o=C[i+24>>2],u=_(n-o),C[r>>2]=_(y(_(s+_(u*u))))*_(.5),a[e+12>>2]=0,C[e+8>>2]=_(n+o)*_(.5),C[e+4>>2]=_(t+l)*_(.5),C[e>>2]=_(c+b)*_(.5),Y=i+96|0},function(A){A|=0;var e,r=_(0),i=_(0);return e=Y-32|0,Y=e,Qt[a[a[A>>2]+12>>2]](A,e+16|0,e+12|0),Y=e+32|0,r=C[e+16>>2],i=_(r*r),r=C[e+20>>2],i=_(i+_(r*r)),r=C[e+24>>2],_(_(C[e+12>>2]+_(y(_(i+_(r*r))))))},function(A,e){return A|=0,e=_(e),_(_(_(Qt[a[a[A>>2]+16>>2]](A))*e))},function(A,e){A|=0,a[A+8>>2]=1065353216,a[A+12>>2]=0,a[A>>2]=1065353216,a[A+4>>2]=1065353216},yA,QA,function(A,e){A|=0,e|=0;var r,i=0,f=0,t=0,n=0,o=0;t=e,n=0|Qt[a[a[A>>2]+52>>2]](A),o=1,f=a[a[e>>2]+16>>2],i=0|Qt[f](0|t,0|n,0|o),o=e,n=i,t=0|Qt[a[a[A>>2]+56>>2]](A,a[i+8>>2],e),r=A,f=a[a[e>>2]+20>>2],Qt[f](0|o,0|n,0|t,1346455635,0|r)},function(A,e,r,i,f,t,n){A|=0,e|=0,r|=0,i|=0,f|=0,t|=0,n|=0;var o,c,b,l,u,s,k,v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0),U=_(0),M=_(0),S=_(0),X=_(0),T=_(0),j=_(0),O=_(0),H=_(0);o=Y-48|0,Y=o,a[o+44>>2]=0,v=C[r>>2],d=C[r+4>>2],g=C[r+8>>2],C[o+32>>2]=_(_(C[e>>2]*v)+_(C[e+16>>2]*d))+_(C[e+32>>2]*g),c=e+24|0,b=e+40|0,C[o+40>>2]=_(_(v*C[e+8>>2])+_(d*C[c>>2]))+_(g*C[b>>2]),l=e+20|0,u=e+36|0,C[o+36>>2]=_(_(v*C[e+4>>2])+_(d*C[l>>2]))+_(g*C[u>>2]),Qt[a[a[A>>2]+64>>2]](o+16|0,A,o+32|0),s=e+56|0,G=C[s>>2],y=C[b>>2],p=C[u>>2],k=e+52|0,Q=C[k>>2],F=C[c>>2],W=C[l>>2],w=C[e+32>>2],h=C[e+48>>2],D=C[e+8>>2],E=C[e>>2],Z=C[e+4>>2],V=C[e+16>>2],v=C[o+24>>2],d=C[o+16>>2],g=C[o+20>>2],a[o+12>>2]=0,C[o+8>>2]=-C[o+40>>2],C[o+4>>2]=-C[o+36>>2],C[o>>2]=-C[o+32>>2],Qt[a[a[A>>2]+64>>2]](o+16|0,A,o),N=C[s>>2],I=C[b>>2],J=C[u>>2],x=C[k>>2],U=C[c>>2],M=C[l>>2],S=C[e+32>>2],X=C[e+48>>2],T=C[e+8>>2],j=C[e>>2],O=C[e+4>>2],H=C[e+16>>2],B=C[o+24>>2],m=C[o+16>>2],R=C[o+20>>2],h=_(h+_(_(_(d*E)+_(g*Z))+_(v*D))),Q=_(Q+_(_(_(d*V)+_(g*W))+_(v*F))),v=_(G+_(_(_(d*w)+_(g*p))+_(v*y))),C[i>>2]=_(_(h*C[r>>2])+_(Q*C[r+4>>2]))+_(v*C[r+8>>2]),d=_(X+_(_(_(m*j)+_(R*O))+_(B*T))),g=_(x+_(_(_(m*H)+_(R*M))+_(B*U))),B=_(N+_(_(_(m*S)+_(R*J))+_(B*I))),C[f>>2]=_(_(d*C[r>>2])+_(g*C[r+4>>2]))+_(B*C[r+8>>2]),a[n+12>>2]=0,C[n+8>>2]=B,C[n+4>>2]=g,C[n>>2]=d,a[t+12>>2]=0,C[t+8>>2]=v,C[t+4>>2]=Q,C[t>>2]=h,m=C[i>>2],R=C[f>>2],m>R&&(C[i>>2]=R,C[f>>2]=m,a[n+12>>2]=0,C[n+8>>2]=v,C[n+4>>2]=Q,C[n>>2]=h,a[t+12>>2]=0,C[t+8>>2]=B,C[t+4>>2]=g,C[t>>2]=d),Y=o+48|0},pA,function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f,t,n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),R=_(0),Q=_(0),h=_(0);f=Y-16|0,a[f+12>>2]=0,t=A+32|0,A=a[A+56>>2],o=C[t+((A+2|0)%3<<2)>>2],C[f+8>>2]=o,C[f+4>>2]=o,C[f>>2]=o,A<<=2,C[A+f>>2]=o+C[A+t>>2],o=C[e+56>>2],v=C[e+40>>2],d=C[e+36>>2],s=C[e+52>>2],l=C[e+24>>2],g=C[e+20>>2],B=C[e+32>>2],R=C[e+16>>2],k=C[e+48>>2],c=C[e+8>>2],n=C[e>>2],b=C[e+4>>2],a[r+12>>2]=0,u=_(m(n)),n=C[f>>2],Q=_(m(b)),b=C[f+4>>2],h=_(m(c)),c=C[f+8>>2],u=_(_(_(u*n)+_(Q*b))+_(h*c)),C[r>>2]=k-u,l=_(_(_(n*_(m(R)))+_(b*_(m(g))))+_(c*_(m(l)))),C[r+4>>2]=s-l,n=_(_(_(n*_(m(B)))+_(b*_(m(d))))+_(c*_(m(v)))),C[r+8>>2]=o-n,C[i>>2]=k+u,C[i+4>>2]=s+l,C[i+8>>2]=o+n,a[i+12>>2]=0},function(A,e){A|=0,e|=0;var r,i,f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0);f=C[A+20>>2],r=A+36|0,t=C[r>>2],n=C[A+24>>2],i=A+40|0,o=C[i>>2],c=C[A+16>>2],b=C[A+32>>2],EA(A,e),l=C[e>>2],u=C[e+4>>2],s=C[e+8>>2],a[A+44>>2]=0,C[i>>2]=s*_(o/n),C[r>>2]=u*_(t/f),C[A+32>>2]=l*_(b/c),a[A+48>>2]=a[(A+32|0)+((a[A+56>>2]+2|0)%3<<2)>>2]},Qe,function(A,e,r){A|=0,e=_(e),r|=0;var i,f=_(0),t=_(0),n=0,o=0,c=_(0);i=A+32|0,o=a[A+56>>2],n=a[i+((o+2|0)%3<<2)>>2],A=Y-16|0,a[A+12>>2]=0,a[A+8>>2]=n,a[A+4>>2]=n,a[A>>2]=n,n=o<<2,o=n+A|0,C[o>>2]=C[n+i>>2]+C[o>>2],e=_(e*_(.0833333283662796)),f=C[A>>2],f=_(f+f),f=_(f*f),t=C[A+4>>2],t=_(t+t),t=_(t*t),C[r+8>>2]=e*_(f+t),c=f,f=C[A+8>>2],f=_(f+f),f=_(f*f),C[r+4>>2]=e*_(c+f),C[r>>2]=e*_(t+f)},function(A){return 6444},FA,WA,function(A){return A|=0,_(C[A+48>>2])},wA,function(A,e,r){return A|=0,e|=0,r|=0,QA(A,e,r),a[e+28>>2]=a[A+32>>2],a[e+32>>2]=a[A+36>>2],a[e+36>>2]=a[A+40>>2],a[e+40>>2]=a[A+44>>2],a[e+12>>2]=a[A+16>>2],a[e+16>>2]=a[A+20>>2],a[e+20>>2]=a[A+24>>2],a[e+24>>2]=a[A+28>>2],a[e+48>>2]=0,a[e+44>>2]=a[A+48>>2],A=a[A+56>>2],a[e+56>>2]=0,a[e+52>>2]=A,6457},function(A,e,r){A|=0,e|=0,r|=0;var i=_(0),f=_(0),t=_(0),n=_(0),o=_(0);Qt[a[a[e>>2]+68>>2]](A,e,r),_(Qt[a[a[e>>2]+48>>2]](e))!=_(0)&&(f=C[r+4>>2],i=C[r>>2],t=C[r+8>>2],n=_(Qt[a[a[e>>2]+48>>2]](e)),e=_(_(_(i*i)+_(f*f))+_(t*t))<_(1.4210854715202004e-14),i=e?_(-1):i,o=i,t=e?_(-1):t,f=e?_(-1):f,i=_(_(1)/_(y(_(_(t*t)+_(_(i*i)+_(f*f)))))),C[A>>2]=C[A>>2]+_(n*_(o*i)),C[A+4>>2]=C[A+4>>2]+_(n*_(f*i)),C[A+8>>2]=C[A+8>>2]+_(n*_(t*i)))},function(A,e,r){A|=0,e|=0,r|=0;var i,f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=0,l=_(0),u=_(0),s=_(0),k=_(0);i=Y-16|0,a[A>>2]=0,a[A+4>>2]=0,b=A+8|0,a[b>>2]=0,a[b+4>>2]=0,o=C[r>>2],n=C[r+4>>2],t=C[r+8>>2],f=_(_(_(o*o)+_(n*n))+_(t*t)),f<_(9999999747378752e-20)?(t=_(0),f=_(1)):(f=_(_(1)/_(y(f))),l=_(t*f),t=_(n*f),f=_(o*f)),a[i+8>>2]=0,a[i+12>>2]=0,a[i>>2]=0,a[i+4>>2]=0,r=a[e+56>>2]<<2,b=r+i|0,c=C[32+(e+r|0)>>2],C[b>>2]=c,o=_(-0xde0b6b000000000),u=C[i>>2],s=C[i+4>>2],k=C[i+8>>2],n=_(_(_(f*u)+_(t*s))+_(l*k)),n>_(-0xde0b6b000000000)&&(a[A+12>>2]=a[i+12>>2],C[A+8>>2]=k,C[A+4>>2]=s,C[A>>2]=u,o=n),a[i+8>>2]=0,a[i+12>>2]=0,a[i>>2]=0,a[i+4>>2]=0,C[b>>2]=-c,n=C[i>>2],c=t,t=C[i+4>>2],c=_(_(f*n)+_(c*t)),f=C[i+8>>2],_(c+_(l*f))>o&&(a[A+12>>2]=a[i+12>>2],C[A+8>>2]=f,C[A+4>>2]=t,C[A>>2]=n)},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f,t=0,n=0,o=0,c=_(0),b=_(0),l=_(0),u=_(0),s=0,k=0,v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=0;if(f=Y-16|0,(0|i)>=1)for(;t=f+8|0,a[t>>2]=0,a[t+4>>2]=0,a[f>>2]=0,a[f+4>>2]=0,o=a[A+56>>2],n=o<<2,s=n+f|0,n=32+(A+n|0)|0,b=C[n>>2],a[s>>2]=a[n>>2],d=_(-0xde0b6b000000000),g=C[f>>2],n=e+k|0,c=C[n>>2],B=C[f+4>>2],s=n+4|0,l=C[s>>2],m=C[t>>2],R=n+8|0,v=C[R>>2],u=_(_(_(g*c)+_(B*l))+_(m*v)),u>_(-0xde0b6b000000000)&&(o=r+k|0,C[o>>2]=g,a[o+12>>2]=a[f+12>>2],C[o+8>>2]=m,C[o+4>>2]=B,v=C[R>>2],l=C[s>>2],o=a[A+56>>2],b=C[32+((o<<2)+A|0)>>2],c=C[n>>2],d=u),a[t>>2]=0,a[t+4>>2]=0,a[f>>2]=0,a[f+4>>2]=0,C[(o<<2)+f>>2]=-b,b=C[f>>2],u=C[f+4>>2],l=_(_(b*c)+_(u*l)),c=C[t>>2],_(l+_(c*v))>d&&(t=r+k|0,C[t>>2]=b,a[t+12>>2]=a[f+12>>2],C[t+8>>2]=c,C[t+4>>2]=u),k=k+16|0,i=i+-1|0,i;);},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f,t,n=_(0),o=_(0),c=_(0),b=0,l=0,u=_(0);for(f=Y-80|0,Y=f,u=_(Qt[a[a[A>>2]+48>>2]](A)),t=f+72|0;a[t>>2]=0,a[t+4>>2]=0,a[f+64>>2]=0,a[f+68>>2]=0,l=(f- -64|0)+b|0,a[l>>2]=1065353216,a[f+44>>2]=0,n=C[f+64>>2],o=C[f+68>>2],c=C[t>>2],C[f+40>>2]=_(_(n*C[e+8>>2])+_(o*C[e+24>>2]))+_(c*C[e+40>>2]),C[f+36>>2]=_(_(n*C[e+4>>2])+_(o*C[e+20>>2]))+_(c*C[e+36>>2]),C[f+32>>2]=_(_(n*C[e>>2])+_(o*C[e+16>>2]))+_(c*C[e+32>>2]),Qt[a[a[A>>2]+64>>2]](f+48|0,A,f+32|0),a[f+44>>2]=0,n=C[f+48>>2],o=C[f+52>>2],c=C[f+56>>2],C[f+40>>2]=_(_(_(n*C[e+32>>2])+_(o*C[e+36>>2]))+_(c*C[e+40>>2]))+C[e+56>>2],C[f+36>>2]=_(_(_(n*C[e+16>>2])+_(o*C[e+20>>2]))+_(c*C[e+24>>2]))+C[e+52>>2],C[f+32>>2]=_(_(_(n*C[e>>2])+_(o*C[e+4>>2]))+_(c*C[e+8>>2]))+C[e+48>>2],a[l>>2]=-1082130432,l=(f+32|0)+b|0,C[i+b>>2]=u+C[l>>2],a[f+12>>2]=0,n=C[f+64>>2],o=C[f+68>>2],c=C[t>>2],C[f+8>>2]=_(_(n*C[e+8>>2])+_(o*C[e+24>>2]))+_(c*C[e+40>>2]),C[f+4>>2]=_(_(n*C[e+4>>2])+_(o*C[e+20>>2]))+_(c*C[e+36>>2]),C[f>>2]=_(_(n*C[e>>2])+_(o*C[e+16>>2]))+_(c*C[e+32>>2]),Qt[a[a[A>>2]+64>>2]](f+16|0,A,f),a[f+44>>2]=0,n=C[f+16>>2],o=C[f+20>>2],c=C[f+24>>2],C[f+40>>2]=_(_(_(n*C[e+32>>2])+_(o*C[e+36>>2]))+_(c*C[e+40>>2]))+C[e+56>>2],C[f+36>>2]=_(_(_(n*C[e+16>>2])+_(o*C[e+20>>2]))+_(c*C[e+24>>2]))+C[e+52>>2],C[f+32>>2]=_(_(_(n*C[e>>2])+_(o*C[e+4>>2]))+_(c*C[e+8>>2]))+C[e+48>>2],C[r+b>>2]=C[l>>2]-u,b=b+4|0,12!=(0|b););Y=f+80|0},we,De,pA,function(A){return 6476},pA,function(A){return 6485},pA,$A,function(A,e){A|=0,e|=0;var r,i=0,f=_(0),t=_(0);i=a[A+72>>2]<<2,r=A+16|0,t=_(C[A+64>>2]*_(C[i+e>>2]/C[i+r>>2])),C[A+64>>2]=t,i=a[A+68>>2]<<2,f=_(C[i+e>>2]/C[i+r>>2]),i=a[A+76>>2]<<2,f=_(C[A+60>>2]*_(_(f+_(C[i+e>>2]/C[i+r>>2]))*_(.5))),C[A+60>>2]=f,C[A+56>>2]=f/_(y(_(_(t*t)+_(f*f)))),EA(A,e)},function(A,e,r){A|=0,e=_(e),r|=0;var i,f=_(0),t=0,n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0);i=Y-96|0,Y=i,t=i+44|0,a[t>>2]=0,a[t+4>>2]=0,t=i+56|0,a[t>>2]=0,a[t+4>>2]=0,a[i+52>>2]=1065353216,t=i+76|0,a[t>>2]=0,a[t+4>>2]=0,a[i+72>>2]=1065353216,t=i+84|0,a[t>>2]=0,a[t+4>>2]=0,a[i+92>>2]=0,a[i+36>>2]=0,a[i+40>>2]=0,a[i+32>>2]=1065353216,a[i+64>>2]=0,a[i+68>>2]=0,Qt[a[a[A>>2]+8>>2]](A,i+32|0,i+16|0,i),c=C[i+24>>2],b=C[i+8>>2],n=C[i+16>>2],o=C[i>>2],l=C[i+20>>2],u=C[i+4>>2],f=_(Qt[a[a[A>>2]+48>>2]](A)),a[r+12>>2]=0,e=_(e*_(.0833333283662796)),n=_(f+_(_(o-n)*_(.5))),n=_(n+n),n=_(n*n),o=_(f+_(_(u-l)*_(.5))),o=_(o+o),o=_(o*o),C[r+8>>2]=e*_(n+o),f=_(f+_(_(b-c)*_(.5))),f=_(f+f),f=_(f*f),C[r+4>>2]=e*_(n+f),C[r>>2]=e*_(o+f),Y=i+96|0},function(A){return 6880},function(A,e){A|=0,a[A+8>>2]=0,a[A+12>>2]=0,a[A>>2]=0,a[A+4>>2]=1065353216},Ge,wA,function(A,e,r){return A|=0,e|=0,r|=0,QA(A,e,r),a[e+28>>2]=a[A+32>>2],a[e+32>>2]=a[A+36>>2],a[e+36>>2]=a[A+40>>2],a[e+40>>2]=a[A+44>>2],a[e+12>>2]=a[A+16>>2],a[e+16>>2]=a[A+20>>2],a[e+20>>2]=a[A+24>>2],a[e+24>>2]=a[A+28>>2],a[e+48>>2]=0,a[e+44>>2]=a[A+48>>2],A=a[A+72>>2],a[e+56>>2]=0,a[e+52>>2]=A,6885},function(A,e,r){A|=0,e|=0,r|=0;var i,f,t=_(0),n=_(0),o=_(0),c=_(0),b=0,l=_(0);n=_(C[e+64>>2]*_(.5)),i=a[e+68>>2],f=a[e+72>>2],b=f<<2,t=C[r>>2],c=_(t*t),t=C[r+4>>2],c=_(c+_(t*t)),t=C[r+8>>2];A:{if(C[b+r>>2]>_(C[e+56>>2]*_(y(_(c+_(t*t))))))a[(i<<2)+A>>2]=0,C[A+b>>2]=n,b=a[e+76>>2];else{if(t=C[(i<<2)+r>>2],b=a[e+76>>2],o=C[(b<<2)+r>>2],l=_(y(_(_(t*t)+_(o*o)))),l>_(1.1920928955078125e-7)){c=t,t=_(C[e+60>>2]/l),C[(i<<2)+A>>2]=c*t,C[(f<<2)+A>>2]=-n,n=_(o*t);break A}a[(i<<2)+A>>2]=0,C[(f<<2)+A>>2]=-n}n=_(0)}C[(b<<2)+A>>2]=n,_(Qt[a[a[e>>2]+48>>2]](e))!=_(0)&&(n=C[r+4>>2],t=C[r>>2],o=C[r+8>>2],l=_(Qt[a[a[e>>2]+48>>2]](e)),e=_(_(_(t*t)+_(n*n))+_(o*o))<_(1.4210854715202004e-14),t=e?_(-1):t,c=t,o=e?_(-1):o,n=e?_(-1):n,t=_(_(1)/_(y(_(_(o*o)+_(_(t*t)+_(n*n)))))),C[A>>2]=C[A>>2]+_(l*_(c*t)),C[A+4>>2]=C[A+4>>2]+_(l*_(n*t)),C[A+8>>2]=C[A+8>>2]+_(l*_(o*t)))},function(A,e,r){A|=0,e|=0,r|=0;var i,f,t=_(0),n=_(0),o=_(0),c=0,b=_(0),l=_(0);n=_(C[e+64>>2]*_(.5)),i=a[e+68>>2],f=a[e+72>>2],c=f<<2,t=C[r>>2],o=_(t*t),t=C[r+4>>2],o=_(o+_(t*t)),t=C[r+8>>2];A:{if(C[c+r>>2]>_(C[e+56>>2]*_(y(_(o+_(t*t))))))a[(i<<2)+A>>2]=0,C[A+c>>2]=n,r=a[e+76>>2];else{if(t=C[(i<<2)+r>>2],c=r,r=a[e+76>>2],b=C[c+(r<<2)>>2],l=_(y(_(_(t*t)+_(b*b)))),l>_(1.1920928955078125e-7)){o=t,t=_(C[e+60>>2]/l),C[(i<<2)+A>>2]=o*t,C[(f<<2)+A>>2]=-n,n=_(b*t);break A}a[(i<<2)+A>>2]=0,C[(f<<2)+A>>2]=-n}n=_(0)}C[(r<<2)+A>>2]=n},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f,t=_(0),n=0,o=0,c=_(0),b=_(0),l=0,u=_(0),s=_(0);if(f=Y-16|0,(0|i)>=1)for(;;){c=_(C[A+64>>2]*_(.5)),n=a[A+68>>2],o=a[A+72>>2]<<2,t=C[e>>2],b=_(t*t),t=C[e+4>>2],b=_(b+_(t*t)),t=C[e+8>>2];A:{if(C[o+e>>2]>_(C[A+56>>2]*_(y(_(b+_(t*t))))))a[(n<<2)+f>>2]=0,C[f+o>>2]=c,n=a[A+76>>2];else{if(l=n<<2,t=C[l+e>>2],n=a[A+76>>2],u=C[(n<<2)+e>>2],s=_(y(_(_(t*t)+_(u*u)))),s>_(1.1920928955078125e-7)){b=t,t=_(C[A+60>>2]/s),C[f+l>>2]=b*t,C[f+o>>2]=-c,c=_(u*t);break A}a[f+l>>2]=0,C[f+o>>2]=-c}c=_(0)}if(C[(n<<2)+f>>2]=c,n=f+8|0,l=a[n+4>>2],o=r+8|0,a[o>>2]=a[n>>2],a[o+4>>2]=l,o=a[f+4>>2],a[r>>2]=a[f>>2],a[r+4>>2]=o,e=e+16|0,r=r+16|0,i=i+-1|0,!i)break}},pA,function(A){return 6901},function(A,e){A|=0,a[A+8>>2]=1065353216,a[A+12>>2]=0,a[A>>2]=0,a[A+4>>2]=0},pA,function(A){return 6907},function(A,e){A|=0,a[A+8>>2]=0,a[A+12>>2]=0,a[A>>2]=1065353216,a[A+4>>2]=0},kA,EA,ye,function(A,e,r){return A|=0,e|=0,r|=0,QA(A,e,r),a[e+28>>2]=a[A+32>>2],a[e+32>>2]=a[A+36>>2],a[e+36>>2]=a[A+40>>2],a[e+40>>2]=a[A+44>>2],a[e+12>>2]=a[A+16>>2],a[e+16>>2]=a[A+20>>2],a[e+20>>2]=a[A+24>>2],a[e+24>>2]=a[A+28>>2],a[e+48>>2]=0,a[e+44>>2]=a[A+48>>2],8329},ZA,function(A){A|=0,CA(ZA(A))},Ae,kA,function(A,e,r){A|=0,e=_(e),r|=0;var i,f=_(0),t=0,n=_(0),o=_(0);i=Y-96|0,Y=i,f=_(Qt[a[a[A>>2]+48>>2]](A)),t=i+44|0,a[t>>2]=0,a[t+4>>2]=0,t=i+56|0,a[t>>2]=0,a[t+4>>2]=0,a[i+52>>2]=1065353216,t=i+76|0,a[t>>2]=0,a[t+4>>2]=0,a[i+72>>2]=1065353216,t=i+84|0,a[t>>2]=0,a[t+4>>2]=0,a[i+92>>2]=0,a[i+36>>2]=0,a[i+40>>2]=0,a[i+32>>2]=1065353216,a[i+64>>2]=0,a[i+68>>2]=0,Qt[a[a[A>>2]+8>>2]](A,i+32|0,i+16|0,i),a[r+12>>2]=0,e=_(e*_(.0833333283662796)),n=_(f+_(_(C[i>>2]-C[i+16>>2])*_(.5))),n=_(n+n),n=_(n*n),o=_(f+_(_(C[i+4>>2]-C[i+20>>2])*_(.5))),o=_(o+o),o=_(o*o),C[r+8>>2]=e*_(n+o),f=_(f+_(_(C[i+8>>2]-C[i+24>>2])*_(.5))),f=_(f+f),f=_(f*f),C[r+4>>2]=e*_(n+f),C[r>>2]=e*_(o+f),Y=i+96|0},function(A,e,r){A|=0,e|=0,r|=0;var i,f=0,t=_(0),n=_(0),o=0,c=_(0),b=_(0),l=0,u=0,s=0,k=_(0),v=_(0);if(i=Y-2048|0,Y=i,a[A>>2]=0,a[A+4>>2]=0,f=A+8|0,a[f>>2]=0,a[f+4>>2]=0,c=C[r>>2],b=C[r+4>>2],t=C[r+8>>2],n=_(_(_(c*c)+_(b*b))+_(t*t)),n<_(9999999747378752e-20)?c=_(1):(n=_(_(1)/_(y(n))),k=_(t*n),v=_(b*n),c=_(c*n)),(0|Qt[a[a[e>>2]+96>>2]](e))>=1)for(n=_(-0xde0b6b000000000);;){if(l=128,((0|Qt[a[a[e>>2]+96>>2]](e))-u|0)>127||(l=(0|Qt[a[a[e>>2]+96>>2]](e))-u|0,(0|l)>=1)){for(r=0,f=i;Qt[a[a[e>>2]+108>>2]](e,r,f),f=f+16|0,r=r+1|0,(0|l)!=(0|r););for(f=0,s=-1,t=_(-3.4028234663852886e38),r=i;b=_(_(_(c*C[r>>2])+_(v*C[r+4>>2]))+_(k*C[r+8>>2])),o=b>t,t=o?b:t,s=o?f:s,r=r+16|0,f=f+1|0,(0|f)!=(0|l););}else t=_(-3.4028234663852886e38),s=-1;if(t>n&&(o=(s<<4)+i|0,r=a[o+12>>2],f=A+8|0,a[f>>2]=a[o+8>>2],a[f+4>>2]=r,r=a[o+4>>2],a[A>>2]=a[o>>2],a[A+4>>2]=r,n=t),u=u+128|0,!((0|u)<(0|Qt[a[a[e>>2]+96>>2]](e))))break}Y=i+2048|0},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f,t=0,n=0,o=_(0),c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=_(0),g=0,B=0,m=0,R=_(0),Q=_(0),h=_(0);if(f=Y-2048|0,Y=f,!((0|i)<1)){for(n=r+12|0,t=i;a[n>>2]=-581039253,n=n+16|0,t=t+-1|0,t;);if(!((0|i)<1))for(;;){if((0|Qt[a[a[A>>2]+96>>2]](A))>=1)for(t=s<<4,l=t+r|0,v=l+12|0,k=e+t|0,B=k+8|0,m=k+4|0,b=0;;){if(u=128,((0|Qt[a[a[A>>2]+96>>2]](A))-b|0)>127||(u=(0|Qt[a[a[A>>2]+96>>2]](A))-b|0,(0|u)>=1)){for(n=0,t=f;Qt[a[a[A>>2]+108>>2]](A,n,t),t=t+16|0,n=n+1|0,(0|u)!=(0|n););for(R=C[B>>2],Q=C[m>>2],h=C[k>>2],t=0,c=-1,o=_(-3.4028234663852886e38),n=f;d=_(_(_(h*C[n>>2])+_(Q*C[n+4>>2]))+_(R*C[n+8>>2])),g=d>o,o=g?d:o,c=g?t:c,n=n+16|0,t=t+1|0,(0|u)!=(0|t););}else o=_(-3.4028234663852886e38),c=-1;if(o>C[v>>2]&&(t=(c<<4)+f|0,c=a[t+12>>2],n=l+8|0,a[n>>2]=a[t+8>>2],a[n+4>>2]=c,n=a[t+4>>2],a[l>>2]=a[t>>2],a[l+4>>2]=n,C[v>>2]=o),b=b+128|0,!((0|b)<(0|Qt[a[a[A>>2]+96>>2]](A))))break}if(s=s+1|0,(0|s)==(0|i))break}}Y=f+2048|0},function(A,e){A|=0,e|=0;var r,i,t=0,n=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=_(0),g=_(0),R=_(0),Q=0,h=0,G=0,p=0,F=_(0),W=_(0),w=0,D=0,E=0,Z=0,V=0,N=0,I=0,J=_(0),x=0,U=0,M=_(0),S=_(0),T=0,j=0;r=Y-240|0,Y=r,t=a[A+56>>2],t&&(Qt[a[a[t>>2]>>2]](t),CA(a[A+56>>2])),t=dA(132),function(A){var e=0;a[A>>2]=7060,f[A+20|0]=1,a[A+16>>2]=0,f[A+40|0]=1,e=A+8|0,a[e>>2]=0,a[e+4>>2]=0,a[A+36>>2]=0,f[A+60|0]=1,e=A+28|0,a[e>>2]=0,a[e+4>>2]=0,a[A+56>>2]=0,A=A+48|0,a[A>>2]=0,a[A+4>>2]=0}(t),a[A+56>>2]=t,a[r+228>>2]=0,a[r+220>>2]=0,a[r+224>>2]=0,f[r+232|0]=1;A:if(!((0|Qt[a[a[A>>2]+96>>2]](A))<1))for(;;){if((0|c)==(0|u))if(k=c?c<<1:1,(0|c)>=(0|k))b=v;else{b=k?dA(k<<4):0;e:{if((0|c)>=1)for(t=b,n=v;s=a[n+4>>2],a[t>>2]=a[n>>2],a[t+4>>2]=s,Q=n+8|0,p=a[Q+4>>2],s=t+8|0,a[s>>2]=a[Q>>2],a[s+4>>2]=p,t=t+16|0,n=n+16|0,c=c+-1|0,c;);else if(!v)break e;o[r+232|0]&&CA(v),a[r+228>>2]=0}a[r+228>>2]=b,f[r+232|0]=1,a[r+224>>2]=k}else b=v;if(a[r+220>>2]=u+1,c=a[r+156>>2],t=u<<4,n=t+b|0,a[n>>2]=a[r+152>>2],a[n+4>>2]=c,b=r+160|0,c=a[b+4>>2],n=n+8|0,a[n>>2]=a[b>>2],a[n+4>>2]=c,v=a[r+228>>2],Qt[a[a[A>>2]+108>>2]](A,l,t+v|0),l=l+1|0,(0|l)>=(0|Qt[a[a[A>>2]+96>>2]](A)))break A;c=a[r+224>>2],u=a[r+220>>2]}if(f[r+188|0]=1,a[r+184>>2]=0,f[r+208|0]=1,t=r+176|0,a[t>>2]=0,a[t+4>>2]=0,a[r+204>>2]=0,t=r+196|0,a[t>>2]=0,a[t+4>>2]=0,a[r+164>>2]=0,f[r+168|0]=1,a[r+156>>2]=0,a[r+160>>2]=0,e){if(a[r+60>>2]=0,f[r+64|0]=1,a[r+52>>2]=0,a[r+56>>2]=0,function(A,e){var r,i=0,t=0,n=_(0),c=0,b=0,l=0,u=_(0),s=_(0),k=_(0),v=0,d=0,g=_(0),B=_(0),m=0,R=0,Q=0,h=0,G=_(0),p=_(0),F=0,W=0,w=_(0),D=_(0),E=_(0),Z=0,Y=0,V=0,N=0;if(r=a[A+4>>2],(0|r)>=1)for(;;){A:if(d=R,R=d+1|0,!((0|R)>=(0|r)))for(t=a[A+12>>2],Q=t+(d<<4)|0,Z=Q+8|0,Y=Q+4|0,i=R;;){e:if(d=i+1|0,!((0|d)>=(0|r)))for(W=(i<<4)+t|0,V=W+8|0,N=W+4|0,h=d;;){w=C[Q>>2],u=_(C[W>>2]-w),i=(h<<4)+t|0,D=C[Y>>2],g=_(C[i+4>>2]-D),n=_(C[N>>2]-D),s=_(C[i>>2]-w),G=_(_(u*g)-_(n*s)),E=C[Z>>2],k=_(C[i+8>>2]-E),B=_(n*k),n=_(C[V>>2]-E),g=_(B-_(n*g)),s=_(_(n*s)-_(u*k)),k=_(_(G*G)+_(_(g*g)+_(s*s))),m=k>_(9999999747378752e-20)^1;r:if(!m){if(n=_(_(1)/_(y(k))),B=_(G*n),p=_(s*n),u=_(g*n),b=a[e+4>>2],(0|b)>=1)for(i=a[e+12>>2],c=b;;){if(_(_(_(u*C[i>>2])+_(p*C[i+4>>2]))+_(B*C[i+8>>2]))>_(.9990000128746033))break r;if(i=i+16|0,c=c+-1|0,!c)break}if(n=_(_(_(u*w)+_(p*D))+_(B*E)),i=a[A+4>>2],(0|i)>=1)for(;;){if(_(_(_(_(_(u*C[t>>2])+_(p*C[t+4>>2]))+_(B*C[t+8>>2]))-n)+_(-.009999999776482582))>_(0))break r;if(t=t+16|0,i=i+-1|0,!i)break}if(n=_(-n),a[e+8>>2]==(0|b)&&(F=b?b<<1:1,!((0|b)>=(0|F)))){if(F?(v=dA(F<<4),b=a[e+4>>2]):v=0,(0|b)>=1)for(i=0;t=a[e+12>>2]+i|0,c=a[t+4>>2],l=i+v|0,a[l>>2]=a[t>>2],a[l+4>>2]=c,t=t+8|0,c=a[t+4>>2],l=l+8|0,a[l>>2]=a[t>>2],a[l+4>>2]=c,i=i+16|0,b=b+-1|0,b;);i=a[e+12>>2],i&&(o[e+16|0]&&CA(i),a[e+12>>2]=0),a[e+12>>2]=v,f[e+16|0]=1,a[e+8>>2]=F,b=a[e+4>>2]}i=a[e+12>>2]+(b<<4)|0,C[i+12>>2]=n,C[i+8>>2]=B,C[i+4>>2]=p,C[i>>2]=u,a[e+4>>2]=a[e+4>>2]+1}r:if(!m){if(n=_(_(1)/_(y(k))),u=_(-_(G*n)),s=_(-_(s*n)),k=_(-_(g*n)),c=a[e+4>>2],(0|c)>=1)for(i=a[e+12>>2],t=c;;){if(_(_(_(C[i>>2]*k)+_(C[i+4>>2]*s))+_(C[i+8>>2]*u))>_(.9990000128746033))break r;if(i=i+16|0,t=t+-1|0,!t)break}if(n=_(_(_(C[Q>>2]*k)+_(C[Y>>2]*s))+_(C[Z>>2]*u)),t=a[A+4>>2],(0|t)>=1)for(i=a[A+12>>2];;){if(_(_(_(_(_(C[i>>2]*k)+_(C[i+4>>2]*s))+_(C[i+8>>2]*u))-n)+_(-.009999999776482582))>_(0))break r;if(i=i+16|0,t=t+-1|0,!t)break}if(n=_(-n),a[e+8>>2]==(0|c)&&(v=c?c<<1:1,!((0|c)>=(0|v)))){if(v?(m=dA(v<<4),c=a[e+4>>2]):m=0,(0|c)>=1)for(i=0;t=a[e+12>>2]+i|0,b=a[t+4>>2],l=i+m|0,a[l>>2]=a[t>>2],a[l+4>>2]=b,t=t+8|0,b=a[t+4>>2],l=l+8|0,a[l>>2]=a[t>>2],a[l+4>>2]=b,i=i+16|0,c=c+-1|0,c;);i=a[e+12>>2],i&&(o[e+16|0]&&CA(i),a[e+12>>2]=0),a[e+12>>2]=m,f[e+16|0]=1,a[e+8>>2]=v,c=a[e+4>>2]}i=a[e+12>>2]+(c<<4)|0,C[i+12>>2]=n,C[i+8>>2]=u,C[i+4>>2]=s,C[i>>2]=k,a[e+4>>2]=a[e+4>>2]+1}if(h=h+1|0,(0|h)==(0|r))break e;t=a[A+12>>2]}if((0|r)==(0|d))break A;t=a[A+12>>2],i=d}if((0|r)==(0|R))break}}(r+216|0,r+48|0),a[r+140>>2]=0,f[r+144|0]=1,a[r+132>>2]=0,a[r+136>>2]=0,a[r+52>>2]>=1)for(b=0;;){if(u=r+112|0,e=a[r+60>>2]+(b<<4)|0,a[u>>2]=a[e+8>>2],t=a[e+4>>2],a[r+104>>2]=a[e>>2],a[r+108>>2]=t,d=_(C[e+12>>2]-_(Qt[a[a[A>>2]+48>>2]](A))),n=a[r+132>>2],(0|n)==a[r+136>>2]&&(e=n?n<<1:1,!((0|n)>=(0|e)))){if(e?(l=dA(e<<4),n=a[r+132>>2]):l=0,(0|n)>=1)for(t=0;c=a[r+140>>2]+t|0,v=a[c+4>>2],k=t+l|0,s=k,a[s>>2]=a[c>>2],a[s+4>>2]=v,c=c+8|0,s=a[c+4>>2],k=k+8|0,a[k>>2]=a[c>>2],a[k+4>>2]=s,t=t+16|0,n=n+-1|0,n;);t=a[r+140>>2],t&&(o[r+144|0]&&CA(t),a[r+140>>2]=0),a[r+140>>2]=l,f[r+144|0]=1,a[r+136>>2]=e,n=a[r+132>>2]}if(t=a[r+108>>2],e=a[r+140>>2]+(n<<4)|0,a[e>>2]=a[r+104>>2],a[e+4>>2]=t,C[e+12>>2]=d,a[e+8>>2]=a[u>>2],a[r+132>>2]=a[r+132>>2]+1,b=b+1|0,!((0|b)>2]))break}a[r+116>>2]=0,f[r+120|0]=1,a[r+108>>2]=0,a[r+112>>2]=0,function(A,e){var r,i=0,t=0,n=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=0,d=_(0),g=0,B=0,R=_(0),Q=_(0),h=0,G=0,y=0,p=0,F=_(0),W=_(0),w=0,D=_(0),E=_(0),Z=_(0),Y=0,V=0,N=0,I=0,J=0,x=0,U=0,M=0;if(r=a[A+4>>2],(0|r)>=1)for(;;){A:if(v=h,h=v+1|0,!((0|h)>=(0|r)))for(t=a[A+12>>2],G=t+(v<<4)|0,N=G+12|0,I=G+4|0,J=G+8|0,i=h;;){e:if(v=i+1|0,!((0|v)>=(0|r)))for(y=(i<<4)+t|0,x=y+12|0,U=y+8|0,M=y+4|0,p=v;;){i=(p<<4)+t|0,l=C[i+4>>2],u=C[y>>2],s=C[M>>2],c=C[i>>2],k=_(_(l*u)-_(s*c)),b=C[i+8>>2],n=C[U>>2],F=_(_(s*b)-_(n*l)),W=_(_(n*c)-_(b*u));r:if(_(_(k*k)+_(_(F*F)+_(W*W)))>_(9999999747378752e-20)&&(d=C[I>>2],R=C[G>>2],D=_(_(c*d)-_(l*R)),Q=C[J>>2],E=_(_(l*Q)-_(b*d)),Z=_(_(b*R)-_(c*Q)),_(_(D*D)+_(_(E*E)+_(Z*Z)))>_(9999999747378752e-20)&&(c=_(_(s*R)-_(u*d)),l=_(_(n*d)-_(s*Q)),b=_(_(u*Q)-_(n*R)),_(_(c*c)+_(_(l*l)+_(b*b)))>_(9999999747378752e-20)&&(n=_(_(Q*k)+_(_(d*W)+_(F*R))),_(m(n))>_(9.999999974752427e-7))))){if(u=_(_(-1)/n),s=C[i+12>>2],d=k,k=C[N>>2],n=C[x>>2],c=_(u*_(_(c*s)+_(_(d*k)+_(D*n)))),b=_(u*_(_(b*s)+_(_(W*k)+_(Z*n)))),n=_(u*_(_(l*s)+_(_(F*k)+_(E*n)))),i=a[A+4>>2],(0|i)>=1)for(;;){if(_(_(C[t+12>>2]+_(_(_(n*C[t>>2])+_(b*C[t+4>>2]))+_(c*C[t+8>>2])))+_(-.009999999776482582))>_(0))break r;if(t=t+16|0,i=i+-1|0,!i)break}if(i=a[e+4>>2],(0|i)==a[e+8>>2]&&(w=i?i<<1:1,!((0|i)>=(0|w)))){if(w?(Y=dA(w<<4),i=a[e+4>>2]):Y=0,(0|i)>=1)for(t=0;B=a[e+12>>2]+t|0,V=a[B+4>>2],g=t+Y|0,a[g>>2]=a[B>>2],a[g+4>>2]=V,B=B+8|0,V=a[B+4>>2],g=g+8|0,a[g>>2]=a[B>>2],a[g+4>>2]=V,t=t+16|0,i=i+-1|0,i;);i=a[e+12>>2],i&&(o[e+16|0]&&CA(i),a[e+12>>2]=0),a[e+12>>2]=Y,f[e+16|0]=1,a[e+8>>2]=w,i=a[e+4>>2]}i=a[e+12>>2]+(i<<4)|0,a[i+12>>2]=0,C[i+8>>2]=c,C[i+4>>2]=b,C[i>>2]=n,a[e+4>>2]=a[e+4>>2]+1}if(p=p+1|0,(0|p)==(0|r))break e;t=a[A+12>>2]}if((0|r)==(0|v))break A;t=a[A+12>>2],i=v}if((0|r)==(0|h))break}}(r+128|0,r+104|0),HA(r+152|0,a[r+116>>2],a[r+108>>2]),e=a[r+116>>2],e&&(o[r+120|0]&&CA(e),a[r+116>>2]=0),e=a[r+140>>2],e&&(o[r+144|0]&&CA(e),a[r+140>>2]=0),e=a[r+60>>2],e&&(o[r+64|0]&&CA(e),a[r+60>>2]=0)}else HA(r+152|0,v,a[r+220>>2]);if(e=a[r+196>>2],(0|e)<1)t=0;else{for(x=dA(e<<4),t=x,n=e;b=a[r+52>>2],a[t>>2]=a[r+48>>2],a[t+4>>2]=b,l=r+56|0,c=a[l+4>>2],b=t+8|0,a[b>>2]=a[l>>2],a[b+4>>2]=c,t=t+16|0,n=n+-1|0,n;);t=x}i=t,a[r+140>>2]=0,f[r+144|0]=1,a[r+132>>2]=0,a[r+136>>2]=0,t=r+63|0,f[0|t]=0,f[t+1|0]=0,f[t+2|0]=0,f[t+3|0]=0,t=r+56|0,a[t>>2]=0,a[t+4>>2]=0,a[r+48>>2]=0,a[r+52>>2]=0;A:{if((0|e)<=-1)for(n=e+1|0,c=B(e,36)+8|0,t=0;;){if(t=t+c|0,l=t+-4|0,b=t+4|0,u=a[b>>2],u&&(o[t+8|0]&&CA(u),a[b>>2]=0),a[l>>2]=0,a[b>>2]=0,a[t>>2]=0,f[t+8|0]=1,!n)break A;c=c+36|0,n=n+1|0,t=a[r+140>>2]}if(e)for(PA(r+128|0,e),b=r+48|3,n=20,u=e;l=o[b+4|0]|o[b+5|0]<<8|o[b+6|0]<<16|o[b+7|0]<<24,t=a[r+140>>2]+n|0,c=o[0|b]|o[b+1|0]<<8|o[b+2|0]<<16|o[b+3|0]<<24,f[0|t]=c,f[t+1|0]=c>>>8,f[t+2|0]=c>>>16,f[t+3|0]=c>>>24,f[t+4|0]=l,f[t+5|0]=l>>>8,f[t+6|0]=l>>>16,f[t+7|0]=l>>>24,f[t+-4|0]=1,k=t+-16|0,l=k,a[l>>2]=0,a[l+4>>2]=0,l=b+8|0,c=o[l+4|0]|o[l+5|0]<<8|o[l+6|0]<<16|o[l+7|0]<<24,t=t+8|0,l=o[0|l]|o[l+1|0]<<8|o[l+2|0]<<16|o[l+3|0]<<24,f[0|t]=l,f[t+1|0]=l>>>8,f[t+2|0]=l>>>16,f[t+3|0]=l>>>24,f[t+4|0]=c,f[t+5|0]=c>>>8,f[t+6|0]=c>>>16,f[t+7|0]=c>>>24,a[k+8>>2]=0,n=n+36|0,u=u+-1|0,u;);}if(a[r+132>>2]=e,l=a[A+56>>2],b=a[l+8>>2],n=a[r+156>>2],(0|b)<(0|n)){if(a[l+12>>2]<(0|n)){if(n?(v=dA(n<<4),c=a[l+8>>2]):(v=0,c=b),(0|c)>=1)for(t=0;u=a[l+16>>2]+t|0,Q=a[u+4>>2],k=t+v|0,s=k,a[s>>2]=a[u>>2],a[s+4>>2]=Q,u=u+8|0,s=a[u+4>>2],k=k+8|0,a[k>>2]=a[u>>2],a[k+4>>2]=s,t=t+16|0,c=c+-1|0,c;);t=a[l+16>>2],t&&(o[l+20|0]&&CA(t),a[l+16>>2]=0),a[l+16>>2]=v,a[l+12>>2]=n,f[l+20|0]=1}for(t=b<<4,c=n-b|0;k=a[r+52>>2],b=a[l+16>>2]+t|0,a[b>>2]=a[r+48>>2],a[b+4>>2]=k,u=r+56|0,k=a[u+4>>2],b=b+8|0,a[b>>2]=a[u>>2],a[b+4>>2]=k,t=t+16|0,c=c+-1|0,c;);}if(a[l+8>>2]=n,(0|n)>=1)for(t=0;b=a[r+164>>2]+t|0,u=a[b+4>>2],l=a[a[A+56>>2]+16>>2]+t|0,c=l,a[c>>2]=a[b>>2],a[c+4>>2]=u,b=b+8|0,c=a[b+4>>2],l=l+8|0,a[l>>2]=a[b>>2],a[l+4>>2]=c,t=t+16|0,n=n+-1|0,n;);if((0|e)>=1)for(k=0;;){for(v=0,h=a[r+184>>2]+B(a[a[r+204>>2]+(k<<2)>>2],12)|0,u=h;;){if(w=B(k,36),s=w+a[r+140>>2]|0,Q=s+4|0,G=a[8+(B(a[u+4>>2],12)+u|0)>>2],c=a[s+4>>2],(0|c)==a[s+8>>2]&&(p=c?c<<1:1,!((0|c)>=(0|p)))){p?(b=dA(p<<2),c=a[Q>>2]):b=0,I=s+8|0,E=s+12|0,l=a[s+12>>2];A:{if((0|c)>=1)for(t=b,n=l;a[t>>2]=a[n>>2],t=t+4|0,n=n+4|0,c=c+-1|0,c;);else if(!l)break A;o[s+16|0]&&CA(l),a[E>>2]=0,c=a[Q>>2]}a[E>>2]=b,a[I>>2]=p,f[s+16|0]=1}if(a[a[s+12>>2]+(c<<2)>>2]=G,a[Q>>2]=a[Q>>2]+1,(0|v)<=1&&(n=a[r+164>>2],t=n+(G<<4)|0,d=C[t+4>>2],n=n+(a[u+8>>2]<<4)|0,g=C[n+4>>2],R=C[t>>2],F=C[n>>2],W=C[t+8>>2],J=C[n+8>>2],t=(r+48|0)+(v<<4)|0,a[t+12>>2]=0,R=_(F-R),g=_(g-d),F=_(J-W),d=_(_(1)/_(y(_(_(_(R*R)+_(g*g))+_(F*F))))),C[t+8>>2]=F*d,C[t+4>>2]=g*d,C[t>>2]=R*d,v=v+1|0),t=B(a[u+4>>2],12)+u|0,u=B(a[t>>2],12)+t|0,(0|h)==(0|u))break}if(2!=(0|v)?(t=(k<<4)+i|0,a[t>>2]=0,a[t+4>>2]=0,t=t+8|0,a[t>>2]=0,a[t+4>>2]=0,n=a[r+140>>2]):(t=(k<<4)+i|0,a[t+12>>2]=0,R=C[r+68>>2],g=C[r+48>>2],F=C[r+52>>2],W=C[r+64>>2],d=_(_(R*g)-_(F*W)),M=d,S=_(d*d),d=F,F=C[r+72>>2],J=C[r+56>>2],d=_(_(d*F)-_(J*R)),R=_(_(J*W)-_(F*g)),g=_(_(1)/_(y(_(S+_(_(d*d)+_(R*R)))))),C[t+8>>2]=M*g,C[t+4>>2]=R*g,d=_(d*g),C[t>>2]=d,n=a[r+140>>2],b=w+n|0,C[b+20>>2]=d,a[b+24>>2]=a[t+4>>2],a[b+28>>2]=a[t+8>>2],a[b+32>>2]=1900671690),n=n+w|0,l=a[n+4>>2],(0|l)<1)d=_(1.0000000150474662e30);else for(t=a[n+12>>2],b=(k<<4)+i|0,R=C[b+8>>2],g=C[b+4>>2],F=C[b>>2],u=a[a[A+56>>2]+16>>2],d=_(1.0000000150474662e30),c=0;b=u+(a[t>>2]<<4)|0,W=_(_(_(C[b>>2]*F)+_(C[b+4>>2]*g))+_(C[b+8>>2]*R)),d=d>W?W:d,t=t+4|0,c=c+1|0,(0|c)<(0|l););if(C[n+32>>2]=-d,k=k+1|0,(0|e)==(0|k))break}A:if(a[r+132>>2]>=1){for(s=0,Q=0,w=0,c=0;;){if((0|c)==(0|s))if(c=s?s<<1:1,(0|s)>=(0|c))c=s;else{u=c?dA(c<<2):0;e:{if(s)for(t=u,n=s;a[t>>2]=a[Q>>2],t=t+4|0,Q=Q+4|0,n=n+-1|0,n;);else if(!Q){c=1;break e}CA(w)}w=u,Q=u}if(a[(s<<2)+Q>>2]=s,s=s+1|0,!((0|s)>2]))break}for(E=r+68|0,I=r+40|0;;){b=s+-1|0,e=a[(b<<2)+Q>>2],k=dA(4),a[k>>2]=e;e:{if((0|b)<1)p=1,e=k,s=b;else{for(n=a[r+140>>2],e=n+B(e,36)|0,d=C[e+20>>2],R=C[e+28>>2],g=C[e+24>>2],u=s+-2|0,t=1,s=b,b=k,p=1;;){c=a[(u<<2)+Q>>2],e=B(c,36)+n|0;r:if(_(_(_(d*C[e+20>>2])+_(g*C[e+24>>2]))+_(R*C[e+28>>2]))>_(.9990000128746033)){if((0|t)!=(0|p)||(l=t?t<<1:1,(0|t)>=(0|l)))l=t,e=b;else{e=l?dA(l<<2):0;i:{if((0|t)>=1)for(n=e;a[n>>2]=a[k>>2],n=n+4|0,k=k+4|0,t=t+-1|0,t;);else if(!k)break i;CA(b)}k=e}if(a[(p<<2)+k>>2]=c,p=p+1|0,!((0|s)<1)){for(n=0,t=Q;;){if(a[t>>2]!=(0|c)){if(t=t+4|0,n=n+1|0,(0|s)!=(0|n))continue;break r}break}(0|s)<=(0|n)||(b=t,s=s+-1|0,t=(s<<2)+Q|0,a[b>>2]=a[t>>2],a[t>>2]=c)}}else l=t,e=b;if(!((0|u)>=1))break;u=u+-1|0,n=a[r+140>>2],b=e,t=l}r:if(!((0|p)<=1)){for(c=0,a[r+116>>2]=0,f[r+120|0]=1,a[r+108>>2]=0,a[r+112>>2]=0,a[I>>2]=0,a[I+4>>2]=0,a[r+32>>2]=0,a[r+36>>2]=0,d=_(0),l=0,R=_(0),g=_(0),G=0;;){if(t=a[r+140>>2]+B(a[(G<<2)+k>>2],36)|0,F=C[t+24>>2],W=C[t+28>>2],C[r+32>>2]=C[t+20>>2]+g,C[r+40>>2]=W+d,C[r+36>>2]=F+R,v=a[t+4>>2],(0|v)>=1)for(T=t+4|0,j=t+12|0,b=0;;){Z=a[a[j>>2]+(b<<2)>>2],t=a[a[A+56>>2]+16>>2]+(Z<<4)|0,h=t+8|0,V=a[h+4>>2],u=r+16|0,n=u,a[n>>2]=a[h>>2],a[n+4>>2]=V,n=a[t+4>>2],a[r+8>>2]=a[t>>2],a[r+12>>2]=n;i:{if((0|l)>=1){for(t=a[r+116>>2]+20|0,n=0;;){if((0|Z)==a[t>>2])break i;if(t=t+24|0,n=n+1|0,!((0|n)<(0|c)))break}l=c}if(n=a[u+4>>2],V=r+56|0,t=V,a[t>>2]=a[u>>2],a[t+4>>2]=n,t=a[r+12>>2],a[r+48>>2]=a[r+8>>2],a[r+52>>2]=t,(0|l)==a[r+112>>2])if(h=l?l<<1:1,(0|l)>=(0|h))c=l;else{h?(u=dA(B(h,24)),c=a[r+108>>2],l=c):u=0,v=a[r+116>>2];f:{if((0|l)>=1)for(t=u,n=v;D=a[n+4>>2],a[t>>2]=a[n>>2],a[t+4>>2]=D,N=n+16|0,U=a[N+4>>2],D=t+16|0,a[D>>2]=a[N>>2],a[D+4>>2]=U,N=n+8|0,U=a[N+4>>2],D=t+8|0,a[D>>2]=a[N>>2],a[D+4>>2]=U,t=t+24|0,n=n+24|0,l=l+-1|0,l;);else if(!v)break f;o[r+120|0]&&(CA(v),c=a[r+108>>2]),a[r+116>>2]=0}a[r+116>>2]=u,f[r+120|0]=1,a[r+112>>2]=h}else c=l;n=a[r+52>>2],t=a[r+116>>2]+B(c,24)|0,a[t>>2]=a[r+48>>2],a[t+4>>2]=n,a[t+20>>2]=Z,a[t+16>>2]=a[r- -64>>2],n=a[V+4>>2],t=t+8|0,a[t>>2]=a[V>>2],a[t+4>>2]=n,c=a[r+108>>2]+1|0,a[r+108>>2]=c,v=a[T>>2]}if(l=c,b=b+1|0,!((0|b)<(0|v)))break}if(d=C[r+40>>2],R=C[r+36>>2],g=C[r+32>>2],G=G+1|0,(0|G)==(0|p))break}if(a[r+52>>2]=0,a[r+56>>2]=0,t=a[r+140>>2]+B(a[k>>2],36)|0,a[r+68>>2]=a[t+20>>2],a[r+72>>2]=a[t+24>>2],a[r+76>>2]=a[t+28>>2],a[r+60>>2]=0,f[r+64|0]=1,a[r+80>>2]=a[t+32>>2],F=d,d=_(_(1)/_(y(_(_(_(g*g)+_(R*R))+_(d*d))))),C[r+40>>2]=F*d,C[r+36>>2]=R*d,C[r+32>>2]=g*d,a[r+20>>2]=0,f[r+24|0]=1,a[r+12>>2]=0,a[r+16>>2]=0,KA(r+104|0,r+8|0,r+32|0),a[r+12>>2]<=0)u=a[r+108>>2];else for(b=0,c=a[r+52>>2];;){if(G=B(b,24),h=20+(G+a[r+20>>2]|0)|0,a[r+56>>2]==(0|c)&&(v=c?c<<1:1,!((0|c)>=(0|v)))){v?(l=dA(v<<2),c=a[r+52>>2]):l=0,u=a[r+60>>2];i:{if((0|c)>=1)for(t=l,n=u;a[t>>2]=a[n>>2],t=t+4|0,n=n+4|0,c=c+-1|0,c;);else if(!u)break i;o[r+64|0]&&CA(u),a[r+60>>2]=0,c=a[r+52>>2]}a[r+60>>2]=l,f[r+64|0]=1,a[r+56>>2]=v}a[a[r+60>>2]+(c<<2)>>2]=a[h>>2],c=a[r+52>>2]+1|0,a[r+52>>2]=c,u=a[r+108>>2];i:if(!((0|u)<1)){for(t=a[r+116>>2]+20|0,l=a[20+(G+a[r+20>>2]|0)>>2],n=0;;){if(a[t>>2]!=(0|l)){if(t=t+24|0,n=n+1|0,(0|n)<(0|u))continue;break i}break}a[t>>2]=-1}if(b=b+1|0,!((0|b)>2]))break}if(!((0|u)<1||(v=a[r+132>>2],(0|v)<1)))for(G=a[r+140>>2],Z=a[r+116>>2],l=0;;){i:if(h=a[20+(Z+B(l,24)|0)>>2],-1!=(0|h)){f:{if((0|p)<=0){for(b=0;;){if(t=G+B(b,36)|0,c=a[t+4>>2],(0|c)>0)for(t=a[t+12>>2],n=0;;){if((0|h)==a[t>>2])break f;if(t=t+4|0,n=n+1|0,!((0|n)<(0|c)))break}if(b=b+1|0,(0|b)==(0|v))break}break i}for(c=0;;){t=k,n=p;t:{for(;;){if(a[t>>2]==(0|c))break t;if(t=t+4|0,n=n+-1|0,!n)break}if(t=G+B(c,36)|0,b=a[t+4>>2],!((0|b)<1))for(t=a[t+12>>2],n=0;;){if((0|h)==a[t>>2])break f;if(t=t+4|0,n=n+1|0,!((0|n)<(0|b)))break}}if(c=c+1|0,(0|c)==(0|v))break}break i}if(t=a[r+20>>2],t&&(o[r+24|0]&&CA(t),a[r+20>>2]=0),t=a[r+60>>2],t&&(o[r+64|0]&&CA(t),a[r+60>>2]=0),t=a[r+116>>2],!t)break r;o[r+120|0]&&CA(t),a[r+116>>2]=0;break r}if(l=l+1|0,!((0|l)<(0|u)))break}if(LA(a[A+56>>2]+24|0,r+48|0),t=a[r+20>>2],t&&(o[r+24|0]&&CA(t),a[r+20>>2]=0),t=a[r+60>>2],t&&(o[r+64|0]&&CA(t),a[r+60>>2]=0),t=a[r+116>>2],!t)break e;o[r+120|0]&&CA(t),a[r+116>>2]=0;break e}if((0|p)<1)break e}for(b=0;;){if(t=a[(b<<2)+k>>2],a[r+52>>2]=0,a[r+56>>2]=0,a[r+60>>2]=0,G=a[r+140>>2]+B(t,36)|0,c=a[G+4>>2],f[r+64|0]=1,(0|c)>=1){h=c<<2,l=dA(h),v=a[r+60>>2],u=a[r+52>>2];r:{if((0|u)>=1)for(t=l,n=v;a[t>>2]=a[n>>2],t=t+4|0,n=n+4|0,u=u+-1|0,u;);else if(!v)break r;o[r+64|0]&&CA(v)}for(a[r+60>>2]=l,f[r+64|0]=1,a[r+56>>2]=c,X(l,0,h),a[r+52>>2]=c,t=a[G+12>>2],n=a[r+60>>2];a[n>>2]=a[t>>2],n=n+4|0,t=t+4|0,c=c+-1|0,c;);}else a[r+52>>2]=c;if(t=a[G+24>>2],a[E>>2]=a[G+20>>2],a[E+4>>2]=t,n=G+28|0,l=a[n+4>>2],t=E+8|0,a[t>>2]=a[n>>2],a[t+4>>2]=l,LA(a[A+56>>2]+24|0,r+48|0),t=a[r+60>>2],t&&(o[r+64|0]&&CA(t),a[r+60>>2]=0),b=b+1|0,(0|p)==(0|b))break}}if(k&&CA(e),!s)break}if(VA(a[A+56>>2]),!Q)break A;CA(w)}else VA(a[A+56>>2]);if(u=a[r+132>>2],(0|u)>=1)for(n=8;A=a[r+140>>2]+n|0,t=A+-4|0,e=A+4|0,b=a[e>>2],b&&(o[A+8|0]&&CA(b),a[e>>2]=0),a[t>>2]=0,a[e>>2]=0,a[A>>2]=0,f[A+8|0]=1,n=n+36|0,u=u+-1|0,u;);return A=a[r+140>>2],A&&(o[r+144|0]&&CA(A),a[r+140>>2]=0),i&&CA(x),A=a[r+204>>2],A&&(o[r+208|0]&&CA(A),a[r+204>>2]=0),a[r+204>>2]=0,f[r+208|0]=1,a[r+196>>2]=0,a[r+200>>2]=0,A=a[r+184>>2],A&&(o[r+188|0]&&CA(A),a[r+184>>2]=0),a[r+184>>2]=0,f[r+188|0]=1,a[r+176>>2]=0,a[r+180>>2]=0,A=a[r+164>>2],A&&(o[r+168|0]&&CA(A),a[r+164>>2]=0),A=a[r+228>>2],A&&(o[r+232|0]&&CA(A),a[r+228>>2]=0),Y=r+240|0,1},kA,qA,function(A,e){A|=0,e|=0;var r,i=_(0);r=Y-96|0,Y=r,EA(A,e),f[A+92|0]=1,o[1680]||(a[397]=0,a[398]=0,a[396]=1065353216,a[399]=0,a[400]=0,a[402]=0,a[403]=0,a[401]=1065353216,a[404]=0,a[405]=0,a[409]=0,a[410]=0,a[408]=-1082130432,a[406]=1065353216,a[407]=0,a[411]=0,a[412]=0,a[414]=0,a[415]=0,a[413]=-1082130432,a[416]=0,a[417]=0,a[418]=-1082130432,a[419]=0,f[1680]=1),e=X(r,0,96),Qt[a[a[A>>2]+76>>2]](A,1584,e,6),i=C[A+48>>2],C[A+76>>2]=C[e>>2]+i,C[A+60>>2]=C[e+48>>2]-i,C[A+80>>2]=i+C[e+20>>2],C[A- -64>>2]=C[e+68>>2]-i,C[A+84>>2]=i+C[e+40>>2],C[A+68>>2]=C[e+88>>2]-i,Y=e+96|0},ce,function(A,e,r,i){A|=0,e|=0,r|=0,i|=0,qA(A,e,r,i)},function(A){return 8528},ne,function(A){return A|=0,A=a[A+96>>2]+-2|0,A>>>0<=2?a[7624+(A<<2)>>2]:0},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f=0,t=0;A:{e:{r:{i:{f=a[A+96>>2]+-2|0;f:if(!(f>>>0>2)){t:switch(f-1|0){case 0:if(e>>>0>2)break f;n:switch(e-1|0){case 0:break r;case 1:break n;default:break i}break e;case 1:break t;default:break i}if(!(e>>>0>5)){t:switch(e-1|0){case 2:e=a[A+104>>2],a[r>>2]=a[A+100>>2],a[r+4>>2]=e,e=r+8|0,r=A+108|0,f=a[r+4>>2],a[e>>2]=a[r>>2],a[e+4>>2]=f;break A;case 3:f=A+124|0,t=a[f+4>>2],e=r+8|0,a[e>>2]=a[f>>2],a[e+4>>2]=t,e=A+116|0,f=a[e+4>>2],a[r>>2]=a[e>>2],a[r+4>>2]=f;break A;case 0:break r;case 1:break e;case 4:break t;default:break i}f=A+140|0,t=a[f+4>>2],e=r+8|0,a[e>>2]=a[f>>2],a[e+4>>2]=t,e=A+132|0,f=a[e+4>>2],a[r>>2]=a[e>>2],a[r+4>>2]=f,r=A+156|0,f=a[r+4>>2],e=i+8|0,a[e>>2]=a[r>>2],a[e+4>>2]=f,A=A+148|0,e=a[A+4>>2],a[i>>2]=a[A>>2],a[i+4>>2]=e}}return}return e=a[A+104>>2],a[r>>2]=a[A+100>>2],a[r+4>>2]=e,e=r+8|0,r=A+108|0,f=a[r+4>>2],a[e>>2]=a[r>>2],a[e+4>>2]=f,r=A+124|0,f=a[r+4>>2],e=i+8|0,a[e>>2]=a[r>>2],a[e+4>>2]=f,A=A+116|0,e=a[A+4>>2],a[i>>2]=a[A>>2],void(a[i+4>>2]=e)}return f=A+124|0,t=a[f+4>>2],e=r+8|0,a[e>>2]=a[f>>2],a[e+4>>2]=t,e=A+116|0,f=a[e+4>>2],a[r>>2]=a[e>>2],a[r+4>>2]=f,r=A+140|0,f=a[r+4>>2],e=i+8|0,a[e>>2]=a[r>>2],a[e+4>>2]=f,A=A+132|0,e=a[A+4>>2],a[i>>2]=a[A>>2],void(a[i+4>>2]=e)}return f=A+140|0,t=a[f+4>>2],e=r+8|0,a[e>>2]=a[f>>2],a[e+4>>2]=t,e=A+132|0,f=a[e+4>>2],a[r>>2]=a[e>>2],a[r+4>>2]=f,r=A+108|0,f=a[r+4>>2],e=i+8|0,a[e>>2]=a[r>>2],a[e+4>>2]=f,e=a[A+104>>2],a[i>>2]=a[A+100>>2],void(a[i+4>>2]=e)}r=A+156|0,f=a[r+4>>2],e=i+8|0,a[e>>2]=a[r>>2],a[e+4>>2]=f,A=A+148|0,e=a[A+4>>2],a[i>>2]=a[A>>2],a[i+4>>2]=e},function(A,e,r){var i,f;A|=0,e|=0,r|=0,A=(e<<4)+A|0,e=A+108|0,f=a[e+4>>2],i=r+8|0,a[i>>2]=a[e>>2],a[i+4>>2]=f,A=A+100|0,e=a[A+4>>2],a[r>>2]=a[A>>2],a[r+4>>2]=e},function(A){return A|=0,A=a[A+96>>2],0|(4==(0|A)?4:(3==(0|A))<<1)},ae,function(A,e,r){return r=_(r),0},oe,sA,ve,function(A,e,r){A|=0,e|=0,r|=0,a[A+24>>2]=r,a[A+16>>2]=e},function(A,e,r){A|=0,e|=0,r|=0,a[A+28>>2]=r,a[A+20>>2]=e},function(A,e,r,i){A|=0,e|=0,r|=0,i=_(i);var f,t=0,n=_(0),c=_(0),b=_(0),l=0,u=_(0),s=_(0),k=0,v=0,d=0,g=_(0),R=_(0),G=0,p=0,F=_(0),W=_(0),w=_(0),D=_(0),E=0,Z=0,V=_(0),N=_(0),I=_(0),x=_(0),U=_(0),M=_(0),S=_(0),X=_(0),T=_(0),j=_(0),O=_(0),H=0,z=0;f=Y-192|0,Y=f,C[a[A+4>>2]+784>>2]>2],c=_(_(C[e+8>>2]*i)+R),F=C[r+4>>2],b=_(_(C[e+4>>2]*i)+F),W=C[r>>2],g=_(_(C[e>>2]*i)+W),l=a[A+4>>2],Z=a[l+780>>2],k=a[l+772>>2],p=a[a[A+8>>2]+8>>2],G=(0|k)==(0|p),G?(n=_(g-C[k+52>>2]),u=_(b-C[k+56>>2]),s=_(c-C[k+60>>2]),w=_(_(_(n*C[k+12>>2])+_(u*C[k+28>>2]))+_(s*C[k+44>>2])),D=_(_(_(n*C[k+8>>2])+_(u*C[k+24>>2]))+_(s*C[k+40>>2])),n=_(_(_(n*C[k+4>>2])+_(u*C[k+20>>2]))+_(s*C[k+36>>2])),t=a[a[A+12>>2]+8>>2]):(t=a[a[A+12>>2]+8>>2],n=_(g-C[t+52>>2]),u=_(b-C[t+56>>2]),s=_(c-C[t+60>>2]),w=_(_(_(n*C[t+12>>2])+_(u*C[t+28>>2]))+_(s*C[t+44>>2])),D=_(_(_(n*C[t+8>>2])+_(u*C[t+24>>2]))+_(s*C[t+40>>2])),n=_(_(_(n*C[t+4>>2])+_(u*C[t+20>>2]))+_(s*C[t+36>>2])),t=p),V=C[t+20>>2],N=C[t+36>>2],I=C[t+40>>2],x=C[t+8>>2],U=C[t+24>>2],M=C[t+44>>2],S=C[t+60>>2],u=C[t+12>>2],s=C[t+52>>2],X=C[t+28>>2],T=C[t+56>>2],j=C[t+4>>2],a[f+28>>2]=0,t=f+124|0,a[t>>2]=0,a[t+4>>2]=0,t=f+132|0,a[t>>2]=0,a[t+4>>2]=0,t=f+140|0,a[t>>2]=0,a[t+4>>2]=0,t=f+148|0,a[t>>2]=0,a[t+4>>2]=0,a[f+156>>2]=0,t=e+8|0,v=a[t+4>>2],d=f+72|0,a[d>>2]=a[t>>2],a[d+4>>2]=v,O=u,u=_(W-s),s=_(F-T),R=_(R-S),C[f+24>>2]=_(_(O*u)+_(X*s))+_(M*R),C[f+20>>2]=_(_(u*x)+_(s*U))+_(R*I),a[f+12>>2]=0,C[f+8>>2]=w,C[f+4>>2]=D,C[f>>2]=n,a[f+84>>2]=0,a[f+88>>2]=0,C[f+80>>2]=i,a[f+92>>2]=0,a[f+96>>2]=0,a[f+116>>2]=0,a[f+120>>2]=0,t=a[e+4>>2],a[f+64>>2]=a[e>>2],a[f+68>>2]=t,C[f+16>>2]=_(_(u*j)+_(s*V))+_(R*N),a[f+60>>2]=0,C[f+56>>2]=c,C[f+52>>2]=b,e=r+8|0,t=a[e+4>>2],v=f+40|0,a[v>>2]=a[e>>2],a[v+4>>2]=t,C[f+48>>2]=g,e=a[r+4>>2],a[f+32>>2]=a[r>>2],a[f+36>>2]=e,r=function(A,e){var r,i=_(0),f=_(0),t=0,n=_(0),o=0,c=_(0),b=_(0),l=_(0);if(r=a[A+780>>2],(0|r)<1)e=-1;else for(t=A+8|0,c=C[e+8>>2],b=C[e+4>>2],l=C[e>>2],f=C[A+784>>2],f=_(f*f),A=0,e=-1;i=_(C[t+-4>>2]-l),n=_(i*i),i=_(C[t>>2]-b),n=_(n+_(i*i)),i=_(C[t+4>>2]-c),i=_(n+_(i*i)),o=i>2],e=a[v+8>>2],d=a[A+12>>2],t=a[d+8>>2],C[f+96>>2]=C[e+232>>2]*C[t+232>>2],i=C[e+228>>2],n=C[t+228>>2],C[f+84>>2]=Q(_(h(_(i*n),_(-10))),_(10)),C[f+88>>2]=Q(_(h(_(_(n*C[e+236>>2])+_(i*C[t+236>>2])),_(-10))),_(10)),C[f+92>>2]=Q(_(h(_(_(n*C[e+240>>2])+_(i*C[t+240>>2])),_(-10))),_(10)),l=a[e+204>>2],(128&o[t+204|0]||128&l)&&(C[f+148>>2]=C[e+244>>2]+C[t+244>>2],C[f+144>>2]=_(1)/_(_(_(1)/C[a[v+8>>2]+248>>2])+_(_(1)/C[a[d+8>>2]+248>>2])),a[f+120>>2]=8|a[f+120>>2],l=a[a[v+8>>2]+204>>2]),(2&o[a[d+8>>2]+205|0]||512&l)&&(a[f+120>>2]=16|a[f+120>>2]),i=C[f+72>>2],_(m(i))>_(.7071067690849304)?(b=C[f+68>>2],n=_(_(i*i)+_(b*b)),c=_(_(1)/_(y(n))),g=_(n*c),s=C[f+64>>2],n=_(-_(i*c)),u=_(s*n),i=_(b*c),c=_(-_(s*i)),b=_(0)):(g=C[f+64>>2],c=C[f+68>>2],b=_(_(g*g)+_(c*c)),n=_(_(1)/_(y(b))),u=_(b*n),b=_(-_(c*n)),c=_(i*b),n=_(g*n),g=_(-_(i*n)),i=_(0)),t=A+4|0,C[f+184>>2]=u,C[f+180>>2]=c,C[f+168>>2]=i,C[f+164>>2]=n,C[f+176>>2]=g,C[f+160>>2]=b,G?(e=A+28|0,l=A+24|0,v=A+16|0,d=A+20|0):(e=A+24|0,l=A+28|0,v=A+20|0,d=A+16|0),a[f+112>>2]=a[e>>2],a[f+108>>2]=a[l>>2],a[f+104>>2]=a[d>>2],a[f+100>>2]=a[v>>2],e=a[t>>2],(0|r)>=0?(e=e+B(r,192)|0,l=e+136|0,i=C[l>>2],v=e+132|0,n=C[v>>2],d=e+128|0,c=C[d>>2],G=e+160|0,H=a[G>>2],16&o[f+120|0]&&(b=_(_(c*C[e+88>>2])+_(0)),!(_(_(n*n)+_(i*i))>_(b*b)))||(E=e+120|0,z=a[E>>2],J(e+4|0,f,192),C[d>>2]=c,a[E>>2]=z,C[v>>2]=n,C[l>>2]=i),a[G>>2]=H):r=ue(e,f),l=a[425],l&&(e=A+8|0,A=A+12|0,(8&o[a[a[A>>2]+8>>2]+204|0]||8&o[a[a[e>>2]+8>>2]+204|0])&&(d=4+(a[t>>2]+B(r,192)|0)|0,r=(0|k)!=(0|p),Qt[l](d,a[(r?A:e)>>2],a[f+100>>2],a[f+108>>2],a[(r?e:A)>>2],a[f+104>>2],a[f+112>>2]))),Z||(A=a[423],A&&Qt[A](t))),Y=f+192|0},function(A,e,r){A|=0,e|=0,r|=0;var i,f,t,n=_(0);i=Y-96|0,Y=i,f=a[a[A>>2]>>2],t=a[a[A+4>>2]>>2],Qt[a[a[e>>2]+24>>2]](e,f,t)&&(a[i+88>>2]=-1,a[i+92>>2]=-1,a[i+72>>2]=0,a[i+80>>2]=f,a[i+84>>2]=f+4,a[i+76>>2]=a[f+192>>2],a[i+64>>2]=-1,a[i+68>>2]=-1,a[i+48>>2]=0,a[i+56>>2]=t,a[i+60>>2]=t+4,a[i+52>>2]=a[t+192>>2],(a[A+8>>2]||(e=0|Qt[a[a[e>>2]+8>>2]](e,i+72|0,i+48|0,0,1),a[A+8>>2]=e,e))&&(e=function(A,e,r){return a[A+32>>2]=0,a[A+12>>2]=r,a[A+8>>2]=e,a[A+4>>2]=0,a[A>>2]=7720,A}(i+8|0,i+72|0,i+48|0),A=a[A+8>>2],1!=a[r+8>>2]?(n=_(Qt[a[a[A>>2]+12>>2]](A,f,t,r,e)),C[r+12>>2]>n&&(C[r+12>>2]=n)):Qt[a[a[A>>2]+8>>2]](A,i+72|0,i+48|0,r,e))),Y=i+96|0},function(A){var e;return A|=0,a[A>>2]=7860,e=a[A+20>>2],e&&(o[A+24|0]&&CA(e),a[A+20>>2]=0),a[A+20>>2]=0,a[A+12>>2]=0,a[A+16>>2]=0,f[A+24|0]=1,0|A},function(A){var e;A|=0,a[A>>2]=7860,e=a[A+20>>2],e&&(o[A+24|0]&&CA(e),a[A+20>>2]=0),a[A+20>>2]=0,a[A+12>>2]=0,a[A+16>>2]=0,f[A+24|0]=1,$(A)},function(A,e,r,i,f){var t,n;return A|=0,e|=0,r|=0,i|=0,f|=0,t=Y-16|0,Y=t,a[t+12>>2]=i,a[t+8>>2]=A,i=a[a[r+4>>2]+4>>2],n=a[a[e+4>>2]+4>>2],1!=(0|f)?(A=a[5260+((B(n,144)+A|0)+(i<<2)|0)>>2],e=0|Qt[a[a[A>>2]+8>>2]](A,t+8|0,e,r)):(A=a[76+((B(n,144)+A|0)+(i<<2)|0)>>2],e=0|Qt[a[a[A>>2]+8>>2]](A,t+8|0,e,r)),Y=t+16|0,0|e},function(A,e,r){A|=0,e|=0,r|=0;var i,t=0,n=0,c=0,b=_(0),l=_(0),u=0;i=Y-16|0,Y=i,a[426]=a[426]+1,n=2976,2&a[A+4>>2]&&(t=a[e+192>>2],b=_(Qt[a[a[t>>2]+20>>2]](t,C[744])),C[i+12>>2]=b,t=a[r+192>>2],l=_(Qt[a[a[t>>2]+20>>2]](t,C[744])),C[i+8>>2]=l,n=b>2],b=C[r+184>>2],l=C[e+184>>2],t=a[A+72>>2],n=a[t+12>>2];A:{if(n)a[t+12>>2]=a[n>>2],a[t+8>>2]=a[t+8>>2]+-1;else{if(n=0,4&o[A+4|0])break A;n=dA(804)}if(a[n>>2]=1025,a[n+160>>2]=0,t=n+152|0,a[t>>2]=0,a[t+4>>2]=0,t=n+144|0,a[t>>2]=0,a[t+4>>2]=0,t=n+136|0,a[t>>2]=0,a[t+4>>2]=0,t=n+128|0,a[t>>2]=0,a[t+4>>2]=0,a[n+120>>2]=0,a[n+124>>2]=0,a[n+312>>2]=0,a[n+316>>2]=0,t=n+320|0,a[t>>2]=0,a[t+4>>2]=0,t=n+328|0,a[t>>2]=0,a[t+4>>2]=0,t=n+336|0,a[t>>2]=0,a[t+4>>2]=0,t=n+344|0,a[t>>2]=0,a[t+4>>2]=0,a[n+352>>2]=0,a[n+504>>2]=0,a[n+508>>2]=0,t=n+512|0,a[t>>2]=0,a[t+4>>2]=0,t=n+520|0,a[t>>2]=0,a[t+4>>2]=0,t=n+528|0,a[t>>2]=0,a[t+4>>2]=0,t=n+536|0,a[t>>2]=0,a[t+4>>2]=0,a[n+544>>2]=0,a[n+736>>2]=0,t=n+728|0,a[t>>2]=0,a[t+4>>2]=0,t=n+720|0,a[t>>2]=0,a[t+4>>2]=0,t=n+712|0,a[t>>2]=0,a[t+4>>2]=0,t=n+704|0,a[t>>2]=0,a[t+4>>2]=0,a[n+696>>2]=0,a[n+700>>2]=0,a[n+772>>2]=e,a[n+776>>2]=r,a[n+780>>2]=0,a[n+784>>2]=c,C[n+788>>2]=l>2],a[n+800>>2]=t,a[A+16>>2]==(0|t)&&(c=t?t<<1:1,!((0|t)>=(0|c)))){if(c&&(u=dA(c<<2),t=a[A+12>>2]),(0|t)>=1)for(e=0,r=t;a[e+u>>2]=a[a[A+20>>2]+e>>2],e=e+4|0,r=r+-1|0,r;);e=a[A+20>>2],e&&(o[A+24|0]&&(CA(e),t=a[A+12>>2]),a[A+20>>2]=0),a[A+20>>2]=u,a[A+16>>2]=c,f[A+24|0]=1}a[A+12>>2]=t+1,a[a[A+20>>2]+(t<<2)>>2]=n}return Y=i+16|0,0|n},function(A,e){A|=0,e|=0;var r,i,f,t,n,o,c=0,b=0,l=0;if(a[426]=a[426]+-1,Qt[a[a[A>>2]+20>>2]](A,e),c=A+20|0,b=a[c>>2],r=a[e+800>>2],i=r<<2,l=b+i|0,t=a[l>>2],n=l,o=b,b=A+12|0,l=a[b>>2]+-1|0,f=l<<2,a[n>>2]=a[o+f>>2],a[a[c>>2]+f>>2]=t,a[b>>2]=l,a[a[a[c>>2]+i>>2]+800>>2]=r,e&&(A=a[A+72>>2],c=a[A+16>>2],!(c>>>0>e>>>0|c+B(a[A>>2],a[A+4>>2])>>>0<=e>>>0)))return a[e>>2]=a[A+12>>2],a[A+12>>2]=e,void(a[A+8>>2]=a[A+8>>2]+1);CA(e)},function(A,e){A|=0,e|=0;var r=0,i=0,f=0;if(A=Y-16|0,Y=A,i=a[e+780>>2],(0|i)>=1)for(r=e+4|0;le(r),r=r+192|0,f=f+1|0,i=a[e+780>>2],(0|f)<(0|i););i&&(r=a[424],r&&(a[A+12>>2]=e,Qt[r](A+12|0))),a[e+780>>2]=0,Y=A+16|0},function(A,e,r){A|=0,e|=0,r|=0;var i=0;A:{e:if(A=a[e+220>>2]+-2|0,!(A>>>0>3)){switch(A-1|0){case 0:case 1:break e}if(i=a[r+220>>2]+-2|0,!(i>>>0>3))switch(A=0,i-1|0){case 0:case 1:break e;default:break A}}if(!a[e+280>>2]||Qt[a[a[e>>2]+12>>2]](e,r)){if(A=1,!a[r+280>>2])break A;if(Qt[a[a[r>>2]+12>>2]](r,e))break A}A=0}return 0|A},function(A,e,r){if(A|=0,e|=0,r|=0,A=0,e=a[e+204>>2],!(4&e||(r=a[r+204>>2],4&r))){if(!(3&e))return 1;A=!(3&r)}return 0|A},function(A,e,r,i){var f;A|=0,e|=0,r|=0,i|=0,f=Y-16|0,Y=f,a[f+8>>2]=A,a[f+4>>2]=r,a[f>>2]=7968,Qt[a[a[e>>2]+48>>2]](e,f,i),Y=f+16|0},function(A){return A|=0,a[A+12>>2]},function(A,e){return A|=0,e|=0,a[a[A+20>>2]+(e<<2)>>2]},function(A){return A|=0,a[A+12>>2]?a[A+20>>2]:0},Ce,Ce,function(A,e){var r;return A|=0,e|=0,A=a[A+68>>2],r=a[A+12>>2],r?(a[A+12>>2]=a[r>>2],a[A+8>>2]=a[A+8>>2]+-1,0|r):0|dA(e)},function(A,e){A|=0,e|=0;var r=0;if(e&&(A=a[A+68>>2],r=a[A+16>>2],!(r>>>0>e>>>0|B(a[A>>2],a[A+4>>2])+r>>>0<=e>>>0)))return a[e>>2]=a[A+12>>2],a[A+12>>2]=e,void(a[A+8>>2]=a[A+8>>2]+1);CA(e)},sA,ve,function(A,e){var r;return A|=0,e|=0,r=e,e=a[A+8>>2],Qt[a[e+64>>2]](r,e,a[A+4>>2]),0},function(A){A|=0;var e=0,r=0;return a[A>>2]=8056,e=a[A+12>>2],e&&(r=a[A+4>>2],Qt[a[a[r>>2]+16>>2]](r,e),a[A+12>>2]=0),e=a[A+8>>2],e&&(Qt[a[a[e>>2]>>2]](e),e=a[A+4>>2],Qt[a[a[e>>2]+60>>2]](e,a[A+8>>2]),a[A+8>>2]=0),a[A+24>>2]=-1,a[A+28>>2]=-1,e=A+32|0,a[e>>2]=-1,a[e+4>>2]=-1,0|A},function(A){A|=0;var e=0,r=0;a[A>>2]=8056,e=a[A+12>>2],e&&(r=a[A+4>>2],Qt[a[a[r>>2]+16>>2]](r,e),a[A+12>>2]=0),e=a[A+8>>2],e&&(Qt[a[a[e>>2]>>2]](e),e=a[A+4>>2],Qt[a[a[e>>2]+60>>2]](e,a[A+8>>2]),a[A+8>>2]=0),a[A+24>>2]=-1,a[A+28>>2]=-1,e=A+32|0,a[e>>2]=-1,a[e+4>>2]=-1,$(A)},function(A,e,r,i,f){A|=0,e|=0,r|=0,i|=0,f|=0;var t=0,n=0;if(t=a[A+12>>2],t&&(n=a[A+4>>2],Qt[a[a[n>>2]+16>>2]](n,t),a[A+12>>2]=0),t=a[A+8>>2],t&&(Qt[a[a[t>>2]>>2]](t),t=a[A+4>>2],Qt[a[a[t>>2]+60>>2]](t,a[A+8>>2]),a[A+8>>2]=0),a[A+24>>2]=-1,a[A+28>>2]=-1,t=A+32|0,a[t>>2]=-1,a[t+4>>2]=-1,a[A+20>>2]=i,a[A+16>>2]=f,i=a[e+4>>2],25==a[i+4>>2])return f=a[r+4>>2],25==a[f+4>>2]?void _e(A,e,r,i,f):void me(A,e,r,i,f,0);f=a[r+4>>2],25==a[f+4>>2]&&me(A,r,e,f,i,1)},Re,function(A,e){A|=0,e|=0;var r=0,i=0,t=0,n=0,c=0;if(i=a[A+12>>2],i){if(r=a[e+4>>2],(0|r)==a[e+8>>2]&&(n=r?r<<1:1,!((0|r)>=(0|n)))){if(n&&(c=dA(n<<2),r=a[e+4>>2]),(0|r)>=1)for(i=0,t=r;a[i+c>>2]=a[a[e+12>>2]+i>>2],i=i+4|0,t=t+-1|0,t;);t=a[e+12>>2],t&&(o[e+16|0]&&(CA(t),r=a[e+4>>2]),a[e+12>>2]=0),a[e+12>>2]=c,f[e+16|0]=1,a[e+8>>2]=n,i=a[A+12>>2]}a[e+4>>2]=r+1,a[a[e+12>>2]+(r<<2)>>2]=i}},ce,function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f,t,n,o=_(0),c=_(0),b=_(0),l=0,u=0,s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=0;f=Y-48|0,o=C[A+60>>2],s=C[e+16>>2],c=C[A- -64>>2],m=C[e+20>>2],b=C[A+68>>2],R=C[e+24>>2],Q=C[e+52>>2],h=_(_(_(_(o*s)+_(c*m))+_(b*R))+Q),C[f+40>>2]=h,k=C[e+32>>2],G=C[e+36>>2],y=C[e+40>>2],p=C[e+56>>2],F=_(_(_(_(o*k)+_(c*G))+_(b*y))+p),C[f+36>>2]=F,v=o,o=C[e>>2],d=C[e+4>>2],W=b,b=C[e+8>>2],g=C[e+48>>2],w=_(_(_(_(v*o)+_(c*d))+_(W*b))+g),C[f+44>>2]=w,a[f+28>>2]=0,c=C[A+76>>2],B=C[A+80>>2],v=C[A+84>>2],D=_(Q+_(_(_(s*c)+_(m*B))+_(R*v))),C[f+20>>2]=D,E=_(p+_(_(_(k*c)+_(G*B))+_(y*v))),C[f+24>>2]=E,c=_(g+_(_(_(o*c)+_(d*B))+_(b*v))),C[f+16>>2]=c,v=g,g=C[A+92>>2],W=d,d=C[A+96>>2],B=C[A+100>>2],b=_(v+_(_(_(o*g)+_(W*d))+_(b*B))),C[f>>2]=b,e=c>b,l=w>(e?b:c),u=l?f:f+44|0,o=C[A+48>>2],C[r>>2]=C[(e?u:l?f+16|0:u)>>2]-o,a[f+12>>2]=0,k=_(p+_(_(_(k*g)+_(G*d))+_(y*B))),C[f+8>>2]=k,A=f+8|0,e=E>k,l=F>C[(e?f:f+16|0)+8>>2],u=l?A:f+36|0,t=f+24|0,C[r+8>>2]=C[(e?u:l?t:u)>>2]-o,s=_(Q+_(_(_(s*g)+_(m*d))+_(R*B))),C[f+4>>2]=s,Z=r,e=4|f,r=D>s,l=h>C[(r?f:f+16|0)+4>>2],u=l?e:f+40|0,n=f+16|4,C[Z+4>>2]=C[(r?u:l?n:u)>>2]-o,Z=A,A=E>2],l=r?Z:f+36|0,C[i+8>>2]=o+C[(A?l:r?t:l)>>2],r=e,A=D>2],r=e?r:f+40|0,C[i+4>>2]=o+C[(A?r:e?n:r)>>2],A=c>2]=o+C[(A?r:e?f+16|0:r)>>2]},he,function(A){return 8320},function(A,e,r){A|=0,e|=0,r|=0;var i=_(0),f=_(0),t=_(0),n=_(0),o=_(0);i=C[r>>2],f=C[r+4>>2],t=C[r+8>>2],n=_(_(_(i*C[e+76>>2])+_(f*C[e+80>>2]))+_(t*C[e+84>>2])),o=_(_(_(i*C[e+92>>2])+_(f*C[e+96>>2]))+_(t*C[e+100>>2])),i=_(_(_(i*C[e+60>>2])+_(f*C[e- -64>>2]))+_(t*C[e+68>>2])),e=(e+60|0)+((i>2],a[A>>2]=a[e>>2],a[A+4>>2]=r,e=e+8|0,r=a[e+4>>2],A=A+8|0,a[A>>2]=a[e>>2],a[A+4>>2]=r},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f=_(0),t=0,n=0,o=_(0),c=_(0),b=_(0),l=_(0),u=0,s=0;if((0|i)>=1)for(u=A+60|0;f=C[e>>2],o=C[e+4>>2],c=C[e+8>>2],b=_(_(_(f*C[A+76>>2])+_(o*C[A+80>>2]))+_(c*C[A+84>>2])),l=_(_(_(f*C[A+92>>2])+_(o*C[A+96>>2]))+_(c*C[A+100>>2])),f=_(_(_(f*C[A+60>>2])+_(o*C[A+64>>2]))+_(c*C[A+68>>2])),t=((f>2],a[r>>2]=a[t>>2],a[r+4>>2]=n,t=t+8|0,s=a[t+4>>2],n=r+8|0,a[n>>2]=a[t>>2],a[n+4>>2]=s,e=e+16|0,r=r+16|0,i=i+-1|0,i;);},pe,function(A,e,r){A|=0,e|=0,r|=0;var i=_(0),f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0);n=C[A+92>>2],o=C[A+76>>2],c=C[A+80>>2],l=C[A+100>>2],f=C[A+68>>2],u=C[A+84>>2],b=C[A+96>>2],i=C[A- -64>>2],t=C[A+60>>2],a[r+12>>2]=0,o=_(o-t),b=_(b-i),c=_(c-i),t=_(n-t),i=_(_(o*b)-_(c*t)),s=i,k=_(i*i),i=_(l-f),n=_(u-f),f=_(_(c*i)-_(n*b)),i=_(_(n*t)-_(o*i)),t=_(_(1)/_(y(_(k+_(_(f*f)+_(i*i)))))),n=_(s*t),C[r+8>>2]=n,i=_(i*t),C[r+4>>2]=i,f=_(f*t),C[r>>2]=f,e&&(C[r+8>>2]=-n,C[r+4>>2]=-i,C[r>>2]=-f)},Fe,Fe,function(A,e,r,i){A|=0,e|=0,r|=0,i|=0,Qt[a[a[A>>2]+108>>2]](A,e,r),Qt[a[a[A>>2]+108>>2]](A,(e+1|0)%3|0,i)},function(A,e,r){var i,f;A|=0,e|=0,r|=0,A=(e<<4)+A|0,e=A+68|0,f=a[e+4>>2],i=r+8|0,a[i>>2]=a[e>>2],a[i+4>>2]=f,A=A+60|0,e=a[A+4>>2],a[r>>2]=a[A>>2],a[r+4>>2]=e},We,function(A,e,r,i){A|=0,e|=0,r|=0,i|=0,Qt[a[a[A>>2]+124>>2]](A,i,e,r)},function(A,e,r){A|=0,e|=0,r=_(r);var i,f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=0;return i=Y-32|0,Y=i,k=C[A+60>>2],c=_(C[A+76>>2]-k),t=C[A- -64>>2],o=_(C[A+96>>2]-t),f=_(C[A+80>>2]-t),b=_(C[A+92>>2]-k),n=_(_(c*o)-_(f*b)),u=n,v=_(n*n),s=f,f=C[A+68>>2],n=_(C[A+100>>2]-f),l=_(C[A+84>>2]-f),o=_(_(s*n)-_(l*o)),c=_(_(l*b)-_(c*n)),b=_(_(1)/_(y(_(v+_(_(o*o)+_(c*c)))))),n=_(u*b),o=_(o*b),c=_(c*b),t=_(_(_(C[e+8>>2]*n)+_(_(C[e>>2]*o)+_(C[e+4>>2]*c)))-_(_(f*n)+_(_(k*o)+_(t*c)))),k=_(-r),t>=k^1|t<=r^1||(Qt[a[a[A>>2]+104>>2]](A,0,i+16|0,i),b=C[i+16>>2],t=_(C[i>>2]-b),l=C[i+20>>2],f=_(C[i+4>>2]-l),r=_(_(c*t)-_(o*f)),u=r,v=_(r*r),r=_(n*f),s=C[i+24>>2],f=_(C[i+8>>2]-s),r=_(r-_(c*f)),t=_(_(o*f)-_(n*t)),f=_(_(1)/_(y(_(v+_(_(r*r)+_(t*t)))))),u=_(u*f),r=_(r*f),t=_(t*f),_(_(_(C[e+8>>2]*u)+_(_(C[e>>2]*r)+_(C[e+4>>2]*t)))-_(_(s*u)+_(_(b*r)+_(l*t))))>2]+104>>2]](A,1,i+16|0,i),b=C[i+16>>2],t=_(C[i>>2]-b),l=C[i+20>>2],f=_(C[i+4>>2]-l),r=_(_(c*t)-_(o*f)),u=r,v=_(r*r),r=_(n*f),s=C[i+24>>2],f=_(C[i+8>>2]-s),r=_(r-_(c*f)),t=_(_(o*f)-_(n*t)),f=_(_(1)/_(y(_(v+_(_(r*r)+_(t*t)))))),u=_(u*f),r=_(r*f),t=_(t*f),_(_(_(C[e+8>>2]*u)+_(_(C[e>>2]*r)+_(C[e+4>>2]*t)))-_(_(s*u)+_(_(b*r)+_(l*t))))>2]+104>>2]](A,2,i+16|0,i),t=C[i+16>>2],f=_(C[i>>2]-t),b=C[i+20>>2],l=_(C[i+4>>2]-b),r=_(_(c*f)-_(o*l)),u=r,s=_(r*r),v=_(n*l),r=c,c=C[i+24>>2],l=_(C[i+8>>2]-c),r=_(v-_(r*l)),n=_(_(o*l)-_(n*f)),o=_(_(1)/_(y(_(s+_(_(r*r)+_(n*n)))))),f=_(u*o),r=_(r*o),n=_(n*o),_(_(_(C[e+8>>2]*f)+_(_(C[e>>2]*r)+_(C[e+4>>2]*n)))-_(_(c*f)+_(_(t*r)+_(b*n))))>2],b=C[A+76>>2],l=C[A+80>>2],s=C[A+100>>2],e=A+68|0,o=C[e>>2],k=C[A+84>>2],u=C[A+96>>2],t=C[A- -64>>2],n=C[A+60>>2],a[r+12>>2]=0,b=_(b-n),u=_(u-t),l=_(l-t),n=_(c-n),t=_(_(b*u)-_(l*n)),v=t,d=_(t*t),t=_(s-o),c=_(k-o),o=_(_(l*t)-_(c*u)),t=_(_(c*n)-_(b*t)),n=_(_(1)/_(y(_(d+_(_(o*o)+_(t*t)))))),C[r+8>>2]=v*n,C[r+4>>2]=t*n,C[r>>2]=o*n,f=a[e+4>>2],r=i+8|0,a[r>>2]=a[e>>2],a[r+4>>2]=f,e=a[A+64>>2],a[i>>2]=a[A+60>>2],a[i+4>>2]=e},ce,function(A,e){return A|=0,e|=0,A=a[a[A+4>>2]>>2],0|Qt[a[a[A>>2]+128>>2]](A,e)},sA,ve,function(A,e){var r,i;return A|=0,e|=0,r=a[A+4>>2],i=a[r>>2],Qt[a[a[i>>2]+104>>2]](i,e,r+4|0),a[A+4>>2]+4|0},ve,function(A,e){var r,i;return A|=0,e|=0,r=a[A+4>>2],i=a[r>>2],Qt[a[a[i>>2]+108>>2]](i,e,r+112|0),a[A+4>>2]+112|0},ve,sA,ve,function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f,t,n=0,c=0,b=0;f=Y-144|0,Y=f,t=zA(f+32|0),c=e+8|0,b=a[c+4>>2],n=f+100|0,a[n>>2]=a[c>>2],a[n+4>>2]=b,c=a[e+20>>2],n=f+108|0,a[n>>2]=a[e+16>>2],a[n+4>>2]=c,c=e+24|0,b=a[c+4>>2],n=f+116|0,a[n>>2]=a[c>>2],a[n+4>>2]=b,c=a[e+36>>2],n=f+124|0,a[n>>2]=a[e+32>>2],a[n+4>>2]=c,c=e+40|0,b=a[c+4>>2],n=f+132|0,a[n>>2]=a[c>>2],a[n+4>>2]=b,a[f+36>>2]=1,a[f+32>>2]=8128,n=a[e+4>>2],a[f+92>>2]=a[e>>2],a[f+96>>2]=n,a[f+80>>2]=a[A+24>>2],e=a[A+4>>2],b=o[A+20|0],b?(a[e+28>>2]=r,n=e+24|0):(a[e+36>>2]=r,n=e+32|0),a[n>>2]=i,n=a[A+12>>2],c=a[n+8>>2],a[f+20>>2]=a[n+12>>2],a[f+16>>2]=c,a[f+28>>2]=i,a[f+24>>2]=r,a[f+8>>2]=n,r=a[e+16>>2],i=a[r+8>>2],n=a[i+8>>2],a[f+12>>2]=f+32,(0|n)==(0|c)?r=r+8|0:(i=a[r+12>>2],r=r+12|0),a[r>>2]=f+8,me(e,a[A+8>>2],f+8|0,a[A+16>>2],f+32|0,0!=(0|b)),A=a[a[A+4>>2]+16>>2],a[(a[a[A+8>>2]+8>>2]==a[f+16>>2]?8:12)+A>>2]=i,Ae(t),Y=f+144|0},sA,ve,function(A,e,r,i){return A|=0,e|=0,A=a[e>>2],A=0|Qt[a[a[A>>2]+56>>2]](A,40),vA(A,e),a[A>>2]=8056,a[A+8>>2]=0,a[A+12>>2]=0,0|A},Ze,function(A){var e;A|=0,a[A>>2]=8964,e=a[A+296>>2],e&&(o[A+300|0]&&CA(e),a[A+296>>2]=0),a[A+296>>2]=0,a[A+288>>2]=0,a[A+292>>2]=0,f[A+300|0]=1,CA(A)},function(A,e){A|=0,e|=0,a[A+200>>2]=e,a[A+192>>2]=e,a[A+304>>2]=a[A+304>>2]+1},function(A,e){A|=0,e|=0;var r,i=0;r=a[A+288>>2],i=r;A:if(!((0|r)<1)){for(A=a[A+296>>2],i=0;;){if(a[A>>2]==(0|e))break A;if(A=A+4|0,i=i+1|0,(0|i)==(0|r))break}i=r}return(0|i)>=(0|r)|0},function(A){return 264},Ne,function(A,e){A|=0,e|=0;var r,i=0,f=0,t=0,n=0,o=0;t=e,n=0|Qt[a[a[A>>2]+16>>2]](A),o=1,f=a[a[e>>2]+16>>2],i=0|Qt[f](0|t,0|n,0|o),o=e,n=i,t=0|Qt[a[a[A>>2]+20>>2]](A,a[i+8>>2],e),r=A,f=a[a[e>>2]+20>>2],Qt[f](0|o,0|n,0|t,1245859651,0|r)},ce,Je,xe,function(A,e,r){A|=0,e=_(e),r|=0;var i=_(0),f=_(0),t=_(0),n=_(0),o=_(0),c=_(0);i=C[A+40>>2],f=C[A+36>>2],t=C[A+32>>2],n=_(Qt[a[a[A>>2]+48>>2]](A)),o=_(Qt[a[a[A>>2]+48>>2]](A)),c=_(Qt[a[a[A>>2]+48>>2]](A)),a[r+12>>2]=0,e=_(e/_(12)),t=_(t+n),t=_(t+t),t=_(t*t),f=_(f+o),f=_(f+f),f=_(f*f),C[r+8>>2]=e*_(t+f),i=_(i+c),i=_(i+i),i=_(i*i),C[r+4>>2]=e*_(t+i),C[r>>2]=e*_(f+i)},function(A){return 9212},Ie,function(A,e,r){A|=0,e|=0,r|=0;var i=_(0),f=_(0),t=_(0),n=_(0),o=_(0),c=_(0);i=C[e+36>>2],f=C[e+40>>2],t=C[e+32>>2],n=_(Qt[a[a[e>>2]+48>>2]](e)),o=_(Qt[a[a[e>>2]+48>>2]](e)),c=_(Qt[a[a[e>>2]+48>>2]](e)),a[A+12>>2]=0,f=_(f+c),C[A+8>>2]=C[r+8>>2]>=_(0)?f:_(-f),i=_(i+o),C[A+4>>2]=C[r+4>>2]>=_(0)?i:_(-i),i=_(t+n),C[A>>2]=C[r>>2]>=_(0)?i:_(-i)},function(A,e,r){A|=0,e|=0,r|=0;var i=_(0);a[A+12>>2]=0,i=C[e+32>>2],C[A>>2]=C[r>>2]>=_(0)?i:_(-i),i=C[e+40>>2],C[A+8>>2]=C[r+8>>2]>=_(0)?i:_(-i),i=C[e+36>>2],C[A+4>>2]=C[r+4>>2]>=_(0)?i:_(-i)},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f=0,t=0,n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0);if((0|i)>=1)for(;f=e+t|0,b=C[f+4>>2],l=C[f+8>>2],u=C[f>>2],n=C[A+36>>2],o=C[A+40>>2],c=C[A+32>>2],f=r+t|0,a[f+12>>2]=0,C[f>>2]=u>=_(0)?c:_(-c),C[f+8>>2]=l>=_(0)?o:_(-o),C[f+4>>2]=b>=_(0)?n:_(-n),t=t+16|0,i=i+-1|0,i;);},Ue,function(A,e,r){A|=0,e|=0,r|=0,e>>>0<=5&&(a[r+12>>2]=0,A=e<<2,a[r+8>>2]=a[A+9264>>2],a[r+4>>2]=a[A+9240>>2],a[r>>2]=a[A+9216>>2])},function(A){return 8},yA,function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f,t=0,n=0;f=A,e>>>0<=11&&(e<<=2,t=a[e+9336>>2],n=a[e+9288>>2]),Qt[a[a[A>>2]+108>>2]](f,n,r),Qt[a[a[A>>2]+108>>2]](A,t,i)},function(A,e,r){A|=0,e|=0,r|=0;var i=_(0),f=_(0),t=_(0),n=_(0),o=_(0),c=_(0);f=C[A+40>>2],i=C[A+36>>2],t=C[A+32>>2],n=_(Qt[a[a[A>>2]+48>>2]](A)),o=_(Qt[a[a[A>>2]+48>>2]](A)),c=_(Qt[a[a[A>>2]+48>>2]](A)),a[r+12>>2]=0,i=_(i+o),A=e>>>1&1,C[r+4>>2]=_(i*_(1^A))-_(i*_(0|A)),i=_(t+n),A=1&e,C[r>>2]=_(i*_(1^A))-_(i*_(0|A)),f=_(f+c),A=e>>>2&1,C[r+8>>2]=_(f*_(1^A))-_(f*_(0|A))},Ue,function(A,e,r,i){var f,t,n;A|=0,e|=0,r|=0,i|=0,f=Y-48|0,Y=f,Qt[a[a[A>>2]+124>>2]](A,f+32|0,i),a[e+12>>2]=0,i=a[f+40>>2],a[e+8>>2]=i,t=a[f+36>>2],a[e+4>>2]=t,n=e,e=a[f+32>>2],a[n>>2]=e,a[f+12>>2]=0,a[f+8>>2]=-2147483648^i,a[f+4>>2]=-2147483648^t,a[f>>2]=-2147483648^e,Qt[a[a[A>>2]+64>>2]](f+16|0,A,f),e=f+24|0,i=a[e+4>>2],A=r+8|0,a[A>>2]=a[e>>2],a[A+4>>2]=i,A=a[f+20>>2],a[r>>2]=a[f+16>>2],a[r+4>>2]=A,Y=f+48|0},function(A,e,r){A|=0,e|=0,r=_(r);var i=_(0),f=_(0),t=0;return i=C[e>>2],f=C[A+32>>2],i<=_(f+r)^1|i>=_(_(-f)-r)^1||(i=C[e+4>>2],f=C[A+36>>2],i<=_(f+r)^1|i>=_(_(-f)-r)^1||(i=C[e+8>>2],f=C[A+40>>2],i<=_(f+r)&&(t=i>=_(_(-f)-r)))),0|t},function(A,e,r){A|=0,e|=0,r|=0;var i=0,f=_(0),t=_(0),n=_(0);if(r>>>0<=5){t=C[A+40>>2],n=C[A+36>>2],f=C[A+32>>2],A=1065353216,i=r;A:{e:{r:{i:switch(r-1|0){case 0:r=0,A=-1082130432,i=0;break A;case 1:r=1065353216;break e;case 2:r=-1082130432;break e;case 3:i=1065353216;break r;case 4:break i;default:break A}i=-1082130432}A=0,f=t,r=0;break A}A=0,f=n,i=0}a[e+8>>2]=i,a[e+4>>2]=r,a[e>>2]=A,C[e+12>>2]=-f}},pA,Je,xe,function(A,e,r){A|=0,e=_(e),r|=0;var i,f,t,n,o=_(0),c=_(0),b=_(0),l=_(0),u=0,s=_(0);i=Y-16|0,Y=i,u=A+40|0,t=a[u+4>>2],f=i+8|0,a[f>>2]=a[u>>2],a[f+4>>2]=t,u=a[A+36>>2],a[i>>2]=a[A+32>>2],a[i+4>>2]=u,o=_(Qt[a[a[A>>2]+48>>2]](A)),l=_(Qt[a[a[A>>2]+48>>2]](A)),n=f,s=_(_(Qt[a[a[A>>2]+48>>2]](A))+C[f>>2]),C[n>>2]=s,C[i>>2]=o+C[i>>2],C[i+4>>2]=l+C[i+4>>2],o=_(e*_(.5)),l=_(e*_(.25)),e=_(e/_(12));A:{e:if(A=a[A+56>>2],!(A>>>0>2)){switch(A-1|0){default:b=o,o=C[i+4>>2],c=_(o*o),o=_(b*c),b=e,e=C[i>>2],c=_(_(l*c)+_(b*_(e*_(e*_(4))))),b=c;break A;case 0:break e;case 1:}c=o,o=C[i>>2],o=_(o*o),b=_(c*o),c=e,e=C[i+8>>2],o=_(_(l*o)+_(c*_(e*_(e*_(4))))),c=o;break A}c=o,o=C[i>>2],o=_(o*o),c=_(c*o),b=e,e=C[i+4>>2],o=_(_(l*o)+_(b*_(e*_(e*_(4))))),b=o}a[r+12>>2]=0,C[r+8>>2]=b,C[r+4>>2]=c,C[r>>2]=o,Y=i+16|0},function(A){return 9792},FA,Ie,wA,function(A,e,r){return A|=0,e|=0,r|=0,QA(A,e,r),a[e+28>>2]=a[A+32>>2],a[e+32>>2]=a[A+36>>2],a[e+36>>2]=a[A+40>>2],a[e+40>>2]=a[A+44>>2],a[e+12>>2]=a[A+16>>2],a[e+16>>2]=a[A+20>>2],a[e+20>>2]=a[A+24>>2],a[e+24>>2]=a[A+28>>2],a[e+48>>2]=0,a[e+44>>2]=a[A+48>>2],A=a[A+56>>2],a[e+56>>2]=0,a[e+52>>2]=A,9802},function(A,e,r){A|=0,e|=0,r|=0;var i,f,t,n=_(0),o=_(0),c=_(0),b=0,l=_(0),u=_(0);i=Y-16|0,Y=i,Qt[a[a[e>>2]+68>>2]](i,e,r),f=i+8|0,t=a[f+4>>2],b=A+8|0,a[b>>2]=a[f>>2],a[b+4>>2]=t,b=a[i+4>>2],a[A>>2]=a[i>>2],a[A+4>>2]=b,_(Qt[a[a[e>>2]+48>>2]](e))!=_(0)&&(o=C[r+4>>2],n=C[r>>2],c=C[r+8>>2],l=_(Qt[a[a[e>>2]+48>>2]](e)),e=_(_(_(n*n)+_(o*o))+_(c*c))<_(1.4210854715202004e-14),n=e?_(-1):n,u=n,c=e?_(-1):c,o=e?_(-1):o,n=_(_(1)/_(y(_(_(c*c)+_(_(n*n)+_(o*o)))))),C[A>>2]=C[A>>2]+_(l*_(u*n)),C[A+4>>2]=C[A+4>>2]+_(l*_(o*n)),C[A+8>>2]=C[A+8>>2]+_(l*_(c*n))),Y=i+16|0},function(A,e,r){A|=0,e|=0,r|=0;var i=_(0),f=_(0),t=_(0),n=_(0),a=_(0),o=_(0);i=C[e+36>>2],f=C[e+32>>2],t=C[r>>2],n=C[r+8>>2],a=_(y(_(_(t*t)+_(n*n)))),a==_(0)?i=C[r+4>>2]<_(0)?_(-i):i:(f=_(f/a),o=_(n*f),f=_(t*f),i=C[r+4>>2]<_(0)?_(-i):i),C[A+8>>2]=o,C[A+4>>2]=i,C[A>>2]=f},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f=_(0),t=_(0),n=_(0),a=_(0),o=_(0);if((0|i)>=1)for(;f=C[A+36>>2],t=C[A+32>>2],a=C[e>>2],n=C[e+8>>2],o=_(y(_(_(a*a)+_(n*n)))),o==_(0)?(n=_(0),f=C[e+4>>2]<_(0)?_(-f):f):(t=_(t/o),n=_(n*t),t=_(a*t),f=C[e+4>>2]<_(0)?_(-f):f),C[r>>2]=t,C[r+8>>2]=n,C[r+4>>2]=f,r=r+16|0,e=e+16|0,i=i+-1|0,i;);},Me,pA,function(A){return 9822},function(A,e,r){A|=0,e|=0,r|=0;var i=_(0),f=_(0),t=_(0),n=_(0),a=_(0),o=_(0);f=C[e+36>>2],i=C[e+32>>2],t=C[r+4>>2],n=C[r+8>>2],a=_(y(_(_(t*t)+_(n*n)))),a==_(0)?i=C[r>>2]<_(0)?_(-i):i:(f=_(f/a),o=_(n*f),f=_(t*f),i=C[r>>2]<_(0)?_(-i):i),C[A+8>>2]=o,C[A>>2]=i,C[A+4>>2]=f},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f=_(0),t=_(0),n=_(0),a=_(0),o=_(0),c=0;if((0|i)>=1)for(;f=C[A+32>>2],t=C[A+36>>2],c=r,a=C[e+4>>2],n=C[e+8>>2],o=_(y(_(_(a*a)+_(n*n)))),o==_(0)?(n=_(0),f=C[e>>2]<_(0)?_(-f):f):(t=_(t/o),n=_(n*t),t=_(a*t),f=C[e>>2]<_(0)?_(-f):f),C[c>>2]=f,C[r+8>>2]=n,C[r+4>>2]=t,r=r+16|0,e=e+16|0,i=i+-1|0,i;);},function(A){A|=0;var e=_(0),r=_(0);return e=C[A+36>>2],_(Qt[a[a[A>>2]+48>>2]](A)),r=_(Qt[a[a[A>>2]+48>>2]](A)),_(Qt[a[a[A>>2]+48>>2]](A)),_(_(e+r))},pA,function(A){return 9832},function(A,e,r){A|=0,e|=0,r|=0;var i=_(0),f=_(0),t=_(0),n=_(0),a=_(0),o=_(0);i=C[e+40>>2],f=C[e+32>>2],e=A,t=C[r>>2],n=C[r+4>>2],a=_(y(_(_(t*t)+_(n*n)))),a==_(0)?i=C[r+8>>2]<_(0)?_(-i):i:(f=_(f/a),o=_(n*f),f=_(t*f),i=C[r+8>>2]<_(0)?_(-i):i),C[e+8>>2]=i,C[A>>2]=f,C[A+4>>2]=o},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f=_(0),t=_(0),n=_(0),a=_(0),o=_(0);if((0|i)>=1)for(;f=C[A+40>>2],t=C[A+32>>2],a=C[e>>2],n=C[e+4>>2],o=_(y(_(_(a*a)+_(n*n)))),o==_(0)?(n=_(0),f=C[e+8>>2]<_(0)?_(-f):f):(t=_(t/o),n=_(n*t),t=_(a*t),f=C[e+8>>2]<_(0)?_(-f):f),C[r>>2]=t,C[r+8>>2]=f,C[r+4>>2]=n,r=r+16|0,e=e+16|0,i=i+-1|0,i;);},Me,pA,function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f,t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0);c=_(Qt[a[a[A>>2]+48>>2]](A)),b=_(Qt[a[a[A>>2]+48>>2]](A)),l=_(Qt[a[a[A>>2]+48>>2]](A)),A=e+52|0,t=C[A>>2],f=e+56|0,n=C[f>>2],o=C[e+48>>2],a[r+12>>2]=0,C[r+8>>2]=n-l,C[r+4>>2]=t-b,C[r>>2]=o-c,t=C[A>>2],n=C[f>>2],o=C[e+48>>2],a[i+12>>2]=0,C[i+8>>2]=l+n,C[i+4>>2]=b+t,C[i>>2]=c+o},function(A,e,r){A|=0,e=_(e),r|=0;var i=_(0),f=_(0);i=_(Qt[a[a[A>>2]+48>>2]](A)),f=_(Qt[a[a[A>>2]+48>>2]](A)),a[r+12>>2]=0,e=_(f*_(i*_(e*_(.4000000059604645)))),C[r+8>>2]=e,C[r+4>>2]=e,C[r>>2]=e},function(A){return 9972},Ge,function(A){return A|=0,_(_(C[A+32>>2]*C[A+16>>2]))},function(A,e,r){A|=0,e|=0,r|=0;var i,f,t,n=_(0),o=_(0),c=_(0),b=0,l=_(0),u=_(0);i=Y-16|0,Y=i,Qt[a[a[e>>2]+68>>2]](i,e,r),t=i+8|0,b=a[t+4>>2],f=A+8|0,a[f>>2]=a[t>>2],a[f+4>>2]=b,b=a[i+4>>2],a[A>>2]=a[i>>2],a[A+4>>2]=b,o=C[r+4>>2],n=C[r>>2],c=C[r+8>>2],l=_(Qt[a[a[e>>2]+48>>2]](e)),e=_(_(_(n*n)+_(o*o))+_(c*c))<_(1.4210854715202004e-14),n=e?_(-1):n,u=n,c=e?_(-1):c,o=e?_(-1):o,n=_(_(1)/_(y(_(_(c*c)+_(_(n*n)+_(o*o)))))),C[A>>2]=C[A>>2]+_(l*_(u*n)),C[A+4>>2]=C[A+4>>2]+_(l*_(o*n)),C[f>>2]=C[f>>2]+_(l*_(c*n)),Y=i+16|0},function(A,e,r){A|=0,a[A>>2]=0,a[A+4>>2]=0,A=A+8|0,a[A>>2]=0,a[A+4>>2]=0},function(A,e,r,i){r|=0,i|=0,(0|i)>=1&&X(r,0,i<<4)},sA,ve,Oe,ve,Oe,sA,kA,function(A,e){A|=0,e=_(e),C[A+16>>2]=e},function(A){return A|=0,_(C[A+16>>2])},sA,pA,function(A,e,r,i){r|=0,i|=0,a[r+8>>2]=-581039253,a[r+12>>2]=0,a[r>>2]=-581039253,a[r+4>>2]=-581039253,a[i+8>>2]=1566444395,a[i+12>>2]=0,a[i>>2]=1566444395,a[i+4>>2]=1566444395},function(A,e){A|=0,e|=0;var r=0;r=a[e+4>>2],a[A+72>>2]=a[e>>2],a[A+76>>2]=r,e=e+8|0,r=a[e+4>>2],A=A+80|0,a[A>>2]=a[e>>2],a[A+4>>2]=r},ze,he,function(A){return 10516},ye,function(A,e,r){return A|=0,e|=0,r|=0,QA(A,e,r),a[e+12>>2]=a[A+72>>2],a[e+16>>2]=a[A+76>>2],a[e+20>>2]=a[A+80>>2],a[e+24>>2]=a[A+84>>2],a[e+28>>2]=a[A+52>>2],a[e+32>>2]=a[A+56>>2],a[e+36>>2]=a[A+60>>2],a[e+40>>2]=a[A- -64>>2],A=a[A+68>>2],a[e+48>>2]=0,a[e+44>>2]=A,10528},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f,t,n,o,c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),p=_(0),F=_(0);f=Y-48|0,Y=f,k=C[i>>2],u=C[r>>2],l=_(_(k-u)*_(.5)),s=_(l*l),b=C[i+4>>2],c=C[r+4>>2],l=_(_(b-c)*_(.5)),g=_(s+_(l*l)),s=C[i+8>>2],v=C[r+8>>2],l=_(_(s-v)*_(.5)),l=_(y(_(g+_(l*l)))),s=_(_(s+v)*_(.5)),v=_(_(b+c)*_(.5)),B=_(_(k+u)*_(.5)),k=C[A+60>>2],_(m(k))>_(.7071067690849304)?(u=C[A+56>>2],b=_(_(k*k)+_(u*u)),c=_(_(1)/_(y(b))),R=_(b*c),b=C[A+52>>2],d=_(u*c),Q=_(-_(b*d)),c=_(-_(k*c)),h=_(b*c)):(b=C[A+52>>2],u=C[A+56>>2],R=_(_(b*b)+_(u*u)),c=_(_(1)/_(y(R))),h=_(R*c),p=_(-_(u*c)),Q=_(k*p),c=_(b*c),R=_(-_(k*c))),G=C[A+68>>2],A=f+44|0,a[A>>2]=0,r=f+28|0,a[r>>2]=0,i=f+40|0,g=s,s=_(_(_(k*s)+_(_(B*b)+_(v*u)))-G),G=_(g-_(k*s)),d=_(l*d),g=_(G-d),k=_(l*h),h=_(g-k),C[i>>2]=h,t=f+36|0,v=_(v-_(u*s)),c=_(l*c),F=_(v-c),u=_(l*Q),Q=_(F-u),C[t>>2]=Q,n=f+24|0,d=_(d+G),C[n>>2]=d-k,o=f+20|0,c=_(c+v),C[o>>2]=c-u,a[f+12>>2]=0,b=_(B-_(b*s)),s=_(l*p),v=_(b-s),l=_(l*R),B=_(v-l),C[f+32>>2]=B,b=_(s+b),C[f+16>>2]=b-l,s=_(k+d),C[f+8>>2]=s,c=_(u+c),C[f+4>>2]=c,b=_(l+b),C[f>>2]=b,Qt[a[a[e>>2]+8>>2]](e,f,0,0),a[A>>2]=0,C[i>>2]=s,C[t>>2]=c,a[r>>2]=0,C[n>>2]=k+g,C[o>>2]=u+F,C[f+32>>2]=b,C[f+16>>2]=l+v,a[f+12>>2]=0,C[f+8>>2]=h,C[f+4>>2]=Q,C[f>>2]=B,Qt[a[a[e>>2]+8>>2]](e,f,0,1),Y=f+48|0},Ke,function(A){var e;A|=0,a[A>>2]=11012,e=a[A+88>>2],e&&(o[A+92|0]&&CA(e),a[A+88>>2]=0),a[A+88>>2]=0,a[A+80>>2]=0,a[A+84>>2]=0,f[A+92|0]=1,CA(A)},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0);h=C[e+52>>2],l=C[e+24>>2],v=C[e+20>>2],f=C[e+56>>2],u=C[e+40>>2],n=C[A+44>>2],o=C[A+28>>2],c=C[A+36>>2],s=C[e+36>>2],b=C[A+40>>2],t=C[A+24>>2],G=C[e+48>>2],d=C[e+8>>2],g=C[e>>2],B=C[e+4>>2],R=C[e+16>>2],Q=C[e+32>>2],k=C[A+20>>2],a[r+12>>2]=0,y=f,f=_(_(k+c)*_(.5)),t=_(_(t+b)*_(.5)),o=_(_(o+n)*_(.5)),k=_(y+_(_(_(Q*f)+_(s*t))+_(u*o))),c=_(c-f),b=_(b-t),n=_(n-o),u=_(_(_(c*_(m(Q)))+_(b*_(m(s))))+_(n*_(m(u)))),C[r+8>>2]=k-u,s=_(h+_(_(_(f*R)+_(t*v))+_(o*l))),l=_(_(_(c*_(m(R)))+_(b*_(m(v))))+_(n*_(m(l)))),C[r+4>>2]=s-l,f=_(G+_(_(_(f*g)+_(t*B))+_(o*d))),t=_(_(_(c*_(m(g)))+_(b*_(m(B))))+_(n*_(m(d)))),C[r>>2]=f-t,a[i+12>>2]=0,C[i+8>>2]=u+k,C[i+4>>2]=l+s,C[i>>2]=t+f},function(A,e){A|=0,e|=0;var r=0,i=0;i=a[e+4>>2],r=A+160|0,a[r>>2]=a[e>>2],a[r+4>>2]=i,e=e+8|0,i=a[e+4>>2],r=A+168|0,a[r>>2]=a[e>>2],a[r+4>>2]=i,Qt[a[a[A>>2]+72>>2]](A)},function(A){return A|=0,A+160|0},function(A,e,r){A|=0,e=_(e),r|=0;var i=0,f=_(0),t=_(0),n=0,o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=0,k=0;if(Qt[a[a[A>>2]+112>>2]](A),i=r+8|0,a[i>>2]=0,a[i+4>>2]=0,a[r>>2]=0,a[r+4>>2]=0,n=a[A+188>>2],n)if(e=_(e/_(0|n)),i=a[A+196>>2],k=a[A+184>>2],1==a[A+192>>2])for(s=0-i|0,i=B(i,n+-1|0)+k|0;f=C[A+168>>2],o=_(g[i>>3]*+C[A+160>>2]),o=_(o*o),t=_(g[i+8>>3]*+C[A+164>>2]),t=_(t*t),b=_(_(e*_(o+t))+b),C[r+8>>2]=b,f=_(g[i+16>>3]*+f),f=_(f*f),l=_(_(e*_(o+f))+l),C[r+4>>2]=l,u=_(u+_(e*_(t+f))),C[r>>2]=u,i=i+s|0,n=n+-1|0,n;);else for(s=0-i|0,i=B(i,n+-1|0)+k|0;f=C[i+8>>2],o=C[A+168>>2],t=_(C[i>>2]*C[A+160>>2]),t=_(t*t),c=_(C[i+4>>2]*C[A+164>>2]),c=_(c*c),b=_(_(e*_(t+c))+b),C[r+8>>2]=b,f=_(f*o),f=_(f*f),l=_(_(e*_(t+f))+l),C[r+4>>2]=l,u=_(u+_(e*_(c+f))),C[r>>2]=u,i=i+s|0,n=n+-1|0,n;);Qt[a[a[A>>2]+116>>2]](A)},function(A){return 11292},function(A,e){A|=0,e=_(e),C[A+152>>2]=e,Qt[a[a[A>>2]+72>>2]](A)},function(A){return A|=0,_(C[A+152>>2])},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var t,n=0,c=0,b=0;if(t=Y-128|0,Y=t,Qt[a[a[A>>2]+112>>2]](A),c=r+8|0,b=a[c+4>>2],n=t+104|0,a[n>>2]=a[c>>2],a[n+4>>2]=b,c=i+8|0,b=a[c+4>>2],n=t+120|0,a[n>>2]=a[c>>2],a[n+4>>2]=b,n=a[r+4>>2],a[t+96>>2]=a[r>>2],a[t+100>>2]=n,r=a[i+4>>2],a[t+112>>2]=a[i>>2],a[t+116>>2]=r,a[t+84>>2]=0,f[t+88|0]=1,a[t+76>>2]=0,a[t+80>>2]=0,_A(A+72|0,t+96|0,t+72|0),r=a[t+76>>2],r)for(n=a[A+176>>2],a[t+64>>2]=1008981770,i=(r<<2)-4|0;c=a[a[t+84>>2]+i>>2],b=0|Qt[a[a[A>>2]+84>>2]](A),Qt[a[a[b>>2]+20>>2]](b,c,t),Qt[a[a[e>>2]+8>>2]](e,t,n,a[a[t+84>>2]+i>>2]),i=i+-4|0,r=r+-1|0,r;);Qt[a[a[A>>2]+116>>2]](A),A=a[t+84>>2],A&&(o[t+88|0]&&CA(A),a[t+84>>2]=0),Y=t+128|0},function(A){A|=0;var e,r,i,n,c,b=0,l=_(0),u=_(0),s=_(0),k=_(0),d=_(0),g=_(0);Qt[a[a[A>>2]+112>>2]](A),b=A+72|0,a[A+72>>2]?function(A){var e,r=0,i=0,f=_(0),n=_(0),o=_(0),c=0,b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=0,Q=_(0),h=_(0),G=0,y=0,p=0,F=0,W=0,w=_(0),D=_(0),E=_(0),Z=_(0),V=0;if(e=Y+-64|0,Y=e,r=a[A>>2],r)for(G=r<<4,y=r+1|0,p=a[A+16>>2],F=e+16|0,W=e+48|0;c=G+p|0,r=a[c+-4>>2],(0|r)>=0?(c=a[A+72>>2],Qt[a[a[c>>2]+16>>2]](c,r,e+32|0),b=C[e+32>>2],f=C[e+36>>2],p=a[A+16>>2],c=p+G|0,r=c+-12|0,l=C[A+48>>2],n=C[A+32>>2],o=C[e+40>>2],o=o>2],o=_(_(_((l=_(0)?~~o>>>0:0,t[r>>1]=i,r=c+-14|0,s=C[A+44>>2],o=C[A+28>>2],f=f>2],f=_(_(_((s=_(0)?~~f>>>0:0,t[r>>1]=i,r=c+-16|0,u=C[A+40>>2],f=C[A+24>>2],b=b>2],b=_(_(_((u=_(0)?~~b>>>0:0,t[r>>1]=i,b=C[e+48>>2],b=b=_(0)?~~f>>>0:0,f=C[e+56>>2],u=C[e+52>>2],t[c+-10>>1]=r,r=c+-8|0,u=u=_(0)?~~o>>>0:0,t[r>>1]=i,r=c+-6|0,o=f=_(0)?~~n>>>0:0,t[r>>1]=c):(a[e+56>>2]=-8388609,a[e+48>>2]=-8388609,a[e+52>>2]=-8388609,a[e+36>>2]=2139095039,a[e+40>>2]=2139095039,r=v[c>>1],i=v[c+2>>1],R=v[c+4>>1],a[e+12>>2]=0,g=C[A+64>>2],s=C[A+32>>2],l=_(_(_(R>>>0)/g)+s),C[e+8>>2]=l,B=C[A+60>>2],u=C[A+28>>2],o=_(_(_(i>>>0)/B)+u),C[e+4>>2]=o,m=C[A+56>>2],b=C[A+24>>2],n=_(_(_(r>>>0)/m)+b),C[e>>2]=n,r=v[c+6>>1],i=v[c+8>>1],R=v[c+10>>1],a[e+28>>2]=0,d=_(s+_(_(R>>>0)/g)),C[e+24>>2]=d,h=_(u+_(_(i>>>0)/B)),C[e+20>>2]=h,f=_(b+_(_(r>>>0)/m)),C[e+16>>2]=f,Q=n<_(3.4028234663852886e38)?n:_(3.4028234663852886e38),C[e+32>>2]=Q,r=o<_(3.4028234663852886e38)?e:e+32|0,o=C[r+4>>2],r=a[r+4>>2],i=l<_(3.4028234663852886e38)?e:e+32|0,n=C[i+8>>2],a[e+40>>2]=a[i+8>>2],k=f>_(-3.4028234663852886e38)?f:_(-3.4028234663852886e38),C[e+48>>2]=k,a[e+36>>2]=r,r=a[c+12>>2],i=h>_(-3.4028234663852886e38)?F:W,f=C[i+4>>2],a[e+52>>2]=a[i+4>>2],i=d>_(-3.4028234663852886e38)?F:W,l=C[i+8>>2],a[e+56>>2]=a[i+8>>2],r=(((0|r)>-1?r:-1)-r|0)+y|0,r&&(r=(r<<4)+p|0,i=v[r+2>>1],R=v[r+4>>1],V=v[r>>1],a[e+12>>2]=0,d=_(_(_(V>>>0)/m)+b),C[e>>2]=d,w=_(_(_(R>>>0)/g)+s),C[e+8>>2]=w,D=_(_(_(i>>>0)/B)+u),C[e+4>>2]=D,i=v[r+6>>1],R=v[r+8>>1],r=v[r+10>>1],a[e+28>>2]=0,E=_(s+_(_(r>>>0)/g)),C[e+24>>2]=E,Z=_(u+_(_(R>>>0)/B)),C[e+20>>2]=Z,h=_(b+_(_(i>>>0)/m)),C[e+16>>2]=h,r=D>2],r=a[r+4>>2],i=w>2],a[e+40>>2]=a[i+8>>2],k=k>2]=k,Q=Q>d?d:Q,C[e+32>>2]=Q,a[e+36>>2]=r,r=Z>f?F:W,f=C[r+4>>2],a[e+52>>2]=a[r+4>>2],r=E>l?F:W,l=C[r+8>>2],a[e+56>>2]=a[r+8>>2]),r=c+-6|0,d=C[A+48>>2],l=l=_(0)?~~l>>>0:0,t[r>>1]=i,r=c+-8|0,l=C[A+44>>2],f=f=_(0)?~~f>>>0:0,t[r>>1]=i,r=c+-10|0,f=C[A+40>>2],k=k=_(0)?~~k>>>0:0,t[r>>1]=i,r=c+-12|0,n=n=_(0)?~~n>>>0:0,t[r>>1]=i,r=c+-14|0,n=o=_(0)?~~n>>>0:0,t[r>>1]=i,r=c+-16|0,n=Q=_(0)?~~n>>>0:0,t[r>>1]=c),G=G+-16|0,y=y+-1|0,1!=(0|y););Y=e- -64|0}(b):function(A){var e,r,i=0,t=0,n=0,c=0,b=0,l=0,u=0;if(e=Y+-64|0,Y=e,f[e+56|0]=1,a[e+44>>2]=0,a[e+48>>2]=0,a[e+52>>2]=0,i=a[A+72>>2],r=0|Qt[a[a[i>>2]+12>>2]](i),n=e+32|0,i=n,a[i>>2]=0,a[i+4>>2]=0,l=e+24|0,i=l,a[i>>2]=0,a[i+4>>2]=0,t=e+16|0,i=t,a[i>>2]=0,a[i+4>>2]=0,a[e+8>>2]=0,a[e+12>>2]=0,(0|r)<=0)a[e+44>>2]=r;else{if(i=dA(B(r,36)),a[i+32>>2]=0,a[e+52>>2]=i,a[e+48>>2]=r,f[e+56|0]=1,c=a[t+4>>2],b=i+8|0,a[b>>2]=a[t>>2],a[b+4>>2]=c,t=a[e+12>>2],a[i>>2]=a[e+8>>2],a[i+4>>2]=t,t=a[e+28>>2],a[i+16>>2]=a[e+24>>2],a[i+20>>2]=t,t=a[n+4>>2],i=i+24|0,a[i>>2]=a[n>>2],a[i+4>>2]=t,1!=(0|r))for(b=r+-1|0,n=36;c=a[e+12>>2],t=a[e+52>>2]+n|0,i=t,a[i>>2]=a[e+8>>2],a[i+4>>2]=c,c=e+16|0,u=a[c+4>>2],i=i+8|0,a[i>>2]=a[c>>2],a[i+4>>2]=u,i=l,u=a[i+4>>2],c=t+16|0,a[c>>2]=a[i>>2],a[c+4>>2]=u,i=i+8|0,u=a[i+4>>2],c=t+24|0,a[c>>2]=a[i>>2],a[c+4>>2]=u,a[t+32>>2]=0,n=n+36|0,b=b+-1|0,b;);if(a[e+44>>2]=r,!((0|r)<1))for(i=0,n=a[e+52>>2];l=a[A+72>>2],Qt[a[a[l>>2]+16>>2]](l,i,n),a[n+32>>2]=i,n=n+36|0,i=i+1|0,(0|i)<(0|r););}BA(A,e+40|0),A=a[e+52>>2],A&&(o[e+56|0]&&CA(A),a[e+52>>2]=0),Y=e- -64|0}(b),Qt[a[a[A>>2]+116>>2]](A),b=a[A+88>>2],e=v[b+8>>1],r=v[b+10>>1],i=v[b>>1],n=v[b+2>>1],c=v[b+4>>1],b=v[b+6>>1],a[A+48>>2]=0,a[A+32>>2]=0,l=C[A+96>>2],u=C[A+128>>2],C[A+36>>2]=l+_(_(b>>>0)/u),s=C[A+136>>2],k=C[A+104>>2],C[A+28>>2]=_(_(c>>>0)/s)+k,d=C[A+132>>2],g=C[A+100>>2],C[A+24>>2]=_(_(n>>>0)/d)+g,C[A+20>>2]=l+_(_(i>>>0)/u),C[A+44>>2]=k+_(_(r>>>0)/s),C[A+40>>2]=g+_(_(e>>>0)/d)},function(A){A|=0,f[A+52|0]=1},function(A){return 25},We,function(A){return A|=0,A+148|0},function(A){return A|=0,a[A+208>>2]},we,We,we,function(A,e,r){A|=0,e|=0,r|=0,function(A,e,r){var i=_(0),f=0,t=0,n=0;e=a[A+52>>2]+B(a[A+56>>2],e)|0,n=a[A+36>>2],3!=a[A+64>>2]?(f=a[e+8>>2],t=a[e+4>>2],e=a[e>>2]):(f=v[e+4>>1],t=v[e+2>>1],e=v[e>>1]),e=n+B(e,a[A+48>>2])|0,n=r+68|0,1!=a[A+44>>2]?(C[r+60>>2]=C[e>>2]*C[A+12>>2],C[r- -64>>2]=C[e+4>>2]*C[A+16>>2],i=_(C[e+8>>2]*C[A+20>>2])):(C[r+60>>2]=g[e>>3]*+C[A+12>>2],C[r- -64>>2]=g[e+8>>3]*+C[A+16>>2],i=_(g[e+16>>3]*+C[A+20>>2])),C[n>>2]=i,e=a[A+36>>2]+B(a[A+48>>2],t)|0,t=r+84|0,1!=a[A+44>>2]?(C[r+76>>2]=C[e>>2]*C[A+12>>2],C[r+80>>2]=C[e+4>>2]*C[A+16>>2],i=_(C[e+8>>2]*C[A+20>>2])):(C[r+76>>2]=g[e>>3]*+C[A+12>>2],C[r+80>>2]=g[e+8>>3]*+C[A+16>>2],i=_(g[e+16>>3]*+C[A+20>>2])),C[t>>2]=i,e=a[A+36>>2]+B(a[A+48>>2],f)|0,f=r+100|0,1!=a[A+44>>2]?(C[r+92>>2]=C[e>>2]*C[A+12>>2],C[r+96>>2]=C[e+4>>2]*C[A+16>>2],i=_(C[e+8>>2]*C[A+20>>2])):(C[r+92>>2]=g[e>>3]*+C[A+12>>2],C[r+96>>2]=g[e+8>>3]*+C[A+16>>2],i=_(g[e+16>>3]*+C[A+20>>2])),C[f>>2]=i,Qt[a[a[r>>2]+44>>2]](r,C[A+4>>2])}(A+148|0,e,r)},De,function(A){A|=0;var e=0;A=a[A+144>>2],e=a[A+32>>2],(0|e)>=1?a[A+32>>2]=e+1:(e=a[A+8>>2],Qt[a[a[e>>2]+16>>2]](e,A+36|0,A+40|0,A+44|0,A+48|0,A+52|0,A+56|0,A+60|0,A- -64|0,a[A+28>>2]),a[A+32>>2]=1)},function(A){A|=0;var e=0,r=0;A=a[A+144>>2],e=a[A+32>>2],e&&(r=A,(0|e)>=2?A=e+-1|0:(e=a[A+8>>2],Qt[a[a[e>>2]+24>>2]](e,a[A+28>>2]),a[A+36>>2]=0,A=0),a[r+32>>2]=A)},function(A,e,r,i,f){A|=0,e|=0,r|=0,i|=0,f|=0;var t,n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0);t=Y-32|0,Y=t,A=0|Qt[a[a[A>>2]+84>>2]](A),Qt[a[a[A>>2]+16>>2]](A,e,t),p=C[r+56>>2],d=C[r+36>>2],g=C[r+40>>2],B=C[r+32>>2],k=C[r+48>>2],u=C[r+8>>2],R=C[r>>2],Q=C[r+4>>2],c=C[t+16>>2],n=_(_(c+C[t>>2])*_(.5)),e=t+20|0,b=C[e>>2],o=_(_(b+C[t+4>>2])*_(.5)),A=t+24|0,l=C[A>>2],v=_(_(l+C[t+8>>2])*_(.5)),c=_(c-n),s=C[r+16>>2],b=_(b-o),h=C[r+20>>2],l=_(l-v),G=C[r+24>>2],y=_(_(_(c*_(m(s)))+_(b*_(m(h))))+_(l*_(m(G)))),s=_(_(_(_(n*s)+_(o*h))+_(v*G))+C[r+52>>2]),C[e>>2]=y+s,C[t+4>>2]=s-y,k=_(k+_(_(_(n*R)+_(o*Q))+_(v*u))),u=_(_(_(c*_(m(R)))+_(b*_(m(Q))))+_(l*_(m(u)))),C[t>>2]=k-u,e=a[t+4>>2],a[i>>2]=a[t>>2],a[i+4>>2]=e,a[t+12>>2]=0,n=_(p+_(_(_(n*B)+_(o*d))+_(v*g))),o=_(_(_(c*_(m(B)))+_(b*_(m(d))))+_(l*_(m(g)))),C[t+8>>2]=n-o,r=a[t+12>>2],e=i+8|0,a[e>>2]=a[t+8>>2],a[e+4>>2]=r,a[t+28>>2]=0,C[A>>2]=o+n,C[t+16>>2]=u+k,e=a[t+20>>2],a[f>>2]=a[t+16>>2],a[f+4>>2]=e,r=a[A+4>>2],e=f+8|0,a[e>>2]=a[A>>2],a[e+4>>2]=r,Y=t+32|0},oe,oe,De,De,ae,function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var t,n=_(0),c=_(0),b=_(0),l=_(0),u=0,s=0,k=0;if(t=Y-112|0,Y=t,Qt[a[a[A>>2]+112>>2]](A),a[t+100>>2]=0,f[t+104|0]=1,a[t+92>>2]=0,a[t+96>>2]=0,a[t+84>>2]=0,n=_(C[i>>2]-C[r>>2]),c=_(C[i+4>>2]-C[r+4>>2]),b=_(C[i+8>>2]-C[r+8>>2]),l=_(_(1)/_(y(_(_(_(n*n)+_(c*c))+_(b*b))))),C[t+80>>2]=b*l,C[t+76>>2]=c*l,C[t+72>>2]=n*l,function(A,e,r,i){var t,n=_(0),c=0,b=0,l=_(0),u=_(0),s=0,k=0,d=_(0),g=_(0),B=_(0),R=0,Q=0,h=_(0),G=0,y=_(0),p=_(0),F=0,W=_(0),w=_(0),D=_(0);if(t=a[A>>2],(0|t)>=1)for(;;){R=G<<4,c=R+a[A+16>>2]|0,s=v[c+4>>1],d=C[A+64>>2],l=C[A+32>>2],k=v[c+10>>1],b=v[c+2>>1],g=C[A+60>>2],u=C[A+28>>2],Q=v[c+8>>1],B=C[A+24>>2],n=C[A+56>>2],h=_(B+_(_(v[c+6>>1])/n));A:{e:{if(n=_(_(_(_(_(v[c>>1])/n)+B)+h)*_(.5)),B=_(C[r>>2]-n),h=_(h-n),_(B*C[e>>2])>=_(0)&&_(m(B))>h||(n=_(_(_(b>>>0)/g)+u),u=_(u+_(_(Q>>>0)/g)),n=_(_(n+u)*_(.5)),g=_(C[r+4>>2]-n),u=_(u-n),_(g*C[e+4>>2])>=_(0)&&_(m(g))>u||(n=_(_(_(s>>>0)/d)+l),l=_(l+_(_(k>>>0)/d)),n=_(_(n+l)*_(.5)),d=_(C[r+8>>2]-n),n=_(l-n),l=C[e+8>>2],_(d*l)>=_(0)&&_(m(d))>n||(y=C[e+4>>2],W=_(m(y)),w=_(m(l)),_(m(_(_(d*y)-_(g*l))))>_(_(u*w)+_(n*W))||(p=C[e>>2],D=_(m(p)),_(m(_(_(B*l)-_(d*p))))>_(_(h*w)+_(n*D)))))))c=a[c+12>>2]>-1,s=0;else if(k=_(m(_(_(g*p)-_(B*y))))>_(_(h*W)+_(u*D)),s=1^k,F=a[c+12>>2],c=(0|F)>-1,!((0|F)<0|k)){if(b=a[i+4>>2],(0|b)==a[i+8>>2]&&(Q=b?b<<1:1,!((0|b)>=(0|Q)))){Q?(R=dA(Q<<2),b=a[i+4>>2]):R=0,k=a[i+12>>2];r:{if((0|b)>=1)for(c=R,s=k;a[c>>2]=a[s>>2],c=c+4|0,s=s+4|0,b=b+-1|0,b;);else if(!k)break r;o[i+16|0]&&CA(k),a[i+12>>2]=0,b=a[i+4>>2]}a[i+12>>2]=R,f[i+16|0]=1,a[i+8>>2]=Q}a[a[i+12>>2]+(b<<2)>>2]=F,a[i+4>>2]=a[i+4>>2]+1;break e}if(!(c|s)){G=G-a[12+(R+a[A+16>>2]|0)>>2]|0;break A}}G=G+1|0}if(!((0|G)<(0|t)))break}}(A+72|0,t+72|0,r,t+88|0),i=a[t+92>>2],i)for(s=a[A+176>>2],a[t+64>>2]=1008981770,r=(i<<2)-4|0;k=a[a[t+100>>2]+r>>2],u=0|Qt[a[a[A>>2]+84>>2]](A),Qt[a[a[u>>2]+20>>2]](u,k,t),Qt[a[a[e>>2]+8>>2]](e,t,s,a[a[t+100>>2]+r>>2]),r=r+-4|0,i=i+-1|0,i;);Qt[a[a[A>>2]+116>>2]](A),A=a[t+100>>2],A&&(o[t+104|0]&&CA(A),a[t+100>>2]=0),Y=t+112|0},$e,function(A){A|=0,CA($e(A))},function(A,e){A|=0,e|=0;var r=0,i=0,t=0;if(r=a[e+4>>2],a[A+56>>2]=a[e>>2],a[A+60>>2]=r,i=e+8|0,t=a[i+4>>2],r=A- -64|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,r=a[A+156>>2],r)for(i=(r<<2)-4|0;t=a[a[A+164>>2]+i>>2],Qt[a[a[t>>2]+24>>2]](t,e),i=i+-4|0,r=r+-1|0,r;);f[A+52|0]=1},Le,function(A,e,r){A|=0,e=_(e),r|=0;var i,f=0,t=0,n=0;if(i=Y-16|0,Y=i,a[r>>2]=0,a[r+4>>2]=0,f=r+8|0,a[f>>2]=0,a[f+4>>2]=0,f=a[A+156>>2],f)for(e=_(e/_(0|f)),t=(f<<2)-4|0;n=a[a[A+164>>2]+t>>2],Qt[a[a[n>>2]+32>>2]](n,e,i),C[r>>2]=C[i>>2]+C[r>>2],C[r+4>>2]=C[i+4>>2]+C[r+4>>2],C[r+8>>2]=C[i+8>>2]+C[r+8>>2],t=t+-4|0,f=f+-1|0,f;);Y=i+16|0},function(A){return 11313},function(A,e){A|=0,e=_(e);var r=0,i=0,t=0;if(C[A+16>>2]=e,r=a[A+156>>2],r)for(i=(r<<2)-4|0;t=a[a[A+164>>2]+i>>2],Qt[a[a[t>>2]+44>>2]](t,e),i=i+-4|0,r=r+-1|0,r;);f[A+52|0]=1},function(A){return 64},function(A,e,r){var i,f,t;return A|=0,e|=0,r|=0,QA(A,e,r),i=a[A+148>>2],Qt[a[a[i>>2]+56>>2]](i,e+12|0,r),a[e+56>>2]=a[A+16>>2],a[e+40>>2]=a[A+56>>2],a[e+44>>2]=a[A+60>>2],a[e+48>>2]=a[A- -64>>2],a[e+52>>2]=a[A+68>>2],f=e,t=0|Qt[a[a[A>>2]+80>>2]](A),a[f+60>>2]=t,10708},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f=0,t=0,n=0;if(f=a[A+156>>2],f)for(t=(f<<2)-4|0;n=a[a[A+164>>2]+t>>2],Qt[a[a[n>>2]+64>>2]](n,e,r,i),t=t+-4|0,f=f+-1|0,f;);},function(A){A|=0;var e,r=0,i=0,t=0,n=_(0),c=_(0),b=_(0),l=0,u=0,s=0,k=_(0),v=_(0),d=_(0),g=_(0),B=0;if(a[A+20>>2]=2139095039,a[A+24>>2]=2139095039,a[A+44>>2]=-8388609,e=A+36|0,a[e>>2]=-8388609,a[e+4>>2]=-8388609,a[A+28>>2]=2139095039,t=a[A+156>>2],t)for(B=A+20|0,u=(t<<2)-4|0,s=a[A+164>>2],k=_(3.4028234663852886e38),v=_(-3.4028234663852886e38),d=_(-3.4028234663852886e38),n=_(-3.4028234663852886e38),g=_(3.4028234663852886e38),c=_(3.4028234663852886e38);t=t+-1|0,r=a[u+s>>2],o[r+52|0]&&(Qt[a[a[r>>2]+68>>2]](r),f[r+52|0]=0,v=C[A+44>>2],d=C[A+40>>2],g=C[A+24>>2],s=a[A+164>>2],n=C[A+36>>2],c=C[A+20>>2],k=C[A+28>>2]),r=a[u+s>>2],b=C[r+20>>2],c=c>b?b:c,C[A+20>>2]=c,i=r+20|0,l=g>C[r+24>>2]?i:B,g=C[l+4>>2],a[A+24>>2]=a[l+4>>2],i=k>C[r+28>>2]?i:B,k=C[i+8>>2],a[A+28>>2]=a[i+8>>2],i=r+36|0,b=C[i>>2],n=n>2]=n,l=d>2]?i:e,d=C[l+4>>2],a[A+40>>2]=a[l+4>>2],r=v>2]?i:e,v=C[r+8>>2],a[A+44>>2]=a[r+8>>2],u=u+-4|0,t;);},function(A){A|=0;var e=0,r=0,i=0;if(e=a[A+156>>2],e)for(r=(e<<2)-4|0;i=a[a[A+164>>2]+r>>2],Qt[a[a[i>>2]+72>>2]](i),r=r+-4|0,e=e+-1|0,e;);f[A+52|0]=1},pe,we,we,we,we,we,De,De,qe,qe,Ar,oe,oe,De,De,ae,function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f=0,t=0,n=0;if(f=a[A+156>>2],f)for(t=(f<<2)-4|0;n=a[a[A+164>>2]+t>>2],Qt[a[a[n>>2]+144>>2]](n,e,r,i),t=t+-4|0,f=f+-1|0,f;);},Ke,kA,function(A,e){A|=0,e|=0;var r,i=0;i=a[e+4>>2],a[A+56>>2]=a[e>>2],a[A+60>>2]=i,e=e+8|0,r=a[e+4>>2],i=A- -64|0,a[i>>2]=a[e>>2],a[i+4>>2]=r,Qt[a[a[A>>2]+72>>2]](A)},function(A,e){A|=0,e=_(e);var r=0,i=0;if(C[A+16>>2]=e,r=0|Qt[a[a[A>>2]+88>>2]](A),r)for(r=r+-1|0;i=0|Qt[a[a[A>>2]+124>>2]](A,r),Qt[a[a[i>>2]+44>>2]](i,e),r=r+-1|0,-1!=(0|r););f[A+52|0]=1},ae,qe,qe,ae,sA,ve,We,function(A){return A|=0,a[A+60>>2]},function(A,e,r){A|=0,e|=0,r|=0;var i,f=0,t=_(0),n=0,o=0,c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0);i=Y-80|0,Y=i,a[i+72>>2]=1008981770,Qt[a[a[A>>2]+20>>2]](A,e,i+8|0),t=C[i+12>>2],A=i+40|0,e=i+24|0,c=C[i+28>>2],b=C[i+44>>2],f=c>b,n=t>C[(f?A:e)+4>>2],o=n?36:4,k=C[(i+8|0)+(f?o:n?20:o)>>2],u=C[i+16>>2],l=C[i+32>>2],s=C[i+48>>2],f=l>s,n=u>C[(f?A:e)+8>>2],o=n?40:8,v=C[(i+8|0)+(f?o:n?24:o)>>2],f=c>2],o=n?36:4,d=C[(i+8|0)+(f?o:n?20:o)>>2],f=A,A=l>2],f=e?40:8,u=C[(i+8|0)+(A?f:e?24:f)>>2],c=C[i+24>>2],b=C[i+40>>2],A=c>b,l=C[i+8>>2],e=l>(A?b:c),f=e<<5,s=C[(i+8|0)+(A?f:e?16:f)>>2],t=C[i+72>>2],A=c>2]=t+C[(i+8|0)+(A?f:e?16:f)>>2],C[r>>2]=s-t,C[r+24>>2]=t+u,C[r+20>>2]=t+d,C[r+8>>2]=v-t,C[r+4>>2]=k-t,Y=i+80|0},function(A,e,r){A|=0,e|=0,r|=0;var i=_(0),f=0,t=0,n=0;e=a[A+52>>2]+B(a[A+56>>2],e)|0,f=a[A+36>>2],3!=a[A+64>>2]?(t=a[e+8>>2],n=a[e+4>>2],e=a[e>>2]):(t=v[e+4>>1],n=v[e+2>>1],e=v[e>>1]),e=f+B(e,a[A+48>>2])|0,f=r,1!=a[A+44>>2]?(C[r>>2]=C[e>>2]*C[A+12>>2],C[r+4>>2]=C[e+4>>2]*C[A+16>>2],i=_(C[e+8>>2]*C[A+20>>2])):(C[r>>2]=g[e>>3]*+C[A+12>>2],C[r+4>>2]=g[e+8>>3]*+C[A+16>>2],i=_(g[e+16>>3]*+C[A+20>>2])),C[f+8>>2]=i,e=a[A+36>>2]+B(a[A+48>>2],n)|0,f=r+24|0,1!=a[A+44>>2]?(C[r+16>>2]=C[e>>2]*C[A+12>>2],C[r+20>>2]=C[e+4>>2]*C[A+16>>2],i=_(C[e+8>>2]*C[A+20>>2])):(C[r+16>>2]=g[e>>3]*+C[A+12>>2],C[r+20>>2]=g[e+8>>3]*+C[A+16>>2],i=_(g[e+16>>3]*+C[A+20>>2])),C[f>>2]=i,e=a[A+36>>2]+B(a[A+48>>2],t)|0,f=r+40|0,1!=a[A+44>>2]?(C[r+32>>2]=C[e>>2]*C[A+12>>2],C[r+36>>2]=C[e+4>>2]*C[A+16>>2],i=_(C[e+8>>2]*C[A+20>>2])):(C[r+32>>2]=g[e>>3]*+C[A+12>>2],C[r+36>>2]=g[e+8>>3]*+C[A+16>>2],i=_(g[e+16>>3]*+C[A+20>>2])),C[f>>2]=i,a[r+64>>2]=a[A+4>>2]},function(A){A|=0;var e=0;return a[A>>2]=14216,e=a[A+68>>2],e&&(rr(e),CA(a[A+68>>2])),e=a[A+28>>2],e&&(o[A+32|0]&&CA(e),a[A+28>>2]=0),a[A+28>>2]=0,a[A+20>>2]=0,a[A+24>>2]=0,f[A+32|0]=1,0|A},function(A){A|=0;var e=0;a[A>>2]=14216,e=a[A+68>>2],e&&(rr(e),CA(a[A+68>>2])),e=a[A+28>>2],e&&(o[A+32|0]&&CA(e),a[A+28>>2]=0),a[A+28>>2]=0,a[A+20>>2]=0,a[A+24>>2]=0,f[A+32|0]=1,CA(A)},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f,t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0);t=C[A+44>>2],c=C[A+60>>2],f=a[A+20>>2],n=C[A+40>>2],b=C[A+56>>2],o=C[A+36>>2],l=C[A+52>>2],F=_(Qt[a[a[A>>2]+48>>2]](A)),W=_(Qt[a[a[A>>2]+48>>2]](A)),w=_(Qt[a[a[A>>2]+48>>2]](A)),D=C[e+52>>2],u=C[e+24>>2],g=C[e+20>>2],s=C[e+56>>2],B=C[e+40>>2],R=C[e+36>>2],E=C[e+48>>2],Q=C[e+8>>2],h=C[e>>2],G=C[e+4>>2],y=C[e+16>>2],p=C[e+32>>2],a[r+12>>2]=0,k=s,s=_(f?_(l+o)*_(.5):0),v=_(f?_(b+n)*_(.5):0),d=_(f?_(c+t)*_(.5):0),k=_(k+_(_(_(p*s)+_(R*v))+_(B*d))),o=_(F+_(f?_(l-o)*_(.5):0)),n=_(W+_(f?_(b-n)*_(.5):0)),t=_(w+_(f?_(c-t)*_(.5):0)),c=_(_(_(o*_(m(p)))+_(n*_(m(R))))+_(t*_(m(B)))),C[r+8>>2]=k-c,b=_(D+_(_(_(s*y)+_(v*g))+_(d*u))),l=_(_(_(o*_(m(y)))+_(n*_(m(g))))+_(t*_(m(u)))),C[r+4>>2]=b-l,u=_(E+_(_(_(s*h)+_(v*G))+_(d*Q))),t=_(_(_(o*_(m(h)))+_(n*_(m(G))))+_(t*_(m(Q)))),C[r>>2]=u-t,a[i+12>>2]=0,C[i+8>>2]=c+k,C[i+4>>2]=l+b,C[i>>2]=t+u},function(A,e){A|=0,e|=0;var r,i=0,f=0,t=0,n=0,o=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0,g=0;if(r=Y-144|0,Y=r,a[A+20>>2]>=1)for(v=r+96|0,u=r- -64|0,s=r+48|0,k=r+32|0;i=a[A+28>>2]+l|0,b=i+8|0,o=a[b+4>>2],f=r+24|0,a[f>>2]=a[b>>2],a[f+4>>2]=o,n=a[i+4>>2],a[r+16>>2]=a[i>>2],a[r+20>>2]=n,o=i+24|0,t=a[o+4>>2],n=k+8|0,a[n>>2]=a[o>>2],a[n+4>>2]=t,b=i+16|0,o=a[b+4>>2],a[k>>2]=a[b>>2],a[k+4>>2]=o,t=i+40|0,c=a[t+4>>2],b=s+8|0,o=b,a[o>>2]=a[t>>2],a[o+4>>2]=c,o=i+32|0,t=a[o+4>>2],a[s>>2]=a[o>>2],a[s+4>>2]=t,c=i+56|0,g=a[c+4>>2],o=u+8|0,t=o,a[t>>2]=a[c>>2],a[t+4>>2]=g,t=i+48|0,c=a[t+4>>2],a[u>>2]=a[t>>2],a[u+4>>2]=c,t=r+8|0,i=a[i- -64>>2],i=0|Qt[a[a[i>>2]+28>>2]](i),a[t>>2]=a[i+8>>2],c=a[i+4>>2],i=a[i>>2],C[t>>2]=_(C[t>>2]*C[e+8>>2])/C[A+88>>2],a[r>>2]=i,a[r+4>>2]=c,a[r+12>>2]=0,C[r>>2]=_(C[r>>2]*C[e>>2])/C[A+80>>2],C[r+4>>2]=_(C[r+4>>2]*C[e+4>>2])/C[A+84>>2],i=a[(a[A+28>>2]+l|0)- -64>>2],Qt[a[a[i>>2]+24>>2]](i,r),a[r+76>>2]=0,C[r+72>>2]=_(C[r+72>>2]*C[e+8>>2])/C[A+88>>2],C[r+68>>2]=_(C[r+68>>2]*C[e+4>>2])/C[A+84>>2],C[r+64>>2]=_(C[r+64>>2]*C[e>>2])/C[A+80>>2],c=a[f+4>>2],i=a[A+28>>2]+l|0,t=i+8|0,a[t>>2]=a[f>>2],a[t+4>>2]=c,f=a[r+20>>2],a[i>>2]=a[r+16>>2],a[i+4>>2]=f,t=a[n+4>>2],f=i+24|0,a[f>>2]=a[n>>2],a[f+4>>2]=t,n=a[k+4>>2],f=i+16|0,a[f>>2]=a[k>>2],a[f+4>>2]=n,n=a[b+4>>2],f=i+40|0,a[f>>2]=a[b>>2],a[f+4>>2]=n,n=a[s+4>>2],f=i+32|0,a[f>>2]=a[s>>2],a[f+4>>2]=n,n=a[u+4>>2],f=i+48|0,a[f>>2]=a[u>>2],a[f+4>>2]=n,f=a[o+4>>2],i=i+56|0,a[i>>2]=a[o>>2],a[i+4>>2]=f,a[A+68>>2]&&(i=a[(a[A+28>>2]+l|0)- -64>>2],Qt[a[a[i>>2]+8>>2]](i,r+16|0,r+128|0,r+112|0),i=a[r+116>>2],a[v>>2]=a[r+112>>2],a[v+4>>2]=i,f=r+136|0,n=a[f+4>>2],i=r+88|0,a[i>>2]=a[f>>2],a[i+4>>2]=n,f=r+120|0,n=a[f+4>>2],i=v+8|0,a[i>>2]=a[f>>2],a[i+4>>2]=n,i=a[r+132>>2],a[r+80>>2]=a[r+128>>2],a[r+84>>2]=i,cr(a[A+68>>2],a[76+(a[A+28>>2]+l|0)>>2],r+80|0)),l=l+80|0,d=d+1|0,(0|d)>2];);i=a[e+4>>2],a[A+80>>2]=a[e>>2],a[A+84>>2]=i,e=e+8|0,l=a[e+4>>2],i=A+88|0,a[i>>2]=a[e>>2],a[i+4>>2]=l,Qt[a[a[A>>2]+68>>2]](A),Y=r+144|0},function(A){return A|=0,A+80|0},function(A,e,r){A|=0,e=_(e),r|=0;var i,f=_(0),t=0,n=_(0),o=_(0);i=Y-96|0,Y=i,t=i+44|0,a[t>>2]=0,a[t+4>>2]=0,t=i+56|0,a[t>>2]=0,a[t+4>>2]=0,a[i+52>>2]=1065353216,t=i+76|0,a[t>>2]=0,a[t+4>>2]=0,a[i+72>>2]=1065353216,t=i+84|0,a[t>>2]=0,a[t+4>>2]=0,a[i+92>>2]=0,a[i+36>>2]=0,a[i+40>>2]=0,a[i+32>>2]=1065353216,a[i+64>>2]=0,a[i+68>>2]=0,Qt[a[a[A>>2]+8>>2]](A,i+32|0,i+16|0,i),e=_(e/_(12)),f=_(_(C[i>>2]-C[i+16>>2])*_(.5)),f=_(f+f),f=_(f*f),n=_(_(C[i+4>>2]-C[i+20>>2])*_(.5)),n=_(n+n),n=_(n*n),C[r+8>>2]=e*_(f+n),o=f,f=_(_(C[i+8>>2]-C[i+24>>2])*_(.5)),f=_(f+f),f=_(f*f),C[r+4>>2]=e*_(o+f),C[r>>2]=e*_(n+f),Y=i+96|0},function(A){return 14364},function(A,e){A|=0,e=_(e),C[A+76>>2]=e},function(A){return A|=0,_(C[A+76>>2])},function(A){return 24},function(A,e,r){A|=0,e|=0,r|=0;var i=0,f=0,t=0,n=0,o=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0;if(QA(A,e,r),a[e+12>>2]=0,a[e+20>>2]=a[A+76>>2],i=a[A+20>>2],a[e+16>>2]=i,i){if(n=0|Qt[a[a[r>>2]+16>>2]](r,76,i),i=a[n+8>>2],b=e,l=0|Qt[a[a[r>>2]+28>>2]](r,i),a[b+12>>2]=l,a[e+16>>2]>0)for(t=72,i=i+72|0;f=a[A+28>>2]+t|0,a[i>>2]=a[f>>2],b=i+-8|0,l=0|Qt[a[a[r>>2]+28>>2]](r,a[f+-8>>2]),a[b>>2]=l,Qt[a[a[r>>2]+24>>2]](r,a[(a[A+28>>2]+t|0)-8>>2])||(f=a[(a[A+28>>2]+t|0)-8>>2],l=r,u=0|Qt[a[a[f>>2]+52>>2]](f),s=1,b=a[a[r>>2]+16>>2],f=0|Qt[b](0|l,0|u,0|s),o=a[(a[A+28>>2]+t|0)-8>>2],s=r,u=f,l=0|Qt[a[a[o>>2]+56>>2]](o,a[f+8>>2],r),k=1346455635,v=a[(a[A+28>>2]+t|0)-8>>2],b=a[a[r>>2]+20>>2],Qt[b](0|s,0|u,0|l,0|k,0|v)),f=a[A+28>>2]+t|0,a[i+-72>>2]=a[f+-72>>2],a[i+-68>>2]=a[f+-68>>2],a[i+-64>>2]=a[f+-64>>2],a[i+-60>>2]=a[f+-60>>2],a[i+-56>>2]=a[f+-56>>2],a[i+-52>>2]=a[f+-52>>2],a[i+-48>>2]=a[f+-48>>2],a[i+-44>>2]=a[f+-44>>2],a[i+-40>>2]=a[f+-40>>2],a[i+-36>>2]=a[f+-36>>2],a[i+-32>>2]=a[f+-32>>2],a[i+-28>>2]=a[f+-28>>2],a[i+-24>>2]=a[f+-24>>2],a[i+-20>>2]=a[f+-20>>2],a[i+-16>>2]=a[f+-16>>2],a[i+-4>>2]=a[f+-4>>2],a[i+-12>>2]=a[f+-12>>2],t=t+80|0,i=i+76|0,c=c+1|0,(0|c)>2];);Qt[a[a[r>>2]+20>>2]](r,n,14288,1497453121,a[n+8>>2])}return 14313},function(A,e){A|=0,e|=0;var r=0,i=0;if(a[A+72>>2]=a[A+72>>2]+1,r=a[A+20>>2],(0|r)>=1)for(i=B(r,80)+-16|0;r=r+-1|0,(0|e)==a[a[A+28>>2]+i>>2]&&Br(A,r),i=i+-80|0,(0|r)>0;);Qt[a[a[A>>2]+68>>2]](A)},function(A){A|=0;var e,r=_(0),i=0,f=0,t=0,n=0;if(e=Y-32|0,Y=e,a[A+52>>2]=-581039253,a[A+56>>2]=-581039253,a[A+36>>2]=1566444395,a[A+40>>2]=1566444395,i=A+60|0,a[i>>2]=-581039253,a[i+4>>2]=0,i=A+44|0,a[i>>2]=1566444395,a[i+4>>2]=0,a[A+20>>2]>=1)for(i=64;f=a[A+28>>2]+i|0,t=a[f>>2],Qt[a[a[t>>2]+8>>2]](t,f+-64|0,e+16|0,e),r=C[e+16>>2],C[A+36>>2]>r&&(C[A+36>>2]=r),r=C[e>>2],C[A+52>>2]>2]=r),r=C[e+20>>2],C[A+40>>2]>r&&(C[A+40>>2]=r),r=C[e+4>>2],C[A+56>>2]>2]=r),r=C[e+24>>2],C[A+44>>2]>r&&(C[A+44>>2]=r),r=C[e+8>>2],C[A+60>>2]>2]=r),i=i+80|0,n=n+1|0,(0|n)>2];);Y=e+32|0},_r,function(A){var e;A|=0,a[A>>2]=14564,e=a[A+32>>2],e&&(o[A+36|0]&&CA(e),a[A+32>>2]=0),a[A+32>>2]=0,a[A+24>>2]=0,a[A+28>>2]=0,f[A+36|0]=1,CA(A)},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f,t=0,n=0,c=0,b=0,l=_(0),u=_(0),s=_(0),k=_(0),d=_(0),m=_(0),R=0,Q=0,h=0,G=0;if(r=Y-80|0,Y=r,f=0|Qt[a[a[A>>2]+28>>2]](A),(0|f)>=1)for(l=C[A+12>>2],u=C[A+8>>2],s=C[A+4>>2];;){Qt[a[a[A>>2]+16>>2]](A,r+76|0,r+52|0,r- -64|0,r+56|0,r+72|0,r+68|0,r+48|0,r+60|0,R),i=a[r+64>>2];A:if(!(i>>>0>1))if(i-1){if(i=a[r+60>>2]+-2|0,i>>>0>3)break A;switch(i-1|0){case 2:if(a[r+48>>2]<1)break A;for(i=0;b=a[r+76>>2],c=a[r+56>>2],n=a[r+72>>2]+B(a[r+68>>2],i)|0,t=b+B(c,o[0|n])|0,k=C[t>>2],d=C[t+4>>2],m=C[t+8>>2],a[r+12>>2]=0,C[r+8>>2]=l*m,C[r+4>>2]=u*d,C[r>>2]=s*k,t=b+B(c,o[n+1|0])|0,k=C[t>>2],d=C[t+4>>2],m=C[t+8>>2],a[r+28>>2]=0,C[r+24>>2]=l*m,C[r+20>>2]=u*d,C[r+16>>2]=s*k,n=b+B(c,o[n+2|0])|0,k=C[n>>2],d=C[n+4>>2],m=C[n+8>>2],a[r+44>>2]=0,C[r+40>>2]=l*m,C[r+36>>2]=u*d,C[r+32>>2]=s*k,Qt[a[a[e>>2]+8>>2]](e,r,R,i),i=i+1|0,(0|i)>2];);break A;case 0:if(a[r+48>>2]<1)break A;for(i=0;b=a[r+76>>2],c=a[r+56>>2],n=a[r+72>>2]+B(a[r+68>>2],i)|0,t=b+B(c,v[n>>1])|0,k=C[t>>2],d=C[t+4>>2],m=C[t+8>>2],a[r+12>>2]=0,C[r+8>>2]=l*m,C[r+4>>2]=u*d,C[r>>2]=s*k,t=b+B(c,v[n+2>>1])|0,k=C[t>>2],d=C[t+4>>2],m=C[t+8>>2],a[r+28>>2]=0,C[r+24>>2]=l*m,C[r+20>>2]=u*d,C[r+16>>2]=s*k,n=b+B(c,v[n+4>>1])|0,k=C[n+8>>2],d=C[n+4>>2],m=C[n>>2],a[r+44>>2]=0,C[r+32>>2]=s*m,C[r+36>>2]=u*d,C[r+40>>2]=l*k,Qt[a[a[e>>2]+8>>2]](e,r,R,i),i=i+1|0,(0|i)>2];);break A;case 1:break A}if(a[r+48>>2]<1)break A;for(i=0;b=a[r+76>>2],c=a[r+56>>2],n=a[r+72>>2]+B(a[r+68>>2],i)|0,t=b+B(c,a[n>>2])|0,k=C[t>>2],d=C[t+4>>2],m=C[t+8>>2],a[r+12>>2]=0,C[r+8>>2]=l*m,C[r+4>>2]=u*d,C[r>>2]=s*k,t=b+B(c,a[n+4>>2])|0,k=C[t>>2],d=C[t+4>>2],m=C[t+8>>2],a[r+28>>2]=0,C[r+24>>2]=l*m,C[r+20>>2]=u*d,C[r+16>>2]=s*k,n=b+B(c,a[n+8>>2])|0,k=C[n+8>>2],d=C[n+4>>2],m=C[n>>2],a[r+44>>2]=0,C[r+32>>2]=s*m,C[r+36>>2]=u*d,C[r+40>>2]=l*k,Qt[a[a[e>>2]+8>>2]](e,r,R,i),i=i+1|0,(0|i)>2];);}else if(i=a[r+60>>2]+-2|0,!(i>>>0>3)){switch(i-1|0){case 2:if(a[r+48>>2]<1)break A;for(i=0;n=a[r+72>>2]+B(a[r+68>>2],i)|0,c=o[0|n],a[r+12>>2]=0,b=a[r+76>>2],t=c,c=a[r+56>>2],t=b+B(t,c)|0,C[r+8>>2]=l*_(g[t+16>>3]),C[r+4>>2]=u*_(g[t+8>>3]),C[r>>2]=s*_(g[t>>3]),t=o[n+1|0],a[r+28>>2]=0,t=b+B(t,c)|0,C[r+24>>2]=l*_(g[t+16>>3]),C[r+20>>2]=u*_(g[t+8>>3]),C[r+16>>2]=s*_(g[t>>3]),n=b+B(c,o[n+2|0])|0,Q=g[n>>3],h=g[n+8>>3],G=g[n+16>>3],a[r+44>>2]=0,C[r+40>>2]=l*_(G),C[r+36>>2]=u*_(h),C[r+32>>2]=s*_(Q),Qt[a[a[e>>2]+8>>2]](e,r,R,i),i=i+1|0,(0|i)>2];);break A;case 0:if(a[r+48>>2]<1)break A;for(i=0;a[r+12>>2]=0,a[r+28>>2]=0,b=a[r+76>>2],c=a[r+56>>2],n=a[r+72>>2]+B(a[r+68>>2],i)|0,t=b+B(c,v[n>>1])|0,C[r+8>>2]=l*_(g[t+16>>3]),C[r+4>>2]=u*_(g[t+8>>3]),C[r>>2]=s*_(g[t>>3]),t=b+B(c,v[n+2>>1])|0,C[r+24>>2]=l*_(g[t+16>>3]),C[r+20>>2]=u*_(g[t+8>>3]),C[r+16>>2]=s*_(g[t>>3]),a[r+44>>2]=0,n=b+B(c,v[n+4>>1])|0,C[r+32>>2]=s*_(g[n>>3]),C[r+36>>2]=u*_(g[n+8>>3]),C[r+40>>2]=l*_(g[n+16>>3]),Qt[a[a[e>>2]+8>>2]](e,r,R,i),i=i+1|0,(0|i)>2];);break A;case 1:break A}if(!(a[r+48>>2]<1))for(i=0;a[r+12>>2]=0,a[r+28>>2]=0,b=a[r+76>>2],c=a[r+56>>2],n=a[r+72>>2]+B(a[r+68>>2],i)|0,t=b+B(c,a[n>>2])|0,C[r+8>>2]=l*_(g[t+16>>3]),C[r+4>>2]=u*_(g[t+8>>3]),C[r>>2]=s*_(g[t>>3]),t=b+B(c,a[n+4>>2])|0,C[r+24>>2]=l*_(g[t+16>>3]),C[r+20>>2]=u*_(g[t+8>>3]),C[r+16>>2]=s*_(g[t>>3]),a[r+44>>2]=0,n=b+B(c,a[n+8>>2])|0,C[r+32>>2]=s*_(g[n>>3]),C[r+36>>2]=u*_(g[n+8>>3]),C[r+40>>2]=l*_(g[n+16>>3]),Qt[a[a[e>>2]+8>>2]](e,r,R,i),i=i+1|0,(0|i)>2];);}if(Qt[a[a[A>>2]+24>>2]](A,R),R=R+1|0,(0|R)==(0|f))break}Y=r+80|0},mr,mr,Rr,Rr,function(A){return A|=0,a[A+24>>2]},Rr,Rr,function(A){return A|=0,1==a[A+48>>2]|0},function(A,e,r){A|=0,e|=0,r|=0;var i,f=0;f=a[e+4>>2],a[A+52>>2]=a[e>>2],a[A+56>>2]=f,e=e+8|0,i=a[e+4>>2],f=A+60|0,a[f>>2]=a[e>>2],a[f+4>>2]=i,e=a[r+4>>2],a[A+68>>2]=a[r>>2],a[A+72>>2]=e,r=r+8|0,f=a[r+4>>2],e=A+76|0,a[e>>2]=a[r>>2],a[e+4>>2]=f,a[A+48>>2]=1},function(A,e,r){A|=0,e|=0,r|=0;var i=0,f=0;i=a[A+56>>2],a[e>>2]=a[A+52>>2],a[e+4>>2]=i,i=A+60|0,f=a[i+4>>2],e=e+8|0,a[e>>2]=a[i>>2],a[e+4>>2]=f,i=A+76|0,f=a[i+4>>2],e=r+8|0,a[e>>2]=a[i>>2],a[e+4>>2]=f,e=a[A+72>>2],a[r>>2]=a[A+68>>2],a[r+4>>2]=e},function(A){return 28},function(A,e,r){A|=0,e|=0,r|=0;var i,n=0,c=0,b=0,l=0,u=0,s=0,k=0,d=0,C=0,g=0,_=0,m=0,R=0,Q=0,h=0;if(i=Y-32|0,Y=i,n=0|Qt[a[a[A>>2]+28>>2]](A),a[e>>2]=0,a[e+20>>2]=n,n){if(g=0|Qt[a[a[r>>2]+16>>2]](r,32,n),u=a[g+8>>2],Q=e,h=0|Qt[a[a[r>>2]+28>>2]](r,u),a[Q>>2]=h,R=0|Qt[a[a[A>>2]+28>>2]](A),(0|R)>0)for(;;){Qt[a[a[A>>2]+16>>2]](A,i+28|0,i+4|0,i+16|0,i+8|0,i+24|0,i+20|0,i,i+12|0,C),a[u>>2]=0,a[u+4>>2]=0,n=u+8|0,a[n>>2]=0,a[n+4>>2]=0,n=u+16|0,a[n>>2]=0,a[n+4>>2]=0,n=a[i>>2],a[u+24>>2]=n,a[u+28>>2]=a[i+4>>2],c=a[i+12>>2]+-2|0;A:if(!(c>>>0>3)){switch(c-1|0){default:if(!n)break A;if(l=0|Qt[a[a[r>>2]+16>>2]](r,4,B(n,3)),n=a[l+8>>2],Q=u,h=0|Qt[a[a[r>>2]+28>>2]](r,n),a[Q+8>>2]=h,a[i>>2]>=1)for(c=0,s=a[i+24>>2];b=s+B(a[i+20>>2],c)|0,a[n>>2]=a[b>>2],a[n+4>>2]=a[b+4>>2],a[n+8>>2]=a[b+8>>2],n=n+12|0,c=c+1|0,(0|c)>2];);Qt[a[a[r>>2]+20>>2]](r,l,14373,1497453121,a[l+8>>2]);break A;case 0:if(!n)break A;if(l=0|Qt[a[a[r>>2]+16>>2]](r,8,n),n=a[l+8>>2],Q=u,h=0|Qt[a[a[r>>2]+28>>2]](r,n),a[Q+12>>2]=h,a[i>>2]>=1)for(c=0;b=a[i+24>>2]+B(a[i+20>>2],c)|0,t[n>>1]=v[b>>1],t[n+2>>1]=v[b+2>>1],b=v[b+4>>1],t[n+6>>1]=0,t[n+4>>1]=b,n=n+8|0,c=c+1|0,(0|c)>2];);Qt[a[a[r>>2]+20>>2]](r,l,14388,1497453121,a[l+8>>2]);break A;case 1:break A;case 2:}if(n){if(l=0|Qt[a[a[r>>2]+16>>2]](r,4,n),n=a[l+8>>2],Q=u,h=0|Qt[a[a[r>>2]+28>>2]](r,n),a[Q+16>>2]=h,a[i>>2]>=1)for(c=0;b=a[i+24>>2]+B(a[i+20>>2],c)|0,f[0|n]=o[0|b],f[n+1|0]=o[b+1|0],f[n+2|0]=o[b+2|0],f[n+3|0]=0,n=n+4|0,c=c+1|0,(0|c)>2];);Qt[a[a[r>>2]+20>>2]](r,l,14415,1497453121,a[l+8>>2])}}n=a[i+16>>2];A:if(!(n>>>0>1))if(n-1){if(n=a[i+4>>2],!n)break A;if(b=0|Qt[a[a[r>>2]+16>>2]](r,16,n),n=a[b+8>>2],Q=u,h=0|Qt[a[a[r>>2]+28>>2]](r,n),a[Q>>2]=h,s=a[i+4>>2],(0|s)>=1)for(l=0,_=a[i+8>>2],c=a[i+28>>2];a[n>>2]=a[c>>2],a[n+4>>2]=a[c+4>>2],a[n+8>>2]=a[c+8>>2],c=c+_|0,n=n+16|0,l=l+1|0,(0|l)<(0|s););Qt[a[a[r>>2]+20>>2]](r,b,14438,1497453121,a[b+8>>2])}else if(n=a[i+4>>2],n){if(b=0|Qt[a[a[r>>2]+16>>2]](r,32,n),n=a[b+8>>2],Q=u,h=0|Qt[a[a[r>>2]+28>>2]](r,n),a[Q+4>>2]=h,s=a[i+4>>2],(0|s)>=1)for(l=0,_=a[i+8>>2],c=a[i+28>>2];k=a[c+4>>2],a[n>>2]=a[c>>2],a[n+4>>2]=k,d=c+8|0,m=a[d+4>>2],k=n+8|0,a[k>>2]=a[d>>2],a[k+4>>2]=m,d=c+16|0,m=a[d+4>>2],k=n+16|0,a[k>>2]=a[d>>2],a[k+4>>2]=m,c=c+_|0,n=n+32|0,l=l+1|0,(0|l)<(0|s););Qt[a[a[r>>2]+20>>2]](r,b,14457,1497453121,a[b+8>>2])}if(Qt[a[a[A>>2]+24>>2]](A,C),u=u+32|0,C=C+1|0,(0|C)==(0|R))break}Qt[a[a[r>>2]+20>>2]](r,g,14477,1497453121,a[g+8>>2])}return a[e+24>>2]=0,a[e+4>>2]=a[A+4>>2],a[e+8>>2]=a[A+8>>2],a[e+12>>2]=a[A+12>>2],a[e+16>>2]=a[A+16>>2],Y=i+32|0,14492},Gr,function(A){A|=0,CA(Gr(A))},function(A,e){A|=0,e|=0;var r=0,i=0,t=0,n=0,c=0,b=0;A:{if(o[A+165|0]){if(a[A+92>>2]>=(0|e))break A;if(r=e?dA(e<<4):0,b=r,n=a[A+88>>2],(0|n)>=1)for(;r=a[A+96>>2]+c|0,t=a[r+4>>2],i=c+b|0,a[i>>2]=a[r>>2],a[i+4>>2]=t,r=r+8|0,t=a[r+4>>2],i=i+8|0,a[i>>2]=a[r>>2],a[i+4>>2]=t,c=c+16|0,n=n+-1|0,n;);return t=a[A+96>>2],t&&(o[A+100|0]&&CA(t),a[A+96>>2]=0),a[A+96>>2]=b,a[A+92>>2]=e,void(f[A+100|0]=1)}if(!(a[A+112>>2]>=(0|e))){r=e?dA(e<<2):0,t=a[A+116>>2],i=a[A+108>>2];e:{if((0|i)>=1)for(c=r,n=t;a[c>>2]=a[n>>2],c=c+4|0,n=n+4|0,i=i+-1|0,i;);else if(!t)break e;o[A+120|0]&&CA(t),a[A+116>>2]=0}a[A+116>>2]=r,a[A+112>>2]=e,f[A+120|0]=1}}},function(A,e){A|=0,e|=0;var r=0,i=0,n=0,c=0,b=0;A:{if(o[A+164|0]){if(a[A+132>>2]>=(0|e))break A;i=e?dA(e<<2):0,n=a[A+136>>2],r=a[A+128>>2];e:{if((0|r)>=1)for(c=i,b=n;a[c>>2]=a[b>>2],c=c+4|0,b=b+4|0,r=r+-1|0,r;);else if(!n)break e;o[A+140|0]&&CA(n),a[A+136>>2]=0}return a[A+136>>2]=i,a[A+132>>2]=e,void(f[A+140|0]=1)}if(!(a[A+152>>2]>=(0|e))){i=e?dA(e<<1):0,n=a[A+156>>2],r=a[A+148>>2];e:{if((0|r)>=1)for(c=i,b=n;t[c>>1]=v[b>>1],c=c+2|0,b=b+2|0,r=r+-1|0,r;);else if(!n)break e;o[A+160|0]&&CA(n),a[A+156>>2]=0}a[A+156>>2]=i,a[A+152>>2]=e,f[A+160|0]=1}}},hA,function(A,e,r){A|=0,e|=0,r|=0;var i,f,t,n,o=_(0),c=_(0),b=_(0),l=0,u=_(0);i=Y-32|0,Y=i,f=r+8|0,n=a[f+4>>2],t=i+24|0,l=t,a[l>>2]=a[f>>2],a[l+4>>2]=n,l=a[r+4>>2],a[i+16>>2]=a[r>>2],a[i+20>>2]=l,o=C[i+16>>2],b=C[i+20>>2],c=C[t>>2],_(_(_(o*o)+_(b*b))+_(c*c))<_(1.4210854715202004e-14)&&(a[i+24>>2]=-1082130432,a[i+28>>2]=0,a[i+16>>2]=-1082130432,a[i+20>>2]=-1082130432,c=_(-1),b=_(-1),o=_(-1)),u=c,c=_(_(1)/_(y(_(_(_(o*o)+_(b*b))+_(c*c))))),C[i+24>>2]=u*c,C[i+20>>2]=b*c,C[i+16>>2]=o*c,hA(i,e,i+16|0);A:{e:if(r=a[e+4>>2],!(r>>>0>13)){switch(r-2|0){case 6:o=_(C[e+32>>2]*C[e+16>>2]);break A;case 0:case 1:case 4:case 5:case 7:case 10:break e}o=C[e+48>>2];break A}o=_(Qt[a[a[e>>2]+48>>2]](e))}a[A+12>>2]=0,C[A+8>>2]=_(o*C[i+24>>2])+C[i+8>>2],C[A+4>>2]=_(o*C[i+20>>2])+C[i+4>>2],C[A>>2]=_(o*C[i+16>>2])+C[i>>2],Y=i+32|0},sA,ve,function(A,e,r,i,f,t,n,o,c,b){return A|=0,e|=0,r|=0,i|=0,f|=0,t|=0,n|=0,o|=0,c|=0,b|=0,b=Y-80|0,Y=b,A=0,a[b+76>>2]=0,C[b+64>>2]=C[t+48>>2]-C[f+48>>2],C[b+72>>2]=C[t+56>>2]-C[f+56>>2],C[b+68>>2]=C[t+52>>2]-C[f+52>>2],e=1,(wr(r,f,i,t,b- -64|0,b+8|0)||(e=0,function(A,e,r,i,f,t){var n,o,c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),g=_(0),B=_(0),m=_(0),R=0,Q=0,h=_(0),G=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0);if(n=Y-544|0,Y=n,a[t>>2]=0,a[t+4>>2]=0,a[t+32>>2]=0,Q=t+24|0,a[Q>>2]=0,a[Q+4>>2]=0,Q=t+16|0,a[Q>>2]=0,a[Q+4>>2]=0,Q=t+8|0,a[Q>>2]=0,a[Q+4>>2]=0,a[n+388>>2]=r,a[n+384>>2]=A,b=C[i+20>>2],l=C[i+36>>2],A=e+20|0,u=C[A>>2],r=e+36|0,s=C[r>>2],Q=e+24|0,g=C[Q>>2],c=C[i+24>>2],o=e+40|0,k=C[o>>2],v=C[i+40>>2],B=C[i+32>>2],m=C[i>>2],h=C[i+16>>2],G=C[i+4>>2],p=C[e+32>>2],W=C[e>>2],w=C[e+16>>2],D=C[e+4>>2],E=C[e+8>>2],F=C[i+8>>2],a[n+436>>2]=0,a[n+420>>2]=0,a[n+404>>2]=0,Z=_(_(_(E*F)+_(g*c))+_(k*v)),C[n+432>>2]=Z,V=_(_(_(D*F)+_(u*c))+_(s*v)),C[n+428>>2]=V,c=_(_(_(W*F)+_(w*c))+_(p*v)),C[n+424>>2]=c,v=_(_(_(E*G)+_(g*b))+_(k*l)),C[n+416>>2]=v,F=_(_(_(D*G)+_(u*b))+_(s*l)),C[n+412>>2]=F,b=_(_(_(W*G)+_(w*b))+_(p*l)),C[n+408>>2]=b,l=_(_(_(m*E)+_(h*g))+_(B*k)),C[n+400>>2]=l,u=_(_(_(m*D)+_(h*u))+_(B*s)),C[n+396>>2]=u,s=_(_(_(m*W)+_(h*w))+_(B*p)),C[n+392>>2]=s,g=C[A>>2],k=C[r>>2],B=C[Q>>2],m=C[i+52>>2],h=C[e+52>>2],G=C[o>>2],p=C[i+56>>2],W=C[e+56>>2],w=C[e>>2],D=C[e+16>>2],E=C[e+32>>2],N=C[e+4>>2],I=C[e+8>>2],J=C[i+48>>2],x=C[e+48>>2],a[n+508>>2]=0,a[n+500>>2]=0,a[n+484>>2]=0,C[n+480>>2]=Z,C[n+476>>2]=v,C[n+472>>2]=l,a[n+468>>2]=0,C[n+464>>2]=V,C[n+460>>2]=F,C[n+456>>2]=u,a[n+452>>2]=0,C[n+448>>2]=c,C[n+444>>2]=b,b=_(J-x),l=_(m-h),u=_(p-W),C[n+496>>2]=_(_(I*b)+_(B*l))+_(G*u),C[n+492>>2]=_(_(b*N)+_(l*g))+_(u*k),C[n+488>>2]=_(_(b*w)+_(l*D))+_(u*E),a[n+504>>2]=348,C[n+440>>2]=s,A=n+136|0,a[A>>2]=0,a[A+4>>2]=0,a[n+128>>2]=0,a[n+132>>2]=0,a[n+364>>2]=0,a[n+368>>2]=0,a[n+376>>2]=2,a[n+144>>2]=0,A=yr(n,n+384|0,f),A)a[t>>2]=1==(0|A)?1:2;else{if(R=a[n+372>>2],a[R+32>>2])for(c=_(0),i=0,A=0,g=_(0),s=_(0),u=_(0),l=_(0),b=_(0);R=i+R|0,k=C[R+16>>2],Q=a[R>>2],R=a[n+504>>2],f=a[n+508>>2],r=a[n+384>>2]+(f>>1)|0,Qt[1&f?a[a[r>>2]+R>>2]:R](n+528|0,r,Q),Q=a[n+508>>2],r=a[n+388>>2]+(Q>>1)|0,h=_(k*C[n+536>>2]),G=_(k*C[n+532>>2]),p=_(k*C[n+528>>2]),f=a[a[n+372>>2]+i>>2],v=_(-C[f+8>>2]),B=_(-C[f+4>>2]),m=_(-C[f>>2]),R=a[n+504>>2],R=1&Q?a[a[r>>2]+R>>2]:R,c=_(c+h),g=_(g+G),s=_(s+p),a[n+524>>2]=0,C[n+520>>2]=_(_(C[n+424>>2]*m)+_(C[n+428>>2]*B))+_(C[n+432>>2]*v),C[n+516>>2]=_(_(C[n+408>>2]*m)+_(C[n+412>>2]*B))+_(C[n+416>>2]*v),C[n+512>>2]=_(_(C[n+392>>2]*m)+_(C[n+396>>2]*B))+_(C[n+400>>2]*v),Qt[R](n+528|0,r,n+512|0),v=C[n+528>>2],B=C[n+532>>2],m=C[n+536>>2],u=_(u+_(k*_(_(_(_(v*C[n+472>>2])+_(B*C[n+476>>2]))+_(m*C[n+480>>2]))+C[n+496>>2]))),l=_(l+_(k*_(_(_(_(v*C[n+456>>2])+_(B*C[n+460>>2]))+_(m*C[n+464>>2]))+C[n+492>>2]))),b=_(b+_(k*_(_(_(_(v*C[n+440>>2])+_(B*C[n+444>>2]))+_(m*C[n+448>>2]))+C[n+488>>2]))),i=i+4|0,A=A+1|0,R=a[n+372>>2],A>>>0>2];);else b=_(0),l=_(0),u=_(0),s=_(0),g=_(0),c=_(0);k=C[e+48>>2],v=C[e+8>>2],B=C[e>>2],m=C[e+4>>2],h=C[e+52>>2],G=C[e+24>>2],p=C[e+16>>2],W=C[e+20>>2],w=C[e+56>>2],D=C[e+40>>2],E=C[e+32>>2],F=C[e+36>>2],a[t+16>>2]=0,C[t+12>>2]=w+_(_(_(s*E)+_(g*F))+_(c*D)),C[t+8>>2]=h+_(_(_(s*p)+_(g*W))+_(c*G)),C[t+4>>2]=k+_(_(_(s*B)+_(g*m))+_(c*v)),v=C[e+48>>2],B=C[e+8>>2],m=C[e>>2],h=C[e+4>>2],G=C[e+52>>2],p=C[e+24>>2],W=C[e+16>>2],w=C[e+20>>2],D=C[e+56>>2],E=C[e+40>>2],F=C[e+32>>2],Z=C[e+36>>2],s=_(s-b),g=_(g-l),c=_(c-u),k=_(y(_(_(_(s*s)+_(g*g))+_(c*c)))),C[t+52>>2]=k,a[t+48>>2]=0,a[t+32>>2]=0,V=c,c=k>_(9999999747378752e-20)?_(_(1)/k):_(1),C[t+44>>2]=V*c,C[t+40>>2]=g*c,C[t+36>>2]=s*c,C[t+28>>2]=D+_(_(_(b*F)+_(l*Z))+_(u*E)),C[t+24>>2]=G+_(_(_(b*W)+_(l*w))+_(u*p)),C[t+20>>2]=v+_(_(_(b*m)+_(l*h))+_(u*B)),R=1}return Y=n+544|0,R}(r,f,i,t,b- -64|0,b+8|0)))&&(A=a[b+16>>2],a[o>>2]=a[b+12>>2],a[o+4>>2]=A,r=b+20|0,i=a[r+4>>2],A=o+8|0,a[A>>2]=a[r>>2],a[A+4>>2]=i,A=b+28|0,r=a[A+4>>2],a[c>>2]=a[A>>2],a[c+4>>2]=r,r=b+36|0,i=a[r+4>>2],A=c+8|0,a[A>>2]=a[r>>2],a[A+4>>2]=i,A=a[b+48>>2],a[n>>2]=a[b+44>>2],a[n+4>>2]=A,r=b+52|0,i=a[r+4>>2],A=n+8|0,a[A>>2]=a[r>>2],a[A+4>>2]=i,A=e),Y=b+80|0,0|A},sA,ve,Sr,ve,function(A,e,r,i,t,n,c,b,l,u){A|=0,e|=0,r|=0,i|=0,t|=0,n|=0,c|=0,b|=0,l|=0,u|=0;var s,k,v,d,g=_(0),B=0,m=_(0),R=_(0),Q=0,h=0,G=_(0),y=0,p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),V=_(0),N=0,I=0,J=_(0),x=0,U=0,M=0,S=_(0),X=_(0),T=_(0),j=_(0),O=0;for(A=Y-4240|0,Y=A,U=a[r+4>>2]+-17>>>0<=1?a[i+4>>2]+-17>>>0<2:U;Xr(),Q=(A+1264|0)+B|0,a[Q+12>>2]=0,R=C[B+1744>>2],G=_(-R),g=C[B+1748>>2],m=C[B+1752>>2],C[Q+8>>2]=_(_(C[t+8>>2]*G)-_(C[t+24>>2]*g))-_(C[t+40>>2]*m),C[Q+4>>2]=_(_(C[t+4>>2]*G)-_(g*C[t+20>>2]))-_(m*C[t+36>>2]),C[Q>>2]=_(_(C[t>>2]*G)-_(g*C[t+16>>2]))-_(m*C[t+32>>2]),G=C[n+32>>2],F=C[n>>2],W=C[n+16>>2],w=C[n+36>>2],D=C[n+4>>2],E=C[n+20>>2],Z=C[n+40>>2],p=C[n+8>>2],V=C[n+24>>2],Q=(A+272|0)+B|0,a[Q+12>>2]=0,C[Q+8>>2]=_(_(R*p)+_(g*V))+_(m*Z),C[Q+4>>2]=_(_(R*D)+_(g*E))+_(m*w),C[Q>>2]=_(_(R*F)+_(g*W))+_(m*G),B=B+16|0,672!=(0|B););if(I=0|Qt[a[a[r>>2]+84>>2]](r),Q=42,!((0|I)<1)){for(B=0,Q=0;Qt[a[a[r>>2]+88>>2]](r,Q,A+3248|0),a[A+3260>>2]=0,g=C[A+3248>>2],m=C[A+3252>>2],R=C[A+3256>>2],C[A+3256>>2]=_(_(g*C[t+32>>2])+_(m*C[t+36>>2]))+_(R*C[t+40>>2]),C[A+3252>>2]=_(_(g*C[t+16>>2])+_(m*C[t+20>>2]))+_(R*C[t+24>>2]),C[A+3248>>2]=_(_(g*C[t>>2])+_(m*C[t+4>>2]))+_(R*C[t+8>>2]),Xr(),N=a[A+3260>>2],h=B+2424|0,a[h>>2]=a[A+3256>>2],a[h+4>>2]=N,N=a[A+3252>>2],h=B+2416|0,a[h>>2]=a[A+3248>>2],a[h+4>>2]=N,h=(A+1264|0)+B|0,a[h+684>>2]=0,R=C[A+3248>>2],G=_(-R),g=C[A+3252>>2],m=C[A+3256>>2],C[h+680>>2]=_(_(C[t+8>>2]*G)-_(C[t+24>>2]*g))-_(C[t+40>>2]*m),C[h+676>>2]=_(_(C[t+4>>2]*G)-_(g*C[t+20>>2]))-_(m*C[t+36>>2]),C[h+672>>2]=_(_(C[t>>2]*G)-_(g*C[t+16>>2]))-_(m*C[t+32>>2]),h=(A+272|0)+B|0,a[h+684>>2]=0,C[h+672>>2]=_(_(R*C[n>>2])+_(g*C[n+16>>2]))+_(m*C[n+32>>2]),C[h+676>>2]=_(_(R*C[n+4>>2])+_(g*C[n+20>>2]))+_(m*C[n+36>>2]),C[h+680>>2]=_(_(R*C[n+8>>2])+_(g*C[n+24>>2]))+_(m*C[n+40>>2]),B=B+16|0,Q=Q+1|0,(0|I)!=(0|Q););Q=Q+42|0}if(k=r,v=A+1264|0,d=A+3248|0,s=0|Qt[a[a[i>>2]+84>>2]](i),(0|s)>=1){for(h=Q<<4,I=1744,N=A+1264|0,M=A+272|0,B=0;Qt[a[a[i>>2]+88>>2]](i,B,A+3248|0),a[A+3260>>2]=0,g=C[A+3248>>2],m=C[A+3252>>2],R=C[A+3256>>2],C[A+3256>>2]=_(_(g*C[n+32>>2])+_(m*C[n+36>>2]))+_(R*C[n+40>>2]),C[A+3252>>2]=_(_(g*C[n+16>>2])+_(m*C[n+20>>2]))+_(R*C[n+24>>2]),C[A+3248>>2]=_(_(g*C[n>>2])+_(m*C[n+4>>2]))+_(R*C[n+8>>2]),Xr(),O=a[A+3260>>2],y=h+I|0,x=y+8|0,a[x>>2]=a[A+3256>>2],a[x+4>>2]=O,x=a[A+3252>>2],a[y>>2]=a[A+3248>>2],a[y+4>>2]=x,F=C[t+32>>2],W=C[t>>2],w=C[t+16>>2],D=C[t+36>>2],E=C[t+4>>2],Z=C[t+20>>2],p=C[t+40>>2],G=C[t+8>>2],V=C[t+24>>2],g=C[A+3256>>2],R=C[A+3248>>2],m=C[A+3252>>2],y=h+N|0,a[y+12>>2]=0,J=G,G=_(-R),C[y+8>>2]=_(_(J*G)-_(V*m))-_(p*g),C[y+4>>2]=_(_(E*G)-_(Z*m))-_(D*g),C[y>>2]=_(_(W*G)-_(w*m))-_(F*g),G=C[n+32>>2],F=C[n>>2],W=C[n+16>>2],w=C[n+36>>2],D=C[n+4>>2],E=C[n+20>>2],Z=C[n+40>>2],p=C[n+8>>2],V=C[n+24>>2],y=h+M|0,a[y+12>>2]=0,C[y+8>>2]=_(_(R*p)+_(m*V))+_(g*Z),C[y+4>>2]=_(_(R*D)+_(m*E))+_(g*w),C[y>>2]=_(_(R*F)+_(m*W))+_(g*G),M=M+16|0,N=N+16|0,I=I+16|0,B=B+1|0,(0|s)!=(0|B););Q=B+Q|0}if(Qt[a[a[r>>2]+76>>2]](k,v,d,Q),Qt[a[a[i>>2]+76>>2]](i,A+272|0,A+2256|0,Q),(0|Q)<1)G=_(0xde0b6b000000000),D=_(0),F=_(0),E=_(0),W=_(0),Z=_(0),w=_(0),V=_(0);else for(G=_(0xde0b6b000000000),B=0,V=_(0),w=_(0),Z=_(0),W=_(0),E=_(0),F=_(0),D=_(0);Xr(),g=C[B+1744>>2],m=C[B+1748>>2],R=U?_(0):C[B+1752>>2],+_(_(_(g*g)+_(m*m))+_(R*R))>.01&&(h=(A+2256|0)+B|0,p=C[h>>2],J=C[h+4>>2],S=C[h+8>>2],h=(A+3248|0)+B|0,X=C[h>>2],T=C[h+4>>2],j=C[h+8>>2],p=_(_(_(g*_(_(_(_(_(p*C[n>>2])+_(J*C[n+4>>2]))+_(S*C[n+8>>2]))+C[n+48>>2])-_(_(_(_(X*C[t>>2])+_(T*C[t+4>>2]))+_(j*C[t+8>>2]))+C[t+48>>2])))+_(m*_(_(_(_(_(p*C[n+16>>2])+_(J*C[n+20>>2]))+_(S*C[n+24>>2]))+C[n+52>>2])-_(_(_(_(X*C[t+16>>2])+_(T*C[t+20>>2]))+_(j*C[t+24>>2]))+C[t+52>>2]))))+_(R*_(U?0:_(_(_(_(p*C[n+32>>2])+_(J*C[n+36>>2]))+_(S*C[n+40>>2]))+C[n+56>>2])-_(_(_(_(X*C[t+32>>2])+_(T*C[t+36>>2]))+_(j*C[t+40>>2]))+C[t+56>>2])))),p>2],D=g,F=g,E=m,W=m,Z=R,w=R,G=p)),B=B+16|0,Q=Q+-1|0,Q;);return GA(r),GA(i),B=0,G<_(0)||(g=GA(r),m=GA(i),e=Mr(A+192|0,r,i,e,0),a[A+116>>2]=0,i=t+8|0,B=a[i+4>>2],r=A- -64|0,a[r>>2]=a[i>>2],a[r+4>>2]=B,i=t+24|0,B=a[i+4>>2],r=A+80|0,a[r>>2]=a[i>>2],a[r+4>>2]=B,i=t+40|0,B=a[i+4>>2],r=A+96|0,a[r>>2]=a[i>>2],a[r+4>>2]=B,g=_(G+_(_(g+m)+_(.5))),C[A+112>>2]=_(w*g)+C[t+56>>2],C[A+108>>2]=_(W*g)+C[t+52>>2],r=a[t+4>>2],a[A+56>>2]=a[t>>2],a[A+60>>2]=r,r=a[t+20>>2],a[A+72>>2]=a[t+16>>2],a[A+76>>2]=r,r=a[t+36>>2],a[A+88>>2]=a[t+32>>2],a[A+92>>2]=r,C[A+104>>2]=_(F*g)+C[t+48>>2],i=n+8|0,t=a[i+4>>2],r=A+128|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,i=a[n+20>>2],r=A+136|0,a[r>>2]=a[n+16>>2],a[r+4>>2]=i,i=n+24|0,t=a[i+4>>2],r=A+144|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,i=a[n+36>>2],r=A+152|0,a[r>>2]=a[n+32>>2],a[r+4>>2]=i,i=n+40|0,t=a[i+4>>2],r=A+160|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,i=a[n+52>>2],r=A+168|0,a[r>>2]=a[n+48>>2],a[r+4>>2]=i,i=n+56|0,t=a[i+4>>2],r=A+176|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,a[A+184>>2]=1566444395,r=a[n+4>>2],a[A+120>>2]=a[n>>2],a[A+124>>2]=r,a[e+16>>2]=0,C[e+12>>2]=-w,C[e+8>>2]=-W,C[e+4>>2]=-F,f[A+48|0]=0,a[A+8>>2]=15076,Sr(e,A+56|0,A+8|0,u),r=o[A+48|0],r&&(m=C[A+44>>2],a[b+12>>2]=0,g=_(g-m),C[b>>2]=C[A+28>>2]-_(F*g),e=A+36|0,C[b+8>>2]=C[e>>2]-_(w*g),C[b+4>>2]=C[A+32>>2]-_(W*g),i=a[A+32>>2],a[l>>2]=a[A+28>>2],a[l+4>>2]=i,t=a[e+4>>2],i=l+8|0,a[i>>2]=a[e>>2],a[i+4>>2]=t,C[c>>2]=D,C[c+4>>2]=E,C[c+8>>2]=Z,C[c+12>>2]=V),B=0!=(0|r)),Y=A+4240|0,0|B},ve,De,De,function(A,e,r,i){A|=0,e|=0,r|=0,i=_(i);var t,n=0;n=a[e+4>>2],a[A+4>>2]=a[e>>2],a[A+8>>2]=n,e=e+8|0,t=a[e+4>>2],n=A+12|0,a[n>>2]=a[e>>2],a[n+4>>2]=t,e=a[r+4>>2],a[A+20>>2]=a[r>>2],a[A+24>>2]=e,r=r+8|0,n=a[r+4>>2],e=A+28|0,a[e>>2]=a[r>>2],a[e+4>>2]=n,f[A+40|0]=1,C[A+36>>2]=i},sA,ve,zr,ve,De,De,function(A,e,r,i){A|=0,e|=0,r|=0,i=_(i);var t=0,n=0;C[A+36>>2]>i&&(f[A+40|0]=1,t=a[e+4>>2],a[A+4>>2]=a[e>>2],a[A+8>>2]=t,e=e+8|0,n=a[e+4>>2],t=A+12|0,a[t>>2]=a[e>>2],a[t+4>>2]=n,e=a[r+4>>2],a[A+20>>2]=a[r>>2],a[A+24>>2]=e,r=r+8|0,t=a[r+4>>2],e=A+28|0,a[e>>2]=a[r>>2],a[e+4>>2]=t,C[A+36>>2]=i)},sA,ve,function(A,e,r,i){var t,n;return A|=0,e|=0,r|=0,i|=0,r=a[e>>2],r=0|Qt[a[a[r>>2]+56>>2]](r,72),i=a[e+4>>2],t=a[A+12>>2],n=a[A+16>>2],A=a[A+8>>2],vA(r,e),f[r+28|0]=1,a[r+8>>2]=A,a[r>>2]=15444,a[r+24>>2]=0,f[r+48|0]=1,a[r+16>>2]=0,a[r+20>>2]=0,a[r+44>>2]=0,a[r+64>>2]=t,a[r+68>>2]=n,f[r+60|0]=0,a[r+56>>2]=i,f[r+52|0]=0,a[r+36>>2]=0,a[r+40>>2]=0,0|r},function(A){A|=0;var e=0,r=0;return a[A>>2]=15444,o[A+52|0]&&(e=a[A+56>>2],e&&(r=a[A+4>>2],Qt[a[a[r>>2]+16>>2]](r,e))),e=a[A+44>>2],e&&(o[A+48|0]&&CA(e),a[A+44>>2]=0),a[A+44>>2]=0,a[A+36>>2]=0,a[A+40>>2]=0,f[A+48|0]=1,e=a[A+24>>2],e&&(o[A+28|0]&&CA(e),a[A+24>>2]=0),a[A+24>>2]=0,a[A+16>>2]=0,a[A+20>>2]=0,f[A+28|0]=1,0|A},function(A){A|=0;var e=0,r=0;a[A>>2]=15444,o[A+52|0]&&(e=a[A+56>>2],e&&(r=a[A+4>>2],Qt[a[a[r>>2]+16>>2]](r,e))),e=a[A+44>>2],e&&(o[A+48|0]&&CA(e),a[A+44>>2]=0),a[A+44>>2]=0,a[A+36>>2]=0,a[A+40>>2]=0,f[A+48|0]=1,e=a[A+24>>2],e&&(o[A+28|0]&&CA(e),a[A+24>>2]=0),a[A+24>>2]=0,a[A+16>>2]=0,a[A+20>>2]=0,f[A+28|0]=1,$(A)},function(A,e,r,i,t){A|=0,e|=0,r|=0,i|=0,t|=0;var n,c=0,b=_(0),l=_(0),u=0,s=_(0),k=0,v=_(0),d=0,g=0,R=0,h=0,G=0,p=0,F=0,W=0,w=0,D=_(0),E=0,Z=_(0),V=0,N=_(0),I=_(0),J=_(0),x=_(0),U=_(0),M=0,S=0,X=_(0),T=0,j=0,O=_(0),H=_(0),z=_(0),P=_(0),K=_(0),L=_(0),q=_(0),$=_(0),AA=_(0),eA=_(0),rA=0,iA=_(0),fA=_(0),tA=_(0),nA=_(0),aA=_(0),oA=_(0),cA=_(0),bA=0,lA=_(0),uA=_(0),sA=0,kA=0,vA=0,gA=0,BA=0,_A=0,mA=0,RA=0,QA=0,hA=0,GA=0,yA=_(0),pA=0,FA=0,WA=0;n=Y-928|0,Y=n,c=a[A+56>>2],c||(c=a[A+4>>2],c=0|Qt[a[a[c>>2]+12>>2]](c,a[e+8>>2],a[r+8>>2]),f[A+52|0]=1,a[A+56>>2]=c),a[t+4>>2]=c,d=a[r+4>>2];A:{e:if(F=a[e+4>>2],k=a[F+4>>2]+-8|0,!(k>>>0>2)){switch(k-1|0){case 1:if(k=a[d+4>>2]+-8|0,k>>>0>2)break e;switch(k-1|0){case 1:if(i=F+32|0,A=a[F+56>>2],K=C[i+(A<<2)>>2],b=C[i+((A+2|0)%3<<2)>>2],k=d+32|0,i=a[d+56>>2],l=C[c+784>>2],b=Pr(n+432|0,n+8|0,K,b,C[k+(i<<2)>>2],C[k+((i+2|0)%3<<2)>>2],A,i,a[e+12>>2],a[r+12>>2],l),b>2]+16>>2]](t,n+432|0,n+8|0,b),A=a[t+4>>2],!a[A+780>>2])break A;if(e=a[A+772>>2],r=a[a[t+8>>2]+8>>2],(0|e)!=(0|r)){se(A,a[a[t+12>>2]+8>>2]+4|0,r+4|0);break A}se(A,e+4|0,a[a[t+12>>2]+8>>2]+4|0);break A;case 0:break e}if(i=F+32|0,A=a[F+56>>2],l=C[c+784>>2],b=Pr(n+432|0,n+8|0,C[i+(A<<2)>>2],C[i+((A+2|0)%3<<2)>>2],_(0),_(C[d+32>>2]*C[d+16>>2]),A,1,a[e+12>>2],a[r+12>>2],l),b>2]+16>>2]](t,n+432|0,n+8|0,b),A=a[t+4>>2],!a[A+780>>2])break A;if(e=a[A+772>>2],r=a[a[t+8>>2]+8>>2],(0|e)!=(0|r)){se(A,a[a[t+12>>2]+8>>2]+4|0,r+4|0);break A}se(A,e+4|0,a[a[t+12>>2]+8>>2]+4|0);break A;case 0:break e}if(10==a[d+4>>2]){if(i=d+32|0,A=a[d+56>>2],l=C[c+784>>2],b=Pr(n+432|0,n+8|0,_(0),_(C[F+32>>2]*C[F+16>>2]),C[i+(A<<2)>>2],C[i+((A+2|0)%3<<2)>>2],1,A,a[e+12>>2],a[r+12>>2],l),b>2]+16>>2]](t,n+432|0,n+8|0,b),A=a[t+4>>2],!a[A+780>>2])break A;if(e=a[A+772>>2],r=a[a[t+8>>2]+8>>2],(0|e)!=(0|r)){se(A,a[a[t+12>>2]+8>>2]+4|0,r+4|0);break A}se(A,e+4|0,a[a[t+12>>2]+8>>2]+4|0);break A}}if(a[n+920>>2]=1566444395,f[n+764|0]=0,a[n+740>>2]=953267991,w=Mr(n+352|0,F,d,n+432|0,a[A+8>>2]),a[w+32>>2]=d,a[w+28>>2]=F,l=_(_(_(_(Qt[a[a[F>>2]+48>>2]](F))+_(Qt[a[a[d>>2]+48>>2]](d)))+C[a[A+56>>2]+784>>2])+C[t+32>>2]),C[n+920>>2]=l*l,c=a[e+12>>2],k=c+8|0,G=a[k+4>>2],h=n+800|0,a[h>>2]=a[k>>2],a[h+4>>2]=G,k=a[c>>2],G=a[c+4>>2],h=c+24|0,R=a[h+4>>2],W=n+816|0,a[W>>2]=a[h>>2],a[W+4>>2]=R,h=a[c+16>>2],R=a[c+20>>2],W=c+40|0,E=a[W+4>>2],S=n+832|0,a[S>>2]=a[W>>2],a[S+4>>2]=E,W=a[c+32>>2],E=a[c+36>>2],S=c+56|0,M=a[S+4>>2],V=n+848|0,a[V>>2]=a[S>>2],a[V+4>>2]=M,a[n+792>>2]=k,a[n+796>>2]=G,a[n+808>>2]=h,a[n+812>>2]=R,a[n+824>>2]=W,a[n+828>>2]=E,k=a[c+52>>2],a[n+840>>2]=a[c+48>>2],a[n+844>>2]=k,c=a[r+12>>2],k=c+8|0,G=a[k+4>>2],h=n+864|0,a[h>>2]=a[k>>2],a[h+4>>2]=G,k=a[c+4>>2],a[n+856>>2]=a[c>>2],a[n+860>>2]=k,G=a[c+20>>2],k=n+872|0,a[k>>2]=a[c+16>>2],a[k+4>>2]=G,G=c+24|0,h=a[G+4>>2],R=n+880|0,a[R>>2]=a[G>>2],a[R+4>>2]=h,G=c+40|0,h=a[G+4>>2],R=n+896|0,a[R>>2]=a[G>>2],a[R+4>>2]=h,h=a[c+36>>2],G=n+888|0,R=G,a[R>>2]=a[c+32>>2],a[R+4>>2]=h,R=a[c+52>>2],h=n+904|0,a[h>>2]=a[c+48>>2],a[h+4>>2]=R,c=c+56|0,R=a[c+4>>2],W=n+912|0,a[W>>2]=a[c>>2],a[W+4>>2]=R,c=a[F+4>>2],!((0|c)>6)&&(R=a[d+4>>2],!((0|R)>6)&&(a[n+344>>2]=15564,l=_(0),c&&(l=_(Qt[a[a[F>>2]+48>>2]](F)),R=a[d+4>>2]),R&&(b=_(Qt[a[a[d>>2]+48>>2]](d))),f[n+44|0]=0,C[n+36>>2]=b,C[n+32>>2]=l,a[n+12>>2]=t,a[n+8>>2]=15740,a[F+56>>2]))){if(a[d+56>>2]){b=C[a[A+56>>2]+784>>2];e:{r:{if(o[i+24|0]){if(l=_(-1.0000000150474662e30),function(A,e,r,i,f,t){var n,c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=0,d=_(0),g=0,B=_(0),R=0,Q=_(0),h=_(0),G=_(0),p=_(0),F=_(0),W=_(0),w=0,D=0,E=_(0),Z=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0),U=0,M=_(0),S=_(0),X=_(0),T=_(0),j=_(0),O=_(0),H=_(0),z=_(0),P=_(0),K=_(0),L=_(0),q=_(0),$=_(0),AA=_(0),eA=_(0),rA=_(0),iA=_(0);n=Y-112|0,Y=n,a[687]=a[687]+1,u=C[r+52>>2],g=20,s=C[r+20>>2],h=C[r+24>>2],S=C[i+52>>2],X=C[i+20>>2],Q=C[i+24>>2],T=C[r+56>>2],c=C[A+68>>2],d=C[r+36>>2],k=C[A+72>>2],G=C[r+40>>2],p=C[i+56>>2],N=C[e+68>>2],b=C[i+36>>2],I=C[e+72>>2],B=C[i+40>>2],F=C[r+48>>2],J=C[r+8>>2],j=C[r+4>>2],O=C[r>>2],H=C[i+48>>2],z=C[i+8>>2],V=C[i+4>>2],W=C[i>>2],E=C[r+16>>2],P=C[i+16>>2],Z=C[A+64>>2],x=C[r+32>>2],l=C[e+64>>2],K=C[i+32>>2],a[n+28>>2]=0,T=_(_(T+_(_(_(Z*x)+_(c*d))+_(k*G)))-_(p+_(_(_(l*K)+_(N*b))+_(I*B)))),C[n+24>>2]=T,S=_(_(u+_(_(_(Z*E)+_(c*s))+_(k*h)))-_(S+_(_(_(l*P)+_(N*X))+_(I*Q)))),C[n+20>>2]=S,X=_(_(F+_(_(_(Z*O)+_(c*j))+_(k*J)))-_(H+_(_(_(l*W)+_(N*V))+_(I*z)))),C[n+16>>2]=X;i:{f:{t:{n:{a:{o:if(R=a[A+28>>2],(0|R)<1)c=_(3.4028234663852886e38);else for(R=R+-1|0,c=_(3.4028234663852886e38);;){if(v=a[A+36>>2]+g|0,k=C[v+8>>2],N=C[v+4>>2],I=C[v>>2],a[n+12>>2]=0,d=_(_(_(I*x)+_(N*d))+_(k*G)),C[n+8>>2]=d,s=_(_(_(I*E)+_(N*s))+_(k*h)),C[n+4>>2]=s,k=_(_(_(I*C[r>>2])+_(N*C[r+4>>2]))+_(k*J)),C[n>>2]=k,_(_(_(k*X)+_(s*S))+_(d*T))<_(0)&&(C[n+8>>2]=-d,C[n+4>>2]=-s,C[n>>2]=-k),a[685]=a[685]+1,!o[2988]||jr(r,i,n+16|0,n,A,e,c)){if(w=0,a[686]=a[686]+1,IA(A,r,n,n+108|0,n+104|0,n+80|0,n- -64|0),IA(e,i,n,n+100|0,n+96|0,n+48|0,n+32|0),s=C[n+104>>2],d=C[n+100>>2],s>2],G=C[n+108>>2],k>2],a[f>>2]=a[n>>2],a[f+4>>2]=v,D=n+8|0,U=a[D+4>>2],v=f+8|0,a[v>>2]=a[D>>2],a[v+4>>2]=U,c=l)}if(!R)break o;g=g+36|0,R=R+-1|0,G=C[r+40>>2],d=C[r+36>>2],x=C[r+32>>2],h=C[r+24>>2],s=C[r+20>>2],E=C[r+16>>2],J=C[r+8>>2]}if(R=a[e+28>>2],(0|R)>=1)for(w=20;;){if(v=a[e+36>>2]+w|0,l=C[v+8>>2],s=C[v>>2],d=C[v+4>>2],a[n+12>>2]=0,k=_(_(_(s*C[i+32>>2])+_(d*C[i+36>>2]))+_(l*C[i+40>>2])),C[n+8>>2]=k,G=_(_(_(s*C[i+16>>2])+_(d*C[i+20>>2]))+_(l*C[i+24>>2])),C[n+4>>2]=G,l=_(_(_(s*C[i>>2])+_(d*C[i+4>>2]))+_(l*C[i+8>>2])),C[n>>2]=l,_(_(_(l*X)+_(G*S))+_(k*T))<_(0)&&(C[n+8>>2]=-k,C[n+4>>2]=-G,C[n>>2]=-l),a[685]=a[685]+1,!o[2988]||jr(r,i,n+16|0,n,A,e,c)){if(g=0,a[686]=a[686]+1,IA(A,r,n,n+108|0,n+104|0,n+80|0,n- -64|0),IA(e,i,n,n+100|0,n+96|0,n+48|0,n+32|0),l=C[n+104>>2],s=C[n+100>>2],l>2],k=C[n+108>>2],d>2],a[f>>2]=a[n>>2],a[f+4>>2]=v,D=n+8|0,U=a[D+4>>2],v=f+8|0,a[v>>2]=a[D>>2],a[v+4>>2]=U,c=h)}if(w=w+36|0,R=R+-1|0,!R)break}if(w=a[A+48>>2],(0|w)>=1)break n;D=-1,h=_(0),l=_(0),s=_(0),d=_(0),k=_(0),G=_(0),U=-1;break t}i=0;break i}for(g=a[e+48>>2],U=-1,v=0,D=-1,G=_(0),k=_(0),d=_(0),s=_(0),l=_(0),h=_(0);;){if((0|g)>=1){for(R=a[A+56>>2]+(v<<4)|0,J=C[R>>2],E=C[R+4>>2],Z=C[R+8>>2],N=_(_(_(J*C[r+32>>2])+_(E*C[r+36>>2]))+_(Z*C[r+40>>2])),I=_(_(_(J*C[r+16>>2])+_(E*C[r+20>>2]))+_(Z*C[r+24>>2])),J=_(_(_(J*C[r>>2])+_(E*C[r+4>>2]))+_(Z*C[r+8>>2])),R=0,w=4;;){if(g=a[e+56>>2]+w|0,x=C[g+4>>2],Q=C[g+-4>>2],p=C[g>>2],M=C[i+40>>2],$=C[i+32>>2],AA=C[i+36>>2],E=C[i+24>>2],Z=C[i+16>>2],u=C[i+20>>2],eA=C[i+8>>2],rA=C[i>>2],iA=C[i+4>>2],a[n+12>>2]=0,E=_(_(_(Q*Z)+_(p*u))+_(x*E)),Z=_(_(_(Q*rA)+_(p*iA))+_(x*eA)),u=_(_(J*E)-_(I*Z)),C[n+8>>2]=u,x=_(_(_(Q*$)+_(p*AA))+_(x*M)),Q=_(_(N*Z)-_(J*x)),C[n+4>>2]=Q,p=_(_(I*x)-_(N*E)),C[n>>2]=p,(!(+_(m(u))>1e-6^1)||+_(m(p))>1e-6|+_(m(Q))>1e-6)&&(M=u,u=_(_(1)/_(y(_(_(u*u)+_(_(p*p)+_(Q*Q)))))),M=_(M*u),C[n+8>>2]=M,Q=_(Q*u),C[n+4>>2]=Q,u=_(p*u),C[n>>2]=u,_(_(_(u*X)+_(Q*S))+_(T*M))<_(0)&&(C[n+8>>2]=-M,C[n+4>>2]=-Q,C[n>>2]=-u),a[685]=a[685]+1,!o[2988]||jr(r,i,n+16|0,n,A,e,c))){if(g=0,a[686]=a[686]+1,IA(A,r,n,n+108|0,n+104|0,n+80|0,n- -64|0),IA(e,i,n,n+100|0,n+96|0,n+48|0,n+32|0),u=C[n+104>>2],Q=C[n+100>>2],u>2],M=C[n+108>>2],p>2],H=C[n+52>>2],z=C[n+48>>2],B=C[n+72>>2],F=C[n+68>>2],j=C[n+64>>2]):(g=1,O=C[n+40>>2],H=C[n+36>>2],z=C[n+32>>2],B=C[n+88>>2],F=C[n+84>>2],j=C[n+80>>2],b=u))),!g)break f;b>2],a[f>>2]=a[n>>2],a[f+4>>2]=D,U=n+8|0,g=a[U+4>>2],D=f+8|0,a[D>>2]=a[U>>2],a[D+4>>2]=g,h=z,l=H,s=O,d=j,k=F,G=B,V=Z,W=E,P=x,K=J,L=I,q=N,D=v,U=R,c=b)}if(w=w+16|0,R=R+1|0,g=a[e+48>>2],!((0|R)<(0|g)))break}w=a[A+48>>2]}if(v=v+1|0,!((0|v)<(0|w)))break}}if(!((D|U)<0)){O=_(h-d),H=_(l-k),z=_(s-G),B=_(_(_(O*V)+_(H*W))+_(z*P)),j=_(_(_(O*K)+_(H*L))+_(z*q)),c=_(0),F=_(_(_(V*K)+_(W*L))+_(P*q)),b=_(_(1)-_(F*F)),b!=_(0)&&(c=_(-1.0000000150474662e30),b=_(_(j-_(B*F))/b),b<_(-1.0000000150474662e30)||(c=b,c>_(1.0000000150474662e30)&&(c=_(1.0000000150474662e30)))),B=_(_(F*c)-B);t:if(B<_(-1.0000000150474662e30)){if(b=_(j+_(F*_(-1.0000000150474662e30))),b<_(-1.0000000150474662e30)){B=_(-1.0000000150474662e30),c=_(-1.0000000150474662e30);break t}if(c=_(1.0000000150474662e30),!(b>_(1.0000000150474662e30))){B=_(-1.0000000150474662e30),c=b;break t}B=_(-1.0000000150474662e30)}else B>_(1.0000000150474662e30)&&(c=_(-1.0000000150474662e30),B=_(1.0000000150474662e30),b=_(j+_(F*_(1.0000000150474662e30))),b<_(-1.0000000150474662e30)||(c=b,c>_(1.0000000150474662e30)&&(c=_(1.0000000150474662e30))));a[n+92>>2]=0,P=_(P*B),b=_(P+_(z-_(q*c))),C[n+88>>2]=b,F=_(W*B),W=_(F+_(H-_(L*c))),C[n+84>>2]=W,B=_(V*B),c=_(B+_(O-_(K*c))),C[n+80>>2]=c,V=_(_(b*b)+_(_(c*c)+_(W*W))),V>_(1.1920928955078125e-7)&&(u=b,K=_(y(V)),b=_(_(1)/K),V=_(u*b),C[n+88>>2]=V,W=_(W*b),C[n+84>>2]=W,c=_(c*b),C[n+80>>2]=c,_(_(_(c*X)+_(W*S))+_(V*T))<_(0)&&(C[n+88>>2]=-V,C[n+84>>2]=-W,C[n+80>>2]=-c),a[n+76>>2]=0,C[n+72>>2]=s+P,C[n+68>>2]=l+F,C[n+64>>2]=h+B,Qt[a[a[t>>2]+16>>2]](t,n+80|0,n- -64|0,_(-K)))}if(i=1,c=C[f>>2],b=C[f+4>>2],h=C[f+8>>2],!(_(_(_(X*c)+_(S*b))+_(T*h))<_(0)))break i;a[f+12>>2]=0,C[f+8>>2]=-h,C[f+4>>2]=-b,C[f>>2]=-c;break i}i=0}return Y=n+112|0,i}(a[F+56>>2],a[d+56>>2],a[e+12>>2],a[r+12>>2],n+248|0,t))break r;break e}if(Sr(w,n+792|0,n+8|0,a[i+20>>2]),i=n+24|0,c=a[i+4>>2],k=n+256|0,a[k>>2]=a[i>>2],a[k+4>>2]=c,i=a[n+20>>2],a[n+248>>2]=a[n+16>>2],a[n+252>>2]=i,l=C[n+40>>2],!o[n+44|0]|l<_(0)^1)break e}if(c=a[A+16>>2],(0|c)<=-1)for(a[A+20>>2]<=-1&&(i=a[A+24>>2],i&&(o[A+28|0]&&CA(i),a[A+24>>2]=0),a[A+20>>2]=0,a[A+24>>2]=0,f[A+28|0]=1),k=c<<4;i=a[n+332>>2],w=a[A+24>>2]+k|0,G=w,a[G>>2]=a[n+328>>2],a[G+4>>2]=i,i=n+336|0,G=a[i+4>>2],w=w+8|0,a[w>>2]=a[i>>2],a[w+4>>2]=G,k=k+16|0,i=c+1|0,w=i>>>0>=c>>>0,c=i,w;);a[A+16>>2]=0,function(A,e,r,i,t,n,c,b,l,u){var s,k,v=0,d=0,g=_(0),m=_(0),R=0,Q=_(0),h=_(0),G=0,p=0,F=0,W=_(0),w=0,D=0,E=_(0),Z=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0),U=_(0),M=_(0),S=_(0),X=_(0),T=0;if(s=Y-32|0,Y=s,a[s+28>>2]=a[A+12>>2],g=C[A>>2],Q=C[A+4>>2],h=C[A+8>>2],m=_(_(1)/_(y(_(_(_(g*g)+_(Q*Q))+_(h*h))))),W=_(h*m),C[s+24>>2]=W,E=_(Q*m),C[s+20>>2]=E,Z=_(g*m),C[s+16>>2]=Z,w=-1,R=a[r+28>>2],(0|R)>=1)for(A=a[r+36>>2]+20|0,V=C[t+40>>2],N=C[t+36>>2],I=C[t+24>>2],J=C[t+20>>2],x=C[t+32>>2],U=C[t+16>>2],M=C[t+8>>2],S=C[t+4>>2],X=C[t>>2],m=_(-3.4028234663852886e38);g=C[A>>2],Q=C[A+4>>2],h=C[A+8>>2],g=_(_(_(Z*_(_(_(g*X)+_(Q*S))+_(h*M)))+_(E*_(_(_(g*U)+_(Q*J))+_(h*I))))+_(W*_(_(_(g*x)+_(Q*N))+_(h*V)))),v=g>m,m=v?g:m,w=v?d:w,A=A+36|0,d=d+1|0,(0|d)<(0|R););if(A=a[b+4>>2],(0|A)<=-1)for(a[b+8>>2]<=-1&&(v=a[b+12>>2],v&&(o[b+16|0]&&CA(v),a[b+12>>2]=0),f[b+16|0]=1,a[b+8>>2]=0,a[b+12>>2]=0),d=A<<4;G=a[s+4>>2],v=a[b+12>>2]+d|0,a[v>>2]=a[s>>2],a[v+4>>2]=G,R=s+8|0,G=a[R+4>>2],v=v+8|0,a[v>>2]=a[R>>2],a[v+4>>2]=G,d=d+16|0,v=A+1|0,R=v>>>0>=A>>>0,A=v,R;);if(a[b+4>>2]=0,A=a[r+36>>2]+B(w,36)|0,k=a[A+4>>2],(0|k)>=1)for(T=A+12|0,d=0,v=0;;){if(A=a[r+16>>2]+(a[a[T>>2]+(v<<2)>>2]<<4)|0,m=C[A>>2],g=C[A+4>>2],Q=C[A+8>>2],h=_(_(_(_(m*C[t+32>>2])+_(g*C[t+36>>2]))+_(Q*C[t+40>>2]))+C[t+56>>2]),W=_(_(_(_(m*C[t+16>>2])+_(g*C[t+20>>2]))+_(Q*C[t+24>>2]))+C[t+52>>2]),m=_(_(_(_(m*C[t>>2])+_(g*C[t+4>>2]))+_(Q*C[t+8>>2]))+C[t+48>>2]),a[b+8>>2]==(0|d)&&(R=d?d<<1:1,!((0|d)>=(0|R)))){if(R?(G=dA(R<<4),d=a[b+4>>2]):G=0,(0|d)>=1)for(A=0;F=a[b+12>>2]+A|0,D=a[F+4>>2],p=A+G|0,a[p>>2]=a[F>>2],a[p+4>>2]=D,F=F+8|0,D=a[F+4>>2],p=p+8|0,a[p>>2]=a[F>>2],a[p+4>>2]=D,A=A+16|0,d=d+-1|0,d;);A=a[b+12>>2],A&&(o[b+16|0]&&CA(A),a[b+12>>2]=0),a[b+12>>2]=G,f[b+16|0]=1,a[b+8>>2]=R,d=a[b+4>>2]}if(A=a[b+12>>2]+(d<<4)|0,a[A+12>>2]=0,C[A+8>>2]=h,C[A+4>>2]=W,C[A>>2]=m,d=a[b+4>>2]+1|0,a[b+4>>2]=d,v=v+1|0,(0|v)==(0|k))break}(0|w)>-1&&Or(s+16|0,e,i,b,l,n,c,u),Y=s+32|0}(n+248|0,a[F+56>>2],a[d+56>>2],a[e+12>>2],a[r+12>>2],_(l-b),b,A+12|0,A+32|0,t)}if(!o[A+52|0])break A;if(A=a[t+4>>2],!a[A+780>>2])break A;if(e=a[A+772>>2],r=a[a[t+8>>2]+8>>2],(0|e)!=(0|r)){se(A,a[a[t+12>>2]+8>>2]+4|0,r+4|0);break A}se(A,e+4|0,a[a[t+12>>2]+8>>2]+4|0);break A}if(1==a[d+4>>2]){if(a[n+252>>2]=0,c=a[r+12>>2],v=C[c+56>>2],N=C[c+36>>2],X=C[c+40>>2],O=C[c+52>>2],z=C[c+20>>2],P=C[c+24>>2],l=C[d+68>>2],b=C[d+60>>2],s=C[d- -64>>2],eA=C[c+32>>2],L=C[c+16>>2],D=C[c+48>>2],Z=C[c+8>>2],q=C[c>>2],$=C[c+4>>2],c=dA(16),a[n+256>>2]=1,a[n+260>>2]=c,f[n+264|0]=1,C[c>>2]=D+_(_(_(b*q)+_(s*$))+_(l*Z)),C[c+4>>2]=O+_(_(_(b*L)+_(s*z))+_(l*P)),a[c+12>>2]=0,C[c+8>>2]=v+_(_(_(b*eA)+_(s*N))+_(l*X)),k=a[n+252>>2]+1|0,a[n+252>>2]=k,l=C[d+76>>2],c=a[r+12>>2],b=C[d+80>>2],s=C[d+84>>2],v=_(_(_(_(l*C[c+32>>2])+_(b*C[c+36>>2]))+_(s*C[c+40>>2]))+C[c+56>>2]),N=_(_(_(_(l*C[c+16>>2])+_(b*C[c+20>>2]))+_(s*C[c+24>>2]))+C[c+52>>2]),l=_(_(_(_(l*C[c>>2])+_(b*C[c+4>>2]))+_(s*C[c+8>>2]))+C[c+48>>2]),a[n+256>>2]==(0|k)&&(G=k?k<<1:1,!((0|k)>=(0|G)))){if(G?(h=dA(G<<4),k=a[n+252>>2]):h=0,(0|k)>=1)for(c=0;R=a[n+260>>2]+c|0,W=a[R+4>>2],E=c+h|0,a[E>>2]=a[R>>2],a[E+4>>2]=W,R=R+8|0,W=a[R+4>>2],E=E+8|0,a[E>>2]=a[R>>2],a[E+4>>2]=W,c=c+16|0,k=k+-1|0,k;);c=a[n+260>>2],c&&(o[n+264|0]&&CA(c),a[n+260>>2]=0),a[n+260>>2]=h,f[n+264|0]=1,a[n+256>>2]=G,k=a[n+252>>2]}if(c=a[n+260>>2]+(k<<4)|0,a[c+12>>2]=0,C[c+8>>2]=v,C[c+4>>2]=N,C[c>>2]=l,k=a[n+252>>2]+1|0,a[n+252>>2]=k,l=C[d+92>>2],r=a[r+12>>2],b=C[d+96>>2],s=C[d+100>>2],v=_(_(_(_(l*C[r>>2])+_(b*C[r+4>>2]))+_(s*C[r+8>>2]))+C[r+48>>2]),N=_(_(_(_(l*C[r+32>>2])+_(b*C[r+36>>2]))+_(s*C[r+40>>2]))+C[r+56>>2]),l=_(_(_(_(l*C[r+16>>2])+_(b*C[r+20>>2]))+_(s*C[r+24>>2]))+C[r+52>>2]),a[n+256>>2]==(0|k)&&(r=k?k<<1:1,!((0|k)>=(0|r)))){if(r?(G=dA(r<<4),k=a[n+252>>2]):G=0,(0|k)>=1)for(c=0;h=a[n+260>>2]+c|0,R=a[h+4>>2],W=c+G|0,a[W>>2]=a[h>>2],a[W+4>>2]=R,h=h+8|0,R=a[h+4>>2],W=W+8|0,a[W>>2]=a[h>>2],a[W+4>>2]=R,c=c+16|0,k=k+-1|0,k;);c=a[n+260>>2],c&&(o[n+264|0]&&CA(c),a[n+260>>2]=0),a[n+260>>2]=G,f[n+264|0]=1,a[n+256>>2]=r,k=a[n+252>>2]}if(r=a[n+260>>2]+(k<<4)|0,a[r+12>>2]=0,C[r+8>>2]=N,C[r+4>>2]=l,C[r>>2]=v,a[n+252>>2]=a[n+252>>2]+1,l=C[a[A+56>>2]+784>>2],Sr(w,n+792|0,n+344|0,a[i+20>>2]),b=C[w+4>>2],s=C[w+8>>2],v=C[w+12>>2],N=_(_(_(b*b)+_(s*s))+_(v*v)),N>_(1.1920928955078125e-7)){if(a[n+340>>2]=0,K=v,v=_(_(1)/N),C[n+336>>2]=K*v,C[n+332>>2]=s*v,C[n+328>>2]=b*v,b=_(_(C[w+56>>2]-_(Qt[a[a[F>>2]+48>>2]](F)))-_(Qt[a[a[d>>2]+48>>2]](d))),d=a[A+36>>2],(0|d)<=-1)for(a[A+40>>2]<=-1&&(r=a[A+44>>2],r&&(o[A+48|0]&&CA(r),a[A+44>>2]=0),a[A+40>>2]=0,a[A+44>>2]=0,f[A+48|0]=1),c=d<<4;r=a[n+316>>2],i=a[A+44>>2]+c|0,k=i,a[k>>2]=a[n+312>>2],a[k+4>>2]=r,r=n+320|0,k=a[r+4>>2],i=i+8|0,a[i>>2]=a[r>>2],a[i+4>>2]=k,c=c+16|0,r=d+1|0,i=r>>>0>=d>>>0,d=r,i;);a[A+36>>2]=0,Or(n+328|0,a[F+56>>2],a[e+12>>2],n+248|0,A+32|0,_(b-l),l,t)}if(o[A+52|0]&&(A=a[t+4>>2],a[A+780>>2]&&(e=a[A+772>>2],r=a[a[t+8>>2]+8>>2],(0|e)==(0|r)?se(A,e+4|0,a[a[t+12>>2]+8>>2]+4|0):se(A,a[a[t+12>>2]+8>>2]+4|0,r+4|0))),A=a[n+260>>2],!A)break A;o[n+264|0]&&CA(A),a[n+260>>2]=0;break A}}if(Sr(w,n+792|0,t,a[i+20>>2]),!(!a[A+64>>2]|a[a[t+4>>2]+780>>2]>=a[A+68>>2])&&(l=C[w+4>>2],b=C[w+8>>2],s=C[w+12>>2],v=_(_(_(l*l)+_(b*b))+_(s*s)),v>_(1.1920928955078125e-7)&&(R=n+856|0,W=n+840|0,E=n+824|0,S=n+808|0,K=b,b=_(_(1)/v),N=_(K*b),eA=_(l*b),L=_(s*b),_(m(L))>_(.7071067690849304)?(l=_(_(1)/_(y(_(_(L*L)+_(N*N))))),b=_(N*l),l=_(-_(L*l)),s=_(0)):(b=_(_(1)/_(y(_(_(eA*eA)+_(N*N))))),l=_(eA*b),s=_(-_(N*b)),b=_(0)),v=_(Qt[a[a[F>>2]+16>>2]](F)),X=_(Qt[a[a[d>>2]+16>>2]](d)),O=C[744],F=v>2],sA=n+256|0,V=sA,a[V>>2]=a[d>>2],a[V+4>>2]=M,d=F?S:k,M=d+8|0,V=a[M+4>>2],T=n+272|0,a[T>>2]=a[M>>2],a[T+4>>2]=V,M=F?E:G,V=M+8|0,T=a[V+4>>2],rA=n+288|0,a[rA>>2]=a[V>>2],a[rA+4>>2]=T,V=F?W:h,T=V+8|0,rA=a[T+4>>2],bA=n+304|0,a[bA>>2]=a[T>>2],a[bA+4>>2]=rA,T=a[c+4>>2],a[n+248>>2]=a[c>>2],a[n+252>>2]=T,c=a[d+4>>2],a[n+264>>2]=a[d>>2],a[n+268>>2]=c,c=a[M+4>>2],a[n+280>>2]=a[M>>2],a[n+284>>2]=c,c=a[V+4>>2],a[n+296>>2]=a[V>>2],a[n+300>>2]=c,c=a[A+64>>2],!((0|c)<1))))for(K=b,v=_(_(Q(_(O/(F?v:X)),_(.39269909262657166)))*_(.5)),yA=_(_(_(s*s)+_(l*l))+_(b*b)),b=_(dr(v)/_(y(yA))),X=_(K*b),O=_(l*b),z=_(s*b),P=Cr(v),K=_(y(_(_(L*L)+_(_(eA*eA)+_(N*N))))),M=n+296|0,V=n+224|0,T=n+208|0,rA=n+280|0,bA=n+192|0,kA=n+264|0,vA=n+176|0,gA=n+160|0,BA=n+144|0,_A=n+128|0,mA=n+112|0,RA=n+96|0,QA=n+80|0,hA=n- -64|0,GA=n+48|0,d=0;yA>_(1.1920928955078125e-7)&&(v=_(_(_(_(6.2831854820251465)/_(0|c))*_(0|d))*_(.5)),s=_(dr(v)/K),l=_(L*s),b=_(N*s),s=_(eA*s),v=Cr(v),F?(c=a[e+12>>2],q=C[c>>2],$=C[c+4>>2],iA=C[c+8>>2],a[n+804>>2]=0,fA=C[c+36>>2],tA=C[c+20>>2],nA=C[c+40>>2],aA=C[c+24>>2],oA=C[c+32>>2],cA=C[c+16>>2],a[n+836>>2]=0,a[n+820>>2]=0,I=_(_(_(_(O*v)-_(P*b))-_(z*l))+_(X*s)),J=_(_(_(_(P*v)+_(z*s))+_(O*b))+_(X*l)),x=_(_(_(_(z*v)-_(P*s))-_(X*b))+_(O*l)),U=_(_(_(_(X*v)-_(P*l))-_(O*s))+_(z*b)),D=_(_(_(l*I)+_(_(s*J)+_(v*x)))-_(b*U)),Z=_(_(_(_(v*J)-_(s*x))-_(b*I))-_(l*U)),AA=_(_(_(b*x)+_(_(l*J)+_(v*U)))-_(s*I)),l=_(_(_(s*U)+_(_(v*I)+_(b*J)))-_(l*x)),b=_(_(2)/_(_(Z*Z)+_(_(AA*AA)+_(_(D*D)+_(l*l))))),s=_(AA*b),J=_(D*s),v=_(l*b),x=_(Z*v),I=_(J-x),U=_(l*s),H=_(D*b),lA=_(Z*H),b=_(U+lA),H=_(D*H),uA=_(l*v),l=_(_(1)-_(H+uA)),C[n+832>>2]=_(_(iA*I)+_(aA*b))+_(nA*l),C[n+828>>2]=_(_(I*$)+_(b*tA))+_(l*fA),C[n+824>>2]=_(_(I*q)+_(b*cA))+_(l*oA),v=_(D*v),D=_(Z*s),l=_(v+D),Z=_(AA*s),b=_(_(1)-_(H+Z)),s=_(U-lA),C[n+816>>2]=_(_(iA*l)+_(aA*b))+_(nA*s),C[n+812>>2]=_(_(l*$)+_(b*tA))+_(s*fA),C[n+808>>2]=_(_(l*q)+_(b*cA))+_(s*oA),l=_(_(1)-_(uA+Z)),b=_(v-D),s=_(J+x),C[n+800>>2]=_(_(iA*l)+_(aA*b))+_(nA*s),C[n+796>>2]=_(_(l*$)+_(b*tA))+_(s*fA),C[n+792>>2]=_(_(l*q)+_(b*cA))+_(s*oA),c=a[r+12>>2],g=a[c+4>>2],a[R>>2]=a[c>>2],a[R+4>>2]=g,u=c+8|0,g=a[u+4>>2],p=R+8|0,a[p>>2]=a[u>>2],a[p+4>>2]=g,u=c+24|0,g=a[u+4>>2],p=k+8|0,a[p>>2]=a[u>>2],a[p+4>>2]=g,u=a[c+20>>2],a[k>>2]=a[c+16>>2],a[k+4>>2]=u,u=c+40|0,g=a[u+4>>2],p=G+8|0,a[p>>2]=a[u>>2],a[p+4>>2]=g,u=a[c+36>>2],a[G>>2]=a[c+32>>2],a[G+4>>2]=u,u=c+56|0,g=a[u+4>>2],p=h+8|0,a[p>>2]=a[u>>2],a[p+4>>2]=g,u=a[c+52>>2],a[h>>2]=a[c+48>>2],a[h+4>>2]=u):(c=a[e+12>>2],u=c+8|0,g=a[u>>2],u=a[u+4>>2],p=a[c>>2],FA=a[c+4>>2],j=a[c+20>>2],a[S>>2]=a[c+16>>2],a[S+4>>2]=j,j=c+24|0,WA=a[j+4>>2],pA=S+8|0,a[pA>>2]=a[j>>2],a[pA+4>>2]=WA,j=n+800|0,a[j>>2]=g,a[j+4>>2]=u,u=a[c+36>>2],a[E>>2]=a[c+32>>2],a[E+4>>2]=u,u=c+40|0,g=a[u+4>>2],j=E+8|0,a[j>>2]=a[u>>2],a[j+4>>2]=g,u=c+56|0,g=a[u+4>>2],j=W+8|0,a[j>>2]=a[u>>2],a[j+4>>2]=g,u=a[c+52>>2],a[W>>2]=a[c+48>>2],a[W+4>>2]=u,a[n+792>>2]=p,a[n+796>>2]=FA,c=a[r+12>>2],q=C[c+36>>2],$=C[c+20>>2],iA=C[c+40>>2],fA=C[c+24>>2],tA=C[c+32>>2],nA=C[c>>2],aA=C[c+16>>2],oA=C[c+4>>2],cA=C[c+8>>2],a[n+900>>2]=0,a[n+884>>2]=0,a[n+868>>2]=0,I=_(_(_(_(O*v)-_(P*b))-_(z*l))+_(X*s)),J=_(_(_(_(P*v)+_(z*s))+_(O*b))+_(X*l)),x=_(_(_(_(z*v)-_(P*s))-_(X*b))+_(O*l)),U=_(_(_(_(X*v)-_(P*l))-_(O*s))+_(z*b)),D=_(_(_(l*I)+_(_(s*J)+_(v*x)))-_(b*U)),Z=_(_(_(_(v*J)-_(s*x))-_(b*I))-_(l*U)),AA=_(_(_(b*x)+_(_(l*J)+_(v*U)))-_(s*I)),l=_(_(_(s*U)+_(_(v*I)+_(b*J)))-_(l*x)),b=_(_(2)/_(_(Z*Z)+_(_(AA*AA)+_(_(D*D)+_(l*l))))),s=_(AA*b),J=_(D*s),v=_(l*b),x=_(Z*v),I=_(J-x),U=_(l*s),H=_(D*b),lA=_(Z*H),b=_(U+lA),H=_(D*H),uA=_(l*v),l=_(_(1)-_(H+uA)),C[n+896>>2]=_(_(cA*I)+_(fA*b))+_(iA*l),C[n+892>>2]=_(_(I*oA)+_(b*$))+_(l*q),C[n+888>>2]=_(_(I*nA)+_(b*aA))+_(l*tA),v=_(D*v),D=_(Z*s),l=_(v+D),Z=_(AA*s),b=_(_(1)-_(H+Z)),s=_(U-lA),C[n+880>>2]=_(_(cA*l)+_(fA*b))+_(iA*s),C[n+876>>2]=_(_(l*oA)+_(b*$))+_(s*q),C[n+872>>2]=_(_(l*nA)+_(b*aA))+_(s*tA),l=_(_(1)-_(uA+Z)),b=_(v-D),s=_(J+x),C[n+864>>2]=_(_(cA*l)+_(fA*b))+_(iA*s),C[n+860>>2]=_(_(l*oA)+_(b*$))+_(s*q),C[n+856>>2]=_(_(l*nA)+_(b*aA))+_(s*tA)),c=a[n+796>>2],a[GA>>2]=a[n+792>>2],a[GA+4>>2]=c,c=a[S+4>>2],a[hA>>2]=a[S>>2],a[hA+4>>2]=c,c=a[E+4>>2],a[QA>>2]=a[E>>2],a[QA+4>>2]=c,c=a[W+4>>2],a[RA>>2]=a[W>>2],a[RA+4>>2]=c,c=n+800|0,u=a[c+4>>2],g=GA+8|0,a[g>>2]=a[c>>2],a[g+4>>2]=u,c=S+8|0,u=a[c+4>>2],g=hA+8|0,a[g>>2]=a[c>>2],a[g+4>>2]=u,c=E+8|0,u=a[c+4>>2],g=QA+8|0,a[g>>2]=a[c>>2],a[g+4>>2]=u,c=W+8|0,u=a[c+4>>2],g=RA+8|0,a[g>>2]=a[c>>2],a[g+4>>2]=u,a[n+40>>2]=0,a[n+44>>2]=t,a[n+8>>2]=15924,c=a[i+20>>2],u=R+8|0,g=a[u+4>>2],p=mA+8|0,a[p>>2]=a[u>>2],a[p+4>>2]=g,u=a[R+4>>2],a[mA>>2]=a[R>>2],a[mA+4>>2]=u,u=k+8|0,g=a[u+4>>2],p=_A+8|0,a[p>>2]=a[u>>2],a[p+4>>2]=g,u=a[k+4>>2],a[_A>>2]=a[k>>2],a[_A+4>>2]=u,u=G+8|0,g=a[u+4>>2],p=BA+8|0,a[p>>2]=a[u>>2],a[p+4>>2]=g,u=a[G+4>>2],a[BA>>2]=a[G>>2],a[BA+4>>2]=u,u=h+8|0,g=a[u+4>>2],p=gA+8|0,a[p>>2]=a[u>>2],a[p+4>>2]=g,u=a[h+4>>2],a[gA>>2]=a[h>>2],a[gA+4>>2]=u,u=a[sA+4>>2],g=vA+8|0,a[g>>2]=a[sA>>2],a[g+4>>2]=u,u=a[n+252>>2],a[vA>>2]=a[n+248>>2],a[vA+4>>2]=u,u=kA+8|0,g=a[u+4>>2],p=bA+8|0,a[p>>2]=a[u>>2],a[p+4>>2]=g,u=a[kA+4>>2],a[bA>>2]=a[kA>>2],a[bA+4>>2]=u,u=rA+8|0,g=a[u+4>>2],p=T+8|0,a[p>>2]=a[u>>2],a[p+4>>2]=g,u=a[rA+4>>2],a[T>>2]=a[rA>>2],a[T+4>>2]=u,u=M+8|0,g=a[u+4>>2],p=V+8|0,a[p>>2]=a[u>>2],a[p+4>>2]=g,u=a[M+4>>2],a[V>>2]=a[M>>2],a[V+4>>2]=u,a[n+244>>2]=c,f[n+240|0]=F,Sr(w,n+792|0,n+8|0,c),c=a[A+64>>2]),d=d+1|0,(0|d)<(0|c););o[A+52|0]&&(A=a[t+4>>2],a[A+780>>2]&&(e=a[A+772>>2],r=a[a[t+8>>2]+8>>2],(0|e)==(0|r)?se(A,e+4|0,a[a[t+12>>2]+8>>2]+4|0):se(A,a[a[t+12>>2]+8>>2]+4|0,r+4|0)))}Y=n+928|0},function(A,e,r,i,t){A|=0,e|=0,r|=0,i|=0,t|=0;var n=_(0),c=_(0),b=_(0),l=0,u=0,s=0,k=0,v=0,d=0,g=0,B=0,m=0;return A=Y-608|0,Y=A,n=_(C[e+116>>2]-C[e+52>>2]),c=_(n*n),n=_(C[e+120>>2]-C[e+56>>2]),c=_(c+_(n*n)),n=_(C[e+124>>2]-C[e+60>>2]),c=_(c+_(n*n)),n=C[e+276>>2],c<_(n*n)&&(c=_(1),n=_(C[r+116>>2]-C[r+52>>2]),b=_(n*n),n=_(C[r+120>>2]-C[r+56>>2]),b=_(b+_(n*n)),n=_(C[r+124>>2]-C[r+60>>2]),b=_(b+_(n*n)),n=C[r+276>>2],b<_(n*n))||(c=_(1),o[2752]||(u=a[e+192>>2],l=a[r+272>>2],DA(A+552|0),t=A+580|0,i=t,a[i>>2]=0,a[i+4>>2]=0,k=A+576|0,a[k>>2]=1065353216,s=A+588|0,i=s,a[i>>2]=0,a[i+4>>2]=0,v=A+596|0,a[v>>2]=0,a[A+568>>2]=1065353216,a[A+572>>2]=1065353216,a[A+556>>2]=8,a[A+552>>2]=9852,a[A+604>>2]=0,a[A+600>>2]=l,a[A+584>>2]=l,a[A+548>>2]=0,a[A+540>>2]=1566444395,a[A+544>>2]=0,a[A+376>>2]=15992,d=A+348|0,f[0|d]=0,a[A+324>>2]=953267991,i=Hr(A,u,A+552|0,A+16|0),g=e+4|0,B=e+68|0,l=r+4|0,u=r+68|0,c=_(1),zr(i,g,B,l,u,A+376|0)&&(n=C[A+540>>2],C[e+268>>2]>n&&(C[e+268>>2]=n),C[r+268>>2]>n&&(C[r+268>>2]=n),c=_(1),n<_(1)&&(c=n)),i=a[r+192>>2],m=a[e+272>>2],DA(A+552|0),a[t>>2]=0,a[t+4>>2]=0,a[k>>2]=1065353216,a[s>>2]=0,a[s+4>>2]=0,a[v>>2]=0,a[A+568>>2]=1065353216,a[A+572>>2]=1065353216,a[A+556>>2]=8,a[A+552>>2]=9852,a[A+604>>2]=0,a[A+600>>2]=m,a[A+584>>2]=m,a[A+548>>2]=0,a[A+540>>2]=1566444395,a[A+544>>2]=0,a[A+376>>2]=15992,f[0|d]=0,a[A+324>>2]=953267991,zr(Hr(A,A+552|0,i,A+16|0),g,B,l,u,A+376|0)&&(n=C[A+540>>2],C[e+268>>2]>n&&(C[e+268>>2]=n),C[r+268>>2]>n&&(C[r+268>>2]=n),c>n&&(c=n)))),Y=A+608|0,_(c)},function(A,e){A|=0,e|=0;var r=0,i=0,t=0,n=0,c=0;if(i=a[A+56>>2],!(!i|!o[A+52|0])){if(r=a[e+4>>2],(0|r)==a[e+8>>2]&&(n=r?r<<1:1,!((0|r)>=(0|n)))){if(n&&(c=dA(n<<2),r=a[e+4>>2]),(0|r)>=1)for(i=0,t=r;a[i+c>>2]=a[a[e+12>>2]+i>>2],i=i+4|0,t=t+-1|0,t;);t=a[e+12>>2],t&&(o[e+16|0]&&(CA(t),r=a[e+4>>2]),a[e+12>>2]=0),a[e+12>>2]=c,f[e+16|0]=1,a[e+8>>2]=n,i=a[A+56>>2]}a[e+4>>2]=r+1,a[a[e+12>>2]+(r<<2)>>2]=i}},ve,De,De,Kr,ve,De,De,function(A,e,r,i){A|=0,e|=0,r|=0,i=_(i);var t,n,o,c=0,b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0);t=Y-16|0,Y=t,C[A+32>>2]=i,c=a[e+4>>2],a[A+8>>2]=a[e>>2],a[A+12>>2]=c,c=e+8|0,o=a[c+4>>2],n=A+16|0,a[n>>2]=a[c>>2],a[n+4>>2]=o,l=C[c>>2],u=C[r>>2],s=C[e>>2],k=C[r+4>>2],v=C[e+4>>2],d=C[r+8>>2],b=C[A+28>>2],i=_(_(b+C[A+24>>2])+i),C[A+32>>2]=i,a[t+12>>2]=0,C[t+8>>2]=d-_(b*l),C[t+4>>2]=k-_(b*v),C[t>>2]=u-_(s*b),i<_(0)&&(f[A+36|0]=1),A=a[A+4>>2],Qt[a[a[A>>2]+16>>2]](A,e,t,i),Y=t+16|0},ve,function(A,e,r,i){A|=0,e|=0,r|=0,i=_(i);var f,t=_(0),n=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0),U=_(0);f=Y-16|0,Y=f,D=C[e+8>>2],W=C[r+8>>2],s=_(_(D*i)+W),E=C[e+4>>2],w=C[r+4>>2],Z=_(_(E*i)+w),V=C[e>>2],t=_(V*i),i=C[r>>2],N=_(t+i),o[A+232|0]?(g=C[A+40>>2],k=_(-C[A+88>>2]),B=C[A+56>>2],u=C[A+92>>2],l=C[A+72>>2],t=C[A+96>>2],h=_(_(_(g*k)-_(B*u))-_(l*t)),n=C[A+200>>2],m=C[A+44>>2],R=C[A+60>>2],v=C[A+76>>2],p=_(_(_(m*k)-_(R*u))-_(v*t)),c=C[A+204>>2],Q=C[A+48>>2],b=_(Q*k),k=C[A- -64>>2],b=_(b-_(k*u)),u=C[A+80>>2],G=_(b-_(u*t)),t=C[A+208>>2],b=_(_(_(_(_(h*n)+_(p*c))+_(G*t))+C[A+224>>2])+_(_(s*_(_(_(l*n)+_(v*c))+_(u*t)))+_(_(N*_(_(_(g*n)+_(m*c))+_(Q*t)))+_(Z*_(_(_(B*n)+_(R*c))+_(k*t)))))),n=C[A+168>>2],c=C[A+172>>2],t=C[A+176>>2],n=_(_(_(s*_(_(_(l*n)+_(v*c))+_(u*t)))+_(_(N*_(_(_(g*n)+_(m*c))+_(Q*t)))+_(Z*_(_(_(B*n)+_(R*c))+_(k*t)))))+_(_(_(_(n*h)+_(p*c))+_(G*t))+C[A+216>>2])),c=_(V*_(n-i)),t=s,i=C[A+184>>2],s=C[A+188>>2],v=_(_(l*i)+_(v*s)),l=C[A+192>>2],s=_(_(_(t*_(v+_(u*l)))+_(_(N*_(_(_(g*i)+_(m*s))+_(Q*l)))+_(Z*_(_(_(B*i)+_(R*s))+_(k*l)))))+_(_(_(_(h*i)+_(p*s))+_(G*l))+C[A+220>>2])),i=_(_(c+_(E*_(s-w)))+_(D*_(b-W))),C[f+8>>2]=b+_(D*i),C[f+4>>2]=s+_(E*i),C[f>>2]=n+_(V*i)):(x=C[A+224>>2],g=C[A+208>>2],B=C[A+200>>2],l=C[A+204>>2],U=C[A+216>>2],n=C[A+172>>2],m=C[A+176>>2],R=C[A+168>>2],v=C[A+104>>2],b=_(-C[A+152>>2]),c=C[A+120>>2],y=C[A+156>>2],Q=C[A+136>>2],F=C[A+160>>2],k=_(_(_(v*b)-_(c*y))-_(Q*F)),u=C[A+108>>2],t=C[A+124>>2],h=C[A+140>>2],p=_(_(_(u*b)-_(t*y))-_(h*F)),G=C[A+112>>2],d=_(G*b),b=C[A+128>>2],d=_(d-_(b*y)),y=C[A+144>>2],F=_(d-_(y*F)),d=C[A+184>>2],I=C[A+188>>2],J=C[A+192>>2],d=_(_(_(W*_(_(_(Q*d)+_(h*I))+_(y*J)))+_(_(i*_(_(_(v*d)+_(u*I))+_(G*J)))+_(w*_(_(_(c*d)+_(t*I))+_(b*J)))))+_(_(_(_(k*d)+_(p*I))+_(F*J))+C[A+220>>2])),C[f+4>>2]=d,n=_(_(_(W*_(_(_(Q*R)+_(h*n))+_(y*m)))+_(_(i*_(_(_(v*R)+_(u*n))+_(G*m)))+_(w*_(_(_(c*R)+_(t*n))+_(b*m)))))+_(U+_(_(_(R*k)+_(p*n))+_(F*m)))),C[f>>2]=n,i=_(_(x+_(_(_(k*B)+_(p*l))+_(F*g)))+_(_(W*_(_(_(Q*B)+_(h*l))+_(y*g)))+_(_(i*_(_(_(v*B)+_(u*l))+_(G*g)))+_(w*_(_(_(c*B)+_(t*l))+_(b*g)))))),C[f+8>>2]=i,i=_(_(_(V*_(N-n))+_(E*_(Z-d)))+_(D*_(s-i)))),a[f+12>>2]=0,A=a[A+36>>2],Qt[a[a[A>>2]+16>>2]](A,e,f,i),Y=f+16|0},WA,Rr,De,sA,ve,qe,function(){},ve,Ai,function(A){A|=0;var e,r,i=0;return a[A+8>>2]=16148,a[A>>2]=16120,i=A+56|0,e=a[i>>2],r=A+72|0,Qt[a[a[e>>2]+20>>2]](e,a[r>>2]),i=a[i>>2],Qt[a[a[i>>2]+16>>2]](i,a[r>>2]),0|A},function(A){A|=0;var e,r,i=0;a[A+8>>2]=16148,a[A>>2]=16120,i=A+56|0,e=a[i>>2],r=A+72|0,Qt[a[a[e>>2]+20>>2]](e,a[r>>2]),i=a[i>>2],Qt[a[a[i>>2]+16>>2]](i,a[r>>2]),CA(A)},function(A,e,r,i,f){A|=0,e|=0,r|=0,i|=0,f|=0;var t,n,c=0,b=0,l=_(0);t=Y-16|0,Y=t,Lr(t+8|0,16202),b=o[A+76|0],n=b?e:r,c=a[n+4>>2],a[c+4>>2]+-21>>>0>8||(e=b?r:e,a[a[e+4>>2]+4>>2]>19||(l=_(Qt[a[a[c>>2]+48>>2]](c)),r=A+72|0,a[f+4>>2]=a[r>>2],b=A+8|0,function(A,e,r,i,f,t){var n,o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0);n=Y+-64|0,Y=n,C[A+56>>2]=e,a[A+52>>2]=r,a[A+40>>2]=f,a[A+36>>2]=i,a[A+44>>2]=t,r=a[f+12>>2],B=C[r+52>>2],m=C[r+56>>2],f=a[i+12>>2],R=C[f+52>>2],Q=C[f+56>>2],o=C[r+20>>2],c=C[r+36>>2],h=C[f+20>>2],G=C[f+36>>2],y=C[f+24>>2],b=C[r+24>>2],p=C[f+40>>2],l=C[r+40>>2],F=C[f+32>>2],u=C[r+32>>2],W=C[f>>2],s=C[r>>2],w=C[f+16>>2],k=C[r+16>>2],v=C[r+48>>2],D=C[f+48>>2],d=C[r+4>>2],E=C[f+4>>2],Z=C[f+8>>2],g=C[r+8>>2],a[n+60>>2]=0,a[n+44>>2]=0,a[n+28>>2]=0,C[n+40>>2]=_(_(g*Z)+_(b*y))+_(l*p),C[n+36>>2]=_(_(g*E)+_(b*h))+_(l*G),C[n+24>>2]=_(_(d*Z)+_(o*y))+_(c*p),C[n+20>>2]=_(_(d*E)+_(o*h))+_(c*G),v=_(-v),C[n+56>>2]=_(_(_(g*v)-_(b*B))-_(l*m))+_(_(_(g*D)+_(b*R))+_(l*Q)),C[n+52>>2]=_(_(_(d*v)-_(o*B))-_(c*m))+_(_(_(d*D)+_(o*R))+_(c*Q)),a[n+12>>2]=0,C[n>>2]=_(_(s*W)+_(k*w))+_(u*F),C[n+32>>2]=_(_(g*W)+_(b*w))+_(l*F),C[n+16>>2]=_(_(d*W)+_(o*w))+_(c*F),C[n+8>>2]=_(_(s*Z)+_(k*y))+_(u*p),C[n+4>>2]=_(_(s*E)+_(k*h))+_(u*G),C[n+48>>2]=_(_(_(s*v)-_(k*B))-_(u*m))+_(_(_(s*D)+_(k*R))+_(u*Q)),r=a[i+4>>2],Qt[a[a[r>>2]+8>>2]](r,n,A+4|0,A+20|0),e=_(C[t+32>>2]+e),C[A+20>>2]=e+C[A+20>>2],r=A+24|0,C[r>>2]=e+C[r>>2],r=A+28|0,C[r>>2]=e+C[r>>2],C[A+4>>2]=C[A+4>>2]-e,r=A+8|0,C[r>>2]=C[r>>2]-e,A=A+12|0,C[A>>2]=C[A>>2]-e,Y=n- -64|0}(b,l,i,e,n,f),r=a[r>>2],a[r+776>>2]=a[n+8>>2],a[r+772>>2]=a[e+8>>2],Qt[a[a[c>>2]+64>>2]](c,b,A+12|0,A+28|0),e=a[f+4>>2],a[e+780>>2]&&(i=a[e+772>>2],c=a[a[f+8>>2]+8>>2],r=(0|i)==(0|c),b=e,e=a[a[f+12>>2]+8>>2],se(b,(r?i:e)+4|0,(r?e:c)+4|0)),A=A+44|0,a[A>>2]=0,a[A+4>>2]=0)),qr(),Y=t+16|0},function(A,e,r,i,f){A|=0,e|=0,r|=0,i|=0,f|=0;var t=_(0),n=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0),U=_(0),M=_(0),S=_(0),X=_(0),T=_(0),j=_(0),O=_(0),H=_(0),z=_(0),P=_(0),K=_(0),L=_(0);return i=Y-240|0,Y=i,K=_(1),f=o[A+76|0],A=f?r:e,t=_(C[A+116>>2]-C[A+52>>2]),n=_(t*t),t=_(C[A+120>>2]-C[A+56>>2]),n=_(n+_(t*t)),t=_(C[A+124>>2]-C[A+60>>2]),n=_(n+_(t*t)),t=C[A+276>>2],n<_(t*t)||(e=f?e:r,r=a[e+192>>2],a[r+4>>2]+-21>>>0>8||(D=C[A+92>>2],E=C[A+76>>2],Z=C[A+108>>2],V=C[A+88>>2],N=C[A+72>>2],I=C[A+104>>2],J=C[A+100>>2],x=C[A+84>>2],U=C[A+68>>2],s=C[e+36>>2],k=C[e+20>>2],v=C[e+4>>2],M=C[A+28>>2],S=C[A+12>>2],X=C[A+44>>2],T=C[A+24>>2],j=C[A+8>>2],O=C[A+40>>2],H=C[A+36>>2],z=C[A+20>>2],P=C[A+4>>2],d=C[e+12>>2],G=C[A+116>>2],g=C[e+28>>2],n=C[A+120>>2],B=C[e+44>>2],y=C[A+124>>2],L=_(_(_(d*G)+_(g*n))+_(B*y)),m=C[e+8>>2],p=_(-C[e+52>>2]),R=C[e+24>>2],Q=C[e+56>>2],h=C[e+40>>2],F=C[e+60>>2],u=_(_(_(m*p)-_(R*Q))-_(h*F)),t=_(u+_(_(_(m*G)+_(R*n))+_(h*y))),c=C[A+56>>2],b=C[A+52>>2],l=C[A+60>>2],a[i+236>>2]=0,w=_(_(_(d*p)-_(g*Q))-_(B*F)),W=_(w+_(_(_(d*b)+_(g*c))+_(B*l))),C[i+232>>2]=W,u=_(u+_(_(_(m*b)+_(R*c))+_(h*l))),C[i+228>>2]=u,Q=_(_(_(v*p)-_(k*Q))-_(s*F)),l=_(Q+_(_(_(v*b)+_(k*c))+_(s*l))),C[i+224>>2]=l,p=l,c=_(Q+_(_(_(v*G)+_(k*n))+_(s*y))),c>2]=c,p=c),G=u,t>2]=t,G=t),b=_(w+L),n=W,b>2]=b,n=b),a[i+220>>2]=0,C[i+216>>2]=W,C[i+212>>2]=u,C[i+208>>2]=l,y=l,l>2]=c,y=c),Q=u,u>2]=t,Q=t),F=W,W>2]=b,F=b),w=n,n=C[A+272>>2],C[i+232>>2]=w-n,C[i+228>>2]=G-n,C[i+224>>2]=p-n,C[i+216>>2]=n+F,C[i+212>>2]=n+Q,C[i+208>>2]=n+y,a[i+128>>2]=0,C[i+124>>2]=b,C[i+120>>2]=t,C[i+116>>2]=c,a[i+112>>2]=0,C[i+108>>2]=_(_(d*E)+_(g*D))+_(B*Z),C[i+104>>2]=_(_(d*N)+_(g*V))+_(B*I),C[i+100>>2]=_(_(d*U)+_(g*x))+_(B*J),a[i+96>>2]=0,C[i+92>>2]=_(_(m*E)+_(R*D))+_(h*Z),C[i+88>>2]=_(_(m*N)+_(R*V))+_(h*I),C[i+84>>2]=_(_(m*U)+_(R*x))+_(h*J),a[i+80>>2]=0,C[i+76>>2]=_(_(v*E)+_(k*D))+_(s*Z),C[i+72>>2]=_(_(v*N)+_(k*V))+_(s*I),a[i- -64>>2]=0,C[i+60>>2]=W,C[i+56>>2]=u,C[i+52>>2]=l,a[i+48>>2]=0,C[i+44>>2]=_(_(d*S)+_(g*M))+_(B*X),C[i+40>>2]=_(_(d*j)+_(g*T))+_(B*O),C[i+36>>2]=_(_(d*P)+_(g*z))+_(B*H),a[i+32>>2]=0,C[i+28>>2]=_(_(m*S)+_(R*M))+_(h*X),C[i+24>>2]=_(_(m*j)+_(R*T))+_(h*O),C[i+20>>2]=_(_(m*P)+_(R*z))+_(h*H),a[i+16>>2]=0,C[i+12>>2]=_(_(v*S)+_(k*M))+_(s*X),C[i+8>>2]=_(_(v*j)+_(k*T))+_(s*O),C[i+196>>2]=n,C[i+68>>2]=_(_(v*U)+_(k*x))+_(s*J),C[i+4>>2]=_(_(v*P)+_(k*z))+_(s*H),a[i>>2]=16488,a[i+200>>2]=a[A+268>>2],r&&(Qt[a[a[r>>2]+64>>2]](r,i,i+224|0,i+208|0),t=C[i+200>>2],t>2]&&(C[A+268>>2]=t,K=t)))),Y=i+240|0,_(K)},function(A,e){A|=0,e|=0;var r=0,i=0,t=0,n=0,c=0;if(i=a[A+72>>2],i){if(r=a[e+4>>2],(0|r)==a[e+8>>2]&&(n=r?r<<1:1,!((0|r)>=(0|n)))){if(n&&(c=dA(n<<2),r=a[e+4>>2]),(0|r)>=1)for(i=0,t=r;a[i+c>>2]=a[a[e+12>>2]+i>>2],i=i+4|0,t=t+-1|0,t;);t=a[e+12>>2],t&&(o[e+16|0]&&(CA(t),r=a[e+4>>2]),a[e+12>>2]=0),a[e+12>>2]=c,f[e+16|0]=1,a[e+8>>2]=n,i=a[A+72>>2]}a[e+4>>2]=r+1,a[a[e+12>>2]+(r<<2)>>2]=i}},function(A){A|=0;var e=0;return a[A>>2]=16148,e=a[A+48>>2],Qt[a[a[e>>2]+20>>2]](e,a[A+64>>2]),e=a[A+48>>2],Qt[a[a[e>>2]+16>>2]](e,a[A+64>>2]),0|A},function(A){A|=0;var e=0;a[A>>2]=16148,e=a[A+48>>2],Qt[a[a[e>>2]+20>>2]](e,a[A+64>>2]),e=a[A+48>>2],Qt[a[a[e>>2]+16>>2]](e,a[A+64>>2]),CA(A)},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f,t=0,n=0,o=_(0),c=0,b=_(0),l=_(0),u=_(0),s=0,k=0;f=Y-144|0,Y=f,Lr(f+136|0,16160),o=C[e>>2],b=C[e+16>>2],u=o>2],(uC[A+20>>2]||(t=(o>b^1)<<4,C[(C[e+t>>2]>l?t:32)+e>>2]>2]||(o=C[e+8>>2],t=e+24|0,b=C[t>>2],u=o>2],(uC[A+28>>2]||(t=o>b?e+8|0:t,C[(C[t>>2]>l?t:c)>>2]>2]||(o=C[e+4>>2],t=e+20|0,b=C[t>>2],u=o>2],(uC[A+24>>2]||(t=o>b?e+4|0:t,a[a[a[A+36>>2]+4>>2]+4>>2]>19|C[(C[t>>2]>l?t:c)>>2]>2]||(c=a[A+48>>2],k=zA(f+24|0),n=e+8|0,s=a[n+4>>2],t=f+92|0,a[t>>2]=a[n>>2],a[t+4>>2]=s,n=a[e+20>>2],t=f+100|0,a[t>>2]=a[e+16>>2],a[t+4>>2]=n,n=e+24|0,s=a[n+4>>2],t=f+108|0,a[t>>2]=a[n>>2],a[t+4>>2]=s,n=a[e+36>>2],t=f+116|0,a[t>>2]=a[e+32>>2],a[t+4>>2]=n,n=e+40|0,s=a[n+4>>2],t=f+124|0,a[t>>2]=a[n>>2],a[t+4>>2]=s,a[f+24>>2]=16352,t=a[e+4>>2],a[f+84>>2]=a[e>>2],a[f+88>>2]=t,a[f+72>>2]=a[A+56>>2],a[f+28>>2]=1,a[f+20>>2]=i,a[f+16>>2]=r,e=a[A+40>>2],a[f>>2]=e,t=a[e+8>>2],a[f+12>>2]=a[e+12>>2],a[f+8>>2]=t,o=C[a[A+44>>2]+32>>2],a[f+4>>2]=f+24,e=a[A+36>>2],e=o>_(0)?0|Qt[a[a[c>>2]+8>>2]](c,e,f,0,2):0|Qt[a[a[c>>2]+8>>2]](c,e,f,a[A+64>>2],1),t=a[A+44>>2],n=a[t+8>>2],a[n+8>>2]!=a[a[A+40>>2]+8>>2]?(n=a[t+12>>2],a[t+12>>2]=f,Qt[a[a[t>>2]+12>>2]](t,r,i)):(a[t+8>>2]=f,Qt[a[a[t>>2]+8>>2]](t,r,i)),Qt[a[a[e>>2]+8>>2]](e,a[A+36>>2],f,a[A+52>>2],a[A+44>>2]),r=a[A+44>>2],a[(a[a[r+8>>2]+8>>2]==a[a[A+40>>2]+8>>2]?8:12)+r>>2]=n,Qt[a[a[e>>2]>>2]](e),Qt[a[a[c>>2]+60>>2]](c,e),Ae(k))))))),qr(),Y=f+144|0},ce,$A,ve,function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var t=0,n=0,o=0,c=_(0);r=Y-800|0,Y=r,Lr(r+792|0,16672),i=r+740|0,a[i>>2]=0,a[i+4>>2]=0,i=r+752|0,a[i>>2]=0,a[i+4>>2]=0,a[r+748>>2]=1065353216,i=r+772|0,a[i>>2]=0,a[i+4>>2]=0,a[r+768>>2]=1065353216,i=r+780|0,a[i>>2]=0,a[i+4>>2]=0,a[r+788>>2]=0,a[r+732>>2]=0,a[r+736>>2]=0,a[r+728>>2]=1065353216,a[r+760>>2]=0,a[r+764>>2]=0,a[r+720>>2]=0,a[r+724>>2]=0,a[r+552>>2]=15992,a[r+716>>2]=a[A+200>>2],i=a[A+196>>2],DA(r+496|0),t=r+524|0,a[t>>2]=0,a[t+4>>2]=0,a[r+520>>2]=1065353216,t=r+532|0,a[t>>2]=0,a[t+4>>2]=0,a[r+540>>2]=0,a[r+512>>2]=1065353216,a[r+516>>2]=1065353216,a[r+496>>2]=9852,a[r+548>>2]=0,a[r+544>>2]=i,a[r+528>>2]=i,a[r+500>>2]=8,i=zA(r+384|0),t=e+8|0,n=a[t+4>>2],o=r+452|0,a[o>>2]=a[t>>2],a[o+4>>2]=n,t=a[e+20>>2],n=r+460|0,a[n>>2]=a[e+16>>2],a[n+4>>2]=t,t=e+24|0,n=a[t+4>>2],o=r+468|0,a[o>>2]=a[t>>2],a[o+4>>2]=n,t=a[e+36>>2],n=r+476|0,a[n>>2]=a[e+32>>2],a[n+4>>2]=t,t=e+40|0,n=a[t+4>>2],o=r+484|0,a[o>>2]=a[t>>2],a[o+4>>2]=n,a[r+388>>2]=1,a[r+384>>2]=16352,t=a[e+4>>2],a[r+444>>2]=a[e>>2],a[r+448>>2]=t,f[r+356|0]=0,a[r+332>>2]=953267991,Ai($r(r+8|0,r+496|0,r+384|0,r+24|0),A+4|0,A+68|0,r+728|0,r+728|0,r+552|0)&&(c=C[r+716>>2],C[A+200>>2]>c&&(C[A+200>>2]=c)),Ae(i),qr(),Y=r+800|0},fi,function(A){A|=0,$(fi(A))},ti,function(A,e,r,i,f){A|=0,e|=0,r|=0,i|=0,f|=0;var t,n,c,b,l,u,s=0,k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=0,p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),Y=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0),U=_(0),M=_(0),S=0;if(y=a[A+52>>2],(0|y)<1)return _(_(1));for(s=o[A+68|0],t=s?e:r,e=s?r:e,n=a[e- -64>>2],x=C[e+60>>2],U=C[e+56>>2],M=C[e+52>>2],c=a[e+48>>2],v=C[e+44>>2],d=C[e+40>>2],g=C[e+36>>2],s=32,b=a[e+32>>2],B=C[e+28>>2],m=C[e+24>>2],R=C[e+20>>2],l=a[e+16>>2],Q=C[e+12>>2],h=C[e+8>>2],r=a[e+304>>2],G=C[e+4>>2],u=a[e+192>>2],p=_(1);a[e+304>>2]=r+1,r=a[u+28>>2]+s|0,k=C[r+24>>2],F=C[r+16>>2],W=C[r+20>>2],w=C[r>>2],D=C[r+-32>>2],E=C[r+-16>>2],Z=C[r+4>>2],Y=C[r+-28>>2],V=C[r+-12>>2],N=C[r+8>>2],I=C[r+-24>>2],J=C[r+-8>>2],a[e+64>>2]=0,a[e+48>>2]=0,a[e+32>>2]=0,a[e+16>>2]=0,C[e+44>>2]=_(_(g*I)+_(d*J))+_(v*N),C[e+40>>2]=_(_(g*Y)+_(d*V))+_(v*Z),C[e+36>>2]=_(_(g*D)+_(d*E))+_(v*w),C[e+28>>2]=_(_(R*I)+_(m*J))+_(B*N),C[e+24>>2]=_(_(R*Y)+_(m*V))+_(B*Z),C[e+20>>2]=_(_(R*D)+_(m*E))+_(B*w),C[e+12>>2]=_(_(G*I)+_(h*J))+_(Q*N),C[e+8>>2]=_(_(G*Y)+_(h*V))+_(Q*Z),C[e+4>>2]=_(_(G*D)+_(h*E))+_(Q*w),C[e+60>>2]=x+_(_(_(g*F)+_(d*W))+_(v*k)),C[e+56>>2]=U+_(_(_(R*F)+_(m*W))+_(B*k)),C[e+52>>2]=M+_(_(_(G*F)+_(h*W))+_(Q*k)),r=a[a[A+60>>2]+S>>2],k=_(Qt[a[a[r>>2]+12>>2]](r,e,t,i,f)),a[e+64>>2]=n,C[e+60>>2]=x,C[e+56>>2]=U,C[e+52>>2]=M,a[e+48>>2]=c,C[e+44>>2]=v,C[e+40>>2]=d,C[e+36>>2]=g,a[e+32>>2]=b,C[e+28>>2]=B,C[e+24>>2]=m,C[e+20>>2]=R,a[e+16>>2]=l,C[e+12>>2]=Q,C[e+8>>2]=h,C[e+4>>2]=G,r=a[e+304>>2]+1|0,a[e+304>>2]=r,p=k>2],(0|r)>=1)for(;i=a[a[A+60>>2]+f>>2],i&&(Qt[a[a[i>>2]+16>>2]](i,e),r=a[A+52>>2]),f=f+4|0,t=t+1|0,(0|t)<(0|r););},sA,ve,De,function(A,e){var r,i;A|=0,e|=0,r=A,i=a[a[a[A+4>>2]+4>>2]+28>>2],A=a[e+36>>2],ni(r,a[64+(i+B(A,80)|0)>>2],A)},function(A,e,r){A|=0,e|=0,r=_(r),Qt[a[a[A>>2]+12>>2]](A,e)},lr,lr,function(A){A|=0;var e=0;return a[A>>2]=16844,e=a[A+56>>2],e&&(o[A+60|0]&&CA(e),a[A+56>>2]=0),a[A+56>>2]=0,a[A+48>>2]=0,a[A+52>>2]=0,f[A+60|0]=1,e=a[A+36>>2],e&&(o[A+40|0]&&CA(e),a[A+36>>2]=0),a[A+36>>2]=0,a[A+28>>2]=0,a[A+32>>2]=0,f[A+40|0]=1,e=a[A+16>>2],e&&(o[A+20|0]&&CA(e),a[A+16>>2]=0),a[A+16>>2]=0,a[A+8>>2]=0,a[A+12>>2]=0,f[A+20|0]=1,0|A},function(A){A|=0;var e=0;a[A>>2]=16844,e=a[A+56>>2],e&&(o[A+60|0]&&CA(e),a[A+56>>2]=0),a[A+56>>2]=0,a[A+48>>2]=0,a[A+52>>2]=0,f[A+60|0]=1,e=a[A+36>>2],e&&(o[A+40|0]&&CA(e),a[A+36>>2]=0),a[A+36>>2]=0,a[A+28>>2]=0,a[A+32>>2]=0,f[A+40|0]=1,e=a[A+16>>2],!e|!o[A+20|0]||CA(e),$(A)},function(A,e,r){A|=0,e|=0,r|=0;var i=0,f=0,t=0,n=0,o=0,c=0,b=0,l=0;a[690]=a[690]+1,c=a[A+36>>2],i=r<<16|e,i=(i<<15^-1)+i|0,i=B(i>>>10^i,9),i^=i>>>6,i=(i<<11^-1)+i|0,b=c+((a[A+12>>2]+-1&(i>>>16^i))<<2)|0,i=a[b>>2];A:if(-1!=(0|i)){for(t=a[A+16>>2],f=i;;){if(o=t+B(f,12)|0,a[o+4>>2]!=(0|r)||(0|e)!=a[o>>2]){if(f=a[a[A+56>>2]+(f<<2)>>2],-1!=(0|f))continue;break A}break}if(o){e=B(f,12),l=a[8+(e+t|0)>>2],f=a[A+56>>2],n=(0|e)/12|0;e:{r:{if((0|i)!=(0|n)){for(;e=i,i=a[f+(e<<2)>>2],(0|n)!=(0|i););if(i=a[f+(n<<2)>>2],r=i,-1==(0|e))break r;a[f+(e<<2)>>2]=i;break e}r=a[f+(n<<2)>>2]}a[b>>2]=r}if(i=a[A+8>>2]+-1|0,(0|n)==(0|i))return a[A+8>>2]=n,0|l;e:{if(t=t+B(i,12)|0,e=a[t+4>>2]<<16|a[t>>2],e=(e<<15^-1)+e|0,e=B(e>>>10^e,9),e^=e>>>6,e=(e<<11^-1)+e|0,b=a[A+12>>2]+-1&(e>>>16^e),c=c+(b<<2)|0,e=a[c>>2],(0|e)!=(0|i)){for(;r=e,e=a[f+(e<<2)>>2],(0|i)!=(0|e););if(e=a[f+(i<<2)>>2],-1!=(0|r)){a[f+(r<<2)>>2]=e;break e}}else e=a[f+(i<<2)>>2];a[c>>2]=e}e=a[t+4>>2],a[o>>2]=a[t>>2],a[o+4>>2]=e,a[o+8>>2]=a[t+8>>2],e=a[A+36>>2]+(b<<2)|0,a[a[A+56>>2]+(n<<2)>>2]=a[e>>2],a[e>>2]=n,a[A+8>>2]=a[A+8>>2]+-1}}return 0|l},function(A,e,r){return A|=0,e|=0,r|=0,a[691]=a[691]+1,0|function(A,e,r){var i,t=0,n=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0;t=r<<16|e,t=(t<<15^-1)+t|0,t=B(t>>>10^t,9),t^=t>>>6,t=(t<<11^-1)+t|0,i=t>>>16^t,t=a[A+12>>2],k=i&t+-1,n=a[a[A+36>>2]+(k<<2)>>2];A:{e:if(-1!=(0|n)){for(v=a[A+16>>2];;){if(c=v+B(n,12)|0,a[c+4>>2]!=(0|r)||(0|e)!=a[c>>2]){if(n=a[a[A+56>>2]+(n<<2)>>2],-1!=(0|n))continue;break e}break}if(c)break A}e:{r:{if(u=A,b=a[A+8>>2],n=b,(0|t)==(0|n)){if(s=t?t<<1:1,d=(0|t)>=(0|s),!d)break r;n=t}a[u+8>>2]=n+1,l=a[A+16>>2],c=l+B(b,12)|0;break e}if(s&&(l=dA(B(s,12)),t=a[A+8>>2]),(0|t)>=1)for(n=0;c=a[A+16>>2]+n|0,v=a[c+4>>2],u=n+l|0,a[u>>2]=a[c>>2],a[u+4>>2]=v,a[u+8>>2]=a[c+8>>2],n=n+12|0,t=t+-1|0,t;);t=a[A+16>>2],t&&(o[A+20|0]&&CA(t),a[A+16>>2]=0),a[A+16>>2]=l,a[A+12>>2]=s,f[A+20|0]=1,a[A+8>>2]=a[A+8>>2]+1,c=B(b,12)+l|0,d||(ai(A),k=a[A+12>>2]+-1&i)}a[c>>2]=e,e=B(b,12)+l|0,a[e+8>>2]=0,a[e+4>>2]=r,e=a[A+56>>2]+(b<<2)|0,A=a[A+36>>2]+(k<<2)|0,a[e>>2]=a[A>>2],a[A>>2]=b}return c}(A,e,r)},ci,li,function(A){A|=0,$(li(A))},function(A,e,r,i,t){A|=0,e|=0,r|=0,i|=0,t|=0;var n,c=0,b=0,l=0,u=0,s=_(0),k=0,v=_(0),d=_(0),g=_(0),R=_(0),Q=0,h=_(0),G=_(0),y=_(0),p=0,F=0,W=_(0),w=_(0),D=_(0),E=0,Z=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0),U=_(0),M=_(0),S=_(0),X=_(0),T=0,j=_(0),O=_(0),H=0,z=_(0),P=0,K=0,L=0,q=_(0),$=_(0),AA=_(0),eA=_(0),rA=_(0),iA=_(0),fA=_(0),tA=_(0),nA=_(0),aA=_(0);if(n=Y-3328|0,Y=n,K=a[e+4>>2],F=a[K+68>>2],F&&(L=a[r+4>>2],T=a[L+68>>2],T)){if(a[L+72>>2]!=a[A+112>>2]||a[K+72>>2]!=a[A+108>>2]){if(b=8,c=a[A+84>>2],l=a[c+8>>2],(0|l)>=1){for(;Q=a[a[c+16>>2]+b>>2],Q&&(Qt[a[a[Q>>2]>>2]](Q),k=a[A+4>>2],Qt[a[a[k>>2]+60>>2]](k,Q)),b=b+12|0,l=l+-1|0,l;);c=a[A+84>>2]}oi(c),a[A+108>>2]=a[K+72>>2],a[A+112>>2]=a[L+72>>2]}a[n+84>>2]=0,f[n+88|0]=1,a[n+76>>2]=0,a[n+80>>2]=0,be(n+112|0),be(n+916|0),be(n+1720|0),be(n+2524|0),c=a[n+84>>2],c&&(o[n+88|0]&&CA(c),a[n+84>>2]=0),a[n+76>>2]=0,a[n+80>>2]=4,Q=a[A+84>>2],f[n+88|0]=0,u=a[Q+8>>2],a[n+84>>2]=n+112;A:{if((0|u)<=0)b=n+112|0;else{for(k=0;;){if(c=a[8+(a[Q+16>>2]+B(k,12)|0)>>2],c){if(Qt[a[a[c>>2]+16>>2]](c,n+72|0),b=a[n+76>>2],(0|b)>=1)for(u=0,l=0;c=a[a[n+84>>2]+u>>2],a[c+780>>2]&&(a[t+4>>2]=c,H=a[c+772>>2],p=a[a[t+8>>2]+8>>2],b=(0|H)==(0|p),P=c,c=a[a[t+12>>2]+8>>2],se(P,(b?H:c)+4|0,(b?c:p)+4|0),a[t+4>>2]=0,b=a[n+76>>2]),u=u+4|0,l=l+1|0,(0|l)<(0|b););if((0|b)<=-1)for(a[n+80>>2]<=-1&&(c=a[n+84>>2],c&&(o[n+88|0]&&CA(c),a[n+84>>2]=0),f[n+88|0]=1,a[n+80>>2]=0,a[n+84>>2]=0),u=b<<2;a[a[n+84>>2]+u>>2]=0,u=u+4|0,c=b+1|0,l=c>>>0>=b>>>0,b=c,l;);a[n+76>>2]=0,u=a[Q+8>>2]}if(k=k+1|0,!((0|k)<(0|u)))break}if(b=a[n+84>>2],!b)break A}o[n+88|0]&&CA(b),a[n+84>>2]=0}if(a[n+92>>2]=i,a[n+76>>2]=0,a[n+72>>2]=16988,a[n+88>>2]=a[A+4>>2],a[n+104>>2]=a[A+72>>2],a[n+100>>2]=a[A+84>>2],a[n+84>>2]=r,i=a[r+12>>2],s=C[i+56>>2],a[n+80>>2]=e,c=a[e+12>>2],v=C[c+40>>2],U=C[i+52>>2],d=C[c+24>>2],Z=C[i+48>>2],G=C[c+8>>2],M=C[c+56>>2],V=C[c+52>>2],j=C[c+48>>2],g=C[c+36>>2],R=C[c+20>>2],y=C[c+4>>2],N=C[i+40>>2],S=C[i+24>>2],I=C[i+8>>2],X=C[i+36>>2],w=C[i+20>>2],J=C[i+4>>2],W=C[c>>2],D=C[c+16>>2],h=C[c+32>>2],x=C[i+16>>2],O=C[i>>2],z=C[i+32>>2],a[n+96>>2]=t,i=a[F>>2],i&&(c=a[T>>2],c)){for(j=_(-j),q=_(_(_(_(G*j)-_(d*V))-_(v*M))+_(_(_(G*Z)+_(d*U))+_(v*s))),iA=_(_(_(_(y*j)-_(R*V))-_(g*M))+_(_(_(y*Z)+_(R*U))+_(g*s))),U=_(_(_(_(W*j)-_(D*V))-_(h*M))+_(_(_(W*Z)+_(D*U))+_(h*s))),s=C[t+32>>2],a[n+116>>2]=c,a[n+112>>2]=i,Z=_(_(_(G*I)+_(d*S))+_(v*N)),M=_(m(Z)),V=_(_(_(G*J)+_(d*w))+_(v*X)),j=_(m(V)),$=_(_(_(G*O)+_(d*x))+_(v*z)),fA=_(m($)),AA=_(_(_(y*I)+_(R*S))+_(g*N)),tA=_(m(AA)),eA=_(_(_(y*J)+_(R*w))+_(g*X)),nA=_(m(eA)),rA=_(_(_(y*O)+_(R*x))+_(g*z)),aA=_(m(rA)),N=_(_(_(W*I)+_(D*S))+_(h*N)),S=_(m(N)),I=_(_(_(W*J)+_(D*w))+_(h*X)),X=_(m(I)),W=_(_(_(W*O)+_(D*x))+_(h*z)),D=_(m(W)),T=124,l=0,k=128,c=n+112|0,i=128,u=1;;){A:{e:{r:{if(H=u+-1|0,P=H<<3,b=P+c|0,E=a[b>>2],p=a[b+4>>2],g=C[p+16>>2],R=C[p>>2],v=_(_(_(g-R)*_(.5))+_(0)),y=C[p+20>>2],h=C[p+4>>2],d=_(_(_(y-h)*_(.5))+_(0)),w=C[p+24>>2],J=C[p+8>>2],G=_(_(_(w-J)*_(.5))+_(0)),x=_(_(_(D*v)+_(X*d))+_(S*G)),g=_(_(g+R)*_(.5)),R=_(_(y+h)*_(.5)),y=_(_(w+J)*_(.5)),h=_(U+_(_(_(W*g)+_(I*R))+_(N*y))),!(C[E>>2]<=_(s+_(x+h))^1|C[E+16>>2]>=_(_(h-x)-s)^1||(h=_(_(_(aA*v)+_(nA*d))+_(tA*G)),w=_(iA+_(_(_(rA*g)+_(eA*R))+_(AA*y))),C[E+4>>2]<=_(s+_(h+w))^1|C[E+20>>2]>=_(_(w-h)-s)^1||(v=_(_(_(fA*v)+_(j*d))+_(M*G)),d=_(q+_(_(_($*g)+_(V*R))+_(Z*y))),C[E+8>>2]<=_(s+_(v+d))^1|C[E+24>>2]>=_(_(d-v)-s)^1)))){if((0|H)<=(0|T))Q=k,b=c,F=l;else{Q=k<<1;i:if((0|k)>=(0|Q)|(0|i)>=(0|Q))b=c,F=l;else{f:{t:{n:{if(k){if(b=dA(k<<4),!((0|k)<1)){for(T=b,i=c;F=a[i+4>>2],a[T>>2]=a[i>>2],a[T+4>>2]=F,T=T+8|0,i=i+8|0,k=k+-1|0,k;);if(!(255&l))break t;break n}}else b=0;if(F=1,i=F,!c)break f;if(i=Q,!(255&l))break i}CA(c)}i=1}F=i,i=Q}T=Q+-4|0}if(c=a[p+40>>2],a[E+40>>2]){if(l=a[E+36>>2],c){c=b+P|0,a[c+4>>2]=a[p+36>>2],a[c>>2]=l,l=a[E+40>>2],c=(u<<3)+b|0,a[c+4>>2]=a[p+36>>2],a[c>>2]=l,l=a[E+36>>2],a[c+12>>2]=a[p+40>>2],a[c+8>>2]=l,l=a[E+40>>2],a[c+20>>2]=a[p+40>>2],a[c+16>>2]=l,u=u+3|0;break e}c=b+P|0,a[c+4>>2]=p,a[c>>2]=l,c=a[E+40>>2],l=(u<<3)+b|0,a[l+4>>2]=p,a[l>>2]=c;break r}if(c){c=b+P|0,a[c+4>>2]=a[p+36>>2],a[c>>2]=E,c=(u<<3)+b|0,a[c+4>>2]=a[p+40>>2],a[c>>2]=E;break r}Qt[a[a[n+72>>2]+8>>2]](n+72|0,E,p),k=Q,c=b,l=F}u=H;break A}u=u+1|0}k=Q,c=b,l=F}if(!u)break}!c|!(255&l)||CA(c)}if(Q=a[A+84>>2],a[Q+8>>2]>=1)for(c=0;;){if(F=B(c,12),i=F+a[Q+16>>2]|0,l=a[i+8>>2],l&&(i=a[K+28>>2]+B(a[i>>2],80)|0,k=a[i+64>>2],b=a[e+12>>2],O=C[b+52>>2],z=C[b+56>>2],h=C[i+48>>2],U=C[i+52>>2],Z=C[i+56>>2],M=C[i+4>>2],V=C[i+20>>2],N=C[i+36>>2],S=C[i+8>>2],I=C[i+24>>2],X=C[i+40>>2],s=C[b+20>>2],v=C[b+24>>2],w=C[i>>2],d=C[b+36>>2],J=C[i+16>>2],G=C[b+40>>2],x=C[i+32>>2],j=C[b+48>>2],g=C[b+8>>2],R=C[b>>2],y=C[b+4>>2],W=C[b+16>>2],D=C[b+32>>2],a[n+172>>2]=0,a[n+156>>2]=0,a[n+140>>2]=0,a[n+124>>2]=0,C[n+144>>2]=_(_(D*w)+_(d*J))+_(G*x),C[n+128>>2]=_(_(W*w)+_(s*J))+_(v*x),C[n+112>>2]=_(_(R*w)+_(y*J))+_(g*x),C[n+152>>2]=_(_(D*S)+_(d*I))+_(G*X),C[n+148>>2]=_(_(D*M)+_(d*V))+_(G*N),C[n+136>>2]=_(_(W*S)+_(s*I))+_(v*X),C[n+132>>2]=_(_(W*M)+_(s*V))+_(v*N),C[n+120>>2]=_(_(R*S)+_(y*I))+_(g*X),C[n+116>>2]=_(_(R*M)+_(y*V))+_(g*N),C[n+168>>2]=z+_(_(_(D*h)+_(d*U))+_(G*Z)),C[n+164>>2]=O+_(_(_(W*h)+_(s*U))+_(v*Z)),C[n+160>>2]=j+_(_(_(R*h)+_(y*U))+_(g*Z)),Qt[a[a[k>>2]+8>>2]](k,n+112|0,n+56|0,n+40|0),s=C[t+32>>2],C[n+56>>2]=C[n+56>>2]-s,C[n+60>>2]=C[n+60>>2]-s,C[n+64>>2]=C[n+64>>2]-s,C[n+40>>2]=s+C[n+40>>2],C[n+44>>2]=s+C[n+44>>2],C[n+48>>2]=s+C[n+48>>2],i=a[L+28>>2]+B(a[4+(F+a[Q+16>>2]|0)>>2],80)|0,k=a[i+64>>2],b=a[r+12>>2],z=C[b+52>>2],j=C[b+56>>2],U=C[i+48>>2],Z=C[i+52>>2],M=C[i+56>>2],V=C[i+4>>2],N=C[i+20>>2],S=C[i+36>>2],I=C[i+8>>2],X=C[i+24>>2],w=C[i+40>>2],v=C[b+20>>2],d=C[b+24>>2],J=C[i>>2],G=C[b+36>>2],x=C[i+16>>2],g=C[b+40>>2],O=C[i+32>>2],q=C[b+48>>2],R=C[b+8>>2],y=C[b>>2],W=C[b+4>>2],D=C[b+16>>2],h=C[b+32>>2],a[n+172>>2]=0,a[n+156>>2]=0,a[n+140>>2]=0,a[n+124>>2]=0,C[n+144>>2]=_(_(h*J)+_(G*x))+_(g*O),C[n+128>>2]=_(_(D*J)+_(v*x))+_(d*O),C[n+112>>2]=_(_(y*J)+_(W*x))+_(R*O),C[n+152>>2]=_(_(h*I)+_(G*X))+_(g*w),C[n+148>>2]=_(_(h*V)+_(G*N))+_(g*S),C[n+136>>2]=_(_(D*I)+_(v*X))+_(d*w),C[n+132>>2]=_(_(D*V)+_(v*N))+_(d*S),C[n+120>>2]=_(_(y*I)+_(W*X))+_(R*w),C[n+116>>2]=_(_(y*V)+_(W*N))+_(R*S),C[n+168>>2]=j+_(_(_(h*U)+_(G*Z))+_(g*M)),C[n+164>>2]=z+_(_(_(D*U)+_(v*Z))+_(d*M)),C[n+160>>2]=q+_(_(_(y*U)+_(W*Z))+_(R*M)),Qt[a[a[k>>2]+8>>2]](k,n+112|0,n+24|0,n+8|0),v=_(C[n+24>>2]-s),C[n+24>>2]=v,d=_(C[n+28>>2]-s),C[n+28>>2]=d,G=_(C[n+32>>2]-s),C[n+32>>2]=G,g=_(s+C[n+8>>2]),C[n+8>>2]=g,R=_(s+C[n+16>>2]),C[n+16>>2]=R,s=_(s+C[n+12>>2]),C[n+12>>2]=s,C[n+44>>2]>2]>s|C[n+40>>2]>2]>g||C[n+64>>2]>R||C[n+48>>2]>2]>>2]](l),i=a[A+4>>2],Qt[a[a[i>>2]+60>>2]](i,l),i=F+a[Q+16>>2]|0,T=a[i+4>>2],H=a[i>>2],u=a[A+92>>2],(0|u)==a[A+96>>2]&&(i=u?u<<1:1,!((0|u)>=(0|i)))){if(i?(k=dA(B(i,12)),u=a[A+92>>2]):k=0,(0|u)>=1)for(b=0;F=a[A+100>>2]+b|0,p=a[F+4>>2],l=b+k|0,a[l>>2]=a[F>>2],a[l+4>>2]=p,a[l+8>>2]=a[F+8>>2],b=b+12|0,u=u+-1|0,u;);b=a[A+100>>2],b&&(o[A+104|0]&&CA(b),a[A+100>>2]=0),a[A+100>>2]=k,f[A+104|0]=1,a[A+96>>2]=i,u=a[A+92>>2]}i=a[A+100>>2]+B(u,12)|0,a[i+8>>2]=0,a[i+4>>2]=T,a[i>>2]=H,a[A+92>>2]=a[A+92>>2]+1}if(c=c+1|0,!((0|c)>2]))break}if(a[A+92>>2]>=1)for(u=0,b=4;e=a[A+84>>2],r=a[A+100>>2]+b|0,Qt[a[a[e>>2]+8>>2]](e,a[r+-4>>2],a[r>>2]),b=b+12|0,u=u+1|0,(0|u)>2];);e=a[A+100>>2],e&&(o[A+104|0]&&CA(e),a[A+100>>2]=0),a[A+100>>2]=0,a[A+92>>2]=0,a[A+96>>2]=0,f[A+104|0]=1}else ti(A,e,r,i,t);Y=n+3328|0},function(A,e,r,i,f){return _(_(0))},function(A,e){A|=0,e|=0;var r=0,i=0,f=0,t=0;if(r=8,A=a[A+84>>2],i=a[A+8>>2],(0|i)>=1)for(;f=a[a[A+16>>2]+r>>2],f&&(Qt[a[a[f>>2]+16>>2]](f,e),i=a[A+8>>2]),r=r+12|0,t=t+1|0,(0|t)<(0|i););},ve,function(A,e,r){A|=0,e|=0,r|=0;var i,f,t,n,o,c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=0,Z=0,V=0,N=_(0),I=_(0),J=0,x=0;i=Y-256|0,Y=i,Lr(i+248|0,17064),a[A+4>>2]=a[A+4>>2]+1,f=a[r+36>>2],n=B(f,80),V=a[A+12>>2],o=a[V+4>>2]+28|0,E=a[64+(n+a[o>>2]|0)>>2],r=a[A+8>>2],t=a[e+36>>2],e=a[a[r+4>>2]+28>>2]+B(t,80)|0,Z=a[e+64>>2],r=a[r+12>>2],R=C[r+52>>2],k=C[r+56>>2],u=C[r+24>>2],s=C[r+20>>2],c=C[r+40>>2],b=C[r+36>>2],N=C[r+48>>2],v=C[r+8>>2],d=C[r>>2],g=C[r+4>>2],m=C[r+16>>2],l=C[r+32>>2],r=0,a[i+244>>2]=0,a[i+228>>2]=0,a[i+212>>2]=0,Q=C[e+8>>2],h=C[e+24>>2],G=C[e+40>>2],C[i+224>>2]=_(_(l*Q)+_(b*h))+_(c*G),y=C[e+4>>2],p=C[e+20>>2],F=C[e+36>>2],C[i+220>>2]=_(_(l*y)+_(b*p))+_(c*F),C[i+208>>2]=_(_(m*Q)+_(s*h))+_(u*G),C[i+204>>2]=_(_(m*y)+_(s*p))+_(u*F),W=k,k=C[e+48>>2],w=C[e+52>>2],D=C[e+56>>2],C[i+240>>2]=W+_(_(_(l*k)+_(b*w))+_(c*D)),C[i+236>>2]=R+_(_(_(m*k)+_(s*w))+_(u*D)),a[i+196>>2]=0,W=l,l=C[e>>2],R=b,b=C[e+16>>2],I=c,c=C[e+32>>2],C[i+216>>2]=_(_(W*l)+_(R*b))+_(I*c),C[i+200>>2]=_(_(m*l)+_(s*b))+_(u*c),C[i+192>>2]=_(_(d*Q)+_(g*h))+_(v*G),C[i+188>>2]=_(_(d*y)+_(g*p))+_(v*F),C[i+184>>2]=_(_(d*l)+_(g*b))+_(v*c),C[i+232>>2]=N+_(_(_(d*k)+_(g*w))+_(v*D)),e=a[V+12>>2],R=C[e+52>>2],k=C[e+56>>2],u=C[e+24>>2],s=C[e+20>>2],c=C[e+40>>2],b=C[e+36>>2],V=a[o>>2],N=C[e+48>>2],v=C[e+8>>2],d=C[e>>2],g=C[e+4>>2],m=C[e+16>>2],l=C[e+32>>2],a[i+180>>2]=0,a[i+164>>2]=0,a[i+148>>2]=0,e=V+n|0,Q=C[e+8>>2],h=C[e+24>>2],G=C[e+40>>2],C[i+160>>2]=_(_(l*Q)+_(b*h))+_(c*G),y=C[e+4>>2],p=C[e+20>>2],F=C[e+36>>2],C[i+156>>2]=_(_(l*y)+_(b*p))+_(c*F),C[i+144>>2]=_(_(m*Q)+_(s*h))+_(u*G),C[i+140>>2]=_(_(m*y)+_(s*p))+_(u*F),W=k,k=C[e+48>>2],w=C[e+52>>2],D=C[e+56>>2],C[i+176>>2]=W+_(_(_(l*k)+_(b*w))+_(c*D)),C[i+172>>2]=R+_(_(_(m*k)+_(s*w))+_(u*D)),a[i+132>>2]=0,W=l,l=C[e>>2],R=b,b=C[e+16>>2],I=c,c=C[e+32>>2],C[i+152>>2]=_(_(W*l)+_(R*b))+_(I*c),C[i+136>>2]=_(_(m*l)+_(s*b))+_(u*c),C[i+128>>2]=_(_(d*Q)+_(g*h))+_(v*G),C[i+124>>2]=_(_(d*y)+_(g*p))+_(v*F),C[i+120>>2]=_(_(d*l)+_(g*b))+_(v*c),C[i+168>>2]=N+_(_(_(d*k)+_(g*w))+_(v*D)),Qt[a[a[Z>>2]+8>>2]](Z,i+184|0,i+104|0,i+88|0),Qt[a[a[E>>2]+8>>2]](E,i+120|0,i+72|0,i+56|0),u=C[a[A+24>>2]+32>>2],s=_(C[i+104>>2]-u),C[i+104>>2]=s,C[i+108>>2]=C[i+108>>2]-u,C[i+112>>2]=C[i+112>>2]-u,C[i+88>>2]=u+C[i+88>>2],C[i+92>>2]=u+C[i+92>>2],C[i+96>>2]=u+C[i+96>>2],e=a[693];A:{if(e){if(!Qt[e](Z,E))break A;s=C[i+104>>2]}s>C[i+56>>2]|C[i+88>>2]>2]||(r=1),e=0,e=C[i+96>>2]>2]|C[i+112>>2]>C[i+64>>2]?e:r,C[i+92>>2]>2]|C[i+108>>2]>C[i+60>>2]|1^e||(a[i+48>>2]=-1,a[i+36>>2]=Z,e=a[A+8>>2],a[i+32>>2]=e,a[i+40>>2]=a[e+8>>2],a[i+44>>2]=i+184,a[i+52>>2]=t,a[i+24>>2]=-1,a[i+12>>2]=E,e=a[A+12>>2],a[i+8>>2]=e,a[i+16>>2]=a[e+8>>2],a[i+20>>2]=i+120,a[i+28>>2]=f,e=function(A,e,r){var i=0,f=0,t=0;a[692]=a[692]+1,i=r<<16|e,i=(i<<15^-1)+i|0,i=B(i>>>10^i,9),i^=i>>>6,i=(i<<11^-1)+i|0,i=a[A+12>>2]+-1&(i>>>16^i);e:{if(!((0|i)>=a[A+28>>2])&&(i=a[a[A+36>>2]+(i<<2)>>2],-1!=(0|i)))for(t=a[A+16>>2];;){if(f=B(i,12)+t|0,a[f+4>>2]==(0|r)&&(0|e)==a[f>>2])break e;if(i=a[a[A+56>>2]+(i<<2)>>2],-1==(0|i))break}f=0}return f}(a[A+28>>2],t,f),C[a[A+24>>2]+32>>2]>_(0)?(e=a[A+16>>2],r=0|Qt[a[a[e>>2]+8>>2]](e,i+32|0,i+8|0,0,2)):e?r=a[e+8>>2]:(e=a[A+16>>2],r=0|Qt[a[a[e>>2]+8>>2]](e,i+32|0,i+8|0,a[A+32>>2],1),e=a[A+28>>2],J=0|Qt[a[a[e>>2]+12>>2]](e,t,f),x=r,a[J+8>>2]=x),e=a[A+24>>2],E=a[e+12>>2],Z=a[e+8>>2],a[e+12>>2]=i+8,a[e+8>>2]=i+32,Qt[a[a[e>>2]+8>>2]](e,-1,t),e=a[A+24>>2],Qt[a[a[e>>2]+12>>2]](e,-1,f),Qt[a[a[r>>2]+8>>2]](r,i+32|0,i+8|0,a[A+20>>2],a[A+24>>2]),A=a[A+24>>2],a[A+8>>2]=Z,a[A+12>>2]=E)}qr(),Y=i+256|0},Rr,ve,Ar,Re,Rr,function(A){A|=0;var e=0,r=0;return a[A>>2]=17172,o[A+8|0]&&(e=a[A+12>>2],e&&(r=a[A+4>>2],Qt[a[a[r>>2]+16>>2]](r,e))),0|A},function(A){A|=0;var e=0,r=0;a[A>>2]=17172,o[A+8|0]&&(e=a[A+12>>2],e&&(r=a[A+4>>2],Qt[a[a[r>>2]+16>>2]](r,e))),$(A)},function(A,e,r,i,f){A|=0,e|=0,r|=0,i|=0,f|=0;var t=_(0),n=0,o=_(0),c=0,b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0);if(i=Y-32|0,Y=i,A=a[A+12>>2],A){if(a[f+4>>2]=A,n=a[e+12>>2],c=a[r+12>>2],s=_(C[n+48>>2]-C[c+48>>2]),b=_(C[n+52>>2]-C[c+52>>2]),l=_(C[n+56>>2]-C[c+56>>2]),t=_(_(_(s*s)+_(b*b))+_(l*l)),n=a[r+4>>2],u=C[n+16>>2],o=C[n+32>>2],e=a[e+4>>2],k=C[e+16>>2],v=C[e+32>>2],n=a[A+780>>2],(0|n)>=1)for(e=A+4|0,c=0;le(e),e=e+192|0,c=c+1|0,n=a[A+780>>2],(0|c)<(0|n););t=_(y(t)),u=_(o*u),o=_(v*k),n&&(e=a[424],e&&(a[i+16>>2]=A,Qt[e](i+16|0))),a[A+780>>2]=0,o=_(o+u),t>_(o+C[f+32>>2])||(a[i+24>>2]=0,a[i+28>>2]=0,a[i+16>>2]=1065353216,a[i+20>>2]=0,o=_(t-o),t>_(1.1920928955078125e-7)?(a[i+28>>2]=0,t=_(_(1)/t),l=_(l*t),C[i+24>>2]=l,b=_(b*t),C[i+20>>2]=b,t=_(s*t),C[i+16>>2]=t):(t=_(1),l=_(0),b=_(0)),a[i+12>>2]=0,A=a[r+12>>2],C[i>>2]=_(u*t)+C[A+48>>2],C[i+8>>2]=_(u*l)+C[A+56>>2],C[i+4>>2]=_(u*b)+C[A+52>>2],Qt[a[a[f>>2]+16>>2]](f,i+16|0,i,o))}Y=i+32|0},Re,ui,ve,si,function(A){A|=0;var e=0,r=0;return a[A>>2]=17308,o[A+8|0]&&(e=a[A+12>>2],e&&(r=a[A+4>>2],Qt[a[a[r>>2]+16>>2]](r,e))),0|A},function(A){A|=0;var e=0,r=0;a[A>>2]=17308,o[A+8|0]&&(e=a[A+12>>2],e&&(r=a[A+4>>2],Qt[a[a[r>>2]+16>>2]](r,e))),$(A)},function(A,e,r,i,f){A|=0,e|=0,r|=0,i|=0,f|=0;var t,n=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0,g=0;t=Y-160|0,Y=t,u=a[A+12>>2],u&&(a[f+4>>2]=u,n=o[A+16|0],c=n?r:e,k=a[c+4>>2],n=n?e:r,r=a[n+4>>2],e=t+144|0,C[e+12>>2]=C[u+784>>2]+C[f+32>>2],a[e+8>>2]=r,a[e+4>>2]=k,a[e>>2]=17248,u=e,a[t+136>>2]=1566444395,e=a[c+12>>2],c=a[e>>2],k=a[e+4>>2],r=e+8|0,v=a[r>>2],r=a[r+4>>2],b=e+24|0,s=a[b+4>>2],l=t+32|0,a[l>>2]=a[b>>2],a[l+4>>2]=s,b=t+16|0,a[b>>2]=v,a[b+4>>2]=r,r=a[e+16>>2],v=a[e+20>>2],b=e+40|0,s=a[b+4>>2],l=t+48|0,a[l>>2]=a[b>>2],a[l+4>>2]=s,b=a[e+32>>2],s=a[e+36>>2],l=e+56|0,g=a[l+4>>2],d=t- -64|0,a[d>>2]=a[l>>2],a[d+4>>2]=g,a[t+8>>2]=c,a[t+12>>2]=k,a[t+24>>2]=r,a[t+28>>2]=v,a[t+40>>2]=b,a[t+44>>2]=s,r=a[e+52>>2],a[t+56>>2]=a[e+48>>2],a[t+60>>2]=r,e=a[n+12>>2],r=e+8|0,n=a[r+4>>2],c=t+80|0,a[c>>2]=a[r>>2],a[c+4>>2]=n,r=a[e+4>>2],a[t+72>>2]=a[e>>2],a[t+76>>2]=r,r=e+24|0,n=a[r+4>>2],c=t+96|0,a[c>>2]=a[r>>2],a[c+4>>2]=n,r=a[e+20>>2],n=t+88|0,a[n>>2]=a[e+16>>2],a[n+4>>2]=r,r=e+40|0,n=a[r+4>>2],c=t+112|0,a[c>>2]=a[r>>2],a[c+4>>2]=n,r=a[e+36>>2],n=t+104|0,a[n>>2]=a[e+32>>2],a[n+4>>2]=r,r=a[e+52>>2],n=t+120|0,a[n>>2]=a[e+48>>2],a[n+4>>2]=r,e=e+56|0,r=a[e+4>>2],n=t+128|0,a[n>>2]=a[e>>2],a[n+4>>2]=r,si(u,t+8|0,f,a[i+20>>2],o[A+16|0]),o[A+8|0]&&(A=a[f+4>>2],a[A+780>>2]&&(e=a[A+772>>2],r=a[a[f+8>>2]+8>>2],(0|e)==(0|r)?se(A,e+4|0,a[a[f+12>>2]+8>>2]+4|0):se(A,a[a[f+12>>2]+8>>2]+4|0,r+4|0)))),Y=t+160|0},Re,ui,ve,Ci,function(A){A|=0;var e=0,r=0;return a[A>>2]=17516,o[A+8|0]&&(e=a[A+12>>2],e&&(r=a[A+4>>2],Qt[a[a[r>>2]+16>>2]](r,e))),0|A},function(A){A|=0;var e=0,r=0;a[A>>2]=17516,o[A+8|0]&&(e=a[A+12>>2],e&&(r=a[A+4>>2],Qt[a[a[r>>2]+16>>2]](r,e))),$(A)},function(A,e,r,i,f){A|=0,e|=0,r|=0,i|=0,f|=0;var t,n=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0,C=0,g=0;t=Y-160|0,Y=t,s=a[A+12>>2],s&&(a[f+4>>2]=s,s=a[r+4>>2],C=a[e+4>>2],a[t+152>>2]=1566444395,e=a[e+12>>2],n=e+8|0,c=a[n+4>>2],b=t+32|0,a[b>>2]=a[n>>2],a[b+4>>2]=c,n=a[e>>2],c=a[e+4>>2],b=e+24|0,k=a[b+4>>2],l=t+48|0,a[l>>2]=a[b>>2],a[l+4>>2]=k,b=a[e+16>>2],k=a[e+20>>2],l=e+40|0,v=a[l+4>>2],u=t- -64|0,a[u>>2]=a[l>>2],a[u+4>>2]=v,l=a[e+32>>2],v=a[e+36>>2],u=e+56|0,g=a[u+4>>2],d=t+80|0,a[d>>2]=a[u>>2],a[d+4>>2]=g,a[t+24>>2]=n,a[t+28>>2]=c,a[t+40>>2]=b,a[t+44>>2]=k,a[t+56>>2]=l,a[t+60>>2]=v,n=a[e+52>>2],a[t+72>>2]=a[e+48>>2],a[t+76>>2]=n,e=a[r+12>>2],r=e+8|0,n=a[r+4>>2],c=t+96|0,a[c>>2]=a[r>>2],a[c+4>>2]=n,r=a[e+4>>2],a[t+88>>2]=a[e>>2],a[t+92>>2]=r,r=a[e+20>>2],n=t+104|0,a[n>>2]=a[e+16>>2],a[n+4>>2]=r,r=e+24|0,n=a[r+4>>2],c=t+112|0,a[c>>2]=a[r>>2],a[c+4>>2]=n,r=e+40|0,n=a[r+4>>2],c=t+128|0,a[c>>2]=a[r>>2],a[c+4>>2]=n,r=a[e+36>>2],n=t+120|0,a[n>>2]=a[e+32>>2],a[n+4>>2]=r,r=a[e+52>>2],n=t+136|0,a[n>>2]=a[e+48>>2],a[n+4>>2]=r,e=e+56|0,r=a[e+4>>2],n=t+144|0,a[n>>2]=a[e>>2],a[n+4>>2]=r,e=t+8|0,a[e+8>>2]=s,a[e+4>>2]=C,a[e>>2]=17464,Ci(e,t+24|0,f,a[i+20>>2],0),o[A+8|0]&&(A=a[f+4>>2],a[A+780>>2]&&(e=a[A+772>>2],r=a[a[f+8>>2]+8>>2],(0|e)==(0|r)?se(A,e+4|0,a[a[f+12>>2]+8>>2]+4|0):se(A,a[a[f+12>>2]+8>>2]+4|0,r+4|0)))),Y=t+160|0},Re,ui,function(A){A|=0;var e=0,r=0;return a[A>>2]=17588,o[A+8|0]&&(e=a[A+12>>2],e&&(r=a[A+4>>2],Qt[a[a[r>>2]+16>>2]](r,e))),0|A},function(A){A|=0;var e=0,r=0;a[A>>2]=17588,o[A+8|0]&&(e=a[A+12>>2],e&&(r=a[A+4>>2],Qt[a[a[r>>2]+16>>2]](r,e))),$(A)},function(A,e,r,i,f){A|=0,e|=0,r|=0,i|=0,f|=0;var t=_(0),n=_(0),c=0,b=_(0),l=_(0),u=0,s=0,k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),R=_(0),h=0,G=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0),Z=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0),U=_(0),M=0,S=_(0),X=_(0),T=_(0),j=_(0),O=_(0),H=0,z=_(0),P=_(0),K=_(0),L=_(0),q=_(0),$=_(0),AA=_(0),eA=_(0),rA=_(0),iA=_(0),fA=_(0),tA=_(0),nA=_(0),aA=_(0),oA=_(0),cA=_(0),bA=_(0);if(i=Y-48|0,Y=i,a[A+12>>2]){if(s=o[A+16|0],h=s?r:e,c=a[h+12>>2],G=C[c+56>>2],p=C[c+52>>2],F=C[c+48>>2],M=s?e:r,u=a[M+12>>2],S=C[u+56>>2],L=C[u+48>>2],X=C[u+52>>2],h=a[h+4>>2],W=C[c+32>>2],w=C[c+16>>2],D=C[c>>2],E=C[c+36>>2],Z=C[c+20>>2],V=C[c+4>>2],n=C[u+40>>2],b=C[u+24>>2],t=C[u+8>>2],l=C[u+32>>2],d=C[u+16>>2],k=C[u>>2],s=a[M+4>>2],B=C[u+36>>2],g=C[c+40>>2],R=C[u+20>>2],N=C[c+24>>2],v=C[u+4>>2],I=C[c+8>>2],a[i+28>>2]=0,j=_(_(_(I*k)+_(N*d))+_(g*l)),J=_(-C[s+52>>2]),O=_(_(_(I*v)+_(N*R))+_(g*B)),u=s+56|0,x=C[u>>2],N=_(_(_(I*t)+_(N*b))+_(g*n)),H=s+60|0,g=C[H>>2],C[i+24>>2]=_(_(j*J)-_(O*x))-_(N*g),I=_(_(_(V*k)+_(Z*d))+_(E*l)),z=_(_(_(V*v)+_(Z*R))+_(E*B)),P=_(_(_(V*t)+_(Z*b))+_(E*n)),C[i+20>>2]=_(_(I*J)-_(x*z))-_(g*P),K=_(_(_(D*k)+_(w*d))+_(W*l)),T=_(K*J),J=_(_(_(D*v)+_(w*R))+_(W*B)),U=g,g=_(_(_(D*t)+_(w*b))+_(W*n)),C[i+16>>2]=_(T-_(x*J))-_(U*g),Qt[a[a[h>>2]+64>>2]](i+32|0,h,i+16|0),c=a[M+12>>2],x=C[c+48>>2],q=C[c+32>>2],$=C[c+16>>2],AA=C[c+8>>2],eA=C[c+4>>2],rA=C[c>>2],iA=C[c+56>>2],fA=C[c+52>>2],tA=C[c+40>>2],nA=C[c+36>>2],aA=C[c+24>>2],oA=C[c+20>>2],cA=C[s+68>>2],E=C[H>>2],Z=C[s+52>>2],V=C[u>>2],W=C[i+40>>2],w=C[i+32>>2],D=C[i+36>>2],bA=C[a[A+12>>2]+784>>2],a[f+4>>2]=a[A+12>>2],T=_(_(_(F*t)+_(p*b))+_(G*n)),U=t,t=_(-L),g=_(_(T+_(_(_(U*t)-_(b*X))-_(n*S)))+_(_(_(g*w)+_(P*D))+_(N*W))),d=_(_(_(_(_(F*k)+_(p*d))+_(G*l))+_(_(_(k*t)-_(d*X))-_(l*S)))+_(_(_(K*w)+_(I*D))+_(j*W))),k=_(_(_(_(_(F*v)+_(p*R))+_(G*B))+_(_(_(v*t)-_(R*X))-_(B*S)))+_(_(_(J*w)+_(z*D))+_(O*W))),n=_(_(_(E*g)+_(_(Z*d)+_(V*k)))-cA),n>2]=0,c=a[M+12>>2],b=C[s+52>>2],t=C[s+56>>2],l=C[s+60>>2],C[i+16>>2]=_(_(C[c>>2]*b)+_(C[c+4>>2]*t))+_(C[c+8>>2]*l),C[i+24>>2]=_(_(b*C[c+32>>2])+_(t*C[c+36>>2]))+_(l*C[c+40>>2]),C[i+20>>2]=_(_(b*C[c+16>>2])+_(t*C[c+20>>2]))+_(l*C[c+24>>2]),a[i+12>>2]=0,b=_(d-_(Z*n)),t=_(k-_(V*n)),l=_(g-_(E*n)),C[i+8>>2]=_(_(_(b*q)+_(t*nA))+_(l*tA))+iA,C[i+4>>2]=_(_(_(b*$)+_(t*oA))+_(l*aA))+fA,C[i>>2]=_(_(AA*l)+_(_(rA*b)+_(eA*t)))+x,Qt[a[a[f>>2]+16>>2]](f,i+16|0,i,n)),!(a[h+4>>2]>6|a[a[f+4>>2]+780>>2]>=a[A+24>>2]||(b=C[s+60>>2],_(m(b))>_(.7071067690849304)?(n=C[s+56>>2],t=_(_(1)/_(y(_(_(b*b)+_(n*n))))),n=_(n*t),b=_(-_(b*t)),t=_(0)):(n=C[s+52>>2],t=C[s+56>>2],l=_(_(1)/_(y(_(_(n*n)+_(t*t))))),b=_(n*l),n=_(0),t=_(-_(t*l))),l=_(Qt[a[a[h>>2]+16>>2]](h)),c=0,l=_(_(Q(_(C[744]/l),_(.39269909262657166)))*_(.5)),k=dr(l),u=a[A+20>>2],d=Cr(l),(0|u)<1)))for(U=n,n=_(k/_(y(_(_(_(t*t)+_(b*b))+_(n*n))))),k=_(U*n),B=_(b*n),R=_(t*n);t=C[s+56>>2],l=C[s+60>>2],n=C[s+52>>2],b=_(_(_(_(6.2831854820251465)/_(0|u))*_(0|c))*_(.5)),v=_(dr(b)/_(y(_(_(_(n*n)+_(t*t))+_(l*l))))),n=_(n*v),b=Cr(b),t=_(t*v),l=_(l*v),v=_(_(_(_(d*b)+_(R*n))+_(B*t))+_(k*l)),G=_(_(_(_(R*b)-_(d*n))-_(k*t))+_(B*l)),p=_(_(_(_(B*b)-_(d*t))-_(R*l))+_(k*n)),F=_(_(_(_(k*b)-_(d*l))-_(B*n))+_(R*t)),C[i+28>>2]=_(_(_(b*v)-_(n*G))-_(t*p))-_(l*F),C[i+24>>2]=_(_(t*G)+_(_(l*v)+_(b*F)))-_(n*p),C[i+20>>2]=_(_(n*F)+_(_(b*p)+_(t*v)))-_(l*G),C[i+16>>2]=_(_(l*p)+_(_(n*v)+_(b*G)))-_(t*F),gi(A,i+16|0,e,r,f),c=c+1|0,u=a[A+20>>2],(0|c)<(0|u););!o[A+8|0]|!a[a[A+12>>2]+780>>2]||(A=a[f+4>>2],a[A+780>>2]&&(e=a[A+772>>2],r=a[a[f+8>>2]+8>>2],(0|e)==(0|r)?se(A,e+4|0,a[a[f+12>>2]+8>>2]+4|0):se(A,a[a[f+12>>2]+8>>2]+4|0,r+4|0)))}Y=i+48|0},Re,ui,_i,function(A){A|=0,$(_i(A))},mi,function(A){return A|=0,a[A+16>>2]},function(A,e,r){var i;if(A|=0,e|=0,r|=0,i=8!=(0|e),!(i|8!=(0|r)))return a[A+56>>2];if(!(1!=(0|r)|i))return a[A+72>>2];if(!(1!=(0|e)|8!=(0|r)))return a[A+76>>2];if(!(e|r))return a[A+68>>2];if(!(28!=(0|r)|(0|e)>19))return a[A+84>>2];if(!(28!=(0|e)|(0|r)>19))return a[A+80>>2];A:{if((0|e)<=19){if((0|r)<=19)return a[A+28>>2];if(r+-21>>>0>8)break A;return a[A+32>>2]}if(!((0|r)>19|e+-21>>>0>8))return a[A+36>>2];if(31==(0|e))return 31==(0|r)?a[A+44>>2]:a[A+40>>2]}return 31==(0|r)?a[A+48>>2]:a[A+52>>2]},function(A,e,r){var i;if(A|=0,e|=0,r|=0,i=8!=(0|e),!(i|8!=(0|r)))return a[A+56>>2];if(!(1!=(0|r)|i))return a[A+72>>2];if(!(1!=(0|e)|8!=(0|r)))return a[A+76>>2];if(!(28!=(0|r)|(0|e)>19))return a[A+84>>2];if(!(28!=(0|e)|(0|r)>19))return a[A+80>>2];A:{if((0|e)<=19){if((0|r)<=19)return a[A+28>>2];if(r+-21>>>0>8)break A;return a[A+32>>2]}if(!((0|r)>19|e+-21>>>0>8))return a[A+36>>2];if(31==(0|e))return 31==(0|r)?a[A+44>>2]:a[A+40>>2]}return 31==(0|r)?a[A+48>>2]:a[A+52>>2]},ve,function(A,e,r,i){return A|=0,e|=0,r|=0,i|=0,A=a[e>>2],A=0|Qt[a[a[A>>2]+56>>2]](A,80),ei(A,e,r,i,0),0|A},ve,function(A,e,r,i){return A|=0,e|=0,r|=0,i|=0,A=a[e>>2],A=0|Qt[a[a[A>>2]+56>>2]](A,80),ei(A,e,r,i,1),0|A},ve,function(A,e,r,i){return A|=0,e|=0,r|=0,i|=0,A=a[e>>2],A=0|Qt[a[a[A>>2]+56>>2]](A,84),ri(A,e,r,i,0),0|A},ve,function(A,e,r,i){return A|=0,e|=0,r|=0,i|=0,A=a[e>>2],A=0|Qt[a[a[A>>2]+56>>2]](A,116),bi(A,e,r,i),0|A},ve,function(A,e,r,i){return A|=0,e|=0,r|=0,i|=0,A=a[e>>2],A=0|Qt[a[a[A>>2]+56>>2]](A,84),ri(A,e,r,i,1),0|A},ve,function(A,e,r,i){return A|=0,e|=0,A=a[e>>2],A=0|Qt[a[a[A>>2]+56>>2]](A,8),uA(A,e),a[A>>2]=17112,0|A},ve,function(A,e,r,i){return A|=0,e|=0,r|=0,i|=0,A=a[e>>2],A=0|Qt[a[a[A>>2]+56>>2]](A,16),function(A,e,r,i){vA(A,e),a[A+12>>2]=0,f[A+8|0]=0,a[A>>2]=17172,e=a[A+4>>2],e=0|Qt[a[a[e>>2]+12>>2]](e,a[r+8>>2],a[i+8>>2]),f[A+8|0]=1,a[A+12>>2]=e}(A,e,r,i),0|A},ve,function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var t=0;return t=a[e>>2],t=0|Qt[a[a[t>>2]+56>>2]](t,20),function(A,e,r,i,t,n){vA(A,r),f[A+16|0]=n,a[A+12>>2]=e,f[A+8|0]=0,a[A>>2]=17308,e||(e=a[A+4>>2],e=0|Qt[a[a[e>>2]+12>>2]](e,a[i+8>>2],a[t+8>>2]),f[A+8|0]=1,a[A+12>>2]=e)}(t,a[e+4>>2],e,r,i,o[A+4|0]),0|t},ve,function(A,e,r,i){return A|=0,e|=0,r|=0,i|=0,A=a[e>>2],A=0|Qt[a[a[A>>2]+56>>2]](A,16),function(A,e,r,i){vA(A,e),a[A+12>>2]=0,f[A+8|0]=0,a[A>>2]=17516,e=a[A+4>>2],Qt[a[a[e>>2]+24>>2]](e,a[r+8>>2],a[i+8>>2])&&(e=a[A+4>>2],e=0|Qt[a[a[e>>2]+12>>2]](e,a[r+8>>2],a[i+8>>2]),f[A+8|0]=1,a[A+12>>2]=e)}(A,e,r,i),0|A},ve,function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var t=0;return t=a[e>>2],t=0|Qt[a[a[t>>2]+56>>2]](t,28),function(A,e,r,i,t,n,o){uA(A,e),a[A+24>>2]=o,a[A+20>>2]=n,f[A+16|0]=t,a[A+12>>2]=0,f[A+8|0]=0,a[A>>2]=17588,e=a[A+4>>2],n=t?i:r,r=t?r:i,Qt[a[a[e>>2]+24>>2]](e,a[n+8>>2],a[r+8>>2])&&(e=a[A+4>>2],e=0|Qt[a[a[e>>2]+12>>2]](e,a[n+8>>2],a[r+8>>2]),f[A+8|0]=1,a[A+12>>2]=e)}(t,e,r,i,o[A+4|0],a[A+8>>2],a[A+12>>2]),0|t},function(A){A|=0;var e=0;return a[A>>2]=18600,e=a[A+60>>2],e&&(o[A- -64|0]&&CA(e),a[A+60>>2]=0),a[A+60>>2]=0,a[A+52>>2]=0,a[A+56>>2]=0,f[A- -64|0]=1,e=a[A+40>>2],e&&(o[A+44|0]&&CA(e),a[A+40>>2]=0),a[A+40>>2]=0,a[A+32>>2]=0,a[A+36>>2]=0,f[A+44|0]=1,e=a[A+16>>2],e&&(o[A+20|0]&&CA(e),a[A+16>>2]=0),a[A+16>>2]=0,a[A+8>>2]=0,a[A+12>>2]=0,f[A+20|0]=1,0|A},function(A){A|=0;var e=0;a[A>>2]=18600,e=a[A+60>>2],e&&(o[A- -64|0]&&CA(e),a[A+60>>2]=0),a[A+60>>2]=0,a[A+52>>2]=0,a[A+56>>2]=0,f[A- -64|0]=1,e=a[A+40>>2],e&&(o[A+44|0]&&CA(e),a[A+40>>2]=0),a[A+40>>2]=0,a[A+32>>2]=0,a[A+36>>2]=0,f[A+44|0]=1,e=a[A+16>>2],e&&(o[A+20|0]&&CA(e),a[A+16>>2]=0),a[A+16>>2]=0,a[A+8>>2]=0,a[A+12>>2]=0,f[A+20|0]=1,CA(A)},function(A,e,r){A|=0,e|=0,r|=0;var i,t=0;a[696]=a[696]+1,i=a[A+24>>2];A:{e:{if(i){if(Qt[a[a[i>>2]+8>>2]](i,e,r))break e;break A}if(!(a[r+8>>2]&a[e+4>>2])|!(a[e+8>>2]&a[r+4>>2]))break A}t=function(A,e,r){var i,t,n,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0,C=0,g=0;b=a[e+12>>2]>a[r+12>>2],i=b?e:r,u=a[i+12>>2],t=b?r:e,l=a[t+12>>2],e=u<<16|l,e=(e<<15^-1)+e|0,e=B(e>>>10^e,9),e^=e>>>6,e=(e<<11^-1)+e|0,n=e>>>16^e,b=a[A+12>>2],k=n&b+-1,e=a[a[A+40>>2]+(k<<2)>>2];e:{if(-1!=(0|e))for(c=a[A+16>>2];;){if(s=e<<4,r=s+c|0,(0|u)==a[a[4+(c+s|0)>>2]+12>>2]&&a[a[r>>2]+12>>2]==(0|l))break e;if(e=a[a[A+60>>2]+(e<<2)>>2],-1==(0|e))break}if(e=b,u=a[A+8>>2],r=u,(0|e)==(0|r)&&(r=b,c=e?e<<1:1,!((0|e)>=(0|c)))){if(c?(l=dA(c<<4),r=a[A+8>>2]):(l=0,r=b),(0|r)>=1)for(e=12;s=e+l|0,v=a[A+16>>2]+e|0,a[s+-12>>2]=a[v+-12>>2],d=v+-8|0,g=a[d+4>>2],C=s+-8|0,a[C>>2]=a[d>>2],a[C+4>>2]=g,a[s>>2]=a[v>>2],e=e+16|0,r=r+-1|0,r;);e=a[A+16>>2],e&&(o[A+20|0]&&CA(e),a[A+16>>2]=0),a[A+16>>2]=l,a[A+12>>2]=c,f[A+20|0]=1,r=a[A+8>>2],e=c}a[A+8>>2]=r+1,l=u<<4,c=a[A+16>>2],r=a[A+68>>2],r&&(Qt[a[a[r>>2]+8>>2]](r,t,i),e=a[A+12>>2]),r=c+l|0,(0|b)<(0|e)&&(Qi(A),k=a[A+12>>2]+-1&n),b=a[i+12>>2],l=a[t+12>>2],e=c+(u<<4)|0,a[e+8>>2]=0,a[e+12>>2]=0,c=e,e=(0|l)<(0|b),a[c+4>>2]=e?i:t,b=a[A+60>>2]+(u<<2)|0,A=a[A+40>>2]+(k<<2)|0,a[b>>2]=a[A>>2],a[r>>2]=e?t:i,a[A>>2]=u}return r}(A,e,r)}return 0|t},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f=0,t=0,n=0,o=0,c=0,b=0,l=0;a[695]=a[695]+1,f=a[e+12>>2]>a[r+12>>2],n=f?e:r,t=a[n+12>>2],c=f?r:e,o=a[c+12>>2],e=t<<16|o,e=(e<<15^-1)+e|0,e=B(e>>>10^e,9),e^=e>>>6,e=(e<<11^-1)+e|0,b=a[A+12>>2]+-1&(e>>>16^e),e=a[a[A+40>>2]+(b<<2)>>2];A:if(-1!=(0|e)){for(f=a[A+16>>2];;){if(r=f+(e<<4)|0,(0|t)!=a[a[r+4>>2]+12>>2]||a[a[r>>2]+12>>2]!=(0|o)){if(e=a[a[A+60>>2]+(e<<2)>>2],-1!=(0|e))continue;break A}break}Qt[a[a[A>>2]+32>>2]](A,r,i),l=a[12+(f+(e<<4)|0)>>2],t=a[A+60>>2];e:{if(o=a[A+40>>2]+(b<<2)|0,e=a[o>>2],f=r-a[A+16>>2]>>4,(0|e)!=(0|f)){for(;r=e,e=a[t+(e<<2)>>2],(0|f)!=(0|e););if(e=a[t+(f<<2)>>2],-1!=(0|r)){a[t+(r<<2)>>2]=e;break e}}else e=a[t+(f<<2)>>2];a[o>>2]=e}if(t=a[A+8>>2]+-1|0,e=a[A+68>>2],e&&Qt[a[a[e>>2]+12>>2]](e,c,n,i),(0|t)==(0|f))return a[A+8>>2]=a[A+8>>2]+-1,0|l;i=a[A+60>>2];e:{if(c=a[A+16>>2],n=c+(t<<4)|0,e=a[a[n+4>>2]+12>>2]<<16|a[a[n>>2]+12>>2],e=(e<<15^-1)+e|0,e=B(e>>>10^e,9),e^=e>>>6,e=(e<<11^-1)+e|0,o=a[A+12>>2]+-1&(e>>>16^e),b=a[A+40>>2]+(o<<2)|0,e=a[b>>2],(0|e)!=(0|t)){for(;r=e,e=a[i+(e<<2)>>2],(0|t)!=(0|e););if(e=a[i+(t<<2)>>2],-1!=(0|r)){a[i+(r<<2)>>2]=e;break e}}else e=a[i+(t<<2)>>2];a[b>>2]=e}r=a[n+4>>2],e=c+(f<<4)|0,a[e>>2]=a[n>>2],a[e+4>>2]=r,r=n+8|0,i=a[r+4>>2],e=e+8|0,a[e>>2]=a[r>>2],a[e+4>>2]=i,e=a[A+40>>2]+(o<<2)|0,a[a[A+60>>2]+(f<<2)>>2]=a[e>>2],a[e>>2]=f,a[A+8>>2]=a[A+8>>2]+-1}return 0|l},function(A,e,r){var i;A|=0,e|=0,r|=0,i=Y-16|0,Y=i,a[i+12>>2]=e,a[i+8>>2]=18960,Qt[a[a[A>>2]+48>>2]](A,i+8|0,r),Y=i+16|0},ci,ci,hi,function(A,e,r){A|=0,e|=0,r|=0,r&&(A=a[e+8>>2],A&&(Qt[a[a[A>>2]>>2]](A),Qt[a[a[r>>2]+60>>2]](r,a[e+8>>2]),a[e+8>>2]=0))},function(A){return A|=0,a[A+8>>2]},function(A,e,r){var i;A|=0,e|=0,r|=0,i=Y-16|0,Y=i,a[i+12>>2]=r,a[i+8>>2]=A,a[i+4>>2]=e,a[i>>2]=18816,Qt[a[a[A>>2]+48>>2]](A,i,r),Y=i+16|0},Gi,function(A,e,r){A|=0,e|=0,r|=0;var i,f=0,t=0;if(i=Y-16|0,Y=i,Lr(i+8|0,18668),a[A+8>>2]>=1)for(;t=a[A+16>>2]+(f<<4)|0,Qt[a[a[e>>2]+8>>2]](e,t)?(Qt[a[a[A>>2]+12>>2]](A,a[t>>2],a[t+4>>2],r),a[694]=a[694]+-1):f=f+1|0,(0|f)>2];);qr(),Y=i+16|0},function(A,e,r){A|=0,e|=0,r|=0;var i,f,t=0,n=0;a[697]=a[697]+1,t=a[e+12>>2]>a[r+12>>2],i=a[(t?e:r)+12>>2],f=a[(t?r:e)+12>>2],e=f|i<<16,e=(e<<15^-1)+e|0,e=B(e>>>10^e,9),e^=e>>>6,e=(e<<11^-1)+e|0,e=a[A+12>>2]+-1&(e>>>16^e);A:{if(!((0|e)>=a[A+32>>2])&&(e=a[a[A+40>>2]+(e<<2)>>2],-1!=(0|e)))for(r=a[A+16>>2];;){if(n=e<<4,t=n+r|0,a[a[4+(r+n|0)>>2]+12>>2]==(0|i)&&(0|f)==a[a[t>>2]+12>>2])break A;if(e=a[a[A+60>>2]+(e<<2)>>2],-1==(0|e))break}t=0}return 0|t},we,function(A,e){A|=0,e|=0,a[A+68>>2]=e},function(A,e){A|=0,e|=0;var r,i=0,t=0,n=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0;if(r=Y-32|0,Y=r,a[r+20>>2]=0,a[r+12>>2]=0,a[r+16>>2]=0,t=a[A+8>>2],f[r+24|0]=1,!((0|t)<1)){for(t=0;;){if(n=a[A+16>>2]+(b<<4)|0,(0|i)==(0|t))if(c=t?t<<1:1,(0|t)>=(0|c))i=t;else{if(l=c?dA(c<<4):0,(0|t)>=1)for(i=12;u=i+l|0,s=a[r+20>>2]+i|0,a[u+-12>>2]=a[s+-12>>2],k=s+-8|0,d=a[k+4>>2],v=u+-8|0,a[v>>2]=a[k>>2],a[v+4>>2]=d,a[u>>2]=a[s>>2],i=i+16|0,t=t+-1|0,t;);i=a[r+20>>2],i&&(o[r+24|0]&&CA(i),a[r+20>>2]=0),a[r+20>>2]=l,f[r+24|0]=1,a[r+16>>2]=c,i=a[r+12>>2]}if(i=a[r+20>>2]+(i<<4)|0,a[i>>2]=a[n>>2],t=a[n+8>>2],a[i+4>>2]=a[n+4>>2],a[i+8>>2]=t,a[i+12>>2]=a[n+12>>2],c=a[r+12>>2],i=c+1|0,a[r+12>>2]=i,b=b+1|0,!((0|b)>2]))break;t=a[r+16>>2]}if(!((0|c)<0))for(t=-1,n=a[r+20>>2];Qt[a[a[A>>2]+12>>2]](A,a[n>>2],a[n+4>>2],e),n=n+16|0,t=t+1|0,(0|t)<(0|c););}if(a[A+52>>2]>=1){for(i=a[A+60>>2],n=0;a[i>>2]=-1,i=i+4|0,n=n+1|0,(0|n)>2];);i=a[r+12>>2]}if((0|i)>=2&&(Ei(r+8|0,r,0,i+-1|0),i=a[r+12>>2]),n=a[r+20>>2],(0|i)>=1)for(e=0,i=4;t=i+n|0,Qt[a[a[A>>2]+8>>2]](A,a[t+-4>>2],a[t>>2]),i=i+16|0,n=a[r+20>>2],e=e+1|0,(0|e)>2];);n&&(o[r+24|0]&&CA(n),a[r+20>>2]=0),Y=r+32|0},ve,function(A,e){A|=0,e|=0;var r=0;return r=a[A+4>>2],(0|r)!=a[e+4>>2]&&(0|r)!=a[e>>2]||(r=a[A+8>>2],Qt[a[a[r>>2]+32>>2]](r,e,a[A+12>>2])),0},ve,function(A,e){return A|=0,e|=0,A=a[A+4>>2],(0|A)==a[e>>2]|(0|A)==a[e+4>>2]},Fi,function(A){A|=0,$(Fi(A))},function(A,e,r,i,f,t,n,c){A|=0,e|=0,r|=0,i|=0,f|=0,t|=0,n|=0,c|=0;var b=0;return c=Y-48|0,Y=c,i=dA(64),a[i+8>>2]=n,a[i+4>>2]=t,a[i>>2]=f,f=a[e+4>>2],a[i+16>>2]=a[e>>2],a[i+20>>2]=f,f=e+8|0,b=a[f+4>>2],t=i+24|0,a[t>>2]=a[f>>2],a[t+4>>2]=b,t=a[r+4>>2],a[i+32>>2]=a[r>>2],a[i+36>>2]=t,t=r+8|0,b=a[t+4>>2],n=i+40|0,a[n>>2]=a[t>>2],a[n+4>>2]=b,a[i+52>>2]=0,a[i+56>>2]=0,b=a[f+4>>2],n=c+24|0,a[n>>2]=a[f>>2],a[n+4>>2]=b,n=a[t+4>>2],f=c+40|0,a[f>>2]=a[t>>2],a[f+4>>2]=n,f=a[e>>2],e=a[e+4>>2],t=a[r+4>>2],r=a[r>>2],a[i+60>>2]=a[A+104>>2],a[c+32>>2]=r,a[c+36>>2]=t,r=a[A+148>>2]+1|0,a[i+12>>2]=r,a[A+148>>2]=r,a[c+16>>2]=f,a[c+20>>2]=e,r=A+4|0,e=or(r,c+16|0,i),a[i+52>>2]=0,a[i+48>>2]=e,e=84+((a[A+104>>2]<<2)+A|0)|0,a[i+56>>2]=a[e>>2],f=a[e>>2],f&&(a[f+52>>2]=i),a[e>>2]=i,o[A+153|0]||(a[c+8>>2]=i,a[c>>2]=19252,a[c+4>>2]=A,Wi(r,a[A+4>>2],c+16|0,c),A=A+44|0,Wi(A,a[A>>2],c+16|0,c)),Y=c+48|0,0|i},function(A,e,r){A|=0,e|=0,r|=0;var i,t=0;br(2==a[e+60>>2]?A+44|0:A+4|0,a[e+48>>2]),i=a[e+56>>2],t=a[e+52>>2],t=t?t+56|0:84+((a[e+60>>2]<<2)+A|0)|0,a[t>>2]=i,t=a[e+56>>2],t&&(a[t+52>>2]=a[e+52>>2]),t=a[A+96>>2],Qt[a[a[t>>2]+16>>2]](t,e,r),CA(e),f[A+154|0]=1},function(A,e,r,i,t){A|=0,e|=0,r|=0,i|=0,t|=0;var n=0,c=0,b=0,l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=0,Q=0;t=Y-48|0,Y=t,c=r+8|0,b=a[c+4>>2],n=t+24|0,a[n>>2]=a[c>>2],a[n+4>>2]=b,c=i+8|0,b=a[c+4>>2],n=t+40|0,a[n>>2]=a[c>>2],a[n+4>>2]=b,n=a[r+4>>2],a[t+16>>2]=a[r>>2],a[t+20>>2]=n,n=a[i+4>>2],a[t+32>>2]=a[i>>2],a[t+36>>2]=n;A:if(2!=a[e+60>>2])if(c=1,a[A+128>>2]=a[A+128>>2]+1,n=a[e+48>>2],C[n>>2]<=C[t+32>>2]^1|C[n+16>>2]>=C[t+16>>2]^1|C[n+4>>2]<=C[t+36>>2]^1|C[n+20>>2]>=C[t+20>>2]^1||C[n+8>>2]<=C[t+40>>2]^1|C[n+24>>2]>=C[t+24>>2]^1)cr(A+4|0,n,t+16|0),a[A+132>>2]=a[A+132>>2]+1;else{if(u=C[e+20>>2],s=C[e+24>>2],g=C[r>>2],B=C[r+4>>2],m=C[r+8>>2],k=C[e+16>>2],a[t+12>>2]=0,l=C[A+100>>2],v=_(l*_(_(C[e+40>>2]-s)*_(.5))),C[t+8>>2]=v,d=_(l*_(_(C[e+36>>2]-u)*_(.5))),C[t+4>>2]=d,l=_(l*_(_(C[e+32>>2]-k)*_(.5))),C[t>>2]=l,u=_(B-u),_(g-k)<_(0)&&(C[t>>2]=-l),s=_(m-s),u<_(0)&&(C[t+4>>2]=-d),s<_(0)&&(C[t+8>>2]=-v),c=0,!function(A,e,r,i){var f=0,t=0,n=_(0),o=0,c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0);c=C[r>>2];e:{if(C[e>>2]<=c){if(n=C[r+4>>2],!(C[e+4>>2]<=n^1|C[e+8>>2]<=C[r+8>>2]^1|C[e+16>>2]>=C[r+16>>2]^1|C[e+20>>2]>=C[r+20>>2]^1)&&(f=0,C[e+24>>2]>=C[r+24>>2]))break e}else n=C[r+4>>2];l=_(n-_(.05000000074505806)),C[r+4>>2]=l,b=_(c-_(.05000000074505806)),C[r>>2]=b,u=_(C[r+8>>2]-_(.05000000074505806)),C[r+8>>2]=u,s=_(C[r+16>>2]+_(.05000000074505806)),C[r+16>>2]=s,f=r+20|0,n=_(C[f>>2]+_(.05000000074505806)),C[f>>2]=n,o=r+24|0,c=_(C[o>>2]+_(.05000000074505806)),C[o>>2]=c,k=C[i>>2],f=k>_(0),C[(f<<4)+r>>2]=(f?s:b)+k,b=C[i+4>>2],f=b>_(0),C[(f?20:4)+r>>2]=(f?n:l)+b,n=C[i+8>>2],i=n>_(0),C[(i?24:8)+r>>2]=(i?c:u)+n,i=nr(A,e);r:if(i)if(t=a[A+8>>2],(0|t)>=0){if(!t)break r;for(;;){if(f=a[i+32>>2],!f)break r;if(i=f,t=t+-1|0,!t)break}}else i=a[A>>2];else i=0;f=a[r+4>>2],a[e>>2]=a[r>>2],a[e+4>>2]=f,f=a[o+4>>2],t=e+24|0,a[t>>2]=a[o>>2],a[t+4>>2]=f,f=r+16|0,o=a[f+4>>2],t=e+16|0,a[t>>2]=a[f>>2],a[t+4>>2]=o,r=r+8|0,f=a[r+4>>2],o=e+8|0,a[o>>2]=a[r>>2],a[o+4>>2]=f,ar(A,i,e),f=1}return f}(A+4|0,n,t+16|0,t))break A;c=1,a[A+132>>2]=a[A+132>>2]+1}else br(A+44|0,a[e+48>>2]),R=e,Q=or(A+4|0,t+16|0,e),a[R+48>>2]=Q,c=1;b=a[e+56>>2],n=a[e+52>>2],n=n?n+56|0:84+((a[e+60>>2]<<2)+A|0)|0,a[n>>2]=b,n=a[e+56>>2],n&&(a[n+52>>2]=a[e+52>>2]),n=a[r+4>>2],a[e+16>>2]=a[r>>2],a[e+20>>2]=n,r=r+8|0,b=a[r+4>>2],n=e+24|0,a[n>>2]=a[r>>2],a[n+4>>2]=b,n=i+8|0,b=a[n+4>>2],r=e+40|0,a[r>>2]=a[n>>2],a[r+4>>2]=b,r=a[i+4>>2],a[e+32>>2]=a[i>>2],a[e+36>>2]=r,a[e+52>>2]=0,i=a[A+104>>2],r=84+((i<<2)+A|0)|0,a[e+56>>2]=a[r>>2],a[e+60>>2]=i,i=a[r>>2],i&&(a[i+52>>2]=e),a[r>>2]=e,c&&(f[A+154|0]=1,o[A+153|0]||(a[t>>2]=19252,a[t+4>>2]=A,r=A+44|0,Di(r,a[r>>2],a[e+48>>2],t),Di(A+4|0,a[A+4>>2],a[e+48>>2],t))),Y=t+48|0},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f=0;A=a[e+20>>2],a[r>>2]=a[e+16>>2],a[r+4>>2]=A,A=r+8|0,r=e+24|0,f=a[r+4>>2],a[A>>2]=a[r>>2],a[A+4>>2]=f,r=e+40|0,f=a[r+4>>2],A=i+8|0,a[A>>2]=a[r>>2],a[A+4>>2]=f,A=a[e+36>>2],a[i>>2]=a[e+32>>2],a[i+4>>2]=A},function(A,e,r,i,f,t){var n,o,c;A|=0,e|=0,r|=0,i|=0,f|=0,t|=0,r=Y-16|0,Y=r,a[r+8>>2]=19324,a[r+12>>2]=i,n=i+4|0,o=i+20|0,c=a[A+168>>2],wi(A+4|0,a[A+4>>2],e,n,o,C[i+32>>2],f,t,c,r+8|0),A=A+44|0,wi(A,a[A>>2],e,n,o,C[i+32>>2],f,t,c,r+8|0),Y=r+16|0},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f,t=0,n=0;f=Y-48|0,Y=f,a[f+44>>2]=i,a[f+40>>2]=19396,t=e+8|0,n=a[t+4>>2],i=f+16|0,a[i>>2]=a[t>>2],a[i+4>>2]=n,t=r+8|0,n=a[t+4>>2],i=f+32|0,a[i>>2]=a[t>>2],a[i+4>>2]=n,i=a[e+4>>2],a[f+8>>2]=a[e>>2],a[f+12>>2]=i,e=a[r+4>>2],a[f+24>>2]=a[r>>2],a[f+28>>2]=e,Wi(A+4|0,a[A+4>>2],f+8|0,f+40|0),A=A+44|0,Wi(A,a[A>>2],f+8|0,f+40|0),Y=f+48|0},function(A,e){A|=0,e|=0,function(A,e){var r=0,i=0,t=0,n=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=_(0);if(n=Y-32|0,Y=n,k=A+4|0,tr(k,1+((0|B(a[A+112>>2],a[A+16>>2]))/100|0)|0),a[A+124>>2]&&(r=1+((0|B(a[A+108>>2],a[A+56>>2]))/100|0)|0,tr(A+44|0,r),r=a[A+124>>2]-r|0,a[A+124>>2]=(0|r)>0?r:0),r=(a[A+104>>2]+1|0)%2|0,a[A+104>>2]=r,i=a[84+((r<<2)+A|0)>>2],i){for(b=A+44|0,v=n+16|0;r=a[i+56>>2],t=a[i+52>>2],t=t?t+56|0:84+((a[i+60>>2]<<2)+A|0)|0,a[t>>2]=r,t=a[i+56>>2],t&&(a[t+52>>2]=a[i+52>>2]),a[i+52>>2]=0,a[i+56>>2]=a[A+92>>2],t=a[A+92>>2],t&&(a[t+52>>2]=i),a[A+92>>2]=i,br(k,a[i+48>>2]),l=i+24|0,t=a[l+4>>2],c=n+8|0,a[c>>2]=a[l>>2],a[c+4>>2]=t,s=a[i+16>>2],u=a[i+20>>2],t=a[i+36>>2],a[v>>2]=a[i+32>>2],a[v+4>>2]=t,l=i+40|0,t=a[l+4>>2],c=v+8|0,a[c>>2]=a[l>>2],a[c+4>>2]=t,a[n>>2]=s,a[n+4>>2]=u,t=or(b,n,i),a[i+60>>2]=2,a[i+48>>2]=t,i=r,r;);f[A+154|0]=1,a[A+124>>2]=a[A+56>>2]}if(a[n>>2]=19252,a[n+4>>2]=A,o[A+153|0]&&(Di(k,a[A+4>>2],a[A+44>>2],n),o[A+153|0]&&(r=a[k>>2],Di(k,r,r,n))),o[A+154|0]&&(r=a[A+96>>2],c=0|Qt[a[a[r>>2]+28>>2]](r),t=a[c+4>>2],!((0|t)<1))){s=A+144|0,i=a[A+120>>2],r=(0|B(a[A+116>>2],t))/100|0,r=(0|i)>(0|r)?i:r,u=(0|t)<(0|r)?t:r;A:{if((0|u)>=1){for(i=0;r=a[c+12>>2]+((a[s>>2]+i|0)%(0|t)<<4)|0,l=a[r>>2],b=a[l+48>>2],t=a[r+4>>2],r=a[t+48>>2],!(C[b>>2]<=C[r+16>>2]^1|C[b+16>>2]>=C[r>>2]^1|C[b+4>>2]<=C[r+20>>2]^1|C[b+20>>2]>=C[r+4>>2]^1)&&C[b+8>>2]<=C[r+24>>2]&&C[b+24>>2]>=C[r+8>>2]||(r=a[A+96>>2],Qt[a[a[r>>2]+12>>2]](r,l,t,e),i=i+-1|0,u=u+-1|0),t=a[c+4>>2],i=i+1|0,(0|i)<(0|u););if(s=A+144|0,i=0,(0|t)<=0)break A}i=(a[s>>2]+u|0)%(0|t)|0}a[s>>2]=i}f[A+154|0]=0,a[A+120>>2]=1,a[A+140>>2]=a[A+140>>2]+1,r=a[A+132>>2],i=A,e=a[A+128>>2],d=_(0),e&&(d=_(_(r>>>0)/_(e>>>0))),C[i+136>>2]=d,a[A+132>>2]=r>>>1,a[A+128>>2]=e>>>1,Y=n+32|0}(A,e),function(A,e){var r=0,i=0,t=0,n=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0;if(v=Y-16|0,Y=v,r=a[A+96>>2],Qt[a[a[r>>2]+56>>2]](r)){if(r=a[A+96>>2],i=0|Qt[a[a[r>>2]+28>>2]](r),t=a[i+4>>2],(0|t)>=2&&(Ei(i,v+8|0,0,t+-1|0),t=a[i+4>>2]),(0|t)>=1){for(;;){l=a[i+12>>2]+d|0,r=a[l+4>>2],n=u,u=a[l>>2];A:{e:if((0|r)!=(0|b)||(0|n)!=(0|u)){if(c=a[u+48>>2],n=a[r+48>>2],!(C[c>>2]<=C[n+16>>2]^1|C[c+16>>2]>=C[n>>2]^1|C[c+4>>2]<=C[n+20>>2]^1|C[c+20>>2]>=C[n+4>>2]^1)&&C[c+8>>2]<=C[n+24>>2]){if(b=r,!(C[c+24>>2]>=C[n+8>>2]))break e;break A}b=r}r=a[A+96>>2],Qt[a[a[r>>2]+32>>2]](r,l,e),a[l>>2]=0,a[l+4>>2]=0,s=s+1|0,t=a[i+4>>2]}if(d=d+16|0,k=k+1|0,!((0|k)<(0|t)))break}if((0|t)>=2&&(Ei(i,v,0,t+-1|0),t=a[i+4>>2]),A=t-s|0,(0|s)<=-1){if(a[i+8>>2]<(0|A)){if(A?(k=dA(A<<4),e=a[i+4>>2]):(k=0,e=t),(0|e)>=1)for(r=12;b=r+k|0,u=a[i+12>>2]+r|0,a[b+-12>>2]=a[u+-12>>2],n=u+-8|0,l=a[n+4>>2],c=b+-8|0,a[c>>2]=a[n>>2],a[c+4>>2]=l,a[b>>2]=a[u>>2],r=r+16|0,e=e+-1|0,e;);e=a[i+12>>2],e&&(o[i+16|0]&&CA(e),a[i+12>>2]=0),a[i+12>>2]=k,f[i+16|0]=1,a[i+8>>2]=A}for(r=t<<4;e=a[i+12>>2]+r|0,a[e>>2]=0,a[e+4>>2]=0,e=e+8|0,a[e>>2]=0,a[e+4>>2]=0,r=r+16|0,e=s+1|0,b=e>>>0>=s>>>0,s=e,b;);}t=A}a[i+4>>2]=t}Y=v+16|0}(A,e)},ne,ne,function(A,e,r){A|=0,e|=0,r|=0;var i,f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0);i=a[A+44>>2],A=a[A+4>>2];A:if(A){if(n=C[A>>2],i){if(f=C[A+20>>2],t=C[i+20>>2],o=f>t?f:t,f=C[A+8>>2],t=C[i+8>>2],c=f>2],t=C[i+4>>2],b=f>2],t=C[i+16>>2],l=f>t?f:t,f=C[i>>2],n=n>2],t=C[i+24>>2],!(f>t)){f=t;break A}break A}t=C[A+28>>2],f=C[A+24>>2],o=C[A+20>>2],l=C[A+16>>2],u=C[A+12>>2],c=C[A+8>>2],b=C[A+4>>2]}else i&&(t=C[i+28>>2],f=C[i+24>>2],o=C[i+20>>2],l=C[i+16>>2],u=C[i+12>>2],c=C[i+8>>2],b=C[i+4>>2],n=C[i>>2]);C[e+12>>2]=u,C[e+8>>2]=c,C[e+4>>2]=b,C[e>>2]=n,C[r+12>>2]=t,C[r+8>>2]=f,C[r+4>>2]=o,C[r>>2]=l},function(A,e){A|=0,e|=0,a[A+16>>2]==(0-a[A+56>>2]|0)&&(fr(A+4|0),fr(A+44|0),f[A+153|0]=256,f[A+154|0]=1,a[A+124>>2]=0,a[A+104>>2]=0,a[A+116>>2]=10,a[A+120>>2]=1,a[A+108>>2]=1,a[A+112>>2]=0,e=A+84|0,a[e>>2]=0,a[e+4>>2]=0,a[A+92>>2]=0,a[A+128>>2]=0,a[A+132>>2]=0,e=A+136|0,a[e>>2]=0,a[e+4>>2]=0,A=A+144|0,a[A>>2]=0,a[A+4>>2]=0)},qe,ve,function(A,e,r){A|=0,e|=0,r|=0;var i=0;(0|e)!=(0|r)&&(i=a[a[A+4>>2]+96>>2],Qt[a[a[i>>2]+8>>2]](i,a[e+36>>2],a[r+36>>2]),A=a[A+4>>2],a[A+120>>2]=a[A+120>>2]+1)},function(A,e){A|=0,e|=0,Qt[a[a[A>>2]+8>>2]](A,e,a[a[A+8>>2]+48>>2])},ve,Zi,ve,Zi,function(A){var e;return A|=0,a[A>>2]=20096,e=a[A+556>>2],e&&(o[A+560|0]&&CA(e),a[A+556>>2]=0),a[A+556>>2]=0,a[A+548>>2]=0,a[A+552>>2]=0,f[A+560|0]=1,Ze(A),0|A},function(A){var e;A|=0,a[A>>2]=20096,e=a[A+556>>2],e&&(o[A+560|0]&&CA(e),a[A+556>>2]=0),a[A+556>>2]=0,a[A+548>>2]=0,a[A+552>>2]=0,f[A+560|0]=1,Ze(A),CA(A)},function(A){return 496},function(A,e,r){return A|=0,e|=0,r|=0,Ne(A,e,r),a[e+264>>2]=a[A+324>>2],a[e+268>>2]=a[A+328>>2],a[e+272>>2]=a[A+332>>2],a[e+276>>2]=a[A+336>>2],a[e+280>>2]=a[A+340>>2],a[e+284>>2]=a[A+344>>2],a[e+288>>2]=a[A+348>>2],a[e+292>>2]=a[A+352>>2],a[e+296>>2]=a[A+356>>2],a[e+300>>2]=a[A+360>>2],a[e+304>>2]=a[A+364>>2],a[e+308>>2]=a[A+368>>2],a[e+312>>2]=a[A+372>>2],a[e+316>>2]=a[A+376>>2],a[e+320>>2]=a[A+380>>2],a[e+324>>2]=a[A+384>>2],a[e+328>>2]=a[A+388>>2],a[e+332>>2]=a[A+392>>2],a[e+336>>2]=a[A+396>>2],a[e+340>>2]=a[A+400>>2],a[e+456>>2]=a[A+404>>2],a[e+344>>2]=a[A+604>>2],a[e+348>>2]=a[A+608>>2],a[e+352>>2]=a[A+612>>2],a[e+356>>2]=a[A+616>>2],a[e+360>>2]=a[A+408>>2],a[e+364>>2]=a[A+412>>2],a[e+368>>2]=a[A+416>>2],a[e+372>>2]=a[A+420>>2],a[e+376>>2]=a[A+424>>2],a[e+380>>2]=a[A+428>>2],a[e+384>>2]=a[A+432>>2],a[e+388>>2]=a[A+436>>2],a[e+392>>2]=a[A+440>>2],a[e+396>>2]=a[A+444>>2],a[e+400>>2]=a[A+448>>2],a[e+404>>2]=a[A+452>>2],a[e+408>>2]=a[A+456>>2],a[e+412>>2]=a[A+460>>2],a[e+416>>2]=a[A+464>>2],a[e+420>>2]=a[A+468>>2],a[e+424>>2]=a[A+472>>2],a[e+428>>2]=a[A+476>>2],a[e+432>>2]=a[A+480>>2],a[e+436>>2]=a[A+484>>2],a[e+440>>2]=a[A+488>>2],a[e+444>>2]=a[A+492>>2],a[e+448>>2]=a[A+496>>2],a[e+452>>2]=a[A+500>>2],r=a[A+508>>2],a[e+460>>2]=a[A+504>>2],a[e+464>>2]=r,r=a[A+520>>2],a[e+468>>2]=a[A+516>>2],a[e+472>>2]=r,r=a[A+528>>2],a[e+476>>2]=a[A+524>>2],a[e+480>>2]=r,r=a[A+536>>2],a[e+484>>2]=a[A+532>>2],a[e+488>>2]=r,a[e+492>>2]=o[A+512|0],20124},function(A,e){A|=0,e|=0;var r,i=0,f=0,t=0,n=0,o=0;t=e,n=0|Qt[a[a[A>>2]+16>>2]](A),o=1,f=a[a[e>>2]+16>>2],i=0|Qt[f](0|t,0|n,0|o),o=e,n=i,t=0|Qt[a[a[A>>2]+20>>2]](A,a[i+8>>2],e),r=A,f=a[a[e>>2]+20>>2],Qt[f](0|o,0|n,0|t,1497645650,0|r)},function(A,e,r){A|=0,e|=0,r|=0;var i=_(0),f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0);return n=C[r+100>>2],o=C[r+16>>2],c=C[r+20>>2],b=C[r+24>>2],f=C[r+108>>2],i=_(_(_(C[r+112>>2]-_(n*C[r+116>>2]))-_(_(_(_(_(o*C[A+64>>2])+_(c*C[A+68>>2]))+_(b*C[A+72>>2]))+_(_(_(C[r>>2]*C[A+80>>2])+_(C[r+4>>2]*C[A+84>>2]))+_(C[r+8>>2]*C[A+88>>2])))*f))-_(f*_(_(_(_(C[r+48>>2]*C[e+64>>2])+_(C[r+52>>2]*C[e+68>>2]))+_(C[r+56>>2]*C[e+72>>2]))+_(_(_(C[r+32>>2]*C[e+80>>2])+_(C[r+36>>2]*C[e+84>>2]))+_(C[r+40>>2]*C[e+88>>2]))))),f=_(n+i),t=C[r+120>>2],f>2],f>t&&(i=_(t-n),f=t)),C[r+100>>2]=f,a[A+240>>2]&&(C[A+64>>2]=_(C[A+112>>2]*_(i*_(o*C[A+128>>2])))+C[A+64>>2],C[A+68>>2]=_(_(i*_(c*C[A+132>>2]))*C[A+116>>2])+C[A+68>>2],C[A+72>>2]=_(_(i*_(b*C[A+136>>2]))*C[A+120>>2])+C[A+72>>2],f=C[r+72>>2],t=C[r+68>>2],C[A+80>>2]=_(_(i*C[A+96>>2])*C[r+64>>2])+C[A+80>>2],n=C[A+104>>2],C[A+84>>2]=_(t*_(i*C[A+100>>2]))+C[A+84>>2],C[A+88>>2]=_(f*_(i*n))+C[A+88>>2]),a[e+240>>2]&&(f=C[r+56>>2],t=C[r+52>>2],C[e+64>>2]=_(C[e+112>>2]*_(i*_(C[r+48>>2]*C[e+128>>2])))+C[e+64>>2],C[e+68>>2]=_(_(i*_(t*C[e+132>>2]))*C[e+116>>2])+C[e+68>>2],C[e+72>>2]=_(_(i*_(f*C[e+136>>2]))*C[e+120>>2])+C[e+72>>2],f=C[r+88>>2],t=C[r+84>>2],C[e+80>>2]=_(_(i*C[e+96>>2])*C[r+80>>2])+C[e+80>>2],n=C[e+104>>2],C[e+84>>2]=_(t*_(i*C[e+100>>2]))+C[e+84>>2],C[e+88>>2]=_(f*_(i*n))+C[e+88>>2]),_(i)},function(A,e,r){A|=0,e|=0,r|=0;var i,f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0);return f=C[r+100>>2],o=C[r+16>>2],c=C[r+20>>2],b=C[r+24>>2],t=C[r+108>>2],t=_(_(_(C[r+112>>2]-_(f*C[r+116>>2]))-_(_(_(_(_(o*C[A+64>>2])+_(c*C[A+68>>2]))+_(b*C[A+72>>2]))+_(_(_(C[r>>2]*C[A+80>>2])+_(C[r+4>>2]*C[A+84>>2]))+_(C[r+8>>2]*C[A+88>>2])))*t))-_(t*_(_(_(_(C[r+48>>2]*C[e+64>>2])+_(C[r+52>>2]*C[e+68>>2]))+_(C[r+56>>2]*C[e+72>>2]))+_(_(_(C[r+32>>2]*C[e+80>>2])+_(C[r+36>>2]*C[e+84>>2]))+_(C[r+40>>2]*C[e+88>>2]))))),l=_(f+t),n=C[r+120>>2],i=l>2]=i?n:l,f=i?_(n-f):t,a[A+240>>2]&&(C[A+64>>2]=_(C[A+112>>2]*_(f*_(o*C[A+128>>2])))+C[A+64>>2],C[A+68>>2]=_(_(f*_(c*C[A+132>>2]))*C[A+116>>2])+C[A+68>>2],C[A+72>>2]=_(_(f*_(b*C[A+136>>2]))*C[A+120>>2])+C[A+72>>2],t=C[r+72>>2],n=C[r+68>>2],C[A+80>>2]=_(_(f*C[A+96>>2])*C[r+64>>2])+C[A+80>>2],o=C[A+104>>2],C[A+84>>2]=_(n*_(f*C[A+100>>2]))+C[A+84>>2],C[A+88>>2]=_(t*_(f*o))+C[A+88>>2]),a[e+240>>2]&&(t=C[r+56>>2],n=C[r+52>>2],C[e+64>>2]=_(C[e+112>>2]*_(f*_(C[r+48>>2]*C[e+128>>2])))+C[e+64>>2],C[e+68>>2]=_(_(f*_(n*C[e+132>>2]))*C[e+116>>2])+C[e+68>>2],C[e+72>>2]=_(_(f*_(t*C[e+136>>2]))*C[e+120>>2])+C[e+72>>2],t=C[r+88>>2],n=C[r+84>>2],C[e+80>>2]=_(_(f*C[e+96>>2])*C[r+80>>2])+C[e+80>>2],o=C[e+104>>2],C[e+84>>2]=_(n*_(f*C[e+100>>2]))+C[e+84>>2],C[e+88>>2]=_(t*_(f*o))+C[e+88>>2]),_(f)},function(A,e,r){A|=0,e|=0,r|=0;var i=_(0),f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=0;return f=C[r+128>>2],f!=_(0)&&(a[700]=a[700]+1,i=C[r+96>>2],t=_(f-_(i*C[r+116>>2])),n=C[r+16>>2],o=C[r+20>>2],c=C[r+24>>2],f=C[r+108>>2],f=_(_(t-_(_(_(_(_(n*C[A+144>>2])+_(o*C[A+148>>2]))+_(c*C[A+152>>2]))+_(_(_(C[r>>2]*C[A+160>>2])+_(C[r+4>>2]*C[A+164>>2]))+_(C[r+8>>2]*C[A+168>>2])))*f))-_(f*_(_(_(_(C[r+48>>2]*C[e+144>>2])+_(C[r+52>>2]*C[e+148>>2]))+_(C[r+56>>2]*C[e+152>>2]))+_(_(_(C[r+32>>2]*C[e+160>>2])+_(C[r+36>>2]*C[e+164>>2]))+_(C[r+40>>2]*C[e+168>>2]))))),b=_(i+f),t=C[r+120>>2],l=b>2]=l?t:b,i=l?_(t-i):f,a[A+240>>2]&&(C[A+144>>2]=_(C[A+112>>2]*_(i*_(n*C[A+128>>2])))+C[A+144>>2],C[A+148>>2]=_(_(i*_(o*C[A+132>>2]))*C[A+116>>2])+C[A+148>>2],C[A+152>>2]=_(_(i*_(c*C[A+136>>2]))*C[A+120>>2])+C[A+152>>2],f=C[r+72>>2],t=C[r+68>>2],C[A+160>>2]=_(_(i*C[A+96>>2])*C[r+64>>2])+C[A+160>>2],n=C[A+104>>2],C[A+164>>2]=_(t*_(i*C[A+100>>2]))+C[A+164>>2],C[A+168>>2]=_(f*_(i*n))+C[A+168>>2]),a[e+240>>2]&&(f=C[r+56>>2],t=C[r+52>>2],C[e+144>>2]=_(C[e+112>>2]*_(i*_(C[r+48>>2]*C[e+128>>2])))+C[e+144>>2],C[e+148>>2]=_(_(i*_(t*C[e+132>>2]))*C[e+116>>2])+C[e+148>>2],C[e+152>>2]=_(_(i*_(f*C[e+136>>2]))*C[e+120>>2])+C[e+152>>2],f=C[r+88>>2],t=C[r+84>>2],C[e+160>>2]=_(_(i*C[e+96>>2])*C[r+80>>2])+C[e+160>>2],n=C[e+104>>2],C[e+164>>2]=_(t*_(i*C[e+100>>2]))+C[e+164>>2],C[e+168>>2]=_(f*_(i*n))+C[e+168>>2])),_(i)},qi,function(A){A|=0,CA(qi(A))},De,function(A,e,r,i,f,t,n,o,c,b){return A|=0,e|=0,r|=0,i|=0,f|=0,t|=0,n|=0,o|=0,c|=0,b|=0,b=Y-16|0,Y=b,Lr(b+8|0,20295),_(Qt[a[a[A>>2]+44>>2]](A,e,r,i,f,t,n,o,c)),_(Qt[a[a[A>>2]+48>>2]](A,e,r,i,f,t,n,o,c)),_(Qt[a[a[A>>2]+36>>2]](A,e,r,o)),qr(),Y=b+16|0,_(_(0))},De,function(A){A|=0,a[A+232>>2]=0},We,function(A,e,r,i){if(A|=0,e|=0,r|=0,i|=0,(0|r)>=1)for(;nf(A,a[e>>2],i),e=e+4|0,r=r+-1|0,r;);},function(A,e,r,i,f,t,n,o,c){A|=0,e|=0,r|=0,i|=0,f|=0,t|=0,o|=0;var b=_(0),l=_(0);A:if(!(!a[o+52>>2]|a[o+20>>2]<1))for(e=0;;){if(b=_(0),i=a[A+28>>2],(0|i)>=1)for(r=0;l=b,t=a[A+16>>2],f=a[A+36>>2]+B(a[a[A+116>>2]+r>>2],152)|0,b=_(Qt[a[A+220>>2]](t+B(a[f+144>>2],244)|0,B(a[f+148>>2],244)+t|0,f)),b=_(l+_(b*b)),r=r+4|0,i=i+-1|0,i;);if(b<=C[o+92>>2])break A;if(r=a[o+20>>2],(0|e)>=(r+-1|0))break A;if(e=e+1|0,!((0|e)<(0|r)))break}},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var t=0,n=0,c=0,b=_(0),l=_(0),u=0,s=_(0),k=_(0),v=_(0),d=_(0),g=0,R=0;if(t=a[i+72>>2],4&t&&(c=a[A+28>>2],!((0|c)<1)))if(r=a[A+76>>2],e=a[A+36>>2],16&t)for(e=e+140|0;t=a[e+-8>>2],a[t+124>>2]=a[e+-40>>2],n=r+B(a[e>>2],152)|0,a[t+128>>2]=a[n+100>>2],a[t+132>>2]=a[n+252>>2],e=e+152|0,c=c+-1|0,c;);else for(e=e+140|0;t=a[e+-8>>2],a[t+124>>2]=a[e+-40>>2],a[t+128>>2]=a[100+(r+B(a[e>>2],152)|0)>>2],e=e+152|0,c=c+-1|0,c;);if(u=a[A+48>>2],(0|u)>=1)for(t=100;r=a[A+56>>2]+t|0,c=a[r+32>>2],e=a[c+44>>2],e&&(n=a[c+28>>2],s=C[n+416>>2],k=C[r+-76>>2],v=C[n+412>>2],d=C[r+-80>>2],b=C[r>>2],l=_(_(1)/C[i+12>>2]),C[e>>2]=C[e>>2]+_(_(_(C[r+-84>>2]*b)*C[n+408>>2])*l),C[e+4>>2]=_(_(v*_(b*d))*l)+C[e+4>>2],C[e+8>>2]=_(_(s*_(b*k))*l)+C[e+8>>2],g=a[c+32>>2],s=C[g+416>>2],k=C[r+-44>>2],v=C[g+412>>2],d=C[r+-48>>2],b=C[r>>2],l=_(_(1)/C[i+12>>2]),C[e+32>>2]=C[e+32>>2]+_(_(_(C[r+-52>>2]*b)*C[g+408>>2])*l),R=e+36|0,C[R>>2]=_(_(v*_(b*d))*l)+C[R>>2],R=e+40|0,C[R>>2]=_(_(s*_(b*k))*l)+C[R>>2],s=C[n+612>>2],k=C[r+-92>>2],v=C[n+608>>2],d=C[r+-96>>2],b=C[r>>2],l=_(_(1)/C[i+12>>2]),C[e+16>>2]=C[e+16>>2]+_(_(_(C[r+-100>>2]*C[n+604>>2])*b)*l),n=e+20|0,C[n>>2]=_(_(b*_(d*v))*l)+C[n>>2],n=e+24|0,C[n>>2]=_(_(b*_(k*s))*l)+C[n>>2],s=C[g+612>>2],k=C[r+-60>>2],v=C[g+608>>2],d=C[r+-64>>2],b=C[r>>2],l=_(_(1)/C[i+12>>2]),C[e+48>>2]=C[e+48>>2]+_(_(_(C[r+-68>>2]*C[g+604>>2])*b)*l),n=e+52|0,C[n>>2]=_(_(b*_(d*v))*l)+C[n>>2],e=e+56|0,C[e>>2]=_(_(b*_(k*s))*l)+C[e>>2]),b=C[r>>2],C[c+36>>2]=b,_(m(b))>=C[c+16>>2]&&(f[c+20|0]=0),t=t+152|0,u=u+-1|0,u;);if(t=a[A+8>>2],(0|t)>=1)for(n=a[A+16>>2],e=176,g=0;r=e+n|0,c=a[r- -64>>2],c&&(a[i+52>>2]?(af(r+-176|0,C[i+12>>2],C[i+60>>2]),n=a[A+16>>2],r=n+e|0,s=C[r>>2],b=C[r+8>>2],l=C[r+4>>2],c=a[r- -64>>2]):(s=_(C[r+-112>>2]+C[r>>2]),C[r>>2]=s,t=r+4|0,l=_(C[r+-108>>2]+C[t>>2]),C[t>>2]=l,t=r+8|0,b=_(C[r+-104>>2]+C[t>>2]),C[t>>2]=b,t=r+16|0,C[t>>2]=C[r+-96>>2]+C[t>>2],t=r+20|0,C[t>>2]=C[r+-92>>2]+C[t>>2],t=r+24|0,C[t>>2]=C[r+-88>>2]+C[t>>2]),r=e+n|0,k=C[r+32>>2],v=C[r+36>>2],d=C[r+40>>2],a[c+384>>2]=0,C[c+380>>2]=b+d,C[c+376>>2]=l+v,C[c+372>>2]=s+k,a[c+304>>2]=a[c+304>>2]+1,r=a[A+16>>2]+e|0,b=C[r+16>>2],l=C[r+48>>2],s=C[r+20>>2],k=C[r+52>>2],v=C[r+24>>2],d=C[r+56>>2],r=a[r- -64>>2],a[r+400>>2]=0,C[r+396>>2]=v+d,C[r+392>>2]=s+k,C[r+388>>2]=b+l,a[r+304>>2]=a[r+304>>2]+1,a[i+52>>2]&&(c=a[A+16>>2]+e|0,r=a[c- -64>>2],a[r+304>>2]=a[r+304>>2]+1,t=c+-176|0,u=t+8|0,R=a[u+4>>2],n=r+12|0,a[n>>2]=a[u>>2],a[n+4>>2]=R,n=a[t+4>>2],a[r+4>>2]=a[t>>2],a[r+8>>2]=n,t=c+-160|0,u=t+8|0,R=a[u+4>>2],n=r+28|0,a[n>>2]=a[u>>2],a[n+4>>2]=R,u=a[t+4>>2],n=r+20|0,a[n>>2]=a[t>>2],a[n+4>>2]=u,t=c+-144|0,u=a[t+4>>2],n=r+36|0,a[n>>2]=a[t>>2],a[n+4>>2]=u,t=t+8|0,u=a[t+4>>2],n=r+44|0,a[n>>2]=a[t>>2],a[n+4>>2]=u,c=c+-128|0,n=c+8|0,u=a[n+4>>2],t=r+60|0,a[t>>2]=a[n>>2],a[t+4>>2]=u,t=a[c+4>>2],r=r+52|0,a[r>>2]=a[c>>2],a[r+4>>2]=t),n=a[A+16>>2],a[a[(n+e|0)- -64>>2]+212>>2]=-1,t=a[A+8>>2]),e=e+244|0,g=g+1|0,(0|g)<(0|t););return a[A+28>>2]>-1|a[A+32>>2]>-1||(e=a[A+36>>2],e&&(o[A+40|0]&&CA(e),a[A+36>>2]=0),a[A+32>>2]=0,a[A+36>>2]=0,f[A+40|0]=1),a[A+28>>2]=0,a[A+48>>2]>-1|a[A+52>>2]>-1||(e=a[A+56>>2],e&&(o[A+60|0]&&CA(e),a[A+56>>2]=0),a[A+52>>2]=0,a[A+56>>2]=0,f[A+60|0]=1),a[A+48>>2]=0,a[A+68>>2]>-1|a[A+72>>2]>-1||(e=a[A+76>>2],e&&(o[A+80|0]&&CA(e),a[A+76>>2]=0),a[A+72>>2]=0,a[A+76>>2]=0,f[A+80|0]=1),a[A+68>>2]=0,a[A+88>>2]>-1|a[A+92>>2]>-1||(e=a[A+96>>2],e&&(o[A+100|0]&&CA(e),a[A+96>>2]=0),a[A+92>>2]=0,a[A+96>>2]=0,f[A+100|0]=1),a[A+88>>2]=0,a[A+8>>2]>-1|a[A+12>>2]>-1||(e=a[A+16>>2],e&&(o[A+20|0]&&CA(e),a[A+16>>2]=0),a[A+12>>2]=0,a[A+16>>2]=0,f[A+20|0]=1),a[A+8>>2]=0,_(_(0))},function(A,e,r,i,t,n,c,b,l,u){A|=0,e|=0,r|=0,i|=0,t|=0,n|=0,c|=0,b|=0,l|=0,u|=0;var s=_(0),k=_(0),v=0,d=_(0),g=0,m=0,R=0,Q=0,h=0,G=0;if(1&f[l+72|0]){if(R=a[A+68>>2],g=a[A+28>>2],m=a[A+48>>2],(0|m)>=1){if(r=B(a[A+232>>2],1664525)+1013904223|0,1!=(0|m)&&(u=a[A+136>>2],i=a[u+4>>2],r=B(r,1664525)+1013904223|0,t=r^r>>>16,t^=t>>>8,t^=t>>>4,t^=t>>>2,t=u+((1&(t>>>1^t))<<2)|0,a[u+4>>2]=a[t>>2],a[t>>2]=i,2!=(0|m)&&(i=a[u+8>>2],r=B(r,1664525)+1013904223|0,t=r^r>>>16,t^=t>>>8,t^=t>>>4,t=u+(((t>>>2^t)>>>0)%3<<2)|0,a[u+8>>2]=a[t>>2],a[t>>2]=i,3!=(0|m)&&(i=a[u+12>>2],r=B(r,1664525)+1013904223|0,t=r^r>>>16,t^=t>>>8,t^=t>>>4,t=u+((3&(t>>>2^t))<<2)|0,a[u+12>>2]=a[t>>2],a[t>>2]=i,4!=(0|m)))))for(n=u+16|0,i=4;G=a[n>>2],Q=n,h=u,r=B(r,1664525)+1013904223|0,i=i+1|0,v=r,i>>>0>65536||(t=r>>>16^r,v=t,i>>>0>256||(t^=t>>>8,v=t,i>>>0>16||(v=t>>>4^t))),t=h+((v>>>0)%(i>>>0)<<2)|0,a[Q>>2]=a[t>>2],a[t>>2]=G,n=n+4|0,(0|i)!=(0|m););a[A+232>>2]=r}if(!(a[l+20>>2]<=(0|e))){if((0|g)>=1){if(r=B(a[A+232>>2],1664525)+1013904223|0,1!=(0|g)&&(u=a[A+116>>2],i=a[u+4>>2],r=B(r,1664525)+1013904223|0,t=r^r>>>16,t^=t>>>8,t^=t>>>4,t^=t>>>2,t=u+((1&(t>>>1^t))<<2)|0,a[u+4>>2]=a[t>>2],a[t>>2]=i,2!=(0|g)&&(i=a[u+8>>2],r=B(r,1664525)+1013904223|0,t=r^r>>>16,t^=t>>>8,t^=t>>>4,t=u+(((t>>>2^t)>>>0)%3<<2)|0,a[u+8>>2]=a[t>>2],a[t>>2]=i,3!=(0|g)&&(i=a[u+12>>2],r=B(r,1664525)+1013904223|0,t=r^r>>>16,t^=t>>>8,t^=t>>>4,t=u+((3&(t>>>2^t))<<2)|0,a[u+12>>2]=a[t>>2],a[t>>2]=i,4!=(0|g)))))for(n=u+16|0,i=4;m=a[n>>2],Q=n,h=u,r=B(r,1664525)+1013904223|0,i=i+1|0,v=r,i>>>0>65536||(t=r>>>16^r,v=t,i>>>0>256||(t^=t>>>8,v=t,i>>>0>16||(v=t>>>4^t))),t=h+((v>>>0)%(i>>>0)<<2)|0,a[Q>>2]=a[t>>2],a[t>>2]=m,n=n+4|0,(0|i)!=(0|g););a[A+232>>2]=r}if(!((0|R)<1)){if(r=B(a[A+232>>2],1664525)+1013904223|0,1!=(0|R)&&(u=a[A+156>>2],i=a[u+4>>2],r=B(r,1664525)+1013904223|0,t=r^r>>>16,t^=t>>>8,t^=t>>>4,t^=t>>>2,t=u+((1&(t>>>1^t))<<2)|0,a[u+4>>2]=a[t>>2],a[t>>2]=i,2!=(0|R)&&(i=a[u+8>>2],r=B(r,1664525)+1013904223|0,t=r^r>>>16,t^=t>>>8,t^=t>>>4,t=u+(((t>>>2^t)>>>0)%3<<2)|0,a[u+8>>2]=a[t>>2],a[t>>2]=i,3!=(0|R)&&(i=a[u+12>>2],r=B(r,1664525)+1013904223|0,t=r^r>>>16,t^=t>>>8,t^=t>>>4,t=u+((3&(t>>>2^t))<<2)|0,a[u+12>>2]=a[t>>2],a[t>>2]=i,4!=(0|R)))))for(n=u+16|0,i=4;g=a[n>>2],Q=n,h=u,r=B(r,1664525)+1013904223|0,i=i+1|0,v=r,i>>>0>65536||(t=r>>>16^r,v=t,i>>>0>256||(t^=t>>>8,v=t,i>>>0>16||(v=t>>>4^t))),t=h+((v>>>0)%(i>>>0)<<2)|0,a[Q>>2]=a[t>>2],a[t>>2]=g,n=n+4|0,(0|i)!=(0|R););a[A+232>>2]=r}}}if(t=a[A+48>>2],(0|t)>=1)for(r=0,n=0;i=a[A+56>>2]+B(a[a[A+136>>2]+r>>2],152)|0,a[i+136>>2]>(0|e)&&(k=s,t=a[A+16>>2],s=_(Qt[a[A+212>>2]](t+B(a[i+144>>2],244)|0,t+B(a[i+148>>2],244)|0,i)),s=_(k+_(s*s)),t=a[A+48>>2]),r=r+4|0,n=n+1|0,(0|n)<(0|t););if(!(a[l+20>>2]<=(0|e))){if((0|b)>=1)for(;e=a[c>>2],o[e+20|0]&&(e=ef(A,a[e+28>>2],C[l+12>>2]),r=ef(A,a[a[c>>2]+32>>2],C[l+12>>2]),i=a[c>>2],t=B(e,244),e=a[A+16>>2],Qt[a[a[i>>2]+24>>2]](i,t+e|0,e+B(r,244)|0,C[l+12>>2])),c=c+4|0,b=b+-1|0,b;);r=a[A+28>>2],e=a[l+72>>2];A:if(512&e){if(!((0|r)<1))for(i=(16&e?2:1)<<2,n=0,c=0;k=s,t=a[A+16>>2],e=a[A+36>>2]+B(a[a[A+116>>2]+c>>2],152)|0,s=_(Qt[a[A+216>>2]](t+B(a[e+144>>2],244)|0,t+B(a[e+148>>2],244)|0,e)),s=_(k+_(s*s)),k=C[e+100>>2],t=k>_(0)^1,t||(e=a[A+76>>2]+B(a[a[A+156>>2]+n>>2],152)|0,d=_(k*C[e+104>>2]),C[e+124>>2]=d,C[e+120>>2]=-d,d=s,b=a[A+16>>2],s=_(Qt[a[A+212>>2]](b+B(a[e+144>>2],244)|0,b+B(a[e+148>>2],244)|0,e)),s=_(d+_(s*s))),t|!(16&o[l+72|0])||(e=a[A+76>>2]+B(a[4+(a[A+156>>2]+n|0)>>2],152)|0,k=_(k*C[e+104>>2]),C[e+124>>2]=k,C[e+120>>2]=-k,k=s,t=a[A+16>>2],s=_(Qt[a[A+212>>2]](t+B(a[e+144>>2],244)|0,t+B(a[e+148>>2],244)|0,e)),s=_(k+_(s*s))),n=i+n|0,c=c+4|0,r=r+-1|0,r;);}else{if((0|r)>=1)for(i=0;k=s,t=a[A+16>>2],e=a[A+36>>2]+B(a[a[A+116>>2]+i>>2],152)|0,s=_(Qt[a[A+216>>2]](t+B(a[e+144>>2],244)|0,t+B(a[e+148>>2],244)|0,e)),s=_(k+_(s*s)),i=i+4|0,r=r+-1|0,r;);if(c=a[A+68>>2],(0|c)<1)break A;for(i=0;e=a[A+76>>2]+B(a[a[A+156>>2]+i>>2],152)|0,k=C[100+(a[A+36>>2]+B(a[e+140>>2],152)|0)>>2],k>_(0)&&(k=_(k*C[e+104>>2]),C[e+124>>2]=k,C[e+120>>2]=-k,k=s,r=a[A+16>>2],s=_(Qt[a[A+212>>2]](r+B(a[e+144>>2],244)|0,r+B(a[e+148>>2],244)|0,e)),s=_(k+_(s*s))),i=i+4|0,c=c+-1|0,c;);}if(c=a[A+88>>2],!((0|c)<1))for(i=0;e=a[A+96>>2]+i|0,k=C[100+(a[A+36>>2]+B(a[e+140>>2],152)|0)>>2],k>_(0)&&(d=k,k=C[e+104>>2],d=_(d*k),k=d>k?k:d,C[e+124>>2]=k,C[e+120>>2]=-k,k=s,r=a[A+16>>2],s=_(Qt[a[A+212>>2]](r+B(a[e+144>>2],244)|0,r+B(a[e+148>>2],244)|0,e)),s=_(k+_(s*s))),i=i+152|0,c=c+-1|0,c;);}return _(s)},function(A,e,r,i,t,n,c,b,l){A|=0,e|=0,r|=0,i|=0,t|=0,n|=0,c|=0,b|=0,l|=0;var u=0,s=0,k=0,v=0,d=0,g=0,R=0,Q=0,h=_(0),G=0,y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=0,Z=_(0),V=_(0),N=_(0),I=0,x=_(0),U=_(0),M=_(0),S=_(0),T=_(0),j=0,O=_(0),H=_(0),z=0,P=0,K=_(0),L=0,q=_(0),$=_(0),AA=_(0),eA=_(0),rA=_(0),iA=_(0),fA=_(0),tA=0,nA=0,aA=0,oA=0,cA=0,bA=0,lA=0,uA=0,sA=_(0),kA=_(0),vA=_(0),gA=_(0),BA=_(0),_A=_(0),mA=_(0),RA=_(0),QA=_(0),hA=_(0),GA=_(0),yA=_(0);if(E=Y-256|0,Y=E,a[A+188>>2]=-1,Lr(E+248|0,20232),l=a[b+72>>2],(0|l)!=a[A+224>>2]&&(a[A+224>>2]=l,a[A+220>>2]=536,a[A+216>>2]=535,a[A+212>>2]=534),a[A+184>>2]=0,(0|r)>=1)for(l=e,k=r;a[a[l>>2]+212>>2]=-1,l=l+4|0,k=k+-1|0,k;);if(l=a[A+12>>2],(0|l)<=(0|r)){if(l=r+1|0,k=0,l&&(k=dA(B(l,244))),u=a[A+8>>2],(0|u)>=1)for(s=64;g=a[A+16>>2]+s|0,Q=g+-64|0,G=a[Q+4>>2],d=s+k|0,R=d+-64|0,v=R,a[v>>2]=a[Q>>2],a[v+4>>2]=G,Q=Q+8|0,v=a[Q+4>>2],R=R+8|0,a[R>>2]=a[Q>>2],a[R+4>>2]=v,R=g+-48|0,G=R+8|0,I=a[G+4>>2],Q=d+-48|0,v=Q+8|0,a[v>>2]=a[G>>2],a[v+4>>2]=I,v=a[R+4>>2],a[Q>>2]=a[R>>2],a[Q+4>>2]=v,R=g+-32|0,G=R+8|0,I=a[G+4>>2],Q=d+-32|0,v=Q+8|0,a[v>>2]=a[G>>2],a[v+4>>2]=I,v=a[R+4>>2],a[Q>>2]=a[R>>2],a[Q+4>>2]=v,Q=g+-16|0,G=a[Q+4>>2],R=d+-16|0,v=R,a[v>>2]=a[Q>>2],a[v+4>>2]=G,Q=Q+8|0,v=a[Q+4>>2],R=R+8|0,a[R>>2]=a[Q>>2],a[R+4>>2]=v,J(d,g,180),s=s+244|0,u=u+-1|0,u;);u=a[A+16>>2],u&&(o[A+20|0]&&CA(u),a[A+16>>2]=0),a[A+16>>2]=k,a[A+12>>2]=l,f[A+20|0]=1}if(d=X(E,0,244),k=a[A+8>>2],(0|k)<=-1)for((0|l)<=-1&&(l=a[A+16>>2],l&&(o[A+20|0]&&CA(l),a[A+16>>2]=0),a[A+12>>2]=0,a[A+16>>2]=0,f[A+20|0]=1),s=B(k,244),R=d- -64|0,E=d+48|0,Q=d+32|0,u=d+16|0;l=a[d+4>>2],g=a[A+16>>2]+s|0,a[g>>2]=a[d>>2],a[g+4>>2]=l,v=d+8|0,G=a[v+4>>2],l=g+8|0,a[l>>2]=a[v>>2],a[l+4>>2]=G,l=u,G=a[l+4>>2],v=g+16|0,a[v>>2]=a[l>>2],a[v+4>>2]=G,l=l+8|0,G=a[l+4>>2],v=g+24|0,a[v>>2]=a[l>>2],a[v+4>>2]=G,v=a[Q+4>>2],l=g+32|0,a[l>>2]=a[Q>>2],a[l+4>>2]=v,v=Q+8|0,G=a[v+4>>2],l=g+40|0,a[l>>2]=a[v>>2],a[l+4>>2]=G,v=a[E+4>>2],l=g+48|0,a[l>>2]=a[E>>2],a[l+4>>2]=v,v=E+8|0,G=a[v+4>>2],l=g+56|0,a[l>>2]=a[v>>2],a[l+4>>2]=G,J(g- -64|0,R,180),s=s+244|0,l=k+1|0,g=l>>>0>=k>>>0,k=l,g;);if(a[A+8>>2]=0,(0|r)>=1)for(;k=ef(A,a[e>>2],C[b+12>>2]),l=a[e>>2],!l|!(2&a[l+252>>2])|C[l+404>>2]==_(0)||(u=a[A+16>>2],s=a[l+564>>2],2&s&&(Oi(d,l,C[b+84>>2]),F=C[l+364>>2],W=C[l+332>>2],x=C[l+348>>2],V=C[l+360>>2],Z=C[l+328>>2],N=C[l+344>>2],s=u+B(k,244)|0,h=C[d>>2],y=C[d+4>>2],w=C[d+8>>2],p=C[b+12>>2],C[s+224>>2]=C[s+224>>2]-_(_(_(_(h*C[l+324>>2])+_(y*C[l+340>>2]))+_(w*C[l+356>>2]))*p),g=s+228|0,C[g>>2]=C[g>>2]-_(p*_(_(_(h*Z)+_(y*N))+_(w*V))),s=s+232|0,C[s>>2]=C[s>>2]-_(p*_(_(_(h*W)+_(y*x))+_(w*F))),s=a[l+564>>2]),4&s&&(zi(d,l,C[b+12>>2]),h=C[d+8>>2],y=C[d+4>>2],s=u+B(k,244)|0,C[s+224>>2]=C[d>>2]+C[s+224>>2],g=s+228|0,C[g>>2]=y+C[g>>2],s=s+232|0,C[s>>2]=h+C[s>>2],s=a[l+564>>2]),8&s&&(Hi(d,l,C[b+12>>2]),h=C[d+8>>2],y=C[d+4>>2],l=u+B(k,244)|0,C[l+224>>2]=C[d>>2]+C[l+224>>2],k=l+228|0,C[k>>2]=y+C[k>>2],l=l+232|0,C[l>>2]=h+C[l>>2])),e=e+4|0,r=r+-1|0,r;);if((0|c)>=1)for(l=n,k=c;e=a[l>>2],Qt[a[a[e>>2]+8>>2]](e),a[e+36>>2]=0,l=l+4|0,k=k+-1|0,k;);if(e=a[A+168>>2],!((0|e)>=(0|c)|a[A+172>>2]>=(0|c))){if(c?(k=dA(c<<3),e=a[A+168>>2]):k=0,(0|e)>=1)for(l=0;u=a[A+176>>2]+l|0,s=a[u+4>>2],r=l+k|0,a[r>>2]=a[u>>2],a[r+4>>2]=s,l=l+8|0,e=e+-1|0,e;);e=a[A+176>>2],e&&(o[A+180|0]&&CA(e),a[A+176>>2]=0),a[A+176>>2]=k,a[A+172>>2]=c,f[A+180|0]=1}if(a[A+168>>2]=c,(0|c)<1)s=0;else for(r=0,k=n,u=c,s=0;g=a[A+176>>2],e=a[k>>2],l=a[e+44>>2],l&&(a[l>>2]=0,a[l+4>>2]=0,e=l+56|0,a[e>>2]=0,a[e+4>>2]=0,e=l+48|0,a[e>>2]=0,a[e+4>>2]=0,e=l+40|0,a[e>>2]=0,a[e+4>>2]=0,e=l+32|0,a[e>>2]=0,a[e+4>>2]=0,e=l+24|0,a[e>>2]=0,a[e+4>>2]=0,e=l+16|0,a[e>>2]=0,a[e+4>>2]=0,e=l+8|0,a[e>>2]=0,a[e+4>>2]=0,e=a[k>>2]),l=r+g|0,r=r+8|0,k=k+4|0,o[e+20|0]?(Qt[a[a[e>>2]+16>>2]](e,l),e=a[l>>2]):(a[l>>2]=0,a[l+4>>2]=0,e=0),s=e+s|0,u=u+-1|0,u;);if(e=a[A+48>>2],!((0|e)>=(0|s)|a[A+52>>2]>=(0|s))){if(s?(k=dA(B(s,152)),e=a[A+48>>2]):k=0,(0|e)>=1)for(l=0;J(l+k|0,a[A+56>>2]+l|0,152),l=l+152|0,e=e+-1|0,e;);e=a[A+56>>2],e&&(o[A+60|0]&&CA(e),a[A+56>>2]=0),a[A+56>>2]=k,a[A+52>>2]=s,f[A+60|0]=1}if(a[A+48>>2]=s,(0|c)>=1)for(l=a[A+176>>2],E=0,R=0;;){if(tA=R,L=E<<3,Q=L+l|0,a[Q>>2]){if(v=(E<<2)+n|0,g=a[v>>2],k=a[g+32>>2],G=a[A+56>>2],u=a[g+28>>2],s=ef(A,u,C[b+12>>2]),I=ef(A,k,C[b+12>>2]),z=B(R,152),P=a[A+16>>2],e=a[g+24>>2],j=(0|e)>0?e:a[b+20>>2],(0|j)>a[A+184>>2]&&(a[A+184>>2]=j),e=G+z|0,a[Q>>2]>=1)for(r=0,l=e;l=X(l,0,152),R=l+120|0,a[R>>2]=-8388609,a[R+4>>2]=2139095039,a[l+148>>2]=I,a[l+144>>2]=s,R=l+96|0,a[R>>2]=0,a[R+4>>2]=0,a[l+136>>2]=j,l=l+152|0,r=r+1|0,(0|r)>2];);if(r=P+B(s,244)|0,l=r,a[l+144>>2]=0,a[l+148>>2]=0,l=l+152|0,a[l>>2]=0,a[l+4>>2]=0,l=r+160|0,a[l>>2]=0,a[l+4>>2]=0,l=r+168|0,a[l>>2]=0,a[l+4>>2]=0,a[r+64>>2]=0,a[r+68>>2]=0,l=r+88|0,a[l>>2]=0,a[l+4>>2]=0,l=r+80|0,a[l>>2]=0,a[l+4>>2]=0,l=r+72|0,a[l>>2]=0,a[l+4>>2]=0,s=P+B(I,244)|0,l=s,a[l+144>>2]=0,a[l+148>>2]=0,l=l+152|0,a[l>>2]=0,a[l+4>>2]=0,l=s+160|0,a[l>>2]=0,a[l+4>>2]=0,l=s+168|0,a[l>>2]=0,a[l+4>>2]=0,a[s+64>>2]=0,a[s+68>>2]=0,l=s+72|0,a[l>>2]=0,a[l+4>>2]=0,l=s+80|0,a[l>>2]=0,a[l+4>>2]=0,l=s+88|0,a[l>>2]=0,a[l+4>>2]=0,a[e+116>>2]=a[b+40>>2],a[d+28>>2]=e+112,a[d+24>>2]=38,a[d+20>>2]=e+32,a[d+16>>2]=e+48,a[d+12>>2]=e,a[d+8>>2]=e+16,a[d+40>>2]=e+124,a[d+36>>2]=e+120,a[d+32>>2]=e+116,a[d+4>>2]=a[b+32>>2],a[d+48>>2]=a[b+4>>2],C[d>>2]=_(1)/C[b+12>>2],a[d+44>>2]=a[b+20>>2],e=a[v>>2],Qt[a[a[e>>2]+20>>2]](e,d),a[Q>>2]>=1)for(l=132+(G+z|0)|0,G=s+232|0,I=s+228|0,z=s+224|0,P=s+216|0,j=s+212|0,R=s+208|0,s=s+240|0,nA=r+232|0,aA=r+228|0,oA=r+224|0,cA=r+216|0,bA=r+212|0,lA=r+208|0,uA=r+240|0,r=0;e=l+-8|0,h=C[a[v>>2]+16>>2],C[e>>2]>=h&&(C[e>>2]=h),e=l+-12|0,h=_(-h),C[e>>2]<=h&&(C[e>>2]=h),a[l>>2]=g,e=a[g+28>>2],p=C[e+328>>2],F=C[e+332>>2],W=C[e+608>>2],x=C[e+348>>2],V=C[e+340>>2],Z=C[e+344>>2],h=C[e+612>>2],w=C[e+364>>2],y=C[e+356>>2],N=C[e+360>>2],M=C[e+604>>2],D=C[e+324>>2],a[l+-56>>2]=0,U=h,h=C[l+-132>>2],S=_(y*h),y=C[l+-128>>2],T=w,w=C[l+-124>>2],C[l+-60>>2]=U*_(_(S+_(N*y))+_(T*w)),C[l+-64>>2]=W*_(_(_(h*V)+_(y*Z))+_(w*x)),C[l+-68>>2]=M*_(_(_(D*h)+_(p*y))+_(F*w)),e=a[g+32>>2],x=C[e+328>>2],V=C[e+332>>2],Z=C[e+608>>2],N=C[e+348>>2],M=C[e+340>>2],D=C[e+344>>2],p=C[e+612>>2],W=C[e+364>>2],F=C[e+356>>2],O=C[e+360>>2],H=C[e+604>>2],S=C[e+324>>2],a[l+-40>>2]=0,U=p,p=C[l+-100>>2],K=_(F*p),F=C[l+-96>>2],T=W,W=C[l+-92>>2],C[l+-44>>2]=U*_(_(K+_(O*F))+_(T*W)),C[l+-48>>2]=Z*_(_(_(p*M)+_(F*D))+_(W*N)),C[l+-52>>2]=H*_(_(_(S*p)+_(x*F))+_(V*W)),x=_(0),V=C[l+-116>>2],Z=C[u+404>>2],N=C[l+-112>>2],M=C[l+-108>>2],U=_(_(_(_(V*_(V*Z))+_(N*_(Z*N)))+_(M*_(Z*M)))+_(_(_(h*_(_(_(h*C[u+324>>2])+_(y*C[u+328>>2]))+_(w*C[u+332>>2])))+_(y*_(_(_(h*C[u+340>>2])+_(y*C[u+344>>2]))+_(w*C[u+348>>2]))))+_(w*_(_(_(h*C[u+356>>2])+_(y*C[u+360>>2]))+_(w*C[u+364>>2]))))),Z=C[l+-84>>2],D=C[k+404>>2],O=C[l+-80>>2],H=C[l+-76>>2],D=_(_(U+_(_(_(Z*_(Z*D))+_(O*_(D*O)))+_(H*_(D*H))))+_(_(_(p*_(_(_(p*C[k+324>>2])+_(F*C[k+328>>2]))+_(W*C[k+332>>2])))+_(F*_(_(_(p*C[k+340>>2])+_(F*C[k+344>>2]))+_(W*C[k+348>>2]))))+_(W*_(_(_(p*C[k+356>>2])+_(F*C[k+360>>2]))+_(W*C[k+364>>2]))))),D=_(m(D))>_(1.1920928955078125e-7)?_(_(1)/D):_(0),C[l+-24>>2]=D,S=_(0),U=_(0),T=_(0),K=_(0),q=_(0),$=_(0),a[uA>>2]&&($=C[nA>>2],q=C[aA>>2],K=C[oA>>2],U=C[bA>>2],T=C[lA>>2],S=C[cA>>2]),AA=_(0),eA=_(0),rA=_(0),iA=_(0),fA=_(0),a[s>>2]&&(fA=C[G>>2],iA=C[I>>2],rA=C[z>>2],AA=C[j>>2],eA=C[R>>2],x=C[P>>2]),sA=C[u+380>>2],kA=C[u+372>>2],vA=C[u+376>>2],gA=C[u+396>>2],BA=C[u+388>>2],_A=C[u+392>>2],mA=C[k+380>>2],RA=C[k+372>>2],QA=C[k+376>>2],hA=C[k+396>>2],GA=C[k+388>>2],yA=C[k+392>>2],a[l+-32>>2]=0,e=l+-20|0,C[e>>2]=_(D*C[e>>2])+_(D*_(_(0)-_(C[d+48>>2]*_(_(_(_(_(V*_(T+kA))+_(N*_(U+vA)))+_(M*_(S+sA)))+_(_(_(h*_(K+BA))+_(y*_(q+_A)))+_(w*_($+gA))))+_(_(_(_(Z*_(eA+RA))+_(O*_(AA+QA)))+_(H*_(x+mA)))+_(_(_(p*_(rA+GA))+_(F*_(iA+yA)))+_(W*_(fA+hA)))))))),l=l+152|0,r=r+1|0,(0|r)>2];);l=a[A+176>>2]}if(R=tA+a[l+L>>2]|0,E=E+1|0,(0|E)==(0|c))break}if(Qt[a[a[A>>2]+28>>2]](A,i,t,b),n=a[A+68>>2],t=a[A+28>>2],u=a[A+128>>2],c=a[A+48>>2],!((0|u)>=(0|c)|a[A+132>>2]>=(0|c))){c?(r=dA(c<<2),u=a[A+128>>2]):r=0,i=a[A+136>>2];A:{if((0|u)>=1)for(l=r,e=i;a[l>>2]=a[e>>2],l=l+4|0,e=e+4|0,u=u+-1|0,u;);else if(!i)break A;o[A+140|0]&&CA(i),a[A+136>>2]=0}a[A+136>>2]=r,a[A+132>>2]=c,f[A+140|0]=1}if(a[A+128>>2]=c,16&o[b+72|0]){if(u=a[A+108>>2],i=t<<1,!((0|u)>=(0|i)|a[A+112>>2]>=(0|i))){t?(k=dA(t<<3),u=a[A+108>>2]):k=0,r=a[A+116>>2];A:{if((0|u)>=1)for(l=k,e=r;a[l>>2]=a[e>>2],l=l+4|0,e=e+4|0,u=u+-1|0,u;);else if(!r)break A;o[A+120|0]&&CA(r),a[A+116>>2]=0}a[A+116>>2]=k,a[A+112>>2]=i,f[A+120|0]=1}a[A+108>>2]=i}else{if(u=a[A+108>>2],!((0|u)>=(0|t)|a[A+112>>2]>=(0|t))){t?(r=dA(t<<2),u=a[A+108>>2]):r=0,i=a[A+116>>2];A:{if((0|u)>=1)for(l=r,e=i;a[l>>2]=a[e>>2],l=l+4|0,e=e+4|0,u=u+-1|0,u;);else if(!i)break A;o[A+120|0]&&CA(i),a[A+116>>2]=0}a[A+116>>2]=r,a[A+112>>2]=t,f[A+120|0]=1}a[A+108>>2]=t}if(u=a[A+148>>2],!((0|u)>=(0|n)|a[A+152>>2]>=(0|n))){n?(r=dA(n<<2),u=a[A+148>>2]):r=0,i=a[A+156>>2];A:{if((0|u)>=1)for(l=r,e=i;a[l>>2]=a[e>>2],l=l+4|0,e=e+4|0,u=u+-1|0,u;);else if(!i)break A;o[A+160|0]&&CA(i),a[A+156>>2]=0}a[A+156>>2]=r,a[A+152>>2]=n,f[A+160|0]=1}if(a[A+148>>2]=n,(0|c)>=1)for(l=a[A+136>>2],e=0;a[l>>2]=e,l=l+4|0,e=e+1|0,(0|c)!=(0|e););if((0|t)>=1)for(l=a[A+116>>2],e=0;a[l>>2]=e,l=l+4|0,e=e+1|0,(0|t)!=(0|e););if((0|n)>=1)for(l=a[A+156>>2],e=0;a[l>>2]=e,l=l+4|0,e=e+1|0,(0|n)!=(0|e););return qr(),Y=d+256|0,_(_(0))},function(A,e,r,i,f,t,n,o,c){A|=0,e|=0,r|=0,i|=0,f|=0,t|=0,n|=0,o|=0,c|=0;var b,l=0,u=0,s=_(0),k=0;b=Y-16|0,Y=b,Lr(b+8|0,20261),Qt[a[a[A>>2]+32>>2]](A,e,r,i,f,t,n,o,c),l=a[A+184>>2],u=a[o+20>>2],u=(0|l)>(0|u)?l:u;A:if(!((0|u)<1))for(k=u+-1|0,l=0;;){if(s=_(Qt[a[a[A>>2]+40>>2]](A,l,e,r,i,f,t,n,o,c)),C[A+228>>2]=s,(0|l)>=(0|k)|s<=C[o+92>>2])break A;if(l=l+1|0,!((0|l)<(0|u)))break}return qr(),Y=b+16|0,_(_(0))},ve,bf,kA,function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f,t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),p=_(0),F=_(0),W=_(0),w=0,D=_(0);f=Y-32|0,Y=f,g=C[e+24>>2],F=C[e+40>>2],B=C[e+36>>2],c=C[e+20>>2],u=C[e+8>>2],m=C[e+16>>2],k=C[e+4>>2],R=C[e+32>>2],v=C[e>>2],a[f+28>>2]=0,n=_(m-v),b=_(B-k),o=_(c-k),s=_(R-v),t=_(_(n*b)-_(o*s)),C[f+24>>2]=t,l=_(g-u),G=_(l*s),s=_(F-u),n=_(G-_(n*s)),C[f+20>>2]=n,b=_(_(o*s)-_(l*b)),C[f+16>>2]=b,d=C[A+4>>2],l=C[A+8>>2],Q=C[A+12>>2],o=_(_(u*t)+_(_(v*b)+_(k*n))),s=_(_(_(_(b*d)+_(n*l))+_(t*Q))-o),p=C[A+20>>2],h=C[A+24>>2],W=C[A+28>>2],o=_(_(_(_(b*p)+_(n*h))+_(t*W))-o),_(s*o)>=_(0)||(e=a[A+36>>2],1&e&&s<=_(0)||(o=_(s/_(s-o)),o>2]&&(G=l,l=_(_(1)-o),h=_(_(h*o)+_(G*l)),c=_(c-h),d=_(_(p*o)+_(d*l)),v=_(v-d),k=_(k-h),m=_(m-d),l=_(_(W*o)+_(Q*l)),g=_(g-l),u=_(u-l),p=_(_(t*t)+_(_(b*b)+_(n*n))),Q=_(p*_(-9999999747378752e-20)),_(_(t*_(_(c*v)-_(k*m)))+_(_(b*_(_(k*g)-_(u*c)))+_(n*_(_(u*m)-_(g*v)))))>=Q&&(B=_(B-h),R=_(R-d),d=_(t*_(_(B*m)-_(c*R))),G=c,c=_(F-l),_(d+_(_(b*_(_(G*c)-_(g*B)))+_(n*_(_(g*R)-_(c*m)))))>=Q^1|_(_(t*_(_(k*R)-_(B*v)))+_(_(b*_(_(B*u)-_(c*k)))+_(n*_(_(c*v)-_(u*R)))))>=Q^1||(c=t,t=_(_(1)/_(y(p))),u=_(c*t),C[f+24>>2]=u,n=_(n*t),C[f+20>>2]=n,t=_(b*t),C[f+16>>2]=t,2&e|s<=_(0)^1?(w=A,D=_(Qt[a[a[A>>2]+12>>2]](A,f+16|0,o,r,i)),C[w+40>>2]=D):(a[f+12>>2]=0,C[f+8>>2]=-u,C[f+4>>2]=-n,C[f>>2]=-t,w=A,D=_(Qt[a[a[A>>2]+12>>2]](A,f,o,r,i)),C[w+40>>2]=D)))))),Y=f+32|0},kA,function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var t,n,o=0,c=0,b=0,l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0);t=Y-688|0,Y=t,n=zA(t+576|0),o=e+8|0,c=a[o+4>>2],b=t+644|0,a[b>>2]=a[o>>2],a[b+4>>2]=c,o=a[e+20>>2],c=t+652|0,a[c>>2]=a[e+16>>2],a[c+4>>2]=o,o=e+24|0,c=a[o+4>>2],b=t+660|0,a[b>>2]=a[o>>2],a[b+4>>2]=c,o=a[e+36>>2],c=t+668|0,a[c>>2]=a[e+32>>2],a[c+4>>2]=o,o=e+40|0,c=a[o+4>>2],b=t+676|0,a[b>>2]=a[o>>2],a[b+4>>2]=c,a[t+580>>2]=1,a[t+576>>2]=16352,o=a[e+4>>2],a[t+636>>2]=a[e>>2],a[t+640>>2]=o,a[t+624>>2]=a[A+204>>2],f[t+548|0]=0,a[t+524>>2]=953267991,a[t+208>>2]=14800,e=of(t+184|0,a[A+4>>2],t+576|0,t+216|0,t+208|0),a[t+8>>2]=15992,a[t+172>>2]=1065353216,a[t+176>>2]=0,a[t+180>>2]=a[A+208>>2],o=e,e=A+136|0,bf(o,A+8|0,A+72|0,e,e,t+8|0)&&(u=C[t+140>>2],s=C[t+144>>2],l=C[t+148>>2],k=_(_(_(u*u)+_(s*s))+_(l*l)),k>_(9999999747378752e-20)&&(v=C[t+172>>2],v>2]&&(d=l,l=_(_(1)/_(y(k))),C[t+148>>2]=d*l,C[t+144>>2]=s*l,C[t+140>>2]=u*l,_(Qt[a[a[A>>2]+12>>2]](A,t+140|0,t+156|0,v,r,i))))),Ae(n),Y=t+688|0},sf,function(A){A|=0;var e=0,r=0,i=0,f=0,t=0,n=0;if(a[A>>2]=20592,e=a[A+16>>2],r=a[A+8>>2],(0|r)>=1)for(;t=a[e+f>>2],i=a[t+188>>2],i&&(e=a[A+68>>2],e=0|Qt[a[a[e>>2]+36>>2]](e),Qt[a[a[e>>2]+40>>2]](e,i,a[A+24>>2]),e=a[A+68>>2],Qt[a[a[e>>2]+12>>2]](e,i,a[A+24>>2]),a[t+188>>2]=0,r=a[A+8>>2],e=a[A+16>>2]),f=f+4|0,n=n+1|0,(0|n)<(0|r););!e|!o[A+20|0]||CA(e),$(A)},function(A){A|=0;var e,r=0,i=0,f=0,t=0,n=0;if(e=Y-16|0,Y=e,Lr(e+8|0,20835),r=a[A+8>>2],(0|r)>=1)for(;;){f=a[a[A+16>>2]+i>>2];A:{e:if(!(o[A+76|0]||(t=a[f+220>>2]+-2|0,t>>>0>3)))switch(t-1|0){case 0:case 1:break e;default:break A}vf(A,f),r=a[A+8>>2]}if(i=i+4|0,n=n+1|0,!((0|n)<(0|r)))break}qr(),Y=e+16|0},function(A){var e,r;A|=0,e=Y-16|0,Y=e,Lr(e+8|0,20847),r=a[A+68>>2],Qt[a[a[r>>2]+32>>2]](r,a[A+24>>2]),qr(),Y=e+16|0},function(A,e){A|=0,e|=0,a[A+72>>2]=e},Ce,mf,function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f,t=0,n=0,o=0,c=_(0),b=_(0),l=_(0),u=_(0),s=0,k=_(0),v=_(0),d=_(0),g=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=0,E=_(0),Z=_(0),V=_(0),N=0,I=0,J=0,x=0,U=0,M=0,S=0,X=_(0);f=Y-144|0,Y=f,Qt[a[a[A>>2]+20>>2]](A)&&(n=0|Qt[a[a[A>>2]+20>>2]](A),32768&Qt[a[a[n>>2]+56>>2]](n)&&(n=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[n>>2]+64>>2]](n,e,_(.10000000149011612))));A:{e:if(n=a[r+4>>2],!(n>>>0>31)){switch(n-1|0){case 30:if(t=a[r+20>>2],(0|t)<1)break A;for(o=B(t,80)+-80|0;n=a[r+28>>2]+o|0,s=a[n- -64>>2],c=C[n+56>>2],b=C[n+48>>2],l=C[n+52>>2],k=C[n+32>>2],g=C[n>>2],m=C[n+16>>2],R=C[n+36>>2],h=C[n+4>>2],y=C[n+20>>2],u=C[n+40>>2],v=C[n+8>>2],d=C[n+24>>2],a[f+60>>2]=0,a[f+44>>2]=0,a[f+28>>2]=0,a[f+12>>2]=0,p=C[e+32>>2],Q=C[e+36>>2],G=C[e+40>>2],C[f+40>>2]=_(_(v*p)+_(d*Q))+_(u*G),C[f+36>>2]=_(_(h*p)+_(y*Q))+_(R*G),C[f+32>>2]=_(_(g*p)+_(m*Q))+_(k*G),F=C[e+16>>2],W=C[e+20>>2],w=C[e+24>>2],C[f+24>>2]=_(_(v*F)+_(d*W))+_(u*w),C[f+20>>2]=_(_(h*F)+_(y*W))+_(R*w),C[f+16>>2]=_(_(g*F)+_(m*W))+_(k*w),E=v,v=C[e>>2],Z=d,d=C[e+4>>2],V=u,u=C[e+8>>2],C[f+8>>2]=_(_(E*v)+_(Z*d))+_(V*u),C[f+4>>2]=_(_(h*v)+_(y*d))+_(R*u),C[f>>2]=_(_(g*v)+_(m*d))+_(k*u),C[f+56>>2]=_(_(_(b*p)+_(l*Q))+_(c*G))+C[e+56>>2],C[f+52>>2]=_(_(_(b*F)+_(l*W))+_(c*w))+C[e+52>>2],C[f+48>>2]=_(_(_(b*v)+_(l*d))+_(c*u))+C[e+48>>2],Qt[a[a[A>>2]+28>>2]](A,f,s,i),o=o+-80|0,t=t+-1|0,(0|t)>0;);break A;default:n=r+40|0,o=a[n+4>>2],t=f+8|0,a[t>>2]=a[n>>2],a[t+4>>2]=o,n=a[r+36>>2],a[f>>2]=a[r+32>>2],a[f+4>>2]=n,c=_(Qt[a[a[r>>2]+48>>2]](r)),b=_(Qt[a[a[r>>2]+48>>2]](r)),l=_(_(Qt[a[a[r>>2]+48>>2]](r))+C[t>>2]),C[t>>2]=l,c=_(c+C[f>>2]),C[f>>2]=c,b=_(b+C[f+4>>2]),C[f+4>>2]=b,A=0|Qt[a[a[A>>2]+20>>2]](A),a[f+140>>2]=0,C[f+136>>2]=-l,C[f+132>>2]=-b,C[f+128>>2]=-c,Qt[a[a[A>>2]+80>>2]](A,f+128|0,f,e,i);break A;case 7:c=_(Qt[a[a[r>>2]+48>>2]](r)),A=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[A>>2]+24>>2]](A,c,e,i);break A;case 8:if(s=a[r+96>>2],(0|s)<1)break A;for(t=(s<<2)-4|0,o=(s<<4)-8|0;n=a[r+104>>2]+o|0,c=C[n>>2],b=C[n+-8>>2],l=C[n+-4>>2],n=0|Qt[a[a[A>>2]+20>>2]](A),p=C[a[r+124>>2]+t>>2],a[f+60>>2]=0,a[f+44>>2]=0,a[f+28>>2]=0,a[f+12>>2]=0,k=C[e+40>>2],g=C[e+32>>2],R=_(g*_(0)),m=C[e+36>>2],h=_(m*_(0)),C[f+40>>2]=k+_(R+h),u=_(R+m),R=_(k*_(0)),C[f+36>>2]=u+R,C[f+32>>2]=_(g+h)+R,R=C[e+24>>2],h=C[e+16>>2],u=_(h*_(0)),y=C[e+20>>2],v=_(y*_(0)),C[f+24>>2]=R+_(u+v),d=_(u+y),u=_(R*_(0)),C[f+20>>2]=d+u,C[f+16>>2]=_(h+v)+u,u=C[e+8>>2],v=C[e>>2],Q=_(v*_(0)),d=C[e+4>>2],G=_(d*_(0)),C[f+8>>2]=u+_(Q+G),E=_(Q+d),Q=_(u*_(0)),C[f+4>>2]=E+Q,C[f>>2]=_(v+G)+Q,C[f+56>>2]=_(_(_(b*g)+_(l*m))+_(c*k))+C[e+56>>2],C[f+52>>2]=_(_(_(b*h)+_(l*y))+_(c*R))+C[e+52>>2],C[f+48>>2]=_(_(_(b*v)+_(l*d))+_(c*u))+C[e+48>>2],Qt[a[a[n>>2]+24>>2]](n,p,f,i),t=t+-4|0,o=o+-16|0,s=s+-1|0,(0|s)>0;);break A;case 9:t=r+32|0,r=a[r+56>>2],c=C[t+(r<<2)>>2],b=C[t+((r+2|0)%3<<2)>>2],A=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[A>>2]+84>>2]](A,b,c,r,e,i);break A;case 10:t=a[r+72>>2],c=C[r+60>>2],b=C[r+64>>2],A=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[A>>2]+92>>2]](A,c,b,t,e,i);break A;case 12:t=a[r+56>>2],c=_(Qt[a[a[r>>2]+92>>2]](r)),o=r+40|0,s=a[o+4>>2],n=f+8|0,a[n>>2]=a[o>>2],a[n+4>>2]=s,o=a[r+36>>2],a[f>>2]=a[r+32>>2],a[f+4>>2]=o,b=_(Qt[a[a[r>>2]+48>>2]](r)),l=_(Qt[a[a[r>>2]+48>>2]](r)),S=n,X=_(_(Qt[a[a[r>>2]+48>>2]](r))+C[n>>2]),C[S>>2]=X,C[f>>2]=b+C[f>>2],C[f+4>>2]=l+C[f+4>>2],b=C[(t<<2)+f>>2],A=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[A>>2]+88>>2]](A,c,b,t,e,i);break A;case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 11:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 28:case 29:break e;case 27:}c=C[r+68>>2],A=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[A>>2]+96>>2]](A,r+52|0,c,e,i);break A}e:if(!((0|n)>6))if(D=a[r+56>>2],D){if(a[D+28>>2]<1)break e;for(;;){l=_(0);r:if(J=B(I,36),t=J+a[D+36>>2]|0,N=a[t+4>>2],N){if(c=_(0),b=_(0),!((0|N)<1))for(o=a[t+12>>2],t=a[(o+(N<<2)|0)-4>>2],s=1,x=0;;){if(n=a[o+x>>2],U=n<<4,o=U+a[D+16>>2]|0,R=C[o>>2],h=C[o+4>>2],y=C[o+8>>2],o=0|Qt[a[a[A>>2]+20>>2]](A),a[f+12>>2]=0,M=a[D+16>>2],t=M+(t<<4)|0,k=C[t>>2],u=C[e+32>>2],g=C[t+4>>2],v=C[e+36>>2],m=C[t+8>>2],d=C[e+40>>2],p=C[e+56>>2],C[f+8>>2]=_(_(_(k*u)+_(g*v))+_(m*d))+p,Q=C[e+16>>2],G=C[e+20>>2],F=C[e+24>>2],W=C[e+52>>2],C[f+4>>2]=_(_(_(k*Q)+_(g*G))+_(m*F))+W,w=C[e>>2],E=C[e+4>>2],Z=C[e+8>>2],V=C[e+48>>2],C[f>>2]=_(_(_(k*w)+_(g*E))+_(m*Z))+V,a[f+140>>2]=0,t=U+M|0,k=C[t>>2],g=C[t+4>>2],m=C[t+8>>2],C[f+136>>2]=p+_(_(_(u*k)+_(v*g))+_(d*m)),C[f+132>>2]=W+_(_(_(Q*k)+_(G*g))+_(F*m)),C[f+128>>2]=V+_(_(_(w*k)+_(E*g))+_(Z*m)),Qt[a[a[o>>2]+16>>2]](o,f,f+128|0,i),b=_(b+y),c=_(c+h),l=_(l+R),t=a[D+36>>2]+J|0,(0|s)>=a[t+4>>2])break r;x=x+4|0,s=s+1|0,o=a[t+12>>2],t=n}}else c=_(0),b=_(0);if(t=0|Qt[a[a[A>>2]+20>>2]](A),16384&Qt[a[a[t>>2]+56>>2]](t)&&(a[f+8>>2]=0,a[f+12>>2]=0,a[f>>2]=1065353216,a[f+4>>2]=1065353216,t=a[D+36>>2]+J|0,g=C[t+28>>2],m=C[t+20>>2],R=C[t+24>>2],t=0|Qt[a[a[A>>2]+20>>2]](A),a[f+140>>2]=0,k=_(_(1)/_(0|N)),l=_(k*l),h=C[e+32>>2],c=_(k*c),y=C[e+36>>2],b=_(k*b),k=C[e+40>>2],u=C[e+56>>2],C[f+136>>2]=_(_(_(l*h)+_(c*y))+_(b*k))+u,v=C[e+16>>2],d=C[e+20>>2],p=C[e+24>>2],Q=C[e+52>>2],C[f+132>>2]=_(_(_(l*v)+_(c*d))+_(b*p))+Q,G=C[e>>2],F=C[e+4>>2],W=C[e+8>>2],w=C[e+48>>2],C[f+128>>2]=_(_(_(l*G)+_(c*F))+_(b*W))+w,a[f+124>>2]=0,l=_(l+m),c=_(c+R),b=_(b+g),C[f+120>>2]=u+_(_(_(h*l)+_(y*c))+_(k*b)),C[f+116>>2]=Q+_(_(_(l*v)+_(c*d))+_(b*p)),C[f+112>>2]=w+_(_(_(l*G)+_(c*F))+_(b*W)),Qt[a[a[t>>2]+16>>2]](t,f+128|0,f+112|0,f)),I=I+1|0,!((0|I)>2]))break}}else if(!((0|Qt[a[a[r>>2]+100>>2]](r))<1))for(;Qt[a[a[r>>2]+104>>2]](r,t,f,f+128|0),a[f+124>>2]=0,c=C[f>>2],k=C[e+32>>2],b=C[f+4>>2],g=C[e+36>>2],l=C[f+8>>2],m=C[e+40>>2],R=C[e+56>>2],C[f+120>>2]=_(_(_(c*k)+_(b*g))+_(l*m))+R,h=C[e+16>>2],y=C[e+20>>2],u=C[e+24>>2],v=C[e+52>>2],C[f+116>>2]=_(_(_(c*h)+_(b*y))+_(l*u))+v,d=C[e>>2],p=C[e+4>>2],Q=C[e+8>>2],G=C[e+48>>2],C[f+112>>2]=_(_(_(c*d)+_(b*p))+_(l*Q))+G,a[f+108>>2]=0,c=C[f+128>>2],b=C[f+132>>2],l=C[f+136>>2],C[f+104>>2]=R+_(_(_(k*c)+_(g*b))+_(m*l)),C[f+100>>2]=v+_(_(_(h*c)+_(y*b))+_(u*l)),C[f+96>>2]=G+_(_(_(d*c)+_(p*b))+_(Q*l)),n=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[n>>2]+16>>2]](n,f+112|0,f+96|0,i),t=t+1|0,(0|t)<(0|Qt[a[a[r>>2]+100>>2]](r)););t=a[r+4>>2],t+-21>>>0<=8&&(a[f+136>>2]=1566444395,a[f+140>>2]=0,a[f+128>>2]=1566444395,a[f+132>>2]=1566444395,a[f+120>>2]=-581039253,a[f+124>>2]=0,a[f+112>>2]=-581039253,a[f+116>>2]=-581039253,t=0|Qt[a[a[A>>2]+20>>2]](A),n=i+8|0,o=a[n+4>>2],s=f+20|0,a[s>>2]=a[n>>2],a[s+4>>2]=o,n=e+8|0,o=a[n+4>>2],s=f+36|0,a[s>>2]=a[n>>2],a[s+4>>2]=o,n=a[e+20>>2],o=f+44|0,a[o>>2]=a[e+16>>2],a[o+4>>2]=n,n=e+24|0,o=a[n+4>>2],s=f+52|0,a[s>>2]=a[n>>2],a[s+4>>2]=o,n=a[e+36>>2],o=f+60|0,a[o>>2]=a[e+32>>2],a[o+4>>2]=n,n=e+40|0,o=a[n+4>>2],s=f+68|0,a[s>>2]=a[n>>2],a[s+4>>2]=o,a[f+8>>2]=t,a[f+4>>2]=22836,a[f>>2]=22812,t=a[i+4>>2],a[f+12>>2]=a[i>>2],a[f+16>>2]=t,t=a[e+4>>2],a[f+28>>2]=a[e>>2],a[f+32>>2]=t,t=e+56|0,n=a[t+4>>2],o=f+84|0,a[o>>2]=a[t>>2],a[o+4>>2]=n,t=a[e+52>>2],n=f+76|0,a[n>>2]=a[e+48>>2],a[n+4>>2]=t,Qt[a[a[r>>2]+64>>2]](r,f,f+112|0,f+128|0),t=a[r+4>>2]),3==(0|t)&&(a[f+136>>2]=1566444395,a[f+140>>2]=0,a[f+128>>2]=1566444395,a[f+132>>2]=1566444395,a[f+120>>2]=-581039253,a[f+124>>2]=0,a[f+112>>2]=-581039253,a[f+116>>2]=-581039253,A=0|Qt[a[a[A>>2]+20>>2]](A),t=i+8|0,n=a[t+4>>2],o=f+20|0,a[o>>2]=a[t>>2],a[o+4>>2]=n,t=e+8|0,n=a[t+4>>2],o=f+36|0,a[o>>2]=a[t>>2],a[o+4>>2]=n,t=a[e+20>>2],n=f+44|0,a[n>>2]=a[e+16>>2],a[n+4>>2]=t,t=e+24|0,n=a[t+4>>2],o=f+52|0,a[o>>2]=a[t>>2],a[o+4>>2]=n,t=a[e+36>>2],n=f+60|0,a[n>>2]=a[e+32>>2],a[n+4>>2]=t,t=e+40|0,n=a[t+4>>2],o=f+68|0,a[o>>2]=a[t>>2],a[o+4>>2]=n,a[f+8>>2]=A,a[f+4>>2]=22836,a[f>>2]=22812,A=a[i+4>>2],a[f+12>>2]=a[i>>2],a[f+16>>2]=A,A=a[e+4>>2],a[f+28>>2]=a[e>>2],a[f+32>>2]=A,A=e+56|0,i=a[A+4>>2],t=f+84|0,a[t>>2]=a[A>>2],a[t+4>>2]=i,A=a[e+52>>2],i=f+76|0,a[i>>2]=a[e+48>>2],a[i+4>>2]=A,A=a[r+96>>2],Qt[a[a[A>>2]+8>>2]](A,4|f,f+112|0,f+128|0))}Y=f+144|0},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f,t,n,o,c,b,l,u=0,s=0,k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0);f=Y-256|0,Y=f,u=f+104|0,a[u>>2]=0,a[u+4>>2]=0,u=f+112|0,a[u>>2]=0,a[u+4>>2]=0,u=f+124|0,a[u>>2]=0,a[u+4>>2]=0,a[f+120>>2]=1065353216,u=f+132|0,a[u>>2]=0,a[u+4>>2]=0,u=f+140|0,a[u>>2]=1065353216,a[u+4>>2]=0,n=e+8|0,u=n,o=a[u+4>>2],c=f+76|0,s=c,b=a[u>>2],a[s>>2]=b,a[s+4>>2]=o,u=r+8|0,s=a[u+4>>2],t=f+92|0,a[t>>2]=a[u>>2],a[t+4>>2]=s,a[f+32>>2]=22628,a[f+248>>2]=i,a[f+100>>2]=1065353216,l=a[e+4>>2],s=a[e>>2],a[f+68>>2]=s,a[f+72>>2]=l,i=a[r+4>>2],a[f+84>>2]=a[r>>2],a[f+88>>2]=i,a[f+244>>2]=A,i=f+156|0,a[i>>2]=b,a[i+4>>2]=o,i=f+148|0,a[i>>2]=s,a[i+4>>2]=l,i=f+168|0,a[i>>2]=0,a[i+4>>2]=0,i=f+176|0,a[i>>2]=0,a[i+4>>2]=0,i=f+188|0,a[i>>2]=0,a[i+4>>2]=0,a[f+184>>2]=1065353216,i=f+196|0,a[i>>2]=0,a[i+4>>2]=0,i=f+204|0,a[i>>2]=1065353216,a[i+4>>2]=0,i=a[r+4>>2],s=f+212|0,a[s>>2]=a[r>>2],a[s+4>>2]=i,i=a[u+4>>2],s=f+220|0,a[s>>2]=a[u>>2],a[s+4>>2]=i,a[f+164>>2]=1065353216,d=_(C[r>>2]-C[e>>2]),v=_(C[r+4>>2]-C[e+4>>2]),k=_(C[u>>2]-C[n>>2]),g=_(_(1)/_(y(_(_(_(d*d)+_(v*v))+_(k*k))))),B=_(k*g),m=B==_(0)?_(0xde0b6b000000000):_(_(1)/B),C[f+44>>2]=m,v=_(v*g),k=v==_(0)?_(0xde0b6b000000000):_(_(1)/v),C[f+40>>2]=k,a[f+60>>2]=m<_(0),a[f+56>>2]=k<_(0),k=_(d*g),C[f+64>>2]=_(_(k*_(C[f+84>>2]-C[f+68>>2]))+_(v*_(C[f+88>>2]-C[f+72>>2])))+_(B*_(C[t>>2]-C[c>>2])),k=k==_(0)?_(0xde0b6b000000000):_(_(1)/k),C[f+36>>2]=k,a[f+52>>2]=k<_(0),i=a[A+68>>2],A=f+24|0,a[A>>2]=0,a[A+4>>2]=0,a[f+16>>2]=0,a[f+20>>2]=0,A=f+8|0,a[A>>2]=0,a[A+4>>2]=0,a[f>>2]=0,a[f+4>>2]=0,Qt[a[a[i>>2]+24>>2]](i,e,r,f+32|0,f+16|0,f),Y=f+256|0},kf,df,function(A){A|=0;var e,r,i=0,f=0,t=0,n=0,o=0,c=0;e=Y-16|0,Y=e,Lr(e+8|0,20873),Qt[a[a[A>>2]+8>>2]](A),Qt[a[a[A>>2]+12>>2]](A),r=a[A+24>>2],Lr(e,20907),r&&(i=a[A+68>>2],t=r,n=0|Qt[a[a[i>>2]+36>>2]](i),o=A+28|0,c=a[A+24>>2],f=a[a[r>>2]+32>>2],Qt[f](0|t,0|n,0|o,0|c)),qr(),qr(),Y=e+16|0},function(A,e){A|=0,e|=0,Qt[a[a[e>>2]+32>>2]](e),Rf(A,e),Qt[a[a[e>>2]+36>>2]](e)},ve,hf,ve,hf,ve,function(A,e){A|=0,e|=0;var r,i,f,t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0),w=_(0),D=_(0),E=_(0);r=Y-128|0,Y=r,i=a[e+36>>2],e=a[a[A+8>>2]+28>>2]+B(i,80)|0,f=a[e+64>>2],v=C[e+32>>2],d=C[e>>2],g=C[e+16>>2],m=C[e+56>>2],R=C[e+52>>2],Q=C[e+48>>2],h=C[e+36>>2],G=C[e+20>>2],y=C[e+4>>2],p=C[e+40>>2],F=C[e+24>>2],W=C[e+8>>2],e=a[A+12>>2],w=C[e+52>>2],D=C[e+56>>2],t=C[e+24>>2],n=C[e+20>>2],o=C[e+40>>2],c=C[e+36>>2],E=C[e+48>>2],b=C[e+8>>2],l=C[e>>2],u=C[e+4>>2],s=C[e+16>>2],k=C[e+32>>2],a[r+124>>2]=0,a[r+108>>2]=0,a[r+92>>2]=0,C[r+104>>2]=_(_(W*k)+_(F*c))+_(p*o),C[r+100>>2]=_(_(y*k)+_(G*c))+_(h*o),C[r+88>>2]=_(_(W*s)+_(F*n))+_(p*t),C[r+84>>2]=_(_(y*s)+_(G*n))+_(h*t),C[r+120>>2]=D+_(_(_(k*Q)+_(c*R))+_(o*m)),C[r+116>>2]=w+_(_(_(s*Q)+_(n*R))+_(t*m)),a[r+76>>2]=0,C[r+72>>2]=_(_(l*W)+_(u*F))+_(b*p),C[r+68>>2]=_(_(l*y)+_(u*G))+_(b*h),C[r+64>>2]=_(_(d*l)+_(g*u))+_(v*b),C[r+112>>2]=E+_(_(_(l*Q)+_(u*R))+_(b*m)),C[r+96>>2]=_(_(d*k)+_(g*c))+_(v*o),C[r+80>>2]=_(_(d*s)+_(g*n))+_(v*t),a[r+60>>2]=i,a[r+56>>2]=-1,a[r+44>>2]=f,a[r+40>>2]=0,a[r+48>>2]=a[A+4>>2],a[r+52>>2]=r- -64,a[r+12>>2]=1065353216,a[r+24>>2]=-1,a[r+28>>2]=0,a[r+16>>2]=0,a[r+20>>2]=1,a[r+36>>2]=i,a[r+8>>2]=21552,e=a[A+24>>2],a[r+32>>2]=e,a[r+12>>2]=a[e+4>>2],a[r+28>>2]=a[e+20>>2],Cf(a[A+16>>2],a[A+20>>2],r+40|0,r+8|0),Y=r+128|0},sA,ve,function(A,e){return A|=0,e|=0,A=a[A+24>>2],0|Qt[a[a[A>>2]+8>>2]](A,e)},function(A,e,r){A|=0,e|=0,r|=0;var i,f,t=_(0);return i=Y-16|0,Y=i,a[i+8>>2]=-1,a[i+12>>2]=a[A+28>>2],a[e+4>>2]||(a[e+4>>2]=i+8),f=a[A+24>>2],t=_(Qt[a[a[f>>2]+12>>2]](f,e,r)),a[A+4>>2]=a[a[A+24>>2]+4>>2],Y=i+16|0,_(t)},ve,Gf,ve,Gf,ve,function(A,e){A|=0,e|=0;var r,i,f,t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=_(0);r=Y-112|0,Y=r,i=a[e+36>>2],e=a[a[A+24>>2]+28>>2]+B(i,80)|0,f=a[e+64>>2],v=C[e+32>>2],d=C[e>>2],g=C[e+16>>2],m=C[e+56>>2],R=C[e+52>>2],Q=C[e+48>>2],h=C[e+36>>2],G=C[e+20>>2],y=C[e+4>>2],t=C[e+40>>2],n=C[e+24>>2],o=C[e+8>>2],a[r+108>>2]=0,a[r+92>>2]=0,a[r+76>>2]=0,e=a[A+28>>2],c=C[e+32>>2],b=C[e+36>>2],l=C[e+40>>2],C[r+88>>2]=_(_(o*c)+_(n*b))+_(t*l),C[r+84>>2]=_(_(y*c)+_(G*b))+_(h*l),u=C[e+16>>2],s=C[e+20>>2],k=C[e+24>>2],C[r+72>>2]=_(_(o*u)+_(n*s))+_(t*k),C[r+68>>2]=_(_(y*u)+_(G*s))+_(h*k),C[r+104>>2]=_(_(_(Q*c)+_(R*b))+_(m*l))+C[e+56>>2],C[r+100>>2]=_(_(_(Q*u)+_(R*s))+_(m*k))+C[e+52>>2],a[r+60>>2]=0,p=o,o=C[e>>2],F=n,n=C[e+4>>2],W=t,t=C[e+8>>2],C[r+56>>2]=_(_(p*o)+_(F*n))+_(W*t),C[r+52>>2]=_(_(y*o)+_(G*n))+_(h*t),C[r+48>>2]=_(_(d*o)+_(g*n))+_(v*t),C[r+96>>2]=_(_(_(Q*o)+_(R*n))+_(m*t))+C[e+48>>2],C[r+80>>2]=_(_(d*c)+_(g*b))+_(v*l),C[r+64>>2]=_(_(d*u)+_(g*s))+_(v*k),a[r+28>>2]=1065353216,a[r+32>>2]=1,a[r+36>>2]=-1,a[r+44>>2]=i,a[r+24>>2]=22368,e=a[A+32>>2],a[r+40>>2]=e,a[r+28>>2]=a[e+4>>2],a[r+20>>2]=i,a[r+16>>2]=-1,a[r+4>>2]=f,e=a[A+4>>2],a[r>>2]=e,a[r+8>>2]=a[e+8>>2],a[r+12>>2]=r+48,Bf(a[A+8>>2],a[A+12>>2],a[A+16>>2],r,r+24|0,C[A+20>>2]),Y=r+112|0},sA,ve,function(A,e){return A|=0,e|=0,A=a[A+16>>2],0|Qt[a[a[A>>2]+8>>2]](A,e)},function(A,e,r){A|=0,e|=0,r|=0;var i,f,t=_(0);return i=Y-16|0,Y=i,a[i+8>>2]=-1,a[i+12>>2]=a[A+20>>2],a[e+4>>2]||(a[e+4>>2]=i+8),f=a[A+16>>2],t=_(Qt[a[a[f>>2]+12>>2]](f,e,r)),a[A+4>>2]=a[a[A+16>>2]+4>>2],Y=i+16|0,_(t)},sA,ve,function(A,e){A|=0,e|=0;var r,i=0,f=0,t=0;return r=Y-32|0,Y=r,i=a[A+216>>2],C[i+4>>2]!=_(0)&&(f=1,e=a[e>>2],Qt[a[a[i>>2]+8>>2]](i,a[e+188>>2])&&(i=a[A+216>>2],t=a[e+192>>2],a[r+24>>2]=-1,a[r+28>>2]=-1,a[r+20>>2]=e+4,a[r+16>>2]=e,a[r+12>>2]=t,a[r+8>>2]=0,Cf(A+68|0,A+132|0,r+8|0,i))),Y=r+32|0,0|f},ve,function(A,e){A|=0,e|=0;var r,i=0,f=0,t=_(0),n=0,o=0;return r=Y-32|0,Y=r,i=a[A+184>>2],C[i+4>>2]!=_(0)&&(f=1,e=a[e>>2],Qt[a[a[i>>2]+8>>2]](i,a[e+188>>2])&&(t=C[A+188>>2],i=a[A+184>>2],n=a[A+192>>2],o=a[e+192>>2],a[r+24>>2]=-1,a[r+28>>2]=-1,a[r+20>>2]=e+4,a[r+16>>2]=e,a[r+12>>2]=o,a[r+8>>2]=0,Bf(n,A+36|0,A+100|0,r+8|0,i,t))),Y=r+32|0,0|f},sA,ve,function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),p=_(0),F=_(0);r=Y-96|0,Y=r,a[r+92>>2]=0,f=C[e>>2],b=C[A+60>>2],n=C[e+4>>2],d=C[A- -64>>2],o=C[e+8>>2],g=C[A+68>>2],B=C[A+84>>2],s=_(_(_(_(f*b)+_(n*d))+_(o*g))+B),C[r+88>>2]=s,c=C[A+44>>2],m=C[A+48>>2],R=C[A+52>>2],Q=C[A+80>>2],t=_(_(_(_(f*c)+_(n*m))+_(o*R))+Q),C[r+84>>2]=t,l=f,f=C[A+28>>2],u=n,n=C[A+32>>2],h=o,o=C[A+36>>2],k=C[A+76>>2],F=_(_(_(_(l*f)+_(u*n))+_(h*o))+k),C[r+80>>2]=F,a[r+76>>2]=0,a[r+60>>2]=0,v=C[e+16>>2],l=C[e+20>>2],u=C[e+24>>2],G=_(k+_(_(_(f*v)+_(n*l))+_(o*u))),C[r+64>>2]=G,p=_(Q+_(_(_(c*v)+_(m*l))+_(R*u))),C[r+68>>2]=p,v=_(B+_(_(_(b*v)+_(d*l))+_(g*u))),C[r+72>>2]=v,l=f,f=C[e+32>>2],u=n,n=C[e+36>>2],h=o,o=C[e+40>>2],k=_(k+_(_(_(l*f)+_(u*n))+_(h*o))),C[r+48>>2]=k,c=_(Q+_(_(_(c*f)+_(m*n))+_(R*o))),C[r+52>>2]=c,f=_(B+_(_(_(b*f)+_(d*n))+_(g*o))),C[r+56>>2]=f,a[r+44>>2]=0,n=_(_(_(s+v)+f)*_(.3333333432674408)),C[r+40>>2]=n,d=_(_(_(t+p)+c)*_(.3333333432674408)),C[r+36>>2]=d,o=_(_(_(F+G)+k)*_(.3333333432674408)),C[r+32>>2]=o,e=a[A+8>>2],16384&Qt[a[a[e>>2]+56>>2]](e)&&(b=C[r+80>>2],a[r+24>>2]=0,a[r+28>>2]=0,a[r+16>>2]=1065353216,a[r+20>>2]=1065353216,e=a[A+8>>2],a[r+12>>2]=0,g=_(G-b),B=_(c-t),c=_(p-t),b=_(k-b),t=_(_(g*B)-_(c*b)),l=t,u=_(t*t),t=_(f-s),f=_(v-s),s=_(_(c*t)-_(f*B)),t=_(_(f*b)-_(g*t)),f=_(_(1)/_(y(_(u+_(_(s*s)+_(t*t)))))),C[r+8>>2]=_(l*f)+n,C[r+4>>2]=d+_(t*f),C[r>>2]=o+_(s*f),Qt[a[a[e>>2]+16>>2]](e,r+32|0,r,r+16|0)),i=a[A+8>>2],e=A+12|0,Qt[a[a[i>>2]+16>>2]](i,r+80|0,r- -64|0,e),i=a[A+8>>2],Qt[a[a[i>>2]+16>>2]](i,r- -64|0,r+48|0,e),A=a[A+8>>2],Qt[a[a[A>>2]+16>>2]](A,r+48|0,r+80|0,e),Y=r+96|0},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0,Qt[a[a[A>>2]+8>>2]](A,e,r,i)},function(A){return A|=0,A+-4|0},function(A){A|=0,$(A+-4|0)},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0,A=A+-4|0,Qt[a[a[A>>2]+8>>2]](A,e,r,i)},function(A){A|=0;var e=0;return a[A>>2]=22908,e=a[A+56>>2],e&&(o[A+60|0]&&CA(e),a[A+56>>2]=0),a[A+56>>2]=0,a[A+48>>2]=0,a[A+52>>2]=0,f[A+60|0]=1,e=a[A+36>>2],e&&(o[A+40|0]&&CA(e),a[A+36>>2]=0),a[A+36>>2]=0,a[A+28>>2]=0,a[A+32>>2]=0,f[A+40|0]=1,yf(A+4|0),0|A},function(A){A|=0;var e=0;a[A>>2]=22908,e=a[A+56>>2],e&&(o[A+60|0]&&CA(e),a[A+56>>2]=0),a[A+56>>2]=0,a[A+48>>2]=0,a[A+52>>2]=0,f[A+60|0]=1,e=a[A+36>>2],e&&(o[A+40|0]&&CA(e),a[A+36>>2]=0),a[A+36>>2]=0,a[A+28>>2]=0,a[A+32>>2]=0,f[A+40|0]=1,yf(A+4|0),$(A)},function(A,e,r){A|=0,e|=0,r|=0;var i,t=0,n=0,c=0;if(i=a[e+8>>2],(0|i)<1)r=0;else for(n=a[e+16>>2],r=0;t=a[n>>2],3&o[t+204|0]||(a[t+208>>2]=r,r=r+1|0),a[t+268>>2]=1065353216,a[t+212>>2]=-1,n=n+4|0,c=c+1|0,(0|c)<(0|i););!function(A,e){var r=0,i=0,t=0,n=0,c=0,b=0,l=0;if(t=a[A+4>>2],(0|t)<(0|e)){if(a[A+8>>2]<(0|e)){if(e?(n=dA(e<<3),r=a[A+4>>2]):r=t,(0|r)>=1)for(;c=a[A+12>>2]+i|0,l=a[c+4>>2],b=i+n|0,a[b>>2]=a[c>>2],a[b+4>>2]=l,i=i+8|0,r=r+-1|0,r;);r=a[A+12>>2],r&&(o[A+16|0]&&CA(r),a[A+12>>2]=0),a[A+12>>2]=n,f[A+16|0]=1,a[A+8>>2]=e}for(i=t<<3,r=e-t|0;t=a[A+12>>2]+i|0,a[t>>2]=0,a[t+4>>2]=0,i=i+8|0,r=r+-1|0,r;);}if(a[A+4>>2]=e,(0|e)>=1)for(i=a[A+12>>2],r=0;a[i>>2]=r,a[i+4>>2]=1,i=i+8|0,r=r+1|0,(0|r)!=(0|e););}(A+4|0,r),function(A,e){var r,i=0,f=0,t=0,n=0,c=0,b=0;if(e=a[e+68>>2],e=0|Qt[a[a[e>>2]+36>>2]](e),r=0|Qt[a[a[e>>2]+36>>2]](e),r&&(b=0|Qt[a[a[e>>2]+20>>2]](e),!((0|r)<1)))for(;;){if(e=(c<<4)+b|0,i=a[a[e>>2]>>2],i&&(e=a[a[e+4>>2]>>2],!(!e|7&a[i+204>>2]|7&o[e+204|0]))){if(e=a[e+208>>2],t=a[A+16>>2],n=a[i+208>>2],f=t+(n<<3)|0,i=a[f>>2],(0|i)!=(0|n))for(;i=t+(i<<3)|0,a[f>>2]=a[i>>2],n=a[i>>2],f=t+(n<<3)|0,i=a[f>>2],(0|i)!=(0|n););if(f=t+(e<<3)|0,i=a[f>>2],(0|e)!=(0|i))for(;e=t+(i<<3)|0,a[f>>2]=a[e>>2],e=a[e>>2],f=t+(e<<3)|0,i=a[f>>2],(0|e)!=(0|i););(0|e)!=(0|n)&&(i=t+(n<<3)|0,a[i>>2]=e,e=t+(e<<3)|0,a[e+4>>2]=a[e+4>>2]+a[i+4>>2])}if(c=c+1|0,(0|c)==(0|r))break}}(A,e)},function(A,e){A|=0,e|=0;var r,i=0,f=0,t=0,n=0,c=0,b=0,l=0,u=0;if(r=a[e+8>>2],(0|r)>=1)for(u=a[e+16>>2];;){if(i=a[(f<<2)+u>>2],3&o[i+204|0])a[i+208>>2]=-1,a[i+212>>2]=-2;else{if(e=b,l=e<<3,t=a[A+16>>2],n=l+t|0,c=a[n>>2],(0|e)!=(0|c))for(;e=t+(c<<3)|0,a[n>>2]=a[e>>2],e=a[e>>2],n=t+(e<<3)|0,c=a[n>>2],(0|e)!=(0|c););a[i+208>>2]=e,a[i+212>>2]=-1,a[4+(t+l|0)>>2]=f,b=b+1|0}if(f=f+1|0,!((0|f)<(0|r)))break}},Ef,kA,qe,function(A,e,r,i,f){f=_(f)},Kr,ye,Df,If,function(A){A|=0,CA(If(A))},function(A){A|=0;var e,r=0,i=0,f=0,t=0,n=0,o=0;if(e=Y-16|0,Y=e,Lr(e+8|0,23348),mf(A),Qt[a[a[A>>2]+20>>2]](A)&&(r=0|Qt[a[a[A>>2]+20>>2]](A),6144&Qt[a[a[r>>2]+56>>2]](r)&&(r=0|Qt[a[a[A>>2]+104>>2]](A),!((0|r)<1))))for(;r=r+-1|0,n=A,o=0|Qt[a[a[A>>2]+108>>2]](A,r),t=a[a[A>>2]+172>>2],Qt[t](0|n,0|o),(0|r)>0;);if(Qt[a[a[A>>2]+20>>2]](A)&&(r=0|Qt[a[a[A>>2]+20>>2]](A),16387&Qt[a[a[r>>2]+56>>2]](r)&&Qt[a[a[A>>2]+20>>2]](A)&&(r=0|Qt[a[a[A>>2]+20>>2]](A),!(!Qt[a[a[r>>2]+56>>2]](r)|a[A+296>>2]<1))))for(r=0;i=a[a[A+304>>2]+r>>2],Qt[a[a[i>>2]+12>>2]](i,a[A+72>>2]),r=r+4|0,f=f+1|0,(0|f)>2];);Qt[a[a[A>>2]+20>>2]](A)&&(A=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[A>>2]+104>>2]](A)),qr(),Y=e+16|0},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0,kf(A,e,r,i)},function(A,e){A|=0,e|=0,!e|!(2&a[e+252>>2])?df(A,e):Qt[a[a[A>>2]+92>>2]](A,e)},function(A,e){A|=0,e|=0;var r,i,f=0,t=0;Qt[a[a[e>>2]+32>>2]](e),i=0|Qt[a[a[e>>2]+16>>2]](e,104,1),r=X(a[i+8>>2],0,104),a[r+88>>2]=a[A+264>>2],a[r+92>>2]=a[A+268>>2],a[r+96>>2]=a[A+272>>2],a[r+100>>2]=a[A+276>>2],f=A+124|0,t=a[f+4>>2],a[r+28>>2]=a[f>>2],a[r+32>>2]=t,f=A+104|0,t=a[f+4>>2],a[r+12>>2]=a[f>>2],a[r+16>>2]=t,f=A+116|0,t=a[f+4>>2],a[r+20>>2]=a[f>>2],a[r+24>>2]=t,f=A+96|0,t=a[f+4>>2],a[r+4>>2]=a[f>>2],a[r+8>>2]=t,a[r>>2]=a[A+92>>2],a[r+36>>2]=a[A+132>>2],a[r+40>>2]=a[A+148>>2],a[r+44>>2]=a[A+152>>2],a[r+48>>2]=a[A+156>>2],a[r+52>>2]=a[A+160>>2],a[r+56>>2]=a[A+176>>2],a[r+60>>2]=a[A+180>>2],a[r+64>>2]=a[A+112>>2],a[r+68>>2]=a[A+164>>2],a[r+72>>2]=a[A+168>>2],a[r+76>>2]=a[A+172>>2],f=a[A+144>>2],a[r+84>>2]=0,a[r+80>>2]=f,Qt[a[a[e>>2]+20>>2]](e,i,23665,1145853764,r),Rf(A,e),function(A,e){var r=0,i=0,f=0,t=0,n=0,c=0,b=0,l=0,u=0,s=0;if(i=a[A+8>>2],(0|i)>=1)for(;r=a[a[A+16>>2]+f>>2],2&o[r+252|0]&&(c=e,b=0|Qt[a[a[r>>2]+16>>2]](r),l=1,n=a[a[e>>2]+16>>2],i=0|Qt[n](0|c,0|b,0|l),l=e,b=i,c=0|Qt[a[a[r>>2]+20>>2]](r,a[i+8>>2],e),u=1497645650,s=r,n=a[a[e>>2]+20>>2],Qt[n](0|l,0|b,0|c,0|u,0|s),i=a[A+8>>2]),f=f+4|0,t=t+1|0,(0|t)<(0|i););if(a[A+228>>2]>=1)for(f=0,t=0;r=a[a[A+236>>2]+f>>2],s=e,u=0|Qt[a[a[r>>2]+36>>2]](r),c=1,n=a[a[e>>2]+16>>2],i=0|Qt[n](0|s,0|u,0|c),c=e,u=i,s=0|Qt[a[a[r>>2]+40>>2]](r,a[i+8>>2],e),b=1397641027,l=r,n=a[a[e>>2]+20>>2],Qt[n](0|c,0|u,0|s,0|b,0|l),f=f+4|0,t=t+1|0,(0|t)>2];);}(A,e),Qt[a[a[e>>2]+36>>2]](e)},function(A,e,r,i){A|=0,e=_(e),r|=0,i=_(i);var t=0,n=0,c=_(0),b=0,l=0;A:if(r){if(C[A+284>>2]=i,e=_(C[A+280>>2]+e),C[A+280>>2]=e,!(e>=i))break A;t=A,c=e,e=_(e/i),n=_(m(e))<_(2147483648)?~~e:-2147483648,C[t+280>>2]=c-_(_(0|n)*i)}else a[A+284>>2]=0,C[A+280>>2]=o[A+316|0]?_(0):e,i=e,n=_(m(e))<_(1.1920928955078125e-7)^1,r=n;Qt[a[a[A>>2]+20>>2]](A)&&(t=0|Qt[a[a[A>>2]+20>>2]](A),b=2792,l=Qt[a[a[t>>2]+56>>2]](t)>>>4&1,f[0|b]=l);A:if(n){if(t=(0|n)>(0|r)?r:n,Qt[a[a[A>>2]+168>>2]](A,_(i*_(0|t))),Qt[a[a[A>>2]+176>>2]](A),(0|t)<1)break A;for(r=0;Qt[a[a[A>>2]+160>>2]](A,i),Qt[a[a[A>>2]+80>>2]](A),r=r+1|0,(0|r)<(0|t););}else Qt[a[a[A>>2]+80>>2]](A);return Qt[a[a[A>>2]+120>>2]](A),0|n},function(A,e,r){A|=0,e|=0,r|=0;var i=0,t=0,n=0,c=0,b=0;if(i=a[A+228>>2],(0|i)==a[A+232>>2]&&(n=i?i<<1:1,!((0|i)>=(0|n)))){if(n&&(b=dA(n<<2),i=a[A+228>>2]),(0|i)>=1)for(t=i;a[c+b>>2]=a[a[A+236>>2]+c>>2],c=c+4|0,t=t+-1|0,t;);t=a[A+236>>2],t&&(o[A+240|0]&&(CA(t),i=a[A+228>>2]),a[A+236>>2]=0),a[A+236>>2]=b,a[A+232>>2]=n,f[A+240|0]=1}a[A+228>>2]=i+1,a[a[A+236>>2]+(i<<2)>>2]=e,r&&(Pi(a[e+28>>2],e),Pi(a[e+32>>2],e))},function(A,e){A|=0,e|=0;var r=0,i=0,f=0,t=0;r=a[A+228>>2];A:if(!((0|r)<1)){for(t=a[A+236>>2],i=t;;){if((0|e)!=a[i>>2]){if(i=i+4|0,f=f+1|0,(0|r)!=(0|f))continue;break A}break}(0|r)<=(0|f)||(f=i,i=r+-1|0,r=i<<2,a[f>>2]=a[r+t>>2],a[A+228>>2]=i,a[r+a[A+236>>2]>>2]=e)}Ki(a[e+28>>2],e),Ki(a[e+32>>2],e)},function(A,e){A|=0,e|=0;var r=0,i=0,t=0,n=0,c=0;if(r=a[A+296>>2],(0|r)==a[A+300>>2]&&(t=r?r<<1:1,!((0|r)>=(0|t)))){if(t&&(c=dA(t<<2),r=a[A+296>>2]),(0|r)>=1)for(i=r;a[n+c>>2]=a[a[A+304>>2]+n>>2],n=n+4|0,i=i+-1|0,i;);i=a[A+304>>2],i&&(o[A+308|0]&&(CA(i),r=a[A+296>>2]),a[A+304>>2]=0),a[A+304>>2]=c,a[A+300>>2]=t,f[A+308|0]=1}a[A+296>>2]=r+1,a[a[A+304>>2]+(r<<2)>>2]=e},function(A,e){A|=0,e|=0;var r=0,i=0,f=0,t=0;r=a[A+296>>2];A:if(!((0|r)<1)){for(t=a[A+304>>2],i=t;;){if((0|e)!=a[i>>2]){if(i=i+4|0,f=f+1|0,(0|r)!=(0|f))continue;break A}break}(0|r)<=(0|f)||(f=i,i=r+-1|0,r=i<<2,a[f>>2]=a[r+t>>2],a[A+296>>2]=i,a[r+a[A+304>>2]>>2]=e)}},function(A,e){A|=0,e|=0;var r=0,i=0,t=0,n=0,o=0;if(r=a[e+4>>2],a[A+264>>2]=a[e>>2],a[A+268>>2]=r,i=e+8|0,t=a[i+4>>2],r=A+272|0,a[r>>2]=a[i>>2],a[r+4>>2]=t,i=a[A+248>>2],(0|i)>=1)for(r=0,t=0;;){A:{e:if(n=a[a[A+256>>2]+r>>2],o=a[n+220>>2]+-2|0,!(o>>>0>3))switch(o-1|0){case 0:case 1:break e;default:break A}1&f[n+564|0]||(Si(n,e),i=a[A+248>>2])}if(r=r+4|0,t=t+1|0,!((0|t)<(0|i)))break}},function(A,e){A|=0,e|=0;var r=0;r=a[e+268>>2],a[A>>2]=a[e+264>>2],a[A+4>>2]=r,e=e+272|0,r=a[e+4>>2],A=A+8|0,a[A>>2]=a[e>>2],a[A+4>>2]=r},function(A){A|=0;var e,r=0,i=_(0),f=0,t=0,n=0,c=0,b=0;e=Y+-64|0,Y=e;A:if(o[A+290|0]){if(f=a[A+8>>2],(0|f)<1)break A;for(;r=a[a[A+16>>2]+c>>2],!r|!(2&a[r+252>>2])|!a[r+540>>2]|3&o[r+204|0]||(f=r+68|0,n=r+132|0,b=r+148|0,i=o[A+316|0]&&(i=C[A+284>>2],i!=_(0))?_(C[A+280>>2]-i):_(C[A+280>>2]*C[r+268>>2]),xi(f,n,b,i,e),r=a[r+540>>2],Qt[a[a[r>>2]+12>>2]](r,e),f=a[A+8>>2]),c=c+4|0,t=t+1|0,(0|t)<(0|f););}else if(t=a[A+248>>2],!((0|t)<1))for(;;){e:{r:if(r=a[a[A+256>>2]+f>>2],n=a[r+220>>2]+-2|0,!(n>>>0>3))switch(n-1|0){case 0:case 1:break r;default:break e}!a[r+540>>2]|3&o[r+204|0]||(t=r+68|0,n=r+132|0,b=r+148|0,i=o[A+316|0]&&(i=C[A+284>>2],i!=_(0))?_(C[A+280>>2]-i):_(C[A+280>>2]*C[r+268>>2]),xi(t,n,b,i,e),r=a[r+540>>2],Qt[a[a[r>>2]+12>>2]](r,e),t=a[A+248>>2])}if(f=f+4|0,c=c+1|0,!((0|c)<(0|t)))break}Y=e- -64|0},function(A,e){A|=0,e|=0;var r=0,i=0,t=0,n=0,c=0;if(3&o[e+204|0]|1&f[e+564|0]||Si(e,A+264|0),a[e+192>>2]){if(1&f[e+204|0])Ye(e,2);else{if(r=a[A+248>>2],(0|r)==a[A+252>>2]&&(t=r?r<<1:1,!((0|r)>=(0|t)))){if(t&&(c=dA(t<<2),r=a[A+248>>2]),(0|r)>=1)for(i=r;a[n+c>>2]=a[a[A+256>>2]+n>>2],n=n+4|0,i=i+-1|0,i;);i=a[A+256>>2],i&&(o[A+260|0]&&(CA(i),r=a[A+248>>2]),a[A+256>>2]=0),a[A+256>>2]=c,a[A+252>>2]=t,f[A+260|0]=1}a[A+248>>2]=r+1,a[a[A+256>>2]+(r<<2)>>2]=e}r=e,e=3&a[e+204>>2],Qt[a[a[A>>2]+36>>2]](A,r,e?2:1,e?-3:-1)}},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var t=0,n=0,c=0,b=0,l=0;if(3&o[e+204|0]|1&f[e+564|0]||Si(e,A+264|0),a[e+192>>2]){if(1&f[e+204|0])Ye(e,2);else{if(t=a[A+248>>2],(0|t)==a[A+252>>2]&&(c=t?t<<1:1,!((0|t)>=(0|c)))){if(c&&(l=dA(c<<2),t=a[A+248>>2]),(0|t)>=1)for(n=t;a[b+l>>2]=a[a[A+256>>2]+b>>2],b=b+4|0,n=n+-1|0,n;);n=a[A+256>>2],n&&(o[A+260|0]&&(CA(n),t=a[A+248>>2]),a[A+256>>2]=0),a[A+256>>2]=l,a[A+252>>2]=c,f[A+260|0]=1}a[A+248>>2]=t+1,a[a[A+256>>2]+(t<<2)>>2]=e}Qt[a[a[A>>2]+36>>2]](A,e,r,i)}},function(A,e){A|=0,e|=0;var r=0,i=0,f=0,t=0;r=a[A+248>>2];A:if(!((0|r)<1)){for(t=a[A+256>>2],i=t;;){if((0|e)!=a[i>>2]){if(i=i+4|0,f=f+1|0,(0|r)!=(0|f))continue;break A}break}(0|r)<=(0|f)||(f=i,i=r+-1|0,r=i<<2,a[f>>2]=a[r+t>>2],a[A+248>>2]=i,a[r+a[A+256>>2]>>2]=e)}df(A,e)},function(A,e){A|=0,e|=0,o[A+289|0]&&CA(a[A+216>>2]),a[A+216>>2]=e,f[A+289|0]=0,a[a[A+212>>2]+8>>2]=e},function(A){return A|=0,a[A+216>>2]},function(A){return A|=0,a[A+228>>2]},Mf,Mf,pe,function(A){A|=0;var e=0,r=0,i=0,f=0;if(a[A+248>>2]>=1)for(;r=a[a[A+256>>2]+i>>2],e=r,a[e+472>>2]=0,a[e+476>>2]=0,e=e+496|0,a[e>>2]=0,a[e+4>>2]=0,e=r+488|0,a[e>>2]=0,a[e+4>>2]=0,r=r+480|0,a[r>>2]=0,a[r+4>>2]=0,i=i+4|0,f=f+1|0,(0|f)>2];);},Jf,xf,Jf,xf,function(A,e){A|=0,e=_(e);var r,i=0,f=0,t=0,n=0;if(r=Y-16|0,Y=r,Lr(r+8|0,23639),f=a[A+248>>2],(0|f)>=1)for(;i=a[a[A+256>>2]+t>>2],3&o[i+204|0]||(Xi(i,e),Ji(i,e,i+68|0),f=a[A+248>>2]),t=t+4|0,n=n+1|0,(0|n)<(0|f););qr(),Y=r+16|0},function(A,e){A|=0,e=_(e);var r,i=0,f=0,t=0,n=_(0),c=0,b=0,l=_(0),u=_(0),s=0,k=_(0);if(r=Y-80|0,Y=r,Lr(r+72|0,23581),i=a[A+248>>2],(0|i)>=1&&function(A,e,r,i){var f,t=0,n=0,c=0,b=_(0),l=0,u=0,s=0,k=0,v=0,d=0,g=0,B=0,m=0,R=0,Q=0,h=0,G=0,y=0,p=_(0),F=0,W=0,w=_(0),D=0,E=0;if(f=Y-304|0,Y=f,(0|r)>=1)for(Q=f+56|0,v=f+40|0,h=f+272|0,d=f+24|0,W=f+256|0,m=f+100|0,G=f+160|0,y=f+144|0,g=f+288|0;;){n=a[e>>2],a[n+268>>2]=1065353216;A:{e:if(t=a[n+220>>2]+-2|0,!(t>>>0>3))switch(t-1|0){case 0:case 1:break e;default:break A}3&o[n+204|0]||(Ji(n,i,f+240|0),o[A+44|0]&&(b=C[n+276>>2],b=_(b*b),b!=_(0)&&(w=b,t=n+52|0,b=_(C[f+288>>2]-C[t>>2]),p=_(b*b),b=_(C[f+292>>2]-C[n+56>>2]),p=_(p+_(b*b)),b=_(C[f+296>>2]-C[n+60>>2]),w<_(p+_(b*b))&&(Lr(f+232|0,23561),a[a[n+192>>2]+4>>2]<=19&&(R=0,a[702]=a[702]+1,c=a[A+68>>2],l=0|Qt[a[a[c>>2]+36>>2]](c),c=a[t+4>>2],a[y>>2]=a[t>>2],a[y+4>>2]=c,t=t+8|0,c=a[t+4>>2],u=y+8|0,a[u>>2]=a[t>>2],a[u+4>>2]=c,t=a[g+4>>2],a[G>>2]=a[g>>2],a[G+4>>2]=t,c=g+8|0,t=c,u=a[t+4>>2],s=G+8|0,a[s>>2]=a[t>>2],a[s+4>>2]=u,a[f+140>>2]=-1,a[f+132>>2]=1065353216,a[f+136>>2]=1,a[f+128>>2]=23884,a[f+208>>2]=0,a[f+216>>2]=0,a[f+224>>2]=a[A+24>>2],a[f+220>>2]=l,a[f+212>>2]=n,t=a[n+272>>2],DA(f+72|0),a[m>>2]=0,a[m+4>>2]=0,l=m+8|0,a[l>>2]=0,a[l+4>>2]=0,a[m+16>>2]=0,a[f+96>>2]=1065353216,a[f+88>>2]=1065353216,a[f+92>>2]=1065353216,a[f+76>>2]=8,a[f+72>>2]=9852,a[f+124>>2]=0,a[f+120>>2]=t,a[f+104>>2]=t,a[f+216>>2]=a[A+56>>2],t=a[n+188>>2],l=a[t+8>>2],a[f+136>>2]=a[t+4>>2],a[f+140>>2]=l,t=f+248|0,u=a[t+4>>2],l=f+16|0,a[l>>2]=a[t>>2],a[l+4>>2]=u,t=a[g+4>>2],a[Q>>2]=a[g>>2],a[Q+4>>2]=t,t=h+8|0,s=a[t+4>>2],u=v+8|0,a[u>>2]=a[t>>2],a[u+4>>2]=s,t=a[h+4>>2],a[v>>2]=a[h>>2],a[v+4>>2]=t,t=W,s=a[t+4>>2],a[d>>2]=a[t>>2],a[d+4>>2]=s,t=t+8|0,k=a[t+4>>2],s=d+8|0,a[s>>2]=a[t>>2],a[s+4>>2]=k,t=a[c+4>>2],k=Q+8|0,a[k>>2]=a[c>>2],a[k+4>>2]=t,t=a[f+244>>2],a[f+8>>2]=a[f+240>>2],a[f+12>>2]=t,t=n+4|0,c=t+8|0,k=a[c>>2],c=a[c+4>>2],D=a[t>>2],E=a[t+4>>2],B=n+20|0,F=a[B+4>>2],a[d>>2]=a[B>>2],a[d+4>>2]=F,B=n+28|0,F=a[B+4>>2],a[s>>2]=a[B>>2],a[s+4>>2]=F,a[l>>2]=k,a[l+4>>2]=c,a[f+8>>2]=D,a[f+12>>2]=E,c=n+36|0,l=a[c+4>>2],a[v>>2]=a[c>>2],a[v+4>>2]=l,c=n+44|0,l=a[c+4>>2],a[u>>2]=a[c>>2],a[u+4>>2]=l,_f(A,f+72|0,t,f+8|0,f+128|0,_(0)),b=C[f+132>>2],b<_(1)&&(C[n+268>>2]=b,Ji(n,_(b*i),f+240|0),a[n+268>>2]=0,ji(n,f+240|0),R=4),R)||(R=0),qr(),R)))||ji(n,f+240|0))}if(e=e+4|0,r=r+-1|0,!r)break}Y=f+304|0}(A,a[A+256>>2],i,e),o[A+291|0]){if(Lr(r- -64|0,23601),a[A+324>>2]>=1)for(;;){if(c=a[a[A+332>>2]+(s<<2)>>2],!(a[c+780>>2]<1))if(i=a[c+776>>2],f=a[i+252>>2]<<30>>31&i,i=a[c+772>>2],t=a[i+252>>2]<<30>>31&i,t)for(i=c+128|0,b=0;e=ke(t,f),e>_(0)&&(n=C[i>>2],n!=_(0)&&(k=C[i+-60>>2],l=C[i+-56>>2],u=C[i+-52>>2],a[r+60>>2]=0,C[r+56>>2]=-_(e*_(u*n)),C[r+52>>2]=-_(e*_(l*n)),C[r+48>>2]=-_(e*_(k*n)),a[r+44>>2]=0,C[r+40>>2]=C[i+-68>>2]-C[t+60>>2],C[r+36>>2]=C[i+-72>>2]-C[t+56>>2],C[r+32>>2]=C[i+-76>>2]-C[t+52>>2],a[r+28>>2]=0,C[r+24>>2]=C[i+-84>>2]-C[f+60>>2],C[r+20>>2]=C[i+-88>>2]-C[f+56>>2],C[r+16>>2]=C[i+-92>>2]-C[f+52>>2],dt(t,r+48|0,r+32|0),a[r+12>>2]=0,C[r+8>>2]=-C[r+56>>2],C[r+4>>2]=-C[r+52>>2],C[r>>2]=-C[r+48>>2],dt(f,r,r+16|0))),i=i+192|0,b=b+1|0,(0|b)>2];);else for(i=c+68|0,b=0;e=ke(t,f),e>_(0)&&(n=C[i+60>>2],n!=_(0)&&(k=C[i+4>>2],l=C[i+8>>2],u=C[i>>2],a[r+60>>2]=0,u=_(e*_(u*n)),C[r+48>>2]=-u,l=_(e*_(l*n)),C[r+56>>2]=-l,e=_(e*_(k*n)),C[r+52>>2]=-e,a[r+44>>2]=0,C[r+40>>2]=C[i+-8>>2]-C[t+60>>2],C[r+36>>2]=C[i+-12>>2]-C[t+56>>2],C[r+32>>2]=C[i+-16>>2]-C[t+52>>2],a[r+28>>2]=0,C[r+24>>2]=C[i+-24>>2]-C[f+60>>2],C[r+20>>2]=C[i+-28>>2]-C[f+56>>2],C[r+16>>2]=C[i+-32>>2]-C[f+52>>2],a[r+12>>2]=0,C[r+8>>2]=l,C[r+4>>2]=e,C[r>>2]=u,dt(f,r,r+16|0))),i=i+192|0,b=b+1|0,(0|b)>2];);if(s=s+1|0,!((0|s)>2]))break}qr()}qr(),Y=r+80|0},function(A){A|=0;var e,r=0,i=0,f=0,t=0,n=0,c=0,b=0,l=0;if(e=Y-16|0,Y=e,Lr(e+8|0,23445),r=a[A+220>>2],Qt[a[a[r>>2]+8>>2]](r,A,a[A+24>>2]),b=a[A+324>>2],(0|b)>=1)for(l=a[A+332>>2];;){if(r=a[l+(c<<2)>>2],i=a[r+772>>2],i&&(r=a[r+776>>2],!(!r|3&a[i+204>>2]|3&o[r+204|0]))){if(r=a[r+208>>2],f=a[a[A+220>>2]+16>>2],t=a[i+208>>2],n=f+(t<<3)|0,i=a[n>>2],(0|i)!=(0|t))for(;i=f+(i<<3)|0,a[n>>2]=a[i>>2],t=a[i>>2],n=f+(t<<3)|0,i=a[n>>2],(0|i)!=(0|t););if(n=f+(r<<3)|0,i=a[n>>2],(0|r)!=(0|i))for(;r=f+(i<<3)|0,a[n>>2]=a[r>>2],r=a[r>>2],n=f+(r<<3)|0,i=a[n>>2],(0|r)!=(0|i););(0|r)!=(0|t)&&(i=f+(t<<3)|0,a[i>>2]=r,r=f+(r<<3)|0,a[r+4>>2]=a[r+4>>2]+a[i+4>>2])}if(c=c+1|0,!((0|c)<(0|b)))break}if(b=a[A+228>>2],(0|b)>=1)for(l=a[A+236>>2],n=0;;){if(r=a[l+(n<<2)>>2],o[r+20|0]&&(i=a[r+28>>2],!(3&o[i+204|0]||(r=a[r+32>>2],3&o[r+204|0])))){if(r=a[r+208>>2],f=a[a[A+220>>2]+16>>2],t=a[i+208>>2],i=f+(t<<3)|0,c=a[i>>2],(0|c)!=(0|t))for(;t=i,i=f+(c<<3)|0,a[t>>2]=a[i>>2],t=a[i>>2],i=f+(t<<3)|0,c=a[i>>2],(0|c)!=(0|t););if(i=f+(r<<3)|0,c=a[i>>2],(0|c)!=(0|r))for(;r=f+(c<<3)|0,a[i>>2]=a[r>>2],r=a[r>>2],i=f+(r<<3)|0,c=a[i>>2],(0|c)!=(0|r););(0|r)!=(0|t)&&(i=f+(t<<3)|0,a[i>>2]=r,r=f+(r<<3)|0,a[r+4>>2]=a[r+4>>2]+a[i+4>>2])}if(n=n+1|0,(0|b)==(0|n))break}r=a[A+220>>2],Qt[a[a[r>>2]+12>>2]](r,A),qr(),Y=e+16|0},function(A,e){A|=0,e|=0;var r,i,t,n,c,b,l=0,u=0,s=0,k=0;if(i=Y-16|0,Y=i,Lr(i+8|0,23428),s=a[A+196>>2],r=a[A+228>>2],(0|s)<(0|r)){if(a[A+200>>2]<(0|r)){if(r?(k=dA(r<<2),l=a[A+196>>2]):l=s,(0|l)>=1)for(;a[u+k>>2]=a[a[A+204>>2]+u>>2],u=u+4|0,l=l+-1|0,l;);l=a[A+204>>2],l&&(o[A+208|0]&&CA(l),a[A+204>>2]=0),a[A+204>>2]=k,a[A+200>>2]=r,f[A+208|0]=1}for(u=s<<2,l=r-s|0;a[a[A+204>>2]+u>>2]=0,u=u+4|0,l=l+-1|0,l;);}if(a[A+196>>2]=r,(0|Qt[a[a[A>>2]+104>>2]](A))>=1)for(u=0,l=0;a[a[A+204>>2]+u>>2]=a[a[A+236>>2]+u>>2],u=u+4|0,l=l+1|0,(0|l)<(0|Qt[a[a[A>>2]+104>>2]](A)););l=a[A+196>>2],(0|l)>=2&&function A(e,r,i,f){for(var t=0,n=0,o=0,c=0,b=0,l=0,u=0,s=0,k=0,v=0;;){for(k=i,n=a[e+12>>2],s=a[n+((i+f|0)/2<<2)>>2],t=f;;){if(l=a[a[s+28>>2]+208>>2],c=(0|l)<0,c)for(b=i+-1|0,o=((i<<2)+n|0)-4|0,u=a[a[s+32>>2]+208>>2];b=b+1|0,o=o+4|0,v=a[o>>2],i=a[a[v+28>>2]+208>>2],(0|i)<=-1&&(i=a[a[v+32>>2]+208>>2]),(0|i)<(0|u););else for(b=i+-1|0,o=((i<<2)+n|0)-4|0;b=b+1|0,o=o+4|0,u=a[o>>2],i=a[a[u+28>>2]+208>>2],(0|i)<=-1&&(i=a[a[u+32>>2]+208>>2]),(0|i)<(0|l););if(c){for(i=t+1|0,t=(t<<2)+n|0,l=a[a[s+32>>2]+208>>2];c=a[t>>2],n=a[a[c+28>>2]+208>>2],(0|n)<=-1&&(n=a[a[c+32>>2]+208>>2]),t=t+-4|0,i=i+-1|0,(0|l)<(0|n););t=t+4|0}else{for(i=t+1|0,t=(t<<2)+n|0;c=a[t>>2],n=a[a[c+28>>2]+208>>2],(0|n)<=-1&&(n=a[a[c+32>>2]+208>>2]),t=t+-4|0,i=i+-1|0,(0|l)<(0|n););t=t+4|0}if((0|b)>(0|i)?(t=i,i=b):(n=a[o>>2],a[o>>2]=a[t>>2],a[a[e+12>>2]+(i<<2)>>2]=n,t=i+-1|0,i=b+1|0),!((0|i)<=(0|t)))break;n=a[e+12>>2]}if((0|t)>(0|k)&&A(e,r,k,t),!((0|i)<(0|f)))break}}(A+192|0,i,0,l+-1|0),u=0,Qt[a[a[A>>2]+104>>2]](A)&&(u=a[A+204>>2]),function(A,e,r,i,t){if(a[A+20>>2]=t,a[A+16>>2]=i,a[A+12>>2]=r,a[A+4>>2]=e,e=a[A+32>>2],(0|e)<=-1)for(a[A+36>>2]<=-1&&(r=a[A+40>>2],r&&(o[A+44|0]&&CA(r),a[A+40>>2]=0),a[A+36>>2]=0,a[A+40>>2]=0,f[A+44|0]=1),r=e<<2;a[a[A+40>>2]+r>>2]=0,r=r+4|0,i=e+1|0,t=i>>>0>=e>>>0,e=i,t;);if(a[A+32>>2]=0,e=a[A+52>>2],(0|e)<=-1)for(a[A+56>>2]<=-1&&(r=a[A+60>>2],r&&(o[A- -64|0]&&CA(r),a[A+60>>2]=0),a[A+56>>2]=0,a[A+60>>2]=0,f[A- -64|0]=1),r=e<<2;a[a[A+60>>2]+r>>2]=0,r=r+4|0,i=e+1|0,t=i>>>0>=e>>>0,e=i,t;);if(a[A+52>>2]=0,e=a[A+72>>2],(0|e)<=-1)for(a[A+76>>2]<=-1&&(r=a[A+80>>2],r&&(o[A+84|0]&&CA(r),a[A+80>>2]=0),a[A+76>>2]=0,a[A+80>>2]=0,f[A+84|0]=1),r=e<<2;a[a[A+80>>2]+r>>2]=0,r=r+4|0,i=e+1|0,t=i>>>0>=e>>>0,e=i,t;);a[A+72>>2]=0}(a[A+212>>2],e,u,a[A+196>>2],0|Qt[a[a[A>>2]+20>>2]](A)),l=a[A+216>>2],s=a[A+24>>2],n=l,c=a[A+8>>2],b=0|Qt[a[a[s>>2]+36>>2]](s),t=a[a[l>>2]+8>>2],Qt[t](0|n,0|c,0|b),Ff(a[A+220>>2],a[A+24>>2],A,a[A+212>>2]),Uf(a[A+212>>2]),l=a[A+216>>2],Qt[a[a[l>>2]+16>>2]](l,e,a[A+72>>2]),qr(),Y=i+16|0},function(A,e){A|=0,e=_(e);var r,i=0,f=_(0),t=0,n=_(0),c=0,b=0,l=0;if(r=Y-16|0,Y=r,Lr(r+8|0,23406),a[A+248>>2]>=1)for(;;){i=a[a[A+256>>2]+c>>2];A:if(i){t=a[i+220>>2],b=t+-2|0;e:{if(!(b-1|0&&b>>>0<=2)){if(f=C[i+372>>2],n=_(f*f),f=C[i+376>>2],n=_(n+_(f*f)),f=C[i+380>>2],n=_(n+_(f*f)),f=C[i+532>>2],n<_(f*f)&&(f=C[i+388>>2],n=_(f*f),f=C[i+392>>2],n=_(n+_(f*f)),f=C[i+396>>2],n=_(n+_(f*f)),f=C[i+536>>2],n<_(f*f))){C[i+224>>2]=C[i+224>>2]+e;break e}a[i+224>>2]=0,Ye(i,0),t=a[i+220>>2]}if(4==(0|t))break A}if(o[2792]||(f=C[750],f==_(0)|(C[i+224>>2]>f^1?2!=(-2&t):0)))Ye(i,1);else{if(3&o[i+204|0]){Ye(i,2);break A}if(1==(0|t)&&(Ye(i,3),t=a[i+220>>2]),2!=(0|t))break A;a[i+388>>2]=0,a[i+392>>2]=0,a[i+372>>2]=0,a[i+376>>2]=0,t=i+396|0,a[t>>2]=0,a[t+4>>2]=0,t=i+380|0,a[t>>2]=0,a[t+4>>2]=0,a[i+304>>2]=a[i+304>>2]+2}}if(c=c+4|0,l=l+1|0,!((0|l)>2]))break}qr(),Y=r+16|0},function(A,e){A|=0,e=_(e);var r,i,f,t=0,n=0,o=0;if(r=Y-16|0,Y=r,Lr(r,23363),t=a[A+84>>2],t&&Qt[t](A,e),Qt[a[a[A>>2]+140>>2]](A,e),t=0,a[A+32>>2]=0,C[A+28>>2]=e,i=A+48|0,f=0|Qt[a[a[A>>2]+20>>2]](A),a[i>>2]=f,Qt[a[a[A>>2]+164>>2]](A,e),Qt[a[a[A>>2]+44>>2]](A),Qt[a[a[A>>2]+148>>2]](A),C[A+104>>2]=e,Qt[a[a[A>>2]+152>>2]](A,A+92|0),Qt[a[a[A>>2]+144>>2]](A,e),Lr(r+8|0,23392),a[A+296>>2]>=1)for(;n=a[a[A+304>>2]+t>>2],Qt[a[a[n>>2]+8>>2]](n,A,e),t=t+4|0,o=o+1|0,(0|o)>2];);qr(),Qt[a[a[A>>2]+156>>2]](A,e),t=a[A+80>>2],t&&Qt[t](A,e),qr(),Y=r+16|0},function(A,e){A|=0,e=_(e);var r,i=0,t=0,n=0,c=0;if(r=Y-16|0,Y=r,Lr(r,23536),Lr(r+8|0,23499),i=a[A+332>>2],a[A+324>>2]>=1)for(;t=a[A+24>>2],Qt[a[a[t>>2]+16>>2]](t,a[i+n>>2]),n=n+4|0,i=a[A+332>>2],c=c+1|0,(0|c)>2];);i&&(o[A+336|0]&&CA(i),a[A+332>>2]=0),a[A+332>>2]=0,a[A+324>>2]=0,a[A+328>>2]=0,f[A+336|0]=1,qr(),i=a[A+248>>2],(0|i)>=1&&function(A,e,r,i){var t,n=0,c=0,b=0,l=0,u=_(0),s=0,k=0,v=_(0),d=_(0),g=0,m=_(0),R=_(0),G=0,y=0,p=0,F=0,W=0,w=0,D=_(0),E=0,Z=_(0),V=_(0),N=_(0),I=_(0),J=_(0),x=_(0),U=0,M=0,S=0,X=0,T=0,j=0,O=0,H=0,z=_(0),P=_(0),K=_(0),L=_(0),q=0,$=0,AA=0,eA=0,rA=0,iA=_(0),fA=_(0),tA=_(0);if(t=Y-496|0,Y=t,(0|r)>=1)for(G=t+124|0,q=t+92|0,U=t+72|0,$=t+368|0,M=t+248|0,p=t+232|0,S=t+464|0,F=t+216|0,AA=t+448|0,E=t+292|0,X=t+352|0,T=t+336|0,W=t+480|0;;){b=a[(j<<2)+e>>2],a[b+268>>2]=1065353216;A:{e:if(n=a[b+220>>2]+-2|0,!(n>>>0>3))switch(n-1|0){case 0:case 1:break e;default:break A}if(!(3&o[b+204|0])&&(Ji(b,i,t+432|0),o[A+44|0]&&(u=C[b+276>>2],u=_(u*u),u!=_(0)&&(d=u,y=b+52|0,u=_(C[t+480>>2]-C[y>>2]),v=_(u*u),u=_(C[t+484>>2]-C[b+56>>2]),v=_(v+_(u*u)),u=_(C[t+488>>2]-C[b+60>>2]),d<_(v+_(u*u)))))){if(Lr(t+424|0,23472),a[a[b+192>>2]+4>>2]<=19&&(a[702]=a[702]+1,n=a[A+68>>2],n=0|Qt[a[a[n>>2]+36>>2]](n),c=a[y+4>>2],a[T>>2]=a[y>>2],a[T+4>>2]=c,O=y+8|0,c=O,l=a[c+4>>2],k=T+8|0,a[k>>2]=a[c>>2],a[k+4>>2]=l,c=a[W+4>>2],a[X>>2]=a[W>>2],a[X+4>>2]=c,c=W+8|0,k=a[c+4>>2],s=X+8|0,a[s>>2]=a[c>>2],a[s+4>>2]=k,a[t+332>>2]=-1,a[t+324>>2]=1065353216,a[t+328>>2]=1,a[t+320>>2]=23884,a[t+400>>2]=0,a[t+408>>2]=0,a[t+416>>2]=a[A+24>>2],a[t+412>>2]=n,a[t+404>>2]=b,n=a[b+272>>2],DA(t+264|0),a[E>>2]=0,a[E+4>>2]=0,l=E+8|0,a[l>>2]=0,a[l+4>>2]=0,a[E+16>>2]=0,a[t+288>>2]=1065353216,a[t+280>>2]=1065353216,a[t+284>>2]=1065353216,a[t+268>>2]=8,a[t+264>>2]=9852,a[t+316>>2]=0,a[t+312>>2]=n,a[t+296>>2]=n,a[t+408>>2]=a[A+56>>2],n=a[b+188>>2],l=a[n+8>>2],a[t+328>>2]=a[n+4>>2],a[t+332>>2]=l,n=t+440|0,k=a[n+4>>2],l=t+208|0,a[l>>2]=a[n>>2],a[l+4>>2]=k,n=a[W+4>>2],a[M>>2]=a[W>>2],a[M+4>>2]=n,n=S+8|0,s=a[n+4>>2],k=p+8|0,a[k>>2]=a[n>>2],a[k+4>>2]=s,n=a[S+4>>2],a[p>>2]=a[S>>2],a[p+4>>2]=n,n=AA,s=a[n+4>>2],a[F>>2]=a[n>>2],a[F+4>>2]=s,n=n+8|0,g=a[n+4>>2],s=F+8|0,a[s>>2]=a[n>>2],a[s+4>>2]=g,n=a[c+4>>2],g=M+8|0,a[g>>2]=a[c>>2],a[g+4>>2]=n,n=a[t+436>>2],a[t+200>>2]=a[t+432>>2],a[t+204>>2]=n,n=b+4|0,c=n+8|0,g=a[c>>2],c=a[c+4>>2],eA=a[n>>2],rA=a[n+4>>2],w=b+20|0,H=a[w+4>>2],a[F>>2]=a[w>>2],a[F+4>>2]=H,w=b+28|0,H=a[w+4>>2],a[s>>2]=a[w>>2],a[s+4>>2]=H,a[l>>2]=g,a[l+4>>2]=c,a[t+200>>2]=eA,a[t+204>>2]=rA,c=b+36|0,l=a[c+4>>2],a[p>>2]=a[c>>2],a[p+4>>2]=l,c=b+44|0,l=a[c+4>>2],a[k>>2]=a[c>>2],a[k+4>>2]=l,_f(A,t+264|0,n,t+200|0,t+320|0,_(0)),u=C[t+324>>2],u<_(1))){if(D=C[b+60>>2],m=C[b+56>>2],R=C[b+52>>2],d=C[t+376>>2],Z=C[t+488>>2],V=C[t+372>>2],N=C[t+484>>2],I=C[t+368>>2],J=C[t+480>>2],n=a[A+24>>2],k=0|Qt[a[a[n>>2]+12>>2]](n,b,a[t+400>>2]),x=_(u*_(N-m)),m=_(u*_(J-R)),v=d,d=_(u*_(Z-D)),R=_(_(_(-_(V*x))-_(I*m))-_(v*d)),n=a[A+324>>2],(0|n)==a[A+328>>2]&&(s=n?n<<1:1,!((0|n)>=(0|s)))){if(s?(g=dA(s<<2),n=a[A+324>>2]):g=0,(0|n)>=1)for(l=0,c=n;a[l+g>>2]=a[a[A+332>>2]+l>>2],l=l+4|0,c=c+-1|0,c;);c=a[A+332>>2],c&&(o[A+336|0]&&(CA(c),n=a[A+324>>2]),a[A+332>>2]=0),a[A+332>>2]=g,f[A+336|0]=1,a[A+328>>2]=s}a[a[A+332>>2]+(n<<2)>>2]=k,a[A+324>>2]=n+1,n=a[t+400>>2],Z=C[n+20>>2],V=C[n+36>>2],N=C[n+40>>2],I=C[n+8>>2],J=C[n+24>>2],u=C[n+60>>2],iA=C[n+52>>2],D=C[n+56>>2],P=C[n+44>>2],v=C[n+12>>2],K=C[n+28>>2],L=C[n+4>>2],z=C[b+60>>2],fA=C[b+52>>2],tA=C[b+56>>2],n=t+16|0,a[n>>2]=0,a[n+4>>2]=0,n=q,a[n>>2]=0,a[n+4>>2]=0,n=n+8|0,a[n>>2]=0,a[n+4>>2]=0,a[G>>2]=0,a[G+4>>2]=0,n=G+8|0,a[n>>2]=0,a[n+4>>2]=0,n=G+16|0,a[n>>2]=0,a[n+4>>2]=0,n=G+24|0,a[n>>2]=0,a[n+4>>2]=0,n=G+32|0,a[n>>2]=0,a[n+4>>2]=0,a[G+40>>2]=0,n=$,c=a[n+4>>2],a[U>>2]=a[n>>2],a[U+4>>2]=c,n=n+8|0,c=a[n+4>>2],l=U+8|0,a[l>>2]=a[n>>2],a[l+4>>2]=c,a[t+8>>2]=0,a[t+12>>2]=0,a[t+36>>2]=0,C[t+88>>2]=R,m=_(m+fA),R=_(x+tA),d=_(d+z),z=_(_(_(v*m)+_(K*R))+_(P*d)),x=v,v=_(-iA),C[t+32>>2]=z+_(_(_(x*v)-_(K*D))-_(P*u)),C[t+28>>2]=_(_(_(m*I)+_(R*J))+_(d*N))+_(_(_(I*v)-_(J*D))-_(N*u)),C[t+24>>2]=_(_(_(m*L)+_(R*Z))+_(d*V))+_(_(_(L*v)-_(Z*D))-_(V*u)),n=k+B(ue(k,t+8|0),192)|0,a[n+100>>2]=0,C[n+88>>2]=Q(_(h(_(C[b+228>>2]*C[a[t+400>>2]+228>>2]),_(-10))),_(10)),c=a[y+4>>2],b=n+52|0,a[b>>2]=a[y>>2],a[b+4>>2]=c,c=a[O+4>>2],b=n+60|0,a[b>>2]=a[O>>2],a[b+4>>2]=c,a[n+48>>2]=0,C[n+44>>2]=d,C[n+40>>2]=R,C[n+36>>2]=m}qr()}}if(j=j+1|0,(0|j)==(0|r))break}Y=t+496|0}(A,a[A+256>>2],i,e),qr(),Y=r+16|0},function(A,e){A|=0,e=_(e);var r=0,i=0,f=0,t=0;if(i=a[A+8>>2],(0|i)>=1)for(;r=a[a[A+16>>2]+f>>2],!r|!(2&a[r+252>>2])|!(2&o[r+204|0])|2==a[r+220>>2]||(Ui(r,e),i=a[A+8>>2]),f=f+4|0,t=t+1|0,(0|t)<(0|i););},function(A,e){A|=0,e|=0;var r,i=0,f=0,t=0,n=0,c=0,b=_(0),l=_(0),u=_(0),s=0,k=_(0),v=0,d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),y=_(0),p=_(0),F=_(0),W=0,w=_(0),D=_(0),E=_(0),Z=0,V=_(0),N=0,I=_(0),J=_(0),x=_(0),U=0,M=0,S=0,X=_(0),T=_(0),j=_(0),O=0,H=_(0),z=_(0),P=0,K=_(0);r=Y-176|0,Y=r,i=0|Qt[a[a[A>>2]+20>>2]](A),i=0|Qt[a[a[i>>2]+56>>2]](i),t=0|Qt[a[a[A>>2]+20>>2]](A),t=0|Qt[a[a[t>>2]+56>>2]](t),w=C[e+40>>2];A:if(!(w<=_(0)||(n=a[e+4>>2]+-3|0,n>>>0>9))){switch(f=2048&i,s=4096&t,n-1|0){default:if(t=r+172|0,a[t>>2]=0,n=r+164|0,i=n,a[i>>2]=0,a[i+4>>2]=0,i=r+156|0,a[i>>2]=0,a[i+4>>2]=0,i=r+124|0,a[i>>2]=0,a[i+4>>2]=0,i=r+136|0,a[i>>2]=0,a[i+4>>2]=0,a[r+132>>2]=1065353216,a[r+152>>2]=1065353216,a[r+116>>2]=0,a[r+120>>2]=0,a[r+144>>2]=0,a[r+148>>2]=0,a[r+112>>2]=1065353216,i=a[e+28>>2],k=C[i+52>>2],g=C[i+8>>2],B=C[i+12>>2],d=C[i+56>>2],m=C[i+28>>2],R=C[i+20>>2],h=C[i+24>>2],b=C[i+60>>2],u=C[i+44>>2],l=C[i+36>>2],G=C[i+40>>2],y=C[i+4>>2],a[t>>2]=0,W=r+168|0,Q=b,b=C[e+300>>2],p=_(l*b),l=C[e+304>>2],F=u,u=C[e+308>>2],C[W>>2]=Q+_(_(p+_(G*l))+_(F*u)),C[n>>2]=d+_(_(_(b*R)+_(l*h))+_(u*m)),C[r+160>>2]=k+_(_(_(b*y)+_(l*g))+_(u*B)),i=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[i>>2]+64>>2]](i,r+112|0,w),i=a[e+32>>2],k=C[i+52>>2],g=C[i+8>>2],B=C[i+12>>2],d=C[i+56>>2],m=C[i+28>>2],R=C[i+20>>2],h=C[i+24>>2],b=C[i+60>>2],u=C[i+44>>2],l=C[i+36>>2],G=C[i+40>>2],y=C[i+4>>2],a[t>>2]=0,Q=b,b=C[e+316>>2],p=_(l*b),l=C[e+320>>2],F=u,u=C[e+324>>2],C[W>>2]=Q+_(_(p+_(G*l))+_(F*u)),C[n>>2]=d+_(_(_(b*R)+_(l*h))+_(u*m)),C[r+160>>2]=k+_(_(_(b*y)+_(l*g))+_(u*B)),!f)break A;A=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[A>>2]+64>>2]](A,r+112|0,w);break A;case 0:if(i=a[e+28>>2],X=C[i+52>>2],b=C[i+8>>2],l=C[i+12>>2],h=C[e+584>>2],G=C[e+552>>2],y=C[e+568>>2],T=C[i+56>>2],j=C[i+60>>2],V=C[e+608>>2],F=C[e+600>>2],I=C[e+604>>2],u=C[i+28>>2],k=C[i+20>>2],g=C[i+24>>2],J=C[e+588>>2],Q=C[e+556>>2],p=C[e+572>>2],D=C[e+592>>2],B=C[i+44>>2],x=C[e+560>>2],d=C[i+36>>2],E=C[e+576>>2],m=C[i+40>>2],R=C[i+4>>2],a[r+172>>2]=0,a[r+156>>2]=0,a[r+140>>2]=0,C[r+152>>2]=_(_(x*d)+_(E*m))+_(D*B),C[r+148>>2]=_(_(Q*d)+_(p*m))+_(J*B),C[r+136>>2]=_(_(x*k)+_(E*g))+_(D*u),C[r+132>>2]=_(_(Q*k)+_(p*g))+_(J*u),C[r+168>>2]=j+_(_(_(d*F)+_(m*I))+_(B*V)),C[r+164>>2]=T+_(_(_(k*F)+_(g*I))+_(u*V)),a[r+124>>2]=0,C[r+144>>2]=_(_(G*d)+_(y*m))+_(h*B),C[r+128>>2]=_(_(G*k)+_(y*g))+_(h*u),C[r+120>>2]=_(_(R*x)+_(b*E))+_(l*D),C[r+116>>2]=_(_(R*Q)+_(b*p))+_(l*J),C[r+112>>2]=_(_(G*R)+_(y*b))+_(h*l),C[r+160>>2]=X+_(_(_(R*F)+_(b*I))+_(l*V)),f?(i=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[i>>2]+64>>2]](i,r+112|0,w),i=a[e+32>>2],X=C[i+52>>2],b=C[i+8>>2],l=C[i+12>>2],T=C[i+56>>2],j=C[i+60>>2],h=C[e+672>>2],G=C[e+664>>2],y=C[e+668>>2],u=C[i+28>>2],k=C[i+20>>2],g=C[i+24>>2],V=C[e+648>>2],F=C[e+616>>2],I=C[e+632>>2],J=C[e+652>>2],Q=C[e+620>>2],p=C[e+636>>2],D=C[e+656>>2],B=C[i+44>>2],x=C[e+624>>2],d=C[i+36>>2],E=C[e+640>>2],m=C[i+40>>2],R=C[i+4>>2],a[r+172>>2]=0,a[r+156>>2]=0,a[r+140>>2]=0,C[r+152>>2]=_(_(x*d)+_(E*m))+_(D*B),C[r+148>>2]=_(_(Q*d)+_(p*m))+_(J*B),C[r+144>>2]=_(_(F*d)+_(I*m))+_(V*B),C[r+136>>2]=_(_(x*k)+_(E*g))+_(D*u),C[r+132>>2]=_(_(Q*k)+_(p*g))+_(J*u),C[r+168>>2]=j+_(_(_(d*G)+_(m*y))+_(B*h)),C[r+164>>2]=T+_(_(_(k*G)+_(g*y))+_(u*h)),C[r+160>>2]=X+_(_(_(R*G)+_(b*y))+_(l*h)),a[r+124>>2]=0,C[r+128>>2]=_(_(F*k)+_(I*g))+_(V*u),C[r+120>>2]=_(_(R*x)+_(b*E))+_(l*D),C[r+116>>2]=_(_(R*Q)+_(b*p))+_(l*J),C[r+112>>2]=_(_(F*R)+_(I*b))+_(V*l),i=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[i>>2]+64>>2]](i,r+112|0,w)):(i=a[e+32>>2],X=C[i+52>>2],T=C[i+56>>2],j=C[i+60>>2],h=C[e+672>>2],G=C[e+664>>2],y=C[e+668>>2],b=C[i+8>>2],l=C[i+12>>2],u=C[i+28>>2],k=C[i+20>>2],g=C[i+24>>2],V=C[e+648>>2],F=C[e+616>>2],I=C[e+632>>2],J=C[e+652>>2],Q=C[e+620>>2],p=C[e+636>>2],D=C[e+656>>2],B=C[i+44>>2],x=C[e+624>>2],d=C[i+36>>2],E=C[e+640>>2],m=C[i+40>>2],R=C[i+4>>2],a[r+172>>2]=0,a[r+156>>2]=0,a[r+140>>2]=0,a[r+124>>2]=0,C[r+152>>2]=_(_(x*d)+_(E*m))+_(D*B),C[r+148>>2]=_(_(Q*d)+_(p*m))+_(J*B),C[r+144>>2]=_(_(F*d)+_(I*m))+_(V*B),C[r+136>>2]=_(_(x*k)+_(E*g))+_(D*u),C[r+132>>2]=_(_(Q*k)+_(p*g))+_(J*u),C[r+128>>2]=_(_(F*k)+_(I*g))+_(V*u),C[r+120>>2]=_(_(R*x)+_(b*E))+_(l*D),C[r+116>>2]=_(_(R*Q)+_(b*p))+_(l*J),C[r+112>>2]=_(_(F*R)+_(I*b))+_(V*l),C[r+168>>2]=j+_(_(_(d*G)+_(m*y))+_(B*h)),C[r+164>>2]=T+_(_(_(k*G)+_(g*y))+_(u*h)),C[r+160>>2]=X+_(_(_(R*G)+_(b*y))+_(l*h))),i=e+688|0,b=function(A){var e=_(0);return e=Wf(_(C[A>>2]-C[A+4>>2])),e<_(-3.1415927410125732)?_(e+_(6.2831854820251465)):e>_(3.1415927410125732)^1?e:_(e+_(-6.2831854820251465))}(i),l=function(A){var e=_(0);return e=Wf(_(C[A>>2]+C[A+4>>2])),e<_(-3.1415927410125732)?_(e+_(6.2831854820251465)):e>_(3.1415927410125732)^1?e:_(e+_(-6.2831854820251465))}(i),!s|b==l)break A;u=C[e+692>>2],a[r+96>>2]=a[r+120>>2],a[r+100>>2]=a[r+136>>2],a[r+108>>2]=0,a[r+104>>2]=a[r+152>>2],a[r+80>>2]=a[r+112>>2],a[r+84>>2]=a[r+128>>2],a[r+92>>2]=0,a[r+88>>2]=a[r+144>>2],A=0|Qt[a[a[A>>2]+20>>2]](A),e=r+72|0,a[e>>2]=0,a[e+4>>2]=0,a[r+64>>2]=0,a[r+68>>2]=0,e=u>_(0),Qt[a[a[A>>2]+68>>2]](A,r+160|0,r+96|0,r+80|0,w,w,e?b:_(0),e?l:_(6.2831854820251465),r- -64|0,e,_(10));break A;case 1:if(i=a[e+28>>2],X=C[i+52>>2],b=C[i+8>>2],l=C[i+12>>2],h=C[e+332>>2],G=C[e+300>>2],y=C[e+316>>2],T=C[i+56>>2],j=C[i+60>>2],V=C[e+356>>2],F=C[e+348>>2],I=C[e+352>>2],u=C[i+28>>2],k=C[i+20>>2],g=C[i+24>>2],J=C[e+336>>2],Q=C[e+304>>2],p=C[e+320>>2],D=C[e+340>>2],B=C[i+44>>2],x=C[e+308>>2],d=C[i+36>>2],E=C[e+324>>2],m=C[i+40>>2],R=C[i+4>>2],a[r+172>>2]=0,a[r+156>>2]=0,a[r+140>>2]=0,C[r+152>>2]=_(_(x*d)+_(E*m))+_(D*B),C[r+148>>2]=_(_(Q*d)+_(p*m))+_(J*B),C[r+136>>2]=_(_(x*k)+_(E*g))+_(D*u),C[r+132>>2]=_(_(Q*k)+_(p*g))+_(J*u),C[r+168>>2]=j+_(_(_(d*F)+_(m*I))+_(B*V)),C[r+164>>2]=T+_(_(_(k*F)+_(g*I))+_(u*V)),a[r+124>>2]=0,C[r+144>>2]=_(_(G*d)+_(y*m))+_(h*B),C[r+128>>2]=_(_(G*k)+_(y*g))+_(h*u),C[r+120>>2]=_(_(R*x)+_(b*E))+_(l*D),C[r+116>>2]=_(_(R*Q)+_(b*p))+_(l*J),C[r+112>>2]=_(_(G*R)+_(y*b))+_(h*l),C[r+160>>2]=X+_(_(_(R*F)+_(b*I))+_(l*V)),f?(i=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[i>>2]+64>>2]](i,r+112|0,w),i=a[e+32>>2],X=C[i+52>>2],b=C[i+8>>2],l=C[i+12>>2],T=C[i+56>>2],j=C[i+60>>2],h=C[e+420>>2],G=C[e+412>>2],y=C[e+416>>2],u=C[i+28>>2],k=C[i+20>>2],g=C[i+24>>2],V=C[e+396>>2],F=C[e+364>>2],I=C[e+380>>2],J=C[e+400>>2],Q=C[e+368>>2],p=C[e+384>>2],D=C[e+404>>2],B=C[i+44>>2],x=C[e+372>>2],d=C[i+36>>2],E=C[e+388>>2],m=C[i+40>>2],R=C[i+4>>2],a[r+172>>2]=0,a[r+156>>2]=0,a[r+140>>2]=0,C[r+152>>2]=_(_(x*d)+_(E*m))+_(D*B),C[r+148>>2]=_(_(Q*d)+_(p*m))+_(J*B),C[r+144>>2]=_(_(F*d)+_(I*m))+_(V*B),C[r+136>>2]=_(_(x*k)+_(E*g))+_(D*u),C[r+132>>2]=_(_(Q*k)+_(p*g))+_(J*u),C[r+168>>2]=j+_(_(_(d*G)+_(m*y))+_(B*h)),C[r+164>>2]=T+_(_(_(k*G)+_(g*y))+_(u*h)),C[r+160>>2]=X+_(_(_(R*G)+_(b*y))+_(l*h)),a[r+124>>2]=0,C[r+128>>2]=_(_(F*k)+_(I*g))+_(V*u),C[r+120>>2]=_(_(R*x)+_(b*E))+_(l*D),C[r+116>>2]=_(_(R*Q)+_(b*p))+_(l*J),C[r+112>>2]=_(_(F*R)+_(I*b))+_(V*l),i=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[i>>2]+64>>2]](i,r+112|0,w)):(i=a[e+32>>2],X=C[i+52>>2],T=C[i+56>>2],j=C[i+60>>2],h=C[e+420>>2],G=C[e+412>>2],y=C[e+416>>2],b=C[i+8>>2],l=C[i+12>>2],u=C[i+28>>2],k=C[i+20>>2],g=C[i+24>>2],V=C[e+396>>2],F=C[e+364>>2],I=C[e+380>>2],J=C[e+400>>2],Q=C[e+368>>2],p=C[e+384>>2],D=C[e+404>>2],B=C[i+44>>2],x=C[e+372>>2],d=C[i+36>>2],E=C[e+388>>2],m=C[i+40>>2],R=C[i+4>>2],a[r+172>>2]=0,a[r+156>>2]=0,a[r+140>>2]=0,a[r+124>>2]=0,C[r+152>>2]=_(_(x*d)+_(E*m))+_(D*B),C[r+148>>2]=_(_(Q*d)+_(p*m))+_(J*B),C[r+144>>2]=_(_(F*d)+_(I*m))+_(V*B),C[r+136>>2]=_(_(x*k)+_(E*g))+_(D*u),C[r+132>>2]=_(_(Q*k)+_(p*g))+_(J*u),C[r+128>>2]=_(_(F*k)+_(I*g))+_(V*u),C[r+120>>2]=_(_(R*x)+_(b*E))+_(l*D),C[r+116>>2]=_(_(R*Q)+_(b*p))+_(l*J),C[r+112>>2]=_(_(F*R)+_(I*b))+_(V*l),C[r+168>>2]=j+_(_(_(d*G)+_(m*y))+_(B*h)),C[r+164>>2]=T+_(_(_(k*G)+_(g*y))+_(u*h)),C[r+160>>2]=X+_(_(_(R*G)+_(b*y))+_(l*h))),!s)break A;for(Zf(r+96|0,e,_(6.0868353843688965),w),a[r+108>>2]=0,b=C[r+96>>2],l=C[r+100>>2],u=C[r+104>>2],C[r+104>>2]=_(_(_(b*C[r+144>>2])+_(l*C[r+148>>2]))+_(u*C[r+152>>2]))+C[r+168>>2],C[r+100>>2]=_(_(_(b*C[r+128>>2])+_(l*C[r+132>>2]))+_(u*C[r+136>>2]))+C[r+164>>2],C[r+96>>2]=_(_(_(b*C[r+112>>2])+_(l*C[r+116>>2]))+_(u*C[r+120>>2]))+C[r+160>>2],t=r+160|0,n=r+72|0,i=0;Zf(r+80|0,e,_(_(_(0|i)*_(6.283185005187988))*_(.03125)),w),a[r+92>>2]=0,b=C[r+80>>2],l=C[r+84>>2],u=C[r+88>>2],C[r+88>>2]=_(_(_(b*C[r+144>>2])+_(l*C[r+148>>2]))+_(u*C[r+152>>2]))+C[r+168>>2],C[r+84>>2]=_(_(_(b*C[r+128>>2])+_(l*C[r+132>>2]))+_(u*C[r+136>>2]))+C[r+164>>2],C[r+80>>2]=_(_(_(b*C[r+112>>2])+_(l*C[r+116>>2]))+_(u*C[r+120>>2]))+C[r+160>>2],f=0|Qt[a[a[A>>2]+20>>2]](A),a[n>>2]=0,a[n+4>>2]=0,a[r+64>>2]=0,a[r+68>>2]=0,Qt[a[a[f>>2]+16>>2]](f,r+96|0,r+80|0,r- -64|0),3&i||(f=0|Qt[a[a[A>>2]+20>>2]](A),a[n>>2]=0,a[n+4>>2]=0,a[r+64>>2]=0,a[r+68>>2]=0,Qt[a[a[f>>2]+16>>2]](f,t,r+80|0,r- -64|0)),W=r+88|0,U=a[W+4>>2],f=r+104|0,a[f>>2]=a[W>>2],a[f+4>>2]=U,f=a[r+84>>2],a[r+96>>2]=a[r+80>>2],a[r+100>>2]=f,i=i+1|0,32!=(0|i););G=C[e+512>>2],y=C[e+452>>2],i=a[e+32>>2],C[i+404>>2]>_(0)?(b=C[i+36>>2],d=C[e+412>>2],l=C[i+40>>2],m=C[e+416>>2],V=_(_(b*d)+_(l*m)),u=C[i+20>>2],k=C[i+24>>2],g=C[i+28>>2],F=C[e+420>>2],I=_(_(_(u*d)+_(k*m))+_(g*F)),B=C[i+4>>2],Q=_(B*d),d=C[i+8>>2],Q=_(Q+_(d*m)),m=C[i+12>>2],J=_(Q+_(m*F)),Q=C[e+372>>2],p=C[e+388>>2],D=C[e+404>>2],R=C[i+44>>2],x=_(_(_(Q*b)+_(p*l))+_(D*R)),E=C[e+368>>2],X=C[e+384>>2],T=C[e+400>>2],h=_(_(_(E*b)+_(X*l))+_(T*R)),j=C[e+364>>2],H=C[e+380>>2],z=C[e+396>>2],b=_(_(_(j*b)+_(H*l))+_(z*R)),K=_(_(_(Q*u)+_(p*k))+_(D*g)),l=_(_(_(E*u)+_(X*k))+_(T*g)),u=_(_(_(j*u)+_(H*k))+_(z*g)),Q=_(_(_(B*Q)+_(d*p))+_(m*D)),k=_(_(_(B*E)+_(d*X))+_(m*T)),g=_(_(_(j*B)+_(H*d))+_(z*m)),B=_(R*F)):(i=a[e+28>>2],b=C[i+36>>2],d=C[e+348>>2],l=C[i+40>>2],m=C[e+352>>2],V=_(_(b*d)+_(l*m)),u=C[i+20>>2],k=C[i+24>>2],g=C[i+28>>2],F=C[e+356>>2],I=_(_(_(u*d)+_(k*m))+_(g*F)),B=C[i+4>>2],Q=_(B*d),d=C[i+8>>2],Q=_(Q+_(d*m)),m=C[i+12>>2],J=_(Q+_(m*F)),Q=C[e+308>>2],p=C[e+324>>2],D=C[e+340>>2],R=C[i+44>>2],x=_(_(_(Q*b)+_(p*l))+_(D*R)),E=C[e+304>>2],X=C[e+320>>2],T=C[e+336>>2],h=_(_(_(E*b)+_(X*l))+_(T*R)),j=C[e+300>>2],H=C[e+316>>2],z=C[e+332>>2],b=_(_(_(j*b)+_(H*l))+_(z*R)),K=_(_(_(Q*u)+_(p*k))+_(D*g)),l=_(_(_(E*u)+_(X*k))+_(T*g)),u=_(_(_(j*u)+_(H*k))+_(z*g)),Q=_(_(_(B*Q)+_(d*p))+_(m*D)),k=_(_(_(B*E)+_(d*X))+_(m*T)),g=_(_(_(j*B)+_(H*d))+_(z*m)),B=_(R*F)),a[r+156>>2]=0,C[r+152>>2]=x,C[r+148>>2]=h,C[r+144>>2]=b,a[r+140>>2]=0,C[r+136>>2]=K,C[r+132>>2]=l,C[r+128>>2]=u,a[r+124>>2]=0,C[r+120>>2]=Q,C[r+116>>2]=k,C[r+112>>2]=g,d=C[i+52>>2],m=C[i+56>>2],R=C[i+60>>2],a[r+172>>2]=0,C[r+168>>2]=R+_(V+B),C[r+164>>2]=I+m,C[r+160>>2]=d+J,i=t+8|0,n=a[i+4>>2],e=r+88|0,a[e>>2]=a[i>>2],a[e+4>>2]=n,e=a[t+4>>2],a[r+80>>2]=a[t>>2],a[r+84>>2]=e,a[r+76>>2]=0,C[r+72>>2]=b,C[r+68>>2]=u,C[r+64>>2]=g,a[r+60>>2]=0,C[r+56>>2]=h,C[r+52>>2]=l,C[r+48>>2]=k,A=0|Qt[a[a[A>>2]+20>>2]](A),e=r+40|0,a[e>>2]=0,a[e+4>>2]=0,a[r+32>>2]=0,a[r+36>>2]=0,Qt[a[a[A>>2]+68>>2]](A,r+80|0,r- -64|0,r+48|0,w,w,_(_(-G)-y),_(y-G),r+32|0,1,_(10));break A;case 2:case 5:if(t=e+1072|0,n=a[t+4>>2],c=r+120|0,i=c,a[i>>2]=a[t>>2],a[i+4>>2]=n,t=e+1088|0,n=a[t+4>>2],i=r+136|0,a[i>>2]=a[t>>2],a[i+4>>2]=n,t=e+1104|0,n=a[t+4>>2],i=r+152|0,a[i>>2]=a[t>>2],a[i+4>>2]=n,t=e+1120|0,n=a[t+4>>2],i=r+168|0,a[i>>2]=a[t>>2],a[i+4>>2]=n,W=e+1064|0,i=W,t=a[i+4>>2],a[r+112>>2]=a[i>>2],a[r+116>>2]=t,U=e+1080|0,i=U,t=a[i+4>>2],a[r+128>>2]=a[i>>2],a[r+132>>2]=t,M=e+1096|0,i=M,t=a[i+4>>2],a[r+144>>2]=a[i>>2],a[r+148>>2]=t,S=e+1112|0,i=S,t=a[i+4>>2],a[r+160>>2]=a[i>>2],a[r+164>>2]=t,i=r+160|0,t=r+144|0,n=r+128|0,f?(f=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[f>>2]+64>>2]](f,r+112|0,w),v=e+1184|0,N=a[v+4>>2],f=i+8|0,a[f>>2]=a[v>>2],a[f+4>>2]=N,f=e+1176|0,v=a[f+4>>2],a[i>>2]=a[f>>2],a[i+4>>2]=v,f=e+1144|0,v=a[f+4>>2],a[n>>2]=a[f>>2],a[n+4>>2]=v,v=e+1152|0,N=a[v+4>>2],f=n+8|0,a[f>>2]=a[v>>2],a[f+4>>2]=N,f=e+1160|0,v=a[f+4>>2],a[t>>2]=a[f>>2],a[t+4>>2]=v,v=e+1168|0,N=a[v+4>>2],f=t+8|0,a[f>>2]=a[v>>2],a[f+4>>2]=N,f=e+1136|0,v=a[f+4>>2],a[c>>2]=a[f>>2],a[c+4>>2]=v,f=e+1128|0,c=a[f+4>>2],a[r+112>>2]=a[f>>2],a[r+116>>2]=c,f=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[f>>2]+64>>2]](f,r+112|0,w)):(f=e+1136|0,v=a[f+4>>2],a[c>>2]=a[f>>2],a[c+4>>2]=v,f=e+1144|0,c=a[f+4>>2],a[n>>2]=a[f>>2],a[n+4>>2]=c,c=e+1152|0,v=a[c+4>>2],f=n+8|0,a[f>>2]=a[c>>2],a[f+4>>2]=v,f=e+1160|0,c=a[f+4>>2],a[t>>2]=a[f>>2],a[t+4>>2]=c,c=e+1168|0,v=a[c+4>>2],f=t+8|0,a[f>>2]=a[c>>2],a[f+4>>2]=v,f=e+1176|0,c=a[f+4>>2],a[i>>2]=a[f>>2],a[i+4>>2]=c,c=e+1184|0,v=a[c+4>>2],f=i+8|0,a[f>>2]=a[c>>2],a[f+4>>2]=v,f=e+1128|0,c=a[f+4>>2],a[r+112>>2]=a[f>>2],a[r+116>>2]=c),!s)break A;f=a[U+4>>2],a[n>>2]=a[U>>2],a[n+4>>2]=f,f=a[M+4>>2],a[t>>2]=a[M>>2],a[t+4>>2]=f,f=a[S+4>>2],a[i>>2]=a[S>>2],a[i+4>>2]=f,c=W+8|0,v=a[c+4>>2],s=r+120|0,f=s,Z=a[c>>2],a[f>>2]=Z,a[f+4>>2]=v,v=U+8|0,N=a[v+4>>2],c=n+8|0,f=c,a[f>>2]=a[v>>2],a[f+4>>2]=N,N=M+8|0,O=a[N+4>>2],v=t+8|0,f=v,a[f>>2]=a[N>>2],a[f+4>>2]=O,O=S+8|0,P=a[O+4>>2],N=i+8|0,f=N,a[f>>2]=a[O>>2],a[f+4>>2]=P,f=a[W+4>>2],a[r+112>>2]=a[W>>2],a[r+116>>2]=f,a[r+96>>2]=Z,a[r+100>>2]=a[r+136>>2],a[r+108>>2]=0,a[r+104>>2]=a[r+152>>2],a[r+80>>2]=a[r+112>>2],a[r+84>>2]=a[r+128>>2],a[r+92>>2]=0,a[r+88>>2]=a[r+144>>2],b=C[e+932>>2],l=C[e+936>>2],u=C[e+996>>2],k=C[e+1e3>>2],Z=0|Qt[a[a[A>>2]+20>>2]](A),f=r+72|0,a[f>>2]=0,a[f+4>>2]=0,a[r+64>>2]=0,a[r+68>>2]=0,f=e+1176|0,Qt[a[a[Z>>2]+72>>2]](Z,f,r+96|0,r+80|0,_(w*_(.8999999761581421)),b,l,u,k,r- -64|0,_(10),1),a[r+92>>2]=0,a[r+88>>2]=a[r+148>>2],a[r+84>>2]=a[r+132>>2],a[r+80>>2]=a[r+116>>2],u=Vf(e,1),k=Vf(e,2),Z=e+1136|0,O=a[Z+4>>2],a[s>>2]=a[Z>>2],a[s+4>>2]=O,s=e+1144|0,Z=a[s+4>>2],a[n>>2]=a[s>>2],a[n+4>>2]=Z,s=e+1152|0,Z=a[s+4>>2],a[c>>2]=a[s>>2],a[c+4>>2]=Z,s=e+1160|0,c=a[s+4>>2],a[t>>2]=a[s>>2],a[t+4>>2]=c,s=e+1168|0,c=a[s+4>>2],a[v>>2]=a[s>>2],a[v+4>>2]=c,s=e+1128|0,c=a[s+4>>2],a[r+112>>2]=a[s>>2],a[r+116>>2]=c,b=dr(k),l=C[r+80>>2],k=Cr(k),g=C[r+84>>2],C[r+68>>2]=_(k*g)-_(b*l),B=dr(u),u=Cr(u),d=C[r+88>>2],C[r+72>>2]=_(_(l*_(k*B))+_(g*_(B*b)))+_(u*d),C[r+64>>2]=_(_(l*_(u*k))+_(g*_(u*b)))-_(B*d),s=e+1184|0,c=a[s+4>>2],a[N>>2]=a[s>>2],a[N+4>>2]=c,s=a[f+4>>2],a[i>>2]=a[f>>2],a[i+4>>2]=s,a[r+60>>2]=0,C[r+56>>2]=-C[r+144>>2],C[r+52>>2]=-C[r+128>>2],C[r+48>>2]=-C[r+112>>2],b=C[e+868>>2],l=C[e+872>>2],b>l?(s=0|Qt[a[a[A>>2]+20>>2]](A),c=r+40|0,a[c>>2]=0,a[c+4>>2]=0,a[r+32>>2]=0,a[r+36>>2]=0,Qt[a[a[s>>2]+68>>2]](s,f,r+48|0,r- -64|0,w,w,_(-3.1415927410125732),_(3.1415927410125732),r+32|0,0,_(10))):b>2]+20>>2]](A),c=r+40|0,a[c>>2]=0,a[c+4>>2]=0,a[r+32>>2]=0,a[r+36>>2]=0,Qt[a[a[s>>2]+68>>2]](s,f,r+48|0,r- -64|0,w,w,b,l,r+32|0,1,_(10))),f=a[U+4>>2],a[n>>2]=a[U>>2],a[n+4>>2]=f,f=a[M+4>>2],a[t>>2]=a[M>>2],a[t+4>>2]=f,f=a[S+4>>2],a[i>>2]=a[S>>2],a[i+4>>2]=f,s=W+8|0,c=a[s+4>>2],f=r+120|0,a[f>>2]=a[s>>2],a[f+4>>2]=c,f=U+8|0,U=a[f+4>>2],n=n+8|0,a[n>>2]=a[f>>2],a[n+4>>2]=U,n=M+8|0,f=a[n+4>>2],t=t+8|0,a[t>>2]=a[n>>2],a[t+4>>2]=f,t=S+8|0,n=a[t+4>>2],i=i+8|0,a[i>>2]=a[t>>2],a[i+4>>2]=n,i=a[W+4>>2],a[r+112>>2]=a[W>>2],a[r+116>>2]=i,t=e+688|0,n=a[t+4>>2],i=r+40|0,a[i>>2]=a[t>>2],a[i+4>>2]=n,i=e+680|0,t=a[i+4>>2],a[r+32>>2]=a[i>>2],a[r+36>>2]=t,t=e+704|0,n=a[t+4>>2],i=r+24|0,a[i>>2]=a[t>>2],a[i+4>>2]=n,e=e+696|0,i=a[e+4>>2],a[r+16>>2]=a[e>>2],a[r+20>>2]=i,A=0|Qt[a[a[A>>2]+20>>2]](A),e=r+8|0,a[e>>2]=0,a[e+4>>2]=0,a[r>>2]=0,a[r+4>>2]=0,Qt[a[a[A>>2]+80>>2]](A,r+32|0,r+16|0,r+112|0,r);break A;case 8:if(t=e+1244|0,n=a[t+4>>2],c=r+120|0,i=c,a[i>>2]=a[t>>2],a[i+4>>2]=n,t=e+1260|0,n=a[t+4>>2],i=r+136|0,a[i>>2]=a[t>>2],a[i+4>>2]=n,t=e+1276|0,n=a[t+4>>2],i=r+152|0,a[i>>2]=a[t>>2],a[i+4>>2]=n,t=e+1292|0,n=a[t+4>>2],i=r+168|0,a[i>>2]=a[t>>2],a[i+4>>2]=n,W=e+1236|0,i=W,t=a[i+4>>2],a[r+112>>2]=a[i>>2],a[r+116>>2]=t,U=e+1252|0,i=U,t=a[i+4>>2],a[r+128>>2]=a[i>>2],a[r+132>>2]=t,M=e+1268|0,i=M,t=a[i+4>>2],a[r+144>>2]=a[i>>2],a[r+148>>2]=t,S=e+1284|0,i=S,t=a[i+4>>2],a[r+160>>2]=a[i>>2],a[r+164>>2]=t,i=r+160|0,t=r+144|0,n=r+128|0,f?(f=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[f>>2]+64>>2]](f,r+112|0,w),v=e+1356|0,N=a[v+4>>2],f=i+8|0,a[f>>2]=a[v>>2],a[f+4>>2]=N,f=e+1348|0,v=a[f+4>>2],a[i>>2]=a[f>>2],a[i+4>>2]=v,f=e+1316|0,v=a[f+4>>2],a[n>>2]=a[f>>2],a[n+4>>2]=v,v=e+1324|0,N=a[v+4>>2],f=n+8|0,a[f>>2]=a[v>>2],a[f+4>>2]=N,f=e+1332|0,v=a[f+4>>2],a[t>>2]=a[f>>2],a[t+4>>2]=v,v=e+1340|0,N=a[v+4>>2],f=t+8|0,a[f>>2]=a[v>>2],a[f+4>>2]=N,f=e+1308|0,v=a[f+4>>2],a[c>>2]=a[f>>2],a[c+4>>2]=v,f=e+1300|0,c=a[f+4>>2],a[r+112>>2]=a[f>>2],a[r+116>>2]=c,f=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[f>>2]+64>>2]](f,r+112|0,w)):(f=e+1308|0,v=a[f+4>>2],a[c>>2]=a[f>>2],a[c+4>>2]=v,f=e+1316|0,c=a[f+4>>2],a[n>>2]=a[f>>2],a[n+4>>2]=c,c=e+1324|0,v=a[c+4>>2],f=n+8|0,a[f>>2]=a[c>>2],a[f+4>>2]=v,f=e+1332|0,c=a[f+4>>2],a[t>>2]=a[f>>2],a[t+4>>2]=c,c=e+1340|0,v=a[c+4>>2],f=t+8|0,a[f>>2]=a[c>>2],a[f+4>>2]=v,f=e+1348|0,c=a[f+4>>2],a[i>>2]=a[f>>2],a[i+4>>2]=c,c=e+1356|0,v=a[c+4>>2],f=i+8|0,a[f>>2]=a[c>>2],a[f+4>>2]=v,f=e+1300|0,c=a[f+4>>2],a[r+112>>2]=a[f>>2],a[r+116>>2]=c),!s)break A;f=a[U+4>>2],a[n>>2]=a[U>>2],a[n+4>>2]=f,f=a[M+4>>2],a[t>>2]=a[M>>2],a[t+4>>2]=f,f=a[S+4>>2],a[i>>2]=a[S>>2],a[i+4>>2]=f,c=W+8|0,v=a[c+4>>2],s=r+120|0,f=s,Z=a[c>>2],a[f>>2]=Z,a[f+4>>2]=v,v=U+8|0,N=a[v+4>>2],c=n+8|0,f=c,a[f>>2]=a[v>>2],a[f+4>>2]=N,N=M+8|0,O=a[N+4>>2],v=t+8|0,f=v,a[f>>2]=a[N>>2],a[f+4>>2]=O,O=S+8|0,P=a[O+4>>2],N=i+8|0,f=N,a[f>>2]=a[O>>2],a[f+4>>2]=P,f=a[W+4>>2],a[r+112>>2]=a[W>>2],a[r+116>>2]=f,a[r+96>>2]=Z,a[r+100>>2]=a[r+136>>2],a[r+108>>2]=0,a[r+104>>2]=a[r+152>>2],a[r+80>>2]=a[r+112>>2],a[r+84>>2]=a[r+128>>2],a[r+92>>2]=0,a[r+88>>2]=a[r+144>>2],b=C[e+1060>>2],l=C[e+1144>>2],u=C[e+1148>>2],k=C[e+1056>>2],Z=0|Qt[a[a[A>>2]+20>>2]](A),f=r+72|0,a[f>>2]=0,a[f+4>>2]=0,a[r+64>>2]=0,a[r+68>>2]=0,f=e+1348|0,Qt[a[a[Z>>2]+72>>2]](Z,f,r+96|0,r+80|0,_(w*_(.8999999761581421)),k,b,l,u,r- -64|0,_(10),1),a[r+92>>2]=0,Z=r+148|0,k=C[Z>>2],a[r+88>>2]=a[Z>>2],Z=r+132|0,b=C[Z>>2],a[r+84>>2]=a[Z>>2],l=C[r+116>>2],a[r+80>>2]=a[r+116>>2],g=C[e+1368>>2],B=C[e+1372>>2],Z=e+1308|0,O=a[Z+4>>2],a[s>>2]=a[Z>>2],a[s+4>>2]=O,s=e+1316|0,Z=a[s+4>>2],a[n>>2]=a[s>>2],a[n+4>>2]=Z,s=e+1324|0,Z=a[s+4>>2],a[c>>2]=a[s>>2],a[c+4>>2]=Z,s=e+1332|0,c=a[s+4>>2],a[t>>2]=a[s>>2],a[t+4>>2]=c,s=e+1340|0,c=a[s+4>>2],a[v>>2]=a[s>>2],a[v+4>>2]=c,s=a[f+4>>2],a[i>>2]=a[f>>2],a[i+4>>2]=s,s=e+1356|0,c=a[s+4>>2],a[N>>2]=a[s>>2],a[N+4>>2]=c,s=e+1300|0,c=a[s+4>>2],a[r+112>>2]=a[s>>2],a[r+116>>2]=c,u=dr(B),B=Cr(B),C[r+68>>2]=_(B*b)-_(u*l),d=dr(g),g=Cr(g),C[r+72>>2]=_(_(_(B*d)*l)+_(_(d*u)*b))+_(g*k),C[r+64>>2]=_(_(_(g*B)*l)+_(_(g*u)*b))-_(d*k),a[r+60>>2]=0,C[r+56>>2]=-C[r+144>>2],C[r+52>>2]=-C[r+128>>2],C[r+48>>2]=-C[r+112>>2],b=C[e+968>>2],l=C[e+972>>2],b>l?(s=0|Qt[a[a[A>>2]+20>>2]](A),c=r+40|0,a[c>>2]=0,a[c+4>>2]=0,a[r+32>>2]=0,a[r+36>>2]=0,Qt[a[a[s>>2]+68>>2]](s,f,r+48|0,r- -64|0,w,w,_(-3.1415927410125732),_(3.1415927410125732),r+32|0,0,_(10))):b>2]+20>>2]](A),c=r+40|0,a[c>>2]=0,a[c+4>>2]=0,a[r+32>>2]=0,a[r+36>>2]=0,Qt[a[a[s>>2]+68>>2]](s,f,r+48|0,r- -64|0,w,w,b,l,r+32|0,1,_(10))),f=a[U+4>>2],a[n>>2]=a[U>>2],a[n+4>>2]=f,f=a[M+4>>2],a[t>>2]=a[M>>2],a[t+4>>2]=f,f=a[S+4>>2],a[i>>2]=a[S>>2],a[i+4>>2]=f,s=W+8|0,c=a[s+4>>2],f=r+120|0,a[f>>2]=a[s>>2],a[f+4>>2]=c,f=U+8|0,U=a[f+4>>2],n=n+8|0,a[n>>2]=a[f>>2],a[n+4>>2]=U,n=M+8|0,f=a[n+4>>2],t=t+8|0,a[t>>2]=a[n>>2],a[t+4>>2]=f,t=S+8|0,n=a[t+4>>2],i=i+8|0,a[i>>2]=a[t>>2],a[i+4>>2]=n,i=a[W+4>>2],a[r+112>>2]=a[W>>2],a[r+116>>2]=i,t=e+688|0,n=a[t+4>>2],i=r+40|0,a[i>>2]=a[t>>2],a[i+4>>2]=n,i=e+680|0,t=a[i+4>>2],a[r+32>>2]=a[i>>2],a[r+36>>2]=t,t=e+704|0,n=a[t+4>>2],i=r+24|0,a[i>>2]=a[t>>2],a[i+4>>2]=n,e=e+696|0,i=a[e+4>>2],a[r+16>>2]=a[e>>2],a[r+20>>2]=i,A=0|Qt[a[a[A>>2]+20>>2]](A),e=r+8|0,a[e>>2]=0,a[e+4>>2]=0,a[r>>2]=0,a[r+4>>2]=0,Qt[a[a[A>>2]+80>>2]](A,r+32|0,r+16|0,r+112|0,r);break A;case 4:case 6:case 7:break A;case 3:}t=e+832|0,n=a[t+4>>2],W=r+120|0,i=W,a[i>>2]=a[t>>2],a[i+4>>2]=n,t=e+848|0,n=a[t+4>>2],i=r+136|0,a[i>>2]=a[t>>2],a[i+4>>2]=n,t=e+864|0,n=a[t+4>>2],i=r+152|0,a[i>>2]=a[t>>2],a[i+4>>2]=n,t=e+880|0,n=a[t+4>>2],i=r+168|0,a[i>>2]=a[t>>2],a[i+4>>2]=n,U=e+824|0,i=U,t=a[i+4>>2],a[r+112>>2]=a[i>>2],a[r+116>>2]=t,i=e+840|0,t=a[i+4>>2],a[r+128>>2]=a[i>>2],a[r+132>>2]=t,i=e+856|0,t=a[i+4>>2],a[r+144>>2]=a[i>>2],a[r+148>>2]=t,i=e+872|0,t=a[i+4>>2],a[r+160>>2]=a[i>>2],a[r+164>>2]=t,i=r+160|0,t=r+144|0,n=r+128|0,f?(f=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[f>>2]+64>>2]](f,r+112|0,w),M=e+944|0,S=a[M+4>>2],f=i+8|0,a[f>>2]=a[M>>2],a[f+4>>2]=S,f=e+936|0,M=a[f+4>>2],a[i>>2]=a[f>>2],a[i+4>>2]=M,i=e+904|0,f=a[i+4>>2],a[n>>2]=a[i>>2],a[n+4>>2]=f,i=n+8|0,n=e+912|0,f=a[n+4>>2],a[i>>2]=a[n>>2],a[i+4>>2]=f,i=e+920|0,n=a[i+4>>2],a[t>>2]=a[i>>2],a[t+4>>2]=n,i=t+8|0,t=e+928|0,n=a[t+4>>2],a[i>>2]=a[t>>2],a[i+4>>2]=n,i=e+896|0,t=a[i+4>>2],a[W>>2]=a[i>>2],a[W+4>>2]=t,i=e+888|0,t=a[i+4>>2],a[r+112>>2]=a[i>>2],a[r+116>>2]=t,i=0|Qt[a[a[A>>2]+20>>2]](A),Qt[a[a[i>>2]+64>>2]](i,r+112|0,w)):(f=e+896|0,M=a[f+4>>2],a[W>>2]=a[f>>2],a[W+4>>2]=M,f=e+904|0,W=a[f+4>>2],a[n>>2]=a[f>>2],a[n+4>>2]=W,f=e+912|0,W=a[f+4>>2],n=n+8|0,a[n>>2]=a[f>>2],a[n+4>>2]=W,n=e+920|0,f=a[n+4>>2],a[t>>2]=a[n>>2],a[t+4>>2]=f,n=e+928|0,f=a[n+4>>2],t=t+8|0,a[t>>2]=a[n>>2],a[t+4>>2]=f,t=e+936|0,n=a[t+4>>2],a[i>>2]=a[t>>2],a[i+4>>2]=n,t=e+944|0,n=a[t+4>>2],i=i+8|0,a[i>>2]=a[t>>2],a[i+4>>2]=n,i=e+888|0,t=a[i+4>>2],a[r+112>>2]=a[i>>2],a[r+116>>2]=t),s&&(t=o[e+180|0],i=t?U:e+888|0,b=C[i+48>>2],m=C[i+8>>2],R=C[i+4>>2],n=a[i+4>>2],l=C[i+52>>2],h=C[i+24>>2],u=C[i+16>>2],f=a[i+16>>2],G=C[i+20>>2],W=a[i+20>>2],k=C[i+56>>2],d=C[i+40>>2],g=C[i+32>>2],U=a[i+32>>2],y=C[i+36>>2],M=a[i+36>>2],i=(t?824:888)+e|0,B=C[i>>2],t=a[i>>2],a[r+108>>2]=0,V=_(d*_(0)),y=_(y*_(0)),d=C[e+184>>2],C[r+104>>2]=k+_(V+_(y+_(d*g))),h=_(h*_(0)),G=_(G*_(0)),C[r+100>>2]=l+_(h+_(G+_(d*u))),m=_(m*_(0)),R=_(R*_(0)),C[r+96>>2]=b+_(m+_(R+_(d*B))),a[r+92>>2]=0,Q=k,k=C[e+188>>2],C[r+88>>2]=Q+_(V+_(y+_(k*g))),C[r+84>>2]=l+_(h+_(G+_(k*u))),C[r+80>>2]=b+_(m+_(R+_(k*B))),i=0|Qt[a[a[A>>2]+20>>2]](A),S=r+72|0,a[S>>2]=0,a[S+4>>2]=0,a[r+64>>2]=0,a[r+68>>2]=0,Qt[a[a[i>>2]+16>>2]](i,r+96|0,r+80|0,r- -64|0),a[r+76>>2]=0,a[r+72>>2]=U,a[r+68>>2]=f,a[r+64>>2]=t,a[r+60>>2]=0,a[r+56>>2]=M,a[r+52>>2]=W,a[r+48>>2]=n,b=C[e+196>>2],l=C[e+192>>2],A=0|Qt[a[a[A>>2]+20>>2]](A),i=r+40|0,a[i>>2]=0,a[i+4>>2]=0,a[r+32>>2]=0,a[r+36>>2]=0,Qt[a[a[A>>2]+68>>2]](A,e+936|0,r- -64|0,r+48|0,w,w,l,b,r+32|0,1,_(10)))}Y=r+176|0},function(A){A|=0;var e=0,r=0,i=0,f=0,t=0;if(e=a[A+248>>2],(0|e)>=1)for(;;){A:{e:if(i=a[a[A+256>>2]+r>>2],f=a[i+220>>2]+-2|0,!(f>>>0>3))switch(f-1|0){case 0:case 1:break e;default:break A}Ti(i),e=a[A+248>>2]}if(r=r+4|0,t=t+1|0,!((0|t)<(0|e)))break}},Rr,function(A,e){A|=0,e=_(e);var r,i=0,f=0,t=0;if(r=Y-16|0,Y=r,Lr(r+8|0,23392),a[A+296>>2]>=1)for(;f=a[a[A+304>>2]+i>>2],Qt[a[a[f>>2]+8>>2]](f,A,e),i=i+4|0,t=t+1|0,(0|t)>2];);qr(),Y=r+16|0},function(A){A|=0;var e=0;return a[A>>2]=23768,e=a[A+80>>2],e&&(o[A+84|0]&&CA(e),a[A+80>>2]=0),a[A+80>>2]=0,a[A+72>>2]=0,a[A+76>>2]=0,f[A+84|0]=1,e=a[A+60>>2],e&&(o[A- -64|0]&&CA(e),a[A+60>>2]=0),a[A+60>>2]=0,a[A+52>>2]=0,a[A+56>>2]=0,f[A- -64|0]=1,e=a[A+40>>2],e&&(o[A+44|0]&&CA(e),a[A+40>>2]=0),a[A+40>>2]=0,a[A+32>>2]=0,a[A+36>>2]=0,f[A+44|0]=1,0|A},function(A){A|=0;var e=0;a[A>>2]=23768,e=a[A+80>>2],e&&(o[A+84|0]&&CA(e),a[A+80>>2]=0),a[A+80>>2]=0,a[A+72>>2]=0,a[A+76>>2]=0,f[A+84|0]=1,e=a[A+60>>2],e&&(o[A- -64|0]&&CA(e),a[A+60>>2]=0),a[A+60>>2]=0,a[A+52>>2]=0,a[A+56>>2]=0,f[A- -64|0]=1,e=a[A+40>>2],!e|!o[A+44|0]||CA(e),$(A)},function(A,e,r,i,t,n){A|=0,e|=0,r|=0,i|=0,t|=0,n|=0;var c=0,b=0,l=0,u=0,s=0,k=0,v=0,d=0;if(!((0|n)>=0))return n=a[A+8>>2],void _(Qt[a[a[n>>2]+12>>2]](n,e,r,i,t,a[A+12>>2],a[A+16>>2],a[A+4>>2],a[A+20>>2],a[A+24>>2]));u=a[A+16>>2];A:{if((0|u)>=1)for(k=a[A+12>>2];;){if(l=a[k>>2],c=a[a[l+28>>2]+208>>2],(0|c)<=-1&&(c=a[a[l+32>>2]+208>>2]),(0|c)==(0|n))break A;if(k=k+4|0,b=b+1|0,!((0|b)<(0|u)))break}k=0}if((0|b)<(0|u))for(l=u-b|0,c=a[A+12>>2]+(b<<2)|0;u=a[c>>2],b=a[a[u+28>>2]+208>>2],(0|b)<=-1&&(b=a[a[u+32>>2]+208>>2]),c=c+4|0,v=((0|n)==(0|b))+v|0,l=l+-1|0,l;);if(n=a[A+4>>2],a[n+80>>2]<2)c=a[A+8>>2],_(Qt[a[a[c>>2]+12>>2]](c,e,r,i,t,k,v,n,a[A+20>>2],a[A+24>>2]));else{if(!((0|r)<1))for(c=a[A+36>>2],b=a[A+32>>2];;){if(d=(s<<2)+e|0,(0|c)==(0|b))if(u=c?c<<1:1,(0|c)>=(0|u))n=c;else{if(u?(l=dA(u<<2),n=a[A+32>>2]):(l=0,n=c),(0|n)>=1)for(c=0,b=n;a[c+l>>2]=a[a[A+40>>2]+c>>2],c=c+4|0,b=b+-1|0,b;);c=a[A+40>>2],c&&(o[A+44|0]&&(CA(c),n=a[A+32>>2]),a[A+40>>2]=0),a[A+40>>2]=l,f[A+44|0]=1,a[A+36>>2]=u,c=u}else n=b;if(b=n+1|0,a[A+32>>2]=b,a[a[A+40>>2]+(n<<2)>>2]=a[d>>2],s=s+1|0,(0|s)==(0|r))break}if((0|t)>=1)for(c=a[A+56>>2],b=a[A+52>>2],s=0;;){if(r=(s<<2)+i|0,(0|c)==(0|b))if(e=c?c<<1:1,(0|c)>=(0|e))n=c;else{if(e?(l=dA(e<<2),n=a[A+52>>2]):(l=0,n=c),(0|n)>=1)for(c=0,b=n;a[c+l>>2]=a[a[A+60>>2]+c>>2],c=c+4|0,b=b+-1|0,b;);c=a[A+60>>2],c&&(o[A+64|0]&&(CA(c),n=a[A+52>>2]),a[A+60>>2]=0),a[A+60>>2]=l,f[A+64|0]=1,a[A+56>>2]=e,c=e}else n=b;if(b=n+1|0,a[A+52>>2]=b,a[a[A+60>>2]+(n<<2)>>2]=a[r>>2],s=s+1|0,(0|s)==(0|t))break}if(v)for(c=a[A+76>>2],b=a[A+72>>2],s=0;;){if(r=(s<<2)+k|0,(0|c)==(0|b))if(e=c?c<<1:1,(0|c)>=(0|e))n=c;else{if(e?(l=dA(e<<2),n=a[A+72>>2]):(l=0,n=c),(0|n)>=1)for(c=0,b=n;a[c+l>>2]=a[a[A+80>>2]+c>>2],c=c+4|0,b=b+-1|0,b;);i=a[A+80>>2],i&&(o[A+84|0]&&(CA(i),n=a[A+72>>2]),a[A+80>>2]=0),a[A+80>>2]=l,f[A+84|0]=1,a[A+76>>2]=e,c=e}else n=b;if(b=n+1|0,a[A+72>>2]=b,a[a[A+80>>2]+(n<<2)>>2]=a[r>>2],s=s+1|0,(0|v)==(0|s))break}else b=a[A+72>>2];(a[A+52>>2]+b|0)>a[a[A+4>>2]+80>>2]&&Uf(A)}},ve,function(A,e){A|=0,e|=0;var r,i,f=0;return r=a[e>>2],i=a[A+84>>2],!(a[e+8>>2]&a[A+8>>2])|!(a[A+12>>2]&a[e+4>>2])|(0|r)==(0|i)||(A=a[A+96>>2],f=0|Qt[a[a[A>>2]+28>>2]](A,i,r)),0|f},function(A,e,r){A|=0,e|=0,r|=0;var i=0,f=_(0),t=_(0),n=_(0),c=0,b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0);return f=_(1),i=a[e>>2],(0|i)==a[A+84>>2]|4&o[i+204|0]|_(_(_(_(C[A+32>>2]-C[A+16>>2])*C[e+8>>2])+_(_(C[A+36>>2]-C[A+20>>2])*C[e+12>>2]))+_(_(C[A+40>>2]-C[A+24>>2])*C[e+16>>2]))>=_(-C[A+88>>2])||(a[A+80>>2]=i,a[A+4>>2]=a[e+40>>2],r?(r=e+8|0,i=a[r+4>>2],a[A+48>>2]=a[r>>2],a[A+52>>2]=i,r=r+8|0,c=a[r+4>>2],i=A+56|0,a[i>>2]=a[r>>2],a[i+4>>2]=c):(b=C[i+12>>2],l=C[i+8>>2],u=C[i+28>>2],s=C[i+20>>2],k=C[i+24>>2],v=C[i+44>>2],d=C[i+36>>2],g=C[i+40>>2],B=C[i+4>>2],f=C[e+16>>2],t=C[e+8>>2],n=C[e+12>>2],a[A+60>>2]=0,C[A+56>>2]=_(_(t*d)+_(n*g))+_(f*v),C[A+52>>2]=_(_(t*s)+_(n*k))+_(f*u),C[A+48>>2]=_(_(B*t)+_(l*n))+_(b*f)),r=a[e+28>>2],a[A+64>>2]=a[e+24>>2],a[A+68>>2]=r,r=e+32|0,i=a[r+4>>2],A=A+72|0,a[A>>2]=a[r>>2],a[A+4>>2]=i,f=C[e+40>>2]),_(f)},function(A){var e;return A|=0,a[A>>2]=23960,e=a[A+336>>2],e&&(o[A+340|0]&&CA(e),a[A+336>>2]=0),a[A+336>>2]=0,a[A+328>>2]=0,a[A+332>>2]=0,f[A+340|0]=1,Ze(A),0|A},function(A){var e;A|=0,a[A>>2]=23960,e=a[A+336>>2],e&&(o[A+340|0]&&CA(e),a[A+336>>2]=0),a[A+336>>2]=0,a[A+328>>2]=0,a[A+332>>2]=0,f[A+340|0]=1,Ze(A),CA(A)},function(A,e,r){A|=0,e|=0,r|=0;var i,t=0,n=0,c=0;i=a[e>>2],r=a[A+328>>2];A:{e:if(!((0|r)<1)){for(e=a[A+336>>2],t=r;;){if((0|i)!=a[e>>2]){if(e=e+4|0,t=t+-1|0,t)continue;break e}break}if(t)break A}if(a[A+332>>2]==(0|r)&&(n=r?r<<1:1,!((0|r)>=(0|n)))){if(n&&(c=dA(n<<2),r=a[A+328>>2]),(0|r)>=1)for(e=0,t=r;a[e+c>>2]=a[a[A+336>>2]+e>>2],e=e+4|0,t=t+-1|0,t;);e=a[A+336>>2],e&&(o[A+340|0]&&(CA(e),r=a[A+328>>2]),a[A+336>>2]=0),a[A+336>>2]=c,a[A+332>>2]=n,f[A+340|0]=1}a[A+328>>2]=r+1,a[a[A+336>>2]+(r<<2)>>2]=i}},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f=0,t=0;r=a[A+328>>2];A:if(!((0|r)<1)){for(t=a[e>>2],i=0,f=a[A+336>>2],e=f;;){if((0|t)!=a[e>>2]){if(e=e+4|0,i=i+1|0,(0|i)!=(0|r))continue;break A}break}(0|i)>=(0|r)||(i=A,A=r+-1|0,a[i+328>>2]=A,a[e>>2]=a[(A<<2)+f>>2])}},function(A){A|=0;var e=0;return a[A>>2]=24004,e=a[A+344>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+344>>2]),a[A>>2]=23960,e=a[A+336>>2],e&&(o[A+340|0]&&CA(e),a[A+336>>2]=0),a[A+336>>2]=0,a[A+328>>2]=0,a[A+332>>2]=0,f[A+340|0]=1,Ze(A),0|A},function(A){A|=0;var e=0;a[A>>2]=24004,e=a[A+344>>2],Qt[a[a[e>>2]>>2]](e),CA(a[A+344>>2]),a[A>>2]=23960,e=a[A+336>>2],e&&(o[A+340|0]&&CA(e),a[A+336>>2]=0),a[A+336>>2]=0,a[A+328>>2]=0,a[A+332>>2]=0,f[A+340|0]=1,Ze(A),CA(A)},function(A,e,r){A|=0,e|=0,r|=0;var i,t=0,n=0,c=0,b=0,l=0;r=r||a[A+188>>2],i=a[e>>2],t=a[A+328>>2];A:{e:if(!((0|t)<1)){for(c=a[A+336>>2],n=t;;){if((0|i)!=a[c>>2]){if(c=c+4|0,n=n+-1|0,n)continue;break e}break}if(n)break A}if(a[A+332>>2]==(0|t)&&(b=t?t<<1:1,!((0|t)>=(0|b)))){if(b&&(l=dA(b<<2),t=a[A+328>>2]),(0|t)>=1)for(c=0,n=t;a[c+l>>2]=a[a[A+336>>2]+c>>2],c=c+4|0,n=n+-1|0,n;);n=a[A+336>>2],n&&(o[A+340|0]&&(CA(n),t=a[A+328>>2]),a[A+336>>2]=0),a[A+336>>2]=l,a[A+332>>2]=b,f[A+340|0]=1}a[a[A+336>>2]+(t<<2)>>2]=i,a[A+328>>2]=t+1,A=a[A+344>>2],Qt[a[a[A>>2]+8>>2]](A,r,e)}},function(A,e,r,i){A|=0,e|=0,r|=0,i|=0;var f,t,n=0,o=0,c=0;t=a[e>>2],i=i||a[A+188>>2],f=a[A+328>>2];A:if(!((0|f)<1)){for(c=a[A+336>>2],n=c;;){if((0|t)!=a[n>>2]){if(n=n+4|0,o=o+1|0,(0|o)!=(0|f))continue;break A}break}(0|o)>=(0|f)||(o=n,n=f+-1|0,a[o>>2]=a[(n<<2)+c>>2],a[A+328>>2]=n,A=a[A+344>>2],Qt[a[a[A>>2]+12>>2]](A,i,e,r))}},function(A){var e;return A|=0,a[A>>2]=24116,e=a[A+212>>2],e&&(o[A+216|0]&&CA(e),a[A+212>>2]=0),a[A+212>>2]=0,a[A+204>>2]=0,a[A+208>>2]=0,f[A+216|0]=1,0|A},function(A){var e;A|=0,a[A>>2]=24116,e=a[A+212>>2],e&&(o[A+216|0]&&CA(e),a[A+212>>2]=0),a[A+212>>2]=0,a[A+204>>2]=0,a[A+208>>2]=0,f[A+216|0]=1,CA(A)},function(A,e,r){A|=0,e|=0,r=_(r),Qt[a[a[A>>2]+32>>2]](A,e),Qt[a[a[A>>2]+36>>2]](A,e,r)},Rr,function(A,e){A|=0,e|=0;var r,i=_(0),t=_(0),n=_(0),o=_(0),c=0;f[A+251|0]=1,c=a[e+4>>2],a[A+68>>2]=a[e>>2],a[A+72>>2]=c,e=e+8|0,r=a[e+4>>2],c=A+76|0,a[c>>2]=a[e>>2],a[c+4>>2]=r,i=C[A+68>>2],t=C[A+72>>2],n=C[c>>2],o=_(y(_(_(_(i*i)+_(t*t))+_(n*n)))),o>_(1.1920928955078125e-7)?(o=_(_(1)/o),n=_(n*o),t=_(t*o),i=_(i*o),e=a[A+80>>2]):(i=_(0),t=_(0),n=_(0),e=0),C[A+84>>2]=i,a[A+96>>2]=e,C[A+92>>2]=n,C[A+88>>2]=t},function(A,e,r){A|=0,e|=0,r=_(r);var i,t=0,n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=0;f[A+251|0]=0,t=a[e+4>>2],a[A+68>>2]=a[e>>2],a[A+72>>2]=t,e=e+8|0,i=a[e+4>>2],t=A+76|0,a[t>>2]=a[e>>2],a[t+4>>2]=i,o=C[A+68>>2],c=C[A+72>>2],b=C[t>>2],l=_(y(_(_(_(o*o)+_(c*c))+_(b*b)))),l>_(1.1920928955078125e-7)&&(n=_(_(1)/l),u=_(b*n),s=_(c*n),n=_(o*n),k=a[A+80>>2]),C[A+84>>2]=n,a[A+96>>2]=k,C[A+92>>2]=u,C[A+88>>2]=s,C[A+252>>2]=C[A+252>>2]+r},function(A,e){A|=0,e|=0;var r,i=0,f=0,n=0,o=0,c=0;if(a[A+68>>2]=0,a[A+72>>2]=0,r=A+76|0,a[r>>2]=0,a[r+4>>2]=0,a[A+252>>2]=0,t[A+248>>1]=0,a[A+20>>2]=0,a[A+24>>2]=0,A=a[a[A+8>>2]+344>>2],a[4+(0|Qt[a[a[A>>2]+28>>2]](A))>>2]>=1)for(;f=A,n=a[a[12+(0|Qt[a[a[A>>2]+28>>2]](A))>>2]>>2],o=a[a[12+(0|Qt[a[a[A>>2]+28>>2]](A))>>2]+4>>2],c=a[e+24>>2],i=a[a[A>>2]+12>>2],Qt[i](0|f,0|n,0|o,0|c),a[4+(0|Qt[a[a[A>>2]+28>>2]](A))>>2]>0;);},function(A,e){A|=0,e|=0;var r,i,f=0,t=0;t=e+8|0,r=a[t>>2],t=a[t+4>>2],i=a[e>>2],e=a[e+4>>2],A=a[A+8>>2],f=A+44|0,a[f>>2]=1065353216,a[f+4>>2]=0,f=A+36|0,a[f>>2]=0,a[f+4>>2]=0,a[A+24>>2]=1065353216,f=A+28|0,a[f>>2]=0,a[f+4>>2]=0,f=A+16|0,a[f>>2]=0,a[f+4>>2]=0,a[A+4>>2]=1065353216,f=A+8|0,a[f>>2]=0,a[f+4>>2]=0,f=A+60|0,a[f>>2]=r,a[f+4>>2]=t,t=A+52|0,a[t>>2]=i,a[t+4>>2]=e,a[A+304>>2]=a[A+304>>2]+1},function(A,e){A|=0,e|=0;var r,i=0,f=0,t=0,n=0,o=0;e=Y-16|0,Y=e,t=a[A+8>>2],i=t+52|0,n=a[i+4>>2],a[A+132>>2]=a[i>>2],a[A+136>>2]=n,f=t+60|0,o=a[f+4>>2],n=A+140|0,a[n>>2]=a[f>>2],a[n+4>>2]=o,n=a[i>>2],i=a[i+4>>2],o=a[f+4>>2],r=A+160|0,a[r>>2]=a[f>>2],a[r+4>>2]=o,a[A+152>>2]=n,a[A+156>>2]=i,tt(t+4|0,e),f=e+8|0,n=a[f+4>>2],t=A+176|0,i=t,a[i>>2]=a[f>>2],a[i+4>>2]=n,i=a[e+4>>2],a[A+168>>2]=a[e>>2],a[A+172>>2]=i,f=a[t+4>>2],i=A+192|0,a[i>>2]=a[t>>2],a[i+4>>2]=f,t=a[A+172>>2],a[A+184>>2]=a[A+168>>2],a[A+188>>2]=t,Y=e+16|0},function(A,e,r){A|=0,e|=0,r=_(r);var i,t=0,n=0,c=0,b=_(0),l=0,u=_(0),s=_(0),k=0,v=_(0),d=_(0),g=_(0),B=0,R=0,Q=_(0),h=_(0),G=_(0),p=_(0),F=0,W=_(0),w=0,D=0,E=0,Z=0,V=0,N=0,I=0,J=0,x=0;i=Y-80|0,Y=i,b=C[A+100>>2],u=C[A+104>>2],v=C[A+108>>2],s=_(_(_(b*b)+_(u*u))+_(v*v)),s>_(0)&&(s=Vi(_(_(1)-C[A+244>>2]),r),v=_(v*s),C[A+108>>2]=v,u=_(u*s),C[A+104>>2]=u,b=_(b*s),C[A+100>>2]=b,s=_(_(_(b*b)+_(u*u))+_(v*v))),s>_(0)&&(t=a[A+8>>2],c=t+12|0,l=a[c>>2],B=a[c+4>>2],k=a[t+4>>2],R=a[t+8>>2],F=t+28|0,w=a[F+4>>2],c=i+40|0,n=c,a[n>>2]=a[F>>2],a[n+4>>2]=w,n=i+24|0,a[n>>2]=l,a[n+4>>2]=B,l=t+36|0,F=a[l>>2],w=a[l+4>>2],l=t+20|0,E=a[l>>2],Z=a[l+4>>2],l=t+44|0,V=a[l>>2],N=a[l+4>>2],D=t+60|0,I=a[D+4>>2],B=i+72|0,l=B,a[l>>2]=a[D>>2],a[l+4>>2]=I,l=i+56|0,a[l>>2]=V,a[l+4>>2]=N,a[i+16>>2]=k,a[i+20>>2]=R,a[i+32>>2]=E,a[i+36>>2]=Z,t=t+52|0,k=a[t+4>>2],a[i+64>>2]=a[t>>2],a[i+68>>2]=k,a[i+48>>2]=F,a[i+52>>2]=w,g=_(y(s)),Q=_(_(g*r)*_(.5)),h=dr(Q),tt(i+16|0,i),s=C[i+12>>2],G=C[i>>2],Q=Cr(Q),d=b,b=_(_(1)/g),g=_(d*b),d=_(v*b),b=_(u*b),u=_(h/_(y(_(_(d*d)+_(_(g*g)+_(b*b)))))),v=_(g*u),g=_(b*u),h=C[i+8>>2],d=_(d*u),p=C[i+4>>2],b=_(_(_(_(G*Q)+_(s*v))+_(g*h))-_(d*p)),u=_(_(_(_(Q*s)-_(v*G))-_(g*p))-_(d*h)),W=_(_(_(_(d*s)+_(Q*h))+_(v*p))-_(g*G)),v=_(_(_(d*G)+_(_(g*s)+_(Q*p)))-_(v*h)),s=_(_(2)/_(_(u*u)+_(_(W*W)+_(_(b*b)+_(v*v))))),G=_(W*s),g=_(b*G),Q=_(v*s),h=_(u*Q),C[n>>2]=g+h,a[i+60>>2]=0,a[i+44>>2]=0,d=_(v*G),s=_(b*s),p=_(u*s),C[i+52>>2]=d+p,C[c>>2]=d-p,s=_(b*s),v=_(v*Q),C[l>>2]=_(1)-_(s+v),d=s,s=_(W*G),C[i+36>>2]=_(1)-_(d+s),a[i+28>>2]=0,C[i+48>>2]=g-h,b=_(b*Q),u=_(u*G),C[i+32>>2]=b+u,C[i+20>>2]=b-u,R=a[n+4>>2],t=a[A+8>>2],k=t+12|0,a[k>>2]=a[n>>2],a[k+4>>2]=R,C[i+16>>2]=_(1)-_(v+s),n=a[i+20>>2],a[t+4>>2]=a[i+16>>2],a[t+8>>2]=n,k=a[i+36>>2],n=t+20|0,a[n>>2]=a[i+32>>2],a[n+4>>2]=k,k=a[c+4>>2],n=t+28|0,a[n>>2]=a[c>>2],a[n+4>>2]=k,a[t+304>>2]=a[t+304>>2]+1,n=a[i+52>>2],c=t+36|0,a[c>>2]=a[i+48>>2],a[c+4>>2]=n,n=a[l+4>>2],c=t+44|0,a[c>>2]=a[l>>2],a[c+4>>2]=n,n=a[B+4>>2],c=t+60|0,a[c>>2]=a[B>>2],a[c+4>>2]=n,c=a[i+68>>2],t=t+52|0,a[t>>2]=a[i+64>>2],a[t+4>>2]=c,t=a[A+8>>2],c=t+52|0,n=c,l=a[n+4>>2],a[A+132>>2]=a[n>>2],a[A+136>>2]=l,n=t+60|0,k=a[n+4>>2],l=A+140|0,a[l>>2]=a[n>>2],a[l+4>>2]=k,l=a[c>>2],c=a[c+4>>2],k=a[n+4>>2],B=A+160|0,a[B>>2]=a[n>>2],a[B+4>>2]=k,a[A+152>>2]=l,a[A+156>>2]=c,tt(t+4|0,i),n=i+8|0,l=a[n+4>>2],t=A+176|0,a[t>>2]=a[n>>2],a[t+4>>2]=l,c=a[i+4>>2],a[A+168>>2]=a[i>>2],a[A+172>>2]=c,n=a[t+4>>2],c=A+192|0,a[c>>2]=a[t>>2],a[c+4>>2]=n,t=a[A+172>>2],a[A+184>>2]=a[A+168>>2],a[A+188>>2]=t),C[A+252>>2]<=_(0)&&!o[A+251|0]||(J=A,x=0|Qt[a[a[A>>2]+48>>2]](A),f[J+248|0]=x,u=C[A+72>>2],v=C[A+68>>2],s=C[A+76>>2],b=Vi(_(_(1)-C[A+240>>2]),r),_(_(_(v*v)+_(u*u))+_(s*s))>_(0)&&(C[A+76>>2]=s*b,C[A+72>>2]=u*b,C[A+68>>2]=v*b),b=_(_(C[A+20>>2]*b)-_(C[A+52>>2]*r)),C[A+20>>2]=b,b>_(0)&&(u=C[A+32>>2],b>u&&(C[A+20>>2]=u,b=u)),b<_(0)&&(u=_(m(C[A+28>>2])),_(m(b))>u&&(b=_(-u),C[A+20>>2]=b)),C[A+24>>2]=b*r,t=a[A+8>>2],n=t+12|0,l=a[n+4>>2],c=i+24|0,a[c>>2]=a[n>>2],a[c+4>>2]=l,n=t+28|0,l=a[n+4>>2],c=i+40|0,a[c>>2]=a[n>>2],a[c+4>>2]=l,n=t+44|0,l=a[n+4>>2],c=i+56|0,a[c>>2]=a[n>>2],a[c+4>>2]=l,n=t+60|0,l=a[n+4>>2],c=i+72|0,a[c>>2]=a[n>>2],a[c+4>>2]=l,c=a[t+8>>2],a[i+16>>2]=a[t+4>>2],a[i+20>>2]=c,c=t+20|0,n=a[c+4>>2],a[i+32>>2]=a[c>>2],a[i+36>>2]=n,c=t+36|0,n=a[c+4>>2],a[i+48>>2]=a[c>>2],a[i+52>>2]=n,t=t+52|0,c=a[t+4>>2],a[i+64>>2]=a[t>>2],a[i+68>>2]=c,function(A,e){var r,i,t,n=0,c=0,b=_(0),l=0,u=0,s=0,k=_(0),v=_(0),d=_(0),g=0,B=_(0),m=_(0),R=0,Q=_(0),h=0,G=0,y=_(0),p=_(0),F=0,W=_(0),w=_(0),D=_(0),E=_(0);r=Y-240|0,Y=r,C[A+20>>2]<_(0)&&(p=C[A+60>>2],c=a[A+60>>2]),F=r+200|0,n=F,a[n>>2]=0,a[n+4>>2]=0,G=r+196|0,a[G>>2]=1065353216,s=r+216|0,n=s,a[n>>2]=1065353216,a[n+4>>2]=0,g=r+136|0,n=g,a[n>>2]=0,a[n+4>>2]=0,h=r+132|0,a[h>>2]=1065353216,i=r+152|0,n=i,a[n>>2]=1065353216,a[n+4>>2]=0,n=A+140|0,R=a[n+4>>2],u=r+232|0,a[u>>2]=a[n>>2],a[u+4>>2]=R,a[r+180>>2]=0,a[r+184>>2]=0,a[r+176>>2]=1065353216,a[r+188>>2]=0,a[r+192>>2]=0,a[r+208>>2]=0,a[r+212>>2]=0,a[r+116>>2]=0,a[r+120>>2]=0,a[r+112>>2]=1065353216,a[r+124>>2]=0,a[r+128>>2]=0,a[r+144>>2]=0,a[r+148>>2]=0,u=a[A+136>>2],a[r+224>>2]=a[A+132>>2],a[r+228>>2]=u,w=C[A+256>>2],b=C[A+24>>2],b=b>_(0)?b:_(0),C[A+152>>2]=_(_(p*w)+C[A+132>>2])+_(C[A+272>>2]*b),D=C[A+260>>2],C[A+156>>2]=_(_(p*D)+C[A+136>>2])+_(b*C[A+276>>2]),a[A+164>>2]=0,u=A+160|0,E=C[A+264>>2],C[u>>2]=_(_(p*E)+C[n>>2])+_(b*C[A+280>>2]),l=a[A+156>>2],t=a[A+152>>2],a[A+132>>2]=t,a[A+136>>2]=l,R=a[u+4>>2],u=a[u>>2],a[n>>2]=u,a[n+4>>2]=R,n=r+168|0,a[n>>2]=u,a[n+4>>2]=R,a[r+160>>2]=t,a[r+164>>2]=l,v=C[A+180>>2],B=C[A+176>>2],k=C[A+172>>2],b=C[A+168>>2],a[r+220>>2]=0,a[r+204>>2]=0,Q=_(_(2)/_(_(_(_(b*b)+_(k*k))+_(B*B))+_(v*v))),y=_(B*Q),d=_(k*y),m=_(b*Q),W=_(v*m),C[r+212>>2]=d+W,C[F>>2]=d-W,d=_(b*m),m=k,k=_(k*Q),Q=_(m*k),C[s>>2]=_(1)-_(d+Q),B=_(B*y),C[G>>2]=_(1)-_(d+B),a[r+188>>2]=0,d=_(b*y),m=_(v*k),C[r+208>>2]=d-m,b=_(b*k),v=_(v*y),C[r+192>>2]=b+v,C[r+184>>2]=d+m,C[r+180>>2]=b-v,C[r+176>>2]=_(1)-_(Q+B),v=C[A+196>>2],B=C[A+192>>2],k=C[A+188>>2],b=C[A+184>>2],a[r+156>>2]=0,a[r+140>>2]=0,Q=_(_(2)/_(_(_(_(b*b)+_(k*k))+_(B*B))+_(v*v))),y=_(B*Q),d=_(k*y),m=_(b*Q),W=_(v*m),C[r+148>>2]=d+W,C[g>>2]=d-W,d=_(b*m),m=k,k=_(k*Q),Q=_(m*k),C[i>>2]=_(1)-_(d+Q),B=_(B*y),C[h>>2]=_(1)-_(d+B),a[r+124>>2]=0,d=_(b*y),m=_(v*k),C[r+144>>2]=d-m,b=_(b*k),v=_(v*y),C[r+128>>2]=b+v,C[r+120>>2]=d+m,C[r+116>>2]=b-v,C[r+112>>2]=_(1)-_(Q+B),n=r+24|0,a[n>>2]=0,a[n+4>>2]=0,n=r+32|0,a[n>>2]=0,a[n+4>>2]=0,n=r+40|0,a[n>>2]=0,a[n+4>>2]=0,a[r+100>>2]=0,C[r+96>>2]=-E,C[r+92>>2]=-D,a[r+16>>2]=0,a[r+20>>2]=0,C[r+88>>2]=-w,a[r+80>>2]=0,a[r+4>>2]=1065353216,a[r>>2]=24320,n=a[A+8>>2],a[r+84>>2]=n,a[r+104>>2]=a[A+48>>2],u=a[n+188>>2],a[r+8>>2]=a[u+4>>2],a[r+12>>2]=a[u+8>>2],o[A+250|0]?Sf(n,a[A+12>>2],r+176|0,r+112|0,r,C[e+56>>2]):_f(e,a[A+12>>2],r+176|0,r+112|0,r,C[e+56>>2]),u=A+152|0,n=A+132|0;A:{e:{r:{if(C[r+4>>2]<_(1)&&(l=a[A+8>>2],!(4&o[l+204|0])&&Qt[a[a[A>>2]+56>>2]](A,l,a[r+80>>2]))){if(_(_(_(C[r+48>>2]*C[A+256>>2])+_(C[r+52>>2]*C[A+260>>2]))+_(C[r+56>>2]*C[A+264>>2]))>_(0)&&(b=C[r+4>>2],C[A+148>>2]=p*b,o[A+288|0]?(p=_(_(1)-b),C[A+132>>2]=_(p*C[A+132>>2])+_(b*C[A+152>>2]),C[A+136>>2]=_(p*C[A+136>>2])+_(b*C[A+156>>2]),C[A+140>>2]=_(p*C[A+140>>2])+_(b*C[A+160>>2])):(c=a[u+4>>2],a[n>>2]=a[u>>2],a[n+4>>2]=c,l=u+8|0,R=a[l+4>>2],c=n+8|0,a[c>>2]=a[l>>2],a[c+4>>2]=R)),F=n+8|0,G=F,s=a[G+4>>2],l=a[A+8>>2],R=l+60|0,c=R,a[c>>2]=a[G>>2],a[c+4>>2]=s,s=a[n+4>>2],G=l+52|0,c=G,a[c>>2]=a[n>>2],a[c+4>>2]=s,c=a[A+8>>2],a[c+304>>2]=a[c+304>>2]+1,g=l+12|0,h=a[g+4>>2],s=c+12|0,a[s>>2]=a[g>>2],a[s+4>>2]=h,s=a[l+8>>2],a[c+4>>2]=a[l+4>>2],a[c+8>>2]=s,g=l+28|0,h=a[g+4>>2],s=c+28|0,a[s>>2]=a[g>>2],a[s+4>>2]=h,g=l+20|0,h=a[g+4>>2],s=c+20|0,a[s>>2]=a[g>>2],a[s+4>>2]=h,g=l+44|0,h=a[g+4>>2],s=c+44|0,a[s>>2]=a[g>>2],a[s+4>>2]=h,l=l+36|0,g=a[l+4>>2],s=c+36|0,a[s>>2]=a[l>>2],a[s+4>>2]=g,s=a[G+4>>2],l=c+52|0,a[l>>2]=a[G>>2],a[l+4>>2]=s,l=a[R+4>>2],c=c+60|0,a[c>>2]=a[R>>2],a[c+4>>2]=l,f[A+220|0]=0,!jf(A,e))break e;if(f[A+220|0]=1,jf(A,e))break r;break e}a[A+148>>2]=c,A=a[u+4>>2],a[n>>2]=a[u>>2],a[n+4>>2]=A,A=n+8|0,e=u+8|0,n=a[e+4>>2],a[A>>2]=a[e>>2],a[A+4>>2]=n;break A}f[A+220|0]=1,jf(A,e)&&(f[A+220|0]=1,jf(A,e)&&(f[A+220|0]=1,jf(A,e)&&(f[A+220|0]=1)))}c=a[A+8>>2],e=c+52|0,l=e,R=a[l+4>>2],a[u>>2]=a[l>>2],a[u+4>>2]=R,c=c+60|0,R=a[c+4>>2],u=u+8|0,a[u>>2]=a[c>>2],a[u+4>>2]=R,u=a[e>>2],e=a[e+4>>2],l=a[c+4>>2],a[F>>2]=a[c>>2],a[F+4>>2]=l,a[n>>2]=u,a[n+4>>2]=e,C[A+24>>2]>_(0)&&(a[A+20>>2]=0,a[A+24>>2]=0,a[A+148>>2]=a[A+60>>2])}Y=r+240|0}(A,e),l=i- -64|0,c=i+48|0,t=i+32|0,o[A+251|0]?Hf(A,e,A+68|0):(b=C[A+252>>2],C[A+252>>2]=b-r,a[i+12>>2]=0,b=b>r?r:b,C[i+8>>2]=b*C[A+76>>2],C[i+4>>2]=b*C[A+72>>2],C[i>>2]=b*C[A+68>>2],Hf(A,e,i)),function(A,e,r){var i,t=_(0),n=0,c=0,b=_(0),l=0,u=_(0),s=0,k=0,v=_(0),d=_(0),g=_(0),B=0,m=_(0),R=_(0),Q=_(0),h=0,G=0,y=_(0),p=_(0),F=_(0),W=0,w=0,D=0,E=0,Z=_(0),V=_(0),N=0,I=0;i=Y-432|0,Y=i,l=A+160|0,c=a[l+4>>2],s=i+232|0,a[s>>2]=a[l>>2],a[s+4>>2]=c,s=a[A+156>>2],a[i+224>>2]=a[A+152>>2],a[i+228>>2]=s,t=C[A+20>>2];A:if(!(t>_(0))){for(t=_((t<_(0)?_(-t):_(0))*r),t>_(0)&&(b=C[A+28>>2],t>b^1|(o[A+249|0]?!o[A+248|0]:0)||(t=b)),s=A+152|0,t=_(t+C[A+148>>2]),y=_(C[A+256>>2]*t),C[A+152>>2]=C[A+152>>2]-y,l=A+156|0,p=_(t*C[A+260>>2]),C[l>>2]=C[l>>2]-p,l=A+160|0,B=l,u=C[l>>2],l=A+264|0,F=_(t*C[l>>2]),C[B>>2]=u-F,c=i+136|0,a[c>>2]=0,a[c+4>>2]=0,c=i+144|0,a[c>>2]=0,a[c+4>>2]=0,c=i+152|0,a[c>>2]=0,a[c+4>>2]=0,n=a[l+4>>2],c=i+208|0,a[c>>2]=a[l>>2],a[c+4>>2]=n,a[i+128>>2]=0,a[i+132>>2]=0,c=a[A+260>>2],a[i+200>>2]=a[A+256>>2],a[i+204>>2]=c,a[i+192>>2]=0,a[i+116>>2]=1065353216,a[i+112>>2]=24320,n=a[A+8>>2],a[i+196>>2]=n,h=a[A+48>>2],a[i+216>>2]=h,c=a[n+188>>2],a[i+120>>2]=a[c+4>>2],a[i+124>>2]=a[c+8>>2],k=i+24|0,a[k>>2]=0,a[k+4>>2]=0,k=i+32|0,a[k>>2]=0,a[k+4>>2]=0,k=i+40|0,a[k>>2]=0,a[k+4>>2]=0,W=a[l+4>>2],k=i+96|0,a[k>>2]=a[l>>2],a[k+4>>2]=W,a[i+80>>2]=0,a[i+4>>2]=1065353216,a[i+16>>2]=0,a[i+20>>2]=0,a[i+84>>2]=n,l=a[A+260>>2],a[i+88>>2]=a[A+256>>2],a[i+92>>2]=l,a[i>>2]=24320,a[i+104>>2]=h,l=a[c+8>>2],a[i+8>>2]=a[c+4>>2],a[i+12>>2]=l,l=A+132|0,h=i+352|0,k=i+416|0,W=i+264|0,D=i+240|4,E=i+328|0,w=i+284|0,N=w+16|0,c=0;;){a[E>>2]=0,a[E+4>>2]=0,a[D>>2]=0,a[D+4>>2]=0,a[W>>2]=0,a[W+4>>2]=0,a[w>>2]=0,a[w+4>>2]=0,n=E+8|0,a[n>>2]=0,a[n+4>>2]=0,n=D+8|0,a[n>>2]=0,a[n+4>>2]=0,n=W+8|0,a[n>>2]=0,a[n+4>>2]=0,n=w+8|0,a[n>>2]=0,a[n+4>>2]=0,a[N>>2]=0,n=a[l+4>>2],a[k>>2]=a[l>>2],a[k+4>>2]=n,G=l+8|0,B=a[G+4>>2],n=k+8|0,a[n>>2]=a[G>>2],a[n+4>>2]=B,a[i+324>>2]=1065353216,a[i+316>>2]=0,a[i+320>>2]=0,a[i+344>>2]=1065353216,a[i+348>>2]=0,a[i+240>>2]=1065353216,a[i+260>>2]=1065353216,a[i+280>>2]=1065353216,G=s+8|0,B=G,I=a[B+4>>2],n=h+8|0,a[n>>2]=a[B>>2],a[n+4>>2]=I,n=a[s+4>>2],a[h>>2]=a[s>>2],a[h+4>>2]=n,a[i+412>>2]=0,a[i+396>>2]=0,a[i+380>>2]=0,t=C[A+168>>2],b=C[A+172>>2],v=C[A+176>>2],u=C[A+180>>2],g=_(_(2)/_(_(_(_(t*t)+_(b*b))+_(v*v))+_(u*u))),Q=_(b*g),d=_(t*Q),R=_(v*g),m=_(u*R),C[i+372>>2]=d-m,Z=_(t*R),V=_(u*Q),C[i+376>>2]=Z+V,C[i+384>>2]=d+m,d=_(b*R),m=u,u=_(t*g),g=_(m*u),C[i+392>>2]=d-g,C[i+400>>2]=Z-V,C[i+404>>2]=d+g,b=_(b*Q),v=_(v*R),C[i+368>>2]=_(1)-_(b+v),t=_(t*u),C[i+388>>2]=_(1)-_(t+v),C[i+408>>2]=_(1)-_(t+b),a[i+316>>2]=0,a[i+332>>2]=0,a[i+348>>2]=0,t=C[A+184>>2],b=C[A+188>>2],v=C[A+192>>2],u=C[A+196>>2],g=_(_(2)/_(_(_(_(t*t)+_(b*b))+_(v*v))+_(u*u))),Q=_(b*g),d=_(t*Q),R=_(v*g),m=_(u*R),C[i+320>>2]=d+m,C[i+308>>2]=d-m,d=_(t*R),m=_(u*Q),C[i+336>>2]=d-m,C[i+312>>2]=d+m,d=_(b*R),m=u,u=_(t*g),g=_(m*u),C[i+340>>2]=d+g,C[i+328>>2]=d-g,b=_(b*Q),v=_(v*R),C[i+304>>2]=_(1)-_(b+v),t=_(t*u),C[i+344>>2]=_(1)-_(t+b),C[i+324>>2]=_(1)-_(t+v),t=C[A+152>>2],b=C[A+156>>2],u=C[A+160>>2],a[i+300>>2]=0,C[i+296>>2]=u-F,C[i+292>>2]=b-p,C[i+288>>2]=t-y;e:if(o[A+250|0]){if(Sf(a[A+8>>2],a[A+12>>2],i+368|0,i+304|0,i+112|0,C[e+56>>2]),C[i+116>>2]<_(1))break e;if(n=a[A+8>>2],4&o[n+204|0])break e;Sf(n,a[A+12>>2],i+368|0,i+240|0,i,C[e+56>>2])}else _f(e,a[A+12>>2],i+368|0,i+304|0,i+112|0,C[e+56>>2]),4&o[a[A+8>>2]+204|0]|C[i+116>>2]<_(1)||_f(e,a[A+12>>2],i+368|0,i+240|0,i,C[e+56>>2]);t=C[A+20>>2],t=t<_(0)?_(-t):_(0);e:if(o[A+290|0]){if(n=0,C[i+4>>2]<_(1)^1&&!(C[i+116>>2]<_(1)))break e;if(B=a[A+8>>2],4&o[B+204|0])break e;n=0|Qt[a[a[A>>2]+56>>2]](A,B,a[i+192>>2])}else n=0,C[i+4>>2]<_(1)&&(B=a[A+8>>2],4&o[B+204|0]||(n=0|Qt[a[a[A>>2]+56>>2]](A,B,a[i+80>>2])));b=_(t*r),t=_(0);e:{r:{if(t=C[A+20>>2]<_(0)^1?t:C[A+60>>2],!(1&(b>_(0)^-1|b>2];i:{if(!(4&o[e+204|0]|C[i+116>>2]<_(1)^1)){if(1&(Qt[a[a[A>>2]+56>>2]](A,e,a[i+192>>2])|c))break i;break e}if(!c)break e}r=C[A+136>>2],t=o[A+290|0]?o[A+289|0]?C[i+116>>2]:_(_(r-C[i+180>>2])*_(.5)):C[i+116>>2],f[A+289|0]=0,f[A+249|0]=0,a[A+20>>2]=0,a[A+24>>2]=0,b=_(_(1)-t),C[A+132>>2]=_(b*C[A+132>>2])+_(t*C[A+152>>2]),C[A+136>>2]=_(r*b)+_(t*C[A+156>>2]),e=A+140|0,C[e>>2]=_(b*C[e>>2])+_(t*C[A+160>>2]);break A}c=a[i+228>>2],a[s>>2]=a[i+224>>2],a[s+4>>2]=c,c=i+232|0,n=a[c+4>>2],a[G>>2]=a[c>>2],a[G+4>>2]=n,t=_(t+C[A+148>>2]),y=_(C[A+256>>2]*t),C[A+152>>2]=C[A+152>>2]-y,p=_(t*C[A+260>>2]),C[A+156>>2]=C[A+156>>2]-p,F=_(t*C[A+264>>2]),C[A+160>>2]=C[A+160>>2]-F,c=1;continue}break}f[A+289|0]=1,o[A+290|0]&&(t=C[A+20>>2],t=_((t<_(0)?_(-t):_(0))*r),r=C[A+28>>2],t>r^1|(o[A+249|0]?!o[A+248|0]:0)||(r=_(r+C[A+148>>2]),C[A+160>>2]=_(F+C[A+160>>2])-_(r*C[A+264>>2]),C[A+156>>2]=_(p+C[A+156>>2])-_(r*C[A+260>>2]),C[A+152>>2]=_(y+C[A+152>>2])-_(C[A+256>>2]*r))),A=a[s+4>>2],a[l>>2]=a[s>>2],a[l+4>>2]=A,e=s+8|0,s=a[e+4>>2],A=l+8|0,a[A>>2]=a[e>>2],a[A+4>>2]=s}Y=i+432|0}(A,e,r),k=A+140|0,R=a[k+4>>2],B=l+8|0,n=B,a[n>>2]=a[k>>2],a[n+4>>2]=R,n=a[A+136>>2],a[l>>2]=a[A+132>>2],a[l+4>>2]=n,R=a[i+20>>2],n=a[A+8>>2],a[n+4>>2]=a[i+16>>2],a[n+8>>2]=R,R=a[t+4>>2],k=n+20|0,a[k>>2]=a[t>>2],a[k+4>>2]=R,t=t+8|0,R=a[t+4>>2],k=n+28|0,a[k>>2]=a[t>>2],a[k+4>>2]=R,t=c,c=a[t+4>>2],k=n+36|0,a[k>>2]=a[t>>2],a[k+4>>2]=c,t=t+8|0,k=a[t+4>>2],c=n+44|0,a[c>>2]=a[t>>2],a[c+4>>2]=k,c=i+24|0,k=a[c+4>>2],t=n+12|0,a[t>>2]=a[c>>2],a[t+4>>2]=k,a[n+304>>2]=a[n+304>>2]+1,c=a[l+4>>2],t=n+52|0,a[t>>2]=a[l>>2],a[t+4>>2]=c,c=a[B+4>>2],t=n+60|0,a[t>>2]=a[B>>2],a[t+4>>2]=c,f[A+220|0]=0,jf(A,e)&&(f[A+220|0]=1,jf(A,e)&&(f[A+220|0]=1,jf(A,e)&&(f[A+220|0]=1,jf(A,e)&&(f[A+220|0]=1,jf(A,e)&&(f[A+220|0]=1)))))),Y=i+80|0},zf,function(A,e){A|=0,e|=0;var r=_(0),i=_(0),t=_(0),n=_(0),o=0,c=0;o=A,r=C[e>>2],i=_(r*r),r=C[e+4>>2],i=_(i+_(r*r)),r=C[e+8>>2],r=_(i+_(r*r)),i=C[A+36>>2],r!=_(0)&&(i=_(y(r))),r=i,C[o+20>>2]=r,C[A+32>>2]=r,f[A+249|0]=1,o=A+284|0,r=C[e>>2],t=C[e+4>>2],n=C[e+8>>2],i=_(_(_(r*r)+_(t*t))+_(n*n)),i!=_(0)?(i=_(_(1)/_(y(i))),n=_(n*i),t=_(t*i),r=_(r*i),e=e+12|0):(n=C[A+264>>2],t=C[A+260>>2],r=C[A+256>>2],e=A+268|0),a[o>>2]=a[e>>2],C[A+280>>2]=n,C[A+276>>2]=t,C[A+272>>2]=r,e=a[A+8>>2],c=e+52|0,o=a[c+4>>2],a[A+116>>2]=a[c>>2],a[A+120>>2]=o,e=e+60|0,c=a[e+4>>2],A=A+124|0,a[A>>2]=a[e>>2],a[A+4>>2]=c},function(A){return A|=0,0|(_(m(C[A+20>>2]))<_(1.1920928955078125e-7)^1?0:_(m(C[A+24>>2]))<_(1.1920928955078125e-7))},function(A,e){A|=0,e|=0,f[A+288|0]=e},function(A,e,r){return A|=0,e|=0,r|=0,A=a[r+188>>2],e=a[e+188>>2],a[A+8>>2]&a[e+4>>2]?0!=(a[e+8>>2]&a[A+4>>2])|0:0},function(A,e){A|=0,e|=0;var r=0;r=a[e+4>>2],a[A+100>>2]=a[e>>2],a[A+104>>2]=r,e=e+8|0,r=a[e+4>>2],A=A+108|0,a[A>>2]=a[e>>2],a[A+4>>2]=r},function(A){return A|=0,A+100|0},function(A,e){A|=0,e|=0;var r,i=0,t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=0,k=_(0),v=_(0),d=_(0),g=_(0);i=a[e+4>>2],a[A+68>>2]=a[e>>2],a[A+72>>2]=i,s=e+8|0,r=a[s+4>>2],i=A+76|0,a[i>>2]=a[s>>2],a[i+4>>2]=r,o=C[A+68>>2],c=C[A+72>>2],b=C[i>>2],k=_(_(_(o*o)+_(c*c))+_(b*b));A:{if(k>_(0)){if(l=C[e>>2],t=C[e+4>>2],u=C[e+8>>2],n=_(_(1)/_(y(_(_(_(l*l)+_(t*t))+_(u*u))))),v=C[A+264>>2],g=_(v*_(u*n)),u=C[A+256>>2],d=C[A+260>>2],n=_(g+_(_(u*_(l*n))+_(d*_(t*n)))),n==_(0))break A;if(t=b,b=_(_(y(k))*dr(_(_(1.5707963705062866)-Ni(_(Q(_(h(n,_(-1))),_(1))))))),l=_(v*b),C[A+76>>2]=t-l,t=c,c=_(d*b),C[A+72>>2]=t-c,t=o,o=_(u*b),C[A+68>>2]=t-o,C[A+20>>2]=(n<_(0)?_(-1):_(1))*_(y(_(_(l*l)+_(_(o*o)+_(c*c))))),!(n>_(0)))break A;return f[A+249|0]=1,e=a[A+8>>2],i=e+52|0,s=a[i+4>>2],a[A+116>>2]=a[i>>2],a[A+120>>2]=s,e=e+60|0,i=a[e+4>>2],A=A+124|0,a[A>>2]=a[e>>2],void(a[A+4>>2]=i)}a[A+20>>2]=0}},function(A,e){A|=0,e|=0;var r=_(0);a[A+12>>2]=0,r=C[e+20>>2],C[A>>2]=_(C[e+256>>2]*r)+C[e+68>>2],C[A+8>>2]=_(r*C[e+264>>2])+C[e+76>>2],C[A+4>>2]=_(r*C[e+260>>2])+C[e+72>>2]},ve,function(A,e){return A|=0,e|=0,a[A+12>>2]&a[e+4>>2]?0!=(a[e+8>>2]&a[A+8>>2])|0:0},function(A,e,r){A|=0,e|=0,r|=0;var i=0,f=_(0),t=_(0),n=_(0),c=_(0),b=_(0),l=_(0),u=0,s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0);return t=_(1),i=a[e>>2],(0|i)==a[A+84>>2]|4&o[i+204|0]||(r?(n=C[e+16>>2],c=C[e+12>>2],f=C[e+8>>2]):(f=C[e+8>>2],b=C[e+12>>2],l=C[e+16>>2],n=_(_(_(f*C[i+36>>2])+_(b*C[i+40>>2]))+_(l*C[i+44>>2])),c=_(_(_(f*C[i+20>>2])+_(b*C[i+24>>2]))+_(l*C[i+28>>2])),f=_(_(_(C[i+4>>2]*f)+_(C[i+8>>2]*b))+_(C[i+12>>2]*l))),_(_(_(f*C[A+88>>2])+_(c*C[A+92>>2]))+_(n*C[A+96>>2]))>2]||(a[A+80>>2]=i,a[A+4>>2]=a[e+40>>2],r?(r=a[e+12>>2],a[A+48>>2]=a[e+8>>2],a[A+52>>2]=r,i=e+16|0,u=a[i+4>>2],r=A+56|0,a[r>>2]=a[i>>2],a[r+4>>2]=u):(f=C[i+8>>2],b=C[i+12>>2],l=C[i+20>>2],s=C[i+24>>2],k=C[i+28>>2],v=C[i+36>>2],d=C[i+40>>2],t=C[e+12>>2],g=C[i+44>>2],n=C[e+16>>2],B=C[i+4>>2],c=C[e+8>>2],a[A+60>>2]=0,C[A+56>>2]=_(_(c*v)+_(t*d))+_(n*g),C[A+52>>2]=_(_(c*l)+_(t*s))+_(n*k),C[A+48>>2]=_(_(B*c)+_(f*t))+_(b*n)),r=a[e+28>>2],a[A+64>>2]=a[e+24>>2],a[A+68>>2]=r,r=e+32|0,i=a[r+4>>2],A=A+72|0,a[A>>2]=a[r>>2],a[A+4>>2]=i,t=C[e+40>>2])),_(t)},At,qe,function(A,e){A|=0,e|=0;var r=0,i=0,f=0;Kf(A,a[A+28>>2]+4|0,a[A+32>>2]+4|0),a[e>>2]=0,a[e+4>>2]=0;A:{e:{r:if(r=a[A+956>>2],!(r>>>0>4))switch(i=2,r-1|0){case 3:break e;case 0:case 1:case 2:break r;default:break A}i=1}a[e>>2]=i,r=i}o[A+792|0]&&(r=r+1|0,a[e>>2]=r),o[A+798|0]&&(r=r+1|0,a[e>>2]=r),f=e;A:{e:{r:if(i=a[A+960>>2],!(i>>>0>4)){i:switch(i-1|0){case 0:case 1:case 2:break r;case 3:break i;default:break A}r=r+2|0;break e}r=r+1|0}a[f>>2]=r}o[A+793|0]&&(r=r+1|0,a[e>>2]=r),o[A+799|0]&&(r=r+1|0,a[e>>2]=r),f=e;A:{e:{r:if(i=a[A+964>>2],!(i>>>0>4)){i:switch(i-1|0){case 0:case 1:case 2:break r;case 3:break i;default:break A}r=r+2|0;break e}r=r+1|0}a[f>>2]=r}o[A+794|0]&&(r=r+1|0,a[e>>2]=r),o[A+800|0]&&(a[e>>2]=r+1),Lf(A,0);A:{e:{r:if(i=a[A+1052>>2],!(i>>>0>4))switch(r=2,i-1|0){case 3:break e;case 0:case 1:case 2:break r;default:break A}r=1}a[e>>2]=a[e>>2]+r}o[A+996|0]&&(a[e>>2]=a[e>>2]+1),o[A+1016|0]&&(a[e>>2]=a[e>>2]+1),Lf(A,1);A:{e:{r:if(i=a[A+1140>>2],!(i>>>0>4))switch(r=2,i-1|0){case 3:break e;case 0:case 1:case 2:break r;default:break A}r=1}a[e>>2]=a[e>>2]+r}o[A+1084|0]&&(a[e>>2]=a[e>>2]+1),o[A+1104|0]&&(a[e>>2]=a[e>>2]+1),r=2,Lf(A,2);A:{e:{r:if(i=a[A+1228>>2],!(i>>>0>4))switch(i-1|0){case 3:break e;case 0:case 1:case 2:break r;default:break A}r=1}a[e>>2]=a[e>>2]+r}o[A+1172|0]&&(a[e>>2]=a[e>>2]+1),o[A+1192|0]&&(a[e>>2]=a[e>>2]+1)},function(A,e){var r,i,t,n,c,b;A|=0,e|=0,r=A,i=e,e=a[A+28>>2],t=e+4|0,A=a[A+32>>2],n=A+4|0,c=e+372|0,b=A+372|0,e=e+388|0,A=A+388|0,function(A,e,r,i,t,n,c,b,l){var u=0,s=0,k=0,v=0,d=0,g=0,_=0,m=0,R=0,Q=0;for(u=Y-112|0,Y=u,k=u+100|0,a[k>>2]=0,a[k+4>>2]=0,a[u+108>>2]=0,a[u+92>>2]=0,a[u+96>>2]=0,f[u+88|0]=0,a[u+84>>2]=0,f[u+80|0]=0,a[u+76>>2]=0,f[u+72|0]=0,a[u+68>>2]=0,f[u+64|0]=0,a[u+56>>2]=0,a[u+60>>2]=1036831949,f[u+52|0]=0,a[u+48>>2]=0,a[u+40>>2]=0,a[u+44>>2]=1063675494,a[u+32>>2]=0,a[u+36>>2]=1045220557,a[u+24>>2]=1065353216,a[u+28>>2]=-1082130432,R=e+4|0;;){if(v=A+_|0,k=o[v+792|0],s=A+m|0,Q=a[s+956>>2],Q||(d=k,k=1,d||(k=0,o[v+798|0]))){a[u+108>>2]=Q,f[u+52|0]=k,a[u+32>>2]=a[s+712>>2],a[u+104>>2]=a[s+940>>2],a[u+96>>2]=a[s+908>>2],a[u+100>>2]=a[s+924>>2],f[u+64|0]=o[v+795|0],a[u+68>>2]=a[s+804>>2],f[u+72|0]=o[v+798|0],a[u+76>>2]=a[s+820>>2],f[u+80|0]=o[v+836|0],a[u+84>>2]=a[s+840>>2],f[u+88|0]=o[v+856|0],a[u+92>>2]=a[s+860>>2],a[u+28>>2]=a[s+696>>2],a[u+24>>2]=a[s+680>>2],a[u+60>>2]=a[s+892>>2],a[u+56>>2]=a[s+876>>2],a[u+20>>2]=0,a[u+8>>2]=a[s+1236>>2],a[u+12>>2]=a[s+1252>>2],a[u+16>>2]=a[s+1268>>2],d=u,k=a[A+1456>>2]>>m,v=s+744|0,1&k||(v=a[e+32>>2]),a[d+40>>2]=a[v>>2],a[u+36>>2]=a[(2&k?s+728|0:R)>>2],a[u+48>>2]=a[(4&k?s+776|0:a[e+32>>2])>>2],a[u+44>>2]=a[(8&k?s+760|0:R)>>2],d=1,s=((_+2&255)>>>0)%3|0,k=B(((_+1&255)>>>0)%3|0,88)+A|0,v=a[k+1052>>2]+-1|0;A:if(v>>>0<=3){e:switch(v-2|0){case 0:g=+C[k+1040>>2],d=g<-.001|g>.001;break A;case 1:break e;default:break A}if(+C[k+1040>>2]<-.001)break A;d=+C[k+1044>>2]>.001}else d=0;k=1,s=B(s,88)+A|0,v=a[s+1052>>2]+-1|0;A:if(!(v>>>0>3)){e:{r:switch(v-2|0){case 0:if(g=+C[s+1040>>2],g<-.001|g>.001)break e;break A;case 1:break r;default:break e}if(!(+C[s+1040>>2]<-.001||+C[s+1044>>2]>.001))break A}k=0}r=qf(A,u+24|0,i,t,n,c,b,l,e,r,u+8|0,0,d?k:1)+r|0}if(_=_+1|0,m=m+4|0,12==(0|m))break}Y=u+112|0}(r,i,function(A,e,r,i,f,t,n,c){var b=0,l=0,u=0,s=0,k=0,v=0,d=0,C=0;return u=Y-32|0,Y=u,a[u+24>>2]=a[6114],l=a[6113],a[u+16>>2]=a[6112],a[u+20>>2]=l,l=1,s=a[A+1232>>2],s>>>0<=5&&(b=s<<2,a[u+24>>2]=a[b+24508>>2],l=a[b+24532>>2],a[u+20>>2]=l,b=a[b+24556>>2],a[u+16>>2]=b),s=B(b,88)+A|0,(o[1016+(B(b,88)+A|0)|0]||a[s+1052>>2]|o[s+996|0])&&(l=(b<<4)+A|0,k=l+1388|0,v=a[k+4>>2],d=u+8|0,a[d>>2]=a[k>>2],a[d+4>>2]=v,l=l+1380|0,k=a[l+4>>2],a[u>>2]=a[l>>2],a[u+4>>2]=k,l=a[A+1456>>2]>>12+(b<<2),1&l||(a[984+(B(b,88)+A|0)>>2]=a[a[e+32>>2]>>2]),2&l||(a[980+(B(b,88)+A|0)>>2]=a[e+4>>2]),4&l||(a[992+(B(b,88)+A|0)>>2]=a[a[e+32>>2]>>2]),8&l||(a[988+(B(b,88)+A|0)>>2]=a[e+4>>2]),k=qf(A,s+968|0,r,i,f,t,n,c,e,0,u,1,0),l=a[u+20>>2]),s=B(l,88)+A|0,(o[1016+(B(l,88)+A|0)|0]||a[s+1052>>2]|o[s+996|0])&&(b=(l<<4)+A|0,v=b+1388|0,d=a[v+4>>2],C=u+8|0,a[C>>2]=a[v>>2],a[C+4>>2]=d,b=b+1380|0,v=a[b+4>>2],a[u>>2]=a[b>>2],a[u+4>>2]=v,b=a[A+1456>>2]>>12+(l<<2),1&b||(a[984+(B(l,88)+A|0)>>2]=a[a[e+32>>2]>>2]),2&b||(a[980+(B(l,88)+A|0)>>2]=a[e+4>>2]),4&b||(a[992+(B(l,88)+A|0)>>2]=a[a[e+32>>2]>>2]),8&b||(a[988+(B(l,88)+A|0)>>2]=a[e+4>>2]),k=qf(A,s+968|0,r,i,f,t,n,c,e,k,u,1,0)+k|0),l=a[u+24>>2],s=B(l,88)+A|0,(o[1016+(B(l,88)+A|0)|0]||a[s+1052>>2]|o[s+996|0])&&(b=(l<<4)+A|0,v=b+1388|0,d=a[v+4>>2],C=u+8|0,a[C>>2]=a[v>>2],a[C+4>>2]=d,b=b+1380|0,v=a[b+4>>2],a[u>>2]=a[b>>2],a[u+4>>2]=v,b=a[A+1456>>2]>>12+(l<<2),1&b||(a[984+(B(l,88)+A|0)>>2]=a[a[e+32>>2]>>2]),2&b||(a[980+(B(l,88)+A|0)>>2]=a[e+4>>2]),4&b||(a[992+(B(l,88)+A|0)>>2]=a[a[e+32>>2]>>2]),8&b||(a[988+(B(l,88)+A|0)>>2]=a[e+4>>2]),k=qf(A,s+968|0,r,i,f,t,n,c,e,k,u,1,0)+k|0),Y=u+32|0,k}(r,i,t,n,c,b,e,A),t,n,c,b,e,A)},function(A,e,r,i){A|=0,e|=0,r=_(r),i|=0;var f=0;A:{if(i>>>0<=2){if(e=e+-1|0,e>>>0>3)break A;switch(e-1|0){case 0:return e=i<<2,C[728+(e+A|0)>>2]=r,void(a[A+1456>>2]=a[A+1456>>2]|2<>2]=r,void(a[A+1456>>2]=a[A+1456>>2]|1<>2]=r,void(a[A+1456>>2]=a[A+1456>>2]|8<>2]=r,void(a[A+1456>>2]=a[A+1456>>2]|4<>>0>2||(e=e+-1|0,e>>>0>3))){switch(e-1|0){case 0:return C[980+(B(f,88)+A|0)>>2]=r,void(a[A+1456>>2]=a[A+1456>>2]|2<<(i<<2));case 2:return C[984+(B(f,88)+A|0)>>2]=r,void(a[A+1456>>2]=a[A+1456>>2]|1<<(i<<2));default:return C[988+(B(f,88)+A|0)>>2]=r,void(a[A+1456>>2]=a[A+1456>>2]|8<<(i<<2));case 1:}C[992+(B(f,88)+A|0)>>2]=r,a[A+1456>>2]=a[A+1456>>2]|4<<(i<<2)}}},function(A,e,r){A|=0,e|=0,r|=0;var i=_(0);if(r>>>0<=2){if(e=e+-1|0,e>>>0>3)return _(_(0));switch(e-1|0){case 0:return _(C[728+((r<<2)+A|0)>>2]);case 2:return _(C[744+((r<<2)+A|0)>>2]);default:return _(C[760+((r<<2)+A|0)>>2]);case 1:}return _(C[776+((r<<2)+A|0)>>2])}if(r=r+-3|0,!(r>>>0>2||(e=e+-1|0,e>>>0>3))){switch(e-1|0){case 0:return _(C[980+(B(r,88)+A|0)>>2]);case 2:return _(C[984+(B(r,88)+A|0)>>2]);default:return _(C[988+(B(r,88)+A|0)>>2]);case 1:}i=C[992+(B(r,88)+A|0)>>2]}return _(i)},function(A){return 644},function(A,e,r){return A|=0,e|=0,r|=0,Df(A,e,r),a[e+52>>2]=a[A+48>>2],a[e+56>>2]=a[A+52>>2],a[e+60>>2]=a[A+56>>2],a[e+64>>2]=a[A+60>>2],a[e+68>>2]=a[A- -64>>2],a[e+72>>2]=a[A+68>>2],a[e+76>>2]=a[A+72>>2],a[e+80>>2]=a[A+76>>2],a[e+84>>2]=a[A+80>>2],a[e+88>>2]=a[A+84>>2],a[e+92>>2]=a[A+88>>2],a[e+96>>2]=a[A+92>>2],a[e+100>>2]=a[A+96>>2],a[e+104>>2]=a[A+100>>2],a[e+108>>2]=a[A+104>>2],a[e+112>>2]=a[A+108>>2],a[e+116>>2]=a[A+112>>2],a[e+120>>2]=a[A+116>>2],a[e+124>>2]=a[A+120>>2],a[e+128>>2]=a[A+124>>2],a[e+132>>2]=a[A+128>>2],a[e+136>>2]=a[A+132>>2],a[e+140>>2]=a[A+136>>2],a[e+144>>2]=a[A+140>>2],a[e+148>>2]=a[A+144>>2],a[e+152>>2]=a[A+148>>2],a[e+156>>2]=a[A+152>>2],a[e+160>>2]=a[A+156>>2],a[e+164>>2]=a[A+160>>2],a[e+168>>2]=a[A+164>>2],a[e+172>>2]=a[A+168>>2],a[e+176>>2]=a[A+172>>2],a[e+428>>2]=a[A+968>>2],a[e+412>>2]=a[A+972>>2],a[e+444>>2]=a[A+976>>2],a[e+460>>2]=a[A+980>>2],a[e+476>>2]=a[A+984>>2],a[e+492>>2]=a[A+988>>2],a[e+508>>2]=a[A+992>>2],a[e+524>>2]=a[A+1e3>>2],a[e+540>>2]=a[A+1004>>2],a[e+556>>2]=a[A+1012>>2],a[e+572>>2]=a[A+1020>>2],a[e+588>>2]=a[A+1028>>2],a[e+604>>2]=a[A+1036>>2],a[e+432>>2]=a[A+1056>>2],a[e+416>>2]=a[A+1060>>2],a[e+448>>2]=a[A+1064>>2],a[e+464>>2]=a[A+1068>>2],a[e+480>>2]=a[A+1072>>2],a[e+496>>2]=a[A+1076>>2],a[e+512>>2]=a[A+1080>>2],a[e+528>>2]=a[A+1088>>2],a[e+544>>2]=a[A+1092>>2],a[e+560>>2]=a[A+1100>>2],a[e+576>>2]=a[A+1108>>2],a[e+592>>2]=a[A+1116>>2],a[e+608>>2]=a[A+1124>>2],a[e+436>>2]=a[A+1144>>2],a[e+420>>2]=a[A+1148>>2],a[e+452>>2]=a[A+1152>>2],a[e+468>>2]=a[A+1156>>2],a[e+484>>2]=a[A+1160>>2],a[e+500>>2]=a[A+1164>>2],a[e+516>>2]=a[A+1168>>2],a[e+532>>2]=a[A+1176>>2],a[e+548>>2]=a[A+1180>>2],a[e+564>>2]=a[A+1188>>2],a[e+580>>2]=a[A+1196>>2],a[e+596>>2]=a[A+1204>>2],r=a[A+1212>>2],a[e+440>>2]=0,a[e+612>>2]=r,a[e+616>>2]=0,a[e+600>>2]=0,a[e+584>>2]=0,a[e+568>>2]=0,a[e+552>>2]=0,a[e+536>>2]=0,a[e+520>>2]=0,a[e+504>>2]=0,a[e+488>>2]=0,a[e+472>>2]=0,a[e+456>>2]=0,a[e+424>>2]=0,f[e+620|0]=o[A+996|0],f[e+624|0]=o[A+1008|0],f[e+628|0]=o[A+1016|0],f[e+632|0]=o[A+1024|0],f[e+636|0]=o[A+1032|0],f[e+621|0]=o[A+1084|0],f[e+625|0]=o[A+1096|0],f[e+629|0]=o[A+1104|0],f[e+633|0]=o[A+1112|0],f[e+637|0]=o[A+1120|0],f[e+622|0]=o[A+1172|0],f[e+626|0]=o[A+1184|0],f[e+630|0]=o[A+1192|0],f[e+634|0]=o[A+1200|0],r=o[A+1208|0],f[e+639|0]=0,f[e+635|0]=0,f[e+631|0]=0,f[e+627|0]=0,f[e+623|0]=0,f[e+638|0]=r,a[e+196>>2]=a[A+680>>2],a[e+200>>2]=a[A+684>>2],a[e+204>>2]=a[A+688>>2],a[e+208>>2]=a[A+692>>2],a[e+180>>2]=a[A+696>>2],a[e+184>>2]=a[A+700>>2],a[e+188>>2]=a[A+704>>2],a[e+192>>2]=a[A+708>>2],a[e+212>>2]=a[A+712>>2],a[e+216>>2]=a[A+716>>2],a[e+220>>2]=a[A+720>>2],a[e+224>>2]=a[A+724>>2],a[e+228>>2]=a[A+728>>2],a[e+232>>2]=a[A+732>>2],a[e+236>>2]=a[A+736>>2],a[e+240>>2]=a[A+740>>2],a[e+244>>2]=a[A+744>>2],a[e+248>>2]=a[A+748>>2],a[e+252>>2]=a[A+752>>2],a[e+256>>2]=a[A+756>>2],a[e+260>>2]=a[A+760>>2],a[e+264>>2]=a[A+764>>2],a[e+268>>2]=a[A+768>>2],a[e+272>>2]=a[A+772>>2],a[e+276>>2]=a[A+776>>2],a[e+280>>2]=a[A+780>>2],a[e+284>>2]=a[A+784>>2],a[e+288>>2]=a[A+788>>2],a[e+292>>2]=a[A+876>>2],a[e+296>>2]=a[A+880>>2],a[e+300>>2]=a[A+884>>2],a[e+304>>2]=a[A+888>>2],a[e+308>>2]=a[A+892>>2],a[e+312>>2]=a[A+896>>2],a[e+316>>2]=a[A+900>>2],a[e+320>>2]=a[A+904>>2],a[e+324>>2]=a[A+804>>2],a[e+328>>2]=a[A+808>>2],a[e+332>>2]=a[A+812>>2],a[e+336>>2]=a[A+816>>2],a[e+340>>2]=a[A+820>>2],a[e+344>>2]=a[A+824>>2],a[e+348>>2]=a[A+828>>2],a[e+352>>2]=a[A+832>>2],a[e+356>>2]=a[A+840>>2],a[e+360>>2]=a[A+844>>2],a[e+364>>2]=a[A+848>>2],a[e+368>>2]=a[A+852>>2],a[e+372>>2]=a[A+860>>2],a[e+376>>2]=a[A+864>>2],a[e+380>>2]=a[A+868>>2],a[e+384>>2]=a[A+872>>2],f[e+388|0]=o[A+792|0],f[e+392|0]=o[A+795|0],f[e+396|0]=o[A+798|0],f[e+400|0]=o[A+836|0],f[e+404|0]=o[A+856|0],f[e+389|0]=o[A+793|0],f[e+393|0]=o[A+796|0],f[e+397|0]=o[A+799|0],f[e+401|0]=o[A+837|0],f[e+405|0]=o[A+857|0],f[e+390|0]=o[A+794|0],f[e+394|0]=o[A+797|0],f[e+398|0]=o[A+800|0],f[e+402|0]=o[A+838|0],r=o[A+858|0],f[e+407|0]=0,f[e+403|0]=0,f[e+399|0]=0,f[e+395|0]=0,f[e+391|0]=0,f[e+406|0]=r,A=a[A+1232>>2],a[e+408>>2]=0,a[e+640>>2]=A,24664},Ef,At,sA,ve,function(A,e){A|=0,e|=0,D(a[A+4>>2],0|e)},function(A,e){A|=0,e|=0,E(a[A+4>>2],0|e)},ve,function(A,e){return A|=0,e|=0,a[A+16>>2]&a[e+4>>2]?0!=(a[e+8>>2]&a[A+12>>2])|0:0},function(A,e,r){A|=0,e|=0,r|=0;var i=0,f=_(0),t=_(0),n=_(0),o=0,c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0);return a[A+4>>2]=a[e+24>>2],i=a[e>>2],a[A+8>>2]=i,r?(r=a[e+12>>2],a[A+56>>2]=a[e+8>>2],a[A+60>>2]=r,i=e+16|0,o=a[i+4>>2],r=A- -64|0,a[r>>2]=a[i>>2],a[r+4>>2]=o):(c=C[i+8>>2],b=C[i+12>>2],l=C[i+20>>2],u=C[i+24>>2],s=C[i+28>>2],k=C[i+36>>2],v=C[i+40>>2],f=C[e+12>>2],d=C[i+44>>2],t=C[e+16>>2],g=C[i+4>>2],n=C[e+8>>2],a[A+68>>2]=0,C[A- -64>>2]=_(_(n*k)+_(f*v))+_(t*d),C[A+60>>2]=_(_(n*l)+_(f*u))+_(t*s),C[A+56>>2]=_(_(g*n)+_(c*f))+_(b*t)),f=C[e+24>>2],t=_(_(1)-f),C[A+72>>2]=_(t*C[A+24>>2])+_(f*C[A+40>>2]),C[A+76>>2]=_(t*C[A+28>>2])+_(f*C[A+44>>2]),C[A+80>>2]=_(t*C[A+32>>2])+_(f*C[A+48>>2]),_(C[e+24>>2])},Ct,function(A){A|=0,$(Ct(A))},function(A,e,r){A|=0,e|=0,r|=0;var i=0,t=0,n=0,c=0,b=0,l=_(0),u=0,s=0,k=_(0),v=_(0),d=_(0),g=_(0);if(a[A+8>>2]=a[e>>2],i=a[A+28>>2],(0|i)==a[A+32>>2]&&(n=i?i<<1:1,!((0|i)>=(0|n)))){if(n&&(c=dA(n<<2),i=a[A+28>>2]),(0|i)>=1)for(t=i;a[b+c>>2]=a[a[A+36>>2]+b>>2],b=b+4|0,t=t+-1|0,t;);t=a[A+36>>2],t&&(o[A+40|0]&&(CA(t),i=a[A+28>>2]),a[A+36>>2]=0),a[A+36>>2]=c,a[A+32>>2]=n,f[A+40|0]=1}if(a[A+28>>2]=i+1,a[a[A+36>>2]+(i<<2)>>2]=a[e>>2],r?(g=C[e+16>>2],v=C[e+12>>2],l=C[e+8>>2],k=C[e+20>>2]):(d=C[e+8>>2],r=a[A+8>>2],k=C[e+12>>2],l=C[e+16>>2],g=_(_(_(d*C[r+36>>2])+_(k*C[r+40>>2]))+_(l*C[r+44>>2])),v=_(_(_(d*C[r+20>>2])+_(k*C[r+24>>2]))+_(l*C[r+28>>2])),l=_(_(_(C[r+4>>2]*d)+_(C[r+8>>2]*k))+_(C[r+12>>2]*l)),k=_(0)),t=a[A+80>>2],(0|t)==a[A+84>>2]&&(s=t?t<<1:1,!((0|t)>=(0|s)))){if(s?(r=dA(s<<4),t=a[A+80>>2]):r=0,(0|t)>=1)for(b=0;u=a[A+88>>2]+b|0,i=a[u+4>>2],c=r+b|0,n=c,a[n>>2]=a[u>>2],a[n+4>>2]=i,n=u+8|0,i=a[n+4>>2],c=c+8|0,a[c>>2]=a[n>>2],a[c+4>>2]=i,b=b+16|0,t=t+-1|0,t;);i=a[A+88>>2],i&&(o[A+92|0]&&CA(i),a[A+88>>2]=0),a[A+88>>2]=r,a[A+84>>2]=s,f[A+92|0]=1,t=a[A+80>>2]}if(r=a[A+88>>2]+(t<<4)|0,C[r+12>>2]=k,C[r+8>>2]=g,C[r+4>>2]=v,C[r>>2]=l,a[A+80>>2]=a[A+80>>2]+1,v=C[e+24>>2],l=_(_(1)-v),d=_(_(l*C[A+52>>2])+_(v*C[A+68>>2])),k=_(_(l*C[A+48>>2])+_(v*C[A- -64>>2])),l=_(_(l*C[A+44>>2])+_(v*C[A+60>>2])),t=a[A+100>>2],(0|t)==a[A+104>>2]&&(s=t?t<<1:1,!((0|t)>=(0|s)))){if(s?(r=dA(s<<4),t=a[A+100>>2]):r=0,(0|t)>=1)for(b=0;u=a[A+108>>2]+b|0,i=a[u+4>>2],c=r+b|0,n=c,a[n>>2]=a[u>>2],a[n+4>>2]=i,n=u+8|0,i=a[n+4>>2],c=c+8|0,a[c>>2]=a[n>>2],a[c+4>>2]=i,b=b+16|0,t=t+-1|0,t;);i=a[A+108>>2],i&&(o[A+112|0]&&CA(i),a[A+108>>2]=0),a[A+108>>2]=r,a[A+104>>2]=s,f[A+112|0]=1,t=a[A+100>>2]}if(r=a[A+108>>2]+(t<<4)|0,C[r+8>>2]=d,C[r+4>>2]=k,C[r>>2]=l,a[A+100>>2]=a[A+100>>2]+1,i=a[A+120>>2],(0|i)==a[A+124>>2]&&(u=i?i<<1:1,!((0|i)>=(0|u)))){u?(n=dA(u<<2),i=a[A+120>>2]):n=0,r=a[A+128>>2];A:{if((0|i)>=1)for(b=n,t=r,c=i;a[b>>2]=a[t>>2],b=b+4|0,t=t+4|0,c=c+-1|0,c;);else if(!r)break A;o[A+132|0]&&(CA(r),i=a[A+120>>2]),a[A+128>>2]=0}a[A+128>>2]=n,a[A+124>>2]=u,f[A+132|0]=1}return a[a[A+128>>2]+(i<<2)>>2]=a[e+24>>2],a[A+120>>2]=i+1,_(C[A+4>>2])},ve,function(A,e,r){A|=0,e|=0,r|=0;var i=0,f=_(0),t=_(0),n=_(0),o=0,c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0);return a[A+4>>2]=a[e+40>>2],i=a[e>>2],a[A+80>>2]=i,r?(r=a[e+12>>2],a[A+48>>2]=a[e+8>>2],a[A+52>>2]=r,i=e+16|0,o=a[i+4>>2],r=A+56|0,a[r>>2]=a[i>>2],a[r+4>>2]=o):(c=C[i+8>>2],b=C[i+12>>2],l=C[i+20>>2],u=C[i+24>>2],s=C[i+28>>2],k=C[i+36>>2],v=C[i+40>>2],f=C[e+12>>2],d=C[i+44>>2],t=C[e+16>>2],g=C[i+4>>2],n=C[e+8>>2],a[A+60>>2]=0,C[A+56>>2]=_(_(n*k)+_(f*v))+_(t*d),C[A+52>>2]=_(_(n*l)+_(f*u))+_(t*s),C[A+48>>2]=_(_(g*n)+_(c*f))+_(b*t)),r=a[e+28>>2],a[A+64>>2]=a[e+24>>2],a[A+68>>2]=r,r=e+32|0,i=a[r+4>>2],A=A+72|0,a[A>>2]=a[r>>2],a[A+4>>2]=i,_(C[e+40>>2])},gt,function(A){A|=0,$(gt(A))},function(A,e,r){A|=0,e|=0,r|=0;var i,t=0,n=0,c=0,b=0,l=0,u=0,s=0,k=_(0),v=_(0),d=_(0),g=_(0),B=_(0);if(t=a[A+20>>2],(0|t)==a[A+24>>2]&&(c=t?t<<1:1,!((0|t)>=(0|c)))){if(c&&(b=dA(c<<2),t=a[A+20>>2]),(0|t)>=1)for(n=t;a[l+b>>2]=a[a[A+28>>2]+l>>2],l=l+4|0,n=n+-1|0,n;);n=a[A+28>>2],n&&(o[A+32|0]&&(CA(n),t=a[A+20>>2]),a[A+28>>2]=0),a[A+28>>2]=b,a[A+24>>2]=c,f[A+32|0]=1}if(a[A+20>>2]=t+1,a[a[A+28>>2]+(t<<2)>>2]=a[e>>2],r?(g=C[e+16>>2],B=C[e+12>>2],k=C[e+8>>2],v=C[e+20>>2]):(d=C[e+8>>2],r=a[e>>2],v=C[e+12>>2],k=C[e+16>>2],g=_(_(_(d*C[r+36>>2])+_(v*C[r+40>>2]))+_(k*C[r+44>>2])),B=_(_(_(d*C[r+20>>2])+_(v*C[r+24>>2]))+_(k*C[r+28>>2])),k=_(_(_(C[r+4>>2]*d)+_(C[r+8>>2]*v))+_(C[r+12>>2]*k)),v=_(0)),n=a[A+72>>2],(0|n)==a[A+76>>2]&&(s=n?n<<1:1,!((0|n)>=(0|s)))){if(s?(r=dA(s<<4),n=a[A+72>>2]):r=0,(0|n)>=1)for(l=0;u=a[A+80>>2]+l|0,t=a[u+4>>2],b=r+l|0,c=b,a[c>>2]=a[u>>2],a[c+4>>2]=t,c=u+8|0,t=a[c+4>>2],b=b+8|0,a[b>>2]=a[c>>2],a[b+4>>2]=t,l=l+16|0,n=n+-1|0,n;);t=a[A+80>>2],t&&(o[A+84|0]&&CA(t),a[A+80>>2]=0),a[A+80>>2]=r,a[A+76>>2]=s,f[A+84|0]=1,n=a[A+72>>2]}if(r=a[A+80>>2]+(n<<4)|0,C[r+12>>2]=v,C[r+8>>2]=g,C[r+4>>2]=B,C[r>>2]=k,a[A+72>>2]=a[A+72>>2]+1,i=e+24|0,n=a[A+92>>2],(0|n)==a[A+96>>2]&&(s=n?n<<1:1,!((0|n)>=(0|s)))){if(s?(r=dA(s<<4),n=a[A+92>>2]):r=0,(0|n)>=1)for(l=0;u=a[A+100>>2]+l|0,t=a[u+4>>2],b=r+l|0,c=b,a[c>>2]=a[u>>2],a[c+4>>2]=t,c=u+8|0,t=a[c+4>>2],b=b+8|0,a[b>>2]=a[c>>2],a[b+4>>2]=t,l=l+16|0,n=n+-1|0,n;);t=a[A+100>>2],t&&(o[A+104|0]&&CA(t),a[A+100>>2]=0),a[A+100>>2]=r,a[A+96>>2]=s,f[A+104|0]=1,n=a[A+92>>2]}if(r=a[i+4>>2],t=a[A+100>>2]+(n<<4)|0,a[t>>2]=a[i>>2],a[t+4>>2]=r,n=t+8|0,t=i+8|0,r=a[t+4>>2],a[n>>2]=a[t>>2],a[n+4>>2]=r,a[A+92>>2]=a[A+92>>2]+1,t=a[A+112>>2],(0|t)==a[A+116>>2]&&(u=t?t<<1:1,!((0|t)>=(0|u)))){u?(c=dA(u<<2),t=a[A+112>>2]):c=0,r=a[A+120>>2];A:{if((0|t)>=1)for(l=c,n=r,b=t;a[l>>2]=a[n>>2],l=l+4|0,n=n+4|0,b=b+-1|0,b;);else if(!r)break A;o[A+124|0]&&(CA(r),t=a[A+112>>2]),a[A+120>>2]=0}a[A+120>>2]=c,a[A+116>>2]=u,f[A+124|0]=1}return a[a[A+120>>2]+(t<<2)>>2]=a[e+40>>2],a[A+112>>2]=t+1,_(C[A+4>>2])},sA,ve,function(A,e,r){var i;return A|=0,e|=0,r|=0,A=a[r>>2],A=4==a[A+252>>2]?A:0,i=a[e>>2],!i|4!=a[i+252>>2]||Qt[a[a[i>>2]+28>>2]](i,r,e),A&&Qt[a[a[A>>2]+28>>2]](A,e,r),0},function(A,e,r,i){var f;return A|=0,e|=0,r|=0,i|=0,A=a[r>>2],A=4==a[A+252>>2]?A:0,f=a[e>>2],!f|4!=a[f+252>>2]||Qt[a[a[f>>2]+32>>2]](f,r,i,e),A&&Qt[a[a[A>>2]+32>>2]](A,e,i,r),0},De];function ht(){return r.byteLength/65536|0}return{btGImpactCollisionAlgorithm_RegisterAlgorithm:function(A){A|=0,function(A){o[1716]||(a[427]=8844,f[1716]=1,f[1712]=0),de(A,25,0),de(A,25,1),de(A,25,2),de(A,25,3),de(A,25,4),de(A,25,5),de(A,25,6),de(A,25,7),de(A,25,8),de(A,25,9),de(A,25,10),de(A,25,11),de(A,25,12),de(A,25,13),de(A,25,14),de(A,25,15),de(A,25,16),de(A,25,17),de(A,25,18),de(A,25,19),de(A,25,20),de(A,25,21),de(A,25,22),de(A,25,23),de(A,25,24),de(A,25,25),de(A,25,26),de(A,25,27),de(A,25,28),de(A,25,29),de(A,25,30),de(A,25,31),de(A,25,32),de(A,25,33),de(A,25,34),de(A,25,35),de(A,0,25),de(A,1,25),de(A,2,25),de(A,3,25),de(A,4,25),de(A,5,25),de(A,6,25),de(A,7,25),de(A,8,25),de(A,9,25),de(A,10,25),de(A,11,25),de(A,12,25),de(A,13,25),de(A,14,25),de(A,15,25),de(A,16,25),de(A,17,25),de(A,18,25),de(A,19,25),de(A,20,25),de(A,21,25),de(A,22,25),de(A,23,25),de(A,24,25),de(A,25,25),de(A,26,25),de(A,27,25),de(A,28,25),de(A,29,25),de(A,30,25),de(A,31,25),de(A,32,25),de(A,33,25),de(A,34,25),de(A,35,25)}(A)},btVector3_create:function(A,e,r){var i;return A=_(A),e=_(e),r=_(r),i=dA(16),a[i+12>>2]=0,C[i+8>>2]=r,C[i+4>>2]=e,C[i>>2]=A,0|i},btVector3_setValue:function(A,e,r,i){A|=0,e=_(e),r=_(r),i=_(i),a[A+12>>2]=0,C[A+8>>2]=i,C[A+4>>2]=r,C[A>>2]=e},btVector3_x:et,btVector3_y:rt,btVector3_z:it,btQuaternion_create:function(A,e,r,i){var f;return A=_(A),e=_(e),r=_(r),i=_(i),f=q(16),C[f+12>>2]=i,C[f+8>>2]=r,C[f+4>>2]=e,C[f>>2]=A,0|f},btQuaternion_setValue:function(A,e,r,i,f){A|=0,e=_(e),r=_(r),i=_(i),f=_(f),C[A+12>>2]=f,C[A+8>>2]=i,C[A+4>>2]=r,C[A>>2]=e},btQuaternion_x:et,btQuaternion_y:rt,btQuaternion_z:it,btQuaternion_w:function(A){return A|=0,_(C[A+12>>2])},btTransform_create:function(){return 0|q(64)},btTransform_setOrigin:function(A,e){A|=0,e|=0;var r=0;r=a[e+4>>2],a[A+48>>2]=a[e>>2],a[A+52>>2]=r,e=e+8|0,r=a[e+4>>2],A=A+56|0,a[A>>2]=a[e>>2],a[A+4>>2]=r},btTransform_setRotation:function(A,e){A|=0,e|=0;var r=_(0),i=_(0),f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0);i=C[e+12>>2],o=C[e+8>>2],r=C[e>>2],t=C[e+4>>2],a[A+44>>2]=0,a[A+28>>2]=0,a[A+12>>2]=0,f=_(_(2)/_(_(_(_(r*r)+_(t*t))+_(o*o))+_(i*i))),c=_(o*f),n=_(t*c),l=_(r*f),u=_(i*l),C[A+36>>2]=n+u,s=_(r*c),f=_(t*f),b=_(i*f),C[A+32>>2]=s-b,C[A+24>>2]=n-u,n=_(r*f),i=_(i*c),C[A+16>>2]=n+i,C[A+8>>2]=s+b,C[A+4>>2]=n-i,r=_(r*l),i=_(t*f),C[A+40>>2]=_(1)-_(r+i),b=r,r=_(o*c),C[A+20>>2]=_(1)-_(b+r),C[A>>2]=_(1)-_(i+r)},btTransform_getOrigin:ft,btTransform_getRotation:function(A){var e,r;return A|=0,e=Y-16|0,Y=e,tt(A,e),A=e+8|0,r=a[A+4>>2],a[709]=a[A>>2],a[710]=r,A=a[e+4>>2],a[707]=a[e>>2],a[708]=A,Y=e+16|0,2828},btTransform_setIdentity:function(A){A|=0;var e=0;a[A+4>>2]=0,a[A+8>>2]=0,a[A>>2]=1065353216,a[A+32>>2]=0,a[A+36>>2]=0,e=A+12|0,a[e>>2]=0,a[e+4>>2]=0,e=A+24|0,a[e>>2]=0,a[e+4>>2]=0,a[A+20>>2]=1065353216,e=A+44|0,a[e>>2]=0,a[e+4>>2]=0,a[A+40>>2]=1065353216,e=A+52|0,a[e>>2]=0,a[e+4>>2]=0,a[A+60>>2]=0},btTransform_equal:Rr,btMotionState_destroy:nt,layaMotionState_create:function(){var A;return A=q(8),a[A>>2]=0,a[A+4>>2]=0,a[A>>2]=24708,0|A},layaMotionState_set_rigidBodyID:function(A,e){A|=0,e|=0,a[A+4>>2]=e},btCollisionObject_create:function(){var A;return A=dA(324),Ee(A),0|A},btCollisionObject_setContactProcessingThreshold:function(A,e){A|=0,e=_(e),C[A+184>>2]=e},btCollisionObject_setActivationState:function(A,e){A|=0,e|=0,Ye(A,e)},btCollisionObject_forceActivationState:function(A,e){A|=0,e|=0,a[A+220>>2]=e},btCollisionObject_activate:function(A,e){A|=0,e|=0,Ve(A,e)},btCollisionObject_isActive:function(A){return A|=0,A=a[A+220>>2],2!=(0|A)&5!=(0|A)},btCollisionObject_setRestitution:function(A,e){A|=0,e=_(e),C[A+232>>2]=e,a[A+304>>2]=a[A+304>>2]+1},btCollisionObject_setFriction:function(A,e){A|=0,e=_(e),C[A+228>>2]=e,a[A+304>>2]=a[A+304>>2]+1},btCollisionObject_setRollingFriction:function(A,e){A|=0,e=_(e),C[A+236>>2]=e,a[A+304>>2]=a[A+304>>2]+1},btCollisionObject_getCollisionFlags:function(A){return A|=0,a[A+204>>2]},btCollisionObject_setCollisionFlags:function(A,e){A|=0,e|=0,a[A+204>>2]=e},btCollisionObject_getWorldTransform:hi,btCollisionObject_setWorldTransform:function(A,e){A|=0,e|=0;var r=0,i=0,f=0;a[A+304>>2]=a[A+304>>2]+1,i=e+8|0,f=a[i+4>>2],r=A+12|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,r=a[e+4>>2],a[A+4>>2]=a[e>>2],a[A+8>>2]=r,i=e+24|0,f=a[i+4>>2],r=A+28|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,i=a[e+20>>2],r=A+20|0,a[r>>2]=a[e+16>>2],a[r+4>>2]=i,i=a[e+36>>2],r=A+36|0,a[r>>2]=a[e+32>>2],a[r+4>>2]=i,i=e+40|0,f=a[i+4>>2],r=A+44|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,i=e+56|0,f=a[i+4>>2],r=A+60|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,r=a[e+52>>2],A=A+52|0,a[A>>2]=a[e+48>>2],a[A+4>>2]=r},btCollisionObject_setInterpolationWorldTransform:function(A,e){A|=0,e|=0;var r=0,i=0,f=0;a[A+304>>2]=a[A+304>>2]+1,i=e+8|0,f=a[i+4>>2],r=A+76|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,r=a[e+4>>2],a[A+68>>2]=a[e>>2],a[A+72>>2]=r,i=e+24|0,f=a[i+4>>2],r=A+92|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,i=a[e+20>>2],r=A+84|0,a[r>>2]=a[e+16>>2],a[r+4>>2]=i,i=a[e+36>>2],r=A+100|0,a[r>>2]=a[e+32>>2],a[r+4>>2]=i,i=e+40|0,f=a[i+4>>2],r=A+108|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,i=e+56|0,f=a[i+4>>2],r=A+124|0,a[r>>2]=a[i>>2],a[r+4>>2]=f,r=a[e+52>>2],A=A+116|0,a[A>>2]=a[e+48>>2],a[A+4>>2]=r},btCollisionObject_setCollisionShape:function(A,e){A|=0,e|=0,Qt[a[a[A>>2]+8>>2]](A,e)},btCollisionObject_getCcdMotionThreshold:function(A){return A|=0,_(C[A+276>>2])},btCollisionObject_setCcdMotionThreshold:function(A,e){A|=0,e=_(e),C[A+276>>2]=e},btCollisionObject_getCcdSweptSphereRadius:function(A){return A|=0,_(C[A+272>>2])},btCollisionObject_setCcdSweptSphereRadius:function(A,e){A|=0,e=_(e),C[A+272>>2]=e},btCollisionObject_getUserIndex:function(A){return A|=0,a[A+264>>2]},btCollisionObject_setUserIndex:function(A,e){A|=0,e|=0,a[A+264>>2]=e},btCollisionObject_getActivationState:function(A){return A|=0,a[A+220>>2]},btCollisionObject_setInterpolationAngularVelocity:function(A,e){A|=0,e|=0;var r=0;a[A+304>>2]=a[A+304>>2]+1,r=a[e+4>>2],a[A+148>>2]=a[e>>2],a[A+152>>2]=r,e=e+8|0,r=a[e+4>>2],A=A+156|0,a[A>>2]=a[e>>2],a[A+4>>2]=r},btCollisionObject_setInterpolationLinearVelocity:function(A,e){A|=0,e|=0;var r=0;a[A+304>>2]=a[A+304>>2]+1,r=a[e+4>>2],a[A+132>>2]=a[e>>2],a[A+136>>2]=r,e=e+8|0,r=a[e+4>>2],A=A+140|0,a[A>>2]=a[e>>2],a[A+4>>2]=r},btCollisionObject_destroy:nt,RayResultCallback_set_m_flags:function(A,e){A|=0,e|=0,a[A+20>>2]=e},RayResultCallback_hasHit:function(A){return A|=0,0!=a[A+8>>2]|0},RayResultCallback_set_m_collisionFilterGroup:at,RayResultCallback_set_m_collisionFilterMask:function(A,e){A|=0,e|=0,a[A+16>>2]=e},RayResultCallback_get_m_closestHitFraction:rt,RayResultCallback_set_m_closestHitFraction:ot,RayResultCallback_get_m_collisionObject:mi,RayResultCallback_set_m_collisionObject:ct,ClosestRayResultCallback_create:function(A,e){A|=0,e|=0;var r,i,f=0;return r=q(88),a[r+20>>2]=0,a[r+12>>2]=1,a[r+16>>2]=-1,a[r+4>>2]=1065353216,a[r+8>>2]=0,a[r>>2]=24788,f=a[A+4>>2],a[r+24>>2]=a[A>>2],a[r+28>>2]=f,A=A+8|0,i=a[A+4>>2],f=r+32|0,a[f>>2]=a[A>>2],a[f+4>>2]=i,A=a[e+4>>2],a[r+40>>2]=a[e>>2],a[r+44>>2]=A,e=e+8|0,f=a[e+4>>2],A=r+48|0,a[A>>2]=a[e>>2],a[A+4>>2]=f,0|r},ClosestRayResultCallback_get_m_rayFromWorld:bt,ClosestRayResultCallback_set_m_rayFromWorld:function(A,e){A|=0,e|=0;var r=0;r=a[e+4>>2],a[A+24>>2]=a[e>>2],a[A+28>>2]=r,e=e+8|0,r=a[e+4>>2],A=A+32|0,a[A>>2]=a[e>>2],a[A+4>>2]=r},ClosestRayResultCallback_get_m_rayToWorld:function(A){return A|=0,A+40|0},ClosestRayResultCallback_set_m_rayToWorld:function(A,e){A|=0,e|=0;var r=0;r=a[e+4>>2],a[A+40>>2]=a[e>>2],a[A+44>>2]=r,e=e+8|0,r=a[e+4>>2],A=A+48|0,a[A>>2]=a[e>>2],a[A+4>>2]=r},ClosestRayResultCallback_get_m_hitNormalWorld:Le,ClosestRayResultCallback_get_m_hitPointWorld:ze,tBtCollisionObjectArray_size:function(A){return A|=0,a[A+4>>2]},tBtCollisionObjectArray_at:function(A,e){return A|=0,e|=0,a[a[A+12>>2]+(e<<2)>>2]},tBtCollisionObjectArray_clear:lt,tVector3Array_at:function(A,e){return A|=0,e|=0,a[A+12>>2]+(e<<4)|0},tVector3Array_clear:lt,tScalarArray_at:function(A,e){return A|=0,e|=0,_(C[a[A+12>>2]+(e<<2)>>2])},tScalarArray_clear:lt,AllHitsRayResultCallback_create:function(A,e){A|=0,e|=0;var r,i,t=0;return r=q(136),a[r+28>>2]=0,a[r+32>>2]=0,a[r+20>>2]=0,a[r+12>>2]=1,a[r+16>>2]=-1,a[r+4>>2]=1065353216,a[r+8>>2]=0,f[r+40|0]=1,a[r>>2]=24920,a[r+36>>2]=0,t=a[A+4>>2],a[r+44>>2]=a[A>>2],a[r+48>>2]=t,t=A+8|0,A=a[t+4>>2],i=r+52|0,a[i>>2]=a[t>>2],a[i+4>>2]=A,A=a[e+4>>2],a[r+60>>2]=a[e>>2],a[r+64>>2]=A,A=e+8|0,t=a[A>>2],e=a[A+4>>2],a[r+88>>2]=0,a[r+80>>2]=0,a[r+84>>2]=0,a[r+120>>2]=0,a[r+124>>2]=0,a[r+128>>2]=0,a[r+108>>2]=0,f[r+132|0]=1,f[r+112|0]=1,f[r+92|0]=1,a[r+100>>2]=0,a[r+104>>2]=0,A=r+68|0,a[A>>2]=t,a[A+4>>2]=e,0|r},AllHitsRayResultCallback_get_m_rayFromWorld:function(A){return A|=0,A+44|0},AllHitsRayResultCallback_set_m_rayFromWorld:function(A,e){A|=0,e|=0;var r=0;r=a[e+4>>2],a[A+44>>2]=a[e>>2],a[A+48>>2]=r,e=e+8|0,r=a[e+4>>2],A=A+52|0,a[A>>2]=a[e>>2],a[A+4>>2]=r},AllHitsRayResultCallback_get_m_rayToWorld:function(A){return A|=0,A+60|0},AllHitsRayResultCallback_set_m_rayToWorld:function(A,e){A|=0,e|=0;var r=0;r=a[e+4>>2],a[A+60>>2]=a[e>>2],a[A+64>>2]=r,e=e+8|0,r=a[e+4>>2],A=A+68|0,a[A>>2]=a[e>>2],a[A+4>>2]=r},AllHitsRayResultCallback_get_m_hitPointWorld:function(A){return A|=0,A+96|0},AllHitsRayResultCallback_get_m_hitNormalWorld:function(A){return A|=0,A+76|0},AllHitsRayResultCallback_get_m_collisionObjects:bt,AllHitsRayResultCallback_get_m_hitFractions:function(A){return A|=0,A+116|0},btManifoldPoint_get_m_positionWorldOnA:ft,btManifoldPoint_get_m_positionWorldOnB:ut,btManifoldPoint_get_m_normalWorldOnB:st,btManifoldPoint_getDistance:function(A){return A|=0,_(C[A+80>>2])},ConvexResultCallback_hasHit:function(A){return A|=0,C[A+4>>2]<_(1)|0},ConvexResultCallback_set_m_collisionFilterGroup:ct,ConvexResultCallback_set_m_collisionFilterMask:at,ConvexResultCallback_get_m_closestHitFraction:rt,ConvexResultCallback_set_m_closestHitFraction:ot,ClosestConvexResultCallback_create:function(A,e){A|=0,e|=0;var r,i,f=0;return r=q(84),a[r+12>>2]=-1,a[r+4>>2]=1065353216,a[r+8>>2]=1,a[r>>2]=25004,f=a[A+4>>2],a[r+16>>2]=a[A>>2],a[r+20>>2]=f,A=A+8|0,i=a[A+4>>2],f=r+24|0,a[f>>2]=a[A>>2],a[f+4>>2]=i,A=a[e+4>>2],a[r+32>>2]=a[e>>2],a[r+36>>2]=A,e=e+8|0,f=a[e+4>>2],A=r+40|0,a[A>>2]=a[e>>2],a[A+4>>2]=f,a[r+80>>2]=0,0|r},ClosestConvexResultCallback_get_m_hitNormalWorld:ft,ClosestConvexResultCallback_get_m_hitPointWorld:st,ClosestConvexResultCallback_get_m_hitCollisionObject:function(A){return A|=0,a[A+80>>2]},ClosestConvexResultCallback_set_m_hitCollisionObject:function(A,e){A|=0,e|=0,a[A+80>>2]=e},AllConvexResultCallback_create:function(A,e){A|=0,e|=0;var r,i,t=0;return r=q(128),a[r+20>>2]=0,a[r+24>>2]=0,a[r+12>>2]=-1,a[r+4>>2]=1065353216,a[r+8>>2]=1,f[r+32|0]=1,a[r>>2]=25144,a[r+28>>2]=0,t=a[A+4>>2],a[r+36>>2]=a[A>>2],a[r+40>>2]=t,A=A+8|0,i=a[A+4>>2],t=r+44|0,a[t>>2]=a[A>>2],a[t+4>>2]=i,A=a[e+4>>2],a[r+52>>2]=a[e>>2],a[r+56>>2]=A,A=e+8|0,e=a[A>>2],A=a[A+4>>2],a[r+80>>2]=0,a[r+72>>2]=0,a[r+76>>2]=0,a[r+100>>2]=0,a[r+112>>2]=0,a[r+116>>2]=0,a[r+120>>2]=0,f[r+124|0]=1,f[r+104|0]=1,f[r+84|0]=1,a[r+92>>2]=0,a[r+96>>2]=0,t=r+60|0,a[t>>2]=e,a[t+4>>2]=A,0|r},AllConvexResultCallback_get_m_hitNormalWorld:function(A){return A|=0,A+68|0},AllConvexResultCallback_get_m_hitPointWorld:function(A){return A|=0,A+88|0},AllConvexResultCallback_get_m_hitFractions:function(A){return A|=0,A+108|0},AllConvexResultCallback_get_m_collisionObjects:Qe,btCollisionShape_getLocalScaling:function(A){return A|=0,0|Qt[a[a[A>>2]+28>>2]](A)},btCollisionShape_setLocalScaling:function(A,e){A|=0,e|=0,Qt[a[a[A>>2]+24>>2]](A,e)},btCollisionShape_calculateLocalInertia:function(A,e,r){A|=0,e=_(e),r|=0,Qt[a[a[A>>2]+32>>2]](A,e,r)},btCollisionShape_destroy:nt,btBoxShape_create:function(A){var e;return A|=0,e=dA(60),function(A,e){var r=_(0),i=_(0),f=_(0),t=_(0);zA(A),r=C[e>>2],f=C[e+4>>2],i=C[e+8>>2],a[A+44>>2]=0,t=_(i*C[A+24>>2]),i=C[A+48>>2],C[A+40>>2]=t-i,C[A+36>>2]=_(f*C[A+20>>2])-i,C[A+32>>2]=_(r*C[A+16>>2])-i,a[A+4>>2]=0,a[A>>2]=9056,r=C[e>>2],f=C[e+8>>2],t=C[e+4>>2],r=_(C[((r>2]*_(.10000000149011612)),r>2]=e,a[A>>2]=6056,a[A+56>>2]=1,a[A+4>>2]=10,a[A+44>>2]=0,C[A+40>>2]=e,C[A+36>>2]=r*_(.5),C[A+32>>2]=e}(r,A,e),0|r},btCapsuleShapeX_create:function(A,e){var r;return A=_(A),e=_(e),r=dA(60),function(A,e,r){DA(A),a[A+56>>2]=0,C[A+48>>2]=e,a[A>>2]=6156,a[A+4>>2]=10,a[A+44>>2]=0,C[A+40>>2]=e,C[A+36>>2]=e,C[A+32>>2]=r*_(.5)}(r,A,e),0|r},btCapsuleShapeZ_create:function(A,e){var r;return A=_(A),e=_(e),r=dA(60),function(A,e,r){DA(A),a[A+56>>2]=2,C[A+48>>2]=e,a[A>>2]=6256,a[A+4>>2]=10,a[A+44>>2]=0,C[A+40>>2]=r*_(.5),C[A+36>>2]=e,C[A+32>>2]=e}(r,A,e),0|r},btCylinderShape_create:function(A){var e;return A|=0,e=dA(60),function(A,e){var r=_(0),i=_(0),f=_(0),t=_(0);DA(A),r=C[e>>2],f=C[e+4>>2],i=C[e+8>>2],a[A+44>>2]=0,t=_(i*C[A+24>>2]),i=C[A+48>>2],C[A+40>>2]=t-i,C[A+36>>2]=_(f*C[A+20>>2])-i,C[A+32>>2]=_(r*C[A+16>>2])-i,a[A+56>>2]=1,a[A>>2]=9392,r=C[e>>2],f=C[e+8>>2],t=C[e+4>>2],r=_(C[((r>2]*_(.10000000149011612)),r>2]=13}(e,A),0|e},btCylinderShapeX_create:function(A){var e;return A|=0,e=dA(60),function(A,e){var r=_(0),i=_(0),f=_(0),t=_(0);DA(A),r=C[e>>2],f=C[e+4>>2],i=C[e+8>>2],a[A+44>>2]=0,t=_(i*C[A+24>>2]),i=C[A+48>>2],C[A+40>>2]=t-i,C[A+36>>2]=_(f*C[A+20>>2])-i,C[A+32>>2]=_(r*C[A+16>>2])-i,a[A+56>>2]=1,a[A>>2]=9392,r=C[e>>2],f=C[e+8>>2],t=C[e+4>>2],r=_(C[((r>2]*_(.10000000149011612)),r>2]=0,a[A>>2]=9496,a[A+4>>2]=13}(e,A),0|e},btCylinderShapeZ_create:function(A){var e;return A|=0,e=dA(60),function(A,e){var r=_(0),i=_(0),f=_(0),t=_(0);DA(A),r=C[e>>2],f=C[e+4>>2],i=C[e+8>>2],a[A+44>>2]=0,t=_(i*C[A+24>>2]),i=C[A+48>>2],C[A+40>>2]=t-i,C[A+36>>2]=_(f*C[A+20>>2])-i,C[A+32>>2]=_(r*C[A+16>>2])-i,a[A+56>>2]=1,a[A>>2]=9392,r=C[e>>2],f=C[e+8>>2],t=C[e+4>>2],r=_(C[((r>2]*_(.10000000149011612)),r>2]=2,a[A>>2]=9600,a[A+4>>2]=13}(e,A),0|e},btSphereShape_create:function(A){var e,r;return A=_(A),e=dA(56),DA(e),a[e+28>>2]=0,a[e+32>>2]=0,a[e+24>>2]=1065353216,a[e+16>>2]=1065353216,a[e+20>>2]=1065353216,a[e+4>>2]=8,a[e>>2]=9852,r=e+36|0,a[r>>2]=0,a[r+4>>2]=0,a[e+44>>2]=0,a[e+52>>2]=0,C[e+48>>2]=A,C[e+32>>2]=A,0|e},btConeShape_create:function(A,e){var r;return A=_(A),e=_(e),r=dA(80),function(A,e,r){DA(A),C[A+64>>2]=r,C[A+60>>2]=e,a[A>>2]=6504,a[A+76>>2]=2,a[A+68>>2]=0,a[A+72>>2]=1,a[A+4>>2]=11,C[A+40>>2]=e,C[A+36>>2]=r,C[A+32>>2]=e,C[A+56>>2]=e/_(y(_(_(e*e)+_(r*r))))}(r,A,e),0|r},btConeShapeX_create:function(A,e){var r;return A=_(A),e=_(e),r=dA(80),function(A,e,r){DA(A),C[A+64>>2]=r,C[A+60>>2]=e,a[A+4>>2]=11,a[A+76>>2]=2,a[A+68>>2]=1,a[A+72>>2]=0,a[A>>2]=6704,C[A+36>>2]=e,C[A+40>>2]=e,C[A+32>>2]=r,C[A+56>>2]=e/_(y(_(_(e*e)+_(r*r))))}(r,A,e),0|r},btConeShapeZ_create:function(A,e){var r;return A=_(A),e=_(e),r=dA(80),function(A,e,r){DA(A),C[A+64>>2]=r,C[A+60>>2]=e,a[A+4>>2]=11,a[A+76>>2]=1,a[A+68>>2]=0,a[A+72>>2]=2,a[A>>2]=6604,C[A+40>>2]=r,C[A+32>>2]=e,C[A+36>>2]=e,C[A+56>>2]=e/_(y(_(_(e*e)+_(r*r))))}(r,A,e),0|r},btStaticPlaneShape_create:function(A,e){var r;return A|=0,e=_(e),r=dA(88),function(A,e,r){var i,f=_(0),t=_(0),n=_(0);He(A),a[A>>2]=10412,f=C[e+8>>2],t=C[e>>2],n=C[e+4>>2],e=a[e+12>>2],i=A+80|0,a[i>>2]=1065353216,a[i+4>>2]=0,a[A+72>>2]=1065353216,a[A+76>>2]=1065353216,C[A+68>>2]=r,a[A- -64>>2]=e,a[A+4>>2]=28,r=_(_(1)/_(y(_(_(_(t*t)+_(n*n))+_(f*f))))),C[A+60>>2]=f*r,C[A+56>>2]=n*r,C[A+52>>2]=t*r}(r,A,e),0|r},btGImpactShapeInterface_updateBound:function(A){A|=0,o[A+52|0]&&(Qt[a[a[A>>2]+68>>2]](A),f[A+52|0]=0)},btGImpactMeshShape_create:function(A){var e;return A|=0,e=dA(172),function(A,e){var r=0,i=0,t=0,n=0,c=0,b=0,l=0;if(He(A),r=A- -64|0,a[r>>2]=1065353216,a[r+4>>2]=0,a[A+56>>2]=1065353216,a[A+60>>2]=1065353216,r=A+36|0,a[r>>2]=-8388609,a[r+4>>2]=-8388609,a[A+20>>2]=2139095039,a[A+24>>2]=2139095039,a[A>>2]=10820,a[A+88>>2]=0,f[A+92|0]=1,r=A+80|0,a[r>>2]=0,a[r+4>>2]=0,a[A+144>>2]=0,a[A+72>>2]=0,f[A+52|0]=1,a[A+44>>2]=-8388609,a[A+28>>2]=2139095039,a[A+4>>2]=25,f[A+168|0]=1,a[A+164>>2]=0,r=A+156|0,a[r>>2]=0,a[r+4>>2]=0,a[A+148>>2]=e,(0|Qt[a[a[e>>2]+28>>2]](e))>=1)for(;;){if(l=dA(216),Pe(l,e,c),i=a[A+156>>2],(0|i)==a[A+160>>2]&&(t=i?i<<1:1,!((0|i)>=(0|t)))){if(t?(b=dA(t<<2),i=a[A+156>>2]):b=0,(0|i)>=1)for(n=0,r=i;a[n+b>>2]=a[a[A+164>>2]+n>>2],n=n+4|0,r=r+-1|0,r;);r=a[A+164>>2],r&&(o[A+168|0]&&(CA(r),i=a[A+156>>2]),a[A+164>>2]=0),a[A+164>>2]=b,f[A+168|0]=1,a[A+160>>2]=t}if(a[A+156>>2]=i+1,a[a[A+164>>2]+(i<<2)>>2]=l,c=c+1|0,!((0|c)<(0|Qt[a[a[e>>2]+28>>2]](e))))break}}(e,A),0|e},btCompoundShape_create:function(){var A;return A=dA(96),function(A){var e=0,r=0,i=0,t=0,n=0,c=0,b=0,l=0;if(a[A+12>>2]=-1,a[A+4>>2]=31,a[A+8>>2]=0,a[A>>2]=14216,a[A+76>>2]=0,a[A+80>>2]=1065353216,a[A+68>>2]=0,a[A+72>>2]=1,a[A+52>>2]=-581039253,a[A+56>>2]=-581039253,a[A+36>>2]=1566444395,a[A+40>>2]=1566444395,f[A+32|0]=1,a[A+28>>2]=0,a[A+92>>2]=0,e=A+84|0,a[e>>2]=1065353216,a[e+4>>2]=1065353216,e=A+60|0,a[e>>2]=-581039253,a[e+4>>2]=0,e=A+44|0,a[e>>2]=1566444395,a[e+4>>2]=0,e=A+20|0,a[e>>2]=0,a[e+4>>2]=0,e=dA(40),er(e),a[A+68>>2]=e,a[A+24>>2]<0){if(l=a[A+20>>2],(0|l)>=1)for(e=64;n=a[A+28>>2]+e|0,r=n+-64|0,t=a[r+4>>2],i=e+-64|0,a[i>>2]=a[r>>2],a[i+4>>2]=t,r=r+8|0,t=a[r+4>>2],i=i+8|0,a[i>>2]=a[r>>2],a[i+4>>2]=t,r=n+-48|0,i=r+8|0,b=a[i+4>>2],t=e+-48|0,c=t+8|0,a[c>>2]=a[i>>2],a[c+4>>2]=b,i=a[r+4>>2],a[t>>2]=a[r>>2],a[t+4>>2]=i,r=n+-32|0,i=r+8|0,b=a[i+4>>2],t=e+-32|0,c=t+8|0,a[c>>2]=a[i>>2],a[c+4>>2]=b,i=a[r+4>>2],a[t>>2]=a[r>>2],a[t+4>>2]=i,r=n+-16|0,i=r+8|0,b=a[i+4>>2],t=e+-16|0,c=t+8|0,a[c>>2]=a[i>>2],a[c+4>>2]=b,i=a[r+4>>2],a[t>>2]=a[r>>2],a[t+4>>2]=i,r=a[n+4>>2],a[e>>2]=a[n>>2],a[e+4>>2]=r,n=n+8|0,r=a[n+4>>2],t=e+8|0,a[t>>2]=a[n>>2],a[t+4>>2]=r,e=e+80|0,l=l+-1|0,l;);e=a[A+28>>2],e&&(o[A+32|0]&&CA(e),a[A+28>>2]=0),a[A+28>>2]=0,f[A+32|0]=1,a[A+24>>2]=0}}(A),0|A},btCompoundShape_addChildShape:function(A,e,r){A|=0,e|=0,r|=0,gr(A,e,r)},btCompoundShape_removeChildShapeByIndex:function(A,e){A|=0,e|=0,Br(A,e)},btCompoundShape_getChildShape:function(A,e){return A|=0,e|=0,a[64+(a[A+28>>2]+B(e,80)|0)>>2]},btCompoundShape_updateChildTransform:function(A,e,r,i){A|=0,e|=0,r|=0,i|=0,function(A,e,r,i){var f,t,n=0,o=0,c=0;f=Y+-64|0,Y=f,o=a[r+4>>2],t=B(e,80),e=t+a[A+28>>2]|0,a[e>>2]=a[r>>2],a[e+4>>2]=o,o=r+8|0,c=a[o+4>>2],n=e+8|0,a[n>>2]=a[o>>2],a[n+4>>2]=c,o=r+24|0,c=a[o+4>>2],n=e+24|0,a[n>>2]=a[o>>2],a[n+4>>2]=c,n=a[r+20>>2],a[e+16>>2]=a[r+16>>2],a[e+20>>2]=n,o=r+40|0,c=a[o+4>>2],n=e+40|0,a[n>>2]=a[o>>2],a[n+4>>2]=c,n=a[r+36>>2],a[e+32>>2]=a[r+32>>2],a[e+36>>2]=n,o=r+56|0,c=a[o+4>>2],n=e+56|0,a[n>>2]=a[o>>2],a[n+4>>2]=c,n=a[r+52>>2],a[e+48>>2]=a[r+48>>2],a[e+52>>2]=n,a[A+68>>2]&&(e=a[64+(a[A+28>>2]+t|0)>>2],Qt[a[a[e>>2]+8>>2]](e,r,f+48|0,f+32|0),r=f+56|0,n=a[r+4>>2],e=f+8|0,a[e>>2]=a[r>>2],a[e+4>>2]=n,r=f+40|0,n=a[r+4>>2],e=f+24|0,a[e>>2]=a[r>>2],a[e+4>>2]=n,e=a[f+36>>2],a[f+16>>2]=a[f+32>>2],a[f+20>>2]=e,e=a[f+52>>2],a[f>>2]=a[f+48>>2],a[f+4>>2]=e,cr(a[A+68>>2],a[76+(a[A+28>>2]+t|0)>>2],f)),i&&Qt[a[a[A>>2]+68>>2]](A),Y=f- -64|0}(A,e,r,i)},btStridingMeshInterface_destroy:nt,btTriangleMesh_create:function(){var A;return A=dA(172),function(A){var e=0,r=0,i=0,t=0,n=0,c=0,b=0,l=0;if(a[A+4>>2]=1065353216,a[A+8>>2]=1065353216,a[A+48>>2]=0,a[A>>2]=14676,f[A+36|0]=1,e=A+12|0,a[e>>2]=1065353216,a[e+4>>2]=0,a[A+32>>2]=0,r=A+24|0,e=r,a[e>>2]=0,a[e+4>>2]=0,f[A+100|0]=1,a[A+96>>2]=0,f[A+120|0]=1,e=A+88|0,a[e>>2]=0,a[e+4>>2]=0,a[A+116>>2]=0,f[A+140|0]=1,e=A+108|0,a[e>>2]=0,a[e+4>>2]=0,a[A+136>>2]=0,f[A+160|0]=1,e=A+128|0,a[e>>2]=0,a[e+4>>2]=0,a[A+168>>2]=0,f[A+164|0]=1,e=A+148|0,a[e>>2]=0,a[e+4>>2]=0,a[A+156>>2]=0,f[A+165|0]=1,e=dA(32),n=a[r>>2],(0|n)>=1)for(;c=a[A+32>>2]+t|0,i=c,b=a[i+4>>2],r=e+t|0,a[r>>2]=a[i>>2],a[r+4>>2]=b,i=i+24|0,b=a[i+4>>2],l=r+24|0,a[l>>2]=a[i>>2],a[l+4>>2]=b,i=c+16|0,b=a[i+4>>2],l=r+16|0,a[l>>2]=a[i>>2],a[l+4>>2]=b,c=c+8|0,i=a[c+4>>2],r=r+8|0,a[r>>2]=a[c>>2],a[r+4>>2]=i,t=t+32|0,n=n+-1|0,n;);t=a[A+32>>2],t&&(o[A+36|0]&&CA(t),a[A+32>>2]=0),a[A+32>>2]=e,f[A+36|0]=1,a[A+28>>2]=1,e=(a[A+24>>2]<<5)+e|0,a[e+24>>2]=2,a[e+28>>2]=0,a[e+16>>2]=0,a[e+20>>2]=16,a[e+8>>2]=12,a[e+12>>2]=0,a[e>>2]=0,a[e+4>>2]=0,a[A+24>>2]=a[A+24>>2]+1,e=a[A+32>>2],a[e+4>>2]=0,t=o[A+164|0],a[e+24>>2]=t?2:3,n=a[(t?128:148)+A>>2],r=12,a[e+8>>2]=t?12:6,a[e>>2]=(0|n)/3,o[A+165|0]?(r=16,A=a[A+88>>2]):A=a[A+108>>2]/3|0,a[e+20>>2]=r,a[e+16>>2]=0,a[e+12>>2]=A}(A),0|A},btTriangleMesh_addTriangle:function(A,e,r,i,f){A|=0,e|=0,r|=0,i|=0,f|=0,function(A,e,r,i,f){var t;t=a[A+32>>2],a[t>>2]=a[t>>2]+1,Qr(A,hr(A,e,f)),Qr(A,hr(A,r,f)),Qr(A,hr(A,i,f))}(A,e,r,i,f)},btDefaultCollisionConfiguration_create:function(){var A,e;return A=Y-32|0,Y=A,e=q(88),a[A+24>>2]=0,a[A+28>>2]=1,a[A+16>>2]=4096,a[A+20>>2]=4096,a[A+8>>2]=0,a[A+12>>2]=0,Bi(e,A+8|0),Y=A+32|0,0|e},btDefaultCollisionConfiguration_destroy:nt,btPersistentManifold_getBody0:function(A){return A|=0,a[A+772>>2]},btPersistentManifold_getBody1:function(A){return A|=0,a[A+776>>2]},btPersistentManifold_getNumContacts:function(A){return A|=0,a[A+780>>2]},btPersistentManifold_getContactPoint:function(A,e){return A|=0,e|=0,4+(B(e,192)+A|0)|0},btDispatcher_getNumManifolds:kt,btDispatcher_getManifoldByIndexInternal:function(A,e){return A|=0,e|=0,0|Qt[a[a[A>>2]+40>>2]](A,e)},btCollisionDispatcher_create:function(A){var e;return A|=0,e=q(10448),function(A,e){var r=0,i=0,t=0,n=0,o=0,c=0;for(a[A+28>>2]=7720,a[A>>2]=7860,a[A+4>>2]=2,a[A+10444>>2]=e,a[A+64>>2]=111,f[A+24|0]=1,a[A+20>>2]=0,a[A+60>>2]=0,r=A+12|0,a[r>>2]=0,a[r+4>>2]=0,o=A,c=0|Qt[a[a[e>>2]+12>>2]](e),a[o+68>>2]=c,o=A,c=0|Qt[a[a[e>>2]+8>>2]](e),a[o+72>>2]=c,r=A+5260|0;;){for(e=r,i=0;t=a[A+10444>>2],o=e+-5184|0,c=0|Qt[a[a[t>>2]+16>>2]](t,n,i),a[o>>2]=c,t=a[A+10444>>2],o=e,c=0|Qt[a[a[t>>2]+20>>2]](t,n,i),a[o>>2]=c,e=e+4|0,i=i+1|0,36!=(0|i););if(r=r+144|0,n=n+1|0,36==(0|n))break}}(e,A),0|e},btCollisionDispatcher_destroy:nt,btOverlappingPairCache_setInternalGhostPairCallback:vt,btDbvtBroadphase_create:function(){var A;return A=q(176),yi(A),0|A},btDbvtBroadphase_getOverlappingPairCache:kt,btDbvtBroadphase_destroy:nt,btRigidBodyConstructionInfo_create:function(A,e,r,i){var t;return A=_(A),e|=0,r|=0,i|=0,t=q(144),a[t+72>>2]=r,a[t+4>>2]=e,C[t>>2]=A,e=a[i+4>>2],a[t+76>>2]=a[i>>2],a[t+80>>2]=e,r=i+8|0,e=a[r+4>>2],i=t+84|0,a[i>>2]=a[r>>2],a[i+4>>2]=e,a[t+136>>2]=1008981770,a[t+140>>2]=1008981770,a[t+128>>2]=1000593162,a[t+132>>2]=1008981770,f[t+124|0]=0,a[t+116>>2]=1061997773,a[t+120>>2]=1065353216,a[t+108>>2]=0,a[t+112>>2]=0,a[t+100>>2]=1056964608,a[t+104>>2]=0,a[t+92>>2]=0,a[t+96>>2]=0,a[t+8>>2]=1065353216,e=t+20|0,a[e>>2]=0,a[e+4>>2]=0,a[t+12>>2]=0,a[t+16>>2]=0,a[t+28>>2]=1065353216,e=t+40|0,a[e>>2]=0,a[e+4>>2]=0,a[t+32>>2]=0,a[t+36>>2]=0,a[t+48>>2]=1065353216,a[t+68>>2]=0,e=t+60|0,a[e>>2]=0,a[e+4>>2]=0,a[t+52>>2]=0,a[t+56>>2]=0,0|t},btRigidBodyConstructionInfo_destroy:function(A){A|=0,A&&$(A)},btRigidBody_create:function(A){var e;return A|=0,e=dA(676),Ii(e,A),0|e},btRigidBody_setCenterOfMassTransform:ji,btRigidBody_setSleepingThresholds:function(A,e,r){A|=0,e=_(e),r=_(r),C[A+536>>2]=r,C[A+532>>2]=e},btRigidBody_getLinearSleepingThreshold:function(A){return A|=0,_(C[A+532>>2])},btRigidBody_getAngularSleepingThreshold:function(A){return A|=0,_(C[A+536>>2])},btRigidBody_setDamping:function(A,e,r){A|=0,e=_(e),r=_(r),function(A,e,r){var i;i=Y-16|0,C[i+8>>2]=r,C[i+12>>2]=e,a[i+4>>2]=0,a[i>>2]=1065353216,a[A+504>>2]=a[(e<_(0)?i+4|0:e>_(1)?i:i+12|0)>>2],a[i+4>>2]=0,a[i>>2]=1065353216,a[A+508>>2]=a[(r<_(0)?i+4|0:r>_(1)?i:i+8|0)>>2]}(A,e,r)},btRigidBody_setMassProps:function(A,e,r){A|=0,e=_(e),r|=0,function(A,e,r){var i,f=_(0),t=_(0),n=_(0);i=a[A+204>>2],e!=_(0)?(a[A+204>>2]=-2&i,f=_(_(1)/e)):a[A+204>>2]=1|i,C[A+404>>2]=f,a[A+436>>2]=0,C[A+424>>2]=C[A+440>>2]*e,C[A+432>>2]=C[A+448>>2]*e,C[A+428>>2]=C[A+444>>2]*e,e=C[r+8>>2],t=C[r+4>>2],n=C[r>>2],C[A+620>>2]=C[A+408>>2]*f,C[A+624>>2]=f*C[A+412>>2],C[A+628>>2]=f*C[A+416>>2],a[A+632>>2]=0,a[A+468>>2]=0,C[A+456>>2]=n!=_(0)?_(_(1)/n):_(0),C[A+460>>2]=t!=_(0)?_(_(1)/t):_(0),C[A+464>>2]=e!=_(0)?_(_(1)/e):_(0)}(A,e,r)},btRigidBody_setLinearFactor:function(A,e){A|=0,e|=0;var r,i=0,f=_(0);i=a[e+4>>2],a[A+408>>2]=a[e>>2],a[A+412>>2]=i,e=e+8|0,r=a[e+4>>2],i=A+416|0,a[i>>2]=a[e>>2],a[i+4>>2]=r,a[A+632>>2]=0,f=C[A+404>>2],C[A+624>>2]=f*C[A+412>>2],C[A+620>>2]=f*C[A+408>>2],C[A+628>>2]=f*C[i>>2]},btRigidBody_applyTorque:function(A,e){A|=0,e|=0;var r=_(0),i=_(0);r=C[e+8>>2],i=C[e+4>>2],C[A+488>>2]=_(C[e>>2]*C[A+604>>2])+C[A+488>>2],e=A+492|0,C[e>>2]=_(i*C[A+608>>2])+C[e>>2],e=A+496|0,C[e>>2]=_(r*C[A+612>>2])+C[e>>2]},btRigidBody_applyForce:function(A,e,r){A|=0,e|=0,r|=0;var i=_(0),f=_(0),t=0,n=_(0),a=_(0),o=_(0),c=_(0),b=_(0),l=_(0);a=C[e+8>>2],i=C[e+4>>2],f=C[A+408>>2],C[A+472>>2]=_(C[e>>2]*f)+C[A+472>>2],t=A+476|0,o=i,i=C[A+412>>2],C[t>>2]=_(o*i)+C[t>>2],t=A+480|0,n=C[A+416>>2],C[t>>2]=_(a*n)+C[t>>2],l=C[e>>2],a=C[r>>2],c=C[r+4>>2],n=_(n*C[e+8>>2]),i=_(i*C[e+4>>2]),b=C[r+8>>2],C[A+488>>2]=_(_(_(c*n)-_(i*b))*C[A+604>>2])+C[A+488>>2],o=C[A+612>>2],e=A+492|0,f=_(f*l),C[e>>2]=_(_(_(b*f)-_(n*a))*C[A+608>>2])+C[e>>2],A=A+496|0,C[A>>2]=_(o*_(_(i*a)-_(f*c)))+C[A>>2]},btRigidBody_applyCentralForce:function(A,e){A|=0,e|=0;var r=_(0),i=_(0);r=C[e+8>>2],i=C[e+4>>2],C[A+472>>2]=_(C[e>>2]*C[A+408>>2])+C[A+472>>2],e=A+476|0,C[e>>2]=_(i*C[A+412>>2])+C[e>>2],e=A+480|0,C[e>>2]=_(r*C[A+416>>2])+C[e>>2]},btRigidBody_applyTorqueImpulse:function(A,e){A|=0,e|=0;var r=_(0),i=_(0),f=_(0);r=C[e>>2],i=C[e+4>>2],f=C[e+8>>2],C[A+388>>2]=_(_(_(_(C[A+324>>2]*r)+_(C[A+328>>2]*i))+_(C[A+332>>2]*f))*C[A+604>>2])+C[A+388>>2],e=A+392|0,C[e>>2]=_(_(_(_(r*C[A+340>>2])+_(i*C[A+344>>2]))+_(f*C[A+348>>2]))*C[A+608>>2])+C[e>>2],e=A+396|0,C[e>>2]=_(_(_(_(r*C[A+356>>2])+_(i*C[A+360>>2]))+_(f*C[A+364>>2]))*C[A+612>>2])+C[e>>2]},btRigidBody_applyImpulse:function(A,e,r){A|=0,e|=0,r|=0,dt(A,e,r)},btRigidBody_applyCentralImpulse:function(A,e){A|=0,e|=0;var r=_(0),i=_(0),f=_(0);i=C[e+8>>2],f=C[e+4>>2],r=C[A+404>>2],C[A+372>>2]=_(_(C[e>>2]*C[A+408>>2])*r)+C[A+372>>2],e=A+376|0,C[e>>2]=_(r*_(f*C[A+412>>2]))+C[e>>2],e=A+380|0,C[e>>2]=_(r*_(i*C[A+416>>2]))+C[e>>2]},btRigidBody_updateInertiaTensor:function(A){A|=0,function(A){var e=_(0),r=_(0),i=_(0),f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0);a[A+368>>2]=0,a[A+352>>2]=0,a[A+336>>2]=0,k=C[A+456>>2],e=C[A+36>>2],r=_(k*e),v=C[A+460>>2],i=C[A+40>>2],f=_(v*i),d=C[A+464>>2],t=C[A+44>>2],n=_(d*t),C[A+364>>2]=_(_(r*e)+_(f*i))+_(n*t),l=C[A+20>>2],u=C[A+24>>2],s=C[A+28>>2],C[A+360>>2]=_(_(r*l)+_(f*u))+_(n*s),o=r,r=C[A+4>>2],c=f,f=C[A+8>>2],b=n,n=C[A+12>>2],C[A+356>>2]=_(_(o*r)+_(c*f))+_(b*n),o=_(k*l),c=_(v*u),b=_(d*s),C[A+348>>2]=_(_(e*o)+_(i*c))+_(t*b),C[A+344>>2]=_(_(o*l)+_(c*u))+_(b*s),C[A+340>>2]=_(_(o*r)+_(c*f))+_(b*n),o=e,e=_(r*k),c=i,i=_(f*v),b=t,t=_(n*d),C[A+332>>2]=_(_(o*e)+_(c*i))+_(b*t),C[A+328>>2]=_(_(e*l)+_(i*u))+_(t*s),C[A+324>>2]=_(_(e*r)+_(i*f))+_(t*n)}(A)},btRigidBody_getLinearVelocity:function(A){return A|=0,A+372|0},btRigidBody_getAngularVelocity:function(A){return A|=0,A+388|0},btRigidBody_setLinearVelocity:function(A,e){A|=0,e|=0;var r=0;a[A+304>>2]=a[A+304>>2]+1,r=a[e+4>>2],a[A+372>>2]=a[e>>2],a[A+376>>2]=r,e=e+8|0,r=a[e+4>>2],A=A+380|0,a[A>>2]=a[e>>2],a[A+4>>2]=r},btRigidBody_setAngularVelocity:function(A,e){A|=0,e|=0;var r=0;a[A+304>>2]=a[A+304>>2]+1,r=a[e+4>>2],a[A+388>>2]=a[e>>2],a[A+392>>2]=r,e=e+8|0,r=a[e+4>>2],A=A+396|0,a[A>>2]=a[e>>2],a[A+4>>2]=r},btRigidBody_setAngularFactor:function(A,e){A|=0,e|=0;var r=0;a[A+304>>2]=a[A+304>>2]+1,r=a[e+4>>2],a[A+604>>2]=a[e>>2],a[A+608>>2]=r,e=e+8|0,r=a[e+4>>2],A=A+612|0,a[A>>2]=a[e>>2],a[A+4>>2]=r},btRigidBody_getGravity:function(A){return A|=0,A+440|0},btRigidBody_setGravity:function(A,e){A|=0,e|=0,Si(A,e)},btRigidBody_getTotalForce:function(A){return A|=0,A+472|0},btRigidBody_getTotalTorque:function(A){return A|=0,A+488|0},btRigidBody_getFlags:function(A){return A|=0,a[A+564>>2]},btRigidBody_setFlags:function(A,e){A|=0,e|=0,a[A+564>>2]=e},btRigidBody_clearForces:function(A){A|=0;var e=0;a[A+472>>2]=0,a[A+476>>2]=0,e=A+496|0,a[e>>2]=0,a[e+4>>2]=0,e=A+488|0,a[e>>2]=0,a[e+4>>2]=0,A=A+480|0,a[A>>2]=0,a[A+4>>2]=0},btSequentialImpulseConstraintSolver_create:function(){var A;return A=dA(236),Li(A),0|A},btCollisionWorld_get_m_useContinuous:function(A){return A|=0,o[A+16|0]},btCollisionWorld_set_m_useContinuous:function(A,e){A|=0,e|=0,f[A+16|0]=e},btCollisionWorld_rayTest:function(A,e,r,i){A|=0,e|=0,r|=0,i|=0,Qt[a[a[A>>2]+32>>2]](A,e,r,i)},btCollisionWorld_getDispatchInfo:function(A){return A|=0,A+28|0},btCollisionWorld_addCollisionObject:function(A,e,r,i){A|=0,e|=0,r|=0,i|=0,Qt[a[a[A>>2]+36>>2]](A,e,r,i)},btCollisionWorld_removeCollisionObject:function(A,e){A|=0,e|=0,Qt[a[a[A>>2]+40>>2]](A,e)},btCollisionWorld_convexSweepTest:function(A,e,r,i,f,t){A|=0,e|=0,r|=0,i|=0,f|=0,t=_(t),_f(A,e,r,i,f,t)},btCollisionWorld_destroy:nt,btDynamicsWorld_addAction:Jf,btDynamicsWorld_removeAction:xf,btDynamicsWorld_getSolverInfo:function(A){return A|=0,A+92|0},btDiscreteDynamicsWorld_create:function(A,e,r,i){return A|=0,e|=0,r|=0,i|=0,i=dA(344),Nf(i,A,e,r),0|i},btDiscreteDynamicsWorld_setGravity:function(A,e){A|=0,e|=0,Qt[a[a[A>>2]+72>>2]](A,e)},btDiscreteDynamicsWorld_getGravity:function(A){var e,r;return A|=0,e=Y-16|0,Y=e,Qt[a[a[A>>2]+76>>2]](e,A),A=e+8|0,r=a[A+4>>2],a[705]=a[A>>2],a[706]=r,A=a[e+4>>2],a[703]=a[e>>2],a[704]=A,Y=e+16|0,2812},btDiscreteDynamicsWorld_addRigidBody:function(A,e,r,i){A|=0,e|=0,r|=0,i|=0,Qt[a[a[A>>2]+88>>2]](A,e,r,i)},btDiscreteDynamicsWorld_removeRigidBody:function(A,e){A|=0,e|=0,Qt[a[a[A>>2]+92>>2]](A,e)},btDiscreteDynamicsWorld_stepSimulation:function(A,e,r,i){A|=0,e=_(e),r|=0,i=_(i),Qt[a[a[A>>2]+52>>2]](A,e,r,i)},btDiscreteDynamicsWorld_clearForces:function(A){A|=0,Qt[a[a[A>>2]+120>>2]](A)},btDiscreteDynamicsWorld_setApplySpeculativeContactRestitution:function(A,e){A|=0,e|=0,f[A+291|0]=e},btDiscreteDynamicsWorld_getApplySpeculativeContactRestitution:function(A){return A|=0,o[A+291|0]},btKinematicCharacterController_create:function(A,e,r,i){var n;return A|=0,e|=0,r=_(r),i|=0,n=dA(292),function(A,e,r,i,n){var o,c=_(0),b=_(0),l=_(0),u=_(0),s=_(0);o=Y-16|0,Y=o,a[A>>2]=24116,a[A+272>>2]=0,a[A+276>>2]=0,a[A+256>>2]=0,a[A+260>>2]=0,a[A+8>>2]=e,a[A+68>>2]=0,a[A+72>>2]=0,a[A+64>>2]=1017370378,a[A+100>>2]=0,a[A+104>>2]=0,t[A+250>>1]=257,a[A+56>>2]=0,a[A+12>>2]=r,a[A+252>>2]=0,f[A+216|0]=1,a[A+212>>2]=0,e=A+204|0,a[e>>2]=0,a[e+4>>2]=0,e=A+280|0,a[e>>2]=1065353216,a[e+4>>2]=0,e=A+264|0,a[e>>2]=1065353216,a[e+4>>2]=0,e=A+76|0,a[e>>2]=0,a[e+4>>2]=0,e=A+108|0,a[e>>2]=0,a[e+4>>2]=0,a[A+52>>2]=1105933107,a[A+20>>2]=0,a[A+24>>2]=0,t[A+248>>1]=0,a[A+28>>2]=1113325568,a[A+32>>2]=1092616192,a[A+36>>2]=1092616192,a[A+148>>2]=0,f[A+289|0]=0,f[A+290|0]=0,a[A+16>>2]=1045220557,a[A+240>>2]=0,a[A+244>>2]=0,f[A+288|0]=1,b=C[n>>2],l=C[n+4>>2],c=C[n+8>>2],u=_(_(_(b*b)+_(l*l))+_(c*c)),u>_(0)?(s=c,c=_(_(1)/_(y(u))),u=_(_(s*c)*_(-29.399999618530273)),b=_(_(b*c)*_(-29.399999618530273)),l=_(_(l*c)*_(-29.399999618530273)),c=_(_(u*u)+_(_(b*b)+_(l*l))),c>_(0)&&(a[o+12>>2]=0,C[o+8>>2]=-u,C[o+4>>2]=-l,C[o>>2]=-b,Tf(A,o)),C[A+52>>2]=y(c)):Tf(A,n),a[A+44>>2]=1061752795,a[A+48>>2]=1060439283,C[A+60>>2]=i,Y=o+16|0}(n,A,e,r,i),0|n},btKinematicCharacterController_setWalkDirection:function(A,e){A|=0,e|=0,Qt[a[a[A>>2]+16>>2]](A,e)},btKinematicCharacterController_setFallSpeed:function(A,e){A|=0,e=_(e),C[A+28>>2]=e},btKinematicCharacterController_setJumpSpeed:function(A,e){A|=0,e=_(e),C[A+36>>2]=e,C[A+32>>2]=e},btKinematicCharacterController_setMaxSlope:function(A,e){A|=0,e=_(e);var r,i=_(0);C[A+44>>2]=e,r=A,i=Cr(e),C[r+48>>2]=i},btKinematicCharacterController_onGround:zf,btKinematicCharacterController_jump:function(A,e){A|=0,e|=0,Qt[a[a[A>>2]+44>>2]](A,e)},btKinematicCharacterController_setGravity:function(A,e){A|=0,e|=0,function(A,e){var r,i,f=_(0),t=_(0),n=_(0),o=_(0);r=Y-16|0,Y=r,i=A,f=C[e>>2],n=C[e+4>>2],o=C[e+8>>2],t=_(_(_(f*f)+_(n*n))+_(o*o)),t>_(0)&&(a[r+12>>2]=0,C[r+8>>2]=-o,C[r+4>>2]=-n,C[r>>2]=-f,Tf(A,r),f=C[e>>2],t=_(f*f),f=C[e+4>>2],t=_(t+_(f*f)),f=C[e+8>>2],t=_(t+_(f*f))),C[i+52>>2]=y(t),Y=r+16|0}(A,e)},btKinematicCharacterController_setUp:function(A,e){A|=0,e|=0,function(A,e){var r,i=_(0),f=_(0),t=_(0),n=_(0),o=_(0),c=_(0);r=Y-16|0,Y=r,f=C[e>>2],t=C[e+4>>2],i=C[e+8>>2],n=_(_(_(f*f)+_(t*t))+_(i*i)),n>_(0)&&(o=C[A+52>>2],o>_(0))?(c=i,i=_(_(1)/_(y(n))),n=_(-o),o=_(_(c*i)*n),f=_(_(f*i)*n),t=_(_(t*i)*n),i=_(_(o*o)+_(_(f*f)+_(t*t))),i>_(0)&&(a[r+12>>2]=0,C[r+8>>2]=-o,C[r+4>>2]=-t,C[r>>2]=-f,Tf(A,r)),C[A+52>>2]=y(i)):Tf(A,e),Y=r+16|0}(A,e)},btKinematicCharacterController_setStepHeight:function(A,e){A|=0,e=_(e),C[A+60>>2]=e},btKinematicCharacterController_destroy:nt,btPairCachingGhostObject_create:function(){var A;return A=dA(348),function(A){var e=0;Ee(A),a[A+336>>2]=0,f[A+340|0]=1,e=A+328|0,a[e>>2]=0,a[e+4>>2]=0,a[A+252>>2]=4,a[A>>2]=24004,e=dA(72),Ri(e),a[A+344>>2]=e}(A),0|A},btGhostPairCallback_create:function(){var A;return A=q(4),a[A>>2]=25228,0|A},btTypedConstraint_setEnabled:function(A,e){A|=0,e|=0,f[A+20|0]=e},btCollisionWorld_addConstraint:function(A,e,r){A|=0,e|=0,r|=0,Qt[a[a[A>>2]+56>>2]](A,e,r)},btCollisionWorld_removeConstraint:vt,btJointFeedback_create:function(){var A,e=0;return A=dA(64),e=A,a[e>>2]=0,a[e+4>>2]=0,e=e+56|0,a[e>>2]=0,a[e+4>>2]=0,e=A+48|0,a[e>>2]=0,a[e+4>>2]=0,e=A+40|0,a[e>>2]=0,a[e+4>>2]=0,e=A+32|0,a[e>>2]=0,a[e+4>>2]=0,e=A+24|0,a[e>>2]=0,a[e+4>>2]=0,e=A+16|0,a[e>>2]=0,a[e+4>>2]=0,e=A+8|0,a[e>>2]=0,a[e+4>>2]=0,0|A},btJointFeedback_destroy:function(A){A|=0,A&&CA(A)},btTypedConstraint_setJointFeedback:function(A,e){A|=0,e|=0,a[A+44>>2]=e},btTypedConstraint_getJointFeedback:function(A){return A|=0,a[A+44>>2]},btTypedConstraint_enableFeedback:function(A,e){A|=0,e|=0,f[A+21|0]=e},btTypedConstraint_setParam:function(A,e,r,i){A|=0,e|=0,r|=0,i=_(i),Qt[a[a[A>>2]+28>>2]](A,r,i,e)},btTypedConstraint_setOverrideNumSolverIterations:Gi,btTypedConstraint_destroy:nt,btJointFeedback_getAppliedForceBodyA:sA,btJointFeedback_getAppliedForceBodyB:ut,btJointFeedback_getAppliedTorqueBodyA:Qe,btFixedConstraint_create:function(A,e,r,i){var f;return A|=0,e|=0,r|=0,i|=0,f=dA(1460),function(A,e,r,i,f){Pf(A,e,r,i,f,0),a[A>>2]=24588,e=A+1144|0,a[e>>2]=0,a[e+4>>2]=0,e=A+1056|0,a[e>>2]=0,a[e+4>>2]=0,a[A+968>>2]=0,a[A+972>>2]=0,a[A+680>>2]=0,a[A+684>>2]=0,e=A+688|0,a[e>>2]=0,a[e+4>>2]=0,e=A+696|0,a[e>>2]=0,a[e+4>>2]=0,A=A+704|0,a[A>>2]=0,a[A+4>>2]=0}(f,A,r,e,i),0|f},btGeneric6DofSpring2Constraint_create:function(A,e,r,i,f){var t;return A|=0,e|=0,r|=0,i|=0,f|=0,t=dA(1460),A=Pf(t,A,r,e,i,f),a[t+24>>2]=80,Qt[a[a[t>>2]+28>>2]](A,2,_(.800000011920929),0),Qt[a[a[t>>2]+28>>2]](A,4,_(0),0),Qt[a[a[t>>2]+28>>2]](A,2,_(.800000011920929),1),Qt[a[a[t>>2]+28>>2]](A,4,_(0),1),Qt[a[a[t>>2]+28>>2]](A,2,_(.800000011920929),2),Qt[a[a[t>>2]+28>>2]](A,4,_(0),2),Qt[a[a[t>>2]+28>>2]](A,2,_(.800000011920929),3),Qt[a[a[t>>2]+28>>2]](A,4,_(0),3),Qt[a[a[t>>2]+28>>2]](A,2,_(.800000011920929),4),Qt[a[a[t>>2]+28>>2]](A,4,_(0),4),Qt[a[a[t>>2]+28>>2]](A,2,_(.800000011920929),5),Qt[a[a[t>>2]+28>>2]](A,4,_(0),5),0|t},btGeneric6DofSpring2Constraint_setAxis:function(A,e,r){A|=0,e|=0,r|=0,function(A,e,r){var i,f=_(0),t=_(0),n=_(0),o=_(0),c=_(0),b=_(0),l=_(0),u=_(0),s=_(0),k=_(0),v=_(0),d=_(0),g=_(0),B=_(0),m=_(0),R=_(0),Q=_(0),h=_(0),G=_(0),p=_(0),F=_(0);i=a[A+28>>2],d=C[i+20>>2],g=C[i+36>>2],B=C[i+40>>2],m=C[i+8>>2],R=C[i+24>>2],t=C[i+60>>2],o=C[i+44>>2],c=C[i+12>>2],n=C[i+52>>2],b=C[i+56>>2],l=C[i+28>>2],u=C[r+8>>2],s=C[r>>2],k=C[r+4>>2],v=C[e+8>>2],f=C[e>>2],Q=C[e+4>>2],h=C[i+4>>2],a[A+108>>2]=0,a[A+92>>2]=0,a[A+76>>2]=0,a[A+60>>2]=0,n=_(-n),C[A+104>>2]=_(_(_(c*_(0))+_(l*_(0)))+_(o*_(0)))+_(_(_(c*n)-_(l*b))-_(o*t)),C[A+100>>2]=_(_(_(m*_(0))+_(R*_(0)))+_(B*_(0)))+_(_(_(m*n)-_(R*b))-_(B*t)),C[A+96>>2]=_(_(_(h*_(0))+_(d*_(0)))+_(g*_(0)))+_(_(_(h*n)-_(d*b))-_(g*t)),n=f,f=_(_(1)/_(y(_(_(_(f*f)+_(Q*Q))+_(v*v))))),t=_(n*f),b=_(Q*f),v=_(v*f),C[A+88>>2]=_(_(c*t)+_(l*b))+_(o*v),f=_(_(1)/_(y(_(_(_(s*s)+_(k*k))+_(u*u))))),s=_(s*f),k=_(k*f),u=_(u*f),C[A+84>>2]=_(_(c*s)+_(l*k))+_(o*u),C[A+72>>2]=_(_(t*m)+_(b*R))+_(v*B),C[A+68>>2]=_(_(s*m)+_(k*R))+_(u*B),C[A+56>>2]=_(_(h*t)+_(b*d))+_(v*g),C[A+52>>2]=_(g*u)+_(_(h*s)+_(d*k)),f=c,c=_(_(v*k)-_(b*u)),n=l,l=_(_(t*u)-_(v*s)),Q=o,o=_(_(b*s)-_(t*k)),C[A+80>>2]=_(_(f*c)+_(n*l))+_(Q*o),C[A- -64>>2]=_(o*B)+_(_(m*c)+_(R*l)),C[A+48>>2]=_(g*o)+_(_(h*c)+_(d*l)),e=a[A+32>>2],G=C[e+60>>2],F=C[e+52>>2],p=C[e+56>>2],d=C[e+20>>2],g=C[e+36>>2],B=C[e+40>>2],m=C[e+8>>2],R=C[e+24>>2],h=C[e+44>>2],f=C[e+12>>2],Q=C[e+28>>2],n=C[e+4>>2],a[A+172>>2]=0,a[A+156>>2]=0,a[A+140>>2]=0,a[A+124>>2]=0,C[A+152>>2]=_(_(t*f)+_(b*Q))+_(v*h),C[A+148>>2]=_(_(s*f)+_(k*Q))+_(u*h),C[A+144>>2]=_(_(c*f)+_(l*Q))+_(o*h),C[A+136>>2]=_(_(t*m)+_(b*R))+_(v*B),C[A+132>>2]=_(_(s*m)+_(k*R))+_(u*B),C[A+128>>2]=_(_(c*m)+_(l*R))+_(o*B),C[A+120>>2]=_(_(t*n)+_(b*d))+_(v*g),C[A+116>>2]=_(_(s*n)+_(k*d))+_(u*g),C[A+112>>2]=_(_(c*n)+_(l*d))+_(o*g),t=_(-F),C[A+168>>2]=_(_(_(f*_(0))+_(Q*_(0)))+_(h*_(0)))+_(_(_(f*t)-_(Q*p))-_(h*G)),C[A+164>>2]=_(_(_(m*_(0))+_(R*_(0)))+_(B*_(0)))+_(_(_(m*t)-_(R*p))-_(B*G)),C[A+160>>2]=_(_(_(n*_(0))+_(d*_(0)))+_(g*_(0)))+_(_(_(n*t)-_(d*p))-_(g*G)),Kf(A,i+4|0,e+4|0)}(A,e,r)},btGeneric6DofSpring2Constraint_setLimit:function(A,e,r,i){if(A|=0,e|=0,r=_(r),i=_(i),(0|e)<=2)return A=(e<<2)+A|0,C[A+696>>2]=i,void(C[A+680>>2]=r);r=Wf(r),r<_(-3.1415927410125732)?r=_(r+_(6.2831854820251465)):r>_(3.1415927410125732)&&(r=_(r+_(-6.2831854820251465))),i=Wf(i),i<_(-3.1415927410125732)?i=_(i+_(6.2831854820251465)):i>_(3.1415927410125732)&&(i=_(i+_(-6.2831854820251465))),A=B(e,88)+A|0,C[A+708>>2]=i,C[A+704>>2]=r},btGeneric6DofSpring2Constraint_enableSpring:function(A,e,r){A|=0,e|=0,r|=0,function(A,e,r){(0|e)<=2?f[798+(A+e|0)|0]=r:f[752+(B(e,88)+A|0)|0]=r}(A,e,r)},btGeneric6DofSpring2Constraint_setBounce:function(A,e,r){A|=0,e|=0,r=_(r),function(A,e,r){C[((0|e)<3?712+((e<<2)+A|0)|0:712+(B(e,88)+A|0)|0)>>2]=r}(A,e,r)},btGeneric6DofSpring2Constraint_setStiffness:function(A,e,r,i){A|=0,e|=0,r=_(r),i|=0,function(A,e,r,i){if((0|e)<=2)return A=A+680|0,f[156+(A+e|0)|0]=i,void(C[140+(A+(e<<2)|0)>>2]=r);A=B(e,88)+A|0,f[A+760|0]=i,C[A+756>>2]=r}(A,e,r,i)},btGeneric6DofSpring2Constraint_setDamping:function(A,e,r,i){A|=0,e|=0,r=_(r),i|=0,function(A,e,r,i){if((0|e)<=2)return A=A+680|0,f[176+(A+e|0)|0]=i,void(C[160+(A+(e<<2)|0)>>2]=r);A=B(e,88)+A|0,f[A+768|0]=i,C[A+764>>2]=r}(A,e,r,i)},btGeneric6DofSpring2Constraint_setEquilibriumPoint:function(A,e,r){A|=0,e|=0,r=_(r),function(A,e,r){C[((0|e)<3?860+((e<<2)+A|0)|0:772+(B(e,88)+A|0)|0)>>2]=r}(A,e,r)},btGeneric6DofSpring2Constraint_enableMotor:function(A,e,r){A|=0,e|=0,r|=0,function(A,e,r){(0|e)<=2?f[792+(A+e|0)|0]=r:f[732+(B(e,88)+A|0)|0]=r}(A,e,r)},btGeneric6DofSpring2Constraint_setServo:function(A,e,r){A|=0,e|=0,r|=0,function(A,e,r){(0|e)<=2?f[795+(A+e|0)|0]=r:f[744+(B(e,88)+A|0)|0]=r}(A,e,r)},btGeneric6DofSpring2Constraint_setTargetVelocity:function(A,e,r){A|=0,e|=0,r=_(r),function(A,e,r){C[((0|e)<3?876+((e<<2)+A|0)|0:736+(B(e,88)+A|0)|0)>>2]=r}(A,e,r)},btGeneric6DofSpring2Constraint_setServoTarget:function(A,e,r){A|=0,e|=0,r=_(r),function(A,e,r){var i=_(0);(0|e)<=2?C[804+((e<<2)+A|0)>>2]=r:(A=748+(B(e,88)+A|0)|0,r=_(r+_(3.1415927410125732)),r=_(r-_(_(G(_(r/_(6.2831854820251465))))*_(6.2831854820251465))),i=_(0),r>=_(6.2831854820251465)||(i=r,r<_(0)&&(r=_(r+_(6.2831854820251465)),i=r==_(6.2831854820251465)?_(0):r)),C[A>>2]=i+_(-3.1415927410125732))}(A,e,r)},btGeneric6DofSpring2Constraint_setMaxMotorForce:function(A,e,r){A|=0,e|=0,r=_(r),function(A,e,r){C[((0|e)<3?892+((e<<2)+A|0)|0:740+(B(e,88)+A|0)|0)>>2]=r}(A,e,r)},btGeneric6DofSpring2Constraint_setFrames:function(A,e,r){A|=0,e|=0,r|=0,function(A,e,r){var i=0,f=0,t=0;i=a[e+4>>2],a[A+48>>2]=a[e>>2],a[A+52>>2]=i,f=e+8|0,t=a[f+4>>2],i=A+56|0,a[i>>2]=a[f>>2],a[i+4>>2]=t,f=e+24|0,t=a[f+4>>2],i=A+72|0,a[i>>2]=a[f>>2],a[i+4>>2]=t,f=a[e+20>>2],i=A- -64|0,a[i>>2]=a[e+16>>2],a[i+4>>2]=f,f=e+40|0,t=a[f+4>>2],i=A+88|0,a[i>>2]=a[f>>2],a[i+4>>2]=t,f=a[e+36>>2],i=A+80|0,a[i>>2]=a[e+32>>2],a[i+4>>2]=f,f=e+56|0,t=a[f+4>>2],i=A+104|0,a[i>>2]=a[f>>2],a[i+4>>2]=t,f=a[e+52>>2],i=A+96|0,a[i>>2]=a[e+48>>2],a[i+4>>2]=f,i=r+8|0,f=a[i+4>>2],e=A+120|0,a[e>>2]=a[i>>2],a[e+4>>2]=f,e=a[r+4>>2],a[A+112>>2]=a[r>>2],a[A+116>>2]=e,i=a[r+20>>2],e=A+128|0,a[e>>2]=a[r+16>>2],a[e+4>>2]=i,i=r+24|0,f=a[i+4>>2],e=A+136|0,a[e>>2]=a[i>>2],a[e+4>>2]=f,i=a[r+36>>2],e=A+144|0,a[e>>2]=a[r+32>>2],a[e+4>>2]=i,i=r+40|0,f=a[i+4>>2],e=A+152|0,a[e>>2]=a[i>>2],a[e+4>>2]=f,i=r+56|0,f=a[i+4>>2],e=A+168|0,a[e>>2]=a[i>>2],a[e+4>>2]=f,i=a[r+52>>2],e=A+160|0,a[e>>2]=a[r+48>>2],a[e+4>>2]=i,Qt[a[a[A>>2]+8>>2]](A),Kf(A,a[A+28>>2]+4|0,a[A+32>>2]+4|0)}(A,e,r)}}}({Math:Math,Int8Array:Int8Array,Uint8Array:Uint8Array,Int16Array:Int16Array,Uint16Array:Uint16Array,Int32Array:Int32Array,Uint32Array:Uint32Array,Float32Array:Float32Array,Float64Array:Float64Array,NaN:NaN,Infinity:1/0},{memory:{},abort:function(){throw new Error("abort")},fd_close:()=>{console.log("fd_close")},fd_write:()=>{console.log("fd_write")},getWorldTransform:i,setWorldTransform:f,fd_seek:()=>{console.log("fd_seek")}},v);r.btGImpactCollisionAlgorithm_RegisterAlgorithm=C.btGImpactCollisionAlgorithm_RegisterAlgorithm,r.btVector3_create=C.btVector3_create,r.btVector3_setValue=C.btVector3_setValue,r.btVector3_x=C.btVector3_x,r.btVector3_y=C.btVector3_y,r.btVector3_z=C.btVector3_z,r.btQuaternion_create=C.btQuaternion_create,r.btQuaternion_setValue=C.btQuaternion_setValue,r.btQuaternion_x=C.btQuaternion_x,r.btQuaternion_y=C.btQuaternion_y,r.btQuaternion_z=C.btQuaternion_z,r.btQuaternion_w=C.btQuaternion_w,r.btTransform_create=C.btTransform_create,r.btTransform_setOrigin=C.btTransform_setOrigin,r.btTransform_setRotation=C.btTransform_setRotation,r.btTransform_getOrigin=C.btTransform_getOrigin,r.btTransform_getRotation=C.btTransform_getRotation,r.btTransform_setIdentity=C.btTransform_setIdentity,r.btTransform_equal=C.btTransform_equal,r.btMotionState_destroy=C.btMotionState_destroy,r.layaMotionState_create=C.layaMotionState_create,r.layaMotionState_set_rigidBodyID=C.layaMotionState_set_rigidBodyID,r.btCollisionObject_create=C.btCollisionObject_create,r.btCollisionObject_setContactProcessingThreshold=C.btCollisionObject_setContactProcessingThreshold,r.btCollisionObject_setActivationState=C.btCollisionObject_setActivationState,r.btCollisionObject_forceActivationState=C.btCollisionObject_forceActivationState,r.btCollisionObject_activate=C.btCollisionObject_activate,r.btCollisionObject_isActive=C.btCollisionObject_isActive,r.btCollisionObject_setRestitution=C.btCollisionObject_setRestitution,r.btCollisionObject_setFriction=C.btCollisionObject_setFriction,r.btCollisionObject_setRollingFriction=C.btCollisionObject_setRollingFriction,r.btCollisionObject_getCollisionFlags=C.btCollisionObject_getCollisionFlags,r.btCollisionObject_setCollisionFlags=C.btCollisionObject_setCollisionFlags,r.btCollisionObject_getWorldTransform=C.btCollisionObject_getWorldTransform,r.btCollisionObject_setWorldTransform=C.btCollisionObject_setWorldTransform,r.btCollisionObject_setInterpolationWorldTransform=C.btCollisionObject_setInterpolationWorldTransform,r.btCollisionObject_setCollisionShape=C.btCollisionObject_setCollisionShape,r.btCollisionObject_getCcdMotionThreshold=C.btCollisionObject_getCcdMotionThreshold,r.btCollisionObject_setCcdMotionThreshold=C.btCollisionObject_setCcdMotionThreshold,r.btCollisionObject_getCcdSweptSphereRadius=C.btCollisionObject_getCcdSweptSphereRadius,r.btCollisionObject_setCcdSweptSphereRadius=C.btCollisionObject_setCcdSweptSphereRadius,r.btCollisionObject_getUserIndex=C.btCollisionObject_getUserIndex,r.btCollisionObject_setUserIndex=C.btCollisionObject_setUserIndex,r.btCollisionObject_getActivationState=C.btCollisionObject_getActivationState,r.btCollisionObject_setInterpolationAngularVelocity=C.btCollisionObject_setInterpolationAngularVelocity,r.btCollisionObject_setInterpolationLinearVelocity=C.btCollisionObject_setInterpolationLinearVelocity,r.btCollisionObject_destroy=C.btCollisionObject_destroy,r.RayResultCallback_set_m_flags=C.RayResultCallback_set_m_flags,r.RayResultCallback_hasHit=C.RayResultCallback_hasHit,r.RayResultCallback_set_m_collisionFilterGroup=C.RayResultCallback_set_m_collisionFilterGroup,r.RayResultCallback_set_m_collisionFilterMask=C.RayResultCallback_set_m_collisionFilterMask,r.RayResultCallback_get_m_closestHitFraction=C.RayResultCallback_get_m_closestHitFraction,r.RayResultCallback_set_m_closestHitFraction=C.RayResultCallback_set_m_closestHitFraction,r.RayResultCallback_get_m_collisionObject=C.RayResultCallback_get_m_collisionObject,r.RayResultCallback_set_m_collisionObject=C.RayResultCallback_set_m_collisionObject,r.ClosestRayResultCallback_create=C.ClosestRayResultCallback_create,r.ClosestRayResultCallback_get_m_rayFromWorld=C.ClosestRayResultCallback_get_m_rayFromWorld,r.ClosestRayResultCallback_set_m_rayFromWorld=C.ClosestRayResultCallback_set_m_rayFromWorld,r.ClosestRayResultCallback_get_m_rayToWorld=C.ClosestRayResultCallback_get_m_rayToWorld,r.ClosestRayResultCallback_set_m_rayToWorld=C.ClosestRayResultCallback_set_m_rayToWorld,r.ClosestRayResultCallback_get_m_hitNormalWorld=C.ClosestRayResultCallback_get_m_hitNormalWorld,r.ClosestRayResultCallback_get_m_hitPointWorld=C.ClosestRayResultCallback_get_m_hitPointWorld,r.tBtCollisionObjectArray_size=C.tBtCollisionObjectArray_size,r.tBtCollisionObjectArray_at=C.tBtCollisionObjectArray_at,r.tBtCollisionObjectArray_clear=C.tBtCollisionObjectArray_clear,r.tVector3Array_at=C.tVector3Array_at,r.tVector3Array_clear=C.tVector3Array_clear,r.tScalarArray_at=C.tScalarArray_at,r.tScalarArray_clear=C.tScalarArray_clear,r.AllHitsRayResultCallback_create=C.AllHitsRayResultCallback_create,r.AllHitsRayResultCallback_get_m_rayFromWorld=C.AllHitsRayResultCallback_get_m_rayFromWorld,r.AllHitsRayResultCallback_set_m_rayFromWorld=C.AllHitsRayResultCallback_set_m_rayFromWorld,r.AllHitsRayResultCallback_get_m_rayToWorld=C.AllHitsRayResultCallback_get_m_rayToWorld,r.AllHitsRayResultCallback_set_m_rayToWorld=C.AllHitsRayResultCallback_set_m_rayToWorld,r.AllHitsRayResultCallback_get_m_hitPointWorld=C.AllHitsRayResultCallback_get_m_hitPointWorld,r.AllHitsRayResultCallback_get_m_hitNormalWorld=C.AllHitsRayResultCallback_get_m_hitNormalWorld,r.AllHitsRayResultCallback_get_m_collisionObjects=C.AllHitsRayResultCallback_get_m_collisionObjects,r.AllHitsRayResultCallback_get_m_hitFractions=C.AllHitsRayResultCallback_get_m_hitFractions,r.btManifoldPoint_get_m_positionWorldOnA=C.btManifoldPoint_get_m_positionWorldOnA,r.btManifoldPoint_get_m_positionWorldOnB=C.btManifoldPoint_get_m_positionWorldOnB,r.btManifoldPoint_get_m_normalWorldOnB=C.btManifoldPoint_get_m_normalWorldOnB,r.btManifoldPoint_getDistance=C.btManifoldPoint_getDistance,r.ConvexResultCallback_hasHit=C.ConvexResultCallback_hasHit,r.ConvexResultCallback_set_m_collisionFilterGroup=C.ConvexResultCallback_set_m_collisionFilterGroup,r.ConvexResultCallback_set_m_collisionFilterMask=C.ConvexResultCallback_set_m_collisionFilterMask,r.ConvexResultCallback_get_m_closestHitFraction=C.ConvexResultCallback_get_m_closestHitFraction,r.ConvexResultCallback_set_m_closestHitFraction=C.ConvexResultCallback_set_m_closestHitFraction,r.ClosestConvexResultCallback_create=C.ClosestConvexResultCallback_create,r.ClosestConvexResultCallback_get_m_hitNormalWorld=C.ClosestConvexResultCallback_get_m_hitNormalWorld,r.ClosestConvexResultCallback_get_m_hitPointWorld=C.ClosestConvexResultCallback_get_m_hitPointWorld,r.ClosestConvexResultCallback_get_m_hitCollisionObject=C.ClosestConvexResultCallback_get_m_hitCollisionObject,r.ClosestConvexResultCallback_set_m_hitCollisionObject=C.ClosestConvexResultCallback_set_m_hitCollisionObject,r.AllConvexResultCallback_create=C.AllConvexResultCallback_create,r.AllConvexResultCallback_get_m_hitNormalWorld=C.AllConvexResultCallback_get_m_hitNormalWorld,r.AllConvexResultCallback_get_m_hitPointWorld=C.AllConvexResultCallback_get_m_hitPointWorld,r.AllConvexResultCallback_get_m_hitFractions=C.AllConvexResultCallback_get_m_hitFractions,r.AllConvexResultCallback_get_m_collisionObjects=C.AllConvexResultCallback_get_m_collisionObjects,r.btCollisionShape_getLocalScaling=C.btCollisionShape_getLocalScaling,r.btCollisionShape_setLocalScaling=C.btCollisionShape_setLocalScaling,r.btCollisionShape_calculateLocalInertia=C.btCollisionShape_calculateLocalInertia,r.btCollisionShape_destroy=C.btCollisionShape_destroy,r.btBoxShape_create=C.btBoxShape_create,r.btCapsuleShape_create=C.btCapsuleShape_create,r.btCapsuleShapeX_create=C.btCapsuleShapeX_create,r.btCapsuleShapeZ_create=C.btCapsuleShapeZ_create,r.btCylinderShape_create=C.btCylinderShape_create,r.btCylinderShapeX_create=C.btCylinderShapeX_create,r.btCylinderShapeZ_create=C.btCylinderShapeZ_create,r.btSphereShape_create=C.btSphereShape_create,r.btConeShape_create=C.btConeShape_create,r.btConeShapeX_create=C.btConeShapeX_create,r.btConeShapeZ_create=C.btConeShapeZ_create,r.btStaticPlaneShape_create=C.btStaticPlaneShape_create,r.btGImpactShapeInterface_updateBound=C.btGImpactShapeInterface_updateBound,r.btGImpactMeshShape_create=C.btGImpactMeshShape_create,r.btCompoundShape_create=C.btCompoundShape_create,r.btCompoundShape_addChildShape=C.btCompoundShape_addChildShape,r.btCompoundShape_removeChildShapeByIndex=C.btCompoundShape_removeChildShapeByIndex,r.btCompoundShape_getChildShape=C.btCompoundShape_getChildShape,r.btCompoundShape_updateChildTransform=C.btCompoundShape_updateChildTransform,r.btStridingMeshInterface_destroy=C.btStridingMeshInterface_destroy,r.btTriangleMesh_create=C.btTriangleMesh_create,r.btTriangleMesh_addTriangle=C.btTriangleMesh_addTriangle,r.btDefaultCollisionConfiguration_create=C.btDefaultCollisionConfiguration_create,r.btDefaultCollisionConfiguration_destroy=C.btDefaultCollisionConfiguration_destroy,r.btPersistentManifold_getBody0=C.btPersistentManifold_getBody0,r.btPersistentManifold_getBody1=C.btPersistentManifold_getBody1,r.btPersistentManifold_getNumContacts=C.btPersistentManifold_getNumContacts,r.btPersistentManifold_getContactPoint=C.btPersistentManifold_getContactPoint,r.btDispatcher_getNumManifolds=C.btDispatcher_getNumManifolds,r.btDispatcher_getManifoldByIndexInternal=C.btDispatcher_getManifoldByIndexInternal,r.btCollisionDispatcher_create=C.btCollisionDispatcher_create,r.btCollisionDispatcher_destroy=C.btCollisionDispatcher_destroy,r.btOverlappingPairCache_setInternalGhostPairCallback=C.btOverlappingPairCache_setInternalGhostPairCallback,r.btDbvtBroadphase_create=C.btDbvtBroadphase_create,r.btDbvtBroadphase_getOverlappingPairCache=C.btDbvtBroadphase_getOverlappingPairCache,r.btDbvtBroadphase_destroy=C.btDbvtBroadphase_destroy,r.btRigidBodyConstructionInfo_create=C.btRigidBodyConstructionInfo_create,r.btRigidBodyConstructionInfo_destroy=C.btRigidBodyConstructionInfo_destroy,r.btRigidBody_create=C.btRigidBody_create,r.btRigidBody_setCenterOfMassTransform=C.btRigidBody_setCenterOfMassTransform,r.btRigidBody_setSleepingThresholds=C.btRigidBody_setSleepingThresholds,r.btRigidBody_getLinearSleepingThreshold=C.btRigidBody_getLinearSleepingThreshold,r.btRigidBody_getAngularSleepingThreshold=C.btRigidBody_getAngularSleepingThreshold,r.btRigidBody_setDamping=C.btRigidBody_setDamping,r.btRigidBody_setMassProps=C.btRigidBody_setMassProps,r.btRigidBody_setLinearFactor=C.btRigidBody_setLinearFactor,r.btRigidBody_applyTorque=C.btRigidBody_applyTorque,r.btRigidBody_applyForce=C.btRigidBody_applyForce,r.btRigidBody_applyCentralForce=C.btRigidBody_applyCentralForce,r.btRigidBody_applyTorqueImpulse=C.btRigidBody_applyTorqueImpulse,r.btRigidBody_applyImpulse=C.btRigidBody_applyImpulse,r.btRigidBody_applyCentralImpulse=C.btRigidBody_applyCentralImpulse,r.btRigidBody_updateInertiaTensor=C.btRigidBody_updateInertiaTensor,r.btRigidBody_getLinearVelocity=C.btRigidBody_getLinearVelocity,r.btRigidBody_getAngularVelocity=C.btRigidBody_getAngularVelocity,r.btRigidBody_setLinearVelocity=C.btRigidBody_setLinearVelocity,r.btRigidBody_setAngularVelocity=C.btRigidBody_setAngularVelocity,r.btRigidBody_setAngularFactor=C.btRigidBody_setAngularFactor,r.btRigidBody_getGravity=C.btRigidBody_getGravity,r.btRigidBody_setGravity=C.btRigidBody_setGravity,r.btRigidBody_getTotalForce=C.btRigidBody_getTotalForce,r.btRigidBody_getTotalTorque=C.btRigidBody_getTotalTorque,r.btRigidBody_getFlags=C.btRigidBody_getFlags,r.btRigidBody_setFlags=C.btRigidBody_setFlags,r.btRigidBody_clearForces=C.btRigidBody_clearForces,r.btSequentialImpulseConstraintSolver_create=C.btSequentialImpulseConstraintSolver_create,r.btCollisionWorld_get_m_useContinuous=C.btCollisionWorld_get_m_useContinuous,r.btCollisionWorld_set_m_useContinuous=C.btCollisionWorld_set_m_useContinuous,r.btCollisionWorld_rayTest=C.btCollisionWorld_rayTest,r.btCollisionWorld_getDispatchInfo=C.btCollisionWorld_getDispatchInfo,r.btCollisionWorld_addCollisionObject=C.btCollisionWorld_addCollisionObject,r.btCollisionWorld_removeCollisionObject=C.btCollisionWorld_removeCollisionObject,r.btCollisionWorld_convexSweepTest=C.btCollisionWorld_convexSweepTest,r.btCollisionWorld_destroy=C.btCollisionWorld_destroy,r.btDynamicsWorld_addAction=C.btDynamicsWorld_addAction,r.btDynamicsWorld_removeAction=C.btDynamicsWorld_removeAction,r.btDynamicsWorld_getSolverInfo=C.btDynamicsWorld_getSolverInfo,r.btDiscreteDynamicsWorld_create=C.btDiscreteDynamicsWorld_create,r.btDiscreteDynamicsWorld_setGravity=C.btDiscreteDynamicsWorld_setGravity,r.btDiscreteDynamicsWorld_getGravity=C.btDiscreteDynamicsWorld_getGravity,r.btDiscreteDynamicsWorld_addRigidBody=C.btDiscreteDynamicsWorld_addRigidBody,r.btDiscreteDynamicsWorld_removeRigidBody=C.btDiscreteDynamicsWorld_removeRigidBody,r.btDiscreteDynamicsWorld_stepSimulation=C.btDiscreteDynamicsWorld_stepSimulation,r.btDiscreteDynamicsWorld_clearForces=C.btDiscreteDynamicsWorld_clearForces,r.btDiscreteDynamicsWorld_setApplySpeculativeContactRestitution=C.btDiscreteDynamicsWorld_setApplySpeculativeContactRestitution,r.btDiscreteDynamicsWorld_getApplySpeculativeContactRestitution=C.btDiscreteDynamicsWorld_getApplySpeculativeContactRestitution,r.btKinematicCharacterController_create=C.btKinematicCharacterController_create,r.btKinematicCharacterController_setWalkDirection=C.btKinematicCharacterController_setWalkDirection,r.btKinematicCharacterController_setFallSpeed=C.btKinematicCharacterController_setFallSpeed,r.btKinematicCharacterController_setJumpSpeed=C.btKinematicCharacterController_setJumpSpeed,r.btKinematicCharacterController_setMaxSlope=C.btKinematicCharacterController_setMaxSlope,r.btKinematicCharacterController_onGround=C.btKinematicCharacterController_onGround,r.btKinematicCharacterController_jump=C.btKinematicCharacterController_jump,r.btKinematicCharacterController_setGravity=C.btKinematicCharacterController_setGravity,r.btKinematicCharacterController_setUp=C.btKinematicCharacterController_setUp,r.btKinematicCharacterController_setStepHeight=C.btKinematicCharacterController_setStepHeight,r.btKinematicCharacterController_destroy=C.btKinematicCharacterController_destroy,r.btPairCachingGhostObject_create=C.btPairCachingGhostObject_create,r.btGhostPairCallback_create=C.btGhostPairCallback_create,r.btTypedConstraint_setEnabled=C.btTypedConstraint_setEnabled,r.btCollisionWorld_addConstraint=C.btCollisionWorld_addConstraint,r.btCollisionWorld_removeConstraint=C.btCollisionWorld_removeConstraint,r.btJointFeedback_create=C.btJointFeedback_create,r.btJointFeedback_destroy=C.btJointFeedback_destroy,r.btTypedConstraint_setJointFeedback=C.btTypedConstraint_setJointFeedback,r.btTypedConstraint_getJointFeedback=C.btTypedConstraint_getJointFeedback,r.btTypedConstraint_enableFeedback=C.btTypedConstraint_enableFeedback,r.btTypedConstraint_setParam=C.btTypedConstraint_setParam,r.btTypedConstraint_setOverrideNumSolverIterations=C.btTypedConstraint_setOverrideNumSolverIterations,r.btTypedConstraint_destroy=C.btTypedConstraint_destroy,r.btJointFeedback_getAppliedForceBodyA=C.btJointFeedback_getAppliedForceBodyA,r.btJointFeedback_getAppliedForceBodyB=C.btJointFeedback_getAppliedForceBodyB,r.btJointFeedback_getAppliedTorqueBodyA=C.btJointFeedback_getAppliedTorqueBodyA,r.btFixedConstraint_create=C.btFixedConstraint_create,r.btGeneric6DofSpring2Constraint_create=C.btGeneric6DofSpring2Constraint_create,r.btGeneric6DofSpring2Constraint_setAxis=C.btGeneric6DofSpring2Constraint_setAxis,r.btGeneric6DofSpring2Constraint_setLimit=C.btGeneric6DofSpring2Constraint_setLimit,r.btGeneric6DofSpring2Constraint_enableSpring=C.btGeneric6DofSpring2Constraint_enableSpring,r.btGeneric6DofSpring2Constraint_setBounce=C.btGeneric6DofSpring2Constraint_setBounce,r.btGeneric6DofSpring2Constraint_setStiffness=C.btGeneric6DofSpring2Constraint_setStiffness,r.btGeneric6DofSpring2Constraint_setDamping=C.btGeneric6DofSpring2Constraint_setDamping,r.btGeneric6DofSpring2Constraint_setEquilibriumPoint=C.btGeneric6DofSpring2Constraint_setEquilibriumPoint,r.btGeneric6DofSpring2Constraint_enableMotor=C.btGeneric6DofSpring2Constraint_enableMotor,r.btGeneric6DofSpring2Constraint_setServo=C.btGeneric6DofSpring2Constraint_setServo,r.btGeneric6DofSpring2Constraint_setTargetVelocity=C.btGeneric6DofSpring2Constraint_setTargetVelocity,r.btGeneric6DofSpring2Constraint_setServoTarget=C.btGeneric6DofSpring2Constraint_setServoTarget,r.btGeneric6DofSpring2Constraint_setMaxMotorForce=C.btGeneric6DofSpring2Constraint_setMaxMotorForce,r.btGeneric6DofSpring2Constraint_setFrames=C.btGeneric6DofSpring2Constraint_setFrames}(64*A*1024,e,r),r}; +(function (exports, Laya) { + 'use strict'; + + class ColliderShape { + constructor() { + this._scale = new Laya.Vector3(1, 1, 1); + this._centerMatrix = new Laya.Matrix4x4(); + this._attatched = false; + this._indexInCompound = -1; + this._compoundParent = null; + this._attatchedCollisionObject = null; + this._referenceCount = 0; + this._localOffset = new Laya.Vector3(0, 0, 0); + this._localRotation = new Laya.Quaternion(0, 0, 0, 1); + this.needsCustomCollisionCallback = false; + } + static __init__() { + var bt = Laya.ILaya3D.Physics3D._bullet; + ColliderShape._btScale = bt.btVector3_create(1, 1, 1); + ColliderShape._btVector30 = bt.btVector3_create(0, 0, 0); + ColliderShape._btQuaternion0 = bt.btQuaternion_create(0, 0, 0, 1); + ColliderShape._btTransform0 = bt.btTransform_create(); + } + static _createAffineTransformation(trans, rot, outE) { + var x = rot.x, y = rot.y, z = rot.z, w = rot.w, x2 = x + x, y2 = y + y, z2 = z + z; + var xx = x * x2, xy = x * y2, xz = x * z2, yy = y * y2, yz = y * z2, zz = z * z2; + var wx = w * x2, wy = w * y2, wz = w * z2; + outE[0] = (1 - (yy + zz)); + outE[1] = (xy + wz); + outE[2] = (xz - wy); + outE[3] = 0; + outE[4] = (xy - wz); + outE[5] = (1 - (xx + zz)); + outE[6] = (yz + wx); + outE[7] = 0; + outE[8] = (xz + wy); + outE[9] = (yz - wx); + outE[10] = (1 - (xx + yy)); + outE[11] = 0; + outE[12] = trans.x; + outE[13] = trans.y; + outE[14] = trans.z; + outE[15] = 1; + } + get type() { + return this._type; + } + get localOffset() { + return this._localOffset; + } + set localOffset(value) { + this._localOffset = value; + if (this._compoundParent) + this._compoundParent._updateChildTransform(this); + } + get localRotation() { + return this._localRotation; + } + set localRotation(value) { + this._localRotation = value; + if (this._compoundParent) + this._compoundParent._updateChildTransform(this); + } + _setScale(value) { + if (this._compoundParent) { + this.updateLocalTransformations(); + } + else { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(ColliderShape._btScale, value.x, value.y, value.z); + bt.btCollisionShape_setLocalScaling(this._btShape, ColliderShape._btScale); + } + } + _addReference() { + this._referenceCount++; + } + _removeReference() { + this._referenceCount--; + } + updateLocalTransformations() { + if (this._compoundParent) { + var offset = ColliderShape._tempVector30; + Laya.Vector3.multiply(this.localOffset, this._scale, offset); + ColliderShape._createAffineTransformation(offset, this.localRotation, this._centerMatrix.elements); + } + else { + ColliderShape._createAffineTransformation(this.localOffset, this.localRotation, this._centerMatrix.elements); + } + } + cloneTo(destObject) { + var destColliderShape = destObject; + this._localOffset.cloneTo(destColliderShape.localOffset); + this._localRotation.cloneTo(destColliderShape.localRotation); + destColliderShape.localOffset = destColliderShape.localOffset; + destColliderShape.localRotation = destColliderShape.localRotation; + } + clone() { + return null; + } + destroy() { + if (this._btShape) { + Laya.ILaya3D.Physics3D._bullet.btCollisionShape_destroy(this._btShape); + this._btShape = null; + } + } + } + ColliderShape.SHAPEORIENTATION_UPX = 0; + ColliderShape.SHAPEORIENTATION_UPY = 1; + ColliderShape.SHAPEORIENTATION_UPZ = 2; + ColliderShape.SHAPETYPES_BOX = 0; + ColliderShape.SHAPETYPES_SPHERE = 1; + ColliderShape.SHAPETYPES_CYLINDER = 2; + ColliderShape.SHAPETYPES_CAPSULE = 3; + ColliderShape.SHAPETYPES_CONVEXHULL = 4; + ColliderShape.SHAPETYPES_COMPOUND = 5; + ColliderShape.SHAPETYPES_STATICPLANE = 6; + ColliderShape.SHAPETYPES_CONE = 7; + ColliderShape._tempVector30 = new Laya.Vector3(); + + class BoxColliderShape extends ColliderShape { + constructor(sizeX = 1.0, sizeY = 1.0, sizeZ = 1.0) { + super(); + this._sizeX = sizeX; + this._sizeY = sizeY; + this._sizeZ = sizeZ; + this._type = ColliderShape.SHAPETYPES_BOX; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(BoxColliderShape._btSize, sizeX / 2, sizeY / 2, sizeZ / 2); + this._btShape = bt.btBoxShape_create(BoxColliderShape._btSize); + } + static __init__() { + BoxColliderShape._btSize = Laya.ILaya3D.Physics3D._bullet.btVector3_create(0, 0, 0); + } + get sizeX() { + return this._sizeX; + } + get sizeY() { + return this._sizeY; + } + get sizeZ() { + return this._sizeZ; + } + clone() { + var dest = new BoxColliderShape(this._sizeX, this._sizeY, this._sizeZ); + this.cloneTo(dest); + return dest; + } + } + + class CapsuleColliderShape extends ColliderShape { + constructor(radius = 0.5, length = 1.25, orientation = ColliderShape.SHAPEORIENTATION_UPY) { + super(); + this._radius = radius; + this._length = length; + this._orientation = orientation; + this._type = ColliderShape.SHAPETYPES_CAPSULE; + var bt = Laya.ILaya3D.Physics3D._bullet; + switch (orientation) { + case ColliderShape.SHAPEORIENTATION_UPX: + this._btShape = bt.btCapsuleShapeX_create(radius, length - radius * 2); + break; + case ColliderShape.SHAPEORIENTATION_UPY: + this._btShape = bt.btCapsuleShape_create(radius, length - radius * 2); + break; + case ColliderShape.SHAPEORIENTATION_UPZ: + this._btShape = bt.btCapsuleShapeZ_create(radius, length - radius * 2); + break; + default: + throw "CapsuleColliderShape:unknown orientation."; + } + } + get radius() { + return this._radius; + } + get length() { + return this._length; + } + get orientation() { + return this._orientation; + } + _setScale(value) { + var fixScale = CapsuleColliderShape._tempVector30; + switch (this.orientation) { + case ColliderShape.SHAPEORIENTATION_UPX: + fixScale.x = value.x; + fixScale.y = fixScale.z = Math.max(value.y, value.z); + break; + case ColliderShape.SHAPEORIENTATION_UPY: + fixScale.y = value.y; + fixScale.x = fixScale.z = Math.max(value.x, value.z); + break; + case ColliderShape.SHAPEORIENTATION_UPZ: + fixScale.z = value.z; + fixScale.x = fixScale.y = Math.max(value.x, value.y); + break; + default: + throw "CapsuleColliderShape:unknown orientation."; + } + super._setScale(fixScale); + } + clone() { + var dest = new CapsuleColliderShape(this._radius, this._length, this._orientation); + this.cloneTo(dest); + return dest; + } + } + CapsuleColliderShape._tempVector30 = new Laya.Vector3(); + + class CompoundColliderShape extends ColliderShape { + constructor() { + super(); + this._childColliderShapes = []; + this._type = ColliderShape.SHAPETYPES_COMPOUND; + this._btShape = Laya.ILaya3D.Physics3D._bullet.btCompoundShape_create(); + } + static __init__() { + var bt = Laya.ILaya3D.Physics3D._bullet; + CompoundColliderShape._btVector3One = bt.btVector3_create(1, 1, 1); + CompoundColliderShape._btTransform = bt.btTransform_create(); + CompoundColliderShape._btOffset = bt.btVector3_create(0, 0, 0); + CompoundColliderShape._btRotation = bt.btQuaternion_create(0, 0, 0, 1); + } + _clearChildShape(shape) { + shape._attatched = false; + shape._compoundParent = null; + shape._indexInCompound = -1; + } + _addReference() { + } + _removeReference() { + } + _updateChildTransform(shape) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var offset = shape.localOffset; + var rotation = shape.localRotation; + var btOffset = ColliderShape._btVector30; + var btQuaternion = ColliderShape._btQuaternion0; + var btTransform = ColliderShape._btTransform0; + bt.btVector3_setValue(btOffset, -offset.x, offset.y, offset.z); + bt.btQuaternion_setValue(btQuaternion, -rotation.x, rotation.y, rotation.z, -rotation.w); + bt.btTransform_setOrigin(btTransform, btOffset); + bt.btTransform_setRotation(btTransform, btQuaternion); + bt.btCompoundShape_updateChildTransform(this._btShape, shape._indexInCompound, btTransform, true); + } + addChildShape(shape) { + if (shape._attatched) + throw "CompoundColliderShape: this shape has attatched to other entity."; + shape._attatched = true; + shape._compoundParent = this; + shape._indexInCompound = this._childColliderShapes.length; + this._childColliderShapes.push(shape); + var offset = shape.localOffset; + var rotation = shape.localRotation; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(CompoundColliderShape._btOffset, -offset.x, offset.y, offset.z); + bt.btQuaternion_setValue(CompoundColliderShape._btRotation, -rotation.x, rotation.y, rotation.z, -rotation.w); + bt.btTransform_setOrigin(CompoundColliderShape._btTransform, CompoundColliderShape._btOffset); + bt.btTransform_setRotation(CompoundColliderShape._btTransform, CompoundColliderShape._btRotation); + var btScale = bt.btCollisionShape_getLocalScaling(this._btShape); + bt.btCollisionShape_setLocalScaling(this._btShape, CompoundColliderShape._btVector3One); + bt.btCompoundShape_addChildShape(this._btShape, CompoundColliderShape._btTransform, shape._btShape); + bt.btCollisionShape_setLocalScaling(this._btShape, btScale); + (this._attatchedCollisionObject) && (this._attatchedCollisionObject.colliderShape = this); + } + removeChildShape(shape) { + if (shape._compoundParent === this) { + var index = shape._indexInCompound; + this._clearChildShape(shape); + var endShape = this._childColliderShapes[this._childColliderShapes.length - 1]; + endShape._indexInCompound = index; + this._childColliderShapes[index] = endShape; + this._childColliderShapes.pop(); + Laya.ILaya3D.Physics3D._bullet.btCompoundShape_removeChildShapeByIndex(this._btShape, index); + } + } + clearChildShape() { + for (var i = 0, n = this._childColliderShapes.length; i < n; i++) { + this._clearChildShape(this._childColliderShapes[i]); + Laya.ILaya3D.Physics3D._bullet.btCompoundShape_removeChildShapeByIndex(this._btShape, 0); + } + this._childColliderShapes.length = 0; + } + getChildShapeCount() { + return this._childColliderShapes.length; + } + cloneTo(destObject) { + var destCompoundColliderShape = destObject; + destCompoundColliderShape.clearChildShape(); + for (var i = 0, n = this._childColliderShapes.length; i < n; i++) + destCompoundColliderShape.addChildShape(this._childColliderShapes[i].clone()); + } + clone() { + var dest = new CompoundColliderShape(); + this.cloneTo(dest); + return dest; + } + destroy() { + super.destroy(); + for (var i = 0, n = this._childColliderShapes.length; i < n; i++) { + var childShape = this._childColliderShapes[i]; + if (childShape._referenceCount === 0) + childShape.destroy(); + } + } + } + + class ConeColliderShape extends ColliderShape { + constructor(radius = 0.5, height = 1.0, orientation = ColliderShape.SHAPEORIENTATION_UPY) { + super(); + this._radius = 1; + this._height = 0.5; + this._radius = radius; + this._height = height; + this._orientation = orientation; + this._type = ColliderShape.SHAPETYPES_CYLINDER; + var bt = Laya.ILaya3D.Physics3D._bullet; + switch (orientation) { + case ColliderShape.SHAPEORIENTATION_UPX: + this._btShape = bt.btConeShapeX_create(radius, height); + break; + case ColliderShape.SHAPEORIENTATION_UPY: + this._btShape = bt.btConeShape_create(radius, height); + break; + case ColliderShape.SHAPEORIENTATION_UPZ: + this._btShape = bt.btConeShapeZ_create(radius, height); + break; + default: + throw "ConeColliderShape:unknown orientation."; + } + } + get radius() { + return this._radius; + } + get height() { + return this._height; + } + get orientation() { + return this._orientation; + } + clone() { + var dest = new ConeColliderShape(this._radius, this._height, this._orientation); + this.cloneTo(dest); + return dest; + } + } + + class CylinderColliderShape extends ColliderShape { + constructor(radius = 0.5, height = 1.0, orientation = ColliderShape.SHAPEORIENTATION_UPY) { + super(); + this._radius = 1; + this._height = 0.5; + this._radius = radius; + this._height = height; + this._orientation = orientation; + this._type = ColliderShape.SHAPETYPES_CYLINDER; + var bt = Laya.ILaya3D.Physics3D._bullet; + switch (orientation) { + case ColliderShape.SHAPEORIENTATION_UPX: + bt.btVector3_setValue(CylinderColliderShape._btSize, height / 2, radius, radius); + this._btShape = bt.btCylinderShapeX_create(CylinderColliderShape._btSize); + break; + case ColliderShape.SHAPEORIENTATION_UPY: + bt.btVector3_setValue(CylinderColliderShape._btSize, radius, height / 2, radius); + this._btShape = bt.btCylinderShape_create(CylinderColliderShape._btSize); + break; + case ColliderShape.SHAPEORIENTATION_UPZ: + bt.btVector3_setValue(CylinderColliderShape._btSize, radius, radius, height / 2); + this._btShape = bt.btCylinderShapeZ_create(CylinderColliderShape._btSize); + break; + default: + throw "CapsuleColliderShape:unknown orientation."; + } + } + static __init__() { + CylinderColliderShape._btSize = Laya.ILaya3D.Physics3D._bullet.btVector3_create(0, 0, 0); + } + get radius() { + return this._radius; + } + get height() { + return this._height; + } + get orientation() { + return this._orientation; + } + clone() { + var dest = new CylinderColliderShape(this._radius, this._height, this._orientation); + this.cloneTo(dest); + return dest; + } + } + + class MeshColliderShape extends ColliderShape { + constructor() { + super(); + this._mesh = null; + this._convex = false; + } + get mesh() { + return this._mesh; + } + set mesh(value) { + if (this._mesh !== value) { + var bt = Laya.ILaya3D.Physics3D._bullet; + if (this._mesh) { + bt.btCollisionShape_destroy(this._btShape); + } + if (value) { + this._btShape = bt.btGImpactMeshShape_create(value._getPhysicMesh()); + bt.btGImpactShapeInterface_updateBound(this._btShape); + } + this._mesh = value; + } + } + get convex() { + return this._convex; + } + set convex(value) { + this._convex = value; + } + _setScale(value) { + if (this._compoundParent) { + this.updateLocalTransformations(); + } + else { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(ColliderShape._btScale, value.x, value.y, value.z); + bt.btCollisionShape_setLocalScaling(this._btShape, ColliderShape._btScale); + bt.btGImpactShapeInterface_updateBound(this._btShape); + } + } + cloneTo(destObject) { + var destMeshCollider = destObject; + destMeshCollider.convex = this._convex; + destMeshCollider.mesh = this._mesh; + super.cloneTo(destObject); + } + clone() { + var dest = new MeshColliderShape(); + this.cloneTo(dest); + return dest; + } + destroy() { + if (this._btShape) { + Laya.ILaya3D.Physics3D._bullet.btCollisionShape_destroy(this._btShape); + this._btShape = null; + } + } + } + + class SphereColliderShape extends ColliderShape { + constructor(radius = 0.5) { + super(); + this._radius = radius; + this._type = ColliderShape.SHAPETYPES_SPHERE; + this._btShape = Laya.ILaya3D.Physics3D._bullet.btSphereShape_create(radius); + } + get radius() { + return this._radius; + } + clone() { + var dest = new SphereColliderShape(this._radius); + this.cloneTo(dest); + return dest; + } + } + + class PhysicsComponent extends Laya.Component { + constructor(collisionGroup, canCollideWith) { + super(); + this._restitution = 0.0; + this._friction = 0.5; + this._rollingFriction = 0.0; + this._ccdMotionThreshold = 0.0; + this._ccdSweptSphereRadius = 0.0; + this._collisionGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER; + this._canCollideWith = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER; + this._colliderShape = null; + this._transformFlag = 2147483647; + this._controlBySimulation = false; + this._enableProcessCollisions = true; + this._inPhysicUpdateListIndex = -1; + this.canScaleShape = true; + this._collisionGroup = collisionGroup; + this._canCollideWith = canCollideWith; + PhysicsComponent._physicObjectsMap[this.id] = this; + } + static __init__() { + var bt = Laya.ILaya3D.Physics3D._bullet; + PhysicsComponent._btVector30 = bt.btVector3_create(0, 0, 0); + PhysicsComponent._btQuaternion0 = bt.btQuaternion_create(0, 0, 0, 1); + } + static _createAffineTransformationArray(tranX, tranY, tranZ, rotX, rotY, rotZ, rotW, scale, outE) { + var x2 = rotX + rotX, y2 = rotY + rotY, z2 = rotZ + rotZ; + var xx = rotX * x2, xy = rotX * y2, xz = rotX * z2, yy = rotY * y2, yz = rotY * z2, zz = rotZ * z2; + var wx = rotW * x2, wy = rotW * y2, wz = rotW * z2, sx = scale[0], sy = scale[1], sz = scale[2]; + outE[0] = (1 - (yy + zz)) * sx; + outE[1] = (xy + wz) * sx; + outE[2] = (xz - wy) * sx; + outE[3] = 0; + outE[4] = (xy - wz) * sy; + outE[5] = (1 - (xx + zz)) * sy; + outE[6] = (yz + wx) * sy; + outE[7] = 0; + outE[8] = (xz + wy) * sz; + outE[9] = (yz - wx) * sz; + outE[10] = (1 - (xx + yy)) * sz; + outE[11] = 0; + outE[12] = tranX; + outE[13] = tranY; + outE[14] = tranZ; + outE[15] = 1; + } + static _creatShape(shapeData) { + var colliderShape; + switch (shapeData.type) { + case "BoxColliderShape": + var sizeData = shapeData.size; + colliderShape = sizeData ? new BoxColliderShape(sizeData[0], sizeData[1], sizeData[2]) : new BoxColliderShape(); + break; + case "SphereColliderShape": + colliderShape = new SphereColliderShape(shapeData.radius); + break; + case "CapsuleColliderShape": + colliderShape = new CapsuleColliderShape(shapeData.radius, shapeData.height, shapeData.orientation); + break; + case "MeshColliderShape": + var meshCollider = new MeshColliderShape(); + shapeData.mesh && (meshCollider.mesh = Laya.Loader.getRes(shapeData.mesh)); + colliderShape = meshCollider; + break; + case "ConeColliderShape": + colliderShape = new ConeColliderShape(shapeData.radius, shapeData.height, shapeData.orientation); + break; + case "CylinderColliderShape": + colliderShape = new CylinderColliderShape(shapeData.radius, shapeData.height, shapeData.orientation); + break; + default: + throw "unknown shape type."; + } + if (shapeData.center) { + var localOffset = colliderShape.localOffset; + localOffset.fromArray(shapeData.center); + colliderShape.localOffset = localOffset; + } + return colliderShape; + } + static physicVector3TransformQuat(source, qx, qy, qz, qw, out) { + var x = source.x, y = source.y, z = source.z, ix = qw * x + qy * z - qz * y, iy = qw * y + qz * x - qx * z, iz = qw * z + qx * y - qy * x, iw = -qx * x - qy * y - qz * z; + out.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; + out.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; + out.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + } + static physicQuaternionMultiply(lx, ly, lz, lw, right, out) { + var rx = right.x; + var ry = right.y; + var rz = right.z; + var rw = right.w; + var a = (ly * rz - lz * ry); + var b = (lz * rx - lx * rz); + var c = (lx * ry - ly * rx); + var d = (lx * rx + ly * ry + lz * rz); + out.x = (lx * rw + rx * lw) + a; + out.y = (ly * rw + ry * lw) + b; + out.z = (lz * rw + rz * lw) + c; + out.w = lw * rw - d; + } + get restitution() { + return this._restitution; + } + set restitution(value) { + this._restitution = value; + this._btColliderObject && Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setRestitution(this._btColliderObject, value); + } + get friction() { + return this._friction; + } + set friction(value) { + this._friction = value; + this._btColliderObject && Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setFriction(this._btColliderObject, value); + } + get rollingFriction() { + return this._rollingFriction; + } + set rollingFriction(value) { + this._rollingFriction = value; + this._btColliderObject && Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setRollingFriction(this._btColliderObject, value); + } + get ccdMotionThreshold() { + return this._ccdMotionThreshold; + } + set ccdMotionThreshold(value) { + this._ccdMotionThreshold = value; + this._btColliderObject && Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setCcdMotionThreshold(this._btColliderObject, value); + } + get ccdSweptSphereRadius() { + return this._ccdSweptSphereRadius; + } + set ccdSweptSphereRadius(value) { + this._ccdSweptSphereRadius = value; + this._btColliderObject && Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setCcdSweptSphereRadius(this._btColliderObject, value); + } + get isActive() { + return this._btColliderObject ? Laya.ILaya3D.Physics3D._bullet.btCollisionObject_isActive(this._btColliderObject) : false; + } + get colliderShape() { + return this._colliderShape; + } + set colliderShape(value) { + var lastColliderShape = this._colliderShape; + if (lastColliderShape) { + lastColliderShape._attatched = false; + lastColliderShape._attatchedCollisionObject = null; + } + this._colliderShape = value; + if (value) { + if (value._attatched) { + throw "PhysicsComponent: this shape has attatched to other entity."; + } + else { + value._attatched = true; + value._attatchedCollisionObject = this; + } + if (this._btColliderObject) { + Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setCollisionShape(this._btColliderObject, value._btShape); + var canInSimulation = this._simulation && this._enabled; + (canInSimulation && lastColliderShape) && (this._removeFromSimulation()); + this._onShapeChange(value); + if (canInSimulation) { + this._derivePhysicsTransformation(true); + this._addToSimulation(); + } + } + } + else { + if (this._simulation && this._enabled) + lastColliderShape && this._removeFromSimulation(); + } + } + get simulation() { + return this._simulation; + } + get collisionGroup() { + return this._collisionGroup; + } + set collisionGroup(value) { + if (this._collisionGroup !== value) { + this._collisionGroup = value; + if (this._simulation && this._colliderShape && this._enabled) { + this._removeFromSimulation(); + this._addToSimulation(); + } + } + } + get canCollideWith() { + return this._canCollideWith; + } + set canCollideWith(value) { + if (this._canCollideWith !== value) { + this._canCollideWith = value; + if (this._simulation && this._colliderShape && this._enabled) { + this._removeFromSimulation(); + this._addToSimulation(); + } + } + } + _parseShape(shapesData) { + var shapeCount = shapesData.length; + if (shapeCount === 1) { + var shape = PhysicsComponent._creatShape(shapesData[0]); + this.colliderShape = shape; + } + else { + var compoundShape = new CompoundColliderShape(); + for (var i = 0; i < shapeCount; i++) { + shape = PhysicsComponent._creatShape(shapesData[i]); + compoundShape.addChildShape(shape); + } + this.colliderShape = compoundShape; + } + } + _onScaleChange(scale) { + this._colliderShape._setScale(scale); + } + _onEnable() { + this._simulation = this.owner._scene.physicsSimulation; + Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setContactProcessingThreshold(this._btColliderObject, 0); + if (this._colliderShape) { + this._derivePhysicsTransformation(true); + this._addToSimulation(); + } + } + _onDisable() { + if (this._colliderShape) { + this._removeFromSimulation(); + (this._inPhysicUpdateListIndex !== -1) && (this._simulation._physicsUpdateList.remove(this)); + } + this._simulation = null; + } + _onDestroy() { + delete PhysicsComponent._physicObjectsMap[this.id]; + Laya.ILaya3D.Physics3D._bullet.btCollisionObject_destroy(this._btColliderObject); + this._colliderShape.destroy(); + super._onDestroy(); + this._btColliderObject = null; + this._colliderShape = null; + this._simulation = null; + this.owner.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onTransformChanged); + } + _isValid() { + return this._simulation && this._colliderShape && this._enabled; + } + _parse(data) { + (data.collisionGroup != null) && (this.collisionGroup = data.collisionGroup); + (data.canCollideWith != null) && (this.canCollideWith = data.canCollideWith); + (data.ccdMotionThreshold != null) && (this.ccdMotionThreshold = data.ccdMotionThreshold); + (data.ccdSweptSphereRadius != null) && (this.ccdSweptSphereRadius = data.ccdSweptSphereRadius); + } + _setTransformFlag(type, value) { + if (value) + this._transformFlag |= type; + else + this._transformFlag &= ~type; + } + _getTransformFlag(type) { + return (this._transformFlag & type) != 0; + } + _addToSimulation() { + } + _removeFromSimulation() { + } + _derivePhysicsTransformation(force) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var btColliderObject = this._btColliderObject; + var btTransform = bt.btCollisionObject_getWorldTransform(btColliderObject); + this._innerDerivePhysicsTransformation(btTransform, force); + bt.btCollisionObject_setWorldTransform(btColliderObject, btTransform); + } + _innerDerivePhysicsTransformation(physicTransformOut, force) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var transform = this.owner._transform; + if (force || this._getTransformFlag(Laya.Transform3D.TRANSFORM_WORLDPOSITION)) { + var shapeOffset = this._colliderShape.localOffset; + var position = transform.position; + var btPosition = PhysicsComponent._btVector30; + if (shapeOffset.x !== 0 || shapeOffset.y !== 0 || shapeOffset.z !== 0) { + var physicPosition = PhysicsComponent._tempVector30; + var worldMat = transform.worldMatrix; + Laya.Vector3.transformCoordinate(shapeOffset, worldMat, physicPosition); + bt.btVector3_setValue(btPosition, -physicPosition.x, physicPosition.y, physicPosition.z); + } + else { + bt.btVector3_setValue(btPosition, -position.x, position.y, position.z); + } + bt.btTransform_setOrigin(physicTransformOut, btPosition); + this._setTransformFlag(Laya.Transform3D.TRANSFORM_WORLDPOSITION, false); + } + if (force || this._getTransformFlag(Laya.Transform3D.TRANSFORM_WORLDQUATERNION)) { + var shapeRotation = this._colliderShape.localRotation; + var btRotation = PhysicsComponent._btQuaternion0; + var rotation = transform.rotation; + if (shapeRotation.x !== 0 || shapeRotation.y !== 0 || shapeRotation.z !== 0 || shapeRotation.w !== 1) { + var physicRotation = PhysicsComponent._tempQuaternion0; + PhysicsComponent.physicQuaternionMultiply(rotation.x, rotation.y, rotation.z, rotation.w, shapeRotation, physicRotation); + bt.btQuaternion_setValue(btRotation, -physicRotation.x, physicRotation.y, physicRotation.z, -physicRotation.w); + } + else { + bt.btQuaternion_setValue(btRotation, -rotation.x, rotation.y, rotation.z, -rotation.w); + } + bt.btTransform_setRotation(physicTransformOut, btRotation); + this._setTransformFlag(Laya.Transform3D.TRANSFORM_WORLDQUATERNION, false); + } + if (force || this._getTransformFlag(Laya.Transform3D.TRANSFORM_WORLDSCALE)) { + this._onScaleChange(transform.getWorldLossyScale()); + this._setTransformFlag(Laya.Transform3D.TRANSFORM_WORLDSCALE, false); + } + } + _updateTransformComponent(physicsTransform) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var colliderShape = this._colliderShape; + var localOffset = colliderShape.localOffset; + var localRotation = colliderShape.localRotation; + var transform = this.owner._transform; + var position = transform.position; + var rotation = transform.rotation; + var btPosition = bt.btTransform_getOrigin(physicsTransform); + var btRotation = bt.btTransform_getRotation(physicsTransform); + var btRotX = -bt.btQuaternion_x(btRotation); + var btRotY = bt.btQuaternion_y(btRotation); + var btRotZ = bt.btQuaternion_z(btRotation); + var btRotW = -bt.btQuaternion_w(btRotation); + if (localRotation.x !== 0 || localRotation.y !== 0 || localRotation.z !== 0 || localRotation.w !== 1) { + var invertShapeRotaion = PhysicsComponent._tempQuaternion0; + localRotation.invert(invertShapeRotaion); + PhysicsComponent.physicQuaternionMultiply(btRotX, btRotY, btRotZ, btRotW, invertShapeRotaion, rotation); + } + else { + rotation.x = btRotX; + rotation.y = btRotY; + rotation.z = btRotZ; + rotation.w = btRotW; + } + transform.rotation = rotation; + if (localOffset.x !== 0 || localOffset.y !== 0 || localOffset.z !== 0) { + var btScale = bt.btCollisionShape_getLocalScaling(colliderShape._btShape); + var rotShapePosition = PhysicsComponent._tempVector30; + rotShapePosition.x = localOffset.x * bt.btVector3_x(btScale); + rotShapePosition.y = localOffset.y * bt.btVector3_y(btScale); + rotShapePosition.z = localOffset.z * bt.btVector3_z(btScale); + Laya.Vector3.transformQuat(rotShapePosition, rotation, rotShapePosition); + position.x = -bt.btVector3_x(btPosition) - rotShapePosition.x; + position.y = bt.btVector3_y(btPosition) - rotShapePosition.y; + position.z = bt.btVector3_z(btPosition) - rotShapePosition.z; + } + else { + position.x = -bt.btVector3_x(btPosition); + position.y = bt.btVector3_y(btPosition); + position.z = bt.btVector3_z(btPosition); + } + transform.position = position; + } + _onShapeChange(colShape) { + var btColObj = this._btColliderObject; + var bt = Laya.ILaya3D.Physics3D._bullet; + var flags = bt.btCollisionObject_getCollisionFlags(btColObj); + if (colShape.needsCustomCollisionCallback) { + if ((flags & PhysicsComponent.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK) === 0) + bt.btCollisionObject_setCollisionFlags(btColObj, flags | PhysicsComponent.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK); + } + else { + if ((flags & PhysicsComponent.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK) > 0) + bt.btCollisionObject_setCollisionFlags(btColObj, flags ^ PhysicsComponent.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK); + } + } + _onAdded() { + this.enabled = this._enabled; + this.restitution = this._restitution; + this.friction = this._friction; + this.rollingFriction = this._rollingFriction; + this.ccdMotionThreshold = this._ccdMotionThreshold; + this.ccdSweptSphereRadius = this._ccdSweptSphereRadius; + this.owner.transform.on(Laya.Event.TRANSFORM_CHANGED, this, this._onTransformChanged); + } + _onTransformChanged(flag) { + if (PhysicsComponent._addUpdateList || !this._controlBySimulation) { + flag &= Laya.Transform3D.TRANSFORM_WORLDPOSITION | Laya.Transform3D.TRANSFORM_WORLDQUATERNION | Laya.Transform3D.TRANSFORM_WORLDSCALE; + if (flag) { + this._transformFlag |= flag; + if (this._isValid() && this._inPhysicUpdateListIndex === -1) + this._simulation._physicsUpdateList.add(this); + } + } + } + _cloneTo(dest) { + var destPhysicsComponent = dest; + destPhysicsComponent.restitution = this._restitution; + destPhysicsComponent.friction = this._friction; + destPhysicsComponent.rollingFriction = this._rollingFriction; + destPhysicsComponent.ccdMotionThreshold = this._ccdMotionThreshold; + destPhysicsComponent.ccdSweptSphereRadius = this._ccdSweptSphereRadius; + destPhysicsComponent.collisionGroup = this._collisionGroup; + destPhysicsComponent.canCollideWith = this._canCollideWith; + destPhysicsComponent.canScaleShape = this.canScaleShape; + (this._colliderShape) && (destPhysicsComponent.colliderShape = this._colliderShape.clone()); + } + } + PhysicsComponent.ACTIVATIONSTATE_ACTIVE_TAG = 1; + PhysicsComponent.ACTIVATIONSTATE_ISLAND_SLEEPING = 2; + PhysicsComponent.ACTIVATIONSTATE_WANTS_DEACTIVATION = 3; + PhysicsComponent.ACTIVATIONSTATE_DISABLE_DEACTIVATION = 4; + PhysicsComponent.ACTIVATIONSTATE_DISABLE_SIMULATION = 5; + PhysicsComponent.COLLISIONFLAGS_STATIC_OBJECT = 1; + PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT = 2; + PhysicsComponent.COLLISIONFLAGS_NO_CONTACT_RESPONSE = 4; + PhysicsComponent.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK = 8; + PhysicsComponent.COLLISIONFLAGS_CHARACTER_OBJECT = 16; + PhysicsComponent.COLLISIONFLAGS_DISABLE_VISUALIZE_OBJECT = 32; + PhysicsComponent.COLLISIONFLAGS_DISABLE_SPU_COLLISION_PROCESSING = 64; + PhysicsComponent._tempVector30 = new Laya.Vector3(); + PhysicsComponent._tempQuaternion0 = new Laya.Quaternion(); + PhysicsComponent._tempQuaternion1 = new Laya.Quaternion(); + PhysicsComponent._tempMatrix4x40 = new Laya.Matrix4x4(); + PhysicsComponent._physicObjectsMap = {}; + PhysicsComponent._addUpdateList = true; + + class BulletInteractive { + } + BulletInteractive._interactive = { + "getWorldTransform": (rigidBodyID, worldTransPointer) => { + }, + "setWorldTransform": (rigidBodyID, worldTransPointer) => { + var rigidBody = PhysicsComponent._physicObjectsMap[rigidBodyID]; + rigidBody._simulation._updatedRigidbodies++; + rigidBody._updateTransformComponent(worldTransPointer); + } + }; + + class CharacterController extends PhysicsComponent { + constructor(stepheight = 0.1, upAxis = null, collisionGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER, canCollideWith = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + super(collisionGroup, canCollideWith); + this._upAxis = new Laya.Vector3(0, 1, 0); + this._maxSlope = 45.0; + this._jumpSpeed = 10.0; + this._fallSpeed = 55.0; + this._gravity = new Laya.Vector3(0, -9.8 * 3, 0); + this._btKinematicCharacter = null; + this._stepHeight = stepheight; + (upAxis) && (this._upAxis = upAxis); + this._controlBySimulation = true; + } + static __init__() { + CharacterController._btTempVector30 = Laya.ILaya3D.Physics3D._bullet.btVector3_create(0, 0, 0); + } + get fallSpeed() { + return this._fallSpeed; + } + set fallSpeed(value) { + this._fallSpeed = value; + Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setFallSpeed(this._btKinematicCharacter, value); + } + get jumpSpeed() { + return this._jumpSpeed; + } + set jumpSpeed(value) { + this._jumpSpeed = value; + Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setJumpSpeed(this._btKinematicCharacter, value); + } + get gravity() { + return this._gravity; + } + set gravity(value) { + this._gravity = value; + var bt = Laya.ILaya3D.Physics3D._bullet; + var btGravity = CharacterController._btTempVector30; + bt.btVector3_setValue(btGravity, -value.x, value.y, value.z); + bt.btKinematicCharacterController_setGravity(this._btKinematicCharacter, btGravity); + } + get maxSlope() { + return this._maxSlope; + } + set maxSlope(value) { + this._maxSlope = value; + Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setMaxSlope(this._btKinematicCharacter, (value / 180) * Math.PI); + } + get isGrounded() { + return Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_onGround(this._btKinematicCharacter); + } + get stepHeight() { + return this._stepHeight; + } + set stepHeight(value) { + this._stepHeight = value; + Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setStepHeight(this._btKinematicCharacter, value); + } + get upAxis() { + return this._upAxis; + } + set upAxis(value) { + this._upAxis = value; + var btUpAxis = CharacterController._btTempVector30; + Laya.Utils3D._convertToBulletVec3(value, btUpAxis, false); + Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setUp(this._btKinematicCharacter, btUpAxis); + } + _constructCharacter() { + var bt = Laya.ILaya3D.Physics3D._bullet; + if (this._btKinematicCharacter) + bt.btKinematicCharacterController_destroy(this._btKinematicCharacter); + var btUpAxis = CharacterController._btTempVector30; + bt.btVector3_setValue(btUpAxis, this._upAxis.x, this._upAxis.y, this._upAxis.z); + this._btKinematicCharacter = bt.btKinematicCharacterController_create(this._btColliderObject, this._colliderShape._btShape, this._stepHeight, btUpAxis); + this.fallSpeed = this._fallSpeed; + this.maxSlope = this._maxSlope; + this.jumpSpeed = this._jumpSpeed; + this.gravity = this._gravity; + } + _onShapeChange(colShape) { + super._onShapeChange(colShape); + this._constructCharacter(); + } + _onAdded() { + var bt = Laya.ILaya3D.Physics3D._bullet; + var ghostObject = bt.btPairCachingGhostObject_create(); + bt.btCollisionObject_setUserIndex(ghostObject, this.id); + bt.btCollisionObject_setCollisionFlags(ghostObject, PhysicsComponent.COLLISIONFLAGS_CHARACTER_OBJECT); + this._btColliderObject = ghostObject; + (this._colliderShape) && (this._constructCharacter()); + super._onAdded(); + } + _addToSimulation() { + this._simulation._characters.push(this); + this._simulation._addCharacter(this, this._collisionGroup, this._canCollideWith); + } + _removeFromSimulation() { + this._simulation._removeCharacter(this); + var characters = this._simulation._characters; + characters.splice(characters.indexOf(this), 1); + } + _cloneTo(dest) { + super._cloneTo(dest); + var destCharacterController = dest; + destCharacterController.stepHeight = this._stepHeight; + destCharacterController.upAxis = this._upAxis; + destCharacterController.maxSlope = this._maxSlope; + destCharacterController.jumpSpeed = this._jumpSpeed; + destCharacterController.fallSpeed = this._fallSpeed; + destCharacterController.gravity = this._gravity; + } + _onDestroy() { + Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_destroy(this._btKinematicCharacter); + super._onDestroy(); + this._btKinematicCharacter = null; + } + move(movement) { + var btMovement = CharacterController._btVector30; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(btMovement, -movement.x, movement.y, movement.z); + bt.btKinematicCharacterController_setWalkDirection(this._btKinematicCharacter, btMovement); + } + jump(velocity = null) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var btVelocity = CharacterController._btVector30; + if (velocity) { + Laya.Utils3D._convertToBulletVec3(velocity, btVelocity, true); + bt.btKinematicCharacterController_jump(this._btKinematicCharacter, btVelocity); + } + else { + bt.btVector3_setValue(btVelocity, 0, 0, 0); + bt.btKinematicCharacterController_jump(this._btKinematicCharacter, btVelocity); + } + } + } + CharacterController.UPAXIS_X = 0; + CharacterController.UPAXIS_Y = 1; + CharacterController.UPAXIS_Z = 2; + + class Collision { + constructor() { + this._lastUpdateFrame = -2147483648; + this._updateFrame = -2147483648; + this._isTrigger = false; + this.contacts = []; + } + _setUpdateFrame(farme) { + this._lastUpdateFrame = this._updateFrame; + this._updateFrame = farme; + } + } + + class ContactPoint { + constructor() { + this._idCounter = 0; + this.colliderA = null; + this.colliderB = null; + this.distance = 0; + this.normal = new Laya.Vector3(); + this.positionOnA = new Laya.Vector3(); + this.positionOnB = new Laya.Vector3(); + this._id = ++this._idCounter; + } + } + + class HitResult { + constructor() { + this.succeeded = false; + this.collider = null; + this.point = new Laya.Vector3(); + this.normal = new Laya.Vector3(); + this.hitFraction = 0; + } + } + + class CollisionTool { + constructor() { + this._hitResultsPoolIndex = 0; + this._hitResultsPool = []; + this._contactPonintsPoolIndex = 0; + this._contactPointsPool = []; + this._collisionsPool = []; + this._collisions = {}; + } + getHitResult() { + var hitResult = this._hitResultsPool[this._hitResultsPoolIndex++]; + if (!hitResult) { + hitResult = new HitResult(); + this._hitResultsPool.push(hitResult); + } + return hitResult; + } + recoverAllHitResultsPool() { + this._hitResultsPoolIndex = 0; + } + getContactPoints() { + var contactPoint = this._contactPointsPool[this._contactPonintsPoolIndex++]; + if (!contactPoint) { + contactPoint = new ContactPoint(); + this._contactPointsPool.push(contactPoint); + } + return contactPoint; + } + recoverAllContactPointsPool() { + this._contactPonintsPoolIndex = 0; + } + getCollision(physicComponentA, physicComponentB) { + var collision; + var idA = physicComponentA.id; + var idB = physicComponentB.id; + var subCollisionFirst = this._collisions[idA]; + if (subCollisionFirst) + collision = subCollisionFirst[idB]; + if (!collision) { + if (!subCollisionFirst) { + subCollisionFirst = {}; + this._collisions[idA] = subCollisionFirst; + } + collision = this._collisionsPool.length === 0 ? new Collision() : this._collisionsPool.pop(); + collision._colliderA = physicComponentA; + collision._colliderB = physicComponentB; + subCollisionFirst[idB] = collision; + } + return collision; + } + recoverCollision(collision) { + var idA = collision._colliderA.id; + var idB = collision._colliderB.id; + this._collisions[idA][idB] = null; + this._collisionsPool.push(collision); + } + garbageCollection() { + this._hitResultsPoolIndex = 0; + this._hitResultsPool.length = 0; + this._contactPonintsPoolIndex = 0; + this._contactPointsPool.length = 0; + this._collisionsPool.length = 0; + for (var subCollisionsKey in this._collisionsPool) { + var subCollisions = this._collisionsPool[subCollisionsKey]; + var wholeDelete = true; + for (var collisionKey in subCollisions) { + if (subCollisions[collisionKey]) + wholeDelete = false; + else + delete subCollisions[collisionKey]; + } + if (wholeDelete) + delete this._collisionsPool[subCollisionsKey]; + } + } + } + + class Constraint3D { + constructor() { + } + } + + class PhysicsTriggerComponent extends PhysicsComponent { + constructor(collisionGroup, canCollideWith) { + super(collisionGroup, canCollideWith); + this._isTrigger = false; + } + get isTrigger() { + return this._isTrigger; + } + set isTrigger(value) { + this._isTrigger = value; + var bt = Laya.ILaya3D.Physics3D._bullet; + if (this._btColliderObject) { + var flags = bt.btCollisionObject_getCollisionFlags(this._btColliderObject); + if (value) { + if ((flags & PhysicsComponent.COLLISIONFLAGS_NO_CONTACT_RESPONSE) === 0) + bt.btCollisionObject_setCollisionFlags(this._btColliderObject, flags | PhysicsComponent.COLLISIONFLAGS_NO_CONTACT_RESPONSE); + } + else { + if ((flags & PhysicsComponent.COLLISIONFLAGS_NO_CONTACT_RESPONSE) !== 0) + bt.btCollisionObject_setCollisionFlags(this._btColliderObject, flags ^ PhysicsComponent.COLLISIONFLAGS_NO_CONTACT_RESPONSE); + } + } + } + _onAdded() { + super._onAdded(); + this.isTrigger = this._isTrigger; + } + _cloneTo(dest) { + super._cloneTo(dest); + dest.isTrigger = this._isTrigger; + } + } + + class PhysicsCollider extends PhysicsTriggerComponent { + constructor(collisionGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER, canCollideWith = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + super(collisionGroup, canCollideWith); + this._enableProcessCollisions = false; + } + _addToSimulation() { + this._simulation._addPhysicsCollider(this, this._collisionGroup, this._canCollideWith); + } + _removeFromSimulation() { + this._simulation._removePhysicsCollider(this); + } + _parse(data) { + (data.friction != null) && (this.friction = data.friction); + (data.rollingFriction != null) && (this.rollingFriction = data.rollingFriction); + (data.restitution != null) && (this.restitution = data.restitution); + (data.isTrigger != null) && (this.isTrigger = data.isTrigger); + super._parse(data); + this._parseShape(data.shapes); + } + _onAdded() { + var bt = Laya.Physics3D._bullet; + var btColObj = bt.btCollisionObject_create(); + bt.btCollisionObject_setUserIndex(btColObj, this.id); + bt.btCollisionObject_forceActivationState(btColObj, PhysicsComponent.ACTIVATIONSTATE_DISABLE_SIMULATION); + var flags = bt.btCollisionObject_getCollisionFlags(btColObj); + if (this.owner.isStatic) { + if ((flags & PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT) > 0) + flags = flags ^ PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT; + flags = flags | PhysicsComponent.COLLISIONFLAGS_STATIC_OBJECT; + } + else { + if ((flags & PhysicsComponent.COLLISIONFLAGS_STATIC_OBJECT) > 0) + flags = flags ^ PhysicsComponent.COLLISIONFLAGS_STATIC_OBJECT; + flags = flags | PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT; + } + bt.btCollisionObject_setCollisionFlags(btColObj, flags); + this._btColliderObject = btColObj; + super._onAdded(); + } + } + + class PhysicsSettings { + constructor() { + this.flags = 0; + this.maxSubSteps = 1; + this.fixedTimeStep = 1.0 / 60.0; + } + } + + class PhysicsUpdateList extends Laya.SingletonList { + constructor() { + super(); + } + add(element) { + var index = element._inPhysicUpdateListIndex; + if (index !== -1) + throw "PhysicsUpdateList:element has in PhysicsUpdateList."; + this._add(element); + element._inPhysicUpdateListIndex = this.length++; + } + remove(element) { + var index = element._inPhysicUpdateListIndex; + this.length--; + if (index !== this.length) { + var end = this.elements[this.length]; + this.elements[index] = end; + end._inPhysicUpdateListIndex = index; + } + element._inPhysicUpdateListIndex = -1; + } + } + + class PhysicsSimulation { + constructor(configuration) { + this._gravity = new Laya.Vector3(0, -10, 0); + this._btVector3Zero = Laya.ILaya3D.Physics3D._bullet.btVector3_create(0, 0, 0); + this._btDefaultQuaternion = Laya.ILaya3D.Physics3D._bullet.btQuaternion_create(0, 0, 0, -1); + this._collisionsUtils = new CollisionTool(); + this._previousFrameCollisions = []; + this._currentFrameCollisions = []; + this._currentConstraint = {}; + this._physicsUpdateList = new PhysicsUpdateList(); + this._characters = []; + this._updatedRigidbodies = 0; + this.maxSubSteps = 1; + this.fixedTimeStep = 1.0 / 60.0; + this.maxSubSteps = configuration.maxSubSteps; + this.fixedTimeStep = configuration.fixedTimeStep; + var bt = Laya.ILaya3D.Physics3D._bullet; + this._btCollisionConfiguration = bt.btDefaultCollisionConfiguration_create(); + this._btDispatcher = bt.btCollisionDispatcher_create(this._btCollisionConfiguration); + this._btBroadphase = bt.btDbvtBroadphase_create(); + bt.btOverlappingPairCache_setInternalGhostPairCallback(bt.btDbvtBroadphase_getOverlappingPairCache(this._btBroadphase), bt.btGhostPairCallback_create()); + var conFlags = configuration.flags; + if (conFlags & PhysicsSimulation.PHYSICSENGINEFLAGS_COLLISIONSONLY) { + this._btCollisionWorld = new bt.btCollisionWorld(this._btDispatcher, this._btBroadphase, this._btCollisionConfiguration); + } + else if (conFlags & PhysicsSimulation.PHYSICSENGINEFLAGS_SOFTBODYSUPPORT) { + throw "PhysicsSimulation:SoftBody processing is not yet available"; + } + else { + var solver = bt.btSequentialImpulseConstraintSolver_create(); + this._btDiscreteDynamicsWorld = bt.btDiscreteDynamicsWorld_create(this._btDispatcher, this._btBroadphase, solver, this._btCollisionConfiguration); + this._btCollisionWorld = this._btDiscreteDynamicsWorld; + } + if (this._btDiscreteDynamicsWorld) { + this._btSolverInfo = bt.btDynamicsWorld_getSolverInfo(this._btDiscreteDynamicsWorld); + this._btDispatchInfo = bt.btCollisionWorld_getDispatchInfo(this._btDiscreteDynamicsWorld); + } + this._btClosestRayResultCallback = bt.ClosestRayResultCallback_create(this._btVector3Zero, this._btVector3Zero); + this._btAllHitsRayResultCallback = bt.AllHitsRayResultCallback_create(this._btVector3Zero, this._btVector3Zero); + this._btClosestConvexResultCallback = bt.ClosestConvexResultCallback_create(this._btVector3Zero, this._btVector3Zero); + this._btAllConvexResultCallback = bt.AllConvexResultCallback_create(this._btVector3Zero, this._btVector3Zero); + this.setHitsRayResultCallbackFlag(); + bt.btGImpactCollisionAlgorithm_RegisterAlgorithm(this._btDispatcher); + } + static __init__() { + var bt = Laya.ILaya3D.Physics3D._bullet; + PhysicsSimulation._btTempVector30 = bt.btVector3_create(0, 0, 0); + PhysicsSimulation._btTempVector31 = bt.btVector3_create(0, 0, 0); + PhysicsSimulation._btTempQuaternion0 = bt.btQuaternion_create(0, 0, 0, 1); + PhysicsSimulation._btTempQuaternion1 = bt.btQuaternion_create(0, 0, 0, 1); + PhysicsSimulation._btTempTransform0 = bt.btTransform_create(); + PhysicsSimulation._btTempTransform1 = bt.btTransform_create(); + } + static createConstraint() { + } + get continuousCollisionDetection() { + return Laya.ILaya3D.Physics3D._bullet.btCollisionWorld_get_m_useContinuous(this._btDispatchInfo); + } + set continuousCollisionDetection(value) { + Laya.ILaya3D.Physics3D._bullet.btCollisionWorld_set_m_useContinuous(this._btDispatchInfo, value); + } + get gravity() { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + return this._gravity; + } + set gravity(value) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + this._gravity = value; + var bt = Laya.ILaya3D.Physics3D._bullet; + var btGravity = PhysicsSimulation._btTempVector30; + bt.btVector3_setValue(btGravity, -value.x, value.y, value.z); + bt.btDiscreteDynamicsWorld_setGravity(this._btDiscreteDynamicsWorld, btGravity); + } + get speculativeContactRestitution() { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot Cannot perform this action when the physics engine is set to CollisionsOnly"; + return Laya.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_getApplySpeculativeContactRestitution(this._btDiscreteDynamicsWorld); + } + set speculativeContactRestitution(value) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot Cannot perform this action when the physics engine is set to CollisionsOnly"; + Laya.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_setApplySpeculativeContactRestitution(this._btDiscreteDynamicsWorld, value); + } + _simulate(deltaTime) { + this._updatedRigidbodies = 0; + var bt = Laya.ILaya3D.Physics3D._bullet; + if (this._btDiscreteDynamicsWorld) + bt.btDiscreteDynamicsWorld_stepSimulation(this._btDiscreteDynamicsWorld, deltaTime, this.maxSubSteps, this.fixedTimeStep); + else + bt.PerformDiscreteCollisionDetection(this._btCollisionWorld); + } + _destroy() { + var bt = Laya.ILaya3D.Physics3D._bullet; + if (this._btDiscreteDynamicsWorld) { + bt.btCollisionWorld_destroy(this._btDiscreteDynamicsWorld); + this._btDiscreteDynamicsWorld = null; + } + else { + bt.btCollisionWorld_destroy(this._btCollisionWorld); + this._btCollisionWorld = null; + } + bt.btDbvtBroadphase_destroy(this._btBroadphase); + this._btBroadphase = null; + bt.btCollisionDispatcher_destroy(this._btDispatcher); + this._btDispatcher = null; + bt.btDefaultCollisionConfiguration_destroy(this._btCollisionConfiguration); + this._btCollisionConfiguration = null; + } + _addPhysicsCollider(component, group, mask) { + Laya.ILaya3D.Physics3D._bullet.btCollisionWorld_addCollisionObject(this._btCollisionWorld, component._btColliderObject, group, mask); + } + _removePhysicsCollider(component) { + Laya.ILaya3D.Physics3D._bullet.btCollisionWorld_removeCollisionObject(this._btCollisionWorld, component._btColliderObject); + } + _addRigidBody(rigidBody, group, mask) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + Laya.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_addRigidBody(this._btCollisionWorld, rigidBody._btColliderObject, group, mask); + } + _removeRigidBody(rigidBody) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + Laya.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_removeRigidBody(this._btCollisionWorld, rigidBody._btColliderObject); + } + _addCharacter(character, group, mask) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btCollisionWorld_addCollisionObject(this._btCollisionWorld, character._btColliderObject, group, mask); + bt.btDynamicsWorld_addAction(this._btCollisionWorld, character._btKinematicCharacter); + } + _removeCharacter(character) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btCollisionWorld_removeCollisionObject(this._btCollisionWorld, character._btColliderObject); + bt.btDynamicsWorld_removeAction(this._btCollisionWorld, character._btKinematicCharacter); + } + raycastFromTo(from, to, out = null, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var rayResultCall = this._btClosestRayResultCallback; + var rayFrom = PhysicsSimulation._btTempVector30; + var rayTo = PhysicsSimulation._btTempVector31; + bt.btVector3_setValue(rayFrom, -from.x, from.y, from.z); + bt.btVector3_setValue(rayTo, -to.x, to.y, to.z); + bt.ClosestRayResultCallback_set_m_rayFromWorld(rayResultCall, rayFrom); + bt.ClosestRayResultCallback_set_m_rayToWorld(rayResultCall, rayTo); + bt.RayResultCallback_set_m_collisionFilterGroup(rayResultCall, collisonGroup); + bt.RayResultCallback_set_m_collisionFilterMask(rayResultCall, collisionMask); + bt.RayResultCallback_set_m_collisionObject(rayResultCall, null); + bt.RayResultCallback_set_m_closestHitFraction(rayResultCall, 1); + bt.btCollisionWorld_rayTest(this._btCollisionWorld, rayFrom, rayTo, rayResultCall); + if (bt.RayResultCallback_hasHit(rayResultCall)) { + if (out) { + out.succeeded = true; + out.collider = PhysicsComponent._physicObjectsMap[bt.btCollisionObject_getUserIndex(bt.RayResultCallback_get_m_collisionObject(rayResultCall))]; + out.hitFraction = bt.RayResultCallback_get_m_closestHitFraction(rayResultCall); + var btPoint = bt.ClosestRayResultCallback_get_m_hitPointWorld(rayResultCall); + var point = out.point; + point.x = -bt.btVector3_x(btPoint); + point.y = bt.btVector3_y(btPoint); + point.z = bt.btVector3_z(btPoint); + var btNormal = bt.ClosestRayResultCallback_get_m_hitNormalWorld(rayResultCall); + var normal = out.normal; + normal.x = -bt.btVector3_x(btNormal); + normal.y = bt.btVector3_y(btNormal); + normal.z = bt.btVector3_z(btNormal); + } + return true; + } + else { + if (out) + out.succeeded = false; + return false; + } + } + raycastAllFromTo(from, to, out, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var rayResultCall = this._btAllHitsRayResultCallback; + var rayFrom = PhysicsSimulation._btTempVector30; + var rayTo = PhysicsSimulation._btTempVector31; + out.length = 0; + bt.btVector3_setValue(rayFrom, -from.x, from.y, from.z); + bt.btVector3_setValue(rayTo, -to.x, to.y, to.z); + bt.AllHitsRayResultCallback_set_m_rayFromWorld(rayResultCall, rayFrom); + bt.AllHitsRayResultCallback_set_m_rayToWorld(rayResultCall, rayTo); + bt.RayResultCallback_set_m_collisionFilterGroup(rayResultCall, collisonGroup); + bt.RayResultCallback_set_m_collisionFilterMask(rayResultCall, collisionMask); + var collisionObjects = bt.AllHitsRayResultCallback_get_m_collisionObjects(rayResultCall); + var btPoints = bt.AllHitsRayResultCallback_get_m_hitPointWorld(rayResultCall); + var btNormals = bt.AllHitsRayResultCallback_get_m_hitNormalWorld(rayResultCall); + var btFractions = bt.AllHitsRayResultCallback_get_m_hitFractions(rayResultCall); + bt.tBtCollisionObjectArray_clear(collisionObjects); + bt.tVector3Array_clear(btPoints); + bt.tVector3Array_clear(btNormals); + bt.tScalarArray_clear(btFractions); + bt.btCollisionWorld_rayTest(this._btCollisionWorld, rayFrom, rayTo, rayResultCall); + var count = bt.tBtCollisionObjectArray_size(collisionObjects); + if (count > 0) { + this._collisionsUtils.recoverAllHitResultsPool(); + for (var i = 0; i < count; i++) { + var hitResult = this._collisionsUtils.getHitResult(); + out.push(hitResult); + hitResult.succeeded = true; + hitResult.collider = PhysicsComponent._physicObjectsMap[bt.btCollisionObject_getUserIndex(bt.tBtCollisionObjectArray_at(collisionObjects, i))]; + hitResult.hitFraction = bt.tScalarArray_at(btFractions, i); + var btPoint = bt.tVector3Array_at(btPoints, i); + var pointE = hitResult.point; + pointE.x = -bt.btVector3_x(btPoint); + pointE.y = bt.btVector3_y(btPoint); + pointE.z = bt.btVector3_z(btPoint); + var btNormal = bt.tVector3Array_at(btNormals, i); + var normal = hitResult.normal; + normal.x = -bt.btVector3_x(btNormal); + normal.y = bt.btVector3_y(btNormal); + normal.z = bt.btVector3_z(btNormal); + } + return true; + } + else { + return false; + } + } + rayCast(ray, outHitResult = null, distance = 2147483647, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + var from = ray.origin; + var to = PhysicsSimulation._tempVector30; + Laya.Vector3.normalize(ray.direction, to); + Laya.Vector3.scale(to, distance, to); + Laya.Vector3.add(from, to, to); + return this.raycastFromTo(from, to, outHitResult, collisonGroup, collisionMask); + } + rayCastAll(ray, out, distance = 2147483647, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + var from = ray.origin; + var to = PhysicsSimulation._tempVector30; + Laya.Vector3.normalize(ray.direction, to); + Laya.Vector3.scale(to, distance, to); + Laya.Vector3.add(from, to, to); + return this.raycastAllFromTo(from, to, out, collisonGroup, collisionMask); + } + shapeCast(shape, fromPosition, toPosition, out = null, fromRotation = null, toRotation = null, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, allowedCcdPenetration = 0.0) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var convexResultCall = this._btClosestConvexResultCallback; + var convexPosFrom = PhysicsSimulation._btTempVector30; + var convexPosTo = PhysicsSimulation._btTempVector31; + var convexRotFrom = PhysicsSimulation._btTempQuaternion0; + var convexRotTo = PhysicsSimulation._btTempQuaternion1; + var convexTransform = PhysicsSimulation._btTempTransform0; + var convexTransTo = PhysicsSimulation._btTempTransform1; + var sweepShape = shape._btShape; + bt.btVector3_setValue(convexPosFrom, -fromPosition.x, fromPosition.y, fromPosition.z); + bt.btVector3_setValue(convexPosTo, -toPosition.x, toPosition.y, toPosition.z); + bt.ConvexResultCallback_set_m_collisionFilterGroup(convexResultCall, collisonGroup); + bt.ConvexResultCallback_set_m_collisionFilterMask(convexResultCall, collisionMask); + bt.btTransform_setOrigin(convexTransform, convexPosFrom); + bt.btTransform_setOrigin(convexTransTo, convexPosTo); + if (fromRotation) { + bt.btQuaternion_setValue(convexRotFrom, -fromRotation.x, fromRotation.y, fromRotation.z, -fromRotation.w); + bt.btTransform_setRotation(convexTransform, convexRotFrom); + } + else { + bt.btTransform_setRotation(convexTransform, this._btDefaultQuaternion); + } + if (toRotation) { + bt.btQuaternion_setValue(convexRotTo, -toRotation.x, toRotation.y, toRotation.z, -toRotation.w); + bt.btTransform_setRotation(convexTransTo, convexRotTo); + } + else { + bt.btTransform_setRotation(convexTransTo, this._btDefaultQuaternion); + } + bt.ClosestConvexResultCallback_set_m_hitCollisionObject(convexResultCall, null); + bt.ConvexResultCallback_set_m_closestHitFraction(convexResultCall, 1); + bt.btCollisionWorld_convexSweepTest(this._btCollisionWorld, sweepShape, convexTransform, convexTransTo, convexResultCall, allowedCcdPenetration); + if (bt.ConvexResultCallback_hasHit(convexResultCall)) { + if (out) { + out.succeeded = true; + out.collider = PhysicsComponent._physicObjectsMap[bt.btCollisionObject_getUserIndex(bt.ClosestConvexResultCallback_get_m_hitCollisionObject(convexResultCall))]; + out.hitFraction = bt.ConvexResultCallback_get_m_closestHitFraction(convexResultCall); + var btPoint = bt.ClosestConvexResultCallback_get_m_hitPointWorld(convexResultCall); + var btNormal = bt.ClosestConvexResultCallback_get_m_hitNormalWorld(convexResultCall); + var point = out.point; + var normal = out.normal; + point.x = -bt.btVector3_x(btPoint); + point.y = bt.btVector3_y(btPoint); + point.z = bt.btVector3_z(btPoint); + normal.x = -bt.btVector3_x(btNormal); + normal.y = bt.btVector3_y(btNormal); + normal.z = bt.btVector3_z(btNormal); + } + return true; + } + else { + if (out) + out.succeeded = false; + return false; + } + } + shapeCastAll(shape, fromPosition, toPosition, out, fromRotation = null, toRotation = null, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, allowedCcdPenetration = 0.0) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var convexResultCall = this._btAllConvexResultCallback; + var convexPosFrom = PhysicsSimulation._btTempVector30; + var convexPosTo = PhysicsSimulation._btTempVector31; + var convexRotFrom = PhysicsSimulation._btTempQuaternion0; + var convexRotTo = PhysicsSimulation._btTempQuaternion1; + var convexTransform = PhysicsSimulation._btTempTransform0; + var convexTransTo = PhysicsSimulation._btTempTransform1; + var sweepShape = shape._btShape; + out.length = 0; + bt.btVector3_setValue(convexPosFrom, -fromPosition.x, fromPosition.y, fromPosition.z); + bt.btVector3_setValue(convexPosTo, -toPosition.x, toPosition.y, toPosition.z); + bt.ConvexResultCallback_set_m_collisionFilterGroup(convexResultCall, collisonGroup); + bt.ConvexResultCallback_set_m_collisionFilterMask(convexResultCall, collisionMask); + bt.btTransform_setOrigin(convexTransform, convexPosFrom); + bt.btTransform_setOrigin(convexTransTo, convexPosTo); + if (fromRotation) { + bt.btQuaternion_setValue(convexRotFrom, -fromRotation.x, fromRotation.y, fromRotation.z, -fromRotation.w); + bt.btTransform_setRotation(convexTransform, convexRotFrom); + } + else { + bt.btTransform_setRotation(convexTransform, this._btDefaultQuaternion); + } + if (toRotation) { + bt.btQuaternion_setValue(convexRotTo, -toRotation.x, toRotation.y, toRotation.z, -toRotation.w); + bt.btTransform_setRotation(convexTransTo, convexRotTo); + } + else { + bt.btTransform_setRotation(convexTransTo, this._btDefaultQuaternion); + } + var collisionObjects = bt.AllConvexResultCallback_get_m_collisionObjects(convexResultCall); + var btPoints = bt.AllConvexResultCallback_get_m_hitPointWorld(convexResultCall); + var btNormals = bt.AllConvexResultCallback_get_m_hitNormalWorld(convexResultCall); + var btFractions = bt.AllConvexResultCallback_get_m_hitFractions(convexResultCall); + bt.tVector3Array_clear(btPoints); + bt.tVector3Array_clear(btNormals); + bt.tScalarArray_clear(btFractions); + bt.tBtCollisionObjectArray_clear(collisionObjects); + bt.btCollisionWorld_convexSweepTest(this._btCollisionWorld, sweepShape, convexTransform, convexTransTo, convexResultCall, allowedCcdPenetration); + var count = bt.tBtCollisionObjectArray_size(collisionObjects); + if (count > 0) { + this._collisionsUtils.recoverAllHitResultsPool(); + for (var i = 0; i < count; i++) { + var hitResult = this._collisionsUtils.getHitResult(); + out.push(hitResult); + hitResult.succeeded = true; + hitResult.collider = PhysicsComponent._physicObjectsMap[bt.btCollisionObject_getUserIndex(bt.tBtCollisionObjectArray_at(collisionObjects, i))]; + hitResult.hitFraction = bt.tScalarArray_at(btFractions, i); + var btPoint = bt.tVector3Array_at(btPoints, i); + var point = hitResult.point; + point.x = -bt.btVector3_x(btPoint); + point.y = bt.btVector3_y(btPoint); + point.z = bt.btVector3_z(btPoint); + var btNormal = bt.tVector3Array_at(btNormals, i); + var normal = hitResult.normal; + normal.x = -bt.btVector3_x(btNormal); + normal.y = bt.btVector3_y(btNormal); + normal.z = bt.btVector3_z(btNormal); + } + return true; + } + else { + return false; + } + } + addConstraint(constraint, disableCollisionsBetweenLinkedBodies = false) { + if (!this._btDiscreteDynamicsWorld) + throw "Cannot perform this action when the physics engine is set to CollisionsOnly"; + Laya.ILaya3D.Physics3D._bullet.btCollisionWorld_addConstraint(this._btDiscreteDynamicsWorld, constraint._btConstraint, disableCollisionsBetweenLinkedBodies); + this._currentConstraint[constraint.id] = constraint; + } + removeConstraint(constraint) { + if (!this._btDiscreteDynamicsWorld) + throw "Cannot perform this action when the physics engine is set to CollisionsOnly"; + Laya.ILaya3D.Physics3D._bullet.btCollisionWorld_removeConstraint(this._btDiscreteDynamicsWorld, constraint._btConstraint); + delete this._currentConstraint[constraint.id]; + } + setHitsRayResultCallbackFlag(flag = 1) { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.RayResultCallback_set_m_flags(this._btAllHitsRayResultCallback, flag); + bt.RayResultCallback_set_m_flags(this._btClosestRayResultCallback, flag); + } + _updatePhysicsTransformFromRender() { + var elements = this._physicsUpdateList.elements; + for (var i = 0, n = this._physicsUpdateList.length; i < n; i++) { + var physicCollider = elements[i]; + physicCollider._derivePhysicsTransformation(false); + physicCollider._inPhysicUpdateListIndex = -1; + } + this._physicsUpdateList.length = 0; + } + _updateCharacters() { + for (var i = 0, n = this._characters.length; i < n; i++) { + var character = this._characters[i]; + character._updateTransformComponent(Laya.ILaya3D.Physics3D._bullet.btCollisionObject_getWorldTransform(character._btColliderObject)); + } + } + _updateCollisions() { + this._collisionsUtils.recoverAllContactPointsPool(); + var previous = this._currentFrameCollisions; + this._currentFrameCollisions = this._previousFrameCollisions; + this._currentFrameCollisions.length = 0; + this._previousFrameCollisions = previous; + var loopCount = Laya.Stat.loopCount; + var bt = Laya.ILaya3D.Physics3D._bullet; + var numManifolds = bt.btDispatcher_getNumManifolds(this._btDispatcher); + for (var i = 0; i < numManifolds; i++) { + var contactManifold = bt.btDispatcher_getManifoldByIndexInternal(this._btDispatcher, i); + var componentA = PhysicsComponent._physicObjectsMap[bt.btCollisionObject_getUserIndex(bt.btPersistentManifold_getBody0(contactManifold))]; + var componentB = PhysicsComponent._physicObjectsMap[bt.btCollisionObject_getUserIndex(bt.btPersistentManifold_getBody1(contactManifold))]; + var collision = null; + var isFirstCollision; + var contacts = null; + var isTrigger = componentA.isTrigger || componentB.isTrigger; + if (isTrigger && (componentA.owner._needProcessTriggers || componentB.owner._needProcessTriggers)) { + var numContacts = bt.btPersistentManifold_getNumContacts(contactManifold); + for (var j = 0; j < numContacts; j++) { + var pt = bt.btPersistentManifold_getContactPoint(contactManifold, j); + var distance = bt.btManifoldPoint_getDistance(pt); + if (distance <= 0) { + collision = this._collisionsUtils.getCollision(componentA, componentB); + contacts = collision.contacts; + isFirstCollision = collision._updateFrame !== loopCount; + if (isFirstCollision) { + collision._isTrigger = true; + contacts.length = 0; + } + break; + } + } + } + else if (componentA.owner._needProcessCollisions || componentB.owner._needProcessCollisions) { + if (componentA._enableProcessCollisions || componentB._enableProcessCollisions) { + numContacts = bt.btPersistentManifold_getNumContacts(contactManifold); + for (j = 0; j < numContacts; j++) { + pt = bt.btPersistentManifold_getContactPoint(contactManifold, j); + distance = bt.btManifoldPoint_getDistance(pt); + if (distance <= 0) { + var contactPoint = this._collisionsUtils.getContactPoints(); + contactPoint.colliderA = componentA; + contactPoint.colliderB = componentB; + contactPoint.distance = distance; + var btNormal = bt.btManifoldPoint_get_m_normalWorldOnB(pt); + var normal = contactPoint.normal; + normal.x = -bt.btVector3_x(btNormal); + normal.y = bt.btVector3_y(btNormal); + normal.z = bt.btVector3_z(btNormal); + var btPostionA = bt.btManifoldPoint_get_m_positionWorldOnA(pt); + var positionOnA = contactPoint.positionOnA; + positionOnA.x = -bt.btVector3_x(btPostionA); + positionOnA.y = bt.btVector3_y(btPostionA); + positionOnA.z = bt.btVector3_z(btPostionA); + var btPostionB = bt.btManifoldPoint_get_m_positionWorldOnB(pt); + var positionOnB = contactPoint.positionOnB; + positionOnB.x = -bt.btVector3_x(btPostionB); + positionOnB.y = bt.btVector3_y(btPostionB); + positionOnB.z = bt.btVector3_z(btPostionB); + if (!collision) { + collision = this._collisionsUtils.getCollision(componentA, componentB); + contacts = collision.contacts; + isFirstCollision = collision._updateFrame !== loopCount; + if (isFirstCollision) { + collision._isTrigger = false; + contacts.length = 0; + } + } + contacts.push(contactPoint); + } + } + } + } + if (collision && isFirstCollision) { + this._currentFrameCollisions.push(collision); + collision._setUpdateFrame(loopCount); + } + } + } + _eventScripts() { + var loopCount = Laya.Stat.loopCount; + for (var i = 0, n = this._currentFrameCollisions.length; i < n; i++) { + var curFrameCol = this._currentFrameCollisions[i]; + var colliderA = curFrameCol._colliderA; + var colliderB = curFrameCol._colliderB; + if (colliderA.destroyed || colliderB.destroyed) + continue; + if (loopCount - curFrameCol._lastUpdateFrame === 1) { + var ownerA = colliderA.owner; + var scriptsA = ownerA._scripts; + if (scriptsA) { + if (curFrameCol._isTrigger) { + if (ownerA._needProcessTriggers) { + for (var j = 0, m = scriptsA.length; j < m; j++) + scriptsA[j].onTriggerStay(colliderB); + } + } + else { + if (ownerA._needProcessCollisions) { + for (j = 0, m = scriptsA.length; j < m; j++) { + curFrameCol.other = colliderB; + scriptsA[j].onCollisionStay(curFrameCol); + } + } + } + } + var ownerB = colliderB.owner; + var scriptsB = ownerB._scripts; + if (scriptsB) { + if (curFrameCol._isTrigger) { + if (ownerB._needProcessTriggers) { + for (j = 0, m = scriptsB.length; j < m; j++) + scriptsB[j].onTriggerStay(colliderA); + } + } + else { + if (ownerB._needProcessCollisions) { + for (j = 0, m = scriptsB.length; j < m; j++) { + curFrameCol.other = colliderA; + scriptsB[j].onCollisionStay(curFrameCol); + } + } + } + } + } + else { + ownerA = colliderA.owner; + scriptsA = ownerA._scripts; + if (scriptsA) { + if (curFrameCol._isTrigger) { + if (ownerA._needProcessTriggers) { + for (j = 0, m = scriptsA.length; j < m; j++) + scriptsA[j].onTriggerEnter(colliderB); + } + } + else { + if (ownerA._needProcessCollisions) { + for (j = 0, m = scriptsA.length; j < m; j++) { + curFrameCol.other = colliderB; + scriptsA[j].onCollisionEnter(curFrameCol); + } + } + } + } + ownerB = colliderB.owner; + scriptsB = ownerB._scripts; + if (scriptsB) { + if (curFrameCol._isTrigger) { + if (ownerB._needProcessTriggers) { + for (j = 0, m = scriptsB.length; j < m; j++) + scriptsB[j].onTriggerEnter(colliderA); + } + } + else { + if (ownerB._needProcessCollisions) { + for (j = 0, m = scriptsB.length; j < m; j++) { + curFrameCol.other = colliderA; + scriptsB[j].onCollisionEnter(curFrameCol); + } + } + } + } + } + } + for (i = 0, n = this._previousFrameCollisions.length; i < n; i++) { + var preFrameCol = this._previousFrameCollisions[i]; + var preColliderA = preFrameCol._colliderA; + var preColliderB = preFrameCol._colliderB; + if (preColliderA.destroyed || preColliderB.destroyed) + continue; + if (loopCount - preFrameCol._updateFrame === 1) { + this._collisionsUtils.recoverCollision(preFrameCol); + ownerA = preColliderA.owner; + scriptsA = ownerA._scripts; + if (scriptsA) { + if (preFrameCol._isTrigger) { + if (ownerA._needProcessTriggers) { + for (j = 0, m = scriptsA.length; j < m; j++) + scriptsA[j].onTriggerExit(preColliderB); + } + } + else { + if (ownerA._needProcessCollisions) { + for (j = 0, m = scriptsA.length; j < m; j++) { + preFrameCol.other = preColliderB; + scriptsA[j].onCollisionExit(preFrameCol); + } + } + } + } + ownerB = preColliderB.owner; + scriptsB = ownerB._scripts; + if (scriptsB) { + if (preFrameCol._isTrigger) { + if (ownerB._needProcessTriggers) { + for (j = 0, m = scriptsB.length; j < m; j++) + scriptsB[j].onTriggerExit(preColliderA); + } + } + else { + if (ownerB._needProcessCollisions) { + for (j = 0, m = scriptsB.length; j < m; j++) { + preFrameCol.other = preColliderA; + scriptsB[j].onCollisionExit(preFrameCol); + } + } + } + } + } + } + for (var id in this._currentConstraint) { + var constraintObj = this._currentConstraint[id]; + var scripts = constraintObj.owner._scripts; + if (constraintObj.enabled && constraintObj._isBreakConstrained() && (!!scripts)) { + if (scripts.length != 0) { + for (i = 0, n = scripts.length; i < n; i++) { + scripts[i].onJointBreak(); + } + } + } + } + } + clearForces() { + if (!this._btDiscreteDynamicsWorld) + throw "Cannot perform this action when the physics engine is set to CollisionsOnly"; + Laya.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_clearForces(this._btDiscreteDynamicsWorld); + } + } + PhysicsSimulation.PHYSICSENGINEFLAGS_NONE = 0x0; + PhysicsSimulation.PHYSICSENGINEFLAGS_COLLISIONSONLY = 0x1; + PhysicsSimulation.PHYSICSENGINEFLAGS_SOFTBODYSUPPORT = 0x2; + PhysicsSimulation.PHYSICSENGINEFLAGS_MULTITHREADED = 0x4; + PhysicsSimulation.PHYSICSENGINEFLAGS_USEHARDWAREWHENPOSSIBLE = 0x8; + PhysicsSimulation.SOLVERMODE_RANDMIZE_ORDER = 1; + PhysicsSimulation.SOLVERMODE_FRICTION_SEPARATE = 2; + PhysicsSimulation.SOLVERMODE_USE_WARMSTARTING = 4; + PhysicsSimulation.SOLVERMODE_USE_2_FRICTION_DIRECTIONS = 16; + PhysicsSimulation.SOLVERMODE_ENABLE_FRICTION_DIRECTION_CACHING = 32; + PhysicsSimulation.SOLVERMODE_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION = 64; + PhysicsSimulation.SOLVERMODE_CACHE_FRIENDLY = 128; + PhysicsSimulation.SOLVERMODE_SIMD = 256; + PhysicsSimulation.SOLVERMODE_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS = 512; + PhysicsSimulation.SOLVERMODE_ALLOW_ZERO_LENGTH_FRICTION_DIRECTIONS = 1024; + PhysicsSimulation.HITSRAYRESULTCALLBACK_FLAG_NONE = 0; + PhysicsSimulation.HITSRAYRESULTCALLBACK_FLAG_FILTERBACKFACESS = 1; + PhysicsSimulation.HITSRAYRESULTCALLBACK_FLAG_KEEPUNFILIPPEDNORMAL = 2; + PhysicsSimulation.HITSRAYRESULTCALLBACK_FLAG_USESUBSIMPLEXCONVEXCASTRAYTEST = 4; + PhysicsSimulation.HITSRAYRESULTCALLBACK_FLAG_USEGJKCONVEXCASTRAYTEST = 8; + PhysicsSimulation.HITSRAYRESULTCALLBACK_FLAG_TERMINATOR = 0xffffffff; + PhysicsSimulation._tempVector30 = new Laya.Vector3(); + PhysicsSimulation.disableSimulation = false; + + class Rigidbody3D extends PhysicsTriggerComponent { + constructor(collisionGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER, canCollideWith = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + super(collisionGroup, canCollideWith); + this._isKinematic = false; + this._mass = 1.0; + this._gravity = new Laya.Vector3(0, -10, 0); + this._angularDamping = 0.0; + this._linearDamping = 0.0; + this._overrideGravity = false; + this._totalTorque = new Laya.Vector3(0, 0, 0); + this._totalForce = new Laya.Vector3(0, 0, 0); + this._linearVelocity = new Laya.Vector3(); + this._angularVelocity = new Laya.Vector3(); + this._linearFactor = new Laya.Vector3(1, 1, 1); + this._angularFactor = new Laya.Vector3(1, 1, 1); + this._detectCollisions = true; + this._controlBySimulation = true; + } + static __init__() { + var bt = Laya.ILaya3D.Physics3D._bullet; + Rigidbody3D._btTempVector30 = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btTempVector31 = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btVector3Zero = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btInertia = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btImpulse = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btImpulseOffset = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btGravity = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btTransform0 = bt.btTransform_create(); + } + get mass() { + return this._mass; + } + set mass(value) { + value = Math.max(value, 1e-07); + this._mass = value; + (this._isKinematic) || (this._updateMass(value)); + } + get isKinematic() { + return this._isKinematic; + } + set isKinematic(value) { + this._isKinematic = value; + this._controlBySimulation = !value; + var bt = Laya.ILaya3D.Physics3D._bullet; + var canInSimulation = !!(this._simulation && this._enabled && this._colliderShape); + canInSimulation && this._removeFromSimulation(); + var natColObj = this._btColliderObject; + var flags = bt.btCollisionObject_getCollisionFlags(natColObj); + if (value) { + flags = flags | PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT; + bt.btCollisionObject_setCollisionFlags(natColObj, flags); + bt.btCollisionObject_forceActivationState(this._btColliderObject, PhysicsComponent.ACTIVATIONSTATE_DISABLE_DEACTIVATION); + this._enableProcessCollisions = false; + this._updateMass(0); + } + else { + if ((flags & PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT) > 0) + flags = flags ^ PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT; + bt.btCollisionObject_setCollisionFlags(natColObj, flags); + bt.btCollisionObject_setActivationState(this._btColliderObject, PhysicsComponent.ACTIVATIONSTATE_ACTIVE_TAG); + this._enableProcessCollisions = true; + this._updateMass(this._mass); + } + var btZero = Rigidbody3D._btVector3Zero; + bt.btCollisionObject_setInterpolationLinearVelocity(natColObj, btZero); + bt.btRigidBody_setLinearVelocity(natColObj, btZero); + bt.btCollisionObject_setInterpolationAngularVelocity(natColObj, btZero); + bt.btRigidBody_setAngularVelocity(natColObj, btZero); + canInSimulation && this._addToSimulation(); + } + get linearDamping() { + return this._linearDamping; + } + set linearDamping(value) { + this._linearDamping = value; + if (this._btColliderObject) + Laya.ILaya3D.Physics3D._bullet.btRigidBody_setDamping(this._btColliderObject, value, this._angularDamping); + } + get angularDamping() { + return this._angularDamping; + } + set angularDamping(value) { + this._angularDamping = value; + if (this._btColliderObject) + Laya.ILaya3D.Physics3D._bullet.btRigidBody_setDamping(this._btColliderObject, this._linearDamping, value); + } + get overrideGravity() { + return this._overrideGravity; + } + set overrideGravity(value) { + this._overrideGravity = value; + var bt = Laya.ILaya3D.Physics3D._bullet; + if (this._btColliderObject) { + var flag = bt.btRigidBody_getFlags(this._btColliderObject); + if (value) { + if ((flag & Rigidbody3D._BT_DISABLE_WORLD_GRAVITY) === 0) + bt.btRigidBody_setFlags(this._btColliderObject, flag | Rigidbody3D._BT_DISABLE_WORLD_GRAVITY); + } + else { + if ((flag & Rigidbody3D._BT_DISABLE_WORLD_GRAVITY) > 0) + bt.btRigidBody_setFlags(this._btColliderObject, flag ^ Rigidbody3D._BT_DISABLE_WORLD_GRAVITY); + } + } + } + get gravity() { + var bt = Laya.ILaya3D.Physics3D._bullet; + Rigidbody3D._btGravity = bt.btRigidBody_getGravity(this._btColliderObject); + Laya.Utils3D._convertToLayaVec3(Rigidbody3D._btGravity, this._gravity, true); + return this._gravity; + } + set gravity(value) { + this._gravity = value; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(Rigidbody3D._btGravity, -value.x, value.y, value.z); + bt.btRigidBody_setGravity(this._btColliderObject, Rigidbody3D._btGravity); + } + get totalForce() { + if (this._btColliderObject) { + var btTotalForce = Laya.ILaya3D.Physics3D._bullet.btRigidBody_getTotalForce(this._btColliderObject); + Laya.Utils3D._convertToLayaVec3(btTotalForce, this._totalForce, true); + return this._totalForce; + } + return null; + } + get linearFactor() { + return this._linearFactor; + } + set linearFactor(value) { + this._linearFactor = value; + var btValue = Rigidbody3D._btTempVector30; + Laya.Utils3D._convertToBulletVec3(value, btValue, false); + Laya.ILaya3D.Physics3D._bullet.btRigidBody_setLinearFactor(this._btColliderObject, btValue); + } + get linearVelocity() { + if (this._btColliderObject) + Laya.Utils3D._convertToLayaVec3(Laya.ILaya3D.Physics3D._bullet.btRigidBody_getLinearVelocity(this._btColliderObject), this._linearVelocity, true); + return this._linearVelocity; + } + set linearVelocity(value) { + this._linearVelocity = value; + if (this._btColliderObject) { + var btValue = Rigidbody3D._btTempVector30; + Laya.Utils3D._convertToBulletVec3(value, btValue, true); + (this.isSleeping) && (this.wakeUp()); + Laya.ILaya3D.Physics3D._bullet.btRigidBody_setLinearVelocity(this._btColliderObject, btValue); + } + } + get angularFactor() { + return this._angularFactor; + } + set angularFactor(value) { + this._angularFactor = value; + var btValue = Rigidbody3D._btTempVector30; + Laya.Utils3D._convertToBulletVec3(value, btValue, false); + Laya.ILaya3D.Physics3D._bullet.btRigidBody_setAngularFactor(this._btColliderObject, btValue); + } + get angularVelocity() { + if (this._btColliderObject) + Laya.Utils3D._convertToLayaVec3(Laya.ILaya3D.Physics3D._bullet.btRigidBody_getAngularVelocity(this._btColliderObject), this._angularVelocity, true); + return this._angularVelocity; + } + set angularVelocity(value) { + this._angularVelocity = value; + if (this._btColliderObject) { + var btValue = Rigidbody3D._btTempVector30; + Laya.Utils3D._convertToBulletVec3(value, btValue, true); + (this.isSleeping) && (this.wakeUp()); + Laya.ILaya3D.Physics3D._bullet.btRigidBody_setAngularVelocity(this._btColliderObject, btValue); + } + } + get totalTorque() { + if (this._btColliderObject) { + var btTotalTorque = Laya.ILaya3D.Physics3D._bullet.btRigidBody_getTotalTorque(this._btColliderObject); + Laya.Utils3D._convertToLayaVec3(btTotalTorque, this._totalTorque, true); + return this._totalTorque; + } + return null; + } + get detectCollisions() { + return this._detectCollisions; + } + set detectCollisions(value) { + if (this._detectCollisions !== value) { + this._detectCollisions = value; + if (this._colliderShape && this._enabled && this._simulation) { + this._simulation._removeRigidBody(this); + this._simulation._addRigidBody(this, this._collisionGroup, value ? this._canCollideWith : 0); + } + } + } + get isSleeping() { + if (this._btColliderObject) + return Laya.ILaya3D.Physics3D._bullet.btCollisionObject_getActivationState(this._btColliderObject) === PhysicsComponent.ACTIVATIONSTATE_ISLAND_SLEEPING; + return false; + } + get sleepLinearVelocity() { + return Laya.ILaya3D.Physics3D._bullet.btRigidBody_getLinearSleepingThreshold(this._btColliderObject); + } + set sleepLinearVelocity(value) { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btRigidBody_setSleepingThresholds(this._btColliderObject, value, bt.btRigidBody_getAngularSleepingThreshold(this._btColliderObject)); + } + get sleepAngularVelocity() { + return Laya.ILaya3D.Physics3D._bullet.btRigidBody_getAngularSleepingThreshold(this._btColliderObject); + } + set sleepAngularVelocity(value) { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btRigidBody_setSleepingThresholds(this._btColliderObject, bt.btRigidBody_getLinearSleepingThreshold(this._btColliderObject), value); + } + get btColliderObject() { + return this._btColliderObject; + } + set constaintRigidbodyA(value) { + this._constaintRigidbodyA = value; + } + get constaintRigidbodyA() { + return this._constaintRigidbodyA; + } + set constaintRigidbodyB(value) { + this._constaintRigidbodyB = value; + } + get constaintRigidbodyB() { + return this._constaintRigidbodyB; + } + _updateMass(mass) { + if (this._btColliderObject && this._colliderShape) { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btCollisionShape_calculateLocalInertia(this._colliderShape._btShape, mass, Rigidbody3D._btInertia); + bt.btRigidBody_setMassProps(this._btColliderObject, mass, Rigidbody3D._btInertia); + bt.btRigidBody_updateInertiaTensor(this._btColliderObject); + } + } + _onScaleChange(scale) { + super._onScaleChange(scale); + this._updateMass(this._isKinematic ? 0 : this._mass); + } + _derivePhysicsTransformation(force) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var btColliderObject = this._btColliderObject; + var oriTransform = bt.btCollisionObject_getWorldTransform(btColliderObject); + var transform = Rigidbody3D._btTransform0; + bt.btTransform_equal(transform, oriTransform); + this._innerDerivePhysicsTransformation(transform, force); + bt.btRigidBody_setCenterOfMassTransform(btColliderObject, transform); + } + _onAdded() { + var bt = Laya.ILaya3D.Physics3D._bullet; + var motionState = bt.layaMotionState_create(); + bt.layaMotionState_set_rigidBodyID(motionState, this._id); + this._btLayaMotionState = motionState; + var constructInfo = bt.btRigidBodyConstructionInfo_create(0.0, motionState, null, Rigidbody3D._btVector3Zero); + var btRigid = bt.btRigidBody_create(constructInfo); + bt.btCollisionObject_setUserIndex(btRigid, this.id); + this._btColliderObject = btRigid; + super._onAdded(); + this.mass = this._mass; + this.linearFactor = this._linearFactor; + this.angularFactor = this._angularFactor; + this.linearDamping = this._linearDamping; + this.angularDamping = this._angularDamping; + this.overrideGravity = this._overrideGravity; + this.gravity = this._gravity; + this.isKinematic = this._isKinematic; + bt.btRigidBodyConstructionInfo_destroy(constructInfo); + } + _onEnable() { + super._onEnable(); + if (this._constaintRigidbodyA) { + if (this._constaintRigidbodyA.connectedBody._simulation) { + this._constaintRigidbodyA._createConstraint(); + this._constaintRigidbodyA._onEnable(); + } + } + if (this._constaintRigidbodyB) { + if (this._constaintRigidbodyB.ownBody._simulation) { + this._constaintRigidbodyB._createConstraint(); + this._constaintRigidbodyB._onEnable(); + } + } + } + _onShapeChange(colShape) { + super._onShapeChange(colShape); + if (this._isKinematic) { + this._updateMass(0); + } + else { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btRigidBody_setCenterOfMassTransform(this._btColliderObject, bt.btCollisionObject_getWorldTransform(this._btColliderObject)); + this._updateMass(this._mass); + } + } + _parse(data) { + (data.friction != null) && (this.friction = data.friction); + (data.rollingFriction != null) && (this.rollingFriction = data.rollingFriction); + (data.restitution != null) && (this.restitution = data.restitution); + (data.isTrigger != null) && (this.isTrigger = data.isTrigger); + (data.mass != null) && (this.mass = data.mass); + (data.linearDamping != null) && (this.linearDamping = data.linearDamping); + (data.angularDamping != null) && (this.angularDamping = data.angularDamping); + (data.overrideGravity != null) && (this.overrideGravity = data.overrideGravity); + if (data.linearFactor != null) { + var linFac = this.linearFactor; + linFac.fromArray(data.linearFactor); + this.linearFactor = linFac; + } + if (data.angularFactor != null) { + var angFac = this.angularFactor; + angFac.fromArray(data.angularFactor); + this.angularFactor = angFac; + } + if (data.gravity) { + this.gravity.fromArray(data.gravity); + this.gravity = this.gravity; + } + super._parse(data); + this._parseShape(data.shapes); + (data.isKinematic != null) && (this.isKinematic = data.isKinematic); + } + _onDestroy() { + Laya.ILaya3D.Physics3D._bullet.btMotionState_destroy(this._btLayaMotionState); + super._onDestroy(); + this._btLayaMotionState = null; + this._gravity = null; + this._totalTorque = null; + this._linearVelocity = null; + this._angularVelocity = null; + this._linearFactor = null; + this._angularFactor = null; + if (this.constaintRigidbodyA) + this.constaintRigidbodyA._breakConstrained(); + if (this.constaintRigidbodyB) { + this.constaintRigidbodyB.connectedBody = null; + this.constaintRigidbodyB._onDisable(); + } + } + _addToSimulation() { + this._simulation._addRigidBody(this, this._collisionGroup, this._detectCollisions ? this._canCollideWith : 0); + } + _removeFromSimulation() { + this._simulation._removeRigidBody(this); + } + _cloneTo(dest) { + super._cloneTo(dest); + var destRigidbody3D = dest; + destRigidbody3D.isKinematic = this._isKinematic; + destRigidbody3D.mass = this._mass; + destRigidbody3D.gravity = this._gravity; + destRigidbody3D.angularDamping = this._angularDamping; + destRigidbody3D.linearDamping = this._linearDamping; + destRigidbody3D.overrideGravity = this._overrideGravity; + destRigidbody3D.linearVelocity = this._linearVelocity; + destRigidbody3D.angularVelocity = this._angularVelocity; + destRigidbody3D.linearFactor = this._linearFactor; + destRigidbody3D.angularFactor = this._angularFactor; + destRigidbody3D.detectCollisions = this._detectCollisions; + } + applyForce(force, localOffset = null) { + if (this._btColliderObject == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + var bt = Laya.ILaya3D.Physics3D._bullet; + var btForce = Rigidbody3D._btTempVector30; + bt.btVector3_setValue(btForce, -force.x, force.y, force.z); + if (localOffset) { + var btOffset = Rigidbody3D._btTempVector31; + bt.btVector3_setValue(btOffset, -localOffset.x, localOffset.y, localOffset.z); + bt.btRigidBody_applyForce(this._btColliderObject, btForce, btOffset); + } + else { + bt.btRigidBody_applyCentralForce(this._btColliderObject, btForce); + } + } + applyTorque(torque) { + if (this._btColliderObject == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + var bullet = Laya.ILaya3D.Physics3D._bullet; + var btTorque = Rigidbody3D._btTempVector30; + bullet.btVector3_setValue(btTorque, -torque.x, torque.y, torque.z); + bullet.btRigidBody_applyTorque(this._btColliderObject, btTorque); + } + applyImpulse(impulse, localOffset = null) { + if (this._btColliderObject == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(Rigidbody3D._btImpulse, -impulse.x, impulse.y, impulse.z); + if (localOffset) { + bt.btVector3_setValue(Rigidbody3D._btImpulseOffset, -localOffset.x, localOffset.y, localOffset.z); + bt.btRigidBody_applyImpulse(this._btColliderObject, Rigidbody3D._btImpulse, Rigidbody3D._btImpulseOffset); + } + else { + bt.btRigidBody_applyCentralImpulse(this._btColliderObject, Rigidbody3D._btImpulse); + } + } + applyTorqueImpulse(torqueImpulse) { + if (this._btColliderObject == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + var bt = Laya.ILaya3D.Physics3D._bullet; + var btTorqueImpulse = Rigidbody3D._btTempVector30; + bt.btVector3_setValue(btTorqueImpulse, -torqueImpulse.x, torqueImpulse.y, torqueImpulse.z); + bt.btRigidBody_applyTorqueImpulse(this._btColliderObject, btTorqueImpulse); + } + wakeUp() { + this._btColliderObject && (Laya.ILaya3D.Physics3D._bullet.btCollisionObject_activate(this._btColliderObject, false)); + } + clearForces() { + var rigidBody = this._btColliderObject; + if (rigidBody == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btRigidBody_clearForces(rigidBody); + var btZero = Rigidbody3D._btVector3Zero; + bt.btCollisionObject_setInterpolationLinearVelocity(rigidBody, btZero); + bt.btRigidBody_setLinearVelocity(rigidBody, btZero); + bt.btCollisionObject_setInterpolationAngularVelocity(rigidBody, btZero); + bt.btRigidBody_setAngularVelocity(rigidBody, btZero); + } + } + Rigidbody3D.TYPE_STATIC = 0; + Rigidbody3D.TYPE_DYNAMIC = 1; + Rigidbody3D.TYPE_KINEMATIC = 2; + Rigidbody3D._BT_DISABLE_WORLD_GRAVITY = 1; + Rigidbody3D._BT_ENABLE_GYROPSCOPIC_FORCE = 2; + + class ConstraintComponent extends Laya.Component { + constructor(constraintType) { + super(); + this._anchor = new Laya.Vector3(); + this._connectAnchor = new Laya.Vector3(); + this._feedbackEnabled = false; + this._getJointFeedBack = false; + this._currentForce = new Laya.Vector3(); + this._currentTorque = new Laya.Vector3(); + this._constraintType = constraintType; + var bt = Laya.Physics3D._bullet; + this._btframATrans = bt.btTransform_create(); + this._btframBTrans = bt.btTransform_create(); + bt.btTransform_setIdentity(this._btframATrans); + bt.btTransform_setIdentity(this._btframBTrans); + this._btframAPos = bt.btVector3_create(0, 0, 0); + this._btframBPos = bt.btVector3_create(0, 0, 0); + bt.btTransform_setOrigin(this._btframATrans, this._btframAPos); + bt.btTransform_setOrigin(this._btframBTrans, this._btframBPos); + this._breakForce = -1; + this._breakTorque = -1; + } + get enabled() { + return super.enabled; + } + set enabled(value) { + super.enabled = value; + } + get appliedImpulse() { + if (!this._feedbackEnabled) { + this._btConstraint.EnableFeedback(true); + this._feedbackEnabled = true; + } + return this._btConstraint.AppliedImpulse; + } + set connectedBody(value) { + this._connectedBody = value; + value && (value.constaintRigidbodyB = this); + } + get connectedBody() { + return this._connectedBody; + } + get ownBody() { + return this._ownBody; + } + set ownBody(value) { + this._ownBody = value; + value.constaintRigidbodyA = this; + } + get currentForce() { + if (!this._getJointFeedBack) + this._getFeedBackInfo(); + return this._currentForce; + } + get currentTorque() { + if (!this._getJointFeedBack) + this._getFeedBackInfo(); + return this._currentTorque; + } + get breakForce() { + return this._breakForce; + } + set breakForce(value) { + this._breakForce = value; + } + get breakTorque() { + return this._breakTorque; + } + set breakTorque(value) { + this._breakTorque = value; + } + set anchor(value) { + value.cloneTo(this._anchor); + this.setFrames(); + } + get anchor() { + return this._anchor; + } + set connectAnchor(value) { + value.cloneTo(this._connectAnchor); + this.setFrames(); + } + get connectAnchor() { + return this._connectAnchor; + } + setOverrideNumSolverIterations(overideNumIterations) { + var bt = Laya.Physics3D._bullet; + bt.btTypedConstraint_setOverrideNumSolverIterations(this._btConstraint, overideNumIterations); + } + setConstraintEnabled(enable) { + var bt = Laya.Physics3D._bullet; + bt.btTypedConstraint_setEnabled(this._btConstraint, enable); + } + _onEnable() { + super._onEnable(); + this.enabled = true; + } + _onDisable() { + super._onDisable(); + this.enabled = false; + } + setFrames() { + var bt = Laya.Physics3D._bullet; + bt.btVector3_setValue(this._btframAPos, -this._anchor.x, this.anchor.y, this.anchor.z); + bt.btVector3_setValue(this._btframBPos, -this._connectAnchor.x, this._connectAnchor.y, this._connectAnchor.z); + bt.btTransform_setOrigin(this._btframATrans, this._btframAPos); + bt.btTransform_setOrigin(this._btframBTrans, this._btframBPos); + } + _addToSimulation() { + } + _removeFromSimulation() { + } + _createConstraint() { + } + setConnectRigidBody(ownerRigid, connectRigidBody) { + var ownerCanInSimulation = (ownerRigid) && (!!(ownerRigid._simulation && ownerRigid._enabled && ownerRigid.colliderShape)); + var connectCanInSimulation = (connectRigidBody) && (!!(connectRigidBody._simulation && connectRigidBody._enabled && connectRigidBody.colliderShape)); + if (!(ownerCanInSimulation && connectCanInSimulation)) + throw "ownerRigid or connectRigidBody is not in Simulation"; + if (ownerRigid != this._ownBody || connectRigidBody != this._connectedBody) { + var canInSimulation = !!(this.enabled && this._simulation); + canInSimulation && this._removeFromSimulation(); + this._ownBody = ownerRigid; + this._connectedBody = connectRigidBody; + this._ownBody.constaintRigidbodyA = this; + this._connectedBody.constaintRigidbodyB = this; + this._createConstraint(); + } + } + getcurrentForce(out) { + if (!this._btJointFeedBackObj) + throw "this Constraint is not simulation"; + var bt = Laya.Physics3D._bullet; + var applyForce = bt.btJointFeedback_getAppliedForceBodyA(this._btJointFeedBackObj); + out.setValue(bt.btVector3_x(applyForce), bt.btVector3_y(applyForce), bt.btVector3_z(applyForce)); + return; + } + getcurrentTorque(out) { + if (!this._btJointFeedBackObj) + throw "this Constraint is not simulation"; + var bt = Laya.Physics3D._bullet; + var applyTorque = bt.btJointFeedback_getAppliedTorqueBodyA(this._btJointFeedBackObj); + out.setValue(bt.btVector3_x(applyTorque), bt.btVector3_y(applyTorque), bt.btVector3_z(applyTorque)); + return; + } + _onDestroy() { + var physics3D = Laya.Physics3D._bullet; + this._simulation && this._removeFromSimulation(); + if (this._btConstraint && this._btJointFeedBackObj && this._simulation) { + physics3D.btTypedConstraint_destroy(this._btConstraint); + physics3D.btJointFeedback_destroy(this._btJointFeedBackObj); + this._btJointFeedBackObj = null; + this._btConstraint = null; + } + super._onDisable(); + } + _isBreakConstrained() { + this._getJointFeedBack = false; + if (this.breakForce == -1 && this.breakTorque == -1) + return false; + this._getFeedBackInfo(); + var isBreakForce = this._breakForce != -1 && (Laya.Vector3.scalarLength(this._currentForce) > this._breakForce); + var isBreakTorque = this._breakTorque != -1 && (Laya.Vector3.scalarLength(this._currentTorque) > this._breakTorque); + if (isBreakForce || isBreakTorque) { + this._breakConstrained(); + return true; + } + return false; + } + _parse(data) { + this._anchor.fromArray(data.anchor); + this._connectAnchor.fromArray(data.connectAnchor); + this.setFrames(); + } + _getFeedBackInfo() { + var bt = Laya.Physics3D._bullet; + var applyForce = bt.btJointFeedback_getAppliedForceBodyA(this._btJointFeedBackObj); + var applyTorque = bt.btJointFeedback_getAppliedTorqueBodyA(this._btJointFeedBackObj); + this._currentTorque.setValue(bt.btVector3_x(applyTorque), bt.btVector3_y(applyTorque), bt.btVector3_z(applyTorque)); + this._currentForce.setValue(bt.btVector3_x(applyForce), bt.btVector3_y(applyForce), bt.btVector3_z(applyForce)); + this._getJointFeedBack = true; + } + _breakConstrained() { + this.ownBody.constaintRigidbodyA = null; + this.connectedBody && (this.connectedBody.constaintRigidbodyB = null); + this.destroy(); + } + } + ConstraintComponent.CONSTRAINT_POINT2POINT_CONSTRAINT_TYPE = 3; + ConstraintComponent.CONSTRAINT_HINGE_CONSTRAINT_TYPE = 4; + ConstraintComponent.CONSTRAINT_CONETWIST_CONSTRAINT_TYPE = 5; + ConstraintComponent.CONSTRAINT_D6_CONSTRAINT_TYPE = 6; + ConstraintComponent.CONSTRAINT_SLIDER_CONSTRAINT_TYPE = 7; + ConstraintComponent.CONSTRAINT_CONTACT_CONSTRAINT_TYPE = 8; + ConstraintComponent.CONSTRAINT_D6_SPRING_CONSTRAINT_TYPE = 9; + ConstraintComponent.CONSTRAINT_GEAR_CONSTRAINT_TYPE = 10; + ConstraintComponent.CONSTRAINT_FIXED_CONSTRAINT_TYPE = 11; + ConstraintComponent.CONSTRAINT_MAX_CONSTRAINT_TYPE = 12; + ConstraintComponent.CONSTRAINT_CONSTRAINT_ERP = 1; + ConstraintComponent.CONSTRAINT_CONSTRAINT_STOP_ERP = 2; + ConstraintComponent.CONSTRAINT_CONSTRAINT_CFM = 3; + ConstraintComponent.CONSTRAINT_CONSTRAINT_STOP_CFM = 4; + ConstraintComponent.tempForceV3 = new Laya.Vector3(); + + class ConfigurableConstraint extends ConstraintComponent { + constructor() { + super(ConstraintComponent.CONSTRAINT_D6_SPRING_CONSTRAINT_TYPE); + this._axis = new Laya.Vector3(); + this._secondaryAxis = new Laya.Vector3(); + this._minLinearLimit = new Laya.Vector3(); + this._maxLinearLimit = new Laya.Vector3(); + this._minAngularLimit = new Laya.Vector3(); + this._maxAngularLimit = new Laya.Vector3(); + this._linearLimitSpring = new Laya.Vector3(); + this._angularLimitSpring = new Laya.Vector3(); + this._linearBounce = new Laya.Vector3(); + this._angularBounce = new Laya.Vector3(); + this._linearDamp = new Laya.Vector3(); + this._angularDamp = new Laya.Vector3(); + this._xMotion = 0; + this._yMotion = 0; + this._zMotion = 0; + this._angularXMotion = 0; + this._angularYMotion = 0; + this._angularZMotion = 0; + var bt = Laya.Physics3D._bullet; + this._btAxis = bt.btVector3_create(-1.0, 0.0, 0.0); + this._btSecondaryAxis = bt.btVector3_create(0.0, 1.0, 0.0); + } + get axis() { + return this._axis; + } + get secondaryAxis() { + return this._secondaryAxis; + } + set maxAngularLimit(value) { + value.cloneTo(this._maxAngularLimit); + } + set minAngularLimit(value) { + value.cloneTo(this._minAngularLimit); + } + get maxAngularLimit() { + return this._maxAngularLimit; + } + get minAngularLimit() { + return this._minAngularLimit; + } + set maxLinearLimit(value) { + value.cloneTo(this._maxLinearLimit); + } + set minLinearLimit(value) { + value.cloneTo(this._minLinearLimit); + } + get maxLinearLimit() { + return this._maxLinearLimit; + } + get minLinearLimit() { + return this._minLinearLimit; + } + set XMotion(value) { + if (this._xMotion != value) { + this._xMotion = value; + this.setLimit(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, value, -this._maxLinearLimit.x, -this._minLinearLimit.x); + } + } + get XMotion() { + return this._xMotion; + } + set YMotion(value) { + if (this._yMotion != value) { + this._yMotion = value; + this.setLimit(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, value, this._minLinearLimit.y, this._maxLinearLimit.y); + } + } + get YMotion() { + return this._yMotion; + } + set ZMotion(value) { + if (this._zMotion != value) { + this._zMotion = value; + this.setLimit(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, value, this._minLinearLimit.z, this._maxLinearLimit.z); + } + } + get ZMotion() { + return this._zMotion; + } + set angularXMotion(value) { + if (this._angularXMotion != value) { + this._angularXMotion = value; + this.setLimit(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, value, -this._maxAngularLimit.x, -this._minAngularLimit.x); + } + } + get angularXMotion() { + return this._angularXMotion; + } + set angularYMotion(value) { + if (this._angularYMotion != value) { + this._angularYMotion = value; + this.setLimit(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, value, this._minAngularLimit.y, this._maxAngularLimit.y); + } + } + get angularYMotion() { + return this._angularYMotion; + } + set angularZMotion(value) { + if (this._angularZMotion != value) { + this._angularZMotion = value; + this.setLimit(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, value, this._minAngularLimit.z, this._maxAngularLimit.z); + } + } + get angularZMotion() { + return this._angularZMotion; + } + set linearLimitSpring(value) { + if (!Laya.Vector3.equals(this._linearLimitSpring, value)) { + value.cloneTo(this._linearLimitSpring); + this.setSpring(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, value.x); + this.setSpring(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, value.y); + this.setSpring(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, value.z); + } + } + get linearLimitSpring() { + return this._linearLimitSpring; + } + set angularLimitSpring(value) { + if (!Laya.Vector3.equals(this._angularLimitSpring, value)) { + value.cloneTo(this._angularLimitSpring); + this.setSpring(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, value.x); + this.setSpring(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, value.y); + this.setSpring(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, value.z); + } + } + get angularLimitSpring() { + return this._angularLimitSpring; + } + set linearBounce(value) { + if (!Laya.Vector3.equals(this._linearBounce, value)) { + value.cloneTo(this._linearBounce); + this.setBounce(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, value.x); + this.setBounce(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, value.y); + this.setBounce(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, value.z); + } + } + get linearBounce() { + return this._linearBounce; + } + set angularBounce(value) { + if (!Laya.Vector3.equals(this._angularBounce, value)) { + value.cloneTo(this._angularBounce); + this.setBounce(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, value.x); + this.setBounce(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, value.y); + this.setBounce(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, value.z); + } + } + get angularBounce() { + return this._angularBounce; + } + set linearDamp(value) { + if (!Laya.Vector3.equals(this._linearDamp, value)) { + value.cloneTo(this._linearDamp); + this.setDamping(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, value.x); + this.setDamping(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, value.y); + this.setDamping(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, value.z); + } + } + get linearDamp() { + return this._linearDamp; + } + set angularDamp(value) { + if (!Laya.Vector3.equals(this._angularDamp, value)) { + value.cloneTo(this._angularDamp); + this.setDamping(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, value.x); + this.setDamping(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, value.y); + this.setDamping(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, value.z); + } + } + get angularDamp() { + return this._angularDamp; + } + set anchor(value) { + value.cloneTo(this._anchor); + this.setFrames(); + } + get anchor() { + return this._anchor; + } + set connectAnchor(value) { + value.cloneTo(this._connectAnchor); + this.setFrames(); + } + get connectAnchor() { + return this._connectAnchor; + } + setAxis(axis, secondaryAxis) { + if (!this._btConstraint) + return; + var bt = Laya.Physics3D._bullet; + this._axis.setValue(axis.x, axis.y, axis.y); + this._secondaryAxis.setValue(secondaryAxis.x, secondaryAxis.y, secondaryAxis.z); + this._btAxis = bt.btVector3_setValue(-axis.x, axis.y, axis.z); + this._btSecondaryAxis = bt.btVector3_setValue(-secondaryAxis.x, secondaryAxis.y, secondaryAxis.z); + bt.btGeneric6DofSpring2Constraint_setAxis(this._btConstraint, this._btAxis, this._btSecondaryAxis); + } + setLimit(axis, motionType, low, high) { + if (!this._btConstraint) + return; + var bt = Laya.Physics3D._bullet; + switch (motionType) { + case ConfigurableConstraint.CONFIG_MOTION_TYPE_LOCKED: + bt.btGeneric6DofSpring2Constraint_setLimit(this._btConstraint, axis, 0, 0); + break; + case ConfigurableConstraint.CONFIG_MOTION_TYPE_LIMITED: + if (low < high) + bt.btGeneric6DofSpring2Constraint_setLimit(this._btConstraint, axis, low, high); + break; + case ConfigurableConstraint.CONFIG_MOTION_TYPE_FREE: + bt.btGeneric6DofSpring2Constraint_setLimit(this._btConstraint, axis, 1, 0); + break; + default: + throw "No Type of Axis Motion"; + } + } + setSpring(axis, springValue, limitIfNeeded = true) { + if (!this._btConstraint) + return; + var bt = Laya.Physics3D._bullet; + var enableSpring = springValue > 0; + bt.btGeneric6DofSpring2Constraint_enableSpring(this._btConstraint, axis, enableSpring); + if (enableSpring) + bt.btGeneric6DofSpring2Constraint_setStiffness(this._btConstraint, axis, springValue, limitIfNeeded); + } + setBounce(axis, bounce) { + if (!this._btConstraint) + return; + var bt = Laya.Physics3D._bullet; + bounce = bounce <= 0 ? 0 : bounce; + bt.btGeneric6DofSpring2Constraint_setBounce(this._btConstraint, axis, bounce); + } + setDamping(axis, damp, limitIfNeeded = true) { + if (!this._btConstraint) + return; + var bt = Laya.Physics3D._bullet; + damp = damp <= 0 ? 0 : damp; + bt.btGeneric6DofSpring2Constraint_setDamping(this._btConstraint, axis, damp, limitIfNeeded); + } + setEquilibriumPoint(axis, equilibriumPoint) { + var bt = Laya.Physics3D._bullet; + bt.btGeneric6DofSpring2Constraint_setEquilibriumPoint(this._btConstraint, axis, equilibriumPoint); + } + enableMotor(axis, isEnableMotor) { + var bt = Laya.Physics3D._bullet; + bt.btGeneric6DofSpring2Constraint_enableMotor(this._btConstraint, axis, isEnableMotor); + } + setServo(axis, onOff) { + var bt = Laya.Physics3D._bullet; + bt.btGeneric6DofSpring2Constraint_setServo(this._btConstraint, axis, onOff); + } + setTargetVelocity(axis, velocity) { + var bt = Laya.Physics3D._bullet; + bt.btGeneric6DofSpring2Constraint_setTargetVelocity(this._btConstraint, axis, velocity); + } + setTargetPosition(axis, target) { + var bt = Laya.Physics3D._bullet; + bt.btGeneric6DofSpring2Constraint_setServoTarget(this._btConstraint, axis, target); + } + setMaxMotorForce(axis, force) { + var bt = Laya.Physics3D._bullet; + bt.btGeneric6DofSpring2Constraint_setMaxMotorForce(this._btConstraint, axis, force); + } + setParam(axis, constraintParams, value) { + var bt = Laya.Physics3D._bullet; + bt.btTypedConstraint_setParam(this._btConstraint, axis, constraintParams, value); + } + setFrames() { + super.setFrames(); + var bt = Laya.Physics3D._bullet; + if (!this._btConstraint) + return; + bt.btGeneric6DofSpring2Constraint_setFrames(this._btConstraint, this._btframATrans, this._btframBTrans); + } + _addToSimulation() { + this._simulation && this._simulation.addConstraint(this, this.enabled); + } + _removeFromSimulation() { + this._simulation.removeConstraint(this); + this._simulation = null; + } + _createConstraint() { + var bt = Laya.Physics3D._bullet; + this._btConstraint = bt.btGeneric6DofSpring2Constraint_create(this.ownBody.btColliderObject, this._btframAPos, this.connectedBody.btColliderObject, this._btframBPos, ConfigurableConstraint.RO_XYZ); + this._btJointFeedBackObj = bt.btJointFeedback_create(this._btConstraint); + bt.btTypedConstraint_setJointFeedback(this._btConstraint, this._btJointFeedBackObj); + this._simulation = this.owner._scene.physicsSimulation; + this._initAllConstraintInfo(); + this._addToSimulation(); + Laya.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint, true); + } + _initAllConstraintInfo() { + this.setLimit(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, this._xMotion, -this._maxLinearLimit.x, -this._minLinearLimit.x); + this.setLimit(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, this._yMotion, this._minLinearLimit.y, this._maxLinearLimit.y); + this.setLimit(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, this._zMotion, this._minLinearLimit.z, this._maxLinearLimit.z); + this.setLimit(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, this._angularXMotion, -this._maxAngularLimit.x, -this._minAngularLimit.x); + this.setLimit(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, this._angularYMotion, this._minAngularLimit.y, this._maxAngularLimit.y); + this.setLimit(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, this._angularZMotion, this._minAngularLimit.z, this._maxAngularLimit.z); + this.setSpring(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, this._linearLimitSpring.x); + this.setSpring(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, this._linearLimitSpring.y); + this.setSpring(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, this._linearLimitSpring.z); + this.setSpring(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, this._angularLimitSpring.x); + this.setSpring(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, this._angularLimitSpring.y); + this.setSpring(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, this._angularLimitSpring.z); + this.setBounce(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, this._linearBounce.x); + this.setBounce(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, this._linearBounce.y); + this.setBounce(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, this._linearBounce.z); + this.setBounce(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, this._angularBounce.x); + this.setBounce(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, this._angularBounce.y); + this.setBounce(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, this._angularBounce.z); + this.setDamping(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, this._linearDamp.x); + this.setDamping(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, this._linearDamp.y); + this.setDamping(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, this._linearDamp.z); + this.setDamping(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, this._angularDamp.x); + this.setDamping(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, this._angularDamp.y); + this.setDamping(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, this._angularDamp.z); + this.setFrames(); + this.setEquilibriumPoint(0, 0); + } + _onAdded() { + super._onAdded(); + } + _onEnable() { + if (!this._btConstraint) + return; + super._onEnable(); + if (this._btConstraint) + Laya.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint, true); + } + _onDisable() { + super._onDisable(); + if (!this.connectedBody && this._simulation) + this._removeFromSimulation(); + if (this._btConstraint) + Laya.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint, false); + } + _parse(data, interactMap = null) { + super._parse(data); + this._axis.fromArray(data.axis); + this._secondaryAxis.fromArray(data.secondaryAxis); + var limitlimit = data.linearLimit; + this._minLinearLimit.setValue(-limitlimit, -limitlimit, -limitlimit); + this._maxLinearLimit.setValue(limitlimit, limitlimit, limitlimit); + var limitSpring = data.linearLimitSpring; + this._linearLimitSpring.setValue(limitSpring, limitSpring, limitSpring); + var limitDamp = data.linearLimitDamper; + this._linearDamp.setValue(limitDamp, limitDamp, limitDamp); + var limitBounciness = data.linearLimitBounciness; + this._linearBounce.setValue(limitBounciness, limitBounciness, limitBounciness); + var xlowAngularLimit = data.lowAngularXLimit; + var xhighAngularLimit = data.highAngularXLimit; + var yAngularLimit = data.angularYLimit; + var zAngularLimit = data.angularZLimit; + this._minAngularLimit.setValue(xlowAngularLimit, -yAngularLimit, -zAngularLimit); + this._maxAngularLimit.setValue(xhighAngularLimit, yAngularLimit, zAngularLimit); + var xhighAngularBounciness = data.highAngularXLimitBounciness; + var ybounciness = data.angularYLimitBounciness; + var zbounciness = data.angularZLimitBounciness; + this._angularBounce.setValue(xhighAngularBounciness, ybounciness, zbounciness); + var xAngularSpring = data.angularXLimitSpring; + var yzAngularSpriny = data.angularYZLimitSpring; + this._angularLimitSpring.setValue(xAngularSpring, yzAngularSpriny, yzAngularSpriny); + var xAngularDamper = data.angularXLimitDamper; + var yzAngularDamper = data.angularYZLimitDamper; + this._angularDamp.setValue(xAngularDamper, yzAngularDamper, yzAngularDamper); + this.XMotion = data.xMotion; + this.YMotion = data.yMotion; + this.ZMotion = data.zMotion; + this.angularXMotion = data.angularXMotion; + this.angularYMotion = data.angularYMotion; + this.angularZMotion = data.angularZMotion; + if (data.rigidbodyID != -1 && data.connectRigidbodyID != -1) { + interactMap.component.push(this); + interactMap.data.push(data); + } + (data.breakForce != undefined) && (this.breakForce = data.breakForce); + (data.breakTorque != undefined) && (this.breakTorque = data.breakTorque); + } + _parseInteractive(data = null, spriteMap = null) { + var rigidBodySprite = spriteMap[data.rigidbodyID]; + var rigidBody = rigidBodySprite.getComponent(Rigidbody3D); + var connectSprite = spriteMap[data.connectRigidbodyID]; + var connectRigidbody = connectSprite.getComponent(Rigidbody3D); + this.ownBody = rigidBody; + this.connectedBody = connectRigidbody; + } + _onDestroy() { + super._onDestroy(); + } + } + ConfigurableConstraint.CONFIG_MOTION_TYPE_LOCKED = 0; + ConfigurableConstraint.CONFIG_MOTION_TYPE_LIMITED = 1; + ConfigurableConstraint.CONFIG_MOTION_TYPE_FREE = 2; + ConfigurableConstraint.MOTION_LINEAR_INDEX_X = 0; + ConfigurableConstraint.MOTION_LINEAR_INDEX_Y = 1; + ConfigurableConstraint.MOTION_LINEAR_INDEX_Z = 2; + ConfigurableConstraint.MOTION_ANGULAR_INDEX_X = 3; + ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y = 4; + ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z = 5; + ConfigurableConstraint.RO_XYZ = 0; + ConfigurableConstraint.RO_XZY = 1; + ConfigurableConstraint.RO_YXZ = 2; + ConfigurableConstraint.RO_YZX = 3; + ConfigurableConstraint.RO_ZXY = 4; + ConfigurableConstraint.RO_ZYX = 5; + + class FixedConstraint extends ConstraintComponent { + constructor() { + super(ConstraintComponent.CONSTRAINT_FIXED_CONSTRAINT_TYPE); + this.breakForce = -1; + this.breakTorque = -1; + } + _addToSimulation() { + this._simulation && this._simulation.addConstraint(this, this.enabled); + } + _removeFromSimulation() { + this._simulation.removeConstraint(this); + this._simulation = null; + } + _createConstraint() { + if (this.ownBody && this.ownBody._simulation && this.connectedBody && this.connectedBody._simulation) { + var bt = Laya.Physics3D._bullet; + this._btConstraint = bt.btFixedConstraint_create(this.ownBody.btColliderObject, this._btframATrans, this.connectedBody.btColliderObject, this._btframBTrans); + this._btJointFeedBackObj = bt.btJointFeedback_create(this._btConstraint); + bt.btTypedConstraint_setJointFeedback(this._btConstraint, this._btJointFeedBackObj); + this._simulation = this.owner._scene.physicsSimulation; + this._addToSimulation(); + Laya.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint, true); + } + } + _onAdded() { + super._onAdded(); + } + _onEnable() { + if (!this._btConstraint) + return; + super._onEnable(); + if (this._btConstraint) + Laya.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint, true); + } + _onDisable() { + super._onDisable(); + if (!this.connectedBody) + this._removeFromSimulation(); + if (this._btConstraint) + Laya.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint, false); + } + _onDestroy() { + super._onDestroy(); + } + _parse(data, interactMap = null) { + super._parse(data); + if (data.rigidbodyID != -1 && data.connectRigidbodyID != -1) { + interactMap.component.push(this); + interactMap.data.push(data); + } + (data.breakForce != undefined) && (this.breakForce = data.breakForce); + (data.breakTorque != undefined) && (this.breakTorque = data.breakTorque); + } + _parseInteractive(data = null, spriteMap = null) { + var rigidBodySprite = spriteMap[data.rigidbodyID]; + var rigidBody = rigidBodySprite.getComponent(Rigidbody3D); + var connectSprite = spriteMap[data.connectRigidbodyID]; + var connectRigidbody = connectSprite.getComponent(Rigidbody3D); + this.ownBody = rigidBody; + this.connectedBody = connectRigidbody; + } + } + + class StaticPlaneColliderShape extends ColliderShape { + constructor(normal, offset) { + super(); + this._normal = normal; + this._offset = offset; + this._type = ColliderShape.SHAPETYPES_STATICPLANE; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(StaticPlaneColliderShape._btNormal, -normal.x, normal.y, normal.z); + this._btShape = bt.btStaticPlaneShape_create(StaticPlaneColliderShape._btNormal, offset); + } + static __init__() { + StaticPlaneColliderShape._btNormal = Laya.ILaya3D.Physics3D._bullet.btVector3_create(0, 0, 0); + } + clone() { + var dest = new StaticPlaneColliderShape(this._normal, this._offset); + this.cloneTo(dest); + return dest; + } + } + + exports.BoxColliderShape = BoxColliderShape; + exports.BulletInteractive = BulletInteractive; + exports.CapsuleColliderShape = CapsuleColliderShape; + exports.CharacterController = CharacterController; + exports.ColliderShape = ColliderShape; + exports.Collision = Collision; + exports.CollisionTool = CollisionTool; + exports.CompoundColliderShape = CompoundColliderShape; + exports.ConeColliderShape = ConeColliderShape; + exports.ConfigurableConstraint = ConfigurableConstraint; + exports.Constraint3D = Constraint3D; + exports.ConstraintComponent = ConstraintComponent; + exports.ContactPoint = ContactPoint; + exports.CylinderColliderShape = CylinderColliderShape; + exports.FixedConstraint = FixedConstraint; + exports.HitResult = HitResult; + exports.MeshColliderShape = MeshColliderShape; + exports.PhysicsCollider = PhysicsCollider; + exports.PhysicsComponent = PhysicsComponent; + exports.PhysicsSettings = PhysicsSettings; + exports.PhysicsSimulation = PhysicsSimulation; + exports.PhysicsTriggerComponent = PhysicsTriggerComponent; + exports.PhysicsUpdateList = PhysicsUpdateList; + exports.Rigidbody3D = Rigidbody3D; + exports.SphereColliderShape = SphereColliderShape; + exports.StaticPlaneColliderShape = StaticPlaneColliderShape; + +}(window.Laya = window.Laya || {}, Laya)); diff --git a/examples/layaair/frontend/bin/libs/laya.physics3D.runtime.js b/examples/layaair/frontend/bin/libs/laya.physics3D.runtime.js new file mode 100644 index 0000000..8ae7626 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.physics3D.runtime.js @@ -0,0 +1,10 @@ +window.Physics3D = function(initialMemory, interactive) { + window.conch.setGetWorldTransformFunction(interactive.getWorldTransform); + window.conch.setSetWorldTransformFunction(interactive.setWorldTransform); + var conchBullet = window.layaConchBullet; + conchBullet.then = (complete) => { + complete(); + }; + window.Physics3D = conchBullet; + return conchBullet; +}; \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/laya.physics3D.wasm-wx.js b/examples/layaair/frontend/bin/libs/laya.physics3D.wasm-wx.js new file mode 100644 index 0000000..21b024b --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.physics3D.wasm-wx.js @@ -0,0 +1,3077 @@ +window.Physics3D = function (initialMemory, interactive) { + return new Promise((resolve) => { + var mem = new WXWebAssembly.Memory({ initial: initialMemory }); + + // fetch("libs/laya.physics3D.wasm.wasm").then((response) => { + // response.arrayBuffer().then((buffer) => { + WXWebAssembly.instantiate("libs/laya.physics3D.wasm.wasm", { + LayaAirInteractive: interactive, + wasi_unstable: { + fd_close: () => { console.log('fd_close'); }, + fd_seek: () => { console.log('fd_seek'); }, + fd_write: () => { console.log('fd_write'); } + }, + env: { + memory: mem, + } + }).then((physics3D) => { + window.Physics3D = physics3D.instance.exports; + resolve(); + }); + // }); + // }); + }); +}; + +(function (exports, Laya) { + 'use strict'; + + class ColliderShape { + constructor() { + this._scale = new Laya.Vector3(1, 1, 1); + this._centerMatrix = new Laya.Matrix4x4(); + this._attatched = false; + this._indexInCompound = -1; + this._compoundParent = null; + this._attatchedCollisionObject = null; + this._referenceCount = 0; + this._localOffset = new Laya.Vector3(0, 0, 0); + this._localRotation = new Laya.Quaternion(0, 0, 0, 1); + this.needsCustomCollisionCallback = false; + } + static __init__() { + var bt = Laya.ILaya3D.Physics3D._bullet; + ColliderShape._btScale = bt.btVector3_create(1, 1, 1); + ColliderShape._btVector30 = bt.btVector3_create(0, 0, 0); + ColliderShape._btQuaternion0 = bt.btQuaternion_create(0, 0, 0, 1); + ColliderShape._btTransform0 = bt.btTransform_create(); + } + static _createAffineTransformation(trans, rot, outE) { + var x = rot.x, y = rot.y, z = rot.z, w = rot.w, x2 = x + x, y2 = y + y, z2 = z + z; + var xx = x * x2, xy = x * y2, xz = x * z2, yy = y * y2, yz = y * z2, zz = z * z2; + var wx = w * x2, wy = w * y2, wz = w * z2; + outE[0] = (1 - (yy + zz)); + outE[1] = (xy + wz); + outE[2] = (xz - wy); + outE[3] = 0; + outE[4] = (xy - wz); + outE[5] = (1 - (xx + zz)); + outE[6] = (yz + wx); + outE[7] = 0; + outE[8] = (xz + wy); + outE[9] = (yz - wx); + outE[10] = (1 - (xx + yy)); + outE[11] = 0; + outE[12] = trans.x; + outE[13] = trans.y; + outE[14] = trans.z; + outE[15] = 1; + } + get type() { + return this._type; + } + get localOffset() { + return this._localOffset; + } + set localOffset(value) { + this._localOffset = value; + if (this._compoundParent) + this._compoundParent._updateChildTransform(this); + } + get localRotation() { + return this._localRotation; + } + set localRotation(value) { + this._localRotation = value; + if (this._compoundParent) + this._compoundParent._updateChildTransform(this); + } + _setScale(value) { + if (this._compoundParent) { + this.updateLocalTransformations(); + } + else { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(ColliderShape._btScale, value.x, value.y, value.z); + bt.btCollisionShape_setLocalScaling(this._btShape, ColliderShape._btScale); + } + } + _addReference() { + this._referenceCount++; + } + _removeReference() { + this._referenceCount--; + } + updateLocalTransformations() { + if (this._compoundParent) { + var offset = ColliderShape._tempVector30; + Laya.Vector3.multiply(this.localOffset, this._scale, offset); + ColliderShape._createAffineTransformation(offset, this.localRotation, this._centerMatrix.elements); + } + else { + ColliderShape._createAffineTransformation(this.localOffset, this.localRotation, this._centerMatrix.elements); + } + } + cloneTo(destObject) { + var destColliderShape = destObject; + this._localOffset.cloneTo(destColliderShape.localOffset); + this._localRotation.cloneTo(destColliderShape.localRotation); + destColliderShape.localOffset = destColliderShape.localOffset; + destColliderShape.localRotation = destColliderShape.localRotation; + } + clone() { + return null; + } + destroy() { + if (this._btShape) { + Laya.ILaya3D.Physics3D._bullet.btCollisionShape_destroy(this._btShape); + this._btShape = null; + } + } + } + ColliderShape.SHAPEORIENTATION_UPX = 0; + ColliderShape.SHAPEORIENTATION_UPY = 1; + ColliderShape.SHAPEORIENTATION_UPZ = 2; + ColliderShape.SHAPETYPES_BOX = 0; + ColliderShape.SHAPETYPES_SPHERE = 1; + ColliderShape.SHAPETYPES_CYLINDER = 2; + ColliderShape.SHAPETYPES_CAPSULE = 3; + ColliderShape.SHAPETYPES_CONVEXHULL = 4; + ColliderShape.SHAPETYPES_COMPOUND = 5; + ColliderShape.SHAPETYPES_STATICPLANE = 6; + ColliderShape.SHAPETYPES_CONE = 7; + ColliderShape._tempVector30 = new Laya.Vector3(); + + class BoxColliderShape extends ColliderShape { + constructor(sizeX = 1.0, sizeY = 1.0, sizeZ = 1.0) { + super(); + this._sizeX = sizeX; + this._sizeY = sizeY; + this._sizeZ = sizeZ; + this._type = ColliderShape.SHAPETYPES_BOX; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(BoxColliderShape._btSize, sizeX / 2, sizeY / 2, sizeZ / 2); + this._btShape = bt.btBoxShape_create(BoxColliderShape._btSize); + } + static __init__() { + BoxColliderShape._btSize = Laya.ILaya3D.Physics3D._bullet.btVector3_create(0, 0, 0); + } + get sizeX() { + return this._sizeX; + } + get sizeY() { + return this._sizeY; + } + get sizeZ() { + return this._sizeZ; + } + clone() { + var dest = new BoxColliderShape(this._sizeX, this._sizeY, this._sizeZ); + this.cloneTo(dest); + return dest; + } + } + + class CapsuleColliderShape extends ColliderShape { + constructor(radius = 0.5, length = 1.25, orientation = ColliderShape.SHAPEORIENTATION_UPY) { + super(); + this._radius = radius; + this._length = length; + this._orientation = orientation; + this._type = ColliderShape.SHAPETYPES_CAPSULE; + var bt = Laya.ILaya3D.Physics3D._bullet; + switch (orientation) { + case ColliderShape.SHAPEORIENTATION_UPX: + this._btShape = bt.btCapsuleShapeX_create(radius, length - radius * 2); + break; + case ColliderShape.SHAPEORIENTATION_UPY: + this._btShape = bt.btCapsuleShape_create(radius, length - radius * 2); + break; + case ColliderShape.SHAPEORIENTATION_UPZ: + this._btShape = bt.btCapsuleShapeZ_create(radius, length - radius * 2); + break; + default: + throw "CapsuleColliderShape:unknown orientation."; + } + } + get radius() { + return this._radius; + } + get length() { + return this._length; + } + get orientation() { + return this._orientation; + } + _setScale(value) { + var fixScale = CapsuleColliderShape._tempVector30; + switch (this.orientation) { + case ColliderShape.SHAPEORIENTATION_UPX: + fixScale.x = value.x; + fixScale.y = fixScale.z = Math.max(value.y, value.z); + break; + case ColliderShape.SHAPEORIENTATION_UPY: + fixScale.y = value.y; + fixScale.x = fixScale.z = Math.max(value.x, value.z); + break; + case ColliderShape.SHAPEORIENTATION_UPZ: + fixScale.z = value.z; + fixScale.x = fixScale.y = Math.max(value.x, value.y); + break; + default: + throw "CapsuleColliderShape:unknown orientation."; + } + super._setScale(fixScale); + } + clone() { + var dest = new CapsuleColliderShape(this._radius, this._length, this._orientation); + this.cloneTo(dest); + return dest; + } + } + CapsuleColliderShape._tempVector30 = new Laya.Vector3(); + + class CompoundColliderShape extends ColliderShape { + constructor() { + super(); + this._childColliderShapes = []; + this._type = ColliderShape.SHAPETYPES_COMPOUND; + this._btShape = Laya.ILaya3D.Physics3D._bullet.btCompoundShape_create(); + } + static __init__() { + var bt = Laya.ILaya3D.Physics3D._bullet; + CompoundColliderShape._btVector3One = bt.btVector3_create(1, 1, 1); + CompoundColliderShape._btTransform = bt.btTransform_create(); + CompoundColliderShape._btOffset = bt.btVector3_create(0, 0, 0); + CompoundColliderShape._btRotation = bt.btQuaternion_create(0, 0, 0, 1); + } + _clearChildShape(shape) { + shape._attatched = false; + shape._compoundParent = null; + shape._indexInCompound = -1; + } + _addReference() { + } + _removeReference() { + } + _updateChildTransform(shape) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var offset = shape.localOffset; + var rotation = shape.localRotation; + var btOffset = ColliderShape._btVector30; + var btQuaternion = ColliderShape._btQuaternion0; + var btTransform = ColliderShape._btTransform0; + bt.btVector3_setValue(btOffset, -offset.x, offset.y, offset.z); + bt.btQuaternion_setValue(btQuaternion, -rotation.x, rotation.y, rotation.z, -rotation.w); + bt.btTransform_setOrigin(btTransform, btOffset); + bt.btTransform_setRotation(btTransform, btQuaternion); + bt.btCompoundShape_updateChildTransform(this._btShape, shape._indexInCompound, btTransform, true); + } + addChildShape(shape) { + if (shape._attatched) + throw "CompoundColliderShape: this shape has attatched to other entity."; + shape._attatched = true; + shape._compoundParent = this; + shape._indexInCompound = this._childColliderShapes.length; + this._childColliderShapes.push(shape); + var offset = shape.localOffset; + var rotation = shape.localRotation; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(CompoundColliderShape._btOffset, -offset.x, offset.y, offset.z); + bt.btQuaternion_setValue(CompoundColliderShape._btRotation, -rotation.x, rotation.y, rotation.z, -rotation.w); + bt.btTransform_setOrigin(CompoundColliderShape._btTransform, CompoundColliderShape._btOffset); + bt.btTransform_setRotation(CompoundColliderShape._btTransform, CompoundColliderShape._btRotation); + var btScale = bt.btCollisionShape_getLocalScaling(this._btShape); + bt.btCollisionShape_setLocalScaling(this._btShape, CompoundColliderShape._btVector3One); + bt.btCompoundShape_addChildShape(this._btShape, CompoundColliderShape._btTransform, shape._btShape); + bt.btCollisionShape_setLocalScaling(this._btShape, btScale); + (this._attatchedCollisionObject) && (this._attatchedCollisionObject.colliderShape = this); + } + removeChildShape(shape) { + if (shape._compoundParent === this) { + var index = shape._indexInCompound; + this._clearChildShape(shape); + var endShape = this._childColliderShapes[this._childColliderShapes.length - 1]; + endShape._indexInCompound = index; + this._childColliderShapes[index] = endShape; + this._childColliderShapes.pop(); + Laya.ILaya3D.Physics3D._bullet.btCompoundShape_removeChildShapeByIndex(this._btShape, index); + } + } + clearChildShape() { + for (var i = 0, n = this._childColliderShapes.length; i < n; i++) { + this._clearChildShape(this._childColliderShapes[i]); + Laya.ILaya3D.Physics3D._bullet.btCompoundShape_removeChildShapeByIndex(this._btShape, 0); + } + this._childColliderShapes.length = 0; + } + getChildShapeCount() { + return this._childColliderShapes.length; + } + cloneTo(destObject) { + var destCompoundColliderShape = destObject; + destCompoundColliderShape.clearChildShape(); + for (var i = 0, n = this._childColliderShapes.length; i < n; i++) + destCompoundColliderShape.addChildShape(this._childColliderShapes[i].clone()); + } + clone() { + var dest = new CompoundColliderShape(); + this.cloneTo(dest); + return dest; + } + destroy() { + super.destroy(); + for (var i = 0, n = this._childColliderShapes.length; i < n; i++) { + var childShape = this._childColliderShapes[i]; + if (childShape._referenceCount === 0) + childShape.destroy(); + } + } + } + + class ConeColliderShape extends ColliderShape { + constructor(radius = 0.5, height = 1.0, orientation = ColliderShape.SHAPEORIENTATION_UPY) { + super(); + this._radius = 1; + this._height = 0.5; + this._radius = radius; + this._height = height; + this._orientation = orientation; + this._type = ColliderShape.SHAPETYPES_CYLINDER; + var bt = Laya.ILaya3D.Physics3D._bullet; + switch (orientation) { + case ColliderShape.SHAPEORIENTATION_UPX: + this._btShape = bt.btConeShapeX_create(radius, height); + break; + case ColliderShape.SHAPEORIENTATION_UPY: + this._btShape = bt.btConeShape_create(radius, height); + break; + case ColliderShape.SHAPEORIENTATION_UPZ: + this._btShape = bt.btConeShapeZ_create(radius, height); + break; + default: + throw "ConeColliderShape:unknown orientation."; + } + } + get radius() { + return this._radius; + } + get height() { + return this._height; + } + get orientation() { + return this._orientation; + } + clone() { + var dest = new ConeColliderShape(this._radius, this._height, this._orientation); + this.cloneTo(dest); + return dest; + } + } + + class CylinderColliderShape extends ColliderShape { + constructor(radius = 0.5, height = 1.0, orientation = ColliderShape.SHAPEORIENTATION_UPY) { + super(); + this._radius = 1; + this._height = 0.5; + this._radius = radius; + this._height = height; + this._orientation = orientation; + this._type = ColliderShape.SHAPETYPES_CYLINDER; + var bt = Laya.ILaya3D.Physics3D._bullet; + switch (orientation) { + case ColliderShape.SHAPEORIENTATION_UPX: + bt.btVector3_setValue(CylinderColliderShape._btSize, height / 2, radius, radius); + this._btShape = bt.btCylinderShapeX_create(CylinderColliderShape._btSize); + break; + case ColliderShape.SHAPEORIENTATION_UPY: + bt.btVector3_setValue(CylinderColliderShape._btSize, radius, height / 2, radius); + this._btShape = bt.btCylinderShape_create(CylinderColliderShape._btSize); + break; + case ColliderShape.SHAPEORIENTATION_UPZ: + bt.btVector3_setValue(CylinderColliderShape._btSize, radius, radius, height / 2); + this._btShape = bt.btCylinderShapeZ_create(CylinderColliderShape._btSize); + break; + default: + throw "CapsuleColliderShape:unknown orientation."; + } + } + static __init__() { + CylinderColliderShape._btSize = Laya.ILaya3D.Physics3D._bullet.btVector3_create(0, 0, 0); + } + get radius() { + return this._radius; + } + get height() { + return this._height; + } + get orientation() { + return this._orientation; + } + clone() { + var dest = new CylinderColliderShape(this._radius, this._height, this._orientation); + this.cloneTo(dest); + return dest; + } + } + + class MeshColliderShape extends ColliderShape { + constructor() { + super(); + this._mesh = null; + this._convex = false; + } + get mesh() { + return this._mesh; + } + set mesh(value) { + if (this._mesh !== value) { + var bt = Laya.ILaya3D.Physics3D._bullet; + if (this._mesh) { + bt.btCollisionShape_destroy(this._btShape); + } + if (value) { + this._btShape = bt.btGImpactMeshShape_create(value._getPhysicMesh()); + bt.btGImpactShapeInterface_updateBound(this._btShape); + } + this._mesh = value; + } + } + get convex() { + return this._convex; + } + set convex(value) { + this._convex = value; + } + _setScale(value) { + if (this._compoundParent) { + this.updateLocalTransformations(); + } + else { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(ColliderShape._btScale, value.x, value.y, value.z); + bt.btCollisionShape_setLocalScaling(this._btShape, ColliderShape._btScale); + bt.btGImpactShapeInterface_updateBound(this._btShape); + } + } + cloneTo(destObject) { + var destMeshCollider = destObject; + destMeshCollider.convex = this._convex; + destMeshCollider.mesh = this._mesh; + super.cloneTo(destObject); + } + clone() { + var dest = new MeshColliderShape(); + this.cloneTo(dest); + return dest; + } + destroy() { + if (this._btShape) { + Laya.ILaya3D.Physics3D._bullet.btCollisionShape_destroy(this._btShape); + this._btShape = null; + } + } + } + + class SphereColliderShape extends ColliderShape { + constructor(radius = 0.5) { + super(); + this._radius = radius; + this._type = ColliderShape.SHAPETYPES_SPHERE; + this._btShape = Laya.ILaya3D.Physics3D._bullet.btSphereShape_create(radius); + } + get radius() { + return this._radius; + } + clone() { + var dest = new SphereColliderShape(this._radius); + this.cloneTo(dest); + return dest; + } + } + + class PhysicsComponent extends Laya.Component { + constructor(collisionGroup, canCollideWith) { + super(); + this._restitution = 0.0; + this._friction = 0.5; + this._rollingFriction = 0.0; + this._ccdMotionThreshold = 0.0; + this._ccdSweptSphereRadius = 0.0; + this._collisionGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER; + this._canCollideWith = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER; + this._colliderShape = null; + this._transformFlag = 2147483647; + this._controlBySimulation = false; + this._enableProcessCollisions = true; + this._inPhysicUpdateListIndex = -1; + this.canScaleShape = true; + this._collisionGroup = collisionGroup; + this._canCollideWith = canCollideWith; + PhysicsComponent._physicObjectsMap[this.id] = this; + } + static __init__() { + var bt = Laya.ILaya3D.Physics3D._bullet; + PhysicsComponent._btVector30 = bt.btVector3_create(0, 0, 0); + PhysicsComponent._btQuaternion0 = bt.btQuaternion_create(0, 0, 0, 1); + } + static _createAffineTransformationArray(tranX, tranY, tranZ, rotX, rotY, rotZ, rotW, scale, outE) { + var x2 = rotX + rotX, y2 = rotY + rotY, z2 = rotZ + rotZ; + var xx = rotX * x2, xy = rotX * y2, xz = rotX * z2, yy = rotY * y2, yz = rotY * z2, zz = rotZ * z2; + var wx = rotW * x2, wy = rotW * y2, wz = rotW * z2, sx = scale[0], sy = scale[1], sz = scale[2]; + outE[0] = (1 - (yy + zz)) * sx; + outE[1] = (xy + wz) * sx; + outE[2] = (xz - wy) * sx; + outE[3] = 0; + outE[4] = (xy - wz) * sy; + outE[5] = (1 - (xx + zz)) * sy; + outE[6] = (yz + wx) * sy; + outE[7] = 0; + outE[8] = (xz + wy) * sz; + outE[9] = (yz - wx) * sz; + outE[10] = (1 - (xx + yy)) * sz; + outE[11] = 0; + outE[12] = tranX; + outE[13] = tranY; + outE[14] = tranZ; + outE[15] = 1; + } + static _creatShape(shapeData) { + var colliderShape; + switch (shapeData.type) { + case "BoxColliderShape": + var sizeData = shapeData.size; + colliderShape = sizeData ? new BoxColliderShape(sizeData[0], sizeData[1], sizeData[2]) : new BoxColliderShape(); + break; + case "SphereColliderShape": + colliderShape = new SphereColliderShape(shapeData.radius); + break; + case "CapsuleColliderShape": + colliderShape = new CapsuleColliderShape(shapeData.radius, shapeData.height, shapeData.orientation); + break; + case "MeshColliderShape": + var meshCollider = new MeshColliderShape(); + shapeData.mesh && (meshCollider.mesh = Laya.Loader.getRes(shapeData.mesh)); + colliderShape = meshCollider; + break; + case "ConeColliderShape": + colliderShape = new ConeColliderShape(shapeData.radius, shapeData.height, shapeData.orientation); + break; + case "CylinderColliderShape": + colliderShape = new CylinderColliderShape(shapeData.radius, shapeData.height, shapeData.orientation); + break; + default: + throw "unknown shape type."; + } + if (shapeData.center) { + var localOffset = colliderShape.localOffset; + localOffset.fromArray(shapeData.center); + colliderShape.localOffset = localOffset; + } + return colliderShape; + } + static physicVector3TransformQuat(source, qx, qy, qz, qw, out) { + var x = source.x, y = source.y, z = source.z, ix = qw * x + qy * z - qz * y, iy = qw * y + qz * x - qx * z, iz = qw * z + qx * y - qy * x, iw = -qx * x - qy * y - qz * z; + out.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; + out.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; + out.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + } + static physicQuaternionMultiply(lx, ly, lz, lw, right, out) { + var rx = right.x; + var ry = right.y; + var rz = right.z; + var rw = right.w; + var a = (ly * rz - lz * ry); + var b = (lz * rx - lx * rz); + var c = (lx * ry - ly * rx); + var d = (lx * rx + ly * ry + lz * rz); + out.x = (lx * rw + rx * lw) + a; + out.y = (ly * rw + ry * lw) + b; + out.z = (lz * rw + rz * lw) + c; + out.w = lw * rw - d; + } + get restitution() { + return this._restitution; + } + set restitution(value) { + this._restitution = value; + this._btColliderObject && Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setRestitution(this._btColliderObject, value); + } + get friction() { + return this._friction; + } + set friction(value) { + this._friction = value; + this._btColliderObject && Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setFriction(this._btColliderObject, value); + } + get rollingFriction() { + return this._rollingFriction; + } + set rollingFriction(value) { + this._rollingFriction = value; + this._btColliderObject && Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setRollingFriction(this._btColliderObject, value); + } + get ccdMotionThreshold() { + return this._ccdMotionThreshold; + } + set ccdMotionThreshold(value) { + this._ccdMotionThreshold = value; + this._btColliderObject && Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setCcdMotionThreshold(this._btColliderObject, value); + } + get ccdSweptSphereRadius() { + return this._ccdSweptSphereRadius; + } + set ccdSweptSphereRadius(value) { + this._ccdSweptSphereRadius = value; + this._btColliderObject && Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setCcdSweptSphereRadius(this._btColliderObject, value); + } + get isActive() { + return this._btColliderObject ? Laya.ILaya3D.Physics3D._bullet.btCollisionObject_isActive(this._btColliderObject) : false; + } + get colliderShape() { + return this._colliderShape; + } + set colliderShape(value) { + var lastColliderShape = this._colliderShape; + if (lastColliderShape) { + lastColliderShape._attatched = false; + lastColliderShape._attatchedCollisionObject = null; + } + this._colliderShape = value; + if (value) { + if (value._attatched) { + throw "PhysicsComponent: this shape has attatched to other entity."; + } + else { + value._attatched = true; + value._attatchedCollisionObject = this; + } + if (this._btColliderObject) { + Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setCollisionShape(this._btColliderObject, value._btShape); + var canInSimulation = this._simulation && this._enabled; + (canInSimulation && lastColliderShape) && (this._removeFromSimulation()); + this._onShapeChange(value); + if (canInSimulation) { + this._derivePhysicsTransformation(true); + this._addToSimulation(); + } + } + } + else { + if (this._simulation && this._enabled) + lastColliderShape && this._removeFromSimulation(); + } + } + get simulation() { + return this._simulation; + } + get collisionGroup() { + return this._collisionGroup; + } + set collisionGroup(value) { + if (this._collisionGroup !== value) { + this._collisionGroup = value; + if (this._simulation && this._colliderShape && this._enabled) { + this._removeFromSimulation(); + this._addToSimulation(); + } + } + } + get canCollideWith() { + return this._canCollideWith; + } + set canCollideWith(value) { + if (this._canCollideWith !== value) { + this._canCollideWith = value; + if (this._simulation && this._colliderShape && this._enabled) { + this._removeFromSimulation(); + this._addToSimulation(); + } + } + } + _parseShape(shapesData) { + var shapeCount = shapesData.length; + if (shapeCount === 1) { + var shape = PhysicsComponent._creatShape(shapesData[0]); + this.colliderShape = shape; + } + else { + var compoundShape = new CompoundColliderShape(); + for (var i = 0; i < shapeCount; i++) { + shape = PhysicsComponent._creatShape(shapesData[i]); + compoundShape.addChildShape(shape); + } + this.colliderShape = compoundShape; + } + } + _onScaleChange(scale) { + this._colliderShape._setScale(scale); + } + _onEnable() { + this._simulation = this.owner._scene.physicsSimulation; + Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setContactProcessingThreshold(this._btColliderObject, 0); + if (this._colliderShape) { + this._derivePhysicsTransformation(true); + this._addToSimulation(); + } + } + _onDisable() { + if (this._colliderShape) { + this._removeFromSimulation(); + (this._inPhysicUpdateListIndex !== -1) && (this._simulation._physicsUpdateList.remove(this)); + } + this._simulation = null; + } + _onDestroy() { + delete PhysicsComponent._physicObjectsMap[this.id]; + Laya.ILaya3D.Physics3D._bullet.btCollisionObject_destroy(this._btColliderObject); + this._colliderShape.destroy(); + super._onDestroy(); + this._btColliderObject = null; + this._colliderShape = null; + this._simulation = null; + this.owner.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onTransformChanged); + } + _isValid() { + return this._simulation && this._colliderShape && this._enabled; + } + _parse(data) { + (data.collisionGroup != null) && (this.collisionGroup = data.collisionGroup); + (data.canCollideWith != null) && (this.canCollideWith = data.canCollideWith); + (data.ccdMotionThreshold != null) && (this.ccdMotionThreshold = data.ccdMotionThreshold); + (data.ccdSweptSphereRadius != null) && (this.ccdSweptSphereRadius = data.ccdSweptSphereRadius); + } + _setTransformFlag(type, value) { + if (value) + this._transformFlag |= type; + else + this._transformFlag &= ~type; + } + _getTransformFlag(type) { + return (this._transformFlag & type) != 0; + } + _addToSimulation() { + } + _removeFromSimulation() { + } + _derivePhysicsTransformation(force) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var btColliderObject = this._btColliderObject; + var btTransform = bt.btCollisionObject_getWorldTransform(btColliderObject); + this._innerDerivePhysicsTransformation(btTransform, force); + bt.btCollisionObject_setWorldTransform(btColliderObject, btTransform); + } + _innerDerivePhysicsTransformation(physicTransformOut, force) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var transform = this.owner._transform; + if (force || this._getTransformFlag(Laya.Transform3D.TRANSFORM_WORLDPOSITION)) { + var shapeOffset = this._colliderShape.localOffset; + var position = transform.position; + var btPosition = PhysicsComponent._btVector30; + if (shapeOffset.x !== 0 || shapeOffset.y !== 0 || shapeOffset.z !== 0) { + var physicPosition = PhysicsComponent._tempVector30; + var worldMat = transform.worldMatrix; + Laya.Vector3.transformCoordinate(shapeOffset, worldMat, physicPosition); + bt.btVector3_setValue(btPosition, -physicPosition.x, physicPosition.y, physicPosition.z); + } + else { + bt.btVector3_setValue(btPosition, -position.x, position.y, position.z); + } + bt.btTransform_setOrigin(physicTransformOut, btPosition); + this._setTransformFlag(Laya.Transform3D.TRANSFORM_WORLDPOSITION, false); + } + if (force || this._getTransformFlag(Laya.Transform3D.TRANSFORM_WORLDQUATERNION)) { + var shapeRotation = this._colliderShape.localRotation; + var btRotation = PhysicsComponent._btQuaternion0; + var rotation = transform.rotation; + if (shapeRotation.x !== 0 || shapeRotation.y !== 0 || shapeRotation.z !== 0 || shapeRotation.w !== 1) { + var physicRotation = PhysicsComponent._tempQuaternion0; + PhysicsComponent.physicQuaternionMultiply(rotation.x, rotation.y, rotation.z, rotation.w, shapeRotation, physicRotation); + bt.btQuaternion_setValue(btRotation, -physicRotation.x, physicRotation.y, physicRotation.z, -physicRotation.w); + } + else { + bt.btQuaternion_setValue(btRotation, -rotation.x, rotation.y, rotation.z, -rotation.w); + } + bt.btTransform_setRotation(physicTransformOut, btRotation); + this._setTransformFlag(Laya.Transform3D.TRANSFORM_WORLDQUATERNION, false); + } + if (force || this._getTransformFlag(Laya.Transform3D.TRANSFORM_WORLDSCALE)) { + this._onScaleChange(transform.getWorldLossyScale()); + this._setTransformFlag(Laya.Transform3D.TRANSFORM_WORLDSCALE, false); + } + } + _updateTransformComponent(physicsTransform) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var colliderShape = this._colliderShape; + var localOffset = colliderShape.localOffset; + var localRotation = colliderShape.localRotation; + var transform = this.owner._transform; + var position = transform.position; + var rotation = transform.rotation; + var btPosition = bt.btTransform_getOrigin(physicsTransform); + var btRotation = bt.btTransform_getRotation(physicsTransform); + var btRotX = -bt.btQuaternion_x(btRotation); + var btRotY = bt.btQuaternion_y(btRotation); + var btRotZ = bt.btQuaternion_z(btRotation); + var btRotW = -bt.btQuaternion_w(btRotation); + if (localRotation.x !== 0 || localRotation.y !== 0 || localRotation.z !== 0 || localRotation.w !== 1) { + var invertShapeRotaion = PhysicsComponent._tempQuaternion0; + localRotation.invert(invertShapeRotaion); + PhysicsComponent.physicQuaternionMultiply(btRotX, btRotY, btRotZ, btRotW, invertShapeRotaion, rotation); + } + else { + rotation.x = btRotX; + rotation.y = btRotY; + rotation.z = btRotZ; + rotation.w = btRotW; + } + transform.rotation = rotation; + if (localOffset.x !== 0 || localOffset.y !== 0 || localOffset.z !== 0) { + var btScale = bt.btCollisionShape_getLocalScaling(colliderShape._btShape); + var rotShapePosition = PhysicsComponent._tempVector30; + rotShapePosition.x = localOffset.x * bt.btVector3_x(btScale); + rotShapePosition.y = localOffset.y * bt.btVector3_y(btScale); + rotShapePosition.z = localOffset.z * bt.btVector3_z(btScale); + Laya.Vector3.transformQuat(rotShapePosition, rotation, rotShapePosition); + position.x = -bt.btVector3_x(btPosition) - rotShapePosition.x; + position.y = bt.btVector3_y(btPosition) - rotShapePosition.y; + position.z = bt.btVector3_z(btPosition) - rotShapePosition.z; + } + else { + position.x = -bt.btVector3_x(btPosition); + position.y = bt.btVector3_y(btPosition); + position.z = bt.btVector3_z(btPosition); + } + transform.position = position; + } + _onShapeChange(colShape) { + var btColObj = this._btColliderObject; + var bt = Laya.ILaya3D.Physics3D._bullet; + var flags = bt.btCollisionObject_getCollisionFlags(btColObj); + if (colShape.needsCustomCollisionCallback) { + if ((flags & PhysicsComponent.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK) === 0) + bt.btCollisionObject_setCollisionFlags(btColObj, flags | PhysicsComponent.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK); + } + else { + if ((flags & PhysicsComponent.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK) > 0) + bt.btCollisionObject_setCollisionFlags(btColObj, flags ^ PhysicsComponent.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK); + } + } + _onAdded() { + this.enabled = this._enabled; + this.restitution = this._restitution; + this.friction = this._friction; + this.rollingFriction = this._rollingFriction; + this.ccdMotionThreshold = this._ccdMotionThreshold; + this.ccdSweptSphereRadius = this._ccdSweptSphereRadius; + this.owner.transform.on(Laya.Event.TRANSFORM_CHANGED, this, this._onTransformChanged); + } + _onTransformChanged(flag) { + if (PhysicsComponent._addUpdateList || !this._controlBySimulation) { + flag &= Laya.Transform3D.TRANSFORM_WORLDPOSITION | Laya.Transform3D.TRANSFORM_WORLDQUATERNION | Laya.Transform3D.TRANSFORM_WORLDSCALE; + if (flag) { + this._transformFlag |= flag; + if (this._isValid() && this._inPhysicUpdateListIndex === -1) + this._simulation._physicsUpdateList.add(this); + } + } + } + _cloneTo(dest) { + var destPhysicsComponent = dest; + destPhysicsComponent.restitution = this._restitution; + destPhysicsComponent.friction = this._friction; + destPhysicsComponent.rollingFriction = this._rollingFriction; + destPhysicsComponent.ccdMotionThreshold = this._ccdMotionThreshold; + destPhysicsComponent.ccdSweptSphereRadius = this._ccdSweptSphereRadius; + destPhysicsComponent.collisionGroup = this._collisionGroup; + destPhysicsComponent.canCollideWith = this._canCollideWith; + destPhysicsComponent.canScaleShape = this.canScaleShape; + (this._colliderShape) && (destPhysicsComponent.colliderShape = this._colliderShape.clone()); + } + } + PhysicsComponent.ACTIVATIONSTATE_ACTIVE_TAG = 1; + PhysicsComponent.ACTIVATIONSTATE_ISLAND_SLEEPING = 2; + PhysicsComponent.ACTIVATIONSTATE_WANTS_DEACTIVATION = 3; + PhysicsComponent.ACTIVATIONSTATE_DISABLE_DEACTIVATION = 4; + PhysicsComponent.ACTIVATIONSTATE_DISABLE_SIMULATION = 5; + PhysicsComponent.COLLISIONFLAGS_STATIC_OBJECT = 1; + PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT = 2; + PhysicsComponent.COLLISIONFLAGS_NO_CONTACT_RESPONSE = 4; + PhysicsComponent.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK = 8; + PhysicsComponent.COLLISIONFLAGS_CHARACTER_OBJECT = 16; + PhysicsComponent.COLLISIONFLAGS_DISABLE_VISUALIZE_OBJECT = 32; + PhysicsComponent.COLLISIONFLAGS_DISABLE_SPU_COLLISION_PROCESSING = 64; + PhysicsComponent._tempVector30 = new Laya.Vector3(); + PhysicsComponent._tempQuaternion0 = new Laya.Quaternion(); + PhysicsComponent._tempQuaternion1 = new Laya.Quaternion(); + PhysicsComponent._tempMatrix4x40 = new Laya.Matrix4x4(); + PhysicsComponent._physicObjectsMap = {}; + PhysicsComponent._addUpdateList = true; + + class BulletInteractive { + } + BulletInteractive._interactive = { + "getWorldTransform": (rigidBodyID, worldTransPointer) => { + }, + "setWorldTransform": (rigidBodyID, worldTransPointer) => { + var rigidBody = PhysicsComponent._physicObjectsMap[rigidBodyID]; + rigidBody._simulation._updatedRigidbodies++; + rigidBody._updateTransformComponent(worldTransPointer); + } + }; + + class CharacterController extends PhysicsComponent { + constructor(stepheight = 0.1, upAxis = null, collisionGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER, canCollideWith = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + super(collisionGroup, canCollideWith); + this._upAxis = new Laya.Vector3(0, 1, 0); + this._maxSlope = 45.0; + this._jumpSpeed = 10.0; + this._fallSpeed = 55.0; + this._gravity = new Laya.Vector3(0, -9.8 * 3, 0); + this._btKinematicCharacter = null; + this._stepHeight = stepheight; + (upAxis) && (this._upAxis = upAxis); + this._controlBySimulation = true; + } + static __init__() { + CharacterController._btTempVector30 = Laya.ILaya3D.Physics3D._bullet.btVector3_create(0, 0, 0); + } + get fallSpeed() { + return this._fallSpeed; + } + set fallSpeed(value) { + this._fallSpeed = value; + Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setFallSpeed(this._btKinematicCharacter, value); + } + get jumpSpeed() { + return this._jumpSpeed; + } + set jumpSpeed(value) { + this._jumpSpeed = value; + Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setJumpSpeed(this._btKinematicCharacter, value); + } + get gravity() { + return this._gravity; + } + set gravity(value) { + this._gravity = value; + var bt = Laya.ILaya3D.Physics3D._bullet; + var btGravity = CharacterController._btTempVector30; + bt.btVector3_setValue(btGravity, -value.x, value.y, value.z); + bt.btKinematicCharacterController_setGravity(this._btKinematicCharacter, btGravity); + } + get maxSlope() { + return this._maxSlope; + } + set maxSlope(value) { + this._maxSlope = value; + Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setMaxSlope(this._btKinematicCharacter, (value / 180) * Math.PI); + } + get isGrounded() { + return Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_onGround(this._btKinematicCharacter); + } + get stepHeight() { + return this._stepHeight; + } + set stepHeight(value) { + this._stepHeight = value; + Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setStepHeight(this._btKinematicCharacter, value); + } + get upAxis() { + return this._upAxis; + } + set upAxis(value) { + this._upAxis = value; + var btUpAxis = CharacterController._btTempVector30; + Laya.Utils3D._convertToBulletVec3(value, btUpAxis, false); + Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setUp(this._btKinematicCharacter, btUpAxis); + } + _constructCharacter() { + var bt = Laya.ILaya3D.Physics3D._bullet; + if (this._btKinematicCharacter) + bt.btKinematicCharacterController_destroy(this._btKinematicCharacter); + var btUpAxis = CharacterController._btTempVector30; + bt.btVector3_setValue(btUpAxis, this._upAxis.x, this._upAxis.y, this._upAxis.z); + this._btKinematicCharacter = bt.btKinematicCharacterController_create(this._btColliderObject, this._colliderShape._btShape, this._stepHeight, btUpAxis); + this.fallSpeed = this._fallSpeed; + this.maxSlope = this._maxSlope; + this.jumpSpeed = this._jumpSpeed; + this.gravity = this._gravity; + } + _onShapeChange(colShape) { + super._onShapeChange(colShape); + this._constructCharacter(); + } + _onAdded() { + var bt = Laya.ILaya3D.Physics3D._bullet; + var ghostObject = bt.btPairCachingGhostObject_create(); + bt.btCollisionObject_setUserIndex(ghostObject, this.id); + bt.btCollisionObject_setCollisionFlags(ghostObject, PhysicsComponent.COLLISIONFLAGS_CHARACTER_OBJECT); + this._btColliderObject = ghostObject; + (this._colliderShape) && (this._constructCharacter()); + super._onAdded(); + } + _addToSimulation() { + this._simulation._characters.push(this); + this._simulation._addCharacter(this, this._collisionGroup, this._canCollideWith); + } + _removeFromSimulation() { + this._simulation._removeCharacter(this); + var characters = this._simulation._characters; + characters.splice(characters.indexOf(this), 1); + } + _cloneTo(dest) { + super._cloneTo(dest); + var destCharacterController = dest; + destCharacterController.stepHeight = this._stepHeight; + destCharacterController.upAxis = this._upAxis; + destCharacterController.maxSlope = this._maxSlope; + destCharacterController.jumpSpeed = this._jumpSpeed; + destCharacterController.fallSpeed = this._fallSpeed; + destCharacterController.gravity = this._gravity; + } + _onDestroy() { + Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_destroy(this._btKinematicCharacter); + super._onDestroy(); + this._btKinematicCharacter = null; + } + move(movement) { + var btMovement = CharacterController._btVector30; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(btMovement, -movement.x, movement.y, movement.z); + bt.btKinematicCharacterController_setWalkDirection(this._btKinematicCharacter, btMovement); + } + jump(velocity = null) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var btVelocity = CharacterController._btVector30; + if (velocity) { + Laya.Utils3D._convertToBulletVec3(velocity, btVelocity, true); + bt.btKinematicCharacterController_jump(this._btKinematicCharacter, btVelocity); + } + else { + bt.btVector3_setValue(btVelocity, 0, 0, 0); + bt.btKinematicCharacterController_jump(this._btKinematicCharacter, btVelocity); + } + } + } + CharacterController.UPAXIS_X = 0; + CharacterController.UPAXIS_Y = 1; + CharacterController.UPAXIS_Z = 2; + + class Collision { + constructor() { + this._lastUpdateFrame = -2147483648; + this._updateFrame = -2147483648; + this._isTrigger = false; + this.contacts = []; + } + _setUpdateFrame(farme) { + this._lastUpdateFrame = this._updateFrame; + this._updateFrame = farme; + } + } + + class ContactPoint { + constructor() { + this._idCounter = 0; + this.colliderA = null; + this.colliderB = null; + this.distance = 0; + this.normal = new Laya.Vector3(); + this.positionOnA = new Laya.Vector3(); + this.positionOnB = new Laya.Vector3(); + this._id = ++this._idCounter; + } + } + + class HitResult { + constructor() { + this.succeeded = false; + this.collider = null; + this.point = new Laya.Vector3(); + this.normal = new Laya.Vector3(); + this.hitFraction = 0; + } + } + + class CollisionTool { + constructor() { + this._hitResultsPoolIndex = 0; + this._hitResultsPool = []; + this._contactPonintsPoolIndex = 0; + this._contactPointsPool = []; + this._collisionsPool = []; + this._collisions = {}; + } + getHitResult() { + var hitResult = this._hitResultsPool[this._hitResultsPoolIndex++]; + if (!hitResult) { + hitResult = new HitResult(); + this._hitResultsPool.push(hitResult); + } + return hitResult; + } + recoverAllHitResultsPool() { + this._hitResultsPoolIndex = 0; + } + getContactPoints() { + var contactPoint = this._contactPointsPool[this._contactPonintsPoolIndex++]; + if (!contactPoint) { + contactPoint = new ContactPoint(); + this._contactPointsPool.push(contactPoint); + } + return contactPoint; + } + recoverAllContactPointsPool() { + this._contactPonintsPoolIndex = 0; + } + getCollision(physicComponentA, physicComponentB) { + var collision; + var idA = physicComponentA.id; + var idB = physicComponentB.id; + var subCollisionFirst = this._collisions[idA]; + if (subCollisionFirst) + collision = subCollisionFirst[idB]; + if (!collision) { + if (!subCollisionFirst) { + subCollisionFirst = {}; + this._collisions[idA] = subCollisionFirst; + } + collision = this._collisionsPool.length === 0 ? new Collision() : this._collisionsPool.pop(); + collision._colliderA = physicComponentA; + collision._colliderB = physicComponentB; + subCollisionFirst[idB] = collision; + } + return collision; + } + recoverCollision(collision) { + var idA = collision._colliderA.id; + var idB = collision._colliderB.id; + this._collisions[idA][idB] = null; + this._collisionsPool.push(collision); + } + garbageCollection() { + this._hitResultsPoolIndex = 0; + this._hitResultsPool.length = 0; + this._contactPonintsPoolIndex = 0; + this._contactPointsPool.length = 0; + this._collisionsPool.length = 0; + for (var subCollisionsKey in this._collisionsPool) { + var subCollisions = this._collisionsPool[subCollisionsKey]; + var wholeDelete = true; + for (var collisionKey in subCollisions) { + if (subCollisions[collisionKey]) + wholeDelete = false; + else + delete subCollisions[collisionKey]; + } + if (wholeDelete) + delete this._collisionsPool[subCollisionsKey]; + } + } + } + + class Constraint3D { + constructor() { + } + } + + class PhysicsTriggerComponent extends PhysicsComponent { + constructor(collisionGroup, canCollideWith) { + super(collisionGroup, canCollideWith); + this._isTrigger = false; + } + get isTrigger() { + return this._isTrigger; + } + set isTrigger(value) { + this._isTrigger = value; + var bt = Laya.ILaya3D.Physics3D._bullet; + if (this._btColliderObject) { + var flags = bt.btCollisionObject_getCollisionFlags(this._btColliderObject); + if (value) { + if ((flags & PhysicsComponent.COLLISIONFLAGS_NO_CONTACT_RESPONSE) === 0) + bt.btCollisionObject_setCollisionFlags(this._btColliderObject, flags | PhysicsComponent.COLLISIONFLAGS_NO_CONTACT_RESPONSE); + } + else { + if ((flags & PhysicsComponent.COLLISIONFLAGS_NO_CONTACT_RESPONSE) !== 0) + bt.btCollisionObject_setCollisionFlags(this._btColliderObject, flags ^ PhysicsComponent.COLLISIONFLAGS_NO_CONTACT_RESPONSE); + } + } + } + _onAdded() { + super._onAdded(); + this.isTrigger = this._isTrigger; + } + _cloneTo(dest) { + super._cloneTo(dest); + dest.isTrigger = this._isTrigger; + } + } + + class PhysicsCollider extends PhysicsTriggerComponent { + constructor(collisionGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER, canCollideWith = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + super(collisionGroup, canCollideWith); + this._enableProcessCollisions = false; + } + _addToSimulation() { + this._simulation._addPhysicsCollider(this, this._collisionGroup, this._canCollideWith); + } + _removeFromSimulation() { + this._simulation._removePhysicsCollider(this); + } + _parse(data) { + (data.friction != null) && (this.friction = data.friction); + (data.rollingFriction != null) && (this.rollingFriction = data.rollingFriction); + (data.restitution != null) && (this.restitution = data.restitution); + (data.isTrigger != null) && (this.isTrigger = data.isTrigger); + super._parse(data); + this._parseShape(data.shapes); + } + _onAdded() { + var bt = Laya.Physics3D._bullet; + var btColObj = bt.btCollisionObject_create(); + bt.btCollisionObject_setUserIndex(btColObj, this.id); + bt.btCollisionObject_forceActivationState(btColObj, PhysicsComponent.ACTIVATIONSTATE_DISABLE_SIMULATION); + var flags = bt.btCollisionObject_getCollisionFlags(btColObj); + if (this.owner.isStatic) { + if ((flags & PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT) > 0) + flags = flags ^ PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT; + flags = flags | PhysicsComponent.COLLISIONFLAGS_STATIC_OBJECT; + } + else { + if ((flags & PhysicsComponent.COLLISIONFLAGS_STATIC_OBJECT) > 0) + flags = flags ^ PhysicsComponent.COLLISIONFLAGS_STATIC_OBJECT; + flags = flags | PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT; + } + bt.btCollisionObject_setCollisionFlags(btColObj, flags); + this._btColliderObject = btColObj; + super._onAdded(); + } + } + + class PhysicsSettings { + constructor() { + this.flags = 0; + this.maxSubSteps = 1; + this.fixedTimeStep = 1.0 / 60.0; + } + } + + class PhysicsUpdateList extends Laya.SingletonList { + constructor() { + super(); + } + add(element) { + var index = element._inPhysicUpdateListIndex; + if (index !== -1) + throw "PhysicsUpdateList:element has in PhysicsUpdateList."; + this._add(element); + element._inPhysicUpdateListIndex = this.length++; + } + remove(element) { + var index = element._inPhysicUpdateListIndex; + this.length--; + if (index !== this.length) { + var end = this.elements[this.length]; + this.elements[index] = end; + end._inPhysicUpdateListIndex = index; + } + element._inPhysicUpdateListIndex = -1; + } + } + + class PhysicsSimulation { + constructor(configuration) { + this._gravity = new Laya.Vector3(0, -10, 0); + this._btVector3Zero = Laya.ILaya3D.Physics3D._bullet.btVector3_create(0, 0, 0); + this._btDefaultQuaternion = Laya.ILaya3D.Physics3D._bullet.btQuaternion_create(0, 0, 0, -1); + this._collisionsUtils = new CollisionTool(); + this._previousFrameCollisions = []; + this._currentFrameCollisions = []; + this._currentConstraint = {}; + this._physicsUpdateList = new PhysicsUpdateList(); + this._characters = []; + this._updatedRigidbodies = 0; + this.maxSubSteps = 1; + this.fixedTimeStep = 1.0 / 60.0; + this.maxSubSteps = configuration.maxSubSteps; + this.fixedTimeStep = configuration.fixedTimeStep; + var bt = Laya.ILaya3D.Physics3D._bullet; + this._btCollisionConfiguration = bt.btDefaultCollisionConfiguration_create(); + this._btDispatcher = bt.btCollisionDispatcher_create(this._btCollisionConfiguration); + this._btBroadphase = bt.btDbvtBroadphase_create(); + bt.btOverlappingPairCache_setInternalGhostPairCallback(bt.btDbvtBroadphase_getOverlappingPairCache(this._btBroadphase), bt.btGhostPairCallback_create()); + var conFlags = configuration.flags; + if (conFlags & PhysicsSimulation.PHYSICSENGINEFLAGS_COLLISIONSONLY) { + this._btCollisionWorld = new bt.btCollisionWorld(this._btDispatcher, this._btBroadphase, this._btCollisionConfiguration); + } + else if (conFlags & PhysicsSimulation.PHYSICSENGINEFLAGS_SOFTBODYSUPPORT) { + throw "PhysicsSimulation:SoftBody processing is not yet available"; + } + else { + var solver = bt.btSequentialImpulseConstraintSolver_create(); + this._btDiscreteDynamicsWorld = bt.btDiscreteDynamicsWorld_create(this._btDispatcher, this._btBroadphase, solver, this._btCollisionConfiguration); + this._btCollisionWorld = this._btDiscreteDynamicsWorld; + } + if (this._btDiscreteDynamicsWorld) { + this._btSolverInfo = bt.btDynamicsWorld_getSolverInfo(this._btDiscreteDynamicsWorld); + this._btDispatchInfo = bt.btCollisionWorld_getDispatchInfo(this._btDiscreteDynamicsWorld); + } + this._btClosestRayResultCallback = bt.ClosestRayResultCallback_create(this._btVector3Zero, this._btVector3Zero); + this._btAllHitsRayResultCallback = bt.AllHitsRayResultCallback_create(this._btVector3Zero, this._btVector3Zero); + this._btClosestConvexResultCallback = bt.ClosestConvexResultCallback_create(this._btVector3Zero, this._btVector3Zero); + this._btAllConvexResultCallback = bt.AllConvexResultCallback_create(this._btVector3Zero, this._btVector3Zero); + this.setHitsRayResultCallbackFlag(); + bt.btGImpactCollisionAlgorithm_RegisterAlgorithm(this._btDispatcher); + } + static __init__() { + var bt = Laya.ILaya3D.Physics3D._bullet; + PhysicsSimulation._btTempVector30 = bt.btVector3_create(0, 0, 0); + PhysicsSimulation._btTempVector31 = bt.btVector3_create(0, 0, 0); + PhysicsSimulation._btTempQuaternion0 = bt.btQuaternion_create(0, 0, 0, 1); + PhysicsSimulation._btTempQuaternion1 = bt.btQuaternion_create(0, 0, 0, 1); + PhysicsSimulation._btTempTransform0 = bt.btTransform_create(); + PhysicsSimulation._btTempTransform1 = bt.btTransform_create(); + } + static createConstraint() { + } + get continuousCollisionDetection() { + return Laya.ILaya3D.Physics3D._bullet.btCollisionWorld_get_m_useContinuous(this._btDispatchInfo); + } + set continuousCollisionDetection(value) { + Laya.ILaya3D.Physics3D._bullet.btCollisionWorld_set_m_useContinuous(this._btDispatchInfo, value); + } + get gravity() { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + return this._gravity; + } + set gravity(value) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + this._gravity = value; + var bt = Laya.ILaya3D.Physics3D._bullet; + var btGravity = PhysicsSimulation._btTempVector30; + bt.btVector3_setValue(btGravity, -value.x, value.y, value.z); + bt.btDiscreteDynamicsWorld_setGravity(this._btDiscreteDynamicsWorld, btGravity); + } + get speculativeContactRestitution() { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot Cannot perform this action when the physics engine is set to CollisionsOnly"; + return Laya.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_getApplySpeculativeContactRestitution(this._btDiscreteDynamicsWorld); + } + set speculativeContactRestitution(value) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot Cannot perform this action when the physics engine is set to CollisionsOnly"; + Laya.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_setApplySpeculativeContactRestitution(this._btDiscreteDynamicsWorld, value); + } + _simulate(deltaTime) { + this._updatedRigidbodies = 0; + var bt = Laya.ILaya3D.Physics3D._bullet; + if (this._btDiscreteDynamicsWorld) + bt.btDiscreteDynamicsWorld_stepSimulation(this._btDiscreteDynamicsWorld, deltaTime, this.maxSubSteps, this.fixedTimeStep); + else + bt.PerformDiscreteCollisionDetection(this._btCollisionWorld); + } + _destroy() { + var bt = Laya.ILaya3D.Physics3D._bullet; + if (this._btDiscreteDynamicsWorld) { + bt.btCollisionWorld_destroy(this._btDiscreteDynamicsWorld); + this._btDiscreteDynamicsWorld = null; + } + else { + bt.btCollisionWorld_destroy(this._btCollisionWorld); + this._btCollisionWorld = null; + } + bt.btDbvtBroadphase_destroy(this._btBroadphase); + this._btBroadphase = null; + bt.btCollisionDispatcher_destroy(this._btDispatcher); + this._btDispatcher = null; + bt.btDefaultCollisionConfiguration_destroy(this._btCollisionConfiguration); + this._btCollisionConfiguration = null; + } + _addPhysicsCollider(component, group, mask) { + Laya.ILaya3D.Physics3D._bullet.btCollisionWorld_addCollisionObject(this._btCollisionWorld, component._btColliderObject, group, mask); + } + _removePhysicsCollider(component) { + Laya.ILaya3D.Physics3D._bullet.btCollisionWorld_removeCollisionObject(this._btCollisionWorld, component._btColliderObject); + } + _addRigidBody(rigidBody, group, mask) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + Laya.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_addRigidBody(this._btCollisionWorld, rigidBody._btColliderObject, group, mask); + } + _removeRigidBody(rigidBody) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + Laya.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_removeRigidBody(this._btCollisionWorld, rigidBody._btColliderObject); + } + _addCharacter(character, group, mask) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btCollisionWorld_addCollisionObject(this._btCollisionWorld, character._btColliderObject, group, mask); + bt.btDynamicsWorld_addAction(this._btCollisionWorld, character._btKinematicCharacter); + } + _removeCharacter(character) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btCollisionWorld_removeCollisionObject(this._btCollisionWorld, character._btColliderObject); + bt.btDynamicsWorld_removeAction(this._btCollisionWorld, character._btKinematicCharacter); + } + raycastFromTo(from, to, out = null, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var rayResultCall = this._btClosestRayResultCallback; + var rayFrom = PhysicsSimulation._btTempVector30; + var rayTo = PhysicsSimulation._btTempVector31; + bt.btVector3_setValue(rayFrom, -from.x, from.y, from.z); + bt.btVector3_setValue(rayTo, -to.x, to.y, to.z); + bt.ClosestRayResultCallback_set_m_rayFromWorld(rayResultCall, rayFrom); + bt.ClosestRayResultCallback_set_m_rayToWorld(rayResultCall, rayTo); + bt.RayResultCallback_set_m_collisionFilterGroup(rayResultCall, collisonGroup); + bt.RayResultCallback_set_m_collisionFilterMask(rayResultCall, collisionMask); + bt.RayResultCallback_set_m_collisionObject(rayResultCall, null); + bt.RayResultCallback_set_m_closestHitFraction(rayResultCall, 1); + bt.btCollisionWorld_rayTest(this._btCollisionWorld, rayFrom, rayTo, rayResultCall); + if (bt.RayResultCallback_hasHit(rayResultCall)) { + if (out) { + out.succeeded = true; + out.collider = PhysicsComponent._physicObjectsMap[bt.btCollisionObject_getUserIndex(bt.RayResultCallback_get_m_collisionObject(rayResultCall))]; + out.hitFraction = bt.RayResultCallback_get_m_closestHitFraction(rayResultCall); + var btPoint = bt.ClosestRayResultCallback_get_m_hitPointWorld(rayResultCall); + var point = out.point; + point.x = -bt.btVector3_x(btPoint); + point.y = bt.btVector3_y(btPoint); + point.z = bt.btVector3_z(btPoint); + var btNormal = bt.ClosestRayResultCallback_get_m_hitNormalWorld(rayResultCall); + var normal = out.normal; + normal.x = -bt.btVector3_x(btNormal); + normal.y = bt.btVector3_y(btNormal); + normal.z = bt.btVector3_z(btNormal); + } + return true; + } + else { + if (out) + out.succeeded = false; + return false; + } + } + raycastAllFromTo(from, to, out, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var rayResultCall = this._btAllHitsRayResultCallback; + var rayFrom = PhysicsSimulation._btTempVector30; + var rayTo = PhysicsSimulation._btTempVector31; + out.length = 0; + bt.btVector3_setValue(rayFrom, -from.x, from.y, from.z); + bt.btVector3_setValue(rayTo, -to.x, to.y, to.z); + bt.AllHitsRayResultCallback_set_m_rayFromWorld(rayResultCall, rayFrom); + bt.AllHitsRayResultCallback_set_m_rayToWorld(rayResultCall, rayTo); + bt.RayResultCallback_set_m_collisionFilterGroup(rayResultCall, collisonGroup); + bt.RayResultCallback_set_m_collisionFilterMask(rayResultCall, collisionMask); + var collisionObjects = bt.AllHitsRayResultCallback_get_m_collisionObjects(rayResultCall); + var btPoints = bt.AllHitsRayResultCallback_get_m_hitPointWorld(rayResultCall); + var btNormals = bt.AllHitsRayResultCallback_get_m_hitNormalWorld(rayResultCall); + var btFractions = bt.AllHitsRayResultCallback_get_m_hitFractions(rayResultCall); + bt.tBtCollisionObjectArray_clear(collisionObjects); + bt.tVector3Array_clear(btPoints); + bt.tVector3Array_clear(btNormals); + bt.tScalarArray_clear(btFractions); + bt.btCollisionWorld_rayTest(this._btCollisionWorld, rayFrom, rayTo, rayResultCall); + var count = bt.tBtCollisionObjectArray_size(collisionObjects); + if (count > 0) { + this._collisionsUtils.recoverAllHitResultsPool(); + for (var i = 0; i < count; i++) { + var hitResult = this._collisionsUtils.getHitResult(); + out.push(hitResult); + hitResult.succeeded = true; + hitResult.collider = PhysicsComponent._physicObjectsMap[bt.btCollisionObject_getUserIndex(bt.tBtCollisionObjectArray_at(collisionObjects, i))]; + hitResult.hitFraction = bt.tScalarArray_at(btFractions, i); + var btPoint = bt.tVector3Array_at(btPoints, i); + var pointE = hitResult.point; + pointE.x = -bt.btVector3_x(btPoint); + pointE.y = bt.btVector3_y(btPoint); + pointE.z = bt.btVector3_z(btPoint); + var btNormal = bt.tVector3Array_at(btNormals, i); + var normal = hitResult.normal; + normal.x = -bt.btVector3_x(btNormal); + normal.y = bt.btVector3_y(btNormal); + normal.z = bt.btVector3_z(btNormal); + } + return true; + } + else { + return false; + } + } + rayCast(ray, outHitResult = null, distance = 2147483647, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + var from = ray.origin; + var to = PhysicsSimulation._tempVector30; + Laya.Vector3.normalize(ray.direction, to); + Laya.Vector3.scale(to, distance, to); + Laya.Vector3.add(from, to, to); + return this.raycastFromTo(from, to, outHitResult, collisonGroup, collisionMask); + } + rayCastAll(ray, out, distance = 2147483647, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + var from = ray.origin; + var to = PhysicsSimulation._tempVector30; + Laya.Vector3.normalize(ray.direction, to); + Laya.Vector3.scale(to, distance, to); + Laya.Vector3.add(from, to, to); + return this.raycastAllFromTo(from, to, out, collisonGroup, collisionMask); + } + shapeCast(shape, fromPosition, toPosition, out = null, fromRotation = null, toRotation = null, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, allowedCcdPenetration = 0.0) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var convexResultCall = this._btClosestConvexResultCallback; + var convexPosFrom = PhysicsSimulation._btTempVector30; + var convexPosTo = PhysicsSimulation._btTempVector31; + var convexRotFrom = PhysicsSimulation._btTempQuaternion0; + var convexRotTo = PhysicsSimulation._btTempQuaternion1; + var convexTransform = PhysicsSimulation._btTempTransform0; + var convexTransTo = PhysicsSimulation._btTempTransform1; + var sweepShape = shape._btShape; + bt.btVector3_setValue(convexPosFrom, -fromPosition.x, fromPosition.y, fromPosition.z); + bt.btVector3_setValue(convexPosTo, -toPosition.x, toPosition.y, toPosition.z); + bt.ConvexResultCallback_set_m_collisionFilterGroup(convexResultCall, collisonGroup); + bt.ConvexResultCallback_set_m_collisionFilterMask(convexResultCall, collisionMask); + bt.btTransform_setOrigin(convexTransform, convexPosFrom); + bt.btTransform_setOrigin(convexTransTo, convexPosTo); + if (fromRotation) { + bt.btQuaternion_setValue(convexRotFrom, -fromRotation.x, fromRotation.y, fromRotation.z, -fromRotation.w); + bt.btTransform_setRotation(convexTransform, convexRotFrom); + } + else { + bt.btTransform_setRotation(convexTransform, this._btDefaultQuaternion); + } + if (toRotation) { + bt.btQuaternion_setValue(convexRotTo, -toRotation.x, toRotation.y, toRotation.z, -toRotation.w); + bt.btTransform_setRotation(convexTransTo, convexRotTo); + } + else { + bt.btTransform_setRotation(convexTransTo, this._btDefaultQuaternion); + } + bt.ClosestConvexResultCallback_set_m_hitCollisionObject(convexResultCall, null); + bt.ConvexResultCallback_set_m_closestHitFraction(convexResultCall, 1); + bt.btCollisionWorld_convexSweepTest(this._btCollisionWorld, sweepShape, convexTransform, convexTransTo, convexResultCall, allowedCcdPenetration); + if (bt.ConvexResultCallback_hasHit(convexResultCall)) { + if (out) { + out.succeeded = true; + out.collider = PhysicsComponent._physicObjectsMap[bt.btCollisionObject_getUserIndex(bt.ClosestConvexResultCallback_get_m_hitCollisionObject(convexResultCall))]; + out.hitFraction = bt.ConvexResultCallback_get_m_closestHitFraction(convexResultCall); + var btPoint = bt.ClosestConvexResultCallback_get_m_hitPointWorld(convexResultCall); + var btNormal = bt.ClosestConvexResultCallback_get_m_hitNormalWorld(convexResultCall); + var point = out.point; + var normal = out.normal; + point.x = -bt.btVector3_x(btPoint); + point.y = bt.btVector3_y(btPoint); + point.z = bt.btVector3_z(btPoint); + normal.x = -bt.btVector3_x(btNormal); + normal.y = bt.btVector3_y(btNormal); + normal.z = bt.btVector3_z(btNormal); + } + return true; + } + else { + if (out) + out.succeeded = false; + return false; + } + } + shapeCastAll(shape, fromPosition, toPosition, out, fromRotation = null, toRotation = null, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, allowedCcdPenetration = 0.0) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var convexResultCall = this._btAllConvexResultCallback; + var convexPosFrom = PhysicsSimulation._btTempVector30; + var convexPosTo = PhysicsSimulation._btTempVector31; + var convexRotFrom = PhysicsSimulation._btTempQuaternion0; + var convexRotTo = PhysicsSimulation._btTempQuaternion1; + var convexTransform = PhysicsSimulation._btTempTransform0; + var convexTransTo = PhysicsSimulation._btTempTransform1; + var sweepShape = shape._btShape; + out.length = 0; + bt.btVector3_setValue(convexPosFrom, -fromPosition.x, fromPosition.y, fromPosition.z); + bt.btVector3_setValue(convexPosTo, -toPosition.x, toPosition.y, toPosition.z); + bt.ConvexResultCallback_set_m_collisionFilterGroup(convexResultCall, collisonGroup); + bt.ConvexResultCallback_set_m_collisionFilterMask(convexResultCall, collisionMask); + bt.btTransform_setOrigin(convexTransform, convexPosFrom); + bt.btTransform_setOrigin(convexTransTo, convexPosTo); + if (fromRotation) { + bt.btQuaternion_setValue(convexRotFrom, -fromRotation.x, fromRotation.y, fromRotation.z, -fromRotation.w); + bt.btTransform_setRotation(convexTransform, convexRotFrom); + } + else { + bt.btTransform_setRotation(convexTransform, this._btDefaultQuaternion); + } + if (toRotation) { + bt.btQuaternion_setValue(convexRotTo, -toRotation.x, toRotation.y, toRotation.z, -toRotation.w); + bt.btTransform_setRotation(convexTransTo, convexRotTo); + } + else { + bt.btTransform_setRotation(convexTransTo, this._btDefaultQuaternion); + } + var collisionObjects = bt.AllConvexResultCallback_get_m_collisionObjects(convexResultCall); + var btPoints = bt.AllConvexResultCallback_get_m_hitPointWorld(convexResultCall); + var btNormals = bt.AllConvexResultCallback_get_m_hitNormalWorld(convexResultCall); + var btFractions = bt.AllConvexResultCallback_get_m_hitFractions(convexResultCall); + bt.tVector3Array_clear(btPoints); + bt.tVector3Array_clear(btNormals); + bt.tScalarArray_clear(btFractions); + bt.tBtCollisionObjectArray_clear(collisionObjects); + bt.btCollisionWorld_convexSweepTest(this._btCollisionWorld, sweepShape, convexTransform, convexTransTo, convexResultCall, allowedCcdPenetration); + var count = bt.tBtCollisionObjectArray_size(collisionObjects); + if (count > 0) { + this._collisionsUtils.recoverAllHitResultsPool(); + for (var i = 0; i < count; i++) { + var hitResult = this._collisionsUtils.getHitResult(); + out.push(hitResult); + hitResult.succeeded = true; + hitResult.collider = PhysicsComponent._physicObjectsMap[bt.btCollisionObject_getUserIndex(bt.tBtCollisionObjectArray_at(collisionObjects, i))]; + hitResult.hitFraction = bt.tScalarArray_at(btFractions, i); + var btPoint = bt.tVector3Array_at(btPoints, i); + var point = hitResult.point; + point.x = -bt.btVector3_x(btPoint); + point.y = bt.btVector3_y(btPoint); + point.z = bt.btVector3_z(btPoint); + var btNormal = bt.tVector3Array_at(btNormals, i); + var normal = hitResult.normal; + normal.x = -bt.btVector3_x(btNormal); + normal.y = bt.btVector3_y(btNormal); + normal.z = bt.btVector3_z(btNormal); + } + return true; + } + else { + return false; + } + } + addConstraint(constraint, disableCollisionsBetweenLinkedBodies = false) { + if (!this._btDiscreteDynamicsWorld) + throw "Cannot perform this action when the physics engine is set to CollisionsOnly"; + Laya.ILaya3D.Physics3D._bullet.btCollisionWorld_addConstraint(this._btDiscreteDynamicsWorld, constraint._btConstraint, disableCollisionsBetweenLinkedBodies); + this._currentConstraint[constraint.id] = constraint; + } + removeConstraint(constraint) { + if (!this._btDiscreteDynamicsWorld) + throw "Cannot perform this action when the physics engine is set to CollisionsOnly"; + Laya.ILaya3D.Physics3D._bullet.btCollisionWorld_removeConstraint(this._btDiscreteDynamicsWorld, constraint._btConstraint); + delete this._currentConstraint[constraint.id]; + } + setHitsRayResultCallbackFlag(flag = 1) { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.RayResultCallback_set_m_flags(this._btAllHitsRayResultCallback, flag); + bt.RayResultCallback_set_m_flags(this._btClosestRayResultCallback, flag); + } + _updatePhysicsTransformFromRender() { + var elements = this._physicsUpdateList.elements; + for (var i = 0, n = this._physicsUpdateList.length; i < n; i++) { + var physicCollider = elements[i]; + physicCollider._derivePhysicsTransformation(false); + physicCollider._inPhysicUpdateListIndex = -1; + } + this._physicsUpdateList.length = 0; + } + _updateCharacters() { + for (var i = 0, n = this._characters.length; i < n; i++) { + var character = this._characters[i]; + character._updateTransformComponent(Laya.ILaya3D.Physics3D._bullet.btCollisionObject_getWorldTransform(character._btColliderObject)); + } + } + _updateCollisions() { + this._collisionsUtils.recoverAllContactPointsPool(); + var previous = this._currentFrameCollisions; + this._currentFrameCollisions = this._previousFrameCollisions; + this._currentFrameCollisions.length = 0; + this._previousFrameCollisions = previous; + var loopCount = Laya.Stat.loopCount; + var bt = Laya.ILaya3D.Physics3D._bullet; + var numManifolds = bt.btDispatcher_getNumManifolds(this._btDispatcher); + for (var i = 0; i < numManifolds; i++) { + var contactManifold = bt.btDispatcher_getManifoldByIndexInternal(this._btDispatcher, i); + var componentA = PhysicsComponent._physicObjectsMap[bt.btCollisionObject_getUserIndex(bt.btPersistentManifold_getBody0(contactManifold))]; + var componentB = PhysicsComponent._physicObjectsMap[bt.btCollisionObject_getUserIndex(bt.btPersistentManifold_getBody1(contactManifold))]; + var collision = null; + var isFirstCollision; + var contacts = null; + var isTrigger = componentA.isTrigger || componentB.isTrigger; + if (isTrigger && (componentA.owner._needProcessTriggers || componentB.owner._needProcessTriggers)) { + var numContacts = bt.btPersistentManifold_getNumContacts(contactManifold); + for (var j = 0; j < numContacts; j++) { + var pt = bt.btPersistentManifold_getContactPoint(contactManifold, j); + var distance = bt.btManifoldPoint_getDistance(pt); + if (distance <= 0) { + collision = this._collisionsUtils.getCollision(componentA, componentB); + contacts = collision.contacts; + isFirstCollision = collision._updateFrame !== loopCount; + if (isFirstCollision) { + collision._isTrigger = true; + contacts.length = 0; + } + break; + } + } + } + else if (componentA.owner._needProcessCollisions || componentB.owner._needProcessCollisions) { + if (componentA._enableProcessCollisions || componentB._enableProcessCollisions) { + numContacts = bt.btPersistentManifold_getNumContacts(contactManifold); + for (j = 0; j < numContacts; j++) { + pt = bt.btPersistentManifold_getContactPoint(contactManifold, j); + distance = bt.btManifoldPoint_getDistance(pt); + if (distance <= 0) { + var contactPoint = this._collisionsUtils.getContactPoints(); + contactPoint.colliderA = componentA; + contactPoint.colliderB = componentB; + contactPoint.distance = distance; + var btNormal = bt.btManifoldPoint_get_m_normalWorldOnB(pt); + var normal = contactPoint.normal; + normal.x = -bt.btVector3_x(btNormal); + normal.y = bt.btVector3_y(btNormal); + normal.z = bt.btVector3_z(btNormal); + var btPostionA = bt.btManifoldPoint_get_m_positionWorldOnA(pt); + var positionOnA = contactPoint.positionOnA; + positionOnA.x = -bt.btVector3_x(btPostionA); + positionOnA.y = bt.btVector3_y(btPostionA); + positionOnA.z = bt.btVector3_z(btPostionA); + var btPostionB = bt.btManifoldPoint_get_m_positionWorldOnB(pt); + var positionOnB = contactPoint.positionOnB; + positionOnB.x = -bt.btVector3_x(btPostionB); + positionOnB.y = bt.btVector3_y(btPostionB); + positionOnB.z = bt.btVector3_z(btPostionB); + if (!collision) { + collision = this._collisionsUtils.getCollision(componentA, componentB); + contacts = collision.contacts; + isFirstCollision = collision._updateFrame !== loopCount; + if (isFirstCollision) { + collision._isTrigger = false; + contacts.length = 0; + } + } + contacts.push(contactPoint); + } + } + } + } + if (collision && isFirstCollision) { + this._currentFrameCollisions.push(collision); + collision._setUpdateFrame(loopCount); + } + } + } + _eventScripts() { + var loopCount = Laya.Stat.loopCount; + for (var i = 0, n = this._currentFrameCollisions.length; i < n; i++) { + var curFrameCol = this._currentFrameCollisions[i]; + var colliderA = curFrameCol._colliderA; + var colliderB = curFrameCol._colliderB; + if (colliderA.destroyed || colliderB.destroyed) + continue; + if (loopCount - curFrameCol._lastUpdateFrame === 1) { + var ownerA = colliderA.owner; + var scriptsA = ownerA._scripts; + if (scriptsA) { + if (curFrameCol._isTrigger) { + if (ownerA._needProcessTriggers) { + for (var j = 0, m = scriptsA.length; j < m; j++) + scriptsA[j].onTriggerStay(colliderB); + } + } + else { + if (ownerA._needProcessCollisions) { + for (j = 0, m = scriptsA.length; j < m; j++) { + curFrameCol.other = colliderB; + scriptsA[j].onCollisionStay(curFrameCol); + } + } + } + } + var ownerB = colliderB.owner; + var scriptsB = ownerB._scripts; + if (scriptsB) { + if (curFrameCol._isTrigger) { + if (ownerB._needProcessTriggers) { + for (j = 0, m = scriptsB.length; j < m; j++) + scriptsB[j].onTriggerStay(colliderA); + } + } + else { + if (ownerB._needProcessCollisions) { + for (j = 0, m = scriptsB.length; j < m; j++) { + curFrameCol.other = colliderA; + scriptsB[j].onCollisionStay(curFrameCol); + } + } + } + } + } + else { + ownerA = colliderA.owner; + scriptsA = ownerA._scripts; + if (scriptsA) { + if (curFrameCol._isTrigger) { + if (ownerA._needProcessTriggers) { + for (j = 0, m = scriptsA.length; j < m; j++) + scriptsA[j].onTriggerEnter(colliderB); + } + } + else { + if (ownerA._needProcessCollisions) { + for (j = 0, m = scriptsA.length; j < m; j++) { + curFrameCol.other = colliderB; + scriptsA[j].onCollisionEnter(curFrameCol); + } + } + } + } + ownerB = colliderB.owner; + scriptsB = ownerB._scripts; + if (scriptsB) { + if (curFrameCol._isTrigger) { + if (ownerB._needProcessTriggers) { + for (j = 0, m = scriptsB.length; j < m; j++) + scriptsB[j].onTriggerEnter(colliderA); + } + } + else { + if (ownerB._needProcessCollisions) { + for (j = 0, m = scriptsB.length; j < m; j++) { + curFrameCol.other = colliderA; + scriptsB[j].onCollisionEnter(curFrameCol); + } + } + } + } + } + } + for (i = 0, n = this._previousFrameCollisions.length; i < n; i++) { + var preFrameCol = this._previousFrameCollisions[i]; + var preColliderA = preFrameCol._colliderA; + var preColliderB = preFrameCol._colliderB; + if (preColliderA.destroyed || preColliderB.destroyed) + continue; + if (loopCount - preFrameCol._updateFrame === 1) { + this._collisionsUtils.recoverCollision(preFrameCol); + ownerA = preColliderA.owner; + scriptsA = ownerA._scripts; + if (scriptsA) { + if (preFrameCol._isTrigger) { + if (ownerA._needProcessTriggers) { + for (j = 0, m = scriptsA.length; j < m; j++) + scriptsA[j].onTriggerExit(preColliderB); + } + } + else { + if (ownerA._needProcessCollisions) { + for (j = 0, m = scriptsA.length; j < m; j++) { + preFrameCol.other = preColliderB; + scriptsA[j].onCollisionExit(preFrameCol); + } + } + } + } + ownerB = preColliderB.owner; + scriptsB = ownerB._scripts; + if (scriptsB) { + if (preFrameCol._isTrigger) { + if (ownerB._needProcessTriggers) { + for (j = 0, m = scriptsB.length; j < m; j++) + scriptsB[j].onTriggerExit(preColliderA); + } + } + else { + if (ownerB._needProcessCollisions) { + for (j = 0, m = scriptsB.length; j < m; j++) { + preFrameCol.other = preColliderA; + scriptsB[j].onCollisionExit(preFrameCol); + } + } + } + } + } + } + for (var id in this._currentConstraint) { + var constraintObj = this._currentConstraint[id]; + var scripts = constraintObj.owner._scripts; + if (constraintObj.enabled && constraintObj._isBreakConstrained() && (!!scripts)) { + if (scripts.length != 0) { + for (i = 0, n = scripts.length; i < n; i++) { + scripts[i].onJointBreak(); + } + } + } + } + } + clearForces() { + if (!this._btDiscreteDynamicsWorld) + throw "Cannot perform this action when the physics engine is set to CollisionsOnly"; + Laya.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_clearForces(this._btDiscreteDynamicsWorld); + } + } + PhysicsSimulation.PHYSICSENGINEFLAGS_NONE = 0x0; + PhysicsSimulation.PHYSICSENGINEFLAGS_COLLISIONSONLY = 0x1; + PhysicsSimulation.PHYSICSENGINEFLAGS_SOFTBODYSUPPORT = 0x2; + PhysicsSimulation.PHYSICSENGINEFLAGS_MULTITHREADED = 0x4; + PhysicsSimulation.PHYSICSENGINEFLAGS_USEHARDWAREWHENPOSSIBLE = 0x8; + PhysicsSimulation.SOLVERMODE_RANDMIZE_ORDER = 1; + PhysicsSimulation.SOLVERMODE_FRICTION_SEPARATE = 2; + PhysicsSimulation.SOLVERMODE_USE_WARMSTARTING = 4; + PhysicsSimulation.SOLVERMODE_USE_2_FRICTION_DIRECTIONS = 16; + PhysicsSimulation.SOLVERMODE_ENABLE_FRICTION_DIRECTION_CACHING = 32; + PhysicsSimulation.SOLVERMODE_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION = 64; + PhysicsSimulation.SOLVERMODE_CACHE_FRIENDLY = 128; + PhysicsSimulation.SOLVERMODE_SIMD = 256; + PhysicsSimulation.SOLVERMODE_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS = 512; + PhysicsSimulation.SOLVERMODE_ALLOW_ZERO_LENGTH_FRICTION_DIRECTIONS = 1024; + PhysicsSimulation.HITSRAYRESULTCALLBACK_FLAG_NONE = 0; + PhysicsSimulation.HITSRAYRESULTCALLBACK_FLAG_FILTERBACKFACESS = 1; + PhysicsSimulation.HITSRAYRESULTCALLBACK_FLAG_KEEPUNFILIPPEDNORMAL = 2; + PhysicsSimulation.HITSRAYRESULTCALLBACK_FLAG_USESUBSIMPLEXCONVEXCASTRAYTEST = 4; + PhysicsSimulation.HITSRAYRESULTCALLBACK_FLAG_USEGJKCONVEXCASTRAYTEST = 8; + PhysicsSimulation.HITSRAYRESULTCALLBACK_FLAG_TERMINATOR = 0xffffffff; + PhysicsSimulation._tempVector30 = new Laya.Vector3(); + PhysicsSimulation.disableSimulation = false; + + class Rigidbody3D extends PhysicsTriggerComponent { + constructor(collisionGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER, canCollideWith = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + super(collisionGroup, canCollideWith); + this._isKinematic = false; + this._mass = 1.0; + this._gravity = new Laya.Vector3(0, -10, 0); + this._angularDamping = 0.0; + this._linearDamping = 0.0; + this._overrideGravity = false; + this._totalTorque = new Laya.Vector3(0, 0, 0); + this._totalForce = new Laya.Vector3(0, 0, 0); + this._linearVelocity = new Laya.Vector3(); + this._angularVelocity = new Laya.Vector3(); + this._linearFactor = new Laya.Vector3(1, 1, 1); + this._angularFactor = new Laya.Vector3(1, 1, 1); + this._detectCollisions = true; + this._controlBySimulation = true; + } + static __init__() { + var bt = Laya.ILaya3D.Physics3D._bullet; + Rigidbody3D._btTempVector30 = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btTempVector31 = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btVector3Zero = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btInertia = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btImpulse = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btImpulseOffset = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btGravity = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btTransform0 = bt.btTransform_create(); + } + get mass() { + return this._mass; + } + set mass(value) { + value = Math.max(value, 1e-07); + this._mass = value; + (this._isKinematic) || (this._updateMass(value)); + } + get isKinematic() { + return this._isKinematic; + } + set isKinematic(value) { + this._isKinematic = value; + this._controlBySimulation = !value; + var bt = Laya.ILaya3D.Physics3D._bullet; + var canInSimulation = !!(this._simulation && this._enabled && this._colliderShape); + canInSimulation && this._removeFromSimulation(); + var natColObj = this._btColliderObject; + var flags = bt.btCollisionObject_getCollisionFlags(natColObj); + if (value) { + flags = flags | PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT; + bt.btCollisionObject_setCollisionFlags(natColObj, flags); + bt.btCollisionObject_forceActivationState(this._btColliderObject, PhysicsComponent.ACTIVATIONSTATE_DISABLE_DEACTIVATION); + this._enableProcessCollisions = false; + this._updateMass(0); + } + else { + if ((flags & PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT) > 0) + flags = flags ^ PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT; + bt.btCollisionObject_setCollisionFlags(natColObj, flags); + bt.btCollisionObject_setActivationState(this._btColliderObject, PhysicsComponent.ACTIVATIONSTATE_ACTIVE_TAG); + this._enableProcessCollisions = true; + this._updateMass(this._mass); + } + var btZero = Rigidbody3D._btVector3Zero; + bt.btCollisionObject_setInterpolationLinearVelocity(natColObj, btZero); + bt.btRigidBody_setLinearVelocity(natColObj, btZero); + bt.btCollisionObject_setInterpolationAngularVelocity(natColObj, btZero); + bt.btRigidBody_setAngularVelocity(natColObj, btZero); + canInSimulation && this._addToSimulation(); + } + get linearDamping() { + return this._linearDamping; + } + set linearDamping(value) { + this._linearDamping = value; + if (this._btColliderObject) + Laya.ILaya3D.Physics3D._bullet.btRigidBody_setDamping(this._btColliderObject, value, this._angularDamping); + } + get angularDamping() { + return this._angularDamping; + } + set angularDamping(value) { + this._angularDamping = value; + if (this._btColliderObject) + Laya.ILaya3D.Physics3D._bullet.btRigidBody_setDamping(this._btColliderObject, this._linearDamping, value); + } + get overrideGravity() { + return this._overrideGravity; + } + set overrideGravity(value) { + this._overrideGravity = value; + var bt = Laya.ILaya3D.Physics3D._bullet; + if (this._btColliderObject) { + var flag = bt.btRigidBody_getFlags(this._btColliderObject); + if (value) { + if ((flag & Rigidbody3D._BT_DISABLE_WORLD_GRAVITY) === 0) + bt.btRigidBody_setFlags(this._btColliderObject, flag | Rigidbody3D._BT_DISABLE_WORLD_GRAVITY); + } + else { + if ((flag & Rigidbody3D._BT_DISABLE_WORLD_GRAVITY) > 0) + bt.btRigidBody_setFlags(this._btColliderObject, flag ^ Rigidbody3D._BT_DISABLE_WORLD_GRAVITY); + } + } + } + get gravity() { + var bt = Laya.ILaya3D.Physics3D._bullet; + Rigidbody3D._btGravity = bt.btRigidBody_getGravity(this._btColliderObject); + Laya.Utils3D._convertToLayaVec3(Rigidbody3D._btGravity, this._gravity, true); + return this._gravity; + } + set gravity(value) { + this._gravity = value; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(Rigidbody3D._btGravity, -value.x, value.y, value.z); + bt.btRigidBody_setGravity(this._btColliderObject, Rigidbody3D._btGravity); + } + get totalForce() { + if (this._btColliderObject) { + var btTotalForce = Laya.ILaya3D.Physics3D._bullet.btRigidBody_getTotalForce(this._btColliderObject); + Laya.Utils3D._convertToLayaVec3(btTotalForce, this._totalForce, true); + return this._totalForce; + } + return null; + } + get linearFactor() { + return this._linearFactor; + } + set linearFactor(value) { + this._linearFactor = value; + var btValue = Rigidbody3D._btTempVector30; + Laya.Utils3D._convertToBulletVec3(value, btValue, false); + Laya.ILaya3D.Physics3D._bullet.btRigidBody_setLinearFactor(this._btColliderObject, btValue); + } + get linearVelocity() { + if (this._btColliderObject) + Laya.Utils3D._convertToLayaVec3(Laya.ILaya3D.Physics3D._bullet.btRigidBody_getLinearVelocity(this._btColliderObject), this._linearVelocity, true); + return this._linearVelocity; + } + set linearVelocity(value) { + this._linearVelocity = value; + if (this._btColliderObject) { + var btValue = Rigidbody3D._btTempVector30; + Laya.Utils3D._convertToBulletVec3(value, btValue, true); + (this.isSleeping) && (this.wakeUp()); + Laya.ILaya3D.Physics3D._bullet.btRigidBody_setLinearVelocity(this._btColliderObject, btValue); + } + } + get angularFactor() { + return this._angularFactor; + } + set angularFactor(value) { + this._angularFactor = value; + var btValue = Rigidbody3D._btTempVector30; + Laya.Utils3D._convertToBulletVec3(value, btValue, false); + Laya.ILaya3D.Physics3D._bullet.btRigidBody_setAngularFactor(this._btColliderObject, btValue); + } + get angularVelocity() { + if (this._btColliderObject) + Laya.Utils3D._convertToLayaVec3(Laya.ILaya3D.Physics3D._bullet.btRigidBody_getAngularVelocity(this._btColliderObject), this._angularVelocity, true); + return this._angularVelocity; + } + set angularVelocity(value) { + this._angularVelocity = value; + if (this._btColliderObject) { + var btValue = Rigidbody3D._btTempVector30; + Laya.Utils3D._convertToBulletVec3(value, btValue, true); + (this.isSleeping) && (this.wakeUp()); + Laya.ILaya3D.Physics3D._bullet.btRigidBody_setAngularVelocity(this._btColliderObject, btValue); + } + } + get totalTorque() { + if (this._btColliderObject) { + var btTotalTorque = Laya.ILaya3D.Physics3D._bullet.btRigidBody_getTotalTorque(this._btColliderObject); + Laya.Utils3D._convertToLayaVec3(btTotalTorque, this._totalTorque, true); + return this._totalTorque; + } + return null; + } + get detectCollisions() { + return this._detectCollisions; + } + set detectCollisions(value) { + if (this._detectCollisions !== value) { + this._detectCollisions = value; + if (this._colliderShape && this._enabled && this._simulation) { + this._simulation._removeRigidBody(this); + this._simulation._addRigidBody(this, this._collisionGroup, value ? this._canCollideWith : 0); + } + } + } + get isSleeping() { + if (this._btColliderObject) + return Laya.ILaya3D.Physics3D._bullet.btCollisionObject_getActivationState(this._btColliderObject) === PhysicsComponent.ACTIVATIONSTATE_ISLAND_SLEEPING; + return false; + } + get sleepLinearVelocity() { + return Laya.ILaya3D.Physics3D._bullet.btRigidBody_getLinearSleepingThreshold(this._btColliderObject); + } + set sleepLinearVelocity(value) { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btRigidBody_setSleepingThresholds(this._btColliderObject, value, bt.btRigidBody_getAngularSleepingThreshold(this._btColliderObject)); + } + get sleepAngularVelocity() { + return Laya.ILaya3D.Physics3D._bullet.btRigidBody_getAngularSleepingThreshold(this._btColliderObject); + } + set sleepAngularVelocity(value) { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btRigidBody_setSleepingThresholds(this._btColliderObject, bt.btRigidBody_getLinearSleepingThreshold(this._btColliderObject), value); + } + get btColliderObject() { + return this._btColliderObject; + } + set constaintRigidbodyA(value) { + this._constaintRigidbodyA = value; + } + get constaintRigidbodyA() { + return this._constaintRigidbodyA; + } + set constaintRigidbodyB(value) { + this._constaintRigidbodyB = value; + } + get constaintRigidbodyB() { + return this._constaintRigidbodyB; + } + _updateMass(mass) { + if (this._btColliderObject && this._colliderShape) { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btCollisionShape_calculateLocalInertia(this._colliderShape._btShape, mass, Rigidbody3D._btInertia); + bt.btRigidBody_setMassProps(this._btColliderObject, mass, Rigidbody3D._btInertia); + bt.btRigidBody_updateInertiaTensor(this._btColliderObject); + } + } + _onScaleChange(scale) { + super._onScaleChange(scale); + this._updateMass(this._isKinematic ? 0 : this._mass); + } + _derivePhysicsTransformation(force) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var btColliderObject = this._btColliderObject; + var oriTransform = bt.btCollisionObject_getWorldTransform(btColliderObject); + var transform = Rigidbody3D._btTransform0; + bt.btTransform_equal(transform, oriTransform); + this._innerDerivePhysicsTransformation(transform, force); + bt.btRigidBody_setCenterOfMassTransform(btColliderObject, transform); + } + _onAdded() { + var bt = Laya.ILaya3D.Physics3D._bullet; + var motionState = bt.layaMotionState_create(); + bt.layaMotionState_set_rigidBodyID(motionState, this._id); + this._btLayaMotionState = motionState; + var constructInfo = bt.btRigidBodyConstructionInfo_create(0.0, motionState, null, Rigidbody3D._btVector3Zero); + var btRigid = bt.btRigidBody_create(constructInfo); + bt.btCollisionObject_setUserIndex(btRigid, this.id); + this._btColliderObject = btRigid; + super._onAdded(); + this.mass = this._mass; + this.linearFactor = this._linearFactor; + this.angularFactor = this._angularFactor; + this.linearDamping = this._linearDamping; + this.angularDamping = this._angularDamping; + this.overrideGravity = this._overrideGravity; + this.gravity = this._gravity; + this.isKinematic = this._isKinematic; + bt.btRigidBodyConstructionInfo_destroy(constructInfo); + } + _onEnable() { + super._onEnable(); + if (this._constaintRigidbodyA) { + if (this._constaintRigidbodyA.connectedBody._simulation) { + this._constaintRigidbodyA._createConstraint(); + this._constaintRigidbodyA._onEnable(); + } + } + if (this._constaintRigidbodyB) { + if (this._constaintRigidbodyB.ownBody._simulation) { + this._constaintRigidbodyB._createConstraint(); + this._constaintRigidbodyB._onEnable(); + } + } + } + _onShapeChange(colShape) { + super._onShapeChange(colShape); + if (this._isKinematic) { + this._updateMass(0); + } + else { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btRigidBody_setCenterOfMassTransform(this._btColliderObject, bt.btCollisionObject_getWorldTransform(this._btColliderObject)); + this._updateMass(this._mass); + } + } + _parse(data) { + (data.friction != null) && (this.friction = data.friction); + (data.rollingFriction != null) && (this.rollingFriction = data.rollingFriction); + (data.restitution != null) && (this.restitution = data.restitution); + (data.isTrigger != null) && (this.isTrigger = data.isTrigger); + (data.mass != null) && (this.mass = data.mass); + (data.linearDamping != null) && (this.linearDamping = data.linearDamping); + (data.angularDamping != null) && (this.angularDamping = data.angularDamping); + (data.overrideGravity != null) && (this.overrideGravity = data.overrideGravity); + if (data.linearFactor != null) { + var linFac = this.linearFactor; + linFac.fromArray(data.linearFactor); + this.linearFactor = linFac; + } + if (data.angularFactor != null) { + var angFac = this.angularFactor; + angFac.fromArray(data.angularFactor); + this.angularFactor = angFac; + } + if (data.gravity) { + this.gravity.fromArray(data.gravity); + this.gravity = this.gravity; + } + super._parse(data); + this._parseShape(data.shapes); + (data.isKinematic != null) && (this.isKinematic = data.isKinematic); + } + _onDestroy() { + Laya.ILaya3D.Physics3D._bullet.btMotionState_destroy(this._btLayaMotionState); + super._onDestroy(); + this._btLayaMotionState = null; + this._gravity = null; + this._totalTorque = null; + this._linearVelocity = null; + this._angularVelocity = null; + this._linearFactor = null; + this._angularFactor = null; + if (this.constaintRigidbodyA) + this.constaintRigidbodyA._breakConstrained(); + if (this.constaintRigidbodyB) { + this.constaintRigidbodyB.connectedBody = null; + this.constaintRigidbodyB._onDisable(); + } + } + _addToSimulation() { + this._simulation._addRigidBody(this, this._collisionGroup, this._detectCollisions ? this._canCollideWith : 0); + } + _removeFromSimulation() { + this._simulation._removeRigidBody(this); + } + _cloneTo(dest) { + super._cloneTo(dest); + var destRigidbody3D = dest; + destRigidbody3D.isKinematic = this._isKinematic; + destRigidbody3D.mass = this._mass; + destRigidbody3D.gravity = this._gravity; + destRigidbody3D.angularDamping = this._angularDamping; + destRigidbody3D.linearDamping = this._linearDamping; + destRigidbody3D.overrideGravity = this._overrideGravity; + destRigidbody3D.linearVelocity = this._linearVelocity; + destRigidbody3D.angularVelocity = this._angularVelocity; + destRigidbody3D.linearFactor = this._linearFactor; + destRigidbody3D.angularFactor = this._angularFactor; + destRigidbody3D.detectCollisions = this._detectCollisions; + } + applyForce(force, localOffset = null) { + if (this._btColliderObject == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + var bt = Laya.ILaya3D.Physics3D._bullet; + var btForce = Rigidbody3D._btTempVector30; + bt.btVector3_setValue(btForce, -force.x, force.y, force.z); + if (localOffset) { + var btOffset = Rigidbody3D._btTempVector31; + bt.btVector3_setValue(btOffset, -localOffset.x, localOffset.y, localOffset.z); + bt.btRigidBody_applyForce(this._btColliderObject, btForce, btOffset); + } + else { + bt.btRigidBody_applyCentralForce(this._btColliderObject, btForce); + } + } + applyTorque(torque) { + if (this._btColliderObject == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + var bullet = Laya.ILaya3D.Physics3D._bullet; + var btTorque = Rigidbody3D._btTempVector30; + bullet.btVector3_setValue(btTorque, -torque.x, torque.y, torque.z); + bullet.btRigidBody_applyTorque(this._btColliderObject, btTorque); + } + applyImpulse(impulse, localOffset = null) { + if (this._btColliderObject == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(Rigidbody3D._btImpulse, -impulse.x, impulse.y, impulse.z); + if (localOffset) { + bt.btVector3_setValue(Rigidbody3D._btImpulseOffset, -localOffset.x, localOffset.y, localOffset.z); + bt.btRigidBody_applyImpulse(this._btColliderObject, Rigidbody3D._btImpulse, Rigidbody3D._btImpulseOffset); + } + else { + bt.btRigidBody_applyCentralImpulse(this._btColliderObject, Rigidbody3D._btImpulse); + } + } + applyTorqueImpulse(torqueImpulse) { + if (this._btColliderObject == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + var bt = Laya.ILaya3D.Physics3D._bullet; + var btTorqueImpulse = Rigidbody3D._btTempVector30; + bt.btVector3_setValue(btTorqueImpulse, -torqueImpulse.x, torqueImpulse.y, torqueImpulse.z); + bt.btRigidBody_applyTorqueImpulse(this._btColliderObject, btTorqueImpulse); + } + wakeUp() { + this._btColliderObject && (Laya.ILaya3D.Physics3D._bullet.btCollisionObject_activate(this._btColliderObject, false)); + } + clearForces() { + var rigidBody = this._btColliderObject; + if (rigidBody == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btRigidBody_clearForces(rigidBody); + var btZero = Rigidbody3D._btVector3Zero; + bt.btCollisionObject_setInterpolationLinearVelocity(rigidBody, btZero); + bt.btRigidBody_setLinearVelocity(rigidBody, btZero); + bt.btCollisionObject_setInterpolationAngularVelocity(rigidBody, btZero); + bt.btRigidBody_setAngularVelocity(rigidBody, btZero); + } + } + Rigidbody3D.TYPE_STATIC = 0; + Rigidbody3D.TYPE_DYNAMIC = 1; + Rigidbody3D.TYPE_KINEMATIC = 2; + Rigidbody3D._BT_DISABLE_WORLD_GRAVITY = 1; + Rigidbody3D._BT_ENABLE_GYROPSCOPIC_FORCE = 2; + + class ConstraintComponent extends Laya.Component { + constructor(constraintType) { + super(); + this._anchor = new Laya.Vector3(); + this._connectAnchor = new Laya.Vector3(); + this._feedbackEnabled = false; + this._getJointFeedBack = false; + this._currentForce = new Laya.Vector3(); + this._currentTorque = new Laya.Vector3(); + this._constraintType = constraintType; + var bt = Laya.Physics3D._bullet; + this._btframATrans = bt.btTransform_create(); + this._btframBTrans = bt.btTransform_create(); + bt.btTransform_setIdentity(this._btframATrans); + bt.btTransform_setIdentity(this._btframBTrans); + this._btframAPos = bt.btVector3_create(0, 0, 0); + this._btframBPos = bt.btVector3_create(0, 0, 0); + bt.btTransform_setOrigin(this._btframATrans, this._btframAPos); + bt.btTransform_setOrigin(this._btframBTrans, this._btframBPos); + this._breakForce = -1; + this._breakTorque = -1; + } + get enabled() { + return super.enabled; + } + set enabled(value) { + super.enabled = value; + } + get appliedImpulse() { + if (!this._feedbackEnabled) { + this._btConstraint.EnableFeedback(true); + this._feedbackEnabled = true; + } + return this._btConstraint.AppliedImpulse; + } + set connectedBody(value) { + this._connectedBody = value; + value && (value.constaintRigidbodyB = this); + } + get connectedBody() { + return this._connectedBody; + } + get ownBody() { + return this._ownBody; + } + set ownBody(value) { + this._ownBody = value; + value.constaintRigidbodyA = this; + } + get currentForce() { + if (!this._getJointFeedBack) + this._getFeedBackInfo(); + return this._currentForce; + } + get currentTorque() { + if (!this._getJointFeedBack) + this._getFeedBackInfo(); + return this._currentTorque; + } + get breakForce() { + return this._breakForce; + } + set breakForce(value) { + this._breakForce = value; + } + get breakTorque() { + return this._breakTorque; + } + set breakTorque(value) { + this._breakTorque = value; + } + set anchor(value) { + value.cloneTo(this._anchor); + this.setFrames(); + } + get anchor() { + return this._anchor; + } + set connectAnchor(value) { + value.cloneTo(this._connectAnchor); + this.setFrames(); + } + get connectAnchor() { + return this._connectAnchor; + } + setOverrideNumSolverIterations(overideNumIterations) { + var bt = Laya.Physics3D._bullet; + bt.btTypedConstraint_setOverrideNumSolverIterations(this._btConstraint, overideNumIterations); + } + setConstraintEnabled(enable) { + var bt = Laya.Physics3D._bullet; + bt.btTypedConstraint_setEnabled(this._btConstraint, enable); + } + _onEnable() { + super._onEnable(); + this.enabled = true; + } + _onDisable() { + super._onDisable(); + this.enabled = false; + } + setFrames() { + var bt = Laya.Physics3D._bullet; + bt.btVector3_setValue(this._btframAPos, -this._anchor.x, this.anchor.y, this.anchor.z); + bt.btVector3_setValue(this._btframBPos, -this._connectAnchor.x, this._connectAnchor.y, this._connectAnchor.z); + bt.btTransform_setOrigin(this._btframATrans, this._btframAPos); + bt.btTransform_setOrigin(this._btframBTrans, this._btframBPos); + } + _addToSimulation() { + } + _removeFromSimulation() { + } + _createConstraint() { + } + setConnectRigidBody(ownerRigid, connectRigidBody) { + var ownerCanInSimulation = (ownerRigid) && (!!(ownerRigid._simulation && ownerRigid._enabled && ownerRigid.colliderShape)); + var connectCanInSimulation = (connectRigidBody) && (!!(connectRigidBody._simulation && connectRigidBody._enabled && connectRigidBody.colliderShape)); + if (!(ownerCanInSimulation && connectCanInSimulation)) + throw "ownerRigid or connectRigidBody is not in Simulation"; + if (ownerRigid != this._ownBody || connectRigidBody != this._connectedBody) { + var canInSimulation = !!(this.enabled && this._simulation); + canInSimulation && this._removeFromSimulation(); + this._ownBody = ownerRigid; + this._connectedBody = connectRigidBody; + this._ownBody.constaintRigidbodyA = this; + this._connectedBody.constaintRigidbodyB = this; + this._createConstraint(); + } + } + getcurrentForce(out) { + if (!this._btJointFeedBackObj) + throw "this Constraint is not simulation"; + var bt = Laya.Physics3D._bullet; + var applyForce = bt.btJointFeedback_getAppliedForceBodyA(this._btJointFeedBackObj); + out.setValue(bt.btVector3_x(applyForce), bt.btVector3_y(applyForce), bt.btVector3_z(applyForce)); + return; + } + getcurrentTorque(out) { + if (!this._btJointFeedBackObj) + throw "this Constraint is not simulation"; + var bt = Laya.Physics3D._bullet; + var applyTorque = bt.btJointFeedback_getAppliedTorqueBodyA(this._btJointFeedBackObj); + out.setValue(bt.btVector3_x(applyTorque), bt.btVector3_y(applyTorque), bt.btVector3_z(applyTorque)); + return; + } + _onDestroy() { + var physics3D = Laya.Physics3D._bullet; + this._simulation && this._removeFromSimulation(); + if (this._btConstraint && this._btJointFeedBackObj && this._simulation) { + physics3D.btTypedConstraint_destroy(this._btConstraint); + physics3D.btJointFeedback_destroy(this._btJointFeedBackObj); + this._btJointFeedBackObj = null; + this._btConstraint = null; + } + super._onDisable(); + } + _isBreakConstrained() { + this._getJointFeedBack = false; + if (this.breakForce == -1 && this.breakTorque == -1) + return false; + this._getFeedBackInfo(); + var isBreakForce = this._breakForce != -1 && (Laya.Vector3.scalarLength(this._currentForce) > this._breakForce); + var isBreakTorque = this._breakTorque != -1 && (Laya.Vector3.scalarLength(this._currentTorque) > this._breakTorque); + if (isBreakForce || isBreakTorque) { + this._breakConstrained(); + return true; + } + return false; + } + _parse(data) { + this._anchor.fromArray(data.anchor); + this._connectAnchor.fromArray(data.connectAnchor); + this.setFrames(); + } + _getFeedBackInfo() { + var bt = Laya.Physics3D._bullet; + var applyForce = bt.btJointFeedback_getAppliedForceBodyA(this._btJointFeedBackObj); + var applyTorque = bt.btJointFeedback_getAppliedTorqueBodyA(this._btJointFeedBackObj); + this._currentTorque.setValue(bt.btVector3_x(applyTorque), bt.btVector3_y(applyTorque), bt.btVector3_z(applyTorque)); + this._currentForce.setValue(bt.btVector3_x(applyForce), bt.btVector3_y(applyForce), bt.btVector3_z(applyForce)); + this._getJointFeedBack = true; + } + _breakConstrained() { + this.ownBody.constaintRigidbodyA = null; + this.connectedBody && (this.connectedBody.constaintRigidbodyB = null); + this.destroy(); + } + } + ConstraintComponent.CONSTRAINT_POINT2POINT_CONSTRAINT_TYPE = 3; + ConstraintComponent.CONSTRAINT_HINGE_CONSTRAINT_TYPE = 4; + ConstraintComponent.CONSTRAINT_CONETWIST_CONSTRAINT_TYPE = 5; + ConstraintComponent.CONSTRAINT_D6_CONSTRAINT_TYPE = 6; + ConstraintComponent.CONSTRAINT_SLIDER_CONSTRAINT_TYPE = 7; + ConstraintComponent.CONSTRAINT_CONTACT_CONSTRAINT_TYPE = 8; + ConstraintComponent.CONSTRAINT_D6_SPRING_CONSTRAINT_TYPE = 9; + ConstraintComponent.CONSTRAINT_GEAR_CONSTRAINT_TYPE = 10; + ConstraintComponent.CONSTRAINT_FIXED_CONSTRAINT_TYPE = 11; + ConstraintComponent.CONSTRAINT_MAX_CONSTRAINT_TYPE = 12; + ConstraintComponent.CONSTRAINT_CONSTRAINT_ERP = 1; + ConstraintComponent.CONSTRAINT_CONSTRAINT_STOP_ERP = 2; + ConstraintComponent.CONSTRAINT_CONSTRAINT_CFM = 3; + ConstraintComponent.CONSTRAINT_CONSTRAINT_STOP_CFM = 4; + ConstraintComponent.tempForceV3 = new Laya.Vector3(); + + class ConfigurableConstraint extends ConstraintComponent { + constructor() { + super(ConstraintComponent.CONSTRAINT_D6_SPRING_CONSTRAINT_TYPE); + this._axis = new Laya.Vector3(); + this._secondaryAxis = new Laya.Vector3(); + this._minLinearLimit = new Laya.Vector3(); + this._maxLinearLimit = new Laya.Vector3(); + this._minAngularLimit = new Laya.Vector3(); + this._maxAngularLimit = new Laya.Vector3(); + this._linearLimitSpring = new Laya.Vector3(); + this._angularLimitSpring = new Laya.Vector3(); + this._linearBounce = new Laya.Vector3(); + this._angularBounce = new Laya.Vector3(); + this._linearDamp = new Laya.Vector3(); + this._angularDamp = new Laya.Vector3(); + this._xMotion = 0; + this._yMotion = 0; + this._zMotion = 0; + this._angularXMotion = 0; + this._angularYMotion = 0; + this._angularZMotion = 0; + var bt = Laya.Physics3D._bullet; + this._btAxis = bt.btVector3_create(-1.0, 0.0, 0.0); + this._btSecondaryAxis = bt.btVector3_create(0.0, 1.0, 0.0); + } + get axis() { + return this._axis; + } + get secondaryAxis() { + return this._secondaryAxis; + } + set maxAngularLimit(value) { + value.cloneTo(this._maxAngularLimit); + } + set minAngularLimit(value) { + value.cloneTo(this._minAngularLimit); + } + get maxAngularLimit() { + return this._maxAngularLimit; + } + get minAngularLimit() { + return this._minAngularLimit; + } + set maxLinearLimit(value) { + value.cloneTo(this._maxLinearLimit); + } + set minLinearLimit(value) { + value.cloneTo(this._minLinearLimit); + } + get maxLinearLimit() { + return this._maxLinearLimit; + } + get minLinearLimit() { + return this._minLinearLimit; + } + set XMotion(value) { + if (this._xMotion != value) { + this._xMotion = value; + this.setLimit(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, value, -this._maxLinearLimit.x, -this._minLinearLimit.x); + } + } + get XMotion() { + return this._xMotion; + } + set YMotion(value) { + if (this._yMotion != value) { + this._yMotion = value; + this.setLimit(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, value, this._minLinearLimit.y, this._maxLinearLimit.y); + } + } + get YMotion() { + return this._yMotion; + } + set ZMotion(value) { + if (this._zMotion != value) { + this._zMotion = value; + this.setLimit(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, value, this._minLinearLimit.z, this._maxLinearLimit.z); + } + } + get ZMotion() { + return this._zMotion; + } + set angularXMotion(value) { + if (this._angularXMotion != value) { + this._angularXMotion = value; + this.setLimit(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, value, -this._maxAngularLimit.x, -this._minAngularLimit.x); + } + } + get angularXMotion() { + return this._angularXMotion; + } + set angularYMotion(value) { + if (this._angularYMotion != value) { + this._angularYMotion = value; + this.setLimit(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, value, this._minAngularLimit.y, this._maxAngularLimit.y); + } + } + get angularYMotion() { + return this._angularYMotion; + } + set angularZMotion(value) { + if (this._angularZMotion != value) { + this._angularZMotion = value; + this.setLimit(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, value, this._minAngularLimit.z, this._maxAngularLimit.z); + } + } + get angularZMotion() { + return this._angularZMotion; + } + set linearLimitSpring(value) { + if (!Laya.Vector3.equals(this._linearLimitSpring, value)) { + value.cloneTo(this._linearLimitSpring); + this.setSpring(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, value.x); + this.setSpring(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, value.y); + this.setSpring(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, value.z); + } + } + get linearLimitSpring() { + return this._linearLimitSpring; + } + set angularLimitSpring(value) { + if (!Laya.Vector3.equals(this._angularLimitSpring, value)) { + value.cloneTo(this._angularLimitSpring); + this.setSpring(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, value.x); + this.setSpring(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, value.y); + this.setSpring(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, value.z); + } + } + get angularLimitSpring() { + return this._angularLimitSpring; + } + set linearBounce(value) { + if (!Laya.Vector3.equals(this._linearBounce, value)) { + value.cloneTo(this._linearBounce); + this.setBounce(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, value.x); + this.setBounce(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, value.y); + this.setBounce(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, value.z); + } + } + get linearBounce() { + return this._linearBounce; + } + set angularBounce(value) { + if (!Laya.Vector3.equals(this._angularBounce, value)) { + value.cloneTo(this._angularBounce); + this.setBounce(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, value.x); + this.setBounce(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, value.y); + this.setBounce(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, value.z); + } + } + get angularBounce() { + return this._angularBounce; + } + set linearDamp(value) { + if (!Laya.Vector3.equals(this._linearDamp, value)) { + value.cloneTo(this._linearDamp); + this.setDamping(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, value.x); + this.setDamping(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, value.y); + this.setDamping(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, value.z); + } + } + get linearDamp() { + return this._linearDamp; + } + set angularDamp(value) { + if (!Laya.Vector3.equals(this._angularDamp, value)) { + value.cloneTo(this._angularDamp); + this.setDamping(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, value.x); + this.setDamping(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, value.y); + this.setDamping(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, value.z); + } + } + get angularDamp() { + return this._angularDamp; + } + set anchor(value) { + value.cloneTo(this._anchor); + this.setFrames(); + } + get anchor() { + return this._anchor; + } + set connectAnchor(value) { + value.cloneTo(this._connectAnchor); + this.setFrames(); + } + get connectAnchor() { + return this._connectAnchor; + } + setAxis(axis, secondaryAxis) { + if (!this._btConstraint) + return; + var bt = Laya.Physics3D._bullet; + this._axis.setValue(axis.x, axis.y, axis.y); + this._secondaryAxis.setValue(secondaryAxis.x, secondaryAxis.y, secondaryAxis.z); + this._btAxis = bt.btVector3_setValue(-axis.x, axis.y, axis.z); + this._btSecondaryAxis = bt.btVector3_setValue(-secondaryAxis.x, secondaryAxis.y, secondaryAxis.z); + bt.btGeneric6DofSpring2Constraint_setAxis(this._btConstraint, this._btAxis, this._btSecondaryAxis); + } + setLimit(axis, motionType, low, high) { + if (!this._btConstraint) + return; + var bt = Laya.Physics3D._bullet; + switch (motionType) { + case ConfigurableConstraint.CONFIG_MOTION_TYPE_LOCKED: + bt.btGeneric6DofSpring2Constraint_setLimit(this._btConstraint, axis, 0, 0); + break; + case ConfigurableConstraint.CONFIG_MOTION_TYPE_LIMITED: + if (low < high) + bt.btGeneric6DofSpring2Constraint_setLimit(this._btConstraint, axis, low, high); + break; + case ConfigurableConstraint.CONFIG_MOTION_TYPE_FREE: + bt.btGeneric6DofSpring2Constraint_setLimit(this._btConstraint, axis, 1, 0); + break; + default: + throw "No Type of Axis Motion"; + } + } + setSpring(axis, springValue, limitIfNeeded = true) { + if (!this._btConstraint) + return; + var bt = Laya.Physics3D._bullet; + var enableSpring = springValue > 0; + bt.btGeneric6DofSpring2Constraint_enableSpring(this._btConstraint, axis, enableSpring); + if (enableSpring) + bt.btGeneric6DofSpring2Constraint_setStiffness(this._btConstraint, axis, springValue, limitIfNeeded); + } + setBounce(axis, bounce) { + if (!this._btConstraint) + return; + var bt = Laya.Physics3D._bullet; + bounce = bounce <= 0 ? 0 : bounce; + bt.btGeneric6DofSpring2Constraint_setBounce(this._btConstraint, axis, bounce); + } + setDamping(axis, damp, limitIfNeeded = true) { + if (!this._btConstraint) + return; + var bt = Laya.Physics3D._bullet; + damp = damp <= 0 ? 0 : damp; + bt.btGeneric6DofSpring2Constraint_setDamping(this._btConstraint, axis, damp, limitIfNeeded); + } + setEquilibriumPoint(axis, equilibriumPoint) { + var bt = Laya.Physics3D._bullet; + bt.btGeneric6DofSpring2Constraint_setEquilibriumPoint(this._btConstraint, axis, equilibriumPoint); + } + enableMotor(axis, isEnableMotor) { + var bt = Laya.Physics3D._bullet; + bt.btGeneric6DofSpring2Constraint_enableMotor(this._btConstraint, axis, isEnableMotor); + } + setServo(axis, onOff) { + var bt = Laya.Physics3D._bullet; + bt.btGeneric6DofSpring2Constraint_setServo(this._btConstraint, axis, onOff); + } + setTargetVelocity(axis, velocity) { + var bt = Laya.Physics3D._bullet; + bt.btGeneric6DofSpring2Constraint_setTargetVelocity(this._btConstraint, axis, velocity); + } + setTargetPosition(axis, target) { + var bt = Laya.Physics3D._bullet; + bt.btGeneric6DofSpring2Constraint_setServoTarget(this._btConstraint, axis, target); + } + setMaxMotorForce(axis, force) { + var bt = Laya.Physics3D._bullet; + bt.btGeneric6DofSpring2Constraint_setMaxMotorForce(this._btConstraint, axis, force); + } + setParam(axis, constraintParams, value) { + var bt = Laya.Physics3D._bullet; + bt.btTypedConstraint_setParam(this._btConstraint, axis, constraintParams, value); + } + setFrames() { + super.setFrames(); + var bt = Laya.Physics3D._bullet; + if (!this._btConstraint) + return; + bt.btGeneric6DofSpring2Constraint_setFrames(this._btConstraint, this._btframATrans, this._btframBTrans); + } + _addToSimulation() { + this._simulation && this._simulation.addConstraint(this, this.enabled); + } + _removeFromSimulation() { + this._simulation.removeConstraint(this); + this._simulation = null; + } + _createConstraint() { + var bt = Laya.Physics3D._bullet; + this._btConstraint = bt.btGeneric6DofSpring2Constraint_create(this.ownBody.btColliderObject, this._btframAPos, this.connectedBody.btColliderObject, this._btframBPos, ConfigurableConstraint.RO_XYZ); + this._btJointFeedBackObj = bt.btJointFeedback_create(this._btConstraint); + bt.btTypedConstraint_setJointFeedback(this._btConstraint, this._btJointFeedBackObj); + this._simulation = this.owner._scene.physicsSimulation; + this._initAllConstraintInfo(); + this._addToSimulation(); + Laya.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint, true); + } + _initAllConstraintInfo() { + this.setLimit(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, this._xMotion, -this._maxLinearLimit.x, -this._minLinearLimit.x); + this.setLimit(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, this._yMotion, this._minLinearLimit.y, this._maxLinearLimit.y); + this.setLimit(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, this._zMotion, this._minLinearLimit.z, this._maxLinearLimit.z); + this.setLimit(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, this._angularXMotion, -this._maxAngularLimit.x, -this._minAngularLimit.x); + this.setLimit(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, this._angularYMotion, this._minAngularLimit.y, this._maxAngularLimit.y); + this.setLimit(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, this._angularZMotion, this._minAngularLimit.z, this._maxAngularLimit.z); + this.setSpring(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, this._linearLimitSpring.x); + this.setSpring(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, this._linearLimitSpring.y); + this.setSpring(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, this._linearLimitSpring.z); + this.setSpring(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, this._angularLimitSpring.x); + this.setSpring(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, this._angularLimitSpring.y); + this.setSpring(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, this._angularLimitSpring.z); + this.setBounce(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, this._linearBounce.x); + this.setBounce(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, this._linearBounce.y); + this.setBounce(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, this._linearBounce.z); + this.setBounce(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, this._angularBounce.x); + this.setBounce(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, this._angularBounce.y); + this.setBounce(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, this._angularBounce.z); + this.setDamping(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, this._linearDamp.x); + this.setDamping(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, this._linearDamp.y); + this.setDamping(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, this._linearDamp.z); + this.setDamping(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, this._angularDamp.x); + this.setDamping(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, this._angularDamp.y); + this.setDamping(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, this._angularDamp.z); + this.setFrames(); + this.setEquilibriumPoint(0, 0); + } + _onAdded() { + super._onAdded(); + } + _onEnable() { + if (!this._btConstraint) + return; + super._onEnable(); + if (this._btConstraint) + Laya.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint, true); + } + _onDisable() { + super._onDisable(); + if (!this.connectedBody && this._simulation) + this._removeFromSimulation(); + if (this._btConstraint) + Laya.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint, false); + } + _parse(data, interactMap = null) { + super._parse(data); + this._axis.fromArray(data.axis); + this._secondaryAxis.fromArray(data.secondaryAxis); + var limitlimit = data.linearLimit; + this._minLinearLimit.setValue(-limitlimit, -limitlimit, -limitlimit); + this._maxLinearLimit.setValue(limitlimit, limitlimit, limitlimit); + var limitSpring = data.linearLimitSpring; + this._linearLimitSpring.setValue(limitSpring, limitSpring, limitSpring); + var limitDamp = data.linearLimitDamper; + this._linearDamp.setValue(limitDamp, limitDamp, limitDamp); + var limitBounciness = data.linearLimitBounciness; + this._linearBounce.setValue(limitBounciness, limitBounciness, limitBounciness); + var xlowAngularLimit = data.lowAngularXLimit; + var xhighAngularLimit = data.highAngularXLimit; + var yAngularLimit = data.angularYLimit; + var zAngularLimit = data.angularZLimit; + this._minAngularLimit.setValue(xlowAngularLimit, -yAngularLimit, -zAngularLimit); + this._maxAngularLimit.setValue(xhighAngularLimit, yAngularLimit, zAngularLimit); + var xhighAngularBounciness = data.highAngularXLimitBounciness; + var ybounciness = data.angularYLimitBounciness; + var zbounciness = data.angularZLimitBounciness; + this._angularBounce.setValue(xhighAngularBounciness, ybounciness, zbounciness); + var xAngularSpring = data.angularXLimitSpring; + var yzAngularSpriny = data.angularYZLimitSpring; + this._angularLimitSpring.setValue(xAngularSpring, yzAngularSpriny, yzAngularSpriny); + var xAngularDamper = data.angularXLimitDamper; + var yzAngularDamper = data.angularYZLimitDamper; + this._angularDamp.setValue(xAngularDamper, yzAngularDamper, yzAngularDamper); + this.XMotion = data.xMotion; + this.YMotion = data.yMotion; + this.ZMotion = data.zMotion; + this.angularXMotion = data.angularXMotion; + this.angularYMotion = data.angularYMotion; + this.angularZMotion = data.angularZMotion; + if (data.rigidbodyID != -1 && data.connectRigidbodyID != -1) { + interactMap.component.push(this); + interactMap.data.push(data); + } + (data.breakForce != undefined) && (this.breakForce = data.breakForce); + (data.breakTorque != undefined) && (this.breakTorque = data.breakTorque); + } + _parseInteractive(data = null, spriteMap = null) { + var rigidBodySprite = spriteMap[data.rigidbodyID]; + var rigidBody = rigidBodySprite.getComponent(Rigidbody3D); + var connectSprite = spriteMap[data.connectRigidbodyID]; + var connectRigidbody = connectSprite.getComponent(Rigidbody3D); + this.ownBody = rigidBody; + this.connectedBody = connectRigidbody; + } + _onDestroy() { + super._onDestroy(); + } + } + ConfigurableConstraint.CONFIG_MOTION_TYPE_LOCKED = 0; + ConfigurableConstraint.CONFIG_MOTION_TYPE_LIMITED = 1; + ConfigurableConstraint.CONFIG_MOTION_TYPE_FREE = 2; + ConfigurableConstraint.MOTION_LINEAR_INDEX_X = 0; + ConfigurableConstraint.MOTION_LINEAR_INDEX_Y = 1; + ConfigurableConstraint.MOTION_LINEAR_INDEX_Z = 2; + ConfigurableConstraint.MOTION_ANGULAR_INDEX_X = 3; + ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y = 4; + ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z = 5; + ConfigurableConstraint.RO_XYZ = 0; + ConfigurableConstraint.RO_XZY = 1; + ConfigurableConstraint.RO_YXZ = 2; + ConfigurableConstraint.RO_YZX = 3; + ConfigurableConstraint.RO_ZXY = 4; + ConfigurableConstraint.RO_ZYX = 5; + + class FixedConstraint extends ConstraintComponent { + constructor() { + super(ConstraintComponent.CONSTRAINT_FIXED_CONSTRAINT_TYPE); + this.breakForce = -1; + this.breakTorque = -1; + } + _addToSimulation() { + this._simulation && this._simulation.addConstraint(this, this.enabled); + } + _removeFromSimulation() { + this._simulation.removeConstraint(this); + this._simulation = null; + } + _createConstraint() { + if (this.ownBody && this.ownBody._simulation && this.connectedBody && this.connectedBody._simulation) { + var bt = Laya.Physics3D._bullet; + this._btConstraint = bt.btFixedConstraint_create(this.ownBody.btColliderObject, this._btframATrans, this.connectedBody.btColliderObject, this._btframBTrans); + this._btJointFeedBackObj = bt.btJointFeedback_create(this._btConstraint); + bt.btTypedConstraint_setJointFeedback(this._btConstraint, this._btJointFeedBackObj); + this._simulation = this.owner._scene.physicsSimulation; + this._addToSimulation(); + Laya.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint, true); + } + } + _onAdded() { + super._onAdded(); + } + _onEnable() { + if (!this._btConstraint) + return; + super._onEnable(); + if (this._btConstraint) + Laya.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint, true); + } + _onDisable() { + super._onDisable(); + if (!this.connectedBody) + this._removeFromSimulation(); + if (this._btConstraint) + Laya.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint, false); + } + _onDestroy() { + super._onDestroy(); + } + _parse(data, interactMap = null) { + super._parse(data); + if (data.rigidbodyID != -1 && data.connectRigidbodyID != -1) { + interactMap.component.push(this); + interactMap.data.push(data); + } + (data.breakForce != undefined) && (this.breakForce = data.breakForce); + (data.breakTorque != undefined) && (this.breakTorque = data.breakTorque); + } + _parseInteractive(data = null, spriteMap = null) { + var rigidBodySprite = spriteMap[data.rigidbodyID]; + var rigidBody = rigidBodySprite.getComponent(Rigidbody3D); + var connectSprite = spriteMap[data.connectRigidbodyID]; + var connectRigidbody = connectSprite.getComponent(Rigidbody3D); + this.ownBody = rigidBody; + this.connectedBody = connectRigidbody; + } + } + + class StaticPlaneColliderShape extends ColliderShape { + constructor(normal, offset) { + super(); + this._normal = normal; + this._offset = offset; + this._type = ColliderShape.SHAPETYPES_STATICPLANE; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(StaticPlaneColliderShape._btNormal, -normal.x, normal.y, normal.z); + this._btShape = bt.btStaticPlaneShape_create(StaticPlaneColliderShape._btNormal, offset); + } + static __init__() { + StaticPlaneColliderShape._btNormal = Laya.ILaya3D.Physics3D._bullet.btVector3_create(0, 0, 0); + } + clone() { + var dest = new StaticPlaneColliderShape(this._normal, this._offset); + this.cloneTo(dest); + return dest; + } + } + + exports.BoxColliderShape = BoxColliderShape; + exports.BulletInteractive = BulletInteractive; + exports.CapsuleColliderShape = CapsuleColliderShape; + exports.CharacterController = CharacterController; + exports.ColliderShape = ColliderShape; + exports.Collision = Collision; + exports.CollisionTool = CollisionTool; + exports.CompoundColliderShape = CompoundColliderShape; + exports.ConeColliderShape = ConeColliderShape; + exports.ConfigurableConstraint = ConfigurableConstraint; + exports.Constraint3D = Constraint3D; + exports.ConstraintComponent = ConstraintComponent; + exports.ContactPoint = ContactPoint; + exports.CylinderColliderShape = CylinderColliderShape; + exports.FixedConstraint = FixedConstraint; + exports.HitResult = HitResult; + exports.MeshColliderShape = MeshColliderShape; + exports.PhysicsCollider = PhysicsCollider; + exports.PhysicsComponent = PhysicsComponent; + exports.PhysicsSettings = PhysicsSettings; + exports.PhysicsSimulation = PhysicsSimulation; + exports.PhysicsTriggerComponent = PhysicsTriggerComponent; + exports.PhysicsUpdateList = PhysicsUpdateList; + exports.Rigidbody3D = Rigidbody3D; + exports.SphereColliderShape = SphereColliderShape; + exports.StaticPlaneColliderShape = StaticPlaneColliderShape; + +}(window.Laya = window.Laya || {}, Laya)); diff --git a/examples/layaair/frontend/bin/libs/laya.physics3D.wasm.js b/examples/layaair/frontend/bin/libs/laya.physics3D.wasm.js new file mode 100644 index 0000000..30dfdf2 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.physics3D.wasm.js @@ -0,0 +1,3076 @@ +window.Physics3D = function (initialMemory, interactive) { + return new Promise((resolve) => { + var mem = new WebAssembly.Memory({ initial: initialMemory }); + fetch("laya.physics3D.wasm.wasm").then((response) => { + response.arrayBuffer().then((buffer) => { + WebAssembly.instantiate(buffer, { + LayaAirInteractive: interactive, + wasi_unstable: { + fd_close: () => { console.log('fd_close'); }, + fd_seek: () => { console.log('fd_seek'); }, + fd_write: () => { console.log('fd_write'); } + }, + env: { + memory: mem, + } + }).then((physics3D) => { + window.Physics3D = physics3D.instance.exports; + resolve(); + }); + }); + }); + }); +}; + +(function (exports, Laya) { + 'use strict'; + + class ColliderShape { + constructor() { + this._scale = new Laya.Vector3(1, 1, 1); + this._centerMatrix = new Laya.Matrix4x4(); + this._attatched = false; + this._indexInCompound = -1; + this._compoundParent = null; + this._attatchedCollisionObject = null; + this._referenceCount = 0; + this._localOffset = new Laya.Vector3(0, 0, 0); + this._localRotation = new Laya.Quaternion(0, 0, 0, 1); + this.needsCustomCollisionCallback = false; + } + static __init__() { + var bt = Laya.ILaya3D.Physics3D._bullet; + ColliderShape._btScale = bt.btVector3_create(1, 1, 1); + ColliderShape._btVector30 = bt.btVector3_create(0, 0, 0); + ColliderShape._btQuaternion0 = bt.btQuaternion_create(0, 0, 0, 1); + ColliderShape._btTransform0 = bt.btTransform_create(); + } + static _createAffineTransformation(trans, rot, outE) { + var x = rot.x, y = rot.y, z = rot.z, w = rot.w, x2 = x + x, y2 = y + y, z2 = z + z; + var xx = x * x2, xy = x * y2, xz = x * z2, yy = y * y2, yz = y * z2, zz = z * z2; + var wx = w * x2, wy = w * y2, wz = w * z2; + outE[0] = (1 - (yy + zz)); + outE[1] = (xy + wz); + outE[2] = (xz - wy); + outE[3] = 0; + outE[4] = (xy - wz); + outE[5] = (1 - (xx + zz)); + outE[6] = (yz + wx); + outE[7] = 0; + outE[8] = (xz + wy); + outE[9] = (yz - wx); + outE[10] = (1 - (xx + yy)); + outE[11] = 0; + outE[12] = trans.x; + outE[13] = trans.y; + outE[14] = trans.z; + outE[15] = 1; + } + get type() { + return this._type; + } + get localOffset() { + return this._localOffset; + } + set localOffset(value) { + this._localOffset = value; + if (this._compoundParent) + this._compoundParent._updateChildTransform(this); + } + get localRotation() { + return this._localRotation; + } + set localRotation(value) { + this._localRotation = value; + if (this._compoundParent) + this._compoundParent._updateChildTransform(this); + } + _setScale(value) { + if (this._compoundParent) { + this.updateLocalTransformations(); + } + else { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(ColliderShape._btScale, value.x, value.y, value.z); + bt.btCollisionShape_setLocalScaling(this._btShape, ColliderShape._btScale); + } + } + _addReference() { + this._referenceCount++; + } + _removeReference() { + this._referenceCount--; + } + updateLocalTransformations() { + if (this._compoundParent) { + var offset = ColliderShape._tempVector30; + Laya.Vector3.multiply(this.localOffset, this._scale, offset); + ColliderShape._createAffineTransformation(offset, this.localRotation, this._centerMatrix.elements); + } + else { + ColliderShape._createAffineTransformation(this.localOffset, this.localRotation, this._centerMatrix.elements); + } + } + cloneTo(destObject) { + var destColliderShape = destObject; + this._localOffset.cloneTo(destColliderShape.localOffset); + this._localRotation.cloneTo(destColliderShape.localRotation); + destColliderShape.localOffset = destColliderShape.localOffset; + destColliderShape.localRotation = destColliderShape.localRotation; + } + clone() { + return null; + } + destroy() { + if (this._btShape) { + Laya.ILaya3D.Physics3D._bullet.btCollisionShape_destroy(this._btShape); + this._btShape = null; + } + } + } + ColliderShape.SHAPEORIENTATION_UPX = 0; + ColliderShape.SHAPEORIENTATION_UPY = 1; + ColliderShape.SHAPEORIENTATION_UPZ = 2; + ColliderShape.SHAPETYPES_BOX = 0; + ColliderShape.SHAPETYPES_SPHERE = 1; + ColliderShape.SHAPETYPES_CYLINDER = 2; + ColliderShape.SHAPETYPES_CAPSULE = 3; + ColliderShape.SHAPETYPES_CONVEXHULL = 4; + ColliderShape.SHAPETYPES_COMPOUND = 5; + ColliderShape.SHAPETYPES_STATICPLANE = 6; + ColliderShape.SHAPETYPES_CONE = 7; + ColliderShape._tempVector30 = new Laya.Vector3(); + + class BoxColliderShape extends ColliderShape { + constructor(sizeX = 1.0, sizeY = 1.0, sizeZ = 1.0) { + super(); + this._sizeX = sizeX; + this._sizeY = sizeY; + this._sizeZ = sizeZ; + this._type = ColliderShape.SHAPETYPES_BOX; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(BoxColliderShape._btSize, sizeX / 2, sizeY / 2, sizeZ / 2); + this._btShape = bt.btBoxShape_create(BoxColliderShape._btSize); + } + static __init__() { + BoxColliderShape._btSize = Laya.ILaya3D.Physics3D._bullet.btVector3_create(0, 0, 0); + } + get sizeX() { + return this._sizeX; + } + get sizeY() { + return this._sizeY; + } + get sizeZ() { + return this._sizeZ; + } + clone() { + var dest = new BoxColliderShape(this._sizeX, this._sizeY, this._sizeZ); + this.cloneTo(dest); + return dest; + } + } + + class CapsuleColliderShape extends ColliderShape { + constructor(radius = 0.5, length = 1.25, orientation = ColliderShape.SHAPEORIENTATION_UPY) { + super(); + this._radius = radius; + this._length = length; + this._orientation = orientation; + this._type = ColliderShape.SHAPETYPES_CAPSULE; + var bt = Laya.ILaya3D.Physics3D._bullet; + switch (orientation) { + case ColliderShape.SHAPEORIENTATION_UPX: + this._btShape = bt.btCapsuleShapeX_create(radius, length - radius * 2); + break; + case ColliderShape.SHAPEORIENTATION_UPY: + this._btShape = bt.btCapsuleShape_create(radius, length - radius * 2); + break; + case ColliderShape.SHAPEORIENTATION_UPZ: + this._btShape = bt.btCapsuleShapeZ_create(radius, length - radius * 2); + break; + default: + throw "CapsuleColliderShape:unknown orientation."; + } + } + get radius() { + return this._radius; + } + get length() { + return this._length; + } + get orientation() { + return this._orientation; + } + _setScale(value) { + var fixScale = CapsuleColliderShape._tempVector30; + switch (this.orientation) { + case ColliderShape.SHAPEORIENTATION_UPX: + fixScale.x = value.x; + fixScale.y = fixScale.z = Math.max(value.y, value.z); + break; + case ColliderShape.SHAPEORIENTATION_UPY: + fixScale.y = value.y; + fixScale.x = fixScale.z = Math.max(value.x, value.z); + break; + case ColliderShape.SHAPEORIENTATION_UPZ: + fixScale.z = value.z; + fixScale.x = fixScale.y = Math.max(value.x, value.y); + break; + default: + throw "CapsuleColliderShape:unknown orientation."; + } + super._setScale(fixScale); + } + clone() { + var dest = new CapsuleColliderShape(this._radius, this._length, this._orientation); + this.cloneTo(dest); + return dest; + } + } + CapsuleColliderShape._tempVector30 = new Laya.Vector3(); + + class CompoundColliderShape extends ColliderShape { + constructor() { + super(); + this._childColliderShapes = []; + this._type = ColliderShape.SHAPETYPES_COMPOUND; + this._btShape = Laya.ILaya3D.Physics3D._bullet.btCompoundShape_create(); + } + static __init__() { + var bt = Laya.ILaya3D.Physics3D._bullet; + CompoundColliderShape._btVector3One = bt.btVector3_create(1, 1, 1); + CompoundColliderShape._btTransform = bt.btTransform_create(); + CompoundColliderShape._btOffset = bt.btVector3_create(0, 0, 0); + CompoundColliderShape._btRotation = bt.btQuaternion_create(0, 0, 0, 1); + } + _clearChildShape(shape) { + shape._attatched = false; + shape._compoundParent = null; + shape._indexInCompound = -1; + } + _addReference() { + } + _removeReference() { + } + _updateChildTransform(shape) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var offset = shape.localOffset; + var rotation = shape.localRotation; + var btOffset = ColliderShape._btVector30; + var btQuaternion = ColliderShape._btQuaternion0; + var btTransform = ColliderShape._btTransform0; + bt.btVector3_setValue(btOffset, -offset.x, offset.y, offset.z); + bt.btQuaternion_setValue(btQuaternion, -rotation.x, rotation.y, rotation.z, -rotation.w); + bt.btTransform_setOrigin(btTransform, btOffset); + bt.btTransform_setRotation(btTransform, btQuaternion); + bt.btCompoundShape_updateChildTransform(this._btShape, shape._indexInCompound, btTransform, true); + } + addChildShape(shape) { + if (shape._attatched) + throw "CompoundColliderShape: this shape has attatched to other entity."; + shape._attatched = true; + shape._compoundParent = this; + shape._indexInCompound = this._childColliderShapes.length; + this._childColliderShapes.push(shape); + var offset = shape.localOffset; + var rotation = shape.localRotation; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(CompoundColliderShape._btOffset, -offset.x, offset.y, offset.z); + bt.btQuaternion_setValue(CompoundColliderShape._btRotation, -rotation.x, rotation.y, rotation.z, -rotation.w); + bt.btTransform_setOrigin(CompoundColliderShape._btTransform, CompoundColliderShape._btOffset); + bt.btTransform_setRotation(CompoundColliderShape._btTransform, CompoundColliderShape._btRotation); + var btScale = bt.btCollisionShape_getLocalScaling(this._btShape); + bt.btCollisionShape_setLocalScaling(this._btShape, CompoundColliderShape._btVector3One); + bt.btCompoundShape_addChildShape(this._btShape, CompoundColliderShape._btTransform, shape._btShape); + bt.btCollisionShape_setLocalScaling(this._btShape, btScale); + (this._attatchedCollisionObject) && (this._attatchedCollisionObject.colliderShape = this); + } + removeChildShape(shape) { + if (shape._compoundParent === this) { + var index = shape._indexInCompound; + this._clearChildShape(shape); + var endShape = this._childColliderShapes[this._childColliderShapes.length - 1]; + endShape._indexInCompound = index; + this._childColliderShapes[index] = endShape; + this._childColliderShapes.pop(); + Laya.ILaya3D.Physics3D._bullet.btCompoundShape_removeChildShapeByIndex(this._btShape, index); + } + } + clearChildShape() { + for (var i = 0, n = this._childColliderShapes.length; i < n; i++) { + this._clearChildShape(this._childColliderShapes[i]); + Laya.ILaya3D.Physics3D._bullet.btCompoundShape_removeChildShapeByIndex(this._btShape, 0); + } + this._childColliderShapes.length = 0; + } + getChildShapeCount() { + return this._childColliderShapes.length; + } + cloneTo(destObject) { + var destCompoundColliderShape = destObject; + destCompoundColliderShape.clearChildShape(); + for (var i = 0, n = this._childColliderShapes.length; i < n; i++) + destCompoundColliderShape.addChildShape(this._childColliderShapes[i].clone()); + } + clone() { + var dest = new CompoundColliderShape(); + this.cloneTo(dest); + return dest; + } + destroy() { + super.destroy(); + for (var i = 0, n = this._childColliderShapes.length; i < n; i++) { + var childShape = this._childColliderShapes[i]; + if (childShape._referenceCount === 0) + childShape.destroy(); + } + } + } + + class ConeColliderShape extends ColliderShape { + constructor(radius = 0.5, height = 1.0, orientation = ColliderShape.SHAPEORIENTATION_UPY) { + super(); + this._radius = 1; + this._height = 0.5; + this._radius = radius; + this._height = height; + this._orientation = orientation; + this._type = ColliderShape.SHAPETYPES_CYLINDER; + var bt = Laya.ILaya3D.Physics3D._bullet; + switch (orientation) { + case ColliderShape.SHAPEORIENTATION_UPX: + this._btShape = bt.btConeShapeX_create(radius, height); + break; + case ColliderShape.SHAPEORIENTATION_UPY: + this._btShape = bt.btConeShape_create(radius, height); + break; + case ColliderShape.SHAPEORIENTATION_UPZ: + this._btShape = bt.btConeShapeZ_create(radius, height); + break; + default: + throw "ConeColliderShape:unknown orientation."; + } + } + get radius() { + return this._radius; + } + get height() { + return this._height; + } + get orientation() { + return this._orientation; + } + clone() { + var dest = new ConeColliderShape(this._radius, this._height, this._orientation); + this.cloneTo(dest); + return dest; + } + } + + class CylinderColliderShape extends ColliderShape { + constructor(radius = 0.5, height = 1.0, orientation = ColliderShape.SHAPEORIENTATION_UPY) { + super(); + this._radius = 1; + this._height = 0.5; + this._radius = radius; + this._height = height; + this._orientation = orientation; + this._type = ColliderShape.SHAPETYPES_CYLINDER; + var bt = Laya.ILaya3D.Physics3D._bullet; + switch (orientation) { + case ColliderShape.SHAPEORIENTATION_UPX: + bt.btVector3_setValue(CylinderColliderShape._btSize, height / 2, radius, radius); + this._btShape = bt.btCylinderShapeX_create(CylinderColliderShape._btSize); + break; + case ColliderShape.SHAPEORIENTATION_UPY: + bt.btVector3_setValue(CylinderColliderShape._btSize, radius, height / 2, radius); + this._btShape = bt.btCylinderShape_create(CylinderColliderShape._btSize); + break; + case ColliderShape.SHAPEORIENTATION_UPZ: + bt.btVector3_setValue(CylinderColliderShape._btSize, radius, radius, height / 2); + this._btShape = bt.btCylinderShapeZ_create(CylinderColliderShape._btSize); + break; + default: + throw "CapsuleColliderShape:unknown orientation."; + } + } + static __init__() { + CylinderColliderShape._btSize = Laya.ILaya3D.Physics3D._bullet.btVector3_create(0, 0, 0); + } + get radius() { + return this._radius; + } + get height() { + return this._height; + } + get orientation() { + return this._orientation; + } + clone() { + var dest = new CylinderColliderShape(this._radius, this._height, this._orientation); + this.cloneTo(dest); + return dest; + } + } + + class MeshColliderShape extends ColliderShape { + constructor() { + super(); + this._mesh = null; + this._convex = false; + } + get mesh() { + return this._mesh; + } + set mesh(value) { + if (this._mesh !== value) { + var bt = Laya.ILaya3D.Physics3D._bullet; + if (this._mesh) { + bt.btCollisionShape_destroy(this._btShape); + } + if (value) { + this._btShape = bt.btGImpactMeshShape_create(value._getPhysicMesh()); + bt.btGImpactShapeInterface_updateBound(this._btShape); + } + this._mesh = value; + } + } + get convex() { + return this._convex; + } + set convex(value) { + this._convex = value; + } + _setScale(value) { + if (this._compoundParent) { + this.updateLocalTransformations(); + } + else { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(ColliderShape._btScale, value.x, value.y, value.z); + bt.btCollisionShape_setLocalScaling(this._btShape, ColliderShape._btScale); + bt.btGImpactShapeInterface_updateBound(this._btShape); + } + } + cloneTo(destObject) { + var destMeshCollider = destObject; + destMeshCollider.convex = this._convex; + destMeshCollider.mesh = this._mesh; + super.cloneTo(destObject); + } + clone() { + var dest = new MeshColliderShape(); + this.cloneTo(dest); + return dest; + } + destroy() { + if (this._btShape) { + Laya.ILaya3D.Physics3D._bullet.btCollisionShape_destroy(this._btShape); + this._btShape = null; + } + } + } + + class SphereColliderShape extends ColliderShape { + constructor(radius = 0.5) { + super(); + this._radius = radius; + this._type = ColliderShape.SHAPETYPES_SPHERE; + this._btShape = Laya.ILaya3D.Physics3D._bullet.btSphereShape_create(radius); + } + get radius() { + return this._radius; + } + clone() { + var dest = new SphereColliderShape(this._radius); + this.cloneTo(dest); + return dest; + } + } + + class PhysicsComponent extends Laya.Component { + constructor(collisionGroup, canCollideWith) { + super(); + this._restitution = 0.0; + this._friction = 0.5; + this._rollingFriction = 0.0; + this._ccdMotionThreshold = 0.0; + this._ccdSweptSphereRadius = 0.0; + this._collisionGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER; + this._canCollideWith = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER; + this._colliderShape = null; + this._transformFlag = 2147483647; + this._controlBySimulation = false; + this._enableProcessCollisions = true; + this._inPhysicUpdateListIndex = -1; + this.canScaleShape = true; + this._collisionGroup = collisionGroup; + this._canCollideWith = canCollideWith; + PhysicsComponent._physicObjectsMap[this.id] = this; + } + static __init__() { + var bt = Laya.ILaya3D.Physics3D._bullet; + PhysicsComponent._btVector30 = bt.btVector3_create(0, 0, 0); + PhysicsComponent._btQuaternion0 = bt.btQuaternion_create(0, 0, 0, 1); + } + static _createAffineTransformationArray(tranX, tranY, tranZ, rotX, rotY, rotZ, rotW, scale, outE) { + var x2 = rotX + rotX, y2 = rotY + rotY, z2 = rotZ + rotZ; + var xx = rotX * x2, xy = rotX * y2, xz = rotX * z2, yy = rotY * y2, yz = rotY * z2, zz = rotZ * z2; + var wx = rotW * x2, wy = rotW * y2, wz = rotW * z2, sx = scale[0], sy = scale[1], sz = scale[2]; + outE[0] = (1 - (yy + zz)) * sx; + outE[1] = (xy + wz) * sx; + outE[2] = (xz - wy) * sx; + outE[3] = 0; + outE[4] = (xy - wz) * sy; + outE[5] = (1 - (xx + zz)) * sy; + outE[6] = (yz + wx) * sy; + outE[7] = 0; + outE[8] = (xz + wy) * sz; + outE[9] = (yz - wx) * sz; + outE[10] = (1 - (xx + yy)) * sz; + outE[11] = 0; + outE[12] = tranX; + outE[13] = tranY; + outE[14] = tranZ; + outE[15] = 1; + } + static _creatShape(shapeData) { + var colliderShape; + switch (shapeData.type) { + case "BoxColliderShape": + var sizeData = shapeData.size; + colliderShape = sizeData ? new BoxColliderShape(sizeData[0], sizeData[1], sizeData[2]) : new BoxColliderShape(); + break; + case "SphereColliderShape": + colliderShape = new SphereColliderShape(shapeData.radius); + break; + case "CapsuleColliderShape": + colliderShape = new CapsuleColliderShape(shapeData.radius, shapeData.height, shapeData.orientation); + break; + case "MeshColliderShape": + var meshCollider = new MeshColliderShape(); + shapeData.mesh && (meshCollider.mesh = Laya.Loader.getRes(shapeData.mesh)); + colliderShape = meshCollider; + break; + case "ConeColliderShape": + colliderShape = new ConeColliderShape(shapeData.radius, shapeData.height, shapeData.orientation); + break; + case "CylinderColliderShape": + colliderShape = new CylinderColliderShape(shapeData.radius, shapeData.height, shapeData.orientation); + break; + default: + throw "unknown shape type."; + } + if (shapeData.center) { + var localOffset = colliderShape.localOffset; + localOffset.fromArray(shapeData.center); + colliderShape.localOffset = localOffset; + } + return colliderShape; + } + static physicVector3TransformQuat(source, qx, qy, qz, qw, out) { + var x = source.x, y = source.y, z = source.z, ix = qw * x + qy * z - qz * y, iy = qw * y + qz * x - qx * z, iz = qw * z + qx * y - qy * x, iw = -qx * x - qy * y - qz * z; + out.x = ix * qw + iw * -qx + iy * -qz - iz * -qy; + out.y = iy * qw + iw * -qy + iz * -qx - ix * -qz; + out.z = iz * qw + iw * -qz + ix * -qy - iy * -qx; + } + static physicQuaternionMultiply(lx, ly, lz, lw, right, out) { + var rx = right.x; + var ry = right.y; + var rz = right.z; + var rw = right.w; + var a = (ly * rz - lz * ry); + var b = (lz * rx - lx * rz); + var c = (lx * ry - ly * rx); + var d = (lx * rx + ly * ry + lz * rz); + out.x = (lx * rw + rx * lw) + a; + out.y = (ly * rw + ry * lw) + b; + out.z = (lz * rw + rz * lw) + c; + out.w = lw * rw - d; + } + get restitution() { + return this._restitution; + } + set restitution(value) { + this._restitution = value; + this._btColliderObject && Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setRestitution(this._btColliderObject, value); + } + get friction() { + return this._friction; + } + set friction(value) { + this._friction = value; + this._btColliderObject && Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setFriction(this._btColliderObject, value); + } + get rollingFriction() { + return this._rollingFriction; + } + set rollingFriction(value) { + this._rollingFriction = value; + this._btColliderObject && Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setRollingFriction(this._btColliderObject, value); + } + get ccdMotionThreshold() { + return this._ccdMotionThreshold; + } + set ccdMotionThreshold(value) { + this._ccdMotionThreshold = value; + this._btColliderObject && Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setCcdMotionThreshold(this._btColliderObject, value); + } + get ccdSweptSphereRadius() { + return this._ccdSweptSphereRadius; + } + set ccdSweptSphereRadius(value) { + this._ccdSweptSphereRadius = value; + this._btColliderObject && Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setCcdSweptSphereRadius(this._btColliderObject, value); + } + get isActive() { + return this._btColliderObject ? Laya.ILaya3D.Physics3D._bullet.btCollisionObject_isActive(this._btColliderObject) : false; + } + get colliderShape() { + return this._colliderShape; + } + set colliderShape(value) { + var lastColliderShape = this._colliderShape; + if (lastColliderShape) { + lastColliderShape._attatched = false; + lastColliderShape._attatchedCollisionObject = null; + } + this._colliderShape = value; + if (value) { + if (value._attatched) { + throw "PhysicsComponent: this shape has attatched to other entity."; + } + else { + value._attatched = true; + value._attatchedCollisionObject = this; + } + if (this._btColliderObject) { + Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setCollisionShape(this._btColliderObject, value._btShape); + var canInSimulation = this._simulation && this._enabled; + (canInSimulation && lastColliderShape) && (this._removeFromSimulation()); + this._onShapeChange(value); + if (canInSimulation) { + this._derivePhysicsTransformation(true); + this._addToSimulation(); + } + } + } + else { + if (this._simulation && this._enabled) + lastColliderShape && this._removeFromSimulation(); + } + } + get simulation() { + return this._simulation; + } + get collisionGroup() { + return this._collisionGroup; + } + set collisionGroup(value) { + if (this._collisionGroup !== value) { + this._collisionGroup = value; + if (this._simulation && this._colliderShape && this._enabled) { + this._removeFromSimulation(); + this._addToSimulation(); + } + } + } + get canCollideWith() { + return this._canCollideWith; + } + set canCollideWith(value) { + if (this._canCollideWith !== value) { + this._canCollideWith = value; + if (this._simulation && this._colliderShape && this._enabled) { + this._removeFromSimulation(); + this._addToSimulation(); + } + } + } + _parseShape(shapesData) { + var shapeCount = shapesData.length; + if (shapeCount === 1) { + var shape = PhysicsComponent._creatShape(shapesData[0]); + this.colliderShape = shape; + } + else { + var compoundShape = new CompoundColliderShape(); + for (var i = 0; i < shapeCount; i++) { + shape = PhysicsComponent._creatShape(shapesData[i]); + compoundShape.addChildShape(shape); + } + this.colliderShape = compoundShape; + } + } + _onScaleChange(scale) { + this._colliderShape._setScale(scale); + } + _onEnable() { + this._simulation = this.owner._scene.physicsSimulation; + Laya.ILaya3D.Physics3D._bullet.btCollisionObject_setContactProcessingThreshold(this._btColliderObject, 0); + if (this._colliderShape) { + this._derivePhysicsTransformation(true); + this._addToSimulation(); + } + } + _onDisable() { + if (this._colliderShape) { + this._removeFromSimulation(); + (this._inPhysicUpdateListIndex !== -1) && (this._simulation._physicsUpdateList.remove(this)); + } + this._simulation = null; + } + _onDestroy() { + delete PhysicsComponent._physicObjectsMap[this.id]; + Laya.ILaya3D.Physics3D._bullet.btCollisionObject_destroy(this._btColliderObject); + this._colliderShape.destroy(); + super._onDestroy(); + this._btColliderObject = null; + this._colliderShape = null; + this._simulation = null; + this.owner.transform.off(Laya.Event.TRANSFORM_CHANGED, this, this._onTransformChanged); + } + _isValid() { + return this._simulation && this._colliderShape && this._enabled; + } + _parse(data) { + (data.collisionGroup != null) && (this.collisionGroup = data.collisionGroup); + (data.canCollideWith != null) && (this.canCollideWith = data.canCollideWith); + (data.ccdMotionThreshold != null) && (this.ccdMotionThreshold = data.ccdMotionThreshold); + (data.ccdSweptSphereRadius != null) && (this.ccdSweptSphereRadius = data.ccdSweptSphereRadius); + } + _setTransformFlag(type, value) { + if (value) + this._transformFlag |= type; + else + this._transformFlag &= ~type; + } + _getTransformFlag(type) { + return (this._transformFlag & type) != 0; + } + _addToSimulation() { + } + _removeFromSimulation() { + } + _derivePhysicsTransformation(force) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var btColliderObject = this._btColliderObject; + var btTransform = bt.btCollisionObject_getWorldTransform(btColliderObject); + this._innerDerivePhysicsTransformation(btTransform, force); + bt.btCollisionObject_setWorldTransform(btColliderObject, btTransform); + } + _innerDerivePhysicsTransformation(physicTransformOut, force) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var transform = this.owner._transform; + if (force || this._getTransformFlag(Laya.Transform3D.TRANSFORM_WORLDPOSITION)) { + var shapeOffset = this._colliderShape.localOffset; + var position = transform.position; + var btPosition = PhysicsComponent._btVector30; + if (shapeOffset.x !== 0 || shapeOffset.y !== 0 || shapeOffset.z !== 0) { + var physicPosition = PhysicsComponent._tempVector30; + var worldMat = transform.worldMatrix; + Laya.Vector3.transformCoordinate(shapeOffset, worldMat, physicPosition); + bt.btVector3_setValue(btPosition, -physicPosition.x, physicPosition.y, physicPosition.z); + } + else { + bt.btVector3_setValue(btPosition, -position.x, position.y, position.z); + } + bt.btTransform_setOrigin(physicTransformOut, btPosition); + this._setTransformFlag(Laya.Transform3D.TRANSFORM_WORLDPOSITION, false); + } + if (force || this._getTransformFlag(Laya.Transform3D.TRANSFORM_WORLDQUATERNION)) { + var shapeRotation = this._colliderShape.localRotation; + var btRotation = PhysicsComponent._btQuaternion0; + var rotation = transform.rotation; + if (shapeRotation.x !== 0 || shapeRotation.y !== 0 || shapeRotation.z !== 0 || shapeRotation.w !== 1) { + var physicRotation = PhysicsComponent._tempQuaternion0; + PhysicsComponent.physicQuaternionMultiply(rotation.x, rotation.y, rotation.z, rotation.w, shapeRotation, physicRotation); + bt.btQuaternion_setValue(btRotation, -physicRotation.x, physicRotation.y, physicRotation.z, -physicRotation.w); + } + else { + bt.btQuaternion_setValue(btRotation, -rotation.x, rotation.y, rotation.z, -rotation.w); + } + bt.btTransform_setRotation(physicTransformOut, btRotation); + this._setTransformFlag(Laya.Transform3D.TRANSFORM_WORLDQUATERNION, false); + } + if (force || this._getTransformFlag(Laya.Transform3D.TRANSFORM_WORLDSCALE)) { + this._onScaleChange(transform.getWorldLossyScale()); + this._setTransformFlag(Laya.Transform3D.TRANSFORM_WORLDSCALE, false); + } + } + _updateTransformComponent(physicsTransform) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var colliderShape = this._colliderShape; + var localOffset = colliderShape.localOffset; + var localRotation = colliderShape.localRotation; + var transform = this.owner._transform; + var position = transform.position; + var rotation = transform.rotation; + var btPosition = bt.btTransform_getOrigin(physicsTransform); + var btRotation = bt.btTransform_getRotation(physicsTransform); + var btRotX = -bt.btQuaternion_x(btRotation); + var btRotY = bt.btQuaternion_y(btRotation); + var btRotZ = bt.btQuaternion_z(btRotation); + var btRotW = -bt.btQuaternion_w(btRotation); + if (localRotation.x !== 0 || localRotation.y !== 0 || localRotation.z !== 0 || localRotation.w !== 1) { + var invertShapeRotaion = PhysicsComponent._tempQuaternion0; + localRotation.invert(invertShapeRotaion); + PhysicsComponent.physicQuaternionMultiply(btRotX, btRotY, btRotZ, btRotW, invertShapeRotaion, rotation); + } + else { + rotation.x = btRotX; + rotation.y = btRotY; + rotation.z = btRotZ; + rotation.w = btRotW; + } + transform.rotation = rotation; + if (localOffset.x !== 0 || localOffset.y !== 0 || localOffset.z !== 0) { + var btScale = bt.btCollisionShape_getLocalScaling(colliderShape._btShape); + var rotShapePosition = PhysicsComponent._tempVector30; + rotShapePosition.x = localOffset.x * bt.btVector3_x(btScale); + rotShapePosition.y = localOffset.y * bt.btVector3_y(btScale); + rotShapePosition.z = localOffset.z * bt.btVector3_z(btScale); + Laya.Vector3.transformQuat(rotShapePosition, rotation, rotShapePosition); + position.x = -bt.btVector3_x(btPosition) - rotShapePosition.x; + position.y = bt.btVector3_y(btPosition) - rotShapePosition.y; + position.z = bt.btVector3_z(btPosition) - rotShapePosition.z; + } + else { + position.x = -bt.btVector3_x(btPosition); + position.y = bt.btVector3_y(btPosition); + position.z = bt.btVector3_z(btPosition); + } + transform.position = position; + } + _onShapeChange(colShape) { + var btColObj = this._btColliderObject; + var bt = Laya.ILaya3D.Physics3D._bullet; + var flags = bt.btCollisionObject_getCollisionFlags(btColObj); + if (colShape.needsCustomCollisionCallback) { + if ((flags & PhysicsComponent.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK) === 0) + bt.btCollisionObject_setCollisionFlags(btColObj, flags | PhysicsComponent.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK); + } + else { + if ((flags & PhysicsComponent.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK) > 0) + bt.btCollisionObject_setCollisionFlags(btColObj, flags ^ PhysicsComponent.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK); + } + } + _onAdded() { + this.enabled = this._enabled; + this.restitution = this._restitution; + this.friction = this._friction; + this.rollingFriction = this._rollingFriction; + this.ccdMotionThreshold = this._ccdMotionThreshold; + this.ccdSweptSphereRadius = this._ccdSweptSphereRadius; + this.owner.transform.on(Laya.Event.TRANSFORM_CHANGED, this, this._onTransformChanged); + } + _onTransformChanged(flag) { + if (PhysicsComponent._addUpdateList || !this._controlBySimulation) { + flag &= Laya.Transform3D.TRANSFORM_WORLDPOSITION | Laya.Transform3D.TRANSFORM_WORLDQUATERNION | Laya.Transform3D.TRANSFORM_WORLDSCALE; + if (flag) { + this._transformFlag |= flag; + if (this._isValid() && this._inPhysicUpdateListIndex === -1) + this._simulation._physicsUpdateList.add(this); + } + } + } + _cloneTo(dest) { + var destPhysicsComponent = dest; + destPhysicsComponent.restitution = this._restitution; + destPhysicsComponent.friction = this._friction; + destPhysicsComponent.rollingFriction = this._rollingFriction; + destPhysicsComponent.ccdMotionThreshold = this._ccdMotionThreshold; + destPhysicsComponent.ccdSweptSphereRadius = this._ccdSweptSphereRadius; + destPhysicsComponent.collisionGroup = this._collisionGroup; + destPhysicsComponent.canCollideWith = this._canCollideWith; + destPhysicsComponent.canScaleShape = this.canScaleShape; + (this._colliderShape) && (destPhysicsComponent.colliderShape = this._colliderShape.clone()); + } + } + PhysicsComponent.ACTIVATIONSTATE_ACTIVE_TAG = 1; + PhysicsComponent.ACTIVATIONSTATE_ISLAND_SLEEPING = 2; + PhysicsComponent.ACTIVATIONSTATE_WANTS_DEACTIVATION = 3; + PhysicsComponent.ACTIVATIONSTATE_DISABLE_DEACTIVATION = 4; + PhysicsComponent.ACTIVATIONSTATE_DISABLE_SIMULATION = 5; + PhysicsComponent.COLLISIONFLAGS_STATIC_OBJECT = 1; + PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT = 2; + PhysicsComponent.COLLISIONFLAGS_NO_CONTACT_RESPONSE = 4; + PhysicsComponent.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK = 8; + PhysicsComponent.COLLISIONFLAGS_CHARACTER_OBJECT = 16; + PhysicsComponent.COLLISIONFLAGS_DISABLE_VISUALIZE_OBJECT = 32; + PhysicsComponent.COLLISIONFLAGS_DISABLE_SPU_COLLISION_PROCESSING = 64; + PhysicsComponent._tempVector30 = new Laya.Vector3(); + PhysicsComponent._tempQuaternion0 = new Laya.Quaternion(); + PhysicsComponent._tempQuaternion1 = new Laya.Quaternion(); + PhysicsComponent._tempMatrix4x40 = new Laya.Matrix4x4(); + PhysicsComponent._physicObjectsMap = {}; + PhysicsComponent._addUpdateList = true; + + class BulletInteractive { + } + BulletInteractive._interactive = { + "getWorldTransform": (rigidBodyID, worldTransPointer) => { + }, + "setWorldTransform": (rigidBodyID, worldTransPointer) => { + var rigidBody = PhysicsComponent._physicObjectsMap[rigidBodyID]; + rigidBody._simulation._updatedRigidbodies++; + rigidBody._updateTransformComponent(worldTransPointer); + } + }; + + class CharacterController extends PhysicsComponent { + constructor(stepheight = 0.1, upAxis = null, collisionGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER, canCollideWith = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + super(collisionGroup, canCollideWith); + this._upAxis = new Laya.Vector3(0, 1, 0); + this._maxSlope = 45.0; + this._jumpSpeed = 10.0; + this._fallSpeed = 55.0; + this._gravity = new Laya.Vector3(0, -9.8 * 3, 0); + this._btKinematicCharacter = null; + this._stepHeight = stepheight; + (upAxis) && (this._upAxis = upAxis); + this._controlBySimulation = true; + } + static __init__() { + CharacterController._btTempVector30 = Laya.ILaya3D.Physics3D._bullet.btVector3_create(0, 0, 0); + } + get fallSpeed() { + return this._fallSpeed; + } + set fallSpeed(value) { + this._fallSpeed = value; + Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setFallSpeed(this._btKinematicCharacter, value); + } + get jumpSpeed() { + return this._jumpSpeed; + } + set jumpSpeed(value) { + this._jumpSpeed = value; + Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setJumpSpeed(this._btKinematicCharacter, value); + } + get gravity() { + return this._gravity; + } + set gravity(value) { + this._gravity = value; + var bt = Laya.ILaya3D.Physics3D._bullet; + var btGravity = CharacterController._btTempVector30; + bt.btVector3_setValue(btGravity, -value.x, value.y, value.z); + bt.btKinematicCharacterController_setGravity(this._btKinematicCharacter, btGravity); + } + get maxSlope() { + return this._maxSlope; + } + set maxSlope(value) { + this._maxSlope = value; + Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setMaxSlope(this._btKinematicCharacter, (value / 180) * Math.PI); + } + get isGrounded() { + return Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_onGround(this._btKinematicCharacter); + } + get stepHeight() { + return this._stepHeight; + } + set stepHeight(value) { + this._stepHeight = value; + Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setStepHeight(this._btKinematicCharacter, value); + } + get upAxis() { + return this._upAxis; + } + set upAxis(value) { + this._upAxis = value; + var btUpAxis = CharacterController._btTempVector30; + Laya.Utils3D._convertToBulletVec3(value, btUpAxis, false); + Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setUp(this._btKinematicCharacter, btUpAxis); + } + _constructCharacter() { + var bt = Laya.ILaya3D.Physics3D._bullet; + if (this._btKinematicCharacter) + bt.btKinematicCharacterController_destroy(this._btKinematicCharacter); + var btUpAxis = CharacterController._btTempVector30; + bt.btVector3_setValue(btUpAxis, this._upAxis.x, this._upAxis.y, this._upAxis.z); + this._btKinematicCharacter = bt.btKinematicCharacterController_create(this._btColliderObject, this._colliderShape._btShape, this._stepHeight, btUpAxis); + this.fallSpeed = this._fallSpeed; + this.maxSlope = this._maxSlope; + this.jumpSpeed = this._jumpSpeed; + this.gravity = this._gravity; + } + _onShapeChange(colShape) { + super._onShapeChange(colShape); + this._constructCharacter(); + } + _onAdded() { + var bt = Laya.ILaya3D.Physics3D._bullet; + var ghostObject = bt.btPairCachingGhostObject_create(); + bt.btCollisionObject_setUserIndex(ghostObject, this.id); + bt.btCollisionObject_setCollisionFlags(ghostObject, PhysicsComponent.COLLISIONFLAGS_CHARACTER_OBJECT); + this._btColliderObject = ghostObject; + (this._colliderShape) && (this._constructCharacter()); + super._onAdded(); + } + _addToSimulation() { + this._simulation._characters.push(this); + this._simulation._addCharacter(this, this._collisionGroup, this._canCollideWith); + } + _removeFromSimulation() { + this._simulation._removeCharacter(this); + var characters = this._simulation._characters; + characters.splice(characters.indexOf(this), 1); + } + _cloneTo(dest) { + super._cloneTo(dest); + var destCharacterController = dest; + destCharacterController.stepHeight = this._stepHeight; + destCharacterController.upAxis = this._upAxis; + destCharacterController.maxSlope = this._maxSlope; + destCharacterController.jumpSpeed = this._jumpSpeed; + destCharacterController.fallSpeed = this._fallSpeed; + destCharacterController.gravity = this._gravity; + } + _onDestroy() { + Laya.ILaya3D.Physics3D._bullet.btKinematicCharacterController_destroy(this._btKinematicCharacter); + super._onDestroy(); + this._btKinematicCharacter = null; + } + move(movement) { + var btMovement = CharacterController._btVector30; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(btMovement, -movement.x, movement.y, movement.z); + bt.btKinematicCharacterController_setWalkDirection(this._btKinematicCharacter, btMovement); + } + jump(velocity = null) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var btVelocity = CharacterController._btVector30; + if (velocity) { + Laya.Utils3D._convertToBulletVec3(velocity, btVelocity, true); + bt.btKinematicCharacterController_jump(this._btKinematicCharacter, btVelocity); + } + else { + bt.btVector3_setValue(btVelocity, 0, 0, 0); + bt.btKinematicCharacterController_jump(this._btKinematicCharacter, btVelocity); + } + } + } + CharacterController.UPAXIS_X = 0; + CharacterController.UPAXIS_Y = 1; + CharacterController.UPAXIS_Z = 2; + + class Collision { + constructor() { + this._lastUpdateFrame = -2147483648; + this._updateFrame = -2147483648; + this._isTrigger = false; + this.contacts = []; + } + _setUpdateFrame(farme) { + this._lastUpdateFrame = this._updateFrame; + this._updateFrame = farme; + } + } + + class ContactPoint { + constructor() { + this._idCounter = 0; + this.colliderA = null; + this.colliderB = null; + this.distance = 0; + this.normal = new Laya.Vector3(); + this.positionOnA = new Laya.Vector3(); + this.positionOnB = new Laya.Vector3(); + this._id = ++this._idCounter; + } + } + + class HitResult { + constructor() { + this.succeeded = false; + this.collider = null; + this.point = new Laya.Vector3(); + this.normal = new Laya.Vector3(); + this.hitFraction = 0; + } + } + + class CollisionTool { + constructor() { + this._hitResultsPoolIndex = 0; + this._hitResultsPool = []; + this._contactPonintsPoolIndex = 0; + this._contactPointsPool = []; + this._collisionsPool = []; + this._collisions = {}; + } + getHitResult() { + var hitResult = this._hitResultsPool[this._hitResultsPoolIndex++]; + if (!hitResult) { + hitResult = new HitResult(); + this._hitResultsPool.push(hitResult); + } + return hitResult; + } + recoverAllHitResultsPool() { + this._hitResultsPoolIndex = 0; + } + getContactPoints() { + var contactPoint = this._contactPointsPool[this._contactPonintsPoolIndex++]; + if (!contactPoint) { + contactPoint = new ContactPoint(); + this._contactPointsPool.push(contactPoint); + } + return contactPoint; + } + recoverAllContactPointsPool() { + this._contactPonintsPoolIndex = 0; + } + getCollision(physicComponentA, physicComponentB) { + var collision; + var idA = physicComponentA.id; + var idB = physicComponentB.id; + var subCollisionFirst = this._collisions[idA]; + if (subCollisionFirst) + collision = subCollisionFirst[idB]; + if (!collision) { + if (!subCollisionFirst) { + subCollisionFirst = {}; + this._collisions[idA] = subCollisionFirst; + } + collision = this._collisionsPool.length === 0 ? new Collision() : this._collisionsPool.pop(); + collision._colliderA = physicComponentA; + collision._colliderB = physicComponentB; + subCollisionFirst[idB] = collision; + } + return collision; + } + recoverCollision(collision) { + var idA = collision._colliderA.id; + var idB = collision._colliderB.id; + this._collisions[idA][idB] = null; + this._collisionsPool.push(collision); + } + garbageCollection() { + this._hitResultsPoolIndex = 0; + this._hitResultsPool.length = 0; + this._contactPonintsPoolIndex = 0; + this._contactPointsPool.length = 0; + this._collisionsPool.length = 0; + for (var subCollisionsKey in this._collisionsPool) { + var subCollisions = this._collisionsPool[subCollisionsKey]; + var wholeDelete = true; + for (var collisionKey in subCollisions) { + if (subCollisions[collisionKey]) + wholeDelete = false; + else + delete subCollisions[collisionKey]; + } + if (wholeDelete) + delete this._collisionsPool[subCollisionsKey]; + } + } + } + + class Constraint3D { + constructor() { + } + } + + class PhysicsTriggerComponent extends PhysicsComponent { + constructor(collisionGroup, canCollideWith) { + super(collisionGroup, canCollideWith); + this._isTrigger = false; + } + get isTrigger() { + return this._isTrigger; + } + set isTrigger(value) { + this._isTrigger = value; + var bt = Laya.ILaya3D.Physics3D._bullet; + if (this._btColliderObject) { + var flags = bt.btCollisionObject_getCollisionFlags(this._btColliderObject); + if (value) { + if ((flags & PhysicsComponent.COLLISIONFLAGS_NO_CONTACT_RESPONSE) === 0) + bt.btCollisionObject_setCollisionFlags(this._btColliderObject, flags | PhysicsComponent.COLLISIONFLAGS_NO_CONTACT_RESPONSE); + } + else { + if ((flags & PhysicsComponent.COLLISIONFLAGS_NO_CONTACT_RESPONSE) !== 0) + bt.btCollisionObject_setCollisionFlags(this._btColliderObject, flags ^ PhysicsComponent.COLLISIONFLAGS_NO_CONTACT_RESPONSE); + } + } + } + _onAdded() { + super._onAdded(); + this.isTrigger = this._isTrigger; + } + _cloneTo(dest) { + super._cloneTo(dest); + dest.isTrigger = this._isTrigger; + } + } + + class PhysicsCollider extends PhysicsTriggerComponent { + constructor(collisionGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER, canCollideWith = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + super(collisionGroup, canCollideWith); + this._enableProcessCollisions = false; + } + _addToSimulation() { + this._simulation._addPhysicsCollider(this, this._collisionGroup, this._canCollideWith); + } + _removeFromSimulation() { + this._simulation._removePhysicsCollider(this); + } + _parse(data) { + (data.friction != null) && (this.friction = data.friction); + (data.rollingFriction != null) && (this.rollingFriction = data.rollingFriction); + (data.restitution != null) && (this.restitution = data.restitution); + (data.isTrigger != null) && (this.isTrigger = data.isTrigger); + super._parse(data); + this._parseShape(data.shapes); + } + _onAdded() { + var bt = Laya.Physics3D._bullet; + var btColObj = bt.btCollisionObject_create(); + bt.btCollisionObject_setUserIndex(btColObj, this.id); + bt.btCollisionObject_forceActivationState(btColObj, PhysicsComponent.ACTIVATIONSTATE_DISABLE_SIMULATION); + var flags = bt.btCollisionObject_getCollisionFlags(btColObj); + if (this.owner.isStatic) { + if ((flags & PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT) > 0) + flags = flags ^ PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT; + flags = flags | PhysicsComponent.COLLISIONFLAGS_STATIC_OBJECT; + } + else { + if ((flags & PhysicsComponent.COLLISIONFLAGS_STATIC_OBJECT) > 0) + flags = flags ^ PhysicsComponent.COLLISIONFLAGS_STATIC_OBJECT; + flags = flags | PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT; + } + bt.btCollisionObject_setCollisionFlags(btColObj, flags); + this._btColliderObject = btColObj; + super._onAdded(); + } + } + + class PhysicsSettings { + constructor() { + this.flags = 0; + this.maxSubSteps = 1; + this.fixedTimeStep = 1.0 / 60.0; + } + } + + class PhysicsUpdateList extends Laya.SingletonList { + constructor() { + super(); + } + add(element) { + var index = element._inPhysicUpdateListIndex; + if (index !== -1) + throw "PhysicsUpdateList:element has in PhysicsUpdateList."; + this._add(element); + element._inPhysicUpdateListIndex = this.length++; + } + remove(element) { + var index = element._inPhysicUpdateListIndex; + this.length--; + if (index !== this.length) { + var end = this.elements[this.length]; + this.elements[index] = end; + end._inPhysicUpdateListIndex = index; + } + element._inPhysicUpdateListIndex = -1; + } + } + + class PhysicsSimulation { + constructor(configuration) { + this._gravity = new Laya.Vector3(0, -10, 0); + this._btVector3Zero = Laya.ILaya3D.Physics3D._bullet.btVector3_create(0, 0, 0); + this._btDefaultQuaternion = Laya.ILaya3D.Physics3D._bullet.btQuaternion_create(0, 0, 0, -1); + this._collisionsUtils = new CollisionTool(); + this._previousFrameCollisions = []; + this._currentFrameCollisions = []; + this._currentConstraint = {}; + this._physicsUpdateList = new PhysicsUpdateList(); + this._characters = []; + this._updatedRigidbodies = 0; + this.maxSubSteps = 1; + this.fixedTimeStep = 1.0 / 60.0; + this.maxSubSteps = configuration.maxSubSteps; + this.fixedTimeStep = configuration.fixedTimeStep; + var bt = Laya.ILaya3D.Physics3D._bullet; + this._btCollisionConfiguration = bt.btDefaultCollisionConfiguration_create(); + this._btDispatcher = bt.btCollisionDispatcher_create(this._btCollisionConfiguration); + this._btBroadphase = bt.btDbvtBroadphase_create(); + bt.btOverlappingPairCache_setInternalGhostPairCallback(bt.btDbvtBroadphase_getOverlappingPairCache(this._btBroadphase), bt.btGhostPairCallback_create()); + var conFlags = configuration.flags; + if (conFlags & PhysicsSimulation.PHYSICSENGINEFLAGS_COLLISIONSONLY) { + this._btCollisionWorld = new bt.btCollisionWorld(this._btDispatcher, this._btBroadphase, this._btCollisionConfiguration); + } + else if (conFlags & PhysicsSimulation.PHYSICSENGINEFLAGS_SOFTBODYSUPPORT) { + throw "PhysicsSimulation:SoftBody processing is not yet available"; + } + else { + var solver = bt.btSequentialImpulseConstraintSolver_create(); + this._btDiscreteDynamicsWorld = bt.btDiscreteDynamicsWorld_create(this._btDispatcher, this._btBroadphase, solver, this._btCollisionConfiguration); + this._btCollisionWorld = this._btDiscreteDynamicsWorld; + } + if (this._btDiscreteDynamicsWorld) { + this._btSolverInfo = bt.btDynamicsWorld_getSolverInfo(this._btDiscreteDynamicsWorld); + this._btDispatchInfo = bt.btCollisionWorld_getDispatchInfo(this._btDiscreteDynamicsWorld); + } + this._btClosestRayResultCallback = bt.ClosestRayResultCallback_create(this._btVector3Zero, this._btVector3Zero); + this._btAllHitsRayResultCallback = bt.AllHitsRayResultCallback_create(this._btVector3Zero, this._btVector3Zero); + this._btClosestConvexResultCallback = bt.ClosestConvexResultCallback_create(this._btVector3Zero, this._btVector3Zero); + this._btAllConvexResultCallback = bt.AllConvexResultCallback_create(this._btVector3Zero, this._btVector3Zero); + this.setHitsRayResultCallbackFlag(); + bt.btGImpactCollisionAlgorithm_RegisterAlgorithm(this._btDispatcher); + } + static __init__() { + var bt = Laya.ILaya3D.Physics3D._bullet; + PhysicsSimulation._btTempVector30 = bt.btVector3_create(0, 0, 0); + PhysicsSimulation._btTempVector31 = bt.btVector3_create(0, 0, 0); + PhysicsSimulation._btTempQuaternion0 = bt.btQuaternion_create(0, 0, 0, 1); + PhysicsSimulation._btTempQuaternion1 = bt.btQuaternion_create(0, 0, 0, 1); + PhysicsSimulation._btTempTransform0 = bt.btTransform_create(); + PhysicsSimulation._btTempTransform1 = bt.btTransform_create(); + } + static createConstraint() { + } + get continuousCollisionDetection() { + return Laya.ILaya3D.Physics3D._bullet.btCollisionWorld_get_m_useContinuous(this._btDispatchInfo); + } + set continuousCollisionDetection(value) { + Laya.ILaya3D.Physics3D._bullet.btCollisionWorld_set_m_useContinuous(this._btDispatchInfo, value); + } + get gravity() { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + return this._gravity; + } + set gravity(value) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + this._gravity = value; + var bt = Laya.ILaya3D.Physics3D._bullet; + var btGravity = PhysicsSimulation._btTempVector30; + bt.btVector3_setValue(btGravity, -value.x, value.y, value.z); + bt.btDiscreteDynamicsWorld_setGravity(this._btDiscreteDynamicsWorld, btGravity); + } + get speculativeContactRestitution() { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot Cannot perform this action when the physics engine is set to CollisionsOnly"; + return Laya.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_getApplySpeculativeContactRestitution(this._btDiscreteDynamicsWorld); + } + set speculativeContactRestitution(value) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot Cannot perform this action when the physics engine is set to CollisionsOnly"; + Laya.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_setApplySpeculativeContactRestitution(this._btDiscreteDynamicsWorld, value); + } + _simulate(deltaTime) { + this._updatedRigidbodies = 0; + var bt = Laya.ILaya3D.Physics3D._bullet; + if (this._btDiscreteDynamicsWorld) + bt.btDiscreteDynamicsWorld_stepSimulation(this._btDiscreteDynamicsWorld, deltaTime, this.maxSubSteps, this.fixedTimeStep); + else + bt.PerformDiscreteCollisionDetection(this._btCollisionWorld); + } + _destroy() { + var bt = Laya.ILaya3D.Physics3D._bullet; + if (this._btDiscreteDynamicsWorld) { + bt.btCollisionWorld_destroy(this._btDiscreteDynamicsWorld); + this._btDiscreteDynamicsWorld = null; + } + else { + bt.btCollisionWorld_destroy(this._btCollisionWorld); + this._btCollisionWorld = null; + } + bt.btDbvtBroadphase_destroy(this._btBroadphase); + this._btBroadphase = null; + bt.btCollisionDispatcher_destroy(this._btDispatcher); + this._btDispatcher = null; + bt.btDefaultCollisionConfiguration_destroy(this._btCollisionConfiguration); + this._btCollisionConfiguration = null; + } + _addPhysicsCollider(component, group, mask) { + Laya.ILaya3D.Physics3D._bullet.btCollisionWorld_addCollisionObject(this._btCollisionWorld, component._btColliderObject, group, mask); + } + _removePhysicsCollider(component) { + Laya.ILaya3D.Physics3D._bullet.btCollisionWorld_removeCollisionObject(this._btCollisionWorld, component._btColliderObject); + } + _addRigidBody(rigidBody, group, mask) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + Laya.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_addRigidBody(this._btCollisionWorld, rigidBody._btColliderObject, group, mask); + } + _removeRigidBody(rigidBody) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + Laya.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_removeRigidBody(this._btCollisionWorld, rigidBody._btColliderObject); + } + _addCharacter(character, group, mask) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btCollisionWorld_addCollisionObject(this._btCollisionWorld, character._btColliderObject, group, mask); + bt.btDynamicsWorld_addAction(this._btCollisionWorld, character._btKinematicCharacter); + } + _removeCharacter(character) { + if (!this._btDiscreteDynamicsWorld) + throw "Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly"; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btCollisionWorld_removeCollisionObject(this._btCollisionWorld, character._btColliderObject); + bt.btDynamicsWorld_removeAction(this._btCollisionWorld, character._btKinematicCharacter); + } + raycastFromTo(from, to, out = null, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var rayResultCall = this._btClosestRayResultCallback; + var rayFrom = PhysicsSimulation._btTempVector30; + var rayTo = PhysicsSimulation._btTempVector31; + bt.btVector3_setValue(rayFrom, -from.x, from.y, from.z); + bt.btVector3_setValue(rayTo, -to.x, to.y, to.z); + bt.ClosestRayResultCallback_set_m_rayFromWorld(rayResultCall, rayFrom); + bt.ClosestRayResultCallback_set_m_rayToWorld(rayResultCall, rayTo); + bt.RayResultCallback_set_m_collisionFilterGroup(rayResultCall, collisonGroup); + bt.RayResultCallback_set_m_collisionFilterMask(rayResultCall, collisionMask); + bt.RayResultCallback_set_m_collisionObject(rayResultCall, null); + bt.RayResultCallback_set_m_closestHitFraction(rayResultCall, 1); + bt.btCollisionWorld_rayTest(this._btCollisionWorld, rayFrom, rayTo, rayResultCall); + if (bt.RayResultCallback_hasHit(rayResultCall)) { + if (out) { + out.succeeded = true; + out.collider = PhysicsComponent._physicObjectsMap[bt.btCollisionObject_getUserIndex(bt.RayResultCallback_get_m_collisionObject(rayResultCall))]; + out.hitFraction = bt.RayResultCallback_get_m_closestHitFraction(rayResultCall); + var btPoint = bt.ClosestRayResultCallback_get_m_hitPointWorld(rayResultCall); + var point = out.point; + point.x = -bt.btVector3_x(btPoint); + point.y = bt.btVector3_y(btPoint); + point.z = bt.btVector3_z(btPoint); + var btNormal = bt.ClosestRayResultCallback_get_m_hitNormalWorld(rayResultCall); + var normal = out.normal; + normal.x = -bt.btVector3_x(btNormal); + normal.y = bt.btVector3_y(btNormal); + normal.z = bt.btVector3_z(btNormal); + } + return true; + } + else { + if (out) + out.succeeded = false; + return false; + } + } + raycastAllFromTo(from, to, out, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var rayResultCall = this._btAllHitsRayResultCallback; + var rayFrom = PhysicsSimulation._btTempVector30; + var rayTo = PhysicsSimulation._btTempVector31; + out.length = 0; + bt.btVector3_setValue(rayFrom, -from.x, from.y, from.z); + bt.btVector3_setValue(rayTo, -to.x, to.y, to.z); + bt.AllHitsRayResultCallback_set_m_rayFromWorld(rayResultCall, rayFrom); + bt.AllHitsRayResultCallback_set_m_rayToWorld(rayResultCall, rayTo); + bt.RayResultCallback_set_m_collisionFilterGroup(rayResultCall, collisonGroup); + bt.RayResultCallback_set_m_collisionFilterMask(rayResultCall, collisionMask); + var collisionObjects = bt.AllHitsRayResultCallback_get_m_collisionObjects(rayResultCall); + var btPoints = bt.AllHitsRayResultCallback_get_m_hitPointWorld(rayResultCall); + var btNormals = bt.AllHitsRayResultCallback_get_m_hitNormalWorld(rayResultCall); + var btFractions = bt.AllHitsRayResultCallback_get_m_hitFractions(rayResultCall); + bt.tBtCollisionObjectArray_clear(collisionObjects); + bt.tVector3Array_clear(btPoints); + bt.tVector3Array_clear(btNormals); + bt.tScalarArray_clear(btFractions); + bt.btCollisionWorld_rayTest(this._btCollisionWorld, rayFrom, rayTo, rayResultCall); + var count = bt.tBtCollisionObjectArray_size(collisionObjects); + if (count > 0) { + this._collisionsUtils.recoverAllHitResultsPool(); + for (var i = 0; i < count; i++) { + var hitResult = this._collisionsUtils.getHitResult(); + out.push(hitResult); + hitResult.succeeded = true; + hitResult.collider = PhysicsComponent._physicObjectsMap[bt.btCollisionObject_getUserIndex(bt.tBtCollisionObjectArray_at(collisionObjects, i))]; + hitResult.hitFraction = bt.tScalarArray_at(btFractions, i); + var btPoint = bt.tVector3Array_at(btPoints, i); + var pointE = hitResult.point; + pointE.x = -bt.btVector3_x(btPoint); + pointE.y = bt.btVector3_y(btPoint); + pointE.z = bt.btVector3_z(btPoint); + var btNormal = bt.tVector3Array_at(btNormals, i); + var normal = hitResult.normal; + normal.x = -bt.btVector3_x(btNormal); + normal.y = bt.btVector3_y(btNormal); + normal.z = bt.btVector3_z(btNormal); + } + return true; + } + else { + return false; + } + } + rayCast(ray, outHitResult = null, distance = 2147483647, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + var from = ray.origin; + var to = PhysicsSimulation._tempVector30; + Laya.Vector3.normalize(ray.direction, to); + Laya.Vector3.scale(to, distance, to); + Laya.Vector3.add(from, to, to); + return this.raycastFromTo(from, to, outHitResult, collisonGroup, collisionMask); + } + rayCastAll(ray, out, distance = 2147483647, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + var from = ray.origin; + var to = PhysicsSimulation._tempVector30; + Laya.Vector3.normalize(ray.direction, to); + Laya.Vector3.scale(to, distance, to); + Laya.Vector3.add(from, to, to); + return this.raycastAllFromTo(from, to, out, collisonGroup, collisionMask); + } + shapeCast(shape, fromPosition, toPosition, out = null, fromRotation = null, toRotation = null, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, allowedCcdPenetration = 0.0) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var convexResultCall = this._btClosestConvexResultCallback; + var convexPosFrom = PhysicsSimulation._btTempVector30; + var convexPosTo = PhysicsSimulation._btTempVector31; + var convexRotFrom = PhysicsSimulation._btTempQuaternion0; + var convexRotTo = PhysicsSimulation._btTempQuaternion1; + var convexTransform = PhysicsSimulation._btTempTransform0; + var convexTransTo = PhysicsSimulation._btTempTransform1; + var sweepShape = shape._btShape; + bt.btVector3_setValue(convexPosFrom, -fromPosition.x, fromPosition.y, fromPosition.z); + bt.btVector3_setValue(convexPosTo, -toPosition.x, toPosition.y, toPosition.z); + bt.ConvexResultCallback_set_m_collisionFilterGroup(convexResultCall, collisonGroup); + bt.ConvexResultCallback_set_m_collisionFilterMask(convexResultCall, collisionMask); + bt.btTransform_setOrigin(convexTransform, convexPosFrom); + bt.btTransform_setOrigin(convexTransTo, convexPosTo); + if (fromRotation) { + bt.btQuaternion_setValue(convexRotFrom, -fromRotation.x, fromRotation.y, fromRotation.z, -fromRotation.w); + bt.btTransform_setRotation(convexTransform, convexRotFrom); + } + else { + bt.btTransform_setRotation(convexTransform, this._btDefaultQuaternion); + } + if (toRotation) { + bt.btQuaternion_setValue(convexRotTo, -toRotation.x, toRotation.y, toRotation.z, -toRotation.w); + bt.btTransform_setRotation(convexTransTo, convexRotTo); + } + else { + bt.btTransform_setRotation(convexTransTo, this._btDefaultQuaternion); + } + bt.ClosestConvexResultCallback_set_m_hitCollisionObject(convexResultCall, null); + bt.ConvexResultCallback_set_m_closestHitFraction(convexResultCall, 1); + bt.btCollisionWorld_convexSweepTest(this._btCollisionWorld, sweepShape, convexTransform, convexTransTo, convexResultCall, allowedCcdPenetration); + if (bt.ConvexResultCallback_hasHit(convexResultCall)) { + if (out) { + out.succeeded = true; + out.collider = PhysicsComponent._physicObjectsMap[bt.btCollisionObject_getUserIndex(bt.ClosestConvexResultCallback_get_m_hitCollisionObject(convexResultCall))]; + out.hitFraction = bt.ConvexResultCallback_get_m_closestHitFraction(convexResultCall); + var btPoint = bt.ClosestConvexResultCallback_get_m_hitPointWorld(convexResultCall); + var btNormal = bt.ClosestConvexResultCallback_get_m_hitNormalWorld(convexResultCall); + var point = out.point; + var normal = out.normal; + point.x = -bt.btVector3_x(btPoint); + point.y = bt.btVector3_y(btPoint); + point.z = bt.btVector3_z(btPoint); + normal.x = -bt.btVector3_x(btNormal); + normal.y = bt.btVector3_y(btNormal); + normal.z = bt.btVector3_z(btNormal); + } + return true; + } + else { + if (out) + out.succeeded = false; + return false; + } + } + shapeCastAll(shape, fromPosition, toPosition, out, fromRotation = null, toRotation = null, collisonGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, collisionMask = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER, allowedCcdPenetration = 0.0) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var convexResultCall = this._btAllConvexResultCallback; + var convexPosFrom = PhysicsSimulation._btTempVector30; + var convexPosTo = PhysicsSimulation._btTempVector31; + var convexRotFrom = PhysicsSimulation._btTempQuaternion0; + var convexRotTo = PhysicsSimulation._btTempQuaternion1; + var convexTransform = PhysicsSimulation._btTempTransform0; + var convexTransTo = PhysicsSimulation._btTempTransform1; + var sweepShape = shape._btShape; + out.length = 0; + bt.btVector3_setValue(convexPosFrom, -fromPosition.x, fromPosition.y, fromPosition.z); + bt.btVector3_setValue(convexPosTo, -toPosition.x, toPosition.y, toPosition.z); + bt.ConvexResultCallback_set_m_collisionFilterGroup(convexResultCall, collisonGroup); + bt.ConvexResultCallback_set_m_collisionFilterMask(convexResultCall, collisionMask); + bt.btTransform_setOrigin(convexTransform, convexPosFrom); + bt.btTransform_setOrigin(convexTransTo, convexPosTo); + if (fromRotation) { + bt.btQuaternion_setValue(convexRotFrom, -fromRotation.x, fromRotation.y, fromRotation.z, -fromRotation.w); + bt.btTransform_setRotation(convexTransform, convexRotFrom); + } + else { + bt.btTransform_setRotation(convexTransform, this._btDefaultQuaternion); + } + if (toRotation) { + bt.btQuaternion_setValue(convexRotTo, -toRotation.x, toRotation.y, toRotation.z, -toRotation.w); + bt.btTransform_setRotation(convexTransTo, convexRotTo); + } + else { + bt.btTransform_setRotation(convexTransTo, this._btDefaultQuaternion); + } + var collisionObjects = bt.AllConvexResultCallback_get_m_collisionObjects(convexResultCall); + var btPoints = bt.AllConvexResultCallback_get_m_hitPointWorld(convexResultCall); + var btNormals = bt.AllConvexResultCallback_get_m_hitNormalWorld(convexResultCall); + var btFractions = bt.AllConvexResultCallback_get_m_hitFractions(convexResultCall); + bt.tVector3Array_clear(btPoints); + bt.tVector3Array_clear(btNormals); + bt.tScalarArray_clear(btFractions); + bt.tBtCollisionObjectArray_clear(collisionObjects); + bt.btCollisionWorld_convexSweepTest(this._btCollisionWorld, sweepShape, convexTransform, convexTransTo, convexResultCall, allowedCcdPenetration); + var count = bt.tBtCollisionObjectArray_size(collisionObjects); + if (count > 0) { + this._collisionsUtils.recoverAllHitResultsPool(); + for (var i = 0; i < count; i++) { + var hitResult = this._collisionsUtils.getHitResult(); + out.push(hitResult); + hitResult.succeeded = true; + hitResult.collider = PhysicsComponent._physicObjectsMap[bt.btCollisionObject_getUserIndex(bt.tBtCollisionObjectArray_at(collisionObjects, i))]; + hitResult.hitFraction = bt.tScalarArray_at(btFractions, i); + var btPoint = bt.tVector3Array_at(btPoints, i); + var point = hitResult.point; + point.x = -bt.btVector3_x(btPoint); + point.y = bt.btVector3_y(btPoint); + point.z = bt.btVector3_z(btPoint); + var btNormal = bt.tVector3Array_at(btNormals, i); + var normal = hitResult.normal; + normal.x = -bt.btVector3_x(btNormal); + normal.y = bt.btVector3_y(btNormal); + normal.z = bt.btVector3_z(btNormal); + } + return true; + } + else { + return false; + } + } + addConstraint(constraint, disableCollisionsBetweenLinkedBodies = false) { + if (!this._btDiscreteDynamicsWorld) + throw "Cannot perform this action when the physics engine is set to CollisionsOnly"; + Laya.ILaya3D.Physics3D._bullet.btCollisionWorld_addConstraint(this._btDiscreteDynamicsWorld, constraint._btConstraint, disableCollisionsBetweenLinkedBodies); + this._currentConstraint[constraint.id] = constraint; + } + removeConstraint(constraint) { + if (!this._btDiscreteDynamicsWorld) + throw "Cannot perform this action when the physics engine is set to CollisionsOnly"; + Laya.ILaya3D.Physics3D._bullet.btCollisionWorld_removeConstraint(this._btDiscreteDynamicsWorld, constraint._btConstraint); + delete this._currentConstraint[constraint.id]; + } + setHitsRayResultCallbackFlag(flag = 1) { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.RayResultCallback_set_m_flags(this._btAllHitsRayResultCallback, flag); + bt.RayResultCallback_set_m_flags(this._btClosestRayResultCallback, flag); + } + _updatePhysicsTransformFromRender() { + var elements = this._physicsUpdateList.elements; + for (var i = 0, n = this._physicsUpdateList.length; i < n; i++) { + var physicCollider = elements[i]; + physicCollider._derivePhysicsTransformation(false); + physicCollider._inPhysicUpdateListIndex = -1; + } + this._physicsUpdateList.length = 0; + } + _updateCharacters() { + for (var i = 0, n = this._characters.length; i < n; i++) { + var character = this._characters[i]; + character._updateTransformComponent(Laya.ILaya3D.Physics3D._bullet.btCollisionObject_getWorldTransform(character._btColliderObject)); + } + } + _updateCollisions() { + this._collisionsUtils.recoverAllContactPointsPool(); + var previous = this._currentFrameCollisions; + this._currentFrameCollisions = this._previousFrameCollisions; + this._currentFrameCollisions.length = 0; + this._previousFrameCollisions = previous; + var loopCount = Laya.Stat.loopCount; + var bt = Laya.ILaya3D.Physics3D._bullet; + var numManifolds = bt.btDispatcher_getNumManifolds(this._btDispatcher); + for (var i = 0; i < numManifolds; i++) { + var contactManifold = bt.btDispatcher_getManifoldByIndexInternal(this._btDispatcher, i); + var componentA = PhysicsComponent._physicObjectsMap[bt.btCollisionObject_getUserIndex(bt.btPersistentManifold_getBody0(contactManifold))]; + var componentB = PhysicsComponent._physicObjectsMap[bt.btCollisionObject_getUserIndex(bt.btPersistentManifold_getBody1(contactManifold))]; + var collision = null; + var isFirstCollision; + var contacts = null; + var isTrigger = componentA.isTrigger || componentB.isTrigger; + if (isTrigger && (componentA.owner._needProcessTriggers || componentB.owner._needProcessTriggers)) { + var numContacts = bt.btPersistentManifold_getNumContacts(contactManifold); + for (var j = 0; j < numContacts; j++) { + var pt = bt.btPersistentManifold_getContactPoint(contactManifold, j); + var distance = bt.btManifoldPoint_getDistance(pt); + if (distance <= 0) { + collision = this._collisionsUtils.getCollision(componentA, componentB); + contacts = collision.contacts; + isFirstCollision = collision._updateFrame !== loopCount; + if (isFirstCollision) { + collision._isTrigger = true; + contacts.length = 0; + } + break; + } + } + } + else if (componentA.owner._needProcessCollisions || componentB.owner._needProcessCollisions) { + if (componentA._enableProcessCollisions || componentB._enableProcessCollisions) { + numContacts = bt.btPersistentManifold_getNumContacts(contactManifold); + for (j = 0; j < numContacts; j++) { + pt = bt.btPersistentManifold_getContactPoint(contactManifold, j); + distance = bt.btManifoldPoint_getDistance(pt); + if (distance <= 0) { + var contactPoint = this._collisionsUtils.getContactPoints(); + contactPoint.colliderA = componentA; + contactPoint.colliderB = componentB; + contactPoint.distance = distance; + var btNormal = bt.btManifoldPoint_get_m_normalWorldOnB(pt); + var normal = contactPoint.normal; + normal.x = -bt.btVector3_x(btNormal); + normal.y = bt.btVector3_y(btNormal); + normal.z = bt.btVector3_z(btNormal); + var btPostionA = bt.btManifoldPoint_get_m_positionWorldOnA(pt); + var positionOnA = contactPoint.positionOnA; + positionOnA.x = -bt.btVector3_x(btPostionA); + positionOnA.y = bt.btVector3_y(btPostionA); + positionOnA.z = bt.btVector3_z(btPostionA); + var btPostionB = bt.btManifoldPoint_get_m_positionWorldOnB(pt); + var positionOnB = contactPoint.positionOnB; + positionOnB.x = -bt.btVector3_x(btPostionB); + positionOnB.y = bt.btVector3_y(btPostionB); + positionOnB.z = bt.btVector3_z(btPostionB); + if (!collision) { + collision = this._collisionsUtils.getCollision(componentA, componentB); + contacts = collision.contacts; + isFirstCollision = collision._updateFrame !== loopCount; + if (isFirstCollision) { + collision._isTrigger = false; + contacts.length = 0; + } + } + contacts.push(contactPoint); + } + } + } + } + if (collision && isFirstCollision) { + this._currentFrameCollisions.push(collision); + collision._setUpdateFrame(loopCount); + } + } + } + _eventScripts() { + var loopCount = Laya.Stat.loopCount; + for (var i = 0, n = this._currentFrameCollisions.length; i < n; i++) { + var curFrameCol = this._currentFrameCollisions[i]; + var colliderA = curFrameCol._colliderA; + var colliderB = curFrameCol._colliderB; + if (colliderA.destroyed || colliderB.destroyed) + continue; + if (loopCount - curFrameCol._lastUpdateFrame === 1) { + var ownerA = colliderA.owner; + var scriptsA = ownerA._scripts; + if (scriptsA) { + if (curFrameCol._isTrigger) { + if (ownerA._needProcessTriggers) { + for (var j = 0, m = scriptsA.length; j < m; j++) + scriptsA[j].onTriggerStay(colliderB); + } + } + else { + if (ownerA._needProcessCollisions) { + for (j = 0, m = scriptsA.length; j < m; j++) { + curFrameCol.other = colliderB; + scriptsA[j].onCollisionStay(curFrameCol); + } + } + } + } + var ownerB = colliderB.owner; + var scriptsB = ownerB._scripts; + if (scriptsB) { + if (curFrameCol._isTrigger) { + if (ownerB._needProcessTriggers) { + for (j = 0, m = scriptsB.length; j < m; j++) + scriptsB[j].onTriggerStay(colliderA); + } + } + else { + if (ownerB._needProcessCollisions) { + for (j = 0, m = scriptsB.length; j < m; j++) { + curFrameCol.other = colliderA; + scriptsB[j].onCollisionStay(curFrameCol); + } + } + } + } + } + else { + ownerA = colliderA.owner; + scriptsA = ownerA._scripts; + if (scriptsA) { + if (curFrameCol._isTrigger) { + if (ownerA._needProcessTriggers) { + for (j = 0, m = scriptsA.length; j < m; j++) + scriptsA[j].onTriggerEnter(colliderB); + } + } + else { + if (ownerA._needProcessCollisions) { + for (j = 0, m = scriptsA.length; j < m; j++) { + curFrameCol.other = colliderB; + scriptsA[j].onCollisionEnter(curFrameCol); + } + } + } + } + ownerB = colliderB.owner; + scriptsB = ownerB._scripts; + if (scriptsB) { + if (curFrameCol._isTrigger) { + if (ownerB._needProcessTriggers) { + for (j = 0, m = scriptsB.length; j < m; j++) + scriptsB[j].onTriggerEnter(colliderA); + } + } + else { + if (ownerB._needProcessCollisions) { + for (j = 0, m = scriptsB.length; j < m; j++) { + curFrameCol.other = colliderA; + scriptsB[j].onCollisionEnter(curFrameCol); + } + } + } + } + } + } + for (i = 0, n = this._previousFrameCollisions.length; i < n; i++) { + var preFrameCol = this._previousFrameCollisions[i]; + var preColliderA = preFrameCol._colliderA; + var preColliderB = preFrameCol._colliderB; + if (preColliderA.destroyed || preColliderB.destroyed) + continue; + if (loopCount - preFrameCol._updateFrame === 1) { + this._collisionsUtils.recoverCollision(preFrameCol); + ownerA = preColliderA.owner; + scriptsA = ownerA._scripts; + if (scriptsA) { + if (preFrameCol._isTrigger) { + if (ownerA._needProcessTriggers) { + for (j = 0, m = scriptsA.length; j < m; j++) + scriptsA[j].onTriggerExit(preColliderB); + } + } + else { + if (ownerA._needProcessCollisions) { + for (j = 0, m = scriptsA.length; j < m; j++) { + preFrameCol.other = preColliderB; + scriptsA[j].onCollisionExit(preFrameCol); + } + } + } + } + ownerB = preColliderB.owner; + scriptsB = ownerB._scripts; + if (scriptsB) { + if (preFrameCol._isTrigger) { + if (ownerB._needProcessTriggers) { + for (j = 0, m = scriptsB.length; j < m; j++) + scriptsB[j].onTriggerExit(preColliderA); + } + } + else { + if (ownerB._needProcessCollisions) { + for (j = 0, m = scriptsB.length; j < m; j++) { + preFrameCol.other = preColliderA; + scriptsB[j].onCollisionExit(preFrameCol); + } + } + } + } + } + } + for (var id in this._currentConstraint) { + var constraintObj = this._currentConstraint[id]; + var scripts = constraintObj.owner._scripts; + if (constraintObj.enabled && constraintObj._isBreakConstrained() && (!!scripts)) { + if (scripts.length != 0) { + for (i = 0, n = scripts.length; i < n; i++) { + scripts[i].onJointBreak(); + } + } + } + } + } + clearForces() { + if (!this._btDiscreteDynamicsWorld) + throw "Cannot perform this action when the physics engine is set to CollisionsOnly"; + Laya.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_clearForces(this._btDiscreteDynamicsWorld); + } + } + PhysicsSimulation.PHYSICSENGINEFLAGS_NONE = 0x0; + PhysicsSimulation.PHYSICSENGINEFLAGS_COLLISIONSONLY = 0x1; + PhysicsSimulation.PHYSICSENGINEFLAGS_SOFTBODYSUPPORT = 0x2; + PhysicsSimulation.PHYSICSENGINEFLAGS_MULTITHREADED = 0x4; + PhysicsSimulation.PHYSICSENGINEFLAGS_USEHARDWAREWHENPOSSIBLE = 0x8; + PhysicsSimulation.SOLVERMODE_RANDMIZE_ORDER = 1; + PhysicsSimulation.SOLVERMODE_FRICTION_SEPARATE = 2; + PhysicsSimulation.SOLVERMODE_USE_WARMSTARTING = 4; + PhysicsSimulation.SOLVERMODE_USE_2_FRICTION_DIRECTIONS = 16; + PhysicsSimulation.SOLVERMODE_ENABLE_FRICTION_DIRECTION_CACHING = 32; + PhysicsSimulation.SOLVERMODE_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION = 64; + PhysicsSimulation.SOLVERMODE_CACHE_FRIENDLY = 128; + PhysicsSimulation.SOLVERMODE_SIMD = 256; + PhysicsSimulation.SOLVERMODE_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS = 512; + PhysicsSimulation.SOLVERMODE_ALLOW_ZERO_LENGTH_FRICTION_DIRECTIONS = 1024; + PhysicsSimulation.HITSRAYRESULTCALLBACK_FLAG_NONE = 0; + PhysicsSimulation.HITSRAYRESULTCALLBACK_FLAG_FILTERBACKFACESS = 1; + PhysicsSimulation.HITSRAYRESULTCALLBACK_FLAG_KEEPUNFILIPPEDNORMAL = 2; + PhysicsSimulation.HITSRAYRESULTCALLBACK_FLAG_USESUBSIMPLEXCONVEXCASTRAYTEST = 4; + PhysicsSimulation.HITSRAYRESULTCALLBACK_FLAG_USEGJKCONVEXCASTRAYTEST = 8; + PhysicsSimulation.HITSRAYRESULTCALLBACK_FLAG_TERMINATOR = 0xffffffff; + PhysicsSimulation._tempVector30 = new Laya.Vector3(); + PhysicsSimulation.disableSimulation = false; + + class Rigidbody3D extends PhysicsTriggerComponent { + constructor(collisionGroup = Laya.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER, canCollideWith = Laya.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER) { + super(collisionGroup, canCollideWith); + this._isKinematic = false; + this._mass = 1.0; + this._gravity = new Laya.Vector3(0, -10, 0); + this._angularDamping = 0.0; + this._linearDamping = 0.0; + this._overrideGravity = false; + this._totalTorque = new Laya.Vector3(0, 0, 0); + this._totalForce = new Laya.Vector3(0, 0, 0); + this._linearVelocity = new Laya.Vector3(); + this._angularVelocity = new Laya.Vector3(); + this._linearFactor = new Laya.Vector3(1, 1, 1); + this._angularFactor = new Laya.Vector3(1, 1, 1); + this._detectCollisions = true; + this._controlBySimulation = true; + } + static __init__() { + var bt = Laya.ILaya3D.Physics3D._bullet; + Rigidbody3D._btTempVector30 = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btTempVector31 = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btVector3Zero = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btInertia = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btImpulse = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btImpulseOffset = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btGravity = bt.btVector3_create(0, 0, 0); + Rigidbody3D._btTransform0 = bt.btTransform_create(); + } + get mass() { + return this._mass; + } + set mass(value) { + value = Math.max(value, 1e-07); + this._mass = value; + (this._isKinematic) || (this._updateMass(value)); + } + get isKinematic() { + return this._isKinematic; + } + set isKinematic(value) { + this._isKinematic = value; + this._controlBySimulation = !value; + var bt = Laya.ILaya3D.Physics3D._bullet; + var canInSimulation = !!(this._simulation && this._enabled && this._colliderShape); + canInSimulation && this._removeFromSimulation(); + var natColObj = this._btColliderObject; + var flags = bt.btCollisionObject_getCollisionFlags(natColObj); + if (value) { + flags = flags | PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT; + bt.btCollisionObject_setCollisionFlags(natColObj, flags); + bt.btCollisionObject_forceActivationState(this._btColliderObject, PhysicsComponent.ACTIVATIONSTATE_DISABLE_DEACTIVATION); + this._enableProcessCollisions = false; + this._updateMass(0); + } + else { + if ((flags & PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT) > 0) + flags = flags ^ PhysicsComponent.COLLISIONFLAGS_KINEMATIC_OBJECT; + bt.btCollisionObject_setCollisionFlags(natColObj, flags); + bt.btCollisionObject_setActivationState(this._btColliderObject, PhysicsComponent.ACTIVATIONSTATE_ACTIVE_TAG); + this._enableProcessCollisions = true; + this._updateMass(this._mass); + } + var btZero = Rigidbody3D._btVector3Zero; + bt.btCollisionObject_setInterpolationLinearVelocity(natColObj, btZero); + bt.btRigidBody_setLinearVelocity(natColObj, btZero); + bt.btCollisionObject_setInterpolationAngularVelocity(natColObj, btZero); + bt.btRigidBody_setAngularVelocity(natColObj, btZero); + canInSimulation && this._addToSimulation(); + } + get linearDamping() { + return this._linearDamping; + } + set linearDamping(value) { + this._linearDamping = value; + if (this._btColliderObject) + Laya.ILaya3D.Physics3D._bullet.btRigidBody_setDamping(this._btColliderObject, value, this._angularDamping); + } + get angularDamping() { + return this._angularDamping; + } + set angularDamping(value) { + this._angularDamping = value; + if (this._btColliderObject) + Laya.ILaya3D.Physics3D._bullet.btRigidBody_setDamping(this._btColliderObject, this._linearDamping, value); + } + get overrideGravity() { + return this._overrideGravity; + } + set overrideGravity(value) { + this._overrideGravity = value; + var bt = Laya.ILaya3D.Physics3D._bullet; + if (this._btColliderObject) { + var flag = bt.btRigidBody_getFlags(this._btColliderObject); + if (value) { + if ((flag & Rigidbody3D._BT_DISABLE_WORLD_GRAVITY) === 0) + bt.btRigidBody_setFlags(this._btColliderObject, flag | Rigidbody3D._BT_DISABLE_WORLD_GRAVITY); + } + else { + if ((flag & Rigidbody3D._BT_DISABLE_WORLD_GRAVITY) > 0) + bt.btRigidBody_setFlags(this._btColliderObject, flag ^ Rigidbody3D._BT_DISABLE_WORLD_GRAVITY); + } + } + } + get gravity() { + var bt = Laya.ILaya3D.Physics3D._bullet; + Rigidbody3D._btGravity = bt.btRigidBody_getGravity(this._btColliderObject); + Laya.Utils3D._convertToLayaVec3(Rigidbody3D._btGravity, this._gravity, true); + return this._gravity; + } + set gravity(value) { + this._gravity = value; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(Rigidbody3D._btGravity, -value.x, value.y, value.z); + bt.btRigidBody_setGravity(this._btColliderObject, Rigidbody3D._btGravity); + } + get totalForce() { + if (this._btColliderObject) { + var btTotalForce = Laya.ILaya3D.Physics3D._bullet.btRigidBody_getTotalForce(this._btColliderObject); + Laya.Utils3D._convertToLayaVec3(btTotalForce, this._totalForce, true); + return this._totalForce; + } + return null; + } + get linearFactor() { + return this._linearFactor; + } + set linearFactor(value) { + this._linearFactor = value; + var btValue = Rigidbody3D._btTempVector30; + Laya.Utils3D._convertToBulletVec3(value, btValue, false); + Laya.ILaya3D.Physics3D._bullet.btRigidBody_setLinearFactor(this._btColliderObject, btValue); + } + get linearVelocity() { + if (this._btColliderObject) + Laya.Utils3D._convertToLayaVec3(Laya.ILaya3D.Physics3D._bullet.btRigidBody_getLinearVelocity(this._btColliderObject), this._linearVelocity, true); + return this._linearVelocity; + } + set linearVelocity(value) { + this._linearVelocity = value; + if (this._btColliderObject) { + var btValue = Rigidbody3D._btTempVector30; + Laya.Utils3D._convertToBulletVec3(value, btValue, true); + (this.isSleeping) && (this.wakeUp()); + Laya.ILaya3D.Physics3D._bullet.btRigidBody_setLinearVelocity(this._btColliderObject, btValue); + } + } + get angularFactor() { + return this._angularFactor; + } + set angularFactor(value) { + this._angularFactor = value; + var btValue = Rigidbody3D._btTempVector30; + Laya.Utils3D._convertToBulletVec3(value, btValue, false); + Laya.ILaya3D.Physics3D._bullet.btRigidBody_setAngularFactor(this._btColliderObject, btValue); + } + get angularVelocity() { + if (this._btColliderObject) + Laya.Utils3D._convertToLayaVec3(Laya.ILaya3D.Physics3D._bullet.btRigidBody_getAngularVelocity(this._btColliderObject), this._angularVelocity, true); + return this._angularVelocity; + } + set angularVelocity(value) { + this._angularVelocity = value; + if (this._btColliderObject) { + var btValue = Rigidbody3D._btTempVector30; + Laya.Utils3D._convertToBulletVec3(value, btValue, true); + (this.isSleeping) && (this.wakeUp()); + Laya.ILaya3D.Physics3D._bullet.btRigidBody_setAngularVelocity(this._btColliderObject, btValue); + } + } + get totalTorque() { + if (this._btColliderObject) { + var btTotalTorque = Laya.ILaya3D.Physics3D._bullet.btRigidBody_getTotalTorque(this._btColliderObject); + Laya.Utils3D._convertToLayaVec3(btTotalTorque, this._totalTorque, true); + return this._totalTorque; + } + return null; + } + get detectCollisions() { + return this._detectCollisions; + } + set detectCollisions(value) { + if (this._detectCollisions !== value) { + this._detectCollisions = value; + if (this._colliderShape && this._enabled && this._simulation) { + this._simulation._removeRigidBody(this); + this._simulation._addRigidBody(this, this._collisionGroup, value ? this._canCollideWith : 0); + } + } + } + get isSleeping() { + if (this._btColliderObject) + return Laya.ILaya3D.Physics3D._bullet.btCollisionObject_getActivationState(this._btColliderObject) === PhysicsComponent.ACTIVATIONSTATE_ISLAND_SLEEPING; + return false; + } + get sleepLinearVelocity() { + return Laya.ILaya3D.Physics3D._bullet.btRigidBody_getLinearSleepingThreshold(this._btColliderObject); + } + set sleepLinearVelocity(value) { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btRigidBody_setSleepingThresholds(this._btColliderObject, value, bt.btRigidBody_getAngularSleepingThreshold(this._btColliderObject)); + } + get sleepAngularVelocity() { + return Laya.ILaya3D.Physics3D._bullet.btRigidBody_getAngularSleepingThreshold(this._btColliderObject); + } + set sleepAngularVelocity(value) { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btRigidBody_setSleepingThresholds(this._btColliderObject, bt.btRigidBody_getLinearSleepingThreshold(this._btColliderObject), value); + } + get btColliderObject() { + return this._btColliderObject; + } + set constaintRigidbodyA(value) { + this._constaintRigidbodyA = value; + } + get constaintRigidbodyA() { + return this._constaintRigidbodyA; + } + set constaintRigidbodyB(value) { + this._constaintRigidbodyB = value; + } + get constaintRigidbodyB() { + return this._constaintRigidbodyB; + } + _updateMass(mass) { + if (this._btColliderObject && this._colliderShape) { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btCollisionShape_calculateLocalInertia(this._colliderShape._btShape, mass, Rigidbody3D._btInertia); + bt.btRigidBody_setMassProps(this._btColliderObject, mass, Rigidbody3D._btInertia); + bt.btRigidBody_updateInertiaTensor(this._btColliderObject); + } + } + _onScaleChange(scale) { + super._onScaleChange(scale); + this._updateMass(this._isKinematic ? 0 : this._mass); + } + _derivePhysicsTransformation(force) { + var bt = Laya.ILaya3D.Physics3D._bullet; + var btColliderObject = this._btColliderObject; + var oriTransform = bt.btCollisionObject_getWorldTransform(btColliderObject); + var transform = Rigidbody3D._btTransform0; + bt.btTransform_equal(transform, oriTransform); + this._innerDerivePhysicsTransformation(transform, force); + bt.btRigidBody_setCenterOfMassTransform(btColliderObject, transform); + } + _onAdded() { + var bt = Laya.ILaya3D.Physics3D._bullet; + var motionState = bt.layaMotionState_create(); + bt.layaMotionState_set_rigidBodyID(motionState, this._id); + this._btLayaMotionState = motionState; + var constructInfo = bt.btRigidBodyConstructionInfo_create(0.0, motionState, null, Rigidbody3D._btVector3Zero); + var btRigid = bt.btRigidBody_create(constructInfo); + bt.btCollisionObject_setUserIndex(btRigid, this.id); + this._btColliderObject = btRigid; + super._onAdded(); + this.mass = this._mass; + this.linearFactor = this._linearFactor; + this.angularFactor = this._angularFactor; + this.linearDamping = this._linearDamping; + this.angularDamping = this._angularDamping; + this.overrideGravity = this._overrideGravity; + this.gravity = this._gravity; + this.isKinematic = this._isKinematic; + bt.btRigidBodyConstructionInfo_destroy(constructInfo); + } + _onEnable() { + super._onEnable(); + if (this._constaintRigidbodyA) { + if (this._constaintRigidbodyA.connectedBody._simulation) { + this._constaintRigidbodyA._createConstraint(); + this._constaintRigidbodyA._onEnable(); + } + } + if (this._constaintRigidbodyB) { + if (this._constaintRigidbodyB.ownBody._simulation) { + this._constaintRigidbodyB._createConstraint(); + this._constaintRigidbodyB._onEnable(); + } + } + } + _onShapeChange(colShape) { + super._onShapeChange(colShape); + if (this._isKinematic) { + this._updateMass(0); + } + else { + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btRigidBody_setCenterOfMassTransform(this._btColliderObject, bt.btCollisionObject_getWorldTransform(this._btColliderObject)); + this._updateMass(this._mass); + } + } + _parse(data) { + (data.friction != null) && (this.friction = data.friction); + (data.rollingFriction != null) && (this.rollingFriction = data.rollingFriction); + (data.restitution != null) && (this.restitution = data.restitution); + (data.isTrigger != null) && (this.isTrigger = data.isTrigger); + (data.mass != null) && (this.mass = data.mass); + (data.linearDamping != null) && (this.linearDamping = data.linearDamping); + (data.angularDamping != null) && (this.angularDamping = data.angularDamping); + (data.overrideGravity != null) && (this.overrideGravity = data.overrideGravity); + if (data.linearFactor != null) { + var linFac = this.linearFactor; + linFac.fromArray(data.linearFactor); + this.linearFactor = linFac; + } + if (data.angularFactor != null) { + var angFac = this.angularFactor; + angFac.fromArray(data.angularFactor); + this.angularFactor = angFac; + } + if (data.gravity) { + this.gravity.fromArray(data.gravity); + this.gravity = this.gravity; + } + super._parse(data); + this._parseShape(data.shapes); + (data.isKinematic != null) && (this.isKinematic = data.isKinematic); + } + _onDestroy() { + Laya.ILaya3D.Physics3D._bullet.btMotionState_destroy(this._btLayaMotionState); + super._onDestroy(); + this._btLayaMotionState = null; + this._gravity = null; + this._totalTorque = null; + this._linearVelocity = null; + this._angularVelocity = null; + this._linearFactor = null; + this._angularFactor = null; + if (this.constaintRigidbodyA) + this.constaintRigidbodyA._breakConstrained(); + if (this.constaintRigidbodyB) { + this.constaintRigidbodyB.connectedBody = null; + this.constaintRigidbodyB._onDisable(); + } + } + _addToSimulation() { + this._simulation._addRigidBody(this, this._collisionGroup, this._detectCollisions ? this._canCollideWith : 0); + } + _removeFromSimulation() { + this._simulation._removeRigidBody(this); + } + _cloneTo(dest) { + super._cloneTo(dest); + var destRigidbody3D = dest; + destRigidbody3D.isKinematic = this._isKinematic; + destRigidbody3D.mass = this._mass; + destRigidbody3D.gravity = this._gravity; + destRigidbody3D.angularDamping = this._angularDamping; + destRigidbody3D.linearDamping = this._linearDamping; + destRigidbody3D.overrideGravity = this._overrideGravity; + destRigidbody3D.linearVelocity = this._linearVelocity; + destRigidbody3D.angularVelocity = this._angularVelocity; + destRigidbody3D.linearFactor = this._linearFactor; + destRigidbody3D.angularFactor = this._angularFactor; + destRigidbody3D.detectCollisions = this._detectCollisions; + } + applyForce(force, localOffset = null) { + if (this._btColliderObject == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + var bt = Laya.ILaya3D.Physics3D._bullet; + var btForce = Rigidbody3D._btTempVector30; + bt.btVector3_setValue(btForce, -force.x, force.y, force.z); + if (localOffset) { + var btOffset = Rigidbody3D._btTempVector31; + bt.btVector3_setValue(btOffset, -localOffset.x, localOffset.y, localOffset.z); + bt.btRigidBody_applyForce(this._btColliderObject, btForce, btOffset); + } + else { + bt.btRigidBody_applyCentralForce(this._btColliderObject, btForce); + } + } + applyTorque(torque) { + if (this._btColliderObject == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + var bullet = Laya.ILaya3D.Physics3D._bullet; + var btTorque = Rigidbody3D._btTempVector30; + bullet.btVector3_setValue(btTorque, -torque.x, torque.y, torque.z); + bullet.btRigidBody_applyTorque(this._btColliderObject, btTorque); + } + applyImpulse(impulse, localOffset = null) { + if (this._btColliderObject == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(Rigidbody3D._btImpulse, -impulse.x, impulse.y, impulse.z); + if (localOffset) { + bt.btVector3_setValue(Rigidbody3D._btImpulseOffset, -localOffset.x, localOffset.y, localOffset.z); + bt.btRigidBody_applyImpulse(this._btColliderObject, Rigidbody3D._btImpulse, Rigidbody3D._btImpulseOffset); + } + else { + bt.btRigidBody_applyCentralImpulse(this._btColliderObject, Rigidbody3D._btImpulse); + } + } + applyTorqueImpulse(torqueImpulse) { + if (this._btColliderObject == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + var bt = Laya.ILaya3D.Physics3D._bullet; + var btTorqueImpulse = Rigidbody3D._btTempVector30; + bt.btVector3_setValue(btTorqueImpulse, -torqueImpulse.x, torqueImpulse.y, torqueImpulse.z); + bt.btRigidBody_applyTorqueImpulse(this._btColliderObject, btTorqueImpulse); + } + wakeUp() { + this._btColliderObject && (Laya.ILaya3D.Physics3D._bullet.btCollisionObject_activate(this._btColliderObject, false)); + } + clearForces() { + var rigidBody = this._btColliderObject; + if (rigidBody == null) + throw "Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene."; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btRigidBody_clearForces(rigidBody); + var btZero = Rigidbody3D._btVector3Zero; + bt.btCollisionObject_setInterpolationLinearVelocity(rigidBody, btZero); + bt.btRigidBody_setLinearVelocity(rigidBody, btZero); + bt.btCollisionObject_setInterpolationAngularVelocity(rigidBody, btZero); + bt.btRigidBody_setAngularVelocity(rigidBody, btZero); + } + } + Rigidbody3D.TYPE_STATIC = 0; + Rigidbody3D.TYPE_DYNAMIC = 1; + Rigidbody3D.TYPE_KINEMATIC = 2; + Rigidbody3D._BT_DISABLE_WORLD_GRAVITY = 1; + Rigidbody3D._BT_ENABLE_GYROPSCOPIC_FORCE = 2; + + class ConstraintComponent extends Laya.Component { + constructor(constraintType) { + super(); + this._anchor = new Laya.Vector3(); + this._connectAnchor = new Laya.Vector3(); + this._feedbackEnabled = false; + this._getJointFeedBack = false; + this._currentForce = new Laya.Vector3(); + this._currentTorque = new Laya.Vector3(); + this._constraintType = constraintType; + var bt = Laya.Physics3D._bullet; + this._btframATrans = bt.btTransform_create(); + this._btframBTrans = bt.btTransform_create(); + bt.btTransform_setIdentity(this._btframATrans); + bt.btTransform_setIdentity(this._btframBTrans); + this._btframAPos = bt.btVector3_create(0, 0, 0); + this._btframBPos = bt.btVector3_create(0, 0, 0); + bt.btTransform_setOrigin(this._btframATrans, this._btframAPos); + bt.btTransform_setOrigin(this._btframBTrans, this._btframBPos); + this._breakForce = -1; + this._breakTorque = -1; + } + get enabled() { + return super.enabled; + } + set enabled(value) { + super.enabled = value; + } + get appliedImpulse() { + if (!this._feedbackEnabled) { + this._btConstraint.EnableFeedback(true); + this._feedbackEnabled = true; + } + return this._btConstraint.AppliedImpulse; + } + set connectedBody(value) { + this._connectedBody = value; + value && (value.constaintRigidbodyB = this); + } + get connectedBody() { + return this._connectedBody; + } + get ownBody() { + return this._ownBody; + } + set ownBody(value) { + this._ownBody = value; + value.constaintRigidbodyA = this; + } + get currentForce() { + if (!this._getJointFeedBack) + this._getFeedBackInfo(); + return this._currentForce; + } + get currentTorque() { + if (!this._getJointFeedBack) + this._getFeedBackInfo(); + return this._currentTorque; + } + get breakForce() { + return this._breakForce; + } + set breakForce(value) { + this._breakForce = value; + } + get breakTorque() { + return this._breakTorque; + } + set breakTorque(value) { + this._breakTorque = value; + } + set anchor(value) { + value.cloneTo(this._anchor); + this.setFrames(); + } + get anchor() { + return this._anchor; + } + set connectAnchor(value) { + value.cloneTo(this._connectAnchor); + this.setFrames(); + } + get connectAnchor() { + return this._connectAnchor; + } + setOverrideNumSolverIterations(overideNumIterations) { + var bt = Laya.Physics3D._bullet; + bt.btTypedConstraint_setOverrideNumSolverIterations(this._btConstraint, overideNumIterations); + } + setConstraintEnabled(enable) { + var bt = Laya.Physics3D._bullet; + bt.btTypedConstraint_setEnabled(this._btConstraint, enable); + } + _onEnable() { + super._onEnable(); + this.enabled = true; + } + _onDisable() { + super._onDisable(); + this.enabled = false; + } + setFrames() { + var bt = Laya.Physics3D._bullet; + bt.btVector3_setValue(this._btframAPos, -this._anchor.x, this.anchor.y, this.anchor.z); + bt.btVector3_setValue(this._btframBPos, -this._connectAnchor.x, this._connectAnchor.y, this._connectAnchor.z); + bt.btTransform_setOrigin(this._btframATrans, this._btframAPos); + bt.btTransform_setOrigin(this._btframBTrans, this._btframBPos); + } + _addToSimulation() { + } + _removeFromSimulation() { + } + _createConstraint() { + } + setConnectRigidBody(ownerRigid, connectRigidBody) { + var ownerCanInSimulation = (ownerRigid) && (!!(ownerRigid._simulation && ownerRigid._enabled && ownerRigid.colliderShape)); + var connectCanInSimulation = (connectRigidBody) && (!!(connectRigidBody._simulation && connectRigidBody._enabled && connectRigidBody.colliderShape)); + if (!(ownerCanInSimulation && connectCanInSimulation)) + throw "ownerRigid or connectRigidBody is not in Simulation"; + if (ownerRigid != this._ownBody || connectRigidBody != this._connectedBody) { + var canInSimulation = !!(this.enabled && this._simulation); + canInSimulation && this._removeFromSimulation(); + this._ownBody = ownerRigid; + this._connectedBody = connectRigidBody; + this._ownBody.constaintRigidbodyA = this; + this._connectedBody.constaintRigidbodyB = this; + this._createConstraint(); + } + } + getcurrentForce(out) { + if (!this._btJointFeedBackObj) + throw "this Constraint is not simulation"; + var bt = Laya.Physics3D._bullet; + var applyForce = bt.btJointFeedback_getAppliedForceBodyA(this._btJointFeedBackObj); + out.setValue(bt.btVector3_x(applyForce), bt.btVector3_y(applyForce), bt.btVector3_z(applyForce)); + return; + } + getcurrentTorque(out) { + if (!this._btJointFeedBackObj) + throw "this Constraint is not simulation"; + var bt = Laya.Physics3D._bullet; + var applyTorque = bt.btJointFeedback_getAppliedTorqueBodyA(this._btJointFeedBackObj); + out.setValue(bt.btVector3_x(applyTorque), bt.btVector3_y(applyTorque), bt.btVector3_z(applyTorque)); + return; + } + _onDestroy() { + var physics3D = Laya.Physics3D._bullet; + this._simulation && this._removeFromSimulation(); + if (this._btConstraint && this._btJointFeedBackObj && this._simulation) { + physics3D.btTypedConstraint_destroy(this._btConstraint); + physics3D.btJointFeedback_destroy(this._btJointFeedBackObj); + this._btJointFeedBackObj = null; + this._btConstraint = null; + } + super._onDisable(); + } + _isBreakConstrained() { + this._getJointFeedBack = false; + if (this.breakForce == -1 && this.breakTorque == -1) + return false; + this._getFeedBackInfo(); + var isBreakForce = this._breakForce != -1 && (Laya.Vector3.scalarLength(this._currentForce) > this._breakForce); + var isBreakTorque = this._breakTorque != -1 && (Laya.Vector3.scalarLength(this._currentTorque) > this._breakTorque); + if (isBreakForce || isBreakTorque) { + this._breakConstrained(); + return true; + } + return false; + } + _parse(data) { + this._anchor.fromArray(data.anchor); + this._connectAnchor.fromArray(data.connectAnchor); + this.setFrames(); + } + _getFeedBackInfo() { + var bt = Laya.Physics3D._bullet; + var applyForce = bt.btJointFeedback_getAppliedForceBodyA(this._btJointFeedBackObj); + var applyTorque = bt.btJointFeedback_getAppliedTorqueBodyA(this._btJointFeedBackObj); + this._currentTorque.setValue(bt.btVector3_x(applyTorque), bt.btVector3_y(applyTorque), bt.btVector3_z(applyTorque)); + this._currentForce.setValue(bt.btVector3_x(applyForce), bt.btVector3_y(applyForce), bt.btVector3_z(applyForce)); + this._getJointFeedBack = true; + } + _breakConstrained() { + this.ownBody.constaintRigidbodyA = null; + this.connectedBody && (this.connectedBody.constaintRigidbodyB = null); + this.destroy(); + } + } + ConstraintComponent.CONSTRAINT_POINT2POINT_CONSTRAINT_TYPE = 3; + ConstraintComponent.CONSTRAINT_HINGE_CONSTRAINT_TYPE = 4; + ConstraintComponent.CONSTRAINT_CONETWIST_CONSTRAINT_TYPE = 5; + ConstraintComponent.CONSTRAINT_D6_CONSTRAINT_TYPE = 6; + ConstraintComponent.CONSTRAINT_SLIDER_CONSTRAINT_TYPE = 7; + ConstraintComponent.CONSTRAINT_CONTACT_CONSTRAINT_TYPE = 8; + ConstraintComponent.CONSTRAINT_D6_SPRING_CONSTRAINT_TYPE = 9; + ConstraintComponent.CONSTRAINT_GEAR_CONSTRAINT_TYPE = 10; + ConstraintComponent.CONSTRAINT_FIXED_CONSTRAINT_TYPE = 11; + ConstraintComponent.CONSTRAINT_MAX_CONSTRAINT_TYPE = 12; + ConstraintComponent.CONSTRAINT_CONSTRAINT_ERP = 1; + ConstraintComponent.CONSTRAINT_CONSTRAINT_STOP_ERP = 2; + ConstraintComponent.CONSTRAINT_CONSTRAINT_CFM = 3; + ConstraintComponent.CONSTRAINT_CONSTRAINT_STOP_CFM = 4; + ConstraintComponent.tempForceV3 = new Laya.Vector3(); + + class ConfigurableConstraint extends ConstraintComponent { + constructor() { + super(ConstraintComponent.CONSTRAINT_D6_SPRING_CONSTRAINT_TYPE); + this._axis = new Laya.Vector3(); + this._secondaryAxis = new Laya.Vector3(); + this._minLinearLimit = new Laya.Vector3(); + this._maxLinearLimit = new Laya.Vector3(); + this._minAngularLimit = new Laya.Vector3(); + this._maxAngularLimit = new Laya.Vector3(); + this._linearLimitSpring = new Laya.Vector3(); + this._angularLimitSpring = new Laya.Vector3(); + this._linearBounce = new Laya.Vector3(); + this._angularBounce = new Laya.Vector3(); + this._linearDamp = new Laya.Vector3(); + this._angularDamp = new Laya.Vector3(); + this._xMotion = 0; + this._yMotion = 0; + this._zMotion = 0; + this._angularXMotion = 0; + this._angularYMotion = 0; + this._angularZMotion = 0; + var bt = Laya.Physics3D._bullet; + this._btAxis = bt.btVector3_create(-1.0, 0.0, 0.0); + this._btSecondaryAxis = bt.btVector3_create(0.0, 1.0, 0.0); + } + get axis() { + return this._axis; + } + get secondaryAxis() { + return this._secondaryAxis; + } + set maxAngularLimit(value) { + value.cloneTo(this._maxAngularLimit); + } + set minAngularLimit(value) { + value.cloneTo(this._minAngularLimit); + } + get maxAngularLimit() { + return this._maxAngularLimit; + } + get minAngularLimit() { + return this._minAngularLimit; + } + set maxLinearLimit(value) { + value.cloneTo(this._maxLinearLimit); + } + set minLinearLimit(value) { + value.cloneTo(this._minLinearLimit); + } + get maxLinearLimit() { + return this._maxLinearLimit; + } + get minLinearLimit() { + return this._minLinearLimit; + } + set XMotion(value) { + if (this._xMotion != value) { + this._xMotion = value; + this.setLimit(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, value, -this._maxLinearLimit.x, -this._minLinearLimit.x); + } + } + get XMotion() { + return this._xMotion; + } + set YMotion(value) { + if (this._yMotion != value) { + this._yMotion = value; + this.setLimit(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, value, this._minLinearLimit.y, this._maxLinearLimit.y); + } + } + get YMotion() { + return this._yMotion; + } + set ZMotion(value) { + if (this._zMotion != value) { + this._zMotion = value; + this.setLimit(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, value, this._minLinearLimit.z, this._maxLinearLimit.z); + } + } + get ZMotion() { + return this._zMotion; + } + set angularXMotion(value) { + if (this._angularXMotion != value) { + this._angularXMotion = value; + this.setLimit(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, value, -this._maxAngularLimit.x, -this._minAngularLimit.x); + } + } + get angularXMotion() { + return this._angularXMotion; + } + set angularYMotion(value) { + if (this._angularYMotion != value) { + this._angularYMotion = value; + this.setLimit(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, value, this._minAngularLimit.y, this._maxAngularLimit.y); + } + } + get angularYMotion() { + return this._angularYMotion; + } + set angularZMotion(value) { + if (this._angularZMotion != value) { + this._angularZMotion = value; + this.setLimit(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, value, this._minAngularLimit.z, this._maxAngularLimit.z); + } + } + get angularZMotion() { + return this._angularZMotion; + } + set linearLimitSpring(value) { + if (!Laya.Vector3.equals(this._linearLimitSpring, value)) { + value.cloneTo(this._linearLimitSpring); + this.setSpring(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, value.x); + this.setSpring(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, value.y); + this.setSpring(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, value.z); + } + } + get linearLimitSpring() { + return this._linearLimitSpring; + } + set angularLimitSpring(value) { + if (!Laya.Vector3.equals(this._angularLimitSpring, value)) { + value.cloneTo(this._angularLimitSpring); + this.setSpring(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, value.x); + this.setSpring(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, value.y); + this.setSpring(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, value.z); + } + } + get angularLimitSpring() { + return this._angularLimitSpring; + } + set linearBounce(value) { + if (!Laya.Vector3.equals(this._linearBounce, value)) { + value.cloneTo(this._linearBounce); + this.setBounce(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, value.x); + this.setBounce(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, value.y); + this.setBounce(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, value.z); + } + } + get linearBounce() { + return this._linearBounce; + } + set angularBounce(value) { + if (!Laya.Vector3.equals(this._angularBounce, value)) { + value.cloneTo(this._angularBounce); + this.setBounce(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, value.x); + this.setBounce(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, value.y); + this.setBounce(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, value.z); + } + } + get angularBounce() { + return this._angularBounce; + } + set linearDamp(value) { + if (!Laya.Vector3.equals(this._linearDamp, value)) { + value.cloneTo(this._linearDamp); + this.setDamping(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, value.x); + this.setDamping(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, value.y); + this.setDamping(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, value.z); + } + } + get linearDamp() { + return this._linearDamp; + } + set angularDamp(value) { + if (!Laya.Vector3.equals(this._angularDamp, value)) { + value.cloneTo(this._angularDamp); + this.setDamping(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, value.x); + this.setDamping(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, value.y); + this.setDamping(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, value.z); + } + } + get angularDamp() { + return this._angularDamp; + } + set anchor(value) { + value.cloneTo(this._anchor); + this.setFrames(); + } + get anchor() { + return this._anchor; + } + set connectAnchor(value) { + value.cloneTo(this._connectAnchor); + this.setFrames(); + } + get connectAnchor() { + return this._connectAnchor; + } + setAxis(axis, secondaryAxis) { + if (!this._btConstraint) + return; + var bt = Laya.Physics3D._bullet; + this._axis.setValue(axis.x, axis.y, axis.y); + this._secondaryAxis.setValue(secondaryAxis.x, secondaryAxis.y, secondaryAxis.z); + this._btAxis = bt.btVector3_setValue(-axis.x, axis.y, axis.z); + this._btSecondaryAxis = bt.btVector3_setValue(-secondaryAxis.x, secondaryAxis.y, secondaryAxis.z); + bt.btGeneric6DofSpring2Constraint_setAxis(this._btConstraint, this._btAxis, this._btSecondaryAxis); + } + setLimit(axis, motionType, low, high) { + if (!this._btConstraint) + return; + var bt = Laya.Physics3D._bullet; + switch (motionType) { + case ConfigurableConstraint.CONFIG_MOTION_TYPE_LOCKED: + bt.btGeneric6DofSpring2Constraint_setLimit(this._btConstraint, axis, 0, 0); + break; + case ConfigurableConstraint.CONFIG_MOTION_TYPE_LIMITED: + if (low < high) + bt.btGeneric6DofSpring2Constraint_setLimit(this._btConstraint, axis, low, high); + break; + case ConfigurableConstraint.CONFIG_MOTION_TYPE_FREE: + bt.btGeneric6DofSpring2Constraint_setLimit(this._btConstraint, axis, 1, 0); + break; + default: + throw "No Type of Axis Motion"; + } + } + setSpring(axis, springValue, limitIfNeeded = true) { + if (!this._btConstraint) + return; + var bt = Laya.Physics3D._bullet; + var enableSpring = springValue > 0; + bt.btGeneric6DofSpring2Constraint_enableSpring(this._btConstraint, axis, enableSpring); + if (enableSpring) + bt.btGeneric6DofSpring2Constraint_setStiffness(this._btConstraint, axis, springValue, limitIfNeeded); + } + setBounce(axis, bounce) { + if (!this._btConstraint) + return; + var bt = Laya.Physics3D._bullet; + bounce = bounce <= 0 ? 0 : bounce; + bt.btGeneric6DofSpring2Constraint_setBounce(this._btConstraint, axis, bounce); + } + setDamping(axis, damp, limitIfNeeded = true) { + if (!this._btConstraint) + return; + var bt = Laya.Physics3D._bullet; + damp = damp <= 0 ? 0 : damp; + bt.btGeneric6DofSpring2Constraint_setDamping(this._btConstraint, axis, damp, limitIfNeeded); + } + setEquilibriumPoint(axis, equilibriumPoint) { + var bt = Laya.Physics3D._bullet; + bt.btGeneric6DofSpring2Constraint_setEquilibriumPoint(this._btConstraint, axis, equilibriumPoint); + } + enableMotor(axis, isEnableMotor) { + var bt = Laya.Physics3D._bullet; + bt.btGeneric6DofSpring2Constraint_enableMotor(this._btConstraint, axis, isEnableMotor); + } + setServo(axis, onOff) { + var bt = Laya.Physics3D._bullet; + bt.btGeneric6DofSpring2Constraint_setServo(this._btConstraint, axis, onOff); + } + setTargetVelocity(axis, velocity) { + var bt = Laya.Physics3D._bullet; + bt.btGeneric6DofSpring2Constraint_setTargetVelocity(this._btConstraint, axis, velocity); + } + setTargetPosition(axis, target) { + var bt = Laya.Physics3D._bullet; + bt.btGeneric6DofSpring2Constraint_setServoTarget(this._btConstraint, axis, target); + } + setMaxMotorForce(axis, force) { + var bt = Laya.Physics3D._bullet; + bt.btGeneric6DofSpring2Constraint_setMaxMotorForce(this._btConstraint, axis, force); + } + setParam(axis, constraintParams, value) { + var bt = Laya.Physics3D._bullet; + bt.btTypedConstraint_setParam(this._btConstraint, axis, constraintParams, value); + } + setFrames() { + super.setFrames(); + var bt = Laya.Physics3D._bullet; + if (!this._btConstraint) + return; + bt.btGeneric6DofSpring2Constraint_setFrames(this._btConstraint, this._btframATrans, this._btframBTrans); + } + _addToSimulation() { + this._simulation && this._simulation.addConstraint(this, this.enabled); + } + _removeFromSimulation() { + this._simulation.removeConstraint(this); + this._simulation = null; + } + _createConstraint() { + var bt = Laya.Physics3D._bullet; + this._btConstraint = bt.btGeneric6DofSpring2Constraint_create(this.ownBody.btColliderObject, this._btframAPos, this.connectedBody.btColliderObject, this._btframBPos, ConfigurableConstraint.RO_XYZ); + this._btJointFeedBackObj = bt.btJointFeedback_create(this._btConstraint); + bt.btTypedConstraint_setJointFeedback(this._btConstraint, this._btJointFeedBackObj); + this._simulation = this.owner._scene.physicsSimulation; + this._initAllConstraintInfo(); + this._addToSimulation(); + Laya.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint, true); + } + _initAllConstraintInfo() { + this.setLimit(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, this._xMotion, -this._maxLinearLimit.x, -this._minLinearLimit.x); + this.setLimit(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, this._yMotion, this._minLinearLimit.y, this._maxLinearLimit.y); + this.setLimit(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, this._zMotion, this._minLinearLimit.z, this._maxLinearLimit.z); + this.setLimit(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, this._angularXMotion, -this._maxAngularLimit.x, -this._minAngularLimit.x); + this.setLimit(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, this._angularYMotion, this._minAngularLimit.y, this._maxAngularLimit.y); + this.setLimit(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, this._angularZMotion, this._minAngularLimit.z, this._maxAngularLimit.z); + this.setSpring(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, this._linearLimitSpring.x); + this.setSpring(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, this._linearLimitSpring.y); + this.setSpring(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, this._linearLimitSpring.z); + this.setSpring(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, this._angularLimitSpring.x); + this.setSpring(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, this._angularLimitSpring.y); + this.setSpring(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, this._angularLimitSpring.z); + this.setBounce(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, this._linearBounce.x); + this.setBounce(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, this._linearBounce.y); + this.setBounce(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, this._linearBounce.z); + this.setBounce(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, this._angularBounce.x); + this.setBounce(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, this._angularBounce.y); + this.setBounce(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, this._angularBounce.z); + this.setDamping(ConfigurableConstraint.MOTION_LINEAR_INDEX_X, this._linearDamp.x); + this.setDamping(ConfigurableConstraint.MOTION_LINEAR_INDEX_Y, this._linearDamp.y); + this.setDamping(ConfigurableConstraint.MOTION_LINEAR_INDEX_Z, this._linearDamp.z); + this.setDamping(ConfigurableConstraint.MOTION_ANGULAR_INDEX_X, this._angularDamp.x); + this.setDamping(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y, this._angularDamp.y); + this.setDamping(ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z, this._angularDamp.z); + this.setFrames(); + this.setEquilibriumPoint(0, 0); + } + _onAdded() { + super._onAdded(); + } + _onEnable() { + if (!this._btConstraint) + return; + super._onEnable(); + if (this._btConstraint) + Laya.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint, true); + } + _onDisable() { + super._onDisable(); + if (!this.connectedBody && this._simulation) + this._removeFromSimulation(); + if (this._btConstraint) + Laya.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint, false); + } + _parse(data, interactMap = null) { + super._parse(data); + this._axis.fromArray(data.axis); + this._secondaryAxis.fromArray(data.secondaryAxis); + var limitlimit = data.linearLimit; + this._minLinearLimit.setValue(-limitlimit, -limitlimit, -limitlimit); + this._maxLinearLimit.setValue(limitlimit, limitlimit, limitlimit); + var limitSpring = data.linearLimitSpring; + this._linearLimitSpring.setValue(limitSpring, limitSpring, limitSpring); + var limitDamp = data.linearLimitDamper; + this._linearDamp.setValue(limitDamp, limitDamp, limitDamp); + var limitBounciness = data.linearLimitBounciness; + this._linearBounce.setValue(limitBounciness, limitBounciness, limitBounciness); + var xlowAngularLimit = data.lowAngularXLimit; + var xhighAngularLimit = data.highAngularXLimit; + var yAngularLimit = data.angularYLimit; + var zAngularLimit = data.angularZLimit; + this._minAngularLimit.setValue(xlowAngularLimit, -yAngularLimit, -zAngularLimit); + this._maxAngularLimit.setValue(xhighAngularLimit, yAngularLimit, zAngularLimit); + var xhighAngularBounciness = data.highAngularXLimitBounciness; + var ybounciness = data.angularYLimitBounciness; + var zbounciness = data.angularZLimitBounciness; + this._angularBounce.setValue(xhighAngularBounciness, ybounciness, zbounciness); + var xAngularSpring = data.angularXLimitSpring; + var yzAngularSpriny = data.angularYZLimitSpring; + this._angularLimitSpring.setValue(xAngularSpring, yzAngularSpriny, yzAngularSpriny); + var xAngularDamper = data.angularXLimitDamper; + var yzAngularDamper = data.angularYZLimitDamper; + this._angularDamp.setValue(xAngularDamper, yzAngularDamper, yzAngularDamper); + this.XMotion = data.xMotion; + this.YMotion = data.yMotion; + this.ZMotion = data.zMotion; + this.angularXMotion = data.angularXMotion; + this.angularYMotion = data.angularYMotion; + this.angularZMotion = data.angularZMotion; + if (data.rigidbodyID != -1 && data.connectRigidbodyID != -1) { + interactMap.component.push(this); + interactMap.data.push(data); + } + (data.breakForce != undefined) && (this.breakForce = data.breakForce); + (data.breakTorque != undefined) && (this.breakTorque = data.breakTorque); + } + _parseInteractive(data = null, spriteMap = null) { + var rigidBodySprite = spriteMap[data.rigidbodyID]; + var rigidBody = rigidBodySprite.getComponent(Rigidbody3D); + var connectSprite = spriteMap[data.connectRigidbodyID]; + var connectRigidbody = connectSprite.getComponent(Rigidbody3D); + this.ownBody = rigidBody; + this.connectedBody = connectRigidbody; + } + _onDestroy() { + super._onDestroy(); + } + } + ConfigurableConstraint.CONFIG_MOTION_TYPE_LOCKED = 0; + ConfigurableConstraint.CONFIG_MOTION_TYPE_LIMITED = 1; + ConfigurableConstraint.CONFIG_MOTION_TYPE_FREE = 2; + ConfigurableConstraint.MOTION_LINEAR_INDEX_X = 0; + ConfigurableConstraint.MOTION_LINEAR_INDEX_Y = 1; + ConfigurableConstraint.MOTION_LINEAR_INDEX_Z = 2; + ConfigurableConstraint.MOTION_ANGULAR_INDEX_X = 3; + ConfigurableConstraint.MOTION_ANGULAR_INDEX_Y = 4; + ConfigurableConstraint.MOTION_ANGULAR_INDEX_Z = 5; + ConfigurableConstraint.RO_XYZ = 0; + ConfigurableConstraint.RO_XZY = 1; + ConfigurableConstraint.RO_YXZ = 2; + ConfigurableConstraint.RO_YZX = 3; + ConfigurableConstraint.RO_ZXY = 4; + ConfigurableConstraint.RO_ZYX = 5; + + class FixedConstraint extends ConstraintComponent { + constructor() { + super(ConstraintComponent.CONSTRAINT_FIXED_CONSTRAINT_TYPE); + this.breakForce = -1; + this.breakTorque = -1; + } + _addToSimulation() { + this._simulation && this._simulation.addConstraint(this, this.enabled); + } + _removeFromSimulation() { + this._simulation.removeConstraint(this); + this._simulation = null; + } + _createConstraint() { + if (this.ownBody && this.ownBody._simulation && this.connectedBody && this.connectedBody._simulation) { + var bt = Laya.Physics3D._bullet; + this._btConstraint = bt.btFixedConstraint_create(this.ownBody.btColliderObject, this._btframATrans, this.connectedBody.btColliderObject, this._btframBTrans); + this._btJointFeedBackObj = bt.btJointFeedback_create(this._btConstraint); + bt.btTypedConstraint_setJointFeedback(this._btConstraint, this._btJointFeedBackObj); + this._simulation = this.owner._scene.physicsSimulation; + this._addToSimulation(); + Laya.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint, true); + } + } + _onAdded() { + super._onAdded(); + } + _onEnable() { + if (!this._btConstraint) + return; + super._onEnable(); + if (this._btConstraint) + Laya.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint, true); + } + _onDisable() { + super._onDisable(); + if (!this.connectedBody) + this._removeFromSimulation(); + if (this._btConstraint) + Laya.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint, false); + } + _onDestroy() { + super._onDestroy(); + } + _parse(data, interactMap = null) { + super._parse(data); + if (data.rigidbodyID != -1 && data.connectRigidbodyID != -1) { + interactMap.component.push(this); + interactMap.data.push(data); + } + (data.breakForce != undefined) && (this.breakForce = data.breakForce); + (data.breakTorque != undefined) && (this.breakTorque = data.breakTorque); + } + _parseInteractive(data = null, spriteMap = null) { + var rigidBodySprite = spriteMap[data.rigidbodyID]; + var rigidBody = rigidBodySprite.getComponent(Rigidbody3D); + var connectSprite = spriteMap[data.connectRigidbodyID]; + var connectRigidbody = connectSprite.getComponent(Rigidbody3D); + this.ownBody = rigidBody; + this.connectedBody = connectRigidbody; + } + } + + class StaticPlaneColliderShape extends ColliderShape { + constructor(normal, offset) { + super(); + this._normal = normal; + this._offset = offset; + this._type = ColliderShape.SHAPETYPES_STATICPLANE; + var bt = Laya.ILaya3D.Physics3D._bullet; + bt.btVector3_setValue(StaticPlaneColliderShape._btNormal, -normal.x, normal.y, normal.z); + this._btShape = bt.btStaticPlaneShape_create(StaticPlaneColliderShape._btNormal, offset); + } + static __init__() { + StaticPlaneColliderShape._btNormal = Laya.ILaya3D.Physics3D._bullet.btVector3_create(0, 0, 0); + } + clone() { + var dest = new StaticPlaneColliderShape(this._normal, this._offset); + this.cloneTo(dest); + return dest; + } + } + + exports.BoxColliderShape = BoxColliderShape; + exports.BulletInteractive = BulletInteractive; + exports.CapsuleColliderShape = CapsuleColliderShape; + exports.CharacterController = CharacterController; + exports.ColliderShape = ColliderShape; + exports.Collision = Collision; + exports.CollisionTool = CollisionTool; + exports.CompoundColliderShape = CompoundColliderShape; + exports.ConeColliderShape = ConeColliderShape; + exports.ConfigurableConstraint = ConfigurableConstraint; + exports.Constraint3D = Constraint3D; + exports.ConstraintComponent = ConstraintComponent; + exports.ContactPoint = ContactPoint; + exports.CylinderColliderShape = CylinderColliderShape; + exports.FixedConstraint = FixedConstraint; + exports.HitResult = HitResult; + exports.MeshColliderShape = MeshColliderShape; + exports.PhysicsCollider = PhysicsCollider; + exports.PhysicsComponent = PhysicsComponent; + exports.PhysicsSettings = PhysicsSettings; + exports.PhysicsSimulation = PhysicsSimulation; + exports.PhysicsTriggerComponent = PhysicsTriggerComponent; + exports.PhysicsUpdateList = PhysicsUpdateList; + exports.Rigidbody3D = Rigidbody3D; + exports.SphereColliderShape = SphereColliderShape; + exports.StaticPlaneColliderShape = StaticPlaneColliderShape; + +}(window.Laya = window.Laya || {}, Laya)); diff --git a/examples/layaair/frontend/bin/libs/laya.physics3D.wasm.wasm b/examples/layaair/frontend/bin/libs/laya.physics3D.wasm.wasm new file mode 100644 index 0000000..a33b255 Binary files /dev/null and b/examples/layaair/frontend/bin/libs/laya.physics3D.wasm.wasm differ diff --git a/examples/layaair/frontend/bin/libs/laya.qqmini.js b/examples/layaair/frontend/bin/libs/laya.qqmini.js new file mode 100644 index 0000000..bf3c6c4 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.qqmini.js @@ -0,0 +1,1855 @@ +window.qqMiniGame = function (exports, Laya) { + 'use strict'; + + function ImageDataPolyfill() { + let width, height, data; + if (arguments.length == 3) { + if (arguments[0] instanceof Uint8ClampedArray) { + if (arguments[0].length % 4 !== 0) { + throw new Error("Failed to construct 'ImageData': The input data length is not a multiple of 4."); + } + if (arguments[0].length !== arguments[1] * arguments[2] * 4) { + throw new Error("Failed to construct 'ImageData': The input data length is not equal to (4 * width * height)."); + } + else { + data = arguments[0]; + width = arguments[1]; + height = arguments[2]; + } + } + else { + throw new Error("Failed to construct 'ImageData': parameter 1 is not of type 'Uint8ClampedArray'."); + } + } + else if (arguments.length == 2) { + width = arguments[0]; + height = arguments[1]; + data = new Uint8ClampedArray(arguments[0] * arguments[1] * 4); + } + else if (arguments.length < 2) { + throw new Error("Failed to construct 'ImageData': 2 arguments required, but only " + arguments.length + " present."); + } + let imgdata = Laya.Browser.canvas.getContext("2d").getImageData(0, 0, width, height); + for (let i = 0; i < data.length; i += 4) { + imgdata.data[i] = data[i]; + imgdata.data[i + 1] = data[i + 1]; + imgdata.data[i + 2] = data[i + 2]; + imgdata.data[i + 3] = data[i + 3]; + } + return imgdata; + } + + class MiniFileMgr { + static isLocalNativeFile(url) { + for (var i = 0, sz = QQMiniAdapter.nativefiles.length; i < sz; i++) { + if (url.indexOf(QQMiniAdapter.nativefiles[i]) != -1) + return true; + } + return false; + } + static isNetFile(url) { + return (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) && url.indexOf(QQMiniAdapter.window.qq.env.USER_DATA_PATH) == -1; + } + static getFileInfo(fileUrl) { + var fileNativePath = fileUrl; + var fileObj = MiniFileMgr.fakeObj[fileNativePath]; + if (fileObj == null) + return null; + else + return fileObj; + } + static read(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "") { + var fileUrl; + if (readyUrl != "" && (readyUrl.indexOf("http://") != -1 || readyUrl.indexOf("https://") != -1)) { + fileUrl = MiniFileMgr.getFileNativePath(filePath); + } + else { + fileUrl = filePath; + } + fileUrl = Laya.URL.getAdptedFilePath(fileUrl); + MiniFileMgr.fs.readFile({ filePath: fileUrl, encoding: encoding, success: function (data) { + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data && readyUrl != "") + MiniFileMgr.downFiles(QQMiniAdapter.safeEncodeURI(readyUrl), encoding, callBack, readyUrl, isSaveFile, fileType); + else + callBack != null && callBack.runWith([1]); + } }); + } + static isFile(url) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(url); + } + catch (err) { + return false; + } + return stat.isFile(); + } + static downFiles(fileUrl, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + var downloadTask = MiniFileMgr.down({ url: fileUrl, success: function (data) { + if (data.statusCode === 200) + MiniFileMgr.readFile(data.tempFilePath, encoding, callBack, readyUrl, isSaveFile, fileType, isAutoClear); + else if (data.statusCode === 403) { + callBack != null && callBack.runWith([0, fileUrl]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + downloadTask.onProgressUpdate(function (data) { + callBack != null && callBack.runWith([2, data.progress]); + }); + } + static readFile(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + filePath = Laya.URL.getAdptedFilePath(filePath); + MiniFileMgr.fs.readFile({ filePath: filePath, encoding: encoding, success: function (data) { + if ((filePath.indexOf("http://") != -1 || filePath.indexOf("https://") != -1) && filePath.indexOf(QQMiniAdapter.window.qq.env.USER_DATA_PATH) == -1) { + if (QQMiniAdapter.AutoCacheDownFile || isSaveFile) { + callBack != null && callBack.runWith([0, data]); + MiniFileMgr.copyTOCache(filePath, readyUrl, null, encoding, isAutoClear); + } + else + callBack != null && callBack.runWith([0, data]); + } + else + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data) + callBack != null && callBack.runWith([1, data]); + } }); + } + static downOtherFiles(fileUrl, callBack = null, readyUrl = "", isSaveFile = false, isAutoClear = true) { + MiniFileMgr.down({ url: fileUrl, success: function (data) { + if (data.statusCode === 200) { + if ((QQMiniAdapter.autoCacheFile || isSaveFile) && readyUrl.indexOf(".php") == -1) { + callBack != null && callBack.runWith([0, data.tempFilePath]); + MiniFileMgr.copyTOCache(data.tempFilePath, readyUrl, null, "", isAutoClear); + } + else + callBack != null && callBack.runWith([0, data.tempFilePath]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static copyFile(src, dest, complete = null) { + MiniFileMgr.fs.copyFile({ + srcPath: src, + destPath: dest, + success: function () { + complete && complete.runWith(0); + }, + fail: function (err) { + complete && complete.runWith([1, err]); + } + }); + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + if (window.navigator.userAgent.indexOf('MiniGame') < 0) { + Laya.Laya.loader.load(fileUrl, callBack); + } + else { + if (fileType == Laya.Loader.IMAGE || fileType == Laya.Loader.SOUND) + MiniFileMgr.downOtherFiles(fileUrl, callBack, fileUrl, true, false); + else + MiniFileMgr.downFiles(fileUrl, encoding, callBack, fileUrl, true, fileType, false); + } + } + static copyTOCache(tempFilePath, readyUrl, callBack, encoding = "", isAutoClear = true) { + var temp = tempFilePath.split("/"); + var tempFileName = temp[temp.length - 1]; + var fileurlkey = readyUrl; + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fakeObj[fileurlkey] = { md5: tempFileName, readyUrl: readyUrl, size: 0, times: Laya.Browser.now(), encoding: encoding, tempFilePath: tempFilePath }; + var totalSize = QQMiniAdapter.sizeLimit; + var chaSize = 4 * 1024 * 1024; + var fileUseSize = MiniFileMgr.getCacheUseSize(); + if (fileObj) { + if (fileObj.readyUrl != readyUrl) { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > QQMiniAdapter.minClearSize) + QQMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.deleteFile(tempFilePath, readyUrl, callBack, encoding, data.size); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + else + callBack != null && callBack.runWith([0]); + } + else { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > QQMiniAdapter.minClearSize) + QQMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.fs.copyFile({ srcPath: tempFilePath, destPath: saveFilePath, success: function (data2) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, data.size); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + } + static onClearCacheRes() { + var memSize = QQMiniAdapter.minClearSize; + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + MiniFileMgr.sortOn(tempFileListArr, "times", MiniFileMgr.NUMERIC); + var clearSize = 0; + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + if (clearSize >= memSize) + break; + clearSize += fileObj.size; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + } + static sortOn(array, name, options = 0) { + if (options == MiniFileMgr.NUMERIC) + return array.sort(function (a, b) { return a[name] - b[name]; }); + if (options == (MiniFileMgr.NUMERIC | MiniFileMgr.DESCENDING)) + return array.sort(function (a, b) { return b[name] - a[name]; }); + return array.sort(function (a, b) { return a[name] - b[name]; }); + } + static getFileNativePath(fileName) { + return MiniFileMgr.fileNativeDir + "/" + fileName; + } + static deleteFile(tempFileName, readyUrl = "", callBack = null, encoding = "", fileSize = 0) { + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var deleteFileUrl = MiniFileMgr.getFileNativePath(fileObj.md5); + MiniFileMgr.fs.unlink({ filePath: deleteFileUrl, success: function (data) { + if (tempFileName != "") { + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fs.copyFile({ srcPath: tempFileName, destPath: saveFilePath, success: function (data) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, fileSize); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + else { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, false, encoding, callBack, fileSize); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static deleteAll() { + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj.fileUsedSize) { + MiniFileMgr.filesListObj.fileUsedSize = 0; + } + MiniFileMgr.writeFilesList("", JSON.stringify({}), false); + } + static onSaveFile(readyUrl, md5Name, isAdd = true, encoding = "", callBack = null, fileSize = 0) { + var fileurlkey = readyUrl; + if (MiniFileMgr.filesListObj['fileUsedSize'] == null) + MiniFileMgr.filesListObj['fileUsedSize'] = 0; + if (isAdd) { + var fileNativeName = MiniFileMgr.getFileNativePath(md5Name); + MiniFileMgr.filesListObj[fileurlkey] = { md5: md5Name, readyUrl: readyUrl, size: fileSize, times: Laya.Browser.now(), encoding: encoding, tempFilePath: fileNativeName }; + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) + fileSize; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), true); + callBack != null && callBack.runWith([0]); + } + else { + if (MiniFileMgr.filesListObj[fileurlkey]) { + var deletefileSize = parseInt(MiniFileMgr.filesListObj[fileurlkey].size); + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) - deletefileSize; + if (MiniFileMgr.fakeObj[fileurlkey].md5 == MiniFileMgr.filesListObj[fileurlkey].md5) { + delete MiniFileMgr.fakeObj[fileurlkey]; + } + delete MiniFileMgr.filesListObj[fileurlkey]; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), false); + callBack != null && callBack.runWith([0]); + } + } + } + static writeFilesList(fileurlkey, filesListStr, isAdd) { + var listFilesPath = MiniFileMgr.fileNativeDir + "/" + MiniFileMgr.fileListName; + MiniFileMgr.fs.writeFile({ filePath: listFilesPath, encoding: 'utf8', data: filesListStr, success: function (data) { + }, fail: function (data) { + } }); + if (!QQMiniAdapter.isZiYu && QQMiniAdapter.isPosMsgYu) { + QQMiniAdapter.window.qq.postMessage({ url: fileurlkey, data: MiniFileMgr.filesListObj[fileurlkey], isLoad: "filenative", isAdd: isAdd }); + } + } + static getCacheUseSize() { + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj['fileUsedSize']) + return MiniFileMgr.filesListObj['fileUsedSize']; + return 0; + } + static getCacheList(dirPath, cb) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(dirPath); + } + catch (err) { + stat = null; + } + if (stat) { + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", cb); + } + else { + MiniFileMgr.fs.mkdirSync(dirPath, true); + cb && cb.runWith([1]); + } + } + static existDir(dirPath, callBack) { + MiniFileMgr.fs.mkdir({ dirPath: dirPath, success: function (data) { + callBack != null && callBack.runWith([0, { data: JSON.stringify({}) }]); + }, fail: function (data) { + if (data.errMsg.indexOf("file already exists") != -1) + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", callBack); + else + callBack != null && callBack.runWith([1, data]); + } }); + } + static readSync(filePath, encoding = "utf8", callBack = null, readyUrl = "") { + var fileUrl = MiniFileMgr.getFileNativePath(filePath); + var filesListStr; + try { + filesListStr = MiniFileMgr.fs.readFileSync(fileUrl, encoding); + callBack != null && callBack.runWith([0, { data: filesListStr }]); + } + catch (error) { + callBack != null && callBack.runWith([1]); + } + } + static setNativeFileDir(value) { + MiniFileMgr.fileNativeDir = QQMiniAdapter.window.qq.env.USER_DATA_PATH + value; + } + } + MiniFileMgr.fs = window.qq.getFileSystemManager(); + MiniFileMgr.down = window.qq.downloadFile; + MiniFileMgr.filesListObj = {}; + MiniFileMgr.fakeObj = {}; + MiniFileMgr.fileListName = "layaairfiles.txt"; + MiniFileMgr.ziyuFileData = {}; + MiniFileMgr.ziyuFileTextureData = {}; + MiniFileMgr.loadPath = ""; + MiniFileMgr.DESCENDING = 2; + MiniFileMgr.NUMERIC = 16; + + class MiniSoundChannel extends Laya.SoundChannel { + constructor(audio, miniSound) { + super(); + this._audio = audio; + this._miniSound = miniSound; + this._onEnd = MiniSoundChannel.bindToThis(this.__onEnd, this); + audio.onEnded(this._onEnd); + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + __onEnd() { + if (this.loops == 1) { + if (this.completeHandler) { + Laya.Laya.systemTimer.once(10, this, this.__runComplete, [this.completeHandler], false); + this.completeHandler = null; + } + this.stop(); + this.event(Laya.Event.COMPLETE); + return; + } + if (this.loops > 0) { + this.loops--; + } + this.startTime = 0; + this.play(); + } + play() { + this.isStopped = false; + Laya.SoundManager.addChannel(this); + this._audio.play(); + } + set startTime(time) { + if (this._audio) { + this._audio.startTime = time; + } + } + set autoplay(value) { + this._audio.autoplay = value; + } + get autoplay() { + return this._audio.autoplay; + } + get position() { + if (!this._audio) + return 0; + return this._audio.currentTime; + } + get duration() { + if (!this._audio) + return 0; + return this._audio.duration; + } + stop() { + this.isStopped = true; + Laya.SoundManager.removeChannel(this); + this.completeHandler = null; + if (!this._audio) + return; + this._audio.stop(); + if (!this.loop) { + this._audio.offEnded(null); + this._miniSound.dispose(); + this._audio = null; + this._miniSound = null; + this._onEnd = null; + } + } + pause() { + this.isStopped = true; + this._audio.pause(); + } + get loop() { + return this._audio.loop; + } + set loop(value) { + this._audio.loop = value; + } + resume() { + if (!this._audio) + return; + this.isStopped = false; + Laya.SoundManager.addChannel(this); + this._audio.play(); + } + set volume(v) { + if (!this._audio) + return; + this._audio.volume = v; + } + get volume() { + if (!this._audio) + return 1; + return this._audio.volume; + } + } + + class MiniSound extends Laya.EventDispatcher { + constructor() { + super(); + this.loaded = false; + } + static _createSound() { + MiniSound._id++; + return QQMiniAdapter.window.qq.createInnerAudioContext(); + } + load(url) { + if (!MiniSound._musicAudio) + MiniSound._musicAudio = MiniSound._createSound(); + if (!MiniFileMgr.isLocalNativeFile(url)) { + url = Laya.URL.formatURL(url); + } + else { + if (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + if (tempStr != "") + url = url.split(tempStr)[1]; + } + } + } + this.url = url; + this.readyUrl = url; + if (MiniSound._audioCache[this.readyUrl]) { + this.event(Laya.Event.COMPLETE); + return; + } + if (QQMiniAdapter.autoCacheFile && MiniFileMgr.getFileInfo(url)) { + this.onDownLoadCallBack(url, 0); + } + else { + if (!QQMiniAdapter.autoCacheFile) { + this.onDownLoadCallBack(url, 0); + } + else { + if (MiniFileMgr.isLocalNativeFile(url)) { + tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + if (QQMiniAdapter.subNativeFiles && QQMiniAdapter.subNativeheads.length == 0) { + for (var key in QQMiniAdapter.subNativeFiles) { + var tempArr = QQMiniAdapter.subNativeFiles[key]; + QQMiniAdapter.subNativeheads = QQMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + QQMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (QQMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && QQMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = QQMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + this.onDownLoadCallBack(url, 0); + } + else { + if (!MiniFileMgr.isLocalNativeFile(url) && (url.indexOf("http://") == -1 && url.indexOf("https://") == -1) || (url.indexOf(QQMiniAdapter.window.qq.env.USER_DATA_PATH) != -1)) { + this.onDownLoadCallBack(url, 0); + } + else { + MiniFileMgr.downOtherFiles(encodeURI(url), Laya.Handler.create(this, this.onDownLoadCallBack, [url]), url); + } + } + } + } + } + onDownLoadCallBack(sourceUrl, errorCode, tempFilePath = null) { + if (!errorCode) { + var fileNativeUrl; + if (QQMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = sourceUrl; + if (tempStr != "" && (sourceUrl.indexOf("http://") != -1 || sourceUrl.indexOf("https://") != -1)) + fileNativeUrl = sourceUrl.split(tempStr)[1]; + if (!fileNativeUrl) { + fileNativeUrl = tempUrl; + } + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + var fileMd5Name = fileObj.md5; + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileMd5Name); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + if (this.url != Laya.SoundManager._bgMusic) { + this._sound = MiniSound._createSound(); + this._sound.src = this.url = fileNativeUrl; + } + else { + this._sound = MiniSound._musicAudio; + this._sound.src = this.url = fileNativeUrl; + } + } + else { + if (this.url != Laya.SoundManager._bgMusic) { + this._sound = MiniSound._createSound(); + this._sound.src = sourceUrl; + } + else { + this._sound = MiniSound._musicAudio; + this._sound.src = sourceUrl; + } + } + this._sound.onCanplay(MiniSound.bindToThis(this.onCanPlay, this)); + this._sound.onError(MiniSound.bindToThis(this.onError, this)); + } + else { + this.event(Laya.Event.ERROR); + } + } + onError(error) { + try { + console.log("-----1---------------minisound-----id:" + MiniSound._id); + console.log(error); + } + catch (error) { + console.log("-----2---------------minisound-----id:" + MiniSound._id); + console.log(error); + } + this.event(Laya.Event.ERROR); + this._sound.offError(null); + } + onCanPlay() { + this.loaded = true; + this.event(Laya.Event.COMPLETE); + this._sound.offCanplay(null); + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + play(startTime = 0, loops = 0) { + var tSound; + if (this.url == Laya.SoundManager._bgMusic) { + if (!MiniSound._musicAudio) + MiniSound._musicAudio = MiniSound._createSound(); + tSound = MiniSound._musicAudio; + } + else { + if (MiniSound._audioCache[this.readyUrl]) { + tSound = MiniSound._audioCache[this.readyUrl]._sound; + } + else { + tSound = MiniSound._createSound(); + } + } + if (!tSound) + return null; + if (QQMiniAdapter.autoCacheFile && MiniFileMgr.getFileInfo(this.url)) { + var fileObj = MiniFileMgr.getFileInfo(this.url); + var fileMd5Name = fileObj.md5; + tSound.src = this.url = MiniFileMgr.getFileNativePath(fileMd5Name); + } + else { + tSound.src = encodeURI(this.url); + } + var channel = new MiniSoundChannel(tSound, this); + channel.url = this.url; + channel.loops = loops; + channel.loop = (loops === 0 ? true : false); + channel.startTime = startTime; + channel.play(); + Laya.SoundManager.addChannel(channel); + return channel; + } + get duration() { + return this._sound.duration; + } + dispose() { + var ad = MiniSound._audioCache[this.readyUrl]; + if (ad) { + ad.src = ""; + if (ad._sound) { + ad._sound.destroy(); + ad._sound = null; + ad = null; + } + delete MiniSound._audioCache[this.readyUrl]; + } + if (this._sound) { + this._sound.destroy(); + this._sound = null; + this.readyUrl = this.url = null; + } + } + } + MiniSound._id = 0; + MiniSound._audioCache = {}; + + class MiniInput { + constructor() { + } + static _createInputElement() { + Laya.Input['_initInput'](Laya.Input['area'] = Laya.Browser.createElement("textarea")); + Laya.Input['_initInput'](Laya.Input['input'] = Laya.Browser.createElement("input")); + Laya.Input['inputContainer'] = Laya.Browser.createElement("div"); + Laya.Input['inputContainer'].style.position = "absolute"; + Laya.Input['inputContainer'].style.zIndex = 1E5; + Laya.Browser.container.appendChild(Laya.Input['inputContainer']); + Laya.Laya.stage.on("resize", null, MiniInput._onStageResize); + QQMiniAdapter.window.qq.onWindowResize && QQMiniAdapter.window.qq.onWindowResize(function (res) { + }); + Laya.SoundManager._soundClass = MiniSound; + Laya.SoundManager._musicClass = MiniSound; + var model = QQMiniAdapter.systemInfo.model; + var system = QQMiniAdapter.systemInfo.system; + if (model.indexOf("iPhone") != -1) { + Laya.Browser.onIPhone = true; + Laya.Browser.onIOS = true; + Laya.Browser.onIPad = true; + Laya.Browser.onAndroid = false; + } + if (system.indexOf("Android") != -1 || system.indexOf("Adr") != -1) { + Laya.Browser.onAndroid = true; + Laya.Browser.onIPhone = false; + Laya.Browser.onIOS = false; + Laya.Browser.onIPad = false; + } + } + static _onStageResize() { + var ts = Laya.Laya.stage._canvasTransform.identity(); + ts.scale((Laya.Browser.width / Laya.Render.canvas.width / Laya.Browser.pixelRatio), Laya.Browser.height / Laya.Render.canvas.height / Laya.Browser.pixelRatio); + } + static wxinputFocus(e) { + var _inputTarget = Laya.Input['inputElement'].target; + if (_inputTarget && !_inputTarget.editable) { + return; + } + QQMiniAdapter.window.qq.offKeyboardConfirm(); + QQMiniAdapter.window.qq.offKeyboardInput(); + QQMiniAdapter.window.qq.showKeyboard({ defaultValue: _inputTarget.text, maxLength: _inputTarget.maxChars, multiple: _inputTarget.multiline, confirmHold: true, confirmType: _inputTarget["confirmType"] || 'done', success: function (res) { + }, fail: function (res) { + } }); + QQMiniAdapter.window.qq.onKeyboardConfirm(function (res) { + var str = res ? res.value : ""; + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + MiniInput.inputEnter(); + _inputTarget.event("confirm"); + }); + QQMiniAdapter.window.qq.onKeyboardInput(function (res) { + var str = res ? res.value : ""; + if (!_inputTarget.multiline) { + if (str.indexOf("\n") != -1) { + MiniInput.inputEnter(); + return; + } + } + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + }); + } + static inputEnter() { + Laya.Input['inputElement'].target.focus = false; + } + static wxinputblur() { + MiniInput.hideKeyboard(); + } + static hideKeyboard() { + QQMiniAdapter.window.qq.offKeyboardConfirm(); + QQMiniAdapter.window.qq.offKeyboardInput(); + QQMiniAdapter.window.qq.hideKeyboard({ success: function (res) { + console.log('隐藏键盘'); + }, fail: function (res) { + console.log("隐藏键盘出错:" + (res ? res.errMsg : "")); + } }); + } + } + + class MiniLoader extends Laya.EventDispatcher { + constructor() { + super(); + } + _loadResourceFilter(type, url) { + var thisLoader = this; + this.sourceUrl = Laya.URL.formatURL(url); + if (MiniFileMgr.isNetFile(url)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (QQMiniAdapter.subNativeFiles && QQMiniAdapter.subNativeheads.length == 0) { + for (var key in QQMiniAdapter.subNativeFiles) { + var tempArr = QQMiniAdapter.subNativeFiles[key]; + QQMiniAdapter.subNativeheads = QQMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + QQMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (QQMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && QQMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = QQMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + switch (type) { + case Laya.Loader.IMAGE: + case "htmlimage": + case "nativeimage": + MiniLoader._transformImgUrl(url, type, thisLoader); + break; + case Laya.Loader.SOUND: + thisLoader._loadSound(url); + break; + default: + thisLoader._loadResource(type, url); + } + } + _loadSound(url) { + var thisLoader = this; + if (!QQMiniAdapter.autoCacheFile) { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + else { + var tempurl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downOtherFiles(QQMiniAdapter.safeEncodeURI(tempurl), Laya.Handler.create(MiniLoader, MiniLoader.onDownLoadCallBack, [tempurl, thisLoader]), tempurl); + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + } + static onDownLoadCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = null) { + if (!errorCode) { + var fileNativeUrl; + if (QQMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + fileNativeUrl = sourceUrl; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + } + else { + fileNativeUrl = Laya.URL.formatURL(sourceUrl); + } + sourceUrl = fileNativeUrl; + var sound = (new Laya.SoundManager._soundClass()); + sound.load(QQMiniAdapter.safeEncodeURI(sourceUrl)); + thisLoader.onLoaded(sound); + } + else { + thisLoader.event(Laya.Event.ERROR, "Load sound failed"); + } + } + complete(data) { + if (data instanceof Laya.Resource) { + data._setCreateURL(this.sourceUrl); + } + else if ((data instanceof Laya.Texture) && (data.bitmap instanceof Laya.Resource)) { + data.bitmap._setCreateURL(this.sourceUrl); + } + this.originComplete(data); + } + _loadHttpRequestWhat(url, contentType) { + var thisLoader = this; + var encoding = QQMiniAdapter.getUrlEncode(url, contentType); + if (Laya.Loader.preLoadedMap[url]) + thisLoader.onLoaded(Laya.Loader.preLoadedMap[url]); + else { + var tempurl = Laya.URL.formatURL(url); + if (!QQMiniAdapter.AutoCacheDownFile) { + if (MiniFileMgr.isNetFile(tempurl)) { + thisLoader._loadHttpRequest(tempurl, contentType, thisLoader, thisLoader.onLoaded, thisLoader, thisLoader.onProgress, thisLoader, thisLoader.onError); + } + else + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + else { + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downFiles(QQMiniAdapter.safeEncodeURI(tempurl), encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), tempurl, true); + } + else { + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + else { + var tempUrl = url; + var fileObj = MiniFileMgr.getFileInfo(tempurl); + if (fileObj && fileObj.md5) { + tempUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + MiniFileMgr.readFile(tempUrl, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + } + } + static onReadNativeCallBack(url, type = null, thisLoader = null, errorCode = 0, data = null) { + if (!errorCode) { + var tempData; + if (type == Laya.Loader.JSON || type == Laya.Loader.ATLAS || type == Laya.Loader.PREFAB || type == Laya.Loader.PLF) { + tempData = QQMiniAdapter.getJson(data.data); + } + else if (type == Laya.Loader.XML) { + tempData = Laya.Utils.parseXMLFromString(data.data); + } + else { + tempData = data.data; + } + if (!QQMiniAdapter.isZiYu && QQMiniAdapter.isPosMsgYu && type != Laya.Loader.BUFFER) { + QQMiniAdapter.window.qq.postMessage({ url: url, data: tempData, isLoad: "filedata" }); + } + thisLoader.onLoaded(tempData); + } + else if (errorCode == 1) { + thisLoader._loadHttpRequest(url, type, thisLoader, thisLoader.onLoaded, thisLoader, thisLoader.onProgress, thisLoader, thisLoader.onError); + } + } + static _transformImgUrl(url, type, thisLoader) { + if (QQMiniAdapter.isZiYu || MiniFileMgr.isLocalNativeFile(url)) { + thisLoader._loadImage(url, false); + return; + } + if (!QQMiniAdapter.autoCacheFile) { + thisLoader._loadImage(QQMiniAdapter.safeEncodeURI(url)); + } + else { + var tempUrl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempUrl)) { + if (MiniFileMgr.isNetFile(tempUrl)) { + MiniFileMgr.downOtherFiles(QQMiniAdapter.safeEncodeURI(tempUrl), new Laya.Handler(MiniLoader, MiniLoader.onDownImgCallBack, [url, thisLoader]), tempUrl); + } + else { + MiniLoader.onCreateImage(url, thisLoader, true); + } + } + else { + MiniLoader.onCreateImage(url, thisLoader); + } + } + } + static onDownImgCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = "") { + if (!errorCode) + MiniLoader.onCreateImage(sourceUrl, thisLoader, false, tempFilePath); + else { + thisLoader.onError(null); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (QQMiniAdapter.autoCacheFile) { + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + var fileObj = MiniFileMgr.getFileInfo(Laya.URL.formatURL(sourceUrl)); + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + } + else if (QQMiniAdapter.isZiYu) { + var tempUrl = Laya.URL.formatURL(sourceUrl); + if (MiniFileMgr.ziyuFileTextureData[tempUrl]) { + fileNativeUrl = MiniFileMgr.ziyuFileTextureData[tempUrl]; + } + else + fileNativeUrl = sourceUrl; + } + else + fileNativeUrl = sourceUrl; + } + else { + if (!isLocal) + fileNativeUrl = tempFilePath; + else + fileNativeUrl = sourceUrl; + } + thisLoader._loadImage(fileNativeUrl, false); + } + } + + class MiniLocalStorage { + constructor() { + } + static __init__() { + MiniLocalStorage.items = MiniLocalStorage; + } + static setItem(key, value) { + try { + QQMiniAdapter.window.qq.setStorageSync(key, value); + } + catch (error) { + QQMiniAdapter.window.qq.setStorage({ + key: key, + data: value + }); + } + } + static getItem(key) { + return QQMiniAdapter.window.qq.getStorageSync(key); + } + static setJSON(key, value) { + MiniLocalStorage.setItem(key, value); + } + static getJSON(key) { + return MiniLocalStorage.getItem(key); + } + static removeItem(key) { + QQMiniAdapter.window.qq.removeStorageSync(key); + } + static clear() { + QQMiniAdapter.window.qq.clearStorageSync(); + } + static getStorageInfoSync() { + try { + var res = QQMiniAdapter.window.qq.getStorageInfoSync(); + console.log(res.keys); + console.log(res.currentSize); + console.log(res.limitSize); + return res; + } + catch (e) { + } + return null; + } + } + MiniLocalStorage.support = true; + + class QQMiniAdapter { + static getJson(data) { + return JSON.parse(data); + } + static enable() { + QQMiniAdapter.init(Laya.Laya.isWXPosMsg, Laya.Laya.isWXOpenDataContext); + } + static init(isPosMsg = false, isSon = false) { + if (QQMiniAdapter._inited) + return; + QQMiniAdapter._inited = true; + QQMiniAdapter.window = window; + if (!QQMiniAdapter.window.hasOwnProperty("qq")) + return; + if (QQMiniAdapter.window.navigator.userAgent.indexOf('MiniGame') < 0) + return; + QQMiniAdapter.isZiYu = isSon; + QQMiniAdapter.isPosMsgYu = isPosMsg; + QQMiniAdapter.EnvConfig = {}; + if (!QQMiniAdapter.isZiYu) { + MiniFileMgr.setNativeFileDir("/layaairGame"); + MiniFileMgr.getCacheList(MiniFileMgr.fileNativeDir, Laya.Handler.create(QQMiniAdapter, QQMiniAdapter.onMkdirCallBack)); + } + QQMiniAdapter.systemInfo = QQMiniAdapter.window.qq.getSystemInfoSync(); + QQMiniAdapter.window.focus = function () { + }; + Laya.Laya['_getUrlPath'] = function () { + return ""; + }; + QQMiniAdapter.window.logtime = function (str) { + }; + QQMiniAdapter.window.alertTimeLog = function (str) { + }; + QQMiniAdapter.window.resetShareInfo = function () { + }; + QQMiniAdapter.window.CanvasRenderingContext2D = function () { + }; + QQMiniAdapter.window.CanvasRenderingContext2D.prototype = QQMiniAdapter.window.qq.createCanvas().getContext('2d').__proto__; + QQMiniAdapter.window.document.body.appendChild = function () { + }; + Laya.HttpRequest._urlEncode = QQMiniAdapter.safeEncodeURI; + QQMiniAdapter.EnvConfig.pixelRatioInt = 0; + Laya.Browser["_pixelRatio"] = QQMiniAdapter.pixelRatio(); + QQMiniAdapter._preCreateElement = Laya.Browser.createElement; + Laya.Browser["createElement"] = QQMiniAdapter.createElement; + Laya.RunDriver.createShaderCondition = QQMiniAdapter.createShaderCondition; + Laya.Utils['parseXMLFromString'] = QQMiniAdapter.parseXMLFromString; + Laya.Input['_createInputElement'] = MiniInput['_createInputElement']; + if (!window.ImageData) { + window.ImageData = ImageDataPolyfill; + } + Laya.Loader.prototype._loadResourceFilter = MiniLoader.prototype._loadResourceFilter; + Laya.Loader.prototype.originComplete = Laya.Loader.prototype.complete; + Laya.Loader.prototype.complete = MiniLoader.prototype.complete; + Laya.Loader.prototype._loadSound = MiniLoader.prototype._loadSound; + Laya.Loader.prototype._loadHttpRequestWhat = MiniLoader.prototype._loadHttpRequestWhat; + Laya.LocalStorage._baseClass = MiniLocalStorage; + MiniLocalStorage.__init__(); + Laya.Config.useRetinalCanvas = true; + QQMiniAdapter.window.qq.onMessage && QQMiniAdapter.window.qq.onMessage(QQMiniAdapter._onMessage); + } + static _onMessage(data) { + switch (data.type) { + case "changeMatrix": + Laya.Laya.stage.transform.identity(); + Laya.Laya.stage._width = data.w; + Laya.Laya.stage._height = data.h; + Laya.Laya.stage._canvasTransform = new Laya.Matrix(data.a, data.b, data.c, data.d, data.tx, data.ty); + break; + case "display": + Laya.Laya.stage.frameRate = data.rate || Laya.Stage.FRAME_FAST; + break; + case "undisplay": + Laya.Laya.stage.frameRate = Laya.Stage.FRAME_SLEEP; + break; + } + if (data['isLoad'] == "opendatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + else if (data['isLoad'] == "openJsondatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + } + } + else if (data['isLoad'] == "openJsondatacontextPic") { + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + static getUrlEncode(url, type) { + if (type == "arraybuffer") + return ""; + return "utf8"; + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + var fileObj = MiniFileMgr.getFileInfo(fileUrl); + if (!fileObj) + MiniFileMgr.downLoadFile(fileUrl, fileType, callBack, encoding); + else { + callBack != null && callBack.runWith([0]); + } + } + static remove(fileUrl, callBack = null) { + MiniFileMgr.deleteFile("", fileUrl, callBack, "", 0); + } + static removeAll() { + MiniFileMgr.deleteAll(); + } + static hasNativeFile(fileUrl) { + return MiniFileMgr.isLocalNativeFile(fileUrl); + } + static getFileInfo(fileUrl) { + return MiniFileMgr.getFileInfo(fileUrl); + } + static getFileList() { + return MiniFileMgr.filesListObj; + } + static exitMiniProgram() { + QQMiniAdapter.window["qq"].exitMiniProgram(); + } + static onMkdirCallBack(errorCode, data) { + if (!errorCode) { + MiniFileMgr.filesListObj = JSON.parse(data.data); + MiniFileMgr.fakeObj = JSON.parse(data.data); + } + else { + MiniFileMgr.fakeObj = {}; + MiniFileMgr.filesListObj = {}; + } + let files = MiniFileMgr.fs.readdirSync(MiniFileMgr.fileNativeDir); + if (!files.length) + return; + var tempMd5ListObj = {}; + var fileObj; + for (let key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") { + fileObj = MiniFileMgr.filesListObj[key]; + tempMd5ListObj[fileObj.md5] = fileObj.readyUrl; + } + } + var fileName; + for (let i = 0, sz = files.length; i < sz; i++) { + fileName = files[i]; + if (fileName == MiniFileMgr.fileListName) + continue; + if (!tempMd5ListObj[fileName]) { + let deleteFileUrl = MiniFileMgr.getFileNativePath(fileName); + MiniFileMgr.fs.unlink({ + filePath: deleteFileUrl, + success: function (data) { + console.log("删除无引用的磁盘文件:" + fileName); + } + }); + } + delete tempMd5ListObj[fileName]; + } + for (let key in tempMd5ListObj) { + delete MiniFileMgr.filesListObj[tempMd5ListObj[key]]; + delete MiniFileMgr.fakeObj[tempMd5ListObj[key]]; + console.log("删除错误记录:", tempMd5ListObj[key]); + } + } + static pixelRatio() { + if (!QQMiniAdapter.EnvConfig.pixelRatioInt) { + try { + QQMiniAdapter.EnvConfig.pixelRatioInt = QQMiniAdapter.systemInfo.pixelRatio; + return QQMiniAdapter.systemInfo.pixelRatio; + } + catch (error) { + } + } + return QQMiniAdapter.EnvConfig.pixelRatioInt; + } + static createElement(type) { + if (type == "canvas") { + var _source; + if (QQMiniAdapter.idx == 1) { + if (QQMiniAdapter.isZiYu) { + _source = QQMiniAdapter.window.sharedCanvas; + _source.style = {}; + } + else { + _source = QQMiniAdapter.window.canvas; + } + } + else { + _source = QQMiniAdapter.window.qq.createCanvas(); + } + QQMiniAdapter.idx++; + return _source; + } + else if (type == "textarea" || type == "input") { + return QQMiniAdapter.onCreateInput(type); + } + else if (type == "div") { + var node = QQMiniAdapter._preCreateElement(type); + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + else { + return QQMiniAdapter._preCreateElement(type); + } + } + static onCreateInput(type) { + var node = QQMiniAdapter._preCreateElement(type); + node.focus = MiniInput.wxinputFocus; + node.blur = MiniInput.wxinputblur; + node.style = {}; + node.value = 0; + node.parentElement = {}; + node.placeholder = {}; + node.type = {}; + node.setColor = function (value) { + }; + node.setType = function (value) { + }; + node.setFontFace = function (value) { + }; + node.addEventListener = function (value) { + }; + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + static createShaderCondition(conditionScript) { + var func = function () { + return this[conditionScript.replace("this.", "")]; + }; + return func; + } + static sendAtlasToOpenDataContext(url) { + if (!QQMiniAdapter.isZiYu) { + var atlasJson = Laya.Loader.getRes(Laya.URL.formatURL(url)); + if (atlasJson) { + var textureArr = atlasJson.meta.image.split(","); + if (atlasJson.meta && atlasJson.meta.image) { + var toloadPics = atlasJson.meta.image.split(","); + var split = url.indexOf("/") >= 0 ? "/" : "\\"; + var idx = url.lastIndexOf(split); + var folderPath = idx >= 0 ? url.substr(0, idx + 1) : ""; + for (var i = 0, len = toloadPics.length; i < len; i++) { + toloadPics[i] = folderPath + toloadPics[i]; + } + } + else { + toloadPics = [url.replace(".json", ".png")]; + } + for (i = 0; i < toloadPics.length; i++) { + var tempAtlasPngUrl = toloadPics[i]; + QQMiniAdapter.postInfoToContext(Laya.Laya.URL.formatURL(url), Laya.Laya.URL.formatURL(tempAtlasPngUrl), atlasJson); + } + } + else { + throw "传递的url没有获取到对应的图集数据信息,请确保图集已经过!"; + } + } + } + static postInfoToContext(url, atlaspngUrl, atlasJson) { + var postData = { "frames": atlasJson.frames, "meta": atlasJson.meta }; + var textureUrl = atlaspngUrl; + var fileObj = MiniFileMgr.getFileInfo(Laya.URL.formatURL(atlaspngUrl)); + if (fileObj) { + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = textureUrl; + } + if (fileNativeUrl) { + QQMiniAdapter.window.qq.postMessage({ url: url, atlasdata: postData, imgNativeUrl: fileNativeUrl, imgReadyUrl: textureUrl, isLoad: "opendatacontext" }); + } + else { + throw "获取图集的磁盘url路径不存在!"; + } + } + static sendSinglePicToOpenDataContext(url) { + var tempTextureUrl = Laya.URL.formatURL(url); + var fileObj = MiniFileMgr.getFileInfo(tempTextureUrl); + if (fileObj) { + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + url = tempTextureUrl; + } + else { + fileNativeUrl = url; + } + if (fileNativeUrl) { + url = Laya.Laya.URL.formatURL(url); + QQMiniAdapter.window.qq.postMessage({ url: url, imgNativeUrl: fileNativeUrl, imgReadyUrl: url, isLoad: "openJsondatacontextPic" }); + } + else { + throw "获取图集的磁盘url路径不存在!"; + } + } + static sendJsonDataToDataContext(url) { + if (!QQMiniAdapter.isZiYu) { + url = Laya.Laya.URL.formatURL(url); + var atlasJson = Laya.Loader.getRes(url); + if (atlasJson) { + QQMiniAdapter.window.qq.postMessage({ url: url, atlasdata: atlasJson, isLoad: "openJsondatacontext" }); + } + else { + throw "传递的url没有获取到对应的图集数据信息,请确保图集已经过!"; + } + } + } + } + QQMiniAdapter.IGNORE = new RegExp("[-_.!~*'();/?:@&=+$,#%]|[0-9|A-Z|a-z]"); + QQMiniAdapter.safeEncodeURI = function (str) { + var strTemp = ""; + var length = str.length; + for (var i = 0; i < length; i++) { + var word = str[i]; + if (QQMiniAdapter.IGNORE.test(word)) { + strTemp += word; + } + else { + try { + strTemp += encodeURI(word); + } + catch (e) { + console.log("errorInfo", ">>>" + word); + } + } + } + return strTemp; + }; + QQMiniAdapter._inited = false; + QQMiniAdapter.autoCacheFile = true; + QQMiniAdapter.minClearSize = (5 * 1024 * 1024); + QQMiniAdapter.sizeLimit = (50 * 1024 * 1024); + QQMiniAdapter.nativefiles = ["layaNativeDir", "wxlocal"]; + QQMiniAdapter.subNativeFiles = []; + QQMiniAdapter.subNativeheads = []; + QQMiniAdapter.subMaps = []; + QQMiniAdapter.AutoCacheDownFile = false; + QQMiniAdapter.parseXMLFromString = function (value) { + var rst; + value = value.replace(/>\s+<'); + try { + rst = (new QQMiniAdapter.window.Parser.DOMParser()).parseFromString(value, 'text/xml'); + } + catch (error) { + throw "需要引入xml解析库文件"; + } + return rst; + }; + QQMiniAdapter.idx = 1; + + class MiniAccelerator extends Laya.EventDispatcher { + constructor() { + super(); + } + static __init__() { + try { + var Acc; + Acc = Laya.Accelerator; + if (!Acc) + return; + Acc["prototype"]["on"] = MiniAccelerator["prototype"]["on"]; + Acc["prototype"]["off"] = MiniAccelerator["prototype"]["off"]; + } + catch (e) { + } + } + static startListen(callBack) { + MiniAccelerator._callBack = callBack; + if (MiniAccelerator._isListening) + return; + MiniAccelerator._isListening = true; + try { + QQMiniAdapter.window.qq.onAccelerometerChange(MiniAccelerator.onAccelerometerChange); + } + catch (e) { } + } + static stopListen() { + MiniAccelerator._isListening = false; + try { + QQMiniAdapter.window.qq.stopAccelerometer({}); + } + catch (e) { } + } + static onAccelerometerChange(res) { + var e; + e = {}; + e.acceleration = res; + e.accelerationIncludingGravity = res; + e.rotationRate = {}; + if (MiniAccelerator._callBack != null) { + MiniAccelerator._callBack(e); + } + } + on(type, caller, listener, args = null) { + super.on(type, caller, listener, args); + MiniAccelerator.startListen(this["onDeviceOrientationChange"]); + return this; + } + off(type, caller, listener, onceOnly = false) { + if (!this.hasListener(type)) + MiniAccelerator.stopListen(); + return super.off(type, caller, listener, onceOnly); + } + } + MiniAccelerator._isListening = false; + + class MiniImage { + _loadImage(url) { + var thisLoader = this; + if (QQMiniAdapter.isZiYu) { + MiniImage.onCreateImage(url, thisLoader, true); + return; + } + var isTransformUrl; + if (!MiniFileMgr.isLocalNativeFile(url)) { + isTransformUrl = true; + url = Laya.URL.formatURL(url); + } + else { + if (url.indexOf(QQMiniAdapter.window.qq.env.USER_DATA_PATH) == -1 && (url.indexOf("http://") != -1 || url.indexOf("https://") != -1)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (QQMiniAdapter.subNativeFiles && QQMiniAdapter.subNativeheads.length == 0) { + for (var key in QQMiniAdapter.subNativeFiles) { + var tempArr = QQMiniAdapter.subNativeFiles[key]; + QQMiniAdapter.subNativeheads = QQMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + QQMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (QQMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && QQMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = QQMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + } + if (!MiniFileMgr.getFileInfo(url)) { + if (url.indexOf(QQMiniAdapter.window.qq.env.USER_DATA_PATH) == -1 && (url.indexOf("http://") != -1 || url.indexOf("https://") != -1)) { + if (QQMiniAdapter.isZiYu) { + MiniImage.onCreateImage(url, thisLoader, true); + } + else { + MiniFileMgr.downOtherFiles(encodeURI(url), new Laya.Handler(MiniImage, MiniImage.onDownImgCallBack, [url, thisLoader]), url); + } + } + else + MiniImage.onCreateImage(url, thisLoader, true); + } + else { + MiniImage.onCreateImage(url, thisLoader, !isTransformUrl); + } + } + static onDownImgCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = "") { + if (!errorCode) + MiniImage.onCreateImage(sourceUrl, thisLoader, false, tempFilePath); + else { + thisLoader.onError(null); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (QQMiniAdapter.autoCacheFile) { + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + var fileMd5Name = fileObj.md5; + fileNativeUrl = MiniFileMgr.getFileNativePath(fileMd5Name); + } + } + else if (QQMiniAdapter.isZiYu) { + var tempUrl = Laya.URL.formatURL(sourceUrl); + if (MiniFileMgr.ziyuFileTextureData[tempUrl]) { + fileNativeUrl = MiniFileMgr.ziyuFileTextureData[tempUrl]; + } + else + fileNativeUrl = sourceUrl; + } + else + fileNativeUrl = sourceUrl; + } + else { + if (!isLocal) + fileNativeUrl = tempFilePath; + else + fileNativeUrl = sourceUrl; + } + if (thisLoader._imgCache == null) + thisLoader._imgCache = {}; + var image; + function clear() { + var img = thisLoader._imgCache[fileNativeUrl]; + if (img) { + img.onload = null; + img.onerror = null; + delete thisLoader._imgCache[fileNativeUrl]; + } + } + var onerror = function () { + clear(); + delete MiniFileMgr.fakeObj[sourceUrl]; + delete MiniFileMgr.filesListObj[sourceUrl]; + thisLoader.event(Laya.Event.ERROR, "Load image failed"); + }; + if (thisLoader._type == "nativeimage") { + var onload = function () { + clear(); + thisLoader.onLoaded(image); + }; + image = new Laya.Browser.window.Image(); + image.crossOrigin = ""; + image.onload = onload; + image.onerror = onerror; + image.src = fileNativeUrl; + thisLoader._imgCache[fileNativeUrl] = image; + } + else { + var imageSource = new Laya.Browser.window.Image(); + onload = function () { + image = Laya.HTMLImage.create(imageSource.width, imageSource.height); + image.loadImageSource(imageSource, true); + image._setCreateURL(fileNativeUrl); + clear(); + thisLoader.onLoaded(image); + }; + imageSource.crossOrigin = ""; + imageSource.onload = onload; + imageSource.onerror = onerror; + imageSource.src = fileNativeUrl; + thisLoader._imgCache[fileNativeUrl] = imageSource; + } + } + } + + class MiniLocation { + constructor() { + } + static __init__() { + QQMiniAdapter.window.navigator.geolocation.getCurrentPosition = MiniLocation.getCurrentPosition; + QQMiniAdapter.window.navigator.geolocation.watchPosition = MiniLocation.watchPosition; + QQMiniAdapter.window.navigator.geolocation.clearWatch = MiniLocation.clearWatch; + } + static getCurrentPosition(success = null, error = null, options = null) { + var paramO; + paramO = {}; + paramO.success = getSuccess; + paramO.fail = error; + QQMiniAdapter.window.qq.getLocation(paramO); + function getSuccess(res) { + if (success != null) { + success(res); + } + } + } + static watchPosition(success = null, error = null, options = null) { + MiniLocation._curID++; + var curWatchO; + curWatchO = {}; + curWatchO.success = success; + curWatchO.error = error; + MiniLocation._watchDic[MiniLocation._curID] = curWatchO; + Laya.Laya.systemTimer.loop(1000, null, MiniLocation._myLoop); + return MiniLocation._curID; + } + static clearWatch(id) { + delete MiniLocation._watchDic[id]; + if (!MiniLocation._hasWatch()) { + Laya.Laya.systemTimer.clear(null, MiniLocation._myLoop); + } + } + static _hasWatch() { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key]) + return true; + } + return false; + } + static _myLoop() { + MiniLocation.getCurrentPosition(MiniLocation._mySuccess, MiniLocation._myError); + } + static _mySuccess(res) { + var rst = {}; + rst.coords = res; + rst.timestamp = Laya.Browser.now(); + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].success) { + MiniLocation._watchDic[key].success(rst); + } + } + } + static _myError(res) { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].error) { + MiniLocation._watchDic[key].error(res); + } + } + } + } + MiniLocation._watchDic = {}; + MiniLocation._curID = 0; + + class MiniVideo { + constructor(width = 320, height = 240) { + this.videoend = false; + this.videourl = ""; + this.videoElement = QQMiniAdapter.window.qq.createVideo({ width: width, height: height, autoplay: true }); + } + static __init__() { + } + on(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.onPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.onEnded = this.onEndedFunction.bind(this); + } + this.videoElement.onTimeUpdate = this.onTimeUpdateFunc.bind(this); + } + onTimeUpdateFunc(data) { + this.position = data.position; + this._duration = data.duration; + } + get duration() { + return this._duration; + } + onPlayFunction() { + if (this.videoElement) + this.videoElement.readyState = 200; + console.log("=====视频加载完成========"); + this.onPlayFunc != null && this.onPlayFunc(); + } + onEndedFunction() { + if (!this.videoElement) + return; + this.videoend = true; + console.log("=====视频播放完毕========"); + this.onEndedFunC != null && this.onEndedFunC(); + } + off(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.offPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.offEnded = this.onEndedFunction.bind(this); + } + } + load(url) { + if (!this.videoElement) + return; + this.videoElement.src = url; + } + play() { + if (!this.videoElement) + return; + this.videoend = false; + this.videoElement.play(); + } + pause() { + if (!this.videoElement) + return; + this.videoend = true; + this.videoElement.pause(); + } + get currentTime() { + if (!this.videoElement) + return 0; + return this.videoElement.initialTime; + } + set currentTime(value) { + if (!this.videoElement) + return; + this.videoElement.initialTime = value; + } + get videoWidth() { + if (!this.videoElement) + return 0; + return this.videoElement.width; + } + get videoHeight() { + if (!this.videoElement) + return 0; + return this.videoElement.height; + } + get ended() { + return this.videoend; + } + get loop() { + if (!this.videoElement) + return false; + return this.videoElement.loop; + } + set loop(value) { + if (!this.videoElement) + return; + this.videoElement.loop = value; + } + get playbackRate() { + if (!this.videoElement) + return 0; + return this.videoElement.playbackRate; + } + set playbackRate(value) { + if (!this.videoElement) + return; + this.videoElement.playbackRate = value; + } + get muted() { + if (!this.videoElement) + return false; + return this.videoElement.muted; + } + set muted(value) { + if (!this.videoElement) + return; + this.videoElement.muted = value; + } + get paused() { + if (!this.videoElement) + return false; + return this.videoElement.paused; + } + size(width, height) { + if (!this.videoElement) + return; + this.videoElement.width = width; + this.videoElement.height = height; + } + get x() { + if (!this.videoElement) + return 0; + return this.videoElement.x; + } + set x(value) { + if (!this.videoElement) + return; + this.videoElement.x = value; + } + get y() { + if (!this.videoElement) + return 0; + return this.videoElement.y; + } + set y(value) { + if (!this.videoElement) + return; + this.videoElement.y = value; + } + get currentSrc() { + return this.videoElement.src; + } + destroy() { + if (this.videoElement) + this.videoElement.destroy(); + this.videoElement = null; + this.onEndedFunC = null; + this.onPlayFunc = null; + this.videoend = false; + this.videourl = null; + } + reload() { + if (!this.videoElement) + return; + this.videoElement.src = this.videourl; + } + } + + exports.ImageDataPolyfill = ImageDataPolyfill; + exports.MiniAccelerator = MiniAccelerator; + exports.MiniFileMgr = MiniFileMgr; + exports.MiniImage = MiniImage; + exports.MiniInput = MiniInput; + exports.MiniLoader = MiniLoader; + exports.MiniLocalStorage = MiniLocalStorage; + exports.MiniLocation = MiniLocation; + exports.MiniSound = MiniSound; + exports.MiniSoundChannel = MiniSoundChannel; + exports.MiniVideo = MiniVideo; + exports.QQMiniAdapter = QQMiniAdapter; + +} diff --git a/examples/layaair/frontend/bin/libs/laya.quickgamemini.js b/examples/layaair/frontend/bin/libs/laya.quickgamemini.js new file mode 100644 index 0000000..941ca70 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.quickgamemini.js @@ -0,0 +1,1821 @@ +window.qgMiniGame = function (exports, Laya) { + 'use strict'; + + function ImageDataPolyfill() { + let width, height, data; + if (arguments.length == 3) { + if (arguments[0] instanceof Uint8ClampedArray) { + if (arguments[0].length % 4 !== 0) { + throw new Error("Failed to construct 'ImageData': The input data length is not a multiple of 4."); + } + if (arguments[0].length !== arguments[1] * arguments[2] * 4) { + throw new Error("Failed to construct 'ImageData': The input data length is not equal to (4 * width * height)."); + } + else { + data = arguments[0]; + width = arguments[1]; + height = arguments[2]; + } + } + else { + throw new Error("Failed to construct 'ImageData': parameter 1 is not of type 'Uint8ClampedArray'."); + } + } + else if (arguments.length == 2) { + width = arguments[0]; + height = arguments[1]; + data = new Uint8ClampedArray(arguments[0] * arguments[1] * 4); + } + else if (arguments.length < 2) { + throw new Error("Failed to construct 'ImageData': 2 arguments required, but only " + arguments.length + " present."); + } + let imgdata = Laya.Browser.canvas.getContext("2d").getImageData(0, 0, width, height); + for (let i = 0; i < data.length; i += 4) { + imgdata.data[i] = data[i]; + imgdata.data[i + 1] = data[i + 1]; + imgdata.data[i + 2] = data[i + 2]; + imgdata.data[i + 3] = data[i + 3]; + } + return imgdata; + } + + class MiniFileMgr { + static isLocalNativeFile(url) { + for (var i = 0, sz = QGMiniAdapter.nativefiles.length; i < sz; i++) { + if (url.indexOf(QGMiniAdapter.nativefiles[i]) != -1) + return true; + } + return false; + } + static isNetFile(url) { + return (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) && url.indexOf(QGMiniAdapter.window.qg.env.USER_DATA_PATH) == -1; + } + static getFileInfo(fileUrl) { + var fileNativePath = fileUrl; + var fileObj = MiniFileMgr.fakeObj[fileNativePath]; + if (fileObj == null) + return null; + else + return fileObj; + } + static read(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "") { + var fileUrl; + if (readyUrl != "" && (readyUrl.indexOf("http://") != -1 || readyUrl.indexOf("https://") != -1)) { + fileUrl = MiniFileMgr.getFileNativePath(filePath); + } + else { + fileUrl = filePath; + } + fileUrl = Laya.URL.getAdptedFilePath(fileUrl); + MiniFileMgr.fs.readFile({ filePath: fileUrl, encoding: encoding, success: function (data) { + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data && readyUrl != "") + MiniFileMgr.downFiles(encodeURI(readyUrl), encoding, callBack, readyUrl, isSaveFile, fileType); + else + callBack != null && callBack.runWith([1]); + } }); + } + static isFile(url) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(url); + } + catch (err) { + return false; + } + return stat.isFile(); + } + static downFiles(fileUrl, encoding = "ascii", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + var downloadTask = MiniFileMgr.wxdown({ url: fileUrl, success: function (data) { + if (data.statusCode === 200) + MiniFileMgr.readFile(data.tempFilePath, encoding, callBack, readyUrl, isSaveFile, fileType, isAutoClear); + else if (data.statusCode === 403) { + callBack != null && callBack.runWith([0, fileUrl]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + downloadTask.onProgressUpdate(function (data) { + callBack != null && callBack.runWith([2, data.progress]); + }); + } + static readFile(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + filePath = Laya.URL.getAdptedFilePath(filePath); + MiniFileMgr.fs.readFile({ filePath: filePath, encoding: encoding, success: function (data) { + if (filePath.indexOf(QGMiniAdapter.window.qg.env.USER_DATA_PATH) == -1 && (filePath.indexOf("http://") != -1 || filePath.indexOf("https://") != -1)) { + if (QGMiniAdapter.autoCacheFile || isSaveFile) { + callBack != null && callBack.runWith([0, data]); + MiniFileMgr.copyTOCache(filePath, readyUrl, null, encoding, isAutoClear); + } + else + callBack != null && callBack.runWith([0, data]); + } + else + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data) + callBack != null && callBack.runWith([1, data]); + } }); + } + static downOtherFiles(fileUrl, callBack = null, readyUrl = "", isSaveFile = false, isAutoClear = true) { + MiniFileMgr.wxdown({ url: fileUrl, success: function (data) { + if (data.statusCode === 200) { + if ((QGMiniAdapter.autoCacheFile || isSaveFile) && readyUrl.indexOf("qlogo.cn") == -1 && readyUrl.indexOf(".php") == -1) { + callBack != null && callBack.runWith([0, data.tempFilePath]); + MiniFileMgr.copyTOCache(data.tempFilePath, readyUrl, null, "", isAutoClear); + } + else + callBack != null && callBack.runWith([0, data.tempFilePath]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static copyFile(src, dest, complete = null) { + MiniFileMgr.fs.copyFile({ + srcPath: src, + destPath: dest, + success: function () { + complete && complete.runWith(0); + }, + fail: function (err) { + complete && complete.runWith([1, err]); + } + }); + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "ascii") { + if (QGMiniAdapter.window.navigator.userAgent.indexOf('MiniGame') < 0 && QGMiniAdapter.window.navigator.userAgent.indexOf('OPPO') < 0) { + Laya.Laya.loader.load(fileUrl, callBack); + } + else { + if (fileType == Laya.Loader.IMAGE || fileType == Laya.Loader.SOUND) + MiniFileMgr.downOtherFiles(encodeURI(fileUrl), callBack, fileUrl, true, false); + else + MiniFileMgr.downFiles(encodeURI(fileUrl), encoding, callBack, fileUrl, true, fileType, false); + } + } + static copyTOCache(tempFilePath, readyUrl, callBack, encoding = "", isAutoClear = true) { + var temp = tempFilePath.split("/"); + var tempFileName = temp[temp.length - 1]; + var fileurlkey = readyUrl; + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fakeObj[fileurlkey] = { md5: tempFileName, readyUrl: readyUrl, size: 0, times: Laya.Browser.now(), encoding: encoding, tempFilePath: tempFilePath }; + var totalSize = QGMiniAdapter.sizeLimit; + var chaSize = 4 * 1024 * 1024; + var fileUseSize = MiniFileMgr.getCacheUseSize(); + if (fileObj) { + if (fileObj.readyUrl != readyUrl) { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > QGMiniAdapter.minClearSize) + QGMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.deleteFile(tempFilePath, readyUrl, callBack, encoding, data.size); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + else + callBack != null && callBack.runWith([0]); + } + else { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > QGMiniAdapter.minClearSize) + QGMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.fs.copyFile({ srcPath: tempFilePath, destPath: saveFilePath, success: function (data2) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, data.size); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + } + static onClearCacheRes() { + var memSize = QGMiniAdapter.minClearSize; + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + MiniFileMgr.sortOn(tempFileListArr, "times", MiniFileMgr.NUMERIC); + var clearSize = 0; + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + if (clearSize >= memSize) + break; + clearSize += fileObj.size; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + } + static sortOn(array, name, options = 0) { + if (options == MiniFileMgr.NUMERIC) + return array.sort(function (a, b) { return a[name] - b[name]; }); + if (options == (MiniFileMgr.NUMERIC | MiniFileMgr.DESCENDING)) + return array.sort(function (a, b) { return b[name] - a[name]; }); + return array.sort(function (a, b) { return a[name] - b[name]; }); + } + static getFileNativePath(fileName) { + return MiniFileMgr.fileNativeDir + "/" + fileName; + } + static deleteFile(tempFileName, readyUrl = "", callBack = null, encoding = "", fileSize = 0) { + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var deleteFileUrl = MiniFileMgr.getFileNativePath(fileObj.md5); + MiniFileMgr.fs.unlink({ filePath: deleteFileUrl, success: function (data) { + if (tempFileName != "") { + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fs.copyFile({ srcPath: tempFileName, destPath: saveFilePath, success: function (data) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, fileSize); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + else { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, false, encoding, callBack, fileSize); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static deleteAll() { + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj.fileUsedSize) { + MiniFileMgr.filesListObj.fileUsedSize = 0; + } + MiniFileMgr.writeFilesList("", JSON.stringify({}), false); + } + static onSaveFile(readyUrl, md5Name, isAdd = true, encoding = "", callBack = null, fileSize = 0) { + var fileurlkey = readyUrl; + if (MiniFileMgr.filesListObj['fileUsedSize'] == null) + MiniFileMgr.filesListObj['fileUsedSize'] = 0; + if (isAdd) { + var fileNativeName = MiniFileMgr.getFileNativePath(md5Name); + MiniFileMgr.filesListObj[fileurlkey] = { md5: md5Name, readyUrl: readyUrl, size: fileSize, times: Laya.Browser.now(), encoding: encoding, tempFilePath: fileNativeName }; + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) + fileSize; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), true); + callBack != null && callBack.runWith([0]); + } + else { + if (MiniFileMgr.filesListObj[fileurlkey]) { + var deletefileSize = parseInt(MiniFileMgr.filesListObj[fileurlkey].size); + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) - deletefileSize; + if (MiniFileMgr.fakeObj[fileurlkey].md5 == MiniFileMgr.filesListObj[fileurlkey].md5) { + delete MiniFileMgr.fakeObj[fileurlkey]; + } + delete MiniFileMgr.filesListObj[fileurlkey]; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), false); + callBack != null && callBack.runWith([0]); + } + } + } + static writeFilesList(fileurlkey, filesListStr, isAdd) { + var listFilesPath = MiniFileMgr.fileNativeDir + "/" + MiniFileMgr.fileListName; + MiniFileMgr.fs.writeFile({ filePath: listFilesPath, encoding: 'utf8', data: filesListStr, success: function (data) { + }, fail: function (data) { + } }); + if (!QGMiniAdapter.isZiYu && QGMiniAdapter.isPosMsgYu && QGMiniAdapter.window.qg.postMessage) { + QGMiniAdapter.window.qg.postMessage && QGMiniAdapter.window.qg.postMessage({ url: fileurlkey, data: MiniFileMgr.filesListObj[fileurlkey], isLoad: "filenative", isAdd: isAdd }); + } + } + static getCacheUseSize() { + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj['fileUsedSize']) + return MiniFileMgr.filesListObj['fileUsedSize']; + return 0; + } + static getCacheList(dirPath, cb) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(dirPath); + } + catch (err) { + stat = null; + } + if (stat) { + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", cb); + } + else { + MiniFileMgr.fs.mkdirSync(dirPath, true); + cb && cb.runWith([1]); + } + } + static existDir(dirPath, callBack) { + MiniFileMgr.fs.mkdir({ dirPath: dirPath, success: function (data) { + callBack != null && callBack.runWith([0, { data: JSON.stringify({}) }]); + }, fail: function (data) { + if (data.errMsg.indexOf("file already exists") != -1) + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", callBack); + else + callBack != null && callBack.runWith([1, data]); + } }); + } + static readSync(filePath, encoding = "utf8", callBack = null, readyUrl = "") { + var fileUrl = MiniFileMgr.getFileNativePath(filePath); + var filesListStr; + try { + filesListStr = MiniFileMgr.fs.readFileSync(fileUrl, encoding); + callBack != null && callBack.runWith([0, { data: filesListStr }]); + } + catch (error) { + callBack != null && callBack.runWith([1]); + } + } + static setNativeFileDir(value) { + MiniFileMgr.fileNativeDir = QGMiniAdapter.window.qg.env.USER_DATA_PATH + value; + } + } + MiniFileMgr.fs = window.qg.getFileSystemManager(); + MiniFileMgr.wxdown = window.qg.downloadFile; + MiniFileMgr.filesListObj = {}; + MiniFileMgr.fakeObj = {}; + MiniFileMgr.fileListName = "layaairfiles.txt"; + MiniFileMgr.ziyuFileData = {}; + MiniFileMgr.ziyuFileTextureData = {}; + MiniFileMgr.loadPath = ""; + MiniFileMgr.DESCENDING = 2; + MiniFileMgr.NUMERIC = 16; + + class MiniSoundChannel extends Laya.SoundChannel { + constructor(audio, miniSound) { + super(); + this._audio = audio; + this._miniSound = miniSound; + this._onEnd = MiniSoundChannel.bindToThis(this.__onEnd, this); + audio.onEnded(this._onEnd); + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + __onEnd() { + if (this.loops == 1) { + if (this.completeHandler) { + Laya.Laya.systemTimer.once(10, this, this.__runComplete, [this.completeHandler], false); + this.completeHandler = null; + } + this.stop(); + this.event(Laya.Event.COMPLETE); + return; + } + if (this.loops > 0) { + this.loops--; + } + this.startTime = 0; + this.play(); + } + play() { + this.isStopped = false; + Laya.SoundManager.addChannel(this); + this._audio.play(); + } + set startTime(time) { + if (this._audio) { + this._audio.startTime = time; + } + } + set autoplay(value) { + this._audio.autoplay = value; + } + get autoplay() { + return this._audio.autoplay; + } + get position() { + if (!this._audio) + return 0; + return this._audio.currentTime; + } + get duration() { + if (!this._audio) + return 0; + return this._audio.duration; + } + stop() { + this.isStopped = true; + Laya.SoundManager.removeChannel(this); + this.completeHandler = null; + if (!this._audio) + return; + this._audio.stop(); + if (!this.loop) { + this._audio.offEnded(null); + this._miniSound.dispose(); + this._audio = null; + this._miniSound = null; + this._onEnd = null; + } + } + pause() { + this.isStopped = true; + this._audio.pause(); + } + get loop() { + return this._audio.loop; + } + set loop(value) { + this._audio.loop = value; + } + resume() { + if (!this._audio) + return; + this.isStopped = false; + Laya.SoundManager.addChannel(this); + this._audio.play(); + } + set volume(v) { + if (!this._audio) + return; + this._audio.volume = v; + } + get volume() { + if (!this._audio) + return 1; + return this._audio.volume; + } + } + + class MiniSound extends Laya.EventDispatcher { + constructor() { + super(); + this.loaded = false; + } + static _createSound() { + MiniSound._id++; + return QGMiniAdapter.window.qg.createInnerAudioContext(); + } + load(url) { + if (!MiniSound._musicAudio) + MiniSound._musicAudio = MiniSound._createSound(); + if (!MiniFileMgr.isLocalNativeFile(url)) { + url = Laya.URL.formatURL(url); + } + else { + if (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + if (tempStr != "") + url = url.split(tempStr)[1]; + } + } + } + this.url = url; + this.readyUrl = url; + if (MiniSound._audioCache[this.readyUrl]) { + this.event(Laya.Event.COMPLETE); + return; + } + if (QGMiniAdapter.autoCacheFile && MiniFileMgr.getFileInfo(url)) { + this.onDownLoadCallBack(url, 0); + } + else { + if (!QGMiniAdapter.autoCacheFile) { + this.onDownLoadCallBack(url, 0); + } + else { + if (MiniFileMgr.isLocalNativeFile(url)) { + tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + if (QGMiniAdapter.subNativeFiles && QGMiniAdapter.subNativeheads.length == 0) { + for (var key in QGMiniAdapter.subNativeFiles) { + var tempArr = QGMiniAdapter.subNativeFiles[key]; + QGMiniAdapter.subNativeheads = QGMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + QGMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (QGMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && QGMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = QGMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + this.onDownLoadCallBack(url, 0); + } + else { + if (!MiniFileMgr.isLocalNativeFile(url) && (url.indexOf("http://") == -1 && url.indexOf("https://") == -1) || (url.indexOf("http://usr/") != -1)) { + this.onDownLoadCallBack(url, 0); + } + else { + MiniFileMgr.downOtherFiles(encodeURI(url), Laya.Handler.create(this, this.onDownLoadCallBack, [url]), url); + } + } + } + } + } + onDownLoadCallBack(sourceUrl, errorCode, tempFilePath = null) { + if (!errorCode) { + var fileNativeUrl; + if (QGMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = sourceUrl; + if (tempStr != "" && (sourceUrl.indexOf("http://") != -1 || sourceUrl.indexOf("https://") != -1)) + fileNativeUrl = sourceUrl.split(tempStr)[1]; + if (!fileNativeUrl) { + fileNativeUrl = tempUrl; + } + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + if (this.url != Laya.SoundManager._bgMusic) { + this._sound = MiniSound._createSound(); + this._sound.src = this.url = fileNativeUrl; + } + else { + this._sound = MiniSound._musicAudio; + this._sound.src = this.url = fileNativeUrl; + } + } + else { + if (this.url != Laya.SoundManager._bgMusic) { + this._sound = MiniSound._createSound(); + this._sound.src = sourceUrl; + } + else { + this._sound = MiniSound._musicAudio; + this._sound.src = sourceUrl; + } + } + this._sound.onCanplay(MiniSound.bindToThis(this.onCanPlay, this)); + this._sound.onError(MiniSound.bindToThis(this.onError, this)); + } + else { + this.event(Laya.Event.ERROR); + } + } + onError(error) { + try { + console.log("-----1---------------minisound-----id:" + MiniSound._id); + console.log(error); + } + catch (error) { + console.log("-----2---------------minisound-----id:" + MiniSound._id); + console.log(error); + } + this.event(Laya.Event.ERROR); + this._sound.offError(null); + } + onCanPlay() { + this.loaded = true; + this.event(Laya.Event.COMPLETE); + this._sound.offCanplay(null); + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + play(startTime = 0, loops = 0) { + var tSound; + if (this.url == Laya.SoundManager._bgMusic) { + if (!MiniSound._musicAudio) + MiniSound._musicAudio = MiniSound._createSound(); + tSound = MiniSound._musicAudio; + } + else { + if (MiniSound._audioCache[this.readyUrl]) { + tSound = MiniSound._audioCache[this.readyUrl]._sound; + } + else { + tSound = MiniSound._createSound(); + } + } + if (!tSound) + return null; + if (QGMiniAdapter.autoCacheFile && MiniFileMgr.getFileInfo(this.url)) { + var fileObj = MiniFileMgr.getFileInfo(this.url); + var fileMd5Name = fileObj.md5; + tSound.src = this.url = MiniFileMgr.getFileNativePath(fileMd5Name); + } + else { + tSound.src = encodeURI(this.url); + } + var channel = new MiniSoundChannel(tSound, this); + channel.url = this.url; + channel.loops = loops; + channel.loop = (loops === 0 ? true : false); + channel.startTime = startTime; + channel.play(); + Laya.SoundManager.addChannel(channel); + return channel; + } + get duration() { + return this._sound.duration; + } + dispose() { + var ad = MiniSound._audioCache[this.readyUrl]; + if (ad) { + ad.src = ""; + if (ad._sound) { + ad._sound.destroy(); + ad._sound = null; + ad = null; + } + delete MiniSound._audioCache[this.readyUrl]; + } + if (this._sound) { + this._sound.destroy(); + this._sound = null; + this.readyUrl = this.url = null; + } + } + } + MiniSound._id = 0; + MiniSound._audioCache = {}; + + class MiniInput { + constructor() { + } + static _createInputElement() { + Laya.Input['_initInput'](Laya.Input['area'] = Laya.Browser.createElement("textarea")); + Laya.Input['_initInput'](Laya.Input['input'] = Laya.Browser.createElement("input")); + Laya.Input['inputContainer'] = Laya.Browser.createElement("div"); + Laya.Input['inputContainer'].style.position = "absolute"; + Laya.Input['inputContainer'].style.zIndex = 1E5; + Laya.Browser.container.appendChild(Laya.Input['inputContainer']); + Laya.Laya.stage.on("resize", null, MiniInput._onStageResize); + QGMiniAdapter.window.qg.onWindowResize && QGMiniAdapter.window.qg.onWindowResize(function (res) { + }); + Laya.SoundManager._soundClass = MiniSound; + Laya.SoundManager._musicClass = MiniSound; + var model = QGMiniAdapter.systemInfo.model; + var system = QGMiniAdapter.systemInfo.system; + if (model && model.indexOf("iPhone") != -1) { + Laya.Browser.onIPhone = true; + Laya.Browser.onIOS = true; + Laya.Browser.onIPad = true; + Laya.Browser.onAndroid = false; + } + if (system && (system.indexOf("Android") != -1 || system.indexOf("Adr") != -1)) { + Laya.Browser.onAndroid = true; + Laya.Browser.onIPhone = false; + Laya.Browser.onIOS = false; + Laya.Browser.onIPad = false; + } + } + static _onStageResize() { + } + static wxinputFocus(e) { + var _inputTarget = Laya.Input['inputElement'].target; + if (_inputTarget && !_inputTarget.editable) { + return; + } + QGMiniAdapter.window.qg.showKeyboard({ defaultValue: _inputTarget.text, maxLength: _inputTarget.maxChars, multiple: _inputTarget.multiline, confirmHold: true, confirmType: _inputTarget["confirmType"] || 'done', success: function (res) { + }, fail: function (res) { + } }); + QGMiniAdapter.window.qg.onKeyboardComplete(function (res) { + QGMiniAdapter.window.qg.offKeyboardComplete(); + var str = res ? res.value : ""; + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + MiniInput.inputEnter(true); + }); + QGMiniAdapter.window.qg.onKeyboardConfirm(function (res) { + var str = res ? res.value : ""; + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + MiniInput.inputEnter(true); + _inputTarget.event("confirm"); + }); + QGMiniAdapter.window.qg.onKeyboardInput(function (res) { + var str = res ? res.value : ""; + if (!_inputTarget.multiline) { + if (str.indexOf("\n") != -1) { + MiniInput.inputEnter(false); + return; + } + } + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + MiniInput.inputEnter(false); + }); + } + static inputEnter(isBool) { + if (isBool) { + MiniInput.hideKeyboard(); + } + if (!Laya.Input['inputElement'].target) + return; + Laya.Input['inputElement'].target.focus = false; + } + static wxinputblur() { + } + static hideKeyboard() { + QGMiniAdapter.window.qg.offKeyboardConfirm(); + QGMiniAdapter.window.qg.offKeyboardInput(); + QGMiniAdapter.window.qg.hideKeyboard({ success: function (res) { + console.log('隐藏键盘'); + }, fail: function (res) { + console.log("隐藏键盘出错:" + (res ? res.errMsg : "")); + } }); + } + } + + class MiniLoader extends Laya.EventDispatcher { + constructor() { + super(); + } + _loadResourceFilter(type, url) { + var thisLoader = this; + this.sourceUrl = Laya.URL.formatURL(url); + if (MiniFileMgr.isNetFile(url)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (QGMiniAdapter.subNativeFiles && QGMiniAdapter.subNativeheads.length == 0) { + for (var key in QGMiniAdapter.subNativeFiles) { + var tempArr = QGMiniAdapter.subNativeFiles[key]; + QGMiniAdapter.subNativeheads = QGMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + QGMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (QGMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && QGMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = QGMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + switch (type) { + case Laya.Loader.IMAGE: + case "htmlimage": + case "nativeimage": + MiniLoader._transformImgUrl(url, type, thisLoader); + break; + case Laya.Loader.SOUND: + thisLoader._loadSound(url); + break; + default: + thisLoader._loadResource(type, url); + } + } + _loadSound(url) { + var thisLoader = this; + if (!QGMiniAdapter.autoCacheFile) { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + else { + var tempurl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downOtherFiles(QGMiniAdapter.safeEncodeURI(tempurl), Laya.Handler.create(MiniLoader, MiniLoader.onDownLoadCallBack, [tempurl, thisLoader]), tempurl); + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + } + static onDownLoadCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = null) { + if (!errorCode) { + var fileNativeUrl; + if (QGMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + fileNativeUrl = sourceUrl; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + } + else { + fileNativeUrl = Laya.URL.formatURL(sourceUrl); + } + sourceUrl = fileNativeUrl; + var sound = (new Laya.SoundManager._soundClass()); + sound.load(QGMiniAdapter.safeEncodeURI(sourceUrl)); + thisLoader.onLoaded(sound); + } + else { + thisLoader.event(Laya.Event.ERROR, "Load sound failed"); + } + } + complete(data) { + if (data instanceof Laya.Resource) { + data._setCreateURL(this.sourceUrl); + } + else if ((data instanceof Laya.Texture) && (data.bitmap instanceof Laya.Resource)) { + data.bitmap._setCreateURL(this.sourceUrl); + } + this.originComplete(data); + } + _loadHttpRequestWhat(url, contentType) { + var thisLoader = this; + var encoding = QGMiniAdapter.getUrlEncode(url, contentType); + if (Laya.Loader.preLoadedMap[url]) + thisLoader.onLoaded(Laya.Loader.preLoadedMap[url]); + else { + var tempurl = Laya.URL.formatURL(url); + if (!QGMiniAdapter.AutoCacheDownFile) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downFiles(QGMiniAdapter.safeEncodeURI(tempurl), encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), tempurl, false); + } + else + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + else { + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downFiles(QGMiniAdapter.safeEncodeURI(tempurl), encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), tempurl, true); + } + else { + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + else { + var tempUrl = url; + var fileObj = MiniFileMgr.getFileInfo(tempurl); + if (fileObj && fileObj.md5) { + tempUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + MiniFileMgr.readFile(tempUrl, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + } + } + static onReadNativeCallBack(url, type = null, thisLoader = null, errorCode = 0, data = null) { + if (!errorCode) { + var tempData; + if (type == Laya.Loader.JSON || type == Laya.Loader.ATLAS || type == Laya.Loader.PREFAB || type == Laya.Loader.PLF) { + tempData = QGMiniAdapter.getJson(data.data); + } + else if (type == Laya.Loader.XML) { + tempData = Laya.Utils.parseXMLFromString(data.data); + } + else { + tempData = data.data; + } + if (!QGMiniAdapter.isZiYu && QGMiniAdapter.isPosMsgYu && type != Laya.Loader.BUFFER) { + QGMiniAdapter.window.qg.postMessage({ url: url, data: tempData, isLoad: "filedata" }); + } + thisLoader.onLoaded(tempData); + } + else if (errorCode == 1) { + thisLoader.onError && thisLoader.onError(data); + } + } + static _transformImgUrl(url, type, thisLoader) { + if (QGMiniAdapter.isZiYu || MiniFileMgr.isLocalNativeFile(url)) { + thisLoader._loadImage(url, false); + return; + } + if (!QGMiniAdapter.autoCacheFile) { + thisLoader._loadImage(QGMiniAdapter.safeEncodeURI(url)); + } + else { + var tempUrl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempUrl)) { + if (MiniFileMgr.isNetFile(tempUrl)) { + MiniFileMgr.downOtherFiles(QGMiniAdapter.safeEncodeURI(tempUrl), new Laya.Handler(MiniLoader, MiniLoader.onDownImgCallBack, [url, thisLoader]), tempUrl); + } + else { + MiniLoader.onCreateImage(url, thisLoader, true); + } + } + else { + MiniLoader.onCreateImage(url, thisLoader); + } + } + } + static onDownImgCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = "") { + if (!errorCode) + MiniLoader.onCreateImage(sourceUrl, thisLoader, false, tempFilePath); + else { + thisLoader.onError(null); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (QGMiniAdapter.autoCacheFile) { + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + var fileObj = MiniFileMgr.getFileInfo(Laya.URL.formatURL(sourceUrl)); + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + } + else if (QGMiniAdapter.isZiYu) { + var tempUrl = Laya.URL.formatURL(sourceUrl); + if (MiniFileMgr.ziyuFileTextureData[tempUrl]) { + fileNativeUrl = MiniFileMgr.ziyuFileTextureData[tempUrl]; + } + else + fileNativeUrl = sourceUrl; + } + else + fileNativeUrl = sourceUrl; + } + else { + if (!isLocal) + fileNativeUrl = tempFilePath; + else + fileNativeUrl = sourceUrl; + } + thisLoader._loadImage(fileNativeUrl, false); + } + } + + class QGMiniAdapter { + static getJson(data) { + return JSON.parse(data); + } + static enable() { + QGMiniAdapter.init(Laya.Laya.isWXPosMsg, Laya.Laya.isWXOpenDataContext); + } + static init(isPosMsg = false, isSon = false) { + if (QGMiniAdapter._inited) + return; + QGMiniAdapter._inited = true; + QGMiniAdapter.window = window; + if (!QGMiniAdapter.window.hasOwnProperty('qg')) + return; + if (QGMiniAdapter.window.navigator.userAgent.indexOf('OPPO') < 0) + return; + QGMiniAdapter.isZiYu = isSon; + QGMiniAdapter.isPosMsgYu = isPosMsg; + QGMiniAdapter.EnvConfig = {}; + if (!QGMiniAdapter.isZiYu) { + MiniFileMgr.setNativeFileDir("/layaairGame"); + MiniFileMgr.getCacheList(MiniFileMgr.fileNativeDir, Laya.Handler.create(QGMiniAdapter, QGMiniAdapter.onMkdirCallBack)); + } + QGMiniAdapter.window.qg.getSystemInfo({ + success: function (data) { + QGMiniAdapter.systemInfo = data; + } + }); + QGMiniAdapter.window.focus = function () { + }; + Laya.Laya['_getUrlPath'] = function () { + return ""; + }; + Laya.Laya['getUrlPath'] = function () { + return ""; + }; + QGMiniAdapter.window.logtime = function (str) { + }; + QGMiniAdapter.window.alertTimeLog = function (str) { + }; + QGMiniAdapter.window.resetShareInfo = function () { + }; + QGMiniAdapter.window.document.body.appendChild = function () { + }; + Laya.HttpRequest._urlEncode = QGMiniAdapter.safeEncodeURI; + QGMiniAdapter.EnvConfig.pixelRatioInt = 0; + Laya.Browser["_pixelRatio"] = QGMiniAdapter.pixelRatio(); + QGMiniAdapter._preCreateElement = Laya.Browser.createElement; + Laya.Browser["createElement"] = QGMiniAdapter.createElement; + Laya.RunDriver.createShaderCondition = QGMiniAdapter.createShaderCondition; + Laya.Utils['parseXMLFromString'] = QGMiniAdapter.parseXMLFromString; + Laya.Input['_createInputElement'] = MiniInput['_createInputElement']; + if (!window.ImageData) { + window.ImageData = ImageDataPolyfill; + } + Laya.Loader.prototype._loadResourceFilter = MiniLoader.prototype._loadResourceFilter; + Laya.Loader.prototype._loadSound = MiniLoader.prototype._loadSound; + Laya.Loader.prototype.originComplete = Laya.Loader.prototype.complete; + Laya.Loader.prototype.complete = MiniLoader.prototype.complete; + Laya.Loader.prototype._loadHttpRequestWhat = MiniLoader.prototype._loadHttpRequestWhat; + Laya.Config.useRetinalCanvas = true; + QGMiniAdapter.window.qg.onMessage && QGMiniAdapter.window.qg.onMessage(QGMiniAdapter._onMessage); + } + static _onMessage(data) { + switch (data.type) { + case "changeMatrix": + Laya.Laya.stage.transform.identity(); + Laya.Laya.stage._width = data.w; + Laya.Laya.stage._height = data.h; + Laya.Laya.stage._canvasTransform = new Laya.Matrix(data.a, data.b, data.c, data.d, data.tx, data.ty); + break; + case "display": + Laya.Laya.stage.frameRate = data.rate || Laya.Stage.FRAME_FAST; + break; + case "undisplay": + Laya.Laya.stage.frameRate = Laya.Stage.FRAME_SLEEP; + break; + } + if (data['isLoad'] == "opendatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + else if (data['isLoad'] == "openJsondatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + } + } + else if (data['isLoad'] == "openJsondatacontextPic") { + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + static getUrlEncode(url, type) { + if (type == "arraybuffer") + return ""; + return "utf8"; + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + var fileObj = MiniFileMgr.getFileInfo(fileUrl); + if (!fileObj) + MiniFileMgr.downLoadFile(fileUrl, fileType, callBack, encoding); + else { + callBack != null && callBack.runWith([0]); + } + } + static remove(fileUrl, callBack = null) { + MiniFileMgr.deleteFile("", fileUrl, callBack, "", 0); + } + static removeAll() { + MiniFileMgr.deleteAll(); + } + static hasNativeFile(fileUrl) { + return MiniFileMgr.isLocalNativeFile(fileUrl); + } + static getFileInfo(fileUrl) { + return MiniFileMgr.getFileInfo(fileUrl); + } + static getFileList() { + return MiniFileMgr.filesListObj; + } + static exitMiniProgram() { + QGMiniAdapter.window["wx"].exitMiniProgram(); + } + static onMkdirCallBack(errorCode, data) { + if (!errorCode) { + MiniFileMgr.filesListObj = JSON.parse(data.data) || {}; + MiniFileMgr.fakeObj = JSON.parse(data.data) || {}; + } + else { + MiniFileMgr.fakeObj = {}; + MiniFileMgr.filesListObj = {}; + } + let files = MiniFileMgr.fs.readdirSync(MiniFileMgr.fileNativeDir); + if (!files || !files.length) + return; + var tempMd5ListObj = {}; + var fileObj; + for (let key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") { + fileObj = MiniFileMgr.filesListObj[key]; + tempMd5ListObj[fileObj.md5] = fileObj.readyUrl; + } + } + var fileName; + for (let i = 0, sz = files.length; i < sz; i++) { + fileName = files[i]; + if (fileName == MiniFileMgr.fileListName) + continue; + if (!tempMd5ListObj[fileName]) { + let deleteFileUrl = MiniFileMgr.getFileNativePath(fileName); + MiniFileMgr.fs.unlink({ + filePath: deleteFileUrl, + success: function (data) { + console.log("删除无引用的磁盘文件:" + fileName); + } + }); + } + delete tempMd5ListObj[fileName]; + } + for (let key in tempMd5ListObj) { + delete MiniFileMgr.filesListObj[tempMd5ListObj[key]]; + delete MiniFileMgr.fakeObj[tempMd5ListObj[key]]; + console.log("删除错误记录:", tempMd5ListObj[key]); + } + } + static pixelRatio() { + if (!QGMiniAdapter.EnvConfig.pixelRatioInt) { + try { + QGMiniAdapter.systemInfo.pixelRatio = QGMiniAdapter.window.devicePixelRatio; + QGMiniAdapter.EnvConfig.pixelRatioInt = QGMiniAdapter.systemInfo.pixelRatio; + return QGMiniAdapter.systemInfo.pixelRatio; + } + catch (error) { + } + } + return QGMiniAdapter.EnvConfig.pixelRatioInt; + } + static createElement(type) { + if (type == "canvas") { + var _source; + if (QGMiniAdapter.idx == 1) { + if (QGMiniAdapter.isZiYu) { + _source = QGMiniAdapter.window.document.createElement("canvas"); + _source.style = {}; + } + else { + _source = QGMiniAdapter.window.__canvas; + } + } + else { + _source = QGMiniAdapter.window.document.createElement("canvas"); + } + QGMiniAdapter.idx++; + return _source; + } + else if (type == "textarea" || type == "input") { + return QGMiniAdapter.onCreateInput(type); + } + else if (type == "div") { + var node = QGMiniAdapter._preCreateElement(type); + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + else { + return QGMiniAdapter._preCreateElement(type); + } + } + static onCreateInput(type) { + var node = QGMiniAdapter._preCreateElement(type); + node.focus = MiniInput.wxinputFocus; + node.blur = MiniInput.wxinputblur; + node.style = {}; + node.value = 0; + node.parentElement = {}; + node.placeholder = {}; + node.type = {}; + node.setColor = function (value) { + }; + node.setType = function (value) { + }; + node.setFontFace = function (value) { + }; + node.addEventListener = function (value) { + }; + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + static createShaderCondition(conditionScript) { + var func = function () { + return this[conditionScript.replace("this.", "")]; + }; + return func; + } + static sendAtlasToOpenDataContext(url) { + if (!QGMiniAdapter.isZiYu) { + var atlasJson = Laya.Loader.getRes(Laya.URL.formatURL(url)); + if (atlasJson) { + var textureArr = atlasJson.meta.image.split(","); + if (atlasJson.meta && atlasJson.meta.image) { + var toloadPics = atlasJson.meta.image.split(","); + var split = url.indexOf("/") >= 0 ? "/" : "\\"; + var idx = url.lastIndexOf(split); + var folderPath = idx >= 0 ? url.substr(0, idx + 1) : ""; + for (var i = 0, len = toloadPics.length; i < len; i++) { + toloadPics[i] = folderPath + toloadPics[i]; + } + } + else { + toloadPics = [url.replace(".json", ".png")]; + } + for (i = 0; i < toloadPics.length; i++) { + var tempAtlasPngUrl = toloadPics[i]; + QGMiniAdapter.postInfoToContext(url, tempAtlasPngUrl, atlasJson); + } + } + else { + throw "传递的url没有获取到对应的图集数据信息,请确保图集已经过!"; + } + } + } + static postInfoToContext(url, atlaspngUrl, atlasJson) { + var postData = { "frames": atlasJson.frames, "meta": atlasJson.meta }; + var textureUrl = atlaspngUrl; + var fileObj = MiniFileMgr.getFileInfo(Laya.URL.formatURL(atlaspngUrl)); + if (fileObj) { + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = textureUrl; + } + if (fileNativeUrl) { + QGMiniAdapter.window.qg.postMessage && QGMiniAdapter.window.qg.postMessage({ url: url, atlasdata: postData, imgNativeUrl: fileNativeUrl, imgReadyUrl: textureUrl, isLoad: "opendatacontext" }); + } + else { + throw "获取图集的磁盘url路径不存在!"; + } + } + static sendSinglePicToOpenDataContext(url) { + var tempTextureUrl = Laya.URL.formatURL(url); + var fileObj = MiniFileMgr.getFileInfo(tempTextureUrl); + if (fileObj) { + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + url = tempTextureUrl; + } + else { + fileNativeUrl = url; + } + if (fileNativeUrl) { + QGMiniAdapter.window.qg.postMessage && QGMiniAdapter.window.qg.postMessage({ url: url, imgNativeUrl: fileNativeUrl, imgReadyUrl: url, isLoad: "openJsondatacontextPic" }); + } + else { + throw "获取图集的磁盘url路径不存在!"; + } + } + static sendJsonDataToDataContext(url) { + if (!QGMiniAdapter.isZiYu) { + var atlasJson = Laya.Loader.getRes(url); + if (atlasJson) { + QGMiniAdapter.window.qg.postMessage && QGMiniAdapter.window.qg.postMessage({ url: url, atlasdata: atlasJson, isLoad: "openJsondatacontext" }); + } + else { + throw "传递的url没有获取到对应的图集数据信息,请确保图集已经过!"; + } + } + } + } + QGMiniAdapter.IGNORE = new RegExp("[-_.!~*'();/?:@&=+$,#%]|[0-9|A-Z|a-z]"); + QGMiniAdapter.safeEncodeURI = function (str) { + var strTemp = ""; + var length = str.length; + for (var i = 0; i < length; i++) { + var word = str[i]; + if (QGMiniAdapter.IGNORE.test(word)) { + strTemp += word; + } + else { + try { + strTemp += encodeURI(word); + } + catch (e) { + console.log("errorInfo", ">>>" + word); + } + } + } + return strTemp; + }; + QGMiniAdapter._inited = false; + QGMiniAdapter.systemInfo = {}; + QGMiniAdapter.autoCacheFile = true; + QGMiniAdapter.minClearSize = (5 * 1024 * 1024); + QGMiniAdapter.sizeLimit = (50 * 1024 * 1024); + QGMiniAdapter.nativefiles = ["layaNativeDir"]; + QGMiniAdapter.subNativeheads = []; + QGMiniAdapter.subMaps = []; + QGMiniAdapter.AutoCacheDownFile = false; + QGMiniAdapter.parseXMLFromString = function (value) { + var rst; + value = value.replace(/>\s+<'); + try { + rst = (new window.DOMParser()).parseFromString(value, 'text/xml'); + } + catch (error) { + throw "需要引入xml解析库文件"; + } + return rst; + }; + QGMiniAdapter.idx = 1; + + class MiniAccelerator extends Laya.EventDispatcher { + constructor() { + super(); + } + static __init__() { + try { + var Acc; + Acc = Laya.Accelerator; + if (!Acc) + return; + Acc["prototype"]["on"] = MiniAccelerator["prototype"]["on"]; + Acc["prototype"]["off"] = MiniAccelerator["prototype"]["off"]; + } + catch (e) { + } + } + static startListen(callBack) { + MiniAccelerator._callBack = callBack; + if (MiniAccelerator._isListening) + return; + MiniAccelerator._isListening = true; + try { + QGMiniAdapter.window.qg.onAccelerometerChange(MiniAccelerator.onAccelerometerChange); + } + catch (e) { } + } + static stopListen() { + MiniAccelerator._isListening = false; + try { + QGMiniAdapter.window.qg.stopAccelerometer({}); + } + catch (e) { } + } + static onAccelerometerChange(res) { + var e; + e = {}; + e.acceleration = res; + e.accelerationIncludingGravity = res; + e.rotationRate = {}; + if (MiniAccelerator._callBack != null) { + MiniAccelerator._callBack(e); + } + } + on(type, caller, listener, args = null) { + super.on(type, caller, listener, args); + MiniAccelerator.startListen(this["onDeviceOrientationChange"]); + return this; + } + off(type, caller, listener, onceOnly = false) { + if (!this.hasListener(type)) + MiniAccelerator.stopListen(); + return super.off(type, caller, listener, onceOnly); + } + } + MiniAccelerator._isListening = false; + + class MiniImage { + _loadImage(url) { + var thisLoader = this; + if (QGMiniAdapter.isZiYu) { + MiniImage.onCreateImage(url, thisLoader, true); + return; + } + var isTransformUrl; + if (!MiniFileMgr.isLocalNativeFile(url)) { + isTransformUrl = true; + url = Laya.URL.formatURL(url); + } + else { + if (url.indexOf("http://usr/") == -1 && (url.indexOf("http://") != -1 || url.indexOf("https://") != -1)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL.basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (QGMiniAdapter.subNativeFiles && QGMiniAdapter.subNativeheads.length == 0) { + for (var key in QGMiniAdapter.subNativeFiles) { + var tempArr = QGMiniAdapter.subNativeFiles[key]; + QGMiniAdapter.subNativeheads = QGMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + QGMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (QGMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && QGMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = QGMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + } + if (!MiniFileMgr.getFileInfo(url)) { + if (url.indexOf('http://usr/') == -1 && (url.indexOf("http://") != -1 || url.indexOf("https://") != -1)) { + if (QGMiniAdapter.isZiYu) { + MiniImage.onCreateImage(url, thisLoader, true); + } + else { + MiniFileMgr.downOtherFiles(encodeURI(url), new Laya.Handler(MiniImage, MiniImage.onDownImgCallBack, [url, thisLoader]), url); + } + } + else + MiniImage.onCreateImage(url, thisLoader, true); + } + else { + MiniImage.onCreateImage(url, thisLoader, !isTransformUrl); + } + } + static onDownImgCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = "") { + if (!errorCode) + MiniImage.onCreateImage(sourceUrl, thisLoader, false, tempFilePath); + else { + thisLoader.onError(null); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (QGMiniAdapter.autoCacheFile) { + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + var fileMd5Name = fileObj.md5; + fileNativeUrl = MiniFileMgr.getFileNativePath(fileMd5Name); + } + } + else if (QGMiniAdapter.isZiYu) { + var tempUrl = Laya.URL.formatURL(sourceUrl); + if (MiniFileMgr.ziyuFileTextureData[tempUrl]) { + fileNativeUrl = MiniFileMgr.ziyuFileTextureData[tempUrl]; + } + else + fileNativeUrl = sourceUrl; + } + else + fileNativeUrl = sourceUrl; + } + else { + if (!isLocal) + fileNativeUrl = tempFilePath; + else + fileNativeUrl = sourceUrl; + } + if (thisLoader._imgCache == null) + thisLoader._imgCache = {}; + var image; + function clear() { + var img = thisLoader._imgCache[sourceUrl]; + if (img) { + img.onload = null; + img.onerror = null; + delete thisLoader._imgCache[sourceUrl]; + } + } + var onerror = function () { + clear(); + delete MiniFileMgr.fakeObj[sourceUrl]; + delete MiniFileMgr.filesListObj[sourceUrl]; + thisLoader.event(Laya.Event.ERROR, "Load image failed"); + }; + if (thisLoader._type == "nativeimage") { + var onload = function () { + clear(); + thisLoader.onLoaded(image); + }; + image = new Laya.Browser.window.Image(); + image.crossOrigin = ""; + image.onload = onload; + image.onerror = onerror; + image.src = fileNativeUrl; + thisLoader._imgCache[sourceUrl] = image; + } + else { + var imageSource = new Laya.Browser.window.Image(); + onload = function () { + image = Laya.HTMLImage.create(imageSource.width, imageSource.height); + image.loadImageSource(imageSource, true); + image._setCreateURL(sourceUrl); + clear(); + thisLoader.onLoaded(image); + }; + imageSource.crossOrigin = ""; + imageSource.onload = onload; + imageSource.onerror = onerror; + imageSource.src = fileNativeUrl; + thisLoader._imgCache[sourceUrl] = imageSource; + } + } + } + + class MiniLocation { + constructor() { + } + static __init__() { + QGMiniAdapter.window.navigator.geolocation.getCurrentPosition = MiniLocation.getCurrentPosition; + QGMiniAdapter.window.navigator.geolocation.watchPosition = MiniLocation.watchPosition; + QGMiniAdapter.window.navigator.geolocation.clearWatch = MiniLocation.clearWatch; + } + static getCurrentPosition(success = null, error = null, options = null) { + var paramO; + paramO = {}; + paramO.success = getSuccess; + paramO.fail = error; + QGMiniAdapter.window.qg.getLocation(paramO); + function getSuccess(res) { + if (success != null) { + success(res); + } + } + } + static watchPosition(success = null, error = null, options = null) { + MiniLocation._curID++; + var curWatchO; + curWatchO = {}; + curWatchO.success = success; + curWatchO.error = error; + MiniLocation._watchDic[MiniLocation._curID] = curWatchO; + Laya.Laya.systemTimer.loop(1000, null, MiniLocation._myLoop); + return MiniLocation._curID; + } + static clearWatch(id) { + delete MiniLocation._watchDic[id]; + if (!MiniLocation._hasWatch()) { + Laya.Laya.systemTimer.clear(null, MiniLocation._myLoop); + } + } + static _hasWatch() { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key]) + return true; + } + return false; + } + static _myLoop() { + MiniLocation.getCurrentPosition(MiniLocation._mySuccess, MiniLocation._myError); + } + static _mySuccess(res) { + var rst = {}; + rst.coords = res; + rst.timestamp = Laya.Browser.now(); + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].success) { + MiniLocation._watchDic[key].success(rst); + } + } + } + static _myError(res) { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].error) { + MiniLocation._watchDic[key].error(res); + } + } + } + } + MiniLocation._watchDic = {}; + MiniLocation._curID = 0; + + class MiniVideo { + constructor(width = 320, height = 240) { + this.videoend = false; + this.videourl = ""; + this.videoW = width; + this.videoH = height; + } + static __init__() { + } + on(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + } + this.videoElement.onTimeUpdate = this.onTimeUpdateFunc.bind(this); + } + onTimeUpdateFunc(data) { + this.position = data.position; + this._duration = data.duration; + } + get duration() { + return this._duration; + } + onPlayFunction() { + if (this.videoElement) + this.videoElement.readyState = 200; + this.onPlayFunc != null && this.onPlayFunc(); + } + onEndedFunction() { + this.videoend = true; + this.onEndedFunC != null && this.onEndedFunC(); + } + off(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.offPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.offEnded = this.onEndedFunction.bind(this); + } + } + load(url) { + if (!this.videoElement) { + this.videoElement = QGMiniAdapter.window.qg.createVideo({ width: this.videoW, height: this.videoH, autoplay: true, src: url }); + this.videoElement.onPlay = this.onPlayFunction.bind(this); + this.videoElement.onEnded = this.onEndedFunction.bind(this); + } + else { + this.videoElement.src = url; + } + } + play() { + if (!this.videoElement) + return; + this.videoend = false; + this.videoElement.play(); + } + pause() { + if (!this.videoElement) + return; + this.videoend = true; + this.videoElement.pause(); + } + get currentTime() { + if (!this.videoElement) + return 0; + return this.videoElement.initialTime; + } + set currentTime(value) { + if (!this.videoElement) + return; + this.videoElement.initialTime = value; + } + get videoWidth() { + if (!this.videoElement) + return 0; + return this.videoElement.width; + } + get videoHeight() { + if (!this.videoElement) + return 0; + return this.videoElement.height; + } + get ended() { + return this.videoend; + } + get loop() { + if (!this.videoElement) + return false; + return this.videoElement.loop; + } + set loop(value) { + if (!this.videoElement) + return; + this.videoElement.loop = value; + } + get playbackRate() { + if (!this.videoElement) + return 0; + return this.videoElement.playbackRate; + } + set playbackRate(value) { + if (!this.videoElement) + return; + this.videoElement.playbackRate = value; + } + get muted() { + if (!this.videoElement) + return false; + return this.videoElement.muted; + } + set muted(value) { + if (!this.videoElement) + return; + this.videoElement.muted = value; + } + get paused() { + if (!this.videoElement) + return false; + return this.videoElement.paused; + } + size(width, height) { + if (!this.videoElement) + return; + this.videoElement.width = width; + this.videoElement.height = height; + } + get x() { + if (!this.videoElement) + return 0; + return this.videoElement.x; + } + set x(value) { + if (!this.videoElement) + return; + this.videoElement.x = value; + } + get y() { + if (!this.videoElement) + return 0; + return this.videoElement.y; + } + set y(value) { + if (!this.videoElement) + return; + this.videoElement.y = value; + } + get currentSrc() { + return this.videoElement.src; + } + destroy() { + if (this.videoElement) + this.videoElement.destroy(); + this.videoElement = null; + this.onEndedFunC = null; + this.onPlayFunc = null; + this.videoend = false; + this.videourl = null; + } + reload() { + if (!this.videoElement) + return; + this.videoElement.src = this.videourl; + } + } + + exports.ImageDataPolyfill = ImageDataPolyfill; + exports.MiniAccelerator = MiniAccelerator; + exports.MiniFileMgr = MiniFileMgr; + exports.MiniImage = MiniImage; + exports.MiniInput = MiniInput; + exports.MiniLoader = MiniLoader; + exports.MiniLocation = MiniLocation; + exports.MiniSound = MiniSound; + exports.MiniSoundChannel = MiniSoundChannel; + exports.MiniVideo = MiniVideo; + exports.QGMiniAdapter = QGMiniAdapter; + +} diff --git a/examples/layaair/frontend/bin/libs/laya.spine.js b/examples/layaair/frontend/bin/libs/laya.spine.js new file mode 100644 index 0000000..6242278 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.spine.js @@ -0,0 +1,745 @@ +(function (exports, Laya) { + 'use strict'; + + class SpineGLTexture extends Laya.Texture { + constructor(tex) { + super(tex); + } + getImage() { + return { + width: this.sourceWidth, + height: this.sourceHeight + }; + } + setFilters(minFilter, magFilter) { + } + setWraps(uWrap, vWrap) { + } + } + + var Color = spine.Color; + var SkeletonClipping = spine.SkeletonClipping; + var Vector2 = spine.Vector2; + var Utils = spine.Utils; + var RegionAttachment = spine.RegionAttachment; + var MeshAttachment = spine.MeshAttachment; + var ClippingAttachment = spine.ClippingAttachment; + class Renderable { + constructor(vertices, numVertices, numFloats) { + this.vertices = vertices; + this.numVertices = numVertices; + this.numFloats = numFloats; + } + } + class SpineSkeletonRenderer { + constructor(twoColorTint = true) { + this.vertexEffect = null; + this.tempColor = new Color(); + this.tempColor2 = new Color(); + this.vertexSize = 2 + 2 + 4; + this.twoColorTint = false; + this.renderable = new Renderable(null, 0, 0); + this.clipper = new SkeletonClipping(); + this.temp = new Vector2(); + this.temp2 = new Vector2(); + this.temp3 = new Color(); + this.temp4 = new Color(); + this.twoColorTint = twoColorTint; + if (twoColorTint) + this.vertexSize += 4; + this.vertices = Utils.newFloatArray(this.vertexSize * 1024); + } + draw(skeleton, slotRangeStart = -1, slotRangeEnd = -1, spineSkeletonIns, textureList) { + let clipper = this.clipper; + let premultipliedAlpha = this.premultipliedAlpha; + let twoColorTint = false; + let tempPos = this.temp; + let tempUv = this.temp2; + let tempLight = this.temp3; + let tempDark = this.temp4; + let renderable = this.renderable; + let uvs = null; + let triangles = null; + let drawOrder = skeleton.drawOrder; + let attachmentColor = null; + let skeletonColor = skeleton.color; + let vertexSize = 8; + let inRange = false; + if (slotRangeStart == -1) + inRange = true; + for (let i = 0, n = drawOrder.length; i < n; i++) { + let clippedVertexSize = clipper.isClipping() ? 2 : vertexSize; + let slot = drawOrder[i]; + if (slotRangeStart >= 0 && slotRangeStart == slot.data.index) { + inRange = true; + } + if (!inRange) { + clipper.clipEndWithSlot(slot); + continue; + } + if (slotRangeEnd >= 0 && slotRangeEnd == slot.data.index) { + inRange = false; + } + let attachment = slot.getAttachment(); + let name = null; + let texture; + if (attachment instanceof RegionAttachment) { + let region = attachment; + renderable.vertices = this.vertices; + renderable.numVertices = 4; + renderable.numFloats = clippedVertexSize << 2; + region.computeWorldVertices(slot.bone, renderable.vertices, 0, clippedVertexSize); + triangles = SpineSkeletonRenderer.QUAD_TRIANGLES; + uvs = region.uvs; + name = region.region.renderObject.page.name; + texture = textureList[name]; + attachmentColor = region.color; + } + else if (attachment instanceof MeshAttachment) { + let mesh = attachment; + renderable.vertices = this.vertices; + renderable.numVertices = (mesh.worldVerticesLength >> 1); + renderable.numFloats = renderable.numVertices * clippedVertexSize; + if (renderable.numFloats > renderable.vertices.length) { + renderable.vertices = this.vertices = Utils.newFloatArray(renderable.numFloats); + } + mesh.computeWorldVertices(slot, 0, mesh.worldVerticesLength, renderable.vertices, 0, clippedVertexSize); + triangles = mesh.triangles; + name = mesh.region.renderObject.page.name; + texture = textureList[name]; + uvs = mesh.uvs; + attachmentColor = mesh.color; + } + else if (attachment instanceof ClippingAttachment) { + let clip = (attachment); + clipper.clipStart(slot, clip); + continue; + } + else { + clipper.clipEndWithSlot(slot); + continue; + } + if (texture != null) { + let slotColor = slot.color; + let finalColor = this.tempColor; + finalColor.r = skeletonColor.r * slotColor.r * attachmentColor.r; + finalColor.g = skeletonColor.g * slotColor.g * attachmentColor.g; + finalColor.b = skeletonColor.b * slotColor.b * attachmentColor.b; + finalColor.a = skeletonColor.a * slotColor.a * attachmentColor.a; + if (premultipliedAlpha) { + finalColor.r *= finalColor.a; + finalColor.g *= finalColor.a; + finalColor.b *= finalColor.a; + } + let slotBlendMode = slot.data.blendMode; + if (clipper.isClipping()) { + clipper.clipTriangles(renderable.vertices, renderable.numFloats, triangles, triangles.length, uvs, finalColor, null, twoColorTint); + let clippedVertices = new Float32Array(clipper.clippedVertices); + let clippedTriangles = clipper.clippedTriangles; + let mVertices = []; + let mUVs = []; + let colors = []; + if (this.vertexEffect != null) { + let vertexEffect = this.vertexEffect; + let verts = clippedVertices; + { + for (let v = 0, n = clippedVertices.length; v < n; v += vertexSize) { + tempPos.x = verts[v]; + tempPos.y = verts[v + 1]; + tempLight.set(verts[v + 2], verts[v + 3], verts[v + 4], verts[v + 5]); + tempUv.x = verts[v + 6]; + tempUv.y = verts[v + 7]; + tempDark.set(0, 0, 0, 0); + vertexEffect.transform(tempPos, tempUv, tempLight, tempDark); + verts[v] = tempPos.x; + verts[v + 1] = tempPos.y; + verts[v + 2] = tempLight.r; + verts[v + 3] = tempLight.g; + verts[v + 4] = tempLight.b; + verts[v + 5] = tempLight.a; + verts[v + 6] = tempUv.x; + verts[v + 7] = tempUv.y; + mVertices.push(verts[v], -verts[v + 1]); + colors.push(verts[v + 2], verts[v + 3], verts[v + 4], verts[v + 5]); + mUVs.push(verts[v + 6], verts[v + 7]); + } + } + } + else { + let vi = 0; + while (Number.isFinite(clippedVertices[vi + 6]) && Number.isFinite(clippedVertices[vi + 7])) { + mVertices.push(clippedVertices[vi]); + mVertices.push(-clippedVertices[vi + 1]); + colors.push(clippedVertices[vi + 2]); + colors.push(clippedVertices[vi + 3]); + colors.push(clippedVertices[vi + 4]); + colors.push(clippedVertices[vi + 5]); + mUVs.push(clippedVertices[vi + 6]); + mUVs.push(clippedVertices[vi + 7]); + vi += this.vertexSize; + } + } + let alpha = 1; + let color = null; + let colorNum = null; + let blendMode; + switch (slotBlendMode) { + case 1: + blendMode = "light"; + break; + case 2: + blendMode = "multiply"; + break; + case 3: + blendMode = "screen"; + break; + default: + blendMode = "normal"; + } + colorNum = ((colors[3] * 255) << 24) + colors[0] * 255 | 0 + ((colors[1] * 255) << 8) + ((colors[2] * 255) << 16); + spineSkeletonIns.graphics.drawTriangles(texture, 0, 0, mVertices, mUVs, new Uint16Array(clippedTriangles), Laya.Matrix.EMPTY, alpha, color, blendMode, colorNum); + } + else { + let verts = renderable.vertices; + let mVertices = []; + let mUVs = []; + let colors = []; + if (this.vertexEffect != null) { + let vertexEffect = this.vertexEffect; + { + for (let v = 0, u = 0, n = renderable.numFloats; v < n; v += vertexSize, u += 2) { + tempPos.x = verts[v]; + tempPos.y = verts[v + 1]; + tempUv.x = uvs[u]; + tempUv.y = uvs[u + 1]; + tempLight.setFromColor(finalColor); + tempDark.set(0, 0, 0, 0); + vertexEffect.transform(tempPos, tempUv, tempLight, tempDark); + verts[v] = tempPos.x; + verts[v + 1] = tempPos.y; + verts[v + 2] = tempLight.r; + verts[v + 3] = tempLight.g; + verts[v + 4] = tempLight.b; + verts[v + 5] = tempLight.a; + verts[v + 6] = tempUv.x; + verts[v + 7] = tempUv.y; + mVertices.push(verts[v], -verts[v + 1]); + colors.push(verts[v + 2], verts[v + 3], verts[v + 4], verts[v + 5]); + mUVs.push(verts[v + 6], verts[v + 7]); + } + } + } + else { + { + for (let v = 2, u = 0, n = renderable.numFloats; v < n; v += vertexSize, u += 2) { + verts[v] = finalColor.r; + verts[v + 1] = finalColor.g; + verts[v + 2] = finalColor.b; + verts[v + 3] = finalColor.a; + verts[v + 4] = uvs[u]; + verts[v + 5] = uvs[u + 1]; + mVertices.push(verts[v - 2], -verts[v - 1]); + colors.push(verts[v], verts[v + 1], verts[v + 2], verts[v + 3]); + mUVs.push(verts[v + 4], verts[v + 5]); + } + } + } + let alpha = 1; + let color = null; + let colorNum = null; + let blendMode; + switch (slotBlendMode) { + case 1: + blendMode = "light"; + break; + case 2: + blendMode = "multiply"; + break; + case 3: + blendMode = "screen"; + break; + default: + blendMode = "normal"; + } + colorNum = ((colors[3] * 255) << 24) + colors[0] * 255 | 0 + ((colors[1] * 255) << 8) + ((colors[2] * 255) << 16); + spineSkeletonIns.graphics.drawTriangles(texture, 0, 0, mVertices, mUVs, new Uint16Array(triangles), Laya.Matrix.EMPTY, alpha, color, blendMode, colorNum); + } + } + clipper.clipEndWithSlot(slot); + } + clipper.clipEnd(); + } + } + SpineSkeletonRenderer.QUAD_TRIANGLES = [0, 1, 2, 2, 3, 0]; + + var TimeKeeper = spine.TimeKeeper; + var Skeleton = spine.Skeleton; + var AnimationState = spine.AnimationState; + var AnimationStateData = spine.AnimationStateData; + class SpineSkeleton extends Laya.Sprite { + constructor(templet = null) { + super(); + this.currentPlayTime = 0; + this._pause = true; + this._currAniName = null; + this._playbackRate = 1.0; + this._playAudio = true; + this._soundChannelArr = []; + this.trackIndex = 0; + if (templet) + this.init(templet); + this._ins = this; + } + init(templet) { + var that = this; + this._templet = templet; + this.skeleton = new Skeleton(this._templet.skeletonData); + this.stateData = new AnimationStateData(this.skeleton.data); + this.state = new AnimationState(this.stateData); + this.skeletonRenderer = new SpineSkeletonRenderer(false); + this.timeKeeper = new TimeKeeper(); + this.skeletonRenderer.premultipliedAlpha = this._templet._spinePremultipliedAlpha; + this.state.addListener({ + start: function (entry) { + }, + interrupt: function (entry) { + }, + end: function (entry) { + }, + dispose: function (entry) { + }, + complete: function (entry) { + if (entry.loop) { + that.event(Laya.Event.COMPLETE); + } + else { + that._currAniName = null; + that.event(Laya.Event.STOPPED); + } + }, + event: function (entry, event) { + var eventData = { + audioValue: event.data.audioPath, + audioPath: event.data.audioPath, + floatValue: event.floatValue, + intValue: event.intValue, + name: event.data.name, + stringValue: event.stringValue, + time: event.time * 1000, + balance: event.balance, + volume: event.volume + }; + that.event(Laya.Event.LABEL, eventData); + var _soundChannel; + if (that._playAudio && eventData.audioValue) { + _soundChannel = Laya.SoundManager.playSound(templet._textureDic.root + eventData.audioValue, 1, Laya.Handler.create(that, that._onAniSoundStoped), null, (that.currentPlayTime * 1000 - eventData.time) / 1000); + Laya.SoundManager.playbackRate = that._playbackRate; + _soundChannel && that._soundChannelArr.push(_soundChannel); + } + }, + }); + } + play(nameOrIndex, loop, force = true, start = 0, end = 0, freshSkin = true, playAudio = true) { + this._playAudio = playAudio; + start /= 1000; + end /= 1000; + var animationName = nameOrIndex; + if (start < 0 || end < 0) + throw new Error("SpineSkeleton: start and end must large than zero."); + if ((end !== 0) && (start > end)) + throw new Error("SpineSkeleton: start must less than end."); + if (typeof animationName == "number") { + animationName = this.getAniNameByIndex(nameOrIndex); + } + if (force || this._pause || this._currAniName != animationName) { + this._currAniName = animationName; + this.state.setAnimation(this.trackIndex, animationName, loop); + let trackEntry = this.state.getCurrent(this.trackIndex); + trackEntry.animationStart = start; + if (!!end && end < trackEntry.animationEnd) + trackEntry.animationEnd = end; + let animationDuration = trackEntry.animation.duration; + this._duration = animationDuration; + this._playStart = start; + this._playEnd = end <= animationDuration ? end : animationDuration; + if (this._pause) { + this._pause = false; + this.timer.frameLoop(1, this, this._update, null, true); + } + this._update(); + } + } + _update() { + this.timeKeeper.update(); + let delta = this.timeKeeper.delta * this._playbackRate; + let trackEntry = this.state.getCurrent(this.trackIndex); + this.state.update(delta); + this.state.apply(this.skeleton); + let animationLast = trackEntry.animationLast; + this.currentPlayTime = Math.max(0, animationLast); + if (!this.state || !this.skeleton) { + return; + } + this.skeleton.updateWorldTransform(); + this._ins.graphics.clear(); + this.skeletonRenderer.draw(this.skeleton, -1, -1, this._ins, this._templet._textureDic); + } + getAnimNum() { + return this._templet.skeletonData.animations.length; + } + getAniNameByIndex(index) { + return this._templet.getAniNameByIndex(index); + } + getSlotByName(slotName) { + return this.skeleton.findSlot(slotName); + } + playbackRate(value) { + this._playbackRate = value; + } + showSkinByName(name) { + this.showSkinByIndex(this._templet.getSkinIndexByName(name)); + } + showSkinByIndex(skinIndex) { + let newSkine = this.skeleton.data.skins[skinIndex]; + this.skeleton.setSkin(newSkine); + this.skeleton.setSlotsToSetupPose(); + } + stop() { + if (!this._pause) { + this._pause = true; + this._currAniName = null; + this.timer.clear(this, this._update); + this.state.update(-this.currentPlayTime); + this.currentPlayTime = 0; + this.event(Laya.Event.STOPPED); + if (this._soundChannelArr.length > 0) { + this._onAniSoundStoped(true); + } + } + } + paused() { + if (!this._pause) { + this._pause = true; + this.timer.clear(this, this._update); + this.event(Laya.Event.PAUSED); + if (this._soundChannelArr.length > 0) { + var _soundChannel; + for (var len = this._soundChannelArr.length, i = 0; i < len; i++) { + _soundChannel = this._soundChannelArr[i]; + if (!_soundChannel.isStopped) { + _soundChannel.pause(); + } + } + } + } + } + resume() { + if (this._pause) { + this._pause = false; + this.timer.frameLoop(1, this, this._update, null, true); + if (this._soundChannelArr.length > 0) { + var _soundChannel; + for (var len = this._soundChannelArr.length, i = 0; i < len; i++) { + _soundChannel = this._soundChannelArr[i]; + if (_soundChannel.audioBuffer) { + _soundChannel.resume(); + } + } + } + } + } + _onAniSoundStoped(force) { + var _channel; + for (var len = this._soundChannelArr.length, i = 0; i < len; i++) { + _channel = this._soundChannelArr[i]; + if (_channel.isStopped || force) { + !_channel.isStopped && _channel.stop(); + this._soundChannelArr.splice(i, 1); + len--; + i--; + } + } + } + destroy(destroyChild = true) { + super.destroy(destroyChild); + this._templet._removeReference(1); + this._templet = null; + this.timeKeeper = null; + this.skeleton = null; + this.state.clearListeners(); + this.state = null; + this.skeletonRenderer = null; + this.timer.clear(this, this._update); + if (this._soundChannelArr.length > 0) { + this._onAniSoundStoped(true); + } + } + get templet() { + return this._templet; + } + addAnimation(nameOrIndex, loop = false, delay = 0) { + delay /= 1000; + var animationName = nameOrIndex; + if (typeof animationName == "number") { + animationName = this.getAniNameByIndex(animationName); + } + this._currAniName = animationName; + this.state.addAnimation(this.trackIndex, animationName, loop, delay); + } + setMix(fromNameOrIndex, toNameOrIndex, duration) { + duration /= 1000; + var fromName = fromNameOrIndex; + if (typeof fromName == "number") { + fromName = this.getAniNameByIndex(fromName); + } + var toName = toNameOrIndex; + if (typeof toName == "number") { + toName = this.getAniNameByIndex(toName); + } + this.stateData.setMix(fromName, toName, duration); + } + getBoneByName(boneName) { + return this.skeleton.findBone(boneName); + } + getSkeleton() { + return this.skeleton; + } + setSlotAttachment(slotName, attachmentName) { + this.skeleton.setAttachment(slotName, attachmentName); + } + set currentTime(value) { + if (!this._currAniName || !this._templet) + return; + value /= 1000; + if (value < this._playStart || (!!this._playEnd && value > this._playEnd) || value > this._duration) + throw new Error("AnimationPlayer: value must large than playStartTime,small than playEndTime."); + this.state.update(value - this.currentPlayTime); + this.currentPlayTime = value; + } + get playState() { + if (!this._currAniName) + return SpineSkeleton.stopped; + if (this._pause) + return SpineSkeleton.paused; + return SpineSkeleton.playing; + } + } + SpineSkeleton.stopped = 0; + SpineSkeleton.paused = 1; + SpineSkeleton.playing = 2; + Laya.ILaya.regClass(SpineSkeleton); + Laya.ClassUtils.regClass("laya.layaspine.SpineSkeleton", SpineSkeleton); + Laya.ClassUtils.regClass("Laya.SpineSkeleton", SpineSkeleton); + + var SharedAssetManager = spine.SharedAssetManager; + var TextureAtlas = spine.TextureAtlas; + var AtlasAttachmentLoader = spine.AtlasAttachmentLoader; + var SkeletonJson = spine.SkeletonJson; + class SpineTemplet extends Laya.Resource { + constructor() { + super(); + this._textureDic = {}; + this._isDestroyed = false; + this._layaPremultipliedAlpha = true; + this._spinePremultipliedAlpha = false; + } + loadAni(jsonUrl, textureUrlList = null) { + let splitIndex = jsonUrl.lastIndexOf("/") + 1; + let clientId = jsonUrl.slice(0, splitIndex); + jsonUrl = jsonUrl.slice(splitIndex); + let atlasUrl = jsonUrl.replace(".json", ".atlas"); + if (!textureUrlList) { + textureUrlList = [jsonUrl.replace(".json", ".png")]; + } + this._textureDic.root = clientId; + this._textureUrlList = textureUrlList; + this.clientId = clientId; + this.atlasUrl = atlasUrl; + this.jsonUrl = jsonUrl; + this.assetManager = new SharedAssetManager(clientId); + this.assetManager.loadJson(clientId, jsonUrl); + this.assetManager.loadText(clientId, atlasUrl); + for (var i = 0, len = textureUrlList.length, texture; i < len; i++) { + texture = textureUrlList[i]; + this.assetManager.loadTexture(clientId, this.textureLoader.bind(this), texture); + } + window.requestAnimationFrame(this.loop.bind(this)); + } + textureLoader(tex) { + var src = tex.url; + var tTextureName, item, textureUrlList = this._textureUrlList; + for (var i = 0, len = textureUrlList.length; i < len; i++) { + item = textureUrlList[i]; + if (src.endsWith(`/${item}`)) { + tTextureName = item; + break; + } + } + var tTexture = this._textureDic[tTextureName] = new SpineGLTexture(tex.bitmap); + return tTexture; + } + loop() { + if (this.assetManager.isLoadingComplete(this.clientId)) { + this.parseSpineAni(); + return; + } + if (this.assetManager.hasErrors()) { + this.event(Laya.Event.ERROR, "load failed:" + this.assetManager.getErrors()); + return; + } + window.requestAnimationFrame(this.loop.bind(this)); + } + parseSpineAni() { + if (this._isDestroyed) { + this.destroy(); + return; + } + var _this = this; + var atlas = new TextureAtlas(this.assetManager.get(this.clientId, this.atlasUrl), function (path) { + return _this.assetManager.get(_this.clientId, path); + }); + var atlasLoader = new AtlasAttachmentLoader(atlas); + this.skeletonJson = new SkeletonJson(atlasLoader); + this.skeletonData = this.skeletonJson.readSkeletonData(this.assetManager.get(this.clientId, this.jsonUrl)); + this.event(Laya.Event.COMPLETE, this); + } + buildArmature() { + return new SpineSkeleton(this); + } + getAniNameByIndex(index) { + var tAni = this.skeletonData.animations[index]; + if (tAni) + return tAni.name; + return null; + } + getSkinIndexByName(skinName) { + var skins = this.skeletonData.skins; + var tSkinData; + for (var i = 0, n = skins.length; i < n; i++) { + tSkinData = skins[i]; + if (tSkinData.name == skinName) { + return i; + } + } + return -1; + } + destroy() { + this._isDestroyed = true; + var tTexture; + for (tTexture in this._textureDic) { + if (tTexture == "root") + continue; + if (tTexture) { + this._textureDic[tTexture].destroy(); + } + } + super.destroy(); + } + } + + var AssetManager = spine.AssetManager; + var AtlasAttachmentLoader$1 = spine.AtlasAttachmentLoader; + var SkeletonBinary = spine.SkeletonBinary; + class SpineTempletBinary extends Laya.Resource { + constructor() { + super(); + this._textureDic = {}; + this._isDestroyed = false; + this._layaPremultipliedAlpha = true; + this._spinePremultipliedAlpha = false; + } + loadAni(skelUrl, textureUrlList = null) { + let splitIndex = skelUrl.lastIndexOf("/") + 1; + let pathPrefix = skelUrl.slice(0, splitIndex); + skelUrl = skelUrl.slice(splitIndex); + this.skelUrl = skelUrl; + skelUrl = skelUrl.replace(".json", ".skel"); + let atlasUrl = skelUrl.replace(".skel", ".atlas"); + if (!textureUrlList) { + textureUrlList = [skelUrl.replace(".skel", ".png")]; + } + this._textureDic.root = pathPrefix; + this.pathPrefix = pathPrefix; + this.atlasUrl = atlasUrl; + this.textureUrlList = textureUrlList; + this.assetManager = new AssetManager(this.textureLoader.bind(this), pathPrefix); + this.assetManager.loadBinary(this.skelUrl); + this.assetManager.loadTextureAtlas(atlasUrl); + Laya.Laya.timer.frameOnce(1, this, this.loop); + } + textureLoader(tex) { + let src = tex.url; + let tTextureName, item, textureUrlList = this.textureUrlList; + for (let i = 0, len = textureUrlList.length; i < len; i++) { + item = textureUrlList[i]; + if (src.endsWith(item)) { + tTextureName = item; + break; + } + } + let tTexture = this._textureDic[tTextureName] = new SpineGLTexture(tex.bitmap); + return tTexture; + } + loop() { + if (this.assetManager.isLoadingComplete()) { + this.parseSpineAni(); + return; + } + if (this.assetManager.hasErrors()) { + this.event(Laya.Event.ERROR, "load failed:" + this.assetManager.getErrors()); + return; + } + window.requestAnimationFrame(this.loop.bind(this)); + } + parseSpineAni() { + if (this._isDestroyed) { + this.destroy(); + return; + } + let atlas = this.assetManager.get(this.atlasUrl); + let atlasLoader = new AtlasAttachmentLoader$1(atlas); + this.skeletonBinary = new SkeletonBinary(atlasLoader); + this.skeletonData = this.skeletonBinary.readSkeletonData(this.assetManager.get(this.skelUrl)); + this.event(Laya.Event.COMPLETE, this); + } + buildArmature() { + return new SpineSkeleton(this); + } + getAniNameByIndex(index) { + let tAni = this.skeletonData.animations[index]; + if (tAni) + return tAni.name; + return null; + } + getSkinIndexByName(skinName) { + let skins = this.skeletonData.skins; + let tSkinData; + for (let i = 0, n = skins.length; i < n; i++) { + tSkinData = skins[i]; + if (tSkinData.name == skinName) { + return i; + } + } + return -1; + } + destroy() { + this._isDestroyed = true; + let tTexture; + for (tTexture in this._textureDic) { + if (tTexture == "root") + continue; + if (tTexture) { + this._textureDic[tTexture].destroy(); + } + } + super.destroy(); + } + } + + exports.SpineGLTexture = SpineGLTexture; + exports.SpineSkeleton = SpineSkeleton; + exports.SpineSkeletonRenderer = SpineSkeletonRenderer; + exports.SpineTemplet = SpineTemplet; + exports.SpineTempletBinary = SpineTempletBinary; + +}(window.Laya = window.Laya || {}, Laya)); diff --git a/examples/layaair/frontend/bin/libs/laya.tbmini.js b/examples/layaair/frontend/bin/libs/laya.tbmini.js new file mode 100644 index 0000000..8c4d324 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.tbmini.js @@ -0,0 +1,1573 @@ +window.tbMiniGame = function (exports, Laya) { + 'use strict'; + + function ImageDataPolyfill() { + let width, height, data; + if (arguments.length == 3) { + if (arguments[0] instanceof Uint8ClampedArray) { + if (arguments[0].length % 4 !== 0) { + throw new Error("Failed to construct 'ImageData': The input data length is not a multiple of 4."); + } + if (arguments[0].length !== arguments[1] * arguments[2] * 4) { + throw new Error("Failed to construct 'ImageData': The input data length is not equal to (4 * width * height)."); + } + else { + data = arguments[0]; + width = arguments[1]; + height = arguments[2]; + } + } + else { + throw new Error("Failed to construct 'ImageData': parameter 1 is not of type 'Uint8ClampedArray'."); + } + } + else if (arguments.length == 2) { + width = arguments[0]; + height = arguments[1]; + data = new Uint8ClampedArray(arguments[0] * arguments[1] * 4); + } + else if (arguments.length < 2) { + throw new Error("Failed to construct 'ImageData': 2 arguments required, but only " + arguments.length + " present."); + } + let imgdata = Laya.Browser.canvas.getContext("2d").getImageData(0, 0, width, height); + for (let i = 0; i < data.length; i += 4) { + imgdata.data[i] = data[i]; + imgdata.data[i + 1] = data[i + 1]; + imgdata.data[i + 2] = data[i + 2]; + imgdata.data[i + 3] = data[i + 3]; + } + return imgdata; + } + + class MiniFileMgr { + static isLocalNativeFile(url) { + for (var i = 0, sz = TBMiniAdapter.nativefiles.length; i < sz; i++) { + if (url.indexOf(TBMiniAdapter.nativefiles[i]) != -1) + return true; + } + return false; + } + static isSubNativeFile(url) { + for (var i = 0, sz = TBMiniAdapter.subNativeheads.length; i < sz; i++) { + if (url.indexOf(TBMiniAdapter.subNativeheads[i]) != -1) + return true; + } + return false; + } + static isNetFile(url) { + return (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) && url.indexOf(TBMiniAdapter.window.my.env.USER_DATA_PATH) == -1; + } + static getFileInfo(fileUrl) { + var fileNativePath = fileUrl; + var fileObj = MiniFileMgr.fakeObj[fileNativePath]; + if (fileObj == null) + return null; + else + return fileObj; + } + static read(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "") { + var fileUrl; + if (readyUrl != "" && (readyUrl.indexOf("http://") != -1 || readyUrl.indexOf("https://") != -1)) { + fileUrl = MiniFileMgr.getFileNativePath(filePath); + } + else { + fileUrl = filePath; + } + fileUrl = Laya.URL.getAdptedFilePath(fileUrl); + MiniFileMgr.fs.readFile({ filePath: fileUrl, encoding: encoding, success: function (data) { + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data && readyUrl != "") + MiniFileMgr.downFiles(TBMiniAdapter.safeEncodeURI(readyUrl), encoding, callBack, readyUrl, isSaveFile, fileType); + else + callBack != null && callBack.runWith([1]); + } }); + } + static isFile(url) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(url); + } + catch (err) { + return false; + } + return stat.isFile(); + } + static downFiles(fileUrl, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + var downloadTask = MiniFileMgr.wxdown({ url: fileUrl, success: function (data) { + if (!data.hasOwnProperty("statusCode")) { + data.statusCode = 200; + } + if (data.statusCode === 200) + MiniFileMgr.readFile(data.apFilePath, encoding, callBack, readyUrl, isSaveFile, fileType, isAutoClear); + else if (data.statusCode === 403) { + callBack != null && callBack.runWith([0, fileUrl]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + console.log("downloadfile fail:", readyUrl, data); + callBack != null && callBack.runWith([1, data]); + } }); + downloadTask.onProgressUpdate(function (data) { + callBack != null && callBack.runWith([2, data.progress]); + }); + } + static readFile(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + filePath = Laya.URL.getAdptedFilePath(filePath); + MiniFileMgr.fs.readFile({ filePath: filePath, encoding: encoding, success: function (data) { + if (filePath.indexOf(TBMiniAdapter.window.my.env.USER_DATA_PATH) && (filePath.indexOf("http://") != -1 || filePath.indexOf("https://") != -1)) { + if (isSaveFile) { + callBack != null && callBack.runWith([0, data]); + MiniFileMgr.copyTOCache(filePath, readyUrl, null, encoding, isAutoClear); + } + else + callBack != null && callBack.runWith([0, data]); + } + else { + callBack != null && callBack.runWith([0, data]); + } + }, fail: function (data) { + if (data) + callBack != null && callBack.runWith([1, data]); + } }); + } + static downOtherFiles(fileUrl, callBack = null, readyUrl = "", isSaveFile = false, isAutoClear = true) { + MiniFileMgr.wxdown({ url: fileUrl, success: function (data) { + if (!data.hasOwnProperty("statusCode")) + data.statusCode = 200; + if (data.statusCode === 200) { + if (isSaveFile && readyUrl.indexOf(".php") == -1) { + callBack != null && callBack.runWith([0, data.apFilePath]); + MiniFileMgr.copyTOCache(data.apFilePath, readyUrl, null, "", isAutoClear); + } + else + callBack != null && callBack.runWith([0, data.apFilePath]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + console.log("downloadfile fail:", readyUrl, data); + callBack != null && callBack.runWith([1, data]); + } }); + } + static copyFile(src, dest, complete = null) { + MiniFileMgr.fs.copyFile({ + srcPath: src, + destPath: dest, + success: function () { + complete && complete.runWith(0); + }, + fail: function (err) { + complete && complete.runWith([1, err]); + } + }); + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8", cacheFile = false) { + if (window.navigator.userAgent.indexOf('AlipayMiniGame') < 0) { + Laya.Laya.loader.load(fileUrl, callBack); + } + else { + if (fileType == Laya.Loader.IMAGE || fileType == Laya.Loader.SOUND) + MiniFileMgr.downOtherFiles(TBMiniAdapter.safeEncodeURI(fileUrl), callBack, fileUrl, cacheFile, false); + else + MiniFileMgr.downFiles(TBMiniAdapter.safeEncodeURI(fileUrl), encoding, callBack, fileUrl, true, fileType, cacheFile); + } + } + static copyTOCache(tempFilePath, readyUrl, callBack, encoding = "", isAutoClear = true) { + var temp = tempFilePath.split("/"); + var tempFileName = temp[temp.length - 1]; + var fileurlkey = readyUrl; + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fakeObj[fileurlkey] = { md5: tempFileName, readyUrl: readyUrl, size: 0, times: Laya.Browser.now(), encoding: encoding, tempFilePath: tempFilePath }; + var totalSize = TBMiniAdapter.sizeLimit; + var chaSize = 4 * 1024 * 1024; + var fileUseSize = MiniFileMgr.getCacheUseSize(); + if (fileObj) { + if (fileObj.readyUrl != readyUrl) { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > TBMiniAdapter.minClearSize) + TBMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.deleteFile(tempFilePath, readyUrl, callBack, encoding, data.size); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + else + callBack != null && callBack.runWith([0]); + } + else { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > TBMiniAdapter.minClearSize) + TBMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.fs.copyFile({ srcPath: tempFilePath, destPath: saveFilePath, success: function (data2) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, data.size); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + } + static onClearCacheRes() { + var memSize = TBMiniAdapter.minClearSize; + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + MiniFileMgr.sortOn(tempFileListArr, "times", MiniFileMgr.NUMERIC); + var clearSize = 0; + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + if (clearSize >= memSize) + break; + clearSize += fileObj.size; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + } + static sortOn(array, name, options = 0) { + if (options == MiniFileMgr.NUMERIC) + return array.sort(function (a, b) { return a[name] - b[name]; }); + if (options == (MiniFileMgr.NUMERIC | MiniFileMgr.DESCENDING)) + return array.sort(function (a, b) { return b[name] - a[name]; }); + return array.sort(function (a, b) { return a[name] - b[name]; }); + } + static getFileNativePath(fileName) { + return MiniFileMgr.fileNativeDir + "/" + fileName; + } + static deleteFile(tempFileName, readyUrl = "", callBack = null, encoding = "", fileSize = 0) { + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var deleteFileUrl = MiniFileMgr.getFileNativePath(fileObj.md5); + MiniFileMgr.fs.unlink({ filePath: deleteFileUrl, success: function (data) { + if (tempFileName != "") { + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fs.copyFile({ srcPath: tempFileName, destPath: saveFilePath, success: function (data) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, fileSize); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + else { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, false, encoding, callBack, fileSize); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static deleteAll() { + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj.fileUsedSize) { + MiniFileMgr.filesListObj.fileUsedSize = 0; + } + MiniFileMgr.writeFilesList("", JSON.stringify({}), false); + } + static onSaveFile(readyUrl, md5Name, isAdd = true, encoding = "", callBack = null, fileSize = 0) { + var fileurlkey = readyUrl; + if (MiniFileMgr.filesListObj['fileUsedSize'] == null) + MiniFileMgr.filesListObj['fileUsedSize'] = 0; + if (isAdd) { + var fileNativeName = MiniFileMgr.getFileNativePath(md5Name); + MiniFileMgr.filesListObj[fileurlkey] = { md5: md5Name, readyUrl: readyUrl, size: fileSize, times: Laya.Browser.now(), encoding: encoding, tempFilePath: fileNativeName }; + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) + fileSize; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), true); + callBack != null && callBack.runWith([0]); + } + else { + if (MiniFileMgr.filesListObj[fileurlkey]) { + var deletefileSize = parseInt(MiniFileMgr.filesListObj[fileurlkey].size); + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) - deletefileSize; + if (MiniFileMgr.fakeObj[fileurlkey].md5 == MiniFileMgr.filesListObj[fileurlkey].md5) { + delete MiniFileMgr.fakeObj[fileurlkey]; + } + delete MiniFileMgr.filesListObj[fileurlkey]; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), false); + callBack != null && callBack.runWith([0]); + } + } + } + static writeFilesList(fileurlkey, filesListStr, isAdd) { + var listFilesPath = MiniFileMgr.fileNativeDir + "/" + MiniFileMgr.fileListName; + MiniFileMgr.fs.writeFile({ filePath: listFilesPath, encoding: 'utf8', data: filesListStr, success: function (data) { + }, fail: function (data) { + } }); + if (!TBMiniAdapter.isZiYu && TBMiniAdapter.isPosMsgYu && TBMiniAdapter.window.my.postMessage) { + TBMiniAdapter.window.my.postMessage({ url: fileurlkey, data: MiniFileMgr.filesListObj[fileurlkey], isLoad: "filenative", isAdd: isAdd }); + } + } + static getCacheUseSize() { + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj['fileUsedSize']) + return MiniFileMgr.filesListObj['fileUsedSize']; + return 0; + } + static getCacheList(dirPath, cb) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(dirPath); + } + catch (err) { + stat = null; + } + if (stat) { + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", cb); + } + else { + MiniFileMgr.fs.mkdirSync(dirPath, true); + cb && cb.runWith([1]); + } + } + static existDir(dirPath, callBack) { + MiniFileMgr.fs.mkdir({ dirPath: dirPath, success: function (data) { + callBack != null && callBack.runWith([0, { data: JSON.stringify({}) }]); + }, fail: function (data) { + if (data.error == 10025) + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", callBack); + else + callBack != null && callBack.runWith([1, data]); + } }); + } + static readSync(filePath, encoding = "utf8", callBack = null, readyUrl = "") { + var fileUrl = MiniFileMgr.getFileNativePath(filePath); + var filesListStr; + try { + MiniFileMgr.fs.readFile({ + filePath: fileUrl, + encoding: encoding, + success: function (data) { + filesListStr = data.data; + callBack != null && callBack.runWith([0, { data: filesListStr }]); + }, + fail: function () { + callBack != null && callBack.runWith([1]); + } + }); + } + catch (error) { + callBack != null && callBack.runWith([1]); + } + } + static setNativeFileDir(value) { + MiniFileMgr.fileNativeDir = TBMiniAdapter.window.my.env.USER_DATA_PATH + value; + } + } + MiniFileMgr.fs = window.my.getFileSystemManager(); + MiniFileMgr.wxdown = window.my.downloadFile; + MiniFileMgr.filesListObj = {}; + MiniFileMgr.fakeObj = {}; + MiniFileMgr.fileListName = "layaairfiles.txt"; + MiniFileMgr.ziyuFileData = {}; + MiniFileMgr.ziyuFileTextureData = {}; + MiniFileMgr.loadPath = ""; + MiniFileMgr.DESCENDING = 2; + MiniFileMgr.NUMERIC = 16; + + class MiniSoundChannel extends Laya.SoundChannel { + constructor(sound) { + super(); + this._sound = sound; + this._audio = sound._sound; + this._onCanplay = this.onCanPlay.bind(this); + this._onError = this.onError.bind(this); + this._onEnd = this.__onEnd.bind(this); + this.addEventListener(); + } + addEventListener() { + this._audio.onError(this._onError); + this._audio.onCanplay(this._onCanplay); + } + offEventListener() { + this._audio.offError(this._onError); + this._audio.offCanplay(this._onCanplay); + this._audio.offEnded(this._onEnd); + } + onError(error) { + console.log("-----1---------------minisound-----url:", this.url); + console.log(error); + this.event(Laya.Event.ERROR); + if (!this._audio) + return; + this._sound.dispose(); + this.offEventListener(); + this._sound = this._audio = null; + } + onCanPlay() { + if (!this._audio) + return; + this.event(Laya.Event.COMPLETE); + this.offEventListener(); + this._audio.onEnded(this._onEnd); + if (!this.isStopped) { + this.play(); + } + else { + this.stop(); + } + } + __onEnd() { + if (this.loops == 1) { + if (this.completeHandler) { + Laya.Laya.systemTimer.once(10, this, this.__runComplete, [this.completeHandler], false); + this.completeHandler = null; + } + this.stop(); + this.event(Laya.Event.COMPLETE); + return; + } + if (this.loops > 0) { + this.loops--; + } + this.startTime = 0; + this.play(); + } + play() { + this.isStopped = false; + Laya.SoundManager.addChannel(this); + if (!this._audio) + return; + this._audio.play(); + } + set startTime(time) { + if (!this._audio) + return; + this._audio.startTime = time; + } + set autoplay(value) { + if (!this._audio) + return; + this._audio.autoplay = value; + } + get autoplay() { + if (!this._audio) + return false; + return this._audio.autoplay; + } + get position() { + if (!this._audio) + return 0; + return this._audio.currentTime; + } + get duration() { + if (!this._audio) + return 0; + return this._audio.duration; + } + stop() { + super.stop(); + this.isStopped = true; + Laya.SoundManager.removeChannel(this); + this.completeHandler = null; + if (!this._audio) + return; + this._audio.stop(); + if (!this.loop) { + this.offEventListener(); + this._sound.dispose(); + this._sound = null; + this._audio = null; + } + } + pause() { + this.isStopped = true; + if (!this._audio) + return; + this._audio.pause(); + } + get loop() { + if (!this._audio) + return false; + return this._audio.loop; + } + set loop(value) { + if (!this._audio) + return; + this._audio.loop = value; + } + resume() { + this.isStopped = false; + Laya.SoundManager.addChannel(this); + if (!this._audio) + return; + this._audio.play(); + } + set volume(v) { + if (!this._audio) + return; + this._audio.volume = v; + } + get volume() { + if (!this._audio) + return 0; + return this._audio.volume; + } + } + + class MiniSound extends Laya.EventDispatcher { + constructor() { + super(); + this.loaded = false; + this._sound = MiniSound._createSound(); + } + static __init__() { + for (let index = 0; index < 10; index++) { + let s = TBMiniAdapter.window.my.createInnerAudioContext(); + MiniSound.cachePool.push(s); + } + } + static _createSound() { + if (MiniSound.cachePool.length) { + return MiniSound.cachePool.pop(); + } + else { + return TBMiniAdapter.window.my.createInnerAudioContext(); + } + } + load(url) { + if (!MiniFileMgr.isLocalNativeFile(url)) { + url = Laya.URL.formatURL(url); + } + else { + if (url.indexOf(TBMiniAdapter.window.my.env.USER_DATA_PATH) == -1 && (url.indexOf("http://") != -1 || url.indexOf("https://") != -1)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + if (tempStr != "") + url = url.split(tempStr)[1]; + } + } + } + this.url = url; + this.readyUrl = url; + if (TBMiniAdapter.autoCacheFile && MiniFileMgr.getFileInfo(url)) { + this.onDownLoadCallBack(url, 0); + } + else { + if (!TBMiniAdapter.autoCacheFile) { + this.onDownLoadCallBack(url, 0); + } + else { + if (MiniFileMgr.isLocalNativeFile(url)) { + if (TBMiniAdapter.subNativeFiles && TBMiniAdapter.subNativeheads.length == 0) { + for (var key in TBMiniAdapter.subNativeFiles) { + var tempArr = TBMiniAdapter.subNativeFiles[key]; + TBMiniAdapter.subNativeheads = TBMiniAdapter.subNativeheads.concat(tempArr); + for (let i = 0; i < tempArr.length; i++) { + TBMiniAdapter.subMaps[tempArr[i]] = key + "/" + tempArr[i]; + } + } + } + if (TBMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && TBMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = TBMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + this.onDownLoadCallBack(url, 0); + } + else { + if ((url.indexOf("http://") == -1 && url.indexOf("https://") == -1) + || url.indexOf(TBMiniAdapter.window.my.env.USER_DATA_PATH) != -1) { + this.onDownLoadCallBack(url, 0); + } + else { + MiniFileMgr.downOtherFiles(url, Laya.Handler.create(this, this.onDownLoadCallBack, [url]), url, TBMiniAdapter.autoCacheFile); + } + } + } + } + } + onDownLoadCallBack(sourceUrl, errorCode, tempFilePath = null) { + if (!errorCode && this._sound) { + var fileNativeUrl; + if (TBMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = sourceUrl; + if (tempStr != "" && (sourceUrl.indexOf("http://") != -1 || sourceUrl.indexOf("https://") != -1)) + fileNativeUrl = sourceUrl.split(tempStr)[1]; + if (!fileNativeUrl) { + fileNativeUrl = tempUrl; + } + if (MiniFileMgr.isSubNativeFile(fileNativeUrl)) { + fileNativeUrl = fileNativeUrl; + } + else + fileNativeUrl = TBMiniAdapter.baseDir + fileNativeUrl; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + var fileMd5Name = fileObj.md5; + fileNativeUrl = MiniFileMgr.getFileNativePath(fileMd5Name); + } + else { + if (sourceUrl.indexOf("http://") == -1 + && sourceUrl.indexOf("https://") == -1 + && sourceUrl.indexOf(TBMiniAdapter.window.my.env.USER_DATA_PATH) == -1) { + fileNativeUrl = TBMiniAdapter.baseDir + sourceUrl; + } + else { + fileNativeUrl = sourceUrl; + } + } + } + } + else { + fileNativeUrl = tempFilePath; + } + this._sound.src = this.readyUrl = fileNativeUrl; + } + else { + if (MiniFileMgr.isLocalNativeFile(sourceUrl) || + (sourceUrl.indexOf("http://") == -1 + && sourceUrl.indexOf("https://") == -1 + && sourceUrl.indexOf(TBMiniAdapter.window.my.env.USER_DATA_PATH) == -1 + && !MiniFileMgr.isSubNativeFile(fileNativeUrl))) { + sourceUrl = TBMiniAdapter.baseDir + sourceUrl; + } + this._sound.src = this.readyUrl = sourceUrl; + } + } + else { + this.event(Laya.Event.ERROR); + } + } + play(startTime = 0, loops = 0) { + if (!this.url) + return null; + var channel = new MiniSoundChannel(this); + channel.url = this.url; + channel.loops = loops; + channel.loop = (loops === 0 ? true : false); + channel.startTime = startTime; + channel.isStopped = false; + Laya.SoundManager.addChannel(channel); + return channel; + } + get duration() { + return this._sound.duration; + } + dispose() { + if (this._sound) { + MiniSound.cachePool.push(this._sound); + this._sound = null; + this.readyUrl = this.url = null; + } + } + } + MiniSound.cachePool = []; + + class MiniInput { + constructor() { + } + static _createInputElement() { + Laya.Input['_initInput'](Laya.Input['area'] = Laya.Browser.createElement("textarea")); + Laya.Input['_initInput'](Laya.Input['input'] = Laya.Browser.createElement("input")); + Laya.Input['inputContainer'] = Laya.Browser.createElement("div"); + Laya.Input['inputContainer'].style.position = "absolute"; + Laya.Input['inputContainer'].style.zIndex = 1E5; + Laya.Browser.container.appendChild(Laya.Input['inputContainer']); + Laya.SoundManager._soundClass = MiniSound; + Laya.SoundManager._musicClass = MiniSound; + var model = TBMiniAdapter.systemInfo.model; + var system = TBMiniAdapter.systemInfo.system; + if (model.indexOf("iPhone") != -1) { + Laya.Browser.onIPhone = true; + Laya.Browser.onIOS = true; + Laya.Browser.onIPad = true; + Laya.Browser.onAndroid = false; + } + if (system.indexOf("Android") != -1 || system.indexOf("Adr") != -1) { + Laya.Browser.onAndroid = true; + Laya.Browser.onIPhone = false; + Laya.Browser.onIOS = false; + Laya.Browser.onIPad = false; + } + } + static _onStageResize() { + var ts = Laya.Laya.stage._canvasTransform.identity(); + ts.scale((Laya.Browser.width / Laya.Render.canvas.width / Laya.Browser.pixelRatio), Laya.Browser.height / Laya.Render.canvas.height / Laya.Browser.pixelRatio); + } + static wxinputFocus(e) { + return; + } + static inputEnter() { + Laya.Input['inputElement'].target.focus = false; + } + static wxinputblur() { + MiniInput.hideKeyboard(); + } + static hideKeyboard() { + return; + } + } + + class MiniLoader extends Laya.EventDispatcher { + constructor() { + super(); + } + _loadResourceFilter(type, url) { + var thisLoader = this; + this.sourceUrl = Laya.URL.formatURL(url); + if (MiniFileMgr.isNetFile(url)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (TBMiniAdapter.subNativeFiles && TBMiniAdapter.subNativeheads.length == 0) { + for (var key in TBMiniAdapter.subNativeFiles) { + var tempArr = TBMiniAdapter.subNativeFiles[key]; + TBMiniAdapter.subNativeheads = TBMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + TBMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (TBMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && TBMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = TBMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + switch (type) { + case Laya.Loader.IMAGE: + case "htmlimage": + case "nativeimage": + MiniLoader._transformImgUrl(url, type, thisLoader); + break; + case Laya.Loader.SOUND: + thisLoader._loadSound(url); + break; + default: + thisLoader._loadResource(type, url); + } + } + _loadSound(url) { + var thisLoader = this; + if (!TBMiniAdapter.autoCacheFile) { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + else { + var tempurl = Laya.URL.formatURL(url); + if (MiniFileMgr.getFileInfo(tempurl)) { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + else { + if (!MiniFileMgr.isLocalNativeFile(url)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downOtherFiles(TBMiniAdapter.safeEncodeURI(tempurl), Laya.Handler.create(MiniLoader, MiniLoader.onDownLoadCallBack, [tempurl, thisLoader]), tempurl, TBMiniAdapter.autoCacheFile); + } + else { + MiniLoader.onDownLoadCallBack(TBMiniAdapter.baseDir + url, thisLoader, 0); + } + } + else { + if (tempurl.indexOf(TBMiniAdapter.window.my.env.USER_DATA_PATH) == -1 && !MiniFileMgr.isSubNativeFile(url)) { + MiniLoader.onDownLoadCallBack(TBMiniAdapter.baseDir + url, thisLoader, 0); + } + else + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + } + } + static onDownLoadCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = null) { + if (!errorCode) { + var fileNativeUrl; + if (TBMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + fileNativeUrl = sourceUrl; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + } + else { + fileNativeUrl = Laya.URL.formatURL(sourceUrl); + } + sourceUrl = fileNativeUrl; + var sound = (new Laya.SoundManager._soundClass()); + sound.load(TBMiniAdapter.safeEncodeURI(sourceUrl)); + thisLoader.onLoaded(sound); + } + else { + thisLoader.event(Laya.Event.ERROR, "Load sound failed"); + } + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + complete(data) { + if (data instanceof Laya.Resource) { + data._setCreateURL(this.sourceUrl); + } + else if ((data instanceof Laya.Texture) && (data.bitmap instanceof Laya.Resource)) { + data.bitmap._setCreateURL(this.sourceUrl); + } + this.originComplete(data); + } + _loadHttpRequestWhat(url, contentType) { + var thisLoader = this; + var encoding = TBMiniAdapter.getUrlEncode(url, contentType); + if (Laya.Loader.preLoadedMap[url]) + thisLoader.onLoaded(Laya.Loader.preLoadedMap[url]); + else { + var tempurl = Laya.URL.formatURL(url); + var fileObj = MiniFileMgr.getFileInfo(tempurl); + if (fileObj) { + fileObj.encoding = fileObj.encoding == null ? "utf8" : fileObj.encoding; + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + MiniFileMgr.readFile(fileNativeUrl, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + else { + if ((tempurl.indexOf("http://") == -1 && tempurl.indexOf("https://") == -1) || MiniFileMgr.isLocalNativeFile(url)) { + if (tempurl.indexOf(TBMiniAdapter.window.my.env.USER_DATA_PATH) == -1 && !MiniFileMgr.isSubNativeFile(url)) { + MiniFileMgr.readFile(TBMiniAdapter.baseDir + url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + else + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + else { + MiniFileMgr.downFiles(TBMiniAdapter.safeEncodeURI(tempurl), encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), tempurl, TBMiniAdapter.AutoCacheDownFile); + } + } + } + } + static onReadNativeCallBack(url, type = null, thisLoader = null, errorCode = 0, data = null) { + if (!errorCode) { + try { + var tempData; + if (type == Laya.Loader.JSON || type == Laya.Loader.ATLAS || type == Laya.Loader.PREFAB || type == Laya.Loader.PLF) { + tempData = TBMiniAdapter.getJson(data.data); + } + else if (type == Laya.Loader.XML) { + tempData = Laya.Utils.parseXMLFromString(data.data); + } + else { + tempData = data.data; + } + thisLoader.onLoaded(tempData); + } + catch (err) { + thisLoader.onError && thisLoader.onError(data); + } + } + else if (errorCode == 1) { + thisLoader.onError && thisLoader.onError(data); + } + } + static _transformImgUrl(url, type, thisLoader) { + let tempurl = Laya.URL.formatURL(url); + if (MiniFileMgr.isLocalNativeFile(url) || (tempurl.indexOf("http://") == -1 && tempurl.indexOf("https://") == -1)) { + if (tempurl.indexOf(TBMiniAdapter.window.my.env.USER_DATA_PATH) == -1) { + MiniLoader.onCreateImage(url, thisLoader, true); + } + else + MiniLoader.onCreateImage(url, thisLoader, false, url); + } + else { + MiniLoader.onCreateImage(url, thisLoader, false, tempurl); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + fileNativeUrl = sourceUrl; + } + } + else { + if (!MiniFileMgr.isSubNativeFile(sourceUrl)) { + fileNativeUrl = TBMiniAdapter.baseDir + sourceUrl; + } + else + fileNativeUrl = sourceUrl; + } + thisLoader._loadImage(TBMiniAdapter.safeEncodeURI(fileNativeUrl), false); + } + } + + class MiniLocalStorage { + constructor() { + } + static __init__() { + MiniLocalStorage.items = MiniLocalStorage; + } + static setItem(key, value) { + TBMiniAdapter.window.my.setStorageSync({ key: key, data: value }); + } + static getItem(key) { + return TBMiniAdapter.window.my.getStorageSync({ "key": key }).data; + } + static setJSON(key, value) { + try { + MiniLocalStorage.setItem(key, JSON.stringify(value)); + } + catch (e) { + console.warn("set localStorage failed", e); + } + } + static getJSON(key) { + return JSON.parse(MiniLocalStorage.getItem(key)); + } + static removeItem(key) { + TBMiniAdapter.window.my.removeStorageSync({ key: key }); + } + static clear() { + TBMiniAdapter.window.my.clearStorageSync(); + } + static getStorageInfoSync() { + try { + var res = TBMiniAdapter.window.my.getStorageInfoSync(); + console.log(res.keys); + console.log(res.currentSize); + console.log(res.limitSize); + return res; + } + catch (e) { + } + return null; + } + } + MiniLocalStorage.support = true; + + class TBMiniAdapter { + static getJson(data) { + return JSON.parse(data); + } + static enable() { + TBMiniAdapter.init(Laya.Laya.isWXPosMsg, Laya.Laya.isWXOpenDataContext); + } + static init(isPosMsg = false, isSon = false) { + if (TBMiniAdapter._inited) + return; + TBMiniAdapter._inited = true; + TBMiniAdapter.window = window; + if (!TBMiniAdapter.window.hasOwnProperty("my")) + return; + TBMiniAdapter.isZiYu = isSon; + TBMiniAdapter.isPosMsgYu = isPosMsg; + TBMiniAdapter.EnvConfig = {}; + if (!TBMiniAdapter.isZiYu) { + MiniFileMgr.setNativeFileDir("/layaairGame"); + MiniFileMgr.getCacheList(MiniFileMgr.fileNativeDir, Laya.Handler.create(TBMiniAdapter, TBMiniAdapter.onMkdirCallBack)); + } + TBMiniAdapter.systemInfo = TBMiniAdapter.window.my.getSystemInfoSync(); + TBMiniAdapter.window.focus = function () { + }; + Laya.Laya['_getUrlPath'] = function () { + return ""; + }; + TBMiniAdapter.window.logtime = function (str) { + }; + TBMiniAdapter.window.alertTimeLog = function (str) { + }; + TBMiniAdapter.window.resetShareInfo = function () { + }; + TBMiniAdapter.window.CanvasRenderingContext2D = function () { + }; + Laya.HttpRequest._urlEncode = TBMiniAdapter.safeEncodeURI; + TBMiniAdapter._preCreateElement = Laya.Browser.createElement; + TBMiniAdapter.window.CanvasRenderingContext2D.prototype = TBMiniAdapter._preCreateElement("canvas").getContext('2d').__proto__; + TBMiniAdapter.window.document.body.appendChild = function () { + }; + Laya.Browser["createElement"] = TBMiniAdapter.createElement; + Laya.RunDriver.createShaderCondition = TBMiniAdapter.createShaderCondition; + Laya.Utils['parseXMLFromString'] = TBMiniAdapter.parseXMLFromString; + Laya.Input['_createInputElement'] = MiniInput['_createInputElement']; + if (!window.ImageData) { + window.ImageData = ImageDataPolyfill; + } + Laya.Loader.prototype._loadResourceFilter = MiniLoader.prototype._loadResourceFilter; + Laya.Loader.prototype._loadSound = MiniLoader.prototype._loadSound; + Laya.Loader.prototype.originComplete = Laya.Loader.prototype.complete; + Laya.Loader.prototype.complete = MiniLoader.prototype.complete; + Laya.Loader.prototype._loadHttpRequestWhat = MiniLoader.prototype._loadHttpRequestWhat; + Laya.Config.useRetinalCanvas = true; + Laya.LocalStorage._baseClass = MiniLocalStorage; + MiniLocalStorage.__init__(); + MiniSound.__init__(); + TBMiniAdapter.window.my.onMessage && TBMiniAdapter.window.my.onMessage(TBMiniAdapter._onMessage); + } + static _onMessage(data) { + switch (data.type) { + case "changeMatrix": + Laya.Laya.stage.transform.identity(); + Laya.Laya.stage._width = data.w; + Laya.Laya.stage._height = data.h; + Laya.Laya.stage._canvasTransform = new Laya.Matrix(data.a, data.b, data.c, data.d, data.tx, data.ty); + break; + case "display": + Laya.Laya.stage.frameRate = data.rate || Laya.Stage.FRAME_FAST; + break; + case "undisplay": + Laya.Laya.stage.frameRate = Laya.Stage.FRAME_SLEEP; + break; + } + if (data['isLoad'] == "opendatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + else if (data['isLoad'] == "openJsondatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + } + } + else if (data['isLoad'] == "openJsondatacontextPic") { + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + static getUrlEncode(url, type) { + if (type == "arraybuffer") + return ""; + return "utf8"; + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + var fileObj = MiniFileMgr.getFileInfo(fileUrl); + if (!fileObj) + MiniFileMgr.downLoadFile(TBMiniAdapter.safeEncodeURI(fileUrl), fileType, callBack, encoding); + else { + callBack != null && callBack.runWith([0]); + } + } + static remove(fileUrl, callBack = null) { + MiniFileMgr.deleteFile("", fileUrl, callBack, "", 0); + } + static removeAll() { + MiniFileMgr.deleteAll(); + } + static hasNativeFile(fileUrl) { + return MiniFileMgr.isLocalNativeFile(fileUrl); + } + static getFileInfo(fileUrl) { + return MiniFileMgr.getFileInfo(fileUrl); + } + static getFileList() { + return MiniFileMgr.filesListObj; + } + static exitMiniProgram() { + TBMiniAdapter.window.my.exitMiniProgram(); + } + static onMkdirCallBack(errorCode, data) { + if (!errorCode) { + MiniFileMgr.filesListObj = JSON.parse(data.data); + MiniFileMgr.fakeObj = JSON.parse(data.data) || {}; + } + else { + MiniFileMgr.fakeObj = {}; + MiniFileMgr.filesListObj = {}; + } + let files = MiniFileMgr.fs.readdirSync(MiniFileMgr.fileNativeDir); + if (!files || !files.length) + return; + var tempMd5ListObj = {}; + var fileObj; + for (let key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") { + fileObj = MiniFileMgr.filesListObj[key]; + tempMd5ListObj[fileObj.md5] = fileObj.readyUrl; + } + } + var fileName; + for (let i = 0, sz = files.length; i < sz; i++) { + fileName = files[i]; + if (fileName == MiniFileMgr.fileListName) + continue; + if (!tempMd5ListObj[fileName]) { + let deleteFileUrl = MiniFileMgr.getFileNativePath(fileName); + MiniFileMgr.fs.unlink({ + filePath: deleteFileUrl, + success: function (data) { + console.log("删除无引用的磁盘文件:" + fileName); + } + }); + } + delete tempMd5ListObj[fileName]; + } + for (let key in tempMd5ListObj) { + delete MiniFileMgr.filesListObj[tempMd5ListObj[key]]; + delete MiniFileMgr.fakeObj[tempMd5ListObj[key]]; + console.log("删除错误记录:", tempMd5ListObj[key]); + } + } + static pixelRatio() { + if (!TBMiniAdapter.EnvConfig.pixelRatioInt) { + try { + TBMiniAdapter.EnvConfig.pixelRatioInt = TBMiniAdapter.systemInfo.pixelRatio; + return TBMiniAdapter.systemInfo.pixelRatio; + } + catch (error) { + } + } + return TBMiniAdapter.EnvConfig.pixelRatioInt; + } + static createElement(type) { + if (type == "canvas") { + var _source; + if (TBMiniAdapter.idx == 1) { + _source = TBMiniAdapter.window.canvas.getRealCanvas(); + if (!my.isIDE) { + var originfun = _source.getContext; + _source.getContext = function (type) { + var gl = originfun.apply(_source, [type]); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + return gl; + }; + } + } + else { + _source = TBMiniAdapter._preCreateElement(type); + } + (!_source.style) && (_source.style = {}); + TBMiniAdapter.idx++; + return _source; + } + else if (type == "textarea" || type == "input") { + return TBMiniAdapter.onCreateInput(type); + } + else if (type == "div") { + var node = TBMiniAdapter._preCreateElement(type); + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + else { + return TBMiniAdapter._preCreateElement(type); + } + } + static onCreateInput(type) { + var node = TBMiniAdapter._preCreateElement(type); + node.focus = MiniInput.wxinputFocus; + node.blur = MiniInput.wxinputblur; + node.value = 0; + node.placeholder = {}; + node.type = {}; + node.setColor = function (value) { + }; + node.setType = function (value) { + }; + node.setFontFace = function (value) { + }; + node.contains = function (value) { + return null; + }; + return node; + } + static createShaderCondition(conditionScript) { + var func = function () { + return this[conditionScript.replace("this.", "")]; + }; + return func; + } + } + TBMiniAdapter.IGNORE = new RegExp("[-_.!~*'();/?:@&=+$,#%]|[0-9|A-Z|a-z]"); + TBMiniAdapter.safeEncodeURI = function (str) { + var strTemp = ""; + var length = str.length; + for (var i = 0; i < length; i++) { + var word = str[i]; + if (TBMiniAdapter.IGNORE.test(word)) { + strTemp += word; + } + else { + try { + strTemp += encodeURI(word); + } + catch (e) { + console.log("errorInfo", ">>>" + word); + } + } + } + return strTemp; + }; + TBMiniAdapter._inited = false; + TBMiniAdapter.autoCacheFile = true; + TBMiniAdapter.minClearSize = (5 * 1024 * 1024); + TBMiniAdapter.sizeLimit = (50 * 1024 * 1024); + TBMiniAdapter.nativefiles = ["layaNativeDir"]; + TBMiniAdapter.subNativeFiles = {}; + TBMiniAdapter.subNativeheads = []; + TBMiniAdapter.subMaps = []; + TBMiniAdapter.AutoCacheDownFile = false; + TBMiniAdapter.baseDir = "pages/index/"; + TBMiniAdapter.parseXMLFromString = function (value) { + var rst; + value = value.replace(/>\s+<'); + try { + rst = (new TBMiniAdapter.window.Parser.DOMParser()).parseFromString(value, 'text/xml'); + } + catch (error) { + throw "需要引入xml解析库文件"; + } + return rst; + }; + TBMiniAdapter.idx = 1; + + class MiniAccelerator extends Laya.EventDispatcher { + constructor() { + super(); + } + static __init__() { + try { + var Acc; + Acc = Laya.Accelerator; + if (!Acc) + return; + Acc["prototype"]["on"] = MiniAccelerator["prototype"]["on"]; + Acc["prototype"]["off"] = MiniAccelerator["prototype"]["off"]; + } + catch (e) { + } + } + static startListen(callBack) { + MiniAccelerator._callBack = callBack; + if (MiniAccelerator._isListening) + return; + MiniAccelerator._isListening = true; + try { + TBMiniAdapter.window.my.onAccelerometerChange(MiniAccelerator.onAccelerometerChange); + } + catch (e) { } + } + static stopListen() { + MiniAccelerator._isListening = false; + try { + TBMiniAdapter.window.my.stopAccelerometer({}); + } + catch (e) { } + } + static onAccelerometerChange(res) { + var e; + e = {}; + e.acceleration = res; + e.accelerationIncludingGravity = res; + e.rotationRate = {}; + if (MiniAccelerator._callBack != null) { + MiniAccelerator._callBack(e); + } + } + on(type, caller, listener, args = null) { + super.on(type, caller, listener, args); + MiniAccelerator.startListen(this["onDeviceOrientationChange"]); + return this; + } + off(type, caller, listener, onceOnly = false) { + if (!this.hasListener(type)) + MiniAccelerator.stopListen(); + return super.off(type, caller, listener, onceOnly); + } + } + MiniAccelerator._isListening = false; + + class MiniLocation { + constructor() { + } + static __init__() { + TBMiniAdapter.window.navigator.geolocation.getCurrentPosition = MiniLocation.getCurrentPosition; + TBMiniAdapter.window.navigator.geolocation.watchPosition = MiniLocation.watchPosition; + TBMiniAdapter.window.navigator.geolocation.clearWatch = MiniLocation.clearWatch; + } + static getCurrentPosition(success = null, error = null, options = null) { + var paramO; + paramO = {}; + paramO.success = getSuccess; + paramO.fail = error; + TBMiniAdapter.window.my.getLocation(paramO); + function getSuccess(res) { + if (success != null) { + success(res); + } + } + } + static watchPosition(success = null, error = null, options = null) { + MiniLocation._curID++; + var curWatchO; + curWatchO = {}; + curWatchO.success = success; + curWatchO.error = error; + MiniLocation._watchDic[MiniLocation._curID] = curWatchO; + Laya.Laya.systemTimer.loop(1000, null, MiniLocation._myLoop); + return MiniLocation._curID; + } + static clearWatch(id) { + delete MiniLocation._watchDic[id]; + if (!MiniLocation._hasWatch()) { + Laya.Laya.systemTimer.clear(null, MiniLocation._myLoop); + } + } + static _hasWatch() { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key]) + return true; + } + return false; + } + static _myLoop() { + MiniLocation.getCurrentPosition(MiniLocation._mySuccess, MiniLocation._myError); + } + static _mySuccess(res) { + var rst = {}; + rst.coords = res; + rst.timestamp = Laya.Browser.now(); + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].success) { + MiniLocation._watchDic[key].success(rst); + } + } + } + static _myError(res) { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].error) { + MiniLocation._watchDic[key].error(res); + } + } + } + } + MiniLocation._watchDic = {}; + MiniLocation._curID = 0; + + class MiniVideo { + constructor(width = 320, height = 240) { + this.videoend = false; + this.videourl = ""; + this.videoElement = TBMiniAdapter.window.my.createVideo({ width: width, height: height, autoplay: true }); + } + static __init__() { + } + on(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.onPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.onEnded = this.onEndedFunction.bind(this); + } + this.videoElement.onTimeUpdate = this.onTimeUpdateFunc.bind(this); + } + onTimeUpdateFunc(data) { + this.position = data.position; + this._duration = data.duration; + } + get duration() { + return this._duration; + } + onPlayFunction() { + if (this.videoElement) + this.videoElement.readyState = 200; + console.log("=====视频加载完成========"); + this.onPlayFunc != null && this.onPlayFunc(); + } + onEndedFunction() { + if (!this.videoElement) + return; + this.videoend = true; + console.log("=====视频播放完毕========"); + this.onEndedFunC != null && this.onEndedFunC(); + } + off(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.offPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.offEnded = this.onEndedFunction.bind(this); + } + } + load(url) { + if (!this.videoElement) + return; + this.videoElement.src = url; + } + play() { + if (!this.videoElement) + return; + this.videoend = false; + this.videoElement.play(); + } + pause() { + if (!this.videoElement) + return; + this.videoend = true; + this.videoElement.pause(); + } + get currentTime() { + if (!this.videoElement) + return 0; + return this.videoElement.initialTime; + } + set currentTime(value) { + if (!this.videoElement) + return; + this.videoElement.initialTime = value; + } + get videoWidth() { + if (!this.videoElement) + return 0; + return this.videoElement.width; + } + get videoHeight() { + if (!this.videoElement) + return 0; + return this.videoElement.height; + } + get ended() { + return this.videoend; + } + get loop() { + if (!this.videoElement) + return false; + return this.videoElement.loop; + } + set loop(value) { + if (!this.videoElement) + return; + this.videoElement.loop = value; + } + get playbackRate() { + if (!this.videoElement) + return 0; + return this.videoElement.playbackRate; + } + set playbackRate(value) { + if (!this.videoElement) + return; + this.videoElement.playbackRate = value; + } + get muted() { + if (!this.videoElement) + return false; + return this.videoElement.muted; + } + set muted(value) { + if (!this.videoElement) + return; + this.videoElement.muted = value; + } + get paused() { + if (!this.videoElement) + return false; + return this.videoElement.paused; + } + size(width, height) { + if (!this.videoElement) + return; + this.videoElement.width = width; + this.videoElement.height = height; + } + get x() { + if (!this.videoElement) + return 0; + return this.videoElement.x; + } + set x(value) { + if (!this.videoElement) + return; + this.videoElement.x = value; + } + get y() { + if (!this.videoElement) + return 0; + return this.videoElement.y; + } + set y(value) { + if (!this.videoElement) + return; + this.videoElement.y = value; + } + get currentSrc() { + return this.videoElement.src; + } + destroy() { + if (this.videoElement) + this.videoElement.destroy(); + this.videoElement = null; + this.onEndedFunC = null; + this.onPlayFunc = null; + this.videoend = false; + this.videourl = null; + } + reload() { + if (!this.videoElement) + return; + this.videoElement.src = this.videourl; + } + } + + exports.ImageDataPolyfill = ImageDataPolyfill; + exports.MiniAccelerator = MiniAccelerator; + exports.MiniFileMgr = MiniFileMgr; + exports.MiniInput = MiniInput; + exports.MiniLoader = MiniLoader; + exports.MiniLocalStorage = MiniLocalStorage; + exports.MiniLocation = MiniLocation; + exports.MiniSound = MiniSound; + exports.MiniSoundChannel = MiniSoundChannel; + exports.MiniVideo = MiniVideo; + exports.TBMiniAdapter = TBMiniAdapter; + +} diff --git a/examples/layaair/frontend/bin/libs/laya.tbpluginmini.js b/examples/layaair/frontend/bin/libs/laya.tbpluginmini.js new file mode 100644 index 0000000..ca7bc70 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.tbpluginmini.js @@ -0,0 +1,1458 @@ +window.tbMiniGame = function (exports, Laya) { + 'use strict'; + + function ImageDataPolyfill() { + let width, height, data; + if (arguments.length == 3) { + if (arguments[0] instanceof Uint8ClampedArray) { + if (arguments[0].length % 4 !== 0) { + throw new Error("Failed to construct 'ImageData': The input data length is not a multiple of 4."); + } + if (arguments[0].length !== arguments[1] * arguments[2] * 4) { + throw new Error("Failed to construct 'ImageData': The input data length is not equal to (4 * width * height)."); + } + else { + data = arguments[0]; + width = arguments[1]; + height = arguments[2]; + } + } + else { + throw new Error("Failed to construct 'ImageData': parameter 1 is not of type 'Uint8ClampedArray'."); + } + } + else if (arguments.length == 2) { + width = arguments[0]; + height = arguments[1]; + data = new Uint8ClampedArray(arguments[0] * arguments[1] * 4); + } + else if (arguments.length < 2) { + throw new Error("Failed to construct 'ImageData': 2 arguments required, but only " + arguments.length + " present."); + } + let imgdata = Laya.Browser.canvas.getContext("2d").getImageData(0, 0, width, height); + for (let i = 0; i < data.length; i += 4) { + imgdata.data[i] = data[i]; + imgdata.data[i + 1] = data[i + 1]; + imgdata.data[i + 2] = data[i + 2]; + imgdata.data[i + 3] = data[i + 3]; + } + return imgdata; + } + + class MiniFileMgr { + static isLocalNativeFile(url) { + for (var i = 0, sz = TBMiniAdapter.nativefiles.length; i < sz; i++) { + if (url.indexOf(TBMiniAdapter.nativefiles[i]) != -1) + return true; + } + return false; + } + static isNetFile(url) { + return (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) && url.indexOf(TBMiniAdapter.window.my.env.USER_DATA_PATH) == -1; + } + static getFileInfo(fileUrl) { + var fileNativePath = fileUrl; + var fileObj = MiniFileMgr.fakeObj[fileNativePath]; + if (fileObj == null) + return null; + else + return fileObj; + } + static read(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "") { + var fileUrl; + if (readyUrl != "" && (readyUrl.indexOf("http://") != -1 || readyUrl.indexOf("https://") != -1)) { + fileUrl = MiniFileMgr.getFileNativePath(filePath); + } + else { + fileUrl = filePath; + } + fileUrl = Laya.URL.getAdptedFilePath(fileUrl); + MiniFileMgr.fs.readFile({ filePath: fileUrl, encoding: encoding, success: function (data) { + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data && readyUrl != "") + MiniFileMgr.downFiles(TBMiniAdapter.safeEncodeURI(readyUrl), encoding, callBack, readyUrl, isSaveFile, fileType); + else + callBack != null && callBack.runWith([1]); + } }); + } + static isFile(url) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(url); + } + catch (err) { + return false; + } + return stat.isFile(); + } + static downFiles(fileUrl, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + var downloadTask = MiniFileMgr.wxdown({ url: fileUrl, success: function (data) { + if (!data.hasOwnProperty("statusCode")) { + data.statusCode = 200; + } + if (data.statusCode === 200) + MiniFileMgr.readFile(data.apFilePath, encoding, callBack, readyUrl, isSaveFile, fileType, isAutoClear); + else if (data.statusCode === 403) { + callBack != null && callBack.runWith([0, fileUrl]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + console.log("downloadfile fail:", readyUrl, data); + callBack != null && callBack.runWith([1, data]); + } }); + } + static readFile(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + filePath = Laya.URL.getAdptedFilePath(filePath); + MiniFileMgr.fs.readFile({ filePath: filePath, encoding: encoding, success: function (data) { + if (filePath.indexOf(TBMiniAdapter.window.my.env.USER_DATA_PATH) && (filePath.indexOf("http://") != -1 || filePath.indexOf("https://") != -1)) { + if (isSaveFile) { + callBack != null && callBack.runWith([0, data]); + MiniFileMgr.copyTOCache(filePath, readyUrl, null, encoding, isAutoClear); + } + else + callBack != null && callBack.runWith([0, data]); + } + else { + callBack != null && callBack.runWith([0, data]); + } + }, fail: function (data) { + if (data) + callBack != null && callBack.runWith([1, data]); + } }); + } + static downOtherFiles(fileUrl, callBack = null, readyUrl = "", isSaveFile = false, isAutoClear = true) { + MiniFileMgr.wxdown({ url: fileUrl, success: function (data) { + if (!data.hasOwnProperty("statusCode")) + data.statusCode = 200; + if (data.statusCode === 200) { + if (isSaveFile && readyUrl.indexOf(".php") == -1) { + callBack != null && callBack.runWith([0, data.apFilePath]); + MiniFileMgr.copyTOCache(data.apFilePath, readyUrl, null, "", isAutoClear); + } + else + callBack != null && callBack.runWith([0, data.apFilePath]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + console.log("downloadfile fail:", readyUrl, data); + callBack != null && callBack.runWith([1, data]); + } }); + } + static copyFile(src, dest, complete = null) { + MiniFileMgr.fs.copyFile({ + srcPath: src, + destPath: dest, + success: function () { + complete && complete.runWith(0); + }, + fail: function (err) { + complete && complete.runWith([1, err]); + } + }); + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8", cacheFile = false) { + if (window.navigator.userAgent.indexOf('AlipayMiniGame') < 0) { + Laya.Laya.loader.load(fileUrl, callBack); + } + else { + if (fileType == Laya.Loader.IMAGE || fileType == Laya.Loader.SOUND) + MiniFileMgr.downOtherFiles(TBMiniAdapter.safeEncodeURI(fileUrl), callBack, fileUrl, cacheFile, false); + else + MiniFileMgr.downFiles(TBMiniAdapter.safeEncodeURI(fileUrl), encoding, callBack, fileUrl, true, fileType, cacheFile); + } + } + static copyTOCache(tempFilePath, readyUrl, callBack, encoding = "", isAutoClear = true) { + var temp = tempFilePath.split("/"); + var tempFileName = temp[temp.length - 1]; + var fileurlkey = readyUrl; + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fakeObj[fileurlkey] = { md5: tempFileName, readyUrl: readyUrl, size: 0, times: Laya.Browser.now(), encoding: encoding, tempFilePath: tempFilePath }; + var totalSize = TBMiniAdapter.sizeLimit; + var chaSize = 4 * 1024 * 1024; + var fileUseSize = MiniFileMgr.getCacheUseSize(); + if (fileObj) { + if (fileObj.readyUrl != readyUrl) { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > TBMiniAdapter.minClearSize) + TBMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.deleteFile(tempFilePath, readyUrl, callBack, encoding, data.size); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + else + callBack != null && callBack.runWith([0]); + } + else { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > TBMiniAdapter.minClearSize) + TBMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.fs.copyFile({ srcPath: tempFilePath, destPath: saveFilePath, success: function (data2) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, data.size); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + } + static onClearCacheRes() { + var memSize = TBMiniAdapter.minClearSize; + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + MiniFileMgr.sortOn(tempFileListArr, "times", MiniFileMgr.NUMERIC); + var clearSize = 0; + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + if (clearSize >= memSize) + break; + clearSize += fileObj.size; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + } + static sortOn(array, name, options = 0) { + if (options == MiniFileMgr.NUMERIC) + return array.sort(function (a, b) { return a[name] - b[name]; }); + if (options == (MiniFileMgr.NUMERIC | MiniFileMgr.DESCENDING)) + return array.sort(function (a, b) { return b[name] - a[name]; }); + return array.sort(function (a, b) { return a[name] - b[name]; }); + } + static getFileNativePath(fileName) { + return MiniFileMgr.fileNativeDir + "/" + fileName; + } + static deleteFile(tempFileName, readyUrl = "", callBack = null, encoding = "", fileSize = 0) { + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var deleteFileUrl = MiniFileMgr.getFileNativePath(fileObj.md5); + MiniFileMgr.fs.unlink({ filePath: deleteFileUrl, success: function (data) { + if (tempFileName != "") { + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fs.copyFile({ srcPath: tempFileName, destPath: saveFilePath, success: function (data) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, fileSize); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + else { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, false, encoding, callBack, fileSize); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static deleteAll() { + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj.fileUsedSize) { + MiniFileMgr.filesListObj.fileUsedSize = 0; + } + MiniFileMgr.writeFilesList("", JSON.stringify({}), false); + } + static onSaveFile(readyUrl, md5Name, isAdd = true, encoding = "", callBack = null, fileSize = 0) { + var fileurlkey = readyUrl; + if (MiniFileMgr.filesListObj['fileUsedSize'] == null) + MiniFileMgr.filesListObj['fileUsedSize'] = 0; + if (isAdd) { + var fileNativeName = MiniFileMgr.getFileNativePath(md5Name); + MiniFileMgr.filesListObj[fileurlkey] = { md5: md5Name, readyUrl: readyUrl, size: fileSize, times: Laya.Browser.now(), encoding: encoding, tempFilePath: fileNativeName }; + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) + fileSize; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), true); + callBack != null && callBack.runWith([0]); + } + else { + if (MiniFileMgr.filesListObj[fileurlkey]) { + var deletefileSize = parseInt(MiniFileMgr.filesListObj[fileurlkey].size); + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) - deletefileSize; + if (MiniFileMgr.fakeObj[fileurlkey].md5 == MiniFileMgr.filesListObj[fileurlkey].md5) { + delete MiniFileMgr.fakeObj[fileurlkey]; + } + delete MiniFileMgr.filesListObj[fileurlkey]; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), false); + callBack != null && callBack.runWith([0]); + } + } + } + static writeFilesList(fileurlkey, filesListStr, isAdd) { + var listFilesPath = MiniFileMgr.fileNativeDir + "/" + MiniFileMgr.fileListName; + MiniFileMgr.fs.writeFile({ filePath: listFilesPath, encoding: 'utf8', data: filesListStr, success: function (data) { + }, fail: function (data) { + } }); + if (!TBMiniAdapter.isZiYu && TBMiniAdapter.isPosMsgYu && TBMiniAdapter.window.my.postMessage) { + TBMiniAdapter.window.my.postMessage({ url: fileurlkey, data: MiniFileMgr.filesListObj[fileurlkey], isLoad: "filenative", isAdd: isAdd }); + } + } + static getCacheUseSize() { + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj['fileUsedSize']) + return MiniFileMgr.filesListObj['fileUsedSize']; + return 0; + } + static getCacheList(dirPath, cb) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(dirPath); + } + catch (err) { + stat = null; + } + if (stat) { + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", cb); + } + else { + MiniFileMgr.fs.mkdirSync(dirPath, true); + cb && cb.runWith([1]); + } + } + static existDir(dirPath, callBack) { + MiniFileMgr.fs.mkdir({ dirPath: dirPath, success: function (data) { + callBack != null && callBack.runWith([0, { data: JSON.stringify({}) }]); + }, fail: function (data) { + if (data.error == 10025) + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", callBack); + else + callBack != null && callBack.runWith([1, data]); + } }); + } + static readSync(filePath, encoding = "utf8", callBack = null, readyUrl = "") { + var fileUrl = MiniFileMgr.getFileNativePath(filePath); + var filesListStr; + try { + MiniFileMgr.fs.readFile({ + filePath: fileUrl, + encoding: encoding, + success: function (data) { + filesListStr = data.data; + callBack != null && callBack.runWith([0, { data: filesListStr }]); + }, + fail: function () { + callBack != null && callBack.runWith([1]); + } + }); + } + catch (error) { + callBack != null && callBack.runWith([1]); + } + } + static setNativeFileDir(value) { + MiniFileMgr.fileNativeDir = TBMiniAdapter.window.my.env.USER_DATA_PATH + value; + } + } + MiniFileMgr.fs = window.my.getFileSystemManager(); + MiniFileMgr.wxdown = window.my.downloadFile; + MiniFileMgr.filesListObj = {}; + MiniFileMgr.fakeObj = {}; + MiniFileMgr.fileListName = "layaairfiles.txt"; + MiniFileMgr.ziyuFileData = {}; + MiniFileMgr.ziyuFileTextureData = {}; + MiniFileMgr.loadPath = ""; + MiniFileMgr.DESCENDING = 2; + MiniFileMgr.NUMERIC = 16; + + class MiniSoundChannel extends Laya.SoundChannel { + constructor(sound) { + super(); + this._sound = sound; + this._audio = sound._sound; + this._onCanplay = this.onCanPlay.bind(this); + this._onError = this.onError.bind(this); + this._onEnd = this.__onEnd.bind(this); + this.addEventListener(); + } + addEventListener() { + this._audio.onError(this._onError); + this._audio.onCanplay(this._onCanplay); + } + offEventListener() { + this._audio.offError(this._onError); + this._audio.offCanplay(this._onCanplay); + this._audio.offEnded(this._onEnd); + } + onError(error) { + console.log("-----1---------------minisound-----url:", this.url); + console.log(error); + this.event(Laya.Event.ERROR); + if (!this._audio) + return; + this._sound.dispose(); + this.offEventListener(); + this._sound = this._audio = null; + } + onCanPlay() { + if (!this._audio) + return; + this.event(Laya.Event.COMPLETE); + this.offEventListener(); + this._audio.onEnded(this._onEnd); + if (!this.isStopped) { + this.play(); + } + else { + this.stop(); + } + } + __onEnd() { + if (this.loops == 1) { + if (this.completeHandler) { + Laya.Laya.systemTimer.once(10, this, this.__runComplete, [this.completeHandler], false); + this.completeHandler = null; + } + this.stop(); + this.event(Laya.Event.COMPLETE); + return; + } + if (this.loops > 0) { + this.loops--; + } + this.startTime = 0; + this.play(); + } + play() { + this.isStopped = false; + Laya.SoundManager.addChannel(this); + if (!this._audio) + return; + this._audio.play(); + } + set startTime(time) { + if (!this._audio) + return; + this._audio.startTime = time; + } + set autoplay(value) { + if (!this._audio) + return; + this._audio.autoplay = value; + } + get autoplay() { + if (!this._audio) + return false; + return this._audio.autoplay; + } + get position() { + if (!this._audio) + return 0; + return this._audio.currentTime; + } + get duration() { + if (!this._audio) + return 0; + return this._audio.duration; + } + stop() { + super.stop(); + this.isStopped = true; + Laya.SoundManager.removeChannel(this); + this.completeHandler = null; + if (!this._audio) + return; + this._audio.stop(); + if (!this.loop) { + this.offEventListener(); + this._sound.dispose(); + this._sound = null; + this._audio = null; + } + } + pause() { + this.isStopped = true; + if (!this._audio) + return; + this._audio.pause(); + } + get loop() { + if (!this._audio) + return false; + return this._audio.loop; + } + set loop(value) { + if (!this._audio) + return; + this._audio.loop = value; + } + resume() { + this.isStopped = false; + Laya.SoundManager.addChannel(this); + if (!this._audio) + return; + this._audio.play(); + } + set volume(v) { + if (!this._audio) + return; + this._audio.volume = v; + } + get volume() { + if (!this._audio) + return 0; + return this._audio.volume; + } + } + + class MiniSound extends Laya.EventDispatcher { + constructor() { + super(); + this.loaded = false; + this._sound = MiniSound._createSound(); + } + static __init__() { + } + static _createSound() { + return null; + } + load(url) { + this.event(Laya.Event.ERROR, "Not support play sound"); + return; + } + onDownLoadCallBack(sourceUrl, errorCode, tempFilePath = null) { + if (!errorCode && this._sound) { + var fileNativeUrl; + if (TBMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = sourceUrl; + if (tempStr != "" && (sourceUrl.indexOf("http://") != -1 || sourceUrl.indexOf("https://") != -1)) + fileNativeUrl = sourceUrl.split(tempStr)[1]; + if (!fileNativeUrl) { + fileNativeUrl = tempUrl; + } + fileNativeUrl = TBMiniAdapter.baseDir + fileNativeUrl; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + var fileMd5Name = fileObj.md5; + fileNativeUrl = MiniFileMgr.getFileNativePath(fileMd5Name); + } + else { + if (sourceUrl.indexOf("http://") == -1 + && sourceUrl.indexOf("https://") == -1 + && sourceUrl.indexOf(TBMiniAdapter.window.my.env.USER_DATA_PATH) == -1) { + fileNativeUrl = TBMiniAdapter.baseDir + sourceUrl; + } + else { + fileNativeUrl = sourceUrl; + } + } + } + } + else { + fileNativeUrl = tempFilePath; + } + this._sound.src = this.readyUrl = fileNativeUrl; + } + else { + if (MiniFileMgr.isLocalNativeFile(sourceUrl) || + (sourceUrl.indexOf("http://") == -1 + && sourceUrl.indexOf("https://") == -1 + && sourceUrl.indexOf(TBMiniAdapter.window.my.env.USER_DATA_PATH) == -1)) { + sourceUrl = TBMiniAdapter.baseDir + sourceUrl; + } + this._sound.src = this.readyUrl = sourceUrl; + } + } + else { + this.event(Laya.Event.ERROR); + } + } + play(startTime = 0, loops = 0) { + return null; + } + get duration() { + return this._sound.duration; + } + dispose() { + if (this._sound) { + MiniSound.cachePool.push(this._sound); + this._sound = null; + this.readyUrl = this.url = null; + } + } + } + MiniSound.cachePool = []; + + class MiniInput { + constructor() { + } + static _createInputElement() { + Laya.Input['_initInput'](Laya.Input['area'] = Laya.Browser.createElement("textarea")); + Laya.Input['_initInput'](Laya.Input['input'] = Laya.Browser.createElement("input")); + Laya.Input['inputContainer'] = Laya.Browser.createElement("div"); + Laya.Input['inputContainer'].style.position = "absolute"; + Laya.Input['inputContainer'].style.zIndex = 1E5; + Laya.Browser.container.appendChild(Laya.Input['inputContainer']); + Laya.SoundManager._soundClass = MiniSound; + Laya.SoundManager._musicClass = MiniSound; + var model = TBMiniAdapter.systemInfo.model; + var system = TBMiniAdapter.systemInfo.system; + if (model.indexOf("iPhone") != -1) { + Laya.Browser.onIPhone = true; + Laya.Browser.onIOS = true; + Laya.Browser.onIPad = true; + Laya.Browser.onAndroid = false; + } + if (system.indexOf("Android") != -1 || system.indexOf("Adr") != -1) { + Laya.Browser.onAndroid = true; + Laya.Browser.onIPhone = false; + Laya.Browser.onIOS = false; + Laya.Browser.onIPad = false; + } + } + static _onStageResize() { + var ts = Laya.Laya.stage._canvasTransform.identity(); + ts.scale((Laya.Browser.width / Laya.Render.canvas.width / Laya.Browser.pixelRatio), Laya.Browser.height / Laya.Render.canvas.height / Laya.Browser.pixelRatio); + } + static wxinputFocus(e) { + return; + } + static inputEnter() { + Laya.Input['inputElement'].target.focus = false; + } + static wxinputblur() { + MiniInput.hideKeyboard(); + } + static hideKeyboard() { + return; + } + } + + class MiniLoader extends Laya.EventDispatcher { + constructor() { + super(); + } + _loadResourceFilter(type, url) { + var thisLoader = this; + this.sourceUrl = Laya.URL.formatURL(url); + if (MiniFileMgr.isNetFile(url)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (TBMiniAdapter.subNativeFiles && TBMiniAdapter.subNativeheads.length == 0) { + for (var key in TBMiniAdapter.subNativeFiles) { + var tempArr = TBMiniAdapter.subNativeFiles[key]; + TBMiniAdapter.subNativeheads = TBMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + TBMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (TBMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && TBMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = TBMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + switch (type) { + case Laya.Loader.IMAGE: + case "htmlimage": + case "nativeimage": + MiniLoader._transformImgUrl(url, type, thisLoader); + break; + case Laya.Loader.SOUND: + thisLoader._loadSound(url); + break; + default: + thisLoader._loadResource(type, url); + } + } + _loadSound(url) { + thisLoader.event(Laya.Event.ERROR, "not support sound"); + return; + var thisLoader = this; + } + static onDownLoadCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = null) { + if (!errorCode) { + var fileNativeUrl; + if (TBMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + fileNativeUrl = sourceUrl; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + } + else { + fileNativeUrl = Laya.URL.formatURL(sourceUrl); + } + sourceUrl = fileNativeUrl; + var sound = (new Laya.SoundManager._soundClass()); + sound.load(TBMiniAdapter.safeEncodeURI(sourceUrl)); + thisLoader.onLoaded(sound); + } + else { + thisLoader.event(Laya.Event.ERROR, "Load sound failed"); + } + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + complete(data) { + if (data instanceof Laya.Resource) { + data._setCreateURL(this.sourceUrl); + } + else if ((data instanceof Laya.Texture) && (data.bitmap instanceof Laya.Resource)) { + data.bitmap._setCreateURL(this.sourceUrl); + } + this.originComplete(data); + } + _loadHttpRequestWhat(url, contentType) { + var thisLoader = this; + var encoding = TBMiniAdapter.getUrlEncode(url, contentType); + if (Laya.Loader.preLoadedMap[url]) + thisLoader.onLoaded(Laya.Loader.preLoadedMap[url]); + else { + var tempurl = Laya.URL.formatURL(url); + var fileObj = MiniFileMgr.getFileInfo(tempurl); + if (fileObj) { + fileObj.encoding = fileObj.encoding == null ? "utf8" : fileObj.encoding; + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + MiniFileMgr.readFile(fileNativeUrl, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + else { + if ((tempurl.indexOf("http://") == -1 && tempurl.indexOf("https://") == -1) || MiniFileMgr.isLocalNativeFile(url)) { + if (tempurl.indexOf(TBMiniAdapter.window.my.env.USER_DATA_PATH) == -1) { + MiniFileMgr.readFile(TBMiniAdapter.baseDir + url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + else + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + else { + MiniFileMgr.downFiles(TBMiniAdapter.safeEncodeURI(tempurl), encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), tempurl, TBMiniAdapter.AutoCacheDownFile); + } + } + } + } + static onReadNativeCallBack(url, type = null, thisLoader = null, errorCode = 0, data = null) { + if (!errorCode) { + try { + var tempData; + if (type == Laya.Loader.JSON || type == Laya.Loader.ATLAS || type == Laya.Loader.PREFAB || type == Laya.Loader.PLF) { + tempData = TBMiniAdapter.getJson(data.data); + } + else if (type == Laya.Loader.XML) { + tempData = Laya.Utils.parseXMLFromString(data.data); + } + else { + tempData = data.data; + } + thisLoader.onLoaded(tempData); + } + catch (err) { + thisLoader.onError && thisLoader.onError(data); + } + } + else if (errorCode == 1) { + thisLoader.onError && thisLoader.onError(data); + } + } + static _transformImgUrl(url, type, thisLoader) { + let tempurl = Laya.URL.formatURL(url); + if (MiniFileMgr.isLocalNativeFile(url) || (tempurl.indexOf("http://") == -1 && tempurl.indexOf("https://") == -1)) { + if (tempurl.indexOf(TBMiniAdapter.window.my.env.USER_DATA_PATH) == -1) { + MiniLoader.onCreateImage(url, thisLoader, true); + } + else + MiniLoader.onCreateImage(url, thisLoader, false, url); + } + else { + MiniLoader.onCreateImage(url, thisLoader, false, tempurl); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + fileNativeUrl = sourceUrl; + } + } + else + fileNativeUrl = TBMiniAdapter.baseDir + sourceUrl; + thisLoader._loadImage(TBMiniAdapter.safeEncodeURI(fileNativeUrl), false); + } + } + + class MiniLocalStorage { + constructor() { + } + static __init__() { + MiniLocalStorage.items = MiniLocalStorage; + } + static setItem(key, value) { + TBMiniAdapter.window.my.setStorageSync({ key: key, data: value }); + } + static getItem(key) { + return TBMiniAdapter.window.my.getStorageSync({ "key": key }).data; + } + static setJSON(key, value) { + try { + MiniLocalStorage.setItem(key, JSON.stringify(value)); + } + catch (e) { + console.warn("set localStorage failed", e); + } + } + static getJSON(key) { + return JSON.parse(MiniLocalStorage.getItem(key)); + } + static removeItem(key) { + TBMiniAdapter.window.my.removeStorageSync({ key: key }); + } + static clear() { + TBMiniAdapter.window.my.clearStorageSync(); + } + static getStorageInfoSync() { + try { + var res = TBMiniAdapter.window.my.getStorageInfoSync(); + console.log(res.keys); + console.log(res.currentSize); + console.log(res.limitSize); + return res; + } + catch (e) { + } + return null; + } + } + MiniLocalStorage.support = true; + + class TBMiniAdapter { + static getJson(data) { + return JSON.parse(data); + } + static enable() { + TBMiniAdapter.init(Laya.Laya.isWXPosMsg, Laya.Laya.isWXOpenDataContext); + } + static init(isPosMsg = false, isSon = false) { + if (TBMiniAdapter._inited) + return; + TBMiniAdapter._inited = true; + TBMiniAdapter.window = window; + if (!TBMiniAdapter.window.hasOwnProperty("my")) + return; + TBMiniAdapter.isZiYu = isSon; + TBMiniAdapter.isPosMsgYu = isPosMsg; + TBMiniAdapter.EnvConfig = {}; + if (!TBMiniAdapter.isZiYu) { + MiniFileMgr.setNativeFileDir("/layaairGame"); + MiniFileMgr.getCacheList(MiniFileMgr.fileNativeDir, Laya.Handler.create(TBMiniAdapter, TBMiniAdapter.onMkdirCallBack)); + } + TBMiniAdapter.systemInfo = TBMiniAdapter.window.my.getSystemInfoSync(); + TBMiniAdapter.window.focus = function () { + }; + Laya.Laya['_getUrlPath'] = function () { + return ""; + }; + TBMiniAdapter.window.logtime = function (str) { + }; + TBMiniAdapter.window.alertTimeLog = function (str) { + }; + TBMiniAdapter.window.resetShareInfo = function () { + }; + TBMiniAdapter.window.CanvasRenderingContext2D = function () { + }; + Laya.HttpRequest._urlEncode = TBMiniAdapter.safeEncodeURI; + TBMiniAdapter._preCreateElement = Laya.Browser.createElement; + TBMiniAdapter.window.CanvasRenderingContext2D.prototype = TBMiniAdapter._preCreateElement("canvas").getContext('2d').__proto__; + TBMiniAdapter.window.document.body.appendChild = function () { + }; + Laya.Browser["createElement"] = TBMiniAdapter.createElement; + Laya.RunDriver.createShaderCondition = TBMiniAdapter.createShaderCondition; + Laya.Utils['parseXMLFromString'] = TBMiniAdapter.parseXMLFromString; + Laya.Input['_createInputElement'] = MiniInput['_createInputElement']; + if (!window.ImageData) { + window.ImageData = ImageDataPolyfill; + } + Laya.Loader.prototype._loadResourceFilter = MiniLoader.prototype._loadResourceFilter; + Laya.Loader.prototype._loadSound = MiniLoader.prototype._loadSound; + Laya.Loader.prototype.originComplete = Laya.Loader.prototype.complete; + Laya.Loader.prototype.complete = MiniLoader.prototype.complete; + Laya.Loader.prototype._loadHttpRequestWhat = MiniLoader.prototype._loadHttpRequestWhat; + Laya.Config.useRetinalCanvas = true; + Laya.LocalStorage._baseClass = MiniLocalStorage; + MiniLocalStorage.__init__(); + MiniSound.__init__(); + TBMiniAdapter.window.my.onMessage && TBMiniAdapter.window.my.onMessage(TBMiniAdapter._onMessage); + } + static _onMessage(data) { + switch (data.type) { + case "changeMatrix": + Laya.Laya.stage.transform.identity(); + Laya.Laya.stage._width = data.w; + Laya.Laya.stage._height = data.h; + Laya.Laya.stage._canvasTransform = new Laya.Matrix(data.a, data.b, data.c, data.d, data.tx, data.ty); + break; + case "display": + Laya.Laya.stage.frameRate = data.rate || Laya.Stage.FRAME_FAST; + break; + case "undisplay": + Laya.Laya.stage.frameRate = Laya.Stage.FRAME_SLEEP; + break; + } + if (data['isLoad'] == "opendatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + else if (data['isLoad'] == "openJsondatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + } + } + else if (data['isLoad'] == "openJsondatacontextPic") { + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + static getUrlEncode(url, type) { + if (type == "arraybuffer") + return ""; + return "utf8"; + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + var fileObj = MiniFileMgr.getFileInfo(fileUrl); + if (!fileObj) + MiniFileMgr.downLoadFile(TBMiniAdapter.safeEncodeURI(fileUrl), fileType, callBack, encoding); + else { + callBack != null && callBack.runWith([0]); + } + } + static remove(fileUrl, callBack = null) { + MiniFileMgr.deleteFile("", fileUrl, callBack, "", 0); + } + static removeAll() { + MiniFileMgr.deleteAll(); + } + static hasNativeFile(fileUrl) { + return MiniFileMgr.isLocalNativeFile(fileUrl); + } + static getFileInfo(fileUrl) { + return MiniFileMgr.getFileInfo(fileUrl); + } + static getFileList() { + return MiniFileMgr.filesListObj; + } + static exitMiniProgram() { + TBMiniAdapter.window.my.exitMiniProgram(); + } + static onMkdirCallBack(errorCode, data) { + if (!errorCode) { + MiniFileMgr.filesListObj = JSON.parse(data.data) || {}; + MiniFileMgr.fakeObj = JSON.parse(data.data) || {}; + } + else { + MiniFileMgr.fakeObj = {}; + MiniFileMgr.filesListObj = {}; + } + let files = MiniFileMgr.fs.readdirSync(MiniFileMgr.fileNativeDir); + if (!files || !files.length) + return; + var tempMd5ListObj = {}; + var fileObj; + for (let key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") { + fileObj = MiniFileMgr.filesListObj[key]; + tempMd5ListObj[fileObj.md5] = fileObj.readyUrl; + } + } + var fileName; + for (let i = 0, sz = files.length; i < sz; i++) { + fileName = files[i]; + if (fileName == MiniFileMgr.fileListName) + continue; + if (!tempMd5ListObj[fileName]) { + let deleteFileUrl = MiniFileMgr.getFileNativePath(fileName); + MiniFileMgr.fs.unlink({ + filePath: deleteFileUrl, + success: function (data) { + console.log("删除无引用的磁盘文件:" + fileName); + } + }); + } + delete tempMd5ListObj[fileName]; + } + for (let key in tempMd5ListObj) { + delete MiniFileMgr.filesListObj[tempMd5ListObj[key]]; + delete MiniFileMgr.fakeObj[tempMd5ListObj[key]]; + console.log("删除错误记录:", tempMd5ListObj[key]); + } + } + static pixelRatio() { + if (!TBMiniAdapter.EnvConfig.pixelRatioInt) { + try { + TBMiniAdapter.EnvConfig.pixelRatioInt = TBMiniAdapter.systemInfo.pixelRatio; + return TBMiniAdapter.systemInfo.pixelRatio; + } + catch (error) { + } + } + return TBMiniAdapter.EnvConfig.pixelRatioInt; + } + static createElement(type) { + if (type == "canvas") { + var _source; + if (TBMiniAdapter.idx == 1) { + _source = TBMiniAdapter.window.canvas.getRealCanvas(); + if (!my.isIDE) { + var originfun = _source.getContext; + _source.getContext = function (type) { + var gl = originfun.apply(_source, [type]); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); + return gl; + }; + } + } + else { + _source = TBMiniAdapter._preCreateElement(type); + } + (!_source.style) && (_source.style = {}); + TBMiniAdapter.idx++; + return _source; + } + else if (type == "textarea" || type == "input") { + return TBMiniAdapter.onCreateInput(type); + } + else if (type == "div") { + var node = TBMiniAdapter._preCreateElement(type); + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + else { + return TBMiniAdapter._preCreateElement(type); + } + } + static onCreateInput(type) { + var node = TBMiniAdapter._preCreateElement(type); + node.focus = MiniInput.wxinputFocus; + node.blur = MiniInput.wxinputblur; + node.value = 0; + node.placeholder = {}; + node.type = {}; + node.setColor = function (value) { + }; + node.setType = function (value) { + }; + node.setFontFace = function (value) { + }; + node.contains = function (value) { + return null; + }; + return node; + } + static createShaderCondition(conditionScript) { + var func = function () { + return this[conditionScript.replace("this.", "")]; + }; + return func; + } + } + TBMiniAdapter.IGNORE = new RegExp("[-_.!~*'();/?:@&=+$,#%]|[0-9|A-Z|a-z]"); + TBMiniAdapter.safeEncodeURI = function (str) { + var strTemp = ""; + var length = str.length; + for (var i = 0; i < length; i++) { + var word = str[i]; + if (TBMiniAdapter.IGNORE.test(word)) { + strTemp += word; + } + else { + try { + strTemp += encodeURI(word); + } + catch (e) { + console.log("errorInfo", ">>>" + word); + } + } + } + return strTemp; + }; + TBMiniAdapter._inited = false; + TBMiniAdapter.autoCacheFile = false; + TBMiniAdapter.minClearSize = (5 * 1024 * 1024); + TBMiniAdapter.sizeLimit = (50 * 1024 * 1024); + TBMiniAdapter.nativefiles = ["layaNativeDir"]; + TBMiniAdapter.subNativeFiles = []; + TBMiniAdapter.subNativeheads = []; + TBMiniAdapter.subMaps = []; + TBMiniAdapter.AutoCacheDownFile = false; + TBMiniAdapter.baseDir = "component/"; + TBMiniAdapter.parseXMLFromString = function (value) { + var rst; + value = value.replace(/>\s+<'); + try { + rst = (new TBMiniAdapter.window.Parser.DOMParser()).parseFromString(value, 'text/xml'); + } + catch (error) { + throw "需要引入xml解析库文件"; + } + return rst; + }; + TBMiniAdapter.idx = 1; + + class MiniAccelerator extends Laya.EventDispatcher { + constructor() { + super(); + } + static __init__() { + try { + var Acc; + Acc = Laya.Accelerator; + if (!Acc) + return; + Acc["prototype"]["on"] = MiniAccelerator["prototype"]["on"]; + Acc["prototype"]["off"] = MiniAccelerator["prototype"]["off"]; + } + catch (e) { + } + } + static startListen(callBack) { + MiniAccelerator._callBack = callBack; + if (MiniAccelerator._isListening) + return; + MiniAccelerator._isListening = true; + try { + TBMiniAdapter.window.my.onAccelerometerChange(MiniAccelerator.onAccelerometerChange); + } + catch (e) { } + } + static stopListen() { + MiniAccelerator._isListening = false; + try { + TBMiniAdapter.window.my.stopAccelerometer({}); + } + catch (e) { } + } + static onAccelerometerChange(res) { + var e; + e = {}; + e.acceleration = res; + e.accelerationIncludingGravity = res; + e.rotationRate = {}; + if (MiniAccelerator._callBack != null) { + MiniAccelerator._callBack(e); + } + } + on(type, caller, listener, args = null) { + super.on(type, caller, listener, args); + MiniAccelerator.startListen(this["onDeviceOrientationChange"]); + return this; + } + off(type, caller, listener, onceOnly = false) { + if (!this.hasListener(type)) + MiniAccelerator.stopListen(); + return super.off(type, caller, listener, onceOnly); + } + } + MiniAccelerator._isListening = false; + + class MiniLocation { + constructor() { + } + static __init__() { + TBMiniAdapter.window.navigator.geolocation.getCurrentPosition = MiniLocation.getCurrentPosition; + TBMiniAdapter.window.navigator.geolocation.watchPosition = MiniLocation.watchPosition; + TBMiniAdapter.window.navigator.geolocation.clearWatch = MiniLocation.clearWatch; + } + static getCurrentPosition(success = null, error = null, options = null) { + var paramO; + paramO = {}; + paramO.success = getSuccess; + paramO.fail = error; + TBMiniAdapter.window.my.getLocation(paramO); + function getSuccess(res) { + if (success != null) { + success(res); + } + } + } + static watchPosition(success = null, error = null, options = null) { + MiniLocation._curID++; + var curWatchO; + curWatchO = {}; + curWatchO.success = success; + curWatchO.error = error; + MiniLocation._watchDic[MiniLocation._curID] = curWatchO; + Laya.Laya.systemTimer.loop(1000, null, MiniLocation._myLoop); + return MiniLocation._curID; + } + static clearWatch(id) { + delete MiniLocation._watchDic[id]; + if (!MiniLocation._hasWatch()) { + Laya.Laya.systemTimer.clear(null, MiniLocation._myLoop); + } + } + static _hasWatch() { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key]) + return true; + } + return false; + } + static _myLoop() { + MiniLocation.getCurrentPosition(MiniLocation._mySuccess, MiniLocation._myError); + } + static _mySuccess(res) { + var rst = {}; + rst.coords = res; + rst.timestamp = Laya.Browser.now(); + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].success) { + MiniLocation._watchDic[key].success(rst); + } + } + } + static _myError(res) { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].error) { + MiniLocation._watchDic[key].error(res); + } + } + } + } + MiniLocation._watchDic = {}; + MiniLocation._curID = 0; + + class MiniVideo { + constructor(width = 320, height = 240) { + this.videoend = false; + this.videourl = ""; + this.videoElement = TBMiniAdapter.window.my.createVideo({ width: width, height: height, autoplay: true }); + } + static __init__() { + } + on(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.onPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.onEnded = this.onEndedFunction.bind(this); + } + this.videoElement.onTimeUpdate = this.onTimeUpdateFunc.bind(this); + } + onTimeUpdateFunc(data) { + this.position = data.position; + this._duration = data.duration; + } + get duration() { + return this._duration; + } + onPlayFunction() { + if (this.videoElement) + this.videoElement.readyState = 200; + console.log("=====视频加载完成========"); + this.onPlayFunc != null && this.onPlayFunc(); + } + onEndedFunction() { + if (!this.videoElement) + return; + this.videoend = true; + console.log("=====视频播放完毕========"); + this.onEndedFunC != null && this.onEndedFunC(); + } + off(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.offPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.offEnded = this.onEndedFunction.bind(this); + } + } + load(url) { + if (!this.videoElement) + return; + this.videoElement.src = url; + } + play() { + if (!this.videoElement) + return; + this.videoend = false; + this.videoElement.play(); + } + pause() { + if (!this.videoElement) + return; + this.videoend = true; + this.videoElement.pause(); + } + get currentTime() { + if (!this.videoElement) + return 0; + return this.videoElement.initialTime; + } + set currentTime(value) { + if (!this.videoElement) + return; + this.videoElement.initialTime = value; + } + get videoWidth() { + if (!this.videoElement) + return 0; + return this.videoElement.width; + } + get videoHeight() { + if (!this.videoElement) + return 0; + return this.videoElement.height; + } + get ended() { + return this.videoend; + } + get loop() { + if (!this.videoElement) + return false; + return this.videoElement.loop; + } + set loop(value) { + if (!this.videoElement) + return; + this.videoElement.loop = value; + } + get playbackRate() { + if (!this.videoElement) + return 0; + return this.videoElement.playbackRate; + } + set playbackRate(value) { + if (!this.videoElement) + return; + this.videoElement.playbackRate = value; + } + get muted() { + if (!this.videoElement) + return false; + return this.videoElement.muted; + } + set muted(value) { + if (!this.videoElement) + return; + this.videoElement.muted = value; + } + get paused() { + if (!this.videoElement) + return false; + return this.videoElement.paused; + } + size(width, height) { + if (!this.videoElement) + return; + this.videoElement.width = width; + this.videoElement.height = height; + } + get x() { + if (!this.videoElement) + return 0; + return this.videoElement.x; + } + set x(value) { + if (!this.videoElement) + return; + this.videoElement.x = value; + } + get y() { + if (!this.videoElement) + return 0; + return this.videoElement.y; + } + set y(value) { + if (!this.videoElement) + return; + this.videoElement.y = value; + } + get currentSrc() { + return this.videoElement.src; + } + destroy() { + if (this.videoElement) + this.videoElement.destroy(); + this.videoElement = null; + this.onEndedFunC = null; + this.onPlayFunc = null; + this.videoend = false; + this.videourl = null; + } + reload() { + if (!this.videoElement) + return; + this.videoElement.src = this.videourl; + } + } + + exports.ImageDataPolyfill = ImageDataPolyfill; + exports.MiniAccelerator = MiniAccelerator; + exports.MiniFileMgr = MiniFileMgr; + exports.MiniInput = MiniInput; + exports.MiniLoader = MiniLoader; + exports.MiniLocalStorage = MiniLocalStorage; + exports.MiniLocation = MiniLocation; + exports.MiniSound = MiniSound; + exports.MiniSoundChannel = MiniSoundChannel; + exports.MiniVideo = MiniVideo; + exports.TBMiniAdapter = TBMiniAdapter; + +} diff --git a/examples/layaair/frontend/bin/libs/laya.tiledmap.js b/examples/layaair/frontend/bin/libs/laya.tiledmap.js new file mode 100644 index 0000000..3149de0 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.tiledmap.js @@ -0,0 +1,1601 @@ +(function (exports, Laya) { + 'use strict'; + + class GridSprite extends Laya.Sprite { + constructor() { + super(...arguments); + this.relativeX = 0; + this.relativeY = 0; + this.isAloneObject = false; + this.isHaveAnimation = false; + this.drawImageNum = 0; + this._map = null; + } + initData(map, objectKey = false) { + this._map = map; + this.isAloneObject = objectKey; + } + addAniSprite(sprite) { + if (this.aniSpriteArray == null) { + this.aniSpriteArray = []; + } + this.aniSpriteArray.push(sprite); + } + show() { + if (!this.visible) { + this.visible = true; + if (this.aniSpriteArray == null) { + return; + } + var tAniSprite; + for (var i = 0; i < this.aniSpriteArray.length; i++) { + tAniSprite = this.aniSpriteArray[i]; + tAniSprite.show(); + } + } + } + hide() { + if (this.visible) { + this.visible = false; + if (this.aniSpriteArray == null) { + return; + } + var tAniSprite; + for (var i = 0; i < this.aniSpriteArray.length; i++) { + tAniSprite = this.aniSpriteArray[i]; + tAniSprite.hide(); + } + } + } + updatePos() { + if (this.isAloneObject) { + if (this._map) { + this.x = this.relativeX - this._map._viewPortX; + this.y = this.relativeY - this._map._viewPortY; + } + if (this.x < 0 || this.x > this._map.viewPortWidth || this.y < 0 || this.y > this._map.viewPortHeight) { + this.hide(); + } + else { + this.show(); + } + } + else { + if (this._map) { + this.x = this.relativeX - this._map._viewPortX; + this.y = this.relativeY - this._map._viewPortY; + } + } + } + clearAll() { + if (this._map) { + this._map = null; + } + this.visible = false; + var tAniSprite; + if (this.aniSpriteArray != null) { + for (var i = 0; i < this.aniSpriteArray.length; i++) { + tAniSprite = this.aniSpriteArray[i]; + tAniSprite.clearAll(); + } + } + this.destroy(); + this.relativeX = 0; + this.relativeY = 0; + this.isHaveAnimation = false; + this.aniSpriteArray = null; + this.drawImageNum = 0; + } + } + + class IMap { + } + IMap.TiledMap = null; + + class TileAniSprite extends Laya.Sprite { + constructor() { + super(...arguments); + this._tileTextureSet = null; + this._aniName = null; + } + setTileTextureSet(aniName, tileTextureSet) { + this._aniName = aniName; + this._tileTextureSet = tileTextureSet; + tileTextureSet.addAniSprite(this._aniName, this); + } + show() { + this._tileTextureSet.addAniSprite(this._aniName, this); + } + hide() { + this._tileTextureSet.removeAniSprite(this._aniName); + } + clearAll() { + this._tileTextureSet.removeAniSprite(this._aniName); + this.destroy(); + this._tileTextureSet = null; + this._aniName = null; + } + } + + class MapLayer extends Laya.Sprite { + constructor() { + super(...arguments); + this._mapData = null; + this._tileWidthHalf = 0; + this._tileHeightHalf = 0; + this._mapWidthHalf = 0; + this._mapHeightHalf = 0; + this._gridSpriteArray = []; + this._objDic = null; + this._dataDic = null; + this._tempMapPos = new Laya.Point(); + this.layerName = null; + } + init(layerData, map) { + this._map = map; + this._mapData = layerData.data; + var tHeight = layerData.height; + var tWidth = layerData.width; + var tTileW = map.tileWidth; + var tTileH = map.tileHeight; + this.layerName = layerData.name; + this._properties = layerData.properties; + this.alpha = layerData.opacity; + this._tileWidthHalf = tTileW / 2; + this._tileHeightHalf = tTileH / 2; + this._mapWidthHalf = this._map.width / 2 - this._tileWidthHalf; + this._mapHeightHalf = this._map.height / 2; + switch (layerData.type) { + case "tilelayer": + break; + case "objectgroup": + var tArray = layerData.objects; + if (tArray.length > 0) { + this._objDic = {}; + this._dataDic = {}; + } + var tObjectData; + var tObjWidth; + var tObjHeight; + for (var i = 0; i < tArray.length; i++) { + tObjectData = tArray[i]; + this._dataDic[tObjectData.name] = tObjectData; + if (tObjectData.visible == true) { + tObjWidth = tObjectData.width; + tObjHeight = tObjectData.height; + var tSprite = map.getSprite(tObjectData.gid, tObjWidth, tObjHeight); + if (tSprite != null) { + switch (this._map.orientation) { + case IMap.TiledMap.ORIENTATION_ISOMETRIC: + this.getScreenPositionByTilePos(tObjectData.x / tTileH, tObjectData.y / tTileH, Laya.Point.TEMP); + tSprite.pivot(tObjWidth / 2, tObjHeight / 2); + tSprite.rotation = tObjectData.rotation; + tSprite.x = tSprite.relativeX = Laya.Point.TEMP.x + this._map.viewPortX; + tSprite.y = tSprite.relativeY = Laya.Point.TEMP.y + this._map.viewPortY - tObjHeight / 2; + break; + case IMap.TiledMap.ORIENTATION_STAGGERED: + tSprite.pivot(tObjWidth / 2, tObjHeight / 2); + tSprite.rotation = tObjectData.rotation; + tSprite.x = tSprite.relativeX = tObjectData.x + tObjWidth / 2; + tSprite.y = tSprite.relativeY = tObjectData.y - tObjHeight / 2; + break; + case IMap.TiledMap.ORIENTATION_ORTHOGONAL: + tSprite.pivot(tObjWidth / 2, tObjHeight / 2); + tSprite.rotation = tObjectData.rotation; + tSprite.x = tSprite.relativeX = tObjectData.x + tObjWidth / 2; + tSprite.y = tSprite.relativeY = tObjectData.y - tObjHeight / 2; + break; + case IMap.TiledMap.ORIENTATION_HEXAGONAL: + tSprite.x = tSprite.relativeX = tObjectData.x; + tSprite.y = tSprite.relativeY = tObjectData.y; + break; + } + this.addChild(tSprite); + this._gridSpriteArray.push(tSprite); + this._objDic[tObjectData.name] = tSprite; + } + } + } + break; + } + } + getObjectByName(objName) { + if (this._objDic) { + return this._objDic[objName]; + } + return null; + } + getObjectDataByName(objName) { + if (this._dataDic) { + return this._dataDic[objName]; + } + return null; + } + getLayerProperties(name) { + if (this._properties) { + return this._properties[name]; + } + return null; + } + getTileData(tileX, tileY) { + if (tileY >= 0 && tileY < this._map.numRowsTile && tileX >= 0 && tileX < this._map.numColumnsTile) { + var tIndex = tileY * this._map.numColumnsTile + tileX; + var tMapData = this._mapData; + if (tMapData != null && tIndex < tMapData.length) { + return tMapData[tIndex]; + } + } + return 0; + } + getScreenPositionByTilePos(tileX, tileY, screenPos = null) { + if (screenPos) { + switch (this._map.orientation) { + case IMap.TiledMap.ORIENTATION_ISOMETRIC: + screenPos.x = this._map.width / 2 - (tileY - tileX) * this._tileWidthHalf; + screenPos.y = (tileY + tileX) * this._tileHeightHalf; + break; + case IMap.TiledMap.ORIENTATION_STAGGERED: + tileX = Math.floor(tileX); + tileY = Math.floor(tileY); + screenPos.x = tileX * this._map.tileWidth + (tileY & 1) * this._tileWidthHalf; + screenPos.y = tileY * this._tileHeightHalf; + break; + case IMap.TiledMap.ORIENTATION_ORTHOGONAL: + screenPos.x = tileX * this._map.tileWidth; + screenPos.y = tileY * this._map.tileHeight; + break; + case IMap.TiledMap.ORIENTATION_HEXAGONAL: + tileX = Math.floor(tileX); + tileY = Math.floor(tileY); + var tTileHeight = this._map.tileHeight * 2 / 3; + screenPos.x = (tileX * this._map.tileWidth + tileY % 2 * this._tileWidthHalf) % this._map.gridWidth; + screenPos.y = (tileY * tTileHeight) % this._map.gridHeight; + break; + } + screenPos.x = (screenPos.x + this._map.viewPortX) * this._map.scale; + screenPos.y = (screenPos.y + this._map.viewPortY) * this._map.scale; + } + } + getTileDataByScreenPos(screenX, screenY) { + var tData = 0; + if (this.getTilePositionByScreenPos(screenX, screenY, this._tempMapPos)) { + tData = this.getTileData(Math.floor(this._tempMapPos.x), Math.floor(this._tempMapPos.y)); + } + return tData; + } + getTilePositionByScreenPos(screenX, screenY, result = null) { + screenX = screenX / this._map.scale - this._map.viewPortX; + screenY = screenY / this._map.scale - this._map.viewPortY; + var tTileW = this._map.tileWidth; + var tTileH = this._map.tileHeight; + var tV = 0; + var tU = 0; + switch (this._map.orientation) { + case IMap.TiledMap.ORIENTATION_ISOMETRIC: + var tDirX = screenX - this._map.width / 2; + var tDirY = screenY; + tV = -(tDirX / tTileW - tDirY / tTileH); + tU = tDirX / tTileW + tDirY / tTileH; + if (result) { + result.x = tU; + result.y = tV; + } + return true; + case IMap.TiledMap.ORIENTATION_STAGGERED: + if (result) { + var cx, cy, rx, ry; + cx = Math.floor(screenX / tTileW) * tTileW + tTileW / 2; + cy = Math.floor(screenY / tTileH) * tTileH + tTileH / 2; + rx = (screenX - cx) * tTileH / 2; + ry = (screenY - cy) * tTileW / 2; + if (Math.abs(rx) + Math.abs(ry) <= tTileW * tTileH / 4) { + tU = Math.floor(screenX / tTileW); + tV = Math.floor(screenY / tTileH) * 2; + } + else { + screenX = screenX - tTileW / 2; + tU = Math.floor(screenX / tTileW) + 1; + screenY = screenY - tTileH / 2; + tV = Math.floor(screenY / tTileH) * 2 + 1; + } + result.x = tU - (tV & 1); + result.y = tV; + } + return true; + case IMap.TiledMap.ORIENTATION_ORTHOGONAL: + tU = screenX / tTileW; + tV = screenY / tTileH; + if (result) { + result.x = tU; + result.y = tV; + } + return true; + case IMap.TiledMap.ORIENTATION_HEXAGONAL: + var tTileHeight = tTileH * 2 / 3; + tV = screenY / tTileHeight; + tU = (screenX - tV % 2 * this._tileWidthHalf) / tTileW; + if (result) { + result.x = tU; + result.y = tV; + } + break; + } + return false; + } + getDrawSprite(gridX, gridY) { + var tSprite = new GridSprite(); + tSprite.relativeX = gridX * this._map.gridWidth; + tSprite.relativeY = gridY * this._map.gridHeight; + tSprite.initData(this._map); + this._gridSpriteArray.push(tSprite); + return tSprite; + } + updateGridPos() { + var tSprite; + for (var i = 0; i < this._gridSpriteArray.length; i++) { + tSprite = this._gridSpriteArray[i]; + if ((tSprite.visible || tSprite.isAloneObject) && tSprite.drawImageNum > 0) { + tSprite.updatePos(); + } + } + } + drawTileTexture(gridSprite, tileX, tileY) { + if (tileY >= 0 && tileY < this._map.numRowsTile && tileX >= 0 && tileX < this._map.numColumnsTile) { + var tIndex = tileY * this._map.numColumnsTile + tileX; + var tMapData = this._mapData; + if (tMapData != null && tIndex < tMapData.length) { + if (tMapData[tIndex] != 0) { + var tTileTexSet = this._map.getTexture(tMapData[tIndex]); + if (tTileTexSet) { + var tX = 0; + var tY = 0; + var tTexture = tTileTexSet.texture; + switch (this._map.orientation) { + case IMap.TiledMap.ORIENTATION_STAGGERED: + tX = tileX * this._map.tileWidth % this._map.gridWidth + (tileY & 1) * this._tileWidthHalf; + tY = tileY * this._tileHeightHalf % this._map.gridHeight; + break; + case IMap.TiledMap.ORIENTATION_ORTHOGONAL: + tX = tileX * this._map.tileWidth % this._map.gridWidth; + tY = tileY * this._map.tileHeight % this._map.gridHeight; + break; + case IMap.TiledMap.ORIENTATION_ISOMETRIC: + tX = (this._mapWidthHalf + (tileX - tileY) * this._tileWidthHalf) % this._map.gridWidth; + tY = ((tileX + tileY) * this._tileHeightHalf) % this._map.gridHeight; + break; + case IMap.TiledMap.ORIENTATION_HEXAGONAL: + var tTileHeight = this._map.tileHeight * 2 / 3; + tX = (tileX * this._map.tileWidth + tileY % 2 * this._tileWidthHalf) % this._map.gridWidth; + tY = (tileY * tTileHeight) % this._map.gridHeight; + break; + } + if (tTileTexSet.isAnimation) { + var tAnimationSprite = new TileAniSprite(); + tAnimationSprite.x = tX; + tAnimationSprite.y = tY; + tAnimationSprite.setTileTextureSet(tIndex.toString(), tTileTexSet); + gridSprite.addAniSprite(tAnimationSprite); + gridSprite.addChild(tAnimationSprite); + gridSprite.isHaveAnimation = true; + } + else { + gridSprite.graphics.drawImage(tTileTexSet.texture, tX + tTileTexSet.offX, tY + tTileTexSet.offY); + } + return true; + } + } + } + } + return false; + } + clearAll() { + this._map = null; + this._mapData = null; + this._tileWidthHalf = 0; + this._tileHeightHalf = 0; + this._mapWidthHalf = 0; + this._mapHeightHalf = 0; + this.layerName = null; + var i = 0; + if (this._objDic) { + for (var p in this._objDic) { + delete this._objDic[p]; + } + this._objDic = null; + } + if (this._dataDic) { + for (p in this._dataDic) { + delete this._dataDic[p]; + } + this._dataDic = null; + } + var tGridSprite; + for (i = 0; i < this._gridSpriteArray.length; i++) { + tGridSprite = this._gridSpriteArray[i]; + tGridSprite.clearAll(); + } + this._properties = null; + this._tempMapPos = null; + this.tarLayer = null; + } + } + + class TileTexSet { + constructor() { + this.gid = -1; + this.offX = 0; + this.offY = 0; + this.textureArray = null; + this.durationTimeArray = null; + this.animationTotalTime = 0; + this.isAnimation = false; + this._spriteNum = 0; + this._aniDic = null; + this._frameIndex = 0; + this._time = 0; + this._interval = 0; + this._preFrameTime = 0; + } + addAniSprite(aniName, sprite) { + if (this.animationTotalTime == 0) { + return; + } + if (this._aniDic == null) { + this._aniDic = {}; + } + if (this._spriteNum == 0) { + Laya.ILaya.timer.frameLoop(3, this, this.animate); + this._preFrameTime = Laya.ILaya.Browser.now(); + this._frameIndex = 0; + this._time = 0; + this._interval = 0; + } + this._spriteNum++; + this._aniDic[aniName] = sprite; + if (this.textureArray && this._frameIndex < this.textureArray.length) { + var tTileTextureSet = this.textureArray[this._frameIndex]; + this.drawTexture(sprite, tTileTextureSet); + } + } + animate() { + if (this.textureArray && this.textureArray.length > 0 && this.durationTimeArray && this.durationTimeArray.length > 0) { + var tNow = Laya.ILaya.Browser.now(); + this._interval = tNow - this._preFrameTime; + this._preFrameTime = tNow; + if (this._interval > this.animationTotalTime) { + this._interval = this._interval % this.animationTotalTime; + } + this._time += this._interval; + var tTime = this.durationTimeArray[this._frameIndex]; + while (this._time > tTime) { + this._time -= tTime; + this._frameIndex++; + if (this._frameIndex >= this.durationTimeArray.length || this._frameIndex >= this.textureArray.length) { + this._frameIndex = 0; + } + var tTileTextureSet = this.textureArray[this._frameIndex]; + var tSprite; + for (var p in this._aniDic) { + tSprite = this._aniDic[p]; + this.drawTexture(tSprite, tTileTextureSet); + } + tTime = this.durationTimeArray[this._frameIndex]; + } + } + } + drawTexture(sprite, tileTextSet) { + sprite.graphics.clear(true); + sprite.graphics.drawImage(tileTextSet.texture, tileTextSet.offX, tileTextSet.offY); + } + removeAniSprite(_name) { + if (this._aniDic && this._aniDic[_name]) { + delete this._aniDic[_name]; + this._spriteNum--; + if (this._spriteNum == 0) { + Laya.ILaya.timer.clear(this, this.animate); + } + } + } + showDebugInfo() { + var tInfo = null; + if (this._spriteNum > 0) { + tInfo = "TileTextureSet::gid:" + this.gid.toString() + " 动画数:" + this._spriteNum.toString(); + } + return tInfo; + } + clearAll() { + this.gid = -1; + if (this.texture) { + this.texture.destroy(); + this.texture = null; + } + this.offX = 0; + this.offY = 0; + this.textureArray = null; + this.durationTimeArray = null; + this.isAnimation = false; + this._spriteNum = 0; + this._aniDic = null; + this._frameIndex = 0; + this._preFrameTime = 0; + this._time = 0; + this._interval = 0; + } + } + + class TiledMap { + constructor() { + this._tileTexSetArr = []; + this._texArray = []; + this._x = 0; + this._y = 0; + this._width = 0; + this._height = 0; + this._mapW = 0; + this._mapH = 0; + this._mapTileW = 0; + this._mapTileH = 0; + this._rect = new Laya.Rectangle(); + this._paddingRect = new Laya.Rectangle(); + this._mapSprite = null; + this._layerArray = []; + this._renderLayerArray = []; + this._gridArray = []; + this._showGridKey = false; + this._totalGridNum = 0; + this._gridW = 0; + this._gridH = 0; + this._gridWidth = 450; + this._gridHeight = 450; + this._jsonLoader = null; + this._loader = null; + this._tileSetArray = []; + this._currTileSet = null; + this._completeHandler = null; + this._mapRect = new GRect(); + this._mapLastRect = new GRect(); + this._index = 0; + this._animationDic = {}; + this._tileProperties = {}; + this._tileProperties2 = {}; + this._orientation = "orthogonal"; + this._renderOrder = "right-down"; + this._colorArray = ["FF", "00", "33", "66"]; + this._scale = 1; + this._pivotScaleX = 0.5; + this._pivotScaleY = 0.5; + this._centerX = 0; + this._centerY = 0; + this._viewPortX = 0; + this._viewPortY = 0; + this._viewPortWidth = 0; + this._viewPortHeight = 0; + this._enableLinear = true; + this._limitRange = false; + this.autoCache = true; + this.autoCacheType = "normal"; + this.enableMergeLayer = false; + this.removeCoveredTile = false; + this.showGridTextureCount = false; + this.antiCrack = true; + this.cacheAllAfterInit = false; + this._texutreStartDic = {}; + } + createMap(mapName, viewRect, completeHandler, viewRectPadding = null, gridSize = null, enableLinear = true, limitRange = false) { + this._enableLinear = enableLinear; + this._limitRange = limitRange; + this._rect.x = viewRect.x; + this._rect.y = viewRect.y; + this._rect.width = viewRect.width; + this._rect.height = viewRect.height; + this._viewPortWidth = viewRect.width / this._scale; + this._viewPortHeight = viewRect.height / this._scale; + this._completeHandler = completeHandler; + if (viewRectPadding) { + this._paddingRect.copyFrom(viewRectPadding); + } + else { + this._paddingRect.setTo(0, 0, 0, 0); + } + if (gridSize) { + this._gridWidth = gridSize.x; + this._gridHeight = gridSize.y; + } + var tIndex = mapName.lastIndexOf("/"); + if (tIndex > -1) { + this._resPath = mapName.substr(0, tIndex); + this._pathArray = this._resPath.split("/"); + } + else { + this._resPath = ""; + this._pathArray = []; + } + this._jsonLoader = new Laya.Loader(); + this._jsonLoader.once("complete", this, this.onJsonComplete); + this._jsonLoader.load(mapName, Laya.Loader.JSON, false); + } + onJsonComplete(e) { + this._mapSprite = new Laya.Sprite(); + Laya.ILaya.stage.addChild(this._mapSprite); + var tJsonData = this._jsonData = e; + this._properties = tJsonData.properties; + this._orientation = tJsonData.orientation; + this._renderOrder = tJsonData.renderorder; + this._mapW = tJsonData.width; + this._mapH = tJsonData.height; + this._mapTileW = tJsonData.tilewidth; + this._mapTileH = tJsonData.tileheight; + this._width = this._mapTileW * this._mapW; + this._height = this._mapTileH * this._mapH; + if (this._orientation == TiledMap.ORIENTATION_STAGGERED) { + this._height = (0.5 + this._mapH * 0.5) * this._mapTileH; + } + this._mapLastRect.top = this._mapLastRect.bottom = this._mapLastRect.left = this._mapLastRect.right = -1; + var tArray = tJsonData.tilesets; + var tileset; + var tTileSet; + var i = 0; + for (i = 0; i < tArray.length; i++) { + tileset = tArray[i]; + tTileSet = new TileSet(); + tTileSet.init(tileset); + if (tTileSet.properties && tTileSet.properties.ignore) + continue; + this._tileProperties[i] = tTileSet.tileproperties; + this.addTileProperties(tTileSet.tileproperties); + this._tileSetArray.push(tTileSet); + var tTiles = tileset.tiles; + if (tTiles) { + for (var p in tTiles) { + var tAnimation = tTiles[p].animation; + if (tAnimation) { + var tAniData = new TileMapAniData(); + this._animationDic[p] = tAniData; + tAniData.image = tileset.image; + for (var j = 0; j < tAnimation.length; j++) { + var tAnimationItem = tAnimation[j]; + tAniData.mAniIdArray.push(tAnimationItem.tileid); + tAniData.mDurationTimeArray.push(tAnimationItem.duration); + } + } + } + } + } + this._tileTexSetArr.push(null); + if (this._tileSetArray.length > 0) { + tTileSet = this._currTileSet = this._tileSetArray.shift(); + this._loader = new Laya.Loader(); + this._loader.once("complete", this, this.onTextureComplete); + var tPath = this.mergePath(this._resPath, tTileSet.image); + this._loader.load(tPath, Laya.Loader.IMAGE, false); + } + } + mergePath(resPath, relativePath) { + var tResultPath = ""; + var tImageArray = relativePath.split("/"); + var tParentPathNum = 0; + var i = 0; + for (i = tImageArray.length - 1; i >= 0; i--) { + if (tImageArray[i] == "..") { + tParentPathNum++; + } + } + if (tParentPathNum == 0) { + if (this._pathArray.length > 0) { + tResultPath = resPath + "/" + relativePath; + } + else { + tResultPath = relativePath; + } + return tResultPath; + } + var tSrcNum = this._pathArray.length - tParentPathNum; + if (tSrcNum < 0) { + console.log("[error]path does not exist", this._pathArray, tImageArray, resPath, relativePath); + } + for (i = 0; i < tSrcNum; i++) { + if (i == 0) { + tResultPath += this._pathArray[i]; + } + else { + tResultPath = tResultPath + "/" + this._pathArray[i]; + } + } + for (i = tParentPathNum; i < tImageArray.length; i++) { + tResultPath = tResultPath + "/" + tImageArray[i]; + } + return tResultPath; + } + onTextureComplete(e) { + var json = this._jsonData; + var tTexture = e; + if (!this._enableLinear) { + tTexture.bitmap.minFifter = 0x2600; + tTexture.bitmap.magFifter = 0x2600; + } + this._texArray.push(tTexture); + var tTileSet = this._currTileSet; + var tTileTextureW = tTileSet.tilewidth; + var tTileTextureH = tTileSet.tileheight; + var tImageWidth = tTileSet.imagewidth; + var tImageHeight = tTileSet.imageheight; + var tFirstgid = tTileSet.firstgid; + var tTileWNum = Math.floor((tImageWidth - tTileSet.margin - tTileTextureW) / (tTileTextureW + tTileSet.spacing)) + 1; + var tTileHNum = Math.floor((tImageHeight - tTileSet.margin - tTileTextureH) / (tTileTextureH + tTileSet.spacing)) + 1; + var tTileTexSet = null; + this._texutreStartDic[tTileSet.image] = this._tileTexSetArr.length; + for (var i = 0; i < tTileHNum; i++) { + for (var j = 0; j < tTileWNum; j++) { + tTileTexSet = new TileTexSet(); + tTileTexSet.offX = tTileSet.titleoffsetX; + tTileTexSet.offY = tTileSet.titleoffsetY - (tTileTextureH - this._mapTileH); + tTileTexSet.texture = Laya.Texture.createFromTexture(tTexture, tTileSet.margin + (tTileTextureW + tTileSet.spacing) * j, tTileSet.margin + (tTileTextureH + tTileSet.spacing) * i, tTileTextureW, tTileTextureH); + if (this.antiCrack) + this.adptTexture(tTileTexSet.texture); + this._tileTexSetArr.push(tTileTexSet); + tTileTexSet.gid = this._tileTexSetArr.length; + } + } + if (this._tileSetArray.length > 0) { + tTileSet = this._currTileSet = this._tileSetArray.shift(); + this._loader.once("complete", this, this.onTextureComplete); + var tPath = this.mergePath(this._resPath, tTileSet.image); + this._loader.load(tPath, Laya.Loader.IMAGE, false); + } + else { + this._currTileSet = null; + this.initMap(); + } + } + adptTexture(tex) { + if (!tex) + return; + var pX = tex.uv[0]; + var pX1 = tex.uv[2]; + var pY = tex.uv[1]; + var pY1 = tex.uv[7]; + var dW = 1 / tex.bitmap.width; + var dH = 1 / tex.bitmap.height; + var Tex = tex; + Tex.uv[0] = Tex.uv[6] = pX + dW; + Tex.uv[2] = Tex.uv[4] = pX1 - dW; + Tex.uv[1] = Tex.uv[3] = pY + dH; + Tex.uv[5] = Tex.uv[7] = pY1 - dH; + } + initMap() { + var i, n; + for (var p in this._animationDic) { + var tAniData = this._animationDic[p]; + var gStart; + gStart = this._texutreStartDic[tAniData.image]; + var tTileTexSet = this.getTexture(parseInt(p) + gStart); + if (tAniData.mAniIdArray.length > 0) { + tTileTexSet.textureArray = []; + tTileTexSet.durationTimeArray = tAniData.mDurationTimeArray; + tTileTexSet.isAnimation = true; + tTileTexSet.animationTotalTime = 0; + for (i = 0, n = tTileTexSet.durationTimeArray.length; i < n; i++) { + tTileTexSet.animationTotalTime += tTileTexSet.durationTimeArray[i]; + } + for (i = 0, n = tAniData.mAniIdArray.length; i < n; i++) { + var tTexture = this.getTexture(tAniData.mAniIdArray[i] + gStart); + tTileTexSet.textureArray.push(tTexture); + } + } + } + this._gridWidth = Math.floor(this._gridWidth / this._mapTileW) * this._mapTileW; + this._gridHeight = Math.floor(this._gridHeight / this._mapTileH) * this._mapTileH; + if (this._gridWidth < this._mapTileW) { + this._gridWidth = this._mapTileW; + } + if (this._gridHeight < this._mapTileH) { + this._gridHeight = this._mapTileH; + } + this._gridW = Math.ceil(this._width / this._gridWidth); + this._gridH = Math.ceil(this._height / this._gridHeight); + this._totalGridNum = this._gridW * this._gridH; + for (i = 0; i < this._gridH; i++) { + var tGridArray = []; + this._gridArray.push(tGridArray); + for (var j = 0; j < this._gridW; j++) { + tGridArray.push(null); + } + } + var tLayerArray = this._jsonData.layers; + var isFirst = true; + var tLayerTarLayerName; + var preLayerTarName; + var preLayer; + for (var tLayerLoop = 0; tLayerLoop < tLayerArray.length; tLayerLoop++) { + var tLayerData = tLayerArray[tLayerLoop]; + if (tLayerData.visible == true) { + var tMapLayer = new MapLayer(); + tMapLayer.init(tLayerData, this); + if (!this.enableMergeLayer) { + this._mapSprite.addChild(tMapLayer); + this._renderLayerArray.push(tMapLayer); + } + else { + tLayerTarLayerName = tMapLayer.getLayerProperties("layer"); + isFirst = isFirst || (!preLayer) || (tLayerTarLayerName != preLayerTarName); + if (isFirst) { + isFirst = false; + tMapLayer.tarLayer = tMapLayer; + preLayer = tMapLayer; + this._mapSprite.addChild(tMapLayer); + this._renderLayerArray.push(tMapLayer); + } + else { + tMapLayer.tarLayer = preLayer; + } + preLayerTarName = tLayerTarLayerName; + } + this._layerArray.push(tMapLayer); + } + } + if (this.removeCoveredTile) { + this.adptTiledMapData(); + } + if (this.cacheAllAfterInit) { + this.cacheAllGrid(); + } + this.moveViewPort(this._rect.x, this._rect.y); + if (this._completeHandler != null) { + this._completeHandler.run(); + } + } + addTileProperties(tileDataDic) { + var key; + for (key in tileDataDic) { + this._tileProperties2[key] = tileDataDic[key]; + } + } + getTileUserData(id, sign, defaultV = null) { + if (!this._tileProperties2 || !this._tileProperties2[id] || !(sign in this._tileProperties2[id])) + return defaultV; + return this._tileProperties2[id][sign]; + } + adptTiledMapData() { + var i, len; + len = this._layerArray.length; + var tLayer; + var noNeeds = {}; + var tDatas; + for (i = len - 1; i >= 0; i--) { + tLayer = this._layerArray[i]; + tDatas = tLayer._mapData; + if (!tDatas) + continue; + this.removeCoverd(tDatas, noNeeds); + this.collectCovers(tDatas, noNeeds, i); + } + } + removeCoverd(datas, noNeeds) { + var i, len; + len = datas.length; + for (i = 0; i < len; i++) { + if (noNeeds[i]) { + datas[i] = 0; + } + } + } + collectCovers(datas, noNeeds, layer) { + var i, len; + len = datas.length; + var tTileData; + var isCover; + for (i = 0; i < len; i++) { + tTileData = datas[i]; + if (tTileData > 0) { + isCover = this.getTileUserData(tTileData - 1, "type", 0); + if (isCover > 0) { + noNeeds[i] = tTileData; + } + } + } + } + getTexture(index) { + if (index < this._tileTexSetArr.length) { + return this._tileTexSetArr[index]; + } + return null; + } + getMapProperties(name) { + if (this._properties) { + return this._properties[name]; + } + return null; + } + getTileProperties(index, id, name) { + if (this._tileProperties[index] && this._tileProperties[index][id]) { + return this._tileProperties[index][id][name]; + } + return null; + } + getSprite(index, width, height) { + if (0 < this._tileTexSetArr.length) { + var tGridSprite = new GridSprite(); + tGridSprite.initData(this, true); + tGridSprite.size(width, height); + var tTileTexSet = this._tileTexSetArr[index]; + if (tTileTexSet != null && tTileTexSet.texture != null) { + if (tTileTexSet.isAnimation) { + var tAnimationSprite = new TileAniSprite(); + this._index++; + tAnimationSprite.setTileTextureSet(this._index.toString(), tTileTexSet); + tGridSprite.addAniSprite(tAnimationSprite); + tGridSprite.addChild(tAnimationSprite); + } + else { + tGridSprite.graphics.drawImage(tTileTexSet.texture, 0, 0, width, height); + } + tGridSprite.drawImageNum++; + } + return tGridSprite; + } + return null; + } + setViewPortPivotByScale(scaleX, scaleY) { + this._pivotScaleX = scaleX; + this._pivotScaleY = scaleY; + } + set scale(scale) { + if (scale <= 0) + return; + this._scale = scale; + this._viewPortWidth = this._rect.width / scale; + this._viewPortHeight = this._rect.height / scale; + this._mapSprite.scale(this._scale, this._scale); + this.updateViewPort(); + } + get scale() { + return this._scale; + } + moveViewPort(moveX, moveY) { + this._x = -moveX; + this._y = -moveY; + this._rect.x = moveX; + this._rect.y = moveY; + this.updateViewPort(); + } + changeViewPort(moveX, moveY, width, height) { + if (moveX == this._rect.x && moveY == this._rect.y && width == this._rect.width && height == this._rect.height) + return; + this._x = -moveX; + this._y = -moveY; + this._rect.x = moveX; + this._rect.y = moveY; + this._rect.width = width; + this._rect.height = height; + this._viewPortWidth = width / this._scale; + this._viewPortHeight = height / this._scale; + this.updateViewPort(); + } + changeViewPortBySize(width, height, rect = null) { + if (rect == null) { + rect = new Laya.Rectangle(); + } + this._centerX = this._rect.x + this._rect.width * this._pivotScaleX; + this._centerY = this._rect.y + this._rect.height * this._pivotScaleY; + rect.x = this._centerX - width * this._pivotScaleX; + rect.y = this._centerY - height * this._pivotScaleY; + rect.width = width; + rect.height = height; + this.changeViewPort(rect.x, rect.y, rect.width, rect.height); + return rect; + } + updateViewPort() { + this._centerX = this._rect.x + this._rect.width * this._pivotScaleX; + this._centerY = this._rect.y + this._rect.height * this._pivotScaleY; + var posChanged = false; + var preValue = this._viewPortX; + this._viewPortX = this._centerX - this._rect.width * this._pivotScaleX / this._scale; + if (preValue != this._viewPortX) { + posChanged = true; + } + else { + preValue = this._viewPortY; + } + this._viewPortY = this._centerY - this._rect.height * this._pivotScaleY / this._scale; + if (!posChanged && preValue != this._viewPortY) { + posChanged = true; + } + if (this._limitRange) { + var tRight = this._viewPortX + this._viewPortWidth; + if (tRight > this._width) { + this._viewPortX = this._width - this._viewPortWidth; + } + var tBottom = this._viewPortY + this._viewPortHeight; + if (tBottom > this._height) { + this._viewPortY = this._height - this._viewPortHeight; + } + if (this._viewPortX < 0) { + this._viewPortX = 0; + } + if (this._viewPortY < 0) { + this._viewPortY = 0; + } + } + var tPaddingRect = this._paddingRect; + this._mapRect.top = Math.floor((this._viewPortY - tPaddingRect.y) / this._gridHeight); + this._mapRect.bottom = Math.floor((this._viewPortY + this._viewPortHeight + tPaddingRect.height + tPaddingRect.y) / this._gridHeight); + this._mapRect.left = Math.floor((this._viewPortX - tPaddingRect.x) / this._gridWidth); + this._mapRect.right = Math.floor((this._viewPortX + this._viewPortWidth + tPaddingRect.width + tPaddingRect.x) / this._gridWidth); + if (this._mapRect.top != this._mapLastRect.top || this._mapRect.bottom != this._mapLastRect.bottom || this._mapRect.left != this._mapLastRect.left || this._mapRect.right != this._mapLastRect.right) { + this.clipViewPort(); + this._mapLastRect.top = this._mapRect.top; + this._mapLastRect.bottom = this._mapRect.bottom; + this._mapLastRect.left = this._mapRect.left; + this._mapLastRect.right = this._mapRect.right; + posChanged = true; + } + if (!posChanged) + return; + var tMapLayer; + var len = this._renderLayerArray.length; + for (var i = 0; i < len; i++) { + tMapLayer = this._renderLayerArray[i]; + if (tMapLayer._gridSpriteArray.length > 0) + tMapLayer.updateGridPos(); + } + } + clipViewPort() { + var tSub = 0; + var tAdd = 0; + var i, j; + if (this._mapRect.left > this._mapLastRect.left) { + tSub = this._mapRect.left - this._mapLastRect.left; + if (tSub > 0) { + for (j = this._mapLastRect.left; j < this._mapLastRect.left + tSub; j++) { + for (i = this._mapLastRect.top; i <= this._mapLastRect.bottom; i++) { + this.hideGrid(j, i); + } + } + } + } + else { + tAdd = Math.min(this._mapLastRect.left, this._mapRect.right + 1) - this._mapRect.left; + if (tAdd > 0) { + for (j = this._mapRect.left; j < this._mapRect.left + tAdd; j++) { + for (i = this._mapRect.top; i <= this._mapRect.bottom; i++) { + this.showGrid(j, i); + } + } + } + } + if (this._mapRect.right > this._mapLastRect.right) { + tAdd = this._mapRect.right - this._mapLastRect.right; + if (tAdd > 0) { + for (j = Math.max(this._mapLastRect.right + 1, this._mapRect.left); j <= this._mapLastRect.right + tAdd; j++) { + for (i = this._mapRect.top; i <= this._mapRect.bottom; i++) { + this.showGrid(j, i); + } + } + } + } + else { + tSub = this._mapLastRect.right - this._mapRect.right; + if (tSub > 0) { + for (j = this._mapRect.right + 1; j <= this._mapRect.right + tSub; j++) { + for (i = this._mapLastRect.top; i <= this._mapLastRect.bottom; i++) { + this.hideGrid(j, i); + } + } + } + } + if (this._mapRect.top > this._mapLastRect.top) { + tSub = this._mapRect.top - this._mapLastRect.top; + if (tSub > 0) { + for (i = this._mapLastRect.top; i < this._mapLastRect.top + tSub; i++) { + for (j = this._mapLastRect.left; j <= this._mapLastRect.right; j++) { + this.hideGrid(j, i); + } + } + } + } + else { + tAdd = Math.min(this._mapLastRect.top, this._mapRect.bottom + 1) - this._mapRect.top; + if (tAdd > 0) { + for (i = this._mapRect.top; i < this._mapRect.top + tAdd; i++) { + for (j = this._mapRect.left; j <= this._mapRect.right; j++) { + this.showGrid(j, i); + } + } + } + } + if (this._mapRect.bottom > this._mapLastRect.bottom) { + tAdd = this._mapRect.bottom - this._mapLastRect.bottom; + if (tAdd > 0) { + for (i = Math.max(this._mapLastRect.bottom + 1, this._mapRect.top); i <= this._mapLastRect.bottom + tAdd; i++) { + for (j = this._mapRect.left; j <= this._mapRect.right; j++) { + this.showGrid(j, i); + } + } + } + } + else { + tSub = this._mapLastRect.bottom - this._mapRect.bottom; + if (tSub > 0) { + for (i = this._mapRect.bottom + 1; i <= this._mapRect.bottom + tSub; i++) { + for (j = this._mapLastRect.left; j <= this._mapLastRect.right; j++) { + this.hideGrid(j, i); + } + } + } + } + } + showGrid(gridX, gridY) { + if (gridX < 0 || gridX >= this._gridW || gridY < 0 || gridY >= this._gridH) { + return; + } + var i; + var tGridSprite; + var tTempArray = this._gridArray[gridY][gridX]; + if (tTempArray == null) { + tTempArray = this.getGridArray(gridX, gridY); + } + else { + for (i = 0; i < tTempArray.length && i < this._layerArray.length; i++) { + var tLayerSprite = this._layerArray[i]; + if (tLayerSprite && tTempArray[i]) { + tGridSprite = tTempArray[i]; + if (tGridSprite.visible == false && tGridSprite.drawImageNum > 0) { + tGridSprite.show(); + } + } + } + } + } + cacheAllGrid() { + var i, j; + var tempArr; + for (i = 0; i < this._gridW; i++) { + for (j = 0; j < this._gridH; j++) { + tempArr = this.getGridArray(i, j); + this.cacheGridsArray(tempArr); + } + } + } + cacheGridsArray(arr) { + var canvas; + if (!TiledMap._tempCanvas) { + TiledMap._tempCanvas = new Laya.HTMLCanvas(); + var tx = TiledMap._tempCanvas.context; + if (!tx) { + tx = TiledMap._tempCanvas.getContext('2d'); + } + } + canvas = TiledMap._tempCanvas; + canvas.context.asBitmap = false; + var i, len; + len = arr.length; + var tGrid; + for (i = 0; i < len; i++) { + tGrid = arr[i]; + canvas.clear(); + canvas.size(1, 1); + tGrid.render(canvas.context, 0, 0); + tGrid.hide(); + } + canvas.clear(); + canvas.size(1, 1); + } + getGridArray(gridX, gridY) { + var i, j; + var tGridSprite; + var tTempArray = this._gridArray[gridY][gridX]; + if (tTempArray == null) { + tTempArray = this._gridArray[gridY][gridX] = []; + var tLeft = 0; + var tRight = 0; + var tTop = 0; + var tBottom = 0; + var tGridWidth = this._gridWidth; + var tGridHeight = this._gridHeight; + switch (this.orientation) { + case TiledMap.ORIENTATION_ISOMETRIC: + tLeft = Math.floor(gridX * tGridWidth); + tRight = Math.floor(gridX * tGridWidth + tGridWidth); + tTop = Math.floor(gridY * tGridHeight); + tBottom = Math.floor(gridY * tGridHeight + tGridHeight); + var tLeft1, tRight1, tTop1, tBottom1; + break; + case TiledMap.ORIENTATION_STAGGERED: + tLeft = Math.floor(gridX * tGridWidth / this._mapTileW); + tRight = Math.floor((gridX * tGridWidth + tGridWidth) / this._mapTileW); + tTop = Math.floor(gridY * tGridHeight / (this._mapTileH / 2)); + tBottom = Math.floor((gridY * tGridHeight + tGridHeight) / (this._mapTileH / 2)); + break; + case TiledMap.ORIENTATION_ORTHOGONAL: + tLeft = Math.floor(gridX * tGridWidth / this._mapTileW); + tRight = Math.floor((gridX * tGridWidth + tGridWidth) / this._mapTileW); + tTop = Math.floor(gridY * tGridHeight / this._mapTileH); + tBottom = Math.floor((gridY * tGridHeight + tGridHeight) / this._mapTileH); + break; + case TiledMap.ORIENTATION_HEXAGONAL: + var tHeight = this._mapTileH * 2 / 3; + tLeft = Math.floor(gridX * tGridWidth / this._mapTileW); + tRight = Math.ceil((gridX * tGridWidth + tGridWidth) / this._mapTileW); + tTop = Math.floor(gridY * tGridHeight / tHeight); + tBottom = Math.ceil((gridY * tGridHeight + tGridHeight) / tHeight); + break; + } + var tLayer = null; + var tTGridSprite; + var tDrawMapLayer; + for (var z = 0; z < this._layerArray.length; z++) { + tLayer = this._layerArray[z]; + if (this.enableMergeLayer) { + if (tLayer.tarLayer != tDrawMapLayer) { + tTGridSprite = null; + tDrawMapLayer = tLayer.tarLayer; + } + if (!tTGridSprite) { + tTGridSprite = tDrawMapLayer.getDrawSprite(gridX, gridY); + tTempArray.push(tTGridSprite); + } + tGridSprite = tTGridSprite; + } + else { + tGridSprite = tLayer.getDrawSprite(gridX, gridY); + tTempArray.push(tGridSprite); + } + var tColorStr; + if (this._showGridKey) { + tColorStr = "#"; + tColorStr += this._colorArray[Math.floor(Math.random() * this._colorArray.length)]; + tColorStr += this._colorArray[Math.floor(Math.random() * this._colorArray.length)]; + tColorStr += this._colorArray[Math.floor(Math.random() * this._colorArray.length)]; + } + switch (this.orientation) { + case TiledMap.ORIENTATION_ISOMETRIC: + var tHalfTileHeight = this.tileHeight / 2; + var tHalfTileWidth = this.tileWidth / 2; + var tHalfMapWidth = this._width / 2; + tTop1 = Math.floor(tTop / tHalfTileHeight); + tBottom1 = Math.floor(tBottom / tHalfTileHeight); + tLeft1 = this._mapW + Math.floor((tLeft - tHalfMapWidth) / tHalfTileWidth); + tRight1 = this._mapW + Math.floor((tRight - tHalfMapWidth) / tHalfTileWidth); + var tMapW = this._mapW * 2; + var tMapH = this._mapH * 2; + if (tTop1 < 0) { + tTop1 = 0; + } + if (tTop1 >= tMapH) { + tTop1 = tMapH - 1; + } + if (tBottom1 < 0) { + tBottom = 0; + } + if (tBottom1 >= tMapH) { + tBottom1 = tMapH - 1; + } + tGridSprite.zOrder = this._totalGridNum * z + gridY * this._gridW + gridX; + for (i = tTop1; i < tBottom1; i++) { + for (j = 0; j <= i; j++) { + var tIndexX = i - j; + var tIndexY = j; + var tIndexValue = (tIndexX - tIndexY) + this._mapW; + if (tIndexValue > tLeft1 && tIndexValue <= tRight1) { + if (tLayer.drawTileTexture(tGridSprite, tIndexX, tIndexY)) { + tGridSprite.drawImageNum++; + } + } + } + } + break; + case TiledMap.ORIENTATION_STAGGERED: + tGridSprite.zOrder = z * this._totalGridNum + gridY * this._gridW + gridX; + for (i = tTop; i < tBottom; i++) { + for (j = tLeft; j < tRight; j++) { + if (tLayer.drawTileTexture(tGridSprite, j, i)) { + tGridSprite.drawImageNum++; + } + } + } + break; + case TiledMap.ORIENTATION_ORTHOGONAL: + case TiledMap.ORIENTATION_HEXAGONAL: + switch (this._renderOrder) { + case TiledMap.RENDERORDER_RIGHTDOWN: + tGridSprite.zOrder = z * this._totalGridNum + gridY * this._gridW + gridX; + for (i = tTop; i < tBottom; i++) { + for (j = tLeft; j < tRight; j++) { + if (tLayer.drawTileTexture(tGridSprite, j, i)) { + tGridSprite.drawImageNum++; + } + } + } + break; + case TiledMap.RENDERORDER_RIGHTUP: + tGridSprite.zOrder = z * this._totalGridNum + (this._gridH - 1 - gridY) * this._gridW + gridX; + for (i = tBottom - 1; i >= tTop; i--) { + for (j = tLeft; j < tRight; j++) { + if (tLayer.drawTileTexture(tGridSprite, j, i)) { + tGridSprite.drawImageNum++; + } + } + } + break; + case TiledMap.RENDERORDER_LEFTDOWN: + tGridSprite.zOrder = z * this._totalGridNum + gridY * this._gridW + (this._gridW - 1 - gridX); + for (i = tTop; i < tBottom; i++) { + for (j = tRight - 1; j >= tLeft; j--) { + if (tLayer.drawTileTexture(tGridSprite, j, i)) { + tGridSprite.drawImageNum++; + } + } + } + break; + case TiledMap.RENDERORDER_LEFTUP: + tGridSprite.zOrder = z * this._totalGridNum + (this._gridH - 1 - gridY) * this._gridW + (this._gridW - 1 - gridX); + for (i = tBottom - 1; i >= tTop; i--) { + for (j = tRight - 1; j >= tLeft; j--) { + if (tLayer.drawTileTexture(tGridSprite, j, i)) { + tGridSprite.drawImageNum++; + } + } + } + break; + } + break; + } + if (!tGridSprite.isHaveAnimation) { + tGridSprite.autoSize = true; + if (this.autoCache) + tGridSprite.cacheAs = this.autoCacheType; + tGridSprite.autoSize = false; + } + if (!this.enableMergeLayer) { + if (tGridSprite.drawImageNum > 0) { + tLayer.addChild(tGridSprite); + } + if (this._showGridKey) { + tGridSprite.graphics.drawRect(0, 0, tGridWidth, tGridHeight, null, tColorStr); + } + } + else { + if (tTGridSprite && tTGridSprite.drawImageNum > 0 && tDrawMapLayer) { + tDrawMapLayer.addChild(tTGridSprite); + } + } + } + if (this.enableMergeLayer && this.showGridTextureCount) { + if (tTGridSprite) { + tTGridSprite.graphics.fillText(tTGridSprite.drawImageNum + "", 20, 20, null, "#ff0000", "left"); + } + } + } + return tTempArray; + } + hideGrid(gridX, gridY) { + if (gridX < 0 || gridX >= this._gridW || gridY < 0 || gridY >= this._gridH) { + return; + } + var tTempArray = this._gridArray[gridY][gridX]; + if (tTempArray) { + var tGridSprite; + for (var i = 0; i < tTempArray.length; i++) { + tGridSprite = tTempArray[i]; + if (tGridSprite.drawImageNum > 0) { + if (tGridSprite != null) { + tGridSprite.hide(); + } + } + } + } + } + getLayerObject(layerName, objectName) { + var tLayer = null; + for (var i = 0; i < this._layerArray.length; i++) { + tLayer = this._layerArray[i]; + if (tLayer.layerName == layerName) { + break; + } + } + if (tLayer) { + return tLayer.getObjectByName(objectName); + } + return null; + } + destroy() { + this._orientation = TiledMap.ORIENTATION_ORTHOGONAL; + this._jsonData = null; + var i = 0; + this._gridArray = []; + var tTileTexSet; + for (i = 0; i < this._tileTexSetArr.length; i++) { + tTileTexSet = this._tileTexSetArr[i]; + if (tTileTexSet) { + tTileTexSet.clearAll(); + } + } + this._tileTexSetArr = []; + var tTexture; + for (i = 0; i < this._texArray.length; i++) { + tTexture = this._texArray[i]; + tTexture.destroy(); + } + this._texArray = []; + this._width = 0; + this._height = 0; + this._mapW = 0; + this._mapH = 0; + this._mapTileW = 0; + this._mapTileH = 0; + this._rect.setTo(0, 0, 0, 0); + var tLayer; + for (i = 0; i < this._layerArray.length; i++) { + tLayer = this._layerArray[i]; + tLayer.clearAll(); + } + this._layerArray = []; + this._renderLayerArray = []; + if (this._mapSprite) { + this._mapSprite.destroy(); + this._mapSprite = null; + } + this._jsonLoader = null; + this._loader = null; + var tDic = this._animationDic; + for (var p in tDic) { + delete tDic[p]; + } + this._properties = null; + tDic = this._tileProperties; + for (p in tDic) { + delete tDic[p]; + } + this._currTileSet = null; + this._completeHandler = null; + this._mapRect.clearAll(); + this._mapLastRect.clearAll(); + this._tileSetArray = []; + this._gridWidth = 450; + this._gridHeight = 450; + this._gridW = 0; + this._gridH = 0; + this._x = 0; + this._y = 0; + this._index = 0; + this._enableLinear = true; + this._resPath = null; + this._pathArray = null; + } + get tileWidth() { + return this._mapTileW; + } + get tileHeight() { + return this._mapTileH; + } + get width() { + return this._width; + } + get height() { + return this._height; + } + get numColumnsTile() { + return this._mapW; + } + get numRowsTile() { + return this._mapH; + } + get viewPortX() { + return -this._viewPortX; + } + get viewPortY() { + return -this._viewPortY; + } + get viewPortWidth() { + return this._viewPortWidth; + } + get viewPortHeight() { + return this._viewPortHeight; + } + get x() { + return this._x; + } + get y() { + return this._y; + } + get gridWidth() { + return this._gridWidth; + } + get gridHeight() { + return this._gridHeight; + } + get numColumnsGrid() { + return this._gridW; + } + get numRowsGrid() { + return this._gridH; + } + get orientation() { + return this._orientation; + } + get renderOrder() { + return this._renderOrder; + } + mapSprite() { + return this._mapSprite; + } + getLayerByName(layerName) { + var tMapLayer; + for (var i = 0; i < this._layerArray.length; i++) { + tMapLayer = this._layerArray[i]; + if (layerName == tMapLayer.layerName) { + return tMapLayer; + } + } + return null; + } + getLayerByIndex(index) { + if (index < this._layerArray.length) { + return this._layerArray[index]; + } + return null; + } + } + TiledMap.ORIENTATION_ORTHOGONAL = "orthogonal"; + TiledMap.ORIENTATION_ISOMETRIC = "isometric"; + TiledMap.ORIENTATION_STAGGERED = "staggered"; + TiledMap.ORIENTATION_HEXAGONAL = "hexagonal"; + TiledMap.RENDERORDER_RIGHTDOWN = "right-down"; + TiledMap.RENDERORDER_RIGHTUP = "right-up"; + TiledMap.RENDERORDER_LEFTDOWN = "left-down"; + TiledMap.RENDERORDER_LEFTUP = "left-up"; + class GRect { + clearAll() { + this.left = this.top = this.right = this.bottom = 0; + } + } + class TileMapAniData { + constructor() { + this.mAniIdArray = []; + this.mDurationTimeArray = []; + this.mTileTexSetArr = []; + } + } + class TileSet { + constructor() { + this.firstgid = 0; + this.image = ""; + this.imageheight = 0; + this.imagewidth = 0; + this.margin = 0; + this.name = 0; + this.spacing = 0; + this.tileheight = 0; + this.tilewidth = 0; + this.titleoffsetX = 0; + this.titleoffsetY = 0; + } + init(data) { + this.firstgid = data.firstgid; + this.image = data.image; + this.imageheight = data.imageheight; + this.imagewidth = data.imagewidth; + this.margin = data.margin; + this.name = data.name; + this.properties = data.properties; + this.spacing = data.spacing; + this.tileheight = data.tileheight; + this.tilewidth = data.tilewidth; + this.tileproperties = data.tileproperties; + var tTileoffset = data.tileoffset; + if (tTileoffset) { + this.titleoffsetX = tTileoffset.x; + this.titleoffsetY = tTileoffset.y; + } + } + } + IMap.TiledMap = TiledMap; + + exports.GridSprite = GridSprite; + exports.IMap = IMap; + exports.MapLayer = MapLayer; + exports.TileAniSprite = TileAniSprite; + exports.TileTexSet = TileTexSet; + exports.TiledMap = TiledMap; + +}(window.Laya = window.Laya || {}, Laya)); diff --git a/examples/layaair/frontend/bin/libs/laya.ttmini.js b/examples/layaair/frontend/bin/libs/laya.ttmini.js new file mode 100644 index 0000000..cef2d4d --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.ttmini.js @@ -0,0 +1,1856 @@ +window.ttMiniGame = function (exports, Laya) { + 'use strict'; + + function ImageDataPolyfill() { + let width, height, data; + if (arguments.length == 3) { + if (arguments[0] instanceof Uint8ClampedArray) { + if (arguments[0].length % 4 !== 0) { + throw new Error("Failed to construct 'ImageData': The input data length is not a multiple of 4."); + } + if (arguments[0].length !== arguments[1] * arguments[2] * 4) { + throw new Error("Failed to construct 'ImageData': The input data length is not equal to (4 * width * height)."); + } + else { + data = arguments[0]; + width = arguments[1]; + height = arguments[2]; + } + } + else { + throw new Error("Failed to construct 'ImageData': parameter 1 is not of type 'Uint8ClampedArray'."); + } + } + else if (arguments.length == 2) { + width = arguments[0]; + height = arguments[1]; + data = new Uint8ClampedArray(arguments[0] * arguments[1] * 4); + } + else if (arguments.length < 2) { + throw new Error("Failed to construct 'ImageData': 2 arguments required, but only " + arguments.length + " present."); + } + let imgdata = Laya.Browser.canvas.getContext("2d").getImageData(0, 0, width, height); + for (let i = 0; i < data.length; i += 4) { + imgdata.data[i] = data[i]; + imgdata.data[i + 1] = data[i + 1]; + imgdata.data[i + 2] = data[i + 2]; + imgdata.data[i + 3] = data[i + 3]; + } + return imgdata; + } + + class MiniFileMgr { + static isLocalNativeFile(url) { + for (var i = 0, sz = TTMiniAdapter.nativefiles.length; i < sz; i++) { + if (url.indexOf(TTMiniAdapter.nativefiles[i]) != -1) + return true; + } + return false; + } + static isNetFile(url) { + return (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) && url.indexOf(TTMiniAdapter.window.tt.env.USER_DATA_PATH) == -1; + } + static getFileInfo(fileUrl) { + var fileNativePath = fileUrl; + var fileObj = MiniFileMgr.fakeObj[fileNativePath]; + if (fileObj == null) + return null; + else + return fileObj; + } + static read(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "") { + var fileUrl; + if (readyUrl != "" && (readyUrl.indexOf("http://") != -1 || readyUrl.indexOf("https://") != -1)) { + fileUrl = MiniFileMgr.getFileNativePath(filePath); + } + else { + fileUrl = filePath; + } + fileUrl = Laya.URL.getAdptedFilePath(fileUrl); + MiniFileMgr.fs.readFile({ filePath: fileUrl, encoding: encoding, success: function (data) { + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data && readyUrl != "") + MiniFileMgr.downFiles(TTMiniAdapter.safeEncodeURI(readyUrl), encoding, callBack, readyUrl, isSaveFile, fileType); + else + callBack != null && callBack.runWith([1]); + } }); + } + static isFile(url) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(url); + } + catch (err) { + return false; + } + return stat.isFile(); + } + static downFiles(fileUrl, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + var downloadTask = MiniFileMgr.down({ url: fileUrl, success: function (data) { + if (data.statusCode === 200) + MiniFileMgr.readFile(data.tempFilePath, encoding, callBack, readyUrl, isSaveFile, fileType, isAutoClear); + else if (data.statusCode === 403) { + callBack != null && callBack.runWith([0, fileUrl]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + downloadTask.onProgressUpdate(function (data) { + callBack != null && callBack.runWith([2, data.progress]); + }); + } + static readFile(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + filePath = Laya.URL.getAdptedFilePath(filePath); + MiniFileMgr.fs.readFile({ filePath: filePath, encoding: encoding, success: function (data) { + if ((filePath.indexOf("http://") != -1 || filePath.indexOf("https://") != -1) && filePath.indexOf(TTMiniAdapter.window.tt.env.USER_DATA_PATH) == -1) { + if (TTMiniAdapter.AutoCacheDownFile || isSaveFile) { + callBack != null && callBack.runWith([0, data]); + MiniFileMgr.copyTOCache(filePath, readyUrl, null, encoding, isAutoClear); + } + else + callBack != null && callBack.runWith([0, data]); + } + else + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data) + callBack != null && callBack.runWith([1, data]); + } }); + } + static downOtherFiles(fileUrl, callBack = null, readyUrl = "", isSaveFile = false, isAutoClear = true) { + MiniFileMgr.down({ url: fileUrl, success: function (data) { + if (data.statusCode === 200) { + if ((TTMiniAdapter.autoCacheFile || isSaveFile) && readyUrl.indexOf(".php") == -1) { + callBack != null && callBack.runWith([0, data.tempFilePath]); + MiniFileMgr.copyTOCache(data.tempFilePath, readyUrl, null, "", isAutoClear); + } + else + callBack != null && callBack.runWith([0, data.tempFilePath]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static copyFile(src, dest, complete = null) { + MiniFileMgr.fs.copyFile({ + srcPath: src, + destPath: dest, + success: function () { + complete && complete.runWith(0); + }, + fail: function (err) { + complete && complete.runWith([1, err]); + } + }); + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + if (window.navigator.userAgent.indexOf('MiniGame') < 0) { + Laya.Laya.loader.load(fileUrl, callBack); + } + else { + if (fileType == Laya.Loader.IMAGE || fileType == Laya.Loader.SOUND) + MiniFileMgr.downOtherFiles(fileUrl, callBack, fileUrl, true, false); + else + MiniFileMgr.downFiles(fileUrl, encoding, callBack, fileUrl, true, fileType, false); + } + } + static copyTOCache(tempFilePath, readyUrl, callBack, encoding = "", isAutoClear = true) { + var temp = tempFilePath.split("/"); + var tempFileName = temp[temp.length - 1]; + var fileurlkey = readyUrl; + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fakeObj[fileurlkey] = { md5: tempFileName, readyUrl: readyUrl, size: 0, times: Laya.Browser.now(), encoding: encoding, tempFilePath: tempFilePath }; + var totalSize = TTMiniAdapter.sizeLimit; + var chaSize = 4 * 1024 * 1024; + var fileUseSize = MiniFileMgr.getCacheUseSize(); + if (fileObj) { + if (fileObj.readyUrl != readyUrl) { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > TTMiniAdapter.minClearSize) + TTMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.deleteFile(tempFilePath, readyUrl, callBack, encoding, data.size); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + else + callBack != null && callBack.runWith([0]); + } + else { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > TTMiniAdapter.minClearSize) + TTMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.fs.copyFile({ srcPath: tempFilePath, destPath: saveFilePath, success: function (data2) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, data.size); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + } + static onClearCacheRes() { + var memSize = TTMiniAdapter.minClearSize; + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + MiniFileMgr.sortOn(tempFileListArr, "times", MiniFileMgr.NUMERIC); + var clearSize = 0; + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + if (clearSize >= memSize) + break; + clearSize += fileObj.size; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + } + static sortOn(array, name, options = 0) { + if (options == MiniFileMgr.NUMERIC) + return array.sort(function (a, b) { return a[name] - b[name]; }); + if (options == (MiniFileMgr.NUMERIC | MiniFileMgr.DESCENDING)) + return array.sort(function (a, b) { return b[name] - a[name]; }); + return array.sort(function (a, b) { return a[name] - b[name]; }); + } + static getFileNativePath(fileName) { + return MiniFileMgr.fileNativeDir + "/" + fileName; + } + static deleteFile(tempFileName, readyUrl = "", callBack = null, encoding = "", fileSize = 0) { + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var deleteFileUrl = MiniFileMgr.getFileNativePath(fileObj.md5); + MiniFileMgr.fs.unlink({ filePath: deleteFileUrl, success: function (data) { + if (tempFileName != "") { + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fs.copyFile({ srcPath: tempFileName, destPath: saveFilePath, success: function (data) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, fileSize); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + else { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, false, encoding, callBack, fileSize); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static deleteAll() { + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj.fileUsedSize) { + MiniFileMgr.filesListObj.fileUsedSize = 0; + } + MiniFileMgr.writeFilesList("", JSON.stringify({}), false); + } + static onSaveFile(readyUrl, md5Name, isAdd = true, encoding = "", callBack = null, fileSize = 0) { + var fileurlkey = readyUrl; + if (MiniFileMgr.filesListObj['fileUsedSize'] == null) + MiniFileMgr.filesListObj['fileUsedSize'] = 0; + if (isAdd) { + var fileNativeName = MiniFileMgr.getFileNativePath(md5Name); + MiniFileMgr.filesListObj[fileurlkey] = { md5: md5Name, readyUrl: readyUrl, size: fileSize, times: Laya.Browser.now(), encoding: encoding, tempFilePath: fileNativeName }; + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) + fileSize; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), true); + callBack != null && callBack.runWith([0]); + } + else { + if (MiniFileMgr.filesListObj[fileurlkey]) { + var deletefileSize = parseInt(MiniFileMgr.filesListObj[fileurlkey].size); + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) - deletefileSize; + if (MiniFileMgr.fakeObj[fileurlkey].md5 == MiniFileMgr.filesListObj[fileurlkey].md5) { + delete MiniFileMgr.fakeObj[fileurlkey]; + } + delete MiniFileMgr.filesListObj[fileurlkey]; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), false); + callBack != null && callBack.runWith([0]); + } + } + } + static writeFilesList(fileurlkey, filesListStr, isAdd) { + var listFilesPath = MiniFileMgr.fileNativeDir + "/" + MiniFileMgr.fileListName; + MiniFileMgr.fs.writeFile({ filePath: listFilesPath, encoding: 'utf8', data: filesListStr, success: function (data) { + }, fail: function (data) { + } }); + if (!TTMiniAdapter.isZiYu && TTMiniAdapter.isPosMsgYu) { + TTMiniAdapter.window.tt.postMessage({ url: fileurlkey, data: MiniFileMgr.filesListObj[fileurlkey], isLoad: "filenative", isAdd: isAdd }); + } + } + static getCacheUseSize() { + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj['fileUsedSize']) + return MiniFileMgr.filesListObj['fileUsedSize']; + return 0; + } + static getCacheList(dirPath, cb) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(dirPath); + } + catch (err) { + stat = null; + } + if (stat) { + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", cb); + } + else { + MiniFileMgr.fs.mkdirSync(dirPath, true); + cb && cb.runWith([1]); + } + } + static existDir(dirPath, callBack) { + MiniFileMgr.fs.mkdir({ dirPath: dirPath, success: function (data) { + callBack != null && callBack.runWith([0, { data: JSON.stringify({}) }]); + }, fail: function (data) { + if (data.errMsg.indexOf("file already exists") != -1) + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", callBack); + else + callBack != null && callBack.runWith([1, data]); + } }); + } + static readSync(filePath, encoding = "utf8", callBack = null, readyUrl = "") { + var fileUrl = MiniFileMgr.getFileNativePath(filePath); + var filesListStr; + try { + filesListStr = MiniFileMgr.fs.readFileSync(fileUrl, encoding); + callBack != null && callBack.runWith([0, { data: filesListStr }]); + } + catch (error) { + callBack != null && callBack.runWith([1]); + } + } + static setNativeFileDir(value) { + MiniFileMgr.fileNativeDir = TTMiniAdapter.window.tt.env.USER_DATA_PATH + value; + } + } + MiniFileMgr.fs = window.tt.getFileSystemManager(); + MiniFileMgr.down = window.tt.downloadFile; + MiniFileMgr.filesListObj = {}; + MiniFileMgr.fakeObj = {}; + MiniFileMgr.fileListName = "layaairfiles.txt"; + MiniFileMgr.ziyuFileData = {}; + MiniFileMgr.ziyuFileTextureData = {}; + MiniFileMgr.loadPath = ""; + MiniFileMgr.DESCENDING = 2; + MiniFileMgr.NUMERIC = 16; + + class MiniSoundChannel extends Laya.SoundChannel { + constructor(audio, miniSound) { + super(); + this._audio = audio; + this._miniSound = miniSound; + this._onEnd = MiniSoundChannel.bindToThis(this.__onEnd, this); + audio.onEnded(this._onEnd); + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + __onEnd() { + if (this.loops == 1) { + if (this.completeHandler) { + Laya.Laya.systemTimer.once(10, this, this.__runComplete, [this.completeHandler], false); + this.completeHandler = null; + } + this.stop(); + this.event(Laya.Event.COMPLETE); + return; + } + if (this.loops > 0) { + this.loops--; + } + this.startTime = 0; + this.play(); + } + play() { + this.isStopped = false; + Laya.SoundManager.addChannel(this); + this._audio.play(); + } + set startTime(time) { + if (this._audio) { + this._audio.startTime = time; + } + } + set autoplay(value) { + this._audio.autoplay = value; + } + get autoplay() { + return this._audio.autoplay; + } + get position() { + if (!this._audio) + return 0; + return this._audio.currentTime; + } + get duration() { + if (!this._audio) + return 0; + return this._audio.duration; + } + stop() { + this.isStopped = true; + Laya.SoundManager.removeChannel(this); + this.completeHandler = null; + if (!this._audio) + return; + this._audio.stop(); + if (!this.loop) { + this._audio.offEnded(null); + this._miniSound.dispose(); + this._audio = null; + this._miniSound = null; + this._onEnd = null; + } + } + pause() { + this.isStopped = true; + this._audio.pause(); + } + get loop() { + return this._audio.loop; + } + set loop(value) { + this._audio.loop = value; + } + resume() { + if (!this._audio) + return; + this.isStopped = false; + Laya.SoundManager.addChannel(this); + this._audio.play(); + } + set volume(v) { + if (!this._audio) + return; + this._audio.volume = v; + } + get volume() { + if (!this._audio) + return 1; + return this._audio.volume; + } + } + + class MiniSound extends Laya.EventDispatcher { + constructor() { + super(); + this.loaded = false; + } + static _createSound() { + MiniSound._id++; + return TTMiniAdapter.window.tt.createInnerAudioContext(); + } + load(url) { + if (!MiniSound._musicAudio) + MiniSound._musicAudio = MiniSound._createSound(); + if (!MiniFileMgr.isLocalNativeFile(url)) { + url = Laya.URL.formatURL(url); + } + else { + if (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + if (tempStr != "") + url = url.split(tempStr)[1]; + } + } + } + this.url = url; + this.readyUrl = url; + if (MiniSound._audioCache[this.readyUrl]) { + this.event(Laya.Event.COMPLETE); + return; + } + if (TTMiniAdapter.autoCacheFile && MiniFileMgr.getFileInfo(url)) { + this.onDownLoadCallBack(url, 0); + } + else { + if (!TTMiniAdapter.autoCacheFile) { + this.onDownLoadCallBack(url, 0); + } + else { + if (MiniFileMgr.isLocalNativeFile(url)) { + tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + if (TTMiniAdapter.subNativeFiles && TTMiniAdapter.subNativeheads.length == 0) { + for (var key in TTMiniAdapter.subNativeFiles) { + var tempArr = TTMiniAdapter.subNativeFiles[key]; + TTMiniAdapter.subNativeheads = TTMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + TTMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (TTMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && TTMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = TTMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + this.onDownLoadCallBack(url, 0); + } + else { + if (!MiniFileMgr.isLocalNativeFile(url) && (url.indexOf("http://") == -1 && url.indexOf("https://") == -1) || (url.indexOf("http://usr/") != -1)) { + this.onDownLoadCallBack(url, 0); + } + else { + MiniFileMgr.downOtherFiles(TTMiniAdapter.safeEncodeURI(url), Laya.Handler.create(this, this.onDownLoadCallBack, [url]), url); + } + } + } + } + } + onDownLoadCallBack(sourceUrl, errorCode, tempFilePath = null) { + if (!errorCode) { + var fileNativeUrl; + if (TTMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = sourceUrl; + if (tempStr != "" && (sourceUrl.indexOf("http://") != -1 || sourceUrl.indexOf("https://") != -1)) + fileNativeUrl = sourceUrl.split(tempStr)[1]; + if (!fileNativeUrl) { + fileNativeUrl = tempUrl; + } + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + var fileMd5Name = fileObj.md5; + fileNativeUrl = MiniFileMgr.getFileNativePath(fileMd5Name); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + if (this.url != Laya.SoundManager._bgMusic) { + this._sound = MiniSound._createSound(); + this._sound.src = this.url = fileNativeUrl; + } + else { + this._sound = MiniSound._musicAudio; + this._sound.src = this.url = fileNativeUrl; + } + } + else { + if (this.url != Laya.SoundManager._bgMusic) { + this._sound = MiniSound._createSound(); + this._sound.src = sourceUrl; + } + else { + this._sound = MiniSound._musicAudio; + this._sound.src = sourceUrl; + } + } + this._sound.onCanplay(MiniSound.bindToThis(this.onCanPlay, this)); + this._sound.onError(MiniSound.bindToThis(this.onError, this)); + } + else { + this.event(Laya.Event.ERROR); + } + } + onError(error) { + try { + console.log("-----1---------------minisound-----id:" + MiniSound._id); + console.log(error); + } + catch (error) { + console.log("-----2---------------minisound-----id:" + MiniSound._id); + console.log(error); + } + this.event(Laya.Event.ERROR); + this._sound.offError(null); + } + onCanPlay() { + this.loaded = true; + this.event(Laya.Event.COMPLETE); + this._sound.offCanplay(null); + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + play(startTime = 0, loops = 0) { + var tSound; + if (this.url == Laya.SoundManager._bgMusic) { + if (!MiniSound._musicAudio) + MiniSound._musicAudio = MiniSound._createSound(); + tSound = MiniSound._musicAudio; + } + else { + if (MiniSound._audioCache[this.readyUrl]) { + tSound = MiniSound._audioCache[this.readyUrl]._sound; + } + else { + tSound = MiniSound._createSound(); + } + } + if (!tSound) + return null; + if (TTMiniAdapter.autoCacheFile && MiniFileMgr.getFileInfo(this.url)) { + var fileObj = MiniFileMgr.getFileInfo(this.url); + var fileMd5Name = fileObj.md5; + tSound.src = this.url = MiniFileMgr.getFileNativePath(fileMd5Name); + } + else { + tSound.src = this.url; + } + var channel = new MiniSoundChannel(tSound, this); + channel.url = this.url; + channel.loops = loops; + channel.loop = (loops === 0 ? true : false); + channel.startTime = startTime; + channel.play(); + Laya.SoundManager.addChannel(channel); + return channel; + } + get duration() { + return this._sound.duration; + } + dispose() { + var ad = MiniSound._audioCache[this.readyUrl]; + if (ad) { + ad.src = ""; + if (ad._sound) { + ad._sound.destroy(); + ad._sound = null; + ad = null; + } + delete MiniSound._audioCache[this.readyUrl]; + } + if (this._sound) { + this._sound.destroy(); + this._sound = null; + this.readyUrl = this.url = null; + } + } + } + MiniSound._id = 0; + MiniSound._audioCache = {}; + + class MiniInput { + constructor() { + } + static _createInputElement() { + Laya.Input['_initInput'](Laya.Input['area'] = Laya.Browser.createElement("textarea")); + Laya.Input['_initInput'](Laya.Input['input'] = Laya.Browser.createElement("input")); + Laya.Input['inputContainer'] = Laya.Browser.createElement("div"); + Laya.Input['inputContainer'].style.position = "absolute"; + Laya.Input['inputContainer'].style.zIndex = 1E5; + Laya.Browser.container.appendChild(Laya.Input['inputContainer']); + Laya.Laya.stage.on("resize", null, MiniInput._onStageResize); + TTMiniAdapter.window.tt.onWindowResize && TTMiniAdapter.window.tt.onWindowResize(function (res) { + }); + Laya.SoundManager._soundClass = MiniSound; + Laya.SoundManager._musicClass = MiniSound; + var model = TTMiniAdapter.systemInfo.model; + var system = TTMiniAdapter.systemInfo.system; + if (model.indexOf("iPhone") != -1) { + Laya.Browser.onIPhone = true; + Laya.Browser.onIOS = true; + Laya.Browser.onIPad = true; + Laya.Browser.onAndroid = false; + } + if (system.indexOf("Android") != -1 || system.indexOf("Adr") != -1) { + Laya.Browser.onAndroid = true; + Laya.Browser.onIPhone = false; + Laya.Browser.onIOS = false; + Laya.Browser.onIPad = false; + } + } + static _onStageResize() { + var ts = Laya.Laya.stage._canvasTransform.identity(); + ts.scale((Laya.Browser.width / Laya.Render.canvas.width / Laya.Browser.pixelRatio), Laya.Browser.height / Laya.Render.canvas.height / Laya.Browser.pixelRatio); + } + static inputFocus(e) { + var _inputTarget = Laya.Input['inputElement'].target; + if (_inputTarget && !_inputTarget.editable) { + return; + } + TTMiniAdapter.window.tt.offKeyboardConfirm(); + TTMiniAdapter.window.tt.offKeyboardInput(); + TTMiniAdapter.window.tt.showKeyboard({ defaultValue: _inputTarget.text, maxLength: _inputTarget.maxChars, multiple: _inputTarget.multiline, confirmHold: true, confirmType: _inputTarget["confirmType"] || 'done', success: function (res) { + }, fail: function (res) { + } }); + TTMiniAdapter.window.tt.onKeyboardConfirm(function (res) { + var str = res ? res.value : ""; + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + MiniInput.inputEnter(); + _inputTarget.event("confirm"); + }); + TTMiniAdapter.window.tt.onKeyboardInput(function (res) { + var str = res ? res.value : ""; + if (!_inputTarget.multiline) { + if (str.indexOf("\n") != -1) { + MiniInput.inputEnter(); + return; + } + } + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + }); + } + static inputEnter() { + Laya.Input['inputElement'].target.focus = false; + } + static inputblur() { + MiniInput.hideKeyboard(); + } + static hideKeyboard() { + TTMiniAdapter.window.tt.offKeyboardConfirm(); + TTMiniAdapter.window.tt.offKeyboardInput(); + TTMiniAdapter.window.tt.hideKeyboard({ success: function (res) { + console.log('隐藏键盘'); + }, fail: function (res) { + console.log("隐藏键盘出错:" + (res ? res.errMsg : "")); + } }); + } + } + + class MiniLoader extends Laya.EventDispatcher { + constructor() { + super(); + } + _loadResourceFilter(type, url) { + var thisLoader = this; + this.sourceUrl = Laya.URL.formatURL(url); + if (MiniFileMgr.isNetFile(url)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (TTMiniAdapter.subNativeFiles && TTMiniAdapter.subNativeheads.length == 0) { + for (var key in TTMiniAdapter.subNativeFiles) { + var tempArr = TTMiniAdapter.subNativeFiles[key]; + TTMiniAdapter.subNativeheads = TTMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + TTMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (TTMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && TTMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = TTMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + switch (type) { + case Laya.Loader.IMAGE: + case "htmlimage": + case "nativeimage": + MiniLoader._transformImgUrl(url, type, thisLoader); + break; + case Laya.Loader.SOUND: + thisLoader._loadSound(url); + break; + default: + thisLoader._loadResource(type, url); + } + } + _loadSound(url) { + var thisLoader = this; + if (!TTMiniAdapter.autoCacheFile) { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + else { + var tempurl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downOtherFiles(TTMiniAdapter.safeEncodeURI(tempurl), Laya.Handler.create(MiniLoader, MiniLoader.onDownLoadCallBack, [tempurl, thisLoader]), tempurl); + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + } + static onDownLoadCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = null) { + if (!errorCode) { + var fileNativeUrl; + if (TTMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + fileNativeUrl = sourceUrl; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + } + else { + fileNativeUrl = Laya.URL.formatURL(sourceUrl); + } + sourceUrl = fileNativeUrl; + var sound = (new Laya.SoundManager._soundClass()); + sound.load(sourceUrl); + thisLoader.onLoaded(sound); + } + else { + thisLoader.event(Laya.Event.ERROR, "Load sound failed"); + } + } + complete(data) { + if (data instanceof Laya.Resource) { + data._setCreateURL(this.sourceUrl); + } + else if ((data instanceof Laya.Texture) && (data.bitmap instanceof Laya.Resource)) { + data.bitmap._setCreateURL(this.sourceUrl); + } + this.originComplete(data); + } + _loadHttpRequestWhat(url, contentType) { + var thisLoader = this; + var encoding = TTMiniAdapter.getUrlEncode(url, contentType); + if (Laya.Loader.preLoadedMap[url]) + thisLoader.onLoaded(Laya.Loader.preLoadedMap[url]); + else { + var tempurl = Laya.URL.formatURL(url); + if (!TTMiniAdapter.AutoCacheDownFile) { + if (MiniFileMgr.isNetFile(tempurl)) { + thisLoader._loadHttpRequest(tempurl, contentType, thisLoader, thisLoader.onLoaded, thisLoader, thisLoader.onProgress, thisLoader, thisLoader.onError); + } + else + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + else { + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downFiles(TTMiniAdapter.safeEncodeURI(tempurl), encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), tempurl, true); + } + else { + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + else { + var tempUrl = url; + var fileObj = MiniFileMgr.getFileInfo(tempurl); + if (fileObj && fileObj.md5) { + tempUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + MiniFileMgr.readFile(tempUrl, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + } + } + static onReadNativeCallBack(url, type = null, thisLoader = null, errorCode = 0, data = null) { + if (!errorCode) { + var tempData; + if (type == Laya.Loader.JSON || type == Laya.Loader.ATLAS || type == Laya.Loader.PREFAB || type == Laya.Loader.PLF) { + tempData = TTMiniAdapter.getJson(data.data); + } + else if (type == Laya.Loader.XML) { + tempData = Laya.Utils.parseXMLFromString(data.data); + } + else { + tempData = data.data; + } + if (!TTMiniAdapter.isZiYu && TTMiniAdapter.isPosMsgYu && type != Laya.Loader.BUFFER) { + TTMiniAdapter.window.tt.postMessage({ url: url, data: tempData, isLoad: "filedata" }); + } + thisLoader.onLoaded(tempData); + } + else if (errorCode == 1) { + thisLoader._loadHttpRequest(url, type, thisLoader, thisLoader.onLoaded, thisLoader, thisLoader.onProgress, thisLoader, thisLoader.onError); + } + } + static _transformImgUrl(url, type, thisLoader) { + if (TTMiniAdapter.isZiYu || MiniFileMgr.isLocalNativeFile(url)) { + thisLoader._loadImage(url, false); + return; + } + if (!TTMiniAdapter.autoCacheFile) { + thisLoader._loadImage(TTMiniAdapter.safeEncodeURI(url)); + } + else { + var tempUrl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempUrl)) { + if (MiniFileMgr.isNetFile(tempUrl)) { + MiniFileMgr.downOtherFiles(TTMiniAdapter.safeEncodeURI(tempUrl), new Laya.Handler(MiniLoader, MiniLoader.onDownImgCallBack, [url, thisLoader]), tempUrl); + } + else { + MiniLoader.onCreateImage(url, thisLoader, true); + } + } + else { + MiniLoader.onCreateImage(url, thisLoader); + } + } + } + static onDownImgCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = "") { + if (!errorCode) + MiniLoader.onCreateImage(sourceUrl, thisLoader, false, tempFilePath); + else { + thisLoader.onError(null); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (TTMiniAdapter.autoCacheFile) { + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + var fileObj = MiniFileMgr.getFileInfo(Laya.URL.formatURL(sourceUrl)); + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + } + else if (TTMiniAdapter.isZiYu) { + var tempUrl = Laya.URL.formatURL(sourceUrl); + if (MiniFileMgr.ziyuFileTextureData[tempUrl]) { + fileNativeUrl = MiniFileMgr.ziyuFileTextureData[tempUrl]; + } + else + fileNativeUrl = sourceUrl; + } + else + fileNativeUrl = sourceUrl; + } + else { + if (!isLocal) + fileNativeUrl = tempFilePath; + else + fileNativeUrl = sourceUrl; + } + thisLoader._loadImage(fileNativeUrl, false); + } + } + + class MiniLocalStorage { + constructor() { + } + static __init__() { + MiniLocalStorage.items = MiniLocalStorage; + } + static setItem(key, value) { + try { + TTMiniAdapter.window.tt.setStorageSync(key, value); + } + catch (error) { + TTMiniAdapter.window.tt.setStorage({ + key: key, + data: value + }); + } + } + static getItem(key) { + return TTMiniAdapter.window.tt.getStorageSync(key); + } + static setJSON(key, value) { + MiniLocalStorage.setItem(key, value); + } + static getJSON(key) { + return MiniLocalStorage.getItem(key); + } + static removeItem(key) { + TTMiniAdapter.window.tt.removeStorageSync(key); + } + static clear() { + TTMiniAdapter.window.tt.clearStorageSync(); + } + static getStorageInfoSync() { + try { + var res = TTMiniAdapter.window.tt.getStorageInfoSync(); + console.log(res.keys); + console.log(res.currentSize); + console.log(res.limitSize); + return res; + } + catch (e) { + } + return null; + } + } + MiniLocalStorage.support = true; + + class TTMiniAdapter { + static getJson(data) { + return JSON.parse(data); + } + static enable() { + TTMiniAdapter.init(Laya.Laya.isWXPosMsg, Laya.Laya.isWXOpenDataContext); + } + static init(isPosMsg = false, isSon = false) { + if (TTMiniAdapter._inited) + return; + TTMiniAdapter._inited = true; + TTMiniAdapter.window = window; + if (!TTMiniAdapter.window.hasOwnProperty("tt")) + return; + if (TTMiniAdapter.window.navigator.userAgent.indexOf('MiniGame') < 0) + return; + TTMiniAdapter.isZiYu = isSon; + TTMiniAdapter.isPosMsgYu = isPosMsg; + TTMiniAdapter.EnvConfig = {}; + if (!TTMiniAdapter.isZiYu) { + MiniFileMgr.setNativeFileDir("/layaairGame"); + MiniFileMgr.getCacheList(MiniFileMgr.fileNativeDir, Laya.Handler.create(TTMiniAdapter, TTMiniAdapter.onMkdirCallBack)); + } + TTMiniAdapter.systemInfo = TTMiniAdapter.window.tt.getSystemInfoSync(); + TTMiniAdapter.window.focus = function () { + }; + Laya.Laya['_getUrlPath'] = function () { + return ""; + }; + TTMiniAdapter.window.logtime = function (str) { + }; + TTMiniAdapter.window.alertTimeLog = function (str) { + }; + TTMiniAdapter.window.resetShareInfo = function () { + }; + TTMiniAdapter.window.CanvasRenderingContext2D = function () { + }; + TTMiniAdapter.window.CanvasRenderingContext2D.prototype = TTMiniAdapter.window.tt.createCanvas().getContext('2d').__proto__; + TTMiniAdapter.window.document.body.appendChild = function () { + }; + Laya.HttpRequest._urlEncode = TTMiniAdapter.safeEncodeURI; + TTMiniAdapter.EnvConfig.pixelRatioInt = 0; + Laya.Browser["_pixelRatio"] = TTMiniAdapter.pixelRatio(); + TTMiniAdapter._preCreateElement = Laya.Browser.createElement; + Laya.Browser["createElement"] = TTMiniAdapter.createElement; + Laya.RunDriver.createShaderCondition = TTMiniAdapter.createShaderCondition; + Laya.Utils['parseXMLFromString'] = TTMiniAdapter.parseXMLFromString; + Laya.Input['_createInputElement'] = MiniInput['_createInputElement']; + TTMiniAdapter.openCtx = TTMiniAdapter.window.tt.getOpenDataContext(); + Laya.Loader.prototype._loadResourceFilter = MiniLoader.prototype._loadResourceFilter; + Laya.Loader.prototype.originComplete = Laya.Loader.prototype.complete; + Laya.Loader.prototype.complete = MiniLoader.prototype.complete; + Laya.Loader.prototype._loadSound = MiniLoader.prototype._loadSound; + Laya.Loader.prototype._loadHttpRequestWhat = MiniLoader.prototype._loadHttpRequestWhat; + if (!window.ImageData) { + window.ImageData = ImageDataPolyfill; + } + Laya.LocalStorage._baseClass = MiniLocalStorage; + MiniLocalStorage.__init__(); + Laya.Config.useRetinalCanvas = true; + TTMiniAdapter.window.tt.onMessage && TTMiniAdapter.window.tt.onMessage(TTMiniAdapter._onMessage); + } + static _onMessage(data) { + switch (data.type) { + case "changeMatrix": + Laya.Laya.stage.transform.identity(); + Laya.Laya.stage._width = data.w; + Laya.Laya.stage._height = data.h; + Laya.Laya.stage._canvasTransform = new Laya.Matrix(data.a, data.b, data.c, data.d, data.tx, data.ty); + break; + case "display": + Laya.Laya.stage.frameRate = data.rate || Laya.Stage.FRAME_FAST; + break; + case "undisplay": + Laya.Laya.stage.frameRate = Laya.Stage.FRAME_SLEEP; + break; + } + if (data['isLoad'] == "opendatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + else if (data['isLoad'] == "openJsondatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + } + } + else if (data['isLoad'] == "openJsondatacontextPic") { + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + static getUrlEncode(url, type) { + if (type == "arraybuffer") + return ""; + return "utf8"; + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + var fileObj = MiniFileMgr.getFileInfo(fileUrl); + if (!fileObj) + MiniFileMgr.downLoadFile(fileUrl, fileType, callBack, encoding); + else { + callBack != null && callBack.runWith([0]); + } + } + static remove(fileUrl, callBack = null) { + MiniFileMgr.deleteFile("", fileUrl, callBack, "", 0); + } + static removeAll() { + MiniFileMgr.deleteAll(); + } + static hasNativeFile(fileUrl) { + return MiniFileMgr.isLocalNativeFile(fileUrl); + } + static getFileInfo(fileUrl) { + return MiniFileMgr.getFileInfo(fileUrl); + } + static getFileList() { + return MiniFileMgr.filesListObj; + } + static exitMiniProgram() { + TTMiniAdapter.window["tt"].exitMiniProgram(); + } + static onMkdirCallBack(errorCode, data) { + if (!errorCode) { + MiniFileMgr.filesListObj = JSON.parse(data.data); + MiniFileMgr.fakeObj = JSON.parse(data.data); + } + else { + MiniFileMgr.fakeObj = {}; + MiniFileMgr.filesListObj = {}; + } + let files = MiniFileMgr.fs.readdirSync(MiniFileMgr.fileNativeDir); + if (!files || !files.length) + return; + var tempMd5ListObj = {}; + var fileObj; + for (let key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") { + fileObj = MiniFileMgr.filesListObj[key]; + tempMd5ListObj[fileObj.md5] = fileObj.readyUrl; + } + } + var fileName; + for (let i = 0, sz = files.length; i < sz; i++) { + fileName = files[i]; + if (fileName == MiniFileMgr.fileListName) + continue; + if (!tempMd5ListObj[fileName]) { + let deleteFileUrl = MiniFileMgr.getFileNativePath(fileName); + MiniFileMgr.fs.unlink({ + filePath: deleteFileUrl, + success: function (data) { + console.log("删除无引用的磁盘文件:" + fileName); + } + }); + } + delete tempMd5ListObj[fileName]; + } + for (let key in tempMd5ListObj) { + delete MiniFileMgr.filesListObj[tempMd5ListObj[key]]; + delete MiniFileMgr.fakeObj[tempMd5ListObj[key]]; + console.log("删除错误记录:", tempMd5ListObj[key]); + } + } + static pixelRatio() { + if (!TTMiniAdapter.EnvConfig.pixelRatioInt) { + try { + TTMiniAdapter.EnvConfig.pixelRatioInt = TTMiniAdapter.systemInfo.pixelRatio; + return TTMiniAdapter.systemInfo.pixelRatio; + } + catch (error) { + } + } + return TTMiniAdapter.EnvConfig.pixelRatioInt; + } + static createElement(type) { + if (type == "canvas") { + var _source; + if (TTMiniAdapter.idx == 1) { + if (TTMiniAdapter.isZiYu) { + _source = TTMiniAdapter.window.sharedCanvas; + _source.style = {}; + } + else { + _source = TTMiniAdapter.window.canvas; + } + } + else { + _source = TTMiniAdapter.window.tt.createCanvas(); + } + TTMiniAdapter.idx++; + return _source; + } + else if (type == "textarea" || type == "input") { + return TTMiniAdapter.onCreateInput(type); + } + else if (type == "div") { + var node = TTMiniAdapter._preCreateElement(type); + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + else { + return TTMiniAdapter._preCreateElement(type); + } + } + static onCreateInput(type) { + var node = TTMiniAdapter._preCreateElement(type); + node.focus = MiniInput.inputFocus; + node.blur = MiniInput.inputblur; + node.style = {}; + node.value = 0; + node.parentElement = {}; + node.placeholder = {}; + node.type = {}; + node.setColor = function (value) { + }; + node.setType = function (value) { + }; + node.setFontFace = function (value) { + }; + node.addEventListener = function (value) { + }; + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + static createShaderCondition(conditionScript) { + var func = function () { + return this[conditionScript.replace("this.", "")]; + }; + return func; + } + static sendAtlasToOpenDataContext(url) { + if (!TTMiniAdapter.isZiYu) { + var atlasJson = Laya.Loader.getRes(Laya.URL.formatURL(url)); + if (atlasJson) { + var textureArr = atlasJson.meta.image.split(","); + if (atlasJson.meta && atlasJson.meta.image) { + var toloadPics = atlasJson.meta.image.split(","); + var split = url.indexOf("/") >= 0 ? "/" : "\\"; + var idx = url.lastIndexOf(split); + var folderPath = idx >= 0 ? url.substr(0, idx + 1) : ""; + for (var i = 0, len = toloadPics.length; i < len; i++) { + toloadPics[i] = folderPath + toloadPics[i]; + } + } + else { + toloadPics = [url.replace(".json", ".png")]; + } + for (i = 0; i < toloadPics.length; i++) { + var tempAtlasPngUrl = toloadPics[i]; + TTMiniAdapter.postInfoToContext(Laya.Laya.URL.formatURL(url), Laya.Laya.URL.formatURL(tempAtlasPngUrl), atlasJson); + } + } + else { + throw "传递的url没有获取到对应的图集数据信息,请确保图集已经过!"; + } + } + } + static postInfoToContext(url, atlaspngUrl, atlasJson) { + var postData = { "frames": atlasJson.frames, "meta": atlasJson.meta }; + var textureUrl = atlaspngUrl; + var fileObj = MiniFileMgr.getFileInfo(Laya.URL.formatURL(atlaspngUrl)); + if (fileObj) { + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = textureUrl; + } + if (fileNativeUrl) { + TTMiniAdapter.openCtx.postMessage({ url: url, atlasdata: postData, imgNativeUrl: fileNativeUrl, imgReadyUrl: textureUrl, isLoad: "opendatacontext" }); + } + else { + throw "获取图集的磁盘url路径不存在!"; + } + } + static sendSinglePicToOpenDataContext(url) { + var tempTextureUrl = Laya.URL.formatURL(url); + var fileObj = MiniFileMgr.getFileInfo(tempTextureUrl); + if (fileObj) { + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + url = tempTextureUrl; + } + else { + fileNativeUrl = url; + } + if (fileNativeUrl) { + url = Laya.Laya.URL.formatURL(url); + TTMiniAdapter.openCtx.postMessage({ url: url, imgNativeUrl: fileNativeUrl, imgReadyUrl: url, isLoad: "openJsondatacontextPic" }); + } + else { + throw "获取图集的磁盘url路径不存在!"; + } + } + static sendJsonDataToDataContext(url) { + if (!TTMiniAdapter.isZiYu) { + url = Laya.Laya.URL.formatURL(url); + var atlasJson = Laya.Loader.getRes(url); + if (atlasJson) { + TTMiniAdapter.openCtx.postMessage({ url: url, atlasdata: atlasJson, isLoad: "openJsondatacontext" }); + } + else { + throw "传递的url没有获取到对应的图集数据信息,请确保图集已经过!"; + } + } + } + } + TTMiniAdapter.IGNORE = new RegExp("[-_.!~*'();/?:@&=+$,#%]|[0-9|A-Z|a-z]"); + TTMiniAdapter.safeEncodeURI = function (str) { + var strTemp = ""; + var length = str.length; + for (var i = 0; i < length; i++) { + var word = str[i]; + if (TTMiniAdapter.IGNORE.test(word)) { + strTemp += word; + } + else { + try { + strTemp += encodeURI(word); + } + catch (e) { + console.log("errorInfo", ">>>" + word); + } + } + } + return strTemp; + }; + TTMiniAdapter._inited = false; + TTMiniAdapter.autoCacheFile = true; + TTMiniAdapter.minClearSize = (5 * 1024 * 1024); + TTMiniAdapter.sizeLimit = (50 * 1024 * 1024); + TTMiniAdapter.nativefiles = ["layaNativeDir", "wxlocal"]; + TTMiniAdapter.subNativeFiles = []; + TTMiniAdapter.subNativeheads = []; + TTMiniAdapter.subMaps = []; + TTMiniAdapter.AutoCacheDownFile = false; + TTMiniAdapter.parseXMLFromString = function (value) { + var rst; + value = value.replace(/>\s+<'); + try { + rst = (new TTMiniAdapter.window.Parser.DOMParser()).parseFromString(value, 'text/xml'); + } + catch (error) { + throw "需要引入xml解析库文件"; + } + return rst; + }; + TTMiniAdapter.idx = 1; + + class MiniAccelerator extends Laya.EventDispatcher { + constructor() { + super(); + } + static __init__() { + try { + var Acc; + Acc = Laya.Accelerator; + if (!Acc) + return; + Acc["prototype"]["on"] = MiniAccelerator["prototype"]["on"]; + Acc["prototype"]["off"] = MiniAccelerator["prototype"]["off"]; + } + catch (e) { + } + } + static startListen(callBack) { + MiniAccelerator._callBack = callBack; + if (MiniAccelerator._isListening) + return; + MiniAccelerator._isListening = true; + try { + TTMiniAdapter.window.tt.onAccelerometerChange(MiniAccelerator.onAccelerometerChange); + } + catch (e) { } + } + static stopListen() { + MiniAccelerator._isListening = false; + try { + TTMiniAdapter.window.tt.stopAccelerometer({}); + } + catch (e) { } + } + static onAccelerometerChange(res) { + var e; + e = {}; + e.acceleration = res; + e.accelerationIncludingGravity = res; + e.rotationRate = {}; + if (MiniAccelerator._callBack != null) { + MiniAccelerator._callBack(e); + } + } + on(type, caller, listener, args = null) { + super.on(type, caller, listener, args); + MiniAccelerator.startListen(this["onDeviceOrientationChange"]); + return this; + } + off(type, caller, listener, onceOnly = false) { + if (!this.hasListener(type)) + MiniAccelerator.stopListen(); + return super.off(type, caller, listener, onceOnly); + } + } + MiniAccelerator._isListening = false; + + class MiniImage { + _loadImage(url) { + var thisLoader = this; + if (TTMiniAdapter.isZiYu) { + MiniImage.onCreateImage(url, thisLoader, true); + return; + } + var isTransformUrl; + if (!MiniFileMgr.isLocalNativeFile(url)) { + isTransformUrl = true; + url = Laya.URL.formatURL(url); + } + else { + if (url.indexOf(TTMiniAdapter.window.tt.env.USER_DATA_PATH) == -1 && (url.indexOf("http://") != -1 || url.indexOf("https://") != -1)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (TTMiniAdapter.subNativeFiles && TTMiniAdapter.subNativeheads.length == 0) { + for (var key in TTMiniAdapter.subNativeFiles) { + var tempArr = TTMiniAdapter.subNativeFiles[key]; + TTMiniAdapter.subNativeheads = TTMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + TTMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (TTMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && TTMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = TTMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + } + if (!MiniFileMgr.getFileInfo(url)) { + if (url.indexOf(TTMiniAdapter.window.tt.env.USER_DATA_PATH) == -1 && (url.indexOf("http://") != -1 || url.indexOf("https://") != -1)) { + if (TTMiniAdapter.isZiYu) { + MiniImage.onCreateImage(url, thisLoader, true); + } + else { + MiniFileMgr.downOtherFiles(url, new Laya.Handler(MiniImage, MiniImage.onDownImgCallBack, [url, thisLoader]), url); + } + } + else + MiniImage.onCreateImage(url, thisLoader, true); + } + else { + MiniImage.onCreateImage(url, thisLoader, !isTransformUrl); + } + } + static onDownImgCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = "") { + if (!errorCode) + MiniImage.onCreateImage(sourceUrl, thisLoader, false, tempFilePath); + else { + thisLoader.onError(null); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (TTMiniAdapter.autoCacheFile) { + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + var fileMd5Name = fileObj.md5; + fileNativeUrl = MiniFileMgr.getFileNativePath(fileMd5Name); + } + } + else if (TTMiniAdapter.isZiYu) { + var tempUrl = Laya.URL.formatURL(sourceUrl); + if (MiniFileMgr.ziyuFileTextureData[tempUrl]) { + fileNativeUrl = MiniFileMgr.ziyuFileTextureData[tempUrl]; + } + else + fileNativeUrl = sourceUrl; + } + else + fileNativeUrl = sourceUrl; + } + else { + if (!isLocal) + fileNativeUrl = tempFilePath; + else + fileNativeUrl = sourceUrl; + } + if (thisLoader._imgCache == null) + thisLoader._imgCache = {}; + var image; + function clear() { + var img = thisLoader._imgCache[fileNativeUrl]; + if (img) { + img.onload = null; + img.onerror = null; + delete thisLoader._imgCache[fileNativeUrl]; + } + } + var onerror = function () { + clear(); + delete MiniFileMgr.fakeObj[sourceUrl]; + delete MiniFileMgr.filesListObj[sourceUrl]; + thisLoader.event(Laya.Event.ERROR, "Load image failed"); + }; + if (thisLoader._type == "nativeimage") { + var onload = function () { + clear(); + thisLoader.onLoaded(image); + }; + image = new Laya.Browser.window.Image(); + image.crossOrigin = ""; + image.onload = onload; + image.onerror = onerror; + image.src = fileNativeUrl; + thisLoader._imgCache[fileNativeUrl] = image; + } + else { + var imageSource = new Laya.Browser.window.Image(); + onload = function () { + image = Laya.HTMLImage.create(imageSource.width, imageSource.height); + image.loadImageSource(imageSource, true); + image._setCreateURL(fileNativeUrl); + clear(); + thisLoader.onLoaded(image); + }; + imageSource.crossOrigin = ""; + imageSource.onload = onload; + imageSource.onerror = onerror; + imageSource.src = fileNativeUrl; + thisLoader._imgCache[fileNativeUrl] = imageSource; + } + } + } + + class MiniLocation { + constructor() { + } + static __init__() { + TTMiniAdapter.window.navigator.geolocation.getCurrentPosition = MiniLocation.getCurrentPosition; + TTMiniAdapter.window.navigator.geolocation.watchPosition = MiniLocation.watchPosition; + TTMiniAdapter.window.navigator.geolocation.clearWatch = MiniLocation.clearWatch; + } + static getCurrentPosition(success = null, error = null, options = null) { + var paramO; + paramO = {}; + paramO.success = getSuccess; + paramO.fail = error; + TTMiniAdapter.window.tt.getLocation(paramO); + function getSuccess(res) { + if (success != null) { + success(res); + } + } + } + static watchPosition(success = null, error = null, options = null) { + MiniLocation._curID++; + var curWatchO; + curWatchO = {}; + curWatchO.success = success; + curWatchO.error = error; + MiniLocation._watchDic[MiniLocation._curID] = curWatchO; + Laya.Laya.systemTimer.loop(1000, null, MiniLocation._myLoop); + return MiniLocation._curID; + } + static clearWatch(id) { + delete MiniLocation._watchDic[id]; + if (!MiniLocation._hasWatch()) { + Laya.Laya.systemTimer.clear(null, MiniLocation._myLoop); + } + } + static _hasWatch() { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key]) + return true; + } + return false; + } + static _myLoop() { + MiniLocation.getCurrentPosition(MiniLocation._mySuccess, MiniLocation._myError); + } + static _mySuccess(res) { + var rst = {}; + rst.coords = res; + rst.timestamp = Laya.Browser.now(); + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].success) { + MiniLocation._watchDic[key].success(rst); + } + } + } + static _myError(res) { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].error) { + MiniLocation._watchDic[key].error(res); + } + } + } + } + MiniLocation._watchDic = {}; + MiniLocation._curID = 0; + + class MiniVideo { + constructor(width = 320, height = 240) { + this.videoend = false; + this.videourl = ""; + this.videoElement = TTMiniAdapter.window.tt.createVideo({ width: width, height: height, autoplay: true }); + } + static __init__() { + } + on(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.onPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.onEnded = this.onEndedFunction.bind(this); + } + this.videoElement.onTimeUpdate = this.onTimeUpdateFunc.bind(this); + } + onTimeUpdateFunc(data) { + this.position = data.position; + this._duration = data.duration; + } + get duration() { + return this._duration; + } + onPlayFunction() { + if (this.videoElement) + this.videoElement.readyState = 200; + console.log("=====视频加载完成========"); + this.onPlayFunc != null && this.onPlayFunc(); + } + onEndedFunction() { + if (!this.videoElement) + return; + this.videoend = true; + console.log("=====视频播放完毕========"); + this.onEndedFunC != null && this.onEndedFunC(); + } + off(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.offPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.offEnded = this.onEndedFunction.bind(this); + } + } + load(url) { + if (!this.videoElement) + return; + this.videoElement.src = url; + } + play() { + if (!this.videoElement) + return; + this.videoend = false; + this.videoElement.play(); + } + pause() { + if (!this.videoElement) + return; + this.videoend = true; + this.videoElement.pause(); + } + get currentTime() { + if (!this.videoElement) + return 0; + return this.videoElement.initialTime; + } + set currentTime(value) { + if (!this.videoElement) + return; + this.videoElement.initialTime = value; + } + get videoWidth() { + if (!this.videoElement) + return 0; + return this.videoElement.width; + } + get videoHeight() { + if (!this.videoElement) + return 0; + return this.videoElement.height; + } + get ended() { + return this.videoend; + } + get loop() { + if (!this.videoElement) + return false; + return this.videoElement.loop; + } + set loop(value) { + if (!this.videoElement) + return; + this.videoElement.loop = value; + } + get playbackRate() { + if (!this.videoElement) + return 0; + return this.videoElement.playbackRate; + } + set playbackRate(value) { + if (!this.videoElement) + return; + this.videoElement.playbackRate = value; + } + get muted() { + if (!this.videoElement) + return false; + return this.videoElement.muted; + } + set muted(value) { + if (!this.videoElement) + return; + this.videoElement.muted = value; + } + get paused() { + if (!this.videoElement) + return false; + return this.videoElement.paused; + } + size(width, height) { + if (!this.videoElement) + return; + this.videoElement.width = width; + this.videoElement.height = height; + } + get x() { + if (!this.videoElement) + return 0; + return this.videoElement.x; + } + set x(value) { + if (!this.videoElement) + return; + this.videoElement.x = value; + } + get y() { + if (!this.videoElement) + return 0; + return this.videoElement.y; + } + set y(value) { + if (!this.videoElement) + return; + this.videoElement.y = value; + } + get currentSrc() { + return this.videoElement.src; + } + destroy() { + if (this.videoElement) + this.videoElement.destroy(); + this.videoElement = null; + this.onEndedFunC = null; + this.onPlayFunc = null; + this.videoend = false; + this.videourl = null; + } + reload() { + if (!this.videoElement) + return; + this.videoElement.src = this.videourl; + } + } + + exports.ImageDataPolyfill = ImageDataPolyfill; + exports.MiniAccelerator = MiniAccelerator; + exports.MiniFileMgr = MiniFileMgr; + exports.MiniImage = MiniImage; + exports.MiniInput = MiniInput; + exports.MiniLoader = MiniLoader; + exports.MiniLocalStorage = MiniLocalStorage; + exports.MiniLocation = MiniLocation; + exports.MiniSound = MiniSound; + exports.MiniSoundChannel = MiniSoundChannel; + exports.MiniVideo = MiniVideo; + exports.TTMiniAdapter = TTMiniAdapter; + +} diff --git a/examples/layaair/frontend/bin/libs/laya.ui.js b/examples/layaair/frontend/bin/libs/laya.ui.js new file mode 100644 index 0000000..e6b58f4 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.ui.js @@ -0,0 +1,6176 @@ +(function (exports, Laya) { + 'use strict'; + + class UIConfig { + } + UIConfig.touchScrollEnable = true; + UIConfig.mouseWheelEnable = true; + UIConfig.showButtons = true; + UIConfig.popupBgColor = "#000000"; + UIConfig.popupBgAlpha = 0.5; + UIConfig.closeDialogOnSide = true; + window.UIConfig = UIConfig; + + class Styles { + } + Styles.defaultSizeGrid = [4, 4, 4, 4, 0]; + Styles.labelColor = "#000000"; + Styles.labelPadding = [2, 2, 2, 2]; + Styles.inputLabelPadding = [1, 1, 1, 3]; + Styles.buttonStateNum = 3; + Styles.buttonLabelColors = ["#32556b", "#32cc6b", "#ff0000", "#C0C0C0"]; + Styles.comboBoxItemColors = ["#5e95b6", "#ffffff", "#000000", "#8fa4b1", "#ffffff"]; + Styles.scrollBarMinNum = 15; + Styles.scrollBarDelayTime = 500; + + class AutoBitmap extends Laya.Graphics { + constructor() { + super(...arguments); + this.autoCacheCmd = true; + this._width = 0; + this._height = 0; + this.uv = null; + } + destroy() { + super.destroy(); + this._source = null; + this._sizeGrid = null; + this._offset = null; + } + get sizeGrid() { + return this._sizeGrid; + } + set sizeGrid(value) { + this._sizeGrid = value.map((v) => { return +v; }); + this._setChanged(); + } + get width() { + if (this._width) + return this._width; + if (this._source) + return this._source.sourceWidth; + return 0; + } + set width(value) { + if (this._width != value) { + this._width = value; + this._setChanged(); + } + } + get height() { + if (this._height) + return this._height; + if (this._source) + return this._source.sourceHeight; + return 0; + } + set height(value) { + if (this._height != value) { + this._height = value; + this._setChanged(); + } + } + get source() { + return this._source; + } + set source(value) { + if (value) { + this._source = value; + this._setChanged(); + } + else { + this._source = null; + if (this._drawGridCmd) { + if (this._one) { + if (this._one == this._drawGridCmd) { + this.clear(); + } + } + let cmds = this.cmds; + if (cmds && cmds.length > 0) { + if (cmds[0] == this._drawGridCmd) { + cmds.splice(0, 1); + } + } + } + } + } + _setChanged() { + if (!this._isChanged) { + this._isChanged = true; + Laya.ILaya.timer.callLater(this, this.changeSource); + } + } + _createDrawTexture(texture, x = 0, y = 0, width = 0, height = 0, matrix = null, alpha = 1, color = null, blendMode = null, uv) { + if (!texture || alpha < 0.01) + return null; + if (!texture.getIsReady()) + return null; + if (!width) + width = texture.sourceWidth; + if (!height) + height = texture.sourceHeight; + if (texture.getIsReady()) { + var wRate = width / texture.sourceWidth; + var hRate = height / texture.sourceHeight; + width = texture.width * wRate; + height = texture.height * hRate; + if (width <= 0 || height <= 0) + return null; + x += texture.offsetX * wRate; + y += texture.offsetY * hRate; + } + if (this._sp) { + this._sp._renderType |= Laya.SpriteConst.GRAPHICS; + this._sp._setRenderType(this._sp._renderType); + } + return Laya.DrawTextureCmd.create.call(this, texture, x, y, width, height, matrix, alpha, color, blendMode, uv); + } + changeSource() { + this._isChanged = false; + var source = this._source; + if (!source || !source.bitmap) + return; + var width = this.width; + var height = this.height; + var sizeGrid = this._sizeGrid; + var sw = source.sourceWidth; + var sh = source.sourceHeight; + if (!sizeGrid || (sw === width && sh === height)) { + let cmd = this._createDrawTexture(source, this._offset ? this._offset[0] : 0, this._offset ? this._offset[1] : 0, width, height, null, 1, null, null, this.uv); + cmd && this._setDrawGridCmd(cmd); + } + else { + let cmd = Laya.Draw9GridTexture.create(source, 0, 0, width, height, sizeGrid); + this._setDrawGridCmd(cmd); + } + this._repaint(); + } + drawBitmap(repeat, tex, x, y, width = 0, height = 0) { + if (width < 0.1 || height < 0.1) + return; + if (repeat && (tex.width != width || tex.height != height)) + this.fillTexture(tex, x, y, width, height); + else + this.drawImage(tex, x, y, width, height); + } + static getTexture(tex, x, y, width, height) { + if (width <= 0) + width = 1; + if (height <= 0) + height = 1; + tex.$_GID || (tex.$_GID = Laya.Utils.getGID()); + var texture; + if (!texture || !texture._getSource()) { + texture = Laya.Texture.createFromTexture(tex, x, y, width, height); + } + return texture; + } + _setDrawGridCmd(newcmd) { + var source = this._source; + if (!source || !source.bitmap) { + return; + } + let cmds = this.cmds; + if (!this._one && (!cmds || cmds.length <= 0)) { + this._saveToCmd(null, newcmd); + } + else { + let lastOne = this._one; + if (lastOne) { + if (lastOne == this._drawGridCmd) { + this._one = newcmd; + } + else { + this.clear(); + this._saveToCmd(null, newcmd); + this._saveToCmd(null, lastOne); + } + } + else { + cmds.splice(0, 0, newcmd); + } + } + this._drawGridCmd = newcmd; + } + } + Laya.ClassUtils.regClass("laya.ui.AutoBitmap", AutoBitmap); + Laya.ClassUtils.regClass("Laya.AutoBitmap", AutoBitmap); + + class Widget extends Laya.Component { + constructor() { + super(...arguments); + this._top = NaN; + this._bottom = NaN; + this._left = NaN; + this._right = NaN; + this._centerX = NaN; + this._centerY = NaN; + } + onReset() { + this._top = this._bottom = this._left = this._right = this._centerX = this._centerY = NaN; + } + _onEnable() { + if (this.owner.parent) + this._onAdded(); + else + this.owner.once(Laya.Event.ADDED, this, this._onAdded); + } + _onDisable() { + this.owner.off(Laya.Event.ADDED, this, this._onAdded); + if (this.owner.parent) + this.owner.parent.off(Laya.Event.RESIZE, this, this._onParentResize); + } + _onAdded() { + if (this.owner.parent) + this.owner.parent.on(Laya.Event.RESIZE, this, this._onParentResize); + this.resetLayoutX(); + this.resetLayoutY(); + } + _onParentResize() { + var flagX = this.resetLayoutX(); + var flagY = this.resetLayoutY(); + if (flagX || flagY) + this.owner.event(Laya.Event.RESIZE); + } + resetLayoutX() { + var owner = this.owner; + if (!owner) + return false; + var parent = owner.parent; + if (parent) { + if (!isNaN(this.centerX)) { + owner.x = Math.round((parent.width - owner.displayWidth) * 0.5 + this.centerX + owner.pivotX * owner.scaleX); + } + else if (!isNaN(this.left)) { + owner.x = Math.round(this.left + owner.pivotX * owner.scaleX); + if (!isNaN(this.right)) { + if (!parent._width) + return false; + var temp = (parent._width - this.left - this.right) / (owner.scaleX || 0.01); + if (temp != owner.width) { + owner.width = temp; + return true; + } + } + } + else if (!isNaN(this.right)) { + owner.x = Math.round(parent.width - owner.displayWidth - this.right + owner.pivotX * owner.scaleX); + } + } + return false; + } + resetLayoutY() { + var owner = this.owner; + if (!owner) + return false; + var parent = owner.parent; + if (parent) { + if (!isNaN(this.centerY)) { + owner.y = Math.round((parent.height - owner.displayHeight) * 0.5 + this.centerY + owner.pivotY * owner.scaleY); + } + else if (!isNaN(this.top)) { + owner.y = Math.round(this.top + owner.pivotY * owner.scaleY); + if (!isNaN(this.bottom)) { + if (!parent._height) + return false; + var temp = (parent._height - this.top - this.bottom) / (owner.scaleY || 0.01); + if (temp != owner.height) { + owner.height = temp; + return true; + } + } + } + else if (!isNaN(this.bottom)) { + owner.y = Math.round(parent.height - owner.displayHeight - this.bottom + owner.pivotY * owner.scaleY); + } + } + return false; + } + resetLayout() { + if (this.owner) { + this.resetLayoutX(); + this.resetLayoutY(); + } + } + get top() { + return this._top; + } + set top(value) { + if (this._top != value) { + this._top = value; + this.resetLayoutY(); + } + } + get bottom() { + return this._bottom; + } + set bottom(value) { + if (this._bottom != value) { + this._bottom = value; + this.resetLayoutY(); + } + } + get left() { + return this._left; + } + set left(value) { + if (this._left != value) { + this._left = value; + this.resetLayoutX(); + } + } + get right() { + return this._right; + } + set right(value) { + if (this._right != value) { + this._right = value; + this.resetLayoutX(); + } + } + get centerX() { + return this._centerX; + } + set centerX(value) { + if (this._centerX != value) { + this._centerX = value; + this.resetLayoutX(); + } + } + get centerY() { + return this._centerY; + } + set centerY(value) { + if (this._centerY != value) { + this._centerY = value; + this.resetLayoutY(); + } + } + } + Widget.EMPTY = null; + Laya.ILaya.regClass(Widget); + Widget.EMPTY = new Widget(); + Laya.ClassUtils.regClass("laya.ui.Widget", Widget); + Laya.ClassUtils.regClass("Laya.Widget", Widget); + + class UIEvent extends Laya.Event { + } + UIEvent.SHOW_TIP = "showtip"; + UIEvent.HIDE_TIP = "hidetip"; + Laya.ILaya.regClass(UIEvent); + Laya.ClassUtils.regClass("laya.ui.UIEvent", UIEvent); + Laya.ClassUtils.regClass("Laya.UIEvent", UIEvent); + + class UIUtils { + static fillArray(arr, str, type = null) { + var temp = arr.concat(); + if (str) { + var a = str.split(","); + for (var i = 0, n = Math.min(temp.length, a.length); i < n; i++) { + var value = a[i]; + temp[i] = (value == "true" ? true : (value == "false" ? false : value)); + if (type != null) + temp[i] = type(value); + } + } + return temp; + } + static toColor(color) { + return Laya.Utils.toHexColor(color); + } + static gray(traget, isGray = true) { + if (isGray) { + UIUtils.addFilter(traget, UIUtils.grayFilter); + } + else { + UIUtils.clearFilter(traget, Laya.ColorFilter); + } + } + static addFilter(target, filter) { + var filters = target.filters || []; + filters.push(filter); + target.filters = filters; + } + static clearFilter(target, filterType) { + var filters = target.filters; + if (filters != null && filters.length > 0) { + for (var i = filters.length - 1; i > -1; i--) { + var filter = filters[i]; + if (filter instanceof filterType) + filters.splice(i, 1); + } + target.filters = filters; + } + } + static _getReplaceStr(word) { + return UIUtils.escapeSequence[word]; + } + static adptString(str) { + return str.replace(/\\(\w)/g, UIUtils._getReplaceStr); + } + static getBindFun(value) { + if (!UIUtils._funMap) { + UIUtils._funMap = new Laya.WeakObject(); + } + var fun = UIUtils._funMap.get(value); + if (fun == null) { + var temp = "\"" + value + "\""; + temp = temp.replace(/^"\${|}"$/g, "").replace(/\${/g, "\"+").replace(/}/g, "+\""); + var str = "(function(data){if(data==null)return;with(data){try{\nreturn " + temp + "\n}catch(e){}}})"; + fun = window.Laya._runScript(str); + UIUtils._funMap.set(value, fun); + } + return fun; + } + } + UIUtils.grayFilter = new Laya.ColorFilter([0.3086, 0.6094, 0.082, 0, 0, 0.3086, 0.6094, 0.082, 0, 0, 0.3086, 0.6094, 0.082, 0, 0, 0, 0, 0, 1, 0]); + UIUtils.escapeSequence = { "\\n": "\n", "\\t": "\t" }; + UIUtils._funMap = null; + Laya.ClassUtils.regClass("laya.ui.UIUtils", UIUtils); + Laya.ClassUtils.regClass("Laya.UIUtils", UIUtils); + + class UIComponent extends Laya.Sprite { + constructor(createChildren = true) { + super(); + this._anchorX = NaN; + this._anchorY = NaN; + this._widget = Widget.EMPTY; + if (createChildren) { + this.preinitialize(); + this.createChildren(); + this.initialize(); + } + } + destroy(destroyChild = true) { + super.destroy(destroyChild); + this._dataSource = null; + this._tag = null; + this._toolTip = null; + } + preinitialize() { + } + createChildren() { + } + initialize() { + } + get width() { + return this.get_width(); + } + get_width() { + if (this._width) + return this._width; + return this.measureWidth(); + } + measureWidth() { + var max = 0; + this.commitMeasure(); + for (var i = this.numChildren - 1; i > -1; i--) { + var comp = this.getChildAt(i); + if (comp._visible) { + max = Math.max(comp._x + comp.width * comp.scaleX, max); + } + } + return max; + } + commitMeasure() { + } + get height() { + return this.get_height(); + } + get_height() { + if (this._height) + return this._height; + return this.measureHeight(); + } + measureHeight() { + var max = 0; + this.commitMeasure(); + for (var i = this.numChildren - 1; i > -1; i--) { + var comp = this.getChildAt(i); + if (comp._visible) { + max = Math.max(comp._y + comp.height * comp.scaleY, max); + } + } + return max; + } + get dataSource() { + return this.get_dataSource(); + } + get_dataSource() { + return this._dataSource; + } + set dataSource(value) { + this.set_dataSource(value); + } + set_dataSource(value) { + this._dataSource = value; + for (var prop in this._dataSource) { + if (prop in this && !(typeof (this[prop]) == 'function')) { + this[prop] = this._dataSource[prop]; + } + } + } + get top() { + return this.get_top(); + } + get_top() { + return this._widget.top; + } + set top(value) { + this.set_top(value); + } + set_top(value) { + if (value != this._widget.top) { + this._getWidget().top = value; + } + } + get bottom() { + return this.get_bottom(); + } + get_bottom() { + return this._widget.bottom; + } + set bottom(value) { + this.set_bottom(value); + } + set_bottom(value) { + if (value != this._widget.bottom) { + this._getWidget().bottom = value; + } + } + get left() { + return this._widget.left; + } + set left(value) { + if (value != this._widget.left) { + this._getWidget().left = value; + } + } + get right() { + return this._widget.right; + } + set right(value) { + if (value != this._widget.right) { + this._getWidget().right = value; + } + } + get centerX() { + return this._widget.centerX; + } + set centerX(value) { + if (value != this._widget.centerX) { + this._getWidget().centerX = value; + } + } + get centerY() { + return this._widget.centerY; + } + set centerY(value) { + if (value != this._widget.centerY) { + this._getWidget().centerY = value; + } + } + _sizeChanged() { + if (!isNaN(this._anchorX)) + this.pivotX = this.anchorX * this.width; + if (!isNaN(this._anchorY)) + this.pivotY = this.anchorY * this.height; + this.event(Laya.Event.RESIZE); + if (this._widget !== Widget.EMPTY) + this._widget.resetLayout(); + } + get tag() { + return this._tag; + } + set tag(value) { + this._tag = value; + } + get toolTip() { + return this._toolTip; + } + set toolTip(value) { + if (this._toolTip != value) { + this._toolTip = value; + if (value != null) { + this.on(Laya.Event.MOUSE_OVER, this, this.onMouseOver); + this.on(Laya.Event.MOUSE_OUT, this, this.onMouseOut); + } + else { + this.off(Laya.Event.MOUSE_OVER, this, this.onMouseOver); + this.off(Laya.Event.MOUSE_OUT, this, this.onMouseOut); + } + } + } + onMouseOver(e) { + Laya.ILaya.stage.event(UIEvent.SHOW_TIP, this._toolTip); + } + onMouseOut(e) { + Laya.ILaya.stage.event(UIEvent.HIDE_TIP, this._toolTip); + } + get gray() { + return this._gray; + } + set gray(value) { + if (value !== this._gray) { + this._gray = value; + UIUtils.gray(this, value); + } + } + get disabled() { + return this._disabled; + } + set disabled(value) { + if (value !== this._disabled) { + this.gray = this._disabled = value; + this.mouseEnabled = !value; + } + } + _getWidget() { + this._widget === Widget.EMPTY && (this._widget = this.addComponent(Widget)); + return this._widget; + } + set scaleX(value) { + this.set_scaleX(value); + } + set_scaleX(value) { + if (super.get_scaleX() == value) + return; + super.set_scaleX(value); + this.callLater(this._sizeChanged); + } + get scaleX() { + return super.scaleX; + } + set scaleY(value) { + this.set_scaleY(value); + } + set_scaleY(value) { + if (super.get_scaleY() == value) + return; + super.set_scaleY(value); + this.callLater(this._sizeChanged); + } + get scaleY() { + return super.scaleY; + } + onCompResize() { + this._sizeChanged(); + } + set width(value) { + this.set_width(value); + } + set_width(value) { + if (super.get_width() == value) + return; + super.set_width(value); + this.callLater(this._sizeChanged); + } + set height(value) { + this.set_height(value); + } + set_height(value) { + if (super.get_height() == value) + return; + super.set_height(value); + this.callLater(this._sizeChanged); + } + get anchorX() { + return this.get_anchorX(); + } + get_anchorX() { + return this._anchorX; + } + set anchorX(value) { + this.set_anchorX(value); + } + set_anchorX(value) { + if (this._anchorX != value) { + this._anchorX = value; + this.callLater(this._sizeChanged); + } + } + get anchorY() { + return this.get_anchorY(); + } + get_anchorY() { + return this._anchorY; + } + set anchorY(value) { + this.set_anchorY(value); + } + set_anchorY(value) { + if (this._anchorY != value) { + this._anchorY = value; + this.callLater(this._sizeChanged); + } + } + _childChanged(child = null) { + this.callLater(this._sizeChanged); + super._childChanged(child); + } + } + Laya.ILaya.regClass(UIComponent); + Laya.ClassUtils.regClass("laya.ui.UIComponent", UIComponent); + Laya.ClassUtils.regClass("Laya.UIComponent", UIComponent); + + class Image extends UIComponent { + constructor(skin = null) { + super(); + this.skin = skin; + } + destroy(destroyChild = true) { + super.destroy(destroyChild); + this._bitmap && this._bitmap.destroy(); + this._bitmap = null; + } + dispose() { + this.destroy(true); + Laya.ILaya.loader.clearRes(this._skin); + } + createChildren() { + this.graphics = this._bitmap = new AutoBitmap(); + this._bitmap.autoCacheCmd = false; + } + get skin() { + return this._skin; + } + set skin(value) { + if (this._skin != value) { + this._skin = value; + if (value) { + var source = Laya.Loader.getRes(value); + if (source) { + this.source = source; + this.onCompResize(); + } + else + Laya.ILaya.loader.load(this._skin, Laya.Handler.create(this, this.setSource, [this._skin]), null, Laya.Loader.IMAGE, 1, true, this._group); + } + else { + this.source = null; + } + } + } + get source() { + return this._bitmap.source; + } + set source(value) { + if (!this._bitmap) + return; + this._bitmap.source = value; + this.event(Laya.Event.LOADED); + this.repaint(); + } + get group() { + return this._group; + } + set group(value) { + if (value && this._skin) + Laya.Loader.setGroup(this._skin, value); + this._group = value; + } + setSource(url, img = null) { + if (url === this._skin && img) { + this.source = img; + this.onCompResize(); + } + } + measureWidth() { + return this._bitmap.width; + } + measureHeight() { + return this._bitmap.height; + } + set width(value) { + super.width = value; + this._bitmap.width = value == 0 ? 0.0000001 : value; + } + get width() { + return super.width; + } + set height(value) { + super.height = value; + this._bitmap.height = value == 0 ? 0.0000001 : value; + } + get height() { + return super.height; + } + get sizeGrid() { + if (this._bitmap.sizeGrid) + return this._bitmap.sizeGrid.join(","); + return null; + } + set sizeGrid(value) { + this._bitmap.sizeGrid = UIUtils.fillArray(Styles.defaultSizeGrid, value, Number); + } + set dataSource(value) { + this._dataSource = value; + if (typeof (value) == 'string') + this.skin = value; + else + super.dataSource = value; + } + get dataSource() { + return super.dataSource; + } + } + Laya.ILaya.regClass(Image); + Laya.ClassUtils.regClass("laya.ui.Image", Image); + Laya.ClassUtils.regClass("Laya.Image", Image); + + class AdvImage extends Image { + constructor(skin = null) { + super(); + this.advsListArr = []; + this.resUrl = "https://unioncdn.layabox.com/config/iconlist.json"; + this._http = new Laya.Browser.window.XMLHttpRequest(); + this._data = []; + this._resquestTime = 360000; + this._playIndex = 0; + this._lunboTime = 5000; + this.skin = skin; + this.setLoadUrl(); + this.init(); + this.size(120, 120); + } + setLoadUrl() { + } + init() { + if (this.isSupportJump()) { + if (Laya.Browser.onMiniGame || Laya.Browser.onBDMiniGame) { + Laya.ILaya.timer.loop(this._resquestTime, this, this.onGetAdvsListData); + } + this.onGetAdvsListData(); + this.initEvent(); + } + else + this.visible = false; + } + initEvent() { + this.on(Laya.Event.CLICK, this, this.onAdvsImgClick); + } + onAdvsImgClick() { + var currentJumpUrl = this.getCurrentAppidObj(); + if (currentJumpUrl) + this.jumptoGame(); + } + revertAdvsData() { + if (this.advsListArr[this._playIndex]) { + this.visible = true; + this.skin = this.advsListArr[this._playIndex]; + } + } + isSupportJump() { + if (Laya.Browser.onMiniGame) { + var isSupperJump = window.wx.navigateToMiniProgram instanceof Function; + return isSupperJump; + } + else if (Laya.Browser.onBDMiniGame) + return true; + return false; + } + jumptoGame() { + var advsObj = this.advsListArr[this._playIndex]; + var desGameId = parseInt(advsObj.gameid); + var extendInfo = advsObj.extendInfo; + var path = advsObj.path; + if (Laya.Browser.onMiniGame) { + if (this.isSupportJump()) { + window.wx.navigateToMiniProgram({ + appId: this._appid, + path: "", + extraData: "", + envVersion: "release", + success: () => { + console.log("-------------跳转成功--------------"); + }, + fail: () => { + console.log("-------------跳转失败--------------"); + }, + complete: () => { + console.log("-------------跳转接口调用成功--------------"); + this.updateAdvsInfo(); + } + }); + } + } + else if (Laya.Browser.onBDMiniGame) ; + else { + this.visible = false; + } + } + updateAdvsInfo() { + this.visible = false; + this.onLunbo(); + Laya.ILaya.timer.loop(this._lunboTime, this, this.onLunbo); + } + onLunbo() { + if (this._playIndex >= this.advsListArr.length - 1) + this._playIndex = 0; + else + this._playIndex += 1; + this.visible = true; + this.revertAdvsData(); + } + getCurrentAppidObj() { + return this.advsListArr[this._playIndex]; + } + onGetAdvsListData() { + var _this = this; + var random = AdvImage.randRange(10000, 1000000); + var url = this.resUrl + "?" + random; + this._http.open("get", url, true); + this._http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + this._http.responseType = "text"; + this._http.onerror = function (e) { + _this._onError(e); + }; + this._http.onload = function (e) { + _this._onLoad(e); + }; + this._http.send(null); + } + static randRange(minNum, maxNum) { + return (Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum); + } + _onError(e) { + this.error("Request failed Status:" + this._http.status + " text:" + this._http.statusText); + } + _onLoad(e) { + var http = this._http; + var status = http.status !== undefined ? http.status : 200; + if (status === 200 || status === 204 || status === 0) { + this.complete(); + } + else { + this.error("[" + http.status + "]" + http.statusText + ":" + http.responseURL); + } + } + error(message) { + this.event(Laya.Event.ERROR, message); + } + complete() { + try { + this._data = this._http.response || this._http.responseText; + this._data = JSON.parse(this._data); + this.advsListArr = this._data.list; + this._appid = this._data.appid; + this.updateAdvsInfo(); + this.revertAdvsData(); + } + catch (e) { + this.error(e.message); + } + } + getAdvsQArr(data) { + var tempArr = []; + var gameAdvsObj = Laya.LocalStorage.getJSON("gameObj"); + for (var key in data) { + var tempObj = data[key]; + if (gameAdvsObj && gameAdvsObj[tempObj.gameid] && !tempObj.isQiangZhi) + continue; + tempArr.push(tempObj); + } + return tempArr; + } + clear() { + var http = this._http; + http.onerror = http.onabort = http.onprogress = http.onload = null; + } + destroy(destroyChild = true) { + Laya.ILaya.timer.clear(this, this.onLunbo); + super.destroy(true); + this.clear(); + Laya.ILaya.timer.clear(this, this.onGetAdvsListData); + } + } + Laya.ClassUtils.regClass("laya.ui.AdvImage", AdvImage); + Laya.ClassUtils.regClass("Laya.AdvImage", AdvImage); + + class Box extends UIComponent { + set dataSource(value) { + this._dataSource = value; + for (var name in value) { + var comp = this.getChildByName(name); + if (comp) + comp.dataSource = value[name]; + else if (name in this && !(this[name] instanceof Function)) + this[name] = value[name]; + } + } + get dataSource() { + return super.dataSource; + } + get bgColor() { + return this._bgColor; + } + set bgColor(value) { + this._bgColor = value; + if (value) { + this._onResize(null); + this.on(Laya.Event.RESIZE, this, this._onResize); + } + else { + this.graphics.clear(); + this.off(Laya.Event.RESIZE, this, this._onResize); + } + } + _onResize(e) { + this.graphics.clear(); + this.graphics.drawRect(0, 0, this.width, this.height, this._bgColor); + } + } + Laya.ILaya.regClass(Box); + Laya.ClassUtils.regClass("laya.ui.Box", Box); + Laya.ClassUtils.regClass("Laya.Box", Box); + + class Button extends UIComponent { + constructor(skin = null, label = "") { + super(); + this._labelColors = Styles.buttonLabelColors; + this._state = 0; + this._autoSize = true; + this._stateNum = Styles.buttonStateNum; + this._stateChanged = false; + this.skin = skin; + this.label = label; + } + destroy(destroyChild = true) { + super.destroy(destroyChild); + this._bitmap && this._bitmap.destroy(); + this._text && this._text.destroy(destroyChild); + this._bitmap = null; + this._text = null; + this._clickHandler = null; + this._labelColors = this._sources = this._strokeColors = null; + } + createChildren() { + this.graphics = this._bitmap = new AutoBitmap(); + } + createText() { + if (!this._text) { + this._text = new Laya.Text(); + this._text.overflow = Laya.Text.HIDDEN; + this._text.align = "center"; + this._text.valign = "middle"; + this._text.width = this._width; + this._text.height = this._height; + } + } + initialize() { + if (this._mouseState !== 1) { + this.mouseEnabled = true; + this._setBit(Laya.Const.HAS_MOUSE, true); + } + this._createListener(Laya.Event.MOUSE_OVER, this, this.onMouse, null, false, false); + this._createListener(Laya.Event.MOUSE_OUT, this, this.onMouse, null, false, false); + this._createListener(Laya.Event.MOUSE_DOWN, this, this.onMouse, null, false, false); + this._createListener(Laya.Event.MOUSE_UP, this, this.onMouse, null, false, false); + this._createListener(Laya.Event.CLICK, this, this.onMouse, null, false, false); + } + onMouse(e) { + if (this.toggle === false && this._selected) + return; + if (e.type === Laya.Event.CLICK) { + this.toggle && (this.selected = !this._selected); + this._clickHandler && this._clickHandler.run(); + return; + } + !this._selected && (this.state = Button.stateMap[e.type]); + } + get skin() { + return this._skin; + } + set skin(value) { + if (this._skin != value) { + this._skin = value; + if (value) { + if (!Laya.Loader.getRes(value)) { + Laya.ILaya.loader.load(this._skin, Laya.Handler.create(this, this._skinLoaded), null, Laya.Loader.IMAGE, 1); + } + else { + this._skinLoaded(); + } + } + else { + this._skinLoaded(); + } + } + } + _skinLoaded() { + this.callLater(this.changeClips); + this._setStateChanged(); + this._sizeChanged(); + this.event(Laya.Event.LOADED); + } + get stateNum() { + return this._stateNum; + } + set stateNum(value) { + if (typeof value == 'string') { + value = parseInt(value); + } + if (this._stateNum != value) { + this._stateNum = value < 1 ? 1 : value > 3 ? 3 : value; + this.callLater(this.changeClips); + } + } + changeClips() { + var img = Laya.Loader.getRes(this._skin); + if (!img) { + console.log("lose skin", this._skin); + return; + } + var width = img.sourceWidth; + var height = img.sourceHeight / this._stateNum; + img.$_GID || (img.$_GID = Laya.Utils.getGID()); + var key = img.$_GID + "-" + this._stateNum; + var clips = Laya.WeakObject.I.get(key); + if (!Laya.Utils.isOkTextureList(clips)) { + clips = null; + } + if (clips) + this._sources = clips; + else { + this._sources = []; + if (this._stateNum === 1) { + this._sources.push(img); + } + else { + for (var i = 0; i < this._stateNum; i++) { + this._sources.push(Laya.Texture.createFromTexture(img, 0, height * i, width, height)); + } + } + Laya.WeakObject.I.set(key, this._sources); + } + if (this._autoSize) { + this._bitmap.width = this._width || width; + this._bitmap.height = this._height || height; + if (this._text) { + this._text.width = this._bitmap.width; + this._text.height = this._bitmap.height; + } + } + else { + this._text && (this._text.x = width); + } + } + measureWidth() { + this.runCallLater(this.changeClips); + if (this._autoSize) + return this._bitmap.width; + this.runCallLater(this.changeState); + return this._bitmap.width + (this._text ? this._text.width : 0); + } + measureHeight() { + this.runCallLater(this.changeClips); + return this._text ? Math.max(this._bitmap.height, this._text.height) : this._bitmap.height; + } + get label() { + return this._text ? this._text.text : null; + } + set label(value) { + if (!this._text && !value) + return; + this.createText(); + if (this._text.text != value) { + value && !this._text.parent && this.addChild(this._text); + this._text.text = (value + "").replace(/\\n/g, "\n"); + this._setStateChanged(); + } + } + get selected() { + return this._selected; + } + set selected(value) { + if (this._selected != value) { + this._selected = value; + this.state = this._selected ? 2 : 0; + this.event(Laya.Event.CHANGE); + } + } + get state() { + return this._state; + } + set state(value) { + if (this._state != value) { + this._state = value; + this._setStateChanged(); + } + } + changeState() { + this._stateChanged = false; + this.runCallLater(this.changeClips); + var index = this._state < this._stateNum ? this._state : this._stateNum - 1; + this._sources && (this._bitmap.source = this._sources[index]); + if (this.label) { + this._text.color = this._labelColors[index]; + if (this._strokeColors) + this._text.strokeColor = this._strokeColors[index]; + } + } + get labelColors() { + return this._labelColors.join(","); + } + set labelColors(value) { + this._labelColors = UIUtils.fillArray(Styles.buttonLabelColors, value, String); + this._setStateChanged(); + } + get strokeColors() { + return this._strokeColors ? this._strokeColors.join(",") : ""; + } + set strokeColors(value) { + this._strokeColors = UIUtils.fillArray(Styles.buttonLabelColors, value, String); + this._setStateChanged(); + } + get labelPadding() { + this.createText(); + return this._text.padding.join(","); + } + set labelPadding(value) { + this.createText(); + this._text.padding = UIUtils.fillArray(Styles.labelPadding, value, Number); + } + get labelSize() { + this.createText(); + return this._text.fontSize; + } + set labelSize(value) { + this.createText(); + this._text.fontSize = value; + } + get labelStroke() { + this.createText(); + return this._text.stroke; + } + set labelStroke(value) { + this.createText(); + this._text.stroke = value; + } + get labelStrokeColor() { + this.createText(); + return this._text.strokeColor; + } + set labelStrokeColor(value) { + this.createText(); + this._text.strokeColor = value; + } + get labelBold() { + this.createText(); + return this._text.bold; + } + set labelBold(value) { + this.createText(); + this._text.bold = value; + } + get labelFont() { + this.createText(); + return this._text.font; + } + set labelFont(value) { + this.createText(); + this._text.font = value; + } + get labelAlign() { + this.createText(); + return this._text.align; + } + set labelAlign(value) { + this.createText(); + this._text.align = value; + } + get clickHandler() { + return this._clickHandler; + } + set clickHandler(value) { + this._clickHandler = value; + } + get text() { + this.createText(); + return this._text; + } + get sizeGrid() { + if (this._bitmap.sizeGrid) + return this._bitmap.sizeGrid.join(","); + return null; + } + set sizeGrid(value) { + this._bitmap.sizeGrid = UIUtils.fillArray(Styles.defaultSizeGrid, value, Number); + } + set width(value) { + super.set_width(value); + if (this._autoSize) { + this._bitmap.width = value; + this._text && (this._text.width = value); + } + } + get width() { + return super.get_width(); + } + set height(value) { + super.set_height(value); + if (this._autoSize) { + this._bitmap.height = value; + this._text && (this._text.height = value); + } + } + get height() { + return super.get_height(); + } + set dataSource(value) { + this._dataSource = value; + if (typeof (value) == 'number' || typeof (value) == 'string') + this.label = value + ""; + else + super.set_dataSource(value); + } + get dataSource() { + return super.get_dataSource(); + } + get iconOffset() { + return this._bitmap._offset ? this._bitmap._offset.join(",") : null; + } + set iconOffset(value) { + if (value) + this._bitmap._offset = UIUtils.fillArray([1, 1], value, Number); + else + this._bitmap._offset = []; + } + _setStateChanged() { + if (!this._stateChanged) { + this._stateChanged = true; + this.callLater(this.changeState); + } + } + } + Button.stateMap = { "mouseup": 0, "mouseover": 1, "mousedown": 2, "mouseout": 0 }; + Laya.ILaya.regClass(Button); + Laya.ClassUtils.regClass("laya.ui.Button", Button); + Laya.ClassUtils.regClass("Laya.Button", Button); + + class CheckBox extends Button { + constructor(skin = null, label = "") { + super(skin, label); + this.toggle = true; + this._autoSize = false; + } + preinitialize() { + super.preinitialize(); + this.toggle = true; + this._autoSize = false; + } + initialize() { + super.initialize(); + this.createText(); + this._text.align = "left"; + this._text.valign = "top"; + this._text.width = 0; + } + set dataSource(value) { + this._dataSource = value; + if (value instanceof Boolean) + this.selected = value; + else if (typeof (value) == 'string') + this.selected = value === "true"; + else + super.dataSource = value; + } + get dataSource() { + return super.dataSource; + } + } + Laya.ILaya.regClass(CheckBox); + Laya.ClassUtils.regClass("laya.ui.CheckBox", CheckBox); + Laya.ClassUtils.regClass("Laya.CheckBox", CheckBox); + + class Clip extends UIComponent { + constructor(url = null, clipX = 1, clipY = 1) { + super(); + this._clipX = 1; + this._clipY = 1; + this._clipWidth = 0; + this._clipHeight = 0; + this._interval = 50; + this._index = 0; + this._toIndex = -1; + this._clipX = clipX; + this._clipY = clipY; + this.skin = url; + } + destroy(destroyChild = true) { + super.destroy(true); + this._bitmap && this._bitmap.destroy(); + this._bitmap = null; + this._sources = null; + } + dispose() { + this.destroy(true); + Laya.ILaya.loader.clearRes(this._skin); + } + createChildren() { + this.graphics = this._bitmap = new AutoBitmap(); + } + _onDisplay(e) { + if (this._isPlaying) { + if (this._getBit(Laya.Const.DISPLAYED_INSTAGE)) + this.play(); + else + this.stop(); + } + else if (this._autoPlay) { + this.play(); + } + } + get skin() { + return this._skin; + } + set skin(value) { + if (this._skin != value) { + this._skin = value; + if (value) { + if (!Laya.Loader.getRes(value)) { + Laya.ILaya.loader.load(this._skin, Laya.Handler.create(this, this._skinLoaded), null, Laya.Loader.IMAGE, 1); + } + else { + this._skinLoaded(); + } + } + else { + this._bitmap.source = null; + } + } + } + _skinLoaded() { + this._setClipChanged(); + this._sizeChanged(); + this.event(Laya.Event.LOADED); + } + get clipX() { + return this._clipX; + } + set clipX(value) { + this._clipX = value || 1; + this._setClipChanged(); + } + get clipY() { + return this._clipY; + } + set clipY(value) { + this._clipY = value || 1; + this._setClipChanged(); + } + get clipWidth() { + return this._clipWidth; + } + set clipWidth(value) { + this._clipWidth = value; + this._setClipChanged(); + } + get clipHeight() { + return this._clipHeight; + } + set clipHeight(value) { + this._clipHeight = value; + this._setClipChanged(); + } + changeClip() { + this._clipChanged = false; + if (!this._skin || this.destroyed) + return; + var img = Laya.Loader.getRes(this._skin); + if (img) { + this.loadComplete(this._skin, img); + } + else { + Laya.ILaya.loader.load(this._skin, Laya.Handler.create(this, this.loadComplete, [this._skin])); + } + } + loadComplete(url, img) { + if (url === this._skin && img) { + var w = this._clipWidth || Math.ceil(img.sourceWidth / this._clipX); + var h = this._clipHeight || Math.ceil(img.sourceHeight / this._clipY); + var key = this._skin + w + h; + var clips = Laya.WeakObject.I.get(key); + if (!Laya.Utils.isOkTextureList(clips)) { + clips = null; + } + if (clips) + this._sources = clips; + else { + this._sources = []; + for (var i = 0; i < this._clipY; i++) { + for (var j = 0; j < this._clipX; j++) { + this._sources.push(Laya.Texture.createFromTexture(img, w * j, h * i, w, h)); + } + } + Laya.WeakObject.I.set(key, this._sources); + } + this.index = this._index; + this.event(Laya.Event.LOADED); + this.onCompResize(); + } + } + get sources() { + return this._sources; + } + set sources(value) { + this._sources = value; + this.index = this._index; + this.event(Laya.Event.LOADED); + } + get group() { + return this._group; + } + set group(value) { + if (value && this._skin) + Laya.Loader.setGroup(this._skin, value); + this._group = value; + } + set width(value) { + super.width = value; + this._bitmap.width = value; + } + get width() { + return super.width; + } + set height(value) { + super.height = value; + this._bitmap.height = value; + } + get height() { + return super.height; + } + measureWidth() { + this.runCallLater(this.changeClip); + return this._bitmap.width; + } + measureHeight() { + this.runCallLater(this.changeClip); + return this._bitmap.height; + } + get sizeGrid() { + if (this._bitmap.sizeGrid) + return this._bitmap.sizeGrid.join(","); + return null; + } + set sizeGrid(value) { + this._bitmap.sizeGrid = UIUtils.fillArray(Styles.defaultSizeGrid, value, Number); + } + get index() { + return this._index; + } + set index(value) { + this._index = value; + this._bitmap && this._sources && (this._bitmap.source = this._sources[value]); + this.event(Laya.Event.CHANGE); + } + get total() { + this.runCallLater(this.changeClip); + return this._sources ? this._sources.length : 0; + } + get autoPlay() { + return this._autoPlay; + } + set autoPlay(value) { + if (this._autoPlay != value) { + this._autoPlay = value; + value ? this.play() : this.stop(); + } + } + get interval() { + return this._interval; + } + set interval(value) { + if (this._interval != value) { + this._interval = value; + if (this._isPlaying) + this.play(); + } + } + get isPlaying() { + return this._isPlaying; + } + set isPlaying(value) { + this._isPlaying = value; + } + play(from = 0, to = -1) { + this._isPlaying = true; + this.index = from; + this._toIndex = to; + this._index++; + Laya.ILaya.timer.loop(this.interval, this, this._loop); + this.on(Laya.Event.DISPLAY, this, this._onDisplay); + this.on(Laya.Event.UNDISPLAY, this, this._onDisplay); + } + _loop() { + if (this._visible && this._sources) { + this._index++; + if (this._toIndex > -1 && this._index >= this._toIndex) + this.stop(); + else if (this._index >= this._sources.length) + this._index = 0; + this.index = this._index; + } + } + stop() { + this._isPlaying = false; + Laya.ILaya.timer.clear(this, this._loop); + this.event(Laya.Event.COMPLETE); + } + set dataSource(value) { + this._dataSource = value; + if (typeof (value) == 'number' || typeof (value) == 'string') + this.index = parseInt(value); + else + super.dataSource = value; + } + get dataSource() { + return super.dataSource; + } + get bitmap() { + return this._bitmap; + } + _setClipChanged() { + if (!this._clipChanged) { + this._clipChanged = true; + this.callLater(this.changeClip); + } + } + } + Laya.ILaya.regClass(Clip); + Laya.ClassUtils.regClass("laya.ui.Clip", Clip); + Laya.ClassUtils.regClass("Laya.Clip", Clip); + + class ColorPicker extends UIComponent { + constructor(createChildren = true) { + super(false); + this._gridSize = 11; + this._bgColor = "#ffffff"; + this._borderColor = "#000000"; + this._inputColor = "#000000"; + this._inputBgColor = "#efefef"; + this._colors = []; + this._selectedColor = "#000000"; + if (createChildren) { + this.preinitialize(); + this.createChildren(); + this.initialize(); + } + } + destroy(destroyChild = true) { + Laya.ILaya.stage.off(Laya.Event.MOUSE_DOWN, this, this.removeColorBox); + super.destroy(destroyChild); + this._colorPanel && this._colorPanel.destroy(destroyChild); + this._colorButton && this._colorButton.destroy(destroyChild); + this._colorPanel = null; + this._colorTiles = null; + this._colorBlock = null; + this._colorInput = null; + this._colorButton = null; + this._colors = null; + this.changeHandler = null; + } + createChildren() { + this.addChild(this._colorButton = new Button()); + this._colorPanel = new Box(); + this._colorPanel.size(230, 166); + this._colorPanel.addChild(this._colorTiles = new Laya.Sprite()); + this._colorPanel.addChild(this._colorBlock = new Laya.Sprite()); + this._colorPanel.addChild(this._colorInput = new Laya.Input()); + } + initialize() { + this._colorButton.on(Laya.Event.CLICK, this, this.onColorButtonClick); + this._colorBlock.pos(5, 5); + this._colorInput.pos(60, 5); + this._colorInput.size(60, 20); + this._colorInput.on(Laya.Event.CHANGE, this, this.onColorInputChange); + this._colorInput.on(Laya.Event.KEY_DOWN, this, this.onColorFieldKeyDown); + this._colorTiles.pos(5, 30); + this._colorTiles.on(Laya.Event.MOUSE_MOVE, this, this.onColorTilesMouseMove); + this._colorTiles.on(Laya.Event.CLICK, this, this.onColorTilesClick); + this._colorTiles.size(20 * this._gridSize, 12 * this._gridSize); + this._colorPanel.on(Laya.Event.MOUSE_DOWN, this, this.onPanelMouseDown); + this.bgColor = this._bgColor; + } + onPanelMouseDown(e) { + e.stopPropagation(); + } + changePanel() { + this._panelChanged = false; + var g = this._colorPanel.graphics; + g.clear(true); + g.drawRect(0, 0, 230, 166, this._bgColor, this._borderColor); + this.drawBlock(this._selectedColor); + this._colorInput.borderColor = this._borderColor; + this._colorInput.bgColor = this._inputBgColor; + this._colorInput.color = this._inputColor; + g = this._colorTiles.graphics; + g.clear(true); + var mainColors = [0x000000, 0x333333, 0x666666, 0x999999, 0xCCCCCC, 0xFFFFFF, 0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF, 0xFF00FF]; + for (var i = 0; i < 12; i++) { + for (var j = 0; j < 20; j++) { + var color; + if (j === 0) + color = mainColors[i]; + else if (j === 1) + color = 0x000000; + else + color = (((i * 3 + j / 6) % 3 << 0) + ((i / 6) << 0) * 3) * 0x33 << 16 | j % 6 * 0x33 << 8 | (i << 0) % 6 * 0x33; + var strColor = UIUtils.toColor(color); + this._colors.push(strColor); + var x = j * this._gridSize; + var y = i * this._gridSize; + g.drawRect(x, y, this._gridSize, this._gridSize, strColor, "#000000"); + } + } + } + onColorButtonClick(e) { + if (this._colorPanel.parent) + this.close(); + else + this.open(); + } + open() { + let stage = Laya.ILaya.stage; + var p = this.localToGlobal(new Laya.Point()); + var px = p.x + this._colorPanel.width <= stage.width ? p.x : stage.width - this._colorPanel.width; + var py = p.y + this._colorButton.height; + py = py + this._colorPanel.height <= stage.height ? py : p.y - this._colorPanel.height; + this._colorPanel.pos(px, py); + this._colorPanel.zOrder = 1001; + stage.addChild(this._colorPanel); + stage.on(Laya.Event.MOUSE_DOWN, this, this.removeColorBox); + } + close() { + Laya.ILaya.stage.off(Laya.Event.MOUSE_DOWN, this, this.removeColorBox); + this._colorPanel.removeSelf(); + } + removeColorBox(e = null) { + this.close(); + } + onColorFieldKeyDown(e) { + if (e.keyCode == 13) { + if (this._colorInput.text) + this.selectedColor = this._colorInput.text; + else + this.selectedColor = null; + this.close(); + e.stopPropagation(); + } + } + onColorInputChange(e = null) { + if (this._colorInput.text) + this.drawBlock(this._colorInput.text); + else + this.drawBlock("#FFFFFF"); + } + onColorTilesClick(e) { + this.selectedColor = this.getColorByMouse(); + this.close(); + } + onColorTilesMouseMove(e) { + this._colorInput.focus = false; + var color = this.getColorByMouse(); + this._colorInput.text = color; + this.drawBlock(color); + } + getColorByMouse() { + var point = this._colorTiles.getMousePoint(); + var x = Math.floor(point.x / this._gridSize); + var y = Math.floor(point.y / this._gridSize); + return this._colors[y * 20 + x]; + } + drawBlock(color) { + var g = this._colorBlock.graphics; + g.clear(true); + var showColor = color ? color : "#ffffff"; + g.drawRect(0, 0, 50, 20, showColor, this._borderColor); + color || g.drawLine(0, 0, 50, 20, "#ff0000"); + } + get selectedColor() { + return this._selectedColor; + } + set selectedColor(value) { + if (this._selectedColor != value) { + this._selectedColor = this._colorInput.text = value; + this.drawBlock(value); + this.changeColor(); + this.changeHandler && this.changeHandler.runWith(this._selectedColor); + this.event(Laya.Event.CHANGE, Laya.Event.EMPTY.setTo(Laya.Event.CHANGE, this, this)); + } + } + get skin() { + return this._colorButton.skin; + } + set skin(value) { + this._colorButton.once(Laya.Event.LOADED, this, this.changeColor); + this._colorButton.skin = value; + } + changeColor() { + var g = this.graphics; + g.clear(true); + var showColor = this._selectedColor || "#000000"; + g.drawRect(0, 0, this._colorButton.width, this._colorButton.height, showColor); + } + get bgColor() { + return this._bgColor; + } + set bgColor(value) { + this._bgColor = value; + this._setPanelChanged(); + } + get borderColor() { + return this._borderColor; + } + set borderColor(value) { + this._borderColor = value; + this._setPanelChanged(); + } + get inputColor() { + return this._inputColor; + } + set inputColor(value) { + this._inputColor = value; + this._setPanelChanged(); + } + get inputBgColor() { + return this._inputBgColor; + } + set inputBgColor(value) { + this._inputBgColor = value; + this._setPanelChanged(); + } + _setPanelChanged() { + if (!this._panelChanged) { + this._panelChanged = true; + this.callLater(this.changePanel); + } + } + } + Laya.ILaya.regClass(ColorPicker); + Laya.ClassUtils.regClass("laya.ui.ColorPicker", ColorPicker); + Laya.ClassUtils.regClass("Laya.ColorPicker", ColorPicker); + + class Label extends UIComponent { + constructor(text = "") { + super(); + this.text = text; + } + destroy(destroyChild = true) { + super.destroy(destroyChild); + this._tf = null; + } + createChildren() { + this.addChild(this._tf = new Laya.Text()); + } + get text() { + return this._tf.text; + } + set text(value) { + if (this._tf.text != value) { + if (value) + value = UIUtils.adptString(value + ""); + this._tf.text = value; + this.event(Laya.Event.CHANGE); + if (!this._width || !this._height) + this.onCompResize(); + } + } + changeText(text) { + this._tf.changeText(text); + } + get wordWrap() { + return this._tf.wordWrap; + } + set wordWrap(value) { + this._tf.wordWrap = value; + } + get color() { + return this._tf.color; + } + set color(value) { + this._tf.color = value; + } + get font() { + return this._tf.font; + } + set font(value) { + this._tf.font = value; + } + get align() { + return this._tf.align; + } + set align(value) { + this._tf.align = value; + } + get valign() { + return this._tf.valign; + } + set valign(value) { + this._tf.valign = value; + } + get bold() { + return this._tf.bold; + } + set bold(value) { + this._tf.bold = value; + } + get italic() { + return this._tf.italic; + } + set italic(value) { + this._tf.italic = value; + } + get leading() { + return this._tf.leading; + } + set leading(value) { + this._tf.leading = value; + } + get fontSize() { + return this._tf.fontSize; + } + set fontSize(value) { + this._tf.fontSize = value; + } + get padding() { + return this._tf.padding.join(","); + } + set padding(value) { + this._tf.padding = UIUtils.fillArray(Styles.labelPadding, value, Number); + } + get bgColor() { + return this._tf.bgColor; + } + set bgColor(value) { + this._tf.bgColor = value; + } + get borderColor() { + return this._tf.borderColor; + } + set borderColor(value) { + this._tf.borderColor = value; + } + get stroke() { + return this._tf.stroke; + } + set stroke(value) { + this._tf.stroke = value; + } + get strokeColor() { + return this._tf.strokeColor; + } + set strokeColor(value) { + this._tf.strokeColor = value; + } + get textField() { + return this._tf; + } + measureWidth() { + return this._tf.width; + } + measureHeight() { + return this._tf.height; + } + get width() { + if (this._width || this._tf.text) + return super.width; + return 0; + } + set width(value) { + super.width = value; + this._tf.width = value; + } + get height() { + if (this._height || this._tf.text) + return super.height; + return 0; + } + set height(value) { + super.height = value; + this._tf.height = value; + } + set dataSource(value) { + this._dataSource = value; + if (typeof (value) == 'number' || typeof (value) == 'string') + this.text = value + ""; + else + super.dataSource = value; + } + get dataSource() { + return super.dataSource; + } + get overflow() { + return this._tf.overflow; + } + set overflow(value) { + this._tf.overflow = value; + } + get underline() { + return this._tf.underline; + } + set underline(value) { + this._tf.underline = value; + } + get underlineColor() { + return this._tf.underlineColor; + } + set underlineColor(value) { + this._tf.underlineColor = value; + } + } + Laya.ILaya.regClass(Label); + Laya.ClassUtils.regClass("laya.ui.Label", Label); + Laya.ClassUtils.regClass("Laya.Label", Label); + + class Slider extends UIComponent { + constructor(skin = null) { + super(); + this.isVertical = true; + this.showLabel = true; + this._max = 100; + this._min = 0; + this._tick = 1; + this._value = 0; + if (!Slider.label) { + Slider.label = new Label(); + } + this.skin = skin; + } + destroy(destroyChild = true) { + super.destroy(destroyChild); + this._bg && this._bg.destroy(destroyChild); + this._bar && this._bar.destroy(destroyChild); + this._progress && this._progress.destroy(destroyChild); + this._bg = null; + this._bar = null; + this._progress = null; + this.changeHandler = null; + } + createChildren() { + this.addChild(this._bg = new Image()); + this.addChild(this._bar = new Button()); + } + initialize() { + this._bar.on(Laya.Event.MOUSE_DOWN, this, this.onBarMouseDown); + this._bg.sizeGrid = this._bar.sizeGrid = "4,4,4,4,0"; + if (this._progress) + this._progress.sizeGrid = this._bar.sizeGrid; + this.allowClickBack = true; + } + onBarMouseDown(e) { + var Laya$1 = Laya.ILaya; + this._globalSacle || (this._globalSacle = new Laya.Point()); + this._globalSacle.setTo(this.globalScaleX || 0.01, this.globalScaleY || 0.01); + this._maxMove = this.isVertical ? (this.height - this._bar.height) : (this.width - this._bar.width); + this._tx = Laya$1.stage.mouseX; + this._ty = Laya$1.stage.mouseY; + Laya$1.stage.on(Laya.Event.MOUSE_MOVE, this, this.mouseMove); + Laya$1.stage.once(Laya.Event.MOUSE_UP, this, this.mouseUp); + Laya$1.stage.once(Laya.Event.MOUSE_OUT, this, this.mouseUp); + this.showValueText(); + } + showValueText() { + if (this.showLabel) { + var label = Slider.label; + this.addChild(label); + label.textField.changeText(this._value + ""); + if (this.isVertical) { + label.x = this._bar._x + 20; + label.y = (this._bar.height - label.height) * 0.5 + this._bar._y; + } + else { + label.y = this._bar._y - 20; + label.x = (this._bar.width - label.width) * 0.5 + this._bar._x; + } + } + } + hideValueText() { + Slider.label && Slider.label.removeSelf(); + } + mouseUp(e) { + let stage = Laya.ILaya.stage; + stage.off(Laya.Event.MOUSE_MOVE, this, this.mouseMove); + stage.off(Laya.Event.MOUSE_UP, this, this.mouseUp); + stage.off(Laya.Event.MOUSE_OUT, this, this.mouseUp); + this.sendChangeEvent(Laya.Event.CHANGED); + this.hideValueText(); + } + mouseMove(e) { + let stage = Laya.ILaya.stage; + var oldValue = this._value; + if (this.isVertical) { + this._bar.y += (stage.mouseY - this._ty) / this._globalSacle.y; + if (this._bar._y > this._maxMove) + this._bar.y = this._maxMove; + else if (this._bar._y < 0) + this._bar.y = 0; + this._value = this._bar._y / this._maxMove * (this._max - this._min) + this._min; + if (this._progress) + this._progress.height = this._bar._y + 0.5 * this._bar.height; + } + else { + this._bar.x += (stage.mouseX - this._tx) / this._globalSacle.x; + if (this._bar._x > this._maxMove) + this._bar.x = this._maxMove; + else if (this._bar._x < 0) + this._bar.x = 0; + this._value = this._bar._x / this._maxMove * (this._max - this._min) + this._min; + if (this._progress) + this._progress.width = this._bar._x + 0.5 * this._bar.width; + } + this._tx = stage.mouseX; + this._ty = stage.mouseY; + if (this._tick != 0) { + var pow = Math.pow(10, (this._tick + "").length - 1); + this._value = Math.round(Math.round(this._value / this._tick) * this._tick * pow) / pow; + } + if (this._value != oldValue) { + this.sendChangeEvent(); + } + this.showValueText(); + } + sendChangeEvent(type = Laya.Event.CHANGE) { + this.event(type); + this.changeHandler && this.changeHandler.runWith(this._value); + } + get skin() { + return this._skin; + } + set skin(value) { + if (this._skin != value) { + this._skin = value; + if (this._skin && !Laya.Loader.getRes(this._skin)) { + Laya.ILaya.loader.load([this._skin, this._skin.replace(".png", "$bar.png")], Laya.Handler.create(this, this._skinLoaded)); + } + else { + this._skinLoaded(); + } + } + } + _skinLoaded() { + this._bg.skin = this._skin; + this._bar.skin = this._skin.replace(".png", "$bar.png"); + var progressSkin = this._skin.replace(".png", "$progress.png"); + if (Laya.Loader.getRes(progressSkin)) { + if (!this._progress) { + this.addChild(this._progress = new Image()); + this._progress.sizeGrid = this._bar.sizeGrid; + this.setChildIndex(this._progress, 1); + } + this._progress.skin = progressSkin; + } + this.setBarPoint(); + this.callLater(this.changeValue); + this._sizeChanged(); + this.event(Laya.Event.LOADED); + } + setBarPoint() { + if (this.isVertical) + this._bar.x = Math.round((this._bg.width - this._bar.width) * 0.5); + else + this._bar.y = Math.round((this._bg.height - this._bar.height) * 0.5); + } + measureWidth() { + return Math.max(this._bg.width, this._bar.width); + } + measureHeight() { + return Math.max(this._bg.height, this._bar.height); + } + _sizeChanged() { + super._sizeChanged(); + if (this.isVertical) + this._bg.height = this.height; + else + this._bg.width = this.width; + this.setBarPoint(); + this.changeValue(); + } + get sizeGrid() { + return this._bg.sizeGrid; + } + set sizeGrid(value) { + this._bg.sizeGrid = value; + this._bar.sizeGrid = value; + if (this._progress) + this._progress.sizeGrid = this._bar.sizeGrid; + } + setSlider(min, max, value) { + this._value = -1; + this._min = min; + this._max = max > min ? max : min; + this.value = value < min ? min : value > max ? max : value; + } + get tick() { + return this._tick; + } + set tick(value) { + if (this._tick != value) { + this._tick = value; + this.callLater(this.changeValue); + } + } + changeValue() { + if (this.tick != 0) { + var pow = Math.pow(10, (this._tick + "").length - 1); + this._value = Math.round(Math.round(this._value / this._tick) * this._tick * pow) / pow; + } + if (this._max >= this._max) { + this._value = this._value > this._max ? this._max : this._value < this._min ? this._min : this._value; + } + else { + this._value = this._value > this._min ? this._min : this._value < this._max ? this._max : this._value; + } + var num = this._max - this._min; + if (num === 0) + num = 1; + if (this.isVertical) { + this._bar.y = (this._value - this._min) / num * (this.height - this._bar.height); + if (this._progress) + this._progress.height = this._bar._y + 0.5 * this._bar.height; + } + else { + this._bar.x = (this._value - this._min) / num * (this.width - this._bar.width); + if (this._progress) + this._progress.width = this._bar._x + 0.5 * this._bar.width; + } + } + get max() { + return this._max; + } + set max(value) { + if (this._max != value) { + this._max = value; + this.callLater(this.changeValue); + } + } + get min() { + return this._min; + } + set min(value) { + if (this._min != value) { + this._min = value; + this.callLater(this.changeValue); + } + } + get value() { + return this._value; + } + set value(num) { + if (this._value != num) { + var oldValue = this._value; + this._value = num; + this.changeValue(); + if (this._value != oldValue) { + this.sendChangeEvent(); + } + } + } + get allowClickBack() { + return this._allowClickBack; + } + set allowClickBack(value) { + if (this._allowClickBack != value) { + this._allowClickBack = value; + if (value) + this._bg.on(Laya.Event.MOUSE_DOWN, this, this.onBgMouseDown); + else + this._bg.off(Laya.Event.MOUSE_DOWN, this, this.onBgMouseDown); + } + } + onBgMouseDown(e) { + var point = this._bg.getMousePoint(); + if (this.isVertical) + this.value = point.y / (this.height - this._bar.height) * (this._max - this._min) + this._min; + else + this.value = point.x / (this.width - this._bar.width) * (this._max - this._min) + this._min; + } + set dataSource(value) { + this._dataSource = value; + if (typeof (value) == 'number' || typeof (value) == 'string') + this.value = Number(value); + else + super.dataSource = value; + } + get dataSource() { + return super.dataSource; + } + get bar() { + return this._bar; + } + } + Slider.label = null; + Laya.ILaya.regClass(Slider); + Laya.ClassUtils.regClass("laya.ui.Slider", Slider); + Laya.ClassUtils.regClass("Laya.Slider", Slider); + + class ScrollBar extends UIComponent { + constructor(skin = null) { + super(); + this.rollRatio = 0.97; + this.scaleBar = true; + this.autoHide = false; + this.elasticDistance = 0; + this.elasticBackTime = 500; + this._showButtons = UIConfig.showButtons; + this._scrollSize = 1; + this._thumbPercent = 1; + this._lastOffset = 0; + this._checkElastic = false; + this._isElastic = false; + this._hide = false; + this._clickOnly = true; + this._touchScrollEnable = UIConfig.touchScrollEnable; + this._mouseWheelEnable = UIConfig.mouseWheelEnable; + this.skin = skin; + this.max = 1; + } + destroy(destroyChild = true) { + this.stopScroll(); + this.target = null; + super.destroy(destroyChild); + this.upButton && this.upButton.destroy(destroyChild); + this.downButton && this.downButton.destroy(destroyChild); + this.slider && this.slider.destroy(destroyChild); + this.upButton = this.downButton = null; + this.slider = null; + this.changeHandler = null; + this._offsets = null; + } + createChildren() { + this.addChild(this.slider = new Slider()); + this.addChild(this.upButton = new Button()); + this.addChild(this.downButton = new Button()); + } + initialize() { + this.slider.showLabel = false; + this.slider.tick = 0; + this.slider.on(Laya.Event.CHANGE, this, this.onSliderChange); + this.slider.setSlider(0, 0, 0); + this.upButton.on(Laya.Event.MOUSE_DOWN, this, this.onButtonMouseDown); + this.downButton.on(Laya.Event.MOUSE_DOWN, this, this.onButtonMouseDown); + } + onSliderChange() { + if (this._value != this.slider.value) + this.value = this.slider.value; + } + onButtonMouseDown(e) { + var isUp = e.currentTarget === this.upButton; + this.slide(isUp); + Laya.ILaya.timer.once(Styles.scrollBarDelayTime, this, this.startLoop, [isUp]); + Laya.ILaya.stage.once(Laya.Event.MOUSE_UP, this, this.onStageMouseUp); + } + startLoop(isUp) { + Laya.ILaya.timer.frameLoop(1, this, this.slide, [isUp]); + } + slide(isUp) { + if (isUp) + this.value -= this._scrollSize; + else + this.value += this._scrollSize; + } + onStageMouseUp(e) { + Laya.ILaya.timer.clear(this, this.startLoop); + Laya.ILaya.timer.clear(this, this.slide); + } + get skin() { + return this._skin; + } + set skin(value) { + if (value == " ") + return; + if (this._skin != value) { + this._skin = value; + if (this._skin && !Laya.Loader.getRes(this._skin)) { + Laya.ILaya.loader.load([this._skin, this._skin.replace(".png", "$up.png"), this._skin.replace(".png", "$down.png"), this._skin.replace(".png", "$bar.png")], Laya.Handler.create(this, this._skinLoaded)); + } + else { + this._skinLoaded(); + } + } + } + _skinLoaded() { + if (this.destroyed) { + return; + } + this.slider.skin = this._skin; + this.callLater(this.changeScrollBar); + this._sizeChanged(); + this.event(Laya.Event.LOADED); + } + changeScrollBar() { + this.upButton.visible = this._showButtons; + this.downButton.visible = this._showButtons; + if (this._showButtons) { + this.upButton.skin = this._skin.replace(".png", "$up.png"); + this.downButton.skin = this._skin.replace(".png", "$down.png"); + } + if (this.slider.isVertical) + this.slider.y = this._showButtons ? this.upButton.height : 0; + else + this.slider.x = this._showButtons ? this.upButton.width : 0; + this.resetPositions(); + this.repaint(); + } + _sizeChanged() { + super._sizeChanged(); + this.repaint(); + this.resetPositions(); + this.event(Laya.Event.CHANGE); + this.changeHandler && this.changeHandler.runWith(this.value); + } + resetPositions() { + if (this.slider.isVertical) + this.slider.height = this.height - (this._showButtons ? (this.upButton.height + this.downButton.height) : 0); + else + this.slider.width = this.width - (this._showButtons ? (this.upButton.width + this.downButton.width) : 0); + this.resetButtonPosition(); + } + resetButtonPosition() { + if (this.slider.isVertical) + this.downButton.y = this.slider._y + this.slider.height; + else + this.downButton.x = this.slider._x + this.slider.width; + } + measureWidth() { + if (this.slider.isVertical) + return this.slider.width; + return 100; + } + measureHeight() { + if (this.slider.isVertical) + return 100; + return this.slider.height; + } + setScroll(min, max, value) { + this.runCallLater(this._sizeChanged); + this.slider.setSlider(min, max, value); + this.slider.bar.visible = max > 0; + if (!this._hide && this.autoHide) + this.visible = false; + } + get max() { + return this.slider.max; + } + set max(value) { + this.slider.max = value; + } + get min() { + return this.slider.min; + } + set min(value) { + this.slider.min = value; + } + get value() { + return this._value; + } + set value(v) { + if (v !== this._value) { + this._value = v; + if (!this._isElastic) { + if (this.slider["_value"] != v) { + this.slider["_value"] = v; + this.slider.changeValue(); + } + this._value = this.slider["_value"]; + } + this.event(Laya.Event.CHANGE); + this.changeHandler && this.changeHandler.runWith(this._value); + } + } + get isVertical() { + return this.slider.isVertical; + } + set isVertical(value) { + this.slider.isVertical = value; + } + get sizeGrid() { + return this.slider.sizeGrid; + } + set sizeGrid(value) { + this.slider.sizeGrid = value; + } + get scrollSize() { + return this._scrollSize; + } + set scrollSize(value) { + this._scrollSize = value; + } + set dataSource(value) { + this._dataSource = value; + if (typeof (value) == 'number' || typeof (value) == 'string') + this.value = Number(value); + else + super.dataSource = value; + } + get dataSource() { + return super.dataSource; + } + get thumbPercent() { + return this._thumbPercent; + } + set thumbPercent(value) { + this.runCallLater(this.changeScrollBar); + this.runCallLater(this._sizeChanged); + value = value >= 1 ? 0.99 : value; + this._thumbPercent = value; + if (this.scaleBar) { + if (this.slider.isVertical) + this.slider.bar.height = Math.max(this.slider.height * value, Styles.scrollBarMinNum); + else + this.slider.bar.width = Math.max(this.slider.width * value, Styles.scrollBarMinNum); + } + } + get target() { + return this._target; + } + set target(value) { + if (this._target) { + this._target.off(Laya.Event.MOUSE_WHEEL, this, this.onTargetMouseWheel); + this._target.off(Laya.Event.MOUSE_DOWN, this, this.onTargetMouseDown); + } + this._target = value; + if (value) { + this._mouseWheelEnable && this._target.on(Laya.Event.MOUSE_WHEEL, this, this.onTargetMouseWheel); + this._touchScrollEnable && this._target.on(Laya.Event.MOUSE_DOWN, this, this.onTargetMouseDown); + } + } + get hide() { + return this._hide; + } + set hide(value) { + this._hide = value; + this.visible = !value; + } + get showButtons() { + return this._showButtons; + } + set showButtons(value) { + this._showButtons = value; + this.callLater(this.changeScrollBar); + } + get touchScrollEnable() { + return this._touchScrollEnable; + } + set touchScrollEnable(value) { + this._touchScrollEnable = value; + this.target = this._target; + } + get mouseWheelEnable() { + return this._mouseWheelEnable; + } + set mouseWheelEnable(value) { + this._mouseWheelEnable = value; + this.target = this._target; + } + onTargetMouseWheel(e) { + this.value -= e.delta * this._scrollSize; + this.target = this._target; + } + onTargetMouseDown(e) { + if ((this.isLockedFun) && !this.isLockedFun(e)) + return; + this.event(Laya.Event.END); + this._clickOnly = true; + this._lastOffset = 0; + this._checkElastic = false; + this._lastPoint || (this._lastPoint = new Laya.Point()); + this._lastPoint.setTo(Laya.ILaya.stage.mouseX, Laya.ILaya.stage.mouseY); + Laya.ILaya.timer.clear(this, this.tweenMove); + Laya.Tween.clearTween(this); + Laya.ILaya.stage.once(Laya.Event.MOUSE_UP, this, this.onStageMouseUp2); + Laya.ILaya.stage.once(Laya.Event.MOUSE_OUT, this, this.onStageMouseUp2); + Laya.ILaya.timer.frameLoop(1, this, this.loop); + } + startDragForce() { + this._clickOnly = true; + this._lastOffset = 0; + this._checkElastic = false; + this._lastPoint || (this._lastPoint = new Laya.Point()); + this._lastPoint.setTo(Laya.ILaya.stage.mouseX, Laya.ILaya.stage.mouseY); + Laya.ILaya.timer.clear(this, this.tweenMove); + Laya.Tween.clearTween(this); + Laya.ILaya.stage.once(Laya.Event.MOUSE_UP, this, this.onStageMouseUp2); + Laya.ILaya.stage.once(Laya.Event.MOUSE_OUT, this, this.onStageMouseUp2); + Laya.ILaya.timer.frameLoop(1, this, this.loop); + } + cancelDragOp() { + Laya.ILaya.stage.off(Laya.Event.MOUSE_UP, this, this.onStageMouseUp2); + Laya.ILaya.stage.off(Laya.Event.MOUSE_OUT, this, this.onStageMouseUp2); + Laya.ILaya.timer.clear(this, this.tweenMove); + Laya.ILaya.timer.clear(this, this.loop); + this._target.mouseEnabled = true; + } + checkTriggers(isTweenMove = false) { + if (this.value >= 0 && this.value - this._lastOffset <= 0) { + if ((this.triggerDownDragLimit) && this.triggerDownDragLimit(isTweenMove)) { + this.cancelDragOp(); + this.value = 0; + return true; + } + } + if (this.value <= this.max && (this.value - this._lastOffset >= this.max)) { + if ((this.triggerUpDragLimit) && this.triggerUpDragLimit(isTweenMove)) { + this.cancelDragOp(); + this.value = this.max; + return true; + } + } + return false; + } + get lastOffset() { + return this._lastOffset; + } + startTweenMoveForce(lastOffset) { + this._lastOffset = lastOffset; + Laya.ILaya.timer.frameLoop(1, this, this.tweenMove, [200]); + } + loop() { + var mouseY = Laya.ILaya.stage.mouseY; + var mouseX = Laya.ILaya.stage.mouseX; + this._lastOffset = this.isVertical ? (mouseY - this._lastPoint.y) : (mouseX - this._lastPoint.x); + if (this._clickOnly) { + if (Math.abs(this._lastOffset * (this.isVertical ? Laya.ILaya.stage._canvasTransform.getScaleY() : Laya.ILaya.stage._canvasTransform.getScaleX())) > 1) { + this._clickOnly = false; + if (this.checkTriggers()) + return; + this._offsets || (this._offsets = []); + this._offsets.length = 0; + this._target.mouseEnabled = false; + if (!this.hide && this.autoHide) { + this.alpha = 1; + this.visible = true; + } + this.event(Laya.Event.START); + } + else + return; + } + else { + if (this.checkTriggers()) + return; + } + this._offsets.push(this._lastOffset); + this._lastPoint.x = mouseX; + this._lastPoint.y = mouseY; + if (this._lastOffset === 0) + return; + if (!this._checkElastic) { + if (this.elasticDistance > 0) { + if (!this._checkElastic && this._lastOffset != 0) { + if ((this._lastOffset > 0 && this._value <= this.min) || (this._lastOffset < 0 && this._value >= this.max)) { + this._isElastic = true; + this._checkElastic = true; + } + else { + this._isElastic = false; + } + } + } + else { + this._checkElastic = true; + } + } + if (this._isElastic) { + if (this._value <= this.min) { + if (this._lastOffset > 0) { + this.value -= this._lastOffset * Math.max(0, (1 - ((this.min - this._value) / this.elasticDistance))); + } + else { + this.value -= this._lastOffset * 0.5; + if (this._value >= this.min) + this._checkElastic = false; + } + } + else if (this._value >= this.max) { + if (this._lastOffset < 0) { + this.value -= this._lastOffset * Math.max(0, (1 - ((this._value - this.max) / this.elasticDistance))); + } + else { + this.value -= this._lastOffset * 0.5; + if (this._value <= this.max) + this._checkElastic = false; + } + } + } + else { + this.value -= this._lastOffset; + } + } + onStageMouseUp2(e) { + Laya.ILaya.stage.off(Laya.Event.MOUSE_UP, this, this.onStageMouseUp2); + Laya.ILaya.stage.off(Laya.Event.MOUSE_OUT, this, this.onStageMouseUp2); + Laya.ILaya.timer.clear(this, this.loop); + if (this._clickOnly) { + if (this._value >= this.min && this._value <= this.max) + return; + } + this._target.mouseEnabled = true; + if (this._isElastic) { + if (this._value < this.min) { + Laya.Tween.to(this, { value: this.min }, this.elasticBackTime, Laya.Ease.sineOut, Laya.Handler.create(this, this.elasticOver)); + } + else if (this._value > this.max) { + Laya.Tween.to(this, { value: this.max }, this.elasticBackTime, Laya.Ease.sineOut, Laya.Handler.create(this, this.elasticOver)); + } + } + else { + if (!this._offsets) + return; + if (this._offsets.length < 1) { + this._offsets[0] = this.isVertical ? Laya.ILaya.stage.mouseY - this._lastPoint.y : Laya.ILaya.stage.mouseX - this._lastPoint.x; + } + var offset = 0; + var n = Math.min(this._offsets.length, 3); + for (var i = 0; i < n; i++) { + offset += this._offsets[this._offsets.length - 1 - i]; + } + this._lastOffset = offset / n; + offset = Math.abs(this._lastOffset); + if (offset < 2) { + this.event(Laya.Event.END); + return; + } + if (offset > 250) + this._lastOffset = this._lastOffset > 0 ? 250 : -250; + var dis = Math.round(Math.abs(this.elasticDistance * (this._lastOffset / 150))); + Laya.ILaya.timer.frameLoop(1, this, this.tweenMove, [dis]); + } + } + elasticOver() { + this._isElastic = false; + if (!this.hide && this.autoHide) { + Laya.Tween.to(this, { alpha: 0 }, 500); + } + this.event(Laya.Event.END); + } + tweenMove(maxDistance) { + this._lastOffset *= this.rollRatio; + if (this.checkTriggers(true)) { + return; + } + var tarSpeed; + if (maxDistance > 0) { + if (this._lastOffset > 0 && this.value <= this.min) { + this._isElastic = true; + tarSpeed = -(this.min - maxDistance - this.value) * 0.5; + if (this._lastOffset > tarSpeed) + this._lastOffset = tarSpeed; + } + else if (this._lastOffset < 0 && this.value >= this.max) { + this._isElastic = true; + tarSpeed = -(this.max + maxDistance - this.value) * 0.5; + if (this._lastOffset < tarSpeed) + this._lastOffset = tarSpeed; + } + } + this.value -= this._lastOffset; + if (Math.abs(this._lastOffset) < 0.1) { + Laya.ILaya.timer.clear(this, this.tweenMove); + if (this._isElastic) { + if (this._value < this.min) { + Laya.Tween.to(this, { value: this.min }, this.elasticBackTime, Laya.Ease.sineOut, Laya.Handler.create(this, this.elasticOver)); + } + else if (this._value > this.max) { + Laya.Tween.to(this, { value: this.max }, this.elasticBackTime, Laya.Ease.sineOut, Laya.Handler.create(this, this.elasticOver)); + } + else { + this.elasticOver(); + } + return; + } + this.event(Laya.Event.END); + if (!this.hide && this.autoHide) { + Laya.Tween.to(this, { alpha: 0 }, 500); + } + } + } + stopScroll() { + this.onStageMouseUp2(null); + Laya.ILaya.timer.clear(this, this.tweenMove); + Laya.Tween.clearTween(this); + } + get tick() { + return this.slider.tick; + } + set tick(value) { + this.slider.tick = value; + } + } + Laya.ILaya.regClass(ScrollBar); + Laya.ClassUtils.regClass("laya.ui.ScrollBar", ScrollBar); + Laya.ClassUtils.regClass("Laya.ScrollBar", ScrollBar); + + class VScrollBar extends ScrollBar { + } + Laya.ILaya.regClass(VScrollBar); + Laya.ClassUtils.regClass("laya.ui.VScrollBar", VScrollBar); + Laya.ClassUtils.regClass("Laya.VScrollBar", VScrollBar); + + class HScrollBar extends ScrollBar { + initialize() { + super.initialize(); + this.slider.isVertical = false; + } + } + Laya.ILaya.regClass(HScrollBar); + Laya.ClassUtils.regClass("laya.ui.HScrollBar", HScrollBar); + Laya.ClassUtils.regClass("Laya.HScrollBar", HScrollBar); + + class List extends Box { + constructor() { + super(...arguments); + this.selectEnable = false; + this.totalPage = 0; + this._$componentType = "List"; + this._repeatX = 0; + this._repeatY = 0; + this._repeatX2 = 0; + this._repeatY2 = 0; + this._spaceX = 0; + this._spaceY = 0; + this._cells = []; + this._startIndex = 0; + this._selectedIndex = -1; + this._page = 0; + this._isVertical = true; + this._cellSize = 20; + this._cellOffset = 0; + this._createdLine = 0; + this._offset = new Laya.Point(); + this._usedCache = null; + this._elasticEnabled = false; + this._preLen = 0; + } + destroy(destroyChild = true) { + this._content && this._content.destroy(destroyChild); + this._scrollBar && this._scrollBar.destroy(destroyChild); + super.destroy(destroyChild); + this._content = null; + this._scrollBar = null; + this._itemRender = null; + this._cells = null; + this._array = null; + this.selectHandler = this.renderHandler = this.mouseHandler = null; + } + createChildren() { + this.addChild(this._content = new Box()); + } + set cacheAs(value) { + super.cacheAs = value; + if (this._scrollBar) { + this._usedCache = null; + if (value !== "none") + this._scrollBar.on(Laya.Event.START, this, this.onScrollStart); + else + this._scrollBar.off(Laya.Event.START, this, this.onScrollStart); + } + } + get cacheAs() { + return super.cacheAs; + } + onScrollStart() { + this._usedCache || (this._usedCache = super.cacheAs); + super.cacheAs = "none"; + this._scrollBar.once(Laya.Event.END, this, this.onScrollEnd); + } + onScrollEnd() { + super.cacheAs = this._usedCache || 'none'; + } + get content() { + return this._content; + } + get vScrollBarSkin() { + return this._scrollBar ? this._scrollBar.skin : null; + } + set vScrollBarSkin(value) { + this._removePreScrollBar(); + var scrollBar = new VScrollBar(); + scrollBar.name = "scrollBar"; + scrollBar.right = 0; + scrollBar.skin = value; + scrollBar.elasticDistance = this._elasticEnabled ? 200 : 0; + this.scrollBar = scrollBar; + this.addChild(scrollBar); + this._setCellChanged(); + } + _removePreScrollBar() { + var preNode = this.removeChildByName("scrollBar"); + if (preNode) + preNode.destroy(true); + } + get hScrollBarSkin() { + return this._scrollBar ? this._scrollBar.skin : null; + } + set hScrollBarSkin(value) { + this._removePreScrollBar(); + var scrollBar = new HScrollBar(); + scrollBar.name = "scrollBar"; + scrollBar.bottom = 0; + scrollBar.skin = value; + scrollBar.elasticDistance = this._elasticEnabled ? 200 : 0; + this.scrollBar = scrollBar; + this.addChild(scrollBar); + this._setCellChanged(); + } + get scrollBar() { + return this._scrollBar; + } + set scrollBar(value) { + if (this._scrollBar != value) { + this._scrollBar = value; + if (value) { + this._isVertical = this._scrollBar.isVertical; + this.addChild(this._scrollBar); + this._scrollBar.on(Laya.Event.CHANGE, this, this.onScrollBarChange); + } + } + } + get itemRender() { + return this._itemRender; + } + set itemRender(value) { + if (this._itemRender != value) { + this._itemRender = value; + for (var i = this._cells.length - 1; i > -1; i--) { + this._cells[i].destroy(); + } + this._cells.length = 0; + this._setCellChanged(); + } + } + set width(value) { + if (value != this._width) { + super.width = value; + this._setCellChanged(); + } + } + get width() { + return super.width; + } + set height(value) { + if (value != this._height) { + super.height = value; + this._setCellChanged(); + } + } + get height() { + return super.height; + } + get repeatX() { + return this._repeatX > 0 ? this._repeatX : this._repeatX2 > 0 ? this._repeatX2 : 1; + } + set repeatX(value) { + this._repeatX = value; + this._setCellChanged(); + } + get repeatY() { + return this._repeatY > 0 ? this._repeatY : this._repeatY2 > 0 ? this._repeatY2 : 1; + } + set repeatY(value) { + this._repeatY = value; + this._setCellChanged(); + } + get spaceX() { + return this._spaceX; + } + set spaceX(value) { + this._spaceX = value; + this._setCellChanged(); + } + get spaceY() { + return this._spaceY; + } + set spaceY(value) { + this._spaceY = value; + this._setCellChanged(); + } + changeCells() { + this._cellChanged = false; + if (this._itemRender) { + this.scrollBar = this.getChildByName("scrollBar"); + var cell = this._getOneCell(); + var cellWidth = (cell.width + this._spaceX) || 1; + var cellHeight = (cell.height + this._spaceY) || 1; + if (this._width > 0) + this._repeatX2 = this._isVertical ? Math.round(this._width / cellWidth) : Math.ceil(this._width / cellWidth); + if (this._height > 0) + this._repeatY2 = this._isVertical ? Math.ceil(this._height / cellHeight) : Math.round(this._height / cellHeight); + var listWidth = this._width ? this._width : (cellWidth * this.repeatX - this._spaceX); + var listHeight = this._height ? this._height : (cellHeight * this.repeatY - this._spaceY); + this._cellSize = this._isVertical ? cellHeight : cellWidth; + this._cellOffset = this._isVertical ? (cellHeight * Math.max(this._repeatY2, this._repeatY) - listHeight - this._spaceY) : (cellWidth * Math.max(this._repeatX2, this._repeatX) - listWidth - this._spaceX); + if (this._isVertical && this.vScrollBarSkin) + this._scrollBar.height = listHeight; + else if (!this._isVertical && this.hScrollBarSkin) + this._scrollBar.width = listWidth; + this.setContentSize(listWidth, listHeight); + var numX = this._isVertical ? this.repeatX : this.repeatY; + var numY = (this._isVertical ? this.repeatY : this.repeatX) + (this._scrollBar ? 1 : 0); + this._createItems(0, numX, numY); + this._createdLine = numY; + if (this._array) { + this.array = this._array; + this.runCallLater(this.renderItems); + } + } + } + _getOneCell() { + if (this._cells.length === 0) { + var item = this.createItem(); + this._offset.setTo(item._x, item._y); + if (this.cacheContent) + return item; + this._cells.push(item); + } + return this._cells[0]; + } + _createItems(startY, numX, numY) { + var box = this._content; + var cell = this._getOneCell(); + var cellWidth = cell.width + this._spaceX; + var cellHeight = cell.height + this._spaceY; + if (this.cacheContent) { + var cacheBox = new Box(); + cacheBox.cacheAs = "normal"; + cacheBox.pos((this._isVertical ? 0 : startY) * cellWidth, (this._isVertical ? startY : 0) * cellHeight); + this._content.addChild(cacheBox); + box = cacheBox; + } + else { + var arr = []; + for (var i = this._cells.length - 1; i > -1; i--) { + var item = this._cells[i]; + item.removeSelf(); + arr.push(item); + } + this._cells.length = 0; + } + for (var k = startY; k < numY; k++) { + for (var l = 0; l < numX; l++) { + if (arr && arr.length) { + cell = arr.pop(); + } + else { + cell = this.createItem(); + } + cell.x = (this._isVertical ? l : k) * cellWidth - box._x; + cell.y = (this._isVertical ? k : l) * cellHeight - box._y; + cell.name = "item" + (k * numX + l); + box.addChild(cell); + this.addCell(cell); + } + } + } + createItem() { + var arr = []; + if (typeof (this._itemRender) == "function") { + var box = new this._itemRender(); + } + else { + box = Laya.SceneUtils.createComp(this._itemRender, null, null, arr); + } + if (arr.length == 0 && box["_watchMap"]) { + var watchMap = box["_watchMap"]; + for (var name in watchMap) { + var a = watchMap[name]; + for (var i = 0; i < a.length; i++) { + var watcher = a[i]; + arr.push(watcher.comp, watcher.prop, watcher.value); + } + } + } + if (arr.length) + box["_$bindData"] = arr; + return box; + } + addCell(cell) { + cell.on(Laya.Event.CLICK, this, this.onCellMouse); + cell.on(Laya.Event.RIGHT_CLICK, this, this.onCellMouse); + cell.on(Laya.Event.MOUSE_OVER, this, this.onCellMouse); + cell.on(Laya.Event.MOUSE_OUT, this, this.onCellMouse); + cell.on(Laya.Event.MOUSE_DOWN, this, this.onCellMouse); + cell.on(Laya.Event.MOUSE_UP, this, this.onCellMouse); + this._cells.push(cell); + } + _afterInited() { + this.initItems(); + } + initItems() { + if (!this._itemRender && this.getChildByName("item0") != null) { + this.repeatX = 1; + var count; + count = 0; + for (var i = 0; i < 10000; i++) { + var cell = this.getChildByName("item" + i); + if (cell) { + this.addCell(cell); + count++; + continue; + } + break; + } + this.repeatY = count; + } + } + setContentSize(width, height) { + this._content.width = width; + this._content.height = height; + if (this._scrollBar || this._offset.x != 0 || this._offset.y != 0) { + this._content._style.scrollRect || (this._content.scrollRect = Laya.Rectangle.create()); + this._content._style.scrollRect.setTo(-this._offset.x, -this._offset.y, width, height); + this._content.scrollRect = this._content.scrollRect; + } + this.event(Laya.Event.RESIZE); + } + onCellMouse(e) { + if (e.type === Laya.Event.MOUSE_DOWN) + this._isMoved = false; + var cell = e.currentTarget; + var index = this._startIndex + this._cells.indexOf(cell); + if (index < 0) + return; + if (e.type === Laya.Event.CLICK || e.type === Laya.Event.RIGHT_CLICK) { + if (this.selectEnable && !this._isMoved) + this.selectedIndex = index; + else + this.changeCellState(cell, true, 0); + } + else if ((e.type === Laya.Event.MOUSE_OVER || e.type === Laya.Event.MOUSE_OUT) && this._selectedIndex !== index) { + this.changeCellState(cell, e.type === Laya.Event.MOUSE_OVER, 0); + } + this.mouseHandler && this.mouseHandler.runWith([e, index]); + } + changeCellState(cell, visible, index) { + var selectBox = cell.getChildByName("selectBox"); + if (selectBox) { + this.selectEnable = true; + selectBox.visible = visible; + selectBox.index = index; + } + } + _sizeChanged() { + super._sizeChanged(); + this.setContentSize(this.width, this.height); + if (this._scrollBar) + this.callLater(this.onScrollBarChange); + } + onScrollBarChange(e = null) { + this.runCallLater(this.changeCells); + var scrollValue = this._scrollBar.value; + var lineX = (this._isVertical ? this.repeatX : this.repeatY); + var lineY = (this._isVertical ? this.repeatY : this.repeatX); + var scrollLine = Math.floor(scrollValue / this._cellSize); + if (!this.cacheContent) { + var index = scrollLine * lineX; + var num = 0; + let down = true; + var toIndex = 0; + if (index > this._startIndex) { + num = index - this._startIndex; + toIndex = this._startIndex + lineX * (lineY + 1); + this._isMoved = true; + } + else if (index < this._startIndex) { + num = this._startIndex - index; + down = false; + toIndex = this._startIndex - 1; + this._isMoved = true; + } + for (var i = 0; i < num; i++) { + if (down) { + var cell = this._cells.shift(); + this._cells[this._cells.length] = cell; + var cellIndex = toIndex + i; + } + else { + cell = this._cells.pop(); + this._cells.unshift(cell); + cellIndex = toIndex - i; + } + var pos = Math.floor(cellIndex / lineX) * this._cellSize; + this._isVertical ? cell.y = pos : cell.x = pos; + this.renderItem(cell, cellIndex); + } + this._startIndex = index; + this.changeSelectStatus(); + } + else { + num = (lineY + 1); + if (this._createdLine - scrollLine < num) { + this._createItems(this._createdLine, lineX, this._createdLine + num); + this.renderItems(this._createdLine * lineX, 0); + this._createdLine += num; + } + } + var r = this._content._style.scrollRect; + if (this._isVertical) { + r.y = scrollValue - this._offset.y; + r.x = -this._offset.x; + } + else { + r.y = -this._offset.y; + r.x = scrollValue - this._offset.x; + } + this._content.scrollRect = r; + } + posCell(cell, cellIndex) { + if (!this._scrollBar) + return; + var lineX = (this._isVertical ? this.repeatX : this.repeatY); + var pos = Math.floor(cellIndex / lineX) * this._cellSize; + this._isVertical ? cell._y = pos : cell.x = pos; + } + get selectedIndex() { + return this._selectedIndex; + } + set selectedIndex(value) { + if (this._selectedIndex != value) { + this._selectedIndex = value; + this.changeSelectStatus(); + this.event(Laya.Event.CHANGE); + this.selectHandler && this.selectHandler.runWith(value); + this.startIndex = this._startIndex; + } + } + changeSelectStatus() { + for (var i = 0, n = this._cells.length; i < n; i++) { + this.changeCellState(this._cells[i], this._selectedIndex === this._startIndex + i, 1); + } + } + get selectedItem() { + if (!this._array) + return null; + return this._selectedIndex != -1 ? this._array[this._selectedIndex] : null; + } + set selectedItem(value) { + this._array && (this.selectedIndex = this._array.indexOf(value)); + } + get selection() { + return this.getCell(this._selectedIndex); + } + set selection(value) { + this.selectedIndex = this._startIndex + this._cells.indexOf(value); + } + get startIndex() { + return this._startIndex; + } + set startIndex(value) { + this._startIndex = value > 0 ? value : 0; + this.callLater(this.renderItems); + } + renderItems(from = 0, to = 0) { + for (var i = from, n = to || this._cells.length; i < n; i++) { + this.renderItem(this._cells[i], this._startIndex + i); + } + this.changeSelectStatus(); + } + renderItem(cell, index) { + if (this._array && index >= 0 && index < this._array.length) { + cell.visible = true; + if (cell["_$bindData"]) { + cell["_dataSource"] = this._array[index]; + this._bindData(cell, this._array[index]); + } + else + cell.dataSource = this._array[index]; + if (!this.cacheContent) { + this.posCell(cell, index); + } + if (this.hasListener(Laya.Event.RENDER)) + this.event(Laya.Event.RENDER, [cell, index]); + if (this.renderHandler) + this.renderHandler.runWith([cell, index]); + } + else { + cell.visible = false; + cell.dataSource = null; + } + } + _bindData(cell, data) { + var arr = cell._$bindData; + for (var i = 0, n = arr.length; i < n; i++) { + var ele = arr[i++]; + var prop = arr[i++]; + var value = arr[i]; + var fun = UIUtils.getBindFun(value); + ele[prop] = fun.call(this, data); + } + } + get array() { + return this._array; + } + set array(value) { + this.runCallLater(this.changeCells); + this._array = value || []; + this._preLen = this._array.length; + var length = this._array.length; + this.totalPage = Math.ceil(length / (this.repeatX * this.repeatY)); + this._selectedIndex = this._selectedIndex < length ? this._selectedIndex : length - 1; + this.startIndex = this._startIndex; + if (this._scrollBar) { + this._scrollBar.stopScroll(); + var numX = this._isVertical ? this.repeatX : this.repeatY; + var numY = this._isVertical ? this.repeatY : this.repeatX; + var lineCount = Math.ceil(length / numX); + var total = this._cellOffset > 0 ? this.totalPage + 1 : this.totalPage; + if (total > 1 && lineCount >= numY) { + this._scrollBar.scrollSize = this._cellSize; + this._scrollBar.thumbPercent = numY / lineCount; + this._scrollBar.setScroll(0, (lineCount - numY) * this._cellSize + this._cellOffset, this._scrollBar.value); + this._scrollBar.target = this._content; + } + else { + this._scrollBar.setScroll(0, 0, 0); + this._scrollBar.target = this._content; + } + } + } + updateArray(array) { + this._array = array; + if (this._array) { + let freshStart = this._preLen - this._startIndex; + if (freshStart >= 0) + this.renderItems(freshStart); + this._preLen = this._array.length; + } + if (this._scrollBar) { + var length = array.length; + var numX = this._isVertical ? this.repeatX : this.repeatY; + var numY = this._isVertical ? this.repeatY : this.repeatX; + var lineCount = Math.ceil(length / numX); + if (lineCount >= numY) { + this._scrollBar.thumbPercent = numY / lineCount; + this._scrollBar.slider["_max"] = (lineCount - numY) * this._cellSize + this._cellOffset; + } + } + } + get page() { + return this._page; + } + set page(value) { + this._page = value; + if (this._array) { + this._page = value > 0 ? value : 0; + this._page = this._page < this.totalPage ? this._page : this.totalPage - 1; + this.startIndex = this._page * this.repeatX * this.repeatY; + } + } + get length() { + return this._array ? this._array.length : 0; + } + set dataSource(value) { + this._dataSource = value; + if (typeof (value) == 'number' || typeof (value) == 'string') + this.selectedIndex = parseInt(value); + else if (value instanceof Array) + this.array = value; + else + super.dataSource = value; + } + get dataSource() { + return super.dataSource; + } + get cells() { + this.runCallLater(this.changeCells); + return this._cells; + } + get elasticEnabled() { + return this._elasticEnabled; + } + set elasticEnabled(value) { + this._elasticEnabled = value; + if (this._scrollBar) { + this._scrollBar.elasticDistance = value ? 200 : 0; + } + } + refresh() { + this.array = this._array; + } + getItem(index) { + if (!this._array) + return null; + if (index > -1 && index < this._array.length) { + return this._array[index]; + } + return null; + } + changeItem(index, source) { + if (index > -1 && this._array && index < this._array.length) { + this._array[index] = source; + if (index >= this._startIndex && index < this._startIndex + this._cells.length) { + this.renderItem(this.getCell(index), index); + } + } + } + setItem(index, source) { + this.changeItem(index, source); + } + addItem(source) { + if (!this.array) { + this.array = [source]; + } + else { + this._array.push(source); + } + this.array = this._array; + } + addItemAt(souce, index) { + this._array.splice(index, 0, souce); + this.array = this._array; + } + deleteItem(index) { + if (this._array) { + this._array.splice(index, 1); + this.array = this._array; + } + } + getCell(index) { + this.runCallLater(this.changeCells); + if (index > -1 && this._cells) { + return this._cells[(index - this._startIndex) % this._cells.length]; + } + return null; + } + scrollTo(index) { + if (this._scrollBar) { + var numX = this._isVertical ? this.repeatX : this.repeatY; + this._scrollBar.value = Math.floor(index / numX) * this._cellSize; + } + else { + this.startIndex = index; + } + } + tweenTo(index, time = 200, complete = null) { + if (this._scrollBar) { + this._scrollBar.stopScroll(); + var numX = this._isVertical ? this.repeatX : this.repeatY; + Laya.Tween.to(this._scrollBar, { value: Math.floor(index / numX) * this._cellSize }, time, null, complete, 0, true); + } + else { + this.startIndex = index; + if (complete) + complete.run(); + } + } + _setCellChanged() { + if (!this._cellChanged) { + this._cellChanged = true; + this.callLater(this.changeCells); + } + } + commitMeasure() { + this.runCallLater(this.changeCells); + } + } + Laya.ILaya.regClass(List); + Laya.ClassUtils.regClass("laya.ui.List", List); + Laya.ClassUtils.regClass("Laya.List", List); + + class ComboBox extends UIComponent { + constructor(skin = null, labels = null) { + super(); + this._visibleNum = 6; + this._itemColors = Styles.comboBoxItemColors; + this._itemSize = 12; + this._labels = []; + this._selectedIndex = -1; + this.itemRender = null; + this.skin = skin; + this.labels = labels; + } + destroy(destroyChild = true) { + Laya.ILaya.stage.off(Laya.Event.MOUSE_DOWN, this, this.removeList); + Laya.ILaya.stage.off(Laya.Event.MOUSE_WHEEL, this, this._onStageMouseWheel); + super.destroy(destroyChild); + this._button && this._button.destroy(destroyChild); + this._list && this._list.destroy(destroyChild); + this._button = null; + this._list = null; + this._itemColors = null; + this._labels = null; + this._selectHandler = null; + } + createChildren() { + this.addChild(this._button = new Button()); + this._button.text.align = "left"; + this._button.labelPadding = "0,0,0,5"; + this._button.on(Laya.Event.MOUSE_DOWN, this, this.onButtonMouseDown); + } + _createList() { + this._list = new List(); + if (this._scrollBarSkin) + this._list.vScrollBarSkin = this._scrollBarSkin; + this._setListEvent(this._list); + } + _setListEvent(list) { + this._list.selectEnable = true; + this._list.on(Laya.Event.MOUSE_DOWN, this, this.onListDown); + this._list.mouseHandler = Laya.Handler.create(this, this.onlistItemMouse, null, false); + if (this._list.scrollBar) + this._list.scrollBar.on(Laya.Event.MOUSE_DOWN, this, this.onScrollBarDown); + } + onListDown(e) { + e.stopPropagation(); + } + onScrollBarDown(e) { + e.stopPropagation(); + } + onButtonMouseDown(e) { + this.callLater(this.switchTo, [!this._isOpen]); + } + get skin() { + return this._button.skin; + } + set skin(value) { + if (this._button.skin != value) { + this._button.skin = value; + this._listChanged = true; + } + } + measureWidth() { + return this._button.width; + } + measureHeight() { + return this._button.height; + } + changeList() { + this._listChanged = false; + var labelWidth = this.width - 2; + var labelColor = this._itemColors[2]; + this._itemHeight = this._itemSize + 6; + this._list.itemRender = this.itemRender || { type: "Box", child: [{ type: "Label", props: { name: "label", x: 1, padding: "3,3,3,3", width: labelWidth, height: this._itemHeight, fontSize: this._itemSize, color: labelColor } }] }; + this._list.repeatY = this._visibleNum; + this._list.refresh(); + } + onlistItemMouse(e, index) { + var type = e.type; + if (type === Laya.Event.MOUSE_OVER || type === Laya.Event.MOUSE_OUT) { + if (this._isCustomList) + return; + var box = this._list.getCell(index); + if (!box) + return; + var label = box.getChildByName("label"); + if (label) { + if (type === Laya.Event.ROLL_OVER) { + label.bgColor = this._itemColors[0]; + label.color = this._itemColors[1]; + } + else { + label.bgColor = null; + label.color = this._itemColors[2]; + } + } + } + else if (type === Laya.Event.CLICK) { + this.selectedIndex = index; + this.isOpen = false; + } + } + switchTo(value) { + this.isOpen = value; + } + changeOpen() { + this.isOpen = !this._isOpen; + } + set width(value) { + super.width = value; + this._button.width = this._width; + this._itemChanged = true; + this._listChanged = true; + } + get width() { + return super.width; + } + set height(value) { + super.height = value; + this._button.height = this._height; + } + get height() { + return super.height; + } + get labels() { + return this._labels.join(","); + } + set labels(value) { + if (this._labels.length > 0) + this.selectedIndex = -1; + if (value) + this._labels = value.split(","); + else + this._labels.length = 0; + this._itemChanged = true; + } + changeItem() { + this._itemChanged = false; + this._listHeight = this._labels.length > 0 ? Math.min(this._visibleNum, this._labels.length) * this._itemHeight : this._itemHeight; + if (!this._isCustomList) { + var g = this._list.graphics; + g.clear(true); + g.drawRect(0, 0, this.width - 1, this._listHeight, this._itemColors[4], this._itemColors[3]); + } + var a = this._list.array || []; + a.length = 0; + for (var i = 0, n = this._labels.length; i < n; i++) { + a.push({ label: this._labels[i] }); + } + this._list.height = this._listHeight; + this._list.array = a; + } + get selectedIndex() { + return this._selectedIndex; + } + set selectedIndex(value) { + if (this._selectedIndex != value) { + this._selectedIndex = value; + if (this._labels.length > 0) + this.changeSelected(); + else + this.callLater(this.changeSelected); + this.event(Laya.Event.CHANGE, [Laya.Event.EMPTY.setTo(Laya.Event.CHANGE, this, this)]); + this._selectHandler && this._selectHandler.runWith(this._selectedIndex); + } + } + changeSelected() { + this._button.label = this.selectedLabel; + } + get selectHandler() { + return this._selectHandler; + } + set selectHandler(value) { + this._selectHandler = value; + } + get selectedLabel() { + return this._selectedIndex > -1 && this._selectedIndex < this._labels.length ? this._labels[this._selectedIndex] : null; + } + set selectedLabel(value) { + this.selectedIndex = this._labels.indexOf(value); + } + get visibleNum() { + return this._visibleNum; + } + set visibleNum(value) { + this._visibleNum = value; + this._listChanged = true; + } + get itemColors() { + return String(this._itemColors); + } + set itemColors(value) { + this._itemColors = UIUtils.fillArray(this._itemColors, value, String); + this._listChanged = true; + } + get itemSize() { + return this._itemSize; + } + set itemSize(value) { + this._itemSize = value; + this._listChanged = true; + } + get isOpen() { + return this._isOpen; + } + set isOpen(value) { + if (this._isOpen != value) { + this._isOpen = value; + this._button.selected = this._isOpen; + if (this._isOpen) { + this._list || this._createList(); + this._listChanged && !this._isCustomList && this.changeList(); + this._itemChanged && this.changeItem(); + var p = this.localToGlobal(Laya.Point.TEMP.setTo(0, 0)); + var py = p.y + this._button.height; + py = py + this._listHeight <= Laya.ILaya.stage.height ? py : p.y - this._listHeight; + this._list.pos(p.x, py); + this._list.zOrder = 1001; + Laya.ILaya.stage.addChild(this._list); + Laya.ILaya.stage.once(Laya.Event.MOUSE_DOWN, this, this.removeList); + Laya.ILaya.stage.on(Laya.Event.MOUSE_WHEEL, this, this._onStageMouseWheel); + this._list.selectedIndex = this._selectedIndex; + } + else { + this._list && this._list.removeSelf(); + } + } + } + _onStageMouseWheel(e) { + if (!this._list || this._list.contains(e.target)) + return; + this.removeList(null); + } + removeList(e) { + Laya.ILaya.stage.off(Laya.Event.MOUSE_DOWN, this, this.removeList); + Laya.ILaya.stage.off(Laya.Event.MOUSE_WHEEL, this, this._onStageMouseWheel); + this.isOpen = false; + } + get scrollBarSkin() { + return this._scrollBarSkin; + } + set scrollBarSkin(value) { + this._scrollBarSkin = value; + } + get sizeGrid() { + return this._button.sizeGrid; + } + set sizeGrid(value) { + this._button.sizeGrid = value; + } + get scrollBar() { + return this.list.scrollBar; + } + get button() { + return this._button; + } + get list() { + this._list || this._createList(); + return this._list; + } + set list(value) { + if (value) { + value.removeSelf(); + this._isCustomList = true; + this._list = value; + this._setListEvent(value); + this._itemHeight = value.getCell(0).height + value.spaceY; + } + } + set dataSource(value) { + this._dataSource = value; + if (typeof (value) == 'number' || typeof (value) == 'string') + this.selectedIndex = parseInt(value); + else if (value instanceof Array) + this.labels = value.join(","); + else + super.dataSource = value; + } + get dataSource() { + return super.dataSource; + } + get labelColors() { + return this._button.labelColors; + } + set labelColors(value) { + if (this._button.labelColors != value) { + this._button.labelColors = value; + } + } + get labelPadding() { + return this._button.text.padding.join(","); + } + set labelPadding(value) { + this._button.text.padding = UIUtils.fillArray(Styles.labelPadding, value, Number); + } + get labelSize() { + return this._button.text.fontSize; + } + set labelSize(value) { + this._button.text.fontSize = value; + } + get labelBold() { + return this._button.text.bold; + } + set labelBold(value) { + this._button.text.bold = value; + } + get labelFont() { + return this._button.text.font; + } + set labelFont(value) { + this._button.text.font = value; + } + get stateNum() { + return this._button.stateNum; + } + set stateNum(value) { + this._button.stateNum = value; + } + } + Laya.ILaya.regClass(ComboBox); + Laya.ClassUtils.regClass("laya.ui.ComboBox", ComboBox); + Laya.ClassUtils.regClass("Laya.ComboBox", ComboBox); + + class ProgressBar extends UIComponent { + constructor(skin = null) { + super(); + this._value = 0.5; + this.skin = skin; + } + destroy(destroyChild = true) { + super.destroy(destroyChild); + this._bg && this._bg.destroy(destroyChild); + this._bar && this._bar.destroy(destroyChild); + this._bg = this._bar = null; + this.changeHandler = null; + } + createChildren() { + this.addChild(this._bg = new Image()); + this.addChild(this._bar = new Image()); + this._bar._bitmap.autoCacheCmd = false; + } + get skin() { + return this._skin; + } + set skin(value) { + if (this._skin != value) { + this._skin = value; + if (this._skin && !Laya.Loader.getRes(this._skin)) { + Laya.ILaya.loader.load(this._skin, Laya.Handler.create(this, this._skinLoaded), null, Laya.Loader.IMAGE, 1); + } + else { + this._skinLoaded(); + } + } + } + _skinLoaded() { + if (this.destroyed) { + return; + } + this._bg.skin = this._skin; + this._bar.skin = this._skin.replace(".png", "$bar.png"); + this.callLater(this.changeValue); + this._sizeChanged(); + this.event(Laya.Event.LOADED); + } + measureWidth() { + return this._bg.width; + } + measureHeight() { + return this._bg.height; + } + get value() { + return this._value; + } + set value(num) { + if (this._value != num) { + num = num > 1 ? 1 : num < 0 ? 0 : num; + this._value = num; + this.callLater(this.changeValue); + this.event(Laya.Event.CHANGE); + this.changeHandler && this.changeHandler.runWith(num); + } + } + changeValue() { + if (this.sizeGrid) { + var grid = this.sizeGrid.split(","); + var left = Number(grid[3]); + var right = Number(grid[1]); + var max = this.width - left - right; + var sw = max * this._value; + this._bar.width = left + right + sw; + this._bar.visible = this._bar.width > left + right; + } + else { + this._bar.width = this.width * this._value; + } + } + get bar() { + return this._bar; + } + get bg() { + return this._bg; + } + get sizeGrid() { + return this._bg.sizeGrid; + } + set sizeGrid(value) { + this._bg.sizeGrid = this._bar.sizeGrid = value; + } + set width(value) { + super.width = value; + this._bg.width = this._width; + this.callLater(this.changeValue); + } + get width() { + return super.width; + } + set height(value) { + super.height = value; + this._bg.height = this._height; + this._bar.height = this._height; + } + get height() { + return super.height; + } + set dataSource(value) { + this._dataSource = value; + if (typeof (value) == 'number' || typeof (value) == 'string') + this.value = Number(value); + else + super.dataSource = value; + } + get dataSource() { + return super.dataSource; + } + } + Laya.ILaya.regClass(ProgressBar); + Laya.ClassUtils.regClass("laya.ui.ProgressBar", ProgressBar); + Laya.ClassUtils.regClass("Laya.ProgressBar", ProgressBar); + + class Radio extends Button { + constructor(skin = null, label = "") { + super(skin, label); + this.toggle = false; + this._autoSize = false; + } + destroy(destroyChild = true) { + super.destroy(destroyChild); + this._value = null; + } + preinitialize() { + super.preinitialize(); + this.toggle = false; + this._autoSize = false; + } + initialize() { + super.initialize(); + this.createText(); + this._text.align = "left"; + this._text.valign = "top"; + this._text.width = 0; + this.on(Laya.Event.CLICK, this, this.onClick); + } + onClick(e) { + this.selected = true; + } + get value() { + return this._value != null ? this._value : this.label; + } + set value(obj) { + this._value = obj; + } + } + Laya.ILaya.regClass(Radio); + Laya.ClassUtils.regClass("laya.ui.Radio", Radio); + Laya.ClassUtils.regClass("Laya.Radio", Radio); + + class UIGroup extends Box { + constructor(labels = null, skin = null) { + super(); + this._selectedIndex = -1; + this._direction = "horizontal"; + this._space = 0; + this.skin = skin; + this.labels = labels; + } + preinitialize() { + this.mouseEnabled = true; + } + destroy(destroyChild = true) { + super.destroy(destroyChild); + this._items && (this._items.length = 0); + this._items = null; + this.selectHandler = null; + } + addItem(item, autoLayOut = true) { + var display = item; + var index = this._items.length; + display.name = "item" + index; + this.addChild(display); + this.initItems(); + if (autoLayOut && index > 0) { + var preItem = this._items[index - 1]; + if (this._direction == "horizontal") { + display.x = preItem._x + preItem.width + this._space; + } + else { + display.y = preItem._y + preItem.height + this._space; + } + } + else { + if (autoLayOut) { + display.x = 0; + display.y = 0; + } + } + return index; + } + delItem(item, autoLayOut = true) { + var index = this._items.indexOf(item); + if (index != -1) { + var display = item; + this.removeChild(display); + for (var i = index + 1, n = this._items.length; i < n; i++) { + var child = this._items[i]; + child.name = "item" + (i - 1); + if (autoLayOut) { + if (this._direction == "horizontal") { + child.x -= display.width + this._space; + } + else { + child.y -= display.height + this._space; + } + } + } + this.initItems(); + if (this._selectedIndex > -1) { + var newIndex; + newIndex = this._selectedIndex < this._items.length ? this._selectedIndex : (this._selectedIndex - 1); + this._selectedIndex = -1; + this.selectedIndex = newIndex; + } + } + } + _afterInited() { + this.initItems(); + } + initItems() { + this._items || (this._items = []); + this._items.length = 0; + for (var i = 0; i < 10000; i++) { + var item = this.getChildByName("item" + i); + if (item == null) + break; + this._items.push(item); + item.selected = (i === this._selectedIndex); + item.clickHandler = Laya.Handler.create(this, this.itemClick, [i], false); + } + } + itemClick(index) { + this.selectedIndex = index; + } + get selectedIndex() { + return this._selectedIndex; + } + set selectedIndex(value) { + if (this._selectedIndex != value) { + this.setSelect(this._selectedIndex, false); + this._selectedIndex = value; + this.setSelect(value, true); + this.event(Laya.Event.CHANGE); + this.selectHandler && this.selectHandler.runWith(this._selectedIndex); + } + } + setSelect(index, selected) { + if (this._items && index > -1 && index < this._items.length) + this._items[index].selected = selected; + } + get skin() { + return this._skin; + } + set skin(value) { + if (this._skin != value) { + this._skin = value; + if (this._skin && !Laya.Loader.getRes(this._skin)) { + Laya.ILaya.loader.load(this._skin, Laya.Handler.create(this, this._skinLoaded), null, Laya.Loader.IMAGE, 1); + } + else { + this._skinLoaded(); + } + } + } + _skinLoaded() { + this._setLabelChanged(); + this.event(Laya.Event.LOADED); + } + get labels() { + return this._labels; + } + set labels(value) { + if (this._labels != value) { + this._labels = value; + this.removeChildren(); + this._setLabelChanged(); + if (this._labels) { + var a = this._labels.split(","); + for (var i = 0, n = a.length; i < n; i++) { + var item = this.createItem(this._skin, a[i]); + item.name = "item" + i; + this.addChild(item); + } + } + this.initItems(); + } + } + createItem(skin, label) { + return null; + } + get labelColors() { + return this._labelColors; + } + set labelColors(value) { + if (this._labelColors != value) { + this._labelColors = value; + this._setLabelChanged(); + } + } + get labelStroke() { + return this._labelStroke; + } + set labelStroke(value) { + if (this._labelStroke != value) { + this._labelStroke = value; + this._setLabelChanged(); + } + } + get labelStrokeColor() { + return this._labelStrokeColor; + } + set labelStrokeColor(value) { + if (this._labelStrokeColor != value) { + this._labelStrokeColor = value; + this._setLabelChanged(); + } + } + get strokeColors() { + return this._strokeColors; + } + set strokeColors(value) { + if (this._strokeColors != value) { + this._strokeColors = value; + this._setLabelChanged(); + } + } + get labelSize() { + return this._labelSize; + } + set labelSize(value) { + if (this._labelSize != value) { + this._labelSize = value; + this._setLabelChanged(); + } + } + get stateNum() { + return this._stateNum; + } + set stateNum(value) { + if (this._stateNum != value) { + this._stateNum = value; + this._setLabelChanged(); + } + } + get labelBold() { + return this._labelBold; + } + set labelBold(value) { + if (this._labelBold != value) { + this._labelBold = value; + this._setLabelChanged(); + } + } + get labelFont() { + return this._labelFont; + } + set labelFont(value) { + if (this._labelFont != value) { + this._labelFont = value; + this._setLabelChanged(); + } + } + get labelPadding() { + return this._labelPadding; + } + set labelPadding(value) { + if (this._labelPadding != value) { + this._labelPadding = value; + this._setLabelChanged(); + } + } + get direction() { + return this._direction; + } + set direction(value) { + this._direction = value; + this._setLabelChanged(); + } + get space() { + return this._space; + } + set space(value) { + this._space = value; + this._setLabelChanged(); + } + changeLabels() { + this._labelChanged = false; + if (this._items) { + var left = 0; + for (var i = 0, n = this._items.length; i < n; i++) { + var btn = this._items[i]; + this._skin && (btn.skin = this._skin); + this._labelColors && (btn.labelColors = this._labelColors); + this._labelSize && (btn.labelSize = this._labelSize); + this._labelStroke && (btn.labelStroke = this._labelStroke); + this._labelStrokeColor && (btn.labelStrokeColor = this._labelStrokeColor); + this._strokeColors && (btn.strokeColors = this._strokeColors); + this._labelBold && (btn.labelBold = this._labelBold); + this._labelPadding && (btn.labelPadding = this._labelPadding); + this._labelAlign && (btn.labelAlign = this._labelAlign); + this._stateNum && (btn.stateNum = this._stateNum); + this._labelFont && (btn.labelFont = this._labelFont); + if (this._direction === "horizontal") { + btn.y = 0; + btn.x = left; + left += btn.width + this._space; + } + else { + btn.x = 0; + btn.y = left; + left += btn.height + this._space; + } + } + } + this._sizeChanged(); + } + commitMeasure() { + this.runCallLater(this.changeLabels); + } + get items() { + return this._items; + } + get selection() { + return this._selectedIndex > -1 && this._selectedIndex < this._items.length ? this._items[this._selectedIndex] : null; + } + set selection(value) { + this.selectedIndex = this._items.indexOf(value); + } + set dataSource(value) { + this._dataSource = value; + if (typeof (value) == 'number' || typeof (value) == 'string') + this.selectedIndex = parseInt(value); + else if (value instanceof Array) + this.labels = value.join(","); + else + super.dataSource = value; + } + get dataSource() { + return super.dataSource; + } + _setLabelChanged() { + if (!this._labelChanged) { + this._labelChanged = true; + this.callLater(this.changeLabels); + } + } + } + Laya.ILaya.regClass(UIGroup); + Laya.ClassUtils.regClass("laya.ui.UIGroup", UIGroup); + Laya.ClassUtils.regClass("Laya.UIGroup", UIGroup); + + class RadioGroup extends UIGroup { + createItem(skin, label) { + return new Radio(skin, label); + } + } + Laya.ILaya.regClass(RadioGroup); + Laya.ClassUtils.regClass("laya.ui.RadioGroup", RadioGroup); + Laya.ClassUtils.regClass("Laya.RadioGroup", RadioGroup); + + class Tab extends UIGroup { + createItem(skin, label) { + return new Button(skin, label); + } + } + Laya.ILaya.regClass(Tab); + Laya.ClassUtils.regClass("laya.ui.Tab", Tab); + Laya.ClassUtils.regClass("Laya.Tab", Tab); + + class ViewStack extends Box { + constructor() { + super(...arguments); + this._setIndexHandler = Laya.Handler.create(this, this.setIndex, null, false); + } + setItems(views) { + this.removeChildren(); + var index = 0; + for (var i = 0, n = views.length; i < n; i++) { + var item = views[i]; + if (item) { + item.name = "item" + index; + this.addChild(item); + index++; + } + } + this.initItems(); + } + addItem(view) { + view.name = "item" + this._items.length; + this.addChild(view); + this.initItems(); + } + _afterInited() { + this.initItems(); + } + initItems() { + this._items = []; + for (var i = 0; i < 10000; i++) { + var item = this.getChildByName("item" + i); + if (item == null) { + break; + } + this._items.push(item); + item.visible = (i == this._selectedIndex); + } + } + get selectedIndex() { + return this._selectedIndex; + } + set selectedIndex(value) { + if (this._selectedIndex != value) { + this.setSelect(this._selectedIndex, false); + this._selectedIndex = value; + this.setSelect(this._selectedIndex, true); + } + } + setSelect(index, selected) { + if (this._items && index > -1 && index < this._items.length) { + this._items[index].visible = selected; + } + } + get selection() { + return this._selectedIndex > -1 && this._selectedIndex < this._items.length ? this._items[this._selectedIndex] : null; + } + set selection(value) { + this.selectedIndex = this._items.indexOf(value); + } + get setIndexHandler() { + return this._setIndexHandler; + } + set setIndexHandler(value) { + this._setIndexHandler = value; + } + setIndex(index) { + this.selectedIndex = index; + } + get items() { + return this._items; + } + set dataSource(value) { + this._dataSource = value; + if (typeof (value) == 'number' || typeof (value) == 'string') { + this.selectedIndex = parseInt(value); + } + else { + for (var prop in this._dataSource) { + if (prop in this) { + this[prop] = this._dataSource[prop]; + } + } + } + } + get dataSource() { + return super.dataSource; + } + } + Laya.ILaya.regClass(ViewStack); + Laya.ClassUtils.regClass("laya.ui.ViewStack", ViewStack); + Laya.ClassUtils.regClass("Laya.ViewStack", ViewStack); + + class TextInput extends Label { + constructor(text = "") { + super(); + this.text = text; + this.skin = this.skin; + } + preinitialize() { + this.mouseEnabled = true; + } + destroy(destroyChild = true) { + super.destroy(destroyChild); + this._bg && this._bg.destroy(); + this._bg = null; + } + createChildren() { + this.addChild(this._tf = new Laya.Input()); + this._tf.padding = Styles.inputLabelPadding; + this._tf.on(Laya.Event.INPUT, this, this._onInput); + this._tf.on(Laya.Event.ENTER, this, this._onEnter); + this._tf.on(Laya.Event.BLUR, this, this._onBlur); + this._tf.on(Laya.Event.FOCUS, this, this._onFocus); + } + _onFocus() { + this.event(Laya.Event.FOCUS, this); + } + _onBlur() { + this.event(Laya.Event.BLUR, this); + } + _onInput() { + this.event(Laya.Event.INPUT, this); + } + _onEnter() { + this.event(Laya.Event.ENTER, this); + } + initialize() { + this.width = 128; + this.height = 22; + } + get bg() { + return this._bg; + } + set bg(value) { + this.graphics = this._bg = value; + } + get skin() { + return this._skin; + } + set skin(value) { + if (this._skin != value) { + this._skin = value; + if (this._skin && !Laya.Loader.getRes(this._skin)) { + Laya.ILaya.loader.load(this._skin, Laya.Handler.create(this, this._skinLoaded), null, Laya.Loader.IMAGE, 1); + } + else { + this._skinLoaded(); + } + } + } + _skinLoaded() { + this._bg || (this.graphics = this._bg = new AutoBitmap()); + this._bg.source = Laya.Loader.getRes(this._skin); + this._width && (this._bg.width = this._width); + this._height && (this._bg.height = this._height); + this._sizeChanged(); + this.event(Laya.Event.LOADED); + } + get sizeGrid() { + return this._bg && this._bg.sizeGrid ? this._bg.sizeGrid.join(",") : null; + } + set sizeGrid(value) { + this._bg || (this.graphics = this._bg = new AutoBitmap()); + this._bg.sizeGrid = UIUtils.fillArray(Styles.defaultSizeGrid, value, Number); + } + set text(value) { + if (this._tf.text != value) { + value = value + ""; + this._tf.text = value; + this.event(Laya.Event.CHANGE); + } + } + get text() { + return super.text; + } + set width(value) { + super.width = value; + this._bg && (this._bg.width = value); + } + get width() { + return super.width; + } + set height(value) { + super.height = value; + this._bg && (this._bg.height = value); + } + get height() { + return super.height; + } + get multiline() { + return this._tf.multiline; + } + set multiline(value) { + this._tf.multiline = value; + } + set editable(value) { + this._tf.editable = value; + } + get editable() { + return this._tf.editable; + } + select() { + this._tf.select(); + } + get restrict() { + return this._tf.restrict; + } + set restrict(pattern) { + this._tf.restrict = pattern; + } + get prompt() { + return this._tf.prompt; + } + set prompt(value) { + this._tf.prompt = value; + } + get promptColor() { + return this._tf.promptColor; + } + set promptColor(value) { + this._tf.promptColor = value; + } + get maxChars() { + return this._tf.maxChars; + } + set maxChars(value) { + this._tf.maxChars = value; + } + get focus() { + return this._tf.focus; + } + set focus(value) { + this._tf.focus = value; + } + get type() { + return this._tf.type; + } + set type(value) { + this._tf.type = value; + } + setSelection(startIndex, endIndex) { + this._tf.setSelection(startIndex, endIndex); + } + } + Laya.ILaya.regClass(TextInput); + Laya.ClassUtils.regClass("laya.ui.TextInput", TextInput); + Laya.ClassUtils.regClass("Laya.TextInput", TextInput); + + class TextArea extends TextInput { + constructor(text = "") { + super(text); + this.on(Laya.Event.CHANGE, this, this._onTextChange); + } + _onTextChange() { + this.callLater(this.changeScroll); + } + destroy(destroyChild = true) { + this._vScrollBar && this._vScrollBar.destroy(); + this._hScrollBar && this._hScrollBar.destroy(); + this._vScrollBar = null; + this._hScrollBar = null; + super.destroy(destroyChild); + } + initialize() { + this.width = 180; + this.height = 150; + this._tf.wordWrap = true; + this.multiline = true; + } + set width(value) { + super.width = value; + this.callLater(this.changeScroll); + } + get width() { + return super.width; + } + set height(value) { + super.height = value; + this.callLater(this.changeScroll); + } + get height() { + return super.height; + } + get vScrollBarSkin() { + return this._vScrollBar ? this._vScrollBar.skin : null; + } + set vScrollBarSkin(value) { + if (this._vScrollBar == null) { + this.addChild(this._vScrollBar = new VScrollBar()); + this._vScrollBar.on(Laya.Event.CHANGE, this, this.onVBarChanged); + this._vScrollBar.target = this._tf; + this.callLater(this.changeScroll); + } + this._vScrollBar.skin = value; + } + get hScrollBarSkin() { + return this._hScrollBar ? this._hScrollBar.skin : null; + } + set hScrollBarSkin(value) { + if (this._hScrollBar == null) { + this.addChild(this._hScrollBar = new HScrollBar()); + this._hScrollBar.on(Laya.Event.CHANGE, this, this.onHBarChanged); + this._hScrollBar.mouseWheelEnable = false; + this._hScrollBar.target = this._tf; + this.callLater(this.changeScroll); + } + this._hScrollBar.skin = value; + } + onVBarChanged(e) { + if (this._tf.scrollY != this._vScrollBar.value) { + this._tf.scrollY = this._vScrollBar.value; + } + } + onHBarChanged(e) { + if (this._tf.scrollX != this._hScrollBar.value) { + this._tf.scrollX = this._hScrollBar.value; + } + } + get vScrollBar() { + return this._vScrollBar; + } + get hScrollBar() { + return this._hScrollBar; + } + get maxScrollY() { + return this._tf.maxScrollY; + } + get scrollY() { + return this._tf.scrollY; + } + get maxScrollX() { + return this._tf.maxScrollX; + } + get scrollX() { + return this._tf.scrollX; + } + changeScroll() { + var vShow = this._vScrollBar && this._tf.maxScrollY > 0; + var hShow = this._hScrollBar && this._tf.maxScrollX > 0; + var showWidth = vShow ? this._width - this._vScrollBar.width : this._width; + var showHeight = hShow ? this._height - this._hScrollBar.height : this._height; + var padding = this._tf.padding || Styles.labelPadding; + this._tf.width = showWidth; + this._tf.height = showHeight; + if (this._vScrollBar) { + this._vScrollBar.x = this._width - this._vScrollBar.width - padding[2]; + this._vScrollBar.y = padding[1]; + this._vScrollBar.height = this._height - (hShow ? this._hScrollBar.height : 0) - padding[1] - padding[3]; + this._vScrollBar.scrollSize = 1; + this._vScrollBar.thumbPercent = showHeight / Math.max(this._tf.textHeight, showHeight); + this._vScrollBar.setScroll(1, this._tf.maxScrollY, this._tf.scrollY); + this._vScrollBar.visible = vShow; + } + if (this._hScrollBar) { + this._hScrollBar.x = padding[0]; + this._hScrollBar.y = this._height - this._hScrollBar.height - padding[3]; + this._hScrollBar.width = this._width - (vShow ? this._vScrollBar.width : 0) - padding[0] - padding[2]; + this._hScrollBar.scrollSize = Math.max(showWidth * 0.033, 1); + this._hScrollBar.thumbPercent = showWidth / Math.max(this._tf.textWidth, showWidth); + this._hScrollBar.setScroll(0, this.maxScrollX, this.scrollX); + this._hScrollBar.visible = hShow; + } + } + scrollTo(y) { + this.commitMeasure(); + this._tf.scrollY = y; + } + } + Laya.ILaya.regClass(TextArea); + Laya.ClassUtils.regClass("laya.ui.TextArea", TextArea); + Laya.ClassUtils.regClass("Laya.TextArea", TextArea); + + class ScaleBox extends Box { + constructor() { + super(...arguments); + this._oldW = 0; + this._oldH = 0; + } + onEnable() { + Laya.ILaya.stage.on("resize", this, this.onResize); + this.onResize(); + } + onDisable() { + Laya.ILaya.stage.off("resize", this, this.onResize); + } + onResize() { + let stage = Laya.ILaya.stage; + if (this.width > 0 && this.height > 0) { + var scale = Math.min(stage.width / this._oldW, stage.height / this._oldH); + super.width = stage.width; + super.height = stage.height; + this.scale(scale, scale); + } + } + set width(value) { + super.width = value; + this._oldW = value; + } + get width() { + return super.width; + } + set height(value) { + super.height = value; + this._oldH = value; + } + get height() { + return super.height; + } + } + Laya.ILaya.regClass(ScaleBox); + Laya.ClassUtils.regClass("laya.ui.ScaleBox", ScaleBox); + Laya.ClassUtils.regClass("Laya.ScaleBox", ScaleBox); + + class HSlider extends Slider { + constructor(skin = null) { + super(skin); + this.isVertical = false; + } + } + Laya.ILaya.regClass(HSlider); + Laya.ClassUtils.regClass("laya.ui.HSlider", HSlider); + Laya.ClassUtils.regClass("Laya.HSlider", HSlider); + + class Panel extends Box { + constructor() { + super(); + this._usedCache = null; + this._elasticEnabled = false; + this.width = this.height = 100; + } + destroy(destroyChild = true) { + super.destroy(destroyChild); + this._content && this._content.destroy(destroyChild); + this._vScrollBar && this._vScrollBar.destroy(destroyChild); + this._hScrollBar && this._hScrollBar.destroy(destroyChild); + this._vScrollBar = null; + this._hScrollBar = null; + this._content = null; + } + destroyChildren() { + this._content.destroyChildren(); + } + createChildren() { + super.addChild(this._content = new Box()); + } + addChild(child) { + child.on(Laya.Event.RESIZE, this, this.onResize); + this._setScrollChanged(); + return this._content.addChild(child); + } + onResize() { + this._setScrollChanged(); + } + addChildAt(child, index) { + child.on(Laya.Event.RESIZE, this, this.onResize); + this._setScrollChanged(); + return this._content.addChildAt(child, index); + } + removeChild(child) { + child.off(Laya.Event.RESIZE, this, this.onResize); + this._setScrollChanged(); + return this._content.removeChild(child); + } + removeChildAt(index) { + this.getChildAt(index).off(Laya.Event.RESIZE, this, this.onResize); + this._setScrollChanged(); + return this._content.removeChildAt(index); + } + removeChildren(beginIndex = 0, endIndex = 0x7fffffff) { + this._content.removeChildren(beginIndex, endIndex); + this._setScrollChanged(); + return this; + } + getChildAt(index) { + return this._content.getChildAt(index); + } + getChildByName(name) { + return this._content.getChildByName(name); + } + getChildIndex(child) { + return this._content.getChildIndex(child); + } + get numChildren() { + return this._content.numChildren; + } + changeScroll() { + this._scrollChanged = false; + var contentW = this.contentWidth || 1; + var contentH = this.contentHeight || 1; + var vscroll = this._vScrollBar; + var hscroll = this._hScrollBar; + var vShow = vscroll && contentH > this._height; + var hShow = hscroll && contentW > this._width; + var showWidth = vShow ? this._width - vscroll.width : this._width; + var showHeight = hShow ? this._height - hscroll.height : this._height; + if (vscroll) { + vscroll.x = this._width - vscroll.width; + vscroll.y = 0; + vscroll.height = this._height - (hShow ? hscroll.height : 0); + vscroll.scrollSize = Math.max(this._height * 0.033, 1); + vscroll.thumbPercent = showHeight / contentH; + vscroll.setScroll(0, contentH - showHeight, vscroll.value); + } + if (hscroll) { + hscroll.x = 0; + hscroll.y = this._height - hscroll.height; + hscroll.width = this._width - (vShow ? vscroll.width : 0); + hscroll.scrollSize = Math.max(this._width * 0.033, 1); + hscroll.thumbPercent = showWidth / contentW; + hscroll.setScroll(0, contentW - showWidth, hscroll.value); + } + } + _sizeChanged() { + super._sizeChanged(); + this.setContentSize(this._width, this._height); + } + get contentWidth() { + var max = 0; + for (var i = this._content.numChildren - 1; i > -1; i--) { + var comp = this._content.getChildAt(i); + max = Math.max(comp._x + comp.width * comp.scaleX - comp.pivotX, max); + } + return max; + } + get contentHeight() { + var max = 0; + for (var i = this._content.numChildren - 1; i > -1; i--) { + var comp = this._content.getChildAt(i); + max = Math.max(comp._y + comp.height * comp.scaleY - comp.pivotY, max); + } + return max; + } + setContentSize(width, height) { + var content = this._content; + content.width = width; + content.height = height; + content._style.scrollRect || (content.scrollRect = Laya.Rectangle.create()); + content._style.scrollRect.setTo(0, 0, width, height); + content.scrollRect = content.scrollRect; + } + set width(value) { + super.width = value; + this._setScrollChanged(); + } + get width() { + return super.width; + } + set height(value) { + super.height = value; + this._setScrollChanged(); + } + get height() { + return super.height; + } + get vScrollBarSkin() { + return this._vScrollBar ? this._vScrollBar.skin : null; + } + set vScrollBarSkin(value) { + if (this._vScrollBar == null) { + super.addChild(this._vScrollBar = new VScrollBar()); + this._vScrollBar.on(Laya.Event.CHANGE, this, this.onScrollBarChange, [this._vScrollBar]); + this._vScrollBar.target = this._content; + this._vScrollBar.elasticDistance = this._elasticEnabled ? 200 : 0; + this._setScrollChanged(); + } + this._vScrollBar.skin = value; + } + get hScrollBarSkin() { + return this._hScrollBar ? this._hScrollBar.skin : null; + } + set hScrollBarSkin(value) { + if (this._hScrollBar == null) { + super.addChild(this._hScrollBar = new HScrollBar()); + this._hScrollBar.on(Laya.Event.CHANGE, this, this.onScrollBarChange, [this._hScrollBar]); + this._hScrollBar.target = this._content; + this._hScrollBar.elasticDistance = this._elasticEnabled ? 200 : 0; + this._setScrollChanged(); + } + this._hScrollBar.skin = value; + } + get vScrollBar() { + return this._vScrollBar; + } + get hScrollBar() { + return this._hScrollBar; + } + get content() { + return this._content; + } + onScrollBarChange(scrollBar) { + var rect = this._content._style.scrollRect; + if (rect) { + var start = Math.round(scrollBar.value); + scrollBar.isVertical ? rect.y = start : rect.x = start; + this._content.scrollRect = rect; + } + } + scrollTo(x = 0, y = 0) { + if (this.vScrollBar) + this.vScrollBar.value = y; + if (this.hScrollBar) + this.hScrollBar.value = x; + } + refresh() { + this.changeScroll(); + } + set cacheAs(value) { + super.cacheAs = value; + this._usedCache = null; + if (value !== "none") { + this._hScrollBar && this._hScrollBar.on(Laya.Event.START, this, this.onScrollStart); + this._vScrollBar && this._vScrollBar.on(Laya.Event.START, this, this.onScrollStart); + } + else { + this._hScrollBar && this._hScrollBar.off(Laya.Event.START, this, this.onScrollStart); + this._vScrollBar && this._vScrollBar.off(Laya.Event.START, this, this.onScrollStart); + } + } + get cacheAs() { + return super.cacheAs; + } + get elasticEnabled() { + return this._elasticEnabled; + } + set elasticEnabled(value) { + this._elasticEnabled = value; + if (this._vScrollBar) { + this._vScrollBar.elasticDistance = value ? 200 : 0; + } + if (this._hScrollBar) { + this._hScrollBar.elasticDistance = value ? 200 : 0; + } + } + onScrollStart() { + this._usedCache || (this._usedCache = super.cacheAs); + super.cacheAs = "none"; + this._hScrollBar && this._hScrollBar.once(Laya.Event.END, this, this.onScrollEnd); + this._vScrollBar && this._vScrollBar.once(Laya.Event.END, this, this.onScrollEnd); + } + onScrollEnd() { + super.cacheAs = this._usedCache; + } + _setScrollChanged() { + if (!this._scrollChanged) { + this._scrollChanged = true; + this.callLater(this.changeScroll); + } + } + } + Laya.ILaya.regClass(Panel); + Laya.ClassUtils.regClass("laya.ui.Panel", Panel); + Laya.ClassUtils.regClass("Laya.Panel", Panel); + + class VSlider extends Slider { + } + Laya.ILaya.regClass(VSlider); + Laya.ClassUtils.regClass("laya.ui.VSlider", VSlider); + Laya.ClassUtils.regClass("Laya.VSlider", VSlider); + + class Tree extends Box { + constructor() { + super(); + this._spaceLeft = 10; + this._spaceBottom = 0; + this._keepStatus = true; + this.width = this.height = 200; + } + destroy(destroyChild = true) { + super.destroy(destroyChild); + this._list && this._list.destroy(destroyChild); + this._list = null; + this._source = null; + this._renderHandler = null; + } + createChildren() { + this.addChild(this._list = new List()); + this._list.renderHandler = Laya.Handler.create(this, this.renderItem, null, false); + this._list.repeatX = 1; + this._list.on(Laya.Event.CHANGE, this, this.onListChange); + } + onListChange(e = null) { + this.event(Laya.Event.CHANGE); + } + get keepStatus() { + return this._keepStatus; + } + set keepStatus(value) { + this._keepStatus = value; + } + get array() { + return this._list.array; + } + set array(value) { + if (this._keepStatus && this._list.array && value) { + this.parseOpenStatus(this._list.array, value); + } + this._source = value; + this._list.array = this.getArray(); + } + get source() { + return this._source; + } + get list() { + return this._list; + } + get itemRender() { + return this._list.itemRender; + } + set itemRender(value) { + this._list.itemRender = value; + } + get scrollBarSkin() { + return this._list.vScrollBarSkin; + } + set scrollBarSkin(value) { + this._list.vScrollBarSkin = value; + } + get scrollBar() { + return this._list.scrollBar; + } + get mouseHandler() { + return this._list.mouseHandler; + } + set mouseHandler(value) { + this._list.mouseHandler = value; + } + get renderHandler() { + return this._renderHandler; + } + set renderHandler(value) { + this._renderHandler = value; + } + get spaceLeft() { + return this._spaceLeft; + } + set spaceLeft(value) { + this._spaceLeft = value; + } + get spaceBottom() { + return this._list.spaceY; + } + set spaceBottom(value) { + this._list.spaceY = value; + } + get selectedIndex() { + return this._list.selectedIndex; + } + set selectedIndex(value) { + this._list.selectedIndex = value; + } + get selectedItem() { + return this._list.selectedItem; + } + set selectedItem(value) { + this._list.selectedItem = value; + } + set width(value) { + super.width = value; + this._list.width = value; + } + get width() { + return super.width; + } + set height(value) { + super.height = value; + this._list.height = value; + } + get height() { + return super.height; + } + getArray() { + var arr = []; + for (let key in this._source) { + let item = this._source[key]; + if (this.getParentOpenStatus(item)) { + item.x = this._spaceLeft * this.getDepth(item); + arr.push(item); + } + } + return arr; + } + getDepth(item, num = 0) { + if (item.nodeParent == null) + return num; + else + return this.getDepth(item.nodeParent, num + 1); + } + getParentOpenStatus(item) { + var parent = item.nodeParent; + if (parent == null) { + return true; + } + else { + if (parent.isOpen) { + if (parent.nodeParent != null) + return this.getParentOpenStatus(parent); + else + return true; + } + else { + return false; + } + } + } + renderItem(cell, index) { + var item = cell.dataSource; + if (item) { + cell.left = item.x; + var arrow = cell.getChildByName("arrow"); + if (arrow) { + if (item.hasChild) { + arrow.visible = true; + arrow.index = item.isOpen ? 1 : 0; + arrow.tag = index; + arrow.off(Laya.Event.CLICK, this, this.onArrowClick); + arrow.on(Laya.Event.CLICK, this, this.onArrowClick); + } + else { + arrow.visible = false; + } + } + var folder = cell.getChildByName("folder"); + if (folder) { + if (folder.clipY == 2) { + folder.index = item.isDirectory ? 0 : 1; + } + else { + folder.index = item.isDirectory ? item.isOpen ? 1 : 0 : 2; + } + } + this._renderHandler && this._renderHandler.runWith([cell, index]); + } + } + onArrowClick(e) { + var arrow = e.currentTarget; + var index = arrow.tag; + this._list.array[index].isOpen = !this._list.array[index].isOpen; + this.event(Laya.Event.OPEN); + this._list.array = this.getArray(); + } + setItemState(index, isOpen) { + if (!this._list.array[index]) + return; + this._list.array[index].isOpen = isOpen; + this._list.array = this.getArray(); + } + fresh() { + this._list.array = this.getArray(); + this.repaint(); + } + set dataSource(value) { + this._dataSource = value; + super.dataSource = value; + } + get dataSource() { + return super.dataSource; + } + set xml(value) { + var arr = []; + this.parseXml(value.childNodes[0], arr, null, true); + this.array = arr; + } + parseXml(xml, source, nodeParent, isRoot) { + var obj; + var list = xml.childNodes; + var childCount = list.length; + if (!isRoot) { + obj = {}; + var list2 = xml.attributes; + for (let key in list2) { + var attrs = list2[key]; + var prop = attrs.nodeName; + var value = attrs.nodeValue; + obj[prop] = value == "true" ? true : value == "false" ? false : value; + } + obj.nodeParent = nodeParent; + if (childCount > 0) + obj.isDirectory = true; + obj.hasChild = childCount > 0; + source.push(obj); + } + for (var i = 0; i < childCount; i++) { + var node = list[i]; + this.parseXml(node, source, obj, false); + } + } + parseOpenStatus(oldSource, newSource) { + for (var i = 0, n = newSource.length; i < n; i++) { + var newItem = newSource[i]; + if (newItem.isDirectory) { + for (var j = 0, m = oldSource.length; j < m; j++) { + var oldItem = oldSource[j]; + if (oldItem.isDirectory && this.isSameParent(oldItem, newItem) && newItem.label == oldItem.label) { + newItem.isOpen = oldItem.isOpen; + break; + } + } + } + } + } + isSameParent(item1, item2) { + if (item1.nodeParent == null && item2.nodeParent == null) + return true; + else if (item1.nodeParent == null || item2.nodeParent == null) + return false; + else { + if (item1.nodeParent.label == item2.nodeParent.label) + return this.isSameParent(item1.nodeParent, item2.nodeParent); + else + return false; + } + } + get selectedPath() { + if (this._list.selectedItem) { + return this._list.selectedItem.path; + } + return null; + } + filter(key) { + if (Boolean(key)) { + var result = []; + this.getFilterSource(this._source, result, key); + this._list.array = result; + } + else { + this._list.array = this.getArray(); + } + } + getFilterSource(array, result, key) { + key = key.toLocaleLowerCase(); + for (let item of array) { + if (!item.isDirectory && String(item.label).toLowerCase().indexOf(key) > -1) { + item.x = 0; + result.push(item); + } + if (item.child && item.child.length > 0) { + this.getFilterSource(item.child, result, key); + } + } + } + } + Laya.ILaya.regClass(Tree); + Laya.ClassUtils.regClass("laya.ui.Tree", Tree); + Laya.ClassUtils.regClass("Laya.Tree", Tree); + + class LayoutBox extends Box { + constructor() { + super(...arguments); + this._space = 0; + this._align = "none"; + this._itemChanged = false; + } + addChild(child) { + child.on(Laya.Event.RESIZE, this, this.onResize); + this._setItemChanged(); + return super.addChild(child); + } + onResize(e) { + this._setItemChanged(); + } + addChildAt(child, index) { + child.on(Laya.Event.RESIZE, this, this.onResize); + this._setItemChanged(); + return super.addChildAt(child, index); + } + removeChildAt(index) { + this.getChildAt(index).off(Laya.Event.RESIZE, this, this.onResize); + this._setItemChanged(); + return super.removeChildAt(index); + } + refresh() { + this._setItemChanged(); + } + changeItems() { + this._itemChanged = false; + } + get space() { + return this._space; + } + set space(value) { + this._space = value; + this._setItemChanged(); + } + get align() { + return this._align; + } + set align(value) { + this._align = value; + this._setItemChanged(); + } + sortItem(items) { + if (items) + items.sort(function (a, b) { return a.y - b.y; }); + } + _setItemChanged() { + if (!this._itemChanged) { + this._itemChanged = true; + this.callLater(this.changeItems); + } + } + } + Laya.ILaya.regClass(LayoutBox); + Laya.ClassUtils.regClass("laya.ui.LayoutBox", LayoutBox); + Laya.ClassUtils.regClass("Laya.LayoutBox", LayoutBox); + + class HBox extends LayoutBox { + sortItem(items) { + if (items) + items.sort(function (a, b) { return a.x - b.x; }); + } + set height(value) { + if (this._height != value) { + super.height = value; + this.callLater(this.changeItems); + } + } + get height() { + return super.height; + } + changeItems() { + this._itemChanged = false; + var items = []; + var maxHeight = 0; + for (var i = 0, n = this.numChildren; i < n; i++) { + var item = this.getChildAt(i); + if (item) { + items.push(item); + maxHeight = this._height ? this._height : Math.max(maxHeight, item.height * item.scaleY); + } + } + this.sortItem(items); + var left = 0; + for (i = 0, n = items.length; i < n; i++) { + item = items[i]; + item.x = left; + left += item.width * item.scaleX + this._space; + if (this._align == HBox.TOP) { + item.y = 0; + } + else if (this._align == HBox.MIDDLE) { + item.y = (maxHeight - item.height * item.scaleY) * 0.5; + } + else if (this._align == HBox.BOTTOM) { + item.y = maxHeight - item.height * item.scaleY; + } + } + this._sizeChanged(); + } + } + HBox.NONE = "none"; + HBox.TOP = "top"; + HBox.MIDDLE = "middle"; + HBox.BOTTOM = "bottom"; + Laya.ILaya.regClass(HBox); + Laya.ClassUtils.regClass("laya.ui.HBox", HBox); + Laya.ClassUtils.regClass("Laya.HBox", HBox); + + class VBox extends LayoutBox { + constructor() { + super(...arguments); + this.isSortItem = false; + } + set width(value) { + if (this._width != value) { + super.width = value; + this.callLater(this.changeItems); + } + } + get width() { + return super.width; + } + changeItems() { + this._itemChanged = false; + var items = []; + var maxWidth = 0; + for (var i = 0, n = this.numChildren; i < n; i++) { + var item = this.getChildAt(i); + if (item) { + items.push(item); + maxWidth = this._width ? this._width : Math.max(maxWidth, item.width * item.scaleX); + } + } + if (this.isSortItem) { + this.sortItem(items); + } + var top = 0; + for (i = 0, n = items.length; i < n; i++) { + item = items[i]; + item.y = top; + top += item.height * item.scaleY + this._space; + if (this._align == VBox.LEFT) { + item.x = 0; + } + else if (this._align == VBox.CENTER) { + item.x = (maxWidth - item.width * item.scaleX) * 0.5; + } + else if (this._align == VBox.RIGHT) { + item.x = maxWidth - item.width * item.scaleX; + } + } + this._sizeChanged(); + } + } + VBox.NONE = "none"; + VBox.LEFT = "left"; + VBox.CENTER = "center"; + VBox.RIGHT = "right"; + Laya.ILaya.regClass(VBox); + Laya.ClassUtils.regClass("laya.ui.VBox", VBox); + Laya.ClassUtils.regClass("Laya.VBox", VBox); + + class FontClip extends Clip { + constructor(skin = null, sheet = null) { + super(); + this._valueArr = ''; + this._indexMap = null; + this._sheet = null; + this._direction = "horizontal"; + this._spaceX = 0; + this._spaceY = 0; + this._align = "left"; + this._wordsW = 0; + this._wordsH = 0; + if (skin) + this.skin = skin; + if (sheet) + this.sheet = sheet; + } + createChildren() { + this._bitmap = new AutoBitmap(); + this.on(Laya.Event.LOADED, this, this._onClipLoaded); + } + _onClipLoaded() { + this.callLater(this.changeValue); + } + get sheet() { + return this._sheet; + } + set sheet(value) { + value += ""; + this._sheet = value; + var arr = value.split(" "); + this._clipX = String(arr[0]).length; + this.clipY = arr.length; + this._indexMap = {}; + for (var i = 0; i < this._clipY; i++) { + var line = arr[i].split(""); + for (var j = 0, n = line.length; j < n; j++) { + this._indexMap[line[j]] = i * this._clipX + j; + } + } + } + get value() { + if (!this._valueArr) + return ""; + return this._valueArr; + } + set value(value) { + value += ""; + this._valueArr = value; + this.callLater(this.changeValue); + } + get direction() { + return this._direction; + } + set direction(value) { + this._direction = value; + this.callLater(this.changeValue); + } + get spaceX() { + return this._spaceX; + } + set spaceX(value) { + this._spaceX = value; + if (this._direction === "horizontal") + this.callLater(this.changeValue); + } + get spaceY() { + return this._spaceY; + } + set spaceY(value) { + this._spaceY = value; + if (!(this._direction === "horizontal")) + this.callLater(this.changeValue); + } + set align(v) { + this._align = v; + this.callLater(this.changeValue); + } + get align() { + return this._align; + } + changeValue() { + if (!this._sources) + return; + if (!this._valueArr) + return; + this.graphics.clear(true); + var texture; + texture = this._sources[0]; + if (!texture) + return; + var isHorizontal = (this._direction === "horizontal"); + if (isHorizontal) { + this._wordsW = this._valueArr.length * (texture.sourceWidth + this.spaceX); + this._wordsH = texture.sourceHeight; + } + else { + this._wordsW = texture.sourceWidth; + this._wordsH = (texture.sourceHeight + this.spaceY) * this._valueArr.length; + } + var dX = 0; + if (this._width) { + switch (this._align) { + case "center": + dX = 0.5 * (this._width - this._wordsW); + break; + case "right": + dX = this._width - this._wordsW; + break; + default: + dX = 0; + } + } + for (var i = 0, sz = this._valueArr.length; i < sz; i++) { + var index = this._indexMap[this._valueArr.charAt(i)]; + if (!this.sources[index]) + continue; + texture = this.sources[index]; + if (isHorizontal) + this.graphics.drawImage(texture, dX + i * (texture.sourceWidth + this.spaceX), 0, texture.sourceWidth, texture.sourceHeight); + else + this.graphics.drawImage(texture, 0 + dX, i * (texture.sourceHeight + this.spaceY), texture.sourceWidth, texture.sourceHeight); + } + if (!this._width) { + this._widget.resetLayoutX(); + this.callLater(this._sizeChanged); + } + if (!this._height) { + this._widget.resetLayoutY(); + this.callLater(this._sizeChanged); + } + } + set width(value) { + super.width = value; + this.callLater(this.changeValue); + } + get width() { + return super.width; + } + set height(value) { + super.height = value; + this.callLater(this.changeValue); + } + get height() { + return super.height; + } + measureWidth() { + return this._wordsW; + } + measureHeight() { + return this._wordsH; + } + destroy(destroyChild = true) { + this._valueArr = null; + this._indexMap = null; + this.graphics.clear(true); + this.removeSelf(); + this.off(Laya.Event.LOADED, this, this._onClipLoaded); + super.destroy(destroyChild); + } + } + Laya.ILaya.regClass(FontClip); + Laya.ClassUtils.regClass("laya.ui.FontClip", FontClip); + Laya.ClassUtils.regClass("Laya.FontClip", FontClip); + + class View extends Laya.Scene { + constructor() { + super(false); + this._watchMap = {}; + this._anchorX = NaN; + this._anchorY = NaN; + this._widget = Widget.EMPTY; + this.createChildren(); + } + static __init__() { + Laya.ILaya.ClassUtils.regShortClassName([ViewStack, Button, TextArea, ColorPicker, Box, ScaleBox, CheckBox, Clip, ComboBox, UIComponent, + HScrollBar, HSlider, Image, Label, List, Panel, ProgressBar, Radio, RadioGroup, ScrollBar, Slider, Tab, TextInput, View, + VScrollBar, VSlider, Tree, HBox, VBox, Laya.Animation, Laya.Text, FontClip]); + } + static regComponent(key, compClass) { + Laya.ILaya.ClassUtils.regClass(key, compClass); + } + static regViewRuntime(key, compClass) { + Laya.ILaya.ClassUtils.regClass(key, compClass); + } + static regUI(url, json) { + Laya.ILaya.loader.cacheRes(url, json); + } + destroy(destroyChild = true) { + this._watchMap = null; + super.destroy(destroyChild); + } + changeData(key) { + var arr = this._watchMap[key]; + if (!arr) + return; + for (var i = 0, n = arr.length; i < n; i++) { + var watcher = arr[i]; + watcher.exe(this); + } + } + get top() { + return this._widget.top; + } + set top(value) { + if (value != this._widget.top) { + this._getWidget().top = value; + } + } + get bottom() { + return this._widget.bottom; + } + set bottom(value) { + if (value != this._widget.bottom) { + this._getWidget().bottom = value; + } + } + get left() { + return this._widget.left; + } + set left(value) { + if (value != this._widget.left) { + this._getWidget().left = value; + } + } + get right() { + return this._widget.right; + } + set right(value) { + if (value != this._widget.right) { + this._getWidget().right = value; + } + } + get centerX() { + return this._widget.centerX; + } + set centerX(value) { + if (value != this._widget.centerX) { + this._getWidget().centerX = value; + } + } + get centerY() { + return this._widget.centerY; + } + set centerY(value) { + if (value != this._widget.centerY) { + this._getWidget().centerY = value; + } + } + get anchorX() { + return this._anchorX; + } + set anchorX(value) { + if (this._anchorX != value) { + this._anchorX = value; + this.callLater(this._sizeChanged); + } + } + get anchorY() { + return this._anchorY; + } + set anchorY(value) { + if (this._anchorY != value) { + this._anchorY = value; + this.callLater(this._sizeChanged); + } + } + _sizeChanged() { + if (!isNaN(this._anchorX)) + this.pivotX = this.anchorX * this.width; + if (!isNaN(this._anchorY)) + this.pivotY = this.anchorY * this.height; + this.event(Laya.Event.RESIZE); + } + _getWidget() { + this._widget === Widget.EMPTY && (this._widget = this.addComponent(Widget)); + return this._widget; + } + loadUI(path) { + var uiView = View.uiMap[path]; + View.uiMap && this.createView(uiView); + } + get dataSource() { + return this._dataSource; + } + set dataSource(value) { + this._dataSource = value; + for (var name in value) { + var comp = this.getChildByName(name); + if (comp instanceof UIComponent) + comp.dataSource = value[name]; + else if (name in this && !(this[name] instanceof Function)) + this[name] = value[name]; + } + } + } + View.uiMap = {}; + Laya.ILaya.regClass(View); + Laya.ClassUtils.regClass("laya.ui.View", View); + Laya.ClassUtils.regClass("Laya.View", View); + + class IUI { + } + + class DialogManager extends Laya.Sprite { + constructor() { + super(); + this.maskLayer = new Laya.Sprite(); + this.popupEffect = (dialog) => { + dialog.scale(1, 1); + dialog._effectTween = Laya.Tween.from(dialog, { x: Laya.ILaya.stage.width / 2, y: Laya.ILaya.stage.height / 2, scaleX: 0, scaleY: 0 }, 300, Laya.Ease.backOut, Laya.Handler.create(this, this.doOpen, [dialog]), 0, false, false); + }; + this.closeEffect = (dialog) => { + dialog._effectTween = Laya.Tween.to(dialog, { x: Laya.ILaya.stage.width / 2, y: Laya.ILaya.stage.height / 2, scaleX: 0, scaleY: 0 }, 300, Laya.Ease.strongOut, Laya.Handler.create(this, this.doClose, [dialog]), 0, false, false); + }; + this.popupEffectHandler = new Laya.Handler(this, this.popupEffect); + this.closeEffectHandler = new Laya.Handler(this, this.closeEffect); + this.mouseEnabled = this.maskLayer.mouseEnabled = true; + this.zOrder = 1000; + Laya.ILaya.stage.addChild(this); + Laya.ILaya.stage.on(Laya.Event.RESIZE, this, this._onResize); + if (UIConfig.closeDialogOnSide) + this.maskLayer.on("click", this, this._closeOnSide); + this._onResize(null); + } + _closeOnSide() { + var dialog = this.getChildAt(this.numChildren - 1); + if (dialog instanceof IUI.Dialog) + dialog.close("side"); + } + setLockView(value) { + if (!this.lockLayer) { + this.lockLayer = new Box(); + this.lockLayer.mouseEnabled = true; + this.lockLayer.size(Laya.ILaya.stage.width, Laya.ILaya.stage.height); + } + this.lockLayer.removeChildren(); + if (value) { + value.centerX = value.centerY = 0; + this.lockLayer.addChild(value); + } + } + _onResize(e = null) { + var width = this.maskLayer.width = Laya.ILaya.stage.width; + var height = this.maskLayer.height = Laya.ILaya.stage.height; + if (this.lockLayer) + this.lockLayer.size(width, height); + this.maskLayer.graphics.clear(true); + this.maskLayer.graphics.drawRect(0, 0, width, height, UIConfig.popupBgColor); + this.maskLayer.alpha = UIConfig.popupBgAlpha; + for (var i = this.numChildren - 1; i > -1; i--) { + var item = this.getChildAt(i); + if (item.isPopupCenter) + this._centerDialog(item); + } + } + _centerDialog(dialog) { + dialog.x = Math.round(((Laya.ILaya.stage.width - dialog.width) >> 1) + dialog.pivotX); + dialog.y = Math.round(((Laya.ILaya.stage.height - dialog.height) >> 1) + dialog.pivotY); + } + open(dialog, closeOther = false, showEffect = false) { + if (closeOther) + this._closeAll(); + this._clearDialogEffect(dialog); + if (dialog.isPopupCenter) + this._centerDialog(dialog); + this.addChild(dialog); + if (dialog.isModal || this._getBit(Laya.Const.HAS_ZORDER)) + Laya.ILaya.timer.callLater(this, this._checkMask); + if (showEffect && dialog.popupEffect != null) + dialog.popupEffect.runWith(dialog); + else + this.doOpen(dialog); + this.event(Laya.Event.OPEN); + } + _clearDialogEffect(dialog) { + if (dialog._effectTween) { + Laya.Tween.clear(dialog._effectTween); + dialog._effectTween = null; + } + } + doOpen(dialog) { + dialog.onOpened(dialog._param); + } + lock(value) { + if (this.lockLayer) { + if (value) + this.addChild(this.lockLayer); + else + this.lockLayer.removeSelf(); + } + } + close(dialog) { + this._clearDialogEffect(dialog); + if (dialog.isShowEffect && dialog.closeEffect != null) + dialog.closeEffect.runWith([dialog]); + else + this.doClose(dialog); + this.event(Laya.Event.CLOSE); + } + doClose(dialog) { + dialog.removeSelf(); + dialog.isModal && this._checkMask(); + dialog.closeHandler && dialog.closeHandler.runWith(dialog.closeType); + dialog.onClosed(dialog.closeType); + if (dialog.autoDestroyAtClosed) + dialog.destroy(); + } + closeAll() { + this._closeAll(); + this.event(Laya.Event.CLOSE); + } + _closeAll() { + for (var i = this.numChildren - 1; i > -1; i--) { + var item = this.getChildAt(i); + if (item && item.close != null) { + this.doClose(item); + } + } + } + getDialogsByGroup(group) { + var arr = []; + for (var i = this.numChildren - 1; i > -1; i--) { + var item = this.getChildAt(i); + if (item && item.group === group) { + arr.push(item); + } + } + return arr; + } + closeByGroup(group) { + var arr = []; + for (var i = this.numChildren - 1; i > -1; i--) { + var item = this.getChildAt(i); + if (item && item.group === group) { + item.close(); + arr.push(item); + } + } + return arr; + } + _checkMask() { + this.maskLayer.removeSelf(); + for (var i = this.numChildren - 1; i > -1; i--) { + var dialog = this.getChildAt(i); + if (dialog && dialog.isModal) { + this.addChildAt(this.maskLayer, i); + return; + } + } + } + } + Laya.ClassUtils.regClass("laya.ui.DialogManager", DialogManager); + Laya.ClassUtils.regClass("Laya.DialogManager", DialogManager); + + class Dialog extends View { + constructor() { + super(); + this.isShowEffect = true; + this.isPopupCenter = true; + this.popupEffect = Dialog.manager.popupEffectHandler; + this.closeEffect = Dialog.manager.closeEffectHandler; + this._dealDragArea(); + this.on(Laya.Event.CLICK, this, this._onClick); + } + static get manager() { + return Dialog._manager = Dialog._manager || new DialogManager(); + } + static set manager(value) { + Dialog._manager = value; + } + _dealDragArea() { + var dragTarget = this.getChildByName("drag"); + if (dragTarget) { + this.dragArea = dragTarget._x + "," + dragTarget._y + "," + dragTarget.width + "," + dragTarget.height; + dragTarget.removeSelf(); + } + } + get dragArea() { + if (this._dragArea) + return this._dragArea.toString(); + return null; + } + set dragArea(value) { + if (value) { + var a = UIUtils.fillArray([0, 0, 0, 0], value, Number); + this._dragArea = new Laya.Rectangle(a[0], a[1], a[2], a[3]); + this.on(Laya.Event.MOUSE_DOWN, this, this._onMouseDown); + } + else { + this._dragArea = null; + this.off(Laya.Event.MOUSE_DOWN, this, this._onMouseDown); + } + } + _onMouseDown(e) { + var point = this.getMousePoint(); + if (this._dragArea.contains(point.x, point.y)) + this.startDrag(); + else + this.stopDrag(); + } + _onClick(e) { + var btn = e.target; + if (btn) { + switch (btn.name) { + case Dialog.CLOSE: + case Dialog.CANCEL: + case Dialog.SURE: + case Dialog.NO: + case Dialog.OK: + case Dialog.YES: + this.close(btn.name); + return; + } + } + } + open(closeOther = true, param = null) { + this._dealDragArea(); + this._param = param; + Dialog.manager.open(this, closeOther, this.isShowEffect); + Dialog.manager.lock(false); + } + close(type = null) { + this.closeType = type; + Dialog.manager.close(this); + } + destroy(destroyChild = true) { + this.closeHandler = null; + this.popupEffect = null; + this.closeEffect = null; + this._dragArea = null; + super.destroy(destroyChild); + } + show(closeOther = false, showEffect = true) { + this._open(false, closeOther, showEffect); + } + popup(closeOther = false, showEffect = true) { + this._open(true, closeOther, showEffect); + } + _open(modal, closeOther, showEffect) { + this.isModal = modal; + this.isShowEffect = showEffect; + Dialog.manager.lock(true); + this.open(closeOther); + } + get isPopup() { + return this.parent != null; + } + set zOrder(value) { + super.zOrder = value; + Dialog.manager._checkMask(); + } + get zOrder() { + return super.zOrder; + } + static setLockView(view) { + Dialog.manager.setLockView(view); + } + static lock(value) { + Dialog.manager.lock(value); + } + static closeAll() { + Dialog.manager.closeAll(); + } + static getDialogsByGroup(group) { + return Dialog.manager.getDialogsByGroup(group); + } + static closeByGroup(group) { + return Dialog.manager.closeByGroup(group); + } + } + Dialog.CLOSE = "close"; + Dialog.CANCEL = "cancel"; + Dialog.SURE = "sure"; + Dialog.NO = "no"; + Dialog.YES = "yes"; + Dialog.OK = "ok"; + IUI.Dialog = Dialog; + Laya.ILaya.regClass(Dialog); + Laya.ClassUtils.regClass("laya.ui.Dialog", Dialog); + Laya.ClassUtils.regClass("Laya.Dialog", Dialog); + + class TipManager extends UIComponent { + constructor() { + super(); + this._tipBox = new UIComponent(); + this._tipBox.addChild(this._tipText = new Laya.Text()); + this._tipText.x = this._tipText.y = 5; + this._tipText.color = TipManager.tipTextColor; + this._defaultTipHandler = this._showDefaultTip; + Laya.ILaya.stage.on(UIEvent.SHOW_TIP, this, this._onStageShowTip); + Laya.ILaya.stage.on(UIEvent.HIDE_TIP, this, this._onStageHideTip); + this.zOrder = 1100; + } + _onStageHideTip(e) { + Laya.ILaya.timer.clear(this, this._showTip); + this.closeAll(); + this.removeSelf(); + } + _onStageShowTip(data) { + Laya.ILaya.timer.once(TipManager.tipDelay, this, this._showTip, [data], true); + } + _showTip(tip) { + if (typeof (tip) == 'string') { + var text = String(tip); + if (Boolean(text)) { + this._defaultTipHandler(text); + } + } + else if (tip instanceof Laya.Handler) { + tip.run(); + } + else if (tip instanceof Function) { + tip.apply(); + } + { + Laya.ILaya.stage.on(Laya.Event.MOUSE_MOVE, this, this._onStageMouseMove); + Laya.ILaya.stage.on(Laya.Event.MOUSE_DOWN, this, this._onStageMouseDown); + } + this._onStageMouseMove(null); + } + _onStageMouseDown(e) { + this.closeAll(); + } + _onStageMouseMove(e) { + this._showToStage(this, TipManager.offsetX, TipManager.offsetY); + } + _showToStage(dis, offX = 0, offY = 0) { + var rec = dis.getBounds(); + dis.x = Laya.ILaya.stage.mouseX + offX; + dis.y = Laya.ILaya.stage.mouseY + offY; + if (dis._x + rec.width > Laya.ILaya.stage.width) { + dis.x -= rec.width + offX; + } + if (dis._y + rec.height > Laya.ILaya.stage.height) { + dis.y -= rec.height + offY; + } + } + closeAll() { + Laya.ILaya.timer.clear(this, this._showTip); + Laya.ILaya.stage.off(Laya.Event.MOUSE_MOVE, this, this._onStageMouseMove); + Laya.ILaya.stage.off(Laya.Event.MOUSE_DOWN, this, this._onStageMouseDown); + this.removeChildren(); + } + showDislayTip(tip) { + this.addChild(tip); + this._showToStage(this); + Laya.ILaya.stage.addChild(this); + } + _showDefaultTip(text) { + this._tipText.text = text; + var g = this._tipBox.graphics; + g.clear(true); + g.drawRect(0, 0, this._tipText.width + 10, this._tipText.height + 10, TipManager.tipBackColor); + this.addChild(this._tipBox); + this._showToStage(this); + Laya.ILaya.stage.addChild(this); + } + get defaultTipHandler() { + return this._defaultTipHandler; + } + set defaultTipHandler(value) { + this._defaultTipHandler = value; + } + } + TipManager.offsetX = 10; + TipManager.offsetY = 15; + TipManager.tipTextColor = "#ffffff"; + TipManager.tipBackColor = "#111111"; + TipManager.tipDelay = 200; + Laya.ILaya.regClass(TipManager); + Laya.ClassUtils.regClass("laya.ui.TipManager", TipManager); + Laya.ClassUtils.regClass("Laya.TipManager", TipManager); + + class UILib { + static __init__() { + } + } + + class WXOpenDataViewer extends UIComponent { + constructor() { + super(); + this._width = this._height = 200; + var tex = new Laya.Texture(); + tex.bitmap = new Laya.Texture2D(); + this.texture = tex; + } + onEnable() { + this.postMsg({ type: "display", rate: Laya.Laya.stage.frameRate }); + if (window.wx && window.sharedCanvas) + Laya.Laya.timer.frameLoop(1, this, this._onLoop); + } + onDisable() { + this.postMsg({ type: "undisplay" }); + Laya.Laya.timer.clear(this, this._onLoop); + } + _onLoop() { + let _canvas = window.sharedCanvas; + this.texture.sourceWidth = _canvas.width; + this.texture.sourceHeight = _canvas.height; + this.texture.bitmap.loadImageSource(_canvas); + } + set width(value) { + super.width = value; + if (window.sharedCanvas) + window.sharedCanvas.width = value; + this.callLater(this._postMsg); + } + get width() { + return super.width; + } + set height(value) { + super.height = value; + if (window.sharedCanvas) + window.sharedCanvas.height = value; + this.callLater(this._postMsg); + } + get height() { + return super.height; + } + set x(value) { + super.x = value; + this.callLater(this._postMsg); + } + get x() { + return super.x; + } + set y(value) { + super.y = value; + this.callLater(this._postMsg); + } + get y() { + return super.y; + } + _postMsg() { + var mat = new Laya.Matrix(); + mat.translate(this.x, this.y); + var stage = Laya.Laya.stage; + mat.scale(stage._canvasTransform.getScaleX() * this.globalScaleX * stage.transform.getScaleX(), stage._canvasTransform.getScaleY() * this.globalScaleY * stage.transform.getScaleY()); + this.postMsg({ type: "changeMatrix", a: mat.a, b: mat.b, c: mat.c, d: mat.d, tx: mat.tx, ty: mat.ty, w: this.width, h: this.height }); + } + postMsg(msg) { + if (window.wx && window.wx.getOpenDataContext) { + var openDataContext = window.wx.getOpenDataContext(); + openDataContext.postMessage(msg); + } + } + } + Laya.ILaya.regClass(WXOpenDataViewer); + Laya.ClassUtils.regClass("laya.ui.WXOpenDataViewer", WXOpenDataViewer); + Laya.ClassUtils.regClass("Laya.WXOpenDataViewer", WXOpenDataViewer); + + exports.AdvImage = AdvImage; + exports.AutoBitmap = AutoBitmap; + exports.Box = Box; + exports.Button = Button; + exports.CheckBox = CheckBox; + exports.Clip = Clip; + exports.ColorPicker = ColorPicker; + exports.ComboBox = ComboBox; + exports.Dialog = Dialog; + exports.DialogManager = DialogManager; + exports.FontClip = FontClip; + exports.HBox = HBox; + exports.HScrollBar = HScrollBar; + exports.HSlider = HSlider; + exports.IUI = IUI; + exports.Image = Image; + exports.Label = Label; + exports.LayoutBox = LayoutBox; + exports.List = List; + exports.Panel = Panel; + exports.ProgressBar = ProgressBar; + exports.Radio = Radio; + exports.RadioGroup = RadioGroup; + exports.ScaleBox = ScaleBox; + exports.ScrollBar = ScrollBar; + exports.Slider = Slider; + exports.Styles = Styles; + exports.Tab = Tab; + exports.TextArea = TextArea; + exports.TextInput = TextInput; + exports.TipManager = TipManager; + exports.Tree = Tree; + exports.UIComponent = UIComponent; + exports.UIConfig = UIConfig; + exports.UIEvent = UIEvent; + exports.UIGroup = UIGroup; + exports.UILib = UILib; + exports.UIUtils = UIUtils; + exports.VBox = VBox; + exports.VScrollBar = VScrollBar; + exports.VSlider = VSlider; + exports.View = View; + exports.ViewStack = ViewStack; + exports.WXOpenDataViewer = WXOpenDataViewer; + exports.Widget = Widget; + +}(window.Laya = window.Laya || {}, Laya)); diff --git a/examples/layaair/frontend/bin/libs/laya.vvmini.js b/examples/layaair/frontend/bin/libs/laya.vvmini.js new file mode 100644 index 0000000..dde6a4c --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.vvmini.js @@ -0,0 +1,1841 @@ +window.vvMiniGame = function (exports, Laya) { + 'use strict'; + + function ImageDataPolyfill() { + let width, height, data; + if (arguments.length == 3) { + if (arguments[0] instanceof Uint8ClampedArray) { + if (arguments[0].length % 4 !== 0) { + throw new Error("Failed to construct 'ImageData': The input data length is not a multiple of 4."); + } + if (arguments[0].length !== arguments[1] * arguments[2] * 4) { + throw new Error("Failed to construct 'ImageData': The input data length is not equal to (4 * width * height)."); + } + else { + data = arguments[0]; + width = arguments[1]; + height = arguments[2]; + } + } + else { + throw new Error("Failed to construct 'ImageData': parameter 1 is not of type 'Uint8ClampedArray'."); + } + } + else if (arguments.length == 2) { + width = arguments[0]; + height = arguments[1]; + data = new Uint8ClampedArray(arguments[0] * arguments[1] * 4); + } + else if (arguments.length < 2) { + throw new Error("Failed to construct 'ImageData': 2 arguments required, but only " + arguments.length + " present."); + } + let imgdata = Laya.Browser.canvas.getContext("2d").getImageData(0, 0, width, height); + for (let i = 0; i < data.length; i += 4) { + imgdata.data[i] = data[i]; + imgdata.data[i + 1] = data[i + 1]; + imgdata.data[i + 2] = data[i + 2]; + imgdata.data[i + 3] = data[i + 3]; + } + return imgdata; + } + + class MiniFileMgr { + static isLocalNativeFile(url) { + for (var i = 0, sz = VVMiniAdapter.nativefiles.length; i < sz; i++) { + if (url.indexOf(VVMiniAdapter.nativefiles[i]) != -1) + return true; + } + return false; + } + static isNetFile(url) { + return (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) && url.indexOf(VVMiniAdapter.window.qg.env.USER_DATA_PATH) == -1; + } + static getFileInfo(fileUrl) { + var fileNativePath = fileUrl; + var fileObj = MiniFileMgr.fakeObj[fileNativePath]; + if (fileObj == null) + return null; + else + return fileObj; + } + static read(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "") { + var fileUrl; + if (readyUrl != "" && (readyUrl.indexOf("http://") != -1 || readyUrl.indexOf("https://") != -1)) { + fileUrl = MiniFileMgr.getFileNativePath(filePath); + } + else { + fileUrl = filePath; + } + fileUrl = Laya.URL.getAdptedFilePath(fileUrl); + MiniFileMgr.fs.readFile({ filePath: fileUrl, encoding: encoding, success: function (data) { + if (!data.data) + data.data = data.text; + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data && readyUrl != "") + MiniFileMgr.downFiles(VVMiniAdapter.safeEncodeURI(readyUrl), encoding, callBack, readyUrl, isSaveFile, fileType); + else + callBack != null && callBack.runWith([1]); + } }); + } + static isFile(url) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(url); + } + catch (err) { + return false; + } + return stat.isFile(); + } + static downFiles(fileUrl, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + var downloadTask = MiniFileMgr.wxdown({ url: fileUrl, success: function (data) { + if (data.errCode == 0) + data.statusCode = 200; + if (data.statusCode === 200) + MiniFileMgr.readFile(data.tempFilePath, encoding, callBack, readyUrl, isSaveFile, fileType, isAutoClear); + else if (data.statusCode === 403) { + callBack != null && callBack.runWith([0, fileUrl]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + downloadTask.onProgressUpdate(function (data) { + callBack != null && callBack.runWith([2, data.progress]); + }); + } + static readFile(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + filePath = Laya.URL.getAdptedFilePath(filePath); + MiniFileMgr.fs.readFile({ filePath: filePath, encoding: encoding, success: function (data) { + if (filePath.indexOf(VVMiniAdapter.window.qg.env.USER_DATA_PATH) == -1 && (filePath.indexOf("http://") != -1 || filePath.indexOf("https://") != -1)) { + if (VVMiniAdapter.autoCacheFile || isSaveFile) { + if (!data.data) + data.data = data.text; + callBack != null && callBack.runWith([0, data]); + MiniFileMgr.copyTOCache(filePath, readyUrl, null, encoding, isAutoClear); + } + else { + if (!data.data) + data.data = data.text; + callBack != null && callBack.runWith([0, data]); + } + } + else { + if (!data.data) + data.data = data.text; + callBack != null && callBack.runWith([0, data]); + } + }, fail: function (data) { + if (data) + callBack != null && callBack.runWith([1, data]); + } }); + } + static downOtherFiles(fileUrl, callBack = null, readyUrl = "", isSaveFile = false, isAutoClear = true) { + MiniFileMgr.wxdown({ url: fileUrl, success: function (data) { + if (data.errCode == 0) + data.statusCode = 200; + if (data.statusCode === 200) { + if ((VVMiniAdapter.autoCacheFile || isSaveFile) && readyUrl.indexOf(".php") == -1) { + callBack != null && callBack.runWith([0, data.tempFilePath]); + MiniFileMgr.copyTOCache(data.tempFilePath, readyUrl, null, "", isAutoClear); + } + else + callBack != null && callBack.runWith([0, data.tempFilePath]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static copyFile(src, dest, complete = null) { + MiniFileMgr.fs.copyFile({ + srcPath: src, + destPath: dest, + success: function () { + complete && complete.runWith(0); + }, + fail: function (err) { + complete && complete.runWith([1, err]); + } + }); + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + if (VVMiniAdapter.window.navigator.userAgent.indexOf('VVGame') < 0) { + Laya.Laya.loader.load(fileUrl, callBack); + } + else { + if (fileType == Laya.Loader.IMAGE || fileType == Laya.Loader.SOUND) + MiniFileMgr.downOtherFiles(VVMiniAdapter.safeEncodeURI(fileUrl), callBack, fileUrl, true, false); + else + MiniFileMgr.downFiles(VVMiniAdapter.safeEncodeURI(fileUrl), encoding, callBack, fileUrl, true, fileType, false); + } + } + static copyTOCache(tempFilePath, readyUrl, callBack, encoding = "", isAutoClear = true) { + var temp = tempFilePath.split("/"); + var tempFileName = temp[temp.length - 1]; + var fileurlkey = readyUrl; + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fakeObj[fileurlkey] = { md5: tempFileName, readyUrl: readyUrl, size: 0, times: Laya.Browser.now(), encoding: encoding, tempFilePath: tempFilePath }; + var totalSize = VVMiniAdapter.sizeLimit; + var chaSize = 4 * 1024 * 1024; + var fileUseSize = MiniFileMgr.getCacheUseSize(); + if (fileObj) { + if (fileObj.readyUrl != readyUrl) { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if (data.length) + data.size = data.length; + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > VVMiniAdapter.minClearSize) + VVMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.deleteFile(tempFilePath, readyUrl, callBack, encoding, data.size); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + else + callBack != null && callBack.runWith([0]); + } + else { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if (data.length) + data.size = data.length; + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > VVMiniAdapter.minClearSize) + VVMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.fs.copyFile({ srcPath: tempFilePath, destPath: saveFilePath, success: function (data2) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, data.size); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + } + static onClearCacheRes() { + var memSize = VVMiniAdapter.minClearSize; + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + MiniFileMgr.sortOn(tempFileListArr, "times", MiniFileMgr.NUMERIC); + var clearSize = 0; + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + if (clearSize >= memSize) + break; + clearSize += fileObj.size; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + } + static sortOn(array, name, options = 0) { + if (options == MiniFileMgr.NUMERIC) + return array.sort(function (a, b) { return a[name] - b[name]; }); + if (options == (MiniFileMgr.NUMERIC | MiniFileMgr.DESCENDING)) + return array.sort(function (a, b) { return b[name] - a[name]; }); + return array.sort(function (a, b) { return a[name] - b[name]; }); + } + static getFileNativePath(fileName) { + return MiniFileMgr.fileNativeDir + "/" + fileName; + } + static deleteFile(tempFileName, readyUrl = "", callBack = null, encoding = "", fileSize = 0) { + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var deleteFileUrl = MiniFileMgr.getFileNativePath(fileObj.md5); + MiniFileMgr.fs.unlink({ filePath: deleteFileUrl, success: function (data) { + if (tempFileName != "") { + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fs.copyFile({ srcPath: tempFileName, destPath: saveFilePath, success: function (data) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, fileSize); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + else { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, false, encoding, callBack, fileSize); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static deleteAll() { + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj.fileUsedSize) { + MiniFileMgr.filesListObj.fileUsedSize = 0; + } + MiniFileMgr.writeFilesList("", JSON.stringify({}), false); + } + static onSaveFile(readyUrl, md5Name, isAdd = true, encoding = "", callBack = null, fileSize = 0) { + var fileurlkey = readyUrl; + if (MiniFileMgr.filesListObj['fileUsedSize'] == null) + MiniFileMgr.filesListObj['fileUsedSize'] = 0; + if (isAdd) { + var fileNativeName = MiniFileMgr.getFileNativePath(md5Name); + MiniFileMgr.filesListObj[fileurlkey] = { md5: md5Name, readyUrl: readyUrl, size: fileSize, times: Laya.Browser.now(), encoding: encoding, tempFilePath: fileNativeName }; + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) + fileSize; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), true); + callBack != null && callBack.runWith([0]); + } + else { + if (MiniFileMgr.filesListObj[fileurlkey]) { + var deletefileSize = parseInt(MiniFileMgr.filesListObj[fileurlkey].size); + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) - deletefileSize; + if (MiniFileMgr.filesListObj[fileurlkey].md5 == MiniFileMgr.fakeObj[fileurlkey].md5) { + delete MiniFileMgr.fakeObj[fileurlkey]; + } + delete MiniFileMgr.filesListObj[fileurlkey]; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), false); + callBack != null && callBack.runWith([0]); + } + } + } + static writeFilesList(fileurlkey, filesListStr, isAdd) { + var listFilesPath = MiniFileMgr.fileNativeDir + "/" + MiniFileMgr.fileListName; + MiniFileMgr.fs.writeFile({ filePath: listFilesPath, encoding: 'utf8', data: filesListStr, success: function (data) { + }, fail: function (data) { + } }); + if (!VVMiniAdapter.isZiYu && VVMiniAdapter.isPosMsgYu && VVMiniAdapter.window.qg.postMessage) { + VVMiniAdapter.window.qg.postMessage({ url: fileurlkey, data: MiniFileMgr.filesListObj[fileurlkey], isLoad: "filenative", isAdd: isAdd }); + } + } + static getCacheUseSize() { + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj['fileUsedSize']) + return MiniFileMgr.filesListObj['fileUsedSize']; + return 0; + } + static getCacheList(dirPath, cb) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(dirPath); + } + catch (err) { + stat = null; + } + if (stat) { + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", cb); + } + else { + MiniFileMgr.fs.mkdirSync(dirPath, true); + cb && cb.runWith([1]); + } + } + static existDir(dirPath, callBack) { + MiniFileMgr.fs.mkdir({ dirPath: dirPath, success: function (data) { + callBack != null && callBack.runWith([0, { data: JSON.stringify({}) }]); + }, fail: function (data2, code) { + if (code == 300) { + var data = {}; + data.errMsg = "file already exists"; + } + if (data.errMsg.indexOf("file already exists") != -1) + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", callBack); + else + callBack != null && callBack.runWith([1, data]); + } }); + } + static readSync(filePath, encoding = "utf8", callBack = null, readyUrl = "") { + var fileUrl = MiniFileMgr.getFileNativePath(filePath); + var filesListStr; + try { + filesListStr = MiniFileMgr.fs.readFileSync(fileUrl, encoding); + if (filesListStr.errMsg && filesListStr.errMsg.indexOf("No such file or directory") != -1) { + filesListStr = JSON.stringify({}); + } + callBack != null && callBack.runWith([0, { data: filesListStr.data }]); + } + catch (error) { + callBack != null && callBack.runWith([1]); + } + } + static setNativeFileDir(value) { + MiniFileMgr.fileNativeDir = VVMiniAdapter.window.qg.env.USER_DATA_PATH + value; + } + } + MiniFileMgr.fs = window.qg.getFileSystemManager(); + MiniFileMgr.wxdown = window.qg.download; + MiniFileMgr.filesListObj = {}; + MiniFileMgr.fakeObj = {}; + MiniFileMgr.fileListName = "layaairfiles.txt"; + MiniFileMgr.ziyuFileData = {}; + MiniFileMgr.ziyuFileTextureData = {}; + MiniFileMgr.loadPath = ""; + MiniFileMgr.DESCENDING = 2; + MiniFileMgr.NUMERIC = 16; + + class MiniSoundChannel extends Laya.SoundChannel { + constructor(audio, miniSound) { + super(); + this._audio = audio; + this._miniSound = miniSound; + this._onEnd = MiniSoundChannel.bindToThis(this.__onEnd, this); + audio.onEnded(this._onEnd); + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + __onEnd() { + if (this.loops == 1) { + if (this.completeHandler) { + Laya.Laya.systemTimer.once(10, this, this.__runComplete, [this.completeHandler], false); + this.completeHandler = null; + } + this.stop(); + this.event(Laya.Event.COMPLETE); + return; + } + if (this.loops > 0) { + this.loops--; + } + this.startTime = 0; + this.play(); + } + play() { + this.isStopped = false; + Laya.SoundManager.addChannel(this); + this._audio.play(); + } + set startTime(time) { + if (this._audio) { + this._audio.startTime = time; + } + } + set autoplay(value) { + this._audio.autoplay = value; + } + get autoplay() { + return this._audio.autoplay; + } + get position() { + if (!this._audio) + return 0; + return this._audio.currentTime; + } + get duration() { + if (!this._audio) + return 0; + return this._audio.duration; + } + stop() { + this.isStopped = true; + Laya.SoundManager.removeChannel(this); + this.completeHandler = null; + if (!this._audio) + return; + this._audio.stop(); + if (!this.loop) { + this._audio.offEnded(null); + this._miniSound.dispose(); + this._audio = null; + this._miniSound = null; + this._onEnd = null; + } + } + pause() { + this.isStopped = true; + this._audio.pause(); + } + get loop() { + return this._audio.loop; + } + set loop(value) { + this._audio.loop = value; + } + resume() { + if (!this._audio) + return; + this.isStopped = false; + Laya.SoundManager.addChannel(this); + this._audio.play(); + } + set volume(v) { + if (!this._audio) + return; + this._audio.volume = v; + } + get volume() { + if (!this._audio) + return 1; + return this._audio.volume; + } + } + + class MiniSound extends Laya.EventDispatcher { + constructor() { + super(); + this.loaded = false; + } + static _createSound() { + MiniSound._id++; + return VVMiniAdapter.window.qg.createInnerAudioContext(); + } + load(url) { + if (!MiniSound._musicAudio) + MiniSound._musicAudio = MiniSound._createSound(); + if (!MiniFileMgr.isLocalNativeFile(url)) { + url = Laya.URL.formatURL(url); + } + else { + if (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + if (tempStr != "") + url = url.split(tempStr)[1]; + } + } + } + this.url = url; + this.readyUrl = url; + if (MiniSound._audioCache[this.readyUrl]) { + this.event(Laya.Event.COMPLETE); + return; + } + if (VVMiniAdapter.autoCacheFile && MiniFileMgr.getFileInfo(url)) { + this.onDownLoadCallBack(url, 0); + } + else { + if (!VVMiniAdapter.autoCacheFile) { + this.onDownLoadCallBack(url, 0); + } + else { + if (MiniFileMgr.isLocalNativeFile(url)) { + tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + if (VVMiniAdapter.subNativeFiles && VVMiniAdapter.subNativeheads.length == 0) { + for (var key in VVMiniAdapter.subNativeFiles) { + var tempArr = VVMiniAdapter.subNativeFiles[key]; + VVMiniAdapter.subNativeheads = VVMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + VVMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (VVMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && VVMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = VVMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + this.onDownLoadCallBack(url, 0); + } + else { + if (!MiniFileMgr.isLocalNativeFile(url) && (url.indexOf("http://") == -1 && url.indexOf("https://") == -1) || (url.indexOf("http://usr/") != -1)) { + this.onDownLoadCallBack(url, 0); + } + else { + MiniFileMgr.downOtherFiles(VVMiniAdapter.safeEncodeURI(url), Laya.Handler.create(this, this.onDownLoadCallBack, [url]), url); + } + } + } + } + } + onDownLoadCallBack(sourceUrl, errorCode, tempFilePath = null) { + if (!errorCode) { + var fileNativeUrl; + if (VVMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = sourceUrl; + if (tempStr != "" && (sourceUrl.indexOf("http://") != -1 || sourceUrl.indexOf("https://") != -1)) + fileNativeUrl = sourceUrl.split(tempStr)[1]; + if (!fileNativeUrl) { + fileNativeUrl = tempUrl; + } + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + var fileMd5Name = fileObj.md5; + fileNativeUrl = MiniFileMgr.getFileNativePath(fileMd5Name); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + if (this.url != Laya.SoundManager._bgMusic) { + this._sound = MiniSound._createSound(); + this._sound.src = this.url = fileNativeUrl; + } + else { + this._sound = MiniSound._musicAudio; + this._sound.src = this.url = fileNativeUrl; + } + } + else { + if (this.url != Laya.SoundManager._bgMusic) { + this._sound = MiniSound._createSound(); + this._sound.src = sourceUrl; + } + else { + this._sound = MiniSound._musicAudio; + this._sound.src = sourceUrl; + } + } + if (this._sound.onCanplay) { + this._sound.onCanplay(MiniSound.bindToThis(this.onCanPlay, this)); + this._sound.onError(MiniSound.bindToThis(this.onError, this)); + } + else { + Laya.Laya.timer.clear(this, this.onCheckComplete); + Laya.Laya.timer.frameLoop(2, this, this.onCheckComplete); + } + } + else { + this.event(Laya.Event.ERROR); + } + } + onCheckComplete() { + if (this._sound && this._sound.duration && this._sound.duration > 0) { + this.onCanPlay(); + } + Laya.Laya.timer.clear(this, this.onCheckComplete); + } + onError(error) { + try { + console.log("-----1---------------minisound-----id:" + MiniSound._id); + console.log(error); + } + catch (error) { + console.log("-----2---------------minisound-----id:" + MiniSound._id); + console.log(error); + } + this.event(Laya.Event.ERROR); + this._sound.offError(null); + } + onCanPlay() { + this.loaded = true; + this.event(Laya.Event.COMPLETE); + if (this._sound && this._sound.offCanplay) { + this._sound.offCanplay(null); + } + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + play(startTime = 0, loops = 0) { + var tSound; + if (this.url == Laya.SoundManager._bgMusic) { + if (!MiniSound._musicAudio) + MiniSound._musicAudio = MiniSound._createSound(); + tSound = MiniSound._musicAudio; + } + else { + if (MiniSound._audioCache[this.readyUrl]) { + tSound = MiniSound._audioCache[this.readyUrl]._sound; + } + else { + tSound = MiniSound._createSound(); + } + } + if (!tSound) + return null; + if (VVMiniAdapter.autoCacheFile && MiniFileMgr.getFileInfo(this.url)) { + var fileObj = MiniFileMgr.getFileInfo(this.url); + var fileMd5Name = fileObj.md5; + tSound.src = this.url = MiniFileMgr.getFileNativePath(fileMd5Name); + } + else { + tSound.src = VVMiniAdapter.safeEncodeURI(this.url); + } + var channel = new MiniSoundChannel(tSound, this); + channel.url = this.url; + channel.loops = loops; + channel.loop = (loops === 0 ? true : false); + channel.startTime = startTime; + channel.play(); + Laya.SoundManager.addChannel(channel); + return channel; + } + get duration() { + return this._sound.duration; + } + dispose() { + var ad = MiniSound._audioCache[this.readyUrl]; + if (ad) { + ad.src = ""; + if (ad._sound) { + ad._sound.destroy(); + ad._sound = null; + ad = null; + } + delete MiniSound._audioCache[this.readyUrl]; + } + if (this._sound) { + this._sound.destroy(); + this._sound = null; + this.readyUrl = this.url = null; + } + } + } + MiniSound._id = 0; + MiniSound._audioCache = {}; + + class MiniInput { + constructor() { + } + static _createInputElement() { + Laya.Input['_initInput'](Laya.Input['area'] = Laya.Browser.createElement("textarea")); + Laya.Input['_initInput'](Laya.Input['input'] = Laya.Browser.createElement("input")); + Laya.Input['inputContainer'] = Laya.Browser.createElement("div"); + Laya.Input['inputContainer'].style.position = "absolute"; + Laya.Input['inputContainer'].style.zIndex = 1E5; + Laya.Browser.container.appendChild(Laya.Input['inputContainer']); + Laya.Laya.stage.on("resize", null, MiniInput._onStageResize); + VVMiniAdapter.window.qg.onWindowResize && VVMiniAdapter.window.qg.onWindowResize(function (res) { + }); + Laya.SoundManager._soundClass = MiniSound; + Laya.SoundManager._musicClass = MiniSound; + Laya.Browser.onAndroid = true; + Laya.Browser.onIPhone = false; + Laya.Browser.onIOS = false; + Laya.Browser.onIPad = false; + } + static _onStageResize() { + var ts = Laya.Laya.stage._canvasTransform.identity(); + ts.scale((Laya.Browser.width / Laya.Render.canvas.width / Laya.Browser.pixelRatio), Laya.Browser.height / Laya.Render.canvas.height / Laya.Browser.pixelRatio); + } + static wxinputFocus(e) { + var _inputTarget = Laya.Input['inputElement'].target; + if (_inputTarget && !_inputTarget.editable) { + return; + } + VVMiniAdapter.window.qg.offKeyboardConfirm(); + VVMiniAdapter.window.qg.offKeyboardInput(); + VVMiniAdapter.window.qg.showKeyboard({ defaultValue: _inputTarget.text, maxLength: _inputTarget.maxChars, multiple: _inputTarget.multiline, confirmHold: true, confirmType: _inputTarget["confirmType"] || 'done', success: function (res) { + }, fail: function (res) { + } }); + VVMiniAdapter.window.qg.onKeyboardConfirm(function (res) { + var str = res ? res.value : ""; + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + MiniInput.inputEnter(); + _inputTarget.event("confirm"); + }); + VVMiniAdapter.window.qg.onKeyboardInput(function (res) { + var str = res ? res.value : ""; + if (!_inputTarget.multiline) { + if (str.indexOf("\n") != -1) { + MiniInput.inputEnter(); + return; + } + } + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + }); + } + static inputEnter() { + Laya.Input['inputElement'].target.focus = false; + } + static wxinputblur() { + MiniInput.hideKeyboard(); + } + static hideKeyboard() { + VVMiniAdapter.window.qg.offKeyboardConfirm(); + VVMiniAdapter.window.qg.offKeyboardInput(); + VVMiniAdapter.window.qg.hideKeyboard({ success: function (res) { + console.log('隐藏键盘'); + }, fail: function (res) { + console.log("隐藏键盘出错:" + (res ? res.errMsg : "")); + } }); + } + } + + class MiniLoader extends Laya.EventDispatcher { + constructor() { + super(); + } + _loadResourceFilter(type, url) { + var thisLoader = this; + this.sourceUrl = Laya.URL.formatURL(url); + if (MiniFileMgr.isNetFile(url)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (VVMiniAdapter.subNativeFiles && VVMiniAdapter.subNativeheads.length == 0) { + for (var key in VVMiniAdapter.subNativeFiles) { + var tempArr = VVMiniAdapter.subNativeFiles[key]; + VVMiniAdapter.subNativeheads = VVMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + VVMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (VVMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && VVMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = VVMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + switch (type) { + case Laya.Loader.IMAGE: + case "htmlimage": + case "nativeimage": + MiniLoader._transformImgUrl(url, type, thisLoader); + break; + case Laya.Loader.SOUND: + thisLoader._loadSound(url); + break; + default: + thisLoader._loadResource(type, url); + } + } + _loadSound(url) { + var thisLoader = this; + if (!VVMiniAdapter.autoCacheFile) { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + else { + var tempurl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downOtherFiles(VVMiniAdapter.safeEncodeURI(tempurl), Laya.Handler.create(MiniLoader, MiniLoader.onDownLoadCallBack, [tempurl, thisLoader]), tempurl); + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + } + static onDownLoadCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = null) { + if (!errorCode) { + var fileNativeUrl; + if (VVMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + fileNativeUrl = sourceUrl; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + } + else { + fileNativeUrl = Laya.URL.formatURL(sourceUrl); + } + sourceUrl = fileNativeUrl; + var sound = (new Laya.SoundManager._soundClass()); + sound.load(VVMiniAdapter.safeEncodeURI(sourceUrl)); + thisLoader.onLoaded(sound); + } + else { + thisLoader.event(Laya.Event.ERROR, "Load sound failed"); + } + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + complete(data) { + if (data instanceof Laya.Resource) { + data._setCreateURL(this.sourceUrl); + } + else if ((data instanceof Laya.Texture) && (data.bitmap instanceof Laya.Resource)) { + data.bitmap._setCreateURL(this.sourceUrl); + } + this.originComplete(data); + } + _loadHttpRequestWhat(url, contentType) { + var thisLoader = this; + var encoding = VVMiniAdapter.getUrlEncode(url, contentType); + if (Laya.Loader.preLoadedMap[url]) + thisLoader.onLoaded(Laya.Loader.preLoadedMap[url]); + else { + var tempurl = Laya.URL.formatURL(url); + if (!VVMiniAdapter.AutoCacheDownFile) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downFiles(VVMiniAdapter.safeEncodeURI(tempurl), encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), tempurl, true); + } + else + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + else { + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downFiles(VVMiniAdapter.safeEncodeURI(tempurl), encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), tempurl, true); + } + else { + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + else { + var tempUrl = url; + var fileObj = MiniFileMgr.getFileInfo(tempurl); + if (fileObj && fileObj.md5) { + tempUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + MiniFileMgr.readFile(tempUrl, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + } + } + static onReadNativeCallBack(url, type = null, thisLoader = null, errorCode = 0, data = null) { + if (!errorCode) { + var tempData; + if (type == Laya.Loader.JSON || type == Laya.Loader.ATLAS || type == Laya.Loader.PREFAB || type == Laya.Loader.PLF) { + tempData = VVMiniAdapter.getJson(data.data); + } + else if (type == Laya.Loader.XML) { + tempData = Laya.Utils.parseXMLFromString(data.data); + } + else { + tempData = data.data; + } + if (!VVMiniAdapter.isZiYu && VVMiniAdapter.isPosMsgYu && type != Laya.Loader.BUFFER && VVMiniAdapter.window.qg.postMessage) { + VVMiniAdapter.window.qg.postMessage({ url: url, data: tempData, isLoad: "filedata" }); + } + thisLoader.onLoaded(tempData); + } + else if (errorCode == 1) { + thisLoader._loadHttpRequest(url, type, thisLoader, thisLoader.onLoaded, thisLoader, thisLoader.onProgress, thisLoader, thisLoader.onError); + } + } + static _transformImgUrl(url, type, thisLoader) { + if (VVMiniAdapter.isZiYu || MiniFileMgr.isLocalNativeFile(url)) { + thisLoader._loadImage(url, false); + return; + } + if (!VVMiniAdapter.autoCacheFile) { + thisLoader._loadImage(VVMiniAdapter.safeEncodeURI(url)); + } + else { + var tempUrl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempUrl)) { + if (MiniFileMgr.isNetFile(tempUrl)) { + MiniFileMgr.downOtherFiles(VVMiniAdapter.safeEncodeURI(tempUrl), new Laya.Handler(MiniLoader, MiniLoader.onDownImgCallBack, [url, thisLoader]), tempUrl); + } + else { + MiniLoader.onCreateImage(url, thisLoader, true); + } + } + else { + MiniLoader.onCreateImage(url, thisLoader); + } + } + } + static onDownImgCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = "") { + if (!errorCode) + MiniLoader.onCreateImage(sourceUrl, thisLoader, false, tempFilePath); + else { + thisLoader.onError(null); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (VVMiniAdapter.autoCacheFile) { + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + var fileObj = MiniFileMgr.getFileInfo(Laya.URL.formatURL(sourceUrl)); + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + } + else if (VVMiniAdapter.isZiYu) { + var tempUrl = Laya.URL.formatURL(sourceUrl); + if (MiniFileMgr.ziyuFileTextureData[tempUrl]) { + fileNativeUrl = MiniFileMgr.ziyuFileTextureData[tempUrl]; + } + else + fileNativeUrl = sourceUrl; + } + else + fileNativeUrl = sourceUrl; + } + else { + if (!isLocal) + fileNativeUrl = tempFilePath; + else + fileNativeUrl = sourceUrl; + } + thisLoader._loadImage(fileNativeUrl, false); + } + } + + class VVMiniAdapter { + static getJson(data) { + return JSON.parse(data); + } + static enable() { + VVMiniAdapter.init(Laya.Laya.isWXPosMsg, Laya.Laya.isWXOpenDataContext); + } + static init(isPosMsg = false, isSon = false) { + if (VVMiniAdapter._inited) + return; + VVMiniAdapter._inited = true; + VVMiniAdapter.window = window; + if (!VVMiniAdapter.window.hasOwnProperty("qg")) + return; + if (VVMiniAdapter.window.navigator.userAgent.indexOf('VVGame') < 0) + return; + VVMiniAdapter.isZiYu = isSon; + VVMiniAdapter.isPosMsgYu = isPosMsg; + VVMiniAdapter.EnvConfig = {}; + if (!VVMiniAdapter.window.qg.env) { + VVMiniAdapter.window.qg.env = {}; + VVMiniAdapter.window.qg.env.USER_DATA_PATH = "internal://files"; + } + if (!VVMiniAdapter.isZiYu) { + MiniFileMgr.setNativeFileDir("/layaairGame"); + MiniFileMgr.getCacheList(MiniFileMgr.fileNativeDir, Laya.Handler.create(VVMiniAdapter, VVMiniAdapter.onMkdirCallBack)); + } + VVMiniAdapter.systemInfo = VVMiniAdapter.window.qg.getSystemInfoSync(); + VVMiniAdapter.window.focus = function () { + }; + Laya.Laya['_getUrlPath'] = function () { + return ""; + }; + VVMiniAdapter.window.logtime = function (str) { + }; + VVMiniAdapter.window.alertTimeLog = function (str) { + }; + VVMiniAdapter.window.resetShareInfo = function () { + }; + VVMiniAdapter.window.CanvasRenderingContext2D = function () { + }; + VVMiniAdapter.window.CanvasRenderingContext2D.prototype = VVMiniAdapter.window.qg.createCanvas().getContext('2d').__proto__; + VVMiniAdapter.window.document.body.appendChild = function () { + }; + Laya.HttpRequest._urlEncode = VVMiniAdapter.safeEncodeURI; + VVMiniAdapter.EnvConfig.pixelRatioInt = 0; + Laya.Browser["_pixelRatio"] = VVMiniAdapter.pixelRatio(); + VVMiniAdapter._preCreateElement = Laya.Browser.createElement; + Laya.Browser["createElement"] = VVMiniAdapter.createElement; + Laya.RunDriver.createShaderCondition = VVMiniAdapter.createShaderCondition; + Laya.Utils['parseXMLFromString'] = VVMiniAdapter.parseXMLFromString; + Laya.Input['_createInputElement'] = MiniInput['_createInputElement']; + if (!window.ImageData) { + window.ImageData = ImageDataPolyfill; + } + Laya.Loader.prototype._loadResourceFilter = MiniLoader.prototype._loadResourceFilter; + Laya.Loader.prototype._loadSound = MiniLoader.prototype._loadSound; + Laya.Loader.prototype.originComplete = Laya.Loader.prototype.complete; + Laya.Loader.prototype.complete = MiniLoader.prototype.complete; + Laya.Loader.prototype._loadHttpRequestWhat = MiniLoader.prototype._loadHttpRequestWhat; + VVMiniAdapter.window.qg.onMessage && VVMiniAdapter.window.qg.onMessage(VVMiniAdapter._onMessage); + Laya.Config.useRetinalCanvas = true; + } + static _onMessage(data) { + switch (data.type) { + case "changeMatrix": + Laya.Laya.stage.transform.identity(); + Laya.Laya.stage._width = data.w; + Laya.Laya.stage._height = data.h; + Laya.Laya.stage._canvasTransform = new Laya.Matrix(data.a, data.b, data.c, data.d, data.tx, data.ty); + break; + case "display": + Laya.Laya.stage.frameRate = data.rate || Laya.Stage.FRAME_FAST; + break; + case "undisplay": + Laya.Laya.stage.frameRate = Laya.Stage.FRAME_SLEEP; + break; + } + if (data['isLoad'] == "opendatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + else if (data['isLoad'] == "openJsondatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + } + } + else if (data['isLoad'] == "openJsondatacontextPic") { + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + static getUrlEncode(url, type) { + if (type == "arraybuffer") + return "binary"; + return "utf8"; + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + var fileObj = MiniFileMgr.getFileInfo(fileUrl); + if (!fileObj) + MiniFileMgr.downLoadFile(fileUrl, fileType, callBack, encoding); + else { + callBack != null && callBack.runWith([0]); + } + } + static remove(fileUrl, callBack = null) { + MiniFileMgr.deleteFile("", fileUrl, callBack, "", 0); + } + static removeAll() { + MiniFileMgr.deleteAll(); + } + static hasNativeFile(fileUrl) { + return MiniFileMgr.isLocalNativeFile(fileUrl); + } + static getFileInfo(fileUrl) { + return MiniFileMgr.getFileInfo(fileUrl); + } + static getFileList() { + return MiniFileMgr.filesListObj; + } + static exitMiniProgram() { + VVMiniAdapter.window.qg.exitMiniProgram(); + } + static onMkdirCallBack(errorCode, data) { + if (!errorCode) { + MiniFileMgr.filesListObj = JSON.parse(data.data); + MiniFileMgr.fakeObj = JSON.parse(data.data) || {}; + } + else { + MiniFileMgr.fakeObj = {}; + MiniFileMgr.filesListObj = {}; + } + let files = MiniFileMgr.fs.readdirSync(MiniFileMgr.fileNativeDir); + if (!files || !files.length) + return; + var tempMd5ListObj = {}; + var fileObj; + for (let key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") { + fileObj = MiniFileMgr.filesListObj[key]; + tempMd5ListObj[fileObj.md5] = fileObj.readyUrl; + } + } + var fileName; + for (let i = 0, sz = files.length; i < sz; i++) { + fileName = files[i]; + if (fileName == MiniFileMgr.fileListName) + continue; + if (!tempMd5ListObj[fileName]) { + let deleteFileUrl = MiniFileMgr.getFileNativePath(fileName); + MiniFileMgr.fs.unlink({ + filePath: deleteFileUrl, + success: function (data) { + console.log("删除无引用的磁盘文件:" + fileName); + } + }); + } + delete tempMd5ListObj[fileName]; + } + for (let key in tempMd5ListObj) { + delete MiniFileMgr.filesListObj[tempMd5ListObj[key]]; + delete MiniFileMgr.fakeObj[tempMd5ListObj[key]]; + console.log("删除错误记录:", tempMd5ListObj[key]); + } + } + static pixelRatio() { + if (!VVMiniAdapter.EnvConfig.pixelRatioInt) { + try { + VVMiniAdapter.systemInfo.pixelRatio = VVMiniAdapter.window.devicePixelRatio; + VVMiniAdapter.EnvConfig.pixelRatioInt = VVMiniAdapter.systemInfo.pixelRatio; + return VVMiniAdapter.systemInfo.pixelRatio; + } + catch (error) { + } + } + return VVMiniAdapter.EnvConfig.pixelRatioInt; + } + static createElement(type) { + if (type == "canvas") { + var _source; + if (VVMiniAdapter.idx == 1) { + if (VVMiniAdapter.isZiYu) { + _source = {}; + _source.style = {}; + } + else { + _source = document.getElementById("canvas"); + } + } + else { + _source = VVMiniAdapter.window.qg.createCanvas(); + } + VVMiniAdapter.idx++; + return _source; + } + else if (type == "textarea" || type == "input") { + return VVMiniAdapter.onCreateInput(type); + } + else if (type == "div") { + var node = VVMiniAdapter._preCreateElement(type); + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + else { + return VVMiniAdapter._preCreateElement(type); + } + } + static onCreateInput(type) { + var node = VVMiniAdapter._preCreateElement(type); + node.focus = MiniInput.wxinputFocus; + node.blur = MiniInput.wxinputblur; + node.style = {}; + node.value = 0; + node.parentElement = {}; + node.placeholder = {}; + node.type = {}; + node.setColor = function (value) { + }; + node.setType = function (value) { + }; + node.setFontFace = function (value) { + }; + node.addEventListener = function (value) { + }; + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + static createShaderCondition(conditionScript) { + var func = function () { + return this[conditionScript.replace("this.", "")]; + }; + return func; + } + static sendAtlasToOpenDataContext(url) { + if (!VVMiniAdapter.isZiYu) { + var atlasJson = Laya.Loader.getRes(Laya.URL.formatURL(url)); + if (atlasJson) { + var textureArr = atlasJson.meta.image.split(","); + if (atlasJson.meta && atlasJson.meta.image) { + var toloadPics = atlasJson.meta.image.split(","); + var split = url.indexOf("/") >= 0 ? "/" : "\\"; + var idx = url.lastIndexOf(split); + var folderPath = idx >= 0 ? url.substr(0, idx + 1) : ""; + for (var i = 0, len = toloadPics.length; i < len; i++) { + toloadPics[i] = folderPath + toloadPics[i]; + } + } + else { + toloadPics = [url.replace(".json", ".png")]; + } + for (i = 0; i < toloadPics.length; i++) { + var tempAtlasPngUrl = toloadPics[i]; + VVMiniAdapter.postInfoToContext(url, tempAtlasPngUrl, atlasJson); + } + } + else { + throw "传递的url没有获取到对应的图集数据信息,请确保图集已经过!"; + } + } + } + static postInfoToContext(url, atlaspngUrl, atlasJson) { + var postData = { "frames": atlasJson.frames, "meta": atlasJson.meta }; + var textureUrl = atlaspngUrl; + var fileObj = MiniFileMgr.getFileInfo(Laya.URL.formatURL(atlaspngUrl)); + if (fileObj) { + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = textureUrl; + } + if (fileNativeUrl) { + VVMiniAdapter.window.qg.postMessage({ url: url, atlasdata: postData, imgNativeUrl: fileNativeUrl, imgReadyUrl: textureUrl, isLoad: "opendatacontext" }); + } + else { + throw "获取图集的磁盘url路径不存在!"; + } + } + static sendSinglePicToOpenDataContext(url) { + var tempTextureUrl = Laya.URL.formatURL(url); + var fileObj = MiniFileMgr.getFileInfo(tempTextureUrl); + if (fileObj) { + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + url = tempTextureUrl; + } + else { + fileNativeUrl = url; + } + if (fileNativeUrl) { + VVMiniAdapter.window.qg.postMessage({ url: url, imgNativeUrl: fileNativeUrl, imgReadyUrl: url, isLoad: "openJsondatacontextPic" }); + } + else { + throw "获取图集的磁盘url路径不存在!"; + } + } + static sendJsonDataToDataContext(url) { + if (!VVMiniAdapter.isZiYu) { + var atlasJson = Laya.Loader.getRes(url); + if (atlasJson) { + VVMiniAdapter.window.qg.postMessage({ url: url, atlasdata: atlasJson, isLoad: "openJsondatacontext" }); + } + else { + throw "传递的url没有获取到对应的图集数据信息,请确保图集已经过!"; + } + } + } + } + VVMiniAdapter.IGNORE = new RegExp("[-_.!~*'();/?:@&=+$,#%]|[0-9|A-Z|a-z]"); + VVMiniAdapter.safeEncodeURI = function (str) { + var strTemp = ""; + var length = str.length; + for (var i = 0; i < length; i++) { + var word = str[i]; + if (VVMiniAdapter.IGNORE.test(word)) { + strTemp += word; + } + else { + try { + strTemp += encodeURI(word); + } + catch (e) { + console.log("errorInfo", ">>>" + word); + } + } + } + return strTemp; + }; + VVMiniAdapter._inited = false; + VVMiniAdapter.autoCacheFile = true; + VVMiniAdapter.minClearSize = (5 * 1024 * 1024); + VVMiniAdapter.sizeLimit = (50 * 1024 * 1024); + VVMiniAdapter.nativefiles = ["layaNativeDir", "wxlocal"]; + VVMiniAdapter.subNativeheads = []; + VVMiniAdapter.subMaps = []; + VVMiniAdapter.AutoCacheDownFile = false; + VVMiniAdapter.parseXMLFromString = function (value) { + var rst; + value = value.replace(/>\s+<'); + try { + rst = new DOMParser().parseFromString(value, 'text/xml'); + } + catch (error) { + throw "需要引入xml解析库文件"; + } + return rst; + }; + VVMiniAdapter.idx = 1; + + class MiniAccelerator extends Laya.EventDispatcher { + constructor() { + super(); + } + static __init__() { + try { + var Acc; + Acc = Laya.Accelerator; + if (!Acc) + return; + Acc["prototype"]["on"] = MiniAccelerator["prototype"]["on"]; + Acc["prototype"]["off"] = MiniAccelerator["prototype"]["off"]; + } + catch (e) { + } + } + static startListen(callBack) { + MiniAccelerator._callBack = callBack; + if (MiniAccelerator._isListening) + return; + MiniAccelerator._isListening = true; + try { + VVMiniAdapter.window.qg.onAccelerometerChange(MiniAccelerator.onAccelerometerChange); + } + catch (e) { } + } + static stopListen() { + MiniAccelerator._isListening = false; + try { + VVMiniAdapter.window.qg.stopAccelerometer({}); + } + catch (e) { } + } + static onAccelerometerChange(res) { + var e; + e = {}; + e.acceleration = res; + e.accelerationIncludingGravity = res; + e.rotationRate = {}; + if (MiniAccelerator._callBack != null) { + MiniAccelerator._callBack(e); + } + } + on(type, caller, listener, args = null) { + super.on(type, caller, listener, args); + MiniAccelerator.startListen(this["onDeviceOrientationChange"]); + return this; + } + off(type, caller, listener, onceOnly = false) { + if (!this.hasListener(type)) + MiniAccelerator.stopListen(); + return super.off(type, caller, listener, onceOnly); + } + } + MiniAccelerator._isListening = false; + + class MiniImage { + _loadImage(url) { + var thisLoader = this; + if (VVMiniAdapter.isZiYu) { + MiniImage.onCreateImage(url, thisLoader, true); + return; + } + var isTransformUrl; + if (!MiniFileMgr.isLocalNativeFile(url)) { + isTransformUrl = true; + url = Laya.URL.formatURL(url); + } + else { + if (url.indexOf("http://usr/") == -1 && (url.indexOf("http://") != -1 || url.indexOf("https://") != -1)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (VVMiniAdapter.subNativeFiles && VVMiniAdapter.subNativeheads.length == 0) { + for (var key in VVMiniAdapter.subNativeFiles) { + var tempArr = VVMiniAdapter.subNativeFiles[key]; + VVMiniAdapter.subNativeheads = VVMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + VVMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (VVMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && VVMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = VVMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + } + if (!MiniFileMgr.getFileInfo(url)) { + if (url.indexOf('http://usr/') == -1 && (url.indexOf("http://") != -1 || url.indexOf("https://") != -1)) { + if (VVMiniAdapter.isZiYu) { + MiniImage.onCreateImage(url, thisLoader, true); + } + else { + MiniFileMgr.downOtherFiles(url, new Laya.Handler(MiniImage, MiniImage.onDownImgCallBack, [url, thisLoader]), url); + } + } + else + MiniImage.onCreateImage(url, thisLoader, true); + } + else { + MiniImage.onCreateImage(url, thisLoader, !isTransformUrl); + } + } + static onDownImgCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = "") { + if (!errorCode) + MiniImage.onCreateImage(sourceUrl, thisLoader, false, tempFilePath); + else { + thisLoader.onError(null); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (VVMiniAdapter.autoCacheFile) { + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + var fileMd5Name = fileObj.md5; + fileNativeUrl = MiniFileMgr.getFileNativePath(fileMd5Name); + } + } + else if (VVMiniAdapter.isZiYu) { + var tempUrl = Laya.URL.formatURL(sourceUrl); + if (MiniFileMgr.ziyuFileTextureData[tempUrl]) { + fileNativeUrl = MiniFileMgr.ziyuFileTextureData[tempUrl]; + } + else + fileNativeUrl = sourceUrl; + } + else + fileNativeUrl = sourceUrl; + } + else { + if (!isLocal) + fileNativeUrl = tempFilePath; + else + fileNativeUrl = sourceUrl; + } + if (thisLoader._imgCache == null) + thisLoader._imgCache = {}; + var image; + function clear() { + var img = thisLoader._imgCache[fileNativeUrl]; + if (img) { + img.onload = null; + img.onerror = null; + delete thisLoader._imgCache[fileNativeUrl]; + } + } + var onerror = function () { + clear(); + delete MiniFileMgr.fakeObj[sourceUrl]; + delete MiniFileMgr.filesListObj[sourceUrl]; + thisLoader.event(Laya.Event.ERROR, "Load image failed"); + }; + if (thisLoader._type == "nativeimage") { + var onload = function () { + clear(); + thisLoader.onLoaded(image); + }; + image = new Laya.Browser.window.Image(); + image.crossOrigin = ""; + image.onload = onload; + image.onerror = onerror; + image.src = fileNativeUrl; + thisLoader._imgCache[fileNativeUrl] = image; + } + else { + var imageSource = new Laya.Browser.window.Image(); + onload = function () { + image = Laya.HTMLImage.create(imageSource.width, imageSource.height); + image.loadImageSource(imageSource, true); + image._setCreateURL(fileNativeUrl); + clear(); + thisLoader.onLoaded(image); + }; + imageSource.crossOrigin = ""; + imageSource.onload = onload; + imageSource.onerror = onerror; + imageSource.src = fileNativeUrl; + thisLoader._imgCache[fileNativeUrl] = imageSource; + } + } + } + + class MiniLocation { + constructor() { + } + static __init__() { + VVMiniAdapter.window.navigator.geolocation.getCurrentPosition = MiniLocation.getCurrentPosition; + VVMiniAdapter.window.navigator.geolocation.watchPosition = MiniLocation.watchPosition; + VVMiniAdapter.window.navigator.geolocation.clearWatch = MiniLocation.clearWatch; + } + static getCurrentPosition(success = null, error = null, options = null) { + var paramO; + paramO = {}; + paramO.success = getSuccess; + paramO.fail = error; + VVMiniAdapter.window.qg.getLocation(paramO); + function getSuccess(res) { + if (success != null) { + success(res); + } + } + } + static watchPosition(success = null, error = null, options = null) { + MiniLocation._curID++; + var curWatchO; + curWatchO = {}; + curWatchO.success = success; + curWatchO.error = error; + MiniLocation._watchDic[MiniLocation._curID] = curWatchO; + Laya.Laya.systemTimer.loop(1000, null, MiniLocation._myLoop); + return MiniLocation._curID; + } + static clearWatch(id) { + delete MiniLocation._watchDic[id]; + if (!MiniLocation._hasWatch()) { + Laya.Laya.systemTimer.clear(null, MiniLocation._myLoop); + } + } + static _hasWatch() { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key]) + return true; + } + return false; + } + static _myLoop() { + MiniLocation.getCurrentPosition(MiniLocation._mySuccess, MiniLocation._myError); + } + static _mySuccess(res) { + var rst = {}; + rst.coords = res; + rst.timestamp = Laya.Browser.now(); + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].success) { + MiniLocation._watchDic[key].success(rst); + } + } + } + static _myError(res) { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].error) { + MiniLocation._watchDic[key].error(res); + } + } + } + } + MiniLocation._watchDic = {}; + MiniLocation._curID = 0; + + class MiniVideo { + constructor(width = 320, height = 240) { + this.videoend = false; + this.videourl = ""; + this.videoElement = VVMiniAdapter.window.qg.createVideo({ width: width, height: height, autoplay: true }); + } + static __init__() { + } + on(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.onPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.onEnded = this.onEndedFunction.bind(this); + } + this.videoElement.onTimeUpdate = this.onTimeUpdateFunc.bind(this); + } + onTimeUpdateFunc(data) { + this.position = data.position; + this._duration = data.duration; + } + get duration() { + return this._duration; + } + onPlayFunction() { + if (this.videoElement) + this.videoElement.readyState = 200; + console.log("=====视频加载完成========"); + this.onPlayFunc != null && this.onPlayFunc(); + } + onEndedFunction() { + if (!this.videoElement) + return; + this.videoend = true; + console.log("=====视频播放完毕========"); + this.onEndedFunC != null && this.onEndedFunC(); + } + off(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.offPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.offEnded = this.onEndedFunction.bind(this); + } + } + load(url) { + if (!this.videoElement) + return; + this.videoElement.src = url; + } + play() { + if (!this.videoElement) + return; + this.videoend = false; + this.videoElement.play(); + } + pause() { + if (!this.videoElement) + return; + this.videoend = true; + this.videoElement.pause(); + } + get currentTime() { + if (!this.videoElement) + return 0; + return this.videoElement.initialTime; + } + set currentTime(value) { + if (!this.videoElement) + return; + this.videoElement.initialTime = value; + } + get videoWidth() { + if (!this.videoElement) + return 0; + return this.videoElement.width; + } + get videoHeight() { + if (!this.videoElement) + return 0; + return this.videoElement.height; + } + get ended() { + return this.videoend; + } + get loop() { + if (!this.videoElement) + return false; + return this.videoElement.loop; + } + set loop(value) { + if (!this.videoElement) + return; + this.videoElement.loop = value; + } + get playbackRate() { + if (!this.videoElement) + return 0; + return this.videoElement.playbackRate; + } + set playbackRate(value) { + if (!this.videoElement) + return; + this.videoElement.playbackRate = value; + } + get muted() { + if (!this.videoElement) + return false; + return this.videoElement.muted; + } + set muted(value) { + if (!this.videoElement) + return; + this.videoElement.muted = value; + } + get paused() { + if (!this.videoElement) + return false; + return this.videoElement.paused; + } + size(width, height) { + if (!this.videoElement) + return; + this.videoElement.width = width; + this.videoElement.height = height; + } + get x() { + if (!this.videoElement) + return 0; + return this.videoElement.x; + } + set x(value) { + if (!this.videoElement) + return; + this.videoElement.x = value; + } + get y() { + if (!this.videoElement) + return 0; + return this.videoElement.y; + } + set y(value) { + if (!this.videoElement) + return; + this.videoElement.y = value; + } + get currentSrc() { + return this.videoElement.src; + } + destroy() { + if (this.videoElement) + this.videoElement.destroy(); + this.videoElement = null; + this.onEndedFunC = null; + this.onPlayFunc = null; + this.videoend = false; + this.videourl = null; + } + reload() { + if (!this.videoElement) + return; + this.videoElement.src = this.videourl; + } + } + + exports.ImageDataPolyfill = ImageDataPolyfill; + exports.MiniAccelerator = MiniAccelerator; + exports.MiniFileMgr = MiniFileMgr; + exports.MiniImage = MiniImage; + exports.MiniInput = MiniInput; + exports.MiniLoader = MiniLoader; + exports.MiniLocation = MiniLocation; + exports.MiniSound = MiniSound; + exports.MiniSoundChannel = MiniSoundChannel; + exports.MiniVideo = MiniVideo; + exports.VVMiniAdapter = VVMiniAdapter; + +} diff --git a/examples/layaair/frontend/bin/libs/laya.wxmini.js b/examples/layaair/frontend/bin/libs/laya.wxmini.js new file mode 100644 index 0000000..58cd6e3 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.wxmini.js @@ -0,0 +1,1778 @@ +window.wxMiniGame = function (exports, Laya) { + 'use strict'; + + function ImageDataPolyfill() { + let width, height, data; + if (arguments.length == 3) { + if (arguments[0] instanceof Uint8ClampedArray) { + if (arguments[0].length % 4 !== 0) { + throw new Error("Failed to construct 'ImageData': The input data length is not a multiple of 4."); + } + if (arguments[0].length !== arguments[1] * arguments[2] * 4) { + throw new Error("Failed to construct 'ImageData': The input data length is not equal to (4 * width * height)."); + } + else { + data = arguments[0]; + width = arguments[1]; + height = arguments[2]; + } + } + else { + throw new Error("Failed to construct 'ImageData': parameter 1 is not of type 'Uint8ClampedArray'."); + } + } + else if (arguments.length == 2) { + width = arguments[0]; + height = arguments[1]; + data = new Uint8ClampedArray(arguments[0] * arguments[1] * 4); + } + else if (arguments.length < 2) { + throw new Error("Failed to construct 'ImageData': 2 arguments required, but only " + arguments.length + " present."); + } + let imgdata = Laya.Browser.canvas.getContext("2d").getImageData(0, 0, width, height); + for (let i = 0; i < data.length; i += 4) { + imgdata.data[i] = data[i]; + imgdata.data[i + 1] = data[i + 1]; + imgdata.data[i + 2] = data[i + 2]; + imgdata.data[i + 3] = data[i + 3]; + } + return imgdata; + } + + class MiniFileMgr { + static isLocalNativeFile(url) { + for (var i = 0, sz = MiniAdpter.nativefiles.length; i < sz; i++) { + if (url.indexOf(MiniAdpter.nativefiles[i]) != -1) + return true; + } + return false; + } + static isLocalNativeZipFile(url) { + for (var i = 0, sz = MiniAdpter.nativezipfiles.length; i < sz; i++) { + if (url.indexOf(MiniAdpter.nativezipfiles[i]) != -1) + return true; + } + return false; + } + static isNetFile(url) { + return (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) && url.indexOf(MiniAdpter.window.wx.env.USER_DATA_PATH) == -1; + } + static getFileInfo(fileUrl) { + var fileNativePath = fileUrl; + var fileObj = MiniFileMgr.fakeObj[fileNativePath]; + if (fileObj == null) + return null; + else + return fileObj; + } + static read(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "") { + var fileUrl; + if (readyUrl != "" && (readyUrl.indexOf("http://") != -1 || readyUrl.indexOf("https://") != -1)) { + fileUrl = MiniFileMgr.getFileNativePath(filePath); + } + else { + fileUrl = filePath; + } + fileUrl = Laya.URL.getAdptedFilePath(fileUrl); + MiniFileMgr.fs.readFile({ filePath: fileUrl, encoding: encoding, success: function (data) { + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data && readyUrl != "") + MiniFileMgr.downFiles(readyUrl, encoding, callBack, readyUrl, isSaveFile, fileType); + else + callBack != null && callBack.runWith([1]); + } }); + } + static isFile(url) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(url); + } + catch (err) { + return false; + } + return stat.isFile(); + } + static downFiles(fileUrl, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + var downloadTask = MiniFileMgr.down({ url: fileUrl, success: function (data) { + if (data.statusCode === 200) + MiniFileMgr.readFile(data.tempFilePath, encoding, callBack, readyUrl, isSaveFile, fileType, isAutoClear); + else if (data.statusCode === 403) { + callBack != null && callBack.runWith([0, fileUrl]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + downloadTask.onProgressUpdate(function (data) { + callBack != null && callBack.runWith([2, data.progress]); + }); + } + static readFile(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + filePath = Laya.URL.getAdptedFilePath(filePath); + MiniFileMgr.fs.readFile({ filePath: filePath, encoding: encoding, success: function (data) { + if ((filePath.indexOf("http://") != -1 || filePath.indexOf("https://") != -1) && filePath.indexOf(MiniAdpter.window.wx.env.USER_DATA_PATH) == -1) { + if (MiniAdpter.AutoCacheDownFile || isSaveFile) { + callBack != null && callBack.runWith([0, data]); + MiniFileMgr.copyTOCache(filePath, readyUrl, null, encoding, isAutoClear); + } + else + callBack != null && callBack.runWith([0, data]); + } + else + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data) + callBack != null && callBack.runWith([1, data]); + } }); + } + static downOtherFiles(fileUrl, callBack = null, readyUrl = "", isSaveFile = false, isAutoClear = true) { + MiniFileMgr.down({ url: fileUrl, success: function (data) { + if (data.statusCode === 200) { + if ((MiniAdpter.autoCacheFile || isSaveFile) && readyUrl.indexOf("qlogo.cn") == -1 && readyUrl.indexOf(".php") == -1) { + callBack != null && callBack.runWith([0, data.tempFilePath]); + MiniFileMgr.copyTOCache(data.tempFilePath, readyUrl, null, "", isAutoClear); + } + else + callBack != null && callBack.runWith([0, data.tempFilePath]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static copyFile(src, dest, complete = null) { + MiniFileMgr.fs.copyFile({ + srcPath: src, + destPath: dest, + success: function () { + complete && complete.runWith(0); + }, + fail: function (err) { + complete && complete.runWith([1, err]); + } + }); + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + if (window.navigator.userAgent.indexOf('MiniGame') < 0) { + Laya.Laya.loader.load(fileUrl, callBack); + } + else { + if (fileType == Laya.Loader.IMAGE || fileType == Laya.Loader.SOUND) + MiniFileMgr.downOtherFiles(fileUrl, callBack, fileUrl, true, false); + else + MiniFileMgr.downFiles(fileUrl, encoding, callBack, fileUrl, true, fileType, false); + } + } + static copyTOCache(tempFilePath, readyUrl, callBack, encoding = "", isAutoClear = true) { + var temp = tempFilePath.split("/"); + var tempFileName = temp[temp.length - 1]; + var fileurlkey = readyUrl; + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fakeObj[fileurlkey] = { md5: tempFileName, readyUrl: readyUrl, size: 0, times: Laya.Browser.now(), encoding: encoding, tempFilePath: tempFilePath }; + var totalSize = MiniAdpter.sizeLimit; + var chaSize = 4 * 1024 * 1024; + var fileUseSize = MiniFileMgr.getCacheUseSize(); + if (fileObj) { + if (fileObj.readyUrl != readyUrl) { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > MiniAdpter.minClearSize) + MiniAdpter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.deleteFile(tempFilePath, readyUrl, callBack, encoding, data.size); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + else + callBack != null && callBack.runWith([0]); + } + else { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > MiniAdpter.minClearSize) + MiniAdpter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.fs.copyFile({ srcPath: tempFilePath, destPath: saveFilePath, success: function (data2) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, data.size); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + } + static onClearCacheRes() { + var memSize = MiniAdpter.minClearSize; + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + MiniFileMgr.sortOn(tempFileListArr, "times", MiniFileMgr.NUMERIC); + var clearSize = 0; + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + if (clearSize >= memSize) + break; + clearSize += fileObj.size; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + } + static sortOn(array, name, options = 0) { + if (options == MiniFileMgr.NUMERIC) + return array.sort(function (a, b) { return a[name] - b[name]; }); + if (options == (MiniFileMgr.NUMERIC | MiniFileMgr.DESCENDING)) + return array.sort(function (a, b) { return b[name] - a[name]; }); + return array.sort(function (a, b) { return a[name] - b[name]; }); + } + static getFileNativePath(fileName) { + return MiniFileMgr.fileNativeDir + "/" + fileName; + } + static deleteFile(tempFileName, readyUrl = "", callBack = null, encoding = "", fileSize = 0) { + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var deleteFileUrl = MiniFileMgr.getFileNativePath(fileObj.md5); + MiniFileMgr.fs.unlink({ filePath: deleteFileUrl, success: function (data) { + if (tempFileName != "") { + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fs.copyFile({ srcPath: tempFileName, destPath: saveFilePath, success: function (data) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, fileSize); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + else { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, false, encoding, callBack, fileSize); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + if (readyUrl && readyUrl != "" && readyUrl.indexOf(".zip") != -1) { + var nativepath = MiniAdpter.zipHeadFiles[readyUrl]; + if (nativepath) { + try { + MiniFileMgr.fs.rmdirSync(nativepath, true); + } + catch (e) { + console.log("目录:" + nativepath + "delete fail"); + console.log(e); + } + } + } + } + static deleteAll() { + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj.fileUsedSize) { + MiniFileMgr.filesListObj.fileUsedSize = 0; + } + MiniFileMgr.writeFilesList("", JSON.stringify({}), false); + } + static onSaveFile(readyUrl, md5Name, isAdd = true, encoding = "", callBack = null, fileSize = 0) { + var fileurlkey = readyUrl; + if (MiniFileMgr.filesListObj['fileUsedSize'] == null) + MiniFileMgr.filesListObj['fileUsedSize'] = 0; + if (isAdd) { + var fileNativeName = MiniFileMgr.getFileNativePath(md5Name); + MiniFileMgr.filesListObj[fileurlkey] = { md5: md5Name, readyUrl: readyUrl, size: fileSize, times: Laya.Browser.now(), encoding: encoding, tempFilePath: fileNativeName }; + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) + fileSize; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), true); + callBack != null && callBack.runWith([0]); + } + else { + if (MiniFileMgr.filesListObj[fileurlkey]) { + var deletefileSize = parseInt(MiniFileMgr.filesListObj[fileurlkey].size); + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) - deletefileSize; + if (MiniFileMgr.fakeObj[fileurlkey].md5 == MiniFileMgr.filesListObj[fileurlkey].md5) { + delete MiniFileMgr.fakeObj[fileurlkey]; + } + delete MiniFileMgr.filesListObj[fileurlkey]; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), false); + callBack != null && callBack.runWith([0]); + } + } + } + static writeFilesList(fileurlkey, filesListStr, isAdd) { + var listFilesPath = MiniFileMgr.fileNativeDir + "/" + MiniFileMgr.fileListName; + MiniFileMgr.fs.writeFile({ filePath: listFilesPath, encoding: 'utf8', data: filesListStr, success: function (data) { + }, fail: function (data) { + } }); + if (!MiniAdpter.isZiYu && MiniAdpter.isPosMsgYu) { + MiniAdpter.window.wx.postMessage({ url: fileurlkey, data: MiniFileMgr.filesListObj[fileurlkey], isLoad: "filenative", isAdd: isAdd }); + } + } + static getCacheUseSize() { + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj['fileUsedSize']) + return MiniFileMgr.filesListObj['fileUsedSize']; + return 0; + } + static getCacheList(dirPath, cb) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(dirPath); + } + catch (err) { + stat = null; + } + if (stat) { + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", cb); + } + else { + MiniFileMgr.fs.mkdirSync(dirPath, true); + cb && cb.runWith([1]); + } + } + static existDir(dirPath, callBack) { + MiniFileMgr.fs.mkdir({ dirPath: dirPath, success: function (data) { + callBack != null && callBack.runWith([0, { data: JSON.stringify({}) }]); + }, fail: function (data) { + if (data.errMsg.indexOf("file already exists") != -1) + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", callBack); + else + callBack != null && callBack.runWith([1, data]); + } }); + } + static readSync(filePath, encoding = "utf8", callBack = null, readyUrl = "") { + var fileUrl = MiniFileMgr.getFileNativePath(filePath); + var filesListStr; + try { + filesListStr = MiniFileMgr.fs.readFileSync(fileUrl, encoding); + callBack != null && callBack.runWith([0, { data: filesListStr }]); + } + catch (error) { + callBack != null && callBack.runWith([1]); + } + } + static setNativeFileDir(value) { + MiniFileMgr.fileNativeDir = MiniAdpter.window.wx.env.USER_DATA_PATH + value; + } + } + MiniFileMgr.fs = window.wx.getFileSystemManager(); + MiniFileMgr.down = window.wx.downloadFile; + MiniFileMgr.filesListObj = {}; + MiniFileMgr.fakeObj = {}; + MiniFileMgr.fileListName = "layaairfiles.txt"; + MiniFileMgr.ziyuFileData = {}; + MiniFileMgr.ziyuFileTextureData = {}; + MiniFileMgr.loadPath = ""; + MiniFileMgr.DESCENDING = 2; + MiniFileMgr.NUMERIC = 16; + + class MiniSoundChannel extends Laya.SoundChannel { + constructor(sound) { + super(); + this._sound = sound; + this._audio = sound._sound; + this._onCanplay = this.onCanPlay.bind(this); + this._onError = this.onError.bind(this); + this._onEnd = this.__onEnd.bind(this); + this.addEventListener(); + } + addEventListener() { + this._audio.onError(this._onError); + this._audio.onCanplay(this._onCanplay); + } + offEventListener() { + this._audio.offError(this._onError); + this._audio.offCanplay(this._onCanplay); + this._audio.offEnded(this._onEnd); + } + onError(error) { + console.log("-----1---------------minisound-----url:", this.url); + console.log(error); + this.event(Laya.Event.ERROR); + if (!this._audio) + return; + this._sound.dispose(); + this.offEventListener(); + this._sound = this._audio = null; + } + onCanPlay() { + if (!this._audio) + return; + this.event(Laya.Event.COMPLETE); + this.offEventListener(); + this._audio.onEnded(this._onEnd); + if (!this.isStopped) { + this.play(); + } + else { + this.stop(); + } + } + __onEnd() { + if (this.loops == 1) { + if (this.completeHandler) { + Laya.Laya.systemTimer.once(10, this, this.__runComplete, [this.completeHandler], false); + this.completeHandler = null; + } + this.stop(); + this.event(Laya.Event.COMPLETE); + return; + } + if (this.loops > 0) { + this.loops--; + } + this.startTime = 0; + this.play(); + } + play() { + this.isStopped = false; + Laya.SoundManager.addChannel(this); + if (!this._audio) + return; + this._audio.play(); + } + set startTime(time) { + if (!this._audio) + return; + this._audio.startTime = time; + } + set autoplay(value) { + if (!this._audio) + return; + this._audio.autoplay = value; + } + get autoplay() { + if (!this._audio) + return false; + return this._audio.autoplay; + } + get position() { + if (!this._audio) + return 0; + return this._audio.currentTime; + } + get duration() { + if (!this._audio) + return 0; + return this._audio.duration; + } + stop() { + super.stop(); + this.isStopped = true; + Laya.SoundManager.removeChannel(this); + this.completeHandler = null; + if (!this._audio) + return; + this._audio.stop(); + if (!this.loop) { + this.offEventListener(); + this._sound.dispose(); + this._sound = null; + this._audio = null; + } + } + pause() { + this.isStopped = true; + if (!this._audio) + return; + this._audio.pause(); + } + get loop() { + if (!this._audio) + return false; + return this._audio.loop; + } + set loop(value) { + if (!this._audio) + return; + this._audio.loop = value; + } + resume() { + this.isStopped = false; + Laya.SoundManager.addChannel(this); + if (!this._audio) + return; + this._audio.play(); + } + set volume(v) { + if (!this._audio) + return; + this._audio.volume = v; + } + get volume() { + if (!this._audio) + return 0; + return this._audio.volume; + } + } + + class MiniSound extends Laya.EventDispatcher { + constructor() { + super(); + this.loaded = false; + this._sound = MiniSound._createSound(); + } + static _createSound() { + MiniSound._id++; + return MiniAdpter.window.wx.createInnerAudioContext(); + } + load(url) { + if (!MiniFileMgr.isLocalNativeFile(url)) { + url = Laya.URL.formatURL(url); + } + else { + if (!MiniFileMgr.isLocalNativeZipFile(url) && MiniFileMgr.isNetFile(url)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + if (tempStr != "") + url = url.split(tempStr)[1]; + } + } + } + this.url = url; + this.readyUrl = url; + if (MiniAdpter.autoCacheFile && MiniFileMgr.getFileInfo(url)) { + this.onDownLoadCallBack(url, 0); + } + else { + if (!MiniAdpter.autoCacheFile) { + this.onDownLoadCallBack(url, 0); + } + else { + if (MiniFileMgr.isLocalNativeFile(url)) { + if (MiniAdpter.subNativeFiles && MiniAdpter.subNativeheads.length == 0) { + for (var key in MiniAdpter.subNativeFiles) { + var tempArr = MiniAdpter.subNativeFiles[key]; + MiniAdpter.subNativeheads = MiniAdpter.subNativeheads.concat(tempArr); + for (let i = 0; i < tempArr.length; i++) { + MiniAdpter.subMaps[tempArr[i]] = key + "/" + tempArr[i]; + } + } + } + if (MiniAdpter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && MiniAdpter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = MiniAdpter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + this.onDownLoadCallBack(url, 0); + } + else { + if (MiniFileMgr.isNetFile(url)) { + MiniFileMgr.downOtherFiles(url, Laya.Handler.create(this, this.onDownLoadCallBack, [url]), url); + } + else { + this.onDownLoadCallBack(url, 0); + } + } + } + } + } + onDownLoadCallBack(sourceUrl, errorCode, tempFilePath = null) { + if (!errorCode && this._sound) { + var fileNativeUrl; + if (MiniAdpter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = sourceUrl; + if (tempStr != "" && (sourceUrl.indexOf("http://") != -1 || sourceUrl.indexOf("https://") != -1)) + fileNativeUrl = sourceUrl.split(tempStr)[1]; + if (!fileNativeUrl) { + fileNativeUrl = tempUrl; + } + if (fileNativeUrl.indexOf(MiniAdpter.window.wx.env.USER_DATA_PATH) == -1 && MiniFileMgr.isLocalNativeZipFile(fileNativeUrl)) { + fileNativeUrl = MiniFileMgr.getFileNativePath(fileNativeUrl); + } + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + this._sound.src = this.readyUrl = fileNativeUrl; + } + else { + this._sound.src = this.readyUrl = sourceUrl; + } + } + else { + this.event(Laya.Event.ERROR); + } + } + play(startTime = 0, loops = 0) { + if (!this.url) + return null; + var channel = new MiniSoundChannel(this); + channel.url = this.url; + channel.loops = loops; + channel.loop = (loops === 0 ? true : false); + channel.startTime = startTime; + channel.isStopped = false; + Laya.SoundManager.addChannel(channel); + return channel; + } + get duration() { + return this._sound.duration; + } + dispose() { + if (this._sound) { + this._sound.destroy(); + this._sound = null; + this.readyUrl = this.url = null; + } + } + } + MiniSound._id = 0; + + class MiniInput { + constructor() { + } + static _createInputElement() { + Laya.Input['_initInput'](Laya.Input['area'] = Laya.Browser.createElement("textarea")); + Laya.Input['_initInput'](Laya.Input['input'] = Laya.Browser.createElement("input")); + Laya.Input['inputContainer'] = Laya.Browser.createElement("div"); + Laya.Input['inputContainer'].style.position = "absolute"; + Laya.Input['inputContainer'].style.zIndex = 1E5; + Laya.Browser.container.appendChild(Laya.Input['inputContainer']); + Laya.Laya.stage.on("resize", null, MiniInput._onStageResize); + MiniAdpter.window.wx.onWindowResize && MiniAdpter.window.wx.onWindowResize(function (res) { + }); + Laya.SoundManager._soundClass = MiniSound; + Laya.SoundManager._musicClass = MiniSound; + var model = MiniAdpter.systemInfo.model; + var system = MiniAdpter.systemInfo.system; + if (model.indexOf("iPhone") != -1) { + Laya.Browser.onIPhone = true; + Laya.Browser.onIOS = true; + Laya.Browser.onIPad = true; + Laya.Browser.onAndroid = false; + } + if (system.indexOf("Android") != -1 || system.indexOf("Adr") != -1) { + Laya.Browser.onAndroid = true; + Laya.Browser.onIPhone = false; + Laya.Browser.onIOS = false; + Laya.Browser.onIPad = false; + } + } + static _onStageResize() { + var ts = Laya.Laya.stage._canvasTransform.identity(); + ts.scale((Laya.Browser.width / Laya.Render.canvas.width / Laya.Browser.pixelRatio), Laya.Browser.height / Laya.Render.canvas.height / Laya.Browser.pixelRatio); + } + static wxinputFocus(e) { + var _inputTarget = Laya.Input['inputElement'].target; + if (_inputTarget && !_inputTarget.editable) { + return; + } + MiniAdpter.window.wx.offKeyboardConfirm(); + MiniAdpter.window.wx.offKeyboardInput(); + MiniAdpter.window.wx.showKeyboard({ defaultValue: _inputTarget.text, maxLength: _inputTarget.maxChars, multiple: _inputTarget.multiline, confirmHold: true, confirmType: _inputTarget["confirmType"] || 'done', success: function (res) { + }, fail: function (res) { + } }); + MiniAdpter.window.wx.onKeyboardConfirm(function (res) { + var str = res ? res.value : ""; + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + MiniInput.inputEnter(); + _inputTarget.event("confirm"); + }); + MiniAdpter.window.wx.onKeyboardInput(function (res) { + var str = res ? res.value : ""; + if (!_inputTarget.multiline) { + if (str.indexOf("\n") != -1) { + MiniInput.inputEnter(); + return; + } + } + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + }); + } + static inputEnter() { + Laya.Input['inputElement'].target.focus = false; + } + static wxinputblur() { + MiniInput.hideKeyboard(); + } + static hideKeyboard() { + MiniAdpter.window.wx.offKeyboardConfirm(); + MiniAdpter.window.wx.offKeyboardInput(); + MiniAdpter.window.wx.hideKeyboard({ success: function (res) { + console.log('隐藏键盘'); + }, fail: function (res) { + console.log("隐藏键盘出错:" + (res ? res.errMsg : "")); + } }); + } + } + + class MiniLoader extends Laya.EventDispatcher { + constructor() { + super(); + } + _loadResourceFilter(type, url) { + var thisLoader = this; + this.sourceUrl = Laya.URL.formatURL(url); + if (MiniFileMgr.isNetFile(url)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (MiniAdpter.subNativeFiles && MiniAdpter.subNativeheads.length == 0) { + for (var key in MiniAdpter.subNativeFiles) { + var tempArr = MiniAdpter.subNativeFiles[key]; + MiniAdpter.subNativeheads = MiniAdpter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + MiniAdpter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (MiniAdpter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && MiniAdpter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = MiniAdpter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + switch (type) { + case Laya.Loader.IMAGE: + case "htmlimage": + case "nativeimage": + MiniLoader._transformImgUrl(url, type, thisLoader); + break; + case Laya.Loader.SOUND: + thisLoader._loadSound(url); + break; + default: + thisLoader._loadResource(type, url); + } + } + _loadSound(url) { + var thisLoader = this; + if (!MiniAdpter.autoCacheFile) { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + else { + var tempurl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downOtherFiles(tempurl, Laya.Handler.create(MiniLoader, MiniLoader.onDownLoadCallBack, [tempurl, thisLoader]), tempurl); + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + } + static onDownLoadCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = null) { + if (!errorCode) { + var fileNativeUrl; + if (MiniAdpter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + fileNativeUrl = sourceUrl; + if (fileNativeUrl.indexOf(MiniAdpter.window.wx.env.USER_DATA_PATH) == -1 && MiniFileMgr.isLocalNativeZipFile(fileNativeUrl)) { + fileNativeUrl = MiniFileMgr.getFileNativePath(fileNativeUrl); + } + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + } + else { + fileNativeUrl = Laya.URL.formatURL(sourceUrl); + } + sourceUrl = fileNativeUrl; + var sound = (new Laya.SoundManager._soundClass()); + sound.load(sourceUrl); + thisLoader.onLoaded(sound); + } + else { + thisLoader.event(Laya.Event.ERROR, "Load sound failed"); + } + } + complete(data) { + if (data instanceof Laya.Resource) { + data._setCreateURL(this.sourceUrl); + } + else if ((data instanceof Laya.Texture) && (data.bitmap instanceof Laya.Resource)) { + data.bitmap._setCreateURL(this.sourceUrl); + } + this.originComplete(data); + } + _loadHttpRequestWhat(url, contentType) { + var thisLoader = this; + var encoding = MiniAdpter.getUrlEncode(url, contentType); + if (Laya.Loader.preLoadedMap[url]) + thisLoader.onLoaded(Laya.Loader.preLoadedMap[url]); + else { + var tempurl = Laya.URL.formatURL(url); + if (!MiniAdpter.AutoCacheDownFile) { + if (MiniFileMgr.isNetFile(tempurl)) { + thisLoader._loadHttpRequest(tempurl, contentType, thisLoader, thisLoader.onLoaded, thisLoader, thisLoader.onProgress, thisLoader, thisLoader.onError); + } + else { + if (url.indexOf(MiniAdpter.window.wx.env.USER_DATA_PATH) == -1 && MiniFileMgr.isLocalNativeZipFile(url)) { + url = MiniFileMgr.getFileNativePath(url); + } + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + else { + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downFiles(tempurl, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), tempurl, true); + } + else { + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + else { + var tempUrl = url; + var fileObj = MiniFileMgr.getFileInfo(tempurl); + if (fileObj && fileObj.md5) { + tempUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + MiniFileMgr.readFile(tempUrl, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + } + } + static onReadNativeCallBack(url, type = null, thisLoader = null, errorCode = 0, data = null) { + if (!errorCode) { + var tempData; + if (type == Laya.Loader.JSON || type == Laya.Loader.ATLAS || type == Laya.Loader.PREFAB || type == Laya.Loader.PLF) { + tempData = MiniAdpter.getJson(data.data); + } + else if (type == Laya.Loader.XML) { + tempData = Laya.Utils.parseXMLFromString(data.data); + } + else { + tempData = data.data; + } + if (!MiniAdpter.isZiYu && MiniAdpter.isPosMsgYu && type != Laya.Loader.BUFFER) { + MiniAdpter.window.wx.postMessage({ url: url, data: tempData, isLoad: "filedata" }); + } + thisLoader.onLoaded(tempData); + } + else if (errorCode == 1) { + thisLoader._loadHttpRequest(url, type, thisLoader, thisLoader.onLoaded, thisLoader, thisLoader.onProgress, thisLoader, thisLoader.onError); + } + } + static _transformImgUrl(url, type, thisLoader) { + if (MiniAdpter.isZiYu || MiniFileMgr.isLocalNativeFile(url)) { + if (MiniFileMgr.isLocalNativeZipFile(url)) { + url = MiniFileMgr.getFileNativePath(url); + } + thisLoader._loadImage(url, false); + return; + } + if (!MiniAdpter.autoCacheFile) { + thisLoader._loadImage(url); + } + else { + var tempUrl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempUrl)) { + if (MiniFileMgr.isNetFile(tempUrl)) { + MiniFileMgr.downOtherFiles(tempUrl, new Laya.Handler(MiniLoader, MiniLoader.onDownImgCallBack, [url, thisLoader]), tempUrl); + } + else { + MiniLoader.onCreateImage(url, thisLoader, true); + } + } + else { + MiniLoader.onCreateImage(url, thisLoader); + } + } + } + static onDownImgCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = "") { + if (!errorCode) + MiniLoader.onCreateImage(sourceUrl, thisLoader, false, tempFilePath); + else { + thisLoader.onError(null); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (MiniAdpter.autoCacheFile) { + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + var fileObj = MiniFileMgr.getFileInfo(Laya.URL.formatURL(sourceUrl)); + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + } + else if (MiniAdpter.isZiYu) { + var tempUrl = Laya.URL.formatURL(sourceUrl); + if (MiniFileMgr.ziyuFileTextureData[tempUrl]) { + fileNativeUrl = MiniFileMgr.ziyuFileTextureData[tempUrl]; + } + else + fileNativeUrl = sourceUrl; + } + else + fileNativeUrl = sourceUrl; + } + else { + if (!isLocal) + fileNativeUrl = tempFilePath; + else + fileNativeUrl = sourceUrl; + } + thisLoader._loadImage(fileNativeUrl, false); + } + } + + class MiniLocalStorage { + constructor() { + } + static __init__() { + MiniLocalStorage.items = MiniLocalStorage; + } + static setItem(key, value) { + try { + MiniAdpter.window.wx.setStorageSync(key, value); + } + catch (error) { + MiniAdpter.window.wx.setStorage({ + key: key, + data: value + }); + } + } + static getItem(key) { + return MiniAdpter.window.wx.getStorageSync(key); + } + static setJSON(key, value) { + MiniLocalStorage.setItem(key, value); + } + static getJSON(key) { + return MiniLocalStorage.getItem(key); + } + static removeItem(key) { + MiniAdpter.window.wx.removeStorageSync(key); + } + static clear() { + MiniAdpter.window.wx.clearStorageSync(); + } + static getStorageInfoSync() { + try { + var res = MiniAdpter.window.wx.getStorageInfoSync(); + console.log(res.keys); + console.log(res.currentSize); + console.log(res.limitSize); + return res; + } + catch (e) { + } + return null; + } + } + MiniLocalStorage.support = true; + + class MiniAdpter { + static getJson(data) { + return JSON.parse(data); + } + static enable() { + MiniAdpter.init(Laya.Laya.isWXPosMsg, Laya.Laya.isWXOpenDataContext); + } + static init(isPosMsg = false, isSon = false) { + if (MiniAdpter._inited) + return; + MiniAdpter._inited = true; + MiniAdpter.window = window; + if (!MiniAdpter.window.hasOwnProperty("wx")) + return; + if (MiniAdpter.window.navigator.userAgent.indexOf('MiniGame') < 0) + return; + MiniAdpter.isZiYu = isSon; + MiniAdpter.isPosMsgYu = isPosMsg; + MiniAdpter.EnvConfig = {}; + if (!MiniAdpter.isZiYu) { + MiniFileMgr.setNativeFileDir("/layaairGame"); + MiniFileMgr.getCacheList(MiniFileMgr.fileNativeDir, Laya.Handler.create(MiniAdpter, MiniAdpter.onMkdirCallBack)); + } + MiniAdpter.systemInfo = MiniAdpter.window.wx.getSystemInfoSync(); + MiniAdpter.window.focus = function () { + }; + Laya.Laya['_getUrlPath'] = function () { + return ""; + }; + MiniAdpter.window.logtime = function (str) { + }; + MiniAdpter.window.alertTimeLog = function (str) { + }; + MiniAdpter.window.resetShareInfo = function () { + }; + MiniAdpter.window.CanvasRenderingContext2D = function () { + }; + MiniAdpter.window.CanvasRenderingContext2D.prototype = MiniAdpter.window.wx.createCanvas().getContext('2d').__proto__; + MiniAdpter.window.document.body.appendChild = function () { + }; + MiniAdpter.EnvConfig.pixelRatioInt = 0; + Laya.Browser["_pixelRatio"] = MiniAdpter.pixelRatio(); + MiniAdpter._preCreateElement = Laya.Browser.createElement; + Laya.Browser["createElement"] = MiniAdpter.createElement; + Laya.RunDriver.createShaderCondition = MiniAdpter.createShaderCondition; + Laya.Utils['parseXMLFromString'] = MiniAdpter.parseXMLFromString; + Laya.Input['_createInputElement'] = MiniInput['_createInputElement']; + if (!window.ImageData) { + window.ImageData = ImageDataPolyfill; + } + Laya.Loader.prototype._loadResourceFilter = MiniLoader.prototype._loadResourceFilter; + Laya.Loader.prototype.originComplete = Laya.Loader.prototype.complete; + Laya.Loader.prototype.complete = MiniLoader.prototype.complete; + Laya.Loader.prototype._loadSound = MiniLoader.prototype._loadSound; + Laya.Loader.prototype._loadHttpRequestWhat = MiniLoader.prototype._loadHttpRequestWhat; + Laya.LocalStorage._baseClass = MiniLocalStorage; + MiniLocalStorage.__init__(); + MiniAdpter.window.wx.onMessage && MiniAdpter.window.wx.onMessage(MiniAdpter._onMessage); + } + static _onMessage(data) { + switch (data.type) { + case "changeMatrix": + Laya.Laya.stage.transform.identity(); + Laya.Laya.stage._width = data.w; + Laya.Laya.stage._height = data.h; + Laya.Laya.stage._canvasTransform = new Laya.Matrix(data.a, data.b, data.c, data.d, data.tx, data.ty); + break; + case "display": + Laya.Laya.stage.frameRate = data.rate || Laya.Stage.FRAME_FAST; + break; + case "undisplay": + Laya.Laya.stage.frameRate = Laya.Stage.FRAME_SLEEP; + break; + } + if (data['isLoad'] == "opendatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + else if (data['isLoad'] == "openJsondatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + } + } + else if (data['isLoad'] == "openJsondatacontextPic") { + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + static loadZip(zipurl, nativeurl, callBack, proCallBack, isUpdateType = 0) { + var fs = MiniFileMgr.fs; + if (fs && fs.unzip) { + MiniAdpter.nativefiles.push(nativeurl); + MiniAdpter.nativezipfiles.push(nativeurl); + var path = MiniFileMgr.fileNativeDir + "/" + nativeurl; + MiniAdpter.zipHeadFiles[zipurl] = nativeurl; + fs.access({ + path: path, + success: function (data) { + if (isUpdateType == 1) { + try { + fs.rmdirSync(path, true); + } + catch (e) { + console.log("目录删除成功"); + console.log(e); + } + fs.mkdir({ + dirPath: path, + recursive: true, + success: function (data1) { + MiniAdpter.downZip(zipurl, path, fs, callBack, proCallBack); + }.bind(this), + fail: function (data1) { + callBack != null && callBack.runWith([{ errCode: 3, errMsg: "创建压缩包目录失败", wxData: data1 }]); + }.bind(this) + }); + } + else if (isUpdateType == 2) { + MiniAdpter.downZip(zipurl, path, fs, callBack, proCallBack); + } + else { + var fileObj = MiniFileMgr.getFileInfo(zipurl); + if (!fileObj) { + MiniAdpter.downZip(zipurl, path, fs, callBack, proCallBack); + } + else { + callBack != null && callBack.runWith([{ errCode: 0, errMsg: "zip包目录存在,直接返回完成", wxData: data }]); + } + } + }.bind(this), + fail: function (data) { + if (data && data.errMsg.indexOf("access:fail no such file or directory") != -1) { + fs.mkdir({ + dirPath: path, + recursive: true, + success: function (data1) { + MiniAdpter.downZip(zipurl, path, fs, callBack, proCallBack); + }.bind(this), + fail: function (data1) { + callBack != null && callBack.runWith([{ errCode: 3, errMsg: "创建压缩包目录失败", wxData: data1 }]); + }.bind(this) + }); + } + }.bind(this) + }); + } + else { + callBack != null && callBack.runWith([{ errCode: 2, errMsg: "微信压缩接口不支持" }]); + } + } + static downZip(zipurl, path, fs, callBack, proCallBack) { + var obj = { + zipFilePath: zipurl, + targetPath: path, + success: function (data) { + callBack != null && callBack.runWith([{ errCode: 0, errMsg: "解压成功", wxData: data }]); + }.bind(this), + fail: function (data) { + callBack != null && callBack.runWith([{ errCode: 1, errMsg: "解压失败", wxData: data }]); + }.bind(this) + }; + if (zipurl.indexOf('http://') == -1 && zipurl.indexOf('https://') == -1) { + fs.unzip(obj); + } + else { + var downloadTask = window.wx.downloadFile({ + url: zipurl, + success: function (data) { + if (data.statusCode === 200) { + obj.zipFilePath = data.tempFilePath; + fs.unzip(obj); + MiniFileMgr.copyTOCache(data.tempFilePath, zipurl, null, 'utf8', true); + } + else { + callBack != null && callBack.runWith([{ errCode: 4, errMsg: "远端下载zip包失败", wxData: data }]); + } + }.bind(this), + fail: function (data) { + callBack != null && callBack.runWith([{ errCode: 4, errMsg: "远端下载zip包失败", wxData: data }]); + }.bind(this) + }); + downloadTask.onProgressUpdate(function (data) { + proCallBack != null && proCallBack.runWith([{ errCode: 5, errMsg: "zip包下载中", progress: data.progress }]); + }); + } + } + static getUrlEncode(url, type) { + if (type == "arraybuffer") + return ""; + return "utf8"; + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + var fileObj = MiniFileMgr.getFileInfo(fileUrl); + if (!fileObj) + MiniFileMgr.downLoadFile(fileUrl, fileType, callBack, encoding); + else { + callBack != null && callBack.runWith([0]); + } + } + static remove(fileUrl, callBack = null) { + MiniFileMgr.deleteFile("", fileUrl, callBack, "", 0); + } + static removeAll() { + MiniFileMgr.deleteAll(); + } + static hasNativeFile(fileUrl) { + return MiniFileMgr.isLocalNativeFile(fileUrl); + } + static getFileInfo(fileUrl) { + return MiniFileMgr.getFileInfo(fileUrl); + } + static getFileList() { + return MiniFileMgr.filesListObj; + } + static exitMiniProgram() { + MiniAdpter.window["wx"].exitMiniProgram(); + } + static onMkdirCallBack(errorCode, data) { + if (!errorCode) { + MiniFileMgr.filesListObj = JSON.parse(data.data); + MiniFileMgr.fakeObj = JSON.parse(data.data); + } + else { + MiniFileMgr.fakeObj = {}; + MiniFileMgr.filesListObj = {}; + } + let files = MiniFileMgr.fs.readdirSync(MiniFileMgr.fileNativeDir); + if (!files.length) + return; + var tempMd5ListObj = {}; + var fileObj; + for (let key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") { + fileObj = MiniFileMgr.filesListObj[key]; + tempMd5ListObj[fileObj.md5] = fileObj.readyUrl; + } + } + var fileName; + for (let i = 0, sz = files.length; i < sz; i++) { + fileName = files[i]; + if (fileName == MiniFileMgr.fileListName) + continue; + if (!tempMd5ListObj[fileName]) { + let deleteFileUrl = MiniFileMgr.getFileNativePath(fileName); + MiniFileMgr.fs.unlink({ + filePath: deleteFileUrl, + success: function (data) { + console.log("删除无引用的磁盘文件:" + fileName); + } + }); + } + delete tempMd5ListObj[fileName]; + } + for (let key in tempMd5ListObj) { + delete MiniFileMgr.filesListObj[tempMd5ListObj[key]]; + delete MiniFileMgr.fakeObj[tempMd5ListObj[key]]; + console.log("删除错误记录:", tempMd5ListObj[key]); + } + } + static pixelRatio() { + if (!MiniAdpter.EnvConfig.pixelRatioInt) { + try { + MiniAdpter.EnvConfig.pixelRatioInt = MiniAdpter.systemInfo.pixelRatio; + return MiniAdpter.systemInfo.pixelRatio; + } + catch (error) { + } + } + return MiniAdpter.EnvConfig.pixelRatioInt; + } + static createElement(type) { + if (type == "canvas") { + var _source; + if (MiniAdpter.idx == 1) { + if (MiniAdpter.isZiYu) { + _source = MiniAdpter.window.sharedCanvas; + _source.style = {}; + } + else { + _source = MiniAdpter.window.canvas; + } + } + else { + _source = MiniAdpter.window.wx.createCanvas(); + } + MiniAdpter.idx++; + return _source; + } + else if (type == "textarea" || type == "input") { + return MiniAdpter.onCreateInput(type); + } + else if (type == "div") { + var node = MiniAdpter._preCreateElement(type); + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + else { + return MiniAdpter._preCreateElement(type); + } + } + static onCreateInput(type) { + var node = MiniAdpter._preCreateElement(type); + node.focus = MiniInput.wxinputFocus; + node.blur = MiniInput.wxinputblur; + node.style = {}; + node.value = 0; + node.parentElement = {}; + node.placeholder = {}; + node.type = {}; + node.setColor = function (value) { + }; + node.setType = function (value) { + }; + node.setFontFace = function (value) { + }; + node.addEventListener = function (value) { + }; + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + static createShaderCondition(conditionScript) { + var func = function () { + return this[conditionScript.replace("this.", "")]; + }; + return func; + } + static sendAtlasToOpenDataContext(url) { + if (!MiniAdpter.isZiYu) { + var atlasJson = Laya.Loader.getRes(Laya.URL.formatURL(url)); + if (atlasJson) { + var textureArr = atlasJson.meta.image.split(","); + if (atlasJson.meta && atlasJson.meta.image) { + var toloadPics = atlasJson.meta.image.split(","); + var split = url.indexOf("/") >= 0 ? "/" : "\\"; + var idx = url.lastIndexOf(split); + var folderPath = idx >= 0 ? url.substr(0, idx + 1) : ""; + for (var i = 0, len = toloadPics.length; i < len; i++) { + toloadPics[i] = folderPath + toloadPics[i]; + } + } + else { + toloadPics = [url.replace(".json", ".png")]; + } + for (i = 0; i < toloadPics.length; i++) { + var tempAtlasPngUrl = toloadPics[i]; + MiniAdpter.postInfoToContext(Laya.Laya.URL.formatURL(url), Laya.Laya.URL.formatURL(tempAtlasPngUrl), atlasJson); + } + } + else { + throw "传递的url没有获取到对应的图集数据信息,请确保图集已经过!"; + } + } + } + static postInfoToContext(url, atlaspngUrl, atlasJson) { + var postData = { "frames": atlasJson.frames, "meta": atlasJson.meta }; + var textureUrl = atlaspngUrl; + var fileObj = MiniFileMgr.getFileInfo(Laya.URL.formatURL(atlaspngUrl)); + if (fileObj) { + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = textureUrl; + } + if (fileNativeUrl) { + MiniAdpter.window.wx.postMessage({ url: url, atlasdata: postData, imgNativeUrl: fileNativeUrl, imgReadyUrl: textureUrl, isLoad: "opendatacontext" }); + } + else { + throw "获取图集的磁盘url路径不存在!"; + } + } + static sendSinglePicToOpenDataContext(url) { + var tempTextureUrl = Laya.URL.formatURL(url); + var fileObj = MiniFileMgr.getFileInfo(tempTextureUrl); + if (fileObj) { + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + url = tempTextureUrl; + } + else { + fileNativeUrl = url; + } + if (fileNativeUrl) { + url = Laya.Laya.URL.formatURL(url); + MiniAdpter.window.wx.postMessage({ url: url, imgNativeUrl: fileNativeUrl, imgReadyUrl: url, isLoad: "openJsondatacontextPic" }); + } + else { + throw "获取图集的磁盘url路径不存在!"; + } + } + static sendJsonDataToDataContext(url) { + if (!MiniAdpter.isZiYu) { + url = Laya.Laya.URL.formatURL(url); + var atlasJson = Laya.Loader.getRes(url); + if (atlasJson) { + MiniAdpter.window.wx.postMessage({ url: url, atlasdata: atlasJson, isLoad: "openJsondatacontext" }); + } + else { + throw "传递的url没有获取到对应的图集数据信息,请确保图集已经过!"; + } + } + } + } + MiniAdpter._inited = false; + MiniAdpter.autoCacheFile = true; + MiniAdpter.minClearSize = (5 * 1024 * 1024); + MiniAdpter.sizeLimit = (200 * 1024 * 1024); + MiniAdpter.nativefiles = ["layaNativeDir", "wxlocal"]; + MiniAdpter.nativezipfiles = []; + MiniAdpter.zipRequestHead = ""; + MiniAdpter.zipHeadFiles = {}; + MiniAdpter.subNativeFiles = []; + MiniAdpter.subNativeheads = []; + MiniAdpter.subMaps = []; + MiniAdpter.AutoCacheDownFile = false; + MiniAdpter.parseXMLFromString = function (value) { + var rst; + value = value.replace(/>\s+<'); + try { + rst = (new MiniAdpter.window.Parser.DOMParser()).parseFromString(value, 'text/xml'); + } + catch (error) { + throw "需要引入xml解析库文件"; + } + return rst; + }; + MiniAdpter.idx = 1; + + class MiniAccelerator extends Laya.EventDispatcher { + constructor() { + super(); + } + static __init__() { + try { + var Acc; + Acc = Laya.Accelerator; + if (!Acc) + return; + Acc["prototype"]["on"] = MiniAccelerator["prototype"]["on"]; + Acc["prototype"]["off"] = MiniAccelerator["prototype"]["off"]; + } + catch (e) { + } + } + static startListen(callBack) { + MiniAccelerator._callBack = callBack; + if (MiniAccelerator._isListening) + return; + MiniAccelerator._isListening = true; + try { + MiniAdpter.window.wx.onAccelerometerChange(MiniAccelerator.onAccelerometerChange); + } + catch (e) { } + } + static stopListen() { + MiniAccelerator._isListening = false; + try { + MiniAdpter.window.wx.stopAccelerometer({}); + } + catch (e) { } + } + static onAccelerometerChange(res) { + var e; + e = {}; + e.acceleration = res; + e.accelerationIncludingGravity = res; + e.rotationRate = {}; + if (MiniAccelerator._callBack != null) { + MiniAccelerator._callBack(e); + } + } + on(type, caller, listener, args = null) { + super.on(type, caller, listener, args); + MiniAccelerator.startListen(this["onDeviceOrientationChange"]); + return this; + } + off(type, caller, listener, onceOnly = false) { + if (!this.hasListener(type)) + MiniAccelerator.stopListen(); + return super.off(type, caller, listener, onceOnly); + } + } + MiniAccelerator._isListening = false; + + class MiniLocation { + constructor() { + } + static __init__() { + MiniAdpter.window.navigator.geolocation.getCurrentPosition = MiniLocation.getCurrentPosition; + MiniAdpter.window.navigator.geolocation.watchPosition = MiniLocation.watchPosition; + MiniAdpter.window.navigator.geolocation.clearWatch = MiniLocation.clearWatch; + } + static getCurrentPosition(success = null, error = null, options = null) { + var paramO; + paramO = {}; + paramO.success = getSuccess; + paramO.fail = error; + MiniAdpter.window.wx.getLocation(paramO); + function getSuccess(res) { + if (success != null) { + success(res); + } + } + } + static watchPosition(success = null, error = null, options = null) { + MiniLocation._curID++; + var curWatchO; + curWatchO = {}; + curWatchO.success = success; + curWatchO.error = error; + MiniLocation._watchDic[MiniLocation._curID] = curWatchO; + Laya.Laya.systemTimer.loop(1000, null, MiniLocation._myLoop); + return MiniLocation._curID; + } + static clearWatch(id) { + delete MiniLocation._watchDic[id]; + if (!MiniLocation._hasWatch()) { + Laya.Laya.systemTimer.clear(null, MiniLocation._myLoop); + } + } + static _hasWatch() { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key]) + return true; + } + return false; + } + static _myLoop() { + MiniLocation.getCurrentPosition(MiniLocation._mySuccess, MiniLocation._myError); + } + static _mySuccess(res) { + var rst = {}; + rst.coords = res; + rst.timestamp = Laya.Browser.now(); + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].success) { + MiniLocation._watchDic[key].success(rst); + } + } + } + static _myError(res) { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].error) { + MiniLocation._watchDic[key].error(res); + } + } + } + } + MiniLocation._watchDic = {}; + MiniLocation._curID = 0; + + class MiniVideo { + constructor(width = 320, height = 240) { + this.videoend = false; + this.videourl = ""; + this.videoElement = MiniAdpter.window.wx.createVideo({ width: width, height: height, autoplay: true }); + } + static __init__() { + } + on(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.onPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.onEnded = this.onEndedFunction.bind(this); + } + this.videoElement.onTimeUpdate = this.onTimeUpdateFunc.bind(this); + } + onTimeUpdateFunc(data) { + this.position = data.position; + this._duration = data.duration; + } + get duration() { + return this._duration; + } + onPlayFunction() { + if (this.videoElement) + this.videoElement.readyState = 200; + console.log("=====视频加载完成========"); + this.onPlayFunc != null && this.onPlayFunc(); + } + onEndedFunction() { + if (!this.videoElement) + return; + this.videoend = true; + console.log("=====视频播放完毕========"); + this.onEndedFunC != null && this.onEndedFunC(); + } + off(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.offPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.offEnded = this.onEndedFunction.bind(this); + } + } + load(url) { + if (!this.videoElement) + return; + this.videoElement.src = url; + } + play() { + if (!this.videoElement) + return; + this.videoend = false; + this.videoElement.play(); + } + pause() { + if (!this.videoElement) + return; + this.videoend = true; + this.videoElement.pause(); + } + get currentTime() { + if (!this.videoElement) + return 0; + return this.videoElement.initialTime; + } + set currentTime(value) { + if (!this.videoElement) + return; + this.videoElement.initialTime = value; + } + get videoWidth() { + if (!this.videoElement) + return 0; + return this.videoElement.width; + } + get videoHeight() { + if (!this.videoElement) + return 0; + return this.videoElement.height; + } + get ended() { + return this.videoend; + } + get loop() { + if (!this.videoElement) + return false; + return this.videoElement.loop; + } + set loop(value) { + if (!this.videoElement) + return; + this.videoElement.loop = value; + } + get playbackRate() { + if (!this.videoElement) + return 0; + return this.videoElement.playbackRate; + } + set playbackRate(value) { + if (!this.videoElement) + return; + this.videoElement.playbackRate = value; + } + get muted() { + if (!this.videoElement) + return false; + return this.videoElement.muted; + } + set muted(value) { + if (!this.videoElement) + return; + this.videoElement.muted = value; + } + get paused() { + if (!this.videoElement) + return false; + return this.videoElement.paused; + } + size(width, height) { + if (!this.videoElement) + return; + this.videoElement.width = width; + this.videoElement.height = height; + } + get x() { + if (!this.videoElement) + return 0; + return this.videoElement.x; + } + set x(value) { + if (!this.videoElement) + return; + this.videoElement.x = value; + } + get y() { + if (!this.videoElement) + return 0; + return this.videoElement.y; + } + set y(value) { + if (!this.videoElement) + return; + this.videoElement.y = value; + } + get currentSrc() { + return this.videoElement.src; + } + destroy() { + if (this.videoElement) + this.videoElement.destroy(); + this.videoElement = null; + this.onEndedFunC = null; + this.onPlayFunc = null; + this.videoend = false; + this.videourl = null; + } + reload() { + if (!this.videoElement) + return; + this.videoElement.src = this.videourl; + } + } + + exports.ImageDataPolyfill = ImageDataPolyfill; + exports.MiniAccelerator = MiniAccelerator; + exports.MiniAdpter = MiniAdpter; + exports.MiniFileMgr = MiniFileMgr; + exports.MiniInput = MiniInput; + exports.MiniLoader = MiniLoader; + exports.MiniLocalStorage = MiniLocalStorage; + exports.MiniLocation = MiniLocation; + exports.MiniSound = MiniSound; + exports.MiniSoundChannel = MiniSoundChannel; + exports.MiniVideo = MiniVideo; + +} diff --git a/examples/layaair/frontend/bin/libs/laya.xmmini.js b/examples/layaair/frontend/bin/libs/laya.xmmini.js new file mode 100644 index 0000000..a8a374b --- /dev/null +++ b/examples/layaair/frontend/bin/libs/laya.xmmini.js @@ -0,0 +1,1840 @@ +window.miMiniGame = function (exports, Laya) { + 'use strict'; + + function ImageDataPolyfill() { + let width, height, data; + if (arguments.length == 3) { + if (arguments[0] instanceof Uint8ClampedArray) { + if (arguments[0].length % 4 !== 0) { + throw new Error("Failed to construct 'ImageData': The input data length is not a multiple of 4."); + } + if (arguments[0].length !== arguments[1] * arguments[2] * 4) { + throw new Error("Failed to construct 'ImageData': The input data length is not equal to (4 * width * height)."); + } + else { + data = arguments[0]; + width = arguments[1]; + height = arguments[2]; + } + } + else { + throw new Error("Failed to construct 'ImageData': parameter 1 is not of type 'Uint8ClampedArray'."); + } + } + else if (arguments.length == 2) { + width = arguments[0]; + height = arguments[1]; + data = new Uint8ClampedArray(arguments[0] * arguments[1] * 4); + } + else if (arguments.length < 2) { + throw new Error("Failed to construct 'ImageData': 2 arguments required, but only " + arguments.length + " present."); + } + let imgdata = Laya.Browser.canvas.getContext("2d").getImageData(0, 0, width, height); + for (let i = 0; i < data.length; i += 4) { + imgdata.data[i] = data[i]; + imgdata.data[i + 1] = data[i + 1]; + imgdata.data[i + 2] = data[i + 2]; + imgdata.data[i + 3] = data[i + 3]; + } + return imgdata; + } + + class MiniFileMgr { + static isLocalNativeFile(url) { + for (var i = 0, sz = KGMiniAdapter.nativefiles.length; i < sz; i++) { + if (url.indexOf(KGMiniAdapter.nativefiles[i]) != -1) + return true; + } + return false; + } + static isNetFile(url) { + return (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) && url.indexOf(KGMiniAdapter.window.qg.env.USER_DATA_PATH) == -1; + } + static getFileInfo(fileUrl) { + var fileNativePath = fileUrl; + var fileObj = MiniFileMgr.fakeObj[fileNativePath]; + if (fileObj == null) + return null; + else + return fileObj; + } + static read(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "") { + var fileUrl; + if (readyUrl != "" && (readyUrl.indexOf("http://") != -1 || readyUrl.indexOf("https://") != -1)) { + fileUrl = MiniFileMgr.getFileNativePath(filePath); + } + else { + fileUrl = filePath; + } + fileUrl = Laya.URL.getAdptedFilePath(fileUrl); + MiniFileMgr.fs.readFile({ filePath: fileUrl, encoding: encoding, success: function (data) { + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data && readyUrl != "") + MiniFileMgr.downFiles(KGMiniAdapter.safeEncodeURI(readyUrl), encoding, callBack, readyUrl, isSaveFile, fileType); + else + callBack != null && callBack.runWith([1]); + } }); + } + static isFile(url) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(url); + } + catch (err) { + return false; + } + return stat.isFile(); + } + static downFiles(fileUrl, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + var downloadTask = MiniFileMgr.down({ url: fileUrl, success: function (data) { + if (data.statusCode === 200) + MiniFileMgr.readFile(data.tempFilePath, encoding, callBack, readyUrl, isSaveFile, fileType, isAutoClear); + else if (data.statusCode === 403) { + callBack != null && callBack.runWith([0, fileUrl]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + downloadTask.onProgressUpdate(function (data) { + callBack != null && callBack.runWith([2, data.progress]); + }); + } + static readFile(filePath, encoding = "utf8", callBack = null, readyUrl = "", isSaveFile = false, fileType = "", isAutoClear = true) { + filePath = Laya.URL.getAdptedFilePath(filePath); + MiniFileMgr.fs.readFile({ filePath: filePath, encoding: encoding, success: function (data) { + if (filePath.indexOf(KGMiniAdapter.window.qg.env.USER_DATA_PATH) == -1 && (filePath.indexOf("http://") != -1 || filePath.indexOf("https://") != -1)) { + if (KGMiniAdapter.AutoCacheDownFile || isSaveFile) { + callBack != null && callBack.runWith([0, data]); + MiniFileMgr.copyTOCache(filePath, readyUrl, null, encoding, isAutoClear); + } + else + callBack != null && callBack.runWith([0, data]); + } + else + callBack != null && callBack.runWith([0, data]); + }, fail: function (data) { + if (data) + callBack != null && callBack.runWith([1, data]); + } }); + } + static downOtherFiles(fileUrl, callBack = null, readyUrl = "", isSaveFile = false, isAutoClear = true) { + MiniFileMgr.down({ url: fileUrl, success: function (data) { + if (data.statusCode === 200) { + if ((KGMiniAdapter.autoCacheFile || isSaveFile) && readyUrl.indexOf(".php") == -1) { + callBack != null && callBack.runWith([0, data.tempFilePath]); + MiniFileMgr.copyTOCache(data.tempFilePath, readyUrl, null, "", isAutoClear); + } + else + callBack != null && callBack.runWith([0, data.tempFilePath]); + } + else { + callBack != null && callBack.runWith([1, data]); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static copyFile(src, dest, complete = null) { + MiniFileMgr.fs.copyFile({ + srcPath: src, + destPath: dest, + success: function () { + complete && complete.runWith(0); + }, + fail: function (err) { + complete && complete.runWith([1, err]); + } + }); + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + if (window.navigator.userAgent.indexOf('QuickGame') < 0) { + Laya.Laya.loader.load(fileUrl, callBack); + } + else { + if (fileType == Laya.Loader.IMAGE || fileType == Laya.Loader.SOUND) + MiniFileMgr.downOtherFiles(fileUrl, callBack, fileUrl, true, false); + else + MiniFileMgr.downFiles(fileUrl, encoding, callBack, fileUrl, true, fileType, false); + } + } + static copyTOCache(tempFilePath, readyUrl, callBack, encoding = "", isAutoClear = true) { + var temp = tempFilePath.split("/"); + var tempFileName = temp[temp.length - 1]; + var fileurlkey = readyUrl; + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fakeObj[fileurlkey] = { md5: tempFileName, readyUrl: readyUrl, size: 0, times: Laya.Browser.now(), encoding: encoding, tempFilePath: tempFilePath }; + var totalSize = KGMiniAdapter.sizeLimit; + var chaSize = 4 * 1024 * 1024; + var fileUseSize = MiniFileMgr.getCacheUseSize(); + if (fileObj) { + if (fileObj.readyUrl != readyUrl) { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > KGMiniAdapter.minClearSize) + KGMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.deleteFile(tempFilePath, readyUrl, callBack, encoding, data.size); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + else + callBack != null && callBack.runWith([0]); + } + else { + MiniFileMgr.fs.getFileInfo({ + filePath: tempFilePath, + success: function (data) { + if ((isAutoClear && (fileUseSize + chaSize + data.size) >= totalSize)) { + if (data.size > KGMiniAdapter.minClearSize) + KGMiniAdapter.minClearSize = data.size; + MiniFileMgr.onClearCacheRes(); + } + MiniFileMgr.fs.copyFile({ srcPath: tempFilePath, destPath: saveFilePath, success: function (data2) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, data.size); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + }, + fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } + }); + } + } + static onClearCacheRes() { + var memSize = KGMiniAdapter.minClearSize; + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + MiniFileMgr.sortOn(tempFileListArr, "times", MiniFileMgr.NUMERIC); + var clearSize = 0; + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + if (clearSize >= memSize) + break; + clearSize += fileObj.size; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + } + static sortOn(array, name, options = 0) { + if (options == MiniFileMgr.NUMERIC) + return array.sort(function (a, b) { return a[name] - b[name]; }); + if (options == (MiniFileMgr.NUMERIC | MiniFileMgr.DESCENDING)) + return array.sort(function (a, b) { return b[name] - a[name]; }); + return array.sort(function (a, b) { return a[name] - b[name]; }); + } + static getFileNativePath(fileName) { + return MiniFileMgr.fileNativeDir + "/" + fileName; + } + static deleteFile(tempFileName, readyUrl = "", callBack = null, encoding = "", fileSize = 0) { + var fileObj = MiniFileMgr.getFileInfo(readyUrl); + var deleteFileUrl = MiniFileMgr.getFileNativePath(fileObj.md5); + MiniFileMgr.fs.unlink({ filePath: deleteFileUrl, success: function (data) { + if (tempFileName != "") { + var saveFilePath = MiniFileMgr.getFileNativePath(tempFileName); + MiniFileMgr.fs.copyFile({ srcPath: tempFileName, destPath: saveFilePath, success: function (data) { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, true, encoding, callBack, fileSize); + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + else { + MiniFileMgr.onSaveFile(readyUrl, tempFileName, false, encoding, callBack, fileSize); + } + }, fail: function (data) { + callBack != null && callBack.runWith([1, data]); + } }); + } + static deleteAll() { + var tempFileListArr = []; + for (var key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") + tempFileListArr.push(MiniFileMgr.filesListObj[key]); + } + for (var i = 1, sz = tempFileListArr.length; i < sz; i++) { + var fileObj = tempFileListArr[i]; + MiniFileMgr.deleteFile("", fileObj.readyUrl); + } + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj.fileUsedSize) { + MiniFileMgr.filesListObj.fileUsedSize = 0; + } + MiniFileMgr.writeFilesList("", JSON.stringify({}), false); + } + static onSaveFile(readyUrl, md5Name, isAdd = true, encoding = "", callBack = null, fileSize = 0) { + var fileurlkey = readyUrl; + if (MiniFileMgr.filesListObj['fileUsedSize'] == null) + MiniFileMgr.filesListObj['fileUsedSize'] = 0; + if (isAdd) { + var fileNativeName = MiniFileMgr.getFileNativePath(md5Name); + MiniFileMgr.filesListObj[fileurlkey] = { md5: md5Name, readyUrl: readyUrl, size: fileSize, times: Laya.Browser.now(), encoding: encoding, tempFilePath: fileNativeName }; + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) + fileSize; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), true); + callBack != null && callBack.runWith([0]); + } + else { + if (MiniFileMgr.filesListObj[fileurlkey]) { + var deletefileSize = parseInt(MiniFileMgr.filesListObj[fileurlkey].size); + MiniFileMgr.filesListObj['fileUsedSize'] = parseInt(MiniFileMgr.filesListObj['fileUsedSize']) - deletefileSize; + if (MiniFileMgr.fakeObj[fileurlkey].md5 == MiniFileMgr.filesListObj[fileurlkey].md5) { + delete MiniFileMgr.fakeObj[fileurlkey]; + } + delete MiniFileMgr.filesListObj[fileurlkey]; + MiniFileMgr.writeFilesList(fileurlkey, JSON.stringify(MiniFileMgr.filesListObj), false); + callBack != null && callBack.runWith([0]); + } + } + } + static writeFilesList(fileurlkey, filesListStr, isAdd) { + var listFilesPath = MiniFileMgr.fileNativeDir + "/" + MiniFileMgr.fileListName; + MiniFileMgr.fs.writeFile({ filePath: listFilesPath, encoding: 'utf8', data: filesListStr, success: function (data) { + }, fail: function (data) { + } }); + if (!KGMiniAdapter.isZiYu && KGMiniAdapter.isPosMsgYu) { + KGMiniAdapter.window.qg.postMessage({ url: fileurlkey, data: MiniFileMgr.filesListObj[fileurlkey], isLoad: "filenative", isAdd: isAdd }); + } + } + static getCacheUseSize() { + if (MiniFileMgr.filesListObj && MiniFileMgr.filesListObj['fileUsedSize']) + return MiniFileMgr.filesListObj['fileUsedSize']; + return 0; + } + static getCacheList(dirPath, cb) { + let stat; + try { + stat = MiniFileMgr.fs.statSync(dirPath); + } + catch (err) { + stat = null; + } + if (stat) { + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", cb); + } + else { + MiniFileMgr.fs.mkdirSync(dirPath, true); + cb && cb.runWith([1]); + } + } + static existDir(dirPath, callBack) { + MiniFileMgr.fs.mkdir({ dirPath: dirPath, success: function (data) { + callBack != null && callBack.runWith([0, { data: JSON.stringify({}) }]); + }, fail: function (data) { + if (data.errMsg.indexOf("file already exists") != -1) + MiniFileMgr.readSync(MiniFileMgr.fileListName, "utf8", callBack); + else + callBack != null && callBack.runWith([1, data]); + } }); + } + static readSync(filePath, encoding = "utf8", callBack = null, readyUrl = "") { + var fileUrl = MiniFileMgr.getFileNativePath(filePath); + var filesListStr; + try { + filesListStr = MiniFileMgr.fs.readFileSync(fileUrl, encoding); + callBack != null && callBack.runWith([0, { data: filesListStr }]); + } + catch (error) { + callBack != null && callBack.runWith([1]); + } + } + static setNativeFileDir(value) { + MiniFileMgr.fileNativeDir = KGMiniAdapter.window.qg.env.USER_DATA_PATH + value; + } + } + MiniFileMgr.fs = window.qg.getFileSystemManager(); + MiniFileMgr.down = window.qg.downloadFile; + MiniFileMgr.filesListObj = {}; + MiniFileMgr.fakeObj = {}; + MiniFileMgr.fileListName = "layaairfiles.txt"; + MiniFileMgr.ziyuFileData = {}; + MiniFileMgr.ziyuFileTextureData = {}; + MiniFileMgr.loadPath = ""; + MiniFileMgr.DESCENDING = 2; + MiniFileMgr.NUMERIC = 16; + + class MiniSoundChannel extends Laya.SoundChannel { + constructor(audio, miniSound) { + super(); + this._audio = audio; + this._miniSound = miniSound; + this._onEnd = MiniSoundChannel.bindToThis(this.__onEnd, this); + audio.onEnded(this._onEnd); + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + __onEnd() { + if (this.loops == 1) { + if (this.completeHandler) { + Laya.Laya.systemTimer.once(10, this, this.__runComplete, [this.completeHandler], false); + this.completeHandler = null; + } + this.stop(); + this.event(Laya.Event.COMPLETE); + return; + } + if (this.loops > 0) { + this.loops--; + } + this.startTime = 0; + this.play(); + } + play() { + this.isStopped = false; + Laya.SoundManager.addChannel(this); + this._audio.play(); + } + set startTime(time) { + if (this._audio) { + this._audio.startTime = time; + } + } + set autoplay(value) { + this._audio.autoplay = value; + } + get autoplay() { + return this._audio.autoplay; + } + get position() { + if (!this._audio) + return 0; + return this._audio.currentTime; + } + get duration() { + if (!this._audio) + return 0; + return this._audio.duration; + } + stop() { + this.isStopped = true; + Laya.SoundManager.removeChannel(this); + this.completeHandler = null; + if (!this._audio) + return; + this._audio.stop(); + if (!this.loop) { + this._audio.offEnded(null); + this._miniSound.dispose(); + this._audio = null; + this._miniSound = null; + this._onEnd = null; + } + } + pause() { + this.isStopped = true; + this._audio.pause(); + } + get loop() { + return this._audio.loop; + } + set loop(value) { + this._audio.loop = value; + } + resume() { + if (!this._audio) + return; + this.isStopped = false; + Laya.SoundManager.addChannel(this); + this._audio.play(); + } + set volume(v) { + if (!this._audio) + return; + this._audio.volume = v; + } + get volume() { + if (!this._audio) + return 1; + return this._audio.volume; + } + } + + class MiniSound extends Laya.EventDispatcher { + constructor() { + super(); + this.loaded = false; + } + static _createSound() { + MiniSound._id++; + return KGMiniAdapter.window.qg.createInnerAudioContext(); + } + load(url) { + if (!MiniSound._musicAudio) + MiniSound._musicAudio = MiniSound._createSound(); + if (!MiniFileMgr.isLocalNativeFile(url)) { + url = Laya.URL.formatURL(url); + } + else { + if (url.indexOf("http://") != -1 || url.indexOf("https://") != -1) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + if (tempStr != "") + url = url.split(tempStr)[1]; + } + } + } + this.url = url; + this.readyUrl = url; + if (MiniSound._audioCache[this.readyUrl]) { + this.event(Laya.Event.COMPLETE); + return; + } + if (KGMiniAdapter.autoCacheFile && MiniFileMgr.getFileInfo(url)) { + this.onDownLoadCallBack(url, 0); + } + else { + if (!KGMiniAdapter.autoCacheFile) { + this.onDownLoadCallBack(url, 0); + } + else { + if (MiniFileMgr.isLocalNativeFile(url)) { + tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + if (KGMiniAdapter.subNativeFiles && KGMiniAdapter.subNativeheads.length == 0) { + for (var key in KGMiniAdapter.subNativeFiles) { + var tempArr = KGMiniAdapter.subNativeFiles[key]; + KGMiniAdapter.subNativeheads = KGMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + KGMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (KGMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && KGMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = KGMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + this.onDownLoadCallBack(url, 0); + } + else { + if (!MiniFileMgr.isLocalNativeFile(url) && (url.indexOf("http://") == -1 && url.indexOf("https://") == -1) || (url.indexOf(KGMiniAdapter.window.qg.env.USER_DATA_PATH) != -1)) { + this.onDownLoadCallBack(url, 0); + } + else { + MiniFileMgr.downOtherFiles(KGMiniAdapter.safeEncodeURI(url), Laya.Handler.create(this, this.onDownLoadCallBack, [url]), url); + } + } + } + } + } + onDownLoadCallBack(sourceUrl, errorCode) { + if (!errorCode) { + var fileNativeUrl; + if (KGMiniAdapter.autoCacheFile) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = sourceUrl; + if (tempStr != "" && (sourceUrl.indexOf("http://") != -1 || sourceUrl.indexOf("https://") != -1)) + fileNativeUrl = sourceUrl.split(tempStr)[1]; + if (!fileNativeUrl) { + fileNativeUrl = tempUrl; + } + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + var fileMd5Name = fileObj.md5; + fileNativeUrl = MiniFileMgr.getFileNativePath(fileMd5Name); + } + else { + fileNativeUrl = sourceUrl; + } + } + if (this.url != Laya.SoundManager._bgMusic) { + this._sound = MiniSound._createSound(); + this._sound.src = this.url = fileNativeUrl; + } + else { + this._sound = MiniSound._musicAudio; + this._sound.src = this.url = fileNativeUrl; + } + } + else { + if (this.url != Laya.SoundManager._bgMusic) { + this._sound = MiniSound._createSound(); + this._sound.src = sourceUrl; + } + else { + this._sound = MiniSound._musicAudio; + this._sound.src = sourceUrl; + } + } + this._sound.onCanplay(MiniSound.bindToThis(this.onCanPlay, this)); + this._sound.onError(MiniSound.bindToThis(this.onError, this)); + } + else { + this.event(Laya.Event.ERROR); + } + } + onError(error) { + try { + console.log("-----1---------------minisound-----id:" + MiniSound._id); + console.log(error); + } + catch (error) { + console.log("-----2---------------minisound-----id:" + MiniSound._id); + console.log(error); + } + this.event(Laya.Event.ERROR); + this._sound.offError(null); + } + onCanPlay() { + this.loaded = true; + this.event(Laya.Event.COMPLETE); + this._sound.offCanplay(null); + } + static bindToThis(fun, scope) { + var rst = fun; + rst = fun.bind(scope); + return rst; + } + play(startTime = 0, loops = 0) { + var tSound; + if (this.url == Laya.SoundManager._bgMusic) { + if (!MiniSound._musicAudio) + MiniSound._musicAudio = MiniSound._createSound(); + tSound = MiniSound._musicAudio; + } + else { + if (MiniSound._audioCache[this.readyUrl]) { + tSound = MiniSound._audioCache[this.readyUrl]._sound; + } + else { + tSound = MiniSound._createSound(); + } + } + if (!tSound) + return null; + if (KGMiniAdapter.autoCacheFile && MiniFileMgr.getFileInfo(this.url)) { + var fileObj = MiniFileMgr.getFileInfo(this.url); + var fileMd5Name = fileObj.md5; + tSound.src = this.url = MiniFileMgr.getFileNativePath(fileMd5Name); + } + else { + tSound.src = KGMiniAdapter.safeEncodeURI(this.url); + } + var channel = new MiniSoundChannel(tSound, this); + channel.url = this.url; + channel.loops = loops; + channel.loop = (loops === 0 ? true : false); + channel.startTime = startTime; + channel.play(); + Laya.SoundManager.addChannel(channel); + return channel; + } + get duration() { + return this._sound.duration; + } + dispose() { + var ad = MiniSound._audioCache[this.readyUrl]; + if (ad) { + ad.src = ""; + if (ad._sound) { + ad._sound.destroy(); + ad._sound = null; + ad = null; + } + delete MiniSound._audioCache[this.readyUrl]; + } + if (this._sound) { + this._sound.destroy(); + this._sound = null; + this.readyUrl = this.url = null; + } + } + } + MiniSound._id = 0; + MiniSound._audioCache = {}; + + class MiniInput { + constructor() { + } + static _createInputElement() { + Laya.Input['_initInput'](Laya.Input['area'] = Laya.Browser.createElement("textarea")); + Laya.Input['_initInput'](Laya.Input['input'] = Laya.Browser.createElement("input")); + Laya.Input['inputContainer'] = Laya.Browser.createElement("div"); + Laya.Input['inputContainer'].style.position = "absolute"; + Laya.Input['inputContainer'].style.zIndex = 1E5; + Laya.Browser.container.appendChild(Laya.Input['inputContainer']); + Laya.Laya.stage.on("resize", null, MiniInput._onStageResize); + KGMiniAdapter.window.qg.onWindowResize && KGMiniAdapter.window.qg.onWindowResize(function (res) { + }); + Laya.SoundManager._soundClass = MiniSound; + Laya.SoundManager._musicClass = MiniSound; + var model = KGMiniAdapter.systemInfo.model; + var system = KGMiniAdapter.systemInfo.system; + if (model.indexOf("iPhone") != -1) { + Laya.Browser.onIPhone = true; + Laya.Browser.onIOS = true; + Laya.Browser.onIPad = true; + Laya.Browser.onAndroid = false; + } + if (system.indexOf("Android") != -1 || system.indexOf("Adr") != -1) { + Laya.Browser.onAndroid = true; + Laya.Browser.onIPhone = false; + Laya.Browser.onIOS = false; + Laya.Browser.onIPad = false; + } + } + static _onStageResize() { + var ts = Laya.Laya.stage._canvasTransform.identity(); + ts.scale((Laya.Browser.width / Laya.Render.canvas.width / Laya.Browser.pixelRatio), Laya.Browser.height / Laya.Render.canvas.height / Laya.Browser.pixelRatio); + } + static wxinputFocus(e) { + var _inputTarget = Laya.Input['inputElement'].target; + if (_inputTarget && !_inputTarget.editable) { + return; + } + KGMiniAdapter.window.qg.offKeyboardConfirm(); + KGMiniAdapter.window.qg.offKeyboardInput(); + KGMiniAdapter.window.qg.showKeyboard({ defaultValue: _inputTarget.text, maxLength: _inputTarget.maxChars, multiple: _inputTarget.multiline, confirmHold: true, confirmType: _inputTarget["confirmType"] || 'done', success: function (res) { + }, fail: function (res) { + } }); + KGMiniAdapter.window.qg.onKeyboardConfirm(function (res) { + var str = res ? res.value : ""; + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + MiniInput.inputEnter(); + _inputTarget.event("confirm"); + }); + KGMiniAdapter.window.qg.onKeyboardInput(function (res) { + var str = res ? res.value : ""; + if (!_inputTarget.multiline) { + if (str.indexOf("\n") != -1) { + MiniInput.inputEnter(); + return; + } + } + if (_inputTarget._restrictPattern) { + str = str.replace(/\u2006|\x27/g, ""); + if (_inputTarget._restrictPattern.test(str)) { + str = str.replace(_inputTarget._restrictPattern, ""); + } + } + _inputTarget.text = str; + _inputTarget.event(Laya.Event.INPUT); + }); + } + static inputEnter() { + Laya.Input['inputElement'].target.focus = false; + } + static wxinputblur() { + MiniInput.hideKeyboard(); + } + static hideKeyboard() { + KGMiniAdapter.window.qg.offKeyboardConfirm(); + KGMiniAdapter.window.qg.offKeyboardInput(); + KGMiniAdapter.window.qg.hideKeyboard({ success: function (res) { + console.log('隐藏键盘'); + }, fail: function (res) { + console.log("隐藏键盘出错:" + (res ? res.errMsg : "")); + } }); + } + } + + class MiniLoader extends Laya.EventDispatcher { + constructor() { + super(); + } + _loadResourceFilter(type, url) { + var thisLoader = this; + this.sourceUrl = Laya.URL.formatURL(url); + if (MiniFileMgr.isNetFile(url)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (KGMiniAdapter.subNativeFiles && KGMiniAdapter.subNativeheads.length == 0) { + for (var key in KGMiniAdapter.subNativeFiles) { + var tempArr = KGMiniAdapter.subNativeFiles[key]; + KGMiniAdapter.subNativeheads = KGMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + KGMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (KGMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && KGMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = KGMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + switch (type) { + case Laya.Loader.IMAGE: + case "htmlimage": + case "nativeimage": + MiniLoader._transformImgUrl(url, type, thisLoader); + break; + case Laya.Loader.SOUND: + thisLoader._loadSound(url); + break; + default: + thisLoader._loadResource(type, url); + } + } + _loadSound(url) { + var thisLoader = this; + if (!KGMiniAdapter.autoCacheFile) { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + else { + var tempurl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downOtherFiles(KGMiniAdapter.safeEncodeURI(tempurl), Laya.Handler.create(MiniLoader, MiniLoader.onDownLoadCallBack, [tempurl, thisLoader]), tempurl); + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + else { + MiniLoader.onDownLoadCallBack(url, thisLoader, 0); + } + } + } + static onDownLoadCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = null) { + if (!errorCode) { + var fileNativeUrl; + if (KGMiniAdapter.autoCacheFile) { + if (!tempFilePath) { + if (MiniFileMgr.isLocalNativeFile(sourceUrl)) { + fileNativeUrl = sourceUrl; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + if (fileObj && fileObj.md5) { + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = sourceUrl; + } + } + } + else { + fileNativeUrl = tempFilePath; + } + } + else { + fileNativeUrl = Laya.URL.formatURL(sourceUrl); + } + sourceUrl = fileNativeUrl; + var sound = (new Laya.SoundManager._soundClass()); + sound.load(KGMiniAdapter.safeEncodeURI(sourceUrl)); + thisLoader.onLoaded(sound); + } + else { + thisLoader.event(Laya.Event.ERROR, "Load sound failed"); + } + } + complete(data) { + if (data instanceof Laya.Resource) { + data._setCreateURL(this.sourceUrl); + } + else if ((data instanceof Laya.Texture) && (data.bitmap instanceof Laya.Resource)) { + data.bitmap._setCreateURL(this.sourceUrl); + } + this.originComplete(data); + } + _loadHttpRequestWhat(url, contentType) { + var thisLoader = this; + var encoding = KGMiniAdapter.getUrlEncode(url, contentType); + if (Laya.Loader.preLoadedMap[url]) + thisLoader.onLoaded(Laya.Loader.preLoadedMap[url]); + else { + var tempurl = Laya.URL.formatURL(url); + if (!KGMiniAdapter.AutoCacheDownFile) { + if (MiniFileMgr.isNetFile(tempurl)) { + thisLoader._loadHttpRequest(tempurl, contentType, thisLoader, thisLoader.onLoaded, thisLoader, thisLoader.onProgress, thisLoader, thisLoader.onError); + } + else + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + else { + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempurl)) { + if (MiniFileMgr.isNetFile(tempurl)) { + MiniFileMgr.downFiles(KGMiniAdapter.safeEncodeURI(tempurl), encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), tempurl, true); + } + else { + MiniFileMgr.readFile(url, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + else { + var tempUrl = url; + var fileObj = MiniFileMgr.getFileInfo(tempurl); + if (fileObj && fileObj.md5) { + tempUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + MiniFileMgr.readFile(tempUrl, encoding, new Laya.Handler(MiniLoader, MiniLoader.onReadNativeCallBack, [url, contentType, thisLoader]), url); + } + } + } + } + static onReadNativeCallBack(url, type = null, thisLoader = null, errorCode = 0, data = null) { + if (!errorCode) { + var tempData; + if (type == Laya.Loader.JSON || type == Laya.Loader.ATLAS || type == Laya.Loader.PREFAB || type == Laya.Loader.PLF) { + tempData = KGMiniAdapter.getJson(data.data); + } + else if (type == Laya.Loader.XML) { + tempData = Laya.Utils.parseXMLFromString(data.data); + } + else { + tempData = data.data; + } + if (!KGMiniAdapter.isZiYu && KGMiniAdapter.isPosMsgYu && type != Laya.Loader.BUFFER) { + KGMiniAdapter.window.qg.postMessage({ url: url, data: tempData, isLoad: "filedata" }); + } + thisLoader.onLoaded(tempData); + } + else if (errorCode == 1) { + thisLoader._loadHttpRequest(url, type, thisLoader, thisLoader.onLoaded, thisLoader, thisLoader.onProgress, thisLoader, thisLoader.onError); + } + } + static _transformImgUrl(url, type, thisLoader) { + if (KGMiniAdapter.isZiYu || MiniFileMgr.isLocalNativeFile(url)) { + thisLoader._loadImage(url, false); + return; + } + if (!KGMiniAdapter.autoCacheFile) { + thisLoader._loadImage(KGMiniAdapter.safeEncodeURI(url)); + } + else { + var tempUrl = Laya.URL.formatURL(url); + if (!MiniFileMgr.isLocalNativeFile(url) && !MiniFileMgr.getFileInfo(tempUrl)) { + if (MiniFileMgr.isNetFile(tempUrl)) { + MiniFileMgr.downOtherFiles(KGMiniAdapter.safeEncodeURI(tempUrl), new Laya.Handler(MiniLoader, MiniLoader.onDownImgCallBack, [url, thisLoader]), tempUrl); + } + else { + MiniLoader.onCreateImage(url, thisLoader, true); + } + } + else { + MiniLoader.onCreateImage(url, thisLoader); + } + } + } + static onDownImgCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = "") { + if (!errorCode) + MiniLoader.onCreateImage(sourceUrl, thisLoader, false, tempFilePath); + else { + thisLoader.onError(null); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (KGMiniAdapter.autoCacheFile) { + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + var fileObj = MiniFileMgr.getFileInfo(Laya.URL.formatURL(sourceUrl)); + fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + } + else if (KGMiniAdapter.isZiYu) { + var tempUrl = Laya.URL.formatURL(sourceUrl); + if (MiniFileMgr.ziyuFileTextureData[tempUrl]) { + fileNativeUrl = MiniFileMgr.ziyuFileTextureData[tempUrl]; + } + else + fileNativeUrl = sourceUrl; + } + else + fileNativeUrl = sourceUrl; + } + else { + if (!isLocal) + fileNativeUrl = tempFilePath; + else + fileNativeUrl = sourceUrl; + } + thisLoader._loadImage(fileNativeUrl, false); + } + } + + class KGMiniAdapter { + static getJson(data) { + return JSON.parse(data); + } + static enable() { + KGMiniAdapter.init(Laya.Laya.isWXPosMsg, Laya.Laya.isWXOpenDataContext); + } + static init(isPosMsg = false, isSon = false) { + if (KGMiniAdapter._inited) + return; + KGMiniAdapter._inited = true; + KGMiniAdapter.window = window; + if (KGMiniAdapter.window.navigator.userAgent.indexOf('QuickGame') < 0) + return; + KGMiniAdapter.isZiYu = isSon; + KGMiniAdapter.isPosMsgYu = isPosMsg; + KGMiniAdapter.EnvConfig = {}; + if (!KGMiniAdapter.isZiYu) { + MiniFileMgr.setNativeFileDir("/layaairGame"); + MiniFileMgr.getCacheList(MiniFileMgr.fileNativeDir, Laya.Handler.create(KGMiniAdapter, KGMiniAdapter.onMkdirCallBack)); + } + KGMiniAdapter.systemInfo = KGMiniAdapter.window.qg.getSystemInfoSync(); + KGMiniAdapter.window.focus = function () { + }; + Laya.Laya['_getUrlPath'] = function () { + return ""; + }; + KGMiniAdapter.window.logtime = function (str) { + }; + KGMiniAdapter.window.alertTimeLog = function (str) { + }; + KGMiniAdapter.window.resetShareInfo = function () { + }; + Laya.HttpRequest._urlEncode = KGMiniAdapter.safeEncodeURI; + KGMiniAdapter.EnvConfig.pixelRatioInt = 0; + Laya.Browser["_pixelRatio"] = KGMiniAdapter.pixelRatio(); + KGMiniAdapter._preCreateElement = Laya.Browser.createElement; + Laya.Browser["createElement"] = KGMiniAdapter.createElement; + Laya.RunDriver.createShaderCondition = KGMiniAdapter.createShaderCondition; + Laya.Utils['parseXMLFromString'] = KGMiniAdapter.parseXMLFromString; + Laya.Input['_createInputElement'] = MiniInput['_createInputElement']; + if (!window.ImageData) { + window.ImageData = ImageDataPolyfill; + } + Laya.Loader.prototype._loadResourceFilter = MiniLoader.prototype._loadResourceFilter; + Laya.Loader.prototype._loadSound = MiniLoader.prototype._loadSound; + Laya.Loader.prototype.originComplete = Laya.Loader.prototype.complete; + Laya.Loader.prototype.complete = MiniLoader.prototype.complete; + Laya.Loader.prototype._loadHttpRequestWhat = MiniLoader.prototype._loadHttpRequestWhat; + Laya.Config.useRetinalCanvas = true; + Laya.Config.useWebGL2 = false; + KGMiniAdapter.window.qg.onMessage && KGMiniAdapter.window.qg.onMessage(KGMiniAdapter._onMessage); + } + static _onMessage(data) { + switch (data.type) { + case "changeMatrix": + Laya.Laya.stage.transform.identity(); + Laya.Laya.stage._width = data.w; + Laya.Laya.stage._height = data.h; + Laya.Laya.stage._canvasTransform = new Laya.Matrix(data.a, data.b, data.c, data.d, data.tx, data.ty); + break; + case "display": + Laya.Laya.stage.frameRate = data.rate || Laya.Stage.FRAME_FAST; + break; + case "undisplay": + Laya.Laya.stage.frameRate = Laya.Stage.FRAME_SLEEP; + break; + } + if (data['isLoad'] == "opendatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + else if (data['isLoad'] == "openJsondatacontext") { + if (data.url) { + MiniFileMgr.ziyuFileData[data.url] = data.atlasdata; + } + } + else if (data['isLoad'] == "openJsondatacontextPic") { + MiniFileMgr.ziyuFileTextureData[data.imgReadyUrl] = data.imgNativeUrl; + } + } + static getUrlEncode(url, type) { + if (type == "arraybuffer") + return ""; + return "utf8"; + } + static downLoadFile(fileUrl, fileType = "", callBack = null, encoding = "utf8") { + var fileObj = MiniFileMgr.getFileInfo(fileUrl); + if (!fileObj) + MiniFileMgr.downLoadFile(fileUrl, fileType, callBack, encoding); + else { + callBack != null && callBack.runWith([0]); + } + } + static remove(fileUrl, callBack = null) { + MiniFileMgr.deleteFile("", fileUrl, callBack, "", 0); + } + static removeAll() { + MiniFileMgr.deleteAll(); + } + static hasNativeFile(fileUrl) { + return MiniFileMgr.isLocalNativeFile(fileUrl); + } + static getFileInfo(fileUrl) { + return MiniFileMgr.getFileInfo(fileUrl); + } + static getFileList() { + return MiniFileMgr.filesListObj; + } + static exitMiniProgram() { + KGMiniAdapter.window["qg"].exitMiniProgram(); + } + static onMkdirCallBack(errorCode, data) { + if (!errorCode) { + MiniFileMgr.filesListObj = JSON.parse(data.data); + MiniFileMgr.fakeObj = JSON.parse(data.data) || {}; + } + else { + MiniFileMgr.fakeObj = {}; + MiniFileMgr.filesListObj = {}; + } + let files = MiniFileMgr.fs.readdirSync(MiniFileMgr.fileNativeDir); + if (!files.length) + return; + var tempMd5ListObj = {}; + var fileObj; + for (let key in MiniFileMgr.filesListObj) { + if (key != "fileUsedSize") { + fileObj = MiniFileMgr.filesListObj[key]; + tempMd5ListObj[fileObj.md5] = fileObj.readyUrl; + } + } + var fileName; + for (let i = 0, sz = files.length; i < sz; i++) { + fileName = files[i]; + if (fileName == MiniFileMgr.fileListName) + continue; + if (!tempMd5ListObj[fileName]) { + let deleteFileUrl = MiniFileMgr.getFileNativePath(fileName); + MiniFileMgr.fs.unlink({ + filePath: deleteFileUrl, + success: function (data) { + console.log("删除无引用的磁盘文件:" + fileName); + } + }); + } + delete tempMd5ListObj[fileName]; + } + for (let key in tempMd5ListObj) { + delete MiniFileMgr.filesListObj[tempMd5ListObj[key]]; + delete MiniFileMgr.fakeObj[tempMd5ListObj[key]]; + console.log("删除错误记录:", tempMd5ListObj[key]); + } + } + static pixelRatio() { + if (!KGMiniAdapter.EnvConfig.pixelRatioInt) { + try { + KGMiniAdapter.EnvConfig.pixelRatioInt = KGMiniAdapter.systemInfo.pixelRatio; + return KGMiniAdapter.systemInfo.pixelRatio; + } + catch (error) { + } + } + return KGMiniAdapter.EnvConfig.pixelRatioInt; + } + static createElement(type) { + if (type == "canvas") { + var _source; + if (KGMiniAdapter.idx == 1) { + if (KGMiniAdapter.isZiYu) ; + else { + _source = KGMiniAdapter.window.canvas; + _source.style = { + width: _source.width + "px", + height: _source.height + "px" + }; + } + } + else { + var tempCanvas = window.document.createElement('canvas'); + _source = tempCanvas; + } + KGMiniAdapter.idx++; + return _source; + } + else if (type == "textarea" || type == "input") { + return KGMiniAdapter.onCreateInput(type); + } + else if (type == "div") { + var node = KGMiniAdapter._preCreateElement(type); + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + else { + return KGMiniAdapter._preCreateElement(type); + } + } + static onCreateInput(type) { + var node = KGMiniAdapter._preCreateElement(type); + node.focus = MiniInput.wxinputFocus; + node.blur = MiniInput.wxinputblur; + node.style = {}; + node.value = 0; + node.placeholder = {}; + node.setColor = function (value) { + }; + node.setType = function (value) { + }; + node.setFontFace = function (value) { + }; + node.addEventListener = function (value) { + }; + node.contains = function (value) { + return null; + }; + node.removeChild = function (value) { + }; + return node; + } + static createShaderCondition(conditionScript) { + var func = function () { + return this[conditionScript.replace("this.", "")]; + }; + return func; + } + static sendAtlasToOpenDataContext(url) { + if (!KGMiniAdapter.isZiYu) { + var atlasJson = Laya.Loader.getRes(Laya.URL.formatURL(url)); + if (atlasJson) { + var textureArr = atlasJson.meta.image.split(","); + if (atlasJson.meta && atlasJson.meta.image) { + var toloadPics = atlasJson.meta.image.split(","); + var split = url.indexOf("/") >= 0 ? "/" : "\\"; + var idx = url.lastIndexOf(split); + var folderPath = idx >= 0 ? url.substr(0, idx + 1) : ""; + for (var i = 0, len = toloadPics.length; i < len; i++) { + toloadPics[i] = folderPath + toloadPics[i]; + } + } + else { + toloadPics = [url.replace(".json", ".png")]; + } + for (i = 0; i < toloadPics.length; i++) { + var tempAtlasPngUrl = toloadPics[i]; + KGMiniAdapter.postInfoToContext(url, tempAtlasPngUrl, atlasJson); + } + } + else { + throw "传递的url没有获取到对应的图集数据信息,请确保图集已经过!"; + } + } + } + static postInfoToContext(url, atlaspngUrl, atlasJson) { + var postData = { "frames": atlasJson.frames, "meta": atlasJson.meta }; + var textureUrl = atlaspngUrl; + var fileObj = MiniFileMgr.getFileInfo(Laya.URL.formatURL(atlaspngUrl)); + if (fileObj) { + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + } + else { + fileNativeUrl = textureUrl; + } + if (fileNativeUrl) { + KGMiniAdapter.window.qg.postMessage({ url: url, atlasdata: postData, imgNativeUrl: fileNativeUrl, imgReadyUrl: textureUrl, isLoad: "opendatacontext" }); + } + else { + throw "获取图集的磁盘url路径不存在!"; + } + } + static sendSinglePicToOpenDataContext(url) { + var tempTextureUrl = Laya.URL.formatURL(url); + var fileObj = MiniFileMgr.getFileInfo(tempTextureUrl); + if (fileObj) { + var fileNativeUrl = fileObj.tempFilePath || MiniFileMgr.getFileNativePath(fileObj.md5); + url = tempTextureUrl; + } + else { + fileNativeUrl = url; + } + if (fileNativeUrl) { + KGMiniAdapter.window.qg.postMessage({ url: url, imgNativeUrl: fileNativeUrl, imgReadyUrl: url, isLoad: "openJsondatacontextPic" }); + } + else { + throw "获取图集的磁盘url路径不存在!"; + } + } + static sendJsonDataToDataContext(url) { + if (!KGMiniAdapter.isZiYu) { + var atlasJson = Laya.Loader.getRes(url); + if (atlasJson) { + KGMiniAdapter.window.qg.postMessage({ url: url, atlasdata: atlasJson, isLoad: "openJsondatacontext" }); + } + else { + throw "传递的url没有获取到对应的图集数据信息,请确保图集已经过!"; + } + } + } + } + KGMiniAdapter.IGNORE = new RegExp("[-_.!~*'();/?:@&=+$,#%]|[0-9|A-Z|a-z]"); + KGMiniAdapter.safeEncodeURI = function (str) { + var strTemp = ""; + var length = str.length; + for (var i = 0; i < length; i++) { + var word = str[i]; + if (KGMiniAdapter.IGNORE.test(word)) { + strTemp += word; + } + else { + try { + strTemp += encodeURI(word); + } + catch (e) { + console.log("errorInfo", ">>>" + word); + } + } + } + return strTemp; + }; + KGMiniAdapter._inited = false; + KGMiniAdapter.autoCacheFile = true; + KGMiniAdapter.minClearSize = (5 * 1024 * 1024); + KGMiniAdapter.sizeLimit = (50 * 1024 * 1024); + KGMiniAdapter.nativefiles = ["layaNativeDir", "wxlocal"]; + KGMiniAdapter.subNativeFiles = []; + KGMiniAdapter.subNativeheads = []; + KGMiniAdapter.subMaps = []; + KGMiniAdapter.AutoCacheDownFile = false; + KGMiniAdapter.parseXMLFromString = function (value) { + var rst; + value = value.replace(/>\s+<'); + try { + rst = (new KGMiniAdapter.window.Parser.DOMParser()).parseFromString(value, 'text/xml'); + } + catch (error) { + throw "需要引入xml解析库文件"; + } + return rst; + }; + KGMiniAdapter.idx = 1; + + class MiniAccelerator extends Laya.EventDispatcher { + constructor() { + super(); + } + static __init__() { + try { + var Acc; + Acc = Laya.Accelerator; + if (!Acc) + return; + Acc["prototype"]["on"] = MiniAccelerator["prototype"]["on"]; + Acc["prototype"]["off"] = MiniAccelerator["prototype"]["off"]; + } + catch (e) { + } + } + static startListen(callBack) { + MiniAccelerator._callBack = callBack; + if (MiniAccelerator._isListening) + return; + MiniAccelerator._isListening = true; + try { + KGMiniAdapter.window.swan.onAccelerometerChange(MiniAccelerator.onAccelerometerChange); + } + catch (e) { } + } + static stopListen() { + MiniAccelerator._isListening = false; + try { + KGMiniAdapter.window.swan.stopAccelerometer({}); + } + catch (e) { } + } + static onAccelerometerChange(res) { + var e; + e = {}; + e.acceleration = res; + e.accelerationIncludingGravity = res; + e.rotationRate = {}; + if (MiniAccelerator._callBack != null) { + MiniAccelerator._callBack(e); + } + } + on(type, caller, listener, args = null) { + super.on(type, caller, listener, args); + MiniAccelerator.startListen(this["onDeviceOrientationChange"]); + return this; + } + off(type, caller, listener, onceOnly = false) { + if (!this.hasListener(type)) + MiniAccelerator.stopListen(); + return super.off(type, caller, listener, onceOnly); + } + } + MiniAccelerator._isListening = false; + + class MiniImage { + _loadImage(url) { + var thisLoader = this; + if (KGMiniAdapter.isZiYu) { + MiniImage.onCreateImage(url, thisLoader, true); + return; + } + var isTransformUrl; + if (!MiniFileMgr.isLocalNativeFile(url)) { + isTransformUrl = true; + url = Laya.URL.formatURL(url); + } + else { + if (url.indexOf("http://usr/") == -1 && (url.indexOf("http://") != -1 || url.indexOf("https://") != -1)) { + if (MiniFileMgr.loadPath != "") { + url = url.split(MiniFileMgr.loadPath)[1]; + } + else { + var tempStr = Laya.URL.rootPath != "" ? Laya.URL.rootPath : Laya.URL._basePath; + var tempUrl = url; + if (tempStr != "") + url = url.split(tempStr)[1]; + if (!url) { + url = tempUrl; + } + } + } + if (KGMiniAdapter.subNativeFiles && KGMiniAdapter.subNativeheads.length == 0) { + for (var key in KGMiniAdapter.subNativeFiles) { + var tempArr = KGMiniAdapter.subNativeFiles[key]; + KGMiniAdapter.subNativeheads = KGMiniAdapter.subNativeheads.concat(tempArr); + for (var aa = 0; aa < tempArr.length; aa++) { + KGMiniAdapter.subMaps[tempArr[aa]] = key + "/" + tempArr[aa]; + } + } + } + if (KGMiniAdapter.subNativeFiles && url.indexOf("/") != -1) { + var curfileHead = url.split("/")[0] + "/"; + if (curfileHead && KGMiniAdapter.subNativeheads.indexOf(curfileHead) != -1) { + var newfileHead = KGMiniAdapter.subMaps[curfileHead]; + url = url.replace(curfileHead, newfileHead); + } + } + } + if (!MiniFileMgr.getFileInfo(url)) { + if (url.indexOf('http://usr/') == -1 && (url.indexOf("http://") != -1 || url.indexOf("https://") != -1)) { + if (KGMiniAdapter.isZiYu) { + MiniImage.onCreateImage(url, thisLoader, true); + } + else { + MiniFileMgr.downOtherFiles(url, new Laya.Handler(MiniImage, MiniImage.onDownImgCallBack, [url, thisLoader]), url); + } + } + else + MiniImage.onCreateImage(url, thisLoader, true); + } + else { + MiniImage.onCreateImage(url, thisLoader, !isTransformUrl); + } + } + static onDownImgCallBack(sourceUrl, thisLoader, errorCode, tempFilePath = "") { + if (!errorCode) + MiniImage.onCreateImage(sourceUrl, thisLoader, false, tempFilePath); + else { + thisLoader.onError(null); + } + } + static onCreateImage(sourceUrl, thisLoader, isLocal = false, tempFilePath = "") { + var fileNativeUrl; + if (KGMiniAdapter.autoCacheFile) { + if (!isLocal) { + if (tempFilePath != "") { + fileNativeUrl = tempFilePath; + } + else { + var fileObj = MiniFileMgr.getFileInfo(sourceUrl); + var fileMd5Name = fileObj.md5; + fileNativeUrl = MiniFileMgr.getFileNativePath(fileMd5Name); + } + } + else if (KGMiniAdapter.isZiYu) { + var tempUrl = Laya.URL.formatURL(sourceUrl); + if (MiniFileMgr.ziyuFileTextureData[tempUrl]) { + fileNativeUrl = MiniFileMgr.ziyuFileTextureData[tempUrl]; + } + else + fileNativeUrl = sourceUrl; + } + else + fileNativeUrl = sourceUrl; + } + else { + if (!isLocal) + fileNativeUrl = tempFilePath; + else + fileNativeUrl = sourceUrl; + } + if (thisLoader._imgCache == null) + thisLoader._imgCache = {}; + var image; + function clear() { + var img = thisLoader._imgCache[fileNativeUrl]; + if (img) { + img.onload = null; + img.onerror = null; + delete thisLoader._imgCache[fileNativeUrl]; + } + } + var onerror = function () { + clear(); + delete MiniFileMgr.fakeObj[sourceUrl]; + delete MiniFileMgr.filesListObj[sourceUrl]; + thisLoader.event(Laya.Event.ERROR, "Load image failed"); + }; + if (thisLoader._type == "nativeimage") { + var onload = function () { + clear(); + thisLoader.onLoaded(image); + }; + image = new Laya.Browser.window.Image(); + image.crossOrigin = ""; + image.onload = onload; + image.onerror = onerror; + image.src = fileNativeUrl; + thisLoader._imgCache[fileNativeUrl] = image; + } + else { + var imageSource = new Laya.Browser.window.Image(); + onload = function () { + image = Laya.HTMLImage.create(imageSource.width, imageSource.height); + image.loadImageSource(imageSource, true); + image._setCreateURL(fileNativeUrl); + clear(); + thisLoader.onLoaded(image); + }; + imageSource.crossOrigin = ""; + imageSource.onload = onload; + imageSource.onerror = onerror; + imageSource.src = fileNativeUrl; + thisLoader._imgCache[fileNativeUrl] = imageSource; + } + } + } + + class MiniLocalStorage { + constructor() { + } + static __init__() { + MiniLocalStorage.items = MiniLocalStorage; + } + static setItem(key, value) { + try { + KGMiniAdapter.window.qg.setStorageSync(key, value); + } + catch (error) { + KGMiniAdapter.window.qg.setStorage({ + key: key, + data: value + }); + } + } + static getItem(key) { + return KGMiniAdapter.window.qg.getStorageSync(key); + } + static setJSON(key, value) { + MiniLocalStorage.setItem(key, value); + } + static getJSON(key) { + return MiniLocalStorage.getItem(key); + } + static removeItem(key) { + KGMiniAdapter.window.qg.removeStorageSync(key); + } + static clear() { + KGMiniAdapter.window.qg.clearStorageSync(); + } + static getStorageInfoSync() { + try { + var res = KGMiniAdapter.window.qg.getStorageInfoSync(); + console.log(res.keys); + console.log(res.currentSize); + console.log(res.limitSize); + return res; + } + catch (e) { + } + return null; + } + } + MiniLocalStorage.support = true; + + class MiniLocation { + constructor() { + } + static __init__() { + KGMiniAdapter.window.navigator.geolocation.getCurrentPosition = MiniLocation.getCurrentPosition; + KGMiniAdapter.window.navigator.geolocation.watchPosition = MiniLocation.watchPosition; + KGMiniAdapter.window.navigator.geolocation.clearWatch = MiniLocation.clearWatch; + } + static getCurrentPosition(success = null, error = null, options = null) { + var paramO; + paramO = {}; + paramO.success = getSuccess; + paramO.fail = error; + KGMiniAdapter.window.qg.getLocation(paramO); + function getSuccess(res) { + if (success != null) { + success(res); + } + } + } + static watchPosition(success = null, error = null, options = null) { + MiniLocation._curID++; + var curWatchO; + curWatchO = {}; + curWatchO.success = success; + curWatchO.error = error; + MiniLocation._watchDic[MiniLocation._curID] = curWatchO; + Laya.Laya.systemTimer.loop(1000, null, MiniLocation._myLoop); + return MiniLocation._curID; + } + static clearWatch(id) { + delete MiniLocation._watchDic[id]; + if (!MiniLocation._hasWatch()) { + Laya.Laya.systemTimer.clear(null, MiniLocation._myLoop); + } + } + static _hasWatch() { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key]) + return true; + } + return false; + } + static _myLoop() { + MiniLocation.getCurrentPosition(MiniLocation._mySuccess, MiniLocation._myError); + } + static _mySuccess(res) { + var rst = {}; + rst.coords = res; + rst.timestamp = Laya.Browser.now(); + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].success) { + MiniLocation._watchDic[key].success(rst); + } + } + } + static _myError(res) { + var key; + for (key in MiniLocation._watchDic) { + if (MiniLocation._watchDic[key].error) { + MiniLocation._watchDic[key].error(res); + } + } + } + } + MiniLocation._watchDic = {}; + MiniLocation._curID = 0; + + class MiniVideo { + constructor(width = 320, height = 240) { + this.videoend = false; + this.videourl = ""; + this.videoElement = KGMiniAdapter.window.qg.createVideo({ width: width, height: height, autoplay: true }); + } + static __init__() { + } + on(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.onPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.onEnded = this.onEndedFunction.bind(this); + } + this.videoElement.onTimeUpdate = this.onTimeUpdateFunc.bind(this); + } + onTimeUpdateFunc(data) { + this.position = data.position; + this._duration = data.duration; + } + get duration() { + return this._duration; + } + onPlayFunction() { + if (this.videoElement) + this.videoElement.readyState = 200; + console.log("=====视频加载完成========"); + this.onPlayFunc != null && this.onPlayFunc(); + } + onEndedFunction() { + if (!this.videoElement) + return; + this.videoend = true; + console.log("=====视频播放完毕========"); + this.onEndedFunC != null && this.onEndedFunC(); + } + off(eventType, ths, callBack) { + if (eventType == "loadedmetadata") { + this.onPlayFunc = callBack.bind(ths); + this.videoElement.offPlay = this.onPlayFunction.bind(this); + } + else if (eventType == "ended") { + this.onEndedFunC = callBack.bind(ths); + this.videoElement.offEnded = this.onEndedFunction.bind(this); + } + } + load(url) { + if (!this.videoElement) + return; + this.videoElement.src = url; + } + play() { + if (!this.videoElement) + return; + this.videoend = false; + this.videoElement.play(); + } + pause() { + if (!this.videoElement) + return; + this.videoend = true; + this.videoElement.pause(); + } + get currentTime() { + if (!this.videoElement) + return 0; + return this.videoElement.initialTime; + } + set currentTime(value) { + if (!this.videoElement) + return; + this.videoElement.initialTime = value; + } + get videoWidth() { + if (!this.videoElement) + return 0; + return this.videoElement.width; + } + get videoHeight() { + if (!this.videoElement) + return 0; + return this.videoElement.height; + } + get ended() { + return this.videoend; + } + get loop() { + if (!this.videoElement) + return false; + return this.videoElement.loop; + } + set loop(value) { + if (!this.videoElement) + return; + this.videoElement.loop = value; + } + get playbackRate() { + if (!this.videoElement) + return 0; + return this.videoElement.playbackRate; + } + set playbackRate(value) { + if (!this.videoElement) + return; + this.videoElement.playbackRate = value; + } + get muted() { + if (!this.videoElement) + return false; + return this.videoElement.muted; + } + set muted(value) { + if (!this.videoElement) + return; + this.videoElement.muted = value; + } + get paused() { + if (!this.videoElement) + return false; + return this.videoElement.paused; + } + size(width, height) { + if (!this.videoElement) + return; + this.videoElement.width = width; + this.videoElement.height = height; + } + get x() { + if (!this.videoElement) + return 0; + return this.videoElement.x; + } + set x(value) { + if (!this.videoElement) + return; + this.videoElement.x = value; + } + get y() { + if (!this.videoElement) + return 0; + return this.videoElement.y; + } + set y(value) { + if (!this.videoElement) + return; + this.videoElement.y = value; + } + get currentSrc() { + return this.videoElement.src; + } + destroy() { + if (this.videoElement) + this.videoElement.destroy(); + this.videoElement = null; + this.onEndedFunC = null; + this.onPlayFunc = null; + this.videoend = false; + this.videourl = null; + } + reload() { + if (!this.videoElement) + return; + this.videoElement.src = this.videourl; + } + } + + exports.ImageDataPolyfill = ImageDataPolyfill; + exports.KGMiniAdapter = KGMiniAdapter; + exports.MiniAccelerator = MiniAccelerator; + exports.MiniFileMgr = MiniFileMgr; + exports.MiniImage = MiniImage; + exports.MiniInput = MiniInput; + exports.MiniLoader = MiniLoader; + exports.MiniLocalStorage = MiniLocalStorage; + exports.MiniLocation = MiniLocation; + exports.MiniSound = MiniSound; + exports.MiniSoundChannel = MiniSoundChannel; + exports.MiniVideo = MiniVideo; + +} diff --git a/examples/layaair/frontend/bin/libs/min/bytebuffer.min.js b/examples/layaair/frontend/bin/libs/min/bytebuffer.min.js new file mode 100644 index 0000000..c49a4a5 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/min/bytebuffer.min.js @@ -0,0 +1,7 @@ +/** + * @license bytebuffer.js (c) 2015 Daniel Wirtz + * Backing buffer: ArrayBuffer, Accessor: Uint8Array + * Released under the Apache License, Version 2.0 + * see: https://github.com/dcodeIO/bytebuffer.js for details + */ +!function(t,e){"function"==typeof define&&define.amd?define(["long"],e):"function"==typeof require&&"object"==typeof module&&module&&module.exports?module.exports=function(){var t;try{t=require("long")}catch(t){}return e(t)}():(t.dcodeIO=t.dcodeIO||{}).ByteBuffer=e(t.dcodeIO.Long)}(this,(function(t){"use strict";var ByteBuffer=function(t,e,i){if(void 0===t&&(t=ByteBuffer.DEFAULT_CAPACITY),void 0===e&&(e=ByteBuffer.DEFAULT_ENDIAN),void 0===i&&(i=ByteBuffer.DEFAULT_NOASSERT),!i){if((t|=0)<0)throw RangeError("Illegal capacity");e=!!e,i=!!i}this.buffer=0===t?r:new ArrayBuffer(t),this.view=0===t?null:new Uint8Array(this.buffer),this.offset=0,this.markedOffset=-1,this.limit=t,this.littleEndian=e,this.noAssert=i};ByteBuffer.VERSION="5.0.1",ByteBuffer.LITTLE_ENDIAN=!0,ByteBuffer.BIG_ENDIAN=!1,ByteBuffer.DEFAULT_CAPACITY=16,ByteBuffer.DEFAULT_ENDIAN=ByteBuffer.BIG_ENDIAN,ByteBuffer.DEFAULT_NOASSERT=!1,ByteBuffer.Long=t||null;var e=ByteBuffer.prototype;e.__isByteBuffer__,Object.defineProperty(e,"__isByteBuffer__",{value:!0,enumerable:!1,configurable:!1});var r=new ArrayBuffer(0),i=String.fromCharCode;function stringSource(t){var e=0;return function(){return e1024&&(e.push(i.apply(String,t)),t.length=0),Array.prototype.push.apply(t,arguments)}}function ieee754_read(t,e,r,i,n){var f,o,s=8*n-i-1,h=(1<>1,l=-7,u=r?n-1:0,g=r?-1:1,w=t[e+u];for(u+=g,f=w&(1<<-l)-1,w>>=-l,l+=s;l>0;f=256*f+t[e+u],u+=g,l-=8);for(o=f&(1<<-l)-1,f>>=-l,l+=i;l>0;o=256*o+t[e+u],u+=g,l-=8);if(0===f)f=1-a;else{if(f===h)return o?NaN:1/0*(w?-1:1);o+=Math.pow(2,i),f-=a}return(w?-1:1)*o*Math.pow(2,f-i)}function ieee754_write(t,e,r,i,n,f){var o,s,h,a=8*f-n-1,l=(1<>1,g=23===n?Math.pow(2,-24)-Math.pow(2,-77):0,w=i?0:f-1,b=i?1:-1,v=e<0||0===e&&1/e<0?1:0;for(e=Math.abs(e),isNaN(e)||e===1/0?(s=isNaN(e)?1:0,o=l):(o=Math.floor(Math.log(e)/Math.LN2),e*(h=Math.pow(2,-o))<1&&(o--,h*=2),(e+=o+u>=1?g/h:g*Math.pow(2,1-u))*h>=2&&(o++,h/=2),o+u>=l?(s=0,o=l):o+u>=1?(s=(e*h-1)*Math.pow(2,n),o+=u):(s=e*Math.pow(2,u-1)*Math.pow(2,n),o=0));n>=8;t[r+w]=255&s,w+=b,s/=256,n-=8);for(o=o<0;t[r+w]=255&o,w+=b,o/=256,a-=8);t[r+w-b]|=128*v}ByteBuffer.accessor=function(){return Uint8Array},ByteBuffer.allocate=function(t,e,r){return new ByteBuffer(t,e,r)},ByteBuffer.concat=function(t,e,r,i){"boolean"!=typeof e&&"string"==typeof e||(i=r,r=e,e=void 0);for(var n,f=0,o=0,s=t.length;o0&&(f+=n);if(0===f)return new ByteBuffer(0,r,i);var h,a=new ByteBuffer(f,r,i);for(o=0;o0&&(f.buffer=t.buffer,f.offset=t.byteOffset,f.limit=t.byteOffset+t.byteLength,f.view=new Uint8Array(t.buffer));else if(t instanceof ArrayBuffer)f=new ByteBuffer(0,i,n),t.byteLength>0&&(f.buffer=t,f.offset=0,f.limit=t.byteLength,f.view=t.byteLength>0?new Uint8Array(t):null);else{if("[object Array]"!==Object.prototype.toString.call(t))throw TypeError("Illegal buffer");(f=new ByteBuffer(t.length,i,n)).limit=t.length;for(var o=0;o>>=0)<0||e+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+0) <= "+this.buffer.byteLength)}var i,n=e,f=t.length,o=f>>3,s=0;for(e+=this.writeVarint32(f,e);o--;)i=1&!!t[s++]|(1&!!t[s++])<<1|(1&!!t[s++])<<2|(1&!!t[s++])<<3|(1&!!t[s++])<<4|(1&!!t[s++])<<5|(1&!!t[s++])<<6|(1&!!t[s++])<<7,this.writeByte(i,e++);if(s>3,o=0,s=[];for(t+=i.length;f--;)r=this.readByte(t++),s[o++]=!!(1&r),s[o++]=!!(2&r),s[o++]=!!(4&r),s[o++]=!!(8&r),s[o++]=!!(16&r),s[o++]=!!(32&r),s[o++]=!!(64&r),s[o++]=!!(128&r);if(o>h++&1)}return e&&(this.offset=t),s},e.readBytes=function(t,e){var r=void 0===e;if(r&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+t>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+"+t+") <= "+this.buffer.byteLength)}var i=this.slice(e,e+t);return r&&(this.offset+=t),i},e.writeBytes=e.append,e.writeInt8=function(t,e){var r=void 0===e;if(r&&(e=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal value: "+t+" (not an integer)");if(t|=0,"number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+0) <= "+this.buffer.byteLength)}e+=1;var i=this.buffer.byteLength;return e>i&&this.resize((i*=2)>e?i:e),e-=1,this.view[e]=t,r&&(this.offset+=1),this},e.writeByte=e.writeInt8,e.readInt8=function(t){var e=void 0===t;if(e&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+1) <= "+this.buffer.byteLength)}var r=this.view[t];return 128==(128&r)&&(r=-(255-r+1)),e&&(this.offset+=1),r},e.readByte=e.readInt8,e.writeUint8=function(t,e){var r=void 0===e;if(r&&(e=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal value: "+t+" (not an integer)");if(t>>>=0,"number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+0) <= "+this.buffer.byteLength)}e+=1;var i=this.buffer.byteLength;return e>i&&this.resize((i*=2)>e?i:e),e-=1,this.view[e]=t,r&&(this.offset+=1),this},e.writeUInt8=e.writeUint8,e.readUint8=function(t){var e=void 0===t;if(e&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+1) <= "+this.buffer.byteLength)}var r=this.view[t];return e&&(this.offset+=1),r},e.readUInt8=e.readUint8,e.writeInt16=function(t,e){var r=void 0===e;if(r&&(e=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal value: "+t+" (not an integer)");if(t|=0,"number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+0) <= "+this.buffer.byteLength)}e+=2;var i=this.buffer.byteLength;return e>i&&this.resize((i*=2)>e?i:e),e-=2,this.littleEndian?(this.view[e+1]=(65280&t)>>>8,this.view[e]=255&t):(this.view[e]=(65280&t)>>>8,this.view[e+1]=255&t),r&&(this.offset+=2),this},e.writeShort=e.writeInt16,e.readInt16=function(t){var e=void 0===t;if(e&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+2>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+2) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[t],r|=this.view[t+1]<<8):(r=this.view[t]<<8,r|=this.view[t+1]),32768==(32768&r)&&(r=-(65535-r+1)),e&&(this.offset+=2),r},e.readShort=e.readInt16,e.writeUint16=function(t,e){var r=void 0===e;if(r&&(e=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal value: "+t+" (not an integer)");if(t>>>=0,"number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+0) <= "+this.buffer.byteLength)}e+=2;var i=this.buffer.byteLength;return e>i&&this.resize((i*=2)>e?i:e),e-=2,this.littleEndian?(this.view[e+1]=(65280&t)>>>8,this.view[e]=255&t):(this.view[e]=(65280&t)>>>8,this.view[e+1]=255&t),r&&(this.offset+=2),this},e.writeUInt16=e.writeUint16,e.readUint16=function(t){var e=void 0===t;if(e&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+2>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+2) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[t],r|=this.view[t+1]<<8):(r=this.view[t]<<8,r|=this.view[t+1]),e&&(this.offset+=2),r},e.readUInt16=e.readUint16,e.writeInt32=function(t,e){var r=void 0===e;if(r&&(e=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal value: "+t+" (not an integer)");if(t|=0,"number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+0) <= "+this.buffer.byteLength)}e+=4;var i=this.buffer.byteLength;return e>i&&this.resize((i*=2)>e?i:e),e-=4,this.littleEndian?(this.view[e+3]=t>>>24&255,this.view[e+2]=t>>>16&255,this.view[e+1]=t>>>8&255,this.view[e]=255&t):(this.view[e]=t>>>24&255,this.view[e+1]=t>>>16&255,this.view[e+2]=t>>>8&255,this.view[e+3]=255&t),r&&(this.offset+=4),this},e.writeInt=e.writeInt32,e.readInt32=function(t){var e=void 0===t;if(e&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+4) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[t+2]<<16,r|=this.view[t+1]<<8,r|=this.view[t],r+=this.view[t+3]<<24>>>0):(r=this.view[t+1]<<16,r|=this.view[t+2]<<8,r|=this.view[t+3],r+=this.view[t]<<24>>>0),r|=0,e&&(this.offset+=4),r},e.readInt=e.readInt32,e.writeUint32=function(t,e){var r=void 0===e;if(r&&(e=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal value: "+t+" (not an integer)");if(t>>>=0,"number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+0) <= "+this.buffer.byteLength)}e+=4;var i=this.buffer.byteLength;return e>i&&this.resize((i*=2)>e?i:e),e-=4,this.littleEndian?(this.view[e+3]=t>>>24&255,this.view[e+2]=t>>>16&255,this.view[e+1]=t>>>8&255,this.view[e]=255&t):(this.view[e]=t>>>24&255,this.view[e+1]=t>>>16&255,this.view[e+2]=t>>>8&255,this.view[e+3]=255&t),r&&(this.offset+=4),this},e.writeUInt32=e.writeUint32,e.readUint32=function(t){var e=void 0===t;if(e&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+4) <= "+this.buffer.byteLength)}var r=0;return this.littleEndian?(r=this.view[t+2]<<16,r|=this.view[t+1]<<8,r|=this.view[t],r+=this.view[t+3]<<24>>>0):(r=this.view[t+1]<<16,r|=this.view[t+2]<<8,r|=this.view[t+3],r+=this.view[t]<<24>>>0),e&&(this.offset+=4),r},e.readUInt32=e.readUint32,t&&(e.writeInt64=function(e,r){var i=void 0===r;if(i&&(r=this.offset),!this.noAssert){if("number"==typeof e)e=t.fromNumber(e);else if("string"==typeof e)e=t.fromString(e);else if(!(e&&e instanceof t))throw TypeError("Illegal value: "+e+" (not an integer or Long)");if("number"!=typeof r||r%1!=0)throw TypeError("Illegal offset: "+r+" (not an integer)");if((r>>>=0)<0||r+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+0) <= "+this.buffer.byteLength)}"number"==typeof e?e=t.fromNumber(e):"string"==typeof e&&(e=t.fromString(e)),r+=8;var n=this.buffer.byteLength;r>n&&this.resize((n*=2)>r?n:r),r-=8;var f=e.low,o=e.high;return this.littleEndian?(this.view[r+3]=f>>>24&255,this.view[r+2]=f>>>16&255,this.view[r+1]=f>>>8&255,this.view[r]=255&f,r+=4,this.view[r+3]=o>>>24&255,this.view[r+2]=o>>>16&255,this.view[r+1]=o>>>8&255,this.view[r]=255&o):(this.view[r]=o>>>24&255,this.view[r+1]=o>>>16&255,this.view[r+2]=o>>>8&255,this.view[r+3]=255&o,r+=4,this.view[r]=f>>>24&255,this.view[r+1]=f>>>16&255,this.view[r+2]=f>>>8&255,this.view[r+3]=255&f),i&&(this.offset+=8),this},e.writeLong=e.writeInt64,e.readInt64=function(e){var r=void 0===e;if(r&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+8) <= "+this.buffer.byteLength)}var i=0,n=0;this.littleEndian?(i=this.view[e+2]<<16,i|=this.view[e+1]<<8,i|=this.view[e],i+=this.view[e+3]<<24>>>0,e+=4,n=this.view[e+2]<<16,n|=this.view[e+1]<<8,n|=this.view[e],n+=this.view[e+3]<<24>>>0):(n=this.view[e+1]<<16,n|=this.view[e+2]<<8,n|=this.view[e+3],n+=this.view[e]<<24>>>0,e+=4,i=this.view[e+1]<<16,i|=this.view[e+2]<<8,i|=this.view[e+3],i+=this.view[e]<<24>>>0);var f=new t(i,n,!1);return r&&(this.offset+=8),f},e.readLong=e.readInt64,e.writeUint64=function(e,r){var i=void 0===r;if(i&&(r=this.offset),!this.noAssert){if("number"==typeof e)e=t.fromNumber(e);else if("string"==typeof e)e=t.fromString(e);else if(!(e&&e instanceof t))throw TypeError("Illegal value: "+e+" (not an integer or Long)");if("number"!=typeof r||r%1!=0)throw TypeError("Illegal offset: "+r+" (not an integer)");if((r>>>=0)<0||r+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+0) <= "+this.buffer.byteLength)}"number"==typeof e?e=t.fromNumber(e):"string"==typeof e&&(e=t.fromString(e)),r+=8;var n=this.buffer.byteLength;r>n&&this.resize((n*=2)>r?n:r),r-=8;var f=e.low,o=e.high;return this.littleEndian?(this.view[r+3]=f>>>24&255,this.view[r+2]=f>>>16&255,this.view[r+1]=f>>>8&255,this.view[r]=255&f,r+=4,this.view[r+3]=o>>>24&255,this.view[r+2]=o>>>16&255,this.view[r+1]=o>>>8&255,this.view[r]=255&o):(this.view[r]=o>>>24&255,this.view[r+1]=o>>>16&255,this.view[r+2]=o>>>8&255,this.view[r+3]=255&o,r+=4,this.view[r]=f>>>24&255,this.view[r+1]=f>>>16&255,this.view[r+2]=f>>>8&255,this.view[r+3]=255&f),i&&(this.offset+=8),this},e.writeUInt64=e.writeUint64,e.readUint64=function(e){var r=void 0===e;if(r&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+8) <= "+this.buffer.byteLength)}var i=0,n=0;this.littleEndian?(i=this.view[e+2]<<16,i|=this.view[e+1]<<8,i|=this.view[e],i+=this.view[e+3]<<24>>>0,e+=4,n=this.view[e+2]<<16,n|=this.view[e+1]<<8,n|=this.view[e],n+=this.view[e+3]<<24>>>0):(n=this.view[e+1]<<16,n|=this.view[e+2]<<8,n|=this.view[e+3],n+=this.view[e]<<24>>>0,e+=4,i=this.view[e+1]<<16,i|=this.view[e+2]<<8,i|=this.view[e+3],i+=this.view[e]<<24>>>0);var f=new t(i,n,!0);return r&&(this.offset+=8),f},e.readUInt64=e.readUint64),e.writeFloat32=function(t,e){var r=void 0===e;if(r&&(e=this.offset),!this.noAssert){if("number"!=typeof t)throw TypeError("Illegal value: "+t+" (not a number)");if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+0) <= "+this.buffer.byteLength)}e+=4;var i=this.buffer.byteLength;return e>i&&this.resize((i*=2)>e?i:e),e-=4,ieee754_write(this.view,t,e,this.littleEndian,23,4),r&&(this.offset+=4),this},e.writeFloat=e.writeFloat32,e.readFloat32=function(t){var e=void 0===t;if(e&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+4) <= "+this.buffer.byteLength)}var r=ieee754_read(this.view,t,this.littleEndian,23,4);return e&&(this.offset+=4),r},e.readFloat=e.readFloat32,e.writeFloat64=function(t,e){var r=void 0===e;if(r&&(e=this.offset),!this.noAssert){if("number"!=typeof t)throw TypeError("Illegal value: "+t+" (not a number)");if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+0) <= "+this.buffer.byteLength)}e+=8;var i=this.buffer.byteLength;return e>i&&this.resize((i*=2)>e?i:e),e-=8,ieee754_write(this.view,t,e,this.littleEndian,52,8),r&&(this.offset+=8),this},e.writeDouble=e.writeFloat64,e.readFloat64=function(t){var e=void 0===t;if(e&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+8) <= "+this.buffer.byteLength)}var r=ieee754_read(this.view,t,this.littleEndian,52,8);return e&&(this.offset+=8),r},e.readDouble=e.readFloat64,ByteBuffer.MAX_VARINT32_BYTES=5,ByteBuffer.calculateVarint32=function(t){return(t>>>=0)<128?1:t<16384?2:t<1<<21?3:t<1<<28?4:5},ByteBuffer.zigZagEncode32=function(t){return((t|=0)<<1^t>>31)>>>0},ByteBuffer.zigZagDecode32=function(t){return t>>>1^-(1&t)|0},e.writeVarint32=function(t,e){var r=void 0===e;if(r&&(e=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal value: "+t+" (not an integer)");if(t|=0,"number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+0) <= "+this.buffer.byteLength)}var i,n=ByteBuffer.calculateVarint32(t);e+=n;var f=this.buffer.byteLength;for(e>f&&this.resize((f*=2)>e?f:e),e-=n,t>>>=0;t>=128;)i=127&t|128,this.view[e++]=i,t>>>=7;return this.view[e++]=t,r?(this.offset=e,this):n},e.writeVarint32ZigZag=function(t,e){return this.writeVarint32(ByteBuffer.zigZagEncode32(t),e)},e.readVarint32=function(t){var e=void 0===t;if(e&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+1) <= "+this.buffer.byteLength)}var r,i=0,n=0;do{if(!this.noAssert&&t>this.limit){var f=Error("Truncated");throw f.truncated=!0,f}r=this.view[t++],i<5&&(n|=(127&r)<<7*i),++i}while(0!=(128&r));return n|=0,e?(this.offset=t,n):{value:n,length:i}},e.readVarint32ZigZag=function(t){var e=this.readVarint32(t);return"object"==typeof e?e.value=ByteBuffer.zigZagDecode32(e.value):e=ByteBuffer.zigZagDecode32(e),e},t&&(ByteBuffer.MAX_VARINT64_BYTES=10,ByteBuffer.calculateVarint64=function(e){"number"==typeof e?e=t.fromNumber(e):"string"==typeof e&&(e=t.fromString(e));var r=e.toInt()>>>0,i=e.shiftRightUnsigned(28).toInt()>>>0,n=e.shiftRightUnsigned(56).toInt()>>>0;return 0==n?0==i?r<16384?r<128?1:2:r<1<<21?3:4:i<16384?i<128?5:6:i<1<<21?7:8:n<128?9:10},ByteBuffer.zigZagEncode64=function(e){return"number"==typeof e?e=t.fromNumber(e,!1):"string"==typeof e?e=t.fromString(e,!1):!1!==e.unsigned&&(e=e.toSigned()),e.shiftLeft(1).xor(e.shiftRight(63)).toUnsigned()},ByteBuffer.zigZagDecode64=function(e){return"number"==typeof e?e=t.fromNumber(e,!1):"string"==typeof e?e=t.fromString(e,!1):!1!==e.unsigned&&(e=e.toSigned()),e.shiftRightUnsigned(1).xor(e.and(t.ONE).toSigned().negate()).toSigned()},e.writeVarint64=function(e,r){var i=void 0===r;if(i&&(r=this.offset),!this.noAssert){if("number"==typeof e)e=t.fromNumber(e);else if("string"==typeof e)e=t.fromString(e);else if(!(e&&e instanceof t))throw TypeError("Illegal value: "+e+" (not an integer or Long)");if("number"!=typeof r||r%1!=0)throw TypeError("Illegal offset: "+r+" (not an integer)");if((r>>>=0)<0||r+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+0) <= "+this.buffer.byteLength)}"number"==typeof e?e=t.fromNumber(e,!1):"string"==typeof e?e=t.fromString(e,!1):!1!==e.unsigned&&(e=e.toSigned());var n=ByteBuffer.calculateVarint64(e),f=e.toInt()>>>0,o=e.shiftRightUnsigned(28).toInt()>>>0,s=e.shiftRightUnsigned(56).toInt()>>>0;r+=n;var h=this.buffer.byteLength;switch(r>h&&this.resize((h*=2)>r?h:r),r-=n,n){case 10:this.view[r+9]=s>>>7&1;case 9:this.view[r+8]=9!==n?128|s:127&s;case 8:this.view[r+7]=8!==n?o>>>21|128:o>>>21&127;case 7:this.view[r+6]=7!==n?o>>>14|128:o>>>14&127;case 6:this.view[r+5]=6!==n?o>>>7|128:o>>>7&127;case 5:this.view[r+4]=5!==n?128|o:127&o;case 4:this.view[r+3]=4!==n?f>>>21|128:f>>>21&127;case 3:this.view[r+2]=3!==n?f>>>14|128:f>>>14&127;case 2:this.view[r+1]=2!==n?f>>>7|128:f>>>7&127;case 1:this.view[r]=1!==n?128|f:127&f}return i?(this.offset+=n,this):n},e.writeVarint64ZigZag=function(t,e){return this.writeVarint64(ByteBuffer.zigZagEncode64(t),e)},e.readVarint64=function(e){var r=void 0===e;if(r&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+1) <= "+this.buffer.byteLength)}var i=e,n=0,f=0,o=0,s=0;if(n=127&(s=this.view[e++]),128&s&&(n|=(127&(s=this.view[e++]))<<7,(128&s||this.noAssert&&void 0===s)&&(n|=(127&(s=this.view[e++]))<<14,(128&s||this.noAssert&&void 0===s)&&(n|=(127&(s=this.view[e++]))<<21,(128&s||this.noAssert&&void 0===s)&&(f=127&(s=this.view[e++]),(128&s||this.noAssert&&void 0===s)&&(f|=(127&(s=this.view[e++]))<<7,(128&s||this.noAssert&&void 0===s)&&(f|=(127&(s=this.view[e++]))<<14,(128&s||this.noAssert&&void 0===s)&&(f|=(127&(s=this.view[e++]))<<21,(128&s||this.noAssert&&void 0===s)&&(o=127&(s=this.view[e++]),(128&s||this.noAssert&&void 0===s)&&(o|=(127&(s=this.view[e++]))<<7,128&s||this.noAssert&&void 0===s))))))))))throw Error("Buffer overrun");var h=t.fromBits(n|f<<28,f>>>4|o<<24,!1);return r?(this.offset=e,h):{value:h,length:e-i}},e.readVarint64ZigZag=function(e){var r=this.readVarint64(e);return r&&r.value instanceof t?r.value=ByteBuffer.zigZagDecode64(r.value):r=ByteBuffer.zigZagDecode64(r),r}),e.writeCString=function(t,e){var r=void 0===e;r&&(e=this.offset);var i,n=t.length;if(!this.noAssert){if("string"!=typeof t)throw TypeError("Illegal str: Not a string");for(i=0;i>>=0)<0||e+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+0) <= "+this.buffer.byteLength)}n=f.calculateUTF16asUTF8(stringSource(t))[1],e+=n+1;var o=this.buffer.byteLength;return e>o&&this.resize((o*=2)>e?o:e),e-=n+1,f.encodeUTF16toUTF8(stringSource(t),function(t){this.view[e++]=t}.bind(this)),this.view[e++]=0,r?(this.offset=e,this):n},e.readCString=function(t){var e=void 0===t;if(e&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+1) <= "+this.buffer.byteLength)}var r,i=t,n=-1;return f.decodeUTF8toUTF16(function(){if(0===n)return null;if(t>=this.limit)throw RangeError("Illegal range: Truncated data, "+t+" < "+this.limit);return 0===(n=this.view[t++])?null:n}.bind(this),r=stringDestination(),!0),e?(this.offset=t,r()):{string:r(),length:t-i}},e.writeIString=function(t,e){var r=void 0===e;if(r&&(e=this.offset),!this.noAssert){if("string"!=typeof t)throw TypeError("Illegal str: Not a string");if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+0) <= "+this.buffer.byteLength)}var i,n=e;i=f.calculateUTF16asUTF8(stringSource(t),this.noAssert)[1],e+=4+i;var o=this.buffer.byteLength;if(e>o&&this.resize((o*=2)>e?o:e),e-=4+i,this.littleEndian?(this.view[e+3]=i>>>24&255,this.view[e+2]=i>>>16&255,this.view[e+1]=i>>>8&255,this.view[e]=255&i):(this.view[e]=i>>>24&255,this.view[e+1]=i>>>16&255,this.view[e+2]=i>>>8&255,this.view[e+3]=255&i),e+=4,f.encodeUTF16toUTF8(stringSource(t),function(t){this.view[e++]=t}.bind(this)),e!==n+4+i)throw RangeError("Illegal range: Truncated data, "+e+" == "+(e+4+i));return r?(this.offset=e,this):e-n},e.readIString=function(t){var e=void 0===t;if(e&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+4) <= "+this.buffer.byteLength)}var r=t,i=this.readUint32(t),n=this.readUTF8String(i,ByteBuffer.METRICS_BYTES,t+=4);return t+=n.length,e?(this.offset=t,n.string):{string:n.string,length:t-r}},ByteBuffer.METRICS_CHARS="c",ByteBuffer.METRICS_BYTES="b",e.writeUTF8String=function(t,e){var r,i=void 0===e;if(i&&(e=this.offset),!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: "+e+" (not an integer)");if((e>>>=0)<0||e+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+0) <= "+this.buffer.byteLength)}var n=e;r=f.calculateUTF16asUTF8(stringSource(t))[1],e+=r;var o=this.buffer.byteLength;return e>o&&this.resize((o*=2)>e?o:e),e-=r,f.encodeUTF16toUTF8(stringSource(t),function(t){this.view[e++]=t}.bind(this)),i?(this.offset=e,this):e-n},e.writeString=e.writeUTF8String,ByteBuffer.calculateUTF8Chars=function(t){return f.calculateUTF16asUTF8(stringSource(t))[0]},ByteBuffer.calculateUTF8Bytes=function(t){return f.calculateUTF16asUTF8(stringSource(t))[1]},ByteBuffer.calculateString=ByteBuffer.calculateUTF8Bytes,e.readUTF8String=function(t,e,r){"number"==typeof e&&(r=e,e=void 0);var i=void 0===r;if(i&&(r=this.offset),void 0===e&&(e=ByteBuffer.METRICS_CHARS),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal length: "+t+" (not an integer)");if(t|=0,"number"!=typeof r||r%1!=0)throw TypeError("Illegal offset: "+r+" (not an integer)");if((r>>>=0)<0||r+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+0) <= "+this.buffer.byteLength)}var n,o=0,s=r;if(e===ByteBuffer.METRICS_CHARS){if(n=stringDestination(),f.decodeUTF8(function(){return o>>=0)<0||r+t>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+"+t+") <= "+this.buffer.byteLength)}var h=r+t;if(f.decodeUTF8toUTF16(function(){return r>>=0)<0||e+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+e+" (+0) <= "+this.buffer.byteLength)}var i,n,o=e;i=f.calculateUTF16asUTF8(stringSource(t),this.noAssert)[1],n=ByteBuffer.calculateVarint32(i),e+=n+i;var s=this.buffer.byteLength;if(e>s&&this.resize((s*=2)>e?s:e),e-=n+i,e+=this.writeVarint32(i,e),f.encodeUTF16toUTF8(stringSource(t),function(t){this.view[e++]=t}.bind(this)),e!==o+i+n)throw RangeError("Illegal range: Truncated data, "+e+" == "+(e+i+n));return r?(this.offset=e,this):e-o},e.readVString=function(t){var e=void 0===t;if(e&&(t=this.offset),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal offset: "+t+" (not an integer)");if((t>>>=0)<0||t+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+1) <= "+this.buffer.byteLength)}var r=t,i=this.readVarint32(t),n=this.readUTF8String(i.value,ByteBuffer.METRICS_BYTES,t+=i.length);return t+=n.length,e?(this.offset=t,n.string):{string:n.string,length:t-r}},e.append=function(t,e,r){"number"!=typeof e&&"string"==typeof e||(r=e,e=void 0);var i=void 0===r;if(i&&(r=this.offset),!this.noAssert){if("number"!=typeof r||r%1!=0)throw TypeError("Illegal offset: "+r+" (not an integer)");if((r>>>=0)<0||r+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+0) <= "+this.buffer.byteLength)}t instanceof ByteBuffer||(t=ByteBuffer.wrap(t,e));var n=t.limit-t.offset;if(n<=0)return this;r+=n;var f=this.buffer.byteLength;return r>f&&this.resize((f*=2)>r?f:r),r-=n,this.view.set(t.view.subarray(t.offset,t.limit),r),t.offset+=n,i&&(this.offset+=n),this},e.appendTo=function(t,e){return t.append(this,e),this},e.assert=function(t){return this.noAssert=!t,this},e.capacity=function(){return this.buffer.byteLength},e.clear=function(){return this.offset=0,this.limit=this.buffer.byteLength,this.markedOffset=-1,this},e.clone=function(t){var e=new ByteBuffer(0,this.littleEndian,this.noAssert);return t?(e.buffer=new ArrayBuffer(this.buffer.byteLength),e.view=new Uint8Array(e.buffer)):(e.buffer=this.buffer,e.view=this.view),e.offset=this.offset,e.markedOffset=this.markedOffset,e.limit=this.limit,e},e.compact=function(t,e){if(void 0===t&&(t=this.offset),void 0===e&&(e=this.limit),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal begin: Not an integer");if(t>>>=0,"number"!=typeof e||e%1!=0)throw TypeError("Illegal end: Not an integer");if(e>>>=0,t<0||t>e||e>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+e+" <= "+this.buffer.byteLength)}if(0===t&&e===this.buffer.byteLength)return this;var i=e-t;if(0===i)return this.buffer=r,this.view=null,this.markedOffset>=0&&(this.markedOffset-=t),this.offset=0,this.limit=0,this;var n=new ArrayBuffer(i),f=new Uint8Array(n);return f.set(this.view.subarray(t,e)),this.buffer=n,this.view=f,this.markedOffset>=0&&(this.markedOffset-=t),this.offset=0,this.limit=i,this},e.copy=function(t,e){if(void 0===t&&(t=this.offset),void 0===e&&(e=this.limit),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal begin: Not an integer");if(t>>>=0,"number"!=typeof e||e%1!=0)throw TypeError("Illegal end: Not an integer");if(e>>>=0,t<0||t>e||e>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+e+" <= "+this.buffer.byteLength)}if(t===e)return new ByteBuffer(0,this.littleEndian,this.noAssert);var r=e-t,i=new ByteBuffer(r,this.littleEndian,this.noAssert);return i.offset=0,i.limit=r,i.markedOffset>=0&&(i.markedOffset-=t),this.copyTo(i,0,t,e),i},e.copyTo=function(t,e,r,i){var n,f;if(!this.noAssert&&!ByteBuffer.isByteBuffer(t))throw TypeError("Illegal target: Not a ByteBuffer");if(e=(f=void 0===e)?t.offset:0|e,r=(n=void 0===r)?this.offset:0|r,i=void 0===i?this.limit:0|i,e<0||e>t.buffer.byteLength)throw RangeError("Illegal target range: 0 <= "+e+" <= "+t.buffer.byteLength);if(r<0||i>this.buffer.byteLength)throw RangeError("Illegal source range: 0 <= "+r+" <= "+this.buffer.byteLength);var o=i-r;return 0===o?t:(t.ensureCapacity(e+o),t.view.set(this.view.subarray(r,i),e),n&&(this.offset+=o),f&&(t.offset+=o),this)},e.ensureCapacity=function(t){var e=this.buffer.byteLength;return et?e:t):this},e.fill=function(t,e,r){var i=void 0===e;if(i&&(e=this.offset),"string"==typeof t&&t.length>0&&(t=t.charCodeAt(0)),void 0===e&&(e=this.offset),void 0===r&&(r=this.limit),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal value: "+t+" (not an integer)");if(t|=0,"number"!=typeof e||e%1!=0)throw TypeError("Illegal begin: Not an integer");if(e>>>=0,"number"!=typeof r||r%1!=0)throw TypeError("Illegal end: Not an integer");if(r>>>=0,e<0||e>r||r>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+r+" <= "+this.buffer.byteLength)}if(e>=r)return this;for(;e>>=0)<0||t+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+t+" (+0) <= "+this.buffer.byteLength)}return this.markedOffset=t,this},e.order=function(t){if(!this.noAssert&&"boolean"!=typeof t)throw TypeError("Illegal littleEndian: Not a boolean");return this.littleEndian=!!t,this},e.LE=function(t){return this.littleEndian=void 0===t||!!t,this},e.BE=function(t){return this.littleEndian=void 0!==t&&!t,this},e.prepend=function(t,e,r){"number"!=typeof e&&"string"==typeof e||(r=e,e=void 0);var i=void 0===r;if(i&&(r=this.offset),!this.noAssert){if("number"!=typeof r||r%1!=0)throw TypeError("Illegal offset: "+r+" (not an integer)");if((r>>>=0)<0||r+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+r+" (+0) <= "+this.buffer.byteLength)}t instanceof ByteBuffer||(t=ByteBuffer.wrap(t,e));var n=t.limit-t.offset;if(n<=0)return this;var f=n-r;if(f>0){var o=new ArrayBuffer(this.buffer.byteLength+f),s=new Uint8Array(o);s.set(this.view.subarray(r,this.buffer.byteLength),n),this.buffer=o,this.view=s,this.offset+=f,this.markedOffset>=0&&(this.markedOffset+=f),this.limit+=f,r+=f}else new Uint8Array(this.buffer);return this.view.set(t.view.subarray(t.offset,t.limit),r-n),t.offset=t.limit,i&&(this.offset-=n),this},e.prependTo=function(t,e){return t.prepend(this,e),this},e.printDebug=function(t){"function"!=typeof t&&(t=console.log.bind(console)),t(this.toString()+"\n-------------------------------------------------------------------\n"+this.toDebug(!0))},e.remaining=function(){return this.limit-this.offset},e.reset=function(){return this.markedOffset>=0?(this.offset=this.markedOffset,this.markedOffset=-1):this.offset=0,this},e.resize=function(t){if(!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal capacity: "+t+" (not an integer)");if((t|=0)<0)throw RangeError("Illegal capacity: 0 <= "+t)}if(this.buffer.byteLength>>=0,"number"!=typeof e||e%1!=0)throw TypeError("Illegal end: Not an integer");if(e>>>=0,t<0||t>e||e>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+e+" <= "+this.buffer.byteLength)}return t===e||Array.prototype.reverse.call(this.view.subarray(t,e)),this},e.skip=function(t){if(!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal length: "+t+" (not an integer)");t|=0}var e=this.offset+t;if(!this.noAssert&&(e<0||e>this.buffer.byteLength))throw RangeError("Illegal length: 0 <= "+this.offset+" + "+t+" <= "+this.buffer.byteLength);return this.offset=e,this},e.slice=function(t,e){if(void 0===t&&(t=this.offset),void 0===e&&(e=this.limit),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal begin: Not an integer");if(t>>>=0,"number"!=typeof e||e%1!=0)throw TypeError("Illegal end: Not an integer");if(e>>>=0,t<0||t>e||e>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+e+" <= "+this.buffer.byteLength)}var r=this.clone();return r.offset=t,r.limit=e,r},e.toBuffer=function(t){var e=this.offset,i=this.limit;if(!this.noAssert){if("number"!=typeof e||e%1!=0)throw TypeError("Illegal offset: Not an integer");if(e>>>=0,"number"!=typeof i||i%1!=0)throw TypeError("Illegal limit: Not an integer");if(i>>>=0,e<0||e>i||i>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+e+" <= "+i+" <= "+this.buffer.byteLength)}if(!t&&0===e&&i===this.buffer.byteLength)return this.buffer;if(e===i)return r;var n=new ArrayBuffer(i-e);return new Uint8Array(n).set(new Uint8Array(this.buffer).subarray(e,i),0),n},e.toArrayBuffer=e.toBuffer,e.toString=function(t,e,r){if(void 0===t)return"ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+")";switch("number"==typeof t&&(r=e=t="utf8"),t){case"utf8":return this.toUTF8(e,r);case"base64":return this.toBase64(e,r);case"hex":return this.toHex(e,r);case"binary":return this.toBinary(e,r);case"debug":return this.toDebug();case"columns":return this.toColumns();default:throw Error("Unsupported encoding: "+t)}};var n=function(){for(var t={},e=[65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,48,49,50,51,52,53,54,55,56,57,43,47],r=[],i=0,n=e.length;i>2&63]),n=(3&i)<<4,null!==(i=t())?(r(e[63&((n|=i>>4&15)|i>>4&15)]),n=(15&i)<<2,null!==(i=t())?(r(e[63&(n|i>>6&3)]),r(e[63&i])):(r(e[63&n]),r(61))):(r(e[63&n]),r(61),r(61))},t.decode=function(t,e){var i,n,f;function fail(t){throw Error("Illegal character code: "+t)}for(;null!==(i=t());)if(void 0===(n=r[i])&&fail(i),null!==(i=t())&&(void 0===(f=r[i])&&fail(i),e(n<<2>>>0|(48&f)>>4),null!==(i=t()))){if(void 0===(n=r[i])){if(61===i)break;fail(i)}if(e((15&f)<<4>>>0|(60&n)>>2),null!==(i=t())){if(void 0===(f=r[i])){if(61===i)break;fail(i)}e((3&n)<<6>>>0|f)}}},t.test=function(t){return/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(t)},t}();e.toBase64=function(t,e){if(void 0===t&&(t=this.offset),void 0===e&&(e=this.limit),e|=0,(t|=0)<0||e>this.capacity||t>e)throw RangeError("begin, end");var r;return n.encode(function(){return tthis.capacity()||t>e)throw RangeError("begin, end");if(t===e)return"";for(var r=[],i=[];t=1024&&(i.push(String.fromCharCode.apply(String,r)),r=[]);return i.join("")+String.fromCharCode.apply(String,r)},ByteBuffer.fromBinary=function(t,e){if("string"!=typeof t)throw TypeError("str");for(var r,i=0,n=t.length,f=new ByteBuffer(n,e);i255)throw RangeError("illegal char code: "+r);f.view[i++]=r}return f.limit=n,f},e.toDebug=function(t){for(var e,r=-1,i=this.buffer.byteLength,n="",f="",o="";r32&&e<127?String.fromCharCode(e):".")),++r,t&&r>0&&r%16==0&&r!==i){for(;n.length<51;)n+=" ";o+=n+f+"\n",n=f=""}r===this.offset&&r===this.limit?n+=r===this.markedOffset?"!":"|":r===this.offset?n+=r===this.markedOffset?"[":"<":r===this.limit?n+=r===this.markedOffset?"]":">":n+=r===this.markedOffset?"'":t||0!==r&&r!==i?" ":""}if(t&&" "!==n){for(;n.length<51;)n+=" ";o+=n+f+"\n"}return t?o:n},ByteBuffer.fromDebug=function(t,e,r){for(var i,n,f=t.length,o=new ByteBuffer((f+1)/3|0,e,r),s=0,h=0,a=!1,l=!1,u=!1,g=!1,w=!1;s":if(!r){if(g){w=!0;break}g=!0}o.limit=h,a=!1;break;case"'":if(!r){if(u){w=!0;break}u=!0}o.markedOffset=h,a=!1;break;case" ":a=!1;break;default:if(!r&&a){w=!0;break}if(n=parseInt(i+t.charAt(s++),16),!r&&(isNaN(n)||n<0||n>255))throw TypeError("Illegal str: Not a debug encoded string");o.view[h++]=n,a=!0}if(w)throw TypeError("Illegal str: Invalid symbol at "+s)}if(!r){if(!l||!g)throw TypeError("Illegal str: Missing offset or limit");if(h>>=0,"number"!=typeof e||e%1!=0)throw TypeError("Illegal end: Not an integer");if(e>>>=0,t<0||t>e||e>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+e+" <= "+this.buffer.byteLength)}for(var r,i=new Array(e-t);t255))throw TypeError("Illegal str: Contains non-hex characters");f.view[s++]=i}return f.limit=s,f};var f=function(){var t={MAX_CODEPOINT:1114111,encodeUTF8:function(t,e){var r=null;for("number"==typeof t&&(r=t,t=function(){return null});null!==r||null!==(r=t());)r<128?e(127&r):r<2048?(e(r>>6&31|192),e(63&r|128)):r<65536?(e(r>>12&15|224),e(r>>6&63|128),e(63&r|128)):(e(r>>18&7|240),e(r>>12&63|128),e(r>>6&63|128),e(63&r|128)),r=null},decodeUTF8:function(t,e){for(var r,i,n,f,fail=function(t){t=t.slice(0,t.indexOf(null));var e=Error(t.toString());throw e.name="TruncatedError",e.bytes=t,e};null!==(r=t());)if(0==(128&r))e(r);else if(192==(224&r))null===(i=t())&&fail([r,i]),e((31&r)<<6|63&i);else if(224==(240&r))(null===(i=t())||null===(n=t()))&&fail([r,i,n]),e((15&r)<<12|(63&i)<<6|63&n);else{if(240!=(248&r))throw RangeError("Illegal starting byte: "+r);(null===(i=t())||null===(n=t())||null===(f=t()))&&fail([r,i,n,f]),e((7&r)<<18|(63&i)<<12|(63&n)<<6|63&f)}},UTF16toUTF8:function(t,e){for(var r,i=null;null!==(r=null!==i?i:t());)r>=55296&&r<=57343&&null!==(i=t())&&i>=56320&&i<=57343?(e(1024*(r-55296)+i-56320+65536),i=null):e(r);null!==i&&e(i)},UTF8toUTF16:function(t,e){var r=null;for("number"==typeof t&&(r=t,t=function(){return null});null!==r||null!==(r=t());)r<=65535?e(r):(e(55296+((r-=65536)>>10)),e(r%1024+56320)),r=null},encodeUTF16toUTF8:function(e,r){t.UTF16toUTF8(e,(function(e){t.encodeUTF8(e,r)}))},decodeUTF8toUTF16:function(e,r){t.decodeUTF8(e,(function(e){t.UTF8toUTF16(e,r)}))},calculateCodePoint:function(t){return t<128?1:t<2048?2:t<65536?3:4},calculateUTF8:function(t){for(var e,r=0;null!==(e=t());)r+=e<128?1:e<2048?2:e<65536?3:4;return r},calculateUTF16asUTF8:function(e){var r=0,i=0;return t.UTF16toUTF8(e,(function(t){++r,i+=t<128?1:t<2048?2:t<65536?3:4})),[r,i]}};return t}();return e.toUTF8=function(t,e){if(void 0===t&&(t=this.offset),void 0===e&&(e=this.limit),!this.noAssert){if("number"!=typeof t||t%1!=0)throw TypeError("Illegal begin: Not an integer");if(t>>>=0,"number"!=typeof e||e%1!=0)throw TypeError("Illegal end: Not an integer");if(e>>>=0,t<0||t>e||e>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+t+" <= "+e+" <= "+this.buffer.byteLength)}var r;try{f.decodeUTF8toUTF16(function(){return t",amp:"&",quot:'"',apos:"'",Agrave:"À",Aacute:"Á",Acirc:"Â",Atilde:"Ã",Auml:"Ä",Aring:"Å",AElig:"Æ",Ccedil:"Ç",Egrave:"È",Eacute:"É",Ecirc:"Ê",Euml:"Ë",Igrave:"Ì",Iacute:"Í",Icirc:"Î",Iuml:"Ï",ETH:"Ð",Ntilde:"Ñ",Ograve:"Ò",Oacute:"Ó",Ocirc:"Ô",Otilde:"Õ",Ouml:"Ö",Oslash:"Ø",Ugrave:"Ù",Uacute:"Ú",Ucirc:"Û",Uuml:"Ü",Yacute:"Ý",THORN:"Þ",szlig:"ß",agrave:"à",aacute:"á",acirc:"â",atilde:"ã",auml:"ä",aring:"å",aelig:"æ",ccedil:"ç",egrave:"è",eacute:"é",ecirc:"ê",euml:"ë",igrave:"ì",iacute:"í",icirc:"î",iuml:"ï",eth:"ð",ntilde:"ñ",ograve:"ò",oacute:"ó",ocirc:"ô",otilde:"õ",ouml:"ö",oslash:"ø",ugrave:"ù",uacute:"ú",ucirc:"û",uuml:"ü",yacute:"ý",thorn:"þ",yuml:"ÿ",nbsp:" ",iexcl:"¡",cent:"¢",pound:"£",curren:"¤",yen:"¥",brvbar:"¦",sect:"§",uml:"¨",copy:"©",ordf:"ª",laquo:"«",not:"¬",shy:"­­",reg:"®",macr:"¯",deg:"°",plusmn:"±",sup2:"²",sup3:"³",acute:"´",micro:"µ",para:"¶",middot:"·",cedil:"¸",sup1:"¹",ordm:"º",raquo:"»",frac14:"¼",frac12:"½",frac34:"¾",iquest:"¿",times:"×",divide:"÷",forall:"∀",part:"∂",exist:"∃",empty:"∅",nabla:"∇",isin:"∈",notin:"∉",ni:"∋",prod:"∏",sum:"∑",minus:"−",lowast:"∗",radic:"√",prop:"∝",infin:"∞",ang:"∠",and:"∧",or:"∨",cap:"∩",cup:"∪",int:"∫",there4:"∴",sim:"∼",cong:"≅",asymp:"≈",ne:"≠",equiv:"≡",le:"≤",ge:"≥",sub:"⊂",sup:"⊃",nsub:"⊄",sube:"⊆",supe:"⊇",oplus:"⊕",otimes:"⊗",perp:"⊥",sdot:"⋅",Alpha:"Α",Beta:"Β",Gamma:"Γ",Delta:"Δ",Epsilon:"Ε",Zeta:"Ζ",Eta:"Η",Theta:"Θ",Iota:"Ι",Kappa:"Κ",Lambda:"Λ",Mu:"Μ",Nu:"Ν",Xi:"Ξ",Omicron:"Ο",Pi:"Π",Rho:"Ρ",Sigma:"Σ",Tau:"Τ",Upsilon:"Υ",Phi:"Φ",Chi:"Χ",Psi:"Ψ",Omega:"Ω",alpha:"α",beta:"β",gamma:"γ",delta:"δ",epsilon:"ε",zeta:"ζ",eta:"η",theta:"θ",iota:"ι",kappa:"κ",lambda:"λ",mu:"μ",nu:"ν",xi:"ξ",omicron:"ο",pi:"π",rho:"ρ",sigmaf:"ς",sigma:"σ",tau:"τ",upsilon:"υ",phi:"φ",chi:"χ",psi:"ψ",omega:"ω",thetasym:"ϑ",upsih:"ϒ",piv:"ϖ",OElig:"Œ",oelig:"œ",Scaron:"Š",scaron:"š",Yuml:"Ÿ",fnof:"ƒ",circ:"ˆ",tilde:"˜",ensp:" ",emsp:" ",thinsp:" ",zwnj:"‌",zwj:"‍",lrm:"‎",rlm:"‏",ndash:"–",mdash:"—",lsquo:"‘",rsquo:"’",sbquo:"‚",ldquo:"“",rdquo:"”",bdquo:"„",dagger:"†",Dagger:"‡",bull:"•",hellip:"…",permil:"‰",prime:"′",Prime:"″",lsaquo:"‹",rsaquo:"›",oline:"‾",euro:"€",trade:"™",larr:"←",uarr:"↑",rarr:"→",darr:"↓",harr:"↔",crarr:"↵",lceil:"⌈",rceil:"⌉",lfloor:"⌊",rfloor:"⌋",loz:"◊",spades:"♠",clubs:"♣",hearts:"♥",diams:"♦"},nameStartChar=/[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/,nameChar=new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]"),tagNamePattern=new RegExp("^"+nameStartChar.source+nameChar.source+"*(?::"+nameStartChar.source+nameChar.source+"*)?$"),S_TAG=0,S_ATTR=1,S_ATTR_SPACE=2,S_EQ=3,S_ATTR_NOQUOT_VALUE=4,S_ATTR_END=5,S_TAG_SPACE=6,S_TAG_CLOSE=7;function XMLReader(){}function parse(e,n,r,i,o){function entityReplacer(e){var n=e.slice(1,-1);return n in r?r[n]:"#"===n.charAt(0)?function(e){if(e>65535){var n=55296+((e-=65536)>>10),r=56320+(1023&e);return String.fromCharCode(n,r)}return String.fromCharCode(e)}(parseInt(n.substr(1).replace("x","0x"))):(o.error("entity not found:"+e),e)}function appendText(n){if(n>p){var r=e.substring(p,n).replace(/&#?\w+;/g,entityReplacer);u&&position(p),i.characters(r,0,n-p),p=n}}function position(n,r){for(;n>=s&&(r=c.exec(e));)a=r.index,s=a+r[0].length,u.lineNumber++;u.columnNumber=n-a+1}for(var a=0,s=0,c=/.*(?:\r\n?|\n)|.*$/g,u=i.locator,l=[{currentNSMap:n}],d={},p=0;;){try{var m=e.indexOf("<",p);if(m<0){if(!e.substr(p).match(/^\s*$/)){var N=i.doc,E=N.createTextNode(e.substr(p));N.appendChild(E),i.currentElement=E}return}switch(m>p&&appendText(m),e.charAt(m+1)){case"/":var h=e.indexOf(">",m+3),f=e.substring(m+2,h),_=l.pop();h<0?(f=e.substring(m+2).replace(/[\s<].*/,""),o.error("end tag name: "+f+" is not complete:"+_.tagName),h=m+1+f.length):f.match(/\sp?p=h:appendText(Math.max(m,p)+1)}}function copyLocator(e,n){return n.lineNumber=e.lineNumber,n.columnNumber=e.columnNumber,n}function parseElementStartPart(e,n,r,i,o,a){for(var s,c=++n,u=S_TAG;;){var l=e.charAt(c);switch(l){case"=":if(u===S_ATTR)s=e.slice(n,c),u=S_EQ;else{if(u!==S_ATTR_SPACE)throw new Error("attribute equal must after attrName");u=S_EQ}break;case"'":case'"':if(u===S_EQ||u===S_ATTR){if(u===S_ATTR&&(a.warning('attribute value must after "="'),s=e.slice(n,c)),n=c+1,!((c=e.indexOf(l,n))>0))throw new Error("attribute value no end '"+l+"' match");d=e.slice(n,c).replace(/&#?\w+;/g,o),r.add(s,d,n-1),u=S_ATTR_END}else{if(u!=S_ATTR_NOQUOT_VALUE)throw new Error('attribute value must after "="');d=e.slice(n,c).replace(/&#?\w+;/g,o),r.add(s,d,n),a.warning('attribute "'+s+'" missed start quot('+l+")!!"),n=c+1,u=S_ATTR_END}break;case"/":switch(u){case S_TAG:r.setTagName(e.slice(n,c));case S_ATTR_END:case S_TAG_SPACE:case S_TAG_CLOSE:u=S_TAG_CLOSE,r.closed=!0;case S_ATTR_NOQUOT_VALUE:case S_ATTR:case S_ATTR_SPACE:break;default:throw new Error("attribute invalid close char('/')")}break;case"":return a.error("unexpected end of input"),u==S_TAG&&r.setTagName(e.slice(n,c)),c;case">":switch(u){case S_TAG:r.setTagName(e.slice(n,c));case S_ATTR_END:case S_TAG_SPACE:case S_TAG_CLOSE:break;case S_ATTR_NOQUOT_VALUE:case S_ATTR:"/"===(d=e.slice(n,c)).slice(-1)&&(r.closed=!0,d=d.slice(0,-1));case S_ATTR_SPACE:u===S_ATTR_SPACE&&(d=s),u==S_ATTR_NOQUOT_VALUE?(a.warning('attribute "'+d+'" missed quot(")!!'),r.add(s,d.replace(/&#?\w+;/g,o),n)):("http://www.w3.org/1999/xhtml"===i[""]&&d.match(/^(?:disabled|checked|selected)$/i)||a.warning('attribute "'+d+'" missed value!! "'+d+'" instead!!'),r.add(d,d,n));break;case S_EQ:throw new Error("attribute value missed!!")}return c;case"€":l=" ";default:if(l<=" ")switch(u){case S_TAG:r.setTagName(e.slice(n,c)),u=S_TAG_SPACE;break;case S_ATTR:s=e.slice(n,c),u=S_ATTR_SPACE;break;case S_ATTR_NOQUOT_VALUE:var d=e.slice(n,c).replace(/&#?\w+;/g,o);a.warning('attribute "'+d+'" missed quot(")!!'),r.add(s,d,n);case S_ATTR_END:u=S_TAG_SPACE}else switch(u){case S_ATTR_SPACE:r.tagName;"http://www.w3.org/1999/xhtml"===i[""]&&s.match(/^(?:disabled|checked|selected)$/i)||a.warning('attribute "'+s+'" missed value!! "'+s+'" instead2!!'),r.add(s,s,n),n=c,u=S_ATTR;break;case S_ATTR_END:a.warning('attribute space is required"'+s+'"!!');case S_TAG_SPACE:u=S_ATTR,n=c;break;case S_EQ:u=S_ATTR_NOQUOT_VALUE,n=c;break;case S_TAG_CLOSE:throw new Error("elements closed character '/' and '>' must be connected to")}}c++}}function parseHtmlSpecialContent(e,n,r,i,o){if(/^(?:script|textarea)$/i.test(r)){var a=e.indexOf("",n),s=e.substring(n+1,a);if(/[&<]/.test(s))return/^script$/i.test(r)?(o.characters(s,0,s.length),a):(s=s.replace(/&#?\w+;/g,i),o.characters(s,0,s.length),a)}return n+1}function fixSelfClosed(e,n,r,i){var o=i[r];return null==o&&((o=e.lastIndexOf(""))n?(r.comment(e,n+4,o-n-4),o+3):(i.error("Unclosed comment"),-1):-1;default:if("CDATA["==e.substr(n+3,6)){var o=e.indexOf("]]>",n+9);return r.startCDATA(),r.characters(e,n+9,o-n-9),r.endCDATA(),o+3}var a=split(e,n),s=a.length;if(s>1&&/!doctype/i.test(a[0][0])){var c=a[1][0],u=s>3&&/^public$/i.test(a[2][0])&&a[3][0],l=s>4&&a[4][0],d=a[s-1];return r.startDTD(c,u&&u.replace(/^(['"])(.*?)\1$/,"$2"),l&&l.replace(/^(['"])(.*?)\1$/,"$2")),r.endDTD(),d.index+d[0].length}}return-1}function parseInstruction(e,n,r){var i=e.indexOf("?>",n);if(i){var o=e.substring(n,i).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);if(o){o[0].length;return r.processingInstruction(o[1],o[2]),i+2}return-1}return-1}function ElementAttributes(e){}function split(e,n){var r,i=[],o=/'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;for(o.lastIndex=n,o.exec(e);r=o.exec(e);)if(i.push(r),r[1])return i}function copy(e,n){for(var r in e)n[r]=e[r]}function _extends(e,n){var r=e.prototype;if(!(r instanceof n)){function t(){}t.prototype=n.prototype,copy(r,t=new t),e.prototype=r=t}r.constructor!=e&&("function"!=typeof e&&console.error("unknow Class:"+e),r.constructor=e)}SaxO={},XMLReader.prototype={parse:function(e,n,r){var i=this.domBuilder;i.startDocument(),_copy(n,n={}),parse(e,n,r,i,this.errorHandler),i.endDocument()}},SaxO.appendElement=function(e,n,r){for(var i=e.tagName,o=null,a=e.length;a--;){var s=e[a],c=s.qName,u=s.value;if((m=c.indexOf(":"))>0)var l=s.prefix=c.slice(0,m),d=c.slice(m+1),p="xmlns"===l&&d;else d=c,l=null,p="xmlns"===c&&"";s.localName=d,!1!==p&&(null==o&&(o={},_copy(r,r={})),r[p]=o[p]=u,s.uri="http://www.w3.org/2000/xmlns/",n.startPrefixMapping(p,u))}for(a=e.length;a--;){(l=(s=e[a]).prefix)&&("xml"===l&&(s.uri="http://www.w3.org/XML/1998/namespace"),"xmlns"!==l&&(s.uri=r[l||""]))}var m;(m=i.indexOf(":"))>0?(l=e.prefix=i.slice(0,m),d=e.localName=i.slice(m+1)):(l=null,d=e.localName=i);var N=e.uri=r[l||""];if(n.startElement(N,d,i,e),!e.closed)return e.currentNSMap=r,e.localNSMap=o,!0;if(n.endElement(N,d,i),o)for(l in o)n.endPrefixMapping(l)},ElementAttributes.prototype={setTagName:function(e){if(!tagNamePattern.test(e))throw new Error("invalid tagName:"+e);this.tagName=e},add:function(e,n,r){if(!tagNamePattern.test(e))throw new Error("invalid attribute:"+e);this[this.length++]={qName:e,value:n,offset:r}},length:0,getLocalName:function(e){return this[e].localName},getLocator:function(e){return this[e].locator},getQName:function(e){return this[e].qName},getURI:function(e){return this[e].uri},getValue:function(e){return this[e].value}},"function"==typeof require&&(exports.XMLReader=XMLReader);var htmlns="http://www.w3.org/1999/xhtml",NodeType={},ELEMENT_NODE=NodeType.ELEMENT_NODE=1,ATTRIBUTE_NODE=NodeType.ATTRIBUTE_NODE=2,TEXT_NODE=NodeType.TEXT_NODE=3,CDATA_SECTION_NODE=NodeType.CDATA_SECTION_NODE=4,ENTITY_REFERENCE_NODE=NodeType.ENTITY_REFERENCE_NODE=5,ENTITY_NODE=NodeType.ENTITY_NODE=6,PROCESSING_INSTRUCTION_NODE=NodeType.PROCESSING_INSTRUCTION_NODE=7,COMMENT_NODE=NodeType.COMMENT_NODE=8,DOCUMENT_NODE=NodeType.DOCUMENT_NODE=9,DOCUMENT_TYPE_NODE=NodeType.DOCUMENT_TYPE_NODE=10,DOCUMENT_FRAGMENT_NODE=NodeType.DOCUMENT_FRAGMENT_NODE=11,NOTATION_NODE=NodeType.NOTATION_NODE=12,ExceptionCode={},ExceptionMessage={},INDEX_SIZE_ERR=ExceptionCode.INDEX_SIZE_ERR=(ExceptionMessage[1]="Index size error",1),DOMSTRING_SIZE_ERR=ExceptionCode.DOMSTRING_SIZE_ERR=(ExceptionMessage[2]="DOMString size error",2),HIERARCHY_REQUEST_ERR=ExceptionCode.HIERARCHY_REQUEST_ERR=(ExceptionMessage[3]="Hierarchy request error",3),WRONG_DOCUMENT_ERR=ExceptionCode.WRONG_DOCUMENT_ERR=(ExceptionMessage[4]="Wrong document",4),INVALID_CHARACTER_ERR=ExceptionCode.INVALID_CHARACTER_ERR=(ExceptionMessage[5]="Invalid character",5),NO_DATA_ALLOWED_ERR=ExceptionCode.NO_DATA_ALLOWED_ERR=(ExceptionMessage[6]="No data allowed",6),NO_MODIFICATION_ALLOWED_ERR=ExceptionCode.NO_MODIFICATION_ALLOWED_ERR=(ExceptionMessage[7]="No modification allowed",7),NOT_FOUND_ERR=ExceptionCode.NOT_FOUND_ERR=(ExceptionMessage[8]="Not found",8),NOT_SUPPORTED_ERR=ExceptionCode.NOT_SUPPORTED_ERR=(ExceptionMessage[9]="Not supported",9),INUSE_ATTRIBUTE_ERR=ExceptionCode.INUSE_ATTRIBUTE_ERR=(ExceptionMessage[10]="Attribute in use",10),INVALID_STATE_ERR=ExceptionCode.INVALID_STATE_ERR=(ExceptionMessage[11]="Invalid state",11),SYNTAX_ERR=ExceptionCode.SYNTAX_ERR=(ExceptionMessage[12]="Syntax error",12),INVALID_MODIFICATION_ERR=ExceptionCode.INVALID_MODIFICATION_ERR=(ExceptionMessage[13]="Invalid modification",13),NAMESPACE_ERR=ExceptionCode.NAMESPACE_ERR=(ExceptionMessage[14]="Invalid namespace",14),INVALID_ACCESS_ERR=ExceptionCode.INVALID_ACCESS_ERR=(ExceptionMessage[15]="Invalid access",15);function DOMException(e,n){if(n instanceof Error)var r=n;else r=this,Error.call(this,ExceptionMessage[e]),this.message=ExceptionMessage[e],Error.captureStackTrace&&Error.captureStackTrace(this,DOMException);return r.code=e,n&&(this.message=this.message+": "+n),r}function NodeList(){}function LiveNodeList(e,n){this._node=e,this._refresh=n,_updateLiveList(this)}function _updateLiveList(e){var n=e._node._inc||e._node.ownerDocument._inc;if(e._inc!=n){var r=e._refresh(e._node);__set__(e,"length",r.length),copy(r,e),e._inc=n}}function NamedNodeMap(){}function _findNodeIndex(e,n){for(var r=e.length;r--;)if(e[r]===n)return r}function _addNamedNode(e,n,r,i){if(i?n[_findNodeIndex(n,i)]=r:n[n.length++]=r,e){r.ownerElement=e;var o=e.ownerDocument;o&&(i&&_onRemoveAttribute(o,e,i),_onAddAttribute(o,e,r))}}function _removeNamedNode(e,n,r){var i=_findNodeIndex(n,r);if(!(i>=0))throw DOMException(NOT_FOUND_ERR,new Error(e.tagName+"@"+r));for(var o=n.length-1;i"==e&&">")||"&"==e&&"&"||'"'==e&&"""||"&#"+e.charCodeAt()+";"}function _visitNode(e,n){if(n(e))return!0;if(e=e.firstChild)do{if(_visitNode(e,n))return!0}while(e=e.nextSibling)}function Document(){}function _onAddAttribute(e,n,r){e&&e._inc++,"http://www.w3.org/2000/xmlns/"==r.namespaceURI&&(n._nsMap[r.prefix?r.localName:""]=r.value)}function _onRemoveAttribute(e,n,r,i){e&&e._inc++,"http://www.w3.org/2000/xmlns/"==r.namespaceURI&&delete n._nsMap[r.prefix?r.localName:""]}function _onUpdateChild(e,n,r){if(e&&e._inc){e._inc++;var i=n.childNodes;if(r)i[i.length++]=r;else{for(var o=n.firstChild,a=0;o;)i[a++]=o,o=o.nextSibling;i.length=a}}}function _removeChild(e,n){var r=n.previousSibling,i=n.nextSibling;return r?r.nextSibling=i:e.firstChild=i,i?i.previousSibling=r:e.lastChild=r,_onUpdateChild(e.ownerDocument,e),n}function _insertBefore(e,n,r){var i=n.parentNode;if(i&&i.removeChild(n),n.nodeType===DOCUMENT_FRAGMENT_NODE){var o=n.firstChild;if(null==o)return n;var a=n.lastChild}else o=a=n;var s=r?r.previousSibling:e.lastChild;o.previousSibling=s,a.nextSibling=r,s?s.nextSibling=o:e.firstChild=o,null==r?e.lastChild=a:r.previousSibling=a;do{o.parentNode=e}while(o!==a&&(o=o.nextSibling));return _onUpdateChild(e.ownerDocument||e,e),n.nodeType==DOCUMENT_FRAGMENT_NODE&&(n.firstChild=n.lastChild=null),n}function _appendSingleChild(e,n){var r=n.parentNode;if(r){var i=e.lastChild;r.removeChild(n);i=e.lastChild}i=e.lastChild;return n.parentNode=e,n.previousSibling=i,n.nextSibling=null,i?i.nextSibling=n:e.firstChild=n,e.lastChild=n,_onUpdateChild(e.ownerDocument,e,n),n}function Element(){this._nsMap={}}function Attr(){}function CharacterData(){}function Text(){}function Comment(){}function CDATASection(){}function DocumentType(){}function Notation(){}function Entity(){}function EntityReference(){}function DocumentFragment(){}function ProcessingInstruction(){}function XMLSerializer(){}function nodeSerializeToString(e,n){var r=[],i=9==this.nodeType&&this.documentElement||this,o=i.prefix,a=i.namespaceURI;if(a&&null==o&&null==(o=i.lookupPrefix(a)))var s=[{namespace:a,prefix:null}];return serializeToString(this,r,e,n,s),r.join("")}function needNamespaceDefine(e,n,r){var i=e.prefix||"",o=e.namespaceURI;if(!i&&!o)return!1;if("xml"===i&&"http://www.w3.org/XML/1998/namespace"===o||"http://www.w3.org/2000/xmlns/"==o)return!1;for(var a=r.length;a--;){var s=r[a];if(s.prefix==i)return s.namespace!=o}return!0}function serializeToString(e,n,r,i,o){if(i){if(!(e=i(e)))return;if("string"==typeof e)return void n.push(e)}switch(e.nodeType){case ELEMENT_NODE:o||(o=[]);o.length;var a=e.attributes,s=a.length,c=e.firstChild,u=e.tagName;r=htmlns===e.namespaceURI||r,n.push("<",u);for(var l=0;l"),r&&/^script$/i.test(u))for(;c;)c.data?n.push(c.data):serializeToString(c,n,r,i,o),c=c.nextSibling;else for(;c;)serializeToString(c,n,r,i,o),c=c.nextSibling;n.push("")}else n.push("/>");return;case DOCUMENT_NODE:case DOCUMENT_FRAGMENT_NODE:for(c=e.firstChild;c;)serializeToString(c,n,r,i,o),c=c.nextSibling;return;case ATTRIBUTE_NODE:return n.push(" ",e.name,'="',e.value.replace(/[<&"]/g,_xmlEncoder),'"');case TEXT_NODE:return n.push(e.data.replace(/[<&]/g,_xmlEncoder));case CDATA_SECTION_NODE:return n.push("");case COMMENT_NODE:return n.push("\x3c!--",e.data,"--\x3e");case DOCUMENT_TYPE_NODE:var E=e.publicId,h=e.systemId;if(n.push("');else if(h&&"."!=h)n.push(' SYSTEM "',h,'">');else{var f=e.internalSubset;f&&n.push(" [",f,"]"),n.push(">")}return;case PROCESSING_INSTRUCTION_NODE:return n.push("");case ENTITY_REFERENCE_NODE:return n.push("&",e.nodeName,";");default:n.push("??",e.nodeName)}}function importNode(e,n,r){var i;switch(n.nodeType){case ELEMENT_NODE:(i=n.cloneNode(!1)).ownerDocument=e;case DOCUMENT_FRAGMENT_NODE:break;case ATTRIBUTE_NODE:r=!0}if(i||(i=n.cloneNode(!1)),i.ownerDocument=e,i.parentNode=null,r)for(var o=n.firstChild;o;)i.appendChild(importNode(e,o,r)),o=o.nextSibling;return i}function cloneNode(e,n,r){var i=new n.constructor;for(var o in n){var a=n[o];"object"!=typeof a&&a!=i[o]&&(i[o]=a)}switch(n.childNodes&&(i.childNodes=new NodeList),i.ownerDocument=e,i.nodeType){case ELEMENT_NODE:var s=n.attributes,c=i.attributes=new NamedNodeMap,u=s.length;c._ownerElement=i;for(var l=0;l0},lookupPrefix:function(e){for(var n=this;n;){var r=n._nsMap;if(r)for(var i in r)if(r[i]==e)return i;n=n.nodeType==ATTRIBUTE_NODE?n.ownerDocument:n.parentNode}return null},lookupNamespaceURI:function(e){for(var n=this;n;){var r=n._nsMap;if(r&&e in r)return r[e];n=n.nodeType==ATTRIBUTE_NODE?n.ownerDocument:n.parentNode}return null},isDefaultNamespace:function(e){return null==this.lookupPrefix(e)}},copy(NodeType,Node),copy(NodeType,Node.prototype),Document.prototype={nodeName:"#document",nodeType:DOCUMENT_NODE,doctype:null,documentElement:null,_inc:1,insertBefore:function(e,n){if(e.nodeType==DOCUMENT_FRAGMENT_NODE){for(var r=e.firstChild;r;){var i=r.nextSibling;this.insertBefore(r,n),r=i}return e}return null==this.documentElement&&e.nodeType==ELEMENT_NODE&&(this.documentElement=e),_insertBefore(this,e,n),e.ownerDocument=this,e},removeChild:function(e){return this.documentElement==e&&(this.documentElement=null),_removeChild(this,e)},importNode:function(e,n){return importNode(this,e,n)},getElementById:function(e){var n=null;return _visitNode(this.documentElement,(function(r){if(r.nodeType==ELEMENT_NODE&&r.getAttribute("id")==e)return n=r,!0})),n},createElement:function(e){var n=new Element;return n.ownerDocument=this,n.nodeName=e,n.tagName=e,n.childNodes=new NodeList,(n.attributes=new NamedNodeMap)._ownerElement=n,n},createDocumentFragment:function(){var e=new DocumentFragment;return e.ownerDocument=this,e.childNodes=new NodeList,e},createTextNode:function(e){var n=new Text;return n.ownerDocument=this,n.appendData(e),n},createComment:function(e){var n=new Comment;return n.ownerDocument=this,n.appendData(e),n},createCDATASection:function(e){var n=new CDATASection;return n.ownerDocument=this,n.appendData(e),n},createProcessingInstruction:function(e,n){var r=new ProcessingInstruction;return r.ownerDocument=this,r.tagName=r.target=e,r.nodeValue=r.data=n,r},createAttribute:function(e){var n=new Attr;return n.ownerDocument=this,n.name=e,n.nodeName=e,n.localName=e,n.specified=!0,n},createEntityReference:function(e){var n=new EntityReference;return n.ownerDocument=this,n.nodeName=e,n},createElementNS:function(e,n){var r=new Element,i=n.split(":"),o=r.attributes=new NamedNodeMap;return r.childNodes=new NodeList,r.ownerDocument=this,r.nodeName=n,r.tagName=n,r.namespaceURI=e,2==i.length?(r.prefix=i[0],r.localName=i[1]):r.localName=n,o._ownerElement=r,r},createAttributeNS:function(e,n){var r=new Attr,i=n.split(":");return r.ownerDocument=this,r.nodeName=n,r.name=n,r.namespaceURI=e,r.specified=!0,2==i.length?(r.prefix=i[0],r.localName=i[1]):r.localName=n,r}},_extends(Document,Node),Element.prototype={nodeType:ELEMENT_NODE,hasAttribute:function(e){return null!=this.getAttributeNode(e)},getAttribute:function(e){var n=this.getAttributeNode(e);return n&&n.value||""},getAttributeNode:function(e){return this.attributes.getNamedItem(e)},setAttribute:function(e,n){var r=this.ownerDocument.createAttribute(e);r.value=r.nodeValue=""+n,this.setAttributeNode(r)},removeAttribute:function(e){var n=this.getAttributeNode(e);n&&this.removeAttributeNode(n)},appendChild:function(e){return e.nodeType===DOCUMENT_FRAGMENT_NODE?this.insertBefore(e,null):_appendSingleChild(this,e)},setAttributeNode:function(e){return this.attributes.setNamedItem(e)},setAttributeNodeNS:function(e){return this.attributes.setNamedItemNS(e)},removeAttributeNode:function(e){return this.attributes.removeNamedItem(e.nodeName)},removeAttributeNS:function(e,n){var r=this.getAttributeNodeNS(e,n);r&&this.removeAttributeNode(r)},hasAttributeNS:function(e,n){return null!=this.getAttributeNodeNS(e,n)},getAttributeNS:function(e,n){var r=this.getAttributeNodeNS(e,n);return r&&r.value||""},setAttributeNS:function(e,n,r){var i=this.ownerDocument.createAttributeNS(e,n);i.value=i.nodeValue=""+r,this.setAttributeNode(i)},getAttributeNodeNS:function(e,n){return this.attributes.getNamedItemNS(e,n)},getElementsByTagName:function(e){return new LiveNodeList(this,(function(n){var r=[];return _visitNode(n,(function(i){i===n||i.nodeType!=ELEMENT_NODE||"*"!==e&&i.tagName!=e||r.push(i)})),r}))},getElementsByTagNameNS:function(e,n){return new LiveNodeList(this,(function(r){var i=[];return _visitNode(r,(function(o){o===r||o.nodeType!==ELEMENT_NODE||"*"!==e&&o.namespaceURI!==e||"*"!==n&&o.localName!=n||i.push(o)})),i}))}},Document.prototype.getElementsByTagName=Element.prototype.getElementsByTagName,Document.prototype.getElementsByTagNameNS=Element.prototype.getElementsByTagNameNS,_extends(Element,Node),Attr.prototype.nodeType=ATTRIBUTE_NODE,_extends(Attr,Node),CharacterData.prototype={data:"",substringData:function(e,n){return this.data.substring(e,e+n)},appendData:function(e){e=this.data+e,this.nodeValue=this.data=e,this.length=e.length},insertData:function(e,n){this.replaceData(e,0,n)},appendChild:function(e){throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR])},deleteData:function(e,n){this.replaceData(e,n,"")},replaceData:function(e,n,r){r=this.data.substring(0,e)+r+this.data.substring(e+n),this.nodeValue=this.data=r,this.length=r.length}},_extends(CharacterData,Node),Text.prototype={nodeName:"#text",nodeType:TEXT_NODE,splitText:function(e){var n=this.data,r=n.substring(e);n=n.substring(0,e),this.data=this.nodeValue=n,this.length=n.length;var i=this.ownerDocument.createTextNode(r);return this.parentNode&&this.parentNode.insertBefore(i,this.nextSibling),i}},_extends(Text,CharacterData),Comment.prototype={nodeName:"#comment",nodeType:COMMENT_NODE},_extends(Comment,CharacterData),CDATASection.prototype={nodeName:"#cdata-section",nodeType:CDATA_SECTION_NODE},_extends(CDATASection,CharacterData),DocumentType.prototype.nodeType=DOCUMENT_TYPE_NODE,_extends(DocumentType,Node),Notation.prototype.nodeType=NOTATION_NODE,_extends(Notation,Node),Entity.prototype.nodeType=ENTITY_NODE,_extends(Entity,Node),EntityReference.prototype.nodeType=ENTITY_REFERENCE_NODE,_extends(EntityReference,Node),DocumentFragment.prototype.nodeName="#document-fragment",DocumentFragment.prototype.nodeType=DOCUMENT_FRAGMENT_NODE,_extends(DocumentFragment,Node),ProcessingInstruction.prototype.nodeType=PROCESSING_INSTRUCTION_NODE,_extends(ProcessingInstruction,Node),XMLSerializer.prototype.serializeToString=function(e,n,r){return nodeSerializeToString.call(e,n,r)},Node.prototype.toString=nodeSerializeToString;try{if(Object.defineProperty){function getTextContent(e){switch(e.nodeType){case ELEMENT_NODE:case DOCUMENT_FRAGMENT_NODE:var n=[];for(e=e.firstChild;e;)7!==e.nodeType&&8!==e.nodeType&&n.push(getTextContent(e)),e=e.nextSibling;return n.join("");default:return e.nodeValue}}Object.defineProperty(LiveNodeList.prototype,"length",{get:function(){return _updateLiveList(this),this.$$length}}),Object.defineProperty(Node.prototype,"textContent",{get:function(){return getTextContent(this)},set:function(e){switch(this.nodeType){case ELEMENT_NODE:case DOCUMENT_FRAGMENT_NODE:for(;this.firstChild;)this.removeChild(this.firstChild);(e||String(e))&&this.appendChild(this.ownerDocument.createTextNode(e));break;default:this.data=e,this.value=e,this.nodeValue=e}}}),__set__=function(e,n,r){e["$$"+n]=r}}}catch(e){}function DOMParser(e){this.options=e||{locator:{}}}function buildErrorHandler(e,n,r){if(!e){if(n instanceof DOMHandler)return n;e=n}var i={},o=e instanceof Function;function build(n){var a=e[n];!a&&o&&(a=2==e.length?function(r){e(n,r)}:e),i[n]=a&&function(e){a("[xmldom "+n+"]\t"+e+_locator(r))}||function(){}}return r=r||{},build("warning"),build("error"),build("fatalError"),i}function DOMHandler(){this.cdata=!1}function position(e,n){n.lineNumber=e.lineNumber,n.columnNumber=e.columnNumber}function _locator(e){if(e)return"\n@"+(e.systemId||"")+"#[line:"+e.lineNumber+",col:"+e.columnNumber+"]"}function _toString(e,n,r){return"string"==typeof e?e.substr(n,r):e.length>=n+r||n?new java.lang.String(e,n,r)+"":e}function appendElement(e,n){e.currentElement?e.currentElement.appendChild(n):e.doc.appendChild(n)}"function"==typeof require&&(exports.DOMImplementation=DOMImplementation,exports.XMLSerializer=XMLSerializer),DOMParser.prototype.parseFromString=function(e,n){var r=this.options,i=new XMLReader,o=r.domBuilder||new DOMHandler,a=r.errorHandler,s=r.locator,c=r.xmlns||{},u=/\/x?html?$/.test(n),l=u?htmlEntity.entityMap:{lt:"<",gt:">",amp:"&",quot:'"',apos:"'"};return s&&o.setDocumentLocator(s),i.errorHandler=buildErrorHandler(a,o,s),i.domBuilder=r.domBuilder||o,u&&(c[""]="http://www.w3.org/1999/xhtml"),c.xml=c.xml||"http://www.w3.org/XML/1998/namespace",e?i.parse(e,c,l):i.errorHandler.error("invalid doc source"),o.doc},DOMHandler.prototype={startDocument:function(){this.doc=(new DOMImplementation).createDocument(null,null,null),this.locator&&(this.doc.documentURI=this.locator.systemId)},startElement:function(e,n,r,i){var o=this.doc,a=o.createElementNS(e,r||n),s=i.length;appendElement(this,a),this.currentElement=a,this.locator&&position(this.locator,a);for(var c=0;c=f&&(t.size>l.minClearSize&&(l.minClearSize=t.size),i.onClearCacheRes()),i.deleteFile(e,a,n,s,t.size)},fail:function(e){null!=n&&n.runWith([1,e])}}):null!=n&&n.runWith([0]):i.fs.getFileInfo({filePath:e,success:function(t){o&&m+4194304+t.size>=f&&(t.size>l.minClearSize&&(l.minClearSize=t.size),i.onClearCacheRes()),i.fs.copyFile({srcPath:e,destPath:h,success:function(e){i.onSaveFile(a,d,!0,s,n,t.size)},fail:function(e){null!=n&&n.runWith([1,e])}})},fail:function(e){null!=n&&n.runWith([1,e])}})}static onClearCacheRes(){var e=l.minClearSize,t=[];for(var a in i.filesListObj)"fileUsedSize"!=a&&t.push(i.filesListObj[a]);i.sortOn(t,"times",i.NUMERIC);for(var n=0,s=1,o=t.length;s=e)break;n+=r.size,i.deleteFile("",r.readyUrl)}}static sortOn(e,t,a=0){return a==i.NUMERIC?e.sort((function(e,i){return e[t]-i[t]})):a==(i.NUMERIC|i.DESCENDING)?e.sort((function(e,i){return i[t]-e[t]})):e.sort((function(e,i){return e[t]-i[t]}))}static getFileNativePath(e){return i.fileNativeDir+"/"+e}static deleteFile(e,t="",a=null,n="",s=0){var o=i.getFileInfo(t),r=i.getFileNativePath(o.md5);i.fs.unlink({filePath:r,success:function(o){if(""!=e){var r=i.getFileNativePath(e);i.fs.copyFile({srcPath:e,destPath:r,success:function(o){i.onSaveFile(t,e,!0,n,a,s)},fail:function(e){null!=a&&a.runWith([1,e])}})}else i.onSaveFile(t,e,!1,n,a,s)},fail:function(e){null!=a&&a.runWith([1,e])}})}static deleteAll(){var e=[];for(var t in i.filesListObj)"fileUsedSize"!=t&&e.push(i.filesListObj[t]);for(var a=1,n=e.length;a0&&this.loops--,this.startTime=0,this.play()}play(){this.isStopped=!1,t.SoundManager.addChannel(this),this._audio.play()}set startTime(e){this._audio&&(this._audio.startTime=e)}set autoplay(e){this._audio.autoplay=e}get autoplay(){return this._audio.autoplay}get position(){return this._audio?this._audio.currentTime:0}get duration(){return this._audio?this._audio.duration:0}stop(){this.isStopped=!0,t.SoundManager.removeChannel(this),this.completeHandler=null,this._audio&&(this._audio.stop(),this.loop||(this._audio.offEnded(null),this._miniSound.dispose(),this._audio=null,this._miniSound=null,this._onEnd=null))}pause(){this.isStopped=!0,this._audio.pause()}get loop(){return this._audio.loop}set loop(e){this._audio.loop=e}resume(){this._audio&&(this.isStopped=!1,t.SoundManager.addChannel(this),this._audio.play())}set volume(e){this._audio&&(this._audio.volume=e)}get volume(){return this._audio?this._audio.volume:1}}class n extends t.EventDispatcher{constructor(){super(),this.loaded=!1}static _createSound(){return n._id++,l.window.my.createInnerAudioContext()}load(e){if(n._musicAudio||(n._musicAudio=n._createSound()),i.isLocalNativeFile(e)){if(-1!=e.indexOf("http://")||-1!=e.indexOf("https://"))if(""!=i.loadPath)e=e.split(i.loadPath)[1];else{var a=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath;""!=a&&(e=e.split(a)[1])}}else e=t.URL.formatURL(e);if(this.url=e,this.readyUrl=e,n._audioCache[this.readyUrl])this.event(t.Event.COMPLETE);else if(l.autoCacheFile&&i.getFileInfo(e))this.onDownLoadCallBack(e,0);else if(l.autoCacheFile)if(i.isLocalNativeFile(e)){var s=e;if(""!=(a=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath)&&(e=e.split(a)[1]),e||(e=s),l.subNativeFiles&&0==l.subNativeheads.length)for(var o in l.subNativeFiles){var r=l.subNativeFiles[o];l.subNativeheads=l.subNativeheads.concat(r);for(var d=0;d=0?"/":"\\",s=e.lastIndexOf(n),o=s>=0?e.substr(0,s+1):"",r=0,d=a.length;r\s+<");try{t=(new l.window.Parser.DOMParser).parseFromString(e,"text/xml")}catch(e){throw"需要引入xml解析库文件"}return t},l.idx=1;class d extends t.EventDispatcher{constructor(){super()}static __init__(){try{var e;if(!(e=t.Accelerator))return;e.prototype.on=d.prototype.on,e.prototype.off=d.prototype.off}catch(e){}}static startListen(e){if(d._callBack=e,!d._isListening){d._isListening=!0;try{l.window.my.onAccelerometerChange(d.onAccelerometerChange)}catch(e){}}}static stopListen(){d._isListening=!1;try{l.window.my.stopAccelerometer({})}catch(e){}}static onAccelerometerChange(e){var t;(t={}).acceleration=e,t.accelerationIncludingGravity=e,t.rotationRate={},null!=d._callBack&&d._callBack(t)}on(e,t,i,a=null){return super.on(e,t,i,a),d.startListen(this.onDeviceOrientationChange),this}off(e,t,i,a=!1){return this.hasListener(e)||d.stopListen(),super.off(e,t,i,a)}}d._isListening=!1;class u{_loadImage(e){if(l.isZiYu)u.onCreateImage(e,this,!0);else{var a;if(i.isLocalNativeFile(e)){if(-1==e.indexOf("http://usr/")&&(-1!=e.indexOf("http://")||-1!=e.indexOf("https://")))if(""!=i.loadPath)e=e.split(i.loadPath)[1];else{var n=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath,s=e;""!=n&&(e=e.split(n)[1]),e||(e=s)}if(l.subNativeFiles&&0==l.subNativeheads.length)for(var o in l.subNativeFiles){var r=l.subNativeFiles[o];l.subNativeheads=l.subNativeheads.concat(r);for(var d=0;d0&&(x=c.slice(f,M));var D=new e.Byte(x);for(M>0&&(t._publicExtData=c.slice(M,c.byteLength)),t._useParent=!!n.getUint8(),t._anis.length=g,h=0;h=0&&(T.name=y[S],v.bone3DMap[T.name]=l),T.keyFrame=[],T.parentIndex=n.getInt16(),-1==T.parentIndex?T.parent=null:T.parent=v.nodes[T.parentIndex],T.lerpType=n.getUint8();var b=n.getUint32();D.pos=b;var C=T.keyframeWidth=D.getUint16();if(v.totalKeyframeDatasLength+=C,0===T.lerpType||1===T.lerpType)for(T.interpolationMethod=[],T.interpolationMethod.length=C,o=0;o0&&(T.extenData=c.slice(n.pos,n.pos+F),n.pos+=F);var w=n.getUint16();T.keyFrame.length=w;var k,P=0;for(o=0,u=w;o-1e-8&&k.data[_]<1e-8&&(k.data[_]=0);P+=k.duration}k.startTime=v.playTime,T.playTime=v.playTime,t._calculateKeyFrame(T,w,C)}}}}class h{static READ_DATA(){h._DATA.offset=h._reader.getUint32(),h._DATA.size=h._reader.getUint32()}static READ_BLOCK(){for(var t=h._BLOCK.count=h._reader.getUint16(),e=h._BLOCK.blockStarts=[],i=h._BLOCK.blockLengths=[],a=0;a=0&&(y.name=h._strings[g],c.bone3DMap[y.name]=e),y.keyFrame=[],y.parentIndex=o.getInt16(),-1==y.parentIndex?y.parent=null:y.parent=c.nodes[y.parentIndex],c.totalKeyframeDatasLength+=_,y.interpolationMethod=p,null!=y.parent&&y.parent.childs.push(y);var f=o.getUint16();y.keyFrame.length=f;var M=null,D=null;for(n=0,l=f;nthis._playEnd)throw new Error("AnimationPlayer:value must large than playStartTime,small than playEndTime.");this._startUpdateLoopCount=e.Stat.loopCount;var i=this._cacheFrameRateInterval*this._cachePlayRate;this._currentTime=t,this._currentKeyframeIndex=Math.floor(this.currentPlayTime/i),this._currentFrameTime=this._currentKeyframeIndex*i}}get paused(){return this._paused}set paused(t){this._paused=t,t&&this.event(e.Event.PAUSED)}get cacheFrameRateInterval(){return this._cacheFrameRateInterval}get state(){return-1===this._currentAnimationClipIndex?l.stopped:this._paused?l.paused:l.playing}get destroyed(){return this._destroyed}_onTempletLoadedComputeFullKeyframeIndices(t,e,i){this._templet===i&&this._cachePlayRate===t&&this._cacheFrameRate===e&&this._computeFullKeyframeIndices()}_computeFullKeyframeIndices(){}_onAnimationTempletLoaded(){this.destroyed||this._calculatePlayDuration()}_calculatePlayDuration(){if(this.state!==l.stopped){var t=this._templet.getAniDuration(this._currentAnimationClipIndex);0===this._playEnd&&(this._playEnd=t),this._playEnd>t&&(this._playEnd=t),this._playDuration=this._playEnd-this._playStart}}_setPlayParams(t,e){this._currentTime=t,this._currentKeyframeIndex=Math.floor(this.currentPlayTime/e+.01),this._currentFrameTime=this._currentKeyframeIndex*e}_setPlayParamsWhenStop(t,e,i=-1){this._currentTime=t;var a=i>0?i:t;this._currentKeyframeIndex=Math.floor(a/e+.01),this._currentKeyframeIndex=Math.floor(t/e+.01),this._currentFrameTime=this._currentKeyframeIndex*e,this._currentAnimationClipIndex=-1}_update(t){if(-1!==this._currentAnimationClipIndex&&!this._paused&&this._templet){var i=this._cacheFrameRateInterval*this._cachePlayRate,a=0;this._startUpdateLoopCount!==e.Stat.loopCount&&(a=t*this.playbackRate,this._elapsedPlaybackTime+=a);var r=this.playDuration;if(a+=this._currentTime,0!==this._overallDuration&&this._elapsedPlaybackTime>=this._overallDuration||0===this._overallDuration&&this._elapsedPlaybackTime>=r||0===this._overallDuration&&a>=this.playEnd)return this._setPlayParamsWhenStop(r,i,this.playEnd),void this.event(e.Event.STOPPED);if(r>0){if(a>=r)return this._stopWhenCircleFinish?(this._setPlayParamsWhenStop(r,i),this._stopWhenCircleFinish=!1,void this.event(e.Event.STOPPED)):(a%=r,this._setPlayParams(a,i),void this.event(e.Event.COMPLETE));this._setPlayParams(a,i)}else{if(this._stopWhenCircleFinish)return this._setPlayParamsWhenStop(r,i),this._stopWhenCircleFinish=!1,void this.event(e.Event.STOPPED);this._currentTime=this._currentFrameTime=this._currentKeyframeIndex=0,this.event(e.Event.COMPLETE)}}}_destroy(){this.offAll(),this._templet=null,this._destroyed=!0}play(t=0,i=1,a=2147483647,r=0,s=0){if(!this._templet)throw new Error("AnimationPlayer:templet must not be null,maybe you need to set url.");if(a<0||r<0||s<0)throw new Error("AnimationPlayer:overallDuration,playStart and playEnd must large than zero.");if(0!==s&&r>s)throw new Error("AnimationPlayer:start must less than end.");this._currentTime=0,this._currentFrameTime=0,this._elapsedPlaybackTime=0,this.playbackRate=i,this._overallDuration=a,this._playStart=r,this._playEnd=s,this._paused=!1,this._currentAnimationClipIndex=t,this._currentKeyframeIndex=0,this._startUpdateLoopCount=e.Stat.loopCount,this.event(e.Event.PLAYED),this._calculatePlayDuration(),this._update(0)}playByFrame(t=0,e=1,i=2147483647,a=0,r=0,s=30){var n=1e3/s;this.play(t,e,i,a*n,r*n)}stop(t=!0){t?(this._currentTime=this._currentFrameTime=this._currentKeyframeIndex=0,this._currentAnimationClipIndex=-1,this.event(e.Event.STOPPED)):this._stopWhenCircleFinish=!0}destroy(){}}class u{constructor(){}static getBezierRate(t,e,i,a,r){var s=u._getBezierParamKey(e,i,a,r),n=100*s+t;if(u._bezierResultCache[n])return u._bezierResultCache[n];var h,l,o=u._getBezierPoints(e,i,a,r,s);for(l=o.length,h=0;h=r)&&(a=this._boneCurKeyFrm[e]=0);var s=t[a],n=i-s.startTime;if(0==n||n>0&&s.duration>n)return a;var h=0;if(n>0){for(i+=.01,h=a+1;hi)return this._boneCurKeyFrm[e]=h,h;return r-1}for(h=0;hi)return this._boneCurKeyFrm[e]=h,h;return a}getOriginalData(t,e,i,a,r){var s=this._anis[t].nodes,n=this._boneCurKeyFrm;n.lengththis.unfixedCurrentTimes[a]);)this.unfixedCurrentFrameIndexes[a]++;this.unfixedCurrentFrameIndexes[a]--}return this.unfixedCurrentFrameIndexes}getOriginalDataUnfixedRate(t,e,i){var a=this._anis[t].nodes;t!==this.unfixedLastAniIndex&&(this.unfixedCurrentFrameIndexes=new Uint32Array(a.length),this.unfixedCurrentTimes=new Float32Array(a.length),this.unfixedKeyframes=[],this.unfixedLastAniIndex=t);for(var r=0,s=0,n=a.length,h=0;sthis.unfixedCurrentTimes[s]);)this.unfixedKeyframes[s]=l.keyFrame[this.unfixedCurrentFrameIndexes[s]],this.unfixedCurrentFrameIndexes[s]++;var o=this.unfixedKeyframes[s];l.dataOffset=h;var u=i-o.startTime;if(l.lerpType)switch(l.lerpType){case 0:case 1:for(r=0;r-1&&tthis.currDisplayData.uvs[5]&&(u.d=-1),this.currDisplayData.uvs[0]>this.currDisplayData.uvs[4]&&this.currDisplayData.uvs[1]>this.currDisplayData.uvs[5]&&(l=!0,u.rotate(-Math.PI/2)),e.Matrix.mul(u,e.Matrix.TEMP,o)}else e.Matrix.TEMP.copyTo(o);a||(o=this.getSaveMatrix(o)),o._checkTransform(),l?t.drawTexture(n,-this.currDisplayData.height/2,-this.currDisplayData.width/2,this.currDisplayData.height,this.currDisplayData.width,o,r):t.drawTexture(n,-this.currDisplayData.width/2,-this.currDisplayData.height/2,this.currDisplayData.width,this.currDisplayData.height,o,r)}}}break;case 1:if(a?(null==this._skinSprite&&(this._skinSprite=g.createSkinMesh()),s=this._skinSprite):s=g.createSkinMesh(),null==s)return;var _;if(null==this.currDisplayData.bones){var p,d=this.currDisplayData.weights;this.deformData&&(d=this.deformData),this._diyTexture?(this._curDiyUV||(this._curDiyUV=[]),0==this._curDiyUV.length&&(this._curDiyUV=m.getRelativeUV(this.currTexture.uv,this.currDisplayData.uvs,this._curDiyUV),this._curDiyUV=m.getAbsoluteUV(this._diyTexture.uv,this._curDiyUV,this._curDiyUV)),p=this._curDiyUV):p=this.currDisplayData.uvs,this._mVerticleArr=d;this.currDisplayData.triangles.length;_=this.currDisplayData.triangles,this.deformData&&(a||(this._mVerticleArr=this.getSaveVerticle(this._mVerticleArr))),s.init2(n,_,this._mVerticleArr,p);var c,x=this.getDisplayMatrix();if(this._parentMatrix)if(x)e.Matrix.mul(x,this._parentMatrix,e.Matrix.TEMP),a?(null==this._resultMatrix&&(this._resultMatrix=new e.Matrix),c=this._resultMatrix):c=g._tempResultMatrix,e.Matrix.TEMP.copyTo(c),a||(c=this.getSaveMatrix(c)),s.transform=c}else this.skinMesh(i,s);t.drawSkin(s,r);break;case 2:if(a?(null==this._skinSprite&&(this._skinSprite=g.createSkinMesh()),s=this._skinSprite):s=g.createSkinMesh(),null==s)return;this.skinMesh(i,s),t.drawSkin(s,r)}}}skinMesh(t,e){var i,a=this.currTexture,r=this.currDisplayData.bones;this._diyTexture?(a=this._diyTexture,this._curDiyUV||(this._curDiyUV=[]),0==this._curDiyUV.length&&(this._curDiyUV=m.getRelativeUV(this.currTexture.uv,this.currDisplayData.uvs,this._curDiyUV),this._curDiyUV=m.getAbsoluteUV(this._diyTexture.uv,this._curDiyUV,this._curDiyUV)),i=this._curDiyUV):i=this.currDisplayData.uvs;var s,n,h,l,o,u=this.currDisplayData.weights,_=this.currDisplayData.triangles,p=0,d=0,c=0,x=0,y=0,f=0,M=0;if(g._tempVerticleArr.length=0,o=g._tempVerticleArr,this.deformData&&this.deformData.length>0){var D=0;for(f=0,M=r.length;f>>1;;){if(t[Math.floor(r+1)]<=e?i=r+1:a=r,i==a)return i+1;r=i+a>>>1}return 0}apply(t,e,i=1){if(t+=.05,!(this.timeList.length<=0)){var a=0;if(!(t=this.timeList[this.timeList.length-1]){var h=this.vectices[this.vectices.length-1];if(i<1)for(a=0;a180?u-=360:u<-180&&(u+=360),t.transform.skX=t.transform.skY=t.transform.skX+u*a,t.update()}updatePos(t,e){this._sp&&this._sp.pos(t,e)}_applyIk2(t,i,a,r,s,n){if(0!=n){var h,l,o,u=t.resultTransform.x,_=t.resultTransform.y,p=t.transform.scX,d=t.transform.scY,c=i.transform.scX;p<0?(p=-p,h=180,o=-1):(h=0,o=1),d<0&&(d=-d,o=-o),c<0?(c=-c,l=180):l=0;var m,x,y,g=i.resultTransform.x,f=t.resultMatrix.a,M=t.resultMatrix.c,D=t.resultMatrix.b,v=t.resultMatrix.d,I=Math.abs(p-d)<=1e-4;I?(x=f*g+M*(m=i.resultTransform.y)+t.resultMatrix.tx,y=D*g+v*m+t.resultMatrix.ty):(m=0,x=f*g+t.resultMatrix.tx,y=D*g+t.resultMatrix.ty),this.isDebug&&(this._sp||(this._sp=new e.Sprite,e.ILaya.stage.addChild(this._sp)),this._sp.graphics.clear(),this._sp.graphics.drawCircle(a,r,15,"#ffff00"),this._sp.graphics.drawCircle(x,y,15,"#ff00ff")),t.setRotation(Math.atan2(y-t.resultMatrix.ty,x-t.resultMatrix.tx));var T=t.parentBone;f=T.resultMatrix.a,M=T.resultMatrix.c,D=T.resultMatrix.b;var S,b,C=1/(f*(v=T.resultMatrix.d)-M*D),F=a-T.resultMatrix.tx,w=r-T.resultMatrix.ty,k=(F*v-w*M)*C-u,P=(w*f-F*D)*C-_,L=((F=x-T.resultMatrix.tx)*v-(w=y-T.resultMatrix.ty)*M)*C-u,U=(w*f-F*D)*C-_,B=Math.sqrt(L*L+U*U),E=i.length*c;if(I){var R=(k*k+P*P-B*B-(E*=p)*E)/(2*B*E);R<-1?R=-1:R>1&&(R=1),b=Math.acos(R)*s,f=B+E*R,M=E*Math.sin(b),S=Math.atan2(P*f-k*M,k*f+P*M)}else{var N=(f=p*E)*f,O=(M=d*E)*M,V=k*k+P*P,Y=Math.atan2(P,k),K=-2*O*B,X=O-N;if((v=K*K-4*X*(D=O*B*B+N*V-N*O))>0){var W=Math.sqrt(v);K<0&&(W=-W);var z=(W=-(K+W)/2)/X,G=D/W,q=Math.abs(z)$&&(J=0,$=v,tt=F),(v=(F=B-f)*F)$&&(J=it,$=v,tt=F,et=w),V<=(Q+$)/2?(S=Y-Math.atan2(j*s,Z),b=H*s):(S=Y-Math.atan2(et*s,tt),b=J*s)}var at=Math.atan2(m,g)*o,rt=t.resultTransform.skX;(S=(S-at)*A.radDeg+h-rt)>180?S-=360:S<-180&&(S+=360),t.resultTransform.x=u,t.resultTransform.y=_,t.resultTransform.skX=t.resultTransform.skY=rt+S*n,rt=i.resultTransform.skX,rt%=360,(b=((b+at)*A.radDeg-0)*o+l-rt)>180?b-=360:b<-180&&(b+=360),i.resultTransform.x=g,i.resultTransform.y=m,i.resultTransform.skX=i.resultTransform.skY=i.resultTransform.skY+b*n,t.update()}}_applyIk3(t,i,a,r,s,n){if(0==n)return;var h,l;const o=i.resultMatrix.a*i.length,u=i.resultMatrix.b*i.length,_=o*o+u*u,p=Math.sqrt(_);var d=t.resultMatrix.tx,c=t.resultMatrix.ty,m=i.resultMatrix.tx,x=i.resultMatrix.ty,y=m-d,g=x-c;const f=y*y+g*g,M=Math.sqrt(f),D=(y=a-t.resultMatrix.tx)*y+(g=r-t.resultMatrix.ty)*g,v=Math.sqrt(D);if(p+M<=v||v+p<=M||v+M<=p){var I;m=d+(I=p+M<=v?1:-1)*(a-d)*M/v,x=c+I*(r-c)*M/v}else{const t=(f-_+D)/(2*D),e=Math.sqrt(f-t*t*D)/v,i=d+y*t,a=c+g*t,r=-g*e,n=y*e;s>0?(m=i-r,x=a-n):(m=i+r,x=a+n)}var T,S,b,C;h=m,l=x,this.isDebug&&(this._sp||(this._sp=new e.Sprite,e.ILaya.stage.addChild(this._sp)),this._sp.graphics.clear(),this._sp.graphics.drawCircle(d,c,15,"#ff00ff"),this._sp.graphics.drawCircle(a,r,15,"#ffff00"),this._sp.graphics.drawCircle(h,l,15,"#ff00ff")),T=Math.atan2(l-t.resultMatrix.ty,h-t.resultMatrix.tx),t.setRotation(T),(S=A._tempMatrix).identity(),S.rotate(T),S.scale(t.resultMatrix.getScaleX(),t.resultMatrix.getScaleY()),S.translate(t.resultMatrix.tx,t.resultMatrix.ty),S.copyTo(t.resultMatrix),t.updateChild(),b=Math.atan2(r-l,a-h),i.setRotation(b),(C=A._tempMatrix).identity(),C.rotate(b),C.scale(i.resultMatrix.getScaleX(),i.resultMatrix.getScaleY()),C.translate(h,l),S.copyTo(i.resultMatrix),i.updateChild()}}A.radDeg=180/Math.PI,A.degRad=Math.PI/180,A._tempMatrix=new e.Matrix;class T{constructor(){this.boneNames=[],this.bendDirection=1,this.mix=1,this.isSpine=!0,this.targetBoneIndex=-1,this.boneIndexs=[]}}class S{constructor(t,e){this._debugKey=!1,this._segments=[],this._curves=[],this.data=t,this.position=t.position,this.spacing=t.spacing,this.rotateMix=t.rotateMix,this.translateMix=t.translateMix,this.bones=[];for(var i=this.data.bones,a=0,r=i.length;a0,s=this.data.spacingMode,n="length"==s,h=this.data.rotateMode,l="tangent"==h,o="chainScale"==h,u=[],_=this.bones.length,p=l?_:_+1,d=[];this._spaces=d,d[0]=this.position;var c=this.spacing;if(o||n)for(var m=0,x=p-1;mMath.PI?k-=2*Math.PI:k<-Math.PI&&(k+=2*Math.PI),k*=a,P=Math.cos(k),L=Math.sin(k),y.resultMatrix.a=P*U-L*E,y.resultMatrix.c=P*B-L*R,y.resultMatrix.b=L*U+P*E,y.resultMatrix.d=L*B+P*R}}}}computeWorldVertices2(t,e,i,a,r,s){var n,h,l,o=t.currDisplayData.bones,u=t.currDisplayData.weights,_=t.currDisplayData.triangles,p=0,d=0,c=0,m=0,x=0,y=0,g=0,f=0,M=0,D=0;if(null!=o){for(p=0;pl)this.addAfterPosition(_-l,h,y-4,M,o);else{for(;;u++)if(!(_>(c=I[u]))){0==u?_/=c:_=(_-(d=I[u-1]))/(c-d);break}if(u!=v){v=u;var W=6*u;for(C=2*(A=.03*((L=h[W])-2*(B=h[W+2])+(R=h[W+4])))+(S=.006*(3*(B-R)-L+(O=h[W+6]))),F=2*(T=.03*((U=h[W+1])-2*(E=h[W+3])+(N=h[W+5])))+(b=.006*(3*(E-N)-U+(V=h[W+7]))),w=.3*(B-L)+A+.16666667*S,k=.3*(E-U)+T+.16666667*b,X=Math.sqrt(w*w+k*k),K[0]=X,W=1;W<8;W++)w+=C,k+=F,C+=S,F+=b,X+=Math.sqrt(w*w+k*k),K[W]=X;w+=C,k+=F,X+=Math.sqrt(w*w+k*k),K[8]=X,w+=C+S,k+=F+b,X+=Math.sqrt(w*w+k*k),K[9]=X,Y=0}for(_*=X;;Y++)if(!(_>(c=K[Y]))){0==Y?_/=c:_=Y+(_-(d=K[Y-1]))/(c-d);break}this.addCurvePosition(.1*_,L,U,B,E,R,N,O,V,M,o,r||x>0&&0==p)}return M}addBeforePosition(t,e,i,a,r){var s=e[i],n=e[i+1],h=e[i+2]-s,l=e[i+3]-n,o=Math.atan2(l,h);a[r]=s+t*Math.cos(o),a[r+1]=n+t*Math.sin(o),a[r+2]=o}addAfterPosition(t,e,i,a,r){var s=e[i+2],n=e[i+3],h=s-e[i],l=n-e[i+1],o=Math.atan2(l,h);a[r]=s+t*Math.cos(o),a[r+1]=n+t*Math.sin(o),a[r+2]=o}addCurvePosition(t,e,i,a,r,s,n,h,l,o,u,_){0==t&&(t=1e-4);var p=t*t,d=p*t,c=1-t,m=c*c,x=m*c,y=c*t,g=3*y,f=c*g,M=g*t,D=e*x+a*f+s*M+h*d,v=i*x+r*f+n*M+l*d;o[u]=D,o[u+1]=v,o[u+2]=_?Math.atan2(v-(i*m+r*y*2+n*p),D-(e*m+a*y*2+s*p)):0}}S.BEFORE=-2,S.AFTER=-3,S._tempMt=new e.Matrix;class b{constructor(){this.bones=[]}}class C{constructor(t,e){var i,a;for(this._temp=[],this._data=t,null==this._bones&&(this._bones=[]),this.target=e[t.targetIndex],i=0,a=t.boneIndexs.length;i0){var h=t.resultMatrix.a,l=t.resultMatrix.b,o=t.resultMatrix.c,u=t.resultMatrix.d,_=Math.atan2(a,e)-Math.atan2(o,h)+this._data.offsetRotation*Math.PI/180;_>Math.PI?_-=2*Math.PI:_<-Math.PI&&(_+=2*Math.PI),_*=this.rotateMix;var p=Math.cos(_),d=Math.sin(_);t.resultMatrix.a=p*h-d*o,t.resultMatrix.b=p*l-d*u,t.resultMatrix.c=d*h+p*o,t.resultMatrix.d=d*l+p*u}if(this.translateMix&&(this._temp[0]=this._data.offsetX,this._temp[1]=this._data.offsetY,this.target.localToWorld(this._temp),t.resultMatrix.tx+=(this._temp[0]-t.resultMatrix.tx)*this.translateMix,t.resultMatrix.ty+=(this._temp[1]-t.resultMatrix.ty)*this.translateMix,t.updateChild()),this.scaleMix>0){var c=Math.sqrt(t.resultMatrix.a*t.resultMatrix.a+t.resultMatrix.c*t.resultMatrix.c),m=Math.sqrt(e*e+a*a),x=c>1e-5?(c+(m-c+this._data.offsetScaleX)*this.scaleMix)/c:0;t.resultMatrix.a*=x,t.resultMatrix.c*=x,c=Math.sqrt(t.resultMatrix.b*t.resultMatrix.b+t.resultMatrix.d*t.resultMatrix.d),m=Math.sqrt(i*i+r*r),x=c>1e-5?(c+(m-c+this._data.offsetScaleY)*this.scaleMix)/c:0,t.resultMatrix.b*=x,t.resultMatrix.d*=x}if(this.shearMix>0){l=t.resultMatrix.b,u=t.resultMatrix.d;var y=Math.atan2(u,l);(_=Math.atan2(r,i)-Math.atan2(a,e)-(y-Math.atan2(t.resultMatrix.c,t.resultMatrix.a)))>Math.PI?_-=2*Math.PI:_<-Math.PI&&(_+=2*Math.PI),_=y+(_+this._data.offsetShearY*Math.PI/180)*this.shearMix,x=Math.sqrt(l*l+u*u),t.resultMatrix.b=Math.cos(_)*x,t.resultMatrix.d=Math.sin(_)*x}}}}class F extends e.Sprite{constructor(t=null,e=0){super(),this._boneMatrixArray=[],this._lastTime=0,this._currAniIndex=-1,this._pause=!0,this._aniClipIndex=-1,this._clipIndex=-1,this._skinIndex=0,this._skinName="default",this._aniMode=0,this._index=-1,this._total=-1,this._indexControl=!1,this._eventIndex=0,this._drawOrderIndex=0,this._drawOrder=null,this._lastAniClipIndex=-1,this._lastUpdateAniClipIndex=-1,this._playAudio=!0,this._soundChannelArr=[],t&&this.init(t,e)}init(t,i=0){var a,r,s,n,h=0;if(1==i)for(this._graphicsCache=[],h=0,a=t.getAnimationCount();h0)for(this._ikArr=[],h=0,a=t.ikArr.length;h0)for(null==this._pathDic&&(this._pathDic={}),h=0,a=t.pathArr.length;h0)for(this._tfArr=[],h=0,a=t.tfArr.length;h0){var l=this._templet.skinDataArray[this._skinIndex];this._skinName=l.name}this._player.on(e.Event.PLAYED,this,this._onPlay),this._player.on(e.Event.STOPPED,this,this._onStop),this._player.on(e.Event.PAUSED,this,this._onPause)}get url(){return this._aniPath}set url(t){this.load(t)}load(t,i=null,a=0){this._aniPath=t,this._complete=i,this._loadAniMode=a,e.ILaya.loader.load([{url:t,type:e.ILaya.Loader.BUFFER}],e.Handler.create(this,this._onLoaded))}_onLoaded(){var t,a=e.ILaya.Loader.getRes(this._aniPath);null!=a&&(null==i.Templet.TEMPLET_DICTIONARY&&(i.Templet.TEMPLET_DICTIONARY={}),(t=i.Templet.TEMPLET_DICTIONARY[this._aniPath])?t.isParseFail?this._parseFail():t.isParserComplete?this._parseComplete():(t.on(e.Event.COMPLETE,this,this._parseComplete),t.on(e.Event.ERROR,this,this._parseFail)):((t=new i.Templet)._setCreateURL(this._aniPath),i.Templet.TEMPLET_DICTIONARY[this._aniPath]=t,t.on(e.Event.COMPLETE,this,this._parseComplete),t.on(e.Event.ERROR,this,this._parseFail),t.isParserComplete=!1,t.parseData(null,a)))}_parseComplete(){var t=i.Templet.TEMPLET_DICTIONARY[this._aniPath];t&&(this.init(t,this._loadAniMode),this.play(0,!0)),this._complete&&this._complete.runWith(this)}_parseFail(){console.log("[Error]:"+this._aniPath+"解析失败")}_onPlay(){this.event(e.Event.PLAYED)}_onStop(){var t,i=this._templet.eventAniArr[this._aniClipIndex];if(i&&this._eventIndex=this._player.playStart&&t.time<=this._player.playEnd&&this.event(e.Event.LABEL,t);this._drawOrder=null,this.event(e.Event.STOPPED)}_onPause(){this.event(e.Event.PAUSED)}_parseSrcBoneMatrix(){var t=0,i=0;for(i=this._templet.srcBoneMatrixArr.length,t=0;t=this._player.playStart&&n.time<=this._player.playEnd&&this.event(e.Event.LABEL,n)}}_update(t=!0){if(!(t&&this._pause||t&&this._indexControl)){var i=this.timer.currTimer,a=this._player.currentKeyframeIndex,r=i-this._lastTime;if(t?this._player._update(r):a=-1,this._lastTime=i,this._player&&(this._index=this._clipIndex=this._player.currentKeyframeIndex,!(this._index<0||r>0&&this._clipIndex==a&&this._lastUpdateAniClipIndex==this._aniClipIndex))){this._lastUpdateAniClipIndex=this._aniClipIndex,a>this._clipIndex&&0!=this._eventIndex&&(this._emitMissedEvents(this._player.playStart,this._player.playEnd,this._eventIndex),this._eventIndex=0);var s,n,h=this._templet.eventAniArr[this._aniClipIndex];if(h&&this._eventIndex=this._player.playStart&&l.time<=this._player.playEnd?this._player.currentPlayTime>=l.time&&(this.event(e.Event.LABEL,l),this._eventIndex++,this._playAudio&&l.audioValue&&"null"!==l.audioValue&&"undefined"!==l.audioValue&&(s=e.SoundManager.playSound(this._player.templet._path+l.audioValue,1,e.Handler.create(this,this._onAniSoundStoped)),e.SoundManager.playbackRate=this._player.playbackRate,s&&this._soundChannelArr.push(s))):l.time0)for(this._drawOrderIndex=0,i=r[this._drawOrderIndex];a>=i.time&&(this._drawOrder=i.drawOrder,this._drawOrderIndex++,!(this._drawOrderIndex>=r.length));)i=r[this._drawOrderIndex];0==this._aniMode||1==this._aniMode?this.graphics=p.create():this.graphics instanceof p?this.graphics.clear():this.graphics=p.create();var s=this.graphics,n=this._templet.getNodes(this._aniClipIndex),h=0==this._player.state;this._templet.getOriginalData(this._aniClipIndex,this._curOriginalData,null,t,h?a+this._player.cacheFrameRateInterval:a);var l,o,u,_,d=this._aniSectionDic[this._aniClipIndex],c=0,m=0,x=0,y=0,g=0,f=this._templet.srcBoneMatrixArr.length,M=this._curOriginalData;for(m=0,g=d[0];m0){if(this._lastAniClipIndex!=this._aniClipIndex)for(this._lastAniClipIndex=this._aniClipIndex,m=0,g=this._boneSlotArray.length;m-1&&o0&&this._onAniSoundStoped(!0),this.timer.clear(this,this._update))}playbackRate(t){this._player&&(this._player.playbackRate=t)}paused(){if(!this._pause){if(this._pause=!0,this._player&&(this._player.paused=!0),this._soundChannelArr.length>0)for(var t,e=this._soundChannelArr.length,i=0;i0)for(var t,i=this._soundChannelArr.length,a=0;a0&&this._onAniSoundStoped(!0)}get index(){return this._index}set index(t){this.player&&(this._index=t,this._player.currentTime=1e3*this._index/this._player.cacheFrameRate,this._indexControl=!0,(this._aniClipIndex<0||this._aniClipIndex>=this.getAnimNum())&&(this._aniClipIndex=0,this._currAniIndex=0,this._curOriginalData=new Float32Array(this._templet.getTotalkeyframesLength(this._currAniIndex)),this._drawOrder=null,this._eventIndex=0),this._update(!1))}get total(){return this._templet&&this._player?this._total=Math.floor(this._templet.getAniDuration(this._player.currentAnimationClipIndex)/1e3*this._player.cacheFrameRate):this._total=-1,this._total}get player(){return this._player}get templet(){return this._templet}}F.useSimpleMeshInCanvas=!1,i.Skeleton=F,e.ILaya.regClass(F),e.ClassUtils.regClass("laya.ani.bone.Skeleton",F),e.ClassUtils.regClass("Laya.Skeleton",F);class w{constructor(){this.slotArr=[]}}class k{createTexture(t){return this.texture||(this.texture=new e.Texture(t.bitmap,this.uvs),this.uvs[0]>this.uvs[4]&&this.uvs[1]>this.uvs[5]?(this.texture.width=t.height,this.texture.height=t.width,this.texture.offsetX=-t.offsetX,this.texture.offsetY=-t.offsetY,this.texture.sourceWidth=t.sourceHeight,this.texture.sourceHeight=t.sourceWidth):(this.texture.width=t.width,this.texture.height=t.height,this.texture.offsetX=-t.offsetX,this.texture.offsetY=-t.offsetY,this.texture.sourceWidth=t.sourceWidth,this.texture.sourceHeight=t.sourceHeight)),this.texture}destory(){this.texture&&this.texture.destroy()}}class P{constructor(){this.displayArr=[]}getDisplayByName(t){for(var e=0,i=this.displayArr.length;e0?a.slice(0,r)+"/":""}}this._mainTexture=t,this._rate=i,this.parse(e)}buildArmature(t=0){return new F(this,t)}parse(t){super.parse(t),this.event(e.Event.LOADED,this),this._aniVersion===U.LAYA_ANIMATION_VISION?this._isParseAudio=!0:this._aniVersion!=U.LAYA_ANIMATION_160_VISION&&console.log("[Error] 版本不一致,请使用IDE版本配套的重新导出"+this._aniVersion+"->"+U.LAYA_ANIMATION_VISION),this._mainTexture?this._parsePublicExtData():this._parseTexturePath()}_parseTexturePath(){if(this._isDestroyed)this.destroy();else{var t=0;this._loadList=[];var i,a=new e.Byte(this.getPublicExtData()),r=a.getInt32(),s=a.readUTFString(),n=s.split("\n");for(t=0;t0)for(this.attachmentNames=[],i=0;i0)for(Pt.bones=[],s=0;s0)for(Pt.uvs=[],s=0;s0)for(Pt.weights=[],s=0;s0)for(Pt.triangles=[],s=0;s0)for(Pt.vertices=[],s=0;s0)for(Pt.lengths=[],s=0;s=this.skinDataArray.length)return!1;var a,r,s,n,h=this.skinDataArray[e];if(h){for(a=0,r=h.slotArr.length;a=this._count){if(!this.loop)return this._playIndex--,void this.stop();this._playIndex=0}if(this._parseFrame(this._playIndex),this._labels&&this._labels[this._playIndex]&&this.event(e.Event.LABEL,this._labels[this._playIndex]),-1!=this._endFrame&&this._endFrame==this._playIndex){if(this._endFrame=-1,null!=this._completeHandler){var t=this._completeHandler;this._completeHandler=null,t.run()}this.stop()}}}stop(){this._playing=!1}gotoAndStop(t){this.index=t,this.stop()}_clear(){if(this.stop(),this._idOfSprite.length=0,!this._parentMovieClip){var t,i;for(this.timer.clear(this,this.updates),i=this._movieClipList.length,t=0;tt&&this._reset(),this._parseFrame(t))}_reset(t=!0){t&&1!=this._curIndex&&this.removeChildren(),this._preIndex=this._curIndex=-1,this._Pos=this._start}_parseFrame(t){var i,a,r,s,n,h,l=!1,o=this._idOfSprite,u=this._data;for(this._ended&&this._reset(),u.pos=this._Pos,this._ended=!1,this._playIndex=t,this._curIndex>t&&t0;break;case 7:var m=(a=o[u.getUint16()]).transform||e.Matrix.create();m.setTo(u.getFloat32(),u.getFloat32(),u.getFloat32(),u.getFloat32(),u.getFloat32(),u.getFloat32()),a.transform=m;break;case 8:o[u.getUint16()].setPos(u.getFloat32(),u.getFloat32());break;case 9:o[u.getUint16()].setSize(u.getFloat32(),u.getFloat32());break;case 10:o[u.getUint16()].alpha=u.getFloat32();break;case 11:o[u.getUint16()].setScale(u.getFloat32(),u.getFloat32());break;case 98:h=u.getString(),this.event(h),"stop"==h&&this.stop();break;case 99:this._curIndex=u.getUint16(),l&&this.updateZOrder();break;case 100:this._count=this._curIndex+1,this._ended=!0,this._playing&&(this.event(e.Event.FRAME),this.event(e.Event.END),this.event(e.Event.COMPLETE)),this._reset(!1)}this._playing&&!this._ended&&this.event(e.Event.FRAME),this._Pos=u.pos}_setData(t,e){this._data=t,this._start=e+3}set url(t){this.load(t)}load(t,i=!1,a=null){var r;this._url=t,i&&(this._atlasPath=a||t.split(".swf")[0]+".json"),this.stop(),this._clear(),this._movieClipList=[this],r=[{url:t,type:e.ILaya.Loader.BUFFER}],this._atlasPath&&r.push({url:this._atlasPath,type:e.ILaya.Loader.ATLAS}),e.ILaya.loader.load(r,e.Handler.create(this,this._onLoaded))}_onLoaded(){var t;(t=e.ILaya.Loader.getRes(this._url))?!this._atlasPath||e.ILaya.Loader.getAtlas(this._atlasPath)?(this.basePath=this._atlasPath?e.ILaya.Loader.getAtlas(this._atlasPath).dir:this._url.split(".swf")[0]+"/image/",this._initData(t)):this.event(e.Event.ERROR,"Atlas not find"):this.event(e.Event.ERROR,"file not find")}_initState(){this._reset(),this._ended=!1;var t=this._playing;for(this._playing=!1,this._curIndex=0;!this._ended;)this._parseFrame(++this._curIndex);this._playing=t}_initData(t){this._data=new e.Byte(t);var i,a=this._data.getUint16();for(i=0;i=f&&(t.size>l.minClearSize&&(l.minClearSize=t.size),i.onClearCacheRes()),i.deleteFile(e,a,n,s,t.size)},fail:function(e){null!=n&&n.runWith([1,e])}}):null!=n&&n.runWith([0]):i.fs.getFileInfo({filePath:e,success:function(t){o&&m+4194304+t.size>=f&&(t.size>l.minClearSize&&(l.minClearSize=t.size),i.onClearCacheRes()),i.fs.copyFile({srcPath:e,destPath:h,success:function(e){i.onSaveFile(a,d,!0,s,n,t.size)},fail:function(e){null!=n&&n.runWith([1,e])}})},fail:function(e){null!=n&&n.runWith([1,e])}})}static onClearCacheRes(){var e=l.minClearSize,t=[];for(var a in i.filesListObj)"fileUsedSize"!=a&&t.push(i.filesListObj[a]);i.sortOn(t,"times",i.NUMERIC);for(var n=0,s=1,o=t.length;s=e)break;n+=r.size,i.deleteFile("",r.readyUrl)}}static sortOn(e,t,a=0){return a==i.NUMERIC?e.sort((function(e,i){return e[t]-i[t]})):a==(i.NUMERIC|i.DESCENDING)?e.sort((function(e,i){return i[t]-e[t]})):e.sort((function(e,i){return e[t]-i[t]}))}static getFileNativePath(e){return i.fileNativeDir+"/"+e}static deleteFile(e,t="",a=null,n="",s=0){var o=i.getFileInfo(t),r=i.getFileNativePath(o.md5);i.fs.unlink({filePath:r,success:function(o){if(""!=e){var r=i.getFileNativePath(e);i.fs.copyFile({srcPath:e,destPath:r,success:function(o){i.onSaveFile(t,e,!0,n,a,s)},fail:function(e){null!=a&&a.runWith([1,e])}})}else i.onSaveFile(t,e,!1,n,a,s)},fail:function(e){null!=a&&a.runWith([1,e])}})}static deleteAll(){var e=[];for(var t in i.filesListObj)"fileUsedSize"!=t&&e.push(i.filesListObj[t]);for(var a=1,n=e.length;a0&&this.loops--,this.startTime=0,this.play()}play(){this.isStopped=!1,t.SoundManager.addChannel(this),this._audio.play()}set startTime(e){this._audio&&(this._audio.startTime=e)}set autoplay(e){this._audio.autoplay=e}get autoplay(){return this._audio.autoplay}get position(){return this._audio?this._audio.currentTime:0}get duration(){return this._audio?this._audio.duration:0}stop(){this.isStopped=!0,t.SoundManager.removeChannel(this),this.completeHandler=null,this._audio&&(this._audio.stop(),this.loop||(this._audio.offEnded(null),this._miniSound.dispose(),this._audio=null,this._miniSound=null,this._onEnd=null))}pause(){this.isStopped=!0,this._audio.pause()}get loop(){return this._audio.loop}set loop(e){this._audio.loop=e}resume(){this._audio&&(this.isStopped=!1,t.SoundManager.addChannel(this),this._audio.play())}set volume(e){this._audio&&(this._audio.volume=e)}get volume(){return this._audio?this._audio.volume:1}}class n extends t.EventDispatcher{constructor(){super(),this.loaded=!1}static _createSound(){return n._id++,l.window.swan.createInnerAudioContext()}load(e){if(n._musicAudio||(n._musicAudio=n._createSound()),i.isLocalNativeFile(e)){if(-1!=e.indexOf("http://")||-1!=e.indexOf("https://"))if(""!=i.loadPath)e=e.split(i.loadPath)[1];else{var a=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath;""!=a&&(e=e.split(a)[1])}}else e=t.URL.formatURL(e);if(this.url=e,this.readyUrl=e,n._audioCache[this.readyUrl])this.event(t.Event.COMPLETE);else if(l.autoCacheFile&&i.getFileInfo(e))this.onDownLoadCallBack(e,0);else if(l.autoCacheFile)if(i.isLocalNativeFile(e)){var s=e;if(""!=(a=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath)&&(e=e.split(a)[1]),e||(e=s),l.subNativeFiles&&0==l.subNativeheads.length)for(var o in l.subNativeFiles){var r=l.subNativeFiles[o];l.subNativeheads=l.subNativeheads.concat(r);for(var d=0;d=0?"/":"\\",s=e.lastIndexOf(n),o=s>=0?e.substr(0,s+1):"",r=0,d=a.length;r\s+<");try{t=(new l.window.Parser.DOMParser).parseFromString(e,"text/xml")}catch(e){throw"需要引入xml解析库文件"}return t},l.idx=1;class d extends t.EventDispatcher{constructor(){super()}static __init__(){try{var e;if(!(e=t.Accelerator))return;e.prototype.on=d.prototype.on,e.prototype.off=d.prototype.off}catch(e){}}static startListen(e){if(d._callBack=e,!d._isListening){d._isListening=!0;try{l.window.swan.onAccelerometerChange(d.onAccelerometerChange)}catch(e){}}}static stopListen(){d._isListening=!1;try{l.window.swan.stopAccelerometer({})}catch(e){}}static onAccelerometerChange(e){var t;(t={}).acceleration=e,t.accelerationIncludingGravity=e,t.rotationRate={},null!=d._callBack&&d._callBack(t)}on(e,t,i,a=null){return super.on(e,t,i,a),d.startListen(this.onDeviceOrientationChange),this}off(e,t,i,a=!1){return this.hasListener(e)||d.stopListen(),super.off(e,t,i,a)}}d._isListening=!1;class u{_loadImage(e){if(l.isZiYu)u.onCreateImage(e,this,!0);else{var a;if(i.isLocalNativeFile(e)){if(-1==e.indexOf("http://usr/")&&(-1!=e.indexOf("http://")||-1!=e.indexOf("https://")))if(""!=i.loadPath)e=e.split(i.loadPath)[1];else{var n=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath,s=e;""!=n&&(e=e.split(n)[1]),e||(e=s)}if(l.subNativeFiles&&0==l.subNativeheads.length)for(var o in l.subNativeFiles){var r=l.subNativeFiles[o];l.subNativeheads=l.subNativeheads.concat(r);for(var d=0;d=f&&(t.size>r.minClearSize&&(r.minClearSize=t.size),i.onClearCacheRes()),i.deleteFile(e,a,n,o,t.size)},fail:function(e){null!=n&&n.runWith([1,e])}}):null!=n&&n.runWith([0]):i.fs.getFileInfo({filePath:e,success:function(t){s&&m+4194304+t.size>=f&&(t.size>r.minClearSize&&(r.minClearSize=t.size),i.onClearCacheRes()),i.fs.copyFile({srcPath:e,destPath:h,success:function(e){i.onSaveFile(a,d,!0,o,n,t.size)},fail:function(e){null!=n&&n.runWith([1,e])}})},fail:function(e){null!=n&&n.runWith([1,e])}})}static onClearCacheRes(){var e=r.minClearSize,t=[];for(var a in i.filesListObj)"fileUsedSize"!=a&&t.push(i.filesListObj[a]);i.sortOn(t,"times",i.NUMERIC);for(var n=0,o=1,s=t.length;o=e)break;n+=l.size,i.deleteFile("",l.readyUrl)}}static sortOn(e,t,a=0){return a==i.NUMERIC?e.sort((function(e,i){return e[t]-i[t]})):a==(i.NUMERIC|i.DESCENDING)?e.sort((function(e,i){return i[t]-e[t]})):e.sort((function(e,i){return e[t]-i[t]}))}static getFileNativePath(e){return i.fileNativeDir+"/"+e}static deleteFile(e,t="",a=null,n="",o=0){var s=i.getFileInfo(t),l=i.getFileNativePath(s.md5);i.fs.unlink({filePath:l,success:function(s){if(""!=e){var l=i.getFileNativePath(e);i.fs.copyFile({srcPath:e,destPath:l,success:function(s){i.onSaveFile(t,e,!0,n,a,o)},fail:function(e){null!=a&&a.runWith([1,e])}})}else i.onSaveFile(t,e,!1,n,a,o)},fail:function(e){null!=a&&a.runWith([1,e])}})}static deleteAll(){var e=[];for(var t in i.filesListObj)"fileUsedSize"!=t&&e.push(i.filesListObj[t]);for(var a=1,n=e.length;a0&&this.loops--,this.startTime=0,this.play()}play(){this.isStopped=!1,t.SoundManager.addChannel(this),this._audio.play()}set startTime(e){this._audio&&(this._audio.startTime=e)}set autoplay(e){this._audio.autoplay=e}get autoplay(){return this._audio.autoplay}get position(){return this._audio?this._audio.currentTime:0}get duration(){return this._audio?this._audio.duration:0}stop(){this.isStopped=!0,t.SoundManager.removeChannel(this),this.completeHandler=null,this._audio&&(this._audio.stop(),this.loop||(this._audio.offEnded(null),this._miniSound.dispose(),this._audio=null,this._miniSound=null,this._onEnd=null))}pause(){this.isStopped=!0,this._audio.pause()}get loop(){return this._audio.loop}set loop(e){this._audio.loop=e}resume(){this._audio&&(this.isStopped=!1,t.SoundManager.addChannel(this),this._audio.play())}set volume(e){this._audio&&(this._audio.volume=e)}get volume(){return this._audio?this._audio.volume:1}}class n extends t.EventDispatcher{constructor(){super(),this.loaded=!1}static _createSound(){return n._id++,r.window.bl.createInnerAudioContext()}load(e){if(n._musicAudio||(n._musicAudio=n._createSound()),i.isLocalNativeFile(e)){if(-1!=e.indexOf("http://")||-1!=e.indexOf("https://"))if(""!=i.loadPath)e=e.split(i.loadPath)[1];else{var a=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath;""!=a&&(e=e.split(a)[1])}}else e=t.URL.formatURL(e);if(this.url=e,this.readyUrl=e,n._audioCache[this.readyUrl])this.event(t.Event.COMPLETE);else if(r.autoCacheFile&&i.getFileInfo(e))this.onDownLoadCallBack(e,0);else if(r.autoCacheFile)if(i.isLocalNativeFile(e)){var o=e;if(""!=(a=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath)&&(e=e.split(a)[1]),e||(e=o),r.subNativeFiles&&0==r.subNativeheads.length)for(var s in r.subNativeFiles){var l=r.subNativeFiles[s];r.subNativeheads=r.subNativeheads.concat(l);for(var d=0;d=0?"/":"\\",o=e.lastIndexOf(n),s=o>=0?e.substr(0,o+1):"",l=0,d=a.length;l>>"+n)}}return t},r._inited=!1,r.autoCacheFile=!0,r.minClearSize=5242880,r.sizeLimit=52428800,r.nativefiles=["layaNativeDir","bllocal"],r.subNativeFiles=[],r.subNativeheads=[],r.subMaps=[],r.AutoCacheDownFile=!1,r.parseXMLFromString=function(e){var t;e=e.replace(/>\s+<");try{t=(new r.window.Parser.DOMParser).parseFromString(e,"text/xml")}catch(e){throw"需要引入xml解析库文件"}return t},r.idx=1;class d extends t.EventDispatcher{constructor(){super()}static __init__(){try{var e;if(!(e=t.Accelerator))return;e.prototype.on=d.prototype.on,e.prototype.off=d.prototype.off}catch(e){}}static startListen(e){if(d._callBack=e,!d._isListening){d._isListening=!0;try{r.window.bl.onAccelerometerChange(d.onAccelerometerChange)}catch(e){}}}static stopListen(){d._isListening=!1;try{r.window.bl.stopAccelerometer({})}catch(e){}}static onAccelerometerChange(e){var t;(t={}).acceleration=e,t.accelerationIncludingGravity=e,t.rotationRate={},null!=d._callBack&&d._callBack(t)}on(e,t,i,a=null){return super.on(e,t,i,a),d.startListen(this.onDeviceOrientationChange),this}off(e,t,i,a=!1){return this.hasListener(e)||d.stopListen(),super.off(e,t,i,a)}}d._isListening=!1;class u{_loadImage(e){if(r.isZiYu)u.onCreateImage(e,this,!0);else{var a;if(i.isLocalNativeFile(e)){if(-1==e.indexOf(r.window.bl.env.USER_DATA_PATH)&&(-1!=e.indexOf("http://")||-1!=e.indexOf("https://")))if(""!=i.loadPath)e=e.split(i.loadPath)[1];else{var n=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath,o=e;""!=n&&(e=e.split(n)[1]),e||(e=o)}if(r.subNativeFiles&&0==r.subNativeheads.length)for(var s in r.subNativeFiles){var l=r.subNativeFiles[s];r.subNativeheads=r.subNativeheads.concat(l);for(var d=0;d (http://steffe.se)",keywords:["cannon.js","cannon","physics","engine","3d"],main:"./build/cannon.js",engines:{node:"*"},repository:{type:"git",url:"https://github.com/schteppe/cannon.js.git"},bugs:{url:"https://github.com/schteppe/cannon.js/issues"},licenses:[{type:"MIT"}],devDependencies:{jshint:"latest","uglify-js":"latest",nodeunit:"^0.9.0",grunt:"~0.4.0","grunt-contrib-jshint":"~0.1.1","grunt-contrib-nodeunit":"^0.4.1","grunt-contrib-concat":"~0.1.3","grunt-contrib-uglify":"^0.5.1","grunt-browserify":"^2.1.4","grunt-contrib-yuidoc":"^0.5.2",browserify:"*"},dependencies:{}}},{}],2:[function(t,i,o){i.exports={version:t("../package.json").version,AABB:t("./collision/AABB"),ArrayCollisionMatrix:t("./collision/ArrayCollisionMatrix"),Body:t("./objects/Body"),Box:t("./shapes/Box"),Broadphase:t("./collision/Broadphase"),Constraint:t("./constraints/Constraint"),ContactEquation:t("./equations/ContactEquation"),Narrowphase:t("./world/Narrowphase"),ConeTwistConstraint:t("./constraints/ConeTwistConstraint"),ContactMaterial:t("./material/ContactMaterial"),ConvexPolyhedron:t("./shapes/ConvexPolyhedron"),Cylinder:t("./shapes/Cylinder"),DistanceConstraint:t("./constraints/DistanceConstraint"),Equation:t("./equations/Equation"),EventTarget:t("./utils/EventTarget"),FrictionEquation:t("./equations/FrictionEquation"),GSSolver:t("./solver/GSSolver"),GridBroadphase:t("./collision/GridBroadphase"),Heightfield:t("./shapes/Heightfield"),HingeConstraint:t("./constraints/HingeConstraint"),LockConstraint:t("./constraints/LockConstraint"),Mat3:t("./math/Mat3"),Material:t("./material/Material"),NaiveBroadphase:t("./collision/NaiveBroadphase"),ObjectCollisionMatrix:t("./collision/ObjectCollisionMatrix"),Pool:t("./utils/Pool"),Particle:t("./shapes/Particle"),Plane:t("./shapes/Plane"),PointToPointConstraint:t("./constraints/PointToPointConstraint"),Quaternion:t("./math/Quaternion"),Ray:t("./collision/Ray"),RaycastVehicle:t("./objects/RaycastVehicle"),RaycastResult:t("./collision/RaycastResult"),RigidVehicle:t("./objects/RigidVehicle"),RotationalEquation:t("./equations/RotationalEquation"),RotationalMotorEquation:t("./equations/RotationalMotorEquation"),SAPBroadphase:t("./collision/SAPBroadphase"),SPHSystem:t("./objects/SPHSystem"),Shape:t("./shapes/Shape"),Solver:t("./solver/Solver"),Sphere:t("./shapes/Sphere"),SplitSolver:t("./solver/SplitSolver"),Spring:t("./objects/Spring"),Trimesh:t("./shapes/Trimesh"),Vec3:t("./math/Vec3"),Vec3Pool:t("./utils/Vec3Pool"),World:t("./world/World")}},{"../package.json":1,"./collision/AABB":3,"./collision/ArrayCollisionMatrix":4,"./collision/Broadphase":5,"./collision/GridBroadphase":6,"./collision/NaiveBroadphase":7,"./collision/ObjectCollisionMatrix":8,"./collision/Ray":9,"./collision/RaycastResult":10,"./collision/SAPBroadphase":11,"./constraints/ConeTwistConstraint":12,"./constraints/Constraint":13,"./constraints/DistanceConstraint":14,"./constraints/HingeConstraint":15,"./constraints/LockConstraint":16,"./constraints/PointToPointConstraint":17,"./equations/ContactEquation":19,"./equations/Equation":20,"./equations/FrictionEquation":21,"./equations/RotationalEquation":22,"./equations/RotationalMotorEquation":23,"./material/ContactMaterial":24,"./material/Material":25,"./math/Mat3":27,"./math/Quaternion":28,"./math/Vec3":30,"./objects/Body":31,"./objects/RaycastVehicle":32,"./objects/RigidVehicle":33,"./objects/SPHSystem":34,"./objects/Spring":35,"./shapes/Box":37,"./shapes/ConvexPolyhedron":38,"./shapes/Cylinder":39,"./shapes/Heightfield":40,"./shapes/Particle":41,"./shapes/Plane":42,"./shapes/Shape":43,"./shapes/Sphere":44,"./shapes/Trimesh":45,"./solver/GSSolver":46,"./solver/Solver":47,"./solver/SplitSolver":48,"./utils/EventTarget":49,"./utils/Pool":51,"./utils/Vec3Pool":54,"./world/Narrowphase":55,"./world/World":56}],3:[function(t,i,o){var n=t("../math/Vec3");t("../utils/Utils");function AABB(t){t=t||{},this.lowerBound=new n,t.lowerBound&&this.lowerBound.copy(t.lowerBound),this.upperBound=new n,t.upperBound&&this.upperBound.copy(t.upperBound)}i.exports=AABB;var r=new n;AABB.prototype.setFromPoints=function(t,i,o,n){var a=this.lowerBound,l=this.upperBound,h=o;a.copy(t[0]),h&&h.vmult(a,a),l.copy(a);for(var c=1;cl.x&&(l.x=p.x),p.xl.y&&(l.y=p.y),p.yl.z&&(l.z=p.z),p.zi&&(this.lowerBound.x=i);var o=t.upperBound.x;this.upperBound.xi&&(this.lowerBound.y=i);o=t.upperBound.y;this.upperBound.yi&&(this.lowerBound.z=i);o=t.upperBound.z;this.upperBound.z=r.x&&i.y<=n.y&&o.y>=r.y&&i.z<=n.z&&o.z>=r.z},AABB.prototype.getCorners=function(t,i,o,n,r,a,l,h){var c=this.lowerBound,p=this.upperBound;t.copy(c),i.set(p.x,c.y,c.z),o.set(p.x,p.y,c.z),n.set(c.x,p.y,p.z),r.set(p.x,c.y,c.z),a.set(c.x,p.y,c.z),l.set(c.x,c.y,p.z),h.copy(p)};var a=[new n,new n,new n,new n,new n,new n,new n,new n];AABB.prototype.toLocalFrame=function(t,i){var o=a,n=o[0],r=o[1],l=o[2],h=o[3],c=o[4],p=o[5],u=o[6],d=o[7];this.getCorners(n,r,l,h,c,p,u,d);for(var y=0;8!==y;y++){var v=o[y];t.pointToLocal(v,v)}return i.setFromPoints(o)},AABB.prototype.toWorldFrame=function(t,i){var o=a,n=o[0],r=o[1],l=o[2],h=o[3],c=o[4],p=o[5],u=o[6],d=o[7];this.getCorners(n,r,l,h,c,p,u,d);for(var y=0;8!==y;y++){var v=o[y];t.pointToWorld(v,v)}return i.setFromPoints(o)}},{"../math/Vec3":30,"../utils/Utils":53}],4:[function(t,i,o){function ArrayCollisionMatrix(){this.matrix=[]}i.exports=ArrayCollisionMatrix,ArrayCollisionMatrix.prototype.get=function(t,i){if(t=t.index,(i=i.index)>t){var o=i;i=t,t=o}return this.matrix[(t*(t+1)>>1)+i-1]},ArrayCollisionMatrix.prototype.set=function(t,i,o){if(t=t.index,(i=i.index)>t){var n=i;i=t,t=n}this.matrix[(t*(t+1)>>1)+i-1]=o?1:0},ArrayCollisionMatrix.prototype.reset=function(){for(var t=0,i=this.matrix.length;t!==i;t++)this.matrix[t]=0},ArrayCollisionMatrix.prototype.setNumObjects=function(t){this.matrix.length=t*(t-1)>>1}},{}],5:[function(t,i,o){var n=t("../objects/Body"),r=t("../math/Vec3"),a=t("../math/Quaternion");t("../shapes/Shape"),t("../shapes/Plane");function Broadphase(){this.world=null,this.useBoundingBoxes=!1,this.dirty=!0}i.exports=Broadphase,Broadphase.prototype.collisionPairs=function(t,i,o){throw new Error("collisionPairs not implemented for this BroadPhase class!")};n.STATIC,n.KINEMATIC;Broadphase.prototype.needBroadphaseCollision=function(t,i){return 0!=(t.collisionFilterGroup&i.collisionFilterMask)&&0!=(i.collisionFilterGroup&t.collisionFilterMask)&&(0==(t.type&n.STATIC)&&t.sleepState!==n.SLEEPING||0==(i.type&n.STATIC)&&i.sleepState!==n.SLEEPING)},Broadphase.prototype.intersectionTest=function(t,i,o,n){this.useBoundingBoxes?this.doBoundingBoxBroadphase(t,i,o,n):this.doBoundingSphereBroadphase(t,i,o,n)};var l=new r;new r,new a,new r;Broadphase.prototype.doBoundingSphereBroadphase=function(t,i,o,n){var r=l;i.position.vsub(t.position,r);var a=Math.pow(t.boundingRadius+i.boundingRadius,2);r.norm2()o.norm2()},Broadphase.prototype.aabbQuery=function(t,i,o){return console.warn(".aabbQuery is not implemented in this Broadphase subclass."),[]}},{"../math/Quaternion":28,"../math/Vec3":30,"../objects/Body":31,"../shapes/Plane":42,"../shapes/Shape":43}],6:[function(t,i,o){i.exports=GridBroadphase;var n=t("./Broadphase"),r=t("../math/Vec3"),a=t("../shapes/Shape");function GridBroadphase(t,i,o,a,l){n.apply(this),this.nx=o||10,this.ny=a||10,this.nz=l||10,this.aabbMin=t||new r(100,100,100),this.aabbMax=i||new r(-100,-100,-100);var h=this.nx*this.ny*this.nz;if(h<=0)throw"GridBroadphase: Each dimension's n must be >0";this.bins=[],this.binLengths=[],this.bins.length=h,this.binLengths.length=h;for(var c=0;c=p&&(h=p-1),c<0?c=0:c>=u&&(c=u-1),f<0?f=0:f>=d&&(f=d-1),m<0?m=0:m>=p&&(m=p-1),g<0?g=0:g>=u&&(g=u-1),A<0?A=0:A>=d&&(A=d-1),c*=v,f*=1,m*=y,g*=v,A*=1;for(var B=h*=y;B<=m;B+=y)for(var E=c;E<=g;E+=v)for(var T=f;T<=A;T+=1){var R=B+E+T;O[R][V[R]++]=l}}for(M=0;M!==n;M++){var z=(it=r[M]).shape;switch(z.type){case P:var L=it.position.x,q=it.position.y,W=it.position.z,j=z.radius;addBoxToBins(L-j,q-j,W-j,L+j,q+j,W+j,it);break;case N:z.worldNormalNeedsUpdate&&z.computeWorldNormal(it.quaternion);var D=z.worldNormal,U=w+.5*A-it.position.x,H=b+.5*B-it.position.y,k=x+.5*E-it.position.z,G=l;G.set(U,H,k);for(var Q=0,Y=0;Q!==p;Q++,Y+=y,G.y=H,G.x+=A)for(var X=0,Z=0;X!==u;X++,Z+=v,G.z=k,G.y+=B)for(var K=0,J=0;K!==d;K++,J+=1,G.z+=E)if(G.dot(D)1){var et=O[M];for(Q=0;Q!==tt;Q++){var it=et[Q];for(X=0;X!==Q;X++){var ot=et[X];this.needBroadphaseCollision(it,ot)&&this.intersectionTest(it,ot,i,o)}}}}this.makePairsUnique(i,o)}},{"../math/Vec3":30,"../shapes/Shape":43,"./Broadphase":5}],7:[function(t,i,o){i.exports=NaiveBroadphase;var n=t("./Broadphase"),r=t("./AABB");function NaiveBroadphase(){n.apply(this)}NaiveBroadphase.prototype=new n,NaiveBroadphase.prototype.constructor=NaiveBroadphase,NaiveBroadphase.prototype.collisionPairs=function(t,i,o){var n,r,a,l,h=t.bodies,c=h.length;for(n=0;n!==c;n++)for(r=0;r!==n;r++)a=h[n],l=h[r],this.needBroadphaseCollision(a,l)&&this.intersectionTest(a,l,i,o)};new r;NaiveBroadphase.prototype.aabbQuery=function(t,i,o){o=o||[];for(var n=0;nt){var o=i;i=t,t=o}return t+"-"+i in this.matrix},ObjectCollisionMatrix.prototype.set=function(t,i,o){if(t=t.id,(i=i.id)>t){var n=i;i=t,t=n}o?this.matrix[t+"-"+i]=!0:delete this.matrix[t+"-"+i]},ObjectCollisionMatrix.prototype.reset=function(){this.matrix={}},ObjectCollisionMatrix.prototype.setNumObjects=function(t){}},{}],9:[function(t,i,o){i.exports=Ray;var n=t("../math/Vec3"),r=t("../math/Quaternion"),a=t("../math/Transform"),l=(t("../shapes/ConvexPolyhedron"),t("../shapes/Box"),t("../collision/RaycastResult")),h=t("../shapes/Shape"),c=t("../collision/AABB");function Ray(t,i){this.from=t?t.clone():new n,this.to=i?i.clone():new n,this._direction=new n,this.precision=1e-4,this.checkCollisionResponse=!0,this.skipBackfaces=!1,this.collisionFilterMask=-1,this.collisionFilterGroup=-1,this.mode=Ray.ANY,this.result=new l,this.hasHit=!1,this.callback=function(t){}}Ray.prototype.constructor=Ray,Ray.CLOSEST=1,Ray.ANY=2,Ray.ALL=4;var p=new c,u=[];Ray.prototype.intersectWorld=function(t,i){return this.mode=i.mode||Ray.ANY,this.result=i.result||new l,this.skipBackfaces=!!i.skipBackfaces,this.collisionFilterMask=void 0!==i.collisionFilterMask?i.collisionFilterMask:-1,this.collisionFilterGroup=void 0!==i.collisionFilterGroup?i.collisionFilterGroup:-1,i.from&&this.from.copy(i.from),i.to&&this.to.copy(i.to),this.callback=i.callback||function(){},this.hasHit=!1,this.result.reset(),this._updateDirection(),this.getAABB(p),u.length=0,t.broadphase.aabbQuery(t,p,u),this.intersectBodies(u),this.hasHit};var d=new n,y=new n;function pointInTriangle(t,i,o,n){n.vsub(i,I),o.vsub(i,d),t.vsub(i,y);var r,a,l=I.dot(I),h=I.dot(d),c=I.dot(y),p=d.dot(d),u=d.dot(y);return(r=p*c-h*u)>=0&&(a=l*u-h*c)>=0&&r+at.boundingSphereRadius)){var r=this[t.type];r&&r.call(this,t,i,o,n)}};new n,new n;var m=new n,g=new n,w=new n,b=new n;new n,new l;Ray.prototype.intersectBox=function(t,i,o,n){return this.intersectConvex(t.convexPolyhedronRepresentation,i,o,n)},Ray.prototype[h.types.BOX]=Ray.prototype.intersectBox,Ray.prototype.intersectPlane=function(t,i,o,r){var a=this.from,l=this.to,h=this._direction,c=new n(0,0,1);i.vmult(c,c);var p=new n;a.vsub(o,p);var u=p.dot(c);if(l.vsub(o,p),!(u*p.dot(c)>0||a.distanceTo(l)d)&&(d=c[0]),(null===u||c[1]y)&&(y=c[1])),null!==p){var f=[];t.getRectMinMax(p,u,d,y,f);for(var m=p;m<=d;m++)for(var g=u;g<=y;g++){if(this.result._shouldStop)return;if(t.getConvexTrianglePillar(m,g,!1),a.pointToWorldFrame(o,i,t.pillarOffset,l),this.intersectConvex(t.pillarConvex,i,l,r,x),this.result._shouldStop)return;t.getConvexTrianglePillar(m,g,!0),a.pointToWorldFrame(o,i,t.pillarOffset,l),this.intersectConvex(t.pillarConvex,i,l,r,x)}}},Ray.prototype[h.types.HEIGHTFIELD]=Ray.prototype.intersectHeightfield;var C=new n,_=new n;Ray.prototype.intersectSphere=function(t,i,o,n){var r=this.from,a=this.to,l=t.radius,h=Math.pow(a.x-r.x,2)+Math.pow(a.y-r.y,2)+Math.pow(a.z-r.z,2),c=2*((a.x-r.x)*(r.x-o.x)+(a.y-r.y)*(r.y-o.y)+(a.z-r.z)*(r.z-o.z)),p=Math.pow(r.x-o.x,2)+Math.pow(r.y-o.y,2)+Math.pow(r.z-o.z,2)-Math.pow(l,2),u=Math.pow(c,2)-4*h*p,d=C,y=_;if(!(u<0))if(0===u)r.lerp(a,u,d),d.vsub(o,y),y.normalize(),this.reportIntersection(y,d,t,n,-1);else{var v=(-c-Math.sqrt(u))/(2*h),f=(-c+Math.sqrt(u))/(2*h);if(v>=0&&v<=1&&(r.lerp(a,v,d),d.vsub(o,y),y.normalize(),this.reportIntersection(y,d,t,n,-1)),this.result._shouldStop)return;f>=0&&f<=1&&(r.lerp(a,f,d),d.vsub(o,y),y.normalize(),this.reportIntersection(y,d,t,n,-1))}},Ray.prototype[h.types.SPHERE]=Ray.prototype.intersectSphere;var S=new n,A=(new n,new n,new n);Ray.prototype.intersectConvex=function(t,i,o,n,r){for(var a=S,l=A,h=r&&r.faceList||null,c=t.faces,p=t.vertices,u=t.faceNormals,d=this._direction,y=this.from,v=this.to,f=y.distanceTo(v),x=h?h.length:c.length,C=this.result,_=0;!C._shouldStop&&_f||this.reportIntersection(a,m,t,n,B)}}}}},Ray.prototype[h.types.CONVEXPOLYHEDRON]=Ray.prototype.intersectConvex;var B=new n,E=new n,T=new n,R=new n,P=new n,N=new n,O=(new c,[]),V=new a;Ray.prototype.intersectTrimesh=function(t,i,o,n,r){var l=B,h=O,c=V,p=A,u=E,d=T,y=R,v=N,f=P,x=(r&&r.faceList,t.indices),C=(t.vertices,t.faceNormals,this.from),_=this.to,S=this._direction;c.position.copy(o),c.quaternion.copy(i),a.vectorToLocalFrame(o,i,S,u),a.pointToLocalFrame(o,i,C,d),a.pointToLocalFrame(o,i,_,y);var I=d.distanceSquared(y);t.tree.rayQuery(this,c,h);for(var M=0,F=h.length;!this.result._shouldStop&&M!==F;M++){var z=h[M];t.getNormal(z,l),t.getVertex(x[3*z],g),g.vsub(d,p);var L=u.dot(l),q=l.dot(p)/L;if(!(q<0)){u.scale(q,m),m.vadd(d,m),t.getVertex(x[3*z+1],w),t.getVertex(x[3*z+2],b);var W=m.distanceSquared(d);!pointInTriangle(m,w,g,b)&&!pointInTriangle(m,g,w,b)||W>I||(a.vectorToWorldFrame(i,l,f),a.pointToWorldFrame(o,i,m,v),this.reportIntersection(f,v,t,n,z))}}h.length=0},Ray.prototype[h.types.TRIMESH]=Ray.prototype.intersectTrimesh,Ray.prototype.reportIntersection=function(t,i,o,n,r){var a=this.from,l=this.to,h=a.distanceTo(i),c=this.result;if(!(this.skipBackfaces&&t.dot(this._direction)>0))switch(c.hitFaceIndex=void 0!==r?r:-1,this.mode){case Ray.ALL:this.hasHit=!0,c.set(a,l,t,i,o,n,h),c.hasHit=!0,this.callback(c);break;case Ray.CLOSEST:(h=0&&!(t[r].aabb.lowerBound.x<=n.aabb.lowerBound.x);r--)t[r+1]=t[r];t[r+1]=n}return t},SAPBroadphase.insertionSortY=function(t){for(var i=1,o=t.length;i=0&&!(t[r].aabb.lowerBound.y<=n.aabb.lowerBound.y);r--)t[r+1]=t[r];t[r+1]=n}return t},SAPBroadphase.insertionSortZ=function(t){for(var i=1,o=t.length;i=0&&!(t[r].aabb.lowerBound.z<=n.aabb.lowerBound.z);r--)t[r+1]=t[r];t[r+1]=n}return t},SAPBroadphase.prototype.collisionPairs=function(t,i,o){var n,r,a=this.axisList,l=a.length,h=this.axisIndex;for(this.dirty&&(this.sortList(),this.dirty=!1),n=0;n!==l;n++){var c=a[n];for(r=n+1;rm?f>g?0:2:m>g?1:2},SAPBroadphase.prototype.aabbQuery=function(t,i,o){o=o||[],this.dirty&&(this.sortList(),this.dirty=!1);var n=this.axisIndex,r="x";1===n&&(r="y"),2===n&&(r="z");for(var a=this.axisList,l=(i.lowerBound[r],i.upperBound[r],0);l.499&&(o=2*Math.atan2(a,c),n=Math.PI/2,r=0),p<-.499&&(o=-2*Math.atan2(a,c),n=-Math.PI/2,r=0),isNaN(o)){var u=a*a,d=l*l,y=h*h;o=Math.atan2(2*l*c-2*a*h,1-2*d-2*y),n=Math.asin(2*p),r=Math.atan2(2*a*c-2*l*h,1-2*u-2*y)}break;default:throw new Error("Euler order "+i+" not supported yet.")}t.y=o,t.z=n,t.x=r},Quaternion.prototype.setFromEuler=function(t,i,o,n){n=n||"XYZ";var r=Math.cos(t/2),a=Math.cos(i/2),l=Math.cos(o/2),h=Math.sin(t/2),c=Math.sin(i/2),p=Math.sin(o/2);return"XYZ"===n?(this.x=h*a*l+r*c*p,this.y=r*c*l-h*a*p,this.z=r*a*p+h*c*l,this.w=r*a*l-h*c*p):"YXZ"===n?(this.x=h*a*l+r*c*p,this.y=r*c*l-h*a*p,this.z=r*a*p-h*c*l,this.w=r*a*l+h*c*p):"ZXY"===n?(this.x=h*a*l-r*c*p,this.y=r*c*l+h*a*p,this.z=r*a*p+h*c*l,this.w=r*a*l-h*c*p):"ZYX"===n?(this.x=h*a*l-r*c*p,this.y=r*c*l+h*a*p,this.z=r*a*p-h*c*l,this.w=r*a*l+h*c*p):"YZX"===n?(this.x=h*a*l+r*c*p,this.y=r*c*l+h*a*p,this.z=r*a*p-h*c*l,this.w=r*a*l-h*c*p):"XZY"===n&&(this.x=h*a*l-r*c*p,this.y=r*c*l-h*a*p,this.z=r*a*p+h*c*l,this.w=r*a*l+h*c*p),this},Quaternion.prototype.clone=function(){return new Quaternion(this.x,this.y,this.z,this.w)}},{"./Vec3":30}],29:[function(t,i,o){var n=t("./Vec3"),r=t("./Quaternion");function Transform(t){t=t||{},this.position=new n,t.position&&this.position.copy(t.position),this.quaternion=new r,t.quaternion&&this.quaternion.copy(t.quaternion)}i.exports=Transform;var a=new r;Transform.pointToLocalFrame=function(t,i,o,r){r=r||new n;return o.vsub(t,r),i.conjugate(a),a.vmult(r,r),r},Transform.prototype.pointToLocal=function(t,i){return Transform.pointToLocalFrame(this.position,this.quaternion,t,i)},Transform.pointToWorldFrame=function(t,i,o,r){r=r||new n;return i.vmult(o,r),r.vadd(t,r),r},Transform.prototype.pointToWorld=function(t,i){return Transform.pointToWorldFrame(this.position,this.quaternion,t,i)},Transform.prototype.vectorToWorldFrame=function(t,i){i=i||new n;return this.quaternion.vmult(t,i),i},Transform.vectorToWorldFrame=function(t,i,o){return t.vmult(i,o),o},Transform.vectorToLocalFrame=function(t,i,o,r){r=r||new n;return i.w*=-1,i.vmult(o,r),i.w*=-1,r}},{"./Quaternion":28,"./Vec3":30}],30:[function(t,i,o){i.exports=Vec3;var n=t("./Mat3");function Vec3(t,i,o){this.x=t||0,this.y=i||0,this.z=o||0}Vec3.ZERO=new Vec3(0,0,0),Vec3.UNIT_X=new Vec3(1,0,0),Vec3.UNIT_Y=new Vec3(0,1,0),Vec3.UNIT_Z=new Vec3(0,0,1),Vec3.prototype.cross=function(t,i){var o=t.x,n=t.y,r=t.z,a=this.x,l=this.y,h=this.z;return(i=i||new Vec3).x=l*r-h*n,i.y=h*o-a*r,i.z=a*n-l*o,i},Vec3.prototype.set=function(t,i,o){return this.x=t,this.y=i,this.z=o,this},Vec3.prototype.setZero=function(){this.x=this.y=this.z=0},Vec3.prototype.vadd=function(t,i){if(!i)return new Vec3(this.x+t.x,this.y+t.y,this.z+t.z);i.x=t.x+this.x,i.y=t.y+this.y,i.z=t.z+this.z},Vec3.prototype.vsub=function(t,i){if(!i)return new Vec3(this.x-t.x,this.y-t.y,this.z-t.z);i.x=this.x-t.x,i.y=this.y-t.y,i.z=this.z-t.z},Vec3.prototype.crossmat=function(){return new n([0,-this.z,this.y,this.z,0,-this.x,-this.y,this.x,0])},Vec3.prototype.normalize=function(){var t=this.x,i=this.y,o=this.z,n=Math.sqrt(t*t+i*i+o*o);if(n>0){var r=1/n;this.x*=r,this.y*=r,this.z*=r}else this.x=0,this.y=0,this.z=0;return n},Vec3.prototype.unit=function(t){t=t||new Vec3;var i=this.x,o=this.y,n=this.z,r=Math.sqrt(i*i+o*o+n*n);return r>0?(r=1/r,t.x=i*r,t.y=o*r,t.z=n*r):(t.x=1,t.y=0,t.z=0),t},Vec3.prototype.norm=function(){var t=this.x,i=this.y,o=this.z;return Math.sqrt(t*t+i*i+o*o)},Vec3.prototype.length=Vec3.prototype.norm,Vec3.prototype.norm2=function(){return this.dot(this)},Vec3.prototype.lengthSquared=Vec3.prototype.norm2,Vec3.prototype.distanceTo=function(t){var i=this.x,o=this.y,n=this.z,r=t.x,a=t.y,l=t.z;return Math.sqrt((r-i)*(r-i)+(a-o)*(a-o)+(l-n)*(l-n))},Vec3.prototype.distanceSquared=function(t){var i=this.x,o=this.y,n=this.z,r=t.x,a=t.y,l=t.z;return(r-i)*(r-i)+(a-o)*(a-o)+(l-n)*(l-n)},Vec3.prototype.mult=function(t,i){i=i||new Vec3;var o=this.x,n=this.y,r=this.z;return i.x=t*o,i.y=t*n,i.z=t*r,i},Vec3.prototype.scale=Vec3.prototype.mult,Vec3.prototype.dot=function(t){return this.x*t.x+this.y*t.y+this.z*t.z},Vec3.prototype.isZero=function(){return 0===this.x&&0===this.y&&0===this.z},Vec3.prototype.negate=function(t){return(t=t||new Vec3).x=-this.x,t.y=-this.y,t.z=-this.z,t};var r=new Vec3,a=new Vec3;Vec3.prototype.tangents=function(t,i){var o=this.norm();if(o>0){var n=r,l=1/o;n.set(this.x*l,this.y*l,this.z*l);var h=a;Math.abs(n.x)<.9?(h.set(1,0,0),n.cross(h,t)):(h.set(0,1,0),n.cross(h,t)),n.cross(t,i)}else t.set(1,0,0),i.set(0,1,0)},Vec3.prototype.toString=function(){return this.x+","+this.y+","+this.z},Vec3.prototype.toArray=function(){return[this.x,this.y,this.z]},Vec3.prototype.copy=function(t){return this.x=t.x,this.y=t.y,this.z=t.z,this},Vec3.prototype.lerp=function(t,i,o){var n=this.x,r=this.y,a=this.z;o.x=n+(t.x-n)*i,o.y=r+(t.y-r)*i,o.z=a+(t.z-a)*i},Vec3.prototype.almostEquals=function(t,i){return void 0===i&&(i=1e-6),!(Math.abs(this.x-t.x)>i||Math.abs(this.y-t.y)>i||Math.abs(this.z-t.z)>i)},Vec3.prototype.almostZero=function(t){return void 0===t&&(t=1e-6),!(Math.abs(this.x)>t||Math.abs(this.y)>t||Math.abs(this.z)>t)};var l=new Vec3;Vec3.prototype.isAntiparallelTo=function(t,i){return this.negate(l),l.almostEquals(t,i)},Vec3.prototype.clone=function(){return new Vec3(this.x,this.y,this.z)}},{"./Mat3":27}],31:[function(t,i,o){i.exports=Body;var n=t("../utils/EventTarget"),r=(t("../shapes/Shape"),t("../math/Vec3")),a=t("../math/Mat3"),l=t("../math/Quaternion"),h=(t("../material/Material"),t("../collision/AABB")),c=t("../shapes/Box");function Body(t){t=t||{},n.apply(this),this.id=Body.idCounter++,this.layaID,this.isTrigger=!1,this.world=null,this.preStep=null,this.postStep=null,this.vlambda=new r,this.collisionFilterGroup="number"==typeof t.collisionFilterGroup?t.collisionFilterGroup:1,this.collisionFilterMask="number"==typeof t.collisionFilterMask?t.collisionFilterMask:1,this.collisionResponse=!0,this.position=new r,t.position&&this.position.copy(t.position),this.previousPosition=new r,this.initPosition=new r,this.velocity=new r,t.velocity&&this.velocity.copy(t.velocity),this.initVelocity=new r,this.force=new r;var i="number"==typeof t.mass?t.mass:0;this.mass=i,this.invMass=i>0?1/i:0,this.material=t.material||null,this.linearDamping="number"==typeof t.linearDamping?t.linearDamping:.01,this.type=i<=0?Body.STATIC:Body.DYNAMIC,typeof t.type==typeof Body.STATIC&&(this.type=t.type),this.allowSleep=void 0===t.allowSleep||t.allowSleep,this.sleepState=0,this.sleepSpeedLimit=void 0!==t.sleepSpeedLimit?t.sleepSpeedLimit:.1,this.sleepTimeLimit=void 0!==t.sleepTimeLimit?t.sleepTimeLimit:1,this.timeLastSleepy=0,this._wakeUpAfterNarrowphase=!1,this.torque=new r,this.quaternion=new l,t.quaternion&&this.quaternion.copy(t.quaternion),this.initQuaternion=new l,this.angularVelocity=new r,t.angularVelocity&&this.angularVelocity.copy(t.angularVelocity),this.initAngularVelocity=new r,this.interpolatedPosition=new r,this.interpolatedQuaternion=new l,this.shapes=[],this.shapeOffsets=[],this.shapeOrientations=[],this.inertia=new r,this.invInertia=new r,this.invInertiaWorld=new a,this.invMassSolve=0,this.invInertiaSolve=new r,this.invInertiaWorldSolve=new a,this.fixedRotation=void 0!==t.fixedRotation&&t.fixedRotation,this.angularDamping=void 0!==t.angularDamping?t.angularDamping:.01,this.aabb=new h,this.aabbNeedsUpdate=!0,this.wlambda=new r,t.shape&&this.addShape(t.shape),this.updateMassProperties()}Body.prototype=new n,Body.prototype.constructor=Body,Body.DYNAMIC=1,Body.STATIC=2,Body.KINEMATIC=4,Body.AWAKE=0,Body.SLEEPY=1,Body.SLEEPING=2,Body.idCounter=0,Body.prototype.wakeUp=function(){var t=this.sleepState;this.sleepState=0,t===Body.SLEEPING&&this.dispatchEvent({type:"wakeup"})},Body.prototype.sleep=function(){this.sleepState=Body.SLEEPING,this.velocity.set(0,0,0),this.angularVelocity.set(0,0,0)},Body.sleepyEvent={type:"sleepy"},Body.sleepEvent={type:"sleep"},Body.prototype.sleepTick=function(t){if(this.allowSleep){var i=this.sleepState,o=this.velocity.norm2()+this.angularVelocity.norm2(),n=Math.pow(this.sleepSpeedLimit,2);i===Body.AWAKE&&on?this.wakeUp():i===Body.SLEEPY&&t-this.timeLastSleepy>this.sleepTimeLimit&&(this.sleep(),this.dispatchEvent(Body.sleepEvent))}},Body.prototype.updateSolveMassProperties=function(){this.sleepState===Body.SLEEPING||this.type===Body.KINEMATIC?(this.invMassSolve=0,this.invInertiaSolve.setZero(),this.invInertiaWorldSolve.setZero()):(this.invMassSolve=this.invMass,this.invInertiaSolve.copy(this.invInertia),this.invInertiaWorldSolve.copy(this.invInertiaWorld))},Body.prototype.pointToLocalFrame=function(t,i){i=i||new r;return t.vsub(this.position,i),this.quaternion.conjugate().vmult(i,i),i},Body.prototype.vectorToLocalFrame=function(t,i){i=i||new r;return this.quaternion.conjugate().vmult(t,i),i},Body.prototype.pointToWorldFrame=function(t,i){i=i||new r;return this.quaternion.vmult(t,i),i.vadd(this.position,i),i},Body.prototype.vectorToWorldFrame=function(t,i){i=i||new r;return this.quaternion.vmult(t,i),i};var p=new r,u=new l;Body.prototype.addShape=function(t,i,o){var n=new r,a=new l;return i&&n.copy(i),o&&a.copy(o),this.shapes.push(t),this.shapeOffsets.push(n),this.shapeOrientations.push(a),this.updateMassProperties(),this.updateBoundingRadius(),this.aabbNeedsUpdate=!0,this},Body.prototype.updateBoundingRadius=function(){for(var t=this.shapes,i=this.shapeOffsets,o=t.length,n=0,r=0;r!==o;r++){var a=t[r];a.updateBoundingSphereRadius();var l=i[r].norm(),h=a.boundingSphereRadius;l+h>n&&(n=l+h)}this.boundingRadius=n};var d=new h;Body.prototype.computeAABB=function(){for(var t=this.shapes,i=this.shapeOffsets,o=this.shapeOrientations,n=t.length,r=p,a=u,l=this.quaternion,h=this.aabb,c=d,y=0;y!==n;y++){var v=t[y];o[y].mult(l,a),a.vmult(i[y],r),r.vadd(this.position,r),v.calculateWorldAABB(r,a,c.lowerBound,c.upperBound),0===y?h.copy(c):h.extend(c)}this.aabbNeedsUpdate=!1};var y=new a,v=new a;new a;Body.prototype.updateInertiaWorld=function(t){var i=this.invInertia;if(i.x!==i.y||i.y!==i.z||t){var o=y,n=v;o.setRotationFromQuaternion(this.quaternion),o.transpose(n),o.scale(i,o),o.mmult(n,this.invInertiaWorld)}else;};var f=new r,m=new r;Body.prototype.applyForce=function(t,i){if(this.type===Body.DYNAMIC){var o=f;i.vsub(this.position,o);var n=m;o.cross(t,n),this.force.vadd(t,this.force),this.torque.vadd(n,this.torque)}};var g=new r,w=new r;Body.prototype.applyLocalForce=function(t,i){if(this.type===Body.DYNAMIC){var o=g,n=w;this.vectorToWorldFrame(t,o),this.pointToWorldFrame(i,n),this.applyForce(o,n)}};var b=new r,x=new r,C=new r;Body.prototype.applyImpulse=function(t,i){if(this.type===Body.DYNAMIC){var o=b;i.vsub(this.position,o);var n=x;n.copy(t),n.mult(this.invMass,n),this.velocity.vadd(n,this.velocity);var r=C;o.cross(t,r),this.invInertiaWorld.vmult(r,r),this.angularVelocity.vadd(r,this.angularVelocity)}};var _=new r,S=new r;Body.prototype.applyLocalImpulse=function(t,i){if(this.type===Body.DYNAMIC){var o=_,n=S;this.vectorToWorldFrame(t,o),this.pointToWorldFrame(i,n),this.applyImpulse(o,n)}};var A=new r;Body.prototype.updateMassProperties=function(){var t=A;this.invMass=this.mass>0?1/this.mass:0;var i=this.inertia,o=this.fixedRotation;this.computeAABB(),t.set((this.aabb.upperBound.x-this.aabb.lowerBound.x)/2,(this.aabb.upperBound.y-this.aabb.lowerBound.y)/2,(this.aabb.upperBound.z-this.aabb.lowerBound.z)/2),c.calculateInertia(t,this.mass,i),this.invInertia.set(i.x>0&&!o?1/i.x:0,i.y>0&&!o?1/i.y:0,i.z>0&&!o?1/i.z:0),this.updateInertiaWorld(!0)},Body.prototype.getVelocityAtWorldPoint=function(t,i){var o=new r;return t.vsub(this.position,o),this.angularVelocity.cross(o,i),this.velocity.vadd(i,i),i}},{"../collision/AABB":3,"../material/Material":25,"../math/Mat3":27,"../math/Quaternion":28,"../math/Vec3":30,"../shapes/Box":37,"../shapes/Shape":43,"../utils/EventTarget":49}],32:[function(t,i,o){t("./Body");var n=t("../math/Vec3"),r=t("../math/Quaternion"),a=(t("../collision/RaycastResult"),t("../collision/Ray")),l=t("../objects/WheelInfo");function RaycastVehicle(t){this.chassisBody=t.chassisBody,this.wheelInfos=[],this.sliding=!1,this.world=null,this.indexRightAxis=void 0!==t.indexRightAxis?t.indexRightAxis:1,this.indexForwardAxis=void 0!==t.indexForwardAxis?t.indexForwardAxis:0,this.indexUpAxis=void 0!==t.indexUpAxis?t.indexUpAxis:2}i.exports=RaycastVehicle;new n,new n,new n;var h=new n,c=new n,p=new n;new a;RaycastVehicle.prototype.addWheel=function(t){var i=new l(t=t||{}),o=this.wheelInfos.length;return this.wheelInfos.push(i),o},RaycastVehicle.prototype.setSteeringValue=function(t,i){this.wheelInfos[i].steering=t};new n;RaycastVehicle.prototype.applyEngineForce=function(t,i){this.wheelInfos[i].engineForce=t},RaycastVehicle.prototype.setBrake=function(t,i){this.wheelInfos[i].brake=t},RaycastVehicle.prototype.addToWorld=function(t){this.constraints;t.add(this.chassisBody);var i=this;this.preStepCallback=function(){i.updateVehicle(t.dt)},t.addEventListener("preStep",this.preStepCallback),this.world=t},RaycastVehicle.prototype.getVehicleAxisWorld=function(t,i){i.set(0===t?1:0,1===t?1:0,2===t?1:0),this.chassisBody.vectorToWorldFrame(i,i)},RaycastVehicle.prototype.updateVehicle=function(t){for(var i=this.wheelInfos,o=i.length,r=this.chassisBody,a=0;av.maxSuspensionForce&&(p=v.maxSuspensionForce),v.raycastResult.hitNormalWorld.scale(p*t,h),v.raycastResult.hitPointWorld.vsub(r.position,c),r.applyImpulse(h,v.raycastResult.hitPointWorld)}this.updateFriction(t);var u=new n,d=new n,y=new n;for(a=0;a0?1:-1)*v.customSlidingRotationalSpeed*t),Math.abs(v.brake)>Math.abs(v.engineForce)&&(v.deltaRotation=0),v.rotation+=v.deltaRotation,v.deltaRotation*=.99}},RaycastVehicle.prototype.updateSuspension=function(t){for(var i=this.chassisBody.mass,o=this.wheelInfos,n=o.length,r=0;rm&&(t.suspensionLength=m,t.raycastResult.reset());var g=t.raycastResult.hitNormalWorld.dot(t.directionWorld),w=new n;r.getVelocityAtWorldPoint(t.raycastResult.hitPointWorld,w);var b=t.raycastResult.hitNormalWorld.dot(w);if(g>=-.1)t.suspensionRelativeVelocity=0,t.clippedInvContactDotSuspension=10;else{var x=-1/g;t.suspensionRelativeVelocity=b*x,t.clippedInvContactDotSuspension=x}}else t.suspensionLength=t.suspensionRestLength+0*t.maxSuspensionTravel,t.suspensionRelativeVelocity=0,t.directionWorld.scale(-1,t.raycastResult.hitNormalWorld),t.clippedInvContactDotSuspension=1;return a},RaycastVehicle.prototype.updateWheelTransformWorld=function(t){t.isInContact=!1;var i=this.chassisBody;i.pointToWorldFrame(t.chassisConnectionPointLocal,t.chassisConnectionPointWorld),i.vectorToWorldFrame(t.directionLocal,t.directionWorld),i.vectorToWorldFrame(t.axleLocal,t.axleWorld)},RaycastVehicle.prototype.updateWheelTransform=function(t){var i=h,o=c,n=p,a=this.wheelInfos[t];this.updateWheelTransformWorld(a),a.directionLocal.scale(-1,i),o.copy(a.axleLocal),i.cross(o,n),n.normalize(),o.normalize();var l=a.steering,u=new r;u.setFromAxisAngle(i,l);var d=new r;d.setFromAxisAngle(o,a.rotation);var y=a.worldTransform.quaternion;this.chassisBody.quaternion.mult(u,y),y.mult(d,y),y.normalize();var v=a.worldTransform.position;v.copy(a.directionWorld),v.scale(a.suspensionLength,v),v.vadd(a.chassisConnectionPointWorld,v)};var y=[new n(1,0,0),new n(0,1,0),new n(0,0,1)];RaycastVehicle.prototype.getWheelTransformWorld=function(t){return this.wheelInfos[t].worldTransform};var v=new n,f=[],m=[];RaycastVehicle.prototype.updateFriction=function(t){for(var i=v,o=this.wheelInfos,r=o.length,a=this.chassisBody,l=m,h=f,c=0;c_){this.sliding=!0,E.sliding=!0;x=C/Math.sqrt(B);E.skidInfo*=x}}}if(this.sliding)for(c=0;c1.1)return 0;var l=A,h=B,c=E;t.getVelocityAtWorldPoint(i,l),o.getVelocityAtWorldPoint(n,h),l.vsub(h,c);return-.2*r.dot(c)*(1/(t.invMass+o.invMass))}},{"../collision/Ray":9,"../collision/RaycastResult":10,"../math/Quaternion":28,"../math/Vec3":30,"../objects/WheelInfo":36,"./Body":31}],33:[function(t,i,o){var n=t("./Body"),r=t("../shapes/Sphere"),a=t("../shapes/Box"),l=t("../math/Vec3"),h=t("../constraints/HingeConstraint");function RigidVehicle(t){if(this.wheelBodies=[],this.coordinateSystem=void 0===t.coordinateSystem?new l(1,2,3):t.coordinateSystem.clone(),this.chassisBody=t.chassisBody,!this.chassisBody){var i=new a(new l(5,2,.5));this.chassisBody=new n(1,i)}this.constraints=[],this.wheelAxes=[],this.wheelForces=[]}i.exports=RigidVehicle,RigidVehicle.prototype.addWheel=function(t){var i=(t=t||{}).body;i||(i=new n(1,new r(1.2))),this.wheelBodies.push(i),this.wheelForces.push(0);new l;var o=void 0!==t.position?t.position.clone():new l,a=new l;this.chassisBody.pointToWorldFrame(o,a),i.position.set(a.x,a.y,a.z);var c=void 0!==t.axis?t.axis.clone():new l(0,1,0);this.wheelAxes.push(c);var p=new h(this.chassisBody,i,{pivotA:o,axisA:c,pivotB:l.ZERO,axisB:c,collideConnected:!1});return this.constraints.push(p),this.wheelBodies.length-1},RigidVehicle.prototype.setSteeringValue=function(t,i){var o=this.wheelAxes[i],n=Math.cos(t),r=Math.sin(t),a=o.x,l=o.y;this.constraints[i].axisA.set(n*a-r*l,r*a+n*l,0)},RigidVehicle.prototype.setMotorSpeed=function(t,i){var o=this.constraints[i];o.enableMotor(),o.motorTargetVelocity=t},RigidVehicle.prototype.disableMotor=function(t){this.constraints[t].disableMotor()};var c=new l;RigidVehicle.prototype.setWheelForce=function(t,i){this.wheelForces[i]=t},RigidVehicle.prototype.applyWheelForce=function(t,i){var o=this.wheelAxes[i],n=this.wheelBodies[i],r=n.torque;o.scale(t,c),n.vectorToWorldFrame(c,c),r.vadd(c,r)},RigidVehicle.prototype.addToWorld=function(t){for(var i=this.constraints,o=this.wheelBodies.concat([this.chassisBody]),n=0;nthis.particles.length&&this.neighbors.pop())};var r=new n;SPHSystem.prototype.getNeighbors=function(t,i){for(var o=this.particles.length,n=t.id,a=this.smoothingRadius*this.smoothingRadius,l=r,h=0;h!==o;h++){var c=this.particles[h];c.position.vsub(t.position,l),n!==c.id&&l.norm2()=-.1)this.suspensionRelativeVelocity=0,this.clippedInvContactDotSuspension=10;else{var r=-1/o;this.suspensionRelativeVelocity=n*r,this.clippedInvContactDotSuspension=r}}else i.suspensionLength=this.suspensionRestLength,this.suspensionRelativeVelocity=0,i.directionWorld.scale(-1,i.hitNormalWorld),this.clippedInvContactDotSuspension=1}},{"../collision/RaycastResult":10,"../math/Transform":29,"../math/Vec3":30,"../utils/Utils":53}],37:[function(t,i,o){i.exports=Box;var n=t("./Shape"),r=t("../math/Vec3"),a=t("./ConvexPolyhedron");function Box(t){n.call(this),this.type=n.types.BOX,this.halfExtents=t,this.convexPolyhedronRepresentation=null,this.updateConvexPolyhedronRepresentation(),this.updateBoundingSphereRadius()}Box.prototype=new n,Box.prototype.constructor=Box,Box.prototype.updateConvexPolyhedronRepresentation=function(){var t=this.halfExtents.x,i=this.halfExtents.y,o=this.halfExtents.z,n=r,l=[new n(-t,-i,-o),new n(t,-i,-o),new n(t,i,-o),new n(-t,i,-o),new n(-t,-i,o),new n(t,-i,o),new n(t,i,o),new n(-t,i,o)],h=(new n(0,0,1),new n(0,1,0),new n(1,0,0),new a(l,[[3,2,1,0],[4,5,6,7],[5,4,0,1],[2,3,7,6],[0,4,7,3],[1,2,6,5]]));this.convexPolyhedronRepresentation=h,h.material=this.material},Box.prototype.calculateLocalInertia=function(t,i){return i=i||new r,Box.calculateInertia(this.halfExtents,t,i),i},Box.calculateInertia=function(t,i,o){var n=t;o.x=1/12*i*(2*n.y*2*n.y+2*n.z*2*n.z),o.y=1/12*i*(2*n.x*2*n.x+2*n.z*2*n.z),o.z=1/12*i*(2*n.y*2*n.y+2*n.x*2*n.x)},Box.prototype.getSideNormals=function(t,i){var o=t,n=this.halfExtents;if(o[0].set(n.x,0,0),o[1].set(0,n.y,0),o[2].set(0,0,n.z),o[3].set(-n.x,0,0),o[4].set(0,-n.y,0),o[5].set(0,0,-n.z),void 0!==i)for(var r=0;r!==o.length;r++)i.vmult(o[r],o[r]);return o},Box.prototype.volume=function(){return 8*this.halfExtents.x*this.halfExtents.y*this.halfExtents.z},Box.prototype.updateBoundingSphereRadius=function(){this.boundingSphereRadius=this.halfExtents.norm()};var l=new r;new r;Box.prototype.forEachWorldCorner=function(t,i,o){for(var n=this.halfExtents,r=[[n.x,n.y,n.z],[-n.x,n.y,n.z],[-n.x,-n.y,n.z],[-n.x,-n.y,-n.z],[n.x,-n.y,-n.z],[n.x,n.y,-n.z],[-n.x,n.y,-n.z],[n.x,-n.y,n.z]],a=0;an.x&&(n.x=c),p>n.y&&(n.y=p),u>n.z&&(n.z=u),cv&&(v=m,y=f)}for(var g=[],w=o.faces[y],b=w.length,x=0;x=0&&this.clipFaceAgainstHull(l,t,i,g,h,c,u)};var u=new r,d=new r,y=new r,v=new r,f=new r,m=new r;ConvexPolyhedron.prototype.findSeparatingAxis=function(t,i,o,n,r,a,l,h){var c=u,p=d,g=y,w=v,b=f,x=m,C=Number.MAX_VALUE;if(this.uniqueAxes)for(S=0;S!==this.uniqueAxes.length;S++){if(o.vmult(this.uniqueAxes[S],c),!1===(E=this.testSepAxis(c,t,i,o,n,r)))return!1;E0&&a.negate(a),!0};var g=[],w=[];ConvexPolyhedron.prototype.testSepAxis=function(t,i,o,n,r,a){ConvexPolyhedron.project(this,t,o,n,g),ConvexPolyhedron.project(i,t,r,a,w);var l=g[0],h=g[1],c=w[0],p=w[1];if(li&&(i=r)}this.maxValue=i},Heightfield.prototype.setHeightValueAtIndex=function(t,i,o){this.data[t][i]=o,this.clearCachedConvexTrianglePillar(t,i,!1),t>0&&(this.clearCachedConvexTrianglePillar(t-1,i,!0),this.clearCachedConvexTrianglePillar(t-1,i,!1)),i>0&&(this.clearCachedConvexTrianglePillar(t,i-1,!0),this.clearCachedConvexTrianglePillar(t,i-1,!1)),i>0&&t>0&&this.clearCachedConvexTrianglePillar(t-1,i-1,!0)},Heightfield.prototype.getRectMinMax=function(t,i,o,n,r){r=r||[];for(var a=this.data,l=this.minValue,h=t;h<=o;h++)for(var c=i;c<=n;c++){var p=a[h][c];p>l&&(l=p)}r[0]=this.minValue,r[1]=l},Heightfield.prototype.getIndexOfPosition=function(t,i,o,n){var r=this.elementSize,a=this.data,l=Math.floor(t/r),h=Math.floor(i/r);return o[0]=l,o[1]=h,n&&(l<0&&(l=0),h<0&&(h=0),l>=a.length-1&&(l=a.length-1),h>=a[0].length-1&&(h=a[0].length-1)),!(l<0||h<0||l>=a.length-1||h>=a[0].length-1)},Heightfield.prototype.getHeightAt=function(t,i,o){var n=[];this.getIndexOfPosition(t,i,n,o);var r=[];return this.getRectMinMax(n[0],n[1]+1,n[0],n[1]+1,r),(r[0]+r[1])/2},Heightfield.prototype.getCacheConvexTrianglePillarKey=function(t,i,o){return t+"_"+i+"_"+(o?1:0)},Heightfield.prototype.getCachedConvexTrianglePillar=function(t,i,o){return this._cachedPillars[this.getCacheConvexTrianglePillarKey(t,i,o)]},Heightfield.prototype.setCachedConvexTrianglePillar=function(t,i,o,n,r){this._cachedPillars[this.getCacheConvexTrianglePillarKey(t,i,o)]={convex:n,offset:r}},Heightfield.prototype.clearCachedConvexTrianglePillar=function(t,i,o){delete this._cachedPillars[this.getCacheConvexTrianglePillarKey(t,i,o)]},Heightfield.prototype.getConvexTrianglePillar=function(t,i,o){var n=this.pillarConvex,l=this.pillarOffset;if(this.cacheEnabled){if(h=this.getCachedConvexTrianglePillar(t,i,o))return this.pillarConvex=h.convex,void(this.pillarOffset=h.offset);n=new r,l=new a,this.pillarConvex=n,this.pillarOffset=l}var h=this.data,c=this.elementSize,p=n.faces;n.vertices.length=6;for(var u=0;u<6;u++)n.vertices[u]||(n.vertices[u]=new a);p.length=5;for(u=0;u<5;u++)p[u]||(p[u]=[]);var d=n.vertices,y=(Math.min(h[t][i],h[t+1][i],h[t][i+1],h[t+1][i+1])-this.minValue)/2+this.minValue;o?(l.set((t+.75)*c,(i+.75)*c,y),d[0].set(.25*c,.25*c,h[t+1][i+1]-y),d[1].set(-.75*c,.25*c,h[t][i+1]-y),d[2].set(.25*c,-.75*c,h[t+1][i]-y),d[3].set(.25*c,.25*c,-y-1),d[4].set(-.75*c,.25*c,-y-1),d[5].set(.25*c,-.75*c,-y-1),p[0][0]=0,p[0][1]=1,p[0][2]=2,p[1][0]=5,p[1][1]=4,p[1][2]=3,p[2][0]=2,p[2][1]=5,p[2][2]=3,p[2][3]=0,p[3][0]=3,p[3][1]=4,p[3][2]=1,p[3][3]=0,p[4][0]=1,p[4][1]=4,p[4][2]=5,p[4][3]=2):(l.set((t+.25)*c,(i+.25)*c,y),d[0].set(-.25*c,-.25*c,h[t][i]-y),d[1].set(.75*c,-.25*c,h[t+1][i]-y),d[2].set(-.25*c,.75*c,h[t][i+1]-y),d[3].set(-.25*c,-.25*c,-y-1),d[4].set(.75*c,-.25*c,-y-1),d[5].set(-.25*c,.75*c,-y-1),p[0][0]=0,p[0][1]=1,p[0][2]=2,p[1][0]=5,p[1][1]=4,p[1][2]=3,p[2][0]=0,p[2][1]=2,p[2][2]=5,p[2][3]=3,p[3][0]=1,p[3][1]=0,p[3][2]=3,p[3][3]=4,p[4][0]=4,p[4][1]=5,p[4][2]=2,p[4][3]=1),n.computeNormals(),n.computeEdges(),n.updateBoundingSphereRadius(),this.setCachedConvexTrianglePillar(t,i,o,n,l)},Heightfield.prototype.calculateLocalInertia=function(t,i){return(i=i||new a).set(0,0,0),i},Heightfield.prototype.volume=function(){return Number.MAX_VALUE},Heightfield.prototype.calculateWorldAABB=function(t,i,o,n){o.set(-Number.MAX_VALUE,-Number.MAX_VALUE,-Number.MAX_VALUE),n.set(Number.MAX_VALUE,Number.MAX_VALUE,Number.MAX_VALUE)},Heightfield.prototype.updateBoundingSphereRadius=function(){var t=this.data,i=this.elementSize;this.boundingSphereRadius=new a(t.length*i,t[0].length*i,Math.max(Math.abs(this.maxValue),Math.abs(this.minValue))).norm()}},{"../math/Vec3":30,"../utils/Utils":53,"./ConvexPolyhedron":38,"./Shape":43}],41:[function(t,i,o){i.exports=Particle;var n=t("./Shape"),r=t("../math/Vec3");function Particle(){n.call(this),this.type=n.types.PARTICLE}Particle.prototype=new n,Particle.prototype.constructor=Particle,Particle.prototype.calculateLocalInertia=function(t,i){return(i=i||new r).set(0,0,0),i},Particle.prototype.volume=function(){return 0},Particle.prototype.updateBoundingSphereRadius=function(){this.boundingSphereRadius=0},Particle.prototype.calculateWorldAABB=function(t,i,o,n){o.copy(t),n.copy(t)}},{"../math/Vec3":30,"./Shape":43}],42:[function(t,i,o){i.exports=Plane;var n=t("./Shape"),r=t("../math/Vec3");function Plane(){n.call(this),this.type=n.types.PLANE,this.worldNormal=new r,this.worldNormalNeedsUpdate=!0,this.boundingSphereRadius=Number.MAX_VALUE}Plane.prototype=new n,Plane.prototype.constructor=Plane,Plane.prototype.computeWorldNormal=function(t){var i=this.worldNormal;i.set(0,0,1),t.vmult(i,i),this.worldNormalNeedsUpdate=!1},Plane.prototype.calculateLocalInertia=function(t,i){return i=i||new r},Plane.prototype.volume=function(){return Number.MAX_VALUE};var a=new r;Plane.prototype.calculateWorldAABB=function(t,i,o,n){a.set(0,0,1),i.vmult(a,a);var r=Number.MAX_VALUE;o.set(-r,-r,-r),n.set(r,r,r),1===a.x&&(n.x=t.x),1===a.y&&(n.y=t.y),1===a.z&&(n.z=t.z),-1===a.x&&(o.x=t.x),-1===a.y&&(o.y=t.y),-1===a.z&&(o.z=t.z)},Plane.prototype.updateBoundingSphereRadius=function(){this.boundingSphereRadius=Number.MAX_VALUE}},{"../math/Vec3":30,"./Shape":43}],43:[function(t,i,o){i.exports=n;var n=t("./Shape");t("../math/Vec3"),t("../math/Quaternion"),t("../material/Material");function n(){this.id=n.idCounter++,this.type=0,this.boundingSphereRadius=0,this.collisionResponse=!0,this.material=null}n.prototype.constructor=n,n.prototype.updateBoundingSphereRadius=function(){throw"computeBoundingSphereRadius() not implemented for shape type "+this.type},n.prototype.volume=function(){throw"volume() not implemented for shape type "+this.type},n.prototype.calculateLocalInertia=function(t,i){throw"calculateLocalInertia() not implemented for shape type "+this.type},n.idCounter=0,n.types={SPHERE:1,PLANE:2,BOX:4,COMPOUND:8,CONVEXPOLYHEDRON:16,HEIGHTFIELD:32,PARTICLE:64,CYLINDER:128,TRIMESH:256}},{"../material/Material":25,"../math/Quaternion":28,"../math/Vec3":30,"./Shape":43}],44:[function(t,i,o){i.exports=Sphere;var n=t("./Shape"),r=t("../math/Vec3");function Sphere(t){if(n.call(this),this.radius=void 0!==t?Number(t):1,this.type=n.types.SPHERE,this.radius<0)throw new Error("The sphere radius cannot be negative.");this.updateBoundingSphereRadius()}Sphere.prototype=new n,Sphere.prototype.constructor=Sphere,Sphere.prototype.calculateLocalInertia=function(t,i){i=i||new r;var o=2*t*this.radius*this.radius/5;return i.x=o,i.y=o,i.z=o,i},Sphere.prototype.volume=function(){return 4*Math.PI*this.radius/3},Sphere.prototype.updateBoundingSphereRadius=function(){this.boundingSphereRadius=this.radius},Sphere.prototype.calculateWorldAABB=function(t,i,o,n){for(var r=this.radius,a=["x","y","z"],l=0;lo.x&&(o.x=r.x),r.yo.y&&(o.y=r.y),r.zo.z&&(o.z=r.z)},Trimesh.prototype.updateAABB=function(){this.computeLocalAABB(this.aabb)},Trimesh.prototype.updateBoundingSphereRadius=function(){for(var t=0,i=this.vertices,o=new r,n=0,a=i.length/3;n!==a;n++){this.getVertex(n,o);var l=o.norm2();l>t&&(t=l)}this.boundingSphereRadius=Math.sqrt(t)};new r;var x=new a,C=new l;Trimesh.prototype.calculateWorldAABB=function(t,i,o,n){var r=x,a=C;r.position=t,r.quaternion=i,this.aabb.toWorldFrame(r,a),o.copy(a.lowerBound),n.copy(a.upperBound)},Trimesh.prototype.volume=function(){return 4*Math.PI*this.boundingSphereRadius/3},Trimesh.createTorus=function(t,i,o,n,r){t=t||1,i=i||.5,o=o||8,n=n||6,r=r||2*Math.PI;for(var a=[],l=[],h=0;h<=o;h++)for(var c=0;c<=n;c++){var p=c/n*r,u=h/o*Math.PI*2,d=(t+i*Math.cos(u))*Math.cos(p),y=(t+i*Math.cos(u))*Math.sin(p),v=i*Math.sin(u);a.push(d,y,v)}for(h=1;h<=o;h++)for(c=1;c<=n;c++){var f=(n+1)*h+c-1,m=(n+1)*(h-1)+c-1,g=(n+1)*(h-1)+c,w=(n+1)*h+c;l.push(f,m,w),l.push(m,g,w)}return new Trimesh(a,l)}},{"../collision/AABB":3,"../math/Quaternion":28,"../math/Transform":29,"../math/Vec3":30,"../utils/Octree":50,"./Shape":43}],46:[function(t,i,o){i.exports=GSSolver;t("../math/Vec3"),t("../math/Quaternion");var n=t("./Solver");function GSSolver(){n.call(this),this.iterations=10,this.tolerance=1e-7}GSSolver.prototype=new n;var r=[],a=[],l=[];GSSolver.prototype.solve=function(t,i){var o,n,h,c,p,u=0,d=this.iterations,y=this.tolerance*this.tolerance,v=this.equations,f=v.length,m=i.bodies,g=m.length,w=t;if(0!==f)for(var b=0;b!==g;b++)m[b].updateSolveMassProperties();var x=a,C=l,_=r;x.length=f,C.length=f,_.length=f;for(b=0;b!==f;b++){var S=v[b];_[b]=0,C[b]=S.computeB(w),x[b]=1/S.computeC()}if(0!==f){for(b=0;b!==g;b++){var A=(T=m[b]).vlambda,B=T.wlambda;A.set(0,0,0),B&&B.set(0,0,0)}for(u=0;u!==d;u++){c=0;for(var E=0;E!==f;E++){S=v[E];o=C[E],n=x[E],(p=_[E])+(h=n*(o-S.computeGWlambda()-S.eps*p))S.maxForce&&(h=S.maxForce-p),_[E]+=h,c+=h>0?h:-h,S.addToWlambda(h)}if(c*c=0;o--)i.children[o].data.length||i.children.splice(o,1);Array.prototype.push.apply(t,i.children)}}},{"../collision/AABB":3,"../math/Vec3":30}],51:[function(t,i,o){function Pool(){this.objects=[],this.type=Object}i.exports=Pool,Pool.prototype.release=function(){for(var t=arguments.length,i=0;i!==t;i++)this.objects.push(arguments[i])},Pool.prototype.get=function(){return 0===this.objects.length?this.constructObject():this.objects.pop()},Pool.prototype.constructObject=function(){throw new Error("constructObject() not implemented in this Pool subclass yet!")}},{}],52:[function(t,i,o){function TupleDictionary(){this.data={keys:[]}}i.exports=TupleDictionary,TupleDictionary.prototype.get=function(t,i){if(t>i){var o=i;i=t,t=o}return this.data[t+"-"+i]},TupleDictionary.prototype.set=function(t,i,o){if(t>i){var n=i;i=t,t=n}var r=t+"-"+i;this.get(t,i)||this.data.keys.push(r),this.data[r]=o},TupleDictionary.prototype.reset=function(){for(var t=this.data,i=t.keys;i.length>0;){delete t[i.pop()]}}},{}],53:[function(t,i,o){function Utils(){}i.exports=Utils,Utils.defaults=function(t,i){for(var o in t=t||{},i)o in t||(t[o]=i[o]);return t}},{}],54:[function(t,i,o){i.exports=Vec3Pool;var n=t("../math/Vec3"),r=t("./Pool");function Vec3Pool(){r.call(this),this.type=n}Vec3Pool.prototype=new r,Vec3Pool.prototype.constructObject=function(){return new n}},{"../math/Vec3":30,"./Pool":51}],55:[function(t,i,o){i.exports=Narrowphase;var n=t("../collision/AABB"),r=t("../shapes/Shape"),a=t("../collision/Ray"),l=t("../math/Vec3"),h=t("../math/Transform"),c=(t("../shapes/ConvexPolyhedron"),t("../math/Quaternion")),p=(t("../solver/Solver"),t("../utils/Vec3Pool")),u=t("../equations/ContactEquation"),d=t("../equations/FrictionEquation");function Narrowphase(t){this.contactPointPool=[],this.frictionEquationPool=[],this.result=[],this.frictionResult=[],this.v3pool=new p,this.world=t,this.currentContactMaterial=null,this.enableFrictionReduction=!1}Narrowphase.prototype.createContactEquation=function(t,i,o,n,r,a){var l;this.contactPointPool.length?((l=this.contactPointPool.pop()).bi=t,l.bj=i):l=new u(t,i),l.enabled=t.collisionResponse&&i.collisionResponse&&o.collisionResponse&&n.collisionResponse;var h=this.currentContactMaterial;l.restitution=h.restitution,l.setSpookParams(h.contactEquationStiffness,h.contactEquationRelaxation,this.world.dt);var c=o.material||t.material,p=n.material||i.material;return c&&p&&c.restitution>=0&&p.restitution>=0&&(l.restitution=c.restitution*p.restitution),l.si=r||o,l.sj=a||n,l},Narrowphase.prototype.createFrictionEquationsFromContact=function(t,i){var o=t.bi,n=t.bj,r=t.si,a=t.sj,l=this.world,h=this.currentContactMaterial,c=h.friction,p=r.material||o.material,u=a.material||n.material;if(p&&u&&p.friction>=0&&u.friction>=0&&(c=p.friction*u.friction),c>0){var y=c*l.gravity.length(),v=o.invMass+n.invMass;v>0&&(v=1/v);var f=this.frictionEquationPool,m=f.length?f.pop():new d(o,n,y*v),g=f.length?f.pop():new d(o,n,y*v);return m.bi=g.bi=o,m.bj=g.bj=n,m.minForce=g.minForce=-y*v,m.maxForce=g.maxForce=y*v,m.ri.copy(t.ri),m.rj.copy(t.rj),g.ri.copy(t.ri),g.rj.copy(t.rj),t.ni.tangents(m.t,g.t),m.setSpookParams(h.frictionEquationStiffness,h.frictionEquationRelaxation,l.dt),g.setSpookParams(h.frictionEquationStiffness,h.frictionEquationRelaxation,l.dt),m.enabled=g.enabled=t.enabled,i.push(m,g),!0}return!1};var y=new l,v=new l,f=new l;Narrowphase.prototype.createFrictionFromAverage=function(t){var i=this.result[this.result.length-1];if(this.createFrictionEquationsFromContact(i,this.frictionResult)&&1!==t){var o=this.frictionResult[this.frictionResult.length-2],n=this.frictionResult[this.frictionResult.length-1];y.setZero(),v.setZero(),f.setZero();for(var r=i.bi,a=(i.bj,0);a!==t;a++)(i=this.result[this.result.length-1-a]).bodyA!==r?(y.vadd(i.ni,y),v.vadd(i.ri,v),f.vadd(i.rj,f)):(y.vsub(i.ni,y),v.vadd(i.rj,v),f.vadd(i.ri,f));var l=1/t;v.scale(l,o.ri),f.scale(l,o.rj),n.ri.copy(o.ri),n.rj.copy(o.rj),y.normalize(),y.tangents(o.t,n.t)}};var m=new l,g=new l,w=new c,b=new c;Narrowphase.prototype.getContacts=function(t,i,o,n,r,a,l){this.contactPointPool=r,this.frictionEquationPool=l,this.result=n,this.frictionResult=a;for(var h=w,c=b,p=m,u=g,d=0,y=t.length;d!==y;d++){var v=t[d],f=i[d],x=!1;v.material&&f.material&&(x=!0);for(var C=0;C_.boundingSphereRadius+A.boundingSphereRadius)){_.material&&A.material&&(o.getContactMaterial(_.material,A.material)||null),x?(this.currentContactMaterial=o.defaultContactMaterial2,this.currentContactMaterial.materials[0]=v.material,this.currentContactMaterial.materials[1]=f.material,this.currentContactMaterial.friction=v.material.friction+f.material.friction,this.currentContactMaterial.restitution=v.material.restitution*f.material.restitution):this.currentContactMaterial=o.defaultContactMaterial2,this.currentContactMaterial=o.defaultContactMaterial2;var B=this[_.type|A.type];B&&(_.type0&&D<0)if(f.vsub(u,m),v.copy(y),v.normalize(),U=m.dot(v),v.scale(U,m),m.vadd(u,m),(Z=m.distanceTo(f))0&&!0===n||u<=0&&!1===n))return!1;null===n&&(n=u>0)}return!0}var H=new l,k=new l,G=new l,Q=new l,Y=[new l,new l,new l,new l,new l,new l],X=new l,Z=new l,K=new l,J=new l;Narrowphase.prototype[r.types.SPHERE|r.types.BOX]=Narrowphase.prototype.sphereBox=function(t,i,o,n,r,a,l,h){var c=this.v3pool,p=Y;o.vsub(n,H),i.getSideNormals(p,a);for(var u=t.radius,d=!1,y=Z,v=K,f=J,m=null,g=0,w=0,b=0,x=null,C=0,_=p.length;C!==_&&!1===d;C++){var S=k;S.copy(p[C]);var A=S.norm();S.normalize();var B=H.dot(S);if(B0){var E=G,T=Q;E.copy(p[(C+1)%3]),T.copy(p[(C+2)%3]);var R=E.norm(),P=T.norm();E.normalize(),T.normalize();var N=H.dot(E),O=H.dot(T);if(N-R&&O-P){var V=Math.abs(B-A-u);(null===x||V0){for(var R=[],P=0,N=C.length;P!==N;P++){var O=c.get();a.vmult(d[C[P]],O),n.vadd(O,O),R.push(O)}if(pointInPolygon(R,_,o)){w=!0;var V=this.createContactEquation(l,h,t,i);_.mult(-y,V.ri),_.negate(V.ni);var I=c.get();_.mult(-E,I);var M=c.get();_.mult(-y,M),o.vsub(n,V.rj),V.rj.vadd(M,V.rj),V.rj.vadd(I,V.rj),V.rj.vadd(n,V.rj),V.rj.vsub(h.position,V.rj),V.ri.vadd(o,V.ri),V.ri.vsub(l.position,V.ri),c.release(I),c.release(M),this.result.push(V),this.createFrictionEquationsFromContact(V,this.frictionResult);P=0;for(var F=R.length;P!==F;P++)c.release(R[P]);return}for(P=0;P!==C.length;P++){var z=c.get(),L=c.get();a.vmult(d[C[(P+1)%C.length]],z),a.vmult(d[C[(P+2)%C.length]],L),n.vadd(z,z),n.vadd(L,L);var q=tt;L.vsub(z,q);var W=et;q.unit(W);var j=c.get(),D=c.get();o.vsub(z,D);var U=D.dot(W);W.mult(U,j),j.vadd(z,j);var H=c.get();if(j.vsub(o,H),U>0&&U*Ut.boundingSphereRadius+i.boundingSphereRadius)&&t.findSeparatingAxis(i,o,r,n,a,y,u,d)){var v=[],f=yt;t.clipAgainstHull(o,r,i,n,a,y,-100,100,v);for(var m=0,g=0;g!==v.length;g++){var w=this.createContactEquation(l,h,t,i,c,p),b=w.ri,x=w.rj;y.negate(w.ni),v[g].normal.negate(f),f.mult(v[g].depth,f),v[g].point.vadd(f,b),x.copy(v[g].point),b.vsub(o,b),x.vsub(n,x),b.vadd(o,b),b.vsub(l.position,b),x.vadd(n,x),x.vsub(h.position,x),this.result.push(w),m++,this.enableFrictionReduction||this.createFrictionEquationsFromContact(w,this.frictionResult)}this.enableFrictionReduction&&m&&this.createFrictionFromAverage(m)}};var vt=new l,ft=new l,mt=new l;Narrowphase.prototype[r.types.PLANE|r.types.PARTICLE]=Narrowphase.prototype.planeParticle=function(t,i,o,n,r,a,l,h){var c=vt;c.set(0,0,1),l.quaternion.vmult(c,c);var p=ft;if(n.vsub(l.position,p),c.dot(p)<=0){var u=this.createContactEquation(h,l,i,t);u.ni.copy(c),u.ni.negate(u.ni),u.ri.set(0,0,0);var d=mt;c.mult(c.dot(n),d),n.vsub(d,d),u.rj.copy(d),this.result.push(u),this.createFrictionEquationsFromContact(u,this.frictionResult)}};var gt=new l;Narrowphase.prototype[r.types.PARTICLE|r.types.SPHERE]=Narrowphase.prototype.sphereParticle=function(t,i,o,n,r,a,l,h){var c=gt;if(c.set(0,0,1),n.vsub(o,c),c.norm2()<=t.radius*t.radius){var p=this.createContactEquation(h,l,i,t);c.normalize(),p.rj.copy(c),p.rj.mult(t.radius,p.rj),p.ni.copy(c),p.ni.negate(p.ni),p.ri.set(0,0,0),this.result.push(p),this.createFrictionEquationsFromContact(p,this.frictionResult)}};var wt=new c,bt=new l,xt=(new l,new l),Ct=new l,_t=new l;Narrowphase.prototype[r.types.PARTICLE|r.types.CONVEXPOLYHEDRON]=Narrowphase.prototype.convexParticle=function(t,i,o,n,r,a,l,h){var c=-1,p=xt,u=_t,d=null,y=bt;if(y.copy(n),y.vsub(o,y),r.conjugate(wt),wt.vmult(y,y),t.pointIsInside(y)){t.worldVerticesNeedsUpdate&&t.computeWorldVertices(o,r),t.worldFaceNormalsNeedsUpdate&&t.computeWorldFaceNormals(r);for(var v=0,f=t.faces.length;v!==f;v++){var m=[t.worldVertices[t.faces[v][0]]],g=t.worldFaceNormals[v];n.vsub(m[0],Ct);var w=-g.dot(Ct);(null===d||Math.abs(w)p.length||w>p[0].length)){m<0&&(m=0),g<0&&(g=0),w<0&&(w=0),b<0&&(b=0),m>=p.length&&(m=p.length-1),g>=p.length&&(g=p.length-1),b>=p[0].length&&(b=p[0].length-1),w>=p[0].length&&(w=p[0].length-1);var x=[];i.getRectMinMax(m,w,g,b,x);var C=x[0],_=x[1];if(!(f.z-d>_||f.z+dp.length||w>p[0].length)){f<0&&(f=0),m<0&&(m=0),g<0&&(g=0),w<0&&(w=0),f>=p.length&&(f=p.length-1),m>=p.length&&(m=p.length-1),w>=p[0].length&&(w=p[0].length-1),g>=p[0].length&&(g=p[0].length-1);var b=[];i.getRectMinMax(f,g,m,w,b);var x=b[0],C=b[1];if(!(v.z-u>C||v.z+u2)return}}}},{"../collision/AABB":3,"../collision/Ray":9,"../equations/ContactEquation":19,"../equations/FrictionEquation":21,"../math/Quaternion":28,"../math/Transform":29,"../math/Vec3":30,"../shapes/ConvexPolyhedron":38,"../shapes/Shape":43,"../solver/Solver":47,"../utils/Vec3Pool":54}],56:[function(t,i,o){i.exports=World;var n=t("../shapes/Shape"),r=t("../math/Vec3"),a=t("../math/Quaternion"),l=t("../solver/GSSolver"),h=(t("../utils/Vec3Pool"),t("../equations/ContactEquation"),t("../equations/FrictionEquation"),t("./Narrowphase")),c=t("../utils/EventTarget"),p=t("../collision/ArrayCollisionMatrix"),u=t("../material/Material"),d=t("../material/ContactMaterial"),y=t("../objects/Body"),v=t("../utils/TupleDictionary"),f=t("../collision/RaycastResult"),m=t("../collision/AABB"),g=t("../collision/Ray"),w=t("../collision/NaiveBroadphase");function World(){c.apply(this),this.dt=-1,this.allowSleep=!1,this.contacts=[],this.allContacts=[],this.frictionEquations=[],this.quatNormalizeSkip=0,this.quatNormalizeFast=!1,this.time=0,this.stepnumber=0,this.default_dt=1/60,this.nextId=0,this.gravity=new r,this.broadphase=new w,this.bodies=[],this.callBackBody=[],this.solver=new l,this.constraints=[],this.narrowphase=new h(this),this.collisionMatrix=new p,this.collisionMatrixPrevious=new p,this.materials=[],this.contactmaterials=[],this.contactMaterialTable=new v,this.defaultMaterial=new u("default"),this.defaultContactMaterial=new d(this.defaultMaterial,this.defaultMaterial,{friction:.3,restitution:0}),this.defaultContactMaterial2=new d(this.defaultMaterial,this.defaultMaterial,{friction:.3,restitution:0}),this.doProfiling=!1,this.profile={solve:0,makeContactConstraints:0,broadphase:0,integrate:0,narrowphase:0},this.subsystems=[],this.addBodyEvent={type:"addBody",body:null},this.removeBodyEvent={type:"removeBody",body:null}}World.prototype=new c;new m;var b=new g;if(World.prototype.getContactMaterial=function(t,i){return this.contactMaterialTable.get(t.id,i.id)},World.prototype.numObjects=function(){return this.bodies.length},World.prototype.collisionMatrixTick=function(){var t=this.collisionMatrixPrevious;this.collisionMatrixPrevious=this.collisionMatrix,this.collisionMatrix=t,this.collisionMatrix.reset()},World.prototype.add=World.prototype.addBody=function(t){-1===this.bodies.indexOf(t)&&(t.index=this.bodies.length,this.bodies.push(t),t.world=this,t.initPosition.copy(t.position),t.initVelocity.copy(t.velocity),t.timeLastSleepy=this.time,t instanceof y&&(t.initAngularVelocity.copy(t.angularVelocity),t.initQuaternion.copy(t.quaternion)),this.collisionMatrix.setNumObjects(this.bodies.length),this.addBodyEvent.body=t,this.dispatchEvent(this.addBodyEvent))},World.prototype.addConstraint=function(t){this.constraints.push(t)},World.prototype.removeConstraint=function(t){var i=this.constraints.indexOf(t);-1!==i&&this.constraints.splice(i,1)},World.prototype.rayTest=function(t,i,o){o instanceof f?this.raycastClosest(t,i,{skipBackfaces:!0},o):this.raycastAll(t,i,{skipBackfaces:!0},o)},World.prototype.raycastAll=function(t,i,o,n){return o.mode=g.ALL,o.from=t,o.to=i,o.callback=n,b.intersectWorld(this,o)},World.prototype.raycastAny=function(t,i,o,n){return o.mode=g.ANY,o.from=t,o.to=i,o.result=n,b.intersectWorld(this,o)},World.prototype.raycastClosest=function(t,i,o,n){return o.mode=g.CLOSEST,o.from=t,o.to=i,o.result=n,b.intersectWorld(this,o)},World.prototype.remove=function(t){t.world=null;var i=this.bodies.length-1,o=this.bodies,n=o.indexOf(t);if(-1!==n){o.splice(n,1);for(var r=0;r!==o.length;r++)o[r].index=r;this.collisionMatrix.setNumObjects(i),this.removeBodyEvent.body=t,this.dispatchEvent(this.removeBodyEvent)}},World.prototype.removeBody=World.prototype.remove,World.prototype.addMaterial=function(t){this.materials.push(t)},World.prototype.addContactMaterial=function(t){this.contactmaterials.push(t),this.contactMaterialTable.set(t.materials[0].id,t.materials[1].id,t)},"undefined"==typeof performance&&(performance={}),!performance.now){var x=Date.now();performance.timing&&performance.timing.navigationStart&&(x=performance.timing.navigationStart),performance.now=function(){return Date.now()-x}}var C=new r;World.prototype.step=function(t,i,o){if(o=o||10,0===(i=i||0))this.internalStep(t),this.time+=t;else{var n=Math.floor((this.time+i)/t)-Math.floor(this.time/t);n=Math.min(n,o);for(var r=performance.now(),a=0;a!==n&&(this.internalStep(t),!(performance.now()-r>1e3*t));a++);this.time+=i;for(var l=this.time%t/t,h=C,c=this.bodies,p=0;p!==c.length;p++){var u=c[p];u.type!==y.STATIC&&u.sleepState!==y.SLEEPING?(u.position.vsub(u.previousPosition,h),h.scale(l,h),u.position.vadd(h,u.interpolatedPosition)):(u.interpolatedPosition.copy(u.position),u.interpolatedQuaternion.copy(u.quaternion))}}};var _={type:"postStep"},S={type:"preStep"},A={type:"collide",body:null,contact:null},B=[],E=[],T=[],R=[],P=(new r,new r,new r,new r,new r,new r,new r,new r,new r,new a,new a),N=new a,O=new r;World.prototype.internalStep=function(t){this.dt=t;var i,o=this.contacts,r=this.allContacts,a=T,l=R,h=this.numObjects(),c=this.bodies,p=this.solver,u=this.gravity,d=this.doProfiling,v=this.profile,f=y.DYNAMIC,m=this.constraints,g=E,w=(u.norm(),u.x),b=u.y,x=u.z,C=0;for(d&&(i=performance.now()),C=0;C!==h;C++){if((G=c[C]).type&f){var V=G.force,I=G.mass;V.x+=I*w,V.y+=I*b,V.z+=I*x}}C=0;for(var M=this.subsystems.length;C!==M;C++)this.subsystems[C].update();d&&(i=performance.now()),a.length=0,l.length=0,this.broadphase.collisionPairs(this,a,l),d&&(v.broadphase=performance.now()-i);var F=m.length;for(C=0;C!==F;C++){if(!(Y=m[C]).collideConnected)for(var z=a.length-1;z>=0;z-=1)(Y.bodyA===a[z]&&Y.bodyB===l[z]||Y.bodyB===a[z]&&Y.bodyA===l[z])&&(a.splice(z,1),l.splice(z,1))}this.collisionMatrixTick(),d&&(i=performance.now());var L=B,q=r.length;for(C=0;C!==q;C++)L.push(r[C]);o.length=0,r.length=0;var W=this.frictionEquations.length;for(C=0;C!==W;C++)g.push(this.frictionEquations[C]);this.frictionEquations.length=0,this.narrowphase.getContacts(a,l,this,r,L,this.frictionEquations,g);for(var j=r.length,D=0;D!=j;D++){var U=r[D];U.bi.isTrigger||U.bj.isTrigger||o.push(U)}d&&(v.narrowphase=performance.now()-i),d&&(i=performance.now());for(C=0;C=0&&Q.material.friction>=0&&G.material.friction*Q.material.friction,G.material.restitution>=0&&Q.material.restitution>=0&&(Y.restitution=G.material.restitution*Q.material.restitution)),p.addEquation(Y),G.allowSleep&&G.type===y.DYNAMIC&&G.sleepState===y.SLEEPING&&Q.sleepState===y.AWAKE&&Q.type!==y.STATIC)Q.velocity.norm2()+Q.angularVelocity.norm2()>=2*Math.pow(Q.sleepSpeedLimit,2)&&(G._wakeUpAfterNarrowphase=!0);if(Q.allowSleep&&Q.type===y.DYNAMIC&&Q.sleepState===y.SLEEPING&&G.sleepState===y.AWAKE&&G.type!==y.STATIC)G.velocity.norm2()+G.angularVelocity.norm2()>=2*Math.pow(G.sleepSpeedLimit,2)&&(Q._wakeUpAfterNarrowphase=!0);this.collisionMatrix.set(G,Q,!0),this.collisionMatrixPrevious.get(G,Q)||(A.body=Q,A.contact=Y,G.dispatchEvent(A),A.body=G,Q.dispatchEvent(A))}for(d&&(v.makeContactConstraints=performance.now()-i,i=performance.now()),C=0;C!==h;C++){(G=c[C])._wakeUpAfterNarrowphase&&(G.wakeUp(),G._wakeUpAfterNarrowphase=!1)}F=m.length;for(C=0;C!==F;C++){var Y;(Y=m[C]).update();z=0;for(var X=Y.equations.length;z!==X;z++){var Z=Y.equations[z];p.addEquation(Z)}}p.solve(t,this),d&&(v.solve=performance.now()-i),p.removeAllEquations();var K=Math.pow;for(C=0;C!==h;C++){if((G=c[C]).type&f){var J=K(1-G.linearDamping,t),$=G.velocity;$.mult(J,$);var tt=G.angularVelocity;if(tt){var et=K(1-G.angularDamping,t);tt.mult(et,tt)}}}for(this.dispatchEvent(S),C=0;C!==h;C++){(G=c[C]).preStep&&G.preStep.call(G)}d&&(i=performance.now());var it=P,ot=N,st=this.stepnumber,nt=y.DYNAMIC|y.KINEMATIC,rt=st%(this.quatNormalizeSkip+1)==0,at=this.quatNormalizeFast,lt=.5*t;n.types.PLANE,n.types.CONVEXPOLYHEDRON;for(this.callBackBody.length=0,C=0;C!==h;C++){var ht=c[C],ct=ht.force,pt=ht.torque;if(ht.type&nt&&ht.sleepState!==y.SLEEPING){var ut=ht.velocity,dt=ht.angularVelocity,yt=ht.position,vt=ht.quaternion,ft=ht.invMass,mt=ht.invInertiaWorld;ut.x+=ct.x*ft*t,ut.y+=ct.y*ft*t,ut.z+=ct.z*ft*t,ht.angularVelocity&&(mt.vmult(pt,O),O.mult(t,O),O.vadd(dt,dt)),yt.x+=ut.x*t,yt.y+=ut.y*t,yt.z+=ut.z*t,ht.angularVelocity&&(it.set(dt.x,dt.y,dt.z,0),it.mult(vt,ot),vt.x+=lt*ot.x,vt.y+=lt*ot.y,vt.z+=lt*ot.z,vt.w+=lt*ot.w,rt&&(at?vt.normalizeFast():vt.normalize())),this.callBackBody.push(ht),ht.aabb&&(ht.aabbNeedsUpdate=!0),ht.updateInertiaWorld&&ht.updateInertiaWorld()}}for(this.clearForces(),this.broadphase.dirty=!0,d&&(v.integrate=performance.now()-i),this.time+=t,this.stepnumber+=1,this.dispatchEvent(_),C=0;C!==h;C++){var gt=(G=c[C]).postStep;gt&>.call(G)}if(this.allowSleep)for(C=0;C!==h;C++)c[C].sleepTick(this.time)},World.prototype.clearForces=function(){for(var t=this.bodies,i=t.length,o=0;o!==i;o++){var n=t[o];n.force,n.torque;n.force.set(0,0,0),n.torque.set(0,0,0)}}},{"../collision/AABB":3,"../collision/ArrayCollisionMatrix":4,"../collision/NaiveBroadphase":7,"../collision/Ray":9,"../collision/RaycastResult":10,"../equations/ContactEquation":19,"../equations/FrictionEquation":21,"../material/ContactMaterial":24,"../material/Material":25,"../math/Quaternion":28,"../math/Vec3":30,"../objects/Body":31,"../shapes/Shape":43,"../solver/GSSolver":46,"../utils/EventTarget":49,"../utils/TupleDictionary":52,"../utils/Vec3Pool":54,"./Narrowphase":55}]},{},[2])(2)})),function(t,i){"use strict";class o{constructor(){this._lastUpdateFrame=-2147483648,this._updateFrame=-2147483648,this._isTrigger=!1,this.contacts=[]}_setUpdateFrame(t){this._lastUpdateFrame=this._updateFrame,this._updateFrame=t}}class n{constructor(){this._idCounter=0,this.colliderA=null,this.colliderB=null,this.distance=0,this.normal=new i.Vector3,this.positionOnA=new i.Vector3,this.positionOnB=new i.Vector3,this._id=++this._idCounter}}class r{constructor(){this.succeeded=!1,this.collider=null,this.point=new i.Vector3,this.normal=new i.Vector3,this.hitFraction=0}}class a{constructor(){this._hitResultsPoolIndex=0,this._hitResultsPool=[],this._contactPonintsPoolIndex=0,this._contactPointsPool=[],this._collisionsPool=[],this._collisions={}}getHitResult(){var t=this._hitResultsPool[this._hitResultsPoolIndex++];return t||(t=new r,this._hitResultsPool.push(t)),t}recoverAllHitResultsPool(){this._hitResultsPoolIndex=0}getContactPoints(){var t=this._contactPointsPool[this._contactPonintsPoolIndex++];return t||(t=new n,this._contactPointsPool.push(t)),t}recoverAllContactPointsPool(){this._contactPonintsPoolIndex=0}getCollision(t,i){var n,r=t.id,a=i.id,l=this._collisions[r];return l&&(n=l[a]),n||(l||(l={},this._collisions[r]=l),(n=0===this._collisionsPool.length?new o:this._collisionsPool.pop())._colliderA=t,n._colliderB=i,l[a]=n),n}recoverCollision(t){var i=t._colliderA.id,o=t._colliderB.id;this._collisions[i][o]=null,this._collisionsPool.push(t)}garbageCollection(){for(var t in this._hitResultsPoolIndex=0,this._hitResultsPool.length=0,this._contactPonintsPoolIndex=0,this._contactPointsPool.length=0,this._collisionsPool.length=0,this._collisionsPool){var i=this._collisionsPool[t],o=!0;for(var n in i)i[n]?o=!1:delete i[n];o&&delete this._collisionsPool[t]}}}class l{constructor(){this._scale=new i.Vector3(1,1,1),this._centerMatrix=new i.Matrix4x4,this._attatched=!1,this._indexInCompound=-1,this._compoundParent=null,this._attatchedCollisionObject=null,this._referenceCount=0,this._localOffset=new i.Vector3(0,0,0),this._localRotation=new i.Quaternion(0,0,0,1),this.needsCustomCollisionCallback=!1}static __init__(){l._btScale=new CANNON.Vec3,l._btVector30=new CANNON.Vec3,l._btQuaternion0=new CANNON.Quaternion}static _createAffineTransformation(t,i,o){var n=i.x,r=i.y,a=i.z,l=i.w,h=n+n,c=r+r,p=a+a,u=n*h,d=n*c,y=n*p,v=r*c,f=r*p,m=a*p,g=l*h,w=l*c,b=l*p;o[0]=1-(v+m),o[1]=d+b,o[2]=y-w,o[3]=0,o[4]=d-b,o[5]=1-(u+m),o[6]=f+g,o[7]=0,o[8]=y+w,o[9]=f-g,o[10]=1-(u+v),o[11]=0,o[12]=t.x,o[13]=t.y,o[14]=t.z,o[15]=1}get type(){return this._type}get localOffset(){return this._localOffset}set localOffset(t){t.cloneTo(this._localOffset)}get localRotation(){return this._localRotation}set localRotation(t){this._localRotation=t,this._compoundParent&&this._compoundParent._updateChildTransform(this)}_setScale(t){}_addReference(){this._referenceCount++}_removeReference(){this._referenceCount--}updateLocalTransformations(){if(this._compoundParent){var t=l._tempVector30;i.Vector3.multiply(this.localOffset,this._scale,t),l._createAffineTransformation(t,this.localRotation,this._centerMatrix.elements)}else l._createAffineTransformation(this.localOffset,this.localRotation,this._centerMatrix.elements)}cloneTo(t){var i=t;this._localOffset.cloneTo(i.localOffset),this._localRotation.cloneTo(i.localRotation),i.localOffset=i.localOffset,i.localRotation=i.localRotation}clone(){return null}destroy(){this._btShape&&(this._btShape=null)}}l.SHAPEORIENTATION_UPX=0,l.SHAPEORIENTATION_UPY=1,l.SHAPEORIENTATION_UPZ=2,l.SHAPETYPES_BOX=0,l.SHAPETYPES_SPHERE=1,l.SHAPETYPES_CYLINDER=2,l.SHAPETYPES_CAPSULE=3,l.SHAPETYPES_CONVEXHULL=4,l.SHAPETYPES_COMPOUND=5,l.SHAPETYPES_STATICPLANE=6,l.SHAPETYPES_CONE=7,l._tempVector30=new i.Vector3;class h extends l{constructor(t=1,i=1,o=1){super(),this._sizeX=t,this._sizeY=i,this._sizeZ=o,this._type=l.SHAPETYPES_BOX;var n=new CANNON.Vec3(t/2,i/2,o/2);this._btShape=new CANNON.Box(n)}static __init__(){h._btSize=new CANNON.Vec3}get sizeX(){return this._sizeX}get sizeY(){return this._sizeY}get sizeZ(){return this._sizeZ}_setScale(t){this._scale.setValue(t.x,t.y,t.z),this._btShape.halfExtents.set(this.sizeX/2*t.x,this.sizeY/2*t.y,this.sizeZ/2*t.z),this._btShape.updateConvexPolyhedronRepresentation(),this._btShape.updateBoundingSphereRadius()}clone(){var t=new h(this._sizeX,this._sizeY,this._sizeZ);return this.cloneTo(t),t}}class c extends l{constructor(t=.5){super(),this._radius=t,this._type=l.SHAPETYPES_SPHERE,this._btShape=new CANNON.Sphere(t)}get radius(){return this._radius}_setScale(t){var i=Math.max(t.x,t.y,t.z);this._scale.setValue(i,i,i),this._btShape.radius=i*this.radius,this._btShape.updateBoundingSphereRadius()}clone(){var t=new c(this._radius);return this.cloneTo(t),t}}class p extends i.Component{constructor(t,o){super(),this._restitution=0,this._friction=.5,this._collisionGroup=i.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER,this._canCollideWith=i.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER,this._colliderShape=null,this._transformFlag=2147483647,this._controlBySimulation=!1,this._enableProcessCollisions=!0,this._inPhysicUpdateListIndex=-1,this.canScaleShape=!0,this._collisionGroup=t,this._canCollideWith=o,p._physicObjectsMap[this.id]=this}static __init__(){p._btVector30=new CANNON.Vec3(0,0,0),p._btQuaternion0=new CANNON.Quaternion(0,0,0,1)}static _creatShape(t){var i;switch(t.type){case"BoxColliderShape":var o=t.size;i=o?new h(o[0],o[1],o[2]):new h;break;case"SphereColliderShape":i=new c(t.radius);break;default:throw"unknown shape type."}if(t.center){var n=i.localOffset;n.fromArray(t.center),i.localOffset=n}return i}static physicQuaternionMultiply(t,i,o,n,r,a){var l=r.x,h=r.y,c=r.z,p=r.w,u=i*c-o*h,d=o*l-t*c,y=t*h-i*l,v=t*l+i*h+o*c;a.x=t*p+l*n+u,a.y=i*p+h*n+d,a.z=o*p+c*n+y,a.w=n*p-v}get restitution(){return this._restitution}set restitution(t){this._restitution=t,this._btColliderObject&&(this._btColliderObject.material.restitution=t)}get friction(){return this._friction}set friction(t){this._friction=t,this._btColliderObject&&(this._btColliderObject.material.friction=t)}get colliderShape(){return this._colliderShape}set colliderShape(t){var i=this._colliderShape;if(i&&(i._attatched=!1,i._attatchedCollisionObject=null),this._colliderShape=t,t){if(t._attatched)throw"PhysicsComponent: this shape has attatched to other entity.";if(t._attatched=!0,t._attatchedCollisionObject=this,this._btColliderObject){if(t.type!=l.SHAPETYPES_COMPOUND){this._btColliderObject.shapes.length=0,this._btColliderObject.shapeOffsets.length=0,this._btColliderObject.shapeOrientations.length=0;var o=t.localOffset,n=t._scale,r=new CANNON.Vec3(o.x*n.x,o.y*n.y,o.z*n.z);this._btColliderObject.addShape(this._colliderShape._btShape,r),this._btColliderObject.updateBoundingRadius()}else t.bindRigidBody(this);var a=this._simulation&&this._enabled;a&&i&&this._removeFromSimulation(),this._onShapeChange(t),a&&(this._derivePhysicsTransformation(!0),this._addToSimulation())}}else this._simulation&&this._enabled&&i&&this._removeFromSimulation()}get simulation(){return this._simulation}get collisionGroup(){return this._collisionGroup}set collisionGroup(t){this._collisionGroup!==t&&(this._collisionGroup=t,this._btColliderObject.collisionFilterGroup=t,this._simulation&&this._colliderShape&&this._enabled&&(this._removeFromSimulation(),this._addToSimulation()))}get canCollideWith(){return this._canCollideWith}set canCollideWith(t){this._canCollideWith!==t&&(this._canCollideWith=t,this._btColliderObject.collisionFilterMask=t,this._simulation&&this._colliderShape&&this._enabled&&(this._removeFromSimulation(),this._addToSimulation()))}_parseShape(t){if(1===t.length){var i=p._creatShape(t[0]);this.colliderShape=i}}_onScaleChange(t){this._colliderShape._setScale(t),this._btColliderObject.updateBoundingRadius()}_onEnable(){this._simulation=this.owner._scene._cannonPhysicsSimulation,this._colliderShape&&(this._derivePhysicsTransformation(!0),this._addToSimulation())}_onDisable(){this._colliderShape&&(this._removeFromSimulation(),-1!==this._inPhysicUpdateListIndex&&this._simulation._physicsUpdateList.remove(this)),this._simulation=null}_onDestroy(){delete p._physicObjectsMap[this.id],this._btColliderObject=null,this._colliderShape.destroy(),super._onDestroy(),this._btColliderObject=null,this._colliderShape=null,this._simulation=null,this.owner.transform.off(i.Event.TRANSFORM_CHANGED,this,this._onTransformChanged)}_isValid(){return this._simulation&&this._colliderShape&&this._enabled}_parse(t){null!=t.collisionGroup&&(this.collisionGroup=t.collisionGroup),null!=t.canCollideWith&&(this.canCollideWith=t.canCollideWith)}_setTransformFlag(t,i){i?this._transformFlag|=t:this._transformFlag&=~t}_getTransformFlag(t){return 0!=(this._transformFlag&t)}_addToSimulation(){}_removeFromSimulation(){}_derivePhysicsTransformation(t){var i=this._btColliderObject;this._innerDerivePhysicsTransformation(i,t)}_innerDerivePhysicsTransformation(t,o){var n=this.owner._transform;if(o||this._getTransformFlag(i.Transform3D.TRANSFORM_WORLDPOSITION)){var r=this._colliderShape.localOffset,a=n.position,l=p._btVector30;if(0!==r.x||0!==r.y||0!==r.z){var h=p._tempVector30,c=n.worldMatrix;i.Vector3.transformCoordinate(r,c,h),l.set(h.x,h.y,h.z)}else l.set(a.x,a.y,a.z);t.position.set(l.x,l.y,l.z),this._setTransformFlag(i.Transform3D.TRANSFORM_WORLDPOSITION,!1)}if(o||this._getTransformFlag(i.Transform3D.TRANSFORM_WORLDQUATERNION)){var u=this._colliderShape.localRotation,d=p._btQuaternion0,y=n.rotation;if(0!==u.x||0!==u.y||0!==u.z||1!==u.w){var v=p._tempQuaternion0;p.physicQuaternionMultiply(y.x,y.y,y.z,y.w,u,v),d.set(v.x,v.y,v.z,v.w)}else d.set(y.x,y.y,y.z,y.w);t.quaternion.set(d.x,d.y,d.z,d.w),this._setTransformFlag(i.Transform3D.TRANSFORM_WORLDQUATERNION,!1)}(o||this._getTransformFlag(i.Transform3D.TRANSFORM_WORLDSCALE))&&(this._onScaleChange(n.getWorldLossyScale()),this._setTransformFlag(i.Transform3D.TRANSFORM_WORLDSCALE,!1))}_updateTransformComponent(t){var o=this._colliderShape,n=o.localOffset,r=o.localRotation,a=this.owner._transform,l=a.position,h=a.rotation,c=t.position,u=t.quaternion,d=u.x,y=u.y,v=u.z,f=u.w;if(0!==r.x||0!==r.y||0!==r.z||1!==r.w){var m=p._tempQuaternion0;r.invert(m),p.physicQuaternionMultiply(d,y,v,f,m,h)}else h.x=d,h.y=y,h.z=v,h.w=f;if(a.rotation=h,0!==n.x||0!==n.y||0!==n.z){var g=p._tempVector30;g.x=n.x,g.y=n.y,g.z=n.z,i.Vector3.transformQuat(g,h,g),l.x=c.x-g.x,l.y=c.y-g.z,l.z=c.z-g.y}else l.x=c.x,l.y=c.y,l.z=c.z;a.position=l}_onShapeChange(t){}_onAdded(){this.enabled=this._enabled,this.restitution=this._restitution,this.friction=this._friction,this.owner.transform.on(i.Event.TRANSFORM_CHANGED,this,this._onTransformChanged)}_onTransformChanged(t){!p._addUpdateList&&this._controlBySimulation||(t&=i.Transform3D.TRANSFORM_WORLDPOSITION|i.Transform3D.TRANSFORM_WORLDQUATERNION|i.Transform3D.TRANSFORM_WORLDSCALE)&&(this._transformFlag|=t,this._isValid()&&-1===this._inPhysicUpdateListIndex&&this._simulation._physicsUpdateList.add(this))}_cloneTo(t){var i=t;i.restitution=this._restitution,i.friction=this._friction,i.collisionGroup=this._collisionGroup,i.canCollideWith=this._canCollideWith,i.canScaleShape=this.canScaleShape,this._colliderShape&&(i.colliderShape=this._colliderShape.clone())}}p.ACTIVATIONSTATE_ACTIVE_TAG=1,p.ACTIVATIONSTATE_ISLAND_SLEEPING=2,p.ACTIVATIONSTATE_WANTS_DEACTIVATION=3,p.ACTIVATIONSTATE_DISABLE_DEACTIVATION=4,p.ACTIVATIONSTATE_DISABLE_SIMULATION=5,p.COLLISIONFLAGS_STATIC_OBJECT=1,p.COLLISIONFLAGS_KINEMATIC_OBJECT=2,p.COLLISIONFLAGS_NO_CONTACT_RESPONSE=4,p.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK=8,p.COLLISIONFLAGS_CHARACTER_OBJECT=16,p.COLLISIONFLAGS_DISABLE_VISUALIZE_OBJECT=32,p.COLLISIONFLAGS_DISABLE_SPU_COLLISION_PROCESSING=64,p._tempVector30=new i.Vector3,p._tempQuaternion0=new i.Quaternion,p._tempQuaternion1=new i.Quaternion,p._tempMatrix4x40=new i.Matrix4x4,p._physicObjectsMap={},p._addUpdateList=!0;class u extends p{constructor(t,i){super(t,i),this._isTrigger=!1}get isTrigger(){return this._isTrigger}set isTrigger(t){if(this._isTrigger=t,this._btColliderObject)if(this._btColliderObject.isTrigger=t,t){var i=this._btColliderObject.type;this._btColliderObject.collisionResponse=!1,0==(i&CANNON.Body.STATIC)&&(this._btColliderObject.type|=CANNON.Body.STATIC)}else this._btColliderObject.collisionResponse=!0,0!=(i&CANNON.Body.STATIC)&&(this._btColliderObject.type^=CANNON.Body.STATIC)}_onAdded(){super._onAdded(),this.isTrigger=this._isTrigger}_cloneTo(t){super._cloneTo(t),t.isTrigger=this._isTrigger}}class d extends u{constructor(t=-1,i=-1){super(t,i),this._enableProcessCollisions=!1}_addToSimulation(){this._simulation._addPhysicsCollider(this)}_removeFromSimulation(){this._simulation._removePhysicsCollider(this)}_parse(t){null!=t.friction&&(this.friction=t.friction),null!=t.restitution&&(this.restitution=t.restitution),null!=t.isTrigger&&(this.isTrigger=t.isTrigger),super._parse(t),this._parseShape(t.shapes)}_onAdded(){this._btColliderObject=new CANNON.Body,this._btColliderObject.material=new CANNON.Material,this._btColliderObject.layaID=this._id,this._btColliderObject.type=CANNON.Body.STATIC,this._btColliderObject.collisionFilterGroup=this._collisionGroup,this._btColliderObject.collisionFilterMask=this._canCollideWith,super._onAdded()}}class y extends i.SingletonList{constructor(){super()}add(t){if(-1!==t._inPhysicUpdateListIndex)throw"PhysicsUpdateList:element has in PhysicsUpdateList.";this._add(t),t._inPhysicUpdateListIndex=this.length++}remove(t){var i=t._inPhysicUpdateListIndex;if(this.length--,i!==this.length){var o=this.elements[this.length];this.elements[i]=o,o._inPhysicUpdateListIndex=i}t._inPhysicUpdateListIndex=-1}}class v{constructor(t){this._gravity=new i.Vector3(0,-10,0),this._btClosestRayResultCallback=new CANNON.RaycastResult,this._btRayoption={},this._collisionsUtils=new a,this._previousFrameCollisions=[],this._currentFrameCollisions=[],this._physicsUpdateList=new y,this._updatedRigidbodies=0,this.maxSubSteps=1,this.fixedTimeStep=1/60,this.maxSubSteps=t.maxSubSteps,this.fixedTimeStep=t.fixedTimeStep,this._btDiscreteDynamicsWorld=new CANNON.World,this._btBroadphase=new CANNON.NaiveBroadphase,this._btDiscreteDynamicsWorld.broadphase=this._btBroadphase,this._btDiscreteDynamicsWorld.defaultContactMaterial.contactEquationRelaxation=t.contactEquationRelaxation,this._btDiscreteDynamicsWorld.defaultContactMaterial.contactEquationStiffness=t.contactEquationStiffness,this.gravity=this._gravity,v._cannonPhysicsSimulation=this}static __init__(){v._btTempVector30=new CANNON.Vec3(0,0,0),v._btTempVector31=new CANNON.Vec3(0,0,0)}static createConstraint(){}get gravity(){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";return this._gravity}set gravity(t){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";this._gravity=t,this._btDiscreteDynamicsWorld.gravity.set(t.x,t.y,t.z)}get solverIterations(){if(!this._btDiscreteDynamicsWorld||!this._btDiscreteDynamicsWorld.solver)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";return this._iterations}set solverIterations(t){if(!this._btDiscreteDynamicsWorld||!this._btDiscreteDynamicsWorld.solver)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";this._btDiscreteDynamicsWorld.solver.iterations=t,this._iterations=t}_simulate(t){this._updatedRigidbodies=0,this._btDiscreteDynamicsWorld&&(this._btDiscreteDynamicsWorld.callBackBody.length=0,this._btDiscreteDynamicsWorld.allContacts.length=0,this._btDiscreteDynamicsWorld.step(this.fixedTimeStep,t,this.maxSubSteps));for(var i=this._btDiscreteDynamicsWorld.callBackBody,o=0,n=i.length;o0&&(n^=CANNON.Body.KINEMATIC),o.allowSleep=!0,o.type=n,this._enableProcessCollisions=!0,this._updateMass(this._mass)),o.velocity.set(0,0,0),o.angularVelocity.set(0,0,0),i&&this._addToSimulation()}get linearDamping(){return this._linearDamping}set linearDamping(t){this._linearDamping=t,this._btColliderObject&&(this._btColliderObject.linearDamping=t)}get angularDamping(){return this._angularDamping}set angularDamping(t){this._angularDamping=t,this._btColliderObject&&(this._btColliderObject.angularDamping=t)}get totalForce(){if(this._btColliderObject){var t=this.btColliderObject.force;return this.totalForce.setValue(t.x,t.y,t.z),this._totalForce}return null}get linearVelocity(){if(this._btColliderObject){var t=this.btColliderObject.velocity;this._linearVelocity.setValue(t.x,t.y,t.z)}return this._linearVelocity}set linearVelocity(t){if(this._linearVelocity=t,this._btColliderObject){var i=this.btColliderObject.velocity;this.isSleeping&&this.wakeUp(),i.set(t.x,t.y,t.z),this.btColliderObject.velocity=i}}get angularVelocity(){if(this._btColliderObject){var t=this._btColliderObject.angularVelocity;this.angularVelocity.setValue(t.x,t.y,t.z)}return this._angularVelocity}set angularVelocity(t){if(this._angularVelocity=t,this._btColliderObject){var i=this.btColliderObject.angularVelocity;this.isSleeping&&this.wakeUp(),i.set(t.x,t.y,t.z),this.btColliderObject.angularVelocity=i}}get totalTorque(){if(this._btColliderObject){var t=this._btColliderObject.torque;return this._totalTorque.setValue(t.x,t.y,t.z),this._totalTorque}return null}get isSleeping(){return!!this._btColliderObject&&this._btColliderObject.sleepState!=CANNON.Body.AWAKE}get sleepLinearVelocity(){return this._btColliderObject.sleepSpeedLimit}set sleepLinearVelocity(t){this._btColliderObject.sleepSpeedLimit=t}get btColliderObject(){return this._btColliderObject}_updateMass(t){this._btColliderObject&&this._colliderShape&&(this._btColliderObject.mass=t,this._btColliderObject.updateMassProperties(),this._btColliderObject.updateSolveMassProperties())}_onScaleChange(t){super._onScaleChange(t),this._updateMass(this._isKinematic?0:this._mass)}_derivePhysicsTransformation(t){this._innerDerivePhysicsTransformation(this.btColliderObject,t)}_onAdded(){var t=new CANNON.Body;t.material=new CANNON.Material,t.layaID=this.id,t.collisionFilterGroup=this.collisionGroup,t.collisionFilterMask=this._canCollideWith,this._btColliderObject=t,super._onAdded(),this.mass=this._mass,this.linearDamping=this._linearDamping,this.angularDamping=this._angularDamping,this.isKinematic=this._isKinematic,this.isKinematic?this._btColliderObject.type=CANNON.Body.KINEMATIC:this._btColliderObject.type=CANNON.Body.DYNAMIC}_onShapeChange(t){super._onShapeChange(t),this._isKinematic?this._updateMass(0):this._updateMass(this._mass)}_parse(t){null!=t.friction&&(this.friction=t.friction),null!=t.restitution&&(this.restitution=t.restitution),null!=t.isTrigger&&(this.isTrigger=t.isTrigger),null!=t.mass&&(this.mass=t.mass),null!=t.isKinematic&&(this.isKinematic=t.isKinematic),null!=t.linearDamping&&(this.linearDamping=t.linearDamping),null!=t.angularDamping&&(this.angularDamping=t.angularDamping),super._parse(t),this._parseShape(t.shapes)}_onDestroy(){super._onDestroy(),this._gravity=null,this._totalTorque=null,this._linearVelocity=null,this._angularVelocity=null}_addToSimulation(){this._simulation._addRigidBody(this)}_removeFromSimulation(){this._simulation._removeRigidBody(this)}_cloneTo(t){super._cloneTo(t);var i=t;i.isKinematic=this._isKinematic,i.mass=this._mass,i.angularDamping=this._angularDamping,i.linearDamping=this._linearDamping,i.linearVelocity=this._linearVelocity,i.angularVelocity=this._angularVelocity}applyForce(t,i=null){if(null==this._btColliderObject)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";var o=f._btTempVector30;o.set(t.x,t.y,t.z);var n=f._btTempVector31;i?n.set(i.x,i.y,i.z):n.set(0,0,0),this.btColliderObject.applyLocalForce(o,n)}applyTorque(t){if(null==this._btColliderObject)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";var i=f._btTempVector30;i.set(t.x,t.y,t.z);var o=this.btColliderObject.torque;o.set(o.x+i.x,o.y+i.y,o.z+i.z),this.btColliderObject.torque=o}applyImpulse(t,i=null){if(null==this._btColliderObject)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";if(null==this._btColliderObject)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";var o=f._btTempVector30;o.set(t.x,t.y,t.z);var n=f._btTempVector31;i?n.set(i.x,i.y,i.z):n.set(0,0,0),this.btColliderObject.applyImpulse(o,n)}wakeUp(){this._btColliderObject&&this._btColliderObject.wakeUp()}clearForces(){var t=this._btColliderObject;if(null==t)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";t.velocity.set(0,0,0),t.velocity=t.velocity,t.angularVelocity.set(0,0,0),t.angularVelocity=t.angularVelocity}}f.TYPE_STATIC=0,f.TYPE_DYNAMIC=1,f.TYPE_KINEMATIC=2,f._BT_DISABLE_WORLD_GRAVITY=1,f._BT_ENABLE_GYROPSCOPIC_FORCE=2;class m extends l{constructor(){super(),this._childColliderShapes=[],this._type=l.SHAPETYPES_COMPOUND}static __init__(){}_clearChildShape(t){t._attatched=!1,t._compoundParent=null,t._indexInCompound=-1}_addReference(){this._referenceCount++}_removeReference(){this._referenceCount--}addChildShape(t,i=null){if(t._attatched)throw"CompoundColliderShape: this shape has attatched to other entity.";t._attatched=!0,t._compoundParent=this,t._indexInCompound=this._childColliderShapes.length,this._childColliderShapes.push(t),t.localOffset=i,this.physicColliderObject&&(m._tempCannonQue.set(0,0,0,1),m._tempCannonVec.set(i.x*this._scale.x,i.y*this._scale.y,i.z*this._scale.z),this.physicColliderObject._btColliderObject.addShape(t._btShape,m._tempCannonVec,CANNON.Vec3.ZERO))}removeChildShape(t){if(t._compoundParent===this){var i=t._indexInCompound;this._clearChildShape(t);var o=this._childColliderShapes[this._childColliderShapes.length-1];o._indexInCompound=i,this._childColliderShapes[i]=o,this._childColliderShapes.pop(),this.physicColliderObject&&this.bindRigidBody(this.physicColliderObject)}}bindRigidBody(t){this.physicColliderObject=t;var i,o=t._btColliderObject;o.shapes.length=0,o.shapeOffsets.length=0,o.shapeOrientations.length=0;for(var n=0,r=this._childColliderShapes.length;n!=r;n++){var a=this._childColliderShapes[n];o.shapes.push(a._btShape),i=a.localOffset,o.shapeOffsets.push(new CANNON.Vec3(i.x*this._scale.x,i.y*this._scale.y,i.z*this._scale.z)),o.shapeOrientations.push(m._tempCannonQue)}o.updateMassProperties(),o.updateBoundingRadius(),o.aabbNeedsUpdate=!0}_setScale(t){this._scale.setValue(t.x,t.y,t.z);for(var i=this.physicColliderObject._btColliderObject,o=this.getChildShapeCount(),n=i.shapeOffsets,r=0;r0){var e=1/t;this.x*=e,this.y*=e}}copy(t){return this.setTo(t.x,t.y)}}f.TEMP=new f,f.EMPTY=new f;class m{constructor(t=0,e=0,i=0,s=0){this.x=t,this.y=e,this.width=i,this.height=s}get right(){return this.x+this.width}get bottom(){return this.y+this.height}setTo(t,e,i,s){return this.x=t,this.y=e,this.width=i,this.height=s,this}reset(){return this.x=this.y=this.width=this.height=0,this}recover(){this!=m.TEMP&&this!=m.EMPTY?s.recover("Rectangle",this.reset()):console.log("recover Temp or Empty:",this)}static create(){return s.getItemByClass("Rectangle",m)}copyFrom(t){return this.x=t.x,this.y=t.y,this.width=t.width,this.height=t.height,this}contains(t,e){return!(this.width<=0||this.height<=0)&&(t>=this.x&&t=this.y&&ethis.x+this.width||t.x+t.widththis.y+this.height||t.y+t.heightt&&(this.width+=this.x-t,this.x=t),this.y>e&&(this.height+=this.y-e,this.y=e),this.widtho.x?r:o.x,n=n>o.y?n:o.y;return e.setTo(s,a,r-s,n-a)}isEmpty(){return this.width<=0||this.height<=0}}m.EMPTY=new m,m.TEMP=new m,m._temB=[],m._temA=[];class g{}g.ARRAY_BUFFER_TYPE_DATA=0,g.ARRAY_BUFFER_TYPE_CMD=1,g.ARRAY_BUFFER_REF_REFERENCE=0,g.ARRAY_BUFFER_REF_COPY=1,g.UPLOAD_SHADER_UNIFORM_TYPE_ID=0,g.UPLOAD_SHADER_UNIFORM_TYPE_DATA=1;var T,v,x,y,E,C=1,A=0;class R{static __init__(){var t=g.instance;R._depthFunc=t.LESS,R._blendEquation=t.FUNC_ADD,R._blendEquationRGB=t.FUNC_ADD,R._blendEquationAlpha=t.FUNC_ADD,C=t.ONE,A=t.ZERO,R._sFactorAlpha=t.ONE,R._dFactorAlpha=t.ZERO,R._activedTextureID=t.TEXTURE0;var e=t.getParameter(t.MAX_VERTEX_TEXTURE_IMAGE_UNITS);R._activeTextures=new Array(e),R._glTextureIDs=[t.TEXTURE0,t.TEXTURE1,t.TEXTURE2,t.TEXTURE3,t.TEXTURE4,t.TEXTURE5,t.TEXTURE6,t.TEXTURE7,t.TEXTURE8,t.TEXTURE9,t.TEXTURE10,t.TEXTURE11,t.TEXTURE12,t.TEXTURE13,t.TEXTURE14,t.TEXTURE15,t.TEXTURE16,t.TEXTURE17,t.TEXTURE18,t.TEXTURE19,t.TEXTURE20,t.TEXTURE21,t.TEXTURE22,t.TEXTURE23,t.TEXTURE24,t.TEXTURE25,t.TEXTURE26,t.TEXTURE27,t.TEXTURE28,t.TEXTURE29,t.TEXTURE30,t.TEXTURE31];var i=t.getParameter(t.MAX_VERTEX_UNIFORM_VECTORS),s=t.getParameter(t.MAX_FRAGMENT_UNIFORM_VECTORS);R._maxUniformFragmentVectors=Math.min(i,s)}static useProgram(t,e){return R._useProgram!==e&&(t.useProgram(e),R._useProgram=e,!0)}static setDepthTest(t,e){e!==R._depthTest&&(R._depthTest=e,e?t.enable(t.DEPTH_TEST):t.disable(t.DEPTH_TEST))}static setDepthMask(t,e){e!==R._depthMask&&(R._depthMask=e,t.depthMask(e))}static setDepthFunc(t,e){e!==R._depthFunc&&(R._depthFunc=e,t.depthFunc(e))}static setBlend(t,e){e!==R._blend&&(R._blend=e,e?t.enable(t.BLEND):t.disable(t.BLEND))}static setBlendEquation(t,e){e!==R._blendEquation&&(R._blendEquation=e,R._blendEquationRGB=R._blendEquationAlpha=null,t.blendEquation(e))}static setBlendEquationSeparate(t,e,i){e===R._blendEquationRGB&&i===R._blendEquationAlpha||(R._blendEquationRGB=e,R._blendEquationAlpha=i,R._blendEquation=null,t.blendEquationSeparate(e,i))}static setBlendFunc(t,e,i,s=!1){(s||e!==C||i!==A)&&(C=e,A=i,R._sFactorRGB=null,R._dFactorRGB=null,R._sFactorAlpha=null,R._dFactorAlpha=null,t.blendFunc(e,i))}static setBlendFuncSeperate(t,e,i,s,r){e===R._sFactorRGB&&i===R._dFactorRGB&&s===R._sFactorAlpha&&r===R._dFactorAlpha||(R._sFactorRGB=e,R._dFactorRGB=i,R._sFactorAlpha=s,R._dFactorAlpha=r,C=null,A=null,t.blendFuncSeparate(e,i,s,r))}static setCullFace(t,e){e!==R._cullFace&&(R._cullFace=e,e?t.enable(t.CULL_FACE):t.disable(t.CULL_FACE))}static setFrontFace(t,e){e!==R._frontFace&&(R._frontFace=e,t.frontFace(e))}static activeTexture(t,e){R._activedTextureID!==e&&(t.activeTexture(e),R._activedTextureID=e)}static bindTexture(t,e,i){R._activeTextures[R._activedTextureID-t.TEXTURE0]!==i&&(t.bindTexture(e,i),R._activeTextures[R._activedTextureID-t.TEXTURE0]=i)}static __init_native(){if(i.Render.supportWebGLPlusRendering){var t=R;t.activeTexture=t.activeTextureForNative,t.bindTexture=t.bindTextureForNative}}static useProgramForNative(t,e){return t.useProgram(e),!0}static setDepthTestForNative(t,e){e?t.enable(t.DEPTH_TEST):t.disable(t.DEPTH_TEST)}static setDepthMaskForNative(t,e){t.depthMask(e)}static setDepthFuncForNative(t,e){t.depthFunc(e)}static setBlendForNative(t,e){e?t.enable(t.BLEND):t.disable(t.BLEND)}static setBlendFuncForNative(t,e,i){t.blendFunc(e,i)}static setCullFaceForNative(t,e){e?t.enable(t.CULL_FACE):t.disable(t.CULL_FACE)}static setFrontFaceForNative(t,e){t.frontFace(e)}static activeTextureForNative(t,e){t.activeTexture(e)}static bindTextureForNative(t,e,i){t.bindTexture(e,i)}static bindVertexArrayForNative(t,e){t.bindVertexArray(e)}static getUniformMaxVector(){return R._maxUniformFragmentVectors}}R._activeTextures=new Array(1),R._useProgram=null,R._depthTest=!0,R._depthMask=!0,R._blend=!1,R._cullFace=!1,R.mainContext=null;class b{constructor(t=null,e=null,i=null,s=!1){this.once=!1,this._id=0,this.setTo(t,e,i,s)}setTo(t,e,i,s=!1){return this._id=b._gid++,this.caller=t,this.method=e,this.args=i,this.once=s,this}run(){if(null==this.method)return null;var t=this._id,e=this.method.apply(this.caller,this.args);return this._id===t&&this.once&&this.recover(),e}runWith(t){if(null==this.method)return null;var e=this._id;if(null==t)var i=this.method.apply(this.caller,this.args);else i=this.args||t.unshift?this.args?this.method.apply(this.caller,this.args.concat(t)):this.method.apply(this.caller,t):this.method.call(this.caller,t);return this._id===e&&this.once&&this.recover(),i}clear(){return this.caller=null,this.method=null,this.args=null,this}recover(){this._id>0&&(this._id=0,b._pool.push(this.clear()))}static create(t,e,i=null,s=!0){return b._pool.length?b._pool.pop().setTo(t,e,i,s):new b(t,e,i,s)}}b._pool=[],b._gid=1;class S{hasListener(t){return!!(this._events&&this._events[t])}event(t,e=null){if(!this._events||!this._events[t])return!1;var i=this._events[t];if(i.run)i.once&&delete this._events[t],null!=e?i.runWith(e):i.run();else{for(var s=0,r=i.length;s-1;e--)t[e]&&(t[e].recover(),t[e]=null)}isMouseEvent(t){return S.MOUSE_EVENTS[t]||!1}}S.MOUSE_EVENTS={rightmousedown:!0,rightmouseup:!0,rightclick:!0,mousedown:!0,mouseup:!0,mousemove:!0,mouseover:!0,mouseout:!0,click:!0,doubleclick:!0};class w extends b{constructor(t,e,i,s){super(t,e,i,s)}recover(){this._id>0&&(this._id=0,w._pool.push(this.clear()))}static create(t,e,i=null,s=!0){return w._pool.length?w._pool.pop().setTo(t,e,i,s):new w(t,e,i,s)}}w._pool=[];class M{constructor(t){this._url=M.formatURL(t),this._path=M.getPath(t)}get url(){return this._url}get path(){return this._path}static set basePath(t){M._basePath=i.Laya._getUrlPath(),M._basePath=M.formatURL(t)}static get basePath(){return M._basePath}static formatURL(t){if(!t)return"null path";if(t.indexOf(":")>0)return t;if(M.exportSceneToJson&&(t=M.getAdptedFilePath(t)),null!=M.customFormat&&(t=M.customFormat(t)),t.indexOf(":")>0)return t;var e=t.charAt(0);if("."===e)return M._formatRelativePath(M._basePath+t);if("~"===e)return M.rootPath+t.substring(1);if("d"===e){if(0===t.indexOf("data:image"))return t}else if("/"===e)return t;return M._basePath+t}static _formatRelativePath(t){for(var e=t.split("/"),i=0,s=e.length;i0?t.substr(0,e+1):""}static getFileName(t){var e=t.lastIndexOf("/");return e>0?t.substr(e+1):t}static getAdptedFilePath(t){if(!M.exportSceneToJson||!t)return t;var e,i,s;for(i=M._adpteTypeList.length,e=0;et&&this._resizeBuffer(this._allocated_=t),this._length=t}get length(){return this._length}_resizeBuffer(t){try{var e=new Uint8Array(t);null!=this._u8d_&&(this._u8d_.length<=t?e.set(this._u8d_):e.set(this._u8d_.subarray(0,t))),this._u8d_=e,this._d_=new DataView(e.buffer)}catch(e){throw"Invalid typed array length:"+t}}getString(){return this.readString()}readString(){return this._rUTF(this.getUint16())}getFloat32Array(t,e){return this.readFloat32Array(t,e)}readFloat32Array(t,e){var i=t+e;i=i>this._length?this._length:i;var s=new Float32Array(this._d_.buffer.slice(t,i));return this._pos_=i,s}getUint8Array(t,e){return this.readUint8Array(t,e)}readUint8Array(t,e){var i=t+e;i=i>this._length?this._length:i;var s=new Uint8Array(this._d_.buffer.slice(t,i));return this._pos_=i,s}getInt16Array(t,e){return this.readInt16Array(t,e)}readInt16Array(t,e){var i=t+e;i=i>this._length?this._length:i;var s=new Int16Array(this._d_.buffer.slice(t,i));return this._pos_=i,s}getFloat32(){return this.readFloat32()}readFloat32(){if(this._pos_+4>this._length)throw"getFloat32 error - Out of bounds";var t=this._d_.getFloat32(this._pos_,this._xd_);return this._pos_+=4,t}getFloat64(){return this.readFloat64()}readFloat64(){if(this._pos_+8>this._length)throw"getFloat64 error - Out of bounds";var t=this._d_.getFloat64(this._pos_,this._xd_);return this._pos_+=8,t}writeFloat32(t){this._ensureWrite(this._pos_+4),this._d_.setFloat32(this._pos_,t,this._xd_),this._pos_+=4}writeFloat64(t){this._ensureWrite(this._pos_+8),this._d_.setFloat64(this._pos_,t,this._xd_),this._pos_+=8}getInt32(){return this.readInt32()}readInt32(){if(this._pos_+4>this._length)throw"getInt32 error - Out of bounds";var t=this._d_.getInt32(this._pos_,this._xd_);return this._pos_+=4,t}getUint32(){return this.readUint32()}readUint32(){if(this._pos_+4>this._length)throw"getUint32 error - Out of bounds";var t=this._d_.getUint32(this._pos_,this._xd_);return this._pos_+=4,t}writeInt32(t){this._ensureWrite(this._pos_+4),this._d_.setInt32(this._pos_,t,this._xd_),this._pos_+=4}writeUint32(t){this._ensureWrite(this._pos_+4),this._d_.setUint32(this._pos_,t,this._xd_),this._pos_+=4}getInt16(){return this.readInt16()}readInt16(){if(this._pos_+2>this._length)throw"getInt16 error - Out of bounds";var t=this._d_.getInt16(this._pos_,this._xd_);return this._pos_+=2,t}getUint16(){return this.readUint16()}readUint16(){if(this._pos_+2>this._length)throw"getUint16 error - Out of bounds";var t=this._d_.getUint16(this._pos_,this._xd_);return this._pos_+=2,t}writeUint16(t){this._ensureWrite(this._pos_+2),this._d_.setUint16(this._pos_,t,this._xd_),this._pos_+=2}writeInt16(t){this._ensureWrite(this._pos_+2),this._d_.setInt16(this._pos_,t,this._xd_),this._pos_+=2}getUint8(){return this.readUint8()}readUint8(){if(this._pos_+1>this._length)throw"getUint8 error - Out of bounds";return this._u8d_[this._pos_++]}writeUint8(t){this._ensureWrite(this._pos_+1),this._d_.setUint8(this._pos_,t),this._pos_++}_getUInt8(t){return this._readUInt8(t)}_readUInt8(t){return this._d_.getUint8(t)}_getUint16(t){return this._readUint16(t)}_readUint16(t){return this._d_.getUint16(t,this._xd_)}_getMatrix(){return this._readMatrix()}_readMatrix(){return new p(this.getFloat32(),this.getFloat32(),this.getFloat32(),this.getFloat32(),this.getFloat32(),this.getFloat32())}_rUTF(t){var e,i,s=this._pos_+t,r=String.fromCharCode,a=this._u8d_,n=[],h=0;for(n.length=1e3;this._pos_=65536){const e=t-65536,i=55296|e>>10,s=56320|1023&e;n[h++]=r(i),n[h++]=r(s)}else n[h++]=r(t)}return n.length=h,n.join("")}getCustomString(t){return this.readCustomString(t)}readCustomString(t){for(var e,i="",s=0,r=String.fromCharCode,a=this._u8d_;t>0;)if((e=a[this._pos_])<128)i+=r(e),this._pos_++,t--;else for(s=e-128,this._pos_++,t-=s;s>0;)e=a[this._pos_++],i+=r(a[this._pos_++]<<8|e),s--;return i}get pos(){return this._pos_}set pos(t){this._pos_=t}get bytesAvailable(){return this._length-this._pos_}clear(){this._pos_=0,this.length=0}__getBuffer(){return this._d_.buffer}writeUTFBytes(t){for(var e=0,i=(t+="").length;e>6,128|63&s],this._pos_),this._pos_+=2;else if(s>=55296&&s<=56319){e++;const i=t.charCodeAt(e);if(!Number.isNaN(i)&&i>=56320&&i<=57343){const t=64+(1023&s),e=1023&i,r=240|t>>8&63,a=128|t>>2&63,n=128|(3&t)<<4|e>>6&15,h=128|63&e;this._ensureWrite(this._pos_+4),this._u8d_.set([r,a,n,h],this._pos_),this._pos_+=4}}else s<=65535?(this._ensureWrite(this._pos_+3),this._u8d_.set([224|s>>12,128|s>>6&63,128|63&s],this._pos_),this._pos_+=3):(this._ensureWrite(this._pos_+4),this._u8d_.set([240|s>>18,128|s>>12&63,128|s>>6&63,128|63&s],this._pos_),this._pos_+=4)}}writeUTFString(t){var e=this.pos;this.writeUint16(1),this.writeUTFBytes(t);var i=this.pos-e-2;this._d_.setUint16(e,i,this._xd_)}writeUTFString32(t){var e=this.pos;this.writeUint32(1),this.writeUTFBytes(t);var i=this.pos-e-4;this._d_.setUint32(e,i,this._xd_)}readUTFString(){return this.readUTFBytes(this.getUint16())}readUTFString32(){return this.readUTFBytes(this.getUint32())}getUTFString(){return this.readUTFString()}readUTFBytes(t=-1){if(0===t)return"";var e=this.bytesAvailable;if(t>e)throw"readUTFBytes error - Out of bounds";return t=t>0?t:e,this._rUTF(t)}getUTFBytes(t=-1){return this.readUTFBytes(t)}writeByte(t){this._ensureWrite(this._pos_+1),this._d_.setInt8(this._pos_,t),this._pos_+=1}readByte(){if(this._pos_+1>this._length)throw"readByte error - Out of bounds";return this._d_.getInt8(this._pos_++)}getByte(){return this.readByte()}_ensureWrite(t){this._length>-e-14,F._baseTable[256|t]=1024>>-e-14|32768,F._shiftTable[0|t]=-e-1,F._shiftTable[256|t]=-e-1):e<=15?(F._baseTable[0|t]=e+15<<10,F._baseTable[256|t]=e+15<<10|32768,F._shiftTable[0|t]=13,F._shiftTable[256|t]=13):e<128?(F._baseTable[0|t]=31744,F._baseTable[256|t]=64512,F._shiftTable[0|t]=24,F._shiftTable[256|t]=24):(F._baseTable[0|t]=31744,F._baseTable[256|t]=64512,F._shiftTable[0|t]=13,F._shiftTable[256|t]=13)}for(F._mantissaTable[0]=0,t=1;t<1024;++t){var i=t<<13;for(e=0;0==(8388608&i);)e-=8388608,i<<=1;i&=-8388609,e+=947912704,F._mantissaTable[t]=i|e}for(t=1024;t<2048;++t)F._mantissaTable[t]=939524096+(t-1024<<13);for(F._exponentTable[0]=0,t=1;t<31;++t)F._exponentTable[t]=t<<23;for(F._exponentTable[31]=1199570944,F._exponentTable[32]=2147483648,t=33;t<63;++t)F._exponentTable[t]=2147483648+(t-32<<23);for(F._exponentTable[63]=3347054592,F._offsetTable[0]=0,t=1;t<64;++t)F._offsetTable[t]=32===t?0:1024}static roundToFloat16Bits(t){F._floatView[0]=t;var e=F._uint32View[0],i=e>>23&511;return F._baseTable[i]+((8388607&e)>>F._shiftTable[i])}static convertToNumber(t){var e=t>>10;return F._uint32View[0]=F._mantissaTable[F._offsetTable[e]+(1023&t)]+F._exponentTable[e],F._floatView[0]}}F._buffer=new ArrayBuffer(4),F._floatView=new Float32Array(F._buffer),F._uint32View=new Uint32Array(F._buffer),F._baseTable=new Uint32Array(512),F._shiftTable=new Uint32Array(512),F._mantissaTable=new Uint32Array(2048),F._exponentTable=new Uint32Array(64),F._offsetTable=new Uint32Array(64);class O extends L{constructor(e=0,i=0,s=t.TextureFormat.R8G8B8A8,r=!0,a=!1){super(s,r);var n=g.instance;this._glTextureType=n.TEXTURE_2D,this._width=e,this._height=i,this._canRead=a,this._setWarpMode(n.TEXTURE_WRAP_S,this._wrapModeU),this._setWarpMode(n.TEXTURE_WRAP_T,this._wrapModeV),this._setFilterMode(this._filterMode),this._setAnisotropy(this._anisoLevel);var h=this._gpuCompressFormat();if(r){var o=Math.max(Math.ceil(Math.log2(e))+1,Math.ceil(Math.log2(i))+1);if(!h)for(var l=0;l>l,1),Math.max(i>>l,1));this._mipmapCount=o,this._setGPUMemory(e*i*4*(1+1/3))}else h||this._setPixels(null,0,e,i),this._mipmapCount=1,this._setGPUMemory(e*i*4)}static __init__(){var e=new Uint8Array(3);e[0]=128,e[1]=128,e[2]=128,O.grayTexture=new O(1,1,t.TextureFormat.R8G8B8,!1,!1),O.grayTexture.setPixels(e),O.grayTexture.lock=!0,e[0]=255,e[1]=255,e[2]=255,O.whiteTexture=new O(1,1,t.TextureFormat.R8G8B8,!1,!1),O.whiteTexture.setPixels(e),O.whiteTexture.lock=!0,e[0]=0,e[1]=0,e[2]=0,O.blackTexture=new O(1,1,t.TextureFormat.R8G8B8,!1,!1),O.blackTexture.setPixels(e),O.blackTexture.lock=!0,O.erroTextur=O.whiteTexture}static _parse(e,i=null,s=null){var r=s?new O(s[0],s[1],s[2],s[3],s[4]):new O(0,0);switch(i&&(r.wrapModeU=i.wrapModeU,r.wrapModeV=i.wrapModeV,r.filterMode=i.filterMode,r.anisoLevel=i.anisoLevel),r._format){case t.TextureFormat.R8G8B8:case t.TextureFormat.R8G8B8A8:r.loadImageSource(e);break;case t.TextureFormat.DXT1:case t.TextureFormat.DXT5:case t.TextureFormat.ETC1RGB:case t.TextureFormat.PVRTCRGB_2BPPV:case t.TextureFormat.PVRTCRGBA_2BPPV:case t.TextureFormat.PVRTCRGB_4BPPV:case t.TextureFormat.PVRTCRGBA_4BPPV:case t.TextureFormat.ETC2RGB:case t.TextureFormat.ETC2RGBA:case t.TextureFormat.ETC2SRGB:case t.TextureFormat.ASTC4x4:case t.TextureFormat.ASTC6x6:case t.TextureFormat.ASTC8x8:case t.TextureFormat.ASTC10x10:case t.TextureFormat.ASTC12x12:case t.TextureFormat.KTXTEXTURE:case t.TextureFormat.PVRTEXTURE:r.setCompressData(e);break;default:throw"Texture2D:unkonwn format."}return r}static _SimpleAnimatorTextureParse(e,i=null,s=null){var r,a,n=new D(e);switch(n.readUTFString()){case"LAYAANIMATORTEXTURE:0000":var h,o=n.readInt32(),l=n.readInt32();r=new Float32Array(o*o*4),a=new Float32Array(n.readArrayBuffer(4*l)),r.set(a,0),(h=new O(o,o,t.TextureFormat.R32G32B32A32,!1,!1)).setPixels(r,0),h.filterMode=t.FilterMode.Point;break;case"LAYACOMPRESSANIMATORTEXTURE:0000":o=n.readInt32(),l=n.readInt32();if(r=new Uint16Array(n.readArrayBuffer(2*l)),B.supportTextureFormat(t.TextureFormat.R16G16B16A16))(a=new Uint16Array(o*o*4)).set(r,0),(h=new O(o,o,t.TextureFormat.R16G16B16A16,!1,!1)).setPixels(a,0),h.filterMode=t.FilterMode.Point;else{console.log("The platform does not support 16-bit floating-point textures"),B.supportTextureFormat(t.TextureFormat.R32G32B32A32)||console.error("The platform does not support 32-bit floating-point textures"),a=new Float32Array(o*o*4);for(var _=0,u=r.length;_>2)*(s+3>>2)*8;case t.TextureFormat.DXT5:return(i+3>>2)*(s+3>>2)*16;case t.TextureFormat.PVRTCRGB_4BPPV:case t.TextureFormat.PVRTCRGBA_4BPPV:return Math.floor((Math.max(i,8)*Math.max(s,8)*4+7)/8);case t.TextureFormat.PVRTCRGB_2BPPV:case t.TextureFormat.PVRTCRGBA_2BPPV:return Math.floor((Math.max(i,16)*Math.max(s,8)*2+7)/8);default:return 0}}_pharseDDS(e){var i=new Int32Array(e,0,31);if(542327876!=i[0])throw"Invalid magic number in DDS header";if(!(4&i[20]))throw"Unsupported format, must contain a FourCC code";var s=i[21];switch(this._format){case t.TextureFormat.DXT1:if(827611204!==s)throw"the FourCC code is not same with texture format.";break;case t.TextureFormat.DXT5:if(894720068!==s)throw"the FourCC code is not same with texture format.";break;default:throw"unknown texture format."}var r=1;if(131072&i[2]){if(r=Math.max(1,i[7]),!this._mipmap)throw"the mipmap is not same with Texture2D."}else if(this._mipmap)throw"the mipmap is not same with Texture2D.";var a=i[4],n=i[3];this._width=a,this._height=n;var h=i[1]+4;this._upLoadCompressedTexImage2D(e,a,n,r,h,0)}_pharseKTX(e){var i=new Uint8Array(e,0,12);if(171!=i[0]||75!=i[1]||84!=i[2]||88!=i[3]||32!=i[4]||49!=i[5]||49!=i[6]||187!=i[7]||13!=i[8]||10!=i[9]||26!=i[10]||10!=i[11])throw"Invalid fileIdentifier in KTX header";var s=new Int32Array(i.buffer,i.length,13),r=s[4];if(this._format=-1,g.layaGPUInstance._compressedTextureASTC)switch(r){case g.layaGPUInstance._compressedTextureASTC.COMPRESSED_RGBA_ASTC_4x4_KHR:this._format=t.TextureFormat.ASTC4x4;break;case g.layaGPUInstance._compressedTextureASTC.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:this._format=t.TextureFormat.ASTC4x4SRGB;break;case g.layaGPUInstance._compressedTextureASTC.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:this._format=t.TextureFormat.ASTC6x6SRGB;break;case g.layaGPUInstance._compressedTextureASTC.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:this._format=t.TextureFormat.ASTC8x8SRGB;break;case g.layaGPUInstance._compressedTextureASTC.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:this._format=t.TextureFormat.ASTC10x10SRGB;break;case g.layaGPUInstance._compressedTextureASTC.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:this._format=t.TextureFormat.ASTC12x12SRGB;break;case g.layaGPUInstance._compressedTextureASTC.COMPRESSED_RGBA_ASTC_6x6_KHR:this._format=t.TextureFormat.ASTC6x6;break;case g.layaGPUInstance._compressedTextureASTC.COMPRESSED_RGBA_ASTC_8x8_KHR:this._format=t.TextureFormat.ASTC8x8;break;case g.layaGPUInstance._compressedTextureASTC.COMPRESSED_RGBA_ASTC_10x10_KHR:this._format=t.TextureFormat.ASTC10x10;break;case g.layaGPUInstance._compressedTextureASTC.COMPRESSED_RGBA_ASTC_12x12_KHR:this._format=t.TextureFormat.ASTC12x12}if(g.layaGPUInstance._compressedTextureEtc1)switch(r){case g.layaGPUInstance._compressedTextureEtc1.COMPRESSED_RGB_ETC1_WEBGL:this._format=t.TextureFormat.ETC1RGB}if(g.layaGPUInstance._compressedTextureETC)switch(r){case g.layaGPUInstance._compressedTextureETC.COMPRESSED_RGBA8_ETC2_EAC:this._format=t.TextureFormat.ETC2RGBA;break;case g.layaGPUInstance._compressedTextureETC.COMPRESSED_RGB8_ETC2:this._format=t.TextureFormat.ETC2RGB;break;case g.layaGPUInstance._compressedTextureETC.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:this._format=t.TextureFormat.ETC2RGB_Alpha8;break;case g.layaGPUInstance._compressedTextureETC.COMPRESSED_SRGB8_ETC2:this._format=t.TextureFormat.ETC2SRGB}if(-1==this._format)throw"unknown texture format.";var a=s[11],n=s[6],h=s[7];this._width=n,this._height=h;var o=64+s[12];this._upLoadKTXCompressedTexImage2D(e,n,h,a,o,4)}_pharsePVR(e){var i=new Int32Array(e,0,13);if(55727696!=i[0])throw"Invalid magic number in PVR header";switch(i[2]){case 0:this._format=t.TextureFormat.PVRTCRGB_2BPPV;break;case 2:this._format=t.TextureFormat.PVRTCRGB_4BPPV;break;case 1:this._format=t.TextureFormat.PVRTCRGBA_2BPPV;break;case 3:this._format=t.TextureFormat.PVRTCRGBA_4BPPV;break;default:throw"Texture2D:unknown PVR format."}var s=i[11],r=i[7],a=i[6];this._width=r,this._height=a;var n=i[12]+52;this._upLoadCompressedTexImage2D(e,r,a,s,n,0)}_upLoadCompressedTexImage2D(t,e,i,s,r,a){var n=g.instance,h=this._glTextureType;R.bindTexture(n,h,this._glTexture);for(var o=this._getGLFormat(),l=r,_=0;_>1,1),i=Math.max(i>>1,1),l+=u}var d=l;this._setGPUMemory(d),this._readyed=!0,this._activeResource()}_upLoadKTXCompressedTexImage2D(t,e,i,s,r,a){var n=g.instance,h=this._glTextureType;R.bindTexture(n,h,this._glTexture);for(var o=this._getGLFormat(),l=r,_=0;_>1,1),i=Math.max(i>>1,1),l+=u,l+=3-(u+3)%4}var d=l;this._setGPUMemory(d),this._readyed=!0,this._activeResource()}loadImageSource(e,s=!1){var r=g.instance,a=e.width,n=e.height;this._width=a,this._height=n,this._isPot(a)&&this._isPot(n)||(this._mipmap=!1),this._setWarpMode(r.TEXTURE_WRAP_S,this._wrapModeU),this._setWarpMode(r.TEXTURE_WRAP_T,this._wrapModeV),this._setFilterMode(this._filterMode),R.bindTexture(r,this._glTextureType,this._glTexture);var h=this._getGLFormat();i.Render.isConchApp?(e.setPremultiplyAlpha&&e.setPremultiplyAlpha(s),r.texImage2D(this._glTextureType,0,r.RGBA,r.RGBA,r.UNSIGNED_BYTE,e)):(s&&r.pixelStorei(r.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),this.format==t.TextureFormat.R5G6B5?r.texImage2D(this._glTextureType,0,r.RGB,r.RGB,r.UNSIGNED_SHORT_5_6_5,e):r.texImage2D(this._glTextureType,0,h,h,r.UNSIGNED_BYTE,e),s&&r.pixelStorei(r.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1)),this._mipmap?(r.generateMipmap(this._glTextureType),this._setGPUMemory(a*n*4*(1+1/3))):this._setGPUMemory(a*n*4),this._canRead&&(i.Render.isConchApp?this._pixels=new Uint8Array(e._nativeObj.getImageData(0,0,a,n)):(i.Browser.canvas.size(a,n),i.Browser.canvas.clear(),i.Browser.context.drawImage(e,0,0,a,n),this._pixels=new Uint8Array(i.Browser.context.getImageData(0,0,a,n).data.buffer))),this._readyed=!0,this._activeResource()}setPixels(t,e=0){if(this._gpuCompressFormat())throw"Texture2D:the format is GPU compression format.";if(!t)throw"Texture2D:pixels can't be null.";var i=Math.max(this._width>>e,1),s=Math.max(this._height>>e,1),r=i*s*this._getFormatByteCount();if(t.length=1e4&&console.error("getRT error! w too big"),new G(e,i,t.RenderTextureFormat.R8G8B8A8,-1)}static releaseRT(t){t.destroy()}}k.dict={};class W{static _init_(t){W.fns=[W.BlendNormal,W.BlendAdd,W.BlendMultiply,W.BlendScreen,W.BlendOverlay,W.BlendLight,W.BlendMask,W.BlendDestinationOut,W.BlendAddOld],W.targetFns=[W.BlendNormalTarget,W.BlendAddTarget,W.BlendMultiplyTarget,W.BlendScreenTarget,W.BlendOverlayTarget,W.BlendLightTarget,W.BlendMask,W.BlendDestinationOut,W.BlendAddTargetOld]}static BlendNormal(t){R.setBlendFunc(t,t.ONE,t.ONE_MINUS_SRC_ALPHA,!0)}static BlendAddOld(t){R.setBlendFunc(t,t.ONE,t.DST_ALPHA,!0)}static BlendAdd(t){R.setBlendFunc(t,t.ONE,t.ONE,!0)}static BlendMultiply(t){R.setBlendFunc(t,t.DST_COLOR,t.ONE_MINUS_SRC_ALPHA,!0)}static BlendScreen(t){R.setBlendFunc(t,t.ONE,t.ONE,!0)}static BlendOverlay(t){R.setBlendFunc(t,t.ONE,t.ONE_MINUS_SRC_COLOR,!0)}static BlendLight(t){R.setBlendFunc(t,t.ONE,t.ONE,!0)}static BlendNormalTarget(t){R.setBlendFunc(t,t.ONE,t.ONE_MINUS_SRC_ALPHA,!0)}static BlendAddTargetOld(t){R.setBlendFunc(t,t.ONE,t.DST_ALPHA,!0)}static BlendAddTarget(t){R.setBlendFunc(t,t.ONE,t.ONE,!0)}static BlendMultiplyTarget(t){R.setBlendFunc(t,t.DST_COLOR,t.ONE_MINUS_SRC_ALPHA,!0)}static BlendScreenTarget(t){R.setBlendFunc(t,t.ONE,t.ONE,!0)}static BlendOverlayTarget(t){R.setBlendFunc(t,t.ONE,t.ONE_MINUS_SRC_COLOR,!0)}static BlendLightTarget(t){R.setBlendFunc(t,t.ONE,t.ONE,!0)}static BlendMask(t){R.setBlendFunc(t,t.ZERO,t.SRC_ALPHA,!0)}static BlendDestinationOut(t){R.setBlendFunc(t,t.ZERO,t.ZERO,!0)}}W.activeBlendFunction=null,W.NAMES=["normal","add","multiply","screen","overlay","light","mask","destination-out","add_old"],W.TOINT={normal:0,add:1,multiply:2,screen:3,overlay:4,light:5,mask:6,"destination-out":7,lighter:1,lighter_old:8,add_old:8},W.NORMAL="normal",W.MASK="mask",W.LIGHTER="lighter";class Y{constructor(t,e,i){this._value=0,this._name2int=t,this._int2name=e,this._int2nameMap=i}add(t){return this._value|="string"==typeof t?this._name2int[t]:t,this._value}addInt(t){return this._value|=t,this._value}remove(t){return this._value&="string"==typeof t?~this._name2int[t]:~t,this._value}isDefine(t){return(this._value&t)===t}getValue(){return this._value}setValue(t){this._value=t}toNameDic(){var t=this._int2nameMap[this._value];return t||Y._toText(this._value,this._int2name,this._int2nameMap)}static _reg(t,e,i,s){i[t]=e,s[e]=t}static _toText(t,e,i){var s=i[t];if(s)return s;for(var r={},a=1,n=0;n<32&&!((a=1<t);n++)if(t&a){var h=e[a];h&&(r[h]="")}return i[t]=r,r}static _toInt(t,e){for(var i=t.split("."),s=0,r=0,a=i.length;r0&&(e.name=e.name.substr(0,e.name.length-3),e.isArray=!0,e.location=a.getUniformLocation(this._program,e.name)),this._params.push(e)}for(s=0,r=this._params.length;s=0;n-=2)(r=this._paramsMap[t[n]])&&null!=(s=t[n+1])&&(i&&i[r.name]&&i[r.name].bind(),a+=r.fun.call(this,r,s));X.shaderCall+=a}getParams(){return this._params}setAttributesLocation(t){this._attribInfo=t}}z._count=0,z._preCompileShader={},z.SHADERNAME2ID=2e-4,z.nameKey=new H,z.sharders=new Array(32);class K extends z{constructor(t,e,i=null,s=null,r=null){super(t,e,i,s,r),this._params2dQuick2=null,this._shaderValueWidth=0,this._shaderValueHeight=0}_disposeResource(){super._disposeResource(),this._params2dQuick2=null}upload2dQuick2(t){this.upload(t,this._params2dQuick2||this._make2dQuick2())}_make2dQuick2(){if(!this._params2dQuick2){this._params2dQuick2=[];for(var t,e=this._params,i=0,s=e.length;i0&&!this._inClassCache&&(this._inClassCache=j._cache[this._cacheID]=[],this._inClassCache._length=0),this.clear()}static _initone(t,e){j._typeClass[t]=e,j._cache[t]=[],j._cache[t]._length=0}static __init__(){}setValue(t){}_ShaderWithCompile(){return z.withCompile2D(0,this.mainID,this.defines.toNameDic(),this.mainID|this.defines._value,K.create,this._attribLocation)}upload(){var t=U;U.worldMatrix4===U.TEMPMAT4_ARRAY||this.defines.addInt(V.WORLDMAT),this.mmat=t.worldMatrix4,U.matWVP&&(this.defines.addInt(V.MVP3D),this.u_MvpMatrix=U.matWVP.elements);var e=z.sharders[this.mainID|this.defines._value]||this._ShaderWithCompile();e._shaderValueWidth!==t.width||e._shaderValueHeight!==t.height?(this.size[0]=t.width,this.size[1]=t.height,e._shaderValueWidth=t.width,e._shaderValueHeight=t.height,e.upload(this,null)):e.upload(this,e._params2dQuick2||e._make2dQuick2())}setFilters(t){if(this.filters=t,t)for(var e,i=t.length,s=0;s-1&&t[e]._zOrder>i;)t[e+1]=t[e];t[e+1]=s,r++}return!0}static transPointList(t,e,i){var s,r=t.length;for(s=0;s1?e[1].toLowerCase():null}static getFilecompatibleExtension(t){var e=t.split("."),i=e.length;return e.length>2?e[i-2]+"."+e[i-1]:null}static getTransformRelativeToWindow(t,e,i){var s=$.gStage,r=$.getGlobalPosAndScale(t),a=s._canvasTransform.clone(),n=a.tx,h=a.ty;a.rotate(-Math.PI/180*s.canvasDegree),a.scale(s.clientScaleX,s.clientScaleY);var o,l,_,u,c=s.canvasDegree%180!=0;return c?(o=i+r.y,l=e+r.x,o*=a.d,l*=a.a,90==s.canvasDegree?(o=n-o,l+=h):(o+=n,l=h-l)):(o=e+r.x,l=i+r.y,o*=a.a,l*=a.d,o+=n,l+=h),l+=s._safariOffsetY,c?(_=a.d*r.height,u=a.a*r.width):(_=a.a*r.width,u=a.d*r.height),{x:o,y:l,scaleX:_,scaleY:u}}static fitDOMElementInArea(t,e,i,s,r,a){t._fitLayaAirInitialized||(t._fitLayaAirInitialized=!0,t.style.transformOrigin=t.style.webKittransformOrigin="left top",t.style.position="absolute");var n=$.getTransformRelativeToWindow(e,i,s);t.style.transform=t.style.webkitTransform="scale("+n.scaleX+","+n.scaleY+") rotate("+$.gStage.canvasDegree+"deg)",t.style.width=r+"px",t.style.height=a+"px",t.style.left=n.x+"px",t.style.top=n.y+"px"}static isOkTextureList(t){if(!t)return!1;var e,i,s=t.length;for(e=0;e\s+<"),(e=(new DOMParser).parseFromString(t,"text/xml")).firstChild.textContent.indexOf("This page contains the following errors")>-1)throw new Error(e.firstChild.firstChild.textContent);return e};class J{constructor(t){if(this.arrColor=[],null==t||"none"==t)return this.strColor="#00000000",this.numColor=0,void(this.arrColor=[0,0,0,0]);var e,i,s;if("string"==typeof t)if(t.indexOf("rgba(")>=0||t.indexOf("rgb(")>=0){var r,a,n=t;for(r=n.indexOf("("),a=n.indexOf(")"),n=n.substring(r+1,a),this.arrColor=n.split(","),i=this.arrColor.length,e=0;e=0||9===this.strColor.length?(this.arrColor=[((4278190080&s)>>>24)/255,((16711680&s)>>16)/255,((65280&s)>>8)/255,(255&s)/255],this.numColor=(4278190080&s)>>>24|(16711680&s)>>8|(65280&s)<<8|(255&s)<<24):(this.arrColor=[((16711680&s)>>16)/255,((65280&s)>>8)/255,(255&s)/255,1],this.numColor=4278190080|(16711680&s)>>16|65280&s|(255&s)<<16),this.arrColor.__id=++J._COLODID}static _initDefault(){for(var t in J._DEFAULT={},J._COLOR_MAP)J._SAVE[t]=J._DEFAULT[t]=new J(J._COLOR_MAP[t]);return J._DEFAULT}static _initSaveMap(){for(var t in J._SAVE_SIZE=0,J._SAVE={},J._DEFAULT)J._SAVE[t]=J._DEFAULT[t]}static create(t){var e=t+"",i=J._SAVE[e];return null!=i?i:(J._SAVE_SIZE<1e3&&J._initSaveMap(),J._SAVE[e]=new J(t))}}J._SAVE={},J._SAVE_SIZE=0,J._COLOR_MAP={purple:"#800080",orange:"#ffa500",white:"#FFFFFF",red:"#FF0000",green:"#00FF00",blue:"#0000FF",black:"#000000",yellow:"#FFFF00",gray:"#808080"},J._DEFAULT=J._initDefault(),J._COLODID=1;class tt extends Q{constructor(t=null){super(),t||(t=this._copyMatrix(tt.IDENTITY_MATRIX)),this._mat=new Float32Array(16),this._alpha=new Float32Array(4),this.setByMatrix(t)}gray(){return this.setByMatrix(tt.GRAY_MATRIX)}color(t=0,e=0,i=0,s=1){return this.setByMatrix([1,0,0,0,t,0,1,0,0,e,0,0,1,0,i,0,0,0,1,s])}setColor(t){var e=J.create(t).arrColor,i=[0,0,0,0,256*e[0],0,0,0,0,256*e[1],0,0,0,0,256*e[2],0,0,0,1,0];return this.setByMatrix(i)}setByMatrix(t){this._matrix!=t&&this._copyMatrix(t);for(var e=0,i=0,s=0;s<20;s++)s%5!=4?this._mat[e++]=t[s]:this._alpha[i++]=t[s];return this}get type(){return Q.COLOR}adjustColor(t,e,i,s){return this.adjustHue(s),this.adjustContrast(e),this.adjustBrightness(t),this.adjustSaturation(i),this}adjustBrightness(t){return 0==(t=this._clampValue(t,100))||isNaN(t)?this:this._multiplyMatrix([1,0,0,0,t,0,1,0,0,t,0,0,1,0,t,0,0,0,1,0,0,0,0,0,1])}adjustContrast(t){if(0==(t=this._clampValue(t,100))||isNaN(t))return this;var e,i=(e=t<0?127+t/100*127:127*(e=0==(e=t%1)?tt.DELTA_INDEX[t]:tt.DELTA_INDEX[t<<0]*(1-e)+tt.DELTA_INDEX[1+(t<<0)]*e)+127)/127,s=.5*(127-e);return this._multiplyMatrix([i,0,0,0,s,0,i,0,0,s,0,0,i,0,s,0,0,0,1,0,0,0,0,0,1])}adjustSaturation(t){if(0==(t=this._clampValue(t,100))||isNaN(t))return this;var e=1+(t>0?3*t/100:t/100),i=1-e,s=.3086*i,r=.6094*i,a=.082*i;return this._multiplyMatrix([s+e,r,a,0,0,s,r+e,a,0,0,s,r,a+e,0,0,0,0,0,1,0,0,0,0,0,1])}adjustHue(t){if(0==(t=this._clampValue(t,180)/180*Math.PI)||isNaN(t))return this;var e=Math.cos(t),i=Math.sin(t),s=.213,r=.715,a=.072;return this._multiplyMatrix([s+e*(1-s)+i*-s,r+e*-r+i*-r,a+e*-a+i*(1-a),0,0,s+e*-s+.143*i,r+e*(1-r)+.14*i,a+e*-a+-.283*i,0,0,s+e*-s+-.787*i,r+e*-r+i*r,a+e*(1-a)+i*a,0,0,0,0,0,1,0,0,0,0,0,1])}reset(){return this.setByMatrix(this._copyMatrix(tt.IDENTITY_MATRIX))}_multiplyMatrix(t){var e=[];this._matrix=this._fixMatrix(this._matrix);for(var i=0;i<5;i++){for(var s=0;s<5;s++)e[s]=this._matrix[s+5*i];for(s=0;s<5;s++){for(var r=0,a=0;a<5;a++)r+=t[s+5*a]*e[a];this._matrix[s+5*i]=r}}return this.setByMatrix(this._matrix)}_clampValue(t,e){return Math.min(e,Math.max(-e,t))}_fixMatrix(t=null){return null==t?tt.IDENTITY_MATRIX:(t.lengthtt.LENGTH&&(t=t.slice(0,tt.LENGTH)),t)}_copyMatrix(t){var e=tt.LENGTH;this._matrix||(this._matrix=[]);for(var i=0;i0?t:5),i=0;i<=1;i+=s)this._calFun(i,e)}getBezierPoints(t,e=5,i=2){var s,r;if((r=t.length)<2*(i+1))return[];var a=[];switch(i){case 2:this._calFun=this.getPoint2;break;case 3:this._calFun=this.getPoint3;break;default:return[]}for(;this._controlPoints.length<=i;)this._controlPoints.push(f.create());for(s=0;s<2*i;s+=2)this._switchPoint(t[s],t[s+1]);for(s=2*i;s=0;e--)(a=(s=t[e]).x+"_"+s.y)in o||(o[a]=!0,r.push(s));for(h=r.length,$.copyArray(t,r),e=1;e0||0==lt.multiply(t[i],t[n],t[0])&<.dis(t[0],t[i])=2&<.multiply(t[e],r[r.length-1],r[r.length-2])>=0;)r.pop();t[e]&&r.push(t[e])}return r}}lt._tempPointList=[],lt._temPList=[],lt._temArr=[];class _t{constructor(t){this.setValue(t)}static create(t){if(t){var e=t instanceof J?t:J.create(t);return e._drawStyle||(e._drawStyle=new _t(t))}return _t.DEFAULT}setValue(t){this._color=t?t instanceof J?t:J.create(t):J.create("#000000")}reset(){this._color=J.create("#000000")}toInt(){return this._color.numColor}equal(t){return"string"==typeof t?this._color.strColor===t:t instanceof J&&this._color.numColor===t.numColor}toColorStr(){return this._color.strColor}}_t.DEFAULT=new _t("#000000");class ut{constructor(){this._lastOriX=0,this._lastOriY=0,this.paths=[],this._curPath=null}beginPath(t){this.paths.length=1,this._curPath=this.paths[0]=new ct,this._curPath.convex=t}closePath(){this._curPath.loop=!0}newPath(){this._curPath=new ct,this.paths.push(this._curPath)}addPoint(t,e){this._curPath.path.push(t,e)}push(t,e){this._curPath?this._curPath.path.length>0&&(this._curPath=new ct,this.paths.push(this._curPath)):(this._curPath=new ct,this.paths.push(this._curPath));var i=this._curPath;i.path=t.slice(),i.convex=e}reset(){this.paths.length=0}}class ct{constructor(){this.path=[],this.loop=!1,this.convex=!1}}class dt{constructor(t=dt.TYPE_2D){this.clipInfoID=-1,this._mesh=null,this._blendFn=null,this._id=0,this._renderType=0,this._parent=null,this._key=new q,this._startIdx=0,this._numEle=0,this._ref=1,this.shaderValue=null,this._renderType=t,this._id=++dt.ID}static __init__(){var t=dt.RENDERBASE=new dt(-1);t.shaderValue=new j(0,0),t.shaderValue.ALPHA=1,t._ref=4294967295}getID(){return this._id}getRenderType(){return this._renderType}toString(){return"ibindex:"+this._startIdx+" num:"+this._numEle+" key="+this._key}renderSubmit(){return 1}releaseRender(){}}dt.TYPE_2D=1e4,dt.TYPE_CANVAS=10003,dt.TYPE_CMDSETRT=10004,dt.TYPE_CUSTOM=10005,dt.TYPE_BLURRT=10006,dt.TYPE_CMDDESTORYPRERT=10007,dt.TYPE_DISABLESTENCIL=10008,dt.TYPE_OTHERIBVB=10009,dt.TYPE_PRIMITIVE=10010,dt.TYPE_RT=10011,dt.TYPE_BLUR_RT=10012,dt.TYPE_TARGET=10013,dt.TYPE_CHANGE_VALUE=10014,dt.TYPE_SHAPE=10015,dt.TYPE_TEXTURE=10016,dt.TYPE_FILLTEXTURE=10017,dt.KEY_ONCE=-1,dt.KEY_FILLRECT=1,dt.KEY_DRAWTEXTURE=2,dt.KEY_VG=3,dt.KEY_TRIANGLES=4,dt.ID=1,dt.preRender=null;class pt{constructor(){}static _createArray(){var t=[];return t._length=0,t}static _init(){var t=pt._namemap={};return t[pt.TYPE_ALPHA]="ALPHA",t[pt.TYPE_FILESTYLE]="fillStyle",t[pt.TYPE_FONT]="font",t[pt.TYPE_LINEWIDTH]="lineWidth",t[pt.TYPE_STROKESTYLE]="strokeStyle",t[pt.TYPE_ENABLEMERGE]="_mergeID",t[pt.TYPE_MARK]=t[pt.TYPE_TRANSFORM]=t[pt.TYPE_TRANSLATE]=[],t[pt.TYPE_TEXTBASELINE]="textBaseline",t[pt.TYPE_TEXTALIGN]="textAlign",t[pt.TYPE_GLOBALCOMPOSITEOPERATION]="_nBlendType",t[pt.TYPE_SHADER]="shader",t[pt.TYPE_FILTERS]="filters",t[pt.TYPE_COLORFILTER]="_colorFiler",t}isSaveMark(){return!1}restore(t){this._dataObj[this._valueName]=this._value,pt.POOL[pt.POOL._length++]=this,this._newSubmit&&(t._curSubmit=dt.RENDERBASE)}static save(t,e,i,s){if((t._saveMark._saveuse&e)!==e){t._saveMark._saveuse|=e;var r=pt.POOL,a=r._length>0?r[--r._length]:new pt;a._value=i[a._valueName=pt._namemap[e]],a._dataObj=i,a._newSubmit=s;var n=t._save;n[n._length++]=a}}}pt.TYPE_ALPHA=1,pt.TYPE_FILESTYLE=2,pt.TYPE_FONT=8,pt.TYPE_LINEWIDTH=256,pt.TYPE_STROKESTYLE=512,pt.TYPE_MARK=1024,pt.TYPE_TRANSFORM=2048,pt.TYPE_TRANSLATE=4096,pt.TYPE_ENABLEMERGE=8192,pt.TYPE_TEXTBASELINE=16384,pt.TYPE_TEXTALIGN=32768,pt.TYPE_GLOBALCOMPOSITEOPERATION=65536,pt.TYPE_CLIPRECT=131072,pt.TYPE_CLIPRECT_STENCIL=262144,pt.TYPE_IBVB=524288,pt.TYPE_SHADER=1048576,pt.TYPE_FILTERS=2097152,pt.TYPE_FILTERS_TYPE=4194304,pt.TYPE_COLORFILTER=8388608,pt.POOL=pt._createArray(),pt._namemap=pt._init();class ft{constructor(){this._globalClipMatrix=new p,this._clipInfoID=-1,this._clipRect=new m,this.incache=!1}isSaveMark(){return!1}restore(t){this._globalClipMatrix.copyTo(t._globalClipMatrix),this._clipRect.clone(t._clipRect),t._clipInfoID=this._clipInfoID,ft.POOL[ft.POOL._length++]=this,t._clipInCache=this.incache}static save(t){if((t._saveMark._saveuse&pt.TYPE_CLIPRECT)!=pt.TYPE_CLIPRECT){t._saveMark._saveuse|=pt.TYPE_CLIPRECT;var e=ft.POOL,i=e._length>0?e[--e._length]:new ft;t._globalClipMatrix.copyTo(i._globalClipMatrix),t._clipRect.clone(i._clipRect),i._clipInfoID=t._clipInfoID,i.incache=t._clipInCache;var s=t._save;s[s._length++]=i}}}ft.POOL=pt._createArray();class mt{constructor(){this._saveuse=0}isSaveMark(){return!0}restore(t){t._saveMark=this._preSaveMark,mt.POOL[mt.POOL._length++]=this}static Create(t){var e=mt.POOL,i=e._length>0?e[--e._length]:new mt;return i._saveuse=0,i._preSaveMark=t._saveMark,t._saveMark=i,i}}mt.POOL=pt._createArray();class gt{constructor(){this._matrix=new p}isSaveMark(){return!1}restore(t){t._curMat=this._savematrix,gt.POOL[gt.POOL._length++]=this}static save(t){var e=t._saveMark;if((e._saveuse&pt.TYPE_TRANSFORM)!==pt.TYPE_TRANSFORM){e._saveuse|=pt.TYPE_TRANSFORM;var i=gt.POOL,s=i._length>0?i[--i._length]:new gt;s._savematrix=t._curMat,t._curMat=t._curMat.copyTo(s._matrix);var r=t._save;r[r._length++]=s}}}gt.POOL=pt._createArray();class Tt{constructor(){this._mat=new p}isSaveMark(){return!1}restore(t){this._mat.copyTo(t._curMat),Tt.POOL[Tt.POOL._length++]=this}static save(t){var e=Tt.POOL,i=e._length>0?e[--e._length]:new Tt;t._curMat.copyTo(i._mat);var s=t._save;s[s._length++]=i}}Tt.POOL=pt._createArray();class vt{constructor(){this._nativeVertexArrayObject=g.layaGPUInstance.createVertexArray()}bind(){vt._curBindedBufferState!==this&&(g.layaGPUInstance.bindVertexArray(this._nativeVertexArrayObject),vt._curBindedBufferState=this)}unBind(){if(vt._curBindedBufferState!==this)throw"BufferState: must call bind() function first.";g.layaGPUInstance.bindVertexArray(null),vt._curBindedBufferState=null}destroy(){g.layaGPUInstance.deleteVertexArray(this._nativeVertexArrayObject)}bindForNative(){g.instance.bindVertexArray(this._nativeVertexArrayObject),vt._curBindedBufferState=this}unBindForNative(){g.instance.bindVertexArray(null),vt._curBindedBufferState=null}}class xt extends vt{constructor(){super()}}class yt{constructor(){this._byteLength=0,this._glBuffer=g.instance.createBuffer()}get bufferUsage(){return this._bufferUsage}_bindForVAO(){}bind(){return!1}destroy(){this._glBuffer&&(g.instance.deleteBuffer(this._glBuffer),this._glBuffer=null)}}class Et{}Et.loopStTm=0,Et.loopCount=0;class Ct extends yt{constructor(){super(),this._maxsize=0,this._upload=!0,this._uploadSize=0,this._bufferSize=0,this._u8Array=null}static __int__(t){}get bufferLength(){return this._buffer.byteLength}set byteLength(t){this.setByteLength(t)}setByteLength(t){this._byteLength!==t&&(t<=this._bufferSize||this._resizeBuffer(2*t+256,!0),this._byteLength=t)}needSize(t){var e=this._byteLength;if(t){var i=this._byteLength+t;i<=this._bufferSize||this._resizeBuffer(i<<1,!0),this._byteLength=i}return e}_bufferData(){this._maxsize=Math.max(this._maxsize,this._byteLength),Et.loopCount%30==0&&(this._buffer.byteLength>this._maxsize+64&&(this._buffer=this._buffer.slice(0,this._maxsize+64),this._bufferSize=this._buffer.byteLength,this._checkArrayUse()),this._maxsize=this._byteLength),this._uploadSizethis._maxsize+64&&(this._buffer=this._buffer.slice(0,this._maxsize+64),this._bufferSize=this._buffer.byteLength,this._checkArrayUse()),this._maxsize=this._byteLength),this._uploadSize0){var r=new ArrayBuffer(t),a=s&&s.buffer==i?s:new Uint8Array(i);(s=this._u8Array=new Uint8Array(r)).set(a,0),i=this._buffer=r}else i=this._buffer=new ArrayBuffer(t),this._u8Array=null;return this._checkArrayUse(),this._upload=!0,this._bufferSize=i.byteLength,this}append(t){var e,i;this._upload=!0,e=t.byteLength,t instanceof Uint8Array?(this._resizeBuffer(this._byteLength+e,!0),i=new Uint8Array(this._buffer,this._byteLength)):t instanceof Uint16Array?(this._resizeBuffer(this._byteLength+e,!0),i=new Uint16Array(this._buffer,this._byteLength)):t instanceof Float32Array&&(this._resizeBuffer(this._byteLength+e,!0),i=new Float32Array(this._buffer,this._byteLength)),i.set(t,0),this._byteLength+=e,this._checkArrayUse()}appendU16Array(t,e){this._resizeBuffer(this._byteLength+2*e,!0);var i=new Uint16Array(this._buffer,this._byteLength,e);if(6==e)i[0]=t[0],i[1]=t[1],i[2]=t[2],i[3]=t[3],i[4]=t[4],i[5]=t[5];else if(e>=100)i.set(new Uint16Array(t.buffer,0,e));else for(var s=0;s>2;this.setByteLength(this._byteLength+4*t.length),this.getFloat32Array().set(t,e),this._upload=!0}_checkArrayUse(){this._floatArray32&&(this._floatArray32=new Float32Array(this._buffer)),this._uint32Array&&(this._uint32Array=new Uint32Array(this._buffer))}deleteBuffer(){super._disposeResource()}_bindForVAO(){var t=g.instance;t.bindBuffer(t.ARRAY_BUFFER,this._glBuffer)}bind(){if(yt._bindedVertexBuffer!==this._glBuffer){var t=g.instance;return t.bindBuffer(t.ARRAY_BUFFER,this._glBuffer),yt._bindedVertexBuffer=this._glBuffer,!0}return!1}destroy(){super.destroy(),this._byteLength=0,this._upload=!0,this._buffer=null,this._floatArray32=null}}Rt.create=function(t,e=35048){return new Rt(t,e)};class bt{constructor(t,i,s){this._stride=0,this.vertNum=0,this.indexNum=0,this._applied=!1,this._quadNum=0,this.canReuse=!1,this._stride=t,this._vb=new Rt(t,g.instance.DYNAMIC_DRAW),i?this._vb._resizeBuffer(i,!1):e.webGL2D_MeshAllocMaxMem&&this._vb._resizeBuffer(65536*t,!1),this._ib=new At,s&&this._ib._resizeBuffer(s,!1)}cloneWithNewVB(){var t=new bt(this._stride,0,0);return t._ib=this._ib,t._quadNum=this._quadNum,t._attribInfo=this._attribInfo,t}cloneWithNewVBIB(){var t=new bt(this._stride,0,0);return t._attribInfo=this._attribInfo,t}getVBW(){return this._vb.setNeedUpload(),this._vb}getVBR(){return this._vb}getIBR(){return this._ib}getIBW(){return this._ib.setNeedUpload(),this._ib}createQuadIB(t){this._quadNum=t,this._ib._resizeBuffer(6*t*2,!1),this._ib.byteLength=this._ib.bufferLength;for(var e=this._ib.getUint16Array(),i=0,s=0,r=0;r>2;r.setByteLength(a+St.const_stride<<2);var n=r._floatArray32||r.getFloat32Array(),h=r._uint32Array,o=a,l=s?255:0;n[o++]=t[0],n[o++]=t[1],n[o++]=e[0],n[o++]=e[1],h[o++]=i,h[o++]=l,n[o++]=t[2],n[o++]=t[3],n[o++]=e[2],n[o++]=e[3],h[o++]=i,h[o++]=l,n[o++]=t[4],n[o++]=t[5],n[o++]=e[4],n[o++]=e[5],h[o++]=i,h[o++]=l,n[o++]=t[6],n[o++]=t[7],n[o++]=e[6],n[o++]=e[7],h[o++]=i,h[o++]=l,r._upload=!0}}St.const_stride=24,St._maxIB=16384,St._POOL=[];class wt extends bt{constructor(){super(wt.const_stride,4,4),this.canReuse=!0,this.setAttributes(wt._fixattriInfo)}static __init__(){wt._fixattriInfo=[5126,4,0,5121,4,16,5121,4,20]}static getAMesh(t){var e;return e=wt._POOL.length?wt._POOL.pop():new wt,t&&e._vb._resizeBuffer(65536*wt.const_stride,!1),e}addData(t,e,i,s,r){var a=this._vb,n=this._ib,h=t.length>>1,o=a.needSize(h*wt.const_stride)>>2,l=a._floatArray32||a.getFloat32Array(),_=a._uint32Array,u=0,c=s.a,d=s.b,p=s.c,f=s.d,m=s.tx,g=s.ty,T=0;for(T=0;T>1;if(y>0){var b=R+E,S=0;for(T=R;T>2,a=this._vb._floatArray32||this._vb.getFloat32Array(),n=this._vb._uint32Array,h=0,o=e.length/2,l=0;l0.0){\r\n\t\t\tclpos.x+=mmat[3].x;\t//tx\t最简单处理\r\n\t\t\tclpos.y+=mmat[3].y;\t//ty\r\n\t\t}\r\n\t#endif\r\n\tvec2 clippos = pos.xy - clpos;\t//pos已经应用矩阵了,为了减的有意义,clip的位置也要缩放\r\n\tif(clipw>20000. && cliph>20000.)\r\n\t\tcliped = vec2(0.5,0.5);\r\n\telse {\r\n\t\t//转成0到1之间。/clipw/clipw 表示clippos与normalize之后的clip朝向点积之后,再除以clipw\r\n\t\tcliped=vec2( dot(clippos,clipMatDir.xy)/clipw/clipw, dot(clippos,clipMatDir.zw)/cliph/cliph);\r\n\t}\r\n\r\n}","/*\r\n\ttexture和fillrect使用的。\r\n*/\r\n#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\nprecision highp float;\r\n#else\r\nprecision mediump float;\r\n#endif\r\n\r\nvarying vec4 v_texcoordAlpha;\r\nvarying vec4 v_color;\r\nvarying float v_useTex;\r\nuniform sampler2D texture;\r\nvarying vec2 cliped;\r\n\r\n#ifdef BLUR_FILTER\r\nuniform vec4 strength_sig2_2sig2_gauss1;\r\nuniform vec2 blurInfo;\r\n\r\n#define PI 3.141593\r\n\r\nfloat getGaussian(float x, float y){\r\n return strength_sig2_2sig2_gauss1.w*exp(-(x*x+y*y)/strength_sig2_2sig2_gauss1.z);\r\n}\r\n\r\nvec4 blur(){\r\n const float blurw = 9.0;\r\n vec4 vec4Color = vec4(0.0,0.0,0.0,0.0);\r\n vec2 halfsz=vec2(blurw,blurw)/2.0/blurInfo; \r\n vec2 startpos=v_texcoordAlpha.xy-halfsz;\r\n vec2 ctexcoord = startpos;\r\n vec2 step = 1.0/blurInfo; //每个像素 \r\n \r\n for(float y = 0.0;y<=blurw; ++y){\r\n ctexcoord.x=startpos.x;\r\n for(float x = 0.0;x<=blurw; ++x){\r\n //TODO 纹理坐标的固定偏移应该在vs中处理\r\n vec4Color += texture2D(texture, ctexcoord)*getGaussian(x-blurw/2.0,y-blurw/2.0);\r\n ctexcoord.x+=step.x;\r\n }\r\n ctexcoord.y+=step.y;\r\n }\r\n return vec4Color;\r\n}\r\n#endif\r\n\r\n#ifdef COLOR_FILTER\r\nuniform vec4 colorAlpha;\r\nuniform mat4 colorMat;\r\n#endif\r\n\r\n#ifdef GLOW_FILTER\r\nuniform vec4 u_color;\r\nuniform vec4 u_blurInfo1;\r\nuniform vec4 u_blurInfo2;\r\n#endif\r\n\r\n#ifdef COLOR_ADD\r\nuniform vec4 colorAdd;\r\n#endif\r\n\r\n#ifdef FILLTEXTURE\t\r\nuniform vec4 u_TexRange;//startu,startv,urange, vrange\r\n#endif\r\nvoid main() {\r\n\tif(cliped.x<0.) discard;\r\n\tif(cliped.x>1.) discard;\r\n\tif(cliped.y<0.) discard;\r\n\tif(cliped.y>1.) discard;\r\n\t\r\n#ifdef FILLTEXTURE\t\r\n vec4 color= texture2D(texture, fract(v_texcoordAlpha.xy)*u_TexRange.zw + u_TexRange.xy);\r\n#else\r\n vec4 color= texture2D(texture, v_texcoordAlpha.xy);\r\n#endif\r\n\r\n if(v_useTex<=0.)color = vec4(1.,1.,1.,1.);\r\n color.a*=v_color.w;\r\n //color.rgb*=v_color.w;\r\n color.rgb*=v_color.rgb;\r\n gl_FragColor=color;\r\n \r\n #ifdef COLOR_ADD\r\n\tgl_FragColor = vec4(colorAdd.rgb,colorAdd.a*gl_FragColor.a);\r\n\tgl_FragColor.xyz *= colorAdd.a;\r\n #endif\r\n \r\n #ifdef BLUR_FILTER\r\n\tgl_FragColor = blur();\r\n\tgl_FragColor.w*=v_color.w; \r\n #endif\r\n \r\n #ifdef COLOR_FILTER\r\n\tmat4 alphaMat =colorMat;\r\n\r\n\talphaMat[0][3] *= gl_FragColor.a;\r\n\talphaMat[1][3] *= gl_FragColor.a;\r\n\talphaMat[2][3] *= gl_FragColor.a;\r\n\r\n\tgl_FragColor = gl_FragColor * alphaMat;\r\n\tgl_FragColor += colorAlpha/255.0*gl_FragColor.a;\r\n #endif\r\n \r\n #ifdef GLOW_FILTER\r\n\tconst float c_IterationTime = 10.0;\r\n\tfloat floatIterationTotalTime = c_IterationTime * c_IterationTime;\r\n\tvec4 vec4Color = vec4(0.0,0.0,0.0,0.0);\r\n\tvec2 vec2FilterDir = vec2(-(u_blurInfo1.z)/u_blurInfo2.x,-(u_blurInfo1.w)/u_blurInfo2.y);\r\n\tvec2 vec2FilterOff = vec2(u_blurInfo1.x/u_blurInfo2.x/c_IterationTime * 2.0,u_blurInfo1.y/u_blurInfo2.y/c_IterationTime * 2.0);\r\n\tfloat maxNum = u_blurInfo1.x * u_blurInfo1.y;\r\n\tvec2 vec2Off = vec2(0.0,0.0);\r\n\tfloat floatOff = c_IterationTime/2.0;\r\n\tfor(float i = 0.0;i<=c_IterationTime; ++i){\r\n\t\tfor(float j = 0.0;j<=c_IterationTime; ++j){\r\n\t\t\tvec2Off = vec2(vec2FilterOff.x * (i - floatOff),vec2FilterOff.y * (j - floatOff));\r\n\t\t\tvec4Color += texture2D(texture, v_texcoordAlpha.xy + vec2FilterDir + vec2Off)/floatIterationTotalTime;\r\n\t\t}\r\n\t}\r\n\tgl_FragColor = vec4(u_color.rgb,vec4Color.a * u_blurInfo2.z);\r\n\tgl_FragColor.rgb *= gl_FragColor.a; \r\n #endif\r\n \r\n}",null),z.preCompile2D(0,V.PRIMITIVE,"attribute vec4 position;\r\nattribute vec4 attribColor;\r\n//attribute vec4 clipDir;\r\n//attribute vec2 clipRect;\r\nuniform vec4 clipMatDir;\r\nuniform vec2 clipMatPos;\r\n#ifdef WORLDMAT\r\n\tuniform mat4 mmat;\r\n#endif\r\nuniform mat4 u_mmat2;\r\n//uniform vec2 u_pos;\r\nuniform vec2 size;\r\nvarying vec4 color;\r\n//vec4 dirxy=vec4(0.9,0.1, -0.1,0.9);\r\n//vec4 clip=vec4(100.,30.,300.,600.);\r\nvarying vec2 cliped;\r\nvoid main(){\r\n\t\r\n#ifdef WORLDMAT\r\n\tvec4 pos=mmat*vec4(position.xy,0.,1.);\r\n\tgl_Position =vec4((pos.x/size.x-0.5)*2.0,(0.5-pos.y/size.y)*2.0,pos.z,1.0);\r\n#else\r\n\tgl_Position =vec4((position.x/size.x-0.5)*2.0,(0.5-position.y/size.y)*2.0,position.z,1.0);\r\n#endif\t\r\n\tfloat clipw = length(clipMatDir.xy);\r\n\tfloat cliph = length(clipMatDir.zw);\r\n\tvec2 clippos = position.xy - clipMatPos.xy;\t//pos已经应用矩阵了,为了减的有意义,clip的位置也要缩放\r\n\tif(clipw>20000. && cliph>20000.)\r\n\t\tcliped = vec2(0.5,0.5);\r\n\telse {\r\n\t\t//clipdir是带缩放的方向,由于上面clippos是在缩放后的空间计算的,所以需要把方向先normalize一下\r\n\t\tcliped=vec2( dot(clippos,clipMatDir.xy)/clipw/clipw, dot(clippos,clipMatDir.zw)/cliph/cliph);\r\n\t}\r\n //pos2d.x = dot(clippos,dirx);\r\n color=attribColor/255.;\r\n}","precision mediump float;\r\n//precision mediump float;\r\nvarying vec4 color;\r\n//uniform float alpha;\r\nvarying vec2 cliped;\r\nvoid main(){\r\n\t//vec4 a=vec4(color.r, color.g, color.b, 1);\r\n\t//a.a*=alpha;\r\n gl_FragColor= color;// vec4(color.r, color.g, color.b, alpha);\r\n\tgl_FragColor.rgb*=color.a;\r\n\tif(cliped.x<0.) discard;\r\n\tif(cliped.x>1.) discard;\r\n\tif(cliped.y<0.) discard;\r\n\tif(cliped.y>1.) discard;\r\n}",null),z.preCompile2D(0,V.SKINMESH,"attribute vec2 position;\r\nattribute vec2 texcoord;\r\nattribute vec4 color;\r\nuniform vec2 size;\r\nuniform float offsetX;\r\nuniform float offsetY;\r\nuniform mat4 mmat;\r\nuniform mat4 u_mmat2;\r\nvarying vec2 v_texcoord;\r\nvarying vec4 v_color;\r\nvoid main() {\r\n vec4 pos=mmat*u_mmat2*vec4(offsetX+position.x,offsetY+position.y,0,1 );\r\n gl_Position = vec4((pos.x/size.x-0.5)*2.0,(0.5-pos.y/size.y)*2.0,pos.z,1.0);\r\n v_color = color;\r\n v_color.rgb *= v_color.a;\r\n v_texcoord = texcoord; \r\n}","precision mediump float;\r\nvarying vec2 v_texcoord;\r\nvarying vec4 v_color;\r\nuniform sampler2D texture;\r\nuniform float alpha;\r\nvoid main() {\r\n\tvec4 t_color = texture2D(texture, v_texcoord);\r\n\tgl_FragColor = t_color.rgba * v_color;\r\n\tgl_FragColor *= alpha;\r\n}",null)}}class Lt{constructor(){var t=g.instance;this.ib=At.create(t.DYNAMIC_DRAW),this.vb=Rt.create(8)}static getInstance(){return Lt.instance=Lt.instance||new Lt}addSkinMesh(t){t.getData2(this.vb,this.ib,this.vb._byteLength/32)}reset(){this.vb.clear(),this.ib.clear()}}class Dt{static createLine2(t,e,i,s,r,a){if(t.length<4)return null;var n=Dt.tempData.length>t.length+2?Dt.tempData:new Array(t.length+2);n[0]=t[0],n[1]=t[1];var h=2,o=0,l=t.length;for(o=2;o.01&&(n[h++]=t[o],n[h++]=t[o+1]);a&&Math.abs(t[0]-n[h-2])+Math.abs(t[1]-n[h-1])>.01&&(n[h++]=t[0],n[h++]=t[1]);var _=r;l=h/2;var u,c,d,p,f,m,g,T,v,x,y,E,C,A,R,b,S,w,M,I,P=i/2;for(d=n[0],p=n[1],x=d-(f=n[2]),v=(v=-(p-(m=n[3])))/(I=Math.sqrt(v*v+x*x))*P,x=x/I*P,_.push(d-v,p-x,d+v,p+x),o=1;o.001&&(g[d=4*T]=l,g[d+1]=_,g[d+2]=p/c,g[d+3]=f/c,T++);for(s?(l=h[o-2],_=h[o-1],u=h[0],f=h[1]-_,0!=(p=u-l)&&0!=f&&(c=Math.sqrt(p*p+f*f))>.001&&(g[d=4*T]=l,g[d+1]=_,g[d+2]=p/c,g[d+3]=f/c,T++)):(g[d=4*T]=l,g[d+1]=_,g[d+2]=p/c,g[d+3]=f/c,T++),v=0,x=0;x80*i){s=a=t[0],r=n=t[1];for(var p=i;pa&&(a=h),o>n&&(n=o);l=0!==(l=Math.max(a-s,n-r))?1/l:0}return Ft.earcutLinked(c,d,i,s,r,l),d}static linkedList(t,e,i,s,r){var a,n;if(r===Ft.signedArea(t,e,i,s)>0)for(a=e;a=e;a-=s)n=Ft.insertNode(a,t[a],t[a+1],n);return n&&Ft.equals(n,n.next)&&(Ft.removeNode(n),n=n.next),n}static filterPoints(t,e){if(!t)return t;e||(e=t);var i,s=t;do{if(i=!1,s.steiner||!Ft.equals(s,s.next)&&0!==Ft.area(s.prev,s,s.next))s=s.next;else{if(Ft.removeNode(s),(s=e=s.prev)===s.next)break;i=!0}}while(i||s!==e);return e}static earcutLinked(t,e,i,s,r,a,n=null){if(t){!n&&a&&Ft.indexCurve(t,s,r,a);for(var h,o,l=t;t.prev!==t.next;)if(h=t.prev,o=t.next,a?Ft.isEarHashed(t,s,r,a):Ft.isEar(t))e.push(h.i/i),e.push(t.i/i),e.push(o.i/i),Ft.removeNode(t),t=o.next,l=o.next;else if((t=o)===l){n?1===n?(t=Ft.cureLocalIntersections(t,e,i),Ft.earcutLinked(t,e,i,s,r,a,2)):2===n&&Ft.splitEarcut(t,e,i,s,r,a):Ft.earcutLinked(Ft.filterPoints(t,null),e,i,s,r,a,1);break}}}static isEar(t){var e=t.prev,i=t,s=t.next;if(Ft.area(e,i,s)>=0)return!1;for(var r=t.next.next;r!==t.prev;){if(Ft.pointInTriangle(e.x,e.y,i.x,i.y,s.x,s.y,r.x,r.y)&&Ft.area(r.prev,r,r.next)>=0)return!1;r=r.next}return!0}static isEarHashed(t,e,i,s){var r=t.prev,a=t,n=t.next;if(Ft.area(r,a,n)>=0)return!1;for(var h=r.xa.x?r.x>n.x?r.x:n.x:a.x>n.x?a.x:n.x,_=r.y>a.y?r.y>n.y?r.y:n.y:a.y>n.y?a.y:n.y,u=Ft.zOrder(h,o,e,i,s),c=Ft.zOrder(l,_,e,i,s),d=t.nextZ;d&&d.z<=c;){if(d!==t.prev&&d!==t.next&&Ft.pointInTriangle(r.x,r.y,a.x,a.y,n.x,n.y,d.x,d.y)&&Ft.area(d.prev,d,d.next)>=0)return!1;d=d.nextZ}for(d=t.prevZ;d&&d.z>=u;){if(d!==t.prev&&d!==t.next&&Ft.pointInTriangle(r.x,r.y,a.x,a.y,n.x,n.y,d.x,d.y)&&Ft.area(d.prev,d,d.next)>=0)return!1;d=d.prevZ}return!0}static cureLocalIntersections(t,e,i){var s=t;do{var r=s.prev,a=s.next.next;!Ft.equals(r,a)&&Ft.intersects(r,s,s.next,a)&&Ft.locallyInside(r,a)&&Ft.locallyInside(a,r)&&(e.push(r.i/i),e.push(s.i/i),e.push(a.i/i),Ft.removeNode(s),Ft.removeNode(s.next),s=t=a),s=s.next}while(s!==t);return s}static splitEarcut(t,e,i,s,r,a){var n=t;do{for(var h=n.next.next;h!==n.prev;){if(n.i!==h.i&&Ft.isValidDiagonal(n,h)){var o=Ft.splitPolygon(n,h);return n=Ft.filterPoints(n,n.next),o=Ft.filterPoints(o,o.next),Ft.earcutLinked(n,e,i,s,r,a),void Ft.earcutLinked(o,e,i,s,r,a)}h=h.next}n=n.next}while(n!==t)}static eliminateHoles(t,e,i,s){var r,a,n,h,o,l=[];for(r=0,a=e.length;r=s.next.y&&s.next.y!==s.y){var h=s.x+(a-s.y)*(s.next.x-s.x)/(s.next.y-s.y);if(h<=r&&h>n){if(n=h,h===r){if(a===s.y)return s;if(a===s.next.y)return s.next}i=s.x=s.x&&s.x>=_&&r!==s.x&&Ft.pointInTriangle(ai.x)&&Ft.locallyInside(s,t)&&(i=s,c=o),s=s.next;return i}static indexCurve(t,e,i,s){var r=t;do{null===r.z&&(r.z=Ft.zOrder(r.x,r.y,e,i,s)),r.prevZ=r.prev,r.nextZ=r.next,r=r.next}while(r!==t);r.prevZ.nextZ=null,r.prevZ=null,Ft.sortLinked(r)}static sortLinked(t){var e,i,s,r,a,n,h,o,l=1;do{for(i=t,t=null,a=null,n=0;i;){for(n++,s=i,h=0,e=0;e0||o>0&&s;)0!==h&&(0===o||!s||i.z<=s.z)?(r=i,i=i.nextZ,h--):(r=s,s=s.nextZ,o--),a?a.nextZ=r:t=r,r.prevZ=a,a=r;i=s}a.nextZ=null,l*=2}while(n>1);return t}static zOrder(t,e,i,s,r){return(t=1431655765&((t=858993459&((t=252645135&((t=16711935&((t=32767*(t-i)*r)|t<<8))|t<<4))|t<<2))|t<<1))|(e=1431655765&((e=858993459&((e=252645135&((e=16711935&((e=32767*(e-s)*r)|e<<8))|e<<4))|e<<2))|e<<1))<<1}static getLeftmost(t){var e=t,i=t;do{e.x=0&&(t-n)*(s-h)-(i-n)*(e-h)>=0&&(i-n)*(a-h)-(r-n)*(s-h)>=0}static isValidDiagonal(t,e){return t.next.i!==e.i&&t.prev.i!==e.i&&!Ft.intersectsPolygon(t,e)&&Ft.locallyInside(t,e)&&Ft.locallyInside(e,t)&&Ft.middleInside(t,e)}static area(t,e,i){return(e.y-t.y)*(i.x-e.x)-(e.x-t.x)*(i.y-e.y)}static equals(t,e){return t.x===e.x&&t.y===e.y}static intersects(t,e,i,s){return!!(Ft.equals(t,e)&&Ft.equals(i,s)||Ft.equals(t,s)&&Ft.equals(i,e))||Ft.area(t,e,i)>0!=Ft.area(t,e,s)>0&&Ft.area(i,s,t)>0!=Ft.area(i,s,e)>0}static intersectsPolygon(t,e){var i=t;do{if(i.i!==t.i&&i.next.i!==t.i&&i.i!==e.i&&i.next.i!==e.i&&Ft.intersects(i,i.next,t,e))return!0;i=i.next}while(i!==t);return!1}static locallyInside(t,e){return Ft.area(t.prev,t,t.next)<0?Ft.area(t,e,t.next)>=0&&Ft.area(t,t.prev,e)>=0:Ft.area(t,e,t.prev)<0||Ft.area(t,t.next,e)<0}static middleInside(t,e){var i=t,s=!1,r=(t.x+e.x)/2,a=(t.y+e.y)/2;do{i.y>a!=i.next.y>a&&i.next.y!==i.y&&r<(i.next.x-i.x)*(a-i.y)/(i.next.y-i.y)+i.x&&(s=!s),i=i.next}while(i!==t);return s}static splitPolygon(t,e){var i=new Bt(t.i,t.x,t.y),s=new Bt(e.i,e.x,e.y),r=t.next,a=e.prev;return t.next=e,e.prev=t,i.next=r,r.prev=i,s.next=i,i.prev=s,a.next=s,s.prev=a,s}static insertNode(t,e,i,s){var r=new Bt(t,e,i);return s?(r.next=s.next,r.prev=s,s.next.prev=r,s.next=r):(r.prev=r,r.next=r),r}static removeNode(t){t.next.prev=t.prev,t.prev.next=t.next,t.prevZ&&(t.prevZ.nextZ=t.nextZ),t.nextZ&&(t.nextZ.prevZ=t.prevZ)}static signedArea(t,e,i,s){for(var r=0,a=e,n=i-s;a0&&(this._tex!=e||this._imgId!=i||this._clipid>=0&&this._clipid!=t._clipInfoID)&&this.submit(t),this._clipid=t._clipInfoID,t._globalClipMatrix.copyTo(this._clipMatrix),this._tex=e,this._imgId=i,this._colorFiler=t._colorFiler,this._data[this._ndata]=s,this._data[this._ndata+1]=r,this._data[this._ndata+2]=a,this._ndata+=3}getPos(){return 0==Wt.__nPosPool?new Array(8):Wt.__posPool[--Wt.__nPosPool]}enable(t,e){t!==this._enable&&(this._enable=t,this._enable||this.submit(e))}submit(t){var e=this._ndata;if(e){var i=t._mesh,s=t._colorFiler;t._colorFiler=this._colorFiler;var r=kt.create(t,i,j.create(V.TEXTURE2D,0));t._submits[t._submits._length++]=t._curSubmit=r,r.shaderValue.textureHost=this._tex,r._key.other=this._imgId,t._colorFiler=s,t._copyClipInfo(r,this._clipMatrix),r.clipInfoID=this._clipid;for(var a=0;athis._width||e>this._height)return!1;for(var s=-1,r=-1,a=this._width,n=this._height,h=this._cells,o=0;o=i),this._rowInfo[h]-=i;for(var o=0;o0)for(h=0;h=0&&0==this._cells[3*((e+h)*a+o)];--o,++_);for(o=_;o>0;--o)this._cells[3*((e+h)*a+t-o)+1]=o,this._check(o>0)}if(e>0)for(o=t;o=0&&0==this._cells[3*(o+h*a)];--h,_++);for(h=_;h>0;--h)this._cells[3*(o+(e-h)*a)+2]=h,this._check(h>0)}this._used+=i*s/(this._width*this._height)}_check(t){0==t&&console.log("xtexMerger 错误啦")}_clear(){this._texCount=0;for(var t=0;t=Vt.gTextRender.checkCleanTextureDt){for(var e=0;e=Vt.gTextRender.destroyUnusedTextureDt&&(i.destroy(),Vt.pool[e]=Vt.pool[Vt.poolLen-1],Vt.poolLen--,e--)}Vt.cleanTm=t}}touchRect(t,e){this.lastTouchTm!=e&&(this.curUsedCovRate=0,this.curUsedCovRateAtlas=0,this.lastTouchTm=e);var s=Vt.gTextRender.atlasWidth*Vt.gTextRender.atlasWidth,r=i.TextAtlas.atlasGridW*i.TextAtlas.atlasGridW;this.curUsedCovRate+=t.bmpWidth*t.bmpHeight/s,this.curUsedCovRateAtlas+=Math.ceil(t.bmpWidth/i.TextAtlas.atlasGridW)*Math.ceil(t.bmpHeight/i.TextAtlas.atlasGridW)/(s/r)}get texture(){return this}_getSource(){return this._source}drawOnScreen(t,e){}}Vt.gTextRender=null,Vt.pool=new Array(10),Vt.poolLen=0,Vt.cleanTm=0;class Xt{constructor(){this.texWidth=1024,this.texHeight=1024,this.texture=null,this.charMaps={},this.texHeight=this.texWidth=i.TextRender.atlasWidth,this.texture=Vt.getTextTexture(this.texWidth,this.texHeight),this.texWidth/Xt.atlasGridW>256&&(Xt.atlasGridW=Math.ceil(this.texWidth/256)),this.atlasgrid=new Yt(this.texWidth/Xt.atlasGridW,this.texHeight/Xt.atlasGridW,this.texture.id)}setProtecteDist(t){}getAEmpty(t,e,i){var s=this.atlasgrid.addRect(1,Math.ceil(t/Xt.atlasGridW),Math.ceil(e/Xt.atlasGridW),i);return s&&(i.x*=Xt.atlasGridW,i.y*=Xt.atlasGridW),s}get usedRate(){return this.atlasgrid._used}destroy(){for(var t in this.charMaps){this.charMaps[t].deleted=!0}this.texture.discard()}printDebugInfo(){}}Xt.atlasGridW=16;class Ht{setTo(t,e,i){return this.type=t,this.currentTarget=e,this.target=i,this}stopPropagation(){this._stoped=!0}get touches(){if(!this.nativeEvent)return null;var t=this.nativeEvent.touches;if(t)for(var e=i.stage,s=0,r=t.length;sd.width&&(s=d.width-e),d.height&&i+r>d.height&&(r=d.height-i),l?(_=l).setTo(d,null,h||s,o||r):_=new zt(d,null,h||s,o||r),_.width=s,_.height=r,_.offsetX=a,_.offsetY=n;var p=1/d.width,f=1/d.height;e*=p,i*=f,s*=p,r*=f;var m=_.uv[0],g=_.uv[1],T=_.uv[4],v=_.uv[5],x=T-m,y=v-g,E=zt.moveUV(c[0],c[1],[e,i,e+s,i,e+s,i+r,e,i+r]);_.uv=new Float32Array([m+E[0]*x,g+E[1]*y,T-(1-E[2])*x,g+E[3]*y,T-(1-E[4])*x,v-(1-E[5])*y,m+E[6]*x,v-(1-E[7])*y]);var C=d.scaleRate;return C&&1!=C?(_.sourceWidth/=C,_.sourceHeight/=C,_.width/=C,_.height/=C,_.scaleRate=C):_.scaleRate=1,_}static createFromTexture(t,e,i,s,r){var a=t.scaleRate;1!=a&&(e*=a,i*=a,s*=a,r*=a);var n=m.TEMP.setTo(e-t.offsetX,i-t.offsetY,s,r),h=n.intersection(zt._rect1.setTo(0,0,t.width,t.height),zt._rect2);return h?zt.create(t,h.x,h.y,h.width,h.height,h.x-n.x,h.y-n.y,s,r):null}get uv(){return this._uv}set uv(t){this.uvrect[0]=Math.min(t[0],t[2],t[4],t[6]),this.uvrect[1]=Math.min(t[1],t[3],t[5],t[7]),this.uvrect[2]=Math.max(t[0],t[2],t[4],t[6])-this.uvrect[0],this.uvrect[3]=Math.max(t[1],t[3],t[5],t[7])-this.uvrect[1],this._uv=t}get width(){return this._w?this._w:this.bitmap?this.uv&&this.uv!==zt.DEF_UV?(this.uv[2]-this.uv[0])*this.bitmap.width:this.bitmap.width:0}set width(t){this._w=t,this.sourceWidth||(this.sourceWidth=t)}get height(){return this._h?this._h:this.bitmap?this.uv&&this.uv!==zt.DEF_UV?(this.uv[5]-this.uv[1])*this.bitmap.height:this.bitmap.height:0}set height(t){this._h=t,this.sourceHeight||(this.sourceHeight=t)}get bitmap(){return this._bitmap}set bitmap(t){this._bitmap&&this._bitmap._removeReference(this._referenceCount),this._bitmap=t,t&&t._addReference(this._referenceCount)}get destroyed(){return this._destroyed}_addReference(){this._bitmap&&this._bitmap._addReference(),this._referenceCount++}_removeReference(){this._bitmap&&this._bitmap._removeReference(),this._referenceCount--}_getSource(t=null){return this._destroyed||!this._bitmap?null:(this.recoverBitmap(t),this._bitmap.destroyed?null:this.bitmap._getSource())}_onLoaded(t,e){if(e)if(e==this);else if(e instanceof zt){var i=e;zt._create(e,0,0,i.width,i.height,0,0,i.sourceWidth,i.sourceHeight,this)}else this.bitmap=e,this.sourceWidth=this._w=e.width,this.sourceHeight=this._h=e.height;else;t&&t.run(),this.event(Ht.READY,this)}getIsReady(){return!this._destroyed&&!!this._bitmap}setTo(t=null,e=null,i=0,s=0){this.bitmap=t,this.sourceWidth=i,this.sourceHeight=s,t&&(this._w=t.width,this._h=t.height,this.sourceWidth=this.sourceWidth||t.width,this.sourceHeight=this.sourceHeight||t.height),this.uv=e||zt.DEF_UV}load(t,e=null){this._destroyed||i.loader.load(t,b.create(this,this._onLoaded,[e]),null,"htmlimage",1,!0)}getTexturePixels(t,e,s,r){var a,n,h,o=this.bitmap,l=this._w,_=this._h,u=this.sourceWidth,c=this.sourceHeight,d=o.width,p=o.height,f=this.offsetX,m=this.offsetY;let g=s,T=r;if(t+s>l+f&&(g-=t+s-l-f),t+s>u&&(s-=t+s-u),e+r>_+m&&(T-=e+r-_-m),e+r>c&&(r-=e+r-c),s<=0||r<=0)return null;let v=f>t?f-t:0,x=m>e?m-e:0,y=t>f?t-f:0,E=e>m?e-m:0;g-=v,T-=x;var C=4*s,A=null;try{A=o.getPixels()}catch(t){}if(A){if(0==t&&0==e&&s==d&&r==p)return A;let i=this._uv.slice(),o=Math.round(i[0]*d),l=Math.round(i[1]*p);var R=new Uint8Array(s*r*4);for(a=4*o+4*y+(n=(l+E)*(C=4*d)),h=0;h=0;h--)R.set(L.slice(n,n+C),a),a+=C,n-=C;return R}getPixels(t,e,i,s){return window.conch?this._nativeObj.getImageData(t,e,i,s):this.getTexturePixels(t,e,i,s)}recoverBitmap(t=null){var e=this._bitmap.url;if(!this._destroyed&&(!this._bitmap||this._bitmap.destroyed)&&e){let s=i.Loader.loadedMap[e];s?(this.bitmap=s,t&&t()):i.loader.load(e,b.create(this,e=>{this.bitmap=e,t&&t()}),null,"htmlimage",1,!0)}}disposeBitmap(){!this._destroyed&&this._bitmap&&this._bitmap.destroy()}destroy(t=!1){if(!this._destroyed){this._destroyed=!0;var e=this._bitmap;e&&(e._removeReference(this._referenceCount),(0===e.referenceCount||t)&&e.destroy(),e=null),this.url&&this===i.loader.getRes(this.url)&&i.Loader.clearRes(this.url)}}}zt.DEF_UV=new Float32Array([0,0,1,0,1,1,0,1]),zt.NO_UV=new Float32Array([0,0,0,0,0,0,0,0]),zt.INV_UV=new Float32Array([0,1,1,1,1,0,0,0]),zt._rect1=new m,zt._rect2=new m;class Kt{constructor(t){this._font="14px Arial",this._family="Arial",this._size=14,this._italic=!1,this._bold=!1,this._id=Kt._gfontID++,this.setFont(t||this._font)}static Parse(t){if(t===Kt._lastFont)return Kt._lastFontInfo;var e=Kt._cache[t];return e||(e=Kt._cache[t]=new Kt(t)),Kt._lastFont=t,Kt._lastFontInfo=e,e}setFont(t){this._font=t;var e=t.split(" "),i=e.length;if(i<2)1==i&&e[0].indexOf("px")>0&&(this._size=parseInt(e[0]));else{for(var s=-1,r=0;r0||e[r].indexOf("pt")>0){s=r,this._size=parseInt(e[r]),this._size<=0&&(console.error("font parse error:"+t),this._size=14);break}var a=s+1,n=e[a];for(a++;a=0,this._bold=e.indexOf("bold")>=0}}}Kt.EMPTY=new Kt(null),Kt._cache={},Kt._gfontID=0,Kt._lastFont="";class jt{constructor(){this.save=[],this.toUpperCase=null,this.width=-1,this.pageChars=[],this.startID=0,this.startIDStroke=0,this.lastGCCnt=0,this.splitRender=!1,this.scalex=1,this.scaley=1}setText(t){this.changed=!0,this._text=t,this.width=-1,this.cleanCache()}toString(){return this._text}get length(){return this._text?this._text.length:0}charCodeAt(t){return this._text?this._text.charCodeAt(t):NaN}charAt(t){return this._text?this._text.charAt(t):null}cleanCache(){let t=this.pageChars;for(var e in t){let s=t[e];var i=s.tex;1==s.words.length&&i&&i.ri&&i.destroy()}this.pageChars=[],this.startID=0,this.scalex=1,this.scaley=1}}class qt{constructor(){this.char="",this.deleted=!1,this.uv=new Array(8),this.pos=0,this.orix=0,this.oriy=0,this.touchTick=0,this.isSpace=!1}touch(){var t=Et.loopCount;this.touchTick!=t&&this.tex.touchRect(this,t),this.touchTick=t}}class Zt{constructor(){this.fontsz=16}getWidth(t,e){return 0}scale(t,e){}get canvasWidth(){return 0}set canvasWidth(t){}getCharBmp(t,e,i,s,r,a,n,h,o,l,_=null){return null}}class Qt{static __init__(){var t=window.Laya||i.Laya;if(Qt._window)return Qt._window;var e=Qt._window=window,s=Qt._document=e.document,r=Qt.userAgent=e.navigator.userAgent,a=e.navigator.maxTouchPoints||0,n=e.navigator.platform;"my"in Qt.window&&(r.indexOf("TB/")>-1||r.indexOf("Taobao/")>-1||r.indexOf("TM/")>-1?(window.tbMiniGame(t,t),t.TBMiniAdapter?t.TBMiniAdapter.enable():console.error("请先添加淘宝适配库,详细教程:https://ldc2.layabox.com/doc/?language=zh&nav=zh-ts-5-6-0")):r.indexOf("AlipayMiniGame")>-1&&(window.aliPayMiniGame(t,t),t.ALIMiniAdapter?t.ALIMiniAdapter.enable():console.error("请先添加阿里小游戏适配库,详细教程:https://ldc2.layabox.com/doc/?language=zh&nav=zh-ts-5-6-0"))),-1==r.indexOf("OPPO")&&r.indexOf("MiniGame")>-1&&"wx"in Qt.window&&("tt"in Qt.window?(window.ttMiniGame(t,t),t.TTMiniAdapter?t.TTMiniAdapter.enable():console.error("请引入字节跳动小游戏的适配库")):"bl"in Qt.window?(window.biliMiniGame(t,t),t.BLMiniAdapter?t.BLMiniAdapter.enable():console.error("请引入bilibili小游戏的适配库,详细教程:https://ldc2.layabox.com/doc/?language=zh&nav=zh-ts-5-7-0")):"qq"in Qt.window?(window.qqMiniGame(t,t),t.QQMiniAdapter?t.QQMiniAdapter.enable():console.error("请引入手机QQ小游戏的适配库,详细教程:https://ldc2.layabox.com/doc/?language=zh&nav=zh-ts-5-0-0")):(window.wxMiniGame(t,t),t.MiniAdpter?t.MiniAdpter.enable():console.error("请先添加小游戏适配库,详细教程:https://ldc2.layabox.com/doc/?nav=zh-ts-5-0-0"))),"hbs"in Qt.window&&(window.hwMiniGame(t,t),t.HWMiniAdapter?t.HWMiniAdapter.enable():console.error("请先添加小游戏适配库!")),r.indexOf("SwanGame")>-1&&(window.bdMiniGame(t,t),t.BMiniAdapter?t.BMiniAdapter.enable():console.error("请先添加百度小游戏适配库,详细教程:https://ldc2.layabox.com/doc/?language=zh&nav=zh-ts-5-1-0")),r.indexOf("QuickGame")>-1&&(window.miMiniGame(t,t),t.KGMiniAdapter?t.KGMiniAdapter.enable():console.error("请先添加小米小游戏适配库,详细教程:https://ldc2.layabox.com/doc/?language=zh&nav=zh-ts-5-2-0")),r.indexOf("OPPO")>-1&&r.indexOf("MiniGame")>-1&&(window.qgMiniGame(t,t),t.QGMiniAdapter?t.QGMiniAdapter.enable():console.error("请先添加OPPO小游戏适配库,详细教程:https://ldc2.layabox.com/doc/?language=zh&nav=zh-ts-5-3-0")),r.indexOf("VVGame")>-1&&(window.vvMiniGame(t,t),t.VVMiniAdapter?t.VVMiniAdapter.enable():console.error("请先添加VIVO小游戏适配库,详细教程:https://ldc2.layabox.com/doc/?language=zh&nav=zh-ts-5-4-0")),e.trace=console.log,e.requestAnimationFrame=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(t){return e.setTimeout(t,1e3/60)};var h=s.body.style;h.margin=0,h.overflow="hidden",h["-webkit-user-select"]="none",h["-webkit-tap-highlight-color"]="rgba(200,200,200,0)";for(var o=s.getElementsByTagName("meta"),l=0,_=!1,u="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no";l-1,Qt.onIOS=!!r.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/),Qt.onIPhone=r.indexOf("iPhone")>-1,Qt.onMac=r.indexOf("Mac OS X")>-1,Qt.onIPad=r.indexOf("iPad")>-1||"MacIntel"===n&&a>1,Qt.onAndroid=r.indexOf("Android")>-1||r.indexOf("Adr")>-1,Qt.onWP=r.indexOf("Windows Phone")>-1,Qt.onQQBrowser=r.indexOf("QQBrowser")>-1,Qt.onMQQBrowser=r.indexOf("MQQBrowser")>-1||r.indexOf("Mobile")>-1&&r.indexOf("QQ")>-1,Qt.onIE=!!e.ActiveXObject||"ActiveXObject"in e,Qt.onWeiXin=r.indexOf("MicroMessenger")>-1,Qt.onSafari=r.indexOf("Safari")>-1,Qt.onPC=!Qt.onMobile,Qt.onFirefox=r.indexOf("Firefox")>-1,Qt.onEdge=r.indexOf("Edge")>-1,Qt.onMiniGame=r.indexOf("MiniGame")>-1,Qt.onBDMiniGame=r.indexOf("SwanGame")>-1,Qt.onLayaRuntime=!!window.conch,r.indexOf("OPPO")>-1&&r.indexOf("MiniGame")>-1?(Qt.onQGMiniGame=!0,Qt.onMiniGame=!1):"qq"in Qt.window&&r.indexOf("MiniGame")>-1?(Qt.onQQMiniGame=!0,Qt.onMiniGame=!1):"bl"in Qt.window&&r.indexOf("MiniGame")>-1?(Qt.onBLMiniGame=!0,Qt.onMiniGame=!1):"tt"in Qt.window&&r.indexOf("MiniGame")>-1&&(Qt.onTTMiniGame=!0,Qt.onMiniGame=!1),Qt.onHWMiniGame="hbs"in Qt.window,Qt.onVVMiniGame=r.indexOf("VVGame")>-1,Qt.onKGMiniGame=r.indexOf("QuickGame")>-1,r.indexOf("AlipayMiniGame")>-1&&(Qt.onAlipayMiniGame=!0,Qt.onMiniGame=!1),(r.indexOf("TB/")>-1||r.indexOf("Taobao/")>-1||r.indexOf("TM/")>-1)&&(Qt.onTBMiniGame=!0),e}static get _isMiniGame(){return Qt.onMiniGame||Qt.onBDMiniGame||Qt.onQGMiniGame||Qt.onKGMiniGame||Qt.onVVMiniGame||Qt.onAlipayMiniGame||Qt.onQQMiniGame||Qt.onBLMiniGame||Qt.onTTMiniGame||Qt.onHWMiniGame||Qt.onTBMiniGame}static createElement(t){return Qt.__init__(),Qt._document.createElement(t)}static getElementById(t){return Qt.__init__(),Qt._document.getElementById(t)}static removeElement(t){t&&t.parentNode&&t.parentNode.removeChild(t)}static now(){return Date.now()}static get clientWidth(){return Qt.__init__(),Qt._window.innerWidth||Qt._document.body.clientWidth}static get clientHeight(){return Qt.__init__(),Qt._window.innerHeight||Qt._document.body.clientHeight||Qt._document.documentElement.clientHeight}static get width(){return Qt.__init__(),(i.stage&&i.stage.canvasRotation?Qt.clientHeight:Qt.clientWidth)*Qt.pixelRatio}static get height(){return Qt.__init__(),(i.stage&&i.stage.canvasRotation?Qt.clientWidth:Qt.clientHeight)*Qt.pixelRatio}static get pixelRatio(){return Qt._pixelRatio<0&&(Qt.__init__(),Qt.userAgent.indexOf("Mozilla/6.0(Linux; Android 6.0; HUAWEI NXT-AL10 Build/HUAWEINXT-AL10)")>-1?Qt._pixelRatio=2:(Qt._pixelRatio=Qt._window.devicePixelRatio||1,Qt._pixelRatio<1&&(Qt._pixelRatio=1))),Qt._pixelRatio}static get container(){return Qt._container||(Qt.__init__(),Qt._container=Qt.createElement("div"),Qt._container.id="layaContainer",Qt._document.body.appendChild(Qt._container)),Qt._container}static set container(t){Qt._container=t}static get window(){return Qt._window||Qt.__init__()}static get document(){return Qt.__init__(),Qt._document}}Qt._pixelRatio=-1,Qt.mainCanvas=null,Qt.hanzi=new RegExp("^[一-龥]$"),Qt.fontMap={},Qt.measureText=function(t,e){var i=Qt.hanzi.test(t);if(i&&Qt.fontMap[e])return Qt.fontMap[e];var s=Qt.context;s.font=e;var r=s.measureText(t);return i&&(Qt.fontMap[e]=r),r};class $t extends Zt{constructor(t,e,i=!0,s=!0,r=!1){super(),this.ctx=null,this.lastScaleX=1,this.lastScaleY=1,this.maxTexW=0,this.maxTexH=0,this.scaleFontSize=!0,this.showDbgInfo=!1,this.supportImageData=!0,this.maxTexW=t,this.maxTexH=e,this.scaleFontSize=i,this.supportImageData=s,this.showDbgInfo=r,$t.canvas||($t.canvas=Qt.createElement("canvas"),$t.canvas.width=1024,$t.canvas.height=512,$t.canvas.style.left="-10000px",$t.canvas.style.position="absolute",document.body.appendChild($t.canvas),this.ctx=$t.canvas.getContext("2d"))}get canvasWidth(){return $t.canvas.width}set canvasWidth(t){$t.canvas.width!=t&&($t.canvas.width=t,t>2048&&console.warn("画文字设置的宽度太大,超过2048了"),this.ctx.setTransform(1,0,0,1,0,0),this.ctx.scale(this.lastScaleX,this.lastScaleY))}getWidth(t,e){return this.ctx?(this.ctx._lastFont!=t&&(this.ctx.font=t,this.ctx._lastFont=t),this.ctx.measureText(e).width):0}scale(t,e){if(!this.supportImageData)return this.lastScaleX=t,void(this.lastScaleY=e);this.lastScaleX==t&&this.lastScaleY==e||(this.ctx.setTransform(t,0,0,e,0,0),this.lastScaleX=t,this.lastScaleY=e)}getCharBmp(t,e,i,s,r,a,n,h,o,l,_=null){if(!this.supportImageData)return this.getCharCanvas(t,e,i,s,r,a,n,h,o,l);var u=this.ctx,c=this.fontsz;u.font!=e&&(u.font=e,u._lastFont=e),a.width=u.measureText(t).width;var d=a.width*this.lastScaleX,p=a.height*this.lastScaleY;d+=(n+o)*this.lastScaleX,p+=(h+l)*this.lastScaleY,d=Math.ceil(d),p=Math.ceil(p);var f=(d=Math.min(d,$t.canvas.width))+2*i+1,m=(p=Math.min(p,$t.canvas.height))+2*i+1;_&&(f=Math.max(f,_[0]+_[2]+1),m=Math.max(m,_[1]+_[3]+1)),u.clearRect(0,0,f/this.lastScaleX+1,m/this.lastScaleY+1),u.save(),u.textBaseline="middle",i>0&&(u.strokeStyle=r,u.lineWidth=i,u.strokeText(t,n,h+c/2)),s&&(u.fillStyle=s,u.fillText(t,n,h+c/2)),this.showDbgInfo&&(u.strokeStyle="#ff0000",u.strokeRect(1,1,d-2,p-2),u.strokeStyle="#00ff00",u.strokeRect(n,h,a.width,a.height)),_&&(-1==_[2]&&(_[2]=Math.ceil((a.width+2*i)*this.lastScaleX)),_[2]<=0&&(_[2]=1));var g=_?u.getImageData(_[0],_[1],_[2],_[3]+1):u.getImageData(0,0,d,p+1);return u.restore(),a.bmpWidth=g.width,a.bmpHeight=g.height,g}getCharCanvas(t,e,i,s,r,a,n,h,o,l){var _=this.ctx;_.font!=e&&(_.font=e,_._lastFont=e),a.width=_.measureText(t).width;var u=a.width*this.lastScaleX,c=a.height*this.lastScaleY;u+=(n+o)*this.lastScaleX,c+=(h+l)*this.lastScaleY+1,u=Math.min(u,this.maxTexW),c=Math.min(c,this.maxTexH),$t.canvas.width=Math.min(u+1,this.maxTexW),$t.canvas.height=Math.min(c+1,this.maxTexH),_.font=e,_.clearRect(0,0,u+1+i,c+1+i),_.setTransform(1,0,0,1,0,0),_.save(),this.scaleFontSize&&_.scale(this.lastScaleX,this.lastScaleY),_.translate(n,h),_.textAlign="left";var d=this.fontsz;return _.textBaseline="middle",i>0?(_.strokeStyle=r,_.fillStyle=s,_.lineWidth=i,_.fillAndStrokeText?_.fillAndStrokeText(t,0,d/2):(_.strokeText(t,0,d/2),_.fillText(t,0,d/2))):s&&(_.fillStyle=s,_.fillText(t,0,d/2)),this.showDbgInfo&&(_.strokeStyle="#ff0000",_.strokeRect(0,0,u,c),_.strokeStyle="#00ff00",_.strokeRect(0,0,a.width,a.height)),_.restore(),a.bmpWidth=$t.canvas.width,a.bmpHeight=$t.canvas.height,$t.canvas}}$t.canvas=null;class Jt extends Zt{constructor(){super(),this.lastFont="",this.lastScaleX=1,this.lastScaleY=1}getWidth(t,e){return window.conchTextCanvas?(window.conchTextCanvas.font=t,this.lastFont=t,window.conchTextCanvas.measureText(e).width):0}scale(t,e){this.lastScaleX=t,this.lastScaleY=e}getCharBmp(t,e,i,s,r,a,n,h,o,l,_=null){if(!window.conchTextCanvas)return null;window.conchTextCanvas.font=e,this.lastFont=e;a.width=window.conchTextCanvas.measureText(t).width,a.height;window.conchTextCanvas.scale&&window.conchTextCanvas.scale(this.lastScaleX,this.lastScaleY);var u=J.create(r).numColor,c=J.create(s).numColor,d=window.conchTextCanvas.getTextBitmapData(t,c,i>2?2:i,u);return a.bmpWidth=d.width,a.bmpHeight=d.height,d}}class te{constructor(){this.fontSizeInfo={},this.mapFont={},this.fontID=0,this.fontScaleX=1,this.fontScaleY=1,this._curStrPos=0,this.textAtlases=[],this.isoTextures=[],this.lastFont=null,this.fontSizeW=0,this.fontSizeH=0,this.fontSizeOffX=0,this.fontSizeOffY=0,this.renderPerChar=!0,this.tmpAtlasPos=new f,this.textureMem=0,i.TextAtlas=Xt;var t=!1,e=i.Laya.MiniAdpter;e&&e.systemInfo&&e.systemInfo.system&&(t="ios 10.1.1"===e.systemInfo.system.toLowerCase()),(i.Browser.onMiniGame||i.Browser.onTTMiniGame||i.Browser.onBLMiniGame||i.Browser.onAlipayMiniGame||i.Browser.onTBMiniGame)&&!t&&(te.isWan1Wan=!0),this.charRender=i.Render.isConchApp?new Jt:new $t(2048,2048,te.scaleFontWithCtx,!te.isWan1Wan,!1),te.textRenderInst=this,i.Laya.textRender=this,te.atlasWidth2=te.atlasWidth*te.atlasWidth}setFont(t){if(this.lastFont!=t){this.lastFont=t;var e=this.getFontSizeInfo(t._family),i=e>>24,s=e>>16&255,r=e>>8&255,a=255&e,n=t._size/te.standardFontSize;this.fontSizeOffX=Math.ceil(i*n),this.fontSizeOffY=Math.ceil(s*n),this.fontSizeW=Math.ceil(r*n),this.fontSizeH=Math.ceil(a*n),t._font.indexOf("italic")>=0?this.fontStr=t._font.replace("italic",""):this.fontStr=t._font}}getNextChar(t){var e=t.length,i=this._curStrPos;if(!t.substring)return null;if(i>=e)return null;for(var s=i,r=0;s>>11==27){if(1==r)break;r=1,s++}else if(65038===a||65039===a);else if(8205==a)r=2;else if(0==r)r=1;else if(1==r)break}return this._curStrPos=s,t.substring(i,s)}filltext(t,e,s,r,a,n,h,o,l,_=0){if(!(e.length<=0)){var u=Kt.Parse(a),c=0;switch(l){case"center":c=i.Context.ENUM_TEXTALIGN_CENTER;break;case"right":c=i.Context.ENUM_TEXTALIGN_RIGHT}this._fast_filltext(t,e,null,s,r,u,n,h,o,c,_)}}fillWords(t,e,i,s,r,a,n,h){if(e&&!(e.length<=0)){var o="string"==typeof r?Kt.Parse(r):r;this._fast_filltext(t,null,e,i,s,o,a,n,h,0,0)}}_fast_filltext(t,e,s,r,a,n,h,o,l,_,u=0){if((!e||e.length>=1)&&!(s&&s.length<1)){if(l<0&&(l=0),this.setFont(n),this.fontScaleX=this.fontScaleY=1,te.scaleFontWithCtx){var c=1,d=1;if(i.Render.isConchApp&&!window.conchTextCanvas.scale||(c=t.getMatScaleX(),d=t.getMatScaleY()),c<1e-4||d<.1)return;c>1&&(this.fontScaleX=c),d>1&&(this.fontScaleY=d)}n._italic&&(t._italicDeg=13);var p=e,f=!s&&e instanceof jt,m=e&&e.toString(),g=!!s,T=f?p.pageChars:[],v=0;switch(f?(m=p._text,(v=p.width)<0&&(v=p.width=this.charRender.getWidth(this.fontStr,m))):v=m?this.charRender.getWidth(this.fontStr,m):0,_){case i.Context.ENUM_TEXTALIGN_CENTER:r-=v/2;break;case i.Context.ENUM_TEXTALIGN_RIGHT:r-=v}p&&T&&this.hasFreedText(T)&&(T=p.pageChars=[]);var x=null,y=this.renderPerChar=!f||te.forceSplitRender||g||f&&p.splitRender;if(!T||T.length<1)if(f&&(p.scalex=this.fontScaleX,p.scaley=this.fontScaleY),y){var E,C=0,A=0;for(this._curStrPos=0;;){if(s){var R=s[this._curStrPos++];R?(E=R.char,C=R.x,A=R.y):E=null}else E=this.getNextChar(m);if(!E)break;if(!(x=this.getCharRenderInfo(E,n,h,o,l,!1)))break;if(x.isSpace);else{var b=T[x.tex.id];if(b)b=b.words;else{var S={texgen:x.tex.genID,tex:x.tex,words:new Array};T[x.tex.id]=S,b=S.words}b.push({ri:x,x:C,y:A,w:x.bmpWidth/this.fontScaleX,h:x.bmpHeight/this.fontScaleY}),C+=x.width}}}else{var w=i.Render.isConchApp?0:n._size/3|0,M=te.noAtlas||(v+w+w)*this.fontScaleX>te.atlasWidth;x=this.getCharRenderInfo(m,n,h,o,l,M),T[0]={texgen:x.tex.genID,tex:x.tex,words:[{ri:x,x:0,y:0,w:x.bmpWidth/this.fontScaleX,h:x.bmpHeight/this.fontScaleY}]}}this._drawResortedWords(t,r,a,T),t._italicDeg=0}}_drawResortedWords(t,e,s,r){var a=!!t._charSubmitCache&&t._charSubmitCache._enable,n=t._curMat;for(var h in r){var o=r[h];if(o){var l=o.words,_=l.length;if(!(_<=0))for(var u=r[h].tex,c=0;c<_;c++){var d=l[c],p=d.ri;if(!p.isSpace){if(p.touch(),t.drawTexAlign=!0,i.Render.isConchApp)t._drawTextureM(u.texture,e+d.x-p.orix,s+d.y-p.oriy,d.w,d.h,null,1,p.uv);else{let i=u;t._inner_drawTexture(i.texture,i.id,e+d.x-p.orix,s+d.y-p.oriy,d.w,d.h,n,p.uv,1,a)}t.touches&&t.touches.push(p)}}}}}hasFreedText(t){for(let s in t){var e=t[s];if(e){var i=e.tex;if(i.__destroyed||i.genID!=e.texgen)return!0}}return!1}getCharRenderInfo(t,e,s,r,a,n=!1){var h=this.mapFont[e._family];null==h&&(this.mapFont[e._family]=h=this.fontID++);var o=t+"_"+h+"_"+e._size+"_"+s;a>0&&(o+="_"+r+a),e._bold&&(o+="P"),1==this.fontScaleX&&1==this.fontScaleY||(o+=(20*this.fontScaleX|0)+"_"+(20*this.fontScaleY|0));var l,_,u=0,c=this.textAtlases.length;if(!n)for(u=0;uthis.charRender.canvasWidth&&(this.charRender.canvasWidth=Math.min(2048,f+2*d)),n){if(this.charRender.fontsz=e._size,p=this.charRender.getCharBmp(t,this.fontStr,a,s,r,l,d,d,d,d,null)){var m=Vt.getTextTexture(p.width,p.height);m.addChar(p,0,0,l.uv),l.tex=m,l.orix=d,l.oriy=d,m.ri=l,this.isoTextures.push(m)}}else{var g=t.length,T=1*a,v=Math.ceil((this.fontSizeW+2*T)*this.fontScaleX),x=Math.ceil((this.fontSizeH+2*T)*this.fontScaleY);te.imgdtRect[0]=(d-this.fontSizeOffX-T)*this.fontScaleX|0,te.imgdtRect[1]=(d-this.fontSizeOffY-T)*this.fontScaleY|0,this.renderPerChar||1==g?(te.imgdtRect[2]=Math.max(f,v),te.imgdtRect[3]=Math.max(f,x)):(te.imgdtRect[2]=-1,te.imgdtRect[3]=x),this.charRender.fontsz=e._size,(p=this.charRender.getCharBmp(t,this.fontStr,a,s,r,l,d,d,d,d,te.imgdtRect))&&(_=this.addBmpData(p,l),te.isWan1Wan?(l.orix=d,l.oriy=d):(l.orix=this.fontSizeOffX+T,l.oriy=this.fontSizeOffY+T),_.charMaps[o]=l)}return l}addBmpData(t,e){for(var i,s=t.width,r=t.height,a=this.textAtlases.length,n=!1,h=0;hi&&(te.showLog&&console.log(o.texture.id),o.destroy(),this.textAtlases[t]=this.textAtlases[e-1],e--,t--,a=-1)}for(this.textAtlases.length=e,e=this.isoTextures.length,t=0;tte.destroyUnusedTextureDt&&(h.ri.deleted=!0,h.ri.tex=null,h.destroy(),this.isoTextures[t]=this.isoTextures[e-1],e--,t--);this.isoTextures.length=e;var _=this.textAtlases.length>1&&this.textAtlases.length-s>=2;(te.atlasWidth*te.atlasWidth*4*this.textAtlases.length>te.cleanMem||_||te.simClean)&&(te.simClean=!1,te.showLog&&console.log("清理使用率低的贴图。总使用率:",s,":",this.textAtlases.length,"最差贴图:"+a),a>=0&&((o=this.textAtlases[a]).destroy(),this.textAtlases[a]=this.textAtlases[this.textAtlases.length-1],this.textAtlases.length=this.textAtlases.length-1)),Vt.clean()}cleanAtlases(){}getCharBmp(t){}checkBmpLine(t,e,i,s){this.bmpData32.buffer!=t.data.buffer&&(this.bmpData32=new Uint32Array(t.data.buffer));for(var r=t.width*e+i,a=i;a=n){e[1]=o;break}this.checkBmpLine(t,o,0,s)?n=o:h=o}if(e[3]>r)e[3]=r;else if(o=n=e[3],h=r,this.checkBmpLine(t,n,0,s))for(;;){if((o=(n+h)/2|0)-1<=n){e[3]=o;break}this.checkBmpLine(t,o,0,s)?n=o:h=o}if(!i){var l=e[0],_=s*e[1];for(o=e[1];o>24,s=e>>16&255,r=e>>8&255,a=255&e;console.log(" "+t," off:",i,s," size:",r,a)}var n=0;console.log("缓存数据:");var h=0,o=0;this.textAtlases.forEach((function(t){var e=t.texture.id,i=Et.loopCount-t.texture.lastTouchTm,s=i>0?i+"帧以前":"当前帧";for(var r in h+=t.texture.curUsedCovRate,o+=t.texture.curUsedCovRateAtlas,console.log("--图集(id:"+e+",当前使用率:"+(1e3*t.texture.curUsedCovRate|0)+"‰","当前图集使用率:",(100*t.texture.curUsedCovRateAtlas|0)+"%","图集使用率:",100*t.usedRate|0,"%, 使用于:"+s+")--:"),t.charMaps){var a=t.charMaps[r];console.log(" off:",a.orix,a.oriy," bmp宽高:",a.bmpWidth,a.bmpHeight,"无效:",a.deleted,"touchdt:",Et.loopCount-a.touchTick,"位置:",a.uv[0]*te.atlasWidth|0,a.uv[1]*te.atlasWidth|0,"字符:",a.char,"key:",r),n++}})),console.log("独立贴图文字("+this.isoTextures.length+"个):"),this.isoTextures.forEach((function(t){console.log(" size:",t._texW,t._texH,"touch间隔:",Et.loopCount-t.lastTouchTm,"char:",t.ri.char)})),console.log("总缓存:",n,"总使用率:",h,"总当前图集使用率:",o)}showAtlas(t,e,s,r,a,n){if(!this.textAtlases[t])return console.log("没有这个图集"),null;var h=new i.Sprite,o=this.textAtlases[t].texture,l={width:te.atlasWidth,height:te.atlasWidth,sourceWidth:te.atlasWidth,sourceHeight:te.atlasWidth,offsetX:0,offsetY:0,getIsReady:function(){return!0},_addReference:function(){},_removeReference:function(){},_getSource:function(){return o._getSource()},bitmap:{id:o.id},_uv:zt.DEF_UV};return h.size=function(t,i){return this.width=t,this.height=i,h.graphics.clear(),h.graphics.drawRect(0,0,h.width,h.height,e),h.graphics.drawTexture(l,0,0,h.width,h.height),this},h.graphics.drawRect(0,0,a,n,e),h.graphics.drawTexture(l,0,0,a,n),h.pos(s,r),i.stage.addChild(h),h}filltext_native(t,e,s,r,a,n,h,o,l,_,u=0){if(!(e&&e.length<=0||s&&s.length<1)){var c=Kt.Parse(n),d=0;switch(_){case"center":d=i.Context.ENUM_TEXTALIGN_CENTER;break;case"right":d=i.Context.ENUM_TEXTALIGN_RIGHT}return this._fast_filltext(t,e,s,r,a,c,h,o,l,d,u)}}}te.useOldCharBook=!1,te.atlasWidth=1024,te.noAtlas=!1,te.forceSplitRender=!1,te.forceWholeRender=!1,te.scaleFontWithCtx=!0,te.standardFontSize=32,te.destroyAtlasDt=10,te.checkCleanTextureDt=2e3,te.destroyUnusedTextureDt=3e3,te.cleanMem=104857600,te.isWan1Wan=!1,te.showLog=!1,te.debugUV=!1,te.tmpRI=new qt,te.pixelBBX=[0,0,0,0],te.imgdtRect=[0,0,0,0],te.simClean=!1,Vt.gTextRender=te;class ee{constructor(){if(this._tmpMatrix=new p,this._drawTexToDrawTri_Vert=new Float32Array(8),this._drawTexToDrawTri_Index=new Uint16Array([0,1,2,0,2,3]),this._tempUV=new Float32Array(8),this._drawTriUseAbsMatrix=!1,this._id=++ee._COUNT,this._other=null,this._renderNextSubmitIndex=0,this._path=null,this._drawCount=1,this._width=ee._MAXSIZE,this._height=ee._MAXSIZE,this._renderCount=0,this._submits=null,this._curSubmit=null,this._submitKey=new q,this._pathMesh=null,this._triangleMesh=null,this.meshlist=[],this._transedPoints=new Array(8),this._temp4Points=new Array(8),this._clipRect=ee.MAXCLIPRECT,this._globalClipMatrix=new p(ee._MAXSIZE,0,0,ee._MAXSIZE,0,0),this._clipInCache=!1,this._clipInfoID=0,this._clipID_Gen=0,this._lastMatScaleX=1,this._lastMatScaleY=1,this._lastMat_a=1,this._lastMat_b=0,this._lastMat_c=0,this._lastMat_d=1,this._nBlendType=0,this._save=null,this._targets=null,this._charSubmitCache=null,this._saveMark=null,this._shader2D=new Pt,this.sprite=null,this._italicDeg=0,this._lastTex=null,this._fillColor=0,this._flushCnt=0,this.defTexture=null,this._colorFiler=null,this.drawTexAlign=!1,this._incache=!1,this.isMain=!1,ee._contextcount++,ee._textRender=ee._textRender||new te,!this.defTexture){var t=new O(2,2);t.setPixels(new Uint8Array(16)),t.lock=!0,this.defTexture=new zt(t)}this._lastTex=this.defTexture,this.clear()}static __init__(){ee.MAXCLIPRECT=new m(0,0,ee._MAXSIZE,ee._MAXSIZE),ie.DEFAULT=new ie}drawImage(...t){}getImageData(...t){}measureText(t){return null}setTransform(...t){}$transform(t,e,i,s,r,a){}get lineJoin(){return""}set lineJoin(t){}get lineCap(){return""}set lineCap(t){}get miterLimit(){return""}set miterLimit(t){}clearRect(t,e,i,s){}_drawRect(t,e,i,s,r){X.renderBatches++,r&&(this.fillStyle=r),this.fillRect(t,e,i,s,null)}drawTexture2(t,e,i,s,r,a){}transformByMatrix(t,e,i){this.transform(t.a,t.b,t.c,t.d,t.tx+e,t.ty+i)}saveTransform(t){this.save()}restoreTransform(t){this.restore()}drawRect(t,e,i,s,r,a,n){null!=r&&(this.fillStyle=r,this.fillRect(t,e,i,s)),null!=a&&(this.strokeStyle=a,this.lineWidth=n,this.strokeRect(t,e,i,s))}alpha(t){this.globalAlpha*=t}_transform(t,e,i){this.translate(e,i),this.transform(t.a,t.b,t.c,t.d,t.tx,t.ty),this.translate(-e,-i)}_rotate(t,e,i){this.translate(e,i),this.rotate(t),this.translate(-e,-i)}_scale(t,e,i,s){this.translate(i,s),this.scale(t,e),this.translate(-i,-s)}_drawLine(t,e,i,s,r,a,n,h,o){this.beginPath(),this.strokeStyle=n,this.lineWidth=h,this.moveTo(t+i,e+s),this.lineTo(t+r,e+a),this.stroke()}_drawLines(t,e,i,s,r,a){this.beginPath(),this.strokeStyle=s,this.lineWidth=r,this.addPath(i.slice(),!1,!1,t,e),this.stroke()}drawCurves(t,e,i,s,r){this.beginPath(),this.strokeStyle=s,this.lineWidth=r,this.moveTo(t+i[0],e+i[1]);for(var a=2,n=i.length;a0&&(this.strokeStyle=e,this.lineWidth=i,this.stroke())}_drawCircle(t,e,i,s,r,a,n){X.renderBatches++,this.beginPath(!0),this.arc(t,e,i,0,ee.PI2),this.closePath(),this._fillAndStroke(s,r,a)}_drawPie(t,e,i,s,r,a,n,h,o){this.beginPath(),this.moveTo(t,e),this.arc(t,e,i,s,r),this.closePath(),this._fillAndStroke(a,n,h)}_drawPoly(t,e,i,s,r,a,n,h){this.beginPath(),this.addPath(i.slice(),!0,n,t,e),this.closePath(),this._fillAndStroke(s,r,a,n)}_drawPath(t,e,i,s,r){this.beginPath();for(var a=0,n=i.length;a=0;i--){var s=this._save[i];if(s.restore(this),s.isSaveMark())return void(this._save._length=i)}e!=this._nBlendType&&(this._curSubmit=dt.RENDERBASE)}}set font(t){this._other=this._other.make(),pt.save(this,pt.TYPE_FONT,this._other,!1)}fillText(t,e,i,s,r,a,n=0,h=""){ee._textRender.filltext(this,t,e,i,s,r,h,n,a)}drawText(t,e,i,s,r,a){ee._textRender.filltext(this,t,e,i,s,r,null,0,a)}fillWords(t,e,i,s,r){ee._textRender.fillWords(this,t,e,i,s,r,null,0)}strokeWord(t,e,i,s,r,a,n){ee._textRender.filltext(this,t,e,i,s,null,r,a,n)}fillBorderText(t,e,i,s,r,a,n,h){ee._textRender.filltext(this,t,e,i,s,r,a,n,h)}fillBorderWords(t,e,i,s,r,a,n){ee._textRender.fillWords(this,t,e,i,s,r,a,n)}_fast_filltext(t,e,i,s,r,a,n,h,o=0){ee._textRender._fast_filltext(this,t,null,e,i,s,r,a,n,h,o)}_fillRect(t,e,i,s,r){var a=this._curSubmit,n=a&&a._key.submitType===dt.KEY_DRAWTEXTURE&&a._key.blendShader===this._nBlendType;this._mesh.vertNum+4>ee._MAXVERTNUM&&(this._mesh=St.getAMesh(this.isMain),this.meshlist.push(this._mesh),n=!1),n&&(n=n&&this.isSameClipInfo(a)),this.transformQuad(t,e,i,s,0,this._curMat,this._transedPoints),this.clipedOff(this._transedPoints)||(this._mesh.addQuad(this._transedPoints,zt.NO_UV,r,!1),n||(a=this._curSubmit=kt.create(this,this._mesh,j.create(V.TEXTURE2D,0)),this._submits[this._submits._length++]=a,this._copyClipInfo(a,this._globalClipMatrix),a.shaderValue.textureHost=this._lastTex,a._key.other=this._lastTex&&this._lastTex.bitmap?this._lastTex.bitmap.id:-1,a._renderType=dt.TYPE_TEXTURE),this._curSubmit._numEle+=6,this._mesh.indexNum+=6,this._mesh.vertNum+=4)}fillRect(t,e,i,s,r){var a=r?_t.create(r):this._shader2D.fillStyle,n=this.mixRGBandAlpha(a.toInt());this._fillRect(t,e,i,s,n)}fillTexture(t,e,s,r,a,n,h,o){t._getSource()?this._fillTexture(t,t.width,t.height,t.uvrect,e,s,r,a,n,h.x,h.y):this.sprite&&i.systemTimer.callLater(this,this._repaintSprite)}_fillTexture(t,e,i,s,r,a,n,h,o,l,_){var u=this._curSubmit;this._mesh.vertNum+4>ee._MAXVERTNUM&&(this._mesh=St.getAMesh(this.isMain),this.meshlist.push(this._mesh));var c=!0,d=!0;switch(o){case"repeat":break;case"repeat-x":d=!1;break;case"repeat-y":c=!1;break;case"no-repeat":c=d=!1}var p=this._temp4Points,f=0,m=0,g=0,T=0,v=0,x=0;if(l<0?(g=r,f=-l%e/e):g=r+l,_<0?(T=a,m=-_%i/i):T=a+_,v=r+n,x=a+h,!c&&(v=Math.min(v,r+l+e)),!d&&(x=Math.min(x,a+_+i)),!(vv||T>x)){var y=(v-r-l)/e,E=(x-a-_)/i;if(this.transformQuad(g,T,v-g,x-T,0,this._curMat,this._transedPoints),p[0]=f,p[1]=m,p[2]=y,p[3]=m,p[4]=y,p[5]=E,p[6]=f,p[7]=E,!this.clipedOff(this._transedPoints)){var C=this._mixRGBandAlpha(4294967295,this._shader2D.ALPHA);this._mesh.addQuad(this._transedPoints,p,C,!0);var A=j.create(V.TEXTURE2D,0);A.defines.add(V.FILLTEXTURE),A.u_TexRange=s.concat(),u=this._curSubmit=kt.create(this,this._mesh,A),this._submits[this._submits._length++]=u,this._copyClipInfo(u,this._globalClipMatrix),u.shaderValue.textureHost=t,u._renderType=dt.TYPE_TEXTURE,this._curSubmit._numEle+=6,this._mesh.indexNum+=6,this._mesh.vertNum+=4}this.breakNextMerge()}}setColorFilter(t){pt.save(this,pt.TYPE_COLORFILTER,this,!0),this._colorFiler=t,this._curSubmit=dt.RENDERBASE}drawTexture(t,e,i,s,r){this._drawTextureM(t,e,i,s,r,null,1,null)}drawTextures(t,e,s,r){if(t._getSource())for(var a=e.length/2,n=0,h=t.bitmap.id,o=0;oee._MAXVERTNUM&&(this._mesh=St.getAMesh(this.isMain),this.meshlist.push(this._mesh));var i=kt.create(this,this._mesh,j.create(V.TEXTURE2D,0));this._submits[this._submits._length++]=this._curSubmit=i,i.shaderValue.textureHost=t,this._copyClipInfo(i,this._globalClipMatrix)}_drawTexRect(t,e,i,s,r){this.transformQuad(t,e,i,s,this._italicDeg,this._curMat,this._transedPoints);var a=this._transedPoints;a[0]=a[0]+.5|0,a[1]=a[1]+.5|0,a[2]=a[2]+.5|0,a[3]=a[3]+.5|0,a[4]=a[4]+.5|0,a[5]=a[5]+.5|0,a[6]=a[6]+.5|0,a[7]=a[7]+.5|0,this.clipedOff(this._transedPoints)||(this._mesh.addQuad(this._transedPoints,r,this._fillColor,!0),this._curSubmit._numEle+=6,this._mesh.indexNum+=6,this._mesh.vertNum+=4)}drawCallOptimize(t){return this._charSubmitCache.enable(t,this),t}_inner_drawTexture(t,e,i,s,r,a,n,h,o,l){if(r<=0||a<=0)return!1;var _=this._curSubmit._key;if(h=h||t._uv,_.submitType===dt.KEY_TRIANGLES&&_.other===e){var u=this._drawTexToDrawTri_Vert;u[0]=i,u[1]=s,u[2]=i+r,u[3]=s,u[4]=i+r,u[5]=s+a,u[6]=i,u[7]=s+a,this._drawTriUseAbsMatrix=!0;var c=this._tempUV;return c[0]=h[0],c[1]=h[1],c[2]=h[2],c[3]=h[3],c[4]=h[4],c[5]=h[5],c[6]=h[6],c[7]=h[7],this.drawTriangles(t,0,0,u,c,this._drawTexToDrawTri_Index,n,o,null,null),this._drawTriUseAbsMatrix=!1,!0}var d=this._mesh,p=this._curSubmit,f=l?this._charSubmitCache.getPos():this._transedPoints;if(this.transformQuad(i,s,r||t.width,a||t.height,this._italicDeg,n||this._curMat,f),this.drawTexAlign){var m=Math.round;f[0]=m(f[0]),f[1]=m(f[1]),f[2]=m(f[2]),f[3]=m(f[3]),f[4]=m(f[4]),f[5]=m(f[5]),f[6]=m(f[6]),f[7]=m(f[7]),this.drawTexAlign=!1}var g=this._mixRGBandAlpha(4294967295,this._shader2D.ALPHA*o);if(l)return this._charSubmitCache.add(this,t,e,f,h,g),!0;this._drawCount++;var T=e>=0&&_.submitType===dt.KEY_DRAWTEXTURE&&_.other===e;return T&&(T=T&&this.isSameClipInfo(p)),this._lastTex=t,d.vertNum+4>ee._MAXVERTNUM&&(d=this._mesh=St.getAMesh(this.isMain),this.meshlist.push(d),T=!1),d.addQuad(f,h,g,!0),T||(this._submits[this._submits._length++]=this._curSubmit=p=kt.create(this,d,j.create(V.TEXTURE2D,0)),p.shaderValue.textureHost=t,p._key.other=e,this._copyClipInfo(p,this._globalClipMatrix)),p._numEle+=6,d.indexNum+=6,d.vertNum+=4,!0}transform4Points(t,e,i){var s=e.tx,r=e.ty,a=e.a,n=e.b,h=e.c,o=e.d,l=t[0],_=t[1],u=t[2],c=t[3],d=t[4],p=t[5],f=t[6],m=t[7];e._bTransform?(i[0]=l*a+_*h+s,i[1]=l*n+_*o+r,i[2]=u*a+c*h+s,i[3]=u*n+c*o+r,i[4]=d*a+p*h+s,i[5]=d*n+p*o+r,i[6]=f*a+m*h+s,i[7]=f*n+m*o+r):(i[0]=l+s,i[1]=_+r,i[2]=u+s,i[3]=c+r,i[4]=d+s,i[5]=p+r,i[6]=f+s,i[7]=m+r)}clipedOff(t){return this._clipRect.width<=0||this._clipRect.height<=0}transformQuad(t,e,i,s,r,a,n){var h=0;0!=r&&(h=Math.tan(r*Math.PI/180)*s);var o=t+i,l=e+s,_=a.tx,u=a.ty,c=a.a,d=a.b,p=a.c,f=a.d,m=t+h,g=e,T=o+h,v=e,x=o,y=l,E=t,C=l;a._bTransform?(n[0]=m*c+g*p+_,n[1]=m*d+g*f+u,n[2]=T*c+v*p+_,n[3]=T*d+v*f+u,n[4]=x*c+y*p+_,n[5]=x*d+y*f+u,n[6]=E*c+C*p+_,n[7]=E*d+C*f+u):(n[0]=m+_,n[1]=g+u,n[2]=T+_,n[3]=v+u,n[4]=x+_,n[5]=y+u,n[6]=E+_,n[7]=C+u)}pushRT(){this.addRenderObject(Z.create(null,G.pushRT,this))}popRT(){this.addRenderObject(Z.create(null,G.popRT,this)),this.breakNextMerge()}useRT(t){this.addRenderObject(Z.create([t],(function(t){if(!t)throw"error useRT";t.start(),t.clear(0,0,0,0)}),this)),this.breakNextMerge()}RTRestore(t){this.addRenderObject(Z.create([t],(function(t){t.restore()}),this)),this.breakNextMerge()}breakNextMerge(){this._curSubmit=dt.RENDERBASE}_repaintSprite(){this.sprite&&this.sprite.repaint()}drawTextureWithTransform(t,e,i,s,r,a,n,h,o,l,_=null,u){var c,d=this._curMat;l&&(c=this.globalCompositeOperation,this.globalCompositeOperation=l);var f=this._colorFiler;if(_&&this.setColorFilter(_),!a)return this._drawTextureM(t,e+n,i+h,s,r,d,o,u),l&&(this.globalCompositeOperation=c),void(_&&this.setColorFilter(f));var m=this._tmpMatrix;m.a=a.a,m.b=a.b,m.c=a.c,m.d=a.d,m.tx=a.tx+n,m.ty=a.ty+h,m._bTransform=a._bTransform,a&&d._bTransform?(p.mul(m,d,m),(a=m)._bTransform=!0):(m.tx+=d.tx,m.ty+=d.ty,a=m),this._drawTextureM(t,e,i,s,r,a,o,u),l&&(this.globalCompositeOperation=c),_&&this.setColorFilter(f)}_flushToTarget(t,e){U.worldScissorTest=!1;var i=g.instance;i.disable(i.SCISSOR_TEST);var s=U.worldAlpha,r=U.worldMatrix4,a=U.worldMatrix;U.worldMatrix=p.EMPTY,U.restoreTempArray(),U.worldMatrix4=U.TEMPMAT4_ARRAY,U.worldAlpha=1,N.activeShader=null,e.start(),t._submits._length>0&&e.clear(0,0,0,0),t._curSubmit=dt.RENDERBASE,t.flush(),t.clear(),e.restore(),t._curSubmit=dt.RENDERBASE,N.activeShader=null,U.worldAlpha=s,U.worldMatrix4=r,U.worldMatrix=a}drawCanvas(t,e,i,s,r){if(t){var a,n=t.context;if(n._targets)n._submits._length>0&&(a=Z.create([n,n._targets],this._flushToTarget,this),this._submits[this._submits._length++]=a),this._drawRenderTexture(n._targets,e,i,s,r,null,1,G.flipyuv),this._curSubmit=dt.RENDERBASE;else{var h=t;h.touches&&h.touches.forEach((function(t){t.touch()})),a=Ut.create(t,this._shader2D.ALPHA,this._shader2D.filters),this._submits[this._submits._length++]=a,a._key.clear();var o=a._matrix;this._curMat.copyTo(o);var l=o.tx,_=o.ty;o.tx=o.ty=0,o.transformPoint(f.TEMP.setTo(e,i)),o.translate(f.TEMP.x+l,f.TEMP.y+_),p.mul(h.invMat,o,o),this._curSubmit=dt.RENDERBASE}}}drawTarget(t,e,i,s,r,a,n,h=null,o=-1){if(this._drawCount++,this._mesh.vertNum+4>ee._MAXVERTNUM&&(this._mesh=St.getAMesh(this.isMain),this.meshlist.push(this._mesh)),this.transformQuad(e,i,s,r,0,a||this._curMat,this._transedPoints),!this.clipedOff(this._transedPoints)){this._mesh.addQuad(this._transedPoints,h||zt.DEF_UV,4294967295,!0);var l=this._curSubmit=Gt.create(this,this._mesh,n,t);return l.blendType=-1==o?this._nBlendType:o,this._copyClipInfo(l,this._globalClipMatrix),l._numEle=6,this._mesh.indexNum+=6,this._mesh.vertNum+=4,this._submits[this._submits._length++]=l,this._curSubmit=dt.RENDERBASE,!0}return this._curSubmit=dt.RENDERBASE,!1}drawTriangles(t,e,s,r,a,n,h,o,l,_,u=4294967295){if(t._getSource()){var c=null;_&&(c=this.globalCompositeOperation,this.globalCompositeOperation=_),this._drawCount++;var d=this._tmpMatrix,f=this._triangleMesh,m=null,g=!1;l&&(m=this._colorFiler,this._colorFiler=l,this._curSubmit=dt.RENDERBASE,g=m!=l);var T=t.bitmap,v=this._curSubmit._key,x=v.submitType===dt.KEY_TRIANGLES&&v.other===T.id&&v.blendShader==this._nBlendType;if(f.vertNum+r.length/2>ee._MAXVERTNUM&&(f=this._triangleMesh=wt.getAMesh(this.isMain),this.meshlist.push(f),x=!1),!x){var y=this._curSubmit=kt.create(this,f,j.create(V.TEXTURE2D,0));y.shaderValue.textureHost=t,y._renderType=dt.TYPE_TEXTURE,y._key.submitType=dt.KEY_TRIANGLES,y._key.other=T.id,this._copyClipInfo(y,this._globalClipMatrix),this._submits[this._submits._length++]=y}var E=this._mixRGBandAlpha(u,this._shader2D.ALPHA*o);this._drawTriUseAbsMatrix?f.addData(r,a,n,h,E):(h?(d.a=h.a,d.b=h.b,d.c=h.c,d.d=h.d,d.tx=h.tx+e,d.ty=h.ty+s):(d.a=1,d.b=0,d.c=0,d.d=1,d.tx=e,d.ty=s),p.mul(d,this._curMat,d),f.addData(r,a,n,d||this._curMat,E)),this._curSubmit._numEle+=n.length,g&&(this._colorFiler=m,this._curSubmit=dt.RENDERBASE),_&&(this.globalCompositeOperation=c)}else this.sprite&&i.systemTimer.callLater(this,this._repaintSprite)}transform(t,e,i,s,r,a){gt.save(this),p.mul(p.TEMP.setTo(t,e,i,s,r,a),this._curMat,this._curMat),this._curMat._checkTransform()}_transformByMatrix(t,e,i){t.setTranslate(e,i),p.mul(t,this._curMat,this._curMat),t.setTranslate(0,0),this._curMat._bTransform=!0}setTransformByMatrix(t){t.copyTo(this._curMat)}rotate(t){gt.save(this),this._curMat.rotateEx(t)}scale(t,e){gt.save(this),this._curMat.scaleEx(t,e)}clipRect(t,e,i,s){ft.save(this),this._clipRect==ee.MAXCLIPRECT?this._clipRect=new m(t,e,i,s):(this._clipRect.width=i,this._clipRect.height=s,this._clipRect.x=t,this._clipRect.y=e),this._clipID_Gen++,this._clipID_Gen%=1e4,this._clipInfoID=this._clipID_Gen;var r=this._globalClipMatrix,a=r.tx,n=r.ty,h=a+r.a,o=n+r.d;if(this._clipRect.width>=ee._MAXSIZE?(r.a=r.d=ee._MAXSIZE,r.b=r.c=r.tx=r.ty=0):(this._curMat._bTransform?(r.tx=this._clipRect.x*this._curMat.a+this._clipRect.y*this._curMat.c+this._curMat.tx,r.ty=this._clipRect.x*this._curMat.b+this._clipRect.y*this._curMat.d+this._curMat.ty,r.a=this._clipRect.width*this._curMat.a,r.b=this._clipRect.width*this._curMat.b,r.c=this._clipRect.height*this._curMat.c,r.d=this._clipRect.height*this._curMat.d):(r.tx=this._clipRect.x+this._curMat.tx,r.ty=this._clipRect.y+this._curMat.ty,r.a=this._clipRect.width,r.b=r.c=0,r.d=this._clipRect.height),this._incache&&(this._clipInCache=!0)),r.a>0&&r.d>0){var l=r.tx+r.a,_=r.ty+r.d;l<=a||_<=n||r.tx>=h||r.ty>=o?(r.a=-.1,r.d=-.1):(r.txh&&(r.a-=l-h),r.tyo&&(r.d-=_-o),r.a<=0&&(r.a=-.1),r.d<=0&&(r.d=-.1))}}drawMesh(t,e,i,s,r,a,n,h,o=0){}addRenderObject(t){this._submits[this._submits._length++]=t}submitElement(t,e){this.isMain;var i=this._submits,s=i._length;e<0&&(e=i._length);for(var r=dt.RENDERBASE;tee._MAXVERTNUM&&(this._curSubmit._numEle+=n,n=0,this._pathMesh=Mt.getAMesh(this.isMain),this._curSubmit=this.addVGSubmit(this._pathMesh));var g=this._pathMesh.vertNum;if(l.convex){var T=_-2;r=new Array(3*T);for(var v=0,x=0;x0)for(var y=0;y0){var t=this.mixRGBandAlpha(this.strokeStyle._color.numColor),e=this._getPath(),i=this._curSubmit,s=i._key.submitType===dt.KEY_VG&&i._key.blendShader===this._nBlendType;s&&(s=s&&this.isSameClipInfo(i)),s||(this._curSubmit=this.addVGSubmit(this._pathMesh));for(var r=0,a=0,n=e.paths.length;aee._MAXVERTNUM&&(this._curSubmit._numEle+=r,r=0,this._pathMesh=Mt.getAMesh(this.isMain),this.meshlist.push(this._pathMesh),this._curSubmit=this.addVGSubmit(this._pathMesh)),Dt.createLine2(h.path,o,this.lineWidth,this._pathMesh.vertNum,l,h.loop);var u,c,d,p,f=l.length/2,m=this._curMat,g=0;if(m._bTransform)for(g=0;g=0){var D=2*R/ee.SEGNUM;P=Math.sin(D),L=Math.cos(D)}else D=2*-R/ee.SEGNUM,P=Math.sin(D),L=Math.cos(D);var B=this._path._lastOriX,F=this._path._lastOriY,O=b,N=S;(Math.abs(O-this._path._lastOriX)>.1||Math.abs(N-this._path._lastOriY)>.1)&&(n=O,h=N,B=O,F=N,this._path._lastOriX=n,this._path._lastOriY=h,this._path.addPoint(n,h));var U=b-M,G=S-I;for(a=0;a.1||Math.abs(F-h)>.1)&&(this._path._lastOriX=n,this._path._lastOriY=h,this._path.addPoint(n,h),B=n,F=h),U=k,G=W}}}}}arc(t,e,i,s,r,a=!1,n=!0){var h,o,l=0,_=0,u=0,c=0,d=0;if(_=r-s,a)if(Math.abs(_)>=2*Math.PI)_=2*-Math.PI;else for(;_>0;)_-=2*Math.PI;else if(Math.abs(_)>=2*Math.PI)_=2*Math.PI;else for(;_<0;)_+=2*Math.PI;var p=this.getMatScaleX(),f=this.getMatScaleY(),m=i*(p>f?p:f),g=2*Math.PI*m;o=0|Math.max(g/10,10);var T=this._getPath();for(h=0;h<=o;h++)l=s+_*(h/o),u=Math.cos(l),d=e+Math.sin(l)*i,(c=t+u*i)==this._path._lastOriX&&d==this._path._lastOriY||T.addPoint(c,d);u=Math.cos(r),d=e+Math.sin(r)*i,(c=t+u*i)==this._path._lastOriX&&d==this._path._lastOriY||T.addPoint(c,d)}quadraticCurveTo(t,e,i,s){for(var r=ot.I.getBezierPoints([this._path._lastOriX,this._path._lastOriY,t,e,i,s],30,2),a=0,n=r.length/2;a=1)return t;var i=(4278190080&t)>>>24;return 0!=i?i*=e:i=255*e,16777215&t|i<<24}strokeRect(t,e,i,s,r){if(this.lineWidth>0){var a=this.mixRGBandAlpha(this.strokeStyle._color.numColor),n=this.lineWidth/2;this._fillRect(t-n,e-n,i+this.lineWidth,this.lineWidth,a),this._fillRect(t-n,e-n+s,i+this.lineWidth,this.lineWidth,a),this._fillRect(t-n,e+n,this.lineWidth,s-this.lineWidth,a),this._fillRect(t-n+i,e+n,this.lineWidth,s-this.lineWidth,a)}}clip(){}drawParticle(t,e,i){i.x=t,i.y=e,this._submits[this._submits._length++]=i}_getPath(){return this._path||(this._path=new ut)}get canvas(){return this._canvas}_fillTexture_h(t,e,i,s,r,a,n,h){s<=0&&console.error("_fillTexture_h error: oriw must>0");for(var o=a,l=Math.floor(h/s),_=h%s,u=0;u0){var c=i[2]-i[0],d=i[0]+c*(_/s),p=ee.tmpuv1;p[0]=i[0],p[1]=i[1],p[2]=d,p[3]=i[3],p[4]=d,p[5]=i[5],p[6]=i[6],p[7]=i[7],this._inner_drawTexture(t,e,o,n,_,r,this._curMat,p,1,!1)}}_fillTexture_v(t,e,i,s,r,a,n,h){r<=0&&console.error("_fillTexture_v error: orih must>0");for(var o=n,l=Math.floor(h/r),_=h%r,u=0;u0){var c=i[7]-i[1],d=i[1]+c*(_/r),p=ee.tmpuv1;p[0]=i[0],p[1]=i[1],p[2]=i[2],p[3]=i[3],p[4]=i[4],p[5]=d,p[6]=i[6],p[7]=d,this._inner_drawTexture(t,e,a,o,s,_,this._curMat,p,1,!1)}}drawTextureWithSizeGrid(t,e,i,s,r,a,n,h){if(t._getSource()){e+=n,i+=h;var o=t.uv,l=t.bitmap.width,_=t.bitmap.height,u=a[0],c=a[3],d=a[1],p=a[2],f=a[4],m=!1;s==l&&(c=d=0),r==_&&(u=p=0);var g=u/_,T=c/l,v=d/l,x=p/_;if(c+d>s){var y=s;m=!0,s=c+d,this.save(),this.clipRect(0+e,0+i,y,r)}var E=t.bitmap.id,C=this._curMat,A=this._tempUV,R=o[0],b=o[1],S=o[4],w=o[5],M=R,I=b,P=S,L=w;if(c&&u&&(P=R+T,L=b+g,A[0]=R,A[1]=b,A[2]=P,A[3]=b,A[4]=P,A[5]=L,A[6]=R,A[7]=L,this._inner_drawTexture(t,E,e,i,c,u,C,A,1,!1)),d&&u&&(M=S-v,I=b,P=S,L=b+g,A[0]=M,A[1]=I,A[2]=P,A[3]=I,A[4]=P,A[5]=L,A[6]=M,A[7]=L,this._inner_drawTexture(t,E,s-d+e,0+i,d,u,C,A,1,!1)),c&&p&&(M=R,I=w-x,P=R+T,L=w,A[0]=M,A[1]=I,A[2]=P,A[3]=I,A[4]=P,A[5]=L,A[6]=M,A[7]=L,this._inner_drawTexture(t,E,0+e,r-p+i,c,p,C,A,1,!1)),d&&p&&(M=S-v,I=w-x,P=S,L=w,A[0]=M,A[1]=I,A[2]=P,A[3]=I,A[4]=P,A[5]=L,A[6]=M,A[7]=L,this._inner_drawTexture(t,E,s-d+e,r-p+i,d,p,C,A,1,!1)),u&&(M=R+T,I=b,P=S-v,L=b+g,A[0]=M,A[1]=I,A[2]=P,A[3]=I,A[4]=P,A[5]=L,A[6]=M,A[7]=L,f?this._fillTexture_h(t,E,A,t.width-c-d,u,c+e,i,s-c-d):this._inner_drawTexture(t,E,c+e,i,s-c-d,u,C,A,1,!1)),p&&(M=R+T,I=w-x,P=S-v,L=w,A[0]=M,A[1]=I,A[2]=P,A[3]=I,A[4]=P,A[5]=L,A[6]=M,A[7]=L,f?this._fillTexture_h(t,E,A,t.width-c-d,p,c+e,r-p+i,s-c-d):this._inner_drawTexture(t,E,c+e,r-p+i,s-c-d,p,C,A,1,!1)),c&&(M=R,I=b+g,P=R+T,L=w-x,A[0]=M,A[1]=I,A[2]=P,A[3]=I,A[4]=P,A[5]=L,A[6]=M,A[7]=L,f?this._fillTexture_v(t,E,A,c,t.height-u-p,e,u+i,r-u-p):this._inner_drawTexture(t,E,e,u+i,c,r-u-p,C,A,1,!1)),d&&(M=S-v,I=b+g,P=S,L=w-x,A[0]=M,A[1]=I,A[2]=P,A[3]=I,A[4]=P,A[5]=L,A[6]=M,A[7]=L,f?this._fillTexture_v(t,E,A,d,t.height-u-p,s-d+e,u+i,r-u-p):this._inner_drawTexture(t,E,s-d+e,u+i,d,r-u-p,C,A,1,!1)),M=R+T,I=b+g,P=S-v,L=w-x,A[0]=M,A[1]=I,A[2]=P,A[3]=I,A[4]=P,A[5]=L,A[6]=M,A[7]=L,f){var D=ee.tmpUVRect;D[0]=M,D[1]=I,D[2]=P-M,D[3]=L-I,this._fillTexture(t,t.width-c-d,t.height-u-p,D,c+e,u+i,s-c-d,r-u-p,"repeat",0,0)}else this._inner_drawTexture(t,E,c+e,u+i,s-c-d,r-u-p,C,A,1,!1);m&&this.restore()}}}ee.ENUM_TEXTALIGN_DEFAULT=0,ee.ENUM_TEXTALIGN_CENTER=1,ee.ENUM_TEXTALIGN_RIGHT=2,ee._SUBMITVBSIZE=32e3,ee._MAXSIZE=99999999,ee._MAXVERTNUM=65535,ee.MAXCLIPRECT=null,ee._COUNT=0,ee.SEGNUM=32,ee._contextcount=0,ee.PI2=2*Math.PI,ee._textRender=null,ee.tmpuv1=[0,0,0,0,0,0,0,0],ee.tmpUV=[0,0,0,0,0,0,0,0],ee.tmpUVRect=[0,0,0,0];class ie{constructor(){this.lineWidth=1}clear(){this.lineWidth=1,this.textAlign=this.textBaseline=null}make(){return this===ie.DEFAULT?new ie:this}}class se{static _uint8ArraySlice(){for(var t=this.length,e=new Uint8Array(this.length),i=0;ir)for(e=a-r,i=new Uint16Array(e),s=r;s0?g.offsetX:0,b=g.offsetY>0?g.offsetY:0;R*=y,b*=E,le._addPointArrToRst(e,m._getBoundPointS(f.x-R,f.y-b,C,A),p)}break;case it.ID:f.width&&f.height?le._addPointArrToRst(e,m._getBoundPointS(f.x,f.y,f.width,f.height),p):(g=f.texture,le._addPointArrToRst(e,m._getBoundPointS(f.x,f.y,g.width,g.height),p));break;case et.ID:var S;f.matrix?(p.copyTo(T),T.concat(f.matrix),S=T):S=p,t?f.width&&f.height?le._addPointArrToRst(e,m._getBoundPointS(f.x,f.y,f.width,f.height),S):(g=f.texture,le._addPointArrToRst(e,m._getBoundPointS(f.x,f.y,g.width,g.height),S)):(g=f.texture,y=(f.width||g.sourceWidth)/g.width,E=(f.height||g.sourceHeight)/g.height,C=y*g.sourceWidth,A=E*g.sourceHeight,R=g.offsetX>0?g.offsetX:0,b=g.offsetY>0?g.offsetY:0,R*=y,b*=E,le._addPointArrToRst(e,m._getBoundPointS(f.x-R,f.y-b,C,A),S));break;case d.ID:le._addPointArrToRst(e,m._getBoundPointS(f.x,f.y,f.width,f.height),p);break;case a.ID:le._addPointArrToRst(e,m._getBoundPointS(f.x-f.radius,f.y-f.radius,f.radius+f.radius,f.radius+f.radius),p);break;case o.ID:var w;le._tempPoints.length=0,w=.5*f.lineWidth,f.fromX==f.toX?le._tempPoints.push(f.fromX+w,f.fromY,f.toX+w,f.toY,f.fromX-w,f.fromY,f.toX-w,f.toY):f.fromY==f.toY?le._tempPoints.push(f.fromX,f.fromY+w,f.toX,f.toY+w,f.fromX,f.fromY-w,f.toX,f.toY-w):le._tempPoints.push(f.fromX,f.fromY,f.toX,f.toY),le._addPointArrToRst(e,le._tempPoints,p);break;case n.ID:le._addPointArrToRst(e,ot.I.getBezierPoints(f.points),p,f.x,f.y);break;case l.ID:case c.ID:le._addPointArrToRst(e,f.points,p,f.x,f.y);break;case _.ID:le._addPointArrToRst(e,this._getPathPoints(f.paths),p,f.x,f.y);break;case u.ID:le._addPointArrToRst(e,this._getPiePoints(f.x,f.y,f.radius,f.startAngle,f.endAngle),p);break;case ne.ID:le._addPointArrToRst(e,this._getTriAngBBXPoints(f.vertices),p);break;case he.ID:le._addPointArrToRst(e,this._getDraw9GridBBXPoints(f),p)}return e.length>200?e=$.copyArray(e,m._getWrapRec(e)._getBoundPoints()):e.length>8&&(e=lt.scanPList(e)),e}_switchMatrix(t,e){e.concat(t),e.copyTo(t)}static _addPointArrToRst(t,e,i,s=0,r=0){var a,n;for(n=e.length,a=0;a=360||h<=-360)return a.push(t-i,e-i),a.push(t+i,e-i),a.push(t+i,e+i),a.push(t-i,e+i),a;a.push(t,e);var o=h%360;o<0&&(o+=360);var l=s+o,_=s*n,u=l*n;a.push(t+i*Math.cos(_),e+i*Math.sin(_)),a.push(t+i*Math.cos(u),e+i*Math.sin(u));for(var c=90*Math.ceil(s/90),d=90*Math.floor(l/90),p=c;p<=d;p+=90){var f=p*n;a.push(t+i*Math.cos(f),e+i*Math.sin(f))}return a}_getTriAngBBXPoints(t){var e=t.length;if(e<2)return[];for(var i=t[0],s=t[1],r=i,a=s,n=2;nh&&(i=h),s>o&&(s=o),r1&&(r.push(s[1],s[2]),s.length>3&&r.push(s[3],s[4]));return r}}le._tempMatrix=new p,le._initMatrix=new p,le._tempPoints=[],le._tempMatrixArrays=[],le._tempCmds=[];class _e{}_e.ALPHA=1,_e.TRANSFORM=2,_e.BLEND=4,_e.CANVAS=8,_e.FILTERS=16,_e.MASK=32,_e.CLIP=64,_e.STYLE=128,_e.TEXTURE=256,_e.GRAPHICS=512,_e.LAYAGL3D=1024,_e.CUSTOM=2048,_e.ONECHILD=4096,_e.CHILDS=8192,_e.REPAINT_NONE=0,_e.REPAINT_NODE=1,_e.REPAINT_CACHE=2,_e.REPAINT_ALL=3;class ue{static create(t,e,i,r){var a=s.getItemByClass("ClipRectCmd",ue);return a.x=t,a.y=e,a.width=i,a.height=r,a}recover(){s.recover("ClipRectCmd",this)}run(t,e,i){t.clipRect(this.x+e,this.y+i,this.width,this.height)}get cmdID(){return ue.ID}}ue.ID="ClipRect";class ce{static create(t,e){var i=s.getItemByClass("DrawTexturesCmd",ce);return i.texture=t,t._addReference(),i.pos=e,i}recover(){this.texture._removeReference(),this.texture=null,this.pos=null,s.recover("DrawTexturesCmd",this)}run(t,e,i){t.drawTextures(this.texture,this.pos,e,i)}get cmdID(){return ce.ID}}ce.ID="DrawTextures";class de{constructor(){this._textIsWorldText=!1,this._fontColor=4294967295,this._strokeColor=0,this._fontObj=de._defFontObj,this._nTexAlign=0}static create(t,e,i,r,a,n,h,o,l){var _=s.getItemByClass("FillTextCmd",de);return _.text=t,_._textIsWorldText=t instanceof jt,_._words=e,_.x=i,_.y=r,_.font=a,_.color=n,_.textAlign=h,_._lineWidth=o,_._borderColor=l,_}recover(){s.recover("FillTextCmd",this)}run(t,e,s){i.stage.isGlobalRepaint()&&this._textIsWorldText&&this._text.cleanCache(),this._words?ee._textRender.fillWords(t,this._words,this.x+e,this.y+s,this._fontObj,this._color,this._borderColor,this._lineWidth):this._textIsWorldText?t._fast_filltext(this._text,this.x+e,this.y+s,this._fontObj,this._color,this._borderColor,this._lineWidth,this._nTexAlign,0):ee._textRender.filltext(t,this._text,this.x+e,this.y+s,this.font,this.color,this._borderColor,this._lineWidth,this._textAlign)}get cmdID(){return de.ID}get text(){return this._text}set text(t){this._text=t,this._textIsWorldText=t instanceof jt,this._textIsWorldText&&this._text.cleanCache()}get font(){return this._font}set font(t){this._font=t,this._fontObj=Kt.Parse(t),this._textIsWorldText&&this._text.cleanCache()}get color(){return this._color}set color(t){this._color=t,this._fontColor=J.create(t).numColor,this._textIsWorldText&&this._text.cleanCache()}get textAlign(){return this._textAlign}set textAlign(t){switch(this._textAlign=t,t){case"center":this._nTexAlign=i.Context.ENUM_TEXTALIGN_CENTER;break;case"right":this._nTexAlign=i.Context.ENUM_TEXTALIGN_RIGHT;break;default:this._nTexAlign=i.Context.ENUM_TEXTALIGN_DEFAULT}this._textIsWorldText&&this._text.cleanCache()}}de.ID="FillText",de._defFontObj=new Kt(null);class pe{constructor(){}static regCacheByFunction(t,e){var i;pe.unRegCacheByFunction(t,e),i={tryDispose:t,getCacheList:e},pe._cacheList.push(i)}static unRegCacheByFunction(t,e){var i,s;for(s=pe._cacheList.length,i=0;i0&&(pe._index++,pe._index=pe._index%s,t[pe._index].tryDispose(!1),!(i.Browser.now()-r>pe.loopTimeLimit));)e--}}}pe.loopTimeLimit=2,pe._cacheList=[],pe._index=0;class fe{constructor(){this.useDic={},this.shapeDic={},this.shapeLineDic={},this._id=0,this._checkKey=!1,this._freeIdArray=[],pe.regCacheByFunction(this.startDispose.bind(this),this.getCacheList.bind(this))}static getInstance(){return fe.instance=fe.instance||new fe}getId(){return this._id++}addShape(t,e){this.shapeDic[t]=e,this.useDic[t]||(this.useDic[t]=!0)}addLine(t,e){this.shapeLineDic[t]=e,this.shapeLineDic[t]||(this.shapeLineDic[t]=!0)}getShape(t){this._checkKey&&null!=this.useDic[t]&&(this.useDic[t]=!0)}deleteShape(t){this.shapeDic[t]&&(this.shapeDic[t]=null,delete this.shapeDic[t]),this.shapeLineDic[t]&&(this.shapeLineDic[t]=null,delete this.shapeLineDic[t]),null!=this.useDic[t]&&delete this.useDic[t]}getCacheList(){var t,e=[];for(t in this.shapeDic)e.push(this.shapeDic[t]);for(t in this.shapeLineDic)e.push(this.shapeLineDic[t]);return e}startDispose(t){var e;for(e in this.useDic)this.useDic[e]=!1;this._checkKey=!0}endDispose(){if(this._checkKey){var t;for(t in this.useDic)this.useDic[t]||this.deleteShape(t);this._checkKey=!1}}}class me{constructor(){this._sp=null,this._one=null,this._render=this._renderEmpty,this._cmds=null,this._vectorgraphArray=null,this._graphicBounds=null,this.autoDestroy=!1,this._createData()}_createData(){}_clearData(){}_destroyData(){}destroy(){this.clear(!0),this._graphicBounds&&this._graphicBounds.destroy(),this._graphicBounds=null,this._vectorgraphArray=null,this._sp&&(this._sp._renderType=0,this._sp._setRenderType(0),this._sp=null),this._destroyData()}clear(t=!0){if(t){var e=this._one;if(this._cmds){var i,s=this._cmds.length;for(i=0;i-1;i--)if(this._isTextCmd(e[i]))return e[i].text=t,!0}else if(this._one&&this._isTextCmd(this._one))return this._one.text=t,!0;return!1}_isTextCmd(t){return t.cmdID==de.ID}replaceTextColor(t){this._repaint();var e=this._cmds;if(e)for(var i=e.length-1;i>-1;i--)this._isTextCmd(e[i])&&this._setTextCmdColor(e[i],t);else this._one&&this._isTextCmd(this._one)&&this._setTextCmdColor(this._one,t)}_setTextCmdColor(t,e){switch(t.cmdID){case de.ID:t.color=e}}loadImage(t,e=0,s=0,r=0,a=0,n=null){var h=i.Loader.getRes(t);h?h.getIsReady()?this.drawImage(h,e,s,r,a):h.once(Ht.READY,this,this.drawImage,[h,e,s,r,a]):((h=new zt).load(t),i.Loader.cacheTexture(t,h),h.once(Ht.READY,this,this.drawImage,[h,e,s,r,a])),null!=n&&(h.getIsReady()?n.call(this._sp):h.on(Ht.READY,this._sp,n))}_renderEmpty(t,e,i,s){}_renderAll(t,e,i,s){for(var r=this._cmds,a=0,n=r.length;a=1&&a?n/2:0,o=a?n:0;return this._saveToCmd(ae._context.drawRect,d.create.call(this,t+h,e+h,i-o,s-o,r,a,n))}drawCircle(t,e,i,s,r=null,n=1){var h=n>=1&&r?n/2:0;return this._saveToCmd(ae._context._drawCircle,a.create.call(this,t,e,i-h,s,r,n,0))}drawPie(t,e,i,s,r,a,n=null,h=1){var o=h>=1&&n?h/2:0,l=n?h:0;return this._saveToCmd(ae._context._drawPie,u.create.call(this,t+o,e+o,i-l,$.toRadian(s),$.toRadian(r),a,n,h,0))}drawPoly(t,e,i,s,r=null,a=1){var n=!1;n=!(i.length>6);var h=a>=1&&r?a%2==0?0:.5:0;return this._saveToCmd(ae._context._drawPoly,c.create.call(this,t+h,e+h,i,s,r,a,n,0))}drawPath(t,e,i,s=null,r=null){return this._saveToCmd(ae._context._drawPath,_.create.call(this,t,e,i,s,r))}draw9Grid(t,e=0,i=0,s=0,r=0,a){this._saveToCmd(null,he.create(t,e,i,s,r,a))}}class ge{}ge.NOT_ACTIVE=1,ge.ACTIVE_INHIERARCHY=2,ge.AWAKED=4,ge.NOT_READY=8,ge.DISPLAY=16,ge.HAS_ZORDER=32,ge.HAS_MOUSE=64,ge.DISPLAYED_INSTAGE=128,ge.DRAWCALL_OPTIMIZE=256;class Te{static __init__(){Te.map[_e.ALPHA|_e.TRANSFORM|_e.GRAPHICS]=Te.alpha_transform_drawLayaGL,Te.map[_e.ALPHA|_e.GRAPHICS]=Te.alpha_drawLayaGL,Te.map[_e.TRANSFORM|_e.GRAPHICS]=Te.transform_drawLayaGL,Te.map[_e.TRANSFORM|_e.CHILDS]=Te.transform_drawNodes,Te.map[_e.ALPHA|_e.TRANSFORM|_e.TEXTURE]=Te.alpha_transform_drawTexture,Te.map[_e.ALPHA|_e.TEXTURE]=Te.alpha_drawTexture,Te.map[_e.TRANSFORM|_e.TEXTURE]=Te.transform_drawTexture,Te.map[_e.GRAPHICS|_e.CHILDS]=Te.drawLayaGL_drawNodes}static transform_drawTexture(t,e,i,s){t._style;var r=t.texture;e.saveTransform(Te.curMat),e.transformByMatrix(t.transform,i,s);var a=t._width||r.sourceWidth,n=t._height||r.sourceHeight,h=a/r.sourceWidth,o=n/r.sourceHeight;if(a=r.width*h,n=r.height*o,a<=0||n<=0)return null;var l=-t.pivotX+r.offsetX*h,_=-t.pivotY+r.offsetY*o;e.drawTexture(r,l,_,a,n),e.restoreTransform(Te.curMat)}static alpha_drawTexture(t,e,i,s){var r,a=t._style,n=t.texture;if((r=a.alpha)>.01||t._needRepaint()){var h=e.globalAlpha;e.globalAlpha*=r;var o=t._width||n.width,l=t._height||n.height,_=o/n.sourceWidth,u=l/n.sourceHeight;if(o=n.width*_,l=n.height*u,o<=0||l<=0)return null;var c=i-a.pivotX+n.offsetX*_,d=s-a.pivotY+n.offsetY*u;e.drawTexture(n,c,d,o,l),e.globalAlpha=h}}static alpha_transform_drawTexture(t,e,i,s){var r,a=t._style,n=t.texture;if((r=a.alpha)>.01||t._needRepaint()){var h=e.globalAlpha;e.globalAlpha*=r,e.saveTransform(Te.curMat),e.transformByMatrix(t.transform,i,s);var o=t._width||n.sourceWidth,l=t._height||n.sourceHeight,_=o/n.sourceWidth,u=l/n.sourceHeight;if(o=n.width*_,l=n.height*u,o<=0||l<=0)return null;var c=-a.pivotX+n.offsetX*_,d=-a.pivotY+n.offsetY*u;e.drawTexture(n,c,d,o,l),e.restoreTransform(Te.curMat),e.globalAlpha=h}}static alpha_transform_drawLayaGL(t,e,i,s){var r,a=t._style;if((r=a.alpha)>.01||t._needRepaint()){var n=e.globalAlpha;e.globalAlpha*=r,e.saveTransform(Te.curMat),e.transformByMatrix(t.transform,i,s),t._graphics&&t._graphics._render(t,e,-a.pivotX,-a.pivotY),e.restoreTransform(Te.curMat),e.globalAlpha=n}}static alpha_drawLayaGL(t,e,i,s){var r,a=t._style;if((r=a.alpha)>.01||t._needRepaint()){var n=e.globalAlpha;e.globalAlpha*=r,t._graphics&&t._graphics._render(t,e,i-a.pivotX,s-a.pivotY),e.globalAlpha=n}}static transform_drawLayaGL(t,e,i,s){var r=t._style;e.saveTransform(Te.curMat),e.transformByMatrix(t.transform,i,s),t._graphics&&t._graphics._render(t,e,-r.pivotX,-r.pivotY),e.restoreTransform(Te.curMat)}static transform_drawNodes(t,e,i,s){var r=t._getBit(ge.DRAWCALL_OPTIMIZE)&&e.drawCallOptimize(!0),a=t._style;e.saveTransform(Te.curMat),e.transformByMatrix(t.transform,i,s),i=-a.pivotX,s=-a.pivotY;var n,h=t._children,o=h.length;if(a.viewport){var l,_,u=a.viewport,c=u.x,d=u.y,p=u.right,f=u.bottom;for(m=0;mc&&(_=n._y)d&&n.render(e,i,s)}else for(var m=0;mc&&(_=n._y)d&&n.render(e,i,s)}else for(var m=0;m0;)i&t&&(e=new ve(i,e)),i>>=1;return e}onCreate(t){}_style(t,e,i,s){var r=t._style;null!=r.render&&r.render(t,e,i,s);var a=this._next;a._fun.call(a,t,e,i,s)}_no(t,e,i,s){}_custom(t,e,i,s){t.customRender(e,i,s),this._next._fun.call(this._next,t,e,0,0)}_clip(t,e,i,s){var r=this._next;if(r!=ve.NORENDER){var a=t._style.scrollRect,n=a.width,h=a.height;0!==n&&0!==h&&(e.save(),e.clipRect(i,s,n,h),r._fun.call(r,t,e,i-a.x,s-a.y),e.restore())}}_texture(t,e,i,s){var r=t.texture;if(r._getSource()){var a=t._width||r.sourceWidth,n=t._height||r.sourceHeight,h=a/r.sourceWidth,o=n/r.sourceHeight;if(a=r.width*h,n=r.height*o,a<=0||n<=0)return;var l=i-t.pivotX+r.offsetX*h,_=s-t.pivotY+r.offsetY*o;e.drawTexture(r,l,_,a,n)}var u=this._next;u!=ve.NORENDER&&u._fun.call(u,t,e,i,s)}_graphics(t,e,i,s){var r=t._style,a=t._graphics;a&&a._render(t,e,i-r.pivotX,s-r.pivotY);var n=this._next;n!=ve.NORENDER&&n._fun.call(n,t,e,i,s)}_image(t,e,i,s){var r=t._style;e.drawTexture2(i,s,r.pivotX,r.pivotY,t.transform,t._graphics._one)}_image2(t,e,i,s){var r=t._style;e.drawTexture2(i,s,r.pivotX,r.pivotY,t.transform,t._graphics._one)}_alpha(t,e,i,s){var r;if((r=t._style.alpha)>.01||t._needRepaint()){var a=e.globalAlpha;e.globalAlpha*=r;var n=this._next;n._fun.call(n,t,e,i,s),e.globalAlpha=a}}_transform(t,e,i,s){var r=t.transform,a=this._next;t._style;r&&a!=ve.NORENDER?(e.save(),e.transform(r.a,r.b,r.c,r.d,r.tx+i,r.ty+s),a._fun.call(a,t,e,0,0),e.restore()):a!=ve.NORENDER&&a._fun.call(a,t,e,i,s)}_children(t,e,i,s){var r,a=t._style,n=t._children,h=n.length;i-=t.pivotX,s-=t.pivotY;var o=t._getBit(ge.DRAWCALL_OPTIMIZE)&&e.drawCallOptimize(!0);if(a.viewport){var l,_,u=a.viewport,c=u.x,d=u.y,p=u.right,f=u.bottom;for(m=0;mc&&(_=r._y)d&&r.render(e,i,s)}else for(var m=0;m2048||l>2048))return console.warn("cache bitmap size larger than 2048,cache ignored"),d.releaseContext(),void p._fun.call(p,t,e,i,s);if(f||(d.createContext(),f=d.canvas),(r=f.context).sprite=t,(f.width!=o||f.height!=l)&&f.size(o,l),"bitmap"===m?r.asBitmap=!0:"normal"===m&&(r.asBitmap=!1),r.clear(),1!=_||1!=u){var g=r;g.save(),g.scale(_,u),p._fun.call(p,t,r,-a,-n),g.restore(),t._applyFilters()}else g=r,p._fun.call(p,t,r,-a,-n),t._applyFilters();d.staticCache&&(d.reCache=!1),X.canvasReCache++}_canvas_webgl_normal_repaint(t,e){var i=t._cacheStyle,s=this._next,r=i.canvas,a=i.cacheAs;i._calculateCacheRect(t,a,0,0),r||(r=new It(e,t),i.canvas=r);var n=r.context;r.startRec(),s._fun.call(s,t,n,t.pivotX,t.pivotY),t._applyFilters(),X.canvasReCache++,r.endRec()}_blend(t,e,i,s){var r=t._style,a=this._next;r.blendMode?(e.save(),e.globalCompositeOperation=r.blendMode,a._fun.call(a,t,e,i,s),e.restore()):a._fun.call(a,t,e,i,s)}_mask(t,e,i,s){var r=this._next,a=t.mask,n=e;if(a){n.save();var h=n.globalCompositeOperation,o=new m;if(o.copyFrom(a.getBounds()),o.width=Math.round(o.width),o.height=Math.round(o.height),o.x=Math.round(o.x),o.y=Math.round(o.y),o.width>0&&o.height>0){var l=o.width,_=o.height,u=k.getRT(l,_);n.breakNextMerge(),n.pushRT(),n.addRenderObject(Z.create([n,u,l,_],ve.tmpTarget,this)),a.render(n,-o.x,-o.y),n.breakNextMerge(),n.popRT(),n.save();let e=.1;n.clipRect(i+o.x-t.getStyle().pivotX+e,s+o.y-t.getStyle().pivotY+e,l-2*e,_-2*e),r._fun.call(r,t,n,i,s),n.restore(),h=n.globalCompositeOperation,n.addRenderObject(Z.create(["mask"],ve.setBlendMode,this));var c=j.create(V.TEXTURE2D,0),d=zt.INV_UV;n.drawTarget(u,i+o.x-t.getStyle().pivotX,s+o.y-t.getStyle().pivotY,l,_,p.TEMP.identity(),c,d,6),n.addRenderObject(Z.create([u],ve.recycleTarget,this)),n.addRenderObject(Z.create([h],ve.setBlendMode,this))}n.restore()}else r._fun.call(r,t,e,i,s)}static tmpTarget(t,e,i,s){e.start(),e.clear(0,0,0,0)}static recycleTarget(t){k.releaseRT(t)}static setBlendMode(t){var e=R.mainContext;W.targetFns[W.TOINT[t]](e)}}ve.INIT=69905,ve.renders=[],ve.NORENDER=new ve(0,null),ve.tempUV=new Array(8);class xe extends P{constructor(t=!1){super(),this._source=t?Qt.createElement("canvas"):this,this.lock=!0}get source(){return this._source}_getSource(){return this._source}clear(){this._ctx&&(this._ctx.clear?this._ctx.clear():this._ctx.clearRect(0,0,this._width,this._height)),this._texture&&(this._texture.destroy(),this._texture=null)}destroy(){super.destroy(),this._setCPUMemory(0),this._ctx&&this._ctx.destroy&&this._ctx.destroy(),this._ctx=null}release(){}get context(){return this._ctx||(this._source==this?this._ctx=new i.Context:this._ctx=this._source.getContext(i.Render.isConchApp?"layagl":"2d"),this._ctx._canvas=this),this._ctx}_setContext(t){this._ctx=t}getContext(t,e=null){return this.context}getMemSize(){return 0}size(t,e){(this._width!=t||this._height!=e||this._source&&(this._source.width!=t||this._source.height!=e))&&(this._width=t,this._height=e,this._setCPUMemory(t*e*4),this._ctx&&this._ctx.size&&this._ctx.size(t,e),this._source&&(this._source.height=e,this._source.width=t),this._texture&&(this._texture.destroy(),this._texture=null))}getTexture(){if(!this._texture){var t=new O;t.loadImageSource(this.source),this._texture=new zt(t)}return this._texture}toBase64(t,e){if(this._source){if(i.Render.isConchApp){var s=window;if(2==s.conchConfig.threadMode)throw"native 2 thread mode use toBase64Async";var r=this._ctx._targets.sourceWidth,a=this._ctx._targets.sourceHeight,n=this._ctx._targets.getData(0,0,r,a);return s.conchToBase64FlipY?s.conchToBase64FlipY(t,e,n.buffer,r,a):s.conchToBase64(t,e,n.buffer,r,a)}return this._source.toDataURL(t,e)}return null}toBase64Async(t,e,i){var s=this._ctx._targets.sourceWidth,r=this._ctx._targets.sourceHeight;this._ctx._targets.getDataAsync(0,0,s,r,(function(a){let n=window;var h=n.conchToBase64FlipY?n.conchToBase64FlipY(t,e,a.buffer,s,r):n.conchToBase64(t,e,a.buffer,s,r);i(h)}))}}class ye{contains(t,e){return!!ye._isHitGraphic(t,e,this.hit)&&!ye._isHitGraphic(t,e,this.unHit)}static _isHitGraphic(t,e,i){if(!i)return!1;var s,r,a,n=i.cmds;if(!n&&i._one&&((n=ye._cmds).length=1,n[0]=i._one),!n)return!1;for(r=n.length,s=0;s=Math.max(a,h)))(s.y-a)*(n-r)/(h-a)+r>s.x&&l++}return l%2==1}get hit(){return this._hit||(this._hit=new i.Graphics),this._hit}set hit(t){this._hit=t}get unHit(){return this._unHit||(this._unHit=new i.Graphics),this._unHit}set unHit(t){this._unHit=t}}ye._cmds=[],ye._rect=new m,ye._ptPoint=new f;class Ee{static regClass(t,e){Ee._classMap[t]=e}static regShortClassName(t){for(var e=0;e=0)return null;this._extUIChild.push(t)}return null}removeInputChild(t){var e=this._extUIChild.indexOf(t);e>=0&&this._extUIChild.splice(e,1)}addChildren(...t){for(var e=0,i=t.length;e=0&&e<=this._children.length){if(t._parent===this){var i=this.getChildIndex(t);this._children.splice(i,1),this._children.splice(e,0,t),this._childChanged()}else t._parent&&t._parent.removeChild(t),this._children===be.ARRAY_EMPTY&&(this._children=[]),this._children.splice(e,0,t),t._setParent(this);return t}throw new Error("appendChildAt:The index is out of bounds")}getChildIndex(t){return this._children.indexOf(t)}getChildByName(t){var e=this._children;if(e)for(var i=0,s=e.length;i=i.length)throw new Error("setChildIndex:The index is out of bounds.");var s=this.getChildIndex(t);if(s<0)throw new Error("setChildIndex:node is must child of this object.");return i.splice(s,1),i.splice(e,0,t),this._childChanged(),t}_childChanged(t=null){}removeChild(t){if(!this._children)return t;var e=this._children.indexOf(t);return this.removeChildAt(e)}removeSelf(){return this._parent&&this._parent.removeChild(this),this}removeChildByName(t){var e=this.getChildByName(t);return e&&this.removeChild(e),e}removeChildAt(t){var e=this.getChildAt(t);return e&&(this._children.splice(t,1),e._setParent(null)),e}removeChildren(t=0,e=2147483647){if(this._children&&this._children.length>0){var i=this._children;if(0===t&&e>=i.length-1){var s=i;this._children=be.ARRAY_EMPTY}else s=i.splice(t,e-t+1);for(var r=0,a=s.length;r-1?(this._children.splice(i,1,t),e._setParent(null),t._setParent(this),t):null}get numChildren(){return this._children.length}get parent(){return this._parent}_setParent(t){this._parent!==t&&(t?(this._parent=t,this._onAdded(),this.event(Ht.ADDED),this._getBit(ge.DISPLAY)&&(this._setUpNoticeChain(),t.displayedInStage&&this._displayChild(this,!0)),t._childChanged(this)):(this._onRemoved(),this.event(Ht.REMOVED),this._parent._childChanged(),this._getBit(ge.DISPLAY)&&this._displayChild(this,!1),this._parent=t))}get displayedInStage(){return this._getBit(ge.DISPLAY)||this._setBitUp(ge.DISPLAY),this._getBit(ge.DISPLAYED_INSTAGE)}_updateDisplayedInstage(){var t;t=this;for(var e=i.stage,s=!1;t;){if(t._getBit(ge.DISPLAY)){s=t._getBit(ge.DISPLAYED_INSTAGE);break}if(t===e||t._getBit(ge.DISPLAYED_INSTAGE)){s=!0;break}t=t._parent}this._setBit(ge.DISPLAYED_INSTAGE,s)}_setDisplay(t){this._getBit(ge.DISPLAYED_INSTAGE)!==t&&(this._setBit(ge.DISPLAYED_INSTAGE,t),t?this.event(Ht.DISPLAY):this.event(Ht.UNDISPLAY))}_displayChild(t,e){var i=t._children;if(i)for(var s=0,r=i.length;s0?this._displayChild(a,e):a._setDisplay(e))}t._setDisplay(e)}contains(t){if(t===this)return!0;for(;t;){if(t._parent===this)return!0;t=t._parent}return!1}timerLoop(t,e,s,r=null,a=!0,n=!1){(this.scene?this.scene.timer:i.timer).loop(t,e,s,r,a,n)}timerOnce(t,e,s,r=null,a=!0){(this.scene?this.scene.timer:i.timer)._create(!1,!1,t,e,s,r,a)}frameLoop(t,e,s,r=null,a=!0){(this.scene?this.scene.timer:i.timer)._create(!0,!0,t,e,s,r,a)}frameOnce(t,e,s,r=null,a=!0){(this.scene?this.scene.timer:i.timer)._create(!0,!1,t,e,s,r,a)}clearTimer(t,e){(this.scene?this.scene.timer:i.timer).clear(t,e)}callLater(t,e=null){(this.scene?this.scene.timer:i.timer).callLater(this,t,e)}runCallLater(t){(this.scene?this.scene.timer:i.timer).runCallLater(this,t)}get scene(){return this._scene}get active(){return!this._getBit(ge.NOT_READY)&&!this._getBit(ge.NOT_ACTIVE)}set active(t){if(t=!!t,!this._getBit(ge.NOT_ACTIVE)!==t){if(this._activeChangeScripts&&0!==this._activeChangeScripts.length)throw t?"Node: can't set the main inActive node active in hierarchy,if the operate is in main inActive node or it's children script's onDisable Event.":"Node: can't set the main active node inActive in hierarchy,if the operate is in main active node or it's children script's onEnable Event.";this._setBit(ge.NOT_ACTIVE,!t),this._parent&&this._parent.activeInHierarchy&&(t?this._processActive():this._processInActive())}}get activeInHierarchy(){return this._getBit(ge.ACTIVE_INHIERARCHY)}_onActive(){X.spriteCount++}_onInActive(){X.spriteCount--}_onActiveInScene(){}_onInActiveInScene(){}_parse(t,e){}_setBelongScene(t){if(!this._scene){this._scene=t,this._onActiveInScene();for(var e=0,i=this._children.length;e1?1:t,this._setAlpha(t)}get visible(){return this.get_visible()}set visible(t){this.set_visible(t)}get_visible(){return this._visible}set_visible(t){this._visible!==t&&(this._visible=t,this.parentRepaint(_e.REPAINT_ALL))}_setBlendMode(t){}get blendMode(){return this._style.blendMode}set blendMode(t){this._setBlendMode(t),this.getStyle().blendMode=t,t&&"source-over"!=t?this._renderType|=_e.BLEND:this._renderType&=~_e.BLEND,this._setRenderType(this._renderType),this.parentRepaint()}get graphics(){return this._graphics||(this.graphics=new me,this._graphics.autoDestroy=!0),this._graphics}_setGraphics(t){}_setGraphicsCallBack(){}set graphics(t){this._graphics&&(this._graphics._sp=null),this._graphics=t,t?(this._setGraphics(t),this._renderType|=_e.GRAPHICS,t._sp=this):this._renderType&=~_e.GRAPHICS,this._setRenderType(this._renderType),this.repaint()}get scrollRect(){return this._style.scrollRect}_setScrollRect(t){}set scrollRect(t){this.getStyle().scrollRect=t,this._setScrollRect(t),this.repaint(),t?this._renderType|=_e.CLIP:this._renderType&=~_e.CLIP,this._setRenderType(this._renderType)}pos(t,e,i=!1){if(this._x!==t||this._y!==e){if(this.destroyed)return this;if(i){this._setX(t),this._setY(e),this.parentRepaint(_e.REPAINT_CACHE);var s=this._cacheStyle.maskParent;s&&s.repaint(_e.REPAINT_CACHE)}else this.x=t,this.y=e}return this}pivot(t,e){return this.pivotX=t,this.pivotY=e,this}size(t,e){return this.width=t,this.height=e,this}scale(t,e,i=!1){var s=this.getStyle();if(s.scaleX!=t||s.scaleY!=e){if(this.destroyed)return this;i?(this._setScaleX(t),this._setScaleY(e),this._setTranformChange()):(this.scaleX=t,this.scaleY=e)}return this}skew(t,e){return this.skewX=t,this.skewY=e,this}render(t,e,i){ve.renders[this._renderType]._fun(this,t,e+this._x,i+this._y),this._repaint=0}drawToCanvas(t,e,i,s){return Se.drawToCanvas(this,this._renderType,t,e,i,s)}drawToTexture(t,e,i,s,r=null){return Se.drawToTexture(this,this._renderType,t,e,i,s,r)}drawToTexture3D(t,e,i){throw"not implement"}static drawToCanvas(t,e,i,s,r,a){r-=t.x,a-=t.y,r|=0,a|=0,i|=0,s|=0;var n=new ee;n.size(i,s),n.asBitmap=!0,n._targets.start(),n._targets.clear(0,0,0,0),ve.renders[e]._fun(t,n,r,a),n.flush(),n._targets.end(),n._targets.restore();var h=n._targets.getData(0,0,i,s);n.destroy();for(var o=new ImageData(i,s),l=4*i,_=o.data,u=s-1,c=u*l,d=0;u>=0;u--)_.set(h.subarray(d,d+l),c),c-=l,d+=l;var p=new xe(!0);return p.size(i,s),p.getContext("2d").putImageData(o,0,0),p}static drawToTexture(t,e,i,s,r,a,n=null){Se.drawtocanvCtx||(Se.drawtocanvCtx=new ee),r-=t.x,a-=t.y,r|=0,a|=0,i|=0,s|=0;var h=n?Se.drawtocanvCtx:new ee;if(h.clear(),h.size(i,s),n?h._targets=n:h.asBitmap=!0,h._targets&&(h._targets.start(),h._targets.clear(0,0,0,0),ve.renders[e]._fun(t,h,r,a),h.flush(),h._targets.end(),h._targets.restore()),!n){var o=new zt(h._targets,zt.INV_UV);return h.destroy(!0),o}return t._repaint=0,n}customRender(t,e,i){this._repaint=_e.REPAINT_ALL}_applyFilters(){}get filters(){return this._cacheStyle.filters}_setColorFilter(t){}set filters(t){t&&0===t.length&&(t=null),this._cacheStyle.filters!=t&&(this._getCacheStyle().filters=t?t.slice():null,t&&t.length?(this._setColorFilter(t[0]),this._renderType|=_e.FILTERS):(this._setColorFilter(null),this._renderType&=~_e.FILTERS),this._setRenderType(this._renderType),t&&t.length>0?(this._getBit(ge.DISPLAY)||this._setBitUp(ge.DISPLAY),1==t.length&&t[0]instanceof tt||(this._getCacheStyle().cacheForFilters=!0,this._checkCanvasEnable())):this._cacheStyle.cacheForFilters&&(this._cacheStyle.cacheForFilters=!1,this._checkCanvasEnable()),this._getCacheStyle().hasGlowFilter=this._isHaveGlowFilter(),this.repaint())}_isHaveGlowFilter(){var t,e;if(this.filters)for(t=0;t=0;)t=(r=a[n]).fromParentPoint(t),n--;return t}toParentPoint(t){if(!t)return t;t.x-=this.pivotX,t.y-=this.pivotY,this.transform&&this._transform.transformPoint(t),t.x+=this._x,t.y+=this._y;var e=this._style.scrollRect;return e&&(t.x-=e.x,t.y-=e.y),t}fromParentPoint(t){if(!t)return t;t.x-=this._x,t.y-=this._y;var e=this._style.scrollRect;return e&&(t.x+=e.x,t.y+=e.y),this.transform&&this._transform.invertTransformPoint(t),t.x+=this.pivotX,t.y+=this.pivotY,t}fromStagePoint(t){return t}on(t,e,i,s=null){return 1!==this._mouseState&&this.isMouseEvent(t)?(this.mouseEnabled=!0,this._setBit(ge.HAS_MOUSE,!0),this._parent&&this._onDisplay(),this._createListener(t,e,i,s,!1)):super.on(t,e,i,s)}once(t,e,i,s=null){return 1!==this._mouseState&&this.isMouseEvent(t)?(this.mouseEnabled=!0,this._setBit(ge.HAS_MOUSE,!0),this._parent&&this._onDisplay(),this._createListener(t,e,i,s,!0)):super.once(t,e,i,s)}_onDisplay(t){if(1!==this._mouseState){var e=this;for(e=e.parent;e&&1!==e._mouseState&&!e._getBit(ge.HAS_MOUSE);)e.mouseEnabled=!0,e._setBit(ge.HAS_MOUSE,!0),e=e.parent}}_setParent(t){super._setParent(t),t&&this._getBit(ge.HAS_MOUSE)&&this._onDisplay()}loadImage(t,e=null){if(t){var s=i.Loader.textureMap[M.formatURL(t)];s||((s=new zt).load(t),i.Loader.cacheTexture(t,s)),this.texture=s,s.getIsReady()?loaded.call(this):s.once(Ht.READY,this,loaded)}else this.texture=null,loaded.call(this);function loaded(){this.repaint(_e.REPAINT_ALL),e&&e.run()}return this}static fromImage(t){return(new Se).loadImage(t)}repaint(t=_e.REPAINT_CACHE){this._repaint&t||(this._repaint|=t,this.parentRepaint(t)),this._cacheStyle&&this._cacheStyle.maskParent&&this._cacheStyle.maskParent.repaint(t)}_needRepaint(){return this._repaint&_e.REPAINT_CACHE&&this._cacheStyle.enableCanvasRender&&this._cacheStyle.reCache}_childChanged(t=null){this._children.length?this._renderType|=_e.CHILDS:this._renderType&=~_e.CHILDS,this._setRenderType(this._renderType),t&&this._getBit(ge.HAS_ZORDER)&&i.systemTimer.callLater(this,this.updateZOrder),this.repaint(_e.REPAINT_ALL)}parentRepaint(t=_e.REPAINT_CACHE){var e=this._parent;!e||e._repaint&t||(e._repaint|=t,e.parentRepaint(t))}get stage(){return i.stage}get hitArea(){return this._style.hitArea}set hitArea(t){this.getStyle().hitArea=t}_setMask(t){}get mask(){return this._cacheStyle.mask}set mask(t){t&&this.mask&&this.mask._cacheStyle.maskParent||(this._getCacheStyle().mask=t,this._setMask(t),this._checkCanvasEnable(),t?t._getCacheStyle().maskParent=this:this.mask&&(this.mask._getCacheStyle().maskParent=null),this._renderType|=_e.MASK,this._setRenderType(this._renderType),this.parentRepaint(_e.REPAINT_ALL))}get mouseEnabled(){return this._mouseState>1}set mouseEnabled(t){this._mouseState=t?2:1}startDrag(t=null,e=!1,s=0,r=300,a=null,n=!1,h=.92){this._style.dragging||(this.getStyle().dragging=new i.Dragging),this._style.dragging.start(this,t,e,s,r,a,n,h)}stopDrag(){this._style.dragging&&this._style.dragging.stop()}_setDisplay(t){t||this._cacheStyle&&(this._cacheStyle.releaseContext(),this._cacheStyle.releaseFilterCache(),this._cacheStyle.hasGlowFilter&&(this._cacheStyle.hasGlowFilter=!1)),super._setDisplay(t)}hitTestPoint(t,e){var i=this.globalToLocal(f.TEMP.setTo(t,e));return t=i.x,e=i.y,(this._style.hitArea?this._style.hitArea:this._width>0&&this._height>0?m.TEMP.setTo(0,0,this._width,this._height):this.getSelfBounds()).contains(t,e)}getMousePoint(){return this.globalToLocal(f.TEMP.setTo(i.stage.mouseX,i.stage.mouseY))}get globalScaleX(){for(var t=1,e=this;e&&e!==i.stage;)t*=e.scaleX,e=e.parent;return t}get globalRotation(){for(var t=0,e=this;e&&e!==i.stage;)t+=e.rotation,e=e.parent;return t}get globalScaleY(){for(var t=1,e=this;e&&e!==i.stage;)t*=e.scaleY,e=e.parent;return t}get mouseX(){return this.getMousePoint().x}get mouseY(){return this.getMousePoint().y}get zOrder(){return this._zOrder}set zOrder(t){this._zOrder!=t&&(this._zOrder=t,this._parent&&(t&&this._parent._setBit(ge.HAS_ZORDER,!0),i.systemTimer.callLater(this._parent,this.updateZOrder)))}get texture(){return this._texture}_setTexture(t){}set texture(t){"string"==typeof t?this.loadImage(t):this._texture!=t&&(this._texture&&this._texture._removeReference(),this._texture=t,t&&t._addReference(),this._setTexture(t),this._setWidth(this._texture,this.width),this._setHeight(this._texture,this.height),t?this._renderType|=_e.TEXTURE:this._renderType&=~_e.TEXTURE,this._setRenderType(this._renderType),this.repaint())}get viewport(){return this._style.viewport}set viewport(t){var e;"string"==typeof t&&((e=t.split(",")).length>3&&(t=new m(parseFloat(e[0]),parseFloat(e[1]),parseFloat(e[2]),parseFloat(e[3]))));this.getStyle().viewport=t}_setRenderType(t){}_setTranformChange(){this._tfChanged=!0,this._renderType|=_e.TRANSFORM,this.parentRepaint(_e.REPAINT_CACHE)}_setBgStyleColor(t,e,i,s,r){}_setBorderStyleColor(t,e,i,s,r,a){}captureMouseEvent(t){i.MouseManager.instance.setCapture(this,t)}releaseMouseEvent(){i.MouseManager.instance.releaseCapture()}set drawCallOptimize(t){this._setBit(ge.DRAWCALL_OPTIMIZE,t)}get drawCallOptimize(){return this._getBit(ge.DRAWCALL_OPTIMIZE)}}Ee.regClass("laya.display.Sprite",Se),Ee.regClass("Laya.Sprite",Se);class we extends Re{constructor(){super(...arguments),this.italic=!1}reset(){return super.reset(),this.italic=!1,this.align="left",this.wordWrap=!1,this.leading=0,this.padding=[0,0,0,0],this.bgColor=null,this.borderColor=null,this.asPassword=!1,this.stroke=0,this.strokeColor="#000000",this.bold=!1,this.underline=!1,this.underlineColor=null,this.currBitmapFont=null,this}recover(){this!==we.EMPTY&&s.recover("TextStyle",this.reset())}static create(){return s.getItemByClass("TextStyle",we)}render(t,e,i,s){(this.bgColor||this.borderColor)&&e.drawRect(i-this.pivotX,s-this.pivotY,t.width,t.height,this.bgColor,this.borderColor,1)}}we.EMPTY=new we;class Me extends Se{constructor(){super(),this._textWidth=0,this._textHeight=0,this._lines=[],this._lineWidths=[],this._startX=0,this._startY=0,this._charSize={},this._valign="top",this._fontSize=Me.defaultFontSize,this._font=Me.defaultFont,this._color="#000000",this._singleCharRender=!1,this.overflow=Me.VISIBLE,this._style=we.EMPTY}static defaultFontStr(){return Me.defaultFontSize+"px "+Me.defaultFont}getStyle(){return this._style===we.EMPTY&&(this._style=we.create()),this._style}_getTextStyle(){return this._style===we.EMPTY&&(this._style=we.create()),this._style}static registerBitmapFont(t,e){Me._bitmapFonts||(Me._bitmapFonts={}),Me._bitmapFonts[t]=e}static unregisterBitmapFont(t,e=!0){if(Me._bitmapFonts&&Me._bitmapFonts[t]){var i=Me._bitmapFonts[t];e&&i.destroy(),delete Me._bitmapFonts[t]}}destroy(t=!0){super.destroy(t),this._clipPoint=null,this._lines=null,this._lineWidths=null,this._words&&this._words.forEach((function(t){t.cleanCache()})),this._words=null,this._charSize=null}_getBoundPointsM(t=!1){var e=m.TEMP;return e.setTo(0,0,this.width,this.height),e._getBoundPoints()}getGraphicBounds(t=!1){var e=m.TEMP;return e.setTo(0,0,this.width,this.height),e}get width(){return this._width?this._width:this.textWidth+this.padding[1]+this.padding[3]}set width(t){t!=this._width&&(super.set_width(t),this.isChanged=!0,this.borderColor&&this._setBorderStyleColor(0,0,this.width,this.height,this.borderColor,1))}_getCSSStyle(){return this._style}get height(){return this._height?this._height:this.textHeight}set height(t){t!=this._height&&(super.set_height(t),this.isChanged=!0,this.borderColor&&this._setBorderStyleColor(0,0,this.width,this.height,this.borderColor,1))}get textWidth(){return this._isChanged&&i.systemTimer.runCallLater(this,this.typeset),this._textWidth}get textHeight(){return this._isChanged&&i.systemTimer.runCallLater(this,this.typeset),this._textHeight}get text(){return this._text||""}get_text(){return this._text||""}set_text(t){this._text!==t&&(this.lang(t+""),this.isChanged=!0,this.event(Ht.CHANGE),this.borderColor&&this._setBorderStyleColor(0,0,this.width,this.height,this.borderColor,1))}set text(t){this.set_text(t)}lang(t,e=null,i=null,s=null,r=null,a=null,n=null,h=null,o=null,l=null,_=null){if(t=Me.langPacks&&Me.langPacks[t]?Me.langPacks[t]:t,arguments.length<2)this._text=t;else{for(var u=0,c=arguments.length;u0;i--)e+="●";return e}_renderText(){var t=this.padding,e=this._lines.length;this.overflow!=Me.VISIBLE&&(e=Math.min(e,Math.floor((this.height-t[0]-t[2])/(this.leading+this._charSize.height))+1));var s=this.scrollY/(this._charSize.height+this.leading)|0,r=this.graphics;r.clear(!0);var a=this._getContextFont();i.Browser.context.font=a;var n=t[3],h="left",o=this._lines,l=this.leading+this._charSize.height,_=this._style.currBitmapFont;_&&(l=this.leading+_.getMaxHeight());var u=t[0];!_&&this._width>0&&this._textWidth<=this._width&&("right"==this.align?(h="right",n=this._width-t[1]):"center"==this.align&&(h="center",n=.5*this._width+t[3]-t[1]));let c=1;if(_&&_.autoScaleSize&&(c=_.fontSize/this.fontSize),this._height>0){var d=this._textHeight>this._height?"top":this.valign;"middle"===d?u=.5*(this._height-e/c*l)+t[0]-t[2]:"bottom"===d&&(u=this._height-e/c*l-t[2])}if(this._clipPoint){var p,f;if(r.save(),_&&_.autoScaleSize)p=this._width?this._width-t[3]-t[1]:this._textWidth,f=this._height?this._height-t[0]-t[2]:this._textHeight,p*=c,f*=c,r.clipRect(t[3],t[0],p,f);else r.clipRect(t[3],t[0],this._width?this._width-t[3]-t[1]:this._textWidth,this._height?this._height-t[0]-t[2]:this._textHeight);this.repaint()}var m=this._style,g=m.asPassword;"prompt"in this&&this.prompt==this._text&&(g=!1);for(var T=0,v=0,x=Math.min(this._lines.length,e+s)||1,y=s;y0;A--)C+="●"}if(null==C&&(C=""),T=n-(this._clipPoint?this._clipPoint.x:0),v=u+l*y-(this._clipPoint?this._clipPoint.y:0),this.underline&&this._drawUnderline(h,T,v,y),_){var R=this.width;_.autoScaleSize&&(R=this.width*c,T*=c,v*=c),_._drawText(C,this,T,v,this.align,R)}else this._words||(this._words=[]),this._words.length>y-s?E=this._words[y-s]:(E=new jt,this._words.push(E)),E.setText(C),E.splitRender=this._singleCharRender,m.stroke?r.fillBorderText(E,T,v,a,this.color,h,m.stroke,m.strokeColor):r.fillText(E,T,v,a,this.color,h)}if(_&&_.autoScaleSize){var b=1/c;this.scale(b,b)}this._clipPoint&&r.restore(),this._startX=n,this._startY=u}_drawUnderline(t,e,i,s){var r=this._lineWidths[s];switch(t){case"center":e-=r/2;break;case"right":e-=r}i+=this._charSize.height,this._graphics.drawLine(e,i,e+r,i,this.underlineColor||this.color,1)}typeset(){if(this._isChanged=!1,!this._text)return this._clipPoint=null,this._textWidth=this._textHeight=0,void this.graphics.clear(!0);i.Render.isConchApp?window.conchTextCanvas.font=this._getContextFont():i.Browser.context.font=this._getContextFont(),this._lines.length=0,this._lineWidths.length=0,this._isPassWordMode()?this._parseLines(this._getPassWordTxt(this._text)):this._parseLines(this._text),this._evalTextSize(),this._checkEnabledViewportOrNot()?this._clipPoint||(this._clipPoint=new f(0,0)):this._clipPoint=null,this._renderText()}_evalTextSize(){var t,e;t=Math.max.apply(this,this._lineWidths);let i=this._style.currBitmapFont;if(i){let t=i.getMaxHeight();i.autoScaleSize&&(t=this.fontSize),e=this._lines.length*(t+this.leading)+this.padding[0]+this.padding[2]}else e=this._lines.length*(this._charSize.height+this.leading)+this.padding[0]+this.padding[2],this._lines.length&&(e-=this.leading);t==this._textWidth&&e==this._textHeight||(this._textWidth=t,this._textHeight=e)}_checkEnabledViewportOrNot(){return this.overflow==Me.SCROLL&&(this._width>0&&this._textWidth>this._width||this._height>0&&this._textHeight>this._height)}changeText(t){this._text!==t&&(this.lang(t+""),this._graphics&&this._graphics.replaceText(this._text)||this.typeset())}_parseLines(t){var e=this.wordWrap||this.overflow==Me.HIDDEN;if(e)var s=this._getWordWrapWidth();var r=this._style.currBitmapFont;if(r)this._charSize.width=r.getMaxWidth(),this._charSize.height=r.getMaxHeight();else{var a=null;(a=i.Render.isConchApp?window.conchTextCanvas.measureText(Me._testWord):i.Browser.context.measureText(Me._testWord))||(a={width:100}),this._charSize.width=a.width,this._charSize.height=a.height||this.fontSize}for(var n=t.replace(/\r\n/g,"\n").split("\n"),h=0,o=n.length;he)if(this.wordWrap){var l=t.substring(n,h),_=l.charCodeAt(l.length-1);if(_<19968||_>40869){var u=/(?:[^\s\!-\/])+$/.exec(l);u&&(h=u.index+n,0==u.index?h+=l.length:l=t.substring(n,h))}if(i.push(l),this._lineWidths.push(a-r),n=h,!(h+se?e:t,this._clipPoint.x=t,this._renderText()}}get scrollX(){return this._clipPoint?this._clipPoint.x:0}set scrollY(t){if(!(this.overflow!=Me.SCROLL||this.textHeighte?e:t,this._clipPoint.y=t,this._renderText()}}get scrollY(){return this._clipPoint?this._clipPoint.y:0}get maxScrollX(){return this.textWidth-1&&(t=t.replace("^^","")),this._restrictPattern=new RegExp(t,"g")):this._restrictPattern=null}set editable(t){this._editable=t,i.Render.isConchApp&&Ie.input.setForbidEdit(!t)}get editable(){return this._editable}get maxChars(){return this._maxChars}set maxChars(t){t<=0&&(t=1e5),this._maxChars=t}get prompt(){return this._prompt}set prompt(t){!this._text&&t&&super.set_color(this._promptColor),this.promptColor=this._promptColor,this._text?super.set_text(this._text==this._prompt?t:this._text):super.set_text(t),this._prompt=Me.langPacks&&Me.langPacks[t]?Me.langPacks[t]:t}get promptColor(){return this._promptColor}set promptColor(t){this._promptColor=t,this._content||super.set_color(t)}get type(){return this._type}set type(t){this._getTextStyle().asPassword="password"===t,this._type=t}}Ie.TYPE_TEXT="text",Ie.TYPE_PASSWORD="password",Ie.TYPE_EMAIL="email",Ie.TYPE_URL="url",Ie.TYPE_NUMBER="number",Ie.TYPE_RANGE="range",Ie.TYPE_DATE="date",Ie.TYPE_MONTH="month",Ie.TYPE_WEEK="week",Ie.TYPE_TIME="time",Ie.TYPE_DATE_TIME="datetime",Ie.TYPE_DATE_TIME_LOCAL="datetime-local",Ie.TYPE_SEARCH="search",Ie.IOS_IFRAME=!1,Ie.inputHeight=45,Ie.isInputting=!1,Ee.regClass("laya.display.Input",Ie),Ee.regClass("Laya.Input",Ie);class Pe{constructor(){this.preOvers=[],this.preDowns=[],this.preRightDowns=[],this.enable=!0,this._event=new Ht,this._lastClickTime=0}_clearTempArrs(){Pe._oldArr.length=0,Pe._newArr.length=0,Pe._tEleArr.length=0}getTouchFromArr(t,e){var i,s,r;for(s=e.length,i=0;i=0;i--)e[i].id==t&&e.splice(i,1)}createTouchO(t,e){var i;return(i=s.getItem("TouchData")||{}).id=e,i.tar=t,i}onMouseDown(t,e,i=!1){var s,r,a,n;this.enable&&(s=this.getTouchFromArr(e,this.preOvers),a=this.getEles(t,null,Pe._tEleArr),s?s.tar=t:(r=this.createTouchO(t,e),this.preOvers.push(r)),Qt.onMobile&&this.sendEvents(a,Ht.MOUSE_OVER),n=i?this.preDowns:this.preRightDowns,(s=this.getTouchFromArr(e,n))?s.tar=t:(r=this.createTouchO(t,e),n.push(r)),this.sendEvents(a,i?Ht.MOUSE_DOWN:Ht.RIGHT_MOUSE_DOWN),this._clearTempArrs())}sendEvents(t,e){var i,s,r;for(s=t.length,this._event._stoped=!1,r=t[0],i=0;i=0){o.splice(l,o.length-l);break}r.push(s)}r.length>0&&this.sendEvents(r,Ht.MOUSE_OUT),o.length>0&&this.sendEvents(o,Ht.MOUSE_OVER)}}onMouseMove(t,e){var i,s;this.enable&&((i=this.getTouchFromArr(e,this.preOvers))?(this.checkMouseOutAndOverOfMove(t,i.tar),i.tar=t,s=this.getEles(t,null,Pe._tEleArr)):(s=this.getEles(t,null,Pe._tEleArr),this.sendEvents(s,Ht.MOUSE_OVER),this.preOvers.push(this.createTouchO(t,e))),this.sendEvents(s,Ht.MOUSE_MOVE),this._clearTempArrs())}getLastOvers(){return Pe._tEleArr.length=0,this.preOvers.length>0&&this.preOvers[0].tar?this.getEles(this.preOvers[0].tar,null,Pe._tEleArr):(Pe._tEleArr.push(i.stage),Pe._tEleArr)}stageMouseOut(){var t;t=this.getLastOvers(),this.preOvers.length=0,this.sendEvents(t,Ht.MOUSE_OUT)}onMouseUp(t,e,i=!1){if(this.enable){var r,a,n,h,o,l,_,u,c=Qt.onMobile;if(a=this.getEles(t,null,Pe._tEleArr),this.sendEvents(a,i?Ht.MOUSE_UP:Ht.RIGHT_MOUSE_UP),u=i?this.preDowns:this.preRightDowns,r=this.getTouchFromArr(e,u)){var d,p=Qt.now();if(d=p-this._lastClickTime<300,this._lastClickTime=p,t==r.tar)_=a;else for(n=this.getEles(r.tar,null,Pe._oldArr),(_=Pe._newArr).length=0,o=n.length,h=0;h=0&&_.push(l);_.length>0&&this.sendEvents(_,i?Ht.CLICK:Ht.RIGHT_CLICK),i&&d&&this.sendEvents(_,Ht.DOUBLE_CLICK),this.removeTouchFromArr(e,u),r.tar=null,s.recover("TouchData",r)}else;(r=this.getTouchFromArr(e,this.preOvers))&&c&&((_=this.getEles(r.tar,null,_))&&_.length>0&&this.sendEvents(_,Ht.MOUSE_OUT),this.removeTouchFromArr(e,this.preOvers),r.tar=null,s.recover("TouchData",r)),this._clearTempArrs()}}}Pe.I=new Pe,Pe._oldArr=[],Pe._newArr=[],Pe._tEleArr=[];class Le{constructor(){this.mouseX=0,this.mouseY=0,this.disableMouseEvent=!1,this.mouseDownTime=0,this.mouseMoveAccuracy=2,this._event=new Ht,this._captureSp=null,this._captureChain=[],this._captureExlusiveMode=!1,this._hitCaputreSp=!1,this._point=new f,this._rect=new m,this._lastMoveTimer=0,this._prePoint=new f,this._touchIDs={},this._curTouchID=NaN,this._id=1}__init__(t,e){this._stage=t;var i=this;e.oncontextmenu=function(t){if(Le.enabled)return!1},e.addEventListener("mousedown",(function(t){Le.enabled&&(Qt.onIE||t.cancelable&&t.preventDefault(),i.mouseDownTime=Qt.now(),i.runEvent(t))})),e.addEventListener("mouseup",(function(t){Le.enabled&&(t.cancelable&&t.preventDefault(),i.mouseDownTime=-Qt.now(),i.runEvent(t))}),!0),e.addEventListener("mousemove",(function(t){if(Le.enabled){t.cancelable&&t.preventDefault();var e=Qt.now();if(e-i._lastMoveTimer<10)return;i._lastMoveTimer=e,i.runEvent(t)}}),!0),e.addEventListener("mouseout",(function(t){Le.enabled&&i.runEvent(t)})),e.addEventListener("mouseover",(function(t){Le.enabled&&i.runEvent(t)})),e.addEventListener("touchstart",(function(t){Le.enabled&&(Le._isFirstTouch||Ie.isInputting||t.cancelable&&t.preventDefault(),i.mouseDownTime=Qt.now(),i.runEvent(t))})),e.addEventListener("touchend",(function(t){Le.enabled?(Le._isFirstTouch||Ie.isInputting||t.cancelable&&t.preventDefault(),Le._isFirstTouch=!1,i.mouseDownTime=-Qt.now(),i.runEvent(t)):i._curTouchID=NaN}),!0),e.addEventListener("touchmove",(function(t){Le.enabled&&(t.cancelable&&t.preventDefault(),i.runEvent(t))}),!0),e.addEventListener("touchcancel",(function(t){Le.enabled?(t.cancelable&&t.preventDefault(),i.runEvent(t)):i._curTouchID=NaN}),!0),e.addEventListener("mousewheel",(function(t){Le.enabled&&i.runEvent(t)})),e.addEventListener("DOMMouseScroll",(function(t){Le.enabled&&i.runEvent(t)}))}initEvent(t,e=null){var i;this._event._stoped=!1,this._event.nativeEvent=e||t,this._target=null,this._point.setTo(t.pageX||t.clientX,t.pageY||t.clientY),this._stage._canvasTransform&&(this._stage._canvasTransform.invertTransformPoint(this._point),this.mouseX=this._point.x,this.mouseY=this._point.y),this._event.touchId=t.identifier||0,this._tTouchID=this._event.touchId,(i=Pe.I._event)._stoped=!1,i.nativeEvent=this._event.nativeEvent,i.touchId=this._event.touchId}checkMouseWheel(t){this._event.delta=t.wheelDelta?.025*t.wheelDelta:-t.detail;for(var e=Pe.I.getLastOvers(),i=0,s=e.length;i-1;a--){var n=t._children[a];if(!n.destroyed&&n._mouseState>1&&n._visible&&this.check(n,e,i,s))return!0}for(a=t._extUIChild.length-1;a>=0;a--){var h=t._extUIChild[a];if(!h.destroyed&&h._mouseState>1&&h._visible&&this.check(h,e,i,s))return!0}}var o=!(!t.hitTestPrior||t.mouseThrough||this.disableMouseEvent)||this.hitTest(t,e,i);return o?(this._target=t,s.call(this,t),this._target==this._hitCaputreSp&&(this._hitCaputreSp=!0)):s===this.onMouseUp&&t===this._stage&&(this._target=this._stage,s.call(this,this._target)),o}hitTest(t,e,i){var s=!1;t.scrollRect&&(e-=t._style.scrollRect.x,i-=t._style.scrollRect.y);var r=t._style.hitArea;return r&&r._hit?r.contains(e,i):((t.width>0&&t.height>0||t.mouseThrough||r)&&(s=t.mouseThrough?t.getGraphicBounds().contains(e,i):(r||this._rect.setTo(0,0,t.width,t.height)).contains(e,i)),s)}_checkAllBaseUI(t,e,i){var s=this.handleExclusiveCapture(this.mouseX,this.mouseY,i);return!!s||(s=this.check(this._stage,this.mouseX,this.mouseY,i),this.handleCapture(this.mouseX,this.mouseY,i)||s)}check3DUI(t,e,i){for(var s=this._stage._3dUI,r=0,a=!1;r1&&n._visible&&(a=a||this.check(n,this.mouseX,this.mouseY,i))}return this._stage._curUIBase=this._stage,a}handleExclusiveCapture(t,e,i){if(this._captureExlusiveMode&&this._captureSp&&this._captureChain.length>0){var s;this._point.setTo(t,e);for(var r=0;r0){var s;this._point.setTo(t,e);for(var r=0;r=this.mouseMoveAccuracy&&(this._prePoint.x=t.clientX,this._prePoint.y=t.clientY,this.initEvent(t),this._checkAllBaseUI(this.mouseX,this.mouseY,this.onMouseMove));break;case"touchstart":Le._isTouchRespond=!0,this._isLeftMouse=!0;var r=t.changedTouches;for(e=0,i=r.length;e0){for(let i=0,s=e-1;i<=s;i++){let e=t[i];this._map[e.key]=null,null!==e.method&&(e.run(),e.clear()),this._pool.push(e),i===s&&(s=t.length-1)}t.length=0}}_getHandler(t,e){var s=t?t.$_GID||(t.$_GID=i.Utils.getGID()):0,r=e.$_TID||(e.$_TID=i.Timer._mid++);return this._map[s+"."+r]}callLater(t,e,i=null){if(null==this._getHandler(t,e)){let a;a=this._pool.length?this._pool.pop():new Be,a.caller=t,a.method=e,a.args=i;var s=t?t.$_GID:0,r=e.$_TID;a.key=s+"."+r,this._map[a.key]=a,this._laters.push(a)}}runCallLater(t,e){var i=this._getHandler(t,e);i&&null!=i.method&&(this._map[i.key]=null,i.run(),i.clear())}}De.I=new De;class Be{clear(){this.caller=null,this.method=null,this.args=null}run(){var t=this.caller;if(t&&t.destroyed)return this.clear();var e=this.method,i=this.args;null!=e&&(i?e.apply(t,i):e.call(t))}}class Fe{}Fe.createShaderCondition=function(t){var e="(function() {return "+t+";})";return window.Laya._runScript(e)},Fe.changeWebGLSize=function(t,e){se.onStageResize(t,e)};class Oe{static setPerformanceDataTool(t){this.performanceTool=t}static begainSample(t){this.performanceTool&&this.performanceTool.enable&&this.performanceTool.BegainSample(t)}static endSample(t){return this.performanceTool&&this.performanceTool.enable?this.performanceTool.EndSample(t):0}static expoertFile(t){if(this.performanceTool)return this.performanceTool.enable?this.performanceTool.exportPerformanceFile():null}static showFunSampleFun(t){this.performanceTool.showFunSampleFun(t)}static set enable(t){this.performanceTool&&(this.performanceTool.enable=t)}static get enable(){return!!this.performanceTool&&this._enable}static set enableDataExport(t){this.performanceTool&&(this.performanceTool.enableDataExport=t)}static get enableDataExport(){return!!this.performanceTool&&this.performanceTool.enableDataExport}}Oe.performanceTool=null,Oe._enable=!1,Oe.PERFORMANCE_LAYA="Laya",Oe.PERFORMANCE_LAYA_3D="Laya/3D",Oe.PERFORMANCE_LAYA_2D="Laya/2D",Oe.PERFORMANCE_LAYA_3D_PRERENDER="Laya/3D/PreRender",Oe.PERFORMANCE_LAYA_3D_UPDATESCRIPT="Laya/3D/UpdateScript",Oe.PERFORMANCE_LAYA_3D_PHYSICS="Laya/3D/Physics",Oe.PERFORMANCE_LAYA_3D_PHYSICS_SIMULATE="Laya/3D/Physics/simulate",Oe.PERFORMANCE_LAYA_3D_PHYSICS_CHARACTORCOLLISION="Laya/3D/Physics/updataCharacters&Collisions",Oe.PERFORMANCE_LAYA_3D_PHYSICS_EVENTSCRIPTS="Laya/3D/Physics/eventScripts",Oe.PERFORMANCE_LAYA_3D_RENDER="Laya/3D/Render",Oe.PERFORMANCE_LAYA_3D_RENDER_SHADOWMAP="Laya/3D/Render/ShadowMap",Oe.PERFORMANCE_LAYA_3D_RENDER_CLUSTER="Laya/3D/Render/Cluster",Oe.PERFORMANCE_LAYA_3D_RENDER_CULLING="Laya/3D/Render/Culling",Oe.PERFORMANCE_LAYA_3D_RENDER_RENDERDEPTHMDOE="Laya/3D/Render/RenderDepthMode",Oe.PERFORMANCE_LAYA_3D_RENDER_RENDEROPAQUE="Laya/3D/Render/RenderOpaque",Oe.PERFORMANCE_LAYA_3D_RENDER_RENDERCOMMANDBUFFER="Laya/3D/Render/RenderCommandBuffer",Oe.PERFORMANCE_LAYA_3D_RENDER_RENDERTRANSPARENT="Laya/3D/Render/RenderTransparent",Oe.PERFORMANCE_LAYA_3D_RENDER_POSTPROCESS="Laya/3D/Render/PostProcess",window.PerformancePlugin=Oe;class Ne extends Se{constructor(){super(),this.offset=new f,this._frameRate="fast",this.designWidth=0,this.designHeight=0,this.canvasRotation=!1,this.canvasDegree=0,this.renderingEnabled=!0,this.screenAdaptationEnabled=!0,this._canvasTransform=new p,this._screenMode="none",this._scaleMode="noscale",this._alignV="top",this._alignH="left",this._bgColor="black",this._mouseMoveTime=0,this._renderCount=0,this._safariOffsetY=0,this._frameStartTime=0,this._previousOrientation=Qt.window.orientation,this._wgColor=[0,0,0,1],this._scene3Ds=[],this._globalRepaintSet=!1,this._globalRepaintGet=!1,this._3dUI=[],this._curUIBase=null,this.useRetinalCanvas=!1,super.set_transform(this._createTransform()),this.mouseEnabled=!0,this.hitTestPrior=!0,this.autoSize=!1,this._setBit(ge.DISPLAYED_INSTAGE,!0),this._setBit(ge.ACTIVE_INHIERARCHY,!0),this._isFocused=!0,this._isVisibility=!0,this.useRetinalCanvas=e.useRetinalCanvas;var t=Qt.window;t.addEventListener("focus",()=>{this._isFocused=!0,this.event(Ht.FOCUS),this.event(Ht.FOCUS_CHANGE)}),t.addEventListener("blur",()=>{this._isFocused=!1,this.event(Ht.BLUR),this.event(Ht.FOCUS_CHANGE),this._isInputting()&&(Ie.inputElement.target.focus=!1)});var i="visibilityState",s="visibilitychange",r=t.document;void 0!==r.hidden?(s="visibilitychange",i="visibilityState"):void 0!==r.mozHidden?(s="mozvisibilitychange",i="mozVisibilityState"):void 0!==r.msHidden?(s="msvisibilitychange",i="msVisibilityState"):void 0!==r.webkitHidden&&(s="webkitvisibilitychange",i="webkitVisibilityState"),t.document.addEventListener(s,()=>{"hidden"==Qt.document[i]?(this._isVisibility=!1,this._isInputting()&&(Ie.inputElement.target.focus=!1)):this._isVisibility=!0,this.renderingEnabled=this._isVisibility,this.event(Ht.VISIBILITY_CHANGE)}),t.addEventListener("resize",()=>{var t=Qt.window.orientation;null!=t&&t!=this._previousOrientation&&this._isInputting()&&(Ie.inputElement.target.focus=!1),this._previousOrientation=t,this._isInputting()||(Qt.onSafari&&(this._safariOffsetY=(Qt.window.__innerHeight||Qt.document.body.clientHeight||Qt.document.documentElement.clientHeight)-Qt.window.innerHeight),this._resetCanvas())}),t.addEventListener("orientationchange",t=>{this._resetCanvas()}),this.on(Ht.MOUSE_MOVE,this,this._onmouseMove),Qt.onMobile&&this.on(Ht.MOUSE_DOWN,this,this._onmouseMove)}_isInputting(){return Qt.onMobile&&Ie.isInputting}set width(t){this.designWidth=t,super.set_width(t),i.systemTimer.callLater(this,this._changeCanvasSize)}get width(){return super.get_width()}set height(t){this.designHeight=t,super.set_height(t),i.systemTimer.callLater(this,this._changeCanvasSize)}get height(){return super.get_height()}set transform(t){super.set_transform(t)}get transform(){return this._tfChanged&&this._adjustTransform(),this._transform=this._transform||this._createTransform()}get isFocused(){return this._isFocused}get isVisibility(){return this._isVisibility}_changeCanvasSize(){this.setScreenSize(Qt.clientWidth*Qt.pixelRatio,Qt.clientHeight*Qt.pixelRatio)}_resetCanvas(){this.screenAdaptationEnabled&&this._changeCanvasSize()}setScreenSize(t,e){var i=!1;if(this._screenMode!==Ne.SCREEN_NONE&&(i=(t/e<1?Ne.SCREEN_VERTICAL:Ne.SCREEN_HORIZONTAL)!==this._screenMode)){var s=e;e=t,t=s}this.canvasRotation=i;var r=ae._mainCanvas,a=r.source.style,n=this._canvasTransform.identity(),h=this._scaleMode,o=t/this.designWidth,l=e/this.designHeight,_=this.useRetinalCanvas?t:this.designWidth,u=this.useRetinalCanvas?e:this.designHeight,c=t,d=e,p=Qt.pixelRatio;switch(this._width=this.designWidth,this._height=this.designHeight,h){case Ne.SCALE_NOSCALE:o=l=1,c=this.designWidth,d=this.designHeight;break;case Ne.SCALE_SHOWALL:o=l=Math.min(o,l),_=c=Math.round(this.designWidth*o),u=d=Math.round(this.designHeight*l);break;case Ne.SCALE_NOBORDER:o=l=Math.max(o,l),c=Math.round(this.designWidth*o),d=Math.round(this.designHeight*l);break;case Ne.SCALE_FULL:o=l=1,this._width=_=t,this._height=u=e;break;case Ne.SCALE_FIXED_WIDTH:l=o,this._height=u=Math.round(e/o);break;case Ne.SCALE_FIXED_HEIGHT:o=l,this._width=_=Math.round(t/l);break;case Ne.SCALE_FIXED_AUTO:t/e0?1:-1:t}get scaleMode(){return this._scaleMode}set scaleMode(t){this._scaleMode=t,i.systemTimer.callLater(this,this._changeCanvasSize)}get alignH(){return this._alignH}set alignH(t){this._alignH=t,i.systemTimer.callLater(this,this._changeCanvasSize)}get alignV(){return this._alignV}set alignV(t){this._alignV=t,i.systemTimer.callLater(this,this._changeCanvasSize)}get bgColor(){return this._bgColor}set bgColor(t){this._bgColor=t,this._wgColor=t?J.create(t).arrColor:null,ae.canvas.style.background=t||"none"}get mouseX(){return Math.round(Le.instance.mouseX/this.clientScaleX)}get mouseY(){return Math.round(Le.instance.mouseY/this.clientScaleY)}getMousePoint(){return f.TEMP.setTo(this.mouseX,this.mouseY)}get clientScaleX(){return this._transform?this._transform.getScaleX():1}get clientScaleY(){return this._transform?this._transform.getScaleY():1}get screenMode(){return this._screenMode}set screenMode(t){this._screenMode=t}repaint(t=_e.REPAINT_CACHE){this._repaint|=t}parentRepaint(t=_e.REPAINT_CACHE){}_loop(){return this._globalRepaintGet=this._globalRepaintSet,this._globalRepaintSet=!1,this.render(ae._context,0,0),!0}getFrameTm(){return this._frameStartTime}_onmouseMove(t){this._mouseMoveTime=Qt.now()}getTimeFromFrameStart(){return Qt.now()-this._frameStartTime}set visible(t){this.visible!==t&&(super.set_visible(t),ae._mainCanvas.source.style.visibility=t?"visible":"hidden")}get visible(){return super.visible}render(t,e,i){if(window.conch)this.renderToNative(t,e,i);else{if(this._frameRate===Ne.FRAME_SLEEP){var s=Qt.now();if(!(s-this._frameStartTime>=1e3))return;this._frameStartTime=s}else{if(!this._visible)return this._renderCount++,void(this._renderCount%5==0&&(De.I._update(),X.loopCount++,Et.loopCount=X.loopCount,this._updateTimers()));this._frameStartTime=Qt.now(),Et.loopStTm=this._frameStartTime}this._renderCount++;var r=(this._frameRate===Ne.FRAME_MOUSE?this._frameStartTime-this._mouseMoveTime<2e3?Ne.FRAME_FAST:Ne.FRAME_SLOW:this._frameRate)!==Ne.FRAME_SLOW,a=this._renderCount%2==0;if(X.renderSlow=!r,r||a){if(De.I._update(),X.loopCount++,Et.loopCount=X.loopCount,Oe.begainSample(Oe.PERFORMANCE_LAYA),this.renderingEnabled){for(var n=0,h=this._scene3Ds.length;n=0||this._3dUI.push(e)}remove3DUI(t){var e=t.rootView,i=this._3dUI.indexOf(e);return i>=0&&(this._3dUI.splice(i,1),!0)}}Ne.SCALE_NOSCALE="noscale",Ne.SCALE_EXACTFIT="exactfit",Ne.SCALE_SHOWALL="showall",Ne.SCALE_NOBORDER="noborder",Ne.SCALE_FULL="full",Ne.SCALE_FIXED_WIDTH="fixedwidth",Ne.SCALE_FIXED_HEIGHT="fixedheight",Ne.SCALE_FIXED_AUTO="fixedauto",Ne.ALIGN_LEFT="left",Ne.ALIGN_RIGHT="right",Ne.ALIGN_CENTER="center",Ne.ALIGN_TOP="top",Ne.ALIGN_MIDDLE="middle",Ne.ALIGN_BOTTOM="bottom",Ne.SCREEN_NONE="none",Ne.SCREEN_HORIZONTAL="horizontal",Ne.SCREEN_VERTICAL="vertical",Ne.FRAME_FAST="fast",Ne.FRAME_SLOW="slow",Ne.FRAME_MOUSE="mouse",Ne.FRAME_SLEEP="sleep",Ne.clear=function(t){ee.set2DRenderConfig();var s=g.instance;U.worldScissorTest&&s.disable(s.SCISSOR_TEST);var r=ae.context,a=0==r._submits._length||e.preserveDrawingBuffer?J.create(t).arrColor:i.stage._wgColor;a?r.clearBG(a[0],a[1],a[2],a[3]):r.clearBG(0,0,0,0),U.clear()},Ee.regClass("laya.display.Stage",Ne),Ee.regClass("Laya.Stage",Ne);class Ue{static __init__(){Ue._addEvent("keydown"),Ue._addEvent("keypress"),Ue._addEvent("keyup")}static _addEvent(t){i.Browser.document.addEventListener(t,(function(e){Ue._dispatch(e,t)}),!0)}static _dispatch(t,e){if(Ue.enabled){Ue._event._stoped=!1,Ue._event.nativeEvent=t,Ue._event.keyCode=t.keyCode||t.which||t.charCode,"keydown"===e?Ue._pressKeys[Ue._event.keyCode]=!0:"keyup"===e&&(Ue._pressKeys[Ue._event.keyCode]=null);for(var s=i.stage.focus&&null!=i.stage.focus.event&&i.stage.focus.displayedInStage?i.stage.focus:i.stage,r=s;r;)r.event(e,Ue._event.setTo(e,r,s)),r=r.parent}}static hasKeyDown(t){return Ue._pressKeys[t]}}Ue._pressKeys={},Ue.enabled=!0,Ue._event=new Ht;class Ge extends S{constructor(){super(...arguments),this.isStopped=!1}set volume(t){}get volume(){return 1}get position(){return 0}get duration(){return 0}play(){}stop(){this.completeHandler&&this.completeHandler.runWith(!1)}pause(){}resume(){}__runComplete(t){t&&t.runWith(!0)}}class ke extends Ge{constructor(t){super(),this._audio=null,this._onEnd=this.__onEnd.bind(this),this._resumePlay=this.__resumePlay.bind(this),t.addEventListener("ended",this._onEnd),this._audio=t}__onEnd(t){if(1==this.loops)return this.completeHandler&&(i.systemTimer.once(10,this,this.__runComplete,[this.completeHandler],!1),this.completeHandler=null),this.stop(),void this.event(Ht.COMPLETE);this.loops>0&&this.loops--,this.startTime=0,this.play()}__resumePlay(){if(this._audio&&this._audio.removeEventListener("canplay",this._resumePlay),!this.isStopped)try{this._audio.currentTime=this.startTime,Qt.container.appendChild(this._audio),this._audio.play()}catch(t){this.event(Ht.ERROR)}}play(){this.isStopped=!1;try{this._audio.playbackRate=i.SoundManager.playbackRate,this._audio.currentTime=this.startTime}catch(t){return void this._audio.addEventListener("canplay",this._resumePlay)}i.SoundManager.addChannel(this),Qt.container.appendChild(this._audio),"play"in this._audio&&this._audio.play()}get position(){return this._audio?this._audio.currentTime:0}get duration(){return this._audio?this._audio.duration:0}stop(){super.stop(),this.isStopped=!0,i.SoundManager.removeChannel(this),this.completeHandler=null,this._audio&&("pause"in this._audio&&i.Render.isConchApp&&this._audio.stop(),this._audio.pause(),this._audio.removeEventListener("ended",this._onEnd),this._audio.removeEventListener("canplay",this._resumePlay),i.Browser.onIE||this._audio!=i.AudioSound._musicAudio&&i.Pool.recover("audio:"+this.url,this._audio),Qt.removeElement(this._audio),this._audio=null,i.SoundManager.autoReleaseSound&&i.SoundManager.disposeSoundLater(this.url))}pause(){this.isStopped=!0,i.SoundManager.removeChannel(this),this._audio&&("pause"in this._audio&&this._audio.pause(),i.SoundManager.autoReleaseSound&&i.SoundManager.disposeSoundLater(this.url))}resume(){var t=this._audio;t&&(this.isStopped=!1,0==t.readyState&&(t.src=this.url,t.addEventListener("canplay",this._resumePlay),t.load()),i.SoundManager.addChannel(this),"play"in t&&t.play())}set volume(t){this._audio&&(this._audio.volume=t)}get volume(){return this._audio?this._audio.volume:1}}class We extends S{constructor(){super(...arguments),this.loaded=!1}dispose(){var t=We._audioCache[this.url];s.clearBySign("audio:"+this.url),t&&(ae.isConchApp||(t.src=""),delete We._audioCache[this.url])}static _initMusicAudio(){We._musicAudio||(We._musicAudio||(We._musicAudio=Qt.createElement("audio")),ae.isConchApp||Qt.document.addEventListener("mousedown",We._makeMusicOK))}static _makeMusicOK(){Qt.document.removeEventListener("mousedown",We._makeMusicOK),We._musicAudio.src?We._musicAudio.play():(We._musicAudio.src="",We._musicAudio.load())}load(t){var e;if(t=M.formatURL(t),this.url=t,t==i.SoundManager._bgMusic?(We._initMusicAudio(),(e=We._musicAudio).src!=t&&(delete We._audioCache[e.src],e=null)):e=We._audioCache[t],e&&e.readyState>=2)this.event(Ht.COMPLETE);else{e||(t==i.SoundManager._bgMusic?(We._initMusicAudio(),e=We._musicAudio):e=Qt.createElement("audio"),We._audioCache[t]=e,e.src=t),e.addEventListener("canplaythrough",onLoaded),e.addEventListener("error",onErr);var s=this;this.audio=e,e.load?e.load():onErr()}function onLoaded(){offs(),s.loaded=!0,s.event(Ht.COMPLETE)}function onErr(){e.load=null,offs(),s.event(Ht.ERROR)}function offs(){e.removeEventListener("canplaythrough",onLoaded),e.removeEventListener("error",onErr)}}play(t=0,e=0){if(!this.url)return null;var r,a;if(this.url==i.SoundManager._bgMusic?""!=(r=We._musicAudio).src&&r.src!=this.url&&(delete We._audioCache[r.src],We._audioCache[this.url]=r):r=We._audioCache[this.url],!r)return null;a=s.getItem("audio:"+this.url),ae.isConchApp?a||((a=Qt.createElement("audio")).src=this.url):this.url==i.SoundManager._bgMusic?(We._initMusicAudio(),(a=We._musicAudio).src=this.url):a=a||r.cloneNode(!0);var n=new ke(a);return n.url=this.url,n.loops=e,n.startTime=t,n.play(),i.SoundManager.addChannel(n),n}get duration(){var t;return(t=We._audioCache[this.url])?t.duration:0}}We._audioCache={};class Ye extends Ge{constructor(){super(),this.bufferSource=null,this._currentTime=0,this._volume=1,this._startTime=0,this._pauseTime=0,this.context=i.WebAudioSound.ctx,this._onPlayEnd=$.bind(this.__onPlayEnd,this),this.context.createGain?this.gain=this.context.createGain():this.gain=this.context.createGainNode()}play(){if(i.SoundManager.addChannel(this),this.isStopped=!1,this._clearBufferSource(),this.audioBuffer){if(this.startTime>=this.duration)return this.stop();var t=this.context,e=this.gain,s=t.createBufferSource();this.bufferSource=s,s.buffer=this.audioBuffer,s.connect(e),e&&e.disconnect(),e.connect(t.destination),s.onended=this._onPlayEnd,this._startTime=Qt.now(),this.gain.gain.setTargetAtTime?this.gain.gain.setTargetAtTime(this._volume,this.context.currentTime,Ye.SetTargetDelay):this.gain.gain.value=this._volume,0==this.loops&&(s.loop=!0),s.playbackRate.setTargetAtTime?s.playbackRate.setTargetAtTime(i.SoundManager.playbackRate,this.context.currentTime,Ye.SetTargetDelay):s.playbackRate.value=i.SoundManager.playbackRate,s.start(0,this.startTime),this._currentTime=0}}__onPlayEnd(){if(1==this.loops)return this.completeHandler&&(i.timer.once(10,this,this.__runComplete,[this.completeHandler],!1),this.completeHandler=null),this.stop(),void this.event(Ht.COMPLETE);this.loops>0&&this.loops--,this.startTime=0,this.play()}get position(){return this.bufferSource?(Qt.now()-this._startTime)/1e3+this.startTime:0}get duration(){return this.audioBuffer?this.audioBuffer.duration:0}_clearBufferSource(){if(this.bufferSource){var t=this.bufferSource;t.stop?t.stop(0):t.noteOff(0),t.disconnect(0),t.onended=null,Ye._tryCleanFailed||this._tryClearBuffer(t),this.bufferSource=null}}_tryClearBuffer(t){try{t.buffer=null}catch(t){Ye._tryCleanFailed=!0}}stop(){super.stop(),this._clearBufferSource(),this.audioBuffer=null,this.gain&&this.gain.disconnect(),this.isStopped=!0,i.SoundManager.removeChannel(this),this.completeHandler=null,i.SoundManager.autoReleaseSound&&i.SoundManager.disposeSoundLater(this.url)}pause(){this.isStopped||(this._pauseTime=this.position),this._clearBufferSource(),this.gain&&this.gain.disconnect(),this.isStopped=!0,i.SoundManager.removeChannel(this),i.SoundManager.autoReleaseSound&&i.SoundManager.disposeSoundLater(this.url)}resume(){this.startTime=this._pauseTime,this.play()}set volume(t){this._volume=t,this.isStopped||(this.gain.gain.setTargetAtTime?this.gain.gain.setTargetAtTime(t,this.context.currentTime,Ye.SetTargetDelay):this.gain.gain.value=t)}get volume(){return this._volume}}Ye._tryCleanFailed=!1,Ye.SetTargetDelay=.001;class Ve extends S{constructor(){super(...arguments),this.loaded=!1,this._disposed=!1}static decode(){Ve.buffs.length<=0||Ve.isDecoding||(Ve.isDecoding=!0,Ve.tInfo=Ve.buffs.shift(),Ve.ctx.decodeAudioData(Ve.tInfo.buffer,Ve._done,Ve._fail))}static _done(t){Ve.e.event("loaded:"+Ve.tInfo.url,t),Ve.isDecoding=!1,Ve.decode()}static _fail(){Ve.e.event("err:"+Ve.tInfo.url,null),Ve.isDecoding=!1,Ve.decode()}static _playEmptySound(){if(null!=Ve.ctx){var t=Ve.ctx.createBufferSource();t.buffer=Ve._miniBuffer,t.connect(Ve.ctx.destination),t.start(0,0,0)}}static _unlock(){Ve._unlocked||(Ve._playEmptySound(),"running"==Ve.ctx.state&&(window.document.removeEventListener("mousedown",Ve._unlock,!0),window.document.removeEventListener("touchend",Ve._unlock,!0),window.document.removeEventListener("touchstart",Ve._unlock,!0),Ve._unlocked=!0))}static initWebAudio(){"running"!=Ve.ctx.state&&(Ve._unlock(),window.document.addEventListener("mousedown",Ve._unlock,!0),window.document.addEventListener("touchend",Ve._unlock,!0),window.document.addEventListener("touchstart",Ve._unlock,!0))}load(t){var e=this;if(t=M.formatURL(t),this.url=t,this.audioBuffer=Ve._dataCache[t],this.audioBuffer)this._loaded(this.audioBuffer);else if(Ve.e.on("loaded:"+t,this,this._loaded),Ve.e.on("err:"+t,this,this._err),!Ve.__loadingSound[t]){Ve.__loadingSound[t]=!0;var i=new XMLHttpRequest;i.open("GET",t,!0),i.responseType="arraybuffer",i.onload=function(){e._disposed?e._removeLoadEvents():(e.data=i.response,Ve.buffs.push({buffer:e.data,url:e.url}),Ve.decode())},i.onerror=function(t){e._err()},i.send()}}_err(){this._removeLoadEvents(),Ve.__loadingSound[this.url]=!1,this.event(Ht.ERROR)}_loaded(t){this._removeLoadEvents(),this._disposed||(this.audioBuffer=t,Ve._dataCache[this.url]=this.audioBuffer,this.loaded=!0,this.event(Ht.COMPLETE))}_removeLoadEvents(){Ve.e.off("loaded:"+this.url,this,this._loaded),Ve.e.off("err:"+this.url,this,this._err)}__playAfterLoaded(){if(this.__toPlays){var t,e,i,s;for(e=(i=this.__toPlays).length,t=0;t=0||Xe._channels.push(t)}static removeChannel(t){var e;for(e=Xe._channels.length-1;e>=0;e--)Xe._channels[e]==t&&Xe._channels.splice(e,1)}static disposeSoundLater(t){Xe._lastSoundUsedTimeDic[t]=i.Browser.now(),Xe._isCheckingDispose||(Xe._isCheckingDispose=!0,i.timer.loop(5e3,null,Xe._checkDisposeSound))}static _checkDisposeSound(){var t,e=i.Browser.now(),s=!1;for(t in Xe._lastSoundUsedTimeDic)e-Xe._lastSoundUsedTimeDic[t]>3e4?(delete Xe._lastSoundUsedTimeDic[t],Xe.disposeSoundIfNotUsed(t)):s=!0;s||(Xe._isCheckingDispose=!1,i.timer.clear(null,Xe._checkDisposeSound))}static disposeSoundIfNotUsed(t){var e;for(e=Xe._channels.length-1;e>=0;e--)if(Xe._channels[e].url==t)return;Xe.destroySound(t)}static set autoStopMusic(t){i.stage.off(Ht.BLUR,null,Xe._stageOnBlur),i.stage.off(Ht.FOCUS,null,Xe._stageOnFocus),i.stage.off(Ht.VISIBILITY_CHANGE,null,Xe._visibilityChange),Xe._autoStopMusic=t,t&&(i.stage.on(Ht.BLUR,null,Xe._stageOnBlur),i.stage.on(Ht.FOCUS,null,Xe._stageOnFocus),i.stage.on(Ht.VISIBILITY_CHANGE,null,Xe._visibilityChange))}static get autoStopMusic(){return Xe._autoStopMusic}static _visibilityChange(){i.stage.isVisibility?Xe._stageOnFocus():Xe._stageOnBlur()}static _stageOnBlur(){Xe._isActive=!1,Xe._musicChannel&&(Xe._musicChannel.isStopped||(Xe._blurPaused=!0,Xe._musicChannel.pause())),Xe.stopAllSound(),i.stage.once(Ht.MOUSE_DOWN,null,Xe._stageOnFocus)}static _recoverWebAudio(){Ve.ctx&&"running"!=Ve.ctx.state&&Ve.ctx.resume&&Ve.ctx.resume()}static _stageOnFocus(){Xe._isActive=!0,Xe._recoverWebAudio(),i.stage.off(Ht.MOUSE_DOWN,null,Xe._stageOnFocus),Xe._blurPaused&&Xe._musicChannel&&Xe._musicChannel.isStopped&&(Xe._blurPaused=!1,Xe._musicChannel.resume())}static set muted(t){t!=Xe._muted&&(t&&Xe.stopAllSound(),Xe.musicMuted=t,Xe._muted=t)}static get muted(){return Xe._muted}static set soundMuted(t){Xe._soundMuted=t}static get soundMuted(){return Xe._soundMuted}static set musicMuted(t){t!=Xe._musicMuted&&(t?(Xe._bgMusic&&Xe._musicChannel&&!Xe._musicChannel.isStopped?i.Render.isConchApp?Xe._musicChannel._audio&&(Xe._musicChannel._audio.muted=!0):Xe._musicChannel.pause():Xe._musicChannel=null,Xe._musicMuted=t):(Xe._musicMuted=t,Xe._bgMusic&&Xe._musicChannel&&(i.Render.isConchApp?Xe._musicChannel._audio&&(Xe._musicChannel._audio.muted=!1):Xe._musicChannel.resume())))}static get musicMuted(){return Xe._musicMuted}static get useAudioMusic(){return Xe._useAudioMusic}static set useAudioMusic(t){Xe._useAudioMusic=t,Xe._musicClass=t?We:null}static playSound(t,e=1,s=null,r=null,a=0){if(!Xe._isActive||!t)return null;if(Xe._muted)return null;if(Xe._recoverWebAudio(),(t=M.formatURL(t))==Xe._bgMusic){if(Xe._musicMuted)return null}else{if(i.Render.isConchApp){var n=$.getFileExtension(t);if("wav"!=n&&"ogg"!=n)return alert("The sound only supports wav or ogg format,for optimal performance reason,please refer to the official website document."),null}if(Xe._soundMuted)return null}var h,o;return Qt._isMiniGame||(h=i.loader.getRes(t)),r||(r=Xe._soundClass),h||((h=new r).load(t),Qt._isMiniGame||i.Loader.cacheRes(t,h)),(o=h.play(a,e))?(o.url=t,o.volume=t==Xe._bgMusic?Xe.musicVolume:Xe.soundVolume,o.completeHandler=s,o):null}static destroySound(t){var e=i.loader.getRes(t);e&&(i.Loader.clearRes(t),e.dispose())}static playMusic(t,e=0,i=null,s=0){return t=M.formatURL(t),Xe._bgMusic=t,Xe._musicChannel&&Xe._musicChannel.stop(),Xe._musicChannel=Xe.playSound(t,e,i,Xe._musicClass,s)}static stopSound(t){var e,i;for(t=M.formatURL(t),e=Xe._channels.length-1;e>=0;e--)(i=Xe._channels[e]).url==t&&i.stop()}static stopAll(){var t;for(Xe._bgMusic=null,t=Xe._channels.length-1;t>=0;t--)Xe._channels[t].stop()}static stopAllSound(){var t,e;for(t=Xe._channels.length-1;t>=0;t--)(e=Xe._channels[t]).url!=Xe._bgMusic&&e.stop()}static stopMusic(){Xe._musicChannel&&Xe._musicChannel.stop(),Xe._bgMusic=null}static setSoundVolume(t,e=null){var i,s;if(e)e=M.formatURL(e),Xe._setVolume(e,t);else for(Xe.soundVolume=t,i=Xe._channels.length-1;i>=0;i--)(s=Xe._channels[i]).url!=Xe._bgMusic&&(s.volume=t)}static setMusicVolume(t){Xe.musicVolume=t,Xe._setVolume(Xe._bgMusic,t)}static _setVolume(t,e){var i,s;for(t=M.formatURL(t),i=Xe._channels.length-1;i>=0;i--)(s=Xe._channels[i]).url==t&&(s.volume=e)}}Xe.musicVolume=1,Xe.soundVolume=1,Xe.playbackRate=1,Xe._useAudioMusic=!0,Xe._muted=!1,Xe._soundMuted=!1,Xe._musicMuted=!1,Xe._bgMusic=null,Xe._musicChannel=null,Xe._channels=[],Xe._blurPaused=!1,Xe._isActive=!0,Xe._lastSoundUsedTimeDic={},Xe._isCheckingDispose=!1,Xe.autoReleaseSound=!0;class He{create(){return this.json?i.SceneUtils.createByData(null,this.json):null}}class ze{constructor(){this._fontCharDic={},this._fontWidthMap={},this._maxWidth=0,this._spaceWidth=10,this.fontSize=12,this.autoScaleSize=!1,this.letterSpacing=0}loadFont(t,e){this._path=t,this._complete=e,t&&-1!==t.indexOf(".fnt")?i.loader.load([{url:t,type:i.Loader.XML},{url:t.replace(".fnt",".png"),type:i.Loader.IMAGE}],b.create(this,this._onLoaded)):console.error('Bitmap font configuration information must be a ".fnt" file')}_onLoaded(){this.parseFont(i.Loader.getRes(this._path),i.Loader.getRes(this._path.replace(".fnt",".png"))),this._complete&&this._complete.run()}parseFont(t,e){if(null!=t&&null!=e){this._texture=e;var i=t.getElementsByTagName("info");if(!i[0].getAttributeNode)return this.parseFont2(t,e);this.fontSize=parseInt(i[0].getAttributeNode("size").nodeValue);var s=i[0].getAttributeNode("padding").nodeValue.split(",");this._padding=[parseInt(s[0]),parseInt(s[1]),parseInt(s[2]),parseInt(s[3])];var r=t.getElementsByTagName("char"),a=0;for(a=0;a=0?"/":"\\",a=this._url.lastIndexOf(r),n=a>=0?this._url.substr(0,a+1):"",h=null;Qt.onAndroid&&e.meta.compressTextureAndroid&&(h=".ktx"),Qt.onIOS&&e.meta.compressTextureIOS&&(h=e.meta.astc?".ktx":".pvr");for(var o=0,l=s.length;o0){this.event(Ht.PROGRESS,.3+1/this._data.toLoads.length*.6);_=M.formatURL(this._data.toLoads.pop()),u=$.getFileExtension(_),c=je.IMAGE;return"pvr"!=u&&"ktx"!=u||(c=je.BUFFER),this._loadResourceFilter(c,_)}var d=this._data.frames,p=this._url.split("?")[0],f=this._data.meta&&this._data.meta.prefix?this._data.meta.prefix:p.substring(0,p.lastIndexOf("."))+"/",m=this._data.pics,g=M.formatURL(this._url),T=je.atlasMap[g]||(je.atlasMap[g]=[]);T.dir=f;var v=1;if(this._data.meta&&this._data.meta.scale&&1!=this._data.meta.scale)for(var x in v=parseFloat(this._data.meta.scale),d){var y,E=d[x],C=m[E.frame.idx?E.frame.idx:0];_=M.formatURL(f+x);C.scaleRate=v,y=zt._create(C,E.frame.x,E.frame.y,E.frame.w,E.frame.h,E.spriteSourceSize.x,E.spriteSourceSize.y,E.sourceSize.w,E.sourceSize.h,je.getRes(_)),je.cacheTexture(_,y),y.url=_,T.push(_)}else for(x in d)C=m[(E=d[x]).frame.idx?E.frame.idx:0],_=M.formatURL(f+x),y=zt._create(C,E.frame.x,E.frame.y,E.frame.w,E.frame.h,E.spriteSourceSize.x,E.spriteSourceSize.y,E.sourceSize.w,E.sourceSize.h,je.getRes(_)),je.cacheTexture(_,y),y.url=_,T.push(_);delete this._data.pics,this.complete(this._data)}else if(c===je.FONT){if(!e._source)return this._data=e,this.event(Ht.PROGRESS,.5),this._loadResourceFilter(je.IMAGE,this._url.replace(".fnt",".png"));var A=new ze;A.parseFont(this._data,new zt(e));var R=this._url.split(".fnt")[0].split("/"),b=R[R.length-1];Me.registerBitmapFont(b,A),this._data=A,this.complete(this._data)}else if(c===je.PREFAB){var S=new He;S.json=e,this.complete(S)}else this.complete(e)}parsePLFData(t){var e,i,s;for(e in t)switch(s=t[e],e){case"json":case"text":for(i in s)je.preLoadedMap[M.formatURL(i)]=s[i];break;default:for(i in s)je.preLoadedMap[M.formatURL(i)]=s[i]}}parsePLFBData(t){var e,i,s;for(s=(e=new D(t)).getInt32(),i=0;ije.maxTimeOut)return console.warn("loader callback cost a long time:"+(Qt.now()-t)+" url="+je._loaders[je._startIndex-1].url),void i.systemTimer.frameOnce(1,null,je.checkNext);je._loaders.length=0,je._startIndex=0,je._isWorking=!1}endLoad(t=null){t&&(this._data=t),this._cache&&je.cacheRes(this._url,this._data),this.event(Ht.PROGRESS,1),this.event(Ht.COMPLETE,this.data instanceof Array?[this.data]:this.data)}get url(){return this._url}get type(){return this._type}get cache(){return this._cache}get data(){return this._data}static clearRes(t){t=M.formatURL(t);var e=je.getAtlas(t);if(e){for(var i=0,s=e.length;i0)e.forEach((function(t){var e=je.getRes(t);e instanceof zt&&e.disposeBitmap()}));else{var i=je.getRes(t);i instanceof zt&&i.disposeBitmap()}}static getRes(t){var e=je.textureMap[M.formatURL(t)];return e||je.loadedMap[M.formatURL(t)]}static getAtlas(t){return je.atlasMap[M.formatURL(t)]}static cacheRes(t,e){t=M.formatURL(t),null!=je.loadedMap[t]?console.warn("Resources already exist,is repeated loading:",t):e instanceof zt?(je.loadedMap[t]=e.bitmap,je.textureMap[t]=e):je.loadedMap[t]=e}static cacheResForce(t,e){je.loadedMap[t]=e}static cacheTexture(t,e){t=M.formatURL(t),null!=je.textureMap[t]?console.warn("Resources already exist,is repeated loading:",t):je.textureMap[t]=e}static setGroup(t,e){je.groupMap[e]||(je.groupMap[e]=[]),je.groupMap[e].push(t)}static clearResByGroup(t){if(je.groupMap[t]){var e,i=je.groupMap[t],s=i.length;for(e=0;e=this.maxLoader)){for(var t=0;t0;){var i=e.shift();if(i)return this._doLoad(i)}this._loaderCount||this.event(Ht.COMPLETE)}}_doLoad(t){this._loaderCount++;var e=this._loaders.length?this._loaders.pop():new je;e.on(Ht.COMPLETE,null,onLoaded),e.on(Ht.PROGRESS,null,(function(e){t.event(Ht.PROGRESS,e)})),e.on(Ht.ERROR,null,(function(t){onLoaded(null)}));var i=this;function onLoaded(s=null){e.offAll(),e._data=null,e._customParse=!1,i._loaders.push(e),i._endLoad(t,s instanceof Array?[s]:s),i._loaderCount--,i._next()}e._constructParams=t.createConstructParams,e._propertyParams=t.createPropertyParams,e._createCache=t.createCache,e.load(t.url,t.type,t.cache,t.group,t.ignoreCache,t.useWorkerLoader)}_endLoad(t,e){var s=t.url;if(null==e){var r=this._failRes[s]||0;if(r-1;i--){var s=e[i];s&&(s.offAll(),this._infoPool.push(s))}e.length=0}this._loaderCount=0,Ze._resMap={}}cancelLoadByUrls(t){if(t)for(var e=0,i=t.length;e-1;s--){var r=i[s];r&&r.url===t&&(i[s]=null,r.offAll(),this._infoPool.push(r))}Ze._resMap[t]&&delete Ze._resMap[t]}_loadAssets(t,e=null,i=null,s=null,r=1,a=!0,n=null){for(var h=t.length,o=0,l=0,_=[],u=!0,c=0;c0&&r0&&r0&&r=this._duration)return this.complete();for(var s=i>0?this._ease(i,0,1,this._duration):0,r=this._props,a=0,n=r.length;a=this.repeat?(this.clear(),s&&s.run()):this.restart()}}pause(){var t;i.timer.clear(this,this._beginLoop),i.timer.clear(this,this._doEase),i.timer.clear(this,this.firstStart),(t=Qt.now()-this._startTimer-this._delay)<0&&(this._usedTimer=t)}setStartTime(t){this._startTimer=t}static clearAll(t){if(t&&t.$_GID){var e=ii.tweenMap[t.$_GID];if(e){for(var i=0,s=e.length;i=this._duration||(this._startTimer=Qt.now()-this._usedTimer-this._delay,this._delayParam?this._usedTimer<0?i.timer.once(-this._usedTimer,this,this.firstStart,this._delayParam):this.firstStart.apply(this,this._delayParam):this._beginLoop())}static easeNone(t,e,i,s){return i*t/s+e}}ii.tweenMap=[];class si{constructor(){this.ratio=.92,this.maxOffset=60,this._dragging=!1,this._clickOnly=!0}start(t,e,s,r,a,n,h,o=.92){this.clearTimer(),this.target=t,this.area=e,this.hasInertia=s,this.elasticDistance=e?r:0,this.elasticBackTime=a,this.data=n,this._disableMouseEvent=h,this.ratio=o,this._parent=t.parent,this._clickOnly=!0,this._dragging=!0,this._elasticRateX=this._elasticRateY=1,this._lastX=this._parent.mouseX,this._lastY=this._parent.mouseY,i.stage.on(Ht.MOUSE_UP,this,this.onStageMouseUp),i.stage.on(Ht.MOUSE_OUT,this,this.onStageMouseUp),i.systemTimer.frameLoop(1,this,this.loop)}clearTimer(){i.systemTimer.clear(this,this.loop),i.systemTimer.clear(this,this.tweenMove),this._tween&&(this._tween.recover(),this._tween=null)}stop(){this._dragging&&(Le.instance.disableMouseEvent=!1,i.stage.off(Ht.MOUSE_UP,this,this.onStageMouseUp),i.stage.off(Ht.MOUSE_OUT,this,this.onStageMouseUp),this._dragging=!1,this.target&&this.area&&this.backToArea(),this.clear())}loop(){var t=this._parent.getMousePoint(),e=t.x,s=t.y,r=e-this._lastX,a=s-this._lastY;if(this._clickOnly){if(!(Math.abs(r*i.stage._canvasTransform.getScaleX())>1||Math.abs(a*i.stage._canvasTransform.getScaleY())>1))return;this._clickOnly=!1,this._offsets||(this._offsets=[]),this._offsets.length=0,this.target.event(Ht.DRAG_START,this.data),Le.instance.disableMouseEvent=this._disableMouseEvent}else this._offsets.push(r,a);0===r&&0===a||(this._lastX=e,this._lastY=s,this.target.x+=r*this._elasticRateX,this.target.y+=a*this._elasticRateY,this.area&&this.checkArea(),this.target.event(Ht.DRAG_MOVE,this.data))}checkArea(){if(this.elasticDistance<=0)this.backToArea();else{if(this.target._xthis.area.x+this.area.width?this.target._x-this.area.x-this.area.width:0;if(this._elasticRateX=Math.max(0,1-t/this.elasticDistance),this.target._ythis.area.y+this.area.height?this.target._y-this.area.y-this.area.height:0;this._elasticRateY=Math.max(0,1-e/this.elasticDistance)}}backToArea(){this.target.x=Math.min(Math.max(this.target._x,this.area.x),this.area.x+this.area.width),this.target.y=Math.min(Math.max(this.target._y,this.area.y),this.area.y+this.area.height)}onStageMouseUp(t){if(Le.instance.disableMouseEvent=!1,i.stage.off(Ht.MOUSE_UP,this,this.onStageMouseUp),i.stage.off(Ht.MOUSE_OUT,this,this.onStageMouseUp),i.systemTimer.clear(this,this.loop),!this._clickOnly&&this.target)if(this.hasInertia){this._offsets.length<1&&this._offsets.push(this._parent.mouseX-this._lastX,this._parent.mouseY-this._lastY),this._offsetX=this._offsetY=0;for(var e=this._offsets.length,s=Math.min(e,6),r=this._offsets.length-s,a=e-1;a>r;a--)this._offsetY+=this._offsets[a--],this._offsetX+=this._offsets[a];this._offsetX=this._offsetX/s*2,this._offsetY=this._offsetY/s*2,Math.abs(this._offsetX)>this.maxOffset&&(this._offsetX=this._offsetX>0?this.maxOffset:-this.maxOffset),Math.abs(this._offsetY)>this.maxOffset&&(this._offsetY=this._offsetY>0?this.maxOffset:-this.maxOffset),i.systemTimer.frameLoop(1,this,this.tweenMove)}else this.elasticDistance>0?this.checkElastic():this.clear()}checkElastic(){var t=NaN,e=NaN;if(this.target.xthis.area.x+this.area.width&&(t=this.area.x+this.area.width),this.target.ythis.area.y+this.area.height&&(e=this.area.y+this.area.height),isNaN(t)&&isNaN(e))this.clear();else{var i={};isNaN(t)||(i.x=t),isNaN(e)||(i.y=e),this._tween=ii.to(this.target,i,this.elasticBackTime,ei.sineOut,b.create(this,this.clear),0,!1,!1)}}tweenMove(){this._offsetX*=this.ratio*this._elasticRateX,this._offsetY*=this.ratio*this._elasticRateY,this.target.x+=this._offsetX,this.target.y+=this._offsetY,this.area&&this.checkArea(),this.target.event(Ht.DRAG_MOVE,this.data),(Math.abs(this._offsetX)<1&&Math.abs(this._offsetY)<1||this._elasticRateX<.5||this._elasticRateY<.5)&&(i.systemTimer.clear(this,this.tweenMove),this.elasticDistance>0?this.checkElastic():this.clear())}clear(){if(this.target){this.clearTimer();var t=this.target;this.target=null,this._parent=null,t.event(Ht.DRAG_END,this.data)}}}class ri{constructor(){this._id=$.getGID(),this._resetComp()}get id(){return this._id}get enabled(){return this._enabled}set enabled(t){this._enabled!=t&&(this._enabled=t,this.owner&&(t?this.owner.activeInHierarchy&&this._onEnable():this.owner.activeInHierarchy&&this._onDisable()))}get isSingleton(){return!0}get destroyed(){return this._destroyed}_isScript(){return!1}_resetComp(){this._indexInList=-1,this._enabled=!0,this._awaked=!1,this.owner=null}_getIndexInList(){return this._indexInList}_setIndexInList(t){this._indexInList=t}_onAdded(){}_onAwake(){}_onEnable(){}_onDisable(){}_onDestroy(){}onReset(){}_parse(t,e=null){}_parseInteractive(t=null,e=null){}_cloneTo(t){}_setActive(t){t?(this._awaked||(this._awaked=!0,this._onAwake()),this._enabled&&this._onEnable()):this._enabled&&this._onDisable()}destroy(){this.owner&&this.owner._destroyComponent(this)}_destroy(){this.owner.activeInHierarchy&&this._enabled&&this._setActive(!1),this._onDestroy(),this._destroyed=!0,this.onReset!==ri.prototype.onReset?(this.onReset(),this._resetComp(),s.recoverByClass(this)):this._resetComp()}}class ai extends Se{constructor(){super(),this.wrapMode=0,this._interval=e.animationInterval,this._isReverse=!1,this._frameRateChanged=!1,this._setBitUp(ge.DISPLAY)}play(t=0,e=!0,i=""){this._isPlaying=!0,this._actionName=i,this.index="string"==typeof t?this._getFrameByLabel(t):t,this.loop=e,this._isReverse=this.wrapMode===ai.WRAP_REVERSE,0==this.index&&this._isReverse&&(this.index=this.count-1),this.interval>0&&this.timerLoop(this.interval,this,this._frameLoop,null,!0,!0)}get interval(){return this._interval}set interval(t){this._interval!=t&&(this._frameRateChanged=!0,this._interval=t,this._isPlaying&&t>0&&this.timerLoop(t,this,this._frameLoop,null,!0,!0))}_getFrameByLabel(t){for(var e=0;e-1)return e}return 0}_frameLoop(){if(this._controlNode&&!this._controlNode.destroyed){if(this._isReverse){if(this._index--,this._index<0){if(!this.loop)return this._index=0,this.stop(),void this.event(Ht.COMPLETE);this.wrapMode==ai.WRAP_PINGPONG?(this._index=this._count>0?1:0,this._isReverse=!1):this._index=this._count-1,this.event(Ht.COMPLETE)}}else if(this._index++,this._index>=this._count){if(!this.loop)return this._index--,this.stop(),void this.event(Ht.COMPLETE);this.wrapMode==ai.WRAP_PINGPONG?(this._index=this._count-2>=0?this._count-2:0,this._isReverse=!0):this._index=0,this.event(Ht.COMPLETE)}this.index=this._index}else this.clearTimer(this,this._frameLoop)}_setControlNode(t){this._controlNode&&(this._controlNode.off(Ht.DISPLAY,this,this._resumePlay),this._controlNode.off(Ht.UNDISPLAY,this,this._resumePlay)),this._controlNode=t,t&&t!=this&&(t.on(Ht.DISPLAY,this,this._resumePlay),t.on(Ht.UNDISPLAY,this,this._resumePlay))}_setDisplay(t){super._setDisplay(t),this._resumePlay()}_resumePlay(){this._isPlaying&&(this._controlNode.displayedInStage?this.play(this._index,this.loop,this._actionName):this.clearTimer(this,this._frameLoop))}stop(){this._isPlaying=!1,this.clearTimer(this,this._frameLoop)}get isPlaying(){return this._isPlaying}addLabel(t,e){this._labels||(this._labels={}),this._labels[e]||(this._labels[e]=[]),this._labels[e].push(t)}removeLabel(t){if(t){if(this._labels)for(var e in this._labels)this._removeLabelFromList(this._labels[e],t)}else this._labels=null}_removeLabelFromList(t,e){if(t)for(var i=t.length-1;i>=0;i--)t[i]==e&&t.splice(i,1)}gotoAndStop(t){this.index="string"==typeof t?this._getFrameByLabel(t):t,this.stop()}get index(){return this._index}set index(t){if(this._index=t,this._displayToIndex(t),this._labels&&this._labels[t])for(var e=this._labels[t],i=0,s=e.length;i1e-6?(h=Math.acos(o),l=Math.sin(h),_=Math.sin((1-r)*h)/l,u=Math.sin(r*h)/l):(_=1-r,u=r),a[n+0]=_*c+u*m,a[n+1]=_*d+u*g,a[n+2]=_*p+u*T,a[n+3]=_*f+u*v,a}static getRotation(t,e,i,s){return Math.atan2(s-e,i-t)/Math.PI*180}static sortBigFirst(t,e){return t==e?0:e>t?1:-1}static sortSmallFirst(t,e){return t==e?0:e>t?-1:1}static sortNumBigFirst(t,e){return parseFloat(e)-parseFloat(t)}static sortNumSmallFirst(t,e){return parseFloat(t)-parseFloat(e)}static sortByKey(t,e=!1,i=!0){var s;return s=e?i?ni.sortNumBigFirst:ni.sortBigFirst:i?ni.sortNumSmallFirst:ni.sortSmallFirst,function(e,i){return s(e[t],i[t])}}}class hi extends ai{constructor(){super(),void 0===hi._sortIndexFun&&(hi._sortIndexFun=ni.sortByKey("index",!1,!0))}static _sortIndexFun(t,e){return t.index-e.index}_setUp(t,e){this._targetDic=t,this._animationData=e,this.interval=1e3/e.frameRate,e.parsed?(this._count=e.count,this._labels=e.labels,this._usedFrames=e.animationNewFrames):(this._usedFrames=[],this._calculateDatas(),e.parsed=!0,e.labels=this._labels,e.count=this._count,e.animationNewFrames=this._usedFrames)}clear(){return super.clear(),this._targetDic=null,this._animationData=null,this}_displayToIndex(t){if(this._animationData){t<0&&(t=0),t>this._count&&(t=this._count);var e,i=this._animationData.nodes,s=i.length;for(e=0;ee?a[e]:a[a.length-1],s[r]=n;var u,c=t.funkeys;if(0!=(_=c.length))for(h=0;h<_;h++)void 0!==(u=o[r=c[h]])[e]&&s[r]&&s[r].apply(s,u[e])}}_calculateDatas(){if(this._animationData){var t,e,i=this._animationData.nodes,s=i.length;for(this._count=0,t=0;tthis._count&&(this._count=o.index)}}else this._targetDic&&this._targetDic[r]&&(t.initValues[e]=this._targetDic[r][e]),i.sort(hi._sortIndexFun),t.keys.push(e),this._calculateNodePropFrames(i,t.frames[e],e,r)}}resetNodes(){if(this._targetDic&&this._animationData){var t,e,i,s=this._animationData.nodes,r=s.length;for(t=0;tthis._count&&(this._count=n),t.tween)for(null==(r=ei[t.tweenMethod])&&(r=ei.linearNone),s=a;s0&&null==e.props.hitTestPrior&&!t.mouseThrough&&(t.hitTestPrior=!0),i.beginLoad(t),t}static createInitTool(){return ui.create()}static createComp(t,e=null,s=null,r=null,a=null){if("Scene3D"==t.type||"Sprite3D"==t.type){var n=[],h=i.Laya.Utils3D._createSceneByJsonForMaker(t,n,a);return"Sprite3D"==t.type?i.Laya.StaticBatchManager.combine(h,n):i.Laya.StaticBatchManager.combine(null,n),h}if(!(e=e||li.getCompInstance(t)))return t.props&&t.props.runtime?console.warn("runtime not found:"+t.props.runtime):console.warn("can not create:"+t.type),null;var o=t.child;if(o)for(var l="List"==e._$componentType,_=0,u=o.length;_=0||g.indexOf("@Prefab:")>=0)?a&&a.addNodeRef(e,m,g):li.setCompValue(e,m,g,s,r)}return e._afterInited&&e._afterInited(),t.compId&&a&&a._idMap&&(a._idMap[t.compId]=e),e}static setCompValue(t,e,s,r=null,a=null){if("string"==typeof s&&s.indexOf("${")>-1){if(li._sheet||(li._sheet=i.ClassUtils.getClass("laya.data.Table")),!li._sheet)return void console.warn("Can not find class Sheet");if(a)a.push(t,e,s);else if(r){-1==s.indexOf("].")&&(s=s.replace(".","[0]."));var n,h,o=new _i(t,e,s);o.exe(r);for(var l=s.replace(/\[.*?\]\./g,".");null!=(n=li._parseWatchData.exec(l));){for(var _=n[1];null!=(h=li._parseKeyWord.exec(_));){var u=h[0],c=r._watchMap[u]||(r._watchMap[u]=[]);c.push(o),li._sheet.I.notifer.on(u,r,r.changeData,[u])}(c=r._watchMap[_]||(r._watchMap[_]=[])).push(o),li._sheet.I.notifer.on(_,r,r.changeData,[_])}}}else"var"===e&&r?r[s]=t:t[e]="true"===s||"false"!==s&&s}static getCompInstance(t){if("UIView"==t.type&&t.props&&t.props.pageData)return li.createByData(null,t.props.pageData);var e=t.props&&t.props.runtime||t.type,r=i.ClassUtils.getClass(e);if(!r)throw"Can not find class "+e;if("Script"===t.type&&r.prototype._doAwake){var a=s.createByClass(r);return a._destroyed=!1,a}return t.props&&"renderType"in t.props&&"instance"==t.props.renderType?(r.instance||(r.instance=new r),r.instance):new r}}li._parseWatchData=/\${(.*?)}/g,li._parseKeyWord=/[a-zA-Z_][a-zA-Z0-9_]*(?:(?:\.[a-zA-Z_][a-zA-Z0-9_]*)+)/g;class _i{constructor(t,e,i){this.comp=t,this.prop=e,this.value=i}exe(t){var e=li.getBindFun(this.value);this.comp[this.prop]=e.call(this,t)}}class ui{reset(){this._nodeRefList=null,this._initList=null,this._idMap=null,this._loadList=null,this._scene=null}recover(){this.reset(),s.recover("InitTool",this)}static create(){var t=s.getItemByClass("InitTool",ui);return t._idMap={},t}addLoadRes(t,e=null){this._loadList||(this._loadList=[]),i.loader.getRes(t)||(e?this._loadList.push({url:t,type:e}):this._loadList.push(t))}addNodeRef(t,e,i){this._nodeRefList||(this._nodeRefList=[]),this._nodeRefList.push([t,e,i]),i.indexOf("@Prefab:")>=0&&this.addLoadRes(i.replace("@Prefab:",""),je.PREFAB)}setNodeRef(){if(this._nodeRefList)if(this._idMap){var t,e,i;for(e=this._nodeRefList.length,t=0;t=0)return je.getRes(t.replace("@Prefab:",""));if(t.indexOf("@arr:")>=0){var e,i,s,r;for(s=(e=(t=t.replace("@arr:","")).split(",")).length,i=0;i0?Math.floor(1e3/X.FPS).toString():" ";X._fpsStr=X.FPS+(X.renderSlow?" slow":"")+" "+i,X._spriteStr=X.spriteCount+(X.spriteRenderUseCacheCount?"/"+X.spriteRenderUseCacheCount:""),X._canvasStr=X.canvasReCache+"/"+X.canvasNormal+"/"+X.canvasBitmap,X.cpuMemory=I.cpuMemory,X.gpuMemory=I.gpuMemory,this._useCanvas?this.renderInfoPre():this.renderInfo(),X.clear()}X._count=0,X._timer=t}}renderInfoPre(){var t,e,i=0;if(this._canvas){var s=this._ctx;for(s.clearRect(this._first?0:this._vx,0,this._width,this._height),i=0;i3e4;this._delta=(e-this._lastTimer)*this.scale;var s=this.currTimer=this.currTimer+this._delta;this._lastTimer=e;var r=this._handlers;this._count=0;for(var a=0,n=r.length;a=h.exeTime)if(h.repeat)if(!h.jumpFrame||i)h.exeTime+=h.delay,h.run(!1),o>h.exeTime&&(h.exeTime+=Math.ceil((o-h.exeTime)/h.delay)*h.delay);else for(;o>=h.exeTime;)h.exeTime+=h.delay,h.run(!1);else h.run(!0)}else this._count++}(this._count>30||t%200==0)&&this._clearHandlers()}_clearHandlers(){for(var t=this._handlers,e=0,i=t.length;e0?pi._pool.pop():new fi).repeat=e,h.userFrame=t,h.delay=i,h.caller=s,h.method=r,h.args=a,h.exeTime=i+(t?this.currFrame:this.currTimer+Date.now()-this._lastTimer),this._indexHandler(h),this._handlers.push(h),h}_indexHandler(t){var e=t.caller,s=t.method,r=e?e.$_GID||(e.$_GID=i.Utils.getGID()):0,a=s.$_TID||(s.$_TID=1e5*pi._mid++);t.key=r+a,this._map[t.key]=t}once(t,e,i,s=null,r=!0){this._create(!1,!1,t,e,i,s,r)}loop(t,e,i,s=null,r=!0,a=!1){var n=this._create(!1,!0,t,e,i,s,r);n&&(n.jumpFrame=a)}frameOnce(t,e,i,s=null,r=!0){this._create(!0,!1,t,e,i,s,r)}frameLoop(t,e,i,s=null,r=!0){this._create(!0,!0,t,e,i,s,r)}toString(){return" handlers:"+this._handlers.length+" pool:"+pi._pool.length}clear(t,e){var i=this._getHandler(t,e);i&&(this._map[i.key]=null,i.key=0,i.clear())}clearAll(t){if(t)for(var e=0,i=this._handlers.length;e=0&&(e+=this.funs[i]);return e}}class xi{constructor(t){this.childs=[],this.text="",this.useFuns="",this.z=0,this.includefiles=t}setParent(t){t.childs.push(this),this.z=t.z+1,this.parent=t}setCondition(t,e){t&&(this.conditionType=e,t=t.replace(/(\s*$)/g,""),this.condition=function(){return this[t]},this.condition.__condition=t)}toscript(t,e){return this._toscript(t,e,++xi.__id)}_toscript(t,e,s){if(this.childs.length<1&&!this.text)return e;e.length;if(this.condition){var r=!!this.condition.call(t);if(this.conditionType===i.ShaderCompile.IFDEF_ELSE&&(r=!r),!r)return e}if(this.noCompile&&this.text&&e.push(this.text),this.childs.length>0&&this.childs.forEach((function(i,r,a){i._toscript(t,e,s)})),this.includefiles.length>0&&this.useFuns.length>0)for(var a,n=0,h=this.includefiles.length;n0&&(this.includefiles[n].curUseID=s,e[0]=a+e[0]);return e}}xi.__id=1;class yi{constructor(t,e,i){this.defs={};let s=this;function _compile(t){t=t.replace(yi._clearCR,"");var e=[],i=new xi(e);return s._compileToTree(i,t.split("\n"),0,e,s.defs),i}var r=Date.now();this._VS=_compile(t),this._PS=_compile(e),this._nameMap=i,Date.now()-r>2&&console.log("ShaderCompile use time:"+(Date.now()-r)+" size:"+t.length+"/"+e.length)}static __init__(){var t=g.instance;yi.shaderParamsMap={float:t.FLOAT,int:t.INT,bool:t.BOOL,vec2:t.FLOAT_VEC2,vec3:t.FLOAT_VEC3,vec4:t.FLOAT_VEC4,ivec2:t.INT_VEC2,ivec3:t.INT_VEC3,ivec4:t.INT_VEC4,bvec2:t.BOOL_VEC2,bvec3:t.BOOL_VEC3,bvec4:t.BOOL_VEC4,mat2:t.FLOAT_MAT2,mat3:t.FLOAT_MAT3,mat4:t.FLOAT_MAT4,sampler2D:t.SAMPLER_2D,samplerCube:t.SAMPLER_CUBE}}static _parseOne(t,e,i,s,r,a){var n={type:yi.shaderParamsMap[i[s+1]],name:i[s+2],size:isNaN(parseInt(i[s+3]))?1:parseInt(i[s+3])};return a&&("attribute"==r?t.push(n):e.push(n)),":"==i[s+3]&&(n.type=i[s+4],s+=2),s+=2}static addInclude(t,e){if(!e||0===e.length)throw new Error("add shader include file err:"+t);if(yi.includes[t])throw new Error("add shader include file err, has add:"+t);yi.includes[t]=new vi(e)}static preGetParams(t,e){var i,s,r=[t,e],a={},n=[],h=[],o={},l={};a.attributes=n,a.uniforms=h,a.defines=o;for(var _=0;_<2;_++){r[_]=r[_].replace(yi._removeAnnotation,"");var u,c=r[_].match(yi._reg);for(i=0,s=c.length;i()'\",;".indexOf(i)>=0){if(a>=0&&n-a>1&&(s=t.substr(a,n-a),r.push(s)),'"'==i||"'"==i){var o=t.indexOf(i,n+1);if(o<0)throw"Sharder err:"+t;r.push(t.substr(n+1,o-n-1)),n=o,a=-1;continue}"("==i&&e&&r.length>0&&(s=r[r.length-1]+";","vec4;main;".indexOf(s)<0&&(e.useFuns+=s)),a=-1}else a<0&&(a=n);return a1&&(s=t.substr(a,h-a),r.push(s)),r}_compileToTree(t,e,i,s,r){var a,n,h,o,l,_,u,c,d,p,f;for(d=i;d=0&&(h=h.substr(0,_)),a=c||new xi(s),c=null,a.text=h,a.noCompile=!0,(_=h.indexOf("#"))>=0){for(o="#",f=_+1,p=h.length;f]/),a.noCompile?console.log("function():Boolean{return "+h.substr(_+a.name.length)+"}"):(u=h.replace(/^\s*/,"").split(/\s+/),a.setCondition(u[1],"#ifdef"===o?yi.IFDEF_YES:yi.IFDEF_ELSE),a.text="//"+a.text),a.setParent(t),t=a,r)for(u=h.substr(f).split(yi._splitToWordExps3),f=0;f0&&yi.splitToWords(h,n),c=a,n.text+="\n"+h;continue}s.length>0&&yi.splitToWords(h,a)}a.setParent(t)}}createShader(t,e,i,s){var r={},a="";if(t)for(var n in t)a+="#define "+n+"\n",r[n]=!0;var h=this._VS.toscript(r,[]),o=this._PS.toscript(r,[]);return(i||z.create)(a+h.join("\n"),a+o.join("\n"),e,this._nameMap,s)}}yi.IFDEF_NO=0,yi.IFDEF_YES=1,yi.IFDEF_ELSE=2,yi.IFDEF_PARENT=3,yi._removeAnnotation=new RegExp("(/\\*([^*]|[\\r\\\n]|(\\*+([^*/]|[\\r\\n])))*\\*+/)|(//.*)","g"),yi._reg=new RegExp("(\".*\")|('.*')|([#\\w\\*-\\.+/()=<>{}\\\\]+)|([,;:\\\\])","g"),yi._splitToWordExps=new RegExp("[(\".*\")]+|[('.*')]+|([ \\t=\\+\\-*/&%!<>!%(),;])","g"),yi.includes={},yi._clearCR=new RegExp("\r","g"),yi._splitToWordExps3=new RegExp("[ \\t=\\+\\-*/&%!<>!%(),;\\|]","g");class Ei extends S{constructor(){super(),this.worker=new Worker(Ei.workerPath);let t=this;this.worker.onmessage=function(e){t.workerMessage(e.data)}}static __init__(){return null==Ei._preLoadFun&&(!!Worker&&(Ei._preLoadFun=je.prototype._loadImage,je.prototype._loadImage=Ei.prototype._loadImage,Ei.I||(Ei.I=new Ei),!0))}static workerSupported(){return!!Worker}static enableWorkerLoader(){Ei._tryEnabled||(Ei.enable=!0,Ei._tryEnabled=!0)}static set enable(t){Ei._enable!=t&&(Ei._enable=t,t&&null==Ei._preLoadFun&&(Ei._enable=Ei.__init__()))}static get enable(){return Ei._enable}workerMessage(t){if(t)switch(t.type){case"Image":this.imageLoaded(t);break;case"Disable":Ei.enable=!1}}imageLoaded(t){if(t.dataType&&"imageBitmap"==t.dataType){var e=t.imageBitmap;console.log("load:",t.url),this.event(t.url,e)}else this.event(t.url,null)}loadImage(t){this.worker.postMessage(t)}_loadImage(e){var i=this;let s=i.type;if(this._useWorkerLoader&&Ei._enable){e=M.formatURL(e);var onload=function(r){if(Ei.I.off(e,i,onload),r){var a=r;"nativeimage"!==s&&((a=new O).wrapModeU=t.WarpMode.Clamp,a.wrapModeV=t.WarpMode.Clamp,a.loadImageSource(r,!0)),i.onLoaded(a)}else Ei._preLoadFun.call(i,e)};Ei.I.on(e,i,onload),Ei.I.loadImage(e)}else Ei._preLoadFun.call(i,e)}}Ei.workerPath="libs/workerloader.js",Ei._enable=!1,Ei._tryEnabled=!1;class Ci{static set cursor(t){Ci._style.cursor=t}static get cursor(){return Ci._style.cursor}static __init__(){Ci._style=Qt.document.body.style}static hide(){"none"!=Ci.cursor&&(Ci._preCursor=Ci.cursor,Ci.cursor="none")}static show(){"none"==Ci.cursor&&(Ci._preCursor?Ci.cursor=Ci._preCursor:Ci.cursor="auto")}}class Ai extends bt{constructor(t){super(Ai.const_stride,4*t*Ai.const_stride,4),this.canReuse=!0,this.setAttributes(Ai._fixattriInfo),this.createQuadIB(t),this._quadNum=t}static __init__(){var t=g.instance;Ai._fixattriInfo=[t.FLOAT,4,0,t.FLOAT,3,16,t.FLOAT,3,28,t.FLOAT,4,40,t.FLOAT,4,56,t.FLOAT,3,72,t.FLOAT,2,84,t.FLOAT,4,92,t.FLOAT,1,108,t.FLOAT,1,112]}setMaxParticleNum(t){this._vb._resizeBuffer(4*t*Ai.const_stride,!1),this.createQuadIB(t)}static getAMesh(t){if(Ai._POOL.length){var e=Ai._POOL.pop();return e.setMaxParticleNum(t),e}return new Ai(t)}releaseMesh(){this._vb.setByteLength(0),this.vertNum=0,this.indexNum=0,Ai._POOL.push(this)}destroy(){this._ib.destroy(),this._vb.destroy(),this._vb.deleteBuffer()}}Ai.const_stride=116,Ai._POOL=[];class Ri extends P{}Ri.create=function(e,i,s){var r=new O(e,i,s,!1,!1);return r.wrapModeU=t.WarpMode.Clamp,r.wrapModeV=t.WarpMode.Clamp,r};class bi{static __init(t){t.forEach((function(t){t.__init$&&t.__init$()}))}static init(e,s,...r){if(!bi._isinit){bi._isinit=!0,ArrayBuffer.prototype.slice||(ArrayBuffer.prototype.slice=bi._arrayBufferSlice),Qt.__init__();var a=Qt.mainCanvas=new xe(!0),n=a.source.style;if(n.position="absolute",n.top=n.left="0px",n.background="#000000",Qt.onKGMiniGame||Qt.onAlipayMiniGame||Qt.container.appendChild(a.source),Qt.canvas=new xe(!0),Qt.context=Qt.canvas.getContext("2d"),Qt.supportWebAudio=Xe.__init__(),Qt.supportLocalStorage=$e.__init__(),bi.systemTimer=new pi(!1),t.systemTimer=pi.gSysTimer=bi.systemTimer,bi.startTimer=new pi(!1),bi.physicsTimer=new pi(!1),bi.updateTimer=new pi(!1),bi.lateTimer=new pi(!1),bi.timer=new pi(!1),t.startTimer=i.startTimer=bi.startTimer,t.lateTimer=i.lateTimer=bi.lateTimer,t.updateTimer=i.updateTimer=bi.updateTimer,i.systemTimer=bi.systemTimer,t.timer=i.timer=bi.timer,t.physicsTimer=i.physicsTimer=bi.physicsTimer,bi.loader=new Ze,i.Laya=bi,t.loader=i.loader=bi.loader,oi.__init__(),li.__init(),Ci.__init__(),se.inner_enable(),r)for(var h=0,o=r.length;h=a.length&&(i=a.length-1),t[e][i]}return e in r?r[e]:s}_getNodeGraphicData(t,e,i){i||(i=new Ui),i.transform?i.transform.identity():i.transform=new p;var s=this.getNodeDataByID(t);if(!s)return i;var r,a,n,h=s.frames,o=this._getParams(h,Ni._drawTextureCmd,e,this._nodeDefaultProps[t]),l=o[0],_=o[5],u=o[6],c=o[13],d=o[14],f=o[7],m=o[8],g=o[9],T=o[11],v=o[12];r=o[3],a=o[4],0!=r&&0!=a||(l=null),-1==r&&(r=0),-1==a&&(a=0),i.skin=l,i.width=r,i.height=a,l&&((n=this._getTextureByUrl(l))?(r||(r=n.sourceWidth),a||(a=n.sourceHeight)):console.warn("lost skin:",l,",you may load pics first")),i.alpha=o[10];var x=i.transform;0!=c&&(_=c*r),0!=d&&(u=d*a),0==_&&0==u||x.translate(-_,-u);var y=null;if(g||1!==f||1!==m||T||v){(y=Ni._tempMt).identity(),y._bTransform=!0;var E=.0174532922222222*(g-T),C=.0174532922222222*(g+v),A=Math.cos(C),R=Math.sin(C),b=Math.sin(E),S=Math.cos(E);y.a=f*A,y.b=f*R,y.c=-m*b,y.d=m*S,y.tx=y.ty=0}return y&&(x=p.mul(x,y,x)),x.translate(o[1],o[2]),i}_getTextureByUrl(t){return je.getRes(t)}setAniData(t,e=null){if(t.animations){this._nodeDefaultProps={},this._nodeGDic={},this._nodeList&&(this._nodeList.length=0),this._rootNode=t,this._parseNodeList(t);var i,s,r={},a=[],n=t.animations,h=n.length;for(i=0;i.01&&this._frames&&super._frameLoop()}_displayToIndex(t){this._frames&&(this.graphics=this._frames[t])}get frames(){return this._frames}set frames(t){this._frames=t,t&&(this._count=t.length,this._actionName&&this._setFramesFromCache(this._actionName,!0),this.index=this._index)}set source(t){t.indexOf(".ani")>-1?this.loadAnimation(t):t.indexOf(".json")>-1||t.indexOf("als")>-1||t.indexOf("atlas")>-1?this.loadAtlas(t):this.loadImages(t.split(","))}set autoAnimation(t){this.play(0,!0,t)}set autoPlay(t){t?this.play():this.stop()}clear(){return super.clear(),this.stop(),this.graphics=null,this._frames=null,this._labels=null,this}loadImages(t,e=""){return this._url="",this._setFramesFromCache(e)||(this.frames=Gi.framesMap[e]?Gi.framesMap[e]:Gi.createFrames(t,e)),this}loadAtlas(t,e=null,s=""){this._url="";var r=this;if(!r._setFramesFromCache(s)){function onLoaded(i){t===i&&(r.frames=Gi.framesMap[s]?Gi.framesMap[s]:Gi.createFrames(t,s),e&&e.run())}je.getAtlas(t)?onLoaded(t):i.loader.load(t,b.create(null,onLoaded,[t]),null,je.ATLAS)}return this}loadAnimation(t,e=null,s=null){this._url=t;return this._actionName||(this._actionName=""),this._setFramesFromCache(this._actionName)?(this._setFramesFromCache(this._actionName,!0),this.index=0,e&&e.run()):!s||je.getAtlas(s)?this._loadAnimationData(t,e,s):i.loader.load(s,b.create(this,this._loadAnimationData,[t,e,s]),null,je.ATLAS),this}_loadAnimationData(t,e=null,s=null){if(!s||je.getAtlas(s)){var r=this;je.getRes(t)?onLoaded(t):i.loader.load(t,b.create(null,onLoaded,[t]),null,je.JSON)}else console.warn("atlas load fail:"+s);function onLoaded(i){if(je.getRes(i)){if(t===i){var s;if(Gi.framesMap[t+"#"])r._setFramesFromCache(r._actionName,!0),r.index=0,r._resumePlay();else{var a=Ni.parseAnimationData(je.getRes(t));if(!a)return;var n,h,o=a.animationList,l=o.length;for(n=0;nthis._count&&(t=this._count);var e,i=this._animationData.nodes,s=i.length;for(s=s>1?1:s,e=0;ee?r[e]:r[r.length-1],c[s]=a}}_calculateKeyFrames(t){super._calculateKeyFrames(t);var e,i,s=t.keyframes,r=(t.target,{});for(e in t.secondFrames=r,s)(i=s[e]).length<=1?r[e]=-1:r[e]=i[1].index}}ki.EFFECT_BEGIN="effectbegin",Ee.regClass("laya.display.EffectAnimation",ki),Ee.regClass("Laya.EffectAnimation",ki);class Wi extends S{constructor(){super(),this._completeHandler=new b(this,this.onOneLoadComplete),this.reset()}reset(){this._toLoadList=[],this._isLoading=!1,this.totalCount=0}get leftCount(){return this._isLoading?this._toLoadList.length+1:this._toLoadList.length}get loadedCount(){return this.totalCount-this.leftCount}load(t,e=!1,i=!0){var s,r;if(t instanceof Array)for(r=t.length,s=0;s=0||je.getRes(t)||(e?this._toLoadList.push({url:t}):this._toLoadList.push(t),this.totalCount++)}_checkNext(){if(!this._isLoading){if(0==this._toLoadList.length)return void this.event(Ht.COMPLETE);var t;"string"==typeof(t=this._toLoadList.pop())?this.loadOne(t):this.loadOne(t.url,!0)}}loadOne(t,e=!1){this._curUrl=t;var s=$.getFileExtension(this._curUrl);e?i.loader.create(t,this._completeHandler):Wi.LoadableExtensions[s]?i.loader.load(t,this._completeHandler,null,Wi.LoadableExtensions[s]):t!=qe.getFileLoadPath(t)||Wi.No3dLoadTypes[s]||!Ze.createMap[s]?i.loader.load(t,this._completeHandler):i.loader.create(t,this._completeHandler)}onOneLoadComplete(){this._isLoading=!1,je.getRes(this._curUrl)||console.log("Fail to load:",this._curUrl);var t,e=$.getFileExtension(this._curUrl);Wi.LoadableExtensions[e]&&((t=je.getRes(this._curUrl))&&t instanceof He&&(t=t.json),t&&(t.loadList&&this.load(t.loadList,!1,!1),t.loadList3D&&this.load(t.loadList3D,!0,!1)));"sk"==e&&this.load(this._curUrl.replace(".sk",".png"),!1,!1),this.event(Ht.PROGRESS,this.getProgress()),this._checkNext()}getProgress(){return this.loadedCount/this.totalCount}}Wi.LoadableExtensions={scene:je.JSON,scene3d:je.JSON,ani:je.JSON,ui:je.JSON,prefab:je.PREFAB},Wi.No3dLoadTypes={png:!0,jpg:!0,txt:!0};class Yi extends Se{constructor(t=!0){super(),this.autoDestroyAtClosed=!1,this.url=null,this._viewCreated=!1,this._idMap=null,this._$componentType="Scene",Yi.unDestroyedScenes.push(this),this._scene=this,t&&this.createChildren()}createChildren(){}static setUIMap(t){let e=i.loader.getRes(t);if(!e)throw"请提前加载uimap的json,再使用该接口设置!";for(let t in e)i.Loader.loadedMap[M.formatURL(t+".scene")]=e[t]}loadScene(t){var e=t.indexOf(".")>-1?t:t+".scene",s=i.loader.getRes(e);if(s)this.createView(s);else{this._setBit(ge.NOT_READY,!0),i.loader.resetProgress();var r=new Wi;r.on(Ht.COMPLETE,this,this._onSceneLoaded,[e]),r.load(e)}}_onSceneLoaded(t){this.createView(i.Loader.getRes(t))}createView(t){t&&!this._viewCreated&&(this._viewCreated=!0,li.createByData(this,t))}getNodeByID(t){return this._idMap?this._idMap[t]:null}open(t=!0,e=null){t&&Yi.closeAll(),Yi.root.addChild(this),this.onOpened(e)}onOpened(t){}close(t=null){this.onClosed(t),this.autoDestroyAtClosed?this.destroy():this.removeSelf()}onClosed(t=null){}destroy(t=!0){this._idMap=null,super.destroy(t);for(var e=Yi.unDestroyedScenes,i=e.length-1;i>-1;i--)if(e[i]===this)return void e.splice(i,1)}set scaleX(t){super.get_scaleX()!=t&&(super.set_scaleX(t),this.event(Ht.RESIZE))}get scaleX(){return super.scaleX}set scaleY(t){super.get_scaleY()!=t&&(super.set_scaleY(t),this.event(Ht.RESIZE))}get scaleY(){return super.scaleY}get width(){if(this._width)return this._width;for(var t=0,e=this.numChildren-1;e>-1;e--){var i=this.getChildAt(e);i._visible&&(t=Math.max(i._x+i.width*i.scaleX,t))}return t}set width(t){super.get_width()!=t&&(super.set_width(t),this.callLater(this._sizeChanged))}get height(){if(this._height)return this._height;for(var t=0,e=this.numChildren-1;e>-1;e--){var i=this.getChildAt(e);i._visible&&(t=Math.max(i._y+i.height*i.scaleY,t))}return t}set height(t){super.get_height()!=t&&(super.set_height(t),this.callLater(this._sizeChanged))}_sizeChanged(){this.event(Ht.RESIZE)}static get root(){return Yi._root||(Yi._root=i.stage.addChild(new Se),Yi._root.name="root",i.stage.on("resize",null,()=>{Yi._root.size(i.stage.width,i.stage.height),Yi._root.event(Ht.RESIZE)}),Yi._root.size(i.stage.width,i.stage.height),Yi._root.event(Ht.RESIZE)),Yi._root}get timer(){return this._timer||i.timer}set timer(t){this._timer=t}static load(t,e=null,s=null){i.loader.resetProgress();var r=new Wi;function onProgress(t){Yi._loadPage&&Yi._loadPage.event("progress",t),s&&s.runWith(t)}r.on(Ht.PROGRESS,null,onProgress),r.once(Ht.COMPLETE,null,(function(){r.off(Ht.PROGRESS,null,onProgress);var s=i.Loader.getRes(t);if(!s)throw"Can not find scene:"+t;if(!s.props)throw"Scene data is error:"+t;var a=s.props.runtime?s.props.runtime:s.type,n=i.ClassUtils.getClass(a);if("instance"==s.props.renderType)var h=n.instance||(n.instance=new n);else h=new n;if(!(h&&h instanceof be))throw"Can not find scene:"+a;h.url=t,h._viewCreated?e&&e.runWith(h):(h.on("onViewCreated",null,(function(){e&&e.runWith(h)})),h.createView(s)),Yi.hideLoadingPage()})),r.load(t)}static open(t,e=!0,i=null,s=null,r=null){if(i instanceof b){var a=s;s=i,i=a}Yi.showLoadingPage(),Yi.load(t,b.create(null,this._onSceneLoaded,[e,s,i]),r)}static _onSceneLoaded(t,e,i,s){s.open(t,i),e&&e.runWith(s)}static close(t,e=""){for(var i=!1,s=Yi.unDestroyedScenes,r=0,a=s.length;r60&&(es.showCountInfo(),es._i=0)}static _addType(t){es._countDic[t]?es._countDic[t]+=1:es._countDic[t]=1}static showCountInfo(){var t;for(t in console.log("==================="),es._countDic)console.log("count:"+es._countDic[t]),es.showRenderTypeInfo(t,!0)}static enableQuickTest(){es.__init__(),Se.prototype.render=es.prototype.render,es._PreStageRender=Ne.prototype.render,Ne.prototype.render=es.prototype._stageRender}}es.showedDic={},es._rendertypeToStrDic={},es._typeToNameDic={},es._countDic={},es._i=0;class is extends Se{constructor(){super(),this.visible=!1,this.on(Ht.ADDED,this,this._onParentChange),this.on(Ht.REMOVED,this,this._onParentChange)}_onParentChange(){this.target=this.parent}play(t=1,e=null){isNaN(t)&&(t=1),this.url&&(this.stop(),this._channel=Xe.playSound(this.url,t,e))}stop(){this._channel&&!this._channel.isStopped&&this._channel.stop(),this._channel=null}_setPlayAction(t,e,i,s=!0){this[i]&&t&&(s?t.on(e,this,this[i]):t.off(e,this,this[i]))}_setPlayActions(t,e,i,s=!0){if(t&&e){var r,a,n=e.split(",");for(a=n.length,r=0;r0&&e<65535&&this.connect(t,e)}get input(){return this._input}get output(){return this._output}get connected(){return this._connected}get endian(){return this._endian}set endian(t){this._endian=t,null!=this._input&&(this._input.endian=t),null!=this._output&&(this._output.endian=t)}connect(t,e){var i="ws://"+t+":"+e;this.connectByUrl(i)}connectByUrl(t){null!=this._socket&&this.close(),this._socket&&this.cleanSocket(),this.protocols&&0!=this.protocols.length?this._socket=new Qt.window.WebSocket(t,this.protocols):this._socket=new Qt.window.WebSocket(t),this._socket.binaryType="arraybuffer",this._output=new this._byteClass,this._output.endian=this.endian,this._input=new this._byteClass,this._input.endian=this.endian,this._addInputPosition=0,this._socket.onopen=t=>{this._onOpen(t)},this._socket.onmessage=t=>{this._onMessage(t)},this._socket.onclose=t=>{this._onClose(t)},this._socket.onerror=t=>{this._onError(t)}}cleanSocket(){this.close(),this._connected=!1,this._socket.onopen=null,this._socket.onmessage=null,this._socket.onclose=null,this._socket.onerror=null,this._socket=null}close(){if(null!=this._socket)try{this._socket.close()}catch(t){}}_onOpen(t){this._connected=!0,this.event(Ht.OPEN,t)}_onMessage(t){if(t&&t.data){var e=t.data;if(this.disableInput&&e)this.event(Ht.MESSAGE,e);else{this._input.length>0&&this._input.bytesAvailable<1&&(this._input.clear(),this._addInputPosition=0);var i=this._input.pos;!this._addInputPosition&&(this._addInputPosition=0),this._input.pos=this._addInputPosition,e&&("string"==typeof e?this._input.writeUTFBytes(e):this._input.writeArrayBuffer(e),this._addInputPosition=this._input.pos,this._input.pos=i),this.event(Ht.MESSAGE,e)}}}_onClose(t){this._connected=!1,this.event(Ht.CLOSE,t)}_onError(t){this.event(Ht.ERROR,t)}send(t){this._socket.send(t)}flush(){if(this._output&&this._output.length>0){var t;try{this._socket&&this._socket.send(this._output.__getBuffer().slice(0,this._output.length))}catch(e){t=e}this._output.endian=this.endian,this._output.clear(),t&&this.event(Ht.ERROR,t)}}}rs.LITTLE_ENDIAN="littleEndian",rs.BIG_ENDIAN="bigEndian",(Ii=t.TextureDecodeFormat||(t.TextureDecodeFormat={}))[Ii.Normal=0]="Normal",Ii[Ii.RGBM=1]="RGBM";class as extends L{constructor(){var e=g.instance;super(e.RGB,!1),this._glTextureType=e.TEXTURE_2D,this._width=1,this._height=1,this._wrapModeU=this._wrapModeV=t.WarpMode.Clamp,this._filterMode=t.FilterMode.Bilinear,this._setWarpMode(e.TEXTURE_WRAP_S,this._wrapModeU),this._setWarpMode(e.TEXTURE_WRAP_T,this._wrapModeV),this._setFilterMode(this._filterMode),this._needUpdate=!1,this._readyed=!0,as._videoTexturePool.push(this)}static _update(){for(var t=as._videoTexturePool,e=0,i=t.length;e=hs.maxCount&&hs.clear(),hs._count++,hs._logdiv.innerText+=t+"\n",hs.autoScrollToBottom&&hs._logdiv.scrollHeight-hs._logdiv.scrollTop-hs._logdiv.clientHeight<50&&(hs._logdiv.scrollTop=hs._logdiv.scrollHeight))}static clear(){hs._logdiv.innerText="",hs._count=0}}hs._count=0,hs.maxCount=50,hs.autoScrollToBottom=!0;class os{constructor(t,e,i,s){this.scale=1,this.datas=new Array(300),this.datapos=0,this.id=t,this.color=e,this.name=i,this.scale=s}addData(t){this.datas[this.datapos]=t,this.datapos++,this.datapos%=300}}class ls extends Se{constructor(){super(),this.datas=[],this.xdata=new Array(ls.DATANUM),this.ydata=new Array(ls.DATANUM),this.hud_width=800,this.hud_height=200,this.gMinV=0,this.gMaxV=100,this.textSpace=40,this.sttm=0,ls.inst=this,this._renderType|=_e.CUSTOM,this._setRenderType(this._renderType),this._setCustomRender(),this.addDataDef(0,16777215,"frame",1),this.addDataDef(1,65280,"update",1),this.addDataDef(2,16711680,"flush",1),ls._now=performance?performance.now.bind(performance):Date.now}now(){return ls._now()}start(){this.sttm=ls._now()}end(t){var e=ls._now()-this.sttm;this.updateValue(t,e)}config(t,e){this.hud_width=t,this.hud_height=e}addDataDef(t,e,i,s){this.datas[t]=new os(t,e,i,s)}updateValue(t,e){this.datas[t].addData(e)}v2y(t){this._y,this.hud_height,this.gMinV,this.gMaxV;return this._y+this.hud_height*(1-(t-this.gMinV)/this.gMaxV)}drawHLine(t,e,i,s){var r=this._x,a=(this._x,this.hud_width,this.v2y(e));t.fillText(s,r,a-6,null,"green",null),r+=this.textSpace,t.fillStyle=i,t.fillRect(r,a,this._x+this.hud_width,1,null)}customRender(t,e,i){var s=performance.now();ls._lastTm<=0&&(ls._lastTm=s),this.updateValue(0,s-ls._lastTm),ls._lastTm=s,t.save(),t.fillRect(this._x,this._y,this.hud_width,this.hud_height+4,"#000000cc"),t.globalAlpha=.9,this.drawHLine(t,0,"green"," 0"),this.drawHLine(t,10,"green"," 10"),this.drawHLine(t,16.667,"red"," "),this.drawHLine(t,20,"green","50|20"),this.drawHLine(t,33.334,"yellow",""),this.drawHLine(t,16.667*3,"yellow",""),this.drawHLine(t,66.668,"yellow",""),this.drawHLine(t,50,"green","20|50"),this.drawHLine(t,100,"green","10|100");for(var r=0,a=this.datas.length;rthis.maxCount&&e.splice(this.maxCount,e.length-this.maxCount)}static addPoolCacheManager(t,e=100){var i;(i=new _s).sign=t,i.maxCount=e,pe.regCacheByFunction($.bind(i.tryDispose,i),$.bind(i.getCacheList,i))}}class us extends S{constructor(){super(...arguments),this._tweenDic={},this._tweenDataList=[],this._currTime=0,this._lastTime=0,this._startTime=0,this._index=0,this._gidIndex=0,this._firstTweenDic={},this._startTimeSort=!1,this._endTimeSort=!1,this._loopKey=!1,this.scale=1,this._frameRate=60,this._frameIndex=0,this._total=0}static to(t,e,i,s=null,r=0){return(new us).to(t,e,i,s,r)}static from(t,e,i,s=null,r=0){return(new us).from(t,e,i,s,r)}to(t,e,i,s=null,r=0){return this._create(t,e,i,s,r,!0)}from(t,e,i,s=null,r=0){return this._create(t,e,i,s,r,!1)}_create(t,e,i,r,a,n){var h=s.getItemByClass("tweenData",cs);return h.isTo=n,h.type=0,h.target=t,h.duration=i,h.data=e,h.startTime=this._startTime+a,h.endTime=h.startTime+h.duration,h.ease=r,this._startTime=Math.max(h.endTime,this._startTime),this._tweenDataList.push(h),this._startTimeSort=!0,this._endTimeSort=!0,this}addLabel(t,e){var i=s.getItemByClass("tweenData",cs);return i.type=1,i.data=t,i.endTime=i.startTime=this._startTime+e,this._labelDic||(this._labelDic={}),this._labelDic[t]=i,this._tweenDataList.push(i),this}removeLabel(t){if(this._labelDic&&this._labelDic[t]){var e=this._labelDic[t];if(e){var i=this._tweenDataList.indexOf(e);i>-1&&this._tweenDataList.splice(i,1)}delete this._labelDic[t]}}gotoTime(t){if(null!=this._tweenDataList&&0!=this._tweenDataList.length){var e,i,r,a;for(var n in this._firstTweenDic)if(i=this._firstTweenDic[n])for(var h in i)h in i.diyTarget&&(i.diyTarget[h]=i[h]);for(n in this._tweenDic)(e=this._tweenDic[n]).clear(),delete this._tweenDic[n];if(this._index=0,this._gidIndex=0,this._currTime=t,this._lastTime=Qt.now(),null==this._endTweenDataList||this._endTimeSort){this._endTimeSort=!1,this._endTweenDataList=r=this._tweenDataList.concat(),r.sort((function(t,e){return t.endTime>e.endTime?1:t.endTime=a.endTime))break;this._index=Math.max(this._index,o+1);var _=a.data;if(a.isTo)for(var u in _)a.target[u]=_[u]}for(o=0,l=this._tweenDataList.length;o=a.startTime&&te.startTime?1:t.startTime=this._startTime){if(!this._loopKey){for(var t in this._tweenDic)(e=this._tweenDic[t]).complete();return this.pause(),void this._complete()}if(this._complete(),!this._tweenDataList)return;this.gotoTime(0)}var e,i=Qt.now(),r=i-this._lastTime,a=this._currTime+=r*this.scale;for(t in this._lastTime=i,this._tweenDic)(e=this._tweenDic[t])._updateEase(a);if(0!=this._tweenDataList.length&&this._index=n.startTime&&(this._index++,0==n.type?(this._gidIndex++,(e=s.getItemByClass("tween",ii))._create(n.target,n.data,n.duration,n.ease,b.create(this,this._animComplete,[this._gidIndex]),0,!1,n.isTo,!0,!1),e.setStartTime(a),e.gid=this._gidIndex,this._tweenDic[this._gidIndex]=e,e._updateEase(a)):this.event(Ht.LABEL,n.data))}}_animComplete(t){this._tweenDic[t]&&delete this._tweenDic[t]}_complete(){this.event(Ht.COMPLETE)}get index(){return this._frameIndex}set index(t){this._frameIndex=t,this.gotoTime(this._frameIndex/this._frameRate*1e3)}get total(){return this._total=Math.floor(this._startTime/1e3*this._frameRate),this._total}reset(){var t,e,s;if(this._labelDic)for(t in this._labelDic)delete this._labelDic[t];for(t in this._tweenDic)this._tweenDic[t].clear(),delete this._tweenDic[t];for(t in this._firstTweenDic)delete this._firstTweenDic[t];if(this._endTweenDataList=null,this._tweenDataList&&this._tweenDataList.length)for(s=this._tweenDataList.length,e=0;e-1)return String.fromCharCode(ds.charsMap[e][0]);for(e=0;e-1)return String.fromCharCode(ds.combCharsMap[e][0][0])+String.fromCharCode(ds.combCharsMap[e][0][1]);return String.fromCharCode(t)}convertArabic(t){for(var e,i,s="",r=0;r=0&&this.isTransparent(t.charCodeAt(o));--o);for((!(e=!!(n=o>=0?t.charCodeAt(o):null)&&this.getCharRep(n))||null==e[2]&&null==e[3])&&(n=null);l0&&(s=g.UPLOAD_SHADER_UNIFORM_TYPE_DATA);var r=i._data;return g.instance.uploadShaderUniforms(e,r,s)}},t.LayaGPU=re,t.Loader=je,t.LoaderManager=Ze,t.LocalStorage=$e,t.Log=hs,t.MathUtil=ni,t.MatirxArray=ps,t.Matrix=p,t.Mesh2D=bt,t.MeshParticle2D=Ai,t.MeshQuadTexture=St,t.MeshTexture=wt,t.MeshVG=Mt,t.Mouse=Ci,t.MouseManager=Le,t.Node=be,t.Path=ut,t.PerfData=os,t.PerfHUD=ls,t.PerformancePlugin=Oe,t.Point=f,t.Pool=s,t.PoolCache=_s,t.Prefab=He,t.PrimitiveSV=gi,t.QuickTestTool=es,t.Rectangle=m,t.Render=ae,t.RenderInfo=Et,t.RenderSprite=ve,t.RenderState2D=U,t.RenderTexture2D=G,t.Resource=I,t.ResourceVersion=ss,t.RestoreCmd=st,t.RotateCmd=rt,t.RunDriver=Fe,t.SaveBase=pt,t.SaveClipRect=ft,t.SaveCmd=oe,t.SaveMark=mt,t.SaveTransform=gt,t.SaveTranslate=Tt,t.ScaleCmd=at,t.Scene=Yi,t.SceneLoader=Wi,t.SceneUtils=li,t.Script=Oi,t.Shader=z,t.Shader2D=Pt,t.Shader2X=K,t.ShaderCompile=yi,t.ShaderDefines2D=V,t.ShaderDefinesBase=Y,t.ShaderNode=xi,t.ShaderValue=class{constructor(){}},t.SkinMeshBuffer=Lt,t.SkinSV=mi,t.Socket=rs,t.Sound=class extends S{load(t){}play(t=0,e=0){return null}get duration(){return 0}dispose(){}},t.SoundChannel=Ge,t.SoundManager=Xe,t.SoundNode=is,t.Sprite=Se,t.SpriteConst=_e,t.SpriteStyle=Re,t.Stage=Ne,t.Stat=X,t.StatUI=di,t.StringKey=H,t.Submit=Nt,t.SubmitBase=dt,t.SubmitCMD=Z,t.SubmitCanvas=Ut,t.SubmitKey=q,t.SubmitTarget=Gt,t.SubmitTexture=kt,t.System=class{static changeDefinition(t,e){window.Laya[t]=e;var i=t+"=classObj";window.eval(i)}},t.SystemUtils=B,t.TTFLoader=ti,t.Text=Me,t.TextAtlas=Xt,t.TextRender=te,t.TextStyle=we,t.TextTexture=Vt,t.Texture=zt,t.Texture2D=O,t.TextureSV=Ti,t.TimeLine=us,t.Timer=pi,t.TouchManager=Pe,t.TransformCmd=nt,t.TranslateCmd=ht,t.Tween=ii,t.URL=M,t.Utils=$,t.Value2D=j,t.VectorGraphManager=fe,t.VertexArrayObject=class{constructor(){}},t.VertexBuffer2D=Rt,t.VideoTexture=as,t.WeakObject=oi,t.WebAudioSound=Ve,t.WebAudioSoundChannel=Ye,t.WebGL=se,t.WebGLCacheAsNormalCanvas=It,t.WebGLContext=R,t.WebGLRTMgr=k,t.WordText=jt,t.WorkerLoader=Ei,t.__init=Pi,t._static=_static,t.alertGlobalError=Bi,t.enableDebugPanel=Fi,t.init=Li,t.isWXOpenDataContext=void 0,t.isWXPosMsg=void 0,t.version=Di,t.static=_static,t}({}); \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/min/laya.d3.min.js b/examples/layaair/frontend/bin/libs/min/laya.d3.min.js new file mode 100644 index 0000000..9620c55 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/min/laya.d3.min.js @@ -0,0 +1 @@ +!function(e,t){"use strict";class r{constructor(){}static isZero(e){return Math.abs(e)0&&(n=1/Math.sqrt(n),t.x=r*n,t.y=a*n)}static scalarLength(e){var t=e.x,r=e.y;return Math.sqrt(t*t+r*r)}clone(){var e=new a;return this.cloneTo(e),e}forNativeElement(e=null){e?(this.elements=e,this.elements[0]=this.x,this.elements[1]=this.y):this.elements=new Float32Array([this.x,this.y]),a.rewriteNumProperty(this,"x",0),a.rewriteNumProperty(this,"y",1)}static rewriteNumProperty(e,t,r){Object.defineProperty(e,t,{get:function(){return this.elements[r]},set:function(e){this.elements[r]=e}})}}a.ZERO=new a(0,0),a.ONE=new a(1,1);class n{constructor(e=0,t=0,r=0,a=0){this.x=e,this.y=t,this.z=r,this.w=a}setValue(e,t,r,a){this.x=e,this.y=t,this.z=r,this.w=a}fromArray(e,t=0){this.x=e[t+0],this.y=e[t+1],this.z=e[t+2],this.w=e[t+3]}toArray(e,t=0){e[t+0]=this.x,e[t+1]=this.y,e[t+2]=this.z,e[t+3]=this.w}cloneTo(e){var t=e;t.x=this.x,t.y=this.y,t.z=this.z,t.w=this.w}clone(){var e=new n;return this.cloneTo(e),e}static lerp(e,t,r,a){var n=e.x,i=e.y,s=e.z,o=e.w;a.x=n+r*(t.x-n),a.y=i+r*(t.y-i),a.z=s+r*(t.z-s),a.w=o+r*(t.w-o)}static transformByM4x4(e,t,r){var a=e.x,n=e.y,i=e.z,s=e.w,o=t.elements;r.x=a*o[0]+n*o[4]+i*o[8]+s*o[12],r.y=a*o[1]+n*o[5]+i*o[9]+s*o[13],r.z=a*o[2]+n*o[6]+i*o[10]+s*o[14],r.w=a*o[3]+n*o[7]+i*o[11]+s*o[15]}static equals(e,t){return r.nearEqual(Math.abs(e.x),Math.abs(t.x))&&r.nearEqual(Math.abs(e.y),Math.abs(t.y))&&r.nearEqual(Math.abs(e.z),Math.abs(t.z))&&r.nearEqual(Math.abs(e.w),Math.abs(t.w))}length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)}lengthSquared(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w}static normalize(e,t){var r=e.length();if(r>0){var a=1/r;t.x=e.x*a,t.y=e.y*a,t.z=e.z*a,t.w=e.w*a}}static add(e,t,r){r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w}static subtract(e,t,r){r.x=e.x-t.x,r.y=e.y-t.y,r.z=e.z-t.z,r.w=e.w-t.w}static multiply(e,t,r){r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z,r.w=e.w*t.w}static scale(e,t,r){r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w*t}static Clamp(e,t,r,a){var n=e.x,i=e.y,s=e.z,o=e.w,l=t.x,h=t.y,_=t.z,d=t.w,c=r.x,u=r.y,m=r.z,f=r.w;n=(n=n>c?c:n)u?u:i)m?m:s)<_?_:s,o=(o=o>f?f:o)0&&(i=1/Math.sqrt(i),t.x=r*i,t.y=a*i,t.z=n*i)}static multiply(e,t,r){r.x=e.x*t.x,r.y=e.y*t.y,r.z=e.z*t.z}static scale(e,t,r){r.x=e.x*t,r.y=e.y*t,r.z=e.z*t}static lerp(e,t,r,a){var n=e.x,i=e.y,s=e.z;a.x=n+r*(t.x-n),a.y=i+r*(t.y-i),a.z=s+r*(t.z-s)}static transformV3ToV3(e,t,r){var a=i._tempVector4;i.transformV3ToV4(e,t,a),r.x=a.x,r.y=a.y,r.z=a.z}static transformV3ToV4(e,t,r){var a=e.x,n=e.y,i=e.z,s=t.elements;r.x=a*s[0]+n*s[4]+i*s[8]+s[12],r.y=a*s[1]+n*s[5]+i*s[9]+s[13],r.z=a*s[2]+n*s[6]+i*s[10]+s[14],r.w=a*s[3]+n*s[7]+i*s[11]+s[15]}static TransformNormal(e,t,r){var a=e.x,n=e.y,i=e.z,s=t.elements;r.x=a*s[0]+n*s[4]+i*s[8],r.y=a*s[1]+n*s[5]+i*s[9],r.z=a*s[2]+n*s[6]+i*s[10]}static transformCoordinate(e,t,r){var a=e.x,n=e.y,i=e.z,s=t.elements,o=a*s[3]+n*s[7]+i*s[11]+s[15];r.x=(a*s[0]+n*s[4]+i*s[8]+s[12])/o,r.y=(a*s[1]+n*s[5]+i*s[9]+s[13])/o,r.z=(a*s[2]+n*s[6]+i*s[10]+s[14])/o}static Clamp(e,t,r,a){var n=e.x,i=e.y,s=e.z,o=t.x,l=t.y,h=t.z,_=r.x,d=r.y,c=r.z;n=(n=n>_?_:n)d?d:i)c?c:s)2048?(this._maxLightCount=2048,console.warn("Config3D: maxLightCount must less equal 2048.")):this._maxLightCount=e}get lightClusterCount(){return this._lightClusterCount}set lightClusterCount(e){e.x>128||e.y>128||e.z>128?(this._lightClusterCount.setValue(Math.min(e.x,128),Math.min(e.y,128),Math.min(e.z,128)),console.warn("Config3D: lightClusterCount X and Y、Z must less equal 128.")):e.cloneTo(this._lightClusterCount);var t=4*Math.floor(2048/this._lightClusterCount.z-1);t0?Math.atan(t/e):e<0?t>0?Math.atan(t/e)+Math.PI:Math.atan(t/e)-Math.PI:0}static angleTo(e,t,r){i.subtract(t,e,T.TEMPVector30),i.normalize(T.TEMPVector30,T.TEMPVector30),r.x=Math.asin(T.TEMPVector30.y),r.y=T.arcTanAngle(-T.TEMPVector30.z,-T.TEMPVector30.x)}static createFromAxisAngle(e,t,r){t*=.5;var a=Math.sin(t);r.x=a*e.x,r.y=a*e.y,r.z=a*e.z,r.w=Math.cos(t)}static createFromMatrix4x4(e,t){var r,a,n=e.elements,i=n[0]+n[5]+n[10];i>0?(r=Math.sqrt(i+1),t.w=.5*r,r=.5/r,t.x=(n[6]-n[9])*r,t.y=(n[8]-n[2])*r,t.z=(n[1]-n[4])*r):n[0]>=n[5]&&n[0]>=n[10]?(a=.5/(r=Math.sqrt(1+n[0]-n[5]-n[10])),t.x=.5*r,t.y=(n[1]+n[4])*a,t.z=(n[2]+n[8])*a,t.w=(n[6]-n[9])*a):n[5]>n[10]?(a=.5/(r=Math.sqrt(1+n[5]-n[0]-n[10])),t.x=(n[4]+n[1])*a,t.y=.5*r,t.z=(n[9]+n[6])*a,t.w=(n[8]-n[2])*a):(a=.5/(r=Math.sqrt(1+n[10]-n[0]-n[5])),t.x=(n[8]+n[2])*a,t.y=(n[9]+n[6])*a,t.z=.5*r,t.w=(n[1]-n[4])*a)}static slerp(e,t,r,a){var n,i,s,o,l,h=e.x,_=e.y,d=e.z,c=e.w,u=t.x,m=t.y,f=t.z,E=t.w;return(i=h*u+_*m+d*f+c*E)<0&&(i=-i,u=-u,m=-m,f=-f,E=-E),1-i>1e-6?(n=Math.acos(i),s=Math.sin(n),o=Math.sin((1-r)*n)/s,l=Math.sin(r*n)/s):(o=1-r,l=r),a.x=o*h+l*u,a.y=o*_+l*m,a.z=o*d+l*f,a.w=o*c+l*E,a}static lerp(e,t,r,a){var n=1-r;T.dot(e,t)>=0?(a.x=n*e.x+r*t.x,a.y=n*e.y+r*t.y,a.z=n*e.z+r*t.z,a.w=n*e.w+r*t.w):(a.x=n*e.x-r*t.x,a.y=n*e.y-r*t.y,a.z=n*e.z-r*t.z,a.w=n*e.w-r*t.w),a.normalize(a)}static add(e,t,r){r.x=e.x+t.x,r.y=e.y+t.y,r.z=e.z+t.z,r.w=e.w+t.w}static dot(e,t){return e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w}scaling(e,t){t.x=this.x*e,t.y=this.y*e,t.z=this.z*e,t.w=this.w*e}normalize(e){var t=this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w;t>0&&(t=1/Math.sqrt(t),e.x=this.x*t,e.y=this.y*t,e.z=this.z*t,e.w=this.w*t)}length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)}rotateX(e,t){e*=.5;var r=Math.sin(e),a=Math.cos(e);t.x=this.x*a+this.w*r,t.y=this.y*a+this.z*r,t.z=this.z*a-this.y*r,t.w=this.w*a-this.x*r}rotateY(e,t){e*=.5;var r=Math.sin(e),a=Math.cos(e);t.x=this.x*a-this.z*r,t.y=this.y*a+this.w*r,t.z=this.z*a+this.x*r,t.w=this.w*a-this.y*r}rotateZ(e,t){e*=.5;var r=Math.sin(e),a=Math.cos(e);t.x=this.x*a+this.y*r,t.y=this.y*a-this.x*r,t.z=this.z*a+this.w*r,t.w=this.w*a-this.z*r}getYawPitchRoll(e){i.transformQuat(i._ForwardRH,this,T.TEMPVector31),i.transformQuat(i._Up,this,T.TEMPVector32);var t=T.TEMPVector32;T.angleTo(i._ZERO,T.TEMPVector31,T.TEMPVector33);var r=T.TEMPVector33;r.x==Math.PI/2?(r.y=T.arcTanAngle(t.z,t.x),r.z=0):r.x==-Math.PI/2?(r.y=T.arcTanAngle(-t.z,-t.x),r.z=0):(h.Matrix4x4.createRotationY(-r.y,h.Matrix4x4.TEMPMatrix0),h.Matrix4x4.createRotationX(-r.x,h.Matrix4x4.TEMPMatrix1),i.transformCoordinate(T.TEMPVector32,h.Matrix4x4.TEMPMatrix0,T.TEMPVector32),i.transformCoordinate(T.TEMPVector32,h.Matrix4x4.TEMPMatrix1,T.TEMPVector32),r.z=T.arcTanAngle(t.y,-t.x)),r.y<=-Math.PI&&(r.y=Math.PI),r.z<=-Math.PI&&(r.z=Math.PI),r.y>=Math.PI&&r.z>=Math.PI&&(r.y=0,r.z=0,r.x=Math.PI-r.x);var a=e;a.x=r.y,a.y=r.x,a.z=r.z}invert(e){var t=this.x,r=this.y,a=this.z,n=this.w,i=t*t+r*r+a*a+n*n,s=i?1/i:0;e.x=-t*s,e.y=-r*s,e.z=-a*s,e.w=n*s}identity(){this.x=0,this.y=0,this.z=0,this.w=1}fromArray(e,t=0){this.x=e[t+0],this.y=e[t+1],this.z=e[t+2],this.w=e[t+3]}cloneTo(e){this!==e&&(e.x=this.x,e.y=this.y,e.z=this.z,e.w=this.w)}clone(){var e=new T;return this.cloneTo(e),e}equals(e){return r.nearEqual(this.x,e.x)&&r.nearEqual(this.y,e.y)&&r.nearEqual(this.z,e.z)&&r.nearEqual(this.w,e.w)}static rotationLookAt(e,t,r){T.lookAt(i._ZERO,e,t,r)}static lookAt(e,t,r,a){E.lookAt(e,t,r,T._tempMatrix3x3),T.rotationMatrix(T._tempMatrix3x3,a)}lengthSquared(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w}static invert(e,t){var a=e.lengthSquared();r.isZero(a)||(a=1/a,t.x=-e.x*a,t.y=-e.y*a,t.z=-e.z*a,t.w=e.w*a)}static rotationMatrix(e,t){var r,a,n=e.elements,i=n[0],s=n[1],o=n[2],l=n[3],h=n[4],_=n[5],d=n[6],c=n[7],u=n[8],m=i+h+u;m>0?(r=Math.sqrt(m+1),t.w=.5*r,r=.5/r,t.x=(_-c)*r,t.y=(d-o)*r,t.z=(s-l)*r):i>=h&&i>=u?(a=.5/(r=Math.sqrt(1+i-h-u)),t.x=.5*r,t.y=(s+l)*a,t.z=(o+d)*a,t.w=(_-c)*a):h>u?(a=.5/(r=Math.sqrt(1+h-i-u)),t.x=(l+s)*a,t.y=.5*r,t.z=(c+_)*a,t.w=(d-o)*a):(a=.5/(r=Math.sqrt(1+u-i-h)),t.x=(d+o)*a,t.y=(c+_)*a,t.z=.5*r,t.w=(s-l)*a)}forNativeElement(e=null){e?(this.elements=e,this.elements[0]=this.x,this.elements[1]=this.y,this.elements[2]=this.z,this.elements[3]=this.w):this.elements=new Float32Array([this.x,this.y,this.z,this.w]),a.rewriteNumProperty(this,"x",0),a.rewriteNumProperty(this,"y",1),a.rewriteNumProperty(this,"z",2),a.rewriteNumProperty(this,"w",3)}}T.TEMPVector30=new i,T.TEMPVector31=new i,T.TEMPVector32=new i,T.TEMPVector33=new i,T._tempMatrix3x3=new E,T.DEFAULT=new T,T.NAN=new T(NaN,NaN,NaN,NaN);class p extends m{constructor(){super(),this.inTangent=new n,this.outTangent=new n,this.value=new T}cloneTo(e){super.cloneTo(e);var t=e;this.inTangent.cloneTo(t.inTangent),this.outTangent.cloneTo(t.outTangent),this.value.cloneTo(t.value)}}class g extends m{constructor(){super(),this.inTangent=new i,this.outTangent=new i,this.value=new i}cloneTo(e){super.cloneTo(e);var t=e;this.inTangent.cloneTo(t.inTangent),this.outTangent.cloneTo(t.outTangent),this.value.cloneTo(t.value)}}class S{static READ_DATA(){S._DATA.offset=S._reader.getUint32(),S._DATA.size=S._reader.getUint32()}static READ_BLOCK(){for(var e=S._BLOCK.count=S._reader.getUint16(),t=S._BLOCK.blockStarts=[],r=S._BLOCK.blockLengths=[],a=0;a0&&(b.params=V=[]),t=0;t0&&(V.params=B=[]),r=0;r=.64&&(s>1?o=0:o*=1-(s-.64)/.36),i[n]=Math.floor(255*o+.5)}static haloTexture(e,t,r,a,n,i){var s=(e-(r>>=1))/r,o=(t-(a>>=1))/a,l=s*s+o*o;l>1&&(l=1),i[n]=Math.floor(255*(1-l)+.5)}static _generateTexture2D(e,r,a,n){var i=0,s=0;switch(e.format){case t.TextureFormat.R8G8B8:s=3;break;case t.TextureFormat.R8G8B8A8:s=4;break;case t.TextureFormat.Alpha8:s=1;break;default:throw"GeneratedTexture._generateTexture: unkonw texture format."}for(var o=new Uint8Array(r*a*s),l=0;l=0?e.substr(t):null}static _createAffineTransformationArray(e,t,r,a){var n=t.x,i=t.y,s=t.z,o=t.w,l=n+n,h=i+i,_=s+s,d=n*l,c=n*h,u=n*_,m=i*h,f=i*_,E=s*_,T=o*l,p=o*h,g=o*_,S=r.x,R=r.y,v=r.z;a[0]=(1-(m+E))*S,a[1]=(c+g)*S,a[2]=(u-p)*S,a[3]=0,a[4]=(c-g)*R,a[5]=(1-(d+E))*R,a[6]=(f+T)*R,a[7]=0,a[8]=(u+p)*v,a[9]=(f-T)*v,a[10]=(1-(d+m))*v,a[11]=0,a[12]=e.x,a[13]=e.y,a[14]=e.z,a[15]=1}static _mulMatrixArray(e,t,r,a,n){var i=t,s=e,o=a,l=i[r],h=i[r+1],_=i[r+2],d=i[r+3],c=i[r+4],u=i[r+5],m=i[r+6],f=i[r+7],E=i[r+8],T=i[r+9],p=i[r+10],g=i[r+11],S=i[r+12],R=i[r+13],v=i[r+14],x=i[r+15],A=s[0],I=s[1],M=s[2],D=s[3],L=s[4],y=s[5],C=s[6],O=s[7],N=s[8],P=s[9],w=s[10],b=s[11],V=s[12],B=s[13],F=s[14],U=s[15];o[n]=l*A+h*L+_*N+d*V,o[n+1]=l*I+h*y+_*P+d*B,o[n+2]=l*M+h*C+_*w+d*F,o[n+3]=l*D+h*O+_*b+d*U,o[n+4]=c*A+u*L+m*N+f*V,o[n+5]=c*I+u*y+m*P+f*B,o[n+6]=c*M+u*C+m*w+f*F,o[n+7]=c*D+u*O+m*b+f*U,o[n+8]=E*A+T*L+p*N+g*V,o[n+9]=E*I+T*y+p*P+g*B,o[n+10]=E*M+T*C+p*w+g*F,o[n+11]=E*D+T*O+p*b+g*U,o[n+12]=S*A+R*L+v*N+x*V,o[n+13]=S*I+R*y+v*P+x*B,o[n+14]=S*M+R*C+v*w+x*F,o[n+15]=S*D+R*O+v*b+x*U}static arcTanAngle(e,t){return 0==e?1==t?Math.PI/2:-Math.PI/2:e>0?Math.atan(t/e):e<0?t>0?Math.atan(t/e)+Math.PI:Math.atan(t/e)-Math.PI:0}static angleTo(e,t,r){i.subtract(t,e,T.TEMPVector30),i.normalize(T.TEMPVector30,T.TEMPVector30),r.x=Math.asin(T.TEMPVector30.y),r.y=A.arcTanAngle(-T.TEMPVector30.z,-T.TEMPVector30.x)}static transformQuat(e,t,r){var a=t,n=e.x,i=e.y,s=e.z,o=a[0],l=a[1],h=a[2],_=a[3],d=_*n+l*s-h*i,c=_*i+h*n-o*s,u=_*s+o*i-l*n,m=-o*n-l*i-h*s;r.x=d*_+m*-o+c*-h-u*-l,r.y=c*_+m*-l+u*-o-d*-h,r.z=u*_+m*-h+d*-l-c*-o}static quaternionWeight(e,t,r){r.x=e.x*t,r.y=e.y*t,r.z=e.z*t,r.w=e.w}static quaternionConjugate(e,t){t.x=-e.x,t.y=-e.y,t.z=-e.z,t.w=e.w}static scaleWeight(e,t,r){var a=e.x,n=e.y,i=e.z;r.x=a>0?Math.pow(Math.abs(a),t):-Math.pow(Math.abs(a),t),r.y=n>0?Math.pow(Math.abs(n),t):-Math.pow(Math.abs(n),t),r.z=i>0?Math.pow(Math.abs(i),t):-Math.pow(Math.abs(i),t)}static scaleBlend(e,t,r,a){var n=A._tempVector3_0,i=A._tempVector3_1;A.scaleWeight(e,1-r,n),A.scaleWeight(t,r,i);var s=r>.5?t:e;a.x=s.x>0?Math.abs(n.x*i.x):-Math.abs(n.x*i.x),a.y=s.y>0?Math.abs(n.y*i.y):-Math.abs(n.y*i.y),a.z=s.z>0?Math.abs(n.z*i.z):-Math.abs(n.z*i.z)}static matrix4x4MultiplyFFF(e,t,r){var a,n,i,s,o;if(r===t)for(t=new Float32Array(16),a=0;a<16;++a)t[a]=r[a];var l=t[0],h=t[1],_=t[2],d=t[3],c=t[4],u=t[5],m=t[6],f=t[7],E=t[8],T=t[9],p=t[10],g=t[11],S=t[12],R=t[13],v=t[14],x=t[15];for(a=0;a<4;a++)n=e[a],i=e[a+4],s=e[a+8],o=e[a+12],r[a]=n*l+i*h+s*_+o*d,r[a+4]=n*c+i*u+s*m+o*f,r[a+8]=n*E+i*T+s*p+o*g,r[a+12]=n*S+i*R+s*v+o*x}static matrix4x4MultiplyFFFForNative(e,r,a){t.LayaGL.instance.matrix4x4Multiply(e,r,a)}static matrix4x4MultiplyMFM(e,t,r){A.matrix4x4MultiplyFFF(e.elements,t,r.elements)}static _buildTexture2D(e,r,a,n,i=!1){var s=new t.Texture2D(e,r,a,i,!0);return s.anisoLevel=1,s.filterMode=t.FilterMode.Point,x._generateTexture2D(s,e,r,n),s}static _drawBound(e,t,r){e.lineCount+12>e.maxLineCount&&(e.maxLineCount+=12);var a=A._tempVector3_0,n=A._tempVector3_1,i=t.min,s=t.max;a.setValue(i.x,i.y,i.z),n.setValue(s.x,i.y,i.z),e.addLine(a,n,r,r),a.setValue(i.x,i.y,i.z),n.setValue(i.x,i.y,s.z),e.addLine(a,n,r,r),a.setValue(s.x,i.y,i.z),n.setValue(s.x,i.y,s.z),e.addLine(a,n,r,r),a.setValue(i.x,i.y,s.z),n.setValue(s.x,i.y,s.z),e.addLine(a,n,r,r),a.setValue(i.x,i.y,i.z),n.setValue(i.x,s.y,i.z),e.addLine(a,n,r,r),a.setValue(i.x,i.y,s.z),n.setValue(i.x,s.y,s.z),e.addLine(a,n,r,r),a.setValue(s.x,i.y,i.z),n.setValue(s.x,s.y,i.z),e.addLine(a,n,r,r),a.setValue(s.x,i.y,s.z),n.setValue(s.x,s.y,s.z),e.addLine(a,n,r,r),a.setValue(i.x,s.y,i.z),n.setValue(s.x,s.y,i.z),e.addLine(a,n,r,r),a.setValue(i.x,s.y,i.z),n.setValue(i.x,s.y,s.z),e.addLine(a,n,r,r),a.setValue(s.x,s.y,i.z),n.setValue(s.x,s.y,s.z),e.addLine(a,n,r,r),a.setValue(i.x,s.y,s.z),n.setValue(s.x,s.y,s.z),e.addLine(a,n,r,r)}static _getHierarchyPath(e,t,r){r.length=0;for(var a=t;a!==e;){var n=a._parent;if(!n)return null;r.push(n.getChildIndex(a)),a=n}return r}static _getNodeByHierarchyPath(e,t){for(var r=e,a=t.length-1;a>=0;a--)r=r.getChildAt(t[a]);return r}static uint8ArrayToArrayBuffer(e){let r,a=e.width,n=e.height;switch(e.format){case t.RenderTextureFormat.R8G8B8:case t.RenderTextureFormat.R8G8B8A8:r=new Uint8Array(a*n*4);break;case t.RenderTextureFormat.R16G16B16A16:r=new Float32Array(a*n*4);break;default:throw"this function is not surpprt "+e.format.toString()+"format Material"}switch(e.getData(0,0,e.width,e.height,r),e.format){case t.RenderTextureFormat.R16G16B16A16:let e=r,i=new Uint8Array(a*n*4);for(let t=0,r=e.length;tt);)m++,h++,r[o]=m;else for((h=m+1)!==u&&t>c[h].time&&(m=u-1,r[o]=m),h=m+1;m>-1&&!(c[m].timee?a=t-1:r=t+1}return r}addEvent(e){var t=this._binarySearchEventIndex(e.time);this._animationEvents.splice(t,0,e)}_disposeResource(){this._nodes=null,this._nodesMap=null}}I.ANIMATIONCLIP="ANIMATIONCLIP",I._tempQuaternion0=new T;class M{constructor(){this._currentState=null}get normalizedTime(){return this._normalizedTime}get duration(){return this._duration}get animatorState(){return this._currentState}_resetPlayState(e,t){this._finish=!1,this._startPlayTime=e,this._elapsedTime=e,this._playEventIndex=0,this._lastIsFront=!0,this._normalizedTime=this._elapsedTime/t;var r=this._normalizedTime%1;this._normalizedPlayTime=r<0?r+1:r}_cloneTo(e){e._finish=this._finish,e._startPlayTime=this._startPlayTime,e._elapsedTime=this._elapsedTime,e._normalizedTime=this._normalizedTime,e._normalizedPlayTime=this._normalizedPlayTime,e._playEventIndex=this._playEventIndex,e._lastIsFront=this._lastIsFront}}class D{constructor(e){this._referenceCount=0,this._playType=-1,this._crossDuration=-1,this._crossMark=0,this._crossNodesOwnersCount=0,this._crossNodesOwners=[],this._crossNodesOwnersIndicesMap={},this._srcCrossClipNodeIndices=[],this._destCrossClipNodeIndices=[],this._statesMap={},this._states=[],this._playStateInfo=new M,this._crossPlayStateInfo=new M,this.blendingMode=D.BLENDINGMODE_OVERRIDE,this.defaultWeight=1,this.playOnWake=!0,this.name=e}get defaultState(){return this._defaultState}set defaultState(e){this._defaultState=e,this._statesMap[e.name]=e}get avatarMask(){return this._avatarMask}set avatarMask(e){this._avatarMask=e}_removeClip(e,t,r,a){var n=a._clip,i=e[r];if(e.splice(r,1),delete t[a.name],this._animator){var s=n._nodes,o=i._nodeOwners;n._removeReference();for(var l=0,h=s.count;l0&&this._clip._removeReference(this._referenceCount),e){var t=this._realtimeDatas,r=e._nodes,a=r.count;this._currentFrameIndices=new Int16Array(a),this._resetFrameIndices(),this._referenceCount>0&&e._addReference(this._referenceCount),this._realtimeDatas.length=a;for(var n=0;n=n)return t._finish=!0,t._elapsedTime=n,void(t._normalizedPlayTime=1);if(h)for(var _=0,d=h.length;_=0&&(s=t[r]).time>=a;r--)for(o=0,l=e.length;o=t._lastElapsedTime;t._lastIsFront!==h&&(h?t._playEventIndex++:t._playEventIndex--,t._lastIsFront=h);var _=t._playEventIndex;if(h){var d=this._eventScript(r,n,t._playEventIndex,l>0?i:o,!0);_===t._playEventIndex&&(t._playEventIndex=d);for(var c=0,u=l-1;c0&&o>0&&(t._playEventIndex=this._eventScript(r,n,0,o,!0))}else{d=this._eventScript(r,n,t._playEventIndex,l>0?0:o,!1);_===t._playEventIndex&&(t._playEventIndex=d);var m=n.length-1;for(c=0,u=l-1;c0&&o>0&&(t._playEventIndex=this._eventScript(r,n,m,o,!1))}}}_updateClipDatas(e,t,r,a=null){var n=e._clip,i=n._duration,s=e.clipStart*i+r._normalizedPlayTime*r._duration,o=e._currentFrameIndices,l=r._elapsedTime>r._lastElapsedTime;n._evaluateClipDatasRealTime(n._nodes,s,o,t,l,e._realtimeDatas,a)}_applyFloat(e,t,r,a,n,i,s){if(r.updateMark===this._updateMark)if(a)e[t]+=n*s;else{var o=e[t];e[t]=o+n*(s-o)}else if(i)e[t]=a?r.defaultValue+s:s;else if(a)e[t]=r.defaultValue+n*s;else{var l=r.defaultValue;e[t]=l+n*(s-l)}}_applyPositionAndRotationEuler(e,t,r,a,n,i){if(e.updateMark===this._updateMark)if(t)i.x+=r*n.x,i.y+=r*n.y,i.z+=r*n.z;else{var s=i.x,o=i.y,l=i.z;i.x=s+r*(n.x-s),i.y=o+r*(n.y-o),i.z=l+r*(n.z-l)}else if(a)if(t){var h=e.defaultValue;i.x=h.x+n.x,i.y=h.y+n.y,i.z=h.z+n.z}else i.x=n.x,i.y=n.y,i.z=n.z;else if(h=e.defaultValue,t)i.x=h.x+r*n.x,i.y=h.y+r*n.y,i.z=h.z+r*n.z;else{var _=h.x,d=h.y,c=h.z;i.x=_+r*(n.x-_),i.y=d+r*(n.y-d),i.z=c+r*(n.z-c)}}_applyRotation(e,t,r,a,n,i){if(e.updateMark===this._updateMark)if(t){var s=O._tempQuaternion1;A.quaternionWeight(n,r,s),s.normalize(s),T.multiply(i,s,i)}else T.lerp(i,n,r,i);else if(a)if(t){var o=e.defaultValue;T.multiply(o,n,i)}else i.x=n.x,i.y=n.y,i.z=n.z,i.w=n.w;else o=e.defaultValue,t?(s=O._tempQuaternion1,A.quaternionWeight(n,r,s),s.normalize(s),T.multiply(o,s,i)):T.lerp(o,n,r,i)}_applyScale(e,t,r,a,n,i){if(e.updateMark===this._updateMark)if(t){var s=O._tempVector31;A.scaleWeight(n,r,s),i.x=i.x*s.x,i.y=i.y*s.y,i.z=i.z*s.z}else A.scaleBlend(i,n,r,i);else if(a)if(t){var o=e.defaultValue;i.x=o.x*n.x,i.y=o.y*n.y,i.z=o.z*n.z}else i.x=n.x,i.y=n.y,i.z=n.z;else o=e.defaultValue,t?(s=O._tempVector31,A.scaleWeight(n,r,s),i.x=o.x*s.x,i.y=o.y*s.y,i.z=o.z*s.z):A.scaleBlend(o,n,r,i)}_applyCrossData(e,t,r,a,n,i,s){var o=e.propertyOwner;if(o){switch(e.type){case 0:for(var l=e.property,h=l.length-1,_=0;_E?E/m:1,p=this._speed*c.speed;this._updatePlayer(c,s,e*T*p,u.islooping);var g=(s._elapsedTime-f)/T/m,S=!1;g>=1?t&&(this._updateClipDatas(c,d,s,n.avatarMask),this._setClipDatasToNode(c,d,n.defaultWeight,0===r,n),n._playType=0,i._currentState=c,s._cloneTo(i)):(i._finish||(h=this._speed*o.speed,S=!0,this._updatePlayer(o,i,e*h,l.islooping),t&&this._updateClipDatas(o,d,i,n.avatarMask)),t&&(this._updateClipDatas(c,d,s,n.avatarMask),this._setCrossClipDatasToNode(n,o,c,g,0===r))),t&&(this._updateEventScript(o,i),this._updateEventScript(c,s)),this._updateStateFinish(c,s),S&&this._updateStateFinish(i._currentState,i);break;case 2:u=(c=n._crossPlayState)._clip,m=n._crossDuration,f=s._startPlayTime,T=m>(E=u._duration-f)?E/m:1,p=this._speed*c.speed,this._updatePlayer(c,s,e*T*p,u.islooping),t&&((g=(s._elapsedTime-f)/T/m)>=1?(this._updateClipDatas(c,d,s,n.avatarMask),this._setClipDatasToNode(c,d,1,0===r,n),n._playType=0,i._currentState=c,s._cloneTo(i)):(this._updateClipDatas(c,d,s,n.avatarMask),this._setFixedCrossClipDatasToNode(n,c,g,0===r)),this._updateEventScript(c,s)),this._updateStateFinish(c,s)}}t&&this._avatar&&this._updateAvatarNodesToSprite()}}_cloneTo(e){var t=e;t.avatar=this.avatar,t.cullingMode=this.cullingMode;for(var r=0,a=this._controllerLayers.length;r1,l!==t.RenderTextureFormat.Depth&&l!==t.RenderTextureFormat.ShadowMap){if(this._mulSamplerRT){switch(this._mulRenderBuffer=n.createRenderbuffer(),n.bindRenderbuffer(n.RENDERBUFFER,this._mulRenderBuffer),l){case t.RenderTextureFormat.R8G8B8:n.renderbufferStorageMultisample(n.RENDERBUFFER,this._mulSampler,n.RGB8,e,r);break;case t.RenderTextureFormat.R8G8B8A8:n.renderbufferStorageMultisample(n.RENDERBUFFER,this._mulSampler,n.RGBA8,e,r);break;case t.RenderTextureFormat.Alpha8:n.renderbufferStorageMultisample(n.RENDERBUFFER,this._mulSampler,n.ALPHA,e,r);break;case t.RenderTextureFormat.R16G16B16A16:n.renderbufferStorageMultisample(n.RENDERBUFFER,this._mulSampler,n.RGBA16F,e,r)}n.framebufferRenderbuffer(a.FRAMEBUFFER,a.COLOR_ATTACHMENT0,a.RENDERBUFFER,this._mulRenderBuffer)}switch(t.WebGLContext.bindTexture(a,i,this._glTexture),l){case t.RenderTextureFormat.R8G8B8:o?n.texStorage2D(i,this._mipmapCount,n.RGB8,e,r):a.texImage2D(i,0,a.RGB,e,r,0,a.RGB,a.UNSIGNED_BYTE,null);break;case t.RenderTextureFormat.R8G8B8A8:o?n.texStorage2D(i,this._mipmapCount,n.RGBA8,e,r):a.texImage2D(i,0,a.RGBA,e,r,0,a.RGBA,a.UNSIGNED_BYTE,null);break;case t.RenderTextureFormat.Alpha8:o?n.texStorage2D(i,this.mipmapCount,n.R8,e,r):a.texImage2D(i,0,a.ALPHA,e,r,0,a.ALPHA,a.UNSIGNED_BYTE,null);break;case t.RenderTextureFormat.R16G16B16A16:o?n.texStorage2D(i,this._mipmapCount,n.RGBA16F,e,r):a.texImage2D(i,0,a.RGBA,e,r,0,a.RGBA,s._oesTextureHalfFloat.HALF_FLOAT_OES,null)}this._mulSamplerRT?(this._mulFrameBuffer=n.createFramebuffer(),a.bindFramebuffer(a.FRAMEBUFFER,this._mulFrameBuffer),a.framebufferTexture2D(n.FRAMEBUFFER,n.COLOR_ATTACHMENT0,n.TEXTURE_2D,this._glTexture,0)):a.framebufferTexture2D(a.FRAMEBUFFER,a.COLOR_ATTACHMENT0,a.TEXTURE_2D,this._glTexture,0)}if(l==t.RenderTextureFormat.Depth||l==t.RenderTextureFormat.ShadowMap){switch(a.bindFramebuffer(a.FRAMEBUFFER,this._frameBuffer),t.WebGLContext.bindTexture(a,i,this._glTexture),this.filterMode=t.FilterMode.Point,this._depthStencilFormat){case t.RenderTextureDepthFormat.DEPTH_16:o?n.texStorage2D(i,this._mipmapCount,n.DEPTH_COMPONENT16,e,r):a.texImage2D(i,0,a.DEPTH_COMPONENT,e,r,0,a.DEPTH_COMPONENT,a.UNSIGNED_SHORT,null),a.framebufferTexture2D(a.FRAMEBUFFER,a.DEPTH_ATTACHMENT,a.TEXTURE_2D,this._glTexture,0);break;case t.RenderTextureDepthFormat.DEPTHSTENCIL_24_8:o?n.texStorage2D(i,this._mipmapCount,n.DEPTH24_STENCIL8,e,r):a.texImage2D(i,0,a.DEPTH_STENCIL,e,r,0,a.DEPTH_STENCIL,s._webgl_depth_texture.UNSIGNED_INT_24_8_WEBGL,null),a.framebufferTexture2D(a.FRAMEBUFFER,a.DEPTH_STENCIL_ATTACHMENT,a.TEXTURE_2D,this._glTexture,0);break;default:throw"RenderTexture: depth format RenderTexture must use depthFormat with DEPTH_16 and DEPTHSTENCIL_16_8."}o&&l==t.RenderTextureFormat.ShadowMap&&n.texParameteri(i,n.TEXTURE_COMPARE_MODE,n.COMPARE_REF_TO_TEXTURE)}else if(a.bindFramebuffer(a.FRAMEBUFFER,this._frameBuffer),this._depthStencilFormat!==t.RenderTextureDepthFormat.DEPTHSTENCIL_NONE){if(this._depthStencilBuffer=a.createRenderbuffer(),a.bindRenderbuffer(a.RENDERBUFFER,this._depthStencilBuffer),this._mulSamplerRT)switch(this._depthStencilFormat){case t.RenderTextureDepthFormat.DEPTH_16:n.renderbufferStorageMultisample(a.RENDERBUFFER,this._mulSampler,n.DEPTH_COMPONENT16,e,r),n.framebufferRenderbuffer(a.FRAMEBUFFER,n.DEPTH_ATTACHMENT,a.RENDERBUFFER,this._depthStencilBuffer);break;case t.RenderTextureDepthFormat.STENCIL_8:n.renderbufferStorageMultisample(a.RENDERBUFFER,this._mulSampler,n.STENCIL_INDEX8,e,r),n.framebufferRenderbuffer(a.FRAMEBUFFER,n.STENCIL_ATTACHMENT,a.RENDERBUFFER,this._depthStencilBuffer);break;case t.RenderTextureDepthFormat.DEPTHSTENCIL_24_8:n.renderbufferStorageMultisample(a.RENDERBUFFER,this._mulSampler,n.DEPTH_STENCIL,e,r),n.framebufferRenderbuffer(a.FRAMEBUFFER,n.DEPTH_STENCIL_ATTACHMENT,a.RENDERBUFFER,this._depthStencilBuffer);break;default:throw"RenderTexture: unkonw depth format."}else switch(this._depthStencilFormat){case t.RenderTextureDepthFormat.DEPTH_16:a.renderbufferStorage(a.RENDERBUFFER,a.DEPTH_COMPONENT16,e,r),a.framebufferRenderbuffer(a.FRAMEBUFFER,n.DEPTH_ATTACHMENT,a.RENDERBUFFER,this._depthStencilBuffer);break;case t.RenderTextureDepthFormat.STENCIL_8:a.renderbufferStorage(a.RENDERBUFFER,a.STENCIL_INDEX8,e,r),a.framebufferRenderbuffer(a.FRAMEBUFFER,a.STENCIL_ATTACHMENT,a.RENDERBUFFER,this._depthStencilBuffer);break;case t.RenderTextureDepthFormat.DEPTHSTENCIL_24_8:a.renderbufferStorage(a.RENDERBUFFER,a.DEPTH_STENCIL,e,r),a.framebufferRenderbuffer(a.FRAMEBUFFER,a.DEPTH_STENCIL_ATTACHMENT,a.RENDERBUFFER,this._depthStencilBuffer);break;default:throw"RenderTexture: unkonw depth format."}a.bindRenderbuffer(a.RENDERBUFFER,null)}a.bindFramebuffer(a.FRAMEBUFFER,null),this._setWarpMode(a.TEXTURE_WRAP_S,this._wrapModeU),this._setWarpMode(a.TEXTURE_WRAP_T,this._wrapModeV),this._setFilterMode(this._filterMode),this._setAnisotropy(this._anisoLevel),this._readyed=!0,this._activeResource(),this._setGPUMemory(e*r*4)}_start(){var e=t.LayaGL.instance;e.bindFramebuffer(e.FRAMEBUFFER,this._frameBuffer),P._currentActive=this,this._isCameraTarget&&(N._instance.invertY=!0),this._readyed=!1}_end(){var e=t.LayaGL.instance,r=e;this._mulSamplerRT&&(r.bindFramebuffer(r.READ_FRAMEBUFFER,this._frameBuffer),r.bindFramebuffer(r.DRAW_FRAMEBUFFER,this._mulFrameBuffer),r.clearBufferfv(r.COLOR,0,[0,0,0,0]),r.blitFramebuffer(0,0,this.width,this.height,0,0,this._width,this._height,r.COLOR_BUFFER_BIT,e.NEAREST)),e.bindFramebuffer(e.FRAMEBUFFER,null),P._currentActive=null,this._isCameraTarget&&(N._instance.invertY=!1),this._readyed=!0}getData(e,r,a,n,i){if(t.Render.isConchApp&&2==window.conchConfig.threadMode)throw"native 2 thread mode use getDataAsync";var s=t.LayaGL.instance;if(s.bindFramebuffer(s.FRAMEBUFFER,this._frameBuffer),!(s.checkFramebufferStatus(s.FRAMEBUFFER)===s.FRAMEBUFFER_COMPLETE))return s.bindFramebuffer(s.FRAMEBUFFER,null),null;switch(this.format){case t.RenderTextureFormat.R8G8B8:case t.RenderTextureFormat.R8G8B8A8:s.readPixels(e,r,a,n,s.RGBA,s.UNSIGNED_BYTE,i);break;case t.RenderTextureFormat.R16G16B16A16:s.readPixels(e,r,a,n,s.RGBA,s.FLOAT,i)}return s.bindFramebuffer(s.FRAMEBUFFER,null),i}_disposeResource(){if(this._frameBuffer){var e=t.LayaGL.instance;e.deleteTexture(this._glTexture),e.deleteFramebuffer(this._frameBuffer),e.deleteRenderbuffer(this._depthStencilBuffer),this._glTexture=null,this._frameBuffer=null,this._depthStencilBuffer=null,this._setGPUMemory(0)}}getDataAsync(e,r,a,n,i){var s=t.LayaGL.instance;s.bindFramebuffer(s.FRAMEBUFFER,this._frameBuffer),s.readPixelsAsync(e,r,a,n,s.RGBA,s.UNSIGNED_BYTE,(function(e){i(new Uint8Array(e))})),s.bindFramebuffer(s.FRAMEBUFFER,null)}}P._pool=[];class w{constructor(){this._mask=[],this._length=0}_intersectionDefineDatas(e){for(var t=e._mask,r=this._mask,a=this._length-1;a>=0;a--){var n=r[a]&t[a];0==n&&a==this._length-1?this._length--:r[a]=n}}add(e){var t=e._index,r=t+1,a=this._mask,n=this._length;if(na)){var n=r[t]&~e._value;t==a&&0===n?this._length--:r[t]=n}}addDefineDatas(e){var t=e._mask,r=e._length,a=this._mask,n=this._length;if(n=0;n--){var i=r[n]&~t[n];n==a&&0===i?(a--,this._length--):r[n]=i}}has(e){var t=e._index;return!(t>=this._length)&&0!=(this._mask[t]&e._value)}clear(){this._length=0}cloneTo(e){var t=e,r=t._mask,a=this._mask,n=this._length;r.length=n;for(var i=0;i3)throw new Error("row Rows and columns for matrices run from 0 to 3, inclusive.");if(t<0||t>3)throw new Error("column Rows and columns for matrices run from 0 to 3, inclusive.");return this.elements[4*e+t]}setElementByRowColumn(e,t,r){if(e<0||e>3)throw new Error("row Rows and columns for matrices run from 0 to 3, inclusive.");if(t<0||t>3)throw new Error("column Rows and columns for matrices run from 0 to 3, inclusive.");this.elements[4*e+t]=r}equalsOtherMatrix(e){var t=this.elements,a=e.elements;return r.nearEqual(t[0],a[0])&&r.nearEqual(t[1],a[1])&&r.nearEqual(t[2],a[2])&&r.nearEqual(t[3],a[3])&&r.nearEqual(t[4],a[4])&&r.nearEqual(t[5],a[5])&&r.nearEqual(t[6],a[6])&&r.nearEqual(t[7],a[7])&&r.nearEqual(t[8],a[8])&&r.nearEqual(t[9],a[9])&&r.nearEqual(t[10],a[10])&&r.nearEqual(t[11],a[11])&&r.nearEqual(t[12],a[12])&&r.nearEqual(t[13],a[13])&&r.nearEqual(t[14],a[14])&&r.nearEqual(t[15],a[15])}decomposeTransRotScale(e,t,r){var a=B._tempMatrix4x4;return this.decomposeTransRotMatScale(e,a,r)?(T.createFromMatrix4x4(a,t),!0):(t.identity(),!1)}decomposeTransRotMatScale(e,t,a){var n=this.elements,s=e,o=t.elements,l=a;s.x=n[12],s.y=n[13],s.z=n[14];var h=n[0],_=n[1],d=n[2],c=n[4],u=n[5],m=n[6],f=n[8],E=n[9],T=n[10],p=l.x=Math.sqrt(h*h+_*_+d*d),g=l.y=Math.sqrt(c*c+u*u+m*m),S=l.z=Math.sqrt(f*f+E*E+T*T);if(r.isZero(p)||r.isZero(g)||r.isZero(S))return o[1]=o[2]=o[3]=o[4]=o[6]=o[7]=o[8]=o[9]=o[11]=o[12]=o[13]=o[14]=0,o[0]=o[5]=o[10]=o[15]=1,!1;var R=B._tempVector0;R.x=f/S,R.y=E/S,R.z=T/S;var v=B._tempVector1;v.x=h/p,v.y=_/p,v.z=d/p;var x=B._tempVector2;i.cross(R,v,x);var A=B._tempVector1;return i.cross(x,R,A),o[3]=o[7]=o[11]=o[12]=o[13]=o[14]=0,o[15]=1,o[0]=A.x,o[1]=A.y,o[2]=A.z,o[4]=x.x,o[5]=x.y,o[6]=x.z,o[8]=R.x,o[9]=R.y,o[10]=R.z,o[0]*h+o[1]*_+o[2]*d<0&&(l.x=-p),o[4]*c+o[5]*u+o[6]*m<0&&(l.y=-g),o[8]*f+o[9]*E+o[10]*T<0&&(l.z=-S),!0}decomposeYawPitchRoll(e){var t=Math.asin(-this.elements[9]);e.y=t,Math.cos(t)>r.zeroTolerance?(e.z=Math.atan2(this.elements[1],this.elements[5]),e.x=Math.atan2(this.elements[8],this.elements[10])):(e.z=Math.atan2(-this.elements[4],this.elements[0]),e.x=0)}normalize(){var e=this.elements,t=e[0],r=e[1],a=e[2],n=Math.sqrt(t*t+r*r+a*a);if(!n)return e[0]=0,e[1]=0,void(e[2]=0);1!=n&&(n=1/n,e[0]=t*n,e[1]=r*n,e[2]=a*n)}transpose(){var e,t;return t=(e=this.elements)[1],e[1]=e[4],e[4]=t,t=e[2],e[2]=e[8],e[8]=t,t=e[3],e[3]=e[12],e[12]=t,t=e[6],e[6]=e[9],e[9]=t,t=e[7],e[7]=e[13],e[13]=t,t=e[11],e[11]=e[14],e[14]=t,this}invert(e){var t=this.elements,r=e.elements,a=t[0],n=t[1],i=t[2],s=t[3],o=t[4],l=t[5],h=t[6],_=t[7],d=t[8],c=t[9],u=t[10],m=t[11],f=t[12],E=t[13],T=t[14],p=t[15],g=a*l-n*o,S=a*h-i*o,R=a*_-s*o,v=n*h-i*l,x=n*_-s*l,A=i*_-s*h,I=d*E-c*f,M=d*T-u*f,D=d*p-m*f,L=c*T-u*E,y=c*p-m*E,C=u*p-m*T,O=g*C-S*y+R*L+v*D-x*M+A*I;0!==Math.abs(O)&&(O=1/O,r[0]=(l*C-h*y+_*L)*O,r[1]=(i*y-n*C-s*L)*O,r[2]=(E*A-T*x+p*v)*O,r[3]=(u*x-c*A-m*v)*O,r[4]=(h*D-o*C-_*M)*O,r[5]=(a*C-i*D+s*M)*O,r[6]=(T*R-f*A-p*S)*O,r[7]=(d*A-u*R+m*S)*O,r[8]=(o*y-l*D+_*I)*O,r[9]=(n*D-a*y-s*I)*O,r[10]=(f*x-E*R+p*g)*O,r[11]=(c*R-d*x-m*g)*O,r[12]=(l*M-o*L-h*I)*O,r[13]=(a*L-n*M+i*I)*O,r[14]=(E*S-f*v-T*g)*O,r[15]=(d*v-c*S+u*g)*O)}static billboard(e,t,a,n,s){i.subtract(e,t,B._tempVector0);var o=i.scalarLengthSquared(B._tempVector0);r.isZero(o)?(i.scale(n,-1,B._tempVector1),B._tempVector1.cloneTo(B._tempVector0)):i.scale(B._tempVector0,1/Math.sqrt(o),B._tempVector0),i.cross(a,B._tempVector0,B._tempVector2),i.normalize(B._tempVector2,B._tempVector2),i.cross(B._tempVector0,B._tempVector2,B._tempVector3);var l=B._tempVector2,h=B._tempVector3,_=B._tempVector0,d=e,c=s.elements;c[0]=l.x,c[1]=l.y,c[2]=l.z,c[3]=0,c[4]=h.x,c[5]=h.y,c[6]=h.z,c[7]=0,c[8]=_.x,c[9]=_.y,c[10]=_.z,c[11]=0,c[12]=d.x,c[13]=d.y,c[14]=d.z,c[15]=1}identity(){var e=this.elements;e[1]=e[2]=e[3]=e[4]=e[6]=e[7]=e[8]=e[9]=e[11]=e[12]=e[13]=e[14]=0,e[0]=e[5]=e[10]=e[15]=1}cloneTo(e){var t,r,a;if((r=this.elements)!==(a=e.elements))for(t=0;t<16;++t)a[t]=r[t]}clone(){var e=new B;return this.cloneTo(e),e}static translation(e,t){var r=t.elements;r[0]=r[5]=r[10]=r[15]=1,r[12]=e.x,r[13]=e.y,r[14]=e.z}getTranslationVector(e){var t=this.elements;e.x=t[12],e.y=t[13],e.z=t[14]}setTranslationVector(e){var t=this.elements,r=e;t[12]=r.x,t[13]=r.y,t[14]=r.z}getForward(e){var t=this.elements;e.x=-t[8],e.y=-t[9],e.z=-t[10]}setForward(e){var t=this.elements;t[8]=-e.x,t[9]=-e.y,t[10]=-e.z}getInvertFront(){this.decomposeTransRotScale(B._tempVector0,B._tempQuaternion,B._tempVector1);var e=B._tempVector1,t=e.x<0;return e.y<0&&(t=!t),e.z<0&&(t=!t),t}}B._tempMatrix4x4=new B,B.TEMPMatrix0=new B,B.TEMPMatrix1=new B,B._tempVector0=new i,B._tempVector1=new i,B._tempVector2=new i,B._tempVector3=new i,B._tempQuaternion=new T,B.DEFAULT=new B,B.ZERO=new B(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);class F{constructor(e=null){this._ownerResource=null,this._data=null,this._defineDatas=new w,this._runtimeCopyValues=[],this._ownerResource=e,this._initData()}_initData(){this._data={}}getData(){return this._data}addDefine(e){this._defineDatas.add(e)}removeDefine(e){this._defineDatas.remove(e)}hasDefine(e){return this._defineDatas.has(e)}clearDefine(){this._defineDatas.clear()}getBool(e){return this._data[e]}setBool(e,t){this._data[e]=t}getInt(e){return this._data[e]}setInt(e,t){this._data[e]=t}getNumber(e){return this._data[e]}setNumber(e,t){this._data[e]=t}getVector2(e){return this._data[e]}setVector2(e,t){this._data[e]=t}getVector3(e){return this._data[e]}setVector3(e,t){this._data[e]=t}getVector(e){return this._data[e]}setVector(e,t){this._data[e]=t}getQuaternion(e){return this._data[e]}setQuaternion(e,t){this._data[e]=t}getMatrix4x4(e){return this._data[e]}setMatrix4x4(e,t){this._data[e]=t}getBuffer(e){return this._data[e]}setBuffer(e,t){this._data[e]=t}setTexture(e,r){var a=this._data[e];this._data[e]=r||t.Texture2D.erroTextur,this._ownerResource&&this._ownerResource.referenceCount>0&&(a&&a._removeReference(),r&&r._addReference())}getTexture(e){return this._data[e]}setValueData(e,t){this._data[e]=t}getValueData(e){return this._data[e]}setAttribute(e,t){this._data[e]=t}getAttribute(e){return this._data[e]}getLength(){return this._data.length}setLength(e){this._data.length=e}cloneTo(e){var r=e,s=r._data;for(var o in this._data){var l=this._data[o];if(null!=l)if("number"==typeof l)s[o]=l;else if("number"==typeof l)s[o]=l;else if("boolean"==typeof l)s[o]=l;else if(l instanceof a){var h=s[o]||(s[o]=new a);l.cloneTo(h),s[o]=h}else if(l instanceof i){var _=s[o]||(s[o]=new i);l.cloneTo(_),s[o]=_}else if(l instanceof n){var d=s[o]||(s[o]=new n);l.cloneTo(d),s[o]=d}else if(l instanceof B){var c=s[o]||(s[o]=new B);l.cloneTo(c),s[o]=c}else l instanceof t.BaseTexture&&(s[o]=l)}this._defineDatas.cloneTo(r._defineDatas)}clone(){var e=new F;return this.cloneTo(e),e}cloneToForNative(e){var r=e;this._int32Data.length-r._int32Data.length>0&&r.needRenewArrayBufferForNative(this._int32Data.length),r._int32Data.set(this._int32Data,0);var s=r._nativeArray,o=this._nativeArray.length;s.length=o;for(var l=0;l=this._int32Data.length){var r=4*(e+1),a=this._int32Data,n=this._data.conchRef,i=this._data._ptrID;this._data=new ArrayBuffer(r),this._int32Data=new Int32Array(this._data),this._float32Data=new Float32Array(this._data),this._data.conchRef=n,this._data._ptrID=i,a&&this._int32Data.set(a,0);var s=t.LayaGL.instance;s.updateArrayBufferRef?s.updateArrayBufferRef(this._data._ptrID,n.isSyncToRender(),this._data):window.conch.updateArrayBufferRef(this._data._ptrID,n.isSyncToRender(),this._data)}}getDataForNative(){return this._nativeArray}getIntForNative(e){return this._int32Data[e]}setIntForNative(e,t){this.needRenewArrayBufferForNative(e),this._int32Data[e]=t,this._nativeArray[e]=t}getBoolForNative(e){return 1==this._int32Data[e]}setBoolForNative(e,t){this.needRenewArrayBufferForNative(e),this._int32Data[e]=t?1:0,this._nativeArray[e]=t}getNumberForNative(e){return this._float32Data[e]}setNumberForNative(e,t){this.needRenewArrayBufferForNative(e),this._float32Data[e]=t,this._nativeArray[e]=t}getMatrix4x4ForNative(e){return this._nativeArray[e]}setMatrix4x4ForNative(e,t){this.needRenewArrayBufferForNative(e),this._nativeArray[e]=t;var r=this.setReferenceForNative(t.elements);this._int32Data[e]=r}getVectorForNative(e){return this._nativeArray[e]}setVectorForNative(e,t){this.needRenewArrayBufferForNative(e),this._nativeArray[e]=t,t.elements||t.forNativeElement();var r=this.setReferenceForNative(t.elements);this._int32Data[e]=r}getVector2ForNative(e){return this._nativeArray[e]}setVector2ForNative(e,t){this.needRenewArrayBufferForNative(e),this._nativeArray[e]=t,t.elements||t.forNativeElement();var r=this.setReferenceForNative(t.elements);this._int32Data[e]=r}getVector3ForNative(e){return this._nativeArray[e]}setVector3ForNative(e,t){this.needRenewArrayBufferForNative(e),this._nativeArray[e]=t,t.elements||t.forNativeElement();var r=this.setReferenceForNative(t.elements);this._int32Data[e]=r}getQuaternionForNative(e){return this._nativeArray[e]}setQuaternionForNative(e,t){this.needRenewArrayBufferForNative(e),this._nativeArray[e]=t,t.elements||t.forNativeElement();var r=this.setReferenceForNative(t.elements);this._int32Data[e]=r}getBufferForNative(e){return this._nativeArray[e]}setBufferForNative(e,t){this.needRenewArrayBufferForNative(e),this._nativeArray[e]=t;var r=this.setReferenceForNative(t);this._int32Data[e]=r}getAttributeForNative(e){return this._nativeArray[e]}setAttributeForNative(e,r){this._nativeArray[e]=r,r._ptrID||t.LayaGL.instance.createArrayBufferRef(r,t.LayaGL.ARRAY_BUFFER_TYPE_DATA,!0),t.LayaGL.instance.syncBufferToRenderThread(r),this._int32Data[e]=r._ptrID}getTextureForNative(e){return this._nativeArray[e]}setTextureForNative(e,t){if(t){this.needRenewArrayBufferForNative(e);var r=this._nativeArray[e];this._nativeArray[e]=t;var a=t._getSource()||t.defaulteTexture._getSource();this._int32Data[e]=a.id,this._ownerResource&&this._ownerResource.referenceCount>0&&(r&&r._removeReference(),t&&t._addReference())}}setReferenceForNative(e){this.clearRuntimeCopyArray();var r=0,a=0;return F._SET_RUNTIME_VALUE_MODE_REFERENCE_?(t.LayaGL.instance.createArrayBufferRefs(e,t.LayaGL.ARRAY_BUFFER_TYPE_DATA,!0,t.LayaGL.ARRAY_BUFFER_REF_REFERENCE),r=0,a=e.getPtrID(r)):(t.LayaGL.instance.createArrayBufferRefs(e,t.LayaGL.ARRAY_BUFFER_TYPE_DATA,!0,t.LayaGL.ARRAY_BUFFER_REF_COPY),r=e.getRefNum()-1,a=e.getPtrID(r),this._runtimeCopyValues.push({obj:e,refID:r,ptrID:a})),t.LayaGL.instance.syncBufferToRenderThread(e,r),a}static setRuntimeValueMode(e){F._SET_RUNTIME_VALUE_MODE_REFERENCE_=e}clearRuntimeCopyArray(){var e=t.Stat.loopCount;if(this._frameCount!=e){this._frameCount=e;for(var r=0,a=this._runtimeCopyValues.length;r0&&h>o)break;o&h&&t.push(s[h])}}static getDefineByName(e){var t=Z._defineMap[e];if(!t){var r=Z._maskMap,a=Z._defineCounter,n=Math.floor(a/32),i=1<0?j._pool.pop():new j)._source=e,h._dest=t,h._offsetScale=r,h._shader=a,h._shaderData=n,h._subShader=i,h._screenType=s,h._commandBuffer=o,h._drawDefineCavans=l,h}run(){var e;if(this._source)e=this._source;else{if(!this._commandBuffer._camera._internalRenderTexture)throw"camera internalRenderTexture is null,please set camera enableBuiltInRenderTexture";e=this._commandBuffer._camera._internalRenderTexture}var r=this._shader||q._screenShader,a=this._shaderData||q._screenShaderData,n=this._dest||this._drawDefineCavans?this._dest:this._commandBuffer._camera._internalRenderTexture;if(n)t.LayaGL.instance.viewport(0,0,n.width,n.height);else{let e=this._commandBuffer._camera.viewport,r=e.height,a=N.clientHeight-e.y-r;t.LayaGL.instance.viewport(e.x,a,e.width,r)}a.setTexture(q.SCREENTEXTURE_ID,e),a.setVector(q.SCREENTEXTUREOFFSETSCALE_ID,this._offsetScale||j._defaultOffsetScale),this._sourceTexelSize.setValue(1/e.width,1/e.height,e.width,e.height),a.setVector(q.MAINTEXTURE_TEXELSIZE_ID,this._sourceTexelSize),P.currentActive&&P.currentActive._end(),n&&n._start();for(var i=r.getSubShaderAt(this._subShader)._passes,s=0,o=i.length;s0?Q._pool.pop():new Q)._renderTexture=e,t}run(){P.currentActive&&P.currentActive._end(),t.LayaGL.instance.viewport(0,0,this._renderTexture.width,this._renderTexture.height),this._renderTexture._start()}recover(){Q._pool.push(this),this._renderTexture=null}}Q._pool=[],(o=e.ShaderDataType||(e.ShaderDataType={}))[o.Int=0]="Int",o[o.Bool=1]="Bool",o[o.Number=2]="Number",o[o.Vector2=3]="Vector2",o[o.Vector3=4]="Vector3",o[o.Vector4=5]="Vector4",o[o.Quaternion=6]="Quaternion",o[o.Matrix4x4=7]="Matrix4x4",o[o.Buffer=8]="Buffer",o[o.Texture=9]="Texture";class K extends q{constructor(){super(...arguments),this._shaderData=null,this._nameID=0,this._value=null,this._dataType=-1}static create(e,t,r,a,n){var i;return(i=K._pool.length>0?K._pool.pop():new K)._shaderData=e,i._nameID=t,i._value=r,i._dataType=a,i._commandBuffer=n,i}run(){switch(this._dataType){case e.ShaderDataType.Int:this._shaderData.setInt(this._nameID,this._value);break;case e.ShaderDataType.Number:this._shaderData.setNumber(this._nameID,this._value);break;case e.ShaderDataType.Bool:this._shaderData.setBool(this._nameID,this._value);break;case e.ShaderDataType.Matrix4x4:this._shaderData.setMatrix4x4(this._nameID,this._value);break;case e.ShaderDataType.Quaternion:this._shaderData.setQuaternion(this._nameID,this._value);break;case e.ShaderDataType.Texture:this._shaderData.setTexture(this._nameID,this._value);break;case e.ShaderDataType.Vector4:this._shaderData.setVector(this._nameID,this._value);break;case e.ShaderDataType.Vector2:this._shaderData.setVector2(this._nameID,this._value);break;case e.ShaderDataType.Vector3:this._shaderData.setVector3(this._nameID,this._value);break;case e.ShaderDataType.Buffer:this._shaderData.setBuffer(this._nameID,this._value);break;default:throw"no type shaderValue on this CommendBuffer"}}recover(){K._pool.push(this),this._shaderData=null,this._nameID=0,this._value=null,this._dataType=-1}}K._pool=[];class J extends t.EventDispatcher{constructor(e){super(),this._localPosition=new i(0,0,0),this._localRotation=new T(0,0,0,1),this._localScale=new i(1,1,1),this._localRotationEuler=new i(0,0,0),this._localMatrix=new B,this._position=new i(0,0,0),this._rotation=new T(0,0,0,1),this._scale=new i(1,1,1),this._rotationEuler=new i(0,0,0),this._worldMatrix=new B,this._children=null,this._parent=null,this._dummy=null,this._transformFlag=0,this._owner=e,this._children=[],this._setTransformFlag(J.TRANSFORM_LOCALQUATERNION|J.TRANSFORM_LOCALEULER|J.TRANSFORM_LOCALMATRIX,!1),this._setTransformFlag(J.TRANSFORM_WORLDPOSITION|J.TRANSFORM_WORLDQUATERNION|J.TRANSFORM_WORLDEULER|J.TRANSFORM_WORLDSCALE|J.TRANSFORM_WORLDMATRIX,!0)}get _isFrontFaceInvert(){var e=this.getWorldLossyScale(),t=e.x<0;return e.y<0&&(t=!t),e.z<0&&(t=!t),t}get owner(){return this._owner}get worldNeedUpdate(){return this._getTransformFlag(J.TRANSFORM_WORLDMATRIX)}get localPositionX(){return this._localPosition.x}set localPositionX(e){this._localPosition.x=e,this.localPosition=this._localPosition}get localPositionY(){return this._localPosition.y}set localPositionY(e){this._localPosition.y=e,this.localPosition=this._localPosition}get localPositionZ(){return this._localPosition.z}set localPositionZ(e){this._localPosition.z=e,this.localPosition=this._localPosition}get localPosition(){return this._localPosition}set localPosition(e){this._localPosition!==e&&e.cloneTo(this._localPosition),this._setTransformFlag(J.TRANSFORM_LOCALMATRIX,!0),this._onWorldPositionTransform()}get localRotationX(){return this.localRotation.x}set localRotationX(e){this._localRotation.x=e,this.localRotation=this._localRotation}get localRotationY(){return this.localRotation.y}set localRotationY(e){this._localRotation.y=e,this.localRotation=this._localRotation}get localRotationZ(){return this.localRotation.z}set localRotationZ(e){this._localRotation.z=e,this.localRotation=this._localRotation}get localRotationW(){return this.localRotation.w}set localRotationW(e){this._localRotation.w=e,this.localRotation=this._localRotation}get localRotation(){if(this._getTransformFlag(J.TRANSFORM_LOCALQUATERNION)){var e=this._localRotationEuler;T.createFromYawPitchRoll(e.y/J._angleToRandin,e.x/J._angleToRandin,e.z/J._angleToRandin,this._localRotation),this._setTransformFlag(J.TRANSFORM_LOCALQUATERNION,!1)}return this._localRotation}set localRotation(e){this._localRotation!==e&&e.cloneTo(this._localRotation),this._localRotation.normalize(this._localRotation),this._setTransformFlag(J.TRANSFORM_LOCALEULER|J.TRANSFORM_LOCALMATRIX,!0),this._setTransformFlag(J.TRANSFORM_LOCALQUATERNION,!1),this._onWorldRotationTransform()}get localScaleX(){return this._localScale.x}set localScaleX(e){this._localScale.x=e,this.localScale=this._localScale}get localScaleY(){return this._localScale.y}set localScaleY(e){this._localScale.y=e,this.localScale=this._localScale}get localScaleZ(){return this._localScale.z}set localScaleZ(e){this._localScale.z=e,this.localScale=this._localScale}get localScale(){return this._localScale}set localScale(e){this._localScale!==e&&e.cloneTo(this._localScale),this._setTransformFlag(J.TRANSFORM_LOCALMATRIX,!0),this._onWorldScaleTransform()}get localRotationEulerX(){return this.localRotationEuler.x}set localRotationEulerX(e){this._localRotationEuler.x=e,this.localRotationEuler=this._localRotationEuler}get localRotationEulerY(){return this.localRotationEuler.y}set localRotationEulerY(e){this._localRotationEuler.y=e,this.localRotationEuler=this._localRotationEuler}get localRotationEulerZ(){return this.localRotationEuler.z}set localRotationEulerZ(e){this._localRotationEuler.z=e,this.localRotationEuler=this._localRotationEuler}get localRotationEuler(){if(this._getTransformFlag(J.TRANSFORM_LOCALEULER)){this._localRotation.getYawPitchRoll(J._tempVector30);var e=J._tempVector30,t=this._localRotationEuler;t.x=e.y*J._angleToRandin,t.y=e.x*J._angleToRandin,t.z=e.z*J._angleToRandin,this._setTransformFlag(J.TRANSFORM_LOCALEULER,!1)}return this._localRotationEuler}set localRotationEuler(e){this._localRotationEuler!==e&&e.cloneTo(this._localRotationEuler),this._setTransformFlag(J.TRANSFORM_LOCALEULER,!1),this._setTransformFlag(J.TRANSFORM_LOCALQUATERNION|J.TRANSFORM_LOCALMATRIX,!0),this._onWorldRotationTransform()}get localMatrix(){return this._getTransformFlag(J.TRANSFORM_LOCALMATRIX)&&(B.createAffineTransformation(this._localPosition,this.localRotation,this._localScale,this._localMatrix),this._setTransformFlag(J.TRANSFORM_LOCALMATRIX,!1)),this._localMatrix}set localMatrix(e){this._localMatrix!==e&&e.cloneTo(this._localMatrix),this._localMatrix.decomposeTransRotScale(this._localPosition,this._localRotation,this._localScale),this._setTransformFlag(J.TRANSFORM_LOCALEULER,!0),this._setTransformFlag(J.TRANSFORM_LOCALMATRIX,!1),this._onWorldTransform()}get position(){if(this._getTransformFlag(J.TRANSFORM_WORLDPOSITION)){if(null!=this._parent){var e=this.worldMatrix.elements;this._position.x=e[12],this._position.y=e[13],this._position.z=e[14]}else this._localPosition.cloneTo(this._position);this._setTransformFlag(J.TRANSFORM_WORLDPOSITION,!1)}return this._position}set position(e){if(null!=this._parent){var t=J._tempMatrix0;this._parent.worldMatrix.invert(t),i.transformCoordinate(e,t,this._localPosition)}else e.cloneTo(this._localPosition);this.localPosition=this._localPosition,this._position!==e&&e.cloneTo(this._position),this._setTransformFlag(J.TRANSFORM_WORLDPOSITION,!1)}get rotation(){return this._getTransformFlag(J.TRANSFORM_WORLDQUATERNION)&&(null!=this._parent?T.multiply(this._parent.rotation,this.localRotation,this._rotation):this.localRotation.cloneTo(this._rotation),this._setTransformFlag(J.TRANSFORM_WORLDQUATERNION,!1)),this._rotation}set rotation(e){null!=this._parent?(this._parent.rotation.invert(J._tempQuaternion0),T.multiply(J._tempQuaternion0,e,this._localRotation)):e.cloneTo(this._localRotation),this.localRotation=this._localRotation,e!==this._rotation&&e.cloneTo(this._rotation),this._setTransformFlag(J.TRANSFORM_WORLDQUATERNION,!1)}get rotationEuler(){if(this._getTransformFlag(J.TRANSFORM_WORLDEULER)){this.rotation.getYawPitchRoll(J._tempVector30);var e=J._tempVector30,t=this._rotationEuler;t.x=e.y*J._angleToRandin,t.y=e.x*J._angleToRandin,t.z=e.z*J._angleToRandin,this._setTransformFlag(J.TRANSFORM_WORLDEULER,!1)}return this._rotationEuler}set rotationEuler(e){T.createFromYawPitchRoll(e.y/J._angleToRandin,e.x/J._angleToRandin,e.z/J._angleToRandin,this._rotation),this.rotation=this._rotation,this._rotationEuler!==e&&e.cloneTo(this._rotationEuler),this._setTransformFlag(J.TRANSFORM_WORLDEULER,!1)}get worldMatrix(){return this._getTransformFlag(J.TRANSFORM_WORLDMATRIX)&&(null!=this._parent?B.multiply(this._parent.worldMatrix,this.localMatrix,this._worldMatrix):this.localMatrix.cloneTo(this._worldMatrix),this._setTransformFlag(J.TRANSFORM_WORLDMATRIX,!1)),this._worldMatrix}set worldMatrix(e){null===this._parent?e.cloneTo(this._localMatrix):(this._parent.worldMatrix.invert(this._localMatrix),B.multiply(this._localMatrix,e,this._localMatrix)),this.localMatrix=this._localMatrix,this._worldMatrix!==e&&e.cloneTo(this._worldMatrix),this._setTransformFlag(J.TRANSFORM_WORLDMATRIX,!1)}_getScaleMatrix(){var e=J._tempQuaternion0,t=J._tempMatrix3x30,r=J._tempMatrix3x31,a=J._tempMatrix3x32;return E.createFromMatrix4x4(this.worldMatrix,r),this.rotation.invert(e),E.createRotationQuaternion(e,t),E.multiply(t,r,a),a}_setTransformFlag(e,t){t?this._transformFlag|=e:this._transformFlag&=~e}_getTransformFlag(e){return 0!=(this._transformFlag&e)}_setParent(e){if(this._parent!==e){if(this._parent){var t=this._parent._children,r=t.indexOf(this);t.splice(r,1)}e&&(e._children.push(this),e&&this._onWorldTransform()),this._parent=e}}_onWorldPositionRotationTransform(){this._getTransformFlag(J.TRANSFORM_WORLDMATRIX)&&this._getTransformFlag(J.TRANSFORM_WORLDPOSITION)&&this._getTransformFlag(J.TRANSFORM_WORLDQUATERNION)&&this._getTransformFlag(J.TRANSFORM_WORLDEULER)||(this._setTransformFlag(J.TRANSFORM_WORLDMATRIX|J.TRANSFORM_WORLDPOSITION|J.TRANSFORM_WORLDQUATERNION|J.TRANSFORM_WORLDEULER,!0),this.event(t.Event.TRANSFORM_CHANGED,this._transformFlag));for(var e=0,r=this._children.length;e=0&&e<=30))throw new Error("Layer value must be 0-30.");this._layer=e}}get url(){return this._url}get isStatic(){return this._isStatic}get transform(){return this._transform}_setCreateURL(e){this._url=t.URL.formatURL(e)}_changeAnimatorsToLinkSprite3D(e,t,r){var a=this.getComponent(O);if(a&&(a.avatar||e._changeAnimatorToLinkSprite3DNoAvatar(a,t,r)),this._parent&&this._parent instanceof $){r.unshift(this._parent.name);var n=this._parent;n._hierarchyAnimator&&n._changeAnimatorsToLinkSprite3D(e,t,r)}}_setHierarchyAnimator(e,t){this._changeHierarchyAnimator(e),this._changeAnimatorAvatar(e.avatar);for(var r=0,a=this._children.length;r0?ee._pool.pop():new ee)._mesh=e,s._matrix=t,s._material=r,s._subMeshIndex=a,s._subShaderIndex=n,s._commandBuffer=i,s}run(){var e=this._material._shader.getSubShaderAt(this._subShaderIndex);this.setContext(this._commandBuffer._context);var t=this._context,r=t.invertY,a=t.scene,n=t.cameraShaderValue,i=t.projectionViewMatrix;B.multiply(i,this._matrix,this._projectionViewWorldMatrix),this._renderShaderValue.setMatrix4x4($.WORLDMATRIX,this._matrix),this._renderShaderValue.setMatrix4x4($.MVPMATRIX,this._projectionViewWorldMatrix);for(var s=t.pipelineMode,o=e._passes,l=0,h=o.length;l0?te._pool.pop():new te)._clearColor=e,i._clearDepth=t,r.cloneTo(i._backgroundColor),i._depth=a,i._commandBuffer=n,i}run(){var e,r=t.LayaGL.instance,a=this._backgroundColor;this._clearColor&&(r.clearColor(a.x,a.y,a.z,a.w),e|=r.COLOR_BUFFER_BIT),this._clearDepth&&(r.clearDepth(this._depth),e|=r.DEPTH_BUFFER_BIT),(this._clearColor||this._clearDepth)&&r.clear(e)}recover(){}}te._pool=[];class re extends q{static create(e,t,r,a){var n;return(n=re._pool.length>0?re._pool.pop():new re)._render=e,n._material=t,n._subShaderIndex=r,n._commandBuffer=a,n}_elementRender(e,t){var r,a,n,i=t.invertY,s=h.Camera._updateMark,o=t.scene;this._render._scene=t.scene;var l=t.cameraShaderValue,_=e._transform,d=e._geometry;t.renderElement=e,s!==e.render._updateMark||e.renderType!==e.render._updateRenderType?(e.render._renderUpdate(t,_),e.render._renderUpdateWithCamera(t,_),e.render._updateMark=s,e.render._updateRenderType=e.renderType):e.renderType==h.RenderElement.RENDERTYPE_INSTANCEBATCH&&(e.render._renderUpdate(t,_),e.render._renderUpdateWithCamera(t,_));var c=t.pipelineMode;if(d._prepareRender(t))for(var u=e.renderSubShader._passes,m=0,f=u.length;m0?ae._pool.pop():new ae)._nameID=e,n._value=t,n._dataType=r,n._commandBuffer=a,n}run(){var t=this._commandBuffer._camera.scene._shaderValues;switch(this._dataType){case e.ShaderDataType.Int:t.setInt(this._nameID,this._value);break;case e.ShaderDataType.Number:t.setNumber(this._nameID,this._value);break;case e.ShaderDataType.Bool:t.setBool(this._nameID,this._value);break;case e.ShaderDataType.Matrix4x4:t.setMatrix4x4(this._nameID,this._value);break;case e.ShaderDataType.Quaternion:t.setQuaternion(this._nameID,this._value);break;case e.ShaderDataType.Texture:t.setTexture(this._nameID,this._value);break;case e.ShaderDataType.Vector4:t.setVector(this._nameID,this._value);break;case e.ShaderDataType.Vector2:t.setVector2(this._nameID,this._value);break;case e.ShaderDataType.Vector3:t.setVector3(this._nameID,this._value);break;case e.ShaderDataType.Buffer:t.setBuffer(this._nameID,this._value);break;default:throw"no type shaderValue on this CommendBuffer"}}recover(){ae._pool.push(this),this._nameID=0,this._value=null,this._dataType=-1}}ae._pool=[];class ne{}class ie{static __init__(){ie.instanceWorldMatrixDeclaration=new U(64,[new H(0,V.Vector4,ie.MESH_WORLDMATRIX_ROW0),new H(16,V.Vector4,ie.MESH_WORLDMATRIX_ROW1),new H(32,V.Vector4,ie.MESH_WORLDMATRIX_ROW2),new H(48,V.Vector4,ie.MESH_WORLDMATRIX_ROW3)]),ie.instanceSimpleAnimatorDeclaration=new U(16,[new H(0,V.Vector4,ie.MESH_SIMPLEANIMATOR)])}static getVertexDeclaration(e,t=!0){var r=ie._vertexDeclarationMap[e+(t?"_0":"_1")];if(!r){for(var a=e.split(","),n=0,i=[],s=0,o=a.length;s1024||s>se.maxInstanceCount)throw"the number of renderings exceeds the maximum number of merges";return(l=se._pool.length>0?se._pool.pop():new se)._mesh=e,l._matrixs=r,l._material=a,l._subMeshIndex=t,l._subShaderIndex=n,l._commandBuffer=o,l._instanceProperty=i,l._drawnums=s,r||l._updateWorldMatrixBuffer(),l._setInstanceBuffer(),l}_setInstanceBuffer(){let e=this._instanceBufferState=new G;e.bind(),e.applyVertexBuffer(this._mesh._vertexBuffer),e.applyInstanceVertexBuffer(this._instanceWorldMatrixBuffer);let t=this._instanceProperty._propertyMap;for(let r in t)e.applyInstanceVertexBuffer(t[r]._vertexBuffer);e.applyIndexBuffer(this._mesh._indexBuffer),e.unBind()}_updateWorldMatrixBuffer(){let e=this._instanceWorldMatrixData,t=this._drawnums;for(let r=0;r0&&this._removeTetxureReference(),this._shaderValues=null}_addReference(e=1){super._addReference(e);var r=this._shaderValues.getData();for(var a in r){var n=r[a];n&&n instanceof t.BaseTexture&&n._addReference()}}_removeReference(e=1){super._removeReference(e),this._removeTetxureReference()}setShaderName(e){if(this._shader=Z.find(e),!this._shader)throw new Error("BaseMaterial: unknown shader name.")}setShaderPropertyValue(e,t){this.shaderData.setValueData(Z.propertyNameToID(e),t)}getShaderPropertyValue(e){return this.shaderData.getValueData(Z.propertyNameToID(e))}cloneTo(e){var t=e;t.name=this.name,t.renderQueue=this.renderQueue,this._shaderValues.cloneTo(t._shaderValues)}clone(){var e=new ue;return this.cloneTo(e),e}get _defineDatas(){return this._shaderValues._defineDatas}}ue.MATERIAL="MATERIAL",ue.RENDERQUEUE_OPAQUE=2e3,ue.RENDERQUEUE_ALPHATEST=2450,ue.RENDERQUEUE_TRANSPARENT=3e3,ue.ALPHATESTVALUE=Z.propertyNameToID("u_AlphaTestValue"),ue.CULL=Z.propertyNameToID("s_Cull"),ue.BLEND=Z.propertyNameToID("s_Blend"),ue.BLEND_SRC=Z.propertyNameToID("s_BlendSrc"),ue.BLEND_DST=Z.propertyNameToID("s_BlendDst"),ue.DEPTH_TEST=Z.propertyNameToID("s_DepthTest"),ue.DEPTH_WRITE=Z.propertyNameToID("s_DepthWrite");class me{static load(e,r){t.Laya.loader.create(e,r,null,ue.MATERIAL)}static __initDefine__(){me.SHADERDEFINE_ALPHATEST=ue.SHADERDEFINE_ALPHATEST}}me.MATERIAL="MATERIAL",me.RENDERQUEUE_OPAQUE=2e3,me.RENDERQUEUE_ALPHATEST=2450,me.RENDERQUEUE_TRANSPARENT=3e3,me.ALPHATESTVALUE=Z.propertyNameToID("u_AlphaTestValue");class fe{constructor(){this.cull=fe.CULL_BACK,this.blend=fe.BLEND_DISABLE,this.srcBlend=fe.BLENDPARAM_ONE,this.dstBlend=fe.BLENDPARAM_ZERO,this.srcBlendRGB=fe.BLENDPARAM_ONE,this.dstBlendRGB=fe.BLENDPARAM_ZERO,this.srcBlendAlpha=fe.BLENDPARAM_ONE,this.dstBlendAlpha=fe.BLENDPARAM_ZERO,this.blendConstColor=new n(1,1,1,1),this.blendEquation=fe.BLENDEQUATION_ADD,this.blendEquationRGB=fe.BLENDEQUATION_ADD,this.blendEquationAlpha=fe.BLENDEQUATION_ADD,this.depthTest=fe.DEPTHTEST_LEQUAL,this.depthWrite=!0}cloneTo(e){var t=e;t.cull=this.cull,t.blend=this.blend,t.srcBlend=this.srcBlend,t.dstBlend=this.dstBlend,t.srcBlendRGB=this.srcBlendRGB,t.dstBlendRGB=this.dstBlendRGB,t.srcBlendAlpha=this.srcBlendAlpha,t.dstBlendAlpha=this.dstBlendAlpha,this.blendConstColor.cloneTo(t.blendConstColor),t.blendEquation=this.blendEquation,t.blendEquationRGB=this.blendEquationRGB,t.blendEquationAlpha=this.blendEquationAlpha,t.depthTest=this.depthTest,t.depthWrite=this.depthWrite}clone(){var e=new fe;return this.cloneTo(e),e}}fe.CULL_NONE=0,fe.CULL_FRONT=1,fe.CULL_BACK=2,fe.BLEND_DISABLE=0,fe.BLEND_ENABLE_ALL=1,fe.BLEND_ENABLE_SEPERATE=2,fe.BLENDPARAM_ZERO=0,fe.BLENDPARAM_ONE=1,fe.BLENDPARAM_SRC_COLOR=768,fe.BLENDPARAM_ONE_MINUS_SRC_COLOR=769,fe.BLENDPARAM_DST_COLOR=774,fe.BLENDPARAM_ONE_MINUS_DST_COLOR=775,fe.BLENDPARAM_SRC_ALPHA=770,fe.BLENDPARAM_ONE_MINUS_SRC_ALPHA=771,fe.BLENDPARAM_DST_ALPHA=772,fe.BLENDPARAM_ONE_MINUS_DST_ALPHA=773,fe.BLENDPARAM_SRC_ALPHA_SATURATE=776,fe.BLENDEQUATION_ADD=32774,fe.BLENDEQUATION_SUBTRACT=32778,fe.BLENDEQUATION_REVERSE_SUBTRACT=32779,fe.DEPTHTEST_OFF=0,fe.DEPTHTEST_NEVER=512,fe.DEPTHTEST_LESS=513,fe.DEPTHTEST_EQUAL=514,fe.DEPTHTEST_LEQUAL=515,fe.DEPTHTEST_GREATER=516,fe.DEPTHTEST_NOTEQUAL=517,fe.DEPTHTEST_GEQUAL=518,fe.DEPTHTEST_ALWAYS=519;class Ee extends ue{constructor(){super(),this.setShaderName("BLINNPHONG"),this.albedoIntensity=1;var e=this._shaderValues;e.setVector(Ee.ALBEDOCOLOR,new n(1,1,1,1)),e.setVector(Ee.MATERIALSPECULAR,new n(1,1,1,1)),e.setNumber(Ee.SHININESS,.078125),e.setNumber(ue.ALPHATESTVALUE,.5),e.setVector(Ee.TILINGOFFSET,new n(1,1,0,0)),this.albedoIntensity=1,this.renderMode=Ee.RENDERMODE_OPAQUE}static __initDefine__(){Ee.SHADERDEFINE_DIFFUSEMAP=Z.getDefineByName("DIFFUSEMAP"),Ee.SHADERDEFINE_NORMALMAP=Z.getDefineByName("NORMALMAP"),Ee.SHADERDEFINE_SPECULARMAP=Z.getDefineByName("SPECULARMAP"),Ee.SHADERDEFINE_ENABLEVERTEXCOLOR=Z.getDefineByName("ENABLEVERTEXCOLOR"),Ee.SHADERDEFINE_ENABLETRANSMISSION=Z.getDefineByName("ENABLETRANSMISSION"),Ee.SHADERDEFINE_THICKNESSMAP=Z.getDefineByName("THICKNESSMAP")}get _ColorR(){return this.albedoColor.x}set _ColorR(e){let t=this.albedoColor;t.x=e,this.albedoColor=t}get _ColorG(){return this.albedoColor.y}set _ColorG(e){let t=this.albedoColor;t.y=e,this.albedoColor=t}get _ColorB(){return this.albedoColor.z}set _ColorB(e){let t=this.albedoColor;t.z=e,this.albedoColor=t}get _ColorA(){return this.albedoColor.w}set _ColorA(e){let t=this.albedoColor;t.w=e,this.albedoColor=t}get _Color(){return this._shaderValues.getVector(Ee.ALBEDOCOLOR)}set _Color(e){this.albedoColor=e}get _SpecColorR(){return this._shaderValues.getVector(Ee.MATERIALSPECULAR).x}set _SpecColorR(e){this._shaderValues.getVector(Ee.MATERIALSPECULAR).x=e}get _SpecColorG(){return this._shaderValues.getVector(Ee.MATERIALSPECULAR).y}set _SpecColorG(e){this._shaderValues.getVector(Ee.MATERIALSPECULAR).y=e}get _SpecColorB(){return this._shaderValues.getVector(Ee.MATERIALSPECULAR).z}set _SpecColorB(e){this._shaderValues.getVector(Ee.MATERIALSPECULAR).z=e}get _SpecColorA(){return this._shaderValues.getVector(Ee.MATERIALSPECULAR).w}set _SpecColorA(e){this._shaderValues.getVector(Ee.MATERIALSPECULAR).w=e}get _SpecColor(){return this._shaderValues.getVector(Ee.MATERIALSPECULAR)}set _SpecColor(e){this.specularColor=e}get _Shininess(){return this._shaderValues.getNumber(Ee.SHININESS)}set _Shininess(e){e=Math.max(0,Math.min(1,e)),this._shaderValues.setNumber(Ee.SHININESS,e)}get _MainTex_STX(){return this._shaderValues.getVector(Ee.TILINGOFFSET).x}set _MainTex_STX(e){var t=this._shaderValues.getVector(Ee.TILINGOFFSET);t.x=e,this.tilingOffset=t}get _MainTex_STY(){return this._shaderValues.getVector(Ee.TILINGOFFSET).y}set _MainTex_STY(e){var t=this._shaderValues.getVector(Ee.TILINGOFFSET);t.y=e,this.tilingOffset=t}get _MainTex_STZ(){return this._shaderValues.getVector(Ee.TILINGOFFSET).z}set _MainTex_STZ(e){var t=this._shaderValues.getVector(Ee.TILINGOFFSET);t.z=e,this.tilingOffset=t}get _MainTex_STW(){return this._shaderValues.getVector(Ee.TILINGOFFSET).w}set _MainTex_STW(e){var t=this._shaderValues.getVector(Ee.TILINGOFFSET);t.w=e,this.tilingOffset=t}get _MainTex_ST(){return this._shaderValues.getVector(Ee.TILINGOFFSET)}set _MainTex_ST(e){this.tilingOffset=e}get _Cutoff(){return this.alphaTestValue}set _Cutoff(e){this.alphaTestValue=e}set renderMode(e){switch(e){case Ee.RENDERMODE_OPAQUE:this.alphaTest=!1,this.renderQueue=ue.RENDERQUEUE_OPAQUE,this.depthWrite=!0,this.cull=fe.CULL_BACK,this.blend=fe.BLEND_DISABLE,this.depthTest=fe.DEPTHTEST_LESS;break;case Ee.RENDERMODE_CUTOUT:this.renderQueue=ue.RENDERQUEUE_ALPHATEST,this.alphaTest=!0,this.depthWrite=!0,this.cull=fe.CULL_BACK,this.blend=fe.BLEND_DISABLE,this.depthTest=fe.DEPTHTEST_LESS;break;case Ee.RENDERMODE_TRANSPARENT:this.renderQueue=ue.RENDERQUEUE_TRANSPARENT,this.alphaTest=!1,this.depthWrite=!1,this.cull=fe.CULL_BACK,this.blend=fe.BLEND_ENABLE_ALL,this.blendSrc=fe.BLENDPARAM_SRC_ALPHA,this.blendDst=fe.BLENDPARAM_ONE_MINUS_SRC_ALPHA,this.depthTest=fe.DEPTHTEST_LESS;break;default:throw new Error("Material:renderMode value error.")}}get enableVertexColor(){return this._shaderValues.hasDefine(Ee.SHADERDEFINE_ENABLEVERTEXCOLOR)}set enableVertexColor(e){e?this._shaderValues.addDefine(Ee.SHADERDEFINE_ENABLEVERTEXCOLOR):this._shaderValues.removeDefine(Ee.SHADERDEFINE_ENABLEVERTEXCOLOR)}get tilingOffsetX(){return this._MainTex_STX}set tilingOffsetX(e){this._MainTex_STX=e}get tilingOffsetY(){return this._MainTex_STY}set tilingOffsetY(e){this._MainTex_STY=e}get tilingOffsetZ(){return this._MainTex_STZ}set tilingOffsetZ(e){this._MainTex_STZ=e}get tilingOffsetW(){return this._MainTex_STW}set tilingOffsetW(e){this._MainTex_STW=e}get tilingOffset(){return this._shaderValues.getVector(Ee.TILINGOFFSET)}set tilingOffset(e){e?this._shaderValues.setVector(Ee.TILINGOFFSET,e):this._shaderValues.getVector(Ee.TILINGOFFSET).setValue(1,1,0,0)}get albedoColorR(){return this._ColorR}set albedoColorR(e){this._ColorR=e}get albedoColorG(){return this._ColorG}set albedoColorG(e){this._ColorG=e}get albedoColorB(){return this._ColorB}set albedoColorB(e){this._ColorB=e}get albedoColorA(){return this._ColorA}set albedoColorA(e){this._ColorA=e}get albedoColor(){return this._shaderValues.getVector(Ee.ALBEDOCOLOR)}set albedoColor(e){this._shaderValues.setVector(Ee.ALBEDOCOLOR,e)}get albedoIntensity(){return this._shaderValues.getNumber(Ee.AlbedoIntensity)}set albedoIntensity(e){this._shaderValues.setNumber(Ee.AlbedoIntensity,e)}get specularColorR(){return this._SpecColorR}set specularColorR(e){this._SpecColorR=e}get specularColorG(){return this._SpecColorG}set specularColorG(e){this._SpecColorG=e}get specularColorB(){return this._SpecColorB}set specularColorB(e){this._SpecColorB=e}get specularColorA(){return this._SpecColorA}set specularColorA(e){this._SpecColorA=e}get specularColor(){return this._shaderValues.getVector(Ee.MATERIALSPECULAR)}set specularColor(e){this._shaderValues.setVector(Ee.MATERIALSPECULAR,e)}get shininess(){return this._Shininess}set shininess(e){this._Shininess=e}get albedoTexture(){return this._shaderValues.getTexture(Ee.ALBEDOTEXTURE)}set albedoTexture(e){e?this._shaderValues.addDefine(Ee.SHADERDEFINE_DIFFUSEMAP):this._shaderValues.removeDefine(Ee.SHADERDEFINE_DIFFUSEMAP),this._shaderValues.setTexture(Ee.ALBEDOTEXTURE,e)}get normalTexture(){return this._shaderValues.getTexture(Ee.NORMALTEXTURE)}set normalTexture(e){e?this._shaderValues.addDefine(Ee.SHADERDEFINE_NORMALMAP):this._shaderValues.removeDefine(Ee.SHADERDEFINE_NORMALMAP),this._shaderValues.setTexture(Ee.NORMALTEXTURE,e)}get specularTexture(){return this._shaderValues.getTexture(Ee.SPECULARTEXTURE)}set specularTexture(e){e?this._shaderValues.addDefine(Ee.SHADERDEFINE_SPECULARMAP):this._shaderValues.removeDefine(Ee.SHADERDEFINE_SPECULARMAP),this._shaderValues.setTexture(Ee.SPECULARTEXTURE,e)}get enableTransmission(){return this._shaderValues.hasDefine(Ee.SHADERDEFINE_ENABLETRANSMISSION)}set enableTransmission(e){e?this._shaderValues.addDefine(Ee.SHADERDEFINE_ENABLETRANSMISSION):this._shaderValues.removeDefine(Ee.SHADERDEFINE_ENABLETRANSMISSION)}get transmissionRate(){return this._shaderValues.getNumber(Ee.TRANSMISSIONRATE)}set transmissionRata(e){this._shaderValues.setNumber(Ee.TRANSMISSIONRATE,e)}get backDiffuse(){return this._shaderValues.getNumber(Ee.IBACKDIFFUSE)}set backDiffuse(e){this._shaderValues.setNumber(Ee.IBACKDIFFUSE,Math.max(e,1))}get backScale(){return this._shaderValues.getNumber(Ee.IBACKSCALE)}set backScale(e){this._shaderValues.setNumber(Ee.IBACKSCALE,e)}get thinknessTexture(){return this._shaderValues.getTexture(Ee.THINKNESSTEXTURE)}set thinknessTexture(e){e?this._shaderValues.addDefine(Ee.SHADERDEFINE_THICKNESSMAP):this._shaderValues.removeDefine(Ee.SHADERDEFINE_THICKNESSMAP),this._shaderValues.setTexture(Ee.THINKNESSTEXTURE,e)}get transmissionColor(){return this._shaderValues.getVector(Ee.TRANSMISSIONCOLOR)}set transmissionColor(e){this._shaderValues.setVector(Ee.TRANSMISSIONCOLOR,e)}clone(){var e=new Ee;return this.cloneTo(e),e}cloneTo(e){super.cloneTo(e);var t=e;t.albedoIntensity=this.albedoIntensity,t.enableVertexColor=this.enableVertexColor,this.albedoColor.cloneTo(t.albedoColor)}}Ee.RENDERMODE_OPAQUE=0,Ee.RENDERMODE_CUTOUT=1,Ee.RENDERMODE_TRANSPARENT=2,Ee.ALBEDOTEXTURE=Z.propertyNameToID("u_DiffuseTexture"),Ee.NORMALTEXTURE=Z.propertyNameToID("u_NormalTexture"),Ee.SPECULARTEXTURE=Z.propertyNameToID("u_SpecularTexture"),Ee.ALBEDOCOLOR=Z.propertyNameToID("u_DiffuseColor"),Ee.MATERIALSPECULAR=Z.propertyNameToID("u_MaterialSpecular"),Ee.SHININESS=Z.propertyNameToID("u_Shininess"),Ee.TILINGOFFSET=Z.propertyNameToID("u_TilingOffset"),Ee.TRANSMISSIONRATE=Z.propertyNameToID("u_TransmissionRate"),Ee.IBACKDIFFUSE=Z.propertyNameToID("u_BackDiffuse"),Ee.IBACKSCALE=Z.propertyNameToID("u_BackScale"),Ee.THINKNESSTEXTURE=Z.propertyNameToID("u_ThinknessTexture"),Ee.TRANSMISSIONCOLOR=Z.propertyNameToID("u_TransmissionColor"),Ee.AlbedoIntensity=Z.propertyNameToID("u_AlbedoIntensity");class Te extends ue{constructor(){super(),this.setShaderName("Effect"),this._shaderValues.setVector(Te.TILINGOFFSET,new n(1,1,0,0)),this._shaderValues.setVector(Te.TINTCOLOR,new n(1,1,1,1)),this.renderMode=Te.RENDERMODE_ADDTIVE}static __initDefine__(){Te.SHADERDEFINE_MAINTEXTURE=Z.getDefineByName("MAINTEXTURE"),Te.SHADERDEFINE_ADDTIVEFOG=Z.getDefineByName("ADDTIVEFOG")}get _TintColorR(){return this.color.x}set _TintColorR(e){let t=this.color;t.x=e,this.color=t}get _TintColorG(){return this.color.y}set _TintColorG(e){let t=this.color;t.y=e,this.color=t}get _TintColorB(){return this.color.z}set _TintColorB(e){let t=this.color;t.z=e,this.color=t}get _TintColorA(){return this.color.w}set _TintColorA(e){let t=this.color;t.w=e,this.color=t}get _TintColor(){return this._shaderValues.getVector(Te.TINTCOLOR)}set _TintColor(e){this.color=e}get _MainTex_STX(){return this._shaderValues.getVector(Te.TILINGOFFSET).x}set _MainTex_STX(e){var t=this._shaderValues.getVector(Te.TILINGOFFSET);t.x=e,this.tilingOffset=t}get _MainTex_STY(){return this._shaderValues.getVector(Te.TILINGOFFSET).y}set _MainTex_STY(e){var t=this._shaderValues.getVector(Te.TILINGOFFSET);t.y=e,this.tilingOffset=t}get _MainTex_STZ(){return this._shaderValues.getVector(Te.TILINGOFFSET).z}set _MainTex_STZ(e){var t=this._shaderValues.getVector(Te.TILINGOFFSET);t.z=e,this.tilingOffset=t}get _MainTex_STW(){return this._shaderValues.getVector(Te.TILINGOFFSET).w}set _MainTex_STW(e){var t=this._shaderValues.getVector(Te.TILINGOFFSET);t.w=e,this.tilingOffset=t}get _MainTex_ST(){return this._shaderValues.getVector(Te.TILINGOFFSET)}set _MainTex_ST(e){this.tilingOffset=e}set renderMode(e){switch(e){case Te.RENDERMODE_ADDTIVE:this.renderQueue=ue.RENDERQUEUE_TRANSPARENT,this.alphaTest=!1,this.depthWrite=!1,this.cull=fe.CULL_NONE,this.blend=fe.BLEND_ENABLE_ALL,this.blendSrc=fe.BLENDPARAM_SRC_ALPHA,this.blendDst=fe.BLENDPARAM_ONE,this.depthTest=fe.DEPTHTEST_LESS,this._shaderValues.addDefine(Te.SHADERDEFINE_ADDTIVEFOG);break;case Te.RENDERMODE_ALPHABLENDED:this.renderQueue=ue.RENDERQUEUE_TRANSPARENT,this.alphaTest=!1,this.depthWrite=!1,this.cull=fe.CULL_NONE,this.blend=fe.BLEND_ENABLE_ALL,this.blendSrc=fe.BLENDPARAM_SRC_ALPHA,this.blendDst=fe.BLENDPARAM_ONE_MINUS_SRC_ALPHA,this.depthTest=fe.DEPTHTEST_LESS,this._shaderValues.removeDefine(Te.SHADERDEFINE_ADDTIVEFOG);break;default:throw new Error("MeshEffectMaterial : renderMode value error.")}}get colorR(){return this._TintColorR}set colorR(e){this._TintColorR=e}get colorG(){return this._TintColorG}set colorG(e){this._TintColorG=e}get colorB(){return this._TintColorB}set colorB(e){this._TintColorB=e}get colorA(){return this._TintColorA}set colorA(e){this._TintColorA=e}get color(){return this._shaderValues.getVector(Te.TINTCOLOR)}set color(e){this._shaderValues.setVector(Te.TINTCOLOR,e)}get texture(){return this._shaderValues.getTexture(Te.MAINTEXTURE)}set texture(e){e?this._shaderValues.addDefine(Te.SHADERDEFINE_MAINTEXTURE):this._shaderValues.removeDefine(Te.SHADERDEFINE_MAINTEXTURE),this._shaderValues.setTexture(Te.MAINTEXTURE,e)}get tilingOffsetX(){return this._MainTex_STX}set tilingOffsetX(e){this._MainTex_STX=e}get tilingOffsetY(){return this._MainTex_STY}set tilingOffsetY(e){this._MainTex_STY=e}get tilingOffsetZ(){return this._MainTex_STZ}set tilingOffsetZ(e){this._MainTex_STZ=e}get tilingOffsetW(){return this._MainTex_STW}set tilingOffsetW(e){this._MainTex_STW=e}get tilingOffset(){return this._shaderValues.getVector(Te.TILINGOFFSET)}set tilingOffset(e){e?this._shaderValues.setVector(Te.TILINGOFFSET,e):this._shaderValues.getVector(Te.TILINGOFFSET).setValue(1,1,0,0)}clone(){var e=new Te;return this.cloneTo(e),e}}Te.RENDERMODE_ADDTIVE=0,Te.RENDERMODE_ALPHABLENDED=1,Te.MAINTEXTURE=Z.propertyNameToID("u_AlbedoTexture"),Te.TINTCOLOR=Z.propertyNameToID("u_AlbedoColor"),Te.TILINGOFFSET=Z.propertyNameToID("u_TilingOffset");class pe extends ue{constructor(){super(),this.setShaderName("ExtendTerrain"),this.renderMode=pe.RENDERMODE_OPAQUE}static __initDefine__(){pe.SHADERDEFINE_DETAIL_NUM1=Z.getDefineByName("ExtendTerrain_DETAIL_NUM1"),pe.SHADERDEFINE_DETAIL_NUM2=Z.getDefineByName("ExtendTerrain_DETAIL_NUM2"),pe.SHADERDEFINE_DETAIL_NUM3=Z.getDefineByName("ExtendTerrain_DETAIL_NUM3"),pe.SHADERDEFINE_DETAIL_NUM4=Z.getDefineByName("ExtendTerrain_DETAIL_NUM4"),pe.SHADERDEFINE_DETAIL_NUM5=Z.getDefineByName("ExtendTerrain_DETAIL_NUM5")}get splatAlphaTexture(){return this._shaderValues.getTexture(pe.SPLATALPHATEXTURE)}set splatAlphaTexture(e){this._shaderValues.setTexture(pe.SPLATALPHATEXTURE,e)}get diffuseTexture1(){return this._shaderValues.getTexture(pe.DIFFUSETEXTURE1)}set diffuseTexture1(e){this._shaderValues.setTexture(pe.DIFFUSETEXTURE1,e),this._setDetailNum(1)}get diffuseTexture2(){return this._shaderValues.getTexture(pe.DIFFUSETEXTURE2)}set diffuseTexture2(e){this._shaderValues.setTexture(pe.DIFFUSETEXTURE2,e),this._setDetailNum(2)}get diffuseTexture3(){return this._shaderValues.getTexture(pe.DIFFUSETEXTURE3)}set diffuseTexture3(e){this._shaderValues.setTexture(pe.DIFFUSETEXTURE3,e),this._setDetailNum(3)}get diffuseTexture4(){return this._shaderValues.getTexture(pe.DIFFUSETEXTURE4)}set diffuseTexture4(e){this._shaderValues.setTexture(pe.DIFFUSETEXTURE4,e),this._setDetailNum(4)}get diffuseTexture5(){return this._shaderValues.getTexture(pe.DIFFUSETEXTURE5)}set diffuseTexture5(e){this._shaderValues.setTexture(pe.DIFFUSETEXTURE5,e),this._setDetailNum(5)}set diffuseScaleOffset1(e){this._shaderValues.setVector(pe.DIFFUSESCALEOFFSET1,e)}set diffuseScaleOffset2(e){this._shaderValues.setVector(pe.DIFFUSESCALEOFFSET2,e)}set diffuseScaleOffset3(e){this._shaderValues.setVector(pe.DIFFUSESCALEOFFSET3,e)}set diffuseScaleOffset4(e){this._shaderValues.setVector(pe.DIFFUSESCALEOFFSET4,e)}set diffuseScaleOffset5(e){this._shaderValues.setVector(pe.DIFFUSESCALEOFFSET5,e)}set renderMode(e){switch(e){case pe.RENDERMODE_OPAQUE:this.renderQueue=ue.RENDERQUEUE_OPAQUE,this.depthWrite=!0,this.cull=fe.CULL_BACK,this.blend=fe.BLEND_DISABLE,this.depthTest=fe.DEPTHTEST_LESS;break;case pe.RENDERMODE_TRANSPARENT:this.renderQueue=ue.RENDERQUEUE_OPAQUE,this.depthWrite=!1,this.cull=fe.CULL_BACK,this.blend=fe.BLEND_ENABLE_ALL,this.blendSrc=fe.BLENDPARAM_SRC_ALPHA,this.blendDst=fe.BLENDPARAM_ONE_MINUS_SRC_ALPHA,this.depthTest=fe.DEPTHTEST_LEQUAL;break;default:throw new Error("ExtendTerrainMaterial:renderMode value error.")}}_setDetailNum(e){switch(e){case 1:this._shaderValues.addDefine(pe.SHADERDEFINE_DETAIL_NUM1),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM2),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM3),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM4),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM5);break;case 2:this._shaderValues.addDefine(pe.SHADERDEFINE_DETAIL_NUM2),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM1),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM3),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM4),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM5);break;case 3:this._shaderValues.addDefine(pe.SHADERDEFINE_DETAIL_NUM3),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM1),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM2),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM4),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM5);break;case 4:this._shaderValues.addDefine(pe.SHADERDEFINE_DETAIL_NUM4),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM1),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM2),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM3),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM5);break;case 5:this._shaderValues.addDefine(pe.SHADERDEFINE_DETAIL_NUM5),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM1),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM2),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM3),this._shaderValues.removeDefine(pe.SHADERDEFINE_DETAIL_NUM4)}}clone(){var e=new pe;return this.cloneTo(e),e}}pe.RENDERMODE_OPAQUE=1,pe.RENDERMODE_TRANSPARENT=2,pe.SPLATALPHATEXTURE=Z.propertyNameToID("u_SplatAlphaTexture"),pe.DIFFUSETEXTURE1=Z.propertyNameToID("u_DiffuseTexture1"),pe.DIFFUSETEXTURE2=Z.propertyNameToID("u_DiffuseTexture2"),pe.DIFFUSETEXTURE3=Z.propertyNameToID("u_DiffuseTexture3"),pe.DIFFUSETEXTURE4=Z.propertyNameToID("u_DiffuseTexture4"),pe.DIFFUSETEXTURE5=Z.propertyNameToID("u_DiffuseTexture5"),pe.DIFFUSESCALEOFFSET1=Z.propertyNameToID("u_DiffuseScaleOffset1"),pe.DIFFUSESCALEOFFSET2=Z.propertyNameToID("u_DiffuseScaleOffset2"),pe.DIFFUSESCALEOFFSET3=Z.propertyNameToID("u_DiffuseScaleOffset3"),pe.DIFFUSESCALEOFFSET4=Z.propertyNameToID("u_DiffuseScaleOffset4"),pe.DIFFUSESCALEOFFSET5=Z.propertyNameToID("u_DiffuseScaleOffset5"),(l=e.PBRRenderMode||(e.PBRRenderMode={}))[l.Opaque=0]="Opaque",l[l.Cutout=1]="Cutout",l[l.Fade=2]="Fade",l[l.Transparent=3]="Transparent";class ge extends ue{constructor(){super(),this._shaderValues.setVector(ge.ALBEDOCOLOR,new n(1,1,1,1)),this._shaderValues.setVector(ge.EMISSIONCOLOR,new n(1,1,1,1)),this._shaderValues.setVector(ge.TILINGOFFSET,new n(1,1,0,0)),this._shaderValues.setNumber(ge.SMOOTHNESS,.5),this._shaderValues.setNumber(ge.SMOOTHNESSSCALE,1),this._shaderValues.setNumber(ge.OCCLUSIONSTRENGTH,1),this._shaderValues.setNumber(ge.NORMALSCALE,1),this._shaderValues.setNumber(ge.PARALLAXSCALE,.001),this._shaderValues.setNumber(ue.ALPHATESTVALUE,.5),this.renderMode=e.PBRRenderMode.Opaque}static __init__(){ge.SHADERDEFINE_ALBEDOTEXTURE=Z.getDefineByName("ALBEDOTEXTURE"),ge.SHADERDEFINE_NORMALTEXTURE=Z.getDefineByName("NORMALTEXTURE"),ge.SHADERDEFINE_PARALLAXTEXTURE=Z.getDefineByName("PARALLAXTEXTURE"),ge.SHADERDEFINE_OCCLUSIONTEXTURE=Z.getDefineByName("OCCLUSIONTEXTURE"),ge.SHADERDEFINE_EMISSION=Z.getDefineByName("EMISSION"),ge.SHADERDEFINE_EMISSIONTEXTURE=Z.getDefineByName("EMISSIONTEXTURE"),ge.SHADERDEFINE_TRANSPARENTBLEND=Z.getDefineByName("TRANSPARENTBLEND"),ge.SHADERDEFINE_LAYA_PBR_BRDF_HIGH=Z.getDefineByName("LAYA_PBR_BRDF_HIGH"),ge.SHADERDEFINE_LAYA_PBR_BRDF_LOW=Z.getDefineByName("LAYA_PBR_BRDF_LOW")}get albedoColor(){return this._shaderValues.getVector(ge.ALBEDOCOLOR)}set albedoColor(e){this._shaderValues.setVector(ge.ALBEDOCOLOR,e)}get albedoTexture(){return this._shaderValues.getTexture(ge.ALBEDOTEXTURE)}set albedoTexture(e){e?this._shaderValues.addDefine(ge.SHADERDEFINE_ALBEDOTEXTURE):this._shaderValues.removeDefine(ge.SHADERDEFINE_ALBEDOTEXTURE),this._shaderValues.setTexture(ge.ALBEDOTEXTURE,e)}get normalTexture(){return this._shaderValues.getTexture(ge.NORMALTEXTURE)}set normalTexture(e){e?this._shaderValues.addDefine(ge.SHADERDEFINE_NORMALTEXTURE):this._shaderValues.removeDefine(ge.SHADERDEFINE_NORMALTEXTURE),this._shaderValues.setTexture(ge.NORMALTEXTURE,e)}get normalTextureScale(){return this._shaderValues.getNumber(ge.NORMALSCALE)}set normalTextureScale(e){this._shaderValues.setNumber(ge.NORMALSCALE,e)}get parallaxTexture(){return this._shaderValues.getTexture(ge.PARALLAXTEXTURE)}set parallaxTexture(e){e?this._shaderValues.addDefine(ge.SHADERDEFINE_PARALLAXTEXTURE):this._shaderValues.removeDefine(ge.SHADERDEFINE_PARALLAXTEXTURE),this._shaderValues.setTexture(ge.PARALLAXTEXTURE,e)}get parallaxTextureScale(){return this._shaderValues.getNumber(ge.PARALLAXSCALE)}set parallaxTextureScale(e){this._shaderValues.setNumber(ge.PARALLAXSCALE,Math.max(.005,Math.min(.08,e)))}get occlusionTexture(){return this._shaderValues.getTexture(ge.OCCLUSIONTEXTURE)}set occlusionTexture(e){e?this._shaderValues.addDefine(ge.SHADERDEFINE_OCCLUSIONTEXTURE):this._shaderValues.removeDefine(ge.SHADERDEFINE_OCCLUSIONTEXTURE),this._shaderValues.setTexture(ge.OCCLUSIONTEXTURE,e)}get occlusionTextureStrength(){return this._shaderValues.getNumber(ge.OCCLUSIONSTRENGTH)}set occlusionTextureStrength(e){this._shaderValues.setNumber(ge.OCCLUSIONSTRENGTH,Math.max(0,Math.min(1,e)))}get smoothness(){return this._shaderValues.getNumber(ge.SMOOTHNESS)}set smoothness(e){this._shaderValues.setNumber(ge.SMOOTHNESS,Math.max(0,Math.min(1,e)))}get smoothnessTextureScale(){return this._shaderValues.getNumber(ge.SMOOTHNESSSCALE)}set smoothnessTextureScale(e){this._shaderValues.setNumber(ge.SMOOTHNESSSCALE,Math.max(0,Math.min(1,e)))}get enableEmission(){return this._shaderValues.hasDefine(ge.SHADERDEFINE_EMISSION)}set enableEmission(e){e?this._shaderValues.addDefine(ge.SHADERDEFINE_EMISSION):this._shaderValues.removeDefine(ge.SHADERDEFINE_EMISSION)}get emissionColor(){return this._shaderValues.getVector(ge.EMISSIONCOLOR)}set emissionColor(e){this._shaderValues.setVector(ge.EMISSIONCOLOR,e)}get emissionTexture(){return this._shaderValues.getTexture(ge.EMISSIONTEXTURE)}set emissionTexture(e){e?this._shaderValues.addDefine(ge.SHADERDEFINE_EMISSIONTEXTURE):this._shaderValues.removeDefine(ge.SHADERDEFINE_EMISSIONTEXTURE),this._shaderValues.setTexture(ge.EMISSIONTEXTURE,e)}get tilingOffset(){return this._shaderValues.getVector(ge.TILINGOFFSET)}set tilingOffset(e){e?this._shaderValues.setVector(ge.TILINGOFFSET,e):this._shaderValues.getVector(ge.TILINGOFFSET).setValue(1,1,0,0)}set renderMode(t){switch(t){case e.PBRRenderMode.Opaque:this.alphaTest=!1,this.renderQueue=ue.RENDERQUEUE_OPAQUE,this.depthWrite=!0,this.cull=fe.CULL_BACK,this.blend=fe.BLEND_DISABLE,this.depthTest=fe.DEPTHTEST_LESS,this._shaderValues.removeDefine(ge.SHADERDEFINE_TRANSPARENTBLEND);break;case e.PBRRenderMode.Cutout:this.renderQueue=ue.RENDERQUEUE_ALPHATEST,this.alphaTest=!0,this.depthWrite=!0,this.cull=fe.CULL_BACK,this.blend=fe.BLEND_DISABLE,this.depthTest=fe.DEPTHTEST_LESS,this._shaderValues.removeDefine(ge.SHADERDEFINE_TRANSPARENTBLEND);break;case e.PBRRenderMode.Fade:this.renderQueue=ue.RENDERQUEUE_TRANSPARENT,this.alphaTest=!1,this.depthWrite=!1,this.cull=fe.CULL_BACK,this.blend=fe.BLEND_ENABLE_ALL,this.blendSrc=fe.BLENDPARAM_SRC_ALPHA,this.blendDst=fe.BLENDPARAM_ONE_MINUS_SRC_ALPHA,this.depthTest=fe.DEPTHTEST_LESS,this._shaderValues.removeDefine(ge.SHADERDEFINE_TRANSPARENTBLEND);break;case e.PBRRenderMode.Transparent:this.renderQueue=ue.RENDERQUEUE_TRANSPARENT,this.alphaTest=!1,this.depthWrite=!1,this.cull=fe.CULL_BACK,this.blend=fe.BLEND_ENABLE_ALL,this.blendSrc=fe.BLENDPARAM_ONE,this.blendDst=fe.BLENDPARAM_ONE_MINUS_SRC_ALPHA,this.depthTest=fe.DEPTHTEST_LESS,this._shaderValues.addDefine(ge.SHADERDEFINE_TRANSPARENTBLEND);break;default:throw new Error("PBRMaterial:unknown renderMode value.")}}}ge.ALBEDOTEXTURE=Z.propertyNameToID("u_AlbedoTexture"),ge.ALBEDOCOLOR=Z.propertyNameToID("u_AlbedoColor"),ge.TILINGOFFSET=Z.propertyNameToID("u_TilingOffset"),ge.NORMALTEXTURE=Z.propertyNameToID("u_NormalTexture"),ge.NORMALSCALE=Z.propertyNameToID("u_NormalScale"),ge.SMOOTHNESS=Z.propertyNameToID("u_Smoothness"),ge.SMOOTHNESSSCALE=Z.propertyNameToID("u_SmoothnessScale"),ge.OCCLUSIONTEXTURE=Z.propertyNameToID("u_OcclusionTexture"),ge.OCCLUSIONSTRENGTH=Z.propertyNameToID("u_occlusionStrength"),ge.PARALLAXTEXTURE=Z.propertyNameToID("u_ParallaxTexture"),ge.PARALLAXSCALE=Z.propertyNameToID("u_ParallaxScale"),ge.EMISSIONTEXTURE=Z.propertyNameToID("u_EmissionTexture"),ge.EMISSIONCOLOR=Z.propertyNameToID("u_EmissionColor"),ge.renderQuality=e.PBRRenderQuality.High;var Se,Re,ve,xe,Ae,Ie,Me,De,Le,ye,Ce,Oe,Ne,Pe,we='#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n\r\n#include "Lighting.glsl";\r\n#include "LayaUtile.glsl"\r\n\r\nattribute vec4 a_Position;\r\nattribute vec3 a_Normal;\r\n\r\n#ifdef BONE\r\n\tconst int c_MaxBoneCount = 24;\r\n\tattribute vec4 a_BoneIndices;\r\n\tattribute vec4 a_BoneWeights;\r\n\tuniform mat4 u_Bones[c_MaxBoneCount];\r\n#endif\r\n\r\n#ifdef GPU_INSTANCE\r\n\tattribute mat4 a_WorldMat;\r\n#else\r\n\tuniform mat4 u_WorldMat;\r\n#endif\r\nuniform mat4 u_View;\r\nuniform mat4 u_ViewProjection;\r\nuniform vec4 u_ProjectionParams;\r\n\r\n//传入法线\r\nvarying vec4 depthNormals;\r\n\r\n\r\nvec4 depthNormalsVertex()\r\n{\r\n\tmat4 worldMat;\r\n\t#ifdef GPU_INSTANCE\r\n\t\tworldMat = a_WorldMat;\r\n\t#else\r\n\t\tworldMat = u_WorldMat;\r\n\t#endif\r\n\t\r\n\t#ifdef BONE\r\n\t\tmat4 skinTransform;\r\n\t \t#ifdef SIMPLEBONE\r\n\t\t\tfloat currentPixelPos;\r\n\t\t\t#ifdef GPU_INSTANCE\r\n\t\t\t\tcurrentPixelPos = a_SimpleTextureParams.x+a_SimpleTextureParams.y;\r\n\t\t\t#else\r\n\t\t\t\tcurrentPixelPos = u_SimpleAnimatorParams.x+u_SimpleAnimatorParams.y;\r\n\t\t\t#endif\r\n\t\t\tfloat offset = 1.0/u_SimpleAnimatorTextureSize;\r\n\t\t\tskinTransform = loadMatFromTexture(currentPixelPos,int(a_BoneIndices.x),offset) * a_BoneWeights.x;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.y),offset) * a_BoneWeights.y;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.z),offset) * a_BoneWeights.z;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.w),offset) * a_BoneWeights.w;\r\n\t\t#else\r\n\t\t\tskinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;\r\n\t\t#endif\r\n\t\tworldMat = worldMat * skinTransform;\r\n\t#endif\r\n\r\n\tvec4 positionWS = worldMat * a_Position;\r\n\r\n\tmat3 worldInvMat;\r\n\t#ifdef BONE\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat*skinTransform));\r\n\t#else\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat));\r\n\t#endif \r\n\r\n\tvec3 normalWS = normalize(a_Normal*worldInvMat);//if no normalize will cause precision problem\r\n\t//depthNormals.xyz = normalWS;\r\n\t//存储View空间法线\r\n\tvec3 normalVS = mat3(u_View) * normalWS;\r\n\tdepthNormals.xyz = normalVS;\r\n\t\r\n\tvec4 positionCS = u_ViewProjection * positionWS;\r\n\tdepthNormals.w = (positionCS.z * 2.0 - positionCS.w)*u_ProjectionParams.w;\r\n\t\r\n return positionCS;\r\n}\r\n\r\nvoid main()\r\n{\r\n\tvec4 positionCS = depthNormalsVertex();\r\n\tgl_Position=remapGLPositionZ(positionCS);\r\n}',be='#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n#include "DepthNormalUtil.glsl";\r\n\r\nvarying vec4 depthNormals;\r\n\r\nvoid main()\r\n{\r\n\tgl_FragColor=depthNormalsFragment(depthNormals);\r\n}';class Ve{constructor(){this.textureID=-1}}class Be extends t.Resource{constructor(e,t,r,a,n){super(),this._stateParamsMap=[],this._uploadMark=-1,this._uploadRenderType=-1,this._vs=e,this._ps=t,this._attributeMap=r,this._uniformMap=a,this._shaderPass=n,this._globaluniformMap={},this._create(),this.lock=!0}_create(){var e=t.LayaGL.instance;for(var r in this._program=e.createProgram(),this._vshader=this._createShader(e,this._vs,e.VERTEX_SHADER),this._pshader=this._createShader(e,this._ps,e.FRAGMENT_SHADER),e.attachShader(this._program,this._vshader),e.attachShader(this._program,this._pshader),this._attributeMap)e.bindAttribLocation(this._program,this._attributeMap[r],r);if(e.linkProgram(this._program),!t.Render.isConchApp&&Z.debugMode&&!e.getProgramParameter(this._program,e.LINK_STATUS))throw e.getProgramInfoLog(this._program);var a=[],n=[],i=[],s=[],o=[];this._customUniformParamsMap=[];var l,h,_,d=e.getProgramParameter(this._program,e.ACTIVE_UNIFORMS);for(t.WebGLContext.useProgram(e,this._program),this._curActTexIndex=0,h=0;h0?(l.name=u=u.substr(0,u.length-3),l.isArray=!0):(l.name=u,l.isArray=!1),l.type=c.type,this._addShaderUnifiormFun(l);var m=this._uniformMap[u];if(null!=m)switch(l.dataOffset=Z.propertyNameToID(u),m){case Z.PERIOD_CUSTOM:o.push(l);break;case Z.PERIOD_MATERIAL:s.push(l);break;case Z.PERIOD_SPRITE:i.push(l);break;case Z.PERIOD_CAMERA:n.push(l);break;case Z.PERIOD_SCENE:a.push(l);break;default:throw new Error("Shader3D: period is unkonw.")}else l.dataOffset=Z.propertyNameToID(u),this._globaluniformMap[u]=Z.PERIOD_SCENE,a.push(l)}for(this._sceneUniformParamsMap=t.LayaGL.instance.createCommandEncoder(4*a.length*5+4,64,!0),h=0,_=a.length;h<_;h++)this._sceneUniformParamsMap.addShaderUniform(a[h]);for(this._cameraUniformParamsMap=t.LayaGL.instance.createCommandEncoder(4*n.length*5+4,64,!0),h=0,_=n.length;h<_;h++)this._cameraUniformParamsMap.addShaderUniform(n[h]);for(this._spriteUniformParamsMap=t.LayaGL.instance.createCommandEncoder(4*i.length*5+4,64,!0),h=0,_=i.length;h<_;h++)this._spriteUniformParamsMap.addShaderUniform(i[h]);for(this._materialUniformParamsMap=t.LayaGL.instance.createCommandEncoder(4*s.length*5+4,64,!0),h=0,_=s.length;h<_;h++)this._materialUniformParamsMap.addShaderUniform(s[h]);for(this._customUniformParamsMap.length=o.length,h=0,_=o.length;h<_;h++){var f=o[h];this._customUniformParamsMap[f.dataOffset]=f}var E=this._shaderPass._stateMap;for(var T in E)this._stateParamsMap[E[T]]=Z.propertyNameToID(T)}_getRenderState(e,t){var r=this._stateParamsMap[t];return null==r?null:e[r]}_disposeResource(){t.LayaGL.instance.deleteShader(this._vshader),t.LayaGL.instance.deleteShader(this._pshader),t.LayaGL.instance.deleteProgram(this._program),this._vshader=this._pshader=this._program=null,this._setGPUMemory(0),this._curActTexIndex=0}_addShaderUnifiormFun(e){var r=t.LayaGL.instance;e.caller=this;var a=e.isArray;switch(e.type){case r.BOOL:e.fun=this._uniform1i,e.uploadedValue=new Array(1);break;case r.INT:e.fun=a?this._uniform1iv:this._uniform1i,e.uploadedValue=new Array(1);break;case r.FLOAT:e.fun=a?this._uniform1fv:this._uniform1f,e.uploadedValue=new Array(1);break;case r.FLOAT_VEC2:e.fun=a?this._uniform_vec2v:this._uniform_vec2,e.uploadedValue=new Array(2);break;case r.FLOAT_VEC3:e.fun=a?this._uniform_vec3v:this._uniform_vec3,e.uploadedValue=new Array(3);break;case r.FLOAT_VEC4:e.fun=a?this._uniform_vec4v:this._uniform_vec4,e.uploadedValue=new Array(4);break;case r.FLOAT_MAT2:e.fun=this._uniformMatrix2fv;break;case r.FLOAT_MAT3:e.fun=this._uniformMatrix3fv;break;case r.FLOAT_MAT4:e.fun=a?this._uniformMatrix4fv:this._uniformMatrix4f;break;case r.SAMPLER_2D:case r.SAMPLER_2D_SHADOW:r.uniform1i(e.location,this._curActTexIndex),e.textureID=t.WebGLContext._glTextureIDs[this._curActTexIndex++],e.fun=this._uniform_sampler2D;break;case 35679:r.uniform1i(e.location,this._curActTexIndex),e.textureID=t.WebGLContext._glTextureIDs[this._curActTexIndex++],e.fun=this._uniform_sampler3D;break;case r.SAMPLER_CUBE:r.uniform1i(e.location,this._curActTexIndex),e.textureID=t.WebGLContext._glTextureIDs[this._curActTexIndex++],e.fun=this._uniform_samplerCube;break;default:throw new Error("compile shader err!")}}_createShader(e,t,r){var a=e.createShader(r);if(e.shaderSource(a,t),e.compileShader(a),Z.debugMode&&!e.getShaderParameter(a,e.COMPILE_STATUS))throw e.getShaderInfoLog(a);return a}_uniform1f(e,r){var a=e.uploadedValue;return a[0]!==r?(t.LayaGL.instance.uniform1f(e.location,a[0]=r),1):0}_uniform1fv(e,r){if(r.length<4){var a=e.uploadedValue;return a[0]!==r[0]||a[1]!==r[1]||a[2]!==r[2]||a[3]!==r[3]?(t.LayaGL.instance.uniform1fv(e.location,r),a[0]=r[0],a[1]=r[1],a[2]=r[2],a[3]=r[3],1):0}return t.LayaGL.instance.uniform1fv(e.location,r),1}_uniform_vec2(e,r){var a=e.uploadedValue;return a[0]!==r.x||a[1]!==r.y?(t.LayaGL.instance.uniform2f(e.location,a[0]=r.x,a[1]=r.y),1):0}_uniform_vec2v(e,r){if(r.length<2){var a=e.uploadedValue;return a[0]!==r[0]||a[1]!==r[1]||a[2]!==r[2]||a[3]!==r[3]?(t.LayaGL.instance.uniform2fv(e.location,r),a[0]=r[0],a[1]=r[1],a[2]=r[2],a[3]=r[3],1):0}return t.LayaGL.instance.uniform2fv(e.location,r),1}_uniform_vec3(e,r){var a=e.uploadedValue;return a[0]!==r.x||a[1]!==r.y||a[2]!==r.z?(t.LayaGL.instance.uniform3f(e.location,a[0]=r.x,a[1]=r.y,a[2]=r.z),1):0}_uniform_vec3v(e,r){return t.LayaGL.instance.uniform3fv(e.location,r),1}_uniform_vec4(e,r){var a=e.uploadedValue;return a[0]!==r.x||a[1]!==r.y||a[2]!==r.z||a[3]!==r.w?(t.LayaGL.instance.uniform4f(e.location,a[0]=r.x,a[1]=r.y,a[2]=r.z,a[3]=r.w),1):0}_uniform_vec4v(e,r){return t.LayaGL.instance.uniform4fv(e.location,r),1}_uniformMatrix2fv(e,r){return t.LayaGL.instance.uniformMatrix2fv(e.location,!1,r),1}_uniformMatrix3fv(e,r){return t.LayaGL.instance.uniformMatrix3fv(e.location,!1,r),1}_uniformMatrix4f(e,r){var a=r.elements;return t.LayaGL.instance.uniformMatrix4fv(e.location,!1,a),1}_uniformMatrix4fv(e,r){return t.LayaGL.instance.uniformMatrix4fv(e.location,!1,r),1}_uniform1i(e,r){var a=e.uploadedValue;return a[0]!==r?(t.LayaGL.instance.uniform1i(e.location,a[0]=r),1):0}_uniform1iv(e,r){return t.LayaGL.instance.uniform1iv(e.location,r),1}_uniform_ivec2(e,r){var a=e.uploadedValue;return a[0]!==r[0]||a[1]!==r[1]?(t.LayaGL.instance.uniform2i(e.location,a[0]=r[0],a[1]=r[1]),1):0}_uniform_ivec2v(e,r){return t.LayaGL.instance.uniform2iv(e.location,r),1}_uniform_vec3i(e,r){var a=e.uploadedValue;return a[0]!==r[0]||a[1]!==r[1]||a[2]!==r[2]?(t.LayaGL.instance.uniform3i(e.location,a[0]=r[0],a[1]=r[1],a[2]=r[2]),1):0}_uniform_vec3vi(e,r){return t.LayaGL.instance.uniform3iv(e.location,r),1}_uniform_vec4i(e,r){var a=e.uploadedValue;return a[0]!==r[0]||a[1]!==r[1]||a[2]!==r[2]||a[3]!==r[3]?(t.LayaGL.instance.uniform4i(e.location,a[0]=r[0],a[1]=r[1],a[2]=r[2],a[3]=r[3]),1):0}_uniform_vec4vi(e,r){return t.LayaGL.instance.uniform4iv(e.location,r),1}_uniform_sampler2D(e,r){var a=r._getSource()||r.defaulteTexture._getSource(),n=t.LayaGL.instance;return t.WebGLContext.activeTexture(n,e.textureID),t.WebGLContext.bindTexture(n,n.TEXTURE_2D,a),0}_uniform_sampler3D(e,r){var a=r._getSource()||r.defaulteTexture._getSource(),n=t.LayaGL.instance;return t.WebGLContext.activeTexture(n,e.textureID),t.WebGLContext.bindTexture(n,WebGL2RenderingContext.TEXTURE_3D,a),0}_uniform_samplerCube(e,r){var a=r._getSource()||r.defaulteTexture._getSource(),n=t.LayaGL.instance;return t.WebGLContext.activeTexture(n,e.textureID),t.WebGLContext.bindTexture(n,n.TEXTURE_CUBE_MAP,a),0}bind(){return t.WebGLContext.useProgram(t.LayaGL.instance,this._program)}uploadUniforms(e,r,a){t.Stat.shaderCall+=t.LayaGLRunner.uploadShaderUniforms(t.LayaGL.instance,e,r,a)}uploadRenderStateBlendDepth(e){var r=t.LayaGL.instance,a=this._shaderPass.renderState,n=e.getData(),i=this._getRenderState(n,Z.RENDER_STATE_DEPTH_WRITE),s=this._getRenderState(n,Z.RENDER_STATE_DEPTH_TEST),o=this._getRenderState(n,Z.RENDER_STATE_BLEND);switch(null==i&&(i=a.depthWrite),null==s&&(s=a.depthTest),null==o&&(o=a.blend),t.WebGLContext.setDepthMask(r,i),s===fe.DEPTHTEST_OFF?t.WebGLContext.setDepthTest(r,!1):(t.WebGLContext.setDepthTest(r,!0),t.WebGLContext.setDepthFunc(r,s)),o){case fe.BLEND_DISABLE:t.WebGLContext.setBlend(r,!1);break;case fe.BLEND_ENABLE_ALL:var l=this._getRenderState(n,Z.RENDER_STATE_BLEND_EQUATION),h=this._getRenderState(n,Z.RENDER_STATE_BLEND_SRC),_=this._getRenderState(n,Z.RENDER_STATE_BLEND_DST);null==l&&(l=a.blendEquation),null==h&&(h=a.srcBlend),null==_&&(_=a.dstBlend),t.WebGLContext.setBlend(r,!0),t.WebGLContext.setBlendEquation(r,l),t.WebGLContext.setBlendFunc(r,h,_);break;case fe.BLEND_ENABLE_SEPERATE:var d=this._getRenderState(n,Z.RENDER_STATE_BLEND_EQUATION_RGB),c=this._getRenderState(n,Z.RENDER_STATE_BLEND_EQUATION_ALPHA),u=this._getRenderState(n,Z.RENDER_STATE_BLEND_SRC_RGB),m=this._getRenderState(n,Z.RENDER_STATE_BLEND_DST_RGB),f=this._getRenderState(n,Z.RENDER_STATE_BLEND_SRC_ALPHA),E=this._getRenderState(n,Z.RENDER_STATE_BLEND_DST_ALPHA);null==d&&(d=a.blendEquationRGB),null==c&&(c=a.blendEquationAlpha),null==u&&(u=a.srcBlendRGB),null==m&&(m=a.dstBlendRGB),null==f&&(f=a.srcBlendAlpha),null==E&&(E=a.dstBlendAlpha),t.WebGLContext.setBlend(r,!0),t.WebGLContext.setBlendEquationSeparate(r,d,c),t.WebGLContext.setBlendFuncSeperate(r,u,m,f,E)}}uploadRenderStateFrontFace(e,r,a){var n,i=t.LayaGL.instance,s=this._shaderPass.renderState,o=e.getData(),l=this._getRenderState(o,Z.RENDER_STATE_CULL);switch(null==l&&(l=s.cull),l){case fe.CULL_NONE:t.WebGLContext.setCullFace(i,!1);break;case fe.CULL_FRONT:t.WebGLContext.setCullFace(i,!0),n=r?a?i.CCW:i.CW:a?i.CW:i.CCW,t.WebGLContext.setFrontFace(i,n);break;case fe.CULL_BACK:t.WebGLContext.setCullFace(i,!0),n=r?a?i.CW:i.CCW:a?i.CCW:i.CW,t.WebGLContext.setFrontFace(i,n)}}uploadCustomUniform(e,r){t.Stat.shaderCall+=t.LayaGLRunner.uploadCustomUniform(t.LayaGL.instance,this._customUniformParamsMap,e,r)}_uniformMatrix2fvForNative(e,r){return t.LayaGL.instance.uniformMatrix2fvEx(e.location,!1,r),1}_uniformMatrix3fvForNative(e,r){return t.LayaGL.instance.uniformMatrix3fvEx(e.location,!1,r),1}_uniformMatrix4fvForNative(e,r){return t.LayaGL.instance.uniformMatrix4fvEx(e.location,!1,r),1}}class Fe{constructor(){this.elements=[],this.length=0}_add(e){this.length===this.elements.length?this.elements.push(e):this.elements[this.length]=e}add(e){this.length===this.elements.length?this.elements.push(e):this.elements[this.length]=e,this.length++}}class Ue extends Fe{constructor(){super()}add(e){if(-1!==e._getIndexInList())throw"SimpleSingletonList:"+e+" has in SingletonList.";this._add(e),e._setIndexInList(this.length++)}remove(e){var t=e._getIndexInList();if(this.length--,t!==this.length){var r=this.elements[this.length];this.elements[t]=r,r._setIndexInList(t)}e._setIndexInList(-1)}clear(){for(var e=this.elements,t=0,r=this.length;t0&&s._quickSort(0,d-1),(d=o.elements.length)>0&&o._quickSort(0,d-1)}static cullingShadow(e,r,a){r._clearRenderQueue();var n=r._opaqueQueue;if(r._octree){let t=r._octree;t.updateMotionObjects(),t.shrinkRootIfPossible(),t._rootNode.getCollidingWithCastShadowFrustum(e,a)}else for(var s=r._renders,o=e.position,l=s.elements,h=t.Stat.loopCount,_=0,d=s.length;_0}static cullingRenderBounds(e,t){for(var r=t.cullPlaneCount,a=t.cullPlanes,n=e.getMin(),i=e.getMax(),s=n.x,o=n.y,l=n.z,h=i.x,_=i.y,d=i.z,c=!0,u=0;u0}static renderObjectCullingNative(e,r,a,n,s,o){var l,h,_,d=r._opaqueQueue,c=r._transparentQueue;r._clearRenderQueue();var u=n.length,m=n.elements;for(l=0;l0&&d._quickSort(0,g-1),(g=c.elements.length)>0&&c._quickSort(0,g-1)}static cullingNative(e,r,a,n,i){return t.LayaGL.instance.culling(e,r,a,n,i)}}ke._tempColor0=new He,ke._cameraCullInfo=new Ge,ke._shadowCullInfo=new ze,ke.debugFrustumCulling=!1;class We{constructor(){this.updateMark=-1,this.pointLightCount=0,this.spotLightCount=0,this.indices=[]}}class Xe{constructor(e,t,r,n){this._updateMark=0,this._depthSliceParam=new a,this._xSlices=e,this._ySlices=t,this._zSlices=r;var i=e*t,s=r*(1+Math.ceil(n/4));this._clusterTexture=A._createFloatTextureBuffer(i,s),this._clusterTexture.lock=!0,this._clusterPixels=new Float32Array(i*s*4);for(var o=new Array(this._zSlices),l=0;lt||o<=e)return!1;var l=this._depthSliceParam;return n.zMin=Math.floor(Math.log2(Math.max(s,e))*l.x-l.y),n.zMax=Math.min(Math.ceil(Math.log2(o)*l.x-l.y),this._zSlices),!0}_shrinkSpotLightZPerspective(e,t,r,a,n,i,s){var o=a.x,l=a.y,h=a.z,_=Math.tan(i)*n,d=r.x,c=r.y,u=r.z,m=o-d,f=l-c,E=h-u,T=m*m+f*f+E*E,p=Math.sqrt(1-E*E/T),g=Math.max(Math.min(u,h-p*_),r.z-n),S=Math.min(Math.max(u,h+p*_),r.z+n);if(g>t||S<=e)return!1;var R=this._depthSliceParam;return s.zMin=Math.floor(Math.log2(Math.max(g,e))*R.x-R.y),s.zMax=Math.min(Math.ceil(Math.log2(S)*R.x-R.y),this._zSlices),!0}_shrinkSphereLightByBoundOrth(e,t,r,a,n,i,s){var o=n.z,l=o-i,h=o+i;if(l>a||h<=r)return!1;var _=n.x,d=_-i,c=_+i;if(d>e||c<=-e)return!1;var u=n.y,m=u-i,f=u+i;if(m>t||f<=-t)return!1;var E=this._xSlices,T=this._ySlices,p=this._depthSliceParam,g=2*e/E,S=2*t/T;return s.xMin=Math.max(Math.floor((d+e)/g),0),s.xMax=Math.min(Math.ceil((c+e)/g),E),s.yMin=Math.max(Math.floor((t-f)/S),0),s.yMax=Math.min(Math.ceil((t-m)/S),T),s.zMin=Math.floor(Math.log2(Math.max(l,r))*p.x-p.y),s.zMax=Math.min(Math.ceil(Math.log2(h)*p.x-p.y),this._zSlices),!0}_shrinkSpotLightByBoundOrth(e,t,r,a,n,i,s,o,l){var h=i.x,_=i.y,d=i.z,c=Math.tan(o)*s,u=n.x,m=n.y,f=n.z,E=h-u,T=_-m,p=d-f,g=E*E+T*T+p*p,S=Math.sqrt(1-p*p/g),R=Math.max(Math.min(f,d-S*c),n.z-s),v=Math.min(Math.max(f,d+S*c),n.z+s);if(R>a||v<=r)return!1;var x=Math.sqrt(1-E*E/g),A=Math.max(Math.min(u,h-x*c),n.x-s),I=Math.min(Math.max(u,h+x*c),n.x+s);if(A>e||I<=-e)return!1;var M=Math.sqrt(1-T*T/g),D=Math.max(Math.min(m,_-M*c),n.y-s),L=Math.min(Math.max(m,_+M*c),n.y+s);if(D>t||L<=-t)return!1;var y=this._xSlices,C=this._ySlices,O=this._depthSliceParam,N=2*e/y,P=2*t/C;return l.xMin=Math.max(Math.floor((A+e)/N),0),l.xMax=Math.min(Math.ceil((I+e)/N),y),l.yMin=Math.max(Math.floor((t-L)/P),0),l.yMax=Math.min(Math.ceil((t-D)/P),C),l.zMin=Math.floor(Math.log2(Math.max(R,r))*O.x-O.y),l.zMax=Math.min(Math.ceil(Math.log2(v)*O.x-O.y),this._zSlices),!0}_shrinkXYByRadiusPerspective(e,t,r,a,n){var i,s,o,l,h,_=e.x,d=e.y,c=e.z,u=this._ySlices+1;for(h=0;h0){for(var g=this._xSlices,S=this._ySlices,R=this._zSlices,v=g*S*4,x=v*R,A=this._clusterPixels,I=A.length,M=this._clusterDatas,D=this._updateMark,L=!0,y=0;yo&&(u+=(o-_)*(o-_)),dl&&(u+=(l-d)*(l-d)),ch&&(u+=(h-c)*(h-c)),Math.sqrt(u)}static distanceBoxToBox(e,t){var r,a=e.min,n=a.x,i=a.y,s=a.z,o=e.max,l=o.x,h=o.y,_=o.z,d=t.min,c=d.x,u=d.y,m=d.z,f=t.max,E=f.x,T=f.y,p=f.z,g=0;return n>E?g+=(r=n-E)*r:c>l&&(g+=(r=c-l)*r),i>T?g+=(r=i-T)*r:u>h&&(g+=(r=u-h)*r),s>p?g+=(r=s-p)*r:m>_&&(g+=(r=m-_)*r),Math.sqrt(g)}static distanceSphereToPoint(e,t){var r=Math.sqrt(i.distanceSquared(e.center,t));return r-=e.radius,Math.max(r,0)}static distanceSphereToSphere(e,t){var r=Math.sqrt(i.distanceSquared(e.center,t.center));return r-=e.radius+t.radius,Math.max(r,0)}static intersectsRayAndTriangleRD(e,t,a,n,i){var s=e.origin,o=s.x,l=s.y,h=s.z,_=e.direction,d=_.x,c=_.y,u=_.z,m=t.x,f=t.y,E=t.z,T=a.x,p=a.y,g=a.z,S=n.x,R=n.y,v=n.z,x=Je._tempV30.x,A=Je._tempV30.y,I=Je._tempV30.z;x=T-m,A=p-f,I=g-E;var M=Je._tempV31.x,D=Je._tempV31.y,L=Je._tempV31.z;M=S-m,D=R-f,L=v-E;var y=Je._tempV32.x,C=Je._tempV32.y,O=Je._tempV32.z,N=x*(y=c*L-u*D)+A*(C=u*M-d*L)+I*(O=d*D-c*M);if(r.isZero(N))return!1;var P=1/N,w=Je._tempV33.x,b=Je._tempV33.y,V=Je._tempV33.z,B=(w=o-m)*y+(b=l-f)*C+(V=h-E)*O;if((B*=P)<0||B>1)return!1;var F=Je._tempV34.x,U=Je._tempV34.y,H=Je._tempV34.z,G=d*(F=b*I-V*A)+c*(U=V*x-w*I)+u*(H=w*A-b*x);if((G*=P)<0||B+G>1)return!1;var z=M*F+D*U+L*H;return!((z*=P)<0)}static intersectsRayAndTriangleRP(e,t,r,a,n){return Je.intersectsRayAndTriangleRD(e,t,r,a,void 0)?(i.scale(e.direction,void 0,Je._tempV30),i.add(e.origin,Je._tempV30,n),!0):(n=i._ZERO,!1)}static intersectsRayAndPoint(e,t){i.subtract(e.origin,t,Je._tempV30);var a=i.dot(Je._tempV30,e.direction),n=i.dot(Je._tempV30,Je._tempV30)-r.zeroTolerance;return!(n>0&&a>0)&&!(a*a-n<0)}static intersectsRayAndRay(e,t,a){var n=e.origin,s=n.x,o=n.y,l=n.z,h=e.direction,_=h.x,d=h.y,c=h.z,u=t.origin,m=u.x,f=u.y,E=u.z,T=t.direction,p=T.x,g=T.y,S=T.z;i.cross(h,T,Je._tempV30);var R=Je._tempV30,v=i.scalarLength(Je._tempV30);if(r.isZero(v)&&r.nearEqual(m,s)&&r.nearEqual(f,o)&&r.nearEqual(E,l))return!0;v*=v;var x=m-s,A=f-o,I=E-l,M=p,D=g,L=S,y=R.x,C=R.y,O=R.z,N=x*D*O+A*L*y+I*M*C-x*L*C-A*M*O-I*D*y;M=_,D=d,L=c;var P=N/v;i.scale(h,P,Je._tempV30),i.scale(T,P,Je._tempV31),i.add(n,Je._tempV30,Je._tempV32),i.add(u,Je._tempV31,Je._tempV33);var w=Je._tempV32,b=Je._tempV33;return!!(r.nearEqual(b.x,w.x)&&r.nearEqual(b.y,w.y)&&r.nearEqual(b.z,w.z))}static intersectsPlaneAndTriangle(e,t,r,a){var n=Je.intersectsPlaneAndPoint(e,t),i=Je.intersectsPlaneAndPoint(e,r),s=Je.intersectsPlaneAndPoint(e,a);return n==je.PlaneIntersectionType_Front&&i==je.PlaneIntersectionType_Front&&s==je.PlaneIntersectionType_Front?je.PlaneIntersectionType_Front:n==je.PlaneIntersectionType_Back&&i==je.PlaneIntersectionType_Back&&s==je.PlaneIntersectionType_Back?je.PlaneIntersectionType_Back:je.PlaneIntersectionType_Intersecting}static intersectsRayAndPlaneRD(e,t){var a=t.normal,n=i.dot(a,e.direction);if(Math.abs(n)E)return-1}else{var R=1/l,v=(c-n)*R,x=(E-n)*R;if(v>x){var A=v;v=x,x=A}if((g=Math.max(v,g))>(S=Math.min(x,S)))return-1}if(r.isZero(h)){if(iT)return-1}else{var I=1/h,M=(u-i)*I,D=(T-i)*I;if(M>D){var L=M;M=D,D=L}if((g=Math.max(M,g))>(S=Math.min(D,S)))return-1}if(r.isZero(_)){if(sp)return-1}else{var y=1/_,C=(m-s)*y,O=(p-s)*y;if(C>O){var N=C;C=O,O=N}if((g=Math.max(C,g))>(S=Math.min(O,S)))return-1}return g}static intersectsRayAndBoxRP(e,t,r){var a=Je.intersectsRayAndBoxRD(e,t);return-1===a?(i._ZERO.cloneTo(r),a):(i.scale(e.direction,a,Je._tempV30),i.add(e.origin,Je._tempV30,Je._tempV31),Je._tempV31.cloneTo(r),a)}static intersectsRayAndSphereRD(e,t){var r=t.radius;i.subtract(e.origin,t.center,Je._tempV30);var a=i.dot(Je._tempV30,e.direction),n=i.dot(Je._tempV30,Je._tempV30)-r*r;if(n>0&&a>0)return-1;var s=a*a-n;if(s<0)return-1;var o=-a-Math.sqrt(s);return o<0&&(o=0),o}static intersectsRayAndSphereRP(e,t,r){var a=Je.intersectsRayAndSphereRD(e,t);return-1===a?(i._ZERO.cloneTo(r),a):(i.scale(e.direction,a,Je._tempV30),i.add(e.origin,Je._tempV30,Je._tempV31),Je._tempV31.cloneTo(r),a)}static intersectsSphereAndTriangle(e,t,r,a){var n=e.center,s=e.radius;return Je.closestPointPointTriangle(n,t,r,a,Je._tempV30),i.subtract(Je._tempV30,n,Je._tempV31),i.dot(Je._tempV31,Je._tempV31)<=s*s}static intersectsPlaneAndPoint(e,t){var r=i.dot(e.normal,t)+e.distance;return r>0?je.PlaneIntersectionType_Front:r<0?je.PlaneIntersectionType_Back:je.PlaneIntersectionType_Intersecting}static intersectsPlaneAndPlane(e,t){i.cross(e.normal,t.normal,Je._tempV30);var a=i.dot(Je._tempV30,Je._tempV30);return!r.isZero(a)}static intersectsPlaneAndPlaneRL(e,t,a){var n=e.normal,s=t.normal;i.cross(n,s,Je._tempV34);var o=i.dot(Je._tempV34,Je._tempV34);return!r.isZero(o)&&(i.scale(s,e.distance,Je._tempV30),i.scale(n,t.distance,Je._tempV31),i.subtract(Je._tempV30,Je._tempV31,Je._tempV32),i.cross(Je._tempV32,Je._tempV34,Je._tempV33),i.normalize(Je._tempV34,Je._tempV34),!0)}static intersectsPlaneAndBox(e,t){var r=e.distance,a=e.normal,n=a.x,s=a.y,o=a.z,l=t.min,h=l.x,_=l.y,d=l.z,c=t.max,u=c.x,m=c.y,f=c.z;Je._tempV30.x=n>0?h:u,Je._tempV30.y=s>0?_:m,Je._tempV30.z=o>0?d:f,Je._tempV31.x=n>0?u:h,Je._tempV31.y=s>0?m:_,Je._tempV31.z=o>0?f:d;var E=i.dot(a,Je._tempV30);return E+r>0?je.PlaneIntersectionType_Front:(E=i.dot(a,Je._tempV31))+r<0?je.PlaneIntersectionType_Back:je.PlaneIntersectionType_Intersecting}static intersectsPlaneAndSphere(e,t){var r=t.radius,a=i.dot(e.normal,t.center)+e.distance;return a>r?je.PlaneIntersectionType_Front:a<-r?je.PlaneIntersectionType_Back:je.PlaneIntersectionType_Intersecting}static intersectsBoxAndBox(e,t){var r=e.min,a=e.max,n=t.min,i=t.max;return!(r.x>i.x||n.x>a.x)&&(!(r.y>i.y||n.y>a.y)&&!(r.z>i.z||n.z>a.z))}static intersectsBoxAndSphere(e,t){var r=t.center,a=t.radius,n=Je._tempV30;return i.Clamp(r,e.min,e.max,n),i.distanceSquared(r,n)<=a*a}static intersectsSphereAndSphere(e,t){var r=e.radius+t.radius;return i.distanceSquared(e.center,t.center)<=r*r}static boxContainsPoint(e,t){var r=e.min,a=e.max;return r.x<=t.x&&a.x>=t.x&&r.y<=t.y&&a.y>=t.y&&r.z<=t.z&&a.z>=t.z?Ke.Contains:Ke.Disjoint}static boxContainsBox(e,t){var r=e.min,a=r.x,n=r.y,i=r.z,s=e.max,o=s.x,l=s.y,h=s.z,_=t.min,d=_.x,c=_.y,u=_.z,m=t.max,f=m.x,E=m.y,T=m.z;return of||lE||hT?Ke.Disjoint:a<=d&&f<=o&&n<=c&&E<=l&&i<=u&&T<=h?Ke.Contains:Ke.Intersects}static boxContainsSphere(e,t){var r=e.min,a=r.x,n=r.y,s=r.z,o=e.max,l=o.x,h=o.y,_=o.z,d=t.center,c=d.x,u=d.y,m=d.z,f=t.radius;return i.Clamp(d,r,o,Je._tempV30),i.distanceSquared(d,Je._tempV30)>f*f?Ke.Disjoint:a+f<=c&&c<=l-f&&l-a>f&&n+f<=u&&u<=h-f&&h-n>f&&s+f<=m&&m<=_-f&&_-s>f?Ke.Contains:Ke.Intersects}static sphereContainsPoint(e,t){return i.distanceSquared(t,e.center)<=e.radius*e.radius?Ke.Contains:Ke.Disjoint}static sphereContainsTriangle(e,t,r,a){var n=Je.sphereContainsPoint(e,t),i=Je.sphereContainsPoint(e,r),s=Je.sphereContainsPoint(e,a);return n==Ke.Contains&&i==Ke.Contains&&s==Ke.Contains?Ke.Contains:Je.intersectsSphereAndTriangle(e,t,r,a)?Ke.Intersects:Ke.Disjoint}static sphereContainsBox(e,t){var r=e.center,a=r.x,n=r.y,s=r.z,o=e.radius,l=t.min,h=l.x,_=l.y,d=l.z,c=t.max,u=c.x,m=c.y,f=c.z,E=Je._tempV30;E.x,E.y,E.z;if(!Je.intersectsBoxAndSphere(t,e))return Ke.Disjoint;var T=o*o;return a-h,n-m,s-f,i.scalarLengthSquared(Je._tempV30)>T?Ke.Intersects:(a-u,n-m,s-f,i.scalarLengthSquared(Je._tempV30)>T?Ke.Intersects:(a-u,n-_,s-f,i.scalarLengthSquared(Je._tempV30)>T?Ke.Intersects:(a-h,n-_,s-f,i.scalarLengthSquared(Je._tempV30)>T?Ke.Intersects:(a-h,n-m,s-d,i.scalarLengthSquared(Je._tempV30)>T?Ke.Intersects:(a-u,n-m,s-d,i.scalarLengthSquared(Je._tempV30)>T?Ke.Intersects:(a-u,n-_,s-d,i.scalarLengthSquared(Je._tempV30)>T?Ke.Intersects:(a-h,n-_,s-d,i.scalarLengthSquared(Je._tempV30)>T?Ke.Intersects:Ke.Contains)))))))}static sphereContainsSphere(e,t){var r=e.radius,a=t.radius,n=i.distance(e.center,t.center);return r+a=0&&h<=l)r.cloneTo(n);else{var c=s*h-l*o;if(c<=0&&s>=0&&l<=0){var u=s/(s-l);return i.scale(Je._tempV30,u,n),void i.add(t,n,n)}if(d>=0&&_<=d)a.cloneTo(n);else{var m=_*o-s*d;if(m<=0&&o>=0&&d<=0){var f=o/(o-d);return i.scale(Je._tempV31,f,n),void i.add(t,n,n)}var E=l*d-_*h;if(E<=0&&h-l>=0&&_-d>=0){var T=(h-l)/(h-l+(_-d));return i.subtract(a,r,n),i.scale(n,T,n),void i.add(r,n,n)}var p=1/(E+m+c),g=m*p,S=c*p;i.scale(Je._tempV30,g,Je._tempV35),i.scale(Je._tempV31,S,Je._tempV36),i.add(Je._tempV35,Je._tempV36,n),i.add(t,n,n)}}}static closestPointPlanePoint(e,t,r){var a=e.normal,n=i.dot(a,t)-e.distance;i.scale(a,n,Je._tempV30),i.subtract(t,Je._tempV30,r)}static closestPointBoxPoint(e,t,r){i.max(t,e.min,Je._tempV30),i.min(Je._tempV30,e.max,r)}static closestPointSpherePoint(e,t,r){var a=e.center;i.subtract(t,a,r),i.normalize(r,r),i.scale(r,e.radius,r),i.add(r,a,r)}static closestPointSphereSphere(e,t,r){var a=e.center;i.subtract(t.center,a,r),i.normalize(r,r),i.scale(r,e.radius,r),i.add(r,a,r)}}Je._tempV30=new i,Je._tempV31=new i,Je._tempV32=new i,Je._tempV33=new i,Je._tempV34=new i,Je._tempV35=new i,Je._tempV36=new i,(Se=e.FrustumCorner||(e.FrustumCorner={}))[Se.FarBottomLeft=0]="FarBottomLeft",Se[Se.FarTopLeft=1]="FarTopLeft",Se[Se.FarTopRight=2]="FarTopRight",Se[Se.FarBottomRight=3]="FarBottomRight",Se[Se.nearBottomLeft=4]="nearBottomLeft",Se[Se.nearTopLeft=5]="nearTopLeft",Se[Se.nearTopRight=6]="nearTopRight",Se[Se.nearBottomRight=7]="nearBottomRight",Se[Se.unknown=8]="unknown";class $e{constructor(e){this._matrix=e,this._near=new je(new i),this._far=new je(new i),this._left=new je(new i),this._right=new je(new i),this._top=new je(new i),this._bottom=new je(new i),$e.getPlanesFromMatrix(this._matrix,this._near,this._far,this._left,this._right,this._top,this._bottom)}static getPlanesFromMatrix(e,t,r,a,n,i,s){var o=e.elements,l=o[0],h=o[1],_=o[2],d=o[3],c=o[4],u=o[5],m=o[6],f=o[7],E=o[8],T=o[9],p=o[10],g=o[11],S=o[12],R=o[13],v=o[14],x=o[15],A=t.normal;A.x=_,A.y=m,A.z=p,t.distance=v,t.normalize();var I=r.normal;I.x=d-_,I.y=f-m,I.z=g-p,r.distance=x-v,r.normalize();var M=a.normal;M.x=d+l,M.y=f+c,M.z=g+E,a.distance=x+S,a.normalize();var D=n.normal;D.x=d-l,D.y=f-c,D.z=g-E,n.distance=x-S,n.normalize();var L=i.normal;L.x=d-h,L.y=f-u,L.z=g-T,i.distance=x-R,i.normalize();var y=s.normal;y.x=d+h,y.y=f+u,y.z=g+T,s.distance=x+R,s.normalize()}get matrix(){return this._matrix}set matrix(e){e.cloneTo(this._matrix),$e.getPlanesFromMatrix(this._matrix,this._near,this._far,this._left,this._right,this._top,this._bottom)}get near(){return this._near}get far(){return this._far}get left(){return this._left}get right(){return this._right}get top(){return this._top}get bottom(){return this._bottom}equalsBoundFrustum(e){return this._matrix.equalsOtherMatrix(e.matrix)}equalsObj(e){if(e instanceof $e){var t=e;return this.equalsBoundFrustum(t)}return!1}getPlane(e){switch(e){case 0:return this._near;case 1:return this._far;case 2:return this._left;case 3:return this._right;case 4:return this._top;case 5:return this._bottom;default:return null}}static get3PlaneInterPoint(e,t,r,a){var n=e.normal,s=t.normal,o=r.normal;i.cross(s,o,$e._tempV30),i.cross(o,n,$e._tempV31),i.cross(n,s,$e._tempV32);var l=i.dot(n,$e._tempV30),h=i.dot(s,$e._tempV31),_=i.dot(o,$e._tempV32);i.scale($e._tempV30,-e.distance/l,$e._tempV33),i.scale($e._tempV31,-t.distance/h,$e._tempV34),i.scale($e._tempV32,-r.distance/_,$e._tempV35),i.add($e._tempV33,$e._tempV34,$e._tempV36),i.add($e._tempV35,$e._tempV36,a)}getCorners(t){$e.get3PlaneInterPoint(this._near,this._bottom,this._right,t[e.FrustumCorner.nearBottomRight]),$e.get3PlaneInterPoint(this._near,this._top,this._right,t[e.FrustumCorner.nearTopRight]),$e.get3PlaneInterPoint(this._near,this._top,this._left,t[e.FrustumCorner.nearTopLeft]),$e.get3PlaneInterPoint(this._near,this._bottom,this._left,t[e.FrustumCorner.nearBottomLeft]),$e.get3PlaneInterPoint(this._far,this._bottom,this._right,t[e.FrustumCorner.FarBottomRight]),$e.get3PlaneInterPoint(this._far,this._top,this._right,t[e.FrustumCorner.FarTopRight]),$e.get3PlaneInterPoint(this._far,this._top,this._left,t[e.FrustumCorner.FarTopLeft]),$e.get3PlaneInterPoint(this._far,this._bottom,this._left,t[e.FrustumCorner.FarBottomLeft])}containsPoint(e){for(var t=je.PlaneIntersectionType_Front,r=je.PlaneIntersectionType_Front,a=0;a<6;a++){switch(a){case 0:r=Je.intersectsPlaneAndPoint(this._near,e);break;case 1:r=Je.intersectsPlaneAndPoint(this._far,e);break;case 2:r=Je.intersectsPlaneAndPoint(this._left,e);break;case 3:r=Je.intersectsPlaneAndPoint(this._right,e);break;case 4:r=Je.intersectsPlaneAndPoint(this._top,e);break;case 5:r=Je.intersectsPlaneAndPoint(this._bottom,e)}switch(r){case je.PlaneIntersectionType_Back:return Ke.Disjoint;case je.PlaneIntersectionType_Intersecting:t=je.PlaneIntersectionType_Intersecting}}switch(t){case je.PlaneIntersectionType_Intersecting:return Ke.Intersects;default:return Ke.Contains}}intersects(e){var t=e.min,r=e.max,a=t.x,n=t.y,i=t.z,s=r.x,o=r.y,l=r.z,h=this._near.normal;if(this._near.distance+h.x*(h.x<0?a:s)+h.y*(h.y<0?n:o)+h.z*(h.z<0?i:l)<0)return!1;var _=this._left.normal;if(this._left.distance+_.x*(_.x<0?a:s)+_.y*(_.y<0?n:o)+_.z*(_.z<0?i:l)<0)return!1;var d=this._right.normal;if(this._right.distance+d.x*(d.x<0?a:s)+d.y*(d.y<0?n:o)+d.z*(d.z<0?i:l)<0)return!1;var c=this._bottom.normal;if(this._bottom.distance+c.x*(c.x<0?a:s)+c.y*(c.y<0?n:o)+c.z*(c.z<0?i:l)<0)return!1;var u=this._top.normal;if(this._top.distance+u.x*(u.x<0?a:s)+u.y*(u.y<0?n:o)+u.z*(u.z<0?i:l)<0)return!1;var m=this._far.normal;return!(this._far.distance+m.x*(m.x<0?a:s)+m.y*(m.y<0?n:o)+m.z*(m.z<0?i:l)<0)}containsBoundBox(e){for(var t=$e._tempV30,r=$e._tempV31,a=e.min,n=e.max,i=Ke.Contains,s=0;s<6;s++){var o=this.getPlane(s),l=o.normal;if(l.x>=0?(t.x=n.x,r.x=a.x):(t.x=a.x,r.x=n.x),l.y>=0?(t.y=n.y,r.y=a.y):(t.y=a.y,r.y=n.y),l.z>=0?(t.z=n.z,r.z=a.z):(t.z=a.z,r.z=n.z),Je.intersectsPlaneAndPoint(o,t)===je.PlaneIntersectionType_Back)return Ke.Disjoint;Je.intersectsPlaneAndPoint(o,r)===je.PlaneIntersectionType_Back&&(i=Ke.Intersects)}return i}containsBoundSphere(e){for(var t=je.PlaneIntersectionType_Front,r=je.PlaneIntersectionType_Front,a=0;a<6;a++){switch(a){case 0:r=Je.intersectsPlaneAndSphere(this._near,e);break;case 1:r=Je.intersectsPlaneAndSphere(this._far,e);break;case 2:r=Je.intersectsPlaneAndSphere(this._left,e);break;case 3:r=Je.intersectsPlaneAndSphere(this._right,e);break;case 4:r=Je.intersectsPlaneAndSphere(this._top,e);break;case 5:r=Je.intersectsPlaneAndSphere(this._bottom,e)}switch(r){case je.PlaneIntersectionType_Back:return Ke.Disjoint;case je.PlaneIntersectionType_Intersecting:t=je.PlaneIntersectionType_Intersecting}}switch(t){case je.PlaneIntersectionType_Intersecting:return Ke.Intersects;default:return Ke.Contains}}}$e._tempV30=new i,$e._tempV31=new i,$e._tempV32=new i,$e._tempV33=new i,$e._tempV34=new i,$e._tempV35=new i,$e._tempV36=new i;class et{constructor(e,t,r,a){this.minDepth=0,this.maxDepth=1,this.x=e,this.y=t,this.width=r,this.height=a}project(e,t,r){i.transformV3ToV4(e,t,r);var a=r.x,n=r.y,s=r.z,o=r.w;1!==o&&(a/=o,n/=o,s/=o),r.x=.5*(a+1)*this.width+this.x,r.y=.5*(1-n)*this.height+this.y,r.z=s*(this.maxDepth-this.minDepth)+this.minDepth}unprojectFromMat(e,t,r){var a=t.elements;r.x=(e.x-this.x)/this.width*2-1,r.y=-((e.y-this.y)/this.height*2-1),r.z=(e.z-this.minDepth)/(this.maxDepth-this.minDepth);var n=r.x*a[3]+r.y*a[7]+r.z*a[11]+a[15];i.transformV3ToV3(r,t,r),1!==n&&(r.x=r.x/n,r.y=r.y/n,r.z=r.z/n)}unprojectFromWVP(e,t,r,a,n){B.multiply(t,r,et._tempMatrix4x4),a&&B.multiply(et._tempMatrix4x4,a,et._tempMatrix4x4),et._tempMatrix4x4.invert(et._tempMatrix4x4),this.unprojectFromMat(e,et._tempMatrix4x4,n)}cloneTo(e){e.x=this.x,e.y=this.y,e.width=this.width,e.height=this.height,e.minDepth=this.minDepth,e.maxDepth=this.maxDepth}}et._tempMatrix4x4=new B;class tt{constructor(){}static calculateCursorRay(e,t,r,a,n,s){var o=e.x,l=e.y,h=tt._tempVector30,_=h;_.x=o,_.y=l,_.z=t.minDepth;var d=tt._tempVector31,c=d;c.x=o,c.y=l,c.z=t.maxDepth;var u=s.origin,m=tt._tempVector32;t.unprojectFromWVP(h,r,a,n,u),t.unprojectFromWVP(d,r,a,n,m);var f=s.direction;f.x=m.x-u.x,f.y=m.y-u.y,f.z=m.z-u.z,i.normalize(s.direction,s.direction)}static rayIntersectsTriangle(e,t,r,a){var n=tt._tempVector30,s=tt._tempVector31;i.subtract(r,t,n),i.subtract(a,t,s);var o,l=tt._tempVector32;if(i.cross(e.direction,s,l),(o=i.dot(n,l))>-Number.MIN_VALUE&&o1)return Number.NaN;var c,u,m=tt._tempVector34;return i.cross(d,n,m),c=i.dot(e.direction,m),(c*=_)<0||h+c>1?Number.NaN:(u=i.dot(s,m),(u*=_)<0?Number.NaN:u)}}tt._tempVector30=new i,tt._tempVector31=new i,tt._tempVector32=new i,tt._tempVector33=new i,tt._tempVector34=new i,(Re=e.IndexFormat||(e.IndexFormat={}))[Re.UInt8=0]="UInt8",Re[Re.UInt16=1]="UInt16",Re[Re.UInt32=2]="UInt32";class rt extends t.Buffer{constructor(r,a,n=35044,i=!1){switch(super(),this._indexType=r,this._indexCount=a,this._bufferUsage=n,this._bufferType=t.LayaGL.instance.ELEMENT_ARRAY_BUFFER,this._canRead=i,r){case e.IndexFormat.UInt32:this._indexTypeByteCount=4;break;case e.IndexFormat.UInt16:this._indexTypeByteCount=2;break;case e.IndexFormat.UInt8:this._indexTypeByteCount=1;break;default:throw new Error("unidentification index type.")}var s=this._indexTypeByteCount*a,o=t.BufferStateBase._curBindedBufferState;if(this._byteLength=s,o?o._bindedIndexBuffer===this?t.LayaGL.instance.bufferData(this._bufferType,s,this._bufferUsage):(o.unBind(),this.bind(),t.LayaGL.instance.bufferData(this._bufferType,s,this._bufferUsage),o.bind()):(this.bind(),t.LayaGL.instance.bufferData(this._bufferType,s,this._bufferUsage)),i)switch(r){case e.IndexFormat.UInt32:this._buffer=new Uint32Array(a);break;case e.IndexFormat.UInt16:this._buffer=new Uint16Array(a);break;case e.IndexFormat.UInt8:this._buffer=new Uint8Array(a)}}get indexType(){return this._indexType}get indexTypeByteCount(){return this._indexTypeByteCount}get indexCount(){return this._indexCount}get canRead(){return this._canRead}_bindForVAO(){if(!t.BufferStateBase._curBindedBufferState)throw"IndexBuffer3D: must bind current BufferState.";var e=t.LayaGL.instance;e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this._glBuffer)}bind(){if(t.BufferStateBase._curBindedBufferState)throw"IndexBuffer3D: must unbind current BufferState.";if(t.Buffer._bindedIndexBuffer!==this._glBuffer){var e=t.LayaGL.instance;return e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,this._glBuffer),t.Buffer._bindedIndexBuffer=this._glBuffer,!0}return!1}setData(r,a=0,n=0,i=4294967295){var s=this._indexTypeByteCount;if(0!==n||4294967295!==i)switch(this._indexType){case e.IndexFormat.UInt32:r=new Uint32Array(r.buffer,n*s,i);break;case e.IndexFormat.UInt16:r=new Uint16Array(r.buffer,n*s,i);break;case e.IndexFormat.UInt8:r=new Uint8Array(r.buffer,n*s,i)}var o=t.BufferStateBase._curBindedBufferState;if(o?o._bindedIndexBuffer===this?t.LayaGL.instance.bufferSubData(this._bufferType,a*s,r):(o.unBind(),this.bind(),t.LayaGL.instance.bufferSubData(this._bufferType,a*s,r),o.bind()):(this.bind(),t.LayaGL.instance.bufferSubData(this._bufferType,a*s,r)),this._canRead)if(0!==a||0!==n||4294967295!==i){var l=this._buffer.length-a;i>l&&(i=l);for(var h=0;he[t].renderingOrder){var a=e[r];e[r]=e[t],e[t]=a}}_calculateProjectionMatrix(){}_onScreenSizeChanged(){this._calculateProjectionMatrix()}_prepareCameraToRender(){var e=this._shaderValues;this.transform.getForward(this._forward),this.transform.getUp(this._up),e.setVector3(st.CAMERAPOS,this.transform.position),e.setVector3(st.CAMERADIRECTION,this._forward),e.setVector3(st.CAMERAUP,this._up)}render(e=null,t=null){}addLayer(e){this.cullingMask|=Math.pow(2,e)}removeLayer(e){this.cullingMask&=~Math.pow(2,e)}addAllLayers(){this.cullingMask=2147483647}removeAllLayers(){this.cullingMask=0}resetProjectionMatrix(){this._useUserProjectionMatrix=!1,this._calculateProjectionMatrix()}_onActive(){this._scene._addCamera(this),super._onActive()}_onInActive(){this._scene._removeCamera(this),super._onInActive()}_parse(e,r){super._parse(e,r),this.orthographic=e.orthographic,void 0!==e.orthographicVerticalSize&&(this.orthographicVerticalSize=e.orthographicVerticalSize),void 0!==e.fieldOfView&&(this.fieldOfView=e.fieldOfView),this.nearPlane=e.nearPlane,this.farPlane=e.farPlane;var a=e.clearColor;this.clearColor=new n(a[0],a[1],a[2],a[3]);var i=e.skyboxMaterial;i&&(this._skyRenderer.material=t.Loader.getRes(i.path))}destroy(e=!0){this._skyRenderer.destroy(),this._skyRenderer=null,t.Laya.stage.off(t.Event.RESIZE,this,this._onScreenSizeChanged),super.destroy(e)}_create(){return new st}}st._tempMatrix4x40=new B,st.CAMERAPOS=Z.propertyNameToID("u_CameraPos"),st.VIEWMATRIX=Z.propertyNameToID("u_View"),st.PROJECTMATRIX=Z.propertyNameToID("u_Projection"),st.VIEWPROJECTMATRIX=Z.propertyNameToID("u_ViewProjection"),st.CAMERADIRECTION=Z.propertyNameToID("u_CameraDirection"),st.CAMERAUP=Z.propertyNameToID("u_CameraUp"),st.VIEWPORT=Z.propertyNameToID("u_Viewport"),st.PROJECTION_PARAMS=Z.propertyNameToID("u_ProjectionParams"),st.DEPTHTEXTURE=Z.propertyNameToID("u_CameraDepthTexture"),st.DEPTHNORMALSTEXTURE=Z.propertyNameToID("u_CameraDepthNormalsTexture"),st.DEPTHZBUFFERPARAMS=Z.propertyNameToID("u_ZBufferParams"),st.SHADERDEFINE_DEPTH=Z.getDefineByName("DEPTHMAP"),st.SHADERDEFINE_DEPTHNORMALS=Z.getDefineByName("DEPTHNORMALSMAP"),st.RENDERINGTYPE_DEFERREDLIGHTING="DEFERREDLIGHTING",st.RENDERINGTYPE_FORWARDRENDERING="FORWARDRENDERING",st._invertYScaleMatrix=new B(1,0,0,0,0,-1,0,0,0,0,1,0,0,0,0,1),st._invertYProjectionMatrix=new B,st._invertYProjectionViewMatrix=new B,st.CLEARFLAG_SOLIDCOLOR=0,st.CLEARFLAG_SKY=1,st.CLEARFLAG_DEPTHONLY=2,st.CLEARFLAG_NONE=3,(ve=e.ShadowMode||(e.ShadowMode={}))[ve.None=0]="None",ve[ve.Hard=1]="Hard",ve[ve.SoftLow=2]="SoftLow",ve[ve.SoftHigh=3]="SoftHigh";class ot{}(xe=e.LightType||(e.LightType={}))[xe.Directional=0]="Directional",xe[xe.Spot=1]="Spot",xe[xe.Point=2]="Point";class lt extends ${constructor(){super(),this._shadowMode=e.ShadowMode.None,this._isAlternate=!1,this._shadowResolution=2048,this._shadowDistance=50,this._shadowDepthBias=1,this._shadowNormalBias=1,this._shadowNearPlane=.1,this._shadowStrength=1,this._lightWoldMatrix=new B,this._intensity=1,this._intensityColor=new i,this.color=new i(1,1,1),this._lightmapBakedType=lt.LIGHTMAPBAKEDTYPE_REALTIME}get intensity(){return this._intensity}set intensity(e){this._intensity=e}get shadowMode(){return this._shadowMode}set shadowMode(e){this._shadowMode=e}get shadowDistance(){return this._shadowDistance}set shadowDistance(e){this._shadowDistance=e}get shadowResolution(){return this._shadowResolution}set shadowResolution(e){this._shadowResolution=e}get shadowDepthBias(){return this._shadowDepthBias}set shadowDepthBias(e){this._shadowDepthBias=e}get shadowNormalBias(){return this._shadowNormalBias}set shadowNormalBias(e){this._shadowNormalBias=e}get shadowStrength(){return this._shadowStrength}set shadowStrength(e){this._shadowStrength=e}get shadowNearPlane(){return this._shadowNearPlane}set shadowNearPlane(e){this._shadowNearPlane=e}get lightmapBakedType(){return this._lightmapBakedType}set lightmapBakedType(e){this._lightmapBakedType!==e&&(this._lightmapBakedType=e,this.activeInHierarchy&&(e!==lt.LIGHTMAPBAKEDTYPE_BAKED?this._addToScene():this._removeFromScene()))}get lightWorldMatrix(){var e=this.transform.position,t=this.transform.rotation;return B.createAffineTransformation(e,t,i._ONE,this._lightWoldMatrix),this._lightWoldMatrix}_parse(e,t){super._parse(e,t);var r=e.color;this.color.fromArray(r),this.intensity=e.intensity,this.lightmapBakedType=e.lightmapBakedType}_cloneTo(e,t,r){super._cloneTo(e,t,r);var a=e;a.color=this.color.clone(),a.intensity=this.intensity,a.lightmapBakedType=this.lightmapBakedType}_addToScene(){var e=this._scene,t=d._config.maxLightCount;e._lightCount0){var t=e._alternateLights.shift();t._addToLightQueue(),t._isAlternate=!1,e._lightCount++}}_addToLightQueue(){}_removeFromLightQueue(){}_onActive(){super._onActive(),this.lightmapBakedType!==lt.LIGHTMAPBAKEDTYPE_BAKED&&this._addToScene()}_onInActive(){super._onInActive(),this.lightmapBakedType!==lt.LIGHTMAPBAKEDTYPE_BAKED&&this._removeFromScene()}_create(){return new lt}get diffuseColor(){return console.log("LightSprite: discard property,please use color property instead."),this.color}set diffuseColor(e){console.log("LightSprite: discard property,please use color property instead."),this.color=e}}lt.LIGHTMAPBAKEDTYPE_REALTIME=0,lt.LIGHTMAPBAKEDTYPE_MIXED=1,lt.LIGHTMAPBAKEDTYPE_BAKED=2,(Ae=e.ShadowCascadesMode||(e.ShadowCascadesMode={}))[Ae.NoCascades=0]="NoCascades",Ae[Ae.TwoCascades=1]="TwoCascades",Ae[Ae.FourCascades=2]="FourCascades",function(e){e[e.Near=0]="Near",e[e.Far=1]="Far",e[e.Left=2]="Left",e[e.Right=3]="Right",e[e.Bottom=4]="Bottom",e[e.Top=5]="Top"}(Ie||(Ie={}));class ht{static supportShadow(){return t.LayaGL.layaGPUInstance._isWebGL2||t.SystemUtils.supportRenderTextureFormat(t.RenderTextureFormat.Depth)}static init(){t.LayaGL.layaGPUInstance._isWebGL2?ht._shadowTextureFormat=t.RenderTextureFormat.ShadowMap:ht._shadowTextureFormat=t.RenderTextureFormat.Depth}static getTemporaryShadowTexture(e,r,a){var n=P.createFromPool(e,r,ht._shadowTextureFormat,a);return n.filterMode=t.FilterMode.Bilinear,n.wrapModeU=t.WarpMode.Clamp,n.wrapModeV=t.WarpMode.Clamp,n}static getShadowBias(t,a,n,i){var s;t._lightType==e.LightType.Directional?s=2/a.elements[0]:t._lightType==e.LightType.Spot?s=Math.tan(.5*t.spotAngle*r.Deg2Rad)*t.range:(console.warn("ShadowUtils:Only spot and directional shadow casters are supported now."),s=0);var o=s/n,l=-t._shadowDepthBias*o,h=-t._shadowNormalBias*o;if(t.shadowMode==e.ShadowMode.SoftHigh){const e=2.5;l*=e,h*=e}i.setValue(l,h,0,0)}static getCameraFrustumPlanes(e,t){$e.getPlanesFromMatrix(e,t[Ie.Near],t[Ie.Far],t[Ie.Left],t[Ie.Right],t[Ie.Top],t[Ie.Bottom])}static getFarWithRadius(e,t){return Math.sqrt(e*e/t)}static getCascadesSplitDistance(t,r,a,n,i,s,o,l){l[0]=a;var h=n-a,_=Math.tan(.5*i),d=1+_*_*(s*s+1);switch(o){case e.ShadowCascadesMode.NoCascades:l[1]=ht.getFarWithRadius(n,d);break;case e.ShadowCascadesMode.TwoCascades:l[1]=ht.getFarWithRadius(a+h*t,d),l[2]=ht.getFarWithRadius(n,d);break;case e.ShadowCascadesMode.FourCascades:l[1]=ht.getFarWithRadius(a+h*r.x,d),l[2]=ht.getFarWithRadius(a+h*r.y,d),l[3]=ht.getFarWithRadius(a+h*r.z,d),l[4]=ht.getFarWithRadius(n,d)}}static applySliceTransform(e,t,r,a,n){var i=ht._tempMatrix0.elements,s=1/t,o=1/r;i[0]=e.resolution*s,i[5]=e.resolution*o,i[12]=e.offsetX*s,i[13]=e.offsetY*o,i[1]=i[2]=i[2]=i[4]=i[6]=i[7]=i[8]=i[9]=i[11]=i[14]=0,i[10]=i[15]=1;var l=16*a;A._mulMatrixArray(i,n,l,n,l)}static getDirectionLightShadowCullPlanes(t,r,a,n,s,o){var l=ht._frustumCorners,h=ht._backPlaneFaces,_=ht._frustumPlaneNeighbors,d=ht._frustumTwoPlaneCorners,c=ht._edgePlanePoint2,u=o.cullPlanes,m=t[Ie.Near],f=t[Ie.Far],E=t[Ie.Left],T=t[Ie.Right],p=t[Ie.Bottom],g=t[Ie.Top],S=a[r]-n,R=ht._adjustNearPlane,v=ht._adjustFarPlane;m.normal.cloneTo(R.normal),f.normal.cloneTo(v.normal),R.distance=m.distance-S,v.distance=Math.min(-m.distance+o.sphereCenterZ+o.splitBoundSphere.radius,f.distance),$e.get3PlaneInterPoint(R,p,T,l[e.FrustumCorner.nearBottomRight]),$e.get3PlaneInterPoint(R,g,T,l[e.FrustumCorner.nearTopRight]),$e.get3PlaneInterPoint(R,g,E,l[e.FrustumCorner.nearTopLeft]),$e.get3PlaneInterPoint(R,p,E,l[e.FrustumCorner.nearBottomLeft]),$e.get3PlaneInterPoint(v,p,T,l[e.FrustumCorner.FarBottomRight]),$e.get3PlaneInterPoint(v,g,T,l[e.FrustumCorner.FarTopRight]),$e.get3PlaneInterPoint(v,g,E,l[e.FrustumCorner.FarTopLeft]),$e.get3PlaneInterPoint(v,p,E,l[e.FrustumCorner.FarBottomLeft]);for(var x=0,A=0;A<6;A++){var I;switch(A){case Ie.Near:I=R;break;case Ie.Far:I=v;break;default:I=t[A]}i.dot(I.normal,s)<0&&(I.cloneTo(u[x]),h[x]=A,x++)}var M=x;for(A=0;Ac/u?(l=t,h=t*_):(l=.5*u*(1+d),h=.5*Math.sqrt(c*c+2*(t*t+e*e)*d+u*u*d*d));var m=o.center;return o.radius=h,i.scale(s,l,m),i.add(n,m,m),l}static getMaxTileResolutionInAtlas(e,t,r){for(var a=Math.min(e,t),n=Math.floor(e/a)*Math.floor(t/a);n>1),n=Math.floor(e/a)*Math.floor(t/a);return a}static getDirectionalLightMatrices(e,t,r,a,n,s,o,l){var h=o.splitBoundSphere,_=h.center,d=h.radius,c=s/2,u=d*c/(c-ht.atlasBorderSize),m=2*u,f=s/m,E=m/s,T=Math.ceil(i.dot(_,e)*f)*E,p=Math.ceil(i.dot(_,t)*f)*E,g=i.dot(_,r);_.x=e.x*T+t.x*p+r.x*g,_.y=e.y*T+t.y*p+r.y*g,_.z=e.z*T+t.z*p+r.z*g;var S=o.position,R=o.viewMatrix,v=o.projectionMatrix,x=o.viewProjectMatrix;o.resolution=s,o.offsetX=a%2*s,o.offsetY=Math.floor(a/2)*s,i.scale(r,d+n,S),i.subtract(_,S,S),B.createLookAt(S,_,e,R),B.createOrthoOffCenter(-u,u,-u,u,0,2*d+n,v),B.multiply(v,R,x),A._mulMatrixArray(ht._shadowMapScaleOffsetMatrix.elements,x.elements,0,l,16*a)}static getSpotLightShadowData(e,t,r,a,n,i){var s=e.position=t.transform.position;e.resolution=r,i.setValue(1/r,1/r,r,r),e.offsetX=0,e.offsetY=0;var o=t.lightWorldMatrix,l=e.viewMatrix,h=e.projectionMatrix,_=e.viewProjectMatrix,d=e.cameraCullInfo.boundFrustum;o.invert(l),B.createPerspective(3.1416*t.spotAngle/180,1,.1,t.range,h),a.y=t.shadowStrength,B.multiply(h,l,_),d.matrix=_,_.cloneTo(n),e.cameraCullInfo.position=s}static prepareShadowReceiverShaderValues(e,t,r,a,n,i,s,o,l){if(i.setValue(1/t,1/r,t,r),s.setValue(e._shadowStrength,0,0,0),n>1){const e=16;for(var h=n*e,_=4*e;h<_;h++)o[h]=0;for(h=0;h=.5?Math.floor(a):o,c=l-n>=.5?Math.floor(n):l,u=i-h>=.5?Math.ceil(i):h,m=s-_>=.5?Math.ceil(s):_;this._viewport.x=d,this._viewport.y=c,this._viewport.width=u-d,this._viewport.height=m-c}_calculateProjectionMatrix(){if(!this._useUserProjectionMatrix)if(this._orthographic){var e=.5*this.orthographicVerticalSize,t=e*this.aspectRatio;B.createOrthoOffCenter(-t,t,-e,e,this.nearPlane,this.farPlane,this._projectionMatrix)}else B.createPerspective(3.1416*this.fieldOfView/180,this.aspectRatio,this.nearPlane,this.farPlane,this._projectionMatrix)}_isLayerVisible(e){return 0!=(Math.pow(2,e)&this.cullingMask)}_onTransformChanged(e){(e&=J.TRANSFORM_WORLDMATRIX)&&(this._updateViewMatrix=!0)}_parse(e,t){super._parse(e,t);var r=e.clearFlag;void 0!==r&&(this.clearFlag=r);var a=e.viewport;this.normalizedViewport=new et(a[0],a[1],a[2],a[3]);var n=e.enableHDR;void 0!==n&&(this.enableHDR=n)}clone(){let e=super.clone();return e.clearFlag=this.clearFlag,e.viewport=this.viewport,this.normalizedViewport.cloneTo(e.normalizedViewport),e.enableHDR=this.enableHDR,e.farPlane=this.farPlane,e.nearPlane=this.nearPlane,e.fieldOfView=this.fieldOfView,e.orthographic=this.orthographic,e}_getCanvasWidth(){return this._offScreenRenderTexture?this._offScreenRenderTexture.width:N.clientWidth}_getCanvasHeight(){return this._offScreenRenderTexture?this._offScreenRenderTexture.height:N.clientHeight}_getRenderTexture(){return this._internalRenderTexture||this._offScreenRenderTexture}_needInternalRenderTexture(){return!!(this._postProcess&&this._postProcess.enable||this._enableHDR||this._needBuiltInRenderTexture)}_getRenderTextureFormat(){return this._enableHDR?t.RenderTextureFormat.R16G16B16A16:t.RenderTextureFormat.R8G8B8}_prepareCameraToRender(){super._prepareCameraToRender();var e=this.viewport;this._viewportParams.setValue(e.x,e.y,e.width,e.height),this._projectionParams.setValue(this._nearPlane,this._farPlane,N._instance.invertY?-1:1,1/this.farPlane),this._shaderValues.setVector(st.VIEWPORT,this._viewportParams),this._shaderValues.setVector(st.PROJECTION_PARAMS,this._projectionParams)}_applyViewProject(e,t,r){var a,n=this._shaderValues;e.invertY?(B.multiply(st._invertYScaleMatrix,r,st._invertYProjectionMatrix),B.multiply(st._invertYProjectionMatrix,t,st._invertYProjectionViewMatrix),r=st._invertYProjectionMatrix,a=st._invertYProjectionViewMatrix):(B.multiply(r,t,this._projectionViewMatrix),a=this._projectionViewMatrix),e.viewMatrix=t,e.projectionMatrix=r,e.projectionViewMatrix=a,n.setMatrix4x4(st.VIEWMATRIX,t),n.setMatrix4x4(st.PROJECTMATRIX,r),n.setMatrix4x4(st.VIEWPROJECTMATRIX,a)}_updateClusterPlaneXY(){var e=this.fieldOfView,t=this.aspectRatio;if(this._clusterPlaneCacheFlag.x!==e||this._clusterPlaneCacheFlag.y!==t){var r=d._config.lightClusterCount,a=r.x,n=r.y,s=a+1,o=n+1,l=this._clusterXPlanes,h=this._clusterYPlanes;if(!l){l=this._clusterXPlanes=new Array(s),h=this._clusterYPlanes=new Array(o);for(var _=0;_{e.cancelable&&e.preventDefault(),this._eventList.push(e)}).bind(this)}__init__(e,r){this._scene=r,_._bullet&&(ct._tempHitResult0=new t.HitResult),e.oncontextmenu=function(e){return!1}}_onCanvasEvent(e){e.addEventListener("mousedown",this._pushEventList),e.addEventListener("mouseup",this._pushEventList,!0),e.addEventListener("mousemove",this._pushEventList,!0),e.addEventListener("touchstart",this._pushEventList),e.addEventListener("touchend",this._pushEventList,!0),e.addEventListener("touchmove",this._pushEventList,!0),e.addEventListener("touchcancel",this._pushEventList,!0)}_offCanvasEvent(e){e.removeEventListener("mousedown",this._pushEventList),e.removeEventListener("mouseup",this._pushEventList,!0),e.removeEventListener("mousemove",this._pushEventList,!0),e.removeEventListener("touchstart",this._pushEventList),e.removeEventListener("touchend",this._pushEventList,!0),e.removeEventListener("touchmove",this._pushEventList,!0),e.removeEventListener("touchcancel",this._pushEventList,!0),this._eventList.length=0,this._touches.clear()}touchCount(){return this._touches.length}get multiTouchEnabled(){return this._multiTouchEnabled}set multiTouchEnabled(e){this._multiTouchEnabled=e}_getTouch(e,t){var r=this._touchPool[e];return 0==t&&r&&-1!=r._getIndexInList()||1==t&&r&&-1==r._getIndexInList()?null:(r||(r=new qe,this._touchPool[e]=r,r._identifier=e),r)}_mouseTouchDown(){var e=this._mouseTouch,r=e.sprite;if(e._pressedSprite=r,e._pressedLoopCount=t.Stat.loopCount,r){var a=r._scripts;if(a)for(var n=0,i=a.length;n=0;o--){var l=t[o],h=l.viewport;if(a.x>=h.x&&a.y>=h.y&&a.x<=h.width&&a.y<=h.height)if(l.viewportPointToRay(a,n),this._scene._physicsSimulation.rayCast(n,r)||l.clearFlag===e.CameraClearFlags.SolidColor||l.clearFlag===e.CameraClearFlags.Sky)break}var d=this._mouseTouch,c=d.sprite;if(r.succeeded){var u=r.collider.owner;d.sprite=u;var m=u._scripts;if(c!==u&&m)for(var f=0,E=m.length;f0){var o=!1;for(e=0;eu._pressedLoopCount){var f=m._scripts;if(f)for(a=0,n=f.length;a>i,1),Math.max(e>>i,1));this._setGPUMemory(e*e*4*(1+1/3)*6)}else this._mipmapCount=1,this._setGPUMemory(e*e*4*6)}static get blackTexture(){return ft._blackTexture}static get grayTexture(){return ft._grayTexture}static __init__(){var e=new ft(1,t.TextureFormat.R8G8B8,!1),r=new ft(1,t.TextureFormat.R8G8B8,!1),a=new Uint8Array(3);a[0]=0,a[1]=0,a[2]=0,e.setSixSidePixels([a,a,a,a,a,a]),e.lock=!0,a[0]=128,a[1]=128,a[2]=128,r.setSixSidePixels([a,a,a,a,a,a]),r.lock=!0,ft._grayTexture=r,ft._blackTexture=e}static _parse(e,t=null,r=null){var a=r?new ft(0,r[0],r[1]):new ft(0);return a.setSixSideImageSources(e),a}static _parseBin(e,t=null,r=null){var a=r?new ft(0,r[0],r[1]):new ft(0);return a.setSixSideImageSources(e),a}static load(e,r){var a=t.LoaderManager.createMap[t.Utils.getFilecompatibleExtension(e)]?t.Utils.getFilecompatibleExtension(e):t.Utils.getFileExtension(e),n=t.LoaderManager.createMap[a]?t.LoaderManager.createMap[a][0]:null;t.ILaya.loader.create(e,r,null,n)}get defaulteTexture(){return ft.grayTexture}_setPixels(e,r,a,n){var i=t.LayaGL.instance,s=this._getGLFormat();t.WebGLContext.bindTexture(i,this._glTextureType,this._glTexture),this.format===t.TextureFormat.R8G8B8?(i.pixelStorei(i.UNPACK_ALIGNMENT,1),i.texImage2D(i.TEXTURE_CUBE_MAP_POSITIVE_Z,r,s,a,n,0,s,i.UNSIGNED_BYTE,e[0]),i.texImage2D(i.TEXTURE_CUBE_MAP_NEGATIVE_Z,r,s,a,n,0,s,i.UNSIGNED_BYTE,e[1]),i.texImage2D(i.TEXTURE_CUBE_MAP_POSITIVE_X,r,s,a,n,0,s,i.UNSIGNED_BYTE,e[2]),i.texImage2D(i.TEXTURE_CUBE_MAP_NEGATIVE_X,r,s,a,n,0,s,i.UNSIGNED_BYTE,e[3]),i.texImage2D(i.TEXTURE_CUBE_MAP_POSITIVE_Y,r,s,a,n,0,s,i.UNSIGNED_BYTE,e[4]),i.texImage2D(i.TEXTURE_CUBE_MAP_NEGATIVE_Y,r,s,a,n,0,s,i.UNSIGNED_BYTE,e[5]),i.pixelStorei(i.UNPACK_ALIGNMENT,4)):(i.texImage2D(i.TEXTURE_CUBE_MAP_POSITIVE_Z,r,s,a,n,0,s,i.UNSIGNED_BYTE,e[0]),i.texImage2D(i.TEXTURE_CUBE_MAP_NEGATIVE_Z,r,s,a,n,0,s,i.UNSIGNED_BYTE,e[1]),i.texImage2D(i.TEXTURE_CUBE_MAP_POSITIVE_X,r,s,a,n,0,s,i.UNSIGNED_BYTE,e[2]),i.texImage2D(i.TEXTURE_CUBE_MAP_NEGATIVE_X,r,s,a,n,0,s,i.UNSIGNED_BYTE,e[3]),i.texImage2D(i.TEXTURE_CUBE_MAP_POSITIVE_Y,r,s,a,n,0,s,i.UNSIGNED_BYTE,e[4]),i.texImage2D(i.TEXTURE_CUBE_MAP_NEGATIVE_Y,r,s,a,n,0,s,i.UNSIGNED_BYTE,e[5]))}setSixSideImageSources(e,r=!1){for(var a,n,i=0;i<6;i++){var s=e[i];if(!s)return void console.log("TextureCube: image Source can't be null.");var o=s.width,l=s.height;if(i>0&&a!==o)return void console.log("TextureCube: each side image's width and height must same.");if((a=o)!==(n=l))return void console.log("TextureCube: each side image's width and height must same.")}this._width=a,this._height=n;var h=t.LayaGL.instance;t.WebGLContext.bindTexture(h,this._glTextureType,this._glTexture);var _=this._getGLFormat();if(t.Render.isConchApp){if(1==r)for(var d=0;d<6;d++)e[d].setPremultiplyAlpha(r);h.texImage2D(h.TEXTURE_CUBE_MAP_POSITIVE_Z,0,h.RGBA,h.RGBA,h.UNSIGNED_BYTE,e[0]),h.texImage2D(h.TEXTURE_CUBE_MAP_NEGATIVE_Z,0,h.RGBA,h.RGBA,h.UNSIGNED_BYTE,e[1]),h.texImage2D(h.TEXTURE_CUBE_MAP_POSITIVE_X,0,h.RGBA,h.RGBA,h.UNSIGNED_BYTE,e[2]),h.texImage2D(h.TEXTURE_CUBE_MAP_NEGATIVE_X,0,h.RGBA,h.RGBA,h.UNSIGNED_BYTE,e[3]),h.texImage2D(h.TEXTURE_CUBE_MAP_POSITIVE_Y,0,h.RGBA,h.RGBA,h.UNSIGNED_BYTE,e[4]),h.texImage2D(h.TEXTURE_CUBE_MAP_NEGATIVE_Y,0,h.RGBA,h.RGBA,h.UNSIGNED_BYTE,e[5])}else r&&h.pixelStorei(h.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),h.texImage2D(h.TEXTURE_CUBE_MAP_POSITIVE_Z,0,_,_,h.UNSIGNED_BYTE,e[0]),h.texImage2D(h.TEXTURE_CUBE_MAP_NEGATIVE_Z,0,_,_,h.UNSIGNED_BYTE,e[1]),h.texImage2D(h.TEXTURE_CUBE_MAP_POSITIVE_X,0,_,_,h.UNSIGNED_BYTE,e[2]),h.texImage2D(h.TEXTURE_CUBE_MAP_NEGATIVE_X,0,_,_,h.UNSIGNED_BYTE,e[3]),h.texImage2D(h.TEXTURE_CUBE_MAP_POSITIVE_Y,0,_,_,h.UNSIGNED_BYTE,e[4]),h.texImage2D(h.TEXTURE_CUBE_MAP_NEGATIVE_Y,0,_,_,h.UNSIGNED_BYTE,e[5]),r&&h.pixelStorei(h.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1);this._mipmap&&this._isPot(a)&&this._isPot(n)?(h.generateMipmap(this._glTextureType),this._setGPUMemory(a*n*4*(1+1/3)*6)):this._setGPUMemory(a*n*4*6),this._setWarpMode(h.TEXTURE_WRAP_S,this._wrapModeU),this._setWarpMode(h.TEXTURE_WRAP_T,this._wrapModeV),this._setFilterMode(this._filterMode),this._readyed=!0,this._activeResource()}setSixSidePixels(e,r=0){if(!e)throw new Error("TextureCube:pixels can't be null.");var a=Math.max(this._width>>r,1),n=Math.max(this._height>>r,1),i=a*n*this._getFormatByteCount();if(e[0].lengths.x||i.y>s.y||i.z>s.z?-1:(s.x-i.x)*(s.y-i.y)*(s.z-i.z)}cloneTo(e){var t=e;this.getMin().cloneTo(t._boundBox.min),this.getMax().cloneTo(t._boundBox.max),this.getCenter().cloneTo(t._center),this.getExtent().cloneTo(t._extent),t._updateFlag=0}clone(){var e=new St(new i,new i);return this.cloneTo(e),e}}St._UPDATE_MIN=1,St._UPDATE_MAX=2,St._UPDATE_CENTER=4,St._UPDATE_EXTENT=8,St.TEMP_VECTOR3_MAX0=new i,St.TEMP_VECTOR3_MAX1=new i;class Rt{constructor(){this._destroyed=!1}get destroyed(){return this._destroyed}_getType(){throw"GeometryElement:must override it."}_prepareRender(e){return!0}_render(e){throw"GeometryElement:must override it."}destroy(){this._destroyed||(this._destroyed=!0)}}Rt._typeCounter=0;class vt{constructor(){}static get vertexDeclaration(){return vt._vertexDeclaration}static __init__(){vt._vertexDeclaration=new U(28,[new H(0,V.Vector3,ie.MESH_POSITION0),new H(12,V.Vector4,ie.MESH_COLOR0)])}get vertexDeclaration(){return vt._vertexDeclaration}}class xt extends Rt{constructor(e,r){super(),this._floatCountPerVertices=7,this._minUpdate=Number.MAX_VALUE,this._maxUpdate=Number.MIN_VALUE,this._bufferState=new G,this._floatBound=new Float32Array(6),this._calculateBound=!1,this._maxLineCount=0,this._lineCount=0;var a=2*r;this._owner=e,this._maxLineCount=r,this._vertices=new Float32Array(a*this._floatCountPerVertices),this._vertexBuffer=new b(vt.vertexDeclaration.vertexStride*a,t.LayaGL.instance.STATIC_DRAW,!1),this._vertexBuffer.vertexDeclaration=vt.vertexDeclaration,this._bufferState.bind(),this._bufferState.applyVertexBuffer(this._vertexBuffer),this._bufferState.unBind();var n=xt._tempVector0,i=xt._tempVector1;n.setValue(Number.MAX_VALUE,Number.MAX_VALUE,Number.MAX_VALUE),i.setValue(-Number.MAX_VALUE,-Number.MAX_VALUE,-Number.MAX_VALUE),this._bounds=new St(n,i)}_getType(){return xt._type}_resizeLineData(e){var r=2*e,a=this._vertices;this._vertexBuffer.destroy(),this._maxLineCount=e;var n=r*this._floatCountPerVertices;this._vertices=new Float32Array(n),this._vertexBuffer=new b(vt.vertexDeclaration.vertexStride*r,t.LayaGL.instance.STATIC_DRAW,!1),this._vertexBuffer.vertexDeclaration=vt.vertexDeclaration,n0){this._bufferState.bind();var r=t.LayaGL.instance;r.drawArrays(r.LINES,0,2*this._lineCount),t.Stat.renderBatches++}}destroy(){this._destroyed||(super.destroy(),this._bufferState.destroy(),this._vertexBuffer.destroy(),this._bufferState=null,this._vertexBuffer=null,this._vertices=null)}}xt._tempVector0=new i,xt._tempVector1=new i,xt._type=Rt._typeCounter++;class At extends ${constructor(e){super(e)}static __init__(){At.SHADERDEFINE_RECEIVE_SHADOW=Z.getDefineByName("RECEIVESHADOW"),At.SAHDERDEFINE_LIGHTMAP=Z.getDefineByName("LIGHTMAP"),At.SHADERDEFINE_LIGHTMAP_DIRECTIONAL=Z.getDefineByName("LIGHTMAP_DIRECTIONAL")}_onInActive(){super._onInActive(),this._scene._removeRenderObject(this._render)}_onActive(){super._onActive(),this._scene._addRenderObject(this._render)}_onActiveInScene(){if(super._onActiveInScene(),h.Laya3D._editerEnvironment){var e=this._scene,t=new n;e._allotPickColorByID(this.id,t),e._pickIdToSprite[this.id]=this,this._render._shaderValues.setVector(At.PICKCOLOR,t)}}_addToInitStaticBatchManager(){}_setBelongScene(e){super._setBelongScene(e),this._render._setBelongScene(e)}_setUnBelongScene(){this.destroyed||(this._render._shaderValues.removeDefine(At.SAHDERDEFINE_LIGHTMAP),this._render._setUnBelongScene(),super._setUnBelongScene())}_changeHierarchyAnimator(e){if(this._hierarchyAnimator){var t=this._hierarchyAnimator._renderableSprites;t.splice(t.indexOf(this),1)}e&&e._renderableSprites.push(this),super._changeHierarchyAnimator(e)}destroy(e=!0){super.destroy(e),this._render._destroy(),this._render=null}_create(){return new At(this.name)}}At.LIGHTMAPSCALEOFFSET=Z.propertyNameToID("u_LightmapScaleOffset"),At.LIGHTMAP=Z.propertyNameToID("u_LightMap"),At.LIGHTMAP_DIRECTION=Z.propertyNameToID("u_LightMapDirection"),At.PICKCOLOR=Z.propertyNameToID("u_PickColor"),At.REFLECTIONTEXTURE=Z.propertyNameToID("u_ReflectTexture"),At.REFLECTIONCUBE_HDR_PARAMS=Z.propertyNameToID("u_ReflectCubeHDRParams"),At.REFLECTIONCUBE_PROBEPOSITION=Z.propertyNameToID("u_SpecCubeProbePosition"),At.REFLECTIONCUBE_PROBEBOXMAX=Z.propertyNameToID("u_SpecCubeBoxMax"),At.REFLECTIONCUBE_PROBEBOXMIN=Z.propertyNameToID("u_SpecCubeBoxMin");class It{constructor(){this.updateMark=-1,this.indexInList=-1,this.batched=!1}}class Mt extends Rt{constructor(){super(),this.instanceWorldMatrixData=new Float32Array(16*Mt.maxInstanceCount),this.instanceSimpleAnimatorData=new Float32Array(4*Mt.maxInstanceCount);var e=t.LayaGL.instance;this.instanceWorldMatrixBuffer=new b(4*this.instanceWorldMatrixData.length,e.DYNAMIC_DRAW),this.instanceWorldMatrixBuffer.vertexDeclaration=ie.instanceWorldMatrixDeclaration,this.instanceSimpleAnimatorBuffer=new b(4*this.instanceSimpleAnimatorData.length,e.DYNAMIC_DRAW),this.instanceSimpleAnimatorBuffer.vertexDeclaration=ie.instanceSimpleAnimatorDeclaration}static __init__(){Mt.instance=new Mt}_render(e){var r=t.LayaGL.instance,a=e.renderElement,n=a.instanceSubMesh,i=a.instanceBatchElementList.length,s=n._indexCount;n._mesh._instanceBufferState.bind(),t.LayaGL.layaGPUInstance.drawElementsInstanced(r.TRIANGLES,s,r.UNSIGNED_SHORT,2*n._indexStart,i),t.Stat.renderBatches++,t.Stat.savedRenderBatches+=i-1,t.Stat.trianglesFaces+=s*i/3}}Mt.maxInstanceCount=1024;class Dt{constructor(){this.renderSubShader=null,this.renderType=Dt.RENDERTYPE_NORMAL}getInvertFront(){return this._transform._isFrontFaceInvert}setTransform(e){this._transform=e}setGeometry(e){this._geometry=e}addToOpaqueRenderQueue(e,t){t.elements.add(this)}addToTransparentRenderQueue(e,t){t.elements.add(this),t.lastTransparentBatched=!1,t.lastTransparentRenderElement=this}_update(e,t,r,a,n=0){if(this.material){var i=this.material._shader.getSubShaderAt(0);if(this.renderSubShader=null,r)if(a){var s=i.getFlag(a);if(!s)return;for(var o=r._subShaders,l=0,h=o.length;l1,n=a?t._indexCount:r._vertexCount;if(n<=h.SubMeshDynamicBatch.maxAllowVertexCount){var i=3*n;this._dynamicVertexBatch=!0,this._dynamicWorldPositions=new Float32Array(i),this._dynamicWorldNormals=new Float32Array(i),this._dynamicVertexCount=n,this._dynamicMultiSubMesh=a}else this._dynamicVertexBatch=!1}this._geometry=e}}addToOpaqueRenderQueue(e,r){var a=this.staticBatch,n=r.elements,i=n.elements;if(a&&(!this.render._probReflection||this.render._probReflection._isScene)&&Lt.enableStaticBatch){var s=h.MeshRenderStaticBatchManager.instance,o=s.getBatchOpaquaMark(this.render.lightmapIndex+1,this.render.receiveShadow,this.material.id,a._batchID);if(s._updateCountMark===o.updateMark){var l=o.indexInList;if(o.batched)i[l].staticBatchElementList.add(this);else{var _=i[l],d=_.render,c=s._getBatchRenderElementFromPool();c.renderType=Dt.RENDERTYPE_STATICBATCH,c.setGeometry(a),c.material=_.material;var u=a.batchOwner,m=u?u._transform:null;c.setTransform(m),c.render=d,c.renderSubShader=_.renderSubShader;var f=c.staticBatchElementList;f.length=0,f.add(_),f.add(this),i[l]=c,o.batched=!0}}else o.updateMark=s._updateCountMark,o.indexInList=n.length,o.batched=!1,n.add(this)}else if(Lt.enableDynamicBatch&&this.renderSubShader._owner._enableInstancing&&t.LayaGL.layaGPUInstance.supportInstance()&&this.render.lightmapIndex<0&&(!this.render._probReflection||this.render._probReflection._isScene)){var E=this._geometry,T=h.MeshRenderDynamicBatchManager.instance,p=T.getInstanceBatchOpaquaMark(this.render.receiveShadow,this.material.id,E._id,this._transform._isFrontFaceInvert);if(T._updateCountMark===p.updateMark){var g=p.indexInList;if(p.batched){var S=i[g].instanceBatchElementList;S.length===Mt.maxInstanceCount?(p.updateMark=T._updateCountMark,p.indexInList=n.length,p.batched=!1,n.add(this)):S.add(this)}else{var R=i[g],v=R.render,x=T._getBatchRenderElementFromPool();x.renderType=Dt.RENDERTYPE_INSTANCEBATCH,x.setGeometry(Mt.instance),x.material=R.material,x.setTransform(null),x.render=v,x.instanceSubMesh=E,x.renderSubShader=R.renderSubShader;var A=x.instanceBatchElementList;A.length=0,A.add(R),A.add(this),i[g]=x,p.batched=!0}}else p.updateMark=T._updateCountMark,p.indexInList=n.length,p.batched=!1,n.add(this)}else if(this._dynamicVertexBatch&&Lt.enableDynamicBatch){var I=this._geometry._vertexBuffer.vertexDeclaration,M=h.MeshRenderDynamicBatchManager.instance,D=M.getVertexBatchOpaquaMark(this.render.lightmapIndex+1,this.render.receiveShadow,this.material.id,I.id);if(M._updateCountMark===D.updateMark){var L=D.indexInList;if(D.batched)i[L].vertexBatchElementList.add(this);else{var y=i[L],C=y.render,O=M._getBatchRenderElementFromPool();O.renderType=Dt.RENDERTYPE_VERTEXBATCH,O.setGeometry(h.SubMeshDynamicBatch.instance),O.material=y.material,O.setTransform(null),O.render=C,O.vertexBatchVertexDeclaration=I,O.renderSubShader=y.renderSubShader;var N=O.vertexBatchElementList;N.length=0,N.add(y),N.add(this),i[L]=O,D.batched=!0}}else D.updateMark=M._updateCountMark,D.indexInList=n.length,D.batched=!1,n.add(this)}else n.add(this)}addToTransparentRenderQueue(e,r){var a=this.staticBatch,n=r.elements,i=n.elements;if(a&&Lt.enableStaticBatch){var s=h.MeshRenderStaticBatchManager.instance,o=r.lastTransparentRenderElement;if(o){var l=o.render;if(o._geometry._getType()!==this._geometry._getType()||o.staticBatch!==a||o.material!==this.material||l.receiveShadow!==this.render.receiveShadow||l.lightmapIndex!==this.render.lightmapIndex)n.add(this),r.lastTransparentBatched=!1;else{if(r.lastTransparentBatched)i[n.length-1].staticBatchElementList.add(this);else{var _=s._getBatchRenderElementFromPool();_.renderType=Dt.RENDERTYPE_STATICBATCH,_.setGeometry(a),_.material=o.material;var d=a.batchOwner,c=d?d._transform:null;_.setTransform(c),_.render=this.render,_.renderSubShader=o.renderSubShader;var u=_.staticBatchElementList;u.length=0,u.add(o),u.add(this),i[n.length-1]=_}r.lastTransparentBatched=!0}}else n.add(this),r.lastTransparentBatched=!1}else if(Lt.enableDynamicBatch&&this.renderSubShader._owner._enableInstancing&&t.LayaGL.layaGPUInstance.supportInstance()&&this.render.lightmapIndex<0&&(!this.render._probReflection||this.render._probReflection._isScene)){var m=this._geometry,f=h.MeshRenderDynamicBatchManager.instance,E=r.lastTransparentRenderElement;if(E){var T=E.render;if(E._geometry._getType()!==this._geometry._getType()||E._geometry!==m||E.material!==this.material||T.receiveShadow!==this.render.receiveShadow)n.add(this),r.lastTransparentBatched=!1;else if(r.lastTransparentBatched){var p=i[n.length-1].instanceBatchElementList;p.length===Mt.maxInstanceCount?(n.add(this),r.lastTransparentBatched=!1):(p.add(this),r.lastTransparentBatched=!0)}else{var g=f._getBatchRenderElementFromPool();g.renderType=Dt.RENDERTYPE_INSTANCEBATCH,g.setGeometry(Mt.instance),g.material=E.material,g.setTransform(null),g.render=this.render,g.instanceSubMesh=m,g.renderSubShader=E.renderSubShader;var S=g.instanceBatchElementList;S.length=0,S.add(E),S.add(this),i[n.length-1]=g,r.lastTransparentBatched=!0}}else n.add(this),r.lastTransparentBatched=!1}else if(this._dynamicVertexBatch&&Lt.enableDynamicBatch){var R=this._geometry._vertexBuffer.vertexDeclaration,v=h.MeshRenderDynamicBatchManager.instance,x=r.lastTransparentRenderElement;if(x){var A=x.render;if(x._dynamicVertexBatch&&x._geometry._getType()===this._geometry._getType()&&x._geometry._vertexBuffer._vertexDeclaration===R&&x.material===this.material&&A.receiveShadow===this.render.receiveShadow&&A.lightmapIndex===this.render.lightmapIndex){if(r.lastTransparentBatched)i[n.length-1].vertexBatchElementList.add(this);else{var I=v._getBatchRenderElementFromPool();I.renderType=Dt.RENDERTYPE_VERTEXBATCH,I.setGeometry(h.SubMeshDynamicBatch.instance),I.material=x.material,I.setTransform(null),I.render=this.render,I.vertexBatchVertexDeclaration=R,I.renderSubShader=x.renderSubShader;var M=I.vertexBatchElementList;M.length=0,M.add(x),M.add(this),i[n.length-1]=I}r.lastTransparentBatched=!0}else n.add(this),r.lastTransparentBatched=!1}else n.add(this),r.lastTransparentBatched=!1}else n.add(this);r.lastTransparentRenderElement=this}getInvertFront(){switch(this.renderType){case Dt.RENDERTYPE_NORMAL:return this._transform._isFrontFaceInvert;case Dt.RENDERTYPE_STATICBATCH:case Dt.RENDERTYPE_VERTEXBATCH:return!1;case Dt.RENDERTYPE_INSTANCEBATCH:return this.instanceBatchElementList.elements[0]._transform._isFrontFaceInvert;default:throw"SubMeshRenderElement: unknown renderType"}}destroy(){super.destroy(),this._dynamicWorldPositions=null,this._dynamicWorldNormals=null,this.staticBatch=null,this.staticBatchElementList=null,this.vertexBatchElementList=null,this.vertexBatchVertexDeclaration=null}}Lt.enableDynamicBatch=!0,Lt.enableStaticBatch=!0;class yt{constructor(){this._initBatchSprites=[],this._staticBatches={},this._batchRenderElementPoolIndex=0,this._batchRenderElementPool=[]}static _addToStaticBatchQueue(e,t){e instanceof At&&t.push(e);for(var r=0,a=e.numChildren;r0){for(var a=0;a0;)r--;if(t1){var a=this._partition(e,t,r),n=a-1;tCt.maxBatchVertexCount)}add(e){var t=e.meshFilter.sharedMesh,r=t.vertexCount;this._batchElements.push(e);var a=e._render;a._isPartOfStaticBatch=!0,a._staticBatch=this;for(var n=a._renderElements,i=0,s=n.length;i=0&&rthis.maxLineCount)throw"PixelLineSprite3D: lineCount can't large than maxLineCount";this._geometryFilter._lineCount=e}get pixelLineRenderer(){return this._render}_onInActive(){t.Stat.spriteCount--,0!=this._geometryFilter._lineCount&&this._isRenderActive&&(this._scene._removeRenderObject(this._render),this._isInRenders=!1),this._isRenderActive=!1}_onActive(){t.Stat.spriteCount++,this._isRenderActive=!0,0!=this._geometryFilter._lineCount&&(this._scene._addRenderObject(this._render),this._isInRenders=!0)}_changeRenderObjects(e,t){var r=this._render._renderElements;t||(t=pt.defaultMaterial);var a=r[e];a||(a=r[e]=new Dt),a.setTransform(this._transform),a.setGeometry(this._geometryFilter),a.render=this._render,a.material=t}addLine(e,t,r,a){if(this._geometryFilter._lineCount===this._geometryFilter._maxLineCount)throw"PixelLineSprite3D: lineCount has equal with maxLineCount.";this._geometryFilter._updateLineData(this._geometryFilter._lineCount++,e,t,r,a),this._isRenderActive&&!this._isInRenders&&this._geometryFilter._lineCount>0&&(this._scene._addRenderObject(this._render),this._isInRenders=!0)}addLines(e){var t=this._geometryFilter._lineCount,r=e.length;if(t+r>this._geometryFilter._maxLineCount)throw"PixelLineSprite3D: lineCount plus lines count must less than maxLineCount.";this._geometryFilter._updateLineDatas(t,e),this._geometryFilter._lineCount+=r,this._isRenderActive&&!this._isInRenders&&this._geometryFilter._lineCount>0&&(this._scene._addRenderObject(this._render),this._isInRenders=!0)}removeLine(e){if(!(e0;)t--;if(e1){var r=this._partitionRenderObject(e,t),a=r-1;e=0;a--){var n=r[a];this._objects.push(n),n._setOctreeNode(this)}}}this._children=null}_merge(){if(null===this._children){var e=this._parent;e&&e._shouldMerge()&&(e._mergeChildren(),e._merge())}}_checkAddNode(e){if(null==this._children){if(this._objects.length=0;t--){var r=this._objects[t],a=this._bestFitChild(r.bounds.getCenter());Bt._encapsulates(this._getChildBound(a),r.bounds._getBoundBox())&&(this._objects.splice(this._objects.indexOf(r),1),this._getChild(a)._add(r))}}var n=this._bestFitChild(e.bounds.getCenter());return Bt._encapsulates(this._getChildBound(n),e.bounds._getBoundBox())?this._getChild(n)._checkAddNode(e):this}_add(e){var t=this._checkAddNode(e);t._objects.push(e),e._setOctreeNode(t)}_remove(e){var t=this._objects.indexOf(e);this._objects.splice(t,1),e._setOctreeNode(null),this._merge()}_addUp(e){return Je.boxContainsBox(this._bounds,e.bounds._getBoundBox())===Ke.Contains?(this._add(e),!0):!!this._parent&&this._parent._addUp(e)}_getCollidingWithFrustum(e,r,a,n,s,o){var l=e.boundFrustum,h=e.position,_=e.cullingMask;if(a){var d=l.containsBoundBox(this._bounds);if(t.Stat.octreeNodeCulling++,d===Ke.Disjoint){for(var c=0,u=this._objects.length;c=this.center.y?0:4)+(e.z<=this.center.z?0:2)}_update(e){if(Je.boxContainsBox(this._bounds,e.bounds._getBoundBox())===Ke.Contains){var t=this._checkAddNode(e);if(t!==e._getOctreeNode()){t._objects.push(e),e._setOctreeNode(t);var r=this._objects.indexOf(e);this._objects.splice(r,1),this._merge()}return!0}if(this._parent){var a=this._parent._addUp(e);return a&&(r=this._objects.indexOf(e),this._objects.splice(r,1),this._merge()),a}return!1}add(e){return!!Bt._encapsulates(this._bounds,e.bounds._getBoundBox())&&(this._add(e),!0)}remove(e){return e._getOctreeNode()===this&&(this._remove(e),!0)}update(e){return e._getOctreeNode()===this&&this._update(e)}shrinkIfPossible(e){if(this.baseLength<2*e)return this;for(var t=-1,r=0,a=this._objects.length;r=0&&t!=r)return this;l=!0,t=r}}if(-1!=t){var _=this._children[t];return _._parent=null,_}return this}hasAnyObjects(){if(this._objects.length>0)return!0;if(null!=this._children)for(var e=0;e<8;e++){var t=this._children[e];if(t&&t.hasAnyObjects())return!0}return!1}getCollidingWithBoundBox(e,t){this._getCollidingWithBoundBox(e,!0,t)}getCollidingWithRay(e,t,r=Number.MAX_VALUE){var a=Je.intersectsRayAndBoxRD(e,this._bounds);if(!(-1==a||a>r)){for(var n=0,i=this._objects.length;nt)return!1;for(var a=0,n=this._objects.length;ae&&(console.warn("Minimum node size must be at least as big as the initial world size. Was: "+r+" Adjusted to: "+e),r=e),this._initialSize=e,this._minSize=r,this._looseness=Math.min(Math.max(a,1),2),this._rootNode=new Bt(this,null,e,t)}_getMaxDepth(e,t){t++;var r=e._children;if(null!=r)for(var a=t,n=0,i=r.length;n=0?1:-1,r=e.y>=0?1:-1,a=e.z>=0?1:-1,n=this._rootNode,s=this._rootNode.baseLength/2,o=2*this._rootNode.baseLength,l=this._rootNode.center,h=new i(l.x+t*s,l.y+r*s,l.z+a*s);if(this._rootNode=new Bt(this,null,o,h),n.hasAnyObjects()){for(var _=this._rootNode._bestFitChild(n.center),d=[],c=0;c<8;c++)c==_&&(n._parent=this._rootNode,d[c]=n);this._rootNode._children=d}}add(e){for(var t=0;!this._rootNode.add(e);){var r=Ut._tempVector30;if(i.subtract(e.bounds.getCenter(),this._rootNode.center,r),this._grow(r),++t>20)throw"Aborted Add operation as it seemed to be going on forever ("+(t-1)+") attempts at growing the octree."}this.count++}remove(e){var t=e._getOctreeNode().remove(e);return t&&this.count--,t}update(e){var t=0,r=e._getOctreeNode();if(r){for(;!r._update(e);){var a=Ut._tempVector30;if(i.subtract(e.bounds.getCenter(),this._rootNode.center,a),this._grow(a),++t>20)throw"Aborted Add operation as it seemed to be going on forever ("+(t-1)+") attempts at growing the octree."}return!0}return!1}shrinkRootIfPossible(){this._rootNode=this._rootNode.shrinkIfPossible(this._initialSize)}addMotionObject(e){this._motionObjects.add(e)}removeMotionObject(e){this._motionObjects.remove(e)}updateMotionObjects(){for(var e=this._motionObjects.elements,t=0,r=this._motionObjects.length;t=e.length)throw new Error("start"+t+"Must be in the range [0, "+(e.length-1)+"]");if(r<0||t+r>e.length)throw new Error("count"+r+"Must be in the range <= "+e.length+"}");var n=t+r,s=Gt._tempVector3;s.x=0,s.y=0,s.z=0;for(var o=t;oh&&(h=_)}a.radius=Math.sqrt(h)}static createfromPoints(e,t){if(null==e)throw new Error("points");Gt.createFromSubPoints(e,0,e.length,t)}intersectsRayDistance(e){return Je.intersectsRayAndSphereRD(e,this)}intersectsRayPoint(e,t){return Je.intersectsRayAndSphereRP(e,this,t)}cloneTo(e){var t=e;this.center.cloneTo(t.center),t.radius=this.radius}clone(){var e=new Gt(new i,0);return this.cloneTo(e),e}}Gt._tempVector3=new i;class zt{constructor(){this.cameraShaderValue=new F,this.position=new i,this.viewMatrix=new B,this.projectionMatrix=new B,this.viewProjectMatrix=new B,this.cullPlanes=[new je(new i),new je(new i),new je(new i),new je(new i),new je(new i),new je(new i),new je(new i),new je(new i),new je(new i),new je(new i)],this.splitBoundSphere=new Gt(new i,0)}}class kt{constructor(){this.cameraShaderValue=new F,this.position=new i,this.viewMatrix=new B,this.projectionMatrix=new B,this.viewProjectMatrix=new B,this.cameraCullInfo=new Ge}}(Oe=e.ShadowLightType||(e.ShadowLightType={}))[Oe.DirectionLight=0]="DirectionLight",Oe[Oe.SpotLight=1]="SpotLight",Oe[Oe.PointLight=2]="PointLight";class Wt{constructor(){this._shadowBias=new n,this._shadowParams=new n,this._shadowMapSize=new n,this._shadowSpotMapSize=new n,this._shadowMatrices=new Float32Array(16*Wt._maxCascades),this._shadowSpotMatrices=new B,this._splitBoundSpheres=new Float32Array(4*Wt._maxCascades),this._cascadeCount=0,this._shadowMapWidth=0,this._shadowMapHeight=0,this._shadowSliceDatas=[new zt,new zt,new zt,new zt],this._shadowSpotData=new kt,this._lightUp=new i,this._lightSide=new i,this._lightForward=new i,this._shadowSpotData.cameraCullInfo.boundFrustum=new $e(new B)}_setupShadowCasterShaderValues(t,r,a,n,i,s,o){switch(r.setVector(Wt.SHADOW_BIAS,s),o){case e.LightType.Directional:r.setVector3(Wt.SHADOW_LIGHT_DIRECTION,n);break;case e.LightType.Spot:r.setVector(Wt.SHADOW_PARAMS,i);break;case e.LightType.Point:}var l=a.cameraShaderValue;l.setMatrix4x4(st.VIEWMATRIX,a.viewMatrix),l.setMatrix4x4(st.PROJECTMATRIX,a.projectionMatrix),l.setMatrix4x4(st.VIEWPROJECTMATRIX,a.viewProjectMatrix),t.viewMatrix=a.viewMatrix,t.projectionMatrix=a.projectionMatrix,t.projectionViewMatrix=a.viewProjectMatrix}_setupShadowReceiverShaderValues(t){var r=this._light;switch(r.shadowCascadesMode!==e.ShadowCascadesMode.NoCascades?t.addDefine(ot.SHADERDEFINE_SHADOW_CASCADE):t.removeDefine(ot.SHADERDEFINE_SHADOW_CASCADE),r.shadowMode){case e.ShadowMode.Hard:t.removeDefine(ot.SHADERDEFINE_SHADOW_SOFT_SHADOW_LOW),t.removeDefine(ot.SHADERDEFINE_SHADOW_SOFT_SHADOW_HIGH);break;case e.ShadowMode.SoftLow:t.addDefine(ot.SHADERDEFINE_SHADOW_SOFT_SHADOW_LOW),t.removeDefine(ot.SHADERDEFINE_SHADOW_SOFT_SHADOW_HIGH);break;case e.ShadowMode.SoftHigh:t.addDefine(ot.SHADERDEFINE_SHADOW_SOFT_SHADOW_HIGH),t.removeDefine(ot.SHADERDEFINE_SHADOW_SOFT_SHADOW_LOW)}t.setTexture(Wt.SHADOW_MAP,this._shadowDirectLightMap),t.setBuffer(Wt.SHADOW_MATRICES,this._shadowMatrices),t.setVector(Wt.SHADOW_MAP_SIZE,this._shadowMapSize),t.setVector(Wt.SHADOW_PARAMS,this._shadowParams),t.setBuffer(Wt.SHADOW_SPLIT_SPHERES,this._splitBoundSpheres)}_setupSpotShadowReceiverShaderValues(t){switch(this._light.shadowMode){case e.ShadowMode.Hard:t.removeDefine(ot.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_HIGH),t.removeDefine(ot.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_LOW);break;case e.ShadowMode.SoftLow:t.addDefine(ot.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_LOW),t.removeDefine(ot.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_HIGH);break;case e.ShadowMode.SoftHigh:t.addDefine(ot.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_HIGH),t.removeDefine(ot.SHADERDEFINE_SHADOW_SPOT_SOFT_SHADOW_LOW)}t.setTexture(Wt.SHADOW_SPOTMAP,this._shadowSpotLightMap),t.setMatrix4x4(Wt.SHADOW_SPOTMATRICES,this._shadowSpotMatrices),t.setVector(Wt.SHADOW_SPOTMAP_SIZE,this._shadowSpotMapSize),t.setVector(Wt.SHADOW_PARAMS,this._shadowParams)}update(t,a,n){switch(n){case e.ShadowLightType.DirectionLight:this._light=a;var s=(I=Wt._tempMatrix0).elements,o=this._lightUp,l=this._lightSide,h=this._lightForward;B.createFromQuaternion(a._transform.rotation,I),l.setValue(s[0],s[1],s[2]),o.setValue(s[4],s[5],s[6]),h.setValue(-s[8],-s[9],-s[10]);var _,d,c,u,m=a._shadowResolution,f=a._shadowCascadesMode;f==e.ShadowCascadesMode.NoCascades?(_=1,d=m,c=m,u=m):(_=f==e.ShadowCascadesMode.TwoCascades?2:4,c=2*(d=ht.getMaxTileResolutionInAtlas(m,m,_)),u=f==e.ShadowCascadesMode.TwoCascades?d:2*d),this._cascadeCount=_,this._shadowMapWidth=c,this._shadowMapHeight=u;var E=Wt._cascadesSplitDistance,T=Wt._frustumPlanes,p=t.nearPlane,g=Math.min(t.farPlane,a._shadowDistance),S=this._shadowMatrices,R=this._splitBoundSpheres;ht.getCascadesSplitDistance(a._shadowTwoCascadeSplits,a._shadowFourCascadeSplits,p,g,t.fieldOfView*r.Deg2Rad,t.aspectRatio,f,E),ht.getCameraFrustumPlanes(t.projectionViewMatrix,T);var v=Wt._tempVector30;t._transform.getForward(v),i.normalize(v,v);for(var x=0;x<_;x++){var A=this._shadowSliceDatas[x];A.sphereCenterZ=ht.getBoundSphereByFrustum(E[x],E[x+1],t.fieldOfView*r.Deg2Rad,t.aspectRatio,t._transform.position,v,A.splitBoundSphere),ht.getDirectionLightShadowCullPlanes(T,x,E,p,h,A),ht.getDirectionalLightMatrices(o,l,h,x,a._shadowNearPlane,d,A,S),_>1&&ht.applySliceTransform(A,c,u,x,S)}ht.prepareShadowReceiverShaderValues(a,c,u,this._shadowSliceDatas,_,this._shadowMapSize,this._shadowParams,S,R);break;case e.ShadowLightType.SpotLight:this._light=a;var I=Wt._tempMatrix0,M=(h=this._lightForward,this._light._shadowResolution);this._shadowMapWidth=M,this._shadowMapHeight=M;var D=this._shadowSpotData;ht.getSpotLightShadowData(D,this._light,M,this._shadowParams,this._shadowSpotMatrices,this._shadowSpotMapSize);break;case e.ShadowLightType.PointLight:break;default:throw"There is no shadow of this type"}}render(r,a,n){switch(n){case e.ShadowLightType.DirectionLight:var i=a._shaderValues;r.pipelineMode="ShadowCaster",F.setRuntimeValueMode(!1),(E=this._shadowDirectLightMap=ht.getTemporaryShadowTexture(this._shadowMapWidth,this._shadowMapHeight,t.RenderTextureDepthFormat.DEPTH_16))._start();for(var s=this._light,o=0,l=this._cascadeCount;ol.importance)continue;if((r=i.calculateBoundsintersection(l.bounds))e._renderingOrder?a=t-1:r=t+1}return r}_allotPickColorByID(e,t){var r=Math.floor(e/65025);e-=255*r*255;var a=Math.floor(e/255),n=e-=255*a;t.x=r/255,t.y=a/255,t.z=n/255,t.w=1}_searchIDByPickColor(e){return 255*e.x*255+255*e.y+e.z}onEnable(){this._input._onCanvasEvent(t.Render.canvas)}onDisable(){this._input._offCanvasEvent(t.Render.canvas)}_setCreateURL(e){this._url=t.URL.formatURL(e)}_getGroup(){return this._group}_setGroup(e){this._group=e}_clearScript(){if(this._needClearScriptPool){for(var e=this._scriptPool,t=0,r=e.length;t0){var o=this._directionLights.getBrightestLight();this._mainDirectionLight=s[o],this._directionLights.normalLightOrdering(o);for(var l=0;l0){var m=this._pointLights._elements,f=this._pointLights.getBrightestLight();this._mainPointLight=m[f],this._pointLights.normalLightOrdering(f);for(l=0;l0){var p=this._spotLights._elements,g=this._spotLights.getBrightestLight();this._mainSpotLight=p[g],this._spotLights.normalLightOrdering(g);for(l=0;l0&&t.setSubPixels(0,0,d,a,r,0),e.setTexture(qt.LIGHTBUFFER,t),e.setInt(qt.DIRECTIONLIGHTCOUNT,this._directionLights._length),e.setTexture(qt.CLUSTERBUFFER,Xe.instance._clusterTexture)}else{if(this._directionLights._length>0){var R=this._directionLights._elements[0];this._mainDirectionLight=R,i.scale(R.color,R._intensity,R._intensityColor),R.transform.worldMatrix.getForward(R._direction),i.normalize(R._direction,R._direction),e.setVector3(qt.LIGHTDIRCOLOR,R._intensityColor),e.setVector3(qt.LIGHTDIRECTION,R._direction),e.setVector3(qt.SUNLIGHTDIRCOLOR,R._intensityColor),e.setVector3(qt.SUNLIGHTDIRECTION,R._direction),e.addDefine(ot.SHADERDEFINE_DIRECTIONLIGHT)}else e.removeDefine(ot.SHADERDEFINE_DIRECTIONLIGHT);if(this._pointLights._length>0){var v=this._pointLights._elements[0];this._mainPointLight=v,i.scale(v.color,v._intensity,v._intensityColor),e.setVector3(qt.POINTLIGHTCOLOR,v._intensityColor),e.setVector3(qt.POINTLIGHTPOS,v.transform.position),e.setNumber(qt.POINTLIGHTRANGE,v.range),e.addDefine(ot.SHADERDEFINE_POINTLIGHT)}else e.removeDefine(ot.SHADERDEFINE_POINTLIGHT);if(this._spotLights._length>0){var x=this._spotLights._elements[0];this._mainSpotLight=x,i.scale(x.color,x._intensity,x._intensityColor),e.setVector3(qt.SPOTLIGHTCOLOR,x._intensityColor),e.setVector3(qt.SPOTLIGHTPOS,x.transform.position),x.transform.worldMatrix.getForward(x._direction),i.normalize(x._direction,x._direction),e.setVector3(qt.SPOTLIGHTDIRECTION,x._direction),e.setNumber(qt.SPOTLIGHTRANGE,x.range),e.setNumber(qt.SPOTLIGHTSPOTANGLE,x.spotAngle*Math.PI/180),e.addDefine(ot.SHADERDEFINE_SPOTLIGHT)}else e.removeDefine(ot.SHADERDEFINE_SPOTLIGHT)}}_addScript(e){if(-1==e._indexInPool){var t=this._scriptPool;e._indexInPool=t.length,t.push(e)}}_removeScript(e){-1!=e._indexInPool&&(this._scriptPool[e._indexInPool]=null,e._indexInPool=-1,this._needClearScriptPool=!0)}_preRenderScript(){for(var e=this._scriptPool,t=0,r=e.length;t0&&e.addRenderObject(this)}renderSubmit(){var e,r,a;for(t.PerformancePlugin.begainSample(t.PerformancePlugin.PERFORMANCE_LAYA_3D),this._prepareSceneToRender(),t.PerformancePlugin.begainSample(t.PerformancePlugin.PERFORMANCE_LAYA_3D_RENDER),e=0,a=(r=this._cameraPool.length)-1;e=0&&(l=l.substr(0,d)),s=u||new t.ShaderNode(n),u=null,s.text=l,s.noCompile=!0,(d=l.indexOf("#"))>=0){for(h="#",E=d+1,f=l.length;E]/),s.noCompile?console.log("function():Boolean{return "+l.substr(d+s.name.length)+"}"):(c=l.replace(/^\s*/,"").split(/\s+/),s.setCondition(c[1],"#ifdef"===h?t.ShaderCompile.IFDEF_YES:t.ShaderCompile.IFDEF_ELSE),s.text="//"+s.text),s.setParent(e),e=s,i)for(c=l.substr(E).split(t.ShaderCompile._splitToWordExps3),E=0;E0&&t.ShaderCompile.splitToWords(l,o),u=s,o.text+="\n"+l;continue}n.length>0&&t.ShaderCompile.splitToWords(l,s)}s.setParent(e)}}_resizeCacheShaderMap(e,t,r){var a=this._cacheShaderHierarchy-1;if(t==a)for(var n in e)for(var i=e[n],s=0,o=r-a;sthis._cacheShaderHierarchy&&(this._resizeCacheShaderMap(i,0,s),this._cacheShaderHierarchy=s);for(var o=e._mask,l=e._length-1,h=this._cacheShaderHierarchy-1,_=0;_lr.maxIndicesCount&&(this._flush(i,s),o++,t.Stat.trianglesFaces+=s/3,i=s=0);var m=d._transform;this._getBatchVertices(a,this._vertices,i,d,c),this._getBatchIndices(this._indices,s,i,m,c,d._dynamicMultiSubMesh),i+=d._dynamicVertexCount,s+=u}this._flush(i,s),o++,t.Stat.renderBatches+=o,t.Stat.savedRenderBatches+=l-o,t.Stat.trianglesFaces+=s/3}}lr.maxAllowVertexCount=10,lr.maxAllowAttribueCount=900,lr.maxIndicesCount=32e3;class hr extends Xt{constructor(){super(),this._instanceBatchOpaqueMarks=[],this._vertexBatchOpaqueMarks=[],this._cacheBufferStates=[],this._updateCountMark=0}getInstanceBatchOpaquaMark(e,t,r,a){var n=this._instanceBatchOpaqueMarks[e?0:1]||(this._instanceBatchOpaqueMarks[e?0:1]=[]),i=n[t]||(n[t]=[]),s=i[r]||(i[r]=[]);return s[a?1:0]||(s[a?1:0]=new It)}getVertexBatchOpaquaMark(e,t,r,a){var n=this._vertexBatchOpaqueMarks[e]||(this._vertexBatchOpaqueMarks[e]=[]),i=n[t?0:1]||(n[t?0:1]=[]),s=i[r]||(i[r]=[]);return s[a]||(s[a]=new It)}_getBufferState(e){var t=this._cacheBufferStates[e.id];if(!t){var r=lr.instance;(t=new G).bind();var a=r._vertexBuffer;a.vertexDeclaration=e,t.applyVertexBuffer(a),t.applyIndexBuffer(r._indexBuffer),t.unBind(),this._cacheBufferStates[e.id]=t}return t}_getBatchRenderElementFromPool(){var e=this._batchRenderElementPool[this._batchRenderElementPoolIndex++];return e||(e=new Lt,this._batchRenderElementPool[this._batchRenderElementPoolIndex-1]=e,e.vertexBatchElementList=new Fe,e.instanceBatchElementList=new Fe),e}_clear(){super._clear(),this._updateCountMark++}}hr.instance=new hr;class _r extends At{constructor(e=null,t=null){super(t),this._meshFilter=new or(this),this._render=new sr(this),e&&(this._meshFilter.sharedMesh=e)}static __init__(){ne.SHADERDEFINE_UV0=Z.getDefineByName("UV"),ne.SHADERDEFINE_COLOR=Z.getDefineByName("COLOR"),ne.SHADERDEFINE_UV1=Z.getDefineByName("UV1"),ne.SHADERDEFINE_GPU_INSTANCE=Z.getDefineByName("GPU_INSTANCE"),ne.SHADERDEFINE_SPECCUBE_BOX_PROJECTION=Z.getDefineByName("SPECCUBE_BOX_PROJECTION"),yt._registerManager(Ot.instance),Xt._registerManager(hr.instance)}get meshFilter(){return this._meshFilter}get meshRenderer(){return this._render}_parse(e,r){super._parse(e,r);var a=this.meshRenderer,i=e.lightmapIndex;null!=i&&(a.lightmapIndex=i);var s=e.lightmapScaleOffset;s&&(a.lightmapScaleOffset=new n(s[0],s[1],s[2],s[3])),null!=e.meshPath&&(this.meshFilter.sharedMesh=t.Loader.getRes(e.meshPath)),null!=e.enableRender&&(a.enable=e.enableRender),null!=e.receiveShadows&&(a.receiveShadow=e.receiveShadows),null!=e.castShadow&&(a.castShadow=e.castShadow);var o=e.materials;if(o){var l=a.sharedMaterials,h=o.length;l.length=h;for(var _=0;_=0;s--){var o=4*s;if(e===(u=n[o]))return t.r=n[o+1],t.g=n[o+2],t.b=n[o+3],i;switch(this._mode){case dr.Blend:if(e>u){if(e>(c=n[o+4]))throw"Gradient:wrong startSearchIndex.";var l=c-u,h=c-e,_=e-u;return t.r=(h*n[o+1]+_*n[o+5])/l,t.g=(h*n[o+2]+_*n[o+6])/l,t.b=(h*n[o+3]+_*n[o+7])/l,i}i--;continue;case dr.Fixed:if(e>u){if(e>n[o+4])throw"Gradient:wrong startSearchIndex.";return t.r=n[o+5],t.g=n[o+6],t.b=n[o+7],i}i--;continue;default:throw"Gradient:unknown mode."}}else{s=0;for(var d=this._rgbElements.length;s=0;s--){if(e===(u=n[d=2*s]))return t.a=n[d+1],i;switch(this._mode){case dr.Blend:if(e>u){if(e>(c=n[d+2]))throw"Gradient:wrong startSearchIndex.";var o=c-u,l=c-e,h=e-u;return t.a=(l*n[d+1]+h*n[d+3])/o,i}i--;continue;case dr.Fixed:if(e>u){if(e>n[d+2])throw"Gradient:wrong startSearchIndex.";return t.a=n[d+3],i}i--;continue;default:throw"Gradient:unknown mode."}}else{s=i;for(var _=this._alphaElements.length;s<_;s++){var d,c;if(e===(c=n[d=2*s]))return t.a=n[d+1],i;switch(this._mode){case dr.Blend:if(e>>15}get seed(){return this.seeds[0]}set seed(e){this.seeds[0]=e,this.seeds[1]=1812433253*this.seeds[0]+1,this.seeds[2]=1812433253*this.seeds[1]+1,this.seeds[3]=1812433253*this.seeds[2]+1}getUint(){return this._temp[0]=this.seeds[0]^this.seeds[0]<<11,this.seeds[0]=this.seeds[1],this.seeds[1]=this.seeds[2],this.seeds[2]=this.seeds[3],this.seeds[3]=this.seeds[3]^this.seeds[3]>>>19^this._temp[0]^this._temp[0]>>>8,this.seeds[3]}getFloat(){return this.getUint(),(8388607&this.seeds[3])*(1/8388607)}getSignedFloat(){return 2*this.getFloat()-1}}class zr{constructor(){this._emissionRate=10,this._destroyed=!1,this._bursts=[]}set emissionRate(e){if(e<0)throw new Error("ParticleBaseShape:emissionRate value must large or equal than 0.");this._emissionRate=e}get emissionRate(){return this._emissionRate}get destroyed(){return this._destroyed}destroy(){this._bursts=null,this._destroyed=!0}getBurstsCount(){return this._bursts.length}getBurstByIndex(e){return this._bursts[e]}addBurst(e){var t=this._bursts.length;if(t>0)for(var r=0;re.time&&this._bursts.splice(r,0,e);this._bursts.push(e)}removeBurst(e){var t=this._bursts.indexOf(e);-1!==t&&this._bursts.splice(t,1)}removeBurstByIndex(e){this._bursts.splice(e,1)}clearBurst(){this._bursts.length=0}cloneTo(e){var t=e,r=t._bursts;r.length=this._bursts.length;for(var a=0,n=this._bursts.length;a=r){var s=e.getKeyByIndex(a-1),o=(r-s)/(i-s);return t.MathUtil.lerp(e.getValueByIndex(a-1),e.getValueByIndex(a),o)}}throw new Error("ShurikenParticleData: can't get value foam startLifeTimeGradient.")}static _randomInvertRoationArray(e,t,r,a,n){var i;a?(a.seed=n[6],i=a.getFloat(),n[6]=a.seed):i=Math.random(),i=this._firstRetiredElement?this._firstNewElement-this._firstRetiredElement:this._bufferMaxParticles-this._firstRetiredElement+this._firstNewElement}get emissionTime(){return this._emissionTime>this.duration?this.duration:this._emissionTime}get shape(){return this._shape}set shape(e){this._shape!==e&&(e&&e.enable?this._owner._render._shaderValues.addDefine(wr.SHADERDEFINE_SHAPE):this._owner._render._shaderValues.removeDefine(wr.SHADERDEFINE_SHAPE),this._shape=e)}get isAlive(){return!!(this._isPlaying||this.aliveParticleCount>0)}get isEmitting(){return this._isEmitting}get isPlaying(){return this._isPlaying}get isPaused(){return this._isPaused}get startLifetimeType(){return this._startLifetimeType}set startLifetimeType(e){var t,r;switch(this.startLifetimeType){case 0:this._maxStartLifetime=this.startLifetimeConstant;break;case 1:this._maxStartLifetime=-Number.MAX_VALUE;var a=a;for(t=0,r=a.gradientCount;t0?(i.scale(l,s,L),i.scale(h,s,y)):(i.scale(l,-s,y),i.scale(h,-s,L)),this.velocityOverLifetime&&this.velocityOverLifetime.enable){var C=this.velocityOverLifetime.velocity,O=Wr._tempVector37;switch(O.setValue(0,0,0),C.type){case 0:C.constant.cloneTo(O);break;case 2:C.constantMax.cloneTo(O);break;case 1:var N=C.gradientX.getAverageValue(),P=C.gradientY.getAverageValue(),w=C.gradientZ.getAverageValue();O.setValue(N,P,w);break;case 3:var b=C.gradientXMax.getAverageValue(),V=C.gradientYMax.getAverageValue(),B=C.gradientZMax.getAverageValue();O.setValue(b,V,B)}1==this.velocityOverLifetime.space&&i.transformV3ToV3(O,this._owner.transform.worldMatrix,O),i.add(L,O,L),i.subtract(y,O,y),i.max(L,i._ZERO,L),i.max(y,i._ZERO,y)}i.scale(L,n,L),i.scale(y,n,y);var F=this.gravityModifier;if(0!=F){var U=.5*Wr.g*F*n*n,H=L.y-U,G=y.y+U;H=H>0?H:0,G=G>0?G:0,this._gravityOffset.setValue(L.y-H,G-y.y)}i.add(L,I,a),i.add(a,_,a),i.add(y,I,r),i.add(r,d,r),i.scale(r,-1,r),this._bounds.setMin(r),this._bounds.setMax(a)}get customBounds(){return this._customBounds}set customBounds(e){this._useCustomBounds=!!e,this._customBounds=e}_simulationSupported(){return 0!=this.simulationSpace}_updateEmission(){if(this.isAlive)if(this._simulateUpdate)this._simulateUpdate=!1;else{var e=this._startUpdateLoopCount===t.Stat.loopCount||this._isPaused?0:this._owner._scene.timer._delta/1e3;e=Math.min(Wr._maxElapsedTime,e*this.simulationSpeed),this._updateParticles(e)}}_updateParticles(e){(4!==this._ownerRender.renderMode||this._ownerRender.mesh)&&(this._currentTime+=e,this._retireActiveParticles(),this._freeRetiredParticles(),this._totalDelayTime+=e,this._totalDelayTime=this._bufferMaxParticles&&(this._firstActiveElement=0)}}_freeRetiredParticles(){for(;this._firstRetiredElement!=this._firstActiveElement;){this._drawCounter,this._vertices[this._firstRetiredElement*this._floatCountPerVertex*this._vertexStride+this._timeIndex];this._firstRetiredElement++,this._firstRetiredElement>=this._bufferMaxParticles&&(this._firstRetiredElement=0)}}_burst(e,r){for(var a=0,n=this._emission._bursts,i=n.length;this._burstsIndexthis.duration){if(!this.looping){for(n=Math.min(this.maxParticles-this.aliveParticleCount,n),r=0;r0){var s=1/i;for(this._frameRateTime+=s,this._frameRateTime=this._currentTime-(this._currentTime-this._frameRateTime)%this._maxStartLifetime;this._frameRateTime<=t&&this.emit(this._frameRateTime);)this._frameRateTime+=s;this._frameRateTime=Math.floor(t/s)*s}}_initBufferDatas(){if(this._vertexBuffer){var r=this._vertexBuffer._byteLength+2*this._indexBuffer.indexCount;this._vertexBuffer.destroy(),this._indexBuffer.destroy(),t.Resource._addMemory(-r,-r)}var a=t.LayaGL.instance,n=this._ownerRender,i=n.renderMode;if(-1!==i&&this.maxParticles>0){var s,o,l,h,_,d,c,u=0,m=(r=0,n.mesh);if(4===i){if(m){c=Hr.vertexDeclaration,this._floatCountPerVertex=c.vertexStride/4,this._startLifeTimeIndex=12,this._timeIndex=16,this._vertexStride=m._vertexCount;var f=this._bufferMaxParticles*this._vertexStride,E=f%65535;if(Math.floor(f/65535)+1>1)throw new Error("ShurikenParticleSystem:the maxParticleCount multiply mesh vertexCount is large than 65535.");u=c.vertexStride*E,this._vertexBuffer=new b(u,a.DYNAMIC_DRAW),this._vertexBuffer.vertexDeclaration=c,this._vertices=new Float32Array(this._floatCountPerVertex*E),this._indexStride=m._indexBuffer.indexCount;var T=m._indexBuffer.getData(),p=this._bufferMaxParticles*this._indexStride;for(this._indexBuffer=new rt(e.IndexFormat.UInt16,p,a.STATIC_DRAW),s=new Uint16Array(p),r=u+2*p,_=0,o=0;o=this._bufferMaxParticles&&(n=0),n===this._firstRetiredElement)return!1;var s,o,l,h,_,d,c,u,m,f,E=this._owner.transform;if(kr.create(this,this._ownerRender),this._currentTime-a>=kr.startLifeTime)return!0;switch(0==this.simulationSpace&&(s=E.position,o=E.rotation),this.startSpeedType){case 0:l=this.startSpeedConstant;break;case 2:this.autoRandomSeed?l=t.MathUtil.lerp(this.startSpeedConstantMin,this.startSpeedConstantMax,Math.random()):(this._rand.seed=this._randomSeeds[8],l=t.MathUtil.lerp(this.startSpeedConstantMin,this.startSpeedConstantMax,this._rand.getFloat()),this._randomSeeds[8]=this._rand.seed)}var T=this._velocityOverLifetime&&this._velocityOverLifetime.enable;if(T){var p=this._velocityOverLifetime.velocity.type;2===p||3===p?this.autoRandomSeed?(h=Math.random(),_=Math.random(),d=Math.random()):(this._rand.seed=this._randomSeeds[9],h=this._rand.getFloat(),_=this._rand.getFloat(),d=this._rand.getFloat(),this._randomSeeds[9]=this._rand.seed):T=!1}else T=!1;var g=this._colorOverLifetime&&this._colorOverLifetime.enable;g?3===this._colorOverLifetime.color.type?this.autoRandomSeed?c=Math.random():(this._rand.seed=this._randomSeeds[10],c=this._rand.getFloat(),this._randomSeeds[10]=this._rand.seed):g=!1:g=!1;var S=this._sizeOverLifetime&&this._sizeOverLifetime.enable;S?3===this._sizeOverLifetime.size.type?this.autoRandomSeed?u=Math.random():(this._rand.seed=this._randomSeeds[11],u=this._rand.getFloat(),this._randomSeeds[11]=this._rand.seed):S=!1:S=!1;var R=this._rotationOverLifetime&&this._rotationOverLifetime.enable;if(R){var v=this._rotationOverLifetime.angularVelocity.type;2===v||3===v?this.autoRandomSeed?m=Math.random():(this._rand.seed=this._randomSeeds[12],m=this._rand.getFloat(),this._randomSeeds[12]=this._rand.seed):R=!1}else R=!1;var x=this._textureSheetAnimation&&this._textureSheetAnimation.enable;x?3===this._textureSheetAnimation.frame.type?this.autoRandomSeed?f=Math.random():(this._rand.seed=this._randomSeeds[15],f=this._rand.getFloat(),this._randomSeeds[15]=this._rand.seed):x=!1:x=!1;var A,I,M,D,L,y,C=this._firstFreeElement*this._floatCountPerVertex*this._vertexStride,O=kr.startUVInfo[0],N=kr.startUVInfo[1],P=kr.startUVInfo[2],w=kr.startUVInfo[3],b=this._ownerRender;if(4===b.renderMode){var V=b.mesh._vertexBuffer;A=V.getFloat32Data();var B=V.vertexDeclaration;M=B.getVertexElementByUsage(ie.MESH_POSITION0)._offset/4;var F=B.getVertexElementByUsage(ie.MESH_COLOR0);D=F?F._offset/4:-1;var U=B.getVertexElementByUsage(ie.MESH_TEXTURECOORDINATE0);L=U?U._offset/4:-1,I=B.vertexStride/4,y=0}else{this._vertices[C+2]=P,this._vertices[C+3]=w+N;var H=C+this._floatCountPerVertex;this._vertices[H+2]=P+O,this._vertices[H+3]=w+N;var G=H+this._floatCountPerVertex;this._vertices[G+2]=P+O,this._vertices[G+3]=w;var z=G+this._floatCountPerVertex;this._vertices[z+2]=P,this._vertices[z+3]=w}for(var k=C,W=C+this._floatCountPerVertex*this._vertexStride;k0&&this._vertexBuffer.setData(this._vertices.buffer,0,0,this._firstFreeElement*t)),this._firstNewElement=this._firstFreeElement}_getType(){return Wr._type}_prepareRender(e){return this._updateMask!=t.Stat.loopCount&&(this._updateMask=t.Stat.loopCount,this._updateEmission(),this._firstNewElement!=this._firstFreeElement&&this.addNewParticlesToVertexBuffer(),this._drawCounter++),this._firstActiveElement!=this._firstFreeElement}_render(e){var r;this._bufferState.bind();var a=t.LayaGL.instance;this._firstActiveElement0&&(r=this._firstFreeElement*this._indexStride,a.drawElements(a.TRIANGLES,r,a.UNSIGNED_SHORT,0),t.Stat.trianglesFaces+=r/3,t.Stat.renderBatches++))}play(){if(this._burstsIndex=0,this._isEmitting=!0,this._isPlaying=!0,this._isPaused=!1,this._emissionTime=0,this._totalDelayTime=0,!this.autoRandomSeed)for(var e=0,r=this._randomSeeds.length;e4&&(r=a-1,console.warn("GradientDataColor warning:alpha data length is large than 4, will ignore the middle data."));var i=n[r];t.addColorAlpha(i.key,i.value)}else t.addColorAlpha(0,1),t.addColorAlpha(1,1);var s=e.rgbs;if(s)for(r=0,a=s.length;r4&&(r=a-1,console.warn("GradientDataColor warning:rgb data length is large than 4, will ignore the middle data."));var o=s[r],l=o.value;t.addColorRGB(o.key,new He(l[0],l[1],l[2],1))}else t.addColorRGB(0,new He(1,1,1,1)),t.addColorRGB(1,new He(1,1,1,1))}else t.addColorAlpha(0,1),t.addColorAlpha(1,1),t.addColorRGB(0,new He(1,1,1,1)),t.addColorRGB(1,new He(1,1,1,1));return t}_initParticleFrame(e){var t=new pr;if(e)for(var r=e.frames,a=0,n=r.length;a=r.zeroTolerance?(this._isTempEndVertex?(h=this._endIndex-1,_=d-this._subDistance[h],this._updateVerticesByPosition(a,s,d,h),this._owner._totalLength+=_):(this._endIndex===this._segementCount&&this._resetData(),this._updateVerticesByPosition(a,s,d,this._endIndex),this._owner._totalLength+=d,this._endIndex++),a.cloneTo(this._lastFixedVertexPosition),this._isTempEndVertex=!1):(this._isTempEndVertex?(h=this._endIndex-1,_=d-this._subDistance[h],this._updateVerticesByPosition(a,s,d,h),this._owner._totalLength+=_):(this._endIndex===this._segementCount&&this._resetData(),this._updateVerticesByPosition(a,s,d,this._endIndex),this._owner._totalLength+=d,this._endIndex++),this._isTempEndVertex=!0)}_updateVerticesByPositionData(e,t,r){var a=2*this._floatCountPerVertices1*r,n=this._owner._curtime;this._vertices1[a]=e.x,this._vertices1[a+1]=e.y,this._vertices1[a+2]=e.z,this._vertices1[a+3]=-t.x,this._vertices1[a+4]=-t.y,this._vertices1[a+5]=-t.z,this._vertices1[a+6]=n,this._vertices1[a+7]=1,this._vertices1[a+8]=e.x,this._vertices1[a+9]=e.y,this._vertices1[a+10]=e.z,this._vertices1[a+11]=t.x,this._vertices1[a+12]=t.y,this._vertices1[a+13]=t.z,this._vertices1[a+14]=n,this._vertices1[a+15]=0;var s=this._owner._owner.trailRenderer.bounds,o=s.getMin(),l=s.getMax(),h=Jr._tempVector35,_=Jr._tempVector36,d=Jr._tempVector32;i.add(e,t,h),i.subtract(e,t,_),i.min(_,h,d),i.min(o,d,o),s.setMin(o),i.max(h,_,d),i.max(l,d,l),s.setMax(l);var c=2*this._floatCountPerVertices1;this._vertexBuffer1.setData(this._vertices1.buffer,4*a,4*a,4*c)}_updateVerticesByPosition(e,t,r,a){this._updateVerticesByPositionData(e,t,a),this._subDistance[a]=r,this._subBirthTime[a]=this._owner._curtime}_updateVertexBufferUV(){var e,t,r;if(this._disappearBoundsMode){e=this._owner._owner.trailRenderer.bounds;var a=this._owner._owner.transform.position;e.setMin(a),e.setMax(a),t=e.getMin(),r=e.getMax()}for(var n=this._endIndex,s=0,o=this._owner.colorGradient,l=o.colorAlphaKeysCount-1,h=o.colorRGBKeysCount-1,_=this._owner._totalLength,d=2*this._floatCountPerVertices2,c=this._activeIndex;c=this._owner.time+r.zeroTolerance;t++){var a=t+1;if(a!==e&&(this._owner._totalLength-=this._subDistance[a]),this._isTempEndVertex&&a===e-1){var n=this._lastFixedVertexPosition;n.x=this._vertices1[0],n.y=this._vertices1[1],n.z=this._vertices1[2],this._isTempEndVertex=!1}this._activeIndex++,this._disappearBoundsMode=!0}}_getType(){return Jr._type}_prepareRender(e){return this._endIndex-this._activeIndex>1}_render(e){this._bufferState.bind();var r=t.LayaGL.instance,a=2*this._activeIndex,n=2*this._endIndex-a;r.drawArrays(r.TRIANGLE_STRIP,a,n),t.Stat.renderBatches++,t.Stat.trianglesFaces+=n-2}destroy(){super.destroy();var e=this._vertexBuffer1._byteLength+this._vertexBuffer2._byteLength;t.Resource._addMemory(-e,-e),this._bufferState.destroy(),this._vertexBuffer1.destroy(),this._vertexBuffer2.destroy(),this._bufferState=null,this._vertices1=null,this._vertexBuffer1=null,this._vertices2=null,this._vertexBuffer2=null,this._subBirthTime=null,this._subDistance=null,this._lastFixedVertexPosition=null,this._disappearBoundsMode=!1}clear(){this._activeIndex=0,this._endIndex=0,this._disappearBoundsMode=!1,this._subBirthTime.fill(0),this._subDistance.fill(0),this._segementCount=0,this._isTempEndVertex=!1,this._needAddFirstVertex=!1,this._lastFixedVertexPosition.setValue(0,0,0)}}Jr.ALIGNMENT_VIEW=0,Jr.ALIGNMENT_TRANSFORM_Z=1,Jr._tempVector30=new i,Jr._tempVector31=new i,Jr._tempVector32=new i,Jr._tempVector33=new i,Jr._tempVector34=new i,Jr._tempVector35=new i,Jr._tempVector36=new i,Jr._type=Rt._typeCounter++;class $r{constructor(e){this._totalLength=0,this._lastPosition=new i,this._curtime=0,this.alignment=$r.ALIGNMENT_VIEW,this._owner=e,this._initDefaultData(),this.addRenderElement()}get time(){return this._time}set time(e){this._time=e,this._owner._render._shaderValues.setNumber($r.LIFETIME,e)}get minVertexDistance(){return this._minVertexDistance}set minVertexDistance(e){this._minVertexDistance=e}get widthMultiplier(){return this._widthMultiplier}set widthMultiplier(e){this._widthMultiplier=e}get widthCurve(){return this._widthCurve}set widthCurve(e){this._widthCurve=e;var t,r,a=new Float32Array(4*e.length),n=0;for(t=0,r=e.length;t 3)// out of shadow range cascadeIndex is 4.\r\n\t\t\t\treturn vec4(0.0);\r\n\t\t\t\r\n\t\t\t#ifdef GRAPHICS_API_GLES3\r\n\t\t\t\treturn u_ShadowMatrices[cascadeIndex] * positionWS;\r\n\t\t\t#else\r\n\t\t\t\tmat4 shadowMat;\r\n\t\t\t\tif(cascadeIndex == 0)\r\n\t\t\t\t\tshadowMat = u_ShadowMatrices[0];\r\n\t\t\t\telse if(cascadeIndex == 1)\r\n\t\t\t\t\tshadowMat = u_ShadowMatrices[1];\r\n\t\t\t\telse if(cascadeIndex == 2)\r\n\t\t\t\t\tshadowMat = u_ShadowMatrices[2];\r\n\t\t\t\telse\r\n\t\t\t\t\tshadowMat = u_ShadowMatrices[3];\r\n\t\t\t\treturn shadowMat * positionWS;\r\n\t\t\t#endif\r\n\t\t#else\r\n\t\t\treturn u_ShadowMatrices[0] * positionWS;\r\n\t\t#endif\r\n\t}\r\n\r\n\tfloat sampleShadowmap(vec4 shadowCoord)\r\n\t{\r\n\t\tshadowCoord.xyz /= shadowCoord.w;\r\n\t\tfloat attenuation = 1.0;\r\n\t\tif(shadowCoord.z > 0.0 && shadowCoord.z < 1.0)\r\n\t\t{\r\n\t\t\t#if defined(SHADOW_SOFT_SHADOW_HIGH)\r\n\t\t\t\tattenuation = sampleShdowMapFiltered9(u_ShadowMap,shadowCoord.xyz,u_ShadowMapSize);\r\n\t\t\t#elif defined(SHADOW_SOFT_SHADOW_LOW)\r\n\t\t\t\tattenuation = sampleShdowMapFiltered4(u_ShadowMap,shadowCoord.xyz,u_ShadowMapSize);\r\n\t\t\t#else\r\n\t\t\t\tattenuation = SAMPLE_TEXTURE2D_SHADOW(u_ShadowMap,shadowCoord.xyz);\r\n\t\t\t#endif\r\n\t\t\tattenuation = mix(1.0,attenuation,u_ShadowParams.x);//shadowParams.x:shadow strength\r\n\t\t}\r\n\t\treturn attenuation;\r\n\t}\r\n#endif\r\n\r\n#if defined(CALCULATE_SPOTSHADOWS)//shader���Զ���ĺ겻����ifdef ����ij�if defined\r\n\tTEXTURE2D_SHADOW(u_SpotShadowMap);\r\n\tuniform mat4 u_SpotViewProjectMatrix;\r\n\tfloat sampleSpotShadowmap(vec4 shadowCoord)\r\n\t{\r\n\t\tshadowCoord.xyz /= shadowCoord.w;\r\n\t\tfloat attenuation = 1.0;\r\n\t\tshadowCoord.xy +=1.0;\r\n\t\tshadowCoord.xy/=2.0; \r\n\t\tif(shadowCoord.z > 0.0 && shadowCoord.z < 1.0)\r\n\t\t{\r\n\t\t\t#if defined(SHADOW_SPOT_SOFT_SHADOW_HIGH)\r\n\t\t\t\tattenuation = sampleShdowMapFiltered9(u_SpotShadowMap,shadowCoord.xyz,u_SpotShadowMapSize);\r\n\t\t\t#elif defined(SHADOW_SPOT_SOFT_SHADOW_LOW)\r\n\t\t\t\tattenuation = sampleShdowMapFiltered4(u_SpotShadowMap,shadowCoord.xyz,u_SpotShadowMapSize);\r\n\t\t\t#else\r\n\t\t\t\tattenuation = SAMPLE_TEXTURE2D_SHADOW(u_SpotShadowMap,shadowCoord.xyz);\r\n\t\t\t#endif\r\n\t\t\tattenuation = mix(1.0,attenuation,u_ShadowParams.y);//shadowParams.y:shadow strength\r\n\t\t}\r\n\t\treturn attenuation;\r\n\t}\r\n#endif\r\n\r\nvec3 applyShadowBias(vec3 positionWS, vec3 normalWS, vec3 lightDirection)\r\n{\r\n float invNdotL = 1.0 - clamp(dot(-lightDirection, normalWS),0.0,1.0);\r\n float scale = invNdotL * u_ShadowBias.y;\r\n\r\n // normal bias is negative since we want to apply an inset normal offset\r\n positionWS += -lightDirection * u_ShadowBias.xxx;\r\n positionWS += normalWS * vec3(scale);\r\n return positionWS;\r\n}\r\n'),Z.addInclude("ShadowCasterVS.glsl",'#include "Lighting.glsl";\r\n#include "LayaUtile.glsl"\r\n#include "Shadow.glsl"\r\n\r\nattribute vec4 a_Position;\r\nattribute vec3 a_Normal;\r\n\r\n#ifdef BONE\r\n\tconst int c_MaxBoneCount = 24;\r\n\tattribute vec4 a_BoneIndices;\r\n\tattribute vec4 a_BoneWeights;\r\n\tuniform mat4 u_Bones[c_MaxBoneCount];\r\n#endif\r\n\r\n#ifdef GPU_INSTANCE\r\n\tattribute mat4 a_WorldMat;\r\n#else\r\n\tuniform mat4 u_WorldMat;\r\n#endif\r\n\r\nuniform mat4 u_ViewProjection;\r\n\r\n#ifdef SHADOW\r\n\tuniform vec3 u_ShadowLightDirection;\r\n#endif\r\n\r\n\r\nvec4 shadowCasterVertex()\r\n{\r\n\tmat4 worldMat;\r\n\t#ifdef GPU_INSTANCE\r\n\t\tworldMat = a_WorldMat;\r\n\t#else\r\n\t\tworldMat = u_WorldMat;\r\n\t#endif\r\n\t\r\n\t#ifdef BONE\r\n\t\tmat4 skinTransform;\r\n\t \t#ifdef SIMPLEBONE\r\n\t\t\tfloat currentPixelPos;\r\n\t\t\t#ifdef GPU_INSTANCE\r\n\t\t\t\tcurrentPixelPos = a_SimpleTextureParams.x+a_SimpleTextureParams.y;\r\n\t\t\t#else\r\n\t\t\t\tcurrentPixelPos = u_SimpleAnimatorParams.x+u_SimpleAnimatorParams.y;\r\n\t\t\t#endif\r\n\t\t\tfloat offset = 1.0/u_SimpleAnimatorTextureSize;\r\n\t\t\tskinTransform = loadMatFromTexture(currentPixelPos,int(a_BoneIndices.x),offset) * a_BoneWeights.x;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.y),offset) * a_BoneWeights.y;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.z),offset) * a_BoneWeights.z;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.w),offset) * a_BoneWeights.w;\r\n\t\t#else\r\n\t\t\tskinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;\r\n\t\t#endif\r\n\t\tworldMat = worldMat * skinTransform;\r\n\t#endif\r\n\r\n\tvec4 positionWS = worldMat * a_Position;\r\n\tmat3 worldInvMat;\r\n\t#ifdef BONE\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat*skinTransform));\r\n\t#else\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat));\r\n\t#endif \r\n\r\n\tvec3 normalWS = normalize(a_Normal*worldInvMat);//if no normalize will cause precision problem\r\n\tvec4 positionCS = u_ViewProjection * positionWS;\r\n\t#ifdef SHADOW\r\n\t\tpositionWS.xyz = applyShadowBias(positionWS.xyz,normalWS,u_ShadowLightDirection);\r\n\t\tpositionCS.z = max(positionCS.z, 0.0);//min ndc z is 0.0\r\n\t#endif\r\n\r\n\t\r\n\t#ifdef SHADOW_SPOT\r\n\t\tpositionCS.z = positionCS.z-u_ShadowBias.x/positionCS.w;\r\n\t\tpositionCS.z = max(positionCS.z, 0.0);//min ndc z is 0.0\r\n\t#endif\r\n\t\r\n\t\r\n\t// //TODO没考虑UV动画呢\r\n\t// #if defined(DIFFUSEMAP)&&defined(ALPHATEST)\r\n\t// \tv_Texcoord0=a_Texcoord0;\r\n\t// #endif\r\n return positionCS;\r\n}\r\n'),Z.addInclude("ShadowCasterFS.glsl","vec4 shadowCasterFragment()\r\n{\r\n return vec4(0.0);\r\n}\r\n"),Z.addInclude("Colors.glsl",'#include "StdLib.glsl";\r\n\r\n#define EPSILON 1.0e-4\r\n\r\n// Quadratic color thresholding\r\n// curve = (threshold - knee, knee * 2, 0.25 / knee)\r\nmediump vec4 quadraticThreshold(mediump vec4 color, mediump float threshold, mediump vec3 curve) {\r\n\t// Pixel brightness\r\n\tmediump float br = max3(color.r, color.g, color.b);\r\n\r\n\t// Under-threshold part: quadratic curve\r\n\tmediump float rq = clamp(br - curve.x, 0.0, curve.y);\r\n\trq = curve.z * rq * rq;\r\n\r\n\t// Combine and apply the brightness response curve.\r\n\tcolor *= max(rq, br - threshold) / max(br, EPSILON);\r\n\r\n\treturn color;\r\n}\r\n\r\n\r\n\r\n//\r\n// sRGB transfer functions\r\n// Fast path ref: http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1\r\n//\r\nmediump vec3 sRGBToLinear(mediump vec3 c) {\r\n\t#ifdef USE_VERY_FAST_SRGB\r\n\t\treturn c * c;\r\n\t#elif defined(USE_FAST_SRGB)\r\n\t\treturn c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878);\r\n\t#else\r\n\t\tmediump vec3 linearRGBLo = c / 12.92;\r\n\t\tmediump vec3 power=vec3(2.4, 2.4, 2.4);\r\n\t\tmediump vec3 linearRGBHi = positivePow((c + 0.055) / 1.055, power);\r\n\t\tmediump vec3 linearRGB =vec3((c.r<=0.04045) ? linearRGBLo.r : linearRGBHi.r,(c.g<=0.04045) ? linearRGBLo.g : linearRGBHi.g,(c.b<=0.04045) ? linearRGBLo.b : linearRGBHi.b);\r\n\t\treturn linearRGB;\r\n\t#endif\r\n}\r\n\r\nmediump vec4 sRGBToLinear(mediump vec4 c){\r\n return vec4(sRGBToLinear(c.rgb), c.a);\r\n}\r\n\r\n\r\n\r\nmediump vec3 linearToSRGB(mediump vec3 c) {\r\n\t#ifdef USE_VERY_FAST_SRGB\r\n\t\treturn sqrt(c);\r\n\t#elif defined(USE_FAST_SRGB)\r\n\t\treturn max(1.055 * PositivePow(c, 0.416666667) - 0.055, 0.0);\r\n\t#else\r\n\t\tmediump vec3 sRGBLo = c * 12.92;\r\n\t\tmediump vec3 power=vec3(1.0 / 2.4, 1.0 / 2.4, 1.0 / 2.4);\r\n\t\tmediump vec3 sRGBHi = (positivePow(c, power) * 1.055) - 0.055;\r\n\t\tmediump vec3 sRGB =vec3((c.r<=0.0031308) ? sRGBLo.r : sRGBHi.r,(c.g<=0.0031308) ? sRGBLo.g : sRGBHi.g,(c.b<=0.0031308) ? sRGBLo.b : sRGBHi.b);\r\n\t\treturn sRGB;\r\n\t#endif\r\n}\r\n\r\nmediump vec4 linearToSRGB(mediump vec4 c){\r\n return vec4(linearToSRGB(c.rgb), c.a);\r\n}'),Z.addInclude("Sampling.glsl","// Better, temporally stable box filtering\r\n// [Jimenez14] http://goo.gl/eomGso\r\n// . . . . . . .\r\n// . A . B . C .\r\n// . . D . E . .\r\n// . F . G . H .\r\n// . . I . J . .\r\n// . K . L . M .\r\n// . . . . . . .\r\nmediump vec4 downsampleBox13Tap(sampler2D tex, vec2 uv, vec2 texelSize)\r\n{\r\n mediump vec4 A = texture2D(tex, uv + texelSize * vec2(-1.0, -1.0));\r\n mediump vec4 B = texture2D(tex, uv + texelSize * vec2( 0.0, -1.0));\r\n mediump vec4 C = texture2D(tex, uv + texelSize * vec2( 1.0, -1.0));\r\n mediump vec4 D = texture2D(tex, uv + texelSize * vec2(-0.5, -0.5));\r\n mediump vec4 E = texture2D(tex, uv + texelSize * vec2( 0.5, -0.5));\r\n mediump vec4 F = texture2D(tex, uv + texelSize * vec2(-1.0, 0.0));\r\n mediump vec4 G = texture2D(tex, uv);\r\n mediump vec4 H = texture2D(tex, uv + texelSize * vec2( 1.0, 0.0));\r\n mediump vec4 I = texture2D(tex, uv + texelSize * vec2(-0.5, 0.5));\r\n mediump vec4 J = texture2D(tex, uv + texelSize * vec2( 0.5, 0.5));\r\n mediump vec4 K = texture2D(tex, uv + texelSize * vec2(-1.0, 1.0));\r\n mediump vec4 L = texture2D(tex, uv + texelSize * vec2( 0.0, 1.0));\r\n mediump vec4 M = texture2D(tex, uv + texelSize * vec2( 1.0, 1.0));\r\n\r\n\tmediump vec2 scale= vec2(0.5, 0.125);\r\n mediump vec2 div = (1.0 / 4.0) * scale;\r\n\r\n mediump vec4 o = (D + E + I + J) * div.x;\r\n o += (A + B + G + F) * div.y;\r\n o += (B + C + H + G) * div.y;\r\n o += (F + G + L + K) * div.y;\r\n o += (G + H + M + L) * div.y;\r\n\r\n return o;\r\n}\r\n\r\n// Standard box filtering\r\nmediump vec4 downsampleBox4Tap(sampler2D tex, vec2 uv, vec2 texelSize)\r\n{\r\n vec4 d = texelSize.xyxy * vec4(-1.0, -1.0, 1.0, 1.0);\r\n\r\n mediump vec4 s = texture2D(tex, uv + d.xy);\r\n s += texture2D(tex, uv + d.zy);\r\n s += texture2D(tex, uv + d.xw);\r\n s += texture2D(tex, uv + d.zw);\r\n\r\n return s * (1.0 / 4.0);\r\n}\r\n\r\n// 9-tap bilinear upsampler (tent filter)\r\n// . . . . . . .\r\n// . 1 . 2 . 1 .\r\n// . . . . . . .\r\n// . 2 . 4 . 2 .\r\n// . . . . . . .\r\n// . 1 . 2 . 1 .\r\n// . . . . . . .\r\nmediump vec4 upsampleTent(sampler2D tex, vec2 uv, vec2 texelSize, vec4 sampleScale)\r\n{\r\n vec4 d = texelSize.xyxy * vec4(1.0, 1.0, -1.0, 0.0) * sampleScale;\r\n\r\n mediump vec4 s = texture2D(tex, uv - d.xy);\r\n s += texture2D(tex, uv - d.wy) * 2.0;\r\n s += texture2D(tex, uv - d.zy);\r\n\r\n s += texture2D(tex, uv + d.zw) * 2.0;\r\n s += texture2D(tex, uv) * 4.0;\r\n s += texture2D(tex,\tuv + d.xw) * 2.0;\r\n\r\n s += texture2D(tex, uv + d.zy);\r\n s += texture2D(tex, uv + d.wy) * 2.0;\r\n s += texture2D(tex, uv + d.xy);\r\n\r\n return s * (1.0 / 16.0);\r\n}\r\n\r\n// Standard box filtering\r\nmediump vec4 upsampleBox(sampler2D tex, vec2 uv, vec2 texelSize, vec4 sampleScale)\r\n{\r\n vec4 d = texelSize.xyxy * vec4(-1.0, -1.0, 1.0, 1.0) * 0.5 * sampleScale;\r\n\r\n mediump vec4 s = texture2D(tex, uv + d.xy);\r\n s += texture2D(tex, uv + d.zy);\r\n s += texture2D(tex, uv + d.xw);\r\n s += texture2D(tex, uv + d.zw);\r\n\r\n return s * (1.0 / 4.0);\r\n}"),Z.addInclude("StdLib.glsl","#define HALF_MAX 65504.0 // (2 - 2^-10) * 2^15\r\n\r\n#define FLT_EPSILON 1.192092896e-07 // Smallest positive number, such that 1.0 + FLT_EPSILON != 1.0\r\n\r\nmediump vec4 safeHDR(mediump vec4 c)\r\n{\r\n return min(c, HALF_MAX);\r\n}\r\n\r\nfloat max3(float a, float b, float c)\r\n{\r\n return max(max(a, b), c);\r\n}\r\n\r\nvec3 positivePow(vec3 base, vec3 power)\r\n{\r\n return pow(max(abs(base), vec3(FLT_EPSILON, FLT_EPSILON, FLT_EPSILON)), power);\r\n}"),Z.addInclude("PBRVSInput.glsl","attribute vec4 a_Position;\r\n\r\n#ifdef GPU_INSTANCE\r\n\tuniform mat4 u_ViewProjection;\r\n\tattribute mat4 a_WorldMat;\r\n#else\r\n\tuniform mat4 u_MvpMatrix;\r\n\tuniform mat4 u_WorldMat;\r\n#endif\r\n\r\n#ifdef BONE\r\n\tconst int c_MaxBoneCount = 24;\r\n\tattribute vec4 a_BoneIndices;\r\n\tattribute vec4 a_BoneWeights;\r\n\tuniform mat4 u_Bones[c_MaxBoneCount];\r\n#endif\r\n\r\nattribute vec3 a_Normal;\r\nvarying vec3 v_Normal; \r\n\r\n#if defined(NORMALTEXTURE)||defined(PARALLAXTEXTURE)\r\n\tattribute vec4 a_Tangent0;\r\n\tvarying vec3 v_Tangent;\r\n\tvarying vec3 v_Binormal;\r\n #ifdef PARALLAXTEXTURE\r\n\t varying vec3 v_ViewDirForParallax;\r\n #endif\r\n#endif\r\n\r\n#if defined(ALBEDOTEXTURE)||defined(METALLICGLOSSTEXTURE)||defined(NORMALTEXTURE)||defined(EMISSIONTEXTURE)||defined(OCCLUSIONTEXTURE)||defined(PARALLAXTEXTURE)||(defined(LIGHTMAP)&&defined(UV))\r\n\tattribute vec2 a_Texcoord0;\r\n\tvarying vec2 v_Texcoord0;\r\n#endif\r\n\r\n#if defined(LIGHTMAP)&&defined(UV1)\r\n\tattribute vec2 a_Texcoord1;\r\n#endif\r\n\r\n#ifdef LIGHTMAP\r\n\tuniform vec4 u_LightmapScaleOffset;\r\n\tvarying vec2 v_LightMapUV;\r\n#endif\r\n\r\nuniform vec3 u_CameraPos;\r\nvarying vec3 v_EyeVec;\r\nvarying vec3 v_PositionWorld;\r\nvarying float v_posViewZ;\r\n\r\n#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)\r\n\tvarying vec4 v_ShadowCoord;\r\n#endif\r\n\r\n#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\tvarying vec4 v_SpotShadowCoord;\r\n#endif\r\n\r\nuniform vec4 u_TilingOffset;\r\n"),Z.addInclude("PBRFSInput.glsl","#ifdef ALPHATEST\r\n\tuniform float u_AlphaTestValue;\r\n#endif\r\n\r\nuniform vec4 u_AlbedoColor;\r\n\r\n#ifdef NORMALTEXTURE\r\n\tuniform sampler2D u_NormalTexture;\r\n\tuniform float u_NormalScale;\r\n#endif\r\n\r\n#ifdef ALBEDOTEXTURE\r\n\tuniform sampler2D u_AlbedoTexture;\r\n#endif\r\n\r\n#ifdef METALLICGLOSSTEXTURE\r\n\tuniform sampler2D u_MetallicGlossTexture;\r\n#endif\r\nuniform float u_Metallic;\r\n\r\n#ifdef SPECULARGLOSSTEXTURE\r\n\tuniform sampler2D u_SpecGlossTexture;\r\n#endif\r\nuniform vec3 u_SpecularColor;\r\n\r\nuniform float u_Smoothness;\r\nuniform float u_SmoothnessScale;\r\n\r\n#ifdef PARALLAXTEXTURE\r\n\tuniform sampler2D u_ParallaxTexture;\r\n\tuniform float u_ParallaxScale;\r\n\tvarying vec3 v_ViewDirForParallax;\r\n#endif\r\n\r\n#ifdef OCCLUSIONTEXTURE\r\n\tuniform sampler2D u_OcclusionTexture;\r\n\tuniform float u_occlusionStrength;\r\n#endif\r\n\r\n#ifdef EMISSION \r\n\t#ifdef EMISSIONTEXTURE\r\n\t\tuniform sampler2D u_EmissionTexture;\r\n\t#endif\r\n\tuniform vec4 u_EmissionColor;\r\n#endif\r\n\r\n#if defined(ALBEDOTEXTURE)||defined(METALLICGLOSSTEXTURE)||defined(NORMALTEXTURE)||defined(EMISSIONTEXTURE)||defined(OCCLUSIONTEXTURE)||defined(PARALLAXTEXTURE)\r\n\tvarying vec2 v_Texcoord0;\r\n#endif\r\n\r\n#ifdef LIGHTMAP\r\n\tvarying vec2 v_LightMapUV;\r\n\tuniform sampler2D u_LightMap;\r\n\t#ifdef LIGHTMAP_DIRECTIONAL\r\n\t\tuniform sampler2D u_LightMapDirection;\r\n\t#endif\r\n#endif\r\n\r\nvarying vec3 v_Normal; \r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t#ifdef LEGACYSINGLELIGHTING\r\n\t\t#ifdef DIRECTIONLIGHT\r\n\t\t\tuniform DirectionLight u_DirectionLight;\r\n\t\t#endif\r\n\t\t#ifdef POINTLIGHT\r\n\t\t\tuniform PointLight u_PointLight;\r\n\t\t#endif\r\n\t\t#ifdef SPOTLIGHT\r\n\t\t\tuniform SpotLight u_SpotLight;\r\n\t\t#endif\r\n\t#else\r\n\t\tuniform mat4 u_View;\r\n\t\tuniform vec4 u_ProjectionParams;\r\n\t\tuniform vec4 u_Viewport;\r\n\t\tuniform int u_DirationLightCount;\r\n\t\tuniform sampler2D u_LightBuffer;\r\n\t\tuniform sampler2D u_LightClusterBuffer;\r\n\t#endif\r\n#endif\r\n\r\nvarying vec3 v_EyeVec;\r\n\r\n#ifdef NORMALTEXTURE\r\n\tvarying vec3 v_Tangent;\r\n\tvarying vec3 v_Binormal;\r\n#endif\r\n\r\n#ifdef FOG\r\n\tuniform float u_FogStart;\r\n\tuniform float u_FogRange;\r\n\tuniform vec3 u_FogColor;\r\n#endif\r\n\r\n\r\n//后面考虑宏TODO\r\nvarying vec3 v_PositionWorld;\r\n\r\n#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)\r\n\tvarying vec4 v_ShadowCoord;\r\n#endif\r\n\r\n#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\tvarying vec4 v_SpotShadowCoord;\r\n#endif\r\n\r\nmediump float lerpOneTo(mediump float b, mediump float t)\r\n{\r\n mediump float oneMinusT = 1.0 - t;\r\n return oneMinusT + b * t;\r\n}\r\n\r\n#ifdef EMISSION \r\n\tvec3 emission(vec2 uv)\r\n\t{\r\n\t\t#ifdef EMISSIONTEXTURE\r\n\t\t\treturn texture2D(u_EmissionTexture, uv).rgb * u_EmissionColor.rgb;\r\n\t\t#else\r\n\t\t\treturn u_EmissionColor.rgb;\r\n\t\t#endif\r\n\t}\r\n#endif\r\n\r\nmediump float getAlpha(vec2 uv)\r\n{\r\n\t#ifdef SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA\r\n\t\treturn u_AlbedoColor.a;\r\n\t#else\r\n\t\t#ifdef ALBEDOTEXTURE\r\n\t\t\treturn texture2D(u_AlbedoTexture, uv).a * u_AlbedoColor.a;\r\n\t\t#else\r\n\t\t\treturn u_AlbedoColor.a;\r\n\t\t#endif\r\n\t#endif\r\n}\r\n\r\nmediump float getOcclusion(vec2 uv)\r\n{\r\n\t#ifdef OCCLUSIONTEXTURE\r\n\t\tmediump float occ = texture2D(u_OcclusionTexture, uv).g;\r\n\t\treturn lerpOneTo(occ, u_occlusionStrength);\r\n\t#else\r\n\t\treturn 1.0;\r\n\t#endif\r\n}\r\n\r\nmediump vec3 albedo(vec2 uv)\r\n{\r\n\t#ifdef ALBEDOTEXTURE\r\n\t\treturn u_AlbedoColor.rgb * texture2D(u_AlbedoTexture, uv).rgb;\r\n\t#else\r\n\t\treturn u_AlbedoColor.rgb;\r\n\t#endif\r\n\t//TODO:Detail Texture\r\n}\r\n\r\nmediump vec2 getMetallicGloss(vec2 uv)\r\n{\r\n\tmediump vec2 ms;//x is metallic,y is smoothness\r\n\t#ifdef METALLICGLOSSTEXTURE\r\n\t\t#ifdef SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA\r\n\t\t\tms.x = texture2D(u_MetallicGlossTexture, uv).r;\r\n\t\t\t#ifdef ALBEDOTEXTURE\r\n\t\t\t\tms.y = texture2D(u_AlbedoTexture, uv).a*u_SmoothnessScale;\r\n\t\t\t#else\r\n\t\t\t\tms.y = u_SmoothnessScale;\r\n\t\t\t#endif\r\n\t\t#else\r\n\t\t\tms = texture2D(u_MetallicGlossTexture, uv).ra;\r\n\t\t\tms.y *= u_SmoothnessScale;\r\n\t\t#endif\r\n\t#else\r\n\t\tms.x = u_Metallic;\r\n\t\t#ifdef SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA\r\n\t\t\t#ifdef ALBEDOTEXTURE\r\n\t\t\t\tms.y = texture2D(u_AlbedoTexture, uv).a * u_SmoothnessScale;\r\n\t\t\t#else\r\n\t\t\t\tms.y = u_SmoothnessScale;\r\n\t\t\t#endif\r\n\t\t#else\r\n\t\t\tms.y = u_Smoothness;\r\n\t\t#endif\r\n\t#endif\r\n\treturn ms;\r\n}\r\n\r\nmediump vec4 specularGloss(vec2 uv)\r\n{\r\n\tmediump vec4 sg;\r\n\t#ifdef SPECULARGLOSSTEXTURE\r\n\t\t#ifdef SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA\r\n\t\t\tsg.rgb = texture2D(u_SpecGlossTexture, uv).rgb;\r\n\t\t\t#ifdef ALBEDOTEXTURE\r\n\t\t\t\tsg.a = texture2D(u_AlbedoTexture, uv).a*u_SmoothnessScale;\r\n\t\t\t#else\r\n\t\t\t\tsg.a = u_SmoothnessScale;\r\n\t\t\t#endif\r\n\t\t#else\r\n\t\t\tsg = texture2D(u_SpecGlossTexture, uv);\r\n\t\t\tsg.a *= u_SmoothnessScale;\r\n\t\t#endif\r\n\t#else\r\n\t\tsg.rgb = u_SpecularColor.rgb;\r\n\t\t#ifdef SMOOTHNESSSOURCE_ALBEDOTEXTURE_ALPHA\r\n\t\t\t#ifdef ALBEDOTEXTURE\r\n\t\t\t\tsg.a = texture2D(u_AlbedoTexture, uv).a * u_SmoothnessScale;\r\n\t\t\t#else\r\n\t\t\t\tsg.a = u_SmoothnessScale;\r\n\t\t\t#endif\r\n\t\t#else\r\n\t\t\tsg.a = u_Smoothness;\r\n\t\t#endif\r\n\t#endif\r\n\t\treturn sg;\r\n}\r\n\r\n\r\n#ifdef NORMALTEXTURE\r\n\tmediump vec3 unpackScaleNormal(mediump vec3 packednormal, mediump float bumpScale)\r\n\t{\r\n\t\tmediump vec3 normal = packednormal.xyz * 2.0 - 1.0;\r\n\t\tnormal.y=-normal.y;//NOTE:because unity to LayaAir coordSystem.\r\n\t\tnormal.xy *= bumpScale;\r\n\t\treturn normal;\r\n\t}\r\n\t\r\n\tmediump vec3 normalInTangentSpace(vec2 texcoords)\r\n\t{\r\n\t\tmediump vec3 normalTangent = unpackScaleNormal(texture2D(u_NormalTexture, texcoords).rgb,u_NormalScale);\r\n\t\treturn normalTangent;\r\n\t}\r\n#endif\r\n\r\n#ifdef PARALLAXTEXTURE\r\n\tmediump vec2 parallaxOffset1Step(mediump float h, mediump float height, mediump vec3 viewDir)\r\n\t{\r\n\t\th = h * height - height / 2.0;\r\n\t\tviewDir.z += 0.42;\r\n\t\treturn h * (viewDir.xy / viewDir.z);\r\n\t}\r\n\r\n\tvec2 parallax(vec2 texcoords, mediump vec3 viewDir)\r\n\t{\r\n\t\tmediump float h = texture2D(u_ParallaxTexture, texcoords.xy).g;\r\n\t\tvec2 offset = parallaxOffset1Step(h, u_ParallaxScale, viewDir);\r\n\t\treturn texcoords+offset;\r\n\t}\r\n#endif\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n"),Z.addInclude("LayaPBRBRDF.glsl",'// allow to explicitly override LAYA_BRDF_GI and LAYA_BRDF_LIGHT in custom shader,default is layaBRDFHighGI and layaBRDFHighLight\r\n#if !defined (LAYA_BRDF_GI) \r\n\t#if defined(LAYA_PBR_BRDF_LOW)\r\n\t\t#define LAYA_BRDF_GI layaBRDFLowGI\r\n\t#elif defined(LAYA_PBR_BRDF_HIGH)\r\n\t\t#define LAYA_BRDF_GI layaBRDFHighGI\r\n\t#endif\r\n#endif\r\n#if !defined (LAYA_BRDF_LIGHT)\r\n\t#if defined(LAYA_PBR_BRDF_LOW)\r\n\t\t#define LAYA_BRDF_LIGHT layaBRDFLowLight\r\n\t#elif defined(LAYA_PBR_BRDF_HIGH)\r\n\t\t#define LAYA_BRDF_LIGHT layaBRDFHighLight\r\n\t#endif\r\n#endif\r\n\r\n#define PI 3.14159265359\r\n#define INV_PI 0.31830988618\r\n\r\nmediump float pow4(mediump float x)\r\n{\r\n\treturn x * x * x * x;\r\n}\r\n\r\nmediump float pow5(mediump float x)\r\n{\r\n\treturn x * x * x * x * x;\r\n}\r\n\r\nmediump vec3 fresnelLerp(mediump vec3 F0,mediump vec3 F90,mediump float cosA)\r\n{\r\n\tfloat t = pow5(1.0 - cosA); // ala Schlick interpoliation\r\n\treturn mix(F0, F90, t);\r\n}\r\n\r\nmediump vec3 fresnelTerm(mediump vec3 F0,mediump float cosA)\r\n{\r\n\tfloat t = pow5(1.0 - cosA); // ala Schlick interpoliation\r\n\treturn F0 + (vec3(1.0) - F0) * t;\r\n}\r\n\r\n// approximage Schlick with ^4 instead of ^5\r\nmediump vec3 fresnelLerpFast (mediump vec3 F0, mediump vec3 F90,mediump float cosA)\r\n{\r\n mediump float t = pow4 (1.0 - cosA);\r\n return mix (F0, F90, t);\r\n}\r\n\r\nfloat smoothnessToPerceptualRoughness(float smoothness)\r\n{\r\n return 1.0 - smoothness;\r\n}\r\n\r\nfloat perceptualRoughnessToRoughness(float perceptualRoughness)\r\n{\r\n return perceptualRoughness * perceptualRoughness;\r\n}\r\n\r\nvec3 safeNormalize(vec3 inVec)\r\n{\r\n\tfloat dp3 = max(0.001,dot(inVec,inVec));\r\n\treturn inVec * inversesqrt(dp3);\r\n}\r\n\r\n// Note: Disney diffuse must be multiply by diffuseAlbedo / PI. This is done outside of this function.\r\nmediump float disneyDiffuse(mediump float NdotV,mediump float NdotL,mediump float LdotH,mediump float perceptualRoughness)\r\n{\r\n\t//https://www.cnblogs.com/herenzhiming/articles/5790389.html\r\n\tmediump float fd90 = 0.5 + 2.0 * LdotH * LdotH * perceptualRoughness;\r\n\t// Two schlick fresnel term\r\n\tmediump float lightScatter = (1.0 + (fd90 - 1.0) * pow5(1.0 - NdotL));\r\n\tmediump float viewScatter = (1.0 + (fd90 - 1.0) * pow5(1.0 - NdotV));\r\n\r\n\treturn lightScatter * viewScatter;\r\n}\r\n\r\n// Ref: http://jcgt.org/published/0003/02/03/paper.pdf\r\nfloat smithJointGGXVisibilityTerm(float NdotL, float NdotV, float roughness)\r\n{\r\n\t// Original formulation:\r\n // lambda_v = (-1 + sqrt(a2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5f;\r\n // lambda_l = (-1 + sqrt(a2 * (1 - NdotV2) / NdotV2 + 1)) * 0.5f;\r\n // G = 1 / (1 + lambda_v + lambda_l);\r\n\r\n\t// scientific code implement:\r\n\t// Reorder code to be more optimal\r\n // half a = roughness;\r\n // half a2 = a * a;\r\n\r\n // half lambdaV = NdotL * sqrt((-NdotV * a2 + NdotV) * NdotV + a2);\r\n // half lambdaL = NdotV * sqrt((-NdotL * a2 + NdotL) * NdotL + a2);\r\n\r\n // Simplify visibility term: (2.0f * NdotL * NdotV) / ((4.0f * NdotL * NdotV) * (lambda_v + lambda_l + 1e-5f));\r\n // return 0.5f / (lambdaV + lambdaL + 1e-5f); \r\n\t// This function is not intended to be running on Mobile,therefore epsilon is smaller than can be represented by half\r\n\r\n\t// Approximation of the above formulation (simplify the sqrt, not mathematically correct but close enough)\r\n\tfloat a = roughness;\r\n\tfloat lambdaV = NdotL * (NdotV * (1.0 - a) + a);\r\n\tfloat lambdaL = NdotV * (NdotL * (1.0 - a) + a);\r\n\treturn 0.5 / (lambdaV + lambdaL + 1e-5);\r\n}\r\n\r\nfloat ggxTerm(float NdotH, float roughness)\r\n{\r\n\tfloat a2 = roughness * roughness;\r\n\tfloat d = (NdotH * a2 - NdotH) * NdotH + 1.0; // 2 mad\r\n\treturn INV_PI * a2 / (d * d + 1e-7); // This function is not intended to be running on Mobile,therefore epsilon is smaller than what can be represented by half//返回值小用half来返回\r\n}\r\n\r\n// BRDF1-------------------------------------------------------------------------------------\r\n\r\n// Note: BRDF entry points use smoothness and oneMinusReflectivity for optimization purposes,\r\n// mostly for DX9 SM2.0 level. Most of the math is being done on these (1-x) values, and that saves a few precious ALU slots.\r\n\r\n// Main Physically Based BRDF\r\n// Derived from Disney work and based on Torrance-Sparrow micro-facet model\r\n//\r\n// BRDF = kD / pi + kS * (D * V * F) / 4\r\n// I = BRDF * NdotL\r\n//\r\n// *NDF GGX:\r\n// *Smith for Visiblity term\r\n// *Schlick approximation for Fresnel\r\nmediump vec4 layaBRDFHighLight(mediump vec3 diffColor, mediump vec3 specColor, mediump float oneMinusReflectivity, float perceptualRoughness,float roughness,mediump float nv,vec3 normal, vec3 viewDir,LayaLight light)\r\n{\r\n\tvec3 halfDir = safeNormalize(viewDir-light.dir);\r\n\r\n\tfloat nl = clamp(dot(normal, -light.dir),0.0,1.0);\r\n\tfloat nh = clamp(dot(normal, halfDir),0.0,1.0);\r\n\tmediump float lv = clamp(dot(light.dir, viewDir),0.0,1.0);\r\n\tmediump float lh = clamp(dot(light.dir, -halfDir),0.0,1.0);\r\n\r\n\t// Diffuse term\r\n\tmediump float diffuseTerm = disneyDiffuse(nv, nl, lh, perceptualRoughness) * nl;\r\n\r\n\t// Specular term\r\n // HACK: theoretically we should divide diffuseTerm by Pi and not multiply specularTerm!\r\n // BUT that will make shader look significantly darker than Legacy ones\r\n\r\n\t// GGX with roughtness to 0 would mean no specular at all, using max(roughness, 0.002) here to match HDrenderloop roughtness remapping.\r\n\troughness = max(roughness, 0.002);\r\n\tfloat V = smithJointGGXVisibilityTerm(nl, nv, roughness);\r\n\tfloat D = ggxTerm(nh, roughness);\r\n\r\n\tfloat specularTerm = V * D * PI; // Torrance-Sparrow model, Fresnel is applied later\r\n\r\n\t//#ifdef LAYA_COLORSPACE_GAMMA\r\n\tspecularTerm = sqrt(max(1e-4, specularTerm));\r\n\t//#endif\r\n\tspecularTerm = max(0.0, specularTerm * nl);\r\n\t\t\r\n\tmediump vec3 color = diffColor * light.color * diffuseTerm + specularTerm * light.color * fresnelTerm(specColor, lh);\r\n\treturn vec4(color, 1.0);\r\n}\r\n\r\nvec4 layaBRDFHighGI(mediump vec3 diffColor,mediump vec3 specColor,mediump float oneMinusReflectivity,float smoothness ,float perceptualRoughness,float roughness,mediump float nv,vec3 normal, vec3 viewDir,LayaGI gi)\r\n{\r\n\t// surfaceReduction = Int D(NdotH) * NdotH * Id(NdotL>0) dH = 1/(roughness^2+1)\r\n\tfloat surfaceReduction;\r\n\tsurfaceReduction = 1.0 - 0.28*roughness*perceptualRoughness;// 1-0.28*x^3 as approximation for (1/(x^4+1))^(1/2.2) on the domain [0;1]\r\n\tfloat grazingTerm = clamp(smoothness + (1.0 - oneMinusReflectivity),0.0,1.0);\r\n\tmediump vec3 color =diffColor * gi.diffuse + surfaceReduction * gi.specular * fresnelLerp(specColor,vec3(grazingTerm), nv);\r\n\treturn vec4(color,1.0);\r\n}\r\n// BRDF1-------------------------------------------------------------------------------------\r\n\r\n\r\n// BRDF2-------------------------------------------------------------------------------------\r\n// Based on Minimalist CookTorrance BRDF\r\n// Implementation is slightly different from original derivation: http://www.thetenthplanet.de/archives/255\r\n//\r\n// *NDF [Modified] GGX:\r\n// *Modified Kelemen and Szirmay-​Kalos for Visibility term\r\n// *Fresnel approximated with 1/LdotH\r\nmediump vec4 layaBRDFLowLight (mediump vec3 diffColor, mediump vec3 specColor,mediump float oneMinusReflectivity,float perceptualRoughness,float roughness,mediump float nv,vec3 normal,vec3 viewDir,LayaLight light)\r\n{\r\n vec3 halfDir = safeNormalize (viewDir-light.dir);\r\n mediump float nl = clamp(dot(normal, -light.dir),0.0,1.0);\r\n float nh = clamp(dot(normal, halfDir),0.0,1.0);\r\n float lh = clamp(dot(-light.dir, halfDir),0.0,1.0);\r\n\r\n // GGX Distribution multiplied by combined approximation of Visibility and Fresnel\r\n // See "Optimizing PBR for Mobile" from Siggraph 2015 moving mobile graphics course\r\n // https://community.arm.com/events/1155\r\n mediump float a = roughness;\r\n float a2 = a*a;\r\n\r\n float d = nh * nh * (a2 - 1.0) + 1.00001;\r\n\t// #ifdef LAYA_COLORSPACE_GAMMA\r\n\t\t// Tighter approximation for Gamma only rendering mode!\r\n\t\t// DVF = sqrt(DVF);\r\n\t\t// DVF = (a * sqrt(.25)) / (max(sqrt(0.1), lh)*sqrt(roughness + .5) * d);\r\n\t\tfloat specularTerm = a / (max(0.32, lh) * (1.5 + roughness) * d);\r\n\t// #else\r\n\t// \tfloat specularTerm = a2 / (max(0.1f, lh*lh) * (roughness + 0.5f) * (d * d) * 4);\r\n\t// #endif\r\n\r\n // on mobiles (where half actually means something) denominator have risk of overflow\r\n // clamp below was added specifically to "fix" that, but dx compiler (we convert bytecode to metal/gles)\r\n // sees that specularTerm have only non-negative terms, so it skips max(0,..) in clamp (leaving only min(100,...))\r\n\r\n\t//#if defined (SHADER_API_MOBILE)\r\n specularTerm = specularTerm - 1e-4;\r\n\t//#endif\r\n\r\n\t// #else\r\n\t\t// // Legacy\r\n\t\t// half specularPower = PerceptualRoughnessToSpecPower(perceptualRoughness);\r\n\t\t// // Modified with approximate Visibility function that takes roughness into account\r\n\t\t// // Original ((n+1)*N.H^n) / (8*Pi * L.H^3) didn\'t take into account roughness\r\n\t\t// // and produced extremely bright specular at grazing angles\r\n\r\n\t\t// half invV = lh * lh * smoothness + perceptualRoughness * perceptualRoughness; // approx ModifiedKelemenVisibilityTerm(lh, perceptualRoughness);\r\n\t\t// half invF = lh;\r\n\r\n\t\t// half specularTerm = ((specularPower + 1) * pow (nh, specularPower)) / (8 * invV * invF + 1e-4h);\r\n\r\n\t\t// #ifdef LAYA_COLORSPACE_GAMMA\r\n\t\t// \tspecularTerm = sqrt(max(1e-4f, specularTerm));\r\n\t\t// #endif\r\n\t// #endif\r\n\r\n\t// #if defined (SHADER_API_MOBILE)\r\n\t\tspecularTerm = clamp(specularTerm, 0.0, 100.0); // Prevent FP16 overflow on mobiles\r\n\t// #endif\r\n \r\n mediump vec3 color = (diffColor + specularTerm * specColor) * light.color * nl;\r\n\r\n return vec4(color, 1.0);\r\n}\r\n\r\nmediump vec4 layaBRDFLowGI (mediump vec3 diffColor, mediump vec3 specColor,mediump float oneMinusReflectivity,mediump float smoothness,float perceptualRoughness,float roughness,mediump float nv,vec3 normal,vec3 viewDir,LayaGI gi)\r\n{\r\n\t// surfaceReduction = Int D(NdotH) * NdotH * Id(NdotL>0) dH = 1/(realRoughness^2+1)\r\n\r\n // 1-0.28*x^3 as approximation for (1/(x^4+1))^(1/2.2) on the domain [0;1]\r\n // 1-x^3*(0.6-0.08*x) approximation for 1/(x^4+1)\r\n\t// #ifdef LAYA_COLORSPACE_GAMMA\r\n\t\tmediump float surfaceReduction = 0.28;\r\n\t// #else\r\n\t\t// mediump float surfaceReduction = (0.6-0.08*perceptualRoughness);\r\n\t// #endif\r\n\r\n surfaceReduction = 1.0 - roughness*perceptualRoughness*surfaceReduction;\r\n\r\n\tmediump float grazingTerm = clamp(smoothness + (1.0-oneMinusReflectivity),0.0,1.0);\r\n\tmediump vec3 color =gi.diffuse * diffColor+ surfaceReduction * gi.specular * fresnelLerpFast (specColor, vec3(grazingTerm), nv);\r\n\r\n return vec4(color, 1.0);\r\n}\r\n// BRDF2-------------------------------------------------------------------------------------'),Z.addInclude("PBRCore.glsl","struct FragmentCommonData{\r\n\tvec3 diffColor;\r\n\tvec3 specColor;\r\n\tfloat oneMinusReflectivity;\r\n\tfloat smoothness;\r\n\t//vec3 eyeVec;TODO:maybe can remove\r\n\t//float alpha;\r\n\t//vec3 reflUVW;\r\n};\r\n\r\n#if !defined(SETUP_BRDF_INPUT)//shader内部的宏需要将改成#ifdef改成#if类型 不然会被Laya的shader分析器优化掉\r\n #define SETUP_BRDF_INPUT metallicSetup//default is metallicSetup,also can be other. \r\n#endif\r\n\r\nconst mediump vec4 dielectricSpecularColor = vec4(0.220916301, 0.220916301, 0.220916301, 1.0 - 0.220916301);\r\n\r\nmediump vec3 diffuseAndSpecularFromMetallic(mediump vec3 albedo,mediump float metallic, out mediump vec3 specColor, out mediump float oneMinusReflectivity)\r\n{\r\n\tspecColor = mix(dielectricSpecularColor.rgb, albedo, metallic);\r\n\toneMinusReflectivity= dielectricSpecularColor.a*(1.0-metallic);//diffuse proportion\r\n\treturn albedo * oneMinusReflectivity;\r\n}\r\n\r\nmediump float specularStrength(mediump vec3 specular)\r\n{\r\n return max (max (specular.r, specular.g), specular.b);\r\n}\r\n\r\n// Diffuse/Spec Energy conservation\r\nmediump vec3 energyConservationBetweenDiffuseAndSpecular (mediump vec3 albedo, mediump vec3 specColor, out mediump float oneMinusReflectivity)\r\n{\r\n\toneMinusReflectivity = 1.0 - specularStrength(specColor);\r\n return albedo * (vec3(1.0) - specColor);\r\n}\r\n\r\n#ifdef TRANSPARENTBLEND\r\n\tmediump vec3 preMultiplyAlpha (mediump vec3 diffColor, mediump float alpha, mediump float oneMinusReflectivity,out mediump float modifiedAlpha)\r\n\t{\r\n\t\t// Transparency 'removes' from Diffuse component\r\n\t\tdiffColor *= alpha;\r\n\t\t// Reflectivity 'removes' from the rest of components, including Transparency\r\n\t\t// modifiedAlpha = 1.0-(1.0-alpha)*(1.0-reflectivity) = 1.0-(oneMinusReflectivity - alpha*oneMinusReflectivity) = 1.0-oneMinusReflectivity + alpha*oneMinusReflectivity\r\n\t\tmodifiedAlpha = 1.0 - oneMinusReflectivity + alpha*oneMinusReflectivity;\r\n\t\treturn diffColor;\r\n\t}\r\n#endif\r\n\r\nFragmentCommonData metallicSetup(vec2 uv)\r\n{\r\n\tmediump vec2 metallicGloss = getMetallicGloss(uv);\r\n\tmediump float metallic = metallicGloss.x;\r\n\tmediump float smoothness = metallicGloss.y; // this is 1 minus the square root of real roughness m.\r\n\tmediump float oneMinusReflectivity;\r\n\tmediump vec3 specColor;\r\n\tmediump vec3 diffColor = diffuseAndSpecularFromMetallic(albedo(uv), metallic,/*out*/specColor,/*out*/oneMinusReflectivity);\r\n\r\n\tFragmentCommonData o;\r\n\to.diffColor = diffColor;\r\n\to.specColor = specColor;\r\n\to.oneMinusReflectivity = oneMinusReflectivity;\r\n\to.smoothness = smoothness;\r\n\treturn o;\r\n}\r\n\r\nFragmentCommonData specularSetup(vec2 uv)\r\n{\r\n mediump vec4 specGloss = specularGloss(uv);\r\n mediump vec3 specColor = specGloss.rgb;\r\n mediump float smoothness = specGloss.a;\r\n\r\n mediump float oneMinusReflectivity;\r\n mediump vec3 diffColor = energyConservationBetweenDiffuseAndSpecular (albedo(uv), specColor, /*out*/ oneMinusReflectivity);\r\n\r\n FragmentCommonData o;\r\n o.diffColor = diffColor;\r\n o.specColor = specColor;\r\n o.oneMinusReflectivity = oneMinusReflectivity;\r\n o.smoothness = smoothness;\r\n return o;\r\n}\r\n\r\nLayaGI fragmentGI(float smoothness,vec3 eyeVec,mediump float occlusion,mediump vec2 lightmapUV,vec3 worldnormal,vec3 worldPos)\r\n{\r\n\tLayaGIInput giInput;\r\n\t#ifdef LIGHTMAP\r\n\t\tgiInput.lightmapUV=lightmapUV;\r\n\t#endif\r\n\tgiInput.worldPos = worldPos;\r\n\r\n\tvec3 worldViewDir = -eyeVec;\r\n\tmediump vec4 uvwRoughness;\r\n\tuvwRoughness.rgb = reflect(worldViewDir, worldnormal);//reflectUVW\r\n\tuvwRoughness.a= smoothnessToPerceptualRoughness(smoothness);//perceptualRoughness\r\n\r\n\treturn layaGlobalIllumination(giInput,occlusion, worldnormal, uvwRoughness);\r\n}\r\n\r\n\r\nvec3 perPixelWorldNormal(vec2 uv,vec3 normal,vec3 binormal,vec3 tangent)\r\n{\r\n\t#ifdef NORMALTEXTURE\r\n\t\tmediump vec3 normalTangent=normalInTangentSpace(uv);\r\n\t\tvec3 normalWorld = normalize(tangent * normalTangent.x + binormal * normalTangent.y + normal * normalTangent.z);\r\n\t#else\r\n\t\tvec3 normalWorld = normalize(normal);\r\n\t#endif\r\n\t\treturn normalWorld;\r\n}\r\n\r\nvoid fragmentForward()\r\n{\r\n\tvec2 uv;\r\n\t#if defined(ALBEDOTEXTURE)||defined(METALLICGLOSSTEXTURE)||defined(NORMALTEXTURE)||defined(EMISSIONTEXTURE)||defined(OCCLUSIONTEXTURE)||defined(PARALLAXTEXTURE)\r\n\t\t#ifdef PARALLAXTEXTURE\r\n\t\t\tuv = parallax(v_Texcoord0,normalize(v_ViewDirForParallax));\r\n\t\t#else\r\n\t\t\tuv = v_Texcoord0;\r\n\t\t#endif\r\n\t#endif\r\n\r\n\tmediump float alpha = getAlpha(uv);\r\n\t#ifdef ALPHATEST\r\n\t\tif(alpha= u_DirationLightCount)\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t#if defined(CALCULATE_SHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\t\t\t\tif(i == 0)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t#ifdef SHADOW_CASCADE\r\n\t\t\t\t\t\t\tvec4 shadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));\r\n\t\t\t\t\t\t#else\r\n\t\t\t\t\t\t\tvec4 shadowCoord = v_ShadowCoord;\r\n\t\t\t\t\t\t#endif\r\n\t\t\t\t\t\tshadowAttenuation *= sampleShadowmap(shadowCoord);\r\n\t\t\t\t\t}\r\n\t\t\t\t#endif\r\n\t\t\t\tDirectionLight directionLight = getDirectionLight(u_LightBuffer,i);\r\n\t\t\t\tLayaLight dirLight = layaDirectionLightToLight(directionLight,shadowAttenuation);\r\n\t\t\t \tcolor+=LAYA_BRDF_LIGHT(o.diffColor,o.specColor,o.oneMinusReflectivity,perceptualRoughness,roughness,nv,normalWorld,eyeVec,dirLight);\r\n\t\t\t}\r\n\t \t#endif\r\n\t\t#if defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\t\tivec4 clusterInfo =getClusterInfo(u_LightClusterBuffer,u_View,u_Viewport, v_PositionWorld,gl_FragCoord,u_ProjectionParams);\r\n\t\t\t#ifdef POINTLIGHT\r\n\t\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t\t{\r\n\t\t\t\t\tshadowAttenuation = 1.0;\r\n\t\t\t\t\tif(i >= clusterInfo.x)//PointLightCount\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tPointLight pointLight = getPointLight(u_LightBuffer,u_LightClusterBuffer,clusterInfo,i);\r\n\t\t\t\t\tLayaLight poiLight = layaPointLightToLight(posworld,normalWorld,pointLight,shadowAttenuation);\r\n\t\t\t\t\tcolor+= LAYA_BRDF_LIGHT(o.diffColor,o.specColor,o.oneMinusReflectivity,perceptualRoughness,roughness,nv,normalWorld,eyeVec,poiLight);\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t\t#ifdef SPOTLIGHT\r\n\t\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t\t{\r\n\t\t\t\t\tshadowAttenuation = 1.0;\r\n\t\t\t\t\tif(i >= clusterInfo.y)//SpotLightCount\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\t\t\t\t\tif(i == 0)\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\tvec4 spotShadowcoord = v_SpotShadowCoord;\r\n\t\t\t\t\t\t\tshadowAttenuation= sampleSpotShadowmap(spotShadowcoord);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t#endif\r\n\t\t\t\t\tSpotLight spotLight = getSpotLight(u_LightBuffer,u_LightClusterBuffer,clusterInfo,i);\r\n\t\t\t\t\tLayaLight spoLight = layaSpotLightToLight(posworld,normalWorld,spotLight,shadowAttenuation);\r\n\t\t\t\t\tcolor+= LAYA_BRDF_LIGHT(o.diffColor,o.specColor,o.oneMinusReflectivity,perceptualRoughness,roughness,nv,normalWorld,eyeVec,spoLight);\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t#endif\r\n\t #endif\r\n\r\n\t#ifdef EMISSION\r\n\t\tcolor.rgb += emission(uv);\r\n\t#endif\r\n\r\n\t#ifdef FOG\r\n\t\tfloat lerpFact=clamp((1.0/gl_FragCoord.w-u_FogStart)/u_FogRange,0.0,1.0);\r\n\t\tcolor.rgb=mix(color.rgb,u_FogColor,lerpFact);\r\n\t#endif\r\n\t\r\n\tgl_FragColor=vec4(color.rgb,alpha);\r\n}\r\n\r\n\r\n\r\n"),Z.addInclude("PBRVertex.glsl","vec2 transformLightMapUV(in vec2 texcoord,in vec4 lightmapScaleOffset)\r\n{\r\n\tvec2 lightMapUV=vec2(texcoord.x,1.0-texcoord.y)*lightmapScaleOffset.xy+lightmapScaleOffset.zw;\r\n\tlightMapUV.y=1.0-lightMapUV.y;\r\n\treturn lightMapUV; \r\n}\r\n\r\nvoid vertexForward()\r\n{\r\n\tvec4 position;\r\n\t#ifdef BONE\r\n\t\tmat4 skinTransform;\r\n\t \t#ifdef SIMPLEBONE\r\n\t\t\tfloat currentPixelPos;\r\n\t\t\t#ifdef GPU_INSTANCE\r\n\t\t\t\tcurrentPixelPos = a_SimpleTextureParams.x+a_SimpleTextureParams.y;\r\n\t\t\t#else\r\n\t\t\t\tcurrentPixelPos = u_SimpleAnimatorParams.x+u_SimpleAnimatorParams.y;\r\n\t\t\t#endif\r\n\t\t\tfloat offset = 1.0/u_SimpleAnimatorTextureSize;\r\n\t\t\tskinTransform = loadMatFromTexture(currentPixelPos,int(a_BoneIndices.x),offset) * a_BoneWeights.x;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.y),offset) * a_BoneWeights.y;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.z),offset) * a_BoneWeights.z;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.w),offset) * a_BoneWeights.w;\r\n\t\t#else\r\n\t\t\tskinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;\r\n\t\t#endif\r\n\t\tposition=skinTransform*a_Position;\r\n\t #else\r\n\t\tposition=a_Position;\r\n\t#endif\r\n\r\n\tmat4 worldMat;\r\n\t#ifdef GPU_INSTANCE\r\n\t\tworldMat = a_WorldMat;\r\n\t#else\r\n\t\tworldMat = u_WorldMat;\r\n\t#endif\r\n\r\n\t#ifdef GPU_INSTANCE\r\n\t\tgl_Position = u_ViewProjection * worldMat * position;\r\n\t#else\r\n\t\tgl_Position = u_MvpMatrix * position;\r\n\t#endif\r\n\r\n\t\r\n\r\n\tv_PositionWorld=(worldMat*position).xyz;\r\n\r\n\t#if defined(ALBEDOTEXTURE)||defined(METALLICGLOSSTEXTURE)||defined(NORMALTEXTURE)||defined(EMISSIONTEXTURE)||defined(OCCLUSIONTEXTURE)||defined(PARALLAXTEXTURE)\r\n\t\tv_Texcoord0=TransformUV(a_Texcoord0,u_TilingOffset);\r\n\t#endif\r\n\r\n\tv_EyeVec =u_CameraPos-v_PositionWorld;//will normalize per-pixel\r\n\r\n\t#ifdef LIGHTMAP\r\n\t\tvec2 texcoord;\r\n\t\t#ifdef UV1\r\n\t\t\ttexcoord=a_Texcoord1;\r\n\t\t#else\r\n\t\t\ttexcoord=a_Texcoord0;\r\n\t\t#endif\r\n\t\tv_LightMapUV=transformLightMapUV(texcoord,u_LightmapScaleOffset);\r\n\t#endif\r\n\r\n\tmat3 worldInvMat;\r\n\t#ifdef BONE\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat*skinTransform));\r\n\t#else\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat));\r\n\t#endif\r\n\r\n\tv_Normal=normalize(a_Normal*worldInvMat);//if no normalize will cause precision problem.\r\n\r\n\t#ifdef NORMALTEXTURE\r\n\t\tv_Tangent=normalize(a_Tangent0.xyz*worldInvMat);\r\n\t\tv_Binormal=cross(v_Normal,v_Tangent)*a_Tangent0.w;\r\n\t#endif\r\n\r\n\t#ifdef PARALLAXTEXTURE\r\n\t\tvec3 binormal = cross(a_Normal, a_Tangent0.xyz)*a_Tangent0.w;\r\n\t\tmat3 objectTBN = mat3(a_Tangent0.xyz, binormal, a_Normal);\r\n\t\tv_ViewDirForParallax =(u_CameraPos*worldInvMat-position.xyz)*objectTBN;\r\n\t#endif\r\n\r\n\t#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)\r\n\t\tv_ShadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));\r\n\t#endif\r\n\r\n\t#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\tv_SpotShadowCoord = u_SpotViewProjectMatrix*vec4(v_PositionWorld,1.0);\r\n\t#endif\r\n}"),Z.addInclude("LayaUtile.glsl","\r\n\r\n//SimpleSkinnedMesh\r\n#ifdef SIMPLEBONE\r\n\t#ifdef GPU_INSTANCE\r\n\t\tattribute vec4 a_SimpleTextureParams;\r\n\t#else\r\n\t\tuniform vec4 u_SimpleAnimatorParams;\r\n\t#endif\r\n\tuniform sampler2D u_SimpleAnimatorTexture;\r\n\r\n\tuniform float u_SimpleAnimatorTextureSize; \r\n#endif\r\n\r\n\r\n#ifdef SIMPLEBONE\r\n\tmat4 loadMatFromTexture(float FramePos,int boneIndices,float offset)\r\n\t{\r\n\t\tvec2 uv;\r\n\t\tfloat PixelPos = FramePos+float(boneIndices)*4.0;\r\n\t\tfloat halfOffset = offset * 0.5;\r\n\t\tfloat uvoffset = PixelPos/u_SimpleAnimatorTextureSize;\r\n\t\tuv.y = floor(uvoffset)*offset+halfOffset;\r\n\t\tuv.x = mod(float(PixelPos),u_SimpleAnimatorTextureSize)*offset+halfOffset;\r\n\t\tvec4 mat0row = texture2D(u_SimpleAnimatorTexture,uv);\r\n\t\tuv.x+=offset;\r\n\t\tvec4 mat1row = texture2D(u_SimpleAnimatorTexture,uv);\r\n\t\tuv.x+=offset;\r\n\t\tvec4 mat2row = texture2D(u_SimpleAnimatorTexture,uv);\r\n\t\tuv.x+=offset;\r\n\t\tvec4 mat3row = texture2D(u_SimpleAnimatorTexture,uv);\r\n\t\tmat4 m =mat4(mat0row.x,mat0row.y,mat0row.z,mat0row.w,\r\n\t\t\t\tmat1row.x,mat1row.y,mat1row.z,mat1row.w,\r\n\t\t\t\tmat2row.x,mat2row.y,mat2row.z,mat2row.w,\r\n\t\t\t\tmat3row.x,mat3row.y,mat3row.z,mat3row.w);\r\n\t\treturn m;\r\n\t}\r\n#endif\r\n\r\n"),Z.addInclude("DepthNormalUtil.glsl","#define SAMPLE_DEPTH_TEXTURE(textureName,coord2) (texture2D(textureName,coord2).r)\r\n//此方法库用来压缩解析深度贴图,法线深度贴图\r\n\r\n/*camera 传入的Texture以及*/\r\nuniform sampler2D u_CameraDepthTexture;\r\nuniform vec4 u_ZBufferParams;\r\nuniform sampler2D u_CameraDepthNormalsTexture;\r\n\r\n// Encoding/decoding view space normals into 2D 0..1 vector\r\nvec2 EncodeViewNormalStereo( vec3 n )\r\n{\r\n n.z = abs(n.z);\r\n float kScale = 1.7777;\r\n vec2 enc;\r\n enc = n.xy / (n.z+1.0);\r\n enc /= kScale;\r\n enc = enc*0.5+0.5;\r\n return enc;\r\n}\r\n\r\nvec3 DecodeViewNormalStereo( vec4 enc4 )\r\n{\r\n float kScale = 1.7777;\r\n vec3 nn = enc4.xyz*vec3(2.0*kScale,2.0*kScale,0.0) + vec3(-kScale,-kScale,1.0);\r\n float g = 2.0 / dot(nn.xyz,nn.xyz);\r\n vec3 n;\r\n n.xy = g*nn.xy;\r\n n.z = g-1.0;\r\n return n;\r\n}\r\n\r\n\r\n// Encoding/decoding [0..1) floats into 8 bit/channel RG. Note that 1.0 will not be encoded properly.\r\nvec2 EncodeFloatRG( float v )\r\n{\r\n vec2 kEncodeMul = vec2(1.0, 255.0);\r\n float kEncodeBit = 1.0/255.0;\r\n vec2 enc = kEncodeMul * v;\r\n enc = fract(enc);\r\n enc.x -= enc.y * kEncodeBit;\r\n return enc;\r\n}\r\n\r\n\r\n\r\nfloat DecodeFloatRG( vec2 enc )\r\n{\r\n vec2 kDecodeDot = vec2(1.0, 1.0/255.0);\r\n return dot( enc, kDecodeDot );\r\n}\r\n\r\nvec4 EncodeDepthNormal(float depth,vec3 normals){\r\n\tvec4 encode;\r\n\tencode.xy = EncodeViewNormalStereo(normals);\r\n\tencode.zw = EncodeFloatRG(depth);\r\n return encode;\r\n}\r\n\r\nvoid DecodeDepthNormal( vec4 enc, out float depth, out vec3 normal )\r\n{\r\n depth = DecodeFloatRG (enc.zw);\r\n normal = DecodeViewNormalStereo (enc);\r\n}\r\n\r\n\r\n\r\nvec4 depthNormalsFragment(vec4 depthNormal)\r\n{\r\n return EncodeDepthNormal(depthNormal.w,depthNormal.xyz);\r\n}\r\n\r\n\r\n// Z buffer to linear 0..1 depth\r\nfloat Linear01Depth(float z,vec4 zbufferParams)\r\n{\r\n return 1.0 / (zbufferParams.x * z + zbufferParams.y);\r\n}\r\n// Z buffer to linear depth\r\nfloat LinearEyeDepth(float z,vec4 zbufferParams)\r\n{\r\n return 1.0 / (zbufferParams.z * z + zbufferParams.w);\r\n}\r\n");var e={a_Position:ie.MESH_POSITION0,a_Color:ie.MESH_COLOR0,a_Normal:ie.MESH_NORMAL0,a_Texcoord0:ie.MESH_TEXTURECOORDINATE0,a_Texcoord1:ie.MESH_TEXTURECOORDINATE1,a_BoneWeights:ie.MESH_BLENDWEIGHT0,a_BoneIndices:ie.MESH_BLENDINDICES0,a_Tangent0:ie.MESH_TANGENT0,a_WorldMat:ie.MESH_WORLDMATRIX_ROW0,a_SimpleTextureParams:ie.MESH_SIMPLEANIMATOR},t={u_Bones:Z.PERIOD_CUSTOM,u_DiffuseTexture:Z.PERIOD_MATERIAL,u_SpecularTexture:Z.PERIOD_MATERIAL,u_NormalTexture:Z.PERIOD_MATERIAL,u_AlphaTestValue:Z.PERIOD_MATERIAL,u_DiffuseColor:Z.PERIOD_MATERIAL,u_AlbedoIntensity:Z.PERIOD_MATERIAL,u_MaterialSpecular:Z.PERIOD_MATERIAL,u_Shininess:Z.PERIOD_MATERIAL,u_TilingOffset:Z.PERIOD_MATERIAL,u_TransmissionRate:Z.PERIOD_MATERIAL,u_BackDiffuse:Z.PERIOD_MATERIAL,u_BackScale:Z.PERIOD_MATERIAL,u_ThinknessTexture:Z.PERIOD_MATERIAL,u_TransmissionColor:Z.PERIOD_MATERIAL,u_WorldMat:Z.PERIOD_SPRITE,u_MvpMatrix:Z.PERIOD_SPRITE,u_LightmapScaleOffset:Z.PERIOD_SPRITE,u_LightMap:Z.PERIOD_SPRITE,u_LightMapDirection:Z.PERIOD_SPRITE,u_SimpleAnimatorTexture:Z.PERIOD_SPRITE,u_SimpleAnimatorParams:Z.PERIOD_SPRITE,u_SimpleAnimatorTextureSize:Z.PERIOD_SPRITE,u_CameraPos:Z.PERIOD_CAMERA,u_Viewport:Z.PERIOD_CAMERA,u_ProjectionParams:Z.PERIOD_CAMERA,u_View:Z.PERIOD_CAMERA,u_ViewProjection:Z.PERIOD_CAMERA,u_ReflectTexture:Z.PERIOD_SCENE,u_FogStart:Z.PERIOD_SCENE,u_FogRange:Z.PERIOD_SCENE,u_FogColor:Z.PERIOD_SCENE,u_DirationLightCount:Z.PERIOD_SCENE,u_LightBuffer:Z.PERIOD_SCENE,u_LightClusterBuffer:Z.PERIOD_SCENE,u_AmbientColor:Z.PERIOD_SCENE,u_ShadowBias:Z.PERIOD_SCENE,u_ShadowLightDirection:Z.PERIOD_SCENE,u_ShadowMap:Z.PERIOD_SCENE,u_ShadowParams:Z.PERIOD_SCENE,u_ShadowSplitSpheres:Z.PERIOD_SCENE,u_ShadowMatrices:Z.PERIOD_SCENE,u_ShadowMapSize:Z.PERIOD_SCENE,u_SpotShadowMap:Z.PERIOD_SCENE,u_SpotViewProjectMatrix:Z.PERIOD_SCENE,u_ShadowLightPosition:Z.PERIOD_SCENE,u_AmbientSHAr:Z.PERIOD_SCENE,u_AmbientSHAg:Z.PERIOD_SCENE,u_AmbientSHAb:Z.PERIOD_SCENE,u_AmbientSHBr:Z.PERIOD_SCENE,u_AmbientSHBg:Z.PERIOD_SCENE,u_AmbientSHBb:Z.PERIOD_SCENE,u_AmbientSHC:Z.PERIOD_SCENE,"u_DirectionLight.color":Z.PERIOD_SCENE,"u_DirectionLight.direction":Z.PERIOD_SCENE,"u_PointLight.position":Z.PERIOD_SCENE,"u_PointLight.range":Z.PERIOD_SCENE,"u_PointLight.color":Z.PERIOD_SCENE,"u_SpotLight.position":Z.PERIOD_SCENE,"u_SpotLight.direction":Z.PERIOD_SCENE,"u_SpotLight.range":Z.PERIOD_SCENE,"u_SpotLight.spot":Z.PERIOD_SCENE,"u_SpotLight.color":Z.PERIOD_SCENE},r={s_Cull:Z.RENDER_STATE_CULL,s_Blend:Z.RENDER_STATE_BLEND,s_BlendSrc:Z.RENDER_STATE_BLEND_SRC,s_BlendDst:Z.RENDER_STATE_BLEND_DST,s_DepthTest:Z.RENDER_STATE_DEPTH_TEST,s_DepthWrite:Z.RENDER_STATE_DEPTH_WRITE},a=Z.add("BLINNPHONG",null,null,!0),n=new Qt(e,t);a.addSubShader(n),n.addShaderPass('#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n#include "Lighting.glsl";\r\n#include "LayaUtile.glsl"\r\n#include "Shadow.glsl";\r\n\r\n\r\nattribute vec4 a_Position;\r\n\r\n#ifdef GPU_INSTANCE\r\n\tuniform mat4 u_ViewProjection;\r\n#else\r\n\tuniform mat4 u_MvpMatrix;\r\n#endif\r\n\r\n#if defined(DIFFUSEMAP)||defined(THICKNESSMAP)||((defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT))&&(defined(SPECULARMAP)||defined(NORMALMAP)))||(defined(LIGHTMAP)&&defined(UV))\r\n\tattribute vec2 a_Texcoord0;\r\n\tvarying vec2 v_Texcoord0;\r\n#endif\r\n\r\n#if defined(LIGHTMAP)&&defined(UV1)\r\n\tattribute vec2 a_Texcoord1;\r\n#endif\r\n\r\n#ifdef LIGHTMAP\r\n\tuniform vec4 u_LightmapScaleOffset;\r\n\tvarying vec2 v_LightMapUV;\r\n#endif\r\n\r\n#ifdef COLOR\r\n\tattribute vec4 a_Color;\r\n\tvarying vec4 v_Color;\r\n#endif\r\n\r\n#ifdef BONE\r\n\tconst int c_MaxBoneCount = 24;\r\n\tattribute vec4 a_BoneIndices;\r\n\tattribute vec4 a_BoneWeights;\r\n\tuniform mat4 u_Bones[c_MaxBoneCount];\r\n#endif\r\n\r\nattribute vec3 a_Normal;\r\nvarying vec3 v_Normal; \r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\tuniform vec3 u_CameraPos;\r\n\tvarying vec3 v_ViewDir; \r\n#endif\r\n\r\n#if defined(NORMALMAP)\r\n\tattribute vec4 a_Tangent0;\r\n\tvarying vec3 v_Tangent;\r\n\tvarying vec3 v_Binormal;\r\n#endif\r\n\r\n#ifdef GPU_INSTANCE\r\n\tattribute mat4 a_WorldMat;\r\n#else\r\n\tuniform mat4 u_WorldMat;\r\n#endif\r\n\r\n#if defined(POINTLIGHT)||defined(SPOTLIGHT)||(defined(CALCULATE_SHADOWS)&&defined(SHADOW_CASCADE))||defined(CALCULATE_SPOTSHADOWS)\r\n\tvarying vec3 v_PositionWorld;\r\n#endif\r\n\r\n#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)\r\n\tvarying vec4 v_ShadowCoord;\r\n#endif\r\n\r\n#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\tvarying vec4 v_SpotShadowCoord;\r\n#endif\r\n\r\nuniform vec4 u_TilingOffset;\r\n\r\nvoid main()\r\n{\r\n\tvec4 position;\r\n\t#ifdef BONE\r\n\t\tmat4 skinTransform;\r\n\t \t#ifdef SIMPLEBONE\r\n\t\t\tfloat currentPixelPos;\r\n\t\t\t#ifdef GPU_INSTANCE\r\n\t\t\t\tcurrentPixelPos = a_SimpleTextureParams.x+a_SimpleTextureParams.y;\r\n\t\t\t#else\r\n\t\t\t\tcurrentPixelPos = u_SimpleAnimatorParams.x+u_SimpleAnimatorParams.y;\r\n\t\t\t#endif\r\n\t\t\tfloat offset = 1.0/u_SimpleAnimatorTextureSize;\r\n\t\t\tskinTransform = loadMatFromTexture(currentPixelPos,int(a_BoneIndices.x),offset) * a_BoneWeights.x;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.y),offset) * a_BoneWeights.y;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.z),offset) * a_BoneWeights.z;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.w),offset) * a_BoneWeights.w;\r\n\t\t#else\r\n\t\t\tskinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;\r\n\t\t#endif\r\n\t\tposition=skinTransform*a_Position;\r\n\t #else\r\n\t\tposition=a_Position;\r\n\t#endif\r\n\r\n\r\n\t\r\n\tmat4 worldMat;\r\n\t#ifdef GPU_INSTANCE\r\n\t\tworldMat = a_WorldMat;\r\n\t#else\r\n\t\tworldMat = u_WorldMat;\r\n\t#endif\r\n\r\n\t#ifdef GPU_INSTANCE\r\n\t\tgl_Position = u_ViewProjection * worldMat * position;\r\n\t#else\r\n\t\tgl_Position = u_MvpMatrix * position;\r\n\t#endif\r\n\r\n\tmat3 worldInvMat;\r\n\t#ifdef BONE\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat*skinTransform));\r\n\t#else\r\n\t\tworldInvMat=INVERSE_MAT(mat3(worldMat));\r\n\t#endif \r\n\tv_Normal=normalize(a_Normal*worldInvMat);\r\n\t#if defined(NORMALMAP)\r\n\t\tv_Tangent=normalize(a_Tangent0.xyz*worldInvMat);\r\n\t\tv_Binormal=cross(v_Normal,v_Tangent)*a_Tangent0.w;\r\n\t#endif\r\n\r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||(defined(CALCULATE_SHADOWS)&&defined(SHADOW_CASCADE))||defined(CALCULATE_SPOTSHADOWS)\r\n\t\tvec3 positionWS=(worldMat*position).xyz;\r\n\t\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\t\tv_ViewDir = u_CameraPos-positionWS;\r\n\t\t#endif\r\n\t\t#if defined(POINTLIGHT)||defined(SPOTLIGHT)||(defined(CALCULATE_SHADOWS)&&defined(SHADOW_CASCADE))||defined(CALCULATE_SPOTSHADOWS)\r\n\t\t\tv_PositionWorld = positionWS;\r\n\t\t#endif\r\n\t#endif\r\n\r\n\t#if defined(DIFFUSEMAP)||defined(THICKNESSMAP)||((defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT))&&(defined(SPECULARMAP)||defined(NORMALMAP)))\r\n\t\tv_Texcoord0=TransformUV(a_Texcoord0,u_TilingOffset);\r\n\t#endif\r\n\r\n\t#ifdef LIGHTMAP\r\n\t\t#ifdef UV1\r\n\t\t\tv_LightMapUV=vec2(a_Texcoord1.x,1.0-a_Texcoord1.y)*u_LightmapScaleOffset.xy+u_LightmapScaleOffset.zw;\r\n\t\t#else\r\n\t\t\tv_LightMapUV=vec2(a_Texcoord0.x,1.0-a_Texcoord0.y)*u_LightmapScaleOffset.xy+u_LightmapScaleOffset.zw;\r\n\t\t#endif \r\n\t\tv_LightMapUV.y=1.0-v_LightMapUV.y;\r\n\t#endif\r\n\r\n\t#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)\r\n\t\tv_Color=a_Color;\r\n\t#endif\r\n\r\n\t#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)\r\n\t\tv_ShadowCoord =getShadowCoord(vec4(positionWS,1.0));\r\n\t#endif\r\n\r\n\t#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\tv_SpotShadowCoord = u_SpotViewProjectMatrix*vec4(positionWS,1.0);\r\n\t#endif\r\n\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}','#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n\r\n\r\n#include "Lighting.glsl";\r\n#include "Shadow.glsl"\r\n\r\nuniform vec4 u_DiffuseColor;\r\nuniform float u_AlbedoIntensity;\r\n\r\n#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)\r\n\tvarying vec4 v_Color;\r\n#endif\r\n\r\n#ifdef ALPHATEST\r\n\tuniform float u_AlphaTestValue;\r\n#endif\r\n\r\n#ifdef DIFFUSEMAP\r\n\tuniform sampler2D u_DiffuseTexture;\r\n#endif\r\n\r\n\r\n#if defined(DIFFUSEMAP)||defined(THICKNESSMAP)||((defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT))&&(defined(SPECULARMAP)||defined(NORMALMAP)))\r\n\tvarying vec2 v_Texcoord0;\r\n#endif\r\n\r\n#ifdef LIGHTMAP\r\n\tvarying vec2 v_LightMapUV;\r\n\tuniform sampler2D u_LightMap;\r\n\t#ifdef LIGHTMAP_DIRECTIONAL\r\n\t\tuniform sampler2D u_LightMapDirection;\r\n\t#endif\r\n#endif\r\n\r\nvarying vec3 v_Normal;\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\tvarying vec3 v_ViewDir; \r\n\r\n\tuniform vec3 u_MaterialSpecular;\r\n\tuniform float u_Shininess;\r\n\r\n\t#ifdef LEGACYSINGLELIGHTING\r\n\t\t#ifdef DIRECTIONLIGHT\r\n\t\t\tuniform DirectionLight u_DirectionLight;\r\n\t\t#endif\r\n\t\t#ifdef POINTLIGHT\r\n\t\t\tuniform PointLight u_PointLight;\r\n\t\t#endif\r\n\t\t#ifdef SPOTLIGHT\r\n\t\t\tuniform SpotLight u_SpotLight;\r\n\t\t#endif\r\n\t#else\r\n\t\tuniform mat4 u_View;\r\n\t\tuniform vec4 u_ProjectionParams;\r\n\t\tuniform vec4 u_Viewport;\r\n\t\tuniform int u_DirationLightCount;\r\n\t\tuniform sampler2D u_LightBuffer;\r\n\t\tuniform sampler2D u_LightClusterBuffer;\r\n\t#endif\r\n\r\n\t#ifdef SPECULARMAP \r\n\t\tuniform sampler2D u_SpecularTexture;\r\n\t#endif\r\n#endif\r\n\r\n#ifdef NORMALMAP \r\n\tuniform sampler2D u_NormalTexture;\r\n\tvarying vec3 v_Tangent;\r\n\tvarying vec3 v_Binormal;\r\n#endif\r\n\r\n#ifdef FOG\r\n\tuniform float u_FogStart;\r\n\tuniform float u_FogRange;\r\n\tuniform vec3 u_FogColor;\r\n#endif\r\n\r\n#if defined(POINTLIGHT)||defined(SPOTLIGHT)||(defined(CALCULATE_SHADOWS)&&defined(SHADOW_CASCADE))||defined(CALCULATE_SPOTSHADOWS)\r\n\tvarying vec3 v_PositionWorld;\r\n#endif\r\n\r\n\r\n#include "GlobalIllumination.glsl";//"GlobalIllumination.glsl use uniform should at front of this\r\n\r\n#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)\r\n\tvarying vec4 v_ShadowCoord;\r\n#endif\r\n\r\n#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\tvarying vec4 v_SpotShadowCoord;\r\n#endif\r\n\r\n\r\nvoid main()\r\n{\r\n\tvec3 normal;//light and SH maybe use normal\r\n\t#if defined(NORMALMAP)\r\n\t\tvec3 normalMapSample = texture2D(u_NormalTexture, v_Texcoord0).rgb;\r\n\t\tnormal = normalize(NormalSampleToWorldSpace(normalMapSample, v_Normal, v_Tangent,v_Binormal));\r\n\t#else\r\n\t\tnormal = normalize(v_Normal);\r\n\t#endif\r\n\r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\tvec3 viewDir= normalize(v_ViewDir);\r\n\t#endif\r\n\r\n\tLayaGIInput giInput;\r\n\t#ifdef LIGHTMAP\t\r\n\t\tgiInput.lightmapUV=v_LightMapUV;\r\n\t#endif\r\n\tvec3 globalDiffuse=layaGIBase(giInput,1.0,normal);\r\n\t\r\n\tvec4 mainColor = u_DiffuseColor * u_AlbedoIntensity;\r\n\t#ifdef DIFFUSEMAP\r\n\t\tvec4 difTexColor=texture2D(u_DiffuseTexture, v_Texcoord0);\r\n\t\tmainColor=mainColor*difTexColor;\r\n\t#endif \r\n\t#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)\r\n\t\tmainColor=mainColor*v_Color;\r\n\t#endif \r\n \r\n\t#ifdef ALPHATEST\r\n\t\tif(mainColor.a= u_DirationLightCount)\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tDirectionLight directionLight = getDirectionLight(u_LightBuffer,i);\r\n\t\t\t\t#if defined(CALCULATE_SHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\t\t\t\tif(i == 0)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t#ifdef SHADOW_CASCADE\r\n\t\t\t\t\t\t\tvec4 shadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));\r\n\t\t\t\t\t\t#else\r\n\t\t\t\t\t\t\tvec4 shadowCoord = v_ShadowCoord;\r\n\t\t\t\t\t\t#endif\r\n\t\t\t\t\t\tdirectionLight.color *= sampleShadowmap(shadowCoord);\r\n\t\t\t\t\t}\r\n\t\t\t\t#endif\r\n\t\t\t\tLayaAirBlinnPhongDiectionLight(u_MaterialSpecular,u_Shininess,normal,gloss,viewDir,directionLight,transmissionFactor,dif,spe,transmis);\r\n\t\t\t\tdiffuse+=dif;\r\n\t\t\t\tspecular+=spe;\r\n\t\t\t\ttransmissionDiffuse+=transmis;\r\n\t\t\t}\r\n\t\t#endif\r\n\t\t#if defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\t\tivec4 clusterInfo =getClusterInfo(u_LightClusterBuffer,u_View,u_Viewport, v_PositionWorld,gl_FragCoord,u_ProjectionParams);\r\n\t\t\t#ifdef POINTLIGHT\r\n\t\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t\t{\r\n\t\t\t\t\tif(i >= clusterInfo.x)//PointLightCount\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tPointLight pointLight = getPointLight(u_LightBuffer,u_LightClusterBuffer,clusterInfo,i);\r\n\t\t\t\t\tLayaAirBlinnPhongPointLight(v_PositionWorld,u_MaterialSpecular,u_Shininess,normal,gloss,viewDir,pointLight,transmissionFactor,dif,spe,transmis);\r\n\t\t\t\t\tdiffuse+=dif;\r\n\t\t\t\t\tspecular+=spe;\r\n\t\t\t\t\ttransmissionDiffuse+=transmis;\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t\t#ifdef SPOTLIGHT\r\n\t\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t\t{\r\n\t\t\t\t\tif(i >= clusterInfo.y)//SpotLightCount\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tSpotLight spotLight = getSpotLight(u_LightBuffer,u_LightClusterBuffer,clusterInfo,i);\r\n\t\t\t\t\t#if defined(CALCULATE_SPOTSHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\t\t\t\t\tif(i == 0)\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\tvec4 spotShadowcoord = v_SpotShadowCoord;\r\n\t\t\t\t\t\t\tspotLight.color *= sampleSpotShadowmap(spotShadowcoord);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t#endif\r\n\t\t\t\t\tLayaAirBlinnPhongSpotLight(v_PositionWorld,u_MaterialSpecular,u_Shininess,normal,gloss,viewDir,spotLight,transmissionFactor,dif,spe,transmis);\r\n\t\t\t\t\tdiffuse+=dif;\r\n\t\t\t\t\tspecular+=spe;\r\n\t\t\t\t\ttransmissionDiffuse+=transmis;\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t#endif\r\n\t#endif\r\n\r\n\tgl_FragColor =vec4(mainColor.rgb*(globalDiffuse + diffuse),mainColor.a);\r\n\r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\tgl_FragColor.rgb+=specular;\r\n\t#endif\r\n\r\n\t#ifdef ENABLETRANSMISSION\r\n\t\tgl_FragColor.rgb+= transmissionDiffuse;\r\n\t#endif\r\n\r\n\t \r\n\t#ifdef FOG\r\n\t\tfloat lerpFact=clamp((1.0/gl_FragCoord.w-u_FogStart)/u_FogRange,0.0,1.0);\r\n\t\tgl_FragColor.rgb=mix(gl_FragColor.rgb,u_FogColor,lerpFact);\r\n\t#endif\r\n\r\n\t//gl_FragColor.rgb =transmissionDiffuse;\r\n}\r\n\r\n',r,"Forward");n.addShaderPass('#include "ShadowCasterVS.glsl"\r\n\r\nvoid main()\r\n{\r\n\tvec4 positionCS = shadowCasterVertex();\r\n\tgl_Position=remapGLPositionZ(positionCS);\r\n}','#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n\tprecision highp int;\r\n#else\r\n\tprecision mediump float;\r\n\tprecision mediump int;\r\n#endif\r\n\r\n#include "ShadowCasterFS.glsl"\r\n\r\nvoid main()\r\n{\r\n\tgl_FragColor=shadowCasterFragment();\r\n}',r,"ShadowCaster");n.addShaderPass(we,be,r,"DepthNormal"),e={a_Position:ie.MESH_POSITION0,a_Color:ie.MESH_COLOR0},t={u_MvpMatrix:Z.PERIOD_SPRITE,u_Color:Z.PERIOD_MATERIAL},r={s_Cull:Z.RENDER_STATE_CULL,s_Blend:Z.RENDER_STATE_BLEND,s_BlendSrc:Z.RENDER_STATE_BLEND_SRC,s_BlendDst:Z.RENDER_STATE_BLEND_DST,s_DepthTest:Z.RENDER_STATE_DEPTH_TEST,s_DepthWrite:Z.RENDER_STATE_DEPTH_WRITE},a=Z.add("LineShader"),n=new Qt(e,t),a.addSubShader(n),n.addShaderPass('#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\nprecision highp float;\r\n#else\r\nprecision mediump float;\r\n#endif\r\n\r\n#include "Lighting.glsl";\r\n\r\nattribute vec4 a_Position;\r\nuniform mat4 u_MvpMatrix;\r\nuniform vec4 u_Color;\r\nattribute vec4 a_Color;\r\nvarying vec4 v_Color;\r\n\r\n\r\nvoid main()\r\n{\r\n\tgl_Position = u_MvpMatrix * a_Position;\r\n\tv_Color=a_Color*u_Color;\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}',"#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\nprecision highp float;\r\n#else\r\nprecision mediump float;\r\n#endif\r\n\r\nvarying vec4 v_Color;\r\nuniform vec4 u_Color;\r\n\r\nvoid main()\r\n{\r\n gl_FragColor = v_Color * u_Color; \r\n}\r\n\r\n",r),e={a_Position:ie.MESH_POSITION0,a_Color:ie.MESH_COLOR0,a_Texcoord0:ie.MESH_TEXTURECOORDINATE0,a_BoneWeights:ie.MESH_BLENDWEIGHT0,a_BoneIndices:ie.MESH_BLENDINDICES0,a_WorldMat:ie.MESH_WORLDMATRIX_ROW0,a_SimpleTextureParams:ie.MESH_SIMPLEANIMATOR},t={u_Bones:Z.PERIOD_CUSTOM,u_AlbedoTexture:Z.PERIOD_MATERIAL,u_AlbedoColor:Z.PERIOD_MATERIAL,u_TilingOffset:Z.PERIOD_MATERIAL,u_AlphaTestValue:Z.PERIOD_MATERIAL,u_MvpMatrix:Z.PERIOD_SPRITE,u_ViewProjection:Z.PERIOD_CAMERA,u_SimpleAnimatorTexture:Z.PERIOD_SPRITE,u_SimpleAnimatorParams:Z.PERIOD_SPRITE,u_SimpleAnimatorTextureSize:Z.PERIOD_SPRITE,u_FogStart:Z.PERIOD_SCENE,u_FogRange:Z.PERIOD_SCENE,u_FogColor:Z.PERIOD_SCENE},r={s_Cull:Z.RENDER_STATE_CULL,s_Blend:Z.RENDER_STATE_BLEND,s_BlendSrc:Z.RENDER_STATE_BLEND_SRC,s_BlendDst:Z.RENDER_STATE_BLEND_DST,s_DepthTest:Z.RENDER_STATE_DEPTH_TEST,s_DepthWrite:Z.RENDER_STATE_DEPTH_WRITE},a=Z.add("Unlit",null,null,!0),n=new Qt(e,t),a.addSubShader(n),n.addShaderPass('#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n#include "Lighting.glsl";\r\n#include "LayaUtile.glsl";\r\n\r\nattribute vec4 a_Position;\r\n\r\nattribute vec2 a_Texcoord0;\r\n\r\n#ifdef GPU_INSTANCE\r\n\tuniform mat4 u_ViewProjection;\r\n\tattribute mat4 a_WorldMat;\r\n#else\r\n\tuniform mat4 u_MvpMatrix;\r\n#endif\r\n\r\nattribute vec4 a_Color;\r\nvarying vec4 v_Color;\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform vec4 u_TilingOffset;\r\n\r\n#ifdef BONE\r\n\tconst int c_MaxBoneCount = 24;\r\n\tattribute vec4 a_BoneIndices;\r\n\tattribute vec4 a_BoneWeights;\r\n\tuniform mat4 u_Bones[c_MaxBoneCount];\r\n#endif\r\n\r\nvoid main() {\r\n\tvec4 position;\r\n\t#ifdef BONE\r\n\t\tmat4 skinTransform;\r\n\t \t#ifdef SIMPLEBONE\r\n\t\t\tfloat currentPixelPos;\r\n\t\t\t#ifdef GPU_INSTANCE\r\n\t\t\t\tcurrentPixelPos = a_SimpleTextureParams.x+a_SimpleTextureParams.y;\r\n\t\t\t#else\r\n\t\t\t\tcurrentPixelPos = u_SimpleAnimatorParams.x+u_SimpleAnimatorParams.y;\r\n\t\t\t#endif\r\n\t\t\tfloat offset = 1.0/u_SimpleAnimatorTextureSize;\r\n\t\t\tskinTransform = loadMatFromTexture(currentPixelPos,int(a_BoneIndices.x),offset) * a_BoneWeights.x;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.y),offset) * a_BoneWeights.y;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.z),offset) * a_BoneWeights.z;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.w),offset) * a_BoneWeights.w;\r\n\t\t#else\r\n\t\t\tskinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;\r\n\t\t#endif\r\n\t\tposition=skinTransform*a_Position;\r\n\t #else\r\n\t\tposition=a_Position;\r\n\t#endif\r\n\t#ifdef GPU_INSTANCE\r\n\t\tgl_Position =u_ViewProjection * a_WorldMat * position;\r\n\t#else\r\n\t\tgl_Position = u_MvpMatrix * position;\r\n\t#endif\r\n\r\n\tv_Texcoord0=TransformUV(a_Texcoord0,u_TilingOffset);\r\n\r\n\t#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)\r\n\t\tv_Color = a_Color;\r\n\t#endif\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}',"#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)\r\n\tvarying vec4 v_Color;\r\n#endif\r\n\r\n#ifdef ALBEDOTEXTURE\r\n\tuniform sampler2D u_AlbedoTexture;\r\n\tvarying vec2 v_Texcoord0;\r\n#endif\r\n\r\nuniform vec4 u_AlbedoColor;\r\n\r\n#ifdef ALPHATEST\r\n\tuniform float u_AlphaTestValue;\r\n#endif\r\n\r\n#ifdef FOG\r\n\tuniform float u_FogStart;\r\n\tuniform float u_FogRange;\r\n\t#ifdef ADDTIVEFOG\r\n\t#else\r\n\t\tuniform vec3 u_FogColor;\r\n\t#endif\r\n#endif\r\n\r\nvoid main()\r\n{\r\n\tvec4 color = u_AlbedoColor;\r\n\t#ifdef ALBEDOTEXTURE\r\n\t\tcolor *= texture2D(u_AlbedoTexture, v_Texcoord0);\r\n\t#endif\r\n\t#if defined(COLOR)&&defined(ENABLEVERTEXCOLOR)\r\n\t\tcolor *= v_Color;\r\n\t#endif\r\n\t\r\n\t#ifdef ALPHATEST\r\n\t\tif(color.a < u_AlphaTestValue)\r\n\t\t\tdiscard;\r\n\t#endif\r\n\t\r\n\tgl_FragColor = color;\r\n\t\r\n\t#ifdef FOG\r\n\t\tfloat lerpFact = clamp((1.0 / gl_FragCoord.w - u_FogStart) / u_FogRange, 0.0, 1.0);\r\n\t\t#ifdef ADDTIVEFOG\r\n\t\t\tgl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.0), lerpFact);\r\n\t\t#else\r\n\t\t\tgl_FragColor.rgb = mix(gl_FragColor.rgb, u_FogColor, lerpFact);\r\n\t\t#endif\r\n\t#endif\r\n\t\r\n}\r\n\r\n",r),e={a_Position:ie.MESH_POSITION0,a_Texcoord0:ie.MESH_TEXTURECOORDINATE0,a_BoneWeights:ie.MESH_BLENDWEIGHT0,a_BoneIndices:ie.MESH_BLENDINDICES0,a_WorldMat:ie.MESH_WORLDMATRIX_ROW0,a_SimpleTextureParams:ie.MESH_SIMPLEANIMATOR},t={u_Bones:Z.PERIOD_CUSTOM,u_AlbedoTexture:Z.PERIOD_MATERIAL,u_AlbedoColor:Z.PERIOD_MATERIAL,u_TilingOffset:Z.PERIOD_MATERIAL,u_AlphaTestValue:Z.PERIOD_MATERIAL,u_ViewProjection:Z.PERIOD_CAMERA,u_MvpMatrix:Z.PERIOD_SPRITE,u_SimpleAnimatorTexture:Z.PERIOD_SPRITE,u_SimpleAnimatorParams:Z.PERIOD_SPRITE,u_SimpleAnimatorTextureSize:Z.PERIOD_SPRITE,u_FogStart:Z.PERIOD_SCENE,u_FogRange:Z.PERIOD_SCENE,u_FogColor:Z.PERIOD_SCENE},r={s_Cull:Z.RENDER_STATE_CULL,s_Blend:Z.RENDER_STATE_BLEND,s_BlendSrc:Z.RENDER_STATE_BLEND_SRC,s_BlendDst:Z.RENDER_STATE_BLEND_DST,s_DepthTest:Z.RENDER_STATE_DEPTH_TEST,s_DepthWrite:Z.RENDER_STATE_DEPTH_WRITE},a=Z.add("Effect",null,null,!0),n=new Qt(e,t),a.addSubShader(n),n.addShaderPass('#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n#include "Lighting.glsl";\r\n#include "LayaUtile.glsl";\r\n\r\nattribute vec4 a_Position;\r\nattribute vec4 a_Color;\r\nattribute vec2 a_Texcoord0;\r\n\r\n#ifdef GPU_INSTANCE\r\n\tuniform mat4 u_ViewProjection;\r\n\tattribute mat4 a_WorldMat;\r\n#else\r\n\tuniform mat4 u_MvpMatrix;\r\n#endif\r\n\r\n#ifdef COLOR\r\n\tvarying vec4 v_Color;\r\n#endif\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform vec4 u_TilingOffset;\r\n\r\n#ifdef BONE\r\n\tconst int c_MaxBoneCount = 24;\r\n\tattribute vec4 a_BoneIndices;\r\n\tattribute vec4 a_BoneWeights;\r\n\tuniform mat4 u_Bones[c_MaxBoneCount];\r\n#endif\r\n\r\n\r\nvoid main()\r\n{\r\n\tvec4 position;\r\n\t#ifdef BONE\r\n\t\tmat4 skinTransform;\r\n\t \t#ifdef SIMPLEBONE\r\n\t\t\tfloat currentPixelPos;\r\n\t\t\t#ifdef GPU_INSTANCE\r\n\t\t\t\tcurrentPixelPos = a_SimpleTextureParams.x+a_SimpleTextureParams.y;\r\n\t\t\t#else\r\n\t\t\t\tcurrentPixelPos = u_SimpleAnimatorParams.x+u_SimpleAnimatorParams.y;\r\n\t\t\t#endif\r\n\t\t\tfloat offset = 1.0/u_SimpleAnimatorTextureSize;\r\n\t\t\tskinTransform = loadMatFromTexture(currentPixelPos,int(a_BoneIndices.x),offset) * a_BoneWeights.x;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.y),offset) * a_BoneWeights.y;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.z),offset) * a_BoneWeights.z;\r\n\t\t\tskinTransform += loadMatFromTexture(currentPixelPos,int(a_BoneIndices.w),offset) * a_BoneWeights.w;\r\n\t\t#else\r\n\t\t\tskinTransform = u_Bones[int(a_BoneIndices.x)] * a_BoneWeights.x;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.y)] * a_BoneWeights.y;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.z)] * a_BoneWeights.z;\r\n\t\t\tskinTransform += u_Bones[int(a_BoneIndices.w)] * a_BoneWeights.w;\r\n\t\t#endif\r\n\t\tposition=skinTransform*a_Position;\r\n\t #else\r\n\t\tposition=a_Position;\r\n\t#endif\r\n\t#ifdef GPU_INSTANCE\r\n\t\tgl_Position = u_ViewProjection * a_WorldMat * position;\r\n\t#else\r\n\t\tgl_Position = u_MvpMatrix * position;\r\n\t#endif\r\n\t\r\n\tv_Texcoord0=TransformUV(a_Texcoord0,u_TilingOffset);\r\n\t\t\r\n\t#ifdef COLOR\r\n\t\tv_Color = a_Color;\r\n\t#endif\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}',"#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#ifdef COLOR\r\n\tvarying vec4 v_Color;\r\n#endif\r\nvarying vec2 v_Texcoord0;\r\n\r\n#ifdef MAINTEXTURE\r\n\tuniform sampler2D u_AlbedoTexture;\r\n#endif\r\n\r\nuniform vec4 u_AlbedoColor;\r\n\r\n#ifdef FOG\r\n\tuniform float u_FogStart;\r\n\tuniform float u_FogRange;\r\n\t#ifdef ADDTIVEFOG\r\n\t#else\r\n\t\tuniform vec3 u_FogColor;\r\n\t#endif\r\n#endif\r\n\r\nvoid main()\r\n{\r\n\tvec4 color = 2.0 * u_AlbedoColor;\r\n\t#ifdef COLOR\r\n\t\tcolor *= v_Color;\r\n\t#endif\r\n\t#ifdef MAINTEXTURE\r\n\t\tcolor *= texture2D(u_AlbedoTexture, v_Texcoord0);\r\n\t#endif\r\n\t\r\n\tgl_FragColor = color;\r\n\t\r\n\t#ifdef FOG\r\n\t\tfloat lerpFact = clamp((1.0 / gl_FragCoord.w - u_FogStart) / u_FogRange, 0.0, 1.0);\r\n\t\t#ifdef ADDTIVEFOG\r\n\t\t\tgl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.0), lerpFact);\r\n\t\t#else\r\n\t\t\tgl_FragColor.rgb = mix(gl_FragColor.rgb, u_FogColor, lerpFact);\r\n\t\t#endif\r\n\t#endif\r\n}\r\n\r\n",r),e={a_CornerTextureCoordinate:Fr.PARTICLE_CORNERTEXTURECOORDINATE0,a_MeshPosition:Fr.PARTICLE_POSITION0,a_MeshColor:Fr.PARTICLE_COLOR0,a_MeshTextureCoordinate:Fr.PARTICLE_TEXTURECOORDINATE0,a_ShapePositionStartLifeTime:Fr.PARTICLE_SHAPEPOSITIONSTARTLIFETIME,a_DirectionTime:Fr.PARTICLE_DIRECTIONTIME,a_StartColor:Fr.PARTICLE_STARTCOLOR0,a_EndColor:Fr.PARTICLE_ENDCOLOR0,a_StartSize:Fr.PARTICLE_STARTSIZE,a_StartRotation0:Fr.PARTICLE_STARTROTATION,a_StartSpeed:Fr.PARTICLE_STARTSPEED,a_Random0:Fr.PARTICLE_RANDOM0,a_Random1:Fr.PARTICLE_RANDOM1,a_SimulationWorldPostion:Fr.PARTICLE_SIMULATIONWORLDPOSTION,a_SimulationWorldRotation:Fr.PARTICLE_SIMULATIONWORLDROTATION},t={u_Tintcolor:Z.PERIOD_MATERIAL,u_TilingOffset:Z.PERIOD_MATERIAL,u_texture:Z.PERIOD_MATERIAL,u_WorldPosition:Z.PERIOD_SPRITE,u_WorldRotation:Z.PERIOD_SPRITE,u_PositionScale:Z.PERIOD_SPRITE,u_SizeScale:Z.PERIOD_SPRITE,u_ScalingMode:Z.PERIOD_SPRITE,u_Gravity:Z.PERIOD_SPRITE,u_ThreeDStartRotation:Z.PERIOD_SPRITE,u_StretchedBillboardLengthScale:Z.PERIOD_SPRITE,u_StretchedBillboardSpeedScale:Z.PERIOD_SPRITE,u_SimulationSpace:Z.PERIOD_SPRITE,u_CurrentTime:Z.PERIOD_SPRITE,u_ColorOverLifeGradientAlphas:Z.PERIOD_SPRITE,u_ColorOverLifeGradientColors:Z.PERIOD_SPRITE,u_MaxColorOverLifeGradientAlphas:Z.PERIOD_SPRITE,u_MaxColorOverLifeGradientColors:Z.PERIOD_SPRITE,u_VOLVelocityConst:Z.PERIOD_SPRITE,u_VOLVelocityGradientX:Z.PERIOD_SPRITE,u_VOLVelocityGradientY:Z.PERIOD_SPRITE,u_VOLVelocityGradientZ:Z.PERIOD_SPRITE,u_VOLVelocityConstMax:Z.PERIOD_SPRITE,u_VOLVelocityGradientMaxX:Z.PERIOD_SPRITE,u_VOLVelocityGradientMaxY:Z.PERIOD_SPRITE,u_VOLVelocityGradientMaxZ:Z.PERIOD_SPRITE,u_VOLSpaceType:Z.PERIOD_SPRITE,u_SOLSizeGradient:Z.PERIOD_SPRITE,u_SOLSizeGradientX:Z.PERIOD_SPRITE,u_SOLSizeGradientY:Z.PERIOD_SPRITE,u_SOLSizeGradientZ:Z.PERIOD_SPRITE,u_SOLSizeGradientMax:Z.PERIOD_SPRITE,u_SOLSizeGradientMaxX:Z.PERIOD_SPRITE,u_SOLSizeGradientMaxY:Z.PERIOD_SPRITE,u_SOLSizeGradientMaxZ:Z.PERIOD_SPRITE,u_ROLAngularVelocityConst:Z.PERIOD_SPRITE,u_ROLAngularVelocityConstSeprarate:Z.PERIOD_SPRITE,u_ROLAngularVelocityGradient:Z.PERIOD_SPRITE,u_ROLAngularVelocityGradientX:Z.PERIOD_SPRITE,u_ROLAngularVelocityGradientY:Z.PERIOD_SPRITE,u_ROLAngularVelocityGradientZ:Z.PERIOD_SPRITE,u_ROLAngularVelocityConstMax:Z.PERIOD_SPRITE,u_ROLAngularVelocityConstMaxSeprarate:Z.PERIOD_SPRITE,u_ROLAngularVelocityGradientMax:Z.PERIOD_SPRITE,u_ROLAngularVelocityGradientMaxX:Z.PERIOD_SPRITE,u_ROLAngularVelocityGradientMaxY:Z.PERIOD_SPRITE,u_ROLAngularVelocityGradientMaxZ:Z.PERIOD_SPRITE,u_ROLAngularVelocityGradientMaxW:Z.PERIOD_SPRITE,u_TSACycles:Z.PERIOD_SPRITE,u_TSASubUVLength:Z.PERIOD_SPRITE,u_TSAGradientUVs:Z.PERIOD_SPRITE,u_TSAMaxGradientUVs:Z.PERIOD_SPRITE,u_CameraPos:Z.PERIOD_CAMERA,u_CameraDirection:Z.PERIOD_CAMERA,u_CameraUp:Z.PERIOD_CAMERA,u_View:Z.PERIOD_CAMERA,u_Projection:Z.PERIOD_CAMERA,u_FogStart:Z.PERIOD_SCENE,u_FogRange:Z.PERIOD_SCENE,u_FogColor:Z.PERIOD_SCENE},r={s_Cull:Z.RENDER_STATE_CULL,s_Blend:Z.RENDER_STATE_BLEND,s_BlendSrc:Z.RENDER_STATE_BLEND_SRC,s_BlendDst:Z.RENDER_STATE_BLEND_DST,s_DepthTest:Z.RENDER_STATE_DEPTH_TEST,s_DepthWrite:Z.RENDER_STATE_DEPTH_WRITE},a=Z.add("PARTICLESHURIKEN"),n=new Qt(e,t),a.addSubShader(n),n.addShaderPass('// #include "Lighting.glsl";\r\n\r\n//修改这里剔除没有用到的光照函数,增加粒子的编译速度\r\nvec2 TransformUV(vec2 texcoord,vec4 tilingOffset) {\r\n\tvec2 transTexcoord=vec2(texcoord.x,texcoord.y-1.0)*tilingOffset.xy+vec2(tilingOffset.z,-tilingOffset.w);\r\n\ttransTexcoord.y+=1.0;\r\n\treturn transTexcoord;\r\n}\r\n\r\nvec4 remapGLPositionZ(vec4 position) {\r\n\tposition.z=position.z * 2.0 - position.w;\r\n\treturn position;\r\n}\r\n\r\n#if defined(GL_FRAGMENT_PRECISION_HIGH)\r\n precision highp float;\r\n#else\r\n precision mediump float;\r\n#endif\r\n\r\n#if defined(SPHERHBILLBOARD)||defined(STRETCHEDBILLBOARD)||defined(HORIZONTALBILLBOARD)||defined(VERTICALBILLBOARD)\r\n\tattribute vec4 a_CornerTextureCoordinate;\r\n#endif\r\n#ifdef RENDERMODE_MESH\r\n\tattribute vec3 a_MeshPosition;\r\n\tattribute vec4 a_MeshColor;\r\n\tattribute vec2 a_MeshTextureCoordinate;\r\n\tvarying vec4 v_MeshColor;\r\n#endif\r\n\r\nattribute vec4 a_ShapePositionStartLifeTime;\r\nattribute vec4 a_DirectionTime;\r\nattribute vec4 a_StartColor;\r\nattribute vec3 a_StartSize;\r\nattribute vec3 a_StartRotation0;\r\nattribute float a_StartSpeed;\r\n#if defined(COLOROVERLIFETIME)||defined(RANDOMCOLOROVERLIFETIME)||defined(SIZEOVERLIFETIMERANDOMCURVES)||defined(SIZEOVERLIFETIMERANDOMCURVESSEPERATE)||defined(ROTATIONOVERLIFETIMERANDOMCONSTANTS)||defined(ROTATIONOVERLIFETIMERANDOMCURVES)\r\n attribute vec4 a_Random0;\r\n#endif\r\n#if defined(TEXTURESHEETANIMATIONRANDOMCURVE)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\n attribute vec4 a_Random1;\r\n#endif\r\nattribute vec3 a_SimulationWorldPostion;\r\nattribute vec4 a_SimulationWorldRotation;\r\n\r\nvarying vec4 v_Color;\r\n#ifdef DIFFUSEMAP\r\n\tvarying vec2 v_TextureCoordinate;\r\n#endif\r\n\r\nuniform float u_CurrentTime;\r\nuniform vec3 u_Gravity;\r\n\r\nuniform vec3 u_WorldPosition;\r\nuniform vec4 u_WorldRotation;\r\nuniform bool u_ThreeDStartRotation;\r\nuniform int u_ScalingMode;\r\nuniform vec3 u_PositionScale;\r\nuniform vec3 u_SizeScale;\r\nuniform mat4 u_View;\r\nuniform mat4 u_Projection;\r\n\r\n#ifdef STRETCHEDBILLBOARD\r\n\tuniform vec3 u_CameraPos;\r\n#endif\r\nuniform vec3 u_CameraDirection;//TODO:只有几种广告牌模式需要用\r\nuniform vec3 u_CameraUp;\r\n\r\nuniform float u_StretchedBillboardLengthScale;\r\nuniform float u_StretchedBillboardSpeedScale;\r\nuniform int u_SimulationSpace;\r\n\r\n#if defined(VELOCITYOVERLIFETIMECONSTANT)||defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\n uniform int u_VOLSpaceType;\r\n#endif\r\n#if defined(VELOCITYOVERLIFETIMECONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)\r\n uniform vec3 u_VOLVelocityConst;\r\n#endif\r\n#if defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\n uniform vec2 u_VOLVelocityGradientX[4];//x为key,y为速度\r\n uniform vec2 u_VOLVelocityGradientY[4];//x为key,y为速度\r\n uniform vec2 u_VOLVelocityGradientZ[4];//x为key,y为速度\r\n#endif\r\n#ifdef VELOCITYOVERLIFETIMERANDOMCONSTANT\r\n uniform vec3 u_VOLVelocityConstMax;\r\n#endif\r\n#ifdef VELOCITYOVERLIFETIMERANDOMCURVE\r\n uniform vec2 u_VOLVelocityGradientMaxX[4];//x为key,y为速度\r\n uniform vec2 u_VOLVelocityGradientMaxY[4];//x为key,y为速度\r\n uniform vec2 u_VOLVelocityGradientMaxZ[4];//x为key,y为速度\r\n#endif\r\n\r\n#ifdef COLOROVERLIFETIME\r\n uniform vec4 u_ColorOverLifeGradientColors[4];//x为key,yzw为Color\r\n uniform vec2 u_ColorOverLifeGradientAlphas[4];//x为key,y为Alpha\r\n#endif\r\n#ifdef RANDOMCOLOROVERLIFETIME\r\n uniform vec4 u_ColorOverLifeGradientColors[4];//x为key,yzw为Color\r\n uniform vec2 u_ColorOverLifeGradientAlphas[4];//x为key,y为Alpha\r\n uniform vec4 u_MaxColorOverLifeGradientColors[4];//x为key,yzw为Color\r\n uniform vec2 u_MaxColorOverLifeGradientAlphas[4];//x为key,y为Alpha\r\n#endif\r\n\r\n\r\n#if defined(SIZEOVERLIFETIMECURVE)||defined(SIZEOVERLIFETIMERANDOMCURVES)\r\n uniform vec2 u_SOLSizeGradient[4];//x为key,y为尺寸\r\n#endif\r\n#ifdef SIZEOVERLIFETIMERANDOMCURVES\r\n uniform vec2 u_SOLSizeGradientMax[4];//x为key,y为尺寸\r\n#endif\r\n#if defined(SIZEOVERLIFETIMECURVESEPERATE)||defined(SIZEOVERLIFETIMERANDOMCURVESSEPERATE)\r\n uniform vec2 u_SOLSizeGradientX[4];//x为key,y为尺寸\r\n uniform vec2 u_SOLSizeGradientY[4];//x为key,y为尺寸\r\n uniform vec2 u_SOLSizeGradientZ[4];//x为key,y为尺寸\r\n#endif\r\n#ifdef SIZEOVERLIFETIMERANDOMCURVESSEPERATE\r\n uniform vec2 u_SOLSizeGradientMaxX[4];//x为key,y为尺寸\r\n uniform vec2 u_SOLSizeGradientMaxY[4];//x为key,y为尺寸\r\n uniform vec2 u_SOLSizeGradientMaxZ[4];//x为key,y为尺寸\r\n#endif\r\n\r\n\r\n#ifdef ROTATIONOVERLIFETIME\r\n #if defined(ROTATIONOVERLIFETIMECONSTANT)||defined(ROTATIONOVERLIFETIMERANDOMCONSTANTS)\r\n uniform float u_ROLAngularVelocityConst;\r\n #endif\r\n #ifdef ROTATIONOVERLIFETIMERANDOMCONSTANTS\r\n uniform float u_ROLAngularVelocityConstMax;\r\n #endif\r\n #if defined(ROTATIONOVERLIFETIMECURVE)||defined(ROTATIONOVERLIFETIMERANDOMCURVES)\r\n uniform vec2 u_ROLAngularVelocityGradient[4];//x为key,y为旋转\r\n #endif\r\n #ifdef ROTATIONOVERLIFETIMERANDOMCURVES\r\n uniform vec2 u_ROLAngularVelocityGradientMax[4];//x为key,y为旋转\r\n #endif\r\n#endif\r\n#ifdef ROTATIONOVERLIFETIMESEPERATE\r\n #if defined(ROTATIONOVERLIFETIMECONSTANT)||defined(ROTATIONOVERLIFETIMERANDOMCONSTANTS)\r\n uniform vec3 u_ROLAngularVelocityConstSeprarate;\r\n #endif\r\n #ifdef ROTATIONOVERLIFETIMERANDOMCONSTANTS\r\n uniform vec3 u_ROLAngularVelocityConstMaxSeprarate;\r\n #endif\r\n #if defined(ROTATIONOVERLIFETIMECURVE)||defined(ROTATIONOVERLIFETIMERANDOMCURVES)\r\n uniform vec2 u_ROLAngularVelocityGradientX[4];\r\n uniform vec2 u_ROLAngularVelocityGradientY[4];\r\n uniform vec2 u_ROLAngularVelocityGradientZ[4];\r\n #endif\r\n #ifdef ROTATIONOVERLIFETIMERANDOMCURVES\r\n uniform vec2 u_ROLAngularVelocityGradientMaxX[4];\r\n uniform vec2 u_ROLAngularVelocityGradientMaxY[4];\r\n uniform vec2 u_ROLAngularVelocityGradientMaxZ[4];\r\n\tuniform vec2 u_ROLAngularVelocityGradientMaxW[4];\r\n #endif\r\n#endif\r\n\r\n#if defined(TEXTURESHEETANIMATIONCURVE)||defined(TEXTURESHEETANIMATIONRANDOMCURVE)\r\n uniform float u_TSACycles;\r\n uniform vec2 u_TSASubUVLength;\r\n uniform vec2 u_TSAGradientUVs[4];//x为key,y为frame\r\n#endif\r\n#ifdef TEXTURESHEETANIMATIONRANDOMCURVE\r\n uniform vec2 u_TSAMaxGradientUVs[4];//x为key,y为frame\r\n#endif\r\n\r\nuniform vec4 u_TilingOffset;\r\n\r\nvec3 rotationByEuler(in vec3 vector,in vec3 rot)\r\n{\r\n\tfloat halfRoll = rot.z * 0.5;\r\n float halfPitch = rot.x * 0.5;\r\n\tfloat halfYaw = rot.y * 0.5;\r\n\r\n\tfloat sinRoll = sin(halfRoll);\r\n\tfloat cosRoll = cos(halfRoll);\r\n\tfloat sinPitch = sin(halfPitch);\r\n\tfloat cosPitch = cos(halfPitch);\r\n\tfloat sinYaw = sin(halfYaw);\r\n\tfloat cosYaw = cos(halfYaw);\r\n\r\n\tfloat quaX = (cosYaw * sinPitch * cosRoll) + (sinYaw * cosPitch * sinRoll);\r\n\tfloat quaY = (sinYaw * cosPitch * cosRoll) - (cosYaw * sinPitch * sinRoll);\r\n\tfloat quaZ = (cosYaw * cosPitch * sinRoll) - (sinYaw * sinPitch * cosRoll);\r\n\tfloat quaW = (cosYaw * cosPitch * cosRoll) + (sinYaw * sinPitch * sinRoll);\r\n\t\r\n\t//vec4 q=vec4(quaX,quaY,quaZ,quaW);\r\n\t//vec3 temp = cross(q.xyz, vector) + q.w * vector;\r\n\t//return (cross(temp, -q.xyz) + dot(q.xyz,vector) * q.xyz + q.w * temp);\r\n\t\r\n\tfloat x = quaX + quaX;\r\n float y = quaY + quaY;\r\n float z = quaZ + quaZ;\r\n float wx = quaW * x;\r\n float wy = quaW * y;\r\n float wz = quaW * z;\r\n\tfloat xx = quaX * x;\r\n float xy = quaX * y;\r\n\tfloat xz = quaX * z;\r\n float yy = quaY * y;\r\n float yz = quaY * z;\r\n float zz = quaZ * z;\r\n\r\n return vec3(((vector.x * ((1.0 - yy) - zz)) + (vector.y * (xy - wz))) + (vector.z * (xz + wy)),\r\n ((vector.x * (xy + wz)) + (vector.y * ((1.0 - xx) - zz))) + (vector.z * (yz - wx)),\r\n ((vector.x * (xz - wy)) + (vector.y * (yz + wx))) + (vector.z * ((1.0 - xx) - yy)));\r\n\t\r\n}\r\n\r\n//假定axis已经归一化\r\nvec3 rotationByAxis(in vec3 vector,in vec3 axis, in float angle)\r\n{\r\n\tfloat halfAngle = angle * 0.5;\r\n\tfloat sin = sin(halfAngle);\r\n\t\r\n\tfloat quaX = axis.x * sin;\r\n\tfloat quaY = axis.y * sin;\r\n\tfloat quaZ = axis.z * sin;\r\n\tfloat quaW = cos(halfAngle);\r\n\t\r\n\t//vec4 q=vec4(quaX,quaY,quaZ,quaW);\r\n\t//vec3 temp = cross(q.xyz, vector) + q.w * vector;\r\n\t//return (cross(temp, -q.xyz) + dot(q.xyz,vector) * q.xyz + q.w * temp);\r\n\t\r\n\tfloat x = quaX + quaX;\r\n float y = quaY + quaY;\r\n float z = quaZ + quaZ;\r\n float wx = quaW * x;\r\n float wy = quaW * y;\r\n float wz = quaW * z;\r\n\tfloat xx = quaX * x;\r\n float xy = quaX * y;\r\n\tfloat xz = quaX * z;\r\n float yy = quaY * y;\r\n float yz = quaY * z;\r\n float zz = quaZ * z;\r\n\r\n return vec3(((vector.x * ((1.0 - yy) - zz)) + (vector.y * (xy - wz))) + (vector.z * (xz + wy)),\r\n ((vector.x * (xy + wz)) + (vector.y * ((1.0 - xx) - zz))) + (vector.z * (yz - wx)),\r\n ((vector.x * (xz - wy)) + (vector.y * (yz + wx))) + (vector.z * ((1.0 - xx) - yy)));\r\n\t\r\n}\r\n\r\nvec3 rotationByQuaternions(in vec3 v,in vec4 q) \r\n{\r\n\treturn v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v);\r\n}\r\n\r\n \r\n#if defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)||defined(SIZEOVERLIFETIMECURVE)||defined(SIZEOVERLIFETIMECURVESEPERATE)||defined(SIZEOVERLIFETIMERANDOMCURVES)||defined(SIZEOVERLIFETIMERANDOMCURVESSEPERATE)\r\nfloat getCurValueFromGradientFloat(in vec2 gradientNumbers[4],in float normalizedAge)\r\n{\r\n\tfloat curValue;\r\n\tfor(int i=1;i<4;i++)\r\n\t{\r\n\t\tvec2 gradientNumber=gradientNumbers[i];\r\n\t\tfloat key=gradientNumber.x;\r\n\t\tif(key>=normalizedAge)\r\n\t\t{\r\n\t\t\tvec2 lastGradientNumber=gradientNumbers[i-1];\r\n\t\t\tfloat lastKey=lastGradientNumber.x;\r\n\t\t\tfloat age=(normalizedAge-lastKey)/(key-lastKey);\r\n\t\t\tcurValue=mix(lastGradientNumber.y,gradientNumber.y,age);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\treturn curValue;\r\n}\r\n#endif\r\n\r\n#if defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)||defined(ROTATIONOVERLIFETIMECURVE)||defined(ROTATIONOVERLIFETIMERANDOMCURVES)\r\nfloat getTotalValueFromGradientFloat(in vec2 gradientNumbers[4],in float normalizedAge)\r\n{\r\n\tfloat totalValue=0.0;\r\n\tfor(int i=1;i<4;i++)\r\n\t{\r\n\t\tvec2 gradientNumber=gradientNumbers[i];\r\n\t\tfloat key=gradientNumber.x;\r\n\t\tvec2 lastGradientNumber=gradientNumbers[i-1];\r\n\t\tfloat lastValue=lastGradientNumber.y;\r\n\t\t\r\n\t\tif(key>=normalizedAge){\r\n\t\t\tfloat lastKey=lastGradientNumber.x;\r\n\t\t\tfloat age=(normalizedAge-lastKey)/(key-lastKey);\r\n\t\t\ttotalValue+=(lastValue+mix(lastValue,gradientNumber.y,age))/2.0*a_ShapePositionStartLifeTime.w*(normalizedAge-lastKey);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\telse{\r\n\t\t\ttotalValue+=(lastValue+gradientNumber.y)/2.0*a_ShapePositionStartLifeTime.w*(key-lastGradientNumber.x);\r\n\t\t}\r\n\t}\r\n\treturn totalValue;\r\n}\r\n#endif\r\n\r\n#if defined(COLOROVERLIFETIME)||defined(RANDOMCOLOROVERLIFETIME)\r\nvec4 getColorFromGradient(in vec2 gradientAlphas[4],in vec4 gradientColors[4],in float normalizedAge)\r\n{\r\n\tvec4 overTimeColor;\r\n\tfor(int i=1;i<4;i++)\r\n\t{\r\n\t\tvec2 gradientAlpha=gradientAlphas[i];\r\n\t\tfloat alphaKey=gradientAlpha.x;\r\n\t\tif(alphaKey>=normalizedAge)\r\n\t\t{\r\n\t\t\tvec2 lastGradientAlpha=gradientAlphas[i-1];\r\n\t\t\tfloat lastAlphaKey=lastGradientAlpha.x;\r\n\t\t\tfloat age=(normalizedAge-lastAlphaKey)/(alphaKey-lastAlphaKey);\r\n\t\t\toverTimeColor.a=mix(lastGradientAlpha.y,gradientAlpha.y,age);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\t\r\n\tfor(int i=1;i<4;i++)\r\n\t{\r\n\t\tvec4 gradientColor=gradientColors[i];\r\n\t\tfloat colorKey=gradientColor.x;\r\n\t\tif(colorKey>=normalizedAge)\r\n\t\t{\r\n\t\t\tvec4 lastGradientColor=gradientColors[i-1];\r\n\t\t\tfloat lastColorKey=lastGradientColor.x;\r\n\t\t\tfloat age=(normalizedAge-lastColorKey)/(colorKey-lastColorKey);\r\n\t\t\toverTimeColor.rgb=mix(gradientColors[i-1].yzw,gradientColor.yzw,age);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\treturn overTimeColor;\r\n}\r\n#endif\r\n\r\n\r\n#if defined(TEXTURESHEETANIMATIONCURVE)||defined(TEXTURESHEETANIMATIONRANDOMCURVE)\r\nfloat getFrameFromGradient(in vec2 gradientFrames[4],in float normalizedAge)\r\n{\r\n\tfloat overTimeFrame;\r\n\tfor(int i=1;i<4;i++)\r\n\t{\r\n\t\tvec2 gradientFrame=gradientFrames[i];\r\n\t\tfloat key=gradientFrame.x;\r\n\t\tif(key>=normalizedAge)\r\n\t\t{\r\n\t\t\tvec2 lastGradientFrame=gradientFrames[i-1];\r\n\t\t\tfloat lastKey=lastGradientFrame.x;\r\n\t\t\tfloat age=(normalizedAge-lastKey)/(key-lastKey);\r\n\t\t\toverTimeFrame=mix(lastGradientFrame.y,gradientFrame.y,age);\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\treturn floor(overTimeFrame);\r\n}\r\n#endif\r\n\r\n#if defined(VELOCITYOVERLIFETIMECONSTANT)||defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\nvec3 computeParticleLifeVelocity(in float normalizedAge)\r\n{\r\n vec3 outLifeVelocity;\r\n #ifdef VELOCITYOVERLIFETIMECONSTANT\r\n\t outLifeVelocity=u_VOLVelocityConst; \r\n #endif\r\n #ifdef VELOCITYOVERLIFETIMECURVE\r\n outLifeVelocity= vec3(getCurValueFromGradientFloat(u_VOLVelocityGradientX,normalizedAge),getCurValueFromGradientFloat(u_VOLVelocityGradientY,normalizedAge),getCurValueFromGradientFloat(u_VOLVelocityGradientZ,normalizedAge));\r\n #endif\r\n #ifdef VELOCITYOVERLIFETIMERANDOMCONSTANT\r\n\t outLifeVelocity=mix(u_VOLVelocityConst,u_VOLVelocityConstMax,vec3(a_Random1.y,a_Random1.z,a_Random1.w)); \r\n #endif\r\n #ifdef VELOCITYOVERLIFETIMERANDOMCURVE\r\n outLifeVelocity=vec3(mix(getCurValueFromGradientFloat(u_VOLVelocityGradientX,normalizedAge),getCurValueFromGradientFloat(u_VOLVelocityGradientMaxX,normalizedAge),a_Random1.y),\r\n\t mix(getCurValueFromGradientFloat(u_VOLVelocityGradientY,normalizedAge),getCurValueFromGradientFloat(u_VOLVelocityGradientMaxY,normalizedAge),a_Random1.z),\r\n\t\t\t\t\t mix(getCurValueFromGradientFloat(u_VOLVelocityGradientZ,normalizedAge),getCurValueFromGradientFloat(u_VOLVelocityGradientMaxZ,normalizedAge),a_Random1.w));\r\n #endif\r\n\t\t\t\t\t\r\n return outLifeVelocity;\r\n} \r\n#endif\r\n\r\nvec3 computeParticlePosition(in vec3 startVelocity, in vec3 lifeVelocity,in float age,in float normalizedAge,vec3 gravityVelocity,vec4 worldRotation)\r\n{\r\n vec3 startPosition;\r\n vec3 lifePosition;\r\n #if defined(VELOCITYOVERLIFETIMECONSTANT)||defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\n\t#ifdef VELOCITYOVERLIFETIMECONSTANT\r\n\t\t startPosition=startVelocity*age;\r\n\t\t lifePosition=lifeVelocity*age;\r\n\t#endif\r\n\t#ifdef VELOCITYOVERLIFETIMECURVE\r\n\t\t startPosition=startVelocity*age;\r\n\t\t lifePosition=vec3(getTotalValueFromGradientFloat(u_VOLVelocityGradientX,normalizedAge),getTotalValueFromGradientFloat(u_VOLVelocityGradientY,normalizedAge),getTotalValueFromGradientFloat(u_VOLVelocityGradientZ,normalizedAge));\r\n\t#endif\r\n\t#ifdef VELOCITYOVERLIFETIMERANDOMCONSTANT\r\n\t\t startPosition=startVelocity*age;\r\n\t\t lifePosition=lifeVelocity*age;\r\n\t#endif\r\n\t#ifdef VELOCITYOVERLIFETIMERANDOMCURVE\r\n\t\t startPosition=startVelocity*age;\r\n\t\t lifePosition=vec3(mix(getTotalValueFromGradientFloat(u_VOLVelocityGradientX,normalizedAge),getTotalValueFromGradientFloat(u_VOLVelocityGradientMaxX,normalizedAge),a_Random1.y)\r\n\t ,mix(getTotalValueFromGradientFloat(u_VOLVelocityGradientY,normalizedAge),getTotalValueFromGradientFloat(u_VOLVelocityGradientMaxY,normalizedAge),a_Random1.z)\r\n\t ,mix(getTotalValueFromGradientFloat(u_VOLVelocityGradientZ,normalizedAge),getTotalValueFromGradientFloat(u_VOLVelocityGradientMaxZ,normalizedAge),a_Random1.w));\r\n\t#endif\r\n\t\r\n\tvec3 finalPosition;\r\n\tif(u_VOLSpaceType==0){\r\n\t if(u_ScalingMode!=2)\r\n\t finalPosition =rotationByQuaternions(u_PositionScale*(a_ShapePositionStartLifeTime.xyz+startPosition+lifePosition),worldRotation);\r\n\t else\r\n\t finalPosition =rotationByQuaternions(u_PositionScale*a_ShapePositionStartLifeTime.xyz+startPosition+lifePosition,worldRotation);\r\n\t}\r\n\telse{\r\n\t if(u_ScalingMode!=2)\r\n\t finalPosition = rotationByQuaternions(u_PositionScale*(a_ShapePositionStartLifeTime.xyz+startPosition),worldRotation)+lifePosition;\r\n\t else\r\n\t finalPosition = rotationByQuaternions(u_PositionScale*a_ShapePositionStartLifeTime.xyz+startPosition,worldRotation)+lifePosition;\r\n\t}\r\n #else\r\n\t startPosition=startVelocity*age;\r\n\t vec3 finalPosition;\r\n\t if(u_ScalingMode!=2)\r\n\t\t\tfinalPosition = rotationByQuaternions(u_PositionScale*(a_ShapePositionStartLifeTime.xyz+startPosition),worldRotation);\r\n\t else\r\n\t \tfinalPosition = rotationByQuaternions(u_PositionScale*a_ShapePositionStartLifeTime.xyz+startPosition,worldRotation);\r\n #endif\r\n \r\n if(u_SimulationSpace==0)\r\n finalPosition=finalPosition+a_SimulationWorldPostion;\r\n else if(u_SimulationSpace==1) \r\n finalPosition=finalPosition+u_WorldPosition;\r\n \r\n finalPosition+=0.5*gravityVelocity*age;\r\n \r\n return finalPosition;\r\n}\r\n\r\n\r\nvec4 computeParticleColor(in vec4 color,in float normalizedAge)\r\n{\r\n\t#ifdef COLOROVERLIFETIME\r\n\t color*=getColorFromGradient(u_ColorOverLifeGradientAlphas,u_ColorOverLifeGradientColors,normalizedAge);\r\n\t#endif\r\n\t\r\n\t#ifdef RANDOMCOLOROVERLIFETIME\r\n\t color*=mix(getColorFromGradient(u_ColorOverLifeGradientAlphas,u_ColorOverLifeGradientColors,normalizedAge),getColorFromGradient(u_MaxColorOverLifeGradientAlphas,u_MaxColorOverLifeGradientColors,normalizedAge),a_Random0.y);\r\n\t#endif\r\n\r\n return color;\r\n}\r\n\r\nvec2 computeParticleSizeBillbard(in vec2 size,in float normalizedAge)\r\n{\r\n\t#ifdef SIZEOVERLIFETIMECURVE\r\n\t\tsize*=getCurValueFromGradientFloat(u_SOLSizeGradient,normalizedAge);\r\n\t#endif\r\n\t#ifdef SIZEOVERLIFETIMERANDOMCURVES\r\n\t size*=mix(getCurValueFromGradientFloat(u_SOLSizeGradient,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMax,normalizedAge),a_Random0.z); \r\n\t#endif\r\n\t#ifdef SIZEOVERLIFETIMECURVESEPERATE\r\n\t\tsize*=vec2(getCurValueFromGradientFloat(u_SOLSizeGradientX,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientY,normalizedAge));\r\n\t#endif\r\n\t#ifdef SIZEOVERLIFETIMERANDOMCURVESSEPERATE\r\n\t size*=vec2(mix(getCurValueFromGradientFloat(u_SOLSizeGradientX,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMaxX,normalizedAge),a_Random0.z)\r\n\t ,mix(getCurValueFromGradientFloat(u_SOLSizeGradientY,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMaxY,normalizedAge),a_Random0.z));\r\n\t#endif\r\n\treturn size;\r\n}\r\n\r\n#ifdef RENDERMODE_MESH\r\nvec3 computeParticleSizeMesh(in vec3 size,in float normalizedAge)\r\n{\r\n\t#ifdef SIZEOVERLIFETIMECURVE\r\n\t\tsize*=getCurValueFromGradientFloat(u_SOLSizeGradient,normalizedAge);\r\n\t#endif\r\n\t#ifdef SIZEOVERLIFETIMERANDOMCURVES\r\n\t size*=mix(getCurValueFromGradientFloat(u_SOLSizeGradient,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMax,normalizedAge),a_Random0.z); \r\n\t#endif\r\n\t#ifdef SIZEOVERLIFETIMECURVESEPERATE\r\n\t\tsize*=vec3(getCurValueFromGradientFloat(u_SOLSizeGradientX,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientY,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientZ,normalizedAge));\r\n\t#endif\r\n\t#ifdef SIZEOVERLIFETIMERANDOMCURVESSEPERATE\r\n\t size*=vec3(mix(getCurValueFromGradientFloat(u_SOLSizeGradientX,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMaxX,normalizedAge),a_Random0.z)\r\n\t ,mix(getCurValueFromGradientFloat(u_SOLSizeGradientY,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMaxY,normalizedAge),a_Random0.z)\r\n\t\t,mix(getCurValueFromGradientFloat(u_SOLSizeGradientZ,normalizedAge),getCurValueFromGradientFloat(u_SOLSizeGradientMaxZ,normalizedAge),a_Random0.z));\r\n\t#endif\r\n\treturn size;\r\n}\r\n#endif\r\n\r\nfloat computeParticleRotationFloat(in float rotation,in float age,in float normalizedAge)\r\n{ \r\n\t#ifdef ROTATIONOVERLIFETIME\r\n\t\t#ifdef ROTATIONOVERLIFETIMECONSTANT\r\n\t\t\tfloat ageRot=u_ROLAngularVelocityConst*age;\r\n\t rotation+=ageRot;\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMECURVE\r\n\t\t\trotation+=getTotalValueFromGradientFloat(u_ROLAngularVelocityGradient,normalizedAge);\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCONSTANTS\r\n\t\t\tfloat ageRot=mix(u_ROLAngularVelocityConst,u_ROLAngularVelocityConstMax,a_Random0.w)*age;\r\n\t rotation+=ageRot;\r\n\t #endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCURVES\r\n\t\t\trotation+=mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradient,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientMax,normalizedAge),a_Random0.w);\r\n\t\t#endif\r\n\t#endif\r\n\t#ifdef ROTATIONOVERLIFETIMESEPERATE\r\n\t\t#ifdef ROTATIONOVERLIFETIMECONSTANT\r\n\t\t\tfloat ageRot=u_ROLAngularVelocityConstSeprarate.z*age;\r\n\t rotation+=ageRot;\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMECURVE\r\n\t\t\trotation+=getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientZ,normalizedAge);\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCONSTANTS\r\n\t\t\tfloat ageRot=mix(u_ROLAngularVelocityConstSeprarate.z,u_ROLAngularVelocityConstMaxSeprarate.z,a_Random0.w)*age;\r\n\t rotation+=ageRot;\r\n\t #endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCURVES\r\n\t\t\trotation+=mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientZ,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientMaxZ,normalizedAge),a_Random0.w));\r\n\t\t#endif\r\n\t#endif\r\n\treturn rotation;\r\n}\r\n\r\n#if defined(RENDERMODE_MESH)&&(defined(ROTATIONOVERLIFETIME)||defined(ROTATIONOVERLIFETIMESEPERATE))\r\nvec3 computeParticleRotationVec3(in vec3 rotation,in float age,in float normalizedAge)\r\n{ \r\n\t#ifdef ROTATIONOVERLIFETIME\r\n\t#ifdef ROTATIONOVERLIFETIMECONSTANT\r\n\t\t\tfloat ageRot=u_ROLAngularVelocityConst*age;\r\n\t rotation+=ageRot;\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMECURVE\r\n\t\t\trotation+=getTotalValueFromGradientFloat(u_ROLAngularVelocityGradient,normalizedAge);\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCONSTANTS\r\n\t\t\tfloat ageRot=mix(u_ROLAngularVelocityConst,u_ROLAngularVelocityConstMax,a_Random0.w)*age;\r\n\t rotation+=ageRot;\r\n\t #endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCURVES\r\n\t\t\trotation+=mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradient,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientMax,normalizedAge),a_Random0.w);\r\n\t\t#endif\r\n\t#endif\r\n\t#ifdef ROTATIONOVERLIFETIMESEPERATE\r\n\t\t#ifdef ROTATIONOVERLIFETIMECONSTANT\r\n\t\t\tvec3 ageRot=u_ROLAngularVelocityConstSeprarate*age;\r\n\t rotation+=ageRot;\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMECURVE\r\n\t\t\trotation+=vec3(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientX,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientY,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientZ,normalizedAge));\r\n\t\t#endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCONSTANTS\r\n\t\t\tvec3 ageRot=mix(u_ROLAngularVelocityConstSeprarate,u_ROLAngularVelocityConstMaxSeprarate,a_Random0.w)*age;\r\n\t rotation+=ageRot;\r\n\t #endif\r\n\t\t#ifdef ROTATIONOVERLIFETIMERANDOMCURVES\r\n\t\t\trotation+=vec3(mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientX,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientMaxX,normalizedAge),a_Random0.w)\r\n\t ,mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientY,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientMaxY,normalizedAge),a_Random0.w)\r\n\t ,mix(getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientZ,normalizedAge),getTotalValueFromGradientFloat(u_ROLAngularVelocityGradientMaxZ,normalizedAge),a_Random0.w));\r\n\t\t#endif\r\n\t#endif\r\n\treturn rotation;\r\n}\r\n#endif\r\n\r\nvec2 computeParticleUV(in vec2 uv,in float normalizedAge)\r\n{ \r\n\t#ifdef TEXTURESHEETANIMATIONCURVE\r\n\t\tfloat cycleNormalizedAge=normalizedAge*u_TSACycles;\r\n\t\tfloat frame=getFrameFromGradient(u_TSAGradientUVs,cycleNormalizedAge-floor(cycleNormalizedAge));\r\n\t\tfloat totalULength=frame*u_TSASubUVLength.x;\r\n\t\tfloat floorTotalULength=floor(totalULength);\r\n\t uv.x+=totalULength-floorTotalULength;\r\n\t\tuv.y+=floorTotalULength*u_TSASubUVLength.y;\r\n #endif\r\n\t#ifdef TEXTURESHEETANIMATIONRANDOMCURVE\r\n\t\tfloat cycleNormalizedAge=normalizedAge*u_TSACycles;\r\n\t\tfloat uvNormalizedAge=cycleNormalizedAge-floor(cycleNormalizedAge);\r\n\t float frame=floor(mix(getFrameFromGradient(u_TSAGradientUVs,uvNormalizedAge),getFrameFromGradient(u_TSAMaxGradientUVs,uvNormalizedAge),a_Random1.x));\r\n\t\tfloat totalULength=frame*u_TSASubUVLength.x;\r\n\t\tfloat floorTotalULength=floor(totalULength);\r\n\t uv.x+=totalULength-floorTotalULength;\r\n\t\tuv.y+=floorTotalULength*u_TSASubUVLength.y;\r\n #endif\r\n\treturn uv;\r\n}\r\n\r\nvoid main()\r\n{\r\n\tfloat age = u_CurrentTime - a_DirectionTime.w;\r\n\tfloat normalizedAge = age/a_ShapePositionStartLifeTime.w;\r\n\tvec3 lifeVelocity;\r\n\tif(normalizedAge<1.0)\r\n\t{ \r\n\t\tvec3 startVelocity=a_DirectionTime.xyz*a_StartSpeed;\r\n\t\t#if defined(VELOCITYOVERLIFETIMECONSTANT)||defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\n\t\t\tlifeVelocity= computeParticleLifeVelocity(normalizedAge);//计算粒子生命周期速度\r\n\t\t#endif \r\n\t\tvec3 gravityVelocity=u_Gravity*age;\r\n\t\t\r\n\t\tvec4 worldRotation;\r\n\t\tif(u_SimulationSpace==0)\r\n\t\t\tworldRotation=a_SimulationWorldRotation;\r\n\t\telse\r\n\t\t\tworldRotation=u_WorldRotation;\r\n\t\t\r\n\t\tvec3 center=computeParticlePosition(startVelocity, lifeVelocity, age, normalizedAge,gravityVelocity,worldRotation);//计算粒子位置\r\n\t\r\n\t\r\n\t\t#ifdef SPHERHBILLBOARD\r\n\t\t\tvec2 corner=a_CornerTextureCoordinate.xy;//Billboard模式z轴无效\r\n\t\t\tvec3 cameraUpVector =normalize(u_CameraUp);//TODO:是否外面归一化\r\n\t\t\tvec3 sideVector = normalize(cross(u_CameraDirection,cameraUpVector));\r\n\t\t\tvec3 upVector = normalize(cross(sideVector,u_CameraDirection));\r\n\t\t\tcorner*=computeParticleSizeBillbard(a_StartSize.xy,normalizedAge);\r\n\t\t\t#if defined(ROTATIONOVERLIFETIME)||defined(ROTATIONOVERLIFETIMESEPERATE)\r\n\t\t\t\tif(u_ThreeDStartRotation){\r\n\t\t\t\t\tvec3 rotation=vec3(a_StartRotation0.xy,computeParticleRotationFloat(a_StartRotation0.z,age,normalizedAge));\r\n\t\t\t\t\tcenter += u_SizeScale.xzy*rotationByEuler(corner.x*sideVector+corner.y*upVector,rotation);\r\n\t\t\t\t}\r\n\t\t\t\telse{\r\n\t\t\t\t\tfloat rot = computeParticleRotationFloat(a_StartRotation0.x, age,normalizedAge);\r\n\t\t\t\t\tfloat c = cos(rot);\r\n\t\t\t\t\tfloat s = sin(rot);\r\n\t\t\t\t\tmat2 rotation= mat2(c, -s, s, c);\r\n\t\t\t\t\tcorner=rotation*corner;\r\n\t\t\t\t\tcenter += u_SizeScale.xzy*(corner.x*sideVector+corner.y*upVector);\r\n\t\t\t\t}\r\n\t\t\t#else\r\n\t\t\t\tif(u_ThreeDStartRotation){\r\n\t\t\t\t\tcenter += u_SizeScale.xzy*rotationByEuler(corner.x*sideVector+corner.y*upVector,a_StartRotation0);\r\n\t\t\t\t}\r\n\t\t\t\telse{\r\n\t\t\t\t\tfloat c = cos(a_StartRotation0.x);\r\n\t\t\t\t\tfloat s = sin(a_StartRotation0.x);\r\n\t\t\t\t\tmat2 rotation= mat2(c, -s, s, c);\r\n\t\t\t\t\tcorner=rotation*corner;\r\n\t\t\t\t\tcenter += u_SizeScale.xzy*(corner.x*sideVector+corner.y*upVector);\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t#endif\r\n\t\r\n\t\t#ifdef STRETCHEDBILLBOARD\r\n\t\t\tvec2 corner=a_CornerTextureCoordinate.xy;//Billboard模式z轴无效\r\n\t\t\tvec3 velocity;\r\n\t\t\t#if defined(VELOCITYOVERLIFETIMECONSTANT)||defined(VELOCITYOVERLIFETIMECURVE)||defined(VELOCITYOVERLIFETIMERANDOMCONSTANT)||defined(VELOCITYOVERLIFETIMERANDOMCURVE)\r\n\t\t\t\tif(u_VOLSpaceType==0)\r\n\t\t\t\tvelocity=rotationByQuaternions(u_SizeScale*(startVelocity+lifeVelocity),worldRotation)+gravityVelocity;\r\n\t\t\t\telse\r\n\t\t\t\tvelocity=rotationByQuaternions(u_SizeScale*startVelocity,worldRotation)+lifeVelocity+gravityVelocity;\r\n\t\t\t#else\r\n\t\t\t\tvelocity= rotationByQuaternions(u_SizeScale*startVelocity,worldRotation)+gravityVelocity;\r\n\t\t\t#endif\t\r\n\t\t\tvec3 cameraUpVector = normalize(velocity);\r\n\t\t\tvec3 direction = normalize(center-u_CameraPos);\r\n\t\t\tvec3 sideVector = normalize(cross(direction,normalize(velocity)));\r\n\t\t\t\r\n\t\t\tsideVector=u_SizeScale.xzy*sideVector;\r\n\t\t\tcameraUpVector=length(vec3(u_SizeScale.x,0.0,0.0))*cameraUpVector;\r\n\t\t\t\r\n\t\t\tvec2 size=computeParticleSizeBillbard(a_StartSize.xy,normalizedAge);\r\n\t\t\t\r\n\t\t\tconst mat2 rotaionZHalfPI=mat2(0.0, -1.0, 1.0, 0.0);\r\n\t\t\tcorner=rotaionZHalfPI*corner;\r\n\t\t\tcorner.y=corner.y-abs(corner.y);\r\n\t\t\t\r\n\t\t\tfloat speed=length(velocity);//TODO:\r\n\t\t\tcenter +=sign(u_SizeScale.x)*(sign(u_StretchedBillboardLengthScale)*size.x*corner.x*sideVector+(speed*u_StretchedBillboardSpeedScale+size.y*u_StretchedBillboardLengthScale)*corner.y*cameraUpVector);\r\n\t\t#endif\r\n\t\r\n\t\t#ifdef HORIZONTALBILLBOARD\r\n\t\t\tvec2 corner=a_CornerTextureCoordinate.xy;//Billboard模式z轴无效\r\n\t\t\tconst vec3 cameraUpVector=vec3(0.0,0.0,1.0);\r\n\t\t\tconst vec3 sideVector = vec3(-1.0,0.0,0.0);\r\n\t\t\t\r\n\t\t\tfloat rot = computeParticleRotationFloat(a_StartRotation0.x, age,normalizedAge);\r\n\t\t\tfloat c = cos(rot);\r\n\t\t\tfloat s = sin(rot);\r\n\t\t\tmat2 rotation= mat2(c, -s, s, c);\r\n\t\t\tcorner=rotation*corner*cos(0.78539816339744830961566084581988);//TODO:临时缩小cos45,不确定U3D原因\r\n\t\t\tcorner*=computeParticleSizeBillbard(a_StartSize.xy,normalizedAge);\r\n\t\t\tcenter +=u_SizeScale.xzy*(corner.x*sideVector+ corner.y*cameraUpVector);\r\n\t\t#endif\r\n\t\r\n\t\t#ifdef VERTICALBILLBOARD\r\n\t\t\tvec2 corner=a_CornerTextureCoordinate.xy;//Billboard模式z轴无效\r\n\t\t\tconst vec3 cameraUpVector =vec3(0.0,1.0,0.0);\r\n\t\t\tvec3 sideVector = normalize(cross(u_CameraDirection,cameraUpVector));\r\n\t\t\t\r\n\t\t\tfloat rot = computeParticleRotationFloat(a_StartRotation0.x, age,normalizedAge);\r\n\t\t\tfloat c = cos(rot);\r\n\t\t\tfloat s = sin(rot);\r\n\t\t\tmat2 rotation= mat2(c, -s, s, c);\r\n\t\t\tcorner=rotation*corner*cos(0.78539816339744830961566084581988);//TODO:临时缩小cos45,不确定U3D原因\r\n\t\t\tcorner*=computeParticleSizeBillbard(a_StartSize.xy,normalizedAge);\r\n\t\t\tcenter +=u_SizeScale.xzy*(corner.x*sideVector+ corner.y*cameraUpVector);\r\n\t\t#endif\r\n\t\r\n\t\t#ifdef RENDERMODE_MESH\r\n\t\t\tvec3 size=computeParticleSizeMesh(a_StartSize,normalizedAge);\r\n\t\t\t#if defined(ROTATIONOVERLIFETIME)||defined(ROTATIONOVERLIFETIMESEPERATE)\r\n\t\t\t\tif(u_ThreeDStartRotation){\r\n\t\t\t\t\tvec3 rotation=vec3(a_StartRotation0.xy,computeParticleRotationFloat(a_StartRotation0.z, age,normalizedAge));\r\n\t\t\t\t\tcenter+= rotationByQuaternions(u_SizeScale*rotationByEuler(a_MeshPosition*size,rotation),worldRotation);\r\n\t\t\t\t}\r\n\t\t\t\telse{\r\n\t\t\t\t\t#ifdef ROTATIONOVERLIFETIME\r\n\t\t\t\t\t\tfloat angle=computeParticleRotationFloat(a_StartRotation0.x, age,normalizedAge);\r\n\t\t\t\t\t\tif(a_ShapePositionStartLifeTime.x!=0.0||a_ShapePositionStartLifeTime.y!=0.0){\r\n\t\t\t\t\t\t\tcenter+= (rotationByQuaternions(rotationByAxis(u_SizeScale*a_MeshPosition*size,normalize(cross(vec3(0.0,0.0,1.0),vec3(a_ShapePositionStartLifeTime.xy,0.0))),angle),worldRotation));//已验证\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\telse{\r\n\t\t\t\t\t\t\t#ifdef SHAPE\r\n\t\t\t\t\t\t\t\tcenter+= u_SizeScale.xzy*(rotationByQuaternions(rotationByAxis(a_MeshPosition*size,vec3(0.0,-1.0,0.0),angle),worldRotation));\r\n\t\t\t\t\t\t\t#else\r\n\t\t\t\t\t\t\t\tif(u_SimulationSpace==0)\r\n\t\t\t\t\t\t\t\t\tcenter+=rotationByAxis(u_SizeScale*a_MeshPosition*size,vec3(0.0,0.0,-1.0),angle);//已验证\r\n\t\t\t\t\t\t\t\telse if(u_SimulationSpace==1)\r\n\t\t\t\t\t\t\t\t\tcenter+=rotationByQuaternions(u_SizeScale*rotationByAxis(a_MeshPosition*size,vec3(0.0,0.0,-1.0),angle),worldRotation);//已验证\r\n\t\t\t\t\t\t\t#endif\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t#endif\r\n\t\t\t\t\t#ifdef ROTATIONOVERLIFETIMESEPERATE\r\n\t\t\t\t\t\t//TODO:是否应合并if(u_ThreeDStartRotation)分支代码,待测试\r\n\t\t\t\t\t\tvec3 angle=computeParticleRotationVec3(vec3(0.0,0.0,-a_StartRotation0.x), age,normalizedAge);\r\n\t\t\t\t\t\tcenter+= (rotationByQuaternions(rotationByEuler(u_SizeScale*a_MeshPosition*size,vec3(angle.x,angle.y,angle.z)),worldRotation));//已验证\r\n\t\t\t\t\t#endif\t\t\r\n\t\t\t\t}\r\n\t\t\t#else\r\n\t\t\t\tif(u_ThreeDStartRotation){\r\n\t\t\t\t\tcenter+= rotationByQuaternions(u_SizeScale*rotationByEuler(a_MeshPosition*size,a_StartRotation0),worldRotation);//已验证\r\n\t\t\t\t}\r\n\t\t\t\telse{\r\n\t\t\t\t\tif(a_ShapePositionStartLifeTime.x!=0.0||a_ShapePositionStartLifeTime.y!=0.0){\r\n\t\t\t\t\t\tif(u_SimulationSpace==0)\r\n\t\t\t\t\t\t\tcenter+= rotationByAxis(u_SizeScale*a_MeshPosition*size,normalize(cross(vec3(0.0,0.0,1.0),vec3(a_ShapePositionStartLifeTime.xy,0.0))),a_StartRotation0.x);\r\n\t\t\t\t\t\telse if(u_SimulationSpace==1)\r\n\t\t\t\t\t\t\tcenter+= (rotationByQuaternions(u_SizeScale*rotationByAxis(a_MeshPosition*size,normalize(cross(vec3(0.0,0.0,1.0),vec3(a_ShapePositionStartLifeTime.xy,0.0))),a_StartRotation0.x),worldRotation));//已验证\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse{\r\n\t\t\t\t\t\t#ifdef SHAPE\r\n\t\t\t\t\t\t\tif(u_SimulationSpace==0)\r\n\t\t\t\t\t\t\t\tcenter+= u_SizeScale*rotationByAxis(a_MeshPosition*size,vec3(0.0,-1.0,0.0),a_StartRotation0.x);\r\n\t\t\t\t\t\t\telse if(u_SimulationSpace==1)\r\n\t\t\t\t\t\t\t\tcenter+= rotationByQuaternions(u_SizeScale*rotationByAxis(a_MeshPosition*size,vec3(0.0,-1.0,0.0),a_StartRotation0.x),worldRotation);\t\r\n\t\t\t\t\t\t#else\r\n\t\t\t\t\t\t\tif(u_SimulationSpace==0)\r\n\t\t\t\t\t\t\t\tcenter+= rotationByAxis(u_SizeScale*a_MeshPosition*size,vec3(0.0,0.0,-1.0),a_StartRotation0.x);\r\n\t\t\t\t\t\t\telse if(u_SimulationSpace==1)\r\n\t\t\t\t\t\t\t\tcenter+= rotationByQuaternions(u_SizeScale*rotationByAxis(a_MeshPosition*size,vec3(0.0,0.0,-1.0),a_StartRotation0.x),worldRotation);//已验证\r\n\t\t\t\t\t\t#endif\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t\tv_MeshColor=a_MeshColor;\r\n\t\t#endif\r\n\t\r\n\t\tgl_Position=u_Projection*u_View*vec4(center,1.0);\r\n\t\tv_Color = computeParticleColor(a_StartColor, normalizedAge);\r\n\t\t#ifdef DIFFUSEMAP\r\n\t\t\t#if defined(SPHERHBILLBOARD)||defined(STRETCHEDBILLBOARD)||defined(HORIZONTALBILLBOARD)||defined(VERTICALBILLBOARD)\r\n\t\t\t\tv_TextureCoordinate =computeParticleUV(a_CornerTextureCoordinate.zw, normalizedAge);\r\n\t\t\t#endif\r\n\t\t\t#ifdef RENDERMODE_MESH\r\n\t\t\t\tv_TextureCoordinate =computeParticleUV(a_MeshTextureCoordinate, normalizedAge);\r\n\t\t\t#endif\r\n\t\t\t\r\n\t\t\tv_TextureCoordinate=TransformUV(v_TextureCoordinate,u_TilingOffset);\r\n\t\t#endif\r\n \t}\r\n \telse\r\n\t{\r\n\t\tgl_Position=vec4(2.0,2.0,2.0,1.0);//Discard use out of X(-1,1),Y(-1,1),Z(0,1)\r\n\t}\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}\r\n\r\n',"#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n precision highp float;\r\n#else\r\n precision mediump float;\r\n#endif\r\n\r\nvarying vec4 v_Color;\r\nvarying vec2 v_TextureCoordinate;\r\nuniform sampler2D u_texture;\r\nuniform vec4 u_Tintcolor;\r\n\r\n#ifdef RENDERMODE_MESH\r\n\tvarying vec4 v_MeshColor;\r\n#endif\r\n\r\n#ifdef FOG\r\n\tuniform float u_FogStart;\r\n\tuniform float u_FogRange;\r\n\t#ifdef ADDTIVEFOG\r\n\t#else\r\n\t\tuniform vec3 u_FogColor;\r\n\t#endif\r\n#endif\r\n\r\n\r\nvoid main()\r\n{\t\r\n\t#ifdef RENDERMODE_MESH\r\n\t\tgl_FragColor=v_MeshColor;\r\n\t#else\r\n\t\tgl_FragColor=vec4(1.0);\t\r\n\t#endif\r\n\t\t\r\n\t#ifdef DIFFUSEMAP\r\n\t\t#ifdef TINTCOLOR\r\n\t\t\tgl_FragColor*=texture2D(u_texture,v_TextureCoordinate)*u_Tintcolor*2.0*v_Color;\r\n\t\t#else\r\n\t\t\tgl_FragColor*=texture2D(u_texture,v_TextureCoordinate)*v_Color;\r\n\t\t#endif\r\n\t#else\r\n\t\t#ifdef TINTCOLOR\r\n\t\t\tgl_FragColor*=u_Tintcolor*2.0*v_Color;\r\n\t\t#else\r\n\t\t\tgl_FragColor*=v_Color;\r\n\t\t#endif\r\n\t#endif\r\n\t\r\n\t#ifdef FOG\r\n\t\tfloat lerpFact=clamp((1.0/gl_FragCoord.w-u_FogStart)/u_FogRange,0.0,1.0);\r\n\t\t#ifdef ADDTIVEFOG\r\n\t\t\tgl_FragColor.rgb=mix(gl_FragColor.rgb,vec3(0.0,0.0,0.0),lerpFact);\r\n\t\t#else\r\n\t\t\tgl_FragColor.rgb=mix(gl_FragColor.rgb,u_FogColor,lerpFact);\r\n\t\t#endif\r\n\t#endif\r\n}",r),e={a_Position:ie.MESH_POSITION0},t={u_TintColor:Z.PERIOD_MATERIAL,u_Exposure:Z.PERIOD_MATERIAL,u_Rotation:Z.PERIOD_MATERIAL,u_CubeTexture:Z.PERIOD_MATERIAL,u_ViewProjection:Z.PERIOD_CAMERA},a=Z.add("SkyBox"),n=new Qt(e,t),a.addSubShader(n),n.addShaderPass('#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\nprecision highp float;\r\n#else\r\nprecision mediump float;\r\n#endif\r\n#include "Lighting.glsl";\r\n\r\nattribute vec4 a_Position;\r\nuniform mat4 u_ViewProjection;\r\nuniform float u_Rotation;\r\nvarying vec3 v_Texcoord;\r\n\r\n\r\nvec4 rotateAroundYInDegrees (vec4 vertex, float degrees)\r\n{\r\n\tfloat angle = degrees * 3.141593 / 180.0;\r\n\tfloat sina=sin(angle);\r\n\tfloat cosa=cos(angle);\r\n\tmat2 m = mat2(cosa, -sina, sina, cosa);\r\n\treturn vec4(m*vertex.xz, vertex.yw).xzyw;\r\n}\r\n\t\t\r\nvoid main()\r\n{\r\n\tvec4 position=rotateAroundYInDegrees(a_Position,u_Rotation);\r\n\tgl_Position = u_ViewProjection*position;\r\n\tv_Texcoord=vec3(-a_Position.x,a_Position.yz);//转换坐标系\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}\r\n',"#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\nprecision highp float;\r\n#else\r\nprecision mediump float;\r\n#endif\r\n\r\nvarying vec3 v_Texcoord;\r\n\r\nuniform samplerCube u_CubeTexture;\r\nuniform float u_Exposure;\r\nuniform vec4 u_TintColor;\r\n\r\n\r\nvoid main()\r\n{\t\r\n\tvec3 color=textureCube(u_CubeTexture, v_Texcoord).rgb*u_TintColor.rgb*u_Exposure*2.0;\r\n\tgl_FragColor=vec4(color,1.0);\r\n}\r\n\r\n"),e={a_Position:ie.MESH_POSITION0},t={u_SunSize:Z.PERIOD_MATERIAL,u_SunSizeConvergence:Z.PERIOD_MATERIAL,u_AtmosphereThickness:Z.PERIOD_MATERIAL,u_SkyTint:Z.PERIOD_MATERIAL,u_GroundTint:Z.PERIOD_MATERIAL,u_Exposure:Z.PERIOD_MATERIAL,u_ViewProjection:Z.PERIOD_CAMERA,"u_SunLight.direction":Z.PERIOD_SCENE,"u_SunLight.color":Z.PERIOD_SCENE},a=Z.add("SkyBoxProcedural"),n=new Qt(e,t),a.addSubShader(n),n.addShaderPass("#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include \"Lighting.glsl\";\r\n\r\n#define OUTER_RADIUS 1.025\r\n#define RAYLEIGH (mix(0.0, 0.0025, pow(u_AtmosphereThickness,2.5)))// Rayleigh constant Rayleigh为夜空光和极光亮度单位\r\n#define MIE 0.0010 // Mie constant 米氏散射\r\n#define SUN_BRIGHTNESS 20.0 // Sun brightness\r\n#define MAX_SCATTER 50.0 // Maximum scattering value, to prevent math overflows on Adrenos\r\n\r\nconst float SKY_GROUND_THRESHOLD = 0.02;\r\nconst float outerRadius = OUTER_RADIUS;\r\nconst float outerRadius2 = OUTER_RADIUS*OUTER_RADIUS;\r\nconst float innerRadius = 1.0;\r\nconst float innerRadius2 = 1.0;\r\nconst float cameraHeight = 0.0001;\r\n\r\nconst float HDSundiskIntensityFactor = 15.0;\r\nconst float simpleSundiskIntensityFactor = 27.0;\r\n\r\nconst float sunScale = 400.0 * SUN_BRIGHTNESS;\r\nconst float kmESun = MIE * SUN_BRIGHTNESS;\r\nconst float km4PI = MIE * 4.0 * 3.14159265;\r\nconst float scale = 1.0 / (OUTER_RADIUS - 1.0);\r\nconst float scaleDepth = 0.25;\r\nconst float scaleOverScaleDepth = (1.0 / (OUTER_RADIUS - 1.0)) / 0.25;\r\nconst float samples = 2.0; // THIS IS UNROLLED MANUALLY, DON'T TOUCH\r\n\r\n// RGB wavelengths .35 (.62=158), .43 (.68=174), .525 (.75=190)\r\nconst vec3 c_DefaultScatteringWavelength = vec3(0.65, 0.57, 0.475);//默认散射波长\r\nconst vec3 c_VariableRangeForScatteringWavelength = vec3(0.15, 0.15, 0.15);//散射播放的可变范围\r\n\r\nattribute vec4 a_Position;\r\n\r\nuniform mat4 u_ViewProjection;\r\nuniform vec3 u_SkyTint;\r\nuniform vec3 u_GroundTint;\r\nuniform float u_Exposure;\r\nuniform float u_AtmosphereThickness;\r\nuniform DirectionLight u_SunLight;\r\n\r\nvarying vec3 v_GroundColor;\r\nvarying vec3 v_SkyColor;\r\n\r\n#ifdef SUN_HIGH_QUALITY\r\n\tvarying vec3 v_Vertex;\r\n#elif defined(SUN_SIMPLE)\r\n\tvarying vec3 v_RayDir;\r\n#else\r\n\tvarying float v_SkyGroundFactor;\r\n#endif\r\n\r\n#if defined(SUN_HIGH_QUALITY)||defined(SUN_SIMPLE)\r\n\tvarying vec3 v_SunColor;\r\n#endif\r\n\r\n// Calculates the Rayleigh phase function\r\nfloat getRayleighPhase(vec3 light, vec3 ray) \r\n{\r\n\tfloat eyeCos = dot(light, ray);\r\n\treturn 0.75 + 0.75*eyeCos*eyeCos;\r\n}\r\n\r\nfloat scaleAngle(float inCos)\r\n{\r\n\tfloat x = 1.0 - inCos;\r\n\treturn 0.25 * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25))));\r\n}\r\n\r\n\r\nvoid main () {\r\n\tgl_Position = u_ViewProjection*a_Position;\r\n\r\n\tvec3 skyTintInGammaSpace = u_SkyTint;//支持非GAMMA空间后要调整\r\n\tvec3 scatteringWavelength = mix(c_DefaultScatteringWavelength-c_VariableRangeForScatteringWavelength,c_DefaultScatteringWavelength+c_VariableRangeForScatteringWavelength,vec3(1.0) - skyTintInGammaSpace); // using Tint in sRGB+ gamma allows for more visually linear interpolation and to keep (0.5) at (128, gray in sRGB) point\r\n\tvec3 invWavelength = 1.0 / pow(scatteringWavelength, vec3(4.0));\r\n\r\n\tfloat krESun = RAYLEIGH * SUN_BRIGHTNESS;\r\n\tfloat kr4PI = RAYLEIGH * 4.0 * 3.14159265;\r\n\r\n\tvec3 cameraPos = vec3(0.0,innerRadius + cameraHeight,0.0); // The camera's current position\r\n\r\n\t// Get the ray from the camera to the vertex and its length (which is the far point of the ray passing through the atmosphere)\r\n\tvec3 eyeRay = normalize(a_Position.xyz);\r\n\r\n\tfloat far = 0.0;\r\n\tvec3 cIn, cOut;\r\n\tif (eyeRay.y >= 0.0) {// Sky\r\n\t\t// Calculate the length of the \"atmosphere\"\r\n\t\tfar = sqrt(outerRadius2 + innerRadius2 * eyeRay.y * eyeRay.y - innerRadius2) - innerRadius * eyeRay.y;\r\n\r\n\t\t// Calculate the ray's starting position, then calculate its scattering offset\r\n\t\tfloat height = innerRadius + cameraHeight;\r\n\t\tfloat depth = exp(scaleOverScaleDepth * -cameraHeight);\r\n\t\tfloat startAngle = dot(eyeRay, cameraPos) / height;\r\n\t\tfloat startOffset = depth*scaleAngle(startAngle);\r\n\r\n\t\t// Initialize the scattering loop variables\r\n\t\tfloat sampleLength = far / samples;\r\n\t\tfloat scaledLength = sampleLength * scale;\r\n\t\tvec3 sampleRay = eyeRay * sampleLength;\r\n\t\tvec3 samplePoint = cameraPos + sampleRay * 0.5;\r\n\r\n\t\tvec3 frontColor = vec3(0.0);\r\n\t\t//unrolling this manually to avoid some platform for loop slow\r\n\t\t{\r\n\t\t\tfloat height = length(samplePoint);\r\n\t\t\tfloat depth = exp(scaleOverScaleDepth * (innerRadius - height));\r\n\t\t\tfloat lightAngle = dot(-u_SunLight.direction, samplePoint) / height;\r\n\t\t\tfloat cameraAngle = dot(eyeRay, samplePoint) / height;\r\n\t\t\tfloat scatter = (startOffset + depth*(scaleAngle(lightAngle) - scaleAngle(cameraAngle)));\r\n\t\t\tvec3 attenuate = exp(-clamp(scatter, 0.0, MAX_SCATTER) * (invWavelength * kr4PI + km4PI));\r\n\r\n\t\t\tfrontColor += attenuate * (depth * scaledLength);\r\n\t\t\tsamplePoint += sampleRay;\r\n\t\t}\r\n\t\t{\r\n\t\t\tfloat height = length(samplePoint);\r\n\t\t\tfloat depth = exp(scaleOverScaleDepth * (innerRadius - height));\r\n\t\t\tfloat lightAngle = dot(-u_SunLight.direction, samplePoint) / height;\r\n\t\t\tfloat cameraAngle = dot(eyeRay, samplePoint) / height;\r\n\t\t\tfloat scatter = (startOffset + depth*(scaleAngle(lightAngle) - scaleAngle(cameraAngle)));\r\n\t\t\tvec3 attenuate = exp(-clamp(scatter, 0.0, MAX_SCATTER) * (invWavelength * kr4PI + km4PI));\r\n\r\n\t\t\tfrontColor += attenuate * (depth * scaledLength);\r\n\t\t\tsamplePoint += sampleRay;\r\n\t\t}\r\n\r\n\t\t// Finally, scale the Mie and Rayleigh colors and set up the varying variables for the pixel shader\r\n\t\tcIn = frontColor * (invWavelength * krESun);\r\n\t\tcOut = frontColor * kmESun;\r\n\t} else {// Ground\r\n\t\tfar = (-cameraHeight) / (min(-0.001, eyeRay.y));\r\n\t\tvec3 pos = cameraPos + far * eyeRay;\r\n\r\n\t\t// Calculate the ray's starting position, then calculate its scattering offset\r\n\t\tfloat depth = exp((-cameraHeight) * (1.0/scaleDepth));\r\n\t\tfloat cameraAngle = dot(-eyeRay, pos);\r\n\t\tfloat lightAngle = dot(-u_SunLight.direction, pos);\r\n\t\tfloat cameraScale = scaleAngle(cameraAngle);\r\n\t\tfloat lightScale = scaleAngle(lightAngle);\r\n\t\tfloat cameraOffset = depth*cameraScale;\r\n\t\tfloat temp = lightScale + cameraScale;\r\n\r\n\t\t// Initialize the scattering loop variables\r\n\t\tfloat sampleLength = far / samples;\r\n\t\tfloat scaledLength = sampleLength * scale;\r\n\t\tvec3 sampleRay = eyeRay * sampleLength;\r\n\t\tvec3 samplePoint = cameraPos + sampleRay * 0.5;\r\n\r\n\t\t// Now loop through the sample rays\r\n\t\tvec3 frontColor = vec3(0.0, 0.0, 0.0);\r\n\t\tvec3 attenuate;\r\n\r\n\t\t// Loop removed because we kept hitting SM2.0 temp variable limits. Doesn't affect the image too much.\r\n\t\t{\r\n\t\t\tfloat height = length(samplePoint);\r\n\t\t\tfloat depth = exp(scaleOverScaleDepth * (innerRadius - height));\r\n\t\t\tfloat scatter = depth*temp - cameraOffset;\r\n\t\t\tattenuate = exp(-clamp(scatter, 0.0, MAX_SCATTER) * (invWavelength * kr4PI + km4PI));\r\n\t\t\tfrontColor += attenuate * (depth * scaledLength);\r\n\t\t\tsamplePoint += sampleRay;\r\n\t\t}\r\n\r\n\t\tcIn = frontColor * (invWavelength * krESun + kmESun);\r\n\t\tcOut = clamp(attenuate, 0.0, 1.0);\r\n\t}\r\n\r\n\t#ifdef SUN_HIGH_QUALITY\r\n\t\tv_Vertex = -a_Position.xyz;\r\n\t#elif defined(SUN_SIMPLE) \r\n\t\tv_RayDir = -eyeRay;\r\n\t#else\r\n\t\tv_SkyGroundFactor = -eyeRay.y / SKY_GROUND_THRESHOLD;\r\n\t#endif\r\n\r\n\t// if we want to calculate color in vprog:\r\n\t// in case of linear: multiply by _Exposure in here (even in case of lerp it will be common multiplier, so we can skip mul in fshader)\r\n\tv_GroundColor = u_Exposure * (cIn + u_GroundTint*u_GroundTint * cOut);//u_GroundColor*u_GroundColor is gamma space convert to linear space\r\n\tv_SkyColor = u_Exposure * (cIn * getRayleighPhase(-u_SunLight.direction, -eyeRay));\r\n\r\n\t\r\n\t// The sun should have a stable intensity in its course in the sky. Moreover it should match the highlight of a purely specular material.\r\n\t// This matching was done using the Unity3D standard shader BRDF1 on the 5/31/2017\r\n\t// Finally we want the sun to be always bright even in LDR thus the normalization of the lightColor for low intensity.\r\n\tfloat lightColorIntensity = clamp(length(u_SunLight.color), 0.25, 1.0);\r\n\r\n\t#ifdef SUN_HIGH_QUALITY \r\n\t\tv_SunColor = HDSundiskIntensityFactor * clamp(cOut,0.0,1.0) * u_SunLight.color / lightColorIntensity;\r\n\t#elif defined(SUN_SIMPLE) \r\n\t\tv_SunColor = simpleSundiskIntensityFactor * clamp(cOut * sunScale,0.0,1.0) * u_SunLight.color / lightColorIntensity;\r\n\t#endif\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}\r\n",'#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include "Lighting.glsl";\r\n\r\nconst float MIE_G = -0.990;\r\nconst float MIE_G2 = 0.9801;\r\nconst float SKY_GROUND_THRESHOLD = 0.02;\r\n\r\nuniform float u_SunSize;\r\nuniform float u_SunSizeConvergence;\r\nuniform DirectionLight u_SunLight;\r\n\r\n\r\nvarying vec3 v_GroundColor;\r\nvarying vec3 v_SkyColor;\r\n\r\n\r\n#ifdef SUN_HIGH_QUALITY\r\n\tvarying vec3 v_Vertex;\r\n#elif defined(SUN_SIMPLE)\r\n\tvarying vec3 v_RayDir;\r\n#else\r\n\tvarying float v_SkyGroundFactor;\r\n#endif\r\n\r\n#if defined(SUN_HIGH_QUALITY)||defined(SUN_SIMPLE)\r\n\tvarying vec3 v_SunColor;\r\n#endif\r\n\r\n// Calculates the Mie phase function\r\nfloat getMiePhase(float eyeCos, float eyeCos2) {\r\n\tfloat temp = 1.0 + MIE_G2 - 2.0 * MIE_G * eyeCos;\r\n\ttemp = pow(temp, pow(u_SunSize,0.65) * 10.0);\r\n\ttemp = max(temp,1.0e-4); // prevent division by zero, esp. in half precision\r\n\ttemp = 1.5 * ((1.0 - MIE_G2) / (2.0 + MIE_G2)) * (1.0 + eyeCos2) / temp;\r\n\treturn temp;\r\n}\r\n\r\n// Calculates the sun shape\r\nfloat calcSunAttenuation(vec3 lightPos, vec3 ray) {\r\n\t#ifdef SUN_HIGH_QUALITY\r\n\t\tfloat focusedEyeCos = pow(clamp(dot(lightPos, ray),0.0,1.0), u_SunSizeConvergence);\r\n\t\treturn getMiePhase(-focusedEyeCos, focusedEyeCos * focusedEyeCos);\r\n\t#else //SUN_SIMPLE\r\n\t\tvec3 delta = lightPos - ray;\r\n\t\tfloat dist = length(delta);\r\n\t\tfloat spot = 1.0 - smoothstep(0.0, u_SunSize, dist);\r\n\t\treturn spot * spot;\r\n\t#endif\r\n}\r\n\r\nvoid main() {\r\n\t// if y > 1 [eyeRay.y < -SKY_GROUND_THRESHOLD] - ground\r\n\t// if y >= 0 and < 1 [eyeRay.y <= 0 and > -SKY_GROUND_THRESHOLD] - horizon\r\n\t// if y < 0 [eyeRay.y > 0] - sky\r\n\tvec3 col = vec3(0.0, 0.0, 0.0);\r\n\r\n\t#ifdef SUN_HIGH_QUALITY\r\n\t\tvec3 ray = normalize(v_Vertex);\r\n\t\tfloat y = ray.y / SKY_GROUND_THRESHOLD;\r\n\t#elif defined(SUN_SIMPLE) \r\n\t\tvec3 ray = v_RayDir;\r\n\t\tfloat y = ray.y / SKY_GROUND_THRESHOLD;\t\r\n\t#else\r\n\t\tfloat y = v_SkyGroundFactor;\r\n\t#endif\r\n\r\n\t// if we did precalculate color in vprog: just do lerp between them\r\n\tcol = mix(v_SkyColor, v_GroundColor, clamp(y,0.0,1.0));\r\n\r\n\t#if defined(SUN_HIGH_QUALITY)||defined(SUN_SIMPLE)\r\n\t\tif (y < 0.0)\r\n\t\t\tcol += v_SunColor * calcSunAttenuation(-u_SunLight.direction, -ray);\r\n\t#endif\r\n\r\n\tcol = sqrt(col);//linear space convert to gamma space\r\n\tgl_FragColor=vec4(col,1.0);\r\n}\r\n\r\n'),e={a_Position:ie.MESH_POSITION0,a_Normal:ie.MESH_NORMAL0,a_Texcoord0:ie.MESH_TEXTURECOORDINATE0},t={u_MvpMatrix:Z.PERIOD_SPRITE,u_WorldMat:Z.PERIOD_SPRITE,u_CameraPos:Z.PERIOD_CAMERA,u_Viewport:Z.PERIOD_CAMERA,u_ProjectionParams:Z.PERIOD_CAMERA,u_View:Z.PERIOD_CAMERA,u_LightmapScaleOffset:Z.PERIOD_SPRITE,u_LightMap:Z.PERIOD_SPRITE,u_SplatAlphaTexture:Z.PERIOD_MATERIAL,u_DiffuseTexture1:Z.PERIOD_MATERIAL,u_DiffuseTexture2:Z.PERIOD_MATERIAL,u_DiffuseTexture3:Z.PERIOD_MATERIAL,u_DiffuseTexture4:Z.PERIOD_MATERIAL,u_DiffuseTexture5:Z.PERIOD_MATERIAL,u_DiffuseScaleOffset1:Z.PERIOD_MATERIAL,u_DiffuseScaleOffset2:Z.PERIOD_MATERIAL,u_DiffuseScaleOffset3:Z.PERIOD_MATERIAL,u_DiffuseScaleOffset4:Z.PERIOD_MATERIAL,u_DiffuseScaleOffset5:Z.PERIOD_MATERIAL,u_FogStart:Z.PERIOD_SCENE,u_FogRange:Z.PERIOD_SCENE,u_FogColor:Z.PERIOD_SCENE,u_DirationLightCount:Z.PERIOD_SCENE,u_LightBuffer:Z.PERIOD_SCENE,u_LightClusterBuffer:Z.PERIOD_SCENE,u_AmbientColor:Z.PERIOD_SCENE,u_ShadowMap:Z.PERIOD_SCENE,u_shadowMap2:Z.PERIOD_SCENE,u_shadowMap3:Z.PERIOD_SCENE,u_ShadowSplitSpheres:Z.PERIOD_SCENE,u_ShadowMatrices:Z.PERIOD_SCENE,u_ShadowMapSize:Z.PERIOD_SCENE,"u_DirectionLight.color":Z.PERIOD_SCENE,"u_DirectionLight.direction":Z.PERIOD_SCENE,"u_PointLight.position":Z.PERIOD_SCENE,"u_PointLight.range":Z.PERIOD_SCENE,"u_PointLight.color":Z.PERIOD_SCENE,"u_SpotLight.position":Z.PERIOD_SCENE,"u_SpotLight.direction":Z.PERIOD_SCENE,"u_SpotLight.range":Z.PERIOD_SCENE,"u_SpotLight.spot":Z.PERIOD_SCENE,"u_SpotLight.color":Z.PERIOD_SCENE},r={s_Cull:Z.RENDER_STATE_CULL,s_Blend:Z.RENDER_STATE_BLEND,s_BlendSrc:Z.RENDER_STATE_BLEND_SRC,s_BlendDst:Z.RENDER_STATE_BLEND_DST,s_DepthTest:Z.RENDER_STATE_DEPTH_TEST,s_DepthWrite:Z.RENDER_STATE_DEPTH_WRITE},a=Z.add("ExtendTerrain"),n=new Qt(e,t),a.addSubShader(n),n.addShaderPass('#include "Lighting.glsl";\r\n\r\nattribute vec4 a_Position;\r\nattribute vec2 a_Texcoord0;\r\n\r\nuniform mat4 u_MvpMatrix;\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||defined(LIGHTMAP)\r\n\tattribute vec3 a_Normal;\r\n\tvarying vec3 v_Normal;\r\n#endif\r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||defined(FOG)||(defined(CALCULATE_SHADOWS)&&defined(SHADOWMAP_PSSM1))\r\n\tuniform mat4 u_WorldMat;\r\n\tvarying vec3 v_PositionWorld;\r\n#endif\r\n\r\n#ifdef LIGHTMAP\r\n\tvarying vec2 v_LightMapUV;\r\n\tuniform vec4 u_LightmapScaleOffset;\r\n#endif\r\n\r\n#if defined(CALCULATE_SHADOWS)//shader���Զ���ĺ겻����ifdef ����ij�if defined\r\n\tvarying vec4 v_ShadowCoord;\r\n#endif\r\n\r\nvoid main()\r\n{\r\n\tgl_Position = u_MvpMatrix * a_Position;\r\n \r\n\tv_Texcoord0 = a_Texcoord0;\r\n \r\n\t#ifdef LIGHTMAP\r\n\t\tv_LightMapUV = vec2(a_Texcoord0.x, 1.0 - a_Texcoord0.y) * u_LightmapScaleOffset.xy + u_LightmapScaleOffset.zw;\r\n\t\tv_LightMapUV.y = 1.0 - v_LightMapUV.y;\r\n\t#endif\r\n \r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\tv_Normal = a_Normal;\r\n\t#endif\r\n\r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||defined(FOG)||(defined(CALCULATE_SHADOWS)&&defined(SHADOWMAP_PSSM1))\r\n\t\tv_PositionWorld=(u_WorldMat*a_Position).xyz;\r\n\t#endif\r\n\r\n\t#if defined(CALCULATE_SHADOWS)//shader���Զ���ĺ겻����ifdef ����ij�if defined\r\n\t\tv_ShadowCoord = getShadowCoord(vec4(v_PositionWorld));\r\n\t#endif\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}','#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include "Lighting.glsl";\r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||defined(FOG)\r\n\tuniform vec3 u_CameraPos;\r\n\tvarying vec3 v_Normal;\r\n\tvarying vec3 v_PositionWorld;\r\n#endif\r\n\r\n#ifdef FOG\r\n\tuniform float u_FogStart;\r\n\tuniform float u_FogRange;\r\n\tuniform vec3 u_FogColor;\r\n#endif\r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t#ifdef LEGACYSINGLELIGHTING\r\n\t\t#ifdef DIRECTIONLIGHT\r\n\t\t\tuniform DirectionLight u_DirectionLight;\r\n\t\t#endif\r\n\t\t#ifdef POINTLIGHT\r\n\t\t\tuniform PointLight u_PointLight;\r\n\t\t#endif\r\n\t\t#ifdef SPOTLIGHT\r\n\t\t\tuniform SpotLight u_SpotLight;\r\n\t\t#endif\r\n\t#else\r\n\t\tuniform mat4 u_View;\r\n\t\tuniform vec4 u_ProjectionParams;\r\n\t\tuniform vec4 u_Viewport;\r\n\t\tuniform int u_DirationLightCount;\r\n\t\tuniform sampler2D u_LightBuffer;\r\n\t\tuniform sampler2D u_LightClusterBuffer;\r\n\t#endif\r\n#endif\r\n\r\n#include "Shadow.glsl"\r\n#if defined(CALCULATE_SHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\tvarying vec4 v_ShadowCoord;\r\n#endif\r\nvarying float v_posViewZ;\r\n\r\nuniform vec3 u_AmbientColor;\r\n\r\nuniform sampler2D u_SplatAlphaTexture;\r\n\r\nuniform sampler2D u_DiffuseTexture1;\r\nuniform sampler2D u_DiffuseTexture2;\r\nuniform sampler2D u_DiffuseTexture3;\r\nuniform sampler2D u_DiffuseTexture4;\r\nuniform sampler2D u_DiffuseTexture5;\r\n\r\nuniform vec4 u_DiffuseScaleOffset1;\r\nuniform vec4 u_DiffuseScaleOffset2;\r\nuniform vec4 u_DiffuseScaleOffset3;\r\nuniform vec4 u_DiffuseScaleOffset4;\r\nuniform vec4 u_DiffuseScaleOffset5;\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\n#ifdef LIGHTMAP\r\n\tuniform sampler2D u_LightMap;\r\n\tvarying vec2 v_LightMapUV;\r\n#endif\r\n\r\nvoid main()\r\n{\r\n\tvec4 splatAlpha = vec4(1.0);\r\n\t#ifdef ExtendTerrain_DETAIL_NUM1\r\n\t\tsplatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);\r\n\t\tvec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);\r\n\t\tgl_FragColor.xyz = color1.xyz * splatAlpha.r;\r\n\t#endif\r\n\t#ifdef ExtendTerrain_DETAIL_NUM2\r\n\t\tsplatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);\r\n\t\tvec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);\r\n\t\tvec4 color2 = texture2D(u_DiffuseTexture2, v_Texcoord0 * u_DiffuseScaleOffset2.xy);\r\n\t\tgl_FragColor.xyz = color1.xyz * splatAlpha.r + color2.xyz * (1.0 - splatAlpha.r);\r\n\t#endif\r\n\t#ifdef ExtendTerrain_DETAIL_NUM3\r\n\t\tsplatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);\r\n\t\tvec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);\r\n\t\tvec4 color2 = texture2D(u_DiffuseTexture2, v_Texcoord0 * u_DiffuseScaleOffset2.xy);\r\n\t\tvec4 color3 = texture2D(u_DiffuseTexture3, v_Texcoord0 * u_DiffuseScaleOffset3.xy);\r\n\t\tgl_FragColor.xyz = color1.xyz * splatAlpha.r + color2.xyz * splatAlpha.g + color3.xyz * (1.0 - splatAlpha.r - splatAlpha.g);\r\n\t#endif\r\n\t#ifdef ExtendTerrain_DETAIL_NUM4\r\n\t\tsplatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);\r\n\t\tvec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);\r\n\t\tvec4 color2 = texture2D(u_DiffuseTexture2, v_Texcoord0 * u_DiffuseScaleOffset2.xy);\r\n\t\tvec4 color3 = texture2D(u_DiffuseTexture3, v_Texcoord0 * u_DiffuseScaleOffset3.xy);\r\n\t\tvec4 color4 = texture2D(u_DiffuseTexture4, v_Texcoord0 * u_DiffuseScaleOffset4.xy);\r\n\t\tgl_FragColor.xyz = color1.xyz * splatAlpha.r + color2.xyz * splatAlpha.g + color3.xyz * splatAlpha.b + color4.xyz * (1.0 - splatAlpha.r - splatAlpha.g - splatAlpha.b);\r\n\t#endif\r\n\t#ifdef ExtendTerrain_DETAIL_NUM5\r\n\t\tsplatAlpha = texture2D(u_SplatAlphaTexture, v_Texcoord0);\r\n\t\tvec4 color1 = texture2D(u_DiffuseTexture1, v_Texcoord0 * u_DiffuseScaleOffset1.xy);\r\n\t\tvec4 color2 = texture2D(u_DiffuseTexture2, v_Texcoord0 * u_DiffuseScaleOffset2.xy);\r\n\t\tvec4 color3 = texture2D(u_DiffuseTexture3, v_Texcoord0 * u_DiffuseScaleOffset3.xy);\r\n\t\tvec4 color4 = texture2D(u_DiffuseTexture4, v_Texcoord0 * u_DiffuseScaleOffset4.xy);\r\n\t\tvec4 color5 = texture2D(u_DiffuseTexture5, v_Texcoord0 * u_DiffuseScaleOffset5.xy);\r\n\t\tgl_FragColor.xyz = color1.xyz * splatAlpha.r + color2.xyz * splatAlpha.g + color3.xyz * splatAlpha.b + color4.xyz * splatAlpha.a + color5.xyz * (1.0 - splatAlpha.r - splatAlpha.g - splatAlpha.b - splatAlpha.a);\r\n\t#endif\r\n\t\tgl_FragColor.w = splatAlpha.a;\r\n\t\t\r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\tvec3 normal = v_Normal;\r\n\t\tvec3 dif, spe;\r\n\t#endif\r\n\r\n\tvec3 diffuse = vec3(0.0);\r\n\tvec3 specular= vec3(0.0);\r\n\t#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)||defined(FOG)\r\n\t\tvec3 toEye;\r\n\t\t#ifdef FOG\r\n\t\t\ttoEye=u_CameraPos-v_PositionWorld;\r\n\t\t\tfloat toEyeLength=length(toEye);\r\n\t\t\ttoEye/=toEyeLength;\r\n\t\t#else\r\n\t\t\ttoEye=normalize(u_CameraPos-v_PositionWorld);\r\n\t\t#endif\r\n\t#endif\r\n\r\n\t#ifdef LEGACYSINGLELIGHTING\r\n\t\t#ifdef DIRECTIONLIGHT\r\n\t\t\tLayaAirBlinnPhongDiectionLight(vec3(0.0),1.0,normal,vec3(1.0),toEye,u_DirectionLight,dif,spe);\r\n\t\t\tdiffuse+=dif;\r\n\t\t\tspecular+=spe;\r\n\t\t#endif\r\n\t\r\n\t\t#ifdef POINTLIGHT\r\n\t\t\tLayaAirBlinnPhongPointLight(v_PositionWorld,vec3(0.0),1.0,normal,vec3(1.0),toEye,u_PointLight,dif,spe);\r\n\t\t\tdiffuse+=dif;\r\n\t\t\tspecular+=spe;\r\n\t\t#endif\r\n\r\n\t\t#ifdef SPOTLIGHT\r\n\t\t\tLayaAirBlinnPhongSpotLight(v_PositionWorld,vec3(0.0),1.0,normal,vec3(1.0),toEye,u_SpotLight,dif,spe);\r\n\t\t\tdiffuse+=dif;\r\n\t\t\tspecular+=spe;\r\n\t\t#endif\r\n\t#else\r\n\t\t#ifdef DIRECTIONLIGHT\r\n\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t{\r\n\t\t\t\tif(i >= u_DirationLightCount)\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tDirectionLight directionLight = getDirectionLight(u_LightBuffer,i);\r\n\t\t\t\tLayaAirBlinnPhongDiectionLight(vec3(0.0),1.0,normal,vec3(1.0),toEye,directionLight,dif,spe);\r\n\t\t\t\tdiffuse+=dif;\r\n\t\t\t\tspecular+=spe;\r\n\t\t\t}\r\n\t\t#endif\r\n\t\t#if defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t\t\tivec4 clusterInfo =getClusterInfo(u_LightClusterBuffer,u_View,u_Viewport, v_PositionWorld,gl_FragCoord,u_ProjectionParams);\r\n\t\t\t#ifdef POINTLIGHT\r\n\t\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t\t{\r\n\t\t\t\t\tif(i >= clusterInfo.x)//PointLightCount\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tPointLight pointLight = getPointLight(u_LightBuffer,u_LightClusterBuffer,clusterInfo,i);\r\n\t\t\t\t\tLayaAirBlinnPhongPointLight(v_PositionWorld,vec3(0.0),1.0,normal,vec3(1.0),toEye,pointLight,dif,spe);\r\n\t\t\t\t\tdiffuse+=dif;\r\n\t\t\t\t\tspecular+=spe;\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t\t#ifdef SPOTLIGHT\r\n\t\t\t\tfor (int i = 0; i < MAX_LIGHT_COUNT; i++) \r\n\t\t\t\t{\r\n\t\t\t\t\tif(i >= clusterInfo.y)//SpotLightCount\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tSpotLight spotLight = getSpotLight(u_LightBuffer,u_LightClusterBuffer,clusterInfo,i);\r\n\t\t\t\t\tLayaAirBlinnPhongSpotLight(v_PositionWorld,vec3(0.0),1.0,normal,vec3(1.0),toEye\t,spotLight,dif,spe);\r\n\t\t\t\t\tdiffuse+=dif;\r\n\t\t\t\t\tspecular+=spe;\r\n\t\t\t\t}\r\n\t\t\t#endif\r\n\t\t#endif\r\n\t#endif\r\n\r\nvec3 globalDiffuse = u_AmbientColor;\r\n#ifdef LIGHTMAP\r\n\tglobalDiffuse += decodeHDR(texture2D(u_LightMap, v_LightMapUV),5.0);\r\n#endif\r\n\r\n#if defined(CALCULATE_SHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\tfloat shadowValue = shadowValue = sampleShadowmap(v_ShadowCoord);\r\n\tgl_FragColor = vec4(gl_FragColor.rgb * (globalDiffuse + diffuse) * shadowValue, gl_FragColor.a);\r\n#else\r\n\tgl_FragColor = vec4(gl_FragColor.rgb * (globalDiffuse + diffuse), gl_FragColor.a);\r\n#endif\r\n\r\n#if defined(DIRECTIONLIGHT)||defined(POINTLIGHT)||defined(SPOTLIGHT)\r\n\t#if defined(CALCULATE_SHADOWS)//shader中自定义的宏不可用ifdef 必须改成if defined\r\n\t\tgl_FragColor.rgb += specular * shadowValue;\r\n\t#else\r\n\t\tgl_FragColor.rgb += specular;\r\n\t#endif\r\n#endif\r\n\r\n#ifdef FOG\r\n\tfloat lerpFact=clamp((toEyeLength-u_FogStart)/u_FogRange,0.0,1.0);\r\n\tgl_FragColor.rgb=mix(gl_FragColor.rgb,u_FogColor,lerpFact);\r\n#endif\r\n}\r\n\r\n\r\n\r\n\r\n\r\n',r),e={a_Position:Kr.TRAIL_POSITION0,a_OffsetVector:Kr.TRAIL_OFFSETVECTOR,a_Texcoord0X:Kr.TRAIL_TEXTURECOORDINATE0X,a_Texcoord0Y:Kr.TRAIL_TEXTURECOORDINATE0Y,a_BirthTime:Kr.TRAIL_TIME0,a_Color:Kr.TRAIL_COLOR},t={u_MvpMatrix:Z.PERIOD_SPRITE,u_View:Z.PERIOD_CAMERA,u_Projection:Z.PERIOD_CAMERA,u_TilingOffset:Z.PERIOD_MATERIAL,u_MainTexture:Z.PERIOD_MATERIAL,u_MainColor:Z.PERIOD_MATERIAL,u_CurTime:Z.PERIOD_SPRITE,u_LifeTime:Z.PERIOD_SPRITE,u_WidthCurve:Z.PERIOD_SPRITE,u_WidthCurveKeyLength:Z.PERIOD_SPRITE,u_GradientColorkey:Z.PERIOD_SPRITE,u_GradientAlphakey:Z.PERIOD_SPRITE},r={s_Cull:Z.RENDER_STATE_CULL,s_Blend:Z.RENDER_STATE_BLEND,s_BlendSrc:Z.RENDER_STATE_BLEND_SRC,s_BlendDst:Z.RENDER_STATE_BLEND_DST,s_DepthTest:Z.RENDER_STATE_DEPTH_TEST,s_DepthWrite:Z.RENDER_STATE_DEPTH_WRITE},a=Z.add("Trail"),n=new Qt(e,t),a.addSubShader(n),n.addShaderPass('#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n#include "Lighting.glsl";\r\n\r\nattribute vec3 a_Position;\r\nattribute vec3 a_OffsetVector;\r\nattribute vec4 a_Color;\r\nattribute float a_Texcoord0X;\r\nattribute float a_Texcoord0Y;\r\nattribute float a_BirthTime;\r\n\r\nuniform mat4 u_View;\r\nuniform mat4 u_Projection;\r\n\r\nuniform vec4 u_TilingOffset;\r\n\r\nuniform float u_CurTime;\r\nuniform float u_LifeTime;\r\nuniform vec4 u_WidthCurve[10];\r\nuniform int u_WidthCurveKeyLength;\r\n\r\nvarying vec2 v_Texcoord0;\r\nvarying vec4 v_Color;\r\n\r\nfloat hermiteInterpolate(float t, float outTangent, float inTangent, float duration, float value1, float value2)\r\n{\r\n\tfloat t2 = t * t;\r\n\tfloat t3 = t2 * t;\r\n\tfloat a = 2.0 * t3 - 3.0 * t2 + 1.0;\r\n\tfloat b = t3 - 2.0 * t2 + t;\r\n\tfloat c = t3 - t2;\r\n\tfloat d = -2.0 * t3 + 3.0 * t2;\r\n\treturn a * value1 + b * outTangent * duration + c * inTangent * duration + d * value2;\r\n}\r\n\r\nfloat getCurWidth(in float normalizeTime)\r\n{\r\n\tfloat width;\r\n\tif(normalizeTime == 0.0){\r\n\t\twidth=u_WidthCurve[0].w;\r\n\t}\r\n\telse if(normalizeTime >= 1.0){\r\n\t\twidth=u_WidthCurve[u_WidthCurveKeyLength - 1].w;\r\n\t}\r\n\telse{\r\n\t\tfor(int i = 0; i < 10; i ++ )\r\n\t\t{\r\n\t\t\tif(normalizeTime == u_WidthCurve[i].x){\r\n\t\t\t\twidth=u_WidthCurve[i].w;\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tvec4 lastFrame = u_WidthCurve[i];\r\n\t\t\tvec4 nextFrame = u_WidthCurve[i + 1];\r\n\t\t\tif(normalizeTime > lastFrame.x && normalizeTime < nextFrame.x)\r\n\t\t\t{\r\n\t\t\t\tfloat duration = nextFrame.x - lastFrame.x;\r\n\t\t\t\tfloat t = (normalizeTime - lastFrame.x) / duration;\r\n\t\t\t\tfloat outTangent = lastFrame.z;\r\n\t\t\t\tfloat inTangent = nextFrame.y;\r\n\t\t\t\tfloat value1 = lastFrame.w;\r\n\t\t\t\tfloat value2 = nextFrame.w;\r\n\t\t\t\twidth=hermiteInterpolate(t, outTangent, inTangent, duration, value1, value2);\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn width;\r\n}\t\r\n\r\nvoid main()\r\n{\r\n\tfloat normalizeTime = (u_CurTime - a_BirthTime) / u_LifeTime;\r\n\t\r\n\tv_Texcoord0 = vec2(a_Texcoord0X, 1.0 - a_Texcoord0Y) * u_TilingOffset.xy + u_TilingOffset.zw;\r\n\t\r\n\tv_Color = a_Color;\r\n\t\r\n\tvec3 cameraPos = (u_View*vec4(a_Position,1.0)).rgb;\r\n\tgl_Position = u_Projection * vec4(cameraPos+a_OffsetVector * getCurWidth(normalizeTime),1.0);\r\n\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}\r\n',"#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\nuniform sampler2D u_MainTexture;\r\nuniform vec4 u_MainColor;\r\n\r\nvarying vec2 v_Texcoord0;\r\nvarying vec4 v_Color;\r\n\r\nvoid main()\r\n{\r\n\tvec4 color = 2.0 * u_MainColor * v_Color;\r\n\t#ifdef MAINTEXTURE\r\n\t\tvec4 mainTextureColor = texture2D(u_MainTexture, v_Texcoord0);\r\n\t\tcolor *= mainTextureColor;\r\n\t#endif\r\n\tgl_FragColor = color;\r\n}\r\n\r\n ",r),e={a_Position:ie.MESH_POSITION0,a_Normal:ie.MESH_NORMAL0,a_Tangent0:ie.MESH_TANGENT0},t={u_MvpMatrix:Z.PERIOD_SPRITE,u_WorldMat:Z.PERIOD_SPRITE,u_CameraPos:Z.PERIOD_CAMERA,u_Time:Z.PERIOD_SCENE,u_MainTexture:Z.PERIOD_MATERIAL,u_NormalTexture:Z.PERIOD_MATERIAL,u_HorizonColor:Z.PERIOD_MATERIAL,u_WaveScale:Z.PERIOD_MATERIAL,u_WaveSpeed:Z.PERIOD_MATERIAL},a=Z.add("WaterPrimary"),n=new Qt(e,t),a.addSubShader(n),n.addShaderPass('#include "Lighting.glsl";\r\n\r\nattribute vec4 a_Position;\r\nattribute vec3 a_Normal;\r\nattribute vec4 a_Tangent0;\r\n\r\nuniform mat4 u_MvpMatrix;\r\nuniform mat4 u_WorldMat;\r\nuniform vec3 u_CameraPos;\r\nuniform float u_WaveScale;\r\nuniform vec4 u_WaveSpeed;\r\nuniform float u_Time;\r\n\r\nvarying vec3 v_Normal;\r\nvarying vec3 v_Tangent;\r\nvarying vec3 v_Binormal;\r\nvarying vec3 v_ViewDir;\r\nvarying vec2 v_Texcoord0;\r\nvarying vec2 v_Texcoord1;\r\n\r\nvoid main()\r\n{\r\n\tvec4 positionWorld = u_WorldMat * a_Position;\r\n\tvec4 position = u_MvpMatrix * a_Position;\r\n\t\r\n\tvec4 temp = vec4(positionWorld.x, positionWorld.z, positionWorld.x, positionWorld.z) * u_WaveScale + u_WaveSpeed * u_WaveScale * u_Time;\r\n\t\r\n\tv_Texcoord0 = temp.xy * vec2(0.4, 0.45);\r\n\tv_Texcoord1 = temp.wz;\r\n\t\r\n\tmat3 worldMat = mat3(u_WorldMat);\r\n\tv_Normal = worldMat * a_Normal;\r\n\tv_Tangent = worldMat * a_Tangent0.xyz;\r\n\tv_Binormal = cross(v_Normal, v_Tangent) * a_Tangent0.w;\r\n\t\r\n\tv_ViewDir = u_CameraPos - positionWorld.xyz;\r\n\tgl_Position = position;\r\n\tgl_Position=remapGLPositionZ(gl_Position);\r\n}','#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#ifdef MAINTEXTURE\r\n\tuniform sampler2D u_MainTexture;\r\n#endif\r\n\r\n#ifdef NORMALTEXTURE\r\n\tuniform sampler2D u_NormalTexture;\r\n#endif\r\n\r\nuniform vec4 u_HorizonColor;\r\n\r\nvarying vec3 v_Normal;\r\nvarying vec3 v_Tangent;\r\nvarying vec3 v_Binormal;\r\nvarying vec3 v_ViewDir;\r\nvarying vec2 v_Texcoord0;\r\nvarying vec2 v_Texcoord1;\r\n\r\n\r\n#include "Lighting.glsl"\r\n\r\n\r\n\r\nvec3 NormalSampleToWorldSpace(vec4 normalMapSample) {\r\n\tvec3 normalT;\r\n\tnormalT.x = 2.0 * normalMapSample.x - 1.0;\r\n\tnormalT.y = 1.0 - 2.0 * normalMapSample.y;\r\n\tnormalT.z = sqrt(1.0 - clamp(dot(normalT.xy, normalT.xy), 0.0, 1.0));\r\n\r\n\tvec3 bumpedNormal = normalize(normalT);\r\n\r\n\treturn bumpedNormal;\r\n}\r\n\r\n\r\nvoid main()\r\n{\r\n\tvec4 bumpColor1 = texture2D(u_NormalTexture, v_Texcoord0);\r\n\tvec4 bumpColor2 = texture2D(u_NormalTexture, v_Texcoord1);\r\n\r\n\tvec3 normal1 = NormalSampleToWorldSpace(bumpColor1);\r\n\tvec3 normal2 = NormalSampleToWorldSpace(bumpColor2);\r\n\t\r\n\tvec3 normal = normalize((normal1 + normal2) * 0.5);\r\n\tvec3 viewDir = normalize(v_ViewDir);\r\n\tfloat fresnel = dot(viewDir, normal);\r\n\t\r\n\tvec4 waterColor = texture2D(u_MainTexture, vec2(fresnel, fresnel));\r\n\t\r\n\tvec4 color;\r\n\tcolor.rgb = mix(waterColor.rgb, u_HorizonColor.rgb, vec3(waterColor.a));\r\n\tcolor.a = u_HorizonColor.a;\r\n\t\r\n\tgl_FragColor = color;\r\n}\r\n\r\n\r\n'),e={a_PositionTexcoord:ie.MESH_POSITION0},t={u_MainTex:Z.PERIOD_MATERIAL,u_OffsetScale:Z.PERIOD_MATERIAL},a=Z.add("BlitScreen"),n=new Qt(e,t),a.addSubShader(n);var i=n.addShaderPass('#include "Lighting.glsl";\r\n#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\nattribute vec4 a_PositionTexcoord;\r\nuniform vec4 u_OffsetScale;\r\nvarying vec2 v_Texcoord0;\r\n\r\nvoid main() {\t\r\n\tgl_Position = vec4(u_OffsetScale.x*2.0-1.0+(a_PositionTexcoord.x+1.0)*u_OffsetScale.z,(1.0-((u_OffsetScale.y*2.0-1.0+(-a_PositionTexcoord.y+1.0)*u_OffsetScale.w)+1.0)/2.0)*2.0-1.0, 0.0, 1.0);\t\r\n\tv_Texcoord0 = a_PositionTexcoord.zw;\r\n\tgl_Position = remapGLPositionZ(gl_Position);\r\n}',"#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\nuniform sampler2D u_MainTex;\r\nvarying vec2 v_Texcoord0;\r\n\r\nvoid main() {\r\n\tgl_FragColor = texture2D(u_MainTex, v_Texcoord0);\r\n}\r\n\r\n").renderState;i.depthTest=fe.DEPTHTEST_ALWAYS,i.depthWrite=!1,i.cull=fe.CULL_NONE,i.blend=fe.BLEND_DISABLE,e={a_PositionTexcoord:ie.MESH_POSITION0},t={u_MainTex:Z.PERIOD_MATERIAL,u_BloomTex:Z.PERIOD_MATERIAL,u_AutoExposureTex:Z.PERIOD_MATERIAL,u_MainTex_TexelSize:Z.PERIOD_MATERIAL,u_SampleScale:Z.PERIOD_MATERIAL,u_Threshold:Z.PERIOD_MATERIAL,u_Params:Z.PERIOD_MATERIAL},a=Z.add("PostProcessBloom"),n=new Qt(e,t),a.addSubShader(n),(i=n.addShaderPass(oa,'#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include "Colors.glsl";\r\n#include "Sampling.glsl";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform sampler2D u_AutoExposureTex;\r\nuniform vec4 u_MainTex_TexelSize;\r\nuniform vec4 u_Threshold; // x: threshold value (linear), y: threshold - knee, z: knee * 2, w: 0.25 / knee\r\nuniform vec4 u_Params; // x: clamp, yzw: unused\r\n\r\nmediump vec4 prefilter(mediump vec4 color, vec2 uv) {\r\n\tmediump float autoExposure = texture2D(u_AutoExposureTex, uv).r;\r\n\tcolor *= autoExposure;\r\n\tcolor = min(vec4(u_Params.x), color); // clamp to max\r\n\tcolor = quadraticThreshold(color, u_Threshold.x, u_Threshold.yzw);\r\n\treturn color;\r\n}\r\n\r\nvoid fragPrefilter13() {\r\n\tmediump vec4 color = downsampleBox13Tap(u_MainTex, v_Texcoord0, u_MainTex_TexelSize.xy);\r\n\tgl_FragColor = prefilter(safeHDR(color), v_Texcoord0);\r\n}\r\n\r\nvoid main() {\r\n\tfragPrefilter13();\r\n}').renderState).depthTest=fe.DEPTHTEST_ALWAYS,i.depthWrite=!1,i.cull=fe.CULL_NONE,i.blend=fe.BLEND_DISABLE,n=new Qt(e,t),a.addSubShader(n),(i=n.addShaderPass(oa,'#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include "Colors.glsl";\r\n#include "Sampling.glsl";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform sampler2D u_AutoExposureTex;\r\nuniform vec4 u_MainTex_TexelSize;\r\nuniform vec4 u_Threshold; // x: threshold value (linear), y: threshold - knee, z: knee * 2, w: 0.25 / knee\r\nuniform vec4 u_Params; // x: clamp, yzw: unused\r\n\r\nmediump vec4 prefilter(mediump vec4 color, vec2 uv) {\r\n\tmediump float autoExposure = texture2D(u_AutoExposureTex, uv).r;\r\n\tcolor *= autoExposure;\r\n\tcolor = min(vec4(u_Params.x), color); // clamp to max\r\n\tcolor = quadraticThreshold(color, u_Threshold.x, u_Threshold.yzw);\r\n\treturn color;\r\n}\r\n\r\nvoid fragPrefilter4() {\r\n\tmediump vec4 color = downsampleBox4Tap(u_MainTex, v_Texcoord0, u_MainTex_TexelSize.xy);\r\n\tgl_FragColor = prefilter(safeHDR(color), v_Texcoord0);\r\n}\r\n\r\nvoid main() {\r\n\tfragPrefilter4();\r\n}').renderState).depthTest=fe.DEPTHTEST_ALWAYS,i.depthWrite=!1,i.cull=fe.CULL_NONE,i.blend=fe.BLEND_DISABLE,n=new Qt(e,t),a.addSubShader(n),(i=n.addShaderPass(oa,'#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include "Colors.glsl";\r\n#include "Sampling.glsl";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform vec4 u_MainTex_TexelSize;\r\n\r\nvoid fragDownsample13() {\r\n\tmediump vec4 color = downsampleBox13Tap(u_MainTex, v_Texcoord0, u_MainTex_TexelSize.xy);\r\n\tgl_FragColor = color;\r\n}\r\n\r\nvoid main() {\r\n\tfragDownsample13();\r\n}').renderState).depthTest=fe.DEPTHTEST_ALWAYS,i.depthWrite=!1,i.cull=fe.CULL_NONE,i.blend=fe.BLEND_DISABLE,n=new Qt(e,t),a.addSubShader(n),(i=n.addShaderPass(oa,'#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include "Colors.glsl";\r\n#include "Sampling.glsl";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform vec4 u_MainTex_TexelSize;\r\n\r\nvoid fragDownsample4() {\r\n\tmediump vec4 color = downsampleBox4Tap(u_MainTex, v_Texcoord0, u_MainTex_TexelSize.xy);\r\n\tgl_FragColor = color;\r\n}\r\n\r\nvoid main() {\r\n\tfragDownsample4();\r\n}').renderState).depthTest=fe.DEPTHTEST_ALWAYS,i.depthWrite=!1,i.cull=fe.CULL_NONE,i.blend=fe.BLEND_DISABLE,n=new Qt(e,t),a.addSubShader(n),(i=n.addShaderPass(oa,'#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include "Colors.glsl";\r\n#include "Sampling.glsl";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform sampler2D u_BloomTex;\r\n\r\nuniform vec4 u_MainTex_TexelSize;\r\nuniform float u_SampleScale;\r\n\r\nmediump vec4 combine(mediump vec4 bloom, vec2 uv) {\r\n\tmediump vec4 color = texture2D(u_BloomTex, uv);\r\n\treturn bloom + color;\r\n}\r\n\r\nvoid fragUpsampleTent() {\r\n\tmediump vec4 bloom = upsampleTent(u_MainTex, v_Texcoord0, u_MainTex_TexelSize.xy, vec4(u_SampleScale));\r\n\tgl_FragColor = combine(bloom, v_Texcoord0);\r\n}\r\n\r\nvoid main() {\r\n\tfragUpsampleTent();\r\n}').renderState).depthTest=fe.DEPTHTEST_ALWAYS,i.depthWrite=!1,i.cull=fe.CULL_NONE,i.blend=fe.BLEND_DISABLE,n=new Qt(e,t),a.addSubShader(n),(i=n.addShaderPass(oa,'#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include "Colors.glsl";\r\n#include "Sampling.glsl";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform sampler2D u_BloomTex;\r\n\r\nuniform vec4 u_MainTex_TexelSize;\r\nuniform float u_SampleScale;\r\n\r\nmediump vec4 combine(mediump vec4 bloom, vec2 uv) {\r\n\tmediump vec4 color = texture2D(u_BloomTex, uv);\r\n\treturn bloom + color;\r\n}\r\n\r\nvoid fragUpsampleBox() {\r\n\tmediump vec4 bloom = upsampleBox(u_MainTex, v_Texcoord0, u_MainTex_TexelSize.xy, vec4(u_SampleScale));\r\n\tgl_FragColor = combine(bloom, v_Texcoord0);\r\n}\r\n\r\nvoid main() {\r\n\tfragUpsampleBox();\r\n}').renderState).depthTest=fe.DEPTHTEST_ALWAYS,i.depthWrite=!1,i.cull=fe.CULL_NONE,i.blend=fe.BLEND_DISABLE,e={a_PositionTexcoord:ie.MESH_POSITION0},t={u_MainTex:Z.PERIOD_MATERIAL,u_BloomTex:Z.PERIOD_MATERIAL,u_AutoExposureTex:Z.PERIOD_MATERIAL,u_Bloom_DirtTileOffset:Z.PERIOD_MATERIAL,u_Bloom_DirtTex:Z.PERIOD_MATERIAL,u_BloomTex_TexelSize:Z.PERIOD_MATERIAL,u_Bloom_Settings:Z.PERIOD_MATERIAL,u_Bloom_Color:Z.PERIOD_MATERIAL},a=Z.add("PostProcessComposite"),n=new Qt(e,t),a.addSubShader(n),(i=n.addShaderPass('#include "Lighting.glsl";\r\n\r\nattribute vec4 a_PositionTexcoord;\r\nvarying vec2 v_Texcoord0;\r\n\r\nvoid main() {\r\n\tgl_Position = vec4(a_PositionTexcoord.xy, 0.0, 1.0);\r\n\tv_Texcoord0 = a_PositionTexcoord.zw;\r\n\tgl_Position = remapGLPositionZ(gl_Position);\r\n}','#if defined(GL_FRAGMENT_PRECISION_HIGH)// 原来的写法会被我们自己的解析流程处理,而我们的解析是不认内置宏的,导致被删掉,所以改成 if defined 了\r\n\tprecision highp float;\r\n#else\r\n\tprecision mediump float;\r\n#endif\r\n\r\n#include "Colors.glsl";\r\n#include "Sampling.glsl";\r\n\r\nvarying vec2 v_Texcoord0;\r\n\r\nuniform sampler2D u_MainTex;\r\nuniform sampler2D u_BloomTex;\r\n\r\nuniform sampler2D u_AutoExposureTex;\r\nuniform sampler2D u_Bloom_DirtTex;\r\nuniform vec4 u_BloomTex_TexelSize;\r\nuniform vec4 u_Bloom_DirtTileOffset; // xy: tiling, zw: offset\r\nuniform mediump vec3 u_Bloom_Settings;// x: sampleScale, y: intensity, z: dirt intensity\r\nuniform mediump vec3 u_Bloom_Color;\r\n\r\nvoid main() {\r\n\tmediump float autoExposure = texture2D(u_AutoExposureTex, v_Texcoord0).r;\r\n\tmediump vec4 color=vec4(0.0);\r\n\tcolor = texture2D(u_MainTex, v_Texcoord0);\r\n\t\r\n\tcolor = sRGBToLinear(color);\r\n\tcolor.rgb *= autoExposure;\r\n\t\r\n\t#if defined(BLOOM)||defined(BLOOM_LOW)\r\n\t\t#ifdef BLOOM\r\n\t\t\tmediump vec4 bloom = upsampleTent(u_BloomTex, v_Texcoord0, u_BloomTex_TexelSize.xy, vec4(u_Bloom_Settings.x));\r\n\t\t#else\r\n\t\t\tmediump vec4 bloom = upsampleBox(u_BloomTex, v_Texcoord0, u_BloomTex_TexelSize.xy, vec4(u_Bloom_Settings.x));\r\n\t\t#endif\r\n\r\n\t\t// UVs should be Distort(uv * u_Bloom_DirtTileOffset.xy + u_Bloom_DirtTileOffset.zw)\r\n\t\t// but considering we use a cover-style scale on the dirt texture the difference\r\n\t\t// isn\'t massive so we chose to save a few ALUs here instead in case lens distortion\r\n\t\t// is active\r\n\t\tmediump vec4 dirt =vec4(texture2D(u_Bloom_DirtTex, v_Texcoord0 * u_Bloom_DirtTileOffset.xy + u_Bloom_DirtTileOffset.zw).rgb, 0.0);\r\n\r\n\t\t// Additive bloom (artist friendly)\r\n\t\tbloom *= u_Bloom_Settings.y;\r\n\t\tdirt *= u_Bloom_Settings.z;\r\n\t\tmediump vec4 bloomColor=vec4(u_Bloom_Color, 1.0);\r\n\t\tcolor += bloom * bloomColor;\r\n\t\tcolor += dirt * bloom;\r\n\t#endif\r\n\t\r\n\tmediump vec4 finalColor = color;\r\n\tfinalColor = linearToSRGB(finalColor);\r\n\t//finalColor.rgb = Dither(finalColor.rgb, v_Texcoord0);//TODO:抖动\r\n\tgl_FragColor = finalColor;\r\n}').renderState).depthTest=fe.DEPTHTEST_ALWAYS,i.depthWrite=!1,i.cull=fe.CULL_NONE,i.blend=fe.BLEND_DISABLE}}class ha extends lt{constructor(){super(),this._direction=new i,this._shadowCascadesMode=e.ShadowCascadesMode.NoCascades,this._shadowTwoCascadeSplits=1/3,this._shadowFourCascadeSplits=new i(1/15,.2,7/15),this._lightType=e.LightType.Directional}get shadowCascadesMode(){return this._shadowCascadesMode}set shadowCascadesMode(e){this._shadowCascadesMode=e}get shadowTwoCascadeSplits(){return this._shadowTwoCascadeSplits}set shadowTwoCascadeSplits(e){this._shadowTwoCascadeSplits=e}get shadowFourCascadeSplits(){return this._shadowFourCascadeSplits}set shadowFourCascadeSplits(e){if(e.x>e.y||e.y>e.z||e.z>1)throw"DiretionLight:Invalid value.";e.cloneTo(this._shadowFourCascadeSplits)}_addToLightQueue(){this._scene._directionLights.add(this)}_removeFromLightQueue(){this._scene._directionLights.remove(this)}_create(){return new ha}}class _a extends lt{constructor(){super(),this._range=6,this._lightType=e.LightType.Point}get range(){return this._range}set range(e){this._range=e}_addToLightQueue(){this._scene._pointLights.add(this)}_removeFromLightQueue(){this._scene._pointLights.remove(this)}_parse(e,t){super._parse(e,t),this.range=e.range}_cloneTo(t,r,a){super._cloneTo(t,r,a);var n=t;n.range=this.range,n._lightType=e.LightType.Point}_create(){return new _a}}class da extends lt{constructor(){super(),this._spotAngle=30,this._range=10,this._direction=new i,this._lightType=e.LightType.Spot}get spotAngle(){return this._spotAngle}set spotAngle(e){this._spotAngle=Math.max(Math.min(e,179),0)}get range(){return this._range}set range(e){this._range=e}_addToLightQueue(){this._scene._spotLights.add(this)}_removeFromLightQueue(){this._scene._spotLights.remove(this)}_parse(e,t){super._parse(e,t),this.range=e.range,this.spotAngle=e.spotAngle}_cloneTo(e,t,r){super._cloneTo(e,t,r);var a=e;a.range=this.range,a.spotAngle=this.spotAngle}_create(){return new da}}class ca extends Zr{constructor(e){super(e),this._simpleAnimatorParams=new n,this._simpleAnimatorOffset=new a,this._shaderValues.addDefine(Yr.SHADERDEFINE_SIMPLEBONE),this._shaderValues.addDefine(Yr.SHADERDEFINE_BONE)}get simpleAnimatorTexture(){return this._simpleAnimatorTexture}set simpleAnimatorTexture(e){this._simpleAnimatorTexture=e,this._simpleAnimatorTextureSize=e.width,this._shaderValues.setTexture(ca.SIMPLE_SIMPLEANIMATORTEXTURE,e),e._addReference(),this._shaderValues.setNumber(ca.SIMPLE_SIMPLEANIMATORTEXTURESIZE,this._simpleAnimatorTextureSize)}get simpleAnimatorOffset(){return this._simpleAnimatorOffset}set simpleAnimatorOffset(e){e.cloneTo(this._simpleAnimatorOffset)}_computeAnimatorParamsData(){this._cacheMesh&&(this._simpleAnimatorParams.x=this._simpleAnimatorOffset.x,this._simpleAnimatorParams.y=Math.round(this._simpleAnimatorOffset.y)*this._bonesNums*4)}_createRenderElement(){return new Lt}_setCacheAnimator(e){this._cacheAnimator=e,this._shaderValues.addDefine(Yr.SHADERDEFINE_SIMPLEBONE)}_onMeshChange(e){super._onMeshChange(e),this._cacheMesh=e}_renderUpdate(e,t){var r=e.renderElement;switch(r.renderType){case Dt.RENDERTYPE_NORMAL:if(this._cacheAnimator){var a=this._cacheAnimator.owner.transform.worldMatrix;this._shaderValues.setMatrix4x4($.WORLDMATRIX,a)}else this._shaderValues.setMatrix4x4($.WORLDMATRIX,t.worldMatrix);this._computeAnimatorParamsData(),this._shaderValues.setVector(ca.SIMPLE_SIMPLEANIMATORPARAMS,this._simpleAnimatorParams);break;case Dt.RENDERTYPE_INSTANCEBATCH:var n=Mt.instance.instanceWorldMatrixData,i=r.instanceBatchElementList,s=i.elements,o=i.length;if(this._cacheAnimator)for(var l=0;l65535?e.IndexFormat.UInt32:e.IndexFormat.UInt16,g._vertexBuffer=I,g._vertexCount+=u,n+=4*_.length}var M,D=l+i.getUint32(),L=i.getUint32();M=g.indexFormat==e.IndexFormat.UInt32?new Uint32Array(s.slice(D,D+L)):new Uint16Array(s.slice(D,D+L));var y=new rt(g.indexFormat,M.length,a.STATIC_DRAW,!0);if(y.setData(M),g._indexBuffer=y,g._setBuffer(g._vertexBuffer,y),n+=2*y.indexCount,g._setCPUMemory(n),g._setGPUMemory(n),"LAYAMODEL:0501"==Ea._version||"LAYAMODEL:COMPRESSION_0501"==Ea._version){var C=g.bounds,O=C.getMin(),N=C.getMax();O.setValue(i.getFloat32(),i.getFloat32(),i.getFloat32()),N.setValue(i.getFloat32(),i.getFloat32(),i.getFloat32()),C.setMin(O),C.setMax(N),g.bounds=C}var P=g._boneNames=[],w=i.getUint16();for(P.length=w,r=0;r v_Image180ScaleAndCutoff.y)\r\n\t\tgl_FragColor=vec4(0,0,0,1);\r\n\ttc.x = mod(tc.x*v_Image180ScaleAndCutoff.x, 1.0);\r\n\ttc = (tc + v_Layout3DScaleAndOffset.xy) * v_Layout3DScaleAndOffset.zw;\r\n\r\n\tmediump vec4 tex = texture2D (u_Texture, tc);\r\n\tmediump vec3 c = decodeHDR (tex, u_TextureHDRParams.x);\r\n\tc = c * u_TintColor.rgb * 2.0;//Gamma Space is 2.0,linear space is 4.59479380\r\n\tgl_FragColor=vec4(c, 1.0);\r\n}\r\n\r\n')}get tintColor(){return this._shaderValues.getVector(ga.TINTCOLOR)}set tintColor(e){this._shaderValues.setVector(ga.TINTCOLOR,e)}get exposure(){return this._exposure}set exposure(e){this._exposure!==e&&(this._exposure=e,this._textureDecodeFormat==t.TextureDecodeFormat.RGBM?this._textureHDRParams.x=e*t.BaseTexture._rgbmRange:this._textureHDRParams.x=e)}get rotation(){return this._shaderValues.getNumber(ga.ROTATION)}set rotation(e){this._shaderValues.setNumber(ga.ROTATION,e)}get panoramicTexture(){return this._shaderValues.getTexture(ga.TEXTURE)}set panoramicTexture(e){this._shaderValues.setTexture(ga.TEXTURE,e)}get panoramicTextureDecodeFormat(){return this._textureDecodeFormat}set panoramicTextureDecodeFormat(e){this._textureDecodeFormat!==e&&(this._textureDecodeFormat=e,e==t.TextureDecodeFormat.RGBM?this._textureHDRParams.x=this._exposure*t.BaseTexture._rgbmRange:this._textureHDRParams.x=this._exposure)}}ga.TINTCOLOR=Z.propertyNameToID("u_TintColor"),ga.EXPOSURE=Z.propertyNameToID("u_Exposure"),ga.ROTATION=Z.propertyNameToID("u_Rotation"),ga.TEXTURE=Z.propertyNameToID("u_Texture"),ga.TEXTURE_HDR_PARAMS=Z.propertyNameToID("u_TextureHDRParams");class Sa{constructor(){}static get enablePhysics(){return _._enablePhysics}static _cancelLoadByUrl(e){t.Laya.loader.cancelLoadByUrl(e),Sa._innerFirstLevelLoaderManager.cancelLoadByUrl(e),Sa._innerSecondLevelLoaderManager.cancelLoadByUrl(e),Sa._innerThirdLevelLoaderManager.cancelLoadByUrl(e),Sa._innerFourthLevelLoaderManager.cancelLoadByUrl(e)}static _changeWebGLSize(e,r){t.WebGL.onStageResize(e,r),N.clientWidth=e,N.clientHeight=r}static __init__(r,a,n){if(t.Config.isAntialias=n.isAntialias,t.Config.isAlpha=n.isAlpha,t.Config.premultipliedAlpha=n.premultipliedAlpha,t.Config.isStencil=n.isStencil,t.WebGL.enable()){t.RunDriver.changeWebGLSize=Sa._changeWebGLSize,t.Render.is3DMode=!0,t.Laya.init(r,a),t.Render.supportWebGLPlusRendering||(t.LayaGL.instance=t.WebGLContext.mainContext,t.LayaGL.instance.createCommandEncoder=function(e=128,r=64,a=!1){return new t.CommandEncoder(this,e,r,a)}),n._multiLighting=n.enableMultiLight&&t.SystemUtils.supportTextureFormat(t.TextureFormat.R32G32B32A32),h.Shader3D=Z,h.Scene3D=qt,h.MeshRenderStaticBatchManager=Ot,h.MeshRenderDynamicBatchManager=hr,h.SubMeshDynamicBatch=lr,h.Laya3D=Sa,h.Matrix4x4=B,h.Physics3D=_,h.ShadowLightType=e.ShadowLightType,h.Camera=dt,h.CommandBuffer=oe,h.RenderElement=Dt,h.SubMeshRenderElement=Lt,Sa.enableNative3D(),n.isUseCannonPhysicsEngine&&_.__cannoninit__(),_.__bulletinit__(),V.__init__(),ie.__init__(),Ur.__init__(),Hr.__init__(),ut.__init__(),Kr.__init__(),ra.__init__(),vt.__init__(),Mt.__init__(),lr.__init__(),la.__init__(),ht.init(),ge.__init__(),tr.__init__(),Kt.__init__(),ga.__init__(),ia.__init__(),sa.__init__(),$.__init__(),At.__init__(),_r.__init__(),qr.__init__(),ua.__init__(),Xr.__init__(),ta.__init__(),he.__init__(),qt.__init__(),Ot.__init__(),ue.__initDefine__(),me.__initDefine__(),Ee.__initDefine__(),ar.__initDefine__(),nr.__initDefine__(),jr.__initDefine__(),Te.__initDefine__(),ir.__initDefine__(),br.__initDefine__(),pe.__initDefine__(),pt.__initDefine__(),rr.__initDefine__(),q.__init__(),t.ClassUtils.regClass("Laya.SkyPanoramicMaterial",ga),t.ClassUtils.regClass("Laya.EffectMaterial",Te),t.ClassUtils.regClass("Laya.UnlitMaterial",nr),t.ClassUtils.regClass("Laya.BlinnPhongMaterial",Ee),t.ClassUtils.regClass("Laya.SkyProceduralMaterial",ar),t.ClassUtils.regClass("Laya.PBRStandardMaterial",tr),t.ClassUtils.regClass("Laya.PBRSpecularMaterial",Kt),t.ClassUtils.regClass("Laya.SkyBoxMaterial",rr),t.ClassUtils.regClass("Laya.WaterPrimaryMaterial",ir),t.ClassUtils.regClass("Laya.ExtendTerrainMaterial",pe),t.ClassUtils.regClass("Laya.ShurikenParticleMaterial",br),t.ClassUtils.regClass("Laya.TrailMaterial",jr),t.ClassUtils.regClass("Laya.PhysicsCollider",t.PhysicsCollider),t.ClassUtils.regClass("Laya.Rigidbody3D",t.Rigidbody3D),t.ClassUtils.regClass("Laya.CharacterController",t.CharacterController),t.ClassUtils.regClass("Laya.Animator",O),t.ClassUtils.regClass("PhysicsCollider",t.PhysicsCollider),t.ClassUtils.regClass("CharacterController",t.CharacterController),t.ClassUtils.regClass("Animator",O),t.ClassUtils.regClass("Rigidbody3D",t.Rigidbody3D),t.ClassUtils.regClass("FixedConstraint",t.FixedConstraint),t.ClassUtils.regClass("ConfigurableConstraint",t.ConfigurableConstraint),pt.defaultMaterial=new pt,Ee.defaultMaterial=new Ee,Te.defaultMaterial=new Te,nr.defaultMaterial=new nr,br.defaultMaterial=new br,jr.defaultMaterial=new jr,ar.defaultMaterial=new ar,rr.defaultMaterial=new rr,ir.defaultMaterial=new ir,pt.defaultMaterial.lock=!0,Ee.defaultMaterial.lock=!0,Te.defaultMaterial.lock=!0,nr.defaultMaterial.lock=!0,br.defaultMaterial.lock=!0,jr.defaultMaterial.lock=!0,ar.defaultMaterial.lock=!0,rr.defaultMaterial.lock=!0,ir.defaultMaterial.lock=!0,t.Texture2D.__init__(),ft.__init__(),nt.__init__(),mt.__init__(),z.__init__(),k.__init__(),ke.__init__(),t.HalfFloatUtils.__init__();var i=t.LoaderManager.createMap;i.lh=[Sa.HIERARCHY,ma._parse],i.ls=[Sa.HIERARCHY,ma._parseScene],i.lm=[Sa.MESH,Ta._parse],i.lmat=[Sa.MATERIAL,ue._parse],i.jpg=[Sa.TEXTURE2D,t.Texture2D._parse],i.jpeg=[Sa.TEXTURE2D,t.Texture2D._parse],i.bmp=[Sa.TEXTURE2D,t.Texture2D._parse],i.gif=[Sa.TEXTURE2D,t.Texture2D._parse],i.png=[Sa.TEXTURE2D,t.Texture2D._parse],i.dds=[Sa.TEXTURE2D,t.Texture2D._parse],i.ktx=[Sa.TEXTURE2D,t.Texture2D._parse],i.pvr=[Sa.TEXTURE2D,t.Texture2D._parse],i.lani=[Sa.ANIMATIONCLIP,I._parse],i.lav=[Sa.AVATAR,ce._parse],i.ltc=[Sa.TEXTURECUBE,ft._parse],i.ltcb=[Sa.TEXTURECUBEBIN,ft._parseBin],i["ltcb.ls"]=[Sa.TEXTURECUBEBIN,ft._parseBin],i["lanit.ls"]=[Sa.TEXTURE2D,t.Texture2D._SimpleAnimatorTextureParse];var s=t.Loader.parserMap;s[Sa.HIERARCHY]=Sa._loadHierarchy,s[Sa.MESH]=Sa._loadMesh,s[Sa.MATERIAL]=Sa._loadMaterial,s[Sa.TEXTURECUBE]=Sa._loadTextureCube,s[Sa.TEXTURECUBEBIN]=Sa._loadTextureCubeBin,s[Sa.TEXTURE2D]=Sa._loadTexture2D,s[Sa.ANIMATIONCLIP]=Sa._loadAnimationClip,s[Sa.AVATAR]=Sa._loadAvatar,s[Sa.SIMPLEANIMATORBIN]=Sa._loadSimpleAnimator,Sa._innerFirstLevelLoaderManager.on(t.Event.ERROR,null,Sa._eventLoadManagerError),Sa._innerSecondLevelLoaderManager.on(t.Event.ERROR,null,Sa._eventLoadManagerError),Sa._innerThirdLevelLoaderManager.on(t.Event.ERROR,null,Sa._eventLoadManagerError),Sa._innerFourthLevelLoaderManager.on(t.Event.ERROR,null,Sa._eventLoadManagerError)}else alert("Laya3D init error,must support webGL!")}static enableNative3D(){var e=F,r=Be;t.Render.supportWebGLPlusRendering&&(e.prototype._initData=e.prototype._initDataForNative,e.prototype.setBool=e.prototype.setBoolForNative,e.prototype.getBool=e.prototype.getBoolForNative,e.prototype.setInt=e.prototype.setIntForNative,e.prototype.getInt=e.prototype.getIntForNative,e.prototype.setNumber=e.prototype.setNumberForNative,e.prototype.getNumber=e.prototype.getNumberForNative,e.prototype.setVector=e.prototype.setVectorForNative,e.prototype.getVector=e.prototype.getVectorForNative,e.prototype.setVector2=e.prototype.setVector2ForNative,e.prototype.getVector2=e.prototype.getVector2ForNative,e.prototype.setVector3=e.prototype.setVector3ForNative,e.prototype.getVector3=e.prototype.getVector3ForNative,e.prototype.setQuaternion=e.prototype.setQuaternionForNative,e.prototype.getQuaternion=e.prototype.getQuaternionForNative,e.prototype.setMatrix4x4=e.prototype.setMatrix4x4ForNative,e.prototype.getMatrix4x4=e.prototype.getMatrix4x4ForNative,e.prototype.setBuffer=e.prototype.setBufferForNative,e.prototype.getBuffer=e.prototype.getBufferForNative,e.prototype.setTexture=e.prototype.setTextureForNative,e.prototype.getTexture=e.prototype.getTextureForNative,e.prototype.setAttribute=e.prototype.setAttributeForNative,e.prototype.getAttribute=e.prototype.getAttributeForNative,e.prototype.cloneTo=e.prototype.cloneToForNative,e.prototype.getData=e.prototype.getDataForNative,r.prototype._uniformMatrix2fv=r.prototype._uniformMatrix2fvForNative,r.prototype._uniformMatrix3fv=r.prototype._uniformMatrix3fvForNative,r.prototype._uniformMatrix4fv=r.prototype._uniformMatrix4fvForNative,t.LayaGLRunner.uploadShaderUniforms=t.LayaGLRunner.uploadShaderUniformsForNative)}static formatRelativePath(e,t){var r;if(r=e+t,"."===t.charAt(0)){for(var a=r.split("/"),n=0,i=a.length;n0&&".."!==a[s]&&(a.splice(s,2),n-=2)}r=a.join("/")}return r}static _endLoad(e,r=null,a=null){if(a)for(var n=0,i=a.length;n0){var m=d/c,f=t.Handler.create(null,Sa._onProcessChange,[e,u,m],!1);Sa._innerFourthLevelLoaderManager._create(h,!1,t.Handler.create(null,Sa._onHierarchyInnerForthLevResouLoaded,[e,f,r,_,s,o,l,u+m*h.length,m]),f,null,null,null,1,!0)}else Sa._onHierarchyInnerForthLevResouLoaded(e,null,r,_,s,o,l,u,m)}static _onHierarchyInnerForthLevResouLoaded(e,r,a,n,i,s,o,l,h){if(r&&r.recover(),o.length>0){var _=t.Handler.create(null,Sa._onProcessChange,[e,l,h],!1);Sa._innerThirdLevelLoaderManager._create(o,!1,t.Handler.create(null,Sa._onHierarchyInnerThirdLevResouLoaded,[e,_,a,n,i,s,l+h*s.length,h]),r,null,null,null,1,!0)}else Sa._onHierarchyInnerThirdLevResouLoaded(e,null,a,n,i,s,l,h)}static _onHierarchyInnerThirdLevResouLoaded(e,r,a,n,i,s,o,l){if(r&&r.recover(),s.length>0){var h=t.Handler.create(null,Sa._onProcessChange,[e,o,l],!1);Sa._innerSecondLevelLoaderManager._create(s,!1,t.Handler.create(null,Sa._onHierarchyInnerSecondLevResouLoaded,[e,h,a,n,i,o+l*s.length,l]),r,null,null,null,1,!0)}else Sa._onHierarchyInnerSecondLevResouLoaded(e,null,a,n,i,o,l)}static _onHierarchyInnerSecondLevResouLoaded(e,r,a,n,i,s,o){if(r&&r.recover(),i.length>0){var l=t.Handler.create(null,Sa._onProcessChange,[e,s,o],!1);Sa._innerFirstLevelLoaderManager._create(i,!1,t.Handler.create(null,Sa._onHierarchyInnerFirstLevResouLoaded,[e,l,a,n]),r,null,null,null,1,!0)}else Sa._onHierarchyInnerFirstLevResouLoaded(e,null,a,n)}static _onHierarchyInnerFirstLevResouLoaded(e,t,r,a){t&&t.recover(),e._cache=e._createCache;var n="Scene3D"===r.data.type?ma._parseScene(r,e._propertyParams,e._constructParams):ma._parse(r,e._propertyParams,e._constructParams);Sa._endLoad(e,n,a)}static _loadMesh(e){e.on(t.Event.LOADED,null,Sa._onMeshLmLoaded,[e]),e.load(e.url,t.Loader.BUFFER,!1,null,!0)}static _onMeshLmLoaded(e,t){e._cache=e._createCache;var r=Ta._parse(t,e._propertyParams,e._constructParams);Sa._endLoad(e,r)}static _loadMaterial(e){e.on(t.Event.LOADED,null,Sa._onMaterilLmatLoaded,[e]),e.load(e.url,t.Loader.JSON,!1,null,!0)}static _onMaterilLmatLoaded(e,r){var a,n=e.url,i=A.getURLVerion(n),s=t.URL.getPath(n),o=[],l=[];r.customProps;switch(r.version){case"LAYAMATERIAL:01":case"LAYAMATERIAL:02":case"LAYAMATERIAL:03":var h,_,d=r.props.textures;if(d)for(h=0,_=d.length;h<_;h++){var c=d[h],u=c.path;u&&(a=Sa.formatRelativePath(s,u),i&&(a+=i),o.push({url:a,constructParams:c.constructParams,propertyParams:c.propertyParams}),l.push(a),c.path=a)}break;default:throw new Error("Laya3D:unkonwn version.")}var m=o.length,f=m+1,E=1/f;if(Sa._onProcessChange(e,0,E,1),m>0){var T=t.Handler.create(null,Sa._onProcessChange,[e,E,m/f],!1);Sa._innerFourthLevelLoaderManager._create(o,!1,t.Handler.create(null,Sa._onMateialTexturesLoaded,[e,T,r,l]),T,null,null,null,1,!0)}else Sa._onMateialTexturesLoaded(e,null,r,null)}static _onMateialTexturesLoaded(e,t,r,a){e._cache=e._createCache;var n=ue._parse(r,e._propertyParams,e._constructParams);Sa._endLoad(e,n,a),t&&t.recover()}static _loadAvatar(e){e.on(t.Event.LOADED,null,(function(t){e._cache=e._createCache;var r=ce._parse(t,e._propertyParams,e._constructParams);Sa._endLoad(e,r)})),e.load(e.url,t.Loader.JSON,!1,null,!0)}static _loadSimpleAnimator(e){e.on(t.Event.LOADED,null,(function(r){e._cache=e._createCache;var a=t.Texture2D._SimpleAnimatorTextureParse(r,e._propertyParams,e._constructParams);Sa._endLoad(e,a)})),e.load(e.url,t.Loader.BUFFER,!1,null,!0)}static _loadAnimationClip(e){e.on(t.Event.LOADED,null,(function(t){e._cache=e._createCache;var r=I._parse(t);Sa._endLoad(e,r)})),e.load(e.url,t.Loader.BUFFER,!1,null,!0)}static _loadTexture2D(e){var r,a=e.url,n=a.lastIndexOf(".")+1,i=a.indexOf("?"),s=-1==i?a.length:i;switch(a.substr(n,s-n)){case"jpg":case"jpeg":case"bmp":case"gif":case"png":r="nativeimage";break;case"dds":r=t.Loader.BUFFER;break;case"ktx":r=t.Loader.BUFFER,!e._constructParams&&(e._constructParams=[]),e._constructParams[2]=t.TextureFormat.KTXTEXTURE;break;case"pvr":r=t.Loader.BUFFER,!e._constructParams&&(e._constructParams=[]),e._propertyParams[2]=t.TextureFormat.PVRTEXTURE}e.on(t.Event.LOADED,null,(function(r){e._cache=e._createCache;var a=t.Texture2D._parse(r,e._propertyParams,e._constructParams);Sa._endLoad(e,a)})),e.load(e.url,r,!1,null,!0)}static _loadTextureCube(e){e.on(t.Event.LOADED,null,Sa._onTextureCubeLtcLoaded,[e]),e.load(e.url,t.Loader.JSON,!1,null,!0)}static _loadTextureCubeBin(e){e.on(t.Event.LOADED,null,r=>{e._cache=e._createCache;var a=new t.Byte(r);if("LAYATEXTURECUBE:0000"!==a.readUTFString())throw"Laya3D:unknow version.";var n=a.readUint8(),i=a.getUint8(),s=a.readUint16(),o=a.getUint8(),l=a.getUint8(),h=a.getUint8(),_=a.getUint8(),d=new ft(s,n,i>1);d.filterMode=o,d.wrapModeU=l,d.wrapModeV=h,d.anisoLevel=_;for(var c=a.pos,u=s,m=0;m=0&&e=0&&t0?s:0,h=Math.floor(a.width/(2-o)),_=Math.floor(a.height/(2-l)),d=Math.max(h,_);i=Math.log2(d)+this._diffusion-10;var c=Math.floor(i),u=Math.min(Math.max(c,1),Ma.MAXPYRAMIDSIZE),m=.5+i-c;this._shaderData.setNumber(Ma.SHADERVALUE_SAMPLESCALE,m);var f=He.gammaToLinearSpace(this.threshold),E=f*this._softKnee+1e-5;this._shaderThreshold.setValue(f,f-E,2*E,.25/E),this._shaderData.setVector(Ma.SHADERVALUE_THRESHOLD,this._shaderThreshold);var T=He.gammaToLinearSpace(this.clamp);this._shaderParams.setValue(T,0,0,0),this._shaderData.setVector(Ma.SHADERVALUE_PARAMS,this._shaderParams);for(var p=this.fastMode?1:0,g=e.source,S=0;S=0;S--)v=(R=2*S)+1,A=this._pyramid[R],I=this._pyramid[v],r.setShaderDataTexture(this._shaderData,Ma.SHADERVALUE_BLOOMTEX,A),r.blitScreenTriangle(M,I,null,this._shader,this._shaderData,Ma.SUBSHADER_UPSAMPLETENT+p),M=I;var D=this._linearColor;this.color.toLinear(D);var L=Math.pow(2,this._intensity/10)-1,y=this._shaderSetting;this._shaderSetting.setValue(m,L,this._dirtIntensity,u);var C=this.dirtTexture?this.dirtTexture:t.Texture2D.blackTexture,O=C.width/C.height,N=a.width/a.height,w=this._dirtTileOffset;O>N?w.setValue(N/O,1,.5*(1-w.x),0):O0&&(a[0]=r[0]*n,a[1]=r[1]*n,a[2]=r[2]*n,a[3]=r[3]*n)}static add(e,t,r){var a=r.elements,n=e.elements,i=t.elements;a[0]=n[0]+i[0],a[1]=n[1]+i[1],a[2]=n[2]+i[2],a[3]=n[3]+i[3]}static subtract(e,t,r){var a=r.elements,n=e.elements,i=t.elements;a[0]=n[0]-i[0],a[1]=n[1]-i[1],a[2]=n[2]-i[2],a[3]=n[3]-i[3]}static multiply(e,t,r){var a=r.elements,n=e.elements,i=t.elements;a[0]=n[0]*i[0],a[1]=n[1]*i[1],a[2]=n[2]*i[2],a[3]=n[3]*i[3]}static scale(e,t,r){var a=r.elements,n=e.elements;a[0]=n[0]*t,a[1]=n[1]*t,a[2]=n[2]*t,a[3]=n[3]*t}static Clamp(e,t,r,a){var n=e.elements,i=n[0],s=n[1],o=n[2],l=n[3],h=t.elements,_=h[0],d=h[1],c=h[2],u=h[3],m=r.elements,f=m[0],E=m[1],T=m[2],p=m[3],g=a.elements;i=(i=i>f?f:i)<_?_:i,s=(s=s>E?E:s)T?T:o)p?p:l)0&&(o=1/Math.sqrt(o),a[0]=r[0]*o,a[1]=r[1]*o,a[2]=r[2]*o)}static multiply(e,t,r){var a=r.elements,n=e.elements,i=t.elements;a[0]=n[0]*i[0],a[1]=n[1]*i[1],a[2]=n[2]*i[2]}static scale(e,t,r){var a=r.elements,n=e.elements;a[0]=n[0]*t,a[1]=n[1]*t,a[2]=n[2]*t}static lerp(e,t,r,a){var n=a.elements,i=e.elements,s=t.elements,o=i[0],l=i[1],h=i[2];n[0]=o+r*(s[0]-o),n[1]=l+r*(s[1]-l),n[2]=h+r*(s[2]-h)}static transformV3ToV3(e,t,r){var a=Ca._tempVector4;Ca.transformV3ToV4(e,t,a);var n=a.elements,i=r.elements;i[0]=n[0],i[1]=n[1],i[2]=n[2]}static transformV3ToV4(e,t,r){var a=e.elements,n=a[0],i=a[1],s=a[2],o=t.elements,l=r.elements;l[0]=n*o[0]+i*o[4]+s*o[8]+o[12],l[1]=n*o[1]+i*o[5]+s*o[9]+o[13],l[2]=n*o[2]+i*o[6]+s*o[10]+o[14],l[3]=n*o[3]+i*o[7]+s*o[11]+o[15]}static TransformNormal(e,t,r){var a=e.elements,n=a[0],i=a[1],s=a[2],o=t.elements,l=r.elements;l[0]=n*o[0]+i*o[4]+s*o[8],l[1]=n*o[1]+i*o[5]+s*o[9],l[2]=n*o[2]+i*o[6]+s*o[10]}static transformCoordinate(e,t,r){var a=e.elements,n=a[0],i=a[1],s=a[2],o=t.elements,l=n*o[3]+i*o[7]+s*o[11]+o[15],h=r.elements;h[0]=n*o[0]+i*o[4]+s*o[8]+o[12]/l,h[1]=n*o[1]+i*o[5]+s*o[9]+o[13]/l,h[2]=n*o[2]+i*o[6]+s*o[10]+o[14]/l}static Clamp(e,t,r,a){var n=e.elements,i=n[0],s=n[1],o=n[2],l=t.elements,h=l[0],_=l[1],d=l[2],c=r.elements,u=c[0],m=c[1],f=c[2],E=a.elements;i=(i=i>u?u:i)m?m:s)<_?_:s,o=(o=o>f?f:o)0&&(s=1/Math.sqrt(s),t[0]=r*s,t[1]=a*s,t[2]=n*s,t[3]=i*s)}static _lerpArray(e,t,r,a){var n=1-r;Oa._dotArray(e,t)>=0?(a[0]=n*e[0]+r*t[0],a[1]=n*e[1]+r*t[1],a[2]=n*e[2]+r*t[2],a[3]=n*e[3]+r*t[3]):(a[0]=n*e[0]-r*t[0],a[1]=n*e[1]-r*t[1],a[2]=n*e[2]-r*t[2],a[3]=n*e[3]-r*t[3]),Oa._normalizeArray(a,a)}static createFromYawPitchRoll(e,t,r,a){var n=.5*r,i=.5*t,s=.5*e,o=Math.sin(n),l=Math.cos(n),h=Math.sin(i),_=Math.cos(i),d=Math.sin(s),c=Math.cos(s),u=a.elements;u[0]=c*h*l+d*_*o,u[1]=d*_*l-c*h*o,u[2]=c*_*o-d*h*l,u[3]=c*_*l+d*h*o}static multiply(e,t,r){var a=e.elements,n=t.elements,i=r.elements,s=a[0],o=a[1],l=a[2],h=a[3],_=n[0],d=n[1],c=n[2],u=n[3],m=o*c-l*d,f=l*_-s*c,E=s*d-o*_,T=s*_+o*d+l*c;i[0]=s*u+_*h+m,i[1]=o*u+d*h+f,i[2]=l*u+c*h+E,i[3]=h*u-T}static arcTanAngle(e,t){return 0==e?1==t?Math.PI/2:-Math.PI/2:e>0?Math.atan(t/e):e<0?t>0?Math.atan(t/e)+Math.PI:Math.atan(t/e)-Math.PI:0}static angleTo(e,t,r){Ca.subtract(t,e,Oa.TEMPVector30),Ca.normalize(Oa.TEMPVector30,Oa.TEMPVector30),r.elements[0]=Math.asin(Oa.TEMPVector30.y),r.elements[1]=Oa.arcTanAngle(-Oa.TEMPVector30.z,-Oa.TEMPVector30.x)}static createFromAxisAngle(e,t,r){var a=r.elements,n=e.elements;t*=.5;var i=Math.sin(t);a[0]=i*n[0],a[1]=i*n[1],a[2]=i*n[2],a[3]=Math.cos(t)}static createFromMatrix3x3(e,t){var r,a=t.elements,n=e.elements,i=n[0]+n[4]+n[8];if(i>0)r=Math.sqrt(i+1),a[3]=.5*r,r=.5/r,a[0]=(n[5]-n[7])*r,a[1]=(n[6]-n[2])*r,a[2]=(n[1]-n[3])*r;else{var s=0;n[4]>n[0]&&(s=1),n[8]>n[3*s+s]&&(s=2);var o=(s+1)%3,l=(s+2)%3;r=Math.sqrt(n[3*s+s]-n[3*o+o]-n[3*l+l]+1),a[s]=.5*r,r=.5/r,a[3]=(n[3*o+l]-n[3*l+o])*r,a[o]=(n[3*o+s]+n[3*s+o])*r,a[l]=(n[3*l+s]+n[3*s+l])*r}}static createFromMatrix4x4(e,t){var r,a,n=e.elements,i=t.elements,s=n[0]+n[5]+n[10];s>0?(r=Math.sqrt(s+1),i[3]=.5*r,r=.5/r,i[0]=(n[6]-n[9])*r,i[1]=(n[8]-n[2])*r,i[2]=(n[1]-n[4])*r):n[0]>=n[5]&&n[0]>=n[10]?(a=.5/(r=Math.sqrt(1+n[0]-n[5]-n[10])),i[0]=.5*r,i[1]=(n[1]+n[4])*a,i[2]=(n[2]+n[8])*a,i[3]=(n[6]-n[9])*a):n[5]>n[10]?(a=.5/(r=Math.sqrt(1+n[5]-n[0]-n[10])),i[0]=(n[4]+n[1])*a,i[1]=.5*r,i[2]=(n[9]+n[6])*a,i[3]=(n[8]-n[2])*a):(a=.5/(r=Math.sqrt(1+n[10]-n[0]-n[5])),i[0]=(n[8]+n[2])*a,i[1]=(n[9]+n[6])*a,i[2]=.5*r,i[3]=(n[1]-n[4])*a)}static slerp(e,t,r,a){var n,i,s,o,l,h=e.elements,_=t.elements,d=a.elements,c=h[0],u=h[1],m=h[2],f=h[3],E=_[0],T=_[1],p=_[2],g=_[3];return(i=c*E+u*T+m*p+f*g)<0&&(i=-i,E=-E,T=-T,p=-p,g=-g),1-i>1e-6?(n=Math.acos(i),s=Math.sin(n),o=Math.sin((1-r)*n)/s,l=Math.sin(r*n)/s):(o=1-r,l=r),d[0]=o*c+l*E,d[1]=o*u+l*T,d[2]=o*m+l*p,d[3]=o*f+l*g,d}static lerp(e,t,r,a){Oa._lerpArray(e.elements,t.elements,r,a.elements)}static add(e,t,r){var a=r.elements,n=e.elements,i=t.elements;a[0]=n[0]+i[0],a[1]=n[1]+i[1],a[2]=n[2]+i[2],a[3]=n[3]+i[3]}static dot(e,t){return Oa._dotArray(e.elements,t.elements)}get x(){return this.elements[0]}set x(e){this.elements[0]=e}get y(){return this.elements[1]}set y(e){this.elements[1]=e}get z(){return this.elements[2]}set z(e){this.elements[2]=e}get w(){return this.elements[3]}set w(e){this.elements[3]=e}scaling(e,t){var r=t.elements,a=this.elements;r[0]=a[0]*e,r[1]=a[1]*e,r[2]=a[2]*e,r[3]=a[3]*e}normalize(e){Oa._normalizeArray(this.elements,e.elements)}length(){var e=this.elements,t=e[0],r=e[1],a=e[2],n=e[3];return Math.sqrt(t*t+r*r+a*a+n*n)}rotateX(e,t){var r=t.elements,a=this.elements;e*=.5;var n=a[0],i=a[1],s=a[2],o=a[3],l=Math.sin(e),h=Math.cos(e);r[0]=n*h+o*l,r[1]=i*h+s*l,r[2]=s*h-i*l,r[3]=o*h-n*l}rotateY(e,t){var r=t.elements,a=this.elements;e*=.5;var n=a[0],i=a[1],s=a[2],o=a[3],l=Math.sin(e),h=Math.cos(e);r[0]=n*h-s*l,r[1]=i*h+o*l,r[2]=s*h+n*l,r[3]=o*h-i*l}rotateZ(e,t){var r=t.elements,a=this.elements;e*=.5;var n=a[0],i=a[1],s=a[2],o=a[3],l=Math.sin(e),h=Math.cos(e);r[0]=n*h+i*l,r[1]=i*h-n*l,r[2]=s*h+o*l,r[3]=o*h-s*l}getYawPitchRoll(e){Ca.transformQuat(Ca.ForwardRH,this,Oa.TEMPVector31),Ca.transformQuat(Ca.Up,this,Oa.TEMPVector32);var t=Oa.TEMPVector32.elements;Oa.angleTo(Ca.ZERO,Oa.TEMPVector31,Oa.TEMPVector33);var r=Oa.TEMPVector33.elements;r[0]==Math.PI/2?(r[1]=Oa.arcTanAngle(t[2],t[0]),r[2]=0):r[0]==-Math.PI/2?(r[1]=Oa.arcTanAngle(-t[2],-t[0]),r[2]=0):(B.createRotationY(-r[1],Oa.TEMPMatrix0),B.createRotationX(-r[0],Oa.TEMPMatrix1),Ca.transformCoordinate(Oa.TEMPVector32,Oa.TEMPMatrix0,Oa.TEMPVector32),Ca.transformCoordinate(Oa.TEMPVector32,Oa.TEMPMatrix1,Oa.TEMPVector32),r[2]=Oa.arcTanAngle(t[1],-t[0])),r[1]<=-Math.PI&&(r[1]=Math.PI),r[2]<=-Math.PI&&(r[2]=Math.PI),r[1]>=Math.PI&&r[2]>=Math.PI&&(r[1]=0,r[2]=0,r[0]=Math.PI-r[0]);var a=e.elements;a[0]=r[1],a[1]=r[0],a[2]=r[2]}invert(e){var t=e.elements,r=this.elements,a=r[0],n=r[1],i=r[2],s=r[3],o=a*a+n*n+i*i+s*s,l=o?1/o:0;t[0]=-a*l,t[1]=-n*l,t[2]=-i*l,t[3]=s*l}identity(){var e=this.elements;e[0]=0,e[1]=0,e[2]=0,e[3]=1}fromArray(e,t=0){this.elements[0]=e[t+0],this.elements[1]=e[t+1],this.elements[2]=e[t+2],this.elements[3]=e[t+3]}cloneTo(e){var t,r,a;if((r=this.elements)!==(a=e.elements))for(t=0;t<4;++t)a[t]=r[t]}clone(){var e=new Oa;return this.cloneTo(e),e}equals(e){var t=this.elements,a=e.elements;return r.nearEqual(t[0],a[0])&&r.nearEqual(t[1],a[1])&&r.nearEqual(t[2],a[2])&&r.nearEqual(t[3],a[3])}static rotationLookAt(e,t,r){Oa.lookAt(Ca.ZERO,e,t,r)}static lookAt(e,t,r,a){E.lookAt(e,t,r,Oa._tempMatrix3x3),Oa.rotationMatrix(Oa._tempMatrix3x3,a)}lengthSquared(){var e=this.elements[0],t=this.elements[1],r=this.elements[2],a=this.elements[3];return e*e+t*t+r*r+a*a}static invert(e,t){var a=e.elements,n=t.elements,i=e.lengthSquared();r.isZero(i)||(i=1/i,n[0]=-a[0]*i,n[1]=-a[1]*i,n[2]=-a[2]*i,n[3]=a[3]*i)}static rotationMatrix(e,t){var r,a,n=e.elements,i=n[0],s=n[1],o=n[2],l=n[3],h=n[4],_=n[5],d=n[6],c=n[7],u=n[8],m=t.elements,f=i+h+u;f>0?(r=Math.sqrt(f+1),m[3]=.5*r,r=.5/r,m[0]=(_-c)*r,m[1]=(d-o)*r,m[2]=(s-l)*r):i>=h&&i>=u?(a=.5/(r=Math.sqrt(1+i-h-u)),m[0]=.5*r,m[1]=(s+l)*a,m[2]=(o+d)*a,m[3]=(_-c)*a):h>u?(a=.5/(r=Math.sqrt(1+h-i-u)),m[0]=(l+s)*a,m[1]=.5*r,m[2]=(c+_)*a,m[3]=(d-o)*a):(a=.5/(r=Math.sqrt(1+u-i-h)),m[0]=(d+o)*a,m[1]=(c+_)*a,m[2]=.5*r,m[3]=(s-l)*a)}}Oa.TEMPVector30=new Ca,Oa.TEMPVector31=new Ca,Oa.TEMPVector32=new Ca,Oa.TEMPVector33=new Ca,Oa.TEMPMatrix0=new B,Oa.TEMPMatrix1=new B,Oa._tempMatrix3x3=new E,Oa.DEFAULT=new Oa,Oa.NAN=new Oa(NaN,NaN,NaN,NaN);class Na{constructor(e){if(!(e instanceof Array)||4!==e.length)throw new Error("Rand:Seed must be an array with 4 numbers");this._state0U=0|e[0],this._state0L=0|e[1],this._state1U=0|e[2],this._state1L=0|e[3]}randomint(){var e=this._state0U,t=this._state0L,r=this._state1U,a=this._state1L,n=(a>>>0)+(t>>>0),i=r+e+(n/2>>>31)>>>0,s=n>>>0;this._state0U=r,this._state0L=a;var o=0,l=0;o=(e^=o=e<<23|(-512&t)>>>9)^r,l=(t^=l=t<<23)^a;o^=e>>>18,l^=t>>>18|(262143&e)<<14;return o^=r>>>5,l^=a>>>5|(31&r)<<27,this._state1U=o,this._state1L=l,[i,s]}random(){var e=this.randomint(),t=e[0],r=1023<<20|t>>>12,a=0|(e[1]>>>12|(4095&t)<<20);return Na._CONVERTION_BUFFER.setUint32(0,r,!1),Na._CONVERTION_BUFFER.setUint32(4,a,!1),Na._CONVERTION_BUFFER.getFloat64(0,!1)-1}}Na._CONVERTION_BUFFER=new DataView(new ArrayBuffer(8)),Na.defaultRand=new Na([0,Date.now()/65536,0,Date.now()%65536]);class Pa{constructor(e,t){this._width=0,this._height=0,this._width=e,this._height=t}static get fullScreen(){return new Pa(-1,-1)}get width(){return-1===this._width?N.clientWidth:this._width}get height(){return-1===this._height?N.clientHeight:this._height}}e.AlternateLightQueue=Tt,e.AnimationClip=I,e.AnimationClipParser03=S,e.AnimationClipParser04=R,e.AnimationEvent=u,e.AnimationNode=de,e.AnimationTransform3D=_e,e.Animator=O,e.AnimatorControllerLayer=D,e.AnimatorPlayState=M,e.AnimatorState=L,e.AnimatorStateScript=class{constructor(){}onStateEnter(){}onStateUpdate(){}onStateExit(){}},e.Avatar=ce,e.AvatarMask=y,e.BaseCamera=st,e.BaseMaterial=me,e.BaseRender=Pt,e.BaseShape=xr,e.BatchMark=It,e.BlinnPhongMaterial=Ee,e.BlitScreenQuadCMD=j,e.BloomEffect=Ma,e.BoundBox=gt,e.BoundFrustum=$e,e.BoundSphere=Gt,e.Bounds=St,e.BoundsOctree=Ut,e.BoundsOctreeNode=Bt,e.BoxShape=Ir,e.BufferState=G,e.Burst=ur,e.Camera=dt,e.CameraCullInfo=Ge,e.CastShadowList=class extends Fe{constructor(){super()}add(e){if(-1!==e._indexInCastShadowList)throw"CastShadowList:element has in CastShadowList.";this._add(e),e._indexInCastShadowList=this.length++}remove(e){var t=e._indexInCastShadowList;if(this.length--,t!==this.length){var r=this.elements[this.length];this.elements[t]=r,r._indexInCastShadowList=t}e._indexInCastShadowList=-1}},e.CircleShape=Mr,e.ClearRenderTextureCMD=te,e.Cluster=Xe,e.CollisionUtils=Je,e.Color=He,e.ColorOverLifetime=fr,e.Command=q,e.CommandBuffer=oe,e.ConchQuaternion=Oa,e.ConchVector3=Ca,e.ConchVector4=ya,e.ConeShape=Dr,e.Config3D=d,e.ContainmentType=Ke,e.DefineDatas=w,e.DepthPass=_t,e.DirectionLight=ha,e.DrawMeshCMD=ee,e.DrawMeshInstancedCMD=se,e.DrawRenderCMD=re,e.DynamicBatchManager=Xt,e.EffectMaterial=Te,e.Emission=zr,e.ExtendTerrainMaterial=pe,e.FloatKeyframe=f,e.FrameOverTime=Er,e.FrustumCulling=ke,e.GeometryElement=Rt,e.Gradient=cr,e.GradientAngularVelocity=Tr,e.GradientColor=mr,e.GradientDataInt=pr,e.GradientDataNumber=gr,e.GradientDataVector2=Aa,e.GradientMode=dr,e.GradientSize=Sr,e.GradientVelocity=Rr,e.HeightMap=va,e.HemisphereShape=Lr,e.ILaya3D=h,e.IndexBuffer3D=rt,e.Input3D=ct,e.Keyframe=m,e.KeyframeNode=c,e.KeyframeNodeList=v,e.KeyframeNodeOwner=C,e.Laya3D=Sa,e.LightQueue=Et,e.LightSprite=lt,e.Lightmap=Ht,e.LoadModelV04=fa,e.LoadModelV05=Ea,e.Material=ue,e.MaterialInstanceProperty=Da,e.MaterialInstancePropertyBlock=La,e.MathUtils3D=r,e.Matrix3x3=E,e.Matrix4x4=B,e.Mesh=ia,e.MeshFilter=or,e.MeshReader=Ta,e.MeshRenderDynamicBatchManager=hr,e.MeshRenderStaticBatchManager=Ot,e.MeshRenderer=sr,e.MeshSprite3D=_r,e.MeshSprite3DShaderDeclaration=ne,e.MeshTerrainSprite3D=xa,e.MouseTouch=Ze,e.OctreeMotionList=Ft,e.PBRMaterial=ge,e.PBRSpecularMaterial=Kt,e.PBRStandardMaterial=tr,e.Physics3D=_,e.Physics3DUtils=Vr,e.Picker=tt,e.PixelLineData=class{constructor(){this.startPosition=new i,this.endPosition=new i,this.startColor=new He,this.endColor=new He}cloneTo(e){this.startPosition.cloneTo(e.startPosition),this.endPosition.cloneTo(e.endPosition),this.startColor.cloneTo(e.startColor),this.endColor.cloneTo(e.endColor)}},e.PixelLineFilter=xt,e.PixelLineMaterial=pt,e.PixelLineRenderer=wt,e.PixelLineSprite3D=bt,e.PixelLineVertex=vt,e.Plane=je,e.PointLight=_a,e.PostProcess=he,e.PostProcessEffect=Ia,e.PostProcessRenderContext=le,e.PrimitiveMesh=sa,e.Quaternion=T,e.QuaternionKeyframe=p,e.Rand=Gr,e.RandX=Na,e.Ray=Qe,e.ReflectionProbe=Nt,e.ReflectionProbeList=Yt,e.ReflectionProbeManager=Zt,e.RenderContext3D=N,e.RenderElement=Dt,e.RenderQueue=Vt,e.RenderState=fe,e.RenderTexture=P,e.RenderableSprite3D=At,e.RotationOverLifetime=vr,e.Scene3D=qt,e.Scene3DShaderDeclaration=ot,e.Scene3DUtils=ma,e.ScreenQuad=z,e.ScreenTriangle=k,e.Script3D=Ra,e.SetGlobalShaderDataCMD=ae,e.SetRenderTargetCMD=Q,e.SetShaderDataCMD=K,e.Shader3D=Z,e.ShaderData=F,e.ShaderDefine=W,e.ShaderInit3D=la,e.ShaderInstance=Be,e.ShaderPass=jt,e.ShaderVariable=Ve,e.ShaderVariant=X,e.ShaderVariantCollection=Y,e.ShadowCasterPass=Wt,e.ShadowCullInfo=ze,e.ShadowSliceData=zt,e.ShadowSpotData=kt,e.ShadowUtils=ht,e.ShapeUtils=Ar,e.ShuriKenParticle3D=Xr,e.ShuriKenParticle3DShaderDeclaration=wr,e.ShurikenParticleData=kr,e.ShurikenParticleMaterial=br,e.ShurikenParticleRenderer=Br,e.ShurikenParticleSystem=Wr,e.SimpleSingletonList=Ue,e.SimpleSkinnedMeshRenderer=ca,e.SimpleSkinnedMeshSprite3D=ua,e.SingletonList=Fe,e.Size=Pa,e.SizeOverLifetime=Cr,e.SkinnedMeshRenderer=Zr,e.SkinnedMeshSprite3D=qr,e.SkinnedMeshSprite3DShaderDeclaration=Yr,e.SkyBox=nt,e.SkyBoxMaterial=rr,e.SkyDome=mt,e.SkyMesh=at,e.SkyPanoramicMaterial=ga,e.SkyProceduralMaterial=ar,e.SkyRenderer=it,e.SphereShape=yr,e.SphericalHarmonicsL2=Ye,e.SpotLight=da,e.Sprite3D=$,e.StartFrame=Or,e.StaticBatchManager=yt,e.SubMesh=aa,e.SubMeshDynamicBatch=lr,e.SubMeshInstanceBatch=Mt,e.SubMeshRenderElement=Lt,e.SubMeshStaticBatch=Ct,e.SubShader=Qt,e.TextMesh=class{constructor(){}get text(){return this._text}set text(e){this._text=e}get fontSize(){return this._fontSize}set fontSize(e){this._fontSize=e}get color(){return this._color}set color(e){this._color=e}},e.TextureCube=ft,e.TextureGenerator=x,e.TextureMode=Qr,e.TextureSheetAnimation=Nr,e.Touch=qe,e.TrailFilter=$r,e.TrailGeometry=Jr,e.TrailMaterial=jr,e.TrailRenderer=ea,e.TrailSprite3D=ta,e.Transform3D=J,e.UnlitMaterial=nr,e.Utils3D=A,e.Vector2=a,e.Vector3=i,e.Vector3Keyframe=g,e.Vector4=n,e.VelocityOverLifetime=Pr,e.VertexBuffer3D=b,e.VertexDeclaration=U,e.VertexElement=H,e.VertexElementFormat=V,e.VertexMesh=ie,e.VertexPositionTerrain=ra,e.VertexPositionTexture0=ut,e.VertexShuriKenParticle=Fr,e.VertexShurikenParticleBillboard=Ur,e.VertexShurikenParticleMesh=Hr,e.VertexTrail=Kr,e.Viewport=et,e.WaterPrimaryMaterial=ir,e.skinnedMatrixCache=na}(window.Laya=window.Laya||{},Laya); \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/min/laya.debugtool.min.js b/examples/layaair/frontend/bin/libs/min/laya.debugtool.min.js new file mode 100644 index 0000000..0d0677d --- /dev/null +++ b/examples/layaair/frontend/bin/libs/min/laya.debugtool.min.js @@ -0,0 +1 @@ +!function(t,e){"use strict";class a{constructor(){}static toUpCase(t){return t.toUpperCase()}static toLowCase(t){return t.toLowerCase()}static toUpHead(t){return t.length<=1?t.toUpperCase():t.charAt(0).toUpperCase()+t.substr(1)}static toLowHead(t){return t.length<=1?t.toLowerCase():t.charAt(0).toLowerCase()+t.substr(1)}static packageToFolderPath(t){return t.replace(".","/")}static insert(t,e,a){return t.substring(0,a)+e+t.substr(a)}static insertAfter(t,e,i,s=!1){var l;return(l=s?t.lastIndexOf(i):t.indexOf(i))>=0?a.insert(t,e,l+i.length):t}static insertBefore(t,e,i,s=!1){var l;return(l=s?t.lastIndexOf(i):t.indexOf(i))>=0?a.insert(t,e,l):t}static insertParamToFun(t,e){var i,s;return i=a.getParamArr(t),s=e.join(","),i.length>0&&(s=","+s),a.insertBefore(t,s,")",!0)}static trim(t,e=null){var i,s,l;for(e||(e=[" ","\r","\n","\t",String.fromCharCode(65279)]),i=t,l=e.length,s=0;s=0;)e--;return t.substring(0,e),e>=0?t.substring(0,e+1):""}static trimSide(t){var e;return e=a.trimLeft(t),e=a.trimRight(e)}static isOkFileName(t){if(""==a.trimSide(t))return!1;var e,i;for(i=t.length,e=0;e=0;e--)i=t[e],i=a.trimSide(i),a.isEmpty(i)?t.splice(e,1):t[e]=i;return t}static ifNoAddToTail(t,e){return t.indexOf(e)>=0?t:t+e}static trimEmptyLine(t){var e,i,s;for(e=(i=t.split("\n")).length-1;e>=0;e--)s=i[e],a.isEmptyLine(s)&&i.splice(e,1);return i.join("\n")}static isEmptyLine(t){return""==(t=a.trim(t))}static removeCommentLine(t){var e,i,s,l,r,o;for(e=[],i=0,r=t.length;i=0)for(l=s.substring(0,o-1),a.addIfNotEmpty(e,l);i=0){l=s.substring(o+2),a.addIfNotEmpty(e,l);break}i++}else s.indexOf("//")>=0&&0==a.trim(s).indexOf("//")||a.addIfNotEmpty(e,l);i++}return e}static addIfNotEmpty(t,e){e&&(""!=a.trim(e)&&t.push(e))}static trimExt(t,e){var i,s,l;for(i=a.trim(t),l=e.length,s=0;s0&&""==t[0];)t.shift()}static getWords(t){var e=a.getSplitLine(t);return a.delelteItem(e),e}static getLinesI(t,e,a){var i,s=[];for(i=t;i<=e;i++)s.push(a[i]);return s}static structfy(t,e=4,i=!0){var s,l,r,o,n,h;for(i&&(t=a.trimEmptyLine(t)),l=0,r=a.getEmptyStr(0),n=(s=t.split("\n")).length,o=0;o=0&&(r=a.getEmptyStr(l*e)),h=r+h,s[o]=h,r=a.getEmptyStr(l*e);return s.join("\n")}static getEmptyStr(t){if(!a.emptyDic.hasOwnProperty(t)){var e,i,s;for(i=t,s="",e=0;e0||"0"==i)(a=10*a+Number(i))>0&&(l=!0);else if(l)return a;return a}static getReplace(t,e,a){return t?t.replace(new RegExp(e,"g"),a):""}static getWordCount(t,e){var a=new RegExp(e,"g");return t.match(a).length}static getResolvePath(t,e){if(a.isAbsPath(t))return t;var i,s,l,r,o,n;for(i="\\",e.indexOf("/")>=0&&(i="/"),e.charAt(e.length-1)==i&&(e=e.substr(0,e.length-1)),s=".."+i,l="."+i,r=a.getWordCount(t,s),t=a.getReplace(t,s,""),t=a.getReplace(t,l,""),n=r,o=0;o=0}static removeLastSign(t,e){var a;return a=t.lastIndexOf(e),t=t.substring(0,a)}static getParamArr(t){var e;return e=a.getBetween(t,"(",")",!0),a.trim(e).length<1?[]:e.split(",")}static copyStr(t){return t.substring(0)}static ArrayToString(t){return"[{items}]".replace(new RegExp("\\{items\\}","g"),a.getArrayItems(t))}static getArrayItems(t){var e,i,s;if(t.length<1)return"";for(e=a.parseItem(t[0]),s=t.length,i=1;i=0){for(var s,l=e.split(i.sign);l.length>1;)if(t[s=l.shift()]||(t[s]={},console.log("addKeyObj:",s)),!(t=t[s]))return void console.log("wrong flatKey:",e);t[l.shift()]=a}else t[e]=a}static clearObj(t){var e;for(e in t)delete t[e]}static copyObjFast(t){var e;return e=i.getJsonString(t),i.getObj(e)}static copyObj(t){if(t instanceof Array)return i.copyArr(t);var e,a={};for(e in t)null===t[e]||void 0===t[e]?a[e]=t[e]:t[e]instanceof Array?a[e]=i.copyArr(t[e]):t[e]instanceof Object?a[e]=i.copyObj(t[e]):a[e]=t[e];return a}static copyArr(t){var e,a,s;for(e=[],s=t.length,a=0;at.length&&(a=t.length);var i,s,l;t.length;for(t.length+=e.length,l=e.length,i=t.length-1;i>=a;i--)t[i]=t[i-l];for(s=e.length,i=0;i=0&&(i=i.replace("_$get_",""),e.push(i));return t.__proto__&&s.getObjectGetSetKeys(t.__proto__,e),e}static getObjectDisplayAbleKeys(t,e=null){e||(e=[]);for(let a in t){let i=typeof t[a];"_"!=a.charAt(0)&&this.displayTypes[i]&&e.push(a)}let a=t;for(;a;){let t=Object.getOwnPropertyDescriptors(a);for(let a in t){t[a].get&&e.push(a)}a=Object.getPrototypeOf(a)}return s.getObjectGetSetKeys(t,e),e=i.getNoSameArr(e)}static getClassName(t){return t instanceof Function?t.name:t.constructor.name}static getNodeClassAndName(t){return t?t.name?s.getClassName(t)+"("+t.name+")":s.getClassName(t):"null"}static getClassNameByClz(t){return t.name}static getClassByName(t){return window.eval(t)}static createObjByName(t){return new(s.getClassByName(t))}}s.displayTypes={boolean:!0,number:!0,string:!0};class l{constructor(){}static closeAllLog(){var t;t=l.emptyLog,e.Browser.window.console.log=t}static emptyLog(){}static traceObj(t){var e,a;for(e in l.tempArr.length=0,t)l.tempArr.push(e+":"+t[e]);return a=l.tempArr.join("\n"),console.log(a),a}static traceObjR(t){var e,a;for(e in l.tempArr.length=0,t)l.tempArr.push(t[e]+":"+e);return a=l.tempArr.join("\n"),console.log(a),a}static traceSize(t){l._debugtrace("Size: x:"+t.x+" y:"+t.y+" w:"+t.width+" h:"+t.height+" scaleX:"+t.scaleX+" scaleY:"+t.scaleY)}static traceSplit(t){console.log("---------------------"+t+"---------------------------")}static group(t){console.group(t)}static groupEnd(){console.groupEnd()}static getCallStack(t=1,e=1){var a,i;for(a=(a=l.getCallStack).caller.caller,i="";a&&t>0;)e<=0&&(i+=a+"<-",t--),a=a.caller,e--;return i}static getCallLoc(t=2){var e;try{l.Erroer.i++}catch(i){var a;e=(a=this.e.stack.replace(/Error\n/).split(/\n/))[t]?a[t].replace(/^\s+|\s+$/,""):"unknow"}return e}static traceCallStack(){var t;try{l.Erroer.i++}catch(e){t=this.e.stack}return console.log(t),t}static getPlaceHolder(t){if(!l.holderDic.hasOwnProperty(t)){var e,a;for(e="",a=0;aa?l:a,t.height=r>i?r:i}static onMouseMoveEnd(t){n.clearEvents()}static clearEvents(){e.Laya.timer.clear(null,n.onMouseMoving),e.Laya.stage.off(e.Event.MOUSE_UP,null,n.onMouseMoveEnd)}}n.preMousePoint=new e.Point,n.preTarSize=new e.Point,n.preScale=new e.Point;class h{constructor(){}static getObjectsUnderPoint(t,a,i,s=null,l=null){if(s=s||[],null!=l&&!l(t))return s;if(t.getBounds().contains(a,i)){s.push(t);var r=new e.Point;r.setTo(a,i),a=(r=t.fromParentPoint(r)).x,i=r.y;for(var o=t._children.length-1;o>-1;o--){var n=t._children[o];n instanceof e.Sprite&&h.getObjectsUnderPoint(n,a,i,s,l)}}return s}static getObjectsUnderGlobalPoint(t,a=null){var i=new e.Point;return i.setTo(e.Laya.stage.mouseX,e.Laya.stage.mouseY),t.parent&&(i=t.parent.globalToLocal(i)),h.getObjectsUnderPoint(t,i.x,i.y,null,a)}static findFirstObjectsUnderGlobalPoint(){var t,a,i;if(!(t=h.getObjectsUnderGlobalPoint(e.Laya.stage)))return null;for(a=t.length-1;a>=0;a--)if((i=t[a])&&i.numChildren<1)return i;return i}static visibleAndEnableObjFun(t){return t.visible&&t.mouseEnabled}static visibleObjFun(t){return t.visible}static getMousePoint(t){var a=new e.Point;return a.setTo(e.Laya.stage.mouseX,e.Laya.stage.mouseY),a=t.globalToLocal(a)}static isChildE(t,e){if(!t)return!1;for(;e;){if(e.parent==t)return!0;e=e.parent}return!1}static isInTree(t,e){return t==e||h.isChildE(t,e)}static setTop(t){var e;t&&t.parent&&(e=t.parent).setChildIndex(t,e.numChildren-1)}static clearItemRelativeInfo(t){t.getLayout().left="NaN",t.getLayout().right="NaN",t.getLayout().top="NaN",t.getLayout().bottom="NaN"}static swap(t,e){var a,i,s;t!=e&&(a=t.parent.getChildIndex(t),i=e.parent.getChildIndex(e),s=e.parent,t.parent.addChildAt(e,a),s.addChildAt(t,i))}static insertToTarParent(t,e,a=!1){var i,s;t&&(s=t.parent)&&(i=s.getChildIndex(t),a&&i++,h.insertToParent(s,e,i))}static insertToParent(t,e,a=-1){var i,s;if(t)for(a<0&&(a=t.numChildren),s=e.length,i=0;i=e.numChildren&&(a=e.numChildren-1),console.log("setChildIndex:"+a),e.setChildIndex(t,a))}static downDis(t){var e,a;t&&t.parent&&((a=(e=t.parent).getChildIndex(t)-1)<0&&(a=0),console.log("setChildIndex:"+a),e.setChildIndex(t,a))}static setResizeAbleEx(t){var e;(e=t.getChildByName("resizeBtn"))&&n.setResizeAble(e,t)}static setResizeAble(t){t.on(e.Event.CLICK,null,h.resizeHandler,[t])}static setDragingItem(t,a){t.on(e.Event.MOUSE_DOWN,null,h.dragingHandler,[a]),a.on(e.Event.DRAG_END,null,h.dragingEnd,[a])}static dragingHandler(t){t&&t.startDrag()}static dragingEnd(t){h.intFyDisPos(t),console.log(t.x,t.y)}static showToStage(t,a=0,i=0){var s=t.getBounds();t.x=e.Laya.stage.mouseX+a,t.y=e.Laya.stage.mouseY+i,t.x+s.width>e.Laya.stage.width&&(t.x-=s.width+a),t.y+s.height>e.Laya.stage.height&&(t.y-=s.height+i),h.intFyDisPos(t)}static intFyDisPos(t){t&&(t.x=Math.round(t.x),t.y=Math.round(t.y))}static showOnly(t,e){var a,i;for(i=t.length,a=0;ae.Laya.stage.width)return!1;for(t=0;t0,n}static adptShowKeys(t){var e;for(e=t.length-1;e>=0;e--)t[e]=a.trimSide(t[e]),t[e].length<1&&t.splice(e,1);return t}static getNodeTreeData(t,e){var a,i;return Y.adptShowKeys(e),a=Y.getPropertyDesO(t,e),i=[],Y.getTreeArr(a,i),i}static getTreeArr(t,e,a=!0){a&&e.push(t);var i,s=t.childs,l=s.length;for(i=0;i0&&(N.target=t.getChildAt(0),N.autoWork())}static showAllChild(t=null){if(t||(t=N.target),!t)return console.log("no targetAvalible"),null;N.selectedNodes=h.getAllChild(t),N.showSelected()}static showAllUnderMosue(){N.selectedNodes=h.getObjectsUnderGlobalPoint(e.Laya.stage),N.showSelected()}static showParentChain(t=null){if(t){var e;for(N.selectedNodes=[],e=t.parent;e;)N.selectedNodes.push(e),e=e.parent;N.showSelected()}}static showAllBrother(t=null){if(t||(t=N.target),!t)return console.log("no targetAvalible"),null;t.parent&&(N.selectedNodes=h.getAllChild(t.parent),N.showSelected())}static showBrother(t,e=1){if(t||(t=N.target),!t)return console.log("no targetAvalible"),null;var a,i;(a=t.parent)&&(i=a.getChildIndex(t),(i+=e)<0&&(i+=a.numChildren),i>=a.numChildren&&(i-=a.numChildren),N.target=a.getChildAt(i),N.autoWork())}static set showStatu(t){t?e.Stat.show():(e.Stat.hide(),N.clearDebugLayer())}static clearDebugLayer(){N.debugLayer.graphics&&N.debugLayer.graphics.clear()}static set target(t){N._target=t}static get target(){return N._target}static showSelected(){var t,e;if(N.autoShowSelected&&(N.selectedNodes&&!(N.selectedNodes.length<1)))for(console.log("selected:",N.selectedNodes),e=N.selectedNodes.length,N.clearDebugLayer(),t=0;t0;)N._rSpList.push(N.cmdToTypeO[a._sign]),a=a._next;return console.log("fun:",N._rSpList.join(",")),N.counter.reset(),N.addCMDs(t.graphics.cmds),N.counter.traceSelf(),N.counter.data}static addCMDs(t){W.walkArr(t,N.addCMD)}static addCMD(t){N.counter.add(t.callee)}static traceCMDR(t=null){return t||(t=N.target),t?(N.counter.reset(),W.walkTarget(t,N.getCMdCount),console.log("cmds include children"),N.counter.traceSelf(),N.counter.data):(console.log("no targetAvalible"),0)}static getCMdCount(t){return t&&t instanceof e.Sprite&&t.graphics.cmds?(N.addCMDs(t.graphics.cmds),t.graphics.cmds.length):0}static addNodeInfo(t){var e;e=t.constructor.name,N.counter.add(e)}static find(t,a=!0){var i;return i=N.findTarget(e.Laya.stage,t),N.selectedNodes=i,N.selectedNodes&&(N.target=N.selectedNodes[0]),a&&N.showSelected(),i}static findByName(t){return N.nameFilter.name=t,N.find(N.nameFilter)}static findNameStartWith(t){return N.nameFilter.name=N.getStartWithFun(t),N.find(N.nameFilter)}static findNameHas(t,e=!0){return N.nameFilter.name=N.getHasFun(t),N.find(N.nameFilter,e)}static getStartWithFun(t){return function(e){return!!e&&0==e.indexOf(t)}}static getHasFun(t){return function(e){return!!e&&e.indexOf(t)>=0}}static findTarget(t,a){var i,s,l,r=[];for(N.isFit(t,a)&&r.push(t),s=t.numChildren,i=0;i=0&&o.push(t),l=t.numChildren,i=0;it&&this._resizeBuffer(this._allocated_=t),this._length=t}get length(){return this._length}_resizeBuffer(t){try{var e=new Uint8Array(t);null!=this._u8d_&&(this._u8d_.length<=t?e.set(this._u8d_):e.set(this._u8d_.subarray(0,t))),this._u8d_=e,this._d_=new DataView(e.buffer)}catch(e){throw"Invalid typed array length:"+t}}getString(){return this.readString()}readString(){return this._rUTF(this.getUint16())}getFloat32Array(t,e){return this.readFloat32Array(t,e)}readFloat32Array(t,e){var a=t+e;a=a>this._length?this._length:a;var i=new Float32Array(this._d_.buffer.slice(t,a));return this._pos_=a,i}getUint8Array(t,e){return this.readUint8Array(t,e)}readUint8Array(t,e){var a=t+e;a=a>this._length?this._length:a;var i=new Uint8Array(this._d_.buffer.slice(t,a));return this._pos_=a,i}getInt16Array(t,e){return this.readInt16Array(t,e)}readInt16Array(t,e){var a=t+e;a=a>this._length?this._length:a;var i=new Int16Array(this._d_.buffer.slice(t,a));return this._pos_=a,i}getFloat32(){return this.readFloat32()}readFloat32(){if(this._pos_+4>this._length)throw"getFloat32 error - Out of bounds";var t=this._d_.getFloat32(this._pos_,this._xd_);return this._pos_+=4,t}getFloat64(){return this.readFloat64()}readFloat64(){if(this._pos_+8>this._length)throw"getFloat64 error - Out of bounds";var t=this._d_.getFloat64(this._pos_,this._xd_);return this._pos_+=8,t}writeFloat32(t){this._ensureWrite(this._pos_+4),this._d_.setFloat32(this._pos_,t,this._xd_),this._pos_+=4}writeFloat64(t){this._ensureWrite(this._pos_+8),this._d_.setFloat64(this._pos_,t,this._xd_),this._pos_+=8}getInt32(){return this.readInt32()}readInt32(){if(this._pos_+4>this._length)throw"getInt32 error - Out of bounds";var t=this._d_.getInt32(this._pos_,this._xd_);return this._pos_+=4,t}getUint32(){return this.readUint32()}readUint32(){if(this._pos_+4>this._length)throw"getUint32 error - Out of bounds";var t=this._d_.getUint32(this._pos_,this._xd_);return this._pos_+=4,t}writeInt32(t){this._ensureWrite(this._pos_+4),this._d_.setInt32(this._pos_,t,this._xd_),this._pos_+=4}writeUint32(t){this._ensureWrite(this._pos_+4),this._d_.setUint32(this._pos_,t,this._xd_),this._pos_+=4}getInt16(){return this.readInt16()}readInt16(){if(this._pos_+2>this._length)throw"getInt16 error - Out of bounds";var t=this._d_.getInt16(this._pos_,this._xd_);return this._pos_+=2,t}getUint16(){return this.readUint16()}readUint16(){if(this._pos_+2>this._length)throw"getUint16 error - Out of bounds";var t=this._d_.getUint16(this._pos_,this._xd_);return this._pos_+=2,t}writeUint16(t){this._ensureWrite(this._pos_+2),this._d_.setUint16(this._pos_,t,this._xd_),this._pos_+=2}writeInt16(t){this._ensureWrite(this._pos_+2),this._d_.setInt16(this._pos_,t,this._xd_),this._pos_+=2}getUint8(){return this.readUint8()}readUint8(){if(this._pos_+1>this._length)throw"getUint8 error - Out of bounds";return this._d_.getUint8(this._pos_++)}writeUint8(t){this._ensureWrite(this._pos_+1),this._d_.setUint8(this._pos_,t),this._pos_++}_getUInt8(t){return this._readUInt8(t)}_readUInt8(t){return this._d_.getUint8(t)}_getUint16(t){return this._readUint16(t)}_readUint16(t){return this._d_.getUint16(t,this._xd_)}_getMatrix(){return this._readMatrix()}_readMatrix(){return new e.Matrix(this.getFloat32(),this.getFloat32(),this.getFloat32(),this.getFloat32(),this.getFloat32(),this.getFloat32())}_rUTF(t){for(var e,a="",i=this._pos_+t,s=String.fromCharCode,l=this._u8d_;this._pos_0;)if((e=l[this._pos_])<128)a+=s(e),this._pos_++,t--;else for(i=e-128,this._pos_++,t-=i;i>0;)e=l[this._pos_++],a+=s(l[this._pos_++]<<8|e),i--;return a}get pos(){return this._pos_}set pos(t){this._pos_=t}get bytesAvailable(){return this._length-this._pos_}clear(){this._pos_=0,this.length=0}__getBuffer(){return this._d_.buffer}writeUTFBytes(t){for(var e=0,a=(t+="").length;e>6,128|63&i],this._pos_),this._pos_+=2):i<=65535?(this._ensureWrite(this._pos_+3),this._u8d_.set([224|i>>12,128|i>>6&63,128|63&i],this._pos_),this._pos_+=3):(this._ensureWrite(this._pos_+4),this._u8d_.set([240|i>>18,128|i>>12&63,128|i>>6&63,128|63&i],this._pos_),this._pos_+=4)}}writeUTFString(t){var e=this.pos;this.writeUint16(1),this.writeUTFBytes(t);var a=this.pos-e-2;this._d_.setUint16(e,a,this._xd_)}readUTFString(){return this.readUTFBytes(this.getUint16())}getUTFString(){return this.readUTFString()}readUTFBytes(t=-1){if(0===t)return"";var e=this.bytesAvailable;if(t>e)throw"readUTFBytes error - Out of bounds";return t=t>0?t:e,this._rUTF(t)}getUTFBytes(t=-1){return this.readUTFBytes(t)}writeByte(t){this._ensureWrite(this._pos_+1),this._d_.setInt8(this._pos_,t),this._pos_+=1}readByte(){if(this._pos_+1>this._length)throw"readByte error - Out of bounds";return this._d_.getInt8(this._pos_++)}getByte(){return this.readByte()}_ensureWrite(t){this._length>2],s+=f.chars[(3&a[e])<<4|a[e+1]>>4],s+=f.chars[(15&a[e+1])<<2|a[e+2]>>6],s+=f.chars[63&a[e+2]];return i%3==2?s=s.substring(0,s.length-1)+"=":i%3==1&&(s=s.substring(0,s.length-2)+"=="),s}static encodeStr(t){var e;return(e=new I).writeUTFString(t),f.encodeByte(e)}static encodeStr2(t){var e;return(e=new I).writeUTFBytes(t),f.encodeByte(e)}static encodeByte(t,e=0,a=-1){return a<0&&(a=t.length),f.encode(t.buffer.slice(e,a))}static decodeToByte(t){return new I(f.decode(t))}static decode(t){f.init();var e,a,i,s,l,r=.75*t.length,o=t.length,n=0;"="===t[t.length-1]&&(r--,"="===t[t.length-2]&&r--);var h=new ArrayBuffer(r),d=new Uint8Array(h);for(e=0;e>4,d[n++]=(15&i)<<4|s>>2,d[n++]=(3&s)<<6|63&l;return h}}f.chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",f.lookup=null;class A{constructor(){}static init(){var t;t=f.decodeToByte(A.data).readUTFBytes(),window.eval(t)}}A.data="ZnVuY3Rpb24gZGh0bWx4RXZlbnQoZSx0LGkpe2UuYWRkRXZlbnRMaXN0ZW5lcj9lLmFkZEV2ZW50TGlzdGVuZXIodCxpLCExKTplLmF0dGFjaEV2ZW50JiZlLmF0dGFjaEV2ZW50KCJvbiIrdCxpKX1mdW5jdGlvbiBkaHRtbFhUcmVlT2JqZWN0KGUsdCxpLG4pe2lmKGRodG1seEV2ZW50LmluaXRUb3VjaCYmZGh0bWx4RXZlbnQuaW5pdFRvdWNoKCksX2lzSUUpdHJ5e2RvY3VtZW50LmV4ZWNDb21tYW5kKCJCYWNrZ3JvdW5kSW1hZ2VDYWNoZSIsITEsITApfWNhdGNoKG8pe310aGlzLnBhcmVudE9iamVjdD0ib2JqZWN0IiE9dHlwZW9mIGU/ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZSk6ZSx0aGlzLnBhcmVudE9iamVjdC5zdHlsZS5vdmVyZmxvdz0iaGlkZGVuIix0aGlzLl9pdGltX2RnPSEwLHRoaXMuZGxtdHI9IiwiLHRoaXMuZHJvcExvd2VyPSExLHRoaXMuZW5hYmxlSUVJbWFnZUZpeCghMCksdGhpcy54bWxzdGF0ZT0wLHRoaXMubXl0eXBlPSJ0cmVlIix0aGlzLnNtY2hlY2s9ITAsdGhpcy53aWR0aD10LHRoaXMuaGVpZ2h0PWksdGhpcy5yb290SWQ9bix0aGlzLmNoaWxkQ2FsYz1udWxsLHRoaXMuZGVmX2ltZ194PSIxOHB4Iix0aGlzLmRlZl9pbWdfeT0iMThweCIsdGhpcy5kZWZfbGluZV9pbWdfeD0iMThweCIsdGhpcy5kZWZfbGluZV9pbWdfeT0iMjRweCIsdGhpcy5fZHJhZ2dlZD1uZXcgQXJyYXksdGhpcy5fc2VsZWN0ZWQ9bmV3IEFycmF5LHRoaXMuc3R5bGVfcG9pbnRlcj0icG9pbnRlciIsdGhpcy5fYWltZ3M9ITAsdGhpcy5odG1sY0E9IiBbIix0aGlzLmh0bWxjQj0iXSIsdGhpcy5sV2luPXdpbmRvdyx0aGlzLmNNZW51PTAsdGhpcy5tbGl0ZW1zPTAsdGhpcy5pY29uVVJMPSIiLHRoaXMuZGFkbW9kZT0wLHRoaXMuc2xvd1BhcnNlPSExLHRoaXMuYXV0b1Njcm9sbD0hMCx0aGlzLmhmTW9kZT0wLHRoaXMubm9kZUN1dD1uZXcgQXJyYXksdGhpcy5YTUxzb3VyY2U9MCx0aGlzLlhNTGxvYWRpbmdXYXJuaW5nPTAsdGhpcy5faWRwdWxsPXt9LHRoaXMuX3B1bGxTaXplPTAsdGhpcy50cmVlTGluZXNPbj0hMCx0aGlzLnRzY2hlY2s9ITEsdGhpcy50aW1nZW49ITAsdGhpcy5kcGNweT0hMSx0aGlzLl9sZF9pZD1udWxsLHRoaXMuX2R5bkRlbGV0ZUJyYW5jaGVzPXt9LHRoaXMuX29pZV9vblhMRT1bXSx0aGlzLmltUGF0aD13aW5kb3cuZGh4X2dsb2JhbEltZ1BhdGh8fCIiLHRoaXMuY2hlY2tBcnJheT1uZXcgQXJyYXkoImljb25VbmNoZWNrQWxsLmdpZiIsImljb25DaGVja0FsbC5naWYiLCJpY29uQ2hlY2tHcmF5LmdpZiIsImljb25VbmNoZWNrRGlzLmdpZiIsImljb25DaGVja0Rpcy5naWYiLCJpY29uQ2hlY2tEaXMuZ2lmIiksdGhpcy5yYWRpb0FycmF5PW5ldyBBcnJheSgicmFkaW9fb2ZmLmdpZiIsInJhZGlvX29uLmdpZiIsInJhZGlvX29uLmdpZiIsInJhZGlvX29mZi5naWYiLCJyYWRpb19vbi5naWYiLCJyYWRpb19vbi5naWYiKSx0aGlzLmxpbmVBcnJheT1uZXcgQXJyYXkoImxpbmUyLmdpZiIsImxpbmUzLmdpZiIsImxpbmU0LmdpZiIsYmxhbmtfYmFzZTY0LGJsYW5rX2Jhc2U2NCwibGluZTEuZ2lmIiksdGhpcy5taW51c0FycmF5PW5ldyBBcnJheSgibWludXMyLmdpZiIsIm1pbnVzMy5naWYiLCJtaW51czQuZ2lmIiwiZGF0YTppbWFnZS9naWY7YmFzZTY0LFIwbEdPRGxoRWdBWUFKRUNBTEd2clo2ZG5mVDA5QUFBQUNINUJBRUFBQUlBTEFBQUFBQVNBQmdBQUFJY2xJK3B5KzBQbzV5MFdoc0NEV0IzbUdYZnd3SG1oYWJxeXJaVEFRQTciLCJtaW51czUuZ2lmIiksdGhpcy5wbHVzQXJyYXk9bmV3IEFycmF5KCJwbHVzMi5naWYiLCJwbHVzMy5naWYiLCJwbHVzNC5naWYiLCJkYXRhOmltYWdlL2dpZjtiYXNlNjQsUjBsR09EbGhFZ0FZQUpFQ0FLR2duN0d2cmZUMDlBQUFBQ0g1QkFFQUFBSUFMQUFBQUFBU0FCZ0FBQUljbEkrcHkrMFBvNXkwVW5CRHlIc0NMUUZmT0U2ZGhhYnF5clpKQVFBNyIsInBsdXM1LmdpZiIpLHRoaXMuaW1hZ2VBcnJheT1uZXcgQXJyYXkoImRhdGE6aW1hZ2UvZ2lmO2Jhc2U2NCxSMGxHT0RsaEVnQVNBS0VDQUplWGw3R3ZyZi8vLy8vLy95SDVCQUVLQUFJQUxBQUFBQUFTQUJJQUFBSXpsSStwQXUyOURBaTAxamlUWFJuTm0zVEhCNDVCYUoyZXVsQm94TENTL0s2d09OODBYcHQ2citCOUhrU2FJSVdFS1EwRkFEcz0iLCJkYXRhOmltYWdlL2dpZjtiYXNlNjQsUjBsR09EbGhFZ0FTQUtFQ0FKZVhsN0d2cmYvLy8vLy8veUg1QkFFS0FBSUFMQUFBQUFBU0FCSUFBQUl6bEkrcHl3Y1BtM21oV2drQ3NqQk92VmtpbUVsRzlabENCbFhkKzJYampMS2c1R3FvZVpYcXZzT1FYSy9palVaVEtWVUZBRHM9IiwiZGF0YTppbWFnZS9naWY7YmFzZTY0LFIwbEdPRGxoRWdBU0FLRUNBSmVYbDdHdnJmLy8vLy8vL3lINUJBRUtBQUlBTEFBQUFBQVNBQklBQUFJd2xJK3B5d2NQbTNtaFdna0NzakJPdlZraW1FbEc5WmxDdVlJWTZUWXMrNmJtSERPNGlnZmREM0dOaGhlVjBWUUFBRHM9IiksdGhpcy5jdXRJbWc9bmV3IEFycmF5KDAsMCwwKSx0aGlzLmN1dEltYWdlPSJidXRfY3V0LmdpZiIsZGh4NC5fZXZlbnRhYmxlKHRoaXMpLHRoaXMuaHRtbE5vZGU9bmV3IGRodG1sWFRyZWVJdGVtT2JqZWN0KHRoaXMucm9vdElkLCIiLDAsdGhpcyksdGhpcy5odG1sTm9kZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXNbMF0uc3R5bGUuZGlzcGxheT0ibm9uZSIsdGhpcy5odG1sTm9kZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXNbMF0uY2hpbGROb2Rlc1swXS5jbGFzc05hbWU9ImhpZGRlblJvdyIsdGhpcy5hbGxUcmVlPXRoaXMuX2NyZWF0ZVNlbGYoKSx0aGlzLmFsbFRyZWUuYXBwZW5kQ2hpbGQodGhpcy5odG1sTm9kZS5odG1sTm9kZSksZGh0bWx4LiRjdXN0b21TY3JvbGwmJmRodG1seC5DdXN0b21TY3JvbGwuZW5hYmxlKHRoaXMpLF9pc0ZGJiYodGhpcy5hbGxUcmVlLmNoaWxkTm9kZXNbMF0ud2lkdGg9IjEwMCUiLHRoaXMuYWxsVHJlZS5jaGlsZE5vZGVzWzBdLnN0eWxlLm92ZXJmbG93PSJoaWRkZW4iKTt2YXIgcj10aGlzO2lmKHRoaXMuYWxsVHJlZS5vbnNlbGVjdHN0YXJ0PW5ldyBGdW5jdGlvbigicmV0dXJuIGZhbHNlOyIpLF9pc01hY09TJiYodGhpcy5hbGxUcmVlLm9uY29udGV4dG1lbnU9ZnVuY3Rpb24oZSl7cmV0dXJuIHIuX2RvQ29udENsaWNrKGV8fHdpbmRvdy5ldmVudCwhMCl9KSx0aGlzLmFsbFRyZWUub25tb3VzZWRvd249ZnVuY3Rpb24oZSl7cmV0dXJuIHIuX2RvQ29udENsaWNrKGV8fHdpbmRvdy5ldmVudCl9LHRoaXMuWE1MTG9hZGVyPXRoaXMuX3BhcnNlWE1MVHJlZSxfaXNJRSYmdGhpcy5wcmV2ZW50SUVDYXNoaW5nKCEwKSx0aGlzLnNlbGVjdGlvbkJhcj1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJESVYiKSx0aGlzLnNlbGVjdGlvbkJhci5jbGFzc05hbWU9InNlbGVjdGlvbkJhciIsdGhpcy5zZWxlY3Rpb25CYXIuaW5uZXJIVE1MPSImbmJzcDsiLHRoaXMuc2VsZWN0aW9uQmFyLnN0eWxlLmRpc3BsYXk9Im5vbmUiLHRoaXMuYWxsVHJlZS5hcHBlbmRDaGlsZCh0aGlzLnNlbGVjdGlvbkJhciksd2luZG93LmFkZEV2ZW50TGlzdGVuZXImJndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJ1bmxvYWQiLGZ1bmN0aW9uKCl7dHJ5e3IuZGVzdHJ1Y3RvcigpfWNhdGNoKGUpe319LCExKSx3aW5kb3cuYXR0YWNoRXZlbnQmJndpbmRvdy5hdHRhY2hFdmVudCgib251bmxvYWQiLGZ1bmN0aW9uKCl7dHJ5e3IuZGVzdHJ1Y3RvcigpfWNhdGNoKGUpe319KSx0aGlzLnNldEltYWdlc1BhdGg9dGhpcy5zZXRJbWFnZVBhdGgsdGhpcy5zZXRJY29uc1BhdGg9dGhpcy5zZXRJY29uUGF0aCx0aGlzLnNldFNraW4oIm1hdGVyaWFsIiksZGh0bWx4LmltYWdlX3BhdGgpe3ZhciBsPWRodG1seC5pbWFnZV9wYXRoLHM9dGhpcy5wYXJlbnRPYmplY3QuY2xhc3NOYW1lLm1hdGNoKC9kaHh0cmVlX2RoeF8oW2Etel9dKikvaSk7bnVsbCE9cyYmbnVsbCE9c1sxXSYmKGwrPSJkaHh0cmVlXyIrc1sxXSsiLyIpLHRoaXMuc2V0SW1hZ2VQYXRoKGwpfXJldHVybiB0aGlzfWZ1bmN0aW9uIGNPYmplY3QoKXtyZXR1cm4gdGhpc31mdW5jdGlvbiBkaHRtbFhUcmVlSXRlbU9iamVjdChlLHQsaSxuLG8scil7cmV0dXJuIHRoaXMuaHRtbE5vZGU9IiIsdGhpcy5hY29sb3I9IiIsdGhpcy5zY29sb3I9IiIsdGhpcy50cj0wLHRoaXMuY2hpbGRzQ291bnQ9MCx0aGlzLnRlbXBET01NPTAsdGhpcy50ZW1wRE9NVT0wLHRoaXMuZHJhZ1NwYW49MCx0aGlzLmRyYWdNb3ZlPTAsdGhpcy5zcGFuPTAsdGhpcy5jbG9zZWJsZT0xLHRoaXMuY2hpbGROb2Rlcz1uZXcgQXJyYXksdGhpcy51c2VyRGF0YT1uZXcgY09iamVjdCx0aGlzLmNoZWNrc3RhdGU9MCx0aGlzLnRyZWVOb2Q9bix0aGlzLmxhYmVsPXQsdGhpcy5wYXJlbnRPYmplY3Q9aSx0aGlzLmFjdGlvbkhhbmRsZXI9byx0aGlzLmltYWdlcz1uZXcgQXJyYXkobi5pbWFnZUFycmF5WzBdLG4uaW1hZ2VBcnJheVsxXSxuLmltYWdlQXJyYXlbMl0pLHRoaXMuaWQ9bi5fZ2xvYmFsSWRTdG9yYWdlQWRkKGUsdGhpcyksdGhpcy5odG1sTm9kZT10aGlzLnRyZWVOb2QuY2hlY2tCb3hPZmY/dGhpcy50cmVlTm9kLl9jcmVhdGVJdGVtKDEsdGhpcyxyKTp0aGlzLnRyZWVOb2QuX2NyZWF0ZUl0ZW0oMCx0aGlzLHIpLHRoaXMuaHRtbE5vZGUub2JqQmVsb25nPXRoaXMsdGhpc31mdW5jdGlvbiBqc29uUG9pbnRlcihlLHQpe3RoaXMuZD1lLHRoaXMuZHA9dH1mdW5jdGlvbiBkaHhfaW5pdF90cmVlcygpe2Zvcih2YXIgZT1kb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiZGl2IiksdD0wO3Q8ZS5sZW5ndGg7dCsrKSJkaHRtbHhUcmVlIj09ZVt0XS5jbGFzc05hbWUmJmRodG1sWFRyZWVGcm9tSFRNTChlW3RdKX12YXIgYmxhbmtfYmFzZTY0PSJkYXRhOmltYWdlL2dpZjtiYXNlNjQsUjBsR09EbGhFZ0FTQUlBQUFQLy8vLy8vL3lINUJBVVVBQUVBTEFBQUFBQVNBQklBQUFJUGpJK3B5KzBQbzV5MDJvdXozcHdYQURzPSI7InVuZGVmaW5lZCI9PXR5cGVvZiB3aW5kb3cuZGh4JiYod2luZG93LmRoeD13aW5kb3cuZGh4ND17dmVyc2lvbjoiNS4wIixza2luOm51bGwsbGFzdElkOjEsbmV3SWQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5sYXN0SWQrK30semltOntkYXRhOnt9LHN0ZXA6NSxmaXJzdDpmdW5jdGlvbigpe3JldHVybiAxMDB9LGxhc3Q6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLmZpcnN0KCk7Zm9yKHZhciB0IGluIHRoaXMuZGF0YSllPU1hdGgubWF4KGUsdGhpcy5kYXRhW3RdKTtyZXR1cm4gZX0scmVzZXJ2ZTpmdW5jdGlvbihlKXtyZXR1cm4gdGhpcy5kYXRhW2VdPXRoaXMubGFzdCgpK3RoaXMuc3RlcCx0aGlzLmRhdGFbZV19LGNsZWFyOmZ1bmN0aW9uKGUpe251bGwhPXRoaXMuZGF0YVtlXSYmKHRoaXMuZGF0YVtlXT1udWxsLGRlbGV0ZSB0aGlzLmRhdGFbZV0pfX0sczJiOmZ1bmN0aW9uKGUpe3JldHVybiJzdHJpbmciPT10eXBlb2YgZSYmKGU9ZS50b0xvd2VyQ2FzZSgpKSwxPT1lfHwxPT1lfHwidHJ1ZSI9PWV8fCIxIj09ZXx8InllcyI9PWV8fCJ5Ij09ZXx8Im9uIj09ZX0sczJqOmZ1bmN0aW9uKHMpe3ZhciBvYmo9bnVsbDtkaHg0LnRlbXA9bnVsbDt0cnl7ZXZhbCgiZGh4NC50ZW1wPSIrcyl9Y2F0Y2goZSl7ZGh4NC50ZW1wPW51bGx9cmV0dXJuIG9iaj1kaHg0LnRlbXAsZGh4NC50ZW1wPW51bGwsb2JqfSxhYnNMZWZ0OmZ1bmN0aW9uKGUpe3JldHVybiJzdHJpbmciPT10eXBlb2YgZSYmKGU9ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZSkpLHRoaXMuZ2V0T2Zmc2V0KGUpLmxlZnR9LGFic1RvcDpmdW5jdGlvbihlKXtyZXR1cm4ic3RyaW5nIj09dHlwZW9mIGUmJihlPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGUpKSx0aGlzLmdldE9mZnNldChlKS50b3B9LF9hT2ZzOmZ1bmN0aW9uKGUpe2Zvcih2YXIgdD0wLGk9MDtlOyl0Kz1wYXJzZUludChlLm9mZnNldFRvcCksaSs9cGFyc2VJbnQoZS5vZmZzZXRMZWZ0KSxlPWUub2Zmc2V0UGFyZW50O3JldHVybnt0b3A6dCxsZWZ0Oml9fSxfYU9mc1JlY3Q6ZnVuY3Rpb24oZSl7dmFyIHQ9ZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxpPWRvY3VtZW50LmJvZHksbj1kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsbz13aW5kb3cucGFnZVlPZmZzZXR8fG4uc2Nyb2xsVG9wfHxpLnNjcm9sbFRvcCxyPXdpbmRvdy5wYWdlWE9mZnNldHx8bi5zY3JvbGxMZWZ0fHxpLnNjcm9sbExlZnQsbD1uLmNsaWVudFRvcHx8aS5jbGllbnRUb3B8fDAscz1uLmNsaWVudExlZnR8fGkuY2xpZW50TGVmdHx8MCxhPXQudG9wK28tbCxkPXQubGVmdCtyLXM7cmV0dXJue3RvcDpNYXRoLnJvdW5kKGEpLGxlZnQ6TWF0aC5yb3VuZChkKX19LGdldE9mZnNldDpmdW5jdGlvbihlKXtyZXR1cm4gZS5nZXRCb3VuZGluZ0NsaWVudFJlY3Q/dGhpcy5fYU9mc1JlY3QoZSk6dGhpcy5fYU9mcyhlKX0sX2lzT2JqOmZ1bmN0aW9uKGUpe3JldHVybiBudWxsIT1lJiYib2JqZWN0Ij09dHlwZW9mIGUmJiJ1bmRlZmluZWQiPT10eXBlb2YgZS5sZW5ndGh9LF9jb3B5T2JqOmZ1bmN0aW9uKGUpe2lmKHRoaXMuX2lzT2JqKGUpKXt2YXIgdD17fTtmb3IodmFyIGkgaW4gZSl0W2ldPSJvYmplY3QiPT10eXBlb2YgZVtpXSYmbnVsbCE9ZVtpXT90aGlzLl9jb3B5T2JqKGVbaV0pOmVbaV19ZWxzZSBmb3IodmFyIHQ9W10saT0wO2k8ZS5sZW5ndGg7aSsrKXRbaV09Im9iamVjdCI9PXR5cGVvZiBlW2ldJiZudWxsIT1lW2ldP3RoaXMuX2NvcHlPYmooZVtpXSk6ZVtpXTtyZXR1cm4gdH19LHdpbmRvdy5kaHg0LmlzSUU9bmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJNU0lFIik+PTB8fG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiVHJpZGVudCIpPj0wLHdpbmRvdy5kaHg0LmlzSUU2PW51bGw9PXdpbmRvdy5YTUxIdHRwUmVxdWVzdCYmbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJNU0lFIik+PTAsd2luZG93LmRoeDQuaXNJRTc9bmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJNU0lFIDcuMCIpPj0wJiZuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoIlRyaWRlbnQiKTwwLHdpbmRvdy5kaHg0LmlzSUU4PW5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiTVNJRSA4LjAiKT49MCYmbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJUcmlkZW50Iik+PTAsd2luZG93LmRoeDQuaXNJRTk9bmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJNU0lFIDkuMCIpPj0wJiZuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoIlRyaWRlbnQiKT49MCx3aW5kb3cuZGh4NC5pc0lFMTA9bmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJNU0lFIDEwLjAiKT49MCYmbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJUcmlkZW50Iik+PTAmJjEhPXdpbmRvdy5uYXZpZ2F0b3IucG9pbnRlckVuYWJsZWQsd2luZG93LmRoeDQuaXNJRTExPW5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiVHJpZGVudCIpPj0wJiYxPT13aW5kb3cubmF2aWdhdG9yLnBvaW50ZXJFbmFibGVkLHdpbmRvdy5kaHg0LmlzRWRnZT1uYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoIkVkZ2UiKT49MCx3aW5kb3cuZGh4NC5pc09wZXJhPW5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiT3BlcmEiKT49MCx3aW5kb3cuZGh4NC5pc0Nocm9tZT1uYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoIkNocm9tZSIpPj0wJiYhd2luZG93LmRoeDQuaXNFZGdlLHdpbmRvdy5kaHg0LmlzS0hUTUw9KG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiU2FmYXJpIik+PTB8fG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiS29ucXVlcm9yIik+PTApJiYhd2luZG93LmRoeDQuaXNFZGdlLHdpbmRvdy5kaHg0LmlzRkY9bmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJGaXJlZm94Iik+PTAsd2luZG93LmRoeDQuaXNJUGFkPW5hdmlnYXRvci51c2VyQWdlbnQuc2VhcmNoKC9pUGFkL2dpKT49MCx3aW5kb3cuZGh4NC5kbmQ9e2V2czp7fSxwX2VuOih3aW5kb3cuZGh4NC5pc0lFfHx3aW5kb3cuZGh4NC5pc0VkZ2UpJiYod2luZG93Lm5hdmlnYXRvci5wb2ludGVyRW5hYmxlZHx8d2luZG93Lm5hdmlnYXRvci5tc1BvaW50ZXJFbmFibGVkKSxfbVRvdWNoOmZ1bmN0aW9uKGUpe3JldHVybiB3aW5kb3cuZGh4NC5pc0lFMTAmJmUucG9pbnRlclR5cGU9PWUuTVNQT0lOVEVSX1RZUEVfTU9VU0V8fHdpbmRvdy5kaHg0LmlzSUUxMSYmIm1vdXNlIj09ZS5wb2ludGVyVHlwZXx8d2luZG93LmRoeDQuaXNFZGdlJiYibW91c2UiPT1lLnBvaW50ZXJUeXBlfSxfdG91Y2hPbjpmdW5jdGlvbihlKXtudWxsPT1lJiYoZT1kb2N1bWVudC5ib2R5KSxlLnN0eWxlLnRvdWNoQWN0aW9uPWUuc3R5bGUubXNUb3VjaEFjdGlvbj0iIixlPW51bGx9LF90b3VjaE9mZjpmdW5jdGlvbihlKXtudWxsPT1lJiYoZT1kb2N1bWVudC5ib2R5KSxlLnN0eWxlLnRvdWNoQWN0aW9uPWUuc3R5bGUubXNUb3VjaEFjdGlvbj0ibm9uZSIsZT1udWxsfX0sMT09d2luZG93Lm5hdmlnYXRvci5wb2ludGVyRW5hYmxlZD93aW5kb3cuZGh4NC5kbmQuZXZzPXtzdGFydDoicG9pbnRlcmRvd24iLG1vdmU6InBvaW50ZXJtb3ZlIixlbmQ6InBvaW50ZXJ1cCJ9OjE9PXdpbmRvdy5uYXZpZ2F0b3IubXNQb2ludGVyRW5hYmxlZD93aW5kb3cuZGh4NC5kbmQuZXZzPXtzdGFydDoiTVNQb2ludGVyRG93biIsbW92ZToiTVNQb2ludGVyTW92ZSIsZW5kOiJNU1BvaW50ZXJVcCJ9OiJ1bmRlZmluZWQiIT10eXBlb2Ygd2luZG93LmFkZEV2ZW50TGlzdGVuZXImJih3aW5kb3cuZGh4NC5kbmQuZXZzPXtzdGFydDoidG91Y2hzdGFydCIsbW92ZToidG91Y2htb3ZlIixlbmQ6InRvdWNoZW5kIn0pKSwidW5kZWZpbmVkIj09dHlwZW9mIHdpbmRvdy5kaHg0Ll9ldmVudGFibGUmJih3aW5kb3cuZGh4NC5fZXZlbnRhYmxlPWZ1bmN0aW9uKGUsdCl7cmV0dXJuImNsZWFyIj09dD8oZS5kZXRhY2hBbGxFdmVudHMoKSxlLmRoeGV2cz1udWxsLGUuYXR0YWNoRXZlbnQ9bnVsbCxlLmRldGFjaEV2ZW50PW51bGwsZS5jaGVja0V2ZW50PW51bGwsZS5jYWxsRXZlbnQ9bnVsbCxlLmRldGFjaEFsbEV2ZW50cz1udWxsLGU9bnVsbCx2b2lkIDApOihlLmRoeGV2cz17ZGF0YTp7fX0sZS5hdHRhY2hFdmVudD1mdW5jdGlvbihlLHQpe2U9U3RyaW5nKGUpLnRvTG93ZXJDYXNlKCksdGhpcy5kaHhldnMuZGF0YVtlXXx8KHRoaXMuZGh4ZXZzLmRhdGFbZV09e30pO3ZhciBpPXdpbmRvdy5kaHg0Lm5ld0lkKCk7cmV0dXJuIHRoaXMuZGh4ZXZzLmRhdGFbZV1baV09dCxpfSxlLmRldGFjaEV2ZW50PWZ1bmN0aW9uKGUpe2Zvcih2YXIgdCBpbiB0aGlzLmRoeGV2cy5kYXRhKXt2YXIgaT0wO2Zvcih2YXIgbiBpbiB0aGlzLmRoeGV2cy5kYXRhW3RdKW49PWU/KHRoaXMuZGh4ZXZzLmRhdGFbdF1bbl09bnVsbCxkZWxldGUgdGhpcy5kaHhldnMuZGF0YVt0XVtuXSk6aSsrOzA9PWkmJih0aGlzLmRoeGV2cy5kYXRhW3RdPW51bGwsZGVsZXRlIHRoaXMuZGh4ZXZzLmRhdGFbdF0pfX0sZS5jaGVja0V2ZW50PWZ1bmN0aW9uKGUpe3JldHVybiBlPVN0cmluZyhlKS50b0xvd2VyQ2FzZSgpLG51bGwhPXRoaXMuZGh4ZXZzLmRhdGFbZV19LGUuY2FsbEV2ZW50PWZ1bmN0aW9uKGUsdCl7aWYoZT1TdHJpbmcoZSkudG9Mb3dlckNhc2UoKSxudWxsPT10aGlzLmRoeGV2cy5kYXRhW2VdKXJldHVybiEwO3ZhciBpPSEwO2Zvcih2YXIgbiBpbiB0aGlzLmRoeGV2cy5kYXRhW2VdKWk9dGhpcy5kaHhldnMuZGF0YVtlXVtuXS5hcHBseSh0aGlzLHQpJiZpO3JldHVybiBpfSxlLmRldGFjaEFsbEV2ZW50cz1mdW5jdGlvbigpe2Zvcih2YXIgZSBpbiB0aGlzLmRoeGV2cy5kYXRhKXtmb3IodmFyIHQgaW4gdGhpcy5kaHhldnMuZGF0YVtlXSl0aGlzLmRoeGV2cy5kYXRhW2VdW3RdPW51bGwsZGVsZXRlIHRoaXMuZGh4ZXZzLmRhdGFbZV1bdF07dGhpcy5kaHhldnMuZGF0YVtlXT1udWxsLGRlbGV0ZSB0aGlzLmRoeGV2cy5kYXRhW2VdfX0sZT1udWxsLHZvaWQgMCl9LGRoeDQuX2V2ZW50YWJsZShkaHg0KSksInVuZGVmaW5lZCI9PXR5cGVvZiB3aW5kb3cuZGh0bWx4JiYod2luZG93LmRodG1seD17ZXh0ZW5kOmZ1bmN0aW9uKGUsdCl7Zm9yKHZhciBpIGluIHQpZVtpXXx8KGVbaV09dFtpXSk7cmV0dXJuIGV9LGV4dGVuZF9hcGk6ZnVuY3Rpb24oZSx0LGkpe3ZhciBuPXdpbmRvd1tlXTtuJiYod2luZG93W2VdPWZ1bmN0aW9uKGUpe2lmKGUmJiJvYmplY3QiPT10eXBlb2YgZSYmIWUudGFnTmFtZSl7dmFyIGk9bi5hcHBseSh0aGlzLHQuX2luaXQ/dC5faW5pdChlKTphcmd1bWVudHMpO2Zvcih2YXIgbyBpbiBkaHRtbHgpdFtvXSYmdGhpc1t0W29dXShkaHRtbHhbb10pO2Zvcih2YXIgbyBpbiBlKXRbb10/dGhpc1t0W29dXShlW29dKTowPT09by5pbmRleE9mKCJvbiIpJiZ0aGlzLmF0dGFjaEV2ZW50KG8sZVtvXSl9ZWxzZSB2YXIgaT1uLmFwcGx5KHRoaXMsYXJndW1lbnRzKTtyZXR1cm4gdC5fcGF0Y2gmJnQuX3BhdGNoKHRoaXMpLGl8fHRoaXN9LHdpbmRvd1tlXS5wcm90b3R5cGU9bi5wcm90b3R5cGUsaSYmZGh0bWx4LmV4dGVuZCh3aW5kb3dbZV0ucHJvdG90eXBlLGkpKX0sdXJsOmZ1bmN0aW9uKGUpe3JldHVybi0xIT1lLmluZGV4T2YoIj8iKT8iJiI6Ij8ifX0pLF9pc0ZGPSExLF9pc0lFPSExLF9pc09wZXJhPSExLF9pc0tIVE1MPSExLF9pc01hY09TPSExLF9pc0Nocm9tZT0hMSxfRkZydj0hMSxfS0hUTUxydj0hMSxfT3BlcmFSdj0hMSwtMSE9bmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJNYWNpbnRvc2giKSYmKF9pc01hY09TPSEwKSxuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkuaW5kZXhPZigiY2hyb21lIik+LTEmJihfaXNDaHJvbWU9ITApLC0xIT1uYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoIlNhZmFyaSIpfHwtMSE9bmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCJLb25xdWVyb3IiKT8oX0tIVE1McnY9cGFyc2VGbG9hdChuYXZpZ2F0b3IudXNlckFnZW50LnN1YnN0cihuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoIlNhZmFyaSIpKzcsNSkpLF9LSFRNTHJ2PjUyNT8oX2lzRkY9ITAsX0ZGcnY9MS45KTpfaXNLSFRNTD0hMCk6LTEhPW5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiT3BlcmEiKT8oX2lzT3BlcmE9ITAsX09wZXJhUnY9cGFyc2VGbG9hdChuYXZpZ2F0b3IudXNlckFnZW50LnN1YnN0cihuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoIk9wZXJhIikrNiwzKSkpOi0xIT1uYXZpZ2F0b3IuYXBwTmFtZS5pbmRleE9mKCJNaWNyb3NvZnQiKT8oX2lzSUU9ITAsKC0xIT1uYXZpZ2F0b3IuYXBwVmVyc2lvbi5pbmRleE9mKCJNU0lFIDguMCIpfHwtMSE9bmF2aWdhdG9yLmFwcFZlcnNpb24uaW5kZXhPZigiTVNJRSA5LjAiKXx8LTEhPW5hdmlnYXRvci5hcHBWZXJzaW9uLmluZGV4T2YoIk1TSUUgMTAuMCIpfHxkb2N1bWVudC5kb2N1bWVudE1vZGU+NykmJiJCYWNrQ29tcGF0IiE9ZG9jdW1lbnQuY29tcGF0TW9kZSYmKF9pc0lFPTgpKToiTmV0c2NhcGUiPT1uYXZpZ2F0b3IuYXBwTmFtZSYmLTEhPW5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZigiVHJpZGVudCIpP19pc0lFPTg6KF9pc0ZGPSEwLF9GRnJ2PXBhcnNlRmxvYXQobmF2aWdhdG9yLnVzZXJBZ2VudC5zcGxpdCgicnY6IilbMV0pKSwidW5kZWZpbmVkIj09dHlwZW9mIHdpbmRvdy5kaHRtbHhFdmVudCxudWxsPT1kaHRtbHhFdmVudC50b3VjaERlbGF5JiYoZGh0bWx4RXZlbnQudG91Y2hEZWxheT0yZTMpLCJ1bmRlZmluZWQiPT10eXBlb2YgZGh0bWx4RXZlbnQuaW5pdFRvdWNoJiYoZGh0bWx4RXZlbnQuaW5pdFRvdWNoPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gZSgpe2lmKGkpe3ZhciBlPWRvY3VtZW50LmNyZWF0ZUV2ZW50KCJIVE1MRXZlbnRzIik7ZS5pbml0RXZlbnQoImRibGNsaWNrIiwhMCwhMCksaS5kaXNwYXRjaEV2ZW50KGUpLHQ9aT1udWxsfX12YXIgdCxpLG4sbztkaHRtbHhFdmVudChkb2N1bWVudC5ib2R5LCJ0b3VjaHN0YXJ0IixmdW5jdGlvbihyKXtpPXIudG91Y2hlc1swXS50YXJnZXQsbj1yLnRvdWNoZXNbMF0uY2xpZW50WCxvPXIudG91Y2hlc1swXS5jbGllbnRZLHQ9d2luZG93LnNldFRpbWVvdXQoZSxkaHRtbHhFdmVudC50b3VjaERlbGF5KX0pLGRodG1seEV2ZW50KGRvY3VtZW50LmJvZHksInRvdWNobW92ZSIsZnVuY3Rpb24oZSl7dCYmKE1hdGguYWJzKGUudG91Y2hlc1swXS5jbGllbnRYLW4pPjUwfHxNYXRoLmFicyhlLnRvdWNoZXNbMF0uY2xpZW50WS1vKT41MCkmJih3aW5kb3cuY2xlYXJUaW1lb3V0KHQpLHQ9aT0hMSl9KSxkaHRtbHhFdmVudChkb2N1bWVudC5ib2R5LCJ0b3VjaGVuZCIsZnVuY3Rpb24oKXt0JiYod2luZG93LmNsZWFyVGltZW91dCh0KSx0PWk9ITEpfSksZGh0bWx4RXZlbnQuaW5pdFRvdWNoPWZ1bmN0aW9uKCl7fX0pLGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl9kb0NvbnRDbGljaz1mdW5jdGlvbihlLHQpe2lmKCF0JiYyIT1lLmJ1dHRvbilyZXR1cm4gdGhpcy5fYWNNZW51JiYodGhpcy5fYWNNZW51LmhpZGVDb250ZXh0TWVudT90aGlzLl9hY01lbnUuaGlkZUNvbnRleHRNZW51KCk6dGhpcy5jTWVudS5fY29udGV4dEVuZCgpKSwhMDtmb3IodmFyIGk9X2lzSUU/ZS5zcmNFbGVtZW50OmUudGFyZ2V0O2kmJiJCT0RZIiE9aS50YWdOYW1lJiYhaS5wYXJlbnRPYmplY3Q7KWk9aS5wYXJlbnROb2RlO2lmKCFpfHwhaS5wYXJlbnRPYmplY3QpcmV0dXJuITA7dmFyIG49aS5wYXJlbnRPYmplY3Q7aWYodGhpcy5jYWxsRXZlbnQoIm9uUmlnaHRDbGljayIsW24uaWQsZV0pfHwoKGUuc3JjRWxlbWVudHx8ZS50YXJnZXQpLm9uY29udGV4dG1lbnU9ZnVuY3Rpb24oZSl7cmV0dXJuKGV8fGV2ZW50KS5jYW5jZWxCdWJibGU9ITAsITF9KSx0aGlzLl9hY01lbnU9bi5jTWVudXx8dGhpcy5jTWVudSx0aGlzLl9hY01lbnUpe2lmKCF0aGlzLmNhbGxFdmVudCgib25CZWZvcmVDb250ZXh0TWVudSIsW24uaWRdKSlyZXR1cm4hMDtpZihfaXNNYWNPU3x8KChlLnNyY0VsZW1lbnR8fGUudGFyZ2V0KS5vbmNvbnRleHRtZW51PWZ1bmN0aW9uKGUpe3JldHVybihlfHxldmVudCkuY2FuY2VsQnViYmxlPSEwLCExfSksdGhpcy5fYWNNZW51LnNob3dDb250ZXh0TWVudSl7dmFyIG89d2luZG93LmRvY3VtZW50LmRvY3VtZW50RWxlbWVudCxyPXdpbmRvdy5kb2N1bWVudC5ib2R5LGw9bmV3IEFycmF5KG8uc2Nyb2xsTGVmdHx8ci5zY3JvbGxMZWZ0LG8uc2Nyb2xsVG9wfHxyLnNjcm9sbFRvcCk7aWYoX2lzSUUpdmFyIHM9ZS5jbGllbnRYK2xbMF0sYT1lLmNsaWVudFkrbFsxXTtlbHNlIHZhciBzPWUucGFnZVgsYT1lLnBhZ2VZO3RoaXMuX2FjTWVudS5zaG93Q29udGV4dE1lbnUocy0xLGEtMSksdGhpcy5jb250ZXh0SUQ9bi5pZCxlLmNhbmNlbEJ1YmJsZT0hMCx0aGlzLl9hY01lbnUuX3NraXBfaGlkZT0hMH1lbHNlIGkuY29udGV4dE1lbnVJZD1uLmlkLGkuY29udGV4dE1lbnU9dGhpcy5fYWNNZW51LGkuYT10aGlzLl9hY01lbnUuX2NvbnRleHRTdGFydCxpLmEoaSxlKSxpLmE9bnVsbDtyZXR1cm4hMX1yZXR1cm4hMH0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuZW5hYmxlSUVJbWFnZUZpeD1mdW5jdGlvbihlKXtlPyh0aGlzLl9nZXRJbWc9ZnVuY3Rpb24oKXt2YXIgZT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJESVYiKTtyZXR1cm4gZS5pbm5lckhUTUw9IiZuYnNwOyIsZS5jbGFzc05hbWU9ImRoeF9iZ19pbWdfZml4IixlfSx0aGlzLl9zZXRTcmM9ZnVuY3Rpb24oZSx0KXtlLnN0eWxlLmJhY2tncm91bmRJbWFnZT0idXJsKCIrdCsiKSJ9LHRoaXMuX2dldFNyYz1mdW5jdGlvbihlKXt2YXIgdD1lLnN0eWxlLmJhY2tncm91bmRJbWFnZTtyZXR1cm4gdC5zdWJzdHIoNCx0Lmxlbmd0aC01KS5yZXBsYWNlKC8oXiIpfCgiJCkvZywiIil9KToodGhpcy5fZ2V0SW1nPWZ1bmN0aW9uKGUpe3JldHVybiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGU9PXRoaXMucm9vdElkPyJkaXYiOiJpbWciKX0sdGhpcy5fc2V0U3JjPWZ1bmN0aW9uKGUsdCl7ZS5zcmM9dH0sdGhpcy5fZ2V0U3JjPWZ1bmN0aW9uKGUpe3JldHVybiBlLnNyY30pfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5kZXN0cnVjdG9yPWZ1bmN0aW9uKCl7Zm9yKHZhciBlIGluIHRoaXMuX2lkcHVsbCl7dmFyIHQ9dGhpcy5faWRwdWxsW2VdO3QmJih0LnBhcmVudE9iamVjdD1udWxsLHQudHJlZU5vZD1udWxsLHQuY2hpbGROb2Rlcz1udWxsLHQuc3Bhbj1udWxsLHQudHIubm9kZW09bnVsbCx0LnRyPW51bGwsdC5odG1sTm9kZS5vYmpCZWxvbmc9bnVsbCx0Lmh0bWxOb2RlPW51bGwsdGhpcy5faWRwdWxsW2VdPW51bGwpfXRoaXMucGFyZW50T2JqZWN0LmlubmVySFRNTD0iIix0aGlzLmFsbFRyZWUub25zZWxlY3RzdGFydD1udWxsLHRoaXMuYWxsVHJlZS5vbmNvbnRleHRtZW51PW51bGwsdGhpcy5hbGxUcmVlLm9ubW91c2Vkb3duPW51bGw7Zm9yKHZhciBlIGluIHRoaXMpdGhpc1tlXT1udWxsfSxjT2JqZWN0LnByb3RvdHlwZT1uZXcgT2JqZWN0LGNPYmplY3QucHJvdG90eXBlLmNsb25lPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gZSgpe31yZXR1cm4gZS5wcm90b3R5cGU9dGhpcyxuZXcgZX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX2dsb2JhbElkU3RvcmFnZUFkZD1mdW5jdGlvbihlLHQpe3JldHVybiB0aGlzLl9nbG9iYWxJZFN0b3JhZ2VGaW5kKGUsMSwxKT8oZT1lKyJfIisobmV3IERhdGUpLnZhbHVlT2YoKSx0aGlzLl9nbG9iYWxJZFN0b3JhZ2VBZGQoZSx0KSk6KHRoaXMuX2lkcHVsbFtlXT10LHRoaXMuX3B1bGxTaXplKyssZSl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl9nbG9iYWxJZFN0b3JhZ2VTdWI9ZnVuY3Rpb24oZSl7dGhpcy5faWRwdWxsW2VdJiYodGhpcy5fdW5zZWxlY3RJdGVtKHRoaXMuX2lkcHVsbFtlXSksdGhpcy5faWRwdWxsW2VdPW51bGwsdGhpcy5fcHVsbFNpemUtLSksdGhpcy5fbG9ja2VyJiZ0aGlzLl9sb2NrZXJbZV0mJih0aGlzLl9sb2NrZXJbZV09ITEpfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5fZ2xvYmFsSWRTdG9yYWdlRmluZD1mdW5jdGlvbihlLHQsaSxuKXt2YXIgbz10aGlzLl9pZHB1bGxbZV07aWYobyl7aWYoby51blBhcnNlZCYmIWkmJnRoaXMucmVQYXJzZShvLDApLHRoaXMuX3NybmQmJiFvLmh0bWxOb2RlJiZ0aGlzLl9idWlsZFNSTkQobyxpKSxuJiZ0aGlzLl9lZHNicHNBKWZvcih2YXIgcj0wO3I8dGhpcy5fZWRzYnBzQS5sZW5ndGg7cisrKWlmKHRoaXMuX2Vkc2Jwc0Fbcl1bMl09PWUpcmV0dXJuIGRoeDQuY2FsbEV2ZW50KCJvbmdldEl0ZW1FcnJvciIsWyJSZXF1ZXN0ZWQgaXRlbSBzdGlsbCBpbiBwYXJzaW5nIHByb2Nlc3MuIixlXSksbnVsbDtyZXR1cm4gb31yZXR1cm4gdGhpcy5zbG93UGFyc2UmJjAhPWUmJiF0P3RoaXMucHJlUGFyc2UoZSk6bnVsbH0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX2RyYXdOZXdUcj1mdW5jdGlvbihlKXt2YXIgdD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJ0ciIpLGk9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGQiKSxuPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInRkIik7cmV0dXJuIGkuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoIiAiKSksbi5jb2xTcGFuPTMsbi5hcHBlbmRDaGlsZChlKSx0LmFwcGVuZENoaWxkKGkpLHQuYXBwZW5kQ2hpbGQobiksdH0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUucGFyc2U9ZnVuY3Rpb24oZSx0LGkpe2lmKCJzdHJpbmciPT10eXBlb2YgdCYmKGk9dCx0PW51bGwpLCJqc29uIj09PWkpcmV0dXJuIHRoaXMuX2xvYWRKU09OT2JqZWN0KGUsdCk7aWYoImNzdiI9PT1pKXJldHVybiB0aGlzLl9sb2FkQ1NWU3RyaW5nKGUsdCk7aWYoImpzYXJyYXkiPT09aSlyZXR1cm4gdGhpcy5fbG9hZEpTQXJyYXkoZSx0KTt2YXIgbj10aGlzO3RoaXMucGFyc0NvdW50fHx0aGlzLmNhbGxFdmVudCgib25YTFMiLFtuLG51bGxdKSx0aGlzLnhtbHN0YXRlPTEsdGhpcy5YTUxMb2FkZXIoe3Jlc3BvbnNlWE1MOmRoeDQuYWpheC5wYXJzZShlKX0sdCl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl9hdHRhY2hDaGlsZE5vZGU9ZnVuY3Rpb24oZSx0LGksbixvLHIsbCxzLGEsZCxoKXtkJiZkLnBhcmVudE9iamVjdCYmKGU9ZC5wYXJlbnRPYmplY3QpLDA9PWUuWE1MbG9hZCYmdGhpcy5YTUxzb3VyY2UmJiF0aGlzLlhNTGxvYWRpbmdXYXJuaW5nJiYoZS5YTUxsb2FkPTEsdGhpcy5fbG9hZER5blhNTChlLmlkKSk7dmFyIGM9ZS5jaGlsZHNDb3VudCx1PWUuY2hpbGROb2RlcztpZihoJiZoLnRyLnByZXZpb3VzU2libGluZyYmKGgudHIucHJldmlvdXNTaWJsaW5nLnByZXZpb3VzU2libGluZz9kPWgudHIucHJldmlvdXNTaWJsaW5nLm5vZGVtOnM9cy5yZXBsYWNlKCJUT1AiLCIiKSsiLFRPUCIpLGQpe3ZhciBwLF87Zm9yKHA9MDtjPnA7cCsrKWlmKHVbcF09PWQpe2ZvcihfPWM7XyE9cDtfLS0pdVsxK19dPXVbX107YnJlYWt9cCsrLGM9cH1pZihzKWZvcih2YXIgbT1zLnNwbGl0KCIsIiksZz0wO2c8bS5sZW5ndGg7ZysrKXN3aXRjaChtW2ddKXtjYXNlIlRPUCI6Zm9yKGUuY2hpbGRzQ291bnQ+MCYmKGQ9bmV3IE9iamVjdCxkLnRyPWUuY2hpbGROb2Rlc1swXS50ci5wcmV2aW91c1NpYmxpbmcpLGUuX2hhc190b3A9ITAscD1jO3A+MDtwLS0pdVtwXT11W3AtMV07Yz0wfXZhciBmOyhmPXRoaXMuX2lkcHVsbFt0XSkmJi0xPT1mLnNwYW58fChmPXVbY109bmV3IGRodG1sWFRyZWVJdGVtT2JqZWN0KHQsaSxlLHRoaXMsbiwxKSx0PXVbY10uaWQsZS5jaGlsZHNDb3VudCsrKSxmLmh0bWxOb2RlfHwoZi5sYWJlbD1pLGYuaHRtbE5vZGU9dGhpcy5fY3JlYXRlSXRlbSh0aGlzLmNoZWNrQm94T2ZmPzE6MCxmKSxmLmh0bWxOb2RlLm9iakJlbG9uZz1mKSxvJiYoZi5pbWFnZXNbMF09byksciYmKGYuaW1hZ2VzWzFdPXIpLGwmJihmLmltYWdlc1syXT1sKTt2YXIgYj10aGlzLl9kcmF3TmV3VHIoZi5odG1sTm9kZSk7aWYoKHRoaXMuWE1MbG9hZGluZ1dhcm5pbmd8fHRoaXMuX2hBZEkpJiYoZi5odG1sTm9kZS5wYXJlbnROb2RlLnBhcmVudE5vZGUuc3R5bGUuZGlzcGxheT0ibm9uZSIpLGQmJmQudHImJmQudHIubmV4dFNpYmxpbmc/ZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmluc2VydEJlZm9yZShiLGQudHIubmV4dFNpYmxpbmcpOnRoaXMucGFyc2luZ09uPT1lLmlkP3RoaXMucGFyc2VkQXJyYXlbdGhpcy5wYXJzZWRBcnJheS5sZW5ndGhdPWI6ZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmFwcGVuZENoaWxkKGIpLGQmJiFkLnNwYW4mJihkPW51bGwpLHRoaXMuWE1Mc291cmNlJiYoZi5YTUxsb2FkPWEmJjAhPWE/MDoxKSxmLnRyPWIsYi5ub2RlbT1mLDA9PWUuaXRlbUlkJiYoYi5jaGlsZE5vZGVzWzBdLmNsYXNzTmFtZT0iaGlkZGVuUm93IiksKGUuX3JfbG9naWN8fHRoaXMuX2ZyYnRyKSYmdGhpcy5fc2V0U3JjKGYuaHRtbE5vZGUuY2hpbGROb2Rlc1swXS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXNbMV0uY2hpbGROb2Rlc1swXSx0aGlzLmltUGF0aCt0aGlzLnJhZGlvQXJyYXlbMF0pLHMpZm9yKHZhciBtPXMuc3BsaXQoIiwiKSxnPTA7ZzxtLmxlbmd0aDtnKyspc3dpdGNoKG1bZ10pe2Nhc2UiU0VMRUNUIjp0aGlzLnNlbGVjdEl0ZW0odCwhMSk7YnJlYWs7Y2FzZSJDQUxMIjp0aGlzLnNlbGVjdEl0ZW0odCwhMCk7YnJlYWs7Y2FzZSJDSElMRCI6Zi5YTUxsb2FkPTA7YnJlYWs7Y2FzZSJDSEVDS0VEIjp0aGlzLlhNTGxvYWRpbmdXYXJuaW5nP3RoaXMuc2V0Q2hlY2tMaXN0Kz10aGlzLmRsbXRyK3Q6dGhpcy5zZXRDaGVjayh0LDEpO2JyZWFrO2Nhc2UiSENIRUNLRUQiOnRoaXMuX3NldENoZWNrKGYsInVuc3VyZSIpO2JyZWFrO2Nhc2UiT1BFTiI6Zi5vcGVuTWU9MX1pZighdGhpcy5YTUxsb2FkaW5nV2FybmluZyYmKHRoaXMuX2dldE9wZW5TdGF0ZShlKTwwJiYhdGhpcy5faEFkSSYmdGhpcy5vcGVuSXRlbShlLmlkKSxkJiYodGhpcy5fY29ycmVjdFBsdXMoZCksdGhpcy5fY29ycmVjdExpbmUoZCkpLHRoaXMuX2NvcnJlY3RQbHVzKGUpLHRoaXMuX2NvcnJlY3RMaW5lKGUpLHRoaXMuX2NvcnJlY3RQbHVzKGYpLGUuY2hpbGRzQ291bnQ+PTImJih0aGlzLl9jb3JyZWN0UGx1cyh1W2UuY2hpbGRzQ291bnQtMl0pLHRoaXMuX2NvcnJlY3RMaW5lKHVbZS5jaGlsZHNDb3VudC0yXSkpLDIhPWUuY2hpbGRzQ291bnQmJnRoaXMuX2NvcnJlY3RQbHVzKHVbMF0pLHRoaXMudHNjaGVjayYmdGhpcy5fY29ycmVjdENoZWNrU3RhdGVzKGUpLHRoaXMuX29ucmFkaCkpaWYoMT09dGhpcy54bWxzdGF0ZSl7dmFyIHY9dGhpcy5vblhMRTt0aGlzLm9uWExFPWZ1bmN0aW9uKGUpe3RoaXMuX29ucmFkaCh0KSx2JiZ2KGUpfX1lbHNlIHRoaXMuX29ucmFkaCh0KTtyZXR1cm4gZn0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX3BhcnNlSXRlbT1mdW5jdGlvbihlLHQsaSxuKXt2YXIgbztpZih0aGlzLl9zcm5kJiYoIXRoaXMuX2lkcHVsbFtvPWUuZ2V0KCJpZCIpXXx8IXRoaXMuX2lkcHVsbFtvXS5zcGFuKSlyZXR1cm4gdGhpcy5fYWRkSXRlbVNSTkQodC5pZCxvLGUpLHZvaWQgMDt2YXIgcj1lLmdldF9hbGwoKTtpZigib2JqZWN0Ij09dHlwZW9mIHRoaXMud2FpdFVwZGF0ZVhNTCYmIXRoaXMud2FpdFVwZGF0ZVhNTFtyLmlkXSlyZXR1cm4gdGhpcy5fcGFyc2UoZSxyLmlkLDEpLHZvaWQgMDsobnVsbD09PXIudGV4dHx8InVuZGVmaW5lZCI9PXR5cGVvZiByLnRleHQpJiYoci50ZXh0PWUuc3ViKCJpdGVtdGV4dCIpLHIudGV4dCYmKHIudGV4dD1yLnRleHQuY29udGVudCgpKSk7dmFyIGw9W107aWYoci5zZWxlY3QmJmwucHVzaCgiU0VMRUNUIiksci50b3AmJmwucHVzaCgiVE9QIiksci5jYWxsJiYodGhpcy5ub2RlQXNraW5nQ2FsbD1yLmlkKSwtMT09ci5jaGVja2VkP2wucHVzaCgiSENIRUNLRUQiKTpyLmNoZWNrZWQmJmwucHVzaCgiQ0hFQ0tFRCIpLHIub3BlbiYmbC5wdXNoKCJPUEVOIiksdGhpcy53YWl0VXBkYXRlWE1MKWlmKHRoaXMuX2dsb2JhbElkU3RvcmFnZUZpbmQoci5pZCkpdmFyIHM9dGhpcy51cGRhdGVJdGVtKHIuaWQsci50ZXh0LHIuaW0wLHIuaW0xLHIuaW0yLHIuY2hlY2tlZCxyLmNoaWxkKTtlbHNlezA9PXRoaXMubnBsP2wucHVzaCgiVE9QIik6aT10LmNoaWxkTm9kZXNbdGhpcy5ucGxdO3ZhciBzPXRoaXMuX2F0dGFjaENoaWxkTm9kZSh0LHIuaWQsci50ZXh0LDAsci5pbTAsci5pbTEsci5pbTIsbC5qb2luKCIsIiksci5jaGlsZCwwLGkpO3IuaWQ9cy5pZCxpPW51bGx9ZWxzZSB2YXIgcz10aGlzLl9hdHRhY2hDaGlsZE5vZGUodCxyLmlkLHIudGV4dCwwLHIuaW0wLHIuaW0xLHIuaW0yLGwuam9pbigiLCIpLHIuY2hpbGQsbnx8MCxpKTtpZihyLnRvb2x0aXAmJihzLnNwYW4ucGFyZW50Tm9kZS5wYXJlbnROb2RlLnRpdGxlPXIudG9vbHRpcCksci5zdHlsZSYmKHMuc3Bhbi5zdHlsZS5jc3NUZXh0P3Muc3Bhbi5zdHlsZS5jc3NUZXh0Kz0iOyIrci5zdHlsZTpzLnNwYW4uc2V0QXR0cmlidXRlKCJzdHlsZSIscy5zcGFuLmdldEF0dHJpYnV0ZSgic3R5bGUiKSsiOyAiK3Iuc3R5bGUpKSxyLnJhZGlvJiYocy5fcl9sb2dpYz0hMCksci5ub2NoZWNrYm94KXt2YXIgYT1zLnNwYW4ucGFyZW50Tm9kZS5wcmV2aW91c1NpYmxpbmcucHJldmlvdXNTaWJsaW5nO2Euc3R5bGUuZGlzcGxheT0ibm9uZSIscy5ub2NoZWNrYm94PSEwfXIuZGlzYWJsZWQmJihudWxsIT1yLmNoZWNrZWQmJnRoaXMuX3NldENoZWNrKHMsci5jaGVja2VkKSx0aGlzLmRpc2FibGVDaGVja2JveChzLDEpKSxzLl9hY2M9ci5jaGlsZHx8MCx0aGlzLnBhcnNlckV4dGVuc2lvbiYmdGhpcy5wYXJzZXJFeHRlbnNpb24uX3BhcnNlRXh0ZW5zaW9uLmNhbGwodGhpcyxlLHIsdD90LmlkOjApLHRoaXMuc2V0SXRlbUNvbG9yKHMsci5hQ29sLHIuc0NvbCksIjEiPT1yLmxvY2tlZCYmdGhpcy5sb2NrSXRlbShzLmlkLCEwLCEwKSwoci5pbXdpZHRofHxyLmltaGVpZ2h0KSYmdGhpcy5zZXRJY29uU2l6ZShyLmltd2lkdGgsci5pbWhlaWdodCxzKSwoIjAiPT1yLmNsb3NlYWJsZXx8IjEiPT1yLmNsb3NlYWJsZSkmJnRoaXMuc2V0SXRlbUNsb3NlYWJsZShzLHIuY2xvc2VhYmxlKTt2YXIgZD0iIjtyLnRvcG9mZnNldCYmdGhpcy5zZXRJdGVtVG9wT2Zmc2V0KHMsci50b3BvZmZzZXQpLHRoaXMuc2xvd1BhcnNlJiYib2JqZWN0IiE9dHlwZW9mIHRoaXMud2FpdFVwZGF0ZVhNTD8oIXMuY2hpbGRzQ291bnQmJmUuc3ViX2V4aXN0cygiaXRlbSIpJiYocy51blBhcnNlZD1lLmNsb25lKCkpLGUuZWFjaCgidXNlcmRhdGEiLGZ1bmN0aW9uKGUpe3RoaXMuc2V0VXNlckRhdGEoci5pZCxlLmdldCgibmFtZSIpLGUuY29udGVudCgpKX0sdGhpcykpOmUuc3ViX2V4aXN0cygiaXRlbSIpJiYoZD10aGlzLl9wYXJzZShlLHIuaWQsMSkpLCIiIT1kJiYodGhpcy5ub2RlQXNraW5nQ2FsbD1kKSxlLmVhY2goInVzZXJkYXRhIixmdW5jdGlvbih0KXt0aGlzLnNldFVzZXJEYXRhKGUuZ2V0KCJpZCIpLHQuZ2V0KCJuYW1lIiksdC5jb250ZW50KCkpfSx0aGlzKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX3BhcnNlPWZ1bmN0aW9uKGUsdCxpLG4pe2lmKHRoaXMuX3NybmQmJiF0aGlzLnBhcmVudE9iamVjdC5vZmZzZXRIZWlnaHQpe3ZhciBvPXRoaXM7cmV0dXJuIHdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7by5fcGFyc2UoZSx0LGksbil9LDEwMCl9aWYoZS5leGlzdHMoKSl7aWYodGhpcy5za2lwTG9jaz0hMCwhdCl7dD1lLmdldCgiaWQiKSx0aGlzLl9keW5EZWxldGVCcmFuY2hlc1t0XSYmKHRoaXMuZGVsZXRlQ2hpbGRJdGVtcyh0KSx0aGlzLl9keW5EZWxldGVCcmFuY2hlc1t0XS0tLHRoaXMuX2R5bkRlbGV0ZUJyYW5jaGVzW3RdfHxkZWxldGUgdGhpcy5fZHluRGVsZXRlQnJhbmNoZXNbdF0pO3ZhciByPWUuZ2V0KCJkaHhfc2VjdXJpdHkiKTtyJiYoZGh0bWx4LnNlY3VyaXR5X2tleT1yKSxlLmdldCgicmFkaW8iKSYmKHRoaXMuaHRtbE5vZGUuX3JfbG9naWM9ITApLHRoaXMucGFyc2luZ09uPXQsdGhpcy5wYXJzZWRBcnJheT1uZXcgQXJyYXksdGhpcy5zZXRDaGVja0xpc3Q9IiIsdGhpcy5ub2RlQXNraW5nQ2FsbD0iIn12YXIgbD10aGlzLl9nbG9iYWxJZFN0b3JhZ2VGaW5kKHQpO2lmKCFsKXJldHVybiBkaHg0LmNhbGxFdmVudCgib25EYXRhU3RydWN0dXJlRXJyb3IiLFsiWE1MIHJlZmVycyB0byBub3QgZXhpc3RpbmcgcGFyZW50Il0pO2lmKHRoaXMucGFyc0NvdW50PXRoaXMucGFyc0NvdW50P3RoaXMucGFyc0NvdW50KzE6MSx0aGlzLlhNTGxvYWRpbmdXYXJuaW5nPTEsIWwuY2hpbGRzQ291bnR8fG58fHRoaXMuX2Vkc2Jwc3x8bC5faGFzX3RvcCl2YXIgcz0wO2Vsc2UgdmFyIHM9MDtpZih0aGlzLm5wbD0wLGUuZWFjaCgiaXRlbSIsZnVuY3Rpb24obixvKXtyZXR1cm4gbC5YTUxsb2FkPTEsdGhpcy5fcGFyc2VJdGVtKG4sbCwwLHMpLHRoaXMuX2Vkc2JwcyYmdGhpcy5ucGw9PXRoaXMuX2Vkc2Jwc0M/KHRoaXMuX2Rpc3RyaWJ1dGVkU3RhcnQoZSxvKzEsdCxpLGwuY2hpbGRzQ291bnQpLC0xKToodGhpcy5ucGwrKyx2b2lkIDApfSx0aGlzLG4pLCFpKXtpZihlLmVhY2goInVzZXJkYXRhIixmdW5jdGlvbih0KXt0aGlzLnNldFVzZXJEYXRhKGUuZ2V0KCJpZCIpLHQuZ2V0KCJuYW1lIiksdC5jb250ZW50KCkpfSx0aGlzKSxsLlhNTGxvYWQ9MSx0aGlzLndhaXRVcGRhdGVYTUwpe3RoaXMud2FpdFVwZGF0ZVhNTD0hMTtmb3IodmFyIGE9bC5jaGlsZHNDb3VudC0xO2E+PTA7YS0tKWwuY2hpbGROb2Rlc1thXS5fZG1hcmsmJnRoaXMuZGVsZXRlSXRlbShsLmNoaWxkTm9kZXNbYV0uaWQpfWZvcih2YXIgYT0odGhpcy5fZ2xvYmFsSWRTdG9yYWdlRmluZCh0aGlzLnBhcnNpbmdPbiksMCk7YTx0aGlzLnBhcnNlZEFycmF5Lmxlbmd0aDthKyspbC5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmFwcGVuZENoaWxkKHRoaXMucGFyc2VkQXJyYXlbYV0pO3RoaXMucGFyc2VkQXJyYXk9W10sdGhpcy5sYXN0TG9hZGVkWE1MSWQ9dCx0aGlzLlhNTGxvYWRpbmdXYXJuaW5nPTA7Zm9yKHZhciBkPXRoaXMuc2V0Q2hlY2tMaXN0LnNwbGl0KHRoaXMuZGxtdHIpLGg9MDtoPGQubGVuZ3RoO2grKylkW2hdJiZ0aGlzLnNldENoZWNrKGRbaF0sMSk7dGhpcy5YTUxzb3VyY2UmJnRoaXMudHNjaGVjayYmdGhpcy5zbWNoZWNrJiZsLmlkIT10aGlzLnJvb3RJZCYmKDA9PT1sLmNoZWNrc3RhdGU/dGhpcy5fc2V0U3ViQ2hlY2tlZCgwLGwpOjE9PT1sLmNoZWNrc3RhdGUmJnRoaXMuX3NldFN1YkNoZWNrZWQoMSxsKSksdGhpcy5fcmVkcmF3RnJvbSh0aGlzLG51bGwsbiksZS5nZXQoIm9yZGVyIikmJiJub25lIiE9ZS5nZXQoIm9yZGVyIikmJnRoaXMuX3Jlb3JkZXJCcmFuY2gobCxlLmdldCgib3JkZXIiKSwhMCksIiIhPXRoaXMubm9kZUFza2luZ0NhbGwmJnRoaXMuY2FsbEV2ZW50KCJvbkNsaWNrIixbdGhpcy5ub2RlQXNraW5nQ2FsbCx0aGlzLmdldFNlbGVjdGVkSXRlbUlkKCldKSx0aGlzLl9icmFuY2hVcGRhdGUmJnRoaXMuX2JyYW5jaFVwZGF0ZU5leHQoZSl9aWYoMT09dGhpcy5wYXJzQ291bnQpe2lmKHRoaXMucGFyc2luZ09uPW51bGwsdGhpcy5fc3JuZCYmbC5pZCE9dGhpcy5yb290SWQmJih0aGlzLnByZXBhcmVTUihsLmlkKSx0aGlzLlhNTHNvdXJjZSYmdGhpcy5vcGVuSXRlbShsLmlkKSksZS50aHJvdWdoKCJpdGVtIiwib3BlbiIsbnVsbCxmdW5jdGlvbihlKXt0aGlzLm9wZW5JdGVtKGUuZ2V0KCJpZCIpKX0sdGhpcyksIXRoaXMuX2Vkc2Jwc3x8IXRoaXMuX2Vkc2Jwc0EubGVuZ3RoKXt2YXIgYz10aGlzO3dpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7Yy5jYWxsRXZlbnQoIm9uWExFIixbYyx0XSl9LDEpLHRoaXMueG1sc3RhdGU9MH10aGlzLnNraXBMb2NrPSExfXRoaXMucGFyc0NvdW50LS07dmFyIGM9dGhpcztyZXR1cm4gdGhpcy5fZWRzYnBzJiZ3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbigpe2MuX2Rpc3RyaWJ1dGVkU3RlcCh0KX0sdGhpcy5fZWRzYnBzRCksIWkmJnRoaXMub25YTEUmJnRoaXMub25YTEUodGhpcyx0KSx0aGlzLm5vZGVBc2tpbmdDYWxsfX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX3JlZHJhd0Zyb209ZnVuY3Rpb24oZSx0LGksbil7aWYodClvPXQ7ZWxzZXt2YXIgbz1lLl9nbG9iYWxJZFN0b3JhZ2VGaW5kKGUubGFzdExvYWRlZFhNTElkKTtpZihlLmxhc3RMb2FkZWRYTUxJZD0tMSwhbylyZXR1cm4gMH1mb3IodmFyIHI9MCxsPWk/aS0xOjA7bDxvLmNoaWxkc0NvdW50O2wrKylpZih0aGlzLl9icmFuY2hVcGRhdGUmJjEhPXRoaXMuX2dldE9wZW5TdGF0ZShvKXx8dCYmMSE9bnx8KG8uY2hpbGROb2Rlc1tsXS5odG1sTm9kZS5wYXJlbnROb2RlLnBhcmVudE5vZGUuc3R5bGUuZGlzcGxheT0iIiksMT09by5jaGlsZE5vZGVzW2xdLm9wZW5NZSYmKHRoaXMuX29wZW5JdGVtKG8uY2hpbGROb2Rlc1tsXSksby5jaGlsZE5vZGVzW2xdLm9wZW5NZT0wKSxlLl9yZWRyYXdGcm9tKGUsby5jaGlsZE5vZGVzW2xdKSxudWxsIT10aGlzLmNoaWxkQ2FsYyl7aWYoKG8uY2hpbGROb2Rlc1tsXS51blBhcnNlZHx8IW8uY2hpbGROb2Rlc1tsXS5YTUxsb2FkJiZ0aGlzLlhNTHNvdXJjZSkmJihvLmNoaWxkTm9kZXNbbF0uc3Bhbi5pbm5lckhUTUw9by5jaGlsZE5vZGVzW2xdLl9hY2M/by5jaGlsZE5vZGVzW2xdLmxhYmVsK3RoaXMuaHRtbGNBK28uY2hpbGROb2Rlc1tsXS5fYWNjK3RoaXMuaHRtbGNCOm8uY2hpbGROb2Rlc1tsXS5sYWJlbCksby5jaGlsZE5vZGVzW2xdLmNoaWxkTm9kZXMubGVuZ3RoJiZ0aGlzLmNoaWxkQ2FsYyl7aWYoMT09dGhpcy5jaGlsZENhbGMmJihvLmNoaWxkTm9kZXNbbF0uc3Bhbi5pbm5lckhUTUw9by5jaGlsZE5vZGVzW2xdLmxhYmVsK3RoaXMuaHRtbGNBK28uY2hpbGROb2Rlc1tsXS5jaGlsZHNDb3VudCt0aGlzLmh0bWxjQiksMj09dGhpcy5jaGlsZENhbGMpe3ZhciBzPW8uY2hpbGROb2Rlc1tsXS5jaGlsZHNDb3VudC0oby5jaGlsZE5vZGVzW2xdLnB1cmVDaGlsZHN8fDApO3MmJihvLmNoaWxkTm9kZXNbbF0uc3Bhbi5pbm5lckhUTUw9by5jaGlsZE5vZGVzW2xdLmxhYmVsK3RoaXMuaHRtbGNBK3MrdGhpcy5odG1sY0IpLG8ucHVyZUNoaWxkcz9vLnB1cmVDaGlsZHMrKzpvLnB1cmVDaGlsZHM9MX1pZigzPT10aGlzLmNoaWxkQ2FsYyYmKG8uY2hpbGROb2Rlc1tsXS5zcGFuLmlubmVySFRNTD1vLmNoaWxkTm9kZXNbbF0ubGFiZWwrdGhpcy5odG1sY0Erby5jaGlsZE5vZGVzW2xdLl9hY2MrdGhpcy5odG1sY0IpLDQ9PXRoaXMuY2hpbGRDYWxjKXt2YXIgcz1vLmNoaWxkTm9kZXNbbF0uX2FjYztzJiYoby5jaGlsZE5vZGVzW2xdLnNwYW4uaW5uZXJIVE1MPW8uY2hpbGROb2Rlc1tsXS5sYWJlbCt0aGlzLmh0bWxjQStzK3RoaXMuaHRtbGNCKX19ZWxzZSA0PT10aGlzLmNoaWxkQ2FsYyYmcisrO3IrPW8uY2hpbGROb2Rlc1tsXS5fYWNjLDM9PXRoaXMuY2hpbGRDYWxjJiZyKyt9by51blBhcnNlZHx8IW8uWE1MbG9hZCYmdGhpcy5YTUxzb3VyY2V8fChvLl9hY2M9ciksZS5fY29ycmVjdExpbmUobyksZS5fY29ycmVjdFBsdXMobyksdGhpcy5jaGlsZENhbGMmJiF0JiZlLl9maXhDaGlsZENvdW50TGFiZWwobyl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl9jcmVhdGVTZWxmPWZ1bmN0aW9uKCl7dmFyIGU9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2Iik7cmV0dXJuIGUuY2xhc3NOYW1lPSJjb250YWluZXJUYWJsZVN0eWxlIixlLnN0eWxlLndpZHRoPXRoaXMud2lkdGgsZS5zdHlsZS5oZWlnaHQ9dGhpcy5oZWlnaHQsdGhpcy5wYXJlbnRPYmplY3QuYXBwZW5kQ2hpbGQoZSksZX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX3hjbG9zZUFsbD1mdW5jdGlvbihlKXtpZighZS51blBhcnNlZCl7aWYodGhpcy5yb290SWQhPWUuaWQpe2lmKCFlLmh0bWxOb2RlKXJldHVybjtmb3IodmFyIHQ9ZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXMsaT10Lmxlbmd0aCxuPTE7aT5uO24rKyl0W25dLnN0eWxlLmRpc3BsYXk9Im5vbmUiO3RoaXMuX2NvcnJlY3RQbHVzKGUpfWZvcih2YXIgbj0wO248ZS5jaGlsZHNDb3VudDtuKyspZS5jaGlsZE5vZGVzW25dLmNoaWxkc0NvdW50JiZ0aGlzLl94Y2xvc2VBbGwoZS5jaGlsZE5vZGVzW25dKX19LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl94b3BlbkFsbD1mdW5jdGlvbihlKXt0aGlzLl9IaWRlU2hvdyhlLDIpO2Zvcih2YXIgdD0wO3Q8ZS5jaGlsZHNDb3VudDt0KyspdGhpcy5feG9wZW5BbGwoZS5jaGlsZE5vZGVzW3RdKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX2NvcnJlY3RQbHVzPWZ1bmN0aW9uKGUpe2lmKGUuaHRtbE5vZGUpe3ZhciB0PWUuaHRtbE5vZGUuY2hpbGROb2Rlc1swXS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXNbMF0ubGFzdENoaWxkLGk9ZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXNbMF0uY2hpbGROb2Rlc1syXS5jaGlsZE5vZGVzWzBdLG49dGhpcy5saW5lQXJyYXk7aWYodGhpcy5YTUxzb3VyY2UmJiFlLlhNTGxvYWQpe3ZhciBuPXRoaXMucGx1c0FycmF5O2lmKHRoaXMuX3NldFNyYyhpLHRoaXMuaWNvblVSTCtlLmltYWdlc1syXSksdGhpcy5fdHh0aW1nKXJldHVybiB0LmlubmVySFRNTD0iWytdIn1lbHNlIGlmKGUuY2hpbGRzQ291bnR8fGUudW5QYXJzZWQpaWYoZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXNbMV0mJiJub25lIiE9ZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXNbMV0uc3R5bGUuZGlzcGxheSl7aWYoIWUud3NpZ24pdmFyIG49dGhpcy5taW51c0FycmF5O2lmKHRoaXMuX3NldFNyYyhpLHRoaXMuaWNvblVSTCtlLmltYWdlc1sxXSksdGhpcy5fdHh0aW1nKXJldHVybiB0LmlubmVySFRNTD0iWy1dIn1lbHNle2lmKCFlLndzaWduKXZhciBuPXRoaXMucGx1c0FycmF5O2lmKHRoaXMuX3NldFNyYyhpLHRoaXMuaWNvblVSTCtlLmltYWdlc1syXSksdGhpcy5fdHh0aW1nKXJldHVybiB0LmlubmVySFRNTD0iWytdIn1lbHNlIHRoaXMuX3NldFNyYyhpLHRoaXMuaWNvblVSTCtlLmltYWdlc1swXSk7dmFyIG89MjtlLnRyZWVOb2QudHJlZUxpbmVzT24/KGUucGFyZW50T2JqZWN0JiYobz10aGlzLl9nZXRDb3VudFN0YXR1cyhlLmlkLGUucGFyZW50T2JqZWN0KSksdGhpcy5fc2V0U3JjKHQsdGhpcy5pbVBhdGgrbltvXSkpOnRoaXMuX3NldFNyYyh0LHRoaXMuaW1QYXRoK25bM10pfX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX2NvcnJlY3RMaW5lPWZ1bmN0aW9uKGUpe2lmKGUuaHRtbE5vZGUpe3ZhciB0PWUucGFyZW50T2JqZWN0O2lmKHQpaWYoMCE9dGhpcy5fZ2V0TGluZVN0YXR1cyhlLmlkLHQpJiZ0aGlzLnRyZWVMaW5lc09uKWZvcih2YXIgaT0xO2k8PWUuY2hpbGRzQ291bnQmJmUuaHRtbE5vZGUuY2hpbGROb2Rlc1swXS5jaGlsZE5vZGVzW2ldO2krKyllLmh0bWxOb2RlLmNoaWxkTm9kZXNbMF0uY2hpbGROb2Rlc1tpXS5jaGlsZE5vZGVzWzBdLnN0eWxlLmJhY2tncm91bmRJbWFnZT0idXJsKCIrdGhpcy5pbVBhdGgrdGhpcy5saW5lQXJyYXlbNV0rIikiLGUuaHRtbE5vZGUuY2hpbGROb2Rlc1swXS5jaGlsZE5vZGVzW2ldLmNoaWxkTm9kZXNbMF0uc3R5bGUuYmFja2dyb3VuZFJlcGVhdD0icmVwZWF0LXkiO2Vsc2UgZm9yKHZhciBpPTE7aTw9ZS5jaGlsZHNDb3VudCYmZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXNbaV07aSsrKWUuaHRtbE5vZGUuY2hpbGROb2Rlc1swXS5jaGlsZE5vZGVzW2ldLmNoaWxkTm9kZXNbMF0uc3R5bGUuYmFja2dyb3VuZEltYWdlPSIiLGUuaHRtbE5vZGUuY2hpbGROb2Rlc1swXS5jaGlsZE5vZGVzW2ldLmNoaWxkTm9kZXNbMF0uc3R5bGUuYmFja2dyb3VuZFJlcGVhdD0iIn19LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl9nZXRMaW5lU3RhdHVzPWZ1bmN0aW9uKGUsdCl7cmV0dXJuIHQuY2hpbGROb2Rlc1t0LmNoaWxkc0NvdW50LTFdLmlkPT1lPzA6MX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX0hpZGVTaG93PWZ1bmN0aW9uKGUsdCl7aWYoIXRoaXMuX2xvY2tlcnx8dGhpcy5za2lwTG9ja3x8IXRoaXMuX2xvY2tlcltlLmlkXSl7aWYodGhpcy5YTUxzb3VyY2UmJiFlLlhNTGxvYWQpe2lmKDE9PXQpcmV0dXJuO3JldHVybiBlLlhNTGxvYWQ9MSx0aGlzLl9sb2FkRHluWE1MKGUuaWQpLHZvaWQgMH1lLnVuUGFyc2VkJiZ0aGlzLnJlUGFyc2UoZSk7dmFyIGk9ZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXMsbj1pLmxlbmd0aDtpZihuPjEpeyJub25lIj09aVsxXS5zdHlsZS5kaXNwbGF5JiYxIT10fHwyPT10P25vZGVzdHlsZT0iIjoodGhpcy5hbGxUcmVlLmNoaWxkTm9kZXNbMF0uYm9yZGVyPSIxIix0aGlzLmFsbFRyZWUuY2hpbGROb2Rlc1swXS5ib3JkZXI9IjAiLG5vZGVzdHlsZT0ibm9uZSIpO2Zvcih2YXIgbz0xO24+bztvKyspaVtvXS5zdHlsZS5kaXNwbGF5PW5vZGVzdHlsZX10aGlzLl9jb3JyZWN0UGx1cyhlKX19LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl9nZXRPcGVuU3RhdGU9ZnVuY3Rpb24oZSl7aWYoIWUuaHRtbE5vZGUpcmV0dXJuIDA7dmFyIHQ9ZS5odG1sTm9kZS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXM7cmV0dXJuIHQubGVuZ3RoPD0xPzA6Im5vbmUiIT10WzFdLnN0eWxlLmRpc3BsYXk/MTotMX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUub25Sb3dDbGljazI9ZnVuY3Rpb24oKXt2YXIgZT10aGlzLnBhcmVudE9iamVjdC50cmVlTm9kO3JldHVybiBlLmNhbGxFdmVudCgib25EYmxDbGljayIsW3RoaXMucGFyZW50T2JqZWN0LmlkLGVdKT8odGhpcy5wYXJlbnRPYmplY3QuY2xvc2VibGUmJiIwIiE9dGhpcy5wYXJlbnRPYmplY3QuY2xvc2VibGU/ZS5fSGlkZVNob3codGhpcy5wYXJlbnRPYmplY3QpOmUuX0hpZGVTaG93KHRoaXMucGFyZW50T2JqZWN0LDIpLGUuY2hlY2tFdmVudCgib25PcGVuRW5kIikmJihlLnhtbHN0YXRlPyhlLl9vaWVfb25YTEUucHVzaChlLm9uWExFKSxlLm9uWExFPWUuX2VwbkZIZSk6ZS5jYWxsRXZlbnQoIm9uT3BlbkVuZCIsW3RoaXMucGFyZW50T2JqZWN0LmlkLGUuX2dldE9wZW5TdGF0ZSh0aGlzLnBhcmVudE9iamVjdCldKSksITEpOiExfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5vblJvd0NsaWNrPWZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5wYXJlbnRPYmplY3QudHJlZU5vZDtyZXR1cm4gZS5jYWxsRXZlbnQoIm9uT3BlblN0YXJ0IixbdGhpcy5wYXJlbnRPYmplY3QuaWQsZS5fZ2V0T3BlblN0YXRlKHRoaXMucGFyZW50T2JqZWN0KV0pPyh0aGlzLnBhcmVudE9iamVjdC5jbG9zZWJsZSYmIjAiIT10aGlzLnBhcmVudE9iamVjdC5jbG9zZWJsZT9lLl9IaWRlU2hvdyh0aGlzLnBhcmVudE9iamVjdCk6ZS5fSGlkZVNob3codGhpcy5wYXJlbnRPYmplY3QsMiksZS5jaGVja0V2ZW50KCJvbk9wZW5FbmQiKSYmKGUueG1sc3RhdGU/KGUuX29pZV9vblhMRS5wdXNoKGUub25YTEUpLGUub25YTEU9ZS5fZXBuRkhlKTplLmNhbGxFdmVudCgib25PcGVuRW5kIixbdGhpcy5wYXJlbnRPYmplY3QuaWQsZS5fZ2V0T3BlblN0YXRlKHRoaXMucGFyZW50T2JqZWN0KV0pKSx2b2lkIDApOjB9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLmdldFNlbGVjdGVkSXRlbUlkPWZ1bmN0aW9uKCl7Zm9yKHZhciBlPW5ldyBBcnJheSx0PTA7dDx0aGlzLl9zZWxlY3RlZC5sZW5ndGg7dCsrKWVbdF09dGhpcy5fc2VsZWN0ZWRbdF0uaWQ7cmV0dXJuIGUuam9pbih0aGlzLmRsbXRyKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX3NlbGVjdEl0ZW09ZnVuY3Rpb24oZSx0KXtpZih0aGlzLmNoZWNrRXZlbnQoIm9uU2VsZWN0IikmJih0aGlzLl9vblNTQ0ZvbGQ9dGhpcy5nZXRTZWxlY3RlZEl0ZW1JZCgpKSx0aGlzLl9hbXNlbCYmdCYmKHQuY3RybEtleXx8dC5tZXRhS2V5fHx0LnNoaWZ0S2V5KXx8dGhpcy5fdW5zZWxlY3RJdGVtcygpLGUuaV9zZWwmJnRoaXMuX2Ftc2VsJiZ0JiYodC5jdHJsS2V5fHx0Lm1ldGFLZXkpKXRoaXMuX3Vuc2VsZWN0SXRlbShlKTtlbHNlIGlmKCEoZS5pX3NlbHx8dGhpcy5fYW1zZWxTJiYwIT10aGlzLl9zZWxlY3RlZC5sZW5ndGgmJnRoaXMuX3NlbGVjdGVkWzBdLnBhcmVudE9iamVjdCE9ZS5wYXJlbnRPYmplY3QpKWlmKHRoaXMuX2Ftc2VsJiZ0JiZ0LnNoaWZ0S2V5JiYwIT10aGlzLl9zZWxlY3RlZC5sZW5ndGgmJnRoaXMuX3NlbGVjdGVkW3RoaXMuX3NlbGVjdGVkLmxlbmd0aC0xXS5wYXJlbnRPYmplY3Q9PWUucGFyZW50T2JqZWN0KXt2YXIgaT10aGlzLl9nZXRJbmRleCh0aGlzLl9zZWxlY3RlZFt0aGlzLl9zZWxlY3RlZC5sZW5ndGgtMV0pLG49dGhpcy5fZ2V0SW5kZXgoZSk7aWYoaT5uKXt2YXIgbz1pO2k9bixuPW99Zm9yKHZhciByPWk7bj49cjtyKyspZS5wYXJlbnRPYmplY3QuY2hpbGROb2Rlc1tyXS5pX3NlbHx8dGhpcy5fbWFya0l0ZW0oZS5wYXJlbnRPYmplY3QuY2hpbGROb2Rlc1tyXSl9ZWxzZSB0aGlzLl9tYXJrSXRlbShlKTtpZih0aGlzLmNoZWNrRXZlbnQoIm9uU2VsZWN0Iikpe3ZhciBsPXRoaXMuZ2V0U2VsZWN0ZWRJdGVtSWQoKTtsIT10aGlzLl9vblNTQ0ZvbGQmJnRoaXMuY2FsbEV2ZW50KCJvblNlbGVjdCIsW2xdKX19LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl9tYXJrSXRlbT1mdW5jdGlvbihlKXtlLnNjb2xvciYmKGUuc3Bhbi5zdHlsZS5jb2xvcj1lLnNjb2xvciksZS5zcGFuLmNsYXNzTmFtZT0ic2VsZWN0ZWRUcmVlUm93IixlLnNwYW4ucGFyZW50Tm9kZS5wYXJlbnROb2RlLmNsYXNzTmFtZT0ic2VsZWN0ZWRUcmVlUm93RnVsbCIsZS5pX3NlbD0hMCx0aGlzLl9zZWxlY3RlZFt0aGlzLl9zZWxlY3RlZC5sZW5ndGhdPWV9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLmdldEluZGV4QnlJZD1mdW5jdGlvbihlKXt2YXIgdD10aGlzLl9nbG9iYWxJZFN0b3JhZ2VGaW5kKGUpO3JldHVybiB0P3RoaXMuX2dldEluZGV4KHQpOm51bGx9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl9nZXRJbmRleD1mdW5jdGlvbihlKXtmb3IodmFyIHQ9ZS5wYXJlbnRPYmplY3QsaT0wO2k8dC5jaGlsZHNDb3VudDtpKyspaWYodC5jaGlsZE5vZGVzW2ldPT1lKXJldHVybiBpfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5fdW5zZWxlY3RJdGVtPWZ1bmN0aW9uKGUpe2lmKGUmJmUuaV9zZWwpe2Uuc3Bhbi5jbGFzc05hbWU9InN0YW5kYXJ0VHJlZVJvdyIsZS5zcGFuLnBhcmVudE5vZGUucGFyZW50Tm9kZS5jbGFzc05hbWU9IiIsZS5hY29sb3ImJihlLnNwYW4uc3R5bGUuY29sb3I9ZS5hY29sb3IpLGUuaV9zZWw9ITE7Zm9yKHZhciB0PTA7dDx0aGlzLl9zZWxlY3RlZC5sZW5ndGg7dCsrKWlmKCF0aGlzLl9zZWxlY3RlZFt0XS5pX3NlbCl7dGhpcy5fc2VsZWN0ZWQuc3BsaWNlKHQsMSk7YnJlYWt9fX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX3Vuc2VsZWN0SXRlbXM9ZnVuY3Rpb24oKXtmb3IodmFyIGU9MDtlPHRoaXMuX3NlbGVjdGVkLmxlbmd0aDtlKyspe3ZhciB0PXRoaXMuX3NlbGVjdGVkW2VdO3Quc3Bhbi5jbGFzc05hbWU9InN0YW5kYXJ0VHJlZVJvdyIsdC5zcGFuLnBhcmVudE5vZGUucGFyZW50Tm9kZS5jbGFzc05hbWU9IiIsdC5hY29sb3ImJih0LnNwYW4uc3R5bGUuY29sb3I9dC5hY29sb3IpLHQuaV9zZWw9ITF9dGhpcy5fc2VsZWN0ZWQ9bmV3IEFycmF5fSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5vblJvd1NlbGVjdD1mdW5jdGlvbihlLHQsaSl7ZT1lfHx3aW5kb3cuZXZlbnQ7dmFyIG49dGhpcy5wYXJlbnRPYmplY3Q7dCYmKG49dC5wYXJlbnRPYmplY3QpO3ZhciBvPW4udHJlZU5vZCxyPW8uZ2V0U2VsZWN0ZWRJdGVtSWQoKTtlJiZlLnNraXBVblNlbHx8by5fc2VsZWN0SXRlbShuLGUpLGl8fChuLmFjdGlvbkhhbmRsZXI/bi5hY3Rpb25IYW5kbGVyKG4uaWQscik6by5jYWxsRXZlbnQoIm9uQ2xpY2siLFtuLmlkLHJdKSl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLl9jcmVhdGVJdGVtPWZ1bmN0aW9uKGUsdCxpKXt2YXIgbj1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJ0YWJsZSIpO24uY2VsbFNwYWNpbmc9MCxuLmNlbGxQYWRkaW5nPTAsbi5ib3JkZXI9MCx0aGlzLmhmTW9kZSYmKG4uc3R5bGUudGFibGVMYXlvdXQ9ImZpeGVkIiksbi5zdHlsZS5tYXJnaW49MCxuLnN0eWxlLnBhZGRpbmc9MDt2YXIgbz1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJ0Ym9keSIpLHI9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidHIiKSxsPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInRkIik7aWYobC5jbGFzc05hbWU9InN0YW5kYXJ0VHJlZUltYWdlIix0aGlzLl90eHRpbWcpe3ZhciBzPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpO2wuYXBwZW5kQ2hpbGQocykscy5jbGFzc05hbWU9ImRoeF90cmVlX3RleHRTaWduIn1lbHNle3ZhciBzPXRoaXMuX2dldEltZyh0LmlkKTtzLmJvcmRlcj0iMCIsIklNRyI9PXMudGFnTmFtZSYmKHMuYWxpZ249ImFic21pZGRsZSIpLGwuYXBwZW5kQ2hpbGQocykscy5zdHlsZS5wYWRkaW5nPTAscy5zdHlsZS5tYXJnaW49MCxzLnN0eWxlLndpZHRoPXRoaXMuZGVmX2xpbmVfaW1nX3h9dmFyIGE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGQiKSxkPXRoaXMuX2dldEltZyh0aGlzLmNCUk9mP3RoaXMucm9vdElkOnQuaWQpO2QuY2hlY2tlZD0wLHRoaXMuX3NldFNyYyhkLHRoaXMuaW1QYXRoK3RoaXMuY2hlY2tBcnJheVswXSksZC5zdHlsZS53aWR0aD0iMThweCIsZC5zdHlsZS5oZWlnaHQ9IjE4cHgiLGV8fChhLnN0eWxlLmRpc3BsYXk9Im5vbmUiKSxhLmFwcGVuZENoaWxkKGQpLHRoaXMuY0JST2Z8fCJJTUciIT1kLnRhZ05hbWV8fChkLmFsaWduPSJhYnNtaWRkbGUiKSxkLm9uY2xpY2s9dGhpcy5vbkNoZWNrQm94Q2xpY2ssZC50cmVlTm9kPXRoaXMsZC5wYXJlbnRPYmplY3Q9dCxhLndpZHRoPXdpbmRvdy5fS0hUTUxydj8iMTZweCI6IjIwcHgiO3ZhciBoPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInRkIik7aC5jbGFzc05hbWU9InN0YW5kYXJ0VHJlZUltYWdlIjt2YXIgYz10aGlzLl9nZXRJbWcodGhpcy50aW1nZW4/dC5pZDp0aGlzLnJvb3RJZCk7Yy5vbm1vdXNlZG93bj10aGlzLl9wcmV2ZW50TnNEcmFnLGMub25kcmFnc3RhcnQ9dGhpcy5fcHJldmVudE5zRHJhZyxjLmJvcmRlcj0iMCIsdGhpcy5fYWltZ3MmJihjLnBhcmVudE9iamVjdD10LCJJTUciPT1jLnRhZ05hbWUmJihjLmFsaWduPSJhYnNtaWRkbGUiKSxjLm9uY2xpY2s9dGhpcy5vblJvd1NlbGVjdCksaXx8dGhpcy5fc2V0U3JjKGMsdGhpcy5pY29uVVJMK3RoaXMuaW1hZ2VBcnJheVswXSksaC5hcHBlbmRDaGlsZChjKSxjLnN0eWxlLnBhZGRpbmc9MCxjLnN0eWxlLm1hcmdpbj0wLHRoaXMudGltZ2VuPyhoLnN0eWxlLndpZHRoPWMuc3R5bGUud2lkdGg9dGhpcy5kZWZfaW1nX3gsYy5zdHlsZS5oZWlnaHQ9dGhpcy5kZWZfaW1nX3kpOihjLnN0eWxlLndpZHRoPSIwcHgiLGMuc3R5bGUuaGVpZ2h0PSIwcHgiLChfaXNPcGVyYXx8d2luZG93Ll9LSFRNTHJ2KSYmKGguc3R5bGUuZGlzcGxheT0ibm9uZSIpKTsKdmFyIHU9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGQiKTtyZXR1cm4gdS5jbGFzc05hbWU9ImRoeFRleHRDZWxsIHN0YW5kYXJ0VHJlZVJvdyIsdC5zcGFuPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNwYW4iKSx0LnNwYW4uY2xhc3NOYW1lPSJzdGFuZGFydFRyZWVSb3ciLHRoaXMubWxpdGVtcz8odC5zcGFuLnN0eWxlLndpZHRoPXRoaXMubWxpdGVtcyx0LnNwYW4uc3R5bGUuZGlzcGxheT0iYmxvY2siKTp1Lm5vV3JhcD0hMCxkaHg0LmlzSUU4P3Uuc3R5bGUud2lkdGg9Ijk5OTk5cHgiOndpbmRvdy5fS0hUTUxydnx8KHUuc3R5bGUud2lkdGg9IjEwMCUiKSx0LnNwYW4uaW5uZXJIVE1MPXQubGFiZWwsdS5hcHBlbmRDaGlsZCh0LnNwYW4pLHUucGFyZW50T2JqZWN0PXQsbC5wYXJlbnRPYmplY3Q9dCx1Lm9uY2xpY2s9dGhpcy5vblJvd1NlbGVjdCxsLm9uY2xpY2s9dGhpcy5vblJvd0NsaWNrLHUub25kYmxjbGljaz10aGlzLm9uUm93Q2xpY2syLHRoaXMuZXR0aXAmJihyLnRpdGxlPXQubGFiZWwpLHRoaXMuZHJhZ0FuZERyb3BPZmYmJih0aGlzLl9haW1ncyYmKHRoaXMuZHJhZ2dlci5hZGREcmFnZ2FibGVJdGVtKGgsdGhpcyksaC5wYXJlbnRPYmplY3Q9dCksdGhpcy5kcmFnZ2VyLmFkZERyYWdnYWJsZUl0ZW0odSx0aGlzKSksdC5zcGFuLnN0eWxlLnBhZGRpbmdMZWZ0PSI1cHgiLHQuc3Bhbi5zdHlsZS5wYWRkaW5nUmlnaHQ9IjVweCIsdS5zdHlsZS52ZXJ0aWNhbEFsaWduPSIiLHUuc3R5bGUuZm9udFNpemU9IjEwcHQiLHUuc3R5bGUuY3Vyc29yPXRoaXMuc3R5bGVfcG9pbnRlcixyLmFwcGVuZENoaWxkKGwpLHIuYXBwZW5kQ2hpbGQoYSksci5hcHBlbmRDaGlsZChoKSxyLmFwcGVuZENoaWxkKHUpLG8uYXBwZW5kQ2hpbGQociksbi5hcHBlbmRDaGlsZChvKSwodGhpcy5laGx0fHx0aGlzLmNoZWNrRXZlbnQoIm9uTW91c2VJbiIpfHx0aGlzLmNoZWNrRXZlbnQoIm9uTW91c2VPdXQiKSkmJihyLm9ubW91c2Vtb3ZlPXRoaXMuX2l0ZW1Nb3VzZUluLHJbX2lzSUU/Im9ubW91c2VsZWF2ZSI6Im9ubW91c2VvdXQiXT10aGlzLl9pdGVtTW91c2VPdXQpLG59LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLnNldE9uUmlnaHRDbGlja0hhbmRsZXI9ZnVuY3Rpb24oZSl7dGhpcy5hdHRhY2hFdmVudCgib25SaWdodENsaWNrIixlKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuc2V0T25DbGlja0hhbmRsZXI9ZnVuY3Rpb24oZSl7dGhpcy5hdHRhY2hFdmVudCgib25DbGljayIsZSl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLnNldE9uU2VsZWN0U3RhdGVDaGFuZ2U9ZnVuY3Rpb24oZSl7dGhpcy5hdHRhY2hFdmVudCgib25TZWxlY3QiLGUpfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5zZXRYTUxBdXRvTG9hZGluZz1mdW5jdGlvbihlKXt0aGlzLlhNTHNvdXJjZT1lfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5zZXRPbkNoZWNrSGFuZGxlcj1mdW5jdGlvbihlKXt0aGlzLmF0dGFjaEV2ZW50KCJvbkNoZWNrIixlKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuc2V0T25PcGVuSGFuZGxlcj1mdW5jdGlvbihlKXt0aGlzLmF0dGFjaEV2ZW50KCJvbk9wZW5TdGFydCIsZSl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLnNldE9uT3BlblN0YXJ0SGFuZGxlcj1mdW5jdGlvbihlKXt0aGlzLmF0dGFjaEV2ZW50KCJvbk9wZW5TdGFydCIsZSl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLnNldE9uT3BlbkVuZEhhbmRsZXI9ZnVuY3Rpb24oZSl7dGhpcy5hdHRhY2hFdmVudCgib25PcGVuRW5kIixlKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuc2V0T25EYmxDbGlja0hhbmRsZXI9ZnVuY3Rpb24oZSl7dGhpcy5hdHRhY2hFdmVudCgib25EYmxDbGljayIsZSl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLm9wZW5BbGxJdGVtcz1mdW5jdGlvbihlKXt2YXIgdD10aGlzLl9nbG9iYWxJZFN0b3JhZ2VGaW5kKGUpO3JldHVybiB0Pyh0aGlzLl94b3BlbkFsbCh0KSx2b2lkIDApOjB9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLmdldE9wZW5TdGF0ZT1mdW5jdGlvbihlKXt2YXIgdD10aGlzLl9nbG9iYWxJZFN0b3JhZ2VGaW5kKGUpO3JldHVybiB0P3RoaXMuX2dldE9wZW5TdGF0ZSh0KToiIn0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuY2xvc2VBbGxJdGVtcz1mdW5jdGlvbihlKXtlPT09d2luZG93LnVuZGVmaW5lZCYmKGU9dGhpcy5yb290SWQpO3ZhciB0PXRoaXMuX2dsb2JhbElkU3RvcmFnZUZpbmQoZSk7cmV0dXJuIHQ/KHRoaXMuX3hjbG9zZUFsbCh0KSx0aGlzLmFsbFRyZWUuY2hpbGROb2Rlc1swXS5ib3JkZXI9IjEiLHRoaXMuYWxsVHJlZS5jaGlsZE5vZGVzWzBdLmJvcmRlcj0iMCIsdm9pZCAwKTowfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5zZXRVc2VyRGF0YT1mdW5jdGlvbihlLHQsaSl7dmFyIG49dGhpcy5fZ2xvYmFsSWRTdG9yYWdlRmluZChlLDAsITApO24mJigiaGludCI9PXQmJihuLmh0bWxOb2RlLmNoaWxkTm9kZXNbMF0uY2hpbGROb2Rlc1swXS50aXRsZT1pKSwidW5kZWZpbmVkIj09dHlwZW9mIG4udXNlckRhdGFbInRfIit0XSYmKG4uX3VzZXJkYXRhbGlzdD9uLl91c2VyZGF0YWxpc3QrPSIsIit0Om4uX3VzZXJkYXRhbGlzdD10KSxuLnVzZXJEYXRhWyJ0XyIrdF09aSl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLmdldFVzZXJEYXRhPWZ1bmN0aW9uKGUsdCl7dmFyIGk9dGhpcy5fZ2xvYmFsSWRTdG9yYWdlRmluZChlLDAsITApO2lmKGkpcmV0dXJuIGkudXNlckRhdGFbInRfIit0XX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuZ2V0SXRlbUNvbG9yPWZ1bmN0aW9uKGUpe3ZhciB0PXRoaXMuX2dsb2JhbElkU3RvcmFnZUZpbmQoZSk7aWYoIXQpcmV0dXJuIDA7dmFyIGk9bmV3IE9iamVjdDtyZXR1cm4gdC5hY29sb3ImJihpLmFjb2xvcj10LmFjb2xvciksdC5zY29sb3ImJihpLnNjb2xvcj10LnNjb2xvciksaX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuc2V0SXRlbUNvbG9yPWZ1bmN0aW9uKGUsdCxpKXtpZihlJiZlLnNwYW4pdmFyIG49ZTtlbHNlIHZhciBuPXRoaXMuX2dsb2JhbElkU3RvcmFnZUZpbmQoZSk7cmV0dXJuIG4/KG4uaV9zZWw/KGl8fHQpJiYobi5zcGFuLnN0eWxlLmNvbG9yPWl8fHQpOnQmJihuLnNwYW4uc3R5bGUuY29sb3I9dCksaSYmKG4uc2NvbG9yPWkpLHQmJihuLmFjb2xvcj10KSx2b2lkIDApOjB9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLnNldE9uTW91c2VJbkhhbmRsZXI9ZnVuY3Rpb24oZSl7dGhpcy5laGx0PSEwLHRoaXMuYXR0YWNoRXZlbnQoIm9uTW91c2VJbiIsZSl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLnNldE9uTW91c2VPdXRIYW5kbGVyPWZ1bmN0aW9uKGUpe3RoaXMuZWhsdD0hMCx0aGlzLmF0dGFjaEV2ZW50KCJvbk1vdXNlT3V0IixlKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuZW5hYmxlVHJlZUxpbmVzPWZ1bmN0aW9uKGUpe3RoaXMudHJlZUxpbmVzT249ZGh4NC5zMmIoZSl9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLm9wZW5JdGVtPWZ1bmN0aW9uKGUpe3RoaXMuc2tpcExvY2s9ITA7dmFyIHQ9dGhpcy5fZ2xvYmFsSWRTdG9yYWdlRmluZChlKTtyZXR1cm4gdD90aGlzLl9vcGVuSXRlbSh0KTowfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5fb3Blbkl0ZW09ZnVuY3Rpb24oZSl7dmFyIHQ9dGhpcy5fZ2V0T3BlblN0YXRlKGUpO2lmKDA+dHx8dGhpcy5YTUxzb3VyY2UmJiFlLlhNTGxvYWQpe2lmKCF0aGlzLmNhbGxFdmVudCgib25PcGVuU3RhcnQiLFtlLmlkLHRdKSlyZXR1cm4gMDt0aGlzLl9IaWRlU2hvdyhlLDIpLHRoaXMuY2hlY2tFdmVudCgib25PcGVuRW5kIikmJih0aGlzLm9uWExFPT10aGlzLl9lcG5GSGUmJnRoaXMuX2VwbkZIZSh0aGlzLGUuaWQsITApLHRoaXMueG1sc3RhdGUmJnRoaXMuWE1Mc291cmNlPyh0aGlzLl9vaWVfb25YTEUucHVzaCh0aGlzLm9uWExFKSx0aGlzLm9uWExFPXRoaXMuX2VwbkZIZSk6dGhpcy5jYWxsRXZlbnQoIm9uT3BlbkVuZCIsW2UuaWQsdGhpcy5fZ2V0T3BlblN0YXRlKGUpXSkpfWVsc2UgdGhpcy5fc3JuZCYmdGhpcy5fSGlkZVNob3coZSwyKTtlLnBhcmVudE9iamVjdCYmIXRoaXMuX3NraXBfb3Blbl9wYXJlbnQmJnRoaXMuX29wZW5JdGVtKGUucGFyZW50T2JqZWN0KX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX2dldEFsbEZhdEl0ZW1zPWZ1bmN0aW9uKGUpe2Zvcih2YXIgdD0iIixpPTA7aTxlLmNoaWxkc0NvdW50O2krKylpZihlLmNoaWxkTm9kZXNbaV0udW5QYXJzZWR8fGUuY2hpbGROb2Rlc1tpXS5jaGlsZHNDb3VudD4wKXtpZih0P3QrPXRoaXMuZGxtdHIrZS5jaGlsZE5vZGVzW2ldLmlkOnQ9IiIrZS5jaGlsZE5vZGVzW2ldLmlkLGUuY2hpbGROb2Rlc1tpXS51blBhcnNlZCl2YXIgbj10aGlzLl9nZXRBbGxGYXRJdGVtc1hNTChlLmNoaWxkTm9kZXNbaV0udW5QYXJzZWQsMSk7ZWxzZSB2YXIgbj10aGlzLl9nZXRBbGxGYXRJdGVtcyhlLmNoaWxkTm9kZXNbaV0pO24mJih0Kz10aGlzLmRsbXRyK24pfXJldHVybiB0fSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5zZWxlY3RJdGVtPWZ1bmN0aW9uKGUsdCxpKXt0PWRoeDQuczJiKHQpO3ZhciBuPXRoaXMuX2dsb2JhbElkU3RvcmFnZUZpbmQoZSk7aWYoIW58fCFuLnBhcmVudE9iamVjdClyZXR1cm4gMDt0aGlzLlhNTGxvYWRpbmdXYXJuaW5nP24ucGFyZW50T2JqZWN0Lm9wZW5NZT0xOnRoaXMuX29wZW5JdGVtKG4ucGFyZW50T2JqZWN0KTt2YXIgbz1udWxsO2kmJihvPW5ldyBPYmplY3Qsby5jdHJsS2V5PSEwLG4uaV9zZWwmJihvLnNraXBVblNlbD0hMCkpLHQ/dGhpcy5vblJvd1NlbGVjdChvLG4uaHRtbE5vZGUuY2hpbGROb2Rlc1swXS5jaGlsZE5vZGVzWzBdLmNoaWxkTm9kZXNbM10sITEpOnRoaXMub25Sb3dTZWxlY3QobyxuLmh0bWxOb2RlLmNoaWxkTm9kZXNbMF0uY2hpbGROb2Rlc1swXS5jaGlsZE5vZGVzWzNdLCEwKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX2NvbXByZXNzQ2hpbGRMaXN0PWZ1bmN0aW9uKGUsdCl7ZS0tO2Zvcih2YXIgaT0wO2U+aTtpKyspMD09dFtpXSYmKHRbaV09dFtpKzFdLHRbaSsxXT0wKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX2RlbGV0ZU5vZGU9ZnVuY3Rpb24oZSx0LGkpe2lmKCF0fHwhdC5wYXJlbnRPYmplY3QpcmV0dXJuIDA7dmFyIG49MCxvPTA7dC50ci5uZXh0U2libGluZyYmKG49dC50ci5uZXh0U2libGluZy5ub2RlbSksdC50ci5wcmV2aW91c1NpYmxpbmcmJihvPXQudHIucHJldmlvdXNTaWJsaW5nLm5vZGVtKTtmb3IodmFyIHI9dC5wYXJlbnRPYmplY3QsbD1yLmNoaWxkc0NvdW50LHM9ci5jaGlsZE5vZGVzLGE9MDtsPmE7YSsrKWlmKHNbYV0uaWQ9PWUpe2l8fHIuaHRtbE5vZGUuY2hpbGROb2Rlc1swXS5yZW1vdmVDaGlsZChzW2FdLnRyKSxzW2FdPTA7YnJlYWt9dGhpcy5fY29tcHJlc3NDaGlsZExpc3QobCxzKSxpfHxyLmNoaWxkc0NvdW50LS0sbiYmKHRoaXMuX2NvcnJlY3RQbHVzKG4pLHRoaXMuX2NvcnJlY3RMaW5lKG4pKSxvJiYodGhpcy5fY29ycmVjdFBsdXMobyksdGhpcy5fY29ycmVjdExpbmUobykpLHRoaXMudHNjaGVjayYmdGhpcy5fY29ycmVjdENoZWNrU3RhdGVzKHIpLGl8fHRoaXMuX2dsb2JhbElkU3RvcmFnZVJlY1N1Yih0KX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuZGVsZXRlQ2hpbGRJdGVtcz1mdW5jdGlvbihlKXt2YXIgdD10aGlzLl9nbG9iYWxJZFN0b3JhZ2VGaW5kKGUpO2lmKHQpZm9yKHZhciBpPXQuY2hpbGRzQ291bnQsbj0wO2k+bjtuKyspdGhpcy5fZGVsZXRlTm9kZSh0LmNoaWxkTm9kZXNbMF0uaWQsdC5jaGlsZE5vZGVzWzBdKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX2dsb2JhbElkU3RvcmFnZVJlY1N1Yj1mdW5jdGlvbihlKXtmb3IodmFyIHQ9MDt0PGUuY2hpbGRzQ291bnQ7dCsrKXRoaXMuX2dsb2JhbElkU3RvcmFnZVJlY1N1YihlLmNoaWxkTm9kZXNbdF0pLHRoaXMuX2dsb2JhbElkU3RvcmFnZVN1YihlLmNoaWxkTm9kZXNbdF0uaWQpO3RoaXMuX2dsb2JhbElkU3RvcmFnZVN1YihlLmlkKTt2YXIgaT1lO2kuc3Bhbj1udWxsLGkudHIubm9kZW09bnVsbCxpLnRyPW51bGwsaS5odG1sTm9kZT1udWxsfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5fYXV0b1Njcm9sbD1mdW5jdGlvbihlLHQsaSl7dGhpcy5hdXRvU2Nyb2xsJiYoZSYmKHQ9ZGh4NC5hYnNUb3AoZSksaT1kaHg0LmFic1RvcCh0aGlzLmFsbFRyZWUpLXRoaXMuYWxsVHJlZS5zY3JvbGxUb3ApLHQtaS1wYXJzZUludCh0aGlzLmFsbFRyZWUuc2Nyb2xsVG9wKT5wYXJzZUludCh0aGlzLmFsbFRyZWUub2Zmc2V0SGVpZ2h0KS01MCYmKHRoaXMuYWxsVHJlZS5zY3JvbGxUb3A9cGFyc2VJbnQodGhpcy5hbGxUcmVlLnNjcm9sbFRvcCkrMjApLHQtaTxwYXJzZUludCh0aGlzLmFsbFRyZWUuc2Nyb2xsVG9wKSszMCYmKHRoaXMuYWxsVHJlZS5zY3JvbGxUb3A9cGFyc2VJbnQodGhpcy5hbGxUcmVlLnNjcm9sbFRvcCktMjApKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuZW5hYmxlVGV4dFNpZ25zPWZ1bmN0aW9uKGUpe3RoaXMuX3R4dGltZz1kaHg0LnMyYihlKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUucHJldmVudElFQ2FjaGluZz1mdW5jdGlvbihlKXtkaHg0LmFqYXguY2FjaGU9IWV9LGRodG1sWFRyZWVPYmplY3QucHJvdG90eXBlLnByZXZlbnRJRUNhc2hpbmc9ZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUucHJldmVudElFQ2FjaGluZyxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5zZXRJY29uU2l6ZT1mdW5jdGlvbihlLHQsaSl7aWYoaSl7aWYoaSYmaS5zcGFuKXZhciBuPWk7ZWxzZSB2YXIgbj10aGlzLl9nbG9iYWxJZFN0b3JhZ2VGaW5kKGkpO2lmKCFuKXJldHVybiAwO3ZhciBvPW4uc3Bhbi5wYXJlbnROb2RlLnByZXZpb3VzU2libGluZy5jaGlsZE5vZGVzWzBdO2UmJihvLnN0eWxlLndpZHRoPWUrInB4Iix3aW5kb3cuX0tIVE1McnYmJihvLnBhcmVudE5vZGUuc3R5bGUud2lkdGg9ZSsicHgiKSksdCYmKG8uc3R5bGUuaGVpZ2h0PXQrInB4Iix3aW5kb3cuX0tIVE1McnYmJihvLnBhcmVudE5vZGUuc3R5bGUuaGVpZ2h0PXQrInB4IikpfWVsc2UgdGhpcy5kZWZfaW1nX3g9ZSsicHgiLHRoaXMuZGVmX2ltZ195PXQrInB4In0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuZW5hYmxlU2luZ2xlUmFkaW9Nb2RlPWZ1bmN0aW9uKGUpe3RoaXMuX2ZyYnRycz1kaHg0LnMyYihlKX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUub3Blbk9uSXRlbUFkZGVkPWZ1bmN0aW9uKGUpe3RoaXMuX2hBZEk9IWRoeDQuczJiKGUpfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5vcGVuT25JdGVtQWRkaW5nPWZ1bmN0aW9uKGUpe3RoaXMuX2hBZEk9IWRoeDQuczJiKGUpfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5nZXRBbGxJdGVtc1dpdGhLaWRzPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX2dldEFsbEZhdEl0ZW1zKHRoaXMuaHRtbE5vZGUpfSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5zZXRTa2luPWZ1bmN0aW9uKGUpe3ZhciB0PXRoaXMucGFyZW50T2JqZWN0LmNsYXNzTmFtZS5yZXBsYWNlKC9kaHh0cmVlX1teIF0qL2dpLCIiKTt0aGlzLnBhcmVudE9iamVjdC5jbGFzc05hbWU9dCsiIGRoeHRyZWVfIitlLCgiZGh4X3RlcnJhY2UiPT1lfHwiZGh4X3dlYiI9PWV8fCJtYXRlcmlhbCI9PWUpJiZ0aGlzLmVuYWJsZVRyZWVMaW5lcyghMSksIm1hdGVyaWFsIj09ZSYmdGhpcy5zZXRJY29uU2l6ZSgiMjUiLCIyNSIpfSxqc29uUG9pbnRlci5wcm90b3R5cGU9e3RleHQ6ZnVuY3Rpb24oKXt2YXIgZT1mdW5jdGlvbihlKXtmb3IodmFyIGk9W10sbj0wO248ZS5sZW5ndGg7bisrKWkucHVzaCgieyIrdChlW25dKSsifSIpO3JldHVybiBpLmpvaW4oIiwiKX0sdD1mdW5jdGlvbihpKXt2YXIgbj1bXTtmb3IodmFyIG8gaW4gaSkib2JqZWN0Ij09dHlwZW9mIGlbb10/by5sZW5ndGg/bi5wdXNoKCciJytvKyciOlsnK2UoaVtvXSkrIl0iKTpuLnB1c2goJyInK28rJyI6eycrdChpW29dKSsifSIpOm4ucHVzaCgnIicrbysnIjoiJytpW29dKyciJyk7cmV0dXJuIG4uam9pbigiLCIpfTtyZXR1cm4ieyIrdCh0aGlzLmQpKyJ9In0sZ2V0OmZ1bmN0aW9uKGUpe3JldHVybiB0aGlzLmRbZV19LGV4aXN0czpmdW5jdGlvbigpe3JldHVybiEhdGhpcy5kfSxjb250ZW50OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZC5jb250ZW50fSxlYWNoOmZ1bmN0aW9uKGUsdCxpKXt2YXIgbj10aGlzLmRbZV0sbz1uZXcganNvblBvaW50ZXI7aWYobilmb3IodmFyIHI9MDtyPG4ubGVuZ3RoO3IrKylvLmQ9bltyXSx0LmFwcGx5KGksW28scl0pfSxnZXRfYWxsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sc3ViOmZ1bmN0aW9uKGUpe3JldHVybiBuZXcganNvblBvaW50ZXIodGhpcy5kW2VdLHRoaXMuZCl9LHN1Yl9leGlzdHM6ZnVuY3Rpb24oZSl7cmV0dXJuISF0aGlzLmRbZV19LGVhY2hfeDpmdW5jdGlvbihlLHQsaSxuLG8pe3ZhciByPXRoaXMuZFtlXSxsPW5ldyBqc29uUG9pbnRlcigwLHRoaXMuZCk7aWYocilmb3Iobz1vfHwwO288ci5sZW5ndGg7bysrKWlmKHJbb11bdF0mJihsLmQ9cltvXSwtMT09aS5hcHBseShuLFtsLG9dKSkpcmV0dXJufSx1cDpmdW5jdGlvbigpe3JldHVybiBuZXcganNvblBvaW50ZXIodGhpcy5kcCx0aGlzLmQpfSxzZXQ6ZnVuY3Rpb24oZSx0KXt0aGlzLmRbZV09dH0sY2xvbmU6ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IGpzb25Qb2ludGVyKHRoaXMuZCx0aGlzLmRwKX0sdGhyb3VnaDpmdW5jdGlvbihlLHQsaSxuLG8pe3ZhciByPXRoaXMuZFtlXTtpZihyLmxlbmd0aClmb3IodmFyIGw9MDtsPHIubGVuZ3RoO2wrKyl7aWYobnVsbCE9cltsXVt0XSYmIiIhPXJbbF1bdF0mJighaXx8cltsXVt0XT09aSkpe3ZhciBzPW5ldyBqc29uUG9pbnRlcihyW2xdLHRoaXMuZCk7bi5hcHBseShvLFtzLGxdKX12YXIgYT10aGlzLmQ7dGhpcy5kPXJbbF0sdGhpcy5zdWJfZXhpc3RzKGUpJiZ0aGlzLnRocm91Z2goZSx0LGksbixvKSx0aGlzLmQ9YX19fSxkaHRtbFhUcmVlT2JqZWN0LnByb3RvdHlwZS5sb2FkSlNPTk9iamVjdD1mdW5jdGlvbihlLHQpe3JldHVybiB3aW5kb3cuY29uc29sZSYmd2luZG93LmNvbnNvbGUuaW5mbyYmd2luZG93LmNvbnNvbGUuaW5mbygibG9hZEpTT05PYmplY3Qgd2FzIGRlcHJlY2F0ZWQiLCJodHRwOi8vZG9jcy5kaHRtbHguY29tL21pZ3JhdGlvbl9faW5kZXguaHRtbCNtaWdyYXRpb25mcm9tNDN0bzQ0IiksdGhpcy5fbG9hZEpTT05PYmplY3QoZSx0KX0sZGh0bWxYVHJlZU9iamVjdC5wcm90b3R5cGUuX2xvYWRKU09OT2JqZWN0PWZ1bmN0aW9uKGUsdCl7dGhpcy5wYXJzQ291bnR8fHRoaXMuY2FsbEV2ZW50KCJvblhMUyIsW3RoaXMsbnVsbF0pLHRoaXMueG1sc3RhdGU9MTt2YXIgaT1uZXcganNvblBvaW50ZXIoZSk7dGhpcy5fcGFyc2UoaSksdGhpcy5fcD1pLHQmJnQoKX0sd2luZG93LmFkZEV2ZW50TGlzdGVuZXI/d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLGRoeF9pbml0X3RyZWVzLCExKTp3aW5kb3cuYXR0YWNoRXZlbnQmJndpbmRvdy5hdHRhY2hFdmVudCgib25sb2FkIixkaHhfaW5pdF90cmVlcyk7dmFyIHN0eWxlPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInN0eWxlIik7c3R5bGUuaW5uZXJIVE1MPSdAa2V5ZnJhbWVzIGRoeF9sb2FkZXJfcm90YXRlezEwMCV7dHJhbnNmb3JtOnJvdGF0ZSgzNjBkZWcpO319QGtleWZyYW1lcyBkaHhfbG9hZGVyX2Rhc2h7MCV7c3Ryb2tlLWRhc2hhcnJheToxLDIwMDtzdHJva2UtZGFzaG9mZnNldDowO301MCV7c3Ryb2tlLWRhc2hhcnJheTo4OSwyMDA7c3Ryb2tlLWRhc2hvZmZzZXQ6LTM1cHg7fTEwMCV7c3Ryb2tlLWRhc2hhcnJheTo4OSwyMDA7c3Ryb2tlLWRhc2hvZmZzZXQ6LTEyNHB4O319LmRodG1seE1lbnVfbWF0ZXJpYWxfTWlkZGxle3Bvc2l0aW9uOnJlbGF0aXZlO2hlaWdodDoyOHB4O2xpbmUtaGVpZ2h0OjI4cHg7YmFja2dyb3VuZC1jb2xvcjojZjVmNWY1O292ZXJmbG93OmhpZGRlbjtib3JkZXI6bm9uZTtmb250LXNpemU6MTRweDtmb250LWZhbWlseTpSb2JvdG8sQXJpYWwsSGVsdmV0aWNhO2NvbG9yOiM0MDQwNDA7LXdlYmtpdC11c2VyLXNlbGVjdDpub25lOy1raHRtbC11c2VyLXNlbGVjdDpub25lOy1tb3otdXNlci1zZWxlY3Q6bm9uZTstbXMtdXNlci1zZWxlY3Q6bm9uZTstby11c2VyLXNlbGVjdDpub25lO3VzZXItc2VsZWN0Om5vbmU7fS5kaHRtbHhNZW51X21hdGVyaWFsX01pZGRsZSBkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9Ub3BMZXZlbF9JdGVtX05vcm1hbCwuZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfVG9wTGV2ZWxfSXRlbV9EaXNhYmxlZCwuZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfVG9wTGV2ZWxfSXRlbV9TZWxlY3RlZHtwb3NpdGlvbjpyZWxhdGl2ZTtmbG9hdDpsZWZ0O2ZvbnQ6aW5oZXJpdDtoZWlnaHQ6MjhweDtsaW5lLWhlaWdodDoyOHB4O21hcmdpbjowO3BhZGRpbmc6MCA4cHg7Y3Vyc29yOmRlZmF1bHQ7d2hpdGUtc3BhY2U6bm93cmFwOy13ZWJraXQtdXNlci1zZWxlY3Q6bm9uZTsta2h0bWwtdXNlci1zZWxlY3Q6bm9uZTstbW96LXVzZXItc2VsZWN0Om5vbmU7LW1zLXVzZXItc2VsZWN0Om5vbmU7LW8tdXNlci1zZWxlY3Q6bm9uZTt1c2VyLXNlbGVjdDpub25lO30uZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfVG9wTGV2ZWxfSXRlbV9Ob3JtYWwgZGl2LnRvcF9sZXZlbF90ZXh0LC5kaHRtbHhNZW51X21hdGVyaWFsX01pZGRsZSBkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9Ub3BMZXZlbF9JdGVtX0Rpc2FibGVkIGRpdi50b3BfbGV2ZWxfdGV4dCwuZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfVG9wTGV2ZWxfSXRlbV9TZWxlY3RlZCBkaXYudG9wX2xldmVsX3RleHR7ZmxvYXQ6bGVmdDttYXJnaW46MCAzcHg7fS5kaHRtbHhNZW51X21hdGVyaWFsX01pZGRsZSBkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9Ub3BMZXZlbF9JdGVtX05vcm1hbCBpLC5kaHRtbHhNZW51X21hdGVyaWFsX01pZGRsZSBkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9Ub3BMZXZlbF9JdGVtX0Rpc2FibGVkIGksLmRodG1seE1lbnVfbWF0ZXJpYWxfTWlkZGxlIGRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1RvcExldmVsX0l0ZW1fU2VsZWN0ZWQgaXtoZWlnaHQ6aW5oZXJpdDtsaW5lLWhlaWdodDppbmhlcml0O2Zsb2F0OmxlZnQ7Y29sb3I6aW5oZXJpdDttYXJnaW46MCA0cHg7Zm9udC1zaXplOjEuMmVtO30uZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfVG9wTGV2ZWxfSXRlbV9EaXNhYmxlZHtjb2xvcjojYTZhNmE2O30uZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfVG9wTGV2ZWxfSXRlbV9TZWxlY3RlZHtiYWNrZ3JvdW5kLWNvbG9yOiNlYmViZWI7fS5kaHRtbHhNZW51X21hdGVyaWFsX01pZGRsZSBpbWcuZGh0bWx4TWVudV9Ub3BMZXZlbF9JdGVtX0ljb257ZmxvYXQ6bGVmdDttYXJnaW46NXB4IDNweCAwIDNweDt3aWR0aDoxOHB4O2hlaWdodDoxOHB4O2N1cnNvcjpkZWZhdWx0O30uZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LnRvcF9zZXB7cG9zaXRpb246cmVsYXRpdmU7ZmxvYXQ6bGVmdDtoZWlnaHQ6MjJweDt3aWR0aDowO2JvcmRlci1sZWZ0OjFweCBzb2xpZCAjZGZkZmRmO21hcmdpbjozcHggOHB4IDAgOHB4O2ZvbnQtc2l6ZToxcHg7b3ZlcmZsb3c6aGlkZGVuO2N1cnNvcjpkZWZhdWx0Oy13ZWJraXQtdXNlci1zZWxlY3Q6bm9uZTsta2h0bWwtdXNlci1zZWxlY3Q6bm9uZTstbW96LXVzZXItc2VsZWN0Om5vbmU7LW1zLXVzZXItc2VsZWN0Om5vbmU7LW8tdXNlci1zZWxlY3Q6bm9uZTt1c2VyLXNlbGVjdDpub25lO30uZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LmRodG1seE1lbnVfVG9wTGV2ZWxfVGV4dF9yaWdodCwuZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LmRodG1seE1lbnVfVG9wTGV2ZWxfVGV4dF9sZWZ0e3Bvc2l0aW9uOmFic29sdXRlO3RvcDowO2hlaWdodDoyOHB4O2xpbmUtaGVpZ2h0OjI4cHg7Y3Vyc29yOmRlZmF1bHQ7Zm9udC1zaXplOjE0cHg7Zm9udC1mYW1pbHk6Um9ib3RvLEFyaWFsLEhlbHZldGljYTtjb2xvcjojNDA0MDQwOy13ZWJraXQtdXNlci1zZWxlY3Q6bm9uZTsta2h0bWwtdXNlci1zZWxlY3Q6bm9uZTstbW96LXVzZXItc2VsZWN0Om5vbmU7LW1zLXVzZXItc2VsZWN0Om5vbmU7LW8tdXNlci1zZWxlY3Q6bm9uZTt1c2VyLXNlbGVjdDpub25lO30uZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUgZGl2LmRodG1seE1lbnVfVG9wTGV2ZWxfVGV4dF9yaWdodHtyaWdodDo2cHg7fS5kaHRtbHhNZW51X21hdGVyaWFsX01pZGRsZSBkaXYuZGh0bWx4TWVudV9Ub3BMZXZlbF9UZXh0X2xlZnR7bGVmdDo2cHg7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29ue3Bvc2l0aW9uOmFic29sdXRlO3BhZGRpbmc6NXB4IDA7YmFja2dyb3VuZC1jb2xvcjojZmFmYWZhO292ZXJmbG93OmhpZGRlbjtjdXJzb3I6ZGVmYXVsdDtsaW5lLWhlaWdodDpub3JtYWw7b3ZlcmZsb3cteTphdXRvOy13ZWJraXQtb3ZlcmZsb3ctc2Nyb2xsaW5nOnRvdWNoOy13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjpyZ2JhKDAsMCwwLDApO2JveC1zaGFkb3c6MCAxcHggM3B4IHJnYmEoMCwwLDAsMC4xMiksMCAxcHggMnB4IHJnYmEoMCwwLDAsMC4yNCk7LXdlYmtpdC11c2VyLXNlbGVjdDpub25lOy1raHRtbC11c2VyLXNlbGVjdDpub25lOy1tb3otdXNlci1zZWxlY3Q6bm9uZTstbXMtdXNlci1zZWxlY3Q6bm9uZTstby11c2VyLXNlbGVjdDpub25lO3VzZXItc2VsZWN0Om5vbmU7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRke3BhZGRpbmc6MDttYXJnaW46MDtsaW5lLWhlaWdodDpub3JtYWw7d2hpdGUtc3BhY2U6bm93cmFwO2ZvbnQtc2l6ZToxNHB4O2ZvbnQtZmFtaWx5OlJvYm90byxBcmlhbCxIZWx2ZXRpY2E7Y29sb3I6IzQwNDA0MDt9ZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gdGQuc3ViX2l0ZW1faWNvbnt3aWR0aDoxOHB4O3RleHQtYWxpZ246Y2VudGVyO31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ZC5zdWJfaXRlbV9pY29uIGltZy5zdWJfaWNvbnttYXJnaW46NHB4IDZweCAwIDZweDt3aWR0aDoxOHB4O2hlaWdodDoxOHB4O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ZC5zdWJfaXRlbV9pY29uIGl7d2lkdGg6MThweDtoZWlnaHQ6MzBweDtsaW5lLWhlaWdodDoyOXB4O21hcmdpbjowIDZweDtmb250LXNpemU6MS4yZW07dGV4dC1hbGlnbjpjZW50ZXI7Y29sb3I6aW5oZXJpdDt9ZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gdGQuc3ViX2l0ZW1faWNvbiBkaXYuc3ViX2ljb257bWFyZ2luOjAgNnB4O3dpZHRoOjE4cHg7aGVpZ2h0OjMwcHg7bGluZS1oZWlnaHQ6MzBweDtiYWNrZ3JvdW5kLXBvc2l0aW9uOjAgNXB4O2JhY2tncm91bmQtcmVwZWF0Om5vLXJlcGVhdDtiYWNrZ3JvdW5kLWltYWdlOnVybCgiaW1ncy9kaHhtZW51X21hdGVyaWFsL2RoeG1lbnVfY2hyZC5wbmciKTt9ZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gdGQuc3ViX2l0ZW1faWNvbiBkaXYuc3ViX2ljb24uY2hieF8we2JhY2tncm91bmQtcG9zaXRpb246MCA1cHg7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRkLnN1Yl9pdGVtX2ljb24gZGl2LnN1Yl9pY29uLmNoYnhfMXtiYWNrZ3JvdW5kLXBvc2l0aW9uOi0xOHB4IDVweDt9ZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gdGQuc3ViX2l0ZW1faWNvbiBkaXYuc3ViX2ljb24ucmRidF8we2JhY2tncm91bmQtcG9zaXRpb246LTcycHggNXB4O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ZC5zdWJfaXRlbV9pY29uIGRpdi5zdWJfaWNvbi5yZGJ0XzF7YmFja2dyb3VuZC1wb3NpdGlvbjotOTBweCA1cHg7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRkLnN1Yl9pdGVtX3RleHQgZGl2LnN1Yl9pdGVtX3RleHR7cG9zaXRpb246cmVsYXRpdmU7aGVpZ2h0OjMwcHg7bGluZS1oZWlnaHQ6MzBweDtwYWRkaW5nOjAgMjJweCAwIDFweDtvdmVyZmxvdzpoaWRkZW47fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRkLnN1Yl9pdGVtX2hre3BhZGRpbmc6MCAxMHB4IDAgOHB4O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ZC5zdWJfaXRlbV9oayBkaXYuc3ViX2l0ZW1faGt7Y29sb3I6IzhkOGQ4ZDtmb250LXNpemU6MTJweDt0ZXh0LWFsaWduOnJpZ2h0O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ZCBkaXYuY29tcGxleF9hcnJvd3tmbG9hdDpyaWdodDt3aWR0aDoxMHB4O21hcmdpbjowIDFweCAwIDExcHg7aGVpZ2h0OjMwcHg7bGluZS1oZWlnaHQ6MzBweDtiYWNrZ3JvdW5kLWltYWdlOnVybCgiaW1ncy9kaHhtZW51X21hdGVyaWFsL2RoeG1lbnVfc3ViYXIucG5nIik7YmFja2dyb3VuZC1yZXBlYXQ6bm8tcmVwZWF0O2JhY2tncm91bmQtcG9zaXRpb246MCAxMHB4O292ZXJmbG93OmhpZGRlbjtmb250LXNpemU6MXB4O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ZCBkaXYuY29tcGxleF9hcnJvd19sb2FkaW5ne3dpZHRoOjE2cHg7aGVpZ2h0OjMwcHg7bGluZS1oZWlnaHQ6MzBweDtiYWNrZ3JvdW5kLXBvc2l0aW9uOmNlbnRlciBjZW50ZXI7YmFja2dyb3VuZC1yZXBlYXQ6bm8tcmVwZWF0O2JhY2tncm91bmQtaW1hZ2U6dXJsKCJpbWdzL2RoeG1lbnVfbWF0ZXJpYWwvZGh4bWVudV9sb2FkZXIuZ2lmIik7ZmxvYXQ6cmlnaHQ7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRyLnN1Yl9pdGVtX3NlbGVjdGVkIHRke2JhY2tncm91bmQtY29sb3I6I2ViZWJlYjt9ZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gdHIuc3ViX2l0ZW1fc2VsZWN0ZWQgdGQgZGl2LmNvbXBsZXhfYXJyb3d7YmFja2dyb3VuZC1wb3NpdGlvbjotMTBweCAxMHB4O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ci5zdWJfaXRlbV9kaXMgdGQuc3ViX2l0ZW1faGsgZGl2LnN1Yl9pdGVtX2hre2NvbG9yOiNjMGMwYzA7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRyLnN1Yl9pdGVtX2RpcyB0ZCBkaXYuc3ViX2l0ZW1fdGV4dCxkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ci5zdWJfaXRlbV9kaXMgdGQgdGQuc3ViX2l0ZW1faWNvbiBpe2NvbG9yOiNhNmE2YTY7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRyLnN1Yl9pdGVtX2RpcyB0ZCBkaXYuY29tcGxleF9hcnJvd3tiYWNrZ3JvdW5kLXBvc2l0aW9uOi0yMHB4IDEwcHg7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRyLnN1Yl9pdGVtX2RpcyB0ZCBkaXYuc3ViX2ljb24uY2hieF8we2JhY2tncm91bmQtcG9zaXRpb246LTM2cHggNXB4O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ci5zdWJfaXRlbV9kaXMgdGQgZGl2LnN1Yl9pY29uLmNoYnhfMXtiYWNrZ3JvdW5kLXBvc2l0aW9uOi01NHB4IDVweDt9ZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gdHIuc3ViX2l0ZW1fZGlzIHRkIGRpdi5zdWJfaWNvbi5yZGJ0XzB7YmFja2dyb3VuZC1wb3NpdGlvbjotMTA4cHggNXB4O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ci5zdWJfaXRlbV9kaXMgdGQgZGl2LnN1Yl9pY29uLnJkYnRfMXtiYWNrZ3JvdW5kLXBvc2l0aW9uOi0xMjZweCA1cHg7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRyLnN1Yl9pdGVtX2RpcyB0ZCBpe2NvbG9yOiNhNmE2YTY7fWRpdi5kaHRtbHhNZW51X21hdGVyaWFsX1N1YkxldmVsQXJlYV9Qb2x5Z29uIHRyLnN1Yl9zZXAgdGR7cGFkZGluZzo1cHggM3B4O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiB0ci5zdWJfc2VwIHRkIGRpdi5zdWJfc2Vwe3Bvc2l0aW9uOnJlbGF0aXZlO2ZvbnQtc2l6ZToxcHg7bGluZS1oZWlnaHQ6MXB4O2hlaWdodDowO3dpZHRoOjEwMCU7Ym9yZGVyLXRvcDoxcHggc29saWQgI2RmZGZkZjt9ZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX0Fycm93VXAsZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX0Fycm93VXBfT3ZlcixkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiBkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfQXJyb3dVcF9EaXNhYmxlZHtwb3NpdGlvbjpyZWxhdGl2ZTtmb250LXNpemU6MXB4O2JvcmRlci1ib3R0b206MXB4IHNvbGlkICNkZmRmZGY7YmFja2dyb3VuZC1pbWFnZTp1cmwoImltZ3MvZGh4bWVudV9tYXRlcmlhbC9kaHhtZW51X2Fycm93X3VwLnBuZyIpO2JhY2tncm91bmQtcmVwZWF0Om5vLXJlcGVhdDtiYWNrZ3JvdW5kLXBvc2l0aW9uOmNlbnRlciAycHg7cGFkZGluZzo4cHggMDttYXJnaW4tYm90dG9tOjNweDt9ZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX0Fycm93VXBfRGlzYWJsZWR7YmFja2dyb3VuZC1pbWFnZTp1cmwoImltZ3MvZGh4bWVudV9tYXRlcmlhbC9kaHhtZW51X2Fycm93X3VwX2Rpcy5wbmciKTt9ZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX0Fycm93RG93bixkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiBkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfQXJyb3dEb3duX092ZXIsZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX1BvbHlnb24gZGl2LmRodG1seE1lbnVfbWF0ZXJpYWxfU3ViTGV2ZWxBcmVhX0Fycm93RG93bl9EaXNhYmxlZHtwb3NpdGlvbjpyZWxhdGl2ZTtmb250LXNpemU6MXB4O2JvcmRlci10b3A6MXB4IHNvbGlkICNkZmRmZGY7YmFja2dyb3VuZC1pbWFnZTp1cmwoImltZ3MvZGh4bWVudV9tYXRlcmlhbC9kaHhtZW51X2Fycm93X2Rvd24ucG5nIik7YmFja2dyb3VuZC1yZXBlYXQ6bm8tcmVwZWF0O2JhY2tncm91bmQtcG9zaXRpb246Y2VudGVyIDZweDtwYWRkaW5nOjhweCAwO21hcmdpbi10b3A6M3B4O31kaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfUG9seWdvbiBkaXYuZGh0bWx4TWVudV9tYXRlcmlhbF9TdWJMZXZlbEFyZWFfQXJyb3dEb3duX0Rpc2FibGVke2JhY2tncm91bmQtaW1hZ2U6dXJsKCJpbWdzL2RoeG1lbnVfbWF0ZXJpYWwvZGh4bWVudV9hcnJvd19kb3duX2Rpcy5wbmciKTt9aWZyYW1lLmRodG1seE1lbnVfSUU2Q292ZXJGaXhfbWF0ZXJpYWx7cG9zaXRpb246YWJzb2x1dGU7Ym9yZGVyOm5vbmU7YmFja2dyb3VuZDojMDAwO2ZpbHRlcjpwcm9naWQ6RFhJbWFnZVRyYW5zZm9ybS5NaWNyb3NvZnQuQWxwaGEob3BhY2l0eT0xMDApO30uZGh0bWx4TWVudV9tYXRlcmlhbF9NaWRkbGUuZGlyX2xlZnQgZGl2LmFsaWduX2xlZnR7ZmxvYXQ6bGVmdDt9LmRodG1seE1lbnVfbWF0ZXJpYWxfTWlkZGxlLmRpcl9sZWZ0IGRpdi5hbGlnbl9yaWdodHtmbG9hdDpyaWdodDt9LmRoeG1lbnVfc2tpbl9kZXRlY3R7cG9zaXRpb246YWJzb2x1dGU7bGVmdDowO3RvcDotMTAwcHg7bWFyZ2luOjA7cGFkZGluZzowO2JvcmRlcjowIHNvbGlkIHdoaXRlO3dpZHRoOjQwcHg7aGVpZ2h0OjEwcHg7b3ZlcmZsb3c6aGlkZGVuO31Aa2V5ZnJhbWVzIGRoeF9sb2FkZXJfcm90YXRlezEwMCV7dHJhbnNmb3JtOnJvdGF0ZSgzNjBkZWcpO319QGtleWZyYW1lcyBkaHhfbG9hZGVyX2Rhc2h7MCV7c3Ryb2tlLWRhc2hhcnJheToxLDIwMDtzdHJva2UtZGFzaG9mZnNldDowO301MCV7c3Ryb2tlLWRhc2hhcnJheTo4OSwyMDA7c3Ryb2tlLWRhc2hvZmZzZXQ6LTM1cHg7fTEwMCV7c3Ryb2tlLWRhc2hhcnJheTo4OSwyMDA7c3Ryb2tlLWRhc2hvZmZzZXQ6LTEyNHB4O319LmRlZmF1bHRUcmVlVGFibGV7bWFyZ2luOjA7cGFkZGluZzowO2JvcmRlcjowO30uY29udGFpbmVyVGFibGVTdHlsZXtvdmVyZmxvdzphdXRvOy13ZWJraXQtb3ZlcmZsb3ctc2Nyb2xsaW5nOnRvdWNoO3Bvc2l0aW9uOnJlbGF0aXZlO3RvcDowO2ZvbnQtc2l6ZToxMnB4Oy1raHRtbC11c2VyLXNlbGVjdDpub25lO30uY29udGFpbmVyVGFibGVTdHlsZVJUTCBzcGFue2RpcmVjdGlvbjpydGw7dW5pY29kZS1iaWRpOmJpZGktb3ZlcnJpZGU7fS5jb250YWluZXJUYWJsZVN0eWxlUlRMe2RpcmVjdGlvbjpydGw7b3ZlcmZsb3c6YXV0bztwb3NpdGlvbjpyZWxhdGl2ZTt0b3A6MDtmb250LXNpemU6MTJweDt9LnN0YW5kYXJ0VHJlZVJvd3tmb250LWZhbWlseTpSb2JvdG8sQXJpYWwsSGVsdmV0aWNhO2ZvbnQtc2l6ZTo7LW1vei11c2VyLXNlbGVjdDpub25lO2xpbmUtaGVpZ2h0OjI0cHg7fS5zZWxlY3RlZFRyZWVSb3d7Zm9udC1mYW1pbHk6Um9ib3RvLEFyaWFsLEhlbHZldGljYTtmb250LXNpemU6Oy1tb3otdXNlci1zZWxlY3Q6bm9uZTtiYWNrZ3JvdW5kLWNvbG9yOiNlZWU7Y29sb3I6IzM5Yzt9LmRoeHRyZWVfbWF0ZXJpYWwgLnNlbGVjdGVkVHJlZVJvd0Z1bGwgLmRoeFRleHRDZWxse2JhY2tncm91bmQtY29sb3I6I2VlZTtjb2xvcjojMzljO30uZHJhZ0FuZERyb3BSb3d7Y29sb3I6IzM5Yzt9LnN0YW5kYXJ0VHJlZVJvd19sb3J7dGV4dC1kZWNvcmF0aW9uOnVuZGVybGluZTtiYWNrZ3JvdW5kLWNvbG9yOjtmb250LWZhbWlseTpSb2JvdG8sQXJpYWwsSGVsdmV0aWNhO2ZvbnQtc2l6ZTo7LW1vei11c2VyLXNlbGVjdDpub25lO30uc3RhbmRhcnRUcmVlSW1hZ2V7aGVpZ2h0OjI0cHg7b3ZlcmZsb3c6aGlkZGVuO2JvcmRlcjowO3BhZGRpbmc6MDttYXJnaW46MDtmb250LXNpemU6MXB4O30uc3RhbmRhcnRUcmVlSW1hZ2UgaW1ne3dpZHRoOjE4cHg7aGVpZ2h0OjI0cHg7YmFja2dyb3VuZC1wb3NpdGlvbjpjZW50ZXIgY2VudGVyO2JhY2tncm91bmQtcmVwZWF0Om5vLXJlcGVhdDtib3JkZXI6MDtwYWRkaW5nOjA7bWFyZ2luOjA7Zm9udC1zaXplOjFweDstd2Via2l0LXVzZXItc2VsZWN0Om5vbmU7LWtodG1sLXVzZXItc2VsZWN0Om5vbmU7LW1vei11c2VyLXNlbGVjdDpub25lOy1tcy11c2VyLXNlbGVjdDpub25lOy1vLXVzZXItc2VsZWN0Om5vbmU7dXNlci1zZWxlY3Q6bm9uZTt9LmhpZGRlblJvd3t3aWR0aDoxcHg7b3ZlcmZsb3c6aGlkZGVuO30uZHJhZ1NwYW5EaXYsLmRyYWdTcGFuRGl2IHRke2ZvbnQtZmFtaWx5OlJvYm90byxBcmlhbCxIZWx2ZXRpY2E7Zm9udC1zaXplOjtsaW5lLWhlaWdodDo7dmVydGljYWwtYWxpZ246Y2VudGVyO2JhY2tncm91bmQtY29sb3I6d2hpdGU7ei1pbmRleDo5OTk7fS5kcmFnU3BhbkRpdiB0ZHtwYWRkaW5nOjVweDt9LmFfZGh4X2hpZGRlbl9pbnB1dHtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6LTFweDtsZWZ0Oi0xcHg7d2lkdGg6MXB4O2hlaWdodDoxcHg7Ym9yZGVyOm5vbmU7YmFja2dyb3VuZDpub25lO30uYV9kaHhfaGlkZGVuX2lucHV0e3Bvc2l0aW9uOmFic29sdXRlO3RvcDotMXB4O2xlZnQ6LTFweDt3aWR0aDoxcHg7aGVpZ2h0OjFweDtib3JkZXI6bm9uZTtiYWNrZ3JvdW5kOm5vbmU7fS5zZWxlY3Rpb25CYXJ7dG9wOjA7YmFja2dyb3VuZC1jb2xvcjpibGFjaztwb3NpdGlvbjphYnNvbHV0ZTtvdmVyZmxvdzpoaWRkZW47aGVpZ2h0OjJweDt6LWluZGV4OjExO30uaW50cmVlZWRpdFJvd3tmb250LXNpemU6OHB0O2hlaWdodDoxNnB4O2JvcmRlcjoxcHggc29saWQgc2lsdmVyO3BhZGRpbmc6MDttYXJnaW46MDttYXJnaW4tbGVmdDo0cHg7LW1vei11c2VyLXNlbGVjdDp0ZXh0Oy1raHRtbC11c2VyLXNlbGVjdDp0ZXh0O30uZGh4X3RyZWVfdGV4dFNpZ257Zm9udC1zaXplOjhwdDtmb250LWZhbWlseTptb25vc3BhY2U7d2lkdGg6MjFweDtjb2xvcjo7cGFkZGluZzowO21hcmdpbjowO2N1cnNvcjpwb2ludGVyO3RleHQtYWxpZ246Y2VudGVyO30uZGh4X3RyZWVfb3BhY2l0eXtvcGFjaXR5OjA7ZmlsdGVyOnByb2dpZDpEWEltYWdlVHJhbnNmb3JtLk1pY3Jvc29mdC5BbHBoYShvcGFjaXR5PTApOy13ZWJraXQtdXNlci1zZWxlY3Q6bm9uZTsta2h0bWwtdXNlci1zZWxlY3Q6bm9uZTstbW96LXVzZXItc2VsZWN0Om5vbmU7LW1zLXVzZXItc2VsZWN0Om5vbmU7LW8tdXNlci1zZWxlY3Q6bm9uZTt1c2VyLXNlbGVjdDpub25lO30uZGh4X2JnX2ltZ19maXh7d2lkdGg6MThweDtoZWlnaHQ6MjRweDtiYWNrZ3JvdW5kLXJlcGVhdDpuby1yZXBlYXQ7YmFja2dyb3VuZC1wb3NpdGlvbjpjZW50ZXI7YmFja2dyb3VuZC1wb3NpdGlvbi14OmNlbnRlcjtiYWNrZ3JvdW5kLXBvc2l0aW9uLXk6Y2VudGVyO30uZGh4dHJlZV9za2luX2RldGVjdHtwb3NpdGlvbjphYnNvbHV0ZTtsZWZ0OjA7dG9wOi0xMDBweDttYXJnaW46MDtwYWRkaW5nOjA7Ym9yZGVyOjAgc29saWQgd2hpdGU7d2lkdGg6NDBweDtoZWlnaHQ6MTBweDtvdmVyZmxvdzpoaWRkZW47fScsZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzdHlsZSk7dmFyIGxheWFhaXJfZGVidWdfdmlldz17fTt3aW5kb3cubGF5YWFpcl9kZWJ1Z192aWV3PWxheWFhaXJfZGVidWdfdmlldyxsYXlhYWlyX2RlYnVnX3ZpZXcuaW5pdExheWFBaXJEZWJ1Z1ZpZXc9ZnVuY3Rpb24oZSl7ZS5zdHlsZS5ib3JkZXI9IjFweCBzb2xpZCBibGFjayI7dmFyIHQ9TWF0aC5taW4oMjUwLC4zKmUub2Zmc2V0V2lkdGgpLGk9JzxkaXYgY2xhc3M9InRvcC1iYW5uZXIiPlxuPC9kaXY+XG48ZGl2PlxuPGRpdiBzdHlsZT0ib3ZlcmZsb3c6aGlkZGVuOyBib3JkZXItYm90dG9tOjFweCBzb2xpZCAjNDQ0OyBwYWRkaW5nOjVweCI+XG48ZGl2IHN0eWxlPSJmbG9hdDpsZWZ0Ij5cbjxidXR0b24gaWQ9Im5vZGVfZnVuY3Rpb25hbGl0eV9jb250cm9sIj7lrqHmn6XlhYPntKA8L2J1dHRvbj5cbjxidXR0b24gaWQ9InJlZnJlc2hfY29udHJvbCI+5Yi35pawPC9idXR0b24+XG48L2Rpdj5cbjxkaXYgc3R5bGU9ImZsb2F0OnJpZ2h0Ij5cbjxpbnB1dCB0eXBlPSJjaGVja2JveCIgaWQ9InNob3dfY3VycmVudF9jYWNoZV9jb250cm9sIj7mmL7npLpjYWNoZemHjee7mDwvaW5wdXQ+XG48aW5wdXQgdHlwZT0iY2hlY2tib3giIGlkPSJzaG93X2FsbF9jYWNoZV9jb250cm9sIj7mmL7npLpjYWNoZeWMuuWfnzwvaW5wdXQ+XG48aW5wdXQgdHlwZT0iY2hlY2tib3giIGlkPSJzaG93X2F0bGFzX2NvbnRyb2wiPuaYvuekuuaWh+Wtl+WbvumbhjwvaW5wdXQ+XG48L2Rpdj5cbjwvZGl2PlxuPGRpdiBjbGFzcz0iaGdyb3VwIj5cbjxkaXYgc3R5bGU9ImZsb2F0OmxlZnQ7d2lkdGg6Jyt0KydweDsgYm9yZGVyLXJpZ2h0OjFweCBzb2xpZCBibGFjayIgaWQ9InRyZWVfY29udGFpbmVyIj48L2Rpdj5cbjxkaXYgc3R5bGU9Im92ZXJmbG93OmhpZGRlbiI+XG48ZGl2IGlkPSJjb250ZW50X3Rvb2xiYXIiIHN0eWxlPSJ3aWR0aDoxMDAlO21hcmdpbjoxMHB4Ij48aW5wdXQgdHlwZT0iY2hlY2tib3giIGlkPSJ2aXNpYmlsaXR5X2NvbnRyb2wiPuWPr+ingTwvaW5wdXQ+XG48aW5wdXQgdHlwZT0iY2hlY2tib3giIGlkPSJzaG93X2JvcmRlcl9jb250cm9sIj7mmL7npLrovrnmoYY8L2lucHV0PlxuPGJ1dHRvbiBpZD0ibG9nX2luZm9fY29udHJvbCI+5omT5Y2w5Yiw5o6n5Yi25Y+wPC9idXR0b24+XG48YnV0dG9uIGlkPSJlbmFibGVkX25vZGVfY2hhaW5fY29udHJvbCI+ZW5hYmxl6ZO+PC9idXR0b24+XG48YnV0dG9uIGlkPSJzaXplX2NoYWluX2NvbnRyb2wiPnNpemXpk748L2J1dHRvbj5cbjwvZGl2PjxkaXYgc3R5bGU9Im92ZXJmbG93OmF1dG8iPjx0YWJsZSBpZD0iY29udGVudF90YWJsZSIgc3R5bGU9ImJvcmRlcjoxcHggc29saWQgI2NjY2NjYztib3JkZXItY29sbGFwc2U6Y29sbGFwc2UiPjwvdGFibGU+XG48L2Rpdj48L2Rpdj5cbjwvZGl2PlxuPC9kaXY+JztlLmlubmVySFRNTD1pLHRoaXMuY29udGFpbmVyPWUsdGhpcy50cmVlPW5ldyBkaHRtbFhUcmVlT2JqZWN0KHRyZWVfY29udGFpbmVyLCIxMDAlIiwiMTAwJSIsMCksbm9kZV9mdW5jdGlvbmFsaXR5X2NvbnRyb2wub25jbGljaz1mdW5jdGlvbihlKXtlLnN0b3BQcm9wYWdhdGlvbigpLGxheWFhaXJfZGVidWdfdmlldy5vbl9pbnNwZWN0X2VsZW1lbnRfY2FsbGJhY2soKSxub2RlX2Z1bmN0aW9uYWxpdHlfY29udHJvbC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3I9IiNGRkYiLG5vZGVfZnVuY3Rpb25hbGl0eV9jb250cm9sLnN0eWxlLmNvbG9yPSJyZ2IoMTA3LCAxNjMsIDI1NSkifX0sbGF5YWFpcl9kZWJ1Z192aWV3LnNldFRyZWU9ZnVuY3Rpb24oZSl7Zm9yKHZhciB0PXRoaXMudHJlZS5nZXRBbGxJdGVtc1dpdGhLaWRzKCkuc3BsaXQoIiwiKSxpPVtdLG49MDtuPHQubGVuZ3RoO24rKyl7dmFyIG89dFtuXSxyPXRoaXMudHJlZS5nZXRPcGVuU3RhdGUobyk7MT09ciYmaS5wdXNoKG8pfXRoaXMudHJlZS5kZWxldGVDaGlsZEl0ZW1zKDApLHRoaXMudHJlZS5wYXJzZShlLCJqc29uIik7Zm9yKHZhciBuPTA7bjxpLmxlbmd0aDtuKyspdGhpcy50cmVlLm9wZW5JdGVtKGlbbl0pfSxsYXlhYWlyX2RlYnVnX3ZpZXcucmVzaXplPWZ1bmN0aW9uKGUsdCl7dGhpcy5jb250YWluZXIuc3R5bGUud2lkdGg9ZSsicHgiLHRoaXMuY29udGFpbmVyLnN0eWxlLmhlaWdodD10KyJweCI7dmFyIGk9dGhpcy5jb250YWluZXIub2Zmc2V0SGVpZ2h0LXRyZWVfY29udGFpbmVyLm9mZnNldFRvcDt0cmVlX2NvbnRhaW5lci5zdHlsZS5oZWlnaHQ9aSsicHgiLGNvbnRlbnRfdG9vbGJhci5zdHlsZS53aWR0aD1lLXRyZWVfY29udGFpbmVyLm9mZnNldFdpZHRoKyJweCIsY29udGVudF90YWJsZS5wYXJlbnRFbGVtZW50LnN0eWxlLmhlaWdodD1pLWNvbnRlbnRfdG9vbGJhci5vZmZzZXRIZWlnaHQtMjErInB4Iixjb250ZW50X3RhYmxlLnN0eWxlLndpZHRoPWUtdHJlZV9jb250YWluZXIub2Zmc2V0V2lkdGgtMTYrInB4In0sbGF5YWFpcl9kZWJ1Z192aWV3LmJvdW5jZVVwSW5zcGVjdEJ1dHRvbj1mdW5jdGlvbigpe25vZGVfZnVuY3Rpb25hbGl0eV9jb250cm9sLnN0eWxlLmJhY2tncm91bmRDb2xvcj0iYnV0dG9uZmFjZSIsbm9kZV9mdW5jdGlvbmFsaXR5X2NvbnRyb2wuc3R5bGUuY29sb3I9ImJsYWNrIn0sbGF5YWFpcl9kZWJ1Z192aWV3LnNldFZhbHVlSW5wdXRIYW5kbGVyPWZ1bmN0aW9uKGUpe3RoaXMudmFsdWVfaW5wdXRfY2FsbGJhY2s9ZX0sbGF5YWFpcl9kZWJ1Z192aWV3LnNldFZhbHVlQ2hhbmdlSGFuZGxlcj1mdW5jdGlvbihlKXt0aGlzLnZhbHVlX2NoYW5nZV9jYWxsYmFjaz1lfSxsYXlhYWlyX2RlYnVnX3ZpZXcuYWRkQ29udGVudD1mdW5jdGlvbihlKXt2YXIgdD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJ0ciIpO3QuaW5uZXJIVE1MPSc8dGQgc3R5bGU9IndpZHRoOjEwMHB4O2ZvbnQtc2l6ZToxM3B4O2JvcmRlcjoxcHggc29saWQgI0NDQztwYWRkaW5nLWxlZnQ6MTBweCI+JytlLmtleSsnPC90ZD5cbjx0ZCBzdHlsZT0id2lkdGg6MjAwcHg7Ym9yZGVyOjFweCBzb2xpZCAjQ0NDOyI+PGlucHV0IHN0eWxlPSJib3JkZXI6bm9uZTt3aWR0aDoxMDAlO2hlaWdodDoyNXB4O3BhZGRpbmctbGVmdDoxMHB4OyIgdmFsdWU9JytlLnZhbHVlKyI+PC90ZD4iLGNvbnRlbnRfdGFibGUuYXBwZW5kQ2hpbGQodCk7dmFyIGk9dC5sYXN0RWxlbWVudENoaWxkLmxhc3RFbGVtZW50Q2hpbGQ7aS5kYXRhPWUsaS5vbmlucHV0PWZ1bmN0aW9uKGUpe3RoaXMudmFsdWVfaW5wdXRfY2FsbGJhY2smJnRoaXMudmFsdWVfaW5wdXRfY2FsbGJhY2soZS50YXJnZXQuZGF0YSxlLnRhcmdldC52YWx1ZSl9LmJpbmQodGhpcyksaS5vbmNoYW5nZT1mdW5jdGlvbihlKXt0aGlzLnZhbHVlX2NoYW5nZV9jYWxsYmFjayYmdGhpcy52YWx1ZV9jaGFuZ2VfY2FsbGJhY2soZS50YXJnZXQuZGF0YSxlLnRhcmdldC52YWx1ZSl9LmJpbmQodGhpcyl9LGxheWFhaXJfZGVidWdfdmlldy5zZXRDb250ZW50cz1mdW5jdGlvbihlKXtjb250ZW50X3RhYmxlLmlubmVySFRNTD0iIjtmb3IodmFyIHQ9MDt0PGUubGVuZ3RoO3QrKyl7dmFyIGk9ZVt0XTt0aGlzLmFkZENvbnRlbnQoaSl9fSxsYXlhYWlyX2RlYnVnX3ZpZXcuY2hhbmdlVmFsdWVBdD1mdW5jdGlvbihlLHQpe2NvbnRlbnRfdGFibGUuY2hpbGRyZW5bZV0ubGFzdEVsZW1lbnRDaGlsZC5maXJzdEVsZW1lbnRDaGlsZC52YWx1ZT10fSxsYXlhYWlyX2RlYnVnX3ZpZXcuY2hhbmdlVmFsdWVCeUxhYmVsPWZ1bmN0aW9uKGUsdCl7Zm9yKHZhciBpPWNvbnRlbnRfdGFibGUuY2hpbGRyZW4ubGVuZ3RoLTE7aT49MDtpLS0paWYoY29udGVudF90YWJsZS5jaGlsZHJlbltpXS5maXJzdEVsZW1lbnRDaGlsZC5pbm5lclRleHQ9PWUpe2NvbnRlbnRfdGFibGUuY2hpbGRyZW5baV0ubGFzdEVsZW1lbnRDaGlsZC5maXJzdEVsZW1lbnRDaGlsZC52YWx1ZT10O2JyZWFrfX0sbGF5YWFpcl9kZWJ1Z192aWV3LnNldFZpc2liaWxpdHk9ZnVuY3Rpb24oZSl7dmlzaWJpbGl0eV9jb250cm9sLmNoZWNrZWQ9ISFlfSxsYXlhYWlyX2RlYnVnX3ZpZXcuc2V0U2hvd0RlYnVnQm9yZGVyPWZ1bmN0aW9uKGUpe3Nob3dfYm9yZGVyX2NvbnRyb2wuY2hlY2tlZD0hIWV9LGxheWFhaXJfZGVidWdfdmlldy5nZXRWaXNpYmlsaXR5PWZ1bmN0aW9uKCl7cmV0dXJuIHZpc2liaWxpdHlfY29udHJvbC5jaGVja2VkfSxsYXlhYWlyX2RlYnVnX3ZpZXcuZ2V0U2hvd0RlYnVnQm9yZGVyPWZ1bmN0aW9uKCl7cmV0dXJuIHNob3dfYm9yZGVyX2NvbnRyb2wuY2hlY2tlZH0sbGF5YWFpcl9kZWJ1Z192aWV3LmdldFNob3dDdXJyZW50Q2FjaGU9ZnVuY3Rpb24oKXtyZXR1cm4gc2hvd19jdXJyZW50X2NhY2hlX2NvbnRyb2wuY2hlY2tlZH0sbGF5YWFpcl9kZWJ1Z192aWV3LmdldFNob3dBbGxDYWNoZT1mdW5jdGlvbigpe3JldHVybiBzaG93X2FsbF9jYWNoZV9jb250cm9sLmNoZWNrZWR9LGxheWFhaXJfZGVidWdfdmlldy5nZXRTaG93QXRsYXM9ZnVuY3Rpb24oKXtyZXR1cm4gc2hvd19hdGxhc19jb250cm9sLmNoZWNrZWR9LGxheWFhaXJfZGVidWdfdmlldy5vbkluc3BlY3RFbGVtZW50PWZ1bmN0aW9uKGUpe3RoaXMub25faW5zcGVjdF9lbGVtZW50X2NhbGxiYWNrPWV9LGxheWFhaXJfZGVidWdfdmlldy5vbkxvZ0luZm89ZnVuY3Rpb24oZSl7bG9nX2luZm9fY29udHJvbC5vbmNsaWNrPWV9LGxheWFhaXJfZGVidWdfdmlldy5vblJlZnJlc2g9ZnVuY3Rpb24oZSl7cmVmcmVzaF9jb250cm9sLm9uY2xpY2s9ZX0sbGF5YWFpcl9kZWJ1Z192aWV3Lm9uUHJpbnRFbmFibGVkTm9kZUNoYWluPWZ1bmN0aW9uKGUpe2VuYWJsZWRfbm9kZV9jaGFpbl9jb250cm9sLm9uY2xpY2s9ZX0sbGF5YWFpcl9kZWJ1Z192aWV3Lm9uUHJpbnRTaXplQ2hhaW49ZnVuY3Rpb24oZSl7c2l6ZV9jaGFpbl9jb250cm9sLm9uY2xpY2s9ZX0sbGF5YWFpcl9kZWJ1Z192aWV3Lm9uVG9nZ2xlVmlzaWJpbGl0eT1mdW5jdGlvbihlKXt2aXNpYmlsaXR5X2NvbnRyb2wub25jaGFuZ2U9ZX0sbGF5YWFpcl9kZWJ1Z192aWV3Lm9uVG9nZ2xlRGVidWdCb3JkZXI9ZnVuY3Rpb24oZSl7c2hvd19ib3JkZXJfY29udHJvbC5vbmNoYW5nZT1lfSxsYXlhYWlyX2RlYnVnX3ZpZXcub25Ub2dnbGVTaG93Q3VycmVudENhY2hlPWZ1bmN0aW9uKGUpe3Nob3dfY3VycmVudF9jYWNoZV9jb250cm9sLm9uY2hhbmdlPWV9LGxheWFhaXJfZGVidWdfdmlldy5vblRvZ2dsZVNob3dBbGxDYWNoZT1mdW5jdGlvbihlKXtzaG93X2FsbF9jYWNoZV9jb250cm9sLm9uY2hhbmdlPWV9LGxheWFhaXJfZGVidWdfdmlldy5vblRvZ2dsZVNob3dBdGxhcz1mdW5jdGlvbihlKXtzaG93X2F0bGFzX2NvbnRyb2wub25jaGFuZ2U9ZX07";class C{constructor(){this.mIndex=0,this.mTextureDic={}}static getInstance(){return C.mInstance=C.mInstance||new C}start(){null==this.mSprite&&(this.mSprite=new e.Sprite),e.Laya.stage.addChild(this.mSprite),this.showNext()}end(){this.mSprite&&e.Laya.stage.removeChild(this.mSprite)}showNext(){null==this.mSprite&&(this.mSprite=new e.Sprite),e.Laya.stage.addChild(this.mSprite),this.mIndex++,this.mTextureDic[this.mIndex]&&this.mTextureDic[this.mIndex]}}class S{constructor(){this.timeDic={},this.resultDic={},this.countDic={},this.resultCountDic={},this.nodeDic={},this.resultNodeDic={}}addTime(t,e){var a;g.idObj(t),a=g.getObjID(t),this.timeDic.hasOwnProperty(a)||(this.timeDic[a]=0),this.timeDic[a]=this.timeDic[a]+e,this.countDic.hasOwnProperty(a)||(this.countDic[a]=0),this.countDic[a]=this.countDic[a]+1,this.nodeDic[a]=t}getTime(t){var e;return g.idObj(t),e=g.getObjID(t),this.resultDic[e]?this.resultDic[e]:0}getCount(t){var e;return g.idObj(t),e=g.getObjID(t),this.resultCountDic[e]}reset(){var t;for(t in this.timeDic)this.timeDic[t]=0,this.countDic[t]=0;i.clearObj(this.nodeDic)}updates(){i.clearObj(this.resultDic),i.insertValue(this.resultDic,this.timeDic),i.clearObj(this.resultCountDic),i.insertValue(this.resultCountDic,this.countDic),i.insertValue(this.resultNodeDic,this.nodeDic),this.reset()}}class F{constructor(){}}F.CLICK_SELECT_COLOR="#ff0000",F.CANVAS_REC_COLOR="#FF00FF",F.RECACHE_REC_COLOR="#00ff00",F.SPRITE_REC_COLOR="#ff0000",F.SPRITE_REC_LINEWIDTH=2;class k extends e.Sprite{constructor(){super(),this.recColor="#00ff00",this.txt=new e.Text,this.txt.color="#ff0000",this.txt.bgColor="#00ff00",this.txt.fontSize=12,this.addChild(this.txt)}setInfo(t){this.txt.text=t}setTarget(t){this._tar=t}showInfo(t){var a;(this._tar=t,t)&&(t.destroyed||(this.graphics.clear(),!(a=t._getBoundPointsM(!0))||a.length<1||(a=e.GrahamScan.pListToPointList(a,!0),W.walkArr(a,t.localToGlobal,t),a=e.GrahamScan.pointListToPlist(a),k._disBoundRec=e.Rectangle._getWrapRec(a,k._disBoundRec),this.graphics.drawRect(0,0,k._disBoundRec.width,k._disBoundRec.height,null,F.RECACHE_REC_COLOR,2),this.pos(k._disBoundRec.x,k._disBoundRec.y))))}fresh(){this.showInfo(this._tar)}clearMe(){this._tar=null}}k._disBoundRec=new e.Rectangle;class J extends k{constructor(){super(),this.isWorking=!1,this.mTime=0,this.txt.fontSize=12}addCount(t=0){this.count++,this.mTime+=t,this.isWorking||(this.working=!0)}updates(){this._tar.displayedInStage||(this.working=!1,this.removeSelf()),this.txt.text=s.getNodeClassAndName(this._tar)+"\nreCache:"+this.count+"\ntime:"+this.mTime,this.count>0?(this.fresh(),e.Laya.timer.clear(this,this.removeSelfLater)):(this.working=!1,e.Laya.timer.once(J.showTime,this,this.removeSelfLater)),this.count=0,this.mTime=0}removeSelfLater(){this.working=!1,this.removeSelf()}set working(t){this.isWorking=t,t?e.Laya.timer.loop(1e3,this,this.updates):e.Laya.timer.clear(this,this.updates)}}J.showTime=3e3;class T{constructor(){}static renderLoopBegin(){p.I.cacheViewLayer.graphics.clear()}static get I(){return T._instance||(T._instance=new T),T._instance}static set I(t){T._instance=t}static getNodeInfoByNode(t){var e;return g.idObj(t),e=g.getObjID(t),T._nodeInfoDic[e]||(T._nodeInfoDic[e]=new J),T._nodeInfoDic[e].setTarget(t),T._nodeInfoDic[e]}renderCanvas(t,e=0){T.showCacheSprite&&(p.I.isDebugItem(t)||N.showDisBoundToSprite(t,p.I.cacheViewLayer,F.CANVAS_REC_COLOR,4))}reCacheCanvas(t,e=0){var a;T.showRecacheSprite&&(p.I.isDebugItem(t)||((a=T.getNodeInfoByNode(t)).addCount(e),T.counter.addTime(t,e),a.parent||p.I.nodeRecInfoLayer.addChild(a)))}}T.counter=new S,T._nodeInfoDic={},T.showCacheSprite=!1,T.showRecacheSprite=!0;class U extends e.EventDispatcher{constructor(){super()}static get I(){return U._instance||(U._instance=new U),U._instance}static set I(t){U._instance=t}static notify(t,e=null){U.I.event(t,e)}static listen(t,e,a,i=null,s=!1){s&&U.cancel(t,e,a),U.I.on(t,e,a,i)}static cancel(t,e,a){U.I.off(t,e,a)}}class B extends e.Text{constructor(){super(),this.bgColor="#ffff00",this.wordWrap=!1,this.mouseEnabled=!0}}class H{constructor(){this._matrix=new e.Matrix,this._point=new e.Point,this._rect=new e.Rectangle,this._event=e.Event.EMPTY,this.isGetting=!1,this._stage=e.Laya.stage,this.init(e.Render.context.canvas)}static initMe(){H.instance||(H.instance=new H,H.selectNodeUnderMouse=N.selectNodeUnderMouse,N.selectNodeUnderMouse=()=>{H.instance.selectDisUnderMouse(),H.selectNodeUnderMouse()})}init(t){window.navigator.msPointerEnabled&&(t.style["-ms-content-zooming"]="none",t.style["-ms-touch-action"]="none");var a=this;function initEvent(t,i=null){a._event._stoped=!1,a._event.nativeEvent=i||t,a._target=null,t.offsetX?(a.mouseX=t.offsetX,a.mouseY=t.offsetY):(a.mouseX=t.clientX-e.Laya.stage.offset.x,a.mouseY=t.clientY-e.Laya.stage.offset.y)}document.addEventListener("mousedown",t=>{this._event._stoped=!1,H.isFirst=!0,a.check(a._stage,t.offsetX,t.offsetY,a.onMouseDown,!0,!1)},!0),document.addEventListener("touchstart",t=>{this._event._stoped=!1,H.isFirst=!0;for(var e=t.changedTouches,i=0,s=e.length;i-1;h--){var d=t._children[h];if(n=this.check(d,e,a,i,s,!0))break}o=t.getGraphicBounds().contains(e,a),(r=n||o)&&!n&&H.isFirst&&(H.isFirst=!1,t instanceof B||(N.target=t,this.isGetting||(N.autoWork(),U.notify(H.ITEM_CLICKED,t))))}return r}}H.ITEM_CLICKED="ItemClicked",H.isFirst=!1;class E{constructor(){this._selectTip=new e.Sprite,this._selectTip.setSelfBounds(new e.Rectangle(0,0,0,0)),U.listen(H.ITEM_CLICKED,this,this.itemClicked)}static get I(){return E._I||(E._I=new E),E._I}beginClickSelect(t=null){this.completeHandler=t,E.isClickSelectState=!0,this.clickSelectChange()}clickSelectChange(){e.Browser.onPC&&(this.tSelectTar=null,this.clearSelectTip(),E.isClickSelectState?e.Laya.timer.loop(200,this,this.updateSelectTar,null,!0):e.Laya.timer.clear(this,this.updateSelectTar))}clearSelectTip(){this._selectTip.removeSelf()}updateSelectTar(){var t,e;(this.clearSelectTip(),this.tSelectTar=H.instance.getDisUnderMouse(),this.tSelectTar)&&(p.I.isDebugItem(this.tSelectTar)||((t=this._selectTip.graphics).clear(),e=Y.getGRec(this.tSelectTar),p.I.popLayer.addChild(this._selectTip),t.drawRect(0,0,e.width,e.height,null,F.CLICK_SELECT_COLOR,2),this._selectTip.pos(e.x,e.y)))}itemClicked(t){E.isClickSelectState&&(E.ignoreDebugTool&&p.I.isDebugItem(t)||(N.showDisBound(t),this.completeHandler&&this.completeHandler.runWith(t),E.isClickSelectState=!1,this.clickSelectChange()))}}E.isClickSelectState=!1,E.ignoreDebugTool=!1;class M{constructor(){}static init(){M._oldCanvas||(M._oldCanvas=e.RenderSprite.prototype._canvas,e.RenderSprite.prototype._canvas=M.prototype._canvas)}_canvas(t,a,i,s){var l,r,o=t._cacheStyle;this._next;o.enableCanvasRender?(l=!(!t._needRepaint()&&o.canvas),r=e.Browser.now(),M._oldCanvas.call(this,t,a,i,s),l?T.I.reCacheCanvas(t,e.Browser.now()-r):T.I.renderCanvas(t,e.Browser.now()-r)):M._oldCanvas.call(this,t,a,i,s)}}M.IMAGE=1,M.FILTERS=2,M.ALPHA=4,M.TRANSFORM=8,M.CANVAS=16,M.BLEND=32,M.CLIP=64,M.STYLE=128,M.GRAPHICS=256,M.CUSTOM=512,M.ENABLERENDERMERGE=1024,M.CHILDS=2048,M.INIT=69905,M.renders=[];class D{constructor(){this._repaint=1,this._renderType=1}static init(){D.I||(D.I=new D,D.setRenderHook())}static setRenderHook(){e.Sprite.prototype.render=D.I.render}static showDisplayBorder(t,e=!0){t[D.ShowBorderSign]=e}static isDisplayShowBorder(t){return t[D.ShowBorderSign]}render(t,a,i){var s;this==e.Laya.stage&&T.renderLoopBegin(),s=e.Browser.now(),this[D.ShowBorderSign]&&N.showDisBoundToSprite(this,p.I.cacheViewLayer,F.SPRITE_REC_COLOR,F.SPRITE_REC_LINEWIDTH),e.RenderSprite.renders[this._renderType]._fun(this,t,a+this._x,i+this._y),this._repaint=0,y.I.render(this,e.Browser.now()-s)}}D.ShowBorderSign="ShowBorderSign";class j{constructor(){}static showToBody(t,a=0,i=0){var s;e.Browser.document.body.appendChild(t),(s=t.style).position="absolute",s.top=i+"px",s.left=a+"px"}static showToParent(t,e=0,a=0,i=null){var s;i.appendChild(t),(s=t.style).position="absolute",s.top=a+"px",s.left=e+"px"}static addToBody(t){e.Browser.document.body.appendChild(t)}static setPos(t,e,a){var i;(i=t.style).top=a+"px",i.left=e+"px"}static setSize(t,e,a){var i;(i=t.style).width=e+"px",i.height=a+"px"}static setTransform(t,e){var a;(a=t.style).transformOrigin=a.webkitTransformOrigin=a.msTransformOrigin=a.mozTransformOrigin=a.oTransformOrigin="0px 0px 0px",a.transform=a.webkitTransform=a.msTransform=a.mozTransform=a.oTransform="matrix("+e.toString()+")"}static noMouseEvent(t){t.style["pointer-events"]="none"}static setMouseEnable(t,e){t.style["pointer-events"]=e?"auto":"none"}static setZIndex(t,e){t.style["z-index"]=e}static showAboveSprite(t,a,i=0,s=0){var l;l=new e.Point,(l=a.localToGlobal(l)).x+=i,l.y+=s,l.x+=e.Laya.stage.offset.x,l.y+=e.Laya.stage.offset.y,j.showToBody(t,l.x,l.y)}static removeElement(t){e.Browser.removeElement(t)}static isElementInDom(t){return t&&t.parentNode}static getImageSpriteByFile(t,a=0,i=0){var s,l;return(s=new FileReader).readAsDataURL(t),l=new e.Sprite,s.onload=function(t){var r;(r=new e.Texture).load(s.result),l.graphics.drawTexture(r,0,0,a,i)},l}static getPixelRatio(){if(j._pixelRatio>0)return j._pixelRatio;var t=e.Browser.createElement("canvas").getContext("2d"),a=(e.Browser.window.devicePixelRatio||1)/(t.webkitBackingStorePixelRatio||t.mozBackingStorePixelRatio||t.msBackingStorePixelRatio||t.oBackingStorePixelRatio||t.backingStorePixelRatio||1);return console.log("pixelRatioc:",a),j._pixelRatio=a,a}}j._pixelRatio=-1;class z{constructor(){this.preValueO={},this.height=300,this.width=600,this.dragArea=10,this.fromMe=!1,this._init()}static enable(t=!0,a="#ffffff"){z._enable||z.I||(z._enable=!0,z.overlay=!t,A.init(),H.initMe(),N.initBasicFunctions(),M.init(),D.init(),z.I=new z,z.I.setRoot(e.Laya.stage),T.showRecacheSprite=!1,a&&(z.I.div.style.background=a))}static getSpriteTreeArr(t){var e,a,i,l,r;for((e={})[z.LabelSign]=""+s.getNodeClassAndName(t),e.target=t,g.idObj(t),e.id=g.getObjID(t),l=(a=t._children).length,r=[],e[z.ChildrenSign]=r,i=0;i=0;e--)z.noDisplayKeys[t[e]]&&t.splice(e,1)}updateShowKeys(){z.tObjKeys.length=0,this.tShowObj&&(z.tObjKeys=s.getObjectDisplayAbleKeys(this.tShowObj,z.tObjKeys),this.tShowObj==e.Laya.stage&&this.removeNoDisplayKeys(z.tObjKeys),z.tObjKeys.sort(e.MathUtil.sortSmallFirst))}static getObjectData(t){var e,a,i,s,l,r,o,n;for(e=[],n=(r=z.tObjKeys).length,o=0;o{var e;(e=this.getDataByID(t,this._treeDataList[0])).target&&(N.showDisBound(e.target),this.showTargetInfo(e.target))}),this.debug_view.setValueChangeHandler((t,e)=>{this.onValueChange(t,e)}),this.debug_view.onRefresh(()=>{z.I.setRoot(e.Laya.stage)}),this.debug_view.onInspectElement(()=>{E.I.beginClickSelect(this.clickedHandler)}),this.debug_view.onLogInfo(()=>{console.log(this.tShowObj)}),this.debug_view.onPrintEnabledNodeChain(()=>{N.traceDisMouseEnable(this.tShowObj)}),this.debug_view.onPrintSizeChain(()=>{N.traceDisSizeChain(this.tShowObj)}),this.debug_view.onToggleVisibility(t=>{this.tShowObj&&(this.tShowObj.visible=this.debug_view.getVisibility())}),this.debug_view.onToggleDebugBorder(t=>{this.tShowObj&&D.showDisplayBorder(this.tShowObj,this.debug_view.getShowDebugBorder())}),this.debug_view.onToggleShowCurrentCache(t=>{T.showRecacheSprite=this.debug_view.getShowCurrentCache()}),this.debug_view.onToggleShowAllCache(t=>{T.showCacheSprite=this.debug_view.getShowAllCache()}),this.debug_view.onToggleShowAtlas(t=>{console.log("toggle show atlas:",this.debug_view.getShowAtlas()),this.debug_view.getShowAtlas()?C.getInstance().start():C.getInstance().end()}),j.showToBody(this.div,0,0),this.initNewDivs(),this.initDragWork(),this.initTreeWidthDrag(),e.Laya.stage.on(e.Event.RESIZE,this,this.adptPos),this.adptPos()}initNewDivs(){var t,a;t=e.Browser.document.getElementById("show_current_cache_control").parentNode,(a=e.Browser.createElement("input")).type="checkbox",t.appendChild(a),t.append("右侧"),a.addEventListener("change",function(t){t.target.checked?z.sideType=z.Right:z.sideType=z.Bottom,this.adptPos()}.bind(this))}static getOffset(t,e){var a,i,s,l;for(a=t.target,i=t.currentTarget,s="X"==e?"offsetLeft":"offsetTop",l=t["offset"+e];a&&a!=i;)l+=a[s],a=a.offsetParent;return l}initTreeWidthDrag(){var t,a;(a=(t=e.Browser.document.getElementById("tree_container")).parentNode).children[1];var i=!1;a.addEventListener("mousedown",function(e){Math.abs(z.getOffset(e,"X")-t.clientWidth)this.dragArea)return}else if(z.getOffset(e,"X")>this.dragArea)return;i=!0,t=e.pageX,a=e.pageY,e.stopPropagation()}.bind(this),!0),this.div.addEventListener("mousemove",function(t){z.sideType==z.Bottom?z.getOffset(t,"Y")this.width&&(t=(e.Browser.clientWidth-this.width)*e.Browser.pixelRatio),e.Laya.stage.setScreenSize(t,e.Browser.clientHeight*e.Browser.pixelRatio)}this.fromMe=!1}}setRoot(t){var a,i;a=z.getSpriteTreeArr(t),this._treeDataList=[a],(i={}).id=0,i.item=[a],this.debug_view.setTree(i),e.Laya.timer.loop(500,this,this.updateLoop)}getDataByID(t,e){if(!e)return null;if(t==e.id)return e;var a,i,s,l;if(!(a=e[z.ChildrenSign]))return null;for(s=a.length,i=0;in&&(l=n),sd&&(o=d),rt?1:-1}static sortSmallFirst(t,e){return t==e?0:e>t?-1:1}static sortNumBigFirst(t,e){return parseFloat(e)-parseFloat(t)}static sortNumSmallFirst(t,e){return parseFloat(t)-parseFloat(e)}static sortByKey(t,e=!1,a=!0){var i;return i=e?a?q.sortNumBigFirst:q.sortBigFirst:a?q.sortNumSmallFirst:q.sortSmallFirst,function(e,a){return i(e[t],a[t])}}}class ${constructor(){}static toHexColor(t){return e.Utils.toHexColor(t)}static getRGBByRGBStr(t){"#"==t.charAt(0)&&(t=t.substr(1));var e=parseInt(t,16);t.length;return[(16711680&e)>>16,(65280&e)>>8,255&e]}static getColorBit(t){var e;return e=(e=Math.floor(t).toString(16)).length>1?e:"0"+e}static getRGBStr(t,e=1){return"#"+$.getColorBit(t[0]*e)+$.getColorBit(t[1]*e)+$.getColorBit(t[2]*e)}static traseHSB(t){console.log("hsb:",t[0],t[1],t[2])}static rgb2hsb(t,e,a){var i=[t,e,a];i.sort(q.sortNumSmallFirst);var s=i[2],l=i[0],r=0;return s==l?r=1:0==t&&0==e&&0==a||(s==t&&e>=a?r=60*(e-a)/(s-l)+0:s==t&&e0?1:-1),this._box.scaleY=Math.abs(this._box.scaleY)*(this._target.scaleY>0?1:-1),this._left.x=0,this._left.y=.5*e,this._right.x=t,this._right.y=.5*e,this._top.x=.5*t,this._top.y=0,this._bottom.x=.5*t,this._bottom.y=e,this._topLeft.x=this._topLeft.y=0,this._topRight.x=t,this._topRight.y=0,this._bottomLeft.x=0,this._bottomLeft.y=e,this._bottomRight.x=t,this._bottomRight.y=e)}}it.BLOCK_WIDTH=6;class st{static removeNoDisplayKeys(t){var e;for(e=t.length-1;e>=0;e--)st.noDisplayKeys[t[e]]&&t.splice(e,1)}static getClassCount(t){return st.countDic[t]}static addClassCount(t){st.countDic[t]?st.countDic[t]=st.countDic[t]+1:st.countDic[t]=1}static init(){if(!st._inited){st._inited=!0;x.hook(Node,"call",null,(function(t){st.classCreated(t)})),st.handlerO={},st.handlerO.get=function(t,e,a){return console.log("get",t,e,a),Reflect.get(t,e,a)},st.handlerO.set=function(t,e,a,i){return console.log("set",t,e,a,i),Reflect.set(t,e,a,i)}}}static classCreated(t,e=null){var a,i;st.fromMe||(a=s.getClassName(t),st.addClassCount(a),st.addClassCount(st.ALL),g.idObj(t),((i=st.hookClassDic[a])||(st.profileClass(t.constructor),i=st.hookClassDic[a]))&&st.hookObj2(t,i))}static hookObj(t,e){var a=st.handlerO;new Proxy(t,a)}static hookObj2(t,e){var a,i;for(i=e.length,a=0;a=0;l--)r[a[l]]instanceof Function&&a.splice(l,1);a.length,st.removeNoDisplayKeys(a),st.hookClassDic[e]=a}static hookPrototype(t,e){console.log("hook:",e);try{st.hookVar(t,e)}catch(t){console.log("fail",e)}}static reportCall(t,e,a){var i,l;g.idObj(t),i=g.getObjID(t),l=s.getClassName(t),st.recordInfo(l,e,a,i),st.recordInfo(st.ALL,e,a,i)}static recordInfo(t,e,a,i){var s,l,r;st.infoDic[t]||(st.infoDic[t]={}),(s=st.infoDic[t])[e]||(s[e]={}),(l=s[e])[a]||(l[a]={}),(r=l[a])[i]?r[i]=r[i]+1:(r[i]=1,r.objCount?r.objCount=r.objCount+1:r.objCount=1),r.count?r.count=r.count+1:r.count=1}static showInfo(){var t,e,a,i,s,l,r;for(s in t={},e={},a=[],i=[],st.infoDic){var o,n;for(l in o=st.infoDic[s],t[s]=n={},o){var h,d;for(r in h=o[l],n[l]=d={},h){var c,b;(c=h[r]).rate=c.objCount/st.getClassCount(s),d[r]=c.rate,e[b=s+"_"+l+"_"+r]=c.rate,s==st.ALL&&("get"==r?a.push([b,c.rate,c.count]):i.push([b,c.rate,c.count]))}}}console.log(st.infoDic),console.log(st.countDic),console.log(t),console.log(e),console.log("nodeCount:",st.getClassCount(st.ALL)),console.log("sort by rate"),st.showStaticInfo(a,i,"1"),console.log("sort by count"),st.showStaticInfo(a,i,"2")}static showStaticInfo(t,e,a){console.log("get:"),st.showStaticArray(t,a),console.log("set:"),st.showStaticArray(e,a)}static showStaticArray(t,a="1"){var i,s,l;for(t.sort(e.MathUtil.sortByKey(a,!0,!0)),s=t.length,i=0;i-1;o--)if((d=t._children[o])==c&&(c.mouseEnabled||(rt.infoO[g.getObjID(c)]="mouseEnabled=false"),c.visible||(rt.infoO[g.getObjID(c)]="visible=false"),b=!1),d.mouseEnabled&&d.visible){if(rt.check(d,a,i,l))return rt.hitO[g.getObjID(t)]=!0,rt.infoO[g.getObjID(t)]="子对象被击中",d==c?rt.infoO[g.getObjID(t)]="子对象被击中,击中对象在分析链中":(rt.infoO[g.getObjID(t)]="子对象被击中,击中对象不在分析链中",b&&(rt.infoO[g.getObjID(c)]="被兄弟节点挡住,兄弟节点信息:"+s.getNodeClassAndName(d)+","+d.getBounds().toString(),N.showDisBound(d,!1,"#ffff00"))),!0;d==c&&(b=!1)}var m,G=new e.Rectangle;if(m=t.getGraphicBounds().contains(a,i),t.width>0&&t.height>0){var W=rt._rect;t.mouseThrough?(Z=m,G.copyFrom(t.getGraphicBounds())):(t.hitArea?W=t.hitArea:W.setTo(0,0,t.width,t.height),G.copyFrom(W),Z=W.contains(a,i)),Z&&(rt.hitO[g.getObjID(t)]=!0)}return rt.infoO[g.getObjID(t)]=Z?"自身区域被击中":m?"子对象未包含鼠标,实际绘图区域包含鼠标,设置的宽高区域不包含鼠标::"+a+","+i+" hitRec:"+G.toString()+" graphicBounds:"+t.getGraphicBounds().toString()+",设置mouseThrough=true或将宽高设置到实际绘图区域可解决问题":"子对象未包含鼠标,实际绘图区域不包含鼠标,设置的宽高区域不包含鼠标::"+a+","+i+" hitRec:"+G.toString()+" graphicBounds:"+t.getGraphicBounds().toString(),Z}static hitTest(t,a,i){var s=!1;if(t.hitArea instanceof e.HitArea)return e.MouseManager.instance.hitTest(t,a,i);if(t.width>0&&t.height>0||t.mouseThrough||t.hitArea){var l=rt._rect;t.mouseThrough?s=t.getGraphicBounds().contains(a,i):(t.hitArea?l=t.hitArea:l.setTo(0,0,t.width,t.height),s=l.contains(a,i))}return s}}rt.infoO={},rt.nodeO={},rt.hitO={},rt._matrix=new e.Matrix,rt._point=new e.Point,rt._rect=new e.Rectangle,N.analyseMouseHit=()=>{N.target&&rt.analyseNode(N.target)};class ot{constructor(){}static getCachedResList(){return ot.getWebGlResList()}static getWebGlResList(){return[]}static getCanvasResList(){var t,a;return t={},a=e.Loader.loadedMap,ot.collectPics(a,t),ot.getArrFromDic(t)}static getArrFromDic(t){var e,a;for(e in a=[],t)a.push(e);return a}static collectPics(t,e){var a,i;if(t)for(a in t){if(i=t[a])if(i.bitmap&&i.bitmap.src)i.bitmap.src.indexOf("data:image/png;base64")<0&&(e[i.bitmap.src]=!0)}}}class nt{constructor(){this._objDic={}}static get I(){return nt._instance||(nt._instance=new nt),nt._instance}static set I(t){nt._instance=t}getArr(t){var e;return(e=this.getTypeDic("Array"))[t]||(e[t]=[]),e[t]}getObject(t){var e;return(e=this.getTypeDic("Object"))[t]||(e[t]={}),e[t]}getByClass(t,e,a){var i;return(i=this.getTypeDic(e))[t]||(i[t]=new a),i[t]}getTypeDic(t){return this._objDic[t]||(this._objDic[t]={}),this._objDic[t]}}class ht{constructor(){}static getTime(t,a=!0){var i,s;return ht.timeDic[t]||(ht.timeDic[t]=0),s=(i=e.Browser.now())-ht.timeDic[t],ht.timeDic[t]=i,s}static runAllCallLater(){var t;ht._deep,ht._deep++;for(var a=(t=e.Laya.timer)._laters,i=0,s=a.length-1;i<=s;i++){var l=a[i];l&&(null!==l.method&&l.run(!1),t._recoverHandler(l)),i===s&&(s=a.length-1)}a.length=0,ht._deep--}}ht.timeDic={},ht._deep=0;class dt{constructor(){}static now(){return 1!=dt._timeRate?dt.getRatedNow():Date.now()}static getRatedNow(){return(dt.getNow()-dt._startTime)*dt._timeRate+dt._startTime}static getNow(){return Date.now()}static setTimeRate(t){null==dt._browerNow&&(dt._browerNow=e.Browser.now),dt._startTime=dt.getNow(),dt._timeRate=t,1!=t?e.Browser.now=dt.now:null!=dt._browerNow&&(e.Browser.now=dt._browerNow)}static recoverRate(){dt.setTimeRate(1)}}dt._timeRate=1;class ct{constructor(){}static getTouchIDs(t){var e,a,i;for(e=[],i=t.length,a=0;a0&&l.height>0,r=Y.getGAlpha(t),n="",n+="isInstage:"+a+"\n",n+="isInVisibleRec:"+s+"\n",n+="gVisible:"+(o=Y.getGVisible(t))+"\n",n+="gAlpha:"+r+"\n",a&&s&&o&&r>0&&(ut.anlyseRecVisible(t),n+="coverRate:"+ut.coverRate+"\n",ut._coverList.length>0&&e.Laya.timer.once(1e3,null,ut.showListLater)),console.log(n)}static showListLater(){}static isCoverByBrother(t){var e,a=t.parent;a&&(a._children.indexOf(t)<0||(e=a.getSelfBounds()).width<=0||e.height)}static anlyseRecVisible(t){ut.isNodeWalked=!1,ut._analyseTarget=t,ut.mainCanvas||(ut.mainCanvas=P.createCanvas(e.Laya.stage.width,e.Laya.stage.height)),P.clearCanvas(ut.mainCanvas),ut.tColor=1,ut.resetCoverList(),W.walkTargetEX(e.Laya.stage,ut.recVisibleWalker,null,ut.filterFun),ut.isTarRecOK?ut.coverRate=P.getDifferRate(ut.preImageData,ut.tarImageData):ut.coverRate=0,console.log("coverRate:",ut.coverRate)}static getRecArea(t){return t.width*t.height}static addCoverNode(t,e){var a;(a={}).path=t,a.label=s.getNodeClassAndName(t)+":"+e,a.coverRate=e,ut._coverList.push(a),console.log("coverByNode:",t,e)}static resetCoverList(){ut._coverList.length=0}static recVisibleWalker(t){var e,a;t==ut._analyseTarget?(ut.isNodeWalked=!0,ut.tarRec.copyFrom(Y.getGRec(t)),console.log("tarRec:",ut.tarRec.toString()),ut.tarRec.width>0&&ut.tarRec.height>0?(ut.isTarRecOK=!0,ut.tColor++,P.fillCanvasRec(ut.mainCanvas,ut.tarRec,$.toHexColor(ut.tColor)),ut.preImageData=P.getImageDataFromCanvasByRec(ut.mainCanvas,ut.tarRec),ut.tarImageData=P.getImageDataFromCanvasByRec(ut.mainCanvas,ut.tarRec)):console.log("tarRec Not OK:",ut.tarRec)):ut.isTarRecOK&&(e=Y.getGRec(t),ut.interRec=ut.tarRec.intersection(e,ut.interRec),ut.interRec&&ut.interRec.width>0&&ut.interRec.height>0&&(ut.tColor++,P.fillCanvasRec(ut.mainCanvas,e,$.toHexColor(ut.tColor)),ut.tImageData=P.getImageDataFromCanvasByRec(ut.mainCanvas,ut.tarRec),a=P.getDifferRate(ut.preImageData,ut.tImageData),ut.preImageData=ut.tImageData,ut.addCoverNode(t,a)))}static filterFun(t){return 0!=t.visible&&(!(t.alpha<0)&&!p.I.isDebugItem(t))}}ut.tarRec=new e.Rectangle,ut.interRec=new e.Rectangle,ut._coverList=[];class Zt{static parse(t,e=!0){var a={};e&&(a.Name=t.localName);var i=t.children.length,s=[],l={};a.c=l,a.cList=s;for(var r=0;ra.x&&(this._sX=a.x),i1&&(s/=e.length-1),n=i,o=e.length,r=0;r0&&(e.width=t*Yt.getItemRate(e))}static setItemRate(t,e){t[Yt.RateSign]=e}static getItemRate(t){return t[Yt.RateSign]?t[Yt.RateSign]:-1}static setItemFreeSize(t,e=!0){t[Yt.FreeSizeSign]=e}static isItemFreeSize(t){return t[Yt.FreeSizeSign]}static lockedDis(t,e,a=null,i=0){var s,l,r,o,n,h,d,c;for(s=a.dists,l=a.sumDis,Yt.prepareForLayoutWidth(t,e),d=t-l-Yt.getSumWidth(e),(c=Yt.getFreeItem(e))&&(c.width+=d),(h=e[0]).x=i,o=e.length,r=1;rb&&(b=n.height),++c>=e?(c%=e,n.y+=b+i,b=0):r+=n.width+a}static layoutToWidth(t,e,a,i,s,l){var r,o,n,h,d;for(r=s,o=l,d=t.length,h=0;he&&(r=s,o+=i+n.height),n.x=r,n.y=o,r+=a+n.width}},t.Layouter=yt,t.LoaderHook=Xt,t.MathTools=q,t.MouseEventAnalyser=rt,t.NodeConsts=V,t.NodeInfoPanel=X,t.NodeInfosItem=R,t.NodeRecInfo=k,t.NodeUtils=Y,t.Notice=U,t.ObjTimeCountTool=S,t.ObjectTools=i,t.Observer=Vt,t.ReCacheRecInfo=J,t.RecInfo=o,t.Rect=d,t.RenderAnalyser=y,t.RenderSpriteHook=M,t.ResTools=ot,t.RunProfile=G,t.SimpleResizer=n,t.SingleTool=nt,t.SpriteRenderHook=D,t.StringTool=a,t.StyleConsts=vt,t.TimeTool=ht,t.TimerControlTool=dt,t.TouchDebugTools=ct,t.TraceTool=l,t.UVTools=bt,t.ValueChanger=c,t.VarHook=v,t.VisibleAnalyser=ut,t.WalkTools=W,t.Watch=class{constructor(){}static watch(t,e,a){t.watch(e,a)}static unwatch(t,e,a){t.unwatch(e,a)}},t.Watcher=w,t.XML2Object=Zt,t.XML2ObjectNodejs=mt}(window.Laya=window.Laya||{},Laya); \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/min/laya.device.min.js b/examples/layaair/frontend/bin/libs/min/laya.device.min.js new file mode 100644 index 0000000..2490f0f --- /dev/null +++ b/examples/layaair/frontend/bin/libs/min/laya.device.min.js @@ -0,0 +1 @@ +!function(e,t){"use strict";class i{constructor(){}}class n{constructor(){}}class a extends t.EventDispatcher{constructor(e){super(),this.onDeviceOrientationChange=this.onDeviceOrientationChange.bind(this)}static get instance(){return a._instance=a._instance||new a(0),a._instance}on(e,i,n,a=null){return super.on(e,i,n,a),t.ILaya.Browser.window.addEventListener("devicemotion",this.onDeviceOrientationChange),this}off(e,i,n,a=!1){return this.hasListener(e)||t.ILaya.Browser.window.removeEventListener("devicemotion",this.onDeviceOrientationChange),super.off(e,i,n,a)}onDeviceOrientationChange(e){var i=e.interval;a.acceleration.x=e.acceleration.x,a.acceleration.y=e.acceleration.y,a.acceleration.z=e.acceleration.z,a.accelerationIncludingGravity.x=e.accelerationIncludingGravity.x,a.accelerationIncludingGravity.y=e.accelerationIncludingGravity.y,a.accelerationIncludingGravity.z=e.accelerationIncludingGravity.z,a.rotationRate.alpha=-1*e.rotationRate.gamma,a.rotationRate.beta=-1*e.rotationRate.alpha,a.rotationRate.gamma=e.rotationRate.beta,t.ILaya.Browser.onAndroid?(t.ILaya.Browser.userAgent.indexOf("Chrome")>-1&&(a.rotationRate.alpha*=180/Math.PI,a.rotationRate.beta*=180/Math.PI,a.rotationRate.gamma*=180/Math.PI),a.acceleration.x*=-1,a.accelerationIncludingGravity.x*=-1):t.ILaya.Browser.onIOS&&(a.acceleration.y*=-1,a.acceleration.z*=-1,a.accelerationIncludingGravity.y*=-1,a.accelerationIncludingGravity.z*=-1,i*=1e3),this.event(t.Event.CHANGE,[a.acceleration,a.accelerationIncludingGravity,a.rotationRate,i])}static getTransformedAcceleration(e){var n;return a.transformedAcceleration=a.transformedAcceleration||new i,a.transformedAcceleration.z=e.z,90==t.ILaya.Browser.window.orientation?(a.transformedAcceleration.x=e.y,a.transformedAcceleration.y=-e.x):-90==t.ILaya.Browser.window.orientation?(a.transformedAcceleration.x=-e.y,a.transformedAcceleration.y=e.x):t.ILaya.Browser.window.orientation?180==t.ILaya.Browser.window.orientation&&(a.transformedAcceleration.x=-e.x,a.transformedAcceleration.y=-e.y):(a.transformedAcceleration.x=e.x,a.transformedAcceleration.y=e.y),-90==t.ILaya.stage.canvasDegree?(n=a.transformedAcceleration.x,a.transformedAcceleration.x=-a.transformedAcceleration.y,a.transformedAcceleration.y=n):90==t.ILaya.stage.canvasDegree&&(n=a.transformedAcceleration.x,a.transformedAcceleration.x=a.transformedAcceleration.y,a.transformedAcceleration.y=-n),a.transformedAcceleration}}a.acceleration=new i,a.accelerationIncludingGravity=new i,a.rotationRate=new n;class o extends t.EventDispatcher{constructor(){super()}static get instance(){return o._instance=o._instance||new o,o._instance}start(e,i){this.throushold=e,this.shakeInterval=i,this.lastX=this.lastY=this.lastZ=NaN,a.instance.on(t.Event.CHANGE,this,this.onShake)}stop(){a.instance.off(t.Event.CHANGE,this,this.onShake)}onShake(e,i,n,a){if(isNaN(this.lastX))return this.lastX=i.x,this.lastY=i.y,this.lastZ=i.z,void(this.lastMillSecond=t.ILaya.Browser.now());var o=Math.abs(this.lastX-i.x),r=Math.abs(this.lastY-i.y),s=Math.abs(this.lastZ-i.z);this.isShaked(o,r,s)&&(t.ILaya.Browser.now()-this.lastMillSecond>this.shakeInterval&&(this.event(t.Event.CHANGE),this.lastMillSecond=t.ILaya.Browser.now()));this.lastX=i.x,this.lastY=i.y,this.lastZ=i.z}isShaked(e,t,i){return e>this.throushold&&t>this.throushold||e>this.throushold&&i>this.throushold||t>this.throushold&&i>this.throushold}}class r{setPosition(e){this.pos=e,this.coords=e.coords}get latitude(){return this.coords.latitude}get longitude(){return this.coords.longitude}get altitude(){return this.coords.altitude}get accuracy(){return this.coords.accuracy}get altitudeAccuracy(){return this.coords.altitudeAccuracy}get heading(){return this.coords.heading}get speed(){return this.coords.speed}get timestamp(){return this.pos.timestamp}}class s{constructor(){}static getCurrentPosition(e,t=null){s.navigator.geolocation.getCurrentPosition((function(t){s.position.setPosition(t),e.runWith(s.position)}),(function(e){t.runWith(e)}),{enableHighAccuracy:s.enableHighAccuracy,timeout:s.timeout,maximumAge:s.maximumAge})}static watchPosition(e,t){return s.navigator.geolocation.watchPosition((function(t){s.position.setPosition(t),e.runWith(s.position)}),(function(e){t.runWith(e)}),{enableHighAccuracy:s.enableHighAccuracy,timeout:s.timeout,maximumAge:s.maximumAge})}static clearWatch(e){s.navigator.geolocation.clearWatch(e)}}s.navigator=navigator,s.position=new r,s.PERMISSION_DENIED=1,s.POSITION_UNAVAILABLE=2,s.TIMEOUT=3,s.supported=!!s.navigator.geolocation,s.enableHighAccuracy=!1,s.timeout=1e10,s.maximumAge=0;class d extends t.Bitmap{constructor(){super(),this._w=0,this._h=0,this._width=1,this._height=1,this.createDomElement()}createDomElement(){this._source=this.video=t.ILaya.Browser.createElement("video");var e=this.video.style;e.position="absolute",e.top="0px",e.left="0px",this.video.addEventListener("loadedmetadata",()=>{this._w=this.video.videoWidth,this._h=this.video.videoHeight})}setSource(e,t){for(;this.video.childElementCount;)this.video.firstChild.remove();1&t&&this.appendSource(e,"video/mp4"),2&t&&this.appendSource(e+".ogg","video/ogg")}appendSource(e,i){var n=t.ILaya.Browser.createElement("source");n.src=e,n.type=i,this.video.appendChild(n)}getVideo(){return this.video}_getSource(){return this._source}destroy(){super.destroy(),t.ILaya.Render.isConchApp&&this.video._destroy()}}d.create=function(){return new d};class l extends d{constructor(){super();var e=t.LayaGL.instance;this.gl=t.ILaya.Render.isConchApp?window.LayaGLContext.instance:t.WebGLContext.mainContext,this._source=this.gl.createTexture(),t.WebGLContext.bindTexture(this.gl,e.TEXTURE_2D,this._source),this.gl.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),this.gl.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),this.gl.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),this.gl.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),t.WebGLContext.bindTexture(this.gl,e.TEXTURE_2D,null)}updateTexture(){var e=t.LayaGL.instance;t.WebGLContext.bindTexture(this.gl,e.TEXTURE_2D,this._source),this.gl.pixelStorei(e.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),this.gl.texImage2D(e.TEXTURE_2D,0,e.RGB,e.RGB,e.UNSIGNED_BYTE,this.video),this.gl.pixelStorei(e.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1),l.curBindSource=this._source}get _glTexture(){return this._source}destroy(){this._source&&(this.gl=t.ILaya.Render.isConchApp?window.LayaGLContext.instance:t.WebGLContext.mainContext,this.gl&&(l.curBindSource==this._source&&(t.WebGLContext.bindTexture(this.gl,this.gl.TEXTURE_2D,null),l.curBindSource=null),this.gl.deleteTexture(this._source))),super.destroy()}}class h extends t.Sprite{constructor(e=320,i=240){super(),this.htmlVideo=new l,this.videoElement=this.htmlVideo.getVideo(),this.videoElement.layaTarget=this,this.internalTexture=new t.Texture(this.htmlVideo),this.videoElement.addEventListener("abort",h.onAbort),this.videoElement.addEventListener("canplay",h.onCanplay),this.videoElement.addEventListener("canplaythrough",h.onCanplaythrough),this.videoElement.addEventListener("durationchange",h.onDurationchange),this.videoElement.addEventListener("emptied",h.onEmptied),this.videoElement.addEventListener("error",h.onError),this.videoElement.addEventListener("loadeddata",h.onLoadeddata),this.videoElement.addEventListener("loadedmetadata",h.onLoadedmetadata),this.videoElement.addEventListener("loadstart",h.onLoadstart),this.videoElement.addEventListener("pause",h.onPause),this.videoElement.addEventListener("play",h.onPlay),this.videoElement.addEventListener("playing",h.onPlaying),this.videoElement.addEventListener("progress",h.onProgress),this.videoElement.addEventListener("ratechange",h.onRatechange),this.videoElement.addEventListener("seeked",h.onSeeked),this.videoElement.addEventListener("seeking",h.onSeeking),this.videoElement.addEventListener("stalled",h.onStalled),this.videoElement.addEventListener("suspend",h.onSuspend),this.videoElement.addEventListener("timeupdate",h.onTimeupdate),this.videoElement.addEventListener("volumechange",h.onVolumechange),this.videoElement.addEventListener("waiting",h.onWaiting),this.videoElement.addEventListener("ended",this.onPlayComplete.bind(this)),this.size(e,i),t.ILaya.Browser.onMobile&&(this.videoElement["x5-playsInline"]=!0,this.videoElement["x5-playsinline"]=!0,this.videoElement.x5PlaysInline=!0,this.videoElement.playsInline=!0,this.videoElement["webkit-playsInline"]=!0,this.videoElement["webkit-playsinline"]=!0,this.videoElement.webkitPlaysInline=!0,this.videoElement.playsinline=!0,this.videoElement.style.playsInline=!0,this.videoElement.crossOrigin="anonymous",this.videoElement.setAttribute("crossorigin","anonymous"),this.videoElement.setAttribute("playsinline","true"),this.videoElement.setAttribute("x5-playsinline","true"),this.videoElement.setAttribute("webkit-playsinline","true"),this.videoElement.autoplay=!0,this._clickhandle=this.onDocumentClick.bind(this),t.ILaya.Browser.document.addEventListener("touchend",this._clickhandle))}static onAbort(e){e.target.layaTarget.event("abort")}static onCanplay(e){e.target.layaTarget.event("canplay")}static onCanplaythrough(e){e.target.layaTarget.event("canplaythrough")}static onDurationchange(e){e.target.layaTarget.event("durationchange")}static onEmptied(e){e.target.layaTarget.event("emptied")}static onError(e){e.target.layaTarget.event("error")}static onLoadeddata(e){e.target.layaTarget.event("loadeddata")}static onLoadedmetadata(e){e.target.layaTarget.event("loadedmetadata")}static onLoadstart(e){e.target.layaTarget.event("loadstart")}static onPause(e){e.target.layaTarget.event("pause")}static onPlay(e){e.target.layaTarget.event("play")}static onPlaying(e){e.target.layaTarget.event("playing")}static onProgress(e){e.target.layaTarget.event("progress")}static onRatechange(e){e.target.layaTarget.event("ratechange")}static onSeeked(e){e.target.layaTarget.event("seeked")}static onSeeking(e){e.target.layaTarget.event("seeking")}static onStalled(e){e.target.layaTarget.event("stalled")}static onSuspend(e){e.target.layaTarget.event("suspend")}static onTimeupdate(e){e.target.layaTarget.event("timeupdate")}static onVolumechange(e){e.target.layaTarget.event("volumechange")}static onWaiting(e){e.target.layaTarget.event("waiting")}onPlayComplete(e){t.ILaya.Render.isConchApp&&this.videoElement&&this.videoElement.loop||t.ILaya.timer.clear(this,this.renderCanvas),this.event("ended")}load(e){0==e.indexOf("blob:")?this.videoElement.src=e:this.htmlVideo.setSource(e,1)}play(){this.videoElement.play(),t.ILaya.timer.frameLoop(1,this,this.renderCanvas)}pause(){this.videoElement.pause(),t.ILaya.timer.clear(this,this.renderCanvas)}reload(){this.videoElement.load()}canPlayType(e){var t;switch(e){case 1:t="video/mp4";break;case 2:t="video/ogg";break;case 8:t="video/webm"}return this.videoElement.canPlayType(t)}renderCanvas(){0!==this.readyState&&(this.htmlVideo.updateTexture(),this.graphics.clear(),this.graphics.drawTexture(this.internalTexture,0,0,this.width,this.height))}onDocumentClick(){this.videoElement&&0==this.videoElement&&(t.Browser.onIOS?this.videoElement.load():(this.videoElement.play(),this.videoElement.pause()),t.ILaya.Browser.document.removeEventListener("touchend",this._clickhandle))}get buffered(){return this.videoElement.buffered}get currentSrc(){return this.videoElement.currentSrc}get currentTime(){return this.videoElement.currentTime}set currentTime(e){this.videoElement.currentTime=e,this.renderCanvas()}set volume(e){this.videoElement.volume=e}get volume(){return this.videoElement.volume}get readyState(){return this.videoElement.readyState}get videoWidth(){return this.videoElement.videoWidth}get videoHeight(){return this.videoElement.videoHeight}get duration(){return this.videoElement.duration}get ended(){return this.videoElement.ended}get error(){return this.videoElement.error}get loop(){return this.videoElement.loop}set loop(e){this.videoElement.loop=e}set x(e){if(super.x=e,t.ILaya.Render.isConchApp){var i=t.ILaya.Utils.getTransformRelativeToWindow(this,0,0);this.videoElement.style.left=i.x}}get x(){return super.x}set y(e){if(super.y=e,t.ILaya.Render.isConchApp){var i=t.ILaya.Utils.getTransformRelativeToWindow(this,0,0);this.videoElement.style.top=i.y}}get y(){return super.y}get playbackRate(){return this.videoElement.playbackRate}set playbackRate(e){this.videoElement.playbackRate=e}get muted(){return this.videoElement.muted}set muted(e){this.videoElement.muted=e}get paused(){return this.videoElement.paused}get preload(){return this.videoElement.preload}set preload(e){this.videoElement.preload=e}get seekable(){return this.videoElement.seekable}get seeking(){return this.videoElement.seeking}size(e,i){if(super.size(e,i),t.ILaya.Render.isConchApp){var n=t.ILaya.Utils.getTransformRelativeToWindow(this,0,0);this.videoElement.width=e*n.scaleX}else this.videoElement.width=e/t.ILaya.Browser.pixelRatio,this.videoElement.height=i/t.Browser.pixelRatio;return this.paused&&this.renderCanvas(),this}set width(e){if(t.ILaya.Render.isConchApp){var i=t.ILaya.Utils.getTransformRelativeToWindow(this,0,0);this.videoElement.width=e*i.scaleX}else this.videoElement.width=this.width/t.ILaya.Browser.pixelRatio;super.width=e,this.paused&&this.renderCanvas()}get width(){return super.width}set height(e){if(t.ILaya.Render.isConchApp){var i=t.ILaya.Utils.getTransformRelativeToWindow(this,0,0);this.videoElement.height=e*i.scaleY}else this.videoElement.height=this.height/t.ILaya.Browser.pixelRatio;super.height=e}get height(){return super.height}destroy(e=!0){super.destroy(e),this.videoElement.removeEventListener("abort",h.onAbort),this.videoElement.removeEventListener("canplay",h.onCanplay),this.videoElement.removeEventListener("canplaythrough",h.onCanplaythrough),this.videoElement.removeEventListener("durationchange",h.onDurationchange),this.videoElement.removeEventListener("emptied",h.onEmptied),this.videoElement.removeEventListener("error",h.onError),this.videoElement.removeEventListener("loadeddata",h.onLoadeddata),this.videoElement.removeEventListener("loadedmetadata",h.onLoadedmetadata),this.videoElement.removeEventListener("loadstart",h.onLoadstart),this.videoElement.removeEventListener("pause",h.onPause),this.videoElement.removeEventListener("play",h.onPlay),this.videoElement.removeEventListener("playing",h.onPlaying),this.videoElement.removeEventListener("progress",h.onProgress),this.videoElement.removeEventListener("ratechange",h.onRatechange),this.videoElement.removeEventListener("seeked",h.onSeeked),this.videoElement.removeEventListener("seeking",h.onSeeking),this.videoElement.removeEventListener("stalled",h.onStalled),this.videoElement.removeEventListener("suspend",h.onSuspend),this.videoElement.removeEventListener("timeupdate",h.onTimeupdate),this.videoElement.removeEventListener("volumechange",h.onVolumechange),this.videoElement.removeEventListener("waiting",h.onWaiting),this.videoElement.removeEventListener("ended",this.onPlayComplete),this.pause(),this.videoElement.layaTarget=null,this.videoElement=null,this.htmlVideo.destroy()}syncVideoPosition(){var e,i=t.ILaya.stage;e=t.ILaya.Utils.getGlobalPosAndScale(this);var n=i._canvasTransform.a,a=i._canvasTransform.d,o=e.x*i.clientScaleX*n+i.offset.x,r=e.y*i.clientScaleY*a+i.offset.y;this.videoElement.style.left=o+"px",this.videoElement.style.top=r+"px",this.videoElement.width=this.width/t.ILaya.Browser.pixelRatio,this.videoElement.height=this.height/t.ILaya.Browser.pixelRatio}}h.MP4=1,h.OGG=2,h.CAMERA=4,h.WEBM=8,h.SUPPORT_PROBABLY="probably",h.SUPPORT_MAYBY="maybe",h.SUPPORT_NO="";class c extends t.EventDispatcher{constructor(e){super(),this.onDeviceOrientationChange=this.onDeviceOrientationChange.bind(this)}static get instance(){return c._instance=c._instance||new c(0),c._instance}on(e,i,n,a=null){return super.on(e,i,n,a),t.ILaya.Browser.window.addEventListener("deviceorientation",this.onDeviceOrientationChange),this}off(e,i,n,a=!1){return this.hasListener(e)||t.ILaya.Browser.window.removeEventListener("deviceorientation",this.onDeviceOrientationChange),super.off(e,i,n,a)}onDeviceOrientationChange(e){c.info.alpha=e.alpha,c.info.beta=e.beta,c.info.gamma=e.gamma,e.webkitCompassHeading&&(c.info.alpha=-1*e.webkitCompassHeading,c.info.compassAccuracy=e.webkitCompassAccuracy),this.event(t.Event.CHANGE,[e.absolute,c.info])}}c.info=new n,e.AccelerationInfo=i,e.Accelerator=a,e.Geolocation=s,e.GeolocationInfo=r,e.Gyroscope=c,e.HtmlVideo=d,e.Media=class{constructor(){}static supported(){return!!t.ILaya.Browser.window.navigator.getUserMedia}static getMedia(e,i,n){t.ILaya.Browser.window.navigator.getUserMedia&&t.ILaya.Browser.window.navigator.getUserMedia(e,(function(e){i.runWith(t.ILaya.Browser.window.URL.createObjectURL(e))}),(function(e){n.runWith(e)}))}},e.RotationInfo=n,e.Shake=o,e.Video=h,e.WebGLVideo=l}(window.Laya=window.Laya||{},Laya); \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/min/laya.gltf.min.js b/examples/layaair/frontend/bin/libs/min/laya.gltf.min.js new file mode 100644 index 0000000..b317cf9 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/min/laya.gltf.min.js @@ -0,0 +1 @@ +!function(e,t){"use strict";class r{constructor(){}static init(){if(!r.lookup){r.lookup=new Uint8Array(256);for(var e=0;e>2],l+=r.chars[(3&a[t])<<4|a[t+1]>>4],l+=r.chars[(15&a[t+1])<<2|a[t+2]>>6],l+=r.chars[63&a[t+2]];return n%3==2?l=l.substring(0,l.length-1)+"=":n%3==1&&(l=l.substring(0,l.length-2)+"=="),l}static decode(e){r.init();var t,a,n,l,s,o=.75*e.length,i=e.length,u=0;"="===e[e.length-1]&&(o--,"="===e[e.length-2]&&o--);var c=new ArrayBuffer(o),g=new Uint8Array(c);for(t=0;t>4,g[u++]=(15&n)<<4|l>>2,g[u++]=(3&l)<<6|63&s;return c}}r.chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",r.reg=/^\s*data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)?)?(;base64)?,([a-z0-9!$&',()*+;=\-._~:@\/?%\s]*?)\s*$/i,r.reghead=/^\s*data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)?)?(;base64)?,/i,r.lookup=null;class a{static PixelArrayToBase64(e,r,a){let n=new Uint8ClampedArray(e),l=new ImageData(n,r,a),s=new t.HTMLCanvas(!0),o=s.source.getContext("2d");return s.source.width=r,s.source.height=a,o.putImageData(l,0,0),s.source.toDataURL()}static GenerateTexture2DWithPixel(e,r,a,n,l){let s=new t.Texture2D(r,a,n,l,!0);if(s.setPixels(e),l){let e=t.LayaGL.instance;t.WebGLContext.bindTexture(e,s._glTextureType,s._glTexture),e.generateMipmap(s._glTextureType),t.WebGLContext.bindTexture(e,s._glTextureType,null)}return s}static glTFOcclusionTrans(e){let r=e.getPixels(),n=new Uint8Array(r.length),l=r.length/4;for(let e=0;e{s._glTFBuffers[r]=t.Loader.getRes(e.uri)})}static getAccessorComponentsNum(e){switch(e){case"SCALAR":return 1;case"VEC2":return 2;case"VEC3":return 3;case"VEC4":case"MAT2":return 4;case"MAT3":return 9;case"MAT4":return 16;default:return 0}}static getAttributeNum(e){switch(e){case"POSITION":case"NORMAL":return 3;case"COLOR":return 4;case"UV":case"UV1":return 2;case"BLENDWEIGHT":case"BLENDINDICES":case"TANGENT":return 4;default:return 0}}static _getTypedArrayConstructor(e){switch(e){case 5120:return Int8Array;case 5121:return Uint8Array;case 5122:return Int16Array;case 5123:return Uint16Array;case 5125:return Uint32Array;case 5126:return Float32Array}}static getBufferwithAccessorIndex(e){let t=s._glTF.accessors[e];if(!t)return null;let r=s._glTF.bufferViews[t.bufferView],a=s._glTFBuffers[r.buffer],n=t.count,l=s.getAccessorComponentsNum(t.type),o=(r.byteOffset||0)+(t.byteOffset||0),i=n*l;return new(s._getTypedArrayConstructor(t.componentType))(a,o,i)}static _initTextureData(e){e&&e.forEach((e,r)=>{s._glTFTextures[r]=t.Loader.getRes(e.uri)})}static getTextureMipmap(e){return!e||(9729===e.minFilter||9728===e.minFilter)}static getTextureFormat(e){return"image/png"===e.mimeType?1:0}static getTextureFilterMode(e){return e?9728===e.magFilter?0:s.getTextureMipmap(e)&&9987===e.minFilter?2:1:1}static getTextureWrapMode(e){return 33071===e?1:0}static getTextureConstructParams(e,t){let r=[];return r[0]=0,r[1]=0,r[2]=s.getTextureFormat(e),r[3]=s.getTextureMipmap(t),r[4]=!0,r}static getTexturePropertyParams(e){let t={};return e?(t.filterMode=s.getTextureFilterMode(e),t.wrapModeU=s.getTextureWrapMode(e.wrapS),t.wrapModeV=s.getTextureWrapMode(e.wrapT),t.anisoLevel=16,t):null}static getTexturewithInfo(e){e.texCoord&&console.warn("glTF Loader: non 0 uv channel unsupported.");let t=s._glTF.textures[e.index];return s._glTFTextures[t.source]}static _loadMaterials(e){e&&e.forEach((e,t)=>{s._glTFMaterials[t]=s._loadMaterial(e)})}static _loadMaterial(e){if(e.extras){let r=t.Handler.create(this,s._createdefaultMaterial,null,!1);return s.ExecuteExtras("MATERIAL",e.extras,r,[e])}return s._createdefaultMaterial(e)}static _createdefaultMaterial(e){let r=new t.PBRStandardMaterial;if(r.name=e.name?e.name:"",e.pbrMetallicRoughness&&s.applyPBRMetallicRoughness(e.pbrMetallicRoughness,r),e.normalTexture&&(r.normalTexture=s.getTexturewithInfo(e.normalTexture),null!=e.normalTexture.scale&&(r.normalTextureScale=e.normalTexture.scale)),e.occlusionTexture){let t=s.getTexturewithInfo(e.occlusionTexture);r.occlusionTexture=a.glTFOcclusionTrans(t),null!=e.occlusionTexture.strength&&(r.occlusionTextureStrength=e.occlusionTexture.strength)}switch(e.emissiveTexture&&(r.emissionTexture=s.getTexturewithInfo(e.emissiveTexture),r.emissionTexture&&(r.enableEmission=!0)),e.emissiveFactor&&(r.emissionColor.fromArray(e.emissiveFactor),r.emissionColor.w=1,r.enableEmission=!0),e.alphaMode||"OPAQUE"){case"OPAQUE":r.renderMode=t.PBRRenderMode.Opaque;break;case"BLEND":r.renderMode=t.PBRRenderMode.Transparent;break;case"MASK":r.renderMode=t.PBRRenderMode.Cutout}return null!=e.alphaCutoff&&(r.alphaTestValue=e.alphaCutoff),e.doubleSided&&(r.cull=t.RenderState.CULL_NONE),r}static applyPBRMetallicRoughness(e,t){e.baseColorFactor&&t.albedoColor.fromArray(e.baseColorFactor),e.baseColorTexture&&(t.albedoTexture=s.getTexturewithInfo(e.baseColorTexture));let r=t.metallic=1;null!=e.metallicFactor&&(r=t.metallic=e.metallicFactor);let n=1;if(t.smoothness=0,null!=e.roughnessFactor&&(n=e.roughnessFactor,t.smoothness=1-e.roughnessFactor),e.metallicRoughnessTexture){let l=s.getTexturewithInfo(e.metallicRoughnessTexture);t.metallicGlossTexture=a.glTFMetallicGlossTrans(l,r,n)}}static pickMeshMaterials(e){let r=[];return e.primitives.forEach(e=>{if(null!=e.material){let t=s._glTFMaterials[e.material];r.push(t)}else{let a=new t.PBRStandardMaterial;r.push(a),s._glTFMaterials.push(a),e.material=s._glTFMaterials.indexOf(a)}}),r}static _loadScenes(e){e&&e.forEach((e,t)=>{s._glTFScenes[t]=s._loadScene(e)})}static _loadScene(e){return s._createSceneNode(e)}static _createSceneNode(e){let r=new t.Sprite3D(e.name||"glTF_Scene_node");return e.nodes.forEach(e=>{let t=s._glTFNodes[e];r.addChild(t)}),r}static applyTransform(e,t){if(e.matrix){let r=t.transform.localMatrix;r.elements.set(e.matrix),t.transform.localMatrix=r}else{let r=t.transform.localPosition,a=t.transform.localRotation,n=t.transform.localScale;e.translation&&r.fromArray(e.translation),e.rotation&&a.fromArray(e.rotation),e.scale&&n.fromArray(e.scale),t.transform.localPosition=r,t.transform.localRotation=a,t.transform.localScale=n}}static buildHierarchy(e){e.forEach((e,t)=>{let r=s._glTFNodes[t];e.children&&e.children.forEach(e=>{let t=s._glTFNodes[e];r.addChild(t)})}),e.forEach((e,r)=>{let a=s._glTFNodes[r];a instanceof t.SkinnedMeshSprite3D&&s.fixSkinnedSprite(e,a)})}static _loadNodes(e){e&&(e.forEach((e,t)=>{e.name=e.name||s.getNodeRandomName("node")}),e.forEach((e,t)=>{s._glTFNodes[t]=s._loadNode(e)}))}static _loadNode(e){return s._createSprite3D(e)}static _createSprite3D(e){if(e.name=e.name,null!=e.skin){let t=s._createSkinnedMeshSprite3D(e);return s.applyTransform(e,t),t}if(null!=e.mesh){let t=s._createMeshSprite3D(e);return s.applyTransform(e,t),t}{let r=new t.Sprite3D(e.name);return s.applyTransform(e,r),r}}static _createMeshSprite3D(e){let r=s._glTF.meshes[e.mesh],a=s._loadMesh(r),n=s.pickMeshMaterials(r),l=new t.MeshSprite3D(a,e.name);return l.meshRenderer.sharedMaterials=n,l}static _createSkinnedMeshSprite3D(e){let r=s._glTF.meshes[e.mesh],a=s._glTF.skins[e.skin],n=s._loadMesh(r,a),l=s.pickMeshMaterials(r),o=new t.SkinnedMeshSprite3D(n,e.name);return o.skinnedMeshRenderer.sharedMaterials=l,o}static getArrributeBuffer(e,t,r,a){let n=s.getBufferwithAccessorIndex(e);if(!n)return null;a.push(t);let l=n;return r.set(t,l),l}static getIndexBuffer(e,t){let r=s.getBufferwithAccessorIndex(e);if(r)return new Uint32Array(r).reverse();{let e=new Uint32Array(t);for(let r=0;r{a+=e.vertexCount,n+=e.indices.length,l=l||e.vertexDecler});let o,i=t.VertexMesh.getVertexDeclaration(l,!1),u=i.vertexStride/4,c=new Float32Array(u*a),g=t.IndexFormat.UInt32;a<65536?(o=new Uint16Array(n),g=t.IndexFormat.UInt16):o=new Uint32Array(n),s.fillMeshBuffers(e,c,o,u),s.generatMesh(c,o,i,g,e,r)}static fillMeshBuffers(e,t,r,a){let n=0,l=0,s=0;e.forEach(e=>{let o=n,i=e.vertexCount,u=e.indices;for(let e=0;e{let l=s+r;for(let r=0;rl){let t=e-o;a.push(o),n.push(t);let l=Array.from(i);r.push(new Uint16Array(l)),o=e,i=new Set(c)}else i=g;if(e==s-3){let t=e-o+3;a.push(o),n.push(t),o=e;let l=Array.from(i);r.push(new Uint16Array(l))}}let d=r.length,h=new Map;e.forEach((e,t)=>{let r=new Array;h.set(t,r)});let T=c-1;for(let l=0;l{let n=s.getAttributeNum(r),l=e.get(r);if("BLENDINDICES"!==r)for(let e=0;e{f[t]=e||f[t]})}h.forEach((t,r)=>{let a=e.get(r);"BLENDINDICES"==r&&(a=g);let n=a.length+t.length,l=new Float32Array(n);l.set(a,0),l.set(t,a.length),e.set(r,l)}),u=null}static generatMesh(e,r,a,n,l,s){let o=t.LayaGL.instance,i=new t.VertexBuffer3D(e.byteLength,o.STATIC_DRAW,!0);i.vertexDeclaration=a,i.setData(e.buffer);let u=new t.IndexBuffer3D(n,r.length,o.STATIC_DRAW,!0);u.setData(r),s._indexFormat=n,s._indexBuffer=u,s._vertexBuffer=i,s._setBuffer(i,u),s._vertexCount=i._byteLength/a.vertexStride;let c=0,g=l.length,f=new Array(g);for(let e=0;e{let t=s._glTF.nodes[e];i.push(t.name)}),e._inverseBindPoses=[],e._inverseBindPosesBuffer=l.buffer;for(let r=0;r{let t=e.mode;null==t&&(t=4),4!=t&&console.warn("glTF Loader: only support gl.TRIANGLES.");let a=[],l=new Map,c=e.attributes,g=s.getArrributeBuffer(c.POSITION,"POSITION",l,a),f=s.getArrributeBuffer(c.NORMAL,"NORMAL",l,a),d=(s.getArrributeBuffer(c.COLOR_0,"COLOR",l,a),s.getArrributeBuffer(c.TEXCOORD_0,"UV",l,a),s.getArrributeBuffer(c.TEXCOORD_1,"UV1",l,a),s.getArrributeBuffer(c.WEIGHTS_0,"BLENDWEIGHT",l,a),s.getArrributeBuffer(c.JOINTS_0,"BLENDINDICES",l,a),s.getArrributeBuffer(c.TANGENT,"TANGENT",l,a)),h=e.targets;h&&h.forEach((e,t)=>{let r=o[t],a=s.getBufferwithAccessorIndex(e.POSITION),n=s.getBufferwithAccessorIndex(e.NORMAL),l=s.getBufferwithAccessorIndex(e.TANGENT);a&&a.forEach((e,t)=>{g[t]+=e*r}),n&&n.forEach((e,t)=>{f[t]+=e*r}),l&&l.forEach((e,t)=>{d[t]+=e*r})});let T=g.length/3,_=s.getIndexBuffer(e.indices,T),m=new Array,p=[],x=[];if(r)if(i>s.maxSubBoneCount)s.splitSubMeshByBonesCount(l,_,m,p,x),T=l.get("POSITION").length/3;else{p[0]=0,x[0]=_.length,m[0]=new Uint16Array(i);for(let e=0;e{e._boneIndicesList.forEach((r,a)=>{let n=e._subIndexBufferStart[a],l=e._subIndexBufferCount[a]+n;for(let e=n;e{d[r]=new t.Matrix4x4,t.Matrix4x4.multiply(l,e.transform.worldMatrix,h),t.Matrix4x4.multiply(h,g[r],d[r])});let T=new t.Matrix4x4,_=new t.Vector3,m=new t.Vector3(Number.MAX_VALUE,Number.MAX_VALUE,Number.MAX_VALUE),p=new t.Vector3(-Number.MAX_VALUE,-Number.MAX_VALUE,-Number.MAX_VALUE);for(let e=0;e{let t=s._glTFNodes[e];a.bones.push(t)}),null==r.skeleton&&(r.skeleton=r.joints[0]),a.rootBone=s._glTFNodes[r.skeleton],s.calSkinnedSpriteLocalBounds(t)}static getAnimationRoot(e){const isContainNode=(e,t)=>{if(!e)return!1;if(-1==e.indexOf(t))for(let r=0;r{s._loadAnimation(e)})}static _loadAnimation(e){return s._createAnimator(e)}static _createAnimator(e){let r=e.channels,a=(e.samplers,s.getAnimationRoot(r));if(!a)return null;let n=a.getComponent(t.Animator);if(!n){n=a.addComponent(t.Animator);let e=new t.AnimatorControllerLayer("glTF_AnimatorLayer");n.addControllerLayer(e),e.defaultWeight=1}let l=s._createAnimatorClip(e,a),o=n.getControllerLayer(),i=l.name;o._statesMap[i]&&(i=l.name=s.getNodeRandomName(i));let u=new t.AnimatorState;return u.name=i,u.clip=l,o.addState(u),o.defaultState=u,o.playOnWake=!0,n}static _createAnimatorClip(e,r){let a=new t.AnimationClip,n=0,o=e.channels,i=e.samplers,u=new Array(o.length);o.forEach((e,t)=>{let a=e.target,o=i[e.sampler],c=u[t]=new l,g=s._glTFNodes[a.node],f=s.getBufferwithAccessorIndex(o.input),d=s.getBufferwithAccessorIndex(o.output);switch(c.timeArray=new Float32Array(f),c.valueArray=new Float32Array(d),c.paths=s.getAnimationPath(r,g),c.propertyOwner="transform",c.propertyLength=1,c.propertise=[],a.path){case"translation":c.propertise.push("localPosition"),c.type=1;break;case"rotation":c.propertise.push("localRotation"),c.type=2;break;case"scale":c.propertise.push("localScale"),c.type=3}c.duration=c.timeArray[c.timeArray.length-1],n=Math.max(n,c.duration)}),a.name=e.name?e.name:s.getNodeRandomName("glTF_Animation"),a._duration=n,a.islooping=!0,a._frameRate=30;let c=u.length,g=a._nodes;g.count=c;let f=a._nodesMap={},d=a._nodesDic={};for(let e=0;e0&&".."!==e[r]&&(e.splice(r,2),t-=2)}r=e.join("/")}return r}static _addglTFInnerUrls(e,t,r,a,n,l,s=null,i=null){let u=o.formatRelativePath(a,n);return r&&(u+=r),e.push({url:u,type:l,constructParams:s,propertyParams:i}),t&&t.push(u),u}static _getglTFInnerUrlsCount(e){let t=0;return e.buffers&&e.buffers.forEach(e=>{r.isBase64String(e.uri)||t++}),e.textures&&(t+=e.textures.length),t}static _getglTFBufferUrls(e,a,n,l){e.buffers&&e.buffers.forEach(e=>{if(r.isBase64String(e.uri)){let a=r.decode(e.uri.replace(r.reghead,""));t.Loader.cacheRes(e.uri,a)}else e.uri=o._addglTFInnerUrls(a,null,n,l,e.uri,t.Loader.BUFFER)})}static _getglTFTextureUrls(e,a,n,l,i){e.textures&&e.textures.forEach(u=>{let c=e.images[u.source],g=e.samplers?e.samplers[u.sampler]:void 0,f=s.getTextureConstructParams(c,g),d=s.getTexturePropertyParams(g);if(null!=c.bufferView||null!=c.bufferView){let s=e.bufferViews[c.bufferView],i=e.buffers[s.buffer],u=t.Loader.getRes(i.uri),g=s.byteOffset||0,h=s.byteLength,T=u.slice(g,g+h),_=r.encode(T),m=`data:${c.mimeType};base64,${_}`;c.uri=o._addglTFInnerUrls(a,n,l,"",m,o.GLTFBASE64TEX,f,d)}else r.isBase64String(c.uri)?c.uri=o._addglTFInnerUrls(a,n,l,"",c.uri,o.GLTFBASE64TEX,f,d):c.uri=o._addglTFInnerUrls(a,n,l,i,c.uri,t.Loader.TEXTURE2D,f,d)})}static _onglTFLoaded(e,r){let a=e.url,n=t.Utils3D.getURLVerion(a),l=t.URL.getPath(a),s=[];o._getglTFBufferUrls(r,s,n,l);let i=o._getglTFInnerUrlsCount(r),u=i+1,c=1/u;o._onProcessChange(e,0,c,1);let g=i/u;if(s.length>0){let a=t.Handler.create(null,o._onProcessChange,[e,c,g],!1);o._innerBufferLoaderManager._create(s,!1,t.Handler.create(null,o._onglTFBufferResourceLoaded,[e,a,r,n,l,c+g*s.length,g]),a,null,null,null,1,!0)}else o._onglTFBufferResourceLoaded(e,null,r,n,l,c,g)}static _onglTFBufferResourceLoaded(e,r,a,n,l,s,i){r&&r.recover();let u=[],c=[];if(o._getglTFTextureUrls(a,u,c,n,l),u.length>0){let n=t.Handler.create(null,o._onProcessChange,[e,s,i],!1);o._innerTextureLoaderManager._create(u,!1,t.Handler.create(null,o._onglTFTextureResourceLoaded,[e,n,a,c]),r,null,null,null,1,!0)}else o._onglTFTextureResourceLoaded(e,r,a,c)}static _onglTFTextureResourceLoaded(e,t,r,a){t&&t.recover(),e._cache=e._createCache;let n=s._parse(r,e._propertyParams,e._constructParams);o._endLoad(e,n,a)}static _eventLoadManagerError(e){t.Laya.loader.event(t.Event.ERROR,e)}static _onProcessChange(e,r,a,n){(n=r+n*a)<1&&e.event(t.Event.PROGRESS,2*n/3+1/3)}static _endLoad(e,r=null,a=null){if(a)for(let e=0;e0&&(this.fontSize=parseInt(r),this.family=e[s+1],s++)}}get font(){return(this.italic?"italic ":"")+(this.bold?"bold ":"")+this.fontSize+"px "+(e.ILaya.Browser.onIPhone&&e.ILaya.Text.fontFamilyMap[this.family]||this.family)}set block(t){t?this._type|=i._CSS_BLOCK:this._type&=~i._CSS_BLOCK}get block(){return 0!=(this._type&i._CSS_BLOCK)}reset(){return this.ower=null,this._type=0,this.wordWrap=!0,this.fontSize=e.ILaya.Text.defaultFontSize,this.family=e.ILaya.Text.defaultFont,this.color="#000000",this.valign=i.VALIGN_TOP,this.padding=i._PADDING,this.bold=!1,this.italic=!1,this.align=i.ALIGN_LEFT,this.textDecoration=null,this.bgColor=null,this.borderColor=null,this._extendStyle&&this._extendStyle.recover(),this._extendStyle=s.EMPTY,this}recover(){e.Pool.recover("HTMLStyle",this.reset())}static create(){return e.Pool.getItemByClass("HTMLStyle",i)}inherit(t){var e,s,r,h;for(s=(r=i._inheritProps).length,e=0;e=0&&(this._type|=i._WIDTHAUTO,t=t.substr(0,e)),this._calculation("width",t))return;t=parseInt(t)}this.size(t,-1)}set height(t){if(this._type|=i._HEIGHT_SET,"string"==typeof t){if(this._calculation("height",t))return;t=parseInt(t)}this.size(-1,t)}heighted(t){return 0!=(this._type&i._HEIGHT_SET)}size(t,e){var s=this.ower,r=!1;-1!==t&&t!=s.width&&(this._type|=i._WIDTH_SET,s.width=t,r=!0),-1!==e&&e!=s.height&&(this._type|=i._HEIGHT_SET,s.height=e,r=!0),r&&s._layoutLater()}getLineElement(){return 0!=(this._type&i._LINE_ELEMENT)}setLineElement(t){t?this._type|=i._LINE_ELEMENT:this._type&=~i._LINE_ELEMENT}_enableLayout(){return 0==(this._type&i._DISPLAY_NONE)&&0==(this._type&i._ABSOLUTE)}get letterSpacing(){return this._extendStyle.letterSpacing}set letterSpacing(t){"string"==typeof t&&(t=parseInt(t+"")),t!=this._extendStyle.letterSpacing&&(this._getExtendStyle().letterSpacing=t)}cssText(t){this.attrs(i.parseOneCSS(t,";"))}attrs(t){if(t)for(var e=0,s=t.length;e1||(s[1]=s[2]=s[3]=s[0]),g[1]=[parseInt(s[0]),parseInt(s[1]),parseInt(s[2]),parseInt(s[3])];break;default:(g[0]=i._CSSTOVALUE[d])||(g[0]=d)}r.push(g)}}return r}static parseCSS(t,e){for(var s;null!=(s=i._parseCSSRegExp.exec(t));)i.styleSheets[s[1]]=i.parseOneCSS(s[2],";")}}i._CSSTOVALUE={"letter-spacing":"letterSpacing","white-space":"whiteSpace","line-height":"lineHeight","font-family":"family","vertical-align":"valign","text-decoration":"textDecoration","background-color":"bgColor","border-color":"borderColor"},i._parseCSSRegExp=new RegExp("([.#]\\w+)\\s*{([\\s\\S]*?)}","g"),i._inheritProps=["italic","align","valign","leading","letterSpacing","stroke","strokeColor","bold","fontWeight","fontSize","lineHeight","wordWrap","color"],i.ALIGN_LEFT="left",i.ALIGN_CENTER="center",i.ALIGN_RIGHT="right",i.VALIGN_TOP="top",i.VALIGN_MIDDLE="middle",i.VALIGN_BOTTOM="bottom",i.styleSheets={},i.ADDLAYOUTED=512,i._PADDING=[0,0,0,0],i._HEIGHT_SET=8192,i._LINE_ELEMENT=65536,i._NOWARP=131072,i._WIDTHAUTO=262144,i._BOLD=1024,i._ITALIC=2048,i._CSS_BLOCK=1,i._DISPLAY_NONE=2,i._ABSOLUTE=4,i._WIDTH_SET=8,i.alignVDic={left:0,center:16,right:32,top:0,middle:64,bottom:128},i.align_Value={0:"left",16:"center",32:"right"},i.vAlign_Value={0:"top",64:"middle",128:"bottom"},i._ALIGN=48,i._VALIGN=192,e.ClassUtils.regClass("laya.html.utils.HTMLStyle",i),e.ClassUtils.regClass("Laya.HTMLStyle",i);class r{constructor(){this.all={},this.styleSheets=i.styleSheets}getElementById(t){return this.all[t]}setElementById(t,e){this.all[t]=e}}r.document=new r,e.ClassUtils.regClass("laya.html.dom.HTMLDocument",r),e.ClassUtils.regClass("Laya.HTMLDocument",r);class h{constructor(){this.rec=new e.Rectangle,this.reset()}reset(){return this.rec.reset(),this.href=null,this}recover(){e.Pool.recover("HTMLHitRect",this.reset())}static create(){return e.Pool.getItemByClass("HTMLHitRect",h)}}e.ClassUtils.regClass("laya.html.dom.HTMLHitRect",h),e.ClassUtils.regClass("Laya.HTMLHitRect",h);class l{}l.HTMLDivElement=null,l.HTMLImageElement=null,l.HTMLBrElement=null,l.HTMLDivParser=null,l.HTMLParse=null,l.HTMLElementType=null;class a{constructor(){this.elements=[],this.x=0,this.y=0,this.w=0,this.h=0,this.wordStartIndex=0,this.minTextHeight=99999,this.mWidth=0}updatePos(t,e,s,r,h,a,n){var o,d=0;this.elements.length>0&&(d=(o=this.elements[this.elements.length-1]).x+o.width-this.elements[0].x),n=n||this.h;var _,g=0;h===i.ALIGN_CENTER&&(g=(e-d)/2),h===i.ALIGN_RIGHT&&(g=e-d);for(var c=0,y=this.elements.length;c0&&w+H>m&&U.wordStartIndex>0){var R;R=U.elements.length-U.wordStartIndex+1,U.elements.length=U.wordStartIndex,s-=R,addLine();continue}d=!1,D+=_.width}b=!1,(d=d||w+H>m)&&addLine(),U.minTextHeight=Math.min(U.minTextHeight,r.height)}else h=r._getCSSStyle(),g=r,o=h.padding,d=b||h.getLineElement(),H=g.width+o[1]+o[3]+h.letterSpacing,v=g.height+o[0]+o[2],b=h.getLineElement(),(d=d||w+H>m&&h.wordWrap)&&addLine();U.elements.push(r),U.h=Math.max(U.h,v),r.x=w,r.y=I,w+=H,U.w=w-u,U.y=I,f=Math.max(w+C,f)}else A||(w+=n.DIV_ELEMENT_PADDING),U.wordStartIndex=U.elements.length;if(I=U.y+U.h,x){var P=0,O=m;for(T&&t.width>0&&(O=t.width),s=0,c=M.length;st.height&&(t.height=I),[f,I]}}var o;n.DIV_ELEMENT_PADDING=0,e.ClassUtils.regClass("laya.html.utils.Layout",n),e.ClassUtils.regClass("Laya.Layout",n),(o=t.HTMLElementType||(t.HTMLElementType={}))[o.BASE=0]="BASE",o[o.IMAGE=1]="IMAGE";class d{constructor(){this.eletype=t.HTMLElementType.BASE,this._creates(),this.reset()}static formatURL1(t,s=null){if(!t)return"null path";if(s||(s=e.URL.basePath),t.indexOf(":")>0)return t;if(null!=e.URL.customFormat&&(t=e.URL.customFormat(t)),t.indexOf(":")>0)return t;var i=t.charAt(0);if("."===i)return e.URL._formatRelativePath(s+t);if("~"===i)return e.URL.rootPath+t.substring(1);if("d"===i){if(0===t.indexOf("data:image"))return t}else if("/"===i)return t;return s+t}_creates(){this._style=i.create()}reset(){if(this.URI=null,this.parent=null,this._style.reset(),this._style.ower=this,this._style.valign="middle",this._text&&this._text.words){var t,e,s,i=this._text.words;for(e=i.length,t=0;t-1;t--)this._children[t].destroy();this._children.length=0}}get style(){return this._style}_getWords(){if(!this._text)return null;var t=this._text.text;if(!t||0===t.length)return null;var s,i=this._text.words;if(i&&i.length===t.length)return i;null===i&&(this._text.words=i=[]),i.length=t.length;for(var r=this.style,h=r.font,l=0,a=t.length;l0||null!=this._getWords())&&t.block?(n.later(this),t._type|=i.ADDLAYOUTED):this.parent&&this.parent._layoutLater())}set x(t){this._x!=t&&(this._x=t,this.parentRepaint())}get x(){return this._x}set y(t){this._y!=t&&(this._y=t,this.parentRepaint())}get y(){return this._y}get width(){return this._width}set width(t){this._width!==t&&(this._width=t,this.repaint())}get height(){return this._height}set height(t){this._height!==t&&(this._height=t,this.repaint())}_setAttributes(t,e){switch(t){case"style":this.style.cssText(e);break;case"class":this.className=e;break;case"x":this.x=parseFloat(e);break;case"y":this.y=parseFloat(e);break;case"width":this.width=parseFloat(e);break;case"height":this.height=parseFloat(e);break;default:this[t]=e}}set href(t){this._style&&t!=this._style.href&&(this._style.href=t,this.repaint())}get href(){return this._style?this._style.href:null}formatURL(t){return this.URI?d.formatURL1(t,this.URI?this.URI.path:null):t}set color(t){this.style.color=t}set className(t){this.style.attrs(r.document.styleSheets["."+t])}drawToGraphic(t,e,s,i){e+=this.x,s+=this.y;var r,h,l,a=this.style;if(a.paddingLeft&&(e+=a.paddingLeft),a.paddingTop&&(s+=a.paddingTop),(null!=a.bgColor||a.borderColor)&&t.drawRect(e,s,this.width,this.height,a.bgColor,a.borderColor,1),this.renderSelfToGraphic(t,e,s,i),this._children&&this._children.length>0)for(h=this._children.length,r=0;r"+(s=s.replace(/
/g,"
"))+"").replace(p.spacePattern,p.char255);var r=e.Utils.parseXMLFromString(s);p._parseXML(t,r.childNodes[0].childNodes,i)}static _parseXML(t,e,s,i=null){var r,h;if(e.join||e.item)for(r=0,h=e.length;r0&&(a=p.getInstance(n))&&(t.addChild(a),a.innerTEXT=o.replace(p.char255AndOneSpacePattern," "));else if((o=e.textContent.replace(/^\s+|\s+$/g,"")).length>0){var _=t;if(t instanceof d&&t.innerTEXT&&t.innerTEXT.length>0){let e=p.getInstance("p");e&&(t.addChild(e),_=e)}_.innerTEXT=o.replace(p.char255AndOneSpacePattern," ")}return}if("#comment"==(n=e.nodeName.toLowerCase()))return;if(a=p.getInstance(n)){"p"==n?(t.addChild(p.getInstance("br")),a=t.addChild(a),t.addChild(p.getInstance("br"))):a=t.addChild(a),a.URI=s,a.href=i;var g=e.attributes;if(g&&g.length>0)for(r=0,h=g.length;r0&&this._setGraphicDirty()}_updateGraphicWork(){switch(this._repaintState){case 1:this._updateGraphic();break;case 2:this._refresh()}}_setGraphicDirty(){this.callLater(this._updateGraphicWork)}_doClears(){if(this._recList){var t,e=this._recList.length;for(t=0;t{var i=this._element.URI;this._element.URI=new e.URL(t),this.innerHTML=s,!i||(this._element.URI=i)}),s.load(t,e.Loader.TEXT)}}e.ClassUtils.regClass("laya.html.dom.HTMLIframeElement",T),e.ClassUtils.regClass("Laya.HTMLIframeElement",T),t.HTMLBrElement=_,t.HTMLDivElement=L,t.HTMLDivParser=y,t.HTMLDocument=r,t.HTMLElement=d,t.HTMLExtendStyle=s,t.HTMLHitRect=h,t.HTMLIframeElement=T,t.HTMLImageElement=u,t.HTMLLinkElement=c,t.HTMLParse=p,t.HTMLStyle=i,t.HTMLStyleElement=g,t.IHtml=l,t.Layout=n,t.LayoutLine=a}(window.Laya=window.Laya||{},Laya); \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/min/laya.hwmini.min.js b/examples/layaair/frontend/bin/libs/min/laya.hwmini.min.js new file mode 100644 index 0000000..eed3be0 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/min/laya.hwmini.min.js @@ -0,0 +1 @@ +window.hwMiniGame=function(e,t){"use strict";class i{static isLocalNativeFile(e){for(var t=0,i=l.nativefiles.length;t=f&&(t.size>l.minClearSize&&(l.minClearSize=t.size),i.onClearCacheRes()),i.deleteFile(e,n,a,s,t.size)},fail:function(e){null!=a&&a.runWith([1,e])}}):null!=a&&a.runWith([0]):i.fs.getFileInfo({filePath:e,success:function(t){o&&p+4194304+t.size>=f&&(t.size>l.minClearSize&&(l.minClearSize=t.size),i.onClearCacheRes()),i.fs.copyFile({srcPath:e,destPath:h,success:function(e){i.onSaveFile(n,d,!0,s,a,t.size)},fail:function(e){null!=a&&a.runWith([1,e])}})},fail:function(e){null!=a&&a.runWith([1,e])}})}static onClearCacheRes(){var e=l.minClearSize,t=[];for(var n in i.filesListObj)"fileUsedSize"!=n&&t.push(i.filesListObj[n]);i.sortOn(t,"times",i.NUMERIC);for(var a=0,s=1,o=t.length;s=e)break;a+=r.size,i.deleteFile("",r.readyUrl)}}static sortOn(e,t,n=0){return n==i.NUMERIC?e.sort((function(e,i){return e[t]-i[t]})):n==(i.NUMERIC|i.DESCENDING)?e.sort((function(e,i){return i[t]-e[t]})):e.sort((function(e,i){return e[t]-i[t]}))}static getFileNativePath(e){return i.fileNativeDir+"/"+e}static deleteFile(e,t="",n=null,a="",s=0){var o=i.getFileInfo(t),l=i.getFileNativePath(o.md5);i.fs.unlink({filePath:l,success:function(o){if(""!=e){var l=i.getFileNativePath(e);i.fs.copyFile({srcPath:e,destPath:l,success:function(o){i.onSaveFile(t,e,!0,a,n,s)},fail:function(e){null!=n&&n.runWith([1,e])}})}else i.onSaveFile(t,e,!1,a,n,s)},fail:function(e){null!=n&&n.runWith([1,e])}})}static deleteAll(){var e=[];for(var t in i.filesListObj)"fileUsedSize"!=t&&e.push(i.filesListObj[t]);for(var n=1,a=e.length;n0&&this.loops--,this.startTime=0,this.play()}play(){this.isStopped=!1,t.SoundManager.addChannel(this),this._audio.play()}set startTime(e){this._audio&&(this._audio.startTime=e)}set autoplay(e){this._audio.autoplay=e}get autoplay(){return this._audio.autoplay}get position(){return this._audio?this._audio.currentTime:0}get duration(){return this._audio?this._audio.duration:0}stop(){this.isStopped=!0,t.SoundManager.removeChannel(this),this.completeHandler=null,this._audio&&(this._audio.stop(),this.loop||(this._audio.offEnded(null),this._miniSound.dispose(),this._audio=null,this._miniSound=null,this._onEnd=null))}pause(){this.isStopped=!0,this._audio.pause()}get loop(){return this._audio.loop}set loop(e){this._audio.loop=e}resume(){this._audio&&(this.isStopped=!1,t.SoundManager.addChannel(this),this._audio.play())}set volume(e){this._audio&&(this._audio.volume=e)}get volume(){return this._audio?this._audio.volume:1}}class a extends t.EventDispatcher{constructor(){super(),this.loaded=!1}static _createSound(){return a._id++,l.window.hbs.createInnerAudioContext()}load(e){if(a._musicAudio||(a._musicAudio=a._createSound()),i.isLocalNativeFile(e)){if(-1!=e.indexOf("http://")||-1!=e.indexOf("https://"))if(""!=i.loadPath)e=e.split(i.loadPath)[1];else{var n=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath;""!=n&&(e=e.split(n)[1])}}else e=t.URL.formatURL(e);if(this.url=e,this.readyUrl=e,a._audioCache[this.readyUrl])this.event(t.Event.COMPLETE);else if(l.autoCacheFile&&i.getFileInfo(e))this.onDownLoadCallBack(e,0);else if(l.autoCacheFile)if(i.isLocalNativeFile(e)){var s=e;if(""!=(n=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath)&&(e=e.split(n)[1]),e||(e=s),l.subNativeFiles&&0==l.subNativeheads.length)for(var o in l.subNativeFiles){var r=l.subNativeFiles[o];l.subNativeheads=l.subNativeheads.concat(r);for(var d=0;d>>"+a)}}return t},l._inited=!1,l.autoCacheFile=!0,l.minClearSize=5242880,l.sizeLimit=52428800,l.nativefiles=["layaNativeDir","wxlocal"],l.subNativeFiles=[],l.subNativeheads=[],l.subMaps=[],l.AutoCacheDownFile=!1;class r extends t.EventDispatcher{constructor(){super()}static __init__(){try{var e;if(!(e=t.Accelerator))return;e.prototype.on=r.prototype.on,e.prototype.off=r.prototype.off}catch(e){}}static startListen(e){if(r._callBack=e,!r._isListening){r._isListening=!0;try{l.window.hbs.onAccelerometerChange(r.onAccelerometerChange)}catch(e){}}}static stopListen(){r._isListening=!1;try{l.window.hbs.stopAccelerometer({})}catch(e){}}static onAccelerometerChange(e){var t;(t={}).acceleration=e,t.accelerationIncludingGravity=e,t.rotationRate={},null!=r._callBack&&r._callBack(t)}on(e,t,i,n=null){return super.on(e,t,i,n),r.startListen(this.onDeviceOrientationChange),this}off(e,t,i,n=!1){return this.hasListener(e)||r.stopListen(),super.off(e,t,i,n)}}r._isListening=!1;class d{constructor(){}static __init__(){l.window.navigator.geolocation.getCurrentPosition=d.getCurrentPosition,l.window.navigator.geolocation.watchPosition=d.watchPosition,l.window.navigator.geolocation.clearWatch=d.clearWatch}static getCurrentPosition(e=null,t=null,i=null){var n;(n={}).success=function(t){null!=e&&e(t)},n.fail=t,l.window.hbs.getLocation(n)}static watchPosition(e=null,i=null,n=null){var a;return d._curID++,(a={}).success=e,a.error=i,d._watchDic[d._curID]=a,t.Laya.systemTimer.loop(1e3,null,d._myLoop),d._curID}static clearWatch(e){delete d._watchDic[e],d._hasWatch()||t.Laya.systemTimer.clear(null,d._myLoop)}static _hasWatch(){var e;for(e in d._watchDic)if(d._watchDic[e])return!0;return!1}static _myLoop(){d.getCurrentPosition(d._mySuccess,d._myError)}static _mySuccess(e){var i,n={};for(i in n.coords=e,n.timestamp=t.Browser.now(),d._watchDic)d._watchDic[i].success&&d._watchDic[i].success(n)}static _myError(e){var t;for(t in d._watchDic)d._watchDic[t].error&&d._watchDic[t].error(e)}}d._watchDic={},d._curID=0;e.HWMiniAdapter=l,e.ImageDataPolyfill=ImageDataPolyfill,e.MiniAccelerator=r,e.MiniFileMgr=i,e.MiniInput=s,e.MiniLoader=o,e.MiniLocation=d,e.MiniSound=a,e.MiniSoundChannel=n,e.MiniVideo=class{constructor(e=320,t=240){this.videoend=!1,this.videourl="",this.videoElement=l.window.hbs.createVideo({width:e,height:t,autoplay:!0})}static __init__(){}on(e,t,i){"loadedmetadata"==e?(this.onPlayFunc=i.bind(t),this.videoElement.onPlay=this.onPlayFunction.bind(this)):"ended"==e&&(this.onEndedFunC=i.bind(t),this.videoElement.onEnded=this.onEndedFunction.bind(this)),this.videoElement.onTimeUpdate=this.onTimeUpdateFunc.bind(this)}onTimeUpdateFunc(e){this.position=e.position,this._duration=e.duration}get duration(){return this._duration}onPlayFunction(){this.videoElement&&(this.videoElement.readyState=200),console.log("=====视频加载完成========"),null!=this.onPlayFunc&&this.onPlayFunc()}onEndedFunction(){this.videoElement&&(this.videoend=!0,console.log("=====视频播放完毕========"),null!=this.onEndedFunC&&this.onEndedFunC())}off(e,t,i){"loadedmetadata"==e?(this.onPlayFunc=i.bind(t),this.videoElement.offPlay=this.onPlayFunction.bind(this)):"ended"==e&&(this.onEndedFunC=i.bind(t),this.videoElement.offEnded=this.onEndedFunction.bind(this))}load(e){this.videoElement&&(this.videoElement.src=e)}play(){this.videoElement&&(this.videoend=!1,this.videoElement.play())}pause(){this.videoElement&&(this.videoend=!0,this.videoElement.pause())}get currentTime(){return this.videoElement?this.videoElement.initialTime:0}set currentTime(e){this.videoElement&&(this.videoElement.initialTime=e)}get videoWidth(){return this.videoElement?this.videoElement.width:0}get videoHeight(){return this.videoElement?this.videoElement.height:0}get ended(){return this.videoend}get loop(){return!!this.videoElement&&this.videoElement.loop}set loop(e){this.videoElement&&(this.videoElement.loop=e)}get playbackRate(){return this.videoElement?this.videoElement.playbackRate:0}set playbackRate(e){this.videoElement&&(this.videoElement.playbackRate=e)}get muted(){return!!this.videoElement&&this.videoElement.muted}set muted(e){this.videoElement&&(this.videoElement.muted=e)}get paused(){return!!this.videoElement&&this.videoElement.paused}size(e,t){this.videoElement&&(this.videoElement.width=e,this.videoElement.height=t)}get x(){return this.videoElement?this.videoElement.x:0}set x(e){this.videoElement&&(this.videoElement.x=e)}get y(){return this.videoElement?this.videoElement.y:0}set y(e){this.videoElement&&(this.videoElement.y=e)}get currentSrc(){return this.videoElement.src}destroy(){this.videoElement&&this.videoElement.destroy(),this.videoElement=null,this.onEndedFunC=null,this.onPlayFunc=null,this.videoend=!1,this.videourl=null}reload(){this.videoElement&&(this.videoElement.src=this.videourl)}}}; \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/min/laya.particle.min.js b/examples/layaair/frontend/bin/libs/min/laya.particle.min.js new file mode 100644 index 0000000..4d3b0ab --- /dev/null +++ b/examples/layaair/frontend/bin/libs/min/laya.particle.min.js @@ -0,0 +1 @@ +!function(t,e){"use strict";class i{constructor(){this.textureName=null,this.textureCount=1,this.maxPartices=100,this.duration=1,this.ageAddScale=0,this.emitterVelocitySensitivity=1,this.minStartSize=100,this.maxStartSize=100,this.minEndSize=100,this.maxEndSize=100,this.minHorizontalVelocity=0,this.maxHorizontalVelocity=0,this.minVerticalVelocity=0,this.maxVerticalVelocity=0,this.endVelocity=1,this.gravity=new Float32Array([0,0,0]),this.minRotateSpeed=0,this.maxRotateSpeed=0,this.minStartRadius=0,this.maxStartRadius=0,this.minEndRadius=0,this.maxEndRadius=0,this.minHorizontalStartRadian=0,this.maxHorizontalStartRadian=0,this.minVerticalStartRadian=0,this.maxVerticalStartRadian=0,this.useEndRadian=!0,this.minHorizontalEndRadian=0,this.maxHorizontalEndRadian=0,this.minVerticalEndRadian=0,this.maxVerticalEndRadian=0,this.minStartColor=new Float32Array([1,1,1,1]),this.maxStartColor=new Float32Array([1,1,1,1]),this.minEndColor=new Float32Array([1,1,1,1]),this.maxEndColor=new Float32Array([1,1,1,1]),this.colorComponentInter=!1,this.disableColor=!1,this.blendState=0,this.emitterType="null",this.emissionRate=0,this.pointEmitterPosition=new Float32Array([0,0,0]),this.pointEmitterPositionVariance=new Float32Array([0,0,0]),this.pointEmitterVelocity=new Float32Array([0,0,0]),this.pointEmitterVelocityAddVariance=new Float32Array([0,0,0]),this.boxEmitterCenterPosition=new Float32Array([0,0,0]),this.boxEmitterSize=new Float32Array([0,0,0]),this.boxEmitterVelocity=new Float32Array([0,0,0]),this.boxEmitterVelocityAddVariance=new Float32Array([0,0,0]),this.sphereEmitterCenterPosition=new Float32Array([0,0,0]),this.sphereEmitterRadius=1,this.sphereEmitterVelocity=0,this.sphereEmitterVelocityAddVariance=0,this.ringEmitterCenterPosition=new Float32Array([0,0,0]),this.ringEmitterRadius=30,this.ringEmitterVelocity=0,this.ringEmitterVelocityAddVariance=0,this.ringEmitterUp=2,this.positionVariance=new Float32Array([0,0,0])}static checkSetting(t){var e;for(e in i._defaultSetting)e in t||(t[e]=i._defaultSetting[e]);t.endVelocity=+t.endVelocity,t.gravity[0]=+t.gravity[0],t.gravity[1]=+t.gravity[1],t.gravity[2]=+t.gravity[2]}}i._defaultSetting=new i;class r{constructor(){}addParticleArray(t,e){}}class a{constructor(){}static Create(t,i,r,s){var n=new a;n.position=i,e.MathUtil.scaleVector3(r,t.emitterVelocitySensitivity,a._tempVelocity);var o,l=e.MathUtil.lerp(t.minHorizontalVelocity,t.maxHorizontalVelocity,Math.random()),h=Math.random()*Math.PI*2;if(a._tempVelocity[0]+=l*Math.cos(h),a._tempVelocity[2]+=l*Math.sin(h),a._tempVelocity[1]+=e.MathUtil.lerp(t.minVerticalVelocity,t.maxVerticalVelocity,Math.random()),n.velocity=a._tempVelocity,n.startColor=a._tempStartColor,n.endColor=a._tempEndColor,t.disableColor){for(o=0;o<3;o++)n.startColor[o]=1,n.endColor[o]=1;n.startColor[o]=e.MathUtil.lerp(t.minStartColor[o],t.maxStartColor[o],Math.random()),n.endColor[o]=e.MathUtil.lerp(t.minEndColor[o],t.maxEndColor[o],Math.random())}else if(t.colorComponentInter)for(o=0;o<4;o++)n.startColor[o]=e.MathUtil.lerp(t.minStartColor[o],t.maxStartColor[o],Math.random()),n.endColor[o]=e.MathUtil.lerp(t.minEndColor[o],t.maxEndColor[o],Math.random());else e.MathUtil.lerpVector4(t.minStartColor,t.maxStartColor,Math.random(),n.startColor),e.MathUtil.lerpVector4(t.minEndColor,t.maxEndColor,Math.random(),n.endColor);n.sizeRotation=a._tempSizeRotation;var m=Math.random();n.sizeRotation[0]=e.MathUtil.lerp(t.minStartSize,t.maxStartSize,m),n.sizeRotation[1]=e.MathUtil.lerp(t.minEndSize,t.maxEndSize,m),n.sizeRotation[2]=e.MathUtil.lerp(t.minRotateSpeed,t.maxRotateSpeed,Math.random()),n.radius=a._tempRadius;var d=Math.random();n.radius[0]=e.MathUtil.lerp(t.minStartRadius,t.maxStartRadius,d),n.radius[1]=e.MathUtil.lerp(t.minEndRadius,t.maxEndRadius,d),n.radian=a._tempRadian,n.radian[0]=e.MathUtil.lerp(t.minHorizontalStartRadian,t.maxHorizontalStartRadian,Math.random()),n.radian[1]=e.MathUtil.lerp(t.minVerticalStartRadian,t.maxVerticalStartRadian,Math.random());var c=t.useEndRadian;return n.radian[2]=c?e.MathUtil.lerp(t.minHorizontalEndRadian,t.maxHorizontalEndRadian,Math.random()):n.radian[0],n.radian[3]=c?e.MathUtil.lerp(t.minVerticalEndRadian,t.maxVerticalEndRadian,Math.random()):n.radian[1],n.durationAddScale=t.ageAddScale*Math.random(),n.time=s,n}}a._tempVelocity=new Float32Array(3),a._tempStartColor=new Float32Array(4),a._tempEndColor=new Float32Array(4),a._tempSizeRotation=new Float32Array(3),a._tempRadius=new Float32Array(2),a._tempRadian=new Float32Array(4);class s extends r{constructor(t){super(),this._floatCountPerVertex=29,this._firstActiveElement=0,this._firstNewElement=0,this._firstFreeElement=0,this._firstRetiredElement=0,this._currentTime=0,this.settings=t}reUse(t,e){return 0}initialize(){var t;this._vertices=this._mesh._vb.getFloat32Array(),t=this._mesh._stride/4;for(var e=0,i=0,r=0;r=this.settings.maxPartices&&(this._firstActiveElement=0)}}freeRetiredParticles(){for(;this._firstRetiredElement!=this._firstActiveElement;){if(this._drawCounter-this._vertices[this._firstRetiredElement*this._floatCountPerVertex*4+28]<3)break;this._firstRetiredElement++,this._firstRetiredElement>=this.settings.maxPartices&&(this._firstRetiredElement=0)}}addNewParticlesToVertexBuffer(){}addParticleArray(t,e){var i=this._firstFreeElement+1;if(i>=this.settings.maxPartices&&(i=0),i!==this._firstRetiredElement){for(var r=a.Create(this.settings,t,e,this._currentTime),s=this._firstFreeElement*this._floatCountPerVertex*4,n=0;n<4;n++){var o,l;for(o=0,l=4;o<3;o++)this._vertices[s+n*this._floatCountPerVertex+l+o]=r.position[o];for(o=0,l=7;o<3;o++)this._vertices[s+n*this._floatCountPerVertex+l+o]=r.velocity[o];for(o=0,l=10;o<4;o++)this._vertices[s+n*this._floatCountPerVertex+l+o]=r.startColor[o];for(o=0,l=14;o<4;o++)this._vertices[s+n*this._floatCountPerVertex+l+o]=r.endColor[o];for(o=0,l=18;o<3;o++)this._vertices[s+n*this._floatCountPerVertex+l+o]=r.sizeRotation[o];for(o=0,l=21;o<2;o++)this._vertices[s+n*this._floatCountPerVertex+l+o]=r.radius[o];for(o=0,l=23;o<4;o++)this._vertices[s+n*this._floatCountPerVertex+l+o]=r.radian[o];this._vertices[s+n*this._floatCountPerVertex+27]=r.durationAddScale,this._vertices[s+n*this._floatCountPerVertex+28]=r.time}this._firstFreeElement=i}}}var n="attribute vec4 a_CornerTextureCoordinate;\r\nattribute vec3 a_Position;\r\nattribute vec3 a_Velocity;\r\nattribute vec4 a_StartColor;\r\nattribute vec4 a_EndColor;\r\nattribute vec3 a_SizeRotation;\r\nattribute vec2 a_Radius;\r\nattribute vec4 a_Radian;\r\nattribute float a_AgeAddScale;\r\nattribute float a_Time;\r\n\r\nvarying vec4 v_Color;\r\nvarying vec2 v_TextureCoordinate;\r\n\r\nuniform float u_CurrentTime;\r\nuniform float u_Duration;\r\nuniform float u_EndVelocity;\r\nuniform vec3 u_Gravity;\r\n\r\nuniform vec2 size;\r\nuniform mat4 u_mmat;\r\n\r\nvec4 ComputeParticlePosition(in vec3 position, in vec3 velocity,in float age,in float normalizedAge)\r\n{\r\n\r\n float startVelocity = length(velocity);//起始标量速度\r\n float endVelocity = startVelocity * u_EndVelocity;//结束标量速度\r\n\r\n float velocityIntegral = startVelocity * normalizedAge +(endVelocity - startVelocity) * normalizedAge *normalizedAge/2.0;//计算当前速度的标量(单位空间),vt=v0*t+(1/2)*a*(t^2)\r\n \r\n vec3 addPosition = normalize(velocity) * velocityIntegral * u_Duration;//计算受自身速度影响的位置,转换标量到矢量 \r\n addPosition += u_Gravity * age * normalizedAge;//计算受重力影响的位置\r\n \r\n float radius=mix(a_Radius.x, a_Radius.y, normalizedAge); //计算粒子受半径和角度影响(无需计算角度和半径时,可用宏定义优化屏蔽此计算)\r\n float radianHorizontal =mix(a_Radian.x,a_Radian.z,normalizedAge);\r\n float radianVertical =mix(a_Radian.y,a_Radian.w,normalizedAge);\r\n \r\n float r =cos(radianVertical)* radius;\r\n addPosition.y += sin(radianVertical) * radius;\r\n\t\r\n addPosition.x += cos(radianHorizontal) *r;\r\n addPosition.z += sin(radianHorizontal) *r;\r\n \r\n addPosition.y=-addPosition.y;//2D粒子位置更新需要取负,2D粒子坐标系Y轴正向朝上\r\n position+=addPosition;\r\n return vec4(position,1.0);\r\n}\r\n\r\nfloat ComputeParticleSize(in float startSize,in float endSize, in float normalizedAge)\r\n{ \r\n float size = mix(startSize, endSize, normalizedAge);\r\n return size;\r\n}\r\n\r\nmat2 ComputeParticleRotation(in float rot,in float age)\r\n{ \r\n float rotation =rot * age;\r\n //计算2x2旋转矩阵.\r\n float c = cos(rotation);\r\n float s = sin(rotation);\r\n return mat2(c, -s, s, c);\r\n}\r\n\r\nvec4 ComputeParticleColor(in vec4 startColor,in vec4 endColor,in float normalizedAge)\r\n{\r\n\tvec4 color=mix(startColor,endColor,normalizedAge);\r\n //硬编码设置,使粒子淡入很快,淡出很慢,6.7的缩放因子把置归一在0到1之间,可以谷歌x*(1-x)*(1-x)*6.7的制图表\r\n color.a *= normalizedAge * (1.0-normalizedAge) * (1.0-normalizedAge) * 6.7;\r\n \r\n return color;\r\n}\r\n\r\nvoid main()\r\n{\r\n float age = u_CurrentTime - a_Time;\r\n age *= 1.0 + a_AgeAddScale;\r\n float normalizedAge = clamp(age / u_Duration,0.0,1.0);\r\n gl_Position = ComputeParticlePosition(a_Position, a_Velocity, age, normalizedAge);//计算粒子位置\r\n float pSize = ComputeParticleSize(a_SizeRotation.x,a_SizeRotation.y, normalizedAge);\r\n mat2 rotation = ComputeParticleRotation(a_SizeRotation.z, age);\r\n\t\r\n mat4 mat=u_mmat;\r\n gl_Position=vec4((mat*gl_Position).xy,0.0,1.0);\r\n gl_Position.xy += (rotation*a_CornerTextureCoordinate.xy) * pSize*vec2(mat[0][0],mat[1][1]);\r\n gl_Position=vec4((gl_Position.x/size.x-0.5)*2.0,(0.5-gl_Position.y/size.y)*2.0,0.0,1.0);\r\n \r\n v_Color = ComputeParticleColor(a_StartColor,a_EndColor, normalizedAge);\r\n v_TextureCoordinate =a_CornerTextureCoordinate.zw;\r\n}\r\n\r\n",o="#if defined(GL_FRAGMENT_PRECISION_HIGH)\r\nprecision highp float;\r\n#else\r\nprecision mediump float;\r\n#endif\r\n\r\nvarying vec4 v_Color;\r\nvarying vec2 v_TextureCoordinate;\r\nuniform sampler2D u_texture;\r\n\r\nvoid main()\r\n{\t\r\n\tgl_FragColor=texture2D(u_texture,v_TextureCoordinate)*v_Color;\r\n\tgl_FragColor.xyz *= v_Color.w;\r\n}";class l extends e.Shader{constructor(){super(n,o,"ParticleShader",null,["a_CornerTextureCoordinate",0,"a_Position",1,"a_Velocity",2,"a_StartColor",3,"a_EndColor",4,"a_SizeRotation",5,"a_Radius",6,"a_Radian",7,"a_AgeAddScale",8,"a_Time",9])}}l.vs=n,l.ps=o;class h extends e.Value2D{constructor(){super(0,0),h.pShader||(h.pShader=new l)}upload(){var t=this.size;t[0]=e.RenderState2D.width,t[1]=e.RenderState2D.height,this.alpha=this.ALPHA*e.RenderState2D.worldAlpha,h.pShader.upload(this)}}h.pShader=null;class m extends s{constructor(t){super(t),this.x=0,this.y=0,this.sv=new h,this._key={};var i=this;e.ILaya.loader.load(this.settings.textureName,e.Handler.create(null,(function(t){i.texture=t})),null,e.Loader.IMAGE),this.sv.u_Duration=this.settings.duration,this.sv.u_Gravity=this.settings.gravity,this.sv.u_EndVelocity=this.settings.endVelocity,this._blendFn=e.BlendMode.fns[t.blendState],this._mesh=e.MeshParticle2D.getAMesh(this.settings.maxPartices),this.initialize()}getRenderType(){return-111}releaseRender(){}addParticleArray(t,e){t[0]+=this.x,t[1]+=this.y,super.addParticleArray(t,e)}addNewParticlesToVertexBuffer(){var t,e=this._mesh._vb;e.clear(),e.append(this._vertices),this._firstNewElement0&&(e.setNeedUpload(),e.subUpload(0,0,4*this._firstFreeElement*this._floatCountPerVertex*4))),this._firstNewElement=this._firstFreeElement}renderSubmit(){if(this.texture&&this.texture.getIsReady()){if(this.update(e.ILaya.timer._delta),this.sv.u_CurrentTime=this._currentTime,this._firstNewElement!=this._firstFreeElement&&this.addNewParticlesToVertexBuffer(),this.blend(),this._firstActiveElement!=this._firstFreeElement){var t=e.WebGLContext.mainContext;this._mesh.useMesh(t),this.sv.u_texture=this.texture._getSource(),this.sv.upload(),this._firstActiveElement0&&t.drawElements(t.TRIANGLES,6*this._firstFreeElement,t.UNSIGNED_SHORT,0)),e.Stat.renderBatches++}this._drawCounter++}return 1}updateParticleForNative(){this.texture&&this.texture.getIsReady()&&(this.update(e.ILaya.timer._delta),this.sv.u_CurrentTime=this._currentTime,this._firstNewElement!=this._firstFreeElement&&(this._firstNewElement=this._firstFreeElement))}getMesh(){return this._mesh}getConchMesh(){return this._conchMesh}getFirstNewElement(){return this._firstNewElement}getFirstFreeElement(){return this._firstFreeElement}getFirstActiveElement(){return this._firstActiveElement}getFirstRetiredElement(){return this._firstRetiredElement}setFirstFreeElement(t){this._firstFreeElement=t}setFirstNewElement(t){this._firstNewElement=t}addDrawCounter(){this._drawCounter++}blend(){if(e.BlendMode.activeBlendFunction!==this._blendFn){var t=e.WebGLContext.mainContext;t.enable(t.BLEND),this._blendFn(t),e.BlendMode.activeBlendFunction=this._blendFn}}dispose(){this._mesh.releaseMesh()}}m.activeBlendType=-1;class d{constructor(){this._frameTime=0,this._emissionRate=60,this._emissionTime=0,this.minEmissionTime=1/60}set particleTemplate(t){this._particleTemplate=t}set emissionRate(t){t<=0||(this._emissionRate=t,t>0&&(this.minEmissionTime=1/t))}get emissionRate(){return this._emissionRate}start(t=Number.MAX_VALUE){0!=this._emissionRate&&(this._emissionTime=t)}stop(){this._emissionTime=0}clear(){this._emissionTime=0}emit(){}advanceTime(t=1){if(this._emissionTime-=t,!(this._emissionTime<0||(this._frameTime+=t,this._frameTimethis.minEmissionTime;)this._frameTime-=this.minEmissionTime,this.emit()}}class c extends d{constructor(t){super(),this.template=t}set template(t){this._particleTemplate=t,t||(this._emitFun=null,this.setting=null,this._posRange=null),this.setting=t.settings,this._posRange=this.setting.positionVariance,this._particleTemplate instanceof m&&(this._emitFun=this.webGLEmit)}get template(){return this._particleTemplate}emit(){super.emit(),null!=this._emitFun&&this._emitFun()}getRandom(t){return(2*Math.random()-1)*t}webGLEmit(){var t=new Float32Array(3);t[0]=this.getRandom(this._posRange[0]),t[1]=this.getRandom(this._posRange[1]),t[2]=this.getRandom(this._posRange[2]);var e=new Float32Array(3);e[0]=0,e[1]=0,e[2]=0,this._particleTemplate.addParticleArray(t,e)}canvasEmit(){var t=new Float32Array(3);t[0]=this.getRandom(this._posRange[0]),t[1]=this.getRandom(this._posRange[1]),t[2]=this.getRandom(this._posRange[2]);var e=new Float32Array(3);e[0]=0,e[1]=0,e[2]=0,this._particleTemplate.addParticleArray(t,e)}}class _ extends e.Sprite{constructor(t){super(),this._matrix4=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),this.autoPlay=!0,this.customRenderEnable=!0,t&&this.setParticleSetting(t)}set url(t){this.load(t)}load(t){e.ILaya.loader.load(t,e.Handler.create(this,this.setParticleSetting),null,e.ILaya.Loader.JSON)}setParticleSetting(t){if(!t)return this.stop();i.checkSetting(t),this.customRenderEnable=!0,this._particleTemplate=new m(t),this.graphics._saveToCmd(null,e.DrawParticleCmd.create(this._particleTemplate)),this._emitter?this._emitter.template=this._particleTemplate:this._emitter=new c(this._particleTemplate),this.autoPlay&&(this.emitter.start(),this.play())}get emitter(){return this._emitter}play(){e.ILaya.timer.frameLoop(1,this,this._loop)}stop(){e.ILaya.timer.clear(this,this._loop)}_loop(){this.advanceTime(1/60)}advanceTime(t=1){this._canvasTemplate&&this._canvasTemplate.advanceTime(t),this._emitter&&this._emitter.advanceTime(t)}customRender(t,e,i){this._matrix4[0]=t._curMat.a,this._matrix4[1]=t._curMat.b,this._matrix4[4]=t._curMat.c,this._matrix4[5]=t._curMat.d,this._matrix4[12]=t._curMat.tx,this._matrix4[13]=t._curMat.ty,this._particleTemplate.sv.u_mmat=this._matrix4,this._canvasTemplate&&this._canvasTemplate.render(t,e,i)}destroy(t=!0){this._particleTemplate instanceof m&&this._particleTemplate.dispose(),super.destroy(t)}}e.ClassUtils.regClass("laya.particle.Particle2D",_),e.ClassUtils.regClass("Laya.Particle2D",_),e.ILaya.regClass(_);t.Emitter2D=c,t.EmitterBase=d,t.Particle2D=_,t.ParticleData=a,t.ParticleEmitter=class{constructor(t,e,i){this._timeLeftOver=0,this._tempVelocity=new Float32Array([0,0,0]),this._tempPosition=new Float32Array([0,0,0]),this._templet=t,this._timeBetweenParticles=1/e,this._previousPosition=i}update(t,i){if((t/=1e3)>0){e.MathUtil.subtractVector3(i,this._previousPosition,this._tempVelocity),e.MathUtil.scaleVector3(this._tempVelocity,1/t,this._tempVelocity);for(var r=this._timeLeftOver+t,a=-this._timeLeftOver;r>this._timeBetweenParticles;)a+=this._timeBetweenParticles,r-=this._timeBetweenParticles,e.MathUtil.lerpVector3(this._previousPosition,i,a/t,this._tempPosition),this._templet.addParticleArray(this._tempPosition,this._tempVelocity);this._timeLeftOver=r}this._previousPosition[0]=i[0],this._previousPosition[1]=i[1],this._previousPosition[2]=i[2]}},t.ParticleSetting=i,t.ParticleShader=l,t.ParticleShaderValue=h,t.ParticleTemplate2D=m,t.ParticleTemplateBase=r,t.ParticleTemplateWebGL=s}(window.Laya=window.Laya||{},Laya); \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/min/laya.performancetool.min.js b/examples/layaair/frontend/bin/libs/min/laya.performancetool.min.js new file mode 100644 index 0000000..7207354 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/min/laya.performancetool.min.js @@ -0,0 +1 @@ +!function(t,e){"use strict";const a={autoRetryConnnect:!0,retryConnnectCount:0,retryConnnectDelay:1e4};let n=window.WebSocket;class s{constructor(t,e,s,r,o){this.clientId=0,this.socket=null,this.isSupport=!1,this.status=0,this.retryConnnectCount=0,this.onClose=t=>{let{onClose:e,autoRetryConnnect:a,retryConnnectCount:n}=this.options;n=n||0,e&&e(t),0===this.status&&a&&(0==n||this.retryConnnectCount{clearTimeout(this._delayRetryConnnectTimer),this.retryConnnectCount++,this.reConnect()},this.onMessage=t=>{const{onMessage:e}=this.options;e&&e(t)},this.onError=t=>{const{onError:e}=this.options;e&&e(t)},this.onOpen=t=>{const{onOpen:e}=this.options;e&&e(t),this.retryConnnectCount=0,clearTimeout(this._delayRetryConnnectTimer)},this.url="ws://"+t+":"+e+"?type="+r+"&name="+s,o?(Object.assign(o,a),this.options=o):this.options=a,n=window.WebSocket,this.isSupport=void 0!==n,this.isSupport?this.reConnect():console.log("not support websocket")}closeConnect(){if(this.retryConnnectCount=0,this.socket){let t=this.socket;t.onclose=null,t.onmessage=null,t.onerror=null,t.onopen=null,t.close(),this.socket=null}this.status=0}delayRetryConnnect(){clearTimeout(this._delayRetryConnnectTimer),r.enable&&(this._delayRetryConnnectTimer=setTimeout(this._delayRetryConnnect,this.options.retryConnnectDelay))}reConnect(){let t=new n(this.url);this.socket=t,t.onclose=this.onClose,t.onmessage=this.onMessage,t.onerror=this.onError,t.onopen=this.onOpen}dispose(){this.closeConnect()}send(t){return!(!this.socket||1!==this.socket.readyState)&&(this.socket.send(t),!0)}}const getParameterByName=function(t,e){t=t.replace(/[\[\]]/g,"\\$&");var a=new RegExp("[?&]"+t+"(=([^&#]*)|&|#|$)").exec(e);return a?a[2]?decodeURIComponent(a[2].replace(/\+/g," ")):"":null};class r{constructor(){this.socketManager=null,this.selectPlayerId=0,this.active=0,this.selectPlayerStatus=0,this.sendMsg=(t,e,a=0)=>{this.socketManager.send(JSON.stringify({type:t,data:e,toId:a}))},this.sendInternalMsg=(t,e,a=0)=>{this.socketManager.send(JSON.stringify({type:t,data:e,toId:a}))},this.frameDataList=[],this.sendFramData=t=>{this.active&&(this.frameDataList.push(t),this.frameDataList.length>=30&&(this.sendFramDataList(this.frameDataList),this.frameDataList.length=0))},this.sendConfigData=(t=null)=>{let e=this.performanceDataTool.getPathInfo();this.sendInternalMsg("getPerformanceConf_back",e)},this.sendFramDataList=t=>{let e=t.map(t=>({type:"frameData",data:t}));this.sendInternalMsg("msgList",e)}}static set enable(t){if(r._enable!==t)if(r._enable=t,t){const t=r.initOption;if(!t)throw new Error("没有执行初始化init");const{type:e,performanceDataTool:a,onOpen:n,onMessage:s,retryConnectCount:o,retryConnnectDelay:i}=t;r.init(e,a,n,s,o,i)}else r.dispose()}static get enable(){return r._enable}init(t,e,n,o,i,h){if(this.frameDataList=[],"player"===t&&!e)throw new Error("type为player时,performanceDataTool不为空");var l="",_="",d="";window&&window.location&&window.location.href&&(d=window.location.href);var c=getParameterByName("profileName",d)||"",p=getParameterByName("profilePort",d)||"1050";if(r.Host||getParameterByName("profileHost",d))l=r.Host||getParameterByName("profileHost",d);else if(d.startsWith("http")){var D=d.indexOf("//"),R=d.indexOf("/",D+3);-1===R&&(R=d.length),(R=(_=d.substring(D+2,R)).indexOf(":"))>=0&&(_=_.substring(0,R)),l=_}else l="localhost";this.performanceDataTool=e,this.heartIntervalHandler=setInterval(()=>{this.sendInternalMsg("heart",{})},1e4),this.socketManager=new s(l,p,c,t,{retryConnectCount:i||a.retryConnnectCount,retryConnnectDelay:h||a.retryConnnectDelay,onMessage:t=>{if(this.socketManager&&"string"==typeof t.data){let e=JSON.parse(t.data),a=[e];"msgList"===e.type&&(a=e.data),a.forEach(t=>{switch(t.type){case"onSelectMe":this.sendInternalMsg("onSelectMe_back",t.data);break;case"getPerformanceConf":this.sendConfigData();break;case"selectPlayer_back":this.selectPlayerId=t.data.selectPlayer,this.selectPlayerStatus=0;break;case"onReady":this.socketManager.clientId=t.data.id,this.sendInternalMsg("start",{});break;case"active":this.active=t.data.active;break;case"playerList":if(this.selectPlayerId&&(((t,e)=>{for(let a=0;a0&&0==this.selectPlayerStatus){let e=t.data[0].id;this.selectPlayerStatus=1,this.sendMsg("selectPlayer",{id:e})}}}),o&&a.forEach(t=>{o(t)})}},onOpen:t=>{n&&n(t)},onError:t=>{},onClose:t=>{}})}dispose(){clearInterval(this.heartIntervalHandler),this.socketManager&&(this.socketManager.dispose(),this.socketManager=null),this.performanceDataTool=null}static init(t,e,a,n,s,o){r.instance&&r.instance.dispose(),r.initOption={type:t,performanceDataTool:e,onOpen:a,onMessage:n,retryConnectCount:s,retryConnnectDelay:o},r._enable&&(r.instance=new r,r.instance.init(t,e,a,n,s,o))}}r.sendFramData=t=>{r._enable&&r.instance&&r.instance.sendFramData(t)},r.sendConfigData=t=>{r._enable&&r.instance&&r.instance.sendConfigData(t)},r.dispose=()=>{r.instance&&r.instance.dispose(),r.instance=null};class o{constructor(){this._enable=!1,this._AllPathMap={},this._pathColor={},this._pathCount=0,this._runtimeShowPathIndex=-1,this._nodeList=[],this.samplerFramStep=6,this._memoryDataMap={},this.pointArray=[],this.fpsArray=[]}static InitLayaPerformanceInfo(){o.instance.InitLayaPerformanceInfo()}InitLayaPerformanceInfo(){this.setPathDataColor(o.PERFORMANCE_LAYA_2D,[255,128,128,255]),this.setPathDataColor(o.PERFORMANCE_LAYA_3D,[255,255,128,255]),this.setPathDataColor(o.PERFORMANCE_LAYA_3D_RENDER,[128,255,128,255]),this.setPathDataColor(o.PERFORMANCE_LAYA_3D_UPDATESCRIPT,[128,255,255,255]),this.setPathDataColor(o.PERFORMANCE_LAYA_3D_PHYSICS,[0,128,255,255]),this.setPathDataColor(o.PERFORMANCE_LAYA_3D_PHYSICS_SIMULATE,[255,0,0,255]),this.setPathDataColor(o.PERFORMANCE_LAYA_3D_PHYSICS_CHARACTORCOLLISION,[255,128,0,255]),this.setPathDataColor(o.PERFORMANCE_LAYA_3D_PHYSICS_EVENTSCRIPTS,[128,0,0,255]),this.setPathDataColor(o.PERFORMANCE_LAYA_3D_RENDER,[64,128,128,255]),this.setPathDataColor(o.PERFORMANCE_LAYA_3D_RENDER_SHADOWMAP,[192,192,192,255]),this.setPathDataColor(o.PERFORMANCE_LAYA_3D_RENDER_CLUSTER,[128,64,64,255]),this.setPathDataColor(o.PERFORMANCE_LAYA_3D_RENDER_CULLING,[0,64,128,255]),this.setPathDataColor(o.PERFORMANCE_LAYA_3D_RENDER_RENDERDEPTHMDOE,[128,0,64,255]),this.setPathDataColor(o.PERFORMANCE_LAYA_3D_RENDER_RENDEROPAQUE,[128,0,255,255]),this.setPathDataColor(o.PERFORMANCE_LAYA_3D_RENDER_RENDERCOMMANDBUFFER,[128,128,64,255]),this.setPathDataColor(o.PERFORMANCE_LAYA_3D_RENDER_RENDERTRANSPARENT,[128,0,255,255]),this.setPathDataColor(o.PERFORMANCE_LAYA_3D_RENDER_POSTPROCESS,[0,255,0,255])}set enable(t){t?(this._startFram=e.Stat.loopCount,this.resetReCordData(),this._sp=new e.Sprite,this._sp.pos(0,400).zOrder=99,e.Laya.stage.addChild(this._sp)):e.Laya.stage.removeChild(this._sp),this._enable=t}get enable(){return this._enable}get enableDataExport(){return this._enableDataExport}set enableDataExport(t){t?(r.init("player",this),r.enable=t,this.samplerFramStep=1):r.enable=t,this._enableDataExport=t}set runtimeShowPath(t){let e=this._AllPathMap[t];for(let t in this.pointArray)delete this.pointArray[t],delete o.stepLengthArrayMap[t];this._runtimeShowPathIndex=null!=e?e:-1}getNodePathIndex(t){var e;return null!=this._AllPathMap[t]?e=this._AllPathMap[t]:(e=this._pathCount++,this._AllPathMap[t]=e,r.sendConfigData(this.getPathInfo())),e}getPathInfo(){let t={};return 0==Object.keys(this._pathColor).length&&this.InitLayaPerformanceInfo(),t._pathColor=this._pathColor,t._AllPathMap=this._AllPathMap,t}exportPerformanceFile(t=!1){o.InitLayaPerformanceInfo(),t||(this.enable=!1);let a,n,s,r=[],i=[],h=[],l=0,_=new e.Byte;_.pos=0,_.writeUTFString(o.VERSION),r.push("DataInfo01","Color","NodeInfo"),_.writeUint16(r.length);for(let t=0;t{i.revert(t)}),this._nodeList=[],this._runtimeNode=null,this._AllPathMap={},this._memoryDataMap={},this._pathColor={},this._pathCount=0}exportFrontNode(t,e){if(!t||!t.nodeDelty||-1==e)return;const a=o.DrawWidth,n=o.DrawHeight,s=o.StepLength;let r,i,h;this._sp.graphics.clear(),this._sp.graphics.drawRect(0,0,a,n,"rgba(150, 150, 150, 0.8)");for(let l=0,_=t.nodeDelty.length;l<_;l++){if(l!=e&&l!=this.getNodePathIndex(o.PERFORMANCE_DELTYTIME))continue;i=t.nodeDelty[l],h=i/33,this.pointArray[l]||(this.pointArray[l]=[]),r=this.pointArray[l],r.length>=s&&r.shift(),r.push(h);let _=l.toString(16),d=`#${_}${_}C4${_}${_}`;l==this.getNodePathIndex(o.PERFORMANCE_DELTYTIME)&&(d="#FFFFFF"),o.stepLengthArrayMap[l]||(o.stepLengthArrayMap[l]=new Array(2*o.StepLength)),this.updatelineChart(a,n,s,r,d,1,o.stepLengthArrayMap[l])}this._sp.graphics.drawLine(0,n/2,a,n/2,"green",1),this._sp.graphics.drawLine(0,n/4*3,a,n/4*3,"red",1)}updatelineChart(t,e,a,n,s,r,o){switch(r){case 1:let r=o;for(let s=0,o=n.length;s0?this._pool.pop():new i,e.resetData(t),e.inPool=!1,e}static revert(t){t.inPool=!0,this._pool.push(t),t.clearData()}clearData(){this.nodeStart.length=0,this.nodeDelty.length=0}resetData(t){this.nodeNum=t,this.nodeStart.length=t,this.nodeDelty.length=t}getFunStart(t){this.applyCount++,this.nodeStart[t]=performance.now()}getFunEnd(t){return this.nodeDelty[t]?this.nodeDelty[t]+=0!=this.nodeStart[t]?performance.now()-this.nodeStart[t]:0:(this.nodeDelty[t]=0!=this.nodeStart[t]?performance.now()-this.nodeStart[t]:0,this.nodeNum=this.nodeDelty.length),this.nodeDelty[t]}setMemory(t,e){this.nodeDelty[t]=e}getPathData(t){return this.nodeDelty[t]}}i._pool=[];class h{static parsePerformanceFile(t,e){t.pos=0,h.performanceData=e,h._readData=t,h.READ_DATA();for(let t=0,e=h._blockStr.length;tnull),this.m_count=0}Reset(){return this.m_count=0,this}Push(t){this.m_stack[this.m_count]=t,this.m_count++}Pop(){this.m_count--;const t=this.m_stack[this.m_count];return this.m_stack[this.m_count]=null,t}GetCount(){return this.m_count}}const a=Math.abs;function b2Min(t,e){return te?t:e}function b2Clamp(t,e,s){return ts?s:t}const _=isFinite;function b2Sq(t){return t*t}const l=Math.sqrt,m=Math.pow;const c=Math.cos,u=Math.sin,d=Math.acos,p=Math.asin,y=Math.atan2;class b{constructor(t=0,e=0){this.x=t,this.y=e}Clone(){return new b(this.x,this.y)}SetZero(){return this.x=0,this.y=0,this}Set(t,e){return this.x=t,this.y=e,this}Copy(t){return this.x=t.x,this.y=t.y,this}SelfAdd(t){return this.x+=t.x,this.y+=t.y,this}SelfAddXY(t,e){return this.x+=t,this.y+=e,this}SelfSub(t){return this.x-=t.x,this.y-=t.y,this}SelfSubXY(t,e){return this.x-=t,this.y-=e,this}SelfMul(t){return this.x*=t,this.y*=t,this}SelfMulAdd(t,e){return this.x+=t*e.x,this.y+=t*e.y,this}SelfMulSub(t,e){return this.x-=t*e.x,this.y-=t*e.y,this}Dot(t){return this.x*t.x+this.y*t.y}Cross(t){return this.x*t.y-this.y*t.x}Length(){const t=this.x,e=this.y;return Math.sqrt(t*t+e*e)}LengthSquared(){const t=this.x,e=this.y;return t*t+e*e}Normalize(){const t=this.Length();if(t>=1e-5){const e=1/t;this.x*=e,this.y*=e}return t}SelfNormalize(){const t=this.Length();if(t>=1e-5){const e=1/t;this.x*=e,this.y*=e}return this}SelfRotate(t){const e=Math.cos(t),s=Math.sin(t),i=this.x;return this.x=e*i-s*this.y,this.y=s*i+e*this.y,this}SelfRotateCosSin(t,e){const s=this.x;return this.x=t*s-e*this.y,this.y=e*s+t*this.y,this}IsValid(){return isFinite(this.x)&&isFinite(this.y)}SelfCrossVS(t){const e=this.x;return this.x=t*this.y,this.y=-t*e,this}SelfCrossSV(t){const e=this.x;return this.x=-t*this.y,this.y=t*e,this}SelfMinV(t){return this.x=b2Min(this.x,t.x),this.y=b2Min(this.y,t.y),this}SelfMaxV(t){return this.x=b2Max(this.x,t.x),this.y=b2Max(this.y,t.y),this}SelfAbs(){return this.x=a(this.x),this.y=a(this.y),this}SelfNeg(){return this.x=-this.x,this.y=-this.y,this}SelfSkew(){const t=this.x;return this.x=-this.y,this.y=t,this}static MakeArray(t){return b2MakeArray(t,t=>new b)}static AbsV(t,e){return e.x=a(t.x),e.y=a(t.y),e}static MinV(t,e,s){return s.x=b2Min(t.x,e.x),s.y=b2Min(t.y,e.y),s}static MaxV(t,e,s){return s.x=b2Max(t.x,e.x),s.y=b2Max(t.y,e.y),s}static ClampV(t,e,s,i){return i.x=b2Clamp(t.x,e.x,s.x),i.y=b2Clamp(t.y,e.y,s.y),i}static RotateV(t,e,s){const i=t.x,n=t.y,o=Math.cos(e),r=Math.sin(e);return s.x=o*i-r*n,s.y=r*i+o*n,s}static DotVV(t,e){return t.x*e.x+t.y*e.y}static CrossVV(t,e){return t.x*e.y-t.y*e.x}static CrossVS(t,e,s){const i=t.x;return s.x=e*t.y,s.y=-e*i,s}static CrossVOne(t,e){const s=t.x;return e.x=t.y,e.y=-s,e}static CrossSV(t,e,s){const i=e.x;return s.x=-t*e.y,s.y=t*i,s}static CrossOneV(t,e){const s=t.x;return e.x=-t.y,e.y=s,e}static AddVV(t,e,s){return s.x=t.x+e.x,s.y=t.y+e.y,s}static SubVV(t,e,s){return s.x=t.x-e.x,s.y=t.y-e.y,s}static MulSV(t,e,s){return s.x=e.x*t,s.y=e.y*t,s}static MulVS(t,e,s){return s.x=t.x*e,s.y=t.y*e,s}static AddVMulSV(t,e,s,i){return i.x=t.x+e*s.x,i.y=t.y+e*s.y,i}static SubVMulSV(t,e,s,i){return i.x=t.x-e*s.x,i.y=t.y-e*s.y,i}static AddVCrossSV(t,e,s,i){const n=s.x;return i.x=t.x-e*s.y,i.y=t.y+e*n,i}static MidVV(t,e,s){return s.x=.5*(t.x+e.x),s.y=.5*(t.y+e.y),s}static ExtVV(t,e,s){return s.x=.5*(e.x-t.x),s.y=.5*(e.y-t.y),s}static IsEqualToV(t,e){return t.x===e.x&&t.y===e.y}static DistanceVV(t,e){const s=t.x-e.x,i=t.y-e.y;return Math.sqrt(s*s+i*i)}static DistanceSquaredVV(t,e){const s=t.x-e.x,i=t.y-e.y;return s*s+i*i}static NegV(t,e){return e.x=-t.x,e.y=-t.y,e}}b.ZERO=new b(0,0),b.UNITX=new b(1,0),b.UNITY=new b(0,1),b.s_t0=new b,b.s_t1=new b,b.s_t2=new b,b.s_t3=new b;const x=new b(0,0);class A{constructor(...t){if(t[0]instanceof Float32Array){if(3!==t[0].length)throw new Error;this.data=t[0]}else{const e="number"==typeof t[0]?t[0]:0,s="number"==typeof t[1]?t[1]:0,i="number"==typeof t[2]?t[2]:0;this.data=new Float32Array([e,s,i])}}get x(){return this.data[0]}set x(t){this.data[0]=t}get y(){return this.data[1]}set y(t){this.data[1]=t}get z(){return this.data[2]}set z(t){this.data[2]=t}Clone(){return new A(this.x,this.y,this.z)}SetZero(){return this.x=0,this.y=0,this.z=0,this}SetXYZ(t,e,s){return this.x=t,this.y=e,this.z=s,this}Copy(t){return this.x=t.x,this.y=t.y,this.z=t.z,this}SelfNeg(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this}SelfAdd(t){return this.x+=t.x,this.y+=t.y,this.z+=t.z,this}SelfAddXYZ(t,e,s){return this.x+=t,this.y+=e,this.z+=s,this}SelfSub(t){return this.x-=t.x,this.y-=t.y,this.z-=t.z,this}SelfSubXYZ(t,e,s){return this.x-=t,this.y-=e,this.z-=s,this}SelfMul(t){return this.x*=t,this.y*=t,this.z*=t,this}static DotV3V3(t,e){return t.x*e.x+t.y*e.y+t.z*e.z}static CrossV3V3(t,e,s){const i=t.x,n=t.y,o=t.z,r=e.x,h=e.y,a=e.z;return s.x=n*a-o*h,s.y=o*r-i*a,s.z=i*h-n*r,s}}A.ZERO=new A(0,0,0),A.s_t0=new A;class f{constructor(){this.ex=new b(1,0),this.ey=new b(0,1)}Clone(){return(new f).Copy(this)}static FromVV(t,e){return(new f).SetVV(t,e)}static FromSSSS(t,e,s,i){return(new f).SetSSSS(t,e,s,i)}static FromAngle(t){return(new f).SetAngle(t)}SetSSSS(t,e,s,i){return this.ex.Set(t,s),this.ey.Set(e,i),this}SetVV(t,e){return this.ex.Copy(t),this.ey.Copy(e),this}SetAngle(t){const e=Math.cos(t),s=Math.sin(t);return this.ex.Set(e,s),this.ey.Set(-s,e),this}Copy(t){return this.ex.Copy(t.ex),this.ey.Copy(t.ey),this}SetIdentity(){return this.ex.Set(1,0),this.ey.Set(0,1),this}SetZero(){return this.ex.SetZero(),this.ey.SetZero(),this}GetAngle(){return Math.atan2(this.ex.y,this.ex.x)}GetInverse(t){const e=this.ex.x,s=this.ey.x,i=this.ex.y,n=this.ey.y;let o=e*n-s*i;return 0!==o&&(o=1/o),t.ex.x=o*n,t.ey.x=-o*s,t.ex.y=-o*i,t.ey.y=o*e,t}Solve(t,e,s){const i=this.ex.x,n=this.ey.x,o=this.ex.y,r=this.ey.y;let h=i*r-n*o;return 0!==h&&(h=1/h),s.x=h*(r*t-n*e),s.y=h*(i*e-o*t),s}SelfAbs(){return this.ex.SelfAbs(),this.ey.SelfAbs(),this}SelfInv(){return this.GetInverse(this),this}SelfAddM(t){return this.ex.SelfAdd(t.ex),this.ey.SelfAdd(t.ey),this}SelfSubM(t){return this.ex.SelfSub(t.ex),this.ey.SelfSub(t.ey),this}static AbsM(t,e){const s=t.ex,i=t.ey;return e.ex.x=a(s.x),e.ex.y=a(s.y),e.ey.x=a(i.x),e.ey.y=a(i.y),e}static MulMV(t,e,s){const i=t.ex,n=t.ey,o=e.x,r=e.y;return s.x=i.x*o+n.x*r,s.y=i.y*o+n.y*r,s}static MulTMV(t,e,s){const i=t.ex,n=t.ey,o=e.x,r=e.y;return s.x=i.x*o+i.y*r,s.y=n.x*o+n.y*r,s}static AddMM(t,e,s){const i=t.ex,n=t.ey,o=e.ex,r=e.ey;return s.ex.x=i.x+o.x,s.ex.y=i.y+o.y,s.ey.x=n.x+r.x,s.ey.y=n.y+r.y,s}static MulMM(t,e,s){const i=t.ex.x,n=t.ex.y,o=t.ey.x,r=t.ey.y,h=e.ex.x,a=e.ex.y,_=e.ey.x,l=e.ey.y;return s.ex.x=i*h+o*a,s.ex.y=n*h+r*a,s.ey.x=i*_+o*l,s.ey.y=n*_+r*l,s}static MulTMM(t,e,s){const i=t.ex.x,n=t.ex.y,o=t.ey.x,r=t.ey.y,h=e.ex.x,a=e.ex.y,_=e.ey.x,l=e.ey.y;return s.ex.x=i*h+n*a,s.ex.y=o*h+r*a,s.ey.x=i*_+n*l,s.ey.y=o*_+r*l,s}}f.IDENTITY=new f;class S{constructor(){this.data=new Float32Array([1,0,0,0,1,0,0,0,1]),this.ex=new A(this.data.subarray(0,3)),this.ey=new A(this.data.subarray(3,6)),this.ez=new A(this.data.subarray(6,9))}Clone(){return(new S).Copy(this)}SetVVV(t,e,s){return this.ex.Copy(t),this.ey.Copy(e),this.ez.Copy(s),this}Copy(t){return this.ex.Copy(t.ex),this.ey.Copy(t.ey),this.ez.Copy(t.ez),this}SetIdentity(){return this.ex.SetXYZ(1,0,0),this.ey.SetXYZ(0,1,0),this.ez.SetXYZ(0,0,1),this}SetZero(){return this.ex.SetZero(),this.ey.SetZero(),this.ez.SetZero(),this}SelfAddM(t){return this.ex.SelfAdd(t.ex),this.ey.SelfAdd(t.ey),this.ez.SelfAdd(t.ez),this}Solve33(t,e,s,i){const n=this.ex.x,o=this.ex.y,r=this.ex.z,h=this.ey.x,a=this.ey.y,_=this.ey.z,l=this.ez.x,m=this.ez.y,c=this.ez.z;let u=n*(a*c-_*m)+o*(_*l-h*c)+r*(h*m-a*l);return 0!==u&&(u=1/u),i.x=u*(t*(a*c-_*m)+e*(_*l-h*c)+s*(h*m-a*l)),i.y=u*(n*(e*c-s*m)+o*(s*l-t*c)+r*(t*m-e*l)),i.z=u*(n*(a*s-_*e)+o*(_*t-h*s)+r*(h*e-a*t)),i}Solve22(t,e,s){const i=this.ex.x,n=this.ey.x,o=this.ex.y,r=this.ey.y;let h=i*r-n*o;return 0!==h&&(h=1/h),s.x=h*(r*t-n*e),s.y=h*(i*e-o*t),s}GetInverse22(t){const e=this.ex.x,s=this.ey.x,i=this.ex.y,n=this.ey.y;let o=e*n-s*i;0!==o&&(o=1/o),t.ex.x=o*n,t.ey.x=-o*s,t.ex.z=0,t.ex.y=-o*i,t.ey.y=o*e,t.ey.z=0,t.ez.x=0,t.ez.y=0,t.ez.z=0}GetSymInverse33(t){let e=A.DotV3V3(this.ex,A.CrossV3V3(this.ey,this.ez,A.s_t0));0!==e&&(e=1/e);const s=this.ex.x,i=this.ey.x,n=this.ez.x,o=this.ey.y,r=this.ez.y,h=this.ez.z;t.ex.x=e*(o*h-r*r),t.ex.y=e*(n*r-i*h),t.ex.z=e*(i*r-n*o),t.ey.x=t.ex.y,t.ey.y=e*(s*h-n*n),t.ey.z=e*(n*i-s*r),t.ez.x=t.ex.z,t.ez.y=t.ey.z,t.ez.z=e*(s*o-i*i)}static MulM33V3(t,e,s){const i=e.x,n=e.y,o=e.z;return s.x=t.ex.x*i+t.ey.x*n+t.ez.x*o,s.y=t.ex.y*i+t.ey.y*n+t.ez.y*o,s.z=t.ex.z*i+t.ey.z*n+t.ez.z*o,s}static MulM33XYZ(t,e,s,i,n){return n.x=t.ex.x*e+t.ey.x*s+t.ez.x*i,n.y=t.ex.y*e+t.ey.y*s+t.ez.y*i,n.z=t.ex.z*e+t.ey.z*s+t.ez.z*i,n}static MulM33V2(t,e,s){const i=e.x,n=e.y;return s.x=t.ex.x*i+t.ey.x*n,s.y=t.ex.y*i+t.ey.y*n,s}static MulM33XY(t,e,s,i){return i.x=t.ex.x*e+t.ey.x*s,i.y=t.ex.y*e+t.ey.y*s,i}}S.IDENTITY=new S;class w{constructor(t=0){this.s=0,this.c=1,t&&(this.s=Math.sin(t),this.c=Math.cos(t))}Clone(){return(new w).Copy(this)}Copy(t){return this.s=t.s,this.c=t.c,this}SetAngle(t){return this.s=Math.sin(t),this.c=Math.cos(t),this}SetIdentity(){return this.s=0,this.c=1,this}GetAngle(){return Math.atan2(this.s,this.c)}GetXAxis(t){return t.x=this.c,t.y=this.s,t}GetYAxis(t){return t.x=-this.s,t.y=this.c,t}static MulRR(t,e,s){const i=t.c,n=t.s,o=e.c,r=e.s;return s.s=n*o+i*r,s.c=i*o-n*r,s}static MulTRR(t,e,s){const i=t.c,n=t.s,o=e.c,r=e.s;return s.s=i*r-n*o,s.c=i*o+n*r,s}static MulRV(t,e,s){const i=t.c,n=t.s,o=e.x,r=e.y;return s.x=i*o-n*r,s.y=n*o+i*r,s}static MulTRV(t,e,s){const i=t.c,n=t.s,o=e.x,r=e.y;return s.x=i*o+n*r,s.y=-n*o+i*r,s}}w.IDENTITY=new w;class g{constructor(){this.p=new b,this.q=new w}Clone(){return(new g).Copy(this)}Copy(t){return this.p.Copy(t.p),this.q.Copy(t.q),this}SetIdentity(){return this.p.SetZero(),this.q.SetIdentity(),this}SetPositionRotation(t,e){return this.p.Copy(t),this.q.Copy(e),this}SetPositionAngle(t,e){return this.p.Copy(t),this.q.SetAngle(e),this}SetPosition(t){return this.p.Copy(t),this}SetPositionXY(t,e){return this.p.Set(t,e),this}SetRotation(t){return this.q.Copy(t),this}SetRotationAngle(t){return this.q.SetAngle(t),this}GetPosition(){return this.p}GetRotation(){return this.q}GetRotationAngle(){return this.q.GetAngle()}GetAngle(){return this.q.GetAngle()}static MulXV(t,e,s){const i=t.q.c,n=t.q.s,o=e.x,r=e.y;return s.x=i*o-n*r+t.p.x,s.y=n*o+i*r+t.p.y,s}static MulTXV(t,e,s){const i=t.q.c,n=t.q.s,o=e.x-t.p.x,r=e.y-t.p.y;return s.x=i*o+n*r,s.y=-n*o+i*r,s}static MulXX(t,e,s){return w.MulRR(t.q,e.q,s.q),b.AddVV(w.MulRV(t.q,e.p,s.p),t.p,s.p),s}static MulTXX(t,e,s){return w.MulTRR(t.q,e.q,s.q),w.MulTRV(t.q,b.SubVV(e.p,t.p,s.p),s.p),s}}g.IDENTITY=new g;class C{constructor(){this.localCenter=new b,this.c0=new b,this.c=new b,this.a0=0,this.a=0,this.alpha0=0}Clone(){return(new C).Copy(this)}Copy(t){return this.localCenter.Copy(t.localCenter),this.c0.Copy(t.c0),this.c.Copy(t.c),this.a0=t.a0,this.a=t.a,this.alpha0=t.alpha0,this}GetTransform(t,e){t.p.x=(1-e)*this.c0.x+e*this.c.x,t.p.y=(1-e)*this.c0.y+e*this.c.y;const s=(1-e)*this.a0+e*this.a;return t.q.SetAngle(s),t.p.SelfSub(w.MulRV(t.q,this.localCenter,b.s_t0)),t}Advance(t){const e=(t-this.alpha0)/(1-this.alpha0);this.c0.SelfMulAdd(e,this.c.Clone().SelfSub(this.c0)),this.a0+=e*(this.a-this.a0),this.alpha0=t}Normalize(){const t=6.28318530718*Math.floor(this.a0/6.28318530718);this.a0-=t,this.a-=t}}class V{constructor(){this.m_start=Date.now()}Reset(){return this.m_start=Date.now(),this}GetMilliseconds(){return Date.now()-this.m_start}}class B{constructor(){this.mass=0,this.center=new b(0,0),this.I=0}}var v;t.b2ShapeType=void 0,(v=t.b2ShapeType||(t.b2ShapeType={}))[v.e_unknown=-1]="e_unknown",v[v.e_circleShape=0]="e_circleShape",v[v.e_edgeShape=1]="e_edgeShape",v[v.e_polygonShape=2]="e_polygonShape",v[v.e_chainShape=3]="e_chainShape",v[v.e_shapeTypeCount=4]="e_shapeTypeCount";class M{constructor(e,s){this.m_type=t.b2ShapeType.e_unknown,this.m_radius=0,this.m_type=e,this.m_radius=s}Copy(t){return this.m_radius=t.m_radius,this}GetType(){return this.m_type}}class I{constructor(){this.m_buffer=b.MakeArray(2),this.m_vertices=this.m_buffer,this.m_count=0,this.m_radius=0}Copy(t){return t.m_vertices===t.m_buffer?(this.m_vertices=this.m_buffer,this.m_buffer[0].Copy(t.m_buffer[0]),this.m_buffer[1].Copy(t.m_buffer[1])):this.m_vertices=t.m_vertices,this.m_count=t.m_count,this.m_radius=t.m_radius,this}Reset(){return this.m_vertices=this.m_buffer,this.m_count=0,this.m_radius=0,this}SetShape(t,e){t.SetupDistanceProxy(this,e)}SetVerticesRadius(t,e,s){this.m_vertices=t,this.m_count=e,this.m_radius=s}Set(...t){t[0]instanceof M?this.SetShape(t[0],t[1]):this.SetVerticesRadius(t[0],t[1],t[2])}GetSupport(t){let e=0,s=b.DotVV(this.m_vertices[0],t);for(let i=1;is&&(e=i,s=n)}return e}GetSupportVertex(t){let e=0,s=b.DotVV(this.m_vertices[0],t);for(let i=1;is&&(e=i,s=n)}return this.m_vertices[e]}GetVertexCount(){return this.m_count}GetVertex(t){return this.m_vertices[t]}}class D{constructor(){this.metric=0,this.count=0,this.indexA=[0,0,0],this.indexB=[0,0,0]}Reset(){return this.metric=0,this.count=0,this}}class T{constructor(){this.proxyA=new I,this.proxyB=new I,this.transformA=new g,this.transformB=new g,this.useRadii=!1}Reset(){return this.proxyA.Reset(),this.proxyB.Reset(),this.transformA.SetIdentity(),this.transformB.SetIdentity(),this.useRadii=!1,this}}class G{constructor(){this.pointA=new b,this.pointB=new b,this.distance=0,this.iterations=0}Reset(){return this.pointA.SetZero(),this.pointB.SetZero(),this.distance=0,this.iterations=0,this}}t.b2_gjkCalls=0,t.b2_gjkIters=0,t.b2_gjkMaxIters=0;class P{constructor(){this.wA=new b,this.wB=new b,this.w=new b,this.a=0,this.indexA=0,this.indexB=0}Copy(t){return this.wA.Copy(t.wA),this.wB.Copy(t.wB),this.w.Copy(t.w),this.a=t.a,this.indexA=t.indexA,this.indexB=t.indexB,this}}class L{constructor(){this.m_v1=new P,this.m_v2=new P,this.m_v3=new P,this.m_vertices=[],this.m_count=0,this.m_vertices[0]=this.m_v1,this.m_vertices[1]=this.m_v2,this.m_vertices[2]=this.m_v3}ReadCache(t,e,s,i,n){this.m_count=t.count;const o=this.m_vertices;for(let r=0;r1){const e=t.metric,s=this.GetMetric();(s<.5*e||2*e0?b.CrossOneV(e,t):b.CrossVOne(e,t)}default:return t.SetZero()}}GetClosestPoint(t){switch(this.m_count){case 0:return t.SetZero();case 1:return t.Copy(this.m_v1.w);case 2:return t.Set(this.m_v1.a*this.m_v1.w.x+this.m_v2.a*this.m_v2.w.x,this.m_v1.a*this.m_v1.w.y+this.m_v2.a*this.m_v2.w.y);case 3:default:return t.SetZero()}}GetWitnessPoints(t,e){switch(this.m_count){case 0:break;case 1:t.Copy(this.m_v1.wA),e.Copy(this.m_v1.wB);break;case 2:t.x=this.m_v1.a*this.m_v1.wA.x+this.m_v2.a*this.m_v2.wA.x,t.y=this.m_v1.a*this.m_v1.wA.y+this.m_v2.a*this.m_v2.wA.y,e.x=this.m_v1.a*this.m_v1.wB.x+this.m_v2.a*this.m_v2.wB.x,e.y=this.m_v1.a*this.m_v1.wB.y+this.m_v2.a*this.m_v2.wB.y;break;case 3:e.x=t.x=this.m_v1.a*this.m_v1.wA.x+this.m_v2.a*this.m_v2.wA.x+this.m_v3.a*this.m_v3.wA.x,e.y=t.y=this.m_v1.a*this.m_v1.wA.y+this.m_v2.a*this.m_v2.wA.y+this.m_v3.a*this.m_v3.wA.y}}GetMetric(){switch(this.m_count){case 0:case 1:return 0;case 2:return b.DistanceVV(this.m_v1.w,this.m_v2.w);case 3:return b.CrossVV(b.SubVV(this.m_v2.w,this.m_v1.w,b.s_t0),b.SubVV(this.m_v3.w,this.m_v1.w,b.s_t1));default:return 0}}Solve2(){const t=this.m_v1.w,e=this.m_v2.w,s=b.SubVV(e,t,L.s_e12),i=-b.DotVV(t,s);if(i<=0)return this.m_v1.a=1,void(this.m_count=1);const n=b.DotVV(e,s);if(n<=0)return this.m_v2.a=1,this.m_count=1,void this.m_v1.Copy(this.m_v2);const o=1/(n+i);this.m_v1.a=n*o,this.m_v2.a=i*o,this.m_count=2}Solve3(){const t=this.m_v1.w,e=this.m_v2.w,s=this.m_v3.w,i=b.SubVV(e,t,L.s_e12),n=b.DotVV(t,i),o=b.DotVV(e,i),r=-n,h=b.SubVV(s,t,L.s_e13),a=b.DotVV(t,h),_=b.DotVV(s,h),l=-a,m=b.SubVV(s,e,L.s_e23),c=b.DotVV(e,m),u=b.DotVV(s,m),d=-c,p=b.CrossVV(i,h),y=p*b.CrossVV(e,s),x=p*b.CrossVV(s,t),A=p*b.CrossVV(t,e);if(r<=0&&l<=0)return this.m_v1.a=1,void(this.m_count=1);if(o>0&&r>0&&A<=0){const t=1/(o+r);return this.m_v1.a=o*t,this.m_v2.a=r*t,void(this.m_count=2)}if(_>0&&l>0&&x<=0){const t=1/(_+l);return this.m_v1.a=_*t,this.m_v3.a=l*t,this.m_count=2,void this.m_v2.Copy(this.m_v3)}if(o<=0&&d<=0)return this.m_v2.a=1,this.m_count=1,void this.m_v1.Copy(this.m_v2);if(_<=0&&u<=0)return this.m_v3.a=1,this.m_count=1,void this.m_v1.Copy(this.m_v3);if(u>0&&d>0&&y<=0){const t=1/(u+d);return this.m_v2.a=u*t,this.m_v3.a=d*t,this.m_count=2,void this.m_v1.Copy(this.m_v3)}const f=1/(y+x+A);this.m_v1.a=y*f,this.m_v2.a=x*f,this.m_v3.a=A*f,this.m_count=3}}L.s_e12=new b,L.s_e13=new b,L.s_e23=new b;const R=new L,F=[0,0,0],k=[0,0,0],j=new b,q=new b,J=new b,E=new b,O=new b;function b2Distance(e,s,i){++t.b2_gjkCalls;const n=i.proxyA,o=i.proxyB,r=i.transformA,h=i.transformB,a=R;a.ReadCache(s,n,r,o,h);const _=a.m_vertices,l=F,m=k;let c=0,u=0;for(;u<20;){c=a.m_count;for(let t=0;tt+s&&e.distance>1e-5){e.distance-=t+s;const i=b.SubVV(e.pointB,e.pointA,J);i.Normalize(),e.pointA.SelfMulAdd(t,i),e.pointB.SelfMulSub(s,i)}else{const t=b.MidVV(e.pointA,e.pointB,j);e.pointA.Copy(t),e.pointB.Copy(t),e.distance=0}}}const z=new b,X=new L,N=new b,Z=new b,W=new b,U=new b,Y=new b,Q=new b;var K,H,$;t.b2ContactFeatureType=void 0,(K=t.b2ContactFeatureType||(t.b2ContactFeatureType={}))[K.e_vertex=0]="e_vertex",K[K.e_face=1]="e_face";class tt{constructor(){this._key=0,this._key_invalid=!1,this._indexA=0,this._indexB=0,this._typeA=0,this._typeB=0}get key(){return this._key_invalid&&(this._key_invalid=!1,this._key=this._indexA|this._indexB<<8|this._typeA<<16|this._typeB<<24),this._key}set key(t){this._key=t,this._key_invalid=!1,this._indexA=255&this._key,this._indexB=this._key>>8&255,this._typeA=this._key>>16&255,this._typeB=this._key>>24&255}get indexA(){return this._indexA}set indexA(t){this._indexA=t,this._key_invalid=!0}get indexB(){return this._indexB}set indexB(t){this._indexB=t,this._key_invalid=!0}get typeA(){return this._typeA}set typeA(t){this._typeA=t,this._key_invalid=!0}get typeB(){return this._typeB}set typeB(t){this._typeB=t,this._key_invalid=!0}}class et{constructor(){this.cf=new tt}Copy(t){return this.key=t.key,this}Clone(){return(new et).Copy(this)}get key(){return this.cf.key}set key(t){this.cf.key=t}}class st{constructor(){this.localPoint=new b,this.normalImpulse=0,this.tangentImpulse=0,this.id=new et}static MakeArray(t){return b2MakeArray(t,t=>new st)}Reset(){this.localPoint.SetZero(),this.normalImpulse=0,this.tangentImpulse=0,this.id.key=0}Copy(t){return this.localPoint.Copy(t.localPoint),this.normalImpulse=t.normalImpulse,this.tangentImpulse=t.tangentImpulse,this.id.Copy(t.id),this}}t.b2ManifoldType=void 0,(H=t.b2ManifoldType||(t.b2ManifoldType={}))[H.e_unknown=-1]="e_unknown",H[H.e_circles=0]="e_circles",H[H.e_faceA=1]="e_faceA",H[H.e_faceB=2]="e_faceB";class it{constructor(){this.points=st.MakeArray(2),this.localNormal=new b,this.localPoint=new b,this.type=t.b2ManifoldType.e_unknown,this.pointCount=0}Reset(){for(let t=0;t<2;++t)this.points[t].Reset();this.localNormal.SetZero(),this.localPoint.SetZero(),this.type=t.b2ManifoldType.e_unknown,this.pointCount=0}Copy(t){this.pointCount=t.pointCount;for(let e=0;e<2;++e)this.points[e].Copy(t.points[e]);return this.localNormal.Copy(t.localNormal),this.localPoint.Copy(t.localPoint),this.type=t.type,this}Clone(){return(new it).Copy(this)}}class nt{constructor(){this.normal=new b,this.points=b.MakeArray(2),this.separations=b2MakeNumberArray(2)}Initialize(e,s,i,n,o){if(0!==e.pointCount)switch(e.type){case t.b2ManifoldType.e_circles:{this.normal.Set(1,0);const t=g.MulXV(s,e.localPoint,nt.Initialize_s_pointA),r=g.MulXV(n,e.points[0].localPoint,nt.Initialize_s_pointB);b.DistanceSquaredVV(t,r)>1e-5*1e-5&&b.SubVV(r,t,this.normal).SelfNormalize();const h=b.AddVMulSV(t,i,this.normal,nt.Initialize_s_cA),a=b.SubVMulSV(r,o,this.normal,nt.Initialize_s_cB);b.MidVV(h,a,this.points[0]),this.separations[0]=b.DotVV(b.SubVV(a,h,b.s_t0),this.normal);break}case t.b2ManifoldType.e_faceA:{w.MulRV(s.q,e.localNormal,this.normal);const t=g.MulXV(s,e.localPoint,nt.Initialize_s_planePoint);for(let s=0;snew ot)}Copy(t){return this.v.Copy(t.v),this.id.Copy(t.id),this}}class rt{constructor(){this.p1=new b,this.p2=new b,this.maxFraction=1}Copy(t){return this.p1.Copy(t.p1),this.p2.Copy(t.p2),this.maxFraction=t.maxFraction,this}}class ht{constructor(){this.normal=new b,this.fraction=0}Copy(t){return this.normal.Copy(t.normal),this.fraction=t.fraction,this}}class at{constructor(){this.lowerBound=new b,this.upperBound=new b,this.m_cache_center=new b,this.m_cache_extent=new b}Copy(t){return this.lowerBound.Copy(t.lowerBound),this.upperBound.Copy(t.upperBound),this}IsValid(){return!!this.lowerBound.IsValid()&&(!!this.upperBound.IsValid()&&(!(this.upperBound.xi){const t=e;e=i,i=t,r=1}if(e>s&&(c.x=r,c.y=0,s=e),n=b2Min(n,i),s>n)return!1}if(m<1e-5){if(ri){const t=e;e=i,i=t,o=1}if(e>s&&(c.x=0,c.y=o,s=e),n=b2Min(n,i),s>n)return!1}return!(s<0||e.maxFraction0;){const t=i.Pop();if(null!==t&&t.aabb.TestOverlap(e))if(t.IsLeaf()){if(!s(t))return}else i.Push(t.child1),i.Push(t.child2)}}QueryPoint(t,e){const s=this.m_stack.Reset();for(s.Push(this.m_root);s.GetCount()>0;){const i=s.Pop();if(null!==i&&i.aabb.TestContain(t))if(i.IsLeaf()){if(!e(i))return}else s.Push(i.child1),s.Push(i.child2)}}RayCast(...t){let e,s;t[0]instanceof rt?(s=t[0],e=t[1]):(s=t[1],e=t[0]);const i=s.p1,n=s.p2,o=b.SubVV(n,i,ut.s_r);o.Normalize();const r=b.CrossOneV(o,ut.s_v),h=b.AbsV(r,ut.s_abs_v);let _=s.maxFraction;const l=ut.s_segmentAABB;let m=i.x+_*(n.x-i.x),c=i.y+_*(n.y-i.y);l.lowerBound.x=b2Min(i.x,m),l.lowerBound.y=b2Min(i.y,c),l.upperBound.x=b2Max(i.x,m),l.upperBound.y=b2Max(i.y,c);const u=this.m_stack.Reset();for(u.Push(this.m_root);u.GetCount()>0;){const t=u.Pop();if(null===t)continue;if(!b2TestOverlapAABB(t.aabb,l))continue;const o=t.aabb.GetCenter(),d=t.aabb.GetExtents();if(!(a(b.DotVV(r,b.SubVV(i,o,b.s_t0)))-b.DotVV(h,d)>0))if(t.IsLeaf()){const o=ut.s_subInput;o.p1.Copy(s.p1),o.p2.Copy(s.p2),o.maxFraction=_;const r=e(o,t);if(0===r)return;r>0&&(_=r,m=i.x+_*(n.x-i.x),c=i.y+_*(n.y-i.y),l.lowerBound.x=b2Min(i.x,m),l.lowerBound.y=b2Min(i.y,c),l.upperBound.x=b2Max(i.x,m),l.upperBound.y=b2Max(i.y,c))}else u.Push(t.child1),u.Push(t.child2)}}AllocateNode(){if(null!==this.m_freeList){const t=this.m_freeList;return this.m_freeList=t.parent,t.parent=null,t.child1=null,t.child2=null,t.height=0,t.moved=!1,t}return new ct(ut.s_node_id++)}FreeNode(t){t.parent=this.m_freeList,t.child1=null,t.child2=null,t.height=-1,t.Reset(),this.m_freeList=t}CreateProxy(t,e){const s=this.AllocateNode();return s.aabb.lowerBound.x=t.lowerBound.x-.1,s.aabb.lowerBound.y=t.lowerBound.y-.1,s.aabb.upperBound.x=t.upperBound.x+.1,s.aabb.upperBound.y=t.upperBound.y+.1,s.userData=e,s.height=0,s.moved=!0,this.InsertLeaf(s),s}DestroyProxy(t){this.RemoveLeaf(t),this.FreeNode(t)}MoveProxy(t,e,s){const i=ut.MoveProxy_s_fatAABB;i.lowerBound.x=e.lowerBound.x-.1,i.lowerBound.y=e.lowerBound.y-.1,i.upperBound.x=e.upperBound.x+.1,i.upperBound.y=e.upperBound.y+.1;const n=4*s.x,o=4*s.y;n<0?i.lowerBound.x+=n:i.upperBound.x+=n,o<0?i.lowerBound.y+=o:i.upperBound.y+=o;const r=t.aabb;if(r.Contains(e)){const t=ut.MoveProxy_s_hugeAABB;if(t.lowerBound.x=i.lowerBound.x-.4,t.lowerBound.y=i.lowerBound.y-.4,t.upperBound.x=i.upperBound.x+.4,t.upperBound.y=i.upperBound.y+.4,t.Contains(r))return!1}return this.RemoveLeaf(t),t.aabb.Copy(i),this.InsertLeaf(t),t.moved=!0,!0}InsertLeaf(t){if(++this.m_insertionCount,null===this.m_root)return this.m_root=t,void(this.m_root.parent=null);const e=t.aabb;let s=this.m_root;for(;!s.IsLeaf();){const t=verify(s.child1),i=verify(s.child2),n=s.aabb.GetPerimeter(),o=ut.s_combinedAABB;o.Combine2(s.aabb,e);const r=o.GetPerimeter(),h=2*r,a=2*(r-n);let _;const l=ut.s_aabb;let m,c,u;if(t.IsLeaf()?(l.Combine2(e,t.aabb),_=l.GetPerimeter()+a):(l.Combine2(e,t.aabb),m=t.aabb.GetPerimeter(),c=l.GetPerimeter(),_=c-m+a),i.IsLeaf()?(l.Combine2(e,i.aabb),u=l.GetPerimeter()+a):(l.Combine2(e,i.aabb),m=i.aabb.GetPerimeter(),c=l.GetPerimeter(),u=c-m+a),h<_&&h1){const i=verify(s.child1),n=verify(s.child2);return s.child1=t,s.parent=t.parent,t.parent=s,null!==s.parent?s.parent.child1===t?s.parent.child1=s:s.parent.child2=s:this.m_root=s,i.height>n.height?(s.child2=i,t.child2=n,n.parent=t,t.aabb.Combine2(e.aabb,n.aabb),s.aabb.Combine2(t.aabb,i.aabb),t.height=1+b2Max(e.height,n.height),s.height=1+b2Max(t.height,i.height)):(s.child2=n,t.child2=i,i.parent=t,t.aabb.Combine2(e.aabb,i.aabb),s.aabb.Combine2(t.aabb,n.aabb),t.height=1+b2Max(e.height,i.height),s.height=1+b2Max(t.height,n.height)),s}if(i<-1){const i=verify(e.child1),n=verify(e.child2);return e.child1=t,e.parent=t.parent,t.parent=e,null!==e.parent?e.parent.child1===t?e.parent.child1=e:e.parent.child2=e:this.m_root=e,i.height>n.height?(e.child2=i,t.child1=n,n.parent=t,t.aabb.Combine2(s.aabb,n.aabb),e.aabb.Combine2(t.aabb,i.aabb),t.height=1+b2Max(s.height,n.height),e.height=1+b2Max(t.height,i.height)):(e.child2=n,t.child1=i,i.parent=t,t.aabb.Combine2(s.aabb,i.aabb),e.aabb.Combine2(t.aabb,n.aabb),t.height=1+b2Max(s.height,i.height),e.height=1+b2Max(t.height,n.height)),e}return t}GetHeight(){return null===this.m_root?0:this.m_root.height}static GetAreaNode(t){if(null===t)return 0;if(t.IsLeaf())return 0;let e=t.aabb.GetPerimeter();return e+=ut.GetAreaNode(t.child1),e+=ut.GetAreaNode(t.child2),e}GetAreaRatio(){if(null===this.m_root)return 0;const t=this.m_root.aabb.GetPerimeter();return ut.GetAreaNode(this.m_root)/t}static ComputeHeightNode(t){if(null===t)return 0;if(t.IsLeaf())return 0;return 1+b2Max(ut.ComputeHeightNode(t.child1),ut.ComputeHeightNode(t.child2))}ComputeHeight(){return ut.ComputeHeightNode(this.m_root)}ValidateStructure(t){if(null===t)return;if(this.m_root,t.IsLeaf())return;const e=verify(t.child1),s=verify(t.child2);this.ValidateStructure(e),this.ValidateStructure(s)}ValidateMetrics(t){if(null===t)return;if(t.IsLeaf())return;const e=verify(t.child1),s=verify(t.child2);ut.s_aabb.Combine2(e.aabb,s.aabb),this.ValidateMetrics(e),this.ValidateMetrics(s)}Validate(){}static GetMaxBalanceNode(t,e){if(null===t)return e;if(t.height<=1)return e;const s=verify(t.child1),i=verify(t.child2);return b2Max(e,a(i.height-s.height))}GetMaxBalance(){return ut.GetMaxBalanceNode(this.m_root,0)}RebuildBottomUp(){this.Validate()}static ShiftOriginNode(t,e){if(null===t)return;if(t.height<=1)return;const s=t.child1,i=t.child2;ut.ShiftOriginNode(s,e),ut.ShiftOriginNode(i,e),t.aabb.lowerBound.SelfSub(e),t.aabb.upperBound.SelfSub(e)}ShiftOrigin(t){ut.ShiftOriginNode(this.m_root,t)}}ut.s_r=new b,ut.s_v=new b,ut.s_abs_v=new b,ut.s_segmentAABB=new at,ut.s_subInput=new rt,ut.s_combinedAABB=new at,ut.s_aabb=new at,ut.s_node_id=0,ut.MoveProxy_s_fatAABB=new at,ut.MoveProxy_s_hugeAABB=new at;class dt{constructor(t,e){this.proxyA=t,this.proxyB=e}}class pt{constructor(){this.m_tree=new ut,this.m_proxyCount=0,this.m_moveCount=0,this.m_moveBuffer=[],this.m_pairCount=0,this.m_pairBuffer=[]}CreateProxy(t,e){const s=this.m_tree.CreateProxy(t,e);return++this.m_proxyCount,this.BufferMove(s),s}DestroyProxy(t){this.UnBufferMove(t),--this.m_proxyCount,this.m_tree.DestroyProxy(t)}MoveProxy(t,e,s){this.m_tree.MoveProxy(t,e,s)&&this.BufferMove(t)}TouchProxy(t){this.BufferMove(t)}GetProxyCount(){return this.m_proxyCount}UpdatePairs(t){this.m_pairCount=0;for(let t=0;t{if(t.m_id===e.m_id)return!0;if(t.moved&&t.m_id>e.m_id)return!0;let s,i;if(t.m_id0)return!1;const c=b.DotVV(l,r);if(0===c)return!1;const u=m/c;if(u<0||e.maxFraction0&&t.normal.SelfNeg(),!0)}ComputeAABB(t,e,s){const i=g.MulXV(e,this.m_vertex1,yt.ComputeAABB_s_v1),n=g.MulXV(e,this.m_vertex2,yt.ComputeAABB_s_v2);b.MinV(i,n,t.lowerBound),b.MaxV(i,n,t.upperBound);const o=this.m_radius;t.lowerBound.SelfSubXY(o,o),t.upperBound.SelfAddXY(o,o)}ComputeMass(t,e){t.mass=0,b.MidVV(this.m_vertex1,this.m_vertex2,t.center),t.I=0}SetupDistanceProxy(t,e){t.m_vertices=t.m_buffer,t.m_vertices[0].Copy(this.m_vertex1),t.m_vertices[1].Copy(this.m_vertex2),t.m_count=2,t.m_radius=this.m_radius}ComputeSubmergedArea(t,e,s,i){return i.SetZero(),0}Dump(t){t(" const shape: b2EdgeShape = new b2EdgeShape();\n"),t(" shape.m_radius = %.15f;\n",this.m_radius),t(" shape.m_vertex0.Set(%.15f, %.15f);\n",this.m_vertex0.x,this.m_vertex0.y),t(" shape.m_vertex1.Set(%.15f, %.15f);\n",this.m_vertex1.x,this.m_vertex1.y),t(" shape.m_vertex2.Set(%.15f, %.15f);\n",this.m_vertex2.x,this.m_vertex2.y),t(" shape.m_vertex3.Set(%.15f, %.15f);\n",this.m_vertex3.x,this.m_vertex3.y),t(" shape.m_oneSided = %s;\n",this.m_oneSided)}}yt.RayCast_s_p1=new b,yt.RayCast_s_p2=new b,yt.RayCast_s_d=new b,yt.RayCast_s_e=new b,yt.RayCast_s_q=new b,yt.RayCast_s_r=new b,yt.ComputeAABB_s_v1=new b,yt.ComputeAABB_s_v2=new b;class bt extends M{constructor(){super(t.b2ShapeType.e_chainShape,.01),this.m_vertices=[],this.m_count=0,this.m_prevVertex=new b,this.m_nextVertex=new b}CreateLoop(...t){if("number"==typeof t[0][0]){const e=t[0];if(e.length%2!=0)throw new Error;return this._CreateLoop(t=>({x:e[2*t],y:e[2*t+1]}),e.length/2)}{const e=t[0],s=t[1]||e.length;return this._CreateLoop(t=>e[t],s)}}_CreateLoop(t,e){if(e<3)return this;this.m_count=e+1,this.m_vertices=b.MakeArray(this.m_count);for(let s=0;s({x:e[2*t],y:e[2*t+1]}),e.length/2,s,i)}{const e=t[0],s=t[1]||e.length,i=t[2],n=t[3];return this._CreateChain(t=>e[t],s,i,n)}}_CreateChain(t,e,s,i){this.m_count=e,this.m_vertices=b.MakeArray(e);for(let s=0;st.m_vertices[e],t.m_count,t.m_prevVertex,t.m_nextVertex),this.m_prevVertex.Copy(t.m_prevVertex),this.m_nextVertex.Copy(t.m_nextVertex),this}GetChildCount(){return this.m_count-1}GetChildEdge(t,e){t.m_radius=this.m_radius,t.m_vertex1.Copy(this.m_vertices[e]),t.m_vertex2.Copy(this.m_vertices[e+1]),t.m_oneSided=!0,e>0?t.m_vertex0.Copy(this.m_vertices[e-1]):t.m_vertex0.Copy(this.m_prevVertex),ethis.m_radius)return i.Copy(o),n*this.m_radius*this.m_radius;const h=this.m_radius*this.m_radius,a=r*r,_=h*(p(r/this.m_radius)+n/2)+r*l(h-a),c=-2/3*m(h-a,1.5)/_;return i.x=o.x+t.x*c,i.y=o.y+t.y*c,_}Dump(t){t(" const shape: b2CircleShape = new b2CircleShape();\n"),t(" shape.m_radius = %.15f;\n",this.m_radius),t(" shape.m_p.Set(%.15f, %.15f);\n",this.m_p.x,this.m_p.y)}}xt.TestPoint_s_center=new b,xt.TestPoint_s_d=new b,xt.RayCast_s_position=new b,xt.RayCast_s_s=new b,xt.RayCast_s_r=new b,xt.ComputeAABB_s_p=new b;const At=new b,ft=new b;function b2CollideCircles(e,s,i,n,o){e.pointCount=0;const r=g.MulXV(i,s.m_p,At),h=g.MulXV(o,n.m_p,ft),a=b.DistanceSquaredVV(r,h),_=s.m_radius+n.m_radius;a>_*_||(e.type=t.b2ManifoldType.e_circles,e.localPoint.Copy(s.m_p),e.localNormal.SetZero(),e.pointCount=1,e.points[0].localPoint.Copy(n.m_p),e.points[0].id.key=0)}const St=new b,wt=new b,gt=new b;function b2CollidePolygonAndCircle(e,s,n,o,r){e.pointCount=0;const h=g.MulXV(r,o.m_p,St),a=g.MulTXV(n,h,wt);let _=0,l=-i;const m=s.m_radius+o.m_radius,c=s.m_count,u=s.m_vertices,d=s.m_normals;for(let t=0;tm)return;e>l&&(l=e,_=t)}const p=_,y=(p+1)%c,x=u[p],A=u[y];if(l<1e-5)return e.pointCount=1,e.type=t.b2ManifoldType.e_faceA,e.localNormal.Copy(d[_]),b.MidVV(x,A,e.localPoint),e.points[0].localPoint.Copy(o.m_p),void(e.points[0].id.key=0);const f=b.DotVV(b.SubVV(a,x,b.s_t0),b.SubVV(A,x,b.s_t1)),S=b.DotVV(b.SubVV(a,A,b.s_t0),b.SubVV(x,A,b.s_t1));if(f<=0){if(b.DistanceSquaredVV(a,x)>m*m)return;e.pointCount=1,e.type=t.b2ManifoldType.e_faceA,b.SubVV(a,x,e.localNormal).SelfNormalize(),e.localPoint.Copy(x),e.points[0].localPoint.Copy(o.m_p),e.points[0].id.key=0}else if(S<=0){if(b.DistanceSquaredVV(a,A)>m*m)return;e.pointCount=1,e.type=t.b2ManifoldType.e_faceA,b.SubVV(a,A,e.localNormal).SelfNormalize(),e.localPoint.Copy(A),e.points[0].localPoint.Copy(o.m_p),e.points[0].id.key=0}else{const s=b.MidVV(x,A,gt);if(b.DotVV(b.SubVV(a,s,b.s_t1),d[p])>m)return;e.pointCount=1,e.type=t.b2ManifoldType.e_faceA,e.localNormal.Copy(d[p]).SelfNormalize(),e.localPoint.Copy(s),e.points[0].localPoint.Copy(o.m_p),e.points[0].id.key=0}}const Ct=new b,Vt=new b,Bt=new b,vt=new b,Mt=new b,It=new b,Dt=new b,Tt=new et;function b2CollideEdgeAndCircle(e,s,i,n,o){e.pointCount=0;const r=g.MulTXV(i,g.MulXV(o,n.m_p,b.s_t0),Ct),h=s.m_vertex1,a=s.m_vertex2,_=b.SubVV(a,h,Vt),l=Dt.Set(_.y,-_.x),m=b.DotVV(l,b.SubVV(r,h,b.s_t0));if(s.m_oneSided&&m<0)return;const c=b.DotVV(_,b.SubVV(a,r,b.s_t0)),u=b.DotVV(_,b.SubVV(r,h,b.s_t0)),d=s.m_radius+n.m_radius,p=Tt;if(p.cf.indexB=0,p.cf.typeB=t.b2ContactFeatureType.e_vertex,u<=0){const i=h,o=b.SubVV(r,i,Bt);if(b.DotVV(o,o)>d*d)return;if(s.m_oneSided){const t=s.m_vertex0,e=h,i=b.SubVV(e,t,vt);if(b.DotVV(i,b.SubVV(e,r,b.s_t0))>0)return}return p.cf.indexA=0,p.cf.typeA=t.b2ContactFeatureType.e_vertex,e.pointCount=1,e.type=t.b2ManifoldType.e_circles,e.localNormal.SetZero(),e.localPoint.Copy(i),e.points[0].id.Copy(p),void e.points[0].localPoint.Copy(n.m_p)}if(c<=0){const i=a,o=b.SubVV(r,i,Bt);if(b.DotVV(o,o)>d*d)return;if(s.m_oneSided){const t=s.m_vertex3,e=a,i=b.SubVV(t,e,Mt);if(b.DotVV(i,b.SubVV(r,e,b.s_t0))>0)return}return p.cf.indexA=1,p.cf.typeA=t.b2ContactFeatureType.e_vertex,e.pointCount=1,e.type=t.b2ManifoldType.e_circles,e.localNormal.SetZero(),e.localPoint.Copy(i),e.points[0].id.Copy(p),void e.points[0].localPoint.Copy(n.m_p)}const y=b.DotVV(_,_),x=It;x.x=1/y*(c*h.x+u*a.x),x.y=1/y*(c*h.y+u*a.y);const A=b.SubVV(r,x,Bt);b.DotVV(A,A)>d*d||(m<0&&l.Set(-l.x,-l.y),l.Normalize(),p.cf.indexA=0,p.cf.typeA=t.b2ContactFeatureType.e_face,e.pointCount=1,e.type=t.b2ManifoldType.e_faceA,e.localNormal.Copy(l),e.localPoint.Copy(h),e.points[0].id.Copy(p),e.points[0].localPoint.Copy(n.m_p))}var Gt;!function(t){t[t.e_unknown=0]="e_unknown",t[t.e_edgeA=1]="e_edgeA",t[t.e_edgeB=2]="e_edgeB"}(Gt||(Gt={}));class Pt{constructor(){this.normal=new b,this.type=Gt.e_unknown,this.index=0,this.separation=0}}const Lt=new Pt,Rt=[new b,new b];const Ft=new Pt,kt=new b;const jt=new g,qt=new b,Jt=new b,Et=new b,Ot=new b,zt=new b,Xt=new b,Nt=new b,Zt=new class{constructor(){this.vertices=[],this.normals=[],this.count=0}},Wt=new class{constructor(){this.i1=0,this.i2=0,this.v1=new b,this.v2=new b,this.normal=new b,this.sideNormal1=new b,this.sideOffset1=0,this.sideNormal2=new b,this.sideOffset2=0}},Ut=[new ot,new ot],Yt=[new ot,new ot],Qt=[new ot,new ot];function b2CollideEdgeAndPolygon(e,s,i,n,o){e.pointCount=0;const r=g.MulTXX(i,o,jt),h=g.MulXV(r,n.m_centroid,qt),a=s.m_vertex1,_=s.m_vertex2,l=b.SubVV(_,a,Jt);l.Normalize();const m=Et.Set(l.y,-l.x),c=b.DotVV(m,b.SubVV(h,a,b.s_t0)),u=s.m_oneSided;if(u&&c<0)return;const d=Zt;d.count=n.m_count;for(let t=0;ti.separation&&(i.index=s,i.separation=o,i.normal.Copy(n[s]))}return i}(d,a,m);if(y.separation>p)return;const x=function(t,e,s){const i=Ft;i.type=Gt.e_unknown,i.index=-1,i.separation=-Number.MAX_VALUE,i.normal.SetZero();for(let n=0;ni.separation&&(i.type=Gt.e_edgeB,i.index=n,i.separation=r,i.normal.Copy(o))}return i}(d,a,_);if(x.separation>p)return;let A;if(A=x.separation-p>.98*(y.separation-p)+.001?x:y,u){const t=b.SubVV(a,s.m_vertex0,Ot);t.Normalize();const e=zt.Set(t.y,-t.x),i=b.CrossVV(t,l)>=0,n=b.SubVV(s.m_vertex3,_,Xt);n.Normalize();const o=Nt.Set(n.y,-n.x),r=b.CrossVV(l,n)>=0,h=.1;if(b.DotVV(A.normal,l)<=0)if(i){if(b.CrossVV(A.normal,e)>h)return}else A=y;else if(r){if(b.CrossVV(o,A.normal)>h)return}else A=y}const f=Ut,S=Wt;if(A.type===Gt.e_edgeA){e.type=t.b2ManifoldType.e_faceA;let s=0,i=b.DotVV(A.normal,d.normals[0]);for(let t=1;tu&&(u=n,c=t)}return t[0]=c,u}const te=new b;const ee=[new ot,new ot],se=[new ot,new ot],ie=[new ot,new ot],ne=[0],oe=[0],re=new b,he=new b,ae=new b,_e=new b,le=new b,me=new b,ce=new b,ue=new b;function b2CollidePolygons(e,s,n,o,r){e.pointCount=0;const h=s.m_radius+o.m_radius,a=ne;a[0]=0;const _=b2FindMaxSeparation(a,s,n,o,r);if(_>h)return;const l=oe;l[0]=0;const m=b2FindMaxSeparation(l,o,r,s,n);if(m>h)return;let c,u,d,p,y=0,x=0;m>_+5e-4?(c=o,u=s,d=r,p=n,y=l[0],e.type=t.b2ManifoldType.e_faceB,x=1):(c=s,u=o,d=n,p=r,y=a[0],e.type=t.b2ManifoldType.e_faceA,x=0);const A=ee;!function(e,s,n,o,r,h){const a=s.m_normals,_=r.m_count,l=r.m_vertices,m=r.m_normals,c=w.MulTRV(h.q,w.MulRV(n.q,a[o],b.s_t0),te);let u=0,d=i;for(let t=0;t<_;++t){const e=b.DotVV(c,m[t]);e({x:e[2*t],y:e[2*t+1]}),e.length/2)}{const e=t[0],s=t[1]||e.length;return this._Set(t=>e[t],s)}}_Set(t,e){if(e<3)return this.SetAsBox(1,1);let s=e;const i=[];for(let e=0;eo||e===o&&i[t].ys.LengthSquared()&&(t=e)}if(++h,a=t,t===n)break}this.m_count=h,this.m_vertices=b.MakeArray(this.m_count),this.m_normals=b.MakeArray(this.m_count);for(let t=0;t0)return!1}return!0}RayCast(t,e,s,i){const n=g.MulTXV(s,e.p1,de.RayCast_s_p1),o=g.MulTXV(s,e.p2,de.RayCast_s_p2),r=b.SubVV(o,n,de.RayCast_s_d);let h=0,a=e.maxFraction,_=-1;for(let t=0;t0&&e=0&&(t.fraction=h,w.MulRV(s.q,this.m_normals[_],t.normal),!0)}ComputeAABB(t,e,s){const i=g.MulXV(e,this.m_vertices[0],t.lowerBound),n=t.upperBound.Copy(i);for(let t=0;t0&&(e?l||(a=t-1,h++):l&&(_=t-1,h++)),l=e}switch(h){case 0:if(l){const t=de.ComputeSubmergedArea_s_md;return this.ComputeMass(t,1),g.MulXV(s,t.center,i),t.mass}return 0;case 1:-1===a?a=this.m_count-1:_=this.m_count-1}const m=(a+1)%this.m_count,c=(_+1)%this.m_count,u=(0-r[a])/(r[m]-r[a]),d=(0-r[_])/(r[c]-r[_]),p=de.ComputeSubmergedArea_s_intoVec.Set(this.m_vertices[a].x*(1-u)+this.m_vertices[m].x*u,this.m_vertices[a].y*(1-u)+this.m_vertices[m].y*u),y=de.ComputeSubmergedArea_s_outoVec.Set(this.m_vertices[_].x*(1-d)+this.m_vertices[c].x*d,this.m_vertices[_].y*(1-d)+this.m_vertices[c].y*d);let x=0;const A=de.ComputeSubmergedArea_s_center.SetZero();let f,S=this.m_vertices[m],C=m;for(;C!==c;){C=(C+1)%this.m_count,f=C===c?y:this.m_vertices[C];const t=.5*((S.x-p.x)*(f.y-p.y)-(S.y-p.y)*(f.x-p.x));x+=t,A.x+=t*(p.x+S.x+f.x)/3,A.y+=t*(p.y+S.y+f.y)/3,S=f}return A.SelfMul(1/x),g.MulXV(s,A,i),x}Dump(t){t(" const shape: b2PolygonShape = new b2PolygonShape();\n"),t(" const vs: b2Vec2[] = [];\n");for(let e=0;em+.00125){e.state=t.b2TOIOutputState.e_separated,e.t=l,x=!0;break}if(n>m-.00125){c=A;break}let o=b.Evaluate(s[0],i[0],c);if(om?(_=e,o=r):(u=e,n=r),50===h)break}if(t.b2_toiMaxRootIters=b2Max(t.b2_toiMaxRootIters,h),++f,f===r)break}if(++u,++t.b2_toiIters,x)break;if(20===u){e.state=t.b2TOIOutputState.e_failed,e.t=c;break}}t.b2_toiMaxIters=b2Max(t.b2_toiMaxIters,u);const y=i.GetMilliseconds();t.b2_toiMaxTime=b2Max(t.b2_toiMaxTime,y),t.b2_toiTime+=y}var Fe,ke;t.b2JointType=void 0,(Fe=t.b2JointType||(t.b2JointType={}))[Fe.e_unknownJoint=0]="e_unknownJoint",Fe[Fe.e_revoluteJoint=1]="e_revoluteJoint",Fe[Fe.e_prismaticJoint=2]="e_prismaticJoint",Fe[Fe.e_distanceJoint=3]="e_distanceJoint",Fe[Fe.e_pulleyJoint=4]="e_pulleyJoint",Fe[Fe.e_mouseJoint=5]="e_mouseJoint",Fe[Fe.e_gearJoint=6]="e_gearJoint",Fe[Fe.e_wheelJoint=7]="e_wheelJoint",Fe[Fe.e_weldJoint=8]="e_weldJoint",Fe[Fe.e_frictionJoint=9]="e_frictionJoint",Fe[Fe.e_ropeJoint=10]="e_ropeJoint",Fe[Fe.e_motorJoint=11]="e_motorJoint",Fe[Fe.e_areaJoint=12]="e_areaJoint";class je{constructor(t){this._other=null,this.prev=null,this.next=null,this.joint=t}get other(){if(null===this._other)throw new Error;return this._other}set other(t){if(null!==this._other)throw new Error;this._other=t}Reset(){this._other=null,this.prev=null,this.next=null}}class qe{constructor(e){this.type=t.b2JointType.e_unknownJoint,this.userData=null,this.collideConnected=!1,this.type=e}}class Je{constructor(e){this.m_type=t.b2JointType.e_unknownJoint,this.m_prev=null,this.m_next=null,this.m_edgeA=new je(this),this.m_edgeB=new je(this),this.m_index=0,this.m_islandFlag=!1,this.m_collideConnected=!1,this.m_userData=null,this.m_type=e.type,this.m_edgeA.other=e.bodyB,this.m_edgeB.other=e.bodyA,this.m_bodyA=e.bodyA,this.m_bodyB=e.bodyB,this.m_collideConnected=b2Maybe(e.collideConnected,!1),this.m_userData=b2Maybe(e.userData,null)}GetType(){return this.m_type}GetBodyA(){return this.m_bodyA}GetBodyB(){return this.m_bodyB}GetNext(){return this.m_next}GetUserData(){return this.m_userData}SetUserData(t){this.m_userData=t}IsEnabled(){return this.m_bodyA.IsEnabled()&&this.m_bodyB.IsEnabled()}GetCollideConnected(){return this.m_collideConnected}Dump(t){t("// Dump is not supported for this joint type.\n")}ShiftOrigin(t){}Draw(e){const s=this.m_bodyA.GetTransform(),i=this.m_bodyB.GetTransform(),n=s.p,o=i.p,r=this.GetAnchorA(Je.Draw_s_p1),h=this.GetAnchorB(Je.Draw_s_p2),a=Je.Draw_s_color.SetRGB(.5,.8,.8);switch(this.m_type){case t.b2JointType.e_distanceJoint:e.DrawSegment(r,h,a);break;case t.b2JointType.e_pulleyJoint:{const t=this,s=t.GetGroundAnchorA(),i=t.GetGroundAnchorB();e.DrawSegment(s,r,a),e.DrawSegment(i,h,a),e.DrawSegment(s,i,a)}break;case t.b2JointType.e_mouseJoint:{const t=Je.Draw_s_c;t.Set(0,1,0),e.DrawPoint(r,4,t),e.DrawPoint(h,4,t),t.Set(.8,.8,.8),e.DrawSegment(r,h,t)}break;default:e.DrawSegment(n,r,a),e.DrawSegment(r,h,a),e.DrawSegment(o,h,a)}}}Je.Draw_s_p1=new b,Je.Draw_s_p2=new b,Je.Draw_s_color=new e(.5,.8,.8),Je.Draw_s_c=new e;class Ee extends qe{constructor(){super(t.b2JointType.e_distanceJoint),this.localAnchorA=new b,this.localAnchorB=new b,this.length=1,this.minLength=0,this.maxLength=i,this.stiffness=0,this.damping=0}Initialize(t,e,s,i){this.bodyA=t,this.bodyB=e,this.bodyA.GetLocalPoint(s,this.localAnchorA),this.bodyB.GetLocalPoint(i,this.localAnchorB),this.length=b2Max(b.DistanceVV(s,i),.005),this.minLength=this.length,this.maxLength=this.length}}class Oe extends Je{constructor(t){super(t),this.m_stiffness=0,this.m_damping=0,this.m_bias=0,this.m_length=0,this.m_minLength=0,this.m_maxLength=0,this.m_localAnchorA=new b,this.m_localAnchorB=new b,this.m_gamma=0,this.m_impulse=0,this.m_lowerImpulse=0,this.m_upperImpulse=0,this.m_indexA=0,this.m_indexB=0,this.m_u=new b,this.m_rA=new b,this.m_rB=new b,this.m_localCenterA=new b,this.m_localCenterB=new b,this.m_currentLength=0,this.m_invMassA=0,this.m_invMassB=0,this.m_invIA=0,this.m_invIB=0,this.m_softMass=0,this.m_mass=0,this.m_qA=new w,this.m_qB=new w,this.m_lalcA=new b,this.m_lalcB=new b,this.m_localAnchorA.Copy(b2Maybe(t.localAnchorA,b.ZERO)),this.m_localAnchorB.Copy(b2Maybe(t.localAnchorB,b.ZERO)),this.m_length=b2Max(b2Maybe(t.length,this.GetCurrentLength()),.005),this.m_minLength=b2Max(b2Maybe(t.minLength,this.m_length),.005),this.m_maxLength=b2Max(b2Maybe(t.maxLength,this.m_length),this.m_minLength),this.m_stiffness=b2Maybe(t.stiffness,0),this.m_damping=b2Maybe(t.damping,0)}GetAnchorA(t){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA,t)}GetAnchorB(t){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB,t)}GetReactionForce(t,e){return e.x=t*(this.m_impulse+this.m_lowerImpulse-this.m_upperImpulse)*this.m_u.x,e.y=t*(this.m_impulse+this.m_lowerImpulse-this.m_upperImpulse)*this.m_u.y,e}GetReactionTorque(t){return 0}GetLocalAnchorA(){return this.m_localAnchorA}GetLocalAnchorB(){return this.m_localAnchorB}SetLength(t){return this.m_impulse=0,this.m_length=b2Max(.005,t),this.m_length}GetLength(){return this.m_length}SetMinLength(t){return this.m_lowerImpulse=0,this.m_minLength=b2Clamp(t,.005,this.m_maxLength),this.m_minLength}SetMaxLength(t){return this.m_upperImpulse=0,this.m_maxLength=b2Max(t,this.m_minLength),this.m_maxLength}GetCurrentLength(){const t=this.m_bodyA.GetWorldPoint(this.m_localAnchorA,new b),e=this.m_bodyB.GetWorldPoint(this.m_localAnchorB,new b);return b.DistanceVV(t,e)}SetStiffness(t){this.m_stiffness=t}GetStiffness(){return this.m_stiffness}SetDamping(t){this.m_damping=t}GetDamping(){return this.m_damping}Dump(t){const e=this.m_bodyA.m_islandIndex,s=this.m_bodyB.m_islandIndex;t(" const jd: b2DistanceJointDef = new b2DistanceJointDef();\n"),t(" jd.bodyA = bodies[%d];\n",e),t(" jd.bodyB = bodies[%d];\n",s),t(" jd.collideConnected = %s;\n",this.m_collideConnected?"true":"false"),t(" jd.localAnchorA.Set(%.15f, %.15f);\n",this.m_localAnchorA.x,this.m_localAnchorA.y),t(" jd.localAnchorB.Set(%.15f, %.15f);\n",this.m_localAnchorB.x,this.m_localAnchorB.y),t(" jd.length = %.15f;\n",this.m_length),t(" jd.minLength = %.15f;\n",this.m_minLength),t(" jd.maxLength = %.15f;\n",this.m_maxLength),t(" jd.stiffness = %.15f;\n",this.m_stiffness),t(" jd.damping = %.15f;\n",this.m_damping),t(" joints[%d] = this.m_world.CreateJoint(jd);\n",this.m_index)}InitVelocityConstraints(t){this.m_indexA=this.m_bodyA.m_islandIndex,this.m_indexB=this.m_bodyB.m_islandIndex,this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter),this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter),this.m_invMassA=this.m_bodyA.m_invMass,this.m_invMassB=this.m_bodyB.m_invMass,this.m_invIA=this.m_bodyA.m_invI,this.m_invIB=this.m_bodyB.m_invI;const e=t.positions[this.m_indexA].c,s=t.positions[this.m_indexA].a,i=t.velocities[this.m_indexA].v;let n=t.velocities[this.m_indexA].w;const o=t.positions[this.m_indexB].c,r=t.positions[this.m_indexB].a,h=t.velocities[this.m_indexB].v;let a=t.velocities[this.m_indexB].w;const _=this.m_qA.SetAngle(s),l=this.m_qB.SetAngle(r);b.SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA),w.MulRV(_,this.m_lalcA,this.m_rA),b.SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB),w.MulRV(l,this.m_lalcB,this.m_rB),this.m_u.x=o.x+this.m_rB.x-e.x-this.m_rA.x,this.m_u.y=o.y+this.m_rB.y-e.y-this.m_rA.y,this.m_currentLength=this.m_u.Length(),this.m_currentLength>.005?this.m_u.SelfMul(1/this.m_currentLength):(this.m_u.SetZero(),this.m_mass=0,this.m_impulse=0,this.m_lowerImpulse=0,this.m_upperImpulse=0);const m=b.CrossVV(this.m_rA,this.m_u),c=b.CrossVV(this.m_rB,this.m_u);let u=this.m_invMassA+this.m_invIA*m*m+this.m_invMassB+this.m_invIB*c*c;if(this.m_mass=0!==u?1/u:0,this.m_stiffness>0&&this.m_minLength0){const t=b.AddVCrossSV(e,s,this.m_rA,Oe.SolveVelocityConstraints_s_vpA),o=b.AddVCrossSV(i,n,this.m_rB,Oe.SolveVelocityConstraints_s_vpB),r=b.DotVV(this.m_u,b.SubVV(o,t,b.s_t0)),h=-this.m_softMass*(r+this.m_bias+this.m_gamma*this.m_impulse);this.m_impulse+=h;const a=b.MulSV(h,this.m_u,Oe.SolveVelocityConstraints_s_P);e.SelfMulSub(this.m_invMassA,a),s-=this.m_invIA*b.CrossVV(this.m_rA,a),i.SelfMulAdd(this.m_invMassB,a),n+=this.m_invIB*b.CrossVV(this.m_rB,a)}{const o=b2Max(0,this.m_currentLength-this.m_minLength)*t.step.inv_dt,r=b.AddVCrossSV(e,s,this.m_rA,Oe.SolveVelocityConstraints_s_vpA),h=b.AddVCrossSV(i,n,this.m_rB,Oe.SolveVelocityConstraints_s_vpB),a=b.DotVV(this.m_u,b.SubVV(h,r,b.s_t0));let _=-this.m_mass*(a+o);const l=this.m_lowerImpulse;this.m_lowerImpulse=b2Max(0,this.m_lowerImpulse+_),_=this.m_lowerImpulse-l;const m=b.MulSV(_,this.m_u,Oe.SolveVelocityConstraints_s_P);e.SelfMulSub(this.m_invMassA,m),s-=this.m_invIA*b.CrossVV(this.m_rA,m),i.SelfMulAdd(this.m_invMassB,m),n+=this.m_invIB*b.CrossVV(this.m_rB,m)}{const o=b2Max(0,this.m_maxLength-this.m_currentLength)*t.step.inv_dt,r=b.AddVCrossSV(e,s,this.m_rA,Oe.SolveVelocityConstraints_s_vpA),h=b.AddVCrossSV(i,n,this.m_rB,Oe.SolveVelocityConstraints_s_vpB),a=b.DotVV(this.m_u,b.SubVV(r,h,b.s_t0));let _=-this.m_mass*(a+o);const l=this.m_upperImpulse;this.m_upperImpulse=b2Max(0,this.m_upperImpulse+_),_=this.m_upperImpulse-l;const m=b.MulSV(-_,this.m_u,Oe.SolveVelocityConstraints_s_P);e.SelfMulSub(this.m_invMassA,m),s-=this.m_invIA*b.CrossVV(this.m_rA,m),i.SelfMulAdd(this.m_invMassB,m),n+=this.m_invIB*b.CrossVV(this.m_rB,m)}}else{const t=b.AddVCrossSV(e,s,this.m_rA,Oe.SolveVelocityConstraints_s_vpA),o=b.AddVCrossSV(i,n,this.m_rB,Oe.SolveVelocityConstraints_s_vpB),r=b.DotVV(this.m_u,b.SubVV(o,t,b.s_t0)),h=-this.m_mass*r;this.m_impulse+=h;const a=b.MulSV(h,this.m_u,Oe.SolveVelocityConstraints_s_P);e.SelfMulSub(this.m_invMassA,a),s-=this.m_invIA*b.CrossVV(this.m_rA,a),i.SelfMulAdd(this.m_invMassB,a),n+=this.m_invIB*b.CrossVV(this.m_rB,a)}t.velocities[this.m_indexA].w=s,t.velocities[this.m_indexB].w=n}SolvePositionConstraints(t){const e=t.positions[this.m_indexA].c;let s=t.positions[this.m_indexA].a;const i=t.positions[this.m_indexB].c;let n=t.positions[this.m_indexB].a;const o=this.m_qA.SetAngle(s),r=this.m_qB.SetAngle(n),h=w.MulRV(o,this.m_lalcA,this.m_rA),_=w.MulRV(r,this.m_lalcB,this.m_rB),l=this.m_u;l.x=i.x+_.x-e.x-h.x,l.y=i.y+_.y-e.y-h.y;const m=this.m_u.Normalize();let c;if(this.m_minLength==this.m_maxLength)c=m-this.m_minLength;else if(m.005){const e=b.AddVMulSV(n,this.m_minLength,r,Oe.Draw_s_pMin);t.DrawPoint(e,4,a)}if(this.m_maxLengthb2Sq(.2)&&h.SelfMul(.2/l(a)),a>b2Sq(.005)&&(n=!1),o.x+=h.x,o.y+=h.y}return n}}class Xe{constructor(){this.categoryBits=1,this.maskBits=65535,this.groupIndex=0}Clone(){return(new Xe).Copy(this)}Copy(t){return this.categoryBits=t.categoryBits,this.maskBits=t.maskBits,this.groupIndex=t.groupIndex||0,this}}Xe.DEFAULT=new Xe;class Ne{constructor(){this.userData=null,this.friction=.2,this.restitution=0,this.restitutionThreshold=1,this.density=0,this.isSensor=!1,this.filter=new Xe}}class Ze{constructor(t,e){this.aabb=new at,this.childIndex=0,this.fixture=t,this.childIndex=e,this.fixture.m_shape.ComputeAABB(this.aabb,this.fixture.m_body.GetTransform(),e),this.treeNode=this.fixture.m_body.m_world.m_contactManager.m_broadPhase.CreateProxy(this.aabb,this)}Reset(){this.fixture.m_body.m_world.m_contactManager.m_broadPhase.DestroyProxy(this.treeNode)}Touch(){this.fixture.m_body.m_world.m_contactManager.m_broadPhase.TouchProxy(this.treeNode)}Synchronize(t,e){if(t===e)this.fixture.m_shape.ComputeAABB(this.aabb,t,this.childIndex),this.fixture.m_body.m_world.m_contactManager.m_broadPhase.MoveProxy(this.treeNode,this.aabb,b.ZERO);else{const s=Ze.Synchronize_s_aabb1,i=Ze.Synchronize_s_aabb2;this.fixture.m_shape.ComputeAABB(s,t,this.childIndex),this.fixture.m_shape.ComputeAABB(i,e,this.childIndex),this.aabb.Combine2(s,i);const n=Ze.Synchronize_s_displacement;n.Copy(i.GetCenter()).SelfSub(s.GetCenter()),this.fixture.m_body.m_world.m_contactManager.m_broadPhase.MoveProxy(this.treeNode,this.aabb,n)}}}Ze.Synchronize_s_aabb1=new at,Ze.Synchronize_s_aabb2=new at,Ze.Synchronize_s_displacement=new b;class We{constructor(t,e){this.m_density=0,this.m_next=null,this.m_friction=0,this.m_restitution=0,this.m_restitutionThreshold=1,this.m_proxies=[],this.m_filter=new Xe,this.m_isSensor=!1,this.m_userData=null,this.m_body=t,this.m_shape=e.shape.Clone(),this.m_userData=b2Maybe(e.userData,null),this.m_friction=b2Maybe(e.friction,.2),this.m_restitution=b2Maybe(e.restitution,0),this.m_restitutionThreshold=b2Maybe(e.restitutionThreshold,0),this.m_filter.Copy(b2Maybe(e.filter,Xe.DEFAULT)),this.m_isSensor=b2Maybe(e.isSensor,!1),this.m_density=b2Maybe(e.density,0)}get m_proxyCount(){return this.m_proxies.length}Create(t,e,s){}Destroy(){}Reset(){}GetType(){return this.m_shape.GetType()}GetShape(){return this.m_shape}SetSensor(t){t!==this.m_isSensor&&(this.m_body.SetAwake(!0),this.m_isSensor=t)}IsSensor(){return this.m_isSensor}SetFilterData(t){this.m_filter.Copy(t),this.Refilter()}GetFilterData(){return this.m_filter}Refilter(){let t=this.m_body.GetContactList();for(;t;){const e=t.contact,s=e.GetFixtureA(),i=e.GetFixtureB();s!==this&&i!==this||e.FlagForFiltering(),t=t.next}this.TouchProxies()}GetBody(){return this.m_body}GetNext(){return this.m_next}GetUserData(){return this.m_userData}SetUserData(t){this.m_userData=t}TestPoint(t){return this.m_shape.TestPoint(this.m_body.GetTransform(),t)}RayCast(t,e,s){return this.m_shape.RayCast(t,e,this.m_body.GetTransform(),s)}GetMassData(t=new B){return this.m_shape.ComputeMass(t,this.m_density),t}SetDensity(t){this.m_density=t}GetDensity(){return this.m_density}GetFriction(){return this.m_friction}SetFriction(t){this.m_friction=t}GetRestitution(){return this.m_restitution}SetRestitution(t){this.m_restitution=t}GetRestitutionThreshold(){return this.m_restitutionThreshold}SetRestitutionThreshold(t){this.m_restitutionThreshold=t}GetAABB(t){return this.m_proxies[t].aabb}Dump(t,e){t(" const fd: b2FixtureDef = new b2FixtureDef();\n"),t(" fd.friction = %.15f;\n",this.m_friction),t(" fd.restitution = %.15f;\n",this.m_restitution),t(" fd.restitutionThreshold = %.15f;\n",this.m_restitutionThreshold),t(" fd.density = %.15f;\n",this.m_density),t(" fd.isSensor = %s;\n",this.m_isSensor?"true":"false"),t(" fd.filter.categoryBits = %d;\n",this.m_filter.categoryBits),t(" fd.filter.maskBits = %d;\n",this.m_filter.maskBits),t(" fd.filter.groupIndex = %d;\n",this.m_filter.groupIndex),this.m_shape.Dump(t),t("\n"),t(" fd.shape = shape;\n"),t("\n"),t(" bodies[%d].CreateFixture(fd);\n",e)}CreateProxies(){if(0!==this.m_proxies.length)throw new Error;for(let t=0;t0&&this.ResetMassData(),this.m_world.m_newContacts=!0,e}CreateFixtureShapeDensity(t,e=0){const s=Ue.CreateFixtureShapeDensity_s_def;return s.shape=t,s.density=e,this.CreateFixtureDef(s)}DestroyFixture(t){if(this.m_world.IsLocked())throw new Error;let e=this.m_fixtureList,s=null;for(;null!==e;){if(e===t){s?s.m_next=t.m_next:this.m_fixtureList=t.m_next;break}s=e,e=e.m_next}let i=this.m_contactList;for(;i;){const e=i.contact;i=i.next;const s=e.GetFixtureA(),n=e.GetFixtureB();t!==s&&t!==n||this.m_world.m_contactManager.Destroy(e)}this.m_enabledFlag&&t.DestroyProxies(),t.m_next=null,t.Reset(),--this.m_fixtureCount,this.ResetMassData()}SetTransformVec(t,e){this.SetTransformXY(t.x,t.y,e)}SetTransformXY(t,e,s){if(this.m_world.IsLocked())throw new Error;this.m_xf.q.SetAngle(s),this.m_xf.p.Set(t,e),g.MulXV(this.m_xf,this.m_sweep.localCenter,this.m_sweep.c),this.m_sweep.a=s,this.m_sweep.c0.Copy(this.m_sweep.c),this.m_sweep.a0=s;for(let t=this.m_fixtureList;t;t=t.m_next)t.SynchronizeProxies(this.m_xf,this.m_xf);this.m_world.m_newContacts=!0}SetTransform(t,e){this.SetTransformXY(t.x,t.y,e)}GetTransform(){return this.m_xf}GetPosition(){return this.m_xf.p}SetPosition(t){this.SetTransformVec(t,this.GetAngle())}SetPositionXY(t,e){this.SetTransformXY(t,e,this.GetAngle())}GetAngle(){return this.m_sweep.a}SetAngle(t){this.SetTransformVec(this.GetPosition(),t)}GetWorldCenter(){return this.m_sweep.c}GetLocalCenter(){return this.m_sweep.localCenter}SetLinearVelocity(e){this.m_type!==t.b2BodyType.b2_staticBody&&(b.DotVV(e,e)>0&&this.SetAwake(!0),this.m_linearVelocity.Copy(e))}GetLinearVelocity(){return this.m_linearVelocity}SetAngularVelocity(e){this.m_type!==t.b2BodyType.b2_staticBody&&(e*e>0&&this.SetAwake(!0),this.m_angularVelocity=e)}GetAngularVelocity(){return this.m_angularVelocity}GetDefinition(t){return t.type=this.GetType(),t.allowSleep=this.m_autoSleepFlag,t.angle=this.GetAngle(),t.angularDamping=this.m_angularDamping,t.gravityScale=this.m_gravityScale,t.angularVelocity=this.m_angularVelocity,t.fixedRotation=this.m_fixedRotationFlag,t.bullet=this.m_bulletFlag,t.awake=this.m_awakeFlag,t.linearDamping=this.m_linearDamping,t.linearVelocity.Copy(this.GetLinearVelocity()),t.position.Copy(this.GetPosition()),t.userData=this.GetUserData(),t}ApplyForce(e,s,i=!0){this.m_type===t.b2BodyType.b2_dynamicBody&&(i&&!this.m_awakeFlag&&this.SetAwake(!0),this.m_awakeFlag&&(this.m_force.x+=e.x,this.m_force.y+=e.y,this.m_torque+=(s.x-this.m_sweep.c.x)*e.y-(s.y-this.m_sweep.c.y)*e.x))}ApplyForceToCenter(e,s=!0){this.m_type===t.b2BodyType.b2_dynamicBody&&(s&&!this.m_awakeFlag&&this.SetAwake(!0),this.m_awakeFlag&&(this.m_force.x+=e.x,this.m_force.y+=e.y))}ApplyTorque(e,s=!0){this.m_type===t.b2BodyType.b2_dynamicBody&&(s&&!this.m_awakeFlag&&this.SetAwake(!0),this.m_awakeFlag&&(this.m_torque+=e))}ApplyLinearImpulse(e,s,i=!0){this.m_type===t.b2BodyType.b2_dynamicBody&&(i&&!this.m_awakeFlag&&this.SetAwake(!0),this.m_awakeFlag&&(this.m_linearVelocity.x+=this.m_invMass*e.x,this.m_linearVelocity.y+=this.m_invMass*e.y,this.m_angularVelocity+=this.m_invI*((s.x-this.m_sweep.c.x)*e.y-(s.y-this.m_sweep.c.y)*e.x)))}ApplyLinearImpulseToCenter(e,s=!0){this.m_type===t.b2BodyType.b2_dynamicBody&&(s&&!this.m_awakeFlag&&this.SetAwake(!0),this.m_awakeFlag&&(this.m_linearVelocity.x+=this.m_invMass*e.x,this.m_linearVelocity.y+=this.m_invMass*e.y))}ApplyAngularImpulse(e,s=!0){this.m_type===t.b2BodyType.b2_dynamicBody&&(s&&!this.m_awakeFlag&&this.SetAwake(!0),this.m_awakeFlag&&(this.m_angularVelocity+=this.m_invI*e))}GetMass(){return this.m_mass}GetInertia(){return this.m_I+this.m_mass*b.DotVV(this.m_sweep.localCenter,this.m_sweep.localCenter)}GetMassData(t){return t.mass=this.m_mass,t.I=this.m_I+this.m_mass*b.DotVV(this.m_sweep.localCenter,this.m_sweep.localCenter),t.center.Copy(this.m_sweep.localCenter),t}SetMassData(e){if(this.m_world.IsLocked())throw new Error;if(this.m_type!==t.b2BodyType.b2_dynamicBody)return;this.m_invMass=0,this.m_I=0,this.m_invI=0,this.m_mass=e.mass,this.m_mass<=0&&(this.m_mass=1),this.m_invMass=1/this.m_mass,e.I>0&&!this.m_fixedRotationFlag&&(this.m_I=e.I-this.m_mass*b.DotVV(e.center,e.center),this.m_invI=1/this.m_I);const s=Ue.SetMassData_s_oldCenter.Copy(this.m_sweep.c);this.m_sweep.localCenter.Copy(e.center),g.MulXV(this.m_xf,this.m_sweep.localCenter,this.m_sweep.c),this.m_sweep.c0.Copy(this.m_sweep.c),b.AddVCrossSV(this.m_linearVelocity,this.m_angularVelocity,b.SubVV(this.m_sweep.c,s,b.s_t0),this.m_linearVelocity)}ResetMassData(){if(this.m_mass=0,this.m_invMass=0,this.m_I=0,this.m_invI=0,this.m_sweep.localCenter.SetZero(),this.m_type===t.b2BodyType.b2_staticBody||this.m_type===t.b2BodyType.b2_kinematicBody)return this.m_sweep.c0.Copy(this.m_xf.p),this.m_sweep.c.Copy(this.m_xf.p),void(this.m_sweep.a0=this.m_sweep.a);const e=Ue.ResetMassData_s_localCenter.SetZero();for(let t=this.m_fixtureList;t;t=t.m_next){if(0===t.m_density)continue;const s=t.GetMassData(Ue.ResetMassData_s_massData);this.m_mass+=s.mass,e.x+=s.center.x*s.mass,e.y+=s.center.y*s.mass,this.m_I+=s.I}this.m_mass>0&&(this.m_invMass=1/this.m_mass,e.x*=this.m_invMass,e.y*=this.m_invMass),this.m_I>0&&!this.m_fixedRotationFlag?(this.m_I-=this.m_mass*b.DotVV(e,e),this.m_invI=1/this.m_I):(this.m_I=0,this.m_invI=0);const s=Ue.ResetMassData_s_oldCenter.Copy(this.m_sweep.c);this.m_sweep.localCenter.Copy(e),g.MulXV(this.m_xf,this.m_sweep.localCenter,this.m_sweep.c),this.m_sweep.c0.Copy(this.m_sweep.c),b.AddVCrossSV(this.m_linearVelocity,this.m_angularVelocity,b.SubVV(this.m_sweep.c,s,b.s_t0),this.m_linearVelocity)}GetWorldPoint(t,e){return g.MulXV(this.m_xf,t,e)}GetWorldVector(t,e){return w.MulRV(this.m_xf.q,t,e)}GetLocalPoint(t,e){return g.MulTXV(this.m_xf,t,e)}GetLocalVector(t,e){return w.MulTRV(this.m_xf.q,t,e)}GetLinearVelocityFromWorldPoint(t,e){return b.AddVCrossSV(this.m_linearVelocity,this.m_angularVelocity,b.SubVV(t,this.m_sweep.c,b.s_t0),e)}GetLinearVelocityFromLocalPoint(t,e){return this.GetLinearVelocityFromWorldPoint(this.GetWorldPoint(t,e),e)}GetLinearDamping(){return this.m_linearDamping}SetLinearDamping(t){this.m_linearDamping=t}GetAngularDamping(){return this.m_angularDamping}SetAngularDamping(t){this.m_angularDamping=t}GetGravityScale(){return this.m_gravityScale}SetGravityScale(t){this.m_gravityScale=t}SetType(e){if(this.m_world.IsLocked())throw new Error;if(this.m_type===e)return;this.m_type=e,this.ResetMassData(),this.m_type===t.b2BodyType.b2_staticBody&&(this.m_linearVelocity.SetZero(),this.m_angularVelocity=0,this.m_sweep.a0=this.m_sweep.a,this.m_sweep.c0.Copy(this.m_sweep.c),this.m_awakeFlag=!1,this.SynchronizeFixtures()),this.SetAwake(!0),this.m_force.SetZero(),this.m_torque=0;let s=this.m_contactList;for(;s;){const t=s;s=s.next,this.m_world.m_contactManager.Destroy(t.contact)}this.m_contactList=null;for(let t=this.m_fixtureList;t;t=t.m_next)t.TouchProxies()}GetType(){return this.m_type}SetBullet(t){this.m_bulletFlag=t}IsBullet(){return this.m_bulletFlag}SetSleepingAllowed(t){this.m_autoSleepFlag=t,t||this.SetAwake(!0)}IsSleepingAllowed(){return this.m_autoSleepFlag}SetAwake(e){this.m_type!==t.b2BodyType.b2_staticBody&&(e?(this.m_awakeFlag=!0,this.m_sleepTime=0):(this.m_awakeFlag=!1,this.m_sleepTime=0,this.m_linearVelocity.SetZero(),this.m_angularVelocity=0,this.m_force.SetZero(),this.m_torque=0))}IsAwake(){return this.m_awakeFlag}SetEnabled(t){if(this.m_world.IsLocked())throw new Error;if(t!==this.IsEnabled())if(this.m_enabledFlag=t,t){for(let t=this.m_fixtureList;t;t=t.m_next)t.CreateProxies();this.m_world.m_newContacts=!0}else{for(let t=this.m_fixtureList;t;t=t.m_next)t.DestroyProxies();let t=this.m_contactList;for(;t;){const e=t;t=t.next,this.m_world.m_contactManager.Destroy(e.contact)}this.m_contactList=null}}IsEnabled(){return this.m_enabledFlag}SetFixedRotation(t){this.m_fixedRotationFlag!==t&&(this.m_fixedRotationFlag=t,this.m_angularVelocity=0,this.ResetMassData())}IsFixedRotation(){return this.m_fixedRotationFlag}GetFixtureList(){return this.m_fixtureList}GetJointList(){return this.m_jointList}GetContactList(){return this.m_contactList}GetNext(){return this.m_next}GetUserData(){return this.m_userData}SetUserData(t){this.m_userData=t}GetWorld(){return this.m_world}Dump(e){const s=this.m_islandIndex;e("{\n"),e(" const bd: b2BodyDef = new b2BodyDef();\n");let i="";switch(this.m_type){case t.b2BodyType.b2_staticBody:i="b2BodyType.b2_staticBody";break;case t.b2BodyType.b2_kinematicBody:i="b2BodyType.b2_kinematicBody";break;case t.b2BodyType.b2_dynamicBody:i="b2BodyType.b2_dynamicBody"}e(" bd.type = %s;\n",i),e(" bd.position.Set(%.15f, %.15f);\n",this.m_xf.p.x,this.m_xf.p.y),e(" bd.angle = %.15f;\n",this.m_sweep.a),e(" bd.linearVelocity.Set(%.15f, %.15f);\n",this.m_linearVelocity.x,this.m_linearVelocity.y),e(" bd.angularVelocity = %.15f;\n",this.m_angularVelocity),e(" bd.linearDamping = %.15f;\n",this.m_linearDamping),e(" bd.angularDamping = %.15f;\n",this.m_angularDamping),e(" bd.allowSleep = %s;\n",this.m_autoSleepFlag?"true":"false"),e(" bd.awake = %s;\n",this.m_awakeFlag?"true":"false"),e(" bd.fixedRotation = %s;\n",this.m_fixedRotationFlag?"true":"false"),e(" bd.bullet = %s;\n",this.m_bulletFlag?"true":"false"),e(" bd.active = %s;\n",this.m_enabledFlag?"true":"false"),e(" bd.gravityScale = %.15f;\n",this.m_gravityScale),e("\n"),e(" bodies[%d] = this.m_world.CreateBody(bd);\n",this.m_islandIndex),e("\n");for(let t=this.m_fixtureList;t;t=t.m_next)e(" {\n"),t.Dump(e,s),e(" }\n");e("}\n")}SynchronizeFixtures(){if(this.m_awakeFlag){const t=Ue.SynchronizeFixtures_s_xf1;t.q.SetAngle(this.m_sweep.a0),w.MulRV(t.q,this.m_sweep.localCenter,t.p),b.SubVV(this.m_sweep.c0,t.p,t.p);for(let e=this.m_fixtureList;e;e=e.m_next)e.SynchronizeProxies(t,this.m_xf)}else for(let t=this.m_fixtureList;t;t=t.m_next)t.SynchronizeProxies(this.m_xf,this.m_xf)}SynchronizeTransform(){this.m_xf.q.SetAngle(this.m_sweep.a),w.MulRV(this.m_xf.q,this.m_sweep.localCenter,this.m_xf.p),b.SubVV(this.m_sweep.c,this.m_xf.p,this.m_xf.p)}ShouldCollide(e){return(this.m_type!==t.b2BodyType.b2_staticBody||e.m_type!==t.b2BodyType.b2_staticBody)&&this.ShouldCollideConnected(e)}ShouldCollideConnected(t){for(let e=this.m_jointList;e;e=e.next)if(e.other===t&&!e.joint.m_collideConnected)return!1;return!0}Advance(t){this.m_sweep.Advance(t),this.m_sweep.c.Copy(this.m_sweep.c0),this.m_sweep.a=this.m_sweep.a0,this.m_xf.q.SetAngle(this.m_sweep.a),w.MulRV(this.m_xf.q,this.m_sweep.localCenter,this.m_xf.p),b.SubVV(this.m_sweep.c,this.m_xf.p,this.m_xf.p)}}function b2MixFriction(t,e){return l(t*e)}function b2MixRestitution(t,e){return t>e?t:e}function b2MixRestitutionThreshold(t,e){return t0;for(let t=0;t0;return 0!=(o.maskBits&r.categoryBits)&&0!=(o.categoryBits&r.maskBits)}}rs.b2_defaultFilter=new rs;class hs{constructor(){this.normalImpulses=b2MakeNumberArray(2),this.tangentImpulses=b2MakeNumberArray(2),this.count=0}}class as{BeginContact(t){}EndContact(t){}PreSolve(t,e){}PostSolve(t,e){}}as.b2_defaultListener=new as;class _s{ReportFixture(t){return!0}}class ls{ReportFixture(t,e,s,i){return i}}class ms{constructor(){this.m_broadPhase=new pt,this.m_contactList=null,this.m_contactCount=0,this.m_contactFilter=rs.b2_defaultFilter,this.m_contactListener=as.b2_defaultListener,this.m_contactFactory=new os}AddPair(t,e){let s=t.fixture,i=e.fixture,n=t.childIndex,o=e.childIndex,r=s.GetBody(),h=i.GetBody();if(r===h)return;let a=h.GetContactList();for(;a;){if(a.other===r){const t=a.contact.GetFixtureA(),e=a.contact.GetFixtureB(),r=a.contact.GetChildIndexA(),h=a.contact.GetChildIndexB();if(t===s&&e===i&&r===n&&h===o)return;if(t===i&&e===s&&r===o&&h===n)return}a=a.next}if(this.m_contactFilter&&!this.m_contactFilter.ShouldCollide(s,i))return;const _=this.m_contactFactory.Create(s,n,i,o);null!==_&&(s=_.GetFixtureA(),i=_.GetFixtureB(),n=_.GetChildIndexA(),o=_.GetChildIndexB(),r=s.m_body,h=i.m_body,_.m_prev=null,_.m_next=this.m_contactList,null!==this.m_contactList&&(this.m_contactList.m_prev=_),this.m_contactList=_,_.m_nodeA.other=h,_.m_nodeA.prev=null,_.m_nodeA.next=r.m_contactList,null!==r.m_contactList&&(r.m_contactList.prev=_.m_nodeA),r.m_contactList=_.m_nodeA,_.m_nodeB.other=r,_.m_nodeB.prev=null,_.m_nodeB.next=h.m_contactList,null!==h.m_contactList&&(h.m_contactList.prev=_.m_nodeB),h.m_contactList=_.m_nodeB,++this.m_contactCount)}FindNewContacts(){this.m_broadPhase.UpdatePairs((t,e)=>{this.AddPair(t,e)})}Destroy(t){const e=t.GetFixtureA(),s=t.GetFixtureB(),i=e.GetBody(),n=s.GetBody();this.m_contactListener&&t.IsTouching()&&this.m_contactListener.EndContact(t),t.m_prev&&(t.m_prev.m_next=t.m_next),t.m_next&&(t.m_next.m_prev=t.m_prev),t===this.m_contactList&&(this.m_contactList=t.m_next),t.m_nodeA.prev&&(t.m_nodeA.prev.next=t.m_nodeA.next),t.m_nodeA.next&&(t.m_nodeA.next.prev=t.m_nodeA.prev),t.m_nodeA===i.m_contactList&&(i.m_contactList=t.m_nodeA.next),t.m_nodeB.prev&&(t.m_nodeB.prev.next=t.m_nodeB.next),t.m_nodeB.next&&(t.m_nodeB.next.prev=t.m_nodeB.prev),t.m_nodeB===n.m_contactList&&(n.m_contactList=t.m_nodeB.next),t.m_manifold.pointCount>0&&!e.IsSensor()&&!s.IsSensor()&&(e.GetBody().SetAwake(!0),s.GetBody().SetAwake(!0)),this.m_contactFactory.Destroy(t),--this.m_contactCount}Collide(){let e=this.m_contactList;for(;e;){const s=e.GetFixtureA(),i=e.GetFixtureB(),n=e.GetChildIndexA(),o=e.GetChildIndexB(),r=s.GetBody(),h=i.GetBody();if(e.m_filterFlag){if(this.m_contactFilter&&!this.m_contactFilter.ShouldCollide(s,i)){const t=e;e=t.m_next,this.Destroy(t);continue}e.m_filterFlag=!1}const a=r.IsAwake()&&r.m_type!==t.b2BodyType.b2_staticBody,_=h.IsAwake()&&h.m_type!==t.b2BodyType.b2_staticBody;if(!a&&!_){e=e.m_next;continue}const l=s.m_proxies[n].treeNode,m=i.m_proxies[o].treeNode;if(b2TestOverlapAABB(l.aabb,m.aabb))e.Update(this.m_contactListener),e=e.m_next;else{const t=e;e=t.m_next,this.Destroy(t)}}}}class cs{constructor(){this.step=0,this.collide=0,this.solve=0,this.solveInit=0,this.solveVelocity=0,this.solvePosition=0,this.broadphase=0,this.solveTOI=0}Reset(){return this.step=0,this.collide=0,this.solve=0,this.solveInit=0,this.solveVelocity=0,this.solvePosition=0,this.broadphase=0,this.solveTOI=0,this}}class us{constructor(){this.dt=0,this.inv_dt=0,this.dtRatio=0,this.velocityIterations=0,this.positionIterations=0,this.warmStarting=!1}Copy(t){return this.dt=t.dt,this.inv_dt=t.inv_dt,this.dtRatio=t.dtRatio,this.positionIterations=t.positionIterations,this.velocityIterations=t.velocityIterations,this.warmStarting=t.warmStarting,this}}class ds{constructor(){this.c=new b,this.a=0}static MakeArray(t){return b2MakeArray(t,t=>new ds)}}class ps{constructor(){this.v=new b,this.w=0}static MakeArray(t){return b2MakeArray(t,t=>new ps)}}class ys{constructor(){this.step=new us}}t.g_blockSolve=!0;class bs{constructor(){this.rA=new b,this.rB=new b,this.normalImpulse=0,this.tangentImpulse=0,this.normalMass=0,this.tangentMass=0,this.velocityBias=0}static MakeArray(t){return b2MakeArray(t,t=>new bs)}}class xs{constructor(){this.points=bs.MakeArray(2),this.normal=new b,this.tangent=new b,this.normalMass=new f,this.K=new f,this.indexA=0,this.indexB=0,this.invMassA=0,this.invMassB=0,this.invIA=0,this.invIB=0,this.friction=0,this.restitution=0,this.threshold=0,this.tangentSpeed=0,this.pointCount=0,this.contactIndex=0}static MakeArray(t){return b2MakeArray(t,t=>new xs)}}class As{constructor(){this.localPoints=b.MakeArray(2),this.localNormal=new b,this.localPoint=new b,this.indexA=0,this.indexB=0,this.invMassA=0,this.invMassB=0,this.localCenterA=new b,this.localCenterB=new b,this.invIA=0,this.invIB=0,this.type=t.b2ManifoldType.e_unknown,this.radiusA=0,this.radiusB=0,this.pointCount=0}static MakeArray(t){return b2MakeArray(t,t=>new As)}}class fs{constructor(){this.step=new us,this.count=0}}class Ss{constructor(){this.normal=new b,this.point=new b,this.separation=0}Initialize(e,s,i,n){const o=Ss.Initialize_s_pointA,r=Ss.Initialize_s_pointB,h=Ss.Initialize_s_planePoint,a=Ss.Initialize_s_clipPoint;switch(e.type){case t.b2ManifoldType.e_circles:g.MulXV(s,e.localPoint,o),g.MulXV(i,e.localPoints[0],r),b.SubVV(r,o,this.normal).SelfNormalize(),b.MidVV(o,r,this.point),this.separation=b.DotVV(b.SubVV(r,o,b.s_t0),this.normal)-e.radiusA-e.radiusB;break;case t.b2ManifoldType.e_faceA:w.MulRV(s.q,e.localNormal,this.normal),g.MulXV(s,e.localPoint,h),g.MulXV(i,e.localPoints[n],a),this.separation=b.DotVV(b.SubVV(a,h,b.s_t0),this.normal)-e.radiusA-e.radiusB,this.point.Copy(a);break;case t.b2ManifoldType.e_faceB:w.MulRV(i.q,e.localNormal,this.normal),g.MulXV(i,e.localPoint,h),g.MulXV(s,e.localPoints[n],a),this.separation=b.DotVV(b.SubVV(a,h,b.s_t0),this.normal)-e.radiusA-e.radiusB,this.point.Copy(a),this.normal.SelfNeg()}}}Ss.Initialize_s_pointA=new b,Ss.Initialize_s_pointB=new b,Ss.Initialize_s_planePoint=new b,Ss.Initialize_s_clipPoint=new b;class ws{constructor(){this.m_step=new us,this.m_positionConstraints=As.MakeArray(1024),this.m_velocityConstraints=xs.MakeArray(1024),this.m_count=0}Initialize(t){if(this.m_step.Copy(t.step),this.m_count=t.count,this.m_positionConstraints.length0?1/r:0;const h=o.tangent,a=b.CrossVV(e.rA,h),_=b.CrossVV(e.rB,h),l=c+u+d*a*a+p*_*_;e.tangentMass=l>0?1/l:0,e.velocityBias=0;const m=b.DotVV(o.normal,b.SubVV(b.AddVCrossSV(B,v,e.rB,b.s_t0),b.AddVCrossSV(S,g,e.rA,b.s_t1),b.s_t0));m<-o.threshold&&(e.velocityBias+=-o.restitution*m)}if(2===o.pointCount&&t.g_blockSolve){const t=o.points[0],e=o.points[1],s=b.CrossVV(t.rA,o.normal),i=b.CrossVV(t.rB,o.normal),n=b.CrossVV(e.rA,o.normal),r=b.CrossVV(e.rB,o.normal),h=c+u+d*s*s+p*i*i,a=c+u+d*n*n+p*r*r,_=c+u+d*s*n+p*i*r;h*h<1e3*(h*a-_*_)?(o.K.ex.Set(h,_),o.K.ey.Set(_,a),o.K.GetInverse(o.normalMass)):o.pointCount=1}}}WarmStart(){const t=ws.WarmStart_s_P;for(let e=0;e=0&&h.y>=0){b.SubVV(h,o,a),b.MulSV(a.x,v,_),b.MulSV(a.y,v,l),b.AddVV(_,l,m),g.SelfMulSub(y,m),C-=x*(b.CrossVV(t.rA,_)+b.CrossVV(e.rA,l)),V.SelfMulAdd(A,m),B+=S*(b.CrossVV(t.rB,_)+b.CrossVV(e.rB,l)),t.normalImpulse=h.x,e.normalImpulse=h.y;break}if(h.x=-t.normalMass*r.x,h.y=0,n=0,c=u.K.ex.y*h.x+r.y,h.x>=0&&c>=0){b.SubVV(h,o,a),b.MulSV(a.x,v,_),b.MulSV(a.y,v,l),b.AddVV(_,l,m),g.SelfMulSub(y,m),C-=x*(b.CrossVV(t.rA,_)+b.CrossVV(e.rA,l)),V.SelfMulAdd(A,m),B+=S*(b.CrossVV(t.rB,_)+b.CrossVV(e.rB,l)),t.normalImpulse=h.x,e.normalImpulse=h.y;break}if(h.x=0,h.y=-e.normalMass*r.y,n=u.K.ey.x*h.y+r.x,c=0,h.y>=0&&n>=0){b.SubVV(h,o,a),b.MulSV(a.x,v,_),b.MulSV(a.y,v,l),b.AddVV(_,l,m),g.SelfMulSub(y,m),C-=x*(b.CrossVV(t.rA,_)+b.CrossVV(e.rA,l)),V.SelfMulAdd(A,m),B+=S*(b.CrossVV(t.rB,_)+b.CrossVV(e.rB,l)),t.normalImpulse=h.x,e.normalImpulse=h.y;break}if(h.x=0,h.y=0,n=r.x,c=r.y,n>=0&&c>=0){b.SubVV(h,o,a),b.MulSV(a.x,v,_),b.MulSV(a.y,v,l),b.AddVV(_,l,m),g.SelfMulSub(y,m),C-=x*(b.CrossVV(t.rA,_)+b.CrossVV(e.rA,l)),V.SelfMulAdd(A,m),B+=S*(b.CrossVV(t.rB,_)+b.CrossVV(e.rB,l)),t.normalImpulse=h.x,e.normalImpulse=h.y;break}break}}this.m_velocities[d].w=C,this.m_velocities[p].w=B}}StoreImpulses(){for(let t=0;t0?-C/v:0;b.MulSV(M,_,o),A.SelfMulSub(c,o),f-=u*b.CrossVV(i,o),S.SelfMulAdd(p,o),g+=y*b.CrossVV(n,o)}this.m_positions[_].a=f,this.m_positions[l].a=g}return r>-.015}SolveTOIPositionConstraints(t,e){const s=ws.SolveTOIPositionConstraints_s_xfA,i=ws.SolveTOIPositionConstraints_s_xfB,n=ws.SolveTOIPositionConstraints_s_psm,o=ws.SolveTOIPositionConstraints_s_rA,r=ws.SolveTOIPositionConstraints_s_rB,h=ws.SolveTOIPositionConstraints_s_P;let a=0;for(let _=0;_0?-c/v:0;b.MulSV(M,e,h),S.SelfMulSub(y,h),g-=x*b.CrossVV(o,h),C.SelfMulAdd(A,h),V+=f*b.CrossVV(r,h)}this.m_positions[m].a=g,this.m_positions[c].a=V}return a>=-.0075}}ws.InitializeVelocityConstraints_s_xfA=new g,ws.InitializeVelocityConstraints_s_xfB=new g,ws.InitializeVelocityConstraints_s_worldManifold=new nt,ws.WarmStart_s_P=new b,ws.SolveVelocityConstraints_s_dv=new b,ws.SolveVelocityConstraints_s_dv1=new b,ws.SolveVelocityConstraints_s_dv2=new b,ws.SolveVelocityConstraints_s_P=new b,ws.SolveVelocityConstraints_s_a=new b,ws.SolveVelocityConstraints_s_b=new b,ws.SolveVelocityConstraints_s_x=new b,ws.SolveVelocityConstraints_s_d=new b,ws.SolveVelocityConstraints_s_P1=new b,ws.SolveVelocityConstraints_s_P2=new b,ws.SolveVelocityConstraints_s_P1P2=new b,ws.SolvePositionConstraints_s_xfA=new g,ws.SolvePositionConstraints_s_xfB=new g,ws.SolvePositionConstraints_s_psm=new Ss,ws.SolvePositionConstraints_s_rA=new b,ws.SolvePositionConstraints_s_rB=new b,ws.SolvePositionConstraints_s_P=new b,ws.SolveTOIPositionConstraints_s_xfA=new g,ws.SolveTOIPositionConstraints_s_xfB=new g,ws.SolveTOIPositionConstraints_s_psm=new Ss,ws.SolveTOIPositionConstraints_s_rA=new b,ws.SolveTOIPositionConstraints_s_rB=new b,ws.SolveTOIPositionConstraints_s_P=new b;class gs extends Je{constructor(t){super(t),this.m_localAnchorA=new b,this.m_localAnchorB=new b,this.m_linearImpulse=new b,this.m_angularImpulse=0,this.m_maxForce=0,this.m_maxTorque=0,this.m_indexA=0,this.m_indexB=0,this.m_rA=new b,this.m_rB=new b,this.m_localCenterA=new b,this.m_localCenterB=new b,this.m_invMassA=0,this.m_invMassB=0,this.m_invIA=0,this.m_invIB=0,this.m_linearMass=new f,this.m_angularMass=0,this.m_qA=new w,this.m_qB=new w,this.m_lalcA=new b,this.m_lalcB=new b,this.m_K=new f,this.m_localAnchorA.Copy(b2Maybe(t.localAnchorA,b.ZERO)),this.m_localAnchorB.Copy(b2Maybe(t.localAnchorB,b.ZERO)),this.m_linearImpulse.SetZero(),this.m_maxForce=b2Maybe(t.maxForce,0),this.m_maxTorque=b2Maybe(t.maxTorque,0),this.m_linearMass.SetZero()}InitVelocityConstraints(t){this.m_indexA=this.m_bodyA.m_islandIndex,this.m_indexB=this.m_bodyB.m_islandIndex,this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter),this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter),this.m_invMassA=this.m_bodyA.m_invMass,this.m_invMassB=this.m_bodyB.m_invMass,this.m_invIA=this.m_bodyA.m_invI,this.m_invIB=this.m_bodyB.m_invI;const e=t.positions[this.m_indexA].a,s=t.velocities[this.m_indexA].v;let i=t.velocities[this.m_indexA].w;const n=t.positions[this.m_indexB].a,o=t.velocities[this.m_indexB].v;let r=t.velocities[this.m_indexB].w;const h=this.m_qA.SetAngle(e),a=this.m_qB.SetAngle(n);b.SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);const _=w.MulRV(h,this.m_lalcA,this.m_rA);b.SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);const l=w.MulRV(a,this.m_lalcB,this.m_rB),m=this.m_invMassA,c=this.m_invMassB,u=this.m_invIA,d=this.m_invIB,p=this.m_K;if(p.ex.x=m+c+u*_.y*_.y+d*l.y*l.y,p.ex.y=-u*_.x*_.y-d*l.x*l.y,p.ey.x=p.ex.y,p.ey.y=m+c+u*_.x*_.x+d*l.x*l.x,p.GetInverse(this.m_linearMass),this.m_angularMass=u+d,this.m_angularMass>0&&(this.m_angularMass=1/this.m_angularMass),t.step.warmStarting){this.m_linearImpulse.SelfMul(t.step.dtRatio),this.m_angularImpulse*=t.step.dtRatio;const e=this.m_linearImpulse;s.SelfMulSub(m,e),i-=u*(b.CrossVV(this.m_rA,e)+this.m_angularImpulse),o.SelfMulAdd(c,e),r+=d*(b.CrossVV(this.m_rB,e)+this.m_angularImpulse)}else this.m_linearImpulse.SetZero(),this.m_angularImpulse=0;t.velocities[this.m_indexA].w=i,t.velocities[this.m_indexB].w=r}SolveVelocityConstraints(t){const e=t.velocities[this.m_indexA].v;let s=t.velocities[this.m_indexA].w;const i=t.velocities[this.m_indexB].v;let n=t.velocities[this.m_indexB].w;const o=this.m_invMassA,r=this.m_invMassB,h=this.m_invIA,a=this.m_invIB,_=t.step.dt;{const t=n-s;let e=-this.m_angularMass*t;const i=this.m_angularImpulse,o=_*this.m_maxTorque;this.m_angularImpulse=b2Clamp(this.m_angularImpulse+e,-o,o),e=this.m_angularImpulse-i,s-=h*e,n+=a*e}{const t=b.SubVV(b.AddVCrossSV(i,n,this.m_rB,b.s_t0),b.AddVCrossSV(e,s,this.m_rA,b.s_t1),gs.SolveVelocityConstraints_s_Cdot_v2),l=f.MulMV(this.m_linearMass,t,gs.SolveVelocityConstraints_s_impulseV).SelfNeg(),m=gs.SolveVelocityConstraints_s_oldImpulseV.Copy(this.m_linearImpulse);this.m_linearImpulse.SelfAdd(l);const c=_*this.m_maxForce;this.m_linearImpulse.LengthSquared()>c*c&&(this.m_linearImpulse.Normalize(),this.m_linearImpulse.SelfMul(c)),b.SubVV(this.m_linearImpulse,m,l),e.SelfMulSub(o,l),s-=h*b.CrossVV(this.m_rA,l),i.SelfMulAdd(r,l),n+=a*b.CrossVV(this.m_rB,l)}t.velocities[this.m_indexA].w=s,t.velocities[this.m_indexB].w=n}SolvePositionConstraints(t){return!0}GetAnchorA(t){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA,t)}GetAnchorB(t){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB,t)}GetReactionForce(t,e){return e.x=t*this.m_linearImpulse.x,e.y=t*this.m_linearImpulse.y,e}GetReactionTorque(t){return t*this.m_angularImpulse}GetLocalAnchorA(){return this.m_localAnchorA}GetLocalAnchorB(){return this.m_localAnchorB}SetMaxForce(t){this.m_maxForce=t}GetMaxForce(){return this.m_maxForce}SetMaxTorque(t){this.m_maxTorque=t}GetMaxTorque(){return this.m_maxTorque}Dump(t){const e=this.m_bodyA.m_islandIndex,s=this.m_bodyB.m_islandIndex;t(" const jd: b2FrictionJointDef = new b2FrictionJointDef();\n"),t(" jd.bodyA = bodies[%d];\n",e),t(" jd.bodyB = bodies[%d];\n",s),t(" jd.collideConnected = %s;\n",this.m_collideConnected?"true":"false"),t(" jd.localAnchorA.Set(%.15f, %.15f);\n",this.m_localAnchorA.x,this.m_localAnchorA.y),t(" jd.localAnchorB.Set(%.15f, %.15f);\n",this.m_localAnchorB.x,this.m_localAnchorB.y),t(" jd.maxForce = %.15f;\n",this.m_maxForce),t(" jd.maxTorque = %.15f;\n",this.m_maxTorque),t(" joints[%d] = this.m_world.CreateJoint(jd);\n",this.m_index)}}gs.SolveVelocityConstraints_s_Cdot_v2=new b,gs.SolveVelocityConstraints_s_impulseV=new b,gs.SolveVelocityConstraints_s_oldImpulseV=new b;class Cs extends Je{constructor(e){let s,i;super(e),this.m_typeA=t.b2JointType.e_unknownJoint,this.m_typeB=t.b2JointType.e_unknownJoint,this.m_localAnchorA=new b,this.m_localAnchorB=new b,this.m_localAnchorC=new b,this.m_localAnchorD=new b,this.m_localAxisC=new b,this.m_localAxisD=new b,this.m_referenceAngleA=0,this.m_referenceAngleB=0,this.m_constant=0,this.m_ratio=0,this.m_impulse=0,this.m_indexA=0,this.m_indexB=0,this.m_indexC=0,this.m_indexD=0,this.m_lcA=new b,this.m_lcB=new b,this.m_lcC=new b,this.m_lcD=new b,this.m_mA=0,this.m_mB=0,this.m_mC=0,this.m_mD=0,this.m_iA=0,this.m_iB=0,this.m_iC=0,this.m_iD=0,this.m_JvAC=new b,this.m_JvBD=new b,this.m_JwA=0,this.m_JwB=0,this.m_JwC=0,this.m_JwD=0,this.m_mass=0,this.m_qA=new w,this.m_qB=new w,this.m_qC=new w,this.m_qD=new w,this.m_lalcA=new b,this.m_lalcB=new b,this.m_lalcC=new b,this.m_lalcD=new b,this.m_joint1=e.joint1,this.m_joint2=e.joint2,this.m_typeA=this.m_joint1.GetType(),this.m_typeB=this.m_joint2.GetType(),this.m_bodyC=this.m_joint1.GetBodyA(),this.m_bodyA=this.m_joint1.GetBodyB();const n=this.m_bodyA.m_xf,o=this.m_bodyA.m_sweep.a,r=this.m_bodyC.m_xf,h=this.m_bodyC.m_sweep.a;if(this.m_typeA===t.b2JointType.e_revoluteJoint){const t=e.joint1;this.m_localAnchorC.Copy(t.m_localAnchorA),this.m_localAnchorA.Copy(t.m_localAnchorB),this.m_referenceAngleA=t.m_referenceAngle,this.m_localAxisC.SetZero(),s=o-h-this.m_referenceAngleA}else{const t=e.joint1;this.m_localAnchorC.Copy(t.m_localAnchorA),this.m_localAnchorA.Copy(t.m_localAnchorB),this.m_referenceAngleA=t.m_referenceAngle,this.m_localAxisC.Copy(t.m_localXAxisA);const i=this.m_localAnchorC,o=w.MulTRV(r.q,b.AddVV(w.MulRV(n.q,this.m_localAnchorA,b.s_t0),b.SubVV(n.p,r.p,b.s_t1),b.s_t0),b.s_t0);s=b.DotVV(b.SubVV(o,i,b.s_t0),this.m_localAxisC)}this.m_bodyD=this.m_joint2.GetBodyA(),this.m_bodyB=this.m_joint2.GetBodyB();const a=this.m_bodyB.m_xf,_=this.m_bodyB.m_sweep.a,l=this.m_bodyD.m_xf,m=this.m_bodyD.m_sweep.a;if(this.m_typeB===t.b2JointType.e_revoluteJoint){const t=e.joint2;this.m_localAnchorD.Copy(t.m_localAnchorA),this.m_localAnchorB.Copy(t.m_localAnchorB),this.m_referenceAngleB=t.m_referenceAngle,this.m_localAxisD.SetZero(),i=_-m-this.m_referenceAngleB}else{const t=e.joint2;this.m_localAnchorD.Copy(t.m_localAnchorA),this.m_localAnchorB.Copy(t.m_localAnchorB),this.m_referenceAngleB=t.m_referenceAngle,this.m_localAxisD.Copy(t.m_localXAxisA);const s=this.m_localAnchorD,n=w.MulTRV(l.q,b.AddVV(w.MulRV(a.q,this.m_localAnchorB,b.s_t0),b.SubVV(a.p,l.p,b.s_t1),b.s_t0),b.s_t0);i=b.DotVV(b.SubVV(n,s,b.s_t0),this.m_localAxisD)}this.m_ratio=b2Maybe(e.ratio,1),this.m_constant=s+this.m_ratio*i,this.m_impulse=0}InitVelocityConstraints(e){this.m_indexA=this.m_bodyA.m_islandIndex,this.m_indexB=this.m_bodyB.m_islandIndex,this.m_indexC=this.m_bodyC.m_islandIndex,this.m_indexD=this.m_bodyD.m_islandIndex,this.m_lcA.Copy(this.m_bodyA.m_sweep.localCenter),this.m_lcB.Copy(this.m_bodyB.m_sweep.localCenter),this.m_lcC.Copy(this.m_bodyC.m_sweep.localCenter),this.m_lcD.Copy(this.m_bodyD.m_sweep.localCenter),this.m_mA=this.m_bodyA.m_invMass,this.m_mB=this.m_bodyB.m_invMass,this.m_mC=this.m_bodyC.m_invMass,this.m_mD=this.m_bodyD.m_invMass,this.m_iA=this.m_bodyA.m_invI,this.m_iB=this.m_bodyB.m_invI,this.m_iC=this.m_bodyC.m_invI,this.m_iD=this.m_bodyD.m_invI;const s=e.positions[this.m_indexA].a,i=e.velocities[this.m_indexA].v;let n=e.velocities[this.m_indexA].w;const o=e.positions[this.m_indexB].a,r=e.velocities[this.m_indexB].v;let h=e.velocities[this.m_indexB].w;const a=e.positions[this.m_indexC].a,_=e.velocities[this.m_indexC].v;let l=e.velocities[this.m_indexC].w;const m=e.positions[this.m_indexD].a,c=e.velocities[this.m_indexD].v;let u=e.velocities[this.m_indexD].w;const d=this.m_qA.SetAngle(s),p=this.m_qB.SetAngle(o),y=this.m_qC.SetAngle(a),x=this.m_qD.SetAngle(m);if(this.m_mass=0,this.m_typeA===t.b2JointType.e_revoluteJoint)this.m_JvAC.SetZero(),this.m_JwA=1,this.m_JwC=1,this.m_mass+=this.m_iA+this.m_iC;else{const t=w.MulRV(y,this.m_localAxisC,Cs.InitVelocityConstraints_s_u);b.SubVV(this.m_localAnchorC,this.m_lcC,this.m_lalcC);const e=w.MulRV(y,this.m_lalcC,Cs.InitVelocityConstraints_s_rC);b.SubVV(this.m_localAnchorA,this.m_lcA,this.m_lalcA);const s=w.MulRV(d,this.m_lalcA,Cs.InitVelocityConstraints_s_rA);this.m_JvAC.Copy(t),this.m_JwC=b.CrossVV(e,t),this.m_JwA=b.CrossVV(s,t),this.m_mass+=this.m_mC+this.m_mA+this.m_iC*this.m_JwC*this.m_JwC+this.m_iA*this.m_JwA*this.m_JwA}if(this.m_typeB===t.b2JointType.e_revoluteJoint)this.m_JvBD.SetZero(),this.m_JwB=this.m_ratio,this.m_JwD=this.m_ratio,this.m_mass+=this.m_ratio*this.m_ratio*(this.m_iB+this.m_iD);else{const t=w.MulRV(x,this.m_localAxisD,Cs.InitVelocityConstraints_s_u);b.SubVV(this.m_localAnchorD,this.m_lcD,this.m_lalcD);const e=w.MulRV(x,this.m_lalcD,Cs.InitVelocityConstraints_s_rD);b.SubVV(this.m_localAnchorB,this.m_lcB,this.m_lalcB);const s=w.MulRV(p,this.m_lalcB,Cs.InitVelocityConstraints_s_rB);b.MulSV(this.m_ratio,t,this.m_JvBD),this.m_JwD=this.m_ratio*b.CrossVV(e,t),this.m_JwB=this.m_ratio*b.CrossVV(s,t),this.m_mass+=this.m_ratio*this.m_ratio*(this.m_mD+this.m_mB)+this.m_iD*this.m_JwD*this.m_JwD+this.m_iB*this.m_JwB*this.m_JwB}this.m_mass=this.m_mass>0?1/this.m_mass:0,e.step.warmStarting?(i.SelfMulAdd(this.m_mA*this.m_impulse,this.m_JvAC),n+=this.m_iA*this.m_impulse*this.m_JwA,r.SelfMulAdd(this.m_mB*this.m_impulse,this.m_JvBD),h+=this.m_iB*this.m_impulse*this.m_JwB,_.SelfMulSub(this.m_mC*this.m_impulse,this.m_JvAC),l-=this.m_iC*this.m_impulse*this.m_JwC,c.SelfMulSub(this.m_mD*this.m_impulse,this.m_JvBD),u-=this.m_iD*this.m_impulse*this.m_JwD):this.m_impulse=0,e.velocities[this.m_indexA].w=n,e.velocities[this.m_indexB].w=h,e.velocities[this.m_indexC].w=l,e.velocities[this.m_indexD].w=u}SolveVelocityConstraints(t){const e=t.velocities[this.m_indexA].v;let s=t.velocities[this.m_indexA].w;const i=t.velocities[this.m_indexB].v;let n=t.velocities[this.m_indexB].w;const o=t.velocities[this.m_indexC].v;let r=t.velocities[this.m_indexC].w;const h=t.velocities[this.m_indexD].v;let a=t.velocities[this.m_indexD].w,_=b.DotVV(this.m_JvAC,b.SubVV(e,o,b.s_t0))+b.DotVV(this.m_JvBD,b.SubVV(i,h,b.s_t0));_+=this.m_JwA*s-this.m_JwC*r+(this.m_JwB*n-this.m_JwD*a);const l=-this.m_mass*_;this.m_impulse+=l,e.SelfMulAdd(this.m_mA*l,this.m_JvAC),s+=this.m_iA*l*this.m_JwA,i.SelfMulAdd(this.m_mB*l,this.m_JvBD),n+=this.m_iB*l*this.m_JwB,o.SelfMulSub(this.m_mC*l,this.m_JvAC),r-=this.m_iC*l*this.m_JwC,h.SelfMulSub(this.m_mD*l,this.m_JvBD),a-=this.m_iD*l*this.m_JwD,t.velocities[this.m_indexA].w=s,t.velocities[this.m_indexB].w=n,t.velocities[this.m_indexC].w=r,t.velocities[this.m_indexD].w=a}SolvePositionConstraints(e){const s=e.positions[this.m_indexA].c;let i=e.positions[this.m_indexA].a;const n=e.positions[this.m_indexB].c;let o=e.positions[this.m_indexB].a;const r=e.positions[this.m_indexC].c;let h=e.positions[this.m_indexC].a;const a=e.positions[this.m_indexD].c;let _=e.positions[this.m_indexD].a;const l=this.m_qA.SetAngle(i),m=this.m_qB.SetAngle(o),c=this.m_qC.SetAngle(h),u=this.m_qD.SetAngle(_);let d,p;const y=this.m_JvAC,x=this.m_JvBD;let A,f,S,g,C=0;if(this.m_typeA===t.b2JointType.e_revoluteJoint)y.SetZero(),A=1,S=1,C+=this.m_iA+this.m_iC,d=i-h-this.m_referenceAngleA;else{const t=w.MulRV(c,this.m_localAxisC,Cs.SolvePositionConstraints_s_u),e=w.MulRV(c,this.m_lalcC,Cs.SolvePositionConstraints_s_rC),i=w.MulRV(l,this.m_lalcA,Cs.SolvePositionConstraints_s_rA);y.Copy(t),S=b.CrossVV(e,t),A=b.CrossVV(i,t),C+=this.m_mC+this.m_mA+this.m_iC*S*S+this.m_iA*A*A;const n=this.m_lalcC,o=w.MulTRV(c,b.AddVV(i,b.SubVV(s,r,b.s_t0),b.s_t0),b.s_t0);d=b.DotVV(b.SubVV(o,n,b.s_t0),this.m_localAxisC)}if(this.m_typeB===t.b2JointType.e_revoluteJoint)x.SetZero(),f=this.m_ratio,g=this.m_ratio,C+=this.m_ratio*this.m_ratio*(this.m_iB+this.m_iD),p=o-_-this.m_referenceAngleB;else{const t=w.MulRV(u,this.m_localAxisD,Cs.SolvePositionConstraints_s_u),e=w.MulRV(u,this.m_lalcD,Cs.SolvePositionConstraints_s_rD),s=w.MulRV(m,this.m_lalcB,Cs.SolvePositionConstraints_s_rB);b.MulSV(this.m_ratio,t,x),g=this.m_ratio*b.CrossVV(e,t),f=this.m_ratio*b.CrossVV(s,t),C+=this.m_ratio*this.m_ratio*(this.m_mD+this.m_mB)+this.m_iD*g*g+this.m_iB*f*f;const i=this.m_lalcD,o=w.MulTRV(u,b.AddVV(s,b.SubVV(n,a,b.s_t0),b.s_t0),b.s_t0);p=b.DotVV(b.SubVV(o,i,b.s_t0),this.m_localAxisD)}const V=d+this.m_ratio*p-this.m_constant;let B=0;return C>0&&(B=-V/C),s.SelfMulAdd(this.m_mA*B,y),i+=this.m_iA*B*A,n.SelfMulAdd(this.m_mB*B,x),o+=this.m_iB*B*f,r.SelfMulSub(this.m_mC*B,y),h-=this.m_iC*B*S,a.SelfMulSub(this.m_mD*B,x),_-=this.m_iD*B*g,e.positions[this.m_indexA].a=i,e.positions[this.m_indexB].a=o,e.positions[this.m_indexC].a=h,e.positions[this.m_indexD].a=_,!0}GetAnchorA(t){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA,t)}GetAnchorB(t){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB,t)}GetReactionForce(t,e){return b.MulSV(t*this.m_impulse,this.m_JvAC,e)}GetReactionTorque(t){return t*this.m_impulse*this.m_JwA}GetJoint1(){return this.m_joint1}GetJoint2(){return this.m_joint2}GetRatio(){return this.m_ratio}SetRatio(t){this.m_ratio=t}Dump(t){const e=this.m_bodyA.m_islandIndex,s=this.m_bodyB.m_islandIndex,i=this.m_joint1.m_index,n=this.m_joint2.m_index;t(" const jd: b2GearJointDef = new b2GearJointDef();\n"),t(" jd.bodyA = bodies[%d];\n",e),t(" jd.bodyB = bodies[%d];\n",s),t(" jd.collideConnected = %s;\n",this.m_collideConnected?"true":"false"),t(" jd.joint1 = joints[%d];\n",i),t(" jd.joint2 = joints[%d];\n",n),t(" jd.ratio = %.15f;\n",this.m_ratio),t(" joints[%d] = this.m_world.CreateJoint(jd);\n",this.m_index)}}Cs.InitVelocityConstraints_s_u=new b,Cs.InitVelocityConstraints_s_rA=new b,Cs.InitVelocityConstraints_s_rB=new b,Cs.InitVelocityConstraints_s_rC=new b,Cs.InitVelocityConstraints_s_rD=new b,Cs.SolvePositionConstraints_s_u=new b,Cs.SolvePositionConstraints_s_rA=new b,Cs.SolvePositionConstraints_s_rB=new b,Cs.SolvePositionConstraints_s_rC=new b,Cs.SolvePositionConstraints_s_rD=new b;class Vs{constructor(){this.m_bodies=[],this.m_contacts=[],this.m_joints=[],this.m_positions=ds.MakeArray(1024),this.m_velocities=ps.MakeArray(1024),this.m_bodyCount=0,this.m_jointCount=0,this.m_contactCount=0,this.m_bodyCapacity=0,this.m_contactCapacity=0,this.m_jointCapacity=0}Initialize(t,e,s,i){if(this.m_bodyCapacity=t,this.m_contactCapacity=e,this.m_jointCapacity=s,this.m_bodyCount=0,this.m_contactCount=0,this.m_jointCount=0,this.m_listener=i,this.m_positions.length4){const t=2/o.Length();i.SelfMul(t)}const r=h*n;if(r*r>2.4674011002726646){n*=1.570796326795/a(r)}e.x+=h*i.x,e.y+=h*i.y,s+=h*n,this.m_positions[t].a=s,this.m_velocities[t].w=n}r.Reset();let c=!1;for(let t=0;tn||b.DotVV(o.m_linearVelocity,o.m_linearVelocity)>s?(o.m_sleepTime=0,e=0):(o.m_sleepTime+=h,e=b2Min(e,o.m_sleepTime)))}if(e>=.5&&c)for(let t=0;t4){const t=2/r.Length();i.SelfMul(t)}const h=o*n;if(h*h>2.4674011002726646){n*=1.570796326795/a(h)}e.SelfMulAdd(o,i),s+=o*n,this.m_positions[t].a=s,this.m_velocities[t].w=n;const _=this.m_bodies[t];_.m_sweep.c.Copy(e),_.m_sweep.a=s,_.m_linearVelocity.Copy(i),_.m_angularVelocity=n,_.SynchronizeTransform()}this.Report(n.m_velocityConstraints)}Report(t){if(null!==this.m_listener)for(let e=0;e0&&(this.m_angularMass=1/this.m_angularMass),b.SubVV(b.AddVV(o,c,b.s_t0),b.AddVV(e,m,b.s_t1),this.m_linearError),this.m_angularError=r-s-this.m_angularOffset,t.step.warmStarting){this.m_linearImpulse.SelfMul(t.step.dtRatio),this.m_angularImpulse*=t.step.dtRatio;const e=this.m_linearImpulse;i.SelfMulSub(u,e),n-=p*(b.CrossVV(m,e)+this.m_angularImpulse),h.SelfMulAdd(d,e),a+=y*(b.CrossVV(c,e)+this.m_angularImpulse)}else this.m_linearImpulse.SetZero(),this.m_angularImpulse=0;t.velocities[this.m_indexA].w=n,t.velocities[this.m_indexB].w=a}SolveVelocityConstraints(t){const e=t.velocities[this.m_indexA].v;let s=t.velocities[this.m_indexA].w;const i=t.velocities[this.m_indexB].v;let n=t.velocities[this.m_indexB].w;const o=this.m_invMassA,r=this.m_invMassB,h=this.m_invIA,a=this.m_invIB,_=t.step.dt,l=t.step.inv_dt;{const t=n-s+l*this.m_correctionFactor*this.m_angularError;let e=-this.m_angularMass*t;const i=this.m_angularImpulse,o=_*this.m_maxTorque;this.m_angularImpulse=b2Clamp(this.m_angularImpulse+e,-o,o),e=this.m_angularImpulse-i,s-=h*e,n+=a*e}{const t=this.m_rA,m=this.m_rB,c=b.AddVV(b.SubVV(b.AddVV(i,b.CrossSV(n,m,b.s_t0),b.s_t0),b.AddVV(e,b.CrossSV(s,t,b.s_t1),b.s_t1),b.s_t2),b.MulSV(l*this.m_correctionFactor,this.m_linearError,b.s_t3),Bs.SolveVelocityConstraints_s_Cdot_v2),u=f.MulMV(this.m_linearMass,c,Bs.SolveVelocityConstraints_s_impulse_v2).SelfNeg(),d=Bs.SolveVelocityConstraints_s_oldImpulse_v2.Copy(this.m_linearImpulse);this.m_linearImpulse.SelfAdd(u);const p=_*this.m_maxForce;this.m_linearImpulse.LengthSquared()>p*p&&(this.m_linearImpulse.Normalize(),this.m_linearImpulse.SelfMul(p)),b.SubVV(this.m_linearImpulse,d,u),e.SelfMulSub(o,u),s-=h*b.CrossVV(t,u),i.SelfMulAdd(r,u),n+=a*b.CrossVV(m,u)}t.velocities[this.m_indexA].w=s,t.velocities[this.m_indexB].w=n}SolvePositionConstraints(t){return!0}Dump(t){const e=this.m_bodyA.m_islandIndex,s=this.m_bodyB.m_islandIndex;t(" const jd: b2MotorJointDef = new b2MotorJointDef();\n"),t(" jd.bodyA = bodies[%d];\n",e),t(" jd.bodyB = bodies[%d];\n",s),t(" jd.collideConnected = %s;\n",this.m_collideConnected?"true":"false"),t(" jd.linearOffset.Set(%.15f, %.15f);\n",this.m_linearOffset.x,this.m_linearOffset.y),t(" jd.angularOffset = %.15f;\n",this.m_angularOffset),t(" jd.maxForce = %.15f;\n",this.m_maxForce),t(" jd.maxTorque = %.15f;\n",this.m_maxTorque),t(" jd.correctionFactor = %.15f;\n",this.m_correctionFactor),t(" joints[%d] = this.m_world.CreateJoint(jd);\n",this.m_index)}}Bs.SolveVelocityConstraints_s_Cdot_v2=new b,Bs.SolveVelocityConstraints_s_impulse_v2=new b,Bs.SolveVelocityConstraints_s_oldImpulse_v2=new b;class vs extends Je{constructor(t){super(t),this.m_localAnchorB=new b,this.m_targetA=new b,this.m_stiffness=0,this.m_damping=0,this.m_beta=0,this.m_impulse=new b,this.m_maxForce=0,this.m_gamma=0,this.m_indexA=0,this.m_indexB=0,this.m_rB=new b,this.m_localCenterB=new b,this.m_invMassB=0,this.m_invIB=0,this.m_mass=new f,this.m_C=new b,this.m_qB=new w,this.m_lalcB=new b,this.m_K=new f,this.m_targetA.Copy(b2Maybe(t.target,b.ZERO)),g.MulTXV(this.m_bodyB.GetTransform(),this.m_targetA,this.m_localAnchorB),this.m_maxForce=b2Maybe(t.maxForce,0),this.m_impulse.SetZero(),this.m_stiffness=b2Maybe(t.stiffness,0),this.m_damping=b2Maybe(t.damping,0),this.m_beta=0,this.m_gamma=0}SetTarget(t){this.m_bodyB.IsAwake()||this.m_bodyB.SetAwake(!0),this.m_targetA.Copy(t)}GetTarget(){return this.m_targetA}SetMaxForce(t){this.m_maxForce=t}GetMaxForce(){return this.m_maxForce}SetStiffness(t){this.m_stiffness=t}GetStiffness(){return this.m_stiffness}SetDamping(t){this.m_damping=t}GetDamping(){return this.m_damping}InitVelocityConstraints(t){this.m_indexB=this.m_bodyB.m_islandIndex,this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter),this.m_invMassB=this.m_bodyB.m_invMass,this.m_invIB=this.m_bodyB.m_invI;const e=t.positions[this.m_indexB].c,s=t.positions[this.m_indexB].a,i=t.velocities[this.m_indexB].v;let o=t.velocities[this.m_indexB].w;const r=this.m_qB.SetAngle(s),h=this.m_bodyB.GetMass(),a=2*n*this.m_stiffness,_=2*h*this.m_damping*a,l=h*(a*a),m=t.step.dt;this.m_gamma=m*(_+m*l),0!==this.m_gamma&&(this.m_gamma=1/this.m_gamma),this.m_beta=m*l*this.m_gamma,b.SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB),w.MulRV(r,this.m_lalcB,this.m_rB);const c=this.m_K;c.ex.x=this.m_invMassB+this.m_invIB*this.m_rB.y*this.m_rB.y+this.m_gamma,c.ex.y=-this.m_invIB*this.m_rB.x*this.m_rB.y,c.ey.x=c.ex.y,c.ey.y=this.m_invMassB+this.m_invIB*this.m_rB.x*this.m_rB.x+this.m_gamma,c.GetInverse(this.m_mass),this.m_C.x=e.x+this.m_rB.x-this.m_targetA.x,this.m_C.y=e.y+this.m_rB.y-this.m_targetA.y,this.m_C.SelfMul(this.m_beta),o*=.98,t.step.warmStarting?(this.m_impulse.SelfMul(t.step.dtRatio),i.x+=this.m_invMassB*this.m_impulse.x,i.y+=this.m_invMassB*this.m_impulse.y,o+=this.m_invIB*b.CrossVV(this.m_rB,this.m_impulse)):this.m_impulse.SetZero(),t.velocities[this.m_indexB].w=o}SolveVelocityConstraints(t){const e=t.velocities[this.m_indexB].v;let s=t.velocities[this.m_indexB].w;const i=b.AddVCrossSV(e,s,this.m_rB,vs.SolveVelocityConstraints_s_Cdot),n=f.MulMV(this.m_mass,b.AddVV(i,b.AddVV(this.m_C,b.MulSV(this.m_gamma,this.m_impulse,b.s_t0),b.s_t0),b.s_t0).SelfNeg(),vs.SolveVelocityConstraints_s_impulse),o=vs.SolveVelocityConstraints_s_oldImpulse.Copy(this.m_impulse);this.m_impulse.SelfAdd(n);const r=t.step.dt*this.m_maxForce;this.m_impulse.LengthSquared()>r*r&&this.m_impulse.SelfMul(r/this.m_impulse.Length()),b.SubVV(this.m_impulse,o,n),e.SelfMulAdd(this.m_invMassB,n),s+=this.m_invIB*b.CrossVV(this.m_rB,n),t.velocities[this.m_indexB].w=s}SolvePositionConstraints(t){return!0}GetAnchorA(t){return t.x=this.m_targetA.x,t.y=this.m_targetA.y,t}GetAnchorB(t){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB,t)}GetReactionForce(t,e){return b.MulSV(t,this.m_impulse,e)}GetReactionTorque(t){return 0}Dump(t){t("Mouse joint dumping is not supported.\n")}ShiftOrigin(t){this.m_targetA.SelfSub(t)}}vs.SolveVelocityConstraints_s_Cdot=new b,vs.SolveVelocityConstraints_s_impulse=new b,vs.SolveVelocityConstraints_s_oldImpulse=new b;class Ms extends Je{constructor(t){super(t),this.m_localAnchorA=new b,this.m_localAnchorB=new b,this.m_localXAxisA=new b,this.m_localYAxisA=new b,this.m_referenceAngle=0,this.m_impulse=new b(0,0),this.m_motorImpulse=0,this.m_lowerImpulse=0,this.m_upperImpulse=0,this.m_lowerTranslation=0,this.m_upperTranslation=0,this.m_maxMotorForce=0,this.m_motorSpeed=0,this.m_enableLimit=!1,this.m_enableMotor=!1,this.m_indexA=0,this.m_indexB=0,this.m_localCenterA=new b,this.m_localCenterB=new b,this.m_invMassA=0,this.m_invMassB=0,this.m_invIA=0,this.m_invIB=0,this.m_axis=new b(0,0),this.m_perp=new b(0,0),this.m_s1=0,this.m_s2=0,this.m_a1=0,this.m_a2=0,this.m_K=new f,this.m_K3=new S,this.m_K2=new f,this.m_translation=0,this.m_axialMass=0,this.m_qA=new w,this.m_qB=new w,this.m_lalcA=new b,this.m_lalcB=new b,this.m_rA=new b,this.m_rB=new b,this.m_localAnchorA.Copy(b2Maybe(t.localAnchorA,b.ZERO)),this.m_localAnchorB.Copy(b2Maybe(t.localAnchorB,b.ZERO)),this.m_localXAxisA.Copy(b2Maybe(t.localAxisA,new b(1,0))).SelfNormalize(),b.CrossOneV(this.m_localXAxisA,this.m_localYAxisA),this.m_referenceAngle=b2Maybe(t.referenceAngle,0),this.m_lowerTranslation=b2Maybe(t.lowerTranslation,0),this.m_upperTranslation=b2Maybe(t.upperTranslation,0),this.m_maxMotorForce=b2Maybe(t.maxMotorForce,0),this.m_motorSpeed=b2Maybe(t.motorSpeed,0),this.m_enableLimit=b2Maybe(t.enableLimit,!1),this.m_enableMotor=b2Maybe(t.enableMotor,!1)}InitVelocityConstraints(t){this.m_indexA=this.m_bodyA.m_islandIndex,this.m_indexB=this.m_bodyB.m_islandIndex,this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter),this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter),this.m_invMassA=this.m_bodyA.m_invMass,this.m_invMassB=this.m_bodyB.m_invMass,this.m_invIA=this.m_bodyA.m_invI,this.m_invIB=this.m_bodyB.m_invI;const e=t.positions[this.m_indexA].c,s=t.positions[this.m_indexA].a,i=t.velocities[this.m_indexA].v;let n=t.velocities[this.m_indexA].w;const o=t.positions[this.m_indexB].c,r=t.positions[this.m_indexB].a,h=t.velocities[this.m_indexB].v;let a=t.velocities[this.m_indexB].w;const _=this.m_qA.SetAngle(s),l=this.m_qB.SetAngle(r);b.SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);const m=w.MulRV(_,this.m_lalcA,this.m_rA);b.SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);const c=w.MulRV(l,this.m_lalcB,this.m_rB),u=b.AddVV(b.SubVV(o,e,b.s_t0),b.SubVV(c,m,b.s_t1),Ms.InitVelocityConstraints_s_d),d=this.m_invMassA,p=this.m_invMassB,y=this.m_invIA,x=this.m_invIB;if(w.MulRV(_,this.m_localXAxisA,this.m_axis),this.m_a1=b.CrossVV(b.AddVV(u,m,b.s_t0),this.m_axis),this.m_a2=b.CrossVV(c,this.m_axis),this.m_axialMass=d+p+y*this.m_a1*this.m_a1+x*this.m_a2*this.m_a2,this.m_axialMass>0&&(this.m_axialMass=1/this.m_axialMass),w.MulRV(_,this.m_localYAxisA,this.m_perp),this.m_s1=b.CrossVV(b.AddVV(u,m,b.s_t0),this.m_perp),this.m_s2=b.CrossVV(c,this.m_perp),this.m_K.ex.x=d+p+y*this.m_s1*this.m_s1+x*this.m_s2*this.m_s2,this.m_K.ex.y=y*this.m_s1+x*this.m_s2,this.m_K.ey.x=this.m_K.ex.y,this.m_K.ey.y=y+x,0===this.m_K.ey.y&&(this.m_K.ey.y=1),this.m_enableLimit?this.m_translation=b.DotVV(this.m_axis,u):(this.m_lowerImpulse=0,this.m_upperImpulse=0),this.m_enableMotor||(this.m_motorImpulse=0),t.step.warmStarting){this.m_impulse.SelfMul(t.step.dtRatio),this.m_motorImpulse*=t.step.dtRatio,this.m_lowerImpulse*=t.step.dtRatio,this.m_upperImpulse*=t.step.dtRatio;const e=this.m_motorImpulse+this.m_lowerImpulse-this.m_upperImpulse,s=b.AddVV(b.MulSV(this.m_impulse.x,this.m_perp,b.s_t0),b.MulSV(e,this.m_axis,b.s_t1),Ms.InitVelocityConstraints_s_P),o=this.m_impulse.x*this.m_s1+this.m_impulse.y+e*this.m_a1,r=this.m_impulse.x*this.m_s2+this.m_impulse.y+e*this.m_a2;i.SelfMulSub(d,s),n-=y*o,h.SelfMulAdd(p,s),a+=x*r}else this.m_impulse.SetZero(),this.m_motorImpulse=0,this.m_lowerImpulse=0,this.m_upperImpulse=0;t.velocities[this.m_indexA].w=n,t.velocities[this.m_indexB].w=a}SolveVelocityConstraints(t){const e=t.velocities[this.m_indexA].v;let s=t.velocities[this.m_indexA].w;const i=t.velocities[this.m_indexB].v;let n=t.velocities[this.m_indexB].w;const o=this.m_invMassA,r=this.m_invMassB,h=this.m_invIA,a=this.m_invIB;if(this.m_enableMotor){const _=b.DotVV(this.m_axis,b.SubVV(i,e,b.s_t0))+this.m_a2*n-this.m_a1*s;let l=this.m_axialMass*(this.m_motorSpeed-_);const m=this.m_motorImpulse,c=t.step.dt*this.m_maxMotorForce;this.m_motorImpulse=b2Clamp(this.m_motorImpulse+l,-c,c),l=this.m_motorImpulse-m;const u=b.MulSV(l,this.m_axis,Ms.SolveVelocityConstraints_s_P),d=l*this.m_a1,p=l*this.m_a2;e.SelfMulSub(o,u),s-=h*d,i.SelfMulAdd(r,u),n+=a*p}if(this.m_enableLimit){{const _=this.m_translation-this.m_lowerTranslation,l=b.DotVV(this.m_axis,b.SubVV(i,e,b.s_t0))+this.m_a2*n-this.m_a1*s;let m=-this.m_axialMass*(l+b2Max(_,0)*t.step.inv_dt);const c=this.m_lowerImpulse;this.m_lowerImpulse=b2Max(this.m_lowerImpulse+m,0),m=this.m_lowerImpulse-c;const u=b.MulSV(m,this.m_axis,Ms.SolveVelocityConstraints_s_P),d=m*this.m_a1,p=m*this.m_a2;e.SelfMulSub(o,u),s-=h*d,i.SelfMulAdd(r,u),n+=a*p}{const _=this.m_upperTranslation-this.m_translation,l=b.DotVV(this.m_axis,b.SubVV(e,i,b.s_t0))+this.m_a1*s-this.m_a2*n;let m=-this.m_axialMass*(l+b2Max(_,0)*t.step.inv_dt);const c=this.m_upperImpulse;this.m_upperImpulse=b2Max(this.m_upperImpulse+m,0),m=this.m_upperImpulse-c;const u=b.MulSV(m,this.m_axis,Ms.SolveVelocityConstraints_s_P),d=m*this.m_a1,p=m*this.m_a2;e.SelfMulAdd(o,u),s+=h*d,i.SelfMulSub(r,u),n-=a*p}}{const t=b.DotVV(this.m_perp,b.SubVV(i,e,b.s_t0))+this.m_s2*n-this.m_s1*s,_=n-s,l=this.m_K.Solve(-t,-_,Ms.SolveVelocityConstraints_s_df);this.m_impulse.SelfAdd(l);const m=b.MulSV(l.x,this.m_perp,Ms.SolveVelocityConstraints_s_P),c=l.x*this.m_s1+l.y,u=l.x*this.m_s2+l.y;e.SelfMulSub(o,m),s-=h*c,i.SelfMulAdd(r,m),n+=a*u}t.velocities[this.m_indexA].w=s,t.velocities[this.m_indexB].w=n}SolvePositionConstraints(t){const e=t.positions[this.m_indexA].c;let s=t.positions[this.m_indexA].a;const i=t.positions[this.m_indexB].c;let n=t.positions[this.m_indexB].a;const o=this.m_qA.SetAngle(s),r=this.m_qB.SetAngle(n),h=this.m_invMassA,_=this.m_invMassB,l=this.m_invIA,m=this.m_invIB,c=w.MulRV(o,this.m_lalcA,this.m_rA),u=w.MulRV(r,this.m_lalcB,this.m_rB),d=b.SubVV(b.AddVV(i,u,b.s_t0),b.AddVV(e,c,b.s_t1),Ms.SolvePositionConstraints_s_d),p=w.MulRV(o,this.m_localXAxisA,this.m_axis),y=b.CrossVV(b.AddVV(d,c,b.s_t0),p),x=b.CrossVV(u,p),A=w.MulRV(o,this.m_localYAxisA,this.m_perp),f=b.CrossVV(b.AddVV(d,c,b.s_t0),A),S=b.CrossVV(u,A);let g=Ms.SolvePositionConstraints_s_impulse;const C=b.DotVV(A,d),V=n-s-this.m_referenceAngle;let B=a(C);const v=a(V);let M=!1,I=0;if(this.m_enableLimit){const t=b.DotVV(p,d);a(this.m_upperTranslation-this.m_lowerTranslation)<.01?(I=t,B=b2Max(B,a(t)),M=!0):t<=this.m_lowerTranslation?(I=b2Min(t-this.m_lowerTranslation,0),B=b2Max(B,this.m_lowerTranslation-t),M=!0):t>=this.m_upperTranslation&&(I=b2Max(t-this.m_upperTranslation,0),B=b2Max(B,t-this.m_upperTranslation),M=!0)}if(M){const t=h+_+l*f*f+m*S*S,e=l*f+m*S,s=l*f*y+m*S*x;let i=l+m;0===i&&(i=1);const n=l*y+m*x,o=h+_+l*y*y+m*x*x,r=this.m_K3;r.ex.SetXYZ(t,e,s),r.ey.SetXYZ(e,i,n),r.ez.SetXYZ(s,n,o),g=r.Solve33(-C,-V,-I,g)}else{const t=h+_+l*f*f+m*S*S,e=l*f+m*S;let s=l+m;0===s&&(s=1);const i=this.m_K2;i.ex.Set(t,e),i.ey.Set(e,s);const n=i.Solve(-C,-V,Ms.SolvePositionConstraints_s_impulse1);g.x=n.x,g.y=n.y,g.z=0}const D=b.AddVV(b.MulSV(g.x,A,b.s_t0),b.MulSV(g.z,p,b.s_t1),Ms.SolvePositionConstraints_s_P),T=g.x*f+g.y+g.z*y,G=g.x*S+g.y+g.z*x;return e.SelfMulSub(h,D),s-=l*T,i.SelfMulAdd(_,D),n+=m*G,t.positions[this.m_indexA].a=s,t.positions[this.m_indexB].a=n,B<=.005&&v<=.03490658503988889}GetAnchorA(t){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA,t)}GetAnchorB(t){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB,t)}GetReactionForce(t,e){return e.x=t*(this.m_impulse.x*this.m_perp.x+(this.m_motorImpulse+this.m_lowerImpulse-this.m_upperImpulse)*this.m_axis.x),e.y=t*(this.m_impulse.y*this.m_perp.y+(this.m_motorImpulse+this.m_lowerImpulse-this.m_upperImpulse)*this.m_axis.y),e}GetReactionTorque(t){return t*this.m_impulse.y}GetLocalAnchorA(){return this.m_localAnchorA}GetLocalAnchorB(){return this.m_localAnchorB}GetLocalAxisA(){return this.m_localXAxisA}GetReferenceAngle(){return this.m_referenceAngle}GetJointTranslation(){const t=this.m_bodyA.GetWorldPoint(this.m_localAnchorA,Ms.GetJointTranslation_s_pA),e=this.m_bodyB.GetWorldPoint(this.m_localAnchorB,Ms.GetJointTranslation_s_pB),s=b.SubVV(e,t,Ms.GetJointTranslation_s_d),i=this.m_bodyA.GetWorldVector(this.m_localXAxisA,Ms.GetJointTranslation_s_axis);return b.DotVV(s,i)}GetJointSpeed(){const t=this.m_bodyA,e=this.m_bodyB;b.SubVV(this.m_localAnchorA,t.m_sweep.localCenter,this.m_lalcA);const s=w.MulRV(t.m_xf.q,this.m_lalcA,this.m_rA);b.SubVV(this.m_localAnchorB,e.m_sweep.localCenter,this.m_lalcB);const i=w.MulRV(e.m_xf.q,this.m_lalcB,this.m_rB),n=b.AddVV(t.m_sweep.c,s,b.s_t0),o=b.AddVV(e.m_sweep.c,i,b.s_t1),r=b.SubVV(o,n,b.s_t2),h=t.GetWorldVector(this.m_localXAxisA,this.m_axis),a=t.m_linearVelocity,_=e.m_linearVelocity,l=t.m_angularVelocity,m=e.m_angularVelocity;return b.DotVV(r,b.CrossSV(l,h,b.s_t0))+b.DotVV(h,b.SubVV(b.AddVCrossSV(_,m,i,b.s_t0),b.AddVCrossSV(a,l,s,b.s_t1),b.s_t0))}IsLimitEnabled(){return this.m_enableLimit}EnableLimit(t){t!==this.m_enableLimit&&(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_enableLimit=t,this.m_lowerImpulse=0,this.m_upperImpulse=0)}GetLowerLimit(){return this.m_lowerTranslation}GetUpperLimit(){return this.m_upperTranslation}SetLimits(t,e){t===this.m_lowerTranslation&&e===this.m_upperTranslation||(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_lowerTranslation=t,this.m_upperTranslation=e,this.m_lowerImpulse=0,this.m_upperImpulse=0)}IsMotorEnabled(){return this.m_enableMotor}EnableMotor(t){t!==this.m_enableMotor&&(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_enableMotor=t)}SetMotorSpeed(t){t!==this.m_motorSpeed&&(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_motorSpeed=t)}GetMotorSpeed(){return this.m_motorSpeed}SetMaxMotorForce(t){t!==this.m_maxMotorForce&&(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_maxMotorForce=t)}GetMaxMotorForce(){return this.m_maxMotorForce}GetMotorForce(t){return t*this.m_motorImpulse}Dump(t){const e=this.m_bodyA.m_islandIndex,s=this.m_bodyB.m_islandIndex;t(" const jd: b2PrismaticJointDef = new b2PrismaticJointDef();\n"),t(" jd.bodyA = bodies[%d];\n",e),t(" jd.bodyB = bodies[%d];\n",s),t(" jd.collideConnected = %s;\n",this.m_collideConnected?"true":"false"),t(" jd.localAnchorA.Set(%.15f, %.15f);\n",this.m_localAnchorA.x,this.m_localAnchorA.y),t(" jd.localAnchorB.Set(%.15f, %.15f);\n",this.m_localAnchorB.x,this.m_localAnchorB.y),t(" jd.localAxisA.Set(%.15f, %.15f);\n",this.m_localXAxisA.x,this.m_localXAxisA.y),t(" jd.referenceAngle = %.15f;\n",this.m_referenceAngle),t(" jd.enableLimit = %s;\n",this.m_enableLimit?"true":"false"),t(" jd.lowerTranslation = %.15f;\n",this.m_lowerTranslation),t(" jd.upperTranslation = %.15f;\n",this.m_upperTranslation),t(" jd.enableMotor = %s;\n",this.m_enableMotor?"true":"false"),t(" jd.motorSpeed = %.15f;\n",this.m_motorSpeed),t(" jd.maxMotorForce = %.15f;\n",this.m_maxMotorForce),t(" joints[%d] = this.m_world.CreateJoint(jd);\n",this.m_index)}Draw(t){const e=this.m_bodyA.GetTransform(),s=this.m_bodyB.GetTransform(),i=g.MulXV(e,this.m_localAnchorA,Ms.Draw_s_pA),n=g.MulXV(s,this.m_localAnchorB,Ms.Draw_s_pB),o=w.MulRV(e.q,this.m_localXAxisA,Ms.Draw_s_axis),r=Ms.Draw_s_c1,h=Ms.Draw_s_c2,a=Ms.Draw_s_c3,_=Ms.Draw_s_c4,l=Ms.Draw_s_c5;if(t.DrawSegment(i,n,l),this.m_enableLimit){const s=b.AddVMulSV(i,this.m_lowerTranslation,o,Ms.Draw_s_lower),n=b.AddVMulSV(i,this.m_upperTranslation,o,Ms.Draw_s_upper),_=w.MulRV(e.q,this.m_localYAxisA,Ms.Draw_s_perp);t.DrawSegment(s,n,r),t.DrawSegment(b.AddVMulSV(s,-.5,_,b.s_t0),b.AddVMulSV(s,.5,_,b.s_t1),h),t.DrawSegment(b.AddVMulSV(n,-.5,_,b.s_t0),b.AddVMulSV(n,.5,_,b.s_t1),a)}else t.DrawSegment(b.AddVMulSV(i,-1,o,b.s_t0),b.AddVMulSV(i,1,o,b.s_t1),r);t.DrawPoint(i,5,r),t.DrawPoint(n,5,_)}}Ms.InitVelocityConstraints_s_d=new b,Ms.InitVelocityConstraints_s_P=new b,Ms.SolveVelocityConstraints_s_P=new b,Ms.SolveVelocityConstraints_s_df=new b,Ms.SolvePositionConstraints_s_d=new b,Ms.SolvePositionConstraints_s_impulse=new A,Ms.SolvePositionConstraints_s_impulse1=new b,Ms.SolvePositionConstraints_s_P=new b,Ms.GetJointTranslation_s_pA=new b,Ms.GetJointTranslation_s_pB=new b,Ms.GetJointTranslation_s_d=new b,Ms.GetJointTranslation_s_axis=new b,Ms.Draw_s_pA=new b,Ms.Draw_s_pB=new b,Ms.Draw_s_axis=new b,Ms.Draw_s_c1=new e(.7,.7,.7),Ms.Draw_s_c2=new e(.3,.9,.3),Ms.Draw_s_c3=new e(.9,.3,.3),Ms.Draw_s_c4=new e(.3,.3,.9),Ms.Draw_s_c5=new e(.4,.4,.4),Ms.Draw_s_lower=new b,Ms.Draw_s_upper=new b,Ms.Draw_s_perp=new b;class Is extends Je{constructor(t){super(t),this.m_groundAnchorA=new b,this.m_groundAnchorB=new b,this.m_lengthA=0,this.m_lengthB=0,this.m_localAnchorA=new b,this.m_localAnchorB=new b,this.m_constant=0,this.m_ratio=0,this.m_impulse=0,this.m_indexA=0,this.m_indexB=0,this.m_uA=new b,this.m_uB=new b,this.m_rA=new b,this.m_rB=new b,this.m_localCenterA=new b,this.m_localCenterB=new b,this.m_invMassA=0,this.m_invMassB=0,this.m_invIA=0,this.m_invIB=0,this.m_mass=0,this.m_qA=new w,this.m_qB=new w,this.m_lalcA=new b,this.m_lalcB=new b,this.m_groundAnchorA.Copy(b2Maybe(t.groundAnchorA,new b(-1,1))),this.m_groundAnchorB.Copy(b2Maybe(t.groundAnchorB,new b(1,0))),this.m_localAnchorA.Copy(b2Maybe(t.localAnchorA,new b(-1,0))),this.m_localAnchorB.Copy(b2Maybe(t.localAnchorB,new b(1,0))),this.m_lengthA=b2Maybe(t.lengthA,0),this.m_lengthB=b2Maybe(t.lengthB,0),this.m_ratio=b2Maybe(t.ratio,1),this.m_constant=b2Maybe(t.lengthA,0)+this.m_ratio*b2Maybe(t.lengthB,0),this.m_impulse=0}InitVelocityConstraints(t){this.m_indexA=this.m_bodyA.m_islandIndex,this.m_indexB=this.m_bodyB.m_islandIndex,this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter),this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter),this.m_invMassA=this.m_bodyA.m_invMass,this.m_invMassB=this.m_bodyB.m_invMass,this.m_invIA=this.m_bodyA.m_invI,this.m_invIB=this.m_bodyB.m_invI;const e=t.positions[this.m_indexA].c,s=t.positions[this.m_indexA].a,i=t.velocities[this.m_indexA].v;let n=t.velocities[this.m_indexA].w;const o=t.positions[this.m_indexB].c,r=t.positions[this.m_indexB].a,h=t.velocities[this.m_indexB].v;let a=t.velocities[this.m_indexB].w;const _=this.m_qA.SetAngle(s),l=this.m_qB.SetAngle(r);b.SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA),w.MulRV(_,this.m_lalcA,this.m_rA),b.SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB),w.MulRV(l,this.m_lalcB,this.m_rB),this.m_uA.Copy(e).SelfAdd(this.m_rA).SelfSub(this.m_groundAnchorA),this.m_uB.Copy(o).SelfAdd(this.m_rB).SelfSub(this.m_groundAnchorB);const m=this.m_uA.Length(),c=this.m_uB.Length();m>.05?this.m_uA.SelfMul(1/m):this.m_uA.SetZero(),c>.05?this.m_uB.SelfMul(1/c):this.m_uB.SetZero();const u=b.CrossVV(this.m_rA,this.m_uA),d=b.CrossVV(this.m_rB,this.m_uB),p=this.m_invMassA+this.m_invIA*u*u,y=this.m_invMassB+this.m_invIB*d*d;if(this.m_mass=p+this.m_ratio*this.m_ratio*y,this.m_mass>0&&(this.m_mass=1/this.m_mass),t.step.warmStarting){this.m_impulse*=t.step.dtRatio;const e=b.MulSV(-this.m_impulse,this.m_uA,Is.InitVelocityConstraints_s_PA),s=b.MulSV(-this.m_ratio*this.m_impulse,this.m_uB,Is.InitVelocityConstraints_s_PB);i.SelfMulAdd(this.m_invMassA,e),n+=this.m_invIA*b.CrossVV(this.m_rA,e),h.SelfMulAdd(this.m_invMassB,s),a+=this.m_invIB*b.CrossVV(this.m_rB,s)}else this.m_impulse=0;t.velocities[this.m_indexA].w=n,t.velocities[this.m_indexB].w=a}SolveVelocityConstraints(t){const e=t.velocities[this.m_indexA].v;let s=t.velocities[this.m_indexA].w;const i=t.velocities[this.m_indexB].v;let n=t.velocities[this.m_indexB].w;const o=b.AddVCrossSV(e,s,this.m_rA,Is.SolveVelocityConstraints_s_vpA),r=b.AddVCrossSV(i,n,this.m_rB,Is.SolveVelocityConstraints_s_vpB),h=-b.DotVV(this.m_uA,o)-this.m_ratio*b.DotVV(this.m_uB,r),a=-this.m_mass*h;this.m_impulse+=a;const _=b.MulSV(-a,this.m_uA,Is.SolveVelocityConstraints_s_PA),l=b.MulSV(-this.m_ratio*a,this.m_uB,Is.SolveVelocityConstraints_s_PB);e.SelfMulAdd(this.m_invMassA,_),s+=this.m_invIA*b.CrossVV(this.m_rA,_),i.SelfMulAdd(this.m_invMassB,l),n+=this.m_invIB*b.CrossVV(this.m_rB,l),t.velocities[this.m_indexA].w=s,t.velocities[this.m_indexB].w=n}SolvePositionConstraints(t){const e=t.positions[this.m_indexA].c;let s=t.positions[this.m_indexA].a;const i=t.positions[this.m_indexB].c;let n=t.positions[this.m_indexB].a;const o=this.m_qA.SetAngle(s),r=this.m_qB.SetAngle(n);b.SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);const h=w.MulRV(o,this.m_lalcA,this.m_rA);b.SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);const _=w.MulRV(r,this.m_lalcB,this.m_rB),l=this.m_uA.Copy(e).SelfAdd(h).SelfSub(this.m_groundAnchorA),m=this.m_uB.Copy(i).SelfAdd(_).SelfSub(this.m_groundAnchorB),c=l.Length(),u=m.Length();c>.05?l.SelfMul(1/c):l.SetZero(),u>.05?m.SelfMul(1/u):m.SetZero();const d=b.CrossVV(h,l),p=b.CrossVV(_,m),y=this.m_invMassA+this.m_invIA*d*d,x=this.m_invMassB+this.m_invIB*p*p;let A=y+this.m_ratio*this.m_ratio*x;A>0&&(A=1/A);const f=this.m_constant-c-this.m_ratio*u,S=a(f),g=-A*f,C=b.MulSV(-g,l,Is.SolvePositionConstraints_s_PA),V=b.MulSV(-this.m_ratio*g,m,Is.SolvePositionConstraints_s_PB);return e.SelfMulAdd(this.m_invMassA,C),s+=this.m_invIA*b.CrossVV(h,C),i.SelfMulAdd(this.m_invMassB,V),n+=this.m_invIB*b.CrossVV(_,V),t.positions[this.m_indexA].a=s,t.positions[this.m_indexB].a=n,S<.005}GetAnchorA(t){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA,t)}GetAnchorB(t){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB,t)}GetReactionForce(t,e){return e.x=t*this.m_impulse*this.m_uB.x,e.y=t*this.m_impulse*this.m_uB.y,e}GetReactionTorque(t){return 0}GetGroundAnchorA(){return this.m_groundAnchorA}GetGroundAnchorB(){return this.m_groundAnchorB}GetLengthA(){return this.m_lengthA}GetLengthB(){return this.m_lengthB}GetRatio(){return this.m_ratio}GetCurrentLengthA(){const t=this.m_bodyA.GetWorldPoint(this.m_localAnchorA,Is.GetCurrentLengthA_s_p),e=this.m_groundAnchorA;return b.DistanceVV(t,e)}GetCurrentLengthB(){const t=this.m_bodyB.GetWorldPoint(this.m_localAnchorB,Is.GetCurrentLengthB_s_p),e=this.m_groundAnchorB;return b.DistanceVV(t,e)}Dump(t){const e=this.m_bodyA.m_islandIndex,s=this.m_bodyB.m_islandIndex;t(" const jd: b2PulleyJointDef = new b2PulleyJointDef();\n"),t(" jd.bodyA = bodies[%d];\n",e),t(" jd.bodyB = bodies[%d];\n",s),t(" jd.collideConnected = %s;\n",this.m_collideConnected?"true":"false"),t(" jd.groundAnchorA.Set(%.15f, %.15f);\n",this.m_groundAnchorA.x,this.m_groundAnchorA.y),t(" jd.groundAnchorB.Set(%.15f, %.15f);\n",this.m_groundAnchorB.x,this.m_groundAnchorB.y),t(" jd.localAnchorA.Set(%.15f, %.15f);\n",this.m_localAnchorA.x,this.m_localAnchorA.y),t(" jd.localAnchorB.Set(%.15f, %.15f);\n",this.m_localAnchorB.x,this.m_localAnchorB.y),t(" jd.lengthA = %.15f;\n",this.m_lengthA),t(" jd.lengthB = %.15f;\n",this.m_lengthB),t(" jd.ratio = %.15f;\n",this.m_ratio),t(" joints[%d] = this.m_world.CreateJoint(jd);\n",this.m_index)}ShiftOrigin(t){this.m_groundAnchorA.SelfSub(t),this.m_groundAnchorB.SelfSub(t)}}Is.InitVelocityConstraints_s_PA=new b,Is.InitVelocityConstraints_s_PB=new b,Is.SolveVelocityConstraints_s_vpA=new b,Is.SolveVelocityConstraints_s_vpB=new b,Is.SolveVelocityConstraints_s_PA=new b,Is.SolveVelocityConstraints_s_PB=new b,Is.SolvePositionConstraints_s_PA=new b,Is.SolvePositionConstraints_s_PB=new b,Is.GetCurrentLengthA_s_p=new b,Is.GetCurrentLengthB_s_p=new b;class Ds extends Je{constructor(t){super(t),this.m_localAnchorA=new b,this.m_localAnchorB=new b,this.m_impulse=new b,this.m_motorImpulse=0,this.m_lowerImpulse=0,this.m_upperImpulse=0,this.m_enableMotor=!1,this.m_maxMotorTorque=0,this.m_motorSpeed=0,this.m_enableLimit=!1,this.m_referenceAngle=0,this.m_lowerAngle=0,this.m_upperAngle=0,this.m_indexA=0,this.m_indexB=0,this.m_rA=new b,this.m_rB=new b,this.m_localCenterA=new b,this.m_localCenterB=new b,this.m_invMassA=0,this.m_invMassB=0,this.m_invIA=0,this.m_invIB=0,this.m_K=new f,this.m_angle=0,this.m_axialMass=0,this.m_qA=new w,this.m_qB=new w,this.m_lalcA=new b,this.m_lalcB=new b,this.m_localAnchorA.Copy(b2Maybe(t.localAnchorA,b.ZERO)),this.m_localAnchorB.Copy(b2Maybe(t.localAnchorB,b.ZERO)),this.m_referenceAngle=b2Maybe(t.referenceAngle,0),this.m_impulse.SetZero(),this.m_motorImpulse=0,this.m_lowerAngle=b2Maybe(t.lowerAngle,0),this.m_upperAngle=b2Maybe(t.upperAngle,0),this.m_maxMotorTorque=b2Maybe(t.maxMotorTorque,0),this.m_motorSpeed=b2Maybe(t.motorSpeed,0),this.m_enableLimit=b2Maybe(t.enableLimit,!1),this.m_enableMotor=b2Maybe(t.enableMotor,!1)}InitVelocityConstraints(t){this.m_indexA=this.m_bodyA.m_islandIndex,this.m_indexB=this.m_bodyB.m_islandIndex,this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter),this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter),this.m_invMassA=this.m_bodyA.m_invMass,this.m_invMassB=this.m_bodyB.m_invMass,this.m_invIA=this.m_bodyA.m_invI,this.m_invIB=this.m_bodyB.m_invI;const e=t.positions[this.m_indexA].a,s=t.velocities[this.m_indexA].v;let i=t.velocities[this.m_indexA].w;const n=t.positions[this.m_indexB].a,o=t.velocities[this.m_indexB].v;let r=t.velocities[this.m_indexB].w;const h=this.m_qA.SetAngle(e),a=this.m_qB.SetAngle(n);b.SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA),w.MulRV(h,this.m_lalcA,this.m_rA),b.SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB),w.MulRV(a,this.m_lalcB,this.m_rB);const _=this.m_invMassA,l=this.m_invMassB,m=this.m_invIA,c=this.m_invIB;let u;if(this.m_K.ex.x=_+l+this.m_rA.y*this.m_rA.y*m+this.m_rB.y*this.m_rB.y*c,this.m_K.ey.x=-this.m_rA.y*this.m_rA.x*m-this.m_rB.y*this.m_rB.x*c,this.m_K.ex.y=this.m_K.ey.x,this.m_K.ey.y=_+l+this.m_rA.x*this.m_rA.x*m+this.m_rB.x*this.m_rB.x*c,this.m_axialMass=m+c,this.m_axialMass>0?(this.m_axialMass=1/this.m_axialMass,u=!1):u=!0,this.m_angle=n-e-this.m_referenceAngle,(!1===this.m_enableLimit||u)&&(this.m_lowerImpulse=0,this.m_upperImpulse=0),(!1===this.m_enableMotor||u)&&(this.m_motorImpulse=0),t.step.warmStarting){this.m_impulse.SelfMul(t.step.dtRatio),this.m_motorImpulse*=t.step.dtRatio,this.m_lowerImpulse*=t.step.dtRatio,this.m_upperImpulse*=t.step.dtRatio;const e=this.m_motorImpulse+this.m_lowerImpulse-this.m_upperImpulse,n=Ds.InitVelocityConstraints_s_P.Set(this.m_impulse.x,this.m_impulse.y);s.SelfMulSub(_,n),i-=m*(b.CrossVV(this.m_rA,n)+e),o.SelfMulAdd(l,n),r+=c*(b.CrossVV(this.m_rB,n)+e)}else this.m_impulse.SetZero(),this.m_motorImpulse=0,this.m_lowerImpulse=0,this.m_upperImpulse=0;t.velocities[this.m_indexA].w=i,t.velocities[this.m_indexB].w=r}SolveVelocityConstraints(t){const e=t.velocities[this.m_indexA].v;let s=t.velocities[this.m_indexA].w;const i=t.velocities[this.m_indexB].v;let n=t.velocities[this.m_indexB].w;const o=this.m_invMassA,r=this.m_invMassB,h=this.m_invIA,a=this.m_invIB,_=h+a===0;if(this.m_enableMotor&&!_){const e=n-s-this.m_motorSpeed;let i=-this.m_axialMass*e;const o=this.m_motorImpulse,r=t.step.dt*this.m_maxMotorTorque;this.m_motorImpulse=b2Clamp(this.m_motorImpulse+i,-r,r),i=this.m_motorImpulse-o,s-=h*i,n+=a*i}if(this.m_enableLimit&&!_){{const e=this.m_angle-this.m_lowerAngle,i=n-s;let o=-this.m_axialMass*(i+b2Max(e,0)*t.step.inv_dt);const r=this.m_lowerImpulse;this.m_lowerImpulse=b2Max(this.m_lowerImpulse+o,0),o=this.m_lowerImpulse-r,s-=h*o,n+=a*o}{const e=this.m_upperAngle-this.m_angle,i=s-n;let o=-this.m_axialMass*(i+b2Max(e,0)*t.step.inv_dt);const r=this.m_upperImpulse;this.m_upperImpulse=b2Max(this.m_upperImpulse+o,0),o=this.m_upperImpulse-r,s+=h*o,n-=a*o}}{const t=b.SubVV(b.AddVCrossSV(i,n,this.m_rB,b.s_t0),b.AddVCrossSV(e,s,this.m_rA,b.s_t1),Ds.SolveVelocityConstraints_s_Cdot_v2),_=this.m_K.Solve(-t.x,-t.y,Ds.SolveVelocityConstraints_s_impulse_v2);this.m_impulse.x+=_.x,this.m_impulse.y+=_.y,e.SelfMulSub(o,_),s-=h*b.CrossVV(this.m_rA,_),i.SelfMulAdd(r,_),n+=a*b.CrossVV(this.m_rB,_)}t.velocities[this.m_indexA].w=s,t.velocities[this.m_indexB].w=n}SolvePositionConstraints(t){const e=t.positions[this.m_indexA].c;let s=t.positions[this.m_indexA].a;const i=t.positions[this.m_indexB].c;let n=t.positions[this.m_indexB].a;const o=this.m_qA.SetAngle(s),r=this.m_qB.SetAngle(n);let h=0,_=0;const l=this.m_invIA+this.m_invIB===0;if(this.m_enableLimit&&!l){const t=n-s-this.m_referenceAngle;let e=0;a(this.m_upperAngle-this.m_lowerAngle)<.06981317007977778?e=b2Clamp(t-this.m_lowerAngle,-.13962634015955555,.13962634015955555):t<=this.m_lowerAngle?e=b2Clamp(t-this.m_lowerAngle+.03490658503988889,-.13962634015955555,0):t>=this.m_upperAngle&&(e=b2Clamp(t-this.m_upperAngle-.03490658503988889,0,.13962634015955555));const i=-this.m_axialMass*e;s-=this.m_invIA*i,n+=this.m_invIB*i,h=a(e)}{o.SetAngle(s),r.SetAngle(n),b.SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);const t=w.MulRV(o,this.m_lalcA,this.m_rA);b.SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);const h=w.MulRV(r,this.m_lalcB,this.m_rB),a=b.SubVV(b.AddVV(i,h,b.s_t0),b.AddVV(e,t,b.s_t1),Ds.SolvePositionConstraints_s_C_v2);_=a.Length();const l=this.m_invMassA,m=this.m_invMassB,c=this.m_invIA,u=this.m_invIB,d=this.m_K;d.ex.x=l+m+c*t.y*t.y+u*h.y*h.y,d.ex.y=-c*t.x*t.y-u*h.x*h.y,d.ey.x=d.ex.y,d.ey.y=l+m+c*t.x*t.x+u*h.x*h.x;const p=d.Solve(a.x,a.y,Ds.SolvePositionConstraints_s_impulse).SelfNeg();e.SelfMulSub(l,p),s-=c*b.CrossVV(t,p),i.SelfMulAdd(m,p),n+=u*b.CrossVV(h,p)}return t.positions[this.m_indexA].a=s,t.positions[this.m_indexB].a=n,_<=.005&&h<=.03490658503988889}GetAnchorA(t){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA,t)}GetAnchorB(t){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB,t)}GetReactionForce(t,e){return e.x=t*this.m_impulse.x,e.y=t*this.m_impulse.y,e}GetReactionTorque(t){return t*(this.m_lowerImpulse-this.m_upperImpulse)}GetLocalAnchorA(){return this.m_localAnchorA}GetLocalAnchorB(){return this.m_localAnchorB}GetReferenceAngle(){return this.m_referenceAngle}GetJointAngle(){return this.m_bodyB.m_sweep.a-this.m_bodyA.m_sweep.a-this.m_referenceAngle}GetJointSpeed(){return this.m_bodyB.m_angularVelocity-this.m_bodyA.m_angularVelocity}IsMotorEnabled(){return this.m_enableMotor}EnableMotor(t){t!==this.m_enableMotor&&(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_enableMotor=t)}GetMotorTorque(t){return t*this.m_motorImpulse}GetMotorSpeed(){return this.m_motorSpeed}SetMaxMotorTorque(t){t!==this.m_maxMotorTorque&&(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_maxMotorTorque=t)}GetMaxMotorTorque(){return this.m_maxMotorTorque}IsLimitEnabled(){return this.m_enableLimit}EnableLimit(t){t!==this.m_enableLimit&&(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_enableLimit=t,this.m_lowerImpulse=0,this.m_upperImpulse=0)}GetLowerLimit(){return this.m_lowerAngle}GetUpperLimit(){return this.m_upperAngle}SetLimits(t,e){t===this.m_lowerAngle&&e===this.m_upperAngle||(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_lowerImpulse=0,this.m_upperImpulse=0,this.m_lowerAngle=t,this.m_upperAngle=e)}SetMotorSpeed(t){t!==this.m_motorSpeed&&(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_motorSpeed=t)}Dump(t){const e=this.m_bodyA.m_islandIndex,s=this.m_bodyB.m_islandIndex;t(" const jd: b2RevoluteJointDef = new b2RevoluteJointDef();\n"),t(" jd.bodyA = bodies[%d];\n",e),t(" jd.bodyB = bodies[%d];\n",s),t(" jd.collideConnected = %s;\n",this.m_collideConnected?"true":"false"),t(" jd.localAnchorA.Set(%.15f, %.15f);\n",this.m_localAnchorA.x,this.m_localAnchorA.y),t(" jd.localAnchorB.Set(%.15f, %.15f);\n",this.m_localAnchorB.x,this.m_localAnchorB.y),t(" jd.referenceAngle = %.15f;\n",this.m_referenceAngle),t(" jd.enableLimit = %s;\n",this.m_enableLimit?"true":"false"),t(" jd.lowerAngle = %.15f;\n",this.m_lowerAngle),t(" jd.upperAngle = %.15f;\n",this.m_upperAngle),t(" jd.enableMotor = %s;\n",this.m_enableMotor?"true":"false"),t(" jd.motorSpeed = %.15f;\n",this.m_motorSpeed),t(" jd.maxMotorTorque = %.15f;\n",this.m_maxMotorTorque),t(" joints[%d] = this.m_world.CreateJoint(jd);\n",this.m_index)}Draw(t){const e=this.m_bodyA.GetTransform(),s=this.m_bodyB.GetTransform(),i=g.MulXV(e,this.m_localAnchorA,Ds.Draw_s_pA),n=g.MulXV(s,this.m_localAnchorB,Ds.Draw_s_pB),o=Ds.Draw_s_c1,r=Ds.Draw_s_c2,h=Ds.Draw_s_c3,a=Ds.Draw_s_c4,_=Ds.Draw_s_c5;t.DrawPoint(i,5,a),t.DrawPoint(n,5,_);const l=this.m_bodyA.GetAngle(),m=this.m_bodyB.GetAngle()-l-this.m_referenceAngle,c=.5,u=Ds.Draw_s_r.Set(c*Math.cos(m),c*Math.sin(m));if(t.DrawSegment(n,b.AddVV(n,u,b.s_t0),o),t.DrawCircle(n,c,o),this.m_enableLimit){const e=Ds.Draw_s_rlo.Set(c*Math.cos(this.m_lowerAngle),c*Math.sin(this.m_lowerAngle)),s=Ds.Draw_s_rhi.Set(c*Math.cos(this.m_upperAngle),c*Math.sin(this.m_upperAngle));t.DrawSegment(n,b.AddVV(n,e,b.s_t0),r),t.DrawSegment(n,b.AddVV(n,s,b.s_t0),h)}const d=Ds.Draw_s_color_;t.DrawSegment(e.p,i,d),t.DrawSegment(i,n,d),t.DrawSegment(s.p,n,d)}}Ds.InitVelocityConstraints_s_P=new b,Ds.SolveVelocityConstraints_s_Cdot_v2=new b,Ds.SolveVelocityConstraints_s_impulse_v2=new b,Ds.SolvePositionConstraints_s_C_v2=new b,Ds.SolvePositionConstraints_s_impulse=new b,Ds.Draw_s_pA=new b,Ds.Draw_s_pB=new b,Ds.Draw_s_c1=new e(.7,.7,.7),Ds.Draw_s_c2=new e(.3,.9,.3),Ds.Draw_s_c3=new e(.9,.3,.3),Ds.Draw_s_c4=new e(.3,.3,.9),Ds.Draw_s_c5=new e(.4,.4,.4),Ds.Draw_s_color_=new e(.5,.8,.8),Ds.Draw_s_r=new b,Ds.Draw_s_rlo=new b,Ds.Draw_s_rhi=new b;class Ts extends Je{constructor(t){super(t),this.m_stiffness=0,this.m_damping=0,this.m_bias=0,this.m_localAnchorA=new b,this.m_localAnchorB=new b,this.m_referenceAngle=0,this.m_gamma=0,this.m_impulse=new A(0,0,0),this.m_indexA=0,this.m_indexB=0,this.m_rA=new b,this.m_rB=new b,this.m_localCenterA=new b,this.m_localCenterB=new b,this.m_invMassA=0,this.m_invMassB=0,this.m_invIA=0,this.m_invIB=0,this.m_mass=new S,this.m_qA=new w,this.m_qB=new w,this.m_lalcA=new b,this.m_lalcB=new b,this.m_K=new S,this.m_stiffness=b2Maybe(t.stiffness,0),this.m_damping=b2Maybe(t.damping,0),this.m_localAnchorA.Copy(b2Maybe(t.localAnchorA,b.ZERO)),this.m_localAnchorB.Copy(b2Maybe(t.localAnchorB,b.ZERO)),this.m_referenceAngle=b2Maybe(t.referenceAngle,0),this.m_impulse.SetZero()}InitVelocityConstraints(t){this.m_indexA=this.m_bodyA.m_islandIndex,this.m_indexB=this.m_bodyB.m_islandIndex,this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter),this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter),this.m_invMassA=this.m_bodyA.m_invMass,this.m_invMassB=this.m_bodyB.m_invMass,this.m_invIA=this.m_bodyA.m_invI,this.m_invIB=this.m_bodyB.m_invI;const e=t.positions[this.m_indexA].a,s=t.velocities[this.m_indexA].v;let i=t.velocities[this.m_indexA].w;const n=t.positions[this.m_indexB].a,o=t.velocities[this.m_indexB].v;let r=t.velocities[this.m_indexB].w;const h=this.m_qA.SetAngle(e),a=this.m_qB.SetAngle(n);b.SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA),w.MulRV(h,this.m_lalcA,this.m_rA),b.SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB),w.MulRV(a,this.m_lalcB,this.m_rB);const _=this.m_invMassA,l=this.m_invMassB,m=this.m_invIA,c=this.m_invIB,u=this.m_K;if(u.ex.x=_+l+this.m_rA.y*this.m_rA.y*m+this.m_rB.y*this.m_rB.y*c,u.ey.x=-this.m_rA.y*this.m_rA.x*m-this.m_rB.y*this.m_rB.x*c,u.ez.x=-this.m_rA.y*m-this.m_rB.y*c,u.ex.y=u.ey.x,u.ey.y=_+l+this.m_rA.x*this.m_rA.x*m+this.m_rB.x*this.m_rB.x*c,u.ez.y=this.m_rA.x*m+this.m_rB.x*c,u.ex.z=u.ez.x,u.ey.z=u.ez.y,u.ez.z=m+c,this.m_stiffness>0){u.GetInverse22(this.m_mass);let s=m+c;const i=n-e-this.m_referenceAngle,o=this.m_damping,r=this.m_stiffness,h=t.step.dt;this.m_gamma=h*(o+h*r),this.m_gamma=0!==this.m_gamma?1/this.m_gamma:0,this.m_bias=i*h*r*this.m_gamma,s+=this.m_gamma,this.m_mass.ez.z=0!==s?1/s:0}else u.GetSymInverse33(this.m_mass),this.m_gamma=0,this.m_bias=0;if(t.step.warmStarting){this.m_impulse.SelfMul(t.step.dtRatio);const e=Ts.InitVelocityConstraints_s_P.Set(this.m_impulse.x,this.m_impulse.y);s.SelfMulSub(_,e),i-=m*(b.CrossVV(this.m_rA,e)+this.m_impulse.z),o.SelfMulAdd(l,e),r+=c*(b.CrossVV(this.m_rB,e)+this.m_impulse.z)}else this.m_impulse.SetZero();t.velocities[this.m_indexA].w=i,t.velocities[this.m_indexB].w=r}SolveVelocityConstraints(t){const e=t.velocities[this.m_indexA].v;let s=t.velocities[this.m_indexA].w;const i=t.velocities[this.m_indexB].v;let n=t.velocities[this.m_indexB].w;const o=this.m_invMassA,r=this.m_invMassB,h=this.m_invIA,a=this.m_invIB;if(this.m_stiffness>0){const t=n-s,_=-this.m_mass.ez.z*(t+this.m_bias+this.m_gamma*this.m_impulse.z);this.m_impulse.z+=_,s-=h*_,n+=a*_;const l=b.SubVV(b.AddVCrossSV(i,n,this.m_rB,b.s_t0),b.AddVCrossSV(e,s,this.m_rA,b.s_t1),Ts.SolveVelocityConstraints_s_Cdot1),m=S.MulM33XY(this.m_mass,l.x,l.y,Ts.SolveVelocityConstraints_s_impulse1).SelfNeg();this.m_impulse.x+=m.x,this.m_impulse.y+=m.y;const c=m;e.SelfMulSub(o,c),s-=h*b.CrossVV(this.m_rA,c),i.SelfMulAdd(r,c),n+=a*b.CrossVV(this.m_rB,c)}else{const t=b.SubVV(b.AddVCrossSV(i,n,this.m_rB,b.s_t0),b.AddVCrossSV(e,s,this.m_rA,b.s_t1),Ts.SolveVelocityConstraints_s_Cdot1),_=n-s,l=S.MulM33XYZ(this.m_mass,t.x,t.y,_,Ts.SolveVelocityConstraints_s_impulse).SelfNeg();this.m_impulse.SelfAdd(l);const m=Ts.SolveVelocityConstraints_s_P.Set(l.x,l.y);e.SelfMulSub(o,m),s-=h*(b.CrossVV(this.m_rA,m)+l.z),i.SelfMulAdd(r,m),n+=a*(b.CrossVV(this.m_rB,m)+l.z)}t.velocities[this.m_indexA].w=s,t.velocities[this.m_indexB].w=n}SolvePositionConstraints(t){const e=t.positions[this.m_indexA].c;let s=t.positions[this.m_indexA].a;const i=t.positions[this.m_indexB].c;let n=t.positions[this.m_indexB].a;const o=this.m_qA.SetAngle(s),r=this.m_qB.SetAngle(n),h=this.m_invMassA,_=this.m_invMassB,l=this.m_invIA,m=this.m_invIB;b.SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);const c=w.MulRV(o,this.m_lalcA,this.m_rA);b.SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);const u=w.MulRV(r,this.m_lalcB,this.m_rB);let d,p;const y=this.m_K;if(y.ex.x=h+_+c.y*c.y*l+u.y*u.y*m,y.ey.x=-c.y*c.x*l-u.y*u.x*m,y.ez.x=-c.y*l-u.y*m,y.ex.y=y.ey.x,y.ey.y=h+_+c.x*c.x*l+u.x*u.x*m,y.ez.y=c.x*l+u.x*m,y.ex.z=y.ez.x,y.ey.z=y.ez.y,y.ez.z=l+m,this.m_stiffness>0){const t=b.SubVV(b.AddVV(i,u,b.s_t0),b.AddVV(e,c,b.s_t1),Ts.SolvePositionConstraints_s_C1);d=t.Length(),p=0;const o=y.Solve22(t.x,t.y,Ts.SolvePositionConstraints_s_P).SelfNeg();e.SelfMulSub(h,o),s-=l*b.CrossVV(c,o),i.SelfMulAdd(_,o),n+=m*b.CrossVV(u,o)}else{const t=b.SubVV(b.AddVV(i,u,b.s_t0),b.AddVV(e,c,b.s_t1),Ts.SolvePositionConstraints_s_C1),o=n-s-this.m_referenceAngle;d=t.Length(),p=a(o);const r=y.Solve33(t.x,t.y,o,Ts.SolvePositionConstraints_s_impulse).SelfNeg(),x=Ts.SolvePositionConstraints_s_P.Set(r.x,r.y);e.SelfMulSub(h,x),s-=l*(b.CrossVV(this.m_rA,x)+r.z),i.SelfMulAdd(_,x),n+=m*(b.CrossVV(this.m_rB,x)+r.z)}return t.positions[this.m_indexA].a=s,t.positions[this.m_indexB].a=n,d<=.005&&p<=.03490658503988889}GetAnchorA(t){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA,t)}GetAnchorB(t){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB,t)}GetReactionForce(t,e){return e.x=t*this.m_impulse.x,e.y=t*this.m_impulse.y,e}GetReactionTorque(t){return t*this.m_impulse.z}GetLocalAnchorA(){return this.m_localAnchorA}GetLocalAnchorB(){return this.m_localAnchorB}GetReferenceAngle(){return this.m_referenceAngle}SetStiffness(t){this.m_stiffness=t}GetStiffness(){return this.m_stiffness}SetDamping(t){this.m_damping=t}GetDamping(){return this.m_damping}Dump(t){const e=this.m_bodyA.m_islandIndex,s=this.m_bodyB.m_islandIndex;t(" const jd: b2WeldJointDef = new b2WeldJointDef();\n"),t(" jd.bodyA = bodies[%d];\n",e),t(" jd.bodyB = bodies[%d];\n",s),t(" jd.collideConnected = %s;\n",this.m_collideConnected?"true":"false"),t(" jd.localAnchorA.Set(%.15f, %.15f);\n",this.m_localAnchorA.x,this.m_localAnchorA.y),t(" jd.localAnchorB.Set(%.15f, %.15f);\n",this.m_localAnchorB.x,this.m_localAnchorB.y),t(" jd.referenceAngle = %.15f;\n",this.m_referenceAngle),t(" jd.stiffness = %.15f;\n",this.m_stiffness),t(" jd.damping = %.15f;\n",this.m_damping),t(" joints[%d] = this.m_world.CreateJoint(jd);\n",this.m_index)}}Ts.InitVelocityConstraints_s_P=new b,Ts.SolveVelocityConstraints_s_Cdot1=new b,Ts.SolveVelocityConstraints_s_impulse1=new b,Ts.SolveVelocityConstraints_s_impulse=new A,Ts.SolveVelocityConstraints_s_P=new b,Ts.SolvePositionConstraints_s_C1=new b,Ts.SolvePositionConstraints_s_P=new b,Ts.SolvePositionConstraints_s_impulse=new A;class Gs extends Je{constructor(t){super(t),this.m_localAnchorA=new b,this.m_localAnchorB=new b,this.m_localXAxisA=new b,this.m_localYAxisA=new b,this.m_impulse=0,this.m_motorImpulse=0,this.m_springImpulse=0,this.m_lowerImpulse=0,this.m_upperImpulse=0,this.m_translation=0,this.m_lowerTranslation=0,this.m_upperTranslation=0,this.m_maxMotorTorque=0,this.m_motorSpeed=0,this.m_enableLimit=!1,this.m_enableMotor=!1,this.m_stiffness=0,this.m_damping=0,this.m_indexA=0,this.m_indexB=0,this.m_localCenterA=new b,this.m_localCenterB=new b,this.m_invMassA=0,this.m_invMassB=0,this.m_invIA=0,this.m_invIB=0,this.m_ax=new b,this.m_ay=new b,this.m_sAx=0,this.m_sBx=0,this.m_sAy=0,this.m_sBy=0,this.m_mass=0,this.m_motorMass=0,this.m_axialMass=0,this.m_springMass=0,this.m_bias=0,this.m_gamma=0,this.m_qA=new w,this.m_qB=new w,this.m_lalcA=new b,this.m_lalcB=new b,this.m_rA=new b,this.m_rB=new b,this.m_localAnchorA.Copy(b2Maybe(t.localAnchorA,b.ZERO)),this.m_localAnchorB.Copy(b2Maybe(t.localAnchorB,b.ZERO)),this.m_localXAxisA.Copy(b2Maybe(t.localAxisA,b.UNITX)),b.CrossOneV(this.m_localXAxisA,this.m_localYAxisA),this.m_lowerTranslation=b2Maybe(t.lowerTranslation,0),this.m_upperTranslation=b2Maybe(t.upperTranslation,0),this.m_enableLimit=b2Maybe(t.enableLimit,!1),this.m_maxMotorTorque=b2Maybe(t.maxMotorTorque,0),this.m_motorSpeed=b2Maybe(t.motorSpeed,0),this.m_enableMotor=b2Maybe(t.enableMotor,!1),this.m_ax.SetZero(),this.m_ay.SetZero(),this.m_stiffness=b2Maybe(t.stiffness,0),this.m_damping=b2Maybe(t.damping,0)}GetMotorSpeed(){return this.m_motorSpeed}GetMaxMotorTorque(){return this.m_maxMotorTorque}SetStiffness(t){this.m_stiffness=t}GetStiffness(){return this.m_stiffness}SetDamping(t){this.m_damping=t}GetDamping(){return this.m_damping}InitVelocityConstraints(t){this.m_indexA=this.m_bodyA.m_islandIndex,this.m_indexB=this.m_bodyB.m_islandIndex,this.m_localCenterA.Copy(this.m_bodyA.m_sweep.localCenter),this.m_localCenterB.Copy(this.m_bodyB.m_sweep.localCenter),this.m_invMassA=this.m_bodyA.m_invMass,this.m_invMassB=this.m_bodyB.m_invMass,this.m_invIA=this.m_bodyA.m_invI,this.m_invIB=this.m_bodyB.m_invI;const e=this.m_invMassA,s=this.m_invMassB,i=this.m_invIA,n=this.m_invIB,o=t.positions[this.m_indexA].c,r=t.positions[this.m_indexA].a,h=t.velocities[this.m_indexA].v;let a=t.velocities[this.m_indexA].w;const _=t.positions[this.m_indexB].c,l=t.positions[this.m_indexB].a,m=t.velocities[this.m_indexB].v;let c=t.velocities[this.m_indexB].w;const u=this.m_qA.SetAngle(r),d=this.m_qB.SetAngle(l);b.SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);const p=w.MulRV(u,this.m_lalcA,this.m_rA);b.SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);const y=w.MulRV(d,this.m_lalcB,this.m_rB),x=b.SubVV(b.AddVV(_,y,b.s_t0),b.AddVV(o,p,b.s_t1),Gs.InitVelocityConstraints_s_d);w.MulRV(u,this.m_localYAxisA,this.m_ay),this.m_sAy=b.CrossVV(b.AddVV(x,p,b.s_t0),this.m_ay),this.m_sBy=b.CrossVV(y,this.m_ay),this.m_mass=e+s+i*this.m_sAy*this.m_sAy+n*this.m_sBy*this.m_sBy,this.m_mass>0&&(this.m_mass=1/this.m_mass),w.MulRV(u,this.m_localXAxisA,this.m_ax),this.m_sAx=b.CrossVV(b.AddVV(x,p,b.s_t0),this.m_ax),this.m_sBx=b.CrossVV(y,this.m_ax);const A=e+s+i*this.m_sAx*this.m_sAx+n*this.m_sBx*this.m_sBx;if(this.m_axialMass=A>0?1/A:0,this.m_springMass=0,this.m_bias=0,this.m_gamma=0,this.m_stiffness>0&&A>0){this.m_springMass=1/A;const e=b.DotVV(x,this.m_ax),s=t.step.dt;this.m_gamma=s*(this.m_damping+s*this.m_stiffness),this.m_gamma>0&&(this.m_gamma=1/this.m_gamma),this.m_bias=e*s*this.m_stiffness*this.m_gamma,this.m_springMass=A+this.m_gamma,this.m_springMass>0&&(this.m_springMass=1/this.m_springMass)}else this.m_springImpulse=0;if(this.m_enableLimit?this.m_translation=b.DotVV(this.m_ax,x):(this.m_lowerImpulse=0,this.m_upperImpulse=0),this.m_enableMotor?(this.m_motorMass=i+n,this.m_motorMass>0&&(this.m_motorMass=1/this.m_motorMass)):(this.m_motorMass=0,this.m_motorImpulse=0),t.step.warmStarting){this.m_impulse*=t.step.dtRatio,this.m_springImpulse*=t.step.dtRatio,this.m_motorImpulse*=t.step.dtRatio;const e=this.m_springImpulse+this.m_lowerImpulse-this.m_upperImpulse,s=b.AddVV(b.MulSV(this.m_impulse,this.m_ay,b.s_t0),b.MulSV(e,this.m_ax,b.s_t1),Gs.InitVelocityConstraints_s_P),i=this.m_impulse*this.m_sAy+e*this.m_sAx+this.m_motorImpulse,n=this.m_impulse*this.m_sBy+e*this.m_sBx+this.m_motorImpulse;h.SelfMulSub(this.m_invMassA,s),a-=this.m_invIA*i,m.SelfMulAdd(this.m_invMassB,s),c+=this.m_invIB*n}else this.m_impulse=0,this.m_springImpulse=0,this.m_motorImpulse=0,this.m_lowerImpulse=0,this.m_upperImpulse=0;t.velocities[this.m_indexA].w=a,t.velocities[this.m_indexB].w=c}SolveVelocityConstraints(t){const e=this.m_invMassA,s=this.m_invMassB,i=this.m_invIA,n=this.m_invIB,o=t.velocities[this.m_indexA].v;let r=t.velocities[this.m_indexA].w;const h=t.velocities[this.m_indexB].v;let a=t.velocities[this.m_indexB].w;{const t=b.DotVV(this.m_ax,b.SubVV(h,o,b.s_t0))+this.m_sBx*a-this.m_sAx*r,_=-this.m_springMass*(t+this.m_bias+this.m_gamma*this.m_springImpulse);this.m_springImpulse+=_;const l=b.MulSV(_,this.m_ax,Gs.SolveVelocityConstraints_s_P),m=_*this.m_sAx,c=_*this.m_sBx;o.SelfMulSub(e,l),r-=i*m,h.SelfMulAdd(s,l),a+=n*c}{const e=a-r-this.m_motorSpeed;let s=-this.m_motorMass*e;const o=this.m_motorImpulse,h=t.step.dt*this.m_maxMotorTorque;this.m_motorImpulse=b2Clamp(this.m_motorImpulse+s,-h,h),s=this.m_motorImpulse-o,r-=i*s,a+=n*s}if(this.m_enableLimit){{const _=this.m_translation-this.m_lowerTranslation,l=b.DotVV(this.m_ax,b.SubVV(h,o,b.s_t0))+this.m_sBx*a-this.m_sAx*r;let m=-this.m_axialMass*(l+b2Max(_,0)*t.step.inv_dt);const c=this.m_lowerImpulse;this.m_lowerImpulse=b2Max(this.m_lowerImpulse+m,0),m=this.m_lowerImpulse-c;const u=b.MulSV(m,this.m_ax,Gs.SolveVelocityConstraints_s_P),d=m*this.m_sAx,p=m*this.m_sBx;o.SelfMulSub(e,u),r-=i*d,h.SelfMulAdd(s,u),a+=n*p}{const _=this.m_upperTranslation-this.m_translation,l=b.DotVV(this.m_ax,b.SubVV(o,h,b.s_t0))+this.m_sAx*r-this.m_sBx*a;let m=-this.m_axialMass*(l+b2Max(_,0)*t.step.inv_dt);const c=this.m_upperImpulse;this.m_upperImpulse=b2Max(this.m_upperImpulse+m,0),m=this.m_upperImpulse-c;const u=b.MulSV(m,this.m_ax,Gs.SolveVelocityConstraints_s_P),d=m*this.m_sAx,p=m*this.m_sBx;o.SelfMulAdd(e,u),r+=i*d,h.SelfMulSub(s,u),a-=n*p}}{const t=b.DotVV(this.m_ay,b.SubVV(h,o,b.s_t0))+this.m_sBy*a-this.m_sAy*r,_=-this.m_mass*t;this.m_impulse+=_;const l=b.MulSV(_,this.m_ay,Gs.SolveVelocityConstraints_s_P),m=_*this.m_sAy,c=_*this.m_sBy;o.SelfMulSub(e,l),r-=i*m,h.SelfMulAdd(s,l),a+=n*c}t.velocities[this.m_indexA].w=r,t.velocities[this.m_indexB].w=a}SolvePositionConstraints(t){const e=t.positions[this.m_indexA].c;let s=t.positions[this.m_indexA].a;const i=t.positions[this.m_indexB].c;let n=t.positions[this.m_indexB].a,o=0;if(this.m_enableLimit){const t=this.m_qA.SetAngle(s),r=this.m_qB.SetAngle(n);b.SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);const h=w.MulRV(t,this.m_lalcA,this.m_rA);b.SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);const _=w.MulRV(r,this.m_lalcB,this.m_rB),l=b.AddVV(b.SubVV(i,e,b.s_t0),b.SubVV(_,h,b.s_t1),Gs.SolvePositionConstraints_s_d),m=w.MulRV(t,this.m_localXAxisA,this.m_ax),c=b.CrossVV(b.AddVV(l,h,b.s_t0),this.m_ax),u=b.CrossVV(_,this.m_ax);let d=0;const p=b.DotVV(m,l);if(a(this.m_upperTranslation-this.m_lowerTranslation)<.01?d=p:p<=this.m_lowerTranslation?d=b2Min(p-this.m_lowerTranslation,0):p>=this.m_upperTranslation&&(d=b2Max(p-this.m_upperTranslation,0)),0!==d){const t=this.m_invMassA+this.m_invMassB+this.m_invIA*c*c+this.m_invIB*u*u;let r=0;0!==t&&(r=-d/t);const h=b.MulSV(r,m,Gs.SolvePositionConstraints_s_P),_=r*c,l=r*u;e.SelfMulSub(this.m_invMassA,h),s-=this.m_invIA*_,i.SelfMulAdd(this.m_invMassB,h),n+=this.m_invIB*l,o=a(d)}}{const t=this.m_qA.SetAngle(s),r=this.m_qB.SetAngle(n);b.SubVV(this.m_localAnchorA,this.m_localCenterA,this.m_lalcA);const h=w.MulRV(t,this.m_lalcA,this.m_rA);b.SubVV(this.m_localAnchorB,this.m_localCenterB,this.m_lalcB);const _=w.MulRV(r,this.m_lalcB,this.m_rB),l=b.AddVV(b.SubVV(i,e,b.s_t0),b.SubVV(_,h,b.s_t1),Gs.SolvePositionConstraints_s_d),m=w.MulRV(t,this.m_localYAxisA,this.m_ay),c=b.CrossVV(b.AddVV(l,h,b.s_t0),m),u=b.CrossVV(_,m),d=b.DotVV(l,m),p=this.m_invMassA+this.m_invMassB+this.m_invIA*this.m_sAy*this.m_sAy+this.m_invIB*this.m_sBy*this.m_sBy;let y=0;0!==p&&(y=-d/p);const x=b.MulSV(y,m,Gs.SolvePositionConstraints_s_P),A=y*c,f=y*u;e.SelfMulSub(this.m_invMassA,x),s-=this.m_invIA*A,i.SelfMulAdd(this.m_invMassB,x),n+=this.m_invIB*f,o=b2Max(o,a(d))}return t.positions[this.m_indexA].a=s,t.positions[this.m_indexB].a=n,o<=.005}GetDefinition(t){return t}GetAnchorA(t){return this.m_bodyA.GetWorldPoint(this.m_localAnchorA,t)}GetAnchorB(t){return this.m_bodyB.GetWorldPoint(this.m_localAnchorB,t)}GetReactionForce(t,e){return e.x=t*(this.m_impulse*this.m_ay.x+(this.m_springImpulse+this.m_lowerImpulse-this.m_upperImpulse)*this.m_ax.x),e.y=t*(this.m_impulse*this.m_ay.y+(this.m_springImpulse+this.m_lowerImpulse-this.m_upperImpulse)*this.m_ax.y),e}GetReactionTorque(t){return t*this.m_motorImpulse}GetLocalAnchorA(){return this.m_localAnchorA}GetLocalAnchorB(){return this.m_localAnchorB}GetLocalAxisA(){return this.m_localXAxisA}GetJointTranslation(){return this.GetPrismaticJointTranslation()}GetJointLinearSpeed(){return this.GetPrismaticJointSpeed()}GetJointAngle(){return this.GetRevoluteJointAngle()}GetJointAngularSpeed(){return this.GetRevoluteJointSpeed()}GetPrismaticJointTranslation(){const t=this.m_bodyA,e=this.m_bodyB,s=t.GetWorldPoint(this.m_localAnchorA,new b),i=e.GetWorldPoint(this.m_localAnchorB,new b),n=b.SubVV(i,s,new b),o=t.GetWorldVector(this.m_localXAxisA,new b);return b.DotVV(n,o)}GetPrismaticJointSpeed(){const t=this.m_bodyA,e=this.m_bodyB;b.SubVV(this.m_localAnchorA,t.m_sweep.localCenter,this.m_lalcA);const s=w.MulRV(t.m_xf.q,this.m_lalcA,this.m_rA);b.SubVV(this.m_localAnchorB,e.m_sweep.localCenter,this.m_lalcB);const i=w.MulRV(e.m_xf.q,this.m_lalcB,this.m_rB),n=b.AddVV(t.m_sweep.c,s,b.s_t0),o=b.AddVV(e.m_sweep.c,i,b.s_t1),r=b.SubVV(o,n,b.s_t2),h=t.GetWorldVector(this.m_localXAxisA,new b),a=t.m_linearVelocity,_=e.m_linearVelocity,l=t.m_angularVelocity,m=e.m_angularVelocity;return b.DotVV(r,b.CrossSV(l,h,b.s_t0))+b.DotVV(h,b.SubVV(b.AddVCrossSV(_,m,i,b.s_t0),b.AddVCrossSV(a,l,s,b.s_t1),b.s_t0))}GetRevoluteJointAngle(){return this.m_bodyB.m_sweep.a-this.m_bodyA.m_sweep.a}GetRevoluteJointSpeed(){const t=this.m_bodyA.m_angularVelocity;return this.m_bodyB.m_angularVelocity-t}IsMotorEnabled(){return this.m_enableMotor}EnableMotor(t){t!==this.m_enableMotor&&(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_enableMotor=t)}SetMotorSpeed(t){t!==this.m_motorSpeed&&(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_motorSpeed=t)}SetMaxMotorTorque(t){t!==this.m_maxMotorTorque&&(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_maxMotorTorque=t)}GetMotorTorque(t){return t*this.m_motorImpulse}IsLimitEnabled(){return this.m_enableLimit}EnableLimit(t){t!==this.m_enableLimit&&(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_enableLimit=t,this.m_lowerImpulse=0,this.m_upperImpulse=0)}GetLowerLimit(){return this.m_lowerTranslation}GetUpperLimit(){return this.m_upperTranslation}SetLimits(t,e){t===this.m_lowerTranslation&&e===this.m_upperTranslation||(this.m_bodyA.SetAwake(!0),this.m_bodyB.SetAwake(!0),this.m_lowerTranslation=t,this.m_upperTranslation=e,this.m_lowerImpulse=0,this.m_upperImpulse=0)}Dump(t){const e=this.m_bodyA.m_islandIndex,s=this.m_bodyB.m_islandIndex;t(" const jd: b2WheelJointDef = new b2WheelJointDef();\n"),t(" jd.bodyA = bodies[%d];\n",e),t(" jd.bodyB = bodies[%d];\n",s),t(" jd.collideConnected = %s;\n",this.m_collideConnected?"true":"false"),t(" jd.localAnchorA.Set(%.15f, %.15f);\n",this.m_localAnchorA.x,this.m_localAnchorA.y),t(" jd.localAnchorB.Set(%.15f, %.15f);\n",this.m_localAnchorB.x,this.m_localAnchorB.y),t(" jd.localAxisA.Set(%.15f, %.15f);\n",this.m_localXAxisA.x,this.m_localXAxisA.y),t(" jd.enableMotor = %s;\n",this.m_enableMotor?"true":"false"),t(" jd.motorSpeed = %.15f;\n",this.m_motorSpeed),t(" jd.maxMotorTorque = %.15f;\n",this.m_maxMotorTorque),t(" jd.stiffness = %.15f;\n",this.m_stiffness),t(" jd.damping = %.15f;\n",this.m_damping),t(" joints[%d] = this.m_world.CreateJoint(jd);\n",this.m_index)}Draw(t){const e=this.m_bodyA.GetTransform(),s=this.m_bodyB.GetTransform(),i=g.MulXV(e,this.m_localAnchorA,Gs.Draw_s_pA),n=g.MulXV(s,this.m_localAnchorB,Gs.Draw_s_pB),o=w.MulRV(e.q,this.m_localXAxisA,Gs.Draw_s_axis),r=Gs.Draw_s_c1,h=Gs.Draw_s_c2,a=Gs.Draw_s_c3,_=Gs.Draw_s_c4,l=Gs.Draw_s_c5;if(t.DrawSegment(i,n,l),this.m_enableLimit){const s=b.AddVMulSV(i,this.m_lowerTranslation,o,Gs.Draw_s_lower),n=b.AddVMulSV(i,this.m_upperTranslation,o,Gs.Draw_s_upper),_=w.MulRV(e.q,this.m_localYAxisA,Gs.Draw_s_perp);t.DrawSegment(s,n,r),t.DrawSegment(b.AddVMulSV(s,-.5,_,b.s_t0),b.AddVMulSV(s,.5,_,b.s_t1),h),t.DrawSegment(b.AddVMulSV(n,-.5,_,b.s_t0),b.AddVMulSV(n,.5,_,b.s_t1),a)}else t.DrawSegment(b.AddVMulSV(i,-1,o,b.s_t0),b.AddVMulSV(i,1,o,b.s_t1),r);t.DrawPoint(i,5,r),t.DrawPoint(n,5,_)}}Gs.InitVelocityConstraints_s_d=new b,Gs.InitVelocityConstraints_s_P=new b,Gs.SolveVelocityConstraints_s_P=new b,Gs.SolvePositionConstraints_s_d=new b,Gs.SolvePositionConstraints_s_P=new b,Gs.Draw_s_pA=new b,Gs.Draw_s_pB=new b,Gs.Draw_s_axis=new b,Gs.Draw_s_c1=new e(.7,.7,.7),Gs.Draw_s_c2=new e(.3,.9,.3),Gs.Draw_s_c3=new e(.9,.3,.3),Gs.Draw_s_c4=new e(.3,.3,.9),Gs.Draw_s_c5=new e(.4,.4,.4),Gs.Draw_s_lower=new b,Gs.Draw_s_upper=new b,Gs.Draw_s_perp=new b;class Ps{constructor(t){this.m_contactManager=new ms,this.m_bodyList=null,this.m_jointList=null,this.m_bodyCount=0,this.m_jointCount=0,this.m_gravity=new b,this.m_allowSleep=!0,this.m_destructionListener=null,this.m_debugDraw=null,this.m_inv_dt0=0,this.m_newContacts=!1,this.m_locked=!1,this.m_clearForces=!0,this.m_warmStarting=!0,this.m_continuousPhysics=!0,this.m_subStepping=!1,this.m_stepComplete=!0,this.m_profile=new cs,this.m_island=new Vs,this.s_stack=[],this.m_gravity.Copy(t)}SetDestructionListener(t){this.m_destructionListener=t}SetContactFilter(t){this.m_contactManager.m_contactFilter=t}SetContactListener(t){this.m_contactManager.m_contactListener=t}SetDebugDraw(t){this.m_debugDraw=t}CreateBody(t={}){if(this.IsLocked())throw new Error;const e=new Ue(t,this);return e.m_prev=null,e.m_next=this.m_bodyList,this.m_bodyList&&(this.m_bodyList.m_prev=e),this.m_bodyList=e,++this.m_bodyCount,e}DestroyBody(t){if(this.IsLocked())throw new Error;let e=t.m_jointList;for(;e;){const s=e;e=e.next,this.m_destructionListener&&this.m_destructionListener.SayGoodbyeJoint(s.joint),this.DestroyJoint(s.joint),t.m_jointList=e}t.m_jointList=null;let s=t.m_contactList;for(;s;){const t=s;s=s.next,this.m_contactManager.Destroy(t.contact)}t.m_contactList=null;let i=t.m_fixtureList;for(;i;){const e=i;i=i.m_next,this.m_destructionListener&&this.m_destructionListener.SayGoodbyeFixture(e),e.DestroyProxies(),e.Reset(),t.m_fixtureList=i,t.m_fixtureCount-=1}t.m_fixtureList=null,t.m_fixtureCount=0,t.m_prev&&(t.m_prev.m_next=t.m_next),t.m_next&&(t.m_next.m_prev=t.m_prev),t===this.m_bodyList&&(this.m_bodyList=t.m_next),--this.m_bodyCount}static _Joint_Create(e){switch(e.type){case t.b2JointType.e_distanceJoint:return new Oe(e);case t.b2JointType.e_mouseJoint:return new vs(e);case t.b2JointType.e_prismaticJoint:return new Ms(e);case t.b2JointType.e_revoluteJoint:return new Ds(e);case t.b2JointType.e_pulleyJoint:return new Is(e);case t.b2JointType.e_gearJoint:return new Cs(e);case t.b2JointType.e_wheelJoint:return new Gs(e);case t.b2JointType.e_weldJoint:return new Ts(e);case t.b2JointType.e_frictionJoint:return new gs(e);case t.b2JointType.e_motorJoint:return new Bs(e);case t.b2JointType.e_areaJoint:return new ze(e)}throw new Error}static _Joint_Destroy(t){}CreateJoint(t){if(this.IsLocked())throw new Error;const e=Ps._Joint_Create(t);e.m_prev=null,e.m_next=this.m_jointList,this.m_jointList&&(this.m_jointList.m_prev=e),this.m_jointList=e,++this.m_jointCount,e.m_edgeA.prev=null,e.m_edgeA.next=e.m_bodyA.m_jointList,e.m_bodyA.m_jointList&&(e.m_bodyA.m_jointList.prev=e.m_edgeA),e.m_bodyA.m_jointList=e.m_edgeA,e.m_edgeB.prev=null,e.m_edgeB.next=e.m_bodyB.m_jointList,e.m_bodyB.m_jointList&&(e.m_bodyB.m_jointList.prev=e.m_edgeB),e.m_bodyB.m_jointList=e.m_edgeB;const s=e.m_bodyA,i=e.m_bodyB;if(!e.m_collideConnected){let t=i.GetContactList();for(;t;)t.other===s&&t.contact.FlagForFiltering(),t=t.next}return e}DestroyJoint(t){if(this.IsLocked())throw new Error;t.m_prev&&(t.m_prev.m_next=t.m_next),t.m_next&&(t.m_next.m_prev=t.m_prev),t===this.m_jointList&&(this.m_jointList=t.m_next);const e=t.m_bodyA,s=t.m_bodyB,i=t.m_collideConnected;if(e.SetAwake(!0),s.SetAwake(!0),t.m_edgeA.prev&&(t.m_edgeA.prev.next=t.m_edgeA.next),t.m_edgeA.next&&(t.m_edgeA.next.prev=t.m_edgeA.prev),t.m_edgeA===e.m_jointList&&(e.m_jointList=t.m_edgeA.next),t.m_edgeA.Reset(),t.m_edgeB.prev&&(t.m_edgeB.prev.next=t.m_edgeB.next),t.m_edgeB.next&&(t.m_edgeB.next.prev=t.m_edgeB.prev),t.m_edgeB===s.m_jointList&&(s.m_jointList=t.m_edgeB.next),t.m_edgeB.Reset(),Ps._Joint_Destroy(t),--this.m_jointCount,!i){let t=s.GetContactList();for(;t;)t.other===e&&t.contact.FlagForFiltering(),t=t.next}}Step(t,e,s){const i=Ps.Step_s_stepTimer.Reset();this.m_newContacts&&(this.m_contactManager.FindNewContacts(),this.m_newContacts=!1),this.m_locked=!0;const n=Ps.Step_s_step;n.dt=t,n.velocityIterations=e,n.positionIterations=s,n.inv_dt=t>0?1/t:0,n.dtRatio=this.m_inv_dt0*t,n.warmStarting=this.m_warmStarting;const o=Ps.Step_s_timer.Reset();if(this.m_contactManager.Collide(),this.m_profile.collide=o.GetMilliseconds(),this.m_stepComplete&&n.dt>0){const t=Ps.Step_s_timer.Reset();this.Solve(n),this.m_profile.solve=t.GetMilliseconds()}if(this.m_continuousPhysics&&n.dt>0){const t=Ps.Step_s_timer.Reset();this.SolveTOI(n),this.m_profile.solveTOI=t.GetMilliseconds()}n.dt>0&&(this.m_inv_dt0=n.inv_dt),this.m_clearForces&&this.ClearForces(),this.m_locked=!1,this.m_profile.step=i.GetMilliseconds()}ClearForces(){for(let t=this.m_bodyList;t;t=t.m_next)t.m_force.SetZero(),t.m_torque=0}DebugDraw(){if(null===this.m_debugDraw)return;const s=this.m_debugDraw.GetFlags(),i=Ps.DebugDraw_s_color.SetRGB(0,0,0);if(s&t.b2DrawFlags.e_shapeBit)for(let s=this.m_bodyList;s;s=s.m_next){const n=s.m_xf;this.m_debugDraw.PushTransform(n);for(let n=s.GetFixtureList();n;n=n.m_next)s.GetType()===t.b2BodyType.b2_dynamicBody&&0===s.m_mass?this.DrawShape(n,new e(1,0,0)):s.IsEnabled()?s.GetType()===t.b2BodyType.b2_staticBody?(i.SetRGB(.5,.9,.5),this.DrawShape(n,i)):s.GetType()===t.b2BodyType.b2_kinematicBody?(i.SetRGB(.5,.5,.9),this.DrawShape(n,i)):s.IsAwake()?(i.SetRGB(.9,.7,.7),this.DrawShape(n,i)):(i.SetRGB(.6,.6,.6),this.DrawShape(n,i)):(i.SetRGB(.5,.5,.3),this.DrawShape(n,i));this.m_debugDraw.PopTransform(n)}if(s&t.b2DrawFlags.e_jointBit)for(let t=this.m_jointList;t;t=t.m_next)t.Draw(this.m_debugDraw);if(s&t.b2DrawFlags.e_pairBit){i.SetRGB(.3,.9,.9);for(let t=this.m_contactManager.m_contactList;t;t=t.m_next){const e=t.GetFixtureA(),s=t.GetFixtureB(),n=t.GetChildIndexA(),o=t.GetChildIndexB(),r=e.GetAABB(n).GetCenter(),h=s.GetAABB(o).GetCenter();this.m_debugDraw.DrawSegment(r,h,i)}}if(s&t.b2DrawFlags.e_aabbBit){i.SetRGB(.9,.3,.9);const t=Ps.DebugDraw_s_vs;for(let e=this.m_bodyList;e;e=e.m_next)if(e.IsEnabled())for(let s=e.GetFixtureList();s;s=s.m_next)for(let e=0;e{const i=e.userData.fixture;return t?t.ReportFixture(i):!s||s(i)})}QueryAllAABB(t,e=[]){return this.QueryAABB(t,t=>(e.push(t),!0)),e}QueryPointAABB(...t){t[0]instanceof _s?this._QueryPointAABB(t[0],t[1]):this._QueryPointAABB(null,t[0],t[1])}_QueryPointAABB(t,e,s){this.m_contactManager.m_broadPhase.QueryPoint(e,e=>{const i=e.userData.fixture;return t?t.ReportFixture(i):!s||s(i)})}QueryAllPointAABB(t,e=[]){return this.QueryPointAABB(t,t=>(e.push(t),!0)),e}QueryFixtureShape(...t){t[0]instanceof _s?this._QueryFixtureShape(t[0],t[1],t[2],t[3]):this._QueryFixtureShape(null,t[0],t[1],t[2],t[3])}_QueryFixtureShape(t,e,s,i,n){const o=Ps.QueryFixtureShape_s_aabb;e.ComputeAABB(o,i,s),this.m_contactManager.m_broadPhase.Query(o,o=>{const r=o.userData,h=r.fixture;if(b2TestOverlapShape(e,s,h.GetShape(),r.childIndex,i,h.GetBody().GetTransform())){if(t)return t.ReportFixture(h);if(n)return n(h)}return!0})}QueryAllFixtureShape(t,e,s,i=[]){return this.QueryFixtureShape(t,e,s,t=>(i.push(t),!0)),i}QueryFixturePoint(...t){t[0]instanceof _s?this._QueryFixturePoint(t[0],t[1]):this._QueryFixturePoint(null,t[0],t[1])}_QueryFixturePoint(t,e,s){this.m_contactManager.m_broadPhase.QueryPoint(e,i=>{const n=i.userData.fixture;if(n.TestPoint(e)){if(t)return t.ReportFixture(n);if(s)return s(n)}return!0})}QueryAllFixturePoint(t,e=[]){return this.QueryFixturePoint(t,t=>(e.push(t),!0)),e}RayCast(...t){t[0]instanceof ls?this._RayCast(t[0],t[1],t[2]):this._RayCast(null,t[0],t[1],t[2])}_RayCast(t,e,s,i){const n=Ps.RayCast_s_input;n.maxFraction=1,n.p1.Copy(e),n.p2.Copy(s),this.m_contactManager.m_broadPhase.RayCast(n,(n,o)=>{const r=o.userData,h=r.fixture,a=r.childIndex,_=Ps.RayCast_s_output;if(h.RayCast(_,n,a)){const n=_.fraction,o=Ps.RayCast_s_point;if(o.Set((1-n)*e.x+n*s.x,(1-n)*e.y+n*s.y),t)return t.ReportFixture(h,o,_.normal,n);if(i)return i(h,o,_.normal,n)}return n.maxFraction})}RayCastOne(t,e){let s=null,i=1;return this.RayCast(t,e,(t,e,n,o)=>(o(s.push(t),1)),s}GetBodyList(){return this.m_bodyList}GetJointList(){return this.m_jointList}GetContactList(){return this.m_contactManager.m_contactList}SetAllowSleeping(t){if(t!==this.m_allowSleep&&(this.m_allowSleep=t,!this.m_allowSleep))for(let t=this.m_bodyList;t;t=t.m_next)t.SetAwake(!0)}GetAllowSleeping(){return this.m_allowSleep}SetWarmStarting(t){this.m_warmStarting=t}GetWarmStarting(){return this.m_warmStarting}SetContinuousPhysics(t){this.m_continuousPhysics=t}GetContinuousPhysics(){return this.m_continuousPhysics}SetSubStepping(t){this.m_subStepping=t}GetSubStepping(){return this.m_subStepping}GetProxyCount(){return this.m_contactManager.m_broadPhase.GetProxyCount()}GetBodyCount(){return this.m_bodyCount}GetJointCount(){return this.m_jointCount}GetContactCount(){return this.m_contactManager.m_contactCount}GetTreeHeight(){return this.m_contactManager.m_broadPhase.GetTreeHeight()}GetTreeBalance(){return this.m_contactManager.m_broadPhase.GetTreeBalance()}GetTreeQuality(){return this.m_contactManager.m_broadPhase.GetTreeQuality()}SetGravity(t,e=!0){if(!b.IsEqualToV(this.m_gravity,t)&&(this.m_gravity.Copy(t),e))for(let t=this.m_bodyList;t;t=t.m_next)t.SetAwake(!0)}GetGravity(){return this.m_gravity}IsLocked(){return this.m_locked}SetAutoClearForces(t){this.m_clearForces=t}GetAutoClearForces(){return this.m_clearForces}ShiftOrigin(t){if(this.IsLocked())throw new Error;for(let e=this.m_bodyList;e;e=e.m_next)e.m_xf.p.SelfSub(t),e.m_sweep.c0.SelfSub(t),e.m_sweep.c.SelfSub(t);for(let e=this.m_jointList;e;e=e.m_next)e.ShiftOrigin(t);this.m_contactManager.m_broadPhase.ShiftOrigin(t)}GetContactManager(){return this.m_contactManager}GetProfile(){return this.m_profile}Dump(e){if(this.m_locked)return;e("const g: b2Vec2 = new b2Vec2(%.15f, %.15f);\n",this.m_gravity.x,this.m_gravity.y),e("this.m_world.SetGravity(g);\n"),e("const bodies: b2Body[] = [];\n"),e("const joints: b2Joint[] = [];\n");let s=0;for(let t=this.m_bodyList;t;t=t.m_next)t.m_islandIndex=s,t.Dump(e),++s;s=0;for(let t=this.m_jointList;t;t=t.m_next)t.m_index=s,++s;for(let s=this.m_jointList;s;s=s.m_next)s.m_type!==t.b2JointType.e_gearJoint&&(e("{\n"),s.Dump(e),e("}\n"));for(let s=this.m_jointList;s;s=s.m_next)s.m_type===t.b2JointType.e_gearJoint&&(e("{\n"),s.Dump(e),e("}\n"))}DrawShape(e,s){if(null===this.m_debugDraw)return;const i=e.GetShape();switch(i.m_type){case t.b2ShapeType.e_circleShape:{const t=i,e=t.m_p,n=t.m_radius,o=b.UNITX;this.m_debugDraw.DrawSolidCircle(e,n,o,s);break}case t.b2ShapeType.e_edgeShape:{const t=i,e=t.m_vertex1,n=t.m_vertex2;this.m_debugDraw.DrawSegment(e,n,s),!1===t.m_oneSided&&(this.m_debugDraw.DrawPoint(e,4,s),this.m_debugDraw.DrawPoint(n,4,s));break}case t.b2ShapeType.e_chainShape:{const t=i,e=t.m_count,n=t.m_vertices;let o=n[0];for(let t=1;t0;){const e=i[--o];if(!e)throw new Error;if(s.AddBody(e),e.GetType()!==t.b2BodyType.b2_staticBody){e.m_awakeFlag=!0;for(let t=e.m_contactList;t;t=t.next){const e=t.contact;if(e.m_islandFlag)continue;if(!e.IsEnabled()||!e.IsTouching())continue;const n=e.m_fixtureA.m_isSensor,r=e.m_fixtureB.m_isSensor;if(n||r)continue;s.AddContact(e),e.m_islandFlag=!0;const h=t.other;h.m_islandFlag||(i[o++]=h,h.m_islandFlag=!0)}for(let t=e.m_jointList;t;t=t.next){if(t.joint.m_islandFlag)continue;const e=t.other;e.IsEnabled()&&(s.AddJoint(t.joint),t.joint.m_islandFlag=!0,e.m_islandFlag||(i[o++]=e,e.m_islandFlag=!0))}}}const r=new cs;s.Solve(r,e,this.m_gravity,this.m_allowSleep),this.m_profile.solveInit+=r.solveInit,this.m_profile.solveVelocity+=r.solveVelocity,this.m_profile.solvePosition+=r.solvePosition;for(let e=0;e8)continue;let s=1;if(e.m_toiFlag)s=e.m_toi;else{const i=e.GetFixtureA(),n=e.GetFixtureB();if(i.IsSensor()||n.IsSensor())continue;const o=i.GetBody(),r=n.GetBody(),h=o.m_type,a=r.m_type,_=o.IsAwake()&&h!==t.b2BodyType.b2_staticBody,l=r.IsAwake()&&a!==t.b2BodyType.b2_staticBody;if(!_&&!l)continue;const m=o.IsBullet()||h!==t.b2BodyType.b2_dynamicBody,c=r.IsBullet()||a!==t.b2BodyType.b2_dynamicBody;if(!m&&!c)continue;let u=o.m_sweep.alpha0;o.m_sweep.alpha00&&h>0?r*h/(r+h):r>0?r:h;const _=2*n*e;t.stiffness=a*_*_,t.damping=2*a*s*_},t.b2AreaJoint=ze,t.b2AreaJointDef=class extends qe{constructor(){super(t.b2JointType.e_areaJoint),this.bodies=[],this.stiffness=0,this.damping=0}AddBody(t){this.bodies.push(t),1===this.bodies.length?this.bodyA=t:2===this.bodies.length&&(this.bodyB=t)}},t.b2Asin=p,t.b2Assert=function(t,...e){if(!t)throw new Error(...e)},t.b2Atan2=y,t.b2BlockAllocator=class{},t.b2Body=Ue,t.b2BodyDef=class{constructor(){this.type=t.b2BodyType.b2_staticBody,this.position=new b(0,0),this.angle=0,this.linearVelocity=new b(0,0),this.angularVelocity=0,this.linearDamping=0,this.angularDamping=0,this.allowSleep=!0,this.awake=!0,this.fixedRotation=!1,this.bullet=!1,this.enabled=!0,this.userData=null,this.gravityScale=1}},t.b2BroadPhase=pt,t.b2ChainAndCircleContact=Ke,t.b2ChainAndPolygonContact=He,t.b2ChainShape=bt,t.b2CircleContact=$e,t.b2CircleShape=xt,t.b2Clamp=b2Clamp,t.b2ClipSegmentToLine=b2ClipSegmentToLine,t.b2ClipVertex=ot,t.b2CollideCircles=b2CollideCircles,t.b2CollideEdgeAndCircle=b2CollideEdgeAndCircle,t.b2CollideEdgeAndPolygon=b2CollideEdgeAndPolygon,t.b2CollidePolygonAndCircle=b2CollidePolygonAndCircle,t.b2CollidePolygons=b2CollidePolygons,t.b2Color=e,t.b2Contact=Qe,t.b2ContactEdge=Ye,t.b2ContactFactory=os,t.b2ContactFeature=tt,t.b2ContactFilter=rs,t.b2ContactID=et,t.b2ContactImpulse=hs,t.b2ContactListener=as,t.b2ContactManager=ms,t.b2ContactPositionConstraint=As,t.b2ContactRegister=ns,t.b2ContactSolver=ws,t.b2ContactSolverDef=fs,t.b2ContactVelocityConstraint=xs,t.b2Cos=c,t.b2Counter=class{constructor(){this.m_count=0,this.m_min_count=0,this.m_max_count=0}GetCount(){return this.m_count}GetMinCount(){return this.m_min_count}GetMaxCount(){return this.m_max_count}ResetCount(){const t=this.m_count;return this.m_count=0,t}ResetMinCount(){this.m_min_count=0}ResetMaxCount(){this.m_max_count=0}Increment(){this.m_count++,this.m_max_countthis.m_count&&(this.m_min_count=this.m_count)}},t.b2DegToRad=function(t){return.017453292519944444*t},t.b2DestructionListener=class{SayGoodbyeJoint(t){}SayGoodbyeFixture(t){}},t.b2Distance=b2Distance,t.b2DistanceInput=T,t.b2DistanceJoint=Oe,t.b2DistanceJointDef=Ee,t.b2DistanceOutput=G,t.b2DistanceProxy=I,t.b2Draw=class{constructor(){this.m_drawFlags=0}SetFlags(t){this.m_drawFlags=t}GetFlags(){return this.m_drawFlags}AppendFlags(t){this.m_drawFlags|=t}ClearFlags(t){this.m_drawFlags&=~t}},t.b2DynamicTree=ut,t.b2EdgeAndCircleContact=ss,t.b2EdgeAndPolygonContact=is,t.b2EdgeShape=yt,t.b2Filter=Xe,t.b2Fixture=We,t.b2FixtureDef=Ne,t.b2FixtureProxy=Ze,t.b2Free=function(t){},t.b2FrictionJoint=gs,t.b2FrictionJointDef=class extends qe{constructor(){super(t.b2JointType.e_frictionJoint),this.localAnchorA=new b,this.localAnchorB=new b,this.maxForce=0,this.maxTorque=0}Initialize(t,e,s){this.bodyA=t,this.bodyB=e,this.bodyA.GetLocalPoint(s,this.localAnchorA),this.bodyB.GetLocalPoint(s,this.localAnchorB)}},t.b2GearJoint=Cs,t.b2GearJointDef=class extends qe{constructor(){super(t.b2JointType.e_gearJoint),this.ratio=1}},t.b2GetPointStates=function(e,s,i,n){let o;for(o=0;o0&&0==(t&t-1)},t.b2IsValid=_,t.b2Island=Vs,t.b2Jacobian=class{constructor(){this.linear=new b,this.angularA=0,this.angularB=0}SetZero(){return this.linear.SetZero(),this.angularA=0,this.angularB=0,this}Set(t,e,s){return this.linear.Copy(t),this.angularA=e,this.angularB=s,this}},t.b2Joint=Je,t.b2JointDef=qe,t.b2JointEdge=je,t.b2LinearStiffness=function(t,e,s,i,o){const r=i.GetMass(),h=o.GetMass();let a;a=r>0&&h>0?r*h/(r+h):r>0?r:h;const _=2*n*e;t.stiffness=a*_*_,t.damping=2*a*s*_},t.b2Log=function(t,...e){},t.b2MakeArray=b2MakeArray,t.b2MakeNullArray=function(t){const e=new Array(t);for(let s=0;s>1&2147483647,t|=t>>2&1073741823,t|=t>>4&268435455,t|=t>>8&16777215,(t|=t>>16&65535)+1},t.b2Pair=dt,t.b2ParseInt=function(t){return parseInt(t,10)},t.b2ParseUInt=function(t){return Math.abs(parseInt(t,10))},t.b2PolygonAndCircleContact=es,t.b2PolygonContact=ts,t.b2PolygonShape=de,t.b2Position=ds,t.b2PositionSolverManifold=Ss,t.b2Pow=m,t.b2PrismaticJoint=Ms,t.b2PrismaticJointDef=class extends qe{constructor(){super(t.b2JointType.e_prismaticJoint),this.localAnchorA=new b,this.localAnchorB=new b,this.localAxisA=new b(1,0),this.referenceAngle=0,this.enableLimit=!1,this.lowerTranslation=0,this.upperTranslation=0,this.enableMotor=!1,this.maxMotorForce=0,this.motorSpeed=0}Initialize(t,e,s,i){this.bodyA=t,this.bodyB=e,this.bodyA.GetLocalPoint(s,this.localAnchorA),this.bodyB.GetLocalPoint(s,this.localAnchorB),this.bodyA.GetLocalVector(i,this.localAxisA),this.referenceAngle=this.bodyB.GetAngle()-this.bodyA.GetAngle()}},t.b2Profile=cs,t.b2PulleyJoint=Is,t.b2PulleyJointDef=class extends qe{constructor(){super(t.b2JointType.e_pulleyJoint),this.groundAnchorA=new b(-1,1),this.groundAnchorB=new b(1,1),this.localAnchorA=new b(-1,0),this.localAnchorB=new b(1,0),this.lengthA=0,this.lengthB=0,this.ratio=1,this.collideConnected=!0}Initialize(t,e,s,i,n,o,r){this.bodyA=t,this.bodyB=e,this.groundAnchorA.Copy(s),this.groundAnchorB.Copy(i),this.bodyA.GetLocalPoint(n,this.localAnchorA),this.bodyB.GetLocalPoint(o,this.localAnchorB),this.lengthA=b.DistanceVV(n,s),this.lengthB=b.DistanceVV(o,i),this.ratio=r}},t.b2QueryCallback=_s,t.b2RadToDeg=function(t){return 57.29577951307855*t},t.b2Random=function(){return 2*Math.random()-1},t.b2RandomRange=function(t,e){return(e-t)*Math.random()+t},t.b2RayCastCallback=ls,t.b2RayCastInput=rt,t.b2RayCastOutput=ht,t.b2RevoluteJoint=Ds,t.b2RevoluteJointDef=class extends qe{constructor(){super(t.b2JointType.e_revoluteJoint),this.localAnchorA=new b(0,0),this.localAnchorB=new b(0,0),this.referenceAngle=0,this.enableLimit=!1,this.lowerAngle=0,this.upperAngle=0,this.enableMotor=!1,this.motorSpeed=0,this.maxMotorTorque=0}Initialize(t,e,s){this.bodyA=t,this.bodyB=e,this.bodyA.GetLocalPoint(s,this.localAnchorA),this.bodyB.GetLocalPoint(s,this.localAnchorB),this.referenceAngle=this.bodyB.GetAngle()-this.bodyA.GetAngle()}},t.b2Rope=class{constructor(){this.m_position=new b,this.m_count=0,this.m_stretchCount=0,this.m_bendCount=0,this.m_stretchConstraints=[],this.m_bendConstraints=[],this.m_bindPositions=[],this.m_ps=[],this.m_p0s=[],this.m_vs=[],this.m_invMasses=[],this.m_gravity=new b,this.m_tuning=new Fs}Create(t){function make_array(t,e,s){for(let i=0;inew b),make_array(this.m_ps,this.m_count,()=>new b),make_array(this.m_p0s,this.m_count,()=>new b),make_array(this.m_vs,this.m_count,()=>new b),make_array(this.m_invMasses,this.m_count,()=>0);for(let e=0;e0?1/s:0}this.m_stretchCount=this.m_count-1,this.m_bendCount=this.m_count-2,make_array(this.m_stretchConstraints,this.m_stretchCount,()=>new ks),make_array(this.m_bendConstraints,this.m_bendCount,()=>new js);for(let t=0;t0?(this.m_vs[t].x*=o,this.m_vs[t].y*=o,this.m_vs[t].x+=e*this.m_gravity.x,this.m_vs[t].y+=e*this.m_gravity.y):(this.m_vs[t].x=n*(this.m_bindPositions[t].x+i.x-this.m_p0s[t].x),this.m_vs[t].y=n*(this.m_bindPositions[t].y+i.y-this.m_p0s[t].y));this.m_tuning.bendingModel===t.b2BendingModel.b2_springAngleBendingModel&&this.ApplyBendForces(e);for(let t=0;t0?n:i;t.DrawPoint(this.m_ps[e],5,o)}const o=this.m_invMasses[this.m_count-1]>0?n:i;t.DrawPoint(this.m_ps[this.m_count-1],5,o)}SolveStretch_PBD(){const t=this.m_tuning.stretchStiffness;for(let e=0;e.0025;){t.iterations+=1,c=s.GetSupport(w.MulTRV(o.q,b.NegV(y,b.s_t1),b.s_t0)),u=g.MulXV(o,s.GetVertex(c),N),d=i.GetSupport(w.MulTRV(r.q,y,b.s_t0)),p=g.MulXV(r,i.GetVertex(d),Z);const e=b.SubVV(u,p,U);y.Normalize();const n=b.DotVV(y,e),f=b.DotVV(y,h);if(n-x>_*f){if(f<=0)return!1;if(_=(n-x)/f,_>1)return!1;a.Copy(y).SelfNeg(),l.m_count=0}const S=m[l.m_count];switch(S.indexA=d,S.wA.Copy(p).SelfMulAdd(_,h),S.indexB=c,S.wB.Copy(u),S.w.Copy(S.wB).SelfSub(S.wA),S.a=1,l.m_count+=1,l.m_count){case 1:break;case 2:l.Solve2();break;case 3:l.Solve3()}if(3===l.m_count)return!1;l.GetClosestPoint(y),++A}if(0===A)return!1;const f=Y,S=Q;return l.GetWitnessPoints(f,S),y.LengthSquared()>0&&(a.Copy(y).SelfNeg(),a.Normalize()),t.normal.Copy(a),t.lambda=_,t.iterations=A,!0},t.b2ShapeCastInput=class{constructor(){this.proxyA=new I,this.proxyB=new I,this.transformA=new g,this.transformB=new g,this.translationB=new b}},t.b2ShapeCastOutput=class{constructor(){this.point=new b,this.normal=new b,this.lambda=0,this.iterations=0}},t.b2Simplex=L,t.b2SimplexCache=D,t.b2SimplexVertex=P,t.b2Sin=u,t.b2SolverData=ys,t.b2Sq=b2Sq,t.b2Sqrt=l,t.b2StackAllocator=class{},t.b2Swap=function(t,e){const s=t[0];t[0]=e[0],e[0]=s},t.b2Sweep=C,t.b2TOIInput=we,t.b2TOIOutput=Ve,t.b2TestOverlapAABB=b2TestOverlapAABB,t.b2TestOverlapShape=b2TestOverlapShape,t.b2TimeOfImpact=b2TimeOfImpact,t.b2TimeStep=us,t.b2Timer=V,t.b2Transform=g,t.b2TreeNode=ct,t.b2Vec2=b,t.b2Vec2_zero=x,t.b2Vec3=A,t.b2Velocity=ps,t.b2VelocityConstraintPoint=bs,t.b2Version=o,t.b2WeldJoint=Ts,t.b2WeldJointDef=class extends qe{constructor(){super(t.b2JointType.e_weldJoint),this.localAnchorA=new b,this.localAnchorB=new b,this.referenceAngle=0,this.stiffness=0,this.damping=0}Initialize(t,e,s){this.bodyA=t,this.bodyB=e,this.bodyA.GetLocalPoint(s,this.localAnchorA),this.bodyB.GetLocalPoint(s,this.localAnchorB),this.referenceAngle=this.bodyB.GetAngle()-this.bodyA.GetAngle()}},t.b2WheelJoint=Gs,t.b2WheelJointDef=class extends qe{constructor(){super(t.b2JointType.e_wheelJoint),this.localAnchorA=new b(0,0),this.localAnchorB=new b(0,0),this.localAxisA=new b(1,0),this.enableLimit=!1,this.lowerTranslation=0,this.upperTranslation=0,this.enableMotor=!1,this.maxMotorTorque=0,this.motorSpeed=0,this.stiffness=0,this.damping=0}Initialize(t,e,s,i){this.bodyA=t,this.bodyB=e,this.bodyA.GetLocalPoint(s,this.localAnchorA),this.bodyB.GetLocalPoint(s,this.localAnchorB),this.bodyA.GetLocalVector(i,this.localAxisA)}},t.b2World=Ps,t.b2WorldManifold=nt,t.b2_180_over_pi=57.29577951307855,t.b2_aabbExtension=.1,t.b2_aabbMultiplier=4,t.b2_angularSleepTolerance=.03490658503988889,t.b2_angularSlop=.03490658503988889,t.b2_baumgarte=.2,t.b2_branch="master",t.b2_commit="9ebbbcd960ad424e03e5de6e66a40764c16f51bc",t.b2_epsilon=1e-5,t.b2_epsilon_sq=1e-5*1e-5,t.b2_gjk_reset=function(){t.b2_gjkCalls=0,t.b2_gjkIters=0,t.b2_gjkMaxIters=0},t.b2_lengthUnitsPerMeter=1,t.b2_linearSleepTolerance=.01,t.b2_linearSlop=.005,t.b2_maxAngularCorrection=.13962634015955555,t.b2_maxFloat=i,t.b2_maxLinearCorrection=.2,t.b2_maxManifoldPoints=2,t.b2_maxPolygonVertices=8,t.b2_maxRotation=1.570796326795,t.b2_maxRotationSquared=2.4674011002726646,t.b2_maxSubSteps=8,t.b2_maxTOIContacts=32,t.b2_maxTranslation=2,t.b2_maxTranslationSquared=4,t.b2_minPulleyLength=2,t.b2_pi=n,t.b2_pi_over_180=.017453292519944444,t.b2_polygonRadius=.01,t.b2_timeToSleep=.5,t.b2_toiBaumgarte=.75,t.b2_toi_reset=function(){t.b2_toiTime=0,t.b2_toiMaxTime=0,t.b2_toiCalls=0,t.b2_toiIters=0,t.b2_toiMaxIters=0,t.b2_toiRootIters=0,t.b2_toiMaxRootIters=0},t.b2_two_pi=6.28318530718,t.b2_version=r,t.dynamicBody=Es,t.get_g_blockSolve=function(){return t.g_blockSolve},t.kinematicBody=Js,t.pbdAngleBendingModel=zs,t.pbdDistanceBendingModel=Ns,t.pbdHeightBendingModel=Zs,t.pbdStretchingModel=Us,t.pbdTriangleBendingModel=Ws,t.set_g_blockSolve=function(e){t.g_blockSolve=e},t.springAngleBendingModel=Os,t.staticBody=qs,t.xpbdAngleBendingModel=Xs,t.xpbdStretchingModel=Ys,Object.defineProperty(t,"__esModule",{value:!0}),t}({});!function(t,e){"use strict";class s{}s.RigidBody=null,s.Physics=null;class i extends e.Component{constructor(){super(...arguments),this._isSensor=!1,this._density=10,this._friction=.2,this._restitution=0}getDef(){if(!this._def){var t=new window.box2d.b2FixtureDef;t.density=this.density,t.friction=this.friction,t.isSensor=this.isSensor,t.restitution=this.restitution,t.shape=this._shape,this._def=t}return this._def}_onEnable(){this.rigidBody?this.refresh():e.Laya.systemTimer.callLater(this,this._checkRigidBody)}_checkRigidBody(){if(!this.rigidBody){var t=this.owner.getComponent(s.RigidBody);t&&(this.rigidBody=t,this.refresh())}}_onDestroy(){this.rigidBody&&(this.fixture&&(this.fixture.GetBody()==this.rigidBody._getOriBody()&&this.rigidBody.body.DestroyFixture(this.fixture),this.fixture=null),this.rigidBody=null,this._shape=null,this._def=null)}get isSensor(){return this._isSensor}set isSensor(t){this._isSensor=t,this._def&&(this._def.isSensor=t,this.refresh())}get density(){return this._density}set density(t){this._density=t,this._def&&(this._def.density=t,this.refresh())}get friction(){return this._friction}set friction(t){this._friction=t,this._def&&(this._def.friction=t,this.refresh())}get restitution(){return this._restitution}set restitution(t){this._restitution=t,this._def&&(this._def.restitution=t,this.refresh())}refresh(){if(this.enabled&&this.rigidBody){var t=this.rigidBody.body;this.fixture&&(this.fixture.GetBody()==this.rigidBody.body&&this.rigidBody.body.DestroyFixture(this.fixture),this.fixture.Destroy(),this.fixture=null);var e=this.getDef();e.filter.groupIndex=this.rigidBody.group,e.filter.categoryBits=this.rigidBody.category,e.filter.maskBits=this.rigidBody.mask,this.fixture=t.CreateFixture(e),this.fixture.collider=this}}resetShape(t=!0){}get isSingleton(){return!1}}e.ClassUtils.regClass("laya.physics.ColliderBase",i),e.ClassUtils.regClass("Laya.ColliderBase",i);class n extends e.Component{constructor(){super(...arguments),this._type="dynamic",this._allowSleep=!0,this._angularVelocity=0,this._angularDamping=0,this._linearVelocity={x:0,y:0},this._linearDamping=0,this._bullet=!1,this._allowRotation=!0,this._gravityScale=1,this.group=0,this.category=1,this.mask=-1,this.label="RigidBody"}_createBody(){if(!this._body&&this.owner){var t=this.owner,i=window.box2d,n=new i.b2BodyDef,o=t.localToGlobal(e.Point.TEMP.setTo(0,0),!1,s.Physics.I.worldRoot);n.position.Set(o.x/s.Physics.PIXEL_RATIO,o.y/s.Physics.PIXEL_RATIO),n.angle=e.Utils.toRadian(t.rotation),n.allowSleep=this._allowSleep,n.angularDamping=this._angularDamping,n.angularVelocity=this._angularVelocity,n.bullet=this._bullet,n.fixedRotation=!this._allowRotation,n.gravityScale=this._gravityScale,n.linearDamping=this._linearDamping;var r=this._linearVelocity;(r&&0!=r.x||0!=r.y)&&(n.linearVelocity=new i.b2Vec2(r.x,r.y)),n.type=i.b2BodyType["b2_"+this._type+"Body"],this._body=s.Physics.I._createBody(n),this.resetCollider(!1)}}_onAwake(){this._createBody()}_onEnable(){var t=this;this._createBody(),e.Laya.physicsTimer.frameLoop(1,this,this._sysPhysicToNode);var s=this.owner;if(this.accessGetSetFunc(s,"x","set")&&!s._changeByRigidBody){s._changeByRigidBody=!0,this._overSet(s,"x",(function(e){t.accessGetSetFunc(s,"x","set")(e),t._sysPosToPhysic()})),this._overSet(s,"y",(function(e){t.accessGetSetFunc(s,"y","set")(e),t._sysPosToPhysic()})),this._overSet(s,"rotation",(function(e){t.accessGetSetFunc(s,"rotation","set")(e),t._sysNodeToPhysic()})),this._overSet(s,"scaleX",(function(e){t.accessGetSetFunc(s,"scaleX","set")(e),t.resetCollider(!0)})),this._overSet(s,"scaleY",(function(e){t.accessGetSetFunc(s,"scaleY","set")(e),t.resetCollider(!0)}))}}accessGetSetFunc(t,e,s){if(-1===["get","set"].indexOf(s))return;let i=`_$${s}_${e}`;if(t[i])return t[i];let n,o=t.constructor;for(;o;){if(n=Object.getOwnPropertyDescriptor(o.prototype,e),n&&n[s]){t[i]=n[s].bind(t);break}o=Object.getPrototypeOf(o)}return t[i]}resetCollider(t){var e=this.owner.getComponents(i);if(e)for(var s=0,n=e.length;s.033&&(t=.033),this.world.Step(t,this.velocityIterations,this.positionIterations,3);var s=this._eventList.length;if(s>0){for(var i=0;i=0&&(e.maxLength=this._maxLength/r.PIXEL_RATIO),this._minLength>=0&&(e.minLength=this._minLength/r.PIXEL_RATIO),this._joint=r.I._createJoint(e)}}get length(){return this._length}set length(t){this._length=t,this._joint&&this._joint.SetLength(t/r.PIXEL_RATIO)}get minLength(){return this._minLength}set minLength(t){this._minLength=t,this._joint&&this._joint.SetMinLength(t/r.PIXEL_RATIO)}get maxLength(){return this._maxLength}set maxLength(t){this._maxLength=t,this._joint&&this._joint.SetMaxLength(t/r.PIXEL_RATIO)}get frequency(){return this._frequency}set frequency(t){if(this._frequency=t,this._joint){let t={},e=window.box2d,s=this.otherBody?this.otherBody.getBody():r.I._emptyBody,i=this.selfBody.getBody();e.b2LinearStiffness(t,this._frequency,this._dampingRatio,s,i),this._joint.SetStiffness(t.stiffness),this._joint.SetDamping(t.damping)}}get damping(){return this._dampingRatio}set damping(t){if(this._dampingRatio=t,this._joint){let t={},e=window.box2d,s=this.otherBody?this.otherBody.getBody():r.I._emptyBody,i=this.selfBody.getBody();e.b2LinearStiffness(t,this._frequency,this._dampingRatio,s,i),this._joint.SetDamping(t.damping)}}}e.ClassUtils.regClass("laya.physics.joint.DistanceJoint",p),e.ClassUtils.regClass("Laya.DistanceJoint",p);class y extends d{constructor(){super(...arguments),this.collideConnected=!1,this._ratio=1}_createJoint(){if(!this._joint){if(!this.joint1)throw"Joint1 can not be empty";if(!this.joint2)throw"Joint2 can not be empty";var t=window.box2d,e=y._temp||(y._temp=new t.b2GearJointDef);e.bodyA=this.joint1.owner.getComponent(n).getBody(),e.bodyB=this.joint2.owner.getComponent(n).getBody(),e.joint1=this.joint1.joint,e.joint2=this.joint2.joint,e.ratio=this._ratio,e.collideConnected=this.collideConnected,this._joint=r.I._createJoint(e)}}get ratio(){return this._ratio}set ratio(t){this._ratio=t,this._joint&&this._joint.SetRatio(t)}}e.ClassUtils.regClass("laya.physics.joint.GearJoint",y),e.ClassUtils.regClass("Laya.GearJoint",y);class b extends d{constructor(){super(...arguments),this.collideConnected=!1,this._linearOffset=[0,0],this._angularOffset=0,this._maxForce=1e3,this._maxTorque=1e3,this._correctionFactor=.3}_createJoint(){if(!this._joint){if(!this.otherBody)throw"otherBody can not be empty";if(this.selfBody=this.selfBody||this.owner.getComponent(n),!this.selfBody)throw"selfBody can not be empty";var t=window.box2d,e=b._temp||(b._temp=new t.b2MotorJointDef);e.Initialize(this.otherBody.getBody(),this.selfBody.getBody()),e.linearOffset=new t.b2Vec2(this._linearOffset[0]/r.PIXEL_RATIO,this._linearOffset[1]/r.PIXEL_RATIO),e.angularOffset=this._angularOffset,e.maxForce=this._maxForce,e.maxTorque=this._maxTorque,e.correctionFactor=this._correctionFactor,e.collideConnected=this.collideConnected,this._joint=r.I._createJoint(e)}}get linearOffset(){return this._linearOffset}set linearOffset(t){this._linearOffset=t,this._joint&&this._joint.SetLinearOffset(new window.box2d.b2Vec2(t[0]/r.PIXEL_RATIO,t[1]/r.PIXEL_RATIO))}get angularOffset(){return this._angularOffset}set angularOffset(t){this._angularOffset=t,this._joint&&this._joint.SetAngularOffset(t)}get maxForce(){return this._maxForce}set maxForce(t){this._maxForce=t,this._joint&&this._joint.SetMaxForce(t)}get maxTorque(){return this._maxTorque}set maxTorque(t){this._maxTorque=t,this._joint&&this._joint.SetMaxTorque(t)}get correctionFactor(){return this._correctionFactor}set correctionFactor(t){this._correctionFactor=t,this._joint&&this._joint.SetCorrectionFactor(t)}}e.ClassUtils.regClass("laya.physics.joint.MotorJoint",b),e.ClassUtils.regClass("Laya.MotorJoint",b);class x extends d{constructor(){super(...arguments),this._maxForce=1e4,this._frequency=5,this._dampingRatio=.7}_onEnable(){this.owner.on(e.Event.MOUSE_DOWN,this,this.onMouseDown)}_onAwake(){}onMouseDown(){this._createJoint(),e.Laya.stage.on(e.Event.MOUSE_MOVE,this,this.onMouseMove),e.Laya.stage.once(e.Event.MOUSE_UP,this,this.onStageMouseUp),e.Laya.stage.once(e.Event.MOUSE_OUT,this,this.onStageMouseUp)}_createJoint(){if(!this._joint){if(this.selfBody=this.selfBody||this.owner.getComponent(n),!this.selfBody)throw"selfBody can not be empty";var t=window.box2d,s=x._temp||(x._temp=new t.b2MouseJointDef);if(this.anchor)var i=this.selfBody.owner.localToGlobal(e.Point.TEMP.setTo(this.anchor[0],this.anchor[1]),!1,r.I.worldRoot);else i=r.I.worldRoot.globalToLocal(e.Point.TEMP.setTo(e.Laya.stage.mouseX,e.Laya.stage.mouseY));var o=new t.b2Vec2(i.x/r.PIXEL_RATIO,i.y/r.PIXEL_RATIO);s.bodyA=r.I._emptyBody,s.bodyB=this.selfBody.getBody(),s.target=o,t.b2LinearStiffness(s,this._frequency,this._dampingRatio,s.bodyA,s.bodyB),s.maxForce=this._maxForce,this._joint=r.I._createJoint(s)}}onStageMouseUp(){e.Laya.stage.off(e.Event.MOUSE_MOVE,this,this.onMouseMove),e.Laya.stage.off(e.Event.MOUSE_UP,this,this.onStageMouseUp),e.Laya.stage.off(e.Event.MOUSE_OUT,this,this.onStageMouseUp),super._onDisable()}onMouseMove(){this._joint.SetTarget(new window.box2d.b2Vec2(r.I.worldRoot.mouseX/r.PIXEL_RATIO,r.I.worldRoot.mouseY/r.PIXEL_RATIO))}_onDisable(){this.owner.off(e.Event.MOUSE_DOWN,this,this.onMouseDown),super._onDisable()}get maxForce(){return this._maxForce}set maxForce(t){this._maxForce=t,this._joint&&this._joint.SetMaxForce(t)}get frequency(){return this._frequency}set frequency(t){if(this._frequency=t,this._joint){let t={},e=window.box2d,s=r.I._emptyBody,i=this.selfBody.getBody();e.b2LinearStiffness(t,this._frequency,this._dampingRatio,s,i),this._joint.SetStiffness(t.stiffness),this._joint.SetDamping(t.damping)}}get damping(){return this._dampingRatio}set damping(t){if(this._dampingRatio=t,this._joint){let t={},e=window.box2d,s=r.I._emptyBody,i=this.selfBody.getBody();e.b2LinearStiffness(t,this._frequency,this._dampingRatio,s,i),this._joint.SetDamping(t.damping)}}}e.ClassUtils.regClass("laya.physics.joint.MouseJoint",x),e.ClassUtils.regClass("Laya.MouseJoint",x);class A extends d{constructor(){super(...arguments),this.anchor=[0,0],this.axis=[1,0],this.collideConnected=!1,this._enableMotor=!1,this._motorSpeed=0,this._maxMotorForce=1e4,this._enableLimit=!1,this._lowerTranslation=0,this._upperTranslation=0}_createJoint(){if(!this._joint){if(this.selfBody=this.selfBody||this.owner.getComponent(n),!this.selfBody)throw"selfBody can not be empty";var t=window.box2d,s=A._temp||(A._temp=new t.b2PrismaticJointDef),i=this.selfBody.owner.localToGlobal(e.Point.TEMP.setTo(this.anchor[0],this.anchor[1]),!1,r.I.worldRoot),o=new t.b2Vec2(i.x/r.PIXEL_RATIO,i.y/r.PIXEL_RATIO);s.Initialize(this.otherBody?this.otherBody.getBody():r.I._emptyBody,this.selfBody.getBody(),o,new t.b2Vec2(this.axis[0],this.axis[1])),s.enableMotor=this._enableMotor,s.motorSpeed=this._motorSpeed,s.maxMotorForce=this._maxMotorForce,s.enableLimit=this._enableLimit,s.lowerTranslation=this._lowerTranslation/r.PIXEL_RATIO,s.upperTranslation=this._upperTranslation/r.PIXEL_RATIO,s.collideConnected=this.collideConnected,this._joint=r.I._createJoint(s)}}get enableMotor(){return this._enableMotor}set enableMotor(t){this._enableMotor=t,this._joint&&this._joint.EnableMotor(t)}get motorSpeed(){return this._motorSpeed}set motorSpeed(t){this._motorSpeed=t,this._joint&&this._joint.SetMotorSpeed(t)}get maxMotorForce(){return this._maxMotorForce}set maxMotorForce(t){this._maxMotorForce=t,this._joint&&this._joint.SetMaxMotorForce(t)}get enableLimit(){return this._enableLimit}set enableLimit(t){this._enableLimit=t,this._joint&&this._joint.EnableLimit(t)}get lowerTranslation(){return this._lowerTranslation}set lowerTranslation(t){this._lowerTranslation=t,this._joint&&this._joint.SetLimits(t,this._upperTranslation)}get upperTranslation(){return this._upperTranslation}set upperTranslation(t){this._upperTranslation=t,this._joint&&this._joint.SetLimits(this._lowerTranslation,t)}}e.ClassUtils.regClass("laya.physics.joint.PrismaticJoint",A),e.ClassUtils.regClass("Laya.PrismaticJoint",A);class f extends d{constructor(){super(...arguments),this.selfAnchor=[0,0],this.otherAnchor=[0,0],this.selfGroundPoint=[0,0],this.otherGroundPoint=[0,0],this.ratio=1.5,this.collideConnected=!1}_createJoint(){if(!this._joint){if(!this.otherBody)throw"otherBody can not be empty";if(this.selfBody=this.selfBody||this.owner.getComponent(n),!this.selfBody)throw"selfBody can not be empty";var t=window.box2d,s=f._temp||(f._temp=new t.b2PulleyJointDef),i=this.otherBody.owner.localToGlobal(e.Point.TEMP.setTo(this.otherAnchor[0],this.otherAnchor[1]),!1,r.I.worldRoot),o=new t.b2Vec2(i.x/r.PIXEL_RATIO,i.y/r.PIXEL_RATIO),h=this.selfBody.owner.localToGlobal(e.Point.TEMP.setTo(this.selfAnchor[0],this.selfAnchor[1]),!1,r.I.worldRoot),a=new t.b2Vec2(h.x/r.PIXEL_RATIO,h.y/r.PIXEL_RATIO),_=this.otherBody.owner.localToGlobal(e.Point.TEMP.setTo(this.otherGroundPoint[0],this.otherGroundPoint[1]),!1,r.I.worldRoot),l=new t.b2Vec2(_.x/r.PIXEL_RATIO,_.y/r.PIXEL_RATIO),m=this.selfBody.owner.localToGlobal(e.Point.TEMP.setTo(this.selfGroundPoint[0],this.selfGroundPoint[1]),!1,r.I.worldRoot),c=new t.b2Vec2(m.x/r.PIXEL_RATIO,m.y/r.PIXEL_RATIO);s.Initialize(this.otherBody.getBody(),this.selfBody.getBody(),l,c,o,a,this.ratio),s.collideConnected=this.collideConnected,this._joint=r.I._createJoint(s)}}}e.ClassUtils.regClass("laya.physics.joint.PulleyJoint",f),e.ClassUtils.regClass("Laya.PulleyJoint",f);class S extends d{constructor(){super(...arguments),this.anchor=[0,0],this.collideConnected=!1,this._enableMotor=!1,this._motorSpeed=0,this._maxMotorTorque=1e4,this._enableLimit=!1,this._lowerAngle=0,this._upperAngle=0}_createJoint(){if(!this._joint){if(this.selfBody=this.selfBody||this.owner.getComponent(n),!this.selfBody)throw"selfBody can not be empty";var t=window.box2d,s=S._temp||(S._temp=new t.b2RevoluteJointDef),i=this.selfBody.owner.localToGlobal(e.Point.TEMP.setTo(this.anchor[0],this.anchor[1]),!1,r.I.worldRoot),o=new t.b2Vec2(i.x/r.PIXEL_RATIO,i.y/r.PIXEL_RATIO);s.Initialize(this.otherBody?this.otherBody.getBody():r.I._emptyBody,this.selfBody.getBody(),o),s.enableMotor=this._enableMotor,s.motorSpeed=this._motorSpeed,s.maxMotorTorque=this._maxMotorTorque,s.enableLimit=this._enableLimit,s.lowerAngle=this._lowerAngle,s.upperAngle=this._upperAngle,s.collideConnected=this.collideConnected,this._joint=r.I._createJoint(s)}}get enableMotor(){return this._enableMotor}set enableMotor(t){this._enableMotor=t,this._joint&&this._joint.EnableMotor(t)}get motorSpeed(){return this._motorSpeed}set motorSpeed(t){this._motorSpeed=t,this._joint&&this._joint.SetMotorSpeed(t)}get maxMotorTorque(){return this._maxMotorTorque}set maxMotorTorque(t){this._maxMotorTorque=t,this._joint&&this._joint.SetMaxMotorTorque(t)}get enableLimit(){return this._enableLimit}set enableLimit(t){this._enableLimit=t,this._joint&&this._joint.EnableLimit(t)}get lowerAngle(){return this._lowerAngle}set lowerAngle(t){this._lowerAngle=t,this._joint&&this._joint.SetLimits(t,this._upperAngle)}get upperAngle(){return this._upperAngle}set upperAngle(t){this._upperAngle=t,this._joint&&this._joint.SetLimits(this._lowerAngle,t)}}e.ClassUtils.regClass("laya.physics.joint.RevoluteJoint",S),e.ClassUtils.regClass("Laya.RevoluteJoint",S);class w extends d{constructor(){super(...arguments),this.anchor=[0,0],this.collideConnected=!1,this._frequency=5,this._dampingRatio=.7}_createJoint(){if(!this._joint){if(!this.otherBody)throw"otherBody can not be empty";if(this.selfBody=this.selfBody||this.owner.getComponent(n),!this.selfBody)throw"selfBody can not be empty";var t=window.box2d,s=w._temp||(w._temp=new t.b2WeldJointDef),i=this.selfBody.owner.localToGlobal(e.Point.TEMP.setTo(this.anchor[0],this.anchor[1]),!1,r.I.worldRoot),o=new t.b2Vec2(i.x/r.PIXEL_RATIO,i.y/r.PIXEL_RATIO);s.Initialize(this.otherBody.getBody(),this.selfBody.getBody(),o),t.b2AngularStiffness(s,this._frequency,this._dampingRatio,s.bodyA,s.bodyB),s.collideConnected=this.collideConnected,this._joint=r.I._createJoint(s)}}get frequency(){return this._frequency}set frequency(t){if(this._frequency=t,this._joint){let t={},e=window.box2d,s=this.otherBody?this.otherBody.getBody():r.I._emptyBody,i=this.selfBody.getBody();e.b2AngularStiffness(t,this._frequency,this._dampingRatio,s,i),this._joint.SetStiffness(t.stiffness),this._joint.SetDamping(t.damping)}}get damping(){return this._dampingRatio}set damping(t){if(this._dampingRatio=t,this._joint){let t={},e=window.box2d,s=this.otherBody?this.otherBody.getBody():r.I._emptyBody,i=this.selfBody.getBody();e.b2AngularStiffness(t,this._frequency,this._dampingRatio,s,i),this._joint.SetDamping(t.damping)}}}e.ClassUtils.regClass("laya.physics.joint.WeldJoint",w),e.ClassUtils.regClass("Laya.WeldJoint",w);class g extends d{constructor(){super(...arguments),this.anchor=[0,0],this.collideConnected=!1,this.axis=[1,0],this._frequency=5,this._dampingRatio=.7,this._enableMotor=!1,this._motorSpeed=0,this._maxMotorTorque=1e4,this._enableLimit=!0,this._lowerTranslation=0,this._upperTranslation=0}_createJoint(){if(!this._joint){if(!this.otherBody)throw"otherBody can not be empty";if(this.selfBody=this.selfBody||this.owner.getComponent(n),!this.selfBody)throw"selfBody can not be empty";var t=window.box2d,s=g._temp||(g._temp=new t.b2WheelJointDef),i=this.selfBody.owner.localToGlobal(e.Point.TEMP.setTo(this.anchor[0],this.anchor[1]),!1,r.I.worldRoot),o=new t.b2Vec2(i.x/r.PIXEL_RATIO,i.y/r.PIXEL_RATIO);s.Initialize(this.otherBody.getBody(),this.selfBody.getBody(),o,new t.b2Vec2(this.axis[0],this.axis[1])),s.enableMotor=this._enableMotor,s.motorSpeed=this._motorSpeed,s.maxMotorTorque=this._maxMotorTorque,t.b2LinearStiffness(s,this._frequency,this._dampingRatio,s.bodyA,s.bodyB),s.collideConnected=this.collideConnected,s.enableLimit=this._enableLimit,s.lowerTranslation=this._lowerTranslation/r.PIXEL_RATIO,s.upperTranslation=this._upperTranslation/r.PIXEL_RATIO,this._joint=r.I._createJoint(s)}}get frequency(){return this._frequency}set frequency(t){if(this._frequency=t,this._joint){let t={},e=window.box2d,s=this.otherBody?this.otherBody.getBody():r.I._emptyBody,i=this.selfBody.getBody();e.b2LinearStiffness(t,this._frequency,this._dampingRatio,s,i),this._joint.SetStiffness(t.stiffness),this._joint.SetDamping(t.damping)}}get damping(){return this._dampingRatio}set damping(t){if(this._dampingRatio=t,this._joint){let t={},e=window.box2d,s=this.otherBody?this.otherBody.getBody():r.I._emptyBody,i=this.selfBody.getBody();e.b2LinearStiffness(t,this._frequency,this._dampingRatio,s,i),this._joint.SetDamping(t.damping)}}get enableMotor(){return this._enableMotor}set enableMotor(t){this._enableMotor=t,this._joint&&this._joint.EnableMotor(t)}get motorSpeed(){return this._motorSpeed}set motorSpeed(t){this._motorSpeed=t,this._joint&&this._joint.SetMotorSpeed(t)}get maxMotorTorque(){return this._maxMotorTorque}set maxMotorTorque(t){this._maxMotorTorque=t,this._joint&&this._joint.SetMaxMotorTorque(t)}get enableLimit(){return this._enableLimit}set enableLimit(t){this._enableLimit=t,this._joint&&this._joint.EnableLimit(t)}get lowerTranslation(){return this._lowerTranslation}set lowerTranslation(t){this._lowerTranslation=t,this._joint&&this._joint.SetLimits(t,this._upperTranslation)}get upperTranslation(){return this._upperTranslation}set upperTranslation(t){this._upperTranslation=t,this._joint&&this._joint.SetLimits(this._lowerTranslation,t)}}e.ClassUtils.regClass("laya.physics.joint.WheelJoint",g),e.ClassUtils.regClass("Laya.WheelJoint",g),t.BoxCollider=a,t.ChainCollider=_,t.CircleCollider=l,t.ColliderBase=i,t.DestructionListener=o,t.DistanceJoint=p,t.EdgeCollider=m,t.GearJoint=y,t.IPhysics=s,t.JointBase=d,t.MotorJoint=b,t.MouseJoint=x,t.Physics=r,t.PhysicsDebugDraw=c,t.PolygonCollider=u,t.PrismaticJoint=A,t.PulleyJoint=f,t.RevoluteJoint=S,t.RigidBody=n,t.WeldJoint=w,t.WheelJoint=g}(window.Laya=window.Laya||{},Laya); \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/min/laya.physics3D.min.js b/examples/layaair/frontend/bin/libs/min/laya.physics3D.min.js new file mode 100644 index 0000000..e1792f6 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/min/laya.physics3D.min.js @@ -0,0 +1 @@ +window.Physics3D=function(t,e){var i=window.Physics3D={};return i.then=t=>{t(i)},function(t,e,i){var r=e.getWorldTransform,n=e.setWorldTransform;window.atob||(window.atob=function(t){var e=String(t).replace(/[=]+$/,"");if(e.length%4==1)throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded.");for(var i,r,n=0,a=0,o="";r=e.charAt(a++);~r&&(i=n%4?64*i+r:r,n++%4)?o+=String.fromCharCode(255&i>>(-2*n&6)):0)r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(r);return o});var a=new ArrayBuffer(8),o=new Int32Array(a),f=new Float32Array(a),_=new Float64Array(a);function c(t){return o[t]}function b(t,e){o[t]=e}function l(){return _[0]}function u(t){_[0]=t}function s(t){f[0]=t}function k(){return f[0]}var h=new ArrayBuffer(t),d=function(t){var e=new Uint8Array(t);return function(t,i){var r,n;if("undefined"==typeof Buffer)for(r=atob(i),n=0;n>2],Z=r+16|0,n}function I(t){var e=0;return e=f[t+60>>2],f[t+60>>2]=e+-1|e,8&(e=f[t>>2])?(f[t>>2]=32|e,-1):(f[t+4>>2]=0,f[t+8>>2]=0,e=f[t+40>>2],f[t+24>>2]=e,f[t+20>>2]=e,f[t+16>>2]=e+f[t+44>>2],0)}function J(t,e,i){var r=0,a=0,o=0,h=0,d=0,C=0,g=0;t:if(!i|!(3&e))r=i;else for(;;){if(n[0|t]=_[0|e],r=i+-1|0,t=t+1|0,e=e+1|0,1==(0|i))break t;if(i=r,!(3&e))break}t:{if(!(i=3&t)){if(r>>>0<16)i=r;else for(i=r+-16|0;f[t>>2]=f[e>>2],f[t+4>>2]=f[e+4>>2],f[t+8>>2]=f[e+8>>2],f[t+12>>2]=f[e+12>>2],t=t+16|0,e=e+16|0,(r=r+-16|0)>>>0>15;);if(8&i&&(r=f[e+4>>2],f[t>>2]=f[e>>2],f[t+4>>2]=r,e=e+8|0,t=t+8|0),4&i&&(f[t>>2]=f[e>>2],e=e+4|0,t=t+4|0),2&i&&(n[0|t]=_[0|e],n[t+1|0]=_[e+1|0],e=e+2|0,t=t+2|0),!(1&i))break t;return void(n[0|t]=_[0|e])}e:if(!(r>>>0<32||(i=i+-1|0,i>>>0>2))){switch(i-1|0){default:for(n[t+1|0]=_[e+1|0],a=f[e>>2],n[0|t]=a,n[t+2|0]=_[e+2|0],d=r+-3|0,C=t+3|0,g=r+-20&-16,i=0;t=i+C|0,o=f[(h=e+i|0)+4>>2],f[t>>2]=o<<8|a>>>24,a=f[h+8>>2],f[t+4>>2]=a<<8|o>>>24,o=f[h+12>>2],f[t+8>>2]=o<<8|a>>>24,a=f[h+16>>2],f[t+12>>2]=a<<8|o>>>24,i=i+16|0,(d=d+-16|0)>>>0>16;);t=i+C|0,e=3+(e+i|0)|0,r=(r-g|0)-19|0;break e;case 0:for(a=f[e>>2],n[0|t]=a,n[t+1|0]=_[e+1|0],d=r+-2|0,C=t+2|0,g=r+-20&-16,i=0;t=i+C|0,o=f[(h=e+i|0)+4>>2],f[t>>2]=o<<16|a>>>16,a=f[h+8>>2],f[t+4>>2]=a<<16|o>>>16,o=f[h+12>>2],f[t+8>>2]=o<<16|a>>>16,a=f[h+16>>2],f[t+12>>2]=a<<16|o>>>16,i=i+16|0,(d=d+-16|0)>>>0>17;);t=i+C|0,e=2+(e+i|0)|0,r=(r-g|0)-18|0;break e;case 1:}for(a=f[e>>2],n[0|t]=a,d=r+-1|0,C=t+1|0,g=r+-20&-16,i=0;t=i+C|0,o=f[(h=e+i|0)+4>>2],f[t>>2]=o<<24|a>>>8,a=f[h+8>>2],f[t+4>>2]=a<<24|o>>>8,o=f[h+12>>2],f[t+8>>2]=o<<24|a>>>8,a=f[h+16>>2],f[t+12>>2]=a<<24|o>>>8,i=i+16|0,(d=d+-16|0)>>>0>18;);t=i+C|0,e=1+(e+i|0)|0,r=(r-g|0)-17|0}16&r&&(i=_[0|e]|_[e+1|0]<<8,n[0|t]=i,n[t+1|0]=i>>>8,n[t+2|0]=_[e+2|0],n[t+3|0]=_[e+3|0],n[t+4|0]=_[e+4|0],n[t+5|0]=_[e+5|0],n[t+6|0]=_[e+6|0],n[t+7|0]=_[e+7|0],n[t+8|0]=_[e+8|0],n[t+9|0]=_[e+9|0],n[t+10|0]=_[e+10|0],n[t+11|0]=_[e+11|0],n[t+12|0]=_[e+12|0],n[t+13|0]=_[e+13|0],n[t+14|0]=_[e+14|0],n[t+15|0]=_[e+15|0],e=e+16|0,t=t+16|0),8&r&&(n[0|t]=_[0|e],n[t+1|0]=_[e+1|0],n[t+2|0]=_[e+2|0],n[t+3|0]=_[e+3|0],n[t+4|0]=_[e+4|0],n[t+5|0]=_[e+5|0],n[t+6|0]=_[e+6|0],n[t+7|0]=_[e+7|0],e=e+8|0,t=t+8|0),4&r&&(n[0|t]=_[0|e],n[t+1|0]=_[e+1|0],n[t+2|0]=_[e+2|0],n[t+3|0]=_[e+3|0],e=e+4|0,t=t+4|0),2&r&&(n[0|t]=_[0|e],n[t+1|0]=_[e+1|0],e=e+2|0,t=t+2|0),1&r&&(n[0|t]=_[0|e])}}function x(t,e,i){var r=0,n=0,a=0,o=0,h=0;t:{if(!(r=f[i+16>>2])){if(I(i))break t;r=f[i+16>>2]}if(r-(a=f[i+20>>2])>>>0>>0)return void yt[f[i+32>>2]](i,t,e);e:if(!(f[i+64>>2]<0)){for(r=t;;){if((0|e)==(0|n))break e;if(n=n+1|0,h=e+r|0,r=o=r+-1|0,10==_[h+-1|0])break}if(r=t,t=1+(e-n|0)|0,yt[f[i+32>>2]](i,r,t)>>>0>>0)break t;t=1+(e+o|0)|0,a=f[i+20>>2],e=n+-1|0}J(a,t,e),f[i+20>>2]=f[i+20>>2]+e}}function U(t){var e=0,i=0,r=0;f[265]||(f[265]=1036);t:{e:{for(;;){if((0|t)!=_[e+3024|0]){if(i=77,77!=(0|(e=e+1|0)))continue;break e}break}if(i=e,!e){t=3104;break t}}for(e=3104;r=_[0|e],e=t=e+1|0,r||(e=t,i=i+-1|0););}return t}function M(t,e){var i=0,r=0;r=0!=(0|e);t:{e:{i:if(e)if(3&t)for(;;){if(!_[0|t]){i=e;break e}if(r=1!=(0|e),i=e+-1|0,t=t+1|0,1==(0|e))break i;if(e=i,!(3&t))break}else i=e;else i=e;if(!r)break t}e:if(!(!_[0|t]|i>>>0<4))for(;;){if((-1^(e=f[t>>2]))&e+-16843009&-2139062144)break e;if(t=t+4|0,!((i=i+-4|0)>>>0>3))break}if(i)for(;;){if(!_[0|t])return t;if(t=t+1|0,!(i=i+-1|0))break}}return 0}function S(t,e){return t?function(t,e){if(t){if(e>>>0<=127)return n[0|t]=e,1;t:{if(!f[259]){if(57216!=(-128&e))break t;return n[0|t]=e,1}if(e>>>0<=2047)return n[t+1|0]=63&e|128,n[0|t]=e>>>6|192,2;if(!(57344!=(-8192&e)&&e>>>0>=55296))return n[t+2|0]=63&e|128,n[0|t]=e>>>12|224,n[t+1|0]=e>>>6&63|128,3;if(e+-65536>>>0<=1048575)return n[t+3|0]=63&e|128,n[0|t]=e>>>18|240,n[t+2|0]=e>>>6&63|128,n[t+1|0]=e>>>12&63|128,4}f[256]=25,t=-1}else t=1;return t}(t,e):0}function X(t,e,i){var r=0,a=0,o=0,_=0;if(i&&(n[0|t]=e,n[(r=t+i|0)+-1|0]=e,!(i>>>0<3||(n[t+2|0]=e,n[t+1|0]=e,n[r+-3|0]=e,n[r+-2|0]=e,i>>>0<7||(n[t+3|0]=e,n[r+-4|0]=e,i>>>0<9||(r=0-t&3,a=r+t|0,e=m(255&e,16843009),f[a>>2]=e,i=i-r&-4,r=i+a|0,f[r+-4>>2]=e,i>>>0<9||(f[a+8>>2]=e,f[a+4>>2]=e,f[r+-8>>2]=e,f[r+-12>>2]=e,i>>>0<25||(f[a+24>>2]=e,f[a+20>>2]=e,f[a+16>>2]=e,f[a+12>>2]=e,f[r+-16>>2]=e,f[r+-20>>2]=e,f[r+-24>>2]=e,f[r+-28>>2]=e,_=4&a|24,i=i-_|0,i>>>0<32))))))))for(r=e,o=e,e=a+_|0;f[e>>2]=o,f[e+4>>2]=r,f[(a=e+24|0)>>2]=o,f[a+4>>2]=r,f[(a=e+16|0)>>2]=o,f[a+4>>2]=r,f[(a=e+8|0)>>2]=o,f[a+4>>2]=r,e=e+32|0,(i=i+-32|0)>>>0>31;);return t}function T(t,e){var i,r,n=0;if(u(+t),n=0|c(1),i=0|c(0),r=n,2047!=(0|(n=n>>>20&2047))){if(!n)return 0==t?(f[e>>2]=0,t):(t=T(0x10000000000000000*t,e),f[e>>2]=f[e>>2]+-64,t);f[e>>2]=n+-1022,b(0,0|i),b(1,-2146435073&r|1071644672),t=+l()}return t}function j(t,e,i){var r,n=0,a=0;if(Z=r=Z-208|0,f[r+204>>2]=i,f[(n=r+192|0)>>2]=0,f[n+4>>2]=0,f[(n=r+184|0)>>2]=0,f[n+4>>2]=0,f[(n=r+176|0)>>2]=0,f[n+4>>2]=0,f[r+168>>2]=0,f[r+172>>2]=0,f[r+160>>2]=0,f[r+164>>2]=0,f[r+200>>2]=i,(0|O(0,e,r+200|0,r+80|0,r+160|0))>=0){a=f[t>>2],f[t+60>>2]<=0&&(f[t>>2]=-33&a);t:{e:{if(f[t+44>>2]){if(n=0,f[t+16>>2])break e}else f[t+44>>2]=80,f[t+24>>2]=0,f[t+16>>2]=0,f[t+20>>2]=0,n=f[t+40>>2],f[t+40>>2]=r;if(i=-1,I(t))break t}i=O(t,e,r+200|0,r+80|0,r+160|0)}n&&(yt[f[t+32>>2]](t,0,0),f[t+44>>2]=0,f[t+40>>2]=n,f[t+24>>2]=0,f[t+16>>2]=0,f[t+20>>2]=0,i=0),f[t>>2]=f[t>>2]|32&a}Z=r+208|0}function O(t,e,i,r,o){var h,d,C,v,p,R,D,B,E,F=0,G=0,w=0,Q=0,W=0,Y=0,yt=0,pt=0,Dt=0,It=0,St=0,Tt=0,Et=0,Ot=0,Nt=0,Ft=0,Vt=0,Gt=0,Lt=0,wt=0,xt=0,Qt=0,Wt=0,Yt=0,Pt=0,Mt=0,Zt=0;Z=h=Z-880|0,R=h+336|8,D=h+55|0,B=-338-h|0,v=h+336|9,E=h+656|0,C=h+336|0,p=0-(h+336|0)|0,d=h+56|0;t:{e:{i:for(;;){A:if(Q=e,!((0|F)>(2147483647-Gt|0))){Gt=F+Gt|0;r:{n:{a:{if(F=_[0|Q])for(;;){o:{s:if(G=255&F){if(37!=(0|G))break o;for(F=G=e;;){if(37!=_[F+1|0]){e=F;break s}if(G=G+1|0,w=_[F+2|0],F=e=F+2|0,37!=(0|w))break}}else G=e;if((0|(F=G-Q|0))>(0|(Vt=2147483647-Gt|0)))break A;if(!t|32&_[0|t]||x(Q,F,t),F)continue i;F=e+1|0,It=-1,(G=(Y=n[e+1|0])+-48|0)>>>0>9||(F=(w=36==_[e+2|0])?e+3|0:F,Qt=w?1:Qt,Y=n[(w?3:1)+e|0],It=w?G:-1),W=0;s:if(!((e=Y+-32|0)>>>0>31)&&(e=1<>>0>=32)break s;if(w=F+1|0,!(75913&(e=1<>>0>9)yt=F;else{for(e=0;St=-1,G=n[F+1|0],F=yt=F+1|0,e>>>0<=214748364&&(St=(0|w)>(2147483647-(e=m(e,10))|0)?-1:e+w|0),e=St,(w=G+-48|0)>>>0<10;);if((0|St)<0)break A}else{if(e=n[F+1|0]+-48|0,36!=_[F+2|0]|e>>>0>9){if(Qt)break a;if(yt=F+1|0,!t){Qt=0,St=0;break s}e=f[i>>2],f[i>>2]=e+4,Qt=0,St=f[e>>2]}else f[(e<<2)+o>>2]=10,yt=F+3|0,Qt=1,St=f[((n[F+1|0]<<3)+r|0)-384>>2];if((0|St)>-1)break s;St=0-St|0,W|=8192}if(F=0,Y=-1,46==_[0|yt])if(42!=(0|(G=n[yt+1|0])))if(e=yt+1|0,(Dt=G+-48|0)>>>0>9)pt=1,Y=0;else for(yt=0,w=e;Y=-1,yt>>>0<=214748364&&(Y=(0|Dt)>(2147483647-(e=m(yt,10))|0)?-1:e+Dt|0),pt=1,G=n[w+1|0],w=e=w+1|0,yt=Y,(Dt=G+-48|0)>>>0<10;);else{if(e=n[yt+2|0]+-48|0,36!=_[yt+3|0]|e>>>0>9){if(Qt)break a;e=yt+2|0,Y=0,t&&(G=f[i>>2],f[i>>2]=G+4,Y=f[G>>2])}else f[(e<<2)+o>>2]=10,e=yt+4|0,Y=f[((n[yt+2|0]<<3)+r|0)-384>>2];pt=(-1^Y)>>>31}else e=yt,pt=0;for(;;){if(w=F,(G=n[0|e]+-65|0)>>>0>57)break a;if(e=e+1|0,!((F=_[4704+(G+m(w,58)|0)|0])+-1>>>0<8))break}if(!F)break a;s:{l:{f:{if(27==(0|F)){if((0|It)<=-1)break f;break a}if((0|It)<0)break l;f[(It<<2)+o>>2]=F,G=f[(F=(It<<3)+r|0)+4>>2],f[h+56>>2]=f[F>>2],f[h+60>>2]=G}if(F=0,!t)continue i;break s}if(!t){Gt=0;break t}H(h+56|0,F,i)}G=-65537&W,It=8192&W?G:W;s:{l:{f:if(F=n[e+-1|0],wt=w&&3==(15&F)?-33&F:F,F=wt+-65|0,!(F>>>0>55)){c:{b:{_:{u:{h:{d:{C:{k:{g:{m:{v:{y:switch(F-1|0){case 51:Dt=0,W=f[h+56>>2],F=f[h+60>>2],Nt=4678;break v;case 44:if(F=0,(G=255&w)>>>0>7)continue i;switch(G-1|0){default:case 0:f[f[h+56>>2]>>2]=Gt;continue i;case 1:G=f[h+56>>2],f[G>>2]=Gt,f[G+4>>2]=Gt>>31;continue i;case 2:a[f[h+56>>2]>>1]=Gt;continue i;case 3:n[f[h+56>>2]]=Gt;continue i;case 5:f[f[h+56>>2]>>2]=Gt;continue i;case 4:continue i;case 6:}G=f[h+56>>2],f[G>>2]=Gt,f[G+4>>2]=Gt>>31;continue i;case 46:Y=Y>>>0>8?Y:8,It|=8,wt=120;case 22:case 54:if(Dt=0,Nt=4678,!((F=G=f[h+60>>2])|(W=f[h+56>>2]))){Q=d;break m}for(G=32&wt,Q=d;n[0|(Q=Q+-1|0)]=G|_[5312+(15&W)|0],(W=(15&F)<<28|W>>>4)|(F>>>=4););if(!(8&It)|!(f[h+56>>2]|f[h+60>>2]))break m;Nt=4678+(wt>>4)|0,Dt=2;break m;case 45:if(Q=d,(F=G=f[h+60>>2])|(W=f[h+56>>2]))for(;n[0|(Q=Q+-1|0)]=7&W|48,(W=(7&F)<<29|W>>>3)|(F>>>=3););if(Dt=0,Nt=4678,!(8&It))break m;Y=(0|Y)>(0|(G=d-Q|0))?Y:G+1|0;break m;case 0:case 2:case 6:case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:case 15:case 16:case 18:case 19:case 20:case 21:case 23:case 24:case 25:case 26:case 27:case 28:case 29:case 30:case 32:case 38:case 40:case 41:case 42:case 47:case 48:case 50:case 52:case 53:break f;case 1:break u;case 17:break h;case 49:break C;case 43:break k;case 33:break g;case 34:case 39:break y;default:break c}F=G=f[h+60>>2],W=f[h+56>>2],(0|F)>-1||(0|F)>=-1&&!(W>>>0<=4294967295)?2048&It?(Dt=1,Nt=4679):Nt=(Dt=1&It)?4680:4678:(F=0-((0>>0)+F|0)|0,W=0-W|0,f[h+56>>2]=W,f[h+60>>2]=F,Dt=1,Nt=4678)}if(1==(0|F)&W>>>0>=0|F>>>0>1)for(Q=d;Pt=Q=Q+-1|0,Mt=W-_t(G=mt(W,F,10),w=yt=z,10,0)|48,n[0|Pt]=Mt,yt=9==(0|F)&W>>>0>4294967295|F>>>0>9,W=G,F=w,yt;);else G=W,Q=d;if(F=G)for(;G=(F>>>0)/10|0,n[0|(Q=Q+-1|0)]=F-m(G,10)|48,w=F>>>0>9,F=G,w;);}if((0|Y)<0&&pt)break A;if(It=pt?-65537&It:It,!(!!((F=f[h+56>>2])|(G=f[h+60>>2]))|Y)){F=Q=d,Y=0;break r}Y=(0|Y)>(0|(G=!(F|G)+(d-Q|0)|0))?Y:G;break l}n[h+55|0]=f[h+56>>2],Dt=0,Nt=4678,Y=1,Q=D,F=d,It=G;break r}Q=U(f[256]);break d}Q=(F=f[h+56>>2])||4688}if(Dt=0,F=(w=(F=M(Q,w=(0|Y)<0?2147483647:Y))?F-Q|0:w)+Q|0,Nt=4678,(0|Y)<=-1)break s;It=G,Y=w;break r}if(G=Q=f[h+56>>2],Y)break _;F=0;break b}f[h+12>>2]=0,f[h+8>>2]=f[h+56>>2],f[h+56>>2]=h+8,Y=-1,G=h+8|0}F=0,G=Q=G;_:{for(;;){if(!(w=f[G>>2]))break _;if(!((w=(0|(W=S(h+4|0,w)))<0)|W>>>0>Y-F>>>0)){if(G=G+4|0,Y>>>0>(F=F+W|0)>>>0)continue;break _}break}if(w)break e}if((0|F)<0)break A}b:if(!((yt=73728&It)|(0|St)<=(0|F))){if(X(h- -64|0,32,(w=(Dt=St-F|0)>>>0<256)?Dt:256),G=32&(Y=f[t>>2]),w){if(G)break b}else{for(G=!G,w=Dt;1&G&&(x(h- -64|0,256,t),Y=f[t>>2]),G=!(W=32&Y),(w=w+-256|0)>>>0>255;);if(W)break b;Dt&=255}x(h- -64|0,Dt,t)}b:if(F)for(G=0;;){if(!(w=f[Q>>2]))break b;if((G=(w=S(h+4|0,w))+G|0)>>>0>F>>>0)break b;if(32&_[0|t]||x(h+4|0,w,t),Q=Q+4|0,!(G>>>0>>0))break}b:if(!(8192!=(0|yt)|(0|St)<=(0|F))){if(X(h- -64|0,32,(w=(W=St-F|0)>>>0<256)?W:256),G=32&(Q=f[t>>2]),w){if(G)break b}else{for(G=!G,w=W;1&G&&(x(h- -64|0,256,t),Q=f[t>>2]),G=!(yt=32&Q),(w=w+-256|0)>>>0>255;);if(yt)break b;W&=255}x(h- -64|0,W,t)}F=(0|St)>(0|F)?St:F;continue i}if(pt&&(0|Y)<=-1)break A;Tt=g[h+56>>3],f[h+364>>2]=0,u(+Tt),G=0|c(1),Pt=1,Zt=c(0)>>>0<=4294967295?0:1,Mt=(0|G)>=-1?Zt:0,((0|G)>-1?Pt:Mt)?2048&It?(xt=1,Wt=5331):Wt=(xt=1&It)?5334:5329:(Tt=-Tt,xt=1,Wt=5328);c:if((Lt=y(Tt))!=V&Lt==Lt)if(Lt=T(Tt,h+364|0),Tt=Lt+Lt,0!=Tt&&(f[h+364>>2]=f[h+364>>2]+-1),Ft=32|wt,97!=(0|Ft)){for(G=(0|Y)<0,0!=Tt?(Q=f[h+364>>2]+-28|0,f[h+364>>2]=Q,Tt*=268435456):Q=f[h+364>>2],pt=G?6:Y,w=Vt=(0|Q)<0?h+368|0:E;G=Tt<4294967296&Tt>=0?~~Tt>>>0:0,f[w>>2]=G,w=w+4|0,0!=(Tt=1e9*(Tt-+(G>>>0))););if((0|Q)<1)F=w,G=Vt;else for(G=Vt;;){if(Dt=(0|Q)<29?Q:29,!((F=w+-4|0)>>>0>>0)){for(Y=Dt,W=0;Q=F,Et=f[F>>2],Ot=31&Y,32<=(63&Y)>>>0?(yt=Et<>>32-Ot,Ot=Et<>>0>>0?yt+1|0:yt,1e9),z,1e9,0)|0,f[Pt>>2]=Mt,(F=F+-4|0)>>>0>=G>>>0;);W&&(f[(G=G+-4|0)>>2]=W)}for(;(F=w)>>>0>G>>>0&&!f[(w=F+-4|0)>>2];);if(Q=f[h+364>>2]-Dt|0,f[h+364>>2]=Q,w=F,!((0|Q)>0))break}if((0|Q)<=-1)for(Dt=1+((pt+25>>>0)/9|0)|0;;){if(Et=(0|(w=0-Q|0))<9?w:9,G>>>0>=F>>>0)G=f[G>>2]?G:G+4|0;else{for(Y=1e9>>>Et,yt=-1<>2],f[w>>2]=Q+(W>>>Et),Q=m(Y,W&yt),(w=w+4|0)>>>0>>0;);G=f[G>>2]?G:G+4|0,Q&&(f[F>>2]=Q,F=F+4|0)}if(Q=Et+f[h+364>>2]|0,f[h+364>>2]=Q,F=F-(w=102==(0|Ft)?Vt:G)>>2>(0|Dt)?w+(Dt<<2)|0:F,!((0|Q)<0))break}if(w=0,!(G>>>0>=F>>>0||(w=m(Vt-G>>2,9),W=f[G>>2],W>>>0<10)))for(Q=10;w=w+1|0,W>>>0>=(Q=m(Q,10))>>>0;);if((0|(Q=(pt-(Ot=102==(0|Ft)?0:w)|0)-(Et=(Ft=103==(0|Ft))&0!=(0|pt))|0))<(m(F-Vt>>2,9)+-9|0)){if(W=(Dt=Vt+((yt=(0|(Y=Q+9216|0))/9|0)<<2)|0)+-4092|0,Q=10,(1+(Y-(yt=m(yt,9))|0)|0)<=8)for(Y=((Et+(yt+Ot|0)|0)-pt|0)-9208|0;Q=m(Q,10),Y=Y+-1|0;);if(Y=W+4|0,((Ot=(Et=f[W>>2])-m(Q,yt=(Et>>>0)/(Q>>>0)|0)|0)||(0|F)!=(0|Y))&&(!(1&yt)&&(Tt=9007199254740992,!(1&n[W+-4|0])|1e9!=(0|Q)|W>>>0<=G>>>0)||(Tt=9007199254740994),Lt=.5,Ot>>>0>=(yt=Q>>>1)>>>0&&(Lt=(0|F)==(0|Y)&&(0|yt)==(0|Ot)?1:1.5),!xt|45!=_[0|Wt]||(Tt=-Tt,Lt=-Lt),yt=Et-Ot|0,f[W>>2]=yt,Tt+Lt!=Tt)){if(w=Q+yt|0,f[W>>2]=w,w>>>0>=1e9){for(w=Dt+-4096|0;f[w+4>>2]=0,w>>>0>>0&&(f[(G=G+-4|0)>>2]=0),Q=f[w>>2]+1|0,f[w>>2]=Q,w=w+-4|0,Q>>>0>999999999;);W=w+4|0}if(w=m(Vt-G>>2,9),!((yt=f[G>>2])>>>0<10))for(Q=10;w=w+1|0,yt>>>0>=(Q=m(Q,10))>>>0;);}F=F>>>0>(Q=W+4|0)>>>0?Q:F}b:{for(;;){if(Y=F,Ot=0,F>>>0<=G>>>0)break b;if(f[(F=Y+-4|0)>>2])break}Ot=1}if(Ft){if(pt=((F=(0|(Q=pt||1))>(0|w)&(0|w)>-5)?-1^w:-1)+Q|0,wt=(F?-1:-2)+wt|0,!(Dt=8&It)){if(F=9,Ot&&((W=f[Y+-4>>2])&&(F=0,!((W>>>0)%10))))for(Q=10;F=F+1|0,!((W>>>0)%((Q=m(Q,10))>>>0)););Q=m(Y-Vt>>2,9)+-9|0,102!=(32|wt)?(Dt=0,pt=(0|pt)<(0|(F=(0|(F=(w+Q|0)-F|0))>0?F:0))?pt:F):(Dt=0,pt=(0|pt)<(0|(F=(0|(F=Q-F|0))>0?F:0))?pt:F)}}else Dt=8&It;if(F=-1,!((0|pt)>(0|((Ft=pt|Dt)?2147483645:2147483646)))){if(Nt=1+((0!=(0|Ft))+pt|0)|0,Et=102!=(32|wt)){if(Q=C,F=w>>31,F^=F+w)for(;W=(F>>>0)/10|0,n[0|(Q=Q+-1|0)]=F-m(W,10)|48,yt=F>>>0>9,F=W,yt;);if((C-Q|0)<=1){for(F=Q+-1|0;n[0|F]=48,W=C-F|0,F=Q=F+-1|0,(0|W)<2;);Q=Q+1|0}if(n[0|(Yt=Q+-2|0)]=wt,F=-1,n[Q+-1|0]=(0|w)<0?45:43,(0|(w=C-Yt|0))>(2147483647-Nt|0))break c}else{if((0|w)>(2147483647-Nt|0))break c;w=(0|w)>0?w:0}if(!((0|(w=w+Nt|0))>(2147483647^xt))){b:if(!((It&=73728)|(0|St)<=(0|(Nt=w+xt|0)))){if(X(h- -64|0,32,(w=(yt=St-Nt|0)>>>0<256)?yt:256),F=32&(Q=f[t>>2]),w){if(F)break b}else{for(F=!F,w=yt;1&F&&(x(h- -64|0,256,t),Q=f[t>>2]),F=!(W=32&Q),(w=w+-256|0)>>>0>255;);if(W)break b;yt&=255}x(h- -64|0,yt,t)}32&_[0|t]||x(Wt,xt,t);b:if(!(65536!=(0|It)|(0|St)<=(0|Nt))){if(X(h- -64|0,48,(w=(yt=St-Nt|0)>>>0<256)?yt:256),F=32&(Q=f[t>>2]),w){if(F)break b}else{for(F=!F,w=yt;1&F&&(x(h- -64|0,256,t),Q=f[t>>2]),F=!(W=32&Q),(w=w+-256|0)>>>0>255;);if(W)break b;yt&=255}x(h- -64|0,yt,t)}b:if(Et){_:if(!((0|pt)<=-1)){for(Y=Ot?Y:G+4|0,W=G;;){Q=v;u:{if(F=f[W>>2]){for(w=0;Q=(F>>>0)/10|0,n[344+(w+h|0)|0]=F-m(Q,10)|48,w=w+-1|0,yt=F>>>0>9,F=Q,yt;);if(Q=345+(w+h|0)|0,w)break u}n[0|(Q=Q+-1|0)]=48}u:if((0|G)==(0|W))32&_[0|t]||x(Q,1,t),Q=Q+1|0,32&_[0|t]|((0|pt)<1?!Dt:0)||x(5363,1,t);else{if(Q>>>0<=h+336>>>0)break u;for(X(h+336|0,48,Q+p|0);(Q=Q+-1|0)>>>0>h+336>>>0;);}if(F=v-Q|0,32&_[0|t]||x(Q,(0|pt)>(0|F)?F:pt,t),W=W+4|0,!((0|(pt=pt-F|0))>-1&&W>>>0>>0))break}if(!((0|pt)<1)){if(X(h- -64|0,48,(G=pt>>>0<256)?pt:256),F=32&(w=f[t>>2]),G){if(F)break _}else{for(F=!F,G=pt;1&F&&(x(h- -64|0,256,t),w=f[t>>2]),F=!(Q=32&w),(G=G+-256|0)>>>0>255;);if(Q)break _;pt&=255}x(h- -64|0,pt,t)}}32&_[0|t]||x(Yt,C-Yt|0,t)}else{for(W=yt=G>>>0>Vt>>>0?Vt:G;;){if(F=f[W>>2])for(G=0;w=(F>>>0)/10|0,n[G+R|0]=F-m(w,10)|48,G=G+-1|0,Q=F>>>0>9,F=w,Q;);else G=0;F=G+v|0;_:if((0|W)==(0|yt))G||(F=F+-1|0,n[0|F]=48);else{if(F>>>0<=h+336>>>0)break _;X(h+336|0,48,G+9|0),F=h+336|0}if(32&_[0|t]||x(F,v-F|0,t),!((W=W+4|0)>>>0<=Vt>>>0))break}!Ft|32&_[0|t]||x(5363,1,t);_:if(!((0|pt)<1|W>>>0>=Y>>>0))for(;;){F=v;u:{if(G=f[W>>2]){for(;w=(G>>>0)/10|0,n[0|(F=F+-1|0)]=G-m(w,10)|48,Q=G>>>0>9,G=w,Q;);if(F>>>0<=h+336>>>0)break u}for(X(h+336|0,48,F+p|0);(F=F+-1|0)>>>0>h+336>>>0;);}if(32&_[0|t]||x(F,(0|pt)<9?pt:9,t),(0|(pt=pt+-9|0))<1)break _;if(!((W=W+4|0)>>>0>>0))break}if((0|pt)<1)break b;if(X(h- -64|0,48,(G=pt>>>0<256)?pt:256),F=32&(w=f[t>>2]),G){if(F)break b}else{for(F=!F,G=pt;1&F&&(x(h- -64|0,256,t),w=f[t>>2]),F=!(Q=32&w),(G=G+-256|0)>>>0>255;);if(Q)break b;pt&=255}x(h- -64|0,pt,t)}b:if(!(8192!=(0|It)|(0|St)<=(0|Nt))){if(X(h- -64|0,32,(F=(Y=St-Nt|0)>>>0<256)?Y:256),G=32&(w=f[t>>2]),F){if(G)break b}else{for(F=!G,G=Y;1&F&&(x(h- -64|0,256,t),w=f[t>>2]),F=!(Q=32&w),(G=G+-256|0)>>>0>255;);if(Q)break b;Y&=255}x(h- -64|0,Y,t)}F=(0|St)>(0|Nt)?St:Nt}}}else{if(Et=(W=32&wt)?Wt+9|0:Wt,!(!(12-Y)|Y>>>0>11)){for(F=Y+-12|0,Lt=16;Lt*=16,w=(G=F+1|0)>>>0>=F>>>0,F=G,w;);Tt=45!=_[0|Et]?Tt+Lt-Lt:-(Lt+(-Tt-Lt))}w=C;b:{if(F=(G=(yt=f[h+364>>2])>>31)^G+yt){for(G=0;w=(F>>>0)/10|0,n[335+(G+h|0)|0]=F-m(w,10)|48,G=G+-1|0,Q=F>>>0>9,F=w,Q;);if(w=336+(G+h|0)|0,G)break b}n[0|(w=w+-1|0)]=48}for(Dt=2|xt,n[0|(Vt=w+-2|0)]=wt+15,n[w+-1|0]=(0|yt)<0?45:43,Q=8&It,G=h+336|0;F=G,w=y(Tt)<2147483648?~~Tt:-2147483648,n[0|F]=W|_[w+5312|0],1!=((G=F+1|0)-(h+336|0)|0)|(0==(Tt=16*(Tt-+(0|w)))?!((0|Y)>0|Q):0)||(n[F+1|0]=46,G=F+2|0),0!=Tt;);if(F=-1,(2147483645-(w=(yt=C-Vt|0)+Dt|0)|0)<(0|Y))break c;Ft=G-(h+336|0)|0;b:if(!((pt=73728&It)|(0|St)<=(0|(Y=(W=Y&&(G+B|0)<(0|Y)?Y+2|0:Ft)+w|0)))){if(X(h- -64|0,32,(F=(It=St-Y|0)>>>0<256)?It:256),G=32&(w=f[t>>2]),F){if(G)break b}else{for(F=!G,G=It;1&F&&(x(h- -64|0,256,t),w=f[t>>2]),F=!(Q=32&w),(G=G+-256|0)>>>0>255;);if(Q)break b;It&=255}x(h- -64|0,It,t)}32&_[0|t]||x(Et,Dt,t);b:if(!(65536!=(0|pt)|(0|St)<=(0|Y))){if(X(h- -64|0,48,(F=(Dt=St-Y|0)>>>0<256)?Dt:256),G=32&(w=f[t>>2]),F){if(G)break b}else{for(F=!G,G=Dt;1&F&&(x(h- -64|0,256,t),w=f[t>>2]),F=!(Q=32&w),(G=G+-256|0)>>>0>255;);if(Q)break b;Dt&=255}x(h- -64|0,Dt,t)}32&_[0|t]||x(h+336|0,Ft,t);b:if(!((0|(W=W-Ft|0))<1)){if(X(h- -64|0,48,(G=W>>>0<256)?W:256),F=32&(w=f[t>>2]),G){if(F)break b}else{for(F=!F,G=W;1&F&&(x(h- -64|0,256,t),w=f[t>>2]),F=!(Q=32&w),(G=G+-256|0)>>>0>255;);if(Q)break b;W&=255}x(h- -64|0,W,t)}32&_[0|t]||x(Vt,yt,t);b:if(!(8192!=(0|pt)|(0|St)<=(0|Y))){if(X(h- -64|0,32,(F=(W=St-Y|0)>>>0<256)?W:256),G=32&(w=f[t>>2]),F){if(G)break b}else{for(F=!G,G=W;1&F&&(x(h- -64|0,256,t),w=f[t>>2]),F=!(Q=32&w),(G=G+-256|0)>>>0>255;);if(Q)break b;W&=255}x(h- -64|0,W,t)}F=(0|St)>(0|Y)?St:Y}else{b:if(!(8192&It|(0|St)<=(0|(yt=xt+3|0)))){if(X(h- -64|0,32,(F=(W=St-yt|0)>>>0<256)?W:256),G=32&(w=f[t>>2]),F){if(G)break b}else{for(F=!G,G=W;1&F&&(x(h- -64|0,256,t),w=f[t>>2]),F=!(Q=32&w),(G=G+-256|0)>>>0>255;);if(Q)break b;W&=255}x(h- -64|0,W,t)}32&(G=f[t>>2])||(x(Wt,xt,t),G=f[t>>2]),32&G||(G=(32&wt)>>>5,x(Tt!=Tt?G?5355:5359:G?5347:5351,3,t));b:if(!(8192!=(73728&It)|(0|St)<=(0|yt))){if(X(h- -64|0,32,(F=(W=St-yt|0)>>>0<256)?W:256),G=32&(w=f[t>>2]),F){if(G)break b}else{for(F=!G,G=W;1&F&&(x(h- -64|0,256,t),w=f[t>>2]),F=!(Q=32&w),(G=G+-256|0)>>>0>255;);if(Q)break b;W&=255}x(h- -64|0,W,t)}F=(0|St)>(0|yt)?St:yt}if((0|F)>=0)continue i;break A}Dt=0,Nt=4678}F=d;break r}if(It=G,Y=w,!_[0|F])break r;break A}F=_[e+1|0],e=e+1|0}if(t)break t;if(!Qt){Gt=0;break t}if(e=1,(t=f[o+4>>2])&&(H(r+8|0,t,i),e=2,(t=f[o+8>>2])&&(H(r+16|0,t,i),e=3,(t=f[o+12>>2])&&(H(r+24|0,t,i),e=4,(t=f[o+16>>2])&&(H(r+32|0,t,i),e=5,(t=f[o+20>>2])&&(H(r+40|0,t,i),e=6,(t=f[o+24>>2])&&(H(r+48|0,t,i),e=7,(t=f[o+28>>2])&&(H(r+56|0,t,i),e=8,t=f[o+32>>2])))))))){if(H(r- -64|0,t,i),t=f[o+36>>2])break n;e=9}for(e<<=2;;){if(f[e+o>>2])break a;if(40==(0|(e=e+4|0)))break}Gt=1;break t}f[256]=28;break e}H(r+72|0,t,i),Gt=1;break t}if(!((0|(Et=(0|Y)<(0|(Ft=F-Q|0))?Ft:Y))>(2147483647-Dt|0)||(Ot=Dt+Et|0,F=(0|St)<(0|Ot)?Ot:St,(0|F)>(0|Vt)))){r:if(!((It&=73728)|(0|Ot)>=(0|St))){if(X(h- -64|0,32,(w=(pt=F-Ot|0)>>>0<256)?pt:256),G=32&(W=f[t>>2]),w){if(G)break r}else{for(G=!G,w=pt;1&G&&(x(h- -64|0,256,t),W=f[t>>2]),G=!(yt=32&W),(w=w+-256|0)>>>0>255;);if(yt)break r;pt&=255}x(h- -64|0,pt,t)}32&_[0|t]||x(Nt,Dt,t);r:if(!(65536!=(0|It)|(0|Ot)>=(0|St))){if(X(h- -64|0,48,(w=(Dt=F-Ot|0)>>>0<256)?Dt:256),G=32&(W=f[t>>2]),w){if(G)break r}else{for(G=!G,w=Dt;1&G&&(x(h- -64|0,256,t),W=f[t>>2]),G=!(yt=32&W),(w=w+-256|0)>>>0>255;);if(yt)break r;Dt&=255}x(h- -64|0,Dt,t)}r:if(!((0|Ft)>=(0|Y))){if(X(h- -64|0,48,(w=(yt=Et-Ft|0)>>>0<256)?yt:256),G=32&(Y=f[t>>2]),w){if(G)break r}else{for(G=!G,w=yt;1&G&&(x(h- -64|0,256,t),Y=f[t>>2]),G=!(W=32&Y),(w=w+-256|0)>>>0>255;);if(W)break r;yt&=255}x(h- -64|0,yt,t)}if(32&_[0|t]||x(Q,Ft,t),8192!=(0|It)|(0|Ot)>=(0|St))continue;if(X(h- -64|0,32,(w=(Y=F-Ot|0)>>>0<256)?Y:256),G=32&(Q=f[t>>2]),w){if(G)continue}else{for(G=!G,w=Y;1&G&&(x(h- -64|0,256,t),Q=f[t>>2]),G=!(W=32&Q),(w=w+-256|0)>>>0>255;);if(W)continue;Y&=255}x(h- -64|0,Y,t);continue}}break}f[256]=61}Gt=-1}return Z=h+880|0,Gt}function H(t,e,i){t:{e:{i:{A:{r:{if((e=e+-9|0)>>>0<=17){switch(e-1|0){case 5:e=f[i>>2],f[i>>2]=e+4,e=a[e>>1],f[t>>2]=e;break e;case 6:e=f[i>>2],f[i>>2]=e+4,f[t>>2]=h[e>>1];break t;case 7:e=f[i>>2],f[i>>2]=e+4,e=n[0|e],f[t>>2]=e;break e;case 8:e=f[i>>2],f[i>>2]=e+4,f[t>>2]=_[0|e];break t;case 16:(function(t){var e,i=0,r=0,n=0,a=0,o=0,h=0,d=0;o=5168,e=t;n:{if(!(i=f[716])){if(i=0,I(2848))break n;i=f[716]}if(i-(n=f[717])>>>0>>0)i=0|yt[f[720]](2848,5168,e);else{r=e;a:if(!(f[728]<0)){for(h=e+5168|0,i=0;;){if(r=e,!(i+e))break a;if(d=i+h|0,i=r=i+-1|0,10==_[d+-1|0])break}if(a=1+(e+r|0)|0,(i=0|yt[f[720]](2848,5168,a))>>>0
>>0)break n;o=1+(r+h|0)|0,n=f[717],r^=-1}J(n,o,i=r),f[717]=f[717]+i,i=i+a|0}}})(t=function(){var t=0,e=0,i=0;n:{a:{o:if(t=5168,3&t){if(!_[5168])return 0;for(t=5169;;){if(!(3&t))break o;if(e=_[0|t],t=i=t+1|0,!e)break}break a}for(t=t+-4|0;!((-1^(e=f[(t=t+4|0)>>2]))&e+-16843009&-2139062144););if(!(255&e))return t-5168|0;for(;i=_[t+1|0],t=e=t+1|0,i;);break n}e=i+-1|0}return e-5168|0}()),F();case 0:case 3:case 13:break r;case 1:case 4:case 10:case 14:break A;case 2:case 9:case 11:case 12:case 15:break i}e=f[i>>2],f[i>>2]=e+4,f[t>>2]=f[e>>2]}return}e=f[i>>2],f[i>>2]=e+4,e=f[e>>2],f[t>>2]=e;break e}e=f[i>>2],f[i>>2]=e+4,f[t>>2]=f[e>>2];break t}return e=f[i>>2]+7&-8,f[i>>2]=e+8,i=f[e+4>>2],f[t>>2]=f[e>>2],void(f[t+4>>2]=i)}return void(f[t+4>>2]=e>>31)}f[t+4>>2]=0}function P(e){return e?65535&e|(0|e)<=-1?void F():-1==(0|(e=function(e){e|=0;var o=0|ht(),v=o+e|0;if(o>>16)))?(f[256]=48,-1):e<<16:ht()<<16}function K(t){var e,i=0,r=0,n=0,a=0,o=0,h=0,C=0,g=0,m=0,v=0,y=0,p=0;if(Z=e=Z-16|0,!(f[272]||(i=P(0)-90864|0,i>>>0<89))){for((r=f[384])||(f[387]=-1,f[388]=-1,f[385]=65536,f[386]=65536,r=e+8&-16^1431655768,f[384]=r,f[389]=0,f[377]=0),f[379]=i,f[378]=90864,f[270]=90864,f[275]=r,f[274]=-1;r=n+1104|0,f[n+1112>>2]=r,f[n+1116>>2]=r,256!=(0|(n=n+8|0)););r=i+-64|0,f[22719]=1|r,f[273]=f[388],f[272]=90872,f[269]=r,f[i+90812>>2]=56}t:{e:{i:{A:{r:{n:{a:{o:{s:{l:{f:{if(t>>>0<=236){if(3&(i=(o=f[266])>>>(t=(C=t>>>0<11?16:t+19&-16)>>>3))){n=(t=f[(a=(i=1^(t|1&i))<<3)+1112>>2])+8|0,(0|(r=f[t+8>>2]))!=(0|(a=a+1104|0))?(f[a+8>>2]=r,f[r+12>>2]=a):(y=1064,p=Rt(i)&o,f[y>>2]=p),i<<=3,f[t+4>>2]=3|i,f[(t=t+i|0)+4>>2]=1|f[t+4>>2];break t}if(C>>>0<=(g=f[268])>>>0)break f;if(i){r=i=(t=(0-(t=(i<<=t)&(0-(t=2<>>12&16,r|=i=(t>>>=i)>>>5&8,r|=i=(t>>>=i)>>>2&4,t=f[(n=(i=((r|=i=(t>>>=i)>>>1&2)|(i=(t>>>=i)>>>1&1))+(t>>>i)|0)<<3)+1112>>2],(0|(r=f[t+8>>2]))!=(0|(n=n+1104|0))?(f[n+8>>2]=r,f[r+12>>2]=n):(o=Rt(i)&o,f[266]=o),n=t+8|0,f[t+4>>2]=3|C,r=(i<<=3)-C|0,f[t+i>>2]=r,f[(C=t+C|0)+4>>2]=1|r,g&&(t=1104+((a=g>>>3)<<3)|0,i=f[271],(a=1<>2]:(f[266]=a|o,a=t),f[a+12>>2]=i,f[t+8>>2]=i,f[i+12>>2]=t,f[i+8>>2]=a),f[271]=C,f[268]=r;break t}if(!(v=f[267]))break f;for(r=i=(t=(v&0-v)-1|0)>>>12&16,r|=i=(t>>>=i)>>>5&8,r|=i=(t>>>=i)>>>2&4,i=f[1368+(((r|=i=(t>>>=i)>>>1&2)|(i=(t>>>=i)>>>1&1))+(t>>>i)<<2)>>2],r=(-8&f[i+4>>2])-C|0,t=i;(n=f[t+16>>2])||(n=f[t+20>>2]);)r=(t=(a=(-8&f[n+4>>2])-C|0)>>>0>>0)?a:r,i=t?n:i,t=n;if(m=f[i+24>>2],(0|i)!=(0|(a=f[i+12>>2]))){t=f[i+8>>2],d[270],f[a+8>>2]=t,f[t+12>>2]=a;break e}if(!(n=f[(t=i+20|0)>>2])){if(!(n=f[i+16>>2]))break l;t=i+16|0}for(;h=t,a=n,(n=f[(t=n+20|0)>>2])||(t=a+16|0,n=f[a+16>>2]););f[h>>2]=0;break e}if(C=-1,!(t>>>0>4294967231)&&(C=-16&(t=t+19|0),g=f[267])){h=0,(t>>>=8)&&(h=31,C>>>0>16777215||(h=28+((t=((n=(i=t<<(r=t+1048320>>>16&8))<<(t=i+520192>>>16&4))<<(i=n+245760>>>16&2)>>>15)-(i|t|r)|0)<<1|C>>>t+21&1)|0)),t=0-C|0;c:{b:{if(r=f[1368+(h<<2)>>2])for(i=C<<(31==(0|h)?0:25-(h>>>1)|0),n=0;;){if(!((o=(-8&f[r+4>>2])-C|0)>>>0>=t>>>0||(a=r,t=o,t))){t=0,n=r;break b}if(o=f[r+20>>2],r=f[16+((i>>>29&4)+r|0)>>2],n=o?(0|o)==(0|r)?n:o:n,i<<=0!=(0|r),!r)break}else n=0;if(!(n|a)){if(!(i=(0-(i=2<>>12&16,n|=r=(i>>>=r)>>>5&8,n|=r=(i>>>=r)>>>2&4,n=f[1368+(((n|=r=(i>>>=r)>>>1&2)|(r=(i>>>=r)>>>1&1))+(i>>>r)<<2)>>2]}if(!n)break c}for(;t=(i=(o=(-8&f[n+4>>2])-C|0)>>>0>>0)?o:t,a=i?n:a,(r=f[n+16>>2])||(r=f[n+20>>2]),n=r;);}if(!(!a|t>>>0>=f[268]-C>>>0)){if(h=f[a+24>>2],(0|(i=f[a+12>>2]))!=(0|a)){r=f[a+8>>2],d[270],f[i+8>>2]=r,f[r+12>>2]=i;break i}if(!(n=f[(r=a+20|0)>>2])){if(!(n=f[a+16>>2]))break s;r=a+16|0}for(;o=r,(n=f[(r=(i=n)+20|0)>>2])||(r=i+16|0,n=f[i+16>>2]););f[o>>2]=0;break i}}}if((i=f[268])>>>0>=C>>>0){t=f[271],(r=i-C|0)>>>0>=16?(f[(n=t+C|0)+4>>2]=1|r,f[268]=r,f[271]=n,f[t+i>>2]=r,f[t+4>>2]=3|C):(f[t+4>>2]=3|i,f[(i=t+i|0)+4>>2]=1|f[i+4>>2],f[271]=0,f[268]=0),n=t+8|0;break t}if((i=f[269])>>>0>C>>>0){t=f[272],i=i-C|0,f[(r=t+C|0)+4>>2]=1|i,f[269]=i,f[272]=r,f[t+4>>2]=3|C,n=t+8|0;break t}if(n=0,f[384]?r=f[386]:(f[387]=-1,f[388]=-1,f[385]=65536,f[386]=65536,f[384]=e+12&-16^1431655768,f[389]=0,f[377]=0,r=65536),(t=(o=r+(a=C+71|0)|0)&(h=0-r|0))>>>0<=C>>>0){f[256]=48;break t}if((r=f[376])&&!((g=(n=f[374])+t|0)>>>0<=r>>>0&&g>>>0>n>>>0)){n=0,f[256]=48;break t}if(4&_[1508])break n;f:{c:{if(r=f[272])for(n=1512;;){if((g=f[n>>2])+f[n+4>>2]>>>0>r>>>0&&g>>>0<=r>>>0)break c;if(!(n=f[n+8>>2]))break}if(-1==(0|(i=P(0))))break a;if(o=t,(n=(r=f[385])+-1|0)&i&&(o=(t-i|0)+(i+n&0-r)|0),o>>>0<=C>>>0|o>>>0>2147483646)break a;if((r=f[376])&&(h=(n=f[374])+o|0)>>>0<=n>>>0|h>>>0>r>>>0)break a;if((0|i)!=(0|(n=P(o))))break f;break r}if((o=h&o-i)>>>0>2147483646)break a;if((0|(i=P(o)))==(f[n>>2]+f[n+4>>2]|0))break o;n=i}if(!(C+72>>>0<=o>>>0|o>>>0>2147483646|-1==(0|(i=n)))){if((r=(r=f[386])+(a-o|0)&0-r)>>>0>2147483646)break r;if(-1!=(0|P(r))){o=r+o|0;break r}P(0-o|0);break a}if(-1!=(0|i))break r;break a}a=0;break e}i=0;break i}if(-1!=(0|i))break r}f[377]=4|f[377]}if(t>>>0>2147483646)break A;if((i=P(t))>>>0>=(t=P(0))>>>0|-1==(0|i)|-1==(0|t))break A;if((o=t-i|0)>>>0<=C+56>>>0)break A}t=f[374]+o|0,f[374]=t,t>>>0>d[375]&&(f[375]=t);r:{n:{a:{if(r=f[272]){for(n=1512;;){if(((t=f[n>>2])+(a=f[n+4>>2])|0)==(0|i))break a;if(!(n=f[n+8>>2]))break}break n}for(i>>>0>=(t=f[270])>>>0&&t||(f[270]=i),n=0,f[379]=o,f[378]=i,f[274]=-1,f[275]=f[384],f[381]=0;t=n+1104|0,f[n+1112>>2]=t,f[n+1116>>2]=t,256!=(0|(n=n+8|0)););r=(t=i+8&15?-8-i&15:0)+i|0,t=(n=o+-56|0)-t|0,f[r+4>>2]=1|t,f[273]=f[388],f[269]=t,f[272]=r,f[4+(i+n|0)>>2]=56;break r}if(!(8&_[n+12|0]|i>>>0<=r>>>0|t>>>0>r>>>0)){i=(t=r+8&15?-8-r&15:0)+r|0,t=(h=f[269]+o|0)-t|0,f[i+4>>2]=1|t,f[n+4>>2]=a+o,f[273]=f[388],f[269]=t,f[272]=i,f[4+(r+h|0)>>2]=56;break r}}i>>>0<(a=f[270])>>>0&&(f[270]=i,a=i),t=i+o|0,n=1512;n:{a:{o:{s:{l:{f:{for(;;){if(f[n>>2]!=(0|t)){if(n=f[n+8>>2])continue;break f}break}if(!(8&_[n+12|0]))break l}for(n=1512;;){if((t=f[n>>2])>>>0<=r>>>0&&(a=t+f[n+4>>2]|0)>>>0>r>>>0)break s;n=f[n+8>>2]}}if(f[n>>2]=i,f[n+4>>2]=f[n+4>>2]+o,f[(m=(i+8&15?-8-i&15:0)+i|0)+4>>2]=3|C,n=((i=t+(t+8&15?-8-t&15:0)|0)-m|0)-C|0,h=C+m|0,(0|i)==(0|r)){f[272]=h,t=f[269]+n|0,f[269]=t,f[h+4>>2]=1|t;break a}if((0|i)==f[271]){f[271]=h,t=f[268]+n|0,f[268]=t,f[h+4>>2]=1|t,f[t+h>>2]=t;break a}if(1==(3&(r=f[i+4>>2]))){v=-8&r;l:if(r>>>0<=255){if(C=1104+((r>>>=3)<<3)|0,(0|(t=f[i+12>>2]))==(0|(a=f[i+8>>2]))){y=1064,p=f[266]&Rt(r),f[y>>2]=p;break l}f[t+8>>2]=a,f[a+12>>2]=t}else{if(g=f[i+24>>2],(0|(o=f[i+12>>2]))==(0|i))if((C=f[(r=i+20|0)>>2])||(C=f[(r=i+16|0)>>2])){for(;t=r,(C=f[(r=(o=C)+20|0)>>2])||(r=o+16|0,C=f[o+16>>2]););f[t>>2]=0}else o=0;else t=f[i+8>>2],f[o+8>>2]=t,f[t+12>>2]=o;if(g){t=f[i+28>>2];f:{if((0|i)==f[(r=1368+(t<<2)|0)>>2]){if(f[r>>2]=o,o)break f;y=1068,p=f[267]&Rt(t),f[y>>2]=p;break l}if(f[g+(f[g+16>>2]==(0|i)?16:20)>>2]=o,!o)break l}f[o+24>>2]=g,(t=f[i+16>>2])&&(f[o+16>>2]=t,f[t+24>>2]=o),(t=f[i+20>>2])&&(f[o+20>>2]=t,f[t+24>>2]=o)}}n=n+v|0,i=i+v|0}if(f[i+4>>2]=-2&f[i+4>>2],f[n+h>>2]=n,f[h+4>>2]=1|n,n>>>0<=255){t=1104+((i=n>>>3)<<3)|0,(r=f[266])&(i=1<>2]:(f[266]=i|r,r=t),f[r+12>>2]=h,f[t+8>>2]=h,f[h+12>>2]=t,f[h+8>>2]=r;break a}if(r=0,(t=n>>>8)&&(r=31,n>>>0>16777215||(r=28+((t=((a=(i=t<<(r=t+1048320>>>16&8))<<(t=i+520192>>>16&4))<<(i=a+245760>>>16&2)>>>15)-(i|t|r)|0)<<1|n>>>t+21&1)|0)),f[(o=h)+28>>2]=r,f[h+16>>2]=0,f[h+20>>2]=0,t=1368+(r<<2)|0,!((i=f[267])&(a=1<>2]=h,f[267]=i|a,f[h+24>>2]=t,f[h+8>>2]=h,f[h+12>>2]=h;break a}for(r=n<<(31==(0|r)?0:25-(r>>>1)|0),i=f[t>>2];;){if((-8&f[(t=i)+4>>2])==(0|n))break o;if(i=r>>>29,r<<=1,!(i=f[(a=16+(t+(4&i)|0)|0)>>2]))break}f[a>>2]=h,f[h+24>>2]=t,f[h+12>>2]=h,f[h+8>>2]=h;break a}for(g=(h=o+-56|0)-(t=i+8&15?-8-i&15:0)|0,f[(n=t+i|0)+4>>2]=1|g,f[4+(i+h|0)>>2]=56,f[(t=(t=(a+(a+-55&15?55-a&15:0)|0)-63|0)>>>0>>0?r:t)+4>>2]=35,f[273]=f[388],f[269]=g,f[272]=n,h=f[381],f[(n=t+16|0)>>2]=f[380],f[n+4>>2]=h,n=f[379],f[t+8>>2]=f[378],f[t+12>>2]=n,f[380]=t+8,f[379]=o,f[378]=i,f[381]=0,n=t+36|0;f[n>>2]=7,(n=n+4|0)>>>0>>0;);if((0|t)==(0|r))break r;if(f[t+4>>2]=-2&f[t+4>>2],a=t-r|0,f[t>>2]=a,f[r+4>>2]=1|a,a>>>0<=255){i=1104+((t=a>>>3)<<3)|0,(n=f[266])&(t=1<>2]:(f[266]=t|n,t=i),f[t+12>>2]=r,f[i+8>>2]=r,f[r+12>>2]=i,f[r+8>>2]=t;break r}if(f[r+16>>2]=0,f[r+20>>2]=0,n=0,(t=a>>>8)&&(n=31,a>>>0>16777215||(n=28+((t=((o=(i=t<<(n=t+1048320>>>16&8))<<(t=i+520192>>>16&4))<<(i=o+245760>>>16&2)>>>15)-(i|t|n)|0)<<1|a>>>t+21&1)|0)),f[(h=r+28|0)>>2]=n,t=1368+(n<<2)|0,!((i=f[267])&(o=1<>2]=r,f[267]=i|o,f[r+24>>2]=t,f[r+8>>2]=r,f[r+12>>2]=r;break r}for(n=a<<(31==(0|n)?0:25-(n>>>1)|0),i=f[t>>2];;){if((0|a)==(-8&f[(t=i)+4>>2]))break n;if(i=n>>>29,n<<=1,!(i=f[(o=16+(t+(4&i)|0)|0)>>2]))break}f[o>>2]=r,f[r+24>>2]=t,f[r+12>>2]=r,f[r+8>>2]=r;break r}i=f[t+8>>2],f[t+8>>2]=h,f[i+12>>2]=h,f[h+24>>2]=0,f[h+8>>2]=i,f[h+12>>2]=t}n=m+8|0;break t}i=f[t+8>>2],f[t+8>>2]=r,f[i+12>>2]=r,f[r+24>>2]=0,f[r+8>>2]=i,f[r+12>>2]=t}if(!((i=f[269])>>>0<=C>>>0)){t=f[272],i=i-C|0,f[(r=t+C|0)+4>>2]=1|i,f[269]=i,f[272]=r,f[t+4>>2]=3|C,n=t+8|0;break t}}n=0,f[256]=48;break t}i:if(h){r=f[a+28>>2];A:{if((0|a)==f[(n=1368+(r<<2)|0)>>2]){if(f[n>>2]=i,i)break A;g=Rt(r)&g,f[267]=g;break i}if(f[h+(f[h+16>>2]==(0|a)?16:20)>>2]=i,!i)break i}f[i+24>>2]=h,(r=f[a+16>>2])&&(f[i+16>>2]=r,f[r+24>>2]=i),(r=f[a+20>>2])&&(f[i+20>>2]=r,f[r+24>>2]=i)}i:if(t>>>0<=15)t=t+C|0,f[a+4>>2]=3|t,t=t+a|0,f[t+4>>2]=1|f[t+4>>2];else if(o=a+C|0,f[o+4>>2]=1|t,f[a+4>>2]=3|C,f[t+o>>2]=t,t>>>0<=255)i=t>>>3,t=1104+(i<<3)|0,r=f[266],i=1<>2]:(f[266]=i|r,r=t),f[r+12>>2]=o,f[t+8>>2]=o,f[o+12>>2]=t,f[o+8>>2]=r;else if(h=o,i=t>>>8,n=0,i&&(n=31,t>>>0>16777215||(n=i+1048320>>>16&8,r=i<>>16&4,C=r<>>16&2,i=(C<>>15)-(r|i|n)|0,n=28+(i<<1|t>>>i+21&1)|0)),f[h+28>>2]=n,f[o+16>>2]=0,f[o+20>>2]=0,i=1368+(n<<2)|0,r=1<>>1)|0),C=f[i>>2];A:{for(;;){if((-8&f[(i=C)+4>>2])==(0|t))break A;if(r=n>>>29,n<<=1,!(C=f[(r=16+(i+(4&r)|0)|0)>>2]))break}f[r>>2]=o,f[o+24>>2]=i,f[o+12>>2]=o,f[o+8>>2]=o;break i}t=f[i+8>>2],f[i+8>>2]=o,f[t+12>>2]=o,f[o+24>>2]=0,f[o+8>>2]=t,f[o+12>>2]=i}else f[i>>2]=o,f[267]=r|g,f[o+24>>2]=i,f[o+8>>2]=o,f[o+12>>2]=o;n=a+8|0;break t}e:if(m){t=f[i+28>>2];i:{if((0|i)==f[(n=1368+(t<<2)|0)>>2]){if(f[n>>2]=a,a)break i;y=1068,p=Rt(t)&v,f[y>>2]=p;break e}if(f[(f[m+16>>2]==(0|i)?16:20)+m>>2]=a,!a)break e}f[a+24>>2]=m,(t=f[i+16>>2])&&(f[a+16>>2]=t,f[t+24>>2]=a),(t=f[i+20>>2])&&(f[a+20>>2]=t,f[t+24>>2]=a)}r>>>0<=15?(t=r+C|0,f[i+4>>2]=3|t,f[(t=t+i|0)+4>>2]=1|f[t+4>>2]):(f[(h=i+C|0)+4>>2]=1|r,f[i+4>>2]=3|C,f[r+h>>2]=r,g&&(t=1104+((a=g>>>3)<<3)|0,n=f[271],(a=1<>2]:(f[266]=a|o,a=t),f[a+12>>2]=n,f[t+8>>2]=n,f[n+12>>2]=t,f[n+8>>2]=a),f[271]=h,f[268]=r),n=i+8|0}return Z=e+16|0,n}function L(t){var e=0,i=0,r=0,n=0,a=0,o=0,_=0,h=0,C=0;t:if(t){a=(r=t+-8|0)+(t=-8&(i=f[t+-4>>2]))|0;e:if(!(1&i)){if(!(3&i))break t;if((r=r-(e=f[r>>2])|0)>>>0<(n=f[270])>>>0)break t;if(t=t+e|0,(0|r)==f[271]){if(3==(3&(i=f[a+4>>2])))return f[a+4>>2]=-2&i,f[268]=t,f[t+r>>2]=t,void(f[r+4>>2]=1|t)}else{if(e>>>0<=255){if(o=1104+((e>>>=3)<<3)|0,(0|(i=f[r+12>>2]))==(0|(n=f[r+8>>2]))){h=1064,C=f[266]&Rt(e),f[h>>2]=C;break e}f[i+8>>2]=n,f[n+12>>2]=i;break e}if(_=f[r+24>>2],(0|r)==(0|(i=f[r+12>>2])))if((n=f[(e=r+20|0)>>2])||(n=f[(e=r+16|0)>>2])){for(;o=e,(n=f[(e=(i=n)+20|0)>>2])||(e=i+16|0,n=f[i+16>>2]););f[o>>2]=0}else i=0;else e=f[r+8>>2],f[i+8>>2]=e,f[e+12>>2]=i;if(!_)break e;e=f[r+28>>2];i:{if((0|r)==f[(n=1368+(e<<2)|0)>>2]){if(f[n>>2]=i,i)break i;h=1068,C=f[267]&Rt(e),f[h>>2]=C;break e}if(f[_+(f[_+16>>2]==(0|r)?16:20)>>2]=i,!i)break e}if(f[i+24>>2]=_,(e=f[r+16>>2])&&(f[i+16>>2]=e,f[e+24>>2]=i),!(e=f[r+20>>2]))break e;f[i+20>>2]=e,f[e+24>>2]=i}}if(!(a>>>0<=r>>>0)&&1&(i=f[a+4>>2])){e:{if(!(2&i)){if(f[272]==(0|a)){if(f[272]=r,t=f[269]+t|0,f[269]=t,f[r+4>>2]=1|t,f[271]!=(0|r))break t;return f[268]=0,void(f[271]=0)}if(f[271]==(0|a))return f[271]=r,t=f[268]+t|0,f[268]=t,f[r+4>>2]=1|t,void(f[t+r>>2]=t);t=(-8&i)+t|0;i:if(i>>>0<=255){if(o=1104+((i>>>=3)<<3)|0,(0|(e=f[a+12>>2]))==(0|(n=f[a+8>>2]))){h=1064,C=f[266]&Rt(i),f[h>>2]=C;break i}f[e+8>>2]=n,f[n+12>>2]=e}else{if(_=f[a+24>>2],(0|(i=f[a+12>>2]))==(0|a))if((n=f[(e=a+20|0)>>2])||(n=f[(e=a+16|0)>>2])){for(;o=e,(n=f[(e=(i=n)+20|0)>>2])||(e=i+16|0,n=f[i+16>>2]););f[o>>2]=0}else i=0;else e=f[a+8>>2],d[270],f[i+8>>2]=e,f[e+12>>2]=i;if(_){e=f[a+28>>2];A:{if(f[(n=1368+(e<<2)|0)>>2]==(0|a)){if(f[n>>2]=i,i)break A;h=1068,C=f[267]&Rt(e),f[h>>2]=C;break i}if(f[_+((0|a)==f[_+16>>2]?16:20)>>2]=i,!i)break i}f[i+24>>2]=_,(e=f[a+16>>2])&&(f[i+16>>2]=e,f[e+24>>2]=i),(e=f[a+20>>2])&&(f[i+20>>2]=e,f[e+24>>2]=i)}}if(f[t+r>>2]=t,f[r+4>>2]=1|t,f[271]!=(0|r))break e;return void(f[268]=t)}f[a+4>>2]=-2&i,f[t+r>>2]=t,f[r+4>>2]=1|t}if(t>>>0<=255)return t=1104+((i=t>>>3)<<3)|0,(e=f[266])&(i=1<>2]:(f[266]=i|e,e=t),f[e+12>>2]=r,f[t+8>>2]=r,f[r+12>>2]=t,void(f[r+8>>2]=e);f[r+16>>2]=0,f[r+20>>2]=0,e=0,(i=t>>>8)&&(e=31,t>>>0>16777215||(e=28+((i=((o=(e=i<<(n=i+1048320>>>16&8))<<(i=e+520192>>>16&4))<<(e=o+245760>>>16&2)>>>15)-(e|i|n)|0)<<1|t>>>i+21&1)|0)),f[(a=r+28|0)>>2]=e,i=1368+(e<<2)|0;e:if((n=f[267])&(o=1<>>1)|0),i=f[i>>2];i:{for(;;){if(n=i,(-8&f[i+4>>2])==(0|t))break i;if(i=e>>>29,e<<=1,!(i=f[(o=16+(n+(4&i)|0)|0)>>2]))break}f[o>>2]=r,f[r+12>>2]=r,f[r+24>>2]=n,f[r+8>>2]=r;break e}t=f[n+8>>2],f[n+8>>2]=r,f[t+12>>2]=r,f[r+24>>2]=0,f[r+8>>2]=t,f[r+12>>2]=n}else f[i>>2]=r,f[267]=n|o,f[r+24>>2]=i,f[r+8>>2]=r,f[r+12>>2]=r;if(t=f[274]+-1|0,f[274]=t,!t){for(r=1520;r=(t=f[r>>2])+8|0,t;);f[274]=-1}}}}function q(t){var e;for(Z=e=Z-16|0,f[e+12>>2]=t,f[e+12>>2]||(f[e+12>>2]=1);t=K(f[e+12>>2]),f[e+8>>2]=t,!t&&(f[(t=Z-16|0)+12>>2]=1560,f[t+8>>2]=2,f[e+4>>2]=f[f[t+12>>2]>>2],f[e+4>>2]);)yt[f[e+4>>2]]();return Z=e+16|0,f[e+8>>2]}function $(t){var e;Z=e=Z-16|0,f[e+12>>2]=t,L(f[e+12>>2]),Z=e+16|0}function AA(t,e){var i=0,r=0;t:if(!(!(i=_[0|t])|(0|(r=_[0|e]))!=(0|i)))for(t=t+1|0,e=e+1|0;;){if(r=_[0|e],!(i=_[0|t]))break t;if(t=t+1|0,e=e+1|0,(0|i)!=(0|r))break}return i-r|0}function eA(t){t|=0,f[12+(Z-16|0)>>2]=t}function rA(t){var e;return t|=0,Z=e=Z-16|0,f[e+12>>2]=t,function(t){var e;Z=e=Z-16|0,f[e+12>>2]=t,f[12+(Z-16|0)>>2]=f[e+12>>2],Z=e+16|0}(t=f[e+12>>2]),Z=e+16|0,0|t}function iA(t){var e;return t|=0,Z=e=Z-16|0,f[e+12>>2]=t,rA(t=f[e+12>>2]),Z=e+16|0,0|t}function fA(t,e,i){var r,a=0,o=0;return Z=r=Z-16|0,f[r+8>>2]=t,f[r+4>>2]=e,n[r+3|0]=i,1&n[r+3|0]?(t=1,e=r,f[r+8>>2]!=f[r+4>>2]&&(t=!AA(tA(f[r+8>>2]),tA(f[r+4>>2]))),n[e+15|0]=t):(a=r,o=1&function(t,e){var i;return Z=i=Z-16|0,f[i+4>>2]=t,f[i>>2]=e,t=f[f[i>>2]+4>>2],f[i+12>>2]=f[f[i+4>>2]+4>>2],f[i+8>>2]=t,t=1,f[i+12>>2]!=f[i+8>>2]&&(t=!AA(f[i+12>>2],f[i+8>>2])),Z=i+16|0,t}(f[r+8>>2],f[r+4>>2]),n[a+15|0]=o),Z=r+16|0,1&n[r+15|0]}function tA(t){var e;return f[(e=Z-16|0)+8>>2]=t,f[e+12>>2]=f[f[e+8>>2]+4>>2],f[e+12>>2]}function nA(t,e,i,r){var a;f[(a=Z-16|0)+12>>2]=t,f[a+8>>2]=e,f[a+4>>2]=i,f[a>>2]=r,f[f[a+8>>2]+16>>2]?f[f[a+8>>2]+16>>2]!=f[a+4>>2]?(t=f[a+8>>2],f[t+36>>2]=f[t+36>>2]+1,f[f[a+8>>2]+24>>2]=2,n[f[a+8>>2]+54|0]=1):2==f[f[a+8>>2]+24>>2]&&(f[f[a+8>>2]+24>>2]=f[a>>2]):(f[f[a+8>>2]+16>>2]=f[a+4>>2],f[f[a+8>>2]+24>>2]=f[a>>2],f[f[a+8>>2]+36>>2]=1)}function aA(t,e,i,r){var n,a;Z=n=Z-32|0,f[n+28>>2]=t,f[n+24>>2]=e,f[n+20>>2]=i,f[n+16>>2]=r,t=f[n+28>>2],f[n+12>>2]=0,f[n+20>>2]&&(f[n+12>>2]=f[t+4>>2]>>8,1&f[t+4>>2]&&(f[n+8>>2]=f[f[n+20>>2]>>2],f[n+12>>2]=f[f[n+8>>2]+f[n+12>>2]>>2])),i=e=f[t>>2],r=f[n+24>>2],a=f[n+20>>2]+f[n+12>>2]|0,t=2&f[t+4>>2]?f[n+16>>2]:2,yt[f[f[e>>2]+28>>2]](i,r,a,t),Z=n+32|0}function oA(t,e,i,r,a){var o;f[(o=Z-32|0)+28>>2]=t,f[o+24>>2]=e,f[o+20>>2]=i,f[o+16>>2]=r,f[o+12>>2]=a,n[f[o+24>>2]+53|0]=1,f[o+16>>2]==f[f[o+24>>2]+4>>2]&&(n[f[o+24>>2]+52|0]=1,f[f[o+24>>2]+16>>2]?f[f[o+24>>2]+16>>2]!=f[o+20>>2]?(t=f[o+24>>2],f[t+36>>2]=f[t+36>>2]+1,n[f[o+24>>2]+54|0]=1):(2==f[f[o+24>>2]+24>>2]&&(f[f[o+24>>2]+24>>2]=f[o+12>>2]),1!=f[f[o+24>>2]+48>>2]|1!=f[f[o+24>>2]+24>>2]||(n[f[o+24>>2]+54|0]=1)):(f[f[o+24>>2]+16>>2]=f[o+20>>2],f[f[o+24>>2]+24>>2]=f[o+12>>2],f[f[o+24>>2]+36>>2]=1,1!=f[f[o+24>>2]+48>>2]|1!=f[f[o+24>>2]+24>>2]||(n[f[o+24>>2]+54|0]=1)))}function cA(t,e,i,r){var n;f[(n=Z-16|0)+12>>2]=t,f[n+8>>2]=e,f[n+4>>2]=i,f[n>>2]=r,f[n+4>>2]==f[f[n+8>>2]+4>>2]&&1!=f[f[n+8>>2]+28>>2]&&(f[f[n+8>>2]+28>>2]=f[n>>2])}function bA(t,e,i,r,a,o){var _;Z=_=Z-32|0,f[_+28>>2]=t,f[_+24>>2]=e,f[_+20>>2]=i,f[_+16>>2]=r,f[_+12>>2]=a,n[_+11|0]=o,t=f[_+28>>2],f[_+4>>2]=f[t+4>>2]>>8,1&f[t+4>>2]&&(f[_>>2]=f[f[_+16>>2]>>2],f[_+4>>2]=f[f[_>>2]+f[_+4>>2]>>2]),i=e=f[t>>2],r=f[_+24>>2],a=f[_+20>>2],o=f[_+16>>2]+f[_+4>>2]|0,t=2&f[t+4>>2]?f[_+12>>2]:2,yt[f[f[e>>2]+20>>2]](i,r,a,o,t,1&n[_+11|0]),Z=_+32|0}function lA(t,e,i,r,a){var o;Z=o=Z-32|0,f[o+28>>2]=t,f[o+24>>2]=e,f[o+20>>2]=i,f[o+16>>2]=r,n[o+15|0]=a,t=f[o+28>>2],f[o+8>>2]=f[t+4>>2]>>8,1&f[t+4>>2]&&(f[o+4>>2]=f[f[o+20>>2]>>2],f[o+8>>2]=f[f[o+4>>2]+f[o+8>>2]>>2]),i=e=f[t>>2],r=f[o+24>>2],a=f[o+20>>2]+f[o+8>>2]|0,t=2&f[t+4>>2]?f[o+16>>2]:2,yt[f[f[e>>2]+24>>2]](i,r,a,t,1&n[o+15|0]),Z=o+32|0}function uA(t,e){f[t>>2]=5748,f[t+4>>2]=f[e>>2]}function sA(t){return 0|(t|=0)}function kA(t){F()}function vA(t,e){uA(t,e),f[t>>2]=5776}function dA(t){return f[391]=f[391]+1,0|yt[f[740]](t,16)}function CA(t){t&&(f[392]=f[392]+1,yt[f[741]](t))}function gA(t,e,i,r){var n,o,_=v(0),h=v(0),d=v(0),g=v(0),y=v(0),p=0,R=0,D=v(0),B=0,E=v(0),F=0,V=v(0),G=v(0),w=0,Q=v(0),W=0;if(Z=n=Z-32|0,o=f[t>>2],f[t>>2]=o+1,1!=(0|(p=r-i|0))){if(W=function(t,e,i,r){var n,a,o=0,_=0,h=0,d=0,g=0,y=0,p=v(0),R=0,D=0,B=0,E=v(0),F=v(0),V=v(0),G=0,w=0,Q=0,W=0,Y=0,z=0,yt=0,pt=0;if(f[(_=(n=Z+-64|0)+24|0)>>2]=0,f[_+4>>2]=0,f[n+16>>2]=0,f[n+20>>2]=0,!(o=(0|i)<=(0|e))){for(y=i-e|0,_=24+(f[t+12>>2]+m(e,36)|0)|0;p=v(v(v(C[_+-4>>2]+C[_+-20>>2])*v(.5))+p),E=v(v(v(C[_+-8>>2]+C[_+-24>>2])*v(.5))+E),F=v(v(v(C[_>>2]+C[_+-16>>2])*v(.5))+F),_=_+36|0,y=y+-1|0;);C[n+24>>2]=F,C[n+20>>2]=p,C[n+16>>2]=E}if(a=i-e|0,V=v(v(1)/v(0|a)),C[n+24>>2]=V*F,C[n+20>>2]=V*p,C[n+16>>2]=V*E,_=e,!o)for(p=C[(r<<=2)+(n+16|0)>>2],y=m(e,36)+16|0,Y=r+n|0,R=n+48|0,r=a;f[n+12>>2]=0,d=(o=(g=f[t+12>>2])+y|0)+8|0,C[n+8>>2]=v(C[d>>2]+C[o+-8>>2])*v(.5),C[n+4>>2]=v(C[o+4>>2]+C[o+-12>>2])*v(.5),h=o+-16|0,C[n>>2]=v(C[o>>2]+C[h>>2])*v(.5),C[Y>>2]>p&&(z=f[h>>2],yt=f[h+4>>2],W=m(_,36),G=f[(g=g+W|0)+4>>2],f[h>>2]=f[g>>2],f[h+4>>2]=G,pt=f[o>>2],G=f[o+4>>2],w=f[(D=g+16|0)+4>>2],f[o>>2]=f[D>>2],f[o+4>>2]=w,D=f[d>>2],w=f[d+4>>2],Q=f[(B=g+24|0)+4>>2],f[d>>2]=f[B>>2],f[d+4>>2]=Q,d=f[(o=o+16|0)>>2],f[o>>2]=f[g+32>>2],B=f[(o=h+8|0)>>2],Q=f[o+4>>2],g=f[(h=g+8|0)+4>>2],f[o>>2]=f[h>>2],f[o+4>>2]=g,f[R>>2]=pt,f[R+4>>2]=G,f[(o=R+8|0)>>2]=D,f[o+4>>2]=w,f[(o=h=n+40|0)>>2]=B,f[o+4>>2]=Q,o=f[t+12>>2]+W|0,f[o+32>>2]=d,f[n+32>>2]=z,f[n+36>>2]=yt,d=f[n+36>>2],f[o>>2]=f[n+32>>2],f[o+4>>2]=d,d=f[h+4>>2],f[(g=o+8|0)>>2]=f[h>>2],f[g+4>>2]=d,h=f[R+4>>2],f[(d=o+16|0)>>2]=f[R>>2],f[d+4>>2]=h,d=f[(h=n+56|0)+4>>2],f[(o=o+24|0)>>2]=f[h>>2],f[o+4>>2]=d,_=_+1|0),y=y+36|0,r=r+-1|0;);return(0|_)<((-1^(t=(0|a)/3|0))+i|0)&&(0|_)>(t+e|0)||(_=(a>>1)+e|0),_}(e,i,r,function(t,e,i){var r,n=0,a=v(0),o=v(0),_=v(0),h=v(0),d=0,g=v(0),y=v(0),p=v(0),R=v(0);r=i-e|0;t:{e:{if((0|i)<=(0|e))_=v(0|r);else{for(n=24+(f[t+12>>2]+m(e,36)|0)|0,d=r;a=v(a+v(v(C[n+-4>>2]+C[n+-20>>2])*v(.5))),y=v(y+v(v(C[n+-8>>2]+C[n+-24>>2])*v(.5))),o=v(o+v(v(C[n>>2]+C[n+-16>>2])*v(.5))),n=n+36|0,d=d+-1|0;);if(_=v(0|r),(0|i)>(0|e))break e}o=v(0),a=v(0);break t}for(h=v(v(1)/_),p=v(h*o),R=v(h*a),y=v(h*y),d=i-e|0,n=24+(f[t+12>>2]+m(e,36)|0)|0,a=v(0),o=v(0),h=v(0);g=o,o=v(v(v(C[n+-4>>2]+C[n+-20>>2])*v(.5))-R),o=v(g+v(o*o)),g=h,h=v(v(v(C[n+-8>>2]+C[n+-24>>2])*v(.5))-y),h=v(g+v(h*h)),g=a,a=v(v(v(C[n>>2]+C[n+-16>>2])*v(.5))-p),a=v(g+v(a*a)),n=n+36|0,d=d+-1|0;);}return _=v(v(1)/v(_+v(-1))),o=v(_*o),a=v(_*a),(_=v(_*h))>2]=-8388609,f[n+16>>2]=-8388609,f[n+20>>2]=-8388609,f[n+8>>2]=2139095039,f[n>>2]=2139095039,f[n+4>>2]=2139095039,(0|r)<=(0|i))_=v(34028234663852886e22),h=v(-34028234663852886e22),y=v(-34028234663852886e22),g=v(-34028234663852886e22),E=v(34028234663852886e22),D=v(34028234663852886e22);else for(w=n+16|0,R=16+(f[e+12>>2]+m(i,36)|0)|0,_=v(34028234663852886e22),h=v(-34028234663852886e22),y=v(-34028234663852886e22),g=v(-34028234663852886e22),E=v(34028234663852886e22),D=v(34028234663852886e22);D=D>(d=C[(F=R+-16|0)>>2])?d:D,C[n>>2]=D,B=E>C[R+-12>>2]?F:n,E=C[B+4>>2],f[n+4>>2]=f[B+4>>2],F=_>C[R+-8>>2]?F:n,_=C[F+8>>2],f[n+8>>2]=f[F+8>>2],g=g<(d=C[R>>2])?d:g,C[n+16>>2]=g,F=y>2]?R:w,y=C[F+4>>2],f[n+20>>2]=f[F+4>>2],F=h>2]?R:w,h=C[F+8>>2],f[n+24>>2]=f[F+8>>2],R=R+36|0,p=p+-1|0;);p=R=(F=o<<4)+f[(w=t+16|0)>>2]|0,G=C[t+56>>2],V=C[t+40>>2],d=C[t+24>>2],B=(g=v(v(G*v((V<(g=g=v(0)?~~g>>>0:0,a[p+6>>1]=B,p=R,B=(g=v(v(v((V<(g=D=v(0)?~~g>>>0:0,a[p>>1]=B,p=R+10|0,V=C[t- -64>>2],D=C[t+48>>2],g=C[t+32>>2],B=(h=v(v(V*v((D<(h=h=v(0)?~~h>>>0:0,a[p>>1]=B,p=R+8|0,G=C[t+60>>2],d=C[t+44>>2],h=C[t+28>>2],B=(y=v(v(G*v((d<(y=y=v(0)?~~y>>>0:0,a[p>>1]=B,p=R,B=(_=v(v(v((D<(_=_=v(0)?~~_>>>0:0,a[p+4>>1]=B,p=(_=v(v(v((d<(_=E=v(0)?~~_>>>0:0,a[R+2>>1]=p,gA(t,e,i,W),gA(t,e,W,r),f[12+(F+f[w>>2]|0)>>2]=o-f[t>>2]}else E=C[t+48>>2],_=C[t+32>>2],e=f[e+12>>2]+m(i,36)|0,h=(h=C[e+8>>2])<_?_:h,V=C[t- -64>>2],p=(h=v(v(v((E=v(0)?~~h>>>0:0,d=C[e>>2],y=C[e+4>>2],i=f[t+16>>2]+(o<<4)|0,a[i+4>>1]=p,r=i,g=C[t+44>>2],y=y<(h=C[t+28>>2])?h:y,G=C[t+60>>2],R=(y=v(v(v((g=v(0)?~~y>>>0:0,a[r+2>>1]=R,r=i,D=C[t+40>>2],d=d<(y=C[t+24>>2])?y:d,Q=C[t+56>>2],t=(d=v(v(v((D=v(0)?~~d>>>0:0,a[r>>1]=t,d=C[e+24>>2],p=(_=v(v(V*v((E<(d=d<_?_:d)?E:d)-_))+v(.5)))=v(0)?~~_>>>0:0,_=C[e+16>>2],E=C[e+20>>2],a[i+10>>1]=p,t=i+8|0,r=(h=v(v(G*v((g<(E=E=v(0)?~~h>>>0:0,a[t>>1]=r,t=i,r=(_=v(v(Q*v((D<(_=_=v(0)?~~_>>>0:0,a[t+6>>1]=r,f[i+12>>2]=f[e+32>>2];Z=n+32|0}function _A(t,e,i){var r,a,o,d,g,m,y,p=v(0),R=v(0),D=v(0),B=v(0),E=0,F=0,V=v(0),G=0,w=0,Q=0,W=0,Y=0,Z=v(0),z=v(0),yt=0,pt=0,Dt=0;if(Z=C[t- -64>>2],D=C[t+48>>2],p=C[t+32>>2],R=C[e+24>>2],o=(R=v(v(Z*v((D<(R=R=v(0)?~~R>>>0:0,z=C[t+60>>2],V=C[t+44>>2],R=C[t+28>>2],B=C[e+20>>2],d=(B=v(v(z*v((V<(B=B=v(0)?~~B>>>0:0,B=C[e+8>>2],a=(p=v(v(v((D<(B=B=v(0)?~~p>>>0:0,p=C[e+4>>2],g=(p=v(v(v((V<(p=p=v(0)?~~p>>>0:0,V=C[t+56>>2],R=C[t+40>>2],p=C[t+24>>2],D=C[e+16>>2],m=(D=v(v(V*v((R<(D=D=v(0)?~~D>>>0:0,D=C[e>>2],y=(p=v(v(v((R<(D=D=v(0)?~~p>>>0:0,(0|(r=f[t>>2]))>=1)for(e=0;;){if(E=(yt=e<<4)+f[t+16>>2]|0,h[E+4>>1]<=o>>>0&&!(h[E>>1]>m>>>0|h[E+6>>1]>>0|h[E+8>>1]>>0|h[E+2>>1]>d>>>0)){if(pt=(0|(w=f[E+12>>2]))>-1,Dt=(E=h[E+10>>1])>>>0>=a>>>0,!((0|w)<0|E>>>0>>0)){if((0|(F=f[i+4>>2]))==f[i+8>>2]&&!((0|F)>=(0|(G=F?F<<1:1)))){G?(E=dA(G<<2),F=f[i+4>>2]):E=0,Q=f[i+12>>2];t:{if((0|F)>=1)for(W=E,Y=Q;f[W>>2]=f[Y>>2],W=W+4|0,Y=Y+4|0,F=F+-1|0;);else if(!Q)break t;_[i+16|0]&&CA(Q),f[i+12>>2]=0,F=f[i+4>>2]}f[i+12>>2]=E,n[i+16|0]=1,f[i+8>>2]=G}f[f[i+12>>2]+(F<<2)>>2]=w,f[i+4>>2]=f[i+4>>2]+1}}else pt=f[E+12>>2]>-1,Dt=0;if(!((0|(e=pt||Dt?e+1|0:e-f[12+(f[t+16>>2]+yt|0)>>2]|0))<(0|r)))break}}function mA(t,e,i,r,a){var o;Z=o=Z-112|0,!f[t>>2]|!f[i>>2]||(function(t,e,i){var r=v(0),n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),Z=v(0),z=v(0),yt=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0);E=C[e+52>>2],F=C[e+56>>2],V=C[i+52>>2],G=C[i+56>>2],_=C[e+20>>2],h=C[e+36>>2],r=C[i+20>>2],n=C[i+36>>2],a=C[i+24>>2],d=C[e+24>>2],w=C[i+40>>2],g=C[e+40>>2],Et=C[e+48>>2],Q=C[i+48>>2],m=C[e+4>>2],W=C[i+4>>2],Y=C[i+8>>2],p=C[e+8>>2],o=C[i+32>>2],R=C[e+32>>2],Z=C[i>>2],D=C[e>>2],z=C[i+16>>2],B=C[e+16>>2],f[t+60>>2]=0,f[t+44>>2]=0,f[t+28>>2]=0,f[t+12>>2]=0,yt=v(v(v(D*Z)+v(B*z))+v(R*o)),C[t+16>>2]=yt,pt=v(v(v(p*Y)+v(d*a))+v(g*w)),C[t+56>>2]=pt,Dt=v(v(v(p*W)+v(d*r))+v(g*n)),C[t+52>>2]=Dt,It=v(v(v(p*Z)+v(d*z))+v(g*o)),C[t+48>>2]=It,St=v(v(v(m*Y)+v(_*a))+v(h*w)),C[t+40>>2]=St,Tt=v(v(v(m*W)+v(_*r))+v(h*n)),C[t+36>>2]=Tt,o=v(v(v(m*Z)+v(_*z))+v(h*o)),C[t+32>>2]=o,a=v(v(v(D*Y)+v(B*a))+v(R*w)),C[t+24>>2]=a,n=v(v(v(D*W)+v(B*r))+v(R*n)),C[t+20>>2]=n,C[t+64>>2]=v(y(yt))+v(9.999999974752427e-7),r=v(-Et),C[t+8>>2]=v(v(v(p*r)-v(d*E))-v(g*F))+v(v(v(p*Q)+v(d*V))+v(g*G)),C[t+4>>2]=v(v(v(m*r)-v(_*E))-v(h*F))+v(v(v(m*Q)+v(_*V))+v(h*G)),C[t>>2]=v(v(v(D*r)-v(B*E))-v(R*F))+v(v(v(D*Q)+v(B*V))+v(R*G)),C[t+104>>2]=v(y(pt))+v(9.999999974752427e-7),C[t+100>>2]=v(y(Dt))+v(9.999999974752427e-7),C[t+96>>2]=v(y(It))+v(9.999999974752427e-7),C[t+88>>2]=v(y(St))+v(9.999999974752427e-7),C[t+84>>2]=v(y(Tt))+v(9.999999974752427e-7),C[t+80>>2]=v(y(o))+v(9.999999974752427e-7),C[t+72>>2]=v(y(a))+v(9.999999974752427e-7),C[t+68>>2]=v(y(n))+v(9.999999974752427e-7)}(o,e,r),function A(t,e,i,r,a,o,d){var g,m,p=0,R=0,D=0,B=0,E=0,F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0);Z=g=Z+-64|0,p=(B=a<<4)+f[t+16>>2]|0,D=h[p>>1],R=h[p+2>>1],E=h[p+4>>1],f[g+44>>2]=0,F=C[t- -64>>2],V=C[t+32>>2],C[g+40>>2]=v(v(E>>>0)/F)+V,G=C[t+60>>2],w=C[t+28>>2],C[g+36>>2]=v(v(R>>>0)/G)+w,Q=C[t+56>>2],W=C[t+24>>2],C[g+32>>2]=v(v(D>>>0)/Q)+W,D=h[p+6>>1],R=h[p+10>>1],p=h[p+8>>1],f[g+60>>2]=0,C[g+52>>2]=w+v(v(p>>>0)/G),C[g+56>>2]=V+v(v(R>>>0)/F),C[g+48>>2]=W+v(v(D>>>0)/Q),p=(D=o<<4)+f[e+16>>2]|0,R=h[p>>1],E=h[p+2>>1],m=h[p+4>>1],f[g+12>>2]=0,F=C[e- -64>>2],V=C[e+32>>2],C[g+8>>2]=v(v(m>>>0)/F)+V,G=C[e+60>>2],w=C[e+28>>2],C[g+4>>2]=v(v(E>>>0)/G)+w,Q=C[e+56>>2],W=C[e+24>>2],C[g>>2]=v(v(R>>>0)/Q)+W,R=h[p+6>>1],E=h[p+10>>1],p=h[p+8>>1],f[g+28>>2]=0,C[g+20>>2]=w+v(v(p>>>0)/G),C[g+24>>2]=V+v(v(E>>>0)/F),C[g+16>>2]=W+v(v(R>>>0)/Q);t:if(function(t,e,i,r){var n=v(0),a=v(0),o=v(0),f=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),Z=v(0),z=v(0),yt=v(0),pt=v(0),Dt=v(0),It=v(0);e:{if(f=C[e+16>>2],a=v(v(f+C[e>>2])*v(.5)),Q=C[i+16>>2],_=C[e+20>>2],n=v(v(_+C[e+4>>2])*v(.5)),W=C[i+20>>2],h=C[e+24>>2],o=v(v(h+C[e+8>>2])*v(.5)),Y=C[i+24>>2],d=C[t+16>>2],g=v(v(d+C[t>>2])*v(.5)),p=v(v(C[i>>2]+v(v(v(a*Q)+v(n*W))+v(o*Y)))-g),d=v(d-g),f=v(f-a),D=C[i+64>>2],_=v(_-n),B=C[i+68>>2],h=v(h-o),E=C[i+72>>2],!(v(y(p))>v(d+v(v(v(f*D)+v(_*B))+v(h*E)))||(Z=C[i+32>>2],z=C[i+36>>2],yt=C[i+40>>2],m=C[t+20>>2],R=v(v(m+C[t+4>>2])*v(.5)),g=v(v(C[i+4>>2]+v(v(v(a*Z)+v(n*z))+v(o*yt)))-R),m=v(m-R),R=C[i+80>>2],F=C[i+84>>2],V=C[i+88>>2],v(y(g))>v(m+v(v(v(f*R)+v(_*F))+v(h*V)))||(pt=C[i+48>>2],Dt=C[i+52>>2],It=C[i+56>>2],a=v(C[i+8>>2]+v(v(v(a*pt)+v(n*Dt))+v(o*It))),n=C[t+24>>2],o=v(v(n+C[t+8>>2])*v(.5)),a=v(a-o),n=v(n-o),o=C[i+96>>2],G=C[i+100>>2],w=C[i+104>>2],v(y(a))>v(n+v(v(v(f*o)+v(_*G))+v(h*w)))|v(y(v(v(v(p*Q)+v(g*Z))+v(a*pt))))>v(f+v(v(v(d*D)+v(m*R))+v(n*o)))|v(y(v(v(v(p*W)+v(g*z))+v(a*Dt))))>v(_+v(v(v(d*B)+v(m*F))+v(n*G))))))){if(i=1^(t=v(y(v(v(v(p*Y)+v(g*yt))+v(a*It))))>v(h+v(v(v(d*E)+v(m*V))+v(n*w)))),!r|t)break e;if(!(!!(v(y(v(v(a*z)-v(g*Dt))))>v(v(v(v(m*G)+v(n*F))+v(f*E))+v(h*D)))|v(y(v(v(a*Z)-v(g*pt))))>v(v(v(v(m*o)+v(n*R))+v(_*E))+v(h*B))|v(y(v(v(a*yt)-v(g*It))))>v(v(v(v(m*w)+v(n*V))+v(f*B))+v(_*D))|v(y(v(v(p*pt)-v(a*Q))))>v(v(v(v(d*o)+v(n*D))+v(_*V))+v(h*F))||v(y(v(v(p*Dt)-v(a*W))))>v(v(v(v(d*G)+v(n*B))+v(f*V))+v(h*R))|v(y(v(v(p*It)-v(a*Y))))>v(v(v(v(d*w)+v(n*E))+v(f*F))+v(_*R))|v(y(v(v(g*Q)-v(p*Z))))>v(v(v(v(d*R)+v(m*D))+v(_*w))+v(h*G))|v(y(v(v(g*W)-v(p*z))))>v(v(v(v(d*F)+v(m*B))+v(f*w))+v(h*o)))){if(i=0,v(y(v(v(g*Y)-v(p*yt))))>v(v(v(v(d*V)+v(m*E))+v(f*G))+v(_*o)))break e;return 1}}i=0}return i}(g+32|0,g,r,d))if(p=f[12+(f[e+16>>2]+D|0)>>2],D=f[12+(f[t+16>>2]+B|0)>>2],(0|D)>=0){if((0|p)>=0){if((0|(r=f[i+4>>2]))==f[i+8>>2]&&!((0|r)>=(0|(B=r?r<<1:1)))){B?(a=dA(B<<3),r=f[i+4>>2]):a=0,o=f[i+12>>2];e:{if((0|r)>=1)for(e=o,t=a,d=r;R=f[e+4>>2],f[t>>2]=f[e>>2],f[t+4>>2]=R,e=e+8|0,t=t+8|0,d=d+-1|0;);else if(!o)break e;_[i+16|0]&&(CA(o),r=f[i+4>>2]),f[i+12>>2]=0}f[i+12>>2]=a,n[i+16|0]=1,f[i+8>>2]=B}f[i+4>>2]=r+1,t=f[i+12>>2]+(r<<3)|0,f[t+4>>2]=p,f[t>>2]=D;break t}A(t,e,i,r,a,d=o+1|0,0),A(R=t,e,i,r,a,(0|(t=f[12+(f[e+16>>2]+(d<<4)|0)>>2]))>-1?o+2|0:d-t|0,0)}else d=a+1|0,(0|p)>=0?(A(t,e,i,r,d,o,0),R=t,t=f[12+(f[t+16>>2]+(d<<4)|0)>>2],A(R,e,i,r,(0|t)>-1?a+2|0:d-t|0,o,0)):(p=o+1|0,A(t,e,i,r,d,p,0),o=o+2|0,B=p<<4,D=f[12+(B+f[e+16>>2]|0)>>2],A(t,e,i,r,d,(0|D)>-1?o:p-D|0,0),a=a+2|0,D=d<<4,R=f[12+(D+f[t+16>>2]|0)>>2],A(t,e,i,r,(0|R)>-1?a:d-R|0,p,0),R=t,t=f[12+(D+f[t+16>>2]|0)>>2],a=(0|t)>-1?a:d-t|0,t=f[12+(B+f[e+16>>2]|0)>>2],A(R,e,i,r,a,(0|t)>-1?o:p-t|0,0));Z=g- -64|0}(t,i,a,o,0,0,1)),Z=o+112|0}function RA(t,e,i,r,n,a){var o=v(0),_=v(0),h=v(0),d=v(0),g=0,m=0,y=0,p=0,R=0,D=v(0),B=v(0),F=v(0),V=v(0),G=v(0);yt[f[f[t>>2]+8>>2]](t,e,n,a),o=C[i+8>>2],_=C[i+4>>2],d=C[n+8>>2],e=f[n+8>>2],D=C[n+4>>2],g=f[n+4>>2],B=C[n>>2],m=f[n>>2],F=C[a+8>>2],y=f[a+8>>2],V=C[a+4>>2],p=f[a+4>>2],G=C[a>>2],R=f[a>>2],(h=C[i>>2])>v(0)?(s(v(h+G)),R=c(0)):(s(v(h+B)),m=c(0)),_>v(0)?(s(v(_+V)),p=c(0)):(s(v(_+D)),g=c(0)),o>v(0)?(s(v(o+F)),y=c(0)):(s(v(o+d)),e=c(0)),o=C[r+8>>2],_=C[r>>2],h=C[r+4>>2],d=v(yt[f[f[t>>2]+16>>2]](t)),f[n+12>>2]=0,f[n+8>>2]=e,f[n+4>>2]=g,f[n>>2]=m,f[a+12>>2]=0,f[a+8>>2]=y,f[a+4>>2]=p,f[a>>2]=R,o=v(d*v(E(v(v(v(_*_)+v(h*h))+v(o*o))))),C[n>>2]=C[n>>2]-o,C[n+4>>2]=C[n+4>>2]-o,C[n+8>>2]=C[n+8>>2]-o,C[a>>2]=o+C[a>>2],C[a+4>>2]=o+C[a+4>>2],C[a+8>>2]=o+C[a+8>>2]}function QA(t,e,i){var r,n;return t|=0,e|=0,r=0|yt[f[f[(i|=0)>>2]+40>>2]](i,t),n=0|yt[f[f[i>>2]+28>>2]](i,r),f[e>>2]=n,n&&yt[f[f[i>>2]+48>>2]](i,r),t=f[t+4>>2],f[e+8>>2]=0,f[e+4>>2]=t,5872}function hA(t,e,i){t|=0,e|=0,i|=0;var r,n=v(0),a=0,o=v(0),_=v(0),h=0,d=v(0),g=0,m=v(0),y=v(0),p=0,R=v(0),D=v(0),B=0;Z=r=Z-48|0;t:{e:if(a=f[e+4>>2],!(a>>>0>13)){switch(a-1|0){case 7:f[t>>2]=0,f[t+4>>2]=0,f[(t=t+8|0)>>2]=0,f[t+4>>2]=0;break t;default:f[t+12>>2]=0,n=C[e+32>>2],C[t>>2]=C[i>>2]>=v(0)?n:v(-n),n=C[e+40>>2],C[t+8>>2]=C[i+8>>2]>=v(0)?n:v(-n),n=C[e+36>>2],C[t+4>>2]=C[i+4>>2]>=v(0)?n:v(-n);break t;case 0:f[t+12>>2]=0,n=C[i>>2],_=C[i+4>>2],o=C[i+8>>2],d=v(v(v(n*C[e+76>>2])+v(_*C[e+80>>2]))+v(o*C[e+84>>2])),m=v(v(v(n*C[e+92>>2])+v(_*C[e+96>>2]))+v(o*C[e+100>>2])),e=(((n=v(v(v(n*C[(i=e+60|0)>>2])+v(_*C[e- -64>>2]))+v(o*C[e+68>>2])))>2]=f[e+8>>2],i=f[e+4>>2],f[t>>2]=f[e>>2],f[t+4>>2]=i;break t;case 12:g=f[(h=e+40|0)+4>>2],f[(a=r+40|0)>>2]=f[h>>2],f[a+4>>2]=g,a=f[e+36>>2],f[r+32>>2]=f[e+32>>2],f[r+36>>2]=a,a=0,f[r+28>>2]=0,f[r+16>>2]=f[i>>2],_=C[i+4>>2],f[r+20>>2]=f[i+4>>2],n=C[i+8>>2],f[r+24>>2]=f[i+8>>2],i=1,g=2,(e=(h=f[e+56>>2])+-1|0)>>>0>1||(e-1?(i=0,a=1,g=2):(n=_,i=0,a=2,g=1)),e=g,_=C[(r+32|0)+(h<<2)>>2],d=C[((h=i<<2)|r+32)>>2],m=C[(h|r+16)>>2],(y=v(E(v(v(m*m)+v(n*n)))))==v(0)?(C[(i<<2|r)>>2]=d,C[(i=a<<2)+r>>2]=C[i+(r+16|0)>>2]>2]=m*o,C[(i=a<<2)+r>>2]=C[i+(r+16|0)>>2]>2]=o,f[t+12>>2]=0,f[t>>2]=f[r>>2],e=f[r+8>>2],f[t+4>>2]=f[r+4>>2],f[t+8>>2]=e;break t;case 9:h=e,B=f[e+56>>2],y=C[32+(h+(e=B<<2)|0)>>2],n=C[i>>2],_=C[i+4>>2],o=C[i+8>>2],(d=v(v(v(n*n)+v(_*_))+v(o*o)))>2]=0,f[r+44>>2]=0,f[r+32>>2]=0,f[r+36>>2]=0,C[e+(r+32|0)>>2]=y,n=v(-0xde0b6b000000000),e=0,i=0,a=0,h=f[r+32>>2],g=f[r+36>>2],p=f[r+40>>2],(_=v(v(v(o*C[r+32>>2])+v(d*C[r+36>>2]))+v(m*C[r+40>>2])))>v(-0xde0b6b000000000)&&(a=p,i=g,n=_,e=h),f[r+40>>2]=0,f[r+44>>2]=0,f[r+32>>2]=0,f[r+36>>2]=0,C[(r+32|0)+(B<<2)>>2]=-y,h=f[r+32>>2],g=f[r+36>>2],p=f[r+40>>2],v(v(v(o*C[r+32>>2])+v(d*C[r+36>>2]))+v(m*C[r+40>>2]))>n&&(a=p,i=g,e=h),f[t+12>>2]=0,f[t+8>>2]=a,f[t+4>>2]=i,f[t>>2]=e;break t;case 4:if(_=C[e+24>>2],o=C[e+20>>2],d=C[e+16>>2],h=f[e+96>>2],(0|(p=f[e+100>>2]))<1)a=-1;else for(m=v(C[i+8>>2]*_),y=v(C[i+4>>2]*o),D=v(C[i>>2]*d),i=0,a=-1,n=v(-34028234663852886e22),e=h;n=(g=(R=v(v(v(D*C[e>>2])+v(y*C[e+4>>2]))+v(m*C[e+8>>2])))>n)?R:n,a=g?i:a,e=e+16|0,(0|p)!=(0|(i=i+1|0)););f[t+12>>2]=0,e=h+(a<<4)|0,C[t+8>>2]=_*C[e+8>>2],C[t+4>>2]=o*C[e+4>>2],C[t>>2]=d*C[e>>2];break t;case 1:case 2:case 5:case 6:case 8:case 10:case 11:break e;case 3:}if(_=C[e+24>>2],o=C[e+20>>2],d=C[e+16>>2],h=f[e+108>>2],(0|(p=f[e+100>>2]))<1)a=-1;else for(m=v(C[i+8>>2]*_),y=v(C[i+4>>2]*o),D=v(C[i>>2]*d),i=0,a=-1,n=v(-34028234663852886e22),e=h;n=(g=(R=v(v(v(D*C[e>>2])+v(y*C[e+4>>2]))+v(m*C[e+8>>2])))>n)?R:n,a=g?i:a,e=e+16|0,(0|p)!=(0|(i=i+1|0)););f[t+12>>2]=0,e=h+(a<<4)|0,C[t+8>>2]=_*C[e+8>>2],C[t+4>>2]=o*C[e+4>>2],C[t>>2]=d*C[e>>2];break t}yt[f[f[e>>2]+68>>2]](t,e,i)}Z=r+48|0}function GA(t){var e=0;t:if(e=f[t+4>>2],!(e>>>0>13)){switch(e-2|0){case 6:return v(C[t+32>>2]*C[t+16>>2]);case 0:case 1:case 4:case 5:case 7:case 10:break t}return C[t+48>>2]}return v(yt[f[f[t>>2]+48>>2]](t))}function yA(t){return 12}function pA(t){CA(t|=0)}function FA(t,e){var i;e|=0,f[(t|=0)>>2]=0,f[t+4>>2]=0,f[(i=t+8|0)>>2]=0,f[i+4>>2]=0,f[(f[e+56>>2]<<2)+t>>2]=1065353216}function WA(t,e){e=v(e)}function wA(t){return 60}function DA(t){var e;f[t+12>>2]=-1,f[t+4>>2]=35,f[t+8>>2]=0,f[t>>2]=5928,f[t+48>>2]=1025758986,f[(e=t+24|0)>>2]=1065353216,f[e+4>>2]=0,f[t+16>>2]=1065353216,f[t+20>>2]=1065353216,f[t>>2]=6924}function EA(t,e){t|=0,e|=0;var i=v(0),r=v(0),n=v(0);i=C[e>>2],r=C[e+4>>2],n=C[e+8>>2],f[t+28>>2]=0,C[t+24>>2]=y(n),C[t+20>>2]=y(r),C[t+16>>2]=y(i)}function ZA(t){var e=0,i=0,r=0,a=0,o=0,h=0;if(f[(t|=0)>>2]=7060,(e=f[t+56>>2])&&(_[t+60|0]&&CA(e),f[t+56>>2]=0),f[t+56>>2]=0,f[t+48>>2]=0,f[t+52>>2]=0,n[t+60|0]=1,(0|(i=f[t+28>>2]))>=1)for(r=8;h=(e=f[t+36>>2]+r|0)+-4|0,(o=f[(a=e+4|0)>>2])&&(_[e+8|0]&&CA(o),f[a>>2]=0),f[h>>2]=0,f[a>>2]=0,f[e>>2]=0,n[e+8|0]=1,r=r+36|0,i=i+-1|0;);return(e=f[t+36>>2])&&(_[t+40|0]&&CA(e),f[t+36>>2]=0),f[t+36>>2]=0,f[t+28>>2]=0,f[t+32>>2]=0,n[t+40|0]=1,(e=f[t+16>>2])&&(_[t+20|0]&&CA(e),f[t+16>>2]=0),f[t+16>>2]=0,f[t+8>>2]=0,f[t+12>>2]=0,n[t+20|0]=1,0|t}function YA(t){var e,i,r=v(0),n=v(0),a=v(0),o=0,_=0,h=0,d=0;for(i=(0|(e=f[t+28>>2]))<1;;){t:if(!(_>>>0>7)){switch(_-1|0){default:r=v(C[t+88>>2]+C[t+72>>2]),n=v(C[t+84>>2]+C[t+68>>2]),a=v(C[t+80>>2]+C[t+64>>2]);break t;case 0:r=v(C[t+72>>2]-C[t+88>>2]),n=v(C[t+84>>2]+C[t+68>>2]),a=v(C[t+80>>2]+C[t+64>>2]);break t;case 1:r=v(C[t+88>>2]+C[t+72>>2]),n=v(C[t+68>>2]-C[t+84>>2]),a=v(C[t+80>>2]+C[t+64>>2]);break t;case 2:r=v(C[t+72>>2]-C[t+88>>2]),n=v(C[t+68>>2]-C[t+84>>2]),a=v(C[t+80>>2]+C[t+64>>2]);break t;case 3:r=v(C[t+88>>2]+C[t+72>>2]),n=v(C[t+84>>2]+C[t+68>>2]),a=v(C[t+64>>2]-C[t+80>>2]);break t;case 4:r=v(C[t+72>>2]-C[t+88>>2]),n=v(C[t+84>>2]+C[t+68>>2]),a=v(C[t+64>>2]-C[t+80>>2]);break t;case 5:r=v(C[t+88>>2]+C[t+72>>2]),n=v(C[t+68>>2]-C[t+84>>2]),a=v(C[t+64>>2]-C[t+80>>2]);break t;case 6:}r=v(C[t+72>>2]-C[t+88>>2]),n=v(C[t+68>>2]-C[t+84>>2]),a=v(C[t+64>>2]-C[t+80>>2])}t:{if(!i)for(o=f[t+36>>2]+20|0,d=0,h=0;;){if(v(C[o+12>>2]+v(v(v(a*C[o>>2])+v(n*C[o+4>>2]))+v(r*C[o+8>>2])))>v(0))break t;if(o=o+36|0,!((0|(h=h+1|0))<(0|e)))break}if(d=1,8!=(0|(_=_+1|0)))continue}break}return d}function VA(t){var e,i=0,r=v(0),o=0,g=0,p=v(0),R=0,D=v(0),B=0,F=v(0),V=0,G=0,w=v(0),Q=v(0),W=0,Y=0,z=0,yt=v(0),pt=v(0),Dt=v(0),It=v(0),St=0,Tt=0,Et=0,Ot=0,Nt=0,Ft=0,Vt=v(0),Gt=v(0),Lt=v(0),wt=v(0),xt=v(0),Qt=v(0),Wt=v(0),Yt=v(0),Pt=v(0),Mt=v(0);if(Z=e=Z-96|0,f[t+64>>2]=0,f[t+68>>2]=0,n[e+52|0]=1,f[e+48>>2]=0,n[e+72|0]=1,f[(i=e+40|0)>>2]=0,f[i+4>>2]=0,f[e+68>>2]=0,n[e+92|0]=1,f[(i=e+60|0)>>2]=0,f[i+4>>2]=0,f[e+88>>2]=0,f[(i=e+80|0)>>2]=0,f[i+4>>2]=0,f[(i=t+72|0)>>2]=0,f[i+4>>2]=0,f[e+28>>2]=0,n[e+32|0]=1,f[e+20>>2]=0,f[e+24>>2]=0,!((0|(W=f[t+28>>2]))<1)){for(;;){if(o=f[t+36>>2],St=m(z,36),(0|(Tt=f[4+(o+St|0)>>2]))>=1){for(Nt=0;;){i=f[12+(o+St|0)>>2],B=f[i+(Nt<<2)>>2],a[e+8>>1]=B,g=f[i+(((W=(0|Tt)==(0|(Nt=Nt+1|0)))?0:Nt)<<2)>>2],a[e+10>>1]=g,Ft=0,(0|(i=g<<16>>16))>(0|(R=B<<16>>16))&&(a[e+10>>1]=B,a[e+8>>1]=g,R=g,i=B);t:if(!((g=(Et=i<<16)+(G=R<<16>>16)&f[e+64>>2]+-1)>>>0>=d[e+20>>2])&&(o=f[f[e+28>>2]+(g<<2)>>2],-1!=(0|o))){for(V=f[e+48>>2],B=f[e+88>>2];;){if(h[(g=(Ot=o<<2)+B|0)+2>>1]!=(65535&i)||h[g>>1]!=(65535&R)){if(-1!=(0|(o=f[V+Ot>>2])))continue;break t}break}Ft=Ot+f[e+68>>2]|0}g=(i=f[t+16>>2])+(Et>>16<<4)|0,i=i+(G<<4)|0,F=r=v(C[g+8>>2]-C[i+8>>2]),p=v(C[g>>2]-C[i>>2]),D=v(C[g+4>>2]-C[i+4>>2]),r=v(v(1)/v(E(v(v(v(p*p)+v(D*D))+v(r*r))))),F=v(F*r),w=v(D*r),Q=v(p*r);t:{if((0|(R=f[t+48>>2]))>=1)for(o=f[t+56>>2],Y=0;;){if(p=C[o+8>>2],r=C[o>>2],D=C[o+4>>2],(+v(y(v(p-F)))>1e-6^1?!(+v(y(v(r-Q)))>1e-6|+v(y(v(D-w)))>1e-6):0)|(+v(y(v(F+p)))>1e-6^1?!(+v(y(v(Q+r)))>1e-6|+v(y(v(w+D)))>1e-6):0))break t;if(o=o+16|0,!((0|(Y=Y+1|0))<(0|R)))break}if(f[t+52>>2]==(0|R)&&!((0|R)>=(0|(V=R?R<<1:1)))){if(V?(G=dA(V<<4),R=f[t+48>>2]):G=0,(0|R)>=1)for(o=0;g=f[t+56>>2]+o|0,i=f[g+4>>2],f[(B=o+G|0)>>2]=f[g>>2],f[B+4>>2]=i,i=f[(g=g+8|0)+4>>2],f[(B=B+8|0)>>2]=f[g>>2],f[B+4>>2]=i,o=o+16|0,R=R+-1|0;);(i=f[t+56>>2])&&(_[t+60|0]&&CA(i),f[t+56>>2]=0),f[t+56>>2]=G,n[t+60|0]=1,f[t+52>>2]=V,R=f[t+48>>2]}i=f[t+56>>2]+(R<<4)|0,f[i+12>>2]=0,C[i+8>>2]=F,C[i+4>>2]=w,C[i>>2]=Q,f[t+48>>2]=f[t+48>>2]+1}if(Ft?a[Ft+2>>1]=z:(a[e>>1]=z,a[e+2>>1]=65535,NA(e+16|0,e+8|0,e)),W)break;o=f[t+36>>2]}W=f[t+28>>2]}if(!((0|(z=z+1|0))<(0|W)))break}if(Ot=0,!((0|W)<1))for(Ot=(0|W)>0,St=f[t+16>>2],B=f[t+36>>2],z=0;;){if(i=B+m(z,36)|0,(0|(Tt=f[i+4>>2]))>=3)for(o=(Et=f[i+12>>2])+4|0,g=(G=St+(f[Et>>2]<<4)|0)+8|0,i=G+4|0,yt=C[t+72>>2],pt=C[t+68>>2],Dt=C[t+64>>2],Y=2;V=St+(f[o>>2]<<4)|0,wt=C[V+8>>2],R=St+(f[Et+((0|Y)%(0|Tt)<<2)>>2]<<4)|0,xt=C[R+8>>2],Vt=C[G>>2],Qt=C[V>>2],Wt=v(Vt-Qt),Gt=C[i>>2],Yt=C[R+4>>2],F=v(Gt-Yt),w=C[V+4>>2],r=v(Gt-w),Q=C[R>>2],p=v(Vt-Q),Pt=v(v(Wt*F)-v(r*p)),Lt=C[g>>2],D=v(Lt-xt),Mt=v(r*D),r=v(Lt-wt),F=v(Mt-v(r*F)),r=v(v(r*p)-v(Wt*D)),r=v(v(E(v(v(Pt*Pt)+v(v(F*F)+v(r*r)))))*v(.5)),yt=v(yt+v(v(v(v(Lt+wt)+xt)*v(.3333333432674408))*r)),C[t+72>>2]=yt,pt=v(pt+v(v(v(Yt+v(Gt+w))*v(.3333333432674408))*r)),C[t+68>>2]=pt,Dt=v(Dt+v(v(v(Q+v(Vt+Qt))*v(.3333333432674408))*r)),C[t+64>>2]=Dt,It=v(It+r),o=o+4|0,(0|Tt)!=(0|(Y=Y+1|0)););if((0|(z=z+1|0))==(0|W))break}}if(f[t+96>>2]=2139095039,r=v(v(1)/It),F=v(r*C[t+64>>2]),C[t+64>>2]=F,w=v(r*C[t+68>>2]),C[t+68>>2]=w,Q=v(r*C[t+72>>2]),C[t+72>>2]=Q,p=v(34028234663852886e22),D=v(34028234663852886e22),Ot)for(o=f[t+36>>2]+20|0;(r=v(y(v(C[o+12>>2]+v(v(v(F*C[o>>2])+v(w*C[o+4>>2]))+v(Q*C[o+8>>2]))))))>2]=r,D=r),o=o+36|0,W=W+-1|0;);if((0|(i=f[t+8>>2]))<1)F=v(-34028234663852886e22),yt=v(34028234663852886e22),pt=v(-34028234663852886e22),Dt=v(-34028234663852886e22),It=v(34028234663852886e22);else for(o=f[t+16>>2],Dt=v(-34028234663852886e22),Y=0,It=v(34028234663852886e22),pt=v(-34028234663852886e22),F=v(-34028234663852886e22),yt=v(34028234663852886e22);Dt=(r=C[o+8>>2])>Dt?r:Dt,yt=r>2])>pt?r:pt,p=r>2])>F?r:F,It=r>2]=0,w=v(Dt-yt),C[t+124>>2]=w,Q=v(pt-p),C[t+120>>2]=Q,r=v(F-It),C[t+116>>2]=r,f[t+112>>2]=0,C[t+108>>2]=yt+Dt,C[t+104>>2]=p+pt,C[t+100>>2]=F+It,r=C[(i=(g=r>2],p=v(D/v(1.7320507764816284)),C[t+88>>2]=p,C[t+80>>2]=p,C[t+84>>2]=p,i=i+(t+80|0)|0,D=v(r*v(.5)),C[i>>2]=D,r=v(v(D-p)*v(.0009765625)),o=1024;t:{e:{for(;;){if(YA(t))break e;if(D=v(D-r),C[i>>2]=D,!(o=o+-1|0))break}C[t+84>>2]=p,C[t+88>>2]=p,C[t+80>>2]=p;break t}if(G=f[(V=(i=t+80|0)+((1<<(g=1<>2],g=f[(i=B=i+(g<<2)|0)>>2],D=v(v(C[t+96>>2]-p)*v(.0009765625)),C[i>>2]=D+C[i>>2],p=v(D+C[V>>2]),C[V>>2]=p,YA(t)){for(R=1024;;){if(r=p,!(R=R+-1|0))break t;if(g=f[B>>2],C[B>>2]=D+C[B>>2],p=v(D+C[V>>2]),C[V>>2]=p,!YA(t))break}s(r),G=c(0)}f[B>>2]=g,f[V>>2]=G}(t=f[e+88>>2])&&(_[e+92|0]&&CA(t),f[e+88>>2]=0),f[e+88>>2]=0,n[e+92|0]=1,f[e+80>>2]=0,f[e+84>>2]=0,(t=f[e+68>>2])&&(_[e+72|0]&&CA(t),f[e+68>>2]=0),f[e+68>>2]=0,n[e+72|0]=1,f[e+60>>2]=0,f[e+64>>2]=0,(t=f[e+48>>2])&&(_[e+52|0]&&CA(t),f[e+48>>2]=0),f[e+48>>2]=0,n[e+52|0]=1,f[e+40>>2]=0,f[e+44>>2]=0,(t=f[e+28>>2])&&(_[e+32|0]&&CA(t),f[e+28>>2]=0),Z=e+96|0}function NA(t,e,i){var r=0,o=0,C=0,g=0,m=0,v=0,y=0,p=0,R=0;t:{if(!((R=(C=a[e>>1])+((o=h[e+2>>1])<<16)&(y=f[t+48>>2])+-1)>>>0>=d[t+4>>2])&&-1!=(0|(r=f[f[t+12>>2]+(R<<2)>>2])))for(m=f[t+72>>2],C&=65535;;){if(h[(g=(v=r<<2)+m|0)+2>>1]==(0|o)&&h[g>>1]==(0|C))break t;if(-1==(0|(r=f[v+f[t+32>>2]>>2])))break}if((0|(r=v=f[t+44>>2]))==(0|y)&&!((0|(r=y))>=(0|(m=r?r<<1:1)))){if(m?(C=dA(m<<2),r=f[t+44>>2]):(C=0,r=y),(0|(o=r))>=1)for(r=0;g=r+C|0,p=f[t+52>>2]+r|0,p=h[p>>1]|h[p+2>>1]<<16,a[g>>1]=p,a[g+2>>1]=p>>>16,r=r+4|0,o=o+-1|0;);(r=f[t+52>>2])&&(_[t+56|0]&&CA(r),f[t+52>>2]=0),f[t+52>>2]=C,f[t+48>>2]=m,n[t+56|0]=1,r=f[t+44>>2]}if(r=f[t+52>>2]+(r<<2)|0,i=h[i>>1]|h[i+2>>1]<<16,a[r>>1]=i,a[r+2>>1]=i>>>16,f[t+44>>2]=f[t+44>>2]+1,(0|(o=f[t- -64>>2]))==f[t+68>>2]&&!((0|o)>=(0|(i=o?o<<1:1)))){if(i?(C=dA(i<<2),o=f[t+64>>2]):C=0,(0|o)>=1)for(r=0;m=r+C|0,g=f[t+72>>2]+r|0,g=h[g>>1]|h[g+2>>1]<<16,a[m>>1]=g,a[m+2>>1]=g>>>16,r=r+4|0,o=o+-1|0;);(r=f[t+72>>2])&&(_[t+76|0]&&CA(r),f[t+72>>2]=0),f[t+72>>2]=C,f[t+68>>2]=i,n[t+76|0]=1,o=f[t+64>>2]}return i=f[t+72>>2]+(o<<2)|0,r=h[e>>1]|h[e+2>>1]<<16,a[i>>1]=r,a[i+2>>1]=r>>>16,f[t+64>>2]=f[t+64>>2]+1,(0|y)>2]&&(function(t){var e,i,r=0,o=0,d=0,C=0,g=0,m=0,v=0;if(!((0|(i=f[t+4>>2]))>=(0|(e=f[t+48>>2])))){if(f[t+8>>2]>=(0|e))d=f[t+12>>2];else{e?(d=dA(e<<2),o=f[t+4>>2]):o=i,g=f[t+12>>2];e:{if((0|o)>=1)for(C=d,r=g;f[C>>2]=f[r>>2],C=C+4|0,r=r+4|0,o=o+-1|0;);else if(!g)break e;_[t+16|0]&&CA(g)}f[t+12>>2]=d,n[t+16|0]=1,f[t+8>>2]=e}if(X((r=i<<2)+d|0,0,(m=e<<2)-r|0),f[t+4>>2]=e,(0|(v=f[t+24>>2]))<(0|e)){e:if(f[t+28>>2]>=(0|e))d=f[t+32>>2];else{if(e?(d=dA(m),o=f[t+24>>2]):(d=0,o=v),g=f[t+32>>2],(0|o)>=1)for(C=d,r=g;f[C>>2]=f[r>>2],C=C+4|0,r=r+4|0,o=o+-1|0;);else if(!g){f[t+32>>2]=d,f[t+28>>2]=e,n[t+36|0]=1;break e}_[t+36|0]&&CA(g),f[t+32>>2]=d,n[t+36|0]=1,f[t+28>>2]=e}X((r=v<<2)+d|0,0,m-r|0)}if(f[t+24>>2]=e,(0|e)>=1&&(X(f[t+12>>2],255,m),X(f[t+32>>2],255,m)),!((0|i)<1))for(r=f[t+32>>2],C=f[t+72>>2],g=f[t+12>>2],o=0;d=g+((a[C>>1]+(h[C+2>>1]<<16)&f[t+48>>2]+-1)<<2)|0,f[r>>2]=f[d>>2],f[d>>2]=o,C=C+4|0,r=r+4|0,(0|(o=o+1|0))!=(0|i););}}(t),R=a[e>>1]+(h[e+2>>1]<<16)&f[t+48>>2]+-1),e=f[t+32>>2]+(v<<2)|0,t=f[t+12>>2]+(R<<2)|0,f[e>>2]=f[t>>2],void(f[t>>2]=v)}t=f[t+52>>2]+(r<<2)|0,e=h[i>>1]|h[i+2>>1]<<16,a[t>>1]=e,a[t+2>>1]=e>>>16}function IA(t,e,i,r,n,a,o){var _=v(0),h=0,d=v(0),g=0,m=0,y=v(0),p=v(0),R=v(0);if(f[r>>2]=2139095039,h=-8388609,f[n>>2]=-8388609,g=f[t+8>>2],_=v(-34028234663852886e22),!((0|g)<1)){for(h=4;m=f[t+16>>2]+h|0,_=C[m+-4>>2],d=C[m>>2],y=C[m+4>>2],p=v(v(v(v(_*C[e>>2])+v(d*C[e+4>>2]))+v(y*C[e+8>>2]))+C[e+48>>2]),R=v(v(v(v(_*C[e+16>>2])+v(d*C[e+20>>2]))+v(y*C[e+24>>2]))+C[e+52>>2]),d=v(v(v(v(_*C[e+32>>2])+v(d*C[e+36>>2]))+v(y*C[e+40>>2]))+C[e+56>>2]),(_=v(v(v(p*C[i>>2])+v(R*C[i+4>>2]))+v(d*C[i+8>>2])))>2]&&(C[r>>2]=_,f[a+12>>2]=0,C[a+8>>2]=d,C[a+4>>2]=R,C[a>>2]=p),_>C[n>>2]&&(C[n>>2]=_,f[o+12>>2]=0,C[o+8>>2]=d,C[o+4>>2]=R,C[o>>2]=p),h=h+16|0,g=g+-1|0;);h=f[n>>2],_=C[n>>2]}(d=C[r>>2])>_&&(f[r>>2]=h,C[n>>2]=d,i=f[(t=a+8|0)>>2],r=f[t+4>>2],h=f[(e=o+8|0)+4>>2],f[t>>2]=f[e>>2],f[t+4>>2]=h,t=f[a>>2],n=f[a+4>>2],h=f[o+4>>2],f[a>>2]=f[o>>2],f[a+4>>2]=h,f[o>>2]=t,f[o+4>>2]=n,f[e>>2]=i,f[e+4>>2]=r)}function JA(t,e){var i,r,n=0,a=0,o=0,_=0,h=0,d=0,C=0,g=0,v=0,y=0,p=0,R=0,D=0;return(0|(i=f[t+16>>2]))!=(0|(a=f[e+16>>2]))?i-a|0:i?(R=-1,h=f[t+4>>2],d=f[e+8>>2],v=_t(C=f[e+12>>2],0,p=f[t>>2],0),g=z,C=_t(C,o,h,0),a=z+_|0,_=n=C+g|0,n=n>>>0>>0?a+1|0:a,h=_t(d,C=0,h,o),(o=(a=_)+(_=z)|0)>>>0<_>>>0&&(n=n+1|0),a=o,_=n,o=0,(n=h+v|0)>>>0>>0&&(o=o+1|0),v=o,o=o+a|0,a=_,a=o>>>0>>0?a+1|0:a,_=o,o=n,v=0,d=_t(d,C,p,D),n=z+n|0,n=(h=v+d|0)>>>0>>0?n+1|0:n,r=h,d=h,h=n,(n=_+(o=(0|o)==(0|n)&d>>>0>>0|n>>>0>>0)|0)>>>0>>0&&(a=a+1|0),v=n,d=a,C=n,p=a,o=f[t+8>>2],t=f[t+12>>2],n=f[e>>2],D=o,_=_t(g=f[e+4>>2],a=0,o,0),e=z,y=t,g=_t(g,a,t,o=0),a=z,a=(t=e+g|0)>>>0>>0?a+1|0:a,e=t,g=n,t=_t(n,0,y,o),n=a,o=n=(e=(y=z)+e|0)>>>0>>0?n+1|0:n,a=0,(n=t+_|0)>>>0>>0&&(a=a+1|0),y=a,_=a+e|0,a=o,o=(e=_)>>>0>>0?a+1|0:a,y=e,e=0,_=_t(g,0,D,0),a=n,n=n+z|0,n=(t=e+_|0)>>>0<_>>>0?n+1|0:n,_=t,t=n,(a=y+(e=(0|a)==(0|n)&_>>>0>>0|n>>>0>>0)|0)>>>0>>0&&(o=o+1|0),e=o,(0|o)==(0|p)&C>>>0<(n=a)>>>0|p>>>0>>0||(R=1,(0|e)==(0|d)&v>>>0>a>>>0|d>>>0>e>>>0||(R=-1,(0|t)==(0|h)&r>>>0<_>>>0|h>>>0>>0||(R=(0|t)==(0|h)&r>>>0>_>>>0|h>>>0>t>>>0))),m(R,i)):0}function xA(t,e,i){var r=0,n=0,a=0,o=0,_=0,h=0,d=0,C=0;if(!((o=f[t+56>>2])||(r=f[t+52>>2],r?f[t+52>>2]=f[r+8>>2]:(r=dA(12),f[r+8>>2]=0,n=f[t+60>>2],f[r+4>>2]=n,d=r,C=dA(m(n,24)),f[d>>2]=C,n=f[t+48>>2],f[t+48>>2]=r,f[r+8>>2]=n),o=f[r>>2],a=f[r+4>>2],(0|a)<1)))for(r=0,n=o;_=n,n=n+24|0,r=r+1|0,f[_>>2]=(0|r)<(0|a)?n:0,(0|r)!=(0|a););if(f[t+56>>2]=f[o>>2],f[(n=o+8|0)>>2]=0,f[n+4>>2]=0,f[(n=o+16|0)>>2]=0,f[n+4>>2]=0,f[o>>2]=0,f[o+4>>2]=0,!((a=f[t+56>>2])||(r=f[t+52>>2],r?f[t+52>>2]=f[r+8>>2]:(r=dA(12),f[r+8>>2]=0,n=f[t+60>>2],f[r+4>>2]=n,d=r,C=dA(m(n,24)),f[d>>2]=C,n=f[t+48>>2],f[t+48>>2]=r,f[r+8>>2]=n),a=f[r>>2],h=f[r+4>>2],(0|h)<1)))for(r=0,n=a;_=n,n=n+24|0,r=r+1|0,f[_>>2]=(0|r)<(0|h)?n:0,(0|r)!=(0|h););return f[t+56>>2]=f[a>>2],f[a>>2]=0,f[a+4>>2]=0,f[o+8>>2]=a,f[o+12>>2]=i,f[o+16>>2]=0,i=f[t+100>>2],f[o+20>>2]=i,f[a+8>>2]=o,f[a+12>>2]=e,f[a+16>>2]=0,f[a+20>>2]=i,i=(e=f[t+116>>2])+1|0,f[t+116>>2]=i,(0|e)>=f[t+120>>2]&&(f[t+120>>2]=i),o}function UA(t,e,i,r){var n,a=0,o=0,_=0,h=0,d=0,C=0,g=0;Z=n=Z-16|0;t:if((a=i-e|0)>>>0<=2){switch(a-1|0){default:f[r>>2]=0,f[r+4>>2]=0,f[(t=r+8|0)>>2]=0,f[t+4>>2]=0;break t;case 1:if(i=f[f[t+92>>2]+(e<<2)>>2],a=f[i+204>>2],(0|(h=f[i+88>>2]))!=(0|(_=f[i+200>>2]))|(0|(o=f[i+92>>2]))!=(0|a)||(a=o,f[i+96>>2]!=f[i+208>>2])){e=i+112|0,(a=o-a|0)|(o=h-_|0)?(f[i+4>>2]=e,f[i>>2]=e,f[i+116>>2]=i,f[i+112>>2]=i,_=(d=(h=(0|a)<0)&!o)|(o=(0|o)<0),f[r+4>>2]=_?e:i,f[r>>2]=_?i:e,o&!a||h?(f[r+8>>2]=i,a=e):(f[r+8>>2]=e,a=i)):(a=(o=f[i+96>>2]>f[i+208>>2])?e:i,f[r+8>>2]=a,f[r+4>>2]=a,f[r>>2]=a,f[a+4>>2]=a,f[a>>2]=a,e=o?i:e,i=a),f[r+12>>2]=a,t=xA(t,i,e),f[i+8>>2]=t,i=e,e=f[t+8>>2],f[i+8>>2]=e,f[t+4>>2]=t,f[t>>2]=t,f[e+4>>2]=e,f[e>>2]=e;break t}f[i+8>>2]=0,f[r+12>>2]=i,f[r+8>>2]=i,f[r+4>>2]=i,f[r>>2]=i,f[i+4>>2]=i,f[i>>2]=i;break t;case 0:}t=f[f[t+92>>2]+(e<<2)>>2],f[t+8>>2]=0,f[r+12>>2]=t,f[r+8>>2]=t,f[r+4>>2]=t,f[r>>2]=t,f[t+4>>2]=t,f[t>>2]=t}else{e:if(!((0|(o=h=(_=(0|a)/2|0)+e|0))>=(0|i))){for(o=f[t+92>>2],a=f[(o+(h<<2)|0)-4>>2],C=f[a+88>>2],g=f[a+96>>2],d=f[a+92>>2],a=o+(e+_<<2)|0,o=h;;){if(_=f[a>>2],(0|C)!=f[_+88>>2]|f[_+92>>2]!=(0|d)|f[_+96>>2]!=(0|g))break e;if(a=a+4|0,(0|(o=o+1|0))==(0|i))break}o=i}UA(t,e,h,r),f[(e=n+8|0)>>2]=0,f[e+4>>2]=0,f[n>>2]=0,f[n+4>>2]=0,UA(t,o,i,n),function(t,e,i){var r,n=0,a=0,o=0,_=0,h=0,d=0,C=0,g=0,v=0,y=0,p=0,R=0,D=0,B=0,E=0,F=0,V=0,G=0,w=0,Q=0,W=0,Y=0,yt=0,pt=0,Dt=0,It=0,St=0,Tt=0,Et=0,Ot=0,Nt=0,Ft=0;Z=r=Z-128|0;e:if(f[i+4>>2])if(f[e+4>>2]){if(f[t+100>>2]=f[t+100>>2]+-1,f[r+124>>2]=0,f[r+120>>2]=0,e=function(t,e,i,r){var n=0,a=0,o=0,_=0,h=0,d=0,C=0,g=0,v=0,y=0,p=0,R=0,D=0,B=0,E=0,F=0,V=0,G=0,w=0;o=f[t+12>>2],g=f[e+8>>2];i:{if(!(f[o+88>>2]!=f[g+88>>2]|f[o+92>>2]!=f[g+92>>2])){if((0|g)==(0|(n=f[g+4>>2]))){if(f[i>>2]=o,e=0,!(t=f[g+8>>2]))break i;return f[r>>2]=f[t+12>>2],0}o=f[g>>2],f[o+4>>2]=n,f[n>>2]=o,(0|g)==f[e>>2]&&(d=e,v=o,(0|(a=f[o+88>>2]))<(0|(_=f[n+88>>2]))|(f[o+92>>2]>2]?(0|a)==(0|_):0)||(v=n),f[d>>2]=v),f[e+4>>2]==(0|g)&&((0|(a=f[o+88>>2]))!=(0|(_=f[n+88>>2]))|f[o+92>>2]<=f[n+92>>2]&&(0|a)<=(0|_)?f[e+4>>2]=n:f[e+4>>2]=o)}for(F=f[e>>2],G=f[t>>2],_=w=f[t+4>>2],a=V=f[e+4>>2],g=0,v=1;;){p=f[_+88>>2];A:if((0|(n=m(f[a+88>>2]-p|0,v)))>=1)for(d=_;;){for(o=a,h=f[a+92>>2],_=n;p=h-(a=f[d+92>>2])|0,!((0|(n=f[(C=!R<<2)+d>>2]))==(0|d)||(y=f[n+92>>2]-a|0,(0|y)>0||(D=f[n+88>>2],a=m(D-f[d+88>>2]|0,v),(0|a)>-1|(0|m(_,y))>(0|m(a,p))&&a)));)_=m(f[o+88>>2]-D|0,v),d=n;if((0|o)==(0|(a=f[o+C>>2])))break A;if((0|(C=f[a+92>>2]-h|0))>-1)break A;if(h=f[a+88>>2],(0|(n=m(h-f[d+88>>2]|0,v)))<1)break A;if(h=m(h-f[o+88>>2]|0,v)){if((0|h)>-1)break A;if(!((0|m(_,C))<(0|m(h,p))))break}}else if((0|n)<=-1){r:for(;;){for(p=f[a+92>>2],o=f[(D=(0!=(0|R))<<2)+a>>2];;){if(h=n,d=_,C=p-(y=f[_+92>>2])|0,(0|a)!=(0|o)&&!((0|(_=f[o+92>>2]-p|0))<0||(B=f[o+88>>2],n=m(B-f[a+88>>2]|0,v),(0|n)>-1|(0|m(_,h))>(0|m(n,C))&&n))){n=m(B-f[d+88>>2]|0,v),a=o,_=d;continue r}if((0|d)==(0|(_=f[d+D>>2]))){o=a;break A}if((0|(B=f[_+92>>2]-y|0))<1){o=a;break A}if(y=f[_+88>>2],(0|(n=m(f[a+88>>2]-y|0,v)))>-1){o=a;break A}if(y=m(y-f[d+88>>2]|0,v)){if((0|y)>-1){o=a;break A}if(!((0|m(h,B))<(0|m(C,y))))break}}break}o=a}else{o=f[_+92>>2];r:if(R)for(n=_;;){if(d=n,(0|_)==(0|(n=f[n>>2]))|(0|p)!=f[n+88>>2])break r;if(C=(0|(h=f[n+92>>2]))>(0|o),o=h,C)break}else for(n=_;;){if(d=n,(0|_)==(0|(n=f[n+4>>2]))|(0|p)!=f[n+88>>2])break r;if(C=(0|(h=f[n+92>>2]))<=(0|o),o=h,!C)break}if(_=f[a+92>>2],R)for(n=a;;){if(o=n,(0|(n=f[n+4>>2]))==(0|a)|(0|p)!=f[n+88>>2])break A;if(C=(0|(h=f[n+92>>2]))<(0|_),_=h,C)break}else for(n=a;;){if(o=n,(0|(n=f[n>>2]))==(0|a)|(0|p)!=f[n+88>>2])break A;if(C=(0|(h=f[n+92>>2]))>=(0|_),_=h,!C)break}}if(_=R?d:G,a=R?o:F,E=R?E:d,g=R?g:o,v=R?v:-1,2==(0|(R=R+1|0)))break}f[a>>2]=_,f[_+4>>2]=a,f[E>>2]=g,f[g+4>>2]=E,f[F+88>>2]>2]&&(f[t>>2]=F),f[V+88>>2]>=f[w+88>>2]&&(f[t+4>>2]=V),f[t+12>>2]=f[e+12>>2],f[i>>2]=E,e=1}return t=e,f[r>>2]=g,t}(e,i,r+124|0,r+120|0),B=f[r+120>>2],e){if(Q=f[r+124>>2],It=f[Q+96>>2],St=f[B+96>>2],pt=f[Q+92>>2],D=f[B+92>>2],n=f[Q+8>>2],E=f[Q+88>>2],Tt=f[B+88>>2],f[r+80>>2]=0,a=e=St-It|0,o=e>>31,V=e=D-pt|0,Et=_t(a,o,e,G=e>>31),Ot=z,yt=e=0-(i=Tt-E|0)|0,e=_t(e,W=e>>31,i,i>>31),_=z,Nt=e-(i=_t(V,G,V,G))|0,R=_-(z+(e>>>0>>0)|0)|0,p=0-(e=_t(yt,W,a,o))|0,Y=0-(z+(0>>0)|0)|0,n){for(i=n;;){C=f[i+12>>2],h=e=(v=f[C+92>>2])-pt|0,e=_t(e,d=e>>31,yt,W),_=z,Dt=e,a=e=(y=f[C+88>>2])-E|0;i:if(!((0|Dt)!=(0-(e=_t(V,G,e,o=e>>31))|0)|(0-(z+(0>>0)|0)|0)!=(0|_)||(e=_t(Et,Ot,h,d),_=z,h=e,e=_t(a,o,p,Y),o=h+e|0,a=z+_|0,a=o>>>0>>0?a+1|0:a,_=f[C+96>>2],e=_-It|0,e=_t(Nt,R,e,e>>31),o=e+o|0,a=z+a|0,a=o>>>0>>0?a+1|0:a,(0|a)<0||(0|a)<=0&&!(o>>>0>=1)))){A:if(g){if(e=f[g+4>>2],(0|i)==f[g>>2]){if((0|e)!=(0|i))break i;if(h=f[f[i+8>>2]+12>>2],d=_-(e=f[h+96>>2])|0,a=f[g+12>>2],o=f[a+96>>2]-e|0,e=f[h+92>>2],e=_t(e=m(d,f[a+92>>2]-e|0)-m(o,v-e|0)|0,e>>31,V,G),_=z,v=e,e=f[h+88>>2],e=_t(e=m(o,y-e|0)-m(d,f[a+88>>2]-e|0)|0,e>>31,yt,W),a=z+_|0,(0|(a=(o=v+e|0)>>>0>>0?a+1|0:a))<0||(0|a)<=0&&!(o>>>0>0))break A;break i}if((0|e)!=(0|i))break i}g=i}if((0|n)==(0|(i=f[i>>2])))break}f[r+80>>2]=g}if(e=f[B+8>>2],y=0,f[r+56>>2]=0,e){for(i=e;;){E=f[i+12>>2],v=n=(C=f[E+92>>2])-D|0,n=_t(n,h=n>>31,yt,W),_=z,pt=n,a=n=(d=f[E+88>>2])-Tt|0;i:if(!((0|pt)!=(0-(n=_t(V,G,n,o=n>>31))|0)|(0-(z+(0>>0)|0)|0)!=(0|_)||(n=_t(Et,Ot,v,h),_=z,h=n,n=_t(a,o,p,Y),o=h+n|0,a=z+_|0,a=o>>>0>>0?a+1|0:a,_=f[E+96>>2],n=_-St|0,n=_t(Nt,R,n,n>>31),o=n+o|0,a=z+a|0,a=o>>>0>>0?a+1|0:a,(0|a)<0||(0|a)<=0&&!(o>>>0>=1)))){if(y){if(f[y>>2]!=(0|i))break i;if(f[y+4>>2]==(0|i)&&(v=f[f[i+8>>2]+12>>2],h=_-(n=f[v+96>>2])|0,a=f[y+12>>2],o=f[a+96>>2]-n|0,n=f[v+92>>2],n=_t(n=m(h,f[a+92>>2]-n|0)-m(o,C-n|0)|0,n>>31,V,G),_=z,C=n,n=f[v+88>>2],n=_t(n=m(o,d-n|0)-m(h,f[a+88>>2]-n|0)|0,n>>31,yt,W),_=z+_|0,(0|(_=(o=C+n|0)>>>0>>0?_+1|0:_))<0||(0|_)<=0&&!(o>>>0>=1)))break i}y=i}if((0|e)==(0|(i=f[i>>2])))break}f[r+56>>2]=y}g|y&&(MA(t,Q,B,r+80|0,r+56|0),(e=f[r+80>>2])&&(Q=f[e+12>>2],f[r+124>>2]=Q),(e=f[r+56>>2])&&(B=f[e+12>>2],f[r+120>>2]=B)),Dt=f[B+96>>2]+1|0,Ft=f[B+92>>2],V=f[B+88>>2]}else Dt=f[B+96>>2],Ft=f[B+92>>2],Q=f[r+124>>2],V=f[B+88>>2]+1|0;for(y=Q,o=B,a=0,e=0,Y=0,It=1,C=0,g=0,E=0;;){f[r+116>>2]=-1,Tt=o+92|0,d=f[(Et=y+92|0)>>2],n=f[Tt>>2]-d|0,f[r+108>>2]=n,Ot=o+96|0,_=f[(Nt=y+96|0)>>2],h=f[Ot>>2]-_|0,f[r+112>>2]=h,p=f[y+88>>2],i=f[o+88>>2]-p|0,f[r+104>>2]=i,v=Ft-d|0,d=Dt-_|0,G=(_=m(v,h)-m(d,n)|0)>>31,St=_,f[r+80>>2]=_,f[r+84>>2]=G,yt=(_=(_=m(i,d))-m(d=V-p|0,h)|0)>>31,pt=_,f[r+88>>2]=_,f[r+92>>2]=yt,W=(_=m(n,d)-m(i,v)|0)>>31,D=_,f[r+96>>2]=_,f[r+100>>2]=W,d=i,i=_t(pt,yt,i,R=i>>31),v=z,_=n,n=_t(St,G,n,p=n>>31),f[r+72>>2]=i-n,f[r+76>>2]=v-(z+(i>>>0>>0)|0),i=_t(St,G,n=h,v=n>>31),h=z,d=_t(D,W,d,R),f[r+64>>2]=i-d,f[r+68>>2]=h-(z+(i>>>0>>0)|0),i=_t(D,W,_,p),_=z,n=_t(pt,yt,n,v),f[r+56>>2]=i-n,f[r+60>>2]=_-(z+(i>>>0>>0)|0),f[r+48>>2]=0,f[(i=r+40|0)>>2]=0,f[i+4>>2]=0,f[r+32>>2]=0,f[r+36>>2]=0,D=SA(t,0,y,r+104|0,r+80|0,r+56|0,r+32|0),f[r+24>>2]=0,f[(i=r+16|0)>>2]=0,f[i+4>>2]=0,f[r+8>>2]=0,f[r+12>>2]=0;i:if((p=SA(t,1,o,r+104|0,r+80|0,r+56|0,r+8|0))|D){R=D?-1:1,!D|!p||(R=JA(r+32|0,r+8|0));A:{r:if(!It){n:{if((0|R)>=0){if(f[r+24>>2]>-1)break r;if(!(f[r+16>>2]|f[r+20>>2]))break n;break r}if(f[r+40>>2]|f[r+44>>2]|f[r+48>>2]>-1)break r}h=a,n=e,v=C,_=g;break A}_=v=xA(t,y,o),C&&(f[C+4>>2]=v,_=g),f[v>>2]=C,n=h=f[v+8>>2],a&&(f[a>>2]=h,n=e),f[h+4>>2]=a}if(f[r+4>>2]=D,f[r>>2]=p,a=p,R||(MA(t,y,o,r+4|0,r),a=f[r>>2]),!a|(0|R)<0)g=o,a=h;else{if(F&&(0|p)!=(0|(i=f[F>>2])))for(;C=f[i+8>>2],d=0,g=0,(0|i)!=(0|(e=f[i>>2]))&&(f[e+4>>2]=f[i+4>>2],f[f[i+4>>2]>>2]=e,g=e),f[f[C+12>>2]+8>>2]=g,(0|C)!=(0|(g=f[C>>2]))&&(f[g+4>>2]=f[C+4>>2],f[f[C+4>>2]>>2]=g,d=g),f[f[i+12>>2]+8>>2]=d,f[i+12>>2]=0,f[i+16>>2]=0,f[i+4>>2]=0,f[i+8>>2]=0,f[i>>2]=f[t+56>>2],f[t+56>>2]=i,f[(i=C+12|0)>>2]=0,f[i+4>>2]=0,f[C+4>>2]=0,f[C+8>>2]=0,f[C>>2]=f[t+56>>2],f[t+56>>2]=C,f[t+116>>2]=f[t+116>>2]+-1,i=e,(0|p)!=(0|e););h?(F||(F=f[p+4>>2],Y=n),f[F>>2]=n,f[n+4>>2]=F,f[p+4>>2]=h,f[h>>2]=p,n=0):Y=F?Y:p,g=f[a+12>>2],f[r+120>>2]=g,Dt=f[Ot>>2],Ft=f[Tt>>2],F=f[a+8>>2],V=f[o+88>>2],a=0}if((0|R)>0||!(C=f[r+4>>2]))e=y;else{if(w&&(0|D)!=(0|(e=f[w+4>>2])))for(;p=e+4|0,R=f[e+8>>2],d=f[e+4>>2],o=0,i=0,(0|e)!=(0|(h=f[e>>2]))&&(f[h+4>>2]=d,f[f[p>>2]>>2]=h,i=h),f[f[R+12>>2]+8>>2]=i,(0|R)!=(0|(i=f[R>>2]))&&(f[i+4>>2]=f[R+4>>2],f[f[R+4>>2]>>2]=i,o=i),f[f[e+12>>2]+8>>2]=o,f[(i=p+8|0)>>2]=0,f[i+4>>2]=0,f[p>>2]=0,f[p+4>>2]=0,f[e>>2]=f[t+56>>2],f[t+56>>2]=e,f[(e=R+12|0)>>2]=0,f[e+4>>2]=0,f[R+4>>2]=0,f[R+8>>2]=0,f[R>>2]=f[t+56>>2],f[t+56>>2]=R,f[t+116>>2]=f[t+116>>2]+-1,(0|D)!=(0|(e=d)););v?(w||(w=f[D>>2],E=_),f[w+4>>2]=_,f[_>>2]=w,f[v+4>>2]=D,f[D>>2]=v,_=0):E=w?E:D,e=f[C+12>>2],f[r+124>>2]=e,Dt=f[Nt>>2],Ft=f[Et>>2],w=f[C+8>>2],V=f[y+88>>2],v=0}if(C=v,i=1,(0|e)!=(0|Q)|(0|g)!=(0|B))It=0;else{if(w){if((0|(e=f[w+4>>2]))!=(0|E))for(;d=e+4|0,h=f[e+8>>2],g=f[e+4>>2],o=0,i=0,(0|e)!=(0|(y=f[e>>2]))&&(f[y+4>>2]=g,f[f[d>>2]>>2]=y,i=y),f[f[h+12>>2]+8>>2]=i,(0|h)!=(0|(i=f[h>>2]))&&(f[i+4>>2]=f[h+4>>2],f[f[h+4>>2]>>2]=i,o=i),f[f[e+12>>2]+8>>2]=o,f[(i=d+8|0)>>2]=0,f[i+4>>2]=0,f[d>>2]=0,f[d+4>>2]=0,f[e>>2]=f[t+56>>2],f[t+56>>2]=e,f[(e=h+12|0)>>2]=0,f[e+4>>2]=0,f[h+4>>2]=0,f[h+8>>2]=0,f[h>>2]=f[t+56>>2],f[t+56>>2]=h,f[t+116>>2]=f[t+116>>2]+-1,(0|E)!=(0|(e=g)););C&&(f[w+4>>2]=_,f[_>>2]=w,f[C+4>>2]=E,f[E>>2]=C)}else f[C+4>>2]=_,f[_>>2]=C,f[e+8>>2]=C;if(!F){f[a>>2]=n,f[n+4>>2]=a,f[f[r+120>>2]+8>>2]=a,F=0,e=n,g=_,i=0;break i}if((0|(i=f[F>>2]))!=(0|Y))for(;o=f[i+8>>2],d=0,g=0,(0|i)!=(0|(e=f[i>>2]))&&(f[e+4>>2]=f[i+4>>2],f[f[i+4>>2]>>2]=e,g=e),f[f[o+12>>2]+8>>2]=g,(0|o)!=(0|(g=f[o>>2]))&&(f[g+4>>2]=f[o+4>>2],f[f[o+4>>2]>>2]=g,d=g),f[f[i+12>>2]+8>>2]=d,f[i+12>>2]=0,f[i+16>>2]=0,f[i+4>>2]=0,f[i+8>>2]=0,f[i>>2]=f[t+56>>2],f[t+56>>2]=i,f[(i=o+12|0)>>2]=0,f[i+4>>2]=0,f[o+4>>2]=0,f[o+8>>2]=0,f[o>>2]=f[t+56>>2],f[t+56>>2]=o,f[t+116>>2]=f[t+116>>2]+-1,i=e,(0|Y)!=(0|e););i=0,a?(f[n+4>>2]=F,f[F>>2]=n,f[Y+4>>2]=a,f[a>>2]=Y):a=0}e=n,g=_}else n=xA(t,y,o),f[y+8>>2]=n,i=f[n+8>>2],f[o+8>>2]=i,f[n+4>>2]=n,f[n>>2]=n,f[i+4>>2]=i,f[i>>2]=i,i=0;if(!i)break e;y=f[r+124>>2],o=f[r+120>>2]}}else t=f[i+4>>2],f[e>>2]=f[i>>2],f[e+4>>2]=t,n=e+8|0,e=i+8|0,t=f[e+4>>2],f[n>>2]=f[e>>2],f[n+4>>2]=t;Z=r+128|0}(t,r,n)}Z=n+16|0}function MA(t,e,i,r,n){var a,o,_,h,d,C,g,v,y,p,R,D,B,E,F,V,G=0,w=0,Q=0,W=0,Y=0,yt=0,pt=0,Dt=0,It=0,St=0,Tt=0,Et=0,Ot=0,Nt=0,Ft=0,Vt=0,Gt=0,Lt=0,wt=0,xt=0,Qt=0,Wt=0,Yt=0,Pt=0,Mt=0,Zt=0;if(Z=a=Z-48|0,Ft=e,(Wt=f[r>>2])&&(Ft=f[Wt+12>>2]),wt=f[Ft+96>>2],xt=f[Ft+92>>2],Ft=f[Ft+88>>2],w=(Qt=f[n>>2])?f[Qt+12>>2]:i,G=f[e+96>>2],v=f[i+96>>2]-G|0,yt=f[(Wt||Qt)+12>>2],Q=f[e+92>>2],W=f[yt+92>>2]-Q|0,y=f[i+92>>2]-Q|0,Et=f[yt+96>>2]-G|0,E=Y=m(v,W)-m(y,Et)|0,Y=_t(Y,R=Y>>31,v,Vt=v>>31),Gt=z,e=f[e+88>>2],yt=f[yt+88>>2]-e|0,p=f[i+88>>2]-e|0,F=i=m(yt,y)-m(W,p)|0,i=_t(i,D=i>>31,p,W=p>>31),Y=_t(o=Y-i|0,_=Gt-(z+(Y>>>0>>0)|0)|0,xt,xt>>31),Gt=z,i=_t(F,D,y,Nt=y>>31),It=z,V=yt=m(Et,p)-m(yt,v)|0,yt=_t(yt,B=yt>>31,v,Vt),yt=(Et=_t(h=i-yt|0,d=It-(z+(i>>>0>>0)|0)|0,Ft,Ft>>31))+Y|0,Y=z+Gt|0,i=_t(V,B,p,W),W=z,Vt=_t(E,R,y,Nt),Vt=yt+(W=_t(C=i-Vt|0,g=W-(z+(i>>>0>>0)|0)|0,wt,wt>>31))|0,yt=z+(yt>>>0>>0?Y+1|0:Y)|0,yt=(i=Vt)>>>0>>0?yt+1|0:yt,e=_t(E,R,e,e>>31),Y=z,e=(W=_t(F,D,G,G>>31))+e|0,G=z+Y|0,St=Y=(Q=_t(V,B,Q,Q>>31))+e|0,e=z+(e>>>0>>0?G+1|0:G)|0,Nt=Y>>>0>>0?e+1|0:e,Et=f[w+96>>2],Vt=f[w+92>>2],Gt=f[w+88>>2],e=Qt,Wt&&(e=Qt,f[Wt+12>>2])){e=f[f[Wt+8>>2]+4>>2],Q=f[e+12>>2],w=G=f[Q+92>>2],W=_t(G,Y=G>>31,V,B),It=z,Dt=W+(Ot=_t(G=Dt=f[Q+88>>2],pt=G>>31,E,R))|0,Tt=z+It|0,W=Q=f[Q+96>>2],Lt=Dt+(Q=_t(Q,It=Q>>31,F,D))|0,Dt=z+(Dt>>>0>>0?Tt+1|0:Tt)|0;t:if(!((0|(Q=Lt>>>0>>0?Dt+1|0:Dt))<(0|Nt)||(0|Q)<=(0|Nt)&&!(Lt>>>0>=St>>>0))){for(Dt=e+12|0;;){if(f[e+20>>2]==f[t+100>>2])break t;if(w=_t(o,_,w,Y),Q=z,G=(Y=_t(h,d,G,pt))+w|0,Q=z+Q|0,It=(W=_t(C,g,W,It))+G|0,G=z+(G>>>0>>0?Q+1|0:Q)|0,(0|(G=Q=(w=It)>>>0>>0?G+1|0:G))<(0|yt)||(0|G)<=(0|yt)&&!(w>>>0>i>>>0))break t;if(f[r>>2]=e,i=f[Dt>>2],wt=f[i+96>>2],xt=f[i+92>>2],Ft=f[i+88>>2],!i)break;if(Dt=(e=f[f[e+8>>2]+4>>2])+12|0,i=w,yt=G,Q=f[e+12>>2],w=G=f[Q+92>>2],W=_t(G,Y=G>>31,V,B),It=z,Tt=W+(Lt=_t(G=pt=f[Q+88>>2],pt=G>>31,E,R))|0,Ot=z+It|0,W=Q=f[Q+96>>2],Yt=(Q=_t(Q,It=Q>>31,F,D))+Tt|0,Tt=z+(Tt>>>0>>0?Ot+1|0:Ot)|0,(0|(Q=Yt>>>0>>0?Tt+1|0:Tt))<(0|Nt)||(0|Q)<=(0|Nt)&&!(Yt>>>0>=St>>>0))break t}i=w,yt=G}e=f[n>>2]}w=_t(o,_,Vt,Vt>>31),Q=z,G=(Y=_t(h,d,Gt,Gt>>31))+w|0,Q=z+Q|0,It=(W=_t(C,g,Et,Et>>31))+G|0,G=z+(G>>>0>>0?Q+1|0:Q)|0,Y=(w=It)>>>0>>0?G+1|0:G;t:if(e){if(f[e+12>>2]&&(Dt=f[f[e+8>>2]>>2],Q=f[Dt+12>>2],Tt=_t(G=W=f[Q+92>>2],pt=G>>31,V,B),Ot=z,Tt=Tt+(Pt=_t(W=It=f[Q+88>>2],It=W>>31,E,R))|0,Ot=z+Ot|0,Lt=Q=f[Q+96>>2],Mt=(Q=_t(Q,Yt=Q>>31,F,D))+Tt|0,Tt=z+(Tt>>>0>>0?Ot+1|0:Ot)|0,!((0|(Q=Mt>>>0>>0?Tt+1|0:Tt))<(0|Nt)||(0|Q)<=(0|Nt)&&!(Mt>>>0>=St>>>0)))){for(Tt=Dt+12|0;;){if(f[(Q=Dt)+20>>2]==f[t+100>>2])break t;if(G=_t(o,_,G,pt),Dt=z,W=(pt=_t(h,d,W,It))+G|0,It=z+Dt|0,G=(Dt=_t(C,g,Lt,Yt))+W|0,W=z+(W>>>0>>0?It+1|0:It)|0,(0|(W=G>>>0

>>0?W+1|0:W))<(0|Y)||(0|W)<=(0|Y)&&!(G>>>0>w>>>0))break t;if(f[n>>2]=Q,e=f[Tt>>2],Et=f[e+96>>2],Vt=f[e+92>>2],Gt=f[e+88>>2],!e)break;if(Tt=(Dt=f[f[Q+8>>2]>>2])+12|0,w=G,Y=W,e=Q,Q=f[Dt+12>>2],Ot=_t(G=W=f[Q+92>>2],pt=G>>31,V,B),Lt=z,Ot=Ot+(Mt=_t(W=It=f[Q+88>>2],It=W>>31,E,R))|0,Pt=z+Lt|0,Lt=Q=f[Q+96>>2],Zt=Ot+(Q=_t(Q,Yt=Q>>31,F,D))|0,Ot=z+(Ot>>>0>>0?Pt+1|0:Pt)|0,(0|(Q=Zt>>>0>>0?Ot+1|0:Ot))<(0|Nt)||(0|Q)<=(0|Nt)&&!(Zt>>>0>=St>>>0))break t}e=Q,w=G,Y=W}}else e=0;t:{if(yt=Y-((w>>>0>>0)+yt|0)|0,i=w-i|0,!((0|yt)<0||(0|yt)<=0&&!(i>>>0>=1)))for(;;){Q=e=Dt=(m(Vt-xt|0,y)+m(Gt-Ft|0,p)|0)+m(Et-wt|0,v)|0,It=e>>31;e:if(Qt=f[r>>2],!(!Qt|!f[Qt+12>>2]||(Tt=f[f[Qt>>2]+8>>2],f[Tt+20>>2]<=f[t+100>>2]))){w=f[Tt+12>>2],G=(e=f[w+92>>2])-xt|0,Y=(W=f[w+88>>2])-Ft|0,pt=(Nt=f[w+96>>2])-wt|0,w=(m(G,y)+m(Y,p)|0)+m(pt,v)|0,G=_t(o,_,G,G>>31),St=z,G=(Ot=_t(h,d,Y,Y>>31))+G|0,St=z+St|0,Y=(pt=_t(C,g,pt,pt>>31))+G|0,G=z+(G>>>0>>0?St+1|0:St)|0,St=G=Y>>>0>>0?G+1|0:G;i:{if(!(0!=(0|Y)|0!=(0|G))){if((0|w)<0)break i;break e}if((0|St)>-1||(0|St)>=-1&&!(Y>>>0<=4294967295))break e;if(pt=(G=w)>>31,Lt=a,(0|G)>=1?(f[a+40>>2]=1,w=-1):(0|w)<=-1?(f[a+40>>2]=-1,G=0-G|0,pt=0-((0>>0)+pt|0)|0,w=1):(f[a+40>>2]=0,G=0,pt=0,w=0),f[Lt+40>>2]=w,f[a+24>>2]=G,f[a+28>>2]=pt,f[a+32>>2]=0-Y,f[a+36>>2]=0-((0>>0)+St|0),(0|Dt)>=1?(f[a+16>>2]=1,w=Q,Y=It,G=-1):(0|Dt)<=-1?(f[a+16>>2]=-1,w=0-Q|0,Y=0-((0>>0)+It|0)|0,G=1):(f[a+16>>2]=0,w=0,Y=0,G=0),f[a>>2]=w,f[a+4>>2]=Y,w=i,Y=yt,(0|yt)>0||(0|yt)>=0&&!(w>>>0<=0)||(w=0,Y=0,(0|yt)>-1||(0|yt)>=-1&&!(i>>>0<=4294967295)||(f[a+16>>2]=G,w=0-i|0,Y=0-((0>>0)+yt|0)|0)),G=Y,f[a+8>>2]=w,f[a+12>>2]=G,(0|JA(a+24|0,a))<=-1)break e}f[r>>2]=(0|Qt)==(0|Wt)?0:Tt,i=_t(o,_,i=Vt-e|0,i>>31),G=z,yt=_t(h,d,w=Gt-W|0,w>>31),G=z+G|0,Y=(w=i+yt|0)+(Q=_t(C,g,i=Et-Nt|0,i>>31))|0,w=z+(w>>>0>>0?G+1|0:G)|0,yt=(i=Y)>>>0>>0?w+1|0:w,Ft=W,xt=e,wt=Nt;continue}if(!(e=f[n>>2])|!f[e+12>>2])break t;if(Nt=f[f[e+8>>2]>>2],f[Nt+20>>2]<=f[t+100>>2])break t;if(e=f[Nt+12>>2],Vt=w=W=(Y=f[e+92>>2])-Vt|0,w=_t(w,pt=w>>31,V,B),G=z,w=w+(Ot=_t(Tt=St=Gt=(Qt=f[e+88>>2])-Gt|0,St>>=31,E,R))|0,G=z+G|0,Yt=Et=(e=f[e+96>>2])-Et|0,(0-(Pt=_t(F,D,Et,Lt=Et>>31))|0)!=(0|w)|(0-(z+(0>>0)|0)|0)!=(0|(w>>>0>>0?G+1|0:G)))break t;if(w=_t(o,_,w=Y-xt|0,w>>31),G=z,Y=_t(h,d,Y=Qt-Ft|0,Y>>31),G=z+G|0,e=(w=w+Y|0)+(Qt=_t(C,g,e=e-wt|0,e>>31))|0,w=z+(w>>>0>>0?G+1|0:G)|0,Y=w=e>>>0>>0?w+1|0:w,(0|w)<0||(0|w)<=0&&!(e>>>0>=1))break t;w=(m(W,y)+m(Gt,p)|0)+m(Et,v)|0,G=_t(o,_,Vt,pt),W=z,G=(Vt=_t(h,d,Tt,St))+G|0,Et=z+W|0,W=(Gt=_t(C,g,Yt,Lt))+G|0,G=z+(G>>>0>>0?Et+1|0:Et)|0,Et=G=W>>>0>>0?G+1|0:G;e:{if(!(0!=(0|W)|0!=(0|G))){if((0|w)<0)break e;break t}if((0|Et)>-1||(0|Et)>=-1&&!(W>>>0<=4294967295))break t;if(pt=(G=w)>>31,St=a,(0|G)>=1?(f[a+40>>2]=1,w=-1):(0|w)<=-1?(f[a+40>>2]=-1,G=0-G|0,pt=0-((0>>0)+pt|0)|0,w=1):(f[a+40>>2]=0,G=0,pt=0,w=0),f[St+40>>2]=w,f[a+24>>2]=G,f[a+28>>2]=pt,f[a+32>>2]=0-W,f[a+36>>2]=0-((0>>0)+Et|0),(0|Dt)>=1?(f[a+16>>2]=1,G=-1):(0|Dt)<=-1?(f[a+16>>2]=-1,Q=0-(w=Q)|0,It=0-((0>>0)+It|0)|0,G=1):(f[a+16>>2]=0,Q=0,It=0,G=0),f[a>>2]=Q,f[a+4>>2]=It,(0|yt)<0||(0|yt)<=0&&!(i>>>0>0)?(w=0,W=0,(0|yt)>-1||(0|yt)>=-1&&!(i>>>0<=4294967295)||(f[a+16>>2]=G,w=0-i|0,W=0-((0>>0)+yt|0)|0)):(w=i,W=yt),i=W,f[a+8>>2]=w,f[a+12>>2]=i,(0|JA(a+24|0,a))<=0)break t}f[n>>2]=Nt,i=f[Nt+12>>2],Et=f[i+96>>2],Vt=f[i+92>>2],Gt=f[i+88>>2],i=e,yt=Y}if(!((0|yt)>-1||(0|yt)>=-1&&!(i>>>0<=4294967295)))for(;;){Q=w=Wt=(m(Vt-xt|0,y)+m(Gt-Ft|0,p)|0)+m(Et-wt|0,v)|0,It=w>>31;e:if(!(!e|!f[e+12>>2]||(Tt=f[f[e+4>>2]+8>>2],f[Tt+20>>2]<=f[t+100>>2]))){w=f[Tt+12>>2],G=(Y=f[w+92>>2])-Vt|0,Dt=(W=f[w+88>>2])-Gt|0,pt=(Nt=f[w+96>>2])-Et|0,w=(m(G,y)+m(Dt,p)|0)+m(pt,v)|0,G=_t(o,_,G,G>>31),St=z,G=(Ot=_t(h,d,Dt,Dt>>31))+G|0,St=z+St|0,Dt=(pt=_t(C,g,pt,pt>>31))+G|0,G=z+(G>>>0>>0?St+1|0:St)|0,St=G=Dt>>>0>>0?G+1|0:G;i:{if(!(0!=(0|Dt)|0!=(0|G))){if((0|w)>0)break i;break e}if((0|St)>-1||(0|St)>=-1&&!(Dt>>>0<=4294967295))break e;if(pt=(G=w)>>31,Lt=a,(0|G)>=1?(f[a+40>>2]=1,w=-1):(0|w)<=-1?(f[a+40>>2]=-1,G=0-G|0,pt=0-((0>>0)+pt|0)|0,w=1):(f[a+40>>2]=0,G=0,pt=0,w=0),f[Lt+40>>2]=w,f[a+24>>2]=G,f[a+28>>2]=pt,f[a+32>>2]=0-Dt,f[a+36>>2]=0-((0
>>0)+St|0),(0|Wt)>=1?(f[a+16>>2]=1,Dt=-1,w=Q,G=It):(0|Wt)<=-1?(f[a+16>>2]=-1,w=0-Q|0,Dt=1,G=0-((0>>0)+It|0)|0):(Dt=0,f[a+16>>2]=0,w=0,G=0),f[a>>2]=w,f[a+4>>2]=G,w=i,G=yt,(0|yt)>0||(0|yt)>=0&&!(w>>>0<=0)||(w=0,G=0,(0|yt)>-1||(0|yt)>=-1&&!(i>>>0<=4294967295)||(f[a+16>>2]=Dt,w=0-i|0,G=0-((0>>0)+yt|0)|0)),f[a+8>>2]=w,f[a+12>>2]=G,(0|JA(a+24|0,a))>=1)break e}e=(0|e)==(0|Qt)?0:Tt,f[n>>2]=e,i=_t(o,_,i=Y-xt|0,i>>31),G=z,yt=_t(h,d,w=W-Ft|0,w>>31),G=z+G|0,Et=(w=i+yt|0)+(Q=_t(C,g,i=Nt-wt|0,i>>31))|0,w=z+(w>>>0>>0?G+1|0:G)|0,yt=(i=Et)>>>0>>0?w+1|0:w,Gt=W,Vt=Y,Et=Nt;continue}if(!(e=f[r>>2])|!f[e+12>>2])break t;if(Nt=f[f[e+8>>2]+4>>2],f[Nt+20>>2]<=f[t+100>>2])break t;if(e=f[Nt+12>>2],Dt=w=xt=(Y=f[e+92>>2])-xt|0,w=_t(w,pt=w>>31,V,B),G=z,w=w+(Ot=_t(Tt=St=Ft=(W=f[e+88>>2])-Ft|0,St>>=31,E,R))|0,G=z+G|0,Yt=e=wt=(Lt=f[e+96>>2])-wt|0,(0|w)!=(0-(e=_t(F,D,e,Pt=e>>31))|0)|(0-(z+(0>>0)|0)|0)!=(0|(w>>>0>>0?G+1|0:G)))break t;if(e=_t(o,_,e=Vt-Y|0,e>>31),w=z,G=_t(h,d,G=Gt-W|0,G>>31),w=z+w|0,Y=(e=e+G|0)+(W=_t(C,g,Y=Et-Lt|0,Y>>31))|0,e=z+(e>>>0>>0?w+1|0:w)|0,W=e=Y>>>0>>0?e+1|0:e,(0|e)>-1||(0|e)>=-1&&!(Y>>>0<=4294967295))break t;if(e=(m(xt,y)+m(Ft,p)|0)+m(wt,v)|0,w=_t(o,_,Dt,pt),Ft=z,G=(wt=_t(h,d,Tt,St))+w|0,Ft=z+Ft|0,w=(xt=_t(C,g,Yt,Pt))+G|0,G=z+(G>>>0>>0?Ft+1|0:Ft)|0,Ft=G=w>>>0>>0?G+1|0:G,0!=(0|w)|0!=(0|G)){if((0|Ft)>-1||(0|Ft)>=-1&&!(w>>>0<=4294967295))break t;if(pt=(G=e)>>31,St=a,(0|G)>=1?(f[a+40>>2]=1,e=-1):(0|e)<=-1?(f[a+40>>2]=-1,G=0-G|0,pt=0-((0>>0)+pt|0)|0,e=1):(f[a+40>>2]=0,G=0,pt=0,e=0),f[St+40>>2]=e,f[a+24>>2]=G,f[a+28>>2]=pt,f[a+32>>2]=0-w,f[a+36>>2]=0-((0>>0)+Ft|0),(0|Wt)>=1?(f[a+16>>2]=1,e=-1):(0|Wt)<=-1?(f[a+16>>2]=-1,Q=0-(e=Q)|0,It=0-((0>>0)+It|0)|0,e=1):(f[a+16>>2]=0,Q=0,It=0,e=0),f[a>>2]=Q,f[a+4>>2]=It,(0|yt)<0||(0|yt)<=0&&!(i>>>0>0)?(w=0,G=0,(0|yt)>-1||(0|yt)>=-1&&!(i>>>0<=4294967295)||(f[a+16>>2]=e,w=0-i|0,G=0-((0>>0)+yt|0)|0)):(w=i,G=yt),e=G,f[a+8>>2]=w,f[a+12>>2]=e,(0|JA(a+24|0,a))>=0)break t}else if((0|e)<=0)break t;f[r>>2]=Nt,i=f[Nt+12>>2],wt=f[i+96>>2],xt=f[i+92>>2],e=f[n>>2],Ft=f[i+88>>2],i=Y,yt=W}}Z=a+48|0}function SA(t,e,i,r,n,a,o){var _,h=0,d=0,C=0,g=0,m=0,v=0,y=0,p=0,R=0,D=0,B=0,E=0;if(Z=_=Z-48|0,h=f[i+8>>2])for(p=h;;){if(f[p+20>>2]>f[t+100>>2]){f[_+44>>2]=-1,h=f[p+12>>2],C=f[h+96>>2]-f[i+96>>2]|0,f[_+40>>2]=C,d=f[h+92>>2]-f[i+92>>2]|0,f[_+36>>2]=d,g=f[h+88>>2]-f[i+88>>2]|0,f[_+32>>2]=g,v=d,B=d>>31,d=_t(f[(h=n)+8>>2],f[h+12>>2],d,B),y=z,R=d,E=(d=g)>>31,D=_t(f[h>>2],f[h+4>>2],d,E),h=z+y|0,h=(g=R+D|0)>>>0>>0?h+1|0:h,y=g,g=C,D=C>>31,R=_t(f[n+16>>2],f[n+20>>2],C,D),C=z+h|0,C=(y=y+R|0)>>>0>>0?C+1|0:C,v=_t(f[(h=a)+8>>2],f[h+12>>2],v,B),B=z,R=v,v=_t(f[h>>2],f[h+4>>2],d,E),h=z+B|0,h=(d=R+v|0)>>>0>>0?h+1|0:h,g=_t(f[a+16>>2],f[a+20>>2],g,D),h=z+h|0,g=h=(d=g+d|0)>>>0>>0?h+1|0:h,(0|h)<0||(0|h)<=0&&!(d>>>0>=1)?(0|g)>-1||(0|g)>=-1&&!(d>>>0<=4294967295)?(f[_+24>>2]=0,d=0,g=0,v=0,h=0):(f[_+24>>2]=-1,v=d,d=0-d|0,g=0-((0>>0)+g|0)|0,v=1,h=-1):(f[_+24>>2]=1,v=-1,h=-1),f[_+8>>2]=d,f[_+12>>2]=g;t:{e:{i:{if(!((0|C)>0||(0|C)>=0&&!(y>>>0<=0))){if((0|C)>-1||(0|C)>=-1&&!(y>>>0<=4294967295))break i;f[_+24>>2]=v,y=0-(h=y)|0,C=0-((0>>0)+C|0)|0}f[_+16>>2]=y,f[_+20>>2]=C;break e}if(f[_+16>>2]=0,f[_+20>>2]=0,!h)break t}m?(0|(h=JA(_+8|0,o)))<=-1?(m=f[_+12>>2],f[o>>2]=f[_+8>>2],f[o+4>>2]=m,f[o+16>>2]=f[_+24>>2],C=f[(h=_+16|0)+4>>2],f[(m=o+8|0)>>2]=f[h>>2],f[m+4>>2]=C,m=p):h||(m=2!=(0|XA(m,p,r,_+32|0))^e?p:m):(m=f[_+12>>2],f[o>>2]=f[_+8>>2],f[o+4>>2]=m,f[o+16>>2]=f[_+24>>2],C=f[(h=_+16|0)+4>>2],f[(m=o+8|0)>>2]=f[h>>2],f[m+4>>2]=C,m=p)}h=f[i+8>>2]}if((0|(p=f[p>>2]))==(0|h))break}return Z=_+48|0,m}function XA(t,e,i,r){var n=0,a=0,o=0,_=0,h=0,d=0,C=0,g=0,v=0,y=0,p=0,R=0;a=f[t+4>>2];t:{if((0|e)==f[t>>2]){if(n=2,(0|e)!=(0|a))break t;return a=f[e+12>>2],e=f[f[e+8>>2]+12>>2],_=f[e+96>>2],v=f[a+96>>2]-_|0,t=f[t+12>>2],n=f[e+92>>2],h=f[t+92>>2]-n|0,n=f[a+92>>2]-n|0,_=f[t+96>>2]-_|0,o=d=m(v,h)-m(n,_)|0,g=d>>31,d=f[i+8>>2],y=f[r+4>>2],p=f[i+4>>2],R=f[r+8>>2],C=_t(o,g,C=m(d,y)-m(p,R)|0,C>>31),g=z,o=n,n=(n=f[t+88>>2])-(t=f[e+88>>2])|0,a=f[a+88>>2]-t|0,e=t=m(o,n)-m(a,h)|0,o=t>>31,r=f[r>>2],i=f[i>>2],h=_t(e,o,t=m(r,p)-m(i,y)|0,t>>31),t=z+g|0,t=(e=h+C|0)>>>0>>0?t+1|0:t,o=e,i=_t(n=e=m(a,_)-m(n,v)|0,a=e>>31,e=m(i,R)-m(r,d)|0,e>>31),t=z+t|0,(0|(t=(e=o+i|0)>>>0>>0?t+1|0:t))>0||(0|t)>=0&&!(e>>>0<=0)?2:1}n=(0|e)==(0|a)}return n}function TA(t,e,i){var r,a=0,o=0,h=0,d=0,g=0,p=0,R=v(0),D=v(0),B=0,E=v(0),F=0,V=v(0),G=0,w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),yt=0,pt=0,Dt=0,It=0;if(Z=r=Z-48|0,(0|i)<1)a=1900671690,h=-246811958,p=-246811958,o=-246811958,B=1900671690,F=1900671690;else for(o=-246811958,F=1900671690,G=i,g=e,B=1900671690,a=1900671690,p=-246811958,h=-246811958;yt=f[(d=g+8|0)>>2],R=C[d>>2],b(0,o),o=k()>2],D=C[d>>2],b(0,p),p=k()>2],R=C[g>>2],b(0,h),h=k()>2]=a,(0|(h=G?(1^g)<<1:o?1:2))==(0|a)&&(h=(a+1>>>0)%3|0),f[t+104>>2]=h,o=(3^a)-h|0,f[t+108>>2]=o,R=v(R*v(9788566967472434e-20)),D=v(D*v(9788566967472434e-20)),V=v(V*v(9788566967472434e-20)),f[t+12>>2]=0,((o+1|0)%3|0)!=(0|a)&&(D=v(-D),V=v(-V),R=v(-R)),C[t+8>>2]=R,C[t+4>>2]=D,C[t>>2]=V,f[t+28>>2]=0,C[t+24>>2]=v(W+E)*v(.5),C[t+20>>2]=v(w+Q)*v(.5),C[t+16>>2]=v(Y+z)*v(.5),f[r+36>>2]=0,f[r+28>>2]=0,f[r+32>>2]=0,g=R!=v(0),w=v(v(1)/R),G=D!=v(0),Q=v(v(1)/D),B=V!=v(0),W=v(v(1)/V),n[r+40|0]=1,!((0|i)<1)&&(a=dA(i<<4),f[r+36>>2]=a,f[r+32>>2]=i,n[r+40|0]=1,h=f[(o=r+16|0)+4>>2],f[(F=a+8|0)>>2]=f[o>>2],f[F+4>>2]=h,h=f[r+12>>2],f[a>>2]=f[r+8>>2],f[a+4>>2]=h,1!=(0|i)))for(h=i+-1|0,a=16;F=f[r+12>>2],p=f[r+36>>2]+a|0,f[(d=p)>>2]=f[r+8>>2],f[d+4>>2]=F,F=f[o+4>>2],f[(p=d+8|0)>>2]=f[o>>2],f[p+4>>2]=F,a=a+16|0,h=h+-1|0;);if(R=g?w:R,D=G?Q:D,V=B?W:V,f[r+28>>2]=i,!((0|i)<1)){for(a=f[r+36>>2]+8|0,o=(r+8|0)+(f[t+104>>2]<<2)|0,g=(r+8|0)+(f[t+112>>2]<<2)|0,G=(r+8|0)+(f[t+108>>2]<<2)|0,w=C[t+24>>2],Q=C[t+20>>2],W=C[t+16>>2],h=0;E=C[e+4>>2],Y=C[e+8>>2],z=C[e>>2],f[r+20>>2]=0,C[r+8>>2]=V*v(z-W),C[r+16>>2]=R*v(Y-w),C[r+12>>2]=D*v(E-Q),f[a+4>>2]=h,p=a+-8|0,E=C[G>>2],d=v(y(E))>2]=d,p=a+-4|0,E=C[g>>2],d=v(y(E))>2]=d,p=a,E=C[o>>2],d=v(y(E))>2]=d,a=a+16|0,e=e+16|0,(0|(h=h+1|0))!=(0|i););(0|i)<2||function A(t,e,i,r){var n,a,o,_,h=0,d=0,C=0,g=0,m=0,v=0,y=0,p=0;for(Z=n=Z-16|0,g=f[t+12>>2],_=f[(C=g+((i+r|0)/2<<4)|0)+8>>2],a=f[C+4>>2],o=f[C>>2],C=i,v=r;;){for(h=(C<<4)+g|0;;){t:{if(!((0|(d=f[h+4>>2]))<(0|a))){if((0|d)!=(0|a))break t;if(!((0|(d=f[h>>2]))<(0|o))&&(0|d)!=(0|o)|f[h+8>>2]>=(0|_))break t}h=h+16|0,C=C+1|0;continue}break}for(y=v<<4;;){t:{if(!((0|a)<(0|(m=f[(d=g+y|0)+4>>2])))){if((0|m)!=(0|a))break t;if(!((0|o)<(0|(m=f[d>>2])))&&(0|m)!=(0|o)|(0|_)>=f[d+8>>2])break t}y=y+-16|0,v=v+-1|0;continue}break}if((0|C)<=(0|v)&&(p=f[(m=h+8|0)+4>>2],f[(g=n+8|0)>>2]=f[m>>2],f[g+4>>2]=p,p=f[h+4>>2],f[n>>2]=f[h>>2],f[n+4>>2]=p,p=f[d+4>>2],f[h>>2]=f[d>>2],f[h+4>>2]=p,d=f[(h=d+8|0)+4>>2],f[m>>2]=f[h>>2],f[m+4>>2]=d,h=f[t+12>>2]+y|0,y=f[n+4>>2],f[h>>2]=f[n>>2],f[h+4>>2]=y,d=f[g+4>>2],f[(h=h+8|0)>>2]=f[g>>2],f[h+4>>2]=d,v=v+-1|0,C=C+1|0),!((0|C)<=(0|v)))break;g=f[t+12>>2]}(0|v)>(0|i)&&A(t,e,i,v),(0|C)<(0|r)&&A(t,e,C,r),Z=n+16|0}(r+24|0,r+8|0,0,i+-1|0)}if(f[t+44>>2]=i,f[t+40>>2]=0,f[t+36>>2]=f[t+32>>2],(0|(o=f[t+84>>2]))<(0|i)){if(f[t+88>>2]<(0|i)){if(i?(h=dA(i<<2),a=f[t+84>>2]):(h=0,a=o),(0|a)>=1)for(e=0;f[e+h>>2]=f[f[t+92>>2]+e>>2],e=e+4|0,a=a+-1|0;);(e=f[t+92>>2])&&(_[t+96|0]&&CA(e),f[t+92>>2]=0),f[t+92>>2]=h,f[t+88>>2]=i,n[t+96|0]=1}for(e=o<<2,a=i-o|0;f[f[t+92>>2]+e>>2]=0,e=e+4|0,a=a+-1|0;);}if(f[t+84>>2]=i,(0|i)>=1)for(B=0;;){if(!((o=f[t+40>>2])||(e=f[t+36>>2],e?f[t+36>>2]=f[e+8>>2]:(e=dA(12),f[e+8>>2]=0,a=f[t+44>>2],f[e+4>>2]=a,Dt=e,It=dA(m(a,112)),f[Dt>>2]=It,a=f[t+32>>2],f[t+32>>2]=e,f[e+8>>2]=a),o=f[e>>2],g=f[e+4>>2],(0|g)<1)))for(e=0,a=o;p=a,a=a+112|0,e=e+1|0,f[p>>2]=(0|e)<(0|g)?a:0,(0|e)!=(0|g););if(f[t+40>>2]=f[o>>2],f[(e=o+8|0)>>2]=0,f[e+4>>2]=0,f[o+16>>2]=0,f[o>>2]=0,f[o+4>>2]=0,f[o+104>>2]=-1,f[e>>2]=0,e=f[r+36>>2]+(B<<4)|0,a=f[e+4>>2],f[o+88>>2]=f[e>>2],f[o+92>>2]=a,a=f[(e=e+8|0)+4>>2],f[(g=o+96|0)>>2]=f[e>>2],f[g+4>>2]=a,f[o+104>>2]=-1,f[f[t+92>>2]+(B<<2)>>2]=o,(0|(B=B+1|0))==(0|i))break}(e=f[r+36>>2])&&(_[r+40|0]&&CA(e),f[r+36>>2]=0),f[t+116>>2]=0,f[t+120>>2]=0,f[t+100>>2]=-3,f[t+60>>2]=m(i,6),f[t+56>>2]=0,f[t+52>>2]=f[t+48>>2],f[r+36>>2]=0,n[r+40|0]=1,f[r+28>>2]=0,f[r+32>>2]=0,f[(e=r+16|0)>>2]=0,f[e+4>>2]=0,f[r+8>>2]=0,f[r+12>>2]=0,UA(t,0,i,r+8|0),f[t+124>>2]=f[r+8>>2],(t=f[r+36>>2])&&(_[r+40|0]&&CA(t),f[r+36>>2]=0),Z=r+48|0}function jA(t,e,i){var r,n=v(0),a=v(0),o=0;Z=r=Z-16|0;t:{e:{i:{A:{if(f[i+100>>2]>=0)C[(f[e+108>>2]<<2)+r>>2]=f[i+88>>2];else if(n=OA(i+24|0),a=OA(o=i+72|0),C[(f[e+108>>2]<<2)+r>>2]=n/a,f[i+100>>2]<0)break A;C[(f[e+112>>2]<<2)+r>>2]=f[i+92>>2];break i}if(n=OA(i+40|0),a=OA(o),C[(f[e+112>>2]<<2)+r>>2]=n/a,f[i+100>>2]<0)break e}n=v(f[i+96>>2]);break t}n=v(OA(i+56|0)/OA(i+72|0))}C[(f[e+104>>2]<<2)+r>>2]=n,f[t+12>>2]=0,C[t+8>>2]=v(C[r+8>>2]*C[e+8>>2])+C[e+24>>2],C[t+4>>2]=v(C[r+4>>2]*C[e+4>>2])+C[e+20>>2],C[t>>2]=v(C[r>>2]*C[e>>2])+C[e+16>>2],Z=r+16|0}function OA(t){var e,i,r=0,n=0,a=0,o=v(0);return Z=e=Z-16|0,n=r=f[t+12>>2],i=f[t+8>>2],(0|r)<0||(0|r)<=0&&!(i>>>0>=0)?(a=f[t+4>>2],t=r=f[t>>2],f[e>>2]=0-t,f[e+4>>2]=0-(a+(0>>0)|0),n^=-1,(r=(t=!(t|a))+(a=-1^i)|0)>>>0>>0&&(n=n+1|0),f[(t=e)+8>>2]=r,f[t+12>>2]=n,o=v(-OA(t))):o=v(v(v(+(i>>>0)+4294967296*+(n>>>0))*v(0x10000000000000000))+v(+d[t>>2]+4294967296*+d[t+4>>2])),Z=e+16|0,o}function HA(t,e,i){var r,a=0,o=0,h=0,d=0,C=0,g=0,v=0,y=0,p=0,R=0,D=0,B=0,E=0,F=0,V=0,G=0;Z=r=Z-144|0;t:if((0|i)<=0)e=f[t+12>>2],e&&(_[t+16|0]&&CA(e),f[t+12>>2]=0),f[t+12>>2]=0,n[t+16|0]=1,f[t+4>>2]=0,f[t+8>>2]=0,e=f[t+32>>2],e&&(_[t+36|0]&&CA(e),f[t+32>>2]=0),f[t+32>>2]=0,f[t+24>>2]=0,f[t+28>>2]=0,n[t+36|0]=1,e=f[t+52>>2],e&&(_[t+56|0]&&CA(e),f[t+52>>2]=0),f[t+52>>2]=0,f[t+44>>2]=0,f[t+48>>2]=0,n[t+56|0]=1;else{if(n[r+112|0]=1,f[(a=r+88|0)>>2]=0,f[a+4>>2]=256,f[(a=r+72|0)>>2]=0,f[a+4>>2]=256,f[(a=r+56|0)>>2]=0,f[a+4>>2]=256,f[r+108>>2]=0,f[(a=r+100|0)>>2]=0,f[a+4>>2]=0,f[r+80>>2]=0,f[r+84>>2]=0,f[r+64>>2]=0,f[r+68>>2]=0,f[r+48>>2]=0,f[r+52>>2]=0,TA(r+16|0,e,i),(0|(i=f[t+4>>2]))<=-1)for(f[t+8>>2]<=-1&&((e=f[t+12>>2])&&(_[t+16|0]&&CA(e),f[t+12>>2]=0),n[t+16|0]=1,f[t+8>>2]=0,f[t+12>>2]=0),e=i<<4;a=f[r+4>>2],g=f[t+12>>2]+e|0,f[(d=g)>>2]=f[r>>2],f[d+4>>2]=a,d=f[(a=r+8|0)+4>>2],f[(g=g+8|0)>>2]=f[a>>2],f[g+4>>2]=d,e=e+16|0,g=(a=i+1|0)>>>0>=i>>>0,i=a,g;);if(f[t+4>>2]=0,f[r+8>>2]=0,f[r>>2]=0,f[r+4>>2]=0,(0|(i=f[t+24>>2]))<=-1)for(f[t+28>>2]<=-1&&((e=f[t+32>>2])&&(_[t+36|0]&&CA(e),f[t+32>>2]=0),f[t+28>>2]=0,f[t+32>>2]=0,n[t+36|0]=1),e=m(i,12);g=f[r+4>>2],a=f[t+32>>2]+e|0,f[a>>2]=f[r>>2],f[a+4>>2]=g,f[a+8>>2]=f[r+8>>2],e=e+12|0,g=(a=i+1|0)>>>0>=i>>>0,i=a,g;);if(f[t+24>>2]=0,(0|(i=f[t+44>>2]))<=-1&&(e=f[t+52>>2],f[t+48>>2]<=-1?(!e|!_[t+56|0]||CA(e),n[t+56|0]=1,f[t+48>>2]=0,f[t+52>>2]=0,a=0):a=e,X(a+(e=i<<2)|0,0,0-e|0)),f[t+44>>2]=0,e=f[r+140>>2],!(f[e+104>>2]>-1)){for(f[e+104>>2]=0,y=dA(4),f[y>>2]=e,a=1,d=1,g=y;;){if(jA(r,r+16|0,D=f[(F<<2)+y>>2]),(0|(e=f[t+4>>2]))==f[t+8>>2]&&!((0|e)>=(0|(o=e?e<<1:1)))){if(o?(h=dA(o<<4),e=f[t+4>>2]):h=0,(0|e)>=1)for(i=0;C=f[t+12>>2]+i|0,p=f[C+4>>2],f[(R=i+h|0)>>2]=f[C>>2],f[R+4>>2]=p,p=f[(C=C+8|0)+4>>2],f[(R=R+8|0)>>2]=f[C>>2],f[R+4>>2]=p,i=i+16|0,e=e+-1|0;);(e=f[t+12>>2])&&(_[t+16|0]&&CA(e),f[t+12>>2]=0),f[t+12>>2]=h,n[t+16|0]=1,f[t+8>>2]=o,e=f[t+4>>2]}if(i=f[r+4>>2],e=f[t+12>>2]+(e<<4)|0,f[e>>2]=f[r>>2],f[e+4>>2]=i,o=f[(i=V=r+8|0)+4>>2],f[(e=e+8|0)>>2]=f[i>>2],f[e+4>>2]=o,f[t+4>>2]=f[t+4>>2]+1,R=f[D+8>>2]){for(D=-1,C=R,p=-1;;){if((0|(i=f[C+20>>2]))<=-1){if(h=f[t+24>>2],f[V>>2]=0,f[r>>2]=0,f[r+4>>2]=0,(0|(i=h))==f[t+28>>2]&&!((0|i)>=(0|(v=i?h<<1:1)))){if(v?(o=dA(m(v,12)),e=f[t+24>>2]):(o=0,e=h),(0|e)>=1)for(i=0;B=f[t+32>>2]+i|0,G=f[B+4>>2],f[(E=i+o|0)>>2]=f[B>>2],f[E+4>>2]=G,f[E+8>>2]=f[B+8>>2],i=i+12|0,e=e+-1|0;);(e=f[t+32>>2])&&(_[t+36|0]&&CA(e),f[t+32>>2]=0),f[t+32>>2]=o,n[t+36|0]=1,f[t+28>>2]=v,i=f[t+24>>2]}if(e=f[t+32>>2]+m(i,12)|0,i=f[r+4>>2],f[e>>2]=f[r>>2],f[e+4>>2]=i,f[e+8>>2]=f[V>>2],e=f[t+24>>2]+1|0,f[t+24>>2]=e,f[V>>2]=0,f[r>>2]=0,f[r+4>>2]=0,f[t+28>>2]==(0|e)&&!((0|e)>=(0|(v=e?e<<1:1)))){if(v?(o=dA(m(v,12)),e=f[t+24>>2]):o=0,(0|e)>=1)for(i=0;B=f[t+32>>2]+i|0,G=f[B+4>>2],f[(E=i+o|0)>>2]=f[B>>2],f[E+4>>2]=G,f[E+8>>2]=f[B+8>>2],i=i+12|0,e=e+-1|0;);(e=f[t+32>>2])&&(_[t+36|0]&&CA(e),f[t+32>>2]=0),f[t+32>>2]=o,n[t+36|0]=1,f[t+28>>2]=v,e=f[t+24>>2]}if(i=f[r+4>>2],e=f[t+32>>2]+m(e,12)|0,f[e>>2]=f[r>>2],f[e+4>>2]=i,f[e+8>>2]=f[V>>2],f[t+24>>2]=f[t+24>>2]+1,f[C+20>>2]=h,B=h+1|0,f[f[C+8>>2]+20>>2]=B,v=(E=f[t+32>>2])+m(h,12)|0,f[v+4>>2]=1,f[v+16>>2]=-1,h=f[C+12>>2],(0|(e=f[h+104>>2]))>-1)h=a,a=e;else{if(f[h+104>>2]=a,(0|a)!=(0|d)||(0|d)>=(0|(o=d?d<<1:1)))e=g,o=d;else{e=o?dA(o<<2):0;e:{if((0|d)>=1)for(i=e;f[i>>2]=f[y>>2],i=i+4|0,y=y+4|0,d=d+-1|0;);else if(!y)break e;CA(g)}y=e}f[(a<<2)+y>>2]=h,h=a+1|0,g=e,d=o}f[8+(E+m(B,12)|0)>>2]=F,f[v+8>>2]=a,a=h,i=f[C+20>>2]}if(e=i,(0|D)>=0&&(f[f[t+32>>2]+m(i,12)>>2]=D-i,e=p),D=i,p=e,(0|R)==(0|(C=f[C>>2])))break}f[f[t+32>>2]+m(e,12)>>2]=i-e}if(!((0|(F=F+1|0))<(0|a)))break}for(d=0;;){if(h=f[f[(d<<2)+y>>2]+8>>2])for(e=h;;){if((0|(i=f[e+20>>2]))>=0){if((0|(a=f[t+44>>2]))==f[t+48>>2]&&!((0|a)>=(0|(p=a?a<<1:1)))){p?(D=dA(p<<2),a=f[t+44>>2]):D=0,o=f[t+52>>2];e:{if((0|a)>=1)for(i=D,C=o;f[i>>2]=f[C>>2],i=i+4|0,C=C+4|0,a=a+-1|0;);else if(!o)break e;_[t+56|0]&&CA(o),f[t+52>>2]=0,a=f[t+44>>2]}f[t+48>>2]=p,f[t+52>>2]=D,n[t+56|0]=1,i=f[e+20>>2]}for(f[f[t+52>>2]+(a<<2)>>2]=i,f[t+44>>2]=f[t+44>>2]+1,i=e;f[i+20>>2]=-1,(0|(i=f[f[i+8>>2]+4>>2]))!=(0|e););}if((0|h)==(0|(e=f[e>>2])))break}if((0|(d=d+1|0))==(0|F))break}y&&CA(g)}for((t=f[r+108>>2])&&(_[r+112|0]&&CA(t),f[r+108>>2]=0),f[r+108>>2]=0,n[r+112|0]=1,f[r+100>>2]=0,f[r+104>>2]=0;t=f[r+80>>2];)f[r+80>>2]=f[t+8>>2],CA(f[t>>2]),CA(t);for(;t=f[r+64>>2];)f[r+64>>2]=f[t+8>>2],CA(f[t>>2]),CA(t);for(;;){if(!(t=f[r+48>>2]))break t;f[r+48>>2]=f[t+8>>2],CA(f[t>>2]),CA(t)}}Z=r+144|0}function zA(t){return DA(t),f[t+56>>2]=0,f[t>>2]=7108,t}function PA(t,e){var i=0,r=0,a=0,o=0,h=0,d=0,C=0,g=0,v=0,y=0,p=0,R=0,D=0,B=0,E=0,F=0;if(f[t+8>>2]<(0|e)){if(v=e?dA(m(e,36)):0,!((0|(D=f[t+4>>2]))<1)){for(;;){if(i=m(y,36),f[(a=i+v|0)+4>>2]=0,f[a+8>>2]=0,n[a+16|0]=1,f[a+12>>2]=0,p=a+4|0,C=i+f[t+12>>2]|0,(0|(d=f[C+4>>2]))>=1){F=a+8|0,B=a+16|0,o=dA(E=d<<2),g=f[(R=a+12|0)>>2];t:{if((0|(h=f[p>>2]))>=1)for(r=o,i=g;f[r>>2]=f[i>>2],r=r+4|0,i=i+4|0,h=h+-1|0;);else if(!g)break t;_[0|B]&&CA(g)}for(f[R>>2]=o,n[0|B]=1,f[F>>2]=d,X(o,0,E),f[p>>2]=d,r=f[C+12>>2],i=f[R>>2];f[i>>2]=f[r>>2],i=i+4|0,r=r+4|0,d=d+-1|0;);}else f[p>>2]=d;if(i=f[C+24>>2],f[a+20>>2]=f[C+20>>2],f[a+24>>2]=i,o=f[(r=C+28|0)+4>>2],f[(i=a+28|0)>>2]=f[r>>2],f[i+4>>2]=o,(0|(y=y+1|0))==(0|D))break}if(!((0|(h=f[t+4>>2]))<1))for(i=8;g=(r=f[t+12>>2]+i|0)+-4|0,(a=f[(o=r+4|0)>>2])&&(_[r+8|0]&&CA(a),f[o>>2]=0),f[g>>2]=0,f[o>>2]=0,f[r>>2]=0,n[r+8|0]=1,i=i+36|0,h=h+-1|0;);}(i=f[t+12>>2])&&(_[t+16|0]&&CA(i),f[t+12>>2]=0),f[t+12>>2]=v,n[t+16|0]=1,f[t+8>>2]=e}}function KA(t,e,i){var r,a=0,o=0,h=0,d=0,g=0,p=0,R=0,D=0,B=0,F=v(0),V=0,G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),yt=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=0,Ot=v(0);Z=r=Z-32|0,F=C[i+8>>2],v(y(F))>v(.7071067690849304)?(w=C[i+4>>2],Q=v(v(F*F)+v(w*w)),G=v(v(1)/v(E(Q))),z=v(Q*G),Y=C[i>>2],Q=v(-v(F*G)),pt=v(Y*Q),w=v(w*G),W=v(-v(Y*w)),Y=v(0)):(Q=C[i>>2],w=C[i+4>>2],Y=v(v(Q*Q)+v(w*w)),G=v(v(1)/v(E(Y))),pt=v(Y*G),Y=v(-v(w*G)),W=v(F*Y),Q=v(Q*G),z=v(-v(F*Q)),w=v(0));t:if((0|(h=f[t+4>>2]))>=2){for(o=f[t+12>>2];g=(a=o+p|0)+8|0,v(v(v(Y*C[a>>2])+v(Q*C[a+4>>2]))+v(w*C[g>>2]))>2])+v(Q*C[o+4>>2]))+v(w*C[o+8>>2]))&&(B=f[(R=o+16|0)+4>>2],f[(h=r+24|0)>>2]=f[R>>2],f[h+4>>2]=B,B=f[(V=o+8|0)+4>>2],f[(D=r+16|0)>>2]=f[V>>2],f[D+4>>2]=B,B=f[o+4>>2],f[r+8>>2]=f[o>>2],f[r+12>>2]=B,B=f[a+4>>2],f[o>>2]=f[a>>2],f[o+4>>2]=B,o=f[g+4>>2],f[V>>2]=f[g>>2],f[V+4>>2]=o,a=f[(o=a+16|0)+4>>2],f[R>>2]=f[o>>2],f[R+4>>2]=a,g=f[r+12>>2],o=f[t+12>>2]+p|0,f[(a=o)>>2]=f[r+8>>2],f[a+4>>2]=g,g=f[h+4>>2],f[(a=a+16|0)>>2]=f[h>>2],f[a+4>>2]=g,a=f[D+4>>2],f[(o=o+8|0)>>2]=f[D>>2],f[o+4>>2]=a,o=f[t+12>>2],h=f[t+4>>2]),p=p+24|0,(0|(d=d+1|0))<(0|h););if(f[o+16>>2]=-246811958,(0|h)>=2)for(p=h+-1|0,a=o+40|0,Dt=C[o+8>>2],It=C[o>>2],Tt=C[o+4>>2];G=v(0),V=a,F=v(C[a+-16>>2]-It),St=v(C[a+-12>>2]-Tt),Ot=v(C[a+-8>>2]-Dt),yt=v(v(v(z*F)+v(W*St))+v(pt*Ot)),F=v(v(v(Y*F)+v(Q*St))+v(w*Ot)),v(v(yt*yt)+v(F*F))=v(0)?(F=v(v(F-G)/v(F+G)),G=v(.7853981852531433)):(F=v(v(F+G)/v(G-F)),G=v(2.356194496154785)),F=v(G+v(F*v(-.7853981852531433))),G=yt>2]=G,a=a+24|0,p=p+-1|0;);if(p=f[(d=o+8|0)+4>>2],f[(a=r+16|0)>>2]=f[d>>2],f[a+4>>2]=p,a=f[o+4>>2],f[r+8>>2]=f[o>>2],f[r+12>>2]=a,function A(t,e,i,r){var n,a,o=v(0),_=0,h=0,d=0,g=v(0),y=0,p=0,R=0,D=0,B=v(0),E=0,F=v(0),V=v(0),G=v(0),w=v(0),Q=0,W=0,Y=0,z=v(0),yt=v(0),pt=v(0),Dt=0;for(Z=n=Z-32|0,h=(y=f[t+12>>2])+m((i+r|0)/2|0,24)|0,a=f[h+20>>2],F=C[h+16>>2],z=C[h+8>>2],yt=C[h+4>>2],pt=C[h>>2],h=i,p=r;;){for(V=C[e>>2],g=v(pt-V),o=v(g*g),G=C[e+4>>2],g=v(yt-G),o=v(o+v(g*g)),w=C[e+8>>2],g=v(z-w),g=v(o+v(g*g)),_=20+(m(h,24)+y|0)|0;;){e:{i:if((o=C[_+-4>>2])==F){if(o=v(C[_+-20>>2]-V),B=v(o*o),o=v(C[_+-16>>2]-G),B=v(B+v(o*o)),o=v(C[_+-12>>2]-w),(o=v(B+v(o*o)))!=g){if(o>2]>=(0|a))break e}else if(!(o>2])){if(o=v(C[d>>2]-V),B=v(o*o),o=v(C[d+4>>2]-G),B=v(B+v(o*o)),o=v(C[d+8>>2]-w),g!=(o=v(B+v(o*o)))){if(g=f[d+20>>2])break e}else if(!(F>2],f[(y=n+24|0)>>2]=f[E>>2],f[y+4>>2]=D,Dt=f[(E=_+8|0)+4>>2],f[(D=Y=n+16|0)>>2]=f[E>>2],f[D+4>>2]=Dt,D=f[_+4>>2],f[n+8>>2]=f[_>>2],f[n+12>>2]=D,D=f[d+4>>2],f[_>>2]=f[d>>2],f[_+4>>2]=D,d=f[(_=d+8|0)+4>>2],f[E>>2]=f[_>>2],f[E+4>>2]=d,_=f[Q+4>>2],f[W>>2]=f[Q>>2],f[W+4>>2]=_,_=f[t+12>>2]+R|0,R=f[n+12>>2],f[_>>2]=f[n+8>>2],f[_+4>>2]=R,R=f[y+4>>2],f[(d=_+16|0)>>2]=f[y>>2],f[d+4>>2]=R,d=f[Y+4>>2],f[(_=_+8|0)>>2]=f[Y>>2],f[_+4>>2]=d,p=p+-1|0,h=h+1|0),!((0|h)<=(0|p)))break;y=f[t+12>>2]}(0|p)>(0|i)&&A(t,e,i,p),(0|h)<(0|r)&&A(t,e,h,r),Z=n+32|0}(t,r+8|0,1,h+-1|0),a=f[t+12>>2],(0|(d=f[e+4>>2]))==f[e+8>>2]&&!((0|d)>=(0|(p=d?d<<1:1)))){if(p?(h=dA(m(p,24)),d=f[e+4>>2]):h=0,(0|d)>=1)for(o=0;V=f[e+12>>2]+o|0,B=f[(R=V)+4>>2],f[(g=o+h|0)>>2]=f[R>>2],f[g+4>>2]=B,B=f[(R=R+16|0)+4>>2],f[(D=g+16|0)>>2]=f[R>>2],f[D+4>>2]=B,D=f[(R=V+8|0)+4>>2],f[(g=g+8|0)>>2]=f[R>>2],f[g+4>>2]=D,o=o+24|0,d=d+-1|0;);(o=f[e+12>>2])&&(_[e+16|0]&&CA(o),f[e+12>>2]=0),f[e+12>>2]=h,n[e+16|0]=1,f[e+8>>2]=p,d=f[e+4>>2]}if(o=f[e+12>>2]+m(d,24)|0,d=f[a+4>>2],f[o>>2]=f[a>>2],f[o+4>>2]=d,p=f[(d=a+16|0)+4>>2],f[(h=o+16|0)>>2]=f[d>>2],f[h+4>>2]=p,h=f[(a=a+8|0)+4>>2],f[(o=o+8|0)>>2]=f[a>>2],f[o+4>>2]=h,a=f[e+4>>2]+1|0,f[e+4>>2]=a,d=f[t+12>>2]+24|0,f[e+8>>2]==(0|a)&&!((0|a)>=(0|(p=a?a<<1:1)))){if(p?(h=dA(m(p,24)),a=f[e+4>>2]):h=0,(0|a)>=1)for(o=0;V=f[e+12>>2]+o|0,B=f[(R=V)+4>>2],f[(g=o+h|0)>>2]=f[R>>2],f[g+4>>2]=B,B=f[(R=R+16|0)+4>>2],f[(D=g+16|0)>>2]=f[R>>2],f[D+4>>2]=B,D=f[(R=V+8|0)+4>>2],f[(g=g+8|0)>>2]=f[R>>2],f[g+4>>2]=D,o=o+24|0,a=a+-1|0;);(o=f[e+12>>2])&&(_[e+16|0]&&CA(o),f[e+12>>2]=0),f[e+12>>2]=h,n[e+16|0]=1,f[e+8>>2]=p,a=f[e+4>>2]}if(h=f[d+4>>2],o=f[e+12>>2]+m(a,24)|0,f[(a=o)>>2]=f[d>>2],f[a+4>>2]=h,p=f[(h=d+16|0)+4>>2],f[(a=a+16|0)>>2]=f[h>>2],f[a+4>>2]=p,h=f[(a=d+8|0)+4>>2],f[(o=o+8|0)>>2]=f[a>>2],f[o+4>>2]=h,a=f[e+4>>2]+1|0,f[e+4>>2]=a,2==f[t+4>>2])break t;for(R=2;;){e:if(!((0|a)<2)){for(d=m(a,48),p=a<<1,o=((D=f[e+12>>2])+m(a,24)|0)-48|0,g=f[t+12>>2]+m(R,24)|0,F=C[g+8>>2],G=C[g+4>>2],Q=C[g>>2],w=C[i+8>>2],Y=C[i+4>>2],yt=C[i>>2];;){if(z=C[o>>2],pt=v(z-C[o+24>>2]),W=C[o+4>>2],Dt=v(W-G),W=v(W-C[o+28>>2]),z=v(z-Q),St=v(v(v(pt*Dt)-v(W*z))*w),Tt=W,W=C[o+8>>2],It=v(W-F),W=v(W-C[o+32>>2]),!(v(St+v(v(yt*v(v(Tt*It)-v(W*Dt)))+v(Y*v(v(W*z)-v(pt*It)))))>v(0))){if(a=a+-1|0,f[e+4>>2]=a,o=o+-24|0,d=d+-48|0,p=p+-2|0,(0|a)>1)continue;break e}break}if(!(f[e+8>>2]!=(0|a)|(0|a)>=(0|p))){if(D=dA(d),(0|(h=f[e+4>>2]))>=1)for(o=0;B=f[e+12>>2]+o|0,Et=f[(d=B)+4>>2],f[(a=o+D|0)>>2]=f[d>>2],f[a+4>>2]=Et,Et=f[(d=d+16|0)+4>>2],f[(V=a+16|0)>>2]=f[d>>2],f[V+4>>2]=Et,V=f[(d=B+8|0)+4>>2],f[(a=a+8|0)>>2]=f[d>>2],f[a+4>>2]=V,o=o+24|0,h=h+-1|0;);(o=f[e+12>>2])&&(_[e+16|0]&&CA(o),f[e+12>>2]=0),f[e+12>>2]=D,n[e+16|0]=1,f[e+8>>2]=p,a=f[e+4>>2]}h=f[g+4>>2],o=m(a,24)+D|0,f[(a=o)>>2]=f[g>>2],f[a+4>>2]=h,d=f[(h=g+16|0)+4>>2],f[(a=a+16|0)>>2]=f[h>>2],f[a+4>>2]=d,h=f[(a=g+8|0)+4>>2],f[(o=o+8|0)>>2]=f[a>>2],f[o+4>>2]=h,a=f[e+4>>2]+1|0,f[e+4>>2]=a}if(1==(0|a)){if(a=f[t+12>>2]+m(R,24)|0,o=1,1==f[e+8>>2]){if(h=dA(48),(0|(d=f[e+4>>2]))>=1)for(o=0;V=f[e+12>>2]+o|0,B=f[(g=V)+4>>2],f[(p=o+h|0)>>2]=f[g>>2],f[p+4>>2]=B,B=f[(g=g+16|0)+4>>2],f[(D=p+16|0)>>2]=f[g>>2],f[D+4>>2]=B,D=f[(g=V+8|0)+4>>2],f[(p=p+8|0)>>2]=f[g>>2],f[p+4>>2]=D,o=o+24|0,d=d+-1|0;);(o=f[e+12>>2])&&(_[e+16|0]&&CA(o),f[e+12>>2]=0),f[e+12>>2]=h,n[e+16|0]=1,f[e+8>>2]=2,o=f[e+4>>2]}d=f[a+4>>2],o=f[e+12>>2]+m(o,24)|0,f[o>>2]=f[a>>2],f[o+4>>2]=d,p=f[(d=a+16|0)+4>>2],f[(h=o+16|0)>>2]=f[d>>2],f[h+4>>2]=p,h=f[(a=a+8|0)+4>>2],f[(o=o+8|0)>>2]=f[a>>2],f[o+4>>2]=h,a=f[e+4>>2]+1|0,f[e+4>>2]=a}if((0|(R=R+1|0))==f[t+4>>2])break}}else if(1==(0|h))for(a=f[e+4>>2];;){if(i=f[t+12>>2],f[e+8>>2]==(0|a)&&!((0|a)>=(0|(d=a?a<<1:1)))){if(d?(h=dA(m(d,24)),a=f[e+4>>2]):h=0,(0|a)>=1)for(o=0;V=f[e+12>>2]+o|0,B=f[(R=V)+4>>2],f[(g=o+h|0)>>2]=f[R>>2],f[g+4>>2]=B,B=f[(R=R+16|0)+4>>2],f[(D=g+16|0)>>2]=f[R>>2],f[D+4>>2]=B,D=f[(R=V+8|0)+4>>2],f[(g=g+8|0)>>2]=f[R>>2],f[g+4>>2]=D,o=o+24|0,a=a+-1|0;);(o=f[e+12>>2])&&(_[e+16|0]&&CA(o),f[e+12>>2]=0),f[e+12>>2]=h,n[e+16|0]=1,f[e+8>>2]=d,a=f[e+4>>2]}if(h=f[i+4>>2],o=f[e+12>>2]+m(a,24)|0,f[(a=o)>>2]=f[i>>2],f[a+4>>2]=h,d=f[(h=i+16|0)+4>>2],f[(a=a+16|0)>>2]=f[h>>2],f[a+4>>2]=d,a=f[(i=i+8|0)+4>>2],f[(o=o+8|0)>>2]=f[i>>2],f[o+4>>2]=a,a=f[e+4>>2]+1|0,f[e+4>>2]=a,!((0|(p=p+1|0))>2]))break}Z=r+32|0}function LA(t,e){var i,r,a=0,o=0,h=0,d=0,C=0,g=0,v=0,y=0,p=0,R=0,D=0;if((0|(g=f[t+4>>2]))==f[t+8>>2]&&(PA(t,g?g<<1:1),g=f[t+4>>2]),a=(r=f[t+12>>2])+m(g,36)|0,f[a+4>>2]=0,f[a+8>>2]=0,n[a+16|0]=1,f[a+12>>2]=0,i=a+4|0,(0|(h=f[e+4>>2]))>=1){D=a+8|0,p=a+16|0,o=dA(R=h<<2),a=f[(y=a+12|0)>>2];t:{if((0|(v=f[i>>2]))>=1)for(d=o,C=a;f[d>>2]=f[C>>2],d=d+4|0,C=C+4|0,v=v+-1|0;);else if(!a)break t;_[0|p]&&CA(a)}for(f[y>>2]=o,n[0|p]=1,f[D>>2]=h,X(o,0,R),f[i>>2]=h,d=f[e+12>>2],C=f[y>>2];f[C>>2]=f[d>>2],C=C+4|0,d=d+4|0,h=h+-1|0;);}else f[i>>2]=h;a=f[e+24>>2],o=m(g,36)+r|0,f[o+20>>2]=f[e+20>>2],f[o+24>>2]=a,e=f[(a=e+28|0)+4>>2],f[(o=o+28|0)>>2]=f[a>>2],f[o+4>>2]=e,f[t+4>>2]=f[t+4>>2]+1}function qA(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),Z=v(0),z=v(0);n=v(yt[f[f[t>>2]+48>>2]](t)),Z=C[e+52>>2],_=C[e+24>>2],h=C[e+20>>2],d=C[e+56>>2],g=C[e+40>>2],m=C[t+68>>2],B=C[t+84>>2],E=C[e+36>>2],a=C[t- -64>>2],F=C[t+80>>2],z=C[e+48>>2],V=C[e+8>>2],G=C[e>>2],w=C[e+4>>2],Q=C[e+16>>2],W=C[e+32>>2],o=C[t+60>>2],Y=C[t+76>>2],f[i+12>>2]=0,p=d,d=v(v(Y+o)*v(.5)),R=v(v(F+a)*v(.5)),D=v(v(B+m)*v(.5)),p=v(p+v(v(v(W*d)+v(E*R))+v(g*D))),o=v(n+v(v(Y-o)*v(.5))),a=v(n+v(v(F-a)*v(.5))),n=v(n+v(v(B-m)*v(.5))),g=v(v(v(o*v(y(W)))+v(a*v(y(E))))+v(n*v(y(g)))),C[i+8>>2]=p-g,m=v(Z+v(v(v(d*Q)+v(R*h))+v(D*_))),_=v(v(v(o*v(y(Q)))+v(a*v(y(h))))+v(n*v(y(_)))),C[i+4>>2]=m-_,h=v(z+v(v(v(d*G)+v(R*w))+v(D*V))),n=v(v(v(o*v(y(G)))+v(a*v(y(w))))+v(n*v(y(V)))),C[i>>2]=h-n,f[r+12>>2]=0,C[r+8>>2]=g+p,C[r+4>>2]=_+m,C[r>>2]=n+h}function $A(t,e,i,r){e|=0,i|=0,r|=0,yt[f[f[(t|=0)>>2]+80>>2]](t,e,i,r)}function Ae(t){var e;return f[(t|=0)>>2]=7108,(e=f[t+56>>2])&&(yt[f[f[e>>2]>>2]](e),CA(f[t+56>>2])),0|t}function ee(t,e){var i=v(0),r=v(0),n=v(0),a=v(0),o=v(0),f=0;return i=C[t+48>>2],r=C[t+52>>2],n=C[t+56>>2],a=C[t+60>>2],o=v(C[t+64>>2]+C[e+64>>2]),!(v(v(v(v(v(C[e>>2]*i)+v(C[e+4>>2]*r))+v(C[e+8>>2]*n))-a)-o)>v(0)^1|v(v(v(v(v(i*C[e+16>>2])+v(r*C[e+20>>2]))+v(n*C[e+24>>2]))-a)-o)>v(0)^1)&&(f=0,v(v(v(v(v(i*C[e+32>>2])+v(r*C[e+36>>2]))+v(n*C[e+40>>2]))-a)-o)>v(0))||(i=C[e+48>>2],r=C[e+52>>2],n=C[e+56>>2],a=C[e+60>>2],f=v(v(v(v(v(C[t>>2]*i)+v(C[t+4>>2]*r))+v(C[t+8>>2]*n))-a)-o)>v(0)^1|v(v(v(v(v(i*C[t+16>>2])+v(r*C[t+20>>2]))+v(n*C[t+24>>2]))-a)-o)>v(0)^1|v(v(v(v(v(i*C[t+32>>2])+v(r*C[t+36>>2]))+v(n*C[t+40>>2]))-a)-o)>v(0)^1),f}function re(t,e,i){var r,n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=0;return Z=r=Z-528|0,d=C[t+20>>2],o=v(d-C[t+4>>2]),a=C[t+56>>2],g=C[t+24>>2],_=v(g-C[t+8>>2]),h=C[t+52>>2],R=n=v(v(o*a)-v(_*h)),m=C[t+16>>2],y=v(m-C[t>>2]),p=v(y*h),h=C[t+48>>2],o=v(p-v(o*h)),p=v(n*n),n=v(v(_*h)-v(y*a)),a=v(v(1)/v(E(v(v(o*o)+v(p+v(n*n)))))),_=v(R*a),C[r+256>>2]=_,n=v(n*a),C[r+260>>2]=n,o=v(o*a),C[r+264>>2]=o,C[r+268>>2]=v(g*o)+v(v(m*_)+v(d*n)),e=function(t,e,i,r,n){var a=0,o=v(0),_=v(0),h=v(0),d=0,g=v(0),m=0,y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=0,F=v(0),V=0;y=C[e>>2],o=C[t>>2],_=C[t+4>>2],h=C[t+8>>2],g=C[t+12>>2],(d=(p=v(v(v(v(y*o)+v(C[e+4>>2]*_))+v(C[e+8>>2]*h))-g))>v(1.1920928955078125e-7))||(a=f[e+4>>2],f[n>>2]=f[e>>2],f[n+4>>2]=a,E=f[(m=e+8|0)+4>>2],f[(a=n+8|0)>>2]=f[m>>2],f[a+4>>2]=E,g=C[t+12>>2],h=C[t+8>>2],_=C[t+4>>2],o=C[t>>2],a=1),R=C[i>>2],D=C[i+4>>2],B=C[i+8>>2],((o=v(v(v(v(R*o)+v(D*_))+v(B*h))-g))>v(1.1920928955078125e-7)|0)!=(0|d)&&(g=C[e+4>>2],F=C[e+8>>2],f[(d=(a<<4)+n|0)+12>>2]=0,_=v(v(-p)/v(o-p)),h=v(v(1)-_),C[d+8>>2]=v(B*_)+v(F*h),C[d+4>>2]=v(D*_)+v(h*g),C[d>>2]=v(R*_)+v(y*h),a=a+1|0),(d=o>v(1.1920928955078125e-7))||(V=f[i+4>>2],f[(m=(a<<4)+n|0)>>2]=f[i>>2],f[m+4>>2]=V,V=f[(E=i+8|0)+4>>2],f[(m=m+8|0)>>2]=f[E>>2],f[m+4>>2]=V,a=a+1|0),g=C[r>>2],y=C[r+4>>2],R=C[r+8>>2],((_=v(v(v(v(g*C[t>>2])+v(y*C[t+4>>2]))+v(R*C[t+8>>2]))-C[t+12>>2]))>v(1.1920928955078125e-7)|0)!=(0|d)&&(D=C[i>>2],B=C[i+4>>2],F=C[i+8>>2],f[(t=(a<<4)+n|0)+12>>2]=0,o=v(v(-o)/v(_-o)),h=v(v(1)-o),C[t+8>>2]=v(R*o)+v(F*h),C[t+4>>2]=v(y*o)+v(h*B),C[t>>2]=v(g*o)+v(h*D),a=a+1|0);t:{e:{i:{if(!(_>v(1.1920928955078125e-7))){if(i=f[r+4>>2],f[(t=(a<<4)+n|0)>>2]=f[r>>2],f[t+4>>2]=i,d=f[(i=r+8|0)+4>>2],f[(t=t+8|0)>>2]=f[i>>2],f[t+4>>2]=d,a=a+1|0,p>v(1.1920928955078125e-7))break i;break e}if(p>v(1.1920928955078125e-7))break t}if(h=C[r>>2],g=C[e>>2],y=C[r+4>>2],R=C[e+4>>2],o=C[r+8>>2],D=C[e+8>>2],f[(t=(a<<4)+n|0)+12>>2]=0,B=o,o=v(v(-_)/v(p-_)),_=v(v(1)-o),C[t+8>>2]=v(B*_)+v(o*D),C[t+4>>2]=v(_*y)+v(o*R),C[t>>2]=v(_*h)+v(o*g),a=a+1|0,p>v(1.1920928955078125e-7))break t}i=f[e+4>>2],f[(t=(a<<4)+n|0)>>2]=f[e>>2],f[t+4>>2]=i,i=f[(e=e+8|0)+4>>2],f[(t=t+8|0)>>2]=f[e>>2],f[t+4>>2]=i,a=a+1|0}return a}(r+256|0,e,e+16|0,e+32|0,r+272|0),D=0,e&&(d=C[t+40>>2],a=v(d-C[t+24>>2]),o=C[t+48>>2],g=C[t+32>>2],_=v(g-C[t+16>>2]),h=C[t+56>>2],R=n=v(v(a*o)-v(_*h)),p=_,_=C[t+52>>2],m=C[t+36>>2],y=v(m-C[t+20>>2]),o=v(v(p*_)-v(y*o)),a=v(v(y*h)-v(a*_)),n=v(v(1)/v(E(v(v(o*o)+v(v(a*a)+v(n*n)))))),_=v(R*n),C[r+260>>2]=_,a=v(a*n),C[r+256>>2]=a,n=v(o*n),C[r+264>>2]=n,C[r+268>>2]=v(d*n)+v(v(g*a)+v(m*_)),D=0,(e=ie(r+256|0,r+272|0,e,r))&&(d=C[t+8>>2],a=v(d-C[t+40>>2]),o=C[t+48>>2],g=C[t>>2],_=v(g-C[t+32>>2]),h=C[t+56>>2],R=n=v(v(a*o)-v(_*h)),p=_,_=C[t+52>>2],m=C[t+4>>2],y=v(m-C[t+36>>2]),o=v(v(p*_)-v(y*o)),a=v(v(y*h)-v(a*_)),n=v(v(1)/v(E(v(v(o*o)+v(v(a*a)+v(n*n)))))),_=v(R*n),C[r+260>>2]=_,a=v(a*n),C[r+256>>2]=a,n=v(o*n),C[r+264>>2]=n,C[r+268>>2]=v(d*n)+v(v(g*a)+v(m*_)),D=ie(r+256|0,r,e,i))),Z=r+528|0,t=D}function ie(t,e,i,r){var n=0,a=0,o=v(0),_=v(0),h=v(0),d=0,g=0,m=v(0),y=v(0),p=v(0),R=v(0),D=0,B=0,E=v(0),F=v(0),V=v(0);if((h=v(v(v(v(C[e>>2]*C[t>>2])+v(C[e+4>>2]*C[t+4>>2]))+v(C[e+8>>2]*C[t+8>>2]))-C[t+12>>2]))>v(1.1920928955078125e-7)||(n=f[e+4>>2],f[r>>2]=f[e>>2],f[r+4>>2]=n,a=f[(d=e+8|0)+4>>2],f[(n=r+8|0)>>2]=f[d>>2],f[n+4>>2]=a,a=1),(0|i)<2)o=h;else for(D=i+-1|0,n=e,_=h;y=C[(d=n+16|0)>>2],p=C[n+20>>2],R=C[(B=n+24|0)>>2],(0|(g=(o=v(v(v(v(y*C[t>>2])+v(p*C[t+4>>2]))+v(R*C[t+8>>2]))-C[t+12>>2]))>v(1.1920928955078125e-7)))!=(_>v(1.1920928955078125e-7)|0)&&(E=C[n+4>>2],F=C[n+8>>2],V=C[n>>2],f[(n=(a<<4)+r|0)+12>>2]=0,_=v(v(-_)/v(o-_)),m=v(v(1)-_),C[n+8>>2]=v(R*_)+v(F*m),C[n+4>>2]=v(p*_)+v(m*E),C[n>>2]=v(y*_)+v(m*V),a=a+1|0),g||(g=f[d+4>>2],f[(n=(a<<4)+r|0)>>2]=f[d>>2],f[n+4>>2]=g,g=f[B+4>>2],f[(n=n+8|0)>>2]=f[B>>2],f[n+4>>2]=g,a=a+1|0),n=d,_=o,D=D+-1|0;);return(0|(n=h>v(1.1920928955078125e-7)))!=(o>v(1.1920928955078125e-7)|0)&&(_=C[(t=(i+-1<<4)+e|0)>>2],m=C[t+4>>2],y=C[t+8>>2],p=C[e>>2],R=C[e+4>>2],E=C[e+8>>2],f[(t=(a<<4)+r|0)+12>>2]=0,o=v(v(-o)/v(h-o)),h=v(v(1)-o),C[t+8>>2]=v(y*h)+v(o*E),C[t+4>>2]=v(h*m)+v(o*R),C[t>>2]=v(h*_)+v(o*p),a=a+1|0),n||(i=f[e+4>>2],f[(t=(a<<4)+r|0)>>2]=f[e>>2],f[t+4>>2]=i,i=f[(e=e+8|0)+4>>2],f[(t=t+8|0)>>2]=f[e>>2],f[t+4>>2]=i,a=a+1|0),a}function fe(t,e,i){var r,n=0,a=0,o=0,_=0,h=v(0),d=v(0),g=0,m=0,y=0,p=0,R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0);if(Z=r=Z-880|0,d=C[e+64>>2],h=C[t+64>>2],a=f[(m=t+56|0)+4>>2],f[(_=r+296|0)>>2]=f[m>>2],f[_+4>>2]=a,a=f[t+52>>2],f[r+288>>2]=f[t+48>>2],f[r+292>>2]=a,n=0,(a=re(t,e,r+560|0))&&(f[r+280>>2]=-998637568,f[r+284>>2]=0,n=0,!((0|a)<=0))){for(F=v(h+d),m=r+288|0,D=C[r+300>>2],B=C[r+296>>2],E=C[r+292>>2],_=0,R=v(-1e3),n=r+560|0,d=C[r+288>>2];(h=v(F-v(v(v(v(C[n>>2]*d)+v(C[n+4>>2]*E))+v(C[n+8>>2]*B))-D)))>=v(0)&&(h>R?(f[r+816>>2]=o,_=1,R=h):v(h+v(1.1920928955078125e-7))>=R&&(f[(r+816|0)+(_<<2)>>2]=o,_=_+1|0)),n=n+16|0,(0|a)!=(0|(o=o+1|0)););if(C[r+280>>2]=R,f[r+284>>2]=_,(0|_)>=1)for(n=r+304|0,o=r+816|0,a=_;y=(r+560|0)+(f[o>>2]<<4)|0,g=f[y+4>>2],f[n>>2]=f[y>>2],f[n+4>>2]=g,g=f[y+12>>2],f[(p=n+8|0)>>2]=f[y+8>>2],f[p+4>>2]=g,o=o+4|0,n=n+16|0,a=a+-1|0;);if(n=0,_&&(C[(a=r+292|0)>>2]=-C[a>>2],C[(a=r+296|0)>>2]=-C[a>>2],C[r+288>>2]=-C[r+288>>2],a=f[(g=e+56|0)+4>>2],f[(p=r+16|0)>>2]=f[g>>2],f[p+4>>2]=a,a=f[e+52>>2],f[r+8>>2]=f[e+48>>2],f[r+12>>2]=a,n=0,(e=re(e,t,r+560|0))&&(f[r>>2]=-998637568,f[r+4>>2]=0,n=0,!((0|e)<=0)))){for(t=r+8|0,V=C[r+20>>2],D=C[r+16>>2],B=C[r+12>>2],a=0,d=v(-1e3),n=r+560|0,E=C[r+8>>2],o=0;(h=v(F-v(v(v(v(C[n>>2]*E)+v(C[n+4>>2]*B))+v(C[n+8>>2]*D))-V)))>=v(0)&&(h>d?(f[r+816>>2]=o,a=1,d=h):v(h+v(1.1920928955078125e-7))>=d&&(f[(r+816|0)+(a<<2)>>2]=o,a=a+1|0)),n=n+16|0,(0|e)!=(0|(o=o+1|0)););if(C[r>>2]=d,f[r+4>>2]=a,(0|a)>=1)for(n=r+24|0,o=r+816|0,e=a;y=(r+560|0)+(f[o>>2]<<4)|0,g=f[y+4>>2],f[n>>2]=f[y>>2],f[n+4>>2]=g,g=f[y+12>>2],f[(p=n+8|0)>>2]=f[y+8>>2],f[p+4>>2]=g,o=o+4|0,n=n+16|0,e=e+-1|0;);if(n=0,a){if(d>2]=d,f[i+4>>2]=a,e=f[t+4>>2],f[i+8>>2]=f[t>>2],f[i+12>>2]=e,t=f[(e=t+8|0)+4>>2],f[(m=i+16|0)>>2]=f[e>>2],f[m+4>>2]=t,n=(t=a<<4)+(i+8|0)|0,o=8+(t+r|0)|0;t=f[o+4>>2],f[n>>2]=f[o>>2],f[n+4>>2]=t,t=f[(e=o+8|0)+4>>2],f[(i=n+8|0)>>2]=f[e>>2],f[i+4>>2]=t,o=o+-16|0,n=n+-16|0,a=a+-1|0;);else for(C[i>>2]=R,f[i+4>>2]=_,t=f[m+4>>2],f[i+8>>2]=f[m>>2],f[i+12>>2]=t,t=f[(e=m+8|0)+4>>2],f[(a=i+16|0)>>2]=f[e>>2],f[a+4>>2]=t,n=(t=_<<4)+(i+8|0)|0,o=288+(t+r|0)|0;t=f[o+4>>2],f[n>>2]=f[o>>2],f[n+4>>2]=t,t=f[(e=o+8|0)+4>>2],f[(i=n+8|0)>>2]=f[e>>2],f[i+4>>2]=t,o=o+-16|0,n=n+-16|0,_=_+-1|0;);n=1}}}return Z=r+880|0,n}function te(t){!function(t){var e=0;DA(t),n[t+92|0]=0,f[t+88>>2]=0,f[(e=t+80|0)>>2]=-1082130432,f[e+4>>2]=-1082130432,f[(e=t+72|0)>>2]=0,f[e+4>>2]=-1082130432,f[(e=t- -64|0)>>2]=1065353216,f[e+4>>2]=1065353216,f[t>>2]=7240,f[t+56>>2]=0,f[t+60>>2]=1065353216}(t),f[t+96>>2]=0,f[t>>2]=7464,f[t+4>>2]=2}function ne(t){return f[(t|=0)+96>>2]}function ae(t,e,i,r){}function oe(t,e){return 0}function ce(t){Ae(t|=0),CA(t)}function be(t){var e=0;f[t>>2]=1025,f[(e=t+120|0)>>2]=0,f[e+4>>2]=0,f[(e=t+128|0)>>2]=0,f[e+4>>2]=0,f[(e=t+136|0)>>2]=0,f[e+4>>2]=0,f[(e=t+144|0)>>2]=0,f[e+4>>2]=0,f[(e=t+152|0)>>2]=0,f[e+4>>2]=0,f[t+160>>2]=0,f[(e=t+312|0)>>2]=0,f[e+4>>2]=0,f[(e=t+320|0)>>2]=0,f[e+4>>2]=0,f[(e=t+328|0)>>2]=0,f[e+4>>2]=0,f[(e=t+336|0)>>2]=0,f[e+4>>2]=0,f[(e=t+344|0)>>2]=0,f[e+4>>2]=0,f[t+352>>2]=0,f[(e=t+504|0)>>2]=0,f[e+4>>2]=0,f[(e=t+512|0)>>2]=0,f[e+4>>2]=0,f[(e=t+520|0)>>2]=0,f[e+4>>2]=0,f[(e=t+528|0)>>2]=0,f[e+4>>2]=0,f[(e=t+536|0)>>2]=0,f[e+4>>2]=0,f[t+544>>2]=0,f[t+736>>2]=0,f[(e=t+728|0)>>2]=0,f[e+4>>2]=0,f[(e=t+720|0)>>2]=0,f[e+4>>2]=0,f[(e=t+712|0)>>2]=0,f[e+4>>2]=0,f[(e=t+704|0)>>2]=0,f[e+4>>2]=0,f[(e=t+696|0)>>2]=0,f[e+4>>2]=0,f[t+772>>2]=0,f[t+776>>2]=0,f[t+800>>2]=0,f[t+780>>2]=0}function le(t){var e,i=0;(e=f[t+116>>2])&&((i=f[421])&&(yt[i](e),f[t+116>>2]=0))}function ue(t,e){var i=0,r=0,n=0,a=0;t:if(4!=(0|(i=f[t+780>>2])))f[t+780>>2]=i+1;else{if(i=function(t,e){var i,r=v(0),n=v(0),a=v(0),o=v(0),f=v(0),h=v(0),d=v(0),g=v(0),m=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=0,Q=v(0),W=v(0),Y=v(0),Z=v(0),z=v(0),yt=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=0,Vt=v(0),Gt=v(0),Lt=v(0),wt=v(0),xt=v(0),Qt=v(0);Ft=(w=(r=C[t+84>>2])<(o=C[e+80>>2]))?0:-1,i=(w=(g=C[t+276>>2])<(r=w?r:o))?1:Ft,w=(o=C[t+468>>2])<(r=w?g:r),w=(Ft=C[t+660>>2]<(w?o:r))?3:w?2:i,h=C[e>>2];e:{i:{A:{r:{if(_[2980]){if(!w){B=C[t+588>>2],E=C[t+396>>2],r=v(B-E),V=C[t+584>>2],F=C[t+392>>2],o=v(V-F),n=C[t+580>>2],Y=C[t+388>>2],g=v(n-Y),a=C[e+8>>2],d=C[e+4>>2];break r}if(f=C[t+196>>2],m=v(h-f),V=C[t+584>>2],F=C[t+392>>2],o=v(V-F),d=C[e+4>>2],G=C[t+200>>2],r=v(d-G),n=C[t+580>>2],Y=C[t+388>>2],g=v(n-Y),a=v(v(m*o)-v(r*g)),R=v(a*a),p=r,B=C[t+588>>2],E=C[t+396>>2],r=v(B-E),a=C[e+8>>2],Q=C[t+204>>2],Z=v(a-Q),z=v(v(p*r)-v(Z*o)),m=v(v(Z*g)-v(m*r)),Qt=v(R+v(v(z*z)+v(m*m))),1!=(0|w))break r;h=v(h-C[t+4>>2]),a=v(a-C[t+12>>2]),d=v(d-C[t+8>>2]),g=v(0);break A}Z=C[e+8>>2],z=C[e+4>>2];n:{a:{if(w){if(It=C[t+196>>2],V=v(h-It),E=C[t+392>>2],d=C[t+584>>2],yt=v(E-d),St=C[t+200>>2],B=v(z-St),F=C[t+388>>2],m=C[t+580>>2],pt=v(F-m),r=v(v(V*yt)-v(B*pt)),o=v(r*r),f=C[t+396>>2],a=C[t+588>>2],g=v(f-a),n=C[t+204>>2],Y=v(Z-n),r=v(v(B*g)-v(Y*yt)),p=v(r*r),r=v(v(Y*pt)-v(V*g)),o=v(o+v(p+v(r*r))),G=v(h-F),Dt=v(St-d),Q=v(z-E),Vt=v(It-m),r=v(v(G*Dt)-v(Q*Vt)),p=v(r*r),Gt=v(n-a),r=v(Z-f),R=v(v(Q*Gt)-v(r*Dt)),D=v(R*R),R=v(v(r*Vt)-v(G*Gt)),R=o>(R=v(p+v(D+v(R*R))))?o:R,o=v(St-E),Ot=v(h-m),D=v(It-F),Et=v(z-d),W=v(v(o*Ot)-v(D*Et)),Tt=v(W*W),W=v(n-f),p=o,o=v(Z-a),p=v(v(W*Et)-v(p*o)),D=v(v(D*o)-v(W*Ot)),Qt=R>(D=v(Tt+v(v(p*p)+v(D*D))))?R:D,1==(0|w)){R=C[t+4>>2],Lt=v(R-m),p=v(h-R),D=C[t+12>>2],wt=v(D-a),W=C[t+8>>2],xt=v(W-d),Tt=v(Z-D),Nt=v(z-W),g=v(0);break a}}else f=C[t+396>>2],a=C[t+588>>2],g=v(f-a),E=C[t+392>>2],d=C[t+584>>2],yt=v(E-d),F=C[t+388>>2],m=C[t+580>>2],pt=v(F-m),o=v(Z-a),Et=v(z-d),Ot=v(h-m),r=v(Z-f),Q=v(z-E),G=v(h-F);if(R=C[t+4>>2],p=v(h-R),W=C[t+8>>2],Nt=v(z-W),n=v(v(p*yt)-v(Nt*pt)),B=v(n*n),D=C[t+12>>2],Tt=v(Z-D),n=v(v(Nt*g)-v(Tt*yt)),g=v(v(Tt*pt)-v(p*g)),g=v(B+v(v(n*n)+v(g*g))),xt=v(W-d),Lt=v(R-m),n=v(v(G*xt)-v(Q*Lt)),B=v(n*n),wt=v(D-a),n=v(v(Q*wt)-v(r*xt)),V=v(n*n),n=v(v(r*Lt)-v(G*wt)),g=g>(n=v(B+v(V+v(n*n))))?g:n,yt=v(W-E),pt=v(R-F),n=v(v(yt*Ot)-v(pt*Et)),B=v(n*n),Dt=v(D-f),n=v(v(Dt*Et)-v(yt*o)),V=v(n*n),n=v(v(pt*o)-v(Dt*Ot)),g=g>(n=v(B+v(V+v(n*n))))?g:n,n=C[t+204>>2],Y=v(Z-n),St=C[t+200>>2],B=v(z-St),It=C[t+196>>2],V=v(h-It),2==(0|w)){a=v(D-n),d=v(W-St),m=v(R-It),o=v(0);break n}Gt=v(n-a),Dt=v(St-d),Vt=v(It-m)}if(r=v(v(p*Dt)-v(Nt*Vt)),d=v(r*r),r=v(v(Nt*Gt)-v(Tt*Dt)),a=v(r*r),r=v(v(Tt*Vt)-v(p*Gt)),r=v(d+v(a+v(r*r))),a=v(v(V*xt)-v(B*Lt)),d=v(a*a),a=v(v(B*wt)-v(Y*xt)),m=v(a*a),a=v(v(Y*Lt)-v(V*wt)),r=r>(a=v(d+v(m+v(a*a))))?r:a,d=v(W-St),m=v(R-It),a=v(v(d*Ot)-v(m*Et)),Q=v(a*a),a=v(D-n),G=v(v(a*Et)-v(d*o)),o=v(v(m*o)-v(a*Ot)),o=r>(o=v(Q+v(v(G*G)+v(o*o))))?r:o,r=v(0),Ft)break e;Dt=v(D-f),yt=v(W-E),pt=v(R-F),r=v(Z-f),Q=v(z-E),G=v(h-F)}h=v(St-E),E=v(It-F),F=v(v(p*h)-v(Nt*E)),f=v(n-f),h=v(v(Nt*f)-v(Tt*h)),n=v(h*h),h=v(v(Tt*E)-v(p*f)),h=v(v(F*F)+v(n+v(h*h))),f=v(v(V*yt)-v(B*pt)),p=v(f*f),f=v(v(B*Dt)-v(Y*yt)),n=v(f*f),f=v(v(Y*pt)-v(V*Dt)),h=h>(f=v(p+v(n+v(f*f))))?h:f,f=v(v(d*G)-v(m*Q)),p=v(f*f),f=v(v(a*Q)-v(d*r)),r=v(v(m*r)-v(a*G)),r=h>(r=v(p+v(v(f*f)+v(r*r))))?h:r;break e}if(h=v(h-C[t+4>>2]),d=v(d-C[t+8>>2]),f=v(v(h*o)-v(d*g)),a=v(a-C[t+12>>2]),o=v(v(d*r)-v(a*o)),r=v(v(a*g)-v(h*r)),g=v(v(f*f)+v(v(o*o)+v(r*r))),Q=C[t+204>>2],G=C[t+200>>2],f=C[t+196>>2],o=v(0),2==(0|w))break i}if(r=v(V-G),o=v(n-f),m=v(v(h*r)-v(d*o)),p=v(m*m),m=v(B-Q),r=v(v(d*m)-v(a*r)),n=v(r*r),r=v(v(a*o)-v(h*m)),o=v(p+v(n+v(r*r))),r=v(0),Ft)break e}r=v(F-G),f=v(Y-f),m=v(v(h*r)-v(d*f)),p=d,d=v(E-Q),r=v(v(p*d)-v(a*r)),p=v(r*r),r=v(v(a*f)-v(h*d)),r=v(v(m*m)+v(p+v(r*r)))}return e=(t=(h=v(y(Qt)))>v(-0xde0b6b000000000))?0:-1,e=(t=(g=v(y(g)))>(h=t?h:v(-0xde0b6b000000000)))?1:e,t=(o=v(y(o)))>(g=t?g:h),v(y(r))>(t?o:g)?3:t?2:e}(t,e),r=120+(m(i,192)+t|0)|0,!(n=f[r>>2]))break t;if(!(a=f[421]))break t;yt[a](n),f[r>>2]=0}return J(4+(t+m(i=(0|i)>0?i:0,192)|0)|0,e,192),i}function se(t,e,i){var r,n=0,a=v(0),o=0,_=v(0),h=v(0),d=0,g=0,y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0);if(Z=r=Z-16|0,!((0|(g=f[t+780>>2]))<1)){for(n=(m(g,192)+t|0)-188|0,o=g;D=C[e+48>>2],F=C[e+8>>2],V=C[e+4>>2],G=C[e>>2],B=C[e+52>>2],w=C[e+24>>2],y=C[e+20>>2],Q=C[e+16>>2],a=C[e+56>>2],_=C[e+40>>2],h=C[e+36>>2],E=C[e+32>>2],f[n+60>>2]=0,R=a,a=C[n>>2],W=h,h=C[n+4>>2],p=_,_=C[n+8>>2],E=v(R+v(v(v(E*a)+v(W*h))+v(p*_))),C[n+56>>2]=E,B=v(B+v(v(v(a*Q)+v(h*y))+v(_*w))),C[n+52>>2]=B,D=v(D+v(v(v(a*G)+v(h*V))+v(_*F))),C[n+48>>2]=D,F=C[i+56>>2],V=C[i+40>>2],G=C[i+32>>2],w=C[i+36>>2],y=C[i+52>>2],Q=C[i+24>>2],Y=C[i+16>>2],z=C[i+20>>2],a=C[i+48>>2],_=C[i+8>>2],h=C[i>>2],p=C[i+4>>2],f[n+44>>2]=0,R=a,a=C[n+16>>2],pt=v(h*a),h=C[n+20>>2],W=_,_=C[n+24>>2],p=v(R+v(v(pt+v(p*h))+v(W*_))),C[n+32>>2]=p,y=v(y+v(v(v(a*Y)+v(h*z))+v(_*Q))),C[n+36>>2]=y,a=v(F+v(v(v(a*G)+v(h*w))+v(_*V))),C[n+40>>2]=a,C[n+80>>2]=v(v(v(D-p)*C[n- -64>>2])+v(v(B-y)*C[n+68>>2]))+v(v(E-a)*C[n+72>>2]),f[(d=n+156|0)>>2]=f[d>>2]+1,n=n+-192|0,(0|(o=o+-1|0))>0;);if(!((0|g)<1))for(e=m(g,192);;){g=g+-1|0,o=(i=t+e|0)+-188|0;t:if((a=C[i+-108>>2])<=(h=C[t+784>>2]))if(_=v(C[i+-156>>2]-v(C[i+-140>>2]-v(C[i+-124>>2]*a))),R=v(_*_),_=v(C[i+-152>>2]-v(C[i+-136>>2]-v(a*C[i+-120>>2]))),a=v(C[i+-148>>2]-v(C[i+-132>>2]-v(a*C[i+-116>>2]))),v(v(R+v(_*_))+v(a*a))>v(h*h)){if((n=f[(i=i+-72|0)>>2])&&((d=f[421])&&(yt[d](n),f[i>>2]=0)),d=t,(0|g)!=(0|(i=(n=f[t+780>>2])+-1|0))&&(J(o,(i=m(i,192)+t|0)+4|0,192),f[(o=i+120|0)>>2]=0,f[o+4>>2]=0,f[i+160>>2]=0,f[(o=i+128|0)>>2]=0,f[o+4>>2]=0,f[i+136>>2]=0,n=f[t+780>>2]),i=n+-1|0,f[d+780>>2]=i,i)break t;if(!(i=f[424]))break t;f[r+8>>2]=t,yt[i](r+8|0)}else i=f[422],i&&yt[i](o,f[t+772>>2],f[t+776>>2]);else{if((n=f[(i=i+-72|0)>>2])&&((d=f[421])&&(yt[d](n),f[i>>2]=0)),d=t,(0|g)!=(0|(i=(n=f[t+780>>2])+-1|0))&&(J(o,(i=m(i,192)+t|0)+4|0,192),f[(o=i+120|0)>>2]=0,f[o+4>>2]=0,f[i+160>>2]=0,f[(o=i+128|0)>>2]=0,f[o+4>>2]=0,f[i+136>>2]=0,n=f[t+780>>2]),i=n+-1|0,f[d+780>>2]=i,i)break t;if(!(i=f[424]))break t;f[r+12>>2]=t,yt[i](r+12|0)}if(e=e+-192|0,!((0|g)>0))break}}Z=r+16|0}function ke(t,e){return v(C[t+232>>2]*C[e+232>>2])}function ve(t){$(t|=0)}function de(t,e,i){f[76+((m(e,144)+t|0)+(i<<2)|0)>>2]=1708}function Ce(t){return f[(t|=0)+72>>2]}function ge(t,e,i){var r=0,n=0;(r=f[t+12>>2])||(r=f[t+4>>2],r=0|yt[f[f[r>>2]+12>>2]](r,f[e+8>>2],f[i+8>>2]),f[t+12>>2]=r),f[f[t+16>>2]+4>>2]=r,n=f[t+4>>2],r=0|yt[f[f[n>>2]+8>>2]](n,e,i,r,1),n=f[t+16>>2],yt[f[f[n>>2]+8>>2]](n,f[t+28>>2],f[t+24>>2]),n=f[t+16>>2],yt[f[f[n>>2]+12>>2]](n,f[t+36>>2],f[t+32>>2]),yt[f[f[r>>2]+8>>2]](r,e,i,f[t+20>>2],f[t+16>>2]),yt[f[f[r>>2]>>2]](r),t=f[t+4>>2],yt[f[f[t>>2]+60>>2]](t,r)}function Be(t,e,i,r,n){var a,o=0;Z=a=Z-48|0,o=f[t+16>>2],yt[f[f[o>>2]+8>>2]](o,f[t+28>>2],f[t+24>>2]),o=f[t+16>>2],yt[f[f[o>>2]+12>>2]](o,f[t+36>>2],f[t+32>>2]),f[a+28>>2]=r,f[a+44>>2]=f[t+24>>2],f[a+40>>2]=f[t+28>>2],f[a+24>>2]=e,f[a+36>>2]=f[e+12>>2],e=f[e+8>>2],f[a+32>>2]=e,f[a+4>>2]=n,f[a+20>>2]=f[t+32>>2],f[a+16>>2]=f[t+36>>2],f[a>>2]=i,f[a+12>>2]=f[i+12>>2],r=f[i+8>>2],f[a+8>>2]=r,(i=f[t+8>>2])||((i=f[t+12>>2])||(i=f[t+4>>2],i=0|yt[f[f[i>>2]+12>>2]](i,e,r),f[t+12>>2]=i),f[f[t+16>>2]+4>>2]=i,e=f[t+4>>2],i=0|yt[f[f[e>>2]+8>>2]](e,a+24|0,a,i,1),f[t+8>>2]=i),yt[f[f[i>>2]+8>>2]](i,a+24|0,a,f[t+20>>2],f[t+16>>2]),Z=a+48|0}function _e(t,e,i,r,a){var o,h=0,d=0,g=0,m=0,y=0,p=0,R=0,D=0,B=0,F=0,V=0,G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=0,Tt=0,Et=0,Ot=0,Nt=v(0),Ft=v(0),Vt=v(0),Gt=v(0),Lt=v(0),wt=v(0),xt=v(0),Qt=v(0),Wt=v(0),Yt=v(0),Pt=v(0),Mt=v(0),Zt=0,Ut=0,Xt=v(0),Jt=v(0),jt=v(0),zt=0,Ht=0,Kt=0,qt=0,$t=0,bi=0,di=0;Z=o=Z-976|0;t:if(2!=(0|yt[f[f[r>>2]+80>>2]](r)))if(2!=(0|yt[f[f[a>>2]+80>>2]](a))){if(h=f[e+12>>2],D=f[(d=h+8|0)>>2],d=f[d+4>>2],Tt=f[h>>2],Et=f[h+4>>2],R=f[(p=h+24|0)+4>>2],f[(g=o+936|0)>>2]=f[p>>2],f[g+4>>2]=R,f[(g=o+920|0)>>2]=D,f[g+4>>2]=d,d=f[h+16>>2],D=f[h+20>>2],R=f[(p=h+40|0)+4>>2],f[(g=o+952|0)>>2]=f[p>>2],f[g+4>>2]=R,g=f[h+32>>2],p=f[h+36>>2],V=f[(F=h+56|0)+4>>2],f[(R=o+968|0)>>2]=f[F>>2],f[R+4>>2]=V,f[o+912>>2]=Tt,f[o+916>>2]=Et,f[o+928>>2]=d,f[o+932>>2]=D,f[o+944>>2]=g,f[o+948>>2]=p,d=f[h+52>>2],f[o+960>>2]=f[h+48>>2],f[o+964>>2]=d,h=f[i+12>>2],D=f[(d=h+8|0)>>2],d=f[d+4>>2],Tt=f[h>>2],Et=f[h+4>>2],R=f[(p=h+24|0)+4>>2],f[(g=o+872|0)>>2]=f[p>>2],f[g+4>>2]=R,f[(g=o+856|0)>>2]=D,f[g+4>>2]=d,d=f[h+16>>2],D=f[h+20>>2],R=f[(p=h+40|0)+4>>2],f[(g=o+888|0)>>2]=f[p>>2],f[g+4>>2]=R,g=f[h+32>>2],p=f[h+36>>2],V=f[(F=h+56|0)+4>>2],f[(R=o+904|0)>>2]=f[F>>2],f[R+4>>2]=V,f[o+848>>2]=Tt,f[o+852>>2]=Et,f[o+864>>2]=d,f[o+868>>2]=D,f[o+880>>2]=g,f[o+884>>2]=p,d=f[h+52>>2],f[o+896>>2]=f[h+48>>2],f[o+900>>2]=d,f[o+828>>2]=0,bi=o,di=dA(256),f[bi+836>>2]=di,n[o+840|0]=1,f[o+832>>2]=32,function(t,e,i,r,a){var o,h=0,d=0,g=0,m=0,v=0,y=0,p=0,R=0,D=0,B=0,E=0,F=0;if(Z=o=Z+-64|0,!f[i+72>>2]|!f[r+72>>2]){if(d=0|yt[f[f[i>>2]+88>>2]](i))for(B=o+16|0,E=o+48|0;;){if(d=d+-1|0,yt[f[f[i>>2]+120>>2]](i,d,t,o+32|0,E),g=0|yt[f[f[r>>2]+88>>2]](r))for(;;){if(yt[f[f[r>>2]+120>>2]](r,d,e,o,B),g=g+-1|0,!(C[o+16>>2]>2]|C[o>>2]>C[o+48>>2]|C[o+20>>2]>2]|C[o+4>>2]>C[o+52>>2]|C[o+24>>2]>2]|C[o+8>>2]>C[o+56>>2])){if((0|(h=f[a+4>>2]))==f[a+8>>2]&&!((0|h)>=(0|(m=h?h<<1:1)))){m?(p=dA(m<<3),h=f[a+4>>2]):p=0,R=f[a+12>>2];e:{if((0|h)>=1)for(v=R,y=p,D=h;F=f[v+4>>2],f[y>>2]=f[v>>2],f[y+4>>2]=F,v=v+8|0,y=y+8|0,D=D+-1|0;);else if(!R)break e;_[a+16|0]&&(CA(R),h=f[a+4>>2]),f[a+12>>2]=0}f[a+12>>2]=p,n[a+16|0]=1,f[a+8>>2]=m}f[a+4>>2]=h+1,h=f[a+12>>2]+(h<<3)|0,f[h+4>>2]=g,f[h>>2]=d}if(!g)break}if(!d)break}}else mA(i+72|0,t,r+72|0,e,a);Z=o- -64|0}(o+912|0,o+848|0,r,a,o+824|0),f[o+828>>2])if(1!=(0|yt[f[f[r>>2]+80>>2]](r))||1!=(0|yt[f[f[a>>2]+80>>2]](a))){if(yt[f[f[r>>2]+112>>2]](r),yt[f[f[a>>2]+112>>2]](a),zA(o+520|4),f[(h=o+584|0)>>2]=0,f[h+4>>2]=0,f[o+528>>2]=1,f[(h=o+592|0)>>2]=0,f[h+4>>2]=0,f[(h=o+600|0)>>2]=0,f[h+4>>2]=0,f[(h=o+608|0)>>2]=0,f[h+4>>2]=0,f[(h=o+616|0)>>2]=0,f[h+4>>2]=0,f[(h=o+624|0)>>2]=0,f[h+4>>2]=0,f[o+524>>2]=8128,te(o+632|0),f[o+728>>2]=4,f[o+812>>2]=8708,f[o+804>>2]=8628,f[o+796>>2]=8556,f[o+632>>2]=8364,f[o+520>>2]=r,h=o+804|0,yt[f[f[r>>2]+96>>2]](r)||(h=f[o+520>>2],h=0|yt[f[f[h>>2]+100>>2]](h)?o+812|0:o+796|0),f[h+4>>2]=o+520,f[o+820>>2]=h,zA(o+216|4),f[(h=o+280|0)>>2]=0,f[h+4>>2]=0,f[o+224>>2]=1,f[(h=o+288|0)>>2]=0,f[h+4>>2]=0,f[(h=o+296|0)>>2]=0,f[h+4>>2]=0,f[(h=o+304|0)>>2]=0,f[h+4>>2]=0,f[(h=o+312|0)>>2]=0,f[h+4>>2]=0,f[(h=o+320|0)>>2]=0,f[h+4>>2]=0,f[o+220>>2]=8128,te(o+328|0),f[o+424>>2]=4,f[o+508>>2]=8708,f[o+500>>2]=8628,f[o+492>>2]=8556,f[o+328>>2]=8364,f[o+216>>2]=a,h=o+500|0,yt[f[f[a>>2]+96>>2]](a)||(h=f[o+216>>2],h=0|yt[f[f[h>>2]+100>>2]](h)?o+508|0:o+492|0),f[h+4>>2]=o+216,f[o+516>>2]=h,Kt=0|yt[f[f[r>>2]+92>>2]](r),qt=0|yt[f[f[a>>2]+92>>2]](a),d=f[o+828>>2])for(D=(d<<3)-4|0,Tt=o+136|0,Et=o+120|0,g=o+104|0,p=o+200|0,R=o+184|0,F=o+168|0;h=f[o+836>>2]+D|0,f[t+32>>2]=f[h>>2],h=f[h+-4>>2],f[t+24>>2]=h,V=f[o+820>>2],V=0|yt[f[f[V>>2]>>2]](V,h),h=f[o+516>>2],zt=0|yt[f[f[h>>2]>>2]](h,f[t+32>>2]),h=f[e+12>>2],B=f[(y=h+8|0)>>2],y=f[y+4>>2],Zt=f[h>>2],Ut=f[h+4>>2],St=f[(Ot=h+24|0)+4>>2],f[(m=F+8|0)>>2]=f[Ot>>2],f[m+4>>2]=St,f[(m=o+160|0)>>2]=B,f[m+4>>2]=y,y=f[h+16>>2],B=f[h+20>>2],m=f[h+36>>2],f[R>>2]=f[h+32>>2],f[R+4>>2]=m,Ot=f[(m=h+40|0)>>2],m=f[m+4>>2],$t=f[(Ht=h+56|0)+4>>2],f[(St=p+8|0)>>2]=f[Ht>>2],f[St+4>>2]=$t,St=f[h+52>>2],f[p>>2]=f[h+48>>2],f[p+4>>2]=St,f[(h=R+8|0)>>2]=Ot,f[h+4>>2]=m,f[F>>2]=y,f[F+4>>2]=B,f[o+152>>2]=Zt,f[o+156>>2]=Ut,h=f[i+12>>2],B=f[(y=h+8|0)>>2],y=f[y+4>>2],Zt=f[h>>2],Ut=f[h+4>>2],St=f[(Ot=h+24|0)+4>>2],f[(m=g+8|0)>>2]=f[Ot>>2],f[m+4>>2]=St,m=f[h+20>>2],f[g>>2]=f[h+16>>2],f[g+4>>2]=m,f[(m=o+96|0)>>2]=B,f[m+4>>2]=y,m=f[(B=h+40|0)+4>>2],f[(y=Et+8|0)>>2]=f[B>>2],f[y+4>>2]=m,y=f[h+36>>2],f[Et>>2]=f[h+32>>2],f[Et+4>>2]=y,m=f[(B=h+56|0)+4>>2],f[(y=Tt+8|0)>>2]=f[B>>2],f[y+4>>2]=m,y=f[h+52>>2],f[Tt>>2]=f[h+48>>2],f[Tt+4>>2]=y,f[o+88>>2]=Zt,f[o+92>>2]=Ut,Kt&&(yt[f[f[r>>2]+132>>2]](o+24|0,r,f[t+24>>2]),Xt=C[o+960>>2],Jt=C[o+964>>2],jt=C[o+968>>2],Nt=C[o+80>>2],Ft=C[o+72>>2],Vt=C[o+76>>2],G=C[o+920>>2],w=C[o+912>>2],Q=C[o+916>>2],W=C[o+936>>2],Y=C[o+928>>2],z=C[o+932>>2],Gt=C[o+56>>2],Lt=C[o+24>>2],wt=C[o+40>>2],xt=C[o+60>>2],Qt=C[o+28>>2],Wt=C[o+44>>2],pt=C[o+952>>2],Yt=C[o+64>>2],Dt=C[o+944>>2],Pt=C[o+32>>2],It=C[o+948>>2],Mt=C[o+48>>2],f[o+212>>2]=0,f[o+196>>2]=0,f[o+180>>2]=0,f[o+164>>2]=0,C[o+192>>2]=v(v(Pt*Dt)+v(Mt*It))+v(Yt*pt),C[o+188>>2]=v(v(Qt*Dt)+v(Wt*It))+v(xt*pt),C[o+184>>2]=v(v(Lt*Dt)+v(wt*It))+v(Gt*pt),C[o+176>>2]=v(v(Pt*Y)+v(Mt*z))+v(Yt*W),C[o+172>>2]=v(v(Qt*Y)+v(Wt*z))+v(xt*W),C[o+168>>2]=v(v(Lt*Y)+v(wt*z))+v(Gt*W),C[o+160>>2]=v(v(w*Pt)+v(Q*Mt))+v(G*Yt),C[o+156>>2]=v(v(w*Qt)+v(Q*Wt))+v(G*xt),C[o+152>>2]=v(v(Lt*w)+v(wt*Q))+v(Gt*G),C[o+208>>2]=jt+v(v(v(Dt*Ft)+v(It*Vt))+v(pt*Nt)),C[o+204>>2]=Jt+v(v(v(Y*Ft)+v(z*Vt))+v(W*Nt)),C[o+200>>2]=Xt+v(v(v(w*Ft)+v(Q*Vt))+v(G*Nt))),d=d+-1|0,qt&&(yt[f[f[a>>2]+132>>2]](o+24|0,a,f[t+32>>2]),Xt=C[o+896>>2],Jt=C[o+900>>2],jt=C[o+904>>2],Nt=C[o+80>>2],Ft=C[o+72>>2],Vt=C[o+76>>2],G=C[o+856>>2],w=C[o+848>>2],Q=C[o+852>>2],W=C[o+872>>2],Y=C[o+864>>2],z=C[o+868>>2],Gt=C[o+56>>2],Lt=C[o+24>>2],wt=C[o+40>>2],xt=C[o+60>>2],Qt=C[o+28>>2],Wt=C[o+44>>2],pt=C[o+888>>2],Yt=C[o+64>>2],Dt=C[o+880>>2],Pt=C[o+32>>2],It=C[o+884>>2],Mt=C[o+48>>2],f[o+148>>2]=0,f[o+132>>2]=0,f[o+116>>2]=0,f[o+100>>2]=0,C[o+128>>2]=v(v(Pt*Dt)+v(Mt*It))+v(Yt*pt),C[o+124>>2]=v(v(Qt*Dt)+v(Wt*It))+v(xt*pt),C[o+120>>2]=v(v(Lt*Dt)+v(wt*It))+v(Gt*pt),C[o+112>>2]=v(v(Pt*Y)+v(Mt*z))+v(Yt*W),C[o+108>>2]=v(v(Qt*Y)+v(Wt*z))+v(xt*W),C[o+104>>2]=v(v(Lt*Y)+v(wt*z))+v(Gt*W),C[o+96>>2]=v(v(w*Pt)+v(Q*Mt))+v(G*Yt),C[o+92>>2]=v(v(w*Qt)+v(Q*Wt))+v(G*xt),C[o+88>>2]=v(v(Lt*w)+v(wt*Q))+v(Gt*G),C[o+144>>2]=jt+v(v(v(Dt*Ft)+v(It*Vt))+v(pt*Nt)),C[o+140>>2]=Jt+v(v(v(Y*Ft)+v(z*Vt))+v(W*Nt)),C[o+136>>2]=Xt+v(v(v(w*Ft)+v(Q*Vt))+v(G*Nt))),f[o+28>>2]=V,f[o+44>>2]=f[t+24>>2],f[o+40>>2]=f[t+28>>2],f[o+24>>2]=e,f[o+32>>2]=f[e+8>>2],f[o+36>>2]=o+152,f[o+4>>2]=zt,f[o+20>>2]=f[t+32>>2],f[o+16>>2]=f[t+36>>2],f[o>>2]=i,f[o+8>>2]=f[i+8>>2],f[o+12>>2]=o+88,Be(t,o+24|0,o,V,zt),D=D+-8|0,d;);yt[f[f[r>>2]+116>>2]](r),yt[f[f[a>>2]+116>>2]](a),Ae(o+328|0),Ae(o+216|4),Ae(o+632|0),Ae(o+520|4)}else!function(t,e,i,r,n,a,o){var _,h=v(0),d=0,g=v(0),m=0,y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=0,Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0),Gt=v(0),Lt=v(0),wt=v(0),xt=v(0),Qt=v(0),Wt=v(0),Yt=v(0),Pt=v(0),Mt=v(0),Zt=v(0),Ut=v(0),Xt=v(0),Jt=v(0),jt=v(0),zt=v(0),Ht=v(0),Kt=v(0),qt=v(0),$t=v(0),bi=0,di=0,yi=v(0);if(Z=_=Z-432|0,m=f[i+12>>2],Et=C[m+56>>2],Ot=C[m+52>>2],Nt=C[m+40>>2],Ft=C[m+36>>2],Vt=C[m+24>>2],Gt=C[m+20>>2],d=f[e+12>>2],Lt=C[d+56>>2],wt=C[d+52>>2],xt=C[d+40>>2],Qt=C[d+36>>2],Wt=C[d+24>>2],Yt=C[d+20>>2],Pt=C[m+48>>2],Mt=C[m+32>>2],Zt=C[m+16>>2],Ut=C[m+8>>2],Xt=C[m+4>>2],Jt=C[m>>2],jt=C[d+48>>2],zt=C[d+32>>2],Ht=C[d+16>>2],Kt=C[d+8>>2],qt=C[d+4>>2],$t=C[d>>2],f[_+424>>2]=1008981770,f[_+352>>2]=1008981770,yt[f[f[r>>2]+112>>2]](r),yt[f[f[n>>2]+112>>2]](n),o)for(di=_+16|0;;){if(m=f[a>>2],f[t+24>>2]=m,f[t+32>>2]=f[a+4>>2],d=0|yt[f[f[r>>2]+84>>2]](r),yt[f[f[d>>2]+20>>2]](d,m,_+360|0),m=f[t+32>>2],d=0|yt[f[f[n>>2]+84>>2]](n),yt[f[f[d>>2]+20>>2]](d,m,_+288|0),f[_+372>>2]=0,f[_+388>>2]=0,f[_+404>>2]=0,V=C[_+376>>2],G=C[_+380>>2],h=C[_+384>>2],yi=v(wt+v(v(v(Ht*V)+v(Yt*G))+v(Wt*h))),C[_+380>>2]=yi,w=C[_+360>>2],Q=C[_+364>>2],R=C[_+368>>2],Y=v(wt+v(v(v(Ht*w)+v(Yt*Q))+v(Wt*R))),C[_+364>>2]=Y,y=C[_+392>>2],p=C[_+396>>2],g=C[_+400>>2],z=v(wt+v(v(v(Ht*y)+v(Yt*p))+v(Wt*g))),C[_+396>>2]=z,D=v(Lt+v(v(v(zt*V)+v(Qt*G))+v(xt*h))),C[_+384>>2]=D,B=v(jt+v(v(v($t*y)+v(qt*p))+v(Kt*g))),C[_+392>>2]=B,pt=v(jt+v(v(v($t*w)+v(qt*Q))+v(Kt*R))),C[_+360>>2]=pt,h=v(jt+v(v(v($t*V)+v(qt*G))+v(Kt*h))),C[_+376>>2]=h,Dt=v(Lt+v(v(v(zt*w)+v(Qt*Q))+v(xt*R))),C[_+368>>2]=Dt,g=v(Lt+v(v(v(zt*y)+v(Qt*p))+v(xt*g))),C[_+400>>2]=g,R=C[_+296>>2],y=C[_+288>>2],p=C[_+292>>2],f[_+300>>2]=0,It=v(Ot+v(v(v(Zt*y)+v(Gt*p))+v(Vt*R))),C[_+292>>2]=It,St=v(Et+v(v(v(Mt*y)+v(Ft*p))+v(Nt*R))),C[_+296>>2]=St,Tt=v(Pt+v(v(v(Jt*y)+v(Xt*p))+v(Ut*R))),C[_+288>>2]=Tt,R=C[_+312>>2],y=C[_+304>>2],p=C[_+308>>2],f[_+316>>2]=0,V=v(Ot+v(v(v(Zt*y)+v(Gt*p))+v(Vt*R))),C[_+308>>2]=V,G=v(Et+v(v(v(Mt*y)+v(Ft*p))+v(Nt*R))),C[_+312>>2]=G,w=v(Pt+v(v(v(Jt*y)+v(Xt*p))+v(Ut*R))),C[_+304>>2]=w,F=C[_+328>>2],y=C[_+320>>2],p=C[_+324>>2],f[_+332>>2]=0,Q=v(Ot+v(v(v(Zt*y)+v(Gt*p))+v(Vt*F))),C[_+324>>2]=Q,R=v(Pt+v(v(v(Jt*y)+v(Xt*p))+v(Ut*F))),C[_+320>>2]=R,y=v(Et+v(v(v(Mt*y)+v(Ft*p))+v(Nt*F))),C[_+328>>2]=y,p=v(D-Dt),D=v(B-pt),h=v(h-pt),B=v(g-Dt),F=v(v(p*D)-v(h*B)),g=v(z-Y),z=v(h*g),h=v(yi-Y),D=v(z-v(h*D)),g=v(v(h*B)-v(p*g)),h=v(v(1)/v(E(v(v(D*D)+v(v(g*g)+v(F*F)))))),B=v(F*h),C[_+412>>2]=B,g=v(g*h),C[_+408>>2]=g,h=v(D*h),C[_+416>>2]=h,C[_+420>>2]=v(Dt*h)+v(v(pt*g)+v(Y*B)),p=v(G-St),D=v(R-Tt),h=v(w-Tt),B=v(y-St),y=v(v(p*D)-v(h*B)),g=v(Q-It),R=v(h*g),h=v(V-It),D=v(R-v(h*D)),g=v(v(h*B)-v(p*g)),h=v(v(1)/v(E(v(v(D*D)+v(v(g*g)+v(y*y)))))),B=v(y*h),C[_+340>>2]=B,g=v(g*h),C[_+336>>2]=g,h=v(D*h),C[_+344>>2]=h,C[_+348>>2]=v(St*h)+v(v(Tt*g)+v(It*B)),o=o+-1|0,ee(_+360|0,_+288|0)&&fe(_+360|0,_+288|0,_+8|0)&&(W=f[_+12>>2]))for(bi=(W<<4)+di|0;h=C[_+8>>2],d=f[t+16>>2],yt[f[f[d>>2]+8>>2]](d,f[t+28>>2],f[t+24>>2]),d=f[t+16>>2],yt[f[f[d>>2]+12>>2]](d,f[t+36>>2],f[t+32>>2]),W=W+-1|0,h=v(-h),(m=f[t+12>>2])||(d=f[t+4>>2],m=0|yt[f[f[d>>2]+12>>2]](d,f[e+8>>2],f[i+8>>2]),f[t+12>>2]=m),d=f[t+16>>2],f[d+4>>2]=m,yt[f[f[d>>2]+16>>2]](d,di,bi,h),bi=bi+-16|0,W;);if(a=a+8|0,!o)break}yt[f[f[r>>2]+116>>2]](r),yt[f[f[n>>2]+116>>2]](n),Z=_+432|0}(t,e,i,r,a,f[o+836>>2],f[o+828>>2]);(t=f[o+836>>2])&&(_[o+840|0]&&CA(t),f[o+836>>2]=0)}else{if(h=(d=f[a+156>>2])+-1|0,f[t+36>>2]=h,!d)break t;for(;_e(t,e,i,r,f[f[a+164>>2]+(h<<2)>>2]),h=(d=f[t+36>>2])+-1|0,f[t+36>>2]=h,d;);}else{if(h=(d=f[r+156>>2])+-1|0,f[t+28>>2]=h,!d)break t;for(;_e(t,e,i,f[f[r+164>>2]+(h<<2)>>2],a),h=(d=f[t+28>>2])+-1|0,f[t+28>>2]=h,d;);}Z=o+976|0}function me(t,e,i,r,a,o){var h,d=0,p=0,R=0,D=0,B=0,E=0,F=0,V=0,G=0,w=0;Z=h=Z-528|0;t:if(2!=(0|yt[f[f[r>>2]+80>>2]](r)))if(p=1!=(0|yt[f[f[r>>2]+80>>2]](r)),d=f[a+4>>2],p|28!=(0|d))if(31!=(0|d))if(d+-21>>>0<=8)!function(t,e,i,r,a,o){var _,h,d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0);Z=_=Z-128|0,n[_+116|0]=o,f[_+112>>2]=r,f[_+100>>2]=t,f[_+96>>2]=8784,f[_+104>>2]=e,f[_+108>>2]=i,h=_,Nt=v(yt[f[f[a>>2]+48>>2]](a)),C[h+120>>2]=Nt,t=f[i+12>>2],V=C[t+52>>2],G=C[t+56>>2],e=f[e+12>>2],w=C[e+52>>2],Q=C[e+56>>2],d=C[t+20>>2],g=C[t+36>>2],W=C[e+20>>2],Y=C[e+36>>2],z=C[e+24>>2],m=C[t+24>>2],pt=C[e+40>>2],y=C[t+40>>2],Dt=C[e+32>>2],p=C[t+32>>2],It=C[e>>2],R=C[t>>2],St=C[e+16>>2],D=C[t+16>>2],B=C[t+48>>2],Tt=C[e+48>>2],E=C[t+4>>2],Et=C[e+4>>2],Ot=C[e+8>>2],F=C[t+8>>2],f[_+92>>2]=0,f[_+76>>2]=0,f[_+60>>2]=0,C[_+72>>2]=v(v(F*Ot)+v(m*z))+v(y*pt),C[_+68>>2]=v(v(F*Et)+v(m*W))+v(y*Y),C[_+56>>2]=v(v(E*Ot)+v(d*z))+v(g*pt),C[_+52>>2]=v(v(E*Et)+v(d*W))+v(g*Y),B=v(-B),C[_+88>>2]=v(v(v(F*B)-v(m*V))-v(y*G))+v(v(v(F*Tt)+v(m*w))+v(y*Q)),C[_+84>>2]=v(v(v(E*B)-v(d*V))-v(g*G))+v(v(v(E*Tt)+v(d*w))+v(g*Q)),f[_+44>>2]=0,C[_+32>>2]=v(v(R*It)+v(D*St))+v(p*Dt),C[_+64>>2]=v(v(F*It)+v(m*St))+v(y*Dt),C[_+48>>2]=v(v(E*It)+v(d*St))+v(g*Dt),C[_+40>>2]=v(v(R*Ot)+v(D*z))+v(p*pt),C[_+36>>2]=v(v(R*Et)+v(D*W))+v(p*Y),C[_+80>>2]=v(v(v(R*B)-v(D*V))-v(p*G))+v(v(v(R*Tt)+v(D*w))+v(p*Q)),yt[f[f[r>>2]+8>>2]](r,_+32|0,_+16|0,_),yt[f[f[a>>2]+64>>2]](a,_+96|0,_+16|0,_),Z=_+128|0}(t,e,i,r,a,o);else{if(d=f[e+12>>2],p=f[(R=d+8|0)>>2],R=f[R+4>>2],F=f[d>>2],G=f[d+4>>2],E=f[(B=d+24|0)+4>>2],f[(D=h+488|0)>>2]=f[B>>2],f[D+4>>2]=E,f[(D=h+472|0)>>2]=p,f[D+4>>2]=R,R=f[d+16>>2],p=f[d+20>>2],E=f[(B=d+40|0)+4>>2],f[(D=h+504|0)>>2]=f[B>>2],f[D+4>>2]=E,D=f[d+32>>2],B=f[d+36>>2],w=f[(V=d+56|0)+4>>2],f[(E=h+520|0)>>2]=f[V>>2],f[E+4>>2]=w,f[h+464>>2]=F,f[h+468>>2]=G,f[h+480>>2]=R,f[h+484>>2]=p,f[h+496>>2]=D,f[h+500>>2]=B,R=f[d+52>>2],f[h+512>>2]=f[d+48>>2],f[h+516>>2]=R,d=f[i+12>>2],p=f[(R=d+8|0)>>2],R=f[R+4>>2],F=f[d>>2],G=f[d+4>>2],E=f[(B=d+24|0)+4>>2],f[(D=h+424|0)>>2]=f[B>>2],f[D+4>>2]=E,f[(D=h+408|0)>>2]=p,f[D+4>>2]=R,R=f[d+16>>2],p=f[d+20>>2],E=f[(B=d+40|0)+4>>2],f[(D=h+440|0)>>2]=f[B>>2],f[D+4>>2]=E,D=f[d+32>>2],B=f[d+36>>2],w=f[(V=d+56|0)+4>>2],f[(E=h+456|0)>>2]=f[V>>2],f[E+4>>2]=w,f[h+400>>2]=F,f[h+404>>2]=G,f[h+416>>2]=R,f[h+420>>2]=p,f[h+432>>2]=D,f[h+436>>2]=B,R=f[d+52>>2],f[h+448>>2]=f[d+48>>2],f[h+452>>2]=R,f[h+388>>2]=0,n[h+392|0]=1,f[h+380>>2]=0,f[h+384>>2]=0,function(t,e,i,r,a){var o,h=0,d=0,g=0,m=v(0),y=v(0),p=v(0),R=0,D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=0,W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=0,St=v(0),Tt=v(0),Et=v(0);if(Z=o=Z-96|0,f[i+72>>2])V=C[(g=t+20|0)>>2],f[(R=o+20|0)>>2]=f[g>>2],G=C[(h=t+36|0)>>2],f[(g=o+24|0)>>2]=f[h>>2],f[o+12>>2]=0,w=C[t+4>>2],f[o+16>>2]=f[t+4>>2],Y=C[t+32>>2],f[o+8>>2]=f[t+32>>2],z=C[t+16>>2],f[o+4>>2]=f[t+16>>2],pt=C[t>>2],f[o>>2]=f[t>>2],D=C[t+52>>2],B=C[t+56>>2],m=C[(h=t+24|0)>>2],d=f[h>>2],y=C[t+8>>2],Q=f[t+8>>2],p=C[t+48>>2],W=C[(h=t+40|0)>>2],f[(t=o+40|0)>>2]=f[h>>2],f[(h=o+36|0)>>2]=d,f[(d=o+28|0)>>2]=0,f[(It=o+44|0)>>2]=0,f[o+60>>2]=0,p=v(-p),Dt=v(v(v(y*p)-v(D*m))-v(B*W)),E=C[e+48>>2],F=v(E*y),y=C[e+52>>2],F=v(F+v(y*m)),m=C[e+56>>2],C[o+56>>2]=Dt+v(F+v(m*W)),C[o+52>>2]=v(v(v(w*p)-v(D*V))-v(B*G))+v(v(v(E*w)+v(y*V))+v(m*G)),f[o+32>>2]=Q,C[o+48>>2]=v(v(v(pt*p)-v(D*z))-v(B*Y))+v(v(v(E*pt)+v(y*z))+v(m*Y)),D=C[e+36>>2],B=C[e+20>>2],V=C[e+40>>2],G=C[e+24>>2],w=C[e+32>>2],m=C[e>>2],y=C[e+16>>2],W=C[g>>2],p=C[R>>2],E=C[e+4>>2],Dt=C[t>>2],F=C[e+8>>2],St=C[h>>2],Tt=C[o+16>>2],Et=C[o+32>>2],f[It>>2]=0,C[t>>2]=v(v(F*Et)+v(G*St))+v(V*Dt),C[h>>2]=v(v(E*Et)+v(B*St))+v(D*Dt),f[d>>2]=0,C[g>>2]=v(v(F*Tt)+v(G*p))+v(V*W),C[R>>2]=v(v(E*Tt)+v(B*p))+v(D*W),C[o+32>>2]=v(v(m*Et)+v(y*St))+v(w*Dt),C[o+16>>2]=v(v(m*Tt)+v(y*p))+v(w*W),f[o+12>>2]=0,C[o+8>>2]=v(v(F*pt)+v(G*z))+v(V*Y),C[o+4>>2]=v(v(E*pt)+v(B*z))+v(D*Y),C[o>>2]=v(v(m*pt)+v(y*z))+v(w*Y),yt[f[f[r>>2]+8>>2]](r,o,o- -64|0,o+80|0),_A(i+72|0,o- -64|0,a);else if(yt[f[f[r>>2]+8>>2]](r,e,o- -64|0,o+80|0),e=0|yt[f[f[i>>2]+88>>2]](i))for(It=o+16|0;;){if(e=e+-1|0,yt[f[f[i>>2]+120>>2]](i,e,t,o,It),!(C[o+80>>2]>2]|C[o+64>>2]>C[o+16>>2]|C[o+84>>2]>2]|C[o+68>>2]>C[o+20>>2]|C[o+88>>2]>2]|C[o+72>>2]>C[o+24>>2])){if((0|(d=f[a+4>>2]))==f[a+8>>2]&&!((0|d)>=(0|(Q=d?d<<1:1)))){Q?(r=dA(Q<<2),d=f[a+4>>2]):r=0,R=f[a+12>>2];e:{if((0|d)>=1)for(g=r,h=R;f[g>>2]=f[h>>2],g=g+4|0,h=h+4|0,d=d+-1|0;);else if(!R)break e;_[a+16|0]&&CA(R),f[a+12>>2]=0,d=f[a+4>>2]}f[a+12>>2]=r,n[a+16|0]=1,f[a+8>>2]=Q}f[f[a+12>>2]+(d<<2)>>2]=e,f[a+4>>2]=f[a+4>>2]+1}if(!e)break}Z=o+96|0}(h+464|0,h+400|0,r,a,h+376|0),f[h+380>>2]){if(yt[f[f[r>>2]+112>>2]](r),zA(h+72|4),f[(a=h+136|0)>>2]=0,f[a+4>>2]=0,f[h+80>>2]=1,f[(a=h+144|0)>>2]=0,f[a+4>>2]=0,f[(a=h+152|0)>>2]=0,f[a+4>>2]=0,f[(a=h+160|0)>>2]=0,f[a+4>>2]=0,f[(a=h+168|0)>>2]=0,f[a+4>>2]=0,f[(a=h+176|0)>>2]=0,f[a+4>>2]=0,f[h+76>>2]=8128,te(h+184|0),f[h+280>>2]=4,f[h+364>>2]=8708,f[h+356>>2]=8628,f[h+348>>2]=8556,f[h+184>>2]=8364,f[h+72>>2]=r,a=h+356|0,yt[f[f[r>>2]+96>>2]](r)||(a=f[h+72>>2],a=0|yt[f[f[a>>2]+100>>2]](a)?h+364|0:h+348|0),f[a+4>>2]=h+72,f[h+372>>2]=a,R=0|yt[f[f[r>>2]+92>>2]](r),a=f[h+380>>2])if(o)for(d=(a<<2)-4|0;o=f[f[h+388>>2]+d>>2],f[t+32>>2]=o,p=f[h+372>>2],p=0|yt[f[f[p>>2]>>2]](p,o),R&&yt[f[f[r>>2]+132>>2]](h+8|0,r,o),f[h+8>>2]=e,f[h+20>>2]=f[e+12>>2],F=f[e+8>>2],f[h+16>>2]=F,f[h+12>>2]=p,f[h+28>>2]=f[t+24>>2],f[h+24>>2]=f[t+28>>2],p=f[t+16>>2],o=f[p+8>>2],f[((0|F)==f[o+8>>2]?8:12)+p>>2]=h+8,ge(t,i,h+8|0),f[f[t+16>>2]+8>>2]=o,d=d+-4|0,a=a+-1|0;);else for(d=(a<<2)-4|0;o=f[f[h+388>>2]+d>>2],f[t+24>>2]=o,p=f[h+372>>2],p=0|yt[f[f[p>>2]>>2]](p,o),R&&yt[f[f[r>>2]+132>>2]](h+8|0,r,o),f[h+8>>2]=e,f[h+20>>2]=f[e+12>>2],F=f[e+8>>2],f[h+16>>2]=F,f[h+12>>2]=p,f[h+28>>2]=f[t+24>>2],f[h+24>>2]=f[t+28>>2],p=f[t+16>>2],o=f[p+8>>2],f[((0|F)==f[o+8>>2]?8:12)+p>>2]=h+8,ge(t,h+8|0,i),f[f[t+16>>2]+8>>2]=o,d=d+-4|0,a=a+-1|0;);yt[f[f[r>>2]+116>>2]](r),Ae(h+184|0),Ae(h+72|4)}(t=f[h+388>>2])&&(_[h+392|0]&&CA(t),f[h+388>>2]=0)}else!function(t,e,i,r,n,a){var o,_=0,h=0,d=v(0),g=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=0,W=v(0),Y=v(0),z=v(0),yt=v(0),pt=v(0),Dt=v(0),It=0,St=0,Tt=0,Et=0,Ot=v(0),Nt=v(0),Ft=v(0);if(Z=o=Z-96|0,h=f[n+20>>2])for(_=f[i+12>>2],Ot=C[_+56>>2],Nt=C[_+52>>2],p=C[_+40>>2],R=C[_+36>>2],D=C[_+24>>2],B=C[_+20>>2],Ft=C[_+48>>2],E=C[_+32>>2],F=C[_+16>>2],V=C[_+8>>2],G=C[_+4>>2],w=C[_>>2],Q=h+-1|0,h=m(h,80)+-80|0;_=f[n+28>>2]+h|0,Tt=f[_- -64>>2],f[o+92>>2]=0,f[o+76>>2]=0,f[o+60>>2]=0,f[o+44>>2]=0,d=C[_+8>>2],g=C[_+24>>2],y=C[_+40>>2],C[o+72>>2]=v(v(E*d)+v(R*g))+v(p*y),W=C[_+4>>2],Y=C[_+20>>2],z=C[_+36>>2],C[o+68>>2]=v(v(E*W)+v(R*Y))+v(p*z),yt=C[_>>2],pt=C[_+16>>2],Dt=C[_+32>>2],C[o+64>>2]=v(v(E*yt)+v(R*pt))+v(p*Dt),C[o+56>>2]=v(v(F*d)+v(B*g))+v(D*y),C[o+52>>2]=v(v(F*W)+v(B*Y))+v(D*z),C[o+48>>2]=v(v(F*yt)+v(B*pt))+v(D*Dt),C[o+40>>2]=v(v(w*d)+v(G*g))+v(V*y),C[o+36>>2]=v(v(w*W)+v(G*Y))+v(V*z),C[o+32>>2]=v(v(w*yt)+v(G*pt))+v(V*Dt),d=C[_+48>>2],g=C[_+52>>2],y=C[_+56>>2],C[o+88>>2]=Ot+v(v(v(E*d)+v(R*g))+v(p*y)),C[o+84>>2]=Nt+v(v(v(F*d)+v(B*g))+v(D*y)),C[o+80>>2]=Ft+v(v(v(w*d)+v(G*g))+v(V*y)),f[o+8>>2]=i,Et=f[i+8>>2],f[o+16>>2]=Et,f[o+12>>2]=Tt,f[o+28>>2]=Q,f[o+24>>2]=-1,_=f[t+16>>2],f[o+20>>2]=o+32,It=f[_+8>>2],St=_+8|0,f[It+8>>2]!=(0|Et)&&(It=f[_+12>>2],St=_+12|0),f[St>>2]=o+8,me(t,e,o+8|0,r,Tt,a),_=f[t+16>>2],f[(f[f[_+8>>2]+8>>2]==f[o+16>>2]?8:12)+_>>2]=It,h=h+-80|0,-1!=(0|(Q=Q+-1|0)););Z=o+96|0}(t,e,i,r,a,o);else!function(t,e,i,r,n,a){var o,_,h,d=0,p=v(0),R=v(0),D=0,B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=0,Y=0,z=v(0),pt=0,Dt=0,It=0,St=0,Tt=v(0),Et=v(0),Ot=v(0);if(Z=o=Z-144|0,d=f[e+12>>2],W=f[(pt=d+8|0)+4>>2],f[(D=o+88|0)>>2]=f[pt>>2],f[D+4>>2]=W,D=f[d>>2],pt=f[d+4>>2],Y=f[(Dt=d+24|0)+4>>2],f[(W=o+104|0)>>2]=f[Dt>>2],f[W+4>>2]=Y,W=f[d+16>>2],Dt=f[d+20>>2],St=f[(It=d+40|0)+4>>2],f[(Y=o+120|0)>>2]=f[It>>2],f[Y+4>>2]=St,Y=f[d+32>>2],It=f[d+36>>2],h=f[(_=d+56|0)+4>>2],f[(St=o+136|0)>>2]=f[_>>2],f[St+4>>2]=h,f[o+80>>2]=D,f[o+84>>2]=pt,f[o+96>>2]=W,f[o+100>>2]=Dt,f[o+112>>2]=Y,f[o+116>>2]=It,D=f[d+52>>2],f[o+128>>2]=f[d+48>>2],f[o+132>>2]=D,d=f[i+12>>2],G=C[d+20>>2],E=C[d+24>>2],F=C[d+36>>2],V=C[d+40>>2],w=C[d+8>>2],Q=C[d>>2],Tt=C[d+4>>2],Et=C[d+16>>2],Ot=C[d+32>>2],p=C[n+52>>2],R=C[n+56>>2],B=C[n+60>>2],z=v(v(v(v(C[d+48>>2]*p)+v(C[d+52>>2]*R))+v(C[d+56>>2]*B))+C[n+68>>2]),C[o+76>>2]=z,F=v(v(v(Ot*p)+v(F*R))+v(V*B)),C[o+72>>2]=F,G=v(v(v(Et*p)+v(G*R))+v(E*B)),C[o+68>>2]=G,E=v(v(v(Q*p)+v(Tt*R))+v(w*B)),C[o+64>>2]=E,yt[f[f[r>>2]+8>>2]](r,o+80|0,o+32|0,o+48|0),p=v(yt[f[f[n>>2]+48>>2]](n)),R=v(p+C[(d=o+52|0)>>2]),C[d>>2]=R,B=v(p+C[(d=o+56|0)>>2]),C[d>>2]=B,w=v(C[o+36>>2]-p),C[o+36>>2]=w,V=v(p+C[o+48>>2]),C[o+48>>2]=V,Q=v(C[o+32>>2]-p),C[o+32>>2]=Q,p=v(C[o+40>>2]-p),C[o+40>>2]=p,Q=v(v(Q+V)*v(.5)),w=v(v(w+R)*v(.5)),p=v(v(p+B)*v(.5)),Tt=v(v(v(Q*E)+v(w*G))+v(p*F)),p=v(v(v(v(V-Q)*v(y(E)))+v(v(R-w)*v(y(G))))+v(v(B-p)*v(y(F)))),!(z>v(v(Tt+p)+v(9.999999974752427e-7))|v(z+v(9.999999974752427e-7))>=v(Tt-p)^1)){if(yt[f[f[r>>2]+112>>2]](r),p=v(yt[f[f[r>>2]+48>>2]](r)),R=v(yt[f[f[n>>2]+48>>2]](n)),n=f[r+188>>2])for(G=v(p+R),n=n+-1|0;d=f[r+184>>2]+m(f[r+196>>2],n)|0,1!=f[r+192>>2]?(p=v(C[d>>2]*C[r+160>>2]),C[o+16>>2]=p,R=v(C[d+4>>2]*C[r+164>>2]),C[o+20>>2]=R,B=v(C[d+8>>2]*C[r+168>>2])):(p=v(g[d>>3]*+C[r+160>>2]),C[o+16>>2]=p,R=v(g[d+8>>3]*+C[r+164>>2]),C[o+20>>2]=R,B=v(g[d+16>>3]*+C[r+168>>2])),f[o+28>>2]=0,E=v(v(v(v(p*C[o+96>>2])+v(R*C[o+100>>2]))+v(B*C[o+104>>2]))+C[o+132>>2]),C[o+20>>2]=E,z=C[o+68>>2],V=v(v(v(v(p*C[o+80>>2])+v(R*C[o+84>>2]))+v(B*C[o+88>>2]))+C[o+128>>2]),C[o+16>>2]=V,F=C[o+64>>2],p=v(v(v(v(p*C[o+112>>2])+v(R*C[o+116>>2]))+v(B*C[o+120>>2]))+C[o+136>>2]),C[o+24>>2]=p,R=C[o+72>>2],(p=v(v(v(v(v(V*F)+v(E*z))+v(p*R))-C[o+76>>2])-G))>2]=0,C[o+8>>2]=-R,C[o+4>>2]=-z,C[o>>2]=-F,d=f[t+16>>2],yt[f[f[d>>2]+8>>2]](d,f[t+28>>2],f[t+24>>2]),d=f[t+16>>2],yt[f[f[d>>2]+12>>2]](d,f[t+36>>2],f[t+32>>2]),(d=f[t+12>>2])||(d=f[t+4>>2],d=0|yt[f[f[d>>2]+12>>2]](d,f[i+8>>2],f[e+8>>2]),f[t+12>>2]=d),D=f[t+16>>2],f[D+4>>2]=d,yt[f[f[D>>2]+16>>2]](D,o,o+16|0,p)):(d=f[t+16>>2],yt[f[f[d>>2]+8>>2]](d,f[t+28>>2],f[t+24>>2]),d=f[t+16>>2],yt[f[f[d>>2]+12>>2]](d,f[t+36>>2],f[t+32>>2]),(d=f[t+12>>2])||(d=f[t+4>>2],d=0|yt[f[f[d>>2]+12>>2]](d,f[e+8>>2],f[i+8>>2]),f[t+12>>2]=d),D=f[t+16>>2],f[D+4>>2]=d,yt[f[f[D>>2]+16>>2]](D,o- -64|0,o+16|0,p))),-1!=(0|(n=n+-1|0)););yt[f[f[r>>2]+116>>2]](r)}Z=o+144|0}(t,e,i,r,a,o);else{if(R=(o?36:28)+t|0,d=(p=f[r+156>>2])+-1|0,f[R>>2]=d,!p)break t;for(;me(t,e,i,f[f[r+164>>2]+(d<<2)>>2],a,o),d=(p=f[R>>2])+-1|0,f[R>>2]=d,p;);}Z=h+528|0}function Re(t,e,i,r,n){return v(v(1))}function Qe(t){return(t|=0)+16|0}function he(t,e,i){t|=0,e=v(e),f[(i|=0)>>2]=0,f[i+4>>2]=0,f[(t=i+8|0)>>2]=0,f[t+4>>2]=0}function Ge(t,e){t|=0,e=v(e),C[t+48>>2]=e}function ye(t){return 52}function pe(t){return 2}function Fe(t){return 3}function We(t){return 1}function we(t){return 0}function De(t,e,i){}function Ee(t){var e=0;f[t+132>>2]=0,f[t+136>>2]=0,f[t>>2]=8964,f[t+188>>2]=0,f[t+192>>2]=0,f[t+180>>2]=0,f[t+184>>2]=1566444395,f[t+164>>2]=1065353216,f[t+168>>2]=1065353216,f[t+276>>2]=0,f[t+280>>2]=0,f[t+268>>2]=1065353216,f[t+272>>2]=0,f[t+260>>2]=-1,f[t+264>>2]=-1,f[t+252>>2]=1,f[t+256>>2]=0,f[t+244>>2]=1036831949,f[t+248>>2]=1176256512,f[t+236>>2]=0,f[t+240>>2]=0,f[t+228>>2]=1056964608,f[t+232>>2]=0,f[t+220>>2]=1,f[t+224>>2]=0,f[t+212>>2]=-1,f[t+216>>2]=-1,f[t+204>>2]=1,f[t+208>>2]=-1,f[(e=t+140|0)>>2]=0,f[e+4>>2]=0,f[(e=t+148|0)>>2]=0,f[e+4>>2]=0,f[(e=t+156|0)>>2]=0,f[e+4>>2]=0,f[(e=t+172|0)>>2]=1065353216,f[e+4>>2]=0,f[(e=t+196|0)>>2]=0,f[e+4>>2]=0,n[t+300|0]=1,f[t+304>>2]=0,f[t+296>>2]=0,f[(e=t+288|0)>>2]=0,f[e+4>>2]=0,f[(e=t+8|0)>>2]=0,f[e+4>>2]=0,f[t+4>>2]=1065353216,f[(e=t+16|0)>>2]=0,f[e+4>>2]=0,f[(e=t+28|0)>>2]=0,f[e+4>>2]=0,f[t+24>>2]=1065353216,f[(e=t+36|0)>>2]=0,f[e+4>>2]=0,f[(e=t+48|0)>>2]=0,f[e+4>>2]=0,f[t+44>>2]=1065353216,f[(e=t+56|0)>>2]=0,f[e+4>>2]=0,f[(e=t+72|0)>>2]=0,f[e+4>>2]=0,f[(e=t- -64|0)>>2]=0,f[e+4>>2]=1065353216,f[(e=t+80|0)>>2]=0,f[e+4>>2]=0,f[t+88>>2]=1065353216,f[(e=t+100|0)>>2]=0,f[e+4>>2]=0,f[(e=t+92|0)>>2]=0,f[e+4>>2]=0,f[t+128>>2]=0,f[t+108>>2]=1065353216,f[(e=t+120|0)>>2]=0,f[e+4>>2]=0,f[(t=t+112|0)>>2]=0,f[t+4>>2]=0}function Ze(t){var e;return f[(t|=0)>>2]=8964,(e=f[t+296>>2])&&(_[t+300|0]&&CA(e),f[t+296>>2]=0),f[t+296>>2]=0,f[t+288>>2]=0,f[t+292>>2]=0,n[t+300|0]=1,0|t}function Ye(t,e){4!=(-2&f[t+220>>2])&&(f[t+220>>2]=e)}function Ve(t,e){3&_[t+204|0]&&!e||(4!=(-2&f[t+220>>2])&&(f[t+220>>2]=1),f[t+224>>2]=0)}function Ne(t,e,i){t|=0,i|=0;var r=0,n=0;return f[(e|=0)+16>>2]=f[t+4>>2],f[e+20>>2]=f[t+8>>2],f[e+24>>2]=f[t+12>>2],f[e+28>>2]=f[t+16>>2],f[e+32>>2]=f[t+20>>2],f[e+36>>2]=f[t+24>>2],f[e+40>>2]=f[t+28>>2],f[e+44>>2]=f[t+32>>2],f[e+48>>2]=f[t+36>>2],f[e+52>>2]=f[t+40>>2],f[e+56>>2]=f[t+44>>2],f[e+60>>2]=f[t+48>>2],f[e+64>>2]=f[t+52>>2],f[e+68>>2]=f[t+56>>2],f[e+72>>2]=f[t+60>>2],f[e+76>>2]=f[t- -64>>2],f[e+80>>2]=f[t+68>>2],f[e+84>>2]=f[t+72>>2],f[e+88>>2]=f[t+76>>2],f[e+92>>2]=f[t+80>>2],f[e+96>>2]=f[t+84>>2],f[e+100>>2]=f[t+88>>2],f[e+104>>2]=f[t+92>>2],f[e+108>>2]=f[t+96>>2],f[e+112>>2]=f[t+100>>2],f[e+116>>2]=f[t+104>>2],f[e+120>>2]=f[t+108>>2],f[e+124>>2]=f[t+112>>2],f[e+128>>2]=f[t+116>>2],f[e+132>>2]=f[t+120>>2],f[e+136>>2]=f[t+124>>2],f[e+140>>2]=f[t+128>>2],f[e+144>>2]=f[t+132>>2],f[e+148>>2]=f[t+136>>2],f[e+152>>2]=f[t+140>>2],f[e+156>>2]=f[t+144>>2],f[e+160>>2]=f[t+148>>2],f[e+164>>2]=f[t+152>>2],f[e+168>>2]=f[t+156>>2],f[e+172>>2]=f[t+160>>2],f[e+176>>2]=f[t+164>>2],f[e+180>>2]=f[t+168>>2],f[e+184>>2]=f[t+172>>2],f[e+188>>2]=f[t+176>>2],f[e+232>>2]=f[t+180>>2],f[e+192>>2]=f[t+184>>2],f[e>>2]=0,r=0|yt[f[f[i>>2]+28>>2]](i,f[t+192>>2]),n=f[t+228>>2],f[e+196>>2]=f[t+224>>2],f[e+200>>2]=n,n=f[t+212>>2],f[e+240>>2]=f[t+208>>2],f[e+244>>2]=n,f[e+8>>2]=0,f[e+4>>2]=r,f[e+236>>2]=f[t+204>>2],f[e+248>>2]=f[t+220>>2],f[e+204>>2]=f[t+236>>2],f[e+208>>2]=f[t+244>>2],f[e+212>>2]=f[t+248>>2],f[e+216>>2]=f[t+232>>2],f[e+252>>2]=f[t+252>>2],r=0|yt[f[f[i>>2]+40>>2]](i,t),n=0|yt[f[f[i>>2]+28>>2]](i,r),f[e+12>>2]=n,n&&yt[f[f[i>>2]+48>>2]](i,r),f[e+220>>2]=f[t+268>>2],i=f[t+280>>2],r=f[t+276>>2],t=f[t+272>>2],f[e+260>>2]=0,f[e+224>>2]=t,f[e+228>>2]=r,f[e+256>>2]=i,8992}function Ie(t,e){t|=0,e=v(e);var i,r,n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0);n=v(yt[f[f[t>>2]+48>>2]](t)),a=v(yt[f[f[t>>2]+48>>2]](t)),o=v(yt[f[f[t>>2]+48>>2]](t)),C[t+48>>2]=e,e=C[(i=t+40|0)>>2],_=C[(r=t+36|0)>>2],h=C[t+32>>2],d=v(yt[f[f[t>>2]+48>>2]](t)),g=v(yt[f[f[t>>2]+48>>2]](t)),m=v(yt[f[f[t>>2]+48>>2]](t)),f[t+44>>2]=0,C[r>>2]=v(a+_)-g,C[t+32>>2]=v(n+h)-d,C[i>>2]=v(o+e)-m}function Je(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0);n=v(yt[f[f[t>>2]+48>>2]](t)),d=C[e+52>>2],_=C[e+20>>2],p=C[e+24>>2],g=C[e+56>>2],h=C[e+36>>2],a=C[t+36>>2],R=C[e+40>>2],D=C[t+40>>2],m=C[e+48>>2],B=C[e>>2],E=C[e+4>>2],F=C[e+8>>2],V=C[e+16>>2],G=C[e+32>>2],o=C[t+32>>2],f[i+12>>2]=0,o=v(n+o),a=v(n+a),n=v(n+D),h=v(v(v(o*v(y(G)))+v(a*v(y(h))))+v(n*v(y(R)))),C[i+8>>2]=g-h,_=v(v(v(o*v(y(V)))+v(a*v(y(_))))+v(n*v(y(p)))),C[i+4>>2]=d-_,n=v(v(v(o*v(y(B)))+v(a*v(y(E))))+v(n*v(y(F)))),C[i>>2]=m-n,f[r+12>>2]=0,C[r+8>>2]=g+h,C[r+4>>2]=_+d,C[r>>2]=n+m}function xe(t,e){t|=0,e|=0;var i,r,n,a,o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0);o=v(yt[f[f[t>>2]+48>>2]](t)),_=v(yt[f[f[t>>2]+48>>2]](t)),h=v(yt[f[f[t>>2]+48>>2]](t)),d=C[(i=t+20|0)>>2],g=C[(r=t+36|0)>>2],m=C[(n=t+24|0)>>2],y=C[(a=t+40|0)>>2],p=C[t+16>>2],R=C[t+32>>2],EA(t,e),f[t+44>>2]=0,C[a>>2]=v(v(v(h+y)/m)*C[n>>2])-h,C[r>>2]=v(v(v(_+g)/d)*C[i>>2])-_,C[t+32>>2]=v(v(v(o+R)/p)*C[t+16>>2])-o}function Ue(t){return 6}function Me(t){t|=0;var e=v(0),i=v(0);return e=C[t+32>>2],i=v(yt[f[f[t>>2]+48>>2]](t)),v(yt[f[f[t>>2]+48>>2]](t)),v(yt[f[f[t>>2]+48>>2]](t)),v(v(e+i))}function Se(t,e,i,r,n,a){var o,_=v(0),h=v(0),d=v(0),g=v(0),m=0,y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),F=0,V=0,G=v(0),w=0,Q=0,W=v(0),Y=v(0),z=0,pt=v(0),Dt=0,It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=0,Vt=0,Gt=0,Lt=0,wt=0,xt=0,Qt=0,Wt=0,Yt=0;Z=o=Z-32|0;t:if(!(f[t+56>>2]<1))for(h=C[r>>2],p=C[i>>2],g=v(h-p),d=C[r+4>>2],R=C[i+4>>2],y=v(d-R),_=C[r+8>>2],D=C[i+8>>2],B=v(_-D),G=v(v(1)/v(E(v(v(v(g*g)+v(y*y))+v(B*B))))),W=B,B=v(B*G),Y=g,g=v(g*G),pt=y,y=v(y*G),pt=v(v(W*B)+v(v(Y*g)+v(pt*y))),G=C[a+8>>2],It=v((D<_?_:D)+G),W=C[a+4>>2],St=v((R>2],Tt=v((p>2],Et=v(D+_),R=d>2],Ot=v(R+d),p=h>2],Nt=v(p+h),r=f[t+96>>2],p=B==v(0)?v(0xde0b6b000000000):v(v(1)/B),F=p>2],V=f[m+4>>2],Qt=f[r>>2],Wt=f[r+4>>2],m=f[r+20>>2],f[Q>>2]=f[r+16>>2],f[Q+4>>2]=m,Yt=f[(m=r+24|0)+4>>2],f[(Dt=Q+8|0)>>2]=f[m>>2],f[Dt+4>>2]=Yt,f[o>>2]=Qt,f[o+4>>2]=Wt,f[o+8>>2]=w,f[o+12>>2]=V,C[o>>2]=C[o>>2]-Y,C[o+4>>2]=C[o+4>>2]-W,C[o+16>>2]=C[o+16>>2]-h,C[o+20>>2]=C[o+20>>2]-d,C[o+8>>2]=C[o+8>>2]-G,C[o+24>>2]=C[o+24>>2]-_;e:{i:{A:{r:{if(w=St>2]|Ot>C[r+20>>2],V=0,Nt>C[r+16>>2]||(V=0,Tt>2]||(V=1)),!(w|1^(It>2]|Et>C[m>>2]?0:V)||(g=C[i+4>>2],h=v(R*v(C[Vt>>2]-g)),_=C[i>>2],d=v(D*v(C[xt>>2]-_)),h>d||(_=v(D*v(C[wt>>2]-_)),g=v(R*v(C[Lt>>2]-g)),_>g||(B=C[i+8>>2],y=v(p*v(C[Ft>>2]-B)),d=gd||(h=h>_?h:_,_=v(p*v(C[Gt>>2]-B)),h>_)))))){if(m=-1==(0|(V=f[r+32>>2])),1!=(0|(w=(y>h?y:h)v(0)))|-1!=(0|V))break r;yt[f[f[e>>2]+8>>2]](e,f[r+36>>2],f[r+40>>2]);break A}m=-1==f[r+32>>2],w=0}if(!m&&!w)break i}z=z+1|0,r=r- -64|0;break e}z=(m=f[r+32>>2])+z|0,r=(m<<6)+r|0}if((0|z)>=f[t+56>>2])break t;F=F+1|0,_=C[n+8>>2],d=C[n+4>>2],h=C[n>>2],G=C[a+8>>2],W=C[a+4>>2],Y=C[a>>2]}f[430]<(0|F)&&(f[430]=F),Z=o+32|0}function Xe(t,e,i,r,n,a,o){var _,d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=0,F=v(0),V=v(0),G=v(0),w=0,Q=v(0),W=0,Y=v(0),z=v(0),pt=0,Dt=0,It=0,St=0,Tt=v(0),Et=v(0),Ot=v(0),Nt=0,Ft=0,Vt=0,Gt=0,Lt=0,wt=0,xt=0,Qt=0,Wt=0,Yt=0,Pt=0,Mt=0,Zt=0,Ut=0;if(Z=_=Z-32|0,p=C[i+4>>2],R=C[r+4>>2],D=C[i>>2],y=C[r>>2],G=C[t+28>>2],d=C[t+12>>2],V=C[r+8>>2],Q=C[i+8>>2],g=(g=v((V>2]))>2],r=(g=v(v((G=v(0)?~~g>>>0:0,Y=C[t+24>>2],g=C[t+8>>2],m=(m=v((R>2]))>2],B=(m=v(v((Y=v(0)?~~m>>>0:0,z=C[t+20>>2],m=C[t+4>>2],F=(F=v((y>2]))>2],W=(F=v(v((z=v(0)?~~F>>>0:0,F=v((Q>2]),pt=(d=v(v(v((G<(F=F=v(0)?~~d>>>0:0,d=v((p>2]),Dt=(d=v(v(v((Y<(d=d=v(0)?~~d>>>0:0,d=v((D>2]),It=(d=v(v(v((z<(d=d=v(0)?~~d>>>0:0,0<(0|o))for(D=v(y-D),p=v(R-p),R=v(V-Q),y=v(v(1)/v(E(v(v(v(D*D)+v(p*p))+v(R*R))))),d=R,R=v(R*y),g=D,D=v(D*y),m=p,p=v(p*y),Q=v(v(d*R)+v(v(g*D)+v(m*p))),Gt=65534&r,Lt=65534&B,wt=65534&W,pt|=1,Dt|=1,It|=1,r=f[t+136>>2],xt=((w=(R=R==v(0)?v(0xde0b6b000000000):v(v(1)/R))>2],B=0;t:{e:{i:{A:if(!(wt>>>0>h[r+6>>1]||(Nt=h[r>>1],It>>>0>>0|Gt>>>0>h[r+10>>1]||(Ft=h[r+4>>1],pt>>>0>>0|Lt>>>0>h[r+8>>1]||(Vt=h[r+2>>1],Dt>>>0>>0))))){if(f[_+12>>2]=0,B=h[r+10>>1],Zt=h[r+8>>1],Ut=h[r+6>>1],f[_+28>>2]=0,y=C[t+36>>2],d=C[t+4>>2],C[_>>2]=v(v(v(Nt>>>0)/y)+d)-C[a>>2],g=C[t+40>>2],m=C[t+8>>2],C[_+4>>2]=v(v(v(Vt>>>0)/g)+m)-C[a+4>>2],V=C[t+44>>2],G=C[t+12>>2],C[_+8>>2]=v(v(v(Ft>>>0)/V)+G)-C[a+8>>2],C[_+16>>2]=v(d+v(v(Ut>>>0)/y))-C[n>>2],C[_+20>>2]=v(m+v(v(Zt>>>0)/g))-C[n+4>>2],C[_+24>>2]=v(G+v(v(B>>>0)/V))-C[n+8>>2],m=C[i+4>>2],y=v(p*v(C[Qt>>2]-m)),g=C[i>>2],!(y>(d=v(D*v(C[Mt>>2]-g)))||(g=v(D*v(C[Pt>>2]-g)),m=v(p*v(C[Yt>>2]-m)),g>m||(G=C[i+8>>2],V=v(R*v(C[xt>>2]-G)),d=md||(y=y>g?y:g,g=v(R*v(C[Wt>>2]-G)),y>g))))){if(!(B=(V>y?V:y)v(0))|(0|W)<0)break A;B=f[r+12>>2],yt[f[f[e>>2]+8>>2]](e,B>>21,2097151&B);break i}B=0}if(!((0|W)>-1||B))break e}St=St+1|0,r=r+16|0;break t}St=St-(B=f[r+12>>2])|0,r=r-(B<<4)|0}if(w=w+1|0,!((0|St)<(0|o)))break}f[430]<(0|w)&&(f[430]=w),Z=_+32|0}function Te(t,e,i,r){var n;Z=n=Z-16|0,f[n+8>>2]=e,f[n>>2]=9988,f[n+4>>2]=f[t+52>>2],function(t,e,i,r){var n,a=0;Z=n=Z-32|0,f[(a=n+24|0)>>2]=0,f[a+4>>2]=0,f[n+16>>2]=0,f[n+20>>2]=0,f[(a=n+8|0)>>2]=0,f[a+4>>2]=0,f[n>>2]=0,f[n+4>>2]=0,_[t+60|0]?Xe(t,e,i,r,n+16|0,n,f[t+56>>2]):Se(t,e,i,r,n+16|0,n),Z=n+32|0}(f[t+56>>2],n,i,r),Z=n+16|0}function je(t,e,i,r,n,a){var o;Z=o=Z-16|0,f[o+8>>2]=e,f[o>>2]=10156,f[o+4>>2]=f[t+52>>2],function(t,e,i,r,n,a){_[t+60|0]?Xe(t,e,i,r,n,a,f[t+56>>2]):Se(t,e,i,r,n,a)}(f[t+56>>2],o,i,r,n,a),Z=o+16|0}function Oe(t,e,i){t|=0,e|=0,i|=0;var r,n,a,o,_,d=0,y=v(0),p=v(0),R=v(0),D=0,B=0,E=v(0);Z=r=Z-80|0,d=f[t+4>>2],yt[f[f[d>>2]+16>>2]](d,r+28|0,r+24|0,r+20|0,r+16|0,r+12|0,r+8|0,r+4|0,r,e),D=(n=f[t+4>>2])+12|0,a=f[r+12>>2]+m(f[r+8>>2],i)|0,o=f[r+28>>2],_=f[r+20>>2];t:{e:{i:{A:{r:{n:{a:{if(3!=f[r>>2]){if(B=f[r+16>>2],d=m(B,f[a+8>>2])+o|0,_)break a;p=v(C[d+4>>2]*C[n+8>>2]),R=v(C[d>>2]*C[n+4>>2]),y=C[n+12>>2],d=d+8|0;break n}if(B=f[r+16>>2],d=m(B,h[a+4>>1])+o|0,_?(p=v(C[n+8>>2]*v(g[d+8>>3])),R=v(C[n+4>>2]*v(g[d>>3])),y=v(g[d+16>>3]),d=D):(p=v(C[d+4>>2]*C[n+8>>2]),R=v(C[d>>2]*C[n+4>>2]),y=C[n+12>>2],d=d+8|0),E=C[d>>2],f[r+76>>2]=0,C[r+68>>2]=p,C[r+72>>2]=E*y,C[r+64>>2]=R,d=m(B,h[a+2>>1])+o|0,!_)break r;p=v(C[n+8>>2]*v(g[d+8>>3])),R=v(C[n+4>>2]*v(g[d>>3])),y=v(g[d+16>>3]),d=D;break A}p=v(C[n+8>>2]*v(g[d+8>>3])),R=v(C[n+4>>2]*v(g[d>>3])),y=v(g[d+16>>3]),d=D}if(E=C[d>>2],f[r+76>>2]=0,C[r+68>>2]=p,C[r+72>>2]=E*y,C[r+64>>2]=R,d=m(B,f[a+4>>2])+o|0,!_)break i;p=v(C[n+8>>2]*v(g[d+8>>3])),R=v(C[n+4>>2]*v(g[d>>3])),y=v(g[d+16>>3]),d=D;break e}p=v(C[d+4>>2]*C[n+8>>2]),R=v(C[d>>2]*C[n+4>>2]),y=C[n+12>>2],d=d+8|0}E=C[d>>2],f[r+60>>2]=0,C[r+52>>2]=p,C[r+56>>2]=E*y,C[r+48>>2]=R,d=m(B,h[a>>1])+o|0,_?(p=v(C[n+8>>2]*v(g[d+8>>3])),R=v(C[n+4>>2]*v(g[d>>3])),y=v(g[d+16>>3])):(D=d+8|0,p=v(C[d+4>>2]*C[n+8>>2]),R=v(C[d>>2]*C[n+4>>2]),y=C[n+12>>2]),y=v(C[D>>2]*y);break t}p=v(C[d+4>>2]*C[n+8>>2]),R=v(C[d>>2]*C[n+4>>2]),y=C[n+12>>2],d=d+8|0}E=C[d>>2],f[r+60>>2]=0,C[r+52>>2]=p,C[r+56>>2]=E*y,C[r+48>>2]=R,d=m(B,f[a>>2])+o|0,_?(p=v(C[n+8>>2]*v(g[d+8>>3])),R=v(C[n+4>>2]*v(g[d>>3])),y=v(g[d+16>>3])):(D=d+8|0,p=v(C[d+4>>2]*C[n+8>>2]),R=v(C[d>>2]*C[n+4>>2]),y=C[n+12>>2]),y=v(C[D>>2]*y)}f[r+44>>2]=0,C[r+40>>2]=y,C[r+36>>2]=p,C[r+32>>2]=R,d=f[t+8>>2],yt[f[f[d>>2]+8>>2]](d,r+32|0,e,i),t=f[t+4>>2],yt[f[f[t>>2]+24>>2]](t,e),Z=r+80|0}function He(t){f[t+4>>2]=35,f[t+8>>2]=0,f[t+12>>2]=-1,f[t+16>>2]=0,f[t>>2]=10304}function ze(t){return(t|=0)+72|0}function Pe(t,e,i){var r=0;He(t),f[t+88>>2]=0,n[t+92|0]=1,f[(r=t+80|0)>>2]=0,f[r+4>>2]=0,f[t+72>>2]=0,f[(r=t- -64|0)>>2]=1065353216,f[r+4>>2]=0,f[t+56>>2]=1065353216,f[t+60>>2]=1065353216,n[t+52|0]=1,f[t+44>>2]=-8388609,f[(r=t+36|0)>>2]=-8388609,f[r+4>>2]=-8388609,f[t+28>>2]=2139095039,f[t+20>>2]=2139095039,f[t+24>>2]=2139095039,f[t+4>>2]=25,f[t+188>>2]=0,f[(r=t+180|0)>>2]=0,f[r+4>>2]=0,f[(r=t+168|0)>>2]=1065353216,f[r+4>>2]=0,f[(r=t+160|0)>>2]=1065353216,f[r+4>>2]=1065353216,f[t+152>>2]=1008981770,f[t+148>>2]=11168,f[t>>2]=10560,f[(r=t+204|0)>>2]=0,f[r+4>>2]=0,f[(r=t+196|0)>>2]=0,f[r+4>>2]=0,f[t+156>>2]=e,f[t+176>>2]=i,f[t+144>>2]=t+148}function Ke(t){var e;return f[(t|=0)>>2]=11012,(e=f[t+88>>2])&&(_[t+92|0]&&CA(e),f[t+88>>2]=0),f[t+88>>2]=0,f[t+80>>2]=0,f[t+84>>2]=0,n[t+92|0]=1,0|t}function Le(t){return(t|=0)+56|0}function qe(t){}function $e(t){var e=0,i=0,r=0,a=0;if(f[(t|=0)>>2]=10820,e=f[t+164>>2],i=f[t+156>>2])for(r=(i<<2)-4|0;i=i+-1|0,(a=f[e+r>>2])&&(yt[f[f[a>>2]+4>>2]](a),e=f[t+164>>2]),r=r+-4|0,i;);return e&&(_[t+168|0]&&CA(e),f[t+164>>2]=0),f[t+164>>2]=0,f[t+156>>2]=0,f[t+160>>2]=0,f[t>>2]=11012,n[t+168|0]=1,(e=f[t+88>>2])&&(_[t+92|0]&&CA(e),f[t+88>>2]=0),f[t+88>>2]=0,f[t+80>>2]=0,f[t+84>>2]=0,n[t+92|0]=1,0|t}function Ar(t,e,i,r,n){}function er(t){f[t+16>>2]=0,f[t+8>>2]=-1,f[t+12>>2]=0,f[t>>2]=0,f[t+4>>2]=0,f[t+32>>2]=0,n[t+36|0]=1,f[(t=t+24|0)>>2]=0,f[t+4>>2]=0}function rr(t){var e=0;(e=f[t>>2])&&ir(t,e),CA(f[t+4>>2]),f[t+4>>2]=0,f[t+8>>2]=-1,(e=f[t+32>>2])&&(_[t+36|0]&&CA(e),f[t+32>>2]=0),f[t+16>>2]=0,f[t+32>>2]=0,f[t+24>>2]=0,f[t+28>>2]=0,n[t+36|0]=1}function ir(t,e){f[e+40>>2]&&(ir(t,f[e+36>>2]),ir(t,f[e+40>>2])),(0|e)==f[t>>2]&&(f[t>>2]=0),CA(f[t+4>>2]),f[t+4>>2]=e}function fr(t){var e=0;(e=f[t>>2])&&ir(t,e),CA(f[t+4>>2]),f[t+4>>2]=0,f[t+8>>2]=-1,(e=f[t+32>>2])&&(_[t+36|0]&&CA(e),f[t+32>>2]=0),f[t+32>>2]=0,f[t+24>>2]=0,f[t+28>>2]=0,f[t+16>>2]=0,n[t+36|0]=1}function tr(t,e){var i,r=0,n=0,a=0,o=0,_=0,h=0,d=0,C=0,g=0,m=0,v=0,y=0,p=0,R=0,D=0,B=0,E=0;Z=i=Z-32|0;t:if(e=(0|e)<=-1?f[t+12>>2]:e,!((0|e)<1)&&(r=f[t>>2],r))for(;;){if(f[(h=r+40|0)>>2])for(y=0;(a=f[r+32>>2])>>>0<=r>>>0?a=r:(_=(0|(o=f[a+40>>2]))==(0|r),g=f[36+((C=((0|r)!=(0|o))<<2)+a|0)>>2],d=t,(n=f[a+32>>2])&&(d=36+(n+((f[n+40>>2]==(0|a))<<2)|0)|0),f[d>>2]=r,f[g+32>>2]=r,f[a+32>>2]=r,f[r+32>>2]=n,f[a+36>>2]=f[r+36>>2],f[a+40>>2]=f[h>>2],f[f[r+36>>2]+32>>2]=a,f[f[h>>2]+32>>2]=a,f[(o=r+36|0)+(_<<2)>>2]=a,f[o+C>>2]=g,h=f[(o=a+24|0)+4>>2],n=i+24|0,R=f[o>>2],f[n>>2]=R,f[n+4>>2]=h,g=f[(n=a+16|0)+4>>2],_=i+16|0,D=f[n>>2],f[_>>2]=D,f[_+4>>2]=g,C=f[(_=a+8|0)+4>>2],m=i+8|0,B=f[_>>2],f[m>>2]=B,f[m+4>>2]=C,m=f[a+4>>2],E=f[a>>2],f[i>>2]=E,f[i+4>>2]=m,v=f[(d=p=r+24|0)+4>>2],f[o>>2]=f[d>>2],f[o+4>>2]=v,v=f[(o=r+16|0)+4>>2],f[n>>2]=f[o>>2],f[n+4>>2]=v,v=f[(n=r+8|0)+4>>2],f[_>>2]=f[n>>2],f[_+4>>2]=v,_=f[r+4>>2],f[a>>2]=f[r>>2],f[a+4>>2]=_,f[p>>2]=R,f[p+4>>2]=h,f[o>>2]=D,f[o+4>>2]=g,f[n>>2]=B,f[n+4>>2]=C,f[r>>2]=E,f[r+4>>2]=m),r=f[t+16>>2]>>>y,y=y+1&31,r=f[36+(((1&r)<<2)+a|0)>>2],f[(h=r+40|0)>>2];);if(d=t,n=0,nr(t,r)&&(n=f[t>>2]),ar(d,n,r),f[t+16>>2]=f[t+16>>2]+1,!(e=e+-1|0))break t;r=f[t>>2]}Z=i+32|0}function nr(t,e){var i=0,r=0,n=v(0),a=v(0),o=v(0),_=0,h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0);if((0|e)==f[t>>2])return f[t>>2]=0,0;i=f[e+32>>2],r=f[36+(((f[i+40>>2]!=(0|e))<<2)+i|0)>>2];t:{if(e=f[i+32>>2])for(f[36+((((0|i)==f[e+40>>2])<<2)+e|0)>>2]=r,f[r+32>>2]=e,CA(f[t+4>>2]),f[t+4>>2]=i;;){if(E=C[e>>2],i=f[e+36>>2],n=C[i>>2],r=f[e+40>>2],n=n<(m=C[r>>2])?n:m,C[e>>2]=n,m=C[e+16>>2],a=(a=C[i+16>>2])>(y=C[r+16>>2])?a:y,C[e+16>>2]=a,y=C[e+4>>2],o=(o=C[i+4>>2])<(p=C[r+4>>2])?o:p,C[e+4>>2]=o,p=C[(_=e+20|0)>>2],h=(h=C[i+20>>2])>(R=C[r+20>>2])?h:R,C[_>>2]=h,R=C[e+8>>2],d=(d=C[i+8>>2])<(D=C[r+8>>2])?d:D,C[e+8>>2]=d,D=C[(_=e+24|0)>>2],g=(g=C[i+24>>2])>(B=C[r+24>>2])?g:B,C[_>>2]=g,!(p!=h|m!=a|E!=n|y!=o)&&R==d&&D==g)break t;if(!(e=f[e+32>>2]))break}else f[r+32>>2]=0,f[t>>2]=r,CA(f[t+4>>2]),f[t+4>>2]=i;e=f[t>>2]}return e}function ar(t,e,i){var r=0,n=v(0),a=v(0),o=v(0),_=0,h=0;if(!f[t>>2])return f[i+32>>2]=0,void(f[t>>2]=i);if(r=f[e+40>>2])for(a=v(C[i>>2]+C[i+16>>2]),n=v(C[i+8>>2]+C[i+24>>2]),o=v(C[i+4>>2]+C[i+20>>2]);h=e+36|0,e=f[e+36>>2],e=f[h+((v(v(v(y(v(a-v(C[e>>2]+C[e+16>>2]))))+v(y(v(o-v(C[e+4>>2]+C[e+20>>2])))))+v(y(v(n-v(C[e+8>>2]+C[e+24>>2])))))>2]+C[r+16>>2]))))+v(y(v(o-v(C[r+4>>2]+C[r+20>>2])))))+v(y(v(n-v(C[r+8>>2]+C[r+24>>2])))))^1)<<2)>>2],r=f[e+40>>2];);h=f[e+32>>2],(r=f[t+4>>2])?f[t+4>>2]=0:(r=dA(44),f[r>>2]=0,f[r+4>>2]=0,f[r+40>>2]=0,f[(_=r+32|0)>>2]=0,f[_+4>>2]=0,f[(_=r+24|0)>>2]=0,f[_+4>>2]=0,f[(_=r+16|0)>>2]=0,f[_+4>>2]=0,f[(_=r+8|0)>>2]=0,f[_+4>>2]=0),f[r+36>>2]=0,f[r+40>>2]=0,a=C[i>>2],n=C[e>>2],C[r>>2]=a>2],n=C[e+16>>2],C[r+16>>2]=a>n?a:n,a=C[i+4>>2],n=C[e+4>>2],C[r+4>>2]=a>2],n=C[e+20>>2],C[r+20>>2]=a>n?a:n,a=C[i+8>>2],n=C[e+8>>2],C[r+8>>2]=a>2]=h,a=C[i+24>>2],n=C[e+24>>2],C[r+24>>2]=a>n?a:n;t:if(h)for(f[36+(((f[f[e+32>>2]+40>>2]==(0|e))<<2)+h|0)>>2]=r,f[r+36>>2]=e,f[e+32>>2]=r,f[r+40>>2]=i,f[i+32>>2]=r,a=C[r>>2];;){if(t=r,!(C[(r=h)>>2]<=a^1|C[r+4>>2]<=C[t+4>>2]^1|C[r+8>>2]<=C[t+8>>2]^1|C[r+16>>2]>=C[t+16>>2]^1)&&C[r+20>>2]>=C[t+20>>2]&&C[r+24>>2]>=C[t+24>>2])break t;if(t=f[r+36>>2],a=C[t>>2],e=f[r+40>>2],a=a<(n=C[e>>2])?a:n,C[r>>2]=a,n=C[t+16>>2],o=C[e+16>>2],C[r+16>>2]=n>o?n:o,n=C[t+4>>2],o=C[e+4>>2],C[r+4>>2]=n>2],o=C[e+20>>2],C[r+20>>2]=n>o?n:o,n=C[t+8>>2],o=C[e+8>>2],C[r+8>>2]=n>2],o=C[e+24>>2],C[r+24>>2]=n>o?n:o,!(h=f[r+32>>2]))break}else f[r+36>>2]=e,f[e+32>>2]=r,f[r+40>>2]=i,f[t>>2]=r,f[i+32>>2]=r}function or(t,e,i){var r=0,n=0,a=0;return(n=f[t+4>>2])?f[t+4>>2]=0:(n=dA(44),f[(r=n)>>2]=0,f[r+4>>2]=0,f[r+40>>2]=0,f[(r=r+32|0)>>2]=0,f[r+4>>2]=0,f[(r=n+24|0)>>2]=0,f[r+4>>2]=0,f[(r=n+16|0)>>2]=0,f[r+4>>2]=0,f[(r=n+8|0)>>2]=0,f[r+4>>2]=0),f[n+36>>2]=i,f[n+32>>2]=0,f[n+40>>2]=0,i=f[e+4>>2],f[n>>2]=f[e>>2],f[n+4>>2]=i,a=f[(r=e+8|0)+4>>2],f[(i=n+8|0)>>2]=f[r>>2],f[i+4>>2]=a,a=f[(r=e+16|0)+4>>2],f[(i=n+16|0)>>2]=f[r>>2],f[i+4>>2]=a,r=f[(e=e+24|0)+4>>2],f[(i=n+24|0)>>2]=f[e>>2],f[i+4>>2]=r,ar(t,f[t>>2],n),f[t+12>>2]=f[t+12>>2]+1,n}function cr(t,e,i){var r=0,n=0,a=0,o=0;t:if(a=nr(t,e))if(r=f[t+8>>2],(0|r)>=0){if(!r)break t;for(;;){if(!(n=f[a+32>>2]))break t;if(a=n,!(r=r+-1|0))break}}else a=f[t>>2];else a=0;n=f[i+4>>2],f[e>>2]=f[i>>2],f[e+4>>2]=n,n=f[(r=i+24|0)+4>>2],f[(o=e+24|0)>>2]=f[r>>2],f[o+4>>2]=n,n=f[(r=i+16|0)+4>>2],f[(o=e+16|0)>>2]=f[r>>2],f[o+4>>2]=n,i=f[(n=i+8|0)+4>>2],f[(r=e+8|0)>>2]=f[n>>2],f[r+4>>2]=i,ar(t,a,e)}function br(t,e){nr(t,e),CA(f[t+4>>2]),f[t+4>>2]=e,f[t+12>>2]=f[t+12>>2]+-1}function lr(t,e){return 1}function ur(t){var e,i;return v((i=(e=t*t)*t)*(e*e)*(2718311493989822e-21*e-.00019839334836096632)+(i*(.008333329385889463*e-.16666666641626524)+t))}function sr(t){var e;return v(-.499999997251031*(t*=t)+1+.04166662332373906*(e=t*t)+t*e*(2439044879627741e-20*t-.001388676377460993))}function kr(t,e){var i=0;t:if((0|e)>=1024){if(t*=898846567431158e293,(0|(i=e+-1023|0))<1024){e=i;break t}t*=898846567431158e293,e=((0|e)<3069?e:3069)+-2046|0}else(0|e)>-1023||(t*=2004168360008973e-307,i=e+969|0,(0|i)>-1023?e=i:(t*=2004168360008973e-307,e=((0|e)>-2960?e:-2960)+1938|0));return b(0,0),b(1,e+1023<<20),t*+l()}function vr(t,e){var i,r,n=0,a=0,o=0,_=0;Z=i=Z-16|0,s(t);t:if((n=2147483647&(r=c(0)))>>>0<=1305022426){if(a=.6366197723675814*(o=+t)+6755399441055744-6755399441055744,g[e>>3]=o+-1.5707963109016418*a+-1.5893254773528196e-8*a,y(a)<2147483648){n=~~a;break t}n=-2147483648}else n>>>0>=2139095040?(g[e>>3]=v(t-t),n=0):(_=n,n=(n>>>23)-150|0,g[i+8>>3]=(b(0,_-(n<<23)|0),k()),n=function(t,e,i){var r,n,a,o,_,h,d,C,v=0,p=0,R=0,D=0,E=0,F=0,V=0,G=0,w=0,Q=0,W=0,Y=0,z=0;if(Z=r=Z-560|0,Q=i+m(a=(0|(D=(i+-3|0)/24|0))>0?D:0,-24)|0,(0|(n=f[2840]))>=0)for(D=n+1|0,E=11376+((i=a)<<2)|0,p=r+320|0;g[p>>3]=(0|i)<0?0:+f[E>>2],p=p+8|0,E=E+4|0,i=i+1|0,D=D+-1|0;);for(G=Q+-24|0,D=r+320|0;;){for(v=0,i=t,E=1,p=D;v+=g[i>>3]*g[p>>3],i=i+8|0,p=p+-8|0,E=E+-1|0;);if(g[(R<<3)+r>>3]=v,D=D+8|0,i=(0|R)<(0|n),R=R+1|0,!i)break}_=23-G|0,o=24-G|0,h=476+(r+(n<<2)|0)|0,d=r+476|0,C=r+-8|0,R=n;e:{for(;;){if(v=g[(i=R<<3)+r>>3],!(D=(0|R)<1))for(i=i+C|0,p=r+480|0,E=R;F=p,W=v,V=y(v*=5.960464477539063e-8)<2147483648?~~v:-2147483648,V=y(W+=-16777216*(v=+(0|V)))<2147483648?~~W:-2147483648,f[F>>2]=V,p=p+4|0,v=g[i>>3]+v,i=i+-8|0,E=E+-1|0;);v=kr(v,G),v+=-8*B(.125*v),v-=+(0|(V=y(v)<2147483648?~~v:-2147483648));i:{A:{r:{if(E=(0|G)<1){if(G)break r;w=f[476+(r+(R<<2)|0)>>2]>>23}else w=p=476+(r+(R<<2)|0)|0,p=(F=f[p>>2])-((i=F>>o)<>2]=p,V=i+V|0,w=p>>_;if((0|w)<1)break i;break A}if(w=2,!(v>=.5)){w=0;break i}}if(D)F=0;else for(F=0,i=r+480|0,D=R;;){p=f[i>>2];A:{r:{if(z=i,F)Y=16777215;else{if(!p)break r;F=1,Y=16777216}f[z>>2]=Y-p;break A}F=0}if(i=i+4|0,!(D=D+-1|0))break}E||((i=G+-1|0)>>>0>1||(i-1?f[(i=476+(r+(R<<2)|0)|0)>>2]=8388607&f[i>>2]:f[(i=476+(r+(R<<2)|0)|0)>>2]=4194303&f[i>>2])),V=V+1|0,2==(0|w)&&(v=1-v,w=2,F&&(v-=kr(1,G)))}if(0!=v)break;if(!((0|R)<=(0|n))){for(i=(R<<2)+d|0,p=0,E=R;p=f[i>>2]|p,i=i+-4|0,(0|(E=E+-1|0))>(0|n););if(p){for(i=476+(r+(R<<2)|0)|0,Q=G;R=R+-1|0,Q=Q+-24|0,t=f[i>>2],i=i+-4|0,!t;);break e}}for(i=h,D=R;D=D+1|0,p=f[i>>2],i=i+-4|0,!p;);for(F=328+((R<<3)+r|0)|0;;){for(i=328+((R<<3)+r|0)|0,R=R+1|0,g[i>>3]=f[11376+(a+R<<2)>>2],v=0,i=t,p=F,E=1;v+=g[i>>3]*g[p>>3],i=i+8|0,p=p+-8|0,E=E+-1|0;);if(g[(R<<3)+r>>3]=v,F=F+8|0,!((0|R)<(0|D)))break}R=D}(v=kr(v,0-G|0))>=16777216?(t=(r+480|0)+(R<<2)|0,W=v,i=y(v*=5.960464477539063e-8)<2147483648?~~v:-2147483648,D=y(v=W+-16777216*+(0|i))<2147483648?~~v:-2147483648,f[t>>2]=D,R=R+1|0):(i=y(v)<2147483648?~~v:-2147483648,Q=G),f[(r+480|0)+(R<<2)>>2]=i}if(!((0|R)<0)){for(E=R+1|0,v=kr(1,Q),i=(r+480|0)+(R<<2)|0,p=(R<<3)+r|0;g[p>>3]=v*+f[i>>2],i=i+-4|0,p=p+-8|0,v*=5.960464477539063e-8,(0|(E=E+-1|0))>0;);if(!((0|R)<0))for(D=(R<<3)+r|0,i=R;;){for(t=i,E=R-i|0,v=0,i=0,p=0;v+=g[i+14144>>3]*g[i+D>>3],!((0|p)>=(0|n))&&(i=i+8|0,G=p>>>0>>0,p=p+1|0,G););if(g[(r+160|0)+(E<<3)>>3]=v,D=D+-8|0,i=t+-1|0,!((0|t)>0))break}}if((0|R)<0)v=0;else for(p=R+1|0,i=(r+160|0)+(R<<3)|0,v=0;v+=g[i>>3],i=i+-8|0,(0|(p=p+-1|0))>0;);return g[e>>3]=w?-v:v,Z=r+560|0,7&V}(i+8|0,i,n),a=g[i>>3],(0|r)<=-1?(g[e>>3]=-a,n=0-n|0):g[e>>3]=a);return Z=i+16|0,n}function dr(t){var e,i=0,r=0,n=0;Z=e=Z-16|0,s(t);t:if((i=2147483647&(r=c(0)))>>>0<=1061752794){if(i>>>0<964689920)break t;t=ur(+t)}else if(r>>>=31,i>>>0<=1081824209){if(n=+t,i>>>0<=1075235811){if(r){t=v(-sr(n+1.5707963267948966));break t}t=sr(n+-1.5707963267948966);break t}t=ur(-((r?3.141592653589793:-3.141592653589793)+n))}else if(i>>>0<=1088565717){if(n=+t,i>>>0<=1085271519){if(r){t=sr(n+4.71238898038469);break t}t=v(-sr(n+-4.71238898038469));break t}t=ur((r?6.283185307179586:-6.283185307179586)+n)}else if(i>>>0>=2139095040)t=v(t-t);else if(i=3&vr(t,e+8|0),i>>>0<=2){switch(i-1|0){default:t=ur(g[e+8>>3]);break t;case 0:t=sr(g[e+8>>3]);break t;case 1:}t=ur(-g[e+8>>3])}else t=v(-sr(g[e+8>>3]));return Z=e+16|0,t}function Cr(t){var e,i=v(0),r=0,n=0,a=0;Z=e=Z-16|0,s(t);t:if((r=2147483647&(n=c(0)))>>>0<=1061752794){if(i=v(1),r>>>0<964689920)break t;i=sr(+t)}else if(n>>>=31,r>>>0<=1081824209){if(a=+t,r>>>0>=1075235812){i=v(-sr((n?3.141592653589793:-3.141592653589793)+a));break t}if(n){i=ur(a+1.5707963267948966);break t}i=ur(1.5707963267948966-a)}else if(r>>>0<=1088565717){if(r>>>0>=1085271520){i=sr(+t+(n?6.283185307179586:-6.283185307179586));break t}if(n){i=ur(-4.71238898038469-+t);break t}i=ur(+t-4.71238898038469)}else if(i=v(t-t),!(r>>>0>=2139095040))if(r=3&vr(t,e+8|0),r>>>0<=2){switch(r-1|0){default:i=sr(g[e+8>>3]);break t;case 0:i=ur(-g[e+8>>3]);break t;case 1:}i=v(-sr(g[e+8>>3]))}else i=ur(g[e+8>>3]);return Z=e+16|0,t=i}function Br(t,e){var i,r,n,a,o,_,h=0,d=0,C=0,g=0,v=0,y=0,p=0,R=0,D=0,B=0,E=0,F=0;Z=i=Z-80|0,f[t+72>>2]=f[t+72>>2]+1,(h=f[t+68>>2])&&br(h,f[76+(f[t+28>>2]+m(e,80)|0)>>2]),d=f[t+20>>2],B=f[(o=t+28|0)>>2],_=m(e,80),y=f[(C=(h=B+_|0)+8|0)+4>>2],f[(v=i+8|0)>>2]=f[C>>2],f[v+4>>2]=y,E=f[(p=h+24|0)+4>>2],f[(y=n=i+24|0)>>2]=f[p>>2],f[y+4>>2]=E,D=f[(R=a=h+40|0)+4>>2],f[(y=i+40|0)>>2]=f[R>>2],f[y+4>>2]=D,g=f[(R=h+56|0)+4>>2],f[(D=E=i+56|0)>>2]=f[R>>2],f[D+4>>2]=g,F=f[(r=h+72|0)+4>>2],f[(g=D=i+72|0)>>2]=f[r>>2],f[g+4>>2]=F,g=f[h+4>>2],f[i>>2]=f[h>>2],f[i+4>>2]=g,g=f[h+20>>2],f[i+16>>2]=f[h+16>>2],f[i+20>>2]=g,g=f[h+36>>2],f[i+32>>2]=f[h+32>>2],f[i+36>>2]=g,g=f[h+52>>2],f[i+48>>2]=f[h+48>>2],f[i+52>>2]=g,g=f[h+68>>2],f[i+64>>2]=f[h+64>>2],f[i+68>>2]=g,g=B,B=m(d,80)+-80|0,F=f[(g=(d=g+B|0)+8|0)+4>>2],f[C>>2]=f[g>>2],f[C+4>>2]=F,C=f[d+4>>2],f[h>>2]=f[d>>2],f[h+4>>2]=C,g=f[(C=d+24|0)+4>>2],f[p>>2]=f[C>>2],f[p+4>>2]=g,C=f[d+20>>2],f[h+16>>2]=f[d+16>>2],f[h+20>>2]=C,p=f[(C=d+40|0)+4>>2],f[a>>2]=f[C>>2],f[a+4>>2]=p,C=f[d+36>>2],f[h+32>>2]=f[d+32>>2],f[h+36>>2]=C,p=f[(C=d+56|0)+4>>2],f[R>>2]=f[C>>2],f[R+4>>2]=p,C=f[d+52>>2],f[h+48>>2]=f[d+48>>2],f[h+52>>2]=C,C=f[d+68>>2],f[h+64>>2]=f[d+64>>2],f[h+68>>2]=C,d=f[(h=d+72|0)+4>>2],f[r>>2]=f[h>>2],f[r+4>>2]=d,C=f[i+4>>2],h=f[o>>2]+B|0,f[h>>2]=f[i>>2],f[h+4>>2]=C,C=f[v+4>>2],f[(d=h+8|0)>>2]=f[v>>2],f[d+4>>2]=C,d=f[i+20>>2],f[h+16>>2]=f[i+16>>2],f[h+20>>2]=d,v=f[n+4>>2],f[(d=h+24|0)>>2]=f[n>>2],f[d+4>>2]=v,d=f[i+36>>2],f[h+32>>2]=f[i+32>>2],f[h+36>>2]=d,v=f[y+4>>2],f[(d=h+40|0)>>2]=f[y>>2],f[d+4>>2]=v,d=f[i+52>>2],f[h+48>>2]=f[i+48>>2],f[h+52>>2]=d,v=f[E+4>>2],f[(d=h+56|0)>>2]=f[E>>2],f[d+4>>2]=v,v=f[D+4>>2],f[(d=h+72|0)>>2]=f[D>>2],f[d+4>>2]=v,d=f[i+68>>2],f[h+64>>2]=f[i+64>>2],f[h+68>>2]=d,f[t+68>>2]&&(f[f[76+(f[t+28>>2]+_|0)>>2]+36>>2]=e),f[t+20>>2]=f[t+20>>2]+-1,Z=i+80|0}function _r(t){var e;return f[(t|=0)>>2]=14564,(e=f[t+32>>2])&&(_[t+36|0]&&CA(e),f[t+32>>2]=0),f[t+32>>2]=0,f[t+24>>2]=0,f[t+28>>2]=0,n[t+36|0]=1,0|t}function mr(t,e,i,r,n,a,o,_,h,d){e|=0,i|=0,r|=0,n|=0,a|=0,o|=0,_|=0,h|=0,d|=0,t=f[(t|=0)+32>>2]+(d<<5)|0,f[i>>2]=f[t+12>>2],f[n>>2]=f[t+20>>2],f[e>>2]=f[t+16>>2],f[r>>2]=f[t+28>>2],f[_>>2]=f[t>>2],f[a>>2]=f[t+4>>2],f[h>>2]=f[t+24>>2],f[o>>2]=f[t+8>>2]}function Rr(t,e){}function Qr(t,e){var i=0,r=0,o=0,d=0,C=0,g=0,m=0;if(_[t+164|0]){if((0|(i=f[t+128>>2]))==f[t+132>>2]&&!((0|i)>=(0|(d=i?i<<1:1)))){d&&(r=dA(d<<2),i=f[t+128>>2]),g=f[t+136>>2];t:{if((0|i)>=1)for(o=r,C=g;f[o>>2]=f[C>>2],o=o+4|0,C=C+4|0,i=i+-1|0;);else if(!g)break t;_[t+140|0]&&CA(g),f[t+136>>2]=0,i=f[t+128>>2]}f[t+136>>2]=r,f[t+132>>2]=d,n[t+140|0]=1}return o=f[t+136>>2],f[o+(i<<2)>>2]=e,f[f[t+32>>2]+4>>2]=o,void(f[t+128>>2]=f[t+128>>2]+1)}if((0|(r=f[t+148>>2]))==f[t+152>>2]&&!((0|r)>=(0|(m=r?r<<1:1)))){m&&(g=dA(m<<1),r=f[t+148>>2]),d=f[t+156>>2];t:{if((0|r)>=1)for(o=g,C=d,i=r;a[o>>1]=h[C>>1],o=o+2|0,C=C+2|0,i=i+-1|0;);else if(!d)break t;_[t+160|0]&&(CA(d),r=f[t+148>>2]),f[t+156>>2]=0}f[t+156>>2]=g,f[t+152>>2]=m,n[t+160|0]=1}f[t+148>>2]=r+1,o=f[t+32>>2],t=f[t+156>>2],f[o+4>>2]=t,a[t+(r<<1)>>1]=e}function hr(t,e,i){var r=0,a=0,o=0,h=0,d=0,g=0,m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0);t:{if(_[t+165|0]){if(!(!i|(0|(o=f[t+88>>2]))<1))for(i=f[t+96>>2],p=C[t+168>>2],R=C[e+8>>2],D=C[e+4>>2],B=C[e>>2];;){if(m=v(C[i>>2]-B),y=v(m*m),m=v(C[i+4>>2]-D),y=v(y+v(m*m)),m=v(C[i+8>>2]-R),v(y+v(m*m))<=p)break t;if(i=i+16|0,!((0|(h=h+1|0))<(0|o)))break}if(i=f[t+32>>2],f[i+12>>2]=f[i+12>>2]+1,f[t+92>>2]==(0|o)&&!((0|o)>=(0|(h=o?o<<1:1)))){if(h&&(r=dA(h<<4),o=f[t+88>>2]),(0|o)>=1)for(i=0;a=f[t+96>>2]+i|0,g=f[a+4>>2],f[(d=i+r|0)>>2]=f[a>>2],f[d+4>>2]=g,g=f[(a=a+8|0)+4>>2],f[(d=d+8|0)>>2]=f[a>>2],f[d+4>>2]=g,i=i+16|0,o=o+-1|0;);(i=f[t+96>>2])&&(_[t+100|0]&&CA(i),f[t+96>>2]=0),f[t+96>>2]=r,f[t+92>>2]=h,n[t+100|0]=1,o=f[t+88>>2]}return i=f[e+4>>2],r=f[(g=t+96|0)>>2]+(o<<4)|0,f[r>>2]=f[e>>2],f[r+4>>2]=i,e=f[(i=e+8|0)+4>>2],f[(r=r+8|0)>>2]=f[i>>2],f[r+4>>2]=e,f[f[t+32>>2]+16>>2]=f[g>>2],e=t,t=f[t+88>>2],f[e+88>>2]=t+1,t}if(!(!i|(0|(a=f[t+108>>2]))<1))for(i=f[t+116>>2],p=C[t+168>>2],R=C[e+8>>2],D=C[e+4>>2],B=C[e>>2];;){if(m=v(C[i>>2]-B),y=v(m*m),m=v(C[i+4>>2]-D),y=v(y+v(m*m)),m=v(C[i+8>>2]-R),v(y+v(m*m))<=p)break t;if(i=i+12|0,h=h+1|0,!((0|(o=o+3|0))<(0|a)))break}if((0|a)==(0|(r=f[t+112>>2])))if((0|a)>=(0|(r=a?a<<1:1)))r=a;else{r&&(g=dA(r<<2),a=f[t+108>>2]),d=f[t+116>>2];e:{if((0|a)>=1)for(i=g,h=d,o=a;f[i>>2]=f[h>>2],i=i+4|0,h=h+4|0,o=o+-1|0;);else if(!d)break e;_[t+120|0]&&(CA(d),a=f[t+108>>2]),f[t+116>>2]=0}f[t+116>>2]=g,f[t+112>>2]=r,n[t+120|0]=1}if(i=a+1|0,f[t+108>>2]=i,d=f[t+116>>2],f[d+(a<<2)>>2]=f[e>>2],(0|i)==(0|r))if((0|r)>=(0|(a=r?r<<1:1)))g=d,a=r;else{a?(g=dA(a<<2),d=f[t+116>>2],r=f[t+108>>2]):g=0;e:{if((0|r)>=1)for(i=g,h=d,o=r;f[i>>2]=f[h>>2],i=i+4|0,h=h+4|0,o=o+-1|0;);else if(!d)break e;_[t+120|0]&&(CA(d),r=f[t+108>>2]),f[t+116>>2]=0}f[t+116>>2]=g,f[t+112>>2]=a,n[t+120|0]=1}else g=d,a=r,r=i;if(i=r+1|0,f[t+108>>2]=i,f[(r<<2)+g>>2]=f[e+4>>2],(0|i)==(0|a))if((0|a)>=(0|(d=a?a<<1:1)))r=g;else{d?(r=dA(d<<2),g=f[t+116>>2],a=f[t+108>>2]):r=0;e:{if((0|a)>=1)for(i=r,h=g,o=a;f[i>>2]=f[h>>2],i=i+4|0,h=h+4|0,o=o+-1|0;);else if(!g)break e;_[t+120|0]&&(CA(g),a=f[t+108>>2]),f[t+116>>2]=0}f[t+116>>2]=r,f[t+112>>2]=d,n[t+120|0]=1}else r=g,a=i;i=a+1|0,f[t+108>>2]=i,f[(a<<2)+r>>2]=f[e+8>>2],t=f[t+32>>2],f[t+16>>2]=r,f[t+12>>2]=f[t+12>>2]+1,h=((0|i)/3|0)-1|0}return h}function Gr(t){var e=0;return f[(t|=0)>>2]=14676,(e=f[t+156>>2])&&(_[t+160|0]&&CA(e),f[t+156>>2]=0),f[t+156>>2]=0,f[t+148>>2]=0,f[t+152>>2]=0,n[t+160|0]=1,(e=f[t+136>>2])&&(_[t+140|0]&&CA(e),f[t+136>>2]=0),f[t+136>>2]=0,f[t+128>>2]=0,f[t+132>>2]=0,n[t+140|0]=1,(e=f[t+116>>2])&&(_[t+120|0]&&CA(e),f[t+116>>2]=0),f[t+116>>2]=0,f[t+108>>2]=0,f[t+112>>2]=0,n[t+120|0]=1,(e=f[t+96>>2])&&(_[t+100|0]&&CA(e),f[t+96>>2]=0),f[t+96>>2]=0,f[t+88>>2]=0,f[t+92>>2]=0,n[t+100|0]=1,_r(t),0|t}function yr(t,e,i){var r,n,a,o=0,_=0,h=v(0),d=v(0),g=0,y=0,p=v(0),R=v(0),D=0,B=v(0),F=v(0),V=0,G=v(0),w=0,Q=0,W=0,Y=0,z=0,yt=v(0),pt=v(0),Dt=v(0),It=v(0),St=0;Z=r=Z-96|0,f[t+376>>2]=0,f[t+364>>2]=4,f[t+368>>2]=0,g=t+316|0,f[t+360>>2]=g,f[t+356>>2]=t+284,f[t+352>>2]=t+252,f[t+348>>2]=t+220,_=f[e+4>>2],f[t>>2]=f[e>>2],f[t+4>>2]=_,y=f[(o=e+16|0)+4>>2],f[(_=t+16|0)>>2]=f[o>>2],f[_+4>>2]=y,_=f[e+12>>2],f[t+8>>2]=f[e+8>>2],f[t+12>>2]=_,y=f[(o=e+32|0)+4>>2],f[(_=t+32|0)>>2]=f[o>>2],f[_+4>>2]=y,y=f[(o=e+24|0)+4>>2],f[(_=t+24|0)>>2]=f[o>>2],f[_+4>>2]=y,y=f[(o=e+48|0)+4>>2],f[(_=t+48|0)>>2]=f[o>>2],f[_+4>>2]=y,y=f[(o=e+40|0)+4>>2],f[(_=t+40|0)>>2]=f[o>>2],f[_+4>>2]=y,y=f[(o=e- -64|0)+4>>2],f[(_=t- -64|0)>>2]=f[o>>2],f[_+4>>2]=y,_=f[e+60>>2],f[t+56>>2]=f[e+56>>2],f[t+60>>2]=_,y=f[(o=e+80|0)+4>>2],f[(_=t+80|0)>>2]=f[o>>2],f[_+4>>2]=y,y=f[(o=e+72|0)+4>>2],f[(_=t+72|0)>>2]=f[o>>2],f[_+4>>2]=y,y=f[(o=e+96|0)+4>>2],f[(_=t+96|0)>>2]=f[o>>2],f[_+4>>2]=y,y=f[(o=e+88|0)+4>>2],f[(_=t+88|0)>>2]=f[o>>2],f[_+4>>2]=y,y=f[(o=e+104|0)+4>>2],f[(_=t+104|0)>>2]=f[o>>2],f[_+4>>2]=y,y=f[(o=e+112|0)+4>>2],f[(_=t+112|0)>>2]=f[o>>2],f[_+4>>2]=y,_=f[e+120>>2],e=f[e+124>>2],f[t+180>>2]=0,f[t+144>>2]=0,f[t+120>>2]=_,f[t+124>>2]=e,y=f[(o=i+8|0)+4>>2],f[(e=t+136|0)>>2]=f[o>>2],f[e+4>>2]=y,_=f[i+4>>2],f[t+128>>2]=f[i>>2],f[t+132>>2]=_,_=t+128|0,h=C[t+128>>2],p=C[t+132>>2],R=C[e>>2],(F=v(v(v(h*h)+v(p*p))+v(R*R)))>v(0)?(C[r+40>>2]=-R,C[r+36>>2]=-p,C[r+32>>2]=-h):(f[r+40>>2]=0,f[r+32>>2]=1065353216,f[r+36>>2]=0),f[t+364>>2]=3,f[t+180>>2]=1,f[t+148>>2]=g,f[(e=t+164|0)>>2]=0,f[r+44>>2]=0,pr(t,r+32|0,g),f[e>>2]=1065353216,e=f[t+148>>2],i=f[e+20>>2],f[_>>2]=f[e+16>>2],f[_+4>>2]=i,o=f[(g=e+24|0)+4>>2],f[(i=n=_+8|0)>>2]=f[g>>2],f[i+4>>2]=o,i=f[g+4>>2],y=r+88|0,o=f[g>>2],f[y>>2]=o,f[y+4>>2]=i,f[(g=r+72|0)>>2]=o,f[g+4>>2]=i,f[(g=r+56|0)>>2]=o,f[g+4>>2]=i,g=f[e+20>>2],e=f[e+16>>2],f[r+80>>2]=e,f[r+84>>2]=g,f[r+64>>2]=e,f[r+68>>2]=g,f[r+48>>2]=e,f[r+52>>2]=g,f[r+32>>2]=e,f[r+36>>2]=g,f[r+40>>2]=o,f[r+44>>2]=i,a=t+148|0,g=f[t+368>>2],h=C[t+136>>2],p=C[t+132>>2],R=C[t+128>>2],y=0;t:{e:{i:{for(;;){if((G=v(E(v(v(v(R*R)+v(p*p))+v(h*h)))))>2]=1;break i}if(D=f[t+364>>2]+-1|0,f[t+364>>2]=D,w=m(g,36),i=f[(o=(e=w+t|0)+180|0)>>2],f[o>>2]=i+1,V=(V=i<<2)+(i=e+148|0)|0,D=f[348+((D<<2)+t|0)>>2],f[V>>2]=D,f[V+16>>2]=0,f[r+28>>2]=0,C[r+24>>2]=-h,C[r+20>>2]=-p,C[r+16>>2]=-R,pr(t,r+16|0,D),W=f[o>>2],D=f[(i+(W<<2)|0)-4>>2],h=C[D+16>>2],p=v(h-C[r+32>>2]),d=v(p*p),p=C[D+20>>2],R=v(p-C[r+36>>2]),B=v(d+v(R*R)),R=C[D+24>>2],d=v(R-C[r+40>>2]),!(v(B+v(d*d))>2]),B=v(d*d),d=v(p-C[r+52>>2]),B=v(B+v(d*d)),d=v(R-C[r+56>>2]),v(B+v(d*d))>2]),B=v(d*d),d=v(p-C[r+68>>2]),B=v(B+v(d*d)),d=v(R-C[r+72>>2]),v(B+v(d*d))>2]),B=v(d*d),d=v(p-C[r+84>>2]),B=v(B+v(d*d)),d=v(R-C[r+88>>2]),v(B+v(d*d))>2],f[(V=(r+32|0)+((St=St+1&3)<<4)|0)+8>>2]=f[Q>>2],f[V+12>>2]=Y,z=f[D+4>>2],f[V>>2]=f[D>>2],f[V+4>>2]=z,h=v(v(v(v(C[t+128>>2]*h)+v(C[t+132>>2]*p))+v(C[t+136>>2]*R))/G),v(v(G-(yt=h>yt?h:yt))+v(G*v(-9999999747378752e-20)))<=v(0)){i=f[t+364>>2],f[t+364>>2]=i+1,g=f[t+368>>2],_=m(g,36)+t|0,e=f[(o=_+180|0)>>2]+-1|0,f[o>>2]=e,f[348+((i<<2)+t|0)>>2]=f[148+(_+(e<<2)|0)>>2];break i}f[r+12>>2]=0;A:{r:{n:if(!((D=W+-2|0)>>>0>2)){switch(D-1|0){default:if(e=f[e+152>>2],pt=C[e+16>>2],i=f[i>>2],F=C[i+16>>2],G=v(pt-F),Dt=C[e+20>>2],p=C[i+20>>2],d=v(Dt-p),It=C[e+24>>2],R=C[i+24>>2],B=v(It-R),!((h=v(v(v(G*G)+v(d*d))+v(B*B)))>v(0)))break r;if((h=v(v(-v(v(v(F*G)+v(p*d))+v(R*B)))/h))>=v(1)){f[r+16>>2]=0,f[r+20>>2]=1065353216,f[r+12>>2]=2,F=v(v(v(pt*pt)+v(Dt*Dt))+v(It*It));break n}if(h<=v(0)){f[r+16>>2]=1065353216,f[r+20>>2]=0,f[r+12>>2]=1,F=v(v(v(F*F)+v(p*p))+v(R*R));break n}f[r+12>>2]=3,C[r+20>>2]=h,C[r+16>>2]=v(1)-h,R=v(R+v(B*h)),F=v(F+v(G*h)),h=v(p+v(d*h)),F=v(v(R*R)+v(v(F*F)+v(h*h)));break n;case 0:F=Fr(f[i>>2]+16|0,f[e+152>>2]+16|0,f[e+156>>2]+16|0,r+16|0,r+12|0);break n;case 1:}F=Wr(f[i>>2]+16|0,f[e+152>>2]+16|0,f[e+156>>2]+16|0,f[e+160>>2]+16|0,r+16|0,r+12|0)}if(F>=v(0)){if(W=m(g=1-g|0,36)+t|0,f[(D=W+180|0)>>2]=0,f[n>>2]=0,f[n+4>>2]=0,f[_>>2]=0,f[_+4>>2]=0,f[t+368>>2]=g,V=f[r+12>>2],!(z=f[o>>2])){h=v(0),p=v(0),R=v(0);break A}for(e=w+a|0,i=0,h=v(0),o=r+16|0,p=v(0),R=v(0);w=f[e>>2],1<>2],f[(Y=(Q<<2)+W|0)+148>>2]=w,h=C[o>>2],f[Y+164>>2]=f[o>>2],f[D>>2]=Q+1,w=f[e>>2],G=C[w+24>>2],p=C[w+20>>2],R=v(v(C[w+16>>2]*h)+C[t+128>>2]),C[t+128>>2]=R,p=v(v(p*h)+C[t+132>>2]),C[t+132>>2]=p,h=v(v(G*h)+C[t+136>>2]),C[t+136>>2]=h):(Q=f[t+364>>2],f[t+364>>2]=Q+1,f[348+((Q<<2)+t|0)>>2]=w),e=e+4|0,o=o+4|0,(0|(i=i+1|0))!=(0|z););break A}}i=f[t+364>>2],f[t+364>>2]=i+1,g=f[t+368>>2],_=m(g,36)+t|0,e=f[(o=_+180|0)>>2]+-1|0,f[o>>2]=e,f[348+((i<<2)+t|0)>>2]=f[148+(_+(e<<2)|0)>>2];break i}if(15==(0|V)&&(f[t+376>>2]=1),127==(0|y)){e=2,f[t+376>>2]=2,f[t+372>>2]=148+(m(g,36)+t|0);break t}if(y=y+1|0,!(e=f[t+376>>2]))continue;break e}break}i=f[t+364>>2],f[t+364>>2]=i+1,g=f[t+368>>2],_=m(g,36)+t|0,e=f[(o=_+180|0)>>2]+-1|0,f[o>>2]=e,f[348+((i<<2)+t|0)>>2]=f[148+(_+(e<<2)|0)>>2]}e=f[t+376>>2]}f[t+372>>2]=148+(m(g,36)+t|0),e>>>0>1||(e-1?(h=C[t+128>>2],p=v(h*h),h=C[t+132>>2],p=v(p+v(h*h)),h=C[t+136>>2],C[t+144>>2]=E(v(p+v(h*h))),e=0):(f[t+144>>2]=0,e=1))}return Z=r+96|0,e}function pr(t,e,i){var r,n,a,o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0);Z=r=Z-48|0,o=C[e+8>>2],_=C[e>>2],h=C[e+4>>2],f[i+12>>2]=0,d=o,o=v(v(1)/v(E(v(v(v(_*_)+v(h*h))+v(o*o))))),C[i+8>>2]=d*o,C[i+4>>2]=h*o,C[i>>2]=_*o,e=f[t+120>>2],n=f[t+124>>2],a=f[t>>2]+(n>>1)|0,yt[1&n?f[f[a>>2]+e>>2]:e](r+32|0,a,i),f[r+12>>2]=0,C[r+8>>2]=-C[i+8>>2],C[r+4>>2]=-C[i+4>>2],C[r>>2]=-C[i>>2],function(t,e,i){var r,n,a,o=v(0),_=v(0),h=v(0),d=0;Z=r=Z-32|0,n=f[e+124>>2],a=f[e+4>>2]+(n>>1)|0,d=f[e+120>>2],d=1&n?f[f[a>>2]+d>>2]:d,f[r+12>>2]=0,o=C[i>>2],_=C[i+4>>2],h=C[i+8>>2],C[r+8>>2]=v(v(o*C[e+40>>2])+v(_*C[e+44>>2]))+v(h*C[e+48>>2]),C[r+4>>2]=v(v(o*C[e+24>>2])+v(_*C[e+28>>2]))+v(h*C[e+32>>2]),C[r>>2]=v(v(o*C[e+8>>2])+v(_*C[e+12>>2]))+v(h*C[e+16>>2]),yt[d](r+16|0,a,r),f[t+12>>2]=0,o=C[r+16>>2],_=C[r+20>>2],h=C[r+24>>2],C[t+8>>2]=v(v(v(o*C[e+88>>2])+v(_*C[e+92>>2]))+v(h*C[e+96>>2]))+C[e+112>>2],C[t+4>>2]=v(v(v(o*C[e+72>>2])+v(_*C[e+76>>2]))+v(h*C[e+80>>2]))+C[e+108>>2],C[t>>2]=v(v(v(o*C[e+56>>2])+v(_*C[e+60>>2]))+v(h*C[e- -64>>2]))+C[e+104>>2],Z=r+32|0}(r+16|0,t,r),o=C[r+16>>2],_=C[r+32>>2],h=C[r+20>>2],d=C[r+36>>2],g=C[r+24>>2],m=C[r+40>>2],f[i+28>>2]=0,C[i+24>>2]=m-g,C[i+20>>2]=d-h,C[i+16>>2]=_-o,Z=r+48|0}function Fr(t,e,i,r,n){var a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),F=v(0),V=v(0),G=v(0),w=0,Q=v(0),W=v(0),Y=0,Z=0,z=v(0),yt=v(0),pt=v(0),Dt=v(0),It=v(0);return o=v(-1),d=C[t>>2],h=C[e>>2],a=v(d-h),_=C[e+4>>2],G=C[i+4>>2],yt=v(_-G),F=C[t+4>>2],D=v(F-_),Q=C[i>>2],pt=v(h-Q),m=v(v(a*yt)-v(D*pt)),g=C[e+8>>2],W=C[i+8>>2],Dt=v(g-W),V=C[t+8>>2],y=v(V-g),p=v(v(D*Dt)-v(y*yt)),R=v(v(y*pt)-v(a*Dt)),(It=v(v(m*m)+v(v(p*p)+v(R*R))))>v(0)&&(v(v(v(d*v(v(m*D)-v(R*y)))+v(F*v(v(p*y)-v(m*a))))+v(v(v(R*a)-v(p*D))*V))>v(0)?(D=v(h-d),y=v(_-F),B=v(g-V),o=v(v(v(D*D)+v(y*y))+v(B*B)),a=v(-1),o>v(0)&&((o=v(v(-v(v(v(d*D)+v(F*y))+v(V*B)))/o))>=v(1)?(Y=1065353216,w=2,a=v(v(v(h*h)+v(_*_))+v(g*g))):(w=1,o<=v(0)?(Z=1065353216,a=v(v(v(d*d)+v(F*F))+v(V*V))):(s(v(v(1)-o)),Z=c(0),s(o),Y=c(0),w=3,a=v(V+v(B*o)),h=v(a*a),a=v(d+v(D*o)),_=v(a*a),a=v(F+v(y*o)),a=v(h+v(_+v(a*a)))))),f[r+8>>2]=0,f[r+4>>2]=Y,f[r>>2]=Z,f[n>>2]=w,g=C[e+8>>2],_=C[e+4>>2],h=C[e>>2]):a=v(-1),V=v(W-V),F=v(G-F),D=v(Q-d),v(v(v(h*v(v(m*yt)-v(R*Dt)))+v(_*v(v(p*Dt)-v(m*pt))))+v(v(v(R*pt)-v(p*yt))*g))>v(0)?(Q=C[i>>2],y=v(Q-h),W=C[i+4>>2],B=v(W-_),z=C[i+8>>2],G=v(z-g),d=v(v(v(y*y)+v(B*B))+v(G*G)),o=v(-1),d>v(0)&&((d=v(v(-v(v(v(h*y)+v(_*B))+v(g*G)))/d))>=v(1)?(Y=1065353216,Z=0,w=2,o=v(v(v(Q*Q)+v(W*W))+v(z*z))):(w=1,d<=v(0)?(Y=0,Z=1065353216,o=v(v(v(h*h)+v(_*_))+v(g*g))):(s(v(v(1)-d)),Z=c(0),s(d),Y=c(0),w=3,o=v(g+v(G*d)),g=v(o*o),o=v(h+v(y*d)),h=v(o*o),o=v(_+v(B*d)),o=v(g+v(h+v(o*o)))))),!!(o>2]=Y,f[r+4>>2]=Z,f[r>>2]=0,f[n>>2]=w<<1):o=a):o=a,_=C[i>>2],g=C[i+4>>2],d=C[i+8>>2],v(v(v(_*v(v(m*F)-v(R*V)))+v(g*v(v(p*V)-v(m*D))))+v(v(v(R*D)-v(p*F))*d))>v(0)&&(Q=C[t>>2],y=v(Q-_),W=C[t+4>>2],B=v(W-g),z=C[t+8>>2],G=v(z-d),h=v(v(v(y*y)+v(B*B))+v(G*G)),a=v(-1),h>v(0)&&((h=v(v(-v(v(v(_*y)+v(g*B))+v(d*G)))/h))>=v(1)?(Y=1065353216,Z=0,w=2,a=v(v(v(Q*Q)+v(W*W))+v(z*z))):h<=v(0)?(Y=0,Z=1065353216,w=1,a=v(v(v(_*_)+v(g*g))+v(d*d))):(s(v(v(1)-h)),Z=c(0),s(h),Y=c(0),w=3,a=v(d+v(G*h)),d=v(a*a),a=v(_+v(y*h)),_=v(a*a),a=v(g+v(B*h)),a=v(d+v(_+v(a*a))))),a>2]=Z,f[r+4>>2]=0,f[r>>2]=Y,f[n>>2]=5&(w<<2|w>>>1),o=a)),o>2])+v(R*C[t+4>>2]))+v(m*C[t+8>>2]))/It),o=v(R*h),_=v(C[e+4>>2]-o),a=v(p*h),g=v(C[e>>2]-a),p=v(v(pt*_)-v(yt*g)),h=v(m*h),m=v(C[e+8>>2]-h),_=v(v(yt*m)-v(Dt*_)),d=v(_*_),_=v(v(Dt*g)-v(pt*m)),d=v(E(v(v(p*p)+v(d+v(_*_))))),_=v(E(It)),g=v(d/_),C[r>>2]=g,f[n>>2]=7,m=v(C[i+4>>2]-o),p=v(C[i>>2]-a),R=v(v(D*m)-v(F*p)),d=v(R*R),R=v(C[i+8>>2]-h),m=v(v(F*R)-v(V*m)),y=v(m*m),m=v(v(V*p)-v(D*R)),_=v(v(E(v(d+v(y+v(m*m)))))/_),C[r+4>>2]=_,C[r+8>>2]=v(1)-v(g+_),o=v(v(h*h)+v(v(a*a)+v(o*o))))),o}function Wr(t,e,i,r,n,a){var o,_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=0,F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),yt=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0);return Z=o=Z-96|0,f[o+92>>2]=r,f[o+88>>2]=i,f[o+84>>2]=e,f[o+80>>2]=t,f[o+60>>2]=0,Q=C[e+8>>2],G=C[r+8>>2],m=v(Q-G),C[o+56>>2]=m,W=C[e+4>>2],w=C[r+4>>2],Y=v(W-w),C[o+52>>2]=Y,f[o+44>>2]=0,z=C[t+8>>2],R=v(z-G),C[o+40>>2]=R,It=C[t+4>>2],B=v(It-w),C[o+36>>2]=B,St=C[t>>2],Dt=C[r>>2],F=v(St-Dt),C[o+32>>2]=F,yt=C[e>>2],_=v(yt-Dt),C[o+48>>2]=_,pt=C[i>>2],y=C[i+4>>2],Tt=C[i+8>>2],f[o+76>>2]=0,h=v(Tt-G),C[o+72>>2]=h,g=v(y-w),C[o+68>>2]=g,p=v(pt-Dt),C[o+64>>2]=p,d=v(-1),Et=v(F*Y),Ot=v(B*m),Nt=v(R*_),Ft=v(F*m),V=v(B*_),Y=v(R*Y),(m=v(v(v(Et*h)+v(v(v(v(Ot*p)+v(Nt*g))-v(Ft*g))-v(V*h)))-v(Y*p)))==v(0)|m!=m||(D=v(It-W),pt=v(yt-pt),yt=v(St-yt),W=v(W-y),y=v(z*v(v(D*pt)-v(yt*W))),z=v(z-Q),Q=v(Q-Tt),v(m*v(y+v(v(St*v(v(z*W)-v(D*Q)))+v(It*v(v(yt*Q)-v(z*pt))))))<=v(0)&&(f[o+24>>2]=0,f[o+16>>2]=0,f[o+20>>2]=0,f[o+12>>2]=0,v(m*v(v(v(v(Ot-Y)*Dt)+v(w*v(Nt-Ft)))+v(v(Et-V)*G)))>v(0)&&(d=Fr(f[o+80>>2],f[o+84>>2],r,o+16|0,o+12|0),f[n+8>>2]=0,E=f[o+20>>2],f[n>>2]=f[o+16>>2],f[n+4>>2]=E,f[n+12>>2]=f[o+24>>2],E=f[o+12>>2],f[a>>2]=2&E|E<<1&8|1&E),G=C[o+52>>2],w=C[o+56>>2],v(m*v(v(v(v(v(G*h)-v(w*g))*C[r>>2])+v(C[r+4>>2]*v(v(w*p)-v(h*_))))+v(v(v(g*_)-v(G*p))*C[r+8>>2])))>v(0)&&((_=Fr(f[o+84>>2],f[o+88>>2],r,o+16|0,o+12|0))>2]=f[o+16>>2],f[n>>2]=0,E=f[o+24>>2],f[n+8>>2]=f[o+20>>2],f[n+12>>2]=E,f[a>>2]=f[o+12>>2]<<1&14,d=_)),v(m*v(v(v(v(v(g*R)-v(h*B))*C[r>>2])+v(C[r+4>>2]*v(v(h*F)-v(R*p))))+v(v(v(B*p)-v(g*F))*C[r+8>>2])))>v(0)&&((_=Fr(f[o+88>>2],f[o+80>>2],r,o+16|0,o+12|0))>2]=f[o+16>>2],f[n+4>>2]=0,f[n>>2]=f[o+20>>2],f[n+12>>2]=f[o+24>>2],E=f[o+12>>2],f[a>>2]=E>>>1&1|E<<1&8|E<<2&4,d=_)),d>2],_=C[e+8>>2],h=C[r>>2],g=C[i+8>>2],p=C[e>>2],R=C[r+4>>2],V=v(v(v(d*_)*h)+v(v(g*p)*R)),y=_,_=C[i>>2],D=v(d*p),d=C[r+8>>2],D=v(v(V-v(R*v(y*_)))-v(D*d)),y=d,d=C[e+4>>2],d=v(v(v(D+v(y*v(_*d)))-v(h*v(g*d)))/m),C[n>>2]=d,_=C[t+4>>2],h=C[i+8>>2],g=C[r>>2],p=C[t+8>>2],R=C[i>>2],B=C[r+4>>2],V=v(v(v(_*h)*g)+v(v(p*R)*B)),y=h,h=C[t>>2],D=v(_*R),_=C[r+8>>2],D=v(v(V-v(B*v(y*h)))-v(D*_)),y=_,_=C[i+4>>2],_=v(v(v(D+v(y*v(h*_)))-v(g*v(p*_)))/m),C[n+4>>2]=_,f[a>>2]=15,h=C[e+4>>2],g=C[t+8>>2],p=C[r>>2],R=C[e+8>>2],B=C[t>>2],F=C[r+4>>2],V=v(v(v(h*g)*p)+v(v(R*B)*F)),y=g,g=C[e>>2],D=v(h*B),h=C[r+8>>2],D=v(v(V-v(F*v(y*g)))-v(D*h)),y=h,h=C[t+4>>2],m=v(v(v(D+v(y*v(g*h)))-v(p*v(R*h)))/m),C[n+8>>2]=m,C[n+12>>2]=v(1)-v(v(d+_)+m),d=v(0)))),Z=o+96|0,d}function wr(t,e,i,r,a,o){var h,g,m=v(0),y=v(0),p=v(0),R=v(0),D=0,B=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0),Gt=v(0),Lt=0;Z=h=Z-19040|0,f[o>>2]=0,f[o+4>>2]=0,f[o+32>>2]=0,f[(D=o+24|0)>>2]=0,f[D+4>>2]=0,f[(D=o+16|0)>>2]=0,f[D+4>>2]=0,f[(D=o+8|0)>>2]=0,f[D+4>>2]=0,f[h+18916>>2]=i,f[h+18912>>2]=t,m=C[r+20>>2],y=C[r+36>>2],p=C[(t=e+20|0)>>2],R=C[(i=e+36|0)>>2],V=C[(D=e+24|0)>>2],B=C[r+24>>2],G=C[(g=e+40|0)>>2],F=C[r+40>>2],w=C[r+32>>2],Q=C[r>>2],W=C[r+16>>2],Y=C[r+4>>2],z=C[e+32>>2],pt=C[e>>2],Dt=C[e+16>>2],Tt=C[e+4>>2],St=C[e+8>>2],It=C[r+8>>2],f[h+18964>>2]=0,f[h+18948>>2]=0,f[h+18932>>2]=0,Et=v(v(v(St*It)+v(V*B))+v(G*F)),C[h+18960>>2]=Et,Ot=v(v(v(Tt*It)+v(p*B))+v(R*F)),C[h+18956>>2]=Ot,B=v(v(v(pt*It)+v(Dt*B))+v(z*F)),C[h+18952>>2]=B,F=v(v(v(St*Y)+v(V*m))+v(G*y)),C[h+18944>>2]=F,It=v(v(v(Tt*Y)+v(p*m))+v(R*y)),C[h+18940>>2]=It,m=v(v(v(pt*Y)+v(Dt*m))+v(z*y)),C[h+18936>>2]=m,y=v(v(v(Q*St)+v(W*V))+v(w*G)),C[h+18928>>2]=y,p=v(v(v(Q*Tt)+v(W*p))+v(w*R)),C[h+18924>>2]=p,R=v(v(v(Q*pt)+v(W*Dt))+v(w*z)),C[h+18920>>2]=R,V=C[t>>2],G=C[i>>2],w=C[D>>2],Q=C[r+52>>2],W=C[e+52>>2],Y=C[g>>2],z=C[r+56>>2],pt=C[e+56>>2],Dt=C[e>>2],Tt=C[e+16>>2],St=C[e+32>>2],Nt=C[e+4>>2],Ft=C[e+8>>2],Vt=C[r+48>>2],Gt=C[e+48>>2],f[h+19036>>2]=0,f[h+19028>>2]=0,f[h+19012>>2]=0,C[h+19008>>2]=Et,C[h+19004>>2]=F,C[h+19e3>>2]=y,f[h+18996>>2]=0,C[h+18992>>2]=Ot,C[h+18988>>2]=It,C[h+18984>>2]=p,f[h+18980>>2]=0,C[h+18976>>2]=B,C[h+18972>>2]=m,m=v(Vt-Gt),y=v(Q-W),p=v(z-pt),C[h+19024>>2]=v(v(Ft*m)+v(w*y))+v(Y*p),C[h+19020>>2]=v(v(m*Nt)+v(y*V))+v(p*G),C[h+19016>>2]=v(v(m*Dt)+v(y*Tt))+v(p*St),f[h+19032>>2]=349,C[h+18968>>2]=R,f[(t=h+18664|0)>>2]=0,f[t+4>>2]=0,f[h+18656>>2]=0,f[h+18660>>2]=0,f[h+18892>>2]=0,f[h+18896>>2]=0,f[h+18904>>2]=2,f[h+18672>>2]=0,f[h+28>>2]=0,C[h+24>>2]=-C[a+8>>2],C[h+20>>2]=-C[a+4>>2],C[h+16>>2]=-C[a>>2];t:if(!((t=yr(h+18528|0,h+18912|0,h+16|0)+-1|0)>>>0>1)){e:{if(t-1){for(f[(t=h+18520|0)>>2]=0,f[t+4>>2]=0,f[(t=h- -64|0)>>2]=0,f[t+4>>2]=0,f[h+72>>2]=0,f[h+18512>>2]=0,f[h+18516>>2]=0,f[h+18508>>2]=0,f[h+16>>2]=9,f[h+56>>2]=0,f[h+60>>2]=0,r=14336;f[(t=(h+16|0)+r|0)+4144>>2]=0,i=f[h+18520>>2],f[t+4148>>2]=i,t=t+4100|0,i&&(f[i+44>>2]=t),f[h+18520>>2]=t,r=r+-56|0;);if(f[h+18524>>2]=256,f[h+12>>2]=0,C[h+8>>2]=-C[a+8>>2],C[h+4>>2]=-C[a+4>>2],C[h>>2]=-C[a>>2],9!=(0|function(t,e,i){var r,a=0,o=0,h=v(0),g=v(0),m=0,y=0,p=0,R=v(0),D=v(0),B=v(0),F=v(0),V=v(0),G=0,w=0,Q=v(0),W=v(0),Y=0,z=v(0),yt=0,pt=v(0);Z=r=Z-16|0;i:{if(p=f[e+372>>2],!(d[p+32>>2]<2)&&function A(t){var e,i=0,r=0,n=0,a=0,o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0);Z=e=Z-32|0;A:{r:{i=f[t+372>>2];n:if(!((r=f[i+32>>2]+-1|0)>>>0>3)){a:{switch(r-1|0){default:if(f[e+28>>2]=0,f[i+32>>2]=2,f[i+20>>2]=0,r=f[t+364>>2]+-1|0,f[t+364>>2]=r,f[e+20>>2]=0,f[e+24>>2]=0,n=i,i=f[348+((r<<2)+t|0)>>2],f[n+4>>2]=i,f[e+16>>2]=1065353216,pr(t,e+16|0,i),A(t))break r;if(n=f[t+364>>2],i=f[t+372>>2],a=f[i+32>>2]+-1|0,r=f[(a<<2)+i>>2],f[348+((n<<2)+t|0)>>2]=r,f[i+32>>2]=a,i=f[t+372>>2],f[t+364>>2]=n,n=f[i+32>>2],f[i+32>>2]=n+1,f[(i=i+(n<<2)|0)>>2]=r,f[e+12>>2]=0,C[e+8>>2]=-C[e+24>>2],C[e+4>>2]=-C[e+20>>2],C[e>>2]=-C[e+16>>2],f[i+16>>2]=0,pr(t,e,r),A(t))break r;if(i=f[t+372>>2],r=f[i+32>>2]+-1|0,f[i+32>>2]=r,n=f[t+364>>2],i=f[i+(r<<2)>>2],f[348+((n<<2)+t|0)>>2]=i,f[(r=e+24|0)>>2]=0,f[r+4>>2]=0,f[t+364>>2]=n,r=f[t+372>>2],n=f[r+32>>2],f[r+32>>2]=n+1,f[e+16>>2]=0,f[e+20>>2]=0,f[(r=r+(n<<2)|0)>>2]=i,f[e+20>>2]=1065353216,f[r+16>>2]=0,pr(t,e+16|0,i),!A(t))break a;break r;case 0:if(r=f[i>>2],_=C[r+20>>2],n=f[i+4>>2],o=C[n+20>>2],h=C[r+24>>2],d=C[n+24>>2],y=C[r+16>>2],g=C[n+16>>2],f[e+28>>2]=0,p=v(o-_),_=v(p*v(0)),d=v(d-h),o=v(d*v(0)),m=v(_-o),C[e+16>>2]=m,y=v(g-y),h=v(y*v(0)),g=v(d-h),C[e+20>>2]=g,R=v(h-p),C[e+24>>2]=R,v(v(R*R)+v(v(m*m)+v(g*g)))>v(0)){if(f[i+32>>2]=3,f[i+24>>2]=0,r=f[t+364>>2]+-1|0,f[t+364>>2]=r,n=i,i=f[348+((r<<2)+t|0)>>2],f[n+8>>2]=i,pr(t,e+16|0,i),A(t))break r;if(n=f[t+364>>2],i=f[t+372>>2],a=f[i+32>>2]+-1|0,r=f[(a<<2)+i>>2],f[348+((n<<2)+t|0)>>2]=r,f[i+32>>2]=a,i=f[t+372>>2],f[t+364>>2]=n,n=f[i+32>>2],f[i+32>>2]=n+1,f[(i=i+(n<<2)|0)>>2]=r,f[e+12>>2]=0,C[e+8>>2]=-C[e+24>>2],C[e+4>>2]=-C[e+20>>2],C[e>>2]=-C[e+16>>2],f[i+16>>2]=0,pr(t,e,r),A(t))break r;n=f[t+364>>2],f[t+364>>2]=n+1,i=f[t+372>>2],r=f[i+32>>2]+-1|0,f[i+32>>2]=r,f[348+((n<<2)+t|0)>>2]=f[i+(r<<2)>>2]}if(f[e+28>>2]=0,m=v(o-h),C[e+20>>2]=m,d=v(_-d),C[e+16>>2]=d,g=v(y-_),C[e+24>>2]=g,v(v(g*g)+v(v(d*d)+v(m*m)))>v(0)){if(n=f[t+364>>2]+-1|0,f[t+364>>2]=n,i=f[t+372>>2],r=f[i+32>>2],f[i+32>>2]=r+1,f[(i=i+(r<<2)|0)+16>>2]=0,r=i,i=f[348+((n<<2)+t|0)>>2],f[r>>2]=i,pr(t,e+16|0,i),A(t))break r;if(n=f[t+364>>2],i=f[t+372>>2],a=f[i+32>>2]+-1|0,r=f[(a<<2)+i>>2],f[348+((n<<2)+t|0)>>2]=r,f[i+32>>2]=a,i=f[t+372>>2],f[t+364>>2]=n,n=f[i+32>>2],f[i+32>>2]=n+1,f[(i=i+(n<<2)|0)>>2]=r,f[e+12>>2]=0,C[e+8>>2]=-C[e+24>>2],C[e+4>>2]=-C[e+20>>2],C[e>>2]=-C[e+16>>2],f[i+16>>2]=0,pr(t,e,r),A(t))break r;n=f[t+364>>2],f[t+364>>2]=n+1,i=f[t+372>>2],r=f[i+32>>2]+-1|0,f[i+32>>2]=r,f[348+((n<<2)+t|0)>>2]=f[i+(r<<2)>>2]}if(f[e+28>>2]=0,d=v(o-y),C[e+20>>2]=d,o=v(p-o),C[e+16>>2]=o,_=v(h-_),C[e+24>>2]=_,!(v(v(_*_)+v(v(o*o)+v(d*d)))>v(0)))break n;if(n=f[t+364>>2]+-1|0,f[t+364>>2]=n,i=f[t+372>>2],r=f[i+32>>2],f[i+32>>2]=r+1,f[(i=i+(r<<2)|0)+16>>2]=0,r=i,i=f[348+((n<<2)+t|0)>>2],f[r>>2]=i,pr(t,e+16|0,i),A(t))break r;if(n=f[t+364>>2],i=f[t+372>>2],a=f[i+32>>2]+-1|0,r=f[(a<<2)+i>>2],f[348+((n<<2)+t|0)>>2]=r,f[i+32>>2]=a,i=f[t+372>>2],f[t+364>>2]=n,n=f[i+32>>2],f[i+32>>2]=n+1,f[(i=i+(n<<2)|0)>>2]=r,f[e+12>>2]=0,C[e+8>>2]=-C[e+24>>2],C[e+4>>2]=-C[e+20>>2],C[e>>2]=-C[e+16>>2],f[i+16>>2]=0,pr(t,e,r),A(t))break r;n=f[t+364>>2],f[t+364>>2]=n+1,i=f[t+372>>2],r=f[i+32>>2]+-1|0,f[i+32>>2]=r,f[348+((n<<2)+t|0)>>2]=f[i+(r<<2)>>2];break n;case 1:if(f[e+28>>2]=0,r=f[i+4>>2],n=f[i>>2],_=C[n+20>>2],h=v(C[r+20>>2]-_),a=f[i+8>>2],o=C[n+24>>2],p=v(C[a+24>>2]-o),o=v(C[r+24>>2]-o),d=v(C[a+20>>2]-_),_=v(v(h*p)-v(o*d)),C[e+16>>2]=_,g=o,o=C[n+16>>2],m=v(C[a+16>>2]-o),y=v(C[r+16>>2]-o),o=v(v(g*m)-v(y*p)),C[e+20>>2]=o,h=v(v(y*d)-v(h*m)),C[e+24>>2]=h,!(v(v(h*h)+v(v(_*_)+v(o*o)))>v(0)))break n;if(f[(r=i+28|0)>>2]=0,f[r+4>>2]=4,r=f[t+364>>2]+-1|0,f[t+364>>2]=r,n=i,i=f[348+((r<<2)+t|0)>>2],f[n+12>>2]=i,pr(t,e+16|0,i),A(t))break r;if(r=f[t+364>>2],i=f[t+372>>2],a=f[i+32>>2]+-1|0,n=f[(a<<2)+i>>2],f[348+((r<<2)+t|0)>>2]=n,f[i+32>>2]=a,i=f[t+372>>2],f[t+364>>2]=r,a=f[i+32>>2],f[i+32>>2]=a+1,f[(i=i+(a<<2)|0)>>2]=n,f[e+12>>2]=0,C[e+8>>2]=-C[e+24>>2],C[e+4>>2]=-C[e+20>>2],C[e>>2]=-C[e+16>>2],f[i+16>>2]=0,pr(t,e,n),r=1,A(t))break A;n=f[t+364>>2],f[t+364>>2]=n+1,i=f[t+372>>2],r=f[i+32>>2]+-1|0,f[i+32>>2]=r,f[348+((n<<2)+t|0)>>2]=f[i+(r<<2)>>2];break n;case 2:}if(t=f[i>>2],n=f[i+12>>2],_=C[n+16>>2],p=v(C[t+16>>2]-_),a=f[i+4>>2],o=C[n+20>>2],d=v(C[a+20>>2]-o),i=f[i+8>>2],h=C[n+24>>2],m=v(C[i+24>>2]-h),y=v(C[t+20>>2]-o),g=v(C[a+24>>2]-h),R=v(C[i+16>>2]-_),h=v(C[t+24>>2]-h),_=v(C[a+16>>2]-_),o=v(C[i+20>>2]-o),r=1,(_=v(v(v(v(p*d)*m)+v(v(v(v(v(y*g)*R)+v(v(h*_)*o))-v(v(p*g)*o))-v(v(y*_)*m)))-v(v(h*d)*R)))!=v(0)&_==_)break A;break n}if(n=f[t+364>>2],i=f[t+372>>2],a=f[i+32>>2]+-1|0,r=f[(a<<2)+i>>2],f[348+((n<<2)+t|0)>>2]=r,f[i+32>>2]=a,i=f[t+372>>2],f[t+364>>2]=n,n=f[i+32>>2],f[i+32>>2]=n+1,f[(i=i+(n<<2)|0)>>2]=r,f[e+12>>2]=0,C[e+8>>2]=-C[e+24>>2],C[e+4>>2]=-C[e+20>>2],C[e>>2]=-C[e+16>>2],f[i+16>>2]=0,pr(t,e,r),A(t))break r;if(i=f[t+372>>2],r=f[i+32>>2]+-1|0,f[i+32>>2]=r,n=f[t+364>>2],i=f[i+(r<<2)>>2],f[348+((n<<2)+t|0)>>2]=i,f[(r=e+24|0)>>2]=0,f[r+4>>2]=0,f[r>>2]=1065353216,f[t+364>>2]=n,r=f[t+372>>2],n=f[r+32>>2],f[r+32>>2]=n+1,f[e+16>>2]=0,f[e+20>>2]=0,f[(r=r+(n<<2)|0)>>2]=i,f[r+16>>2]=0,pr(t,e+16|0,i),A(t))break r;if(n=f[t+364>>2],i=f[t+372>>2],a=f[i+32>>2]+-1|0,r=f[(a<<2)+i>>2],f[348+((n<<2)+t|0)>>2]=r,f[i+32>>2]=a,i=f[t+372>>2],f[t+364>>2]=n,n=f[i+32>>2],f[i+32>>2]=n+1,f[(i=i+(n<<2)|0)>>2]=r,f[e+12>>2]=0,C[e+8>>2]=-C[e+24>>2],C[e+4>>2]=-C[e+20>>2],C[e>>2]=-C[e+16>>2],f[i+16>>2]=0,pr(t,e,r),A(t))break r;n=f[t+364>>2],f[t+364>>2]=n+1,i=f[t+372>>2],r=f[i+32>>2]+-1|0,f[i+32>>2]=r,f[348+((n<<2)+t|0)>>2]=f[i+(r<<2)>>2]}r=0;break A}r=1}return Z=e+32|0,r}(e)){if(a=f[t+18496>>2]){for(o=f[t+18508>>2],y=f[t+18500>>2];(m=f[a+48>>2])&&(f[m+44>>2]=f[a+44>>2]),(m=f[a+44>>2])&&(f[m+48>>2]=f[a+48>>2]),(0|a)==f[t+18496>>2]&&(f[t+18496>>2]=f[a+48>>2]),f[a+44>>2]=0,f[a+48>>2]=f[t+18504>>2],(m=f[t+18504>>2])&&(f[m+44>>2]=a),y=y+-1|0,f[t+18504>>2]=a,o=o+1|0,a=f[t+18496>>2];);f[t+18508>>2]=o,f[t+18500>>2]=y}if(f[t+18492>>2]=0,f[t>>2]=0,o=f[p>>2],y=f[p+12>>2],h=C[y+16>>2],V=v(C[o+16>>2]-h),a=f[p+4>>2],g=C[y+20>>2],D=v(C[a+20>>2]-g),m=f[p+8>>2],R=C[y+24>>2],B=v(C[m+24>>2]-R),F=v(C[o+20>>2]-g),Q=v(C[a+24>>2]-R),W=v(C[m+16>>2]-h),R=v(C[o+24>>2]-R),h=v(C[a+16>>2]-h),g=v(C[m+20>>2]-g),v(v(v(v(V*D)*B)+v(v(v(v(v(F*Q)*W)+v(v(R*h)*g))-v(v(V*Q)*g))-v(v(F*h)*B)))-v(v(R*D)*W))>2]=o,f[p>>2]=a,y=f[p+16>>2],G=p+20|0,f[p+16>>2]=f[G>>2],f[G>>2]=y,y=o):(y=a,a=o),y=Dr(t,a,y,m,1),m=Dr(t,f[p+4>>2],f[p>>2],f[p+12>>2],1),w=Dr(t,f[p+8>>2],f[p+4>>2],f[p+12>>2],1),G=Dr(t,f[p>>2],f[p+8>>2],f[p+12>>2],1),4==f[t+18500>>2]){if(o=f[t+18496>>2],h=C[o+16>>2],a=f[o+48>>2]){for(h=v(h*h);g=C[a+16>>2],o=(i=(g=v(g*g))>2];);h=C[o+16>>2]}for(i=f[o+28>>2],p=f[o+24>>2],Y=f[o+20>>2],D=C[o+12>>2],V=C[o+8>>2],R=C[o+4>>2],g=C[o>>2],f[y+32>>2]=m,n[y+52|0]=0,f[m+32>>2]=y,n[m+52|0]=0,f[y+36>>2]=w,n[y+53|0]=0,f[w+32>>2]=y,n[w+52|0]=1,f[y+40>>2]=G,n[y+54|0]=0,f[G+32>>2]=y,n[G+52|0]=2,f[m+36>>2]=G,n[m+53|0]=2,f[G+40>>2]=m,n[G+54|0]=1,f[m+40>>2]=w,n[m+54|0]=1,f[w+36>>2]=m,n[0|(a=w+53|0)]=258,n[a+1|0]=1,f[w+40>>2]=G,n[G+53|0]=2,f[G+36>>2]=w,f[t>>2]=0,m=0;;){A:{r:{if(!((a=f[t+18492>>2])>>>0<=127)){f[t>>2]=6;break A}if(f[t+18492>>2]=a+1,m=m+1|0,n[o+55|0]=m,f[r+8>>2]=0,f[r>>2]=0,f[r+4>>2]=0,pr(e,o,G=(a=(a<<5)+t|0)+60|0),!(v(v(v(v(C[o>>2]*C[a+76>>2])+v(C[o+4>>2]*C[a+80>>2]))+v(C[o+8>>2]*C[a+84>>2]))-C[o+16>>2])>v(9999999747378752e-20))){f[t>>2]=7;break A}for(y=o+32|0,a=52;;){if(!(w=Er(t,m,G,f[y>>2],_[o+a|0],r)))break r;if(yt=a+-51|0,y=y+4|0,a=a+1|0,!(yt>>>0<3))break}}if(w&d[r+8>>2]>2){if(i=f[r>>2],n[i+53|0]=2,a=f[r+4>>2],f[i+36>>2]=a,f[a+40>>2]=i,n[a+54|0]=1,(i=f[o+48>>2])&&(f[i+44>>2]=f[o+44>>2]),(i=f[o+44>>2])&&(f[i+48>>2]=f[o+48>>2]),(0|o)==f[t+18496>>2]&&(f[t+18496>>2]=f[o+48>>2]),f[o+44>>2]=0,f[o+48>>2]=f[t+18504>>2],f[t+18500>>2]=f[t+18500>>2]+-1,(i=f[t+18504>>2])&&(f[i+44>>2]=o),f[t+18504>>2]=o,f[t+18508>>2]=f[t+18508>>2]+1,o=f[t+18496>>2],h=C[o+16>>2],a=f[o+48>>2]){for(h=v(h*h);g=C[a+16>>2],o=(i=(g=v(g*g))>2];);h=C[o+16>>2]}if(i=f[o+28>>2],p=f[o+24>>2],Y=f[o+20>>2],D=C[o+12>>2],V=C[o+8>>2],R=C[o+4>>2],g=C[o>>2],255!=(0|m))continue}else f[t>>2]=4}break}C[t+56>>2]=h,C[t+40>>2]=g,C[t+52>>2]=D,C[t+48>>2]=V,C[t+44>>2]=R,e=t+20|0,g=v(g*h),D=v(C[p+16>>2]-g),a=i+20|0,R=v(R*h),B=v(C[a>>2]-R),F=v(C[(o=p+20|0)>>2]-R),Q=v(C[i+16>>2]-g),W=v(v(D*B)-v(F*Q)),y=i+24|0,h=v(V*h),V=v(C[y>>2]-h),z=v(F*V),F=v(C[(m=p+24|0)>>2]-h),B=v(z-v(F*B)),V=v(v(F*Q)-v(D*V)),V=v(E(v(v(W*W)+v(v(B*B)+v(V*V))))),C[e>>2]=V,G=t+24|0,D=v(C[i+16>>2]-g),B=v(C[(w=Y+20|0)>>2]-R),F=v(C[a>>2]-R),Q=v(C[Y+16>>2]-g),W=v(v(D*B)-v(F*Q)),pt=v(W*W),z=F,F=v(C[(a=Y+24|0)>>2]-h),W=v(C[y>>2]-h),B=v(v(z*F)-v(W*B)),D=v(v(W*Q)-v(D*F)),D=v(E(v(pt+v(v(B*B)+v(D*D))))),C[G>>2]=D,f[t+4>>2]=Y,f[t+36>>2]=3,f[t+12>>2]=i,f[t+8>>2]=p,B=v(C[Y+16>>2]-g),F=v(C[o>>2]-R),R=v(C[w>>2]-R),g=v(C[p+16>>2]-g),Q=v(v(B*F)-v(R*g)),z=R,R=v(C[m>>2]-h),h=v(C[a>>2]-h),F=v(v(z*R)-v(h*F)),h=v(v(h*g)-v(B*R)),g=v(E(v(v(Q*Q)+v(v(F*F)+v(h*h))))),h=v(g+v(V+D)),C[t+28>>2]=g/h,C[G>>2]=D/h,C[e>>2]=V/h,a=f[t>>2];break i}}f[t>>2]=8,h=C[i+8>>2],g=C[i+4>>2],R=C[i>>2],f[t+52>>2]=0,V=v(-R),C[t+40>>2]=V,D=v(-g),C[t+44>>2]=D,B=v(-h),C[t+48>>2]=B,(h=v(E(v(v(v(R*R)+v(g*g))+v(h*h)))))>v(0)?(h=v(v(1)/h),C[t+48>>2]=h*B,C[t+44>>2]=h*D,C[t+40>>2]=h*V):(f[t+48>>2]=0,f[t+40>>2]=1065353216,f[t+44>>2]=0),f[t+52>>2]=0,f[t+56>>2]=0,f[t+36>>2]=1,f[t+20>>2]=1065353216,f[t+4>>2]=f[p>>2],a=8}return Z=r+16|0,a}(h+16|0,h+18528|0,h))){if(!f[h+52>>2]){m=v(0),y=v(0),p=v(0);break e}for(r=h+36|0,p=v(0),a=0,y=v(0),m=v(0);t=f[h+19036>>2],i=f[h+18912>>2]+(t>>1)|0,D=f[h+19032>>2],yt[1&t?f[D+f[i>>2]>>2]:D](h,i,f[r+-16>>2]),R=C[r>>2],p=v(p+v(R*C[h+8>>2])),y=v(y+v(R*C[h+4>>2])),m=v(m+v(C[h>>2]*R)),r=r+4|0,(a=a+1|0)>>>0>2];);break e}f[o>>2]=3;break t}f[o>>2]=2;break t}R=C[e+48>>2],V=C[e+8>>2],B=C[e>>2],G=C[e+4>>2],F=C[e+52>>2],w=C[e+24>>2],Q=C[e+16>>2],W=C[e+20>>2],Y=C[e+56>>2],z=C[e+40>>2],pt=C[e+32>>2],Dt=C[e+36>>2],f[o+16>>2]=0,C[o+12>>2]=Y+v(v(v(m*pt)+v(y*Dt))+v(p*z)),C[o+8>>2]=F+v(v(v(m*Q)+v(y*W))+v(p*w)),C[o+4>>2]=R+v(v(v(m*B)+v(y*G))+v(p*V)),Lt=1,f[o>>2]=1,V=C[e+56>>2],B=C[e+40>>2],G=C[e+32>>2],F=C[e+36>>2],w=C[e+52>>2],Q=C[e+24>>2],W=C[e+16>>2],Y=C[e+20>>2],z=C[e+48>>2],pt=C[e+8>>2],Dt=C[e>>2],Tt=C[e+4>>2],f[o+32>>2]=0,f[o+48>>2]=0,St=C[h+56>>2],C[o+36>>2]=-St,It=C[h+60>>2],C[o+40>>2]=-It,Et=C[h- -64>>2],C[o+44>>2]=-Et,R=C[h+72>>2],C[o+52>>2]=-R,m=v(m-v(St*R)),y=v(y-v(R*It)),p=v(p-v(R*Et)),C[o+20>>2]=z+v(v(v(Dt*m)+v(Tt*y))+v(pt*p)),C[o+24>>2]=w+v(v(v(m*W)+v(y*Y))+v(p*Q)),C[o+28>>2]=V+v(v(v(m*G)+v(y*F))+v(p*B))}return Z=h+19040|0,Lt}function Dr(t,e,i,r,a){var o,_=0,h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=0,B=v(0),F=v(0);if(o=f[t+18504>>2]){if((_=f[o+48>>2])&&(f[_+44>>2]=f[o+44>>2]),(_=f[o+44>>2])&&(f[_+48>>2]=f[o+48>>2]),(0|o)==f[t+18504>>2]&&(f[t+18504>>2]=f[o+48>>2]),f[o+44>>2]=0,f[o+48>>2]=f[t+18496>>2],f[(_=t+18508|0)>>2]=f[_>>2]+-1,(_=f[t+18496>>2])&&(f[_+44>>2]=o),f[t+18496>>2]=o,f[(_=t+18500|0)>>2]=f[_>>2]+1,n[o+55|0]=0,f[o+28>>2]=r,f[o+24>>2]=i,f[o+20>>2]=e,y=C[i+20>>2],p=C[r+24>>2],m=C[i+24>>2],h=C[e+24>>2],g=C[e+20>>2],R=C[r+20>>2],B=C[r+16>>2],F=C[i+16>>2],d=C[e+16>>2],f[o+12>>2]=0,y=v(y-g),p=v(p-h),m=v(m-h),R=v(R-g),h=v(v(y*p)-v(m*R)),C[o>>2]=h,g=m,m=v(B-d),d=v(F-d),g=v(v(g*m)-v(d*p)),C[o+4>>2]=g,d=v(v(d*R)-v(y*m)),C[o+8>>2]=d,D=2,(h=v(E(v(v(v(h*h)+v(g*g))+v(d*d)))))>v(9999999747378752e-20)){if(Zr(o,e,i,_=o+16|0)||Zr(o,i,r,_)||Zr(o,r,e,_)||(C[o+16>>2]=v(v(v(C[e+16>>2]*C[o>>2])+v(C[e+20>>2]*C[o+4>>2]))+v(C[e+24>>2]*C[o+8>>2]))/h),h=v(v(1)/h),C[o>>2]=h*C[o>>2],C[o+4>>2]=h*C[o+4>>2],C[o+8>>2]=h*C[o+8>>2],a)return o;if(D=3,C[_>>2]>=v(-9999999747378752e-21))return o}return f[t>>2]=D,(e=f[o+48>>2])&&(f[e+44>>2]=f[o+44>>2]),(e=f[o+44>>2])&&(f[e+48>>2]=f[o+48>>2]),(0|o)==f[t+18496>>2]&&(f[t+18496>>2]=f[o+48>>2]),f[o+44>>2]=0,f[o+48>>2]=f[t+18504>>2],f[t+18500>>2]=f[t+18500>>2]+-1,(e=f[t+18504>>2])&&(f[e+44>>2]=o),f[t+18504>>2]=o,f[t+18508>>2]=f[t+18508>>2]+1,0}return f[t>>2]=5,0}function Er(t,e,i,r,a,o){var h=0,d=0,g=0;t:if(_[r+55|0]!=(0|e)){if(d=f[(h=a<<2)+14768>>2],v(v(v(v(C[r>>2]*C[i+16>>2])+v(C[r+4>>2]*C[i+20>>2]))+v(C[r+8>>2]*C[i+24>>2]))-C[r+16>>2])>2],f[t+h>>2],i,0)))break t;return f[t+32>>2]=r,n[t+52|0]=a,n[52+(r+a|0)|0]=0,f[32+((a<<2)+r|0)>>2]=t,(e=f[o>>2])?(f[e+36>>2]=t,n[e+53|0]=2,f[t+40>>2]=e,n[t+54|0]=1):f[o+4>>2]=t,f[o>>2]=t,f[o+8>>2]=f[o+8>>2]+1,1}n[r+55|0]=e,Er(t,e,i,f[32+((d<<2)+r|0)>>2],_[52+(r+d|0)|0],o)&&(a=e,e=f[h+14780>>2],Er(t,a,i,f[32+((e<<2)+r|0)>>2],_[52+(e+r|0)|0],o)&&((e=f[r+48>>2])&&(f[e+44>>2]=f[r+44>>2]),(e=f[r+44>>2])&&(f[e+48>>2]=f[r+48>>2]),(0|r)==f[t+18496>>2]&&(f[t+18496>>2]=f[r+48>>2]),f[r+44>>2]=0,f[r+48>>2]=f[t+18504>>2],f[(e=t+18500|0)>>2]=f[e>>2]+-1,(e=f[t+18504>>2])&&(f[e+44>>2]=r),f[t+18504>>2]=r,g=1,f[(t=t+18508|0)>>2]=f[t>>2]+1))}return g}function Zr(t,e,i,r){var n=v(0),a=v(0),o=v(0),f=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0);return _=C[i+24>>2],n=C[e+24>>2],g=v(_-n),h=C[i+16>>2],o=C[e+16>>2],m=v(h-o),a=C[t+4>>2],d=C[i+20>>2],f=C[e+20>>2],y=v(d-f),p=C[t>>2],R=C[t+8>>2],t=0,v(v(n*v(v(m*a)-v(y*p)))+v(v(o*v(v(y*R)-v(g*a)))+v(f*v(v(g*p)-v(m*R)))))v(0)||(a=v(v(v(h*h)+v(d*d))+v(_*_)),v(v(v(h*m)+v(d*y))+v(_*g))v(0)?n:v(0))),C[r>>2]=E(a),t=1),t}function Yr(t){var e=0;n[t+356|0]=1,f[t>>2]=0,n[t+312|0]=0,f[t+292>>2]=1566444395,f[t+296>>2]=1566444395,f[(e=t+336|0)>>2]=0,f[e+4>>2]=0,f[(e=t+300|0)>>2]=1566444395,f[e+4>>2]=0,f[(e=t+344|0)>>2]=0,f[e+4>>2]=0,n[t+352|0]=0,n[0|(t=t+332|0)]=240&_[0|t]}function Vr(t,e,i,r){var a,o=0,_=0,h=0;o=f[e+4>>2],f[t+292>>2]=f[e>>2],f[t+296>>2]=o,h=f[(o=e+8|0)+4>>2],f[(_=t+300|0)>>2]=f[o>>2],f[_+4>>2]=h,n[t+356|0]=1,a=f[o+4>>2],_=(f[t>>2]<<4)+t|0,f[(h=_+12|0)>>2]=f[o>>2],f[h+4>>2]=a,o=_+4|0,_=f[e+4>>2],f[o>>2]=f[e>>2],f[o+4>>2]=_,h=f[(_=i+8|0)+4>>2],e=(f[t>>2]<<4)+t|0,f[(o=e+92|0)>>2]=f[_>>2],f[o+4>>2]=h,o=f[i+4>>2],f[(e=e+84|0)>>2]=f[i>>2],f[e+4>>2]=o,o=f[r+4>>2],e=(f[t>>2]<<4)+t|0,f[(i=e+164|0)>>2]=f[r>>2],f[i+4>>2]=o,r=f[(i=r+8|0)+4>>2],f[(e=e+172|0)>>2]=f[i>>2],f[e+4>>2]=r,f[t>>2]=f[t>>2]+1}function Nr(t){var e,i=0,r=0,a=0,o=0,h=0,d=0,g=v(0),m=0,y=0,p=v(0),R=0,D=0,B=v(0),E=v(0),F=0,V=v(0),G=0,w=0,Q=v(0),W=v(0),Y=0,z=v(0),yt=v(0),pt=0,Dt=0,It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=0;Z=e=Z-16|0;t:if(_[t+356|0]){n[t+356|0]=0,n[t+352|0]=0,f[(i=t+344|0)>>2]=0,f[i+4>>2]=0,f[(i=Dt=t+336|0)>>2]=0,f[i+4>>2]=0,i=-16&_[0|(o=t+332|0)],n[0|o]=i;e:if(!((o=f[t>>2])>>>0>4)){r=t+316|0;i:{A:{switch(o-1|0){case 1:o=t,V=C[t+4>>2],g=v(C[t+20>>2]-V),Q=C[t+8>>2],B=v(C[t+24>>2]-Q),W=C[t+12>>2],E=v(C[t+28>>2]-W);r:if((V=v(v(v(v(v(0)-V)*g)+v(v(v(0)-Q)*B))+v(v(v(0)-W)*E)))>v(0)){if(V<(p=v(v(v(g*g)+v(B*B))+v(E*E)))){p=v(V/p),r=3|i;break r}p=v(1),r=2|i}else r=1|i;n[o+332|0]=r,f[(i=t+344|0)>>2]=0,f[i+4>>2]=0,C[t+340>>2]=p,V=v(v(1)-p),C[t+336>>2]=V,f[t+256>>2]=0,g=C[t+92>>2],Q=v(g+v(p*v(C[t+108>>2]-g))),C[t+252>>2]=Q,g=C[t+88>>2],W=v(g+v(p*v(C[t+104>>2]-g))),C[t+248>>2]=W,g=C[t+84>>2],z=v(g+v(p*v(C[t+100>>2]-g))),C[t+244>>2]=z,yt=C[t+180>>2],It=C[t+184>>2],g=C[t+168>>2],St=C[t+188>>2],B=C[t+172>>2],E=C[t+164>>2],f[t+288>>2]=0,B=v(B+v(p*v(St-B))),C[t+284>>2]=Q-B,g=v(g+v(p*v(It-g))),C[t+280>>2]=W-g,E=v(E+v(p*v(yt-E))),C[t+276>>2]=z-E,f[t+272>>2]=0,C[t+268>>2]=B,C[t+264>>2]=g,C[t+260>>2]=E,o=1,2&r||(f[t>>2]=1,o=0),1&r||(f[t>>2]=o,o=f[(i=(r=(o<<4)+t|0)+12|0)>>2],i=f[i+4>>2],h=f[(m=r+4|0)>>2],m=f[m+4>>2],w=f[(R=r+84|0)+4>>2],f[(a=t+84|0)>>2]=f[R>>2],f[a+4>>2]=w,R=f[(d=r+92|0)+4>>2],f[(a=a+8|0)>>2]=f[d>>2],f[a+4>>2]=R,w=f[(R=r+164|0)+4>>2],f[(a=t+164|0)>>2]=f[R>>2],f[a+4>>2]=w,d=f[(r=r+172|0)+4>>2],f[(a=a+8|0)>>2]=f[r>>2],f[a+4>>2]=d,f[(r=t+4|0)>>2]=h,f[r+4>>2]=m,f[(r=r+8|0)>>2]=o,f[r+4>>2]=i),r=p>=v(0)&V>=v(0);break e;case 2:f[(i=e+8|0)>>2]=0,f[i+4>>2]=0,f[e>>2]=0,f[e+4>>2]=0,Ir(e,m=t+4|0,h=t+20|0,a=t+36|0,r),f[t+256>>2]=0,B=C[t+336>>2],p=C[t+340>>2],g=C[t+344>>2],E=v(v(v(B*C[t+92>>2])+v(p*C[t+108>>2]))+v(g*C[t+124>>2])),C[t+252>>2]=E,V=v(v(v(B*C[t+88>>2])+v(p*C[t+104>>2]))+v(g*C[t+120>>2])),C[t+248>>2]=V,d=t+100|0,R=t+116|0,Q=v(v(v(B*C[t+84>>2])+v(p*C[d>>2]))+v(g*C[R>>2])),C[t+244>>2]=Q,W=C[(w=t+180|0)>>2],z=C[(F=t+196|0)>>2],yt=C[t+168>>2],It=C[t+184>>2],St=C[t+200>>2],Et=C[t+172>>2],Ot=C[t+188>>2],Nt=C[t+204>>2],Ft=C[t+164>>2],f[t+288>>2]=0,Tt=E,E=v(v(v(B*Et)+v(p*Ot))+v(g*Nt)),C[t+284>>2]=Tt-E,Tt=V,V=v(v(v(B*yt)+v(p*It))+v(g*St)),C[t+280>>2]=Tt-V,B=v(v(v(B*Ft)+v(p*W))+v(g*z)),C[t+276>>2]=Q-B,f[t+272>>2]=0,C[t+268>>2]=E,C[t+264>>2]=V,C[t+260>>2]=B;r:{n:{a:{o:{s:{l:if((0|(i=f[t>>2]))>=4){if(8&(o=_[t+332|0])){r=i;break l}r=i+-1|0,f[t>>2]=r,G=f[(D=(i=(r<<4)+t|0)+12|0)+4>>2],f[(y=t+60|0)>>2]=f[D>>2],f[y+4>>2]=G,G=f[(D=i+4|0)+4>>2],f[(y=t+52|0)>>2]=f[D>>2],f[y+4>>2]=G,G=f[(D=i+92|0)+4>>2],f[(y=t+140|0)>>2]=f[D>>2],f[y+4>>2]=G,G=f[(D=i+84|0)+4>>2],f[(y=t+132|0)>>2]=f[D>>2],f[y+4>>2]=G,G=f[(D=i+164|0)+4>>2],f[(y=t+212|0)>>2]=f[D>>2],f[y+4>>2]=G,D=f[(i=i+172|0)+4>>2],f[(y=t+220|0)>>2]=f[i>>2],f[y+4>>2]=D}else{if(r=3,3!=(0|i))break s;o=_[t+332|0]}if(4&o)break o;r=r+-1|0,f[t>>2]=r,G=f[(D=(i=(r<<4)+t|0)+12|0)+4>>2],f[(y=a+8|0)>>2]=f[D>>2],f[y+4>>2]=G,D=f[(y=i+4|0)+4>>2],f[a>>2]=f[y>>2],f[a+4>>2]=D,D=f[(y=i+92|0)+4>>2],f[(a=R+8|0)>>2]=f[y>>2],f[a+4>>2]=D,y=f[(a=i+84|0)+4>>2],f[R>>2]=f[a>>2],f[R+4>>2]=y,R=f[(a=i+164|0)+4>>2],f[F>>2]=f[a>>2],f[F+4>>2]=R,R=f[(i=i+172|0)+4>>2],f[(a=F+8|0)>>2]=f[i>>2],f[a+4>>2]=R;break o}if(r=2,(0|i)<2)break a;o=_[t+332|0]}if(2&o)break n;r=r+-1|0,f[t>>2]=r,F=f[(R=(i=(r<<4)+t|0)+12|0)+4>>2],f[(a=h+8|0)>>2]=f[R>>2],f[a+4>>2]=F,R=f[(a=i+4|0)+4>>2],f[h>>2]=f[a>>2],f[h+4>>2]=R,R=f[(a=i+92|0)+4>>2],f[(h=d+8|0)>>2]=f[a>>2],f[h+4>>2]=R,a=f[(h=i+84|0)+4>>2],f[d>>2]=f[h>>2],f[d+4>>2]=a,a=f[(h=i+164|0)+4>>2],f[w>>2]=f[h>>2],f[w+4>>2]=a,a=f[(i=i+172|0)+4>>2],f[(h=w+8|0)>>2]=f[i>>2],f[h+4>>2]=a;break n}if(r=1,1!=(0|i))break r;o=_[t+332|0]}1&o||(r=r+-1|0,f[t>>2]=r,h=f[(o=(r=(r<<4)+t|0)+12|0)+4>>2],f[(i=m+8|0)>>2]=f[o>>2],f[i+4>>2]=h,o=f[(i=r+4|0)+4>>2],f[m>>2]=f[i>>2],f[m+4>>2]=o,h=f[(m=r+92|0)+4>>2],f[(o=(i=t+84|0)+8|0)>>2]=f[m>>2],f[o+4>>2]=h,m=f[(o=r+84|0)+4>>2],f[i>>2]=f[o>>2],f[i+4>>2]=m,h=f[(m=r+164|0)+4>>2],f[(i=t+164|0)>>2]=f[m>>2],f[i+4>>2]=h,o=f[(r=r+172|0)+4>>2],f[(i=i+8|0)>>2]=f[r>>2],f[i+4>>2]=o)}if(r=0,C[Dt>>2]>=v(0)^1|p>=v(0)^1|g>=v(0)^1)break e;r=C[t+348>>2]>=v(0);break e;case 3:if(f[(i=e+8|0)>>2]=0,f[i+4>>2]=0,f[e>>2]=0,f[e+4>>2]=0,function(t,e,i,r,a,o){var h,d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=0,D=0,B=v(0),E=v(0),F=v(0),V=v(0),G=0,w=v(0),Q=v(0),W=0,Y=v(0),z=v(0),yt=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=0,Ot=0,Nt=v(0),Ft=v(0),Vt=v(0),Gt=v(0),Lt=v(0),wt=v(0);return Z=h=Z-48|0,R=f[t+4>>2],f[o>>2]=f[t>>2],f[o+4>>2]=R,D=f[(R=t+8|0)+4>>2],R=f[R>>2],n[o+16|0]=15|_[o+16|0],f[(W=o+8|0)>>2]=R,f[W+4>>2]=D,n[h+24|0]=0,R=-1,D=-1,Nt=C[a>>2],p=C[e>>2],y=v(Nt-p),B=C[i+4>>2],d=C[e+4>>2],F=v(B-d),Ft=C[r+8>>2],m=C[e+8>>2],g=v(Ft-m),Y=C[i+8>>2],V=v(Y-m),Vt=C[r+4>>2],w=v(Vt-d),z=v(v(F*g)-v(V*w)),Gt=C[a+4>>2],Q=v(Gt-d),Lt=C[r>>2],yt=v(Lt-p),pt=C[i>>2],Dt=v(pt-p),It=v(v(V*yt)-v(Dt*g)),St=v(v(Dt*w)-v(F*yt)),wt=C[a+8>>2],Tt=v(wt-m),E=v(v(v(y*z)+v(Q*It))+v(St*Tt)),v(E*E)>2]-p))+v(It*v(C[t+4>>2]-d)))+v(St*v(C[t+8>>2]-m))))>2]-p))+v(St*v(C[t+4>>2]-d)))+v(z*v(C[t+8>>2]-m))))>2]-p))+v(V*v(C[t+4>>2]-d)))+v(g*v(C[t+8>>2]-m))))>2]-pt))+v(d*v(C[t+4>>2]-B)))+v(V*v(C[t+8>>2]-Y))))>2],d=v(p-C[t>>2]),g=v(d*d),d=C[h+12>>2],m=v(d-C[t+4>>2]),g=v(g+v(m*m)),m=C[h+16>>2],y=v(m-C[t+8>>2]),y=v(g+v(y*y)),g=v(34028234663852886e22),y>2]=f[h+20>>2],C[o+8>>2]=m,C[o+4>>2]=d,C[o>>2]=p,D=f[h+32>>2],f[o+20>>2]=f[h+28>>2],f[o+24>>2]=D,f[o+32>>2]=0,f[o+28>>2]=f[h+36>>2],D=_[h+24|0],n[o+16|0]=1&D|240&_[o+16|0]|2&D|4&D,g=y)),p=g,R&&(Ir(t,e,r,a,h+8|0),m=C[h+8>>2],d=v(m-C[t>>2]),g=v(d*d),y=C[h+12>>2],d=v(y-C[t+4>>2]),g=v(g+v(d*d)),B=C[h+16>>2],d=v(B-C[t+8>>2]),(d=v(g+v(d*d)))>2]=f[h+20>>2],C[o+8>>2]=B,C[o+4>>2]=y,C[o>>2]=m,f[o+20>>2]=f[h+28>>2],f[o+24>>2]=0,D=f[(R=h+32|0)+4>>2],f[(Et=o+28|0)>>2]=f[R>>2],f[Et+4>>2]=D,D=(R=_[h+24|0])<<1,n[o+16|0]=8&D|4&D|1&R|240&_[o+16|0],p=d)),Ot&&(Ir(t,e,a,i,h+8|0),m=C[h+8>>2],d=v(m-C[t>>2]),g=v(d*d),y=C[h+12>>2],d=v(y-C[t+4>>2]),g=v(g+v(d*d)),B=C[h+16>>2],d=v(B-C[t+8>>2]),(d=v(g+v(d*d)))>2]=f[h+20>>2],C[o+8>>2]=B,C[o+4>>2]=y,C[o>>2]=m,f[o+20>>2]=f[h+28>>2],f[o+28>>2]=0,f[o+32>>2]=f[h+32>>2],f[o+24>>2]=f[h+36>>2],e=_[h+24|0],n[o+16|0]=1&e|240&_[o+16|0]|e>>>1&2|e<<2&8,p=d)),G=1,W&&(Ir(t,i,a,r,h+8|0),d=C[h+8>>2],m=v(d-C[t>>2]),g=v(m*m),m=C[h+12>>2],y=v(m-C[t+4>>2]),g=v(g+v(y*y)),y=C[h+16>>2],B=v(y-C[t+8>>2]),G=1,v(g+v(B*B))>2]=f[h+20>>2],C[o+8>>2]=y,C[o+4>>2]=m,C[o>>2]=d,f[o+20>>2]=0,f[o+24>>2]=f[h+28>>2],f[o+32>>2]=f[h+32>>2],f[o+28>>2]=f[h+36>>2],t=_[h+24|0],n[o+16|0]=4&t|240&_[o+16|0]|t<<1&2|t<<2&8,G=1)))),Z=h+48|0,t=G}(e,m=t+4|0,h=t+20|0,a=t+36|0,d=t+52|0,r)){f[t+256>>2]=0,g=C[t+336>>2],B=C[t+340>>2],E=C[t+344>>2],p=C[t+348>>2],V=v(v(v(v(g*C[t+92>>2])+v(B*C[t+108>>2]))+v(E*C[t+124>>2]))+v(p*C[t+140>>2])),C[t+252>>2]=V,Q=v(v(v(v(g*C[t+88>>2])+v(B*C[t+104>>2]))+v(E*C[t+120>>2]))+v(p*C[t+136>>2])),C[t+248>>2]=Q,R=t+100|0,w=t+116|0,F=t+132|0,W=v(v(v(v(g*C[t+84>>2])+v(B*C[R>>2]))+v(E*C[w>>2]))+v(p*C[F>>2])),C[t+244>>2]=W,f[t+288>>2]=0,f[t+272>>2]=0,y=t+180|0,D=t+196|0,G=t+212|0,z=v(v(v(v(g*C[t+164>>2])+v(B*C[y>>2]))+v(E*C[D>>2]))+v(p*C[G>>2])),C[t+260>>2]=z,yt=v(v(v(v(g*C[t+168>>2])+v(B*C[t+184>>2]))+v(E*C[t+200>>2]))+v(p*C[t+216>>2])),C[t+264>>2]=yt,g=v(v(v(v(g*C[t+172>>2])+v(B*C[t+188>>2]))+v(E*C[t+204>>2]))+v(p*C[t+220>>2])),C[t+268>>2]=g,C[t+276>>2]=W-z,C[t+280>>2]=Q-yt,C[t+284>>2]=V-g;r:{n:{a:{o:{s:{l:if((0|(i=f[t>>2]))>=4){if(8&(o=_[t+332|0])){r=i;break l}r=i+-1|0,f[t>>2]=r,Vt=f[(pt=(i=(r<<4)+t|0)+12|0)+4>>2],f[(Y=d+8|0)>>2]=f[pt>>2],f[Y+4>>2]=Vt,pt=f[(Y=i+4|0)+4>>2],f[d>>2]=f[Y>>2],f[d+4>>2]=pt,pt=f[(Y=i+92|0)+4>>2],f[(d=F+8|0)>>2]=f[Y>>2],f[d+4>>2]=pt,Y=f[(d=i+84|0)+4>>2],f[F>>2]=f[d>>2],f[F+4>>2]=Y,F=f[(d=i+164|0)+4>>2],f[G>>2]=f[d>>2],f[G+4>>2]=F,F=f[(i=i+172|0)+4>>2],f[(d=G+8|0)>>2]=f[i>>2],f[d+4>>2]=F}else{if(r=3,3!=(0|i))break s;o=_[t+332|0]}if(4&o)break o;r=r+-1|0,f[t>>2]=r,G=f[(F=(i=(r<<4)+t|0)+12|0)+4>>2],f[(d=a+8|0)>>2]=f[F>>2],f[d+4>>2]=G,F=f[(d=i+4|0)+4>>2],f[a>>2]=f[d>>2],f[a+4>>2]=F,F=f[(d=i+92|0)+4>>2],f[(a=w+8|0)>>2]=f[d>>2],f[a+4>>2]=F,d=f[(a=i+84|0)+4>>2],f[w>>2]=f[a>>2],f[w+4>>2]=d,d=f[(a=i+164|0)+4>>2],f[D>>2]=f[a>>2],f[D+4>>2]=d,d=f[(i=i+172|0)+4>>2],f[(a=D+8|0)>>2]=f[i>>2],f[a+4>>2]=d;break o}if(r=2,(0|i)<2)break a;o=_[t+332|0]}if(2&o)break n;r=r+-1|0,f[t>>2]=r,w=f[(d=(i=(r<<4)+t|0)+12|0)+4>>2],f[(a=h+8|0)>>2]=f[d>>2],f[a+4>>2]=w,d=f[(a=i+4|0)+4>>2],f[h>>2]=f[a>>2],f[h+4>>2]=d,d=f[(a=i+92|0)+4>>2],f[(h=R+8|0)>>2]=f[a>>2],f[h+4>>2]=d,a=f[(h=i+84|0)+4>>2],f[R>>2]=f[h>>2],f[R+4>>2]=a,a=f[(h=i+164|0)+4>>2],f[y>>2]=f[h>>2],f[y+4>>2]=a,a=f[(i=i+172|0)+4>>2],f[(h=y+8|0)>>2]=f[i>>2],f[h+4>>2]=a;break n}if(r=1,1!=(0|i))break r;o=_[t+332|0]}1&o||(r=r+-1|0,f[t>>2]=r,h=f[(o=(r=(r<<4)+t|0)+12|0)+4>>2],f[(i=m+8|0)>>2]=f[o>>2],f[i+4>>2]=h,o=f[(i=r+4|0)+4>>2],f[m>>2]=f[i>>2],f[m+4>>2]=o,h=f[(m=r+92|0)+4>>2],f[(o=(i=t+84|0)+8|0)>>2]=f[m>>2],f[o+4>>2]=h,m=f[(o=r+84|0)+4>>2],f[i>>2]=f[o>>2],f[i+4>>2]=m,h=f[(m=r+164|0)+4>>2],f[(i=t+164|0)>>2]=f[m>>2],f[i+4>>2]=h,o=f[(r=r+172|0)+4>>2],f[(i=i+8|0)>>2]=f[r>>2],f[i+4>>2]=o)}if(r=0,C[Dt>>2]>=v(0)^1|C[t+340>>2]>=v(0)^1|C[t+344>>2]>=v(0)^1)break e;r=p>=v(0);break e}if(!_[t+352|0])break A;break;case 0:break i}r=0;break e}f[t+276>>2]=0,f[t+280>>2]=0,r=1,n[t+312|0]=1,f[(t=t+284|0)>>2]=0,f[t+4>>2]=0;break t}r=f[t+168>>2],f[t+260>>2]=f[t+164>>2],f[t+264>>2]=r,r=f[t+88>>2],f[t+244>>2]=f[t+84>>2],f[t+248>>2]=r,h=f[(m=t+172|0)+4>>2],f[(r=o=t+268|0)>>2]=f[m>>2],f[r+4>>2]=h,h=f[(m=t+92|0)+4>>2],f[(r=t+252|0)>>2]=f[m>>2],f[r+4>>2]=h,n[t+352|0]=0,f[t+288>>2]=0,C[t+280>>2]=C[t+248>>2]-C[t+264>>2],C[t+276>>2]=C[t+244>>2]-C[t+260>>2],C[t+284>>2]=C[r>>2]-C[o>>2],f[(r=t+344|0)>>2]=0,f[r+4>>2]=0,f[t+336>>2]=1065353216,f[t+340>>2]=0,n[t+332|0]=i,r=1}n[t+312|0]=r}else r=_[t+312|0];return Z=e+16|0,0!=(255&r)}function Ir(t,e,i,r,a){var o,h,d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),Z=v(0),z=v(0),yt=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0);o=-16&_[a+16|0],n[a+16|0]=o,It=C[r>>2],D=C[e>>2],G=v(It-D),R=C[t>>2],d=v(R-D),St=C[r+4>>2],B=C[e+4>>2],w=v(St-B),y=C[t+4>>2],g=v(y-B),Tt=C[r+8>>2],E=C[e+8>>2],Q=v(Tt-E),F=C[t+8>>2],m=v(F-E),p=v(v(v(G*d)+v(w*g))+v(Q*m)),h=a,z=C[i>>2],W=v(z-D),yt=C[i+4>>2],Y=v(yt-B),pt=C[i+8>>2],Z=v(pt-E),(g=v(v(v(W*d)+v(Y*g))+v(Z*m)))<=v(0)^1|p<=v(0)^1?(d=v(R-z),m=v(y-yt),V=v(F-pt),Dt=v(v(v(G*d)+v(w*m))+v(Q*V)),(m=v(v(v(W*d)+v(Y*m))+v(Z*V)))>=v(0)^1|Dt<=m^1?(V=v(v(g*Dt)-v(m*p)),m<=v(0)^1|g>=v(0)^1||(d=v(0),!(V<=v(0)))?(d=v(R-It),y=v(y-St),F=v(F-Tt),R=v(v(v(W*d)+v(Y*y))+v(Z*F)),(d=v(v(v(G*d)+v(w*y))+v(Q*F)))>=v(0)^1|R<=d^1?(y=v(v(R*p)-v(g*d)),d<=v(0)^1|p>=v(0)^1||(g=v(0),!(y<=v(0)))?(p=v(v(m*d)-v(R*Dt)))<=v(0)&&((g=v(Dt-m))>=v(0)&&(d=v(R-d))>=v(0))?(f[a+12>>2]=0,n[a+16|0]=6|o,d=v(g/v(g+d)),C[a+8>>2]=pt+v(v(Tt-pt)*d),C[a+4>>2]=yt+v(v(St-yt)*d),C[a>>2]=z+v(v(It-z)*d),g=v(v(1)-d),m=v(0)):(f[a+12>>2]=0,n[a+16|0]=7|o,g=v(v(1)/v(V+v(p+y))),d=v(V*g),g=v(y*g),C[a+8>>2]=v(Q*d)+v(E+v(Z*g)),C[a+4>>2]=v(w*d)+v(B+v(Y*g)),C[a>>2]=v(G*d)+v(D+v(W*g)),m=v(v(v(1)-g)-d)):(f[a+12>>2]=0,n[a+16|0]=5|o,d=v(p/v(p-d)),C[a+8>>2]=E+v(Q*d),C[a+4>>2]=B+v(w*d),C[a>>2]=D+v(G*d),m=v(v(1)-d))):(t=f[r+4>>2],f[a>>2]=f[r>>2],f[a+4>>2]=t,e=f[(t=r+8|0)+4>>2],f[(i=a+8|0)>>2]=f[t>>2],f[i+4>>2]=e,n[a+16|0]=4|o,d=v(1),g=v(0),m=v(0))):(f[a+12>>2]=0,n[a+16|0]=3|o,g=v(g/v(g-m)),C[a+8>>2]=E+v(Z*g),C[a+4>>2]=B+v(Y*g),C[a>>2]=D+v(W*g),m=v(v(1)-g))):(t=f[i+4>>2],f[a>>2]=f[i>>2],f[a+4>>2]=t,e=f[(t=i+8|0)+4>>2],f[(i=a+8|0)>>2]=f[t>>2],f[i+4>>2]=e,n[a+16|0]=2|o,g=v(1),d=v(0),m=v(0))):(t=f[e+4>>2],f[a>>2]=f[e>>2],f[a+4>>2]=t,e=f[(t=e+8|0)+4>>2],f[(i=a+8|0)>>2]=f[t>>2],f[i+4>>2]=e,n[a+16|0]=1|o,g=v(0),d=v(0),m=v(1)),C[h+20>>2]=m,f[a+32>>2]=0,C[a+28>>2]=d,C[a+24>>2]=g}function Jr(t,e){var i,r,n,a=0;return r=Nr(t),n=f[(i=t+284|0)+4>>2],f[(a=e+8|0)>>2]=f[i>>2],f[a+4>>2]=n,a=f[t+280>>2],f[e>>2]=f[t+276>>2],f[e+4>>2]=a,r}function xr(t,e){var i=0,r=v(0),n=0,a=0,o=v(0),_=v(0),h=v(0),d=v(0),g=v(0);n=0;t:if(!((0|(a=f[t>>2]))<1)){for(i=t+8|0,_=C[t+308>>2],h=C[e+8>>2],d=C[e+4>>2],g=C[e>>2];;){if(r=v(g-C[i+-4>>2]),o=v(r*r),r=v(d-C[i>>2]),o=v(o+v(r*r)),r=v(h-C[i+4>>2]),n=1,v(o+v(r*r))<=_)break t;if(i=i+16|0,!(a=a+-1|0))break}n=0}return i=n,C[e+12>>2]!=C[t+304>>2]|C[e+8>>2]!=C[t+300>>2]|C[e+4>>2]!=C[t+296>>2]|C[e>>2]!=C[t+292>>2]||(i=1),i}function Ur(t,e,i){var r=0,n=0;Nr(t),r=f[t+248>>2],f[e>>2]=f[t+244>>2],f[e+4>>2]=r,n=f[(r=t+252|0)+4>>2],f[(e=e+8|0)>>2]=f[r>>2],f[e+4>>2]=n,n=f[(r=t+268|0)+4>>2],f[(e=i+8|0)>>2]=f[r>>2],f[e+4>>2]=n,e=f[t+264>>2],f[i>>2]=f[t+260>>2],f[i+4>>2]=e}function Mr(t,e,i,r,a){var o,_=v(0),h=v(0);return f[t>>2]=14908,f[t+32>>2]=i,f[t+28>>2]=e,f[t+24>>2]=r,f[t+20>>2]=a,f[t+4>>2]=0,f[t+8>>2]=1065353216,f[(r=t+12|0)>>2]=0,f[r+4>>2]=0,f[t+36>>2]=f[e+4>>2],f[t+40>>2]=f[i+4>>2],o=t,h=v(yt[f[f[e>>2]+48>>2]](e)),C[o+44>>2]=h,_=v(yt[f[f[i>>2]+48>>2]](i)),f[t+72>>2]=1,f[t+76>>2]=1,f[t+60>>2]=-1,n[t+52|0]=0,C[t+48>>2]=_,t}function Sr(t,e,i,r,n){(function(t,e,i,r){var n,a=0,o=v(0),h=v(0),d=0,g=v(0),m=v(0),y=v(0),p=0,R=0,D=v(0),B=v(0),F=v(0),V=v(0),G=0,w=v(0),Q=v(0),W=0,Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=0,St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0),Gt=v(0),Lt=v(0),wt=v(0),xt=v(0),Qt=v(0),Wt=v(0),Yt=v(0),Pt=v(0),Mt=v(0),Zt=v(0),Ut=v(0),Xt=v(0),Jt=v(0),jt=v(0),zt=v(0),Ht=v(0);for(Z=n=Z-272|0,f[t+56>>2]=0,f[(p=n+264|0)>>2]=0,f[p+4>>2]=0,f[n+256>>2]=0,f[n+260>>2]=0,d=f[(a=e+8|0)+4>>2],f[(p=n+168|0)>>2]=f[a>>2],f[p+4>>2]=d,d=f[(a=e+24|0)+4>>2],f[(p=n+184|0)>>2]=f[a>>2],f[p+4>>2]=d,d=f[(a=e+40|0)+4>>2],f[(p=n+200|0)>>2]=f[a>>2],f[p+4>>2]=d,R=f[(d=e+56|0)+4>>2],f[(a=p=n+216|0)>>2]=f[d>>2],f[a+4>>2]=R,a=f[e+4>>2],f[n+160>>2]=f[e>>2],f[n+164>>2]=a,a=f[e+20>>2],f[n+176>>2]=f[e+16>>2],f[n+180>>2]=a,a=f[e+36>>2],f[n+192>>2]=f[e+32>>2],f[n+196>>2]=a,a=f[e+52>>2],f[n+208>>2]=f[e+48>>2],f[n+212>>2]=a,G=f[(R=e+120|0)+4>>2],f[(a=n+152|0)>>2]=f[R>>2],f[a+4>>2]=G,G=f[(R=e+72|0)+4>>2],f[(d=n+104|0)>>2]=f[R>>2],f[d+4>>2]=G,G=f[(R=e+88|0)+4>>2],f[(d=n+120|0)>>2]=f[R>>2],f[d+4>>2]=G,G=f[(R=e+104|0)+4>>2],f[(d=n+136|0)>>2]=f[R>>2],f[d+4>>2]=G,d=f[e+68>>2],f[n+96>>2]=f[e+64>>2],f[n+100>>2]=d,R=f[(d=e+80|0)+4>>2],f[n+112>>2]=f[d>>2],f[n+116>>2]=R,R=f[(d=e+96|0)+4>>2],f[n+128>>2]=f[d>>2],f[n+132>>2]=R,R=f[(d=e+112|0)+4>>2],f[n+144>>2]=f[d>>2],f[n+148>>2]=R,o=C[(d=n+148|0)>>2],h=C[(R=n+212|0)>>2],g=C[n+144>>2],m=C[n+208>>2],B=C[p>>2],y=C[a>>2],z=v(v(B+y)*v(.5)),C[p>>2]=B-z,pt=v(v(h+o)*v(.5)),C[R>>2]=h-pt,Dt=v(v(m+g)*v(.5)),C[n+208>>2]=m-Dt,C[a>>2]=y-z,C[d>>2]=o-pt,C[n+144>>2]=g-Dt,R=0,R=f[f[t+28>>2]+4>>2]+-17>>>0<=1?f[f[t+32>>2]+4>>2]+-17>>>0<2:R,f[t+68>>2]=0,f[t+4>>2]=0,f[t+8>>2]=1065353216,f[t+60>>2]=-1,f[t+64>>2]=0,f[(p=t+12|0)>>2]=0,f[p+4>>2]=0,f[432]=f[432]+1,D=C[t+44>>2],o=C[t+48>>2],G=_[t+52|0],Yr(f[t+24>>2]),B=G?v(0):o,p=t+4|0,h=v(0xde0b6b000000000),d=0;;){f[n+252>>2]=0,m=C[t+4>>2],y=v(-m),o=C[t+8>>2],g=C[t+12>>2],C[n+248>>2]=v(v(C[e+8>>2]*y)-v(C[e+24>>2]*o))-v(C[e+40>>2]*g),C[n+244>>2]=v(v(C[e+4>>2]*y)-v(o*C[e+20>>2]))-v(g*C[e+36>>2]),C[n+240>>2]=v(v(C[e>>2]*y)-v(o*C[e+16>>2]))-v(g*C[e+32>>2]),f[n+236>>2]=0,C[n+232>>2]=v(v(m*C[e+72>>2])+v(o*C[e+88>>2]))+v(g*C[e+104>>2]),C[n+228>>2]=v(v(m*C[e+68>>2])+v(o*C[e+84>>2]))+v(g*C[e+100>>2]),C[n+224>>2]=v(v(m*C[e+64>>2])+v(o*C[e+80>>2]))+v(g*C[e+96>>2]),hA(n+80|0,f[t+28>>2],n+240|0),hA(n- -64|0,f[t+32>>2],n+224|0),f[n+60>>2]=0,o=C[n+80>>2],m=C[n+84>>2],y=C[n+88>>2],g=v(v(v(v(o*C[n+192>>2])+v(m*C[n+196>>2]))+v(y*C[n+200>>2]))+C[n+216>>2]),C[n+56>>2]=g,V=v(v(v(v(o*C[n+176>>2])+v(m*C[n+180>>2]))+v(y*C[n+184>>2]))+C[n+212>>2]),C[n+52>>2]=V,Q=v(v(v(v(o*C[n+160>>2])+v(m*C[n+164>>2]))+v(y*C[n+168>>2]))+C[n+208>>2]),C[n+48>>2]=Q,f[n+44>>2]=0,o=C[n+64>>2],y=C[n+68>>2],F=C[n+72>>2],m=v(v(v(v(o*C[n+128>>2])+v(y*C[n+132>>2]))+v(F*C[n+136>>2]))+C[n+152>>2]),C[n+40>>2]=m,w=v(v(v(v(o*C[n+112>>2])+v(y*C[n+116>>2]))+v(F*C[n+120>>2]))+C[n+148>>2]),C[n+36>>2]=w,o=v(v(v(v(o*C[n+96>>2])+v(y*C[n+100>>2]))+v(F*C[n+104>>2]))+C[n+144>>2]),C[n+32>>2]=o,R&&(f[n+40>>2]=0,f[n+56>>2]=0,m=v(0),g=v(0)),f[n+28>>2]=0,y=v(V-w),C[n+20>>2]=y,F=C[t+8>>2],o=v(Q-o),C[n+16>>2]=o,V=C[t+4>>2],g=v(g-m),C[n+24>>2]=g;t:{if((o=v(v(v(o*V)+v(y*F))+v(g*C[t+12>>2])))>v(0)^1|v(o*o)>v(h*C[e+128>>2])^1){if(xr(f[t+24>>2],n+16|0)){d=1,f[t+68>>2]=1,a=2;break t}if((o=v(h-o))<=v(h*v(9.999999974752427e-7))){a=2,f[t+68>>2]=o<=v(0)?2:11,d=1;break t}if(Vr(f[t+24>>2],n+16|0,n+48|0,n+32|0),Jr(f[t+24>>2],n)){if(o=C[n>>2],g=v(o*o),o=C[n+4>>2],g=v(g+v(o*o)),o=C[n+8>>2],!((o=v(g+v(o*o)))>2]=12,d=1,a=2):(a=f[n+4>>2],f[p>>2]=f[n>>2],f[p+4>>2]=a,It=f[(W=n+8|0)+4>>2],f[(a=p+8|0)>>2]=f[W>>2],f[a+4>>2]=It,W=f[t+64>>2],f[t+64>>2]=W+1,a=2,(0|W)>1e3||(4==f[f[t+24>>2]>>2]?f[t+68>>2]=13:a=0)),h=o;break t}a=f[n+4>>2],f[p>>2]=f[n>>2],f[p+4>>2]=a,f[t+68>>2]=6,W=f[(d=n+8|0)+4>>2],f[(a=p+8|0)>>2]=f[d>>2],f[a+4>>2]=W}else f[t+68>>2]=3}else f[t+68>>2]=10;d=1,a=2}if(a)break}o=v(0),g=G?v(0):D,m=v(g+B),R=0,a=0,1&d&&(Ur(f[t+24>>2],n+240|0,n+224|0),G=f[(d=p+8|0)+4>>2],f[(a=n+264|0)>>2]=f[d>>2],f[a+4>>2]=G,a=f[p+4>>2],f[n+256>>2]=f[p>>2],f[n+260>>2]=a,o=C[t+4>>2],y=C[t+8>>2],F=C[t+12>>2],(D=v(v(v(o*o)+v(y*y))+v(F*F)))>2]=5),d=1,D>v(14210854715202004e-30)?(D=v(v(1)/v(E(D))),C[n+256>>2]=D*C[n+256>>2],C[n+260>>2]=D*C[n+260>>2],C[n+264>>2]=D*C[n+264>>2],V=v(E(h)),h=v(g/V),C[n+240>>2]=C[n+240>>2]-v(h*o),C[n+244>>2]=C[n+244>>2]-v(h*y),C[n+248>>2]=C[n+248>>2]-v(h*F),h=v(B/V),C[n+224>>2]=v(h*o)+C[n+224>>2],C[n+228>>2]=v(h*y)+C[n+228>>2],C[n+232>>2]=v(h*F)+C[n+232>>2],a=1,o=v(v(v(1)/D)-m)):(a=0,d=2,o=v(0)),f[t+60>>2]=d),!f[t+68>>2]|!f[t+72>>2]|!f[t+20>>2]||(R=v(m+o)>2])){if(f[p>>2]=0,f[p+4>>2]=0,f[(G=p+8|0)>>2]=0,f[G+4>>2]=0,f[431]=f[431]+1,yt[f[f[R>>2]+8>>2]](R,f[t+24>>2],f[t+28>>2],f[t+32>>2],n+160|0,n+96|0,p,n+80|0,n- -64|0,r)){if(F=v(0),h=C[n+64>>2],D=C[n+80>>2],B=v(h-D),V=C[n+68>>2],Q=C[n+84>>2],y=v(V-Q),w=C[n+72>>2],Y=C[n+88>>2],g=v(w-Y),(m=v(v(v(B*B)+v(y*y))+v(g*g)))<=v(14210854715202004e-30)&&(F=C[t+16>>2],B=C[t+4>>2],y=C[t+8>>2],g=C[t+12>>2],m=v(v(v(B*B)+v(y*y))+v(g*g))),m>v(14210854715202004e-30)){if(f[t+60>>2]=3,h=v(D-h),D=v(h*h),h=v(Q-V),D=v(D+v(h*h)),h=v(Y-w),!((o>(h=v(-v(E(v(D+v(h*h))))))^-1)&(1^d))){d=f[(a=n+88|0)+4>>2],f[(r=n+248|0)>>2]=f[a>>2],f[r+4>>2]=d,d=f[(a=n+72|0)+4>>2],f[(r=n+232|0)>>2]=f[a>>2],f[r+4>>2]=d,r=f[n+84>>2],f[n+240>>2]=f[n+80>>2],f[n+244>>2]=r,r=f[n+68>>2],f[n+224>>2]=f[n+64>>2],f[n+228>>2]=r,C[n+268>>2]=F,o=v(v(1)/v(E(m))),C[n+264>>2]=g*o,C[n+260>>2]=y*o,C[n+256>>2]=B*o,o=h;break e}if(f[t+60>>2]=8,a)break e;break t}if(f[t+60>>2]=9,a)break e;break t}if(y=C[t+4>>2],F=C[t+8>>2],D=C[t+12>>2],v(v(v(y*y)+v(F*F))+v(D*D))>v(0)){if(h=v(C[n+80>>2]-C[n+64>>2]),V=v(h*h),h=v(C[n+84>>2]-C[n+68>>2]),V=v(V+v(h*h)),h=v(C[n+88>>2]-C[n+72>>2]),!(((h=v(v(E(v(V+v(h*h))))-m))>2],f[(a=n+248|0)>>2]=f[d>>2],f[a+4>>2]=R,R=f[(d=n+72|0)+4>>2],f[(r=n+232|0)>>2]=f[d>>2],f[r+4>>2]=R,C[a>>2]=C[a>>2]-v(g*D),C[r>>2]=v(B*D)+C[r>>2],r=f[n+68>>2],f[n+224>>2]=f[n+64>>2],f[n+228>>2]=r,r=f[n+84>>2],f[n+240>>2]=f[n+80>>2],f[n+244>>2]=r,C[n+224>>2]=v(B*y)+C[n+224>>2],C[n+228>>2]=v(B*F)+C[n+228>>2],C[n+240>>2]=C[n+240>>2]-v(g*y),C[n+244>>2]=C[n+244>>2]-v(g*F),R=f[(d=p+8|0)+4>>2],f[(a=r=n+264|0)>>2]=f[d>>2],f[a+4>>2]=R,a=f[p+4>>2],f[n+256>>2]=f[p>>2],f[n+260>>2]=a,g=C[n+256>>2],m=C[n+260>>2],B=C[r>>2],o=v(v(1)/v(E(v(v(v(g*g)+v(m*m))+v(B*B))))),C[r>>2]=B*o,C[n+260>>2]=m*o,C[n+256>>2]=g*o,f[t+60>>2]=6,o=h;break e}f[t+60>>2]=5}}if(!a)break t}v(o*o)>2]^1&&!(o>2],f[p>>2]=f[n+256>>2],f[p+4>>2]=r,C[t+56>>2]=o,a=f[(r=n+264|0)+4>>2],f[(p=p+8|0)>>2]=f[r>>2],f[p+4>>2]=a,f[n+92>>2]=0,m=C[n+256>>2],h=C[n+260>>2],g=C[r>>2],C[n+88>>2]=v(v(m*C[e+8>>2])+v(h*C[e+24>>2]))+v(g*C[e+40>>2]),C[n+84>>2]=v(v(m*C[e+4>>2])+v(h*C[e+20>>2]))+v(g*C[e+36>>2]),C[n+80>>2]=v(v(m*C[e>>2])+v(h*C[e+16>>2]))+v(g*C[e+32>>2]),f[n+76>>2]=0,m=v(-m),C[n+72>>2]=v(v(C[e+72>>2]*m)-v(h*C[e+88>>2]))-v(g*C[e+104>>2]),C[n+68>>2]=v(v(C[e+68>>2]*m)-v(h*C[e+84>>2]))-v(g*C[e+100>>2]),C[n+64>>2]=v(v(C[e+64>>2]*m)-v(h*C[e+80>>2]))-v(g*C[e+96>>2]),hA(n+48|0,f[t+28>>2],n+80|0),hA(n+32|0,f[t+32>>2],n- -64|0),h=C[r>>2],Y=C[n+216>>2],St=C[n+200>>2],Tt=C[n+192>>2],Et=C[n+196>>2],Ot=C[n+152>>2],Nt=C[n+136>>2],Ft=C[n+128>>2],Vt=C[n+132>>2],Gt=C[n+208>>2],Lt=C[n+168>>2],wt=C[n+160>>2],xt=C[n+164>>2],Qt=C[n+144>>2],Wt=C[n+104>>2],Yt=C[n+96>>2],Pt=C[n+100>>2],Mt=C[n+212>>2],Zt=C[n+184>>2],B=C[n+56>>2],Ut=C[n+176>>2],y=C[n+48>>2],Xt=C[n+180>>2],F=C[n+52>>2],Jt=C[n+148>>2],jt=C[n+120>>2],D=C[n+40>>2],zt=C[n+112>>2],V=C[n+32>>2],Ht=C[n+116>>2],Q=C[n+36>>2],m=C[n+256>>2],g=C[n+260>>2],f[n+92>>2]=0,w=v(-m),C[n+88>>2]=v(v(C[e+8>>2]*w)-v(g*C[e+24>>2]))-v(h*C[e+40>>2]),C[n+84>>2]=v(v(C[e+4>>2]*w)-v(g*C[e+20>>2]))-v(h*C[e+36>>2]),C[n+80>>2]=v(v(C[e>>2]*w)-v(g*C[e+16>>2]))-v(h*C[e+32>>2]),f[n+76>>2]=0,C[n+72>>2]=v(v(m*C[e+72>>2])+v(g*C[e+88>>2]))+v(h*C[e+104>>2]),C[n+68>>2]=v(v(m*C[e+68>>2])+v(g*C[e+84>>2]))+v(h*C[e+100>>2]),C[n+64>>2]=v(v(m*C[e+64>>2])+v(g*C[e+80>>2]))+v(h*C[e+96>>2]),hA(n+48|0,f[t+28>>2],n+80|0),hA(n+32|0,f[t+32>>2],n- -64|0),Q=v(v(v(v(v(Gt+v(v(v(y*wt)+v(F*xt))+v(B*Lt)))-v(Qt+v(v(v(V*Yt)+v(Q*Pt))+v(D*Wt))))*w)-v(g*v(v(Mt+v(v(v(y*Ut)+v(F*Xt))+v(B*Zt)))-v(Jt+v(v(v(V*zt)+v(Q*Ht))+v(D*jt))))))-v(h*v(v(Y+v(v(v(y*Tt)+v(F*Et))+v(B*St)))-v(Ot+v(v(v(V*Ft)+v(Q*Vt))+v(D*Nt)))))),h=C[n+48>>2],g=C[n+52>>2],m=C[n+56>>2],B=C[n+32>>2],y=C[n+36>>2],F=C[n+40>>2],D=C[n+256>>2],V=C[n+260>>2],w=v(v(v(v(v(v(v(h*C[n+160>>2])+v(g*C[n+164>>2]))+v(m*C[n+168>>2]))+C[n+208>>2])-v(v(v(v(B*C[n+96>>2])+v(y*C[n+100>>2]))+v(F*C[n+104>>2]))+C[n+144>>2]))*D)+v(v(v(v(v(v(h*C[n+176>>2])+v(g*C[n+180>>2]))+v(m*C[n+184>>2]))+C[n+212>>2])-v(v(v(v(B*C[n+112>>2])+v(y*C[n+116>>2]))+v(F*C[n+120>>2]))+C[n+148>>2]))*V)),g=v(v(v(v(v(h*C[n+192>>2])+v(g*C[n+196>>2]))+v(m*C[n+200>>2]))+C[n+216>>2])-v(v(v(v(B*C[n+128>>2])+v(y*C[n+132>>2]))+v(F*C[n+136>>2]))+C[n+152>>2])),h=C[r>>2],Q>v(w+v(g*h))&&(f[t+60>>2]=10,C[n+264>>2]=-h,C[n+260>>2]=-V,C[n+256>>2]=-D),f[n+92>>2]=0,C[n+88>>2]=z+C[n+232>>2],C[n+84>>2]=pt+C[n+228>>2],C[n+80>>2]=Dt+C[n+224>>2],yt[f[f[i>>2]+16>>2]](i,n+256|0,n+80|0,o))}Z=n+272|0})(t|=0,e|=0,i|=0,r|=0)}function Xr(){_[2736]||(f[602]=1062847606,f[603]=0,f[600]=1042701022,f[601]=1056964440,f[598]=1062847606,f[599]=0,f[596]=-1093024784,f[597]=1050556081,f[594]=1062847606,f[595]=0,f[592]=-1093024784,f[593]=-1096927567,f[590]=1062847606,f[591]=0,f[588]=1042701022,f[589]=-1090519208,f[586]=1062847572,f[587]=0,f[584]=1057396286,f[585]=0,f[582]=1057396386,f[583]=0,f[580]=1060121912,f[581]=1056964507,f[578]=1057396420,f[579]=0,f[576]=-1098475836,f[577]=1062148969,f[574]=1057396386,f[575]=0,f[572]=-1084636143,f[573]=0,f[570]=1057396420,f[571]=0,f[568]=-1098475836,f[569]=-1085334679,f[566]=1057396386,f[567]=0,f[564]=1060121912,f[565]=-1090519141,f[562]=-2147483648,f[563]=0,f[560]=1058437413,f[561]=1062149053,f[558]=-2147483648,f[559]=0,f[556]=-2147483648,f[557]=1065353216,f[554]=-2147483648,f[555]=0,f[552]=-1089046235,f[553]=1062149053,f[550]=-2147483648,f[551]=0,f[548]=-1082951543,f[549]=1050556148,f[546]=-2147483648,f[547]=0,f[544]=-1082951543,f[545]=-1096927500,f[542]=0,f[543]=0,f[540]=-1089046235,f[541]=-1085334595,f[538]=0,f[539]=0,f[536]=0,f[537]=-1082130432,f[534]=0,f[535]=0,f[532]=1058437413,f[533]=-1085334595,f[530]=0,f[531]=0,f[528]=1064532105,f[529]=-1096927500,f[526]=0,f[527]=0,f[524]=1064532105,f[525]=1050556148,f[522]=-1090087228,f[523]=0,f[520]=1049007812,f[521]=1062148969,f[518]=-1090087262,f[519]=0,f[516]=-1087361736,f[517]=1056964507,f[514]=-1084636042,f[515]=0,f[512]=-1104782626,f[513]=1056964440,f[510]=-1090087262,f[511]=0,f[508]=-1087361736,f[509]=-1090519141,f[506]=-1084636076,f[507]=0,f[504]=-1090087362,f[505]=-2147483648,f[502]=-1090087262,f[503]=0,f[500]=1062847505,f[501]=-2147483648,f[498]=-1084636042,f[499]=0,f[496]=1054458864,f[497]=1050556081,f[494]=-1090087228,f[495]=0,f[492]=1049007812,f[493]=-1085334679,f[490]=-1084636042,f[491]=0,f[488]=-1104782626,f[489]=-1090519208,f[486]=-1084636042,f[487]=0,f[484]=1054458864,f[485]=-1096927567,f[482]=1065353216,f[483]=0,f[480]=-2147483648,f[481]=0,f[478]=1055193471,f[479]=0,f[476]=1063581978,f[477]=0,f[474]=1055193572,f[475]=0,f[472]=1049461434,f[473]=1062847522,f[470]=1055193572,f[471]=0,f[468]=-1086767520,f[469]=1057396202,f[466]=1055193572,f[467]=0,f[464]=-1086767520,f[465]=-1090087446,f[462]=1055193605,f[463]=0,f[460]=1049461434,f[461]=-1084636126,f[458]=-1092290076,f[459]=0,f[456]=1060716128,f[457]=1057396202,f[454]=-1092290043,f[455]=0,f[452]=-1098022214,f[453]=1062847522,f[450]=-1092290177,f[451]=0,f[448]=-1083901670,f[449]=-2147483648,f[446]=-1092290076,f[447]=0,f[444]=-1098022214,f[445]=-1084636126,f[442]=-1092290076,f[443]=0,f[440]=1060716128,f[441]=-1090087446,f[438]=-1082130432,f[439]=0,f[436]=0,f[437]=-2147483648,n[2736]=1)}function Tr(t,e,i,r){var a=0,o=0,h=0,d=0,g=v(0),m=0,y=0,p=0,R=v(0),D=v(0),B=0,E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=0,W=v(0),Y=v(0),Z=v(0),z=0;t:if(Q=f[t+4>>2],!((0|Q)<2))for(d=f[t+12>>2],a=(d+(Q<<4)|0)-16|0,E=C[a>>2],W=C[i>>2],R=C[a+4>>2],Y=C[i+4>>2],D=C[a+8>>2],Z=C[i+8>>2],g=v(v(v(v(E*W)+v(R*Y))+v(D*Z))+r);;){F=C[(a=(z<<4)+d|0)>>2],V=C[a+4>>2],G=C[a+8>>2],w=v(v(v(v(F*W)+v(V*Y))+v(G*Z))+r),B=f[a+12>>2];e:{i:if(g>2]))==f[e+8>>2]&&!((0|a)>=(0|(m=a?a<<1:1)))){if(m?(y=dA(m<<4),a=f[e+4>>2]):y=0,(0|a)>=1)for(d=0;o=f[e+12>>2]+d|0,p=f[o+4>>2],f[(h=d+y|0)>>2]=f[o>>2],f[h+4>>2]=p,p=f[(o=o+8|0)+4>>2],f[(h=h+8|0)>>2]=f[o>>2],f[h+4>>2]=p,d=d+16|0,a=a+-1|0;);(a=f[e+12>>2])&&(_[e+16|0]&&CA(a),f[e+12>>2]=0),f[e+12>>2]=y,n[e+16|0]=1,f[e+8>>2]=m,a=f[e+4>>2]}a=f[e+12>>2]+(a<<4)|0,f[a+12>>2]=B,C[a+8>>2]=G,C[a+4>>2]=V,C[a>>2]=F;break i}if(g=v(g/v(g-w)),D=v(D+v(v(G-D)*g)),R=v(R+v(v(V-R)*g)),g=v(E+v(v(F-E)*g)),(0|(a=f[e+4>>2]))==f[e+8>>2]&&!((0|a)>=(0|(y=a?a<<1:1)))){if(y?(m=dA(y<<4),a=f[e+4>>2]):m=0,(0|a)>=1)for(d=0;B=f[e+12>>2]+d|0,p=f[B+4>>2],f[(o=d+m|0)>>2]=f[B>>2],f[o+4>>2]=p,h=f[(B=B+8|0)+4>>2],f[(o=o+8|0)>>2]=f[B>>2],f[o+4>>2]=h,d=d+16|0,a=a+-1|0;);(a=f[e+12>>2])&&(_[e+16|0]&&CA(a),f[e+12>>2]=0),f[e+12>>2]=m,n[e+16|0]=1,f[e+8>>2]=y,a=f[e+4>>2]}a=f[e+12>>2]+(a<<4)|0,f[a+12>>2]=0,C[a+8>>2]=D,C[a+4>>2]=R,C[a>>2]=g}else{if(!(w>2]))==f[e+8>>2]&&!((0|a)>=(0|(m=a?a<<1:1)))){if(m?(y=dA(m<<4),a=f[e+4>>2]):y=0,(0|a)>=1)for(d=0;o=f[e+12>>2]+d|0,p=f[o+4>>2],f[(h=d+y|0)>>2]=f[o>>2],f[h+4>>2]=p,p=f[(o=o+8|0)+4>>2],f[(h=h+8|0)>>2]=f[o>>2],f[h+4>>2]=p,d=d+16|0,a=a+-1|0;);(a=f[e+12>>2])&&(_[e+16|0]&&CA(a),f[e+12>>2]=0),f[e+12>>2]=y,n[e+16|0]=1,f[e+8>>2]=m,a=f[e+4>>2]}if(a=f[e+12>>2]+(a<<4)|0,f[a+12>>2]=0,C[a+8>>2]=D,C[a+4>>2]=R,C[a>>2]=g,a=f[e+4>>2]+1|0,f[e+4>>2]=a,f[e+8>>2]==(0|a)&&!((0|a)>=(0|(m=a?a<<1:1)))){if(m?(y=dA(m<<4),a=f[e+4>>2]):y=0,(0|a)>=1)for(d=0;o=f[e+12>>2]+d|0,p=f[o+4>>2],f[(h=d+y|0)>>2]=f[o>>2],f[h+4>>2]=p,p=f[(o=o+8|0)+4>>2],f[(h=h+8|0)>>2]=f[o>>2],f[h+4>>2]=p,d=d+16|0,a=a+-1|0;);(a=f[e+12>>2])&&(_[e+16|0]&&CA(a),f[e+12>>2]=0),f[e+12>>2]=y,n[e+16|0]=1,f[e+8>>2]=m,a=f[e+4>>2]}a=f[e+12>>2]+(a<<4)|0,f[a+12>>2]=B,C[a+8>>2]=G,C[a+4>>2]=V,C[a>>2]=F}f[e+4>>2]=f[e+4>>2]+1}if((0|(z=z+1|0))==(0|Q))break t;Z=C[i+8>>2],Y=C[i+4>>2],W=C[i>>2],d=f[t+12>>2],g=w,D=G,R=V,E=F}}function jr(t,e,i,r,n,a,o){var f=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0);return f=C[r>>2],d=C[r+4>>2],g=C[r+8>>2],y=v(v(v(C[i>>2]*f)+v(C[i+4>>2]*d))+v(C[i+8>>2]*g)),_=v(v(v(f*C[t>>2])+v(d*C[t+16>>2]))+v(g*C[t+32>>2])),h=C[n+80>>2],m=v(_*(_>2])+v(d*C[t+20>>2]))+v(g*C[t+36>>2])),h=C[n+84>>2],m=v(m+v(_*(_>2])+v(d*C[t+24>>2]))+v(g*C[t+40>>2])),h=C[n+88>>2],m=(_=v(m+v(_*(_(h=C[n+96>>2])?_:h,_=v(v(v(f*C[e>>2])+v(d*C[e+16>>2]))+v(g*C[e+32>>2])),h=C[a+80>>2],p=v(_*(_>2])+v(d*C[e+20>>2]))+v(g*C[e+36>>2])),h=C[a+84>>2],f=v(v(v(f*C[e+8>>2])+v(d*C[e+24>>2]))+v(g*C[e+40>>2])),d=C[a+88>>2],f=v(v(p+v(_*(_>2],f=v(m+(f>d?f:d)),((d=v(y+f))<(f=v(f-y))?d:f)>o^1}function Or(t,e,i,r,a,o,h,d){var g,y=0,p=0,R=0,D=0,B=0,E=v(0),F=v(0),V=v(0),G=v(0),w=0,Q=v(0),W=v(0),Y=v(0),z=v(0),pt=0,Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0),Gt=v(0),Lt=0,wt=0,xt=0,Qt=v(0),Wt=v(0),Yt=v(0),Pt=v(0),Mt=v(0),Zt=0,Ut=0,Xt=0,Jt=v(0),jt=v(0),zt=v(0);if(Z=g=Z-32|0,(0|(y=f[a+4>>2]))<=-1)for(f[a+8>>2]<=-1&&((p=f[a+12>>2])&&(_[a+16|0]&&CA(p),f[a+12>>2]=0),n[a+16|0]=1,f[a+8>>2]=0,f[a+12>>2]=0),R=y<<4;D=f[g+20>>2],p=f[a+12>>2]+R|0,f[p>>2]=f[g+16>>2],f[p+4>>2]=D,D=f[(B=g+24|0)+4>>2],f[(p=p+8|0)>>2]=f[B>>2],f[p+4>>2]=D,R=R+16|0,B=(p=y+1|0)>>>0>=y>>>0,y=p,B;);if(p=0,f[a+4>>2]=0,B=f[r+4>>2],f[a+8>>2]<(0|B)){if(B&&(p=dA(B<<4),!((0|(R=f[a+4>>2]))<1)))for(y=0;D=f[a+12>>2]+y|0,wt=f[D+4>>2],f[(w=y+p|0)>>2]=f[D>>2],f[w+4>>2]=wt,Lt=f[(D=D+8|0)+4>>2],f[(w=w+8|0)>>2]=f[D>>2],f[w+4>>2]=Lt,y=y+16|0,R=R+-1|0;);(y=f[a+12>>2])&&(_[a+16|0]&&CA(y),f[a+12>>2]=0),f[a+12>>2]=p,n[a+16|0]=1,f[a+8>>2]=B}if(!((0|(D=f[e+28>>2]))<1)){for(y=f[e+36>>2]+20|0,Y=C[i+40>>2],Dt=C[i+36>>2],G=C[i+24>>2],It=C[i+20>>2],z=C[t+8>>2],St=C[t+4>>2],Tt=C[t>>2],Et=C[i+32>>2],Ot=C[i+16>>2],Nt=C[i+8>>2],Ft=C[i+4>>2],Q=C[i>>2],R=0,V=v(34028234663852886e22),B=-1;F=C[y>>2],E=C[y+4>>2],W=C[y+8>>2],V=(p=(F=v(v(v(v(v(v(F*Q)+v(E*Ft))+v(W*Nt))*Tt)+v(v(v(v(F*Ot)+v(E*It))+v(W*G))*St))+v(v(v(v(F*Et)+v(E*Dt))+v(W*Y))*z)))>2]+m(B,36)|0,(0|(Lt=f[D+4>>2]))<1)p=r;else for(wt=D+28|0,Zt=D+24|0,Ut=D+20|0,Xt=D+12|0,y=0;;){if(p=a,w=(0|(B=y+1|0))==(0|Lt),pt=f[e+16>>2],R=f[Xt>>2],a=pt+(f[R+((w?0:B)<<2)>>2]<<4)|0,Vt=C[a+8>>2],Q=C[a>>2],Gt=C[a+4>>2],a=pt+(f[R+(y<<2)>>2]<<4)|0,V=C[a+8>>2],F=C[a>>2],E=C[a+4>>2],Jt=C[i+56>>2],jt=C[i+48>>2],zt=C[i+52>>2],W=C[i+40>>2],Y=C[i+32>>2],Dt=C[i+36>>2],G=C[wt>>2],It=C[i+8>>2],z=C[Ut>>2],St=C[i>>2],Tt=C[Zt>>2],Et=C[i+4>>2],Ot=C[i+24>>2],Nt=C[i+16>>2],Ft=C[i+20>>2],f[g+28>>2]=0,Q=v(F-Q),Gt=v(E-Gt),Vt=v(V-Vt),Qt=v(v(v(St*Q)+v(Et*Gt))+v(It*Vt)),Wt=v(v(v(Nt*z)+v(Ft*Tt))+v(Ot*G)),Yt=v(v(v(Q*Nt)+v(Gt*Ft))+v(Vt*Ot)),Pt=v(v(v(St*z)+v(Et*Tt))+v(It*G)),Mt=v(v(Qt*Wt)-v(Yt*Pt)),C[g+24>>2]=-Mt,Q=v(v(v(Q*Y)+v(Gt*Dt))+v(Vt*W)),G=v(v(v(Y*z)+v(Dt*Tt))+v(W*G)),z=v(v(Q*Pt)-v(Qt*G)),C[g+20>>2]=-z,G=v(-v(v(Yt*G)-v(Q*Wt))),C[g+16>>2]=G,Tr(a=r,p,g+16|0,v(-v(v(v(v(jt+v(v(v(F*St)+v(E*Et))+v(V*It)))*G)-v(v(zt+v(v(v(F*Nt)+v(E*Ft))+v(V*Ot)))*z))-v(v(Jt+v(v(v(F*Y)+v(E*Dt))+v(V*W)))*Mt)))),(0|(y=f[a+4>>2]))<=-1)for(f[a+8>>2]<=-1&&((r=f[a+12>>2])&&(_[a+16|0]&&CA(r),f[a+12>>2]=0),n[a+16|0]=1,f[a+8>>2]=0,f[a+12>>2]=0),R=y<<4;xt=f[g+4>>2],r=f[a+12>>2]+R|0,f[r>>2]=f[g>>2],f[r+4>>2]=xt,xt=f[(pt=g+8|0)+4>>2],f[(r=r+8|0)>>2]=f[pt>>2],f[r+4>>2]=xt,R=R+16|0,pt=(r=y+1|0)>>>0>=y>>>0,y=r,pt;);if(f[a+4>>2]=0,y=B,r=p,w)break}if(!((0|(r=f[p+4>>2]))<1))for(V=C[D+20>>2],F=C[D+24>>2],E=C[D+28>>2],W=v(v(v(V*C[i>>2])+v(F*C[i+4>>2]))+v(E*C[i+8>>2])),Y=v(v(v(V*C[i+16>>2])+v(F*C[i+20>>2]))+v(E*C[i+24>>2])),V=v(v(v(V*C[i+32>>2])+v(F*C[i+36>>2]))+v(E*C[i+40>>2])),F=v(C[D+32>>2]-v(v(v(W*C[i+48>>2])+v(Y*C[i+52>>2]))+v(V*C[i+56>>2]))),R=0,B=0;i=(e=f[p+12>>2]+R|0)+8|0,(E=(E=v(F+v(v(v(W*C[e>>2])+v(Y*C[e+4>>2]))+v(V*C[i>>2]))))<=o?o:E)<=h&&(a=f[i+4>>2],f[(r=g+24|0)>>2]=f[i>>2],f[r+4>>2]=a,i=f[e+4>>2],f[g+16>>2]=f[e>>2],f[g+20>>2]=i,yt[f[f[d>>2]+16>>2]](d,t,g+16|0,E),r=f[p+4>>2]),R=R+16|0,(0|(B=B+1|0))<(0|r););}}Z=g+32|0}function Hr(t,e,i,r){return f[t+12>>2]=i,f[t+8>>2]=e,f[t+4>>2]=r,f[t>>2]=15312,t}function zr(t,e,i,r,a,o){t|=0,e|=0,i|=0,r|=0,a|=0,o|=0;var h,d,g=0,m=0,y=v(0),p=v(0),R=0,D=v(0),B=0,E=v(0),F=v(0),V=v(0),G=0,w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0);Z=h=Z-288|0,Yr(f[t+4>>2]),y=C[e+52>>2],p=C[i+52>>2],D=C[r+52>>2],E=C[a+52>>2],F=C[(g=e+56|0)>>2],V=C[i+56>>2],w=C[(R=r+56|0)>>2],Q=C[a+56>>2],W=C[e+48>>2],Y=C[i+48>>2],z=C[r+48>>2],pt=C[a+48>>2],n[h+264|0]=0,f[h+260>>2]=1566444395,f[h+224>>2]=15364,d=Mr(h+144|0,f[t+8>>2],f[t+12>>2],f[t+4>>2],0),B=f[(m=e+8|0)+4>>2],f[(t=h+16|0)>>2]=f[m>>2],f[t+4>>2]=B,B=f[(m=e+24|0)+4>>2],f[(t=h+32|0)>>2]=f[m>>2],f[t+4>>2]=B,B=f[(m=e+40|0)+4>>2],f[(t=h+48|0)>>2]=f[m>>2],f[t+4>>2]=B,m=f[g+4>>2],f[(t=h- -64|0)>>2]=f[g>>2],f[t+4>>2]=m,m=f[(g=r+8|0)+4>>2],f[(t=h+80|0)>>2]=f[g>>2],f[t+4>>2]=m,f[h+136>>2]=1566444395,t=f[e+4>>2],f[h+8>>2]=f[e>>2],f[h+12>>2]=t,t=f[e+20>>2],f[h+24>>2]=f[e+16>>2],f[h+28>>2]=t,t=f[e+36>>2],f[h+40>>2]=f[e+32>>2],f[h+44>>2]=t,t=f[e+52>>2],f[h+56>>2]=f[e+48>>2],f[h+60>>2]=t,t=f[r+4>>2],f[h+72>>2]=f[r>>2],f[h+76>>2]=t,m=f[(g=r+24|0)+4>>2],f[(t=h+96|0)>>2]=f[g>>2],f[t+4>>2]=m,g=f[r+20>>2],f[(t=h+88|0)>>2]=f[r+16>>2],f[t+4>>2]=g,m=f[(g=r+40|0)+4>>2],f[(t=h+112|0)>>2]=f[g>>2],f[t+4>>2]=m,g=f[r+36>>2],f[(t=h+104|0)>>2]=f[r+32>>2],f[t+4>>2]=g,g=f[R+4>>2],f[(t=h+128|0)>>2]=f[R>>2],f[t+4>>2]=g,g=f[r+52>>2],f[(t=h+120|0)>>2]=f[r+48>>2],f[t+4>>2]=g,Sr(d,h+8|0,h+224|0,0),R=f[(g=h+252|0)+4>>2],f[(t=h+280|0)>>2]=f[g>>2],f[t+4>>2]=R,t=f[h+248>>2],f[h+272>>2]=f[h+244>>2],f[h+276>>2]=t,g=0;t:if(_[h+264|0]){F=v(v(V-F)-v(Q-w)),E=v(v(p-y)-v(E-D)),V=v(v(Y-W)-v(pt-z)),t=f[h+232>>2],m=f[h+236>>2],B=f[h+228>>2];e:{if((D=C[h+260>>2])>v(.0010000000474974513)){for(R=h+244|0,G=33,p=v(0);;){if(g=0,!(G=G+-1|0))break t;if(g=0,(y=v(p-v(D/v(v(F*(b(0,m),k()))+v(v(E*(b(0,t),k()))+v(V*(b(0,B),k())))))))<=p)break t;if(g=0,yv(1))break t;if(yt[f[f[o>>2]>>2]](o,y),p=v(v(1)-y),C[h+56>>2]=v(p*C[e+48>>2])+v(y*C[i+48>>2]),C[h+60>>2]=v(p*C[e+52>>2])+v(y*C[i+52>>2]),C[h+64>>2]=v(p*C[e+56>>2])+v(y*C[i+56>>2]),C[h+120>>2]=v(p*C[r+48>>2])+v(y*C[a+48>>2]),C[h+124>>2]=v(p*C[r+52>>2])+v(y*C[a+52>>2]),C[h+128>>2]=v(p*C[r+56>>2])+v(y*C[a+56>>2]),Sr(d,h+8|0,h+224|0,0),g=0,!_[h+264|0])break t;if((D=C[h+260>>2])>2]=y,t=f[h+232>>2],f[o+132>>2]=f[h+228>>2],f[o+136>>2]=t,e=f[h+240>>2],f[(t=o+140|0)>>2]=f[h+236>>2],f[t+4>>2]=e,t=f[R+4>>2],f[o+148>>2]=f[R>>2],f[o+152>>2]=t,i=f[(e=R+8|0)+4>>2],f[(t=o+156|0)>>2]=f[e>>2],f[t+4>>2]=i;break e}if(m=f[(g=R+8|0)+4>>2],f[(t=h+280|0)>>2]=f[g>>2],f[t+4>>2]=m,t=f[R+4>>2],f[h+272>>2]=f[R>>2],f[h+276>>2]=t,B=f[h+228>>2],t=f[h+232>>2],m=f[h+236>>2],p=y,!(D>v(.0010000000474974513)))break}D=C[h+240>>2]}else y=v(0),D=C[h+240>>2];if(g=0,v(v(F*(b(0,m),k()))+v(v(E*(b(0,t),k()))+v(V*(b(0,B),k()))))>=v(-C[o+172>>2]))break t;f[o+132>>2]=B,C[o+164>>2]=y,e=f[h+276>>2],f[o+148>>2]=f[h+272>>2],f[o+152>>2]=e,C[o+144>>2]=D,f[o+140>>2]=m,f[o+136>>2]=t,i=f[(e=h+280|0)+4>>2],f[(t=o+156|0)>>2]=f[e>>2],f[t+4>>2]=i}g=1}return Z=h+288|0,0|g}function Pr(t,e,i,r,n,a,o,_,h,d,g){var m=v(0),p=v(0),R=v(0),D=v(0),B=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),Z=v(0),z=v(0);V=C[(_=(_<<2)+d|0)>>2],G=v(C[d+48>>2]-C[h+48>>2]),W=C[_+16>>2],Y=v(C[d+52>>2]-C[h+52>>2]),Z=C[_+32>>2],z=v(C[d+56>>2]-C[h+56>>2]),R=v(v(v(V*G)+v(W*Y))+v(Z*z)),w=C[(o=(o<<2)+h|0)>>2],D=C[o+16>>2],F=C[o+32>>2],Q=v(v(v(w*G)+v(D*Y))+v(F*z)),B=v(v(v(w*V)+v(D*W))+v(F*Z)),(p=v(v(1)-v(B*B)))!=v(0)&&((p=v(v(Q-v(B*R))/p))<(m=v(-i))||(m=p)>i&&(m=i));t:{if((p=v(v(B*m)-R))<(R=v(-n))){if((n=v(v(B*R)+Q))<(m=v(-i))){p=R;break t}if(!(n>i)){p=R,m=n;break t}n=R}else{if(!(p>n))break t;if((R=v(v(B*n)+Q))<(m=v(-i))){p=n;break t}if(!(R>i)){p=n,m=R;break t}}p=n,m=i}if(R=v(Z*p),i=v(R+v(z-v(F*m))),B=v(V*p),n=v(B+v(G-v(w*m))),Q=v(W*p),p=v(Q+v(Y-v(D*m))),m=v(v(i*i)+v(v(n*n)+v(p*p))),V=v(E(m)),!((G=v(v(V-r)-a))>g)){t:if(m<=v(14210854715202004e-30)){if(v(y(F))>v(.7071067690849304)){f[t>>2]=0,r=v(v(1)/v(E(v(v(D*D)+v(F*F))))),i=v(D*r),C[t+8>>2]=i,m=v(-v(F*r)),C[t+4>>2]=m,r=v(0);break t}f[t+8>>2]=0,i=v(v(1)/v(E(v(v(w*w)+v(D*D))))),m=v(w*i),C[t+4>>2]=m,r=v(-v(D*i)),C[t>>2]=r,i=v(0)}else f[t+12>>2]=0,r=v(v(-1)/V),i=v(i*r),C[t+8>>2]=i,m=v(p*r),C[t+4>>2]=m,r=v(n*r),C[t>>2]=r;n=C[d+48>>2],g=C[d+52>>2],p=C[d+56>>2],f[e+12>>2]=0,C[e+8>>2]=v(R+p)+v(i*a),C[e+4>>2]=v(Q+g)+v(m*a),C[e>>2]=v(B+n)+v(r*a)}return G}function Kr(t,e,i,r){r=v(r)}function Lr(t,e){return yt[f[748]](e),t}function qr(){yt[f[749]]()}function $r(t,e,i,r){return f[t+12>>2]=i,f[t+8>>2]=e,f[t+4>>2]=r,f[t>>2]=16060,t}function Ai(t,e,i,r,n,a){t|=0,e|=0,i|=0,r|=0,n|=0,a|=0;var o,_,h,d,g,m,y,p,R,D,B=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=0,z=0,pt=v(0),Dt=v(0),It=0,St=v(0),Tt=v(0),Et=v(0),Ot=0,Nt=v(0),Ft=v(0),Vt=v(0),Gt=v(0),Lt=v(0),wt=v(0),xt=v(0),Qt=v(0),Wt=v(0),Yt=v(0),Pt=v(0),Mt=v(0),Zt=v(0),Ut=v(0),Xt=v(0),Jt=v(0),jt=v(0),zt=v(0),Ht=v(0),Kt=v(0),qt=v(0),$t=v(0),bi=v(0),di=v(0),yi=v(0),Ii=v(0),Bi=0;Z=o=Z-96|0,Yr(f[t+4>>2]),jt=C[(Y=r+40|0)>>2],zt=C[(It=r+36|0)>>2],Ht=C[(z=r+24|0)>>2],Kt=C[(_=r+20|0)>>2],Nt=C[(h=e+20|0)>>2],Ft=C[(d=e+36|0)>>2],Vt=C[(g=e+24|0)>>2],Gt=C[(m=e+52|0)>>2],w=C[i+52>>2],Lt=C[(y=r+52|0)>>2],Q=C[n+52>>2],wt=C[(p=e+40|0)>>2],xt=C[(R=e+56|0)>>2],B=C[i+56>>2],Qt=C[(D=r+56|0)>>2],G=C[n+56>>2],qt=C[r+32>>2],$t=C[r+16>>2],bi=C[r+8>>2],di=C[r+4>>2],yi=C[r>>2],Wt=C[e>>2],Yt=C[e+16>>2],Pt=C[e+32>>2],Mt=C[e+4>>2],Zt=C[e+8>>2],Ut=C[e+48>>2],F=C[i+48>>2],Xt=C[r+48>>2],V=C[n+48>>2],Ot=f[t+8>>2],f[o+60>>2]=0,St=v(v(F-Ut)-v(V-Xt)),F=v(-St),pt=v(v(w-Gt)-v(Q-Lt)),Dt=v(v(B-xt)-v(G-Qt)),C[o+56>>2]=v(v(Zt*F)-v(Vt*pt))-v(wt*Dt),C[o+52>>2]=v(v(Mt*F)-v(Nt*pt))-v(Ft*Dt),C[o+48>>2]=v(v(Wt*F)-v(Yt*pt))-v(Pt*Dt),yt[f[f[Ot>>2]+64>>2]](o+80|0,Ot,o+48|0),f[o+76>>2]=0,F=C[o+80>>2],w=C[o+84>>2],Q=C[o+88>>2],C[o+72>>2]=v(v(v(F*C[e+32>>2])+v(w*C[d>>2]))+v(Q*C[p>>2]))+C[R>>2],C[o+68>>2]=v(v(v(F*C[e+16>>2])+v(w*C[h>>2]))+v(Q*C[g>>2]))+C[m>>2],C[o+64>>2]=v(v(v(F*C[e>>2])+v(w*C[e+4>>2]))+v(Q*C[e+8>>2]))+C[e+48>>2],Ot=f[t+12>>2],f[o+28>>2]=0,C[o+24>>2]=v(v(St*C[r+8>>2])+v(pt*C[z>>2]))+v(Dt*C[Y>>2]),C[o+20>>2]=v(v(St*C[r+4>>2])+v(pt*C[_>>2]))+v(Dt*C[It>>2]),C[o+16>>2]=v(v(St*C[r>>2])+v(pt*C[r+16>>2]))+v(Dt*C[r+32>>2]),yt[f[f[Ot>>2]+64>>2]](o+32|0,Ot,o+16|0),f[o+60>>2]=0,F=C[o+32>>2],w=C[o+36>>2],Q=C[o+40>>2],V=v(v(v(v(F*C[r+32>>2])+v(w*C[It>>2]))+v(Q*C[Y>>2]))+C[D>>2]),C[o+56>>2]=V,G=v(v(v(v(F*C[r>>2])+v(w*C[r+4>>2]))+v(Q*C[r+8>>2]))+C[r+48>>2]),C[o+48>>2]=G,F=v(v(v(v(F*C[r+16>>2])+v(w*C[_>>2]))+v(Q*C[z>>2]))+C[y>>2]),C[o+52>>2]=F,f[o+92>>2]=0,B=v(C[o+68>>2]-F),C[o+84>>2]=B,G=v(C[o+64>>2]-G),C[o+80>>2]=G,V=v(C[o+72>>2]-V),C[o+88>>2]=V,F=v(0),w=v(0),Q=v(0);t:{e:if(v(v(v(G*G)+v(B*B))+v(V*V))>v(9999999747378752e-20))for(Y=-33;;){if((It=Y+1|0)>>>0>>0)break e;if(z=f[t+8>>2],Y=0,f[o+12>>2]=0,B=v(-C[o+80>>2]),G=C[o+84>>2],V=C[o+88>>2],C[o+8>>2]=v(v(Zt*B)-v(Vt*G))-v(wt*V),C[o+4>>2]=v(v(Mt*B)-v(Nt*G))-v(Ft*V),C[o>>2]=v(v(Wt*B)-v(Yt*G))-v(Pt*V),yt[f[f[z>>2]+64>>2]](o+16|0,z,o),f[o+76>>2]=0,B=C[o+16>>2],G=C[o+20>>2],V=C[o+24>>2],C[o+72>>2]=xt+v(v(v(Pt*B)+v(Ft*G))+v(wt*V)),C[o+68>>2]=Gt+v(v(v(Yt*B)+v(Nt*G))+v(Vt*V)),C[o+64>>2]=Ut+v(v(v(Wt*B)+v(Mt*G))+v(Zt*V)),z=f[t+12>>2],f[o+12>>2]=0,B=C[o+80>>2],G=C[o+84>>2],V=C[o+88>>2],C[o+8>>2]=v(v(bi*B)+v(Ht*G))+v(jt*V),C[o+4>>2]=v(v(di*B)+v(Kt*G))+v(zt*V),C[o>>2]=v(v(yi*B)+v($t*G))+v(qt*V),yt[f[f[z>>2]+64>>2]](o+16|0,z,o),f[o+60>>2]=0,f[o+44>>2]=0,B=C[o+16>>2],G=C[o+20>>2],V=C[o+24>>2],Tt=v(Qt+v(v(v(qt*B)+v(zt*G))+v(jt*V))),C[o+56>>2]=Tt,Tt=v(C[o+72>>2]-Tt),C[o+40>>2]=Tt,Et=v(Lt+v(v(v($t*B)+v(Kt*G))+v(Ht*V))),C[o+52>>2]=Et,Et=v(C[o+68>>2]-Et),C[o+36>>2]=Et,B=v(Xt+v(v(v(yi*B)+v(di*G))+v(bi*V))),C[o+48>>2]=B,Jt=v(C[o+64>>2]-B),C[o+32>>2]=Jt,W>v(1))break t;if(B=C[o+80>>2],G=C[o+84>>2],V=C[o+88>>2],(Ii=v(v(v(Jt*B)+v(Et*G))+v(Tt*V)))>v(0)){if((F=v(v(v(St*B)+v(pt*G))+v(Dt*V)))>=v(-14210854715202004e-30))break t;f[o+44>>2]=0,C[o+40>>2]=Tt,C[o+36>>2]=Et,C[o+32>>2]=Jt,W=v(W-v(Ii/F)),F=v(v(1)-W),Qt=v(v(F*C[r+56>>2])+v(W*C[n+56>>2])),Lt=v(v(F*C[r+52>>2])+v(W*C[n+52>>2])),Xt=v(v(F*C[r+48>>2])+v(W*C[n+48>>2])),xt=v(v(F*C[e+56>>2])+v(W*C[i+56>>2])),Gt=v(v(F*C[e+52>>2])+v(W*C[i+52>>2])),Ut=v(v(F*C[e+48>>2])+v(W*C[i+48>>2])),Bi=f[o+92>>2],w=G,Q=V,F=B}if(xr(f[t+4>>2],o+32|0)||Vr(f[t+4>>2],o+32|0,o- -64|0,o+48|0),!Jr(f[t+4>>2],o+80|0))break e;if(Y=It,B=C[o+80>>2],V=v(B*B),B=C[o+84>>2],V=v(V+v(B*B)),B=C[o+88>>2],!(v(V+v(B*B))>v(9999999747378752e-20)))break}C[a+164>>2]=W,(B=v(v(v(F*F)+v(w*w))+v(Q*Q)))>=v(14210854715202004e-30)?(f[a+144>>2]=Bi,V=Q,Q=v(v(1)/v(E(B))),W=v(V*Q),C[a+140>>2]=W,w=v(w*Q),C[a+136>>2]=w,F=v(F*Q),C[a+132>>2]=F):(f[a+132>>2]=0,f[a+136>>2]=0,f[(e=a+140|0)>>2]=0,f[e+4>>2]=0,W=v(0),w=v(0),F=v(0)),Y=0,v(v(v(St*F)+v(pt*w))+v(Dt*W))>=v(-C[a+172>>2])||(Ur(f[t+4>>2],o+16|0,o),i=f[(e=o+8|0)+4>>2],f[(t=a+156|0)>>2]=f[e>>2],f[t+4>>2]=i,t=f[o+4>>2],f[a+148>>2]=f[o>>2],f[a+152>>2]=t,Y=1)}return Z=o+96|0,0|Y}function ei(t,e,i,r,a){var o;vA(t,e),f[t>>2]=16120,f[t+8>>2]=16148,f[t+60>>2]=0,o=a?i:r,f[t+48>>2]=o,i=a?r:i,f[t+44>>2]=i,r=t+56|0,e=f[e>>2],f[r>>2]=e,e=0|yt[f[f[e>>2]+12>>2]](e,f[i+8>>2],f[o+8>>2]),f[t+72>>2]=e,i=f[r>>2],yt[f[f[i>>2]+20>>2]](i,e),n[t+76|0]=a}function ri(t,e,i,r,a){var o=0;vA(t,e),n[t+24|0]=1,f[t>>2]=16696,f[t+20>>2]=0,n[t+44|0]=1,f[(o=t+12|0)>>2]=0,f[o+4>>2]=0,f[t+40>>2]=0,n[t- -64|0]=1,f[(o=t+32|0)>>2]=0,f[o+4>>2]=0,f[t+60>>2]=0,n[t+68|0]=a,f[(o=t+52|0)>>2]=0,f[o+4>>2]=0,n[t+76|0]=0,f[t+72>>2]=f[e+4>>2],f[t+80>>2]=f[f[(a?r:i)+4>>2]+72>>2],ii(t,i,r)}function ii(t,e,i){var r,a,o,h,d,C=0,g=0,m=0,v=0;if(Z=r=Z-32|0,v=f[t+52>>2],d=_[t+68|0],h=f[(o=d?i:e)+4>>2],(0|v)<(0|(a=f[h+20>>2]))){if(f[t+56>>2]<(0|a)){if(a?(m=dA(a<<2),C=f[t+52>>2]):C=v,(0|C)>=1)for(;f[g+m>>2]=f[f[t+60>>2]+g>>2],g=g+4|0,C=C+-1|0;);(C=f[t+60>>2])&&(_[t- -64|0]&&CA(C),f[t+60>>2]=0),f[t+60>>2]=m,f[t+56>>2]=a,n[t- -64|0]=1}for(g=v<<2,C=a-v|0;f[f[t+60>>2]+g>>2]=0,g=g+4|0,C=C+-1|0;);}if(f[t+52>>2]=a,(0|a)>=1)for(e=d?e:i,C=64,g=0,m=0;f[h+68>>2]?f[f[t+60>>2]+g>>2]=0:(i=f[f[h+28>>2]+C>>2],f[r+28>>2]=m,f[r+24>>2]=-1,f[r+8>>2]=o,v=f[o+12>>2],f[r+16>>2]=f[o+8>>2],f[r+20>>2]=v,f[r+12>>2]=i,i=f[t+4>>2],i=0|yt[f[f[i>>2]+8>>2]](i,r+8|0,e,f[t+72>>2],1),f[f[t+60>>2]+g>>2]=i),C=C+80|0,g=g+4|0,(0|(m=m+1|0))!=(0|a););Z=r+32|0}function fi(t){var e=0,i=0,r=0;if(f[(t|=0)>>2]=16696,(0|(r=f[t+52>>2]))>=1)for(;(i=f[f[t+60>>2]+e>>2])&&(yt[f[f[i>>2]>>2]](i),i=f[t+4>>2],yt[f[f[i>>2]+60>>2]](i,f[f[t+60>>2]+e>>2])),e=e+4|0,r=r+-1|0;);return(e=f[t+60>>2])&&(_[t- -64|0]&&CA(e),f[t+60>>2]=0),f[t+60>>2]=0,f[t+52>>2]=0,f[t+56>>2]=0,n[t- -64|0]=1,(e=f[t+40>>2])&&(_[t+44|0]&&CA(e),f[t+40>>2]=0),f[t+40>>2]=0,f[t+32>>2]=0,f[t+36>>2]=0,n[t+44|0]=1,(e=f[t+20>>2])&&(_[t+24|0]&&CA(e),f[t+20>>2]=0),f[t+20>>2]=0,f[t+12>>2]=0,f[t+16>>2]=0,n[t+24|0]=1,0|t}function ti(t,e,i,r,a){t|=0,e|=0,i|=0,r|=0,a|=0;var o,h,d,g=0,m=0,y=0,p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=0,W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0),Gt=v(0),Lt=v(0),wt=0,xt=0,Qt=0,Wt=0;if(Z=o=Z-176|0,Q=_[t+68|0],h=f[(d=Q?i:e)+4>>2],f[h+72>>2]!=f[t+80>>2]){if((0|(y=f[t+52>>2]))>=1)for(;(m=f[f[t+60>>2]+g>>2])&&(yt[f[f[m>>2]>>2]](m),m=f[t+4>>2],yt[f[f[m>>2]+60>>2]](m,f[f[t+60>>2]+g>>2])),g=g+4|0,y=y+-1|0;);ii(t,e,i),f[t+80>>2]=f[h+72>>2]}if(m=f[t+52>>2]){if(y=f[h+68>>2],f[o+164>>2]=a,f[o+160>>2]=r,Q=Q?e:i,f[o+152>>2]=Q,f[o+148>>2]=d,f[o+144>>2]=16768,f[o+172>>2]=f[t+72>>2],f[o+168>>2]=f[t+60>>2],f[o+156>>2]=f[t+4>>2],(0|(g=f[t+32>>2]))<=-1){for(f[t+36>>2]<=-1&&((e=f[t+40>>2])&&(_[t+44|0]&&CA(e),f[t+40>>2]=0),f[t+36>>2]=0,f[t+40>>2]=0,n[t+44|0]=1),m=g<<2;f[f[t+40>>2]+m>>2]=0,m=m+4|0,i=(e=g+1|0)>>>0>=g>>>0,g=e,i;);m=f[t+52>>2]}if(f[t+32>>2]=0,(0|m)>=1)for(Qt=t+28|0,i=0;;){if(e=f[f[t+60>>2]+(i<<2)>>2]){if(yt[f[f[e>>2]+16>>2]](e,Qt),(0|(g=f[t+32>>2]))>=1)for(m=0,e=0;r=f[f[t+40>>2]+m>>2],f[r+780>>2]&&(f[a+4>>2]=r,g=(0|(wt=f[r+772>>2]))==(0|(xt=f[f[a+8>>2]+8>>2])),Wt=r,r=f[f[a+12>>2]+8>>2],se(Wt,(g?wt:r)+4|0,(g?r:xt)+4|0),f[a+4>>2]=0,g=f[t+32>>2]),m=m+4|0,(0|(e=e+1|0))<(0|g););if((0|g)<=-1)for(f[t+36>>2]<=-1&&((e=f[t+40>>2])&&(_[t+44|0]&&CA(e),f[t+40>>2]=0),n[t+44|0]=1,f[t+36>>2]=0,f[t+40>>2]=0),m=g<<2;f[f[t+40>>2]+m>>2]=0,m=m+4|0,r=(e=g+1|0)>>>0>=g>>>0,g=e,r;);f[t+32>>2]=0,m=f[t+52>>2]}if(!((0|(i=i+1|0))<(0|m)))break}t:if(y)e=f[d+12>>2],W=C[e+52>>2],Y=C[e+56>>2],i=f[Q+12>>2],z=C[i+52>>2],pt=C[i+56>>2],p=C[e+20>>2],R=C[e+36>>2],Dt=C[i+20>>2],It=C[i+36>>2],St=C[i+24>>2],D=C[e+24>>2],Tt=C[i+40>>2],B=C[e+40>>2],Et=C[i+32>>2],E=C[e+32>>2],Ot=C[i>>2],F=C[e>>2],Nt=C[i+16>>2],V=C[e+16>>2],Ft=C[e+48>>2],Vt=C[i+48>>2],G=C[e+4>>2],Gt=C[i+4>>2],Lt=C[i+8>>2],w=C[e+8>>2],f[o+108>>2]=0,f[o+92>>2]=0,f[o+76>>2]=0,C[o+88>>2]=v(v(w*Lt)+v(D*St))+v(B*Tt),C[o+84>>2]=v(v(w*Gt)+v(D*Dt))+v(B*It),C[o+72>>2]=v(v(G*Lt)+v(p*St))+v(R*Tt),C[o+68>>2]=v(v(G*Gt)+v(p*Dt))+v(R*It),Ft=v(-Ft),C[o+104>>2]=v(v(v(w*Ft)-v(D*W))-v(B*Y))+v(v(v(w*Vt)+v(D*z))+v(B*pt)),C[o+100>>2]=v(v(v(G*Ft)-v(p*W))-v(R*Y))+v(v(v(G*Vt)+v(p*z))+v(R*pt)),f[o+60>>2]=0,C[o+48>>2]=v(v(F*Ot)+v(V*Nt))+v(E*Et),C[o+80>>2]=v(v(w*Ot)+v(D*Nt))+v(B*Et),C[o+64>>2]=v(v(G*Ot)+v(p*Nt))+v(R*Et),C[o+56>>2]=v(v(F*Lt)+v(V*St))+v(E*Tt),C[o+52>>2]=v(v(F*Gt)+v(V*Dt))+v(E*It),C[o+96>>2]=v(v(v(F*Ft)-v(V*W))-v(E*Y))+v(v(v(F*Vt)+v(V*z))+v(E*pt)),e=f[Q+4>>2],yt[f[f[e>>2]+8>>2]](e,o+48|0,o+128|0,o+112|0),p=C[a+32>>2],C[o+128>>2]=C[o+128>>2]-p,C[o+132>>2]=C[o+132>>2]-p,C[o+136>>2]=C[o+136>>2]-p,C[o+112>>2]=p+C[o+112>>2],C[o+116>>2]=p+C[o+116>>2],C[o+120>>2]=p+C[o+120>>2],i=f[o+140>>2],e=o+24|0,f[e>>2]=f[o+136>>2],f[e+4>>2]=i,i=f[o+124>>2],e=o+40|0,f[e>>2]=f[o+120>>2],f[e+4>>2]=i,e=f[o+116>>2],f[o+32>>2]=f[o+112>>2],f[o+36>>2]=e,e=f[o+132>>2],f[o+16>>2]=f[o+128>>2],f[o+20>>2]=e,function(t,e,i,r){var a=0,o=0,h=0,d=0,g=0,m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0);if(t){if(m=C[e+24>>2],y=C[e+20>>2],o=f[i+8>>2],p=C[e+16>>2],R=C[e+8>>2],D=C[e+4>>2],B=C[e>>2],(0|(e=f[i+4>>2]))<=-1)for((0|o)<=-1&&((a=f[i+12>>2])&&(_[i+16|0]&&CA(a),f[i+12>>2]=0),n[i+16|0]=1,f[i+8>>2]=0,f[i+12>>2]=0,o=0),a=e<<2;f[f[i+12>>2]+a>>2]=0,a=a+4|0,d=(h=e+1|0)>>>0>=e>>>0,e=h,d;);if(h=0,f[i+4>>2]=0,(0|o)<=63){if(o=dA(256),(0|(h=f[i+4>>2]))>=1)for(e=0,a=h;f[e+o>>2]=f[f[i+12>>2]+e>>2],e=e+4|0,a=a+-1|0;);(e=f[i+12>>2])&&(_[i+16|0]&&(CA(e),h=f[i+4>>2]),f[i+12>>2]=0),f[i+12>>2]=o,n[i+16|0]=1,f[i+8>>2]=64,o=64}if((0|o)==(0|h))if((0|o)>=(0|(g=o<<1)))h=o;else{e=0;e:{if(o){if(d=dA(o<<3),(0|(h=f[i+4>>2]))<1)break e}else d=0,h=o;for(a=h;f[e+d>>2]=f[f[i+12>>2]+e>>2],e=e+4|0,a=a+-1|0;);}(e=f[i+12>>2])&&(_[i+16|0]&&(CA(e),h=f[i+4>>2]),f[i+12>>2]=0),f[i+12>>2]=d,n[i+16|0]=1,f[i+8>>2]=g}for(e=h+1|0,f[i+4>>2]=e,f[f[i+12>>2]+(h<<2)>>2]=t;;){if(a=e+-1|0,f[i+4>>2]=a,h=f[i+12>>2],d=f[h+(a<<2)>>2],C[d>>2]<=p)if(C[d+16>>2]>=B)if(C[d+4>>2]<=y)if(C[d+20>>2]>=D)if(C[d+8>>2]<=m)if(C[d+24>>2]>=R)if(f[d+40>>2]){if(g=f[d+36>>2],(0|a)==(0|(t=f[i+8>>2])))if((0|e)>(0|(t=a?a<<1:1)))t=a;else{if(t?(h=dA(t<<2),a=f[i+4>>2]):h=0,(0|a)>=1)for(e=0,o=a;f[e+h>>2]=f[f[i+12>>2]+e>>2],e=e+4|0,o=o+-1|0;);(e=f[i+12>>2])&&(_[i+16|0]&&(CA(e),a=f[i+4>>2]),f[i+12>>2]=0),f[i+12>>2]=h,n[i+16|0]=1,f[i+8>>2]=t}if(o=a+1|0,f[i+4>>2]=o,f[(a<<2)+h>>2]=g,g=f[d+40>>2],(0|t)==(0|o))if((0|t)>=(0|(h=t?t<<1:1)))o=t;else{if(h?(d=dA(h<<2),t=f[i+4>>2]):d=0,(0|(o=t))>=1)for(e=0,a=o;f[e+d>>2]=f[f[i+12>>2]+e>>2],e=e+4|0,a=a+-1|0;);(t=f[i+12>>2])&&(_[i+16|0]&&(CA(t),o=f[i+4>>2]),f[i+12>>2]=0),f[i+12>>2]=d,n[i+16|0]=1,f[i+8>>2]=h}e=o+1|0,f[i+4>>2]=e,f[f[i+12>>2]+(o<<2)>>2]=g}else yt[f[f[r>>2]+12>>2]](r,d),e=f[i+4>>2];else e=a;else e=a;else e=a;else e=a;else e=a;else e=a;if(!((0|e)>0))break}}}(f[y>>2],o+16|0,t+8|0,o+144|0);else{if((0|m)<1)break t;for(g=0,y=64;ni(o+144|0,f[f[h+28>>2]+y>>2],g),y=y+80|0,(0|m)!=(0|(g=g+1|0)););}if(e=f[t+52>>2],(0|(g=f[t+32>>2]))<=-1)for(f[t+36>>2]<=-1&&((i=f[t+40>>2])&&(_[t+44|0]&&CA(i),f[t+40>>2]=0),f[t+36>>2]=0,f[t+40>>2]=0,n[t+44|0]=1),m=g<<2;f[f[t+40>>2]+m>>2]=0,m=m+4|0,r=(i=g+1|0)>>>0>=g>>>0,g=i,r;);if(f[t+32>>2]=0,!((0|e)<1))for(a=64,y=0;f[f[t+60>>2]+y>>2]&&(i=f[h+28>>2]+a|0,g=f[i>>2],r=f[d+12>>2],Gt=C[r+52>>2],Lt=C[r+56>>2],W=C[i+-16>>2],Y=C[i+-12>>2],z=C[i+-8>>2],p=C[r+20>>2],R=C[r+24>>2],pt=C[i+-64>>2],Dt=C[i+-48>>2],It=C[i+-32>>2],St=C[i+-60>>2],Tt=C[i+-44>>2],Et=C[i+-28>>2],Ot=C[i+-56>>2],D=C[r+36>>2],Nt=C[i+-40>>2],B=C[r+40>>2],Vt=C[i+-24>>2],Ft=C[r+48>>2],E=C[r+8>>2],F=C[r>>2],V=C[r+4>>2],G=C[r+16>>2],w=C[r+32>>2],m=0,f[o+108>>2]=0,f[o+92>>2]=0,f[o+76>>2]=0,f[o+60>>2]=0,C[o+88>>2]=v(v(w*Ot)+v(D*Nt))+v(B*Vt),C[o+84>>2]=v(v(w*St)+v(D*Tt))+v(B*Et),C[o+80>>2]=v(v(w*pt)+v(D*Dt))+v(B*It),C[o+72>>2]=v(v(G*Ot)+v(p*Nt))+v(R*Vt),C[o+68>>2]=v(v(G*St)+v(p*Tt))+v(R*Et),C[o+64>>2]=v(v(G*pt)+v(p*Dt))+v(R*It),C[o+56>>2]=v(v(F*Ot)+v(V*Nt))+v(E*Vt),C[o+52>>2]=v(v(F*St)+v(V*Tt))+v(E*Et),C[o+48>>2]=v(v(F*pt)+v(V*Dt))+v(E*It),C[o+104>>2]=Lt+v(v(v(w*W)+v(D*Y))+v(B*z)),C[o+100>>2]=Gt+v(v(v(G*W)+v(p*Y))+v(R*z)),C[o+96>>2]=Ft+v(v(v(F*W)+v(V*Y))+v(E*z)),yt[f[f[g>>2]+8>>2]](g,o+48|0,o+16|0,o+128|0),i=f[Q+4>>2],yt[f[f[i>>2]+8>>2]](i,f[Q+12>>2],o+112|0,o),g=0,C[o+16>>2]>C[o>>2]||(g=0,C[o+128>>2]>2]||(g=1)),(1^(m=C[o+136>>2]>2]|C[o+24>>2]>C[o+8>>2]?m:g)||C[o+132>>2]>2]|C[o+20>>2]>C[o+4>>2])&&(i=f[f[t+60>>2]+y>>2],yt[f[f[i>>2]>>2]](i),i=f[t+4>>2],yt[f[f[i>>2]+60>>2]](i,f[f[t+60>>2]+y>>2]),f[f[t+60>>2]+y>>2]=0)),a=a+80|0,y=y+4|0,e=e+-1|0;);}Z=o+176|0}function ni(t,e,i){var r,n,a=0,o=0,_=v(0),h=v(0),d=v(0),g=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0);Z=r=Z-160|0,a=f[t+4>>2],o=f[a+12>>2],F=C[o+52>>2],y=C[o+56>>2],_=C[o+24>>2],p=C[o+20>>2],h=C[o+40>>2],d=C[o+36>>2],a=f[f[a+4>>2]+28>>2],It=C[o+48>>2],R=C[o+8>>2],D=C[o>>2],B=C[o+4>>2],E=C[o+16>>2],g=C[o+32>>2],o=0,f[r+156>>2]=0,f[r+140>>2]=0,f[r+124>>2]=0,a=a+m(i,80)|0,V=C[a+8>>2],G=C[a+24>>2],w=C[a+40>>2],C[r+136>>2]=v(v(g*V)+v(d*G))+v(h*w),Q=C[a+4>>2],W=C[a+20>>2],Y=C[a+36>>2],C[r+132>>2]=v(v(g*Q)+v(d*W))+v(h*Y),C[r+120>>2]=v(v(E*V)+v(p*G))+v(_*w),C[r+116>>2]=v(v(E*Q)+v(p*W))+v(_*Y),z=y,y=C[a+48>>2],pt=C[a+52>>2],Dt=C[a+56>>2],C[r+152>>2]=z+v(v(v(g*y)+v(d*pt))+v(h*Dt)),C[r+148>>2]=F+v(v(v(E*y)+v(p*pt))+v(_*Dt)),f[r+108>>2]=0,z=g,g=C[a>>2],F=d,d=C[a+16>>2],St=h,h=C[a+32>>2],C[r+128>>2]=v(v(z*g)+v(F*d))+v(St*h),C[r+112>>2]=v(v(E*g)+v(p*d))+v(_*h),C[r+96>>2]=v(v(D*g)+v(B*d))+v(R*h),C[r+104>>2]=v(v(D*V)+v(B*G))+v(R*w),C[r+100>>2]=v(v(D*Q)+v(B*W))+v(R*Y),C[r+144>>2]=It+v(v(v(D*y)+v(B*pt))+v(R*Dt)),yt[f[f[e>>2]+8>>2]](e,r+96|0,r+80|0,r- -64|0),_=C[f[t+20>>2]+32>>2],C[r+80>>2]=C[r+80>>2]-_,C[r+84>>2]=C[r+84>>2]-_,C[r+88>>2]=C[r+88>>2]-_,C[r+64>>2]=_+C[r+64>>2],C[r+68>>2]=_+C[r+68>>2],C[r+72>>2]=_+C[r+72>>2],a=f[t+8>>2],n=f[a+4>>2],yt[f[f[n>>2]+8>>2]](n,f[a+12>>2],r+48|0,r+32|0),(a=f[689])&&!yt[a](f[f[t+8>>2]+4>>2],e)||(o=C[r+64>>2]>2]|C[r+80>>2]>C[r+32>>2]?o:1,a=0,a=C[r+72>>2]>2]|C[r+88>>2]>C[r+40>>2]?a:o,C[r+68>>2]>2]|C[r+84>>2]>C[r+36>>2]|1^a||(f[r+28>>2]=i,f[r+24>>2]=-1,f[r+12>>2]=e,e=f[t+4>>2],f[r+8>>2]=e,f[r+16>>2]=f[e+8>>2],_=C[f[t+20>>2]+32>>2],f[r+20>>2]=r+96,_>v(0)?(e=f[t+12>>2],e=0|yt[f[f[e>>2]+8>>2]](e,r+8|0,f[t+8>>2],0,2)):(e=f[(o=i<<2)+f[t+24>>2]>>2])||(e=f[t+12>>2],e=0|yt[f[f[e>>2]+8>>2]](e,r+8|0,f[t+8>>2],f[t+28>>2],1),f[o+f[t+24>>2]>>2]=e,e=f[o+f[t+24>>2]>>2]),o=f[t+20>>2],a=f[o+8>>2],f[a+8>>2]!=f[f[t+4>>2]+8>>2]?(a=f[o+12>>2],f[o+12>>2]=r+8,yt[f[f[o>>2]+12>>2]](o,-1,i)):(f[o+8>>2]=r+8,yt[f[f[o>>2]+8>>2]](o,-1,i)),yt[f[f[e>>2]+8>>2]](e,r+8|0,f[t+8>>2],f[t+16>>2],f[t+20>>2]),e=f[t+20>>2],f[(f[f[e+8>>2]+8>>2]==f[f[t+4>>2]+8>>2]?8:12)+e>>2]=a)),Z=r+160|0}function ai(t){var e,i,r=0,a=0,o=0,h=0,d=0,C=0,g=0;if(!((0|(i=f[t+28>>2]))>=(0|(e=f[t+12>>2])))){t:if(f[t+32>>2]>=(0|e))o=f[t+36>>2];else{if(e?(o=dA(e<<2),a=f[t+28>>2]):a=i,r=f[t+36>>2],(0|a)>=1)for(h=o,d=r;f[h>>2]=f[d>>2],h=h+4|0,d=d+4|0,a=a+-1|0;);else if(!r){f[t+36>>2]=o,f[t+32>>2]=e,n[t+40|0]=1;break t}_[t+40|0]&&CA(r),f[t+36>>2]=o,n[t+40|0]=1,f[t+32>>2]=e}if(X((a=i<<2)+o|0,0,(C=e<<2)-a|0),f[t+28>>2]=e,(0|(g=f[t+48>>2]))<(0|e)){t:if(f[t+52>>2]>=(0|e))o=f[t+56>>2];else{if(e?(o=dA(C),a=f[t+48>>2]):(o=0,a=g),r=f[t+56>>2],(0|a)>=1)for(h=o,d=r;f[h>>2]=f[d>>2],h=h+4|0,d=d+4|0,a=a+-1|0;);else if(!r){f[t+56>>2]=o,f[t+52>>2]=e,n[t+60|0]=1;break t}_[t+60|0]&&CA(r),f[t+56>>2]=o,n[t+60|0]=1,f[t+52>>2]=e}X((a=g<<2)+o|0,0,C-a|0)}if(f[t+48>>2]=e,(0|e)>=1&&(X(f[t+36>>2],255,C),X(f[t+56>>2],255,C)),!((0|i)<1))for(d=f[t+56>>2],h=f[t+16>>2],o=f[t+36>>2],a=0;r=f[h>>2]|f[h+4>>2]<<16,r=m((r=(r<<15^-1)+r|0)>>>10^r,9),r=((r^=r>>>6)<<11^-1)+r|0,r=o+((f[t+12>>2]+-1&(r>>>16^r))<<2)|0,f[d>>2]=f[r>>2],f[r>>2]=a,h=h+12|0,d=d+4|0,(0|(a=a+1|0))!=(0|i););}}function oi(t){var e=0,i=0,r=0,a=0,o=0,h=0;if((e=f[t+16>>2])&&(_[t+20|0]&&CA(e),f[t+16>>2]=0),f[t+16>>2]=0,f[t+8>>2]=0,f[t+12>>2]=0,n[t+20|0]=1,(e=f[t+36>>2])&&(_[t+40|0]&&CA(e),f[t+36>>2]=0),f[t+36>>2]=0,f[t+28>>2]=0,f[t+32>>2]=0,n[t+40|0]=1,(e=f[t+56>>2])&&(_[t+60|0]&&CA(e),f[t+56>>2]=0),f[t+56>>2]=0,f[t+48>>2]=0,f[t+52>>2]=0,n[t+60|0]=1,f[t+12>>2]<=1){if(o=dA(24),(0|(i=f[t+8>>2]))>=1)for(e=0;r=f[t+16>>2]+e|0,h=f[r+4>>2],f[(a=e+o|0)>>2]=f[r>>2],f[a+4>>2]=h,f[a+8>>2]=f[r+8>>2],e=e+12|0,i=i+-1|0;);(e=f[t+16>>2])&&(_[t+20|0]&&CA(e),f[t+16>>2]=0),f[t+16>>2]=o,n[t+20|0]=1,f[t+12>>2]=2}ai(t)}function ci(t){return f[(t|=0)+16>>2]}function li(t){var e=0,i=0,r=0,a=0,o=0;if(f[(t|=0)>>2]=16908,e=8,i=f[t+84>>2],(0|(r=f[i+8>>2]))>=1){for(;(a=f[f[i+16>>2]+e>>2])&&(yt[f[f[a>>2]>>2]](a),o=f[t+4>>2],yt[f[f[o>>2]+60>>2]](o,a)),e=e+12|0,r=r+-1|0;);i=f[t+84>>2]}return oi(i),e=f[t+84>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+84>>2]),(e=f[t+100>>2])&&(_[t+104|0]&&CA(e),f[t+100>>2]=0),f[t+100>>2]=0,f[t+92>>2]=0,f[t+96>>2]=0,n[t+104|0]=1,fi(t),0|t}function ui(t,e){e|=0;var i=0,r=0,a=0,o=0,h=0;if(!(!(r=f[(t|=0)+12>>2])|!_[t+8|0])){if((0|(i=f[e+4>>2]))==f[e+8>>2]&&!((0|i)>=(0|(o=i?i<<1:1)))){if(o&&(h=dA(o<<2),i=f[e+4>>2]),(0|i)>=1)for(r=0,a=i;f[r+h>>2]=f[f[e+12>>2]+r>>2],r=r+4|0,a=a+-1|0;);(a=f[e+12>>2])&&(_[e+16|0]&&(CA(a),i=f[e+4>>2]),f[e+12>>2]=0),f[e+12>>2]=h,n[e+16|0]=1,f[e+8>>2]=o,r=f[t+12>>2]}f[e+4>>2]=i+1,f[f[e+12>>2]+(i<<2)>>2]=r}}function si(t,e,i,r,n){t|=0,e|=0,i|=0,r|=0,n|=0;var a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0);Z=r=Z-144|0,f[r+108>>2]=0,a=C[e+80>>2],o=C[e+96>>2],F=C[e+120>>2],Dt=C[e+56>>2],Q=C[e+112>>2],W=C[e+116>>2],It=C[e+52>>2],_=C[e+68>>2],d=C[e+84>>2],g=C[e+100>>2],h=C[e+20>>2],D=C[e+36>>2],m=C[e+72>>2],y=C[e+88>>2],B=C[e+24>>2],p=C[e+104>>2],V=C[e+40>>2],R=C[e+64>>2],G=C[e+32>>2],w=C[e>>2],Y=C[e+16>>2],St=C[e+48>>2],z=C[e+4>>2],pt=C[e+8>>2],f[r+100>>2]=0,f[r+84>>2]=0,f[r+68>>2]=0,C[r+80>>2]=v(v(pt*m)+v(B*y))+v(V*p),C[r+76>>2]=v(v(z*m)+v(h*y))+v(D*p),C[r- -64>>2]=v(v(pt*_)+v(B*d))+v(V*g),C[r+60>>2]=v(v(z*_)+v(h*d))+v(D*g),Q=v(St-Q),W=v(It-W),F=v(Dt-F),C[r+96>>2]=v(v(m*Q)+v(y*W))+v(p*F),C[r+92>>2]=v(v(Q*_)+v(W*d))+v(F*g),f[r+52>>2]=0,C[r+72>>2]=v(v(w*m)+v(Y*y))+v(G*p),C[r+56>>2]=v(v(w*_)+v(Y*d))+v(G*g),C[r+48>>2]=v(v(R*pt)+v(a*B))+v(o*V),C[r+44>>2]=v(v(R*z)+v(a*h))+v(o*D),C[r+40>>2]=v(v(R*w)+v(a*Y))+v(o*G),C[r+88>>2]=v(v(Q*R)+v(W*a))+v(F*o),function(t,e,i,r,n,a){var o,_=v(0),h=v(0),d=v(0),g=0,m=v(0),y=v(0),p=0,R=v(0),D=v(0),B=v(0),F=v(0),V=0,G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=0;Z=o=Z-32|0,g=f[t+8>>2],h=C[g+60>>2],_=v(C[g+76>>2]-h),D=C[g- -64>>2],d=v(C[g+96>>2]-D),m=v(C[g+80>>2]-D),R=v(C[g+92>>2]-h),B=v(v(_*d)-v(m*R)),G=m,F=C[g+68>>2],m=v(C[g+100>>2]-F),y=v(C[g+84>>2]-F),d=v(v(G*m)-v(y*d)),R=v(v(y*R)-v(_*m));t:if((m=v(v(B*B)+v(v(d*d)+v(R*R))))>=v(14210854715202004e-30)&&(V=f[t+4>>2],G=v(C[V+32>>2]*C[V+16>>2]),_=v(G+a),a=v(v(1)/v(E(m))),m=v(d*a),d=C[e>>2],R=v(R*a),y=C[e+4>>2],w=v(v(m*v(d-h))+v(R*v(y-D))),D=v(B*a),h=C[e+8>>2],a=v(w+v(D*v(h-F))),a>2],f[(St=o+24|0)>>2]=f[p>>2],f[St+4>>2]=V,p=f[e+4>>2],f[o+16>>2]=f[e>>2],f[o+20>>2]=p,p=0,f[o+12>>2]=0,C[o+8>>2]=D,C[o+4>>2]=R,C[o>>2]=m,function(t,e,i){var r=v(0),n=v(0),a=v(0),o=v(0),f=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0);return d=C[t+40>>2],_=C[t+24>>2],y=v(d-_),g=C[i+8>>2],R=C[t+32>>2],n=C[t+16>>2],f=v(R-n),a=C[e+4>>2],D=C[t+36>>2],h=C[t+20>>2],o=v(D-h),m=C[e>>2],p=v(v(g-_)*v(v(f*a)-v(o*m))),B=C[i>>2],r=o,o=C[e+8>>2],E=C[i+4>>2],y=v(p+v(v(v(B-n)*v(v(r*o)-v(y*a)))+v(v(E-h)*v(v(y*m)-v(f*o))))),r=_,_=C[t+8>>2],f=v(r-_),r=n,n=C[t>>2],p=v(r-n),r=h,h=C[t+4>>2],r=v(r-h),f=v(v(v(g-_)*v(v(p*a)-v(r*m)))+v(v(v(B-n)*v(v(r*o)-v(f*a)))+v(v(E-h)*v(v(f*m)-v(p*o))))),t=1,r=v(g-d),g=v(n-R),n=v(h-D),d=v(_-d),a=v(v(r*v(v(g*a)-v(n*m)))+v(v(v(B-R)*v(v(n*o)-v(d*a)))+v(v(E-D)*v(v(d*m)-v(g*o))))),(!(y>v(0))||a>v(0)^1|f>v(0)^1)&&(t=f<=v(0)&y<=v(0)&a<=v(0)),t}(g+60|0,o,o+16|0))Q=v(h-v(a*D)),W=v(y-v(a*R)),Y=v(d-v(a*m)),w=v(_*_);else{if((0|yt[f[f[g>>2]+100>>2]](g))<1)break t;for(w=v(_*_),V=0,g=0;p=f[t+8>>2],yt[f[f[p>>2]+104>>2]](p,g,o+16|0,o),_=v(0),z=C[o+16>>2],a=v(C[e>>2]-z),y=v(C[o>>2]-z),pt=C[o+20>>2],h=v(C[e+4>>2]-pt),B=v(C[o+4>>2]-pt),Dt=C[o+24>>2],d=v(C[e+8>>2]-Dt),F=v(C[o+8>>2]-Dt),(It=v(v(v(a*y)+v(h*B))+v(d*F)))>v(0)&&(It<(_=v(v(v(y*y)+v(B*B))+v(F*F)))?(_=v(It/_),d=v(d-v(F*_)),h=v(h-v(B*_)),a=v(a-v(y*_))):(d=v(d-F),h=v(h-B),a=v(a-y),_=v(1))),v(v(v(a*a)+v(h*h))+v(d*d))>2],(0|g)<(0|yt[f[f[p>>2]+100>>2]](p)););if(p=0,!V)break t;h=C[e+8>>2],y=C[e+4>>2],d=C[e>>2]}a=v(d-Y),d=v(y-W),h=v(h-Q),(_=v(v(v(a*a)+v(d*d))+v(h*h)))v(1.1920928955078125e-7)?(m=h,_=v(E(_)),h=v(v(1)/_),C[r+8>>2]=m*h,C[r+4>>2]=d*h,C[r>>2]=a*h,G=v(G-_)):(C[r+8>>2]=D,C[r+4>>2]=R,C[r>>2]=m),f[r+12>>2]=0,f[i+12>>2]=0,C[i+8>>2]=Q,C[i+4>>2]=W,C[i>>2]=Y,C[n>>2]=-G,p=1)}return Z=o+32|0,p}(t,r+88|0,r+128|0,r+112|0,r+108|0,C[t+12>>2])&&(n?(d=C[e+72>>2],g=C[e+64>>2],m=C[e+68>>2],y=C[e+88>>2],p=C[e+80>>2],R=C[e+84>>2],h=C[e+104>>2],D=C[e+96>>2],B=C[e+100>>2],a=C[r+120>>2],o=C[r+112>>2],_=C[r+116>>2],f[r+36>>2]=0,V=v(v(v(o*D)+v(_*B))+v(a*h)),C[r+32>>2]=-V,G=v(v(v(o*p)+v(_*R))+v(a*y)),C[r+28>>2]=-G,w=v(v(v(g*o)+v(m*_))+v(d*a)),C[r+24>>2]=-w,f[r+20>>2]=0,o=C[r+128>>2],_=C[r+132>>2],F=h,h=C[r+136>>2],a=C[r+108>>2],C[r+16>>2]=v(v(v(v(D*o)+v(B*_))+v(F*h))+C[e+120>>2])+v(V*a),C[r+12>>2]=v(v(v(v(o*p)+v(_*R))+v(h*y))+C[e+116>>2])+v(G*a),C[r+8>>2]=v(v(v(v(o*g)+v(_*m))+v(h*d))+C[e+112>>2])+v(w*a),yt[f[f[i>>2]+16>>2]](i,r+24|0,r+8|0,a)):(f[r+36>>2]=0,a=C[r+112>>2],d=C[e+96>>2],o=C[r+116>>2],g=C[e+100>>2],_=C[r+120>>2],m=C[e+104>>2],C[r+32>>2]=v(v(a*d)+v(o*g))+v(_*m),y=C[e+80>>2],p=C[e+84>>2],R=C[e+88>>2],C[r+28>>2]=v(v(a*y)+v(o*p))+v(_*R),h=C[e+64>>2],D=C[e+68>>2],B=C[e+72>>2],C[r+24>>2]=v(v(a*h)+v(o*D))+v(_*B),f[r+20>>2]=0,a=C[r+128>>2],o=C[r+132>>2],_=C[r+136>>2],C[r+16>>2]=v(v(v(d*a)+v(g*o))+v(m*_))+C[e+120>>2],C[r+12>>2]=v(v(v(a*y)+v(o*p))+v(_*R))+C[e+116>>2],C[r+8>>2]=v(v(v(a*h)+v(o*D))+v(_*B))+C[e+112>>2],yt[f[f[i>>2]+16>>2]](i,r+24|0,r+8|0,C[r+108>>2]))),Z=r+144|0}function ki(t){var e,i=0,r=v(0),n=0,a=v(0),o=v(0);s(t),e=(i=c(0))>>>31;t:{if((i&=2147483647)>>>0>=1283457024){if(t!=t)break t;return v(e?-1.570796251296997:1.570796251296997)}e:{if(i>>>0<=1054867455){if(n=-1,i>>>0>=964689920)break e;break t}if(t=v(y(t)),i>>>0<=1066926079){if(i>>>0<=1060110335){t=v(v(v(t+t)+v(-1))/v(t+v(2))),n=0;break e}t=v(v(t+v(-1))/v(t+v(1))),n=1}else i>>>0<=1075576831?(t=v(v(t+v(-1.5))/v(v(t*v(1.5))+v(1))),n=2):(t=v(v(-1)/t),n=3)}if(i=n,a=v(t*t),r=v(a*a),o=v(r*v(v(r*v(-.106480173766613))+v(-.19999158382415771))),r=v(a*v(v(r*v(v(r*v(.06168760731816292))+v(.14253635704517365)))+v(.333333283662796))),(0|i)<=-1)return v(t-v(t*v(o+r)));t=v(C[(i<<=2)+17392>>2]-v(v(v(t*v(o+r))-C[i+17408>>2])-t)),t=e?v(-t):t}return t}function vi(t,e){var i,r,n,a=0,o=0,f=v(0);if(!(e==e&t==t))return v(t+e);if(s(e),1065353216==(0|(a=c(0))))return ki(t);n=a>>>30&2,s(t),i=n|(r=(o=c(0))>>>31);t:{e:{i:{if(!(o&=2147483647)){A:switch(i-2|0){case 0:break i;case 1:break A;default:break e}return v(-3.1415927410125732)}if(2139095040!=(0|(a&=2147483647))){if(!a)return v(r?-1.5707963705062866:1.5707963705062866);if(!(a+218103808>>>0>=o>>>0&&2139095040!=(0|o)))return v(r?-1.5707963705062866:1.5707963705062866);if(o+218103808>>>0>>0&&(f=v(0),n)||(f=ki(v(y(v(t/e))))),e=f,i>>>0<=2){t=e;A:switch(i-1|0){case 0:return v(-e);case 1:break A;default:break e}return v(v(3.1415927410125732)-v(e+v(8.742277657347586e-8)))}return v(v(e+v(8.742277657347586e-8))+v(-3.1415927410125732))}if(2139095040==(0|o))break t;return C[17440+(i<<2)>>2]}t=v(3.1415927410125732)}return t}return C[17424+(i<<2)>>2]}function Ci(t,e,i,r,n){t|=0,e|=0,i|=0,r|=0,n|=0;var a=v(0),o=v(0),_=0,h=v(0),d=v(0),g=v(0),p=v(0);Z=r=Z-160|0,f[r+112>>2]=f[e>>2],f[r+64>>2]=f[e+64>>2],n=f[e+8>>2],f[r+116>>2]=f[e+4>>2],f[r+120>>2]=n,_=f[(n=e+68|0)+4>>2],f[r+68>>2]=f[n>>2],f[r+72>>2]=_,n=f[e+20>>2],f[r+128>>2]=f[e+16>>2],f[r+132>>2]=n,_=f[(n=e+80|0)+4>>2],f[r+80>>2]=f[n>>2],f[r+84>>2]=_,f[r+136>>2]=f[e+24>>2],f[r+88>>2]=f[e+88>>2],f[r+144>>2]=f[e+32>>2],f[r+96>>2]=f[e+96>>2],f[r+100>>2]=f[e+100>>2],_=f[(n=e+36|0)+4>>2],f[r+148>>2]=f[n>>2],f[r+152>>2]=_,f[r+104>>2]=f[e+104>>2],n=f[t+4>>2],o=C[n+40>>2],a=C[n+36>>2],h=C[n+32>>2],d=v(yt[f[f[n>>2]+48>>2]](n)),g=v(yt[f[f[n>>2]+48>>2]](n)),p=v(yt[f[f[n>>2]+48>>2]](n)),f[r+36>>2]=0,a=v(a+g),C[r+28>>2]=a+a,a=v(h+d),C[r+24>>2]=a+a,o=v(o+p),C[r+32>>2]=o+o,t=f[t+8>>2],o=C[t+40>>2],a=C[t+36>>2],h=C[t+32>>2],d=v(yt[f[f[t>>2]+48>>2]](t)),g=v(yt[f[f[t>>2]+48>>2]](t)),p=v(yt[f[f[t>>2]+48>>2]](t)),f[r+20>>2]=0,a=v(a+g),C[r+12>>2]=a+a,a=v(h+d),C[r+8>>2]=a+a,o=v(o+p),C[r+16>>2]=o+o,function(t,e,i,r,n,a,o,_,h,d){var g,p=v(0),R=v(0),D=v(0),B=v(0),F=v(0),V=v(0),G=v(0),w=0,Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=0,Vt=v(0),Gt=v(0),Lt=v(0),wt=v(0),xt=0,Qt=v(0),Wt=v(0),Yt=v(0),Pt=v(0),Mt=v(0),Zt=v(0),Ut=v(0),Xt=v(0),Jt=v(0),jt=v(0),zt=v(0),Ht=v(0),Kt=v(0),qt=v(0),$t=v(0),bi=v(0),di=v(0),yi=v(0),Ii=v(0),Bi=v(0),BA=v(0),gr=0,tn=0,en=0,An=0,rn=0,nn=0,an=0;Z=g=Z-368|0,Pt=v(C[i>>2]*v(.5)),C[g+356>>2]=Pt,Vt=C[e+36>>2],Gt=C[(gr=e+4|0)>>2],pt=C[e+20>>2],jt=C[e+40>>2],zt=C[(xt=e+8|0)>>2],Lt=C[e+24>>2],G=C[e+16>>2],W=C[e+32>>2],V=C[t>>2],Q=C[r>>2],B=C[t+4>>2],R=C[r+4>>2],p=C[t+8>>2],D=C[r+8>>2],BA=C[e>>2],Mt=v(C[i+4>>2]*v(.5)),C[g+360>>2]=Mt,Wt=v(C[i+8>>2]*v(.5)),C[g+364>>2]=Wt,Yt=v(C[a>>2]*v(.5)),C[g+344>>2]=Yt,Zt=v(C[a+4>>2]*v(.5)),C[g+348>>2]=Zt,Ut=v(C[a+8>>2]*v(.5)),C[g+352>>2]=Ut,F=v(Q-V),Y=v(R-B),St=v(D-p),Ht=v(v(v(BA*F)+v(G*Y))+v(W*St)),Qt=C[n>>2],Xt=C[n+16>>2],R=C[n+32>>2],qt=v(v(v(BA*Qt)+v(G*Xt))+v(W*R)),V=v(y(qt)),Jt=C[n+4>>2],Tt=C[n+20>>2],Et=C[n+36>>2],$t=v(v(v(BA*Jt)+v(G*Tt))+v(W*Et)),Q=v(y($t)),Ot=C[n+8>>2],z=C[n+24>>2],It=C[n+40>>2],bi=v(v(v(BA*Ot)+v(G*z))+v(W*It)),B=v(y(bi));t:if(!((p=v(v(y(Ht))-v(v(v(Pt+v(Yt*V))+v(Zt*Q))+v(Ut*B))))>v(0)||(di=v(v(v(Gt*Ot)+v(pt*z))+v(Vt*It)),wt=v(y(di)),yi=v(v(v(Gt*Jt)+v(pt*Tt))+v(Vt*Et)),Nt=v(y(yi)),Ii=v(v(v(Gt*Qt)+v(pt*Xt))+v(Vt*R)),Dt=v(y(Ii)),D=v(-34028234663852886e22),i=0,p>v(-34028234663852886e22)&&(Ft=Htv(0)||(Bi=v(v(v(zt*Ot)+v(Lt*z))+v(jt*It)),pt=v(y(Bi)),Vt=v(v(v(zt*Jt)+v(Lt*Tt))+v(jt*Et)),G=v(y(Vt)),Gt=v(v(v(zt*Qt)+v(Lt*Xt))+v(jt*R)),W=v(y(Gt)),p>D&&(Ft=Ktv(0)||(p>D&&(Ft=Ltv(0)||(p>D&&(Ft=Rv(0)||(p>D&&(w=n+4|0,Ft=Rv(0)||(p>D&&(w=n+8|0,Ft=Rv(1.1920928955078125e-7)||(Qt=v(G+v(9999999747378752e-21)),Xt=v(Nt+v(9999999747378752e-21)),Jt=v(V+v(9999999747378752e-21)),St=v(0),Dt=v(Ii*Ii),Q=v(v(Gt*Gt)+v(0)),B=v(E(v(Dt+Q))),B>v(1.1920928955078125e-7)?(Y=v(0),p=v(p/B),F=v(0),v(p*v(1.0499999523162842))>D&&(Ft=Rv(1.1920928955078125e-7)||(Tt=v(pt+v(9999999747378752e-21)),Nt=v(wt+v(9999999747378752e-21)),pt=v(yi*yi),B=v(v(Vt*Vt)+v(0)),V=v(E(v(pt+B))),V>v(1.1920928955078125e-7)&&(p=v(p/V),v(p*v(1.0499999523162842))>D&&(Ft=Rv(1.1920928955078125e-7)||(G=v(di*di),W=v(v(Bi*Bi)+v(0)),V=v(E(v(G+W))),V>v(1.1920928955078125e-7)&&(p=v(p/V),v(p*v(1.0499999523162842))>D&&(Ft=Rv(1.1920928955078125e-7)||(V=v(qt*qt),Q=v(E(v(V+Q))),Q>v(1.1920928955078125e-7)&&(p=v(p/Q),v(p*v(1.0499999523162842))>D&&(Ft=Rv(1.1920928955078125e-7)||(Q=v($t*$t),B=v(E(v(Q+B))),B>v(1.1920928955078125e-7)&&(p=v(p/B),v(p*v(1.0499999523162842))>D&&(Ft=Rv(1.1920928955078125e-7)||(B=v(bi*bi),W=v(E(v(B+W))),W>v(1.1920928955078125e-7)&&(p=v(p/W),v(p*v(1.0499999523162842))>D&&(Ft=Rv(1.1920928955078125e-7)||(V=v(E(v(v(Dt+V)+v(0)))),V>v(1.1920928955078125e-7)&&(p=v(p/V),v(p*v(1.0499999523162842))>D&&(Ft=Rv(1.1920928955078125e-7)||(Q=v(E(v(v(pt+Q)+v(0)))),Q>v(1.1920928955078125e-7)&&(p=v(p/Q),v(p*v(1.0499999523162842))>D&&(Ft=Rv(1.1920928955078125e-7))))))))))))))))){e:{i:{if((B=v(E(v(v(G+B)+v(0)))))>v(1.1920928955078125e-7)&&(p=v(p/B),v(p*v(1.0499999523162842))>D))Ft=R>2]))+v(Y*C[e+8>>2])),C[o>>2]=B,G=v(v(v(St*C[e+16>>2])+v(F*C[e+20>>2]))+v(Y*C[e+24>>2])),C[o+4>>2]=G,F=v(v(v(St*C[e+32>>2])+v(F*C[e+36>>2]))+v(Y*C[e+40>>2])),C[o+8>>2]=F;break e}B=C[w>>2],f[o>>2]=f[w>>2],G=C[w+16>>2],f[o+4>>2]=f[w+16>>2],F=C[w+32>>2],f[o+8>>2]=f[w+32>>2],p=D}if(Ft&&(C[o+8>>2]=-F,C[o+4>>2]=-G,C[o>>2]=-B),C[_>>2]=-p,(0|i)>=7)f[(w=g+120|0)>>2]=f[t+8>>2],a=f[t+4>>2],f[g+112>>2]=f[t>>2],f[g+116>>2]=a,D=v(0),It=C[g+112>>2],Dt=C[g+116>>2],Tt=C[o>>2],pt=C[e>>2],wt=C[(_=o+4|0)>>2],G=C[e+16>>2],Nt=C[(a=o+8|0)>>2],R=C[e+32>>2],Et=v((v(v(v(Tt*pt)+v(wt*G))+v(Nt*R))>v(0)?v(1):v(-1))*C[g+356>>2]),F=v(C[w>>2]+v(Et*R)),W=C[e+4>>2],V=C[e+20>>2],R=C[e+36>>2],Ot=v((v(v(v(Tt*W)+v(wt*V))+v(Nt*R))>v(0)?v(1):v(-1))*C[g+360>>2]),F=v(F+v(Ot*R)),Q=C[e+8>>2],B=C[e+24>>2],R=C[e+40>>2],z=v((v(v(v(Tt*Q)+v(wt*B))+v(Nt*R))>v(0)?v(1):v(-1))*Wt),C[w>>2]=F+v(z*R),C[g+116>>2]=v(v(Dt+v(Et*G))+v(Ot*V))+v(z*B),C[g+112>>2]=v(v(It+v(Et*pt))+v(Ot*W))+v(z*Q),f[(t=g+216|0)>>2]=f[r+8>>2],pt=C[n>>2],G=C[n+16>>2],R=C[n+32>>2],z=v((v(v(v(Tt*pt)+v(wt*G))+v(Nt*R))>v(0)?v(-1):v(1))*Yt),F=v(C[t>>2]+v(z*R)),W=C[n+4>>2],V=C[n+20>>2],R=C[n+36>>2],It=v((v(v(v(Tt*W)+v(wt*V))+v(Nt*R))>v(0)?v(-1):v(1))*C[g+348>>2]),F=v(F+v(It*R)),Q=C[n+8>>2],B=C[n+24>>2],R=C[n+40>>2],Dt=v((v(v(v(Tt*Q)+v(wt*B))+v(Nt*R))>v(0)?v(-1):v(1))*C[g+352>>2]),Et=v(F+v(Dt*R)),C[t>>2]=Et,t=f[r+4>>2],f[g+208>>2]=f[r>>2],f[g+212>>2]=t,Ot=v(v(v(C[g+208>>2]+v(z*pt))+v(It*W))+v(Dt*Q)),C[g+208>>2]=Ot,z=v(v(v(C[g+212>>2]+v(z*G))+v(It*V))+v(Dt*B)),C[g+212>>2]=z,R=C[(e=e+((t=(0|(r=i+-7|0))/3|0)<<2)|0)>>2],t=(r-m(t,3)<<2)+n|0,It=C[t>>2],W=C[e+16>>2],Dt=C[t+16>>2],V=C[e+32>>2],pt=C[t+32>>2],G=v(v(v(R*It)+v(W*Dt))+v(V*pt)),(Q=v(v(1)-v(G*G)))<=v(9999999747378752e-20)||(B=v(Ot-C[g+112>>2]),F=v(B*R),R=v(z-C[g+116>>2]),D=v(Et-C[w>>2]),D=v(v(v(v(v(F+v(R*W))+v(D*V))*G)-v(v(v(B*It)+v(R*Dt))+v(D*pt)))*v(v(1)/Q))),C[g+216>>2]=Et+v(D*pt),C[g+212>>2]=z+v(D*Dt),C[g+208>>2]=Ot+v(D*It),f[g+284>>2]=0,C[g+280>>2]=-C[a>>2],C[g+276>>2]=-C[_>>2],C[g+272>>2]=-C[o>>2],yt[f[f[d>>2]+16>>2]](d,g+272|0,g+208|0,p),f[h>>2]=i;else{Vt=C[o>>2],(0|i)<=3?(Gt=C[o+8>>2],jt=C[o+4>>2],Ft=g+356|0,w=n,xt=g+344|0):(Vt=v(-Vt),Gt=v(-C[o+8>>2]),jt=v(-C[o+4>>2]),a=r,Ft=g+344|0,r=t,t=a,w=e,e=n,xt=g+356|0),R=v(v(v(Vt*C[w>>2])+v(jt*C[w+16>>2]))+v(Gt*C[w+32>>2])),C[g+328>>2]=R,p=v(v(v(Vt*C[w+4>>2])+v(jt*C[w+20>>2]))+v(Gt*C[w+36>>2])),C[g+332>>2]=p,D=v(v(v(Vt*C[w+8>>2])+v(jt*C[w+24>>2]))+v(Gt*C[w+40>>2])),C[g+336>>2]=D,B=v(y(D)),(p=v(y(p)))>(D=v(y(R)))?(n=(_=p>B)?1:2,a=0):(n=(1^(_=D>B))<<1,a=_),rn=a,R=C[(n<<=2)+xt>>2],p=v(R*C[n+w>>2]),D=v(C[r>>2]-C[t>>2]),nn=_?2:1,a=g,C[n+(g+328|0)>>2]>2]=F,p=v(v(C[r+4>>2]-C[t+4>>2])+v(R*C[(16|n)+w>>2])),C[g+316>>2]=p,wt=v(v(C[r+8>>2]-C[t+8>>2])+v(R*C[(32|n)+w>>2]))):(F=v(D-p),C[g+312>>2]=F,p=v(v(C[r+4>>2]-C[t+4>>2])-v(R*C[(16|n)+w>>2])),C[g+316>>2]=p,wt=v(v(C[r+8>>2]-C[t+8>>2])-v(R*C[(32|n)+w>>2]))),C[a+320>>2]=wt,_=1;e:{if((An=((0|i)<4?-1:-4)+i|0)>>>0<=1){if(n=2,An-1)break e}else n=1;_=0}r=2,V=C[(n=(a=n<<2)+e|0)>>2],Q=C[n+16>>2],B=C[n+32>>2],zt=v(v(v(F*V)+v(p*Q))+v(wt*B)),It=C[(tn=(n=rn<<2)+w|0)>>2],Dt=C[tn+16>>2],R=C[tn+32>>2],Nt=v(v(v(V*It)+v(Q*Dt))+v(B*R)),D=C[n+xt>>2],pt=v(Nt*D),G=v(zt+pt),W=C[(en=(n=nn<<2)+w|0)>>2],Y=v(V*W),V=C[en+16>>2],Y=v(Y+v(Q*V)),Q=C[en+32>>2],Et=v(Y+v(B*Q)),B=C[n+xt>>2],Tt=v(Et*B),C[g+300>>2]=G-Tt,Ot=C[(e=(n=_<<2)+e|0)>>2],z=C[e+16>>2],F=v(v(F*Ot)+v(p*z)),p=C[e+32>>2],Lt=v(F+v(wt*p)),Dt=v(v(v(Ot*It)+v(z*Dt))+v(p*R)),R=v(D*Dt),D=v(Lt+R),Q=v(v(v(Ot*W)+v(z*V))+v(p*Q)),V=v(B*Q),C[g+296>>2]=D-V,C[g+292>>2]=G+Tt,Y=v(D+V),C[g+288>>2]=Y,p=v(zt-pt),B=v(p+Tt),C[g+284>>2]=B,D=v(Lt-R),F=v(D+V),C[g+280>>2]=F,p=v(p-Tt),C[g+276>>2]=p,G=v(D-V),C[g+272>>2]=G,V=C[(e=a+Ft|0)>>2],an=f[e>>2],gr=f[(e=n+Ft|0)>>2],W=C[e>>2],R=v(-W);e:{i:{A:{r:{if(!(n=W>(St=v(-G)))){if(a=0,r=1,e=g+208|0,n^(_=W>(D=v(-F))))break r;break A}if(C[g+212>>2]=p,C[g+208>>2]=G,e=g+208|8,a=1,(0|n)==(0|(_=W>(D=v(-F)))))break A}if(C[e>>2]=R,C[e+4>>2]=p+v(v(R-G)*v(v(B-p)/v(F-G))),e=e+8|0,_)break i;a=r;break e}if(r=a,!_)break e}C[e+4>>2]=B,C[e>>2]=F,a=r+1|0,e=e+8|0,F=C[g+280>>2],D=v(-F),Y=C[g+288>>2]}e:{if((Dv(-Y)|0)){if(D=C[g+292>>2],p=C[g+284>>2],C[e>>2]=R,C[e+4>>2]=p+v(v(R-F)*v(v(D-p)/v(Y-F))),8&(a=a+1|0))break e;e=e+8|0}if(F=C[g+288>>2],W>(B=v(-F))){if(C[e>>2]=F,f[e+4>>2]=f[g+292>>2],8&(a=a+1|0))break e;F=C[g+288>>2],B=v(-F),e=e+8|0}if(r=B>2],(0|r)!=(W>(Y=v(-B))|0)){if(D=C[g+300>>2],p=C[g+292>>2],C[e>>2]=R,C[e+4>>2]=p+v(v(R-F)*v(v(D-p)/v(B-F))),8&(a=a+1|0))break e;B=C[g+296>>2],Y=v(-B),e=e+8|0}if(Y>2]=B,f[e+4>>2]=f[g+300>>2],8&(a=a+1|0))break e;G=C[g+272>>2],St=v(-G),B=C[g+296>>2],Y=v(-B),e=e+8|0}i:{A:{if((Y=1)){a=0;break A}}else if(D=C[g+276>>2],p=C[g+300>>2],C[e>>2]=R,C[e+4>>2]=p+v(v(R-B)*v(v(D-p)/v(G-B))),8&(a=a+1|0))break e;for(e=g+208|0,n=g+112|0,r=0;;){if((G=C[e>>2])>2]=G,f[n+4>>2]=f[e+4>>2],8&(r=r+1|0)){a=r;break A}G=C[e>>2],n=n+8|0}if(_=e+8|0,(G1?_:g+208|0)>>2])>2],D=C[xt+4>>2],f[n>>2]=gr,C[n+4>>2]=R+v(v(W-G)*v(v(D-R)/v(p-G))),8&(r=r+1|0)){a=r;break A}n=n+8|0}if(e=_,!((0|(a=a+-1|0))>0))break}if((0|r)<1)a=0;else{for(B=v(-V),n=g+208|0,e=g+112|0,_=0;;){if(F=C[(a=e+4|0)>>2],V>(G=v(-F))){if(f[n>>2]=f[e>>2],f[n+4>>2]=f[a>>2],8&(_=_+1|0)){a=_;break i}F=C[a>>2],G=v(-F),n=n+8|0}if(a=e+8|0,p=C[(xt=(0|r)>1?a:g+112|0)+4>>2],(Gv(-p)|0)){if(D=C[xt>>2],R=C[e>>2],C[n+4>>2]=B,C[n>>2]=R+v(v(B-F)*v(v(D-R)/v(p-F))),8&(_=_+1|0)){a=_;break i}n=n+8|0}if(e=a,!((0|(r=r+-1|0))>0))break}if((0|_)<1)a=0;else for(e=g+208|0,n=g+112|0,a=0;;){if((G=C[(r=e+4|0)>>2])>2]=f[e>>2],f[n+4>>2]=f[r>>2],8&(a=a+1|0))break A;G=C[r>>2],n=n+8|0}if(r=e+8|0,(G1?r:g+208|0)+4>>2])>2],R=C[e>>2],f[n+4>>2]=an,C[n>>2]=R+v(v(V-G)*v(v(D-R)/v(p-G))),8&(a=a+1|0))break A;n=n+8|0}if(e=r,!((0|(_=_+-1|0))>0))break}}}J(g+208|0,g+112|0,a<<3)}if(!((0|a)>=1))break t}for(D=v(v(1)/v(v(Dt*Et)-v(Nt*Q))),Xt=v(Et*D),Jt=v(Nt*D),Tt=v(Q*D),wt=v(Dt*D),Nt=C[(An<<2)+Ft>>2],Et=C[(32|(r=nn<<2))+w>>2],Ot=C[(32|(e=rn<<2))+w>>2],z=C[(16|r)+w>>2],It=C[(16|e)+w>>2],Dt=C[en>>2],pt=C[tn>>2],n=0,e=g+208|0,G=C[g+320>>2],W=C[g+316>>2],V=C[g+312>>2];r=(g+112|0)+m(n,12)|0,Q=C[e>>2],p=v(Q-Lt),B=C[e+4>>2],D=v(B-zt),Qt=v(v(Xt*p)-v(Tt*D)),D=v(v(wt*D)-v(Jt*p)),R=v(v(W+v(Qt*It))+v(D*z)),C[r+4>>2]=R,p=v(v(V+v(Qt*pt))+v(D*Dt)),C[r>>2]=p,D=v(v(G+v(Qt*Ot))+v(D*Et)),C[r+8>>2]=D,D=v(Nt-v(v(v(Vt*p)+v(jt*R))+v(Gt*D))),C[(g+80|0)+(n<<2)>>2]=D,D>=v(0)&&(C[(r=n<<3)+(g+208|0)>>2]=Q,C[(g+208|0)+(4|r)>>2]=B,n=n+1|0),e=e+8|0,a=a+-1|0;);if(!((0|n)<1)){e:if((0|n)<=(0|(a=(0|(e=(0|n)<4?n:4))>1?e:1))){if((0|i)>=4){for(r=g+80|0,e=g+112|0,a=n;R=C[o>>2],B=C[r>>2],C[g+32>>2]=v(C[e>>2]+C[t>>2])-v(R*B),p=C[o+4>>2],C[g+36>>2]=v(C[e+4>>2]+C[t+4>>2])-v(B*p),D=C[o+8>>2],C[g+40>>2]=v(C[e+8>>2]+C[t+8>>2])-v(B*D),f[g+76>>2]=0,C[g+72>>2]=-D,C[g+68>>2]=-p,C[g+64>>2]=-R,yt[f[f[d>>2]+16>>2]](d,g- -64|0,g+32|0,v(-B)),e=e+12|0,r=r+4|0,a=a+-1|0;);break e}for(r=g+80|0,e=g+112|0,a=n;C[g+32>>2]=C[e>>2]+C[t>>2],C[g+36>>2]=C[e+4>>2]+C[t+4>>2],C[g+40>>2]=C[e+8>>2]+C[t+8>>2],f[g+76>>2]=0,C[g+72>>2]=-C[o+8>>2],C[g+68>>2]=-C[o+4>>2],C[g+64>>2]=-C[o>>2],yt[f[f[d>>2]+16>>2]](d,g- -64|0,g+32|0,v(-C[r>>2])),e=e+12|0,r=r+4|0,a=a+-1|0;);}else{if(w=0,(0|n)>=2)for(e=g+80|4,B=C[g+80>>2],r=1;B=(_=(D=C[e>>2])>B)?D:B,w=_?r:w,e=e+4|0,(0|n)!=(0|(r=r+1|0)););if(function(t,e,i,r,n){var a,o=0,_=0,h=v(0),d=v(0),g=v(0),m=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=0,F=v(0),V=0,G=0,w=v(0);Z=a=Z+-64|0;i:{A:{r:{n:{a:{if(!((_=t+-1|0)>>>0<=1)){if((0|_)>=1)break a;break n}if(_-1)break r;g=v(v(C[e+4>>2]+C[e+12>>2])*v(.5)),h=v(v(C[e>>2]+C[e+8>>2])*v(.5));break A}for(o=e;R=g,g=C[o+12>>2],d=C[o+4>>2],B=v(g+d),p=C[o>>2],D=C[(o=o+8|0)>>2],d=v(v(p*g)-v(D*d)),g=v(R+v(B*d)),h=v(h+d),m=v(m+v(v(p+D)*d)),_=_+-1|0;);}if(d=v(0xde0b6b000000000),R=h,p=C[(o=(t<<3)+e|0)+-8>>2],D=C[e+4>>2],F=C[e>>2],B=C[o+-4>>2],h=v(v(p*D)-v(F*B)),R=v(R+h),v(y(R))>v(1.1920928955078125e-7)&&(d=v(v(1)/v(R*v(3)))),_=0,(0|t)<=0)break i;g=v(v(g+v(v(D+B)*h))*d),h=v(v(m+v(v(p+F)*h))*d);break A}g=C[e+4>>2],h=C[e>>2]}for(o=a+32|0,_=t;G=o,w=vi(v(C[e+4>>2]-g),v(C[e>>2]-h)),C[G>>2]=w,e=e+8|0,o=o+4|0,_=_+-1|0;);for(e=a,o=t;_=1,f[e>>2]=1,e=e+4|0,o=o+-1|0;);}if(f[n>>2]=r,f[(o=(e=r<<2)+a|0)>>2]=0,!((0|i)<2))if(n=n+4|0,_)for(g=v(v(6.2831854820251465)/v(0|i)),d=C[e+(a+32|0)>>2],E=1;;){for(f[n>>2]=r,p=(h=v(v(g*v(0|E))+d))>v(3.1415927410125732)?v(h+v(-6.2831854820251465)):h,h=v(1e9),o=a+32|0,e=a,V=r,_=0;f[e>>2]&&((m=(m=v(y(v(C[o>>2]-p))))>v(3.1415927410125732)?v(v(6.2831854820251465)-m):m)>2]=_,V=_,h=m)),e=e+4|0,o=o+4|0,(0|(_=_+1|0))!=(0|t););if(f[(V<<2)+a>>2]=0,n=n+4|0,(0|(E=E+1|0))==(0|i))break}else for(e=i+-1|0;f[n>>2]=r,f[o>>2]=0,n=n+4|0,e=e+-1|0;);Z=a- -64|0}(n,g+208|0,a,w,g+32|0),(0|i)>=4)for(e=g+32|0,r=0;n=f[e>>2],_=(g+112|0)+m(n,12)|0,V=v(C[_>>2]+C[t>>2]),C[g+64>>2]=V,Q=v(C[_+4>>2]+C[t+4>>2]),C[g+68>>2]=Q,B=v(C[_+8>>2]+C[t+8>>2]),C[g+72>>2]=B,f[g+28>>2]=0,R=C[o+8>>2],C[g+24>>2]=-R,p=C[o+4>>2],C[g+20>>2]=-p,D=C[o>>2],C[g+16>>2]=-D,f[g+12>>2]=0,F=R,R=C[(g+80|0)+(n<<2)>>2],C[g+8>>2]=B-v(F*R),C[g+4>>2]=Q-v(p*R),C[g>>2]=V-v(D*R),yt[f[f[d>>2]+16>>2]](d,g+16|0,g,v(-R)),e=e+4|0,(r=r+1|0)>>>0>>0;);else for(e=g+32|0,r=0;n=f[e>>2],_=(g+112|0)+m(n,12)|0,C[g+64>>2]=C[_>>2]+C[t>>2],C[g+68>>2]=C[_+4>>2]+C[t+4>>2],C[g+72>>2]=C[_+8>>2]+C[t+8>>2],f[g+28>>2]=0,C[g+24>>2]=-C[o+8>>2],C[g+20>>2]=-C[o+4>>2],C[g+16>>2]=-C[o>>2],yt[f[f[d>>2]+16>>2]](d,g+16|0,g- -64|0,v(-C[(g+80|0)+(n<<2)>>2])),e=e+4|0,(r=r+1|0)>>>0>>0;);}f[h>>2]=i}}}Z=g+368|0}(e+48|0,r+112|0,r+24|0,e+112|0,r- -64|0,r+8|0,r+48|0,r+44|0,r+40|0,i),Z=r+160|0}function gi(t,e,i,r,n){var a,o=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=0,R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=0,It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0),Gt=v(0),Lt=v(0),wt=0,xt=v(0),Qt=v(0),Wt=v(0),Yt=v(0),Pt=v(0),Mt=v(0),Zt=v(0),Ut=v(0),Xt=v(0),Jt=v(0),jt=v(0),zt=v(0),Ht=v(0),Kt=v(0),qt=v(0),$t=v(0);Z=a=Z-48|0,Dt=_[t+16|0],p=f[(wt=Dt?r:i)+12>>2],Zt=C[p+56>>2],Ut=C[p+52>>2],Xt=C[p+48>>2],i=f[(Dt=Dt?i:r)+12>>2],Jt=C[i+56>>2],xt=C[i+48>>2],jt=C[i+52>>2],wt=f[wt+4>>2],B=C[i+40>>2],g=C[i+8>>2],m=C[i+24>>2],y=C[i+32>>2],G=C[i>>2],w=C[i+16>>2],r=f[Dt+4>>2],W=C[i+36>>2],St=C[p+40>>2],Tt=C[p+32>>2],Et=C[p+36>>2],Y=C[i+4>>2],Ot=C[p+8>>2],Nt=C[p>>2],Ft=C[p+4>>2],z=C[i+20>>2],Vt=C[p+24>>2],Gt=C[p+16>>2],Lt=C[p+20>>2],d=C[e+12>>2],R=C[e+8>>2],o=C[e>>2],h=C[e+4>>2],f[a+28>>2]=0,E=v(v(2)/v(v(v(v(o*o)+v(h*h))+v(R*R))+v(d*d))),D=v(R*E),Qt=v(o*D),F=v(h*E),Wt=v(d*F),Q=v(Qt+Wt),It=v(h*D),V=v(o*E),Yt=v(d*V),E=v(It-Yt),Pt=v(o*V),Mt=v(h*F),h=v(v(1)-v(Pt+Mt)),V=v(v(v(Tt*Q)+v(Et*E))+v(St*h)),pt=v(v(v(Nt*Q)+v(Ft*E))+v(Ot*h)),h=v(v(v(Gt*Q)+v(Lt*E))+v(Vt*h)),E=v(-C[r+52>>2]),Q=C[(i=r+56|0)>>2],zt=v(v(v(v(y*V)+v(v(G*pt)+v(w*h)))*E)-v(v(v(W*V)+v(v(Y*pt)+v(z*h)))*Q)),V=v(v(B*V)+v(v(g*pt)+v(m*h))),h=C[(p=r+60|0)>>2],C[a+24>>2]=zt-v(V*h),V=v(It+Yt),F=v(o*F),pt=v(d*D),o=v(F-pt),It=v(R*D),d=v(v(1)-v(Pt+It)),R=v(v(St*V)+v(v(Tt*o)+v(Et*d))),D=v(v(Ot*V)+v(v(Nt*o)+v(Ft*d))),o=v(v(Vt*V)+v(v(Gt*o)+v(Lt*d))),C[a+20>>2]=v(v(v(v(y*R)+v(v(G*D)+v(w*o)))*E)-v(Q*v(v(W*R)+v(v(Y*D)+v(z*o)))))-v(h*v(v(B*R)+v(v(g*D)+v(m*o)))),o=v(Qt-Wt),d=v(F+pt),R=v(v(1)-v(Mt+It)),D=v(v(St*o)+v(v(Et*d)+v(Tt*R))),F=v(v(Ot*o)+v(v(Ft*d)+v(Nt*R))),o=v(v(Vt*o)+v(v(Lt*d)+v(Gt*R))),C[a+16>>2]=v(v(v(v(y*D)+v(v(G*F)+v(w*o)))*E)-v(Q*v(v(W*D)+v(v(Y*F)+v(z*o)))))-v(h*v(v(B*D)+v(v(g*F)+v(m*o)))),yt[f[f[wt>>2]+64>>2]](a+32|0,wt,a+16|0),e=f[Dt+12>>2],Q=C[e+48>>2],V=C[e+32>>2],pt=C[e+16>>2],Qt=C[e+8>>2],Wt=C[e+4>>2],It=C[e>>2],Yt=C[e+56>>2],Pt=C[e+52>>2],Mt=C[e+40>>2],zt=C[e+36>>2],Ht=C[e+24>>2],Kt=C[e+20>>2],qt=C[r+68>>2],R=C[p>>2],D=C[r+52>>2],E=C[i>>2],o=C[a+40>>2],d=C[a+32>>2],h=C[a+36>>2],$t=C[f[t+12>>2]+784>>2],f[n+4>>2]=f[t+12>>2],F=v(-xt),xt=v(v(v(v(v(Xt*g)+v(Ut*m))+v(Zt*B))+v(v(v(g*F)-v(m*jt))-v(B*Jt)))+v(v(v(d*v(v(v(Nt*g)+v(Gt*m))+v(Tt*B)))+v(h*v(v(v(Ft*g)+v(Lt*m))+v(Et*B))))+v(o*v(v(v(Ot*g)+v(Vt*m))+v(St*B))))),G=v(v(v(v(v(Xt*G)+v(Ut*w))+v(Zt*y))+v(v(v(G*F)-v(w*jt))-v(y*Jt)))+v(v(v(d*v(v(v(Nt*G)+v(Gt*w))+v(Tt*y)))+v(h*v(v(v(Ft*G)+v(Lt*w))+v(Et*y))))+v(o*v(v(v(Ot*G)+v(Vt*w))+v(St*y))))),w=v(v(v(v(v(Xt*Y)+v(Ut*z))+v(Zt*W))+v(v(v(Y*F)-v(z*jt))-v(W*Jt)))+v(v(v(d*v(v(v(Nt*Y)+v(Gt*z))+v(Tt*W)))+v(h*v(v(v(Ft*Y)+v(Lt*z))+v(Et*W))))+v(o*v(v(v(Ot*Y)+v(Vt*z))+v(St*W))))),(B=v(v(v(R*xt)+v(v(D*G)+v(E*w)))-qt))<$t&&(f[a+28>>2]=0,t=f[Dt+12>>2],g=C[r+52>>2],m=C[r+56>>2],y=C[r+60>>2],C[a+16>>2]=v(v(C[t>>2]*g)+v(C[t+4>>2]*m))+v(C[t+8>>2]*y),C[a+24>>2]=v(v(g*C[t+32>>2])+v(m*C[t+36>>2]))+v(y*C[t+40>>2]),C[a+20>>2]=v(v(g*C[t+16>>2])+v(m*C[t+20>>2]))+v(y*C[t+24>>2]),f[a+12>>2]=0,g=v(G-v(D*B)),m=v(w-v(E*B)),y=v(xt-v(R*B)),C[a+8>>2]=v(v(v(g*V)+v(m*zt))+v(y*Mt))+Yt,C[a+4>>2]=v(v(v(g*pt)+v(m*Kt))+v(y*Ht))+Pt,C[a>>2]=v(v(Qt*y)+v(v(It*g)+v(Wt*m)))+Q,yt[f[f[n>>2]+16>>2]](n,a+16|0,a,B)),Z=a+48|0}function _i(t){var e=0;return f[(t|=0)>>2]=17664,_[t+20|0]&&(CA(f[f[t+16>>2]+16>>2]),CA(f[t+16>>2])),_[t+12|0]&&(CA(f[f[t+8>>2]+16>>2]),CA(f[t+8>>2])),e=f[t+28>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+28>>2]),e=f[t+32>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+32>>2]),e=f[t+36>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+36>>2]),e=f[t+40>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+40>>2]),e=f[t+44>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+44>>2]),e=f[t+48>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+48>>2]),e=f[t+52>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+52>>2]),e=f[t+56>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+56>>2]),e=f[t+72>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+72>>2]),e=f[t+76>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+76>>2]),e=f[t+68>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+68>>2]),e=f[t+84>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+84>>2]),e=f[t+80>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+80>>2]),e=f[t+24>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+24>>2]),0|t}function mi(t){return f[(t|=0)+8>>2]}function Ri(t){var e=0,i=0,r=0,a=0,o=0,h=0,d=0,C=0;if(f[t>>2]=18600,f[t+24>>2]=0,f[t+68>>2]=0,n[t+20|0]=1,f[t+16>>2]=0,n[t+44|0]=1,f[(e=i=t+8|0)>>2]=0,f[e+4>>2]=0,f[t+40>>2]=0,n[t- -64|0]=1,f[(e=t+32|0)>>2]=0,f[e+4>>2]=0,f[t+60>>2]=0,f[(e=t+52|0)>>2]=0,f[e+4>>2]=0,e=dA(32),(0|(r=f[i>>2]))>=1)for(i=12;a=i+e|0,o=f[t+16>>2]+i|0,f[a+-12>>2]=f[o+-12>>2],C=f[(h=o+-8|0)+4>>2],f[(d=a+-8|0)>>2]=f[h>>2],f[d+4>>2]=C,f[a>>2]=f[o>>2],i=i+16|0,r=r+-1|0;);(i=f[t+16>>2])&&(_[t+20|0]&&CA(i),f[t+16>>2]=0),f[t+16>>2]=e,n[t+20|0]=1,f[t+12>>2]=2,Qi(t)}function Qi(t){var e,i,r=0,a=0,o=0,h=0,d=0,C=0,g=0;if(!((0|(i=f[t+32>>2]))>=(0|(e=f[t+12>>2])))){t:if(f[t+36>>2]>=(0|e))o=f[t+40>>2];else{if(e?(o=dA(e<<2),a=f[t+32>>2]):a=i,r=f[t+40>>2],(0|a)>=1)for(h=o,d=r;f[h>>2]=f[d>>2],h=h+4|0,d=d+4|0,a=a+-1|0;);else if(!r){f[t+40>>2]=o,f[t+36>>2]=e,n[t+44|0]=1;break t}_[t+44|0]&&CA(r),f[t+40>>2]=o,n[t+44|0]=1,f[t+36>>2]=e}if(X((a=i<<2)+o|0,0,(C=e<<2)-a|0),f[t+32>>2]=e,(0|(g=f[t+52>>2]))<(0|e)){t:if(f[t+56>>2]>=(0|e))o=f[t+60>>2];else{if(e?(o=dA(C),a=f[t+52>>2]):(o=0,a=g),r=f[t+60>>2],(0|a)>=1)for(h=o,d=r;f[h>>2]=f[d>>2],h=h+4|0,d=d+4|0,a=a+-1|0;);else if(!r){f[t+60>>2]=o,f[t+56>>2]=e,n[t- -64|0]=1;break t}_[t- -64|0]&&CA(r),f[t+60>>2]=o,n[t+64|0]=1,f[t+56>>2]=e}X((a=g<<2)+o|0,0,C-a|0)}if(f[t+52>>2]=e,(0|e)>=1&&(X(f[t+40>>2],255,C),X(f[t+60>>2],255,C)),!((0|i)<1))for(d=f[t+60>>2],h=f[t+16>>2],o=f[t+40>>2],a=0;r=f[f[h>>2]+12>>2]|f[f[h+4>>2]+12>>2]<<16,r=m((r=(r<<15^-1)+r|0)>>>10^r,9),r=((r^=r>>>6)<<11^-1)+r|0,r=o+((f[t+12>>2]+-1&(r>>>16^r))<<2)|0,f[d>>2]=f[r>>2],f[r>>2]=a,h=h+16|0,d=d+4|0,(0|(a=a+1|0))!=(0|i););}}function hi(t){return(t|=0)+4|0}function Gi(t,e){e|=0,f[(t|=0)+24>>2]=e}function pi(t,e){var i=0,r=0,a=0,o=0;if(f[t+4>>2]=0,f[t+8>>2]=0,f[t+12>>2]=0,n[t+16|0]=1,(0|(a=f[e+4>>2]))<=0)f[t+4>>2]=a;else{if(o=dA(a<<2),(0|(r=f[t+4>>2]))>=1)for(;f[i+o>>2]=f[f[t+12>>2]+i>>2],i=i+4|0,r=r+-1|0;);for((r=f[t+12>>2])&&(_[t+16|0]&&CA(r),f[t+12>>2]=0),f[t+12>>2]=o,n[t+16|0]=1,f[t+8>>2]=a,i=0,r=a;f[i+o>>2]=0,i=i+4|0,o=f[t+12>>2],r=r+-1|0;);if(f[t+4>>2]=a,(0|a)>=1)for(i=0;f[i+o>>2]=f[f[e+12>>2]+i>>2],i=i+4|0,a=a+-1|0;);}}function Fi(t){var e=0,i=0,r=0,a=0,o=0,h=0;if(f[(t|=0)>>2]=19124,_[t+152|0]&&(e=f[t+96>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+96>>2])),(0|(i=f[t+160>>2]))>=1)for(r=8;h=(e=f[t+168>>2]+r|0)+-4|0,(o=f[(a=e+4|0)>>2])&&(_[e+8|0]&&CA(o),f[a>>2]=0),f[h>>2]=0,f[a>>2]=0,f[e>>2]=0,n[e+8|0]=1,r=r+20|0,i=i+-1|0;);return(e=f[t+168>>2])&&(_[t+172|0]&&CA(e),f[t+168>>2]=0),f[t+168>>2]=0,f[t+160>>2]=0,f[t+164>>2]=0,n[t+172|0]=1,rr(t+44|0),rr(t+4|0),0|t}function Wi(t,e,i,r){var n,a=0,o=0,_=0,h=0,d=0,g=0,m=0,y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=0;if(Z=n=Z-256|0,e){for(y=C[i+24>>2],p=C[i+20>>2],R=C[i+16>>2],D=C[i+8>>2],B=C[i+4>>2],E=C[i>>2],f[n>>2]=e,a=64,t=n,i=1;;){t:{e:{i:{if(o=f[(m=(e=i+-1|0)<<2)+t>>2],!(C[o>>2]<=R^1|C[o+16>>2]>=E^1|C[o+4>>2]<=p^1|C[o+20>>2]>=B^1||C[o+8>>2]<=y^1|C[o+24>>2]>=D^1)){if(f[o+40>>2]){if(F=f[o+36>>2],(0|e)!=(0|a))break i;if((0|i)>(0|(e=a?a<<1:1)))break i;_=e?dA(e<<2):0;A:{r:{if((0|a)>=1){for(h=_,d=t;f[h>>2]=f[d>>2],h=h+4|0,d=d+4|0,a=a+-1|0;);if(g)break r;break A}if(!t|!g)break A}CA(t)}g=1;break e}yt[f[f[r>>2]+12>>2]](r,o)}break t}e=a,_=t}if(f[_+m>>2]=F,o=f[o+40>>2],(0|e)==(0|i))if((0|i)>=(0|(a=i?i<<1:1)))a=i,t=_;else{t=a?dA(a<<2):0;e:{i:{if((0|i)>=1){for(e=t,h=_,d=i;f[e>>2]=f[h>>2],e=e+4|0,h=h+4|0,d=d+-1|0;);if(g)break i;break e}if(!_|!g)break e}CA(_)}g=1}else a=e,t=_;f[(i<<2)+t>>2]=o,e=i+1|0}if(!((0|(i=e))>0))break}!t|!g||CA(t)}Z=n+256|0}function wi(t,e,i,r,a,o,h,d,g,m){var y,p=0,R=0,D=0,B=v(0),E=0,F=v(0),V=v(0),G=v(0),w=0,Q=v(0),W=v(0),Y=0,z=v(0);if(Z=y=Z-32|0,e){if((0|(R=f[g+4>>2]))<=127){if(f[g+8>>2]<=127){if(D=dA(512),(0|(t=f[g+4>>2]))>=1)for(;f[p+D>>2]=f[f[g+12>>2]+p>>2],p=p+4|0,t=t+-1|0;);(t=f[g+12>>2])&&(_[g+16|0]&&CA(t),f[g+12>>2]=0),f[g+12>>2]=D,n[g+16|0]=1,f[g+8>>2]=128}for(p=R<<2,t=R+-128|0;f[f[g+12>>2]+p>>2]=0,p=p+4|0,D=(R=t+1|0)>>>0>=t>>>0,t=R,D;);}for(f[g+4>>2]=128,f[f[g+12>>2]>>2]=e,p=126,t=1;;){f[y+12>>2]=0,D=f[g+12>>2],R=f[D+(Y=(e=t+-1|0)<<2)>>2],C[y+8>>2]=C[R+8>>2]-C[d+8>>2],C[y+4>>2]=C[R+4>>2]-C[d+4>>2],C[y>>2]=C[R>>2]-C[d>>2],F=C[R+24>>2],V=C[R+16>>2],B=C[h+8>>2],G=C[h>>2],C[y+20>>2]=C[R+20>>2]-C[h+4>>2],C[y+16>>2]=V-G,C[y+24>>2]=F-B,f[y+28>>2]=0,E=f[a+4>>2],G=C[i+4>>2],Q=C[r+4>>2],F=v(v(C[4+((E<<4)+y|0)>>2]-G)*Q),B=C[r>>2],w=f[a>>2],W=C[i>>2];t:{if(!(F>(V=v(B*v(C[(1-w<<4)+y>>2]-W)))||(B=v(v(C[(w<<4)+y>>2]-W)*B),G=v(Q*v(C[4+((1-E<<4)+y|0)>>2]-G)),B>G||(E=f[a+8>>2],W=C[i+8>>2],z=C[r+8>>2],Q=v(v(C[8+((E<<4)+y|0)>>2]-W)*z),V=GV||(F=F>B?F:B,B=v(z*v(C[8+((1-E<<4)+y|0)>>2]-W)),F>B|(Q>F?Q:F)v(0)^1))))){if(f[R+40>>2]){if((0|e)>(0|p)){if((0|(e=f[g+4>>2]))<(0|(E=e<<1))){if(f[g+8>>2]<(0|E)){if(e){if(D=dA(e<<3),!((0|(w=f[g+4>>2]))<1))for(p=0;f[p+D>>2]=f[f[g+12>>2]+p>>2],p=p+4|0,w=w+-1|0;);}else D=0;(p=f[g+12>>2])&&(_[g+16|0]&&CA(p),f[g+12>>2]=0),f[g+12>>2]=D,n[g+16|0]=1,f[g+8>>2]=E}for(p=e<<2;f[p+D>>2]=0,p=p+4|0,D=f[g+12>>2],e=e+-1|0;);}f[g+4>>2]=E,p=E+-2|0}f[D+Y>>2]=f[R+36>>2],f[f[g+12>>2]+(t<<2)>>2]=f[R+40>>2],t=t+1|0;break t}yt[f[f[m>>2]+12>>2]](m,R)}t=e}if(!t)break}}Z=y+32|0}function Di(t,e,i,r){var a=0,o=0,h=0,d=0,g=0,m=0,v=0,y=0,p=0,R=0;if(!(!e|!i)){if(!(f[t+24>>2]>127|f[t+28>>2]>127)){if(g=dA(1024),(0|(a=f[t+24>>2]))>=1)for(;d=f[t+32>>2]+h|0,m=f[d+4>>2],f[(o=h+g|0)>>2]=f[d>>2],f[o+4>>2]=m,h=h+8|0,a=a+-1|0;);(a=f[t+32>>2])&&(_[t+36|0]&&CA(a),f[t+32>>2]=0),f[t+32>>2]=g,f[t+28>>2]=128,n[t+36|0]=1}for(f[t+24>>2]=128,g=f[t+32>>2],f[g+4>>2]=i,f[g>>2]=e,i=124,e=1;;){if(d=f[t+32>>2],g=e,o=f[(a=d+(v=(e=e+-1|0)<<3)|0)+4>>2],a=f[a>>2],(0|e)>(0|i)){if(!((0|(i=f[t+24>>2]))>=(0|(m=i<<1))|f[t+28>>2]>=(0|m))){if(i){if(d=dA(i<<4),!((0|(i=f[t+24>>2]))<1))for(h=0;y=f[t+32>>2]+h|0,R=f[y+4>>2],f[(p=h+d|0)>>2]=f[y>>2],f[p+4>>2]=R,h=h+8|0,i=i+-1|0;);}else d=0;(i=f[t+32>>2])&&(_[t+36|0]&&CA(i),f[t+32>>2]=0),f[t+32>>2]=d,n[t+36|0]=1,f[t+28>>2]=m}f[t+24>>2]=m,i=m+-4|0}t:if((0|a)!=(0|o)){if(!(C[a>>2]<=C[o+16>>2]^1|C[a+16>>2]>=C[o>>2]^1|C[a+4>>2]<=C[o+20>>2]^1|C[a+20>>2]>=C[o+4>>2]^1||C[a+8>>2]<=C[o+24>>2]^1|C[a+24>>2]>=C[o+8>>2]^1))if(h=f[o+40>>2],f[a+40>>2]){if(e=f[a+36>>2],h){f[(h=d+v|0)+4>>2]=f[o+36>>2],f[h>>2]=e,h=f[a+40>>2],d=(e=g<<3)+f[t+32>>2]|0,f[d+4>>2]=f[o+36>>2],f[d>>2]=h,h=f[a+36>>2],d=e+f[t+32>>2]|0,f[d+12>>2]=f[o+40>>2],f[d+8>>2]=h,a=f[a+40>>2],e=e+f[t+32>>2]|0,f[e+20>>2]=f[o+40>>2],f[e+16>>2]=a,e=g+3|0;break t}f[(h=d+v|0)+4>>2]=o,f[h>>2]=e,e=f[a+40>>2],a=f[t+32>>2]+(g<<3)|0,f[a+4>>2]=o,f[a>>2]=e,e=g+1|0}else h?(f[(e=d+v|0)+4>>2]=f[o+36>>2],f[e>>2]=a,e=f[t+32>>2]+(g<<3)|0,f[e+4>>2]=f[o+40>>2],f[e>>2]=a,e=g+1|0):yt[f[f[r>>2]+8>>2]](r,a,o)}else{if(!f[a+40>>2])break t;e=d+v|0,o=f[a+36>>2],f[e+4>>2]=o,f[e>>2]=o,o=(e=g<<3)+f[t+32>>2]|0,h=f[a+40>>2],f[o+4>>2]=h,f[o>>2]=h,o=f[a+40>>2],e=8+(e+f[t+32>>2]|0)|0,f[e>>2]=f[a+36>>2],f[e+4>>2]=o,e=g+2|0}if(!e)break}}}function Ei(t,e,i,r){for(var n=0,a=0,o=0,_=0,h=0,C=0,g=0,m=0,v=0,y=0,p=0,R=0,D=0,B=0;;){for(D=i,v=f[t+12>>2],R=f[(g=v+((i+r|0)/2<<4)|0)+8>>2],m=f[g+4>>2],p=f[g>>2],g=r;;){t:{if(!p)for(C=(i<<4)+v|0;;){_=-1,n=-1,(a=f[C>>2])&&(n=f[a+12>>2]),(o=f[C+4>>2])&&(_=f[o+12>>2]),h=m?f[m+12>>2]:-1;e:if(!((0|n)>-1)){if(!(a|(0|_)>(0|h))){if((0|o)!=(0|m))break t;if(d[C+8>>2]>R>>>0)break e;break t}if((0|_)<=(0|h)|a)break t}C=C+16|0,i=i+1|0}for(C=(i<<4)+v|0,y=f[p+12>>2];;){if(_=-1,n=-1,(a=f[C>>2])&&(n=f[a+12>>2]),(o=f[C+4>>2])&&(_=f[o+12>>2]),h=m?f[m+12>>2]:-1,!((0|n)>(0|y)))if((0|a)!=(0|p)|(0|_)>(0|h)){if((0|a)!=(0|p)|(0|_)<=(0|h))break t}else if((0|o)!=(0|m)|d[C+8>>2]<=R>>>0)break t;C=C+16|0,i=i+1|0}}t:{if(!p)for(n=(g<<4)+v|0;;){h=-1,_=-1,(o=f[n>>2])&&(_=f[o+12>>2]),h=m?f[m+12>>2]:h,a=-1,(y=f[n+4>>2])&&(a=f[y+12>>2]);e:if(!((0|_)<-1)){if(!(o|(0|h)>(0|a))){if((0|m)!=(0|y))break t;if(d[n+8>>2]>>0)break e;break t}if((0|h)<=(0|a)|o)break t}n=n+-16|0,g=g+-1|0}for(n=(g<<4)+v|0,B=f[p+12>>2];;){if(h=-1,_=-1,(o=f[n>>2])&&(_=f[o+12>>2]),h=m?f[m+12>>2]:h,a=-1,(y=f[n+4>>2])&&(a=f[y+12>>2]),!((0|B)>(0|_)))if((0|o)!=(0|p)|(0|h)>(0|a)){if((0|o)!=(0|p)|(0|h)<=(0|a))break t}else if((0|m)!=(0|y)|d[n+8>>2]>=R>>>0)break t;n=n+-16|0,g=g+-1|0}}if((0|i)<=(0|g)&&(h=f[(_=(i<<4)+v|0)+4>>2],a=f[_+8>>2],_=f[_+12>>2],v=f[C>>2],o=f[n+4>>2],f[C>>2]=f[n>>2],f[C+4>>2]=o,o=f[(n=n+8|0)+4>>2],f[(C=C+8|0)>>2]=f[n>>2],f[C+4>>2]=o,n=f[t+12>>2]+(g<<4)|0,f[n+12>>2]=_,f[n+4>>2]=h,f[n+8>>2]=a,f[n>>2]=v,g=g+-1|0,i=i+1|0),!((0|i)<=(0|g)))break;v=f[t+12>>2]}if((0|g)>(0|D)&&Ei(t,e,D,g),!((0|i)<(0|r)))break}}function Zi(t,e){e|=0,t=f[(t|=0)+4>>2],yt[f[f[t>>2]+8>>2]](t,f[e+36>>2])}function Yi(t,e){return v((t?v(-e):e)*e)}function Vi(t,e){var i,r=0,n=0,a=0,o=0,_=0,h=v(0),d=0,C=0;s(e),i=(_=(a=c(0))<<1)+-1|0;t:{e:{i:{A:{s(t);r:{if((r=c(0))+-8388608>>>0<=2130706431){if(i>>>0>4278190078)break r;break i}if(i>>>0<4278190079)break A}if(h=v(1),!_|1065353216==(0|r))break e;if(r<<=1,!(_>>>0<4278190081&&r>>>0<=4278190080))return v(t+e);if(2130706432==(0|r))break e;return v((-1^a)>>>31==(r>>>0<2130706432|0)?0:e*e)}if((r<<1)-1>>>0>=4278190079){if(h=v(t*t),(0|r)>-1||((r=a>>>23&255)+-127>>>0>23||(h=(r=1<<150-r)&a?r+-1&a?h:v(-h):h)),(0|a)>-1)break e;return v(v(1)/h)}if((0|r)<=-1){if((o=a>>>23&255)>>>0<127)break t;A:{if(o>>>0<=150){if((o=1<<150-o)+-1&a)break t;if(_=65536,a&o)break A}_=0}o=_,r&=2147483647}r>>>0>8388607||(r=(2147483647&(s(v(t*v(8388608))),c(0)))-192937984|0)}if(d=(n=g[(_=(a=r+-1060306944|0)>>>15&240)+19464>>3]*(b(0,r-(-8388608&a)|0),+k())-1)*n,u(+(n=((g[2466]+g[2465]*n)*(d*d)+(d*(g[2468]+g[2467]*n)+(g[_+19472>>3]+ +(a>>23)+n*g[2469])))*+e)),r=0|c(1),c(0),!(1079967744==(0|(r&=2147450880))|r>>>0<1079967744)){if(n>127.99999995700433)return Yi(o,v(15845632502852868e13));if(n<=-150)return Yi(o,v(2524354896707238e-44))}n=(n=(C=n)-((d=C+(n=g[2502]))-n))*n*(g[2504]+g[2503]*n)+(n*g[2505]+1),u(+d),c(1),a=o+(r=0|c(0))<<15,r=_=f[(o=19760+((31&r)<<3)|0)>>2],a=f[o+4>>2]+a|0,b(0,0|r),b(1,0|(r>>>0>>0?a+1|0:a)),h=v(n*+l())}return h}return t=v(t-t),v(t/t)}function Ni(t){var e,i,r=v(0),n=v(0);if(s(t),(e=2147483647&(i=c(0)))>>>0>=1065353216)return v(1065353216==(0|e)?(0|i)<0?3.141592502593994:0:v(0)/v(t-t));t:{if(e>>>0<=1056964607){if(r=v(1.570796251296997),e>>>0<847249409)break t;return r=v(t*t),v(v(v(v(7.549789415861596e-8)-v(v(v(r*v(v(r*v(v(r*v(-.008656363002955914))+v(-.04274342209100723)))+v(.16666586697101593)))/v(v(r*v(-.7066296339035034))+v(1)))*t))-t)+v(1.570796251296997))}if((0|i)<=-1)return t=v(v(t+v(1))*v(.5)),r=v(E(t)),t=v(v(1.570796251296997)-v(r+v(v(r*v(v(t*v(v(t*v(v(t*v(-.008656363002955914))+v(-.04274342209100723)))+v(.16666586697101593)))/v(v(t*v(-.7066296339035034))+v(1))))+v(-7.549789415861596e-8)))),v(t+t);t=v(v(v(1)-t)*v(.5)),b(0,-4096&(s(n=v(E(t))),c(0))),r=k(),t=v(v(v(n*v(v(t*v(v(t*v(v(t*v(-.008656363002955914))+v(-.04274342209100723)))+v(.16666586697101593)))/v(v(t*v(-.7066296339035034))+v(1))))+v(v(t-v(r*r))/v(n+r)))+r),r=v(t+t)}return r}function Ji(t,e,i){xi(t+4|0,t+372|0,t+388|0,e,i)}function xi(t,e,i,r,n){var a,o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=0;Z=a=Z-16|0,o=C[t+52>>2],_=C[t+56>>2],d=C[t+48>>2],h=C[e>>2],g=C[e+4>>2],m=C[e+8>>2],f[n+60>>2]=0,C[n+56>>2]=_+v(m*r),C[n+52>>2]=o+v(g*r),C[n+48>>2]=d+v(h*r),d=C[i>>2],y=C[i+4>>2],p=C[i+8>>2],o=(o=v(v(v(d*d)+v(y*y))+v(p*p)))>v(1.1920928955078125e-7)?v(E(o)):v(0),o=(_=v(o*r)>v(.7853981852531433)?v(v(.7853981852531433)/r):o)>2],g=Cr(v(v(_*r)*v(.5))),m=v(d*o),R=C[a>>2],y=v(y*o),D=C[a+4>>2],o=v(p*o),p=C[a+8>>2],_=v(v(v(v(h*g)-v(m*R))-v(y*D))-v(o*p)),d=v(v(v(v(o*h)+v(g*p))+v(m*D))-v(y*R)),r=v(v(v(v(g*R)+v(m*h))+v(y*p))-v(o*D)),o=v(v(v(o*R)+v(v(y*h)+v(g*D)))-v(m*p)),(h=v(v(_*_)+v(v(d*d)+v(v(r*r)+v(o*o)))))>v(1.1920928955078125e-7)&&(h=v(v(1)/v(E(h))),_=v(_*h),d=v(d*h),o=v(o*h),r=v(r*h),h=v(v(_*_)+v(v(d*d)+v(v(o*o)+v(r*r))))),h>v(1.1920928955078125e-7)?(f[n+12>>2]=0,f[n+44>>2]=0,f[n+28>>2]=0,g=v(v(2)/h),h=v(d*g),m=v(o*h),R=v(r*g),y=v(_*R),C[n+36>>2]=m+y,D=v(r*h),g=v(o*g),p=v(_*g),C[n+32>>2]=D-p,C[n+24>>2]=m-y,m=v(r*g),_=v(_*h),C[n+16>>2]=m+_,C[n+8>>2]=D+p,C[n+4>>2]=m-_,r=v(r*R),o=v(o*g),C[n+40>>2]=v(1)-v(r+o),_=r,r=v(d*h),C[n+20>>2]=v(1)-v(_+r),C[n>>2]=v(1)-v(o+r)):(e=f[t+4>>2],f[n>>2]=f[t>>2],f[n+4>>2]=e,B=f[(i=t+8|0)+4>>2],f[(e=n+8|0)>>2]=f[i>>2],f[e+4>>2]=B,e=f[t+20>>2],f[n+16>>2]=f[t+16>>2],f[n+20>>2]=e,B=f[(i=t+24|0)+4>>2],f[(e=n+24|0)>>2]=f[i>>2],f[e+4>>2]=B,e=f[t+36>>2],f[n+32>>2]=f[t+32>>2],f[n+36>>2]=e,i=f[(t=t+40|0)+4>>2],f[(e=n+40|0)>>2]=f[t>>2],f[e+4>>2]=i),Z=a+16|0}function Ui(t,e){var i,r=0,n=0,a=0,o=0,_=0,h=0,d=0,g=v(0),m=0;Z=i=Z-32|0,e!=v(0)&&((r=f[t+540>>2])&&yt[f[f[r>>2]+8>>2]](r,t+4|0),f[t+384>>2]=0,r=t+380|0,e=v(v(1)/e),o=t+60|0,_=t+124|0,C[r>>2]=e*v(C[o>>2]-C[_>>2]),C[t+376>>2]=e*v(C[t+56>>2]-C[t+120>>2]),h=t+52|0,d=t+116|0,C[t+372>>2]=e*v(C[h>>2]-C[d>>2]),Mi(t+68|0,t+4|0,i+16|0,i+12|0),f[t+400>>2]=0,n=t+396|0,g=C[i+12>>2],C[n>>2]=e*v(g*C[i+24>>2]),C[t+392>>2]=e*v(g*C[i+20>>2]),C[t+388>>2]=e*v(g*C[i+16>>2]),m=f[r+4>>2],f[(a=t+140|0)>>2]=f[r>>2],f[a+4>>2]=m,r=f[t+376>>2],f[t+132>>2]=f[t+372>>2],f[t+136>>2]=r,r=f[t+392>>2],f[t+148>>2]=f[t+388>>2],f[t+152>>2]=r,a=f[n+4>>2],f[(r=t+156|0)>>2]=f[n>>2],f[r+4>>2]=a,r=f[t+8>>2],f[t+68>>2]=f[t+4>>2],f[t+72>>2]=r,a=f[(n=t+12|0)+4>>2],f[(r=t+76|0)>>2]=f[n>>2],f[r+4>>2]=a,a=f[(n=t+20|0)+4>>2],f[(r=t+84|0)>>2]=f[n>>2],f[r+4>>2]=a,a=f[(n=t+28|0)+4>>2],f[(r=t+92|0)>>2]=f[n>>2],f[r+4>>2]=a,a=f[(n=t+44|0)+4>>2],f[(r=t+108|0)>>2]=f[n>>2],f[r+4>>2]=a,r=t+100|0,n=f[(t=t+36|0)+4>>2],f[r>>2]=f[t>>2],f[r+4>>2]=n,t=f[o+4>>2],f[_>>2]=f[o>>2],f[_+4>>2]=t,t=f[h+4>>2],f[d>>2]=f[h>>2],f[d+4>>2]=t),Z=i+32|0}function Mi(t,e,i,r){var n,a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),B=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),yt=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0);Z=n=Z+-64|0,F=C[e+24>>2],V=C[e+20>>2],G=C[e+40>>2],w=C[e+36>>2],d=C[t+40>>2],g=C[t+20>>2],p=C[t+36>>2],m=C[t+24>>2],Q=C[e+8>>2],W=C[e>>2],Y=C[e+4>>2],z=C[e+16>>2],yt=C[e+32>>2],o=C[t+8>>2],_=C[t+4>>2],B=C[t+32>>2],y=C[t+16>>2],h=C[t>>2],f[n+60>>2]=0,f[n+44>>2]=0,Dt=v(v(g*d)-v(m*p)),It=v(v(m*B)-v(d*y)),St=v(v(p*y)-v(g*B)),a=v(v(1)/v(v(v(h*Dt)+v(_*It))+v(o*St))),pt=v(v(v(m*_)-v(g*o))*a),m=v(v(v(y*o)-v(m*h))*a),g=v(v(v(g*h)-v(y*_))*a),C[n+56>>2]=v(v(yt*pt)+v(w*m))+v(G*g),y=v(v(v(p*o)-v(d*_))*a),o=v(v(v(d*h)-v(B*o))*a),_=v(v(v(B*_)-v(p*h))*a),C[n+52>>2]=v(v(yt*y)+v(w*o))+v(G*_),C[n+40>>2]=v(v(pt*z)+v(m*V))+v(g*F),C[n+36>>2]=v(v(y*z)+v(o*V))+v(_*F),f[n+28>>2]=0,h=v(Dt*a),d=v(It*a),a=v(St*a),C[n+48>>2]=v(v(yt*h)+v(w*d))+v(G*a),C[n+32>>2]=v(v(h*z)+v(d*V))+v(a*F),C[n+24>>2]=v(Q*g)+v(v(W*pt)+v(Y*m)),C[n+20>>2]=v(Q*_)+v(v(W*y)+v(Y*o)),C[n+16>>2]=v(Q*a)+v(v(W*h)+v(Y*d)),tt(n+16|0,n),h=C[n>>2],_=C[n+4>>2],o=C[n+8>>2],d=C[n+12>>2],a=v(v(1)/v(E(v(v(v(v(h*h)+v(_*_))+v(o*o))+v(d*d))))),o=v(o*a),C[n+8>>2]=o,_=v(_*a),C[n+4>>2]=_,h=v(h*a),C[n>>2]=h,a=v(d*a),C[n+12>>2]=a,a=Ni(v(R(v(D(a,v(-1))),v(1)))),C[r>>2]=a+a,f[i+12>>2]=0,C[i+8>>2]=o,C[i+4>>2]=_,C[i>>2]=h,(a=v(v(v(h*h)+v(_*_))+v(o*o)))>2]=0,f[i+12>>2]=0,f[i>>2]=1065353216,f[i+4>>2]=0):(a=v(v(1)/v(E(a))),C[i+8>>2]=o*a,C[i+4>>2]=_*a,C[i>>2]=h*a),Z=n- -64|0}function Si(t,e){var i=v(0),r=0,n=v(0),a=v(0),o=v(0);(i=C[t+404>>2])!=v(0)&&(n=C[e>>2],a=C[e+4>>2],o=C[e+8>>2],f[t+436>>2]=0,i=v(v(1)/i),C[t+432>>2]=o*i,C[t+428>>2]=i*a,C[t+424>>2]=i*n),r=f[e+4>>2],f[t+440>>2]=f[e>>2],f[t+444>>2]=r,r=f[(e=e+8|0)+4>>2],f[(t=t+448|0)>>2]=f[e>>2],f[t+4>>2]=r}function Xi(t,e){var i=0,r=v(0),n=v(0),a=v(0),o=v(0),h=v(0),d=v(0),g=v(0),m=v(0);if(g=C[t+504>>2],n=Vi(v(v(1)-g),e),o=v(n*C[t+372>>2]),C[t+372>>2]=o,r=v(n*C[(i=t+376|0)>>2]),C[i>>2]=r,n=v(n*C[(i=t+380|0)>>2]),C[i>>2]=n,m=C[t+508>>2],a=Vi(v(v(1)-m),e),e=v(a*C[t+388>>2]),C[t+388>>2]=e,h=v(a*C[(i=t+392|0)>>2]),C[i>>2]=h,a=v(a*C[(i=t+396|0)>>2]),C[i>>2]=a,_[t+512|0]&&(v(v(v(e*e)+v(h*h))+v(a*a))>2]^1|v(v(v(o*o)+v(r*r))+v(n*n))>2]^1||(d=C[t+516>>2],a=v(a*d),C[t+396>>2]=a,h=v(h*d),C[t+392>>2]=h,e=v(e*d),C[t+388>>2]=e,n=v(n*d),C[t+380>>2]=n,r=v(r*d),C[t+376>>2]=r,o=v(o*d),C[t+372>>2]=o),(d=v(E(v(v(v(o*o)+v(r*r))+v(n*n)))))v(.004999999888241291)?(g=n,n=v(v(1)/d),C[t+380>>2]=g-v(v(g*n)*v(.004999999888241291)),C[t+376>>2]=r-v(v(r*n)*v(.004999999888241291)),C[t+372>>2]=o-v(v(o*n)*v(.004999999888241291))):(f[(i=t+372|0)>>2]=0,f[i+4>>2]=0,f[(i=i+8|0)>>2]=0,f[i+4>>2]=0)),(r=v(E(v(v(v(e*e)+v(h*h))+v(a*a)))))v(.004999999888241291))return r=v(v(1)/r),C[t+396>>2]=a-v(v(a*r)*v(.004999999888241291)),C[t+392>>2]=h-v(v(h*r)*v(.004999999888241291)),void(C[t+388>>2]=e-v(v(e*r)*v(.004999999888241291)));f[(t=t+388|0)>>2]=0,f[t+4>>2]=0,f[(t=t+8|0)>>2]=0,f[t+4>>2]=0}}function Ti(t){var e=0;3&_[t+204|0]||(C[t+472>>2]=v(C[t+424>>2]*C[t+408>>2])+C[t+472>>2],C[(e=t+476|0)>>2]=v(C[t+428>>2]*C[t+412>>2])+C[e>>2],C[(e=t+480|0)>>2]=v(C[t+432>>2]*C[t+416>>2])+C[e>>2])}function ji(t,e){!function(t,e){var i,r=0,n=0,a=0,o=0,h=0,d=v(0),g=v(0),m=v(0),y=0,p=v(0),R=v(0),D=v(0),B=0,E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),Z=v(0);2&_[t+204|0]?(r=f[t+8>>2],f[t+68>>2]=f[t+4>>2],f[t+72>>2]=r,a=f[(n=t+12|0)+4>>2],f[(r=t+76|0)>>2]=f[n>>2],f[r+4>>2]=a,a=f[(n=t+20|0)+4>>2],f[(r=t+84|0)>>2]=f[n>>2],f[r+4>>2]=a,a=f[(n=t+28|0)+4>>2],f[(r=t+92|0)>>2]=f[n>>2],f[r+4>>2]=a,a=f[(n=t+36|0)+4>>2],f[(r=t+100|0)>>2]=f[n>>2],f[r+4>>2]=a,a=f[(n=t+44|0)+4>>2],f[(r=t+108|0)>>2]=f[n>>2],f[r+4>>2]=a,a=f[(n=t+52|0)+4>>2],f[(r=t+116|0)>>2]=f[n>>2],f[r+4>>2]=a,a=f[(n=t+60|0)+4>>2],f[(r=t+124|0)>>2]=f[n>>2],f[r+4>>2]=a):(r=f[e+4>>2],f[t+68>>2]=f[e>>2],f[t+72>>2]=r,a=f[(n=e+8|0)+4>>2],f[(r=t+76|0)>>2]=f[n>>2],f[r+4>>2]=a,a=f[(n=e+24|0)+4>>2],f[(r=t+92|0)>>2]=f[n>>2],f[r+4>>2]=a,n=f[e+20>>2],f[(r=t+84|0)>>2]=f[e+16>>2],f[r+4>>2]=n,n=f[e+36>>2],f[(r=t+100|0)>>2]=f[e+32>>2],f[r+4>>2]=n,a=f[(n=e+40|0)+4>>2],f[(r=t+108|0)>>2]=f[n>>2],f[r+4>>2]=a,a=f[(n=e+56|0)+4>>2],f[(r=t+124|0)>>2]=f[n>>2],f[r+4>>2]=a,n=f[e+52>>2],f[(r=t+116|0)>>2]=f[e+48>>2],f[r+4>>2]=n),r=f[t+392>>2],f[t+148>>2]=f[t+388>>2],f[t+152>>2]=r,r=f[t+376>>2],f[t+132>>2]=f[t+372>>2],f[t+136>>2]=r,a=f[(n=t+396|0)+4>>2],f[(r=t+156|0)>>2]=f[n>>2],f[r+4>>2]=a,a=f[(n=t+380|0)+4>>2],f[(r=t+140|0)>>2]=f[n>>2],f[r+4>>2]=a,B=f[(a=e+8|0)+4>>2],f[(r=t+12|0)>>2]=f[a>>2],f[r+4>>2]=B,n=f[e+4>>2],f[t+4>>2]=f[e>>2],f[t+8>>2]=n,h=f[(B=e+24|0)+4>>2],f[(n=t+28|0)>>2]=f[B>>2],f[n+4>>2]=h,h=f[e+20>>2],f[(a=t+20|0)>>2]=f[e+16>>2],f[a+4>>2]=h,y=f[(o=e+40|0)+4>>2],f[(h=B=t+44|0)>>2]=f[o>>2],f[h+4>>2]=y,y=f[e+36>>2],f[(o=h=t+36|0)>>2]=f[e+32>>2],f[o+4>>2]=y,i=f[(y=e+56|0)+4>>2],f[(o=t+60|0)>>2]=f[y>>2],f[o+4>>2]=i,y=f[e+52>>2],f[(o=t+52|0)>>2]=f[e+48>>2],f[o+4>>2]=y,E=C[t+8>>2],F=C[r>>2],V=C[n>>2],G=C[a>>2],w=C[t+24>>2],p=C[B>>2],W=C[t+464>>2],R=C[h>>2],D=C[t+40>>2],Y=C[t+460>>2],Q=C[t+4>>2],Z=C[t+456>>2],f[t+368>>2]=0,f[t+352>>2]=0,f[t+336>>2]=0,d=v(Z*R),g=v(Y*D),m=v(W*p),C[t+364>>2]=v(v(R*d)+v(D*g))+v(p*m),C[t+360>>2]=v(v(G*d)+v(w*g))+v(V*m),C[t+356>>2]=v(v(Q*d)+v(E*g))+v(F*m),d=v(Z*G),g=v(Y*w),m=v(W*V),C[t+348>>2]=v(v(R*d)+v(D*g))+v(p*m),C[t+344>>2]=v(v(G*d)+v(w*g))+v(V*m),C[t+340>>2]=v(v(Q*d)+v(E*g))+v(F*m),d=R,R=v(Q*Z),g=D,D=v(E*Y),m=p,p=v(F*W),C[t+332>>2]=v(v(d*R)+v(g*D))+v(m*p),C[t+328>>2]=v(v(R*G)+v(D*w))+v(p*V),C[t+324>>2]=v(v(Q*R)+v(E*D))+v(F*p)}(t,e)}function Oi(t,e,i){var r=v(0),n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0);f[t+12>>2]=0,n=C[e+388>>2],p=(r=C[e+456>>2])!=v(0)?v(v(1)/r):v(0),R=C[e+20>>2],a=v(p*R),h=C[e+4>>2],G=(r=C[e+460>>2])!=v(0)?v(v(1)/r):v(0),D=C[e+24>>2],d=v(G*D),g=C[e+8>>2],w=(r=C[e+464>>2])!=v(0)?v(v(1)/r):v(0),B=C[e+28>>2],m=v(w*B),F=C[e+12>>2],r=C[e+392>>2],y=v(v(n*v(v(v(a*h)+v(d*g))+v(m*F)))+v(v(v(v(a*R)+v(d*D))+v(m*B))*r)),V=C[e+36>>2],o=d,d=C[e+40>>2],_=m,m=C[e+44>>2],o=v(v(v(a*V)+v(o*d))+v(_*m)),a=C[e+396>>2],Q=v(y+v(o*a)),_=v(p*h),y=v(G*g),o=v(w*F),y=v(v(v(v(v(v(_*h)+v(y*g))+v(o*F))*n)+v(r*v(v(v(_*R)+v(y*D))+v(o*B))))+v(v(v(v(_*V)+v(y*d))+v(o*m))*a)),_=v(v(n*Q)-v(r*y)),C[t+8>>2]=_,o=n,n=v(p*V),p=v(h*n),h=v(G*d),p=v(p+v(g*h)),g=v(w*m),R=v(v(v(o*v(p+v(F*g)))+v(r*v(v(v(n*R)+v(h*D))+v(g*B))))+v(a*v(v(v(n*V)+v(h*d))+v(g*m)))),n=v(v(a*y)-v(o*R)),C[t+4>>2]=n,r=v(v(r*R)-v(a*Q)),C[t>>2]=r,(a=v(v(_*_)+v(v(r*r)+v(n*n))))>v(i*i)&&(i=v(v(v(1)/v(E(a)))*i),C[t+8>>2]=_*i,C[t+4>>2]=n*i,C[t>>2]=r*i)}function Hi(t,e,i){var r,n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),yt=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0);Z=r=Z-16|0,d=C[e+464>>2],n=C[e+460>>2],w=C[e+396>>2],Q=C[e+392>>2],_=C[e+456>>2],W=C[e+388>>2],tt(e+4|0,r),f[t+12>>2]=0,g=C[r+12>>2],m=C[r+4>>2],p=C[r+8>>2],o=v(v(v(W*g)-v(w*m))+v(Q*p)),R=C[r>>2],F=v(v(v(Q*m)+v(W*R))+v(w*p)),h=v(v(v(w*g)-v(Q*R))+v(W*m)),V=v(v(v(Q*g)-v(W*p))+v(w*R)),a=v(v(v(m*o)+v(v(p*F)+v(g*h)))-v(R*V)),B=v(a*v(0)),D=v(v(v(p*V)+v(v(R*F)+v(g*o)))-v(m*h)),G=v(D*v(0)),n=n!=v(0)?v(v(1)/n):v(0),o=v(v(v(R*h)+v(v(m*F)+v(g*V)))-v(p*o)),F=v(B+v(G+v(n*o))),_=_!=v(0)?v(v(1)/_):v(0),St=v(v(v(v(v(G-v(_*o))+v(0))+v(F+v(0)))*i)+v(0)),h=d!=v(0)?v(v(1)/d):v(0),E=v(o*v(0)),V=v(v(a*h)+v(G+E)),pt=v(B+v(v(_*D)+E)),d=v(v(v(a*pt)-v(D*V))*i),Y=v(a*v(-0)),Tt=v(_+v(v(E+v(v(_*v(0))+Y))*i)),z=v(o*v(-0)),Dt=v(v(v(v(v(z+v(n*D))+v(0))-pt)*i)+v(0)),E=v(v(v(v(E+v(v(0)-v(n*a)))+V)*i)+v(0)),It=v(v(v(v(v(B+v(0))-v(h*D))+pt)*i)+v(0)),yt=v(D*v(-0)),n=v(n+v(v(yt+v(v(n*v(0))+B))*i)),B=v(v(v(v(v(h*o)+v(Y+v(0)))-F)*i)+v(0)),Y=v(v(E*It)-v(n*B)),h=v(h+v(v(v(h*v(0))+v(z+G))*i)),z=v(v(n*h)-v(Dt*It)),G=v(v(v(v(yt+v(v(_*a)+v(0)))-V)*i)+v(0)),yt=v(v(Dt*B)-v(h*E)),_=v(v(St*Y)+v(v(Tt*z)+v(G*yt))),_=v(y(_))>v(1.1920928955078125e-7)?v(v(1)/_):_,Et=a,a=v(v(v(o*V)-v(a*F))*i),i=v(v(v(D*F)-v(o*pt))*i),n=v(Et-v(v(v(St*v(v(E*d)-v(n*a)))+v(v(Tt*v(v(n*i)-v(Dt*d)))+v(G*v(v(Dt*a)-v(E*i)))))*_)),o=v(o-v(v(v(St*v(v(It*a)-v(B*d)))+v(v(Tt*v(v(h*d)-v(It*i)))+v(G*v(v(B*i)-v(h*a)))))*_)),i=v(D-v(v(v(i*Y)+v(v(a*z)+v(d*yt)))*_)),a=v(v(v(g*n)+v(R*o))-v(m*i)),D=v(v(v(-v(R*i))-v(m*o))-v(p*n)),d=v(v(v(g*i)+v(m*n))-v(p*o)),i=v(v(v(p*i)+v(g*o))-v(R*n)),C[t+8>>2]=v(v(v(v(g*a)-v(D*p))-v(d*m))+v(i*R))-w,C[t+4>>2]=v(v(v(v(g*i)-v(D*m))-v(a*R))+v(d*p))-Q,C[t>>2]=v(v(v(v(g*d)-v(D*R))-v(i*p))+v(a*m))-W,Z=r+16|0}function zi(t,e,i){var r=v(0),n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),Z=v(0),z=v(0),yt=v(0),pt=v(0),Dt=v(0),It=v(0);f[t+12>>2]=0,Y=(r=C[e+456>>2])!=v(0)?v(v(1)/r):v(0),p=C[e+36>>2],Q=v(Y*p),R=C[e+4>>2],_=(r=C[e+460>>2])!=v(0)?v(v(1)/r):v(0),F=C[e+40>>2],Z=v(_*F),a=C[e+8>>2],D=(r=C[e+464>>2])!=v(0)?v(v(1)/r):v(0),h=C[e+44>>2],yt=v(D*h),n=C[e+12>>2],o=v(v(v(Q*R)+v(Z*a))+v(yt*n)),r=C[e+388>>2],d=C[e+20>>2],V=v(Y*d),g=C[e+24>>2],W=v(_*g),m=C[e+28>>2],G=v(D*m),z=v(v(v(V*R)+v(W*a))+v(G*n)),pt=v(r*z),B=C[e+392>>2],w=v(v(v(V*d)+v(W*g))+v(G*m)),E=C[e+396>>2],W=v(v(v(V*p)+v(W*F))+v(G*h)),It=v(E*W),V=v(v(pt+v(B*w))+It),Dt=pt,G=v(Y*R),pt=v(_*a),D=v(D*n),a=v(v(v(G*R)+v(pt*a))+v(D*n)),Y=v(o+v(v(v(v(o*v(0))+v(Dt-v(a*B)))+V)*i)),_=v(v(v(G*d)+v(pt*g))+v(D*m)),Dt=v(r*o),g=v(v(v(Q*d)+v(Z*g))+v(yt*m)),d=v(B*g),n=v(v(v(Q*p)+v(Z*F))+v(yt*h)),R=v(v(Dt+d)+v(E*n)),d=v(_+v(v(R+v(d+v(v(_*v(0))-v(w*E))))*i)),yt=v(B*_),h=v(v(v(G*p)+v(pt*F))+v(D*h)),m=v(E*h),p=v(v(v(r*a)+yt)+m),Z=v(i*v(0)),F=v(v(V+v(v(v(E*p)-v(r*R))*i))-v(Z+V)),m=v(W+v(v(p+v(v(v(W*v(0))+m)-v(n*r)))*i)),_=v(w+v(v(v(v(w*v(0))+v(E*_))-v(g*r))*i)),Q=v(h+v(v(v(v(B*n)+v(v(h*v(0))-It))-V)*i)),G=v(v(d*m)-v(_*Q)),D=v(a+v(v(v(B*o)+v(v(a*v(0))-v(z*E)))*i)),n=v(n+v(v(v(n*v(0))+v(v(r*W)-v(h*B)))*i)),w=v(g+v(v(v(v(g*v(0))+v(v(r*w)-yt))-p)*i)),g=v(v(_*n)-v(w*m)),h=v(z+v(v(v(v(v(z*v(0))+v(E*a))-Dt)-R)*i)),z=v(v(w*Q)-v(d*n)),o=v(v(Y*G)+v(v(D*g)+v(h*z))),a=v(y(o))>v(1.1920928955078125e-7)?v(v(1)/o):o,o=v(v(p+v(v(v(B*R)-v(E*V))*i))-v(Z+p)),i=v(v(R+v(v(v(r*V)-v(B*p))*i))-v(Z+R)),C[t+8>>2]=v(E-v(v(v(Y*v(v(d*F)-v(_*o)))+v(v(D*v(v(_*i)-v(w*F)))+v(h*v(v(w*o)-v(d*i)))))*a))-E,C[t+4>>2]=v(B-v(v(v(Y*v(v(m*o)-v(Q*F)))+v(v(D*v(v(n*F)-v(m*i)))+v(h*v(v(Q*i)-v(n*o)))))*a))-B,C[t>>2]=v(r-v(v(v(i*G)+v(v(o*g)+v(F*z)))*a))-r}function Pi(t,e){var i=0,r=0,a=0,o=0,h=0;t:{e:if(!((0|(r=f[t+548>>2]))<1)){for(a=f[t+556>>2],i=r;;){if((0|e)!=f[a>>2]){if(a=a+4|0,i=i+-1|0)continue;break e}break}if(i)break t}if(f[t+552>>2]==(0|r)&&!((0|r)>=(0|(o=r?r<<1:1)))){if(o&&(h=dA(o<<2),r=f[t+548>>2]),(0|r)>=1)for(a=0,i=r;f[a+h>>2]=f[f[t+556>>2]+a>>2],a=a+4|0,i=i+-1|0;);(i=f[t+556>>2])&&(_[t+560|0]&&(CA(i),r=f[t+548>>2]),f[t+556>>2]=0),f[t+556>>2]=h,f[t+552>>2]=o,n[t+560|0]=1}f[f[t+556>>2]+(r<<2)>>2]=e,f[t+548>>2]=r+1,i=f[e+32>>2];e:if((0|t)!=(0|(h=f[e+28>>2]))){if((0|(e=f[i+288>>2]))==f[i+292>>2]&&!((0|e)>=(0|(o=e?e<<1:1)))){if(o?(r=dA(o<<2),e=f[i+288>>2]):r=0,(0|e)>=1)for(a=0,t=e;f[r+a>>2]=f[f[i+296>>2]+a>>2],a=a+4|0,t=t+-1|0;);(t=f[i+296>>2])&&(_[i+300|0]&&(CA(t),e=f[i+288>>2]),f[i+296>>2]=0),f[i+296>>2]=r,f[i+292>>2]=o,n[i+300|0]=1}t=i,i=h}else{if((0|(e=f[t+288>>2]))!=f[t+292>>2])break e;if((0|e)>=(0|(o=e?e<<1:1)))break e;if(o?(h=dA(o<<2),e=f[t+288>>2]):h=0,(0|e)>=1)for(a=0,r=e;f[a+h>>2]=f[f[t+296>>2]+a>>2],a=a+4|0,r=r+-1|0;);(r=f[t+296>>2])&&(_[t+300|0]&&(CA(r),e=f[t+288>>2]),f[t+296>>2]=0),f[t+296>>2]=h,f[t+292>>2]=o,n[t+300|0]=1}f[t+288>>2]=e+1,f[t+280>>2]=(-1^e)>>>31,f[f[t+296>>2]+(e<<2)>>2]=i}}function Ki(t,e){var i=0,r=0,n=0,a=0,o=0;t:if(!((0|(a=f[t+548>>2]))<1)){for(r=n=f[t+556>>2];;){if((0|e)!=f[r>>2]){if(r=r+4|0,(0|a)!=(0|(i=i+1|0)))continue;break t}break}if(!((0|i)>=(0|a))){i=0,r=n;e:{for(;;){if((0|e)!=f[r>>2]){if(r=r+4|0,(0|a)!=(0|(i=i+1|0)))continue;break e}break}(0|a)<=(0|i)||(o=r,i=n,n=(r=a+-1|0)<<2,f[o>>2]=f[i+n>>2],f[t+548>>2]=r,f[n+f[t+556>>2]>>2]=e)}if(a=f[e+32>>2],(0|t)==(0|(n=f[e+28>>2]))){e:if(!((0|(e=f[t+288>>2]))<1)){for(i=0,r=n=f[t+296>>2];;){if(f[r>>2]!=(0|a)){if(r=r+4|0,(0|(i=i+1|0))!=(0|e))continue;break e}break}(0|e)<=(0|i)||(i=n,n=(e=e+-1|0)<<2,f[r>>2]=f[i+n>>2],f[t+288>>2]=e,f[n+f[t+296>>2]>>2]=a)}return void(f[t+280>>2]=(0|e)>0)}e:if(!((0|(e=f[a+288>>2]))<1)){for(i=0,r=t=f[a+296>>2];;){if(f[r>>2]!=(0|n)){if(r=r+4|0,(0|(i=i+1|0))!=(0|e))continue;break e}break}(0|e)<=(0|i)||(i=t,t=(e=e+-1|0)<<2,f[r>>2]=f[i+t>>2],f[a+288>>2]=e,f[t+f[a+296>>2]>>2]=n)}f[a+280>>2]=(0|e)>0}}}function Li(t){var e=0;f[t>>2]=20180,n[t+20|0]=1,f[t+16>>2]=0,n[t+40|0]=1,f[(e=t+8|0)>>2]=0,f[e+4>>2]=0,f[t+36>>2]=0,n[t+60|0]=1,f[(e=t+28|0)>>2]=0,f[e+4>>2]=0,f[t+56>>2]=0,n[t+80|0]=1,f[(e=t+48|0)>>2]=0,f[e+4>>2]=0,f[t+76>>2]=0,n[t+100|0]=1,f[(e=t+68|0)>>2]=0,f[e+4>>2]=0,f[t+96>>2]=0,n[t+120|0]=1,f[(e=t+88|0)>>2]=0,f[e+4>>2]=0,f[t+116>>2]=0,n[t+140|0]=1,f[(e=t+108|0)>>2]=0,f[e+4>>2]=0,f[t+136>>2]=0,f[(e=t+128|0)>>2]=0,f[e+4>>2]=0,n[t+160|0]=1,f[t+156>>2]=0,f[(e=t+148|0)>>2]=0,f[e+4>>2]=0,n[t+180|0]=1,f[t+176>>2]=0,f[(e=t+168|0)>>2]=0,f[e+4>>2]=0,n[t+208|0]=1,f[t+232>>2]=0,f[t+204>>2]=0,f[(e=t+196|0)>>2]=0,f[e+4>>2]=0,f[t+224>>2]=0,f[t+212>>2]=534,f[t+216>>2]=535,f[t+220>>2]=536}function qi(t){var e=0;return f[(t|=0)>>2]=20180,(e=f[t+204>>2])&&(_[t+208|0]&&CA(e),f[t+204>>2]=0),f[t+204>>2]=0,f[t+196>>2]=0,f[t+200>>2]=0,n[t+208|0]=1,(e=f[t+176>>2])&&(_[t+180|0]&&CA(e),f[t+176>>2]=0),f[t+176>>2]=0,f[t+168>>2]=0,f[t+172>>2]=0,n[t+180|0]=1,(e=f[t+156>>2])&&(_[t+160|0]&&CA(e),f[t+156>>2]=0),f[t+156>>2]=0,f[t+148>>2]=0,f[t+152>>2]=0,n[t+160|0]=1,(e=f[t+136>>2])&&(_[t+140|0]&&CA(e),f[t+136>>2]=0),f[t+136>>2]=0,f[t+128>>2]=0,f[t+132>>2]=0,n[t+140|0]=1,(e=f[t+116>>2])&&(_[t+120|0]&&CA(e),f[t+116>>2]=0),f[t+116>>2]=0,f[t+108>>2]=0,f[t+112>>2]=0,n[t+120|0]=1,(e=f[t+96>>2])&&(_[t+100|0]&&CA(e),f[t+96>>2]=0),f[t+96>>2]=0,f[t+88>>2]=0,f[t+92>>2]=0,n[t+100|0]=1,(e=f[t+76>>2])&&(_[t+80|0]&&CA(e),f[t+76>>2]=0),f[t+76>>2]=0,f[t+68>>2]=0,f[t+72>>2]=0,n[t+80|0]=1,(e=f[t+56>>2])&&(_[t+60|0]&&CA(e),f[t+56>>2]=0),f[t+56>>2]=0,f[t+48>>2]=0,f[t+52>>2]=0,n[t+60|0]=1,(e=f[t+36>>2])&&(_[t+40|0]&&CA(e),f[t+36>>2]=0),f[t+36>>2]=0,f[t+28>>2]=0,f[t+32>>2]=0,n[t+40|0]=1,(e=f[t+16>>2])&&(_[t+20|0]&&CA(e),f[t+16>>2]=0),f[t+16>>2]=0,f[t+8>>2]=0,f[t+12>>2]=0,n[t+20|0]=1,0|t}function $i(t,e,i,r,a,o,h,d,g,y,p,R){var D=0,B=0,E=0,F=0,V=0;if(D=B=f[t+68>>2],(0|B)==f[t+72>>2]&&(D=B,!((0|B)>=(0|(E=B?B<<1:1))))){if(E?(V=dA(m(E,152)),D=f[t+68>>2]):D=B,(0|(F=D))>=1)for(D=0;J(D+V|0,f[t+76>>2]+D|0,152),D=D+152|0,F=F+-1|0;);(D=f[t+76>>2])&&(_[t+80|0]&&CA(D),f[t+76>>2]=0),f[t+76>>2]=V,f[t+72>>2]=E,n[t+80|0]=1,D=f[t+68>>2]}f[t+68>>2]=D+1,B=f[t+76>>2]+m(B,152)|0,f[B+140>>2]=a,function(t,e,i,r,n,a,o,h,d,g,y,p){var R,D,B,E=0,F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),Z=v(0),z=v(0),yt=0,pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0),Gt=v(0),Lt=v(0),wt=v(0),xt=v(0),Qt=0,Wt=v(0),Yt=v(0),Pt=v(0),Mt=v(0),Zt=v(0);f[e+148>>2]=n,f[e+144>>2]=r,f[e+96>>2]=0,f[e+100>>2]=0,xt=C[a+84>>2],B=f[a+84>>2],f[e+104>>2]=B,D=f[t+16>>2],t=f[240+(D+m(n,244)|0)>>2],R=f[240+(m(r,244)+D|0)>>2],f[e+132>>2]=0,E=e+16|0,R?(yt=f[i+4>>2],f[E>>2]=f[i>>2],f[E+4>>2]=yt,Qt=f[(yt=i+8|0)+4>>2],f[(E=E+8|0)>>2]=f[yt>>2],f[E+4>>2]=Qt,w=C[o+8>>2],Q=C[o>>2],W=C[o+4>>2],f[e+12>>2]=0,St=C[e+20>>2],pt=C[e+16>>2],Et=v(v(Q*St)-v(W*pt)),C[e+8>>2]=Et,Dt=C[e+24>>2],Q=v(v(w*pt)-v(Q*Dt)),C[e+4>>2]=Q,w=v(v(W*Dt)-v(w*St)),C[e>>2]=w,W=C[R+612>>2],V=C[R+364>>2],G=C[R+356>>2],F=C[R+360>>2],Ot=C[R+608>>2],Nt=C[R+348>>2],Ft=C[R+340>>2],Y=C[R+344>>2],Z=C[R+332>>2],Vt=C[R+328>>2],It=C[R+604>>2],z=C[R+324>>2],f[e+76>>2]=0,Z=v(It*v(v(v(w*z)+v(Q*Vt))+v(Et*Z))),C[e+64>>2]=Z,Vt=v(Ot*v(v(v(w*Ft)+v(Q*Y))+v(Et*Nt))),C[e+68>>2]=Vt,It=v(W*v(v(v(w*G)+v(Q*F))+v(Et*V))),C[e+72>>2]=It):(f[e+64>>2]=0,f[e+68>>2]=0,f[e>>2]=0,f[e+4>>2]=0,f[(yt=e+72|0)>>2]=0,f[yt+4>>2]=0,f[(yt=e+8|0)>>2]=0,f[yt+4>>2]=0,f[E>>2]=0,f[E+4>>2]=0,f[(E=e+24|0)>>2]=0,f[E+4>>2]=0),t?(V=C[i>>2],G=C[i+4>>2],F=C[i+8>>2],f[e+60>>2]=0,Ot=v(-F),C[e+56>>2]=Ot,Nt=v(-G),C[e+52>>2]=Nt,Ft=v(-V),C[e+48>>2]=Ft,Y=C[h+8>>2],Tt=C[h+4>>2],z=C[h>>2],f[e+44>>2]=0,W=v(v(Tt*V)-v(z*G)),C[e+40>>2]=W,V=v(v(z*F)-v(Y*V)),C[e+36>>2]=V,G=v(v(Y*G)-v(Tt*F)),C[e+32>>2]=G,Tt=C[t+332>>2],z=C[t+328>>2],Y=C[t+608>>2],Lt=C[t+348>>2],Gt=C[t+340>>2],wt=C[t+344>>2],F=C[t+612>>2],Wt=C[t+364>>2],Yt=C[t+356>>2],Pt=C[t+360>>2],Mt=C[t+604>>2],Zt=C[t+324>>2],f[e+92>>2]=0,F=v(F*v(v(v(G*Yt)+v(V*Pt))+v(W*Wt))),C[e+88>>2]=F,Y=v(Y*v(v(v(G*Gt)+v(V*wt))+v(W*Lt))),C[e+84>>2]=Y,Tt=v(Mt*v(v(v(G*Zt)+v(V*z))+v(W*Tt))),C[e+80>>2]=Tt):(f[e+80>>2]=0,f[e+84>>2]=0,f[e+32>>2]=0,f[e+36>>2]=0,f[(E=e+88|0)>>2]=0,f[E+4>>2]=0,f[(E=e+40|0)>>2]=0,f[E+4>>2]=0,f[(E=e+48|0)>>2]=0,f[E+4>>2]=0,f[(E=e+56|0)>>2]=0,f[E+4>>2]=0,W=v(0),V=v(0),G=v(0),Ot=v(0),Nt=v(0),Ft=v(0),F=v(0),Y=v(0)),E=e,Lt=d,R?(d=C[o+8>>2],z=C[o+4>>2],wt=v(v(v(Vt*d)-v(It*z))*C[i>>2]),Gt=It,It=C[o>>2],d=v(C[R+404>>2]+v(v(wt+v(v(v(Gt*It)-v(d*Z))*C[i+4>>2]))+v(v(v(z*Z)-v(Vt*It))*C[i+8>>2])))):d=v(0),It=d,t?(d=C[h+4>>2],Z=C[h+8>>2],Gt=v(v(v(d*F)-v(Z*Y))*C[i>>2]),z=v(Z*Tt),Z=C[h>>2],d=v(C[t+404>>2]+v(v(Gt+v(v(z-v(Z*F))*C[i+4>>2]))+v(v(v(Z*Y)-v(d*Tt))*C[i+8>>2])))):d=v(0),d=v(Lt/v(It+d)),C[E+108>>2]=d,R?(r=m(r,244)+D|0,St=v(v(v(v(C[r+176>>2]+C[r+208>>2])*pt)+v(v(C[r+180>>2]+C[r+212>>2])*St))+v(v(C[r+184>>2]+C[r+216>>2])*Dt)),F=C[r+192>>2],Dt=C[r+200>>2],pt=C[r+196>>2]):(F=v(0),St=v(v(v(pt*v(0))+v(St*v(0)))+v(Dt*v(0))),Dt=v(0),pt=v(0)),St=v(St+v(v(v(F*w)+v(pt*Q))+v(Dt*Et))),t?(t=m(n,244)+D|0,w=v(v(v(v(C[t+176>>2]+C[t+208>>2])*Ft)+v(v(C[t+180>>2]+C[t+212>>2])*Nt))+v(v(C[t+184>>2]+C[t+216>>2])*Ot)),pt=C[t+192>>2],Q=C[t+200>>2],Dt=C[t+196>>2]):(Q=v(0),w=v(v(v(Ft*v(0))+v(Nt*v(0)))+v(Ot*v(0))),pt=v(0),Dt=v(0)),Et=16&_[a+120|0]?v(d*v(v(-v(C[g+44>>2]*v(v(v(v(C[a+48>>2]-C[a+32>>2])*C[i>>2])+v(v(C[a+52>>2]-C[a+36>>2])*C[i+4>>2]))+v(v(C[a+56>>2]-C[a+40>>2])*C[i+8>>2]))))/C[g+12>>2])):v(0),f[e+128>>2]=0,f[e+124>>2]=B,C[e+116>>2]=p,C[e+112>>2]=v(d*v(y-v(St+v(w+v(v(v(pt*G)+v(Dt*V))+v(Q*W))))))+Et,C[e+120>>2]=-xt}(t,B,e,i,r,o,h,d,g,y,p,R)}function Af(t,e,i,r,a,o){var h=0,d=0,g=0,y=0,p=0;if(h=d=f[t+88>>2],(0|d)==f[t+92>>2]&&(h=d,!((0|d)>=(0|(g=d?d<<1:1))))){if(g?(p=dA(m(g,152)),h=f[t+88>>2]):h=d,(0|(y=h))>=1)for(h=0;J(h+p|0,f[t+96>>2]+h|0,152),h=h+152|0,y=y+-1|0;);(h=f[t+96>>2])&&(_[t+100|0]&&CA(h),f[t+96>>2]=0),f[t+96>>2]=p,f[t+92>>2]=g,n[t+100|0]=1,h=f[t+88>>2]}f[t+88>>2]=h+1,d=f[t+96>>2]+m(d,152)|0,f[d+140>>2]=a,function(t,e,i,r,n,a){var o,_,h=0,d=v(0),g=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=0,w=v(0),Q=0,W=0,Y=0,Z=0,z=v(0),yt=v(0),pt=v(0);f[e+48>>2]=-2147483648,f[e+52>>2]=-2147483648,f[e+16>>2]=0,f[e+20>>2]=0,f[(h=e+56|0)>>2]=-2147483648,f[h+4>>2]=0,f[(h=e+24|0)>>2]=0,f[h+4>>2]=0,C[e+104>>2]=a,f[e+96>>2]=0,f[e+100>>2]=0,o=f[t+16>>2],t=f[240+(o+m(r,244)|0)>>2],h=f[240+(m(n,244)+o|0)>>2],f[e+132>>2]=0,f[e+148>>2]=n,f[e+144>>2]=r,y=C[i>>2],p=C[i+4>>2],R=C[i+8>>2],f[e+12>>2]=0,d=v(-R),C[e+8>>2]=d,D=v(-p),C[e+4>>2]=D,g=v(-y),C[e>>2]=g,_=e,t?(s(v(v(v(v(C[t+356>>2]*g)+v(C[t+360>>2]*D))+v(C[t+364>>2]*d))*C[t+612>>2])),Q=c(0),s(v(v(v(v(C[t+340>>2]*g)+v(C[t+344>>2]*D))+v(C[t+348>>2]*d))*C[t+608>>2])),W=c(0),s(v(v(v(v(C[t+324>>2]*g)+v(C[t+328>>2]*D))+v(C[t+332>>2]*d))*C[t+604>>2])),G=c(0)):G=0,f[_+64>>2]=G,f[e+76>>2]=0,f[e+72>>2]=Q,f[e+68>>2]=W,y=C[i>>2],p=C[i+4>>2],R=C[i+8>>2],f[e+44>>2]=f[i+12>>2],C[e+40>>2]=R,C[e+36>>2]=p,C[e+32>>2]=y,i=0,h&&(s(v(v(v(v(y*C[h+356>>2])+v(p*C[h+360>>2]))+v(R*C[h+364>>2]))*C[h+612>>2])),Y=c(0),s(v(v(v(v(y*C[h+324>>2])+v(p*C[h+328>>2]))+v(R*C[h+332>>2]))*C[h+604>>2])),Z=c(0),s(v(v(v(v(y*C[h+340>>2])+v(p*C[h+344>>2]))+v(R*C[h+348>>2]))*C[h+608>>2])),i=c(0)),f[e+80>>2]=Z,f[e+92>>2]=0,f[e+88>>2]=Y,f[e+84>>2]=i,i=e,t?(E=v(v(v(C[t+356>>2]*g)+v(C[t+360>>2]*D))+v(C[t+364>>2]*d)),B=v(v(v(C[t+340>>2]*g)+v(C[t+344>>2]*D))+v(C[t+348>>2]*d)),w=v(v(v(C[t+324>>2]*g)+v(C[t+328>>2]*D))+v(C[t+332>>2]*d))):w=v(0),E=v(v(v(v(w*g)+v(B*D))+v(E*d))+v(0)),h?(F=v(v(v(y*C[h+356>>2])+v(p*C[h+360>>2]))+v(R*C[h+364>>2])),z=v(v(v(y*C[h+340>>2])+v(p*C[h+344>>2]))+v(R*C[h+348>>2])),B=v(v(v(C[h+324>>2]*y)+v(C[h+328>>2]*p))+v(C[h+332>>2]*R))):B=v(0),F=v(v(1)/v(E+v(v(v(B*y)+v(z*p))+v(F*R)))),C[i+108>>2]=F,B=v(0),E=v(0),t&&(t=m(r,244)+o|0,V=v(v(v(v(C[t+176>>2]+C[t+208>>2])*v(0))+v(v(C[t+180>>2]+C[t+212>>2])*v(0)))+v(v(C[t+184>>2]+C[t+216>>2])*v(0))),B=C[t+196>>2],yt=C[t+200>>2],E=C[t+192>>2]),D=v(V+v(v(yt*d)+v(v(B*D)+v(E*g)))),h?(t=m(n,244)+o|0,d=v(v(v(v(C[t+176>>2]+C[t+208>>2])*v(-0))+v(v(C[t+180>>2]+C[t+212>>2])*v(-0)))+v(v(C[t+184>>2]+C[t+216>>2])*v(-0))),V=C[t+192>>2],pt=C[t+200>>2],g=C[t+196>>2]):(d=v(-0),V=v(0),g=v(0)),C[e+124>>2]=a,C[e+116>>2]=0,C[e+120>>2]=-a,C[e+112>>2]=F*v(v(0)-v(D+v(d+v(v(R*pt)+v(v(p*g)+v(y*V))))))}(t,d,e,i,r,o)}function ef(t,e,i){var r,n=0;return Z=r=Z-256|0,(0|(n=f[e+212>>2]))>-1||(2&(n=f[e+252>>2])&&(2&_[(n=n<<30>>31&e)+204|0]||C[n+404>>2]!=v(0))?(n=f[t+8>>2],X(r+8|0,0,244),function(t,e,i){var r=0,n=0,a=0,o=v(0),_=v(0),h=v(0),d=v(0),g=0,m=v(0),y=v(0),p=v(0),R=v(0),D=v(0);e=e?f[e+252>>2]<<30>>31&e:0,f[t+64>>2]=0,f[t+68>>2]=0,f[t+144>>2]=0,f[t+148>>2]=0,f[(r=t+88|0)>>2]=0,f[r+4>>2]=0,f[(r=t+80|0)>>2]=0,f[r+4>>2]=0,f[(r=t+72|0)>>2]=0,f[r+4>>2]=0,f[(r=t+152|0)>>2]=0,f[r+4>>2]=0,f[(r=t+160|0)>>2]=0,f[r+4>>2]=0,f[(r=t+168|0)>>2]=0,f[r+4>>2]=0,e?(r=f[e+8>>2],f[t>>2]=f[e+4>>2],f[t+4>>2]=r,n=f[(r=e+12|0)+4>>2],f[(a=t+8|0)>>2]=f[r>>2],f[a+4>>2]=n,n=f[(r=e+28|0)+4>>2],f[(a=t+24|0)>>2]=f[r>>2],f[a+4>>2]=n,n=f[(r=e+20|0)+4>>2],f[t+16>>2]=f[r>>2],f[t+20>>2]=n,n=f[(r=e+44|0)+4>>2],f[(a=t+40|0)>>2]=f[r>>2],f[a+4>>2]=n,n=f[(r=e+36|0)+4>>2],f[t+32>>2]=f[r>>2],f[t+36>>2]=n,n=f[(r=e+52|0)+4>>2],f[t+48>>2]=f[r>>2],f[t+52>>2]=n,n=f[(r=e+60|0)+4>>2],f[(a=t+56|0)>>2]=f[r>>2],f[a+4>>2]=n,_=C[e+412>>2],h=C[(r=e+416|0)>>2],d=C[e+408>>2],o=C[e+404>>2],f[t+140>>2]=0,C[t+136>>2]=o*h,C[t+132>>2]=o*_,C[t+128>>2]=o*d,f[t+240>>2]=e,a=f[(n=e+612|0)+4>>2],f[(g=t+104|0)>>2]=f[n>>2],f[g+4>>2]=a,n=f[e+608>>2],f[t+96>>2]=f[e+604>>2],f[t+100>>2]=n,n=f[r+4>>2],f[(a=t+120|0)>>2]=f[r>>2],f[a+4>>2]=n,r=f[e+412>>2],f[t+112>>2]=f[e+408>>2],f[t+116>>2]=r,n=f[(r=e+380|0)+4>>2],f[(a=t+184|0)>>2]=f[r>>2],f[a+4>>2]=n,r=f[e+376>>2],f[t+176>>2]=f[e+372>>2],f[t+180>>2]=r,r=f[e+392>>2],f[t+192>>2]=f[e+388>>2],f[t+196>>2]=r,n=f[(r=e+396|0)+4>>2],f[(a=t+200|0)>>2]=f[r>>2],f[a+4>>2]=n,_=C[e+476>>2],h=C[e+480>>2],d=C[e+472>>2],o=C[e+404>>2],f[t+220>>2]=0,C[t+216>>2]=v(o*h)*i,C[t+212>>2]=v(o*_)*i,C[t+208>>2]=v(o*d)*i,d=C[e+340>>2],m=C[e+356>>2],y=C[e+328>>2],p=C[e+344>>2],R=C[e+360>>2],D=C[e+324>>2],o=C[e+488>>2],_=C[e+492>>2],h=C[e+496>>2],C[t+232>>2]=v(v(v(o*C[e+332>>2])+v(_*C[e+348>>2]))+v(h*C[e+364>>2]))*i,C[t+228>>2]=v(v(v(o*y)+v(_*p))+v(h*R))*i,C[t+224>>2]=v(v(v(D*o)+v(d*_))+v(m*h))*i):(f[t+4>>2]=0,f[t+8>>2]=0,f[t>>2]=1065353216,f[t+32>>2]=0,f[t+36>>2]=0,f[t+240>>2]=0,f[t+128>>2]=0,f[t+132>>2]=0,f[t+112>>2]=1065353216,f[t+116>>2]=1065353216,f[t+96>>2]=1065353216,f[t+100>>2]=1065353216,f[t+176>>2]=0,f[t+180>>2]=0,f[(e=t+12|0)>>2]=0,f[e+4>>2]=0,f[(e=t+24|0)>>2]=0,f[e+4>>2]=0,f[t+20>>2]=1065353216,f[(e=t+44|0)>>2]=0,f[e+4>>2]=0,f[t+40>>2]=1065353216,f[(e=t+52|0)>>2]=0,f[e+4>>2]=0,f[t+60>>2]=0,f[(e=t+136|0)>>2]=0,f[e+4>>2]=0,f[(e=t+120|0)>>2]=1065353216,f[e+4>>2]=0,f[(e=t+104|0)>>2]=1065353216,f[e+4>>2]=0,f[t+232>>2]=0,f[(e=t+224|0)>>2]=0,f[e+4>>2]=0,f[(e=t+216|0)>>2]=0,f[e+4>>2]=0,f[(e=t+208|0)>>2]=0,f[e+4>>2]=0,f[(e=t+200|0)>>2]=0,f[e+4>>2]=0,f[(e=t+192|0)>>2]=0,f[e+4>>2]=0,f[(e=t+184|0)>>2]=0,f[e+4>>2]=0),f[t+236>>2]=0}(rf(t+4|0,r+8|0),e,i),f[e+212>>2]=n):(0|(n=f[t+188>>2]))>-1||(f[t+188>>2]=f[t+8>>2],X(r+8|0,0,244),e=rf(t+4|0,r+8|0),f[(n=e+88|0)>>2]=0,f[n+4>>2]=0,f[(n=e+80|0)>>2]=0,f[n+4>>2]=0,f[(n=e+72|0)>>2]=0,f[n+4>>2]=0,f[e+64>>2]=0,f[e+68>>2]=0,f[e+144>>2]=0,f[e+148>>2]=0,f[(n=e+152|0)>>2]=0,f[n+4>>2]=0,f[(n=e+160|0)>>2]=0,f[n+4>>2]=0,f[(n=e+168|0)>>2]=0,f[n+4>>2]=0,f[e+4>>2]=0,f[e+8>>2]=0,f[e>>2]=1065353216,f[(n=e+12|0)>>2]=0,f[n+4>>2]=0,f[(n=e+24|0)>>2]=0,f[n+4>>2]=0,f[e+20>>2]=1065353216,f[e+32>>2]=0,f[e+36>>2]=0,f[(n=e+44|0)>>2]=0,f[n+4>>2]=0,f[e+40>>2]=1065353216,f[(n=e+52|0)>>2]=0,f[n+4>>2]=0,f[e+60>>2]=0,f[(n=e+136|0)>>2]=0,f[n+4>>2]=0,f[e+128>>2]=0,f[e+132>>2]=0,f[(n=e+120|0)>>2]=1065353216,f[n+4>>2]=0,f[e+112>>2]=1065353216,f[e+116>>2]=1065353216,f[(n=e+104|0)>>2]=1065353216,f[n+4>>2]=0,f[e+96>>2]=1065353216,f[e+100>>2]=1065353216,f[(n=e+232|0)>>2]=0,f[n+4>>2]=0,f[(n=e+224|0)>>2]=0,f[n+4>>2]=0,f[(n=e+216|0)>>2]=0,f[n+4>>2]=0,f[(n=e+208|0)>>2]=0,f[n+4>>2]=0,f[(n=e+200|0)>>2]=0,f[n+4>>2]=0,f[(n=e+192|0)>>2]=0,f[n+4>>2]=0,f[(n=e+184|0)>>2]=0,f[n+4>>2]=0,f[e+176>>2]=0,f[e+180>>2]=0,f[e+240>>2]=0,n=f[t+188>>2])),Z=r+256|0,n}function rf(t,e){var i=0,r=0,a=0,o=0,h=0,d=0,C=0,g=0,v=0,y=0,p=0,R=0;if(d=a=f[t+4>>2],(0|a)==f[t+8>>2]&&(d=a,!((0|a)>=(0|(y=a?a<<1:1))))){if(y?(R=dA(m(y,244)),d=f[t+4>>2]):d=a,(0|d)>=1)for(i=64;C=f[t+12>>2]+i|0,v=f[(o=C+-64|0)+4>>2],f[(r=(h=i+R|0)+-64|0)>>2]=f[o>>2],f[r+4>>2]=v,g=f[(o=o+8|0)+4>>2],f[(r=r+8|0)>>2]=f[o>>2],f[r+4>>2]=g,p=f[(v=(r=C+-48|0)+8|0)+4>>2],f[(g=(o=h+-48|0)+8|0)>>2]=f[v>>2],f[g+4>>2]=p,g=f[r+4>>2],f[o>>2]=f[r>>2],f[o+4>>2]=g,p=f[(v=(r=C+-32|0)+8|0)+4>>2],f[(g=(o=h+-32|0)+8|0)>>2]=f[v>>2],f[g+4>>2]=p,g=f[r+4>>2],f[o>>2]=f[r>>2],f[o+4>>2]=g,v=f[(o=C+-16|0)+4>>2],f[(r=h+-16|0)>>2]=f[o>>2],f[r+4>>2]=v,g=f[(o=o+8|0)+4>>2],f[(r=r+8|0)>>2]=f[o>>2],f[r+4>>2]=g,J(h,C,180),i=i+244|0,d=d+-1|0;);(d=f[t+12>>2])&&(_[t+16|0]&&CA(d),f[t+12>>2]=0),f[t+12>>2]=R,n[t+16|0]=1,f[t+8>>2]=y,d=f[t+4>>2]}return f[t+4>>2]=d+1,C=f[(h=e+8|0)+4>>2],a=(d=m(a,244))+f[t+12>>2]|0,f[(i=a+8|0)>>2]=f[h>>2],f[i+4>>2]=C,i=f[e+4>>2],f[a>>2]=f[e>>2],f[a+4>>2]=i,C=f[(h=e+24|0)+4>>2],f[(i=a+24|0)>>2]=f[h>>2],f[i+4>>2]=C,i=f[e+20>>2],f[a+16>>2]=f[e+16>>2],f[a+20>>2]=i,i=f[e+36>>2],f[a+32>>2]=f[e+32>>2],f[a+36>>2]=i,C=f[(h=e+40|0)+4>>2],f[(i=a+40|0)>>2]=f[h>>2],f[i+4>>2]=C,i=f[e+52>>2],f[a+48>>2]=f[e+48>>2],f[a+52>>2]=i,C=f[(h=e+56|0)+4>>2],f[(i=a+56|0)>>2]=f[h>>2],f[i+4>>2]=C,J(a- -64|0,e- -64|0,180),d+f[t+12>>2]|0}function ff(t,e,i,r,n,a,o,h,d){var g,p,R,B,E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=0,Z=v(0),z=v(0),yt=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=0,Gt=v(0);f[o>>2]=f[a+28>>2],R=(p=f[t+16>>2])+m(r,244)|0,t=f[R+240>>2],B=m(i,244)+p|0,g=f[B+240>>2],pt=C[a+12>>2],Ft=C[a+36>>2],Q=C[a+40>>2];t:if(6&(Y=f[n+120>>2])){if(Q=2&Y?C[n+144>>2]:Q,!(4&Y))break t;Ft=C[n+148>>2]}else 8&Y&&(F=v(pt*C[n+144>>2]),E=v(D(v(F+C[n+148>>2]),v(1.1920928955078125e-7))),Ft=v(F/E),Q=v(v(1)/E));E=C[n+68>>2],F=C[h>>2],G=C[h+4>>2],V=C[n+64>>2],Z=v(v(E*F)-v(G*V)),w=C[h+8>>2],z=v(w*V),V=C[n+72>>2],W=v(z-v(V*F)),yt=v(v(G*V)-v(w*E)),w=v(0),E=v(0),F=v(0),g&&(It=v(v(v(v(yt*C[g+356>>2])+v(W*C[g+360>>2]))+v(Z*C[g+364>>2]))*C[g+612>>2]),F=v(v(v(v(yt*C[g+340>>2])+v(W*C[g+344>>2]))+v(Z*C[g+348>>2]))*C[g+608>>2]),E=v(v(v(v(yt*C[g+324>>2])+v(W*C[g+328>>2]))+v(Z*C[g+332>>2]))*C[g+604>>2])),C[e+64>>2]=E,f[e+76>>2]=0,C[e+72>>2]=It,C[e+68>>2]=F,G=C[n+68>>2],V=C[d>>2],z=C[d+4>>2],Dt=C[n+64>>2],Tt=v(v(G*V)-v(z*Dt)),Ot=C[d+8>>2],Et=C[n+72>>2],Dt=v(v(Ot*Dt)-v(Et*V)),Et=v(v(z*Et)-v(Ot*G)),G=v(0),V=v(0),Ot=v(v(1)/pt),t&&(w=v(-Et),V=v(v(v(v(C[t+356>>2]*w)-v(C[t+360>>2]*Dt))-v(C[t+364>>2]*Tt))*C[t+612>>2]),G=v(v(v(v(C[t+340>>2]*w)-v(C[t+344>>2]*Dt))-v(C[t+348>>2]*Tt))*C[t+608>>2]),w=v(v(v(v(C[t+324>>2]*w)-v(C[t+328>>2]*Dt))-v(C[t+332>>2]*Tt))*C[t+604>>2])),C[e+80>>2]=w,f[e+92>>2]=0,C[e+88>>2]=V,C[e+84>>2]=G,pt=v(0),z=v(0),g&&(z=C[h+8>>2],Nt=C[h+4>>2],Gt=v(v(v(F*z)-v(It*Nt))*C[n+64>>2]),St=It,It=C[h>>2],z=v(C[g+404>>2]+v(v(Gt+v(v(v(St*It)-v(z*E))*C[n+68>>2]))+v(v(v(Nt*E)-v(F*It))*C[n+72>>2])))),Y=e,Nt=C[o>>2],St=It=v(Ot*Q),t&&(E=C[d+4>>2],F=C[d+8>>2],pt=v(v(v(E*V)-v(F*G))*C[n+64>>2]),Q=v(F*w),F=C[d>>2],pt=v(C[t+404>>2]+v(v(pt+v(v(Q-v(F*V))*C[n+68>>2]))+v(v(v(F*G)-v(E*w))*C[n+72>>2])))),C[Y+108>>2]=Nt/v(St+v(z+pt)),o=e+16|0,g?(Vt=f[(Y=n- -64|0)+4>>2],f[o>>2]=f[Y>>2],f[o+4>>2]=Vt,Vt=f[(Y=Y+8|0)+4>>2],f[(o=o+8|0)>>2]=f[Y>>2],f[o+4>>2]=Vt,f[e+12>>2]=0,C[e+8>>2]=Z,C[e+4>>2]=W,C[e>>2]=yt):(f[e>>2]=0,f[e+4>>2]=0,f[(Y=e+24|0)>>2]=0,f[Y+4>>2]=0,f[o>>2]=0,f[o+4>>2]=0,f[(o=e+8|0)>>2]=0,f[o+4>>2]=0),t?(E=C[n+64>>2],F=C[n+68>>2],G=C[n+72>>2],f[e+60>>2]=0,f[e+44>>2]=0,C[e+40>>2]=-Tt,C[e+36>>2]=-Dt,C[e+32>>2]=-Et,C[e+56>>2]=-G,C[e+52>>2]=-F,C[e+48>>2]=-E):(f[e+32>>2]=0,f[e+36>>2]=0,f[(o=e+56|0)>>2]=0,f[o+4>>2]=0,f[(o=e+48|0)>>2]=0,f[o+4>>2]=0,f[(o=e+40|0)>>2]=0,f[o+4>>2]=0),pt=C[a+64>>2],z=C[n+80>>2],w=v(0),E=v(0),F=v(0),G=v(0),g&&(E=C[h+4>>2],F=C[g+388>>2],V=C[g+392>>2],Q=C[h>>2],G=v(v(v(E*F)-v(V*Q))+C[g+380>>2]),Z=C[g+396>>2],St=v(Z*Q),Q=C[h+8>>2],F=v(C[g+376>>2]+v(St-v(Q*F))),E=v(v(v(V*Q)-v(Z*E))+C[g+372>>2])),V=v(0),Z=v(0),t&&(Q=C[d+4>>2],V=C[t+388>>2],w=C[t+392>>2],W=C[d>>2],Z=v(v(v(Q*V)-v(w*W))+C[t+380>>2]),yt=C[t+396>>2],St=v(yt*W),W=C[d+8>>2],V=v(C[t+376>>2]+v(St-v(W*V))),w=v(v(v(w*W)-v(yt*Q))+C[t+372>>2])),o=R+240|0,h=B+240|0,Q=C[n+72>>2],W=C[n+64>>2],yt=C[n+68>>2],f[e+104>>2]=f[n+84>>2],E=v(v(v(W*v(E-w))+v(yt*v(F-V)))+v(Q*v(G-Z))),Q=v(y(E))>2]?v(0):v(-v(E*C[n+96>>2]));t:if(4&_[a+72|0]){if(E=v(C[n+124>>2]*C[a+68>>2]),C[e+100>>2]=E,!g|!f[h>>2]||(F=C[g+416>>2],G=C[e+24>>2],V=C[g+412>>2],w=C[e+20>>2],n=m(i,244)+p|0,C[n+64>>2]=v(C[n+112>>2]*v(E*v(v(C[e+16>>2]*C[n+128>>2])*C[g+408>>2])))+C[n+64>>2],C[(d=n+68|0)>>2]=v(v(E*v(V*v(w*C[n+132>>2])))*C[n+116>>2])+C[d>>2],C[(d=n+72|0)>>2]=v(v(E*v(F*v(G*C[n+136>>2])))*C[n+120>>2])+C[d>>2],F=C[e+72>>2],G=C[e+68>>2],C[n+80>>2]=v(v(E*C[n+96>>2])*C[e+64>>2])+C[n+80>>2],V=C[n+104>>2],C[(d=n+84|0)>>2]=v(G*v(E*C[n+100>>2]))+C[d>>2],C[(n=n+88|0)>>2]=v(F*v(E*V))+C[n>>2]),!t|!f[o>>2])break t;F=C[t+416>>2],G=C[e+56>>2],V=C[t+412>>2],w=C[e+52>>2],Z=C[e+88>>2],W=C[e+84>>2],yt=C[e+80>>2],n=m(r,244)+p|0,E=C[e+100>>2],C[n+64>>2]=v(C[n+112>>2]*v(E*v(v(C[e+48>>2]*C[n+128>>2])*C[t+408>>2])))+C[n+64>>2],C[(t=n+68|0)>>2]=v(v(E*v(V*v(w*C[n+132>>2])))*C[n+116>>2])+C[t>>2],C[(t=n+72|0)>>2]=v(v(E*v(F*v(G*C[n+136>>2])))*C[n+120>>2])+C[t>>2],E=v(-E),C[n+80>>2]=C[n+80>>2]-v(yt*v(C[n+96>>2]*E)),F=C[n+104>>2],C[(t=n+84|0)>>2]=C[t>>2]-v(W*v(C[n+100>>2]*E)),C[(t=n+88|0)>>2]=C[t>>2]-v(Z*v(F*E))}else f[e+100>>2]=0;n=Q<=v(0),f[e+96>>2]=0,F=v(0),G=v(0),V=v(0),Z=v(0),W=v(0),yt=v(0),Tt=v(0),f[h>>2]&&(t=m(i,244)+p|0,Tt=C[t+224>>2],Z=C[t+208>>2],W=C[t+232>>2],yt=C[t+228>>2],V=C[t+212>>2],G=C[t+216>>2]),w=v(z+pt),Et=n?v(0):Q,E=v(0),Dt=v(0),Q=v(0),pt=v(0),z=v(0),f[o>>2]&&(t=m(r,244)+p|0,z=C[t+224>>2],F=C[t+208>>2],Q=C[t+232>>2],pt=C[t+228>>2],Dt=C[t+216>>2],E=C[t+212>>2]),t=m(i,244)+p|0,St=v(v(v(v(v(Z+C[t+176>>2])*C[e+16>>2])+v(v(V+C[t+180>>2])*C[e+20>>2]))+v(v(G+C[t+184>>2])*C[e+24>>2]))+v(v(v(v(Tt+C[t+192>>2])*C[e>>2])+v(v(yt+C[t+196>>2])*C[e+4>>2]))+v(v(W+C[t+200>>2])*C[e+8>>2]))),t=m(r,244)+p|0,E=v(Et-v(St+v(v(v(v(v(F+C[t+176>>2])*C[e+48>>2])+v(v(E+C[t+180>>2])*C[e+52>>2]))+v(v(Dt+C[t+184>>2])*C[e+56>>2]))+v(v(v(v(z+C[t+192>>2])*C[e+32>>2])+v(v(pt+C[t+196>>2])*C[e+36>>2]))+v(v(Q+C[t+200>>2])*C[e+40>>2]))))),F=v(0),w>v(0)?E=v(E-v(Ot*w)):F=v(-v(Ot*v(Ft*w))),G=C[e+108>>2],E=v(E*G),F=v(F*G),w>C[a+56>>2]^1&&f[a+52>>2]||(E=v(F+E),F=v(0)),C[e+128>>2]=F,C[e+112>>2]=E,f[e+120>>2]=0,f[e+124>>2]=1343554297,C[e+116>>2]=It*G}function tf(t,e,i,r,n,a){var o,_,h,d,g,y,p,R=v(0),D=v(0),B=0,E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0);h=f[t+16>>2],o=f[240+(h+m(r,244)|0)>>2],_=f[240+(m(i,244)+h|0)>>2],d=f[t+76>>2],g=f[e+140>>2];t:if(p=4&(y=f[a+72>>2])){if(e=m(g,152)+d|0,R=v(C[n+128>>2]*C[a+68>>2]),C[e+100>>2]=R,_&&(E=C[_+416>>2],F=C[e+24>>2],V=C[_+412>>2],G=C[e+20>>2],t=m(i,244)+h|0,D=C[_+404>>2],C[t+64>>2]=v(v(R*v(v(D*C[e+16>>2])*C[_+408>>2]))*C[t+112>>2])+C[t+64>>2],C[(B=t+68|0)>>2]=v(v(R*v(V*v(D*G)))*C[t+116>>2])+C[B>>2],C[(B=t+72|0)>>2]=v(v(R*v(E*v(D*F)))*C[t+120>>2])+C[B>>2],D=C[e+72>>2],E=C[e+68>>2],C[t+80>>2]=v(v(R*C[t+96>>2])*C[e+64>>2])+C[t+80>>2],F=C[t+104>>2],C[(B=t+84|0)>>2]=v(E*v(R*C[t+100>>2]))+C[B>>2],C[(t=t+88|0)>>2]=v(D*v(R*F))+C[t>>2]),!o)break t;B=m(g,152)+d|0,E=C[B+88>>2],F=C[B+84>>2],V=C[B+80>>2],G=C[o+416>>2],w=C[B+56>>2],Q=C[o+412>>2],W=C[B+52>>2],t=m(r,244)+h|0,D=C[o+404>>2],R=C[e+100>>2],C[t+64>>2]=v(v(v(v(C[B+48>>2]*D)*C[o+408>>2])*R)*C[t+112>>2])+C[t+64>>2],C[(e=t+68|0)>>2]=v(v(R*v(Q*v(W*D)))*C[t+116>>2])+C[e>>2],C[(e=t+72|0)>>2]=v(v(R*v(G*v(w*D)))*C[t+120>>2])+C[e>>2],C[t+80>>2]=C[t+80>>2]+v(V*v(R*C[t+96>>2])),D=C[t+104>>2],C[(e=t+84|0)>>2]=C[e>>2]+v(F*v(R*C[t+100>>2])),C[(t=t+88|0)>>2]=C[t>>2]+v(E*v(D*R))}else f[100+(m(g,152)+d|0)>>2]=0;t:if(16&y){if(B=g+1|0,p){if(e=m(B,152)+d|0,R=v(C[n+132>>2]*C[a+68>>2]),C[e+100>>2]=R,_&&(E=C[e+24>>2],F=C[e+20>>2],t=m(i,244)+h|0,D=C[_+404>>2],C[t+64>>2]=v(v(R*v(D*C[e+16>>2]))*C[t+112>>2])+C[t+64>>2],C[(i=t+68|0)>>2]=v(v(R*v(D*F))*C[t+116>>2])+C[i>>2],C[(i=t+72|0)>>2]=v(v(R*v(D*E))*C[t+120>>2])+C[i>>2],D=C[e+72>>2],E=C[e+68>>2],C[t+80>>2]=v(v(R*C[t+96>>2])*C[e+64>>2])+C[t+80>>2],F=C[t+104>>2],C[(i=t+84|0)>>2]=v(E*v(R*C[t+100>>2]))+C[i>>2],C[(t=t+88|0)>>2]=v(D*v(R*F))+C[t>>2]),!o)break t;return i=m(B,152)+d|0,E=C[i+88>>2],F=C[i+84>>2],V=C[i+56>>2],G=C[i+52>>2],w=C[i+48>>2],D=C[o+404>>2],t=m(r,244)+h|0,R=C[e+100>>2],C[t+80>>2]=C[t+80>>2]+v(C[i+80>>2]*v(C[t+96>>2]*R)),C[t+64>>2]=v(v(R*v(w*D))*C[t+112>>2])+C[t+64>>2],C[(e=t+68|0)>>2]=v(v(R*v(G*D))*C[t+116>>2])+C[e>>2],C[(e=t+72|0)>>2]=v(v(R*v(V*D))*C[t+120>>2])+C[e>>2],D=C[t+104>>2],C[(e=t+84|0)>>2]=C[e>>2]+v(F*v(R*C[t+100>>2])),void(C[(t=t+88|0)>>2]=C[t>>2]+v(E*v(D*R)))}f[100+(m(B,152)+d|0)>>2]=0}}function nf(t,e,i){var r,a,o,h,d,g=v(0),p=v(0),R=v(0),D=v(0),B=v(0),F=v(0),V=v(0),G=v(0),w=0,Q=v(0),W=v(0),Y=0,z=v(0),yt=0,pt=0,Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=0,Nt=0,Ft=v(0),Vt=0,Gt=v(0),Lt=v(0),wt=v(0),xt=v(0),Qt=v(0),Wt=v(0),Yt=v(0),Pt=0,Mt=0,Zt=0,Ut=0,Xt=v(0),Jt=0,jt=0,zt=0,Ht=0,Kt=0,qt=0,$t=0,bi=0,di=0,yi=0,Ii=0,Bi=0,BA=0,gr=0,tn=0,en=0,An=0,rn=0,nn=0,an=0,on=0,sn=0,ln=0,fn=0,cn=0,bn=0,_n=0,un=0,hn=v(0);if(Z=o=Z-80|0,r=f[e+776>>2],h=ef(t,a=f[e+772>>2],C[i+12>>2]),d=ef(t,r,C[i+12>>2]),w=(pt=f[t+16>>2])+m(h,244)|0,g=C[w+128>>2],V=v(g*g),g=C[w+132>>2],V=v(V+v(g*g)),g=C[w+136>>2],!(v(V+v(g*g))>2],V=v(g*g),g=C[w+132>>2],V=v(V+v(g*g)),g=C[w+136>>2],v(V+v(g*g))>2],(0|Y)<1)))for(zt=(w=pt+m(d,244)|0)+232|0,Ht=w+200|0,Kt=w+228|0,qt=w+196|0,$t=w+224|0,bi=w+192|0,di=w+216|0,yi=w+184|0,Ii=w+212|0,Bi=w+180|0,BA=w+208|0,gr=w+176|0,tn=w+240|0,en=(w=pt+m(h,244)|0)+232|0,An=w+200|0,rn=w+228|0,nn=w+196|0,an=w+224|0,on=w+192|0,sn=w+216|0,ln=w+184|0,fn=w+212|0,cn=w+180|0,bn=w+208|0,_n=w+176|0,un=w+240|0;;){if(yt=m(Jt,192)+e|0,C[yt+84>>2]<=C[e+788>>2]){if(Mt=yt+4|0,Y=w=f[t+28>>2],(0|w)==f[t+32>>2]&&(Y=w,!((0|w)>=(0|(Ot=w?w<<1:1))))){if(Ot?(Nt=dA(m(Ot,152)),pt=f[t+28>>2]):(Nt=0,pt=w),(0|pt)>=1)for(Y=0;J(Y+Nt|0,f[t+36>>2]+Y|0,152),Y=Y+152|0,pt=pt+-1|0;);(Y=f[t+36>>2])&&(_[t+40|0]&&CA(Y),f[t+36>>2]=0),f[t+36>>2]=Nt,n[t+40|0]=1,f[t+32>>2]=Ot,Y=f[t+28>>2]}f[t+28>>2]=Y+1,Ut=f[t+36>>2]+m(w,152)|0,f[Ut+132>>2]=Mt,f[Ut+148>>2]=d,f[Ut+144>>2]=h,f[o+76>>2]=0,g=v(C[yt+60>>2]-C[a+60>>2]),C[o+72>>2]=g,p=v(C[yt+56>>2]-C[a+56>>2]),C[o+68>>2]=p,R=v(C[yt+52>>2]-C[a+52>>2]),C[o+64>>2]=R,F=C[yt+36>>2],B=C[yt+40>>2],D=C[yt+44>>2],G=C[r+52>>2],Q=C[r+56>>2],V=C[r+60>>2],f[o+60>>2]=0,D=v(D-V),C[o+56>>2]=D,B=v(B-Q),C[o+52>>2]=B,F=v(F-G),C[o+48>>2]=F,V=v(0),z=v(0),Dt=v(0),W=v(0),f[un>>2]&&(G=v(C[on>>2]+C[an>>2]),Q=v(C[nn>>2]+C[rn>>2]),W=v(v(C[ln>>2]+C[sn>>2])+v(v(p*G)-v(R*Q))),z=R,R=v(C[An>>2]+C[en>>2]),Dt=v(v(C[cn>>2]+C[fn>>2])+v(v(z*R)-v(g*G))),z=v(v(C[_n>>2]+C[bn>>2])+v(v(g*Q)-v(p*R)))),Ft=v(0),Et=v(0),f[tn>>2]&&(g=v(C[bi>>2]+C[$t>>2]),p=v(C[qt>>2]+C[Kt>>2]),Et=v(v(C[yi>>2]+C[di>>2])+v(v(B*g)-v(F*p))),R=v(C[Ht>>2]+C[zt>>2]),Ft=v(v(C[Bi>>2]+C[Ii>>2])+v(v(F*R)-v(D*g))),V=v(v(C[gr>>2]+C[BA>>2])+v(v(D*p)-v(B*R)))),Tt=C[(Pt=yt+76|0)>>2],Xt=C[(Nt=yt+68|0)>>2],hn=C[(Vt=yt+72|0)>>2],ff(t,Ut,h,d,Mt,i,o+44|0,o- -64|0,o+48|0),f[Ut+140>>2]=f[t+68>>2],C[(Y=yt+92|0)>>2]>v(0)&&(Af(t,Nt,h,d,w,C[yt+96>>2]),R=C[Pt>>2],v(y(R))>v(.7071067690849304)?(f[o+24>>2]=0,g=C[Vt>>2],D=v(v(R*R)+v(g*g)),p=v(v(1)/v(E(D))),g=v(g*p),C[o+32>>2]=g,B=v(D*p),C[o+8>>2]=B,p=v(-v(R*p)),C[o+28>>2]=p,R=C[Nt>>2],F=v(-v(R*g)),C[o+12>>2]=F,G=v(R*p),D=v(0)):(f[o+32>>2]=0,p=C[Nt>>2],D=C[Vt>>2],G=v(v(p*p)+v(D*D)),g=v(v(1)/v(E(G))),p=v(p*g),C[o+28>>2]=p,D=v(-v(D*g)),C[o+24>>2]=D,F=v(R*D),C[o+12>>2]=F,B=v(-v(R*p)),C[o+8>>2]=B,G=v(G*g),g=v(0)),Q=v(v(1)/v(E(v(v(v(D*D)+v(p*p))+v(g*g))))),g=v(g*Q),C[o+32>>2]=g,R=v(p*Q),C[o+28>>2]=R,D=v(D*Q),C[o+24>>2]=D,p=G,G=v(v(1)/v(E(v(v(G*G)+v(v(B*B)+v(F*F)))))),p=v(p*G),C[o+16>>2]=p,F=v(F*G),C[o+12>>2]=F,B=v(B*G),C[o+8>>2]=B,(pt=2&f[a+180>>2])&&(f[o+36>>2]=0,Gt=C[a+4>>2],Lt=C[a+20>>2],wt=C[a+36>>2],G=v(v(v(v(D*Gt)+v(R*Lt))+v(g*wt))*C[a+164>>2]),xt=C[a+8>>2],Qt=C[a+24>>2],Wt=C[a+40>>2],Q=v(v(v(v(D*xt)+v(R*Qt))+v(g*Wt))*C[a+168>>2]),Yt=C[a+12>>2],It=R,R=C[a+28>>2],St=g,g=C[a+44>>2],D=v(v(v(v(D*Yt)+v(It*R))+v(St*g))*C[a+172>>2]),g=v(v(v(wt*G)+v(Wt*Q))+v(g*D)),C[o+32>>2]=g,R=v(v(v(Lt*G)+v(Qt*Q))+v(R*D)),C[o+28>>2]=R,D=v(v(v(Gt*G)+v(xt*Q))+v(Yt*D)),C[o+24>>2]=D),(Ot=2&f[r+180>>2])&&(f[o+36>>2]=0,Gt=C[r+4>>2],Lt=C[r+20>>2],wt=C[r+36>>2],G=v(v(v(v(Gt*D)+v(Lt*R))+v(wt*g))*C[r+164>>2]),xt=C[r+8>>2],Qt=C[r+24>>2],Wt=C[r+40>>2],Q=v(v(v(v(D*xt)+v(R*Qt))+v(g*Wt))*C[r+168>>2]),Yt=C[r+12>>2],It=R,R=C[r+28>>2],St=g,g=C[r+44>>2],D=v(v(v(v(D*Yt)+v(It*R))+v(St*g))*C[r+172>>2]),g=v(v(v(wt*G)+v(Wt*Q))+v(g*D)),C[o+32>>2]=g,R=v(v(v(Lt*G)+v(Qt*Q))+v(R*D)),C[o+28>>2]=R,D=v(v(v(Gt*G)+v(xt*Q))+v(Yt*D)),C[o+24>>2]=D),pt&&(f[o+20>>2]=0,Gt=C[a+4>>2],Lt=C[a+20>>2],wt=C[a+36>>2],G=v(v(v(v(B*Gt)+v(F*Lt))+v(p*wt))*C[a+164>>2]),xt=C[a+8>>2],Qt=C[a+24>>2],Wt=C[a+40>>2],Q=v(v(v(v(B*xt)+v(F*Qt))+v(p*Wt))*C[a+168>>2]),Yt=C[a+12>>2],It=F,F=C[a+28>>2],St=p,p=C[a+44>>2],B=v(v(v(v(B*Yt)+v(It*F))+v(St*p))*C[a+172>>2]),p=v(v(v(wt*G)+v(Wt*Q))+v(p*B)),C[o+16>>2]=p,F=v(v(v(Lt*G)+v(Qt*Q))+v(F*B)),C[o+12>>2]=F,B=v(v(v(Gt*G)+v(xt*Q))+v(Yt*B)),C[o+8>>2]=B),Ot&&(f[o+20>>2]=0,Gt=C[r+4>>2],Lt=C[r+20>>2],wt=C[r+36>>2],G=v(v(v(v(Gt*B)+v(Lt*F))+v(wt*p))*C[r+164>>2]),xt=C[r+8>>2],Qt=C[r+24>>2],Wt=C[r+40>>2],Q=v(v(v(v(B*xt)+v(F*Qt))+v(p*Wt))*C[r+168>>2]),Yt=C[r+12>>2],It=F,F=C[r+28>>2],St=p,p=C[r+44>>2],B=v(v(v(v(B*Yt)+v(It*F))+v(St*p))*C[r+172>>2]),p=v(v(v(wt*G)+v(Wt*Q))+v(p*B)),C[o+16>>2]=p,F=v(v(v(Lt*G)+v(Qt*Q))+v(F*B)),C[o+12>>2]=F,B=v(v(v(Gt*G)+v(xt*Q))+v(Yt*B)),C[o+8>>2]=B),+v(E(v(v(v(D*D)+v(R*R))+v(g*g))))>.001&&Af(t,o+24|0,h,d,w,C[Y>>2]),+v(E(v(v(v(B*B)+v(F*F))+v(p*p))))>.001&&Af(t,o+8|0,h,d,w,C[Y>>2]));t:if(1&n[yt+124|0]&&32&_[i+72|0])g=C[o+44>>2],Y=yt+156|0,$i(t,yt+164|0,h,d,w,Mt,o- -64|0,o+48|0,g,i,C[yt+140>>2],C[Y>>2]),16&_[i+72|0]&&$i(t,yt+180|0,h,d,w,Mt,o- -64|0,o+48|0,g,i,C[yt+144>>2],C[Y>>2]);else{if(f[(Zt=yt+176|0)>>2]=0,R=v(z-V),p=v(Dt-Ft),D=v(W-Et),g=v(v(v(R*Xt)+v(p*hn))+v(D*Tt)),pt=yt+172|0,V=D,D=C[Pt>>2],B=v(V-v(g*D)),C[pt>>2]=B,Ot=yt+168|0,V=p,p=C[Vt>>2],F=v(V-v(g*p)),C[Ot>>2]=F,Y=yt+164|0,V=R,R=C[Nt>>2],g=v(V-v(g*R)),C[Y>>2]=g,!(64&_[i+72|0])&&(G=v(v(v(g*g)+v(F*F))+v(B*B)))>v(1.1920928955078125e-7)){if(p=v(v(1)/v(E(G))),R=v(F*p),C[Ot>>2]=R,g=v(g*p),C[Y>>2]=g,p=v(B*p),C[pt>>2]=p,1&n[a+180|0]&&(Ft=C[a+172>>2],D=C[a+44>>2],B=C[a+12>>2],F=C[a+28>>2],Et=C[a+164>>2],G=C[a+36>>2],Q=C[a+4>>2],V=C[a+20>>2],Tt=C[a+168>>2],z=C[a+40>>2],Dt=C[a+8>>2],W=C[a+24>>2],f[Zt>>2]=0,It=V,V=v(Et*v(v(v(g*Q)+v(R*V))+v(p*G))),St=W,W=v(Tt*v(v(v(g*Dt)+v(R*W))+v(p*z))),p=v(Ft*v(v(v(g*B)+v(R*F))+v(p*D))),R=v(v(v(It*V)+v(St*W))+v(F*p)),C[Ot>>2]=R,g=v(v(v(Q*V)+v(Dt*W))+v(B*p)),C[Y>>2]=g,p=v(v(v(G*V)+v(z*W))+v(D*p)),C[pt>>2]=p),1&n[r+180|0]&&(Ft=C[r+172>>2],D=C[r+44>>2],B=C[r+12>>2],F=C[r+28>>2],Et=C[r+164>>2],G=C[r+36>>2],Q=C[r+4>>2],V=C[r+20>>2],Tt=C[r+168>>2],z=C[r+40>>2],Dt=C[r+8>>2],W=C[r+24>>2],f[Zt>>2]=0,It=V,V=v(Et*v(v(v(Q*g)+v(V*R))+v(G*p))),St=W,W=v(Tt*v(v(v(g*Dt)+v(R*W))+v(p*z))),g=v(Ft*v(v(v(g*B)+v(R*F))+v(p*D))),C[Ot>>2]=v(v(It*V)+v(St*W))+v(F*g),C[Y>>2]=v(v(Q*V)+v(Dt*W))+v(B*g),C[pt>>2]=v(v(G*V)+v(z*W))+v(D*g)),$i(t,Y,h,d,w,Mt,o- -64|0,o+48|0,Ft=C[o+44>>2],i,v(0),v(0)),!(16&_[i+72|0]))break t;f[(Zt=yt+192|0)>>2]=0,jt=yt+188|0,p=C[Vt>>2],D=C[Y>>2],R=C[Ot>>2],B=C[Nt>>2],g=v(v(p*D)-v(R*B)),F=C[Pt>>2],G=C[pt>>2],R=v(v(R*F)-v(G*p)),p=v(v(G*B)-v(F*D)),D=v(v(1)/v(E(v(v(v(R*R)+v(p*p))+v(g*g))))),g=v(g*D),C[jt>>2]=g,pt=yt+184|0,p=v(p*D),C[pt>>2]=p,Y=yt+180|0,R=v(R*D),C[Y>>2]=R,1&n[a+180|0]&&(Et=C[a+172>>2],D=C[a+44>>2],B=C[a+12>>2],F=C[a+28>>2],Tt=C[a+164>>2],G=C[a+36>>2],Q=C[a+4>>2],V=C[a+20>>2],Xt=C[a+168>>2],z=C[a+40>>2],Dt=C[a+8>>2],W=C[a+24>>2],f[Zt>>2]=0,It=V,V=v(Tt*v(v(v(R*Q)+v(p*V))+v(g*G))),St=W,W=v(Xt*v(v(v(R*Dt)+v(p*W))+v(g*z))),g=v(Et*v(v(v(R*B)+v(p*F))+v(g*D))),p=v(v(v(It*V)+v(St*W))+v(F*g)),C[pt>>2]=p,R=v(v(v(Q*V)+v(Dt*W))+v(B*g)),C[Y>>2]=R,g=v(v(v(G*V)+v(z*W))+v(D*g)),C[jt>>2]=g),1&n[r+180|0]&&(Et=C[r+172>>2],D=C[r+44>>2],B=C[r+12>>2],F=C[r+28>>2],Tt=C[r+164>>2],G=C[r+36>>2],Q=C[r+4>>2],V=C[r+20>>2],Xt=C[r+168>>2],z=C[r+40>>2],Dt=C[r+8>>2],W=C[r+24>>2],f[Zt>>2]=0,It=V,V=v(Tt*v(v(v(Q*R)+v(V*p))+v(G*g))),St=W,W=v(Xt*v(v(v(R*Dt)+v(p*W))+v(g*z))),g=v(Et*v(v(v(R*B)+v(p*F))+v(g*D))),C[pt>>2]=v(v(It*V)+v(St*W))+v(F*g),C[Y>>2]=v(v(Q*V)+v(Dt*W))+v(B*g),C[jt>>2]=v(v(G*V)+v(z*W))+v(D*g)),$i(t,Y,h,d,w,Mt,o- -64|0,o+48|0,Ft,i,v(0),v(0));break t}if(Nt=yt+180|0,v(y(D))>v(.7071067690849304)?(f[Y>>2]=0,F=v(v(p*p)+v(D*D)),B=v(v(1)/v(E(F))),p=v(p*B),C[pt>>2]=p,g=v(-v(D*B)),C[Ot>>2]=g,D=v(F*B),F=v(R*g),B=v(-v(R*p)),R=v(0)):(f[pt>>2]=0,F=v(v(R*R)+v(p*p)),B=v(v(1)/v(E(F))),g=v(R*B),C[Ot>>2]=g,R=v(-v(p*B)),C[Y>>2]=R,F=v(F*B),B=v(D*R),D=v(-v(D*g)),p=v(0)),C[Nt>>2]=D,C[(Vt=yt+188|0)>>2]=F,C[(Pt=yt+184|0)>>2]=B,1&n[a+180|0]&&(Ft=C[a+172>>2],D=C[a+44>>2],B=C[a+12>>2],F=C[a+28>>2],Et=C[a+164>>2],G=C[a+36>>2],Q=C[a+4>>2],V=C[a+20>>2],Tt=C[a+168>>2],z=C[a+40>>2],Dt=C[a+8>>2],W=C[a+24>>2],f[Zt>>2]=0,It=V,V=v(Et*v(v(v(Q*R)+v(V*g))+v(G*p))),St=W,W=v(Tt*v(v(v(R*Dt)+v(g*W))+v(p*z))),p=v(Ft*v(v(v(R*B)+v(g*F))+v(p*D))),g=v(v(v(It*V)+v(St*W))+v(F*p)),C[Ot>>2]=g,R=v(v(v(Q*V)+v(Dt*W))+v(B*p)),C[Y>>2]=R,p=v(v(v(G*V)+v(z*W))+v(D*p)),C[pt>>2]=p),1&n[r+180|0]&&(Ft=C[r+172>>2],D=C[r+44>>2],B=C[r+12>>2],F=C[r+28>>2],Et=C[r+164>>2],G=C[r+36>>2],Q=C[r+4>>2],V=C[r+20>>2],Tt=C[r+168>>2],z=C[r+40>>2],Dt=C[r+8>>2],W=C[r+24>>2],f[Zt>>2]=0,It=V,V=v(Et*v(v(v(Q*R)+v(V*g))+v(G*p))),St=W,W=v(Tt*v(v(v(R*Dt)+v(g*W))+v(p*z))),g=v(Ft*v(v(v(R*B)+v(g*F))+v(p*D))),C[Ot>>2]=v(v(It*V)+v(St*W))+v(F*g),C[Y>>2]=v(v(Q*V)+v(Dt*W))+v(B*g),C[pt>>2]=v(v(G*V)+v(z*W))+v(D*g)),$i(t,Y,h,d,w,Mt,o- -64|0,o+48|0,Ft=C[o+44>>2],i,v(0),v(0)),16&(pt=f[i+72>>2])&&(1&n[a+180|0]&&(Et=C[a+172>>2],g=C[a+44>>2],p=C[a+12>>2],R=C[a+28>>2],z=C[a+164>>2],D=C[a+36>>2],B=C[a+4>>2],F=C[a+20>>2],Tt=C[a+168>>2],G=C[a+40>>2],Q=C[a+8>>2],V=C[a+24>>2],f[yt+192>>2]=0,It=B,W=z,B=C[Nt>>2],z=C[Pt>>2],Dt=C[Vt>>2],W=v(W*v(v(v(It*B)+v(F*z))+v(D*Dt))),St=Q,Q=v(Tt*v(v(v(B*Q)+v(z*V))+v(Dt*G))),Tt=p,p=v(Et*v(v(v(B*p)+v(z*R))+v(Dt*g))),C[Nt>>2]=v(v(It*W)+v(St*Q))+v(Tt*p),C[Pt>>2]=v(v(F*W)+v(V*Q))+v(R*p),C[Vt>>2]=v(v(D*W)+v(G*Q))+v(g*p)),1&n[r+180|0]&&(Et=C[r+172>>2],g=C[r+44>>2],p=C[r+12>>2],R=C[r+28>>2],z=C[r+164>>2],D=C[r+36>>2],B=C[r+4>>2],F=C[r+20>>2],Tt=C[r+168>>2],G=C[r+40>>2],Q=C[r+8>>2],V=C[r+24>>2],f[yt+192>>2]=0,It=B,W=z,B=C[Nt>>2],z=C[Pt>>2],Dt=C[Vt>>2],W=v(W*v(v(v(It*B)+v(F*z))+v(D*Dt))),St=Q,Q=v(Tt*v(v(v(B*Q)+v(z*V))+v(Dt*G))),Tt=p,p=v(Et*v(v(v(B*p)+v(z*R))+v(Dt*g))),C[Nt>>2]=v(v(It*W)+v(St*Q))+v(Tt*p),C[Pt>>2]=v(v(F*W)+v(V*Q))+v(R*p),C[Vt>>2]=v(v(D*W)+v(G*Q))+v(g*p)),$i(t,Nt,h,d,w,Mt,o- -64|0,o+48|0,Ft,i,v(0),v(0)),pt=f[i+72>>2]),80!=(80&pt))break t;f[(w=yt+124|0)>>2]=1|f[w>>2]}tf(t,Ut,h,d,Mt,i),Y=f[e+780>>2]}if(!((0|(Jt=Jt+1|0))<(0|Y)))break}Z=o+80|0}function af(t,e,i){var r,n=0,a=0,o=0;Z=r=Z-80|0,f[t+240>>2]&&(C[t+176>>2]=C[t+64>>2]+C[t+176>>2],C[t+192>>2]=C[t+80>>2]+C[t+192>>2],C[(n=t+180|0)>>2]=C[t+68>>2]+C[n>>2],C[(n=t+184|0)>>2]=C[t+72>>2]+C[n>>2],C[(n=t+196|0)>>2]=C[t+84>>2]+C[n>>2],C[(n=t+200|0)>>2]=C[t+88>>2]+C[n>>2],(C[t+144>>2]!=v(0)|C[t+148>>2]!=v(0)|C[t+152>>2]!=v(0)|C[t+160>>2]!=v(0)||C[t+164>>2]!=v(0)||C[t+168>>2]!=v(0))&&(f[r+12>>2]=0,C[r>>2]=C[t+160>>2]*i,C[r+8>>2]=C[t+168>>2]*i,C[r+4>>2]=C[t+164>>2]*i,xi(t,t+144|0,r,e,r+16|0),o=f[(a=r+24|0)+4>>2],f[(n=t+8|0)>>2]=f[a>>2],f[n+4>>2]=o,n=f[r+20>>2],f[t>>2]=f[r+16>>2],f[t+4>>2]=n,n=f[r+36>>2],f[t+16>>2]=f[r+32>>2],f[t+20>>2]=n,o=f[(a=r+40|0)+4>>2],f[(n=t+24|0)>>2]=f[a>>2],f[n+4>>2]=o,n=f[r+52>>2],f[t+32>>2]=f[r+48>>2],f[t+36>>2]=n,o=f[(a=r+56|0)+4>>2],f[(n=t+40|0)>>2]=f[a>>2],f[n+4>>2]=o,n=f[r+68>>2],f[t+48>>2]=f[r+64>>2],f[t+52>>2]=n,a=f[(n=r+72|0)+4>>2],f[(t=t+56|0)>>2]=f[n>>2],f[t+4>>2]=a)),Z=r+80|0}function of(t,e,i,r,n){return f[t+20>>2]=0,f[t+16>>2]=i,f[t+12>>2]=e,f[t+8>>2]=n,f[t+4>>2]=r,f[t>>2]=20396,t}function cf(t,e,i,r){var a,o=0,_=0,h=0,d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=0,Nt=0,Ft=v(0),Vt=v(0),Gt=v(0),Lt=v(0),wt=0,xt=0,Qt=0,Wt=v(0),Yt=v(0),Pt=v(0),Mt=v(0),Zt=v(0),Ut=v(0);Z=a=Z-240|0,f[t+16>>2]?(Yr(f[t+4>>2]),o=f[t+12>>2],_=f[o+4>>2],h=f[t+16>>2],Ot=f[h+4>>2],Nt=o,w=v(yt[f[f[o>>2]+48>>2]](o)),o=f[t+16>>2],t=function(t,e,i,r,a,o,_,h,d){return f[t+72>>2]=1,f[t+76>>2]=1,f[t+60>>2]=-1,n[t+52|0]=0,C[t+48>>2]=_,C[t+44>>2]=o,f[t+40>>2]=a,f[t+36>>2]=r,f[t+32>>2]=i,f[t+28>>2]=e,f[t+24>>2]=h,f[t+20>>2]=d,f[t+4>>2]=0,f[t+8>>2]=1065353216,f[t>>2]=14908,f[(e=t+12|0)>>2]=0,f[e+4>>2]=0,t}(a+160|0,Nt,h,_,Ot,w,v(yt[f[f[o>>2]+48>>2]](o)),f[t+4>>2],f[t+8>>2]),h=f[(_=e+8|0)+4>>2],f[(o=a+32|0)>>2]=f[_>>2],f[o+4>>2]=h,h=f[(_=e+24|0)+4>>2],f[(o=a+48|0)>>2]=f[_>>2],f[o+4>>2]=h,h=f[(_=e+40|0)+4>>2],f[(o=a- -64|0)>>2]=f[_>>2],f[o+4>>2]=h,h=f[(_=e+56|0)+4>>2],f[(o=a+80|0)>>2]=f[_>>2],f[o+4>>2]=h,h=f[(_=i+8|0)+4>>2],f[(o=a+96|0)>>2]=f[_>>2],f[o+4>>2]=h,f[a+152>>2]=1566444395,o=f[e+4>>2],f[a+24>>2]=f[e>>2],f[a+28>>2]=o,o=f[e+20>>2],f[a+40>>2]=f[e+16>>2],f[a+44>>2]=o,o=f[e+36>>2],f[a+56>>2]=f[e+32>>2],f[a+60>>2]=o,o=f[e+52>>2],f[a+72>>2]=f[e+48>>2],f[a+76>>2]=o,e=f[i+4>>2],f[a+88>>2]=f[i>>2],f[a+92>>2]=e,_=f[(o=i+24|0)+4>>2],f[(e=a+112|0)>>2]=f[o>>2],f[e+4>>2]=_,o=f[i+20>>2],f[(e=a+104|0)>>2]=f[i+16>>2],f[e+4>>2]=o,_=f[(o=i+40|0)+4>>2],f[(e=a+128|0)>>2]=f[o>>2],f[e+4>>2]=_,o=f[i+36>>2],f[(e=a+120|0)>>2]=f[i+32>>2],f[e+4>>2]=o,_=f[(o=i+56|0)+4>>2],f[(e=a+144|0)>>2]=f[o>>2],f[e+4>>2]=_,o=f[i+52>>2],f[(e=a+136|0)>>2]=f[i+48>>2],f[e+4>>2]=o,Sr(t,a+24|0,r,0)):(z=C[e+52>>2],pt=C[e+56>>2],Ft=C[(_=i+52|0)>>2],Vt=C[(h=i+56|0)>>2],B=C[e+20>>2],E=C[e+36>>2],D=C[(Ot=i+20|0)>>2],m=C[(wt=i+36|0)>>2],y=C[(xt=i+24|0)>>2],g=C[e+24>>2],d=C[(Qt=i+40|0)>>2],Q=C[e+40>>2],Gt=C[e+48>>2],Ut=C[i+48>>2],o=f[t+12>>2],W=C[e+32>>2],Y=C[e+16>>2],Dt=C[e>>2],It=C[e+4>>2],R=C[i+32>>2],F=C[i+16>>2],p=C[i>>2],V=C[i+4>>2],t=f[t+20>>2],G=C[i+8>>2],St=C[e+8>>2],f[a+172>>2]=0,Wt=v(v(v(St*p)+v(g*F))+v(Q*R)),Tt=v(-C[t+52>>2]),Yt=v(v(v(St*V)+v(g*D))+v(Q*m)),Et=C[(e=t+56|0)>>2],St=v(v(v(St*G)+v(g*y))+v(Q*d)),g=C[(Nt=t+60|0)>>2],C[a+168>>2]=v(v(Wt*Tt)-v(Yt*Et))-v(St*g),Pt=v(v(v(It*p)+v(B*F))+v(E*R)),Mt=v(v(v(It*V)+v(B*D))+v(E*m)),It=v(v(v(It*G)+v(B*y))+v(E*d)),C[a+164>>2]=v(v(Pt*Tt)-v(Et*Mt))-v(g*It),Zt=v(v(v(Dt*p)+v(Y*F))+v(W*R)),w=v(Zt*Tt),Tt=v(v(v(Dt*V)+v(Y*D))+v(W*m)),Dt=v(v(v(Dt*G)+v(Y*y))+v(W*d)),C[a+160>>2]=v(w-v(Et*Tt))-v(g*Dt),yt[f[f[o>>2]+64>>2]](a+24|0,o,a+160|0),B=C[e>>2],E=C[Nt>>2],Et=C[t+68>>2],g=C[t+52>>2],Q=C[a+24>>2],W=C[a+28>>2],Y=C[a+32>>2],f[a+172>>2]=0,Lt=v(v(v(Gt*p)+v(z*F))+v(pt*R)),w=p,p=v(-Ut),R=v(v(Lt+v(v(v(w*p)-v(F*Ft))-v(R*Vt)))+v(v(v(Zt*Q)+v(Pt*W))+v(Wt*Y))),d=v(v(v(v(v(Gt*G)+v(z*y))+v(pt*d))+v(v(v(G*p)-v(y*Ft))-v(d*Vt)))+v(v(v(Dt*Q)+v(It*W))+v(St*Y))),y=v(v(v(v(v(Gt*V)+v(z*D))+v(pt*m))+v(v(v(V*p)-v(D*Ft))-v(m*Vt)))+v(v(v(Tt*Q)+v(Mt*W))+v(Yt*Y))),D=v(v(v(E*d)+v(v(g*R)+v(B*y)))-Et),m=v(R-v(g*D)),R=C[i+32>>2],y=v(y-v(B*D)),F=C[wt>>2],d=v(d-v(E*D)),p=C[Qt>>2],C[a+168>>2]=v(v(v(m*R)+v(y*F))+v(d*p))+C[h>>2],V=C[i+16>>2],G=C[Ot>>2],z=C[xt>>2],C[a+164>>2]=v(v(v(m*V)+v(y*G))+v(d*z))+C[_>>2],pt=C[i+8>>2],Lt=v(pt*d),d=C[i>>2],w=v(d*m),m=C[i+4>>2],C[a+160>>2]=v(Lt+v(w+v(m*y)))+C[i+48>>2],f[a+20>>2]=0,C[a+16>>2]=v(v(g*R)+v(B*F))+v(E*p),C[a+12>>2]=v(v(g*V)+v(B*G))+v(E*z),C[a+8>>2]=v(v(d*g)+v(m*B))+v(pt*E),yt[f[f[r>>2]+16>>2]](r,a+8|0,a+160|0,D)),Z=a+240|0}function bf(t,e,i,r,a,o){t|=0,e|=0,i|=0,r|=0,a|=0,o|=0;var h,d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=0,F=0,V=0,G=0,w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=0,Dt=v(0),It=v(0),St=0;Z=h=Z-304|0,f[h+300>>2]=0,R=v(C[i+56>>2]-C[e+56>>2]),C[h+296>>2]=R,w=v(C[i+52>>2]-C[e+52>>2]),C[h+292>>2]=w,Q=v(C[i+48>>2]-C[e+48>>2]),C[h+288>>2]=Q,Mi(e,i,h+112|0,h+48|0),f[h+284>>2]=0,g=C[h+48>>2],d=v(g*C[h+120>>2]),C[h+280>>2]=d,m=v(g*C[h+116>>2]),C[h+276>>2]=m,y=v(g*C[h+112>>2]),C[h+272>>2]=y,f[h+268>>2]=0,W=v(C[a+56>>2]-C[r+56>>2]),C[h+264>>2]=W,Y=v(C[a+52>>2]-C[r+52>>2]),C[h+260>>2]=Y,z=v(C[a+48>>2]-C[r+48>>2]),C[h+256>>2]=z,Mi(r,a,h+112|0,h+48|0),f[h+252>>2]=0,g=C[h+48>>2],p=v(g*C[h+120>>2]),C[h+248>>2]=p,D=v(g*C[h+116>>2]),C[h+244>>2]=D,g=v(g*C[h+112>>2]),C[h+240>>2]=g,i=f[t+12>>2],Dt=v(yt[f[f[i>>2]+16>>2]](i)),(i=f[t+16>>2])&&(It=v(yt[f[f[i>>2]+16>>2]](i)),R=C[h+296>>2],W=C[h+264>>2],w=C[h+292>>2],Y=C[h+260>>2],Q=C[h+288>>2],z=C[h+256>>2],p=C[h+248>>2],D=C[h+244>>2],g=C[h+240>>2],m=C[h+276>>2],y=C[h+272>>2],d=C[h+280>>2]),D=v(v(Dt*v(E(v(v(v(y*y)+v(m*m))+v(d*d)))))+v(It*v(E(v(v(v(g*g)+v(D*D))+v(p*p)))))),m=v(z-Q),y=v(Y-w),p=v(W-R);t:if(v(D+v(E(v(v(v(m*m)+v(y*y))+v(p*p)))))!=v(0)&&(n[h+216|0]=0,f[h+212>>2]=1566444395,f[h+176>>2]=15364,cf(t,e,r,h+176|0),a=h+204|0,B=f[a+4>>2],i=h+232|0,f[i>>2]=f[a>>2],f[i+4>>2]=B,i=f[h+200>>2],f[h+224>>2]=f[h+196>>2],f[h+228>>2]=i,_[h+216|0]&&(i=f[h+180>>2],a=h+184|0,B=f[a>>2],V=h+188|0,G=f[V>>2],!(v(D+v(v(v(m*C[h+180>>2])+v(y*C[a>>2]))+v(p*C[V>>2])))<=v(1.1920928955078125e-7))))){F=1;e:{if((R=v(C[h+212>>2]+C[o+172>>2]))>v(.0010000000474974513)){for(V=h+20|0,St=h+160|0,a=0,g=v(0);;){if((pt=f[o+168>>2])&&(f[h+120>>2]=1065353216,f[h+124>>2]=0,f[h+112>>2]=1065353216,f[h+116>>2]=1065353216,yt[f[f[pt>>2]+28>>2]](pt,h+224|0,v(.20000000298023224),h+112|0)),(d=v(D+v(v(v(m*(b(0,i),k()))+v(y*(b(0,B),k())))+v(p*(b(0,G),k())))))<=v(1.1920928955078125e-7)){F=0;break t}if((d=v(g+v(R/d)))<=g){F=0;break t}if(dv(1)){F=0;break t}if(xi(e,h+288|0,h+272|0,d,h+112|0),xi(r,h+256|0,h+240|0,d,h+48|0),(i=f[o+168>>2])&&(f[h+8>>2]=0,f[h+12>>2]=0,f[h>>2]=1065353216,f[h+4>>2]=0,yt[f[f[i>>2]+28>>2]](i,St,v(.20000000298023224),h)),yt[f[f[o>>2]>>2]](o,d),n[h+40|0]=0,f[h+36>>2]=1566444395,f[h>>2]=15364,cf(t,h+112|0,h+48|0,h),!_[h+40|0])break e;if(G=f[(B=V+8|0)+4>>2],f[(i=h+232|0)>>2]=f[B>>2],f[i+4>>2]=G,i=f[V+4>>2],f[h+224>>2]=f[V>>2],f[h+228>>2]=i,a>>>0>63){yt[f[f[o>>2]+8>>2]](o,-2,a+1|0),F=0;break t}if(a=a+1|0,i=f[h+4>>2],B=f[h+8>>2],G=f[h+12>>2],g=d,!((R=v(C[h+36>>2]+C[o+172>>2]))>v(.0010000000474974513)))break}m=C[h+16>>2]}else d=v(0),m=C[h+192>>2];f[o+132>>2]=i,C[o+164>>2]=d,t=f[h+228>>2],f[o+148>>2]=f[h+224>>2],f[o+152>>2]=t,C[o+144>>2]=m,f[o+140>>2]=G,f[o+136>>2]=B,i=f[(e=h+232|0)+4>>2],f[(t=o+156|0)>>2]=f[e>>2],f[t+4>>2]=i;break t}yt[f[f[o>>2]+8>>2]](o,-1,a),F=0}return Z=h+304|0,0|F}function lf(t,e,i,r){var n,a=0;f[t>>2]=20460,a=f[e+4>>2],f[t+4>>2]=f[e>>2],f[t+8>>2]=a,a=f[(e=e+8|0)+4>>2],f[(n=t+12|0)>>2]=f[e>>2],f[n+4>>2]=a,e=f[i+4>>2],f[t+20>>2]=f[i>>2],f[t+24>>2]=e,i=f[(e=i+8|0)+4>>2],f[(a=t+28|0)>>2]=f[e>>2],f[a+4>>2]=i,f[t+40>>2]=1065353216,f[t+36>>2]=r}function uf(t,e,i,r,n,a){var o=0,_=0;f[t+4>>2]=e,f[t>>2]=20484,o=f[(e=i+8|0)+4>>2],f[(_=t+16|0)>>2]=f[e>>2],f[_+4>>2]=o,e=f[i+4>>2],f[t+8>>2]=f[i>>2],f[t+12>>2]=e,o=f[(e=i+24|0)+4>>2],f[(_=t+32|0)>>2]=f[e>>2],f[_+4>>2]=o,e=f[i+20>>2],f[(o=t+24|0)>>2]=f[i+16>>2],f[o+4>>2]=e,o=f[(e=i+40|0)+4>>2],f[(_=t+48|0)>>2]=f[e>>2],f[_+4>>2]=o,e=f[i+36>>2],f[(o=t+40|0)>>2]=f[i+32>>2],f[o+4>>2]=e,o=f[(e=i+56|0)+4>>2],f[(_=t- -64|0)>>2]=f[e>>2],f[_+4>>2]=o,e=f[i+52>>2],f[(o=t+56|0)>>2]=f[i+48>>2],f[o+4>>2]=e,i=f[(e=r+8|0)+4>>2],f[(o=t+80|0)>>2]=f[e>>2],f[o+4>>2]=i,e=f[r+4>>2],f[t+72>>2]=f[r>>2],f[t+76>>2]=e,i=f[(e=r+24|0)+4>>2],f[(o=t+96|0)>>2]=f[e>>2],f[o+4>>2]=i,e=f[r+20>>2],f[(i=t+88|0)>>2]=f[r+16>>2],f[i+4>>2]=e,i=f[(e=r+40|0)+4>>2],f[(o=t+112|0)>>2]=f[e>>2],f[o+4>>2]=i,e=f[r+36>>2],f[(i=t+104|0)>>2]=f[r+32>>2],f[i+4>>2]=e,i=f[(e=r+56|0)+4>>2],f[(o=t+128|0)>>2]=f[e>>2],f[o+4>>2]=i,e=f[r+52>>2],f[(i=t+120|0)>>2]=f[r+48>>2],f[i+4>>2]=e,i=f[(e=n+8|0)+4>>2],f[(r=t+144|0)>>2]=f[e>>2],f[r+4>>2]=i,e=f[n+4>>2],f[t+136>>2]=f[n>>2],f[t+140>>2]=e,i=f[(e=n+24|0)+4>>2],f[(r=t+160|0)>>2]=f[e>>2],f[r+4>>2]=i,e=f[n+20>>2],f[(i=t+152|0)>>2]=f[n+16>>2],f[i+4>>2]=e,i=f[(e=n+40|0)+4>>2],f[(r=t+176|0)>>2]=f[e>>2],f[r+4>>2]=i,e=f[n+36>>2],f[(i=t+168|0)>>2]=f[n+32>>2],f[i+4>>2]=e,i=f[(e=n+56|0)+4>>2],f[(r=t+192|0)>>2]=f[e>>2],f[r+4>>2]=i,e=f[n+52>>2],f[(i=t+184|0)>>2]=f[n+48>>2],f[i+4>>2]=e,f[t+208>>2]=0,C[t+204>>2]=a,f[t+200>>2]=1065353216}function sf(t){var e=0,i=0,r=0,a=0,o=0,h=0;if(f[(t|=0)>>2]=20592,e=f[t+16>>2],(0|(i=f[t+8>>2]))>=1)for(;o=f[e+a>>2],(r=f[o+188>>2])&&(e=f[t+68>>2],e=0|yt[f[f[e>>2]+36>>2]](e),yt[f[f[e>>2]+40>>2]](e,r,f[t+24>>2]),e=f[t+68>>2],yt[f[f[e>>2]+12>>2]](e,r,f[t+24>>2]),f[o+188>>2]=0,i=f[t+8>>2],e=f[t+16>>2]),a=a+4|0,(0|(h=h+1|0))<(0|i););return e&&(_[t+20|0]&&CA(e),f[t+16>>2]=0),f[t+16>>2]=0,f[t+8>>2]=0,f[t+12>>2]=0,n[t+20|0]=1,0|t}function kf(t,e,i,r){e|=0,i|=0,r|=0;var a,o,h,d=0,C=0,g=0,m=0,v=0;if(Z=a=Z-96|0,d=f[(t|=0)+8>>2],f[e+216>>2]=d,f[t+12>>2]==(0|d)&&!((0|d)>=(0|(m=d?d<<1:1)))){if(m&&(v=dA(m<<2),d=f[t+8>>2]),(0|d)>=1)for(C=d;f[g+v>>2]=f[f[t+16>>2]+g>>2],g=g+4|0,C=C+-1|0;);(C=f[t+16>>2])&&(_[t+20|0]&&(CA(C),d=f[t+8>>2]),f[t+16>>2]=0),f[t+16>>2]=v,f[t+12>>2]=m,n[t+20|0]=1}f[t+8>>2]=d+1,f[f[t+16>>2]+(d<<2)>>2]=e,g=f[(C=e+12|0)+4>>2],f[(d=a+40|0)>>2]=f[C>>2],f[d+4>>2]=g,g=f[(C=e+28|0)+4>>2],f[(d=a+56|0)>>2]=f[C>>2],f[d+4>>2]=g,g=f[(C=e+44|0)+4>>2],f[(d=a+72|0)>>2]=f[C>>2],f[d+4>>2]=g,g=f[(C=e+60|0)+4>>2],f[(d=a+88|0)>>2]=f[C>>2],f[d+4>>2]=g,d=f[e+8>>2],f[a+32>>2]=f[e+4>>2],f[a+36>>2]=d,C=f[(d=e+20|0)+4>>2],f[a+48>>2]=f[d>>2],f[a+52>>2]=C,C=f[(d=e+36|0)+4>>2],f[a+64>>2]=f[d>>2],f[a+68>>2]=C,C=f[(d=e+52|0)+4>>2],f[a+80>>2]=f[d>>2],f[a+84>>2]=C,d=f[e+192>>2],yt[f[f[d>>2]+8>>2]](d,a+32|0,a+16|0,a),d=f[t+68>>2],o=e,h=0|yt[f[f[d>>2]+8>>2]](d,a+16|0,a,f[f[e+192>>2]+4>>2],e,i,r,f[t+24>>2]),f[o+188>>2]=h,Z=a+96|0}function vf(t,e){var i,r=v(0),a=v(0),o=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=0;Z=i=Z+-64|0,y=f[e+192>>2],yt[f[f[y>>2]+8>>2]](y,e+4|0,i+48|0,i+32|0),r=C[744],o=v(C[i+48>>2]-r),C[i+48>>2]=o,h=v(C[i+52>>2]-r),C[i+52>>2]=h,d=v(C[i+56>>2]-r),C[i+56>>2]=d,a=v(r+C[i+32>>2]),C[i+32>>2]=a,g=v(r+C[i+36>>2]),C[i+36>>2]=g,m=v(r+C[i+40>>2]),C[i+40>>2]=m,3&_[e+204|0]|!_[t+44|0]|2!=f[e+252>>2]||(y=f[e+192>>2],yt[f[f[y>>2]+8>>2]](y,e+68|0,i+16|0,i),h=v(C[i+16>>2]-r),C[i+16>>2]=h,d=v(C[i+20>>2]-r),C[i+20>>2]=d,a=v(C[i+24>>2]-r),C[i+24>>2]=a,g=v(r+C[i>>2]),C[i>>2]=g,m=v(r+C[i+4>>2]),C[i+4>>2]=m,r=v(r+C[i+8>>2]),C[i+8>>2]=r,h<(o=C[i+48>>2])&&(C[i+48>>2]=h,o=h),d<(h=C[i+52>>2])&&(C[i+52>>2]=d,h=d),a<(d=C[i+56>>2])&&(C[i+56>>2]=a,d=a),(a=C[i+28>>2])>2]&&(C[i+60>>2]=a),(a=C[i+32>>2])>2]=g,a=g),(g=C[i+36>>2])>2]=m,g=m),(m=C[i+40>>2])>2]=r,m=r),r=C[i+12>>2],C[i+44>>2]>2]=r)),y=f[t+68>>2],1&n[e+204|0]||(o=v(a-o),a=v(o*o),o=v(g-h),a=v(a+v(o*o)),o=v(m-d),v(a+v(o*o))>2]+16>>2]](y,f[e+188>>2],i+48|0,i+32|0,f[t+24>>2]):(Ye(e,5),_[2804]||(e=f[t+72>>2])&&(n[2804]=1,yt[f[f[e>>2]+44>>2]](e,20644),e=f[t+72>>2],yt[f[f[e>>2]+44>>2]](e,20693),e=f[t+72>>2],yt[f[f[e>>2]+44>>2]](e,20761),t=f[t+72>>2],yt[f[f[t>>2]+44>>2]](t,20826))),Z=i- -64|0}function df(t,e){t|=0;var i=0,r=0,n=0,a=0,o=0,_=0,h=0,d=0;(r=f[(e|=0)+188>>2])&&(i=f[t+68>>2],i=0|yt[f[f[i>>2]+36>>2]](i),yt[f[f[i>>2]+40>>2]](i,r,f[t+24>>2]),i=f[t+68>>2],yt[f[f[i>>2]+12>>2]](i,r,f[t+24>>2]),f[e+188>>2]=0);t:if((0|(i=f[e+216>>2]))<0|(0|i)>=(0|(r=f[t+8>>2]))){if(!((0|r)<1)){for(i=n=f[t+16>>2];;){if((0|e)!=f[i>>2]){if(i=i+4|0,(0|r)!=(0|(a=a+1|0)))continue;break t}break}(0|r)<=(0|a)||(o=i,i=(r=r+-1|0)<<2,f[o>>2]=f[i+n>>2],f[t+8>>2]=r,f[i+f[t+16>>2]>>2]=e)}}else{if(n=f[(a=t+16|0)>>2],d=f[(h=n+(_=i<<2)|0)>>2],o=n,n=(r=r+-1|0)<<2,f[h>>2]=f[o+n>>2],f[t+8>>2]=r,f[n+f[a>>2]>>2]=d,(0|i)>=(0|r))break t;f[f[f[t+16>>2]+_>>2]+216>>2]=i}f[e+216>>2]=-1}function Cf(t,e,i,r){var a,o=0,_=v(0),h=v(0),d=v(0),g=v(0),m=0,y=v(0),p=0,R=v(0),D=v(0),B=v(0),F=v(0),V=v(0),G=0,w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=0,Ft=v(0),Vt=v(0),Gt=v(0),Lt=v(0),wt=v(0),xt=0,Qt=0,Wt=0;Z=a=Z-704|0,DA(a+624|0),f[(o=a+652|0)>>2]=0,f[o+4>>2]=0,f[(o=a+660|0)>>2]=0,f[o+4>>2]=0,f[(o=a+668|0)>>2]=0,f[o+4>>2]=0,f[a+676>>2]=0,f[a+648>>2]=1065353216,f[a+640>>2]=1065353216,f[a+644>>2]=1065353216,f[a+628>>2]=8,f[a+624>>2]=9852,o=f[i+12>>2];t:if(m=f[i+4>>2],G=f[m+4>>2],(0|G)<=19)f[a+616>>2]=0,f[a+620>>2]=0,f[a+448>>2]=15992,f[a+612>>2]=f[r+4>>2],n[a+420|0]=0,f[a+396>>2]=953267991,G=$r(a+680|0,a+624|0,m,a+88|0),xt=Hr(a+72|0,a+624|0,m,a+88|0),Qt=G,Wt=8&f[r+20>>2],m=Wt?xt:Qt,yt[f[f[m>>2]+8>>2]](m,t,e,o,o,a+448|0)&&(_=C[a+580>>2],d=C[a+584>>2],h=C[a+588>>2],g=v(v(v(_*_)+v(d*d))+v(h*h)),g>v(9999999747378752e-20)&&(y=C[a+612>>2],y>2]&&(D=h,h=v(v(1)/v(E(g))),C[a+588>>2]=D*h,C[a+584>>2]=d*h,C[a+580>>2]=_*h,t=a+580|0,e=t+8|0,o=f[e+4>>2],m=a+56|0,f[m>>2]=f[e>>2],f[m+4>>2]=o,C[a+64>>2]=y,e=f[t+4>>2],f[a+48>>2]=f[t>>2],f[a+52>>2]=e,f[a+44>>2]=0,f[a+40>>2]=f[i+8>>2],v(yt[f[f[r>>2]+12>>2]](r,a+40|0,1)))));else if(G+-21>>>0<=8){if(B=C[o+20>>2],F=C[o+36>>2],y=C[o+24>>2],d=C[o+52>>2],D=C[o+40>>2],Y=C[(G=o+56|0)>>2],V=C[o+32>>2],w=C[o>>2],Q=C[o+16>>2],W=C[o+4>>2],g=C[o+48>>2],z=C[o+8>>2],f[a+460>>2]=0,It=v(-d),Dt=v(y*It),St=v(-Y),Et=v(D*St),R=v(v(Dt-v(z*g))+Et),_=C[t+48>>2],h=C[t+52>>2],Ot=v(y*h),pt=C[t+56>>2],Ft=v(D*pt),C[a+456>>2]=R+v(v(v(z*_)+Ot)+Ft),g=v(-g),Vt=v(F*St),Tt=v(v(v(W*g)-v(B*d))+Vt),Lt=v(F*pt),C[a+452>>2]=Tt+v(v(v(W*_)+v(B*h))+Lt),Y=v(v(v(w*g)-v(Q*d))-v(V*Y)),C[a+448>>2]=Y+v(v(v(w*_)+v(Q*h))+v(V*pt)),f[a+52>>2]=0,Gt=R,d=C[e+48>>2],wt=v(z*d),R=y,y=C[e+52>>2],z=v(R*y),R=D,D=C[e+56>>2],R=v(R*D),C[a+48>>2]=Gt+v(v(wt+z)+R),Gt=Tt,Tt=v(F*D),C[a+44>>2]=Gt+v(v(v(W*d)+v(B*y))+Tt),C[a+40>>2]=Y+v(v(v(w*d)+v(Q*y))+v(V*D)),t=o+32|0,e=o+16|0,21==f[m+4>>2]){i=f[i+8>>2],lf(a+88|0,a+448|0,a+40|0,f[r+20>>2]),f[a+140>>2]=m,f[a+136>>2]=i,f[a+132>>2]=r,f[a+88>>2]=21004,p=f[(i=o+8|0)+4>>2],f[(Nt=a+152|0)>>2]=f[i>>2],f[Nt+4>>2]=p,i=f[o+4>>2],f[a+144>>2]=f[o>>2],f[a+148>>2]=i,p=f[(i=e+8|0)+4>>2],f[(Nt=a+168|0)>>2]=f[i>>2],f[Nt+4>>2]=p,i=f[e+4>>2],f[(p=a+160|0)>>2]=f[e>>2],f[p+4>>2]=i,i=f[(e=t+8|0)+4>>2],f[(p=a+184|0)>>2]=f[e>>2],f[p+4>>2]=i,e=f[t+4>>2],f[(i=a+176|0)>>2]=f[t>>2],f[i+4>>2]=e,t=f[G+4>>2],f[(e=a+200|0)>>2]=f[G>>2],f[e+4>>2]=t,t=f[o+52>>2],f[(e=a+192|0)>>2]=f[o+48>>2],f[e+4>>2]=t,f[a+128>>2]=f[r+4>>2],Te(m,a+88|0,a+448|0,a+40|0);break t}B=C[o+32>>2],F=C[o>>2],V=C[o+16>>2],w=C[o+4>>2],Q=C[o+20>>2],W=C[o+8>>2],f[a+692>>2]=0,Y=v(v(v(W*g)+Dt)+Et),C[a+688>>2]=v(v(v(_*W)+Ot)+Ft)+Y,Dt=v(v(v(w*g)+v(Q*It))+Vt),C[a+684>>2]=v(v(v(_*w)+v(h*Q))+Lt)+Dt,h=v(v(v(_*F)+v(h*V))+v(pt*B)),_=v(v(v(F*g)+v(V*It))+v(B*St)),C[a+680>>2]=h+_,f[a+84>>2]=0,C[a+80>>2]=v(v(v(d*W)+z)+R)+Y,C[a+76>>2]=v(v(v(d*w)+v(y*Q))+Tt)+Dt,C[a+72>>2]=v(v(v(d*F)+v(y*V))+v(D*B))+_,i=f[i+8>>2],lf(a+88|0,a+680|0,a+72|0,f[r+20>>2]),f[a+140>>2]=m,f[a+136>>2]=i,f[a+132>>2]=r,f[a+88>>2]=21188,i=f[o+12>>2],f[(p=a+152|0)>>2]=f[o+8>>2],f[p+4>>2]=i,i=f[o+4>>2],f[a+144>>2]=f[o>>2],f[a+148>>2]=i,i=f[e+4>>2],f[(p=a+160|0)>>2]=f[e>>2],f[p+4>>2]=i,i=f[(e=e+8|0)+4>>2],f[(p=a+168|0)>>2]=f[e>>2],f[p+4>>2]=i,i=f[(e=t+8|0)+4>>2],f[(p=a+184|0)>>2]=f[e>>2],f[p+4>>2]=i,e=f[t+4>>2],f[(i=a+176|0)>>2]=f[t>>2],f[i+4>>2]=e,t=f[o+52>>2],f[(e=a+192|0)>>2]=f[o+48>>2],f[e+4>>2]=t,t=f[G+4>>2],f[(e=a+200|0)>>2]=f[G>>2],f[e+4>>2]=t,f[a+128>>2]=f[r+4>>2],t=f[a+692>>2],f[(e=a+32|0)>>2]=f[a+688>>2],f[e+4>>2]=t,t=f[a+684>>2],f[a+24>>2]=f[a+680>>2],f[a+28>>2]=t,(_=C[a+72>>2])>2]&&(C[a+24>>2]=_),(d=C[a+76>>2])>2]&&(C[a+28>>2]=d),(h=C[a+80>>2])>2]&&(C[a+32>>2]=h),(g=C[a+84>>2])>2]&&(C[a+36>>2]=g),e=f[(t=a+688|0)+4>>2],f[(i=a+16|0)>>2]=f[t>>2],f[i+4>>2]=e,t=f[a+684>>2],f[a+8>>2]=f[a+680>>2],f[a+12>>2]=t,C[a+8>>2]<_&&(C[a+8>>2]=_),C[a+12>>2]>2]=d),C[a+16>>2]>2]=h),C[a+20>>2]>2]=g),yt[f[f[m>>2]+64>>2]](m,a+88|0,a+24|0,a+8|0)}else if(31==(0|G))if(G=f[m+68>>2],f[a+64>>2]=r,f[a+60>>2]=e,f[a+56>>2]=t,f[a+52>>2]=o,f[a+48>>2]=m,f[a+40>>2]=21376,f[a+44>>2]=f[i+8>>2],G)g=C[o>>2],y=C[o+4>>2],_=C[o+8>>2],f[a+100>>2]=0,R=_,B=C[o+48>>2],_=v(C[t+48>>2]-B),F=C[o+52>>2],d=v(C[t+52>>2]-F),D=C[o+24>>2],V=C[o+56>>2],h=v(C[t+56>>2]-V),w=C[o+40>>2],C[a+96>>2]=v(v(R*_)+v(d*D))+v(h*w),R=v(_*y),y=C[o+20>>2],Q=C[o+36>>2],C[a+92>>2]=v(R+v(d*y))+v(h*Q),_=v(_*g),g=C[o+16>>2],W=C[o+32>>2],C[a+88>>2]=v(_+v(d*g))+v(h*W),z=C[o>>2],pt=C[o+4>>2],_=C[o+8>>2],f[a+460>>2]=0,R=_,_=v(C[e+48>>2]-B),d=v(C[e+52>>2]-F),h=v(C[e+56>>2]-V),C[a+456>>2]=v(v(R*_)+v(D*d))+v(w*h),C[a+452>>2]=v(v(_*pt)+v(d*y))+v(h*Q),C[a+448>>2]=v(v(_*z)+v(d*g))+v(h*W),function(t,e,i,r){var n,a=v(0),o=v(0),_=v(0),h=v(0),d=0,g=v(0),m=v(0),y=0,p=0,R=0,D=0,B=0,F=v(0),V=v(0),G=0,w=0,Q=v(0),W=0,Y=0,z=v(0),pt=0,Dt=0,It=0,St=0,Tt=0,Et=0,Ot=0;if(Z=n=Z-544|0,t){for(a=C[e+8>>2],h=C[i+8>>2],g=C[e>>2],o=C[i>>2],m=C[e+4>>2],_=C[i+4>>2],f[n+32>>2]=t,o=v(o-g),_=v(_-m),a=v(h-a),h=v(v(1)/v(E(v(v(v(o*o)+v(_*_))+v(a*a))))),F=a,a=v(a*h),V=o,o=v(o*h),Q=_,_=v(_*h),Q=v(v(F*a)+v(v(V*o)+v(Q*_))),pt=((t=(a=a==v(0)?v(0xde0b6b000000000):v(v(1)/a))>2],i=f[R+20>>2],f[W>>2]=f[R+16>>2],f[W+4>>2]=i,Ot=f[(d=R+24|0)+4>>2],f[(i=W+8|0)>>2]=f[d>>2],f[i+4>>2]=Ot,i=f[R+4>>2],f[n>>2]=f[R>>2],f[n+4>>2]=i,d=f[(i=R+8|0)+4>>2],f[n+8>>2]=f[i>>2],f[n+12>>2]=d;e:{i:{A:{r:{n:{a:{o:{s:{if(!((h=v(_*v(C[Dt>>2]-m)))>(F=v(o*v(C[Et>>2]-g)))||(g=v(o*v(C[Tt>>2]-g)),m=v(_*v(C[St>>2]-m)),g>m||(z=C[e+8>>2],V=v(a*v(C[pt>>2]-z)),m=mm||(g=h>g?h:g,h=v(a*v(C[It>>2]-z)),g>h|(V>g?V:g)v(0)^1))))){if(f[R+40>>2]){if((0|t)<=(0|B)){i=D,d=p;break i}if((0|p)>=(0|(d=p<<1))){i=D;break A}if((0|y)>=(0|d)){i=D;break r}if(!p){i=0;break s}if(i=dA(p<<3),(0|p)<1)break s;for(t=i,B=D,y=p;f[t>>2]=f[B>>2],t=t+4|0,B=B+4|0,y=y+-1|0;);if(!G)break a;break o}yt[f[f[r>>2]+12>>2]](r,R)}i=D,d=p;break e}if(t=G,y=G=1,!t)break n;if(y=d,!D)break r}CA(D)}y=1}G=y,y=d}X((t=p<<2)+i|0,0,t)}B=d+-2|0}f[i+Y>>2]=f[R+36>>2],f[(w<<2)+i>>2]=f[R+40>>2],t=w+1|0}if(!t)break;m=C[e+4>>2],g=C[e>>2],D=i,p=d,w=t}!G|!i||CA(i)}Z=n+544|0}(f[G>>2],a+88|0,a+448|0,a+40|0);else if(t=f[m+20>>2],!((0|t)<1))for(e=t+-1|0,r=64,i=0;;){if(t=f[m+28>>2]+r|0,m=f[t>>2],Ft=C[o+52>>2],Vt=C[o+56>>2],w=C[t+-16>>2],Q=C[t+-12>>2],W=C[t+-8>>2],_=C[o+20>>2],d=C[o+24>>2],z=C[t+-64>>2],pt=C[t+-48>>2],Y=C[t+-32>>2],It=C[t+-60>>2],St=C[t+-44>>2],Dt=C[t+-28>>2],Et=C[t+-56>>2],h=C[o+36>>2],R=C[t+-40>>2],g=C[o+40>>2],Ot=C[t+-24>>2],Tt=C[o+48>>2],y=C[o+8>>2],B=C[o>>2],F=C[o+4>>2],D=C[o+16>>2],V=C[o+32>>2],f[a+148>>2]=0,f[a+132>>2]=0,f[a+116>>2]=0,f[a+100>>2]=0,C[a+128>>2]=v(v(Et*V)+v(R*h))+v(Ot*g),C[a+124>>2]=v(v(It*V)+v(St*h))+v(Dt*g),C[a+120>>2]=v(v(z*V)+v(pt*h))+v(Y*g),C[a+112>>2]=v(v(Et*D)+v(R*_))+v(Ot*d),C[a+108>>2]=v(v(It*D)+v(St*_))+v(Dt*d),C[a+104>>2]=v(v(z*D)+v(pt*_))+v(Y*d),C[a+96>>2]=v(v(B*Et)+v(F*R))+v(y*Ot),C[a+92>>2]=v(v(B*It)+v(F*St))+v(y*Dt),C[a+88>>2]=v(v(z*B)+v(pt*F))+v(Y*y),C[a+144>>2]=Vt+v(v(v(V*w)+v(h*Q))+v(g*W)),C[a+140>>2]=Ft+v(v(v(D*w)+v(_*Q))+v(d*W)),C[a+136>>2]=Tt+v(v(v(B*w)+v(F*Q))+v(y*W)),f[a+700>>2]=i,f[a+696>>2]=-1,f[a+688>>2]=f[a+44>>2],f[a+684>>2]=m,f[a+680>>2]=0,f[a+692>>2]=a+88,f[a+452>>2]=1065353216,f[a+464>>2]=-1,f[a+468>>2]=0,f[a+456>>2]=0,f[a+460>>2]=1,f[a+476>>2]=i,f[a+448>>2]=21552,t=f[a+64>>2],f[a+472>>2]=t,f[a+452>>2]=f[t+4>>2],f[a+468>>2]=f[t+20>>2],Cf(f[a+56>>2],f[a+60>>2],a+680|0,a+448|0),(0|e)==(0|i))break t;i=i+1|0,r=r+80|0,o=f[a+52>>2],m=f[a+48>>2]}Z=a+704|0}function gf(t,e,i,r,n,a,o,_){var h;Z=h=Z-32|0,f[h+24>>2]=-1,f[h+28>>2]=-1,f[h+20>>2]=a,f[h+16>>2]=r,f[h+12>>2]=n,f[h+8>>2]=0,Bf(t,e,i,h+8|0,o,_),Z=h+32|0}function Bf(t,e,i,r,a,o){var _,h,d=0,g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=0,Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0),Gt=0,Lt=v(0),wt=v(0),xt=0,Qt=0,Wt=0,Yt=0,Pt=0,Mt=0,Zt=0,Ut=0,Xt=0,Jt=0,jt=0,zt=0,Ht=0,Kt=v(0);Z=_=Z-688|0,d=f[r+12>>2],h=f[r+4>>2];t:if((0|(St=f[h+4>>2]))<=19)C[_+660>>2]=o,f[_+656>>2]=0,f[_+488>>2]=15992,f[_+652>>2]=f[a+4>>2],n[_+460|0]=0,f[_+436>>2]=953267991,f[_+64>>2]=14800,t=of(_+664|0,t,h,_+128|0,_- -64|0),yt[f[f[t>>2]+8>>2]](t,e,i,d,d,_+488|0)&&(o=C[_+620>>2],g=C[_+624>>2],m=C[_+628>>2],y=v(v(v(o*o)+v(g*g))+v(m*m)),y>v(9999999747378752e-20)&&(p=C[_+652>>2],p>2]&&(R=m,m=v(v(1)/v(E(y))),C[_+628>>2]=R*m,C[_+624>>2]=g*m,C[_+620>>2]=o*m,t=_+644|0,e=f[t+4>>2],i=_+112|0,f[i>>2]=f[t>>2],f[i+4>>2]=e,t=_+620|0,e=t+8|0,i=f[e+4>>2],d=_+96|0,f[d>>2]=f[e>>2],f[d+4>>2]=i,e=f[_+640>>2],f[_+104>>2]=f[_+636>>2],f[_+108>>2]=e,C[_+120>>2]=p,e=f[t+4>>2],f[_+88>>2]=f[t>>2],f[_+92>>2]=e,f[_+84>>2]=0,f[_+80>>2]=f[r+8>>2],v(yt[f[f[a>>2]+12>>2]](a,_+80|0,1)))));else if(Gt=St+-21|0,Gt>>>0<=8){e:if(!(Gt>>>0>7)){switch(Gt-1|0){default:g=C[d+20>>2],m=C[d+36>>2],B=C[d+52>>2],y=C[d+24>>2],F=C[d+56>>2],p=C[d+40>>2],D=C[d+32>>2],G=C[d>>2],w=C[d+16>>2],V=C[d+4>>2],R=C[d+8>>2],Q=C[d+48>>2],f[_+92>>2]=0,Q=v(-Q),pt=v(v(v(R*Q)-v(y*B))-v(p*F)),Y=C[e+48>>2],W=C[e+52>>2],z=C[e+56>>2],C[_+88>>2]=pt+v(v(v(R*Y)+v(y*W))+v(p*z)),Dt=v(v(v(V*Q)-v(g*B))-v(m*F)),C[_+84>>2]=Dt+v(v(v(V*Y)+v(g*W))+v(m*z)),Tt=v(v(v(G*Q)-v(w*B))-v(D*F)),C[_+80>>2]=Tt+v(v(v(G*Y)+v(w*W))+v(D*z)),f[_+676>>2]=0,B=C[i+48>>2],F=C[i+52>>2],Q=C[i+56>>2],C[_+672>>2]=pt+v(v(v(R*B)+v(y*F))+v(p*Q)),C[_+668>>2]=Dt+v(v(v(V*B)+v(g*F))+v(m*Q)),C[_+664>>2]=Tt+v(v(v(G*B)+v(w*F))+v(D*Q)),f[_+516>>2]=0,B=C[i+8>>2],F=C[i+24>>2],Q=C[i+40>>2],C[_+528>>2]=v(v(R*B)+v(y*F))+v(p*Q),Y=C[i+4>>2],W=C[i+20>>2],z=C[i+36>>2],C[_+524>>2]=v(v(R*Y)+v(y*W))+v(p*z),C[_+512>>2]=v(v(V*B)+v(g*F))+v(m*Q),C[_+508>>2]=v(v(V*Y)+v(g*W))+v(m*z),f[_+500>>2]=0,Tt=R,R=C[i>>2],It=y,y=C[i+16>>2],Et=p,p=C[i+32>>2],C[_+520>>2]=v(v(Tt*R)+v(It*y))+v(Et*p),C[_+504>>2]=v(v(V*R)+v(g*y))+v(m*p),C[_+496>>2]=v(v(G*B)+v(w*F))+v(D*Q),C[_+492>>2]=v(v(G*Y)+v(w*W))+v(D*z),C[_+488>>2]=v(v(G*R)+v(w*y))+v(D*p),f[_+548>>2]=0,f[(St=_+540|0)>>2]=0,f[St+4>>2]=0,f[(St=_+532|0)>>2]=0,f[St+4>>2]=0,r=f[r+8>>2],uf(_+128|0,t,e,i,d,v(yt[f[f[h>>2]+48>>2]](h))),f[_+348>>2]=h,f[_+344>>2]=r,f[_+128>>2]=21724,C[_+336>>2]=o,f[_+340>>2]=a,f[_+328>>2]=f[a+4>>2],yt[f[f[t>>2]+8>>2]](t,_+488|0,_- -64|0,_+48|0),je(h,_+128|0,_+80|0,_+664|0,_- -64|0,_+48|0);break t;case 0:case 1:case 2:case 3:case 4:case 5:break e;case 6:}C[_+300>>2]=o,f[_+296>>2]=0,f[_+128>>2]=15992,f[_+292>>2]=f[a+4>>2],t=function(t,e,i){return f[t+20>>2]=i,f[t+16>>2]=0,f[t+12>>2]=e,f[t+4>>2]=0,f[t+8>>2]=0,f[t>>2]=20396,t}(_+80|0,t,h),yt[f[f[t>>2]+8>>2]](t,e,i,d,d,_+128|0)&&(o=C[_+260>>2],g=C[_+264>>2],m=C[_+268>>2],(y=v(v(v(o*o)+v(g*g))+v(m*m)))>v(9999999747378752e-20)&&((p=C[_+292>>2])>2]&&(R=m,m=v(v(1)/v(E(y))),C[_+268>>2]=R*m,C[_+264>>2]=g*m,C[_+260>>2]=o*m,e=f[(t=_+284|0)+4>>2],f[(i=_+520|0)>>2]=f[t>>2],f[i+4>>2]=e,i=f[(e=(t=_+260|0)+8|0)+4>>2],f[(d=_+504|0)>>2]=f[e>>2],f[d+4>>2]=i,e=f[_+280>>2],f[_+512>>2]=f[_+276>>2],f[_+516>>2]=e,C[_+528>>2]=p,e=f[t+4>>2],f[_+496>>2]=f[t>>2],f[_+500>>2]=e,f[_+492>>2]=0,f[_+488>>2]=f[r+8>>2],v(yt[f[f[a>>2]+12>>2]](a,_+488|0,1)))));break t}Q=C[i+52>>2],Y=C[i+56>>2],m=C[d+52>>2],W=C[d+56>>2],z=C[e+52>>2],pt=C[e+56>>2],p=C[d+20>>2],D=C[d+36>>2],V=C[d+24>>2],R=C[d+40>>2],Dt=C[i+48>>2],Kt=C[d+48>>2],Tt=C[e+48>>2],y=C[d+32>>2],G=C[d>>2],w=C[d+16>>2],B=C[d+4>>2],F=C[d+8>>2],f[_+516>>2]=0,g=C[i+8>>2],It=C[i+24>>2],Et=C[i+40>>2],C[_+528>>2]=v(v(F*g)+v(V*It))+v(R*Et),Nt=C[i+4>>2],Ft=C[i+20>>2],Vt=C[i+36>>2],C[_+524>>2]=v(v(F*Nt)+v(V*Ft))+v(R*Vt),C[_+512>>2]=v(v(B*g)+v(p*It))+v(D*Et),C[_+508>>2]=v(v(B*Nt)+v(p*Ft))+v(D*Vt),f[_+500>>2]=0,Ot=C[i>>2],Lt=C[i+16>>2],wt=C[i+32>>2],C[_+520>>2]=v(v(F*Ot)+v(V*Lt))+v(R*wt),C[_+504>>2]=v(v(B*Ot)+v(p*Lt))+v(D*wt),C[_+496>>2]=v(v(G*g)+v(w*It))+v(y*Et),C[_+492>>2]=v(v(G*Nt)+v(w*Ft))+v(y*Vt),C[_+488>>2]=v(v(G*Ot)+v(w*Lt))+v(y*wt),f[_+548>>2]=0,f[(St=_+540|0)>>2]=0,f[St+4>>2]=0,f[(St=_+532|0)>>2]=0,f[St+4>>2]=0,r=f[r+8>>2],uf(_+128|0,t,e,i,d,v(yt[f[f[h>>2]+48>>2]](h))),f[_+348>>2]=h,f[_+344>>2]=r,f[_+128>>2]=21936,C[_+336>>2]=o,f[_+340>>2]=a,f[_+328>>2]=f[a+4>>2],yt[f[f[t>>2]+8>>2]](t,_+488|0,_+80|0,_+664|0),f[_+76>>2]=0,It=v(-Kt),Et=v(v(v(F*It)-v(V*m))-v(R*W)),o=v(Et+v(v(v(F*Tt)+v(V*z))+v(R*pt))),C[_+72>>2]=o,Nt=v(v(v(B*It)-v(p*m))-v(D*W)),g=v(Nt+v(v(v(B*Tt)+v(p*z))+v(D*pt))),C[_+68>>2]=g,W=v(v(v(G*It)-v(w*m))-v(y*W)),m=v(W+v(v(v(G*Tt)+v(w*z))+v(y*pt))),C[_+64>>2]=m,y=v(W+v(v(v(G*Dt)+v(w*Q))+v(y*Y))),G=m,y>2]=y,G=y),w=g,(p=v(Nt+v(v(v(B*Dt)+v(p*Q))+v(D*Y))))>2]=p,w=p),(D=v(Et+v(v(v(F*Dt)+v(V*Q))+v(R*Y))))<(V=o)&&(C[_+72>>2]=D,V=D),f[_+60>>2]=0,C[_+56>>2]=o,C[_+52>>2]=g,C[_+48>>2]=m,m>2]=y,m=y),g>2]=p,g=p),o>2]=D,o=D),C[_+64>>2]=C[_+80>>2]+G,C[_+68>>2]=C[_+84>>2]+w,C[_+72>>2]=C[_+88>>2]+V,C[_+48>>2]=C[_+664>>2]+m,C[_+52>>2]=C[_+668>>2]+g,C[_+56>>2]=C[_+672>>2]+o,yt[f[f[h>>2]+64>>2]](h,_+128|0,_- -64|0,_+48|0)}else if(31==(0|St)){Lr(_+40|0,20933),B=C[(St=d+52|0)>>2],F=C[(Gt=d+56|0)>>2],Q=C[e+52>>2],Y=C[e+56>>2],g=C[(xt=d+20|0)>>2],m=C[(Qt=d+36|0)>>2],W=C[e+20>>2],z=C[e+36>>2],pt=C[e+24>>2],y=C[(Wt=d+24|0)>>2],Dt=C[e+40>>2],p=C[(Yt=d+40|0)>>2],D=C[d+32>>2],G=C[d>>2],w=C[d+16>>2],Tt=C[e+32>>2],It=C[e>>2],Et=C[e+16>>2],Ot=C[d+48>>2],Nt=C[e+48>>2],V=C[d+4>>2],Ft=C[e+4>>2],Vt=C[e+8>>2],R=C[d+8>>2],f[(Pt=_+188|0)>>2]=0,f[(Mt=_+172|0)>>2]=0,f[(Zt=_+156|0)>>2]=0,C[(Ut=_+168|0)>>2]=v(v(R*Vt)+v(y*pt))+v(p*Dt),C[(Xt=_+164|0)>>2]=v(v(R*Ft)+v(y*W))+v(p*z),C[(Jt=_+152|0)>>2]=v(v(V*Vt)+v(g*pt))+v(m*Dt),C[(jt=_+148|0)>>2]=v(v(V*Ft)+v(g*W))+v(m*z),zt=_+184|0,Ot=v(-Ot),C[zt>>2]=v(v(v(R*Ot)-v(y*B))-v(p*F))+v(v(v(R*Nt)+v(y*Q))+v(p*Y)),C[(Ht=_+180|0)>>2]=v(v(v(V*Ot)-v(g*B))-v(m*F))+v(v(v(V*Nt)+v(g*Q))+v(m*Y)),f[_+140>>2]=0,C[_+160>>2]=v(v(R*It)+v(y*Et))+v(p*Tt),C[_+144>>2]=v(v(V*It)+v(g*Et))+v(m*Tt),C[_+136>>2]=v(v(G*Vt)+v(w*pt))+v(D*Dt),C[_+176>>2]=v(v(v(G*Ot)-v(w*B))-v(D*F))+v(v(v(G*Nt)+v(w*Q))+v(D*Y)),C[_+132>>2]=v(v(G*Ft)+v(w*W))+v(D*z),C[_+128>>2]=v(v(G*It)+v(w*Et))+v(D*Tt),yt[f[f[t>>2]+8>>2]](t,_+128|0,_- -64|0,_+48|0),B=C[St>>2],F=C[Gt>>2],Q=C[i+52>>2],Y=C[i+56>>2],g=C[xt>>2],m=C[Qt>>2],W=C[i+20>>2],z=C[i+36>>2],pt=C[i+24>>2],y=C[Wt>>2],Dt=C[i+40>>2],p=C[Yt>>2],D=C[d+32>>2],G=C[d>>2],w=C[d+16>>2],Tt=C[i+32>>2],It=C[i>>2],Et=C[i+16>>2],Ot=C[d+48>>2],Nt=C[i+48>>2],V=C[d+4>>2],Ft=C[i+4>>2],Vt=C[i+8>>2],R=C[d+8>>2],f[Pt>>2]=0,f[Mt>>2]=0,f[Zt>>2]=0,C[Ut>>2]=v(v(R*Vt)+v(y*pt))+v(p*Dt),C[Xt>>2]=v(v(R*Ft)+v(y*W))+v(p*z),C[Jt>>2]=v(v(V*Vt)+v(g*pt))+v(m*Dt),C[jt>>2]=v(v(V*Ft)+v(g*W))+v(m*z),Ot=v(-Ot),C[zt>>2]=v(v(v(R*Ot)-v(y*B))-v(p*F))+v(v(v(R*Nt)+v(y*Q))+v(p*Y)),C[Ht>>2]=v(v(v(V*Ot)-v(g*B))-v(m*F))+v(v(v(V*Nt)+v(g*Q))+v(m*Y)),f[_+140>>2]=0,C[_+160>>2]=v(v(R*It)+v(y*Et))+v(p*Tt),C[_+144>>2]=v(v(V*It)+v(g*Et))+v(m*Tt),C[_+136>>2]=v(v(G*Vt)+v(w*pt))+v(D*Dt),C[_+176>>2]=v(v(v(G*Ot)-v(w*B))-v(D*F))+v(v(v(G*Nt)+v(w*Q))+v(D*Y)),C[_+132>>2]=v(v(G*Ft)+v(w*W))+v(D*z),C[_+128>>2]=v(v(G*It)+v(w*Et))+v(D*Tt),yt[f[f[t>>2]+8>>2]](t,_+128|0,_+24|0,_+8|0),(g=C[_+24>>2])>2]&&(C[_+64>>2]=g),(g=C[_+28>>2])>2]&&(C[_+68>>2]=g),(g=C[_+32>>2])>2]&&(C[_+72>>2]=g),(g=C[_+36>>2])>2]&&(C[_+76>>2]=g),g=C[_+8>>2],C[_+48>>2]>2]=g),g=C[_+12>>2],C[_+52>>2]>2]=g),g=C[_+16>>2],C[_+56>>2]>2]=g),g=C[_+20>>2],C[_+60>>2]>2]=g),f[_+520>>2]=a,f[_+516>>2]=d,C[_+508>>2]=o,f[_+504>>2]=i,f[_+500>>2]=e,f[_+496>>2]=t,f[_+492>>2]=r,f[_+488>>2]=22152,f[_+512>>2]=h;e:{if(!(t=f[h+68>>2])){if(f[h+20>>2]<1)break e;for(r=64,e=1;;){if(t=f[h+28>>2]+r|0,i=f[t>>2],o=C[t+-16>>2],g=C[t+-12>>2],m=C[t+-8>>2],y=C[t+-64>>2],p=C[t+-48>>2],D=C[t+-32>>2],G=C[t+-60>>2],w=C[t+-44>>2],V=C[t+-28>>2],R=C[t+-56>>2],B=C[t+-40>>2],F=C[t+-24>>2],f[_+188>>2]=0,f[_+172>>2]=0,f[_+156>>2]=0,f[_+140>>2]=0,Q=C[d+32>>2],Y=C[d+36>>2],W=C[d+40>>2],C[_+168>>2]=v(v(R*Q)+v(B*Y))+v(F*W),C[_+164>>2]=v(v(G*Q)+v(w*Y))+v(V*W),C[_+160>>2]=v(v(y*Q)+v(p*Y))+v(D*W),z=C[d+16>>2],pt=C[d+20>>2],Dt=C[d+24>>2],C[_+152>>2]=v(v(R*z)+v(B*pt))+v(F*Dt),C[_+148>>2]=v(v(G*z)+v(w*pt))+v(V*Dt),C[_+144>>2]=v(v(y*z)+v(p*pt))+v(D*Dt),Tt=R,R=C[d>>2],It=B,B=C[d+4>>2],Et=F,F=C[d+8>>2],C[_+136>>2]=v(v(Tt*R)+v(It*B))+v(Et*F),C[_+132>>2]=v(v(G*R)+v(w*B))+v(V*F),C[_+128>>2]=v(v(y*R)+v(p*B))+v(D*F),C[_+184>>2]=v(v(v(o*Q)+v(g*Y))+v(m*W))+C[d+56>>2],C[_+180>>2]=v(v(v(o*z)+v(g*pt))+v(m*Dt))+C[d+52>>2],C[_+176>>2]=v(v(v(o*R)+v(g*B))+v(m*F))+C[d+48>>2],f[_+84>>2]=1065353216,f[_+88>>2]=1,f[_+92>>2]=-1,t=e+-1|0,f[_+100>>2]=t,a=f[_+520>>2],f[_+96>>2]=a,f[_+80>>2]=22368,f[_+84>>2]=f[a+4>>2],f[_+684>>2]=t,f[_+680>>2]=-1,f[_+668>>2]=i,t=f[_+492>>2],f[_+664>>2]=t,f[_+672>>2]=f[t+8>>2],f[_+676>>2]=_+128,Bf(f[_+496>>2],f[_+500>>2],f[_+504>>2],_+664|0,_+80|0,C[_+508>>2]),(0|e)>=f[h+20>>2])break e;r=r+80|0,e=e+1|0,d=f[_+516>>2]}}i=f[(e=_+72|0)+4>>2],f[(r=_+136|0)>>2]=f[e>>2],f[r+4>>2]=i,i=f[(e=_+56|0)+4>>2],f[(r=_+152|0)>>2]=f[e>>2],f[r+4>>2]=i,e=f[_+52>>2],f[_+144>>2]=f[_+48>>2],f[_+148>>2]=e,e=f[_+68>>2],f[_+128>>2]=f[_+64>>2],f[_+132>>2]=e,Wi(t,f[t>>2],_+128|0,_+488|0)}qr()}Z=_+688|0}function _f(t,e,i,r,n,a){var o,_,h=0,d=0,g=0,m=0,y=0,p=0,R=v(0),D=v(0),B=0,F=v(0),V=v(0),G=v(0),w=v(0),Q=0,W=v(0),Y=0,z=v(0),pt=0,Dt=0,It=v(0);Z=o=Z-400|0,Lr(o+392|0,20953),h=f[(g=m=i+8|0)+4>>2],f[(B=o+336|0)>>2]=f[g>>2],f[B+4>>2]=h,y=f[(h=B=i+24|0)+4>>2],f[(g=o+352|0)>>2]=f[h>>2],f[g+4>>2]=y,p=f[(g=i+40|0)+4>>2],f[(h=o+368|0)>>2]=f[g>>2],f[h+4>>2]=p,Y=f[(h=i+56|0)+4>>2],f[(y=o+384|0)>>2]=f[h>>2],f[y+4>>2]=Y,Q=f[(y=r+8|0)+4>>2],f[(p=o+272|0)>>2]=f[y>>2],f[p+4>>2]=Q,p=f[i+4>>2],f[o+328>>2]=f[i>>2],f[o+332>>2]=p,p=f[i+20>>2],f[o+344>>2]=f[i+16>>2],f[o+348>>2]=p,p=f[i+36>>2],f[o+360>>2]=f[i+32>>2],f[o+364>>2]=p,p=f[i+52>>2],f[o+376>>2]=f[i+48>>2],f[o+380>>2]=p,p=f[r+4>>2],f[o+264>>2]=f[r>>2],f[o+268>>2]=p,d=f[(p=r+24|0)+4>>2],f[(Y=o+288|0)>>2]=f[p>>2],f[Y+4>>2]=d,pt=f[(d=Y=r+40|0)+4>>2],f[(Q=o+304|0)>>2]=f[d>>2],f[Q+4>>2]=pt,Dt=f[(Q=r+56|0)+4>>2],f[(d=o+320|0)>>2]=f[Q>>2],f[d+4>>2]=Dt,d=f[r+20>>2],f[o+280>>2]=f[r+16>>2],f[o+284>>2]=d,d=f[r+36>>2],f[o+296>>2]=f[r+32>>2],f[o+300>>2]=d,d=f[r+52>>2],f[o+312>>2]=f[r+48>>2],f[o+316>>2]=d,Mi(o+328|0,o+264|0,o,o+248|0),f[o+228>>2]=0,R=C[o+248>>2],C[o+224>>2]=R*C[o+8>>2],C[o+220>>2]=R*C[o+4>>2],C[o+216>>2]=R*C[o>>2],f[(d=o+208|0)>>2]=0,f[d+4>>2]=0,f[o+200>>2]=0,f[o+204>>2]=0,f[(d=o+56|0)>>2]=0,f[d+4>>2]=0,f[(d=o+48|0)>>2]=0,f[d+4>>2]=0,tt(o+328|0,o+248|0),f[(d=o+44|0)>>2]=0,f[(pt=o+28|0)>>2]=0,R=C[o+248>>2],D=C[o+252>>2],F=C[o+256>>2],G=C[o+260>>2],V=v(v(2)/v(v(v(v(R*R)+v(D*D))+v(F*F))+v(G*G))),z=v(F*V),w=v(D*z),W=v(R*V),It=v(G*W),C[o+36>>2]=w+It,C[(Dt=o+24|0)>>2]=w-It,w=v(R*W),W=D,D=v(D*V),V=v(W*D),C[o+40>>2]=v(1)-v(w+V),F=v(F*z),C[o+20>>2]=v(1)-v(w+F),f[o+12>>2]=0,w=v(R*z),W=v(G*D),C[o+32>>2]=w-W,R=v(R*D),D=v(G*z),C[o+16>>2]=R+D,C[o+8>>2]=w+W,C[o+4>>2]=R-D,C[o>>2]=v(1)-v(V+F),RA(e,o,o+200|0,o+216|0,o+248|0,o+232|0),_=f[m+4>>2],f[d>>2]=f[m>>2],f[d+4>>2]=_,d=f[i+20>>2],f[(m=o+52|0)>>2]=f[i+16>>2],f[m+4>>2]=d,d=f[B+4>>2],f[(m=o+60|0)>>2]=f[B>>2],f[m+4>>2]=d,B=f[i+36>>2],f[(m=o+68|0)>>2]=f[i+32>>2],f[m+4>>2]=B,B=f[g+4>>2],f[(m=o+76|0)>>2]=f[g>>2],f[m+4>>2]=B,g=f[i+52>>2],f[(m=o+84|0)>>2]=f[i+48>>2],f[m+4>>2]=g,d=f[h+4>>2],f[(g=B=o+92|0)>>2]=f[h>>2],f[g+4>>2]=d,h=f[y+4>>2],f[(g=o+108|0)>>2]=f[y>>2],f[g+4>>2]=h,f[o>>2]=22756,g=f[i+4>>2],f[o+36>>2]=f[i>>2],f[o+40>>2]=g,i=f[r+4>>2],f[o+100>>2]=f[r>>2],f[o+104>>2]=i,h=f[r+52>>2],f[(i=o+148|0)>>2]=f[r+48>>2],f[i+4>>2]=h,y=f[Q+4>>2],f[(h=g=o+156|0)>>2]=f[Q>>2],f[h+4>>2]=y,y=f[p+4>>2],f[(h=o+124|0)>>2]=f[p>>2],f[h+4>>2]=y,y=f[r+20>>2],f[(h=o+116|0)>>2]=f[r+16>>2],f[h+4>>2]=y,y=f[Y+4>>2],f[(h=o+140|0)>>2]=f[Y>>2],f[h+4>>2]=y,y=f[r+36>>2],f[(h=o+132|0)>>2]=f[r+32>>2],f[h+4>>2]=y,f[o+184>>2]=n,C[o+188>>2]=a,f[o+192>>2]=e,R=C[o+88>>2],D=C[o+152>>2],a=C[m>>2],G=C[i>>2],F=C[B>>2],V=C[g>>2],f[o+180>>2]=t,a=v(G-a),R=v(D-R),D=v(V-F),G=v(v(1)/v(E(v(v(v(a*a)+v(R*R))+v(D*D))))),z=(F=v(D*G))==v(0)?v(0xde0b6b000000000):v(v(1)/F),f[pt>>2]=z>2]=w>2]=z,C[o+8>>2]=w,W=a,a=v(a*G),C[o+32>>2]=v(D*F)+v(v(W*a)+v(R*V)),a=a==v(0)?v(0xde0b6b000000000):v(v(1)/a),C[o+4>>2]=a,f[o+20>>2]=a>2],yt[f[f[t>>2]+24>>2]](t,o+376|0,o+312|0,o,o+248|0,o+232|0),qr(),Z=o+400|0}function mf(t){t|=0;var e,i=0,r=0,a=0,o=v(0),h=0,d=0,g=0,m=0,y=0,p=v(0),R=0,D=0,B=v(0),E=v(0),F=v(0),V=v(0),G=0;if(Z=e=Z-192|0,yt[f[f[t>>2]+20>>2]](t)){if(r=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[r>>2]+100>>2]](r),r=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[r>>2]+8>>2]](e+80|0,r),r=0|yt[f[f[t>>2]+20>>2]](t),8&yt[f[f[r>>2]+56>>2]](r)&&((r=f[t+24>>2])&&!((0|(m=0|yt[f[f[r>>2]+36>>2]](r)))<1)))for(R=e+176|0,r=0;;){if(h=f[t+24>>2],h=0|yt[f[f[h>>2]+40>>2]](h,r),(0|(g=f[h+780>>2]))>=1)for(h=h+160|0;y=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[y>>2]+40>>2]](y,h+-124|0,h+-92|0,C[h+-76>>2],f[h>>2],R),h=h+192|0,g=g+-1|0;);if((0|m)==(0|(r=r+1|0)))break}if(r=0|yt[f[f[t>>2]+20>>2]](t),!(!(3&yt[f[f[r>>2]+56>>2]](r))|f[t+8>>2]<1))for(g=e+160|0,m=e+96|0,R=e+112|0,y=e+128|0,D=e+144|0,h=0;;){if(r=f[f[t+16>>2]+h>>2],!(32&_[r+204|0])){if(yt[f[f[t>>2]+20>>2]](t)&&(i=0|yt[f[f[t>>2]+20>>2]](t),1&yt[f[f[i>>2]+56>>2]](i))){f[e+72>>2]=1053609165,f[e+76>>2]=0,f[e+64>>2]=1053609165,f[e+68>>2]=1053609165;t:if((i=f[r+220>>2]+-1|0)>>>0<=4){switch(i-1|0){default:d=f[(a=e+88|0)+4>>2],f[(i=e+72|0)>>2]=f[a>>2],f[i+4>>2]=d,i=f[e+84>>2],f[e+64>>2]=f[e+80>>2],f[e+68>>2]=i;break t;case 0:d=f[(a=m+8|0)+4>>2],f[(i=e+72|0)>>2]=f[a>>2],f[i+4>>2]=d,i=f[m+4>>2],f[e+64>>2]=f[m>>2],f[e+68>>2]=i;break t;case 1:d=f[(a=R+8|0)+4>>2],f[(i=e+72|0)>>2]=f[a>>2],f[i+4>>2]=d,i=f[R+4>>2],f[e+64>>2]=f[R>>2],f[e+68>>2]=i;break t;case 2:d=f[(a=y+8|0)+4>>2],f[(i=e+72|0)>>2]=f[a>>2],f[i+4>>2]=d,i=f[y+4>>2],f[e+64>>2]=f[y>>2],f[e+68>>2]=i;break t;case 3:}d=f[(a=D+8|0)+4>>2],f[(i=e+72|0)>>2]=f[a>>2],f[i+4>>2]=d,i=f[D+4>>2],f[e+64>>2]=f[D>>2],f[e+68>>2]=i}else f[e+72>>2]=1050253722,f[e+76>>2]=0,f[e+64>>2]=1050253722,f[e+68>>2]=1050253722;1&n[r+205|0]&&(d=f[(a=r+316|0)+4>>2],f[(i=e+72|0)>>2]=f[a>>2],f[i+4>>2]=d,i=f[r+312>>2],f[e+64>>2]=f[r+308>>2],f[e+68>>2]=i),yt[f[f[t>>2]+28>>2]](t,r+4|0,f[r+192>>2],e- -64|0)}(i=f[t+72>>2])&&2&yt[f[f[i>>2]+56>>2]](i)&&(d=f[(a=g+8|0)+4>>2],f[(i=e+40|0)>>2]=f[a>>2],f[i+4>>2]=d,i=f[g+4>>2],f[e+32>>2]=f[g>>2],f[e+36>>2]=i,i=f[r+192>>2],yt[f[f[i>>2]+8>>2]](i,r+4|0,e- -64|0,e+48|0),o=C[744],C[e+64>>2]=C[e+64>>2]-o,C[e+68>>2]=C[e+68>>2]-o,C[e+72>>2]=C[e+72>>2]-o,C[e+48>>2]=o+C[e+48>>2],C[e+52>>2]=o+C[e+52>>2],C[e+56>>2]=o+C[e+56>>2],3&_[r+204|0]|!_[t+44|0]|2!=f[r+252>>2]||(i=f[r+192>>2],yt[f[f[i>>2]+8>>2]](i,r+68|0,e+16|0,e),p=v(C[e+16>>2]-o),C[e+16>>2]=p,B=v(C[e+20>>2]-o),C[e+20>>2]=B,E=v(C[e+24>>2]-o),C[e+24>>2]=E,F=v(o+C[e>>2]),C[e>>2]=F,V=v(o+C[e+4>>2]),C[e+4>>2]=V,o=v(o+C[e+8>>2]),C[e+8>>2]=o,p>2]&&(C[e+64>>2]=p),B>2]&&(C[e+68>>2]=B),E>2]&&(C[e+72>>2]=E),(p=C[e+28>>2])>2]&&(C[e+76>>2]=p),C[e+48>>2]>2]=F),C[e+52>>2]>2]=V),C[e+56>>2]>2]=o),o=C[e+12>>2],C[e+60>>2]>2]=o)),r=f[t+72>>2],yt[f[f[r>>2]+60>>2]](r,e- -64|0,e+48|0,e+32|0))}if(h=h+4|0,!((0|(G=G+1|0))>2]))break}}Z=e+192|0}function Rf(t,e){var i,r=0,a=0,o=0,h=0,d=0,C=0;if(Z=i=Z-96|0,n[i+52|0]=1,f[i+48>>2]=0,n[i+72|0]=1,f[(r=i+40|0)>>2]=0,f[r+4>>2]=0,f[i+68>>2]=0,n[i+92|0]=1,f[(r=i+60|0)>>2]=0,f[r+4>>2]=0,f[i+88>>2]=0,f[(r=i+80|0)>>2]=0,f[r+4>>2]=0,f[i+28>>2]=0,n[i+32|0]=1,f[i+20>>2]=0,f[i+24>>2]=0,!((0|(r=f[t+8>>2]))<1)){for(;;){h=f[f[f[t+16>>2]+(C<<2)>>2]+192>>2],f[i+12>>2]=h,o=m((o=h+(h<<15^-1)|0)>>>10^o,9);t:{e:if(!((d=d+-1&((o=((o^=o>>>6)<<11^-1)+o|0)>>>16^o))>>>0>=a>>>0)&&(a=f[f[i+28>>2]+(d<<2)>>2],-1!=(0|a))){for(d=f[i+48>>2],o=f[i+88>>2];;){if(f[o+(a<<3)>>2]!=(0|h)){if(-1!=(0|(a=f[d+(a<<2)>>2])))continue;break e}break}if(f[i+68>>2]+(a<<2))break t}f[i>>2]=h,Qf(i+16|0,i,i+12|0),a=f[i+12>>2],yt[f[f[a>>2]+60>>2]](a,e),r=f[t+8>>2]}if(!((0|(C=C+1|0))<(0|r)))break;a=f[i+20>>2],d=f[i+64>>2]}if(!((0|r)<1))for(a=0,h=0;C=f[f[t+16>>2]+a>>2],1!=(0|(d=f[C+252>>2]))&&64!=(0|d)||(yt[f[f[C>>2]+24>>2]](C,e),r=f[t+8>>2]),a=a+4|0,(0|(h=h+1|0))<(0|r););}(t=f[i+88>>2])&&(_[i+92|0]&&CA(t),f[i+88>>2]=0),f[i+88>>2]=0,n[i+92|0]=1,f[i+80>>2]=0,f[i+84>>2]=0,(t=f[i+68>>2])&&(_[i+72|0]&&CA(t),f[i+68>>2]=0),f[i+68>>2]=0,n[i+72|0]=1,f[i+60>>2]=0,f[i+64>>2]=0,(t=f[i+48>>2])&&(_[i+52|0]&&CA(t),f[i+48>>2]=0),f[i+48>>2]=0,n[i+52|0]=1,f[i+40>>2]=0,f[i+44>>2]=0,(t=f[i+28>>2])&&(_[i+32|0]&&CA(t),f[i+28>>2]=0),Z=i+96|0}function Qf(t,e,i){var r=0,a=0,o=0,h=0,C=0,g=0,v=0,y=0,p=0;t:{if(r=f[e>>2],o=m((o=(r<<15^-1)+r|0)>>>10^o,9),!((v=(a=(o=((o^=o>>>6)<<11^-1)+o|0)>>>16^o)&(o=f[t+48>>2])+-1)>>>0>=d[t+4>>2])&&-1!=(0|(h=f[f[t+12>>2]+(v<<2)>>2])))for(a=f[t+72>>2];;){if((0|r)==f[a+(h<<3)>>2])break t;if(-1==(0|(h=f[f[t+32>>2]+(h<<2)>>2])))break}if((0|(r=y=f[t+44>>2]))==(0|o)&&!((0|(r=o))>=(0|(C=r?r<<1:1)))){if(C?(g=dA(C<<2),r=f[t+44>>2]):r=o,(0|r)>=1)for(h=0,a=r;f[h+g>>2]=f[f[t+52>>2]+h>>2],h=h+4|0,a=a+-1|0;);(a=f[t+52>>2])&&(_[t+56|0]&&(CA(a),r=f[t+44>>2]),f[t+52>>2]=0),f[t+52>>2]=g,f[t+48>>2]=C,n[t+56|0]=1}if(f[t+44>>2]=r+1,f[f[t+52>>2]+(r<<2)>>2]=f[i>>2],(0|(a=f[t- -64>>2]))==f[t+68>>2]&&!((0|a)>=(0|(i=a?a<<1:1)))){if(i?(g=dA(i<<3),a=f[t+64>>2]):g=0,(0|a)>=1)for(h=0;C=f[t+72>>2]+h|0,p=f[C+4>>2],f[(r=h+g|0)>>2]=f[C>>2],f[r+4>>2]=p,h=h+8|0,a=a+-1|0;);(r=f[t+72>>2])&&(_[t+76|0]&&CA(r),f[t+72>>2]=0),f[t+72>>2]=g,f[t+68>>2]=i,n[t+76|0]=1,a=f[t+64>>2]}return r=f[e+4>>2],i=f[t+72>>2]+(a<<3)|0,f[i>>2]=f[e>>2],f[i+4>>2]=r,f[t+64>>2]=f[t+64>>2]+1,(0|o)>2]&&(function(t){var e,i,r=0,a=0,o=0,h=0,d=0,C=0,g=0;if(!((0|(i=f[t+4>>2]))>=(0|(e=f[t+48>>2])))){if(f[t+8>>2]>=(0|e))r=f[t+12>>2];else{e?(r=dA(e<<2),o=f[t+4>>2]):o=i,d=f[t+12>>2];e:{if((0|o)>=1)for(h=r,a=d;f[h>>2]=f[a>>2],h=h+4|0,a=a+4|0,o=o+-1|0;);else if(!d)break e;_[t+16|0]&&CA(d)}f[t+12>>2]=r,n[t+16|0]=1,f[t+8>>2]=e}if(X((a=i<<2)+r|0,0,(C=e<<2)-a|0),f[t+4>>2]=e,(0|(g=f[t+24>>2]))<(0|e)){e:if(f[t+28>>2]>=(0|e))r=f[t+32>>2];else{if(e?(r=dA(C),o=f[t+24>>2]):(r=0,o=g),d=f[t+32>>2],(0|o)>=1)for(h=r,a=d;f[h>>2]=f[a>>2],h=h+4|0,a=a+4|0,o=o+-1|0;);else if(!d){f[t+32>>2]=r,f[t+28>>2]=e,n[t+36|0]=1;break e}_[t+36|0]&&CA(d),f[t+32>>2]=r,n[t+36|0]=1,f[t+28>>2]=e}X((a=g<<2)+r|0,0,C-a|0)}if(f[t+24>>2]=e,(0|e)>=1&&(X(f[t+12>>2],255,C),X(f[t+32>>2],255,C)),!((0|i)<1))for(h=f[t+32>>2],a=f[t+72>>2],d=f[t+12>>2],o=0;r=f[a>>2],r=m((r=(r<<15^-1)+r|0)>>>10^r,9),r=((r^=r>>>6)<<11^-1)+r|0,r=d+((f[t+48>>2]+-1&(r>>>16^r))<<2)|0,f[h>>2]=f[r>>2],f[r>>2]=o,a=a+8|0,h=h+4|0,(0|(o=o+1|0))!=(0|i););}}(t),e=f[e>>2],e=m((e=(e<<15^-1)+e|0)>>>10^e,9),e=((e^=e>>>6)<<11^-1)+e|0,v=f[t+48>>2]+-1&(e>>>16^e)),e=f[t+32>>2]+(y<<2)|0,t=f[t+12>>2]+(v<<2)|0,f[e>>2]=f[t>>2],void(f[t>>2]=y)}f[f[t+52>>2]+(h<<2)>>2]=f[i>>2]}function hf(t,e,i,r,n){t|=0,e|=0,i=v(i),r|=0,n|=0;var a,o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0);return Z=a=Z-48|0,f[a+44>>2]=n,f[a+40>>2]=r,d=C[t- -64>>2],g=C[t+60>>2],m=C[t+80>>2],y=C[t+72>>2],p=C[t+76>>2],R=C[t+96>>2],D=C[t+88>>2],B=C[t+92>>2],E=C[t+56>>2],o=C[e+8>>2],_=C[e>>2],h=C[e+4>>2],f[a+28>>2]=0,C[a+24>>2]=v(v(_*D)+v(h*B))+v(o*R),C[a+20>>2]=v(v(_*y)+v(h*p))+v(o*m),C[a+16>>2]=v(v(E*_)+v(g*h))+v(d*o),C[a+32>>2]=i,f[a+8>>2]=f[t+48>>2],f[a+12>>2]=a+40,t=f[t+44>>2],i=v(yt[f[f[t>>2]+12>>2]](t,a+8|0,1)),Z=a+48|0,v(i)}function Gf(t,e,i,r,n,a){t|=0,e|=0,i|=0,r=v(r),n|=0,a|=0;var o,_=0,h=0;return Z=o=Z+-64|0,f[o+60>>2]=a,f[o+56>>2]=n,n=f[t+212>>2],C[n+4>>2]>=r&&(h=f[(_=i+8|0)+4>>2],f[(a=o+40|0)>>2]=f[_>>2],f[a+4>>2]=h,h=f[(_=e+8|0)+4>>2],f[(a=o+24|0)>>2]=f[_>>2],f[a+4>>2]=h,a=f[i+4>>2],f[o+32>>2]=f[i>>2],f[o+36>>2]=a,i=f[e+4>>2],f[o+16>>2]=f[e>>2],f[o+20>>2]=i,C[o+48>>2]=r,f[o+8>>2]=f[t+216>>2],f[o+12>>2]=o+56,r=v(yt[f[f[n>>2]+12>>2]](n,o+8|0,1))),Z=o- -64|0,v(r)}function yf(t){var e;(e=f[t+12>>2])&&(_[t+16|0]&&CA(e),f[t+12>>2]=0),f[t+12>>2]=0,n[t+16|0]=1,f[t+4>>2]=0,f[t+8>>2]=0}function Ff(t,e,i,r){var a,o,h=0,d=0,C=0,g=0,m=0,v=0,y=0,p=0,R=0,D=0,B=0;if(Z=o=Z-16|0,function(t,e,i){var r,a,o=0,h=0,d=0,C=0,g=0,m=0,v=0,y=0,p=0,R=0,D=0,B=0;if(Z=r=Z-16|0,Lr(r+8|0,22924),(0|(o=f[t+28>>2]))<=-1)for(f[t+32>>2]<=-1&&((h=f[t+36>>2])&&(_[t+40|0]&&CA(h),f[t+36>>2]=0),f[t+32>>2]=0,f[t+36>>2]=0,n[t+40|0]=1),g=o<<2;f[f[t+36>>2]+g>>2]=0,g=g+4|0,d=(h=o+1|0)>>>0>=o>>>0,o=h,d;);if(f[t+28>>2]=0,function(t){var e,i,r=0,n=0,a=0,o=0,_=0,h=0;if(Z=i=Z-16|0,!((0|(e=f[t+4>>2]))<=0)){for(a=f[t+12>>2];;){if((0|(r=o))!=(0|(n=f[(_=(r<<3)+a|0)>>2])))for(h=_;r=(n<<3)+a|0,f[h>>2]=f[r>>2],(0|(r=f[r>>2]))!=(0|(n=f[(h=(r<<3)+a|0)>>2])););if(f[_>>2]=r,(0|e)==(0|(o=o+1|0)))break}(0|e)<2||function A(t,e,i,r){for(var n=0,a=0,o=0,_=0,h=0,d=0,C=0,g=0,m=0,v=0;;){for(g=i,h=f[t+12>>2],m=f[h+((i+r|0)/2<<3)>>2],o=i,_=r;;){for(a=((o<<3)+h|0)-8|0;o=o+1|0,f[(a=a+8|0)>>2]<(0|m););for(i=o+-1|0,n=8+(_<<3)|0;_=_+-1|0,d=n+h|0,n=C=n+-8|0,f[d+-8>>2]>(0|m););if((0|i)<=(0|(n=_+1|0))&&(v=f[a>>2],d=f[a+4>>2],i=f[(n=h+C|0)+4>>2],f[a>>2]=f[n>>2],f[a+4>>2]=i,i=f[t+12>>2]+C|0,f[i>>2]=v,f[i+4>>2]=d,n=_,i=o),!((0|i)<=(0|n)))break;h=f[t+12>>2],o=i,_=n}if((0|n)>(0|g)&&A(t,e,g,n),!((0|i)<(0|r)))break}}(t,i+8|0,0,e+-1|0)}Z=i+16|0}(t+4|0),(0|(a=f[t+8>>2]))>=1)for(h=0;;){for(d=h,o=(m=(C=f[t+16>>2])+(R=h<<3)|0)+8|0,v=f[m>>2];g=h,(0|(h=h+1|0))<(0|a)&&(y=f[o>>2],o=o+8|0,(0|v)==(0|y)););t:if(y=(0|d)>(0|g),!y){for(D=d+-1|0,o=m+4|0,B=f[i+16>>2],m=1;p=f[(f[o>>2]<<2)+B>>2],f[p+208>>2]==(0|v)&&(m&=4!=(0|(p=f[p+220>>2]))&1!=(0|p)),o=o+8|0,(0|(D=D+1|0))<(0|g););if(!(1&m)){if(y)break t;for(o=4|R;;){if(C=f[f[i+16>>2]+(f[o+C>>2]<<2)>>2],(0|v)!=f[C+208>>2]|2!=f[C+220>>2]||(Ye(C,3),f[C+224>>2]=0),(0|d)>=(0|g))break t;o=o+8|0,d=d+1|0,C=f[t+16>>2]}}if(!y)for(o=4|R;;){if(C=f[f[i+16>>2]+(f[o+C>>2]<<2)>>2],f[C+208>>2]==(0|v)&&Ye(C,2),(0|d)>=(0|g))break t;o=o+8|0,d=d+1|0,C=f[t+16>>2]}}if(!((0|h)<(0|a)))break}if((0|(m=0|yt[f[f[e>>2]+36>>2]](e)))>=1)for(g=0;;){v=0|yt[f[f[e>>2]+40>>2]](e,g),i=f[v+776>>2];t:{e:{i:{if(!(!(h=f[v+772>>2])|2==f[h+220>>2])){if(2&(d=f[h+204>>2]))break i;break e}if(!i|2==f[i+220>>2])break t;if(!(2&(d=f[h+204>>2]))|2==f[h+220>>2])break e}4&d||Ve(i,0)}if(!(2&(o=f[i+204>>2]))|4&o|2==f[i+220>>2]||Ve(h,0),_[t+64|0]&&yt[f[f[e>>2]+28>>2]](e,h,i)){if((0|(i=f[t+28>>2]))==f[t+32>>2]&&!((0|i)>=(0|(C=i?i<<1:1)))){if(C?(d=dA(C<<2),i=f[t+28>>2]):d=0,(0|i)>=1)for(o=0,h=i;f[o+d>>2]=f[f[t+36>>2]+o>>2],o=o+4|0,h=h+-1|0;);(h=f[t+36>>2])&&(_[t+40|0]&&(CA(h),i=f[t+28>>2]),f[t+36>>2]=0),f[t+36>>2]=d,n[t+40|0]=1,f[t+32>>2]=C}f[t+28>>2]=i+1,f[f[t+36>>2]+(i<<2)>>2]=v}}if((0|m)==(0|(g=g+1|0)))break}qr(),Z=r+16|0}(t,e,i),a=f[t+8>>2],Lr(o+8|0,22952),_[t+64|0]){if((0|(y=f[t+28>>2]))>=2&&function A(t,e,i,r){for(var n=0,a=0,o=0,_=0,h=0,d=0,C=0,g=0,m=0,v=0;;){for(m=i,a=f[t+12>>2],g=f[a+((i+r|0)/2<<2)>>2],n=r;;){if(_=(0|(d=f[f[g+772>>2]+208>>2]))<0)for(h=i+-1|0,o=((i<<2)+a|0)-4|0,C=f[f[g+776>>2]+208>>2];h=h+1|0,v=f[(o=o+4|0)>>2],(0|(i=f[f[v+772>>2]+208>>2]))<=-1&&(i=f[f[v+776>>2]+208>>2]),(0|i)<(0|C););else for(h=i+-1|0,o=((i<<2)+a|0)-4|0;h=h+1|0,C=f[(o=o+4|0)>>2],(0|(i=f[f[C+772>>2]+208>>2]))<=-1&&(i=f[f[C+776>>2]+208>>2]),(0|i)<(0|d););if(_){for(i=n+1|0,n=(n<<2)+a|0,d=f[f[g+776>>2]+208>>2];_=f[n>>2],(0|(a=f[f[_+772>>2]+208>>2]))<=-1&&(a=f[f[_+776>>2]+208>>2]),n=n+-4|0,i=i+-1|0,(0|d)<(0|a););n=n+4|0}else{for(i=n+1|0,n=(n<<2)+a|0;_=f[n>>2],(0|(a=f[f[_+772>>2]+208>>2]))<=-1&&(a=f[f[_+776>>2]+208>>2]),n=n+-4|0,i=i+-1|0,(0|d)<(0|a););n=n+4|0}if((0|h)>(0|i)?(n=i,i=h):(a=f[o>>2],f[o>>2]=f[n>>2],f[f[t+12>>2]+(i<<2)>>2]=a,n=i+-1|0,i=h+1|0),!((0|i)<=(0|n)))break;a=f[t+12>>2]}if((0|n)>(0|m)&&A(t,e,m,n),!((0|i)<(0|r)))break}}(t+24|0,o,0,y+-1|0),!((0|a)<1))for(D=1;;){e=f[t+16>>2],p=f[e+(g<<3)>>2],B=1;t:if(!((0|g)>=(0|a)))for(;;){if(m=f[f[i+16>>2]+(f[4+((g<<3)+e|0)>>2]<<2)>>2],(0|(h=f[t+48>>2]))==f[t+52>>2]&&!((0|h)>=(0|(v=h?h<<1:1)))){if(v?(d=dA(v<<2),h=f[t+48>>2]):d=0,(0|h)>=1)for(e=0,C=h;f[e+d>>2]=f[f[t+56>>2]+e>>2],e=e+4|0,C=C+-1|0;);(e=f[t+56>>2])&&(_[t+60|0]&&(CA(e),h=f[t+48>>2]),f[t+56>>2]=0),f[t+56>>2]=d,n[t+60|0]=1,f[t+52>>2]=v}if(f[t+48>>2]=h+1,f[f[t+56>>2]+(h<<2)>>2]=m,B&=5==(0|(e=f[m+220>>2]))|2==(0|e),(0|a)==(0|(g=g+1|0))){g=a;break t}if(e=f[t+16>>2],f[e+(g<<3)>>2]!=(0|p))break}if(m=0,e=0,!((0|R)>=(0|y))&&(v=f[t+36>>2],e=f[(h=v+(d=R<<2)|0)>>2],(0|(C=f[f[e+772>>2]+208>>2]))<=-1&&(C=f[f[e+776>>2]+208>>2]),e=0,(0|C)==(0|p))){for(e=4+(d+v|0)|0,d=1;m=d,!((0|(D=d+R|0))>=(0|y)||(d=f[e>>2],C=f[f[d+772>>2]+208>>2],(0|C)<=-1&&(C=f[f[d+776>>2]+208>>2]),e=e+4|0,d=m+1|0,(0|C)!=(0|p))););e=h}if(B||yt[f[f[r>>2]+8>>2]](r,f[t+56>>2],f[t+48>>2],e,m,p),(0|(e=f[t+48>>2]))<=-1)for(f[t+52>>2]<=-1&&((h=f[t+56>>2])&&(_[t+60|0]&&CA(h),f[t+56>>2]=0),n[t+60|0]=1,f[t+52>>2]=0,f[t+56>>2]=0),C=e<<2;f[f[t+56>>2]+C>>2]=0,C=C+4|0,d=(h=e+1|0)>>>0>=e>>>0,e=h,d;);if(R=m?D:R,f[t+48>>2]=0,!((0|g)<(0|a)))break}}else h=0|yt[f[f[e>>2]+44>>2]](e),t=0|yt[f[f[e>>2]+36>>2]](e),yt[f[f[r>>2]+8>>2]](r,f[i+16>>2],f[i+8>>2],h,t,-1);qr(),Z=o+16|0}function Wf(t){var e,i=0,r=0,n=0,a=0;if(s(t),255==(0|(r=(e=c(0))>>>23&255)))return t=v(t*v(6.2831854820251465)),v(t/t);if((i=e<<1)>>>0>2173837238){if(r)i=8388607&e|8388608;else{if(r=0,(0|(i=e<<9))>=0)for(;r=r+-1|0,(0|(i<<=1))>-1;);i=e<<1-r}if(a=(0|(n=i-13176795|0))>-1,(0|r)>129)for(;;){if(a&&!(i=n))return v(t*v(0));if(a=(0|(n=(i<<=1)-13176795|0))>-1,!((0|(r=r+-1|0))>129))break}if(a&&!(i=n))return v(t*v(0));if(i>>>0<=8388607)for(;r=r+-1|0,(i<<=1)>>>0<8388608;);return b(0,-2147483648&e|((0|r)>=1?i+-8388608|r<<23:i>>>1-r)),k()}return-2121130058==(0|i)?v(t*v(0)):t}function wf(t,e,i,r,n){var a=v(0);if(a=v(1),!(e>i)&&(a=v(0),e!=i)){if((r=v(r/n))=e^1|v(e-r)>t^1?v(tv(0)){if(!(t<=i^1|v(i-r)i?0:1)}}return a}function Df(t,e,i){t|=0;var r=0,n=0,a=0,o=0;if(a=e|=0,o=0|yt[f[f[(i|=0)>>2]+28>>2]](i,f[t+28>>2]),f[a>>2]=o,a=e,o=0|yt[f[f[i>>2]+28>>2]](i,f[t+32>>2]),f[a+4>>2]=o,r=0|yt[f[f[i>>2]+40>>2]](i,t),n=0|yt[f[f[i>>2]+28>>2]](i,r),f[e+8>>2]=n,n&&yt[f[f[i>>2]+48>>2]](i,r),f[e+12>>2]=f[t+4>>2],f[e+24>>2]=_[t+21|0],f[e+40>>2]=f[t+24>>2],f[e+44>>2]=f[t+16>>2],f[e+48>>2]=_[t+20|0],i=f[t+12>>2],r=f[t+40>>2],f[e+28>>2]=f[t+36>>2],f[e+32>>2]=r,f[e+20>>2]=i,r=0,f[e+36>>2]=0,f[e+16>>2]=f[t+8>>2],i=f[t+28>>2],(0|(n=f[i+548>>2]))>=1)for(i=f[i+556>>2];(0|t)==f[i>>2]&&(f[e+36>>2]=1),i=i+4|0,(0|(r=r+1|0))<(0|n););if(i=f[t+32>>2],(0|(n=f[i+548>>2]))>=1)for(i=f[i+556>>2],r=0;(0|t)==f[i>>2]&&(f[e+36>>2]=1),i=i+4|0,(0|(r=r+1|0))<(0|n););return 23056}function Ef(t){return f[(t|=0)>>2]=23012,0|t}function Zf(t,e,i,r){var n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),p=v(0);a=Cr(i),o=C[e+444>>2],i=dr(i),v(y(a))>v(1.1920928955078125e-7)?(n=v(i*i),d=v(a*a),_=v(n/d),h=C[e+448>>2],o=v(E(v(v(_+v(1))/v(v(v(1)/v(h*h))+v(_/v(o*o))))))):(n=v(i*i),d=v(a*a)),f[t+12>>2]=0,_=v(o*v(.5)),n=v(dr(_)/v(E(v(n+v(d+v(0)))))),i=v(i*n),o=v(n*v(0)),a=v(a*n),h=v(a*v(0)),g=v(i*v(-0)),d=v(v(v(-v(o*r))-h)-g),n=Cr(_),m=v(n*v(0)),p=v(o*v(0)),_=v(v(m+p)-v(a*r)),h=v(v(v(n*r)+h)-g),r=v(v(m-v(i*r))-p),C[t+8>>2]=v(v(v(i*d)+v(n*_))-v(h*a))+v(r*o),C[t+4>>2]=v(v(v(n*r)-v(d*a))-v(_*o))-v(i*h),C[t>>2]=v(v(i*r)+v(v(n*h)-v(d*o)))+v(_*a)}function Yf(t){var e=0,i=0,r=v(0),n=0;t:{e:{if(s(t),(i=2147483647&(n=c(0)))>>>0>=1065353216){if(1065353216!=(0|i))break e;return v(1.5707963267948966*+t+752316384526264e-51)}if(i>>>0<=1056964607){if(i+-8388608>>>0<956301312)break t;return r=v(t*t),v(v(v(v(r*v(v(r*v(v(r*v(-.008656363002955914))+v(-.04274342209100723)))+v(.16666586697101593)))/v(v(r*v(-.7066296339035034))+v(1)))*t)+t)}return t=v(v(v(1)-v(y(t)))*v(.5)),e=E(+t),e+=e*+v(v(t*v(v(t*v(v(t*v(-.008656363002955914))+v(-.04274342209100723)))+v(.16666586697101593)))/v(v(t*v(-.7066296339035034))+v(1))),t=v(1.5707963267948966-(e+e)),(0|n)<0?v(-t):t}t=v(v(0)/v(t-t))}return t}function Vf(t,e){return C[1192+((e<<2)+t|0)>>2]}function If(t){var e=0;return f[(t|=0)>>2]=23160,_[t+288|0]&&(e=f[t+220>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+220>>2])),(e=f[t+212>>2])&&(yt[f[f[e>>2]>>2]](e),CA(f[t+212>>2])),_[t+289|0]&&(e=f[t+216>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+216>>2])),(e=f[t+332>>2])&&(_[t+336|0]&&CA(e),f[t+332>>2]=0),f[t+332>>2]=0,f[t+324>>2]=0,f[t+328>>2]=0,n[t+336|0]=1,(e=f[t+304>>2])&&(_[t+308|0]&&CA(e),f[t+304>>2]=0),f[t+304>>2]=0,f[t+296>>2]=0,f[t+300>>2]=0,n[t+308|0]=1,(e=f[t+256>>2])&&(_[t+260|0]&&CA(e),f[t+256>>2]=0),f[t+256>>2]=0,f[t+248>>2]=0,f[t+252>>2]=0,n[t+260|0]=1,(e=f[t+236>>2])&&(_[t+240|0]&&CA(e),f[t+236>>2]=0),f[t+236>>2]=0,f[t+228>>2]=0,f[t+232>>2]=0,n[t+240|0]=1,(e=f[t+204>>2])&&(_[t+208|0]&&CA(e),f[t+204>>2]=0),f[t+204>>2]=0,f[t+196>>2]=0,f[t+200>>2]=0,n[t+208|0]=1,sf(t),0|t}function Jf(t,e){e|=0,yt[f[f[(t|=0)>>2]+64>>2]](t,e)}function xf(t,e){e|=0,yt[f[f[(t|=0)>>2]+68>>2]](t,e)}function Uf(t){var e,i,r,a=0,o=0,h=0,d=0,C=0;if(e=o=f[t+8>>2],(d=f[t+32>>2])&&(h=f[t+40>>2]),i=h,(h=f[t+52>>2])&&(a=f[t+60>>2]),r=a,C=0,(a=f[t+72>>2])&&(C=f[t+80>>2]),v(yt[f[f[o>>2]+12>>2]](e,i,d,r,h,C,a,f[t+4>>2],f[t+20>>2],f[t+24>>2])),(0|(a=f[t+32>>2]))<=-1)for(f[t+36>>2]<=-1&&((o=f[t+40>>2])&&(_[t+44|0]&&CA(o),f[t+40>>2]=0),f[t+36>>2]=0,f[t+40>>2]=0,n[t+44|0]=1),h=a<<2;f[f[t+40>>2]+h>>2]=0,h=h+4|0,d=(o=a+1|0)>>>0>=a>>>0,a=o,d;);if(f[t+32>>2]=0,(0|(a=f[t+52>>2]))<=-1)for(f[t+56>>2]<=-1&&((o=f[t+60>>2])&&(_[t- -64|0]&&CA(o),f[t+60>>2]=0),f[t+56>>2]=0,f[t+60>>2]=0,n[t- -64|0]=1),h=a<<2;f[f[t+60>>2]+h>>2]=0,h=h+4|0,d=(o=a+1|0)>>>0>=a>>>0,a=o,d;);if(f[t+52>>2]=0,(0|(a=f[t+72>>2]))<=-1)for(f[t+76>>2]<=-1&&((o=f[t+80>>2])&&(_[t+84|0]&&CA(o),f[t+80>>2]=0),f[t+76>>2]=0,f[t+80>>2]=0,n[t+84|0]=1),h=a<<2;f[f[t+80>>2]+h>>2]=0,h=h+4|0,d=(o=a+1|0)>>>0>=a>>>0,a=o,d;);f[t+72>>2]=0}function Mf(t,e){return e|=0,f[f[(t|=0)+236>>2]+(e<<2)>>2]}function Sf(t,e,i,r,n,a){var o,_=0,h=0,d=0,g=0,m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=0,V=v(0),G=v(0);if(Z=o=Z-272|0,h=f[(d=i+8|0)+4>>2],f[(_=o+216|0)>>2]=f[d>>2],f[_+4>>2]=h,h=f[(d=i+24|0)+4>>2],f[(_=o+232|0)>>2]=f[d>>2],f[_+4>>2]=h,h=f[(d=i+40|0)+4>>2],f[(_=o+248|0)>>2]=f[d>>2],f[_+4>>2]=h,g=f[(h=i+56|0)+4>>2],f[(_=d=o+264|0)>>2]=f[h>>2],f[_+4>>2]=g,g=f[(h=r+8|0)+4>>2],f[(_=o+152|0)>>2]=f[h>>2],f[_+4>>2]=g,h=f[(_=i)+4>>2],f[o+208>>2]=f[_>>2],f[o+212>>2]=h,h=f[_+20>>2],f[o+224>>2]=f[_+16>>2],f[o+228>>2]=h,h=f[_+36>>2],f[o+240>>2]=f[_+32>>2],f[o+244>>2]=h,h=f[_+52>>2],f[o+256>>2]=f[_+48>>2],f[o+260>>2]=h,_=f[r+4>>2],f[o+144>>2]=f[r>>2],f[o+148>>2]=_,g=f[(h=r+24|0)+4>>2],f[(_=o+168|0)>>2]=f[h>>2],f[_+4>>2]=g,g=f[(h=r+40|0)+4>>2],f[(_=o+184|0)>>2]=f[h>>2],f[_+4>>2]=g,F=f[(g=r+56|0)+4>>2],f[(_=o+200|0)>>2]=f[g>>2],f[_+4>>2]=F,h=f[r+20>>2],f[o+160>>2]=f[r+16>>2],f[o+164>>2]=h,h=f[r+36>>2],f[o+176>>2]=f[r+32>>2],f[o+180>>2]=h,h=f[r+52>>2],f[o+192>>2]=f[r+48>>2],f[o+196>>2]=h,f[o+108>>2]=0,C[o+104>>2]=C[_>>2]-C[d>>2],C[o+100>>2]=C[o+196>>2]-C[o+260>>2],C[o+96>>2]=C[o+192>>2]-C[o+256>>2],Mi(o+208|0,o+144|0,o+16|0,o+128|0),f[o+92>>2]=0,m=C[o+128>>2],C[o+88>>2]=m*C[o+24>>2],C[o+84>>2]=m*C[o+20>>2],C[o+80>>2]=m*C[o+16>>2],f[(_=o+72|0)>>2]=0,f[_+4>>2]=0,f[(_=o- -64|0)>>2]=0,f[_+4>>2]=0,tt(o+208|0,o+128|0),f[o+60>>2]=0,f[o+44>>2]=0,m=C[o+128>>2],y=C[o+132>>2],R=C[o+136>>2],E=C[o+140>>2],B=v(v(2)/v(v(v(v(m*m)+v(y*y))+v(R*R))+v(E*E))),V=v(R*B),p=v(y*V),D=v(m*B),G=v(E*D),C[o+52>>2]=p+G,C[o+40>>2]=p-G,p=v(m*D),D=y,y=v(y*B),B=v(D*y),C[o+56>>2]=v(1)-v(p+B),R=v(R*V),C[o+36>>2]=v(1)-v(p+R),f[o+28>>2]=0,p=v(m*V),D=v(E*y),C[o+48>>2]=p-D,m=v(m*y),y=v(E*V),C[o+32>>2]=m+y,C[o+24>>2]=p+D,C[o+20>>2]=m-y,C[o+16>>2]=v(1)-v(B+R),RA(e,o+16|0,o+96|0,o+80|0,o+128|0,o+112|0),f[t+328>>2]>=1)for(d=r+48|0,h=i+48|0,r=0,_=0;i=f[f[t+336>>2]+r>>2],yt[f[f[n>>2]+8>>2]](n,f[i+188>>2])&&(g=f[i+192>>2],F=i+4|0,yt[f[f[g>>2]+8>>2]](g,F,o+16|0,o+96|0),f[o+28>>2]=0,f[o+108>>2]=0,C[o+24>>2]=C[o+24>>2]+C[o+136>>2],C[o+20>>2]=C[o+20>>2]+C[o+132>>2],C[o+16>>2]=C[o+16>>2]+C[o+128>>2],C[o+96>>2]=C[o+96>>2]+C[o+112>>2],C[o+100>>2]=C[o+100>>2]+C[o+116>>2],C[o+104>>2]=C[o+104>>2]+C[o+120>>2],f[o+12>>2]=1065353216,Xf(h,d,o+16|0,o+96|0,o+12|0,o+80|0)&&gf(e,o+208|0,o+144|0,i,f[i+192>>2],F,n,a)),r=r+4|0,(0|(_=_+1|0))>2];);Z=o+272|0}function Xf(t,e,i,r,n,a){var o,_,h,d,g,m,y,p,R,D=v(0),B=v(0),E=v(0),F=v(0),V=0,G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),yt=v(0),pt=v(0),Dt=v(0),It=v(0);if(o=Z-16|0,E=C[r>>2],D=C[i>>2],G=v(v(E+D)*v(.5)),B=v(C[e>>2]-G),E=v(E-D),_=B>(z=v(E*v(.5))),h=B<(E=v(E*v(-.5))),D=C[r+4>>2],F=C[i+4>>2],w=v(v(D+F)*v(.5)),Q=v(C[e+4>>2]-w),D=v(D-F),d=Q<(Y=v(D*v(-.5))),g=Q>(yt=v(D*v(.5))),D=C[r+8>>2],F=C[i+8>>2],Dt=v(v(D+F)*v(.5)),W=v(C[e+8>>2]-Dt),D=v(D-F),V=0,!((i=h|_<<3|d<<1|g<<4|(e=W<(It=v(D*v(-.5))))<<2|(W>(pt=v(D*v(.5))))<<5)&(R=(r=(G=v(C[t>>2]-G))>z)<<3|(m=G>2]-w))yt)<<4|(t=(w=v(C[t+8>>2]-Dt))pt)<<5))){E=C[n>>2],f[(V=o+8|0)>>2]=0,f[V+4>>2]=0,f[o>>2]=0,f[o+4>>2]=0,Y=v(B-G);t:if(m){if(!((B=v(v(v(-G)-z)/Y))>=v(0))){B=v(0);break t}f[o+12>>2]=0,f[o+4>>2]=0,f[o+8>>2]=0,f[o>>2]=1065353216}else B=v(0),h&&(D=v(v(v(-G)-z)/Y),D>2]=0,f[V+4>>2]=0,f[o>>2]=0,f[o+4>>2]=1065353216;break t}d&&((D=v(v(v(-F)-yt)/Q))>2]=1065353216,f[t+4>>2]=0,f[o>>2]=0,f[o+4>>2]=0;break t}e&&((B=v(v(v(-w)-pt)/W))>2]=0,f[o+4>>2]=0,f[o+8>>2]=0,f[o>>2]=-1082130432;break t}_&&((D=v(v(z-G)/Y))>2]=0,f[t+4>>2]=0,f[o>>2]=0,f[o+4>>2]=-1082130432;break t}g&&((B=v(v(yt-F)/Q))>2]=-1082130432,f[t+4>>2]=0,f[o>>2]=0,f[o+4>>2]=0;break t}32&i&&((D=v(v(pt-w)/W))>2]=D,t=f[o+4>>2],f[a>>2]=f[o>>2],f[a+4>>2]=t,i=f[(e=o+8|0)+4>>2],f[(t=a+8|0)>>2]=f[e>>2],f[t+4>>2]=i,V=1)}return V}function Tf(t,e){var i,r=0,n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),p=v(0),R=0,D=0,B=v(0),F=0,V=v(0),G=0,w=0,Q=0,W=v(0),Y=0,z=0,yt=0,pt=0,Dt=0,It=0,St=0,Tt=0;if(Z=i=Z-80|0,r=t+256|0,n=C[e+12>>2],p=C[t+264>>2],h=C[e+8>>2],(C[t+268>>2]!=n|p!=h|C[t+260>>2]!=C[e+4>>2]||C[r>>2]!=C[e>>2])&&(d=C[t+260>>2],B=C[t+256>>2],a=C[e>>2],o=C[e+4>>2],(_=v(v(v(a*a)+v(o*o))+v(h*h)))>v(0)?(C[t+268>>2]=n,n=v(v(1)/v(E(_))),g=v(h*n),C[t+264>>2]=g,h=v(o*n),C[t+260>>2]=h,m=v(a*n),C[t+256>>2]=m):(f[r>>2]=0,f[r+4>>2]=0,f[(e=r+8|0)>>2]=0,f[e+4>>2]=0,h=v(0)),r=f[t+8>>2])){t:if((V=v(v(v(m*m)+v(h*h))+v(g*g)))!=v(0)&&(W=v(v(v(B*B)+v(d*d))+v(p*p)),W!=v(0)))if(n=v(v(1)/v(E(V))),_=v(g*n),C[t+264>>2]=_,a=v(h*n),C[t+260>>2]=a,o=v(m*n),C[t+256>>2]=o,n=v(v(1)/v(E(W))),p=v(p*n),h=v(d*n),g=v(B*n),n=v(v(p*_)+v(v(h*a)+v(g*o))),nv(.7071067690849304)){d=a,a=v(v(1)/v(E(v(v(a*a)+v(_*_))))),n=v(d*a),o=v(-v(_*a)),a=v(0),_=v(0);break t}n=v(v(1)/v(E(v(v(a*a)+v(o*o))))),o=v(o*n),a=v(-v(a*n)),n=v(0),_=v(0)}else n=v(n+v(1)),d=v(E(v(n+n))),m=v(v(1)/d),n=v(v(v(h*o)-v(g*a))*m),o=v(v(v(g*_)-v(p*o))*m),a=v(v(v(p*a)-v(h*_))*m),_=v(d*v(.5));F=f[(R=r+12|0)+4>>2],f[(e=D=i+24|0)>>2]=f[R>>2],f[e+4>>2]=F,G=f[(e=r+20|0)>>2],z=f[e+4>>2],yt=f[(e=r+36|0)>>2],pt=f[e+4>>2],w=f[(e=r+28|0)>>2],e=f[e+4>>2],F=f[(R=r+44|0)>>2],Dt=f[R+4>>2],It=f[r+4>>2],St=f[r+8>>2],Tt=f[(Y=r+60|0)+4>>2],f[(R=Q=i+72|0)>>2]=f[Y>>2],f[R+4>>2]=Tt,f[(R=i+56|0)>>2]=F,f[R+4>>2]=Dt,f[(F=i+40|0)>>2]=w,f[F+4>>2]=e,f[i+16>>2]=It,f[i+20>>2]=St,w=f[(r=r+52|0)+4>>2],f[(e=i)+64>>2]=f[r>>2],f[e+68>>2]=w,f[e+48>>2]=yt,f[e+52>>2]=pt,f[e+32>>2]=G,f[e+36>>2]=z,tt(e+16|0,e),g=C[e>>2],m=C[e+12>>2],d=C[e+8>>2],B=C[e+4>>2],p=v(v(v(v(_*g)-v(m*a))-v(d*o))+v(B*n)),h=v(v(v(v(_*m)+v(g*a))+v(B*o))+v(d*n)),V=v(v(v(v(_*d)-v(m*n))-v(B*a))+v(g*o)),n=v(v(v(v(_*B)-v(m*o))-v(g*n))+v(d*a)),a=v(v(2)/v(v(h*h)+v(v(V*V)+v(v(p*p)+v(n*n))))),o=v(V*a),g=v(p*o),_=v(n*a),m=v(h*_),C[D>>2]=g+m,f[e+60>>2]=0,f[e+44>>2]=0,d=v(n*o),a=v(p*a),B=v(h*a),C[e+52>>2]=d+B,C[F>>2]=d-B,a=v(p*a),n=v(n*_),C[R>>2]=v(1)-v(a+n),d=a,a=v(V*o),C[e+36>>2]=v(1)-v(d+a),f[e+28>>2]=0,C[e+48>>2]=g-m,_=v(p*_),o=v(h*o),C[e+32>>2]=_+o,C[e+20>>2]=_-o,G=f[D+4>>2],t=f[t+8>>2],f[(r=t+12|0)>>2]=f[D>>2],f[r+4>>2]=G,C[e+16>>2]=v(1)-v(n+a),r=f[e+20>>2],f[t+4>>2]=f[e+16>>2],f[t+8>>2]=r,D=f[e+36>>2],f[(r=t+20|0)>>2]=f[e+32>>2],f[r+4>>2]=D,D=f[F+4>>2],f[(r=t+28|0)>>2]=f[F>>2],f[r+4>>2]=D,f[t+304>>2]=f[t+304>>2]+1,D=f[e+52>>2],f[(r=t+36|0)>>2]=f[e+48>>2],f[r+4>>2]=D,D=f[R+4>>2],f[(r=t+44|0)>>2]=f[R>>2],f[r+4>>2]=D,D=f[Q+4>>2],f[(r=t+60|0)>>2]=f[Q>>2],f[r+4>>2]=D,r=f[e+68>>2],f[(t=t+52|0)>>2]=f[e+64>>2],f[t+4>>2]=r}Z=i+80|0}function jf(t,e){var i,r=0,a=0,o=0,h=0,d=0,g=0,m=0,y=0,p=0,R=v(0),D=v(0),B=0,E=v(0),F=v(0),V=v(0),G=0;if(Z=i=Z-96|0,r=f[t+12>>2],yt[f[f[r>>2]+8>>2]](r,f[t+8>>2]+4|0,i+80|0,i- -64|0),r=f[e+68>>2],yt[f[f[r>>2]+16>>2]](r,f[f[t+8>>2]+188>>2],i+80|0,i- -64|0,f[e+24>>2]),r=f[e+24>>2],yt[f[f[r>>2]+32>>2]](r,f[f[t+8>>2]+344>>2],e+28|0,r),e=f[t+8>>2],a=f[(r=e+52|0)+4>>2],f[t+132>>2]=f[r>>2],f[t+136>>2]=a,h=f[(a=e+60|0)+4>>2],f[(r=t+140|0)>>2]=f[a>>2],f[r+4>>2]=h,h=t+132|0,e=f[e+344>>2],!((0|yt[f[f[e>>2]+36>>2]](e))<1))for(p=t+200|0;;){if((0|(e=f[t+204>>2]))<=-1)for(f[t+208>>2]<=-1&&((r=f[t+212>>2])&&(_[t+216|0]&&CA(r),f[t+212>>2]=0),n[t+216|0]=1,f[t+208>>2]=0,f[t+212>>2]=0),a=e<<2;f[f[t+212>>2]+a>>2]=0,a=a+4|0,d=(r=e+1|0)>>>0>=e>>>0,e=r,d;);if(f[t+204>>2]=0,e=f[f[t+8>>2]+344>>2],r=f[12+(0|yt[f[f[e>>2]+28>>2]](e))>>2]+(m<<4)|0,e=f[f[r+4>>2]>>2],a=f[f[r>>2]>>2],!((4&_[a+204|0]?a:0)|(4&_[e+204|0]?e:0))&&yt[f[f[t>>2]+56>>2]](t,a,e)&&((e=f[r+8>>2])&&yt[f[f[e>>2]+16>>2]](e,p),!((0|(d=f[t+204>>2]))<1)))for(y=f[t+8>>2],o=f[t+212>>2],r=0;;){if(e=f[o+(r<<2)>>2],(0|(g=f[e+780>>2]))>=1)for(D=(0|y)==f[e+772>>2]?v(-1):v(1),e=e+84|0,E=v(-C[t+16>>2]),a=0;(R=C[e>>2])>2],V=C[e+-12>>2],C[t+132>>2]=v(v(R*v(D*C[e+-16>>2]))*v(.20000000298023224))+C[t+132>>2],C[t+136>>2]=v(v(R*v(D*V))*v(.20000000298023224))+C[t+136>>2],C[t+140>>2]=v(v(R*v(D*F))*v(.20000000298023224))+C[t+140>>2],G=1),e=e+192|0,(0|(a=a+1|0))<(0|g););if(!((0|(r=r+1|0))<(0|d)))break}if(m=m+1|0,e=f[f[t+8>>2]+344>>2],!((0|m)<(0|yt[f[f[e>>2]+36>>2]](e))))break}return m=f[(a=h+8|0)+4>>2],f[(e=i+56|0)>>2]=f[a>>2],f[e+4>>2]=m,t=f[t+8>>2],d=f[(a=t+12|0)+4>>2],f[(r=i+8|0)>>2]=f[a>>2],f[r+4>>2]=d,o=f[(y=p=t+28|0)+4>>2],f[(d=m=i+24|0)>>2]=f[y>>2],f[d+4>>2]=o,B=f[(g=y=t+44|0)+4>>2],f[(o=d=i+40|0)>>2]=f[g>>2],f[o+4>>2]=B,o=f[h+4>>2],h=f[h>>2],f[t+304>>2]=f[t+304>>2]+1,f[i+48>>2]=h,f[i+52>>2]=o,h=f[t+8>>2],f[i>>2]=f[t+4>>2],f[i+4>>2]=h,g=f[(o=h=t+20|0)+4>>2],f[i+16>>2]=f[o>>2],f[i+20>>2]=g,B=f[(o=t+36|0)+4>>2],f[i+32>>2]=f[o>>2],f[i+36>>2]=B,g=f[i+4>>2],f[t+4>>2]=f[i>>2],f[t+8>>2]=g,g=f[r+4>>2],f[a>>2]=f[r>>2],f[a+4>>2]=g,r=f[m+4>>2],f[p>>2]=f[m>>2],f[p+4>>2]=r,r=f[i+20>>2],f[h>>2]=f[i+16>>2],f[h+4>>2]=r,r=f[d+4>>2],f[y>>2]=f[d>>2],f[y+4>>2]=r,r=f[i+36>>2],f[o>>2]=f[i+32>>2],f[o+4>>2]=r,a=f[e+4>>2],f[(r=t+60|0)>>2]=f[e>>2],f[r+4>>2]=a,e=f[i+52>>2],f[(t=t+52|0)>>2]=f[i+48>>2],f[t+4>>2]=e,Z=i+96|0,G}function Of(t,e){var i=v(0),r=v(0),n=v(0),a=v(0),o=v(0),_=0,h=v(0),d=v(0),g=v(0),m=v(0),y=0,p=v(0);i=v(C[t+152>>2]-C[t+132>>2]),n=v(C[t+156>>2]-C[t+136>>2]),r=v(C[t+160>>2]-C[t+140>>2]),(h=v(E(v(v(v(i*i)+v(n*n))+v(r*r)))))>v(1.1920928955078125e-7)&&(g=C[e+8>>2],o=C[e>>2],m=C[e+4>>2],y=f[(e=t+132|0)+4>>2],f[(_=t+152|0)>>2]=f[e>>2],f[_+4>>2]=y,y=f[(e=e+8|0)+4>>2],f[(_=_+8|0)>>2]=f[e>>2],f[_+4>>2]=y,a=i,i=v(v(1)/h),d=a=v(a*i),p=v(a*o),a=v(n*i),r=v(r*i),i=v(v(p+v(a*m))+v(r*g)),i=v(i+i),d=n=v(d-v(o*i)),r=v(r-v(g*i)),i=v(a-v(m*i)),n=v(v(1)/v(E(v(v(r*r)+v(v(n*n)+v(i*i)))))),a=v(d*n),d=o,r=v(r*n),i=v(i*n),o=v(v(g*r)+v(v(o*a)+v(m*i))),C[t+152>>2]=v(h*v(a-v(d*o)))+C[t+152>>2],C[t+156>>2]=v(h*v(i-v(m*o)))+C[t+156>>2],C[t+160>>2]=v(h*v(r-v(g*o)))+C[t+160>>2])}function Hf(t,e,i){var r,n,a,o,h,d,g,m=0,y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),F=v(0),V=v(0),G=v(0),w=0,Q=0,W=v(0),Y=0,z=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0);for(Z=r=Z-240|0,f[(w=r+188|0)>>2]=0,f[w+4>>2]=0,f[(w=r+200|0)>>2]=0,f[w+4>>2]=0,f[r+196>>2]=1065353216,f[r+216>>2]=1065353216,y=C[i>>2],p=C[i+4>>2],R=C[i+8>>2],f[t+164>>2]=0,C[t+160>>2]=R+C[t+140>>2],C[t+156>>2]=p+C[t+136>>2],C[t+152>>2]=y+C[t+132>>2],f[r+180>>2]=0,f[r+184>>2]=0,f[r+176>>2]=1065353216,f[r+208>>2]=0,f[r+212>>2]=0,f[r+236>>2]=0,f[(i=r+228|0)>>2]=0,f[i+4>>2]=0,f[(i=r+220|0)>>2]=0,f[i+4>>2]=0,f[r+112>>2]=1065353216,f[(i=r+124|0)>>2]=0,f[i+4>>2]=0,f[r+116>>2]=0,f[r+120>>2]=0,f[r+132>>2]=1065353216,f[(i=r+136|0)>>2]=0,f[i+4>>2]=0,f[r+144>>2]=0,f[r+148>>2]=0,f[r+152>>2]=1065353216,f[r+172>>2]=0,f[(i=r+164|0)>>2]=0,f[i+4>>2]=0,f[(i=r+156|0)>>2]=0,f[i+4>>2]=0,n=t+152|0,a=t+132|0,g=r+48|0,o=r+16|0,h=r+160|0,d=r+224|0,i=-11,Dt=v(1);;){t:if(!((w=i+1|0)>>>0>>0)){i=f[a+4>>2],f[d>>2]=f[a>>2],f[d+4>>2]=i,i=f[n+4>>2],f[h>>2]=f[n>>2],f[h+4>>2]=i,Y=f[(m=i=a+8|0)+4>>2],f[(Q=d+8|0)>>2]=f[m>>2],f[Q+4>>2]=Y,Y=f[(Q=n+8|0)+4>>2],f[(m=h+8|0)>>2]=f[Q>>2],f[m+4>>2]=Y,It=C[t+132>>2],St=C[t+152>>2],Tt=C[t+136>>2],Et=C[t+156>>2],Ot=C[t+140>>2],Nt=C[t+160>>2],p=C[t+180>>2],D=C[t+176>>2],y=C[t+168>>2],R=C[t+172>>2],f[r+220>>2]=0,f[r+204>>2]=0,f[r+188>>2]=0,f[r+156>>2]=0,f[r+140>>2]=0,f[r+124>>2]=0,F=v(v(2)/v(v(v(v(y*y)+v(R*R))+v(D*D))+v(p*p))),B=v(D*F),V=v(R*B),W=v(y*F),G=v(p*W),C[r+212>>2]=V+G,z=v(y*B),F=v(R*F),pt=v(p*F),C[r+208>>2]=z-pt,C[r+200>>2]=V-G,V=v(y*F),p=v(p*B),C[r+192>>2]=V+p,C[r+184>>2]=z+pt,C[r+180>>2]=V-p,y=v(y*W),p=v(R*F),C[r+216>>2]=v(1)-v(y+p),R=y,y=v(D*B),C[r+196>>2]=v(1)-v(R+y),C[r+176>>2]=v(1)-v(p+y),y=C[t+184>>2],p=C[t+188>>2],D=C[t+192>>2],R=C[t+196>>2],B=v(v(2)/v(v(v(v(y*y)+v(p*p))+v(D*D))+v(R*R))),V=v(p*B),W=v(y*V),F=v(D*B),G=v(R*F),C[r+116>>2]=W-G,z=v(y*F),pt=v(R*V),C[r+120>>2]=z+pt,C[r+128>>2]=W+G,W=v(p*F),G=R,R=v(y*B),B=v(G*R),C[r+136>>2]=W-B,C[r+144>>2]=z-pt,C[r+148>>2]=W+B,p=v(p*V),D=v(D*F),C[r+112>>2]=v(1)-v(p+D),y=v(y*R),C[r+132>>2]=v(1)-v(y+D),C[r+152>>2]=v(1)-v(y+p),f[(m=o+24|0)>>2]=0,f[m+4>>2]=0,f[(m=o+16|0)>>2]=0,f[m+4>>2]=0,f[(m=o+8|0)>>2]=0,f[m+4>>2]=0,f[o>>2]=0,f[o+4>>2]=0,f[r+100>>2]=0,f[r+104>>2]=0,C[r+96>>2]=Ot-Nt,C[r+92>>2]=Tt-Et,C[r+88>>2]=It-St,f[r+80>>2]=0,f[r+4>>2]=1065353216,f[r>>2]=24320,m=f[t+8>>2],f[r+84>>2]=m,m=f[m+188>>2],Y=f[m+8>>2],f[r+8>>2]=f[m+4>>2],f[r+12>>2]=Y,m=f[t+12>>2],y=v(yt[f[f[m>>2]+48>>2]](m)),m=f[t+12>>2],yt[f[f[m>>2]+44>>2]](m,v(y+C[t+64>>2])),(C[r+176>>2]!=C[r+112>>2]|C[r+192>>2]!=C[r+128>>2]|C[r+208>>2]!=C[r+144>>2]|C[r+180>>2]!=C[r+116>>2]||C[r+196>>2]!=C[r+132>>2]|C[r+212>>2]!=C[r+148>>2]|C[r+184>>2]!=C[r+120>>2]|C[r+200>>2]!=C[r+136>>2]||C[r+216>>2]!=C[r+152>>2]|C[r+236>>2]!=C[r+172>>2]|C[r+232>>2]!=C[r+168>>2]|C[r+228>>2]!=C[r+164>>2]||C[r+224>>2]!=C[r+160>>2])&&(_[t+250|0]?Sf(f[t+8>>2],f[t+12>>2],r+176|0,r+112|0,r,C[e+56>>2]):_f(e,f[t+12>>2],r+176|0,r+112|0,r,C[e+56>>2])),m=f[t+12>>2],yt[f[f[m>>2]+44>>2]](m,y);e:{if((y=C[r+4>>2])>2],!(4&_[m+204|0])&&yt[f[f[t>>2]+56>>2]](t,m,f[r+80>>2]))){if(Of(t,g),p=v(C[t+152>>2]-C[t+132>>2]),R=v(C[t+156>>2]-C[t+136>>2]),D=v(C[t+160>>2]-C[t+140>>2]),!((B=v(v(v(p*p)+v(R*R))+v(D*D)))>v(1.1920928955078125e-7)))break t;if(G=p,p=v(v(1)/v(E(B))),!(v(v(v(v(G*p)*C[t+84>>2])+v(v(R*p)*C[t+88>>2]))+v(v(D*p)*C[t+92>>2]))<=v(0)))break e;break t}m=f[n+4>>2],f[a>>2]=f[n>>2],f[a+4>>2]=m,m=f[Q+4>>2],f[i>>2]=f[Q>>2],f[i+4>>2]=m}if(i=w,(Dt=v(Dt-y))>v(.009999999776482582))continue}break}Z=r+240|0}function zf(t){return 0|yt[f[f[(t|=0)>>2]+48>>2]](t)}function Pf(t,e,i,r,o,_){var h=0;return function(t,e,i){f[t+44>>2]=0,f[t+36>>2]=0,f[t+40>>2]=1028443341,f[t+32>>2]=i,f[t+28>>2]=e,f[t+24>>2]=-1,a[t+20>>1]=1,f[t+16>>2]=2139095039,f[t+8>>2]=-1,f[t+12>>2]=-1,f[t>>2]=23012,f[t+4>>2]=12}(t,e,i),f[t>>2]=24404,h=f[(i=r+8|0)+4>>2],f[(e=t+56|0)>>2]=f[i>>2],f[e+4>>2]=h,e=f[r+4>>2],f[t+48>>2]=f[r>>2],f[t+52>>2]=e,h=f[(i=r+24|0)+4>>2],f[(e=t+72|0)>>2]=f[i>>2],f[e+4>>2]=h,i=f[r+20>>2],f[(e=t- -64|0)>>2]=f[r+16>>2],f[e+4>>2]=i,h=f[(i=r+40|0)+4>>2],f[(e=t+88|0)>>2]=f[i>>2],f[e+4>>2]=h,i=f[r+36>>2],f[(e=t+80|0)>>2]=f[r+32>>2],f[e+4>>2]=i,h=f[(i=r+56|0)+4>>2],f[(e=t+104|0)>>2]=f[i>>2],f[e+4>>2]=h,i=f[r+52>>2],f[(e=t+96|0)>>2]=f[r+48>>2],f[e+4>>2]=i,r=f[(i=o+8|0)+4>>2],f[(e=t+120|0)>>2]=f[i>>2],f[e+4>>2]=r,e=f[o+4>>2],f[t+112>>2]=f[o>>2],f[t+116>>2]=e,i=f[o+20>>2],f[(e=t+128|0)>>2]=f[o+16>>2],f[e+4>>2]=i,r=f[(i=o+24|0)+4>>2],f[(e=t+136|0)>>2]=f[i>>2],f[e+4>>2]=r,i=f[o+36>>2],f[(e=t+144|0)>>2]=f[o+32>>2],f[e+4>>2]=i,r=f[(i=o+40|0)+4>>2],f[(e=t+152|0)>>2]=f[i>>2],f[e+4>>2]=r,i=f[o+52>>2],f[(e=t+160|0)>>2]=f[o+48>>2],f[e+4>>2]=i,r=f[(i=o+56|0)+4>>2],f[(e=t+168|0)>>2]=f[i>>2],f[e+4>>2]=r,f[t+680>>2]=0,f[t+684>>2]=0,f[(e=t+688|0)>>2]=0,f[e+4>>2]=0,f[(e=t+696|0)>>2]=0,f[e+4>>2]=0,f[(e=t+704|0)>>2]=0,f[e+4>>2]=0,f[(e=t+712|0)>>2]=0,f[e+4>>2]=0,f[(e=t+720|0)>>2]=0,f[e+4>>2]=0,f[t+736>>2]=1045220557,f[(e=t+728|0)>>2]=1045220557,f[e+4>>2]=1045220557,f[t+756>>2]=0,f[(e=t+748|0)>>2]=0,f[e+4>>2]=0,f[(e=t+740|0)>>2]=0,f[e+4>>2]=0,f[t+768>>2]=1063675494,f[(e=t+760|0)>>2]=1063675494,f[e+4>>2]=1063675494,f[t+812>>2]=0,f[(e=t+804|0)>>2]=0,f[e+4>>2]=0,f[t+828>>2]=0,f[(e=t+820|0)>>2]=0,f[e+4>>2]=0,n[t+838|0]=0,n[0|(e=t+836|0)]=0,n[e+1|0]=0,f[t+848>>2]=0,f[(e=t+840|0)>>2]=0,f[e+4>>2]=0,n[t+858|0]=0,n[0|(e=t+856|0)]=0,n[e+1|0]=0,f[t+868>>2]=0,f[(e=t+860|0)>>2]=0,f[e+4>>2]=0,f[t+884>>2]=0,f[(e=t+876|0)>>2]=0,f[e+4>>2]=0,f[t+900>>2]=0,f[(e=t+892|0)>>2]=0,f[e+4>>2]=0,n[0|(e=t+793|0)]=0,n[e+1|0]=0,n[e+2|0]=0,n[e+3|0]=0,n[e+4|0]=0,n[e+5|0]=0,n[e+6|0]=0,n[e+7|0]=0,f[(e=t+788|0)>>2]=0,f[e+4>>2]=0,f[(e=t+780|0)>>2]=0,f[e+4>>2]=0,f[(e=t+772|0)>>2]=0,f[e+4>>2]=0,f[t+964>>2]=0,f[(e=t+956|0)>>2]=0,f[e+4>>2]=0,f[(e=t+948|0)>>2]=0,f[e+4>>2]=0,f[(e=t+940|0)>>2]=0,f[e+4>>2]=0,f[(e=t+932|0)>>2]=0,f[e+4>>2]=0,f[(e=t+924|0)>>2]=0,f[e+4>>2]=0,f[(e=t+916|0)>>2]=0,f[e+4>>2]=0,f[(e=t+908|0)>>2]=0,f[e+4>>2]=0,n[t+1032|0]=0,f[t+1028>>2]=0,n[t+1024|0]=0,f[t+1020>>2]=0,n[t+1016|0]=0,f[t+1012>>2]=0,n[t+1008|0]=0,f[(e=t+1e3|0)>>2]=0,f[e+4>>2]=1036831949,n[t+996|0]=0,f[t+992>>2]=0,f[(e=t+984|0)>>2]=0,f[e+4>>2]=1063675494,f[(e=t+976|0)>>2]=0,f[e+4>>2]=1045220557,f[t+968>>2]=1065353216,f[t+972>>2]=-1082130432,f[t+1052>>2]=0,f[(e=t+1044|0)>>2]=0,f[e+4>>2]=0,f[(e=t+1036|0)>>2]=0,f[e+4>>2]=0,n[t+1120|0]=0,f[t+1116>>2]=0,n[t+1112|0]=0,f[t+1108>>2]=0,n[t+1104|0]=0,f[t+1100>>2]=0,n[t+1096|0]=0,f[(e=t+1088|0)>>2]=0,f[e+4>>2]=1036831949,n[t+1084|0]=0,f[t+1080>>2]=0,f[(e=t+1072|0)>>2]=0,f[e+4>>2]=1063675494,f[(e=t+1064|0)>>2]=0,f[e+4>>2]=1045220557,f[(e=t+1056|0)>>2]=1065353216,f[e+4>>2]=-1082130432,f[t+1140>>2]=0,f[(e=t+1132|0)>>2]=0,f[e+4>>2]=0,f[(e=t+1124|0)>>2]=0,f[e+4>>2]=0,n[t+1208|0]=0,f[t+1204>>2]=0,n[t+1200|0]=0,f[t+1196>>2]=0,n[t+1192|0]=0,f[t+1188>>2]=0,n[t+1184|0]=0,f[(e=t+1176|0)>>2]=0,f[e+4>>2]=1036831949,n[t+1172|0]=0,f[t+1168>>2]=0,f[(e=t+1160|0)>>2]=0,f[e+4>>2]=1063675494,f[(e=t+1152|0)>>2]=0,f[e+4>>2]=1045220557,f[(e=t+1144|0)>>2]=1065353216,f[e+4>>2]=-1082130432,f[t+1228>>2]=0,f[(e=t+1220|0)>>2]=0,f[e+4>>2]=0,f[(e=t+1212|0)>>2]=0,f[e+4>>2]=0,f[t+1456>>2]=0,f[t+1232>>2]=_,Kf(t,f[t+28>>2]+4|0,f[t+32>>2]+4|0),t}function Kf(t,e,i){var r=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),B=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),yt=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0);It=C[e+52>>2],St=C[e+56>>2],p=C[t+96>>2],B=C[t+100>>2],F=C[t+104>>2],r=C[e+20>>2],a=C[e+24>>2],V=C[t- -64>>2],G=C[t+80>>2],w=C[t+52>>2],Q=C[t+68>>2],W=C[t+84>>2],Y=C[t+56>>2],o=C[e+36>>2],z=C[t+72>>2],_=C[e+40>>2],yt=C[t+88>>2],Dt=C[e+48>>2],h=C[e+8>>2],d=C[e>>2],g=C[e+4>>2],m=C[e+16>>2],pt=C[t+48>>2],y=C[e+32>>2],f[t+1296>>2]=0,f[t+1280>>2]=0,f[t+1264>>2]=0,f[t+1248>>2]=0,C[t+1276>>2]=v(v(Y*y)+v(z*o))+v(yt*_),C[t+1272>>2]=v(v(w*y)+v(Q*o))+v(W*_),C[t+1268>>2]=v(v(pt*y)+v(V*o))+v(G*_),C[t+1260>>2]=v(v(Y*m)+v(z*r))+v(yt*a),C[t+1256>>2]=v(v(w*m)+v(Q*r))+v(W*a),C[t+1252>>2]=v(v(pt*m)+v(V*r))+v(G*a),C[t+1244>>2]=v(v(d*Y)+v(g*z))+v(h*yt),C[t+1240>>2]=v(v(d*w)+v(g*Q))+v(h*W),C[t+1236>>2]=v(v(pt*d)+v(V*g))+v(G*h),C[t+1292>>2]=St+v(v(v(y*p)+v(o*B))+v(_*F)),C[t+1288>>2]=It+v(v(v(m*p)+v(r*B))+v(a*F)),C[t+1284>>2]=Dt+v(v(v(d*p)+v(g*B))+v(h*F)),It=C[i+52>>2],St=C[i+56>>2],p=C[t+160>>2],B=C[t+164>>2],F=C[t+168>>2],r=C[i+20>>2],a=C[i+24>>2],V=C[t+128>>2],G=C[t+144>>2],w=C[t+116>>2],Q=C[t+132>>2],W=C[t+148>>2],Y=C[t+120>>2],z=C[t+136>>2],o=C[i+36>>2],yt=C[t+152>>2],_=C[i+40>>2],Dt=C[i+48>>2],h=C[i+8>>2],d=C[i>>2],g=C[i+4>>2],m=C[i+16>>2],pt=C[t+112>>2],y=C[i+32>>2],f[t+1360>>2]=0,f[t+1344>>2]=0,f[t+1328>>2]=0,f[t+1312>>2]=0,C[t+1340>>2]=v(v(Y*y)+v(z*o))+v(yt*_),C[t+1336>>2]=v(v(w*y)+v(Q*o))+v(W*_),C[t+1332>>2]=v(v(pt*y)+v(V*o))+v(G*_),C[t+1324>>2]=v(v(Y*m)+v(z*r))+v(yt*a),C[t+1320>>2]=v(v(w*m)+v(Q*r))+v(W*a),C[t+1316>>2]=v(v(pt*m)+v(V*r))+v(G*a),C[t+1308>>2]=v(v(d*Y)+v(g*z))+v(h*yt),C[t+1304>>2]=v(v(d*w)+v(g*Q))+v(h*W),C[t+1300>>2]=v(v(pt*d)+v(V*g))+v(G*h),C[t+1356>>2]=St+v(v(v(y*p)+v(o*B))+v(_*F)),C[t+1352>>2]=It+v(v(v(m*p)+v(r*B))+v(a*F)),C[t+1348>>2]=Dt+v(v(v(d*p)+v(g*B))+v(h*F)),function(t){var e=v(0),i=v(0),r=v(0),n=v(0),a=0,o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=0,R=v(0),D=v(0),B=v(0),E=v(0),F=v(0);f[t+1440>>2]=0,_=C[t+1256>>2],h=C[t+1276>>2],d=C[t+1260>>2],g=C[t+1272>>2],E=v(v(_*h)-v(d*g)),i=C[t+1236>>2],r=C[t+1240>>2],m=C[t+1268>>2],y=C[t+1252>>2],F=v(v(d*m)-v(h*y)),o=v(v(g*y)-v(_*m)),n=C[t+1244>>2],e=v(v(1)/v(v(v(E*i)+v(r*F))+v(o*n))),R=v(C[t+1356>>2]-C[t+1292>>2]),D=v(C[t+1348>>2]-C[t+1284>>2]),B=v(C[t+1352>>2]-C[t+1288>>2]),o=v(v(R*v(v(v(_*i)-v(y*r))*e))+v(v(D*v(o*e))+v(B*v(v(v(m*r)-v(g*i))*e)))),C[t+1436>>2]=o,i=v(v(R*v(v(v(y*n)-v(d*i))*e))+v(v(D*v(F*e))+v(B*v(v(v(h*i)-v(m*n))*e)))),C[t+1432>>2]=i,e=v(v(R*v(v(v(d*r)-v(_*n))*e))+v(v(D*v(E*e))+v(B*v(v(v(g*n)-v(h*r))*e)))),C[t+1428>>2]=e,C[t+940>>2]=e,(r=C[t+680>>2])>(n=C[t+696>>2])?f[t+908>>2]=0:(C[t+908>>2]=e-r,a=3,r!=n&&(C[t+924>>2]=e-n,a=4)),C[t+944>>2]=i,f[t+956>>2]=a;t:if((e=C[t+684>>2])>(r=C[t+700>>2]))f[t+912>>2]=0,a=0;else{if(C[t+912>>2]=i-e,a=3,e==r)break t;C[t+928>>2]=i-r,a=4}C[t+948>>2]=o,f[t+960>>2]=a,a=t+964|0;t:if((e=C[t+688>>2])>(i=C[t+704>>2]))f[t+916>>2]=0,p=0;else{if(C[t+916>>2]=o-e,p=3,e==i)break t;C[t+932>>2]=o-i,p=4}f[a>>2]=p}(t),function(t){var e,i,r=v(0),n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),B=v(0),F=v(0),V=0,G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),yt=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0);Z=e=Z-48|0,p=C[t+1332>>2],G=C[t+1316>>2],w=C[t+1336>>2],Q=C[t+1304>>2],W=C[t+1320>>2],Y=C[t+1340>>2],z=C[t+1308>>2],yt=C[t+1324>>2],d=C[t+1244>>2],g=C[t+1256>>2],h=C[t+1272>>2],o=C[t+1240>>2],a=C[t+1268>>2],m=C[t+1260>>2],_=C[t+1252>>2],y=C[t+1276>>2],pt=C[t+1300>>2],r=C[t+1236>>2],f[e+44>>2]=0,f[e+28>>2]=0,St=v(v(g*y)-v(m*h)),B=v(v(m*a)-v(y*_)),F=v(v(h*_)-v(g*a)),n=v(v(1)/v(v(v(r*St)+v(o*B))+v(F*d))),F=v(F*n),Dt=v(v(v(a*o)-v(h*r))*n),It=v(v(v(g*r)-v(_*o))*n),C[e+40>>2]=v(v(z*F)+v(yt*Dt))+v(Y*It),C[e+36>>2]=v(v(Q*F)+v(Dt*W))+v(It*w),B=v(B*n),a=v(v(v(y*r)-v(a*d))*n),r=v(v(v(_*d)-v(m*r))*n),C[e+24>>2]=v(v(z*B)+v(yt*a))+v(Y*r),C[e+20>>2]=v(v(Q*B)+v(a*W))+v(r*w),f[e+12>>2]=0,C[e+32>>2]=v(p*It)+v(v(pt*F)+v(G*Dt)),C[e+16>>2]=v(p*r)+v(v(pt*B)+v(G*a)),r=v(St*n),h=v(v(v(h*d)-v(y*o))*n),n=v(v(v(m*o)-v(g*d))*n),C[e+8>>2]=v(v(z*r)+v(yt*h))+v(Y*n),C[e+4>>2]=v(v(r*Q)+v(h*W))+v(n*w),C[e>>2]=v(p*n)+v(v(pt*r)+v(G*h)),i=t;t:{e:{i:{A:{r:{n:{a:{o:{if((V=f[t+1232>>2])>>>0<=5){s:{switch(V-1|0){default:!function(t,e){var i=v(0),r=v(0),n=0,a=v(0);if((i=C[t+32>>2])v(-1))return n=e,a=vi(v(-C[t+36>>2]),C[t+40>>2]),C[n>>2]=a,n=e,a=Yf(v(R(v(D(C[t+32>>2],v(-1))),v(1)))),C[n+4>>2]=a,n=e,a=vi(v(-C[t+16>>2]),C[t>>2]),void(C[n+8>>2]=a);i=C[t+20>>2],r=C[t+4>>2],f[e+4>>2]=-1077342245,n=e,a=v(-vi(r,i)),C[n>>2]=a}else i=C[t+20>>2],r=C[t+4>>2],f[e+4>>2]=1070141403,n=e,a=vi(r,i),C[n>>2]=a;C[e+8>>2]=0}(e,t+1364|0);break s;case 0:!function(t,e){var i=v(0),r=v(0),n=0,a=v(0);if((i=C[t+16>>2])v(-1)?(n=e,a=vi(C[t+24>>2],C[t+20>>2]),C[n>>2]=a,n=e,a=vi(C[t+32>>2],C[t>>2]),C[n+4>>2]=a,n=e,a=Yf(v(R(v(D(v(-C[t+16>>2]),v(-1))),v(1)))),void(C[n+8>>2]=a)):(i=C[t+40>>2],r=C[t+8>>2],f[e+4>>2]=0,n=e,a=v(-vi(v(-r),i)),C[n>>2]=a,void(C[e+8>>2]=1.5707963705062866));i=C[t+40>>2],r=C[t+8>>2],f[e+4>>2]=0,n=e,a=vi(v(-r),i),C[n>>2]=a,C[e+8>>2]=-1.5707963705062866}(e,t+1364|0);break s;case 1:!function(t,e){var i=v(0),r=0,n=v(0);if((i=C[t+36>>2])v(-1))return r=e,n=Yf(v(R(v(D(v(-i),v(-1))),v(1)))),C[r>>2]=n,r=e,n=vi(C[t+32>>2],C[t+40>>2]),C[r+4>>2]=n,r=e,n=vi(C[t+4>>2],C[t+20>>2]),void(C[r+8>>2]=n);f[e>>2]=1070141403,r=e,n=v(-vi(v(-C[t+16>>2]),C[t>>2])),C[r+4>>2]=n}else f[e>>2]=-1077342245,r=e,n=vi(v(-C[t+16>>2]),C[t>>2]),C[r+4>>2]=n;C[e+8>>2]=0}(e,t+1364|0);break s;case 2:!function(t,e){var i=v(0),r=0,n=v(0);if((i=C[t+4>>2])v(-1)?(r=e,n=vi(v(-C[t+36>>2]),C[t+20>>2]),C[r>>2]=n,r=e,n=vi(v(-C[t+8>>2]),C[t>>2]),C[r+4>>2]=n,r=e,n=Yf(v(R(v(D(C[t+4>>2],v(-1))),v(1)))),void(C[r+8>>2]=n)):(f[e>>2]=0,r=e,n=v(-vi(C[t+24>>2],C[t+40>>2])),C[r+4>>2]=n,void(C[e+8>>2]=-1.5707963705062866));f[e>>2]=0,r=e,n=vi(C[t+24>>2],C[t+40>>2]),C[r+4>>2]=n,C[e+8>>2]=1.5707963705062866}(e,t+1364|0);break s;case 3:!function(t,e){var i,r=v(0),n=0,a=v(0);if(i=e,(r=C[t+24>>2])v(-1))return n=e,a=Yf(v(R(v(D(r,v(-1))),v(1)))),C[n>>2]=a,n=e,a=vi(v(-C[t+8>>2]),C[t+40>>2]),C[n+4>>2]=a,n=e,a=vi(v(-C[t+16>>2]),C[t+20>>2]),void(C[n+8>>2]=a);f[e>>2]=-1077342245,f[e+4>>2]=0,r=v(-vi(C[t+32>>2],C[t>>2]))}else f[e>>2]=1070141403,f[e+4>>2]=0,r=vi(C[t+32>>2],C[t>>2]);C[i+8>>2]=r}(e,t+1364|0);break s;case 4:}!function(t,e){var i,r=v(0),n=0,a=v(0);if(i=e,(r=C[t+8>>2])v(-1))return n=e,a=vi(C[t+24>>2],C[t+40>>2]),C[n>>2]=a,n=e,a=Yf(v(R(v(D(v(-C[t+8>>2]),v(-1))),v(1)))),C[n+4>>2]=a,n=e,a=vi(C[t+4>>2],C[t>>2]),void(C[n+8>>2]=a);f[e>>2]=0,f[e+4>>2]=1070141403,r=v(-vi(C[t+16>>2],C[t+32>>2]))}else f[e>>2]=0,f[e+4>>2]=-1077342245,r=vi(v(-C[t+16>>2]),v(-C[t+32>>2]));C[i+8>>2]=r}(e,t+1364|0)}V=f[t+1232>>2]}if(V>>>0<=5)switch(V-1|0){case 4:break i;case 3:break A;case 2:break r;case 1:break n;case 0:break a;default:break o}d=C[t+1420>>2],o=C[t+1416>>2],r=C[t+1412>>2],g=C[t+1404>>2],h=C[t+1400>>2],a=C[t+1396>>2],m=C[t+1388>>2],_=C[t+1384>>2],n=C[t+1380>>2];break t}f[t+1408>>2]=0,f[t+1424>>2]=0,f[t+1392>>2]=0,n=C[t+1316>>2],_=C[t+1244>>2],o=C[t+1300>>2],y=C[t+1260>>2],g=v(v(n*_)-v(o*y)),C[t+1404>>2]=g,p=C[t+1276>>2],r=C[t+1332>>2],h=v(v(o*p)-v(_*r)),C[t+1400>>2]=h,a=v(v(r*y)-v(n*p)),C[t+1396>>2]=a,d=v(v(o*h)-v(n*a)),C[t+1420>>2]=d,o=v(v(r*a)-v(o*g)),C[t+1416>>2]=o,r=v(v(n*g)-v(r*h)),C[t+1412>>2]=r,m=v(v(y*a)-v(_*h)),C[t+1388>>2]=m,_=v(v(_*g)-v(p*a)),C[t+1384>>2]=_,n=v(v(p*h)-v(y*g));break e}f[t+1424>>2]=0,f[t+1408>>2]=0,f[t+1392>>2]=0,n=C[t+1300>>2],y=C[t+1256>>2],a=C[t+1316>>2],_=C[t+1240>>2],d=v(v(n*y)-v(a*_)),C[t+1420>>2]=d,m=C[t+1332>>2],p=C[t+1272>>2],o=v(v(_*m)-v(n*p)),C[t+1416>>2]=o,r=v(v(a*p)-v(m*y)),C[t+1412>>2]=r,g=v(v(a*r)-v(n*o)),C[t+1404>>2]=g,h=v(v(n*d)-v(m*r)),C[t+1400>>2]=h,a=v(v(m*o)-v(a*d)),C[t+1396>>2]=a,m=v(v(_*o)-v(y*r)),C[t+1388>>2]=m,_=v(v(p*r)-v(_*d)),C[t+1384>>2]=_,n=v(v(y*d)-v(p*o));break e}f[t+1424>>2]=0,f[t+1408>>2]=0,f[t+1392>>2]=0,o=C[t+1304>>2],a=C[t+1260>>2],r=C[t+1320>>2],h=C[t+1244>>2],m=v(v(o*a)-v(r*h)),C[t+1388>>2]=m,g=C[t+1336>>2],y=C[t+1276>>2],_=v(v(h*g)-v(o*y)),C[t+1384>>2]=_,n=v(v(r*y)-v(g*a)),C[t+1380>>2]=n,d=v(v(r*n)-v(o*_)),C[t+1420>>2]=d,o=v(v(o*m)-v(g*n)),C[t+1416>>2]=o,r=v(v(g*_)-v(r*m)),C[t+1412>>2]=r,g=v(v(h*_)-v(a*n)),C[t+1404>>2]=g,h=v(v(y*n)-v(h*m)),C[t+1400>>2]=h,a=v(v(a*m)-v(y*_)),C[t+1396>>2]=a;break t}f[t+1424>>2]=0,f[t+1408>>2]=0,f[t+1392>>2]=0,n=C[t+1236>>2],y=C[t+1320>>2],a=C[t+1252>>2],_=C[t+1304>>2],d=v(v(n*y)-v(a*_)),C[t+1420>>2]=d,m=C[t+1268>>2],p=C[t+1336>>2],o=v(v(_*m)-v(n*p)),C[t+1416>>2]=o,r=v(v(a*p)-v(m*y)),C[t+1412>>2]=r,g=v(v(a*r)-v(n*o)),C[t+1404>>2]=g,h=v(v(n*d)-v(m*r)),C[t+1400>>2]=h,a=v(v(m*o)-v(a*d)),C[t+1396>>2]=a,m=v(v(_*o)-v(y*r)),C[t+1388>>2]=m,_=v(v(p*r)-v(_*d)),C[t+1384>>2]=_,n=v(v(y*d)-v(p*o));break e}f[t+1424>>2]=0,f[t+1408>>2]=0,f[t+1392>>2]=0,o=C[t+1240>>2],a=C[t+1324>>2],r=C[t+1256>>2],h=C[t+1308>>2],m=v(v(o*a)-v(r*h)),C[t+1388>>2]=m,g=C[t+1272>>2],y=C[t+1340>>2],_=v(v(h*g)-v(o*y)),C[t+1384>>2]=_,n=v(v(r*y)-v(g*a)),C[t+1380>>2]=n,d=v(v(r*n)-v(o*_)),C[t+1420>>2]=d,o=v(v(o*m)-v(g*n)),C[t+1416>>2]=o,r=v(v(g*_)-v(r*m)),C[t+1412>>2]=r,g=v(v(h*_)-v(a*n)),C[t+1404>>2]=g,h=v(v(y*n)-v(h*m)),C[t+1400>>2]=h,a=v(v(a*m)-v(y*_)),C[t+1396>>2]=a;break t}f[t+1408>>2]=0,f[t+1424>>2]=0,f[t+1392>>2]=0,n=C[t+1252>>2],_=C[t+1308>>2],o=C[t+1236>>2],y=C[t+1324>>2],g=v(v(n*_)-v(o*y)),C[t+1404>>2]=g,p=C[t+1340>>2],r=C[t+1268>>2],h=v(v(o*p)-v(_*r)),C[t+1400>>2]=h,a=v(v(r*y)-v(n*p)),C[t+1396>>2]=a,d=v(v(o*h)-v(n*a)),C[t+1420>>2]=d,o=v(v(r*a)-v(o*g)),C[t+1416>>2]=o,r=v(v(n*g)-v(r*h)),C[t+1412>>2]=r,m=v(v(y*a)-v(_*h)),C[t+1388>>2]=m,_=v(v(_*g)-v(p*a)),C[t+1384>>2]=_,n=v(v(p*h)-v(y*g))}C[i+1380>>2]=n}y=d,d=v(v(1)/v(E(v(v(v(r*r)+v(o*o))+v(d*d))))),C[t+1420>>2]=y*d,C[t+1416>>2]=o*d,C[t+1412>>2]=r*d,d=v(v(1)/v(E(v(v(v(a*a)+v(h*h))+v(g*g))))),C[t+1404>>2]=g*d,C[t+1400>>2]=h*d,C[t+1396>>2]=a*d,d=v(v(1)/v(E(v(v(v(n*n)+v(_*_))+v(m*m))))),C[t+1388>>2]=m*d,C[t+1384>>2]=_*d,C[t+1380>>2]=n*d,Z=e+48|0}(t),a=C[f[t+28>>2]+404>>2],r=C[f[t+32>>2]+404>>2],n[t+1452|0]=av(0)?v(Dt/r):v(.5),C[t+1444>>2]=r,C[t+1448>>2]=v(1)-r}function Lf(t,e){var i,r=v(0),n=v(0),a=v(0),o=v(0),_=v(0);if(n=C[1364+((e<<2)+t|0)>>2],i=m(e,88)+t|0,(a=C[i+968>>2])>=(o=C[i+972>>2])||(nv(3.1415927410125732)&&(r=v(r+v(-6.2831854820251465))),_=v(y(r)),(r=Wf(v(o-n)))v(3.1415927410125732)&&(r=v(r+v(-6.2831854820251465))),n=_o&&((r=Wf(v(n-o)))v(3.1415927410125732)&&(r=v(r+v(-6.2831854820251465))),_=v(y(r)),(r=Wf(v(n-a)))v(3.1415927410125732)&&(r=v(r+v(-6.2831854820251465))),n=v(y(r))<_?v(n+v(-6.2831854820251465)):n)),C[i+1048>>2]=n,a>o)return t=m(e,88)+t|0,f[t+1040>>2]=0,void(f[t+1052>>2]=0);t=m(e,88)+t|0,C[t+1040>>2]=n-a,a!=o?(f[t+1052>>2]=4,C[t+1044>>2]=n-o):f[t+1052>>2]=3}function qf(t,e,i,r,n,a,o,h,d,g,y,p,B){var F=v(0),V=v(0),G=v(0),w=0,Q=0,W=v(0),Y=v(0),Z=v(0),z=v(0),yt=v(0),pt=v(0),Dt=v(0);if(g=m(f[d+24>>2],g),(w=f[e+84>>2]+-3|0)>>>0>1)w=0;else{if(w-1)$f(t,i,r,d,g,y,p,B),C[(Q=g<<2)+f[d+28>>2]>>2]=v(v(C[d>>2]*C[e+12>>2])*C[e+72>>2])*v(0|(p?-1:1)),f[Q+f[d+36>>2]>>2]=-8388609,f[Q+f[d+40>>2]>>2]=2139095039,Q=e+16|0,w=1;else{p?(F=C[y>>2],G=C[y+4>>2],V=v(v(C[o>>2]*F)+v(C[o+4>>2]*G)),W=C[y+8>>2],Z=v(C[o+8>>2]*W),Q=p,w=h):(F=C[y>>2],G=C[y+4>>2],V=v(v(C[n>>2]*F)+v(C[n+4>>2]*G)),W=C[y+8>>2],Z=v(C[n+8>>2]*W),w=a),yt=C[w+8>>2],pt=C[w>>2],z=C[w+4>>2],$f(t,i,r,d,g,y,Q,B),w=f[d+28>>2]+(g<<2)|0,Dt=v(0|(p?-1:1)),Y=v(v(v(C[d>>2]*C[e+12>>2])*C[e+72>>2])*Dt),C[w>>2]=Y,F=v(v(V+Z)-v(v(v(F*pt)+v(G*z))+v(W*yt))),V=v(Y-v(F*C[e+12>>2]));t:if(p){if(!(V>v(0)))break t;if(!(Y<(V=v(-v(F*C[e+8>>2])))))break t;C[w>>2]=V}else V>2])),Y>V&&(C[w>>2]=V));C[(w=g<<2)+f[d+36>>2]>>2]=v(p?0:-34028234663852886e22),C[w+f[d+40>>2]>>2]=v(p?34028234663852886e22:0),f[w+f[d+32>>2]>>2]=f[e+16>>2],$f(t,i,r,d,g=f[d+24>>2]+g|0,y,p,B),w=f[d+28>>2]+(g<<2)|0,V=v(v(v(C[d>>2]*C[e+12>>2])*C[e+76>>2])*Dt),C[w>>2]=V,G=v(V-v(F*C[e+12>>2])),Q=e+16|0;t:if(p){if(!(G(F=v(-v(F*C[e+8>>2])))))break t;C[w>>2]=F}else G>v(0)&&(F=v(-v(F*C[e+8>>2])),V>2]=F));C[(w=g<<2)+f[d+36>>2]>>2]=v(p?-34028234663852886e22:0),C[f[d+40>>2]+w>>2]=v(p?0:34028234663852886e22),w=2}f[f[d+32>>2]+(g<<2)>>2]=f[Q>>2],g=f[d+24>>2]+g|0}return _[e+28|0]&&(!_[e+40|0]&&($f(t,i,r,d,g,y,p,B),F=C[e+32>>2],F=wf(C[e+80>>2],C[e>>2],C[e+4>>2],p?F:v(-F),v(C[d>>2]*C[e+20>>2])),C[(Q=g<<2)+f[d+28>>2]>>2]=F*C[e+32>>2],C[Q+f[d+36>>2]>>2]=-C[e+36>>2],f[Q+f[d+40>>2]>>2]=f[e+36>>2],f[Q+f[d+32>>2]>>2]=f[e+24>>2],w=w+1|0,g=f[d+24>>2]+g|0,!_[e+28|0]|!_[e+40|0])||(V=C[e+44>>2],F=v(C[e+80>>2]-V),p&&(V=(Q=F>v(3.1415927410125732))?v(V+v(6.2831854820251465)):V,(F=Q?v(F+v(-6.2831854820251465)):F)>2],Y=F>2],(G=C[e>>2])>(W=C[e+4>>2])?(W=Fv(0)?V:v(-34028234663852886e22)):(W=Fv(0)&&V>G?V:G),G=wf(z,F,W,Z,v(C[d>>2]*C[e+20>>2]))),C[(Q=g<<2)+f[d+28>>2]>>2]=v(Y*G)*v(0|(p?-1:1)),C[Q+f[d+36>>2]>>2]=-C[e+36>>2],f[Q+f[d+40>>2]>>2]=f[e+36>>2],f[Q+f[d+32>>2]>>2]=f[e+24>>2],w=w+1|0,g=f[d+24>>2]+g|0)),_[e+48|0]&&(z=C[e+68>>2],Dt=C[e+80>>2],$f(t,i,r,d,g,y,p,B),F=C[d>>2],V=C[e+52>>2],W=C[e+60>>2],z=v(Dt-z),p?(yt=C[y+8>>2],pt=v(C[o+8>>2]*yt),G=C[y>>2],Y=C[y+4>>2],Z=v(v(C[o>>2]*G)+v(C[o+4>>2]*Y))):(yt=C[y+8>>2],pt=v(C[n+8>>2]*yt),h=a,G=C[y>>2],Y=C[y+4>>2],Z=v(v(C[n>>2]*G)+v(C[n+4>>2]*Y))),Y=v(v(Z+pt)-v(v(v(G*C[h>>2])+v(Y*C[h+4>>2]))+v(yt*C[h+8>>2]))),F=v(v(1)/F),G=v(v(1)/C[f[t+32>>2]+404>>2]),G=(Z=v(v(1)/C[f[t+28>>2]+404>>2]))>G?G:Z,!_[e+56|0]|v(F*v(E(v(V/G))))>v(.25)^1||(V=v(v(v(v(v(1)/F)/F)*v(.0625))*G)),t=g<<2,Z=v(F*v(z*V)),V=v(0|(p?-1:1)),G=v(F*v(v(Y*(v(W*F)>G&&_[e+64|0]?v(G/F):W))*V)),F=v(Z-G),C[t+f[d+28>>2]>>2]=Y+v(F*V),V=(e=F<(G=v(-G)))?G:F,F=e?F:G,p?(C[t+f[d+36>>2]>>2]=R(v(-V),v(0)),V=v(-F)):C[t+f[d+36>>2]>>2]=R(F,v(0)),C[(t=g<<2)+f[d+40>>2]>>2]=D(V,v(0)),f[t+f[d+32>>2]>>2]=0,w=w+1|0),w}function $f(t,e,i,r,n,a,o,h){var d,g,m,y,p,R,D=v(0),B=v(0),E=v(0),F=0,V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0);d=Z-16|0,g=n<<2,F=f[(o?12:8)+r>>2],f[g+F>>2]=f[a>>2],f[F+(y=(m=n+1|0)<<2)>>2]=f[a+4>>2],f[F+(R=(p=n+2|0)<<2)>>2]=f[a+8>>2],F=f[(o?20:16)+r>>2],C[F+g>>2]=-C[a>>2],C[F+y>>2]=-C[a+4>>2],C[F+R>>2]=-C[a+8>>2],o||(f[d+12>>2]=0,D=v(C[t+1284>>2]-C[e+48>>2]),B=C[a+4>>2],V=v(C[t+1288>>2]-C[e+52>>2]),E=C[a>>2],Q=v(v(D*B)-v(V*E)),C[d+8>>2]=Q,G=v(C[t+1292>>2]-C[e+56>>2]),w=D,D=C[a+8>>2],W=v(v(E*G)-v(w*D)),C[d+4>>2]=W,G=v(v(V*D)-v(G*B)),C[d>>2]=G,Y=v(C[t+1352>>2]-C[i+52>>2]),z=v(C[t+1356>>2]-C[i+56>>2]),V=v(v(D*Y)-v(B*z)),w=v(C[t+1348>>2]-C[i+48>>2]),B=v(v(B*w)-v(Y*E)),E=v(v(z*E)-v(w*D)),!_[t+1452|0]|h||(D=C[t+1444>>2],C[d+8>>2]=Q*D,C[d+4>>2]=W*D,C[d>>2]=G*D,D=C[t+1448>>2],B=v(B*D),V=v(V*D),E=v(E*D)),e=f[d+4>>2],t=(i=n<<2)+f[r+12>>2]|0,f[t>>2]=f[d>>2],f[t+4>>2]=e,f[t+8>>2]=f[d+8>>2],t=f[r+20>>2],C[t+i>>2]=-V,C[t+(m<<2)>>2]=-E,C[t+(p<<2)>>2]=-B)}function At(t){f[(t|=0)>>2]=23012,CA(t)}function et(t){return v(C[(t|=0)>>2])}function rt(t){return v(C[(t|=0)+4>>2])}function it(t){return v(C[(t|=0)+8>>2])}function ft(t){return(t|=0)+48|0}function tt(t,e){var i,r=v(0),n=0,a=0,o=v(0),_=0,h=v(0),d=0,g=0,m=v(0);i=Z-16|0,r=C[t>>2],h=C[t+20>>2],o=C[t+40>>2],(m=v(v(r+h)+o))>v(0)?(h=v(E(v(m+v(1)))),r=v(v(.5)/h),o=v(r*v(C[t+16>>2]-C[t+4>>2])),C[i+8>>2]=o,s(o),n=c(0),o=v(r*v(C[t+8>>2]-C[t+32>>2])),C[i+4>>2]=o,r=v(r*v(C[t+36>>2]-C[t+24>>2])),C[i>>2]=r,s(r),t=c(0),r=v(h*v(.5)),C[i+12>>2]=r,s(r),a=c(0),s(o),_=c(0)):(_=(n=r>>0)%3|0)<<4)+t|0,a<<=2,n=t+((t=(n+2>>>0)%3|0)<<4)|0,t<<=2,r=v(E(v(v(v(C[_+d>>2]-C[g+a>>2])-C[n+t>>2])+v(1)))),C[(_|i)>>2]=r*v(.5),r=v(v(.5)/r),C[i+12>>2]=v(C[n+a>>2]-C[t+g>>2])*r,C[(i|a)>>2]=r*v(C[_+g>>2]+C[a+d>>2]),C[(t|i)>>2]=r*v(C[n+_>>2]+C[t+d>>2]),a=f[i+12>>2],n=f[i+8>>2],t=f[i>>2],_=f[i+4>>2]),f[e+12>>2]=a,f[e+8>>2]=n,f[e+4>>2]=_,f[e>>2]=t}function nt(t){(t|=0)&&yt[f[f[t>>2]+4>>2]](t)}function at(t,e){e|=0,f[(t|=0)+12>>2]=e}function ot(t,e){t|=0,e=v(e),C[t+4>>2]=e}function ct(t,e){e|=0,f[(t|=0)+8>>2]=e}function bt(t){return(t|=0)+24|0}function lt(t){var e;(e=f[(t|=0)+12>>2])&&(_[t+16|0]&&CA(e),f[t+12>>2]=0),f[t+12>>2]=0,n[t+16|0]=1,f[t+4>>2]=0,f[t+8>>2]=0}function ut(t){return(t|=0)+32|0}function st(t){return(t|=0)- -64|0}function kt(t){return 0|yt[f[f[(t|=0)>>2]+36>>2]](t)}function vt(t,e){e|=0,yt[f[f[(t|=0)>>2]+60>>2]](t,e)}function dt(t,e,i){var r=v(0),n=v(0),a=v(0),o=v(0),f=0,_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0);(r=C[t+404>>2])!=v(0)&&(a=C[e+8>>2],n=C[e+4>>2],o=C[t+408>>2],C[t+372>>2]=v(r*v(C[e>>2]*o))+C[t+372>>2],f=t+376|0,_=n,n=C[t+412>>2],C[f>>2]=v(r*v(_*n))+C[f>>2],f=t+380|0,_=r,r=C[t+416>>2],C[f>>2]=v(_*v(a*r))+C[f>>2],g=C[t+612>>2],m=C[t+364>>2],y=C[t+356>>2],p=C[t+360>>2],R=C[t+608>>2],D=C[t+348>>2],B=C[t+340>>2],E=C[t+344>>2],d=C[i+4>>2],a=v(r*C[e+8>>2]),n=v(n*C[e+4>>2]),h=C[i+8>>2],r=v(v(d*a)-v(n*h)),o=v(o*C[e>>2]),_=v(o*h),h=C[i>>2],a=v(_-v(a*h)),n=v(v(n*h)-v(o*d)),C[t+388>>2]=v(v(v(v(C[t+324>>2]*r)+v(C[t+328>>2]*a))+v(n*C[t+332>>2]))*C[t+604>>2])+C[t+388>>2],C[(e=t+392|0)>>2]=v(R*v(v(v(r*B)+v(a*E))+v(n*D)))+C[e>>2],C[(t=t+396|0)>>2]=v(g*v(v(v(r*y)+v(a*p))+v(n*m)))+C[t>>2])}function Ct(t){var e=0;return f[(t|=0)>>2]=24920,(e=f[t+128>>2])&&(_[t+132|0]&&CA(e),f[t+128>>2]=0),f[t+128>>2]=0,f[t+120>>2]=0,f[t+124>>2]=0,n[t+132|0]=1,(e=f[t+108>>2])&&(_[t+112|0]&&CA(e),f[t+108>>2]=0),f[t+108>>2]=0,f[t+100>>2]=0,f[t+104>>2]=0,n[t+112|0]=1,(e=f[t+88>>2])&&(_[t+92|0]&&CA(e),f[t+88>>2]=0),f[t+88>>2]=0,f[t+80>>2]=0,f[t+84>>2]=0,n[t+92|0]=1,(e=f[t+36>>2])&&(_[t+40|0]&&CA(e),f[t+36>>2]=0),f[t+36>>2]=0,f[t+28>>2]=0,f[t+32>>2]=0,n[t+40|0]=1,0|t}function gt(t){var e=0;return f[(t|=0)>>2]=25144,(e=f[t+120>>2])&&(_[t+124|0]&&CA(e),f[t+120>>2]=0),f[t+120>>2]=0,f[t+112>>2]=0,f[t+116>>2]=0,n[t+124|0]=1,(e=f[t+100>>2])&&(_[t+104|0]&&CA(e),f[t+100>>2]=0),f[t+100>>2]=0,f[t+92>>2]=0,f[t+96>>2]=0,n[t+104|0]=1,(e=f[t+80>>2])&&(_[t+84|0]&&CA(e),f[t+80>>2]=0),f[t+80>>2]=0,f[t+72>>2]=0,f[t+76>>2]=0,n[t+84|0]=1,(e=f[t+28>>2])&&(_[t+32|0]&&CA(e),f[t+28>>2]=0),f[t+28>>2]=0,f[t+20>>2]=0,f[t+24>>2]=0,n[t+32|0]=1,0|t}function Bt(t,e){!function(t,e){o[0]=t,o[1]=e}(0|t,0|e)}function _t(t,e,i,r){return t=function(t,e,i,r){var n,a,o,f,_=0,h=0;return f=m(_=i>>>16,h=t>>>16),_=(65535&(h=((o=m(n=65535&i,a=65535&t))>>>16)+m(h,n)|0))+m(_,a)|0,t=(((m(e,i)+f|0)+m(t,r)|0)+(h>>>16)|0)+(_>>>16)|0,z=t,e=65535&o|_<<16}(t,e,i,r)}function mt(t,e,i){return function(t,e,i){var r=0,n=0,a=0,o=0,f=0,_=0,h=0,d=0,C=0;t:{e:{i:{A:{r:{n:{a:{o:{s:{if(n=e){if(!(r=i))break s;break o}return Bt((e=t)-m(t=(t>>>0)/(i>>>0)|0,i)|0,0),z=0,t}if(!t)break a;break n}if(!((o=r+-1|0)&r))break r;f=0-(o=(p(r)+33|0)-p(n)|0)|0;break i}return Bt(0,n-m(t=(n>>>0)/0|0,0)|0),z=0,t}if((r=32-p(n)|0)>>>0<31)break A;break e}if(Bt(t&o,0),1==(0|r))break t;return i=31&(r=r?31-p(r+-1^r)|0:32),32<=(63&r)>>>0?(n=0,t=e>>>i):(n=e>>>i,t=((1<>>i),z=n,t}o=r+1|0,f=63-r|0}if(r=e,a=31&(n=63&o),32<=n>>>0?(n=0,a=r>>>a):(n=r>>>a,a=((1<>>a),r=31&(f&=63),32<=f>>>0?(e=t<>>32-r|e<>>0<4294967295&&(r=0);a=(h=_=a<<1|e>>>31)-(d=i&(_=r-((n=n<<1|a>>>31)+(f>>>0<_>>>0)|0)>>31))|0,n=n-(h>>>0>>0)|0,e=e<<1|t>>>31,t=C|t<<1,C=_&=1,o=o+-1|0;);return Bt(a,n),z=e<<1|t>>>31,_|t<<1}Bt(t,e),t=0,e=0}return z=e,t}(t,e,i)}function Rt(t){var e;return(-1>>>(e=31&t)&-2)<>>t}var yt=[null,function(t){var e=0;return e=0,(t=0|G(f[(t|=0)+56>>2]))&&(f[256]=t,e=-1),0|e},function(t,e,i){t|=0,e|=0,i|=0;var r,n=0,a=0,o=0,_=0,h=0;Z=r=Z-16|0,f[r+12>>2]=i,f[r+8>>2]=e,e=f[t+24>>2],f[r>>2]=e,e=f[t+20>>2]-e|0,f[r+4>>2]=e,o=2;t:{if((0|(_=e+i|0))!=(0|(n=N(f[t+56>>2],r,2))))for(e=r;;){if((0|n)<=-1){if(f[t+24>>2]=0,f[t+16>>2]=0,f[t+20>>2]=0,f[t>>2]=32|f[t>>2],t=0,2==(0|o))break t;t=i-f[e+4>>2]|0;break t}if(a=n-((h=n>>>0>(a=f[e+4>>2])>>>0)?a:0)|0,f[(e=h?e+8|0:e)>>2]=a+f[e>>2],f[e+4>>2]=f[e+4>>2]-a,o=o-h|0,(0|(_=_-n|0))==(0|(n=N(f[t+56>>2],e,o))))break}e=f[t+40>>2],f[t+24>>2]=e,f[t+20>>2]=e,f[t+16>>2]=e+f[t+44>>2],t=i}return Z=r+16|0,0|(n=t)},function(t,e,i,r){return e|=0,i|=0,r|=0,0|(t=function(t,e,i,r){var n;return Z=n=Z-16|0,(t=0|Y(0|t,0|e,0|i,255&r,n+8|0))?(f[256]=76==(0|t)?70:t,i=-1,t=-1):(i=f[n+12>>2],t=f[n+8>>2]),Z=n+16|0,z=i,t}(f[(t|=0)+56>>2],e,i,r))},rA,iA,iA,function(t){var e;t|=0,Z=e=Z-16|0,f[e+12>>2]=t,rA(t=f[e+12>>2]),$(t),Z=e+16|0},eA,eA,function(t,e,i){var r;return t|=0,e|=0,i|=0,Z=r=Z-80|0,f[r+72>>2]=t,f[r+68>>2]=e,f[r+64>>2]=i,1&fA(e=f[r+72>>2],f[r+68>>2],0)?n[r+79|0]=1:(i=r,t=(t=f[r+68>>2])?function(t){var e;if(Z=e=Z-96|0,f[e+92>>2]=t,f[e+88>>2]=5456,f[e+84>>2]=5504,f[e+80>>2]=0,f[e+76>>2]=f[f[e+92>>2]>>2],f[e+72>>2]=f[f[e+76>>2]+-8>>2],f[e+68>>2]=f[e+92>>2]+f[e+72>>2],f[e+64>>2]=f[f[e+76>>2]+-4>>2],f[e+60>>2]=0,f[e>>2]=f[e+84>>2],f[e+4>>2]=f[e+92>>2],f[e+8>>2]=f[e+88>>2],f[e+12>>2]=f[e+80>>2],f[e+16>>2]=0,f[e+20>>2]=0,f[e+24>>2]=0,f[e+28>>2]=0,f[e+32>>2]=0,f[e+36>>2]=0,f[e+40>>2]=0,f[e+44>>2]=0,f[e+48>>2]=0,n[e+52|0]=0,n[e+53|0]=0,n[e+54|0]=0,1&fA(f[e+64>>2],f[e+84>>2],0))f[e+48>>2]=1,t=f[e+64>>2],yt[f[f[t>>2]+20>>2]](t,e,f[e+68>>2],f[e+68>>2],1,0),1==f[e+24>>2]&&(f[e+60>>2]=f[e+68>>2]);else{t=f[e+64>>2],yt[f[f[t>>2]+24>>2]](t,e,f[e+68>>2],1,0);t:if(!((t=f[e+36>>2])>>>0>1))if(t-1){if(1!=f[e+40>>2]|1!=f[e+28>>2]|1!=f[e+32>>2])break t;f[e+60>>2]=f[e+20>>2]}else f[e+40>>2]|1!=f[e+28>>2]|1!=f[e+32>>2]&&1!=f[e+24>>2]||(f[e+60>>2]=f[e+16>>2])}return Z=e+96|0,f[e+60>>2]}(t):0,f[i+60>>2]=t,f[r+60>>2]?(f[r>>2]=f[r+60>>2],f[r+4>>2]=0,f[r+8>>2]=e,f[r+12>>2]=-1,f[r+16>>2]=0,f[r+20>>2]=0,f[r+24>>2]=0,f[r+28>>2]=0,f[r+32>>2]=0,f[r+36>>2]=0,f[r+40>>2]=0,f[r+44>>2]=0,f[r+48>>2]=0,n[r+52|0]=0,n[r+53|0]=0,n[r+54|0]=0,f[r+48>>2]=1,t=f[r+60>>2],yt[f[f[t>>2]+28>>2]](t,r,f[f[r+64>>2]>>2],1),1!=f[r+24>>2]?n[r+79|0]=0:(f[f[r+64>>2]>>2]=f[r+16>>2],n[r+79|0]=1)):n[r+79|0]=0),Z=r+80|0,1&n[r+79|0]},function(t,e,i,r,a,o){var _;t|=0,e|=0,i|=0,r|=0,a|=0,o|=0,Z=_=Z-32|0,f[_+28>>2]=t,f[_+24>>2]=e,f[_+20>>2]=i,f[_+16>>2]=r,f[_+12>>2]=a,n[_+11|0]=o,1&fA(t=f[_+28>>2],f[f[_+24>>2]+8>>2],1&n[_+11|0])&&oA(t,f[_+24>>2],f[_+20>>2],f[_+16>>2],f[_+12>>2]),Z=_+32|0},function(t,e,i,r,a){var o;t|=0,e|=0,i|=0,r|=0,a|=0,Z=o=Z-32|0,f[o+28>>2]=t,f[o+24>>2]=e,f[o+20>>2]=i,f[o+16>>2]=r,n[o+15|0]=a,1&fA(t=f[o+28>>2],f[f[o+24>>2]+8>>2],1&n[o+15|0])?cA(t,f[o+24>>2],f[o+20>>2],f[o+16>>2]):1&fA(t,f[f[o+24>>2]>>2],1&n[o+15|0])&&(f[o+20>>2]!=f[f[o+24>>2]+20>>2]&&f[o+20>>2]!=f[f[o+24>>2]+16>>2]?(f[f[o+24>>2]+32>>2]=f[o+16>>2],f[f[o+24>>2]+20>>2]=f[o+20>>2],t=f[o+24>>2],f[t+40>>2]=f[t+40>>2]+1,1!=f[f[o+24>>2]+36>>2]|2!=f[f[o+24>>2]+24>>2]||(n[f[o+24>>2]+54|0]=1),f[f[o+24>>2]+44>>2]=4):1==f[o+16>>2]&&(f[f[o+24>>2]+32>>2]=1)),Z=o+32|0},function(t,e,i,r){var n;t|=0,e|=0,i|=0,r|=0,Z=n=Z-16|0,f[n+12>>2]=t,f[n+8>>2]=e,f[n+4>>2]=i,f[n>>2]=r,1&fA(t=f[n+12>>2],f[f[n+8>>2]+8>>2],0)&&nA(t,f[n+8>>2],f[n+4>>2],f[n>>2]),Z=n+16|0},function(t){var e;t|=0,Z=e=Z-16|0,f[e+12>>2]=t,iA(t=f[e+12>>2]),$(t),Z=e+16|0},function(t,e,i,r,a,o){var _;t|=0,e|=0,i|=0,r|=0,a|=0,o|=0,Z=_=Z-32|0,f[_+28>>2]=t,f[_+24>>2]=e,f[_+20>>2]=i,f[_+16>>2]=r,f[_+12>>2]=a,n[_+11|0]=o,1&fA(t=f[_+28>>2],f[f[_+24>>2]+8>>2],1&n[_+11|0])?oA(t,f[_+24>>2],f[_+20>>2],f[_+16>>2],f[_+12>>2]):(t=f[t+8>>2],yt[f[f[t>>2]+20>>2]](t,f[_+24>>2],f[_+20>>2],f[_+16>>2],f[_+12>>2],1&n[_+11|0])),Z=_+32|0},function(t,e,i,r,a){var o;if(t|=0,e|=0,i|=0,r|=0,a|=0,Z=o=Z-32|0,f[o+28>>2]=t,f[o+24>>2]=e,f[o+20>>2]=i,f[o+16>>2]=r,n[o+15|0]=a,1&fA(t=f[o+28>>2],f[f[o+24>>2]+8>>2],1&n[o+15|0]))cA(t,f[o+24>>2],f[o+20>>2],f[o+16>>2]);else t:if(1&fA(t,f[f[o+24>>2]>>2],1&n[o+15|0])){if(f[o+20>>2]==f[f[o+24>>2]+20>>2]||f[o+20>>2]==f[f[o+24>>2]+16>>2]){1==f[o+16>>2]&&(f[f[o+24>>2]+32>>2]=1);break t}f[f[o+24>>2]+32>>2]=f[o+16>>2],n[o+14|0]=0,4!=f[f[o+24>>2]+44>>2]&&(n[o+13|0]=0,n[f[o+24>>2]+52|0]=0,n[f[o+24>>2]+53|0]=0,t=f[t+8>>2],yt[f[f[t>>2]+20>>2]](t,f[o+24>>2],f[o+20>>2],f[o+20>>2],1,1&n[o+15|0]),1&n[f[o+24>>2]+53|0]&&(n[o+13|0]=1,1&n[f[o+24>>2]+52|0]&&(n[o+14|0]=1)),1&n[o+13|0]?f[f[o+24>>2]+44>>2]=3:f[f[o+24>>2]+44>>2]=4),1&n[o+14|0]||(f[f[o+24>>2]+20>>2]=f[o+20>>2],t=f[o+24>>2],f[t+40>>2]=f[t+40>>2]+1,1!=f[f[o+24>>2]+36>>2]|2!=f[f[o+24>>2]+24>>2]||(n[f[o+24>>2]+54|0]=1))}else t=f[t+8>>2],yt[f[f[t>>2]+24>>2]](t,f[o+24>>2],f[o+20>>2],f[o+16>>2],1&n[o+15|0]);Z=o+32|0},function(t,e,i,r){var n;t|=0,e|=0,i|=0,r|=0,Z=n=Z-16|0,f[n+12>>2]=t,f[n+8>>2]=e,f[n+4>>2]=i,f[n>>2]=r,1&fA(t=f[n+12>>2],f[f[n+8>>2]+8>>2],0)?nA(t,f[n+8>>2],f[n+4>>2],f[n>>2]):(t=f[t+8>>2],yt[f[f[t>>2]+28>>2]](t,f[n+8>>2],f[n+4>>2],f[n>>2])),Z=n+16|0},function(t){var e;t|=0,Z=e=Z-16|0,f[e+12>>2]=t,iA(t=f[e+12>>2]),$(t),Z=e+16|0},function(t,e,i,r,a,o){var _;if(t|=0,e|=0,i|=0,r|=0,a|=0,o|=0,Z=_=Z-32|0,f[_+28>>2]=t,f[_+24>>2]=e,f[_+20>>2]=i,f[_+16>>2]=r,f[_+12>>2]=a,n[_+11|0]=o,1&fA(t=f[_+28>>2],f[f[_+24>>2]+8>>2],1&n[_+11|0]))oA(t,f[_+24>>2],f[_+20>>2],f[_+16>>2],f[_+12>>2]);else{if(n[_+10|0]=1&n[f[_+24>>2]+52|0],n[_+9|0]=1&n[f[_+24>>2]+53|0],f[_+4>>2]=(t+16|0)+(f[t+12>>2]<<3),f[_>>2]=t+16,n[f[_+24>>2]+52|0]=0,n[f[_+24>>2]+53|0]=0,bA(f[_>>2],f[_+24>>2],f[_+20>>2],f[_+16>>2],f[_+12>>2],1&n[_+11|0]),n[_+10|0]=0!=(1&n[_+10|0]|1&n[f[_+24>>2]+52|0]),n[_+9|0]=0!=(1&n[_+9|0]|1&n[f[_+24>>2]+53|0]),e=f[_>>2]+8|0,f[_>>2]=e,e>>>0>2])for(;;){t:if(!(1&n[f[_+24>>2]+54|0])){if(1&n[f[_+24>>2]+52|0]){if(!(2&f[t+8>>2])|1==f[f[_+24>>2]+24>>2])break t}else if(!(1&f[t+8>>2])&&1&n[f[_+24>>2]+53|0])break t;if(n[f[_+24>>2]+52|0]=0,n[f[_+24>>2]+53|0]=0,bA(f[_>>2],f[_+24>>2],f[_+20>>2],f[_+16>>2],f[_+12>>2],1&n[_+11|0]),n[_+10|0]=0!=(1&n[_+10|0]|1&n[f[_+24>>2]+52|0]),n[_+9|0]=0!=(1&n[_+9|0]|1&n[f[_+24>>2]+53|0]),e=f[_>>2]+8|0,f[_>>2]=e,e>>>0>2])continue}break}n[f[_+24>>2]+52|0]=1&n[_+10|0],n[f[_+24>>2]+53|0]=1&n[_+9|0]}Z=_+32|0},function(t,e,i,r,a){var o;if(t|=0,e|=0,i|=0,r|=0,a|=0,Z=o=Z-48|0,f[o+44>>2]=t,f[o+40>>2]=e,f[o+36>>2]=i,f[o+32>>2]=r,n[o+31|0]=a,1&fA(t=f[o+44>>2],f[f[o+40>>2]+8>>2],1&n[o+31|0]))cA(t,f[o+40>>2],f[o+36>>2],f[o+32>>2]);else t:if(1&fA(t,f[f[o+40>>2]>>2],1&n[o+31|0])){if(f[o+36>>2]==f[f[o+40>>2]+20>>2]||f[o+36>>2]==f[f[o+40>>2]+16>>2]){1==f[o+32>>2]&&(f[f[o+40>>2]+32>>2]=1);break t}if(f[f[o+40>>2]+32>>2]=f[o+32>>2],n[o+30|0]=0,4!=f[f[o+40>>2]+44>>2]){for(n[o+29|0]=0,f[o+24>>2]=(t+16|0)+(f[t+12>>2]<<3),f[o+20>>2]=t+16;;){e:if(!(d[o+20>>2]>=d[o+24>>2]||(n[f[o+40>>2]+52|0]=0,n[f[o+40>>2]+53|0]=0,bA(f[o+20>>2],f[o+40>>2],f[o+36>>2],f[o+36>>2],1,1&n[o+31|0]),1&n[f[o+40>>2]+54|0]))){if(1&n[f[o+40>>2]+53|0])if(n[o+29|0]=1,1&n[f[o+40>>2]+52|0]){if(n[o+30|0]=1,!(2&f[t+8>>2])|1==f[f[o+40>>2]+24>>2])break e}else if(!(1&f[t+8>>2]))break e;f[o+20>>2]=f[o+20>>2]+8;continue}break}1&n[o+29|0]?f[f[o+40>>2]+44>>2]=3:f[f[o+40>>2]+44>>2]=4}1&n[o+30|0]||(f[f[o+40>>2]+20>>2]=f[o+36>>2],t=f[o+40>>2],f[t+40>>2]=f[t+40>>2]+1,1!=f[f[o+40>>2]+36>>2]|2!=f[f[o+40>>2]+24>>2]||(n[f[o+40>>2]+54|0]=1))}else if(f[o+16>>2]=(t+16|0)+(f[t+12>>2]<<3),f[o+12>>2]=t+16,lA(f[o+12>>2],f[o+40>>2],f[o+36>>2],f[o+32>>2],1&n[o+31|0]),e=f[o+12>>2]+8|0,f[o+12>>2]=e,e>>>0>2])if(1==f[f[o+40>>2]+36>>2]||2&f[t+8>>2])for(;!(1&n[f[o+40>>2]+54|0])&&(lA(f[o+12>>2],f[o+40>>2],f[o+36>>2],f[o+32>>2],1&n[o+31|0]),t=f[o+12>>2]+8|0,f[o+12>>2]=t,t>>>0>2]););else if(1&f[t+8>>2])for(;!(!!(1&n[f[o+40>>2]+54|0])|!(1!=f[f[o+40>>2]+36>>2]|1!=f[f[o+40>>2]+24>>2]))&&(lA(f[o+12>>2],f[o+40>>2],f[o+36>>2],f[o+32>>2],1&n[o+31|0]),t=f[o+12>>2]+8|0,f[o+12>>2]=t,t>>>0>2]););else for(;!(!!(1&n[f[o+40>>2]+54|0])|1==f[f[o+40>>2]+36>>2])&&(lA(f[o+12>>2],f[o+40>>2],f[o+36>>2],f[o+32>>2],1&n[o+31|0]),t=f[o+12>>2]+8|0,f[o+12>>2]=t,t>>>0>2]););Z=o+48|0},function(t,e,i,r){var a;if(t|=0,e|=0,i|=0,r|=0,Z=a=Z-32|0,f[a+28>>2]=t,f[a+24>>2]=e,f[a+20>>2]=i,f[a+16>>2]=r,1&fA(t=f[a+28>>2],f[f[a+24>>2]+8>>2],0))nA(t,f[a+24>>2],f[a+20>>2],f[a+16>>2]);else if(f[a+12>>2]=(t+16|0)+(f[t+12>>2]<<3),f[a+8>>2]=t+16,aA(f[a+8>>2],f[a+24>>2],f[a+20>>2],f[a+16>>2]),t=f[a+8>>2]+8|0,f[a+8>>2]=t,t>>>0>2])for(;aA(f[a+8>>2],f[a+24>>2],f[a+20>>2],f[a+16>>2]),!(1&n[f[a+24>>2]+54|0])&&(t=f[a+8>>2]+8|0,f[a+8>>2]=t,t>>>0>2]););Z=a+32|0},sA,kA,function(){(function(){var t;Z=t=Z-16|0,f[t+12>>2]=5367,f[t+8>>2]=0,j(f[752],f[t+12>>2],f[t+8>>2]),function(t){var e;Z=e=Z-16|0,f[e+12>>2]=0,j(t,5365,0),Z=e+16|0}(f[752]),F()})(),F()},sA,kA,function(t,e){t|=0,e|=0;var i=0;return(t=0|yt[f[742]](3+(t+e|0)|0))&&(f[(i=3+(t+e|0)&0-e)+-4>>2]=t),0|i},function(t){(t|=0)&&yt[f[743]](f[t+-4>>2])},function(t){return 0|K(t|=0)},function(t){L(t|=0)},sA,kA,function(t,e,i){t|=0,e|=0,i|=0;var r,n=0,a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0);Z=r=Z-96|0,f[(n=r+44|0)>>2]=0,f[n+4>>2]=0,f[(n=r+56|0)>>2]=0,f[n+4>>2]=0,f[r+52>>2]=1065353216,f[(n=r+76|0)>>2]=0,f[n+4>>2]=0,f[r+72>>2]=1065353216,f[(n=r+84|0)>>2]=0,f[n+4>>2]=0,f[r+92>>2]=0,f[r+36>>2]=0,f[r+40>>2]=0,f[r+32>>2]=1065353216,f[r+64>>2]=0,f[r+68>>2]=0,yt[f[f[t>>2]+8>>2]](t,r+32|0,r+16|0,r),h=C[r>>2],d=C[r+16>>2],a=v(h-d),_=v(a*a),a=C[r+4>>2],g=C[r+20>>2],o=v(a-g),y=v(_+v(o*o)),o=C[r+8>>2],_=C[r+24>>2],m=v(o-_),C[i>>2]=v(E(v(y+v(m*m))))*v(.5),f[e+12>>2]=0,C[e+8>>2]=v(o+_)*v(.5),C[e+4>>2]=v(a+g)*v(.5),C[e>>2]=v(h+d)*v(.5),Z=r+96|0},function(t){t|=0;var e,i=v(0),r=v(0);return Z=e=Z-32|0,yt[f[f[t>>2]+12>>2]](t,e+16|0,e+12|0),Z=e+32|0,i=C[e+16>>2],r=v(i*i),i=C[e+20>>2],r=v(r+v(i*i)),i=C[e+24>>2],v(v(C[e+12>>2]+v(E(v(r+v(i*i))))))},function(t,e){return t|=0,e=v(e),v(v(v(yt[f[f[t>>2]+16>>2]](t))*e))},function(t,e){f[(t|=0)+8>>2]=1065353216,f[t+12>>2]=0,f[t>>2]=1065353216,f[t+4>>2]=1065353216},yA,QA,function(t,e){var i,r,n=0,a=0,o=0,_=0;a=e|=0,o=0|yt[f[f[(t|=0)>>2]+52>>2]](t),_=1,n=f[f[e>>2]+16>>2],r=0|yt[n](0|a,0|o,0|_),_=e,o=r,a=0|yt[f[f[t>>2]+56>>2]](t,f[r+8>>2],e),i=t,n=f[f[e>>2]+20>>2],yt[n](0|_,0|o,0|a,1346455635,0|i)},function(t,e,i,r,n,a,o){t|=0,e|=0,i|=0,r|=0,n|=0,a|=0,o|=0;var _,h,d,g,m,y,p,R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0),Gt=v(0),Lt=v(0),wt=v(0),xt=v(0),Qt=v(0),Wt=v(0),Yt=v(0),Pt=v(0);Z=_=Z-48|0,f[_+44>>2]=0,R=C[i>>2],D=C[i+4>>2],B=C[i+8>>2],C[_+32>>2]=v(v(C[e>>2]*R)+v(C[e+16>>2]*D))+v(C[e+32>>2]*B),h=e+24|0,d=e+40|0,C[_+40>>2]=v(v(R*C[e+8>>2])+v(D*C[h>>2]))+v(B*C[d>>2]),g=e+20|0,m=e+36|0,C[_+36>>2]=v(v(R*C[e+4>>2])+v(D*C[g>>2]))+v(B*C[m>>2]),yt[f[f[t>>2]+64>>2]](_+16|0,t,_+32|0),Q=C[(y=e+56|0)>>2],W=C[d>>2],Y=C[m>>2],G=C[(p=e+52|0)>>2],z=C[h>>2],pt=C[g>>2],Dt=C[e+32>>2],w=C[e+48>>2],It=C[e+8>>2],St=C[e>>2],Tt=C[e+4>>2],Et=C[e+16>>2],R=C[_+24>>2],D=C[_+16>>2],B=C[_+20>>2],f[_+12>>2]=0,C[_+8>>2]=-C[_+40>>2],C[_+4>>2]=-C[_+36>>2],C[_>>2]=-C[_+32>>2],yt[f[f[t>>2]+64>>2]](_+16|0,t,_),Ot=C[y>>2],Nt=C[d>>2],Ft=C[m>>2],Vt=C[p>>2],Gt=C[h>>2],Lt=C[g>>2],wt=C[e+32>>2],xt=C[e+48>>2],Qt=C[e+8>>2],Wt=C[e>>2],Yt=C[e+4>>2],Pt=C[e+16>>2],E=C[_+24>>2],F=C[_+16>>2],V=C[_+20>>2],w=v(w+v(v(v(D*St)+v(B*Tt))+v(R*It))),G=v(G+v(v(v(D*Et)+v(B*pt))+v(R*z))),R=v(Q+v(v(v(D*Dt)+v(B*Y))+v(R*W))),C[r>>2]=v(v(w*C[i>>2])+v(G*C[i+4>>2]))+v(R*C[i+8>>2]),D=v(xt+v(v(v(F*Wt)+v(V*Yt))+v(E*Qt))),B=v(Vt+v(v(v(F*Pt)+v(V*Lt))+v(E*Gt))),E=v(Ot+v(v(v(F*wt)+v(V*Ft))+v(E*Nt))),C[n>>2]=v(v(D*C[i>>2])+v(B*C[i+4>>2]))+v(E*C[i+8>>2]),f[o+12>>2]=0,C[o+8>>2]=E,C[o+4>>2]=B,C[o>>2]=D,f[a+12>>2]=0,C[a+8>>2]=R,C[a+4>>2]=G,C[a>>2]=w,(F=C[r>>2])>(V=C[n>>2])&&(C[r>>2]=V,C[n>>2]=F,f[o+12>>2]=0,C[o+8>>2]=R,C[o+4>>2]=G,C[o>>2]=w,f[a+12>>2]=0,C[a+8>>2]=E,C[a+4>>2]=B,C[a>>2]=D),Z=_+48|0},pA,function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n,a,o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0);f[(n=Z-16|0)+12>>2]=0,a=t+32|0,t=f[t+56>>2],_=C[a+((t+2|0)%3<<2)>>2],C[n+8>>2]=_,C[n+4>>2]=_,C[n>>2]=_,C[(t<<=2)+n>>2]=_+C[t+a>>2],_=C[e+56>>2],D=C[e+40>>2],B=C[e+36>>2],p=C[e+52>>2],g=C[e+24>>2],E=C[e+20>>2],F=C[e+32>>2],V=C[e+16>>2],R=C[e+48>>2],h=C[e+8>>2],o=C[e>>2],d=C[e+4>>2],f[i+12>>2]=0,m=v(y(o)),o=C[n>>2],G=v(y(d)),d=C[n+4>>2],w=v(y(h)),h=C[n+8>>2],m=v(v(v(m*o)+v(G*d))+v(w*h)),C[i>>2]=R-m,g=v(v(v(o*v(y(V)))+v(d*v(y(E))))+v(h*v(y(g)))),C[i+4>>2]=p-g,o=v(v(v(o*v(y(F)))+v(d*v(y(B))))+v(h*v(y(D)))),C[i+8>>2]=_-o,C[r>>2]=R+m,C[r+4>>2]=p+g,C[r+8>>2]=_+o,f[r+12>>2]=0},function(t,e){t|=0,e|=0;var i,r,n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0);n=C[t+20>>2],a=C[(i=t+36|0)>>2],o=C[t+24>>2],_=C[(r=t+40|0)>>2],h=C[t+16>>2],d=C[t+32>>2],EA(t,e),g=C[e>>2],m=C[e+4>>2],y=C[e+8>>2],f[t+44>>2]=0,C[r>>2]=y*v(_/o),C[i>>2]=m*v(a/n),C[t+32>>2]=g*v(d/h),f[t+48>>2]=f[(t+32|0)+((f[t+56>>2]+2|0)%3<<2)>>2]},Qe,function(t,e,i){t|=0,e=v(e),i|=0;var r,n=v(0),a=v(0),o=0,_=0,h=v(0);r=t+32|0,_=f[t+56>>2],o=f[r+((_+2|0)%3<<2)>>2],f[(t=Z-16|0)+12>>2]=0,f[t+8>>2]=o,f[t+4>>2]=o,f[t>>2]=o,C[(_=(o=_<<2)+t|0)>>2]=C[o+r>>2]+C[_>>2],e=v(e*v(.0833333283662796)),n=C[t>>2],n=v(n+n),n=v(n*n),a=C[t+4>>2],a=v(a+a),a=v(a*a),C[i+8>>2]=e*v(n+a),h=n,n=C[t+8>>2],n=v(n+n),n=v(n*n),C[i+4>>2]=e*v(h+n),C[i>>2]=e*v(a+n)},function(t){return 6444},FA,WA,function(t){return v(C[(t|=0)+48>>2])},wA,function(t,e,i){return QA(t|=0,e|=0,i|=0),f[e+28>>2]=f[t+32>>2],f[e+32>>2]=f[t+36>>2],f[e+36>>2]=f[t+40>>2],f[e+40>>2]=f[t+44>>2],f[e+12>>2]=f[t+16>>2],f[e+16>>2]=f[t+20>>2],f[e+20>>2]=f[t+24>>2],f[e+24>>2]=f[t+28>>2],f[e+48>>2]=0,f[e+44>>2]=f[t+48>>2],t=f[t+56>>2],f[e+56>>2]=0,f[e+52>>2]=t,6457},function(t,e,i){t|=0,e|=0,i|=0;var r=v(0),n=v(0),a=v(0),o=v(0),_=v(0);yt[f[f[e>>2]+68>>2]](t,e,i),v(yt[f[f[e>>2]+48>>2]](e))!=v(0)&&(n=C[i+4>>2],r=C[i>>2],a=C[i+8>>2],o=v(yt[f[f[e>>2]+48>>2]](e)),_=r=(e=v(v(v(r*r)+v(n*n))+v(a*a))>2]=C[t>>2]+v(o*v(_*r)),C[t+4>>2]=C[t+4>>2]+v(o*v(n*r)),C[t+8>>2]=C[t+8>>2]+v(o*v(a*r)))},function(t,e,i){t|=0,e|=0,i|=0;var r,n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=0,g=v(0),m=v(0),y=v(0),p=v(0);r=Z-16|0,f[t>>2]=0,f[t+4>>2]=0,f[(d=t+8|0)>>2]=0,f[d+4>>2]=0,_=C[i>>2],o=C[i+4>>2],a=C[i+8>>2],(n=v(v(v(_*_)+v(o*o))+v(a*a)))>2]=0,f[r+12>>2]=0,f[r>>2]=0,f[r+4>>2]=0,d=(i=f[e+56>>2]<<2)+r|0,h=C[32+(e+i|0)>>2],C[d>>2]=h,_=v(-0xde0b6b000000000),m=C[r>>2],y=C[r+4>>2],p=C[r+8>>2],(o=v(v(v(n*m)+v(a*y))+v(g*p)))>v(-0xde0b6b000000000)&&(f[t+12>>2]=f[r+12>>2],C[t+8>>2]=p,C[t+4>>2]=y,C[t>>2]=m,_=o),f[r+8>>2]=0,f[r+12>>2]=0,f[r>>2]=0,f[r+4>>2]=0,C[d>>2]=-h,o=C[r>>2],h=a,a=C[r+4>>2],h=v(v(n*o)+v(h*a)),n=C[r+8>>2],v(h+v(g*n))>_&&(f[t+12>>2]=f[r+12>>2],C[t+8>>2]=n,C[t+4>>2]=a,C[t>>2]=o)},function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n,a=0,o=0,_=0,h=v(0),d=v(0),g=v(0),m=v(0),y=0,p=0,R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=0;if(n=Z-16|0,(0|r)>=1)for(;f[(a=n+8|0)>>2]=0,f[a+4>>2]=0,f[n>>2]=0,f[n+4>>2]=0,y=(o=(_=f[t+56>>2])<<2)+n|0,d=C[(o=32+(t+o|0)|0)>>2],f[y>>2]=f[o>>2],D=v(-0xde0b6b000000000),B=C[n>>2],h=C[(o=e+p|0)>>2],E=C[n+4>>2],g=C[(y=o+4|0)>>2],F=C[a>>2],R=C[(V=o+8|0)>>2],(m=v(v(v(B*h)+v(E*g))+v(F*R)))>v(-0xde0b6b000000000)&&(C[(_=i+p|0)>>2]=B,f[_+12>>2]=f[n+12>>2],C[_+8>>2]=F,C[_+4>>2]=E,R=C[V>>2],g=C[y>>2],_=f[t+56>>2],d=C[32+((_<<2)+t|0)>>2],h=C[o>>2],D=m),f[a>>2]=0,f[a+4>>2]=0,f[n>>2]=0,f[n+4>>2]=0,C[(_<<2)+n>>2]=-d,d=C[n>>2],m=C[n+4>>2],g=v(v(d*h)+v(m*g)),h=C[a>>2],v(g+v(h*R))>D&&(C[(a=i+p|0)>>2]=d,f[a+12>>2]=f[n+12>>2],C[a+8>>2]=h,C[a+4>>2]=m),p=p+16|0,r=r+-1|0;);},function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n,a,o=v(0),_=v(0),h=v(0),d=0,g=0,m=v(0);for(Z=n=Z-80|0,m=v(yt[f[f[t>>2]+48>>2]](t)),a=n+72|0;f[a>>2]=0,f[a+4>>2]=0,f[n+64>>2]=0,f[n+68>>2]=0,f[(g=(n- -64|0)+d|0)>>2]=1065353216,f[n+44>>2]=0,o=C[n+64>>2],_=C[n+68>>2],h=C[a>>2],C[n+40>>2]=v(v(o*C[e+8>>2])+v(_*C[e+24>>2]))+v(h*C[e+40>>2]),C[n+36>>2]=v(v(o*C[e+4>>2])+v(_*C[e+20>>2]))+v(h*C[e+36>>2]),C[n+32>>2]=v(v(o*C[e>>2])+v(_*C[e+16>>2]))+v(h*C[e+32>>2]),yt[f[f[t>>2]+64>>2]](n+48|0,t,n+32|0),f[n+44>>2]=0,o=C[n+48>>2],_=C[n+52>>2],h=C[n+56>>2],C[n+40>>2]=v(v(v(o*C[e+32>>2])+v(_*C[e+36>>2]))+v(h*C[e+40>>2]))+C[e+56>>2],C[n+36>>2]=v(v(v(o*C[e+16>>2])+v(_*C[e+20>>2]))+v(h*C[e+24>>2]))+C[e+52>>2],C[n+32>>2]=v(v(v(o*C[e>>2])+v(_*C[e+4>>2]))+v(h*C[e+8>>2]))+C[e+48>>2],f[g>>2]=-1082130432,g=(n+32|0)+d|0,C[r+d>>2]=m+C[g>>2],f[n+12>>2]=0,o=C[n+64>>2],_=C[n+68>>2],h=C[a>>2],C[n+8>>2]=v(v(o*C[e+8>>2])+v(_*C[e+24>>2]))+v(h*C[e+40>>2]),C[n+4>>2]=v(v(o*C[e+4>>2])+v(_*C[e+20>>2]))+v(h*C[e+36>>2]),C[n>>2]=v(v(o*C[e>>2])+v(_*C[e+16>>2]))+v(h*C[e+32>>2]),yt[f[f[t>>2]+64>>2]](n+16|0,t,n),f[n+44>>2]=0,o=C[n+16>>2],_=C[n+20>>2],h=C[n+24>>2],C[n+40>>2]=v(v(v(o*C[e+32>>2])+v(_*C[e+36>>2]))+v(h*C[e+40>>2]))+C[e+56>>2],C[n+36>>2]=v(v(v(o*C[e+16>>2])+v(_*C[e+20>>2]))+v(h*C[e+24>>2]))+C[e+52>>2],C[n+32>>2]=v(v(v(o*C[e>>2])+v(_*C[e+4>>2]))+v(h*C[e+8>>2]))+C[e+48>>2],C[i+d>>2]=C[g>>2]-m,12!=(0|(d=d+4|0)););Z=n+80|0},we,De,pA,function(t){return 6476},pA,function(t){return 6485},pA,$A,function(t,e){t|=0,e|=0;var i,r=0,n=v(0),a=v(0);r=f[t+72>>2]<<2,i=t+16|0,a=v(C[t+64>>2]*v(C[r+e>>2]/C[r+i>>2])),C[t+64>>2]=a,r=f[t+68>>2]<<2,n=v(C[r+e>>2]/C[r+i>>2]),r=f[t+76>>2]<<2,n=v(C[t+60>>2]*v(v(n+v(C[r+e>>2]/C[r+i>>2]))*v(.5))),C[t+60>>2]=n,C[t+56>>2]=n/v(E(v(v(a*a)+v(n*n)))),EA(t,e)},function(t,e,i){t|=0,e=v(e),i|=0;var r,n=v(0),a=0,o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0);Z=r=Z-96|0,f[(a=r+44|0)>>2]=0,f[a+4>>2]=0,f[(a=r+56|0)>>2]=0,f[a+4>>2]=0,f[r+52>>2]=1065353216,f[(a=r+76|0)>>2]=0,f[a+4>>2]=0,f[r+72>>2]=1065353216,f[(a=r+84|0)>>2]=0,f[a+4>>2]=0,f[r+92>>2]=0,f[r+36>>2]=0,f[r+40>>2]=0,f[r+32>>2]=1065353216,f[r+64>>2]=0,f[r+68>>2]=0,yt[f[f[t>>2]+8>>2]](t,r+32|0,r+16|0,r),h=C[r+24>>2],d=C[r+8>>2],o=C[r+16>>2],_=C[r>>2],g=C[r+20>>2],m=C[r+4>>2],n=v(yt[f[f[t>>2]+48>>2]](t)),f[i+12>>2]=0,e=v(e*v(.0833333283662796)),o=v(n+v(v(_-o)*v(.5))),o=v(o+o),o=v(o*o),_=v(n+v(v(m-g)*v(.5))),_=v(_+_),_=v(_*_),C[i+8>>2]=e*v(o+_),n=v(n+v(v(d-h)*v(.5))),n=v(n+n),n=v(n*n),C[i+4>>2]=e*v(o+n),C[i>>2]=e*v(_+n),Z=r+96|0},function(t){return 6880},function(t,e){f[(t|=0)+8>>2]=0,f[t+12>>2]=0,f[t>>2]=0,f[t+4>>2]=1065353216},Ge,wA,function(t,e,i){return QA(t|=0,e|=0,i|=0),f[e+28>>2]=f[t+32>>2],f[e+32>>2]=f[t+36>>2],f[e+36>>2]=f[t+40>>2],f[e+40>>2]=f[t+44>>2],f[e+12>>2]=f[t+16>>2],f[e+16>>2]=f[t+20>>2],f[e+20>>2]=f[t+24>>2],f[e+24>>2]=f[t+28>>2],f[e+48>>2]=0,f[e+44>>2]=f[t+48>>2],t=f[t+72>>2],f[e+56>>2]=0,f[e+52>>2]=t,6885},function(t,e,i){t|=0,e|=0,i|=0;var r,n,a=v(0),o=v(0),_=v(0),h=v(0),d=0,g=v(0);o=v(C[e+64>>2]*v(.5)),r=f[e+68>>2],d=(n=f[e+72>>2])<<2,a=C[i>>2],h=v(a*a),a=C[i+4>>2],h=v(h+v(a*a)),a=C[i+8>>2];t:{if(C[d+i>>2]>v(C[e+56>>2]*v(E(v(h+v(a*a))))))f[(r<<2)+t>>2]=0,C[t+d>>2]=o,d=f[e+76>>2];else{if(a=C[(r<<2)+i>>2],d=f[e+76>>2],_=C[(d<<2)+i>>2],(g=v(E(v(v(a*a)+v(_*_)))))>v(1.1920928955078125e-7)){h=a,a=v(C[e+60>>2]/g),C[(r<<2)+t>>2]=h*a,C[(n<<2)+t>>2]=-o,o=v(_*a);break t}f[(r<<2)+t>>2]=0,C[(n<<2)+t>>2]=-o}o=v(0)}C[(d<<2)+t>>2]=o,v(yt[f[f[e>>2]+48>>2]](e))!=v(0)&&(o=C[i+4>>2],a=C[i>>2],_=C[i+8>>2],g=v(yt[f[f[e>>2]+48>>2]](e)),h=a=(e=v(v(v(a*a)+v(o*o))+v(_*_))>2]=C[t>>2]+v(g*v(h*a)),C[t+4>>2]=C[t+4>>2]+v(g*v(o*a)),C[t+8>>2]=C[t+8>>2]+v(g*v(_*a)))},function(t,e,i){t|=0,e|=0,i|=0;var r,n,a=v(0),o=v(0),_=v(0),h=0,d=v(0),g=v(0);o=v(C[e+64>>2]*v(.5)),r=f[e+68>>2],h=(n=f[e+72>>2])<<2,a=C[i>>2],_=v(a*a),a=C[i+4>>2],_=v(_+v(a*a)),a=C[i+8>>2];t:{if(C[h+i>>2]>v(C[e+56>>2]*v(E(v(_+v(a*a))))))f[(r<<2)+t>>2]=0,C[t+h>>2]=o,i=f[e+76>>2];else{if(a=C[(r<<2)+i>>2],h=i,i=f[e+76>>2],d=C[h+(i<<2)>>2],(g=v(E(v(v(a*a)+v(d*d)))))>v(1.1920928955078125e-7)){_=a,a=v(C[e+60>>2]/g),C[(r<<2)+t>>2]=_*a,C[(n<<2)+t>>2]=-o,o=v(d*a);break t}f[(r<<2)+t>>2]=0,C[(n<<2)+t>>2]=-o}o=v(0)}C[(i<<2)+t>>2]=o},function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n,a=v(0),o=0,_=0,h=v(0),d=v(0),g=0,m=v(0),y=v(0);if(n=Z-16|0,(0|r)>=1)for(;;){h=v(C[t+64>>2]*v(.5)),o=f[t+68>>2],_=f[t+72>>2]<<2,a=C[e>>2],d=v(a*a),a=C[e+4>>2],d=v(d+v(a*a)),a=C[e+8>>2];t:{if(C[_+e>>2]>v(C[t+56>>2]*v(E(v(d+v(a*a))))))f[(o<<2)+n>>2]=0,C[n+_>>2]=h,o=f[t+76>>2];else{if(a=C[(g=o<<2)+e>>2],o=f[t+76>>2],m=C[(o<<2)+e>>2],(y=v(E(v(v(a*a)+v(m*m)))))>v(1.1920928955078125e-7)){d=a,a=v(C[t+60>>2]/y),C[n+g>>2]=d*a,C[n+_>>2]=-h,h=v(m*a);break t}f[n+g>>2]=0,C[n+_>>2]=-h}h=v(0)}if(C[(o<<2)+n>>2]=h,g=f[(o=n+8|0)+4>>2],f[(_=i+8|0)>>2]=f[o>>2],f[_+4>>2]=g,_=f[n+4>>2],f[i>>2]=f[n>>2],f[i+4>>2]=_,e=e+16|0,i=i+16|0,!(r=r+-1|0))break}},pA,function(t){return 6901},function(t,e){f[(t|=0)+8>>2]=1065353216,f[t+12>>2]=0,f[t>>2]=0,f[t+4>>2]=0},pA,function(t){return 6907},function(t,e){f[(t|=0)+8>>2]=0,f[t+12>>2]=0,f[t>>2]=1065353216,f[t+4>>2]=0},kA,EA,ye,function(t,e,i){return QA(t|=0,e|=0,i|=0),f[e+28>>2]=f[t+32>>2],f[e+32>>2]=f[t+36>>2],f[e+36>>2]=f[t+40>>2],f[e+40>>2]=f[t+44>>2],f[e+12>>2]=f[t+16>>2],f[e+16>>2]=f[t+20>>2],f[e+20>>2]=f[t+24>>2],f[e+24>>2]=f[t+28>>2],f[e+48>>2]=0,f[e+44>>2]=f[t+48>>2],8329},ZA,function(t){CA(ZA(t|=0))},Ae,kA,function(t,e,i){t|=0,e=v(e),i|=0;var r,n=v(0),a=0,o=v(0),_=v(0);Z=r=Z-96|0,n=v(yt[f[f[t>>2]+48>>2]](t)),f[(a=r+44|0)>>2]=0,f[a+4>>2]=0,f[(a=r+56|0)>>2]=0,f[a+4>>2]=0,f[r+52>>2]=1065353216,f[(a=r+76|0)>>2]=0,f[a+4>>2]=0,f[r+72>>2]=1065353216,f[(a=r+84|0)>>2]=0,f[a+4>>2]=0,f[r+92>>2]=0,f[r+36>>2]=0,f[r+40>>2]=0,f[r+32>>2]=1065353216,f[r+64>>2]=0,f[r+68>>2]=0,yt[f[f[t>>2]+8>>2]](t,r+32|0,r+16|0,r),f[i+12>>2]=0,e=v(e*v(.0833333283662796)),o=v(n+v(v(C[r>>2]-C[r+16>>2])*v(.5))),o=v(o+o),o=v(o*o),_=v(n+v(v(C[r+4>>2]-C[r+20>>2])*v(.5))),_=v(_+_),_=v(_*_),C[i+8>>2]=e*v(o+_),n=v(n+v(v(C[r+8>>2]-C[r+24>>2])*v(.5))),n=v(n+n),n=v(n*n),C[i+4>>2]=e*v(o+n),C[i>>2]=e*v(_+n),Z=r+96|0},function(t,e,i){t|=0,e|=0,i|=0;var r,n=0,a=v(0),o=v(0),_=0,h=v(0),d=v(0),g=0,m=0,y=0,p=v(0),R=v(0);if(Z=r=Z-2048|0,f[t>>2]=0,f[t+4>>2]=0,f[(n=t+8|0)>>2]=0,f[n+4>>2]=0,h=C[i>>2],d=C[i+4>>2],a=C[i+8>>2],(o=v(v(v(h*h)+v(d*d))+v(a*a)))>2]+96>>2]](e))>=1)for(o=v(-0xde0b6b000000000);;){if(g=128,((0|yt[f[f[e>>2]+96>>2]](e))-m|0)>127||(0|(g=(0|yt[f[f[e>>2]+96>>2]](e))-m|0))>=1){for(i=0,n=r;yt[f[f[e>>2]+108>>2]](e,i,n),n=n+16|0,(0|g)!=(0|(i=i+1|0)););for(n=0,y=-1,a=v(-34028234663852886e22),i=r;a=(_=(d=v(v(v(h*C[i>>2])+v(R*C[i+4>>2]))+v(p*C[i+8>>2])))>a)?d:a,y=_?n:y,i=i+16|0,(0|(n=n+1|0))!=(0|g););}else a=v(-34028234663852886e22),y=-1;if(a>o&&(i=f[(_=(y<<4)+r|0)+12>>2],f[(n=t+8|0)>>2]=f[_+8>>2],f[n+4>>2]=i,i=f[_+4>>2],f[t>>2]=f[_>>2],f[t+4>>2]=i,o=a),!((0|(m=m+128|0))<(0|yt[f[f[e>>2]+96>>2]](e))))break}Z=r+2048|0},function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n,a=0,o=0,_=v(0),h=0,d=0,g=0,m=0,y=0,p=0,R=0,D=v(0),B=0,E=0,F=0,V=v(0),G=v(0),w=v(0);if(Z=n=Z-2048|0,!((0|r)<1)){for(o=i+12|0,a=r;f[o>>2]=-581039253,o=o+16|0,a=a+-1|0;);if(!((0|r)<1))for(;;){if((0|yt[f[f[t>>2]+96>>2]](t))>=1)for(R=(g=(a=y<<4)+i|0)+12|0,E=(p=e+a|0)+8|0,F=p+4|0,d=0;;){if(m=128,((0|yt[f[f[t>>2]+96>>2]](t))-d|0)>127||(0|(m=(0|yt[f[f[t>>2]+96>>2]](t))-d|0))>=1){for(o=0,a=n;yt[f[f[t>>2]+108>>2]](t,o,a),a=a+16|0,(0|m)!=(0|(o=o+1|0)););for(V=C[E>>2],G=C[F>>2],w=C[p>>2],a=0,h=-1,_=v(-34028234663852886e22),o=n;_=(B=(D=v(v(v(w*C[o>>2])+v(G*C[o+4>>2]))+v(V*C[o+8>>2])))>_)?D:_,h=B?a:h,o=o+16|0,(0|m)!=(0|(a=a+1|0)););}else _=v(-34028234663852886e22),h=-1;if(_>C[R>>2]&&(h=f[(a=(h<<4)+n|0)+12>>2],f[(o=g+8|0)>>2]=f[a+8>>2],f[o+4>>2]=h,o=f[a+4>>2],f[g>>2]=f[a>>2],f[g+4>>2]=o,C[R>>2]=_),!((0|(d=d+128|0))<(0|yt[f[f[t>>2]+96>>2]](t))))break}if((0|(y=y+1|0))==(0|r))break}}Z=n+2048|0},function(t,e){t|=0,e|=0;var i,r,a=0,o=0,h=0,d=0,g=0,p=0,R=0,D=0,B=0,F=v(0),V=v(0),G=v(0),w=0,Q=0,W=0,Y=0,z=v(0),pt=v(0),Dt=0,It=0,St=0,Tt=0,Et=0,Ot=0,Nt=0,Ft=v(0),Vt=0,Gt=0,Lt=v(0),wt=v(0),xt=0,Qt=0;Z=i=Z-240|0,(a=f[t+56>>2])&&(yt[f[f[a>>2]>>2]](a),CA(f[t+56>>2])),function(t){var e=0;f[t>>2]=7060,n[t+20|0]=1,f[t+16>>2]=0,n[t+40|0]=1,f[(e=t+8|0)>>2]=0,f[e+4>>2]=0,f[t+36>>2]=0,n[t+60|0]=1,f[(e=t+28|0)>>2]=0,f[e+4>>2]=0,f[t+56>>2]=0,f[(t=t+48|0)>>2]=0,f[t+4>>2]=0}(a=dA(132)),f[t+56>>2]=a,f[i+228>>2]=0,f[i+220>>2]=0,f[i+224>>2]=0,n[i+232|0]=1;t:if(!((0|yt[f[f[t>>2]+96>>2]](t))<1))for(;;){if((0|h)==(0|p))if((0|h)>=(0|(D=h?h<<1:1)))d=B;else{d=D?dA(D<<4):0;e:{if((0|h)>=1)for(a=d,o=B;R=f[o+4>>2],f[a>>2]=f[o>>2],f[a+4>>2]=R,Y=f[(w=o+8|0)+4>>2],f[(R=a+8|0)>>2]=f[w>>2],f[R+4>>2]=Y,a=a+16|0,o=o+16|0,h=h+-1|0;);else if(!B)break e;_[i+232|0]&&CA(B),f[i+228>>2]=0}f[i+228>>2]=d,n[i+232|0]=1,f[i+224>>2]=D}else d=B;if(f[i+220>>2]=p+1,h=f[i+156>>2],f[(o=(a=p<<4)+d|0)>>2]=f[i+152>>2],f[o+4>>2]=h,h=f[(d=i+160|0)+4>>2],f[(o=o+8|0)>>2]=f[d>>2],f[o+4>>2]=h,B=f[i+228>>2],yt[f[f[t>>2]+108>>2]](t,g,a+B|0),(0|(g=g+1|0))>=(0|yt[f[f[t>>2]+96>>2]](t)))break t;h=f[i+224>>2],p=f[i+220>>2]}if(n[i+188|0]=1,f[i+184>>2]=0,n[i+208|0]=1,f[(a=i+176|0)>>2]=0,f[a+4>>2]=0,f[i+204>>2]=0,f[(a=i+196|0)>>2]=0,f[a+4>>2]=0,f[i+164>>2]=0,n[i+168|0]=1,f[i+156>>2]=0,f[i+160>>2]=0,e){if(f[i+60>>2]=0,n[i+64|0]=1,f[i+52>>2]=0,f[i+56>>2]=0,function(t,e){var i,r=0,a=0,o=v(0),h=0,d=0,g=0,m=v(0),y=v(0),p=v(0),R=0,D=0,B=v(0),F=v(0),V=0,G=0,w=0,Q=0,W=v(0),Y=v(0),Z=0,z=0,yt=v(0),pt=v(0),Dt=v(0),It=0,St=0,Tt=0,Et=0;if((0|(i=f[t+4>>2]))>=1)for(;;){t:if(D=G,G=D+1|0,!((0|G)>=(0|i)))for(a=f[t+12>>2],w=a+(D<<4)|0,It=w+8|0,St=w+4|0,r=G;;){e:if(D=r+1|0,!((0|D)>=(0|i)))for(z=(r<<4)+a|0,Tt=z+8|0,Et=z+4|0,Q=D;;){yt=C[w>>2],m=v(C[z>>2]-yt),r=(Q<<4)+a|0,pt=C[St>>2],B=v(C[r+4>>2]-pt),o=v(C[Et>>2]-pt),y=v(C[r>>2]-yt),W=v(v(m*B)-v(o*y)),Dt=C[It>>2],p=v(C[r+8>>2]-Dt),F=v(o*p),o=v(C[Tt>>2]-Dt),B=v(F-v(o*B)),y=v(v(o*y)-v(m*p));i:if(!(V=(p=v(v(W*W)+v(v(B*B)+v(y*y))))>v(9999999747378752e-20)^1)){if(o=v(v(1)/v(E(p))),F=v(W*o),Y=v(y*o),m=v(B*o),(0|(d=f[e+4>>2]))>=1)for(r=f[e+12>>2],h=d;;){if(v(v(v(m*C[r>>2])+v(Y*C[r+4>>2]))+v(F*C[r+8>>2]))>v(.9990000128746033))break i;if(r=r+16|0,!(h=h+-1|0))break}if(o=v(v(v(m*yt)+v(Y*pt))+v(F*Dt)),(0|(r=f[t+4>>2]))>=1)for(;;){if(v(v(v(v(v(m*C[a>>2])+v(Y*C[a+4>>2]))+v(F*C[a+8>>2]))-o)+v(-.009999999776482582))>v(0))break i;if(a=a+16|0,!(r=r+-1|0))break}if(o=v(-o),f[e+8>>2]==(0|d)&&!((0|d)>=(0|(Z=d?d<<1:1)))){if(Z?(R=dA(Z<<4),d=f[e+4>>2]):R=0,(0|d)>=1)for(r=0;a=f[e+12>>2]+r|0,h=f[a+4>>2],f[(g=r+R|0)>>2]=f[a>>2],f[g+4>>2]=h,h=f[(a=a+8|0)+4>>2],f[(g=g+8|0)>>2]=f[a>>2],f[g+4>>2]=h,r=r+16|0,d=d+-1|0;);(r=f[e+12>>2])&&(_[e+16|0]&&CA(r),f[e+12>>2]=0),f[e+12>>2]=R,n[e+16|0]=1,f[e+8>>2]=Z,d=f[e+4>>2]}r=f[e+12>>2]+(d<<4)|0,C[r+12>>2]=o,C[r+8>>2]=F,C[r+4>>2]=Y,C[r>>2]=m,f[e+4>>2]=f[e+4>>2]+1}i:if(!V){if(o=v(v(1)/v(E(p))),m=v(-v(W*o)),y=v(-v(y*o)),p=v(-v(B*o)),(0|(h=f[e+4>>2]))>=1)for(r=f[e+12>>2],a=h;;){if(v(v(v(C[r>>2]*p)+v(C[r+4>>2]*y))+v(C[r+8>>2]*m))>v(.9990000128746033))break i;if(r=r+16|0,!(a=a+-1|0))break}if(o=v(v(v(C[w>>2]*p)+v(C[St>>2]*y))+v(C[It>>2]*m)),(0|(a=f[t+4>>2]))>=1)for(r=f[t+12>>2];;){if(v(v(v(v(v(C[r>>2]*p)+v(C[r+4>>2]*y))+v(C[r+8>>2]*m))-o)+v(-.009999999776482582))>v(0))break i;if(r=r+16|0,!(a=a+-1|0))break}if(o=v(-o),f[e+8>>2]==(0|h)&&!((0|h)>=(0|(R=h?h<<1:1)))){if(R?(V=dA(R<<4),h=f[e+4>>2]):V=0,(0|h)>=1)for(r=0;a=f[e+12>>2]+r|0,d=f[a+4>>2],f[(g=r+V|0)>>2]=f[a>>2],f[g+4>>2]=d,d=f[(a=a+8|0)+4>>2],f[(g=g+8|0)>>2]=f[a>>2],f[g+4>>2]=d,r=r+16|0,h=h+-1|0;);(r=f[e+12>>2])&&(_[e+16|0]&&CA(r),f[e+12>>2]=0),f[e+12>>2]=V,n[e+16|0]=1,f[e+8>>2]=R,h=f[e+4>>2]}r=f[e+12>>2]+(h<<4)|0,C[r+12>>2]=o,C[r+8>>2]=m,C[r+4>>2]=y,C[r>>2]=p,f[e+4>>2]=f[e+4>>2]+1}if((0|(Q=Q+1|0))==(0|i))break e;a=f[t+12>>2]}if((0|i)==(0|D))break t;a=f[t+12>>2],r=D}if((0|i)==(0|G))break}}(i+216|0,i+48|0),f[i+140>>2]=0,n[i+144|0]=1,f[i+132>>2]=0,f[i+136>>2]=0,f[i+52>>2]>=1)for(d=0;;){if(p=i+112|0,e=f[i+60>>2]+(d<<4)|0,f[p>>2]=f[e+8>>2],a=f[e+4>>2],f[i+104>>2]=f[e>>2],f[i+108>>2]=a,F=v(C[e+12>>2]-v(yt[f[f[t>>2]+48>>2]](t))),(0|(o=f[i+132>>2]))==f[i+136>>2]&&!((0|o)>=(0|(e=o?o<<1:1)))){if(e?(g=dA(e<<4),o=f[i+132>>2]):g=0,(0|o)>=1)for(a=0;h=f[i+140>>2]+a|0,B=f[h+4>>2],f[(R=D=a+g|0)>>2]=f[h>>2],f[R+4>>2]=B,R=f[(h=h+8|0)+4>>2],f[(D=D+8|0)>>2]=f[h>>2],f[D+4>>2]=R,a=a+16|0,o=o+-1|0;);(a=f[i+140>>2])&&(_[i+144|0]&&CA(a),f[i+140>>2]=0),f[i+140>>2]=g,n[i+144|0]=1,f[i+136>>2]=e,o=f[i+132>>2]}if(a=f[i+108>>2],e=f[i+140>>2]+(o<<4)|0,f[e>>2]=f[i+104>>2],f[e+4>>2]=a,C[e+12>>2]=F,f[e+8>>2]=f[p>>2],f[i+132>>2]=f[i+132>>2]+1,!((0|(d=d+1|0))>2]))break}f[i+116>>2]=0,n[i+120|0]=1,f[i+108>>2]=0,f[i+112>>2]=0,function(t,e){var i,r=0,a=0,o=v(0),h=v(0),d=v(0),g=v(0),m=v(0),p=v(0),R=v(0),D=0,B=v(0),E=0,F=0,V=v(0),G=v(0),w=0,Q=0,W=0,Y=0,Z=v(0),z=v(0),yt=0,pt=v(0),Dt=v(0),It=v(0),St=0,Tt=0,Et=0,Ot=0,Nt=0,Ft=0,Vt=0,Gt=0;if((0|(i=f[t+4>>2]))>=1)for(;;){t:if(D=w,w=D+1|0,!((0|w)>=(0|i)))for(a=f[t+12>>2],Q=a+(D<<4)|0,Et=Q+12|0,Ot=Q+4|0,Nt=Q+8|0,r=w;;){e:if(D=r+1|0,!((0|D)>=(0|i)))for(W=(r<<4)+a|0,Ft=W+12|0,Vt=W+8|0,Gt=W+4|0,Y=D;;){g=C[(r=(Y<<4)+a|0)+4>>2],m=C[W>>2],p=C[Gt>>2],h=C[r>>2],R=v(v(g*m)-v(p*h)),d=C[r+8>>2],o=C[Vt>>2],Z=v(v(p*d)-v(o*g)),z=v(v(o*h)-v(d*m));i:if(v(v(R*R)+v(v(Z*Z)+v(z*z)))>v(9999999747378752e-20)&&(B=C[Ot>>2],V=C[Q>>2],pt=v(v(h*B)-v(g*V)),G=C[Nt>>2],Dt=v(v(g*G)-v(d*B)),It=v(v(d*V)-v(h*G)),v(v(pt*pt)+v(v(Dt*Dt)+v(It*It)))>v(9999999747378752e-20)&&(h=v(v(p*V)-v(m*B)),g=v(v(o*B)-v(p*G)),d=v(v(m*G)-v(o*V)),v(v(h*h)+v(v(g*g)+v(d*d)))>v(9999999747378752e-20)&&(o=v(v(G*R)+v(v(B*z)+v(Z*V))),v(y(o))>v(9.999999974752427e-7))))){if(m=v(v(-1)/o),p=C[r+12>>2],B=R,R=C[Et>>2],o=C[Ft>>2],h=v(m*v(v(h*p)+v(v(B*R)+v(pt*o)))),d=v(m*v(v(d*p)+v(v(z*R)+v(It*o)))),o=v(m*v(v(g*p)+v(v(Z*R)+v(Dt*o)))),(0|(r=f[t+4>>2]))>=1)for(;;){if(v(v(C[a+12>>2]+v(v(v(o*C[a>>2])+v(d*C[a+4>>2]))+v(h*C[a+8>>2])))+v(-.009999999776482582))>v(0))break i;if(a=a+16|0,!(r=r+-1|0))break}if((0|(r=f[e+4>>2]))==f[e+8>>2]&&!((0|r)>=(0|(yt=r?r<<1:1)))){if(yt?(St=dA(yt<<4),r=f[e+4>>2]):St=0,(0|r)>=1)for(a=0;F=f[e+12>>2]+a|0,Tt=f[F+4>>2],f[(E=a+St|0)>>2]=f[F>>2],f[E+4>>2]=Tt,Tt=f[(F=F+8|0)+4>>2],f[(E=E+8|0)>>2]=f[F>>2],f[E+4>>2]=Tt,a=a+16|0,r=r+-1|0;);(r=f[e+12>>2])&&(_[e+16|0]&&CA(r),f[e+12>>2]=0),f[e+12>>2]=St,n[e+16|0]=1,f[e+8>>2]=yt,r=f[e+4>>2]}r=f[e+12>>2]+(r<<4)|0,f[r+12>>2]=0,C[r+8>>2]=h,C[r+4>>2]=d,C[r>>2]=o,f[e+4>>2]=f[e+4>>2]+1}if((0|(Y=Y+1|0))==(0|i))break e;a=f[t+12>>2]}if((0|i)==(0|D))break t;a=f[t+12>>2],r=D}if((0|i)==(0|w))break}}(i+128|0,i+104|0),HA(i+152|0,f[i+116>>2],f[i+108>>2]),(e=f[i+116>>2])&&(_[i+120|0]&&CA(e),f[i+116>>2]=0),(e=f[i+140>>2])&&(_[i+144|0]&&CA(e),f[i+140>>2]=0),(e=f[i+60>>2])&&(_[i+64|0]&&CA(e),f[i+60>>2]=0)}else HA(i+152|0,B,f[i+220>>2]);if((0|(e=f[i+196>>2]))<1)a=0;else{for(a=Vt=dA(e<<4),o=e;d=f[i+52>>2],f[a>>2]=f[i+48>>2],f[a+4>>2]=d,h=f[(g=i+56|0)+4>>2],f[(d=a+8|0)>>2]=f[g>>2],f[d+4>>2]=h,a=a+16|0,o=o+-1|0;);a=Vt}r=a,f[i+140>>2]=0,n[i+144|0]=1,f[i+132>>2]=0,f[i+136>>2]=0,n[0|(a=i+63|0)]=0,n[a+1|0]=0,n[a+2|0]=0,n[a+3|0]=0,f[(a=i+56|0)>>2]=0,f[a+4>>2]=0,f[i+48>>2]=0,f[i+52>>2]=0;t:{if((0|e)<=-1)for(o=e+1|0,h=m(e,36)+8|0,a=0;;){if(g=(a=a+h|0)+-4|0,(p=f[(d=a+4|0)>>2])&&(_[a+8|0]&&CA(p),f[d>>2]=0),f[g>>2]=0,f[d>>2]=0,f[a>>2]=0,n[a+8|0]=1,!o)break t;h=h+36|0,o=o+1|0,a=f[i+140>>2]}if(e)for(PA(i+128|0,e),d=i+48|3,o=20,p=e;g=_[d+4|0]|_[d+5|0]<<8|_[d+6|0]<<16|_[d+7|0]<<24,a=f[i+140>>2]+o|0,h=_[0|d]|_[d+1|0]<<8|_[d+2|0]<<16|_[d+3|0]<<24,n[0|a]=h,n[a+1|0]=h>>>8,n[a+2|0]=h>>>16,n[a+3|0]=h>>>24,n[a+4|0]=g,n[a+5|0]=g>>>8,n[a+6|0]=g>>>16,n[a+7|0]=g>>>24,n[a+-4|0]=1,f[(g=D=a+-16|0)>>2]=0,f[g+4>>2]=0,h=_[(g=d+8|0)+4|0]|_[g+5|0]<<8|_[g+6|0]<<16|_[g+7|0]<<24,a=a+8|0,g=_[0|g]|_[g+1|0]<<8|_[g+2|0]<<16|_[g+3|0]<<24,n[0|a]=g,n[a+1|0]=g>>>8,n[a+2|0]=g>>>16,n[a+3|0]=g>>>24,n[a+4|0]=h,n[a+5|0]=h>>>8,n[a+6|0]=h>>>16,n[a+7|0]=h>>>24,f[D+8>>2]=0,o=o+36|0,p=p+-1|0;);}if(f[i+132>>2]=e,g=f[t+56>>2],(0|(d=f[g+8>>2]))<(0|(o=f[i+156>>2]))){if(f[g+12>>2]<(0|o)){if(o?(B=dA(o<<4),h=f[g+8>>2]):(B=0,h=d),(0|h)>=1)for(a=0;p=f[g+16>>2]+a|0,w=f[p+4>>2],f[(R=D=a+B|0)>>2]=f[p>>2],f[R+4>>2]=w,R=f[(p=p+8|0)+4>>2],f[(D=D+8|0)>>2]=f[p>>2],f[D+4>>2]=R,a=a+16|0,h=h+-1|0;);(a=f[g+16>>2])&&(_[g+20|0]&&CA(a),f[g+16>>2]=0),f[g+16>>2]=B,f[g+12>>2]=o,n[g+20|0]=1}for(a=d<<4,h=o-d|0;D=f[i+52>>2],d=f[g+16>>2]+a|0,f[d>>2]=f[i+48>>2],f[d+4>>2]=D,D=f[(p=i+56|0)+4>>2],f[(d=d+8|0)>>2]=f[p>>2],f[d+4>>2]=D,a=a+16|0,h=h+-1|0;);}if(f[g+8>>2]=o,(0|o)>=1)for(a=0;d=f[i+164>>2]+a|0,p=f[d+4>>2],g=f[f[t+56>>2]+16>>2]+a|0,f[(h=g)>>2]=f[d>>2],f[h+4>>2]=p,h=f[(d=d+8|0)+4>>2],f[(g=g+8|0)>>2]=f[d>>2],f[g+4>>2]=h,a=a+16|0,o=o+-1|0;);if((0|e)>=1)for(D=0;;){for(B=0,p=Q=f[i+184>>2]+m(f[f[i+204>>2]+(D<<2)>>2],12)|0;;){if(w=(R=(Dt=m(D,36))+f[i+140>>2]|0)+4|0,W=f[8+(m(f[p+4>>2],12)+p|0)>>2],(0|(h=f[R+4>>2]))==f[R+8>>2]&&!((0|h)>=(0|(Y=h?h<<1:1)))){Y?(d=dA(Y<<2),h=f[w>>2]):d=0,Nt=R+8|0,St=R+12|0,g=f[R+12>>2];t:{if((0|h)>=1)for(a=d,o=g;f[a>>2]=f[o>>2],a=a+4|0,o=o+4|0,h=h+-1|0;);else if(!g)break t;_[R+16|0]&&CA(g),f[St>>2]=0,h=f[w>>2]}f[St>>2]=d,f[Nt>>2]=Y,n[R+16|0]=1}if(f[f[R+12>>2]+(h<<2)>>2]=W,f[w>>2]=f[w>>2]+1,(0|B)<=1&&(o=f[i+164>>2],F=C[(a=o+(W<<4)|0)+4>>2],o=o+(f[p+8>>2]<<4)|0,V=C[o+4>>2],G=C[a>>2],z=C[o>>2],pt=C[a+8>>2],Ft=C[o+8>>2],f[(a=(i+48|0)+(B<<4)|0)+12>>2]=0,G=v(z-G),V=v(V-F),z=v(Ft-pt),F=v(v(1)/v(E(v(v(v(G*G)+v(V*V))+v(z*z))))),C[a+8>>2]=z*F,C[a+4>>2]=V*F,C[a>>2]=G*F,B=B+1|0),a=m(f[p+4>>2],12)+p|0,(0|Q)==(0|(p=m(f[a>>2],12)+a|0)))break}if(2!=(0|B)?(f[(a=(D<<4)+r|0)>>2]=0,f[a+4>>2]=0,f[(a=a+8|0)>>2]=0,f[a+4>>2]=0,o=f[i+140>>2]):(f[(a=(D<<4)+r|0)+12>>2]=0,G=C[i+68>>2],V=C[i+48>>2],z=C[i+52>>2],pt=C[i+64>>2],Lt=F=v(v(G*V)-v(z*pt)),wt=v(F*F),F=z,z=C[i+72>>2],Ft=C[i+56>>2],F=v(v(F*z)-v(Ft*G)),G=v(v(Ft*pt)-v(z*V)),V=v(v(1)/v(E(v(wt+v(v(F*F)+v(G*G)))))),C[a+8>>2]=Lt*V,C[a+4>>2]=G*V,F=v(F*V),C[a>>2]=F,o=f[i+140>>2],C[(d=Dt+o|0)+20>>2]=F,f[d+24>>2]=f[a+4>>2],f[d+28>>2]=f[a+8>>2],f[d+32>>2]=1900671690),(0|(g=f[(o=o+Dt|0)+4>>2]))<1)F=v(1.0000000150474662e30);else for(a=f[o+12>>2],G=C[(d=(D<<4)+r|0)+8>>2],V=C[d+4>>2],z=C[d>>2],p=f[f[t+56>>2]+16>>2],F=v(1.0000000150474662e30),h=0;d=p+(f[a>>2]<<4)|0,F=F>(pt=v(v(v(C[d>>2]*z)+v(C[d+4>>2]*V))+v(C[d+8>>2]*G)))?pt:F,a=a+4|0,(0|(h=h+1|0))<(0|g););if(C[o+32>>2]=-F,(0|e)==(0|(D=D+1|0)))break}t:if(f[i+132>>2]>=1){for(R=0,w=0,Dt=0,h=0;;){if((0|h)==(0|R))if((0|R)>=(0|(h=R?R<<1:1)))h=R;else{p=h?dA(h<<2):0;e:{if(R)for(a=p,o=R;f[a>>2]=f[w>>2],a=a+4|0,w=w+4|0,o=o+-1|0;);else if(!w){h=1;break e}CA(Dt)}Dt=p,w=p}if(f[(R<<2)+w>>2]=R,!((0|(R=R+1|0))>2]))break}for(St=i+68|0,Nt=i+40|0;;){e=f[((d=R+-1|0)<<2)+w>>2],D=dA(4),f[D>>2]=e;e:{if((0|d)<1)Y=1,e=D,R=d;else{for(e=(o=f[i+140>>2])+m(e,36)|0,F=C[e+20>>2],G=C[e+28>>2],V=C[e+24>>2],p=R+-2|0,a=1,R=d,d=D,Y=1;;){h=f[(p<<2)+w>>2],e=m(h,36)+o|0;i:if(v(v(v(F*C[e+20>>2])+v(V*C[e+24>>2]))+v(G*C[e+28>>2]))>v(.9990000128746033)){if((0|a)!=(0|Y)||(0|a)>=(0|(g=a?a<<1:1)))g=a,e=d;else{e=g?dA(g<<2):0;A:{if((0|a)>=1)for(o=e;f[o>>2]=f[D>>2],o=o+4|0,D=D+4|0,a=a+-1|0;);else if(!D)break A;CA(d)}D=e}if(f[(Y<<2)+D>>2]=h,Y=Y+1|0,!((0|R)<1)){for(o=0,a=w;;){if(f[a>>2]!=(0|h)){if(a=a+4|0,(0|R)!=(0|(o=o+1|0)))continue;break i}break}(0|R)<=(0|o)||(d=a,a=((R=R+-1|0)<<2)+w|0,f[d>>2]=f[a>>2],f[a>>2]=h)}}else g=a,e=d;if(!((0|p)>=1))break;p=p+-1|0,o=f[i+140>>2],d=e,a=g}i:if(!((0|Y)<=1)){for(h=0,f[i+116>>2]=0,n[i+120|0]=1,f[i+108>>2]=0,f[i+112>>2]=0,f[Nt>>2]=0,f[Nt+4>>2]=0,f[i+32>>2]=0,f[i+36>>2]=0,F=v(0),g=0,G=v(0),V=v(0),W=0;;){if(a=f[i+140>>2]+m(f[(W<<2)+D>>2],36)|0,z=C[a+24>>2],pt=C[a+28>>2],C[i+32>>2]=C[a+20>>2]+V,C[i+40>>2]=pt+F,C[i+36>>2]=z+G,(0|(B=f[a+4>>2]))>=1)for(xt=a+4|0,Qt=a+12|0,d=0;;){Tt=f[f[Qt>>2]+(d<<2)>>2],a=f[f[t+56>>2]+16>>2]+(Tt<<4)|0,Et=f[(Q=a+8|0)+4>>2],f[(o=p=i+16|0)>>2]=f[Q>>2],f[o+4>>2]=Et,o=f[a+4>>2],f[i+8>>2]=f[a>>2],f[i+12>>2]=o;A:{if((0|g)>=1){for(a=f[i+116>>2]+20|0,o=0;;){if((0|Tt)==f[a>>2])break A;if(a=a+24|0,!((0|(o=o+1|0))<(0|h)))break}g=h}if(o=f[p+4>>2],f[(a=Et=i+56|0)>>2]=f[p>>2],f[a+4>>2]=o,a=f[i+12>>2],f[i+48>>2]=f[i+8>>2],f[i+52>>2]=a,(0|g)==f[i+112>>2])if((0|g)>=(0|(Q=g?g<<1:1)))h=g;else{Q?(p=dA(m(Q,24)),g=h=f[i+108>>2]):p=0,B=f[i+116>>2];r:{if((0|g)>=1)for(a=p,o=B;It=f[o+4>>2],f[a>>2]=f[o>>2],f[a+4>>2]=It,Gt=f[(Ot=o+16|0)+4>>2],f[(It=a+16|0)>>2]=f[Ot>>2],f[It+4>>2]=Gt,Gt=f[(Ot=o+8|0)+4>>2],f[(It=a+8|0)>>2]=f[Ot>>2],f[It+4>>2]=Gt,a=a+24|0,o=o+24|0,g=g+-1|0;);else if(!B)break r;_[i+120|0]&&(CA(B),h=f[i+108>>2]),f[i+116>>2]=0}f[i+116>>2]=p,n[i+120|0]=1,f[i+112>>2]=Q}else h=g;o=f[i+52>>2],a=f[i+116>>2]+m(h,24)|0,f[a>>2]=f[i+48>>2],f[a+4>>2]=o,f[a+20>>2]=Tt,f[a+16>>2]=f[i- -64>>2],o=f[Et+4>>2],f[(a=a+8|0)>>2]=f[Et>>2],f[a+4>>2]=o,h=f[i+108>>2]+1|0,f[i+108>>2]=h,B=f[xt>>2]}if(g=h,!((0|(d=d+1|0))<(0|B)))break}if(F=C[i+40>>2],G=C[i+36>>2],V=C[i+32>>2],(0|(W=W+1|0))==(0|Y))break}if(f[i+52>>2]=0,f[i+56>>2]=0,a=f[i+140>>2]+m(f[D>>2],36)|0,f[i+68>>2]=f[a+20>>2],f[i+72>>2]=f[a+24>>2],f[i+76>>2]=f[a+28>>2],f[i+60>>2]=0,n[i+64|0]=1,f[i+80>>2]=f[a+32>>2],z=F,F=v(v(1)/v(E(v(v(v(V*V)+v(G*G))+v(F*F))))),C[i+40>>2]=z*F,C[i+36>>2]=G*F,C[i+32>>2]=V*F,f[i+20>>2]=0,n[i+24|0]=1,f[i+12>>2]=0,f[i+16>>2]=0,KA(i+104|0,i+8|0,i+32|0),f[i+12>>2]<=0)p=f[i+108>>2];else for(d=0,h=f[i+52>>2];;){if(Q=20+((W=m(d,24))+f[i+20>>2]|0)|0,f[i+56>>2]==(0|h)&&!((0|h)>=(0|(B=h?h<<1:1)))){B?(g=dA(B<<2),h=f[i+52>>2]):g=0,p=f[i+60>>2];A:{if((0|h)>=1)for(a=g,o=p;f[a>>2]=f[o>>2],a=a+4|0,o=o+4|0,h=h+-1|0;);else if(!p)break A;_[i+64|0]&&CA(p),f[i+60>>2]=0,h=f[i+52>>2]}f[i+60>>2]=g,n[i+64|0]=1,f[i+56>>2]=B}f[f[i+60>>2]+(h<<2)>>2]=f[Q>>2],h=f[i+52>>2]+1|0,f[i+52>>2]=h;A:if(!((0|(p=f[i+108>>2]))<1)){for(a=f[i+116>>2]+20|0,g=f[20+(W+f[i+20>>2]|0)>>2],o=0;;){if(f[a>>2]!=(0|g)){if(a=a+24|0,(0|(o=o+1|0))<(0|p))continue;break A}break}f[a>>2]=-1}if(!((0|(d=d+1|0))>2]))break}if(!((0|p)<1||(B=f[i+132>>2],(0|B)<1)))for(W=f[i+140>>2],Tt=f[i+116>>2],g=0;;){A:if(Q=f[20+(Tt+m(g,24)|0)>>2],-1!=(0|Q)){r:{if((0|Y)<=0){for(d=0;;){if(a=W+m(d,36)|0,(0|(h=f[a+4>>2]))>0)for(a=f[a+12>>2],o=0;;){if((0|Q)==f[a>>2])break r;if(a=a+4|0,!((0|(o=o+1|0))<(0|h)))break}if((0|(d=d+1|0))==(0|B))break}break A}for(h=0;;){a=D,o=Y;n:{for(;;){if(f[a>>2]==(0|h))break n;if(a=a+4|0,!(o=o+-1|0))break}if(a=W+m(h,36)|0,!((0|(d=f[a+4>>2]))<1))for(a=f[a+12>>2],o=0;;){if((0|Q)==f[a>>2])break r;if(a=a+4|0,!((0|(o=o+1|0))<(0|d)))break}}if((0|(h=h+1|0))==(0|B))break}break A}if((a=f[i+20>>2])&&(_[i+24|0]&&CA(a),f[i+20>>2]=0),(a=f[i+60>>2])&&(_[i+64|0]&&CA(a),f[i+60>>2]=0),!(a=f[i+116>>2]))break i;_[i+120|0]&&CA(a),f[i+116>>2]=0;break i}if(!((0|(g=g+1|0))<(0|p)))break}if(LA(f[t+56>>2]+24|0,i+48|0),(a=f[i+20>>2])&&(_[i+24|0]&&CA(a),f[i+20>>2]=0),(a=f[i+60>>2])&&(_[i+64|0]&&CA(a),f[i+60>>2]=0),!(a=f[i+116>>2]))break e;_[i+120|0]&&CA(a),f[i+116>>2]=0;break e}if((0|Y)<1)break e}for(d=0;;){if(a=f[(d<<2)+D>>2],f[i+52>>2]=0,f[i+56>>2]=0,f[i+60>>2]=0,W=f[i+140>>2]+m(a,36)|0,h=f[W+4>>2],n[i+64|0]=1,(0|h)>=1){g=dA(Q=h<<2),B=f[i+60>>2];i:{if((0|(p=f[i+52>>2]))>=1)for(a=g,o=B;f[a>>2]=f[o>>2],a=a+4|0,o=o+4|0,p=p+-1|0;);else if(!B)break i;_[i+64|0]&&CA(B)}for(f[i+60>>2]=g,n[i+64|0]=1,f[i+56>>2]=h,X(g,0,Q),f[i+52>>2]=h,a=f[W+12>>2],o=f[i+60>>2];f[o>>2]=f[a>>2],o=o+4|0,a=a+4|0,h=h+-1|0;);}else f[i+52>>2]=h;if(a=f[W+24>>2],f[St>>2]=f[W+20>>2],f[St+4>>2]=a,g=f[(o=W+28|0)+4>>2],f[(a=St+8|0)>>2]=f[o>>2],f[a+4>>2]=g,LA(f[t+56>>2]+24|0,i+48|0),(a=f[i+60>>2])&&(_[i+64|0]&&CA(a),f[i+60>>2]=0),(0|Y)==(0|(d=d+1|0)))break}}if(D&&CA(e),!R)break}if(VA(f[t+56>>2]),!w)break t;CA(Dt)}else VA(f[t+56>>2]);if((0|(p=f[i+132>>2]))>=1)for(o=8;a=(t=f[i+140>>2]+o|0)+-4|0,(d=f[(e=t+4|0)>>2])&&(_[t+8|0]&&CA(d),f[e>>2]=0),f[a>>2]=0,f[e>>2]=0,f[t>>2]=0,n[t+8|0]=1,o=o+36|0,p=p+-1|0;);return(t=f[i+140>>2])&&(_[i+144|0]&&CA(t),f[i+140>>2]=0),r&&CA(Vt),(t=f[i+204>>2])&&(_[i+208|0]&&CA(t),f[i+204>>2]=0),f[i+204>>2]=0,n[i+208|0]=1,f[i+196>>2]=0,f[i+200>>2]=0,(t=f[i+184>>2])&&(_[i+188|0]&&CA(t),f[i+184>>2]=0),f[i+184>>2]=0,n[i+188|0]=1,f[i+176>>2]=0,f[i+180>>2]=0,(t=f[i+164>>2])&&(_[i+168|0]&&CA(t),f[i+164>>2]=0),(t=f[i+228>>2])&&(_[i+232|0]&&CA(t),f[i+228>>2]=0),Z=i+240|0,1},kA,qA,function(t,e){t|=0,e|=0;var i,r=v(0);Z=i=Z-96|0,EA(t,e),n[t+92|0]=1,_[1680]||(f[397]=0,f[398]=0,f[396]=1065353216,f[399]=0,f[400]=0,f[402]=0,f[403]=0,f[401]=1065353216,f[404]=0,f[405]=0,f[409]=0,f[410]=0,f[408]=-1082130432,f[406]=1065353216,f[407]=0,f[411]=0,f[412]=0,f[414]=0,f[415]=0,f[413]=-1082130432,f[416]=0,f[417]=0,f[418]=-1082130432,f[419]=0,n[1680]=1),e=X(i,0,96),yt[f[f[t>>2]+76>>2]](t,1584,e,6),r=C[t+48>>2],C[t+76>>2]=C[e>>2]+r,C[t+60>>2]=C[e+48>>2]-r,C[t+80>>2]=r+C[e+20>>2],C[t- -64>>2]=C[e+68>>2]-r,C[t+84>>2]=r+C[e+40>>2],C[t+68>>2]=C[e+88>>2]-r,Z=e+96|0},ce,function(t,e,i,r){qA(t|=0,e|=0,i|=0,r|=0)},function(t){return 8528},ne,function(t){return(t=f[(t|=0)+96>>2]+-2|0)>>>0<=2?f[7624+(t<<2)>>2]:0},function(t,e,i,r){e|=0,i|=0,r|=0;var n=0,a=0;t:{e:{i:{A:{r:if(!((n=f[(t|=0)+96>>2]+-2|0)>>>0>2)){n:switch(n-1|0){case 0:if(e>>>0>2)break r;a:switch(e-1|0){case 0:break i;case 1:break a;default:break A}break e;case 1:break n;default:break A}if(!(e>>>0>5)){n:switch(e-1|0){case 2:e=f[t+104>>2],f[i>>2]=f[t+100>>2],f[i+4>>2]=e,e=i+8|0,n=f[(i=t+108|0)+4>>2],f[e>>2]=f[i>>2],f[e+4>>2]=n;break t;case 3:a=f[(n=t+124|0)+4>>2],f[(e=i+8|0)>>2]=f[n>>2],f[e+4>>2]=a,n=f[(e=t+116|0)+4>>2],f[i>>2]=f[e>>2],f[i+4>>2]=n;break t;case 0:break i;case 1:break e;case 4:break n;default:break A}a=f[(n=t+140|0)+4>>2],f[(e=i+8|0)>>2]=f[n>>2],f[e+4>>2]=a,n=f[(e=t+132|0)+4>>2],f[i>>2]=f[e>>2],f[i+4>>2]=n,n=f[(i=t+156|0)+4>>2],f[(e=r+8|0)>>2]=f[i>>2],f[e+4>>2]=n,e=f[(t=t+148|0)+4>>2],f[r>>2]=f[t>>2],f[r+4>>2]=e}}return}return e=f[t+104>>2],f[i>>2]=f[t+100>>2],f[i+4>>2]=e,e=i+8|0,n=f[(i=t+108|0)+4>>2],f[e>>2]=f[i>>2],f[e+4>>2]=n,n=f[(i=t+124|0)+4>>2],f[(e=r+8|0)>>2]=f[i>>2],f[e+4>>2]=n,e=f[(t=t+116|0)+4>>2],f[r>>2]=f[t>>2],void(f[r+4>>2]=e)}return a=f[(n=t+124|0)+4>>2],f[(e=i+8|0)>>2]=f[n>>2],f[e+4>>2]=a,n=f[(e=t+116|0)+4>>2],f[i>>2]=f[e>>2],f[i+4>>2]=n,n=f[(i=t+140|0)+4>>2],f[(e=r+8|0)>>2]=f[i>>2],f[e+4>>2]=n,e=f[(t=t+132|0)+4>>2],f[r>>2]=f[t>>2],void(f[r+4>>2]=e)}return a=f[(n=t+140|0)+4>>2],f[(e=i+8|0)>>2]=f[n>>2],f[e+4>>2]=a,n=f[(e=t+132|0)+4>>2],f[i>>2]=f[e>>2],f[i+4>>2]=n,n=f[(i=t+108|0)+4>>2],f[(e=r+8|0)>>2]=f[i>>2],f[e+4>>2]=n,e=f[t+104>>2],f[r>>2]=f[t+100>>2],void(f[r+4>>2]=e)}n=f[(i=t+156|0)+4>>2],f[(e=r+8|0)>>2]=f[i>>2],f[e+4>>2]=n,e=f[(t=t+148|0)+4>>2],f[r>>2]=f[t>>2],f[r+4>>2]=e},function(t,e,i){var r,n;i|=0,n=f[(e=(t=((e|=0)<<4)+(t|=0)|0)+108|0)+4>>2],f[(r=i+8|0)>>2]=f[e>>2],f[r+4>>2]=n,e=f[(t=t+100|0)+4>>2],f[i>>2]=f[t>>2],f[i+4>>2]=e},function(t){return 0|(4==(0|(t=f[(t|=0)+96>>2]))?4:(3==(0|t))<<1)},ae,function(t,e,i){return i=v(i),0},oe,sA,ve,function(t,e,i){e|=0,i|=0,f[(t|=0)+24>>2]=i,f[t+16>>2]=e},function(t,e,i){e|=0,i|=0,f[(t|=0)+28>>2]=i,f[t+20>>2]=e},function(t,e,i,r){t|=0,e|=0,i|=0,r=v(r);var n,a=0,o=v(0),h=v(0),d=v(0),g=0,p=v(0),B=v(0),F=0,V=0,G=0,w=v(0),Q=v(0),W=0,Y=0,z=v(0),pt=v(0),Dt=v(0),It=v(0),St=0,Tt=0,Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0),Gt=v(0),Lt=v(0),wt=v(0),xt=v(0),Qt=v(0),Wt=v(0),Yt=0,Pt=0;Z=n=Z-192|0,C[f[t+4>>2]+784>>2]>2],h=v(v(C[e+8>>2]*r)+Q),z=C[i+4>>2],d=v(v(C[e+4>>2]*r)+z),pt=C[i>>2],w=v(v(C[e>>2]*r)+pt),g=f[t+4>>2],Tt=f[g+780>>2],(W=(0|(F=f[g+772>>2]))==(0|(Y=f[f[t+8>>2]+8>>2])))?(o=v(w-C[F+52>>2]),p=v(d-C[F+56>>2]),B=v(h-C[F+60>>2]),Dt=v(v(v(o*C[F+12>>2])+v(p*C[F+28>>2]))+v(B*C[F+44>>2])),It=v(v(v(o*C[F+8>>2])+v(p*C[F+24>>2]))+v(B*C[F+40>>2])),o=v(v(v(o*C[F+4>>2])+v(p*C[F+20>>2]))+v(B*C[F+36>>2])),a=f[f[t+12>>2]+8>>2]):(a=f[f[t+12>>2]+8>>2],o=v(w-C[a+52>>2]),p=v(d-C[a+56>>2]),B=v(h-C[a+60>>2]),Dt=v(v(v(o*C[a+12>>2])+v(p*C[a+28>>2]))+v(B*C[a+44>>2])),It=v(v(v(o*C[a+8>>2])+v(p*C[a+24>>2]))+v(B*C[a+40>>2])),o=v(v(v(o*C[a+4>>2])+v(p*C[a+20>>2]))+v(B*C[a+36>>2])),a=Y),Et=C[a+20>>2],Ot=C[a+36>>2],Nt=C[a+40>>2],Ft=C[a+8>>2],Vt=C[a+24>>2],Gt=C[a+44>>2],Lt=C[a+60>>2],p=C[a+12>>2],B=C[a+52>>2],wt=C[a+28>>2],xt=C[a+56>>2],Qt=C[a+4>>2],f[n+28>>2]=0,f[(a=n+124|0)>>2]=0,f[a+4>>2]=0,f[(a=n+132|0)>>2]=0,f[a+4>>2]=0,f[(a=n+140|0)>>2]=0,f[a+4>>2]=0,f[(a=n+148|0)>>2]=0,f[a+4>>2]=0,f[n+156>>2]=0,V=f[(a=e+8|0)+4>>2],f[(G=n+72|0)>>2]=f[a>>2],f[G+4>>2]=V,Wt=p,p=v(pt-B),B=v(z-xt),Q=v(Q-Lt),C[n+24>>2]=v(v(Wt*p)+v(wt*B))+v(Gt*Q),C[n+20>>2]=v(v(p*Ft)+v(B*Vt))+v(Q*Nt),f[n+12>>2]=0,C[n+8>>2]=Dt,C[n+4>>2]=It,C[n>>2]=o,f[n+84>>2]=0,f[n+88>>2]=0,C[n+80>>2]=r,f[n+92>>2]=0,f[n+96>>2]=0,f[n+116>>2]=0,f[n+120>>2]=0,a=f[e+4>>2],f[n+64>>2]=f[e>>2],f[n+68>>2]=a,C[n+16>>2]=v(v(p*Qt)+v(B*Et))+v(Q*Ot),f[n+60>>2]=0,C[n+56>>2]=h,C[n+52>>2]=d,a=f[(e=i+8|0)+4>>2],f[(V=n+40|0)>>2]=f[e>>2],f[V+4>>2]=a,C[n+48>>2]=w,e=f[i+4>>2],f[n+32>>2]=f[i>>2],f[n+36>>2]=e,i=function(t,e){var i,r=v(0),n=v(0),a=0,o=v(0),_=0,h=v(0),d=v(0),g=v(0);if((0|(i=f[t+780>>2]))<1)e=-1;else for(a=t+8|0,h=C[e+8>>2],d=C[e+4>>2],g=C[e>>2],n=C[t+784>>2],n=v(n*n),t=0,e=-1;r=v(C[a+-4>>2]-g),o=v(r*r),r=v(C[a>>2]-d),o=v(o+v(r*r)),r=v(C[a+4>>2]-h),n=(_=(r=v(o+v(r*r)))>2],e=f[V+8>>2],G=f[t+12>>2],a=f[G+8>>2],C[n+96>>2]=C[e+232>>2]*C[a+232>>2],r=C[e+228>>2],o=C[a+228>>2],C[n+84>>2]=R(v(D(v(r*o),v(-10))),v(10)),C[n+88>>2]=R(v(D(v(v(o*C[e+236>>2])+v(r*C[a+236>>2])),v(-10))),v(10)),C[n+92>>2]=R(v(D(v(v(o*C[e+240>>2])+v(r*C[a+240>>2])),v(-10))),v(10)),g=f[e+204>>2],(128&_[a+204|0]||128&g)&&(C[n+148>>2]=C[e+244>>2]+C[a+244>>2],C[n+144>>2]=v(1)/v(v(v(1)/C[f[V+8>>2]+248>>2])+v(v(1)/C[f[G+8>>2]+248>>2])),f[n+120>>2]=8|f[n+120>>2],g=f[f[V+8>>2]+204>>2]),(2&_[f[G+8>>2]+205|0]||512&g)&&(f[n+120>>2]=16|f[n+120>>2]),r=C[n+72>>2],v(y(r))>v(.7071067690849304)?(d=C[n+68>>2],o=v(v(r*r)+v(d*d)),h=v(v(1)/v(E(o))),w=v(o*h),B=C[n+64>>2],o=v(-v(r*h)),p=v(B*o),r=v(d*h),h=v(-v(B*r)),d=v(0)):(w=C[n+64>>2],h=C[n+68>>2],d=v(v(w*w)+v(h*h)),o=v(v(1)/v(E(d))),p=v(d*o),d=v(-v(h*o)),h=v(r*d),o=v(w*o),w=v(-v(r*o)),r=v(0)),a=t+4|0,C[n+184>>2]=p,C[n+180>>2]=h,C[n+168>>2]=r,C[n+164>>2]=o,C[n+176>>2]=w,C[n+160>>2]=d,W?(e=t+28|0,g=t+24|0,V=t+16|0,G=t+20|0):(e=t+24|0,g=t+28|0,V=t+20|0,G=t+16|0),f[n+112>>2]=f[e>>2],f[n+108>>2]=f[g>>2],f[n+104>>2]=f[G>>2],f[n+100>>2]=f[V>>2],e=f[a>>2],(0|i)>=0?(e=e+m(i,192)|0,r=C[(g=e+136|0)>>2],o=C[(V=e+132|0)>>2],h=C[(G=e+128|0)>>2],Yt=f[(W=e+160|0)>>2],16&_[n+120|0]&&(d=v(v(h*C[e+88>>2])+v(0)),!(v(v(o*o)+v(r*r))>v(d*d)))||(Pt=f[(St=e+120|0)>>2],J(e+4|0,n,192),C[G>>2]=h,f[St>>2]=Pt,C[V>>2]=o,C[g>>2]=r),f[W>>2]=Yt):i=ue(e,n),(g=f[425])&&(e=t+8|0,(8&_[f[f[(t=t+12|0)>>2]+8>>2]+204|0]||8&_[f[f[e>>2]+8>>2]+204|0])&&(G=4+(f[a>>2]+m(i,192)|0)|0,i=(0|F)!=(0|Y),yt[g](G,f[(i?t:e)>>2],f[n+100>>2],f[n+108>>2],f[(i?e:t)>>2],f[n+104>>2],f[n+112>>2]))),Tt||(t=f[423])&&yt[t](a)),Z=n+192|0},function(t,e,i){t|=0,e|=0,i|=0;var r,n,a,o=v(0);Z=r=Z-96|0,n=f[f[t>>2]>>2],a=f[f[t+4>>2]>>2],yt[f[f[e>>2]+24>>2]](e,n,a)&&(f[r+88>>2]=-1,f[r+92>>2]=-1,f[r+72>>2]=0,f[r+80>>2]=n,f[r+84>>2]=n+4,f[r+76>>2]=f[n+192>>2],f[r+64>>2]=-1,f[r+68>>2]=-1,f[r+48>>2]=0,f[r+56>>2]=a,f[r+60>>2]=a+4,f[r+52>>2]=f[a+192>>2],(f[t+8>>2]||(e=0|yt[f[f[e>>2]+8>>2]](e,r+72|0,r+48|0,0,1),f[t+8>>2]=e,e))&&(e=function(t,e,i){return f[t+32>>2]=0,f[t+12>>2]=i,f[t+8>>2]=e,f[t+4>>2]=0,f[t>>2]=7720,t}(r+8|0,r+72|0,r+48|0),t=f[t+8>>2],1!=f[i+8>>2]?(o=v(yt[f[f[t>>2]+12>>2]](t,n,a,i,e)),C[i+12>>2]>o&&(C[i+12>>2]=o)):yt[f[f[t>>2]+8>>2]](t,r+72|0,r+48|0,i,e))),Z=r+96|0},function(t){var e;return f[(t|=0)>>2]=7860,(e=f[t+20>>2])&&(_[t+24|0]&&CA(e),f[t+20>>2]=0),f[t+20>>2]=0,f[t+12>>2]=0,f[t+16>>2]=0,n[t+24|0]=1,0|t},function(t){var e;f[(t|=0)>>2]=7860,(e=f[t+20>>2])&&(_[t+24|0]&&CA(e),f[t+20>>2]=0),f[t+20>>2]=0,f[t+12>>2]=0,f[t+16>>2]=0,n[t+24|0]=1,$(t)},function(t,e,i,r,n){var a,o;return t|=0,e|=0,i|=0,r|=0,n|=0,Z=a=Z-16|0,f[a+12>>2]=r,f[a+8>>2]=t,r=f[f[i+4>>2]+4>>2],o=f[f[e+4>>2]+4>>2],1!=(0|n)?(t=f[5260+((m(o,144)+t|0)+(r<<2)|0)>>2],e=0|yt[f[f[t>>2]+8>>2]](t,a+8|0,e,i)):(t=f[76+((m(o,144)+t|0)+(r<<2)|0)>>2],e=0|yt[f[f[t>>2]+8>>2]](t,a+8|0,e,i)),Z=a+16|0,0|e},function(t,e,i){t|=0,e|=0,i|=0;var r,a=0,o=0,h=0,d=v(0),g=v(0),m=0;Z=r=Z-16|0,f[426]=f[426]+1,o=2976,2&f[t+4>>2]&&(a=f[e+192>>2],d=v(yt[f[f[a>>2]+20>>2]](a,C[744])),C[r+12>>2]=d,a=f[i+192>>2],g=v(yt[f[f[a>>2]+20>>2]](a,C[744])),C[r+8>>2]=g,o=d>2],d=C[i+184>>2],g=C[e+184>>2],a=f[t+72>>2];t:{if(o=f[a+12>>2])f[a+12>>2]=f[o>>2],f[a+8>>2]=f[a+8>>2]+-1;else{if(o=0,4&_[t+4|0])break t;o=dA(804)}if(f[o>>2]=1025,f[o+160>>2]=0,f[(a=o+152|0)>>2]=0,f[a+4>>2]=0,f[(a=o+144|0)>>2]=0,f[a+4>>2]=0,f[(a=o+136|0)>>2]=0,f[a+4>>2]=0,f[(a=o+128|0)>>2]=0,f[a+4>>2]=0,f[o+120>>2]=0,f[o+124>>2]=0,f[o+312>>2]=0,f[o+316>>2]=0,f[(a=o+320|0)>>2]=0,f[a+4>>2]=0,f[(a=o+328|0)>>2]=0,f[a+4>>2]=0,f[(a=o+336|0)>>2]=0,f[a+4>>2]=0,f[(a=o+344|0)>>2]=0,f[a+4>>2]=0,f[o+352>>2]=0,f[o+504>>2]=0,f[o+508>>2]=0,f[(a=o+512|0)>>2]=0,f[a+4>>2]=0,f[(a=o+520|0)>>2]=0,f[a+4>>2]=0,f[(a=o+528|0)>>2]=0,f[a+4>>2]=0,f[(a=o+536|0)>>2]=0,f[a+4>>2]=0,f[o+544>>2]=0,f[o+736>>2]=0,f[(a=o+728|0)>>2]=0,f[a+4>>2]=0,f[(a=o+720|0)>>2]=0,f[a+4>>2]=0,f[(a=o+712|0)>>2]=0,f[a+4>>2]=0,f[(a=o+704|0)>>2]=0,f[a+4>>2]=0,f[o+696>>2]=0,f[o+700>>2]=0,f[o+772>>2]=e,f[o+776>>2]=i,f[o+780>>2]=0,f[o+784>>2]=h,C[o+788>>2]=g>2],f[o+800>>2]=a,f[t+16>>2]==(0|a)&&!((0|a)>=(0|(h=a?a<<1:1)))){if(h&&(m=dA(h<<2),a=f[t+12>>2]),(0|a)>=1)for(e=0,i=a;f[e+m>>2]=f[f[t+20>>2]+e>>2],e=e+4|0,i=i+-1|0;);(e=f[t+20>>2])&&(_[t+24|0]&&(CA(e),a=f[t+12>>2]),f[t+20>>2]=0),f[t+20>>2]=m,f[t+16>>2]=h,n[t+24|0]=1}f[t+12>>2]=a+1,f[f[t+20>>2]+(a<<2)>>2]=o}return Z=r+16|0,0|o},function(t,e){t|=0,e|=0;var i,r,n,a,o,_,h=0,d=0,C=0;if(f[426]=f[426]+-1,yt[f[f[t>>2]+20>>2]](t,e),d=f[(h=t+20|0)>>2],i=f[e+800>>2],a=f[(C=d+(r=i<<2)|0)>>2],o=C,_=d,n=(C=f[(d=t+12|0)>>2]+-1|0)<<2,f[o>>2]=f[_+n>>2],f[f[h>>2]+n>>2]=a,f[d>>2]=C,f[f[f[h>>2]+r>>2]+800>>2]=i,e&&(t=f[t+72>>2],!((h=f[t+16>>2])>>>0>e>>>0|h+m(f[t>>2],f[t+4>>2])>>>0<=e>>>0)))return f[e>>2]=f[t+12>>2],f[t+12>>2]=e,void(f[t+8>>2]=f[t+8>>2]+1);CA(e)},function(t,e){t|=0;var i=0,r=0,n=0;if(Z=t=Z-16|0,(0|(r=f[(e|=0)+780>>2]))>=1)for(i=e+4|0;le(i),i=i+192|0,(0|(n=n+1|0))<(0|(r=f[e+780>>2])););r&&((i=f[424])&&(f[t+12>>2]=e,yt[i](t+12|0))),f[e+780>>2]=0,Z=t+16|0},function(t,e,i){t|=0,i|=0;var r=0;t:{e:if(t=f[(e|=0)+220>>2]+-2|0,!(t>>>0>3)){switch(t-1|0){case 0:case 1:break e}if(!((r=f[i+220>>2]+-2|0)>>>0>3))switch(t=0,r-1|0){case 0:case 1:break e;default:break t}}if(!f[e+280>>2]||yt[f[f[e>>2]+12>>2]](e,i)){if(t=1,!f[i+280>>2])break t;if(yt[f[f[i>>2]+12>>2]](i,e))break t}t=0}return 0|t},function(t,e,i){if(t|=0,i|=0,t=0,!(4&(e=f[(e|=0)+204>>2])||(i=f[i+204>>2],4&i))){if(!(3&e))return 1;t=!(3&i)}return 0|t},function(t,e,i,r){var n;t|=0,e|=0,i|=0,r|=0,Z=n=Z-16|0,f[n+8>>2]=t,f[n+4>>2]=i,f[n>>2]=7968,yt[f[f[e>>2]+48>>2]](e,n,r),Z=n+16|0},function(t){return f[(t|=0)+12>>2]},function(t,e){return e|=0,f[f[(t|=0)+20>>2]+(e<<2)>>2]},function(t){return f[(t|=0)+12>>2]?f[t+20>>2]:0},Ce,Ce,function(t,e){var i;return e|=0,t=f[(t|=0)+68>>2],(i=f[t+12>>2])?(f[t+12>>2]=f[i>>2],f[t+8>>2]=f[t+8>>2]+-1,0|i):0|dA(e)},function(t,e){t|=0;var i=0;if((e|=0)&&(t=f[t+68>>2],!((i=f[t+16>>2])>>>0>e>>>0|m(f[t>>2],f[t+4>>2])+i>>>0<=e>>>0)))return f[e>>2]=f[t+12>>2],f[t+12>>2]=e,void(f[t+8>>2]=f[t+8>>2]+1);CA(e)},sA,ve,function(t,e){var i;return i=e|=0,e=f[(t|=0)+8>>2],yt[f[e+64>>2]](i,e,f[t+4>>2]),0},function(t){var e=0,i=0;return f[(t|=0)>>2]=8056,(e=f[t+12>>2])&&(i=f[t+4>>2],yt[f[f[i>>2]+16>>2]](i,e),f[t+12>>2]=0),(e=f[t+8>>2])&&(yt[f[f[e>>2]>>2]](e),e=f[t+4>>2],yt[f[f[e>>2]+60>>2]](e,f[t+8>>2]),f[t+8>>2]=0),f[t+24>>2]=-1,f[t+28>>2]=-1,f[(e=t+32|0)>>2]=-1,f[e+4>>2]=-1,0|t},function(t){var e=0,i=0;f[(t|=0)>>2]=8056,(e=f[t+12>>2])&&(i=f[t+4>>2],yt[f[f[i>>2]+16>>2]](i,e),f[t+12>>2]=0),(e=f[t+8>>2])&&(yt[f[f[e>>2]>>2]](e),e=f[t+4>>2],yt[f[f[e>>2]+60>>2]](e,f[t+8>>2]),f[t+8>>2]=0),f[t+24>>2]=-1,f[t+28>>2]=-1,f[(e=t+32|0)>>2]=-1,f[e+4>>2]=-1,$(t)},function(t,e,i,r,n){e|=0,i|=0,r|=0,n|=0;var a=0,o=0;if((a=f[(t|=0)+12>>2])&&(o=f[t+4>>2],yt[f[f[o>>2]+16>>2]](o,a),f[t+12>>2]=0),(a=f[t+8>>2])&&(yt[f[f[a>>2]>>2]](a),a=f[t+4>>2],yt[f[f[a>>2]+60>>2]](a,f[t+8>>2]),f[t+8>>2]=0),f[t+24>>2]=-1,f[t+28>>2]=-1,f[(a=t+32|0)>>2]=-1,f[a+4>>2]=-1,f[t+20>>2]=r,f[t+16>>2]=n,r=f[e+4>>2],25==f[r+4>>2])return n=f[i+4>>2],25==f[n+4>>2]?void _e(t,e,i,r,n):void me(t,e,i,r,n,0);n=f[i+4>>2],25==f[n+4>>2]&&me(t,i,e,n,r,1)},Re,function(t,e){e|=0;var i=0,r=0,a=0,o=0,h=0;if(r=f[(t|=0)+12>>2]){if((0|(i=f[e+4>>2]))==f[e+8>>2]&&!((0|i)>=(0|(o=i?i<<1:1)))){if(o&&(h=dA(o<<2),i=f[e+4>>2]),(0|i)>=1)for(r=0,a=i;f[r+h>>2]=f[f[e+12>>2]+r>>2],r=r+4|0,a=a+-1|0;);(a=f[e+12>>2])&&(_[e+16|0]&&(CA(a),i=f[e+4>>2]),f[e+12>>2]=0),f[e+12>>2]=h,n[e+16|0]=1,f[e+8>>2]=o,r=f[t+12>>2]}f[e+4>>2]=i+1,f[f[e+12>>2]+(i<<2)>>2]=r}},ce,function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n,a,o,_=v(0),h=v(0),d=v(0),g=0,m=0,y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),yt=v(0),pt=v(0),Dt=v(0),It=v(0),St=0;n=Z-48|0,_=C[t+60>>2],y=C[e+16>>2],h=C[t- -64>>2],F=C[e+20>>2],d=C[t+68>>2],V=C[e+24>>2],G=C[e+52>>2],w=v(v(v(v(_*y)+v(h*F))+v(d*V))+G),C[n+40>>2]=w,p=C[e+32>>2],Q=C[e+36>>2],W=C[e+40>>2],Y=C[e+56>>2],z=v(v(v(v(_*p)+v(h*Q))+v(d*W))+Y),C[n+36>>2]=z,R=_,_=C[e>>2],D=C[e+4>>2],yt=d,d=C[e+8>>2],B=C[e+48>>2],pt=v(v(v(v(R*_)+v(h*D))+v(yt*d))+B),C[n+44>>2]=pt,f[n+28>>2]=0,h=C[t+76>>2],E=C[t+80>>2],R=C[t+84>>2],Dt=v(G+v(v(v(y*h)+v(F*E))+v(V*R))),C[n+20>>2]=Dt,It=v(Y+v(v(v(p*h)+v(Q*E))+v(W*R))),C[n+24>>2]=It,h=v(B+v(v(v(_*h)+v(D*E))+v(d*R))),C[n+16>>2]=h,R=B,B=C[t+92>>2],yt=D,D=C[t+96>>2],E=C[t+100>>2],d=v(R+v(v(v(_*B)+v(yt*D))+v(d*E))),C[n>>2]=d,m=(g=pt>((e=h>d)?d:h))?n:n+44|0,_=C[t+48>>2],C[i>>2]=C[(e?m:g?n+16|0:m)>>2]-_,f[n+12>>2]=0,p=v(Y+v(v(v(p*B)+v(Q*D))+v(W*E))),C[n+8>>2]=p,t=n+8|0,m=(g=z>C[((e=It>p)?n:n+16|0)+8>>2])?t:n+36|0,a=n+24|0,C[i+8>>2]=C[(e?m:g?a:m)>>2]-_,y=v(G+v(v(v(y*B)+v(F*D))+v(V*E))),C[n+4>>2]=y,St=i,e=4|n,m=(g=w>C[((i=Dt>y)?n:n+16|0)+4>>2])?e:n+40|0,o=n+16|4,C[St+4>>2]=C[(i?m:g?o:m)>>2]-_,St=t,g=(i=z>2])?St:n+36|0,C[r+8>>2]=_+C[(t?g:i?a:g)>>2],i=e,i=(e=w>2])?i:n+40|0,C[r+4>>2]=_+C[(t?i:e?o:i)>>2],i=(e=pt<((t=h>2]=_+C[(t?i:e?n+16|0:i)>>2]},he,function(t){return 8320},function(t,e,i){t|=0,e|=0,i|=0;var r=v(0),n=v(0),a=v(0),o=v(0),_=v(0);r=C[i>>2],n=C[i+4>>2],a=C[i+8>>2],o=v(v(v(r*C[e+76>>2])+v(n*C[e+80>>2]))+v(a*C[e+84>>2])),_=v(v(v(r*C[e+92>>2])+v(n*C[e+96>>2]))+v(a*C[e+100>>2])),r=v(v(v(r*C[e+60>>2])+v(n*C[e- -64>>2]))+v(a*C[e+68>>2])),i=f[(e=(e+60|0)+((r>2],f[t>>2]=f[e>>2],f[t+4>>2]=i,i=f[(e=e+8|0)+4>>2],f[(t=t+8|0)>>2]=f[e>>2],f[t+4>>2]=i},function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n=v(0),a=0,o=0,_=v(0),h=v(0),d=v(0),g=v(0),m=0,y=0;if((0|r)>=1)for(m=t+60|0;n=C[e>>2],_=C[e+4>>2],h=C[e+8>>2],d=v(v(v(n*C[t+76>>2])+v(_*C[t+80>>2]))+v(h*C[t+84>>2])),g=v(v(v(n*C[t+92>>2])+v(_*C[t+96>>2]))+v(h*C[t+100>>2])),n=v(v(v(n*C[t+60>>2])+v(_*C[t+64>>2]))+v(h*C[t+68>>2])),o=f[(a=((n>2],f[i>>2]=f[a>>2],f[i+4>>2]=o,y=f[(a=a+8|0)+4>>2],f[(o=i+8|0)>>2]=f[a>>2],f[o+4>>2]=y,e=e+16|0,i=i+16|0,r=r+-1|0;);},pe,function(t,e,i){t|=0,e|=0,i|=0;var r=v(0),n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0);o=C[t+92>>2],_=C[t+76>>2],h=C[t+80>>2],g=C[t+100>>2],n=C[t+68>>2],m=C[t+84>>2],d=C[t+96>>2],r=C[t- -64>>2],a=C[t+60>>2],f[i+12>>2]=0,_=v(_-a),d=v(d-r),h=v(h-r),a=v(o-a),y=r=v(v(_*d)-v(h*a)),p=v(r*r),r=v(g-n),o=v(m-n),n=v(v(h*r)-v(o*d)),r=v(v(o*a)-v(_*r)),a=v(v(1)/v(E(v(p+v(v(n*n)+v(r*r)))))),o=v(y*a),C[i+8>>2]=o,r=v(r*a),C[i+4>>2]=r,n=v(n*a),C[i>>2]=n,e&&(C[i+8>>2]=-o,C[i+4>>2]=-r,C[i>>2]=-n)},Fe,Fe,function(t,e,i,r){e|=0,i|=0,r|=0,yt[f[f[(t|=0)>>2]+108>>2]](t,e,i),yt[f[f[t>>2]+108>>2]](t,(e+1|0)%3|0,r)},function(t,e,i){var r,n;i|=0,n=f[(e=(t=((e|=0)<<4)+(t|=0)|0)+68|0)+4>>2],f[(r=i+8|0)>>2]=f[e>>2],f[r+4>>2]=n,e=f[(t=t+60|0)+4>>2],f[i>>2]=f[t>>2],f[i+4>>2]=e},We,function(t,e,i,r){e|=0,i|=0,r|=0,yt[f[f[(t|=0)>>2]+124>>2]](t,r,e,i)},function(t,e,i){t|=0,e|=0,i=v(i);var r,n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=0;return Z=r=Z-32|0,p=C[t+60>>2],h=v(C[t+76>>2]-p),a=C[t- -64>>2],_=v(C[t+96>>2]-a),n=v(C[t+80>>2]-a),d=v(C[t+92>>2]-p),m=o=v(v(h*_)-v(n*d)),R=v(o*o),y=n,n=C[t+68>>2],o=v(C[t+100>>2]-n),g=v(C[t+84>>2]-n),_=v(v(y*o)-v(g*_)),h=v(v(g*d)-v(h*o)),d=v(v(1)/v(E(v(R+v(v(_*_)+v(h*h)))))),o=v(m*d),_=v(_*d),h=v(h*d),(a=v(v(v(C[e+8>>2]*o)+v(v(C[e>>2]*_)+v(C[e+4>>2]*h)))-v(v(n*o)+v(v(p*_)+v(a*h)))))>=(p=v(-i))^1|a<=i^1||(yt[f[f[t>>2]+104>>2]](t,0,r+16|0,r),d=C[r+16>>2],a=v(C[r>>2]-d),g=C[r+20>>2],n=v(C[r+4>>2]-g),m=i=v(v(h*a)-v(_*n)),R=v(i*i),i=v(o*n),y=C[r+24>>2],n=v(C[r+8>>2]-y),i=v(i-v(h*n)),a=v(v(_*n)-v(o*a)),n=v(v(1)/v(E(v(R+v(v(i*i)+v(a*a)))))),m=v(m*n),i=v(i*n),a=v(a*n),v(v(v(C[e+8>>2]*m)+v(v(C[e>>2]*i)+v(C[e+4>>2]*a)))-v(v(y*m)+v(v(d*i)+v(g*a))))>2]+104>>2]](t,1,r+16|0,r),d=C[r+16>>2],a=v(C[r>>2]-d),g=C[r+20>>2],n=v(C[r+4>>2]-g),m=i=v(v(h*a)-v(_*n)),R=v(i*i),i=v(o*n),y=C[r+24>>2],n=v(C[r+8>>2]-y),i=v(i-v(h*n)),a=v(v(_*n)-v(o*a)),n=v(v(1)/v(E(v(R+v(v(i*i)+v(a*a)))))),m=v(m*n),i=v(i*n),a=v(a*n),v(v(v(C[e+8>>2]*m)+v(v(C[e>>2]*i)+v(C[e+4>>2]*a)))-v(v(y*m)+v(v(d*i)+v(g*a))))>2]+104>>2]](t,2,r+16|0,r),a=C[r+16>>2],n=v(C[r>>2]-a),d=C[r+20>>2],g=v(C[r+4>>2]-d),m=i=v(v(h*n)-v(_*g)),y=v(i*i),R=v(o*g),i=h,h=C[r+24>>2],g=v(C[r+8>>2]-h),i=v(R-v(i*g)),o=v(v(_*g)-v(o*n)),_=v(v(1)/v(E(v(y+v(v(i*i)+v(o*o)))))),n=v(m*_),i=v(i*_),o=v(o*_),v(v(v(C[e+8>>2]*n)+v(v(C[e>>2]*i)+v(C[e+4>>2]*o)))-v(v(h*n)+v(v(a*i)+v(d*o))))>2],d=C[t+76>>2],g=C[t+80>>2],y=C[t+100>>2],_=C[(e=t+68|0)>>2],p=C[t+84>>2],m=C[t+96>>2],a=C[t- -64>>2],o=C[t+60>>2],f[i+12>>2]=0,d=v(d-o),m=v(m-a),g=v(g-a),o=v(h-o),R=a=v(v(d*m)-v(g*o)),D=v(a*a),a=v(y-_),h=v(p-_),_=v(v(g*a)-v(h*m)),a=v(v(h*o)-v(d*a)),o=v(v(1)/v(E(v(D+v(v(_*_)+v(a*a)))))),C[i+8>>2]=R*o,C[i+4>>2]=a*o,C[i>>2]=_*o,n=f[e+4>>2],f[(i=r+8|0)>>2]=f[e>>2],f[i+4>>2]=n,e=f[t+64>>2],f[r>>2]=f[t+60>>2],f[r+4>>2]=e},ce,function(t,e){return e|=0,t=f[f[(t|=0)+4>>2]>>2],0|yt[f[f[t>>2]+128>>2]](t,e)},sA,ve,function(t,e){var i,r;return e|=0,i=f[(t|=0)+4>>2],r=f[i>>2],yt[f[f[r>>2]+104>>2]](r,e,i+4|0),f[t+4>>2]+4|0},ve,function(t,e){var i,r;return e|=0,i=f[(t|=0)+4>>2],r=f[i>>2],yt[f[f[r>>2]+108>>2]](r,e,i+112|0),f[t+4>>2]+112|0},ve,sA,ve,function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n,a,o=0,h=0,d=0;Z=n=Z-144|0,a=zA(n+32|0),d=f[(h=e+8|0)+4>>2],f[(o=n+100|0)>>2]=f[h>>2],f[o+4>>2]=d,h=f[e+20>>2],f[(o=n+108|0)>>2]=f[e+16>>2],f[o+4>>2]=h,d=f[(h=e+24|0)+4>>2],f[(o=n+116|0)>>2]=f[h>>2],f[o+4>>2]=d,h=f[e+36>>2],f[(o=n+124|0)>>2]=f[e+32>>2],f[o+4>>2]=h,d=f[(h=e+40|0)+4>>2],f[(o=n+132|0)>>2]=f[h>>2],f[o+4>>2]=d,f[n+36>>2]=1,f[n+32>>2]=8128,o=f[e+4>>2],f[n+92>>2]=f[e>>2],f[n+96>>2]=o,f[n+80>>2]=f[t+24>>2],e=f[t+4>>2],(d=_[t+20|0])?(f[e+28>>2]=i,o=e+24|0):(f[e+36>>2]=i,o=e+32|0),f[o>>2]=r,o=f[t+12>>2],h=f[o+8>>2],f[n+20>>2]=f[o+12>>2],f[n+16>>2]=h,f[n+28>>2]=r,f[n+24>>2]=i,f[n+8>>2]=o,i=f[e+16>>2],r=f[i+8>>2],o=f[r+8>>2],f[n+12>>2]=n+32,(0|o)==(0|h)?i=i+8|0:(r=f[i+12>>2],i=i+12|0),f[i>>2]=n+8,me(e,f[t+8>>2],n+8|0,f[t+16>>2],n+32|0,0!=(0|d)),t=f[f[t+4>>2]+16>>2],f[(f[f[t+8>>2]+8>>2]==f[n+16>>2]?8:12)+t>>2]=r,Ae(a),Z=n+144|0},sA,ve,function(t,e,i,r){return t|=0,t=f[(e|=0)>>2],vA(t=0|yt[f[f[t>>2]+56>>2]](t,40),e),f[t>>2]=8056,f[t+8>>2]=0,f[t+12>>2]=0,0|t},Ze,function(t){var e;f[(t|=0)>>2]=8964,(e=f[t+296>>2])&&(_[t+300|0]&&CA(e),f[t+296>>2]=0),f[t+296>>2]=0,f[t+288>>2]=0,f[t+292>>2]=0,n[t+300|0]=1,CA(t)},function(t,e){e|=0,f[(t|=0)+200>>2]=e,f[t+192>>2]=e,f[t+304>>2]=f[t+304>>2]+1},function(t,e){e|=0;var i,r=0;r=i=f[(t|=0)+288>>2];t:if(!((0|i)<1)){for(t=f[t+296>>2],r=0;;){if(f[t>>2]==(0|e))break t;if(t=t+4|0,(0|(r=r+1|0))==(0|i))break}r=i}return(0|r)>=(0|i)|0},function(t){return 264},Ne,function(t,e){var i,r,n=0,a=0,o=0,_=0;a=e|=0,o=0|yt[f[f[(t|=0)>>2]+16>>2]](t),_=1,n=f[f[e>>2]+16>>2],r=0|yt[n](0|a,0|o,0|_),_=e,o=r,a=0|yt[f[f[t>>2]+20>>2]](t,f[r+8>>2],e),i=t,n=f[f[e>>2]+20>>2],yt[n](0|_,0|o,0|a,1245859651,0|i)},ce,Je,xe,function(t,e,i){t|=0,e=v(e),i|=0;var r=v(0),n=v(0),a=v(0),o=v(0),_=v(0),h=v(0);r=C[t+40>>2],n=C[t+36>>2],a=C[t+32>>2],o=v(yt[f[f[t>>2]+48>>2]](t)),_=v(yt[f[f[t>>2]+48>>2]](t)),h=v(yt[f[f[t>>2]+48>>2]](t)),f[i+12>>2]=0,e=v(e/v(12)),a=v(a+o),a=v(a+a),a=v(a*a),n=v(n+_),n=v(n+n),n=v(n*n),C[i+8>>2]=e*v(a+n),r=v(r+h),r=v(r+r),r=v(r*r),C[i+4>>2]=e*v(a+r),C[i>>2]=e*v(n+r)},function(t){return 9212},Ie,function(t,e,i){t|=0,e|=0,i|=0;var r=v(0),n=v(0),a=v(0),o=v(0),_=v(0),h=v(0);r=C[e+36>>2],n=C[e+40>>2],a=C[e+32>>2],o=v(yt[f[f[e>>2]+48>>2]](e)),_=v(yt[f[f[e>>2]+48>>2]](e)),h=v(yt[f[f[e>>2]+48>>2]](e)),f[t+12>>2]=0,n=v(n+h),C[t+8>>2]=C[i+8>>2]>=v(0)?n:v(-n),r=v(r+_),C[t+4>>2]=C[i+4>>2]>=v(0)?r:v(-r),r=v(a+o),C[t>>2]=C[i>>2]>=v(0)?r:v(-r)},function(t,e,i){t|=0,e|=0,i|=0;var r=v(0);f[t+12>>2]=0,r=C[e+32>>2],C[t>>2]=C[i>>2]>=v(0)?r:v(-r),r=C[e+40>>2],C[t+8>>2]=C[i+8>>2]>=v(0)?r:v(-r),r=C[e+36>>2],C[t+4>>2]=C[i+4>>2]>=v(0)?r:v(-r)},function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n=0,a=0,o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0);if((0|r)>=1)for(;d=C[(n=e+a|0)+4>>2],g=C[n+8>>2],m=C[n>>2],o=C[t+36>>2],_=C[t+40>>2],h=C[t+32>>2],f[(n=i+a|0)+12>>2]=0,C[n>>2]=m>=v(0)?h:v(-h),C[n+8>>2]=g>=v(0)?_:v(-_),C[n+4>>2]=d>=v(0)?o:v(-o),a=a+16|0,r=r+-1|0;);},Ue,function(t,e,i){t|=0,i|=0,(e|=0)>>>0<=5&&(f[i+12>>2]=0,t=e<<2,f[i+8>>2]=f[t+9264>>2],f[i+4>>2]=f[t+9240>>2],f[i>>2]=f[t+9216>>2])},function(t){return 8},yA,function(t,e,i,r){i|=0,r|=0;var n,a=0,o=0;n=t|=0,(e|=0)>>>0<=11&&(a=f[(e<<=2)+9336>>2],o=f[e+9288>>2]),yt[f[f[t>>2]+108>>2]](n,o,i),yt[f[f[t>>2]+108>>2]](t,a,r)},function(t,e,i){t|=0,e|=0,i|=0;var r=v(0),n=v(0),a=v(0),o=v(0),_=v(0),h=v(0);n=C[t+40>>2],r=C[t+36>>2],a=C[t+32>>2],o=v(yt[f[f[t>>2]+48>>2]](t)),_=v(yt[f[f[t>>2]+48>>2]](t)),h=v(yt[f[f[t>>2]+48>>2]](t)),f[i+12>>2]=0,r=v(r+_),t=e>>>1&1,C[i+4>>2]=v(r*v(1^t))-v(r*v(0|t)),r=v(a+o),t=1&e,C[i>>2]=v(r*v(1^t))-v(r*v(0|t)),n=v(n+h),t=e>>>2&1,C[i+8>>2]=v(n*v(1^t))-v(n*v(0|t))},Ue,function(t,e,i,r){var n,a,o;e|=0,i|=0,r|=0,Z=n=Z-48|0,yt[f[f[(t|=0)>>2]+124>>2]](t,n+32|0,r),f[e+12>>2]=0,r=f[n+40>>2],f[e+8>>2]=r,a=f[n+36>>2],f[e+4>>2]=a,o=e,e=f[n+32>>2],f[o>>2]=e,f[n+12>>2]=0,f[n+8>>2]=-2147483648^r,f[n+4>>2]=-2147483648^a,f[n>>2]=-2147483648^e,yt[f[f[t>>2]+64>>2]](n+16|0,t,n),r=f[(e=n+24|0)+4>>2],f[(t=i+8|0)>>2]=f[e>>2],f[t+4>>2]=r,t=f[n+20>>2],f[i>>2]=f[n+16>>2],f[i+4>>2]=t,Z=n+48|0},function(t,e,i){t|=0,e|=0,i=v(i);var r=v(0),n=v(0),a=0;return r=C[e>>2],n=C[t+32>>2],r<=v(n+i)^1|r>=v(v(-n)-i)^1||(r=C[e+4>>2],n=C[t+36>>2],r<=v(n+i)^1|r>=v(v(-n)-i)^1||(r=C[e+8>>2],n=C[t+40>>2],r<=v(n+i)&&(a=r>=v(v(-n)-i)))),0|a},function(t,e,i){t|=0,e|=0,i|=0;var r=0,n=v(0),a=v(0),o=v(0);if(i>>>0<=5){a=C[t+40>>2],o=C[t+36>>2],n=C[t+32>>2],t=1065353216,r=i;t:{e:{i:{A:switch(i-1|0){case 0:i=0,t=-1082130432,r=0;break t;case 1:i=1065353216;break e;case 2:i=-1082130432;break e;case 3:r=1065353216;break i;case 4:break A;default:break t}r=-1082130432}t=0,n=a,i=0;break t}t=0,n=o,r=0}f[e+8>>2]=r,f[e+4>>2]=i,f[e>>2]=t,C[e+12>>2]=-n}},pA,Je,xe,function(t,e,i){t|=0,e=v(e),i|=0;var r,n,a,o,_=v(0),h=v(0),d=v(0),g=v(0),m=0,y=v(0);Z=r=Z-16|0,a=f[(m=t+40|0)+4>>2],f[(n=r+8|0)>>2]=f[m>>2],f[n+4>>2]=a,m=f[t+36>>2],f[r>>2]=f[t+32>>2],f[r+4>>2]=m,_=v(yt[f[f[t>>2]+48>>2]](t)),g=v(yt[f[f[t>>2]+48>>2]](t)),o=n,y=v(v(yt[f[f[t>>2]+48>>2]](t))+C[n>>2]),C[o>>2]=y,C[r>>2]=_+C[r>>2],C[r+4>>2]=g+C[r+4>>2],_=v(e*v(.5)),g=v(e*v(.25)),e=v(e/v(12));t:{e:if(t=f[t+56>>2],!(t>>>0>2)){switch(t-1|0){default:d=_,_=C[r+4>>2],h=v(_*_),_=v(d*h),d=e,e=C[r>>2],d=h=v(v(g*h)+v(d*v(e*v(e*v(4)))));break t;case 0:break e;case 1:}h=_,_=C[r>>2],_=v(_*_),d=v(h*_),h=e,e=C[r+8>>2],h=_=v(v(g*_)+v(h*v(e*v(e*v(4)))));break t}h=_,_=C[r>>2],_=v(_*_),h=v(h*_),d=e,e=C[r+4>>2],d=_=v(v(g*_)+v(d*v(e*v(e*v(4)))))}f[i+12>>2]=0,C[i+8>>2]=d,C[i+4>>2]=h,C[i>>2]=_,Z=r+16|0},function(t){return 9792},FA,Ie,wA,function(t,e,i){return QA(t|=0,e|=0,i|=0),f[e+28>>2]=f[t+32>>2],f[e+32>>2]=f[t+36>>2],f[e+36>>2]=f[t+40>>2],f[e+40>>2]=f[t+44>>2],f[e+12>>2]=f[t+16>>2],f[e+16>>2]=f[t+20>>2],f[e+20>>2]=f[t+24>>2],f[e+24>>2]=f[t+28>>2],f[e+48>>2]=0,f[e+44>>2]=f[t+48>>2],t=f[t+56>>2],f[e+56>>2]=0,f[e+52>>2]=t,9802},function(t,e,i){t|=0,e|=0,i|=0;var r,n,a,o=v(0),_=v(0),h=v(0),d=0,g=v(0),m=v(0);Z=r=Z-16|0,yt[f[f[e>>2]+68>>2]](r,e,i),a=f[(n=r+8|0)+4>>2],f[(d=t+8|0)>>2]=f[n>>2],f[d+4>>2]=a,d=f[r+4>>2],f[t>>2]=f[r>>2],f[t+4>>2]=d,v(yt[f[f[e>>2]+48>>2]](e))!=v(0)&&(_=C[i+4>>2],o=C[i>>2],h=C[i+8>>2],g=v(yt[f[f[e>>2]+48>>2]](e)),m=o=(e=v(v(v(o*o)+v(_*_))+v(h*h))>2]=C[t>>2]+v(g*v(m*o)),C[t+4>>2]=C[t+4>>2]+v(g*v(_*o)),C[t+8>>2]=C[t+8>>2]+v(g*v(h*o))),Z=r+16|0},function(t,e,i){t|=0,e|=0,i|=0;var r=v(0),n=v(0),a=v(0),o=v(0),f=v(0),_=v(0);r=C[e+36>>2],n=C[e+32>>2],a=C[i>>2],o=C[i+8>>2],(f=v(E(v(v(a*a)+v(o*o)))))==v(0)||(n=v(n/f),_=v(o*n),n=v(a*n)),r=C[i+4>>2]>2]=_,C[t+4>>2]=r,C[t>>2]=n},function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n=v(0),a=v(0),o=v(0),f=v(0),_=v(0);if((0|r)>=1)for(;n=C[t+36>>2],a=C[t+32>>2],f=C[e>>2],o=C[e+8>>2],(_=v(E(v(v(f*f)+v(o*o)))))==v(0)?(o=v(0),n=C[e+4>>2]>2]>2]=a,C[i+8>>2]=o,C[i+4>>2]=n,i=i+16|0,e=e+16|0,r=r+-1|0;);},Me,pA,function(t){return 9822},function(t,e,i){t|=0,e|=0,i|=0;var r=v(0),n=v(0),a=v(0),o=v(0),f=v(0),_=v(0);n=C[e+36>>2],r=C[e+32>>2],a=C[i+4>>2],o=C[i+8>>2],(f=v(E(v(v(a*a)+v(o*o)))))==v(0)||(n=v(n/f),_=v(o*n),n=v(a*n)),r=C[i>>2]>2]=_,C[t>>2]=r,C[t+4>>2]=n},function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n=v(0),a=v(0),o=v(0),f=v(0),_=v(0),h=0;if((0|r)>=1)for(;n=C[t+32>>2],a=C[t+36>>2],h=i,f=C[e+4>>2],o=C[e+8>>2],(_=v(E(v(v(f*f)+v(o*o)))))==v(0)?(o=v(0),n=C[e>>2]>2]>2]=n,C[i+8>>2]=o,C[i+4>>2]=a,i=i+16|0,e=e+16|0,r=r+-1|0;);},function(t){t|=0;var e=v(0),i=v(0);return e=C[t+36>>2],v(yt[f[f[t>>2]+48>>2]](t)),i=v(yt[f[f[t>>2]+48>>2]](t)),v(yt[f[f[t>>2]+48>>2]](t)),v(v(e+i))},pA,function(t){return 9832},function(t,e,i){t|=0,e|=0,i|=0;var r=v(0),n=v(0),a=v(0),o=v(0),f=v(0),_=v(0);r=C[e+40>>2],n=C[e+32>>2],e=t,a=C[i>>2],o=C[i+4>>2],(f=v(E(v(v(a*a)+v(o*o)))))==v(0)||(n=v(n/f),_=v(o*n),n=v(a*n)),r=C[i+8>>2]>2]=r,C[t>>2]=n,C[t+4>>2]=_},function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n=v(0),a=v(0),o=v(0),f=v(0),_=v(0);if((0|r)>=1)for(;n=C[t+40>>2],a=C[t+32>>2],f=C[e>>2],o=C[e+4>>2],(_=v(E(v(v(f*f)+v(o*o)))))==v(0)?(o=v(0),n=C[e+8>>2]>2]>2]=a,C[i+8>>2]=n,C[i+4>>2]=o,i=i+16|0,e=e+16|0,r=r+-1|0;);},Me,pA,function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n,a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0);h=v(yt[f[f[t>>2]+48>>2]](t)),d=v(yt[f[f[t>>2]+48>>2]](t)),g=v(yt[f[f[t>>2]+48>>2]](t)),a=C[(t=e+52|0)>>2],o=C[(n=e+56|0)>>2],_=C[e+48>>2],f[i+12>>2]=0,C[i+8>>2]=o-g,C[i+4>>2]=a-d,C[i>>2]=_-h,a=C[t>>2],o=C[n>>2],_=C[e+48>>2],f[r+12>>2]=0,C[r+8>>2]=g+o,C[r+4>>2]=d+a,C[r>>2]=h+_},function(t,e,i){t|=0,e=v(e),i|=0;var r=v(0),n=v(0);r=v(yt[f[f[t>>2]+48>>2]](t)),n=v(yt[f[f[t>>2]+48>>2]](t)),f[i+12>>2]=0,e=v(n*v(r*v(e*v(.4000000059604645)))),C[i+8>>2]=e,C[i+4>>2]=e,C[i>>2]=e},function(t){return 9972},Ge,function(t){return v(v(C[(t|=0)+32>>2]*C[t+16>>2]))},function(t,e,i){t|=0,e|=0,i|=0;var r,n,a,o=v(0),_=v(0),h=v(0),d=0,g=v(0),m=v(0);Z=r=Z-16|0,yt[f[f[e>>2]+68>>2]](r,e,i),d=f[(a=r+8|0)+4>>2],f[(n=t+8|0)>>2]=f[a>>2],f[n+4>>2]=d,d=f[r+4>>2],f[t>>2]=f[r>>2],f[t+4>>2]=d,_=C[i+4>>2],o=C[i>>2],h=C[i+8>>2],g=v(yt[f[f[e>>2]+48>>2]](e)),m=o=(e=v(v(v(o*o)+v(_*_))+v(h*h))>2]=C[t>>2]+v(g*v(m*o)),C[t+4>>2]=C[t+4>>2]+v(g*v(_*o)),C[n>>2]=C[n>>2]+v(g*v(h*o)),Z=r+16|0},function(t,e,i){f[(t|=0)>>2]=0,f[t+4>>2]=0,f[(t=t+8|0)>>2]=0,f[t+4>>2]=0},function(t,e,i,r){(0|(r|=0))>=1&&X(i|=0,0,r<<4)},sA,ve,Oe,ve,Oe,sA,kA,function(t,e){t|=0,e=v(e),C[t+16>>2]=e},function(t){return v(C[(t|=0)+16>>2])},sA,pA,function(t,e,i,r){r|=0,f[(i|=0)+8>>2]=-581039253,f[i+12>>2]=0,f[i>>2]=-581039253,f[i+4>>2]=-581039253,f[r+8>>2]=1566444395,f[r+12>>2]=0,f[r>>2]=1566444395,f[r+4>>2]=1566444395},function(t,e){t|=0;var i=0;i=f[(e|=0)+4>>2],f[t+72>>2]=f[e>>2],f[t+76>>2]=i,i=f[(e=e+8|0)+4>>2],f[(t=t+80|0)>>2]=f[e>>2],f[t+4>>2]=i},ze,he,function(t){return 10516},ye,function(t,e,i){return QA(t|=0,e|=0,i|=0),f[e+12>>2]=f[t+72>>2],f[e+16>>2]=f[t+76>>2],f[e+20>>2]=f[t+80>>2],f[e+24>>2]=f[t+84>>2],f[e+28>>2]=f[t+52>>2],f[e+32>>2]=f[t+56>>2],f[e+36>>2]=f[t+60>>2],f[e+40>>2]=f[t- -64>>2],t=f[t+68>>2],f[e+48>>2]=0,f[e+44>>2]=t,10528},function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n,a,o,_,h=v(0),d=v(0),g=v(0),m=v(0),p=v(0),R=v(0),D=v(0),B=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0);Z=n=Z-48|0,R=C[r>>2],m=C[i>>2],g=v(v(R-m)*v(.5)),p=v(g*g),d=C[r+4>>2],h=C[i+4>>2],g=v(v(d-h)*v(.5)),F=v(p+v(g*g)),p=C[r+8>>2],D=C[i+8>>2],g=v(v(p-D)*v(.5)),g=v(E(v(F+v(g*g)))),p=v(v(p+D)*v(.5)),D=v(v(d+h)*v(.5)),V=v(v(R+m)*v(.5)),R=C[t+60>>2],v(y(R))>v(.7071067690849304)?(m=C[t+56>>2],d=v(v(R*R)+v(m*m)),h=v(v(1)/v(E(d))),G=v(d*h),d=C[t+52>>2],B=v(m*h),w=v(-v(d*B)),h=v(-v(R*h)),Q=v(d*h)):(d=C[t+52>>2],m=C[t+56>>2],G=v(v(d*d)+v(m*m)),h=v(v(1)/v(E(G))),Q=v(G*h),Y=v(-v(m*h)),w=v(R*Y),h=v(d*h),G=v(-v(R*h))),W=C[t+68>>2],f[(t=n+44|0)>>2]=0,f[(i=n+28|0)>>2]=0,r=n+40|0,F=p,p=v(v(v(R*p)+v(v(V*d)+v(D*m)))-W),W=v(F-v(R*p)),B=v(g*B),F=v(W-B),R=v(g*Q),Q=v(F-R),C[r>>2]=Q,a=n+36|0,D=v(D-v(m*p)),h=v(g*h),z=v(D-h),m=v(g*w),w=v(z-m),C[a>>2]=w,o=n+24|0,B=v(B+W),C[o>>2]=B-R,_=n+20|0,h=v(h+D),C[_>>2]=h-m,f[n+12>>2]=0,d=v(V-v(d*p)),p=v(g*Y),D=v(d-p),g=v(g*G),V=v(D-g),C[n+32>>2]=V,d=v(p+d),C[n+16>>2]=d-g,p=v(R+B),C[n+8>>2]=p,h=v(m+h),C[n+4>>2]=h,d=v(g+d),C[n>>2]=d,yt[f[f[e>>2]+8>>2]](e,n,0,0),f[t>>2]=0,C[r>>2]=p,C[a>>2]=h,f[i>>2]=0,C[o>>2]=R+F,C[_>>2]=m+z,C[n+32>>2]=d,C[n+16>>2]=g+D,f[n+12>>2]=0,C[n+8>>2]=Q,C[n+4>>2]=w,C[n>>2]=V,yt[f[f[e>>2]+8>>2]](e,n,0,1),Z=n+48|0},Ke,function(t){var e;f[(t|=0)>>2]=11012,(e=f[t+88>>2])&&(_[t+92|0]&&CA(e),f[t+88>>2]=0),f[t+88>>2]=0,f[t+80>>2]=0,f[t+84>>2]=0,n[t+92|0]=1,CA(t)},function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0);w=C[e+52>>2],g=C[e+24>>2],D=C[e+20>>2],n=C[e+56>>2],m=C[e+40>>2],o=C[t+44>>2],_=C[t+28>>2],h=C[t+36>>2],p=C[e+36>>2],d=C[t+40>>2],a=C[t+24>>2],Q=C[e+48>>2],B=C[e+8>>2],E=C[e>>2],F=C[e+4>>2],V=C[e+16>>2],G=C[e+32>>2],R=C[t+20>>2],f[i+12>>2]=0,W=n,n=v(v(R+h)*v(.5)),a=v(v(a+d)*v(.5)),_=v(v(_+o)*v(.5)),R=v(W+v(v(v(G*n)+v(p*a))+v(m*_))),h=v(h-n),d=v(d-a),o=v(o-_),m=v(v(v(h*v(y(G)))+v(d*v(y(p))))+v(o*v(y(m)))),C[i+8>>2]=R-m,p=v(w+v(v(v(n*V)+v(a*D))+v(_*g))),g=v(v(v(h*v(y(V)))+v(d*v(y(D))))+v(o*v(y(g)))),C[i+4>>2]=p-g,n=v(Q+v(v(v(n*E)+v(a*F))+v(_*B))),a=v(v(v(h*v(y(E)))+v(d*v(y(F))))+v(o*v(y(B)))),C[i>>2]=n-a,f[r+12>>2]=0,C[r+8>>2]=m+R,C[r+4>>2]=g+p,C[r>>2]=a+n},function(t,e){t|=0;var i=0,r=0;r=f[(e|=0)+4>>2],f[(i=t+160|0)>>2]=f[e>>2],f[i+4>>2]=r,r=f[(e=e+8|0)+4>>2],f[(i=t+168|0)>>2]=f[e>>2],f[i+4>>2]=r,yt[f[f[t>>2]+72>>2]](t)},function(t){return(t|=0)+160|0},function(t,e,i){t|=0,e=v(e),i|=0;var r=0,n=v(0),a=v(0),o=0,_=v(0),h=v(0),d=v(0),y=v(0),p=v(0),R=0,D=0;if(yt[f[f[t>>2]+112>>2]](t),f[(r=i+8|0)>>2]=0,f[r+4>>2]=0,f[i>>2]=0,f[i+4>>2]=0,o=f[t+188>>2])if(e=v(e/v(0|o)),r=f[t+196>>2],D=f[t+184>>2],1==f[t+192>>2])for(R=0-r|0,r=m(r,o+-1|0)+D|0;n=C[t+168>>2],_=v(g[r>>3]*+C[t+160>>2]),_=v(_*_),a=v(g[r+8>>3]*+C[t+164>>2]),a=v(a*a),d=v(v(e*v(_+a))+d),C[i+8>>2]=d,n=v(g[r+16>>3]*+n),n=v(n*n),y=v(v(e*v(_+n))+y),C[i+4>>2]=y,p=v(p+v(e*v(a+n))),C[i>>2]=p,r=r+R|0,o=o+-1|0;);else for(R=0-r|0,r=m(r,o+-1|0)+D|0;n=C[r+8>>2],_=C[t+168>>2],a=v(C[r>>2]*C[t+160>>2]),a=v(a*a),h=v(C[r+4>>2]*C[t+164>>2]),h=v(h*h),d=v(v(e*v(a+h))+d),C[i+8>>2]=d,n=v(n*_),n=v(n*n),y=v(v(e*v(a+n))+y),C[i+4>>2]=y,p=v(p+v(e*v(h+n))),C[i>>2]=p,r=r+R|0,o=o+-1|0;);yt[f[f[t>>2]+116>>2]](t)},function(t){return 11292},function(t,e){t|=0,e=v(e),C[t+152>>2]=e,yt[f[f[t>>2]+72>>2]](t)},function(t){return v(C[(t|=0)+152>>2])},function(t,e,i,r){e|=0,i|=0,r|=0;var a,o=0,h=0,d=0;if(Z=a=Z-128|0,yt[f[f[(t|=0)>>2]+112>>2]](t),d=f[(h=i+8|0)+4>>2],f[(o=a+104|0)>>2]=f[h>>2],f[o+4>>2]=d,d=f[(h=r+8|0)+4>>2],f[(o=a+120|0)>>2]=f[h>>2],f[o+4>>2]=d,o=f[i+4>>2],f[a+96>>2]=f[i>>2],f[a+100>>2]=o,i=f[r+4>>2],f[a+112>>2]=f[r>>2],f[a+116>>2]=i,f[a+84>>2]=0,n[a+88|0]=1,f[a+76>>2]=0,f[a+80>>2]=0,_A(t+72|0,a+96|0,a+72|0),i=f[a+76>>2])for(o=f[t+176>>2],f[a+64>>2]=1008981770,r=(i<<2)-4|0;h=f[f[a+84>>2]+r>>2],d=0|yt[f[f[t>>2]+84>>2]](t),yt[f[f[d>>2]+20>>2]](d,h,a),yt[f[f[e>>2]+8>>2]](e,a,o,f[f[a+84>>2]+r>>2]),r=r+-4|0,i=i+-1|0;);yt[f[f[t>>2]+116>>2]](t),(t=f[a+84>>2])&&(_[a+88|0]&&CA(t),f[a+84>>2]=0),Z=a+128|0},function(t){t|=0;var e,i,r,o,d,g=0,y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0);yt[f[f[t>>2]+112>>2]](t),g=t+72|0,f[t+72>>2]?function(t){var e,i=0,r=0,n=v(0),o=v(0),_=v(0),d=0,g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=0,G=v(0),w=v(0),Q=0,W=0,Y=0,z=0,pt=0,Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=0;if(Z=e=Z+-64|0,i=f[t>>2])for(Q=i<<4,W=i+1|0,Y=f[t+16>>2],z=e+16|0,pt=e+48|0;(0|(i=f[(d=Q+Y|0)+-4>>2]))>=0?(d=f[t+72>>2],yt[f[f[d>>2]+16>>2]](d,i,e+32|0),g=C[e+32>>2],n=C[e+36>>2],i=(d=(Y=f[t+16>>2])+Q|0)+-12|0,m=C[t+48>>2],o=C[t+32>>2],_=(_=C[e+40>>2])>2],r=(_=v(v(v((m<_?m:_)-o)*B)+v(.5)))=v(0)?~~_>>>0:0,a[i>>1]=r,i=d+-14|0,p=C[t+44>>2],n=n<(_=C[t+28>>2])?_:n,E=C[t+60>>2],r=(n=v(v(v((p=v(0)?~~n>>>0:0,a[i>>1]=r,i=d+-16|0,y=C[t+40>>2],g=g<(n=C[t+24>>2])?n:g,F=C[t+56>>2],r=(g=v(v(v((y=v(0)?~~g>>>0:0,a[i>>1]=r,g=C[e+48>>2],i=(n=v(v(F*v((y<(g=g=v(0)?~~n>>>0:0,n=C[e+56>>2],y=C[e+52>>2],a[d+-10>>1]=i,i=d+-8|0,r=(_=v(v(E*v((p<(y=y<_?_:y)?p:y)-_))+v(.5)))=v(0)?~~_>>>0:0,a[i>>1]=r,i=d+-6|0,d=(o=v(v(B*v((m<(_=n=v(0)?~~o>>>0:0,a[i>>1]=d):(f[e+56>>2]=-8388609,f[e+48>>2]=-8388609,f[e+52>>2]=-8388609,f[e+36>>2]=2139095039,f[e+40>>2]=2139095039,i=h[d>>1],r=h[d+2>>1],V=h[d+4>>1],f[e+12>>2]=0,B=C[t+64>>2],p=C[t+32>>2],m=v(v(v(V>>>0)/B)+p),C[e+8>>2]=m,E=C[t+60>>2],y=C[t+28>>2],_=v(v(v(r>>>0)/E)+y),C[e+4>>2]=_,F=C[t+56>>2],g=C[t+24>>2],o=v(v(v(i>>>0)/F)+g),C[e>>2]=o,i=h[d+6>>1],r=h[d+8>>1],V=h[d+10>>1],f[e+28>>2]=0,D=v(p+v(v(V>>>0)/B)),C[e+24>>2]=D,w=v(y+v(v(r>>>0)/E)),C[e+20>>2]=w,n=v(g+v(v(i>>>0)/F)),C[e+16>>2]=n,G=o>2]=G,i=_>2],i=f[i+4>>2],r=m>2],f[e+40>>2]=f[r+8>>2],R=n>v(-34028234663852886e22)?n:v(-34028234663852886e22),C[e+48>>2]=R,f[e+36>>2]=i,i=f[d+12>>2],r=w>v(-34028234663852886e22)?z:pt,n=C[r+4>>2],f[e+52>>2]=f[r+4>>2],r=D>v(-34028234663852886e22)?z:pt,m=C[r+8>>2],f[e+56>>2]=f[r+8>>2],(i=(((0|i)>-1?i:-1)-i|0)+W|0)&&(r=h[(i=(i<<4)+Y|0)+2>>1],V=h[i+4>>1],Et=h[i>>1],f[e+12>>2]=0,D=v(v(v(Et>>>0)/F)+g),C[e>>2]=D,Dt=v(v(v(V>>>0)/B)+p),C[e+8>>2]=Dt,It=v(v(v(r>>>0)/E)+y),C[e+4>>2]=It,r=h[i+6>>1],V=h[i+8>>1],i=h[i+10>>1],f[e+28>>2]=0,St=v(p+v(v(i>>>0)/B)),C[e+24>>2]=St,Tt=v(y+v(v(V>>>0)/E)),C[e+20>>2]=Tt,w=v(g+v(v(r>>>0)/F)),C[e+16>>2]=w,_=C[(i=It<_?e:e+32|0)+4>>2],i=f[i+4>>2],o=C[(r=Dt>2],f[e+40>>2]=f[r+8>>2],R=R>2]=R,G=G>D?D:G,C[e+32>>2]=G,f[e+36>>2]=i,n=C[(i=Tt>n?z:pt)+4>>2],f[e+52>>2]=f[i+4>>2],m=C[(i=St>m?z:pt)+8>>2],f[e+56>>2]=f[i+8>>2]),i=d+-6|0,D=C[t+48>>2],r=(m=v(v(B*v((D<(m=m=v(0)?~~m>>>0:0,a[i>>1]=r,i=d+-8|0,m=C[t+44>>2],r=(n=v(v(E*v((m<(n=n=v(0)?~~n>>>0:0,a[i>>1]=r,i=d+-10|0,n=C[t+40>>2],r=(R=v(v(F*v((n<(R=R=v(0)?~~R>>>0:0,a[i>>1]=r,i=d+-12|0,r=(o=v(v(v((D<(o=o=v(0)?~~o>>>0:0,a[i>>1]=r,i=d+-14|0,r=(o=v(v(v((m<(o=_=v(0)?~~o>>>0:0,a[i>>1]=r,i=d+-16|0,d=(o=v(v(v((n<(o=G=v(0)?~~o>>>0:0,a[i>>1]=d),Q=Q+-16|0,1!=(0|(W=W+-1|0)););Z=e- -64|0}(g):function(t){var e,i,r=0,a=0,o=0,h=0,d=0,g=0,y=0;if(Z=e=Z+-64|0,n[e+56|0]=1,f[e+44>>2]=0,f[e+48>>2]=0,f[e+52>>2]=0,r=f[t+72>>2],i=0|yt[f[f[r>>2]+12>>2]](r),f[(r=o=e+32|0)>>2]=0,f[r+4>>2]=0,f[(r=g=e+24|0)>>2]=0,f[r+4>>2]=0,f[(r=a=e+16|0)>>2]=0,f[r+4>>2]=0,f[e+8>>2]=0,f[e+12>>2]=0,(0|i)<=0)f[e+44>>2]=i;else{if(r=dA(m(i,36)),f[r+32>>2]=0,f[e+52>>2]=r,f[e+48>>2]=i,n[e+56|0]=1,h=f[a+4>>2],f[(d=r+8|0)>>2]=f[a>>2],f[d+4>>2]=h,a=f[e+12>>2],f[r>>2]=f[e+8>>2],f[r+4>>2]=a,a=f[e+28>>2],f[r+16>>2]=f[e+24>>2],f[r+20>>2]=a,a=f[o+4>>2],f[(r=r+24|0)>>2]=f[o>>2],f[r+4>>2]=a,1!=(0|i))for(d=i+-1|0,o=36;h=f[e+12>>2],a=f[e+52>>2]+o|0,f[(r=a)>>2]=f[e+8>>2],f[r+4>>2]=h,y=f[(h=e+16|0)+4>>2],f[(r=r+8|0)>>2]=f[h>>2],f[r+4>>2]=y,y=f[(r=g)+4>>2],f[(h=a+16|0)>>2]=f[r>>2],f[h+4>>2]=y,y=f[(r=r+8|0)+4>>2],f[(h=a+24|0)>>2]=f[r>>2],f[h+4>>2]=y,f[a+32>>2]=0,o=o+36|0,d=d+-1|0;);if(f[e+44>>2]=i,!((0|i)<1))for(r=0,o=f[e+52>>2];g=f[t+72>>2],yt[f[f[g>>2]+16>>2]](g,r,o),f[o+32>>2]=r,o=o+36|0,(0|(r=r+1|0))<(0|i););}(function(t,e){var i,r,a=0,o=0,h=0,d=0,g=0,m=0,y=0,p=0;if(Z=i=Z-16|0,function(t,e){var i,r,n=0,a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=0,p=0,R=0;if(f[(i=Z-32|0)+24>>2]=-8388609,f[i+16>>2]=-8388609,f[i+20>>2]=-8388609,f[i+8>>2]=2139095039,f[i>>2]=2139095039,f[i+4>>2]=2139095039,(0|(r=f[e+4>>2]))<1)_=v(34028234663852886e22),h=v(-34028234663852886e22),d=v(-34028234663852886e22),a=v(-34028234663852886e22),g=v(34028234663852886e22),o=v(34028234663852886e22);else for(y=i+16|0,e=f[e+12>>2]+16|0,_=v(34028234663852886e22),h=v(-34028234663852886e22),d=v(-34028234663852886e22),a=v(-34028234663852886e22),g=v(34028234663852886e22),o=v(34028234663852886e22);o=o>(m=C[(n=e+-16|0)>>2])?m:o,C[i>>2]=o,p=g>C[e+-12>>2]?n:i,g=C[p+4>>2],f[i+4>>2]=f[p+4>>2],n=_>C[e+-8>>2]?n:i,_=C[n+8>>2],f[i+8>>2]=f[n+8>>2],a=a<(m=C[e>>2])?m:a,C[i+16>>2]=a,n=d>2]?e:y,d=C[n+4>>2],f[i+20>>2]=f[n+4>>2],n=h>2]?e:y,h=C[n+8>>2],f[i+24>>2]=f[n+8>>2],e=e+36|0,(0|(R=R+1|0))<(0|r););f[t+68>>2]=0,f[t+52>>2]=0,h=v(h+v(1)),C[t+48>>2]=h,d=v(d+v(1)),C[t+44>>2]=d,a=v(a+v(1)),C[t+40>>2]=a,f[t+36>>2]=0,_=v(_-v(1)),C[t+32>>2]=_,g=v(g-v(1)),C[t+28>>2]=g,o=v(o-v(1)),C[t+24>>2]=o,C[t- -64>>2]=v(65535)/v(h-_),C[t+60>>2]=v(65535)/v(d-g),C[t+56>>2]=v(65535)/v(a-o)}(t,e),f[t>>2]=0,(0|(a=f[t+8>>2]))<(0|(r=(h=f[e+4>>2])<<1))){if(f[t+12>>2]<(0|r)){if(h?(p=dA(h<<5),o=f[t+8>>2]):o=a,(0|o)>=1)for(;m=f[t+16>>2]+d|0,y=f[m+4>>2],f[(g=d+p|0)>>2]=f[m>>2],f[g+4>>2]=y,y=f[(m=m+8|0)+4>>2],f[(g=g+8|0)>>2]=f[m>>2],f[g+4>>2]=y,d=d+16|0,o=o+-1|0;);(o=f[t+16>>2])&&(_[t+20|0]&&CA(o),f[t+16>>2]=0),f[t+16>>2]=p,f[t+12>>2]=r,n[t+20|0]=1}for(d=a<<4,o=a-(h<<1)|0;h=f[i+4>>2],a=f[t+16>>2]+d|0,f[a>>2]=f[i>>2],f[a+4>>2]=h,f[a+8>>2]=f[i+8>>2],f[a+12>>2]=0,d=d+16|0,h=(a=o+1|0)>>>0>=o>>>0,o=a,h;);h=f[e+4>>2]}f[t+8>>2]=r,gA(t,e,0,h),Z=i+16|0})(t,e+40|0),(t=f[e+52>>2])&&(_[e+56|0]&&CA(t),f[e+52>>2]=0),Z=e- -64|0}(g),yt[f[f[t>>2]+116>>2]](t),g=f[t+88>>2],e=h[g+8>>1],i=h[g+10>>1],r=h[g>>1],o=h[g+2>>1],d=h[g+4>>1],g=h[g+6>>1],f[t+48>>2]=0,f[t+32>>2]=0,y=C[t+96>>2],p=C[t+128>>2],C[t+36>>2]=y+v(v(g>>>0)/p),R=C[t+136>>2],D=C[t+104>>2],C[t+28>>2]=v(v(d>>>0)/R)+D,B=C[t+132>>2],E=C[t+100>>2],C[t+24>>2]=v(v(o>>>0)/B)+E,C[t+20>>2]=y+v(v(r>>>0)/p),C[t+44>>2]=D+v(v(i>>>0)/R),C[t+40>>2]=E+v(v(e>>>0)/B)},function(t){n[(t|=0)+52|0]=1},function(t){return 25},We,function(t){return(t|=0)+148|0},function(t){return f[(t|=0)+208>>2]},we,We,we,function(t,e,i){(function(t,e,i){var r=v(0),n=0,a=0,o=0;e=f[t+52>>2]+m(f[t+56>>2],e)|0,o=f[t+36>>2],3!=f[t+64>>2]?(n=f[e+8>>2],a=f[e+4>>2],e=f[e>>2]):(n=h[e+4>>1],a=h[e+2>>1],e=h[e>>1]),e=o+m(e,f[t+48>>2])|0,o=i+68|0,1!=f[t+44>>2]?(C[i+60>>2]=C[e>>2]*C[t+12>>2],C[i- -64>>2]=C[e+4>>2]*C[t+16>>2],r=v(C[e+8>>2]*C[t+20>>2])):(C[i+60>>2]=g[e>>3]*+C[t+12>>2],C[i- -64>>2]=g[e+8>>3]*+C[t+16>>2],r=v(g[e+16>>3]*+C[t+20>>2])),C[o>>2]=r,e=f[t+36>>2]+m(f[t+48>>2],a)|0,a=i+84|0,1!=f[t+44>>2]?(C[i+76>>2]=C[e>>2]*C[t+12>>2],C[i+80>>2]=C[e+4>>2]*C[t+16>>2],r=v(C[e+8>>2]*C[t+20>>2])):(C[i+76>>2]=g[e>>3]*+C[t+12>>2],C[i+80>>2]=g[e+8>>3]*+C[t+16>>2],r=v(g[e+16>>3]*+C[t+20>>2])),C[a>>2]=r,e=f[t+36>>2]+m(f[t+48>>2],n)|0,n=i+100|0,1!=f[t+44>>2]?(C[i+92>>2]=C[e>>2]*C[t+12>>2],C[i+96>>2]=C[e+4>>2]*C[t+16>>2],r=v(C[e+8>>2]*C[t+20>>2])):(C[i+92>>2]=g[e>>3]*+C[t+12>>2],C[i+96>>2]=g[e+8>>3]*+C[t+16>>2],r=v(g[e+16>>3]*+C[t+20>>2])),C[n>>2]=r,yt[f[f[i>>2]+44>>2]](i,C[t+4>>2])})((t|=0)+148|0,e|=0,i|=0)},De,function(t){var e=0;t=f[(t|=0)+144>>2],(0|(e=f[t+32>>2]))>=1?f[t+32>>2]=e+1:(e=f[t+8>>2],yt[f[f[e>>2]+16>>2]](e,t+36|0,t+40|0,t+44|0,t+48|0,t+52|0,t+56|0,t+60|0,t- -64|0,f[t+28>>2]),f[t+32>>2]=1)},function(t){var e=0,i=0;t=f[(t|=0)+144>>2],(e=f[t+32>>2])&&(i=t,(0|e)>=2?t=e+-1|0:(e=f[t+8>>2],yt[f[f[e>>2]+24>>2]](e,f[t+28>>2]),f[t+36>>2]=0,t=0),f[i+32>>2]=t)},function(t,e,i,r,n){t|=0,e|=0,i|=0,r|=0,n|=0;var a,o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0);Z=a=Z-32|0,t=0|yt[f[f[t>>2]+84>>2]](t),yt[f[f[t>>2]+16>>2]](t,e,a),Y=C[i+56>>2],B=C[i+36>>2],E=C[i+40>>2],F=C[i+32>>2],R=C[i+48>>2],m=C[i+8>>2],V=C[i>>2],G=C[i+4>>2],h=C[a+16>>2],o=v(v(h+C[a>>2])*v(.5)),d=C[(e=a+20|0)>>2],_=v(v(d+C[a+4>>2])*v(.5)),g=C[(t=a+24|0)>>2],D=v(v(g+C[a+8>>2])*v(.5)),h=v(h-o),p=C[i+16>>2],d=v(d-_),w=C[i+20>>2],g=v(g-D),Q=C[i+24>>2],W=v(v(v(h*v(y(p)))+v(d*v(y(w))))+v(g*v(y(Q)))),p=v(v(v(v(o*p)+v(_*w))+v(D*Q))+C[i+52>>2]),C[e>>2]=W+p,C[a+4>>2]=p-W,R=v(R+v(v(v(o*V)+v(_*G))+v(D*m))),m=v(v(v(h*v(y(V)))+v(d*v(y(G))))+v(g*v(y(m)))),C[a>>2]=R-m,e=f[a+4>>2],f[r>>2]=f[a>>2],f[r+4>>2]=e,f[a+12>>2]=0,o=v(Y+v(v(v(o*F)+v(_*B))+v(D*E))),_=v(v(v(h*v(y(F)))+v(d*v(y(B))))+v(g*v(y(E)))),C[a+8>>2]=o-_,i=f[a+12>>2],f[(e=r+8|0)>>2]=f[a+8>>2],f[e+4>>2]=i,f[a+28>>2]=0,C[t>>2]=_+o,C[a+16>>2]=m+R,e=f[a+20>>2],f[n>>2]=f[a+16>>2],f[n+4>>2]=e,i=f[t+4>>2],f[(e=n+8|0)>>2]=f[t>>2],f[e+4>>2]=i,Z=a+32|0},oe,oe,De,De,ae,function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var a,o=v(0),d=v(0),g=v(0),m=v(0),p=0,R=0,D=0;if(Z=a=Z-112|0,yt[f[f[t>>2]+112>>2]](t),f[a+100>>2]=0,n[a+104|0]=1,f[a+92>>2]=0,f[a+96>>2]=0,f[a+84>>2]=0,o=v(C[r>>2]-C[i>>2]),d=v(C[r+4>>2]-C[i+4>>2]),g=v(C[r+8>>2]-C[i+8>>2]),m=v(v(1)/v(E(v(v(v(o*o)+v(d*d))+v(g*g))))),C[a+80>>2]=g*m,C[a+76>>2]=d*m,C[a+72>>2]=o*m,function(t,e,i,r){var a,o=v(0),d=0,g=0,m=v(0),p=v(0),R=0,D=0,B=v(0),E=v(0),F=v(0),V=0,G=0,w=v(0),Q=0,W=v(0),Y=v(0),Z=0,z=v(0),yt=v(0),pt=v(0);if((0|(a=f[t>>2]))>=1)for(;;){d=(V=Q<<4)+f[t+16>>2]|0,R=h[d+4>>1],B=C[t+64>>2],m=C[t+32>>2],D=h[d+10>>1],g=h[d+2>>1],E=C[t+60>>2],p=C[t+28>>2],G=h[d+8>>1],F=C[t+24>>2],o=C[t+56>>2],w=v(F+v(v(h[d+6>>1])/o));t:{e:{if(o=v(v(v(v(v(h[d>>1])/o)+F)+w)*v(.5)),F=v(C[i>>2]-o),w=v(w-o),v(F*C[e>>2])>=v(0)&&v(y(F))>w||(o=v(v(v(g>>>0)/E)+p),p=v(p+v(v(G>>>0)/E)),o=v(v(o+p)*v(.5)),E=v(C[i+4>>2]-o),p=v(p-o),v(E*C[e+4>>2])>=v(0)&&v(y(E))>p||(o=v(v(v(R>>>0)/B)+m),m=v(m+v(v(D>>>0)/B)),o=v(v(o+m)*v(.5)),B=v(C[i+8>>2]-o),o=v(m-o),m=C[e+8>>2],v(B*m)>=v(0)&&v(y(B))>o||(W=C[e+4>>2],z=v(y(W)),yt=v(y(m)),v(y(v(v(B*W)-v(E*m))))>v(v(p*yt)+v(o*z))||(Y=C[e>>2],pt=v(y(Y)),v(y(v(v(F*m)-v(B*Y))))>v(v(w*yt)+v(o*pt)))))))d=f[d+12>>2]>-1,R=0;else if(R=1^(D=v(y(v(v(E*Y)-v(F*W))))>v(v(w*z)+v(p*pt))),d=(0|(Z=f[d+12>>2]))>-1,!((0|Z)<0|D)){if((0|(g=f[r+4>>2]))==f[r+8>>2]&&!((0|g)>=(0|(G=g?g<<1:1)))){G?(V=dA(G<<2),g=f[r+4>>2]):V=0,D=f[r+12>>2];i:{if((0|g)>=1)for(d=V,R=D;f[d>>2]=f[R>>2],d=d+4|0,R=R+4|0,g=g+-1|0;);else if(!D)break i;_[r+16|0]&&CA(D),f[r+12>>2]=0,g=f[r+4>>2]}f[r+12>>2]=V,n[r+16|0]=1,f[r+8>>2]=G}f[f[r+12>>2]+(g<<2)>>2]=Z,f[r+4>>2]=f[r+4>>2]+1;break e}if(!(d|R)){Q=Q-f[12+(V+f[t+16>>2]|0)>>2]|0;break t}}Q=Q+1|0}if(!((0|Q)<(0|a)))break}}(t+72|0,a+72|0,i,a+88|0),r=f[a+92>>2])for(R=f[t+176>>2],f[a+64>>2]=1008981770,i=(r<<2)-4|0;D=f[f[a+100>>2]+i>>2],p=0|yt[f[f[t>>2]+84>>2]](t),yt[f[f[p>>2]+20>>2]](p,D,a),yt[f[f[e>>2]+8>>2]](e,a,R,f[f[a+100>>2]+i>>2]),i=i+-4|0,r=r+-1|0;);yt[f[f[t>>2]+116>>2]](t),(t=f[a+100>>2])&&(_[a+104|0]&&CA(t),f[a+100>>2]=0),Z=a+112|0},$e,function(t){CA($e(t|=0))},function(t,e){t|=0;var i=0,r=0,a=0;if(i=f[(e|=0)+4>>2],f[t+56>>2]=f[e>>2],f[t+60>>2]=i,a=f[(r=e+8|0)+4>>2],f[(i=t- -64|0)>>2]=f[r>>2],f[i+4>>2]=a,i=f[t+156>>2])for(r=(i<<2)-4|0;a=f[f[t+164>>2]+r>>2],yt[f[f[a>>2]+24>>2]](a,e),r=r+-4|0,i=i+-1|0;);n[t+52|0]=1},Le,function(t,e,i){t|=0,e=v(e);var r,n=0,a=0,o=0;if(Z=r=Z-16|0,f[(i|=0)>>2]=0,f[i+4>>2]=0,f[(n=i+8|0)>>2]=0,f[n+4>>2]=0,n=f[t+156>>2])for(e=v(e/v(0|n)),a=(n<<2)-4|0;o=f[f[t+164>>2]+a>>2],yt[f[f[o>>2]+32>>2]](o,e,r),C[i>>2]=C[r>>2]+C[i>>2],C[i+4>>2]=C[r+4>>2]+C[i+4>>2],C[i+8>>2]=C[r+8>>2]+C[i+8>>2],a=a+-4|0,n=n+-1|0;);Z=r+16|0},function(t){return 11313},function(t,e){t|=0,e=v(e);var i=0,r=0,a=0;if(C[t+16>>2]=e,i=f[t+156>>2])for(r=(i<<2)-4|0;a=f[f[t+164>>2]+r>>2],yt[f[f[a>>2]+44>>2]](a,e),r=r+-4|0,i=i+-1|0;);n[t+52|0]=1},function(t){return 64},function(t,e,i){var r,n,a;return QA(t|=0,e|=0,i|=0),r=f[t+148>>2],yt[f[f[r>>2]+56>>2]](r,e+12|0,i),f[e+56>>2]=f[t+16>>2],f[e+40>>2]=f[t+56>>2],f[e+44>>2]=f[t+60>>2],f[e+48>>2]=f[t- -64>>2],f[e+52>>2]=f[t+68>>2],n=e,a=0|yt[f[f[t>>2]+80>>2]](t),f[n+60>>2]=a,10708},function(t,e,i,r){e|=0,i|=0,r|=0;var n=0,a=0,o=0;if(n=f[(t|=0)+156>>2])for(a=(n<<2)-4|0;o=f[f[t+164>>2]+a>>2],yt[f[f[o>>2]+64>>2]](o,e,i,r),a=a+-4|0,n=n+-1|0;);},function(t){t|=0;var e,i=0,r=0,a=0,o=v(0),h=v(0),d=v(0),g=0,m=0,y=0,p=v(0),R=v(0),D=v(0),B=v(0),E=0;if(f[t+20>>2]=2139095039,f[t+24>>2]=2139095039,f[t+44>>2]=-8388609,f[(e=t+36|0)>>2]=-8388609,f[e+4>>2]=-8388609,f[t+28>>2]=2139095039,a=f[t+156>>2])for(E=t+20|0,m=(a<<2)-4|0,y=f[t+164>>2],p=v(34028234663852886e22),R=v(-34028234663852886e22),D=v(-34028234663852886e22),o=v(-34028234663852886e22),B=v(34028234663852886e22),h=v(34028234663852886e22);a=a+-1|0,i=f[m+y>>2],_[i+52|0]&&(yt[f[f[i>>2]+68>>2]](i),n[i+52|0]=0,R=C[t+44>>2],D=C[t+40>>2],B=C[t+24>>2],y=f[t+164>>2],o=C[t+36>>2],h=C[t+20>>2],p=C[t+28>>2]),i=f[m+y>>2],h=h>(d=C[i+20>>2])?d:h,C[t+20>>2]=h,r=i+20|0,g=B>C[i+24>>2]?r:E,B=C[g+4>>2],f[t+24>>2]=f[g+4>>2],r=p>C[i+28>>2]?r:E,p=C[r+8>>2],f[t+28>>2]=f[r+8>>2],o=o<(d=C[(r=i+36|0)>>2])?d:o,C[t+36>>2]=o,g=D>2]?r:e,D=C[g+4>>2],f[t+40>>2]=f[g+4>>2],i=R>2]?r:e,R=C[i+8>>2],f[t+44>>2]=f[i+8>>2],m=m+-4|0,a;);},function(t){var e=0,i=0,r=0;if(e=f[(t|=0)+156>>2])for(i=(e<<2)-4|0;r=f[f[t+164>>2]+i>>2],yt[f[f[r>>2]+72>>2]](r),i=i+-4|0,e=e+-1|0;);n[t+52|0]=1},pe,we,we,we,we,we,De,De,qe,qe,Ar,oe,oe,De,De,ae,function(t,e,i,r){e|=0,i|=0,r|=0;var n=0,a=0,o=0;if(n=f[(t|=0)+156>>2])for(a=(n<<2)-4|0;o=f[f[t+164>>2]+a>>2],yt[f[f[o>>2]+144>>2]](o,e,i,r),a=a+-4|0,n=n+-1|0;);},Ke,kA,function(t,e){t|=0;var i,r=0;r=f[(e|=0)+4>>2],f[t+56>>2]=f[e>>2],f[t+60>>2]=r,i=f[(e=e+8|0)+4>>2],f[(r=t- -64|0)>>2]=f[e>>2],f[r+4>>2]=i,yt[f[f[t>>2]+72>>2]](t)},function(t,e){t|=0,e=v(e);var i=0,r=0;if(C[t+16>>2]=e,i=0|yt[f[f[t>>2]+88>>2]](t))for(i=i+-1|0;r=0|yt[f[f[t>>2]+124>>2]](t,i),yt[f[f[r>>2]+44>>2]](r,e),-1!=(0|(i=i+-1|0)););n[t+52|0]=1},ae,qe,qe,ae,sA,ve,We,function(t){return f[(t|=0)+60>>2]},function(t,e,i){t|=0,e|=0,i|=0;var r,n=0,a=v(0),o=0,_=0,h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0);Z=r=Z-80|0,f[r+72>>2]=1008981770,yt[f[f[t>>2]+20>>2]](t,e,r+8|0),a=C[r+12>>2],t=r+40|0,e=r+24|0,h=C[r+28>>2],d=C[r+44>>2],_=(o=a>C[((n=h>d)?t:e)+4>>2])?36:4,p=C[(r+8|0)+(n?_:o?20:_)>>2],m=C[r+16>>2],g=C[r+32>>2],y=C[r+48>>2],_=(o=m>C[((n=g>y)?t:e)+8>>2])?40:8,R=C[(r+8|0)+(n?_:o?24:_)>>2],_=(o=a>2])?36:4,D=C[(r+8|0)+(n?_:o?20:_)>>2],n=t,n=(e=m>2])?40:8,m=C[(r+8|0)+(t?n:e?24:n)>>2],t=(h=C[r+24>>2])>(d=C[r+40>>2]),n=(e=(g=C[r+8>>2])>(t?d:h))<<5,y=C[(r+8|0)+(t?n:e?16:n)>>2],a=C[r+72>>2],n=(e=g<((t=h>2]=a+C[(r+8|0)+(t?n:e?16:n)>>2],C[i>>2]=y-a,C[i+24>>2]=a+m,C[i+20>>2]=a+D,C[i+8>>2]=R-a,C[i+4>>2]=p-a,Z=r+80|0},function(t,e,i){t|=0,e|=0,i|=0;var r=v(0),n=0,a=0,o=0;e=f[t+52>>2]+m(f[t+56>>2],e)|0,n=f[t+36>>2],3!=f[t+64>>2]?(a=f[e+8>>2],o=f[e+4>>2],e=f[e>>2]):(a=h[e+4>>1],o=h[e+2>>1],e=h[e>>1]),e=n+m(e,f[t+48>>2])|0,n=i,1!=f[t+44>>2]?(C[i>>2]=C[e>>2]*C[t+12>>2],C[i+4>>2]=C[e+4>>2]*C[t+16>>2],r=v(C[e+8>>2]*C[t+20>>2])):(C[i>>2]=g[e>>3]*+C[t+12>>2],C[i+4>>2]=g[e+8>>3]*+C[t+16>>2],r=v(g[e+16>>3]*+C[t+20>>2])),C[n+8>>2]=r,e=f[t+36>>2]+m(f[t+48>>2],o)|0,n=i+24|0,1!=f[t+44>>2]?(C[i+16>>2]=C[e>>2]*C[t+12>>2],C[i+20>>2]=C[e+4>>2]*C[t+16>>2],r=v(C[e+8>>2]*C[t+20>>2])):(C[i+16>>2]=g[e>>3]*+C[t+12>>2],C[i+20>>2]=g[e+8>>3]*+C[t+16>>2],r=v(g[e+16>>3]*+C[t+20>>2])),C[n>>2]=r,e=f[t+36>>2]+m(f[t+48>>2],a)|0,n=i+40|0,1!=f[t+44>>2]?(C[i+32>>2]=C[e>>2]*C[t+12>>2],C[i+36>>2]=C[e+4>>2]*C[t+16>>2],r=v(C[e+8>>2]*C[t+20>>2])):(C[i+32>>2]=g[e>>3]*+C[t+12>>2],C[i+36>>2]=g[e+8>>3]*+C[t+16>>2],r=v(g[e+16>>3]*+C[t+20>>2])),C[n>>2]=r,f[i+64>>2]=f[t+4>>2]},function(t){var e=0;return f[(t|=0)>>2]=14216,(e=f[t+68>>2])&&(rr(e),CA(f[t+68>>2])),(e=f[t+28>>2])&&(_[t+32|0]&&CA(e),f[t+28>>2]=0),f[t+28>>2]=0,f[t+20>>2]=0,f[t+24>>2]=0,n[t+32|0]=1,0|t},function(t){var e=0;f[(t|=0)>>2]=14216,(e=f[t+68>>2])&&(rr(e),CA(f[t+68>>2])),(e=f[t+28>>2])&&(_[t+32|0]&&CA(e),f[t+28>>2]=0),f[t+28>>2]=0,f[t+20>>2]=0,f[t+24>>2]=0,n[t+32|0]=1,CA(t)},function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n,a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),Z=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0);a=C[t+44>>2],h=C[t+60>>2],n=f[t+20>>2],o=C[t+40>>2],d=C[t+56>>2],_=C[t+36>>2],g=C[t+52>>2],Z=v(yt[f[f[t>>2]+48>>2]](t)),z=v(yt[f[f[t>>2]+48>>2]](t)),pt=v(yt[f[f[t>>2]+48>>2]](t)),Dt=C[e+52>>2],m=C[e+24>>2],E=C[e+20>>2],p=C[e+56>>2],F=C[e+40>>2],V=C[e+36>>2],It=C[e+48>>2],G=C[e+8>>2],w=C[e>>2],Q=C[e+4>>2],W=C[e+16>>2],Y=C[e+32>>2],f[i+12>>2]=0,R=p,p=v(n?v(g+_)*v(.5):0),D=v(n?v(d+o)*v(.5):0),B=v(n?v(h+a)*v(.5):0),R=v(R+v(v(v(Y*p)+v(V*D))+v(F*B))),_=v(Z+v(n?v(g-_)*v(.5):0)),o=v(z+v(n?v(d-o)*v(.5):0)),a=v(pt+v(n?v(h-a)*v(.5):0)),h=v(v(v(_*v(y(Y)))+v(o*v(y(V))))+v(a*v(y(F)))),C[i+8>>2]=R-h,d=v(Dt+v(v(v(p*W)+v(D*E))+v(B*m))),g=v(v(v(_*v(y(W)))+v(o*v(y(E))))+v(a*v(y(m)))),C[i+4>>2]=d-g,m=v(It+v(v(v(p*w)+v(D*Q))+v(B*G))),a=v(v(v(_*v(y(w)))+v(o*v(y(Q))))+v(a*v(y(G)))),C[i>>2]=m-a,f[r+12>>2]=0,C[r+8>>2]=h+R,C[r+4>>2]=g+d,C[r>>2]=a+m},function(t,e){e|=0;var i,r=0,n=0,a=0,o=0,_=0,h=0,d=0,g=0,m=0,y=0,p=0,R=0,D=0,B=0;if(Z=i=Z-144|0,f[(t|=0)+20>>2]>=1)for(R=i+96|0,m=i- -64|0,y=i+48|0,p=i+32|0;r=f[t+28>>2]+g|0,_=f[(d=r+8|0)+4>>2],f[(n=i+24|0)>>2]=f[d>>2],f[n+4>>2]=_,o=f[r+4>>2],f[i+16>>2]=f[r>>2],f[i+20>>2]=o,a=f[(_=r+24|0)+4>>2],f[(o=p+8|0)>>2]=f[_>>2],f[o+4>>2]=a,_=f[(d=r+16|0)+4>>2],f[p>>2]=f[d>>2],f[p+4>>2]=_,h=f[(a=r+40|0)+4>>2],f[(_=d=y+8|0)>>2]=f[a>>2],f[_+4>>2]=h,a=f[(_=r+32|0)+4>>2],f[y>>2]=f[_>>2],f[y+4>>2]=a,B=f[(h=r+56|0)+4>>2],f[(a=_=m+8|0)>>2]=f[h>>2],f[a+4>>2]=B,h=f[(a=r+48|0)+4>>2],f[m>>2]=f[a>>2],f[m+4>>2]=h,a=i+8|0,r=f[r- -64>>2],r=0|yt[f[f[r>>2]+28>>2]](r),f[a>>2]=f[r+8>>2],h=f[r+4>>2],r=f[r>>2],C[a>>2]=v(C[a>>2]*C[e+8>>2])/C[t+88>>2],f[i>>2]=r,f[i+4>>2]=h,f[i+12>>2]=0,C[i>>2]=v(C[i>>2]*C[e>>2])/C[t+80>>2],C[i+4>>2]=v(C[i+4>>2]*C[e+4>>2])/C[t+84>>2],r=f[(f[t+28>>2]+g|0)- -64>>2],yt[f[f[r>>2]+24>>2]](r,i),f[i+76>>2]=0,C[i+72>>2]=v(C[i+72>>2]*C[e+8>>2])/C[t+88>>2],C[i+68>>2]=v(C[i+68>>2]*C[e+4>>2])/C[t+84>>2],C[i+64>>2]=v(C[i+64>>2]*C[e>>2])/C[t+80>>2],h=f[n+4>>2],r=f[t+28>>2]+g|0,f[(a=r+8|0)>>2]=f[n>>2],f[a+4>>2]=h,n=f[i+20>>2],f[r>>2]=f[i+16>>2],f[r+4>>2]=n,a=f[o+4>>2],f[(n=r+24|0)>>2]=f[o>>2],f[n+4>>2]=a,o=f[p+4>>2],f[(n=r+16|0)>>2]=f[p>>2],f[n+4>>2]=o,o=f[d+4>>2],f[(n=r+40|0)>>2]=f[d>>2],f[n+4>>2]=o,o=f[y+4>>2],f[(n=r+32|0)>>2]=f[y>>2],f[n+4>>2]=o,o=f[m+4>>2],f[(n=r+48|0)>>2]=f[m>>2],f[n+4>>2]=o,n=f[_+4>>2],f[(r=r+56|0)>>2]=f[_>>2],f[r+4>>2]=n,f[t+68>>2]&&(r=f[(f[t+28>>2]+g|0)- -64>>2],yt[f[f[r>>2]+8>>2]](r,i+16|0,i+128|0,i+112|0),r=f[i+116>>2],f[R>>2]=f[i+112>>2],f[R+4>>2]=r,o=f[(n=i+136|0)+4>>2],f[(r=i+88|0)>>2]=f[n>>2],f[r+4>>2]=o,o=f[(n=i+120|0)+4>>2],f[(r=R+8|0)>>2]=f[n>>2],f[r+4>>2]=o,r=f[i+132>>2],f[i+80>>2]=f[i+128>>2],f[i+84>>2]=r,cr(f[t+68>>2],f[76+(f[t+28>>2]+g|0)>>2],i+80|0)),g=g+80|0,(0|(D=D+1|0))>2];);r=f[e+4>>2],f[t+80>>2]=f[e>>2],f[t+84>>2]=r,g=f[(e=e+8|0)+4>>2],f[(r=t+88|0)>>2]=f[e>>2],f[r+4>>2]=g,yt[f[f[t>>2]+68>>2]](t),Z=i+144|0},function(t){return(t|=0)+80|0},function(t,e,i){t|=0,e=v(e),i|=0;var r,n=v(0),a=0,o=v(0),_=v(0);Z=r=Z-96|0,f[(a=r+44|0)>>2]=0,f[a+4>>2]=0,f[(a=r+56|0)>>2]=0,f[a+4>>2]=0,f[r+52>>2]=1065353216,f[(a=r+76|0)>>2]=0,f[a+4>>2]=0,f[r+72>>2]=1065353216,f[(a=r+84|0)>>2]=0,f[a+4>>2]=0,f[r+92>>2]=0,f[r+36>>2]=0,f[r+40>>2]=0,f[r+32>>2]=1065353216,f[r+64>>2]=0,f[r+68>>2]=0,yt[f[f[t>>2]+8>>2]](t,r+32|0,r+16|0,r),e=v(e/v(12)),n=v(v(C[r>>2]-C[r+16>>2])*v(.5)),n=v(n+n),n=v(n*n),o=v(v(C[r+4>>2]-C[r+20>>2])*v(.5)),o=v(o+o),o=v(o*o),C[i+8>>2]=e*v(n+o),_=n,n=v(v(C[r+8>>2]-C[r+24>>2])*v(.5)),n=v(n+n),n=v(n*n),C[i+4>>2]=e*v(_+n),C[i>>2]=e*v(o+n),Z=r+96|0},function(t){return 14364},function(t,e){t|=0,e=v(e),C[t+76>>2]=e},function(t){return v(C[(t|=0)+76>>2])},function(t){return 24},function(t,e,i){var r=0,n=0,a=0,o=0,_=0,h=0,d=0,C=0,g=0,m=0,v=0,y=0;if(QA(t|=0,e|=0,i|=0),f[e+12>>2]=0,f[e+20>>2]=f[t+76>>2],r=f[t+20>>2],f[e+16>>2]=r,r){if(o=0|yt[f[f[i>>2]+16>>2]](i,76,r),r=f[o+8>>2],d=e,C=0|yt[f[f[i>>2]+28>>2]](i,r),f[d+12>>2]=C,f[e+16>>2]>0)for(a=72,r=r+72|0;n=f[t+28>>2]+a|0,f[r>>2]=f[n>>2],d=r+-8|0,C=0|yt[f[f[i>>2]+28>>2]](i,f[n+-8>>2]),f[d>>2]=C,yt[f[f[i>>2]+24>>2]](i,f[(f[t+28>>2]+a|0)-8>>2])||(n=f[(f[t+28>>2]+a|0)-8>>2],C=i,g=0|yt[f[f[n>>2]+52>>2]](n),m=1,d=f[f[i>>2]+16>>2],n=0|yt[d](0|C,0|g,0|m),_=f[(f[t+28>>2]+a|0)-8>>2],m=i,g=n,C=0|yt[f[f[_>>2]+56>>2]](_,f[n+8>>2],i),v=1346455635,y=f[(f[t+28>>2]+a|0)-8>>2],d=f[f[i>>2]+20>>2],yt[d](0|m,0|g,0|C,0|v,0|y)),n=f[t+28>>2]+a|0,f[r+-72>>2]=f[n+-72>>2],f[r+-68>>2]=f[n+-68>>2],f[r+-64>>2]=f[n+-64>>2],f[r+-60>>2]=f[n+-60>>2],f[r+-56>>2]=f[n+-56>>2],f[r+-52>>2]=f[n+-52>>2],f[r+-48>>2]=f[n+-48>>2],f[r+-44>>2]=f[n+-44>>2],f[r+-40>>2]=f[n+-40>>2],f[r+-36>>2]=f[n+-36>>2],f[r+-32>>2]=f[n+-32>>2],f[r+-28>>2]=f[n+-28>>2],f[r+-24>>2]=f[n+-24>>2],f[r+-20>>2]=f[n+-20>>2],f[r+-16>>2]=f[n+-16>>2],f[r+-4>>2]=f[n+-4>>2],f[r+-12>>2]=f[n+-12>>2],a=a+80|0,r=r+76|0,(0|(h=h+1|0))>2];);yt[f[f[i>>2]+20>>2]](i,o,14288,1497453121,f[o+8>>2])}return 14313},function(t,e){e|=0;var i=0,r=0;if(f[(t|=0)+72>>2]=f[t+72>>2]+1,(0|(i=f[t+20>>2]))>=1)for(r=m(i,80)+-16|0;i=i+-1|0,(0|e)==f[f[t+28>>2]+r>>2]&&Br(t,i),r=r+-80|0,(0|i)>0;);yt[f[f[t>>2]+68>>2]](t)},function(t){t|=0;var e,i=v(0),r=0,n=0,a=0,o=0;if(Z=e=Z-32|0,f[t+52>>2]=-581039253,f[t+56>>2]=-581039253,f[t+36>>2]=1566444395,f[t+40>>2]=1566444395,f[(r=t+60|0)>>2]=-581039253,f[r+4>>2]=0,f[(r=t+44|0)>>2]=1566444395,f[r+4>>2]=0,f[t+20>>2]>=1)for(r=64;n=f[t+28>>2]+r|0,a=f[n>>2],yt[f[f[a>>2]+8>>2]](a,n+-64|0,e+16|0,e),i=C[e+16>>2],C[t+36>>2]>i&&(C[t+36>>2]=i),i=C[e>>2],C[t+52>>2]>2]=i),i=C[e+20>>2],C[t+40>>2]>i&&(C[t+40>>2]=i),i=C[e+4>>2],C[t+56>>2]>2]=i),i=C[e+24>>2],C[t+44>>2]>i&&(C[t+44>>2]=i),i=C[e+8>>2],C[t+60>>2]>2]=i),r=r+80|0,(0|(o=o+1|0))>2];);Z=e+32|0},_r,function(t){var e;f[(t|=0)>>2]=14564,(e=f[t+32>>2])&&(_[t+36|0]&&CA(e),f[t+32>>2]=0),f[t+32>>2]=0,f[t+24>>2]=0,f[t+28>>2]=0,n[t+36|0]=1,CA(t)},function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n,a=0,o=0,d=0,y=0,p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=0,G=0,w=0,Q=0;if(Z=i=Z-80|0,(0|(n=0|yt[f[f[t>>2]+28>>2]](t)))>=1)for(p=C[t+12>>2],R=C[t+8>>2],D=C[t+4>>2];;){yt[f[f[t>>2]+16>>2]](t,i+76|0,i+52|0,i- -64|0,i+56|0,i+72|0,i+68|0,i+48|0,i+60|0,V);t:if(!((r=f[i+64>>2])>>>0>1))if(r-1){if((r=f[i+60>>2]+-2|0)>>>0>3)break t;switch(r-1|0){case 2:if(f[i+48>>2]<1)break t;for(r=0;y=f[i+76>>2],d=f[i+56>>2],o=f[i+72>>2]+m(f[i+68>>2],r)|0,a=y+m(d,_[0|o])|0,B=C[a>>2],E=C[a+4>>2],F=C[a+8>>2],f[i+12>>2]=0,C[i+8>>2]=p*F,C[i+4>>2]=R*E,C[i>>2]=D*B,a=y+m(d,_[o+1|0])|0,B=C[a>>2],E=C[a+4>>2],F=C[a+8>>2],f[i+28>>2]=0,C[i+24>>2]=p*F,C[i+20>>2]=R*E,C[i+16>>2]=D*B,o=y+m(d,_[o+2|0])|0,B=C[o>>2],E=C[o+4>>2],F=C[o+8>>2],f[i+44>>2]=0,C[i+40>>2]=p*F,C[i+36>>2]=R*E,C[i+32>>2]=D*B,yt[f[f[e>>2]+8>>2]](e,i,V,r),(0|(r=r+1|0))>2];);break t;case 0:if(f[i+48>>2]<1)break t;for(r=0;y=f[i+76>>2],d=f[i+56>>2],o=f[i+72>>2]+m(f[i+68>>2],r)|0,a=y+m(d,h[o>>1])|0,B=C[a>>2],E=C[a+4>>2],F=C[a+8>>2],f[i+12>>2]=0,C[i+8>>2]=p*F,C[i+4>>2]=R*E,C[i>>2]=D*B,a=y+m(d,h[o+2>>1])|0,B=C[a>>2],E=C[a+4>>2],F=C[a+8>>2],f[i+28>>2]=0,C[i+24>>2]=p*F,C[i+20>>2]=R*E,C[i+16>>2]=D*B,o=y+m(d,h[o+4>>1])|0,B=C[o+8>>2],E=C[o+4>>2],F=C[o>>2],f[i+44>>2]=0,C[i+32>>2]=D*F,C[i+36>>2]=R*E,C[i+40>>2]=p*B,yt[f[f[e>>2]+8>>2]](e,i,V,r),(0|(r=r+1|0))>2];);break t;case 1:break t}if(f[i+48>>2]<1)break t;for(r=0;y=f[i+76>>2],d=f[i+56>>2],o=f[i+72>>2]+m(f[i+68>>2],r)|0,a=y+m(d,f[o>>2])|0,B=C[a>>2],E=C[a+4>>2],F=C[a+8>>2],f[i+12>>2]=0,C[i+8>>2]=p*F,C[i+4>>2]=R*E,C[i>>2]=D*B,a=y+m(d,f[o+4>>2])|0,B=C[a>>2],E=C[a+4>>2],F=C[a+8>>2],f[i+28>>2]=0,C[i+24>>2]=p*F,C[i+20>>2]=R*E,C[i+16>>2]=D*B,o=y+m(d,f[o+8>>2])|0,B=C[o+8>>2],E=C[o+4>>2],F=C[o>>2],f[i+44>>2]=0,C[i+32>>2]=D*F,C[i+36>>2]=R*E,C[i+40>>2]=p*B,yt[f[f[e>>2]+8>>2]](e,i,V,r),(0|(r=r+1|0))>2];);}else if(r=f[i+60>>2]+-2|0,!(r>>>0>3)){switch(r-1|0){case 2:if(f[i+48>>2]<1)break t;for(r=0;o=f[i+72>>2]+m(f[i+68>>2],r)|0,d=_[0|o],f[i+12>>2]=0,y=f[i+76>>2],a=d,d=f[i+56>>2],a=y+m(a,d)|0,C[i+8>>2]=p*v(g[a+16>>3]),C[i+4>>2]=R*v(g[a+8>>3]),C[i>>2]=D*v(g[a>>3]),a=_[o+1|0],f[i+28>>2]=0,a=y+m(a,d)|0,C[i+24>>2]=p*v(g[a+16>>3]),C[i+20>>2]=R*v(g[a+8>>3]),C[i+16>>2]=D*v(g[a>>3]),o=y+m(d,_[o+2|0])|0,G=g[o>>3],w=g[o+8>>3],Q=g[o+16>>3],f[i+44>>2]=0,C[i+40>>2]=p*v(Q),C[i+36>>2]=R*v(w),C[i+32>>2]=D*v(G),yt[f[f[e>>2]+8>>2]](e,i,V,r),(0|(r=r+1|0))>2];);break t;case 0:if(f[i+48>>2]<1)break t;for(r=0;f[i+12>>2]=0,f[i+28>>2]=0,y=f[i+76>>2],d=f[i+56>>2],o=f[i+72>>2]+m(f[i+68>>2],r)|0,a=y+m(d,h[o>>1])|0,C[i+8>>2]=p*v(g[a+16>>3]),C[i+4>>2]=R*v(g[a+8>>3]),C[i>>2]=D*v(g[a>>3]),a=y+m(d,h[o+2>>1])|0,C[i+24>>2]=p*v(g[a+16>>3]),C[i+20>>2]=R*v(g[a+8>>3]),C[i+16>>2]=D*v(g[a>>3]),f[i+44>>2]=0,o=y+m(d,h[o+4>>1])|0,C[i+32>>2]=D*v(g[o>>3]),C[i+36>>2]=R*v(g[o+8>>3]),C[i+40>>2]=p*v(g[o+16>>3]),yt[f[f[e>>2]+8>>2]](e,i,V,r),(0|(r=r+1|0))>2];);break t;case 1:break t}if(!(f[i+48>>2]<1))for(r=0;f[i+12>>2]=0,f[i+28>>2]=0,y=f[i+76>>2],d=f[i+56>>2],o=f[i+72>>2]+m(f[i+68>>2],r)|0,a=y+m(d,f[o>>2])|0,C[i+8>>2]=p*v(g[a+16>>3]),C[i+4>>2]=R*v(g[a+8>>3]),C[i>>2]=D*v(g[a>>3]),a=y+m(d,f[o+4>>2])|0,C[i+24>>2]=p*v(g[a+16>>3]),C[i+20>>2]=R*v(g[a+8>>3]),C[i+16>>2]=D*v(g[a>>3]),f[i+44>>2]=0,o=y+m(d,f[o+8>>2])|0,C[i+32>>2]=D*v(g[o>>3]),C[i+36>>2]=R*v(g[o+8>>3]),C[i+40>>2]=p*v(g[o+16>>3]),yt[f[f[e>>2]+8>>2]](e,i,V,r),(0|(r=r+1|0))>2];);}if(yt[f[f[t>>2]+24>>2]](t,V),(0|(V=V+1|0))==(0|n))break}Z=i+80|0},mr,mr,Rr,Rr,function(t){return f[(t|=0)+24>>2]},Rr,Rr,function(t){return 1==f[(t|=0)+48>>2]|0},function(t,e,i){t|=0,i|=0;var r,n=0;n=f[(e|=0)+4>>2],f[t+52>>2]=f[e>>2],f[t+56>>2]=n,r=f[(e=e+8|0)+4>>2],f[(n=t+60|0)>>2]=f[e>>2],f[n+4>>2]=r,e=f[i+4>>2],f[t+68>>2]=f[i>>2],f[t+72>>2]=e,n=f[(i=i+8|0)+4>>2],f[(e=t+76|0)>>2]=f[i>>2],f[e+4>>2]=n,f[t+48>>2]=1},function(t,e,i){e|=0,i|=0;var r=0,n=0;r=f[(t|=0)+56>>2],f[e>>2]=f[t+52>>2],f[e+4>>2]=r,n=f[(r=t+60|0)+4>>2],f[(e=e+8|0)>>2]=f[r>>2],f[e+4>>2]=n,n=f[(r=t+76|0)+4>>2],f[(e=i+8|0)>>2]=f[r>>2],f[e+4>>2]=n,e=f[t+72>>2],f[i>>2]=f[t+68>>2],f[i+4>>2]=e},function(t){return 28},function(t,e,i){e|=0,i|=0;var r,o=0,d=0,C=0,g=0,v=0,y=0,p=0,R=0,D=0,B=0,E=0,F=0,V=0,G=0,w=0;if(Z=r=Z-32|0,o=0|yt[f[f[(t|=0)>>2]+28>>2]](t),f[e>>2]=0,f[e+20>>2]=o,o){if(B=0|yt[f[f[i>>2]+16>>2]](i,32,o),v=f[B+8>>2],G=e,w=0|yt[f[f[i>>2]+28>>2]](i,v),f[G>>2]=w,(0|(V=0|yt[f[f[t>>2]+28>>2]](t)))>0)for(;;){yt[f[f[t>>2]+16>>2]](t,r+28|0,r+4|0,r+16|0,r+8|0,r+24|0,r+20|0,r,r+12|0,D),f[v>>2]=0,f[v+4>>2]=0,f[(o=v+8|0)>>2]=0,f[o+4>>2]=0,f[(o=v+16|0)>>2]=0,f[o+4>>2]=0,o=f[r>>2],f[v+24>>2]=o,f[v+28>>2]=f[r+4>>2];t:if(!((d=f[r+12>>2]+-2|0)>>>0>3)){switch(d-1|0){default:if(!o)break t;if(g=0|yt[f[f[i>>2]+16>>2]](i,4,m(o,3)),o=f[g+8>>2],G=v,w=0|yt[f[f[i>>2]+28>>2]](i,o),f[G+8>>2]=w,f[r>>2]>=1)for(d=0,y=f[r+24>>2];C=y+m(f[r+20>>2],d)|0,f[o>>2]=f[C>>2],f[o+4>>2]=f[C+4>>2],f[o+8>>2]=f[C+8>>2],o=o+12|0,(0|(d=d+1|0))>2];);yt[f[f[i>>2]+20>>2]](i,g,14373,1497453121,f[g+8>>2]);break t;case 0:if(!o)break t;if(g=0|yt[f[f[i>>2]+16>>2]](i,8,o),o=f[g+8>>2],G=v,w=0|yt[f[f[i>>2]+28>>2]](i,o),f[G+12>>2]=w,f[r>>2]>=1)for(d=0;C=f[r+24>>2]+m(f[r+20>>2],d)|0,a[o>>1]=h[C>>1],a[o+2>>1]=h[C+2>>1],C=h[C+4>>1],a[o+6>>1]=0,a[o+4>>1]=C,o=o+8|0,(0|(d=d+1|0))>2];);yt[f[f[i>>2]+20>>2]](i,g,14388,1497453121,f[g+8>>2]);break t;case 1:break t;case 2:}if(o){if(g=0|yt[f[f[i>>2]+16>>2]](i,4,o),o=f[g+8>>2],G=v,w=0|yt[f[f[i>>2]+28>>2]](i,o),f[G+16>>2]=w,f[r>>2]>=1)for(d=0;C=f[r+24>>2]+m(f[r+20>>2],d)|0,n[0|o]=_[0|C],n[o+1|0]=_[C+1|0],n[o+2|0]=_[C+2|0],n[o+3|0]=0,o=o+4|0,(0|(d=d+1|0))>2];);yt[f[f[i>>2]+20>>2]](i,g,14415,1497453121,f[g+8>>2])}}t:if(!((o=f[r+16>>2])>>>0>1))if(o-1){if(!(o=f[r+4>>2]))break t;if(C=0|yt[f[f[i>>2]+16>>2]](i,16,o),o=f[C+8>>2],G=v,w=0|yt[f[f[i>>2]+28>>2]](i,o),f[G>>2]=w,(0|(y=f[r+4>>2]))>=1)for(g=0,E=f[r+8>>2],d=f[r+28>>2];f[o>>2]=f[d>>2],f[o+4>>2]=f[d+4>>2],f[o+8>>2]=f[d+8>>2],d=d+E|0,o=o+16|0,(0|(g=g+1|0))<(0|y););yt[f[f[i>>2]+20>>2]](i,C,14438,1497453121,f[C+8>>2])}else if(o=f[r+4>>2],o){if(C=0|yt[f[f[i>>2]+16>>2]](i,32,o),o=f[C+8>>2],G=v,w=0|yt[f[f[i>>2]+28>>2]](i,o),f[G+4>>2]=w,(0|(y=f[r+4>>2]))>=1)for(g=0,E=f[r+8>>2],d=f[r+28>>2];p=f[d+4>>2],f[o>>2]=f[d>>2],f[o+4>>2]=p,F=f[(R=d+8|0)+4>>2],f[(p=o+8|0)>>2]=f[R>>2],f[p+4>>2]=F,F=f[(R=d+16|0)+4>>2],f[(p=o+16|0)>>2]=f[R>>2],f[p+4>>2]=F,d=d+E|0,o=o+32|0,(0|(g=g+1|0))<(0|y););yt[f[f[i>>2]+20>>2]](i,C,14457,1497453121,f[C+8>>2])}if(yt[f[f[t>>2]+24>>2]](t,D),v=v+32|0,(0|(D=D+1|0))==(0|V))break}yt[f[f[i>>2]+20>>2]](i,B,14477,1497453121,f[B+8>>2])}return f[e+24>>2]=0,f[e+4>>2]=f[t+4>>2],f[e+8>>2]=f[t+8>>2],f[e+12>>2]=f[t+12>>2],f[e+16>>2]=f[t+16>>2],Z=r+32|0,14492},Gr,function(t){CA(Gr(t|=0))},function(t,e){e|=0;var i=0,r=0,a=0,o=0,h=0,d=0;t:{if(_[(t|=0)+165|0]){if(f[t+92>>2]>=(0|e))break t;if(d=i=e?dA(e<<4):0,(0|(o=f[t+88>>2]))>=1)for(;i=f[t+96>>2]+h|0,a=f[i+4>>2],f[(r=h+d|0)>>2]=f[i>>2],f[r+4>>2]=a,a=f[(i=i+8|0)+4>>2],f[(r=r+8|0)>>2]=f[i>>2],f[r+4>>2]=a,h=h+16|0,o=o+-1|0;);return(a=f[t+96>>2])&&(_[t+100|0]&&CA(a),f[t+96>>2]=0),f[t+96>>2]=d,f[t+92>>2]=e,void(n[t+100|0]=1)}if(!(f[t+112>>2]>=(0|e))){i=e?dA(e<<2):0,a=f[t+116>>2];e:{if((0|(r=f[t+108>>2]))>=1)for(h=i,o=a;f[h>>2]=f[o>>2],h=h+4|0,o=o+4|0,r=r+-1|0;);else if(!a)break e;_[t+120|0]&&CA(a),f[t+116>>2]=0}f[t+116>>2]=i,f[t+112>>2]=e,n[t+120|0]=1}}},function(t,e){e|=0;var i=0,r=0,o=0,d=0,C=0;t:{if(_[(t|=0)+164|0]){if(f[t+132>>2]>=(0|e))break t;r=e?dA(e<<2):0,o=f[t+136>>2];e:{if((0|(i=f[t+128>>2]))>=1)for(d=r,C=o;f[d>>2]=f[C>>2],d=d+4|0,C=C+4|0,i=i+-1|0;);else if(!o)break e;_[t+140|0]&&CA(o),f[t+136>>2]=0}return f[t+136>>2]=r,f[t+132>>2]=e,void(n[t+140|0]=1)}if(!(f[t+152>>2]>=(0|e))){r=e?dA(e<<1):0,o=f[t+156>>2];e:{if((0|(i=f[t+148>>2]))>=1)for(d=r,C=o;a[d>>1]=h[C>>1],d=d+2|0,C=C+2|0,i=i+-1|0;);else if(!o)break e;_[t+160|0]&&CA(o),f[t+156>>2]=0}f[t+156>>2]=r,f[t+152>>2]=e,n[t+160|0]=1}}},hA,function(t,e,i){t|=0,e|=0,i|=0;var r,n,a,o,_=v(0),h=v(0),d=v(0),g=0,m=v(0);Z=r=Z-32|0,o=f[(n=i+8|0)+4>>2],f[(g=a=r+24|0)>>2]=f[n>>2],f[g+4>>2]=o,g=f[i+4>>2],f[r+16>>2]=f[i>>2],f[r+20>>2]=g,_=C[r+16>>2],d=C[r+20>>2],h=C[a>>2],v(v(v(_*_)+v(d*d))+v(h*h))>2]=-1082130432,f[r+28>>2]=0,f[r+16>>2]=-1082130432,f[r+20>>2]=-1082130432,h=v(-1),d=v(-1),_=v(-1)),m=h,h=v(v(1)/v(E(v(v(v(_*_)+v(d*d))+v(h*h))))),C[r+24>>2]=m*h,C[r+20>>2]=d*h,C[r+16>>2]=_*h,hA(r,e,r+16|0);t:{e:if(i=f[e+4>>2],!(i>>>0>13)){switch(i-2|0){case 6:_=v(C[e+32>>2]*C[e+16>>2]);break t;case 0:case 1:case 4:case 5:case 7:case 10:break e}_=C[e+48>>2];break t}_=v(yt[f[f[e>>2]+48>>2]](e))}f[t+12>>2]=0,C[t+8>>2]=v(_*C[r+24>>2])+C[r+8>>2],C[t+4>>2]=v(_*C[r+20>>2])+C[r+4>>2],C[t>>2]=v(_*C[r+16>>2])+C[r>>2],Z=r+32|0},sA,ve,function(t,e,i,r,n,a,o,_,h,g){return t|=0,e|=0,i|=0,r|=0,n|=0,a|=0,o|=0,_|=0,h|=0,g|=0,Z=g=Z-80|0,t=0,f[g+76>>2]=0,C[g+64>>2]=C[a+48>>2]-C[n+48>>2],C[g+72>>2]=C[a+56>>2]-C[n+56>>2],C[g+68>>2]=C[a+52>>2]-C[n+52>>2],e=1,(wr(i,n,r,a,g- -64|0,g+8|0)||(e=0,function(t,e,i,r,n,a){var o,_,h=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),F=v(0),V=v(0),G=0,w=0,Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0);if(Z=o=Z-544|0,f[a>>2]=0,f[a+4>>2]=0,f[a+32>>2]=0,f[(w=a+24|0)>>2]=0,f[w+4>>2]=0,f[(w=a+16|0)>>2]=0,f[w+4>>2]=0,f[(w=a+8|0)>>2]=0,f[w+4>>2]=0,f[o+388>>2]=i,f[o+384>>2]=t,g=C[r+20>>2],m=C[r+36>>2],y=C[(t=e+20|0)>>2],p=C[(i=e+36|0)>>2],B=C[(w=e+24|0)>>2],h=C[r+24>>2],R=C[(_=e+40|0)>>2],D=C[r+40>>2],F=C[r+32>>2],V=C[r>>2],Q=C[r+16>>2],W=C[r+4>>2],Y=C[e+32>>2],pt=C[e>>2],Dt=C[e+16>>2],It=C[e+4>>2],St=C[e+8>>2],z=C[r+8>>2],f[o+436>>2]=0,f[o+420>>2]=0,f[o+404>>2]=0,Tt=v(v(v(St*z)+v(B*h))+v(R*D)),C[o+432>>2]=Tt,Et=v(v(v(It*z)+v(y*h))+v(p*D)),C[o+428>>2]=Et,h=v(v(v(pt*z)+v(Dt*h))+v(Y*D)),C[o+424>>2]=h,D=v(v(v(St*W)+v(B*g))+v(R*m)),C[o+416>>2]=D,z=v(v(v(It*W)+v(y*g))+v(p*m)),C[o+412>>2]=z,g=v(v(v(pt*W)+v(Dt*g))+v(Y*m)),C[o+408>>2]=g,m=v(v(v(V*St)+v(Q*B))+v(F*R)),C[o+400>>2]=m,y=v(v(v(V*It)+v(Q*y))+v(F*p)),C[o+396>>2]=y,p=v(v(v(V*pt)+v(Q*Dt))+v(F*Y)),C[o+392>>2]=p,B=C[t>>2],R=C[i>>2],F=C[w>>2],V=C[r+52>>2],Q=C[e+52>>2],W=C[_>>2],Y=C[r+56>>2],pt=C[e+56>>2],Dt=C[e>>2],It=C[e+16>>2],St=C[e+32>>2],Ot=C[e+4>>2],Nt=C[e+8>>2],Ft=C[r+48>>2],Vt=C[e+48>>2],f[o+508>>2]=0,f[o+500>>2]=0,f[o+484>>2]=0,C[o+480>>2]=Tt,C[o+476>>2]=D,C[o+472>>2]=m,f[o+468>>2]=0,C[o+464>>2]=Et,C[o+460>>2]=z,C[o+456>>2]=y,f[o+452>>2]=0,C[o+448>>2]=h,C[o+444>>2]=g,g=v(Ft-Vt),m=v(V-Q),y=v(Y-pt),C[o+496>>2]=v(v(Nt*g)+v(F*m))+v(W*y),C[o+492>>2]=v(v(g*Ot)+v(m*B))+v(y*R),C[o+488>>2]=v(v(g*Dt)+v(m*It))+v(y*St),f[o+504>>2]=348,C[o+440>>2]=p,f[(t=o+136|0)>>2]=0,f[t+4>>2]=0,f[o+128>>2]=0,f[o+132>>2]=0,f[o+364>>2]=0,f[o+368>>2]=0,f[o+376>>2]=2,f[o+144>>2]=0,t=yr(o,o+384|0,n))f[a>>2]=1==(0|t)?1:2;else{if(G=f[o+372>>2],f[G+32>>2])for(h=v(0),r=0,t=0,B=v(0),p=v(0),y=v(0),m=v(0),g=v(0);R=C[(G=r+G|0)+16>>2],w=f[G>>2],G=f[o+504>>2],n=f[o+508>>2],i=f[o+384>>2]+(n>>1)|0,yt[1&n?f[f[i>>2]+G>>2]:G](o+528|0,i,w),w=f[o+508>>2],i=f[o+388>>2]+(w>>1)|0,Q=v(R*C[o+536>>2]),W=v(R*C[o+532>>2]),Y=v(R*C[o+528>>2]),n=f[f[o+372>>2]+r>>2],D=v(-C[n+8>>2]),F=v(-C[n+4>>2]),V=v(-C[n>>2]),G=f[o+504>>2],G=1&w?f[f[i>>2]+G>>2]:G,h=v(h+Q),B=v(B+W),p=v(p+Y),f[o+524>>2]=0,C[o+520>>2]=v(v(C[o+424>>2]*V)+v(C[o+428>>2]*F))+v(C[o+432>>2]*D),C[o+516>>2]=v(v(C[o+408>>2]*V)+v(C[o+412>>2]*F))+v(C[o+416>>2]*D),C[o+512>>2]=v(v(C[o+392>>2]*V)+v(C[o+396>>2]*F))+v(C[o+400>>2]*D),yt[G](o+528|0,i,o+512|0),D=C[o+528>>2],F=C[o+532>>2],V=C[o+536>>2],y=v(y+v(R*v(v(v(v(D*C[o+472>>2])+v(F*C[o+476>>2]))+v(V*C[o+480>>2]))+C[o+496>>2]))),m=v(m+v(R*v(v(v(v(D*C[o+456>>2])+v(F*C[o+460>>2]))+v(V*C[o+464>>2]))+C[o+492>>2]))),g=v(g+v(R*v(v(v(v(D*C[o+440>>2])+v(F*C[o+444>>2]))+v(V*C[o+448>>2]))+C[o+488>>2]))),r=r+4|0,t=t+1|0,G=f[o+372>>2],t>>>0>2];);else g=v(0),m=v(0),y=v(0),p=v(0),B=v(0),h=v(0);R=C[e+48>>2],D=C[e+8>>2],F=C[e>>2],V=C[e+4>>2],Q=C[e+52>>2],W=C[e+24>>2],Y=C[e+16>>2],pt=C[e+20>>2],Dt=C[e+56>>2],It=C[e+40>>2],St=C[e+32>>2],z=C[e+36>>2],f[a+16>>2]=0,C[a+12>>2]=Dt+v(v(v(p*St)+v(B*z))+v(h*It)),C[a+8>>2]=Q+v(v(v(p*Y)+v(B*pt))+v(h*W)),C[a+4>>2]=R+v(v(v(p*F)+v(B*V))+v(h*D)),D=C[e+48>>2],F=C[e+8>>2],V=C[e>>2],Q=C[e+4>>2],W=C[e+52>>2],Y=C[e+24>>2],pt=C[e+16>>2],Dt=C[e+20>>2],It=C[e+56>>2],St=C[e+40>>2],z=C[e+32>>2],Tt=C[e+36>>2],p=v(p-g),B=v(B-m),h=v(h-y),R=v(E(v(v(v(p*p)+v(B*B))+v(h*h)))),C[a+52>>2]=R,f[a+48>>2]=0,f[a+32>>2]=0,Et=h,h=R>v(9999999747378752e-20)?v(v(1)/R):v(1),C[a+44>>2]=Et*h,C[a+40>>2]=B*h,C[a+36>>2]=p*h,C[a+28>>2]=It+v(v(v(g*z)+v(m*Tt))+v(y*St)),C[a+24>>2]=W+v(v(v(g*pt)+v(m*Dt))+v(y*Y)),C[a+20>>2]=D+v(v(v(g*V)+v(m*Q))+v(y*F)),G=1}return Z=o+544|0,G}(i,n,r,a,g- -64|0,g+8|0)))&&(t=f[g+16>>2],f[_>>2]=f[g+12>>2],f[_+4>>2]=t,r=f[(i=g+20|0)+4>>2],f[(t=_+8|0)>>2]=f[i>>2],f[t+4>>2]=r,i=f[(t=g+28|0)+4>>2],f[h>>2]=f[t>>2],f[h+4>>2]=i,r=f[(i=g+36|0)+4>>2],f[(t=h+8|0)>>2]=f[i>>2],f[t+4>>2]=r,t=f[g+48>>2],f[o>>2]=f[g+44>>2],f[o+4>>2]=t,r=f[(i=g+52|0)+4>>2],f[(t=o+8|0)>>2]=f[i>>2],f[t+4>>2]=r,t=e),Z=g+80|0,0|t},sA,ve,Sr,ve,function(t,e,i,r,a,o,h,d,g,m){t|=0,e|=0,i|=0,r|=0,a|=0,o|=0,h|=0,d|=0,g|=0,m|=0;var y,p,R,D,B=v(0),E=0,F=v(0),V=v(0),G=0,w=0,Q=v(0),W=0,Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=0,Nt=0,Ft=v(0),Vt=0,Gt=0,Lt=0,wt=v(0),xt=v(0),Qt=v(0),Wt=v(0),Yt=0;for(Z=t=Z-4240|0,Gt=f[i+4>>2]+-17>>>0<=1?f[r+4>>2]+-17>>>0<2:Gt;Xr(),f[(G=(t+1264|0)+E|0)+12>>2]=0,V=C[E+1744>>2],Q=v(-V),B=C[E+1748>>2],F=C[E+1752>>2],C[G+8>>2]=v(v(C[a+8>>2]*Q)-v(C[a+24>>2]*B))-v(C[a+40>>2]*F),C[G+4>>2]=v(v(C[a+4>>2]*Q)-v(B*C[a+20>>2]))-v(F*C[a+36>>2]),C[G>>2]=v(v(C[a>>2]*Q)-v(B*C[a+16>>2]))-v(F*C[a+32>>2]),Q=C[o+32>>2],z=C[o>>2],pt=C[o+16>>2],Dt=C[o+36>>2],It=C[o+4>>2],St=C[o+20>>2],Tt=C[o+40>>2],Y=C[o+8>>2],Et=C[o+24>>2],f[(G=(t+272|0)+E|0)+12>>2]=0,C[G+8>>2]=v(v(V*Y)+v(B*Et))+v(F*Tt),C[G+4>>2]=v(v(V*It)+v(B*St))+v(F*Dt),C[G>>2]=v(v(V*z)+v(B*pt))+v(F*Q),672!=(0|(E=E+16|0)););if(G=42,!((0|(Nt=0|yt[f[f[i>>2]+84>>2]](i)))<1)){for(E=0,G=0;yt[f[f[i>>2]+88>>2]](i,G,t+3248|0),f[t+3260>>2]=0,B=C[t+3248>>2],F=C[t+3252>>2],V=C[t+3256>>2],C[t+3256>>2]=v(v(B*C[a+32>>2])+v(F*C[a+36>>2]))+v(V*C[a+40>>2]),C[t+3252>>2]=v(v(B*C[a+16>>2])+v(F*C[a+20>>2]))+v(V*C[a+24>>2]),C[t+3248>>2]=v(v(B*C[a>>2])+v(F*C[a+4>>2]))+v(V*C[a+8>>2]),Xr(),Ot=f[t+3260>>2],f[(w=E+2424|0)>>2]=f[t+3256>>2],f[w+4>>2]=Ot,Ot=f[t+3252>>2],f[(w=E+2416|0)>>2]=f[t+3248>>2],f[w+4>>2]=Ot,f[(w=(t+1264|0)+E|0)+684>>2]=0,V=C[t+3248>>2],Q=v(-V),B=C[t+3252>>2],F=C[t+3256>>2],C[w+680>>2]=v(v(C[a+8>>2]*Q)-v(C[a+24>>2]*B))-v(C[a+40>>2]*F),C[w+676>>2]=v(v(C[a+4>>2]*Q)-v(B*C[a+20>>2]))-v(F*C[a+36>>2]),C[w+672>>2]=v(v(C[a>>2]*Q)-v(B*C[a+16>>2]))-v(F*C[a+32>>2]),f[(w=(t+272|0)+E|0)+684>>2]=0,C[w+672>>2]=v(v(V*C[o>>2])+v(B*C[o+16>>2]))+v(F*C[o+32>>2]),C[w+676>>2]=v(v(V*C[o+4>>2])+v(B*C[o+20>>2]))+v(F*C[o+36>>2]),C[w+680>>2]=v(v(V*C[o+8>>2])+v(B*C[o+24>>2]))+v(F*C[o+40>>2]),E=E+16|0,(0|Nt)!=(0|(G=G+1|0)););G=G+42|0}if(p=i,R=t+1264|0,D=t+3248|0,(0|(y=0|yt[f[f[r>>2]+84>>2]](r)))>=1){for(w=G<<4,Nt=1744,Ot=t+1264|0,Lt=t+272|0,E=0;yt[f[f[r>>2]+88>>2]](r,E,t+3248|0),f[t+3260>>2]=0,B=C[t+3248>>2],F=C[t+3252>>2],V=C[t+3256>>2],C[t+3256>>2]=v(v(B*C[o+32>>2])+v(F*C[o+36>>2]))+v(V*C[o+40>>2]),C[t+3252>>2]=v(v(B*C[o+16>>2])+v(F*C[o+20>>2]))+v(V*C[o+24>>2]),C[t+3248>>2]=v(v(B*C[o>>2])+v(F*C[o+4>>2]))+v(V*C[o+8>>2]),Xr(),Yt=f[t+3260>>2],f[(Vt=(W=w+Nt|0)+8|0)>>2]=f[t+3256>>2],f[Vt+4>>2]=Yt,Vt=f[t+3252>>2],f[W>>2]=f[t+3248>>2],f[W+4>>2]=Vt,z=C[a+32>>2],pt=C[a>>2],Dt=C[a+16>>2],It=C[a+36>>2],St=C[a+4>>2],Tt=C[a+20>>2],Y=C[a+40>>2],Q=C[a+8>>2],Et=C[a+24>>2],B=C[t+3256>>2],V=C[t+3248>>2],F=C[t+3252>>2],f[(W=w+Ot|0)+12>>2]=0,Ft=Q,Q=v(-V),C[W+8>>2]=v(v(Ft*Q)-v(Et*F))-v(Y*B),C[W+4>>2]=v(v(St*Q)-v(Tt*F))-v(It*B),C[W>>2]=v(v(pt*Q)-v(Dt*F))-v(z*B),Q=C[o+32>>2],z=C[o>>2],pt=C[o+16>>2],Dt=C[o+36>>2],It=C[o+4>>2],St=C[o+20>>2],Tt=C[o+40>>2],Y=C[o+8>>2],Et=C[o+24>>2],f[(W=w+Lt|0)+12>>2]=0,C[W+8>>2]=v(v(V*Y)+v(F*Et))+v(B*Tt),C[W+4>>2]=v(v(V*It)+v(F*St))+v(B*Dt),C[W>>2]=v(v(V*z)+v(F*pt))+v(B*Q),Lt=Lt+16|0,Ot=Ot+16|0,Nt=Nt+16|0,(0|y)!=(0|(E=E+1|0)););G=E+G|0}if(yt[f[f[i>>2]+76>>2]](p,R,D,G),yt[f[f[r>>2]+76>>2]](r,t+272|0,t+2256|0,G),(0|G)<1)Q=v(0xde0b6b000000000),It=v(0),z=v(0),St=v(0),pt=v(0),Tt=v(0),Dt=v(0),Et=v(0);else for(Q=v(0xde0b6b000000000),E=0,Et=v(0),Dt=v(0),Tt=v(0),pt=v(0),St=v(0),z=v(0),It=v(0);Xr(),B=C[E+1744>>2],F=C[E+1748>>2],V=Gt?v(0):C[E+1752>>2],+v(v(v(B*B)+v(F*F))+v(V*V))>.01&&(Y=C[(w=(t+2256|0)+E|0)>>2],Ft=C[w+4>>2],wt=C[w+8>>2],xt=C[(w=(t+3248|0)+E|0)>>2],Qt=C[w+4>>2],Wt=C[w+8>>2],(Y=v(v(v(B*v(v(v(v(v(Y*C[o>>2])+v(Ft*C[o+4>>2]))+v(wt*C[o+8>>2]))+C[o+48>>2])-v(v(v(v(xt*C[a>>2])+v(Qt*C[a+4>>2]))+v(Wt*C[a+8>>2]))+C[a+48>>2])))+v(F*v(v(v(v(v(Y*C[o+16>>2])+v(Ft*C[o+20>>2]))+v(wt*C[o+24>>2]))+C[o+52>>2])-v(v(v(v(xt*C[a+16>>2])+v(Qt*C[a+20>>2]))+v(Wt*C[a+24>>2]))+C[a+52>>2]))))+v(V*v(Gt?0:v(v(v(v(Y*C[o+32>>2])+v(Ft*C[o+36>>2]))+v(wt*C[o+40>>2]))+C[o+56>>2])-v(v(v(v(xt*C[a+32>>2])+v(Qt*C[a+36>>2]))+v(Wt*C[a+40>>2]))+C[a+56>>2])))))>2],It=B,z=B,St=F,pt=F,Tt=V,Dt=V,Q=Y)),E=E+16|0,G=G+-1|0;);return GA(i),GA(r),E=0,Q>2]=0,E=f[(r=a+8|0)+4>>2],f[(i=t- -64|0)>>2]=f[r>>2],f[i+4>>2]=E,E=f[(r=a+24|0)+4>>2],f[(i=t+80|0)>>2]=f[r>>2],f[i+4>>2]=E,E=f[(r=a+40|0)+4>>2],f[(i=t+96|0)>>2]=f[r>>2],f[i+4>>2]=E,B=v(Q+v(v(B+F)+v(.5))),C[t+112>>2]=v(Dt*B)+C[a+56>>2],C[t+108>>2]=v(pt*B)+C[a+52>>2],i=f[a+4>>2],f[t+56>>2]=f[a>>2],f[t+60>>2]=i,i=f[a+20>>2],f[t+72>>2]=f[a+16>>2],f[t+76>>2]=i,i=f[a+36>>2],f[t+88>>2]=f[a+32>>2],f[t+92>>2]=i,C[t+104>>2]=v(z*B)+C[a+48>>2],a=f[(r=o+8|0)+4>>2],f[(i=t+128|0)>>2]=f[r>>2],f[i+4>>2]=a,r=f[o+20>>2],f[(i=t+136|0)>>2]=f[o+16>>2],f[i+4>>2]=r,a=f[(r=o+24|0)+4>>2],f[(i=t+144|0)>>2]=f[r>>2],f[i+4>>2]=a,r=f[o+36>>2],f[(i=t+152|0)>>2]=f[o+32>>2],f[i+4>>2]=r,a=f[(r=o+40|0)+4>>2],f[(i=t+160|0)>>2]=f[r>>2],f[i+4>>2]=a,r=f[o+52>>2],f[(i=t+168|0)>>2]=f[o+48>>2],f[i+4>>2]=r,a=f[(r=o+56|0)+4>>2],f[(i=t+176|0)>>2]=f[r>>2],f[i+4>>2]=a,f[t+184>>2]=1566444395,i=f[o+4>>2],f[t+120>>2]=f[o>>2],f[t+124>>2]=i,f[e+16>>2]=0,C[e+12>>2]=-Dt,C[e+8>>2]=-pt,C[e+4>>2]=-z,n[t+48|0]=0,f[t+8>>2]=15076,Sr(e,t+56|0,t+8|0,m),(i=_[t+48|0])&&(F=C[t+44>>2],f[d+12>>2]=0,B=v(B-F),C[d>>2]=C[t+28>>2]-v(z*B),e=t+36|0,C[d+8>>2]=C[e>>2]-v(Dt*B),C[d+4>>2]=C[t+32>>2]-v(pt*B),r=f[t+32>>2],f[g>>2]=f[t+28>>2],f[g+4>>2]=r,a=f[e+4>>2],f[(r=g+8|0)>>2]=f[e>>2],f[r+4>>2]=a,C[h>>2]=It,C[h+4>>2]=St,C[h+8>>2]=Tt,C[h+12>>2]=Et),E=0!=(0|i)),Z=t+4240|0,0|E},ve,De,De,function(t,e,i,r){t|=0,e|=0,i|=0,r=v(r);var a,o=0;o=f[e+4>>2],f[t+4>>2]=f[e>>2],f[t+8>>2]=o,a=f[(e=e+8|0)+4>>2],f[(o=t+12|0)>>2]=f[e>>2],f[o+4>>2]=a,e=f[i+4>>2],f[t+20>>2]=f[i>>2],f[t+24>>2]=e,o=f[(i=i+8|0)+4>>2],f[(e=t+28|0)>>2]=f[i>>2],f[e+4>>2]=o,n[t+40|0]=1,C[t+36>>2]=r},sA,ve,zr,ve,De,De,function(t,e,i,r){t|=0,e|=0,i|=0,r=v(r);var a=0,o=0;C[t+36>>2]>r&&(n[t+40|0]=1,a=f[e+4>>2],f[t+4>>2]=f[e>>2],f[t+8>>2]=a,o=f[(e=e+8|0)+4>>2],f[(a=t+12|0)>>2]=f[e>>2],f[a+4>>2]=o,e=f[i+4>>2],f[t+20>>2]=f[i>>2],f[t+24>>2]=e,a=f[(i=i+8|0)+4>>2],f[(e=t+28|0)>>2]=f[i>>2],f[e+4>>2]=a,C[t+36>>2]=r)},sA,ve,function(t,e,i,r){var a,o;return t|=0,i|=0,r|=0,i=f[(e|=0)>>2],i=0|yt[f[f[i>>2]+56>>2]](i,72),r=f[e+4>>2],a=f[t+12>>2],o=f[t+16>>2],t=f[t+8>>2],vA(i,e),n[i+28|0]=1,f[i+8>>2]=t,f[i>>2]=15444,f[i+24>>2]=0,n[i+48|0]=1,f[i+16>>2]=0,f[i+20>>2]=0,f[i+44>>2]=0,f[i+64>>2]=a,f[i+68>>2]=o,n[i+60|0]=0,f[i+56>>2]=r,n[i+52|0]=0,f[i+36>>2]=0,f[i+40>>2]=0,0|i},function(t){var e=0,i=0;return f[(t|=0)>>2]=15444,_[t+52|0]&&((e=f[t+56>>2])&&(i=f[t+4>>2],yt[f[f[i>>2]+16>>2]](i,e))),(e=f[t+44>>2])&&(_[t+48|0]&&CA(e),f[t+44>>2]=0),f[t+44>>2]=0,f[t+36>>2]=0,f[t+40>>2]=0,n[t+48|0]=1,(e=f[t+24>>2])&&(_[t+28|0]&&CA(e),f[t+24>>2]=0),f[t+24>>2]=0,f[t+16>>2]=0,f[t+20>>2]=0,n[t+28|0]=1,0|t},function(t){var e=0,i=0;f[(t|=0)>>2]=15444,_[t+52|0]&&((e=f[t+56>>2])&&(i=f[t+4>>2],yt[f[f[i>>2]+16>>2]](i,e))),(e=f[t+44>>2])&&(_[t+48|0]&&CA(e),f[t+44>>2]=0),f[t+44>>2]=0,f[t+36>>2]=0,f[t+40>>2]=0,n[t+48|0]=1,(e=f[t+24>>2])&&(_[t+28|0]&&CA(e),f[t+24>>2]=0),f[t+24>>2]=0,f[t+16>>2]=0,f[t+20>>2]=0,n[t+28|0]=1,$(t)},function(t,e,i,r,a){t|=0,e|=0,i|=0,r|=0,a|=0;var o,h=0,d=v(0),g=v(0),p=0,D=v(0),B=0,F=v(0),V=0,G=0,w=0,Q=0,W=0,Y=0,z=0,pt=0,Dt=0,It=v(0),St=0,Tt=v(0),Et=0,Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0),Gt=v(0),Lt=0,wt=0,xt=v(0),Qt=0,Wt=0,Yt=v(0),Pt=v(0),Mt=v(0),Zt=v(0),Ut=v(0),Xt=v(0),Jt=v(0),jt=v(0),zt=v(0),Ht=v(0),Kt=0,qt=v(0),$t=v(0),bi=v(0),di=v(0),yi=v(0),Ii=v(0),Bi=v(0),BA=0,gr=v(0),tn=v(0),en=0,An=0,rn=0,nn=0,an=0,on=0,sn=0,ln=0,fn=0,cn=0,bn=0,_n=v(0),un=0,hn=0,dn=0;Z=o=Z-928|0,(h=f[t+56>>2])||(h=f[t+4>>2],h=0|yt[f[f[h>>2]+12>>2]](h,f[e+8>>2],f[i+8>>2]),n[t+52|0]=1,f[t+56>>2]=h),f[a+4>>2]=h,V=f[i+4>>2];t:{e:if(z=f[e+4>>2],B=f[z+4>>2]+-8|0,!(B>>>0>2)){switch(B-1|0){case 1:if((B=f[V+4>>2]+-8|0)>>>0>2)break e;switch(B-1|0){case 1:if(r=z+32|0,t=f[z+56>>2],Ut=C[r+(t<<2)>>2],d=C[r+((t+2|0)%3<<2)>>2],B=V+32|0,r=f[V+56>>2],g=C[h+784>>2],(d=Pr(o+432|0,o+8|0,Ut,d,C[B+(r<<2)>>2],C[B+((r+2|0)%3<<2)>>2],t,r,f[e+12>>2],f[i+12>>2],g))>2]+16>>2]](a,o+432|0,o+8|0,d),t=f[a+4>>2],!f[t+780>>2])break t;if((0|(e=f[t+772>>2]))!=(0|(i=f[f[a+8>>2]+8>>2]))){se(t,f[f[a+12>>2]+8>>2]+4|0,i+4|0);break t}se(t,e+4|0,f[f[a+12>>2]+8>>2]+4|0);break t;case 0:break e}if(r=z+32|0,t=f[z+56>>2],g=C[h+784>>2],(d=Pr(o+432|0,o+8|0,C[r+(t<<2)>>2],C[r+((t+2|0)%3<<2)>>2],v(0),v(C[V+32>>2]*C[V+16>>2]),t,1,f[e+12>>2],f[i+12>>2],g))>2]+16>>2]](a,o+432|0,o+8|0,d),t=f[a+4>>2],!f[t+780>>2])break t;if((0|(e=f[t+772>>2]))!=(0|(i=f[f[a+8>>2]+8>>2]))){se(t,f[f[a+12>>2]+8>>2]+4|0,i+4|0);break t}se(t,e+4|0,f[f[a+12>>2]+8>>2]+4|0);break t;case 0:break e}if(10==f[V+4>>2]){if(r=V+32|0,t=f[V+56>>2],g=C[h+784>>2],(d=Pr(o+432|0,o+8|0,v(0),v(C[z+32>>2]*C[z+16>>2]),C[r+(t<<2)>>2],C[r+((t+2|0)%3<<2)>>2],1,t,f[e+12>>2],f[i+12>>2],g))>2]+16>>2]](a,o+432|0,o+8|0,d),t=f[a+4>>2],!f[t+780>>2])break t;if((0|(e=f[t+772>>2]))!=(0|(i=f[f[a+8>>2]+8>>2]))){se(t,f[f[a+12>>2]+8>>2]+4|0,i+4|0);break t}se(t,e+4|0,f[f[a+12>>2]+8>>2]+4|0);break t}}if(f[o+920>>2]=1566444395,n[o+764|0]=0,f[o+740>>2]=953267991,Dt=Mr(o+352|0,z,V,o+432|0,f[t+8>>2]),f[Dt+32>>2]=V,f[Dt+28>>2]=z,g=v(v(v(v(yt[f[f[z>>2]+48>>2]](z))+v(yt[f[f[V>>2]+48>>2]](V)))+C[f[t+56>>2]+784>>2])+C[a+32>>2]),C[o+920>>2]=g*g,h=f[e+12>>2],W=f[(B=h+8|0)+4>>2],f[(Q=o+800|0)>>2]=f[B>>2],f[Q+4>>2]=W,B=f[h>>2],W=f[h+4>>2],w=f[(Q=h+24|0)+4>>2],f[(pt=o+816|0)>>2]=f[Q>>2],f[pt+4>>2]=w,Q=f[h+16>>2],w=f[h+20>>2],St=f[(pt=h+40|0)+4>>2],f[(wt=o+832|0)>>2]=f[pt>>2],f[wt+4>>2]=St,pt=f[h+32>>2],St=f[h+36>>2],Lt=f[(wt=h+56|0)+4>>2],f[(Et=o+848|0)>>2]=f[wt>>2],f[Et+4>>2]=Lt,f[o+792>>2]=B,f[o+796>>2]=W,f[o+808>>2]=Q,f[o+812>>2]=w,f[o+824>>2]=pt,f[o+828>>2]=St,B=f[h+52>>2],f[o+840>>2]=f[h+48>>2],f[o+844>>2]=B,h=f[i+12>>2],W=f[(B=h+8|0)+4>>2],f[(Q=o+864|0)>>2]=f[B>>2],f[Q+4>>2]=W,B=f[h+4>>2],f[o+856>>2]=f[h>>2],f[o+860>>2]=B,W=f[h+20>>2],f[(B=o+872|0)>>2]=f[h+16>>2],f[B+4>>2]=W,Q=f[(W=h+24|0)+4>>2],f[(w=o+880|0)>>2]=f[W>>2],f[w+4>>2]=Q,Q=f[(W=h+40|0)+4>>2],f[(w=o+896|0)>>2]=f[W>>2],f[w+4>>2]=Q,Q=f[h+36>>2],f[(w=W=o+888|0)>>2]=f[h+32>>2],f[w+4>>2]=Q,w=f[h+52>>2],f[(Q=o+904|0)>>2]=f[h+48>>2],f[Q+4>>2]=w,w=f[(h=h+56|0)+4>>2],f[(pt=o+912|0)>>2]=f[h>>2],f[pt+4>>2]=w,!((0|(h=f[z+4>>2]))>6)&&(!((0|(w=f[V+4>>2]))>6)&&(f[o+344>>2]=15564,g=v(0),h&&(g=v(yt[f[f[z>>2]+48>>2]](z)),w=f[V+4>>2]),w&&(d=v(yt[f[f[V>>2]+48>>2]](V))),n[o+44|0]=0,C[o+36>>2]=d,C[o+32>>2]=g,f[o+12>>2]=a,f[o+8>>2]=15740,f[z+56>>2]))){if(f[V+56>>2]){d=C[f[t+56>>2]+784>>2];e:{i:{if(_[r+24|0]){if(g=v(-1.0000000150474662e30),function(t,e,i,r,n,a){var o,h=v(0),d=v(0),g=v(0),m=v(0),p=v(0),R=v(0),D=0,B=v(0),F=0,V=v(0),G=0,w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=0,It=0,St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0),Gt=0,Lt=v(0),wt=v(0),xt=v(0),Qt=v(0),Wt=v(0),Yt=v(0),Pt=v(0),Mt=v(0),Zt=v(0),Ut=v(0),Xt=v(0),Jt=v(0),jt=v(0),zt=v(0),Ht=v(0),Kt=v(0),qt=v(0);Z=o=Z-112|0,f[687]=f[687]+1,m=C[i+52>>2],F=20,p=C[i+20>>2],Q=C[i+24>>2],wt=C[r+52>>2],xt=C[r+20>>2],w=C[r+24>>2],Qt=C[i+56>>2],h=C[t+68>>2],B=C[i+36>>2],R=C[t+72>>2],W=C[i+40>>2],Y=C[r+56>>2],Ot=C[e+68>>2],d=C[r+36>>2],Nt=C[e+72>>2],V=C[r+40>>2],z=C[i+48>>2],Ft=C[i+8>>2],Wt=C[i+4>>2],Yt=C[i>>2],Pt=C[r+48>>2],Mt=C[r+8>>2],Et=C[r+4>>2],pt=C[r>>2],St=C[i+16>>2],Zt=C[r+16>>2],Tt=C[t+64>>2],Vt=C[i+32>>2],g=C[e+64>>2],Ut=C[r+32>>2],f[o+28>>2]=0,Qt=v(v(Qt+v(v(v(Tt*Vt)+v(h*B))+v(R*W)))-v(Y+v(v(v(g*Ut)+v(Ot*d))+v(Nt*V)))),C[o+24>>2]=Qt,wt=v(v(m+v(v(v(Tt*St)+v(h*p))+v(R*Q)))-v(wt+v(v(v(g*Zt)+v(Ot*xt))+v(Nt*w)))),C[o+20>>2]=wt,xt=v(v(z+v(v(v(Tt*Yt)+v(h*Wt))+v(R*Ft)))-v(Pt+v(v(v(g*pt)+v(Ot*Et))+v(Nt*Mt)))),C[o+16>>2]=xt;A:{r:{n:{a:{o:{s:if(G=f[t+28>>2],(0|G)<1)h=v(34028234663852886e22);else for(G=G+-1|0,h=v(34028234663852886e22);;){if(D=f[t+36>>2]+F|0,R=C[D+8>>2],Ot=C[D+4>>2],Nt=C[D>>2],f[o+12>>2]=0,B=v(v(v(Nt*Vt)+v(Ot*B))+v(R*W)),C[o+8>>2]=B,p=v(v(v(Nt*St)+v(Ot*p))+v(R*Q)),C[o+4>>2]=p,R=v(v(v(Nt*C[i>>2])+v(Ot*C[i+4>>2]))+v(R*Ft)),C[o>>2]=R,v(v(v(R*xt)+v(p*wt))+v(B*Qt))>2]=-B,C[o+4>>2]=-p,C[o>>2]=-R),f[685]=f[685]+1,!_[2988]||jr(i,r,o+16|0,o,t,e,h)){if(Dt=0,f[686]=f[686]+1,IA(t,i,o,o+108|0,o+104|0,o+80|0,o- -64|0),IA(e,r,o,o+100|0,o+96|0,o+48|0,o+32|0),(p=C[o+104>>2])<(B=C[o+100>>2])||((R=C[o+96>>2])<(W=C[o+108>>2])||(g=(g=v(p-B))<(p=v(R-W))?g:p,Dt=1)),!Dt)break o;g>2],f[n>>2]=f[o>>2],f[n+4>>2]=D,Gt=f[(It=o+8|0)+4>>2],f[(D=n+8|0)>>2]=f[It>>2],f[D+4>>2]=Gt,h=g)}if(!G)break s;F=F+36|0,G=G+-1|0,W=C[i+40>>2],B=C[i+36>>2],Vt=C[i+32>>2],Q=C[i+24>>2],p=C[i+20>>2],St=C[i+16>>2],Ft=C[i+8>>2]}if((0|(G=f[e+28>>2]))>=1)for(Dt=20;;){if(D=f[e+36>>2]+Dt|0,g=C[D+8>>2],p=C[D>>2],B=C[D+4>>2],f[o+12>>2]=0,R=v(v(v(p*C[r+32>>2])+v(B*C[r+36>>2]))+v(g*C[r+40>>2])),C[o+8>>2]=R,W=v(v(v(p*C[r+16>>2])+v(B*C[r+20>>2]))+v(g*C[r+24>>2])),C[o+4>>2]=W,g=v(v(v(p*C[r>>2])+v(B*C[r+4>>2]))+v(g*C[r+8>>2])),C[o>>2]=g,v(v(v(g*xt)+v(W*wt))+v(R*Qt))>2]=-R,C[o+4>>2]=-W,C[o>>2]=-g),f[685]=f[685]+1,!_[2988]||jr(i,r,o+16|0,o,t,e,h)){if(F=0,f[686]=f[686]+1,IA(t,i,o,o+108|0,o+104|0,o+80|0,o- -64|0),IA(e,r,o,o+100|0,o+96|0,o+48|0,o+32|0),(g=C[o+104>>2])<(p=C[o+100>>2])||((B=C[o+96>>2])<(R=C[o+108>>2])||(Q=(Q=v(g-p))<(g=v(B-R))?Q:g,F=1)),!F)break o;Q>2],f[n>>2]=f[o>>2],f[n+4>>2]=D,Gt=f[(It=o+8|0)+4>>2],f[(D=n+8|0)>>2]=f[It>>2],f[D+4>>2]=Gt,h=Q)}if(Dt=Dt+36|0,!(G=G+-1|0))break}if((0|(Dt=f[t+48>>2]))>=1)break a;It=-1,Q=v(0),g=v(0),p=v(0),B=v(0),R=v(0),W=v(0),Gt=-1;break n}r=0;break A}for(F=f[e+48>>2],Gt=-1,D=0,It=-1,W=v(0),R=v(0),B=v(0),p=v(0),g=v(0),Q=v(0);;){if((0|F)>=1){for(G=f[t+56>>2]+(D<<4)|0,Ft=C[G>>2],St=C[G+4>>2],Tt=C[G+8>>2],Ot=v(v(v(Ft*C[i+32>>2])+v(St*C[i+36>>2]))+v(Tt*C[i+40>>2])),Nt=v(v(v(Ft*C[i+16>>2])+v(St*C[i+20>>2]))+v(Tt*C[i+24>>2])),Ft=v(v(v(Ft*C[i>>2])+v(St*C[i+4>>2]))+v(Tt*C[i+8>>2])),G=0,Dt=4;;){if(F=f[e+56>>2]+Dt|0,Vt=C[F+4>>2],w=C[F+-4>>2],Y=C[F>>2],Lt=C[r+40>>2],jt=C[r+32>>2],zt=C[r+36>>2],St=C[r+24>>2],Tt=C[r+16>>2],m=C[r+20>>2],Ht=C[r+8>>2],Kt=C[r>>2],qt=C[r+4>>2],f[o+12>>2]=0,St=v(v(v(w*Tt)+v(Y*m))+v(Vt*St)),Tt=v(v(v(w*Kt)+v(Y*qt))+v(Vt*Ht)),m=v(v(Ft*St)-v(Nt*Tt)),C[o+8>>2]=m,Vt=v(v(v(w*jt)+v(Y*zt))+v(Vt*Lt)),w=v(v(Ot*Tt)-v(Ft*Vt)),C[o+4>>2]=w,Y=v(v(Nt*Vt)-v(Ot*St)),C[o>>2]=Y,(!(+v(y(m))>1e-6^1)||+v(y(Y))>1e-6|+v(y(w))>1e-6)&&(Lt=m,m=v(v(1)/v(E(v(v(m*m)+v(v(Y*Y)+v(w*w)))))),Lt=v(Lt*m),C[o+8>>2]=Lt,w=v(w*m),C[o+4>>2]=w,m=v(Y*m),C[o>>2]=m,v(v(v(m*xt)+v(w*wt))+v(Qt*Lt))>2]=-Lt,C[o+4>>2]=-w,C[o>>2]=-m),f[685]=f[685]+1,!_[2988]||jr(i,r,o+16|0,o,t,e,h))){if(F=0,f[686]=f[686]+1,IA(t,i,o,o+108|0,o+104|0,o+80|0,o- -64|0),IA(e,r,o,o+100|0,o+96|0,o+48|0,o+32|0),(m=C[o+104>>2])<(w=C[o+100>>2])||((Y=C[o+96>>2])<(Lt=C[o+108>>2])||((d=v(m-w))<(m=v(Y-Lt))?(F=1,Yt=C[o+56>>2],Pt=C[o+52>>2],Mt=C[o+48>>2],V=C[o+72>>2],z=C[o+68>>2],Wt=C[o+64>>2]):(F=1,Yt=C[o+40>>2],Pt=C[o+36>>2],Mt=C[o+32>>2],V=C[o+88>>2],z=C[o+84>>2],Wt=C[o+80>>2],d=m))),!F)break r;d>2],f[n>>2]=f[o>>2],f[n+4>>2]=It,F=f[(Gt=o+8|0)+4>>2],f[(It=n+8|0)>>2]=f[Gt>>2],f[It+4>>2]=F,Q=Mt,g=Pt,p=Yt,B=Wt,R=z,W=V,Et=Tt,pt=St,Zt=Vt,Ut=Ft,Xt=Nt,Jt=Ot,It=D,Gt=G,h=d)}if(Dt=Dt+16|0,!((0|(G=G+1|0))<(0|(F=f[e+48>>2]))))break}Dt=f[t+48>>2]}if(!((0|(D=D+1|0))<(0|Dt)))break}}if(!((It|Gt)<0)){Yt=v(Q-B),Pt=v(g-R),Mt=v(p-W),V=v(v(v(Yt*Et)+v(Pt*pt))+v(Mt*Zt)),Wt=v(v(v(Yt*Ut)+v(Pt*Xt))+v(Mt*Jt)),h=v(0),z=v(v(v(Et*Ut)+v(pt*Xt))+v(Zt*Jt)),(d=v(v(1)-v(z*z)))!=v(0)&&(h=v(-1.0000000150474662e30),(d=v(v(Wt-v(V*z))/d))v(1.0000000150474662e30)&&(h=v(1.0000000150474662e30)));n:if((V=v(v(z*h)-V))v(1.0000000150474662e30))){V=v(-1.0000000150474662e30),h=d;break n}V=v(-1.0000000150474662e30)}else V>v(1.0000000150474662e30)&&(h=v(-1.0000000150474662e30),V=v(1.0000000150474662e30),d=v(Wt+v(z*v(1.0000000150474662e30))),dv(1.0000000150474662e30)&&(h=v(1.0000000150474662e30))));f[o+92>>2]=0,Zt=v(Zt*V),d=v(Zt+v(Mt-v(Jt*h))),C[o+88>>2]=d,z=v(pt*V),pt=v(z+v(Pt-v(Xt*h))),C[o+84>>2]=pt,V=v(Et*V),h=v(V+v(Yt-v(Ut*h))),C[o+80>>2]=h,(Et=v(v(d*d)+v(v(h*h)+v(pt*pt))))>v(1.1920928955078125e-7)&&(m=d,Ut=v(E(Et)),d=v(v(1)/Ut),Et=v(m*d),C[o+88>>2]=Et,pt=v(pt*d),C[o+84>>2]=pt,h=v(h*d),C[o+80>>2]=h,v(v(v(h*xt)+v(pt*wt))+v(Et*Qt))>2]=-Et,C[o+84>>2]=-pt,C[o+80>>2]=-h),f[o+76>>2]=0,C[o+72>>2]=p+Zt,C[o+68>>2]=g+z,C[o+64>>2]=Q+V,yt[f[f[a>>2]+16>>2]](a,o+80|0,o- -64|0,v(-Ut)))}if(r=1,h=C[n>>2],d=C[n+4>>2],Q=C[n+8>>2],!(v(v(v(xt*h)+v(wt*d))+v(Qt*Q))>2]=0,C[n+8>>2]=-Q,C[n+4>>2]=-d,C[n>>2]=-h;break A}r=0}return Z=o+112|0,r}(f[z+56>>2],f[V+56>>2],f[e+12>>2],f[i+12>>2],o+248|0,a))break i;break e}if(Sr(Dt,o+792|0,o+8|0,f[r+20>>2]),h=f[(r=o+24|0)+4>>2],f[(B=o+256|0)>>2]=f[r>>2],f[B+4>>2]=h,r=f[o+20>>2],f[o+248>>2]=f[o+16>>2],f[o+252>>2]=r,g=C[o+40>>2],!_[o+44|0]|g>2]))<=-1)for(f[t+20>>2]<=-1&&((r=f[t+24>>2])&&(_[t+28|0]&&CA(r),f[t+24>>2]=0),f[t+20>>2]=0,f[t+24>>2]=0,n[t+28|0]=1),B=h<<4;r=f[o+332>>2],Dt=f[t+24>>2]+B|0,f[(W=Dt)>>2]=f[o+328>>2],f[W+4>>2]=r,W=f[(r=o+336|0)+4>>2],f[(Dt=Dt+8|0)>>2]=f[r>>2],f[Dt+4>>2]=W,B=B+16|0,Dt=(r=h+1|0)>>>0>=h>>>0,h=r,Dt;);f[t+16>>2]=0,function(t,e,i,r,a,o,h,d,g,y){var p,R,D=0,B=0,F=v(0),V=v(0),G=0,w=v(0),Q=v(0),W=0,Y=0,z=0,yt=v(0),pt=0,Dt=0,It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0),Gt=v(0),Lt=v(0),wt=v(0),xt=0;if(Z=p=Z-32|0,f[p+28>>2]=f[t+12>>2],F=C[t>>2],w=C[t+4>>2],Q=C[t+8>>2],V=v(v(1)/v(E(v(v(v(F*F)+v(w*w))+v(Q*Q))))),yt=v(Q*V),C[p+24>>2]=yt,It=v(w*V),C[p+20>>2]=It,St=v(F*V),C[p+16>>2]=St,pt=-1,(0|(G=f[i+28>>2]))>=1)for(t=f[i+36>>2]+20|0,Tt=C[a+40>>2],Et=C[a+36>>2],Ot=C[a+24>>2],Nt=C[a+20>>2],Ft=C[a+32>>2],Vt=C[a+16>>2],Gt=C[a+8>>2],Lt=C[a+4>>2],wt=C[a>>2],V=v(-34028234663852886e22);F=C[t>>2],w=C[t+4>>2],Q=C[t+8>>2],V=(D=(F=v(v(v(St*v(v(v(F*wt)+v(w*Lt))+v(Q*Gt)))+v(It*v(v(v(F*Vt)+v(w*Nt))+v(Q*Ot))))+v(yt*v(v(v(F*Ft)+v(w*Et))+v(Q*Tt)))))>V)?F:V,pt=D?B:pt,t=t+36|0,(0|(B=B+1|0))<(0|G););if((0|(t=f[d+4>>2]))<=-1)for(f[d+8>>2]<=-1&&((D=f[d+12>>2])&&(_[d+16|0]&&CA(D),f[d+12>>2]=0),n[d+16|0]=1,f[d+8>>2]=0,f[d+12>>2]=0),B=t<<4;W=f[p+4>>2],D=f[d+12>>2]+B|0,f[D>>2]=f[p>>2],f[D+4>>2]=W,W=f[(G=p+8|0)+4>>2],f[(D=D+8|0)>>2]=f[G>>2],f[D+4>>2]=W,B=B+16|0,G=(D=t+1|0)>>>0>=t>>>0,t=D,G;);if(f[d+4>>2]=0,t=f[i+36>>2]+m(pt,36)|0,(0|(R=f[t+4>>2]))>=1)for(xt=t+12|0,B=0,D=0;;){if(t=f[i+16>>2]+(f[f[xt>>2]+(D<<2)>>2]<<4)|0,V=C[t>>2],F=C[t+4>>2],w=C[t+8>>2],Q=v(v(v(v(V*C[a+32>>2])+v(F*C[a+36>>2]))+v(w*C[a+40>>2]))+C[a+56>>2]),yt=v(v(v(v(V*C[a+16>>2])+v(F*C[a+20>>2]))+v(w*C[a+24>>2]))+C[a+52>>2]),V=v(v(v(v(V*C[a>>2])+v(F*C[a+4>>2]))+v(w*C[a+8>>2]))+C[a+48>>2]),f[d+8>>2]==(0|B)&&!((0|B)>=(0|(G=B?B<<1:1)))){if(G?(W=dA(G<<4),B=f[d+4>>2]):W=0,(0|B)>=1)for(t=0;z=f[d+12>>2]+t|0,Dt=f[z+4>>2],f[(Y=t+W|0)>>2]=f[z>>2],f[Y+4>>2]=Dt,Dt=f[(z=z+8|0)+4>>2],f[(Y=Y+8|0)>>2]=f[z>>2],f[Y+4>>2]=Dt,t=t+16|0,B=B+-1|0;);(t=f[d+12>>2])&&(_[d+16|0]&&CA(t),f[d+12>>2]=0),f[d+12>>2]=W,n[d+16|0]=1,f[d+8>>2]=G,B=f[d+4>>2]}if(t=f[d+12>>2]+(B<<4)|0,f[t+12>>2]=0,C[t+8>>2]=Q,C[t+4>>2]=yt,C[t>>2]=V,B=f[d+4>>2]+1|0,f[d+4>>2]=B,(0|(D=D+1|0))==(0|R))break}(0|pt)>-1&&Or(p+16|0,e,r,d,g,o,h,y),Z=p+32|0}(o+248|0,f[z+56>>2],f[V+56>>2],f[e+12>>2],f[i+12>>2],v(g-d),d,t+12|0,t+32|0,a)}if(!_[t+52|0])break t;if(t=f[a+4>>2],!f[t+780>>2])break t;if((0|(e=f[t+772>>2]))!=(0|(i=f[f[a+8>>2]+8>>2]))){se(t,f[f[a+12>>2]+8>>2]+4|0,i+4|0);break t}se(t,e+4|0,f[f[a+12>>2]+8>>2]+4|0);break t}if(1==f[V+4>>2]){if(f[o+252>>2]=0,h=f[i+12>>2],F=C[h+56>>2],Ot=C[h+36>>2],xt=C[h+40>>2],Yt=C[h+52>>2],Mt=C[h+20>>2],Zt=C[h+24>>2],g=C[V+68>>2],d=C[V+60>>2],D=C[V- -64>>2],Ht=C[h+32>>2],Xt=C[h+16>>2],It=C[h+48>>2],Tt=C[h+8>>2],Jt=C[h>>2],jt=C[h+4>>2],h=dA(16),f[o+256>>2]=1,f[o+260>>2]=h,n[o+264|0]=1,C[h>>2]=It+v(v(v(d*Jt)+v(D*jt))+v(g*Tt)),C[h+4>>2]=Yt+v(v(v(d*Xt)+v(D*Mt))+v(g*Zt)),f[h+12>>2]=0,C[h+8>>2]=F+v(v(v(d*Ht)+v(D*Ot))+v(g*xt)),B=f[o+252>>2]+1|0,f[o+252>>2]=B,g=C[V+76>>2],h=f[i+12>>2],d=C[V+80>>2],D=C[V+84>>2],F=v(v(v(v(g*C[h+32>>2])+v(d*C[h+36>>2]))+v(D*C[h+40>>2]))+C[h+56>>2]),Ot=v(v(v(v(g*C[h+16>>2])+v(d*C[h+20>>2]))+v(D*C[h+24>>2]))+C[h+52>>2]),g=v(v(v(v(g*C[h>>2])+v(d*C[h+4>>2]))+v(D*C[h+8>>2]))+C[h+48>>2]),f[o+256>>2]==(0|B)&&!((0|B)>=(0|(W=B?B<<1:1)))){if(W?(Q=dA(W<<4),B=f[o+252>>2]):Q=0,(0|B)>=1)for(h=0;w=f[o+260>>2]+h|0,pt=f[w+4>>2],f[(St=h+Q|0)>>2]=f[w>>2],f[St+4>>2]=pt,pt=f[(w=w+8|0)+4>>2],f[(St=St+8|0)>>2]=f[w>>2],f[St+4>>2]=pt,h=h+16|0,B=B+-1|0;);(h=f[o+260>>2])&&(_[o+264|0]&&CA(h),f[o+260>>2]=0),f[o+260>>2]=Q,n[o+264|0]=1,f[o+256>>2]=W,B=f[o+252>>2]}if(h=f[o+260>>2]+(B<<4)|0,f[h+12>>2]=0,C[h+8>>2]=F,C[h+4>>2]=Ot,C[h>>2]=g,B=f[o+252>>2]+1|0,f[o+252>>2]=B,g=C[V+92>>2],i=f[i+12>>2],d=C[V+96>>2],D=C[V+100>>2],F=v(v(v(v(g*C[i>>2])+v(d*C[i+4>>2]))+v(D*C[i+8>>2]))+C[i+48>>2]),Ot=v(v(v(v(g*C[i+32>>2])+v(d*C[i+36>>2]))+v(D*C[i+40>>2]))+C[i+56>>2]),g=v(v(v(v(g*C[i+16>>2])+v(d*C[i+20>>2]))+v(D*C[i+24>>2]))+C[i+52>>2]),f[o+256>>2]==(0|B)&&!((0|B)>=(0|(i=B?B<<1:1)))){if(i?(W=dA(i<<4),B=f[o+252>>2]):W=0,(0|B)>=1)for(h=0;Q=f[o+260>>2]+h|0,w=f[Q+4>>2],f[(pt=h+W|0)>>2]=f[Q>>2],f[pt+4>>2]=w,w=f[(Q=Q+8|0)+4>>2],f[(pt=pt+8|0)>>2]=f[Q>>2],f[pt+4>>2]=w,h=h+16|0,B=B+-1|0;);(h=f[o+260>>2])&&(_[o+264|0]&&CA(h),f[o+260>>2]=0),f[o+260>>2]=W,n[o+264|0]=1,f[o+256>>2]=i,B=f[o+252>>2]}if(i=f[o+260>>2]+(B<<4)|0,f[i+12>>2]=0,C[i+8>>2]=Ot,C[i+4>>2]=g,C[i>>2]=F,f[o+252>>2]=f[o+252>>2]+1,g=C[f[t+56>>2]+784>>2],Sr(Dt,o+792|0,o+344|0,f[r+20>>2]),d=C[Dt+4>>2],D=C[Dt+8>>2],F=C[Dt+12>>2],(Ot=v(v(v(d*d)+v(D*D))+v(F*F)))>v(1.1920928955078125e-7)){if(f[o+340>>2]=0,Ut=F,F=v(v(1)/Ot),C[o+336>>2]=Ut*F,C[o+332>>2]=D*F,C[o+328>>2]=d*F,d=v(v(C[Dt+56>>2]-v(yt[f[f[z>>2]+48>>2]](z)))-v(yt[f[f[V>>2]+48>>2]](V))),(0|(V=f[t+36>>2]))<=-1)for(f[t+40>>2]<=-1&&((i=f[t+44>>2])&&(_[t+48|0]&&CA(i),f[t+44>>2]=0),f[t+40>>2]=0,f[t+44>>2]=0,n[t+48|0]=1),h=V<<4;i=f[o+316>>2],r=f[t+44>>2]+h|0,f[(B=r)>>2]=f[o+312>>2],f[B+4>>2]=i,B=f[(i=o+320|0)+4>>2],f[(r=r+8|0)>>2]=f[i>>2],f[r+4>>2]=B,h=h+16|0,r=(i=V+1|0)>>>0>=V>>>0,V=i,r;);f[t+36>>2]=0,Or(o+328|0,f[z+56>>2],f[e+12>>2],o+248|0,t+32|0,v(d-g),g,a)}if(_[t+52|0]&&(t=f[a+4>>2],f[t+780>>2]&&((0|(e=f[t+772>>2]))==(0|(i=f[f[a+8>>2]+8>>2]))?se(t,e+4|0,f[f[a+12>>2]+8>>2]+4|0):se(t,f[f[a+12>>2]+8>>2]+4|0,i+4|0))),!(t=f[o+260>>2]))break t;_[o+264|0]&&CA(t),f[o+260>>2]=0;break t}}if(Sr(Dt,o+792|0,a,f[r+20>>2]),!(!f[t+64>>2]|f[f[a+4>>2]+780>>2]>=f[t+68>>2])&&(g=C[Dt+4>>2],d=C[Dt+8>>2],D=C[Dt+12>>2],(F=v(v(v(g*g)+v(d*d))+v(D*D)))>v(1.1920928955078125e-7)&&(w=o+856|0,pt=o+840|0,St=o+824|0,wt=o+808|0,Ut=d,d=v(v(1)/F),Ot=v(Ut*d),Ht=v(g*d),Xt=v(D*d),v(y(Xt))>v(.7071067690849304)?(g=v(v(1)/v(E(v(v(Xt*Xt)+v(Ot*Ot))))),d=v(Ot*g),g=v(-v(Xt*g)),D=v(0)):(d=v(v(1)/v(E(v(v(Ht*Ht)+v(Ot*Ot))))),g=v(Ht*d),D=v(-v(Ot*d)),d=v(0)),F=v(yt[f[f[z>>2]+16>>2]](z)),xt=v(yt[f[f[V>>2]+16>>2]](V)),Yt=C[744],Lt=f[(V=(h=(z=F>2],f[(Et=en=o+256|0)>>2]=f[V>>2],f[Et+4>>2]=Lt,Et=f[(Lt=(V=z?wt:B)+8|0)+4>>2],f[(Qt=o+272|0)>>2]=f[Lt>>2],f[Qt+4>>2]=Et,Qt=f[(Et=(Lt=z?St:W)+8|0)+4>>2],f[(Kt=o+288|0)>>2]=f[Et>>2],f[Kt+4>>2]=Qt,Kt=f[(Qt=(Et=z?pt:Q)+8|0)+4>>2],f[(BA=o+304|0)>>2]=f[Qt>>2],f[BA+4>>2]=Kt,Qt=f[h+4>>2],f[o+248>>2]=f[h>>2],f[o+252>>2]=Qt,h=f[V+4>>2],f[o+264>>2]=f[V>>2],f[o+268>>2]=h,h=f[Lt+4>>2],f[o+280>>2]=f[Lt>>2],f[o+284>>2]=h,h=f[Et+4>>2],f[o+296>>2]=f[Et>>2],f[o+300>>2]=h,!((0|(h=f[t+64>>2]))<1))))for(Ut=d,F=v(v(R(v(Yt/(z?F:xt)),v(.39269909262657166)))*v(.5)),_n=v(v(v(D*D)+v(g*g))+v(d*d)),d=v(dr(F)/v(E(_n))),xt=v(Ut*d),Yt=v(g*d),Mt=v(D*d),Zt=Cr(F),Ut=v(E(v(v(Xt*Xt)+v(v(Ht*Ht)+v(Ot*Ot))))),Lt=o+296|0,Et=o+224|0,Qt=o+208|0,Kt=o+280|0,BA=o+192|0,An=o+264|0,rn=o+176|0,nn=o+160|0,an=o+144|0,on=o+128|0,sn=o+112|0,ln=o+96|0,fn=o+80|0,cn=o- -64|0,bn=o+48|0,V=0;_n>v(1.1920928955078125e-7)&&(F=v(v(v(v(6.2831854820251465)/v(0|h))*v(0|V))*v(.5)),D=v(dr(F)/Ut),g=v(Xt*D),d=v(Ot*D),D=v(Ht*D),F=Cr(F),z?(h=f[e+12>>2],Jt=C[h>>2],jt=C[h+4>>2],qt=C[h+8>>2],f[o+804>>2]=0,$t=C[h+36>>2],bi=C[h+20>>2],di=C[h+40>>2],yi=C[h+24>>2],Ii=C[h+32>>2],Bi=C[h+16>>2],f[o+836>>2]=0,f[o+820>>2]=0,Nt=v(v(v(v(Yt*F)-v(Zt*d))-v(Mt*g))+v(xt*D)),Ft=v(v(v(v(Zt*F)+v(Mt*D))+v(Yt*d))+v(xt*g)),Vt=v(v(v(v(Mt*F)-v(Zt*D))-v(xt*d))+v(Yt*g)),Gt=v(v(v(v(xt*F)-v(Zt*g))-v(Yt*D))+v(Mt*d)),It=v(v(v(g*Nt)+v(v(D*Ft)+v(F*Vt)))-v(d*Gt)),Tt=v(v(v(v(F*Ft)-v(D*Vt))-v(d*Nt))-v(g*Gt)),zt=v(v(v(d*Vt)+v(v(g*Ft)+v(F*Gt)))-v(D*Nt)),g=v(v(v(D*Gt)+v(v(F*Nt)+v(d*Ft)))-v(g*Vt)),d=v(v(2)/v(v(Tt*Tt)+v(v(zt*zt)+v(v(It*It)+v(g*g))))),D=v(zt*d),Ft=v(It*D),F=v(g*d),Vt=v(Tt*F),Nt=v(Ft-Vt),Gt=v(g*D),Pt=v(It*d),gr=v(Tt*Pt),d=v(Gt+gr),Pt=v(It*Pt),tn=v(g*F),g=v(v(1)-v(Pt+tn)),C[o+832>>2]=v(v(qt*Nt)+v(yi*d))+v(di*g),C[o+828>>2]=v(v(Nt*jt)+v(d*bi))+v(g*$t),C[o+824>>2]=v(v(Nt*Jt)+v(d*Bi))+v(g*Ii),F=v(It*F),It=v(Tt*D),g=v(F+It),Tt=v(zt*D),d=v(v(1)-v(Pt+Tt)),D=v(Gt-gr),C[o+816>>2]=v(v(qt*g)+v(yi*d))+v(di*D),C[o+812>>2]=v(v(g*jt)+v(d*bi))+v(D*$t),C[o+808>>2]=v(v(g*Jt)+v(d*Bi))+v(D*Ii),g=v(v(1)-v(tn+Tt)),d=v(F-It),D=v(Ft+Vt),C[o+800>>2]=v(v(qt*g)+v(yi*d))+v(di*D),C[o+796>>2]=v(v(g*jt)+v(d*bi))+v(D*$t),C[o+792>>2]=v(v(g*Jt)+v(d*Bi))+v(D*Ii),h=f[i+12>>2],G=f[h+4>>2],f[w>>2]=f[h>>2],f[w+4>>2]=G,G=f[(p=h+8|0)+4>>2],f[(Y=w+8|0)>>2]=f[p>>2],f[Y+4>>2]=G,G=f[(p=h+24|0)+4>>2],f[(Y=B+8|0)>>2]=f[p>>2],f[Y+4>>2]=G,p=f[h+20>>2],f[B>>2]=f[h+16>>2],f[B+4>>2]=p,G=f[(p=h+40|0)+4>>2],f[(Y=W+8|0)>>2]=f[p>>2],f[Y+4>>2]=G,p=f[h+36>>2],f[W>>2]=f[h+32>>2],f[W+4>>2]=p,G=f[(p=h+56|0)+4>>2],f[(Y=Q+8|0)>>2]=f[p>>2],f[Y+4>>2]=G,p=f[h+52>>2],f[Q>>2]=f[h+48>>2],f[Q+4>>2]=p):(h=f[e+12>>2],G=f[(p=h+8|0)>>2],p=f[p+4>>2],Y=f[h>>2],hn=f[h+4>>2],Wt=f[h+20>>2],f[wt>>2]=f[h+16>>2],f[wt+4>>2]=Wt,dn=f[(Wt=h+24|0)+4>>2],f[(un=wt+8|0)>>2]=f[Wt>>2],f[un+4>>2]=dn,f[(Wt=o+800|0)>>2]=G,f[Wt+4>>2]=p,p=f[h+36>>2],f[St>>2]=f[h+32>>2],f[St+4>>2]=p,G=f[(p=h+40|0)+4>>2],f[(Wt=St+8|0)>>2]=f[p>>2],f[Wt+4>>2]=G,G=f[(p=h+56|0)+4>>2],f[(Wt=pt+8|0)>>2]=f[p>>2],f[Wt+4>>2]=G,p=f[h+52>>2],f[pt>>2]=f[h+48>>2],f[pt+4>>2]=p,f[o+792>>2]=Y,f[o+796>>2]=hn,h=f[i+12>>2],Jt=C[h+36>>2],jt=C[h+20>>2],qt=C[h+40>>2],$t=C[h+24>>2],bi=C[h+32>>2],di=C[h>>2],yi=C[h+16>>2],Ii=C[h+4>>2],Bi=C[h+8>>2],f[o+900>>2]=0,f[o+884>>2]=0,f[o+868>>2]=0,Nt=v(v(v(v(Yt*F)-v(Zt*d))-v(Mt*g))+v(xt*D)),Ft=v(v(v(v(Zt*F)+v(Mt*D))+v(Yt*d))+v(xt*g)),Vt=v(v(v(v(Mt*F)-v(Zt*D))-v(xt*d))+v(Yt*g)),Gt=v(v(v(v(xt*F)-v(Zt*g))-v(Yt*D))+v(Mt*d)),It=v(v(v(g*Nt)+v(v(D*Ft)+v(F*Vt)))-v(d*Gt)),Tt=v(v(v(v(F*Ft)-v(D*Vt))-v(d*Nt))-v(g*Gt)),zt=v(v(v(d*Vt)+v(v(g*Ft)+v(F*Gt)))-v(D*Nt)),g=v(v(v(D*Gt)+v(v(F*Nt)+v(d*Ft)))-v(g*Vt)),d=v(v(2)/v(v(Tt*Tt)+v(v(zt*zt)+v(v(It*It)+v(g*g))))),D=v(zt*d),Ft=v(It*D),F=v(g*d),Vt=v(Tt*F),Nt=v(Ft-Vt),Gt=v(g*D),Pt=v(It*d),gr=v(Tt*Pt),d=v(Gt+gr),Pt=v(It*Pt),tn=v(g*F),g=v(v(1)-v(Pt+tn)),C[o+896>>2]=v(v(Bi*Nt)+v($t*d))+v(qt*g),C[o+892>>2]=v(v(Nt*Ii)+v(d*jt))+v(g*Jt),C[o+888>>2]=v(v(Nt*di)+v(d*yi))+v(g*bi),F=v(It*F),It=v(Tt*D),g=v(F+It),Tt=v(zt*D),d=v(v(1)-v(Pt+Tt)),D=v(Gt-gr),C[o+880>>2]=v(v(Bi*g)+v($t*d))+v(qt*D),C[o+876>>2]=v(v(g*Ii)+v(d*jt))+v(D*Jt),C[o+872>>2]=v(v(g*di)+v(d*yi))+v(D*bi),g=v(v(1)-v(tn+Tt)),d=v(F-It),D=v(Ft+Vt),C[o+864>>2]=v(v(Bi*g)+v($t*d))+v(qt*D),C[o+860>>2]=v(v(g*Ii)+v(d*jt))+v(D*Jt),C[o+856>>2]=v(v(g*di)+v(d*yi))+v(D*bi)),h=f[o+796>>2],f[bn>>2]=f[o+792>>2],f[bn+4>>2]=h,h=f[wt+4>>2],f[cn>>2]=f[wt>>2],f[cn+4>>2]=h,h=f[St+4>>2],f[fn>>2]=f[St>>2],f[fn+4>>2]=h,h=f[pt+4>>2],f[ln>>2]=f[pt>>2],f[ln+4>>2]=h,p=f[(h=o+800|0)+4>>2],f[(G=bn+8|0)>>2]=f[h>>2],f[G+4>>2]=p,p=f[(h=wt+8|0)+4>>2],f[(G=cn+8|0)>>2]=f[h>>2],f[G+4>>2]=p,p=f[(h=St+8|0)+4>>2],f[(G=fn+8|0)>>2]=f[h>>2],f[G+4>>2]=p,p=f[(h=pt+8|0)+4>>2],f[(G=ln+8|0)>>2]=f[h>>2],f[G+4>>2]=p,f[o+40>>2]=0,f[o+44>>2]=a,f[o+8>>2]=15924,h=f[r+20>>2],G=f[(p=w+8|0)+4>>2],f[(Y=sn+8|0)>>2]=f[p>>2],f[Y+4>>2]=G,p=f[w+4>>2],f[sn>>2]=f[w>>2],f[sn+4>>2]=p,G=f[(p=B+8|0)+4>>2],f[(Y=on+8|0)>>2]=f[p>>2],f[Y+4>>2]=G,p=f[B+4>>2],f[on>>2]=f[B>>2],f[on+4>>2]=p,G=f[(p=W+8|0)+4>>2],f[(Y=an+8|0)>>2]=f[p>>2],f[Y+4>>2]=G,p=f[W+4>>2],f[an>>2]=f[W>>2],f[an+4>>2]=p,G=f[(p=Q+8|0)+4>>2],f[(Y=nn+8|0)>>2]=f[p>>2],f[Y+4>>2]=G,p=f[Q+4>>2],f[nn>>2]=f[Q>>2],f[nn+4>>2]=p,p=f[en+4>>2],f[(G=rn+8|0)>>2]=f[en>>2],f[G+4>>2]=p,p=f[o+252>>2],f[rn>>2]=f[o+248>>2],f[rn+4>>2]=p,G=f[(p=An+8|0)+4>>2],f[(Y=BA+8|0)>>2]=f[p>>2],f[Y+4>>2]=G,p=f[An+4>>2],f[BA>>2]=f[An>>2],f[BA+4>>2]=p,G=f[(p=Kt+8|0)+4>>2],f[(Y=Qt+8|0)>>2]=f[p>>2],f[Y+4>>2]=G,p=f[Kt+4>>2],f[Qt>>2]=f[Kt>>2],f[Qt+4>>2]=p,G=f[(p=Lt+8|0)+4>>2],f[(Y=Et+8|0)>>2]=f[p>>2],f[Y+4>>2]=G,p=f[Lt+4>>2],f[Et>>2]=f[Lt>>2],f[Et+4>>2]=p,f[o+244>>2]=h,n[o+240|0]=z,Sr(Dt,o+792|0,o+8|0,h),h=f[t+64>>2]),(0|(V=V+1|0))<(0|h););_[t+52|0]&&(t=f[a+4>>2],f[t+780>>2]&&((0|(e=f[t+772>>2]))==(0|(i=f[f[a+8>>2]+8>>2]))?se(t,e+4|0,f[f[a+12>>2]+8>>2]+4|0):se(t,f[f[a+12>>2]+8>>2]+4|0,i+4|0)))}Z=o+928|0},function(t,e,i,r,a){t|=0,e|=0,i|=0,r|=0,a|=0;var o=v(0),h=v(0),d=v(0),g=0,m=0,y=0,p=0,R=0,D=0,B=0,E=0,F=0;return Z=t=Z-608|0,o=v(C[e+116>>2]-C[e+52>>2]),h=v(o*o),o=v(C[e+120>>2]-C[e+56>>2]),h=v(h+v(o*o)),o=v(C[e+124>>2]-C[e+60>>2]),h=v(h+v(o*o)),o=C[e+276>>2],h>2]-C[i+52>>2]),d=v(o*o),o=v(C[i+120>>2]-C[i+56>>2]),d=v(d+v(o*o)),o=v(C[i+124>>2]-C[i+60>>2]),d=v(d+v(o*o)),o=C[i+276>>2],d>2],g=f[i+272>>2],DA(t+552|0),f[(r=a=t+580|0)>>2]=0,f[r+4>>2]=0,f[(p=t+576|0)>>2]=1065353216,f[(r=y=t+588|0)>>2]=0,f[r+4>>2]=0,f[(R=t+596|0)>>2]=0,f[t+568>>2]=1065353216,f[t+572>>2]=1065353216,f[t+556>>2]=8,f[t+552>>2]=9852,f[t+604>>2]=0,f[t+600>>2]=g,f[t+584>>2]=g,f[t+548>>2]=0,f[t+540>>2]=1566444395,f[t+544>>2]=0,f[t+376>>2]=15992,n[0|(D=t+348|0)]=0,f[t+324>>2]=953267991,r=Hr(t,m,t+552|0,t+16|0),B=e+4|0,E=e+68|0,g=i+4|0,m=i+68|0,h=v(1),zr(r,B,E,g,m,t+376|0)&&(o=C[t+540>>2],C[e+268>>2]>o&&(C[e+268>>2]=o),C[i+268>>2]>o&&(C[i+268>>2]=o),h=v(1),o>2],F=f[e+272>>2],DA(t+552|0),f[a>>2]=0,f[a+4>>2]=0,f[p>>2]=1065353216,f[y>>2]=0,f[y+4>>2]=0,f[R>>2]=0,f[t+568>>2]=1065353216,f[t+572>>2]=1065353216,f[t+556>>2]=8,f[t+552>>2]=9852,f[t+604>>2]=0,f[t+600>>2]=F,f[t+584>>2]=F,f[t+548>>2]=0,f[t+540>>2]=1566444395,f[t+544>>2]=0,f[t+376>>2]=15992,n[0|D]=0,f[t+324>>2]=953267991,zr(Hr(t,t+552|0,r,t+16|0),B,E,g,m,t+376|0)&&(o=C[t+540>>2],C[e+268>>2]>o&&(C[e+268>>2]=o),C[i+268>>2]>o&&(C[i+268>>2]=o),h>o&&(h=o)))),Z=t+608|0,v(h)},function(t,e){e|=0;var i=0,r=0,a=0,o=0,h=0;if(!(!(r=f[(t|=0)+56>>2])|!_[t+52|0])){if((0|(i=f[e+4>>2]))==f[e+8>>2]&&!((0|i)>=(0|(o=i?i<<1:1)))){if(o&&(h=dA(o<<2),i=f[e+4>>2]),(0|i)>=1)for(r=0,a=i;f[r+h>>2]=f[f[e+12>>2]+r>>2],r=r+4|0,a=a+-1|0;);(a=f[e+12>>2])&&(_[e+16|0]&&(CA(a),i=f[e+4>>2]),f[e+12>>2]=0),f[e+12>>2]=h,n[e+16|0]=1,f[e+8>>2]=o,r=f[t+56>>2]}f[e+4>>2]=i+1,f[f[e+12>>2]+(i<<2)>>2]=r}},ve,De,De,Kr,ve,De,De,function(t,e,i,r){t|=0,e|=0,i|=0,r=v(r);var a,o,_,h=0,d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0);Z=a=Z-16|0,C[t+32>>2]=r,h=f[e+4>>2],f[t+8>>2]=f[e>>2],f[t+12>>2]=h,_=f[(h=e+8|0)+4>>2],f[(o=t+16|0)>>2]=f[h>>2],f[o+4>>2]=_,g=C[h>>2],m=C[i>>2],y=C[e>>2],p=C[i+4>>2],R=C[e+4>>2],D=C[i+8>>2],d=C[t+28>>2],r=v(v(d+C[t+24>>2])+r),C[t+32>>2]=r,f[a+12>>2]=0,C[a+8>>2]=D-v(d*g),C[a+4>>2]=p-v(d*R),C[a>>2]=m-v(y*d),r>2],yt[f[f[t>>2]+16>>2]](t,e,a,r),Z=a+16|0},ve,function(t,e,i,r){t|=0,e|=0,i|=0,r=v(r);var n,a=v(0),o=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0),Gt=v(0);Z=n=Z-16|0,It=C[e+8>>2],pt=C[i+8>>2],y=v(v(It*r)+pt),St=C[e+4>>2],Dt=C[i+4>>2],Tt=v(v(St*r)+Dt),Et=C[e>>2],a=v(Et*r),r=C[i>>2],Ot=v(a+r),_[t+232|0]?(B=C[t+40>>2],p=v(-C[t+88>>2]),E=C[t+56>>2],m=C[t+92>>2],g=C[t+72>>2],a=C[t+96>>2],w=v(v(v(B*p)-v(E*m))-v(g*a)),o=C[t+200>>2],F=C[t+44>>2],V=C[t+60>>2],R=C[t+76>>2],Y=v(v(v(F*p)-v(V*m))-v(R*a)),h=C[t+204>>2],G=C[t+48>>2],d=v(G*p),p=C[t- -64>>2],d=v(d-v(p*m)),m=C[t+80>>2],Q=v(d-v(m*a)),a=C[t+208>>2],d=v(v(v(v(v(w*o)+v(Y*h))+v(Q*a))+C[t+224>>2])+v(v(y*v(v(v(g*o)+v(R*h))+v(m*a)))+v(v(Ot*v(v(v(B*o)+v(F*h))+v(G*a)))+v(Tt*v(v(v(E*o)+v(V*h))+v(p*a)))))),o=C[t+168>>2],h=C[t+172>>2],a=C[t+176>>2],o=v(v(v(y*v(v(v(g*o)+v(R*h))+v(m*a)))+v(v(Ot*v(v(v(B*o)+v(F*h))+v(G*a)))+v(Tt*v(v(v(E*o)+v(V*h))+v(p*a)))))+v(v(v(v(o*w)+v(Y*h))+v(Q*a))+C[t+216>>2])),h=v(Et*v(o-r)),a=y,r=C[t+184>>2],y=C[t+188>>2],R=v(v(g*r)+v(R*y)),g=C[t+192>>2],y=v(v(v(a*v(R+v(m*g)))+v(v(Ot*v(v(v(B*r)+v(F*y))+v(G*g)))+v(Tt*v(v(v(E*r)+v(V*y))+v(p*g)))))+v(v(v(v(w*r)+v(Y*y))+v(Q*g))+C[t+220>>2])),r=v(v(h+v(St*v(y-Dt)))+v(It*v(d-pt))),C[n+8>>2]=d+v(It*r),C[n+4>>2]=y+v(St*r),C[n>>2]=o+v(Et*r)):(Vt=C[t+224>>2],B=C[t+208>>2],E=C[t+200>>2],g=C[t+204>>2],Gt=C[t+216>>2],o=C[t+172>>2],F=C[t+176>>2],V=C[t+168>>2],R=C[t+104>>2],d=v(-C[t+152>>2]),h=C[t+120>>2],W=C[t+156>>2],G=C[t+136>>2],z=C[t+160>>2],p=v(v(v(R*d)-v(h*W))-v(G*z)),m=C[t+108>>2],a=C[t+124>>2],w=C[t+140>>2],Y=v(v(v(m*d)-v(a*W))-v(w*z)),Q=C[t+112>>2],D=v(Q*d),d=C[t+128>>2],D=v(D-v(d*W)),W=C[t+144>>2],z=v(D-v(W*z)),D=C[t+184>>2],Nt=C[t+188>>2],Ft=C[t+192>>2],D=v(v(v(pt*v(v(v(G*D)+v(w*Nt))+v(W*Ft)))+v(v(r*v(v(v(R*D)+v(m*Nt))+v(Q*Ft)))+v(Dt*v(v(v(h*D)+v(a*Nt))+v(d*Ft)))))+v(v(v(v(p*D)+v(Y*Nt))+v(z*Ft))+C[t+220>>2])),C[n+4>>2]=D,o=v(v(v(pt*v(v(v(G*V)+v(w*o))+v(W*F)))+v(v(r*v(v(v(R*V)+v(m*o))+v(Q*F)))+v(Dt*v(v(v(h*V)+v(a*o))+v(d*F)))))+v(Gt+v(v(v(V*p)+v(Y*o))+v(z*F)))),C[n>>2]=o,r=v(v(Vt+v(v(v(p*E)+v(Y*g))+v(z*B)))+v(v(pt*v(v(v(G*E)+v(w*g))+v(W*B)))+v(v(r*v(v(v(R*E)+v(m*g))+v(Q*B)))+v(Dt*v(v(v(h*E)+v(a*g))+v(d*B)))))),C[n+8>>2]=r,r=v(v(v(Et*v(Ot-o))+v(St*v(Tt-D)))+v(It*v(y-r)))),f[n+12>>2]=0,t=f[t+36>>2],yt[f[f[t>>2]+16>>2]](t,e,n,r),Z=n+16|0},WA,Rr,De,sA,ve,qe,function(){},ve,Ai,function(t){var e,i,r=0;return f[(t|=0)+8>>2]=16148,f[t>>2]=16120,e=f[(r=t+56|0)>>2],i=t+72|0,yt[f[f[e>>2]+20>>2]](e,f[i>>2]),r=f[r>>2],yt[f[f[r>>2]+16>>2]](r,f[i>>2]),0|t},function(t){var e,i,r=0;f[(t|=0)+8>>2]=16148,f[t>>2]=16120,e=f[(r=t+56|0)>>2],i=t+72|0,yt[f[f[e>>2]+20>>2]](e,f[i>>2]),r=f[r>>2],yt[f[f[r>>2]+16>>2]](r,f[i>>2]),CA(t)},function(t,e,i,r,n){t|=0,e|=0,i|=0,r|=0,n|=0;var a,o,h=0,d=0,g=v(0);Z=a=Z-16|0,Lr(a+8|0,16202),d=_[t+76|0],h=f[(o=d?e:i)+4>>2],f[h+4>>2]+-21>>>0>8||(f[f[(e=d?i:e)+4>>2]+4>>2]>19||(g=v(yt[f[f[h>>2]+48>>2]](h)),i=t+72|0,f[n+4>>2]=f[i>>2],function(t,e,i,r,n,a){var o,_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0);Z=o=Z+-64|0,C[t+56>>2]=e,f[t+52>>2]=i,f[t+40>>2]=n,f[t+36>>2]=r,f[t+44>>2]=a,i=f[n+12>>2],E=C[i+52>>2],F=C[i+56>>2],n=f[r+12>>2],V=C[n+52>>2],G=C[n+56>>2],_=C[i+20>>2],h=C[i+36>>2],w=C[n+20>>2],Q=C[n+36>>2],W=C[n+24>>2],d=C[i+24>>2],Y=C[n+40>>2],g=C[i+40>>2],z=C[n+32>>2],m=C[i+32>>2],pt=C[n>>2],y=C[i>>2],Dt=C[n+16>>2],p=C[i+16>>2],R=C[i+48>>2],It=C[n+48>>2],D=C[i+4>>2],St=C[n+4>>2],Tt=C[n+8>>2],B=C[i+8>>2],f[o+60>>2]=0,f[o+44>>2]=0,f[o+28>>2]=0,C[o+40>>2]=v(v(B*Tt)+v(d*W))+v(g*Y),C[o+36>>2]=v(v(B*St)+v(d*w))+v(g*Q),C[o+24>>2]=v(v(D*Tt)+v(_*W))+v(h*Y),C[o+20>>2]=v(v(D*St)+v(_*w))+v(h*Q),R=v(-R),C[o+56>>2]=v(v(v(B*R)-v(d*E))-v(g*F))+v(v(v(B*It)+v(d*V))+v(g*G)),C[o+52>>2]=v(v(v(D*R)-v(_*E))-v(h*F))+v(v(v(D*It)+v(_*V))+v(h*G)),f[o+12>>2]=0,C[o>>2]=v(v(y*pt)+v(p*Dt))+v(m*z),C[o+32>>2]=v(v(B*pt)+v(d*Dt))+v(g*z),C[o+16>>2]=v(v(D*pt)+v(_*Dt))+v(h*z),C[o+8>>2]=v(v(y*Tt)+v(p*W))+v(m*Y),C[o+4>>2]=v(v(y*St)+v(p*w))+v(m*Q),C[o+48>>2]=v(v(v(y*R)-v(p*E))-v(m*F))+v(v(v(y*It)+v(p*V))+v(m*G)),i=f[r+4>>2],yt[f[f[i>>2]+8>>2]](i,o,t+4|0,t+20|0),e=v(C[a+32>>2]+e),C[t+20>>2]=e+C[t+20>>2],C[(i=t+24|0)>>2]=e+C[i>>2],C[(i=t+28|0)>>2]=e+C[i>>2],C[t+4>>2]=C[t+4>>2]-e,C[(i=t+8|0)>>2]=C[i>>2]-e,C[(t=t+12|0)>>2]=C[t>>2]-e,Z=o- -64|0}(d=t+8|0,g,r,e,o,n),i=f[i>>2],f[i+776>>2]=f[o+8>>2],f[i+772>>2]=f[e+8>>2],yt[f[f[h>>2]+64>>2]](h,d,t+12|0,t+28|0),e=f[n+4>>2],f[e+780>>2]&&(i=(0|(r=f[e+772>>2]))==(0|(h=f[f[n+8>>2]+8>>2])),d=e,e=f[f[n+12>>2]+8>>2],se(d,(i?r:e)+4|0,(i?e:h)+4|0)),f[(t=t+44|0)>>2]=0,f[t+4>>2]=0)),qr(),Z=a+16|0},function(t,e,i,r,n){t|=0,e|=0,i|=0,r|=0,n|=0;var a=v(0),o=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0),Gt=v(0),Lt=v(0),wt=v(0),xt=v(0),Qt=v(0),Wt=v(0),Yt=v(0),Pt=v(0),Mt=v(0),Zt=v(0),Ut=v(0),Xt=v(0);return Z=r=Z-240|0,Ut=v(1),n=_[t+76|0],a=v(C[(t=n?i:e)+116>>2]-C[t+52>>2]),o=v(a*a),a=v(C[t+120>>2]-C[t+56>>2]),o=v(o+v(a*a)),a=v(C[t+124>>2]-C[t+60>>2]),o=v(o+v(a*a)),a=C[t+276>>2],o>2],f[i+4>>2]+-21>>>0>8||(It=C[t+92>>2],St=C[t+76>>2],Tt=C[t+108>>2],Et=C[t+88>>2],Ot=C[t+72>>2],Nt=C[t+104>>2],Ft=C[t+100>>2],Vt=C[t+84>>2],Gt=C[t+68>>2],y=C[e+36>>2],p=C[e+20>>2],R=C[e+4>>2],Lt=C[t+28>>2],wt=C[t+12>>2],xt=C[t+44>>2],Qt=C[t+24>>2],Wt=C[t+8>>2],Yt=C[t+40>>2],Pt=C[t+36>>2],Mt=C[t+20>>2],Zt=C[t+4>>2],D=C[e+12>>2],Q=C[t+116>>2],B=C[e+28>>2],o=C[t+120>>2],E=C[e+44>>2],W=C[t+124>>2],Xt=v(v(v(D*Q)+v(B*o))+v(E*W)),F=C[e+8>>2],Y=v(-C[e+52>>2]),V=C[e+24>>2],G=C[e+56>>2],w=C[e+40>>2],z=C[e+60>>2],m=v(v(v(F*Y)-v(V*G))-v(w*z)),a=v(m+v(v(v(F*Q)+v(V*o))+v(w*W))),h=C[t+56>>2],d=C[t+52>>2],g=C[t+60>>2],f[r+236>>2]=0,Dt=v(v(v(D*Y)-v(B*G))-v(E*z)),pt=v(Dt+v(v(v(D*d)+v(B*h))+v(E*g))),C[r+232>>2]=pt,m=v(m+v(v(v(F*d)+v(V*h))+v(w*g))),C[r+228>>2]=m,G=v(v(v(R*Y)-v(p*G))-v(y*z)),g=v(G+v(v(v(R*d)+v(p*h))+v(y*g))),C[r+224>>2]=g,Y=g,(h=v(G+v(v(v(R*Q)+v(p*o))+v(y*W))))>2]=h,Y=h),Q=m,a>2]=a,Q=a),(d=v(Dt+Xt))<(o=pt)&&(C[r+232>>2]=d,o=d),f[r+220>>2]=0,C[r+216>>2]=pt,C[r+212>>2]=m,C[r+208>>2]=g,W=g,g>2]=h,W=h),G=m,m>2]=a,G=a),z=pt,pt>2]=d,z=d),Dt=o,o=C[t+272>>2],C[r+232>>2]=Dt-o,C[r+228>>2]=Q-o,C[r+224>>2]=Y-o,C[r+216>>2]=o+z,C[r+212>>2]=o+G,C[r+208>>2]=o+W,f[r+128>>2]=0,C[r+124>>2]=d,C[r+120>>2]=a,C[r+116>>2]=h,f[r+112>>2]=0,C[r+108>>2]=v(v(D*St)+v(B*It))+v(E*Tt),C[r+104>>2]=v(v(D*Ot)+v(B*Et))+v(E*Nt),C[r+100>>2]=v(v(D*Gt)+v(B*Vt))+v(E*Ft),f[r+96>>2]=0,C[r+92>>2]=v(v(F*St)+v(V*It))+v(w*Tt),C[r+88>>2]=v(v(F*Ot)+v(V*Et))+v(w*Nt),C[r+84>>2]=v(v(F*Gt)+v(V*Vt))+v(w*Ft),f[r+80>>2]=0,C[r+76>>2]=v(v(R*St)+v(p*It))+v(y*Tt),C[r+72>>2]=v(v(R*Ot)+v(p*Et))+v(y*Nt),f[r- -64>>2]=0,C[r+60>>2]=pt,C[r+56>>2]=m,C[r+52>>2]=g,f[r+48>>2]=0,C[r+44>>2]=v(v(D*wt)+v(B*Lt))+v(E*xt),C[r+40>>2]=v(v(D*Wt)+v(B*Qt))+v(E*Yt),C[r+36>>2]=v(v(D*Zt)+v(B*Mt))+v(E*Pt),f[r+32>>2]=0,C[r+28>>2]=v(v(F*wt)+v(V*Lt))+v(w*xt),C[r+24>>2]=v(v(F*Wt)+v(V*Qt))+v(w*Yt),C[r+20>>2]=v(v(F*Zt)+v(V*Mt))+v(w*Pt),f[r+16>>2]=0,C[r+12>>2]=v(v(R*wt)+v(p*Lt))+v(y*xt),C[r+8>>2]=v(v(R*Wt)+v(p*Qt))+v(y*Yt),C[r+196>>2]=o,C[r+68>>2]=v(v(R*Gt)+v(p*Vt))+v(y*Ft),C[r+4>>2]=v(v(R*Zt)+v(p*Mt))+v(y*Pt),f[r>>2]=16488,f[r+200>>2]=f[t+268>>2],i&&(yt[f[f[i>>2]+64>>2]](i,r,r+224|0,r+208|0),(a=C[r+200>>2])>2]&&(C[t+268>>2]=a,Ut=a)))),Z=r+240|0,v(Ut)},function(t,e){e|=0;var i=0,r=0,a=0,o=0,h=0;if(r=f[(t|=0)+72>>2]){if((0|(i=f[e+4>>2]))==f[e+8>>2]&&!((0|i)>=(0|(o=i?i<<1:1)))){if(o&&(h=dA(o<<2),i=f[e+4>>2]),(0|i)>=1)for(r=0,a=i;f[r+h>>2]=f[f[e+12>>2]+r>>2],r=r+4|0,a=a+-1|0;);(a=f[e+12>>2])&&(_[e+16|0]&&(CA(a),i=f[e+4>>2]),f[e+12>>2]=0),f[e+12>>2]=h,n[e+16|0]=1,f[e+8>>2]=o,r=f[t+72>>2]}f[e+4>>2]=i+1,f[f[e+12>>2]+(i<<2)>>2]=r}},function(t){var e=0;return f[(t|=0)>>2]=16148,e=f[t+48>>2],yt[f[f[e>>2]+20>>2]](e,f[t+64>>2]),e=f[t+48>>2],yt[f[f[e>>2]+16>>2]](e,f[t+64>>2]),0|t},function(t){var e=0;f[(t|=0)>>2]=16148,e=f[t+48>>2],yt[f[f[e>>2]+20>>2]](e,f[t+64>>2]),e=f[t+48>>2],yt[f[f[e>>2]+16>>2]](e,f[t+64>>2]),CA(t)},function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n,a=0,o=0,_=v(0),h=0,d=v(0),g=v(0),m=v(0),y=0,p=0;Z=n=Z-144|0,Lr(n+136|0,16160),((m=(_=C[e>>2])<(d=C[e+16>>2])?_:d)<(g=C[e+32>>2])?m:g)>C[t+20>>2]||(C[(C[e+(a=(_>d^1)<<4)>>2]>g?a:32)+e>>2]>2]||(((m=(_=C[e+8>>2])<(d=C[(a=e+24|0)>>2])?_:d)<(g=C[(h=e+40|0)>>2])?m:g)>C[t+28>>2]||(C[(C[(a=_>d?e+8|0:a)>>2]>g?a:h)>>2]>2]||(((m=(_=C[e+4>>2])<(d=C[(a=e+20|0)>>2])?_:d)<(g=C[(h=e+36|0)>>2])?m:g)>C[t+24>>2]||(a=_>d?e+4|0:a,f[f[f[t+36>>2]+4>>2]+4>>2]>19|C[(C[a>>2]>g?a:h)>>2]>2]||(h=f[t+48>>2],p=zA(n+24|0),y=f[(o=e+8|0)+4>>2],f[(a=n+92|0)>>2]=f[o>>2],f[a+4>>2]=y,o=f[e+20>>2],f[(a=n+100|0)>>2]=f[e+16>>2],f[a+4>>2]=o,y=f[(o=e+24|0)+4>>2],f[(a=n+108|0)>>2]=f[o>>2],f[a+4>>2]=y,o=f[e+36>>2],f[(a=n+116|0)>>2]=f[e+32>>2],f[a+4>>2]=o,y=f[(o=e+40|0)+4>>2],f[(a=n+124|0)>>2]=f[o>>2],f[a+4>>2]=y,f[n+24>>2]=16352,a=f[e+4>>2],f[n+84>>2]=f[e>>2],f[n+88>>2]=a,f[n+72>>2]=f[t+56>>2],f[n+28>>2]=1,f[n+20>>2]=r,f[n+16>>2]=i,e=f[t+40>>2],f[n>>2]=e,a=f[e+8>>2],f[n+12>>2]=f[e+12>>2],f[n+8>>2]=a,_=C[f[t+44>>2]+32>>2],f[n+4>>2]=n+24,e=f[t+36>>2],e=_>v(0)?0|yt[f[f[h>>2]+8>>2]](h,e,n,0,2):0|yt[f[f[h>>2]+8>>2]](h,e,n,f[t+64>>2],1),a=f[t+44>>2],o=f[a+8>>2],f[o+8>>2]!=f[f[t+40>>2]+8>>2]?(o=f[a+12>>2],f[a+12>>2]=n,yt[f[f[a>>2]+12>>2]](a,i,r)):(f[a+8>>2]=n,yt[f[f[a>>2]+8>>2]](a,i,r)),yt[f[f[e>>2]+8>>2]](e,f[t+36>>2],n,f[t+52>>2],f[t+44>>2]),i=f[t+44>>2],f[(f[f[i+8>>2]+8>>2]==f[f[t+40>>2]+8>>2]?8:12)+i>>2]=o,yt[f[f[e>>2]>>2]](e),yt[f[f[h>>2]+60>>2]](h,e),Ae(p))))))),qr(),Z=n+144|0},ce,$A,ve,function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var a=0,o=0,_=0,h=v(0);Z=i=Z-800|0,Lr(i+792|0,16672),f[(r=i+740|0)>>2]=0,f[r+4>>2]=0,f[(r=i+752|0)>>2]=0,f[r+4>>2]=0,f[i+748>>2]=1065353216,f[(r=i+772|0)>>2]=0,f[r+4>>2]=0,f[i+768>>2]=1065353216,f[(r=i+780|0)>>2]=0,f[r+4>>2]=0,f[i+788>>2]=0,f[i+732>>2]=0,f[i+736>>2]=0,f[i+728>>2]=1065353216,f[i+760>>2]=0,f[i+764>>2]=0,f[i+720>>2]=0,f[i+724>>2]=0,f[i+552>>2]=15992,f[i+716>>2]=f[t+200>>2],r=f[t+196>>2],DA(i+496|0),f[(a=i+524|0)>>2]=0,f[a+4>>2]=0,f[i+520>>2]=1065353216,f[(a=i+532|0)>>2]=0,f[a+4>>2]=0,f[i+540>>2]=0,f[i+512>>2]=1065353216,f[i+516>>2]=1065353216,f[i+496>>2]=9852,f[i+548>>2]=0,f[i+544>>2]=r,f[i+528>>2]=r,f[i+500>>2]=8,r=zA(i+384|0),o=f[(a=e+8|0)+4>>2],f[(_=i+452|0)>>2]=f[a>>2],f[_+4>>2]=o,a=f[e+20>>2],f[(o=i+460|0)>>2]=f[e+16>>2],f[o+4>>2]=a,o=f[(a=e+24|0)+4>>2],f[(_=i+468|0)>>2]=f[a>>2],f[_+4>>2]=o,a=f[e+36>>2],f[(o=i+476|0)>>2]=f[e+32>>2],f[o+4>>2]=a,o=f[(a=e+40|0)+4>>2],f[(_=i+484|0)>>2]=f[a>>2],f[_+4>>2]=o,f[i+388>>2]=1,f[i+384>>2]=16352,a=f[e+4>>2],f[i+444>>2]=f[e>>2],f[i+448>>2]=a,n[i+356|0]=0,f[i+332>>2]=953267991,Ai($r(i+8|0,i+496|0,i+384|0,i+24|0),t+4|0,t+68|0,i+728|0,i+728|0,i+552|0)&&(h=C[i+716>>2],C[t+200>>2]>h&&(C[t+200>>2]=h)),Ae(r),qr(),Z=i+800|0},fi,function(t){$(fi(t|=0))},ti,function(t,e,i,r,n){t|=0,e|=0,i|=0,r|=0,n|=0;var a,o,h,d,g,m,y=0,p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=0,Y=v(0),Z=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0),Gt=v(0),Lt=v(0),wt=0;if((0|(W=f[t+52>>2]))<1)return v(v(1));for(a=(y=_[t+68|0])?e:i,o=f[(e=y?i:e)- -64>>2],Vt=C[e+60>>2],Gt=C[e+56>>2],Lt=C[e+52>>2],h=f[e+48>>2],R=C[e+44>>2],D=C[e+40>>2],B=C[e+36>>2],y=32,d=f[e+32>>2],E=C[e+28>>2],F=C[e+24>>2],V=C[e+20>>2],g=f[e+16>>2],G=C[e+12>>2],w=C[e+8>>2],i=f[e+304>>2],Q=C[e+4>>2],m=f[e+192>>2],Y=v(1);f[e+304>>2]=i+1,i=f[m+28>>2]+y|0,p=C[i+24>>2],Z=C[i+16>>2],z=C[i+20>>2],pt=C[i>>2],Dt=C[i+-32>>2],It=C[i+-16>>2],St=C[i+4>>2],Tt=C[i+-28>>2],Et=C[i+-12>>2],Ot=C[i+8>>2],Nt=C[i+-24>>2],Ft=C[i+-8>>2],f[e+64>>2]=0,f[e+48>>2]=0,f[e+32>>2]=0,f[e+16>>2]=0,C[e+44>>2]=v(v(B*Nt)+v(D*Ft))+v(R*Ot),C[e+40>>2]=v(v(B*Tt)+v(D*Et))+v(R*St),C[e+36>>2]=v(v(B*Dt)+v(D*It))+v(R*pt),C[e+28>>2]=v(v(V*Nt)+v(F*Ft))+v(E*Ot),C[e+24>>2]=v(v(V*Tt)+v(F*Et))+v(E*St),C[e+20>>2]=v(v(V*Dt)+v(F*It))+v(E*pt),C[e+12>>2]=v(v(Q*Nt)+v(w*Ft))+v(G*Ot),C[e+8>>2]=v(v(Q*Tt)+v(w*Et))+v(G*St),C[e+4>>2]=v(v(Q*Dt)+v(w*It))+v(G*pt),C[e+60>>2]=Vt+v(v(v(B*Z)+v(D*z))+v(R*p)),C[e+56>>2]=Gt+v(v(v(V*Z)+v(F*z))+v(E*p)),C[e+52>>2]=Lt+v(v(v(Q*Z)+v(w*z))+v(G*p)),i=f[f[t+60>>2]+wt>>2],p=v(yt[f[f[i>>2]+12>>2]](i,e,a,r,n)),f[e+64>>2]=o,C[e+60>>2]=Vt,C[e+56>>2]=Gt,C[e+52>>2]=Lt,f[e+48>>2]=h,C[e+44>>2]=R,C[e+40>>2]=D,C[e+36>>2]=B,f[e+32>>2]=d,C[e+28>>2]=E,C[e+24>>2]=F,C[e+20>>2]=V,f[e+16>>2]=g,C[e+12>>2]=G,C[e+8>>2]=w,C[e+4>>2]=Q,i=f[e+304>>2]+1|0,f[e+304>>2]=i,Y=p>2]))>=1)for(;(r=f[f[t+60>>2]+n>>2])&&(yt[f[f[r>>2]+16>>2]](r,e),i=f[t+52>>2]),n=n+4|0,(0|(a=a+1|0))<(0|i););},sA,ve,De,function(t,e){var i,r;e|=0,i=t|=0,r=f[f[f[t+4>>2]+4>>2]+28>>2],t=f[e+36>>2],ni(i,f[64+(r+m(t,80)|0)>>2],t)},function(t,e,i){t|=0,e|=0,i=v(i),yt[f[f[t>>2]+12>>2]](t,e)},lr,lr,function(t){var e=0;return f[(t|=0)>>2]=16844,(e=f[t+56>>2])&&(_[t+60|0]&&CA(e),f[t+56>>2]=0),f[t+56>>2]=0,f[t+48>>2]=0,f[t+52>>2]=0,n[t+60|0]=1,(e=f[t+36>>2])&&(_[t+40|0]&&CA(e),f[t+36>>2]=0),f[t+36>>2]=0,f[t+28>>2]=0,f[t+32>>2]=0,n[t+40|0]=1,(e=f[t+16>>2])&&(_[t+20|0]&&CA(e),f[t+16>>2]=0),f[t+16>>2]=0,f[t+8>>2]=0,f[t+12>>2]=0,n[t+20|0]=1,0|t},function(t){var e=0;f[(t|=0)>>2]=16844,(e=f[t+56>>2])&&(_[t+60|0]&&CA(e),f[t+56>>2]=0),f[t+56>>2]=0,f[t+48>>2]=0,f[t+52>>2]=0,n[t+60|0]=1,(e=f[t+36>>2])&&(_[t+40|0]&&CA(e),f[t+36>>2]=0),f[t+36>>2]=0,f[t+28>>2]=0,f[t+32>>2]=0,n[t+40|0]=1,!(e=f[t+16>>2])|!_[t+20|0]||CA(e),$(t)},function(t,e,i){t|=0,e|=0,i|=0;var r=0,n=0,a=0,o=0,_=0,h=0,d=0,C=0;f[690]=f[690]+1,h=f[t+36>>2],r=m((r=((r=i<<16|e)<<15^-1)+r|0)>>>10^r,9),r=((r^=r>>>6)<<11^-1)+r|0,d=h+((f[t+12>>2]+-1&(r>>>16^r))<<2)|0;t:if(-1!=(0|(r=f[d>>2]))){for(a=f[t+16>>2],n=r;;){if(_=a+m(n,12)|0,f[_+4>>2]!=(0|i)||(0|e)!=f[_>>2]){if(-1!=(0|(n=f[f[t+56>>2]+(n<<2)>>2])))continue;break t}break}if(_){e=m(n,12),C=f[8+(e+a|0)>>2],n=f[t+56>>2];e:{i:{if((0|r)!=(0|(o=(0|e)/12|0))){for(;(0|o)!=(0|(r=f[n+((e=r)<<2)>>2])););if(i=r=f[n+(o<<2)>>2],-1==(0|e))break i;f[n+(e<<2)>>2]=r;break e}i=f[n+(o<<2)>>2]}f[d>>2]=i}if((0|o)==(0|(r=f[t+8>>2]+-1|0)))return f[t+8>>2]=o,0|C;e:{if(a=a+m(r,12)|0,e=f[a+4>>2]<<16|f[a>>2],e=m((e=(e<<15^-1)+e|0)>>>10^e,9),e=((e^=e>>>6)<<11^-1)+e|0,d=f[t+12>>2]+-1&(e>>>16^e),(0|(e=f[(h=h+(d<<2)|0)>>2]))!=(0|r)){for(;i=e,(0|r)!=(0|(e=f[n+(e<<2)>>2])););if(e=f[n+(r<<2)>>2],-1!=(0|i)){f[n+(i<<2)>>2]=e;break e}}else e=f[n+(r<<2)>>2];f[h>>2]=e}e=f[a+4>>2],f[_>>2]=f[a>>2],f[_+4>>2]=e,f[_+8>>2]=f[a+8>>2],e=f[t+36>>2]+(d<<2)|0,f[f[t+56>>2]+(o<<2)>>2]=f[e>>2],f[e>>2]=o,f[t+8>>2]=f[t+8>>2]+-1}}return 0|C},function(t,e,i){return t|=0,e|=0,i|=0,f[691]=f[691]+1,0|function(t,e,i){var r,a=0,o=0,h=0,d=0,C=0,g=0,v=0,y=0,p=0,R=0;a=m((a=((a=i<<16|e)<<15^-1)+a|0)>>>10^a,9),y=(r=(a=((a^=a>>>6)<<11^-1)+a|0)>>>16^a)&(a=f[t+12>>2])+-1;t:{e:if(-1!=(0|(o=f[f[t+36>>2]+(y<<2)>>2]))){for(p=f[t+16>>2];;){if(h=p+m(o,12)|0,f[h+4>>2]!=(0|i)||(0|e)!=f[h>>2]){if(-1!=(0|(o=f[f[t+56>>2]+(o<<2)>>2])))continue;break e}break}if(h)break t}e:{i:{if(g=t,(0|a)==(0|(o=d=f[t+8>>2]))){if(!(R=(0|a)>=(0|(v=a?a<<1:1))))break i;o=a}f[g+8>>2]=o+1,h=(C=f[t+16>>2])+m(d,12)|0;break e}if(v&&(C=dA(m(v,12)),a=f[t+8>>2]),(0|a)>=1)for(o=0;h=f[t+16>>2]+o|0,p=f[h+4>>2],f[(g=o+C|0)>>2]=f[h>>2],f[g+4>>2]=p,f[g+8>>2]=f[h+8>>2],o=o+12|0,a=a+-1|0;);(a=f[t+16>>2])&&(_[t+20|0]&&CA(a),f[t+16>>2]=0),f[t+16>>2]=C,f[t+12>>2]=v,n[t+20|0]=1,f[t+8>>2]=f[t+8>>2]+1,h=m(d,12)+C|0,R||(ai(t),y=f[t+12>>2]+-1&r)}f[h>>2]=e,e=m(d,12)+C|0,f[e+8>>2]=0,f[e+4>>2]=i,e=f[t+56>>2]+(d<<2)|0,t=f[t+36>>2]+(y<<2)|0,f[e>>2]=f[t>>2],f[t>>2]=d}return h}(t,e,i)},ci,li,function(t){$(li(t|=0))},function(t,e,i,r,a){t|=0,e|=0,i|=0,r|=0,a|=0;var o,h,d=0,g=0,p=0,R=0,D=v(0),B=0,E=v(0),F=v(0),V=v(0),G=v(0),w=0,Q=v(0),W=v(0),Y=v(0),z=0,pt=0,Dt=v(0),It=v(0),St=v(0),Tt=0,Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0),Gt=v(0),Lt=v(0),wt=v(0),xt=v(0),Qt=v(0),Wt=0,Yt=v(0),Pt=v(0),Mt=0,Zt=v(0),Ut=0,Xt=0,Jt=v(0),jt=v(0),zt=v(0),Ht=v(0),Kt=v(0),qt=v(0),$t=v(0),bi=v(0),di=v(0),yi=v(0);if(Z=o=Z-3328|0,h=f[e+4>>2],(pt=f[h+68>>2])&&(Xt=f[i+4>>2],Wt=f[Xt+68>>2])){if(f[Xt+72>>2]!=f[t+112>>2]||f[h+72>>2]!=f[t+108>>2]){if(g=8,d=f[t+84>>2],(0|(p=f[d+8>>2]))>=1){for(;(w=f[f[d+16>>2]+g>>2])&&(yt[f[f[w>>2]>>2]](w),B=f[t+4>>2],yt[f[f[B>>2]+60>>2]](B,w)),g=g+12|0,p=p+-1|0;);d=f[t+84>>2]}oi(d),f[t+108>>2]=f[h+72>>2],f[t+112>>2]=f[Xt+72>>2]}f[o+84>>2]=0,n[o+88|0]=1,f[o+76>>2]=0,f[o+80>>2]=0,be(o+112|0),be(o+916|0),be(o+1720|0),be(o+2524|0),(d=f[o+84>>2])&&(_[o+88|0]&&CA(d),f[o+84>>2]=0),f[o+76>>2]=0,f[o+80>>2]=4,w=f[t+84>>2],n[o+88|0]=0,R=f[w+8>>2],f[o+84>>2]=o+112;t:{if((0|R)<=0)g=o+112|0;else{for(B=0;;){if(d=f[8+(f[w+16>>2]+m(B,12)|0)>>2]){if(yt[f[f[d>>2]+16>>2]](d,o+72|0),(0|(g=f[o+76>>2]))>=1)for(R=0,p=0;d=f[f[o+84>>2]+R>>2],f[d+780>>2]&&(f[a+4>>2]=d,g=(0|(Mt=f[d+772>>2]))==(0|(z=f[f[a+8>>2]+8>>2])),Ut=d,d=f[f[a+12>>2]+8>>2],se(Ut,(g?Mt:d)+4|0,(g?d:z)+4|0),f[a+4>>2]=0,g=f[o+76>>2]),R=R+4|0,(0|(p=p+1|0))<(0|g););if((0|g)<=-1)for(f[o+80>>2]<=-1&&((d=f[o+84>>2])&&(_[o+88|0]&&CA(d),f[o+84>>2]=0),n[o+88|0]=1,f[o+80>>2]=0,f[o+84>>2]=0),R=g<<2;f[f[o+84>>2]+R>>2]=0,R=R+4|0,p=(d=g+1|0)>>>0>=g>>>0,g=d,p;);f[o+76>>2]=0,R=f[w+8>>2]}if(!((0|(B=B+1|0))<(0|R)))break}if(!(g=f[o+84>>2]))break t}_[o+88|0]&&CA(g),f[o+84>>2]=0}if(f[o+92>>2]=r,f[o+76>>2]=0,f[o+72>>2]=16988,f[o+88>>2]=f[t+4>>2],f[o+104>>2]=f[t+72>>2],f[o+100>>2]=f[t+84>>2],f[o+84>>2]=i,r=f[i+12>>2],D=C[r+56>>2],f[o+80>>2]=e,d=f[e+12>>2],E=C[d+40>>2],Lt=C[r+52>>2],F=C[d+24>>2],Et=C[r+48>>2],W=C[d+8>>2],wt=C[d+56>>2],Ot=C[d+52>>2],Yt=C[d+48>>2],V=C[d+36>>2],G=C[d+20>>2],Y=C[d+4>>2],Nt=C[r+40>>2],xt=C[r+24>>2],Ft=C[r+8>>2],Qt=C[r+36>>2],It=C[r+20>>2],Vt=C[r+4>>2],Dt=C[d>>2],St=C[d+16>>2],Q=C[d+32>>2],Gt=C[r+16>>2],Pt=C[r>>2],Zt=C[r+32>>2],f[o+96>>2]=a,(r=f[pt>>2])&&(d=f[Wt>>2])){for(Yt=v(-Yt),Jt=v(v(v(v(W*Yt)-v(F*Ot))-v(E*wt))+v(v(v(W*Et)+v(F*Lt))+v(E*D))),qt=v(v(v(v(Y*Yt)-v(G*Ot))-v(V*wt))+v(v(v(Y*Et)+v(G*Lt))+v(V*D))),Lt=v(v(v(v(Dt*Yt)-v(St*Ot))-v(Q*wt))+v(v(v(Dt*Et)+v(St*Lt))+v(Q*D))),D=C[a+32>>2],f[o+116>>2]=d,f[o+112>>2]=r,Et=v(v(v(W*Ft)+v(F*xt))+v(E*Nt)),wt=v(y(Et)),Ot=v(v(v(W*Vt)+v(F*It))+v(E*Qt)),Yt=v(y(Ot)),jt=v(v(v(W*Pt)+v(F*Gt))+v(E*Zt)),$t=v(y(jt)),zt=v(v(v(Y*Ft)+v(G*xt))+v(V*Nt)),bi=v(y(zt)),Ht=v(v(v(Y*Vt)+v(G*It))+v(V*Qt)),di=v(y(Ht)),Kt=v(v(v(Y*Pt)+v(G*Gt))+v(V*Zt)),yi=v(y(Kt)),Nt=v(v(v(Dt*Ft)+v(St*xt))+v(Q*Nt)),xt=v(y(Nt)),Ft=v(v(v(Dt*Vt)+v(St*It))+v(Q*Qt)),Qt=v(y(Ft)),Dt=v(v(v(Dt*Pt)+v(St*Gt))+v(Q*Zt)),St=v(y(Dt)),Wt=124,p=0,B=128,d=o+112|0,r=128,R=1;;){t:{e:{i:{if(Tt=f[(g=(Ut=(Mt=R+-1|0)<<3)+d|0)>>2],z=f[g+4>>2],V=C[z+16>>2],G=C[z>>2],E=v(v(v(V-G)*v(.5))+v(0)),Y=C[z+20>>2],Q=C[z+4>>2],F=v(v(v(Y-Q)*v(.5))+v(0)),It=C[z+24>>2],Vt=C[z+8>>2],W=v(v(v(It-Vt)*v(.5))+v(0)),Gt=v(v(v(St*E)+v(Qt*F))+v(xt*W)),V=v(v(V+G)*v(.5)),G=v(v(Y+Q)*v(.5)),Y=v(v(It+Vt)*v(.5)),Q=v(Lt+v(v(v(Dt*V)+v(Ft*G))+v(Nt*Y))),!(C[Tt>>2]<=v(D+v(Gt+Q))^1|C[Tt+16>>2]>=v(v(Q-Gt)-D)^1||(Q=v(v(v(yi*E)+v(di*F))+v(bi*W)),It=v(qt+v(v(v(Kt*V)+v(Ht*G))+v(zt*Y))),C[Tt+4>>2]<=v(D+v(Q+It))^1|C[Tt+20>>2]>=v(v(It-Q)-D)^1||(E=v(v(v($t*E)+v(Yt*F))+v(wt*W)),F=v(Jt+v(v(v(jt*V)+v(Ot*G))+v(Et*Y))),C[Tt+8>>2]<=v(D+v(E+F))^1|C[Tt+24>>2]>=v(v(F-E)-D)^1)))){if((0|Mt)<=(0|Wt))w=B,g=d,pt=p;else{A:if((0|B)>=(0|(w=B<<1))|(0|r)>=(0|w))g=d,pt=p;else{r:{n:{a:{if(B){if(g=dA(B<<4),!((0|B)<1)){for(Wt=g,r=d;pt=f[r+4>>2],f[Wt>>2]=f[r>>2],f[Wt+4>>2]=pt,Wt=Wt+8|0,r=r+8|0,B=B+-1|0;);if(!(255&p))break n;break a}}else g=0;if(r=pt=1,!d)break r;if(r=w,!(255&p))break A}CA(d)}r=1}pt=r,r=w}Wt=w+-4|0}if(d=f[z+40>>2],f[Tt+40>>2]){if(p=f[Tt+36>>2],d){f[(d=g+Ut|0)+4>>2]=f[z+36>>2],f[d>>2]=p,p=f[Tt+40>>2],f[(d=(R<<3)+g|0)+4>>2]=f[z+36>>2],f[d>>2]=p,p=f[Tt+36>>2],f[d+12>>2]=f[z+40>>2],f[d+8>>2]=p,p=f[Tt+40>>2],f[d+20>>2]=f[z+40>>2],f[d+16>>2]=p,R=R+3|0;break e}f[(d=g+Ut|0)+4>>2]=z,f[d>>2]=p,d=f[Tt+40>>2],f[(p=(R<<3)+g|0)+4>>2]=z,f[p>>2]=d;break i}if(d){f[(d=g+Ut|0)+4>>2]=f[z+36>>2],f[d>>2]=Tt,f[(d=(R<<3)+g|0)+4>>2]=f[z+40>>2],f[d>>2]=Tt;break i}yt[f[f[o+72>>2]+8>>2]](o+72|0,Tt,z),B=w,d=g,p=pt}R=Mt;break t}R=R+1|0}B=w,d=g,p=pt}if(!R)break}!d|!(255&p)||CA(d)}if(w=f[t+84>>2],f[w+8>>2]>=1)for(d=0;;){if(r=(pt=m(d,12))+f[w+16>>2]|0,(p=f[r+8>>2])&&(r=f[h+28>>2]+m(f[r>>2],80)|0,B=f[r+64>>2],g=f[e+12>>2],Pt=C[g+52>>2],Zt=C[g+56>>2],Q=C[r+48>>2],Lt=C[r+52>>2],Et=C[r+56>>2],wt=C[r+4>>2],Ot=C[r+20>>2],Nt=C[r+36>>2],xt=C[r+8>>2],Ft=C[r+24>>2],Qt=C[r+40>>2],D=C[g+20>>2],E=C[g+24>>2],It=C[r>>2],F=C[g+36>>2],Vt=C[r+16>>2],W=C[g+40>>2],Gt=C[r+32>>2],Yt=C[g+48>>2],V=C[g+8>>2],G=C[g>>2],Y=C[g+4>>2],Dt=C[g+16>>2],St=C[g+32>>2],f[o+172>>2]=0,f[o+156>>2]=0,f[o+140>>2]=0,f[o+124>>2]=0,C[o+144>>2]=v(v(St*It)+v(F*Vt))+v(W*Gt),C[o+128>>2]=v(v(Dt*It)+v(D*Vt))+v(E*Gt),C[o+112>>2]=v(v(G*It)+v(Y*Vt))+v(V*Gt),C[o+152>>2]=v(v(St*xt)+v(F*Ft))+v(W*Qt),C[o+148>>2]=v(v(St*wt)+v(F*Ot))+v(W*Nt),C[o+136>>2]=v(v(Dt*xt)+v(D*Ft))+v(E*Qt),C[o+132>>2]=v(v(Dt*wt)+v(D*Ot))+v(E*Nt),C[o+120>>2]=v(v(G*xt)+v(Y*Ft))+v(V*Qt),C[o+116>>2]=v(v(G*wt)+v(Y*Ot))+v(V*Nt),C[o+168>>2]=Zt+v(v(v(St*Q)+v(F*Lt))+v(W*Et)),C[o+164>>2]=Pt+v(v(v(Dt*Q)+v(D*Lt))+v(E*Et)),C[o+160>>2]=Yt+v(v(v(G*Q)+v(Y*Lt))+v(V*Et)),yt[f[f[B>>2]+8>>2]](B,o+112|0,o+56|0,o+40|0),D=C[a+32>>2],C[o+56>>2]=C[o+56>>2]-D,C[o+60>>2]=C[o+60>>2]-D,C[o+64>>2]=C[o+64>>2]-D,C[o+40>>2]=D+C[o+40>>2],C[o+44>>2]=D+C[o+44>>2],C[o+48>>2]=D+C[o+48>>2],r=f[Xt+28>>2]+m(f[4+(pt+f[w+16>>2]|0)>>2],80)|0,B=f[r+64>>2],g=f[i+12>>2],Zt=C[g+52>>2],Yt=C[g+56>>2],Lt=C[r+48>>2],Et=C[r+52>>2],wt=C[r+56>>2],Ot=C[r+4>>2],Nt=C[r+20>>2],xt=C[r+36>>2],Ft=C[r+8>>2],Qt=C[r+24>>2],It=C[r+40>>2],E=C[g+20>>2],F=C[g+24>>2],Vt=C[r>>2],W=C[g+36>>2],Gt=C[r+16>>2],V=C[g+40>>2],Pt=C[r+32>>2],Jt=C[g+48>>2],G=C[g+8>>2],Y=C[g>>2],Dt=C[g+4>>2],St=C[g+16>>2],Q=C[g+32>>2],f[o+172>>2]=0,f[o+156>>2]=0,f[o+140>>2]=0,f[o+124>>2]=0,C[o+144>>2]=v(v(Q*Vt)+v(W*Gt))+v(V*Pt),C[o+128>>2]=v(v(St*Vt)+v(E*Gt))+v(F*Pt),C[o+112>>2]=v(v(Y*Vt)+v(Dt*Gt))+v(G*Pt),C[o+152>>2]=v(v(Q*Ft)+v(W*Qt))+v(V*It),C[o+148>>2]=v(v(Q*Ot)+v(W*Nt))+v(V*xt),C[o+136>>2]=v(v(St*Ft)+v(E*Qt))+v(F*It),C[o+132>>2]=v(v(St*Ot)+v(E*Nt))+v(F*xt),C[o+120>>2]=v(v(Y*Ft)+v(Dt*Qt))+v(G*It),C[o+116>>2]=v(v(Y*Ot)+v(Dt*Nt))+v(G*xt),C[o+168>>2]=Yt+v(v(v(Q*Lt)+v(W*Et))+v(V*wt)),C[o+164>>2]=Zt+v(v(v(St*Lt)+v(E*Et))+v(F*wt)),C[o+160>>2]=Jt+v(v(v(Y*Lt)+v(Dt*Et))+v(G*wt)),yt[f[f[B>>2]+8>>2]](B,o+112|0,o+24|0,o+8|0),E=v(C[o+24>>2]-D),C[o+24>>2]=E,F=v(C[o+28>>2]-D),C[o+28>>2]=F,W=v(C[o+32>>2]-D),C[o+32>>2]=W,V=v(D+C[o+8>>2]),C[o+8>>2]=V,G=v(D+C[o+16>>2]),C[o+16>>2]=G,D=v(D+C[o+12>>2]),C[o+12>>2]=D,C[o+44>>2]>2]>D|C[o+40>>2]>2]>V||C[o+64>>2]>G||C[o+48>>2]>2]>>2]](p),r=f[t+4>>2],yt[f[f[r>>2]+60>>2]](r,p),r=pt+f[w+16>>2]|0,Wt=f[r+4>>2],Mt=f[r>>2],(0|(R=f[t+92>>2]))==f[t+96>>2]&&!((0|R)>=(0|(r=R?R<<1:1)))){if(r?(B=dA(m(r,12)),R=f[t+92>>2]):B=0,(0|R)>=1)for(g=0;pt=f[t+100>>2]+g|0,z=f[pt+4>>2],f[(p=g+B|0)>>2]=f[pt>>2],f[p+4>>2]=z,f[p+8>>2]=f[pt+8>>2],g=g+12|0,R=R+-1|0;);(g=f[t+100>>2])&&(_[t+104|0]&&CA(g),f[t+100>>2]=0),f[t+100>>2]=B,n[t+104|0]=1,f[t+96>>2]=r,R=f[t+92>>2]}r=f[t+100>>2]+m(R,12)|0,f[r+8>>2]=0,f[r+4>>2]=Wt,f[r>>2]=Mt,f[t+92>>2]=f[t+92>>2]+1}if(!((0|(d=d+1|0))>2]))break}if(f[t+92>>2]>=1)for(R=0,g=4;e=f[t+84>>2],i=f[t+100>>2]+g|0,yt[f[f[e>>2]+8>>2]](e,f[i+-4>>2],f[i>>2]),g=g+12|0,(0|(R=R+1|0))>2];);(e=f[t+100>>2])&&(_[t+104|0]&&CA(e),f[t+100>>2]=0),f[t+100>>2]=0,f[t+92>>2]=0,f[t+96>>2]=0,n[t+104|0]=1}else ti(t,e,i,r,a);Z=o+3328|0},function(t,e,i,r,n){return v(v(0))},function(t,e){e|=0;var i=0,r=0,n=0,a=0;if(i=8,t=f[(t|=0)+84>>2],(0|(r=f[t+8>>2]))>=1)for(;(n=f[f[t+16>>2]+i>>2])&&(yt[f[f[n>>2]+16>>2]](n,e),r=f[t+8>>2]),i=i+12|0,(0|(a=a+1|0))<(0|r););},ve,function(t,e,i){t|=0,e|=0,i|=0;var r,n,a,o,_,h=v(0),d=v(0),g=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=0,Tt=0,Et=0,Ot=v(0),Nt=v(0),Ft=0,Vt=0;Z=r=Z-256|0,Lr(r+248|0,17064),f[t+4>>2]=f[t+4>>2]+1,n=f[i+36>>2],o=m(n,80),Et=f[t+12>>2],_=f[Et+4>>2]+28|0,St=f[64+(o+f[_>>2]|0)>>2],i=f[t+8>>2],a=f[e+36>>2],e=f[f[i+4>>2]+28>>2]+m(a,80)|0,Tt=f[e+64>>2],i=f[i+12>>2],V=C[i+52>>2],R=C[i+56>>2],y=C[i+24>>2],p=C[i+20>>2],h=C[i+40>>2],d=C[i+36>>2],Ot=C[i+48>>2],D=C[i+8>>2],B=C[i>>2],E=C[i+4>>2],F=C[i+16>>2],g=C[i+32>>2],i=0,f[r+244>>2]=0,f[r+228>>2]=0,f[r+212>>2]=0,G=C[e+8>>2],w=C[e+24>>2],Q=C[e+40>>2],C[r+224>>2]=v(v(g*G)+v(d*w))+v(h*Q),W=C[e+4>>2],Y=C[e+20>>2],z=C[e+36>>2],C[r+220>>2]=v(v(g*W)+v(d*Y))+v(h*z),C[r+208>>2]=v(v(F*G)+v(p*w))+v(y*Q),C[r+204>>2]=v(v(F*W)+v(p*Y))+v(y*z),pt=R,R=C[e+48>>2],Dt=C[e+52>>2],It=C[e+56>>2],C[r+240>>2]=pt+v(v(v(g*R)+v(d*Dt))+v(h*It)),C[r+236>>2]=V+v(v(v(F*R)+v(p*Dt))+v(y*It)),f[r+196>>2]=0,pt=g,g=C[e>>2],V=d,d=C[e+16>>2],Nt=h,h=C[e+32>>2],C[r+216>>2]=v(v(pt*g)+v(V*d))+v(Nt*h),C[r+200>>2]=v(v(F*g)+v(p*d))+v(y*h),C[r+192>>2]=v(v(B*G)+v(E*w))+v(D*Q),C[r+188>>2]=v(v(B*W)+v(E*Y))+v(D*z),C[r+184>>2]=v(v(B*g)+v(E*d))+v(D*h),C[r+232>>2]=Ot+v(v(v(B*R)+v(E*Dt))+v(D*It)),e=f[Et+12>>2],V=C[e+52>>2],R=C[e+56>>2],y=C[e+24>>2],p=C[e+20>>2],h=C[e+40>>2],d=C[e+36>>2],Et=f[_>>2],Ot=C[e+48>>2],D=C[e+8>>2],B=C[e>>2],E=C[e+4>>2],F=C[e+16>>2],g=C[e+32>>2],f[r+180>>2]=0,f[r+164>>2]=0,f[r+148>>2]=0,G=C[(e=Et+o|0)+8>>2],w=C[e+24>>2],Q=C[e+40>>2],C[r+160>>2]=v(v(g*G)+v(d*w))+v(h*Q),W=C[e+4>>2],Y=C[e+20>>2],z=C[e+36>>2],C[r+156>>2]=v(v(g*W)+v(d*Y))+v(h*z),C[r+144>>2]=v(v(F*G)+v(p*w))+v(y*Q),C[r+140>>2]=v(v(F*W)+v(p*Y))+v(y*z),pt=R,R=C[e+48>>2],Dt=C[e+52>>2],It=C[e+56>>2],C[r+176>>2]=pt+v(v(v(g*R)+v(d*Dt))+v(h*It)),C[r+172>>2]=V+v(v(v(F*R)+v(p*Dt))+v(y*It)),f[r+132>>2]=0,pt=g,g=C[e>>2],V=d,d=C[e+16>>2],Nt=h,h=C[e+32>>2],C[r+152>>2]=v(v(pt*g)+v(V*d))+v(Nt*h),C[r+136>>2]=v(v(F*g)+v(p*d))+v(y*h),C[r+128>>2]=v(v(B*G)+v(E*w))+v(D*Q),C[r+124>>2]=v(v(B*W)+v(E*Y))+v(D*z),C[r+120>>2]=v(v(B*g)+v(E*d))+v(D*h),C[r+168>>2]=Ot+v(v(v(B*R)+v(E*Dt))+v(D*It)),yt[f[f[Tt>>2]+8>>2]](Tt,r+184|0,r+104|0,r+88|0),yt[f[f[St>>2]+8>>2]](St,r+120|0,r+72|0,r+56|0),y=C[f[t+24>>2]+32>>2],p=v(C[r+104>>2]-y),C[r+104>>2]=p,C[r+108>>2]=C[r+108>>2]-y,C[r+112>>2]=C[r+112>>2]-y,C[r+88>>2]=y+C[r+88>>2],C[r+92>>2]=y+C[r+92>>2],C[r+96>>2]=y+C[r+96>>2];t:{if(e=f[693]){if(!yt[e](Tt,St))break t;p=C[r+104>>2]}p>C[r+56>>2]|C[r+88>>2]>2]||(i=1),e=0,e=C[r+96>>2]>2]|C[r+112>>2]>C[r+64>>2]?e:i,C[r+92>>2]>2]|C[r+108>>2]>C[r+60>>2]|1^e||(f[r+48>>2]=-1,f[r+36>>2]=Tt,e=f[t+8>>2],f[r+32>>2]=e,f[r+40>>2]=f[e+8>>2],f[r+44>>2]=r+184,f[r+52>>2]=a,f[r+24>>2]=-1,f[r+12>>2]=St,e=f[t+12>>2],f[r+8>>2]=e,f[r+16>>2]=f[e+8>>2],f[r+20>>2]=r+120,f[r+28>>2]=n,e=function(t,e,i){var r=0,n=0,a=0;f[692]=f[692]+1,r=m((r=((r=i<<16|e)<<15^-1)+r|0)>>>10^r,9),r=((r^=r>>>6)<<11^-1)+r|0;e:{if(!((0|(r=f[t+12>>2]+-1&(r>>>16^r)))>=f[t+28>>2])&&-1!=(0|(r=f[f[t+36>>2]+(r<<2)>>2])))for(a=f[t+16>>2];;){if(n=m(r,12)+a|0,f[n+4>>2]==(0|i)&&(0|e)==f[n>>2])break e;if(-1==(0|(r=f[f[t+56>>2]+(r<<2)>>2])))break}n=0}return n}(f[t+28>>2],a,n),C[f[t+24>>2]+32>>2]>v(0)?(e=f[t+16>>2],i=0|yt[f[f[e>>2]+8>>2]](e,r+32|0,r+8|0,0,2)):e?i=f[e+8>>2]:(e=f[t+16>>2],i=0|yt[f[f[e>>2]+8>>2]](e,r+32|0,r+8|0,f[t+32>>2],1),e=f[t+28>>2],Ft=0|yt[f[f[e>>2]+12>>2]](e,a,n),Vt=i,f[Ft+8>>2]=Vt),e=f[t+24>>2],St=f[e+12>>2],Tt=f[e+8>>2],f[e+12>>2]=r+8,f[e+8>>2]=r+32,yt[f[f[e>>2]+8>>2]](e,-1,a),e=f[t+24>>2],yt[f[f[e>>2]+12>>2]](e,-1,n),yt[f[f[i>>2]+8>>2]](i,r+32|0,r+8|0,f[t+20>>2],f[t+24>>2]),t=f[t+24>>2],f[t+8>>2]=Tt,f[t+12>>2]=St)}qr(),Z=r+256|0},Rr,ve,Ar,Re,Rr,function(t){var e=0,i=0;return f[(t|=0)>>2]=17172,_[t+8|0]&&((e=f[t+12>>2])&&(i=f[t+4>>2],yt[f[f[i>>2]+16>>2]](i,e))),0|t},function(t){var e=0,i=0;f[(t|=0)>>2]=17172,_[t+8|0]&&((e=f[t+12>>2])&&(i=f[t+4>>2],yt[f[f[i>>2]+16>>2]](i,e))),$(t)},function(t,e,i,r,n){t|=0,e|=0,i|=0,r|=0,n|=0;var a=v(0),o=0,_=v(0),h=0,d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0);if(Z=r=Z-32|0,t=f[t+12>>2]){if(f[n+4>>2]=t,o=f[e+12>>2],h=f[i+12>>2],y=v(C[o+48>>2]-C[h+48>>2]),d=v(C[o+52>>2]-C[h+52>>2]),g=v(C[o+56>>2]-C[h+56>>2]),a=v(v(v(y*y)+v(d*d))+v(g*g)),o=f[i+4>>2],m=C[o+16>>2],_=C[o+32>>2],e=f[e+4>>2],p=C[e+16>>2],R=C[e+32>>2],(0|(o=f[t+780>>2]))>=1)for(e=t+4|0,h=0;le(e),e=e+192|0,(0|(h=h+1|0))<(0|(o=f[t+780>>2])););a=v(E(a)),m=v(_*m),_=v(R*p),o&&((e=f[424])&&(f[r+16>>2]=t,yt[e](r+16|0))),f[t+780>>2]=0,_=v(_+m),a>v(_+C[n+32>>2])||(f[r+24>>2]=0,f[r+28>>2]=0,f[r+16>>2]=1065353216,f[r+20>>2]=0,_=v(a-_),a>v(1.1920928955078125e-7)?(f[r+28>>2]=0,a=v(v(1)/a),g=v(g*a),C[r+24>>2]=g,d=v(d*a),C[r+20>>2]=d,a=v(y*a),C[r+16>>2]=a):(a=v(1),g=v(0),d=v(0)),f[r+12>>2]=0,t=f[i+12>>2],C[r>>2]=v(m*a)+C[t+48>>2],C[r+8>>2]=v(m*g)+C[t+56>>2],C[r+4>>2]=v(m*d)+C[t+52>>2],yt[f[f[n>>2]+16>>2]](n,r+16|0,r,_))}Z=r+32|0},Re,ui,ve,si,function(t){var e=0,i=0;return f[(t|=0)>>2]=17308,_[t+8|0]&&((e=f[t+12>>2])&&(i=f[t+4>>2],yt[f[f[i>>2]+16>>2]](i,e))),0|t},function(t){var e=0,i=0;f[(t|=0)>>2]=17308,_[t+8|0]&&((e=f[t+12>>2])&&(i=f[t+4>>2],yt[f[f[i>>2]+16>>2]](i,e))),$(t)},function(t,e,i,r,n){e|=0,i|=0,r|=0,n|=0;var a,o=0,h=0,d=0,g=0,m=0,v=0,y=0,p=0,R=0,D=0;Z=a=Z-160|0,(m=f[(t|=0)+12>>2])&&(f[n+4>>2]=m,o=_[t+16|0],y=f[(h=o?i:e)+4>>2],i=f[(o=o?e:i)+4>>2],C[(e=a+144|0)+12>>2]=C[m+784>>2]+C[n+32>>2],f[e+8>>2]=i,f[e+4>>2]=y,f[e>>2]=17248,m=e,f[a+136>>2]=1566444395,e=f[h+12>>2],h=f[e>>2],y=f[e+4>>2],p=f[(i=e+8|0)>>2],i=f[i+4>>2],v=f[(d=e+24|0)+4>>2],f[(g=a+32|0)>>2]=f[d>>2],f[g+4>>2]=v,f[(d=a+16|0)>>2]=p,f[d+4>>2]=i,i=f[e+16>>2],p=f[e+20>>2],v=f[(d=e+40|0)+4>>2],f[(g=a+48|0)>>2]=f[d>>2],f[g+4>>2]=v,d=f[e+32>>2],v=f[e+36>>2],D=f[(g=e+56|0)+4>>2],f[(R=a- -64|0)>>2]=f[g>>2],f[R+4>>2]=D,f[a+8>>2]=h,f[a+12>>2]=y,f[a+24>>2]=i,f[a+28>>2]=p,f[a+40>>2]=d,f[a+44>>2]=v,i=f[e+52>>2],f[a+56>>2]=f[e+48>>2],f[a+60>>2]=i,e=f[o+12>>2],o=f[(i=e+8|0)+4>>2],f[(h=a+80|0)>>2]=f[i>>2],f[h+4>>2]=o,i=f[e+4>>2],f[a+72>>2]=f[e>>2],f[a+76>>2]=i,o=f[(i=e+24|0)+4>>2],f[(h=a+96|0)>>2]=f[i>>2],f[h+4>>2]=o,i=f[e+20>>2],f[(o=a+88|0)>>2]=f[e+16>>2],f[o+4>>2]=i,o=f[(i=e+40|0)+4>>2],f[(h=a+112|0)>>2]=f[i>>2],f[h+4>>2]=o,i=f[e+36>>2],f[(o=a+104|0)>>2]=f[e+32>>2],f[o+4>>2]=i,i=f[e+52>>2],f[(o=a+120|0)>>2]=f[e+48>>2],f[o+4>>2]=i,i=f[(e=e+56|0)+4>>2],f[(o=a+128|0)>>2]=f[e>>2],f[o+4>>2]=i,si(m,a+8|0,n,f[r+20>>2],_[t+16|0]),_[t+8|0]&&(t=f[n+4>>2],f[t+780>>2]&&((0|(e=f[t+772>>2]))==(0|(i=f[f[n+8>>2]+8>>2]))?se(t,e+4|0,f[f[n+12>>2]+8>>2]+4|0):se(t,f[f[n+12>>2]+8>>2]+4|0,i+4|0)))),Z=a+160|0},Re,ui,ve,Ci,function(t){var e=0,i=0;return f[(t|=0)>>2]=17516,_[t+8|0]&&((e=f[t+12>>2])&&(i=f[t+4>>2],yt[f[f[i>>2]+16>>2]](i,e))),0|t},function(t){var e=0,i=0;f[(t|=0)>>2]=17516,_[t+8|0]&&((e=f[t+12>>2])&&(i=f[t+4>>2],yt[f[f[i>>2]+16>>2]](i,e))),$(t)},function(t,e,i,r,n){e|=0,i|=0,r|=0,n|=0;var a,o=0,h=0,d=0,C=0,g=0,m=0,v=0,y=0,p=0,R=0,D=0;Z=a=Z-160|0,(m=f[(t|=0)+12>>2])&&(f[n+4>>2]=m,m=f[i+4>>2],R=f[e+4>>2],f[a+152>>2]=1566444395,e=f[e+12>>2],h=f[(o=e+8|0)+4>>2],f[(d=a+32|0)>>2]=f[o>>2],f[d+4>>2]=h,o=f[e>>2],h=f[e+4>>2],v=f[(d=e+24|0)+4>>2],f[(C=a+48|0)>>2]=f[d>>2],f[C+4>>2]=v,d=f[e+16>>2],v=f[e+20>>2],y=f[(C=e+40|0)+4>>2],f[(g=a- -64|0)>>2]=f[C>>2],f[g+4>>2]=y,C=f[e+32>>2],y=f[e+36>>2],D=f[(g=e+56|0)+4>>2],f[(p=a+80|0)>>2]=f[g>>2],f[p+4>>2]=D,f[a+24>>2]=o,f[a+28>>2]=h,f[a+40>>2]=d,f[a+44>>2]=v,f[a+56>>2]=C,f[a+60>>2]=y,o=f[e+52>>2],f[a+72>>2]=f[e+48>>2],f[a+76>>2]=o,e=f[i+12>>2],o=f[(i=e+8|0)+4>>2],f[(h=a+96|0)>>2]=f[i>>2],f[h+4>>2]=o,i=f[e+4>>2],f[a+88>>2]=f[e>>2],f[a+92>>2]=i,i=f[e+20>>2],f[(o=a+104|0)>>2]=f[e+16>>2],f[o+4>>2]=i,o=f[(i=e+24|0)+4>>2],f[(h=a+112|0)>>2]=f[i>>2],f[h+4>>2]=o,o=f[(i=e+40|0)+4>>2],f[(h=a+128|0)>>2]=f[i>>2],f[h+4>>2]=o,i=f[e+36>>2],f[(o=a+120|0)>>2]=f[e+32>>2],f[o+4>>2]=i,i=f[e+52>>2],f[(o=a+136|0)>>2]=f[e+48>>2],f[o+4>>2]=i,i=f[(e=e+56|0)+4>>2],f[(o=a+144|0)>>2]=f[e>>2],f[o+4>>2]=i,f[(e=a+8|0)+8>>2]=m,f[e+4>>2]=R,f[e>>2]=17464,Ci(e,a+24|0,n,f[r+20>>2],0),_[t+8|0]&&(t=f[n+4>>2],f[t+780>>2]&&((0|(e=f[t+772>>2]))==(0|(i=f[f[n+8>>2]+8>>2]))?se(t,e+4|0,f[f[n+12>>2]+8>>2]+4|0):se(t,f[f[n+12>>2]+8>>2]+4|0,i+4|0)))),Z=a+160|0},Re,ui,function(t){var e=0,i=0;return f[(t|=0)>>2]=17588,_[t+8|0]&&((e=f[t+12>>2])&&(i=f[t+4>>2],yt[f[f[i>>2]+16>>2]](i,e))),0|t},function(t){var e=0,i=0;f[(t|=0)>>2]=17588,_[t+8|0]&&((e=f[t+12>>2])&&(i=f[t+4>>2],yt[f[f[i>>2]+16>>2]](i,e))),$(t)},function(t,e,i,r,n){t|=0,e|=0,i|=0,r|=0,n|=0;var a=v(0),o=v(0),h=0,d=v(0),g=v(0),m=0,p=0,D=v(0),B=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=0,W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=v(0),Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0),Gt=v(0),Lt=0,wt=v(0),xt=v(0),Qt=v(0),Wt=v(0),Yt=v(0),Pt=0,Mt=v(0),Zt=v(0),Ut=v(0),Xt=v(0),Jt=v(0),jt=v(0),zt=v(0),Ht=v(0),Kt=v(0),qt=v(0),$t=v(0),bi=v(0),di=v(0),yi=v(0),Ii=v(0),Bi=v(0),BA=v(0);if(Z=r=Z-48|0,f[t+12>>2]){if(p=_[t+16|0],h=f[(Q=p?i:e)+12>>2],W=C[h+56>>2],Y=C[h+52>>2],z=C[h+48>>2],m=f[(Lt=p?e:i)+12>>2],wt=C[m+56>>2],Xt=C[m+48>>2],xt=C[m+52>>2],Q=f[Q+4>>2],pt=C[h+32>>2],Dt=C[h+16>>2],It=C[h>>2],St=C[h+36>>2],Tt=C[h+20>>2],Et=C[h+4>>2],o=C[m+40>>2],d=C[m+24>>2],a=C[m+8>>2],g=C[m+32>>2],F=C[m+16>>2],D=C[m>>2],p=f[Lt+4>>2],G=C[m+36>>2],V=C[h+40>>2],w=C[m+20>>2],Ot=C[h+24>>2],B=C[m+4>>2],Nt=C[h+8>>2],f[r+28>>2]=0,Wt=v(v(v(Nt*D)+v(Ot*F))+v(V*g)),Ft=v(-C[p+52>>2]),Yt=v(v(v(Nt*B)+v(Ot*w))+v(V*G)),Vt=C[(m=p+56|0)>>2],Ot=v(v(v(Nt*a)+v(Ot*d))+v(V*o)),V=C[(Pt=p+60|0)>>2],C[r+24>>2]=v(v(Wt*Ft)-v(Yt*Vt))-v(Ot*V),Nt=v(v(v(Et*D)+v(Tt*F))+v(St*g)),Mt=v(v(v(Et*B)+v(Tt*w))+v(St*G)),Zt=v(v(v(Et*a)+v(Tt*d))+v(St*o)),C[r+20>>2]=v(v(Nt*Ft)-v(Vt*Mt))-v(V*Zt),Ut=v(v(v(It*D)+v(Dt*F))+v(pt*g)),Qt=v(Ut*Ft),Ft=v(v(v(It*B)+v(Dt*w))+v(pt*G)),Gt=V,V=v(v(v(It*a)+v(Dt*d))+v(pt*o)),C[r+16>>2]=v(Qt-v(Vt*Ft))-v(Gt*V),yt[f[f[Q>>2]+64>>2]](r+32|0,Q,r+16|0),h=f[Lt+12>>2],Vt=C[h+48>>2],Jt=C[h+32>>2],jt=C[h+16>>2],zt=C[h+8>>2],Ht=C[h+4>>2],Kt=C[h>>2],qt=C[h+56>>2],$t=C[h+52>>2],bi=C[h+40>>2],di=C[h+36>>2],yi=C[h+24>>2],Ii=C[h+20>>2],Bi=C[p+68>>2],St=C[Pt>>2],Tt=C[p+52>>2],Et=C[m>>2],pt=C[r+40>>2],Dt=C[r+32>>2],It=C[r+36>>2],BA=C[f[t+12>>2]+784>>2],f[n+4>>2]=f[t+12>>2],Qt=v(v(v(z*a)+v(Y*d))+v(W*o)),Gt=a,a=v(-Xt),V=v(v(Qt+v(v(v(Gt*a)-v(d*xt))-v(o*wt)))+v(v(v(V*Dt)+v(Zt*It))+v(Ot*pt))),F=v(v(v(v(v(z*D)+v(Y*F))+v(W*g))+v(v(v(D*a)-v(F*xt))-v(g*wt)))+v(v(v(Ut*Dt)+v(Nt*It))+v(Wt*pt))),D=v(v(v(v(v(z*B)+v(Y*w))+v(W*G))+v(v(v(B*a)-v(w*xt))-v(G*wt)))+v(v(v(Ft*Dt)+v(Mt*It))+v(Yt*pt))),(o=v(v(v(St*V)+v(v(Tt*F)+v(Et*D)))-Bi))>2]=0,h=f[Lt+12>>2],d=C[p+52>>2],a=C[p+56>>2],g=C[p+60>>2],C[r+16>>2]=v(v(C[h>>2]*d)+v(C[h+4>>2]*a))+v(C[h+8>>2]*g),C[r+24>>2]=v(v(d*C[h+32>>2])+v(a*C[h+36>>2]))+v(g*C[h+40>>2]),C[r+20>>2]=v(v(d*C[h+16>>2])+v(a*C[h+20>>2]))+v(g*C[h+24>>2]),f[r+12>>2]=0,d=v(F-v(Tt*o)),a=v(D-v(Et*o)),g=v(V-v(St*o)),C[r+8>>2]=v(v(v(d*Jt)+v(a*di))+v(g*bi))+qt,C[r+4>>2]=v(v(v(d*jt)+v(a*Ii))+v(g*yi))+$t,C[r>>2]=v(v(zt*g)+v(v(Kt*d)+v(Ht*a)))+Vt,yt[f[f[n>>2]+16>>2]](n,r+16|0,r,o)),!(f[Q+4>>2]>6|f[f[n+4>>2]+780>>2]>=f[t+24>>2]||(d=C[p+60>>2],v(y(d))>v(.7071067690849304)?(o=C[p+56>>2],a=v(v(1)/v(E(v(v(d*d)+v(o*o))))),o=v(o*a),d=v(-v(d*a)),a=v(0)):(o=C[p+52>>2],a=C[p+56>>2],g=v(v(1)/v(E(v(v(o*o)+v(a*a))))),d=v(o*g),o=v(0),a=v(-v(a*g))),g=v(yt[f[f[Q>>2]+16>>2]](Q)),h=0,g=v(v(R(v(C[744]/g),v(.39269909262657166)))*v(.5)),D=dr(g),m=f[t+20>>2],F=Cr(g),(0|m)<1)))for(Gt=o,o=v(D/v(E(v(v(v(a*a)+v(d*d))+v(o*o))))),D=v(Gt*o),G=v(d*o),w=v(a*o);a=C[p+56>>2],g=C[p+60>>2],o=C[p+52>>2],d=v(v(v(v(6.2831854820251465)/v(0|m))*v(0|h))*v(.5)),B=v(dr(d)/v(E(v(v(v(o*o)+v(a*a))+v(g*g))))),o=v(o*B),d=Cr(d),a=v(a*B),g=v(g*B),B=v(v(v(v(F*d)+v(w*o))+v(G*a))+v(D*g)),W=v(v(v(v(w*d)-v(F*o))-v(D*a))+v(G*g)),Y=v(v(v(v(G*d)-v(F*a))-v(w*g))+v(D*o)),z=v(v(v(v(D*d)-v(F*g))-v(G*o))+v(w*a)),C[r+28>>2]=v(v(v(d*B)-v(o*W))-v(a*Y))-v(g*z),C[r+24>>2]=v(v(a*W)+v(v(g*B)+v(d*z)))-v(o*Y),C[r+20>>2]=v(v(o*z)+v(v(d*Y)+v(a*B)))-v(g*W),C[r+16>>2]=v(v(g*Y)+v(v(o*B)+v(d*W)))-v(a*z),gi(t,r+16|0,e,i,n),(0|(h=h+1|0))<(0|(m=f[t+20>>2])););!_[t+8|0]|!f[f[t+12>>2]+780>>2]||(t=f[n+4>>2],f[t+780>>2]&&((0|(e=f[t+772>>2]))==(0|(i=f[f[n+8>>2]+8>>2]))?se(t,e+4|0,f[f[n+12>>2]+8>>2]+4|0):se(t,f[f[n+12>>2]+8>>2]+4|0,i+4|0)))}Z=r+48|0},Re,ui,_i,function(t){$(_i(t|=0))},mi,function(t){return f[(t|=0)+16>>2]},function(t,e,i){var r;if(t|=0,!((r=8!=(0|(e|=0)))|8!=(0|(i|=0))))return f[t+56>>2];if(!(1!=(0|i)|r))return f[t+72>>2];if(!(1!=(0|e)|8!=(0|i)))return f[t+76>>2];if(!(e|i))return f[t+68>>2];if(!(28!=(0|i)|(0|e)>19))return f[t+84>>2];if(!(28!=(0|e)|(0|i)>19))return f[t+80>>2];t:{if((0|e)<=19){if((0|i)<=19)return f[t+28>>2];if(i+-21>>>0>8)break t;return f[t+32>>2]}if(!((0|i)>19|e+-21>>>0>8))return f[t+36>>2];if(31==(0|e))return 31==(0|i)?f[t+44>>2]:f[t+40>>2]}return 31==(0|i)?f[t+48>>2]:f[t+52>>2]},function(t,e,i){var r;if(t|=0,!((r=8!=(0|(e|=0)))|8!=(0|(i|=0))))return f[t+56>>2];if(!(1!=(0|i)|r))return f[t+72>>2];if(!(1!=(0|e)|8!=(0|i)))return f[t+76>>2];if(!(28!=(0|i)|(0|e)>19))return f[t+84>>2];if(!(28!=(0|e)|(0|i)>19))return f[t+80>>2];t:{if((0|e)<=19){if((0|i)<=19)return f[t+28>>2];if(i+-21>>>0>8)break t;return f[t+32>>2]}if(!((0|i)>19|e+-21>>>0>8))return f[t+36>>2];if(31==(0|e))return 31==(0|i)?f[t+44>>2]:f[t+40>>2]}return 31==(0|i)?f[t+48>>2]:f[t+52>>2]},ve,function(t,e,i,r){return t|=0,i|=0,r|=0,t=f[(e|=0)>>2],ei(t=0|yt[f[f[t>>2]+56>>2]](t,80),e,i,r,0),0|t},ve,function(t,e,i,r){return t|=0,i|=0,r|=0,t=f[(e|=0)>>2],ei(t=0|yt[f[f[t>>2]+56>>2]](t,80),e,i,r,1),0|t},ve,function(t,e,i,r){return t|=0,i|=0,r|=0,t=f[(e|=0)>>2],ri(t=0|yt[f[f[t>>2]+56>>2]](t,84),e,i,r,0),0|t},ve,function(t,e,i,r){return t|=0,i|=0,r|=0,t=f[(e|=0)>>2],function(t,e,i,r){ri(t,e,i,r,0),n[t+104|0]=1,f[t>>2]=16908,f[t+100>>2]=0,f[(e=t+92|0)>>2]=0,f[e+4>>2]=0,function(t){var e=0,i=0,r=0,a=0,o=0,h=0;if(f[t>>2]=16844,n[t+20|0]=1,f[t+16>>2]=0,n[t+40|0]=1,f[(e=i=t+8|0)>>2]=0,f[e+4>>2]=0,f[t+36>>2]=0,n[t+60|0]=1,f[(e=t+28|0)>>2]=0,f[e+4>>2]=0,f[t+56>>2]=0,f[(e=t+48|0)>>2]=0,f[e+4>>2]=0,e=dA(24),(0|(i=f[i>>2]))>=1)for(;a=f[t+16>>2]+r|0,h=f[a+4>>2],f[(o=e+r|0)>>2]=f[a>>2],f[o+4>>2]=h,f[o+8>>2]=f[a+8>>2],r=r+12|0,i=i+-1|0;);(r=f[t+16>>2])&&(_[t+20|0]&&CA(r),f[t+16>>2]=0),f[t+16>>2]=e,n[t+20|0]=1,f[t+12>>2]=2,ai(t)}(e=dA(64)),f[t+84>>2]=e,f[t+108>>2]=f[f[i+4>>2]+72>>2],f[t+112>>2]=f[f[r+4>>2]+72>>2]}(t=0|yt[f[f[t>>2]+56>>2]](t,116),e,i,r),0|t},ve,function(t,e,i,r){return t|=0,i|=0,r|=0,t=f[(e|=0)>>2],ri(t=0|yt[f[f[t>>2]+56>>2]](t,84),e,i,r,1),0|t},ve,function(t,e,i,r){return t|=0,t=f[(e|=0)>>2],uA(t=0|yt[f[f[t>>2]+56>>2]](t,8),e),f[t>>2]=17112,0|t},ve,function(t,e,i,r){return t|=0,i|=0,r|=0,t=f[(e|=0)>>2],function(t,e,i,r){vA(t,e),f[t+12>>2]=0,n[t+8|0]=0,f[t>>2]=17172,e=f[t+4>>2],e=0|yt[f[f[e>>2]+12>>2]](e,f[i+8>>2],f[r+8>>2]),n[t+8|0]=1,f[t+12>>2]=e}(t=0|yt[f[f[t>>2]+56>>2]](t,16),e,i,r),0|t},ve,function(t,e,i,r){t|=0,i|=0,r|=0;var a=0;return a=f[(e|=0)>>2],function(t,e,i,r,a,o){vA(t,i),n[t+16|0]=o,f[t+12>>2]=e,n[t+8|0]=0,f[t>>2]=17308,e||(e=f[t+4>>2],e=0|yt[f[f[e>>2]+12>>2]](e,f[r+8>>2],f[a+8>>2]),n[t+8|0]=1,f[t+12>>2]=e)}(a=0|yt[f[f[a>>2]+56>>2]](a,20),f[e+4>>2],e,i,r,_[t+4|0]),0|a},ve,function(t,e,i,r){return t|=0,i|=0,r|=0,t=f[(e|=0)>>2],function(t,e,i,r){vA(t,e),f[t+12>>2]=0,n[t+8|0]=0,f[t>>2]=17516,e=f[t+4>>2],yt[f[f[e>>2]+24>>2]](e,f[i+8>>2],f[r+8>>2])&&(e=f[t+4>>2],e=0|yt[f[f[e>>2]+12>>2]](e,f[i+8>>2],f[r+8>>2]),n[t+8|0]=1,f[t+12>>2]=e)}(t=0|yt[f[f[t>>2]+56>>2]](t,16),e,i,r),0|t},ve,function(t,e,i,r){t|=0,i|=0,r|=0;var a=0;return a=f[(e|=0)>>2],function(t,e,i,r,a,o,_){uA(t,e),f[t+24>>2]=_,f[t+20>>2]=o,n[t+16|0]=a,f[t+12>>2]=0,n[t+8|0]=0,f[t>>2]=17588,e=f[t+4>>2],o=a?r:i,i=a?i:r,yt[f[f[e>>2]+24>>2]](e,f[o+8>>2],f[i+8>>2])&&(e=f[t+4>>2],e=0|yt[f[f[e>>2]+12>>2]](e,f[o+8>>2],f[i+8>>2]),n[t+8|0]=1,f[t+12>>2]=e)}(a=0|yt[f[f[a>>2]+56>>2]](a,28),e,i,r,_[t+4|0],f[t+8>>2],f[t+12>>2]),0|a},function(t){var e=0;return f[(t|=0)>>2]=18600,(e=f[t+60>>2])&&(_[t- -64|0]&&CA(e),f[t+60>>2]=0),f[t+60>>2]=0,f[t+52>>2]=0,f[t+56>>2]=0,n[t- -64|0]=1,(e=f[t+40>>2])&&(_[t+44|0]&&CA(e),f[t+40>>2]=0),f[t+40>>2]=0,f[t+32>>2]=0,f[t+36>>2]=0,n[t+44|0]=1,(e=f[t+16>>2])&&(_[t+20|0]&&CA(e),f[t+16>>2]=0),f[t+16>>2]=0,f[t+8>>2]=0,f[t+12>>2]=0,n[t+20|0]=1,0|t},function(t){var e=0;f[(t|=0)>>2]=18600,(e=f[t+60>>2])&&(_[t- -64|0]&&CA(e),f[t+60>>2]=0),f[t+60>>2]=0,f[t+52>>2]=0,f[t+56>>2]=0,n[t- -64|0]=1,(e=f[t+40>>2])&&(_[t+44|0]&&CA(e),f[t+40>>2]=0),f[t+40>>2]=0,f[t+32>>2]=0,f[t+36>>2]=0,n[t+44|0]=1,(e=f[t+16>>2])&&(_[t+20|0]&&CA(e),f[t+16>>2]=0),f[t+16>>2]=0,f[t+8>>2]=0,f[t+12>>2]=0,n[t+20|0]=1,CA(t)},function(t,e,i){t|=0,e|=0,i|=0;var r,a=0;f[696]=f[696]+1;t:{e:{if(r=f[t+24>>2]){if(yt[f[f[r>>2]+8>>2]](r,e,i))break e;break t}if(!(f[i+8>>2]&f[e+4>>2])|!(f[e+8>>2]&f[i+4>>2]))break t}a=function(t,e,i){var r,a,o,h=0,d=0,C=0,g=0,v=0,y=0,p=0,R=0,D=0,B=0;d=f[e+12>>2]>f[i+12>>2],g=f[(r=d?e:i)+12>>2],C=f[(a=d?i:e)+12>>2],e=m((e=((e=g<<16|C)<<15^-1)+e|0)>>>10^e,9),y=(o=(e=((e^=e>>>6)<<11^-1)+e|0)>>>16^e)&(d=f[t+12>>2])+-1;e:{if(-1!=(0|(e=f[f[t+40>>2]+(y<<2)>>2])))for(h=f[t+16>>2];;){if(i=(v=e<<4)+h|0,(0|g)==f[f[4+(h+v|0)>>2]+12>>2]&&f[f[i>>2]+12>>2]==(0|C))break e;if(-1==(0|(e=f[f[t+60>>2]+(e<<2)>>2])))break}if((0|(e=d))==(0|(i=g=f[t+8>>2]))&&(i=d,!((0|e)>=(0|(h=e?e<<1:1))))){if(h?(C=dA(h<<4),i=f[t+8>>2]):(C=0,i=d),(0|i)>=1)for(e=12;v=e+C|0,p=f[t+16>>2]+e|0,f[v+-12>>2]=f[p+-12>>2],B=f[(R=p+-8|0)+4>>2],f[(D=v+-8|0)>>2]=f[R>>2],f[D+4>>2]=B,f[v>>2]=f[p>>2],e=e+16|0,i=i+-1|0;);(e=f[t+16>>2])&&(_[t+20|0]&&CA(e),f[t+16>>2]=0),f[t+16>>2]=C,f[t+12>>2]=h,n[t+20|0]=1,i=f[t+8>>2],e=h}f[t+8>>2]=i+1,C=g<<4,h=f[t+16>>2],(i=f[t+68>>2])&&(yt[f[f[i>>2]+8>>2]](i,a,r),e=f[t+12>>2]),i=h+C|0,(0|d)<(0|e)&&(Qi(t),y=f[t+12>>2]+-1&o),d=f[r+12>>2],C=f[a+12>>2],f[(e=h+(g<<4)|0)+8>>2]=0,f[e+12>>2]=0,h=e,e=(0|C)<(0|d),f[h+4>>2]=e?r:a,d=f[t+60>>2]+(g<<2)|0,t=f[t+40>>2]+(y<<2)|0,f[d>>2]=f[t>>2],f[i>>2]=e?a:r,f[t>>2]=g}return i}(t,e,i)}return 0|a},function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n=0,a=0,o=0,_=0,h=0,d=0,C=0;f[695]=f[695]+1,n=f[e+12>>2]>f[i+12>>2],a=f[(o=n?e:i)+12>>2],_=f[(h=n?i:e)+12>>2],e=m((e=((e=a<<16|_)<<15^-1)+e|0)>>>10^e,9),e=((e^=e>>>6)<<11^-1)+e|0,d=f[t+12>>2]+-1&(e>>>16^e);t:if(-1!=(0|(e=f[f[t+40>>2]+(d<<2)>>2]))){for(n=f[t+16>>2];;){if((0|a)!=f[f[(i=n+(e<<4)|0)+4>>2]+12>>2]||f[f[i>>2]+12>>2]!=(0|_)){if(-1!=(0|(e=f[f[t+60>>2]+(e<<2)>>2])))continue;break t}break}yt[f[f[t>>2]+32>>2]](t,i,r),C=f[12+(n+(e<<4)|0)>>2],a=f[t+60>>2];e:{if(_=f[t+40>>2]+(d<<2)|0,(0|(e=f[_>>2]))!=(0|(n=i-f[t+16>>2]>>4))){for(;i=e,(0|n)!=(0|(e=f[a+(e<<2)>>2])););if(e=f[a+(n<<2)>>2],-1!=(0|i)){f[a+(i<<2)>>2]=e;break e}}else e=f[a+(n<<2)>>2];f[_>>2]=e}if(a=f[t+8>>2]+-1|0,(e=f[t+68>>2])&&yt[f[f[e>>2]+12>>2]](e,h,o,r),(0|a)==(0|n))return f[t+8>>2]=f[t+8>>2]+-1,0|C;r=f[t+60>>2];e:{if(h=f[t+16>>2],e=f[f[(o=h+(a<<4)|0)+4>>2]+12>>2]<<16|f[f[o>>2]+12>>2],e=m((e=(e<<15^-1)+e|0)>>>10^e,9),e=((e^=e>>>6)<<11^-1)+e|0,_=f[t+12>>2]+-1&(e>>>16^e),d=f[t+40>>2]+(_<<2)|0,(0|(e=f[d>>2]))!=(0|a)){for(;i=e,(0|a)!=(0|(e=f[r+(e<<2)>>2])););if(e=f[r+(a<<2)>>2],-1!=(0|i)){f[r+(i<<2)>>2]=e;break e}}else e=f[r+(a<<2)>>2];f[d>>2]=e}i=f[o+4>>2],f[(e=h+(n<<4)|0)>>2]=f[o>>2],f[e+4>>2]=i,r=f[(i=o+8|0)+4>>2],f[(e=e+8|0)>>2]=f[i>>2],f[e+4>>2]=r,e=f[t+40>>2]+(_<<2)|0,f[f[t+60>>2]+(n<<2)>>2]=f[e>>2],f[e>>2]=n,f[t+8>>2]=f[t+8>>2]+-1}return 0|C},function(t,e,i){var r;t|=0,e|=0,i|=0,Z=r=Z-16|0,f[r+12>>2]=e,f[r+8>>2]=18960,yt[f[f[t>>2]+48>>2]](t,r+8|0,i),Z=r+16|0},ci,ci,hi,function(t,e,i){t|=0,e|=0,(i|=0)&&((t=f[e+8>>2])&&(yt[f[f[t>>2]>>2]](t),yt[f[f[i>>2]+60>>2]](i,f[e+8>>2]),f[e+8>>2]=0))},function(t){return f[(t|=0)+8>>2]},function(t,e,i){var r;t|=0,e|=0,i|=0,Z=r=Z-16|0,f[r+12>>2]=i,f[r+8>>2]=t,f[r+4>>2]=e,f[r>>2]=18816,yt[f[f[t>>2]+48>>2]](t,r,i),Z=r+16|0},Gi,function(t,e,i){t|=0,e|=0,i|=0;var r,n=0,a=0;if(Z=r=Z-16|0,Lr(r+8|0,18668),f[t+8>>2]>=1)for(;a=f[t+16>>2]+(n<<4)|0,yt[f[f[e>>2]+8>>2]](e,a)?(yt[f[f[t>>2]+12>>2]](t,f[a>>2],f[a+4>>2],i),f[694]=f[694]+-1):n=n+1|0,(0|n)>2];);qr(),Z=r+16|0},function(t,e,i){t|=0,e|=0,i|=0;var r,n,a=0,o=0;f[697]=f[697]+1,a=f[e+12>>2]>f[i+12>>2],r=f[(a?e:i)+12>>2],n=f[(a?i:e)+12>>2],e=m((e=((e=n|r<<16)<<15^-1)+e|0)>>>10^e,9),e=((e^=e>>>6)<<11^-1)+e|0;t:{if(!((0|(e=f[t+12>>2]+-1&(e>>>16^e)))>=f[t+32>>2])&&-1!=(0|(e=f[f[t+40>>2]+(e<<2)>>2])))for(i=f[t+16>>2];;){if(a=(o=e<<4)+i|0,f[f[4+(i+o|0)>>2]+12>>2]==(0|r)&&(0|n)==f[f[a>>2]+12>>2])break t;if(-1==(0|(e=f[f[t+60>>2]+(e<<2)>>2])))break}a=0}return 0|a},we,function(t,e){e|=0,f[(t|=0)+68>>2]=e},function(t,e){t|=0,e|=0;var i,r=0,a=0,o=0,h=0,d=0,C=0,g=0,m=0,v=0,y=0,p=0;if(Z=i=Z-32|0,f[i+20>>2]=0,f[i+12>>2]=0,f[i+16>>2]=0,a=f[t+8>>2],n[i+24|0]=1,!((0|a)<1)){for(a=0;;){if(o=f[t+16>>2]+(d<<4)|0,(0|r)==(0|a))if((0|a)>=(0|(h=a?a<<1:1)))r=a;else{if(C=h?dA(h<<4):0,(0|a)>=1)for(r=12;g=r+C|0,m=f[i+20>>2]+r|0,f[g+-12>>2]=f[m+-12>>2],p=f[(v=m+-8|0)+4>>2],f[(y=g+-8|0)>>2]=f[v>>2],f[y+4>>2]=p,f[g>>2]=f[m>>2],r=r+16|0,a=a+-1|0;);(r=f[i+20>>2])&&(_[i+24|0]&&CA(r),f[i+20>>2]=0),f[i+20>>2]=C,n[i+24|0]=1,f[i+16>>2]=h,r=f[i+12>>2]}if(r=f[i+20>>2]+(r<<4)|0,f[r>>2]=f[o>>2],a=f[o+8>>2],f[r+4>>2]=f[o+4>>2],f[r+8>>2]=a,f[r+12>>2]=f[o+12>>2],r=(h=f[i+12>>2])+1|0,f[i+12>>2]=r,!((0|(d=d+1|0))>2]))break;a=f[i+16>>2]}if(!((0|h)<0))for(a=-1,o=f[i+20>>2];yt[f[f[t>>2]+12>>2]](t,f[o>>2],f[o+4>>2],e),o=o+16|0,(0|(a=a+1|0))<(0|h););}if(f[t+52>>2]>=1){for(r=f[t+60>>2],o=0;f[r>>2]=-1,r=r+4|0,(0|(o=o+1|0))>2];);r=f[i+12>>2]}if((0|r)>=2&&(Ei(i+8|0,i,0,r+-1|0),r=f[i+12>>2]),o=f[i+20>>2],(0|r)>=1)for(e=0,r=4;a=r+o|0,yt[f[f[t>>2]+8>>2]](t,f[a+-4>>2],f[a>>2]),r=r+16|0,o=f[i+20>>2],(0|(e=e+1|0))>2];);o&&(_[i+24|0]&&CA(o),f[i+20>>2]=0),Z=i+32|0},ve,function(t,e){e|=0;var i=0;return(0|(i=f[(t|=0)+4>>2]))!=f[e+4>>2]&&(0|i)!=f[e>>2]||(i=f[t+8>>2],yt[f[f[i>>2]+32>>2]](i,e,f[t+12>>2])),0},ve,function(t,e){return e|=0,(0|(t=f[(t|=0)+4>>2]))==f[e>>2]|(0|t)==f[e+4>>2]},Fi,function(t){$(Fi(t|=0))},function(t,e,i,r,n,a,o,h){t|=0,e|=0,i|=0,r|=0,n|=0,a|=0,o|=0,h|=0;var d=0;return Z=h=Z-48|0,r=dA(64),f[r+8>>2]=o,f[r+4>>2]=a,f[r>>2]=n,n=f[e+4>>2],f[r+16>>2]=f[e>>2],f[r+20>>2]=n,d=f[(n=e+8|0)+4>>2],f[(a=r+24|0)>>2]=f[n>>2],f[a+4>>2]=d,a=f[i+4>>2],f[r+32>>2]=f[i>>2],f[r+36>>2]=a,d=f[(a=i+8|0)+4>>2],f[(o=r+40|0)>>2]=f[a>>2],f[o+4>>2]=d,f[r+52>>2]=0,f[r+56>>2]=0,d=f[n+4>>2],f[(o=h+24|0)>>2]=f[n>>2],f[o+4>>2]=d,o=f[a+4>>2],f[(n=h+40|0)>>2]=f[a>>2],f[n+4>>2]=o,n=f[e>>2],e=f[e+4>>2],a=f[i+4>>2],i=f[i>>2],f[r+60>>2]=f[t+104>>2],f[h+32>>2]=i,f[h+36>>2]=a,i=f[t+148>>2]+1|0,f[r+12>>2]=i,f[t+148>>2]=i,f[h+16>>2]=n,f[h+20>>2]=e,e=or(i=t+4|0,h+16|0,r),f[r+52>>2]=0,f[r+48>>2]=e,e=84+((f[t+104>>2]<<2)+t|0)|0,f[r+56>>2]=f[e>>2],(n=f[e>>2])&&(f[n+52>>2]=r),f[e>>2]=r,_[t+153|0]||(f[h+8>>2]=r,f[h>>2]=19252,f[h+4>>2]=t,Wi(i,f[t+4>>2],h+16|0,h),Wi(t=t+44|0,f[t>>2],h+16|0,h)),Z=h+48|0,0|r},function(t,e,i){t|=0,i|=0;var r,a=0;br(2==f[(e|=0)+60>>2]?t+44|0:t+4|0,f[e+48>>2]),r=f[e+56>>2],a=(a=f[e+52>>2])?a+56|0:84+((f[e+60>>2]<<2)+t|0)|0,f[a>>2]=r,(a=f[e+56>>2])&&(f[a+52>>2]=f[e+52>>2]),a=f[t+96>>2],yt[f[f[a>>2]+16>>2]](a,e,i),CA(e),n[t+154|0]=1},function(t,e,i,r,a){t|=0,e|=0,i|=0,r|=0,a|=0;var o=0,h=0,d=0,g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=0,G=0;Z=a=Z-48|0,d=f[(h=i+8|0)+4>>2],f[(o=a+24|0)>>2]=f[h>>2],f[o+4>>2]=d,d=f[(h=r+8|0)+4>>2],f[(o=a+40|0)>>2]=f[h>>2],f[o+4>>2]=d,o=f[i+4>>2],f[a+16>>2]=f[i>>2],f[a+20>>2]=o,o=f[r+4>>2],f[a+32>>2]=f[r>>2],f[a+36>>2]=o;t:if(2!=f[e+60>>2])if(h=1,f[t+128>>2]=f[t+128>>2]+1,o=f[e+48>>2],C[o>>2]<=C[a+32>>2]^1|C[o+16>>2]>=C[a+16>>2]^1|C[o+4>>2]<=C[a+36>>2]^1|C[o+20>>2]>=C[a+20>>2]^1||C[o+8>>2]<=C[a+40>>2]^1|C[o+24>>2]>=C[a+24>>2]^1)cr(t+4|0,o,a+16|0),f[t+132>>2]=f[t+132>>2]+1;else{if(m=C[e+20>>2],y=C[e+24>>2],B=C[i>>2],E=C[i+4>>2],F=C[i+8>>2],p=C[e+16>>2],f[a+12>>2]=0,g=C[t+100>>2],R=v(g*v(v(C[e+40>>2]-y)*v(.5))),C[a+8>>2]=R,D=v(g*v(v(C[e+36>>2]-m)*v(.5))),C[a+4>>2]=D,g=v(g*v(v(C[e+32>>2]-p)*v(.5))),C[a>>2]=g,m=v(E-m),v(B-p)>2]=-g),y=v(F-y),m>2]=-D),y>2]=-R),h=0,!function(t,e,i,r){var n=0,a=0,o=v(0),_=0,h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0);h=C[i>>2];e:{if(C[e>>2]<=h){if(o=C[i+4>>2],!(C[e+4>>2]<=o^1|C[e+8>>2]<=C[i+8>>2]^1|C[e+16>>2]>=C[i+16>>2]^1|C[e+20>>2]>=C[i+20>>2]^1)&&(n=0,C[e+24>>2]>=C[i+24>>2]))break e}else o=C[i+4>>2];g=v(o-v(.05000000074505806)),C[i+4>>2]=g,d=v(h-v(.05000000074505806)),C[i>>2]=d,m=v(C[i+8>>2]-v(.05000000074505806)),C[i+8>>2]=m,y=v(C[i+16>>2]+v(.05000000074505806)),C[i+16>>2]=y,o=v(C[(n=i+20|0)>>2]+v(.05000000074505806)),C[n>>2]=o,h=v(C[(_=i+24|0)>>2]+v(.05000000074505806)),C[_>>2]=h,n=(p=C[r>>2])>v(0),C[(n<<4)+i>>2]=(n?y:d)+p,n=(d=C[r+4>>2])>v(0),C[(n?20:4)+i>>2]=(n?o:g)+d,r=(o=C[r+8>>2])>v(0),C[(r?24:8)+i>>2]=(r?h:m)+o;i:if(r=nr(t,e))if(a=f[t+8>>2],(0|a)>=0){if(!a)break i;for(;;){if(!(n=f[r+32>>2]))break i;if(r=n,!(a=a+-1|0))break}}else r=f[t>>2];else r=0;n=f[i+4>>2],f[e>>2]=f[i>>2],f[e+4>>2]=n,n=f[_+4>>2],f[(a=e+24|0)>>2]=f[_>>2],f[a+4>>2]=n,_=f[(n=i+16|0)+4>>2],f[(a=e+16|0)>>2]=f[n>>2],f[a+4>>2]=_,n=f[(i=i+8|0)+4>>2],f[(_=e+8|0)>>2]=f[i>>2],f[_+4>>2]=n,ar(t,r,e),n=1}return n}(t+4|0,o,a+16|0,a))break t;h=1,f[t+132>>2]=f[t+132>>2]+1}else br(t+44|0,f[e+48>>2]),V=e,G=or(t+4|0,a+16|0,e),f[V+48>>2]=G,h=1;d=f[e+56>>2],o=(o=f[e+52>>2])?o+56|0:84+((f[e+60>>2]<<2)+t|0)|0,f[o>>2]=d,(o=f[e+56>>2])&&(f[o+52>>2]=f[e+52>>2]),o=f[i+4>>2],f[e+16>>2]=f[i>>2],f[e+20>>2]=o,d=f[(i=i+8|0)+4>>2],f[(o=e+24|0)>>2]=f[i>>2],f[o+4>>2]=d,d=f[(o=r+8|0)+4>>2],f[(i=e+40|0)>>2]=f[o>>2],f[i+4>>2]=d,i=f[r+4>>2],f[e+32>>2]=f[r>>2],f[e+36>>2]=i,f[e+52>>2]=0,i=84+(((r=f[t+104>>2])<<2)+t|0)|0,f[e+56>>2]=f[i>>2],f[e+60>>2]=r,(r=f[i>>2])&&(f[r+52>>2]=e),f[i>>2]=e,h&&(n[t+154|0]=1,_[t+153|0]||(f[a>>2]=19252,f[a+4>>2]=t,Di(i=t+44|0,f[i>>2],f[e+48>>2],a),Di(t+4|0,f[t+4>>2],f[e+48>>2],a))),Z=a+48|0},function(t,e,i,r){t|=0,i|=0,r|=0;var n=0;t=f[(e|=0)+20>>2],f[i>>2]=f[e+16>>2],f[i+4>>2]=t,t=i+8|0,n=f[(i=e+24|0)+4>>2],f[t>>2]=f[i>>2],f[t+4>>2]=n,n=f[(i=e+40|0)+4>>2],f[(t=r+8|0)>>2]=f[i>>2],f[t+4>>2]=n,t=f[e+36>>2],f[r>>2]=f[e+32>>2],f[r+4>>2]=t},function(t,e,i,r,n,a){var o,_,h;t|=0,e|=0,i|=0,r|=0,n|=0,a|=0,Z=i=Z-16|0,f[i+8>>2]=19324,f[i+12>>2]=r,o=r+4|0,_=r+20|0,h=f[t+168>>2],wi(t+4|0,f[t+4>>2],e,o,_,C[r+32>>2],n,a,h,i+8|0),wi(t=t+44|0,f[t>>2],e,o,_,C[r+32>>2],n,a,h,i+8|0),Z=i+16|0},function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n,a=0,o=0;Z=n=Z-48|0,f[n+44>>2]=r,f[n+40>>2]=19396,o=f[(a=e+8|0)+4>>2],f[(r=n+16|0)>>2]=f[a>>2],f[r+4>>2]=o,o=f[(a=i+8|0)+4>>2],f[(r=n+32|0)>>2]=f[a>>2],f[r+4>>2]=o,r=f[e+4>>2],f[n+8>>2]=f[e>>2],f[n+12>>2]=r,e=f[i+4>>2],f[n+24>>2]=f[i>>2],f[n+28>>2]=e,Wi(t+4|0,f[t+4>>2],n+8|0,n+40|0),Wi(t=t+44|0,f[t>>2],n+8|0,n+40|0),Z=n+48|0},function(t,e){(function(t,e){var i,r,a=0,o=0,h=0,d=0,g=0,y=0,p=0,R=0,D=0,B=v(0);if(Z=i=Z-32|0,tr(r=t+4|0,1+((0|m(f[t+112>>2],f[t+16>>2]))/100|0)|0),f[t+124>>2]&&(tr(t+44|0,a=1+((0|m(f[t+108>>2],f[t+56>>2]))/100|0)|0),a=f[t+124>>2]-a|0,f[t+124>>2]=(0|a)>0?a:0),a=(f[t+104>>2]+1|0)%2|0,f[t+104>>2]=a,o=f[84+((a<<2)+t|0)>>2]){for(g=t+44|0,D=i+16|0;a=f[o+56>>2],h=(h=f[o+52>>2])?h+56|0:84+((f[o+60>>2]<<2)+t|0)|0,f[h>>2]=a,(h=f[o+56>>2])&&(f[h+52>>2]=f[o+52>>2]),f[o+52>>2]=0,f[o+56>>2]=f[t+92>>2],(h=f[t+92>>2])&&(f[h+52>>2]=o),f[t+92>>2]=o,br(r,f[o+48>>2]),h=f[(y=o+24|0)+4>>2],f[(d=i+8|0)>>2]=f[y>>2],f[d+4>>2]=h,R=f[o+16>>2],p=f[o+20>>2],h=f[o+36>>2],f[D>>2]=f[o+32>>2],f[D+4>>2]=h,h=f[(y=o+40|0)+4>>2],f[(d=D+8|0)>>2]=f[y>>2],f[d+4>>2]=h,f[i>>2]=R,f[i+4>>2]=p,h=or(g,i,o),f[o+60>>2]=2,f[o+48>>2]=h,o=a,a;);n[t+154|0]=1,f[t+124>>2]=f[t+56>>2]}if(f[i>>2]=19252,f[i+4>>2]=t,_[t+153|0]&&(Di(r,f[t+4>>2],f[t+44>>2],i),_[t+153|0]&&Di(r,a=f[r>>2],a,i)),_[t+154|0]&&(a=f[t+96>>2],d=0|yt[f[f[a>>2]+28>>2]](a),!((0|(h=f[d+4>>2]))<1))){R=t+144|0;t:{if((0|(p=(0|h)<(0|(a=(0|(o=f[t+120>>2]))>(0|(a=(0|m(f[t+116>>2],h))/100|0))?o:a))?h:a))>=1){for(o=0;a=f[d+12>>2]+((f[R>>2]+o|0)%(0|h)<<4)|0,y=f[a>>2],g=f[y+48>>2],h=f[a+4>>2],a=f[h+48>>2],!(C[g>>2]<=C[a+16>>2]^1|C[g+16>>2]>=C[a>>2]^1|C[g+4>>2]<=C[a+20>>2]^1|C[g+20>>2]>=C[a+4>>2]^1)&&C[g+8>>2]<=C[a+24>>2]&&C[g+24>>2]>=C[a+8>>2]||(a=f[t+96>>2],yt[f[f[a>>2]+12>>2]](a,y,h,e),o=o+-1|0,p=p+-1|0),h=f[d+4>>2],(0|(o=o+1|0))<(0|p););if(R=t+144|0,o=0,(0|h)<=0)break t}o=(f[R>>2]+p|0)%(0|h)|0}f[R>>2]=o}n[t+154|0]=0,f[t+120>>2]=1,f[t+140>>2]=f[t+140>>2]+1,a=f[t+132>>2],o=t,e=f[t+128>>2],B=v(0),e&&(B=v(v(a>>>0)/v(e>>>0))),C[o+136>>2]=B,f[t+132>>2]=a>>>1,f[t+128>>2]=e>>>1,Z=i+32|0})(t|=0,e|=0),function(t,e){var i,r=0,a=0,o=0,h=0,d=0,g=0,m=0,v=0,y=0,p=0,R=0;if(Z=i=Z-16|0,r=f[t+96>>2],yt[f[f[r>>2]+56>>2]](r)){if(r=f[t+96>>2],a=0|yt[f[f[r>>2]+28>>2]](r),(0|(o=f[a+4>>2]))>=2&&(Ei(a,i+8|0,0,o+-1|0),o=f[a+4>>2]),(0|o)>=1){for(;;){m=f[a+12>>2]+R|0,r=f[m+4>>2],h=v,v=f[m>>2];t:{e:if((0|r)!=(0|g)||(0|h)!=(0|v)){if(d=f[v+48>>2],h=f[r+48>>2],!(C[d>>2]<=C[h+16>>2]^1|C[d+16>>2]>=C[h>>2]^1|C[d+4>>2]<=C[h+20>>2]^1|C[d+20>>2]>=C[h+4>>2]^1)&&C[d+8>>2]<=C[h+24>>2]){if(g=r,!(C[d+24>>2]>=C[h+8>>2]))break e;break t}g=r}r=f[t+96>>2],yt[f[f[r>>2]+32>>2]](r,m,e),f[m>>2]=0,f[m+4>>2]=0,y=y+1|0,o=f[a+4>>2]}if(R=R+16|0,!((0|(p=p+1|0))<(0|o)))break}if((0|o)>=2&&(Ei(a,i,0,o+-1|0),o=f[a+4>>2]),t=o-y|0,(0|y)<=-1){if(f[a+8>>2]<(0|t)){if(t?(p=dA(t<<4),e=f[a+4>>2]):(p=0,e=o),(0|e)>=1)for(r=12;g=r+p|0,v=f[a+12>>2]+r|0,f[g+-12>>2]=f[v+-12>>2],m=f[(h=v+-8|0)+4>>2],f[(d=g+-8|0)>>2]=f[h>>2],f[d+4>>2]=m,f[g>>2]=f[v>>2],r=r+16|0,e=e+-1|0;);(e=f[a+12>>2])&&(_[a+16|0]&&CA(e),f[a+12>>2]=0),f[a+12>>2]=p,n[a+16|0]=1,f[a+8>>2]=t}for(r=o<<4;e=f[a+12>>2]+r|0,f[e>>2]=0,f[e+4>>2]=0,f[(e=e+8|0)>>2]=0,f[e+4>>2]=0,r=r+16|0,g=(e=y+1|0)>>>0>=y>>>0,y=e,g;);}o=t}f[a+4>>2]=o}Z=i+16|0}(t,e)},ne,ne,function(t,e,i){t|=0,e|=0,i|=0;var r,n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0);r=f[t+44>>2];t:if(t=f[t+4>>2]){if(o=C[t>>2],r){if(_=(n=C[t+20>>2])>(a=C[r+20>>2])?n:a,h=(n=C[t+8>>2])<(a=C[r+8>>2])?n:a,d=(n=C[t+4>>2])<(a=C[r+4>>2])?n:a,g=(n=C[t+16>>2])>(a=C[r+16>>2])?n:a,o=o<(n=C[r>>2])?o:n,!((n=C[t+24>>2])>(a=C[r+24>>2]))){n=a;break t}break t}a=C[t+28>>2],n=C[t+24>>2],_=C[t+20>>2],g=C[t+16>>2],m=C[t+12>>2],h=C[t+8>>2],d=C[t+4>>2]}else r&&(a=C[r+28>>2],n=C[r+24>>2],_=C[r+20>>2],g=C[r+16>>2],m=C[r+12>>2],h=C[r+8>>2],d=C[r+4>>2],o=C[r>>2]);C[e+12>>2]=m,C[e+8>>2]=h,C[e+4>>2]=d,C[e>>2]=o,C[i+12>>2]=a,C[i+8>>2]=n,C[i+4>>2]=_,C[i>>2]=g},function(t,e){e|=0,f[(t|=0)+16>>2]==(0-f[t+56>>2]|0)&&(fr(t+4|0),fr(t+44|0),n[t+153|0]=256,n[t+154|0]=1,f[t+124>>2]=0,f[t+104>>2]=0,f[t+116>>2]=10,f[t+120>>2]=1,f[t+108>>2]=1,f[t+112>>2]=0,f[(e=t+84|0)>>2]=0,f[e+4>>2]=0,f[t+92>>2]=0,f[t+128>>2]=0,f[t+132>>2]=0,f[(e=t+136|0)>>2]=0,f[e+4>>2]=0,f[(t=t+144|0)>>2]=0,f[t+4>>2]=0)},qe,ve,function(t,e,i){t|=0;var r=0;(0|(e|=0))!=(0|(i|=0))&&(r=f[f[t+4>>2]+96>>2],yt[f[f[r>>2]+8>>2]](r,f[e+36>>2],f[i+36>>2]),t=f[t+4>>2],f[t+120>>2]=f[t+120>>2]+1)},function(t,e){e|=0,yt[f[f[(t|=0)>>2]+8>>2]](t,e,f[f[t+8>>2]+48>>2])},ve,Zi,ve,Zi,function(t){var e;return f[(t|=0)>>2]=20096,(e=f[t+556>>2])&&(_[t+560|0]&&CA(e),f[t+556>>2]=0),f[t+556>>2]=0,f[t+548>>2]=0,f[t+552>>2]=0,n[t+560|0]=1,Ze(t),0|t},function(t){var e;f[(t|=0)>>2]=20096,(e=f[t+556>>2])&&(_[t+560|0]&&CA(e),f[t+556>>2]=0),f[t+556>>2]=0,f[t+548>>2]=0,f[t+552>>2]=0,n[t+560|0]=1,Ze(t),CA(t)},function(t){return 496},function(t,e,i){return Ne(t|=0,e|=0,i|=0),f[e+264>>2]=f[t+324>>2],f[e+268>>2]=f[t+328>>2],f[e+272>>2]=f[t+332>>2],f[e+276>>2]=f[t+336>>2],f[e+280>>2]=f[t+340>>2],f[e+284>>2]=f[t+344>>2],f[e+288>>2]=f[t+348>>2],f[e+292>>2]=f[t+352>>2],f[e+296>>2]=f[t+356>>2],f[e+300>>2]=f[t+360>>2],f[e+304>>2]=f[t+364>>2],f[e+308>>2]=f[t+368>>2],f[e+312>>2]=f[t+372>>2],f[e+316>>2]=f[t+376>>2],f[e+320>>2]=f[t+380>>2],f[e+324>>2]=f[t+384>>2],f[e+328>>2]=f[t+388>>2],f[e+332>>2]=f[t+392>>2],f[e+336>>2]=f[t+396>>2],f[e+340>>2]=f[t+400>>2],f[e+456>>2]=f[t+404>>2],f[e+344>>2]=f[t+604>>2],f[e+348>>2]=f[t+608>>2],f[e+352>>2]=f[t+612>>2],f[e+356>>2]=f[t+616>>2],f[e+360>>2]=f[t+408>>2],f[e+364>>2]=f[t+412>>2],f[e+368>>2]=f[t+416>>2],f[e+372>>2]=f[t+420>>2],f[e+376>>2]=f[t+424>>2],f[e+380>>2]=f[t+428>>2],f[e+384>>2]=f[t+432>>2],f[e+388>>2]=f[t+436>>2],f[e+392>>2]=f[t+440>>2],f[e+396>>2]=f[t+444>>2],f[e+400>>2]=f[t+448>>2],f[e+404>>2]=f[t+452>>2],f[e+408>>2]=f[t+456>>2],f[e+412>>2]=f[t+460>>2],f[e+416>>2]=f[t+464>>2],f[e+420>>2]=f[t+468>>2],f[e+424>>2]=f[t+472>>2],f[e+428>>2]=f[t+476>>2],f[e+432>>2]=f[t+480>>2],f[e+436>>2]=f[t+484>>2],f[e+440>>2]=f[t+488>>2],f[e+444>>2]=f[t+492>>2],f[e+448>>2]=f[t+496>>2],f[e+452>>2]=f[t+500>>2],i=f[t+508>>2],f[e+460>>2]=f[t+504>>2],f[e+464>>2]=i,i=f[t+520>>2],f[e+468>>2]=f[t+516>>2],f[e+472>>2]=i,i=f[t+528>>2],f[e+476>>2]=f[t+524>>2],f[e+480>>2]=i,i=f[t+536>>2],f[e+484>>2]=f[t+532>>2],f[e+488>>2]=i,f[e+492>>2]=_[t+512|0],20124},function(t,e){var i,r,n=0,a=0,o=0,_=0;a=e|=0,o=0|yt[f[f[(t|=0)>>2]+16>>2]](t),_=1,n=f[f[e>>2]+16>>2],r=0|yt[n](0|a,0|o,0|_),_=e,o=r,a=0|yt[f[f[t>>2]+20>>2]](t,f[r+8>>2],e),i=t,n=f[f[e>>2]+20>>2],yt[n](0|_,0|o,0|a,1497645650,0|i)},function(t,e,i){t|=0,e|=0,i|=0;var r=v(0),n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0);return o=C[i+100>>2],_=C[i+16>>2],h=C[i+20>>2],d=C[i+24>>2],n=C[i+108>>2],r=v(v(v(C[i+112>>2]-v(o*C[i+116>>2]))-v(v(v(v(v(_*C[t+64>>2])+v(h*C[t+68>>2]))+v(d*C[t+72>>2]))+v(v(v(C[i>>2]*C[t+80>>2])+v(C[i+4>>2]*C[t+84>>2]))+v(C[i+8>>2]*C[t+88>>2])))*n))-v(n*v(v(v(v(C[i+48>>2]*C[e+64>>2])+v(C[i+52>>2]*C[e+68>>2]))+v(C[i+56>>2]*C[e+72>>2]))+v(v(v(C[i+32>>2]*C[e+80>>2])+v(C[i+36>>2]*C[e+84>>2]))+v(C[i+40>>2]*C[e+88>>2]))))),(n=v(o+r))<(a=C[i+120>>2])?(r=v(a-o),n=a):n>(a=C[i+124>>2])&&(r=v(a-o),n=a),C[i+100>>2]=n,f[t+240>>2]&&(C[t+64>>2]=v(C[t+112>>2]*v(r*v(_*C[t+128>>2])))+C[t+64>>2],C[t+68>>2]=v(v(r*v(h*C[t+132>>2]))*C[t+116>>2])+C[t+68>>2],C[t+72>>2]=v(v(r*v(d*C[t+136>>2]))*C[t+120>>2])+C[t+72>>2],n=C[i+72>>2],a=C[i+68>>2],C[t+80>>2]=v(v(r*C[t+96>>2])*C[i+64>>2])+C[t+80>>2],o=C[t+104>>2],C[t+84>>2]=v(a*v(r*C[t+100>>2]))+C[t+84>>2],C[t+88>>2]=v(n*v(r*o))+C[t+88>>2]),f[e+240>>2]&&(n=C[i+56>>2],a=C[i+52>>2],C[e+64>>2]=v(C[e+112>>2]*v(r*v(C[i+48>>2]*C[e+128>>2])))+C[e+64>>2],C[e+68>>2]=v(v(r*v(a*C[e+132>>2]))*C[e+116>>2])+C[e+68>>2],C[e+72>>2]=v(v(r*v(n*C[e+136>>2]))*C[e+120>>2])+C[e+72>>2],n=C[i+88>>2],a=C[i+84>>2],C[e+80>>2]=v(v(r*C[e+96>>2])*C[i+80>>2])+C[e+80>>2],o=C[e+104>>2],C[e+84>>2]=v(a*v(r*C[e+100>>2]))+C[e+84>>2],C[e+88>>2]=v(n*v(r*o))+C[e+88>>2]),v(r)},function(t,e,i){t|=0,e|=0,i|=0;var r,n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0);return n=C[i+100>>2],_=C[i+16>>2],h=C[i+20>>2],d=C[i+24>>2],a=C[i+108>>2],a=v(v(v(C[i+112>>2]-v(n*C[i+116>>2]))-v(v(v(v(v(_*C[t+64>>2])+v(h*C[t+68>>2]))+v(d*C[t+72>>2]))+v(v(v(C[i>>2]*C[t+80>>2])+v(C[i+4>>2]*C[t+84>>2]))+v(C[i+8>>2]*C[t+88>>2])))*a))-v(a*v(v(v(v(C[i+48>>2]*C[e+64>>2])+v(C[i+52>>2]*C[e+68>>2]))+v(C[i+56>>2]*C[e+72>>2]))+v(v(v(C[i+32>>2]*C[e+80>>2])+v(C[i+36>>2]*C[e+84>>2]))+v(C[i+40>>2]*C[e+88>>2]))))),r=(g=v(n+a))<(o=C[i+120>>2]),C[i+100>>2]=r?o:g,n=r?v(o-n):a,f[t+240>>2]&&(C[t+64>>2]=v(C[t+112>>2]*v(n*v(_*C[t+128>>2])))+C[t+64>>2],C[t+68>>2]=v(v(n*v(h*C[t+132>>2]))*C[t+116>>2])+C[t+68>>2],C[t+72>>2]=v(v(n*v(d*C[t+136>>2]))*C[t+120>>2])+C[t+72>>2],a=C[i+72>>2],o=C[i+68>>2],C[t+80>>2]=v(v(n*C[t+96>>2])*C[i+64>>2])+C[t+80>>2],_=C[t+104>>2],C[t+84>>2]=v(o*v(n*C[t+100>>2]))+C[t+84>>2],C[t+88>>2]=v(a*v(n*_))+C[t+88>>2]),f[e+240>>2]&&(a=C[i+56>>2],o=C[i+52>>2],C[e+64>>2]=v(C[e+112>>2]*v(n*v(C[i+48>>2]*C[e+128>>2])))+C[e+64>>2],C[e+68>>2]=v(v(n*v(o*C[e+132>>2]))*C[e+116>>2])+C[e+68>>2],C[e+72>>2]=v(v(n*v(a*C[e+136>>2]))*C[e+120>>2])+C[e+72>>2],a=C[i+88>>2],o=C[i+84>>2],C[e+80>>2]=v(v(n*C[e+96>>2])*C[i+80>>2])+C[e+80>>2],_=C[e+104>>2],C[e+84>>2]=v(o*v(n*C[e+100>>2]))+C[e+84>>2],C[e+88>>2]=v(a*v(n*_))+C[e+88>>2]),v(n)},function(t,e,i){t|=0,e|=0,i|=0;var r=v(0),n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=0;return(n=C[i+128>>2])!=v(0)&&(f[700]=f[700]+1,r=C[i+96>>2],a=v(n-v(r*C[i+116>>2])),o=C[i+16>>2],_=C[i+20>>2],h=C[i+24>>2],n=C[i+108>>2],n=v(v(a-v(v(v(v(v(o*C[t+144>>2])+v(_*C[t+148>>2]))+v(h*C[t+152>>2]))+v(v(v(C[i>>2]*C[t+160>>2])+v(C[i+4>>2]*C[t+164>>2]))+v(C[i+8>>2]*C[t+168>>2])))*n))-v(n*v(v(v(v(C[i+48>>2]*C[e+144>>2])+v(C[i+52>>2]*C[e+148>>2]))+v(C[i+56>>2]*C[e+152>>2]))+v(v(v(C[i+32>>2]*C[e+160>>2])+v(C[i+36>>2]*C[e+164>>2]))+v(C[i+40>>2]*C[e+168>>2]))))),g=(d=v(r+n))<(a=C[i+120>>2]),C[i+96>>2]=g?a:d,r=g?v(a-r):n,f[t+240>>2]&&(C[t+144>>2]=v(C[t+112>>2]*v(r*v(o*C[t+128>>2])))+C[t+144>>2],C[t+148>>2]=v(v(r*v(_*C[t+132>>2]))*C[t+116>>2])+C[t+148>>2],C[t+152>>2]=v(v(r*v(h*C[t+136>>2]))*C[t+120>>2])+C[t+152>>2],n=C[i+72>>2],a=C[i+68>>2],C[t+160>>2]=v(v(r*C[t+96>>2])*C[i+64>>2])+C[t+160>>2],o=C[t+104>>2],C[t+164>>2]=v(a*v(r*C[t+100>>2]))+C[t+164>>2],C[t+168>>2]=v(n*v(r*o))+C[t+168>>2]),f[e+240>>2]&&(n=C[i+56>>2],a=C[i+52>>2],C[e+144>>2]=v(C[e+112>>2]*v(r*v(C[i+48>>2]*C[e+128>>2])))+C[e+144>>2],C[e+148>>2]=v(v(r*v(a*C[e+132>>2]))*C[e+116>>2])+C[e+148>>2],C[e+152>>2]=v(v(r*v(n*C[e+136>>2]))*C[e+120>>2])+C[e+152>>2],n=C[i+88>>2],a=C[i+84>>2],C[e+160>>2]=v(v(r*C[e+96>>2])*C[i+80>>2])+C[e+160>>2],o=C[e+104>>2],C[e+164>>2]=v(a*v(r*C[e+100>>2]))+C[e+164>>2],C[e+168>>2]=v(n*v(r*o))+C[e+168>>2])),v(r)},qi,function(t){CA(qi(t|=0))},De,function(t,e,i,r,n,a,o,_,h,d){return t|=0,e|=0,i|=0,r|=0,n|=0,a|=0,o|=0,_|=0,h|=0,d|=0,Z=d=Z-16|0,Lr(d+8|0,20295),v(yt[f[f[t>>2]+44>>2]](t,e,i,r,n,a,o,_,h)),v(yt[f[f[t>>2]+48>>2]](t,e,i,r,n,a,o,_,h)),v(yt[f[f[t>>2]+36>>2]](t,e,i,_)),qr(),Z=d+16|0,v(v(0))},De,function(t){f[(t|=0)+232>>2]=0},We,function(t,e,i,r){if(t|=0,e|=0,r|=0,(0|(i|=0))>=1)for(;nf(t,f[e>>2],r),e=e+4|0,i=i+-1|0;);},function(t,e,i,r,n,a,o,_,h){t|=0,e|=0,i|=0,r|=0,n|=0,a|=0,_|=0;var d=v(0),g=v(0);t:if(!(!f[_+52>>2]|f[_+20>>2]<1))for(e=0;;){if(d=v(0),(0|(r=f[t+28>>2]))>=1)for(i=0;g=d,a=f[t+16>>2],n=f[t+36>>2]+m(f[f[t+116>>2]+i>>2],152)|0,d=v(yt[f[t+220>>2]](a+m(f[n+144>>2],244)|0,m(f[n+148>>2],244)+a|0,n)),d=v(g+v(d*d)),i=i+4|0,r=r+-1|0;);if(d<=C[_+92>>2])break t;if((0|e)>=((i=f[_+20>>2])+-1|0))break t;if(!((0|(e=e+1|0))<(0|i)))break}},function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var a=0,o=0,h=0,d=v(0),g=v(0),p=0,R=v(0),D=v(0),B=v(0),E=v(0),F=0,V=0;if(4&(a=f[r+72>>2])&&!((0|(h=f[t+28>>2]))<1))if(i=f[t+76>>2],e=f[t+36>>2],16&a)for(e=e+140|0;a=f[e+-8>>2],f[a+124>>2]=f[e+-40>>2],o=i+m(f[e>>2],152)|0,f[a+128>>2]=f[o+100>>2],f[a+132>>2]=f[o+252>>2],e=e+152|0,h=h+-1|0;);else for(e=e+140|0;a=f[e+-8>>2],f[a+124>>2]=f[e+-40>>2],f[a+128>>2]=f[100+(i+m(f[e>>2],152)|0)>>2],e=e+152|0,h=h+-1|0;);if((0|(p=f[t+48>>2]))>=1)for(a=100;i=f[t+56>>2]+a|0,h=f[i+32>>2],(e=f[h+44>>2])&&(o=f[h+28>>2],R=C[o+416>>2],D=C[i+-76>>2],B=C[o+412>>2],E=C[i+-80>>2],d=C[i>>2],g=v(v(1)/C[r+12>>2]),C[e>>2]=C[e>>2]+v(v(v(C[i+-84>>2]*d)*C[o+408>>2])*g),C[e+4>>2]=v(v(B*v(d*E))*g)+C[e+4>>2],C[e+8>>2]=v(v(R*v(d*D))*g)+C[e+8>>2],F=f[h+32>>2],R=C[F+416>>2],D=C[i+-44>>2],B=C[F+412>>2],E=C[i+-48>>2],d=C[i>>2],g=v(v(1)/C[r+12>>2]),C[e+32>>2]=C[e+32>>2]+v(v(v(C[i+-52>>2]*d)*C[F+408>>2])*g),C[(V=e+36|0)>>2]=v(v(B*v(d*E))*g)+C[V>>2],C[(V=e+40|0)>>2]=v(v(R*v(d*D))*g)+C[V>>2],R=C[o+612>>2],D=C[i+-92>>2],B=C[o+608>>2],E=C[i+-96>>2],d=C[i>>2],g=v(v(1)/C[r+12>>2]),C[e+16>>2]=C[e+16>>2]+v(v(v(C[i+-100>>2]*C[o+604>>2])*d)*g),C[(o=e+20|0)>>2]=v(v(d*v(E*B))*g)+C[o>>2],C[(o=e+24|0)>>2]=v(v(d*v(D*R))*g)+C[o>>2],R=C[F+612>>2],D=C[i+-60>>2],B=C[F+608>>2],E=C[i+-64>>2],d=C[i>>2],g=v(v(1)/C[r+12>>2]),C[e+48>>2]=C[e+48>>2]+v(v(v(C[i+-68>>2]*C[F+604>>2])*d)*g),C[(o=e+52|0)>>2]=v(v(d*v(E*B))*g)+C[o>>2],C[(e=e+56|0)>>2]=v(v(d*v(D*R))*g)+C[e>>2]),d=C[i>>2],C[h+36>>2]=d,v(y(d))>=C[h+16>>2]&&(n[h+20|0]=0),a=a+152|0,p=p+-1|0;);if((0|(a=f[t+8>>2]))>=1)for(o=f[t+16>>2],e=176,F=0;(h=f[(i=e+o|0)- -64>>2])&&(f[r+52>>2]?(af(i+-176|0,C[r+12>>2],C[r+60>>2]),o=f[t+16>>2],R=C[(i=o+e|0)>>2],d=C[i+8>>2],g=C[i+4>>2],h=f[i- -64>>2]):(R=v(C[i+-112>>2]+C[i>>2]),C[i>>2]=R,a=i+4|0,g=v(C[i+-108>>2]+C[a>>2]),C[a>>2]=g,a=i+8|0,d=v(C[i+-104>>2]+C[a>>2]),C[a>>2]=d,C[(a=i+16|0)>>2]=C[i+-96>>2]+C[a>>2],C[(a=i+20|0)>>2]=C[i+-92>>2]+C[a>>2],C[(a=i+24|0)>>2]=C[i+-88>>2]+C[a>>2]),D=C[(i=e+o|0)+32>>2],B=C[i+36>>2],E=C[i+40>>2],f[h+384>>2]=0,C[h+380>>2]=d+E,C[h+376>>2]=g+B,C[h+372>>2]=R+D,f[h+304>>2]=f[h+304>>2]+1,i=f[t+16>>2]+e|0,d=C[i+16>>2],g=C[i+48>>2],R=C[i+20>>2],D=C[i+52>>2],B=C[i+24>>2],E=C[i+56>>2],i=f[i- -64>>2],f[i+400>>2]=0,C[i+396>>2]=B+E,C[i+392>>2]=R+D,C[i+388>>2]=d+g,f[i+304>>2]=f[i+304>>2]+1,f[r+52>>2]&&(h=f[t+16>>2]+e|0,i=f[h- -64>>2],f[i+304>>2]=f[i+304>>2]+1,V=f[(p=(a=h+-176|0)+8|0)+4>>2],f[(o=i+12|0)>>2]=f[p>>2],f[o+4>>2]=V,o=f[a+4>>2],f[i+4>>2]=f[a>>2],f[i+8>>2]=o,V=f[(p=(a=h+-160|0)+8|0)+4>>2],f[(o=i+28|0)>>2]=f[p>>2],f[o+4>>2]=V,p=f[a+4>>2],f[(o=i+20|0)>>2]=f[a>>2],f[o+4>>2]=p,p=f[(a=h+-144|0)+4>>2],f[(o=i+36|0)>>2]=f[a>>2],f[o+4>>2]=p,p=f[(a=a+8|0)+4>>2],f[(o=i+44|0)>>2]=f[a>>2],f[o+4>>2]=p,p=f[(o=(h=h+-128|0)+8|0)+4>>2],f[(a=i+60|0)>>2]=f[o>>2],f[a+4>>2]=p,a=f[h+4>>2],f[(i=i+52|0)>>2]=f[h>>2],f[i+4>>2]=a),o=f[t+16>>2],f[f[(o+e|0)- -64>>2]+212>>2]=-1,a=f[t+8>>2]),e=e+244|0,(0|(F=F+1|0))<(0|a););return f[t+28>>2]>-1|f[t+32>>2]>-1||((e=f[t+36>>2])&&(_[t+40|0]&&CA(e),f[t+36>>2]=0),f[t+32>>2]=0,f[t+36>>2]=0,n[t+40|0]=1),f[t+28>>2]=0,f[t+48>>2]>-1|f[t+52>>2]>-1||((e=f[t+56>>2])&&(_[t+60|0]&&CA(e),f[t+56>>2]=0),f[t+52>>2]=0,f[t+56>>2]=0,n[t+60|0]=1),f[t+48>>2]=0,f[t+68>>2]>-1|f[t+72>>2]>-1||((e=f[t+76>>2])&&(_[t+80|0]&&CA(e),f[t+76>>2]=0),f[t+72>>2]=0,f[t+76>>2]=0,n[t+80|0]=1),f[t+68>>2]=0,f[t+88>>2]>-1|f[t+92>>2]>-1||((e=f[t+96>>2])&&(_[t+100|0]&&CA(e),f[t+96>>2]=0),f[t+92>>2]=0,f[t+96>>2]=0,n[t+100|0]=1),f[t+88>>2]=0,f[t+8>>2]>-1|f[t+12>>2]>-1||((e=f[t+16>>2])&&(_[t+20|0]&&CA(e),f[t+16>>2]=0),f[t+12>>2]=0,f[t+16>>2]=0,n[t+20|0]=1),f[t+8>>2]=0,v(v(0))},function(t,e,i,r,a,o,h,d,g,y){t|=0,e|=0,i|=0,r|=0,a|=0,o|=0,h|=0,d|=0,g|=0,y|=0;var p=v(0),R=v(0),D=0,B=v(0),E=0,F=0,V=0,G=0,w=0,Q=0;if(1&n[g+72|0]){if(V=f[t+68>>2],E=f[t+28>>2],(0|(F=f[t+48>>2]))>=1){if(i=m(f[t+232>>2],1664525)+1013904223|0,1!=(0|F)&&(y=f[t+136>>2],r=f[y+4>>2],a=(i=m(i,1664525)+1013904223|0)^i>>>16,a^=a>>>8,a^=a>>>4,a=y+((1&((a^=a>>>2)>>>1^a))<<2)|0,f[y+4>>2]=f[a>>2],f[a>>2]=r,2!=(0|F)&&(r=f[y+8>>2],a=(i=m(i,1664525)+1013904223|0)^i>>>16,a^=a>>>8,a=y+((((a^=a>>>4)>>>2^a)>>>0)%3<<2)|0,f[y+8>>2]=f[a>>2],f[a>>2]=r,3!=(0|F)&&(r=f[y+12>>2],a=(i=m(i,1664525)+1013904223|0)^i>>>16,a^=a>>>8,a=y+((3&((a^=a>>>4)>>>2^a))<<2)|0,f[y+12>>2]=f[a>>2],f[a>>2]=r,4!=(0|F)))))for(o=y+16|0,r=4;Q=f[o>>2],G=o,w=y,D=i=m(i,1664525)+1013904223|0,(r=r+1|0)>>>0>65536||(D=a=i>>>16^i,r>>>0>256||(D=a^=a>>>8,r>>>0>16||(D=a>>>4^a))),a=w+((D>>>0)%(r>>>0)<<2)|0,f[G>>2]=f[a>>2],f[a>>2]=Q,o=o+4|0,(0|r)!=(0|F););f[t+232>>2]=i}if(!(f[g+20>>2]<=(0|e))){if((0|E)>=1){if(i=m(f[t+232>>2],1664525)+1013904223|0,1!=(0|E)&&(y=f[t+116>>2],r=f[y+4>>2],a=(i=m(i,1664525)+1013904223|0)^i>>>16,a^=a>>>8,a^=a>>>4,a=y+((1&((a^=a>>>2)>>>1^a))<<2)|0,f[y+4>>2]=f[a>>2],f[a>>2]=r,2!=(0|E)&&(r=f[y+8>>2],a=(i=m(i,1664525)+1013904223|0)^i>>>16,a^=a>>>8,a=y+((((a^=a>>>4)>>>2^a)>>>0)%3<<2)|0,f[y+8>>2]=f[a>>2],f[a>>2]=r,3!=(0|E)&&(r=f[y+12>>2],a=(i=m(i,1664525)+1013904223|0)^i>>>16,a^=a>>>8,a=y+((3&((a^=a>>>4)>>>2^a))<<2)|0,f[y+12>>2]=f[a>>2],f[a>>2]=r,4!=(0|E)))))for(o=y+16|0,r=4;F=f[o>>2],G=o,w=y,D=i=m(i,1664525)+1013904223|0,(r=r+1|0)>>>0>65536||(D=a=i>>>16^i,r>>>0>256||(D=a^=a>>>8,r>>>0>16||(D=a>>>4^a))),a=w+((D>>>0)%(r>>>0)<<2)|0,f[G>>2]=f[a>>2],f[a>>2]=F,o=o+4|0,(0|r)!=(0|E););f[t+232>>2]=i}if(!((0|V)<1)){if(i=m(f[t+232>>2],1664525)+1013904223|0,1!=(0|V)&&(y=f[t+156>>2],r=f[y+4>>2],a=(i=m(i,1664525)+1013904223|0)^i>>>16,a^=a>>>8,a^=a>>>4,a=y+((1&((a^=a>>>2)>>>1^a))<<2)|0,f[y+4>>2]=f[a>>2],f[a>>2]=r,2!=(0|V)&&(r=f[y+8>>2],a=(i=m(i,1664525)+1013904223|0)^i>>>16,a^=a>>>8,a=y+((((a^=a>>>4)>>>2^a)>>>0)%3<<2)|0,f[y+8>>2]=f[a>>2],f[a>>2]=r,3!=(0|V)&&(r=f[y+12>>2],a=(i=m(i,1664525)+1013904223|0)^i>>>16,a^=a>>>8,a=y+((3&((a^=a>>>4)>>>2^a))<<2)|0,f[y+12>>2]=f[a>>2],f[a>>2]=r,4!=(0|V)))))for(o=y+16|0,r=4;E=f[o>>2],G=o,w=y,D=i=m(i,1664525)+1013904223|0,(r=r+1|0)>>>0>65536||(D=a=i>>>16^i,r>>>0>256||(D=a^=a>>>8,r>>>0>16||(D=a>>>4^a))),a=w+((D>>>0)%(r>>>0)<<2)|0,f[G>>2]=f[a>>2],f[a>>2]=E,o=o+4|0,(0|r)!=(0|V););f[t+232>>2]=i}}}if((0|(a=f[t+48>>2]))>=1)for(i=0,o=0;r=f[t+56>>2]+m(f[f[t+136>>2]+i>>2],152)|0,f[r+136>>2]>(0|e)&&(R=p,a=f[t+16>>2],p=v(yt[f[t+212>>2]](a+m(f[r+144>>2],244)|0,a+m(f[r+148>>2],244)|0,r)),p=v(R+v(p*p)),a=f[t+48>>2]),i=i+4|0,(0|(o=o+1|0))<(0|a););if(!(f[g+20>>2]<=(0|e))){if((0|d)>=1)for(;e=f[h>>2],_[e+20|0]&&(e=ef(t,f[e+28>>2],C[g+12>>2]),i=ef(t,f[f[h>>2]+32>>2],C[g+12>>2]),r=f[h>>2],a=m(e,244),e=f[t+16>>2],yt[f[f[r>>2]+24>>2]](r,a+e|0,e+m(i,244)|0,C[g+12>>2])),h=h+4|0,d=d+-1|0;);i=f[t+28>>2];t:if(512&(e=f[g+72>>2])){if(!((0|i)<1))for(r=(16&e?2:1)<<2,o=0,h=0;R=p,a=f[t+16>>2],e=f[t+36>>2]+m(f[f[t+116>>2]+h>>2],152)|0,p=v(yt[f[t+216>>2]](a+m(f[e+144>>2],244)|0,a+m(f[e+148>>2],244)|0,e)),p=v(R+v(p*p)),(a=(R=C[e+100>>2])>v(0)^1)||(e=f[t+76>>2]+m(f[f[t+156>>2]+o>>2],152)|0,B=v(R*C[e+104>>2]),C[e+124>>2]=B,C[e+120>>2]=-B,B=p,d=f[t+16>>2],p=v(yt[f[t+212>>2]](d+m(f[e+144>>2],244)|0,d+m(f[e+148>>2],244)|0,e)),p=v(B+v(p*p))),a|!(16&_[g+72|0])||(e=f[t+76>>2]+m(f[4+(f[t+156>>2]+o|0)>>2],152)|0,R=v(R*C[e+104>>2]),C[e+124>>2]=R,C[e+120>>2]=-R,R=p,a=f[t+16>>2],p=v(yt[f[t+212>>2]](a+m(f[e+144>>2],244)|0,a+m(f[e+148>>2],244)|0,e)),p=v(R+v(p*p))),o=r+o|0,h=h+4|0,i=i+-1|0;);}else{if((0|i)>=1)for(r=0;R=p,a=f[t+16>>2],e=f[t+36>>2]+m(f[f[t+116>>2]+r>>2],152)|0,p=v(yt[f[t+216>>2]](a+m(f[e+144>>2],244)|0,a+m(f[e+148>>2],244)|0,e)),p=v(R+v(p*p)),r=r+4|0,i=i+-1|0;);if((0|(h=f[t+68>>2]))<1)break t;for(r=0;e=f[t+76>>2]+m(f[f[t+156>>2]+r>>2],152)|0,(R=C[100+(f[t+36>>2]+m(f[e+140>>2],152)|0)>>2])>v(0)&&(R=v(R*C[e+104>>2]),C[e+124>>2]=R,C[e+120>>2]=-R,R=p,i=f[t+16>>2],p=v(yt[f[t+212>>2]](i+m(f[e+144>>2],244)|0,i+m(f[e+148>>2],244)|0,e)),p=v(R+v(p*p))),r=r+4|0,h=h+-1|0;);}if(!((0|(h=f[t+88>>2]))<1))for(r=0;e=f[t+96>>2]+r|0,(R=C[100+(f[t+36>>2]+m(f[e+140>>2],152)|0)>>2])>v(0)&&(B=R,R=C[e+104>>2],R=(B=v(B*R))>R?R:B,C[e+124>>2]=R,C[e+120>>2]=-R,R=p,i=f[t+16>>2],p=v(yt[f[t+212>>2]](i+m(f[e+144>>2],244)|0,i+m(f[e+148>>2],244)|0,e)),p=v(R+v(p*p))),r=r+152|0,h=h+-1|0;);}return v(p)},function(t,e,i,r,a,o,h,d,g){t|=0,e|=0,i|=0,r|=0,a|=0,o|=0,h|=0,d|=0,g|=0;var p=0,R=0,D=0,B=0,E=0,F=0,V=0,G=0,w=v(0),Q=0,W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=v(0),St=0,Tt=v(0),Et=v(0),Ot=v(0),Nt=0,Ft=v(0),Vt=v(0),Gt=v(0),Lt=v(0),wt=v(0),xt=0,Qt=v(0),Wt=v(0),Yt=0,Pt=0,Mt=v(0),Zt=0,Ut=v(0),Xt=v(0),Jt=v(0),jt=v(0),zt=v(0),Ht=v(0),Kt=v(0),qt=0,$t=0,bi=0,di=0,yi=0,Ii=0,Bi=0,BA=0,gr=v(0),tn=v(0),en=v(0),An=v(0),rn=v(0),nn=v(0),an=v(0),on=v(0),sn=v(0),ln=v(0),fn=v(0),cn=v(0);if(Z=St=Z-256|0,f[t+188>>2]=-1,Lr(St+248|0,20232),(0|(g=f[d+72>>2]))!=f[t+224>>2]&&(f[t+224>>2]=g,f[t+220>>2]=536,f[t+216>>2]=535,f[t+212>>2]=534),f[t+184>>2]=0,(0|i)>=1)for(g=e,D=i;f[f[g>>2]+212>>2]=-1,g=g+4|0,D=D+-1|0;);if((0|(g=f[t+12>>2]))<=(0|i)){if(D=0,(g=i+1|0)&&(D=dA(m(g,244))),(0|(p=f[t+8>>2]))>=1)for(R=64;F=f[t+16>>2]+R|0,Q=f[(G=F+-64|0)+4>>2],f[(B=V=(E=R+D|0)+-64|0)>>2]=f[G>>2],f[B+4>>2]=Q,B=f[(G=G+8|0)+4>>2],f[(V=V+8|0)>>2]=f[G>>2],f[V+4>>2]=B,Nt=f[(Q=(V=F+-48|0)+8|0)+4>>2],f[(B=(G=E+-48|0)+8|0)>>2]=f[Q>>2],f[B+4>>2]=Nt,B=f[V+4>>2],f[G>>2]=f[V>>2],f[G+4>>2]=B,Nt=f[(Q=(V=F+-32|0)+8|0)+4>>2],f[(B=(G=E+-32|0)+8|0)>>2]=f[Q>>2],f[B+4>>2]=Nt,B=f[V+4>>2],f[G>>2]=f[V>>2],f[G+4>>2]=B,Q=f[(G=F+-16|0)+4>>2],f[(B=V=E+-16|0)>>2]=f[G>>2],f[B+4>>2]=Q,B=f[(G=G+8|0)+4>>2],f[(V=V+8|0)>>2]=f[G>>2],f[V+4>>2]=B,J(E,F,180),R=R+244|0,p=p+-1|0;);(p=f[t+16>>2])&&(_[t+20|0]&&CA(p),f[t+16>>2]=0),f[t+16>>2]=D,f[t+12>>2]=g,n[t+20|0]=1}if(E=X(St,0,244),(0|(D=f[t+8>>2]))<=-1)for((0|g)<=-1&&((g=f[t+16>>2])&&(_[t+20|0]&&CA(g),f[t+16>>2]=0),f[t+12>>2]=0,f[t+16>>2]=0,n[t+20|0]=1),R=m(D,244),V=E- -64|0,St=E+48|0,G=E+32|0,p=E+16|0;g=f[E+4>>2],F=f[t+16>>2]+R|0,f[F>>2]=f[E>>2],f[F+4>>2]=g,Q=f[(B=E+8|0)+4>>2],f[(g=F+8|0)>>2]=f[B>>2],f[g+4>>2]=Q,Q=f[(g=p)+4>>2],f[(B=F+16|0)>>2]=f[g>>2],f[B+4>>2]=Q,Q=f[(g=g+8|0)+4>>2],f[(B=F+24|0)>>2]=f[g>>2],f[B+4>>2]=Q,B=f[G+4>>2],f[(g=F+32|0)>>2]=f[G>>2],f[g+4>>2]=B,Q=f[(B=G+8|0)+4>>2],f[(g=F+40|0)>>2]=f[B>>2],f[g+4>>2]=Q,B=f[St+4>>2],f[(g=F+48|0)>>2]=f[St>>2],f[g+4>>2]=B,Q=f[(B=St+8|0)+4>>2],f[(g=F+56|0)>>2]=f[B>>2],f[g+4>>2]=Q,J(F- -64|0,V,180),R=R+244|0,F=(g=D+1|0)>>>0>=D>>>0,D=g,F;);if(f[t+8>>2]=0,(0|i)>=1)for(;D=ef(t,f[e>>2],C[d+12>>2]),!(g=f[e>>2])|!(2&f[g+252>>2])|C[g+404>>2]==v(0)||(p=f[t+16>>2],2&(R=f[g+564>>2])&&(Oi(E,g,C[d+84>>2]),z=C[g+364>>2],pt=C[g+332>>2],Ft=C[g+348>>2],Et=C[g+360>>2],Tt=C[g+328>>2],Ot=C[g+344>>2],R=p+m(D,244)|0,w=C[E>>2],W=C[E+4>>2],Dt=C[E+8>>2],Y=C[d+12>>2],C[R+224>>2]=C[R+224>>2]-v(v(v(v(w*C[g+324>>2])+v(W*C[g+340>>2]))+v(Dt*C[g+356>>2]))*Y),C[(F=R+228|0)>>2]=C[F>>2]-v(Y*v(v(v(w*Tt)+v(W*Ot))+v(Dt*Et))),C[(R=R+232|0)>>2]=C[R>>2]-v(Y*v(v(v(w*pt)+v(W*Ft))+v(Dt*z))),R=f[g+564>>2]),4&R&&(zi(E,g,C[d+12>>2]),w=C[E+8>>2],W=C[E+4>>2],R=p+m(D,244)|0,C[R+224>>2]=C[E>>2]+C[R+224>>2],C[(F=R+228|0)>>2]=W+C[F>>2],C[(R=R+232|0)>>2]=w+C[R>>2],R=f[g+564>>2]),8&R&&(Hi(E,g,C[d+12>>2]),w=C[E+8>>2],W=C[E+4>>2],g=p+m(D,244)|0,C[g+224>>2]=C[E>>2]+C[g+224>>2],C[(D=g+228|0)>>2]=W+C[D>>2],C[(g=g+232|0)>>2]=w+C[g>>2])),e=e+4|0,i=i+-1|0;);if((0|h)>=1)for(g=o,D=h;e=f[g>>2],yt[f[f[e>>2]+8>>2]](e),f[e+36>>2]=0,g=g+4|0,D=D+-1|0;);if(!((0|(e=f[t+168>>2]))>=(0|h)|f[t+172>>2]>=(0|h))){if(h?(D=dA(h<<3),e=f[t+168>>2]):D=0,(0|e)>=1)for(g=0;p=f[t+176>>2]+g|0,R=f[p+4>>2],f[(i=g+D|0)>>2]=f[p>>2],f[i+4>>2]=R,g=g+8|0,e=e+-1|0;);(e=f[t+176>>2])&&(_[t+180|0]&&CA(e),f[t+176>>2]=0),f[t+176>>2]=D,f[t+172>>2]=h,n[t+180|0]=1}if(f[t+168>>2]=h,(0|h)<1)R=0;else for(i=0,D=o,p=h,R=0;F=f[t+176>>2],e=f[D>>2],(g=f[e+44>>2])&&(f[g>>2]=0,f[g+4>>2]=0,f[(e=g+56|0)>>2]=0,f[e+4>>2]=0,f[(e=g+48|0)>>2]=0,f[e+4>>2]=0,f[(e=g+40|0)>>2]=0,f[e+4>>2]=0,f[(e=g+32|0)>>2]=0,f[e+4>>2]=0,f[(e=g+24|0)>>2]=0,f[e+4>>2]=0,f[(e=g+16|0)>>2]=0,f[e+4>>2]=0,f[(e=g+8|0)>>2]=0,f[e+4>>2]=0,e=f[D>>2]),g=i+F|0,i=i+8|0,D=D+4|0,_[e+20|0]?(yt[f[f[e>>2]+16>>2]](e,g),e=f[g>>2]):(f[g>>2]=0,f[g+4>>2]=0,e=0),R=e+R|0,p=p+-1|0;);if(!((0|(e=f[t+48>>2]))>=(0|R)|f[t+52>>2]>=(0|R))){if(R?(D=dA(m(R,152)),e=f[t+48>>2]):D=0,(0|e)>=1)for(g=0;J(g+D|0,f[t+56>>2]+g|0,152),g=g+152|0,e=e+-1|0;);(e=f[t+56>>2])&&(_[t+60|0]&&CA(e),f[t+56>>2]=0),f[t+56>>2]=D,f[t+52>>2]=R,n[t+60|0]=1}if(f[t+48>>2]=R,(0|h)>=1)for(g=f[t+176>>2],St=0,V=0;;){if(qt=V,f[(G=(Zt=St<<3)+g|0)>>2]){if(F=f[(B=(St<<2)+o|0)>>2],D=f[F+32>>2],Q=f[t+56>>2],R=ef(t,p=f[F+28>>2],C[d+12>>2]),Nt=ef(t,D,C[d+12>>2]),Yt=m(V,152),Pt=f[t+16>>2],(0|(xt=(0|(e=f[F+24>>2]))>0?e:f[d+20>>2]))>f[t+184>>2]&&(f[t+184>>2]=xt),e=Q+Yt|0,f[G>>2]>=1)for(i=0,g=e;g=X(g,0,152),f[(V=g+120|0)>>2]=-8388609,f[V+4>>2]=2139095039,f[g+148>>2]=Nt,f[g+144>>2]=R,f[(V=g+96|0)>>2]=0,f[V+4>>2]=0,f[g+136>>2]=xt,g=g+152|0,(0|(i=i+1|0))>2];);if(i=Pt+m(R,244)|0,f[(g=i)+144>>2]=0,f[g+148>>2]=0,f[(g=g+152|0)>>2]=0,f[g+4>>2]=0,f[(g=i+160|0)>>2]=0,f[g+4>>2]=0,f[(g=i+168|0)>>2]=0,f[g+4>>2]=0,f[i+64>>2]=0,f[i+68>>2]=0,f[(g=i+88|0)>>2]=0,f[g+4>>2]=0,f[(g=i+80|0)>>2]=0,f[g+4>>2]=0,f[(g=i+72|0)>>2]=0,f[g+4>>2]=0,R=Pt+m(Nt,244)|0,f[(g=R)+144>>2]=0,f[g+148>>2]=0,f[(g=g+152|0)>>2]=0,f[g+4>>2]=0,f[(g=R+160|0)>>2]=0,f[g+4>>2]=0,f[(g=R+168|0)>>2]=0,f[g+4>>2]=0,f[R+64>>2]=0,f[R+68>>2]=0,f[(g=R+72|0)>>2]=0,f[g+4>>2]=0,f[(g=R+80|0)>>2]=0,f[g+4>>2]=0,f[(g=R+88|0)>>2]=0,f[g+4>>2]=0,f[e+116>>2]=f[d+40>>2],f[E+28>>2]=e+112,f[E+24>>2]=38,f[E+20>>2]=e+32,f[E+16>>2]=e+48,f[E+12>>2]=e,f[E+8>>2]=e+16,f[E+40>>2]=e+124,f[E+36>>2]=e+120,f[E+32>>2]=e+116,f[E+4>>2]=f[d+32>>2],f[E+48>>2]=f[d+4>>2],C[E>>2]=v(1)/C[d+12>>2],f[E+44>>2]=f[d+20>>2],e=f[B>>2],yt[f[f[e>>2]+20>>2]](e,E),f[G>>2]>=1)for(g=132+(Q+Yt|0)|0,Q=R+232|0,Nt=R+228|0,Yt=R+224|0,Pt=R+216|0,xt=R+212|0,V=R+208|0,R=R+240|0,$t=i+232|0,bi=i+228|0,di=i+224|0,yi=i+216|0,Ii=i+212|0,Bi=i+208|0,BA=i+240|0,i=0;e=g+-8|0,w=C[f[B>>2]+16>>2],C[e>>2]>=w&&(C[e>>2]=w),e=g+-12|0,w=v(-w),C[e>>2]<=w&&(C[e>>2]=w),f[g>>2]=F,e=f[F+28>>2],Y=C[e+328>>2],z=C[e+332>>2],pt=C[e+608>>2],Ft=C[e+348>>2],Et=C[e+340>>2],Tt=C[e+344>>2],w=C[e+612>>2],Dt=C[e+364>>2],W=C[e+356>>2],Ot=C[e+360>>2],Gt=C[e+604>>2],It=C[e+324>>2],f[g+-56>>2]=0,Vt=w,w=C[g+-132>>2],Lt=v(W*w),W=C[g+-128>>2],wt=Dt,Dt=C[g+-124>>2],C[g+-60>>2]=Vt*v(v(Lt+v(Ot*W))+v(wt*Dt)),C[g+-64>>2]=pt*v(v(v(w*Et)+v(W*Tt))+v(Dt*Ft)),C[g+-68>>2]=Gt*v(v(v(It*w)+v(Y*W))+v(z*Dt)),e=f[F+32>>2],Ft=C[e+328>>2],Et=C[e+332>>2],Tt=C[e+608>>2],Ot=C[e+348>>2],Gt=C[e+340>>2],It=C[e+344>>2],Y=C[e+612>>2],pt=C[e+364>>2],z=C[e+356>>2],Qt=C[e+360>>2],Wt=C[e+604>>2],Lt=C[e+324>>2],f[g+-40>>2]=0,Vt=Y,Y=C[g+-100>>2],Mt=v(z*Y),z=C[g+-96>>2],wt=pt,pt=C[g+-92>>2],C[g+-44>>2]=Vt*v(v(Mt+v(Qt*z))+v(wt*pt)),C[g+-48>>2]=Tt*v(v(v(Y*Gt)+v(z*It))+v(pt*Ot)),C[g+-52>>2]=Wt*v(v(v(Lt*Y)+v(Ft*z))+v(Et*pt)),Ft=v(0),Et=C[g+-116>>2],Tt=C[p+404>>2],Ot=C[g+-112>>2],Gt=C[g+-108>>2],Vt=v(v(v(v(Et*v(Et*Tt))+v(Ot*v(Tt*Ot)))+v(Gt*v(Tt*Gt)))+v(v(v(w*v(v(v(w*C[p+324>>2])+v(W*C[p+328>>2]))+v(Dt*C[p+332>>2])))+v(W*v(v(v(w*C[p+340>>2])+v(W*C[p+344>>2]))+v(Dt*C[p+348>>2]))))+v(Dt*v(v(v(w*C[p+356>>2])+v(W*C[p+360>>2]))+v(Dt*C[p+364>>2]))))),Tt=C[g+-84>>2],It=C[D+404>>2],Qt=C[g+-80>>2],Wt=C[g+-76>>2],It=v(v(Vt+v(v(v(Tt*v(Tt*It))+v(Qt*v(It*Qt)))+v(Wt*v(It*Wt))))+v(v(v(Y*v(v(v(Y*C[D+324>>2])+v(z*C[D+328>>2]))+v(pt*C[D+332>>2])))+v(z*v(v(v(Y*C[D+340>>2])+v(z*C[D+344>>2]))+v(pt*C[D+348>>2]))))+v(pt*v(v(v(Y*C[D+356>>2])+v(z*C[D+360>>2]))+v(pt*C[D+364>>2]))))),It=v(y(It))>v(1.1920928955078125e-7)?v(v(1)/It):v(0),C[g+-24>>2]=It,Lt=v(0),Vt=v(0),wt=v(0),Mt=v(0),Ut=v(0),Xt=v(0),f[BA>>2]&&(Xt=C[$t>>2],Ut=C[bi>>2],Mt=C[di>>2],Vt=C[Ii>>2],wt=C[Bi>>2],Lt=C[yi>>2]),Jt=v(0),jt=v(0),zt=v(0),Ht=v(0),Kt=v(0),f[R>>2]&&(Kt=C[Q>>2],Ht=C[Nt>>2],zt=C[Yt>>2],Jt=C[xt>>2],jt=C[V>>2],Ft=C[Pt>>2]),gr=C[p+380>>2],tn=C[p+372>>2],en=C[p+376>>2],An=C[p+396>>2],rn=C[p+388>>2],nn=C[p+392>>2],an=C[D+380>>2],on=C[D+372>>2],sn=C[D+376>>2],ln=C[D+396>>2],fn=C[D+388>>2],cn=C[D+392>>2],f[g+-32>>2]=0,C[(e=g+-20|0)>>2]=v(It*C[e>>2])+v(It*v(v(0)-v(C[E+48>>2]*v(v(v(v(v(Et*v(wt+tn))+v(Ot*v(Vt+en)))+v(Gt*v(Lt+gr)))+v(v(v(w*v(Mt+rn))+v(W*v(Ut+nn)))+v(Dt*v(Xt+An))))+v(v(v(v(Tt*v(jt+on))+v(Qt*v(Jt+sn)))+v(Wt*v(Ft+an)))+v(v(v(Y*v(zt+fn))+v(z*v(Ht+cn)))+v(pt*v(Kt+ln)))))))),g=g+152|0,(0|(i=i+1|0))>2];);g=f[t+176>>2]}if(V=qt+f[g+Zt>>2]|0,(0|(St=St+1|0))==(0|h))break}if(yt[f[f[t>>2]+28>>2]](t,r,a,d),o=f[t+68>>2],a=f[t+28>>2],!((0|(p=f[t+128>>2]))>=(0|(h=f[t+48>>2]))|f[t+132>>2]>=(0|h))){h?(i=dA(h<<2),p=f[t+128>>2]):i=0,r=f[t+136>>2];t:{if((0|p)>=1)for(g=i,e=r;f[g>>2]=f[e>>2],g=g+4|0,e=e+4|0,p=p+-1|0;);else if(!r)break t;_[t+140|0]&&CA(r),f[t+136>>2]=0}f[t+136>>2]=i,f[t+132>>2]=h,n[t+140|0]=1}if(f[t+128>>2]=h,16&_[d+72|0]){if(!((0|(p=f[t+108>>2]))>=(0|(r=a<<1))|f[t+112>>2]>=(0|r))){a?(D=dA(a<<3),p=f[t+108>>2]):D=0,i=f[t+116>>2];t:{if((0|p)>=1)for(g=D,e=i;f[g>>2]=f[e>>2],g=g+4|0,e=e+4|0,p=p+-1|0;);else if(!i)break t;_[t+120|0]&&CA(i),f[t+116>>2]=0}f[t+116>>2]=D,f[t+112>>2]=r,n[t+120|0]=1}f[t+108>>2]=r}else{if(!((0|(p=f[t+108>>2]))>=(0|a)|f[t+112>>2]>=(0|a))){a?(i=dA(a<<2),p=f[t+108>>2]):i=0,r=f[t+116>>2];t:{if((0|p)>=1)for(g=i,e=r;f[g>>2]=f[e>>2],g=g+4|0,e=e+4|0,p=p+-1|0;);else if(!r)break t;_[t+120|0]&&CA(r),f[t+116>>2]=0}f[t+116>>2]=i,f[t+112>>2]=a,n[t+120|0]=1}f[t+108>>2]=a}if(!((0|(p=f[t+148>>2]))>=(0|o)|f[t+152>>2]>=(0|o))){o?(i=dA(o<<2),p=f[t+148>>2]):i=0,r=f[t+156>>2];t:{if((0|p)>=1)for(g=i,e=r;f[g>>2]=f[e>>2],g=g+4|0,e=e+4|0,p=p+-1|0;);else if(!r)break t;_[t+160|0]&&CA(r),f[t+156>>2]=0}f[t+156>>2]=i,f[t+152>>2]=o,n[t+160|0]=1}if(f[t+148>>2]=o,(0|h)>=1)for(g=f[t+136>>2],e=0;f[g>>2]=e,g=g+4|0,(0|h)!=(0|(e=e+1|0)););if((0|a)>=1)for(g=f[t+116>>2],e=0;f[g>>2]=e,g=g+4|0,(0|a)!=(0|(e=e+1|0)););if((0|o)>=1)for(g=f[t+156>>2],e=0;f[g>>2]=e,g=g+4|0,(0|o)!=(0|(e=e+1|0)););return qr(),Z=E+256|0,v(v(0))},function(t,e,i,r,n,a,o,_,h){t|=0,e|=0,i|=0,r|=0,n|=0,a|=0,o|=0,_|=0,h|=0;var d,g=0,m=0,y=v(0),p=0;Z=d=Z-16|0,Lr(d+8|0,20261),yt[f[f[t>>2]+32>>2]](t,e,i,r,n,a,o,_,h);t:if(!((0|(m=(0|(g=f[t+184>>2]))>(0|(m=f[_+20>>2]))?g:m))<1))for(p=m+-1|0,g=0;;){if(y=v(yt[f[f[t>>2]+40>>2]](t,g,e,i,r,n,a,o,_,h)),C[t+228>>2]=y,(0|g)>=(0|p)|y<=C[_+92>>2])break t;if(!((0|(g=g+1|0))<(0|m)))break}return qr(),Z=d+16|0,v(v(0))},ve,bf,kA,function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n,a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=0,It=v(0);Z=n=Z-32|0,B=C[e+24>>2],z=C[e+40>>2],F=C[e+36>>2],h=C[e+20>>2],m=C[e+8>>2],V=C[e+16>>2],p=C[e+4>>2],G=C[e+32>>2],R=C[e>>2],f[n+28>>2]=0,o=v(V-R),d=v(F-p),_=v(h-p),y=v(G-R),a=v(v(o*d)-v(_*y)),C[n+24>>2]=a,g=v(B-m),W=v(g*y),y=v(z-m),o=v(W-v(o*y)),C[n+20>>2]=o,d=v(v(_*y)-v(g*d)),C[n+16>>2]=d,D=C[t+4>>2],g=C[t+8>>2],w=C[t+12>>2],_=v(v(m*a)+v(v(R*d)+v(p*o))),y=v(v(v(v(d*D)+v(o*g))+v(a*w))-_),Y=C[t+20>>2],Q=C[t+24>>2],pt=C[t+28>>2],_=v(v(v(v(d*Y)+v(o*Q))+v(a*pt))-_),v(y*_)>=v(0)||(1&(e=f[t+36>>2])&&y<=v(0)||(_=v(y/v(y-_)))>2]&&(W=g,g=v(v(1)-_),Q=v(v(Q*_)+v(W*g)),h=v(h-Q),D=v(v(Y*_)+v(D*g)),R=v(R-D),p=v(p-Q),V=v(V-D),g=v(v(pt*_)+v(w*g)),B=v(B-g),m=v(m-g),Y=v(v(a*a)+v(v(d*d)+v(o*o))),w=v(Y*v(-9999999747378752e-20)),v(v(a*v(v(h*R)-v(p*V)))+v(v(d*v(v(p*B)-v(m*h)))+v(o*v(v(m*V)-v(B*R)))))>=w&&(F=v(F-Q),G=v(G-D),D=v(a*v(v(F*V)-v(h*G))),W=h,h=v(z-g),v(D+v(v(d*v(v(W*h)-v(B*F)))+v(o*v(v(B*G)-v(h*V)))))>=w^1|v(v(a*v(v(p*G)-v(F*R)))+v(v(d*v(v(F*m)-v(h*p)))+v(o*v(v(h*R)-v(m*G)))))>=w^1||(h=a,a=v(v(1)/v(E(Y))),m=v(h*a),C[n+24>>2]=m,o=v(o*a),C[n+20>>2]=o,a=v(d*a),C[n+16>>2]=a,2&e|y<=v(0)^1?(Dt=t,It=v(yt[f[f[t>>2]+12>>2]](t,n+16|0,_,i,r)),C[Dt+40>>2]=It):(f[n+12>>2]=0,C[n+8>>2]=-m,C[n+4>>2]=-o,C[n>>2]=-a,Dt=t,It=v(yt[f[f[t>>2]+12>>2]](t,n,_,i,r)),C[Dt+40>>2]=It))))),Z=n+32|0},kA,function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var a,o,_=0,h=0,d=0,g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0);Z=a=Z-688|0,o=zA(a+576|0),h=f[(_=e+8|0)+4>>2],f[(d=a+644|0)>>2]=f[_>>2],f[d+4>>2]=h,_=f[e+20>>2],f[(h=a+652|0)>>2]=f[e+16>>2],f[h+4>>2]=_,h=f[(_=e+24|0)+4>>2],f[(d=a+660|0)>>2]=f[_>>2],f[d+4>>2]=h,_=f[e+36>>2],f[(h=a+668|0)>>2]=f[e+32>>2],f[h+4>>2]=_,h=f[(_=e+40|0)+4>>2],f[(d=a+676|0)>>2]=f[_>>2],f[d+4>>2]=h,f[a+580>>2]=1,f[a+576>>2]=16352,_=f[e+4>>2],f[a+636>>2]=f[e>>2],f[a+640>>2]=_,f[a+624>>2]=f[t+204>>2],n[a+548|0]=0,f[a+524>>2]=953267991,f[a+208>>2]=14800,e=of(a+184|0,f[t+4>>2],a+576|0,a+216|0,a+208|0),f[a+8>>2]=15992,f[a+172>>2]=1065353216,f[a+176>>2]=0,f[a+180>>2]=f[t+208>>2],bf(_=e,t+8|0,t+72|0,e=t+136|0,e,a+8|0)&&(m=C[a+140>>2],y=C[a+144>>2],g=C[a+148>>2],(p=v(v(v(m*m)+v(y*y))+v(g*g)))>v(9999999747378752e-20)&&((R=C[a+172>>2])>2]&&(D=g,g=v(v(1)/v(E(p))),C[a+148>>2]=D*g,C[a+144>>2]=y*g,C[a+140>>2]=m*g,v(yt[f[f[t>>2]+12>>2]](t,a+140|0,a+156|0,R,i,r))))),Ae(o),Z=a+688|0},sf,function(t){var e=0,i=0,r=0,n=0,a=0,o=0;if(f[(t|=0)>>2]=20592,e=f[t+16>>2],(0|(i=f[t+8>>2]))>=1)for(;a=f[e+n>>2],(r=f[a+188>>2])&&(e=f[t+68>>2],e=0|yt[f[f[e>>2]+36>>2]](e),yt[f[f[e>>2]+40>>2]](e,r,f[t+24>>2]),e=f[t+68>>2],yt[f[f[e>>2]+12>>2]](e,r,f[t+24>>2]),f[a+188>>2]=0,i=f[t+8>>2],e=f[t+16>>2]),n=n+4|0,(0|(o=o+1|0))<(0|i););!e|!_[t+20|0]||CA(e),$(t)},function(t){t|=0;var e,i=0,r=0,n=0,a=0,o=0;if(Z=e=Z-16|0,Lr(e+8|0,20835),(0|(i=f[t+8>>2]))>=1)for(;;){n=f[f[t+16>>2]+r>>2];t:{e:if(!(_[t+76|0]||(a=f[n+220>>2]+-2|0,a>>>0>3)))switch(a-1|0){case 0:case 1:break e;default:break t}vf(t,n),i=f[t+8>>2]}if(r=r+4|0,!((0|(o=o+1|0))<(0|i)))break}qr(),Z=e+16|0},function(t){var e,i;t|=0,Z=e=Z-16|0,Lr(e+8|0,20847),i=f[t+68>>2],yt[f[f[i>>2]+32>>2]](i,f[t+24>>2]),qr(),Z=e+16|0},function(t,e){e|=0,f[(t|=0)+72>>2]=e},Ce,mf,function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n,a=0,o=0,_=0,h=v(0),d=v(0),g=v(0),y=v(0),p=0,R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=v(0),Dt=v(0),It=0,St=v(0),Tt=v(0),Et=v(0),Ot=0,Nt=0,Ft=0,Vt=0,Gt=0,Lt=0,wt=0,xt=v(0);Z=n=Z-144|0,yt[f[f[t>>2]+20>>2]](t)&&(o=0|yt[f[f[t>>2]+20>>2]](t),32768&yt[f[f[o>>2]+56>>2]](o)&&(o=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[o>>2]+64>>2]](o,e,v(.10000000149011612))));t:{e:if(o=f[i+4>>2],!(o>>>0>31)){switch(o-1|0){case 30:if((0|(a=f[i+20>>2]))<1)break t;for(_=m(a,80)+-80|0;o=f[i+28>>2]+_|0,p=f[o- -64>>2],h=C[o+56>>2],d=C[o+48>>2],g=C[o+52>>2],R=C[o+32>>2],E=C[o>>2],F=C[o+16>>2],V=C[o+36>>2],w=C[o+4>>2],W=C[o+20>>2],y=C[o+40>>2],D=C[o+8>>2],B=C[o+24>>2],f[n+60>>2]=0,f[n+44>>2]=0,f[n+28>>2]=0,f[n+12>>2]=0,Y=C[e+32>>2],G=C[e+36>>2],Q=C[e+40>>2],C[n+40>>2]=v(v(D*Y)+v(B*G))+v(y*Q),C[n+36>>2]=v(v(w*Y)+v(W*G))+v(V*Q),C[n+32>>2]=v(v(E*Y)+v(F*G))+v(R*Q),z=C[e+16>>2],pt=C[e+20>>2],Dt=C[e+24>>2],C[n+24>>2]=v(v(D*z)+v(B*pt))+v(y*Dt),C[n+20>>2]=v(v(w*z)+v(W*pt))+v(V*Dt),C[n+16>>2]=v(v(E*z)+v(F*pt))+v(R*Dt),St=D,D=C[e>>2],Tt=B,B=C[e+4>>2],Et=y,y=C[e+8>>2],C[n+8>>2]=v(v(St*D)+v(Tt*B))+v(Et*y),C[n+4>>2]=v(v(w*D)+v(W*B))+v(V*y),C[n>>2]=v(v(E*D)+v(F*B))+v(R*y),C[n+56>>2]=v(v(v(d*Y)+v(g*G))+v(h*Q))+C[e+56>>2],C[n+52>>2]=v(v(v(d*z)+v(g*pt))+v(h*Dt))+C[e+52>>2],C[n+48>>2]=v(v(v(d*D)+v(g*B))+v(h*y))+C[e+48>>2],yt[f[f[t>>2]+28>>2]](t,n,p,r),_=_+-80|0,(0|(a=a+-1|0))>0;);break t;default:_=f[(o=i+40|0)+4>>2],f[(a=n+8|0)>>2]=f[o>>2],f[a+4>>2]=_,o=f[i+36>>2],f[n>>2]=f[i+32>>2],f[n+4>>2]=o,h=v(yt[f[f[i>>2]+48>>2]](i)),d=v(yt[f[f[i>>2]+48>>2]](i)),g=v(v(yt[f[f[i>>2]+48>>2]](i))+C[a>>2]),C[a>>2]=g,h=v(h+C[n>>2]),C[n>>2]=h,d=v(d+C[n+4>>2]),C[n+4>>2]=d,t=0|yt[f[f[t>>2]+20>>2]](t),f[n+140>>2]=0,C[n+136>>2]=-g,C[n+132>>2]=-d,C[n+128>>2]=-h,yt[f[f[t>>2]+80>>2]](t,n+128|0,n,e,r);break t;case 7:h=v(yt[f[f[i>>2]+48>>2]](i)),t=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[t>>2]+24>>2]](t,h,e,r);break t;case 8:if((0|(p=f[i+96>>2]))<1)break t;for(a=(p<<2)-4|0,_=(p<<4)-8|0;o=f[i+104>>2]+_|0,h=C[o>>2],d=C[o+-8>>2],g=C[o+-4>>2],o=0|yt[f[f[t>>2]+20>>2]](t),Y=C[f[i+124>>2]+a>>2],f[n+60>>2]=0,f[n+44>>2]=0,f[n+28>>2]=0,f[n+12>>2]=0,R=C[e+40>>2],E=C[e+32>>2],V=v(E*v(0)),F=C[e+36>>2],w=v(F*v(0)),C[n+40>>2]=R+v(V+w),y=v(V+F),V=v(R*v(0)),C[n+36>>2]=y+V,C[n+32>>2]=v(E+w)+V,V=C[e+24>>2],w=C[e+16>>2],y=v(w*v(0)),W=C[e+20>>2],D=v(W*v(0)),C[n+24>>2]=V+v(y+D),B=v(y+W),y=v(V*v(0)),C[n+20>>2]=B+y,C[n+16>>2]=v(w+D)+y,y=C[e+8>>2],D=C[e>>2],G=v(D*v(0)),B=C[e+4>>2],Q=v(B*v(0)),C[n+8>>2]=y+v(G+Q),St=v(G+B),G=v(y*v(0)),C[n+4>>2]=St+G,C[n>>2]=v(D+Q)+G,C[n+56>>2]=v(v(v(d*E)+v(g*F))+v(h*R))+C[e+56>>2],C[n+52>>2]=v(v(v(d*w)+v(g*W))+v(h*V))+C[e+52>>2],C[n+48>>2]=v(v(v(d*D)+v(g*B))+v(h*y))+C[e+48>>2],yt[f[f[o>>2]+24>>2]](o,Y,n,r),a=a+-4|0,_=_+-16|0,(0|(p=p+-1|0))>0;);break t;case 9:a=i+32|0,i=f[i+56>>2],h=C[a+(i<<2)>>2],d=C[a+((i+2|0)%3<<2)>>2],t=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[t>>2]+84>>2]](t,d,h,i,e,r);break t;case 10:a=f[i+72>>2],h=C[i+60>>2],d=C[i+64>>2],t=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[t>>2]+92>>2]](t,h,d,a,e,r);break t;case 12:a=f[i+56>>2],h=v(yt[f[f[i>>2]+92>>2]](i)),p=f[(_=i+40|0)+4>>2],f[(o=n+8|0)>>2]=f[_>>2],f[o+4>>2]=p,_=f[i+36>>2],f[n>>2]=f[i+32>>2],f[n+4>>2]=_,d=v(yt[f[f[i>>2]+48>>2]](i)),g=v(yt[f[f[i>>2]+48>>2]](i)),wt=o,xt=v(v(yt[f[f[i>>2]+48>>2]](i))+C[o>>2]),C[wt>>2]=xt,C[n>>2]=d+C[n>>2],C[n+4>>2]=g+C[n+4>>2],d=C[(a<<2)+n>>2],t=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[t>>2]+88>>2]](t,h,d,a,e,r);break t;case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 11:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:case 21:case 22:case 23:case 24:case 25:case 26:case 28:case 29:break e;case 27:}h=C[i+68>>2],t=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[t>>2]+96>>2]](t,i+52|0,h,e,r);break t}e:if(!((0|o)>6))if(It=f[i+56>>2],It){if(f[It+28>>2]<1)break e;for(;;){g=v(0);i:if(Ft=m(Nt,36),a=Ft+f[It+36>>2]|0,Ot=f[a+4>>2],Ot){if(h=v(0),d=v(0),!((0|Ot)<1))for(_=f[a+12>>2],a=f[(_+(Ot<<2)|0)-4>>2],p=1,Vt=0;;){if(_=(Gt=(o=f[_+Vt>>2])<<4)+f[It+16>>2]|0,V=C[_>>2],w=C[_+4>>2],W=C[_+8>>2],_=0|yt[f[f[t>>2]+20>>2]](t),f[n+12>>2]=0,Lt=f[It+16>>2],R=C[(a=Lt+(a<<4)|0)>>2],y=C[e+32>>2],E=C[a+4>>2],D=C[e+36>>2],F=C[a+8>>2],B=C[e+40>>2],Y=C[e+56>>2],C[n+8>>2]=v(v(v(R*y)+v(E*D))+v(F*B))+Y,G=C[e+16>>2],Q=C[e+20>>2],z=C[e+24>>2],pt=C[e+52>>2],C[n+4>>2]=v(v(v(R*G)+v(E*Q))+v(F*z))+pt,Dt=C[e>>2],St=C[e+4>>2],Tt=C[e+8>>2],Et=C[e+48>>2],C[n>>2]=v(v(v(R*Dt)+v(E*St))+v(F*Tt))+Et,f[n+140>>2]=0,R=C[(a=Gt+Lt|0)>>2],E=C[a+4>>2],F=C[a+8>>2],C[n+136>>2]=Y+v(v(v(y*R)+v(D*E))+v(B*F)),C[n+132>>2]=pt+v(v(v(G*R)+v(Q*E))+v(z*F)),C[n+128>>2]=Et+v(v(v(Dt*R)+v(St*E))+v(Tt*F)),yt[f[f[_>>2]+16>>2]](_,n,n+128|0,r),d=v(d+W),h=v(h+w),g=v(g+V),a=f[It+36>>2]+Ft|0,(0|p)>=f[a+4>>2])break i;Vt=Vt+4|0,p=p+1|0,_=f[a+12>>2],a=o}}else h=v(0),d=v(0);if(a=0|yt[f[f[t>>2]+20>>2]](t),16384&yt[f[f[a>>2]+56>>2]](a)&&(f[n+8>>2]=0,f[n+12>>2]=0,f[n>>2]=1065353216,f[n+4>>2]=1065353216,a=f[It+36>>2]+Ft|0,E=C[a+28>>2],F=C[a+20>>2],V=C[a+24>>2],a=0|yt[f[f[t>>2]+20>>2]](t),f[n+140>>2]=0,R=v(v(1)/v(0|Ot)),g=v(R*g),w=C[e+32>>2],h=v(R*h),W=C[e+36>>2],d=v(R*d),R=C[e+40>>2],y=C[e+56>>2],C[n+136>>2]=v(v(v(g*w)+v(h*W))+v(d*R))+y,D=C[e+16>>2],B=C[e+20>>2],Y=C[e+24>>2],G=C[e+52>>2],C[n+132>>2]=v(v(v(g*D)+v(h*B))+v(d*Y))+G,Q=C[e>>2],z=C[e+4>>2],pt=C[e+8>>2],Dt=C[e+48>>2],C[n+128>>2]=v(v(v(g*Q)+v(h*z))+v(d*pt))+Dt,f[n+124>>2]=0,g=v(g+F),h=v(h+V),d=v(d+E),C[n+120>>2]=y+v(v(v(w*g)+v(W*h))+v(R*d)),C[n+116>>2]=G+v(v(v(g*D)+v(h*B))+v(d*Y)),C[n+112>>2]=Dt+v(v(v(g*Q)+v(h*z))+v(d*pt)),yt[f[f[a>>2]+16>>2]](a,n+128|0,n+112|0,n)),!((0|(Nt=Nt+1|0))>2]))break}}else if(!((0|yt[f[f[i>>2]+100>>2]](i))<1))for(;yt[f[f[i>>2]+104>>2]](i,a,n,n+128|0),f[n+124>>2]=0,h=C[n>>2],R=C[e+32>>2],d=C[n+4>>2],E=C[e+36>>2],g=C[n+8>>2],F=C[e+40>>2],V=C[e+56>>2],C[n+120>>2]=v(v(v(h*R)+v(d*E))+v(g*F))+V,w=C[e+16>>2],W=C[e+20>>2],y=C[e+24>>2],D=C[e+52>>2],C[n+116>>2]=v(v(v(h*w)+v(d*W))+v(g*y))+D,B=C[e>>2],Y=C[e+4>>2],G=C[e+8>>2],Q=C[e+48>>2],C[n+112>>2]=v(v(v(h*B)+v(d*Y))+v(g*G))+Q,f[n+108>>2]=0,h=C[n+128>>2],d=C[n+132>>2],g=C[n+136>>2],C[n+104>>2]=V+v(v(v(R*h)+v(E*d))+v(F*g)),C[n+100>>2]=D+v(v(v(w*h)+v(W*d))+v(y*g)),C[n+96>>2]=Q+v(v(v(B*h)+v(Y*d))+v(G*g)),o=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[o>>2]+16>>2]](o,n+112|0,n+96|0,r),a=a+1|0,(0|a)<(0|yt[f[f[i>>2]+100>>2]](i)););(a=f[i+4>>2])+-21>>>0<=8&&(f[n+136>>2]=1566444395,f[n+140>>2]=0,f[n+128>>2]=1566444395,f[n+132>>2]=1566444395,f[n+120>>2]=-581039253,f[n+124>>2]=0,f[n+112>>2]=-581039253,f[n+116>>2]=-581039253,a=0|yt[f[f[t>>2]+20>>2]](t),_=f[(o=r+8|0)+4>>2],f[(p=n+20|0)>>2]=f[o>>2],f[p+4>>2]=_,_=f[(o=e+8|0)+4>>2],f[(p=n+36|0)>>2]=f[o>>2],f[p+4>>2]=_,o=f[e+20>>2],f[(_=n+44|0)>>2]=f[e+16>>2],f[_+4>>2]=o,_=f[(o=e+24|0)+4>>2],f[(p=n+52|0)>>2]=f[o>>2],f[p+4>>2]=_,o=f[e+36>>2],f[(_=n+60|0)>>2]=f[e+32>>2],f[_+4>>2]=o,_=f[(o=e+40|0)+4>>2],f[(p=n+68|0)>>2]=f[o>>2],f[p+4>>2]=_,f[n+8>>2]=a,f[n+4>>2]=22836,f[n>>2]=22812,a=f[r+4>>2],f[n+12>>2]=f[r>>2],f[n+16>>2]=a,a=f[e+4>>2],f[n+28>>2]=f[e>>2],f[n+32>>2]=a,o=f[(a=e+56|0)+4>>2],f[(_=n+84|0)>>2]=f[a>>2],f[_+4>>2]=o,a=f[e+52>>2],f[(o=n+76|0)>>2]=f[e+48>>2],f[o+4>>2]=a,yt[f[f[i>>2]+64>>2]](i,n,n+112|0,n+128|0),a=f[i+4>>2]),3==(0|a)&&(f[n+136>>2]=1566444395,f[n+140>>2]=0,f[n+128>>2]=1566444395,f[n+132>>2]=1566444395,f[n+120>>2]=-581039253,f[n+124>>2]=0,f[n+112>>2]=-581039253,f[n+116>>2]=-581039253,t=0|yt[f[f[t>>2]+20>>2]](t),o=f[(a=r+8|0)+4>>2],f[(_=n+20|0)>>2]=f[a>>2],f[_+4>>2]=o,o=f[(a=e+8|0)+4>>2],f[(_=n+36|0)>>2]=f[a>>2],f[_+4>>2]=o,a=f[e+20>>2],f[(o=n+44|0)>>2]=f[e+16>>2],f[o+4>>2]=a,o=f[(a=e+24|0)+4>>2],f[(_=n+52|0)>>2]=f[a>>2],f[_+4>>2]=o,a=f[e+36>>2],f[(o=n+60|0)>>2]=f[e+32>>2],f[o+4>>2]=a,o=f[(a=e+40|0)+4>>2],f[(_=n+68|0)>>2]=f[a>>2],f[_+4>>2]=o,f[n+8>>2]=t,f[n+4>>2]=22836,f[n>>2]=22812,t=f[r+4>>2],f[n+12>>2]=f[r>>2],f[n+16>>2]=t,t=f[e+4>>2],f[n+28>>2]=f[e>>2],f[n+32>>2]=t,r=f[(t=e+56|0)+4>>2],f[(a=n+84|0)>>2]=f[t>>2],f[a+4>>2]=r,t=f[e+52>>2],f[(r=n+76|0)>>2]=f[e+48>>2],f[r+4>>2]=t,t=f[i+96>>2],yt[f[f[t>>2]+8>>2]](t,4|n,n+112|0,n+128|0))}Z=n+144|0},function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n,a,o,_,h,d,g,m=0,y=0,p=v(0),R=v(0),D=v(0),B=v(0),F=v(0),V=v(0);Z=n=Z-256|0,f[(m=n+104|0)>>2]=0,f[m+4>>2]=0,f[(m=n+112|0)>>2]=0,f[m+4>>2]=0,f[(m=n+124|0)>>2]=0,f[m+4>>2]=0,f[n+120>>2]=1065353216,f[(m=n+132|0)>>2]=0,f[m+4>>2]=0,f[(m=n+140|0)>>2]=1065353216,f[m+4>>2]=0,_=f[(m=o=e+8|0)+4>>2],y=h=n+76|0,d=f[m>>2],f[y>>2]=d,f[y+4>>2]=_,y=f[(m=i+8|0)+4>>2],f[(a=n+92|0)>>2]=f[m>>2],f[a+4>>2]=y,f[n+32>>2]=22628,f[n+248>>2]=r,f[n+100>>2]=1065353216,g=f[e+4>>2],y=f[e>>2],f[n+68>>2]=y,f[n+72>>2]=g,r=f[i+4>>2],f[n+84>>2]=f[i>>2],f[n+88>>2]=r,f[n+244>>2]=t,f[(r=n+156|0)>>2]=d,f[r+4>>2]=_,f[(r=n+148|0)>>2]=y,f[r+4>>2]=g,f[(r=n+168|0)>>2]=0,f[r+4>>2]=0,f[(r=n+176|0)>>2]=0,f[r+4>>2]=0,f[(r=n+188|0)>>2]=0,f[r+4>>2]=0,f[n+184>>2]=1065353216,f[(r=n+196|0)>>2]=0,f[r+4>>2]=0,f[(r=n+204|0)>>2]=1065353216,f[r+4>>2]=0,r=f[i+4>>2],f[(y=n+212|0)>>2]=f[i>>2],f[y+4>>2]=r,r=f[m+4>>2],f[(y=n+220|0)>>2]=f[m>>2],f[y+4>>2]=r,f[n+164>>2]=1065353216,D=v(C[i>>2]-C[e>>2]),R=v(C[i+4>>2]-C[e+4>>2]),p=v(C[m>>2]-C[o>>2]),B=v(v(1)/v(E(v(v(v(D*D)+v(R*R))+v(p*p))))),V=(F=v(p*B))==v(0)?v(0xde0b6b000000000):v(v(1)/F),C[n+44>>2]=V,p=(R=v(R*B))==v(0)?v(0xde0b6b000000000):v(v(1)/R),C[n+40>>2]=p,f[n+60>>2]=V>2]=p>2]=v(v(p*v(C[n+84>>2]-C[n+68>>2]))+v(R*v(C[n+88>>2]-C[n+72>>2])))+v(F*v(C[a>>2]-C[h>>2])),p=p==v(0)?v(0xde0b6b000000000):v(v(1)/p),C[n+36>>2]=p,f[n+52>>2]=p>2],f[(t=n+24|0)>>2]=0,f[t+4>>2]=0,f[n+16>>2]=0,f[n+20>>2]=0,f[(t=n+8|0)>>2]=0,f[t+4>>2]=0,f[n>>2]=0,f[n+4>>2]=0,yt[f[f[r>>2]+24>>2]](r,e,i,n+32|0,n+16|0,n),Z=n+256|0},kf,df,function(t){t|=0;var e,i,r=0,n=0,a=0,o=0,_=0,h=0;Z=e=Z-16|0,Lr(e+8|0,20873),yt[f[f[t>>2]+8>>2]](t),yt[f[f[t>>2]+12>>2]](t),i=f[t+24>>2],Lr(e,20907),i&&(r=f[t+68>>2],a=i,o=0|yt[f[f[r>>2]+36>>2]](r),_=t+28|0,h=f[t+24>>2],n=f[f[i>>2]+32>>2],yt[n](0|a,0|o,0|_,0|h)),qr(),qr(),Z=e+16|0},function(t,e){t|=0,yt[f[f[(e|=0)>>2]+32>>2]](e),Rf(t,e),yt[f[f[e>>2]+36>>2]](e)},ve,hf,ve,hf,ve,function(t,e){t|=0,e|=0;var i,r,n,a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),yt=v(0),pt=v(0),Dt=v(0),It=v(0);Z=i=Z-128|0,r=f[e+36>>2],e=f[f[t+8>>2]+28>>2]+m(r,80)|0,n=f[e+64>>2],D=C[e+32>>2],B=C[e>>2],E=C[e+16>>2],F=C[e+56>>2],V=C[e+52>>2],G=C[e+48>>2],w=C[e+36>>2],Q=C[e+20>>2],W=C[e+4>>2],Y=C[e+40>>2],z=C[e+24>>2],yt=C[e+8>>2],e=f[t+12>>2],pt=C[e+52>>2],Dt=C[e+56>>2],a=C[e+24>>2],o=C[e+20>>2],_=C[e+40>>2],h=C[e+36>>2],It=C[e+48>>2],d=C[e+8>>2],g=C[e>>2],y=C[e+4>>2],p=C[e+16>>2],R=C[e+32>>2],f[i+124>>2]=0,f[i+108>>2]=0,f[i+92>>2]=0,C[i+104>>2]=v(v(yt*R)+v(z*h))+v(Y*_),C[i+100>>2]=v(v(W*R)+v(Q*h))+v(w*_),C[i+88>>2]=v(v(yt*p)+v(z*o))+v(Y*a),C[i+84>>2]=v(v(W*p)+v(Q*o))+v(w*a),C[i+120>>2]=Dt+v(v(v(R*G)+v(h*V))+v(_*F)),C[i+116>>2]=pt+v(v(v(p*G)+v(o*V))+v(a*F)),f[i+76>>2]=0,C[i+72>>2]=v(v(g*yt)+v(y*z))+v(d*Y),C[i+68>>2]=v(v(g*W)+v(y*Q))+v(d*w),C[i+64>>2]=v(v(B*g)+v(E*y))+v(D*d),C[i+112>>2]=It+v(v(v(g*G)+v(y*V))+v(d*F)),C[i+96>>2]=v(v(B*R)+v(E*h))+v(D*_),C[i+80>>2]=v(v(B*p)+v(E*o))+v(D*a),f[i+60>>2]=r,f[i+56>>2]=-1,f[i+44>>2]=n,f[i+40>>2]=0,f[i+48>>2]=f[t+4>>2],f[i+52>>2]=i- -64,f[i+12>>2]=1065353216,f[i+24>>2]=-1,f[i+28>>2]=0,f[i+16>>2]=0,f[i+20>>2]=1,f[i+36>>2]=r,f[i+8>>2]=21552,e=f[t+24>>2],f[i+32>>2]=e,f[i+12>>2]=f[e+4>>2],f[i+28>>2]=f[e+20>>2],Cf(f[t+16>>2],f[t+20>>2],i+40|0,i+8|0),Z=i+128|0},sA,ve,function(t,e){return e|=0,t=f[(t|=0)+24>>2],0|yt[f[f[t>>2]+8>>2]](t,e)},function(t,e,i){t|=0,e|=0,i|=0;var r,n,a=v(0);return Z=r=Z-16|0,f[r+8>>2]=-1,f[r+12>>2]=f[t+28>>2],f[e+4>>2]||(f[e+4>>2]=r+8),n=f[t+24>>2],a=v(yt[f[f[n>>2]+12>>2]](n,e,i)),f[t+4>>2]=f[f[t+24>>2]+4>>2],Z=r+16|0,v(a)},ve,Gf,ve,Gf,ve,function(t,e){t|=0,e|=0;var i,r,n,a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),yt=v(0);Z=i=Z-112|0,r=f[e+36>>2],e=f[f[t+24>>2]+28>>2]+m(r,80)|0,n=f[e+64>>2],D=C[e+32>>2],B=C[e>>2],E=C[e+16>>2],F=C[e+56>>2],V=C[e+52>>2],G=C[e+48>>2],w=C[e+36>>2],Q=C[e+20>>2],W=C[e+4>>2],a=C[e+40>>2],o=C[e+24>>2],_=C[e+8>>2],f[i+108>>2]=0,f[i+92>>2]=0,f[i+76>>2]=0,e=f[t+28>>2],h=C[e+32>>2],d=C[e+36>>2],g=C[e+40>>2],C[i+88>>2]=v(v(_*h)+v(o*d))+v(a*g),C[i+84>>2]=v(v(W*h)+v(Q*d))+v(w*g),y=C[e+16>>2],p=C[e+20>>2],R=C[e+24>>2],C[i+72>>2]=v(v(_*y)+v(o*p))+v(a*R),C[i+68>>2]=v(v(W*y)+v(Q*p))+v(w*R),C[i+104>>2]=v(v(v(G*h)+v(V*d))+v(F*g))+C[e+56>>2],C[i+100>>2]=v(v(v(G*y)+v(V*p))+v(F*R))+C[e+52>>2],f[i+60>>2]=0,Y=_,_=C[e>>2],z=o,o=C[e+4>>2],yt=a,a=C[e+8>>2],C[i+56>>2]=v(v(Y*_)+v(z*o))+v(yt*a),C[i+52>>2]=v(v(W*_)+v(Q*o))+v(w*a),C[i+48>>2]=v(v(B*_)+v(E*o))+v(D*a),C[i+96>>2]=v(v(v(G*_)+v(V*o))+v(F*a))+C[e+48>>2],C[i+80>>2]=v(v(B*h)+v(E*d))+v(D*g),C[i+64>>2]=v(v(B*y)+v(E*p))+v(D*R),f[i+28>>2]=1065353216,f[i+32>>2]=1,f[i+36>>2]=-1,f[i+44>>2]=r,f[i+24>>2]=22368,e=f[t+32>>2],f[i+40>>2]=e,f[i+28>>2]=f[e+4>>2],f[i+20>>2]=r,f[i+16>>2]=-1,f[i+4>>2]=n,e=f[t+4>>2],f[i>>2]=e,f[i+8>>2]=f[e+8>>2],f[i+12>>2]=i+48,Bf(f[t+8>>2],f[t+12>>2],f[t+16>>2],i,i+24|0,C[t+20>>2]),Z=i+112|0},sA,ve,function(t,e){return e|=0,t=f[(t|=0)+16>>2],0|yt[f[f[t>>2]+8>>2]](t,e)},function(t,e,i){t|=0,e|=0,i|=0;var r,n,a=v(0);return Z=r=Z-16|0,f[r+8>>2]=-1,f[r+12>>2]=f[t+20>>2],f[e+4>>2]||(f[e+4>>2]=r+8),n=f[t+16>>2],a=v(yt[f[f[n>>2]+12>>2]](n,e,i)),f[t+4>>2]=f[f[t+16>>2]+4>>2],Z=r+16|0,v(a)},sA,ve,function(t,e){e|=0;var i,r=0,n=0,a=0;return Z=i=Z-32|0,r=f[(t|=0)+216>>2],C[r+4>>2]!=v(0)&&(n=1,e=f[e>>2],yt[f[f[r>>2]+8>>2]](r,f[e+188>>2])&&(r=f[t+216>>2],a=f[e+192>>2],f[i+24>>2]=-1,f[i+28>>2]=-1,f[i+20>>2]=e+4,f[i+16>>2]=e,f[i+12>>2]=a,f[i+8>>2]=0,Cf(t+68|0,t+132|0,i+8|0,r))),Z=i+32|0,0|n},ve,function(t,e){t|=0,e|=0;var i,r=0,n=0,a=v(0),o=0,_=0;return Z=i=Z-32|0,r=f[t+184>>2],C[r+4>>2]!=v(0)&&(n=1,e=f[e>>2],yt[f[f[r>>2]+8>>2]](r,f[e+188>>2])&&(a=C[t+188>>2],r=f[t+184>>2],o=f[t+192>>2],_=f[e+192>>2],f[i+24>>2]=-1,f[i+28>>2]=-1,f[i+20>>2]=e+4,f[i+16>>2]=e,f[i+12>>2]=_,f[i+8>>2]=0,Bf(o,t+36|0,t+100|0,i+8|0,r,a))),Z=i+32|0,0|n},sA,ve,function(t,e,i,r){t|=0,e|=0,i|=0,r|=0;var n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0);Z=i=Z-96|0,f[i+92>>2]=0,n=C[e>>2],d=C[t+60>>2],o=C[e+4>>2],D=C[t- -64>>2],_=C[e+8>>2],B=C[t+68>>2],F=C[t+84>>2],y=v(v(v(v(n*d)+v(o*D))+v(_*B))+F),C[i+88>>2]=y,h=C[t+44>>2],V=C[t+48>>2],G=C[t+52>>2],w=C[t+80>>2],a=v(v(v(v(n*h)+v(o*V))+v(_*G))+w),C[i+84>>2]=a,g=n,n=C[t+28>>2],m=o,o=C[t+32>>2],Q=_,_=C[t+36>>2],p=C[t+76>>2],z=v(v(v(v(g*n)+v(m*o))+v(Q*_))+p),C[i+80>>2]=z,f[i+76>>2]=0,f[i+60>>2]=0,R=C[e+16>>2],g=C[e+20>>2],m=C[e+24>>2],W=v(p+v(v(v(n*R)+v(o*g))+v(_*m))),C[i+64>>2]=W,Y=v(w+v(v(v(h*R)+v(V*g))+v(G*m))),C[i+68>>2]=Y,R=v(F+v(v(v(d*R)+v(D*g))+v(B*m))),C[i+72>>2]=R,g=n,n=C[e+32>>2],m=o,o=C[e+36>>2],Q=_,_=C[e+40>>2],p=v(p+v(v(v(g*n)+v(m*o))+v(Q*_))),C[i+48>>2]=p,h=v(w+v(v(v(h*n)+v(V*o))+v(G*_))),C[i+52>>2]=h,n=v(F+v(v(v(d*n)+v(D*o))+v(B*_))),C[i+56>>2]=n,f[i+44>>2]=0,o=v(v(v(y+R)+n)*v(.3333333432674408)),C[i+40>>2]=o,D=v(v(v(a+Y)+h)*v(.3333333432674408)),C[i+36>>2]=D,_=v(v(v(z+W)+p)*v(.3333333432674408)),C[i+32>>2]=_,e=f[t+8>>2],16384&yt[f[f[e>>2]+56>>2]](e)&&(d=C[i+80>>2],f[i+24>>2]=0,f[i+28>>2]=0,f[i+16>>2]=1065353216,f[i+20>>2]=1065353216,e=f[t+8>>2],f[i+12>>2]=0,B=v(W-d),F=v(h-a),h=v(Y-a),d=v(p-d),g=a=v(v(B*F)-v(h*d)),m=v(a*a),a=v(n-y),n=v(R-y),y=v(v(h*a)-v(n*F)),a=v(v(n*d)-v(B*a)),n=v(v(1)/v(E(v(m+v(v(y*y)+v(a*a)))))),C[i+8>>2]=v(g*n)+o,C[i+4>>2]=D+v(a*n),C[i>>2]=_+v(y*n),yt[f[f[e>>2]+16>>2]](e,i+32|0,i,i+16|0)),r=f[t+8>>2],e=t+12|0,yt[f[f[r>>2]+16>>2]](r,i+80|0,i- -64|0,e),r=f[t+8>>2],yt[f[f[r>>2]+16>>2]](r,i- -64|0,i+48|0,e),t=f[t+8>>2],yt[f[f[t>>2]+16>>2]](t,i+48|0,i+80|0,e),Z=i+96|0},function(t,e,i,r){e|=0,i|=0,r|=0,yt[f[f[(t|=0)>>2]+8>>2]](t,e,i,r)},function(t){return(t|=0)+-4|0},function(t){$((t|=0)+-4|0)},function(t,e,i,r){e|=0,i|=0,r|=0,yt[f[f[(t=(t|=0)+-4|0)>>2]+8>>2]](t,e,i,r)},function(t){var e=0;return f[(t|=0)>>2]=22908,(e=f[t+56>>2])&&(_[t+60|0]&&CA(e),f[t+56>>2]=0),f[t+56>>2]=0,f[t+48>>2]=0,f[t+52>>2]=0,n[t+60|0]=1,(e=f[t+36>>2])&&(_[t+40|0]&&CA(e),f[t+36>>2]=0),f[t+36>>2]=0,f[t+28>>2]=0,f[t+32>>2]=0,n[t+40|0]=1,yf(t+4|0),0|t},function(t){var e=0;f[(t|=0)>>2]=22908,(e=f[t+56>>2])&&(_[t+60|0]&&CA(e),f[t+56>>2]=0),f[t+56>>2]=0,f[t+48>>2]=0,f[t+52>>2]=0,n[t+60|0]=1,(e=f[t+36>>2])&&(_[t+40|0]&&CA(e),f[t+36>>2]=0),f[t+36>>2]=0,f[t+28>>2]=0,f[t+32>>2]=0,n[t+40|0]=1,yf(t+4|0),$(t)},function(t,e,i){t|=0,i|=0;var r,a=0,o=0,h=0;if((0|(r=f[(e|=0)+8>>2]))<1)i=0;else for(o=f[e+16>>2],i=0;a=f[o>>2],3&_[a+204|0]||(f[a+208>>2]=i,i=i+1|0),f[a+268>>2]=1065353216,f[a+212>>2]=-1,o=o+4|0,(0|(h=h+1|0))<(0|r););!function(t,e){var i=0,r=0,a=0,o=0,h=0,d=0,C=0;if((0|(a=f[t+4>>2]))<(0|e)){if(f[t+8>>2]<(0|e)){if(e?(o=dA(e<<3),i=f[t+4>>2]):i=a,(0|i)>=1)for(;h=f[t+12>>2]+r|0,C=f[h+4>>2],f[(d=r+o|0)>>2]=f[h>>2],f[d+4>>2]=C,r=r+8|0,i=i+-1|0;);(i=f[t+12>>2])&&(_[t+16|0]&&CA(i),f[t+12>>2]=0),f[t+12>>2]=o,n[t+16|0]=1,f[t+8>>2]=e}for(r=a<<3,i=e-a|0;a=f[t+12>>2]+r|0,f[a>>2]=0,f[a+4>>2]=0,r=r+8|0,i=i+-1|0;);}if(f[t+4>>2]=e,(0|e)>=1)for(r=f[t+12>>2],i=0;f[r>>2]=i,f[r+4>>2]=1,r=r+8|0,(0|(i=i+1|0))!=(0|e););}(t+4|0,i),function(t,e){var i,r=0,n=0,a=0,o=0,h=0,d=0;if(e=f[e+68>>2],e=0|yt[f[f[e>>2]+36>>2]](e),(i=0|yt[f[f[e>>2]+36>>2]](e))&&(d=0|yt[f[f[e>>2]+20>>2]](e),!((0|i)<1)))for(;;){if((r=f[f[(e=(h<<4)+d|0)>>2]>>2])&&!(!(e=f[f[e+4>>2]>>2])|7&f[r+204>>2]|7&_[e+204|0])){if(e=f[e+208>>2],a=f[t+16>>2],o=f[r+208>>2],(0|(r=f[(n=a+(o<<3)|0)>>2]))!=(0|o))for(;r=a+(r<<3)|0,f[n>>2]=f[r>>2],o=f[r>>2],(0|(r=f[(n=a+(o<<3)|0)>>2]))!=(0|o););if((0|e)!=(0|(r=f[(n=a+(e<<3)|0)>>2])))for(;e=a+(r<<3)|0,f[n>>2]=f[e>>2],(0|(e=f[e>>2]))!=(0|(r=f[(n=a+(e<<3)|0)>>2])););(0|e)!=(0|o)&&(f[(r=a+(o<<3)|0)>>2]=e,f[(e=a+(e<<3)|0)+4>>2]=f[e+4>>2]+f[r+4>>2])}if((0|(h=h+1|0))==(0|i))break}}(t,e)},function(t,e){t|=0;var i,r=0,n=0,a=0,o=0,h=0,d=0,C=0,g=0;if((0|(i=f[(e|=0)+8>>2]))>=1)for(g=f[e+16>>2];;){if(r=f[(n<<2)+g>>2],3&_[r+204|0])f[r+208>>2]=-1,f[r+212>>2]=-2;else{if(C=(e=d)<<3,a=f[t+16>>2],(0|e)!=(0|(h=f[(o=C+a|0)>>2])))for(;e=a+(h<<3)|0,f[o>>2]=f[e>>2],(0|(e=f[e>>2]))!=(0|(h=f[(o=a+(e<<3)|0)>>2])););f[r+208>>2]=e,f[r+212>>2]=-1,f[4+(a+C|0)>>2]=n,d=d+1|0}if(!((0|(n=n+1|0))<(0|i)))break}},Ef,kA,qe,function(t,e,i,r,n){n=v(n)},Kr,ye,Df,If,function(t){CA(If(t|=0))},function(t){t|=0;var e,i=0,r=0,n=0,a=0,o=0,_=0;if(Z=e=Z-16|0,Lr(e+8|0,23348),mf(t),yt[f[f[t>>2]+20>>2]](t)&&(i=0|yt[f[f[t>>2]+20>>2]](t),6144&yt[f[f[i>>2]+56>>2]](i)&&!((0|(i=0|yt[f[f[t>>2]+104>>2]](t)))<1)))for(;i=i+-1|0,o=t,_=0|yt[f[f[t>>2]+108>>2]](t,i),a=f[f[t>>2]+172>>2],yt[a](0|o,0|_),(0|i)>0;);if(yt[f[f[t>>2]+20>>2]](t)&&(i=0|yt[f[f[t>>2]+20>>2]](t),16387&yt[f[f[i>>2]+56>>2]](i)&&yt[f[f[t>>2]+20>>2]](t)&&(i=0|yt[f[f[t>>2]+20>>2]](t),!(!yt[f[f[i>>2]+56>>2]](i)|f[t+296>>2]<1))))for(i=0;r=f[f[t+304>>2]+i>>2],yt[f[f[r>>2]+12>>2]](r,f[t+72>>2]),i=i+4|0,(0|(n=n+1|0))>2];);yt[f[f[t>>2]+20>>2]](t)&&(t=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[t>>2]+104>>2]](t)),qr(),Z=e+16|0},function(t,e,i,r){kf(t|=0,e|=0,i|=0,r|=0)},function(t,e){t|=0,!(e|=0)|!(2&f[e+252>>2])?df(t,e):yt[f[f[t>>2]+92>>2]](t,e)},function(t,e){t|=0;var i,r,n=0,a=0;yt[f[f[(e|=0)>>2]+32>>2]](e),r=0|yt[f[f[e>>2]+16>>2]](e,104,1),i=X(f[r+8>>2],0,104),f[i+88>>2]=f[t+264>>2],f[i+92>>2]=f[t+268>>2],f[i+96>>2]=f[t+272>>2],f[i+100>>2]=f[t+276>>2],a=f[(n=t+124|0)+4>>2],f[i+28>>2]=f[n>>2],f[i+32>>2]=a,a=f[(n=t+104|0)+4>>2],f[i+12>>2]=f[n>>2],f[i+16>>2]=a,a=f[(n=t+116|0)+4>>2],f[i+20>>2]=f[n>>2],f[i+24>>2]=a,a=f[(n=t+96|0)+4>>2],f[i+4>>2]=f[n>>2],f[i+8>>2]=a,f[i>>2]=f[t+92>>2],f[i+36>>2]=f[t+132>>2],f[i+40>>2]=f[t+148>>2],f[i+44>>2]=f[t+152>>2],f[i+48>>2]=f[t+156>>2],f[i+52>>2]=f[t+160>>2],f[i+56>>2]=f[t+176>>2],f[i+60>>2]=f[t+180>>2],f[i+64>>2]=f[t+112>>2],f[i+68>>2]=f[t+164>>2],f[i+72>>2]=f[t+168>>2],f[i+76>>2]=f[t+172>>2],n=f[t+144>>2],f[i+84>>2]=0,f[i+80>>2]=n,yt[f[f[e>>2]+20>>2]](e,r,23665,1145853764,i),Rf(t,e),function(t,e){var i=0,r=0,n=0,a=0,o=0,h=0,d=0,C=0,g=0,m=0;if((0|(r=f[t+8>>2]))>=1)for(;i=f[f[t+16>>2]+n>>2],2&_[i+252|0]&&(h=e,d=0|yt[f[f[i>>2]+16>>2]](i),C=1,o=f[f[e>>2]+16>>2],r=0|yt[o](0|h,0|d,0|C),C=e,d=r,h=0|yt[f[f[i>>2]+20>>2]](i,f[r+8>>2],e),g=1497645650,m=i,o=f[f[e>>2]+20>>2],yt[o](0|C,0|d,0|h,0|g,0|m),r=f[t+8>>2]),n=n+4|0,(0|(a=a+1|0))<(0|r););if(f[t+228>>2]>=1)for(n=0,a=0;i=f[f[t+236>>2]+n>>2],m=e,g=0|yt[f[f[i>>2]+36>>2]](i),h=1,o=f[f[e>>2]+16>>2],r=0|yt[o](0|m,0|g,0|h),h=e,g=r,m=0|yt[f[f[i>>2]+40>>2]](i,f[r+8>>2],e),d=1397641027,C=i,o=f[f[e>>2]+20>>2],yt[o](0|h,0|g,0|m,0|d,0|C),n=n+4|0,(0|(a=a+1|0))>2];);}(t,e),yt[f[f[e>>2]+36>>2]](e)},function(t,e,i,r){t|=0,e=v(e),i|=0,r=v(r);var a=0,o=0,h=v(0),d=0,g=0;t:if(i){if(C[t+284>>2]=r,e=v(C[t+280>>2]+e),C[t+280>>2]=e,!(e>=r))break t;a=t,h=e,e=v(e/r),o=v(y(e))>2]=h-v(v(0|o)*r)}else f[t+284>>2]=0,C[t+280>>2]=_[t+316|0]?v(0):e,r=e,o=v(y(e))>2]+20>>2]](t)&&(a=0|yt[f[f[t>>2]+20>>2]](t),d=2792,g=yt[f[f[a>>2]+56>>2]](a)>>>4&1,n[0|d]=g);t:if(o){if(a=(0|o)>(0|i)?i:o,yt[f[f[t>>2]+168>>2]](t,v(r*v(0|a))),yt[f[f[t>>2]+176>>2]](t),(0|a)<1)break t;for(i=0;yt[f[f[t>>2]+160>>2]](t,r),yt[f[f[t>>2]+80>>2]](t),(0|(i=i+1|0))<(0|a););}else yt[f[f[t>>2]+80>>2]](t);return yt[f[f[t>>2]+120>>2]](t),0|o},function(t,e,i){e|=0,i|=0;var r=0,a=0,o=0,h=0,d=0;if((0|(r=f[(t|=0)+228>>2]))==f[t+232>>2]&&!((0|r)>=(0|(o=r?r<<1:1)))){if(o&&(d=dA(o<<2),r=f[t+228>>2]),(0|r)>=1)for(a=r;f[h+d>>2]=f[f[t+236>>2]+h>>2],h=h+4|0,a=a+-1|0;);(a=f[t+236>>2])&&(_[t+240|0]&&(CA(a),r=f[t+228>>2]),f[t+236>>2]=0),f[t+236>>2]=d,f[t+232>>2]=o,n[t+240|0]=1}f[t+228>>2]=r+1,f[f[t+236>>2]+(r<<2)>>2]=e,i&&(Pi(f[e+28>>2],e),Pi(f[e+32>>2],e))},function(t,e){e|=0;var i=0,r=0,n=0,a=0;t:if(!((0|(i=f[(t|=0)+228>>2]))<1)){for(r=a=f[t+236>>2];;){if((0|e)!=f[r>>2]){if(r=r+4|0,(0|i)!=(0|(n=n+1|0)))continue;break t}break}(0|i)<=(0|n)||(n=r,i=(r=i+-1|0)<<2,f[n>>2]=f[i+a>>2],f[t+228>>2]=r,f[i+f[t+236>>2]>>2]=e)}Ki(f[e+28>>2],e),Ki(f[e+32>>2],e)},function(t,e){e|=0;var i=0,r=0,a=0,o=0,h=0;if((0|(i=f[(t|=0)+296>>2]))==f[t+300>>2]&&!((0|i)>=(0|(a=i?i<<1:1)))){if(a&&(h=dA(a<<2),i=f[t+296>>2]),(0|i)>=1)for(r=i;f[o+h>>2]=f[f[t+304>>2]+o>>2],o=o+4|0,r=r+-1|0;);(r=f[t+304>>2])&&(_[t+308|0]&&(CA(r),i=f[t+296>>2]),f[t+304>>2]=0),f[t+304>>2]=h,f[t+300>>2]=a,n[t+308|0]=1}f[t+296>>2]=i+1,f[f[t+304>>2]+(i<<2)>>2]=e},function(t,e){e|=0;var i=0,r=0,n=0,a=0;t:if(!((0|(i=f[(t|=0)+296>>2]))<1)){for(r=a=f[t+304>>2];;){if((0|e)!=f[r>>2]){if(r=r+4|0,(0|i)!=(0|(n=n+1|0)))continue;break t}break}(0|i)<=(0|n)||(n=r,i=(r=i+-1|0)<<2,f[n>>2]=f[i+a>>2],f[t+296>>2]=r,f[i+f[t+304>>2]>>2]=e)}},function(t,e){t|=0;var i=0,r=0,a=0,o=0,_=0;if(i=f[(e|=0)+4>>2],f[t+264>>2]=f[e>>2],f[t+268>>2]=i,a=f[(r=e+8|0)+4>>2],f[(i=t+272|0)>>2]=f[r>>2],f[i+4>>2]=a,(0|(r=f[t+248>>2]))>=1)for(i=0,a=0;;){t:{e:if(o=f[f[t+256>>2]+i>>2],_=f[o+220>>2]+-2|0,!(_>>>0>3))switch(_-1|0){case 0:case 1:break e;default:break t}1&n[o+564|0]||(Si(o,e),r=f[t+248>>2])}if(i=i+4|0,!((0|(a=a+1|0))<(0|r)))break}},function(t,e){t|=0;var i=0;i=f[(e|=0)+268>>2],f[t>>2]=f[e+264>>2],f[t+4>>2]=i,i=f[(e=e+272|0)+4>>2],f[(t=t+8|0)>>2]=f[e>>2],f[t+4>>2]=i},function(t){t|=0;var e,i=0,r=v(0),n=0,a=0,o=0,h=0;Z=e=Z+-64|0;t:if(_[t+290|0]){if((0|(n=f[t+8>>2]))<1)break t;for(;!(i=f[f[t+16>>2]+h>>2])|!(2&f[i+252>>2])|!f[i+540>>2]|3&_[i+204|0]||(xi(n=i+68|0,o=i+132|0,i+148|0,r=_[t+316|0]&&(r=C[t+284>>2])!=v(0)?v(C[t+280>>2]-r):v(C[t+280>>2]*C[i+268>>2]),e),i=f[i+540>>2],yt[f[f[i>>2]+12>>2]](i,e),n=f[t+8>>2]),h=h+4|0,(0|(a=a+1|0))<(0|n););}else if(a=f[t+248>>2],!((0|a)<1))for(;;){e:{i:if(i=f[f[t+256>>2]+n>>2],o=f[i+220>>2]+-2|0,!(o>>>0>3))switch(o-1|0){case 0:case 1:break i;default:break e}!f[i+540>>2]|3&_[i+204|0]||(xi(a=i+68|0,o=i+132|0,i+148|0,r=_[t+316|0]&&(r=C[t+284>>2])!=v(0)?v(C[t+280>>2]-r):v(C[t+280>>2]*C[i+268>>2]),e),i=f[i+540>>2],yt[f[f[i>>2]+12>>2]](i,e),a=f[t+248>>2])}if(n=n+4|0,!((0|(h=h+1|0))<(0|a)))break}Z=e- -64|0},function(t,e){t|=0;var i=0,r=0,a=0,o=0,h=0;if(3&_[(e|=0)+204|0]|1&n[e+564|0]||Si(e,t+264|0),f[e+192>>2]){if(1&n[e+204|0])Ye(e,2);else{if((0|(i=f[t+248>>2]))==f[t+252>>2]&&!((0|i)>=(0|(a=i?i<<1:1)))){if(a&&(h=dA(a<<2),i=f[t+248>>2]),(0|i)>=1)for(r=i;f[o+h>>2]=f[f[t+256>>2]+o>>2],o=o+4|0,r=r+-1|0;);(r=f[t+256>>2])&&(_[t+260|0]&&(CA(r),i=f[t+248>>2]),f[t+256>>2]=0),f[t+256>>2]=h,f[t+252>>2]=a,n[t+260|0]=1}f[t+248>>2]=i+1,f[f[t+256>>2]+(i<<2)>>2]=e}i=e,e=3&f[e+204>>2],yt[f[f[t>>2]+36>>2]](t,i,e?2:1,e?-3:-1)}},function(t,e,i,r){t|=0,i|=0,r|=0;var a=0,o=0,h=0,d=0,C=0;if(3&_[(e|=0)+204|0]|1&n[e+564|0]||Si(e,t+264|0),f[e+192>>2]){if(1&n[e+204|0])Ye(e,2);else{if((0|(a=f[t+248>>2]))==f[t+252>>2]&&!((0|a)>=(0|(h=a?a<<1:1)))){if(h&&(C=dA(h<<2),a=f[t+248>>2]),(0|a)>=1)for(o=a;f[d+C>>2]=f[f[t+256>>2]+d>>2],d=d+4|0,o=o+-1|0;);(o=f[t+256>>2])&&(_[t+260|0]&&(CA(o),a=f[t+248>>2]),f[t+256>>2]=0),f[t+256>>2]=C,f[t+252>>2]=h,n[t+260|0]=1}f[t+248>>2]=a+1,f[f[t+256>>2]+(a<<2)>>2]=e}yt[f[f[t>>2]+36>>2]](t,e,i,r)}},function(t,e){e|=0;var i=0,r=0,n=0,a=0;t:if(!((0|(i=f[(t|=0)+248>>2]))<1)){for(r=a=f[t+256>>2];;){if((0|e)!=f[r>>2]){if(r=r+4|0,(0|i)!=(0|(n=n+1|0)))continue;break t}break}(0|i)<=(0|n)||(n=r,i=(r=i+-1|0)<<2,f[n>>2]=f[i+a>>2],f[t+248>>2]=r,f[i+f[t+256>>2]>>2]=e)}df(t,e)},function(t,e){e|=0,_[(t|=0)+289|0]&&CA(f[t+216>>2]),f[t+216>>2]=e,n[t+289|0]=0,f[f[t+212>>2]+8>>2]=e},function(t){return f[(t|=0)+216>>2]},function(t){return f[(t|=0)+228>>2]},Mf,Mf,pe,function(t){var e=0,i=0,r=0,n=0;if(f[(t|=0)+248>>2]>=1)for(;i=f[f[t+256>>2]+r>>2],f[(e=i)+472>>2]=0,f[e+476>>2]=0,f[(e=e+496|0)>>2]=0,f[e+4>>2]=0,f[(e=i+488|0)>>2]=0,f[e+4>>2]=0,f[(i=i+480|0)>>2]=0,f[i+4>>2]=0,r=r+4|0,(0|(n=n+1|0))>2];);},Jf,xf,Jf,xf,function(t,e){t|=0,e=v(e);var i,r=0,n=0,a=0,o=0;if(Z=i=Z-16|0,Lr(i+8|0,23639),(0|(n=f[t+248>>2]))>=1)for(;r=f[f[t+256>>2]+a>>2],3&_[r+204|0]||(Xi(r,e),Ji(r,e,r+68|0),n=f[t+248>>2]),a=a+4|0,(0|(o=o+1|0))<(0|n););qr(),Z=i+16|0},function(t,e){t|=0,e=v(e);var i,r=0,n=0,a=0,o=v(0),h=0,d=0,g=v(0),m=v(0),y=0,p=v(0);if(Z=i=Z-80|0,Lr(i+72|0,23581),(0|(r=f[t+248>>2]))>=1&&function(t,e,i,r){var n,a=0,o=0,h=0,d=v(0),g=0,m=0,y=0,p=0,R=0,D=0,B=0,E=0,F=0,V=0,G=0,w=0,Q=0,W=0,Y=v(0),z=0,pt=0,Dt=v(0),It=0,St=0;if(Z=n=Z-304|0,(0|i)>=1)for(G=n+56|0,R=n+40|0,w=n+272|0,D=n+24|0,pt=n+256|0,F=n+100|0,Q=n+160|0,W=n+144|0,B=n+288|0;;){o=f[e>>2],f[o+268>>2]=1065353216;t:{e:if(a=f[o+220>>2]+-2|0,!(a>>>0>3))switch(a-1|0){case 0:case 1:break e;default:break t}3&_[o+204|0]||(Ji(o,r,n+240|0),_[t+44|0]&&(d=C[o+276>>2],(d=v(d*d))!=v(0)&&(Dt=d,a=o+52|0,d=v(C[n+288>>2]-C[a>>2]),Y=v(d*d),d=v(C[n+292>>2]-C[o+56>>2]),Y=v(Y+v(d*d)),d=v(C[n+296>>2]-C[o+60>>2]),Dt>2]+4>>2]<=19&&(V=0,f[702]=f[702]+1,h=f[t+68>>2],g=0|yt[f[f[h>>2]+36>>2]](h),h=f[a+4>>2],f[W>>2]=f[a>>2],f[W+4>>2]=h,h=f[(a=a+8|0)+4>>2],f[(m=W+8|0)>>2]=f[a>>2],f[m+4>>2]=h,a=f[B+4>>2],f[Q>>2]=f[B>>2],f[Q+4>>2]=a,m=f[(a=h=B+8|0)+4>>2],f[(y=Q+8|0)>>2]=f[a>>2],f[y+4>>2]=m,f[n+140>>2]=-1,f[n+132>>2]=1065353216,f[n+136>>2]=1,f[n+128>>2]=23884,f[n+208>>2]=0,f[n+216>>2]=0,f[n+224>>2]=f[t+24>>2],f[n+220>>2]=g,f[n+212>>2]=o,a=f[o+272>>2],DA(n+72|0),f[F>>2]=0,f[F+4>>2]=0,f[(g=F+8|0)>>2]=0,f[g+4>>2]=0,f[F+16>>2]=0,f[n+96>>2]=1065353216,f[n+88>>2]=1065353216,f[n+92>>2]=1065353216,f[n+76>>2]=8,f[n+72>>2]=9852,f[n+124>>2]=0,f[n+120>>2]=a,f[n+104>>2]=a,f[n+216>>2]=f[t+56>>2],a=f[o+188>>2],g=f[a+8>>2],f[n+136>>2]=f[a+4>>2],f[n+140>>2]=g,m=f[(a=n+248|0)+4>>2],f[(g=n+16|0)>>2]=f[a>>2],f[g+4>>2]=m,a=f[B+4>>2],f[G>>2]=f[B>>2],f[G+4>>2]=a,y=f[(a=w+8|0)+4>>2],f[(m=R+8|0)>>2]=f[a>>2],f[m+4>>2]=y,a=f[w+4>>2],f[R>>2]=f[w>>2],f[R+4>>2]=a,y=f[(a=pt)+4>>2],f[D>>2]=f[a>>2],f[D+4>>2]=y,p=f[(a=a+8|0)+4>>2],f[(y=D+8|0)>>2]=f[a>>2],f[y+4>>2]=p,a=f[h+4>>2],f[(p=G+8|0)>>2]=f[h>>2],f[p+4>>2]=a,a=f[n+244>>2],f[n+8>>2]=f[n+240>>2],f[n+12>>2]=a,p=f[(h=(a=o+4|0)+8|0)>>2],h=f[h+4>>2],It=f[a>>2],St=f[a+4>>2],z=f[(E=o+20|0)+4>>2],f[D>>2]=f[E>>2],f[D+4>>2]=z,z=f[(E=o+28|0)+4>>2],f[y>>2]=f[E>>2],f[y+4>>2]=z,f[g>>2]=p,f[g+4>>2]=h,f[n+8>>2]=It,f[n+12>>2]=St,g=f[(h=o+36|0)+4>>2],f[R>>2]=f[h>>2],f[R+4>>2]=g,g=f[(h=o+44|0)+4>>2],f[m>>2]=f[h>>2],f[m+4>>2]=g,_f(t,n+72|0,a,n+8|0,n+128|0,v(0)),(d=C[n+132>>2])>2]=d,Ji(o,v(d*r),n+240|0),f[o+268>>2]=0,ji(o,n+240|0),V=4),V)||(V=0),qr(),V)))||ji(o,n+240|0))}if(e=e+4|0,!(i=i+-1|0))break}Z=n+304|0}(t,f[t+256>>2],r,e),_[t+291|0]){if(Lr(i- -64|0,23601),f[t+324>>2]>=1)for(;;){if(h=f[f[t+332>>2]+(y<<2)>>2],!(f[h+780>>2]<1))if(r=f[h+776>>2],n=f[r+252>>2]<<30>>31&r,r=f[h+772>>2],a=f[r+252>>2]<<30>>31&r)for(r=h+128|0,d=0;(e=ke(a,n))>v(0)&&((o=C[r>>2])!=v(0)&&(p=C[r+-60>>2],g=C[r+-56>>2],m=C[r+-52>>2],f[i+60>>2]=0,C[i+56>>2]=-v(e*v(m*o)),C[i+52>>2]=-v(e*v(g*o)),C[i+48>>2]=-v(e*v(p*o)),f[i+44>>2]=0,C[i+40>>2]=C[r+-68>>2]-C[a+60>>2],C[i+36>>2]=C[r+-72>>2]-C[a+56>>2],C[i+32>>2]=C[r+-76>>2]-C[a+52>>2],f[i+28>>2]=0,C[i+24>>2]=C[r+-84>>2]-C[n+60>>2],C[i+20>>2]=C[r+-88>>2]-C[n+56>>2],C[i+16>>2]=C[r+-92>>2]-C[n+52>>2],dt(a,i+48|0,i+32|0),f[i+12>>2]=0,C[i+8>>2]=-C[i+56>>2],C[i+4>>2]=-C[i+52>>2],C[i>>2]=-C[i+48>>2],dt(n,i,i+16|0))),r=r+192|0,(0|(d=d+1|0))>2];);else for(r=h+68|0,d=0;(e=ke(a,n))>v(0)&&((o=C[r+60>>2])!=v(0)&&(p=C[r+4>>2],g=C[r+8>>2],m=C[r>>2],f[i+60>>2]=0,m=v(e*v(m*o)),C[i+48>>2]=-m,g=v(e*v(g*o)),C[i+56>>2]=-g,e=v(e*v(p*o)),C[i+52>>2]=-e,f[i+44>>2]=0,C[i+40>>2]=C[r+-8>>2]-C[a+60>>2],C[i+36>>2]=C[r+-12>>2]-C[a+56>>2],C[i+32>>2]=C[r+-16>>2]-C[a+52>>2],f[i+28>>2]=0,C[i+24>>2]=C[r+-24>>2]-C[n+60>>2],C[i+20>>2]=C[r+-28>>2]-C[n+56>>2],C[i+16>>2]=C[r+-32>>2]-C[n+52>>2],f[i+12>>2]=0,C[i+8>>2]=g,C[i+4>>2]=e,C[i>>2]=m,dt(n,i,i+16|0))),r=r+192|0,(0|(d=d+1|0))>2];);if(!((0|(y=y+1|0))>2]))break}qr()}qr(),Z=i+80|0},function(t){t|=0;var e,i=0,r=0,n=0,a=0,o=0,h=0,d=0,C=0;if(Z=e=Z-16|0,Lr(e+8|0,23445),i=f[t+220>>2],yt[f[f[i>>2]+8>>2]](i,t,f[t+24>>2]),(0|(d=f[t+324>>2]))>=1)for(C=f[t+332>>2];;){if(i=f[C+(h<<2)>>2],(r=f[i+772>>2])&&!(!(i=f[i+776>>2])|3&f[r+204>>2]|3&_[i+204|0])){if(i=f[i+208>>2],n=f[f[t+220>>2]+16>>2],a=f[r+208>>2],(0|(r=f[(o=n+(a<<3)|0)>>2]))!=(0|a))for(;r=n+(r<<3)|0,f[o>>2]=f[r>>2],a=f[r>>2],(0|(r=f[(o=n+(a<<3)|0)>>2]))!=(0|a););if((0|i)!=(0|(r=f[(o=n+(i<<3)|0)>>2])))for(;i=n+(r<<3)|0,f[o>>2]=f[i>>2],(0|(i=f[i>>2]))!=(0|(r=f[(o=n+(i<<3)|0)>>2])););(0|i)!=(0|a)&&(f[(r=n+(a<<3)|0)>>2]=i,f[(i=n+(i<<3)|0)+4>>2]=f[i+4>>2]+f[r+4>>2])}if(!((0|(h=h+1|0))<(0|d)))break}if((0|(d=f[t+228>>2]))>=1)for(C=f[t+236>>2],o=0;;){if(i=f[C+(o<<2)>>2],_[i+20|0]&&(r=f[i+28>>2],!(3&_[r+204|0]||(i=f[i+32>>2],3&_[i+204|0])))){if(i=f[i+208>>2],n=f[f[t+220>>2]+16>>2],a=f[r+208>>2],(0|(h=f[(r=n+(a<<3)|0)>>2]))!=(0|a))for(;a=r,r=n+(h<<3)|0,f[a>>2]=f[r>>2],a=f[r>>2],(0|(h=f[(r=n+(a<<3)|0)>>2]))!=(0|a););if((0|(h=f[(r=n+(i<<3)|0)>>2]))!=(0|i))for(;i=n+(h<<3)|0,f[r>>2]=f[i>>2],i=f[i>>2],(0|(h=f[(r=n+(i<<3)|0)>>2]))!=(0|i););(0|i)!=(0|a)&&(f[(r=n+(a<<3)|0)>>2]=i,f[(i=n+(i<<3)|0)+4>>2]=f[i+4>>2]+f[r+4>>2])}if((0|d)==(0|(o=o+1|0)))break}i=f[t+220>>2],yt[f[f[i>>2]+12>>2]](i,t),qr(),Z=e+16|0},function(t,e){t|=0,e|=0;var i,r,a,o,h,d,C=0,g=0,m=0,v=0;if(Z=r=Z-16|0,Lr(r+8|0,23428),(0|(m=f[t+196>>2]))<(0|(i=f[t+228>>2]))){if(f[t+200>>2]<(0|i)){if(i?(v=dA(i<<2),C=f[t+196>>2]):C=m,(0|C)>=1)for(;f[g+v>>2]=f[f[t+204>>2]+g>>2],g=g+4|0,C=C+-1|0;);(C=f[t+204>>2])&&(_[t+208|0]&&CA(C),f[t+204>>2]=0),f[t+204>>2]=v,f[t+200>>2]=i,n[t+208|0]=1}for(g=m<<2,C=i-m|0;f[f[t+204>>2]+g>>2]=0,g=g+4|0,C=C+-1|0;);}if(f[t+196>>2]=i,(0|yt[f[f[t>>2]+104>>2]](t))>=1)for(g=0,C=0;f[f[t+204>>2]+g>>2]=f[f[t+236>>2]+g>>2],g=g+4|0,(0|(C=C+1|0))<(0|yt[f[f[t>>2]+104>>2]](t)););(0|(C=f[t+196>>2]))>=2&&function A(t,e,i,r){for(var n=0,a=0,o=0,_=0,h=0,d=0,C=0,g=0,m=0,v=0;;){for(m=i,a=f[t+12>>2],g=f[a+((i+r|0)/2<<2)>>2],n=r;;){if(_=(0|(d=f[f[g+28>>2]+208>>2]))<0)for(h=i+-1|0,o=((i<<2)+a|0)-4|0,C=f[f[g+32>>2]+208>>2];h=h+1|0,v=f[(o=o+4|0)>>2],(0|(i=f[f[v+28>>2]+208>>2]))<=-1&&(i=f[f[v+32>>2]+208>>2]),(0|i)<(0|C););else for(h=i+-1|0,o=((i<<2)+a|0)-4|0;h=h+1|0,C=f[(o=o+4|0)>>2],(0|(i=f[f[C+28>>2]+208>>2]))<=-1&&(i=f[f[C+32>>2]+208>>2]),(0|i)<(0|d););if(_){for(i=n+1|0,n=(n<<2)+a|0,d=f[f[g+32>>2]+208>>2];_=f[n>>2],(0|(a=f[f[_+28>>2]+208>>2]))<=-1&&(a=f[f[_+32>>2]+208>>2]),n=n+-4|0,i=i+-1|0,(0|d)<(0|a););n=n+4|0}else{for(i=n+1|0,n=(n<<2)+a|0;_=f[n>>2],(0|(a=f[f[_+28>>2]+208>>2]))<=-1&&(a=f[f[_+32>>2]+208>>2]),n=n+-4|0,i=i+-1|0,(0|d)<(0|a););n=n+4|0}if((0|h)>(0|i)?(n=i,i=h):(a=f[o>>2],f[o>>2]=f[n>>2],f[f[t+12>>2]+(i<<2)>>2]=a,n=i+-1|0,i=h+1|0),!((0|i)<=(0|n)))break;a=f[t+12>>2]}if((0|n)>(0|m)&&A(t,e,m,n),!((0|i)<(0|r)))break}}(t+192|0,r,0,C+-1|0),g=0,yt[f[f[t>>2]+104>>2]](t)&&(g=f[t+204>>2]),function(t,e,i,r,a){if(f[t+20>>2]=a,f[t+16>>2]=r,f[t+12>>2]=i,f[t+4>>2]=e,(0|(e=f[t+32>>2]))<=-1)for(f[t+36>>2]<=-1&&((i=f[t+40>>2])&&(_[t+44|0]&&CA(i),f[t+40>>2]=0),f[t+36>>2]=0,f[t+40>>2]=0,n[t+44|0]=1),i=e<<2;f[f[t+40>>2]+i>>2]=0,i=i+4|0,a=(r=e+1|0)>>>0>=e>>>0,e=r,a;);if(f[t+32>>2]=0,(0|(e=f[t+52>>2]))<=-1)for(f[t+56>>2]<=-1&&((i=f[t+60>>2])&&(_[t- -64|0]&&CA(i),f[t+60>>2]=0),f[t+56>>2]=0,f[t+60>>2]=0,n[t- -64|0]=1),i=e<<2;f[f[t+60>>2]+i>>2]=0,i=i+4|0,a=(r=e+1|0)>>>0>=e>>>0,e=r,a;);if(f[t+52>>2]=0,(0|(e=f[t+72>>2]))<=-1)for(f[t+76>>2]<=-1&&((i=f[t+80>>2])&&(_[t+84|0]&&CA(i),f[t+80>>2]=0),f[t+76>>2]=0,f[t+80>>2]=0,n[t+84|0]=1),i=e<<2;f[f[t+80>>2]+i>>2]=0,i=i+4|0,a=(r=e+1|0)>>>0>=e>>>0,e=r,a;);f[t+72>>2]=0}(f[t+212>>2],e,g,f[t+196>>2],0|yt[f[f[t>>2]+20>>2]](t)),C=f[t+216>>2],m=f[t+24>>2],o=C,h=f[t+8>>2],d=0|yt[f[f[m>>2]+36>>2]](m),a=f[f[C>>2]+8>>2],yt[a](0|o,0|h,0|d),Ff(f[t+220>>2],f[t+24>>2],t,f[t+212>>2]),Uf(f[t+212>>2]),C=f[t+216>>2],yt[f[f[C>>2]+16>>2]](C,e,f[t+72>>2]),qr(),Z=r+16|0},function(t,e){t|=0,e=v(e);var i,r=0,n=v(0),a=0,o=v(0),h=0,d=0,g=0;if(Z=i=Z-16|0,Lr(i+8|0,23406),f[t+248>>2]>=1)for(;;){t:if(r=f[f[t+256>>2]+h>>2]){e:{if(!((d=(a=f[r+220>>2])+-2|0)-1|0&&d>>>0<=2)){if(n=C[r+372>>2],o=v(n*n),n=C[r+376>>2],o=v(o+v(n*n)),n=C[r+380>>2],o=v(o+v(n*n)),n=C[r+532>>2],o>2],o=v(n*n),n=C[r+392>>2],o=v(o+v(n*n)),n=C[r+396>>2],o=v(o+v(n*n)),n=C[r+536>>2],o>2]=C[r+224>>2]+e;break e}f[r+224>>2]=0,Ye(r,0),a=f[r+220>>2]}if(4==(0|a))break t}if(_[2792]||(n=C[750])==v(0)|(C[r+224>>2]>n^1?2!=(-2&a):0))Ye(r,1);else{if(3&_[r+204|0]){Ye(r,2);break t}if(1==(0|a)&&(Ye(r,3),a=f[r+220>>2]),2!=(0|a))break t;f[r+388>>2]=0,f[r+392>>2]=0,f[r+372>>2]=0,f[r+376>>2]=0,f[(a=r+396|0)>>2]=0,f[a+4>>2]=0,f[(a=r+380|0)>>2]=0,f[a+4>>2]=0,f[r+304>>2]=f[r+304>>2]+2}}if(h=h+4|0,!((0|(g=g+1|0))>2]))break}qr(),Z=i+16|0},function(t,e){t|=0,e=v(e);var i,r,n,a=0,o=0,_=0;if(Z=i=Z-16|0,Lr(i,23363),(a=f[t+84>>2])&&yt[a](t,e),yt[f[f[t>>2]+140>>2]](t,e),a=0,f[t+32>>2]=0,C[t+28>>2]=e,r=t+48|0,n=0|yt[f[f[t>>2]+20>>2]](t),f[r>>2]=n,yt[f[f[t>>2]+164>>2]](t,e),yt[f[f[t>>2]+44>>2]](t),yt[f[f[t>>2]+148>>2]](t),C[t+104>>2]=e,yt[f[f[t>>2]+152>>2]](t,t+92|0),yt[f[f[t>>2]+144>>2]](t,e),Lr(i+8|0,23392),f[t+296>>2]>=1)for(;o=f[f[t+304>>2]+a>>2],yt[f[f[o>>2]+8>>2]](o,t,e),a=a+4|0,(0|(_=_+1|0))>2];);qr(),yt[f[f[t>>2]+156>>2]](t,e),(a=f[t+80>>2])&&yt[a](t,e),qr(),Z=i+16|0},function(t,e){t|=0,e=v(e);var i,r=0,a=0,o=0,h=0;if(Z=i=Z-16|0,Lr(i,23536),Lr(i+8|0,23499),r=f[t+332>>2],f[t+324>>2]>=1)for(;a=f[t+24>>2],yt[f[f[a>>2]+16>>2]](a,f[r+o>>2]),o=o+4|0,r=f[t+332>>2],(0|(h=h+1|0))>2];);r&&(_[t+336|0]&&CA(r),f[t+332>>2]=0),f[t+332>>2]=0,f[t+324>>2]=0,f[t+328>>2]=0,n[t+336|0]=1,qr(),(0|(r=f[t+248>>2]))>=1&&function(t,e,i,r){var a,o=0,h=0,d=0,g=0,y=v(0),p=0,B=0,E=v(0),F=v(0),V=0,G=v(0),w=v(0),Q=0,W=0,Y=0,z=0,pt=0,Dt=0,It=v(0),St=0,Tt=v(0),Et=v(0),Ot=v(0),Nt=v(0),Ft=v(0),Vt=v(0),Gt=0,Lt=0,wt=0,xt=0,Qt=0,Wt=0,Yt=0,Pt=0,Mt=v(0),Zt=v(0),Ut=v(0),Xt=v(0),Jt=0,jt=0,zt=0,Ht=0,Kt=0,qt=v(0),$t=v(0),bi=v(0);if(Z=a=Z-496|0,(0|i)>=1)for(Q=a+124|0,Jt=a+92|0,Gt=a+72|0,jt=a+368|0,Lt=a+248|0,Y=a+232|0,wt=a+464|0,z=a+216|0,zt=a+448|0,St=a+292|0,xt=a+352|0,Qt=a+336|0,pt=a+480|0;;){d=f[(Wt<<2)+e>>2],f[d+268>>2]=1065353216;t:{e:if(o=f[d+220>>2]+-2|0,!(o>>>0>3))switch(o-1|0){case 0:case 1:break e;default:break t}if(!(3&_[d+204|0])&&(Ji(d,r,a+432|0),_[t+44|0]&&(y=C[d+276>>2],(y=v(y*y))!=v(0)&&(F=y,W=d+52|0,y=v(C[a+480>>2]-C[W>>2]),E=v(y*y),y=v(C[a+484>>2]-C[d+56>>2]),E=v(E+v(y*y)),y=v(C[a+488>>2]-C[d+60>>2]),F>2]+4>>2]<=19&&(f[702]=f[702]+1,o=f[t+68>>2],o=0|yt[f[f[o>>2]+36>>2]](o),h=f[W+4>>2],f[Qt>>2]=f[W>>2],f[Qt+4>>2]=h,g=f[(h=Yt=W+8|0)+4>>2],f[(B=Qt+8|0)>>2]=f[h>>2],f[B+4>>2]=g,h=f[pt+4>>2],f[xt>>2]=f[pt>>2],f[xt+4>>2]=h,B=f[(h=pt+8|0)+4>>2],f[(p=xt+8|0)>>2]=f[h>>2],f[p+4>>2]=B,f[a+332>>2]=-1,f[a+324>>2]=1065353216,f[a+328>>2]=1,f[a+320>>2]=23884,f[a+400>>2]=0,f[a+408>>2]=0,f[a+416>>2]=f[t+24>>2],f[a+412>>2]=o,f[a+404>>2]=d,o=f[d+272>>2],DA(a+264|0),f[St>>2]=0,f[St+4>>2]=0,f[(g=St+8|0)>>2]=0,f[g+4>>2]=0,f[St+16>>2]=0,f[a+288>>2]=1065353216,f[a+280>>2]=1065353216,f[a+284>>2]=1065353216,f[a+268>>2]=8,f[a+264>>2]=9852,f[a+316>>2]=0,f[a+312>>2]=o,f[a+296>>2]=o,f[a+408>>2]=f[t+56>>2],o=f[d+188>>2],g=f[o+8>>2],f[a+328>>2]=f[o+4>>2],f[a+332>>2]=g,B=f[(o=a+440|0)+4>>2],f[(g=a+208|0)>>2]=f[o>>2],f[g+4>>2]=B,o=f[pt+4>>2],f[Lt>>2]=f[pt>>2],f[Lt+4>>2]=o,p=f[(o=wt+8|0)+4>>2],f[(B=Y+8|0)>>2]=f[o>>2],f[B+4>>2]=p,o=f[wt+4>>2],f[Y>>2]=f[wt>>2],f[Y+4>>2]=o,p=f[(o=zt)+4>>2],f[z>>2]=f[o>>2],f[z+4>>2]=p,V=f[(o=o+8|0)+4>>2],f[(p=z+8|0)>>2]=f[o>>2],f[p+4>>2]=V,o=f[h+4>>2],f[(V=Lt+8|0)>>2]=f[h>>2],f[V+4>>2]=o,o=f[a+436>>2],f[a+200>>2]=f[a+432>>2],f[a+204>>2]=o,V=f[(h=(o=d+4|0)+8|0)>>2],h=f[h+4>>2],Ht=f[o>>2],Kt=f[o+4>>2],Pt=f[(Dt=d+20|0)+4>>2],f[z>>2]=f[Dt>>2],f[z+4>>2]=Pt,Pt=f[(Dt=d+28|0)+4>>2],f[p>>2]=f[Dt>>2],f[p+4>>2]=Pt,f[g>>2]=V,f[g+4>>2]=h,f[a+200>>2]=Ht,f[a+204>>2]=Kt,g=f[(h=d+36|0)+4>>2],f[Y>>2]=f[h>>2],f[Y+4>>2]=g,g=f[(h=d+44|0)+4>>2],f[B>>2]=f[h>>2],f[B+4>>2]=g,_f(t,a+264|0,o,a+200|0,a+320|0,v(0)),(y=C[a+324>>2])>2],G=C[d+56>>2],w=C[d+52>>2],F=C[a+376>>2],Tt=C[a+488>>2],Et=C[a+372>>2],Ot=C[a+484>>2],Nt=C[a+368>>2],Ft=C[a+480>>2],o=f[t+24>>2],B=0|yt[f[f[o>>2]+12>>2]](o,d,f[a+400>>2]),Vt=v(y*v(Ot-G)),G=v(y*v(Ft-w)),E=F,F=v(y*v(Tt-It)),w=v(v(v(-v(Et*Vt))-v(Nt*G))-v(E*F)),(0|(o=f[t+324>>2]))==f[t+328>>2]&&!((0|o)>=(0|(p=o?o<<1:1)))){if(p?(V=dA(p<<2),o=f[t+324>>2]):V=0,(0|o)>=1)for(g=0,h=o;f[g+V>>2]=f[f[t+332>>2]+g>>2],g=g+4|0,h=h+-1|0;);(h=f[t+332>>2])&&(_[t+336|0]&&(CA(h),o=f[t+324>>2]),f[t+332>>2]=0),f[t+332>>2]=V,n[t+336|0]=1,f[t+328>>2]=p}f[f[t+332>>2]+(o<<2)>>2]=B,f[t+324>>2]=o+1,o=f[a+400>>2],Tt=C[o+20>>2],Et=C[o+36>>2],Ot=C[o+40>>2],Nt=C[o+8>>2],Ft=C[o+24>>2],y=C[o+60>>2],qt=C[o+52>>2],It=C[o+56>>2],Zt=C[o+44>>2],E=C[o+12>>2],Ut=C[o+28>>2],Xt=C[o+4>>2],Mt=C[d+60>>2],$t=C[d+52>>2],bi=C[d+56>>2],f[(o=a+16|0)>>2]=0,f[o+4>>2]=0,f[(o=Jt)>>2]=0,f[o+4>>2]=0,f[(o=o+8|0)>>2]=0,f[o+4>>2]=0,f[Q>>2]=0,f[Q+4>>2]=0,f[(o=Q+8|0)>>2]=0,f[o+4>>2]=0,f[(o=Q+16|0)>>2]=0,f[o+4>>2]=0,f[(o=Q+24|0)>>2]=0,f[o+4>>2]=0,f[(o=Q+32|0)>>2]=0,f[o+4>>2]=0,f[Q+40>>2]=0,h=f[(o=jt)+4>>2],f[Gt>>2]=f[o>>2],f[Gt+4>>2]=h,h=f[(o=o+8|0)+4>>2],f[(g=Gt+8|0)>>2]=f[o>>2],f[g+4>>2]=h,f[a+8>>2]=0,f[a+12>>2]=0,f[a+36>>2]=0,C[a+88>>2]=w,G=v(G+$t),w=v(Vt+bi),F=v(F+Mt),Mt=v(v(v(E*G)+v(Ut*w))+v(Zt*F)),Vt=E,E=v(-qt),C[a+32>>2]=Mt+v(v(v(Vt*E)-v(Ut*It))-v(Zt*y)),C[a+28>>2]=v(v(v(G*Nt)+v(w*Ft))+v(F*Ot))+v(v(v(Nt*E)-v(Ft*It))-v(Ot*y)),C[a+24>>2]=v(v(v(G*Xt)+v(w*Tt))+v(F*Et))+v(v(v(Xt*E)-v(Tt*It))-v(Et*y)),o=B+m(ue(B,a+8|0),192)|0,f[o+100>>2]=0,C[o+88>>2]=R(v(D(v(C[d+228>>2]*C[f[a+400>>2]+228>>2]),v(-10))),v(10)),h=f[W+4>>2],f[(d=o+52|0)>>2]=f[W>>2],f[d+4>>2]=h,h=f[Yt+4>>2],f[(d=o+60|0)>>2]=f[Yt>>2],f[d+4>>2]=h,f[o+48>>2]=0,C[o+44>>2]=F,C[o+40>>2]=w,C[o+36>>2]=G}qr()}}if((0|(Wt=Wt+1|0))==(0|i))break}Z=a+496|0}(t,f[t+256>>2],r,e),qr(),Z=i+16|0},function(t,e){t|=0,e=v(e);var i=0,r=0,n=0,a=0;if((0|(r=f[t+8>>2]))>=1)for(;!(i=f[f[t+16>>2]+n>>2])|!(2&f[i+252>>2])|!(2&_[i+204|0])|2==f[i+220>>2]||(Ui(i,e),r=f[t+8>>2]),n=n+4|0,(0|(a=a+1|0))<(0|r););},function(t,e){t|=0,e|=0;var i,r=0,n=0,a=0,o=0,h=0,d=v(0),g=v(0),m=v(0),y=0,p=v(0),R=0,D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),z=v(0),pt=0,Dt=v(0),It=v(0),St=v(0),Tt=0,Et=v(0),Ot=0,Nt=v(0),Ft=v(0),Vt=v(0),Gt=0,Lt=0,wt=0,xt=v(0),Qt=v(0),Wt=v(0),Yt=0,Pt=v(0),Mt=v(0),Zt=0,Ut=v(0);Z=i=Z-176|0,r=0|yt[f[f[t>>2]+20>>2]](t),r=0|yt[f[f[r>>2]+56>>2]](r),a=0|yt[f[f[t>>2]+20>>2]](t),a=0|yt[f[f[a>>2]+56>>2]](a);t:if(!((Dt=C[e+40>>2])<=v(0)||(o=f[e+4>>2]+-3|0,o>>>0>9))){switch(n=2048&r,y=4096&a,o-1|0){default:if(f[(a=i+172|0)>>2]=0,f[(r=o=i+164|0)>>2]=0,f[r+4>>2]=0,f[(r=i+156|0)>>2]=0,f[r+4>>2]=0,f[(r=i+124|0)>>2]=0,f[r+4>>2]=0,f[(r=i+136|0)>>2]=0,f[r+4>>2]=0,f[i+132>>2]=1065353216,f[i+152>>2]=1065353216,f[i+116>>2]=0,f[i+120>>2]=0,f[i+144>>2]=0,f[i+148>>2]=0,f[i+112>>2]=1065353216,r=f[e+28>>2],p=C[r+52>>2],B=C[r+8>>2],E=C[r+12>>2],D=C[r+56>>2],F=C[r+28>>2],V=C[r+20>>2],w=C[r+24>>2],d=C[r+60>>2],m=C[r+44>>2],g=C[r+36>>2],Q=C[r+40>>2],W=C[r+4>>2],f[a>>2]=0,pt=i+168|0,G=d,d=C[e+300>>2],Y=v(g*d),g=C[e+304>>2],z=m,m=C[e+308>>2],C[pt>>2]=G+v(v(Y+v(Q*g))+v(z*m)),C[o>>2]=D+v(v(v(d*V)+v(g*w))+v(m*F)),C[i+160>>2]=p+v(v(v(d*W)+v(g*B))+v(m*E)),r=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[r>>2]+64>>2]](r,i+112|0,Dt),r=f[e+32>>2],p=C[r+52>>2],B=C[r+8>>2],E=C[r+12>>2],D=C[r+56>>2],F=C[r+28>>2],V=C[r+20>>2],w=C[r+24>>2],d=C[r+60>>2],m=C[r+44>>2],g=C[r+36>>2],Q=C[r+40>>2],W=C[r+4>>2],f[a>>2]=0,G=d,d=C[e+316>>2],Y=v(g*d),g=C[e+320>>2],z=m,m=C[e+324>>2],C[pt>>2]=G+v(v(Y+v(Q*g))+v(z*m)),C[o>>2]=D+v(v(v(d*V)+v(g*w))+v(m*F)),C[i+160>>2]=p+v(v(v(d*W)+v(g*B))+v(m*E)),!n)break t;t=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[t>>2]+64>>2]](t,i+112|0,Dt);break t;case 0:if(r=f[e+28>>2],xt=C[r+52>>2],d=C[r+8>>2],g=C[r+12>>2],w=C[e+584>>2],Q=C[e+552>>2],W=C[e+568>>2],Qt=C[r+56>>2],Wt=C[r+60>>2],Et=C[e+608>>2],z=C[e+600>>2],Nt=C[e+604>>2],m=C[r+28>>2],p=C[r+20>>2],B=C[r+24>>2],Ft=C[e+588>>2],G=C[e+556>>2],Y=C[e+572>>2],It=C[e+592>>2],E=C[r+44>>2],Vt=C[e+560>>2],D=C[r+36>>2],St=C[e+576>>2],F=C[r+40>>2],V=C[r+4>>2],f[i+172>>2]=0,f[i+156>>2]=0,f[i+140>>2]=0,C[i+152>>2]=v(v(Vt*D)+v(St*F))+v(It*E),C[i+148>>2]=v(v(G*D)+v(Y*F))+v(Ft*E),C[i+136>>2]=v(v(Vt*p)+v(St*B))+v(It*m),C[i+132>>2]=v(v(G*p)+v(Y*B))+v(Ft*m),C[i+168>>2]=Wt+v(v(v(D*z)+v(F*Nt))+v(E*Et)),C[i+164>>2]=Qt+v(v(v(p*z)+v(B*Nt))+v(m*Et)),f[i+124>>2]=0,C[i+144>>2]=v(v(Q*D)+v(W*F))+v(w*E),C[i+128>>2]=v(v(Q*p)+v(W*B))+v(w*m),C[i+120>>2]=v(v(V*Vt)+v(d*St))+v(g*It),C[i+116>>2]=v(v(V*G)+v(d*Y))+v(g*Ft),C[i+112>>2]=v(v(Q*V)+v(W*d))+v(w*g),C[i+160>>2]=xt+v(v(v(V*z)+v(d*Nt))+v(g*Et)),n?(r=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[r>>2]+64>>2]](r,i+112|0,Dt),r=f[e+32>>2],xt=C[r+52>>2],d=C[r+8>>2],g=C[r+12>>2],Qt=C[r+56>>2],Wt=C[r+60>>2],w=C[e+672>>2],Q=C[e+664>>2],W=C[e+668>>2],m=C[r+28>>2],p=C[r+20>>2],B=C[r+24>>2],Et=C[e+648>>2],z=C[e+616>>2],Nt=C[e+632>>2],Ft=C[e+652>>2],G=C[e+620>>2],Y=C[e+636>>2],It=C[e+656>>2],E=C[r+44>>2],Vt=C[e+624>>2],D=C[r+36>>2],St=C[e+640>>2],F=C[r+40>>2],V=C[r+4>>2],f[i+172>>2]=0,f[i+156>>2]=0,f[i+140>>2]=0,C[i+152>>2]=v(v(Vt*D)+v(St*F))+v(It*E),C[i+148>>2]=v(v(G*D)+v(Y*F))+v(Ft*E),C[i+144>>2]=v(v(z*D)+v(Nt*F))+v(Et*E),C[i+136>>2]=v(v(Vt*p)+v(St*B))+v(It*m),C[i+132>>2]=v(v(G*p)+v(Y*B))+v(Ft*m),C[i+168>>2]=Wt+v(v(v(D*Q)+v(F*W))+v(E*w)),C[i+164>>2]=Qt+v(v(v(p*Q)+v(B*W))+v(m*w)),C[i+160>>2]=xt+v(v(v(V*Q)+v(d*W))+v(g*w)),f[i+124>>2]=0,C[i+128>>2]=v(v(z*p)+v(Nt*B))+v(Et*m),C[i+120>>2]=v(v(V*Vt)+v(d*St))+v(g*It),C[i+116>>2]=v(v(V*G)+v(d*Y))+v(g*Ft),C[i+112>>2]=v(v(z*V)+v(Nt*d))+v(Et*g),r=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[r>>2]+64>>2]](r,i+112|0,Dt)):(r=f[e+32>>2],xt=C[r+52>>2],Qt=C[r+56>>2],Wt=C[r+60>>2],w=C[e+672>>2],Q=C[e+664>>2],W=C[e+668>>2],d=C[r+8>>2],g=C[r+12>>2],m=C[r+28>>2],p=C[r+20>>2],B=C[r+24>>2],Et=C[e+648>>2],z=C[e+616>>2],Nt=C[e+632>>2],Ft=C[e+652>>2],G=C[e+620>>2],Y=C[e+636>>2],It=C[e+656>>2],E=C[r+44>>2],Vt=C[e+624>>2],D=C[r+36>>2],St=C[e+640>>2],F=C[r+40>>2],V=C[r+4>>2],f[i+172>>2]=0,f[i+156>>2]=0,f[i+140>>2]=0,f[i+124>>2]=0,C[i+152>>2]=v(v(Vt*D)+v(St*F))+v(It*E),C[i+148>>2]=v(v(G*D)+v(Y*F))+v(Ft*E),C[i+144>>2]=v(v(z*D)+v(Nt*F))+v(Et*E),C[i+136>>2]=v(v(Vt*p)+v(St*B))+v(It*m),C[i+132>>2]=v(v(G*p)+v(Y*B))+v(Ft*m),C[i+128>>2]=v(v(z*p)+v(Nt*B))+v(Et*m),C[i+120>>2]=v(v(V*Vt)+v(d*St))+v(g*It),C[i+116>>2]=v(v(V*G)+v(d*Y))+v(g*Ft),C[i+112>>2]=v(v(z*V)+v(Nt*d))+v(Et*g),C[i+168>>2]=Wt+v(v(v(D*Q)+v(F*W))+v(E*w)),C[i+164>>2]=Qt+v(v(v(p*Q)+v(B*W))+v(m*w)),C[i+160>>2]=xt+v(v(v(V*Q)+v(d*W))+v(g*w))),!y|(d=function(t){var e=v(0);return(e=Wf(v(C[t>>2]-C[t+4>>2])))v(3.1415927410125732)^1?e:v(e+v(-6.2831854820251465))}(r=e+688|0))==(g=function(t){var e=v(0);return(e=Wf(v(C[t>>2]+C[t+4>>2])))v(3.1415927410125732)^1?e:v(e+v(-6.2831854820251465))}(r)))break t;m=C[e+692>>2],f[i+96>>2]=f[i+120>>2],f[i+100>>2]=f[i+136>>2],f[i+108>>2]=0,f[i+104>>2]=f[i+152>>2],f[i+80>>2]=f[i+112>>2],f[i+84>>2]=f[i+128>>2],f[i+92>>2]=0,f[i+88>>2]=f[i+144>>2],t=0|yt[f[f[t>>2]+20>>2]](t),f[(e=i+72|0)>>2]=0,f[e+4>>2]=0,f[i+64>>2]=0,f[i+68>>2]=0,e=m>v(0),yt[f[f[t>>2]+68>>2]](t,i+160|0,i+96|0,i+80|0,Dt,Dt,e?d:v(0),e?g:v(6.2831854820251465),i- -64|0,e,v(10));break t;case 1:if(r=f[e+28>>2],xt=C[r+52>>2],d=C[r+8>>2],g=C[r+12>>2],w=C[e+332>>2],Q=C[e+300>>2],W=C[e+316>>2],Qt=C[r+56>>2],Wt=C[r+60>>2],Et=C[e+356>>2],z=C[e+348>>2],Nt=C[e+352>>2],m=C[r+28>>2],p=C[r+20>>2],B=C[r+24>>2],Ft=C[e+336>>2],G=C[e+304>>2],Y=C[e+320>>2],It=C[e+340>>2],E=C[r+44>>2],Vt=C[e+308>>2],D=C[r+36>>2],St=C[e+324>>2],F=C[r+40>>2],V=C[r+4>>2],f[i+172>>2]=0,f[i+156>>2]=0,f[i+140>>2]=0,C[i+152>>2]=v(v(Vt*D)+v(St*F))+v(It*E),C[i+148>>2]=v(v(G*D)+v(Y*F))+v(Ft*E),C[i+136>>2]=v(v(Vt*p)+v(St*B))+v(It*m),C[i+132>>2]=v(v(G*p)+v(Y*B))+v(Ft*m),C[i+168>>2]=Wt+v(v(v(D*z)+v(F*Nt))+v(E*Et)),C[i+164>>2]=Qt+v(v(v(p*z)+v(B*Nt))+v(m*Et)),f[i+124>>2]=0,C[i+144>>2]=v(v(Q*D)+v(W*F))+v(w*E),C[i+128>>2]=v(v(Q*p)+v(W*B))+v(w*m),C[i+120>>2]=v(v(V*Vt)+v(d*St))+v(g*It),C[i+116>>2]=v(v(V*G)+v(d*Y))+v(g*Ft),C[i+112>>2]=v(v(Q*V)+v(W*d))+v(w*g),C[i+160>>2]=xt+v(v(v(V*z)+v(d*Nt))+v(g*Et)),n?(r=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[r>>2]+64>>2]](r,i+112|0,Dt),r=f[e+32>>2],xt=C[r+52>>2],d=C[r+8>>2],g=C[r+12>>2],Qt=C[r+56>>2],Wt=C[r+60>>2],w=C[e+420>>2],Q=C[e+412>>2],W=C[e+416>>2],m=C[r+28>>2],p=C[r+20>>2],B=C[r+24>>2],Et=C[e+396>>2],z=C[e+364>>2],Nt=C[e+380>>2],Ft=C[e+400>>2],G=C[e+368>>2],Y=C[e+384>>2],It=C[e+404>>2],E=C[r+44>>2],Vt=C[e+372>>2],D=C[r+36>>2],St=C[e+388>>2],F=C[r+40>>2],V=C[r+4>>2],f[i+172>>2]=0,f[i+156>>2]=0,f[i+140>>2]=0,C[i+152>>2]=v(v(Vt*D)+v(St*F))+v(It*E),C[i+148>>2]=v(v(G*D)+v(Y*F))+v(Ft*E),C[i+144>>2]=v(v(z*D)+v(Nt*F))+v(Et*E),C[i+136>>2]=v(v(Vt*p)+v(St*B))+v(It*m),C[i+132>>2]=v(v(G*p)+v(Y*B))+v(Ft*m),C[i+168>>2]=Wt+v(v(v(D*Q)+v(F*W))+v(E*w)),C[i+164>>2]=Qt+v(v(v(p*Q)+v(B*W))+v(m*w)),C[i+160>>2]=xt+v(v(v(V*Q)+v(d*W))+v(g*w)),f[i+124>>2]=0,C[i+128>>2]=v(v(z*p)+v(Nt*B))+v(Et*m),C[i+120>>2]=v(v(V*Vt)+v(d*St))+v(g*It),C[i+116>>2]=v(v(V*G)+v(d*Y))+v(g*Ft),C[i+112>>2]=v(v(z*V)+v(Nt*d))+v(Et*g),r=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[r>>2]+64>>2]](r,i+112|0,Dt)):(r=f[e+32>>2],xt=C[r+52>>2],Qt=C[r+56>>2],Wt=C[r+60>>2],w=C[e+420>>2],Q=C[e+412>>2],W=C[e+416>>2],d=C[r+8>>2],g=C[r+12>>2],m=C[r+28>>2],p=C[r+20>>2],B=C[r+24>>2],Et=C[e+396>>2],z=C[e+364>>2],Nt=C[e+380>>2],Ft=C[e+400>>2],G=C[e+368>>2],Y=C[e+384>>2],It=C[e+404>>2],E=C[r+44>>2],Vt=C[e+372>>2],D=C[r+36>>2],St=C[e+388>>2],F=C[r+40>>2],V=C[r+4>>2],f[i+172>>2]=0,f[i+156>>2]=0,f[i+140>>2]=0,f[i+124>>2]=0,C[i+152>>2]=v(v(Vt*D)+v(St*F))+v(It*E),C[i+148>>2]=v(v(G*D)+v(Y*F))+v(Ft*E),C[i+144>>2]=v(v(z*D)+v(Nt*F))+v(Et*E),C[i+136>>2]=v(v(Vt*p)+v(St*B))+v(It*m),C[i+132>>2]=v(v(G*p)+v(Y*B))+v(Ft*m),C[i+128>>2]=v(v(z*p)+v(Nt*B))+v(Et*m),C[i+120>>2]=v(v(V*Vt)+v(d*St))+v(g*It),C[i+116>>2]=v(v(V*G)+v(d*Y))+v(g*Ft),C[i+112>>2]=v(v(z*V)+v(Nt*d))+v(Et*g),C[i+168>>2]=Wt+v(v(v(D*Q)+v(F*W))+v(E*w)),C[i+164>>2]=Qt+v(v(v(p*Q)+v(B*W))+v(m*w)),C[i+160>>2]=xt+v(v(v(V*Q)+v(d*W))+v(g*w))),!y)break t;for(Zf(i+96|0,e,v(6.0868353843688965),Dt),f[i+108>>2]=0,d=C[i+96>>2],g=C[i+100>>2],m=C[i+104>>2],C[i+104>>2]=v(v(v(d*C[i+144>>2])+v(g*C[i+148>>2]))+v(m*C[i+152>>2]))+C[i+168>>2],C[i+100>>2]=v(v(v(d*C[i+128>>2])+v(g*C[i+132>>2]))+v(m*C[i+136>>2]))+C[i+164>>2],C[i+96>>2]=v(v(v(d*C[i+112>>2])+v(g*C[i+116>>2]))+v(m*C[i+120>>2]))+C[i+160>>2],a=i+160|0,o=i+72|0,r=0;Zf(i+80|0,e,v(v(v(0|r)*v(6.283185005187988))*v(.03125)),Dt),f[i+92>>2]=0,d=C[i+80>>2],g=C[i+84>>2],m=C[i+88>>2],C[i+88>>2]=v(v(v(d*C[i+144>>2])+v(g*C[i+148>>2]))+v(m*C[i+152>>2]))+C[i+168>>2],C[i+84>>2]=v(v(v(d*C[i+128>>2])+v(g*C[i+132>>2]))+v(m*C[i+136>>2]))+C[i+164>>2],C[i+80>>2]=v(v(v(d*C[i+112>>2])+v(g*C[i+116>>2]))+v(m*C[i+120>>2]))+C[i+160>>2],n=0|yt[f[f[t>>2]+20>>2]](t),f[o>>2]=0,f[o+4>>2]=0,f[i+64>>2]=0,f[i+68>>2]=0,yt[f[f[n>>2]+16>>2]](n,i+96|0,i+80|0,i- -64|0),3&r||(n=0|yt[f[f[t>>2]+20>>2]](t),f[o>>2]=0,f[o+4>>2]=0,f[i+64>>2]=0,f[i+68>>2]=0,yt[f[f[n>>2]+16>>2]](n,a,i+80|0,i- -64|0)),Gt=f[(pt=i+88|0)+4>>2],f[(n=i+104|0)>>2]=f[pt>>2],f[n+4>>2]=Gt,n=f[i+84>>2],f[i+96>>2]=f[i+80>>2],f[i+100>>2]=n,32!=(0|(r=r+1|0)););Q=C[e+512>>2],W=C[e+452>>2],r=f[e+32>>2],C[r+404>>2]>v(0)?(d=C[r+36>>2],D=C[e+412>>2],g=C[r+40>>2],F=C[e+416>>2],Et=v(v(d*D)+v(g*F)),m=C[r+20>>2],p=C[r+24>>2],B=C[r+28>>2],z=C[e+420>>2],Nt=v(v(v(m*D)+v(p*F))+v(B*z)),E=C[r+4>>2],G=v(E*D),D=C[r+8>>2],G=v(G+v(D*F)),F=C[r+12>>2],Ft=v(G+v(F*z)),G=C[e+372>>2],Y=C[e+388>>2],It=C[e+404>>2],V=C[r+44>>2],Vt=v(v(v(G*d)+v(Y*g))+v(It*V)),St=C[e+368>>2],xt=C[e+384>>2],Qt=C[e+400>>2],w=v(v(v(St*d)+v(xt*g))+v(Qt*V)),Wt=C[e+364>>2],Pt=C[e+380>>2],Mt=C[e+396>>2],d=v(v(v(Wt*d)+v(Pt*g))+v(Mt*V)),Ut=v(v(v(G*m)+v(Y*p))+v(It*B)),g=v(v(v(St*m)+v(xt*p))+v(Qt*B)),m=v(v(v(Wt*m)+v(Pt*p))+v(Mt*B)),G=v(v(v(E*G)+v(D*Y))+v(F*It)),p=v(v(v(E*St)+v(D*xt))+v(F*Qt)),B=v(v(v(Wt*E)+v(Pt*D))+v(Mt*F)),E=v(V*z)):(r=f[e+28>>2],d=C[r+36>>2],D=C[e+348>>2],g=C[r+40>>2],F=C[e+352>>2],Et=v(v(d*D)+v(g*F)),m=C[r+20>>2],p=C[r+24>>2],B=C[r+28>>2],z=C[e+356>>2],Nt=v(v(v(m*D)+v(p*F))+v(B*z)),E=C[r+4>>2],G=v(E*D),D=C[r+8>>2],G=v(G+v(D*F)),F=C[r+12>>2],Ft=v(G+v(F*z)),G=C[e+308>>2],Y=C[e+324>>2],It=C[e+340>>2],V=C[r+44>>2],Vt=v(v(v(G*d)+v(Y*g))+v(It*V)),St=C[e+304>>2],xt=C[e+320>>2],Qt=C[e+336>>2],w=v(v(v(St*d)+v(xt*g))+v(Qt*V)),Wt=C[e+300>>2],Pt=C[e+316>>2],Mt=C[e+332>>2],d=v(v(v(Wt*d)+v(Pt*g))+v(Mt*V)),Ut=v(v(v(G*m)+v(Y*p))+v(It*B)),g=v(v(v(St*m)+v(xt*p))+v(Qt*B)),m=v(v(v(Wt*m)+v(Pt*p))+v(Mt*B)),G=v(v(v(E*G)+v(D*Y))+v(F*It)),p=v(v(v(E*St)+v(D*xt))+v(F*Qt)),B=v(v(v(Wt*E)+v(Pt*D))+v(Mt*F)),E=v(V*z)),f[i+156>>2]=0,C[i+152>>2]=Vt,C[i+148>>2]=w,C[i+144>>2]=d,f[i+140>>2]=0,C[i+136>>2]=Ut,C[i+132>>2]=g,C[i+128>>2]=m,f[i+124>>2]=0,C[i+120>>2]=G,C[i+116>>2]=p,C[i+112>>2]=B,D=C[r+52>>2],F=C[r+56>>2],V=C[r+60>>2],f[i+172>>2]=0,C[i+168>>2]=V+v(Et+E),C[i+164>>2]=Nt+F,C[i+160>>2]=D+Ft,o=f[(r=a+8|0)+4>>2],f[(e=i+88|0)>>2]=f[r>>2],f[e+4>>2]=o,e=f[a+4>>2],f[i+80>>2]=f[a>>2],f[i+84>>2]=e,f[i+76>>2]=0,C[i+72>>2]=d,C[i+68>>2]=m,C[i+64>>2]=B,f[i+60>>2]=0,C[i+56>>2]=w,C[i+52>>2]=g,C[i+48>>2]=p,t=0|yt[f[f[t>>2]+20>>2]](t),f[(e=i+40|0)>>2]=0,f[e+4>>2]=0,f[i+32>>2]=0,f[i+36>>2]=0,yt[f[f[t>>2]+68>>2]](t,i+80|0,i- -64|0,i+48|0,Dt,Dt,v(v(-Q)-W),v(W-Q),i+32|0,1,v(10));break t;case 2:case 5:if(o=f[(a=e+1072|0)+4>>2],f[(r=h=i+120|0)>>2]=f[a>>2],f[r+4>>2]=o,o=f[(a=e+1088|0)+4>>2],f[(r=i+136|0)>>2]=f[a>>2],f[r+4>>2]=o,o=f[(a=e+1104|0)+4>>2],f[(r=i+152|0)>>2]=f[a>>2],f[r+4>>2]=o,o=f[(a=e+1120|0)+4>>2],f[(r=i+168|0)>>2]=f[a>>2],f[r+4>>2]=o,a=f[(r=pt=e+1064|0)+4>>2],f[i+112>>2]=f[r>>2],f[i+116>>2]=a,a=f[(r=Gt=e+1080|0)+4>>2],f[i+128>>2]=f[r>>2],f[i+132>>2]=a,a=f[(r=Lt=e+1096|0)+4>>2],f[i+144>>2]=f[r>>2],f[i+148>>2]=a,a=f[(r=wt=e+1112|0)+4>>2],f[i+160>>2]=f[r>>2],f[i+164>>2]=a,r=i+160|0,a=i+144|0,o=i+128|0,n?(n=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[n>>2]+64>>2]](n,i+112|0,Dt),Ot=f[(R=e+1184|0)+4>>2],f[(n=r+8|0)>>2]=f[R>>2],f[n+4>>2]=Ot,R=f[(n=e+1176|0)+4>>2],f[r>>2]=f[n>>2],f[r+4>>2]=R,R=f[(n=e+1144|0)+4>>2],f[o>>2]=f[n>>2],f[o+4>>2]=R,Ot=f[(R=e+1152|0)+4>>2],f[(n=o+8|0)>>2]=f[R>>2],f[n+4>>2]=Ot,R=f[(n=e+1160|0)+4>>2],f[a>>2]=f[n>>2],f[a+4>>2]=R,Ot=f[(R=e+1168|0)+4>>2],f[(n=a+8|0)>>2]=f[R>>2],f[n+4>>2]=Ot,R=f[(n=e+1136|0)+4>>2],f[h>>2]=f[n>>2],f[h+4>>2]=R,h=f[(n=e+1128|0)+4>>2],f[i+112>>2]=f[n>>2],f[i+116>>2]=h,n=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[n>>2]+64>>2]](n,i+112|0,Dt)):(R=f[(n=e+1136|0)+4>>2],f[h>>2]=f[n>>2],f[h+4>>2]=R,h=f[(n=e+1144|0)+4>>2],f[o>>2]=f[n>>2],f[o+4>>2]=h,R=f[(h=e+1152|0)+4>>2],f[(n=o+8|0)>>2]=f[h>>2],f[n+4>>2]=R,h=f[(n=e+1160|0)+4>>2],f[a>>2]=f[n>>2],f[a+4>>2]=h,R=f[(h=e+1168|0)+4>>2],f[(n=a+8|0)>>2]=f[h>>2],f[n+4>>2]=R,h=f[(n=e+1176|0)+4>>2],f[r>>2]=f[n>>2],f[r+4>>2]=h,R=f[(h=e+1184|0)+4>>2],f[(n=r+8|0)>>2]=f[h>>2],f[n+4>>2]=R,h=f[(n=e+1128|0)+4>>2],f[i+112>>2]=f[n>>2],f[i+116>>2]=h),!y)break t;n=f[Gt+4>>2],f[o>>2]=f[Gt>>2],f[o+4>>2]=n,n=f[Lt+4>>2],f[a>>2]=f[Lt>>2],f[a+4>>2]=n,n=f[wt+4>>2],f[r>>2]=f[wt>>2],f[r+4>>2]=n,R=f[(h=pt+8|0)+4>>2],n=y=i+120|0,Tt=f[h>>2],f[n>>2]=Tt,f[n+4>>2]=R,Ot=f[(R=Gt+8|0)+4>>2],f[(n=h=o+8|0)>>2]=f[R>>2],f[n+4>>2]=Ot,Yt=f[(Ot=Lt+8|0)+4>>2],f[(n=R=a+8|0)>>2]=f[Ot>>2],f[n+4>>2]=Yt,Zt=f[(Yt=wt+8|0)+4>>2],f[(n=Ot=r+8|0)>>2]=f[Yt>>2],f[n+4>>2]=Zt,n=f[pt+4>>2],f[i+112>>2]=f[pt>>2],f[i+116>>2]=n,f[i+96>>2]=Tt,f[i+100>>2]=f[i+136>>2],f[i+108>>2]=0,f[i+104>>2]=f[i+152>>2],f[i+80>>2]=f[i+112>>2],f[i+84>>2]=f[i+128>>2],f[i+92>>2]=0,f[i+88>>2]=f[i+144>>2],d=C[e+932>>2],g=C[e+936>>2],m=C[e+996>>2],p=C[e+1e3>>2],Tt=0|yt[f[f[t>>2]+20>>2]](t),f[(n=i+72|0)>>2]=0,f[n+4>>2]=0,f[i+64>>2]=0,f[i+68>>2]=0,n=e+1176|0,yt[f[f[Tt>>2]+72>>2]](Tt,n,i+96|0,i+80|0,v(Dt*v(.8999999761581421)),d,g,m,p,i- -64|0,v(10),1),f[i+92>>2]=0,f[i+88>>2]=f[i+148>>2],f[i+84>>2]=f[i+132>>2],f[i+80>>2]=f[i+116>>2],m=Vf(e,1),p=Vf(e,2),Yt=f[(Tt=e+1136|0)+4>>2],f[y>>2]=f[Tt>>2],f[y+4>>2]=Yt,Tt=f[(y=e+1144|0)+4>>2],f[o>>2]=f[y>>2],f[o+4>>2]=Tt,Tt=f[(y=e+1152|0)+4>>2],f[h>>2]=f[y>>2],f[h+4>>2]=Tt,h=f[(y=e+1160|0)+4>>2],f[a>>2]=f[y>>2],f[a+4>>2]=h,h=f[(y=e+1168|0)+4>>2],f[R>>2]=f[y>>2],f[R+4>>2]=h,h=f[(y=e+1128|0)+4>>2],f[i+112>>2]=f[y>>2],f[i+116>>2]=h,d=dr(p),g=C[i+80>>2],p=Cr(p),B=C[i+84>>2],C[i+68>>2]=v(p*B)-v(d*g),E=dr(m),m=Cr(m),D=C[i+88>>2],C[i+72>>2]=v(v(g*v(p*E))+v(B*v(E*d)))+v(m*D),C[i+64>>2]=v(v(g*v(m*p))+v(B*v(m*d)))-v(E*D),h=f[(y=e+1184|0)+4>>2],f[Ot>>2]=f[y>>2],f[Ot+4>>2]=h,y=f[n+4>>2],f[r>>2]=f[n>>2],f[r+4>>2]=y,f[i+60>>2]=0,C[i+56>>2]=-C[i+144>>2],C[i+52>>2]=-C[i+128>>2],C[i+48>>2]=-C[i+112>>2],(d=C[e+868>>2])>(g=C[e+872>>2])?(y=0|yt[f[f[t>>2]+20>>2]](t),f[(h=i+40|0)>>2]=0,f[h+4>>2]=0,f[i+32>>2]=0,f[i+36>>2]=0,yt[f[f[y>>2]+68>>2]](y,n,i+48|0,i- -64|0,Dt,Dt,v(-3.1415927410125732),v(3.1415927410125732),i+32|0,0,v(10))):d>2]+20>>2]](t),f[(h=i+40|0)>>2]=0,f[h+4>>2]=0,f[i+32>>2]=0,f[i+36>>2]=0,yt[f[f[y>>2]+68>>2]](y,n,i+48|0,i- -64|0,Dt,Dt,d,g,i+32|0,1,v(10))),n=f[Gt+4>>2],f[o>>2]=f[Gt>>2],f[o+4>>2]=n,n=f[Lt+4>>2],f[a>>2]=f[Lt>>2],f[a+4>>2]=n,n=f[wt+4>>2],f[r>>2]=f[wt>>2],f[r+4>>2]=n,h=f[(y=pt+8|0)+4>>2],f[(n=i+120|0)>>2]=f[y>>2],f[n+4>>2]=h,Gt=f[(n=Gt+8|0)+4>>2],f[(o=o+8|0)>>2]=f[n>>2],f[o+4>>2]=Gt,n=f[(o=Lt+8|0)+4>>2],f[(a=a+8|0)>>2]=f[o>>2],f[a+4>>2]=n,o=f[(a=wt+8|0)+4>>2],f[(r=r+8|0)>>2]=f[a>>2],f[r+4>>2]=o,r=f[pt+4>>2],f[i+112>>2]=f[pt>>2],f[i+116>>2]=r,o=f[(a=e+688|0)+4>>2],f[(r=i+40|0)>>2]=f[a>>2],f[r+4>>2]=o,a=f[(r=e+680|0)+4>>2],f[i+32>>2]=f[r>>2],f[i+36>>2]=a,o=f[(a=e+704|0)+4>>2],f[(r=i+24|0)>>2]=f[a>>2],f[r+4>>2]=o,r=f[(e=e+696|0)+4>>2],f[i+16>>2]=f[e>>2],f[i+20>>2]=r,t=0|yt[f[f[t>>2]+20>>2]](t),f[(e=i+8|0)>>2]=0,f[e+4>>2]=0,f[i>>2]=0,f[i+4>>2]=0,yt[f[f[t>>2]+80>>2]](t,i+32|0,i+16|0,i+112|0,i);break t;case 8:if(o=f[(a=e+1244|0)+4>>2],f[(r=h=i+120|0)>>2]=f[a>>2],f[r+4>>2]=o,o=f[(a=e+1260|0)+4>>2],f[(r=i+136|0)>>2]=f[a>>2],f[r+4>>2]=o,o=f[(a=e+1276|0)+4>>2],f[(r=i+152|0)>>2]=f[a>>2],f[r+4>>2]=o,o=f[(a=e+1292|0)+4>>2],f[(r=i+168|0)>>2]=f[a>>2],f[r+4>>2]=o,a=f[(r=pt=e+1236|0)+4>>2],f[i+112>>2]=f[r>>2],f[i+116>>2]=a,a=f[(r=Gt=e+1252|0)+4>>2],f[i+128>>2]=f[r>>2],f[i+132>>2]=a,a=f[(r=Lt=e+1268|0)+4>>2],f[i+144>>2]=f[r>>2],f[i+148>>2]=a,a=f[(r=wt=e+1284|0)+4>>2],f[i+160>>2]=f[r>>2],f[i+164>>2]=a,r=i+160|0,a=i+144|0,o=i+128|0,n?(n=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[n>>2]+64>>2]](n,i+112|0,Dt),Ot=f[(R=e+1356|0)+4>>2],f[(n=r+8|0)>>2]=f[R>>2],f[n+4>>2]=Ot,R=f[(n=e+1348|0)+4>>2],f[r>>2]=f[n>>2],f[r+4>>2]=R,R=f[(n=e+1316|0)+4>>2],f[o>>2]=f[n>>2],f[o+4>>2]=R,Ot=f[(R=e+1324|0)+4>>2],f[(n=o+8|0)>>2]=f[R>>2],f[n+4>>2]=Ot,R=f[(n=e+1332|0)+4>>2],f[a>>2]=f[n>>2],f[a+4>>2]=R,Ot=f[(R=e+1340|0)+4>>2],f[(n=a+8|0)>>2]=f[R>>2],f[n+4>>2]=Ot,R=f[(n=e+1308|0)+4>>2],f[h>>2]=f[n>>2],f[h+4>>2]=R,h=f[(n=e+1300|0)+4>>2],f[i+112>>2]=f[n>>2],f[i+116>>2]=h,n=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[n>>2]+64>>2]](n,i+112|0,Dt)):(R=f[(n=e+1308|0)+4>>2],f[h>>2]=f[n>>2],f[h+4>>2]=R,h=f[(n=e+1316|0)+4>>2],f[o>>2]=f[n>>2],f[o+4>>2]=h,R=f[(h=e+1324|0)+4>>2],f[(n=o+8|0)>>2]=f[h>>2],f[n+4>>2]=R,h=f[(n=e+1332|0)+4>>2],f[a>>2]=f[n>>2],f[a+4>>2]=h,R=f[(h=e+1340|0)+4>>2],f[(n=a+8|0)>>2]=f[h>>2],f[n+4>>2]=R,h=f[(n=e+1348|0)+4>>2],f[r>>2]=f[n>>2],f[r+4>>2]=h,R=f[(h=e+1356|0)+4>>2],f[(n=r+8|0)>>2]=f[h>>2],f[n+4>>2]=R,h=f[(n=e+1300|0)+4>>2],f[i+112>>2]=f[n>>2],f[i+116>>2]=h),!y)break t;n=f[Gt+4>>2],f[o>>2]=f[Gt>>2],f[o+4>>2]=n,n=f[Lt+4>>2],f[a>>2]=f[Lt>>2],f[a+4>>2]=n,n=f[wt+4>>2],f[r>>2]=f[wt>>2],f[r+4>>2]=n,R=f[(h=pt+8|0)+4>>2],n=y=i+120|0,Tt=f[h>>2],f[n>>2]=Tt,f[n+4>>2]=R,Ot=f[(R=Gt+8|0)+4>>2],f[(n=h=o+8|0)>>2]=f[R>>2],f[n+4>>2]=Ot,Yt=f[(Ot=Lt+8|0)+4>>2],f[(n=R=a+8|0)>>2]=f[Ot>>2],f[n+4>>2]=Yt,Zt=f[(Yt=wt+8|0)+4>>2],f[(n=Ot=r+8|0)>>2]=f[Yt>>2],f[n+4>>2]=Zt,n=f[pt+4>>2],f[i+112>>2]=f[pt>>2],f[i+116>>2]=n,f[i+96>>2]=Tt,f[i+100>>2]=f[i+136>>2],f[i+108>>2]=0,f[i+104>>2]=f[i+152>>2],f[i+80>>2]=f[i+112>>2],f[i+84>>2]=f[i+128>>2],f[i+92>>2]=0,f[i+88>>2]=f[i+144>>2],d=C[e+1060>>2],g=C[e+1144>>2],m=C[e+1148>>2],p=C[e+1056>>2],Tt=0|yt[f[f[t>>2]+20>>2]](t),f[(n=i+72|0)>>2]=0,f[n+4>>2]=0,f[i+64>>2]=0,f[i+68>>2]=0,n=e+1348|0,yt[f[f[Tt>>2]+72>>2]](Tt,n,i+96|0,i+80|0,v(Dt*v(.8999999761581421)),p,d,g,m,i- -64|0,v(10),1),f[i+92>>2]=0,p=C[(Tt=i+148|0)>>2],f[i+88>>2]=f[Tt>>2],d=C[(Tt=i+132|0)>>2],f[i+84>>2]=f[Tt>>2],g=C[i+116>>2],f[i+80>>2]=f[i+116>>2],B=C[e+1368>>2],E=C[e+1372>>2],Yt=f[(Tt=e+1308|0)+4>>2],f[y>>2]=f[Tt>>2],f[y+4>>2]=Yt,Tt=f[(y=e+1316|0)+4>>2],f[o>>2]=f[y>>2],f[o+4>>2]=Tt,Tt=f[(y=e+1324|0)+4>>2],f[h>>2]=f[y>>2],f[h+4>>2]=Tt,h=f[(y=e+1332|0)+4>>2],f[a>>2]=f[y>>2],f[a+4>>2]=h,h=f[(y=e+1340|0)+4>>2],f[R>>2]=f[y>>2],f[R+4>>2]=h,y=f[n+4>>2],f[r>>2]=f[n>>2],f[r+4>>2]=y,h=f[(y=e+1356|0)+4>>2],f[Ot>>2]=f[y>>2],f[Ot+4>>2]=h,h=f[(y=e+1300|0)+4>>2],f[i+112>>2]=f[y>>2],f[i+116>>2]=h,m=dr(E),E=Cr(E),C[i+68>>2]=v(E*d)-v(m*g),D=dr(B),B=Cr(B),C[i+72>>2]=v(v(v(E*D)*g)+v(v(D*m)*d))+v(B*p),C[i+64>>2]=v(v(v(B*E)*g)+v(v(B*m)*d))-v(D*p),f[i+60>>2]=0,C[i+56>>2]=-C[i+144>>2],C[i+52>>2]=-C[i+128>>2],C[i+48>>2]=-C[i+112>>2],(d=C[e+968>>2])>(g=C[e+972>>2])?(y=0|yt[f[f[t>>2]+20>>2]](t),f[(h=i+40|0)>>2]=0,f[h+4>>2]=0,f[i+32>>2]=0,f[i+36>>2]=0,yt[f[f[y>>2]+68>>2]](y,n,i+48|0,i- -64|0,Dt,Dt,v(-3.1415927410125732),v(3.1415927410125732),i+32|0,0,v(10))):d>2]+20>>2]](t),f[(h=i+40|0)>>2]=0,f[h+4>>2]=0,f[i+32>>2]=0,f[i+36>>2]=0,yt[f[f[y>>2]+68>>2]](y,n,i+48|0,i- -64|0,Dt,Dt,d,g,i+32|0,1,v(10))),n=f[Gt+4>>2],f[o>>2]=f[Gt>>2],f[o+4>>2]=n,n=f[Lt+4>>2],f[a>>2]=f[Lt>>2],f[a+4>>2]=n,n=f[wt+4>>2],f[r>>2]=f[wt>>2],f[r+4>>2]=n,h=f[(y=pt+8|0)+4>>2],f[(n=i+120|0)>>2]=f[y>>2],f[n+4>>2]=h,Gt=f[(n=Gt+8|0)+4>>2],f[(o=o+8|0)>>2]=f[n>>2],f[o+4>>2]=Gt,n=f[(o=Lt+8|0)+4>>2],f[(a=a+8|0)>>2]=f[o>>2],f[a+4>>2]=n,o=f[(a=wt+8|0)+4>>2],f[(r=r+8|0)>>2]=f[a>>2],f[r+4>>2]=o,r=f[pt+4>>2],f[i+112>>2]=f[pt>>2],f[i+116>>2]=r,o=f[(a=e+688|0)+4>>2],f[(r=i+40|0)>>2]=f[a>>2],f[r+4>>2]=o,a=f[(r=e+680|0)+4>>2],f[i+32>>2]=f[r>>2],f[i+36>>2]=a,o=f[(a=e+704|0)+4>>2],f[(r=i+24|0)>>2]=f[a>>2],f[r+4>>2]=o,r=f[(e=e+696|0)+4>>2],f[i+16>>2]=f[e>>2],f[i+20>>2]=r,t=0|yt[f[f[t>>2]+20>>2]](t),f[(e=i+8|0)>>2]=0,f[e+4>>2]=0,f[i>>2]=0,f[i+4>>2]=0,yt[f[f[t>>2]+80>>2]](t,i+32|0,i+16|0,i+112|0,i);break t;case 4:case 6:case 7:break t;case 3:}o=f[(a=e+832|0)+4>>2],f[(r=pt=i+120|0)>>2]=f[a>>2],f[r+4>>2]=o,o=f[(a=e+848|0)+4>>2],f[(r=i+136|0)>>2]=f[a>>2],f[r+4>>2]=o,o=f[(a=e+864|0)+4>>2],f[(r=i+152|0)>>2]=f[a>>2],f[r+4>>2]=o,o=f[(a=e+880|0)+4>>2],f[(r=i+168|0)>>2]=f[a>>2],f[r+4>>2]=o,a=f[(r=Gt=e+824|0)+4>>2],f[i+112>>2]=f[r>>2],f[i+116>>2]=a,a=f[(r=e+840|0)+4>>2],f[i+128>>2]=f[r>>2],f[i+132>>2]=a,a=f[(r=e+856|0)+4>>2],f[i+144>>2]=f[r>>2],f[i+148>>2]=a,a=f[(r=e+872|0)+4>>2],f[i+160>>2]=f[r>>2],f[i+164>>2]=a,r=i+160|0,a=i+144|0,o=i+128|0,n?(n=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[n>>2]+64>>2]](n,i+112|0,Dt),wt=f[(Lt=e+944|0)+4>>2],f[(n=r+8|0)>>2]=f[Lt>>2],f[n+4>>2]=wt,Lt=f[(n=e+936|0)+4>>2],f[r>>2]=f[n>>2],f[r+4>>2]=Lt,n=f[(r=e+904|0)+4>>2],f[o>>2]=f[r>>2],f[o+4>>2]=n,r=o+8|0,n=f[(o=e+912|0)+4>>2],f[r>>2]=f[o>>2],f[r+4>>2]=n,o=f[(r=e+920|0)+4>>2],f[a>>2]=f[r>>2],f[a+4>>2]=o,r=a+8|0,o=f[(a=e+928|0)+4>>2],f[r>>2]=f[a>>2],f[r+4>>2]=o,a=f[(r=e+896|0)+4>>2],f[pt>>2]=f[r>>2],f[pt+4>>2]=a,a=f[(r=e+888|0)+4>>2],f[i+112>>2]=f[r>>2],f[i+116>>2]=a,r=0|yt[f[f[t>>2]+20>>2]](t),yt[f[f[r>>2]+64>>2]](r,i+112|0,Dt)):(Lt=f[(n=e+896|0)+4>>2],f[pt>>2]=f[n>>2],f[pt+4>>2]=Lt,pt=f[(n=e+904|0)+4>>2],f[o>>2]=f[n>>2],f[o+4>>2]=pt,pt=f[(n=e+912|0)+4>>2],f[(o=o+8|0)>>2]=f[n>>2],f[o+4>>2]=pt,n=f[(o=e+920|0)+4>>2],f[a>>2]=f[o>>2],f[a+4>>2]=n,n=f[(o=e+928|0)+4>>2],f[(a=a+8|0)>>2]=f[o>>2],f[a+4>>2]=n,o=f[(a=e+936|0)+4>>2],f[r>>2]=f[a>>2],f[r+4>>2]=o,o=f[(a=e+944|0)+4>>2],f[(r=r+8|0)>>2]=f[a>>2],f[r+4>>2]=o,a=f[(r=e+888|0)+4>>2],f[i+112>>2]=f[r>>2],f[i+116>>2]=a),y&&(a=_[e+180|0],d=C[(r=a?Gt:e+888|0)+48>>2],F=C[r+8>>2],V=C[r+4>>2],o=f[r+4>>2],g=C[r+52>>2],w=C[r+24>>2],m=C[r+16>>2],n=f[r+16>>2],Q=C[r+20>>2],pt=f[r+20>>2],p=C[r+56>>2],D=C[r+40>>2],B=C[r+32>>2],Gt=f[r+32>>2],W=C[r+36>>2],Lt=f[r+36>>2],E=C[(r=(a?824:888)+e|0)>>2],a=f[r>>2],f[i+108>>2]=0,Et=v(D*v(0)),W=v(W*v(0)),D=C[e+184>>2],C[i+104>>2]=p+v(Et+v(W+v(D*B))),w=v(w*v(0)),Q=v(Q*v(0)),C[i+100>>2]=g+v(w+v(Q+v(D*m))),F=v(F*v(0)),V=v(V*v(0)),C[i+96>>2]=d+v(F+v(V+v(D*E))),f[i+92>>2]=0,G=p,p=C[e+188>>2],C[i+88>>2]=G+v(Et+v(W+v(p*B))),C[i+84>>2]=g+v(w+v(Q+v(p*m))),C[i+80>>2]=d+v(F+v(V+v(p*E))),r=0|yt[f[f[t>>2]+20>>2]](t),f[(wt=i+72|0)>>2]=0,f[wt+4>>2]=0,f[i+64>>2]=0,f[i+68>>2]=0,yt[f[f[r>>2]+16>>2]](r,i+96|0,i+80|0,i- -64|0),f[i+76>>2]=0,f[i+72>>2]=Gt,f[i+68>>2]=n,f[i+64>>2]=a,f[i+60>>2]=0,f[i+56>>2]=Lt,f[i+52>>2]=pt,f[i+48>>2]=o,d=C[e+196>>2],g=C[e+192>>2],t=0|yt[f[f[t>>2]+20>>2]](t),f[(r=i+40|0)>>2]=0,f[r+4>>2]=0,f[i+32>>2]=0,f[i+36>>2]=0,yt[f[f[t>>2]+68>>2]](t,e+936|0,i- -64|0,i+48|0,Dt,Dt,g,d,i+32|0,1,v(10)))}Z=i+176|0},function(t){var e=0,i=0,r=0,n=0,a=0;if((0|(e=f[(t|=0)+248>>2]))>=1)for(;;){t:{e:if(r=f[f[t+256>>2]+i>>2],n=f[r+220>>2]+-2|0,!(n>>>0>3))switch(n-1|0){case 0:case 1:break e;default:break t}Ti(r),e=f[t+248>>2]}if(i=i+4|0,!((0|(a=a+1|0))<(0|e)))break}},Rr,function(t,e){t|=0,e=v(e);var i,r=0,n=0,a=0;if(Z=i=Z-16|0,Lr(i+8|0,23392),f[t+296>>2]>=1)for(;n=f[f[t+304>>2]+r>>2],yt[f[f[n>>2]+8>>2]](n,t,e),r=r+4|0,(0|(a=a+1|0))>2];);qr(),Z=i+16|0},function(t){var e=0;return f[(t|=0)>>2]=23768,(e=f[t+80>>2])&&(_[t+84|0]&&CA(e),f[t+80>>2]=0),f[t+80>>2]=0,f[t+72>>2]=0,f[t+76>>2]=0,n[t+84|0]=1,(e=f[t+60>>2])&&(_[t- -64|0]&&CA(e),f[t+60>>2]=0),f[t+60>>2]=0,f[t+52>>2]=0,f[t+56>>2]=0,n[t- -64|0]=1,(e=f[t+40>>2])&&(_[t+44|0]&&CA(e),f[t+40>>2]=0),f[t+40>>2]=0,f[t+32>>2]=0,f[t+36>>2]=0,n[t+44|0]=1,0|t},function(t){var e=0;f[(t|=0)>>2]=23768,(e=f[t+80>>2])&&(_[t+84|0]&&CA(e),f[t+80>>2]=0),f[t+80>>2]=0,f[t+72>>2]=0,f[t+76>>2]=0,n[t+84|0]=1,(e=f[t+60>>2])&&(_[t- -64|0]&&CA(e),f[t+60>>2]=0),f[t+60>>2]=0,f[t+52>>2]=0,f[t+56>>2]=0,n[t- -64|0]=1,!(e=f[t+40>>2])|!_[t+44|0]||CA(e),$(t)},function(t,e,i,r,a,o){t|=0,e|=0,i|=0,r|=0,a|=0;var h=0,d=0,C=0,g=0,m=0,y=0,p=0,R=0;if(!((0|(o|=0))>=0))return o=f[t+8>>2],void v(yt[f[f[o>>2]+12>>2]](o,e,i,r,a,f[t+12>>2],f[t+16>>2],f[t+4>>2],f[t+20>>2],f[t+24>>2]));t:{if((0|(g=f[t+16>>2]))>=1)for(y=f[t+12>>2];;){if(C=f[y>>2],(0|(h=f[f[C+28>>2]+208>>2]))<=-1&&(h=f[f[C+32>>2]+208>>2]),(0|h)==(0|o))break t;if(y=y+4|0,!((0|(d=d+1|0))<(0|g)))break}y=0}if((0|d)<(0|g))for(C=g-d|0,h=f[t+12>>2]+(d<<2)|0;g=f[h>>2],(0|(d=f[f[g+28>>2]+208>>2]))<=-1&&(d=f[f[g+32>>2]+208>>2]),h=h+4|0,p=((0|o)==(0|d))+p|0,C=C+-1|0;);if(o=f[t+4>>2],f[o+80>>2]<2)h=f[t+8>>2],v(yt[f[f[h>>2]+12>>2]](h,e,i,r,a,y,p,o,f[t+20>>2],f[t+24>>2]));else{if(!((0|i)<1))for(h=f[t+36>>2],d=f[t+32>>2];;){if(R=(m<<2)+e|0,(0|h)==(0|d))if((0|h)>=(0|(g=h?h<<1:1)))o=h;else{if(g?(C=dA(g<<2),o=f[t+32>>2]):(C=0,o=h),(0|o)>=1)for(h=0,d=o;f[h+C>>2]=f[f[t+40>>2]+h>>2],h=h+4|0,d=d+-1|0;);(h=f[t+40>>2])&&(_[t+44|0]&&(CA(h),o=f[t+32>>2]),f[t+40>>2]=0),f[t+40>>2]=C,n[t+44|0]=1,f[t+36>>2]=g,h=g}else o=d;if(d=o+1|0,f[t+32>>2]=d,f[f[t+40>>2]+(o<<2)>>2]=f[R>>2],(0|(m=m+1|0))==(0|i))break}if((0|a)>=1)for(h=f[t+56>>2],d=f[t+52>>2],m=0;;){if(i=(m<<2)+r|0,(0|h)==(0|d))if((0|h)>=(0|(e=h?h<<1:1)))o=h;else{if(e?(C=dA(e<<2),o=f[t+52>>2]):(C=0,o=h),(0|o)>=1)for(h=0,d=o;f[h+C>>2]=f[f[t+60>>2]+h>>2],h=h+4|0,d=d+-1|0;);(h=f[t+60>>2])&&(_[t+64|0]&&(CA(h),o=f[t+52>>2]),f[t+60>>2]=0),f[t+60>>2]=C,n[t+64|0]=1,f[t+56>>2]=e,h=e}else o=d;if(d=o+1|0,f[t+52>>2]=d,f[f[t+60>>2]+(o<<2)>>2]=f[i>>2],(0|(m=m+1|0))==(0|a))break}if(p)for(h=f[t+76>>2],d=f[t+72>>2],m=0;;){if(i=(m<<2)+y|0,(0|h)==(0|d))if((0|h)>=(0|(e=h?h<<1:1)))o=h;else{if(e?(C=dA(e<<2),o=f[t+72>>2]):(C=0,o=h),(0|o)>=1)for(h=0,d=o;f[h+C>>2]=f[f[t+80>>2]+h>>2],h=h+4|0,d=d+-1|0;);(r=f[t+80>>2])&&(_[t+84|0]&&(CA(r),o=f[t+72>>2]),f[t+80>>2]=0),f[t+80>>2]=C,n[t+84|0]=1,f[t+76>>2]=e,h=e}else o=d;if(d=o+1|0,f[t+72>>2]=d,f[f[t+80>>2]+(o<<2)>>2]=f[i>>2],(0|p)==(0|(m=m+1|0)))break}else d=f[t+72>>2];(f[t+52>>2]+d|0)>f[f[t+4>>2]+80>>2]&&Uf(t)}},ve,function(t,e){t|=0;var i,r,n=0;return i=f[(e|=0)>>2],r=f[t+84>>2],!(f[e+8>>2]&f[t+8>>2])|!(f[t+12>>2]&f[e+4>>2])|(0|i)==(0|r)||(t=f[t+96>>2],n=0|yt[f[f[t>>2]+28>>2]](t,r,i)),0|n},function(t,e,i){t|=0,e|=0,i|=0;var r=0,n=v(0),a=v(0),o=v(0),h=0,d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0);return n=v(1),(0|(r=f[e>>2]))==f[t+84>>2]|4&_[r+204|0]|v(v(v(v(C[t+32>>2]-C[t+16>>2])*C[e+8>>2])+v(v(C[t+36>>2]-C[t+20>>2])*C[e+12>>2]))+v(v(C[t+40>>2]-C[t+24>>2])*C[e+16>>2]))>=v(-C[t+88>>2])||(f[t+80>>2]=r,f[t+4>>2]=f[e+40>>2],i?(r=f[(i=e+8|0)+4>>2],f[t+48>>2]=f[i>>2],f[t+52>>2]=r,h=f[(i=i+8|0)+4>>2],f[(r=t+56|0)>>2]=f[i>>2],f[r+4>>2]=h):(d=C[r+12>>2],g=C[r+8>>2],m=C[r+28>>2],y=C[r+20>>2],p=C[r+24>>2],R=C[r+44>>2],D=C[r+36>>2],B=C[r+40>>2],E=C[r+4>>2],n=C[e+16>>2],a=C[e+8>>2],o=C[e+12>>2],f[t+60>>2]=0,C[t+56>>2]=v(v(a*D)+v(o*B))+v(n*R),C[t+52>>2]=v(v(a*y)+v(o*p))+v(n*m),C[t+48>>2]=v(v(E*a)+v(g*o))+v(d*n)),i=f[e+28>>2],f[t+64>>2]=f[e+24>>2],f[t+68>>2]=i,r=f[(i=e+32|0)+4>>2],f[(t=t+72|0)>>2]=f[i>>2],f[t+4>>2]=r,n=C[e+40>>2]),v(n)},function(t){var e;return f[(t|=0)>>2]=23960,(e=f[t+336>>2])&&(_[t+340|0]&&CA(e),f[t+336>>2]=0),f[t+336>>2]=0,f[t+328>>2]=0,f[t+332>>2]=0,n[t+340|0]=1,Ze(t),0|t},function(t){var e;f[(t|=0)>>2]=23960,(e=f[t+336>>2])&&(_[t+340|0]&&CA(e),f[t+336>>2]=0),f[t+336>>2]=0,f[t+328>>2]=0,f[t+332>>2]=0,n[t+340|0]=1,Ze(t),CA(t)},function(t,e,i){t|=0,i|=0;var r,a=0,o=0,h=0;r=f[(e|=0)>>2];t:{e:if(!((0|(i=f[t+328>>2]))<1)){for(e=f[t+336>>2],a=i;;){if((0|r)!=f[e>>2]){if(e=e+4|0,a=a+-1|0)continue;break e}break}if(a)break t}if(f[t+332>>2]==(0|i)&&!((0|i)>=(0|(o=i?i<<1:1)))){if(o&&(h=dA(o<<2),i=f[t+328>>2]),(0|i)>=1)for(e=0,a=i;f[e+h>>2]=f[f[t+336>>2]+e>>2],e=e+4|0,a=a+-1|0;);(e=f[t+336>>2])&&(_[t+340|0]&&(CA(e),i=f[t+328>>2]),f[t+336>>2]=0),f[t+336>>2]=h,f[t+332>>2]=o,n[t+340|0]=1}f[t+328>>2]=i+1,f[f[t+336>>2]+(i<<2)>>2]=r}},function(t,e,i,r){e|=0,i|=0,r|=0;var n=0,a=0;t:if(!((0|(i=f[(t|=0)+328>>2]))<1)){for(a=f[e>>2],r=0,e=n=f[t+336>>2];;){if((0|a)!=f[e>>2]){if(e=e+4|0,(0|(r=r+1|0))!=(0|i))continue;break t}break}(0|r)>=(0|i)||(r=t,t=i+-1|0,f[r+328>>2]=t,f[e>>2]=f[(t<<2)+n>>2])}},function(t){var e=0;return f[(t|=0)>>2]=24004,e=f[t+344>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+344>>2]),f[t>>2]=23960,(e=f[t+336>>2])&&(_[t+340|0]&&CA(e),f[t+336>>2]=0),f[t+336>>2]=0,f[t+328>>2]=0,f[t+332>>2]=0,n[t+340|0]=1,Ze(t),0|t},function(t){var e=0;f[(t|=0)>>2]=24004,e=f[t+344>>2],yt[f[f[e>>2]>>2]](e),CA(f[t+344>>2]),f[t>>2]=23960,(e=f[t+336>>2])&&(_[t+340|0]&&CA(e),f[t+336>>2]=0),f[t+336>>2]=0,f[t+328>>2]=0,f[t+332>>2]=0,n[t+340|0]=1,Ze(t),CA(t)},function(t,e,i){t|=0,e|=0;var r,a=0,o=0,h=0,d=0,C=0;i=(i|=0)||f[t+188>>2],r=f[e>>2];t:{e:if(!((0|(a=f[t+328>>2]))<1)){for(h=f[t+336>>2],o=a;;){if((0|r)!=f[h>>2]){if(h=h+4|0,o=o+-1|0)continue;break e}break}if(o)break t}if(f[t+332>>2]==(0|a)&&!((0|a)>=(0|(d=a?a<<1:1)))){if(d&&(C=dA(d<<2),a=f[t+328>>2]),(0|a)>=1)for(h=0,o=a;f[h+C>>2]=f[f[t+336>>2]+h>>2],h=h+4|0,o=o+-1|0;);(o=f[t+336>>2])&&(_[t+340|0]&&(CA(o),a=f[t+328>>2]),f[t+336>>2]=0),f[t+336>>2]=C,f[t+332>>2]=d,n[t+340|0]=1}f[f[t+336>>2]+(a<<2)>>2]=r,f[t+328>>2]=a+1,t=f[t+344>>2],yt[f[f[t>>2]+8>>2]](t,i,e)}},function(t,e,i,r){t|=0,i|=0,r|=0;var n,a,o=0,_=0,h=0;a=f[(e|=0)>>2],r=r||f[t+188>>2];t:if(!((0|(n=f[t+328>>2]))<1)){for(o=h=f[t+336>>2];;){if((0|a)!=f[o>>2]){if(o=o+4|0,(0|(_=_+1|0))!=(0|n))continue;break t}break}(0|_)>=(0|n)||(_=o,o=n+-1|0,f[_>>2]=f[(o<<2)+h>>2],f[t+328>>2]=o,t=f[t+344>>2],yt[f[f[t>>2]+12>>2]](t,r,e,i))}},function(t){var e;return f[(t|=0)>>2]=24116,(e=f[t+212>>2])&&(_[t+216|0]&&CA(e),f[t+212>>2]=0),f[t+212>>2]=0,f[t+204>>2]=0,f[t+208>>2]=0,n[t+216|0]=1,0|t},function(t){var e;f[(t|=0)>>2]=24116,(e=f[t+212>>2])&&(_[t+216|0]&&CA(e),f[t+212>>2]=0),f[t+212>>2]=0,f[t+204>>2]=0,f[t+208>>2]=0,n[t+216|0]=1,CA(t)},function(t,e,i){t|=0,e|=0,i=v(i),yt[f[f[t>>2]+32>>2]](t,e),yt[f[f[t>>2]+36>>2]](t,e,i)},Rr,function(t,e){t|=0,e|=0;var i,r=v(0),a=v(0),o=v(0),_=v(0),h=0;n[t+251|0]=1,h=f[e+4>>2],f[t+68>>2]=f[e>>2],f[t+72>>2]=h,i=f[(e=e+8|0)+4>>2],f[(h=t+76|0)>>2]=f[e>>2],f[h+4>>2]=i,r=C[t+68>>2],a=C[t+72>>2],o=C[h>>2],(_=v(E(v(v(v(r*r)+v(a*a))+v(o*o)))))>v(1.1920928955078125e-7)?(_=v(v(1)/_),o=v(o*_),a=v(a*_),r=v(r*_),e=f[t+80>>2]):(r=v(0),a=v(0),o=v(0),e=0),C[t+84>>2]=r,f[t+96>>2]=e,C[t+92>>2]=o,C[t+88>>2]=a},function(t,e,i){t|=0,e|=0,i=v(i);var r,a=0,o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=0;n[t+251|0]=0,a=f[e+4>>2],f[t+68>>2]=f[e>>2],f[t+72>>2]=a,r=f[(e=e+8|0)+4>>2],f[(a=t+76|0)>>2]=f[e>>2],f[a+4>>2]=r,_=C[t+68>>2],h=C[t+72>>2],d=C[a>>2],(g=v(E(v(v(v(_*_)+v(h*h))+v(d*d)))))>v(1.1920928955078125e-7)&&(o=v(v(1)/g),m=v(d*o),y=v(h*o),o=v(_*o),p=f[t+80>>2]),C[t+84>>2]=o,f[t+96>>2]=p,C[t+92>>2]=m,C[t+88>>2]=y,C[t+252>>2]=C[t+252>>2]+i},function(t,e){e|=0;var i,r=0,n=0,o=0,_=0,h=0;if(f[(t|=0)+68>>2]=0,f[t+72>>2]=0,f[(i=t+76|0)>>2]=0,f[i+4>>2]=0,f[t+252>>2]=0,a[t+248>>1]=0,f[t+20>>2]=0,f[t+24>>2]=0,t=f[f[t+8>>2]+344>>2],f[4+(0|yt[f[f[t>>2]+28>>2]](t))>>2]>=1)for(;n=t,o=f[f[12+(0|yt[f[f[t>>2]+28>>2]](t))>>2]>>2],_=f[f[12+(0|yt[f[f[t>>2]+28>>2]](t))>>2]+4>>2],h=f[e+24>>2],r=f[f[t>>2]+12>>2],yt[r](0|n,0|o,0|_,0|h),f[4+(0|yt[f[f[t>>2]+28>>2]](t))>>2]>0;);},function(t,e){t|=0;var i,r,n=0,a=0;i=f[(a=(e|=0)+8|0)>>2],a=f[a+4>>2],r=f[e>>2],e=f[e+4>>2],t=f[t+8>>2],f[(n=t+44|0)>>2]=1065353216,f[n+4>>2]=0,f[(n=t+36|0)>>2]=0,f[n+4>>2]=0,f[t+24>>2]=1065353216,f[(n=t+28|0)>>2]=0,f[n+4>>2]=0,f[(n=t+16|0)>>2]=0,f[n+4>>2]=0,f[t+4>>2]=1065353216,f[(n=t+8|0)>>2]=0,f[n+4>>2]=0,f[(n=t+60|0)>>2]=i,f[n+4>>2]=a,f[(a=t+52|0)>>2]=r,f[a+4>>2]=e,f[t+304>>2]=f[t+304>>2]+1},function(t,e){e|=0;var i,r=0,n=0,a=0,o=0,_=0;Z=e=Z-16|0,a=f[(t|=0)+8>>2],o=f[(r=a+52|0)+4>>2],f[t+132>>2]=f[r>>2],f[t+136>>2]=o,_=f[(n=a+60|0)+4>>2],f[(o=t+140|0)>>2]=f[n>>2],f[o+4>>2]=_,o=f[r>>2],r=f[r+4>>2],_=f[n+4>>2],f[(i=t+160|0)>>2]=f[n>>2],f[i+4>>2]=_,f[t+152>>2]=o,f[t+156>>2]=r,tt(a+4|0,e),o=f[(n=e+8|0)+4>>2],f[(r=a=t+176|0)>>2]=f[n>>2],f[r+4>>2]=o,r=f[e+4>>2],f[t+168>>2]=f[e>>2],f[t+172>>2]=r,n=f[a+4>>2],f[(r=t+192|0)>>2]=f[a>>2],f[r+4>>2]=n,a=f[t+172>>2],f[t+184>>2]=f[t+168>>2],f[t+188>>2]=a,Z=e+16|0},function(t,e,i){t|=0,e|=0,i=v(i);var r,a=0,o=0,h=0,d=v(0),g=0,m=v(0),p=v(0),R=0,D=v(0),B=v(0),F=v(0),V=0,G=0,w=v(0),Q=v(0),W=v(0),Y=v(0),z=0,pt=v(0),Dt=0,It=0,St=0,Tt=0,Et=0,Ot=0,Nt=0,Ft=0,Vt=0;Z=r=Z-80|0,d=C[t+100>>2],m=C[t+104>>2],D=C[t+108>>2],(p=v(v(v(d*d)+v(m*m))+v(D*D)))>v(0)&&(p=Vi(v(v(1)-C[t+244>>2]),i),D=v(D*p),C[t+108>>2]=D,m=v(m*p),C[t+104>>2]=m,d=v(d*p),C[t+100>>2]=d,p=v(v(v(d*d)+v(m*m))+v(D*D))),p>v(0)&&(a=f[t+8>>2],g=f[(h=a+12|0)>>2],V=f[h+4>>2],R=f[a+4>>2],G=f[a+8>>2],Dt=f[(z=a+28|0)+4>>2],f[(o=h=r+40|0)>>2]=f[z>>2],f[o+4>>2]=Dt,f[(o=r+24|0)>>2]=g,f[o+4>>2]=V,z=f[(g=a+36|0)>>2],Dt=f[g+4>>2],St=f[(g=a+20|0)>>2],Tt=f[g+4>>2],Et=f[(g=a+44|0)>>2],Ot=f[g+4>>2],Nt=f[(It=a+60|0)+4>>2],f[(g=V=r+72|0)>>2]=f[It>>2],f[g+4>>2]=Nt,f[(g=r+56|0)>>2]=Et,f[g+4>>2]=Ot,f[r+16>>2]=R,f[r+20>>2]=G,f[r+32>>2]=St,f[r+36>>2]=Tt,R=f[(a=a+52|0)+4>>2],f[r+64>>2]=f[a>>2],f[r+68>>2]=R,f[r+48>>2]=z,f[r+52>>2]=Dt,F=v(E(p)),Q=dr(w=v(v(F*i)*v(.5))),tt(r+16|0,r),p=C[r+12>>2],W=C[r>>2],w=Cr(w),B=d,d=v(v(1)/F),F=v(B*d),B=v(D*d),d=v(m*d),m=v(Q/v(E(v(v(B*B)+v(v(F*F)+v(d*d)))))),D=v(F*m),F=v(d*m),Q=C[r+8>>2],B=v(B*m),Y=C[r+4>>2],d=v(v(v(v(W*w)+v(p*D))+v(F*Q))-v(B*Y)),m=v(v(v(v(w*p)-v(D*W))-v(F*Y))-v(B*Q)),pt=v(v(v(v(B*p)+v(w*Q))+v(D*Y))-v(F*W)),D=v(v(v(B*W)+v(v(F*p)+v(w*Y)))-v(D*Q)),p=v(v(2)/v(v(m*m)+v(v(pt*pt)+v(v(d*d)+v(D*D))))),W=v(pt*p),F=v(d*W),w=v(D*p),Q=v(m*w),C[o>>2]=F+Q,f[r+60>>2]=0,f[r+44>>2]=0,B=v(D*W),p=v(d*p),Y=v(m*p),C[r+52>>2]=B+Y,C[h>>2]=B-Y,p=v(d*p),D=v(D*w),C[g>>2]=v(1)-v(p+D),B=p,p=v(pt*W),C[r+36>>2]=v(1)-v(B+p),f[r+28>>2]=0,C[r+48>>2]=F-Q,d=v(d*w),m=v(m*W),C[r+32>>2]=d+m,C[r+20>>2]=d-m,G=f[o+4>>2],a=f[t+8>>2],f[(R=a+12|0)>>2]=f[o>>2],f[R+4>>2]=G,C[r+16>>2]=v(1)-v(D+p),o=f[r+20>>2],f[a+4>>2]=f[r+16>>2],f[a+8>>2]=o,R=f[r+36>>2],f[(o=a+20|0)>>2]=f[r+32>>2],f[o+4>>2]=R,R=f[h+4>>2],f[(o=a+28|0)>>2]=f[h>>2],f[o+4>>2]=R,f[a+304>>2]=f[a+304>>2]+1,o=f[r+52>>2],f[(h=a+36|0)>>2]=f[r+48>>2],f[h+4>>2]=o,o=f[g+4>>2],f[(h=a+44|0)>>2]=f[g>>2],f[h+4>>2]=o,o=f[V+4>>2],f[(h=a+60|0)>>2]=f[V>>2],f[h+4>>2]=o,h=f[r+68>>2],f[(a=a+52|0)>>2]=f[r+64>>2],f[a+4>>2]=h,a=f[t+8>>2],g=f[(o=h=a+52|0)+4>>2],f[t+132>>2]=f[o>>2],f[t+136>>2]=g,R=f[(o=a+60|0)+4>>2],f[(g=t+140|0)>>2]=f[o>>2],f[g+4>>2]=R,g=f[h>>2],h=f[h+4>>2],R=f[o+4>>2],f[(V=t+160|0)>>2]=f[o>>2],f[V+4>>2]=R,f[t+152>>2]=g,f[t+156>>2]=h,tt(a+4|0,r),g=f[(o=r+8|0)+4>>2],f[(a=t+176|0)>>2]=f[o>>2],f[a+4>>2]=g,h=f[r+4>>2],f[t+168>>2]=f[r>>2],f[t+172>>2]=h,o=f[a+4>>2],f[(h=t+192|0)>>2]=f[a>>2],f[h+4>>2]=o,a=f[t+172>>2],f[t+184>>2]=f[t+168>>2],f[t+188>>2]=a),C[t+252>>2]<=v(0)&&!_[t+251|0]||(Ft=t,Vt=0|yt[f[f[t>>2]+48>>2]](t),n[Ft+248|0]=Vt,m=C[t+72>>2],D=C[t+68>>2],p=C[t+76>>2],d=Vi(v(v(1)-C[t+240>>2]),i),v(v(v(D*D)+v(m*m))+v(p*p))>v(0)&&(C[t+76>>2]=p*d,C[t+72>>2]=m*d,C[t+68>>2]=D*d),d=v(v(C[t+20>>2]*d)-v(C[t+52>>2]*i)),C[t+20>>2]=d,d>v(0)&&(d>(m=C[t+32>>2])&&(C[t+20>>2]=m,d=m)),d>2])),v(y(d))>m&&(d=v(-m),C[t+20>>2]=d)),C[t+24>>2]=d*i,a=f[t+8>>2],g=f[(o=a+12|0)+4>>2],f[(h=r+24|0)>>2]=f[o>>2],f[h+4>>2]=g,g=f[(o=a+28|0)+4>>2],f[(h=r+40|0)>>2]=f[o>>2],f[h+4>>2]=g,g=f[(o=a+44|0)+4>>2],f[(h=r+56|0)>>2]=f[o>>2],f[h+4>>2]=g,g=f[(o=a+60|0)+4>>2],f[(h=r+72|0)>>2]=f[o>>2],f[h+4>>2]=g,h=f[a+8>>2],f[r+16>>2]=f[a+4>>2],f[r+20>>2]=h,o=f[(h=a+20|0)+4>>2],f[r+32>>2]=f[h>>2],f[r+36>>2]=o,o=f[(h=a+36|0)+4>>2],f[r+48>>2]=f[h>>2],f[r+52>>2]=o,h=f[(a=a+52|0)+4>>2],f[r+64>>2]=f[a>>2],f[r+68>>2]=h,function(t,e){var i,r,a,o=0,h=0,d=v(0),g=0,m=0,y=0,p=v(0),R=v(0),D=v(0),B=0,E=v(0),F=v(0),V=0,G=v(0),w=0,Q=0,W=v(0),Y=v(0),z=0,pt=v(0),Dt=v(0),It=v(0),St=v(0);Z=i=Z-240|0,C[t+20>>2]>2],h=f[t+60>>2]),f[(o=z=i+200|0)>>2]=0,f[o+4>>2]=0,f[(Q=i+196|0)>>2]=1065353216,f[(o=y=i+216|0)>>2]=1065353216,f[o+4>>2]=0,f[(o=B=i+136|0)>>2]=0,f[o+4>>2]=0,f[(w=i+132|0)>>2]=1065353216,f[(o=r=i+152|0)>>2]=1065353216,f[o+4>>2]=0,V=f[(o=t+140|0)+4>>2],f[(m=i+232|0)>>2]=f[o>>2],f[m+4>>2]=V,f[i+180>>2]=0,f[i+184>>2]=0,f[i+176>>2]=1065353216,f[i+188>>2]=0,f[i+192>>2]=0,f[i+208>>2]=0,f[i+212>>2]=0,f[i+116>>2]=0,f[i+120>>2]=0,f[i+112>>2]=1065353216,f[i+124>>2]=0,f[i+128>>2]=0,f[i+144>>2]=0,f[i+148>>2]=0,m=f[t+136>>2],f[i+224>>2]=f[t+132>>2],f[i+228>>2]=m,Dt=C[t+256>>2],d=(d=C[t+24>>2])>v(0)?d:v(0),C[t+152>>2]=v(v(Y*Dt)+C[t+132>>2])+v(C[t+272>>2]*d),It=C[t+260>>2],C[t+156>>2]=v(v(Y*It)+C[t+136>>2])+v(d*C[t+276>>2]),f[t+164>>2]=0,m=t+160|0,St=C[t+264>>2],C[m>>2]=v(v(Y*St)+C[o>>2])+v(d*C[t+280>>2]),g=f[t+156>>2],a=f[t+152>>2],f[t+132>>2]=a,f[t+136>>2]=g,V=f[m+4>>2],m=f[m>>2],f[o>>2]=m,f[o+4>>2]=V,f[(o=i+168|0)>>2]=m,f[o+4>>2]=V,f[i+160>>2]=a,f[i+164>>2]=g,R=C[t+180>>2],E=C[t+176>>2],p=C[t+172>>2],d=C[t+168>>2],f[i+220>>2]=0,f[i+204>>2]=0,G=v(v(2)/v(v(v(v(d*d)+v(p*p))+v(E*E))+v(R*R))),W=v(E*G),D=v(p*W),F=v(d*G),pt=v(R*F),C[i+212>>2]=D+pt,C[z>>2]=D-pt,D=v(d*F),F=p,p=v(p*G),G=v(F*p),C[y>>2]=v(1)-v(D+G),E=v(E*W),C[Q>>2]=v(1)-v(D+E),f[i+188>>2]=0,D=v(d*W),F=v(R*p),C[i+208>>2]=D-F,d=v(d*p),R=v(R*W),C[i+192>>2]=d+R,C[i+184>>2]=D+F,C[i+180>>2]=d-R,C[i+176>>2]=v(1)-v(G+E),R=C[t+196>>2],E=C[t+192>>2],p=C[t+188>>2],d=C[t+184>>2],f[i+156>>2]=0,f[i+140>>2]=0,G=v(v(2)/v(v(v(v(d*d)+v(p*p))+v(E*E))+v(R*R))),W=v(E*G),D=v(p*W),F=v(d*G),pt=v(R*F),C[i+148>>2]=D+pt,C[B>>2]=D-pt,D=v(d*F),F=p,p=v(p*G),G=v(F*p),C[r>>2]=v(1)-v(D+G),E=v(E*W),C[w>>2]=v(1)-v(D+E),f[i+124>>2]=0,D=v(d*W),F=v(R*p),C[i+144>>2]=D-F,d=v(d*p),R=v(R*W),C[i+128>>2]=d+R,C[i+120>>2]=D+F,C[i+116>>2]=d-R,C[i+112>>2]=v(1)-v(G+E),f[(o=i+24|0)>>2]=0,f[o+4>>2]=0,f[(o=i+32|0)>>2]=0,f[o+4>>2]=0,f[(o=i+40|0)>>2]=0,f[o+4>>2]=0,f[i+100>>2]=0,C[i+96>>2]=-St,C[i+92>>2]=-It,f[i+16>>2]=0,f[i+20>>2]=0,C[i+88>>2]=-Dt,f[i+80>>2]=0,f[i+4>>2]=1065353216,f[i>>2]=24320,o=f[t+8>>2],f[i+84>>2]=o,f[i+104>>2]=f[t+48>>2],m=f[o+188>>2],f[i+8>>2]=f[m+4>>2],f[i+12>>2]=f[m+8>>2],_[t+250|0]?Sf(o,f[t+12>>2],i+176|0,i+112|0,i,C[e+56>>2]):_f(e,f[t+12>>2],i+176|0,i+112|0,i,C[e+56>>2]),m=t+152|0,o=t+132|0;t:{e:{i:{if(C[i+4>>2]>2],!(4&_[g+204|0])&&yt[f[f[t>>2]+56>>2]](t,g,f[i+80>>2]))){if(v(v(v(C[i+48>>2]*C[t+256>>2])+v(C[i+52>>2]*C[t+260>>2]))+v(C[i+56>>2]*C[t+264>>2]))>v(0)&&(d=C[i+4>>2],C[t+148>>2]=Y*d,_[t+288|0]?(Y=v(v(1)-d),C[t+132>>2]=v(Y*C[t+132>>2])+v(d*C[t+152>>2]),C[t+136>>2]=v(Y*C[t+136>>2])+v(d*C[t+156>>2]),C[t+140>>2]=v(Y*C[t+140>>2])+v(d*C[t+160>>2])):(h=f[m+4>>2],f[o>>2]=f[m>>2],f[o+4>>2]=h,V=f[(g=m+8|0)+4>>2],f[(h=o+8|0)>>2]=f[g>>2],f[h+4>>2]=V)),y=f[(Q=z=o+8|0)+4>>2],g=f[t+8>>2],f[(h=V=g+60|0)>>2]=f[Q>>2],f[h+4>>2]=y,y=f[o+4>>2],f[(h=Q=g+52|0)>>2]=f[o>>2],f[h+4>>2]=y,h=f[t+8>>2],f[h+304>>2]=f[h+304>>2]+1,w=f[(B=g+12|0)+4>>2],f[(y=h+12|0)>>2]=f[B>>2],f[y+4>>2]=w,y=f[g+8>>2],f[h+4>>2]=f[g+4>>2],f[h+8>>2]=y,w=f[(B=g+28|0)+4>>2],f[(y=h+28|0)>>2]=f[B>>2],f[y+4>>2]=w,w=f[(B=g+20|0)+4>>2],f[(y=h+20|0)>>2]=f[B>>2],f[y+4>>2]=w,w=f[(B=g+44|0)+4>>2],f[(y=h+44|0)>>2]=f[B>>2],f[y+4>>2]=w,B=f[(g=g+36|0)+4>>2],f[(y=h+36|0)>>2]=f[g>>2],f[y+4>>2]=B,y=f[Q+4>>2],f[(g=h+52|0)>>2]=f[Q>>2],f[g+4>>2]=y,g=f[V+4>>2],f[(h=h+60|0)>>2]=f[V>>2],f[h+4>>2]=g,n[t+220|0]=0,!jf(t,e))break e;if(n[t+220|0]=1,jf(t,e))break i;break e}f[t+148>>2]=h,t=f[m+4>>2],f[o>>2]=f[m>>2],f[o+4>>2]=t,t=o+8|0,o=f[(e=m+8|0)+4>>2],f[t>>2]=f[e>>2],f[t+4>>2]=o;break t}n[t+220|0]=1,jf(t,e)&&(n[t+220|0]=1,jf(t,e)&&(n[t+220|0]=1,jf(t,e)&&(n[t+220|0]=1)))}h=f[t+8>>2],V=f[(g=e=h+52|0)+4>>2],f[m>>2]=f[g>>2],f[m+4>>2]=V,V=f[(h=h+60|0)+4>>2],f[(m=m+8|0)>>2]=f[h>>2],f[m+4>>2]=V,m=f[e>>2],e=f[e+4>>2],g=f[h+4>>2],f[z>>2]=f[h>>2],f[z+4>>2]=g,f[o>>2]=m,f[o+4>>2]=e,C[t+24>>2]>v(0)&&(f[t+20>>2]=0,f[t+24>>2]=0,f[t+148>>2]=f[t+60>>2])}Z=i+240|0}(t,e),g=r- -64|0,h=r+48|0,a=r+32|0,_[t+251|0]?Hf(t,e,t+68|0):(d=C[t+252>>2],C[t+252>>2]=d-i,f[r+12>>2]=0,d=d>i?i:d,C[r+8>>2]=d*C[t+76>>2],C[r+4>>2]=d*C[t+72>>2],C[r>>2]=d*C[t+68>>2],Hf(t,e,r)),function(t,e,i){var r,a=v(0),o=0,h=0,d=v(0),g=0,m=v(0),y=0,p=0,R=v(0),D=v(0),B=v(0),E=0,F=v(0),V=v(0),G=v(0),w=0,Q=0,W=v(0),Y=v(0),z=v(0),pt=0,Dt=0,It=0,St=0,Tt=v(0),Et=v(0),Ot=0,Nt=0;Z=r=Z-432|0,h=f[(g=t+160|0)+4>>2],f[(y=r+232|0)>>2]=f[g>>2],f[y+4>>2]=h,y=f[t+156>>2],f[r+224>>2]=f[t+152>>2],f[r+228>>2]=y;t:if(!((a=C[t+20>>2])>v(0))){for((a=v((av(0)&&(a>(d=C[t+28>>2])^1|(_[t+249|0]?!_[t+248|0]:0)||(a=d)),y=t+152|0,a=v(a+C[t+148>>2]),W=v(C[t+256>>2]*a),C[t+152>>2]=C[t+152>>2]-W,g=t+156|0,Y=v(a*C[t+260>>2]),C[g>>2]=C[g>>2]-Y,E=g=t+160|0,m=C[g>>2],z=v(a*C[(g=t+264|0)>>2]),C[E>>2]=m-z,f[(h=r+136|0)>>2]=0,f[h+4>>2]=0,f[(h=r+144|0)>>2]=0,f[h+4>>2]=0,f[(h=r+152|0)>>2]=0,f[h+4>>2]=0,o=f[g+4>>2],f[(h=r+208|0)>>2]=f[g>>2],f[h+4>>2]=o,f[r+128>>2]=0,f[r+132>>2]=0,h=f[t+260>>2],f[r+200>>2]=f[t+256>>2],f[r+204>>2]=h,f[r+192>>2]=0,f[r+116>>2]=1065353216,f[r+112>>2]=24320,o=f[t+8>>2],f[r+196>>2]=o,w=f[t+48>>2],f[r+216>>2]=w,h=f[o+188>>2],f[r+120>>2]=f[h+4>>2],f[r+124>>2]=f[h+8>>2],f[(p=r+24|0)>>2]=0,f[p+4>>2]=0,f[(p=r+32|0)>>2]=0,f[p+4>>2]=0,f[(p=r+40|0)>>2]=0,f[p+4>>2]=0,pt=f[g+4>>2],f[(p=r+96|0)>>2]=f[g>>2],f[p+4>>2]=pt,f[r+80>>2]=0,f[r+4>>2]=1065353216,f[r+16>>2]=0,f[r+20>>2]=0,f[r+84>>2]=o,g=f[t+260>>2],f[r+88>>2]=f[t+256>>2],f[r+92>>2]=g,f[r>>2]=24320,f[r+104>>2]=w,g=f[h+8>>2],f[r+8>>2]=f[h+4>>2],f[r+12>>2]=g,g=t+132|0,w=r+352|0,p=r+416|0,pt=r+264|0,It=r+240|4,St=r+328|0,Ot=(Dt=r+284|0)+16|0,h=0;;){f[St>>2]=0,f[St+4>>2]=0,f[It>>2]=0,f[It+4>>2]=0,f[pt>>2]=0,f[pt+4>>2]=0,f[Dt>>2]=0,f[Dt+4>>2]=0,f[(o=St+8|0)>>2]=0,f[o+4>>2]=0,f[(o=It+8|0)>>2]=0,f[o+4>>2]=0,f[(o=pt+8|0)>>2]=0,f[o+4>>2]=0,f[(o=Dt+8|0)>>2]=0,f[o+4>>2]=0,f[Ot>>2]=0,o=f[g+4>>2],f[p>>2]=f[g>>2],f[p+4>>2]=o,E=f[(Q=g+8|0)+4>>2],f[(o=p+8|0)>>2]=f[Q>>2],f[o+4>>2]=E,f[r+324>>2]=1065353216,f[r+316>>2]=0,f[r+320>>2]=0,f[r+344>>2]=1065353216,f[r+348>>2]=0,f[r+240>>2]=1065353216,f[r+260>>2]=1065353216,f[r+280>>2]=1065353216,Nt=f[(E=Q=y+8|0)+4>>2],f[(o=w+8|0)>>2]=f[E>>2],f[o+4>>2]=Nt,o=f[y+4>>2],f[w>>2]=f[y>>2],f[w+4>>2]=o,f[r+412>>2]=0,f[r+396>>2]=0,f[r+380>>2]=0,a=C[t+168>>2],d=C[t+172>>2],R=C[t+176>>2],m=C[t+180>>2],B=v(v(2)/v(v(v(v(a*a)+v(d*d))+v(R*R))+v(m*m))),G=v(d*B),D=v(a*G),V=v(R*B),F=v(m*V),C[r+372>>2]=D-F,Tt=v(a*V),Et=v(m*G),C[r+376>>2]=Tt+Et,C[r+384>>2]=D+F,D=v(d*V),F=m,m=v(a*B),B=v(F*m),C[r+392>>2]=D-B,C[r+400>>2]=Tt-Et,C[r+404>>2]=D+B,d=v(d*G),R=v(R*V),C[r+368>>2]=v(1)-v(d+R),a=v(a*m),C[r+388>>2]=v(1)-v(a+R),C[r+408>>2]=v(1)-v(a+d),f[r+316>>2]=0,f[r+332>>2]=0,f[r+348>>2]=0,a=C[t+184>>2],d=C[t+188>>2],R=C[t+192>>2],m=C[t+196>>2],B=v(v(2)/v(v(v(v(a*a)+v(d*d))+v(R*R))+v(m*m))),G=v(d*B),D=v(a*G),V=v(R*B),F=v(m*V),C[r+320>>2]=D+F,C[r+308>>2]=D-F,D=v(a*V),F=v(m*G),C[r+336>>2]=D-F,C[r+312>>2]=D+F,D=v(d*V),F=m,m=v(a*B),B=v(F*m),C[r+340>>2]=D+B,C[r+328>>2]=D-B,d=v(d*G),R=v(R*V),C[r+304>>2]=v(1)-v(d+R),a=v(a*m),C[r+344>>2]=v(1)-v(a+d),C[r+324>>2]=v(1)-v(a+R),a=C[t+152>>2],d=C[t+156>>2],m=C[t+160>>2],f[r+300>>2]=0,C[r+296>>2]=m-z,C[r+292>>2]=d-Y,C[r+288>>2]=a-W;e:if(_[t+250|0]){if(Sf(f[t+8>>2],f[t+12>>2],r+368|0,r+304|0,r+112|0,C[e+56>>2]),C[r+116>>2]>2],4&_[o+204|0])break e;Sf(o,f[t+12>>2],r+368|0,r+240|0,r,C[e+56>>2])}else _f(e,f[t+12>>2],r+368|0,r+304|0,r+112|0,C[e+56>>2]),4&_[f[t+8>>2]+204|0]|C[r+116>>2]>2],r+368|0,r+240|0,r,C[e+56>>2]);a=(a=C[t+20>>2])>2]>2]>2],4&_[E+204|0])break e;o=0|yt[f[f[t>>2]+56>>2]](t,E,f[r+192>>2])}else o=0,C[r+4>>2]>2],4&_[E+204|0]||(o=0|yt[f[f[t>>2]+56>>2]](t,E,f[r+80>>2])));d=v(a*i),a=v(0);e:{i:{if(a=C[t+20>>2]>2],!(1&(d>v(0)^-1|d>2];A:{if(!(4&_[e+204|0]|C[r+116>>2]>2]+56>>2]](t,e,f[r+192>>2])|h))break A;break e}if(!h)break e}i=C[t+136>>2],a=_[t+290|0]?_[t+289|0]?C[r+116>>2]:v(v(i-C[r+180>>2])*v(.5)):C[r+116>>2],n[t+289|0]=0,n[t+249|0]=0,f[t+20>>2]=0,f[t+24>>2]=0,d=v(v(1)-a),C[t+132>>2]=v(d*C[t+132>>2])+v(a*C[t+152>>2]),C[t+136>>2]=v(i*d)+v(a*C[t+156>>2]),C[(e=t+140|0)>>2]=v(d*C[e>>2])+v(a*C[t+160>>2]);break t}h=f[r+228>>2],f[y>>2]=f[r+224>>2],f[y+4>>2]=h,o=f[(h=r+232|0)+4>>2],f[Q>>2]=f[h>>2],f[Q+4>>2]=o,a=v(a+C[t+148>>2]),W=v(C[t+256>>2]*a),C[t+152>>2]=C[t+152>>2]-W,Y=v(a*C[t+260>>2]),C[t+156>>2]=C[t+156>>2]-Y,z=v(a*C[t+264>>2]),C[t+160>>2]=C[t+160>>2]-z,h=1;continue}break}n[t+289|0]=1,_[t+290|0]&&(a=C[t+20>>2],(a=v((a(i=C[t+28>>2])^1|(_[t+249|0]?!_[t+248|0]:0)||(i=v(i+C[t+148>>2]),C[t+160>>2]=v(z+C[t+160>>2])-v(i*C[t+264>>2]),C[t+156>>2]=v(Y+C[t+156>>2])-v(i*C[t+260>>2]),C[t+152>>2]=v(W+C[t+152>>2])-v(C[t+256>>2]*i))),t=f[y+4>>2],f[g>>2]=f[y>>2],f[g+4>>2]=t,y=f[(e=y+8|0)+4>>2],f[(t=g+8|0)>>2]=f[e>>2],f[t+4>>2]=y}Z=r+432|0}(t,e,i),G=f[(R=t+140|0)+4>>2],f[(o=V=g+8|0)>>2]=f[R>>2],f[o+4>>2]=G,o=f[t+136>>2],f[g>>2]=f[t+132>>2],f[g+4>>2]=o,G=f[r+20>>2],o=f[t+8>>2],f[o+4>>2]=f[r+16>>2],f[o+8>>2]=G,G=f[a+4>>2],f[(R=o+20|0)>>2]=f[a>>2],f[R+4>>2]=G,G=f[(a=a+8|0)+4>>2],f[(R=o+28|0)>>2]=f[a>>2],f[R+4>>2]=G,h=f[(a=h)+4>>2],f[(R=o+36|0)>>2]=f[a>>2],f[R+4>>2]=h,R=f[(a=a+8|0)+4>>2],f[(h=o+44|0)>>2]=f[a>>2],f[h+4>>2]=R,R=f[(h=r+24|0)+4>>2],f[(a=o+12|0)>>2]=f[h>>2],f[a+4>>2]=R,f[o+304>>2]=f[o+304>>2]+1,h=f[g+4>>2],f[(a=o+52|0)>>2]=f[g>>2],f[a+4>>2]=h,h=f[V+4>>2],f[(a=o+60|0)>>2]=f[V>>2],f[a+4>>2]=h,n[t+220|0]=0,jf(t,e)&&(n[t+220|0]=1,jf(t,e)&&(n[t+220|0]=1,jf(t,e)&&(n[t+220|0]=1,jf(t,e)&&(n[t+220|0]=1,jf(t,e)&&(n[t+220|0]=1)))))),Z=r+80|0},zf,function(t,e){t|=0,e|=0;var i=v(0),r=v(0),a=v(0),o=v(0),_=0,h=0;_=t,i=C[e>>2],r=v(i*i),i=C[e+4>>2],r=v(r+v(i*i)),i=C[e+8>>2],i=v(r+v(i*i)),r=C[t+36>>2],i!=v(0)&&(r=v(E(i))),i=r,C[_+20>>2]=i,C[t+32>>2]=i,n[t+249|0]=1,_=t+284|0,i=C[e>>2],a=C[e+4>>2],o=C[e+8>>2],(r=v(v(v(i*i)+v(a*a))+v(o*o)))!=v(0)?(r=v(v(1)/v(E(r))),o=v(o*r),a=v(a*r),i=v(i*r),e=e+12|0):(o=C[t+264>>2],a=C[t+260>>2],i=C[t+256>>2],e=t+268|0),f[_>>2]=f[e>>2],C[t+280>>2]=o,C[t+276>>2]=a,C[t+272>>2]=i,e=f[t+8>>2],_=f[(h=e+52|0)+4>>2],f[t+116>>2]=f[h>>2],f[t+120>>2]=_,h=f[(e=e+60|0)+4>>2],f[(t=t+124|0)>>2]=f[e>>2],f[t+4>>2]=h},function(t){return 0|(v(y(C[(t|=0)+20>>2]))>2]))>2],e=f[e+188>>2],f[t+8>>2]&f[e+4>>2]?0!=(f[e+8>>2]&f[t+4>>2])|0:0},function(t,e){t|=0;var i=0;i=f[(e|=0)+4>>2],f[t+100>>2]=f[e>>2],f[t+104>>2]=i,i=f[(e=e+8|0)+4>>2],f[(t=t+108|0)>>2]=f[e>>2],f[t+4>>2]=i},function(t){return(t|=0)+100|0},function(t,e){t|=0,e|=0;var i,r=0,a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=0,p=v(0),B=v(0),F=v(0),V=v(0);r=f[e+4>>2],f[t+68>>2]=f[e>>2],f[t+72>>2]=r,i=f[(y=e+8|0)+4>>2],f[(r=t+76|0)>>2]=f[y>>2],f[r+4>>2]=i,_=C[t+68>>2],h=C[t+72>>2],d=C[r>>2];t:{if((p=v(v(v(_*_)+v(h*h))+v(d*d)))>v(0)){if(g=C[e>>2],a=C[e+4>>2],m=C[e+8>>2],o=v(v(1)/v(E(v(v(v(g*g)+v(a*a))+v(m*m))))),B=C[t+264>>2],V=v(B*v(m*o)),m=C[t+256>>2],F=C[t+260>>2],(o=v(V+v(v(m*v(g*o))+v(F*v(a*o)))))==v(0))break t;if(a=d,d=v(v(E(p))*dr(v(v(1.5707963705062866)-Ni(v(R(v(D(o,v(-1))),v(1))))))),g=v(B*d),C[t+76>>2]=a-g,a=h,h=v(F*d),C[t+72>>2]=a-h,a=_,_=v(m*d),C[t+68>>2]=a-_,C[t+20>>2]=(ov(0)))break t;return n[t+249|0]=1,e=f[t+8>>2],y=f[(r=e+52|0)+4>>2],f[t+116>>2]=f[r>>2],f[t+120>>2]=y,r=f[(e=e+60|0)+4>>2],f[(t=t+124|0)>>2]=f[e>>2],void(f[t+4>>2]=r)}f[t+20>>2]=0}},function(t,e){t|=0,e|=0;var i=v(0);f[t+12>>2]=0,i=C[e+20>>2],C[t>>2]=v(C[e+256>>2]*i)+C[e+68>>2],C[t+8>>2]=v(i*C[e+264>>2])+C[e+76>>2],C[t+4>>2]=v(i*C[e+260>>2])+C[e+72>>2]},ve,function(t,e){return e|=0,f[(t|=0)+12>>2]&f[e+4>>2]?0!=(f[e+8>>2]&f[t+8>>2])|0:0},function(t,e,i){t|=0,e|=0,i|=0;var r=0,n=v(0),a=v(0),o=v(0),h=v(0),d=v(0),g=v(0),m=0,y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0);return a=v(1),(0|(r=f[e>>2]))==f[t+84>>2]|4&_[r+204|0]||(i?(o=C[e+16>>2],h=C[e+12>>2],n=C[e+8>>2]):(n=C[e+8>>2],d=C[e+12>>2],g=C[e+16>>2],o=v(v(v(n*C[r+36>>2])+v(d*C[r+40>>2]))+v(g*C[r+44>>2])),h=v(v(v(n*C[r+20>>2])+v(d*C[r+24>>2]))+v(g*C[r+28>>2])),n=v(v(v(C[r+4>>2]*n)+v(C[r+8>>2]*d))+v(C[r+12>>2]*g))),v(v(v(n*C[t+88>>2])+v(h*C[t+92>>2]))+v(o*C[t+96>>2]))>2]||(f[t+80>>2]=r,f[t+4>>2]=f[e+40>>2],i?(i=f[e+12>>2],f[t+48>>2]=f[e+8>>2],f[t+52>>2]=i,m=f[(r=e+16|0)+4>>2],f[(i=t+56|0)>>2]=f[r>>2],f[i+4>>2]=m):(n=C[r+8>>2],d=C[r+12>>2],g=C[r+20>>2],y=C[r+24>>2],p=C[r+28>>2],R=C[r+36>>2],D=C[r+40>>2],a=C[e+12>>2],B=C[r+44>>2],o=C[e+16>>2],E=C[r+4>>2],h=C[e+8>>2],f[t+60>>2]=0,C[t+56>>2]=v(v(h*R)+v(a*D))+v(o*B),C[t+52>>2]=v(v(h*g)+v(a*y))+v(o*p),C[t+48>>2]=v(v(E*h)+v(n*a))+v(d*o)),i=f[e+28>>2],f[t+64>>2]=f[e+24>>2],f[t+68>>2]=i,r=f[(i=e+32|0)+4>>2],f[(t=t+72|0)>>2]=f[i>>2],f[t+4>>2]=r,a=C[e+40>>2])),v(a)},At,qe,function(t,e){e|=0;var i=0,r=0,n=0;Kf(t|=0,f[t+28>>2]+4|0,f[t+32>>2]+4|0),f[e>>2]=0,f[e+4>>2]=0;t:{e:{i:if(i=f[t+956>>2],!(i>>>0>4))switch(r=2,i-1|0){case 3:break e;case 0:case 1:case 2:break i;default:break t}r=1}f[e>>2]=r,i=r}_[t+792|0]&&(i=i+1|0,f[e>>2]=i),_[t+798|0]&&(i=i+1|0,f[e>>2]=i),n=e;t:{e:{i:if(r=f[t+960>>2],!(r>>>0>4)){A:switch(r-1|0){case 0:case 1:case 2:break i;case 3:break A;default:break t}i=i+2|0;break e}i=i+1|0}f[n>>2]=i}_[t+793|0]&&(i=i+1|0,f[e>>2]=i),_[t+799|0]&&(i=i+1|0,f[e>>2]=i),n=e;t:{e:{i:if(r=f[t+964>>2],!(r>>>0>4)){A:switch(r-1|0){case 0:case 1:case 2:break i;case 3:break A;default:break t}i=i+2|0;break e}i=i+1|0}f[n>>2]=i}_[t+794|0]&&(i=i+1|0,f[e>>2]=i),_[t+800|0]&&(f[e>>2]=i+1),Lf(t,0);t:{e:{i:if(r=f[t+1052>>2],!(r>>>0>4))switch(i=2,r-1|0){case 3:break e;case 0:case 1:case 2:break i;default:break t}i=1}f[e>>2]=f[e>>2]+i}_[t+996|0]&&(f[e>>2]=f[e>>2]+1),_[t+1016|0]&&(f[e>>2]=f[e>>2]+1),Lf(t,1);t:{e:{i:if(r=f[t+1140>>2],!(r>>>0>4))switch(i=2,r-1|0){case 3:break e;case 0:case 1:case 2:break i;default:break t}i=1}f[e>>2]=f[e>>2]+i}_[t+1084|0]&&(f[e>>2]=f[e>>2]+1),_[t+1104|0]&&(f[e>>2]=f[e>>2]+1),i=2,Lf(t,2);t:{e:{i:if(r=f[t+1228>>2],!(r>>>0>4))switch(r-1|0){case 3:break e;case 0:case 1:case 2:break i;default:break t}i=1}f[e>>2]=f[e>>2]+i}_[t+1172|0]&&(f[e>>2]=f[e>>2]+1),_[t+1192|0]&&(f[e>>2]=f[e>>2]+1)},function(t,e){var i,r,a,o,h,d;(function(t,e,i,r,a,o,h,d,g){var v,y,p=0,R=0,D=0,B=0,E=0,F=0,V=0,G=0;for(Z=v=Z-112|0,f[(R=v+100|0)>>2]=0,f[R+4>>2]=0,f[v+108>>2]=0,f[v+92>>2]=0,f[v+96>>2]=0,n[v+88|0]=0,f[v+84>>2]=0,n[v+80|0]=0,f[v+76>>2]=0,n[v+72|0]=0,f[v+68>>2]=0,n[v+64|0]=0,f[v+56>>2]=0,f[v+60>>2]=1036831949,n[v+52|0]=0,f[v+48>>2]=0,f[v+40>>2]=0,f[v+44>>2]=1063675494,f[v+32>>2]=0,f[v+36>>2]=1045220557,f[v+24>>2]=1065353216,f[v+28>>2]=-1082130432,y=e+4|0;;){if(R=_[(D=t+F|0)+792|0],(G=f[(p=t+V|0)+956>>2])||(B=R,R=1,B||(R=0,_[D+798|0]))){f[v+108>>2]=G,n[v+52|0]=R,f[v+32>>2]=f[p+712>>2],f[v+104>>2]=f[p+940>>2],f[v+96>>2]=f[p+908>>2],f[v+100>>2]=f[p+924>>2],n[v+64|0]=_[D+795|0],f[v+68>>2]=f[p+804>>2],n[v+72|0]=_[D+798|0],f[v+76>>2]=f[p+820>>2],n[v+80|0]=_[D+836|0],f[v+84>>2]=f[p+840>>2],n[v+88|0]=_[D+856|0],f[v+92>>2]=f[p+860>>2],f[v+28>>2]=f[p+696>>2],f[v+24>>2]=f[p+680>>2],f[v+60>>2]=f[p+892>>2],f[v+56>>2]=f[p+876>>2],f[v+20>>2]=0,f[v+8>>2]=f[p+1236>>2],f[v+12>>2]=f[p+1252>>2],f[v+16>>2]=f[p+1268>>2],B=v,D=p+744|0,1&(R=f[t+1456>>2]>>V)||(D=f[e+32>>2]),f[B+40>>2]=f[D>>2],f[v+36>>2]=f[(2&R?p+728|0:y)>>2],f[v+48>>2]=f[(4&R?p+776|0:f[e+32>>2])>>2],f[v+44>>2]=f[(8&R?p+760|0:y)>>2],B=1,p=((F+2&255)>>>0)%3|0,R=m(((F+1&255)>>>0)%3|0,88)+t|0;t:if((D=f[R+1052>>2]+-1|0)>>>0<=3){e:switch(D-2|0){case 0:B=(E=+C[R+1040>>2])<-.001|E>.001;break t;case 1:break e;default:break t}if(+C[R+1040>>2]<-.001)break t;B=+C[R+1044>>2]>.001}else B=0;R=1,p=m(p,88)+t|0;t:if(!((D=f[p+1052>>2]+-1|0)>>>0>3)){e:{i:switch(D-2|0){case 0:if((E=+C[p+1040>>2])<-.001|E>.001)break e;break t;case 1:break i;default:break e}if(!(+C[p+1040>>2]<-.001||+C[p+1044>>2]>.001))break t}R=0}i=qf(t,v+24|0,r,a,o,h,d,g,e,i,v+8|0,0,B?R:1)+i|0}if(F=F+1|0,12==(0|(V=V+4|0)))break}Z=v+112|0})(i=t|=0,r=e|=0,function(t,e,i,r,n,a,o,h){var d,C=0,g=0,v=0,y=0,p=0,R=0,D=0;return Z=d=Z-32|0,f[d+24>>2]=f[6114],g=f[6113],f[d+16>>2]=f[6112],f[d+20>>2]=g,g=1,(v=f[t+1232>>2])>>>0<=5&&(C=v<<2,f[d+24>>2]=f[C+24508>>2],g=f[C+24532>>2],f[d+20>>2]=g,C=f[C+24556>>2],f[d+16>>2]=C),v=m(C,88)+t|0,(_[1016+(m(C,88)+t|0)|0]||f[v+1052>>2]|_[v+996|0])&&(p=f[(y=(g=(C<<4)+t|0)+1388|0)+4>>2],f[(R=d+8|0)>>2]=f[y>>2],f[R+4>>2]=p,y=f[(g=g+1380|0)+4>>2],f[d>>2]=f[g>>2],f[d+4>>2]=y,1&(g=f[t+1456>>2]>>12+(C<<2))||(f[984+(m(C,88)+t|0)>>2]=f[f[e+32>>2]>>2]),2&g||(f[980+(m(C,88)+t|0)>>2]=f[e+4>>2]),4&g||(f[992+(m(C,88)+t|0)>>2]=f[f[e+32>>2]>>2]),8&g||(f[988+(m(C,88)+t|0)>>2]=f[e+4>>2]),y=qf(t,v+968|0,i,r,n,a,o,h,e,0,d,1,0),g=f[d+20>>2]),v=m(g,88)+t|0,(_[1016+(m(g,88)+t|0)|0]||f[v+1052>>2]|_[v+996|0])&&(R=f[(p=(C=(g<<4)+t|0)+1388|0)+4>>2],f[(D=d+8|0)>>2]=f[p>>2],f[D+4>>2]=R,p=f[(C=C+1380|0)+4>>2],f[d>>2]=f[C>>2],f[d+4>>2]=p,1&(C=f[t+1456>>2]>>12+(g<<2))||(f[984+(m(g,88)+t|0)>>2]=f[f[e+32>>2]>>2]),2&C||(f[980+(m(g,88)+t|0)>>2]=f[e+4>>2]),4&C||(f[992+(m(g,88)+t|0)>>2]=f[f[e+32>>2]>>2]),8&C||(f[988+(m(g,88)+t|0)>>2]=f[e+4>>2]),y=qf(t,v+968|0,i,r,n,a,o,h,e,y,d,1,0)+y|0),g=f[d+24>>2],v=m(g,88)+t|0,(_[1016+(m(g,88)+t|0)|0]||f[v+1052>>2]|_[v+996|0])&&(R=f[(p=(C=(g<<4)+t|0)+1388|0)+4>>2],f[(D=d+8|0)>>2]=f[p>>2],f[D+4>>2]=R,p=f[(C=C+1380|0)+4>>2],f[d>>2]=f[C>>2],f[d+4>>2]=p,1&(C=f[t+1456>>2]>>12+(g<<2))||(f[984+(m(g,88)+t|0)>>2]=f[f[e+32>>2]>>2]),2&C||(f[980+(m(g,88)+t|0)>>2]=f[e+4>>2]),4&C||(f[992+(m(g,88)+t|0)>>2]=f[f[e+32>>2]>>2]),8&C||(f[988+(m(g,88)+t|0)>>2]=f[e+4>>2]),y=qf(t,v+968|0,i,r,n,a,o,h,e,y,d,1,0)+y|0),Z=d+32|0,y}(i,r,a=(e=f[t+28>>2])+4|0,o=(t=f[t+32>>2])+4|0,h=e+372|0,d=t+372|0,e=e+388|0,t=t+388|0),a,o,h,d,e,t)},function(t,e,i,r){t|=0,e|=0,i=v(i);var n=0;t:{if((r|=0)>>>0<=2){if((e=e+-1|0)>>>0>3)break t;switch(e-1|0){case 0:return C[728+((e=r<<2)+t|0)>>2]=i,void(f[t+1456>>2]=f[t+1456>>2]|2<>2]=i,void(f[t+1456>>2]=f[t+1456>>2]|1<>2]=i,void(f[t+1456>>2]=f[t+1456>>2]|8<>2]=i,void(f[t+1456>>2]=f[t+1456>>2]|4<>>0>2||(e=e+-1|0,e>>>0>3))){switch(e-1|0){case 0:return C[980+(m(n,88)+t|0)>>2]=i,void(f[t+1456>>2]=f[t+1456>>2]|2<<(r<<2));case 2:return C[984+(m(n,88)+t|0)>>2]=i,void(f[t+1456>>2]=f[t+1456>>2]|1<<(r<<2));default:return C[988+(m(n,88)+t|0)>>2]=i,void(f[t+1456>>2]=f[t+1456>>2]|8<<(r<<2));case 1:}C[992+(m(n,88)+t|0)>>2]=i,f[t+1456>>2]=f[t+1456>>2]|4<<(r<<2)}}},function(t,e,i){t|=0,e|=0,i|=0;var r=v(0);if(i>>>0<=2){if((e=e+-1|0)>>>0>3)return v(v(0));switch(e-1|0){case 0:return v(C[728+((i<<2)+t|0)>>2]);case 2:return v(C[744+((i<<2)+t|0)>>2]);default:return v(C[760+((i<<2)+t|0)>>2]);case 1:}return v(C[776+((i<<2)+t|0)>>2])}if(!((i=i+-3|0)>>>0>2||(e=e+-1|0,e>>>0>3))){switch(e-1|0){case 0:return v(C[980+(m(i,88)+t|0)>>2]);case 2:return v(C[984+(m(i,88)+t|0)>>2]);default:return v(C[988+(m(i,88)+t|0)>>2]);case 1:}r=C[992+(m(i,88)+t|0)>>2]}return v(r)},function(t){return 644},function(t,e,i){return Df(t|=0,e|=0,i|=0),f[e+52>>2]=f[t+48>>2],f[e+56>>2]=f[t+52>>2],f[e+60>>2]=f[t+56>>2],f[e+64>>2]=f[t+60>>2],f[e+68>>2]=f[t- -64>>2],f[e+72>>2]=f[t+68>>2],f[e+76>>2]=f[t+72>>2],f[e+80>>2]=f[t+76>>2],f[e+84>>2]=f[t+80>>2],f[e+88>>2]=f[t+84>>2],f[e+92>>2]=f[t+88>>2],f[e+96>>2]=f[t+92>>2],f[e+100>>2]=f[t+96>>2],f[e+104>>2]=f[t+100>>2],f[e+108>>2]=f[t+104>>2],f[e+112>>2]=f[t+108>>2],f[e+116>>2]=f[t+112>>2],f[e+120>>2]=f[t+116>>2],f[e+124>>2]=f[t+120>>2],f[e+128>>2]=f[t+124>>2],f[e+132>>2]=f[t+128>>2],f[e+136>>2]=f[t+132>>2],f[e+140>>2]=f[t+136>>2],f[e+144>>2]=f[t+140>>2],f[e+148>>2]=f[t+144>>2],f[e+152>>2]=f[t+148>>2],f[e+156>>2]=f[t+152>>2],f[e+160>>2]=f[t+156>>2],f[e+164>>2]=f[t+160>>2],f[e+168>>2]=f[t+164>>2],f[e+172>>2]=f[t+168>>2],f[e+176>>2]=f[t+172>>2],f[e+428>>2]=f[t+968>>2],f[e+412>>2]=f[t+972>>2],f[e+444>>2]=f[t+976>>2],f[e+460>>2]=f[t+980>>2],f[e+476>>2]=f[t+984>>2],f[e+492>>2]=f[t+988>>2],f[e+508>>2]=f[t+992>>2],f[e+524>>2]=f[t+1e3>>2],f[e+540>>2]=f[t+1004>>2],f[e+556>>2]=f[t+1012>>2],f[e+572>>2]=f[t+1020>>2],f[e+588>>2]=f[t+1028>>2],f[e+604>>2]=f[t+1036>>2],f[e+432>>2]=f[t+1056>>2],f[e+416>>2]=f[t+1060>>2],f[e+448>>2]=f[t+1064>>2],f[e+464>>2]=f[t+1068>>2],f[e+480>>2]=f[t+1072>>2],f[e+496>>2]=f[t+1076>>2],f[e+512>>2]=f[t+1080>>2],f[e+528>>2]=f[t+1088>>2],f[e+544>>2]=f[t+1092>>2],f[e+560>>2]=f[t+1100>>2],f[e+576>>2]=f[t+1108>>2],f[e+592>>2]=f[t+1116>>2],f[e+608>>2]=f[t+1124>>2],f[e+436>>2]=f[t+1144>>2],f[e+420>>2]=f[t+1148>>2],f[e+452>>2]=f[t+1152>>2],f[e+468>>2]=f[t+1156>>2],f[e+484>>2]=f[t+1160>>2],f[e+500>>2]=f[t+1164>>2],f[e+516>>2]=f[t+1168>>2],f[e+532>>2]=f[t+1176>>2],f[e+548>>2]=f[t+1180>>2],f[e+564>>2]=f[t+1188>>2],f[e+580>>2]=f[t+1196>>2],f[e+596>>2]=f[t+1204>>2],i=f[t+1212>>2],f[e+440>>2]=0,f[e+612>>2]=i,f[e+616>>2]=0,f[e+600>>2]=0,f[e+584>>2]=0,f[e+568>>2]=0,f[e+552>>2]=0,f[e+536>>2]=0,f[e+520>>2]=0,f[e+504>>2]=0,f[e+488>>2]=0,f[e+472>>2]=0,f[e+456>>2]=0,f[e+424>>2]=0,n[e+620|0]=_[t+996|0],n[e+624|0]=_[t+1008|0],n[e+628|0]=_[t+1016|0],n[e+632|0]=_[t+1024|0],n[e+636|0]=_[t+1032|0],n[e+621|0]=_[t+1084|0],n[e+625|0]=_[t+1096|0],n[e+629|0]=_[t+1104|0],n[e+633|0]=_[t+1112|0],n[e+637|0]=_[t+1120|0],n[e+622|0]=_[t+1172|0],n[e+626|0]=_[t+1184|0],n[e+630|0]=_[t+1192|0],n[e+634|0]=_[t+1200|0],i=_[t+1208|0],n[e+639|0]=0,n[e+635|0]=0,n[e+631|0]=0,n[e+627|0]=0,n[e+623|0]=0,n[e+638|0]=i,f[e+196>>2]=f[t+680>>2],f[e+200>>2]=f[t+684>>2],f[e+204>>2]=f[t+688>>2],f[e+208>>2]=f[t+692>>2],f[e+180>>2]=f[t+696>>2],f[e+184>>2]=f[t+700>>2],f[e+188>>2]=f[t+704>>2],f[e+192>>2]=f[t+708>>2],f[e+212>>2]=f[t+712>>2],f[e+216>>2]=f[t+716>>2],f[e+220>>2]=f[t+720>>2],f[e+224>>2]=f[t+724>>2],f[e+228>>2]=f[t+728>>2],f[e+232>>2]=f[t+732>>2],f[e+236>>2]=f[t+736>>2],f[e+240>>2]=f[t+740>>2],f[e+244>>2]=f[t+744>>2],f[e+248>>2]=f[t+748>>2],f[e+252>>2]=f[t+752>>2],f[e+256>>2]=f[t+756>>2],f[e+260>>2]=f[t+760>>2],f[e+264>>2]=f[t+764>>2],f[e+268>>2]=f[t+768>>2],f[e+272>>2]=f[t+772>>2],f[e+276>>2]=f[t+776>>2],f[e+280>>2]=f[t+780>>2],f[e+284>>2]=f[t+784>>2],f[e+288>>2]=f[t+788>>2],f[e+292>>2]=f[t+876>>2],f[e+296>>2]=f[t+880>>2],f[e+300>>2]=f[t+884>>2],f[e+304>>2]=f[t+888>>2],f[e+308>>2]=f[t+892>>2],f[e+312>>2]=f[t+896>>2],f[e+316>>2]=f[t+900>>2],f[e+320>>2]=f[t+904>>2],f[e+324>>2]=f[t+804>>2],f[e+328>>2]=f[t+808>>2],f[e+332>>2]=f[t+812>>2],f[e+336>>2]=f[t+816>>2],f[e+340>>2]=f[t+820>>2],f[e+344>>2]=f[t+824>>2],f[e+348>>2]=f[t+828>>2],f[e+352>>2]=f[t+832>>2],f[e+356>>2]=f[t+840>>2],f[e+360>>2]=f[t+844>>2],f[e+364>>2]=f[t+848>>2],f[e+368>>2]=f[t+852>>2],f[e+372>>2]=f[t+860>>2],f[e+376>>2]=f[t+864>>2],f[e+380>>2]=f[t+868>>2],f[e+384>>2]=f[t+872>>2],n[e+388|0]=_[t+792|0],n[e+392|0]=_[t+795|0],n[e+396|0]=_[t+798|0],n[e+400|0]=_[t+836|0],n[e+404|0]=_[t+856|0],n[e+389|0]=_[t+793|0],n[e+393|0]=_[t+796|0],n[e+397|0]=_[t+799|0],n[e+401|0]=_[t+837|0],n[e+405|0]=_[t+857|0],n[e+390|0]=_[t+794|0],n[e+394|0]=_[t+797|0],n[e+398|0]=_[t+800|0],n[e+402|0]=_[t+838|0],i=_[t+858|0],n[e+407|0]=0,n[e+403|0]=0,n[e+399|0]=0,n[e+395|0]=0,n[e+391|0]=0,n[e+406|0]=i,t=f[t+1232>>2],f[e+408>>2]=0,f[e+640>>2]=t,24664},Ef,At,sA,ve,function(t,e){e|=0,Q(f[(t|=0)+4>>2],0|e)},function(t,e){e|=0,W(f[(t|=0)+4>>2],0|e)},ve,function(t,e){return e|=0,f[(t|=0)+16>>2]&f[e+4>>2]?0!=(f[e+8>>2]&f[t+12>>2])|0:0},function(t,e,i){t|=0,e|=0,i|=0;var r=0,n=v(0),a=v(0),o=v(0),_=0,h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0);return f[t+4>>2]=f[e+24>>2],r=f[e>>2],f[t+8>>2]=r,i?(i=f[e+12>>2],f[t+56>>2]=f[e+8>>2],f[t+60>>2]=i,_=f[(r=e+16|0)+4>>2],f[(i=t- -64|0)>>2]=f[r>>2],f[i+4>>2]=_):(h=C[r+8>>2],d=C[r+12>>2],g=C[r+20>>2],m=C[r+24>>2],y=C[r+28>>2],p=C[r+36>>2],R=C[r+40>>2],n=C[e+12>>2],D=C[r+44>>2],a=C[e+16>>2],B=C[r+4>>2],o=C[e+8>>2],f[t+68>>2]=0,C[t- -64>>2]=v(v(o*p)+v(n*R))+v(a*D),C[t+60>>2]=v(v(o*g)+v(n*m))+v(a*y),C[t+56>>2]=v(v(B*o)+v(h*n))+v(d*a)),n=C[e+24>>2],a=v(v(1)-n),C[t+72>>2]=v(a*C[t+24>>2])+v(n*C[t+40>>2]),C[t+76>>2]=v(a*C[t+28>>2])+v(n*C[t+44>>2]),C[t+80>>2]=v(a*C[t+32>>2])+v(n*C[t+48>>2]),v(C[e+24>>2])},Ct,function(t){$(Ct(t|=0))},function(t,e,i){t|=0,e|=0,i|=0;var r=0,a=0,o=0,h=0,d=0,g=v(0),m=0,y=0,p=v(0),R=v(0),D=v(0),B=v(0);if(f[t+8>>2]=f[e>>2],(0|(r=f[t+28>>2]))==f[t+32>>2]&&!((0|r)>=(0|(o=r?r<<1:1)))){if(o&&(h=dA(o<<2),r=f[t+28>>2]),(0|r)>=1)for(a=r;f[d+h>>2]=f[f[t+36>>2]+d>>2],d=d+4|0,a=a+-1|0;);(a=f[t+36>>2])&&(_[t+40|0]&&(CA(a),r=f[t+28>>2]),f[t+36>>2]=0),f[t+36>>2]=h,f[t+32>>2]=o,n[t+40|0]=1}if(f[t+28>>2]=r+1,f[f[t+36>>2]+(r<<2)>>2]=f[e>>2],i?(B=C[e+16>>2],R=C[e+12>>2],g=C[e+8>>2],p=C[e+20>>2]):(D=C[e+8>>2],i=f[t+8>>2],p=C[e+12>>2],g=C[e+16>>2],B=v(v(v(D*C[i+36>>2])+v(p*C[i+40>>2]))+v(g*C[i+44>>2])),R=v(v(v(D*C[i+20>>2])+v(p*C[i+24>>2]))+v(g*C[i+28>>2])),g=v(v(v(C[i+4>>2]*D)+v(C[i+8>>2]*p))+v(C[i+12>>2]*g)),p=v(0)),(0|(a=f[t+80>>2]))==f[t+84>>2]&&!((0|a)>=(0|(y=a?a<<1:1)))){if(y?(i=dA(y<<4),a=f[t+80>>2]):i=0,(0|a)>=1)for(d=0;m=f[t+88>>2]+d|0,r=f[m+4>>2],f[(o=h=i+d|0)>>2]=f[m>>2],f[o+4>>2]=r,r=f[(o=m+8|0)+4>>2],f[(h=h+8|0)>>2]=f[o>>2],f[h+4>>2]=r,d=d+16|0,a=a+-1|0;);(r=f[t+88>>2])&&(_[t+92|0]&&CA(r),f[t+88>>2]=0),f[t+88>>2]=i,f[t+84>>2]=y,n[t+92|0]=1,a=f[t+80>>2]}if(i=f[t+88>>2]+(a<<4)|0,C[i+12>>2]=p,C[i+8>>2]=B,C[i+4>>2]=R,C[i>>2]=g,f[t+80>>2]=f[t+80>>2]+1,R=C[e+24>>2],g=v(v(1)-R),D=v(v(g*C[t+52>>2])+v(R*C[t+68>>2])),p=v(v(g*C[t+48>>2])+v(R*C[t- -64>>2])),g=v(v(g*C[t+44>>2])+v(R*C[t+60>>2])),(0|(a=f[t+100>>2]))==f[t+104>>2]&&!((0|a)>=(0|(y=a?a<<1:1)))){if(y?(i=dA(y<<4),a=f[t+100>>2]):i=0,(0|a)>=1)for(d=0;m=f[t+108>>2]+d|0,r=f[m+4>>2],f[(o=h=i+d|0)>>2]=f[m>>2],f[o+4>>2]=r,r=f[(o=m+8|0)+4>>2],f[(h=h+8|0)>>2]=f[o>>2],f[h+4>>2]=r,d=d+16|0,a=a+-1|0;);(r=f[t+108>>2])&&(_[t+112|0]&&CA(r),f[t+108>>2]=0),f[t+108>>2]=i,f[t+104>>2]=y,n[t+112|0]=1,a=f[t+100>>2]}if(i=f[t+108>>2]+(a<<4)|0,C[i+8>>2]=D,C[i+4>>2]=p,C[i>>2]=g,f[t+100>>2]=f[t+100>>2]+1,(0|(r=f[t+120>>2]))==f[t+124>>2]&&!((0|r)>=(0|(m=r?r<<1:1)))){m?(o=dA(m<<2),r=f[t+120>>2]):o=0,i=f[t+128>>2];t:{if((0|r)>=1)for(d=o,a=i,h=r;f[d>>2]=f[a>>2],d=d+4|0,a=a+4|0,h=h+-1|0;);else if(!i)break t;_[t+132|0]&&(CA(i),r=f[t+120>>2]),f[t+128>>2]=0}f[t+128>>2]=o,f[t+124>>2]=m,n[t+132|0]=1}return f[f[t+128>>2]+(r<<2)>>2]=f[e+24>>2],f[t+120>>2]=r+1,v(C[t+4>>2])},ve,function(t,e,i){t|=0,e|=0,i|=0;var r=0,n=v(0),a=v(0),o=v(0),_=0,h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0);return f[t+4>>2]=f[e+40>>2],r=f[e>>2],f[t+80>>2]=r,i?(i=f[e+12>>2],f[t+48>>2]=f[e+8>>2],f[t+52>>2]=i,_=f[(r=e+16|0)+4>>2],f[(i=t+56|0)>>2]=f[r>>2],f[i+4>>2]=_):(h=C[r+8>>2],d=C[r+12>>2],g=C[r+20>>2],m=C[r+24>>2],y=C[r+28>>2],p=C[r+36>>2],R=C[r+40>>2],n=C[e+12>>2],D=C[r+44>>2],a=C[e+16>>2],B=C[r+4>>2],o=C[e+8>>2],f[t+60>>2]=0,C[t+56>>2]=v(v(o*p)+v(n*R))+v(a*D),C[t+52>>2]=v(v(o*g)+v(n*m))+v(a*y),C[t+48>>2]=v(v(B*o)+v(h*n))+v(d*a)),i=f[e+28>>2],f[t+64>>2]=f[e+24>>2],f[t+68>>2]=i,r=f[(i=e+32|0)+4>>2],f[(t=t+72|0)>>2]=f[i>>2],f[t+4>>2]=r,v(C[e+40>>2])},gt,function(t){$(gt(t|=0))},function(t,e,i){t|=0,e|=0,i|=0;var r,a=0,o=0,h=0,d=0,g=0,m=0,y=0,p=v(0),R=v(0),D=v(0),B=v(0),E=v(0);if((0|(a=f[t+20>>2]))==f[t+24>>2]&&!((0|a)>=(0|(h=a?a<<1:1)))){if(h&&(d=dA(h<<2),a=f[t+20>>2]),(0|a)>=1)for(o=a;f[g+d>>2]=f[f[t+28>>2]+g>>2],g=g+4|0,o=o+-1|0;);(o=f[t+28>>2])&&(_[t+32|0]&&(CA(o),a=f[t+20>>2]),f[t+28>>2]=0),f[t+28>>2]=d,f[t+24>>2]=h,n[t+32|0]=1}if(f[t+20>>2]=a+1,f[f[t+28>>2]+(a<<2)>>2]=f[e>>2],i?(B=C[e+16>>2],E=C[e+12>>2],p=C[e+8>>2],R=C[e+20>>2]):(D=C[e+8>>2],i=f[e>>2],R=C[e+12>>2],p=C[e+16>>2],B=v(v(v(D*C[i+36>>2])+v(R*C[i+40>>2]))+v(p*C[i+44>>2])),E=v(v(v(D*C[i+20>>2])+v(R*C[i+24>>2]))+v(p*C[i+28>>2])),p=v(v(v(C[i+4>>2]*D)+v(C[i+8>>2]*R))+v(C[i+12>>2]*p)),R=v(0)),(0|(o=f[t+72>>2]))==f[t+76>>2]&&!((0|o)>=(0|(y=o?o<<1:1)))){if(y?(i=dA(y<<4),o=f[t+72>>2]):i=0,(0|o)>=1)for(g=0;m=f[t+80>>2]+g|0,a=f[m+4>>2],f[(h=d=i+g|0)>>2]=f[m>>2],f[h+4>>2]=a,a=f[(h=m+8|0)+4>>2],f[(d=d+8|0)>>2]=f[h>>2],f[d+4>>2]=a,g=g+16|0,o=o+-1|0;);(a=f[t+80>>2])&&(_[t+84|0]&&CA(a),f[t+80>>2]=0),f[t+80>>2]=i,f[t+76>>2]=y,n[t+84|0]=1,o=f[t+72>>2]}if(i=f[t+80>>2]+(o<<4)|0,C[i+12>>2]=R,C[i+8>>2]=B,C[i+4>>2]=E,C[i>>2]=p,f[t+72>>2]=f[t+72>>2]+1,r=e+24|0,(0|(o=f[t+92>>2]))==f[t+96>>2]&&!((0|o)>=(0|(y=o?o<<1:1)))){if(y?(i=dA(y<<4),o=f[t+92>>2]):i=0,(0|o)>=1)for(g=0;m=f[t+100>>2]+g|0,a=f[m+4>>2],f[(h=d=i+g|0)>>2]=f[m>>2],f[h+4>>2]=a,a=f[(h=m+8|0)+4>>2],f[(d=d+8|0)>>2]=f[h>>2],f[d+4>>2]=a,g=g+16|0,o=o+-1|0;);(a=f[t+100>>2])&&(_[t+104|0]&&CA(a),f[t+100>>2]=0),f[t+100>>2]=i,f[t+96>>2]=y,n[t+104|0]=1,o=f[t+92>>2]}if(i=f[r+4>>2],a=f[t+100>>2]+(o<<4)|0,f[a>>2]=f[r>>2],f[a+4>>2]=i,o=a+8|0,i=f[(a=r+8|0)+4>>2],f[o>>2]=f[a>>2],f[o+4>>2]=i,f[t+92>>2]=f[t+92>>2]+1,(0|(a=f[t+112>>2]))==f[t+116>>2]&&!((0|a)>=(0|(m=a?a<<1:1)))){m?(h=dA(m<<2),a=f[t+112>>2]):h=0,i=f[t+120>>2];t:{if((0|a)>=1)for(g=h,o=i,d=a;f[g>>2]=f[o>>2],g=g+4|0,o=o+4|0,d=d+-1|0;);else if(!i)break t;_[t+124|0]&&(CA(i),a=f[t+112>>2]),f[t+120>>2]=0}f[t+120>>2]=h,f[t+116>>2]=m,n[t+124|0]=1}return f[f[t+120>>2]+(a<<2)>>2]=f[e+40>>2],f[t+112>>2]=a+1,v(C[t+4>>2])},sA,ve,function(t,e,i){var r;return t|=0,e|=0,t=f[(i|=0)>>2],t=4==f[t+252>>2]?t:0,!(r=f[e>>2])|4!=f[r+252>>2]||yt[f[f[r>>2]+28>>2]](r,i,e),t&&yt[f[f[t>>2]+28>>2]](t,e,i),0},function(t,e,i,r){var n;return t|=0,e|=0,r|=0,t=f[(i|=0)>>2],t=4==f[t+252>>2]?t:0,!(n=f[e>>2])|4!=f[n+252>>2]||yt[f[f[n>>2]+32>>2]](n,i,r,e),t&&yt[f[f[t>>2]+32>>2]](t,e,r,i),0},De];function ht(){return i.byteLength/65536|0}return{btGImpactCollisionAlgorithm_RegisterAlgorithm:function(t){(function(t){_[1716]||(f[427]=8844,n[1716]=1,n[1712]=0),de(t,25,0),de(t,25,1),de(t,25,2),de(t,25,3),de(t,25,4),de(t,25,5),de(t,25,6),de(t,25,7),de(t,25,8),de(t,25,9),de(t,25,10),de(t,25,11),de(t,25,12),de(t,25,13),de(t,25,14),de(t,25,15),de(t,25,16),de(t,25,17),de(t,25,18),de(t,25,19),de(t,25,20),de(t,25,21),de(t,25,22),de(t,25,23),de(t,25,24),de(t,25,25),de(t,25,26),de(t,25,27),de(t,25,28),de(t,25,29),de(t,25,30),de(t,25,31),de(t,25,32),de(t,25,33),de(t,25,34),de(t,25,35),de(t,0,25),de(t,1,25),de(t,2,25),de(t,3,25),de(t,4,25),de(t,5,25),de(t,6,25),de(t,7,25),de(t,8,25),de(t,9,25),de(t,10,25),de(t,11,25),de(t,12,25),de(t,13,25),de(t,14,25),de(t,15,25),de(t,16,25),de(t,17,25),de(t,18,25),de(t,19,25),de(t,20,25),de(t,21,25),de(t,22,25),de(t,23,25),de(t,24,25),de(t,25,25),de(t,26,25),de(t,27,25),de(t,28,25),de(t,29,25),de(t,30,25),de(t,31,25),de(t,32,25),de(t,33,25),de(t,34,25),de(t,35,25)})(t|=0)},btVector3_create:function(t,e,i){var r;return t=v(t),e=v(e),i=v(i),r=dA(16),f[r+12>>2]=0,C[r+8>>2]=i,C[r+4>>2]=e,C[r>>2]=t,0|r},btVector3_setValue:function(t,e,i,r){t|=0,e=v(e),i=v(i),r=v(r),f[t+12>>2]=0,C[t+8>>2]=r,C[t+4>>2]=i,C[t>>2]=e},btVector3_x:et,btVector3_y:rt,btVector3_z:it,btQuaternion_create:function(t,e,i,r){var n;return t=v(t),e=v(e),i=v(i),r=v(r),n=q(16),C[n+12>>2]=r,C[n+8>>2]=i,C[n+4>>2]=e,C[n>>2]=t,0|n},btQuaternion_setValue:function(t,e,i,r,n){t|=0,e=v(e),i=v(i),r=v(r),n=v(n),C[t+12>>2]=n,C[t+8>>2]=r,C[t+4>>2]=i,C[t>>2]=e},btQuaternion_x:et,btQuaternion_y:rt,btQuaternion_z:it,btQuaternion_w:function(t){return v(C[(t|=0)+12>>2])},btTransform_create:function(){return 0|q(64)},btTransform_setOrigin:function(t,e){t|=0;var i=0;i=f[(e|=0)+4>>2],f[t+48>>2]=f[e>>2],f[t+52>>2]=i,i=f[(e=e+8|0)+4>>2],f[(t=t+56|0)>>2]=f[e>>2],f[t+4>>2]=i},btTransform_setRotation:function(t,e){t|=0,e|=0;var i=v(0),r=v(0),n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0);r=C[e+12>>2],_=C[e+8>>2],i=C[e>>2],a=C[e+4>>2],f[t+44>>2]=0,f[t+28>>2]=0,f[t+12>>2]=0,n=v(v(2)/v(v(v(v(i*i)+v(a*a))+v(_*_))+v(r*r))),h=v(_*n),o=v(a*h),g=v(i*n),m=v(r*g),C[t+36>>2]=o+m,y=v(i*h),n=v(a*n),d=v(r*n),C[t+32>>2]=y-d,C[t+24>>2]=o-m,o=v(i*n),r=v(r*h),C[t+16>>2]=o+r,C[t+8>>2]=y+d,C[t+4>>2]=o-r,i=v(i*g),r=v(a*n),C[t+40>>2]=v(1)-v(i+r),d=i,i=v(_*h),C[t+20>>2]=v(1)-v(d+i),C[t>>2]=v(1)-v(r+i)},btTransform_getOrigin:ft,btTransform_getRotation:function(t){var e,i;return Z=e=Z-16|0,tt(t|=0,e),i=f[(t=e+8|0)+4>>2],f[709]=f[t>>2],f[710]=i,t=f[e+4>>2],f[707]=f[e>>2],f[708]=t,Z=e+16|0,2828},btTransform_setIdentity:function(t){var e=0;f[(t|=0)+4>>2]=0,f[t+8>>2]=0,f[t>>2]=1065353216,f[t+32>>2]=0,f[t+36>>2]=0,f[(e=t+12|0)>>2]=0,f[e+4>>2]=0,f[(e=t+24|0)>>2]=0,f[e+4>>2]=0,f[t+20>>2]=1065353216,f[(e=t+44|0)>>2]=0,f[e+4>>2]=0,f[t+40>>2]=1065353216,f[(e=t+52|0)>>2]=0,f[e+4>>2]=0,f[t+60>>2]=0},btTransform_equal:Rr,btMotionState_destroy:nt,layaMotionState_create:function(){var t;return t=q(8),f[t>>2]=0,f[t+4>>2]=0,f[t>>2]=24708,0|t},layaMotionState_set_rigidBodyID:function(t,e){e|=0,f[(t|=0)+4>>2]=e},btCollisionObject_create:function(){var t;return Ee(t=dA(324)),0|t},btCollisionObject_setContactProcessingThreshold:function(t,e){t|=0,e=v(e),C[t+184>>2]=e},btCollisionObject_setActivationState:function(t,e){Ye(t|=0,e|=0)},btCollisionObject_forceActivationState:function(t,e){e|=0,f[(t|=0)+220>>2]=e},btCollisionObject_activate:function(t,e){Ve(t|=0,e|=0)},btCollisionObject_isActive:function(t){return 2!=(0|(t=f[(t|=0)+220>>2]))&5!=(0|t)},btCollisionObject_setRestitution:function(t,e){t|=0,e=v(e),C[t+232>>2]=e,f[t+304>>2]=f[t+304>>2]+1},btCollisionObject_setFriction:function(t,e){t|=0,e=v(e),C[t+228>>2]=e,f[t+304>>2]=f[t+304>>2]+1},btCollisionObject_setRollingFriction:function(t,e){t|=0,e=v(e),C[t+236>>2]=e,f[t+304>>2]=f[t+304>>2]+1},btCollisionObject_getCollisionFlags:function(t){return f[(t|=0)+204>>2]},btCollisionObject_setCollisionFlags:function(t,e){e|=0,f[(t|=0)+204>>2]=e},btCollisionObject_getWorldTransform:hi,btCollisionObject_setWorldTransform:function(t,e){e|=0;var i=0,r=0,n=0;f[(t|=0)+304>>2]=f[t+304>>2]+1,n=f[(r=e+8|0)+4>>2],f[(i=t+12|0)>>2]=f[r>>2],f[i+4>>2]=n,i=f[e+4>>2],f[t+4>>2]=f[e>>2],f[t+8>>2]=i,n=f[(r=e+24|0)+4>>2],f[(i=t+28|0)>>2]=f[r>>2],f[i+4>>2]=n,r=f[e+20>>2],f[(i=t+20|0)>>2]=f[e+16>>2],f[i+4>>2]=r,r=f[e+36>>2],f[(i=t+36|0)>>2]=f[e+32>>2],f[i+4>>2]=r,n=f[(r=e+40|0)+4>>2],f[(i=t+44|0)>>2]=f[r>>2],f[i+4>>2]=n,n=f[(r=e+56|0)+4>>2],f[(i=t+60|0)>>2]=f[r>>2],f[i+4>>2]=n,i=f[e+52>>2],f[(t=t+52|0)>>2]=f[e+48>>2],f[t+4>>2]=i},btCollisionObject_setInterpolationWorldTransform:function(t,e){e|=0;var i=0,r=0,n=0;f[(t|=0)+304>>2]=f[t+304>>2]+1,n=f[(r=e+8|0)+4>>2],f[(i=t+76|0)>>2]=f[r>>2],f[i+4>>2]=n,i=f[e+4>>2],f[t+68>>2]=f[e>>2],f[t+72>>2]=i,n=f[(r=e+24|0)+4>>2],f[(i=t+92|0)>>2]=f[r>>2],f[i+4>>2]=n,r=f[e+20>>2],f[(i=t+84|0)>>2]=f[e+16>>2],f[i+4>>2]=r,r=f[e+36>>2],f[(i=t+100|0)>>2]=f[e+32>>2],f[i+4>>2]=r,n=f[(r=e+40|0)+4>>2],f[(i=t+108|0)>>2]=f[r>>2],f[i+4>>2]=n,n=f[(r=e+56|0)+4>>2],f[(i=t+124|0)>>2]=f[r>>2],f[i+4>>2]=n,i=f[e+52>>2],f[(t=t+116|0)>>2]=f[e+48>>2],f[t+4>>2]=i},btCollisionObject_setCollisionShape:function(t,e){e|=0,yt[f[f[(t|=0)>>2]+8>>2]](t,e)},btCollisionObject_getCcdMotionThreshold:function(t){return v(C[(t|=0)+276>>2])},btCollisionObject_setCcdMotionThreshold:function(t,e){t|=0,e=v(e),C[t+276>>2]=e},btCollisionObject_getCcdSweptSphereRadius:function(t){return v(C[(t|=0)+272>>2])},btCollisionObject_setCcdSweptSphereRadius:function(t,e){t|=0,e=v(e),C[t+272>>2]=e},btCollisionObject_getUserIndex:function(t){return f[(t|=0)+264>>2]},btCollisionObject_setUserIndex:function(t,e){e|=0,f[(t|=0)+264>>2]=e},btCollisionObject_getActivationState:function(t){return f[(t|=0)+220>>2]},btCollisionObject_setInterpolationAngularVelocity:function(t,e){e|=0;var i=0;f[(t|=0)+304>>2]=f[t+304>>2]+1,i=f[e+4>>2],f[t+148>>2]=f[e>>2],f[t+152>>2]=i,i=f[(e=e+8|0)+4>>2],f[(t=t+156|0)>>2]=f[e>>2],f[t+4>>2]=i},btCollisionObject_setInterpolationLinearVelocity:function(t,e){e|=0;var i=0;f[(t|=0)+304>>2]=f[t+304>>2]+1,i=f[e+4>>2],f[t+132>>2]=f[e>>2],f[t+136>>2]=i,i=f[(e=e+8|0)+4>>2],f[(t=t+140|0)>>2]=f[e>>2],f[t+4>>2]=i},btCollisionObject_destroy:nt,RayResultCallback_set_m_flags:function(t,e){e|=0,f[(t|=0)+20>>2]=e},RayResultCallback_hasHit:function(t){return 0!=f[(t|=0)+8>>2]|0},RayResultCallback_set_m_collisionFilterGroup:at,RayResultCallback_set_m_collisionFilterMask:function(t,e){e|=0,f[(t|=0)+16>>2]=e},RayResultCallback_get_m_closestHitFraction:rt,RayResultCallback_set_m_closestHitFraction:ot,RayResultCallback_get_m_collisionObject:mi,RayResultCallback_set_m_collisionObject:ct,ClosestRayResultCallback_create:function(t,e){t|=0,e|=0;var i,r,n=0;return i=q(88),f[i+20>>2]=0,f[i+12>>2]=1,f[i+16>>2]=-1,f[i+4>>2]=1065353216,f[i+8>>2]=0,f[i>>2]=24788,n=f[t+4>>2],f[i+24>>2]=f[t>>2],f[i+28>>2]=n,r=f[(t=t+8|0)+4>>2],f[(n=i+32|0)>>2]=f[t>>2],f[n+4>>2]=r,t=f[e+4>>2],f[i+40>>2]=f[e>>2],f[i+44>>2]=t,n=f[(e=e+8|0)+4>>2],f[(t=i+48|0)>>2]=f[e>>2],f[t+4>>2]=n,0|i},ClosestRayResultCallback_get_m_rayFromWorld:bt,ClosestRayResultCallback_set_m_rayFromWorld:function(t,e){t|=0;var i=0;i=f[(e|=0)+4>>2],f[t+24>>2]=f[e>>2],f[t+28>>2]=i,i=f[(e=e+8|0)+4>>2],f[(t=t+32|0)>>2]=f[e>>2],f[t+4>>2]=i},ClosestRayResultCallback_get_m_rayToWorld:function(t){return(t|=0)+40|0},ClosestRayResultCallback_set_m_rayToWorld:function(t,e){t|=0;var i=0;i=f[(e|=0)+4>>2],f[t+40>>2]=f[e>>2],f[t+44>>2]=i,i=f[(e=e+8|0)+4>>2],f[(t=t+48|0)>>2]=f[e>>2],f[t+4>>2]=i},ClosestRayResultCallback_get_m_hitNormalWorld:Le,ClosestRayResultCallback_get_m_hitPointWorld:ze,tBtCollisionObjectArray_size:function(t){return f[(t|=0)+4>>2]},tBtCollisionObjectArray_at:function(t,e){return e|=0,f[f[(t|=0)+12>>2]+(e<<2)>>2]},tBtCollisionObjectArray_clear:lt,tVector3Array_at:function(t,e){return e|=0,f[(t|=0)+12>>2]+(e<<4)|0},tVector3Array_clear:lt,tScalarArray_at:function(t,e){return e|=0,v(C[f[(t|=0)+12>>2]+(e<<2)>>2])},tScalarArray_clear:lt,AllHitsRayResultCallback_create:function(t,e){t|=0,e|=0;var i,r,a=0;return i=q(136),f[i+28>>2]=0,f[i+32>>2]=0,f[i+20>>2]=0,f[i+12>>2]=1,f[i+16>>2]=-1,f[i+4>>2]=1065353216,f[i+8>>2]=0,n[i+40|0]=1,f[i>>2]=24920,f[i+36>>2]=0,a=f[t+4>>2],f[i+44>>2]=f[t>>2],f[i+48>>2]=a,t=f[(a=t+8|0)+4>>2],f[(r=i+52|0)>>2]=f[a>>2],f[r+4>>2]=t,t=f[e+4>>2],f[i+60>>2]=f[e>>2],f[i+64>>2]=t,a=f[(t=e+8|0)>>2],e=f[t+4>>2],f[i+88>>2]=0,f[i+80>>2]=0,f[i+84>>2]=0,f[i+120>>2]=0,f[i+124>>2]=0,f[i+128>>2]=0,f[i+108>>2]=0,n[i+132|0]=1,n[i+112|0]=1,n[i+92|0]=1,f[i+100>>2]=0,f[i+104>>2]=0,f[(t=i+68|0)>>2]=a,f[t+4>>2]=e,0|i},AllHitsRayResultCallback_get_m_rayFromWorld:function(t){return(t|=0)+44|0},AllHitsRayResultCallback_set_m_rayFromWorld:function(t,e){t|=0;var i=0;i=f[(e|=0)+4>>2],f[t+44>>2]=f[e>>2],f[t+48>>2]=i,i=f[(e=e+8|0)+4>>2],f[(t=t+52|0)>>2]=f[e>>2],f[t+4>>2]=i},AllHitsRayResultCallback_get_m_rayToWorld:function(t){return(t|=0)+60|0},AllHitsRayResultCallback_set_m_rayToWorld:function(t,e){t|=0;var i=0;i=f[(e|=0)+4>>2],f[t+60>>2]=f[e>>2],f[t+64>>2]=i,i=f[(e=e+8|0)+4>>2],f[(t=t+68|0)>>2]=f[e>>2],f[t+4>>2]=i},AllHitsRayResultCallback_get_m_hitPointWorld:function(t){return(t|=0)+96|0},AllHitsRayResultCallback_get_m_hitNormalWorld:function(t){return(t|=0)+76|0},AllHitsRayResultCallback_get_m_collisionObjects:bt,AllHitsRayResultCallback_get_m_hitFractions:function(t){return(t|=0)+116|0},btManifoldPoint_get_m_positionWorldOnA:ft,btManifoldPoint_get_m_positionWorldOnB:ut,btManifoldPoint_get_m_normalWorldOnB:st,btManifoldPoint_getDistance:function(t){return v(C[(t|=0)+80>>2])},ConvexResultCallback_hasHit:function(t){return C[(t|=0)+4>>2]>2]=-1,f[i+4>>2]=1065353216,f[i+8>>2]=1,f[i>>2]=25004,n=f[t+4>>2],f[i+16>>2]=f[t>>2],f[i+20>>2]=n,r=f[(t=t+8|0)+4>>2],f[(n=i+24|0)>>2]=f[t>>2],f[n+4>>2]=r,t=f[e+4>>2],f[i+32>>2]=f[e>>2],f[i+36>>2]=t,n=f[(e=e+8|0)+4>>2],f[(t=i+40|0)>>2]=f[e>>2],f[t+4>>2]=n,f[i+80>>2]=0,0|i},ClosestConvexResultCallback_get_m_hitNormalWorld:ft,ClosestConvexResultCallback_get_m_hitPointWorld:st,ClosestConvexResultCallback_get_m_hitCollisionObject:function(t){return f[(t|=0)+80>>2]},ClosestConvexResultCallback_set_m_hitCollisionObject:function(t,e){e|=0,f[(t|=0)+80>>2]=e},AllConvexResultCallback_create:function(t,e){t|=0,e|=0;var i,r,a=0;return i=q(128),f[i+20>>2]=0,f[i+24>>2]=0,f[i+12>>2]=-1,f[i+4>>2]=1065353216,f[i+8>>2]=1,n[i+32|0]=1,f[i>>2]=25144,f[i+28>>2]=0,a=f[t+4>>2],f[i+36>>2]=f[t>>2],f[i+40>>2]=a,r=f[(t=t+8|0)+4>>2],f[(a=i+44|0)>>2]=f[t>>2],f[a+4>>2]=r,t=f[e+4>>2],f[i+52>>2]=f[e>>2],f[i+56>>2]=t,e=f[(t=e+8|0)>>2],t=f[t+4>>2],f[i+80>>2]=0,f[i+72>>2]=0,f[i+76>>2]=0,f[i+100>>2]=0,f[i+112>>2]=0,f[i+116>>2]=0,f[i+120>>2]=0,n[i+124|0]=1,n[i+104|0]=1,n[i+84|0]=1,f[i+92>>2]=0,f[i+96>>2]=0,f[(a=i+60|0)>>2]=e,f[a+4>>2]=t,0|i},AllConvexResultCallback_get_m_hitNormalWorld:function(t){return(t|=0)+68|0},AllConvexResultCallback_get_m_hitPointWorld:function(t){return(t|=0)+88|0},AllConvexResultCallback_get_m_hitFractions:function(t){return(t|=0)+108|0},AllConvexResultCallback_get_m_collisionObjects:Qe,btCollisionShape_getLocalScaling:function(t){return 0|yt[f[f[(t|=0)>>2]+28>>2]](t)},btCollisionShape_setLocalScaling:function(t,e){e|=0,yt[f[f[(t|=0)>>2]+24>>2]](t,e)},btCollisionShape_calculateLocalInertia:function(t,e,i){t|=0,e=v(e),i|=0,yt[f[f[t>>2]+32>>2]](t,e,i)},btCollisionShape_destroy:nt,btBoxShape_create:function(t){var e;return t|=0,function(t,e){var i=v(0),r=v(0),n=v(0),a=v(0);zA(t),i=C[e>>2],n=C[e+4>>2],r=C[e+8>>2],f[t+44>>2]=0,a=v(r*C[t+24>>2]),r=C[t+48>>2],C[t+40>>2]=a-r,C[t+36>>2]=v(n*C[t+20>>2])-r,C[t+32>>2]=v(i*C[t+16>>2])-r,f[t+4>>2]=0,f[t>>2]=9056,i=C[e>>2],n=C[e+8>>2],a=C[e+4>>2],(i=v(C[((i>2]*v(.10000000149011612)))>2]=e,f[t>>2]=6056,f[t+56>>2]=1,f[t+4>>2]=10,f[t+44>>2]=0,C[t+40>>2]=e,C[t+36>>2]=i*v(.5),C[t+32>>2]=e}(i=dA(60),t,e),0|i},btCapsuleShapeX_create:function(t,e){var i;return t=v(t),e=v(e),function(t,e,i){DA(t),f[t+56>>2]=0,C[t+48>>2]=e,f[t>>2]=6156,f[t+4>>2]=10,f[t+44>>2]=0,C[t+40>>2]=e,C[t+36>>2]=e,C[t+32>>2]=i*v(.5)}(i=dA(60),t,e),0|i},btCapsuleShapeZ_create:function(t,e){var i;return t=v(t),e=v(e),function(t,e,i){DA(t),f[t+56>>2]=2,C[t+48>>2]=e,f[t>>2]=6256,f[t+4>>2]=10,f[t+44>>2]=0,C[t+40>>2]=i*v(.5),C[t+36>>2]=e,C[t+32>>2]=e}(i=dA(60),t,e),0|i},btCylinderShape_create:function(t){var e;return t|=0,function(t,e){var i=v(0),r=v(0),n=v(0),a=v(0);DA(t),i=C[e>>2],n=C[e+4>>2],r=C[e+8>>2],f[t+44>>2]=0,a=v(r*C[t+24>>2]),r=C[t+48>>2],C[t+40>>2]=a-r,C[t+36>>2]=v(n*C[t+20>>2])-r,C[t+32>>2]=v(i*C[t+16>>2])-r,f[t+56>>2]=1,f[t>>2]=9392,i=C[e>>2],n=C[e+8>>2],a=C[e+4>>2],(i=v(C[((i>2]*v(.10000000149011612)))>2]=13}(e=dA(60),t),0|e},btCylinderShapeX_create:function(t){var e;return t|=0,function(t,e){var i=v(0),r=v(0),n=v(0),a=v(0);DA(t),i=C[e>>2],n=C[e+4>>2],r=C[e+8>>2],f[t+44>>2]=0,a=v(r*C[t+24>>2]),r=C[t+48>>2],C[t+40>>2]=a-r,C[t+36>>2]=v(n*C[t+20>>2])-r,C[t+32>>2]=v(i*C[t+16>>2])-r,f[t+56>>2]=1,f[t>>2]=9392,i=C[e>>2],n=C[e+8>>2],a=C[e+4>>2],(i=v(C[((i>2]*v(.10000000149011612)))>2]=0,f[t>>2]=9496,f[t+4>>2]=13}(e=dA(60),t),0|e},btCylinderShapeZ_create:function(t){var e;return t|=0,function(t,e){var i=v(0),r=v(0),n=v(0),a=v(0);DA(t),i=C[e>>2],n=C[e+4>>2],r=C[e+8>>2],f[t+44>>2]=0,a=v(r*C[t+24>>2]),r=C[t+48>>2],C[t+40>>2]=a-r,C[t+36>>2]=v(n*C[t+20>>2])-r,C[t+32>>2]=v(i*C[t+16>>2])-r,f[t+56>>2]=1,f[t>>2]=9392,i=C[e>>2],n=C[e+8>>2],a=C[e+4>>2],(i=v(C[((i>2]*v(.10000000149011612)))>2]=2,f[t>>2]=9600,f[t+4>>2]=13}(e=dA(60),t),0|e},btSphereShape_create:function(t){var e,i;return t=v(t),DA(e=dA(56)),f[e+28>>2]=0,f[e+32>>2]=0,f[e+24>>2]=1065353216,f[e+16>>2]=1065353216,f[e+20>>2]=1065353216,f[e+4>>2]=8,f[e>>2]=9852,f[(i=e+36|0)>>2]=0,f[i+4>>2]=0,f[e+44>>2]=0,f[e+52>>2]=0,C[e+48>>2]=t,C[e+32>>2]=t,0|e},btConeShape_create:function(t,e){var i;return t=v(t),e=v(e),function(t,e,i){DA(t),C[t+64>>2]=i,C[t+60>>2]=e,f[t>>2]=6504,f[t+76>>2]=2,f[t+68>>2]=0,f[t+72>>2]=1,f[t+4>>2]=11,C[t+40>>2]=e,C[t+36>>2]=i,C[t+32>>2]=e,C[t+56>>2]=e/v(E(v(v(e*e)+v(i*i))))}(i=dA(80),t,e),0|i},btConeShapeX_create:function(t,e){var i;return t=v(t),e=v(e),function(t,e,i){DA(t),C[t+64>>2]=i,C[t+60>>2]=e,f[t+4>>2]=11,f[t+76>>2]=2,f[t+68>>2]=1,f[t+72>>2]=0,f[t>>2]=6704,C[t+36>>2]=e,C[t+40>>2]=e,C[t+32>>2]=i,C[t+56>>2]=e/v(E(v(v(e*e)+v(i*i))))}(i=dA(80),t,e),0|i},btConeShapeZ_create:function(t,e){var i;return t=v(t),e=v(e),function(t,e,i){DA(t),C[t+64>>2]=i,C[t+60>>2]=e,f[t+4>>2]=11,f[t+76>>2]=1,f[t+68>>2]=0,f[t+72>>2]=2,f[t>>2]=6604,C[t+40>>2]=i,C[t+32>>2]=e,C[t+36>>2]=e,C[t+56>>2]=e/v(E(v(v(e*e)+v(i*i))))}(i=dA(80),t,e),0|i},btStaticPlaneShape_create:function(t,e){var i;return t|=0,e=v(e),function(t,e,i){var r,n=v(0),a=v(0),o=v(0);He(t),f[t>>2]=10412,n=C[e+8>>2],a=C[e>>2],o=C[e+4>>2],e=f[e+12>>2],f[(r=t+80|0)>>2]=1065353216,f[r+4>>2]=0,f[t+72>>2]=1065353216,f[t+76>>2]=1065353216,C[t+68>>2]=i,f[t- -64>>2]=e,f[t+4>>2]=28,i=v(v(1)/v(E(v(v(v(a*a)+v(o*o))+v(n*n))))),C[t+60>>2]=n*i,C[t+56>>2]=o*i,C[t+52>>2]=a*i}(i=dA(88),t,e),0|i},btGImpactShapeInterface_updateBound:function(t){_[(t|=0)+52|0]&&(yt[f[f[t>>2]+68>>2]](t),n[t+52|0]=0)},btGImpactMeshShape_create:function(t){var e;return t|=0,function(t,e){var i=0,r=0,a=0,o=0,h=0,d=0,C=0;if(He(t),f[(i=t- -64|0)>>2]=1065353216,f[i+4>>2]=0,f[t+56>>2]=1065353216,f[t+60>>2]=1065353216,f[(i=t+36|0)>>2]=-8388609,f[i+4>>2]=-8388609,f[t+20>>2]=2139095039,f[t+24>>2]=2139095039,f[t>>2]=10820,f[t+88>>2]=0,n[t+92|0]=1,f[(i=t+80|0)>>2]=0,f[i+4>>2]=0,f[t+144>>2]=0,f[t+72>>2]=0,n[t+52|0]=1,f[t+44>>2]=-8388609,f[t+28>>2]=2139095039,f[t+4>>2]=25,n[t+168|0]=1,f[t+164>>2]=0,f[(i=t+156|0)>>2]=0,f[i+4>>2]=0,f[t+148>>2]=e,(0|yt[f[f[e>>2]+28>>2]](e))>=1)for(;;){if(Pe(C=dA(216),e,h),(0|(r=f[t+156>>2]))==f[t+160>>2]&&!((0|r)>=(0|(a=r?r<<1:1)))){if(a?(d=dA(a<<2),r=f[t+156>>2]):d=0,(0|r)>=1)for(o=0,i=r;f[o+d>>2]=f[f[t+164>>2]+o>>2],o=o+4|0,i=i+-1|0;);(i=f[t+164>>2])&&(_[t+168|0]&&(CA(i),r=f[t+156>>2]),f[t+164>>2]=0),f[t+164>>2]=d,n[t+168|0]=1,f[t+160>>2]=a}if(f[t+156>>2]=r+1,f[f[t+164>>2]+(r<<2)>>2]=C,!((0|(h=h+1|0))<(0|yt[f[f[e>>2]+28>>2]](e))))break}}(e=dA(172),t),0|e},btCompoundShape_create:function(){var t;return function(t){var e=0,i=0,r=0,a=0,o=0,h=0,d=0,C=0;if(f[t+12>>2]=-1,f[t+4>>2]=31,f[t+8>>2]=0,f[t>>2]=14216,f[t+76>>2]=0,f[t+80>>2]=1065353216,f[t+68>>2]=0,f[t+72>>2]=1,f[t+52>>2]=-581039253,f[t+56>>2]=-581039253,f[t+36>>2]=1566444395,f[t+40>>2]=1566444395,n[t+32|0]=1,f[t+28>>2]=0,f[t+92>>2]=0,f[(e=t+84|0)>>2]=1065353216,f[e+4>>2]=1065353216,f[(e=t+60|0)>>2]=-581039253,f[e+4>>2]=0,f[(e=t+44|0)>>2]=1566444395,f[e+4>>2]=0,f[(e=t+20|0)>>2]=0,f[e+4>>2]=0,er(e=dA(40)),f[t+68>>2]=e,f[t+24>>2]<0){if((0|(C=f[t+20>>2]))>=1)for(e=64;o=f[t+28>>2]+e|0,a=f[(i=o+-64|0)+4>>2],f[(r=e+-64|0)>>2]=f[i>>2],f[r+4>>2]=a,a=f[(i=i+8|0)+4>>2],f[(r=r+8|0)>>2]=f[i>>2],f[r+4>>2]=a,d=f[(r=(i=o+-48|0)+8|0)+4>>2],f[(h=(a=e+-48|0)+8|0)>>2]=f[r>>2],f[h+4>>2]=d,r=f[i+4>>2],f[a>>2]=f[i>>2],f[a+4>>2]=r,d=f[(r=(i=o+-32|0)+8|0)+4>>2],f[(h=(a=e+-32|0)+8|0)>>2]=f[r>>2],f[h+4>>2]=d,r=f[i+4>>2],f[a>>2]=f[i>>2],f[a+4>>2]=r,d=f[(r=(i=o+-16|0)+8|0)+4>>2],f[(h=(a=e+-16|0)+8|0)>>2]=f[r>>2],f[h+4>>2]=d,r=f[i+4>>2],f[a>>2]=f[i>>2],f[a+4>>2]=r,i=f[o+4>>2],f[e>>2]=f[o>>2],f[e+4>>2]=i,i=f[(o=o+8|0)+4>>2],f[(a=e+8|0)>>2]=f[o>>2],f[a+4>>2]=i,e=e+80|0,C=C+-1|0;);(e=f[t+28>>2])&&(_[t+32|0]&&CA(e),f[t+28>>2]=0),f[t+28>>2]=0,n[t+32|0]=1,f[t+24>>2]=0}}(t=dA(96)),0|t},btCompoundShape_addChildShape:function(t,e,i){(function(t,e,i){var r,a=0,o=v(0),h=0,d=0,g=0,y=v(0),p=0;Z=r=Z-144|0,f[t+72>>2]=f[t+72>>2]+1,d=f[(h=e+8|0)+4>>2],f[(a=r+72|0)>>2]=f[h>>2],f[a+4>>2]=d,d=f[(h=e+24|0)+4>>2],f[(a=r+88|0)>>2]=f[h>>2],f[a+4>>2]=d,d=f[(h=e+40|0)+4>>2],f[(a=r+104|0)>>2]=f[h>>2],f[a+4>>2]=d,d=f[(h=e+56|0)+4>>2],f[(a=r+120|0)>>2]=f[h>>2],f[a+4>>2]=d,f[r+140>>2]=0,f[r+128>>2]=i,a=f[e+4>>2],f[r+64>>2]=f[e>>2],f[r+68>>2]=a,a=f[e+20>>2],f[r+80>>2]=f[e+16>>2],f[r+84>>2]=a,a=f[e+36>>2],f[r+96>>2]=f[e+32>>2],f[r+100>>2]=a,a=f[e+52>>2],f[r+112>>2]=f[e+48>>2],f[r+116>>2]=a,f[r+132>>2]=f[i+4>>2],g=r,y=v(yt[f[f[i>>2]+48>>2]](i)),C[g+136>>2]=y,yt[f[f[i>>2]+8>>2]](i,e,r+48|0,r+32|0),o=C[r+48>>2],C[t+36>>2]>o&&(C[t+36>>2]=o),o=C[r+32>>2],C[t+52>>2]>2]=o),o=C[r+52>>2],C[t+40>>2]>o&&(C[t+40>>2]=o),o=C[r+36>>2],C[t+56>>2]>2]=o),o=C[r+56>>2],C[t+44>>2]>o&&(C[t+44>>2]=o),o=C[r+40>>2],C[t+60>>2]>2]=o),(e=f[t+68>>2])&&(h=f[(a=r+56|0)+4>>2],f[(i=r+8|0)>>2]=f[a>>2],f[i+4>>2]=h,h=f[(a=r+40|0)+4>>2],f[(i=r+24|0)>>2]=f[a>>2],f[i+4>>2]=h,i=f[r+52>>2],f[r>>2]=f[r+48>>2],f[r+4>>2]=i,i=f[r+36>>2],f[r+16>>2]=f[r+32>>2],f[r+20>>2]=i,g=r,p=or(e,r,f[t+20>>2]),f[g+140>>2]=p),function(t,e){var i=0,r=0,a=0,o=0,h=0,d=0,C=0,g=0,v=0,y=0,p=0;if((0|(r=f[t+4>>2]))==f[t+8>>2]&&!((0|r)>=(0|(y=r?r<<1:1)))){if(y&&(p=dA(m(y,80)),r=f[t+4>>2]),(0|r)>=1)for(C=64;a=f[t+12>>2]+C|0,g=f[(o=a+-64|0)+4>>2],f[(h=(i=C+p|0)+-64|0)>>2]=f[o>>2],f[h+4>>2]=g,d=f[(o=o+8|0)+4>>2],f[(h=h+8|0)>>2]=f[o>>2],f[h+4>>2]=d,v=f[(g=(h=a+-48|0)+8|0)+4>>2],f[(d=(o=i+-48|0)+8|0)>>2]=f[g>>2],f[d+4>>2]=v,d=f[h+4>>2],f[o>>2]=f[h>>2],f[o+4>>2]=d,v=f[(g=(h=a+-32|0)+8|0)+4>>2],f[(d=(o=i+-32|0)+8|0)>>2]=f[g>>2],f[d+4>>2]=v,d=f[h+4>>2],f[o>>2]=f[h>>2],f[o+4>>2]=d,v=f[(g=(h=a+-16|0)+8|0)+4>>2],f[(d=(o=i+-16|0)+8|0)>>2]=f[g>>2],f[d+4>>2]=v,d=f[h+4>>2],f[o>>2]=f[h>>2],f[o+4>>2]=d,o=f[a+4>>2],f[i>>2]=f[a>>2],f[i+4>>2]=o,o=f[(a=a+8|0)+4>>2],f[(i=i+8|0)>>2]=f[a>>2],f[i+4>>2]=o,C=C+80|0,r=r+-1|0;);(r=f[t+12>>2])&&(_[t+16|0]&&CA(r),f[t+12>>2]=0),f[t+12>>2]=p,n[t+16|0]=1,f[t+8>>2]=y,r=f[t+4>>2]}a=f[e+4>>2],r=f[t+12>>2]+m(r,80)|0,f[(i=r)>>2]=f[e>>2],f[i+4>>2]=a,C=f[(a=e+8|0)+4>>2],f[(i=i+8|0)>>2]=f[a>>2],f[i+4>>2]=C,C=f[(a=e+24|0)+4>>2],f[(i=r+24|0)>>2]=f[a>>2],f[i+4>>2]=C,i=f[e+20>>2],f[r+16>>2]=f[e+16>>2],f[r+20>>2]=i,C=f[(a=e+40|0)+4>>2],f[(i=r+40|0)>>2]=f[a>>2],f[i+4>>2]=C,i=f[e+36>>2],f[r+32>>2]=f[e+32>>2],f[r+36>>2]=i,C=f[(a=e+56|0)+4>>2],f[(i=r+56|0)>>2]=f[a>>2],f[i+4>>2]=C,i=f[e+52>>2],f[r+48>>2]=f[e+48>>2],f[r+52>>2]=i,C=f[(a=e+72|0)+4>>2],f[(i=r+72|0)>>2]=f[a>>2],f[i+4>>2]=C,i=f[e+68>>2],f[r+64>>2]=f[e+64>>2],f[r+68>>2]=i,f[t+4>>2]=f[t+4>>2]+1}(t+16|0,r- -64|0),Z=r+144|0})(t|=0,e|=0,i|=0)},btCompoundShape_removeChildShapeByIndex:function(t,e){Br(t|=0,e|=0)},btCompoundShape_getChildShape:function(t,e){return e|=0,f[64+(f[(t|=0)+28>>2]+m(e,80)|0)>>2]},btCompoundShape_updateChildTransform:function(t,e,i,r){(function(t,e,i,r){var n,a,o=0,_=0,h=0;Z=n=Z+-64|0,_=f[i+4>>2],e=(a=m(e,80))+f[t+28>>2]|0,f[e>>2]=f[i>>2],f[e+4>>2]=_,h=f[(_=i+8|0)+4>>2],f[(o=e+8|0)>>2]=f[_>>2],f[o+4>>2]=h,h=f[(_=i+24|0)+4>>2],f[(o=e+24|0)>>2]=f[_>>2],f[o+4>>2]=h,o=f[i+20>>2],f[e+16>>2]=f[i+16>>2],f[e+20>>2]=o,h=f[(_=i+40|0)+4>>2],f[(o=e+40|0)>>2]=f[_>>2],f[o+4>>2]=h,o=f[i+36>>2],f[e+32>>2]=f[i+32>>2],f[e+36>>2]=o,h=f[(_=i+56|0)+4>>2],f[(o=e+56|0)>>2]=f[_>>2],f[o+4>>2]=h,o=f[i+52>>2],f[e+48>>2]=f[i+48>>2],f[e+52>>2]=o,f[t+68>>2]&&(e=f[64+(f[t+28>>2]+a|0)>>2],yt[f[f[e>>2]+8>>2]](e,i,n+48|0,n+32|0),o=f[(i=n+56|0)+4>>2],f[(e=n+8|0)>>2]=f[i>>2],f[e+4>>2]=o,o=f[(i=n+40|0)+4>>2],f[(e=n+24|0)>>2]=f[i>>2],f[e+4>>2]=o,e=f[n+36>>2],f[n+16>>2]=f[n+32>>2],f[n+20>>2]=e,e=f[n+52>>2],f[n>>2]=f[n+48>>2],f[n+4>>2]=e,cr(f[t+68>>2],f[76+(f[t+28>>2]+a|0)>>2],n)),r&&yt[f[f[t>>2]+68>>2]](t),Z=n- -64|0})(t|=0,e|=0,i|=0,r|=0)},btStridingMeshInterface_destroy:nt,btTriangleMesh_create:function(){var t;return function(t){var e=0,i=0,r=0,a=0,o=0,h=0,d=0,C=0;if(f[t+4>>2]=1065353216,f[t+8>>2]=1065353216,f[t+48>>2]=0,f[t>>2]=14676,n[t+36|0]=1,f[(e=t+12|0)>>2]=1065353216,f[e+4>>2]=0,f[t+32>>2]=0,f[(e=i=t+24|0)>>2]=0,f[e+4>>2]=0,n[t+100|0]=1,f[t+96>>2]=0,n[t+120|0]=1,f[(e=t+88|0)>>2]=0,f[e+4>>2]=0,f[t+116>>2]=0,n[t+140|0]=1,f[(e=t+108|0)>>2]=0,f[e+4>>2]=0,f[t+136>>2]=0,n[t+160|0]=1,f[(e=t+128|0)>>2]=0,f[e+4>>2]=0,f[t+168>>2]=0,n[t+164|0]=1,f[(e=t+148|0)>>2]=0,f[e+4>>2]=0,f[t+156>>2]=0,n[t+165|0]=1,e=dA(32),(0|(o=f[i>>2]))>=1)for(;h=f[t+32>>2]+a|0,d=f[(r=h)+4>>2],f[(i=e+a|0)>>2]=f[r>>2],f[i+4>>2]=d,d=f[(r=r+24|0)+4>>2],f[(C=i+24|0)>>2]=f[r>>2],f[C+4>>2]=d,d=f[(r=h+16|0)+4>>2],f[(C=i+16|0)>>2]=f[r>>2],f[C+4>>2]=d,r=f[(h=h+8|0)+4>>2],f[(i=i+8|0)>>2]=f[h>>2],f[i+4>>2]=r,a=a+32|0,o=o+-1|0;);(a=f[t+32>>2])&&(_[t+36|0]&&CA(a),f[t+32>>2]=0),f[t+32>>2]=e,n[t+36|0]=1,f[t+28>>2]=1,e=(f[t+24>>2]<<5)+e|0,f[e+24>>2]=2,f[e+28>>2]=0,f[e+16>>2]=0,f[e+20>>2]=16,f[e+8>>2]=12,f[e+12>>2]=0,f[e>>2]=0,f[e+4>>2]=0,f[t+24>>2]=f[t+24>>2]+1,e=f[t+32>>2],f[e+4>>2]=0,a=_[t+164|0],f[e+24>>2]=a?2:3,o=f[(a?128:148)+t>>2],i=12,f[e+8>>2]=a?12:6,f[e>>2]=(0|o)/3,_[t+165|0]?(i=16,t=f[t+88>>2]):t=f[t+108>>2]/3|0,f[e+20>>2]=i,f[e+16>>2]=0,f[e+12>>2]=t}(t=dA(172)),0|t},btTriangleMesh_addTriangle:function(t,e,i,r,n){(function(t,e,i,r,n){var a;a=f[t+32>>2],f[a>>2]=f[a>>2]+1,Qr(t,hr(t,e,n)),Qr(t,hr(t,i,n)),Qr(t,hr(t,r,n))})(t|=0,e|=0,i|=0,r|=0,n|=0)},btDefaultCollisionConfiguration_create:function(){var t,e;return Z=t=Z-32|0,e=q(88),f[t+24>>2]=0,f[t+28>>2]=1,f[t+16>>2]=4096,f[t+20>>2]=4096,f[t+8>>2]=0,f[t+12>>2]=0,function(t,e){var i,r=0,a=0,o=0,_=0,h=0;if(f[t>>2]=17664,a=f[e+20>>2],r=dA(4),f[t+24>>2]=r,f[r>>2]=a?14800:15008,function(t,e){f[t+12>>2]=0,f[t+16>>2]=3,f[t>>2]=15424,n[t+4|0]=0,f[t+8>>2]=e}(r=dA(20),f[t+24>>2]),f[t+28>>2]=r,r=dA(8),f[r>>2]=17780,n[r+4|0]=0,f[t+32>>2]=r,r=dA(8),f[r>>2]=17864,n[r+4|0]=0,f[t+36>>2]=r,r=dA(8),f[r>>2]=17956,n[r+4|0]=0,f[t+40>>2]=r,r=dA(8),f[r>>2]=18036,n[r+4|0]=0,f[t+44>>2]=r,r=dA(8),f[r>>2]=18124,n[r+4|0]=0,f[t+48>>2]=r,r=dA(8),f[r>>2]=18208,n[r+4|0]=0,f[t+52>>2]=r,r=dA(8),f[r>>2]=18276,n[r+4|0]=0,f[t+56>>2]=r,r=dA(8),f[r>>2]=18360,n[r+4|0]=0,f[t+72>>2]=r,r=dA(8),f[t+76>>2]=r,f[r>>2]=18360,n[r+4|0]=1,r=dA(8),f[r>>2]=18444,n[r+4|0]=0,f[t+68>>2]=r,r=dA(16),f[r+8>>2]=1,f[r+12>>2]=0,f[r>>2]=18520,n[r+4|0]=0,f[t+84>>2]=r,r=dA(16),f[r+8>>2]=1,f[r+12>>2]=0,f[r>>2]=18520,f[t+80>>2]=r,n[r+4|0]=1,i=f[e+16>>2],r=f[e>>2])f[t+8>>2]=r,n[t+12|0]=0;else{if(n[t+12|0]=1,_=dA(24),f[_+20>>2]=0,f[_>>2]=804,r=f[e+8>>2],f[_+4>>2]=r,a=dA(m(r,804)),f[_+12>>2]=a,f[_+16>>2]=a,r=f[_+4>>2],f[_+8>>2]=r,h=r+-1|0)for(o=f[_>>2];r=a+o|0,f[a>>2]=r,a=r,h=h+-1|0;);else r=a;f[r>>2]=0,f[t+8>>2]=_}if(r=f[e+4>>2])return f[t+16>>2]=r,void(n[t+20|0]=0);if(n[t+20|0]=1,o=dA(24),f[o+20>>2]=0,r=(0|(r=(0|i)>80?i:80))>116?r+16&-16:128,f[o>>2]=r,e=f[e+12>>2],f[o+4>>2]=e,a=dA(m(e,r)),f[o+12>>2]=a,f[o+16>>2]=a,e=f[o+4>>2],f[o+8>>2]=e,h=e+-1|0)for(e=f[o>>2];r=e+a|0,f[a>>2]=r,a=r,h=h+-1|0;);else r=a;f[r>>2]=0,f[t+16>>2]=o}(e,t+8|0),Z=t+32|0,0|e},btDefaultCollisionConfiguration_destroy:nt,btPersistentManifold_getBody0:function(t){return f[(t|=0)+772>>2]},btPersistentManifold_getBody1:function(t){return f[(t|=0)+776>>2]},btPersistentManifold_getNumContacts:function(t){return f[(t|=0)+780>>2]},btPersistentManifold_getContactPoint:function(t,e){return t|=0,4+(m(e|=0,192)+t|0)|0},btDispatcher_getNumManifolds:kt,btDispatcher_getManifoldByIndexInternal:function(t,e){return e|=0,0|yt[f[f[(t|=0)>>2]+40>>2]](t,e)},btCollisionDispatcher_create:function(t){var e;return t|=0,function(t,e){var i=0,r=0,a=0,o=0,_=0,h=0;for(f[t+28>>2]=7720,f[t>>2]=7860,f[t+4>>2]=2,f[t+10444>>2]=e,f[t+64>>2]=111,n[t+24|0]=1,f[t+20>>2]=0,f[t+60>>2]=0,f[(i=t+12|0)>>2]=0,f[i+4>>2]=0,_=t,h=0|yt[f[f[e>>2]+12>>2]](e),f[_+68>>2]=h,_=t,h=0|yt[f[f[e>>2]+8>>2]](e),f[_+72>>2]=h,i=t+5260|0;;){for(e=i,r=0;a=f[t+10444>>2],_=e+-5184|0,h=0|yt[f[f[a>>2]+16>>2]](a,o,r),f[_>>2]=h,a=f[t+10444>>2],_=e,h=0|yt[f[f[a>>2]+20>>2]](a,o,r),f[_>>2]=h,e=e+4|0,36!=(0|(r=r+1|0)););if(i=i+144|0,36==(0|(o=o+1|0)))break}}(e=q(10448),t),0|e},btCollisionDispatcher_destroy:nt,btOverlappingPairCache_setInternalGhostPairCallback:vt,btDbvtBroadphase_create:function(){var t;return function(t){var e,i=0,r=0,a=0,o=0,h=0,d=0;if(Z=e=Z-32|0,f[t>>2]=19124,er(t+4|0),er(t+44|0),f[t+168>>2]=0,n[t+172|0]=1,f[(i=t+160|0)>>2]=0,f[i+4>>2]=0,n[t+153|0]=256,n[t+154|0]=1,n[t+152|0]=1,f[t+124>>2]=0,f[t+100>>2]=0,f[t+104>>2]=0,f[t+136>>2]=0,f[t+128>>2]=0,f[t+132>>2]=0,f[t+116>>2]=10,f[t+120>>2]=1,f[t+108>>2]=1,f[t+112>>2]=0,Ri(r=dA(72)),i=f[t+160>>2],f[t+148>>2]=0,f[t+96>>2]=r,f[t+140>>2]=0,f[t+144>>2]=0,f[(r=t+84|0)>>2]=0,f[r+4>>2]=0,f[t+92>>2]=0,f[e+20>>2]=0,n[e+24|0]=1,f[e+12>>2]=0,f[e+16>>2]=0,(0|i)>=2)for(a=i+-1|0,i=36;d=(r=f[t+168>>2]+i|0)+-12|0,(h=f[(o=r+-4|0)>>2])&&(_[0|r]&&CA(h),f[o>>2]=0),f[o>>2]=0,f[d>>2]=0,n[0|r]=1,f[r+-8>>2]=0,i=i+20|0,a=a+-1|0;);else if(1!=(0|i))for(function(t){var e=0,i=0,r=0,a=0,o=0,h=0,d=0;if(f[t+8>>2]<1){if(o=dA(20),!((0|(e=f[t+4>>2]))<1)){for(;pi(i+o|0,f[t+12>>2]+i|0),i=i+20|0,e=e+-1|0;);if(!((0|(r=f[t+4>>2]))<1))for(e=8;d=(i=f[t+12>>2]+e|0)+-4|0,(h=f[(a=i+4|0)>>2])&&(_[i+8|0]&&CA(h),f[a>>2]=0),f[d>>2]=0,f[a>>2]=0,f[i>>2]=0,n[i+8|0]=1,e=e+20|0,r=r+-1|0;);}(e=f[t+12>>2])&&(_[t+16|0]&&CA(e),f[t+12>>2]=0),f[t+12>>2]=o,n[t+16|0]=1,f[t+8>>2]=1}}(t+156|0),a=m(i,20),i=i+-1|0;pi(f[t+168>>2]+a|0,e+8|0),a=a+20|0,o=(r=i+1|0)>>>0>=i>>>0,i=r,o;);f[t+160>>2]=1,(t=f[e+20>>2])&&(_[e+24|0]&&CA(t),f[e+20>>2]=0),Z=e+32|0}(t=q(176)),0|t},btDbvtBroadphase_getOverlappingPairCache:kt,btDbvtBroadphase_destroy:nt,btRigidBodyConstructionInfo_create:function(t,e,i,r){var a;return t=v(t),e|=0,i|=0,r|=0,a=q(144),f[a+72>>2]=i,f[a+4>>2]=e,C[a>>2]=t,e=f[r+4>>2],f[a+76>>2]=f[r>>2],f[a+80>>2]=e,e=f[(i=r+8|0)+4>>2],f[(r=a+84|0)>>2]=f[i>>2],f[r+4>>2]=e,f[a+136>>2]=1008981770,f[a+140>>2]=1008981770,f[a+128>>2]=1000593162,f[a+132>>2]=1008981770,n[a+124|0]=0,f[a+116>>2]=1061997773,f[a+120>>2]=1065353216,f[a+108>>2]=0,f[a+112>>2]=0,f[a+100>>2]=1056964608,f[a+104>>2]=0,f[a+92>>2]=0,f[a+96>>2]=0,f[a+8>>2]=1065353216,f[(e=a+20|0)>>2]=0,f[e+4>>2]=0,f[a+12>>2]=0,f[a+16>>2]=0,f[a+28>>2]=1065353216,f[(e=a+40|0)>>2]=0,f[e+4>>2]=0,f[a+32>>2]=0,f[a+36>>2]=0,f[a+48>>2]=1065353216,f[a+68>>2]=0,f[(e=a+60|0)>>2]=0,f[e+4>>2]=0,f[a+52>>2]=0,f[a+56>>2]=0,0|a},btRigidBodyConstructionInfo_destroy:function(t){(t|=0)&&$(t)},btRigidBody_create:function(t){var e;return t|=0,function(t,e){var i;Ee(t),n[t+560|0]=1,f[t>>2]=20096,f[t+556>>2]=0,f[(i=t+548|0)>>2]=0,f[i+4>>2]=0,function(t,e){var i,r,a=0,o=0,h=0,d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),E=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0);Z=i=Z-16|0,f[t+372>>2]=0,f[t+376>>2]=0,f[t+252>>2]=2,f[t+604>>2]=1065353216,f[t+608>>2]=1065353216,f[t+408>>2]=1065353216,f[t+412>>2]=1065353216,f[t+472>>2]=0,f[t+476>>2]=0,f[(a=t+380|0)>>2]=0,f[a+4>>2]=0,f[(a=t+388|0)>>2]=0,f[a+4>>2]=0,f[(a=t+396|0)>>2]=0,f[a+4>>2]=0,f[(a=t+612|0)>>2]=1065353216,f[a+4>>2]=0,f[(a=t+420|0)>>2]=0,f[a+4>>2]=0,f[t+416>>2]=1065353216,f[(a=t+428|0)>>2]=0,f[a+4>>2]=0,f[(a=t+436|0)>>2]=0,f[a+4>>2]=0,f[(a=t+444|0)>>2]=0,f[a+4>>2]=0,f[t+452>>2]=0,f[(a=t+480|0)>>2]=0,f[a+4>>2]=0,f[(a=t+488|0)>>2]=0,f[a+4>>2]=0,f[(a=t+496|0)>>2]=0,f[a+4>>2]=0,g=C[e+96>>2],d=C[e+92>>2],C[i+12>>2]=d,C[i+8>>2]=g,f[i+4>>2]=0,f[i>>2]=1065353216,f[t+504>>2]=f[(dv(1)?i:i+12|0)>>2],f[i+4>>2]=0,f[i>>2]=1065353216,f[t+508>>2]=f[(gv(1)?i:i+8|0)>>2],f[t+668>>2]=0,f[t+672>>2]=0,a=f[e+120>>2],f[t+532>>2]=f[e+116>>2],f[t+536>>2]=a,o=f[e+4>>2],f[t+540>>2]=o,n[t+512|0]=_[e+124|0],a=f[e+132>>2],f[t+516>>2]=f[e+128>>2],f[t+520>>2]=a,a=f[e+140>>2],f[t+524>>2]=f[e+136>>2],f[t+528>>2]=a,o?(a=t+4|0,yt[f[f[o>>2]+8>>2]](o,a)):(a=f[e+12>>2],f[t+4>>2]=f[e+8>>2],f[t+8>>2]=a,h=f[(o=e+16|0)+4>>2],f[(a=t+12|0)>>2]=f[o>>2],f[a+4>>2]=h,h=f[(o=e+32|0)+4>>2],f[(a=t+28|0)>>2]=f[o>>2],f[a+4>>2]=h,h=f[(o=e+24|0)+4>>2],f[(a=t+20|0)>>2]=f[o>>2],f[a+4>>2]=h,h=f[(o=e+40|0)+4>>2],f[(a=t+36|0)>>2]=f[o>>2],f[a+4>>2]=h,h=f[(o=e+48|0)+4>>2],f[(a=t+44|0)>>2]=f[o>>2],f[a+4>>2]=h,h=f[(o=e- -64|0)+4>>2],f[(a=t+60|0)>>2]=f[o>>2],f[a+4>>2]=h,h=f[(o=e+56|0)+4>>2],f[(a=t+52|0)>>2]=f[o>>2],f[a+4>>2]=h,a=t+4|0),f[t+132>>2]=0,f[t+136>>2]=0,o=f[a+4>>2],f[t+68>>2]=f[a>>2],f[t+72>>2]=o,f[(o=t+156|0)>>2]=0,f[o+4>>2]=0,f[(o=t+148|0)>>2]=0,f[o+4>>2]=0,f[(o=t+140|0)>>2]=0,f[o+4>>2]=0,r=f[(h=t+20|0)+4>>2],f[(o=t+84|0)>>2]=f[h>>2],f[o+4>>2]=r,h=f[(a=a+8|0)+4>>2],f[(o=t+76|0)>>2]=f[a>>2],f[o+4>>2]=h,h=f[(o=t+28|0)+4>>2],f[(a=t+92|0)>>2]=f[o>>2],f[a+4>>2]=h,h=f[(o=t+36|0)+4>>2],f[(a=t+100|0)>>2]=f[o>>2],f[a+4>>2]=h,h=f[(o=t+44|0)+4>>2],f[(a=t+108|0)>>2]=f[o>>2],f[a+4>>2]=h,h=f[(o=t+52|0)+4>>2],f[(a=t+116|0)>>2]=f[o>>2],f[a+4>>2]=h,h=f[(o=t+60|0)+4>>2],f[(a=t+124|0)>>2]=f[o>>2],f[a+4>>2]=h,f[t+228>>2]=f[e+100>>2],f[t+236>>2]=f[e+104>>2],f[t+240>>2]=f[e+108>>2],f[t+232>>2]=f[e+112>>2],yt[f[f[t>>2]+8>>2]](t,f[e+72>>2]),a=f[699],f[t+568>>2]=a,f[699]=a+1,g=v(0),a=f[t+204>>2],(d=C[e>>2])!=v(0)?(f[t+204>>2]=-2&a,g=v(v(1)/d)):f[t+204>>2]=1|a,f[t+436>>2]=0,C[t+404>>2]=g,C[t+432>>2]=d*C[t+448>>2],C[t+428>>2]=d*C[t+444>>2],C[t+424>>2]=d*C[t+440>>2],d=C[e+84>>2],m=C[e+80>>2],F=C[e+76>>2],C[t+620>>2]=g*C[t+408>>2],C[(a=t+624|0)>>2]=g*C[t+412>>2],C[(o=t+628|0)>>2]=g*C[t+416>>2],f[(e=t+632|0)>>2]=0,f[t+468>>2]=0,V=F!=v(0)?v(v(1)/F):v(0),C[t+456>>2]=V,G=m!=v(0)?v(v(1)/m):v(0),C[t+460>>2]=G,w=d!=v(0)?v(v(1)/d):v(0),C[t+464>>2]=w,d=C[t+12>>2],m=C[t+8>>2],F=C[t+28>>2],Q=C[t+20>>2],W=C[t+24>>2],D=C[t+44>>2],B=C[t+36>>2],E=C[t+40>>2],Y=C[t+4>>2],f[t+564>>2]=8,f[t+368>>2]=0,f[t+352>>2]=0,f[t+336>>2]=0,y=v(V*B),p=v(G*E),R=v(w*D),C[t+364>>2]=v(v(B*y)+v(E*p))+v(D*R),C[t+360>>2]=v(v(Q*y)+v(W*p))+v(F*R),C[t+356>>2]=v(v(Y*y)+v(m*p))+v(d*R),y=v(V*Q),p=v(G*W),R=v(w*F),C[t+348>>2]=v(v(B*y)+v(E*p))+v(D*R),C[t+344>>2]=v(v(Q*y)+v(W*p))+v(F*R),C[t+340>>2]=v(v(Y*y)+v(m*p))+v(d*R),y=B,B=v(V*Y),p=E,E=v(G*m),R=D,D=v(w*d),C[t+332>>2]=v(v(y*B)+v(p*E))+v(R*D),C[t+328>>2]=v(v(B*Q)+v(E*W))+v(D*F),C[t+324>>2]=v(v(Y*B)+v(m*E))+v(d*D),f[(h=t+596|0)>>2]=0,f[h+4>>2]=0,f[(h=t+588|0)>>2]=0,f[h+4>>2]=0,f[(h=t+580|0)>>2]=0,f[h+4>>2]=0,f[t+572>>2]=0,f[t+576>>2]=0,d=C[t+408>>2],m=C[t+412>>2],C[o>>2]=g*C[t+416>>2],C[a>>2]=g*m,C[t+620>>2]=g*d,f[t+664>>2]=0,f[(a=t+656|0)>>2]=0,f[a+4>>2]=0,f[(a=t+648|0)>>2]=0,f[a+4>>2]=0,f[(t=t+640|0)>>2]=0,f[t+4>>2]=0,f[e>>2]=0,f[e+4>>2]=0,Z=i+16|0}(t,e)}(e=dA(676),t),0|e},btRigidBody_setCenterOfMassTransform:ji,btRigidBody_setSleepingThresholds:function(t,e,i){t|=0,e=v(e),i=v(i),C[t+536>>2]=i,C[t+532>>2]=e},btRigidBody_getLinearSleepingThreshold:function(t){return v(C[(t|=0)+532>>2])},btRigidBody_getAngularSleepingThreshold:function(t){return v(C[(t|=0)+536>>2])},btRigidBody_setDamping:function(t,e,i){(function(t,e,i){var r;C[(r=Z-16|0)+8>>2]=i,C[r+12>>2]=e,f[r+4>>2]=0,f[r>>2]=1065353216,f[t+504>>2]=f[(ev(1)?r:r+12|0)>>2],f[r+4>>2]=0,f[r>>2]=1065353216,f[t+508>>2]=f[(iv(1)?r:r+8|0)>>2]})(t|=0,e=v(e),i=v(i))},btRigidBody_setMassProps:function(t,e,i){(function(t,e,i){var r,n=v(0),a=v(0),o=v(0);r=f[t+204>>2],e!=v(0)?(f[t+204>>2]=-2&r,n=v(v(1)/e)):f[t+204>>2]=1|r,C[t+404>>2]=n,f[t+436>>2]=0,C[t+424>>2]=C[t+440>>2]*e,C[t+432>>2]=C[t+448>>2]*e,C[t+428>>2]=C[t+444>>2]*e,e=C[i+8>>2],a=C[i+4>>2],o=C[i>>2],C[t+620>>2]=C[t+408>>2]*n,C[t+624>>2]=n*C[t+412>>2],C[t+628>>2]=n*C[t+416>>2],f[t+632>>2]=0,f[t+468>>2]=0,C[t+456>>2]=o!=v(0)?v(v(1)/o):v(0),C[t+460>>2]=a!=v(0)?v(v(1)/a):v(0),C[t+464>>2]=e!=v(0)?v(v(1)/e):v(0)})(t|=0,e=v(e),i|=0)},btRigidBody_setLinearFactor:function(t,e){t|=0,e|=0;var i,r=0,n=v(0);r=f[e+4>>2],f[t+408>>2]=f[e>>2],f[t+412>>2]=r,i=f[(e=e+8|0)+4>>2],f[(r=t+416|0)>>2]=f[e>>2],f[r+4>>2]=i,f[t+632>>2]=0,n=C[t+404>>2],C[t+624>>2]=n*C[t+412>>2],C[t+620>>2]=n*C[t+408>>2],C[t+628>>2]=n*C[r>>2]},btRigidBody_applyTorque:function(t,e){t|=0,e|=0;var i=v(0),r=v(0);i=C[e+8>>2],r=C[e+4>>2],C[t+488>>2]=v(C[e>>2]*C[t+604>>2])+C[t+488>>2],C[(e=t+492|0)>>2]=v(r*C[t+608>>2])+C[e>>2],C[(e=t+496|0)>>2]=v(i*C[t+612>>2])+C[e>>2]},btRigidBody_applyForce:function(t,e,i){t|=0,e|=0,i|=0;var r=v(0),n=v(0),a=0,o=v(0),f=v(0),_=v(0),h=v(0),d=v(0),g=v(0);f=C[e+8>>2],r=C[e+4>>2],n=C[t+408>>2],C[t+472>>2]=v(C[e>>2]*n)+C[t+472>>2],a=t+476|0,_=r,r=C[t+412>>2],C[a>>2]=v(_*r)+C[a>>2],a=t+480|0,o=C[t+416>>2],C[a>>2]=v(f*o)+C[a>>2],g=C[e>>2],f=C[i>>2],h=C[i+4>>2],o=v(o*C[e+8>>2]),r=v(r*C[e+4>>2]),d=C[i+8>>2],C[t+488>>2]=v(v(v(h*o)-v(r*d))*C[t+604>>2])+C[t+488>>2],_=C[t+612>>2],e=t+492|0,n=v(n*g),C[e>>2]=v(v(v(d*n)-v(o*f))*C[t+608>>2])+C[e>>2],C[(t=t+496|0)>>2]=v(_*v(v(r*f)-v(n*h)))+C[t>>2]},btRigidBody_applyCentralForce:function(t,e){t|=0,e|=0;var i=v(0),r=v(0);i=C[e+8>>2],r=C[e+4>>2],C[t+472>>2]=v(C[e>>2]*C[t+408>>2])+C[t+472>>2],C[(e=t+476|0)>>2]=v(r*C[t+412>>2])+C[e>>2],C[(e=t+480|0)>>2]=v(i*C[t+416>>2])+C[e>>2]},btRigidBody_applyTorqueImpulse:function(t,e){t|=0,e|=0;var i=v(0),r=v(0),n=v(0);i=C[e>>2],r=C[e+4>>2],n=C[e+8>>2],C[t+388>>2]=v(v(v(v(C[t+324>>2]*i)+v(C[t+328>>2]*r))+v(C[t+332>>2]*n))*C[t+604>>2])+C[t+388>>2],C[(e=t+392|0)>>2]=v(v(v(v(i*C[t+340>>2])+v(r*C[t+344>>2]))+v(n*C[t+348>>2]))*C[t+608>>2])+C[e>>2],C[(e=t+396|0)>>2]=v(v(v(v(i*C[t+356>>2])+v(r*C[t+360>>2]))+v(n*C[t+364>>2]))*C[t+612>>2])+C[e>>2]},btRigidBody_applyImpulse:function(t,e,i){dt(t|=0,e|=0,i|=0)},btRigidBody_applyCentralImpulse:function(t,e){t|=0,e|=0;var i=v(0),r=v(0),n=v(0);r=C[e+8>>2],n=C[e+4>>2],i=C[t+404>>2],C[t+372>>2]=v(v(C[e>>2]*C[t+408>>2])*i)+C[t+372>>2],C[(e=t+376|0)>>2]=v(i*v(n*C[t+412>>2]))+C[e>>2],C[(e=t+380|0)>>2]=v(i*v(r*C[t+416>>2]))+C[e>>2]},btRigidBody_updateInertiaTensor:function(t){(function(t){var e=v(0),i=v(0),r=v(0),n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0);f[t+368>>2]=0,f[t+352>>2]=0,f[t+336>>2]=0,p=C[t+456>>2],e=C[t+36>>2],i=v(p*e),R=C[t+460>>2],r=C[t+40>>2],n=v(R*r),D=C[t+464>>2],a=C[t+44>>2],o=v(D*a),C[t+364>>2]=v(v(i*e)+v(n*r))+v(o*a),g=C[t+20>>2],m=C[t+24>>2],y=C[t+28>>2],C[t+360>>2]=v(v(i*g)+v(n*m))+v(o*y),_=i,i=C[t+4>>2],h=n,n=C[t+8>>2],d=o,o=C[t+12>>2],C[t+356>>2]=v(v(_*i)+v(h*n))+v(d*o),_=v(p*g),h=v(R*m),d=v(D*y),C[t+348>>2]=v(v(e*_)+v(r*h))+v(a*d),C[t+344>>2]=v(v(_*g)+v(h*m))+v(d*y),C[t+340>>2]=v(v(_*i)+v(h*n))+v(d*o),_=e,e=v(i*p),h=r,r=v(n*R),d=a,a=v(o*D),C[t+332>>2]=v(v(_*e)+v(h*r))+v(d*a),C[t+328>>2]=v(v(e*g)+v(r*m))+v(a*y),C[t+324>>2]=v(v(e*i)+v(r*n))+v(a*o)})(t|=0)},btRigidBody_getLinearVelocity:function(t){return(t|=0)+372|0},btRigidBody_getAngularVelocity:function(t){return(t|=0)+388|0},btRigidBody_setLinearVelocity:function(t,e){e|=0;var i=0;f[(t|=0)+304>>2]=f[t+304>>2]+1,i=f[e+4>>2],f[t+372>>2]=f[e>>2],f[t+376>>2]=i,i=f[(e=e+8|0)+4>>2],f[(t=t+380|0)>>2]=f[e>>2],f[t+4>>2]=i},btRigidBody_setAngularVelocity:function(t,e){e|=0;var i=0;f[(t|=0)+304>>2]=f[t+304>>2]+1,i=f[e+4>>2],f[t+388>>2]=f[e>>2],f[t+392>>2]=i,i=f[(e=e+8|0)+4>>2],f[(t=t+396|0)>>2]=f[e>>2],f[t+4>>2]=i},btRigidBody_setAngularFactor:function(t,e){e|=0;var i=0;f[(t|=0)+304>>2]=f[t+304>>2]+1,i=f[e+4>>2],f[t+604>>2]=f[e>>2],f[t+608>>2]=i,i=f[(e=e+8|0)+4>>2],f[(t=t+612|0)>>2]=f[e>>2],f[t+4>>2]=i},btRigidBody_getGravity:function(t){return(t|=0)+440|0},btRigidBody_setGravity:function(t,e){Si(t|=0,e|=0)},btRigidBody_getTotalForce:function(t){return(t|=0)+472|0},btRigidBody_getTotalTorque:function(t){return(t|=0)+488|0},btRigidBody_getFlags:function(t){return f[(t|=0)+564>>2]},btRigidBody_setFlags:function(t,e){e|=0,f[(t|=0)+564>>2]=e},btRigidBody_clearForces:function(t){var e=0;f[(t|=0)+472>>2]=0,f[t+476>>2]=0,f[(e=t+496|0)>>2]=0,f[e+4>>2]=0,f[(e=t+488|0)>>2]=0,f[e+4>>2]=0,f[(t=t+480|0)>>2]=0,f[t+4>>2]=0},btSequentialImpulseConstraintSolver_create:function(){var t;return Li(t=dA(236)),0|t},btCollisionWorld_get_m_useContinuous:function(t){return _[(t|=0)+16|0]},btCollisionWorld_set_m_useContinuous:function(t,e){e|=0,n[(t|=0)+16|0]=e},btCollisionWorld_rayTest:function(t,e,i,r){e|=0,i|=0,r|=0,yt[f[f[(t|=0)>>2]+32>>2]](t,e,i,r)},btCollisionWorld_getDispatchInfo:function(t){return(t|=0)+28|0},btCollisionWorld_addCollisionObject:function(t,e,i,r){e|=0,i|=0,r|=0,yt[f[f[(t|=0)>>2]+36>>2]](t,e,i,r)},btCollisionWorld_removeCollisionObject:function(t,e){e|=0,yt[f[f[(t|=0)>>2]+40>>2]](t,e)},btCollisionWorld_convexSweepTest:function(t,e,i,r,n,a){_f(t|=0,e|=0,i|=0,r|=0,n|=0,a=v(a))},btCollisionWorld_destroy:nt,btDynamicsWorld_addAction:Jf,btDynamicsWorld_removeAction:xf,btDynamicsWorld_getSolverInfo:function(t){return(t|=0)+92|0},btDiscreteDynamicsWorld_create:function(t,e,i,r){return t|=0,e|=0,i|=0,r|=0,function(t,e,i,r){var o;!function(t,e,i){f[t>>2]=20592,n[t+76|0]=1,f[t+72>>2]=0,f[t+68>>2]=i,f[t+28>>2]=0,f[t+32>>2]=0,f[t+24>>2]=e,n[t+20|0]=1,f[t+16>>2]=0,f[t- -64>>2]=0,n[t+60|0]=0,f[t+56>>2]=1025758986,n[t+54|0]=1,a[t+52>>1]=256,f[t+48>>2]=0,n[t+44|0]=1,f[(e=t+36|0)>>2]=1,f[e+4>>2]=1065353216,f[(t=t+8|0)>>2]=0,f[t+4>>2]=0}(t,e,i),f[(i=t+100|0)>>2]=1050253722,f[i+4>>2]=1015580809,f[t+92>>2]=1058642330,f[t+96>>2]=1065353216,f[t+88>>2]=0,f[t+80>>2]=0,f[t+84>>2]=0,f[(i=t+132|0)>>2]=0,f[i+4>>2]=1045220557,f[(i=t+124|0)>>2]=1045220557,f[i+4>>2]=1045220557,f[(i=t+108|0)>>2]=0,f[i+4>>2]=10,f[(i=t+184|0)>>2]=0,f[i+4>>2]=1045220557,f[(i=t+176|0)>>2]=1120403456,f[i+4>>2]=1900671690,f[t+172>>2]=128,f[(i=t+164|0)>>2]=260,f[i+4>>2]=2,f[(i=t+156|0)>>2]=0,f[i+4>>2]=1062836634,f[(i=t+148|0)>>2]=-1121724662,f[i+4>>2]=1036831949,f[(i=t+140|0)>>2]=0,f[i+4>>2]=1,f[(i=t+116|0)>>2]=1101004800,f[i+4>>2]=1065353216,f[t>>2]=23160,n[t+208|0]=1,f[t+204>>2]=0,n[t+240|0]=1,f[t+216>>2]=r,f[t+212>>2]=0,f[(i=t+196|0)>>2]=0,f[i+4>>2]=0,f[t+236>>2]=0,f[(i=t+228|0)>>2]=0,f[i+4>>2]=0,n[t+260|0]=1,a[t+290>>1]=0,f[t+256>>2]=0,f[(i=t+248|0)>>2]=0,f[i+4>>2]=0,f[t+264>>2]=0,f[t+268>>2]=-1054867456,f[(i=t+272|0)>>2]=0,f[i+4>>2]=0,f[(i=t+280|0)>>2]=0,f[i+4>>2]=0,n[t+308|0]=1,f[t+312>>2]=0,f[t+304>>2]=0,f[(i=t+296|0)>>2]=0,f[i+4>>2]=0,n[t+336|0]=1,n[t+316|0]=1,f[(i=t+324|0)>>2]=0,f[i+4>>2]=0,f[t+332>>2]=0,f[t+340>>2]=0,o=t,r?i=0:(Li(i=dA(236)),f[t+216>>2]=i,i=1),n[o+289|0]=i,function(t){var e=0;f[t>>2]=22908,f[(e=t+4|0)+12>>2]=0,n[e+16|0]=1,f[e+4>>2]=0,f[e+8>>2]=0,f[t+36>>2]=0,n[t+40|0]=1,n[t+60|0]=1,f[(e=t+28|0)>>2]=0,f[e+4>>2]=0,f[t+56>>2]=0,n[t+64|0]=1,f[(t=t+48|0)>>2]=0,f[t+4>>2]=0}(i=dA(68)),n[t+288|0]=1,f[t+220>>2]=i,i=dA(88),f[i+72>>2]=0,f[i+76>>2]=0,n[i+44|0]=1,f[i+24>>2]=e,f[i+20>>2]=0,f[i+12>>2]=0,f[i+16>>2]=0,f[i+4>>2]=0,f[i>>2]=23768,f[i+40>>2]=0,n[i+64|0]=1,f[i+32>>2]=0,f[i+36>>2]=0,f[i+60>>2]=0,n[i+84|0]=1,f[i+52>>2]=0,f[i+56>>2]=0,f[i+80>>2]=0,f[i+8>>2]=f[t+216>>2],f[t+212>>2]=i}(r=dA(344),t,e,i),0|r},btDiscreteDynamicsWorld_setGravity:function(t,e){e|=0,yt[f[f[(t|=0)>>2]+72>>2]](t,e)},btDiscreteDynamicsWorld_getGravity:function(t){var e,i;return Z=e=Z-16|0,yt[f[f[(t|=0)>>2]+76>>2]](e,t),i=f[(t=e+8|0)+4>>2],f[705]=f[t>>2],f[706]=i,t=f[e+4>>2],f[703]=f[e>>2],f[704]=t,Z=e+16|0,2812},btDiscreteDynamicsWorld_addRigidBody:function(t,e,i,r){e|=0,i|=0,r|=0,yt[f[f[(t|=0)>>2]+88>>2]](t,e,i,r)},btDiscreteDynamicsWorld_removeRigidBody:function(t,e){e|=0,yt[f[f[(t|=0)>>2]+92>>2]](t,e)},btDiscreteDynamicsWorld_stepSimulation:function(t,e,i,r){t|=0,e=v(e),i|=0,r=v(r),yt[f[f[t>>2]+52>>2]](t,e,i,r)},btDiscreteDynamicsWorld_clearForces:function(t){yt[f[f[(t|=0)>>2]+120>>2]](t)},btDiscreteDynamicsWorld_setApplySpeculativeContactRestitution:function(t,e){e|=0,n[(t|=0)+291|0]=e},btDiscreteDynamicsWorld_getApplySpeculativeContactRestitution:function(t){return _[(t|=0)+291|0]},btKinematicCharacterController_create:function(t,e,i,r){var o;return t|=0,e|=0,i=v(i),r|=0,function(t,e,i,r,o){var _,h=v(0),d=v(0),g=v(0),m=v(0),y=v(0);Z=_=Z-16|0,f[t>>2]=24116,f[t+272>>2]=0,f[t+276>>2]=0,f[t+256>>2]=0,f[t+260>>2]=0,f[t+8>>2]=e,f[t+68>>2]=0,f[t+72>>2]=0,f[t+64>>2]=1017370378,f[t+100>>2]=0,f[t+104>>2]=0,a[t+250>>1]=257,f[t+56>>2]=0,f[t+12>>2]=i,f[t+252>>2]=0,n[t+216|0]=1,f[t+212>>2]=0,f[(e=t+204|0)>>2]=0,f[e+4>>2]=0,f[(e=t+280|0)>>2]=1065353216,f[e+4>>2]=0,f[(e=t+264|0)>>2]=1065353216,f[e+4>>2]=0,f[(e=t+76|0)>>2]=0,f[e+4>>2]=0,f[(e=t+108|0)>>2]=0,f[e+4>>2]=0,f[t+52>>2]=1105933107,f[t+20>>2]=0,f[t+24>>2]=0,a[t+248>>1]=0,f[t+28>>2]=1113325568,f[t+32>>2]=1092616192,f[t+36>>2]=1092616192,f[t+148>>2]=0,n[t+289|0]=0,n[t+290|0]=0,f[t+16>>2]=1045220557,f[t+240>>2]=0,f[t+244>>2]=0,n[t+288|0]=1,d=C[o>>2],g=C[o+4>>2],h=C[o+8>>2],(m=v(v(v(d*d)+v(g*g))+v(h*h)))>v(0)?(y=h,h=v(v(1)/v(E(m))),m=v(v(y*h)*v(-29.399999618530273)),d=v(v(d*h)*v(-29.399999618530273)),g=v(v(g*h)*v(-29.399999618530273)),(h=v(v(m*m)+v(v(d*d)+v(g*g))))>v(0)&&(f[_+12>>2]=0,C[_+8>>2]=-m,C[_+4>>2]=-g,C[_>>2]=-d,Tf(t,_)),C[t+52>>2]=E(h)):Tf(t,o),f[t+44>>2]=1061752795,f[t+48>>2]=1060439283,C[t+60>>2]=r,Z=_+16|0}(o=dA(292),t,e,i,r),0|o},btKinematicCharacterController_setWalkDirection:function(t,e){e|=0,yt[f[f[(t|=0)>>2]+16>>2]](t,e)},btKinematicCharacterController_setFallSpeed:function(t,e){t|=0,e=v(e),C[t+28>>2]=e},btKinematicCharacterController_setJumpSpeed:function(t,e){t|=0,e=v(e),C[t+36>>2]=e,C[t+32>>2]=e},btKinematicCharacterController_setMaxSlope:function(t,e){t|=0,e=v(e);var i,r=v(0);C[t+44>>2]=e,i=t,r=Cr(e),C[i+48>>2]=r},btKinematicCharacterController_onGround:zf,btKinematicCharacterController_jump:function(t,e){e|=0,yt[f[f[(t|=0)>>2]+44>>2]](t,e)},btKinematicCharacterController_setGravity:function(t,e){(function(t,e){var i,r,n=v(0),a=v(0),o=v(0),_=v(0);Z=i=Z-16|0,r=t,n=C[e>>2],o=C[e+4>>2],_=C[e+8>>2],(a=v(v(v(n*n)+v(o*o))+v(_*_)))>v(0)&&(f[i+12>>2]=0,C[i+8>>2]=-_,C[i+4>>2]=-o,C[i>>2]=-n,Tf(t,i),n=C[e>>2],a=v(n*n),n=C[e+4>>2],a=v(a+v(n*n)),n=C[e+8>>2],a=v(a+v(n*n))),C[r+52>>2]=E(a),Z=i+16|0})(t|=0,e|=0)},btKinematicCharacterController_setUp:function(t,e){(function(t,e){var i,r=v(0),n=v(0),a=v(0),o=v(0),_=v(0),h=v(0);Z=i=Z-16|0,n=C[e>>2],a=C[e+4>>2],r=C[e+8>>2],(o=v(v(v(n*n)+v(a*a))+v(r*r)))>v(0)&&(_=C[t+52>>2])>v(0)?(h=r,r=v(v(1)/v(E(o))),o=v(-_),_=v(v(h*r)*o),n=v(v(n*r)*o),a=v(v(a*r)*o),(r=v(v(_*_)+v(v(n*n)+v(a*a))))>v(0)&&(f[i+12>>2]=0,C[i+8>>2]=-_,C[i+4>>2]=-a,C[i>>2]=-n,Tf(t,i)),C[t+52>>2]=E(r)):Tf(t,e),Z=i+16|0})(t|=0,e|=0)},btKinematicCharacterController_setStepHeight:function(t,e){t|=0,e=v(e),C[t+60>>2]=e},btKinematicCharacterController_destroy:nt,btPairCachingGhostObject_create:function(){var t;return function(t){var e=0;Ee(t),f[t+336>>2]=0,n[t+340|0]=1,f[(e=t+328|0)>>2]=0,f[e+4>>2]=0,f[t+252>>2]=4,f[t>>2]=24004,Ri(e=dA(72)),f[t+344>>2]=e}(t=dA(348)),0|t},btGhostPairCallback_create:function(){var t;return t=q(4),f[t>>2]=25228,0|t},btTypedConstraint_setEnabled:function(t,e){e|=0,n[(t|=0)+20|0]=e},btCollisionWorld_addConstraint:function(t,e,i){e|=0,i|=0,yt[f[f[(t|=0)>>2]+56>>2]](t,e,i)},btCollisionWorld_removeConstraint:vt,btJointFeedback_create:function(){var t,e=0;return t=dA(64),f[(e=t)>>2]=0,f[e+4>>2]=0,f[(e=e+56|0)>>2]=0,f[e+4>>2]=0,f[(e=t+48|0)>>2]=0,f[e+4>>2]=0,f[(e=t+40|0)>>2]=0,f[e+4>>2]=0,f[(e=t+32|0)>>2]=0,f[e+4>>2]=0,f[(e=t+24|0)>>2]=0,f[e+4>>2]=0,f[(e=t+16|0)>>2]=0,f[e+4>>2]=0,f[(e=t+8|0)>>2]=0,f[e+4>>2]=0,0|t},btJointFeedback_destroy:function(t){(t|=0)&&CA(t)},btTypedConstraint_setJointFeedback:function(t,e){e|=0,f[(t|=0)+44>>2]=e},btTypedConstraint_getJointFeedback:function(t){return f[(t|=0)+44>>2]},btTypedConstraint_enableFeedback:function(t,e){e|=0,n[(t|=0)+21|0]=e},btTypedConstraint_setParam:function(t,e,i,r){t|=0,e|=0,i|=0,r=v(r),yt[f[f[t>>2]+28>>2]](t,i,r,e)},btTypedConstraint_setOverrideNumSolverIterations:Gi,btTypedConstraint_destroy:nt,btJointFeedback_getAppliedForceBodyA:sA,btJointFeedback_getAppliedForceBodyB:ut,btJointFeedback_getAppliedTorqueBodyA:Qe,btFixedConstraint_create:function(t,e,i,r){var n;return t|=0,e|=0,i|=0,r|=0,function(t,e,i,r,n){Pf(t,e,i,r,n,0),f[t>>2]=24588,f[(e=t+1144|0)>>2]=0,f[e+4>>2]=0,f[(e=t+1056|0)>>2]=0,f[e+4>>2]=0,f[t+968>>2]=0,f[t+972>>2]=0,f[t+680>>2]=0,f[t+684>>2]=0,f[(e=t+688|0)>>2]=0,f[e+4>>2]=0,f[(e=t+696|0)>>2]=0,f[e+4>>2]=0,f[(t=t+704|0)>>2]=0,f[t+4>>2]=0}(n=dA(1460),t,i,e,r),0|n},btGeneric6DofSpring2Constraint_create:function(t,e,i,r,n){var a;return t|=0,e|=0,i|=0,r|=0,n|=0,t=Pf(a=dA(1460),t,i,e,r,n),f[a+24>>2]=80,yt[f[f[a>>2]+28>>2]](t,2,v(.800000011920929),0),yt[f[f[a>>2]+28>>2]](t,4,v(0),0),yt[f[f[a>>2]+28>>2]](t,2,v(.800000011920929),1),yt[f[f[a>>2]+28>>2]](t,4,v(0),1),yt[f[f[a>>2]+28>>2]](t,2,v(.800000011920929),2),yt[f[f[a>>2]+28>>2]](t,4,v(0),2),yt[f[f[a>>2]+28>>2]](t,2,v(.800000011920929),3),yt[f[f[a>>2]+28>>2]](t,4,v(0),3),yt[f[f[a>>2]+28>>2]](t,2,v(.800000011920929),4),yt[f[f[a>>2]+28>>2]](t,4,v(0),4),yt[f[f[a>>2]+28>>2]](t,2,v(.800000011920929),5),yt[f[f[a>>2]+28>>2]](t,4,v(0),5),0|a},btGeneric6DofSpring2Constraint_setAxis:function(t,e,i){(function(t,e,i){var r,n=v(0),a=v(0),o=v(0),_=v(0),h=v(0),d=v(0),g=v(0),m=v(0),y=v(0),p=v(0),R=v(0),D=v(0),B=v(0),F=v(0),V=v(0),G=v(0),w=v(0),Q=v(0),W=v(0),Y=v(0),Z=v(0);r=f[t+28>>2],D=C[r+20>>2],B=C[r+36>>2],F=C[r+40>>2],V=C[r+8>>2],G=C[r+24>>2],a=C[r+60>>2],_=C[r+44>>2],h=C[r+12>>2],o=C[r+52>>2],d=C[r+56>>2],g=C[r+28>>2],m=C[i+8>>2],y=C[i>>2],p=C[i+4>>2],R=C[e+8>>2],n=C[e>>2],w=C[e+4>>2],Q=C[r+4>>2],f[t+108>>2]=0,f[t+92>>2]=0,f[t+76>>2]=0,f[t+60>>2]=0,o=v(-o),C[t+104>>2]=v(v(v(h*v(0))+v(g*v(0)))+v(_*v(0)))+v(v(v(h*o)-v(g*d))-v(_*a)),C[t+100>>2]=v(v(v(V*v(0))+v(G*v(0)))+v(F*v(0)))+v(v(v(V*o)-v(G*d))-v(F*a)),C[t+96>>2]=v(v(v(Q*v(0))+v(D*v(0)))+v(B*v(0)))+v(v(v(Q*o)-v(D*d))-v(B*a)),o=n,n=v(v(1)/v(E(v(v(v(n*n)+v(w*w))+v(R*R))))),a=v(o*n),d=v(w*n),R=v(R*n),C[t+88>>2]=v(v(h*a)+v(g*d))+v(_*R),n=v(v(1)/v(E(v(v(v(y*y)+v(p*p))+v(m*m))))),y=v(y*n),p=v(p*n),m=v(m*n),C[t+84>>2]=v(v(h*y)+v(g*p))+v(_*m),C[t+72>>2]=v(v(a*V)+v(d*G))+v(R*F),C[t+68>>2]=v(v(y*V)+v(p*G))+v(m*F),C[t+56>>2]=v(v(Q*a)+v(d*D))+v(R*B),C[t+52>>2]=v(B*m)+v(v(Q*y)+v(D*p)),n=h,h=v(v(R*p)-v(d*m)),o=g,g=v(v(a*m)-v(R*y)),w=_,_=v(v(d*y)-v(a*p)),C[t+80>>2]=v(v(n*h)+v(o*g))+v(w*_),C[t- -64>>2]=v(_*F)+v(v(V*h)+v(G*g)),C[t+48>>2]=v(B*_)+v(v(Q*h)+v(D*g)),e=f[t+32>>2],W=C[e+60>>2],Z=C[e+52>>2],Y=C[e+56>>2],D=C[e+20>>2],B=C[e+36>>2],F=C[e+40>>2],V=C[e+8>>2],G=C[e+24>>2],Q=C[e+44>>2],n=C[e+12>>2],w=C[e+28>>2],o=C[e+4>>2],f[t+172>>2]=0,f[t+156>>2]=0,f[t+140>>2]=0,f[t+124>>2]=0,C[t+152>>2]=v(v(a*n)+v(d*w))+v(R*Q),C[t+148>>2]=v(v(y*n)+v(p*w))+v(m*Q),C[t+144>>2]=v(v(h*n)+v(g*w))+v(_*Q),C[t+136>>2]=v(v(a*V)+v(d*G))+v(R*F),C[t+132>>2]=v(v(y*V)+v(p*G))+v(m*F),C[t+128>>2]=v(v(h*V)+v(g*G))+v(_*F),C[t+120>>2]=v(v(a*o)+v(d*D))+v(R*B),C[t+116>>2]=v(v(y*o)+v(p*D))+v(m*B),C[t+112>>2]=v(v(h*o)+v(g*D))+v(_*B),a=v(-Z),C[t+168>>2]=v(v(v(n*v(0))+v(w*v(0)))+v(Q*v(0)))+v(v(v(n*a)-v(w*Y))-v(Q*W)),C[t+164>>2]=v(v(v(V*v(0))+v(G*v(0)))+v(F*v(0)))+v(v(v(V*a)-v(G*Y))-v(F*W)),C[t+160>>2]=v(v(v(o*v(0))+v(D*v(0)))+v(B*v(0)))+v(v(v(o*a)-v(D*Y))-v(B*W)),Kf(t,r+4|0,e+4|0)})(t|=0,e|=0,i|=0)},btGeneric6DofSpring2Constraint_setLimit:function(t,e,i,r){if(t|=0,e|=0,i=v(i),r=v(r),(0|e)<=2)return C[(t=(e<<2)+t|0)+696>>2]=r,void(C[t+680>>2]=i);(i=Wf(i))v(3.1415927410125732)&&(i=v(i+v(-6.2831854820251465))),(r=Wf(r))v(3.1415927410125732)&&(r=v(r+v(-6.2831854820251465))),t=m(e,88)+t|0,C[t+708>>2]=r,C[t+704>>2]=i},btGeneric6DofSpring2Constraint_enableSpring:function(t,e,i){(function(t,e,i){(0|e)<=2?n[798+(t+e|0)|0]=i:n[752+(m(e,88)+t|0)|0]=i})(t|=0,e|=0,i|=0)},btGeneric6DofSpring2Constraint_setBounce:function(t,e,i){(function(t,e,i){C[((0|e)<3?712+((e<<2)+t|0)|0:712+(m(e,88)+t|0)|0)>>2]=i})(t|=0,e|=0,i=v(i))},btGeneric6DofSpring2Constraint_setStiffness:function(t,e,i,r){(function(t,e,i,r){if((0|e)<=2)return n[156+((t=t+680|0)+e|0)|0]=r,void(C[140+(t+(e<<2)|0)>>2]=i);t=m(e,88)+t|0,n[t+760|0]=r,C[t+756>>2]=i})(t|=0,e|=0,i=v(i),r|=0)},btGeneric6DofSpring2Constraint_setDamping:function(t,e,i,r){(function(t,e,i,r){if((0|e)<=2)return n[176+((t=t+680|0)+e|0)|0]=r,void(C[160+(t+(e<<2)|0)>>2]=i);t=m(e,88)+t|0,n[t+768|0]=r,C[t+764>>2]=i})(t|=0,e|=0,i=v(i),r|=0)},btGeneric6DofSpring2Constraint_setEquilibriumPoint:function(t,e,i){(function(t,e,i){C[((0|e)<3?860+((e<<2)+t|0)|0:772+(m(e,88)+t|0)|0)>>2]=i})(t|=0,e|=0,i=v(i))},btGeneric6DofSpring2Constraint_enableMotor:function(t,e,i){(function(t,e,i){(0|e)<=2?n[792+(t+e|0)|0]=i:n[732+(m(e,88)+t|0)|0]=i})(t|=0,e|=0,i|=0)},btGeneric6DofSpring2Constraint_setServo:function(t,e,i){(function(t,e,i){(0|e)<=2?n[795+(t+e|0)|0]=i:n[744+(m(e,88)+t|0)|0]=i})(t|=0,e|=0,i|=0)},btGeneric6DofSpring2Constraint_setTargetVelocity:function(t,e,i){(function(t,e,i){C[((0|e)<3?876+((e<<2)+t|0)|0:736+(m(e,88)+t|0)|0)>>2]=i})(t|=0,e|=0,i=v(i))},btGeneric6DofSpring2Constraint_setServoTarget:function(t,e,i){(function(t,e,i){var r=v(0);(0|e)<=2?C[804+((e<<2)+t|0)>>2]=i:(t=748+(m(e,88)+t|0)|0,i=v(i+v(3.1415927410125732)),i=v(i-v(v(B(v(i/v(6.2831854820251465))))*v(6.2831854820251465))),r=v(0),i>=v(6.2831854820251465)||(r=i,i>2]=r+v(-3.1415927410125732))})(t|=0,e|=0,i=v(i))},btGeneric6DofSpring2Constraint_setMaxMotorForce:function(t,e,i){(function(t,e,i){C[((0|e)<3?892+((e<<2)+t|0)|0:740+(m(e,88)+t|0)|0)>>2]=i})(t|=0,e|=0,i=v(i))},btGeneric6DofSpring2Constraint_setFrames:function(t,e,i){(function(t,e,i){var r=0,n=0,a=0;r=f[e+4>>2],f[t+48>>2]=f[e>>2],f[t+52>>2]=r,a=f[(n=e+8|0)+4>>2],f[(r=t+56|0)>>2]=f[n>>2],f[r+4>>2]=a,a=f[(n=e+24|0)+4>>2],f[(r=t+72|0)>>2]=f[n>>2],f[r+4>>2]=a,n=f[e+20>>2],f[(r=t- -64|0)>>2]=f[e+16>>2],f[r+4>>2]=n,a=f[(n=e+40|0)+4>>2],f[(r=t+88|0)>>2]=f[n>>2],f[r+4>>2]=a,n=f[e+36>>2],f[(r=t+80|0)>>2]=f[e+32>>2],f[r+4>>2]=n,a=f[(n=e+56|0)+4>>2],f[(r=t+104|0)>>2]=f[n>>2],f[r+4>>2]=a,n=f[e+52>>2],f[(r=t+96|0)>>2]=f[e+48>>2],f[r+4>>2]=n,n=f[(r=i+8|0)+4>>2],f[(e=t+120|0)>>2]=f[r>>2],f[e+4>>2]=n,e=f[i+4>>2],f[t+112>>2]=f[i>>2],f[t+116>>2]=e,r=f[i+20>>2],f[(e=t+128|0)>>2]=f[i+16>>2],f[e+4>>2]=r,n=f[(r=i+24|0)+4>>2],f[(e=t+136|0)>>2]=f[r>>2],f[e+4>>2]=n,r=f[i+36>>2],f[(e=t+144|0)>>2]=f[i+32>>2],f[e+4>>2]=r,n=f[(r=i+40|0)+4>>2],f[(e=t+152|0)>>2]=f[r>>2],f[e+4>>2]=n,n=f[(r=i+56|0)+4>>2],f[(e=t+168|0)>>2]=f[r>>2],f[e+4>>2]=n,r=f[i+52>>2],f[(e=t+160|0)>>2]=f[i+48>>2],f[e+4>>2]=r,yt[f[f[t>>2]+8>>2]](t),Kf(t,f[t+28>>2]+4|0,f[t+32>>2]+4|0)})(t|=0,e|=0,i|=0)}}}({Math:Math,Int8Array:Int8Array,Uint8Array:Uint8Array,Int16Array:Int16Array,Uint16Array:Uint16Array,Int32Array:Int32Array,Uint32Array:Uint32Array,Float32Array:Float32Array,Float64Array:Float64Array,NaN:NaN,Infinity:1/0},{memory:{},abort:function(){throw new Error("abort")},fd_close:()=>{console.log("fd_close")},fd_write:()=>{console.log("fd_write")},getWorldTransform:r,setWorldTransform:n,fd_seek:()=>{console.log("fd_seek")}},h);i.btGImpactCollisionAlgorithm_RegisterAlgorithm=C.btGImpactCollisionAlgorithm_RegisterAlgorithm,i.btVector3_create=C.btVector3_create,i.btVector3_setValue=C.btVector3_setValue,i.btVector3_x=C.btVector3_x,i.btVector3_y=C.btVector3_y,i.btVector3_z=C.btVector3_z,i.btQuaternion_create=C.btQuaternion_create,i.btQuaternion_setValue=C.btQuaternion_setValue,i.btQuaternion_x=C.btQuaternion_x,i.btQuaternion_y=C.btQuaternion_y,i.btQuaternion_z=C.btQuaternion_z,i.btQuaternion_w=C.btQuaternion_w,i.btTransform_create=C.btTransform_create,i.btTransform_setOrigin=C.btTransform_setOrigin,i.btTransform_setRotation=C.btTransform_setRotation,i.btTransform_getOrigin=C.btTransform_getOrigin,i.btTransform_getRotation=C.btTransform_getRotation,i.btTransform_setIdentity=C.btTransform_setIdentity,i.btTransform_equal=C.btTransform_equal,i.btMotionState_destroy=C.btMotionState_destroy,i.layaMotionState_create=C.layaMotionState_create,i.layaMotionState_set_rigidBodyID=C.layaMotionState_set_rigidBodyID,i.btCollisionObject_create=C.btCollisionObject_create,i.btCollisionObject_setContactProcessingThreshold=C.btCollisionObject_setContactProcessingThreshold,i.btCollisionObject_setActivationState=C.btCollisionObject_setActivationState,i.btCollisionObject_forceActivationState=C.btCollisionObject_forceActivationState,i.btCollisionObject_activate=C.btCollisionObject_activate,i.btCollisionObject_isActive=C.btCollisionObject_isActive,i.btCollisionObject_setRestitution=C.btCollisionObject_setRestitution,i.btCollisionObject_setFriction=C.btCollisionObject_setFriction,i.btCollisionObject_setRollingFriction=C.btCollisionObject_setRollingFriction,i.btCollisionObject_getCollisionFlags=C.btCollisionObject_getCollisionFlags,i.btCollisionObject_setCollisionFlags=C.btCollisionObject_setCollisionFlags,i.btCollisionObject_getWorldTransform=C.btCollisionObject_getWorldTransform,i.btCollisionObject_setWorldTransform=C.btCollisionObject_setWorldTransform,i.btCollisionObject_setInterpolationWorldTransform=C.btCollisionObject_setInterpolationWorldTransform,i.btCollisionObject_setCollisionShape=C.btCollisionObject_setCollisionShape,i.btCollisionObject_getCcdMotionThreshold=C.btCollisionObject_getCcdMotionThreshold,i.btCollisionObject_setCcdMotionThreshold=C.btCollisionObject_setCcdMotionThreshold,i.btCollisionObject_getCcdSweptSphereRadius=C.btCollisionObject_getCcdSweptSphereRadius,i.btCollisionObject_setCcdSweptSphereRadius=C.btCollisionObject_setCcdSweptSphereRadius,i.btCollisionObject_getUserIndex=C.btCollisionObject_getUserIndex,i.btCollisionObject_setUserIndex=C.btCollisionObject_setUserIndex,i.btCollisionObject_getActivationState=C.btCollisionObject_getActivationState,i.btCollisionObject_setInterpolationAngularVelocity=C.btCollisionObject_setInterpolationAngularVelocity,i.btCollisionObject_setInterpolationLinearVelocity=C.btCollisionObject_setInterpolationLinearVelocity,i.btCollisionObject_destroy=C.btCollisionObject_destroy,i.RayResultCallback_set_m_flags=C.RayResultCallback_set_m_flags,i.RayResultCallback_hasHit=C.RayResultCallback_hasHit,i.RayResultCallback_set_m_collisionFilterGroup=C.RayResultCallback_set_m_collisionFilterGroup,i.RayResultCallback_set_m_collisionFilterMask=C.RayResultCallback_set_m_collisionFilterMask,i.RayResultCallback_get_m_closestHitFraction=C.RayResultCallback_get_m_closestHitFraction,i.RayResultCallback_set_m_closestHitFraction=C.RayResultCallback_set_m_closestHitFraction,i.RayResultCallback_get_m_collisionObject=C.RayResultCallback_get_m_collisionObject,i.RayResultCallback_set_m_collisionObject=C.RayResultCallback_set_m_collisionObject,i.ClosestRayResultCallback_create=C.ClosestRayResultCallback_create,i.ClosestRayResultCallback_get_m_rayFromWorld=C.ClosestRayResultCallback_get_m_rayFromWorld,i.ClosestRayResultCallback_set_m_rayFromWorld=C.ClosestRayResultCallback_set_m_rayFromWorld,i.ClosestRayResultCallback_get_m_rayToWorld=C.ClosestRayResultCallback_get_m_rayToWorld,i.ClosestRayResultCallback_set_m_rayToWorld=C.ClosestRayResultCallback_set_m_rayToWorld,i.ClosestRayResultCallback_get_m_hitNormalWorld=C.ClosestRayResultCallback_get_m_hitNormalWorld,i.ClosestRayResultCallback_get_m_hitPointWorld=C.ClosestRayResultCallback_get_m_hitPointWorld,i.tBtCollisionObjectArray_size=C.tBtCollisionObjectArray_size,i.tBtCollisionObjectArray_at=C.tBtCollisionObjectArray_at,i.tBtCollisionObjectArray_clear=C.tBtCollisionObjectArray_clear,i.tVector3Array_at=C.tVector3Array_at,i.tVector3Array_clear=C.tVector3Array_clear,i.tScalarArray_at=C.tScalarArray_at,i.tScalarArray_clear=C.tScalarArray_clear,i.AllHitsRayResultCallback_create=C.AllHitsRayResultCallback_create,i.AllHitsRayResultCallback_get_m_rayFromWorld=C.AllHitsRayResultCallback_get_m_rayFromWorld,i.AllHitsRayResultCallback_set_m_rayFromWorld=C.AllHitsRayResultCallback_set_m_rayFromWorld,i.AllHitsRayResultCallback_get_m_rayToWorld=C.AllHitsRayResultCallback_get_m_rayToWorld,i.AllHitsRayResultCallback_set_m_rayToWorld=C.AllHitsRayResultCallback_set_m_rayToWorld,i.AllHitsRayResultCallback_get_m_hitPointWorld=C.AllHitsRayResultCallback_get_m_hitPointWorld,i.AllHitsRayResultCallback_get_m_hitNormalWorld=C.AllHitsRayResultCallback_get_m_hitNormalWorld,i.AllHitsRayResultCallback_get_m_collisionObjects=C.AllHitsRayResultCallback_get_m_collisionObjects,i.AllHitsRayResultCallback_get_m_hitFractions=C.AllHitsRayResultCallback_get_m_hitFractions,i.btManifoldPoint_get_m_positionWorldOnA=C.btManifoldPoint_get_m_positionWorldOnA,i.btManifoldPoint_get_m_positionWorldOnB=C.btManifoldPoint_get_m_positionWorldOnB,i.btManifoldPoint_get_m_normalWorldOnB=C.btManifoldPoint_get_m_normalWorldOnB,i.btManifoldPoint_getDistance=C.btManifoldPoint_getDistance,i.ConvexResultCallback_hasHit=C.ConvexResultCallback_hasHit,i.ConvexResultCallback_set_m_collisionFilterGroup=C.ConvexResultCallback_set_m_collisionFilterGroup,i.ConvexResultCallback_set_m_collisionFilterMask=C.ConvexResultCallback_set_m_collisionFilterMask,i.ConvexResultCallback_get_m_closestHitFraction=C.ConvexResultCallback_get_m_closestHitFraction,i.ConvexResultCallback_set_m_closestHitFraction=C.ConvexResultCallback_set_m_closestHitFraction,i.ClosestConvexResultCallback_create=C.ClosestConvexResultCallback_create,i.ClosestConvexResultCallback_get_m_hitNormalWorld=C.ClosestConvexResultCallback_get_m_hitNormalWorld,i.ClosestConvexResultCallback_get_m_hitPointWorld=C.ClosestConvexResultCallback_get_m_hitPointWorld,i.ClosestConvexResultCallback_get_m_hitCollisionObject=C.ClosestConvexResultCallback_get_m_hitCollisionObject,i.ClosestConvexResultCallback_set_m_hitCollisionObject=C.ClosestConvexResultCallback_set_m_hitCollisionObject,i.AllConvexResultCallback_create=C.AllConvexResultCallback_create,i.AllConvexResultCallback_get_m_hitNormalWorld=C.AllConvexResultCallback_get_m_hitNormalWorld,i.AllConvexResultCallback_get_m_hitPointWorld=C.AllConvexResultCallback_get_m_hitPointWorld,i.AllConvexResultCallback_get_m_hitFractions=C.AllConvexResultCallback_get_m_hitFractions,i.AllConvexResultCallback_get_m_collisionObjects=C.AllConvexResultCallback_get_m_collisionObjects,i.btCollisionShape_getLocalScaling=C.btCollisionShape_getLocalScaling,i.btCollisionShape_setLocalScaling=C.btCollisionShape_setLocalScaling,i.btCollisionShape_calculateLocalInertia=C.btCollisionShape_calculateLocalInertia,i.btCollisionShape_destroy=C.btCollisionShape_destroy,i.btBoxShape_create=C.btBoxShape_create,i.btCapsuleShape_create=C.btCapsuleShape_create,i.btCapsuleShapeX_create=C.btCapsuleShapeX_create,i.btCapsuleShapeZ_create=C.btCapsuleShapeZ_create,i.btCylinderShape_create=C.btCylinderShape_create,i.btCylinderShapeX_create=C.btCylinderShapeX_create,i.btCylinderShapeZ_create=C.btCylinderShapeZ_create,i.btSphereShape_create=C.btSphereShape_create,i.btConeShape_create=C.btConeShape_create,i.btConeShapeX_create=C.btConeShapeX_create,i.btConeShapeZ_create=C.btConeShapeZ_create,i.btStaticPlaneShape_create=C.btStaticPlaneShape_create,i.btGImpactShapeInterface_updateBound=C.btGImpactShapeInterface_updateBound,i.btGImpactMeshShape_create=C.btGImpactMeshShape_create,i.btCompoundShape_create=C.btCompoundShape_create,i.btCompoundShape_addChildShape=C.btCompoundShape_addChildShape,i.btCompoundShape_removeChildShapeByIndex=C.btCompoundShape_removeChildShapeByIndex,i.btCompoundShape_getChildShape=C.btCompoundShape_getChildShape,i.btCompoundShape_updateChildTransform=C.btCompoundShape_updateChildTransform,i.btStridingMeshInterface_destroy=C.btStridingMeshInterface_destroy,i.btTriangleMesh_create=C.btTriangleMesh_create,i.btTriangleMesh_addTriangle=C.btTriangleMesh_addTriangle,i.btDefaultCollisionConfiguration_create=C.btDefaultCollisionConfiguration_create,i.btDefaultCollisionConfiguration_destroy=C.btDefaultCollisionConfiguration_destroy,i.btPersistentManifold_getBody0=C.btPersistentManifold_getBody0,i.btPersistentManifold_getBody1=C.btPersistentManifold_getBody1,i.btPersistentManifold_getNumContacts=C.btPersistentManifold_getNumContacts,i.btPersistentManifold_getContactPoint=C.btPersistentManifold_getContactPoint,i.btDispatcher_getNumManifolds=C.btDispatcher_getNumManifolds,i.btDispatcher_getManifoldByIndexInternal=C.btDispatcher_getManifoldByIndexInternal,i.btCollisionDispatcher_create=C.btCollisionDispatcher_create,i.btCollisionDispatcher_destroy=C.btCollisionDispatcher_destroy,i.btOverlappingPairCache_setInternalGhostPairCallback=C.btOverlappingPairCache_setInternalGhostPairCallback,i.btDbvtBroadphase_create=C.btDbvtBroadphase_create,i.btDbvtBroadphase_getOverlappingPairCache=C.btDbvtBroadphase_getOverlappingPairCache,i.btDbvtBroadphase_destroy=C.btDbvtBroadphase_destroy,i.btRigidBodyConstructionInfo_create=C.btRigidBodyConstructionInfo_create,i.btRigidBodyConstructionInfo_destroy=C.btRigidBodyConstructionInfo_destroy,i.btRigidBody_create=C.btRigidBody_create,i.btRigidBody_setCenterOfMassTransform=C.btRigidBody_setCenterOfMassTransform,i.btRigidBody_setSleepingThresholds=C.btRigidBody_setSleepingThresholds,i.btRigidBody_getLinearSleepingThreshold=C.btRigidBody_getLinearSleepingThreshold,i.btRigidBody_getAngularSleepingThreshold=C.btRigidBody_getAngularSleepingThreshold,i.btRigidBody_setDamping=C.btRigidBody_setDamping,i.btRigidBody_setMassProps=C.btRigidBody_setMassProps,i.btRigidBody_setLinearFactor=C.btRigidBody_setLinearFactor,i.btRigidBody_applyTorque=C.btRigidBody_applyTorque,i.btRigidBody_applyForce=C.btRigidBody_applyForce,i.btRigidBody_applyCentralForce=C.btRigidBody_applyCentralForce,i.btRigidBody_applyTorqueImpulse=C.btRigidBody_applyTorqueImpulse,i.btRigidBody_applyImpulse=C.btRigidBody_applyImpulse,i.btRigidBody_applyCentralImpulse=C.btRigidBody_applyCentralImpulse,i.btRigidBody_updateInertiaTensor=C.btRigidBody_updateInertiaTensor,i.btRigidBody_getLinearVelocity=C.btRigidBody_getLinearVelocity,i.btRigidBody_getAngularVelocity=C.btRigidBody_getAngularVelocity,i.btRigidBody_setLinearVelocity=C.btRigidBody_setLinearVelocity,i.btRigidBody_setAngularVelocity=C.btRigidBody_setAngularVelocity,i.btRigidBody_setAngularFactor=C.btRigidBody_setAngularFactor,i.btRigidBody_getGravity=C.btRigidBody_getGravity,i.btRigidBody_setGravity=C.btRigidBody_setGravity,i.btRigidBody_getTotalForce=C.btRigidBody_getTotalForce,i.btRigidBody_getTotalTorque=C.btRigidBody_getTotalTorque,i.btRigidBody_getFlags=C.btRigidBody_getFlags,i.btRigidBody_setFlags=C.btRigidBody_setFlags,i.btRigidBody_clearForces=C.btRigidBody_clearForces,i.btSequentialImpulseConstraintSolver_create=C.btSequentialImpulseConstraintSolver_create,i.btCollisionWorld_get_m_useContinuous=C.btCollisionWorld_get_m_useContinuous,i.btCollisionWorld_set_m_useContinuous=C.btCollisionWorld_set_m_useContinuous,i.btCollisionWorld_rayTest=C.btCollisionWorld_rayTest,i.btCollisionWorld_getDispatchInfo=C.btCollisionWorld_getDispatchInfo,i.btCollisionWorld_addCollisionObject=C.btCollisionWorld_addCollisionObject,i.btCollisionWorld_removeCollisionObject=C.btCollisionWorld_removeCollisionObject,i.btCollisionWorld_convexSweepTest=C.btCollisionWorld_convexSweepTest,i.btCollisionWorld_destroy=C.btCollisionWorld_destroy,i.btDynamicsWorld_addAction=C.btDynamicsWorld_addAction,i.btDynamicsWorld_removeAction=C.btDynamicsWorld_removeAction,i.btDynamicsWorld_getSolverInfo=C.btDynamicsWorld_getSolverInfo,i.btDiscreteDynamicsWorld_create=C.btDiscreteDynamicsWorld_create,i.btDiscreteDynamicsWorld_setGravity=C.btDiscreteDynamicsWorld_setGravity,i.btDiscreteDynamicsWorld_getGravity=C.btDiscreteDynamicsWorld_getGravity,i.btDiscreteDynamicsWorld_addRigidBody=C.btDiscreteDynamicsWorld_addRigidBody,i.btDiscreteDynamicsWorld_removeRigidBody=C.btDiscreteDynamicsWorld_removeRigidBody,i.btDiscreteDynamicsWorld_stepSimulation=C.btDiscreteDynamicsWorld_stepSimulation,i.btDiscreteDynamicsWorld_clearForces=C.btDiscreteDynamicsWorld_clearForces,i.btDiscreteDynamicsWorld_setApplySpeculativeContactRestitution=C.btDiscreteDynamicsWorld_setApplySpeculativeContactRestitution,i.btDiscreteDynamicsWorld_getApplySpeculativeContactRestitution=C.btDiscreteDynamicsWorld_getApplySpeculativeContactRestitution,i.btKinematicCharacterController_create=C.btKinematicCharacterController_create,i.btKinematicCharacterController_setWalkDirection=C.btKinematicCharacterController_setWalkDirection,i.btKinematicCharacterController_setFallSpeed=C.btKinematicCharacterController_setFallSpeed,i.btKinematicCharacterController_setJumpSpeed=C.btKinematicCharacterController_setJumpSpeed,i.btKinematicCharacterController_setMaxSlope=C.btKinematicCharacterController_setMaxSlope,i.btKinematicCharacterController_onGround=C.btKinematicCharacterController_onGround,i.btKinematicCharacterController_jump=C.btKinematicCharacterController_jump,i.btKinematicCharacterController_setGravity=C.btKinematicCharacterController_setGravity,i.btKinematicCharacterController_setUp=C.btKinematicCharacterController_setUp,i.btKinematicCharacterController_setStepHeight=C.btKinematicCharacterController_setStepHeight,i.btKinematicCharacterController_destroy=C.btKinematicCharacterController_destroy,i.btPairCachingGhostObject_create=C.btPairCachingGhostObject_create,i.btGhostPairCallback_create=C.btGhostPairCallback_create,i.btTypedConstraint_setEnabled=C.btTypedConstraint_setEnabled,i.btCollisionWorld_addConstraint=C.btCollisionWorld_addConstraint,i.btCollisionWorld_removeConstraint=C.btCollisionWorld_removeConstraint,i.btJointFeedback_create=C.btJointFeedback_create,i.btJointFeedback_destroy=C.btJointFeedback_destroy,i.btTypedConstraint_setJointFeedback=C.btTypedConstraint_setJointFeedback,i.btTypedConstraint_getJointFeedback=C.btTypedConstraint_getJointFeedback,i.btTypedConstraint_enableFeedback=C.btTypedConstraint_enableFeedback,i.btTypedConstraint_setParam=C.btTypedConstraint_setParam,i.btTypedConstraint_setOverrideNumSolverIterations=C.btTypedConstraint_setOverrideNumSolverIterations,i.btTypedConstraint_destroy=C.btTypedConstraint_destroy,i.btJointFeedback_getAppliedForceBodyA=C.btJointFeedback_getAppliedForceBodyA,i.btJointFeedback_getAppliedForceBodyB=C.btJointFeedback_getAppliedForceBodyB,i.btJointFeedback_getAppliedTorqueBodyA=C.btJointFeedback_getAppliedTorqueBodyA,i.btFixedConstraint_create=C.btFixedConstraint_create,i.btGeneric6DofSpring2Constraint_create=C.btGeneric6DofSpring2Constraint_create,i.btGeneric6DofSpring2Constraint_setAxis=C.btGeneric6DofSpring2Constraint_setAxis,i.btGeneric6DofSpring2Constraint_setLimit=C.btGeneric6DofSpring2Constraint_setLimit,i.btGeneric6DofSpring2Constraint_enableSpring=C.btGeneric6DofSpring2Constraint_enableSpring,i.btGeneric6DofSpring2Constraint_setBounce=C.btGeneric6DofSpring2Constraint_setBounce,i.btGeneric6DofSpring2Constraint_setStiffness=C.btGeneric6DofSpring2Constraint_setStiffness,i.btGeneric6DofSpring2Constraint_setDamping=C.btGeneric6DofSpring2Constraint_setDamping,i.btGeneric6DofSpring2Constraint_setEquilibriumPoint=C.btGeneric6DofSpring2Constraint_setEquilibriumPoint,i.btGeneric6DofSpring2Constraint_enableMotor=C.btGeneric6DofSpring2Constraint_enableMotor,i.btGeneric6DofSpring2Constraint_setServo=C.btGeneric6DofSpring2Constraint_setServo,i.btGeneric6DofSpring2Constraint_setTargetVelocity=C.btGeneric6DofSpring2Constraint_setTargetVelocity,i.btGeneric6DofSpring2Constraint_setServoTarget=C.btGeneric6DofSpring2Constraint_setServoTarget,i.btGeneric6DofSpring2Constraint_setMaxMotorForce=C.btGeneric6DofSpring2Constraint_setMaxMotorForce,i.btGeneric6DofSpring2Constraint_setFrames=C.btGeneric6DofSpring2Constraint_setFrames}(64*t*1024,e,i),i},function(t,e){"use strict";class i{constructor(){this._scale=new e.Vector3(1,1,1),this._centerMatrix=new e.Matrix4x4,this._attatched=!1,this._indexInCompound=-1,this._compoundParent=null,this._attatchedCollisionObject=null,this._referenceCount=0,this._localOffset=new e.Vector3(0,0,0),this._localRotation=new e.Quaternion(0,0,0,1),this.needsCustomCollisionCallback=!1}static __init__(){var t=e.ILaya3D.Physics3D._bullet;i._btScale=t.btVector3_create(1,1,1),i._btVector30=t.btVector3_create(0,0,0),i._btQuaternion0=t.btQuaternion_create(0,0,0,1),i._btTransform0=t.btTransform_create()}static _createAffineTransformation(t,e,i){var r=e.x,n=e.y,a=e.z,o=e.w,f=r+r,_=n+n,h=a+a,d=r*f,C=r*_,g=r*h,m=n*_,v=n*h,y=a*h,p=o*f,R=o*_,D=o*h;i[0]=1-(m+y),i[1]=C+D,i[2]=g-R,i[3]=0,i[4]=C-D,i[5]=1-(d+y),i[6]=v+p,i[7]=0,i[8]=g+R,i[9]=v-p,i[10]=1-(d+m),i[11]=0,i[12]=t.x,i[13]=t.y,i[14]=t.z,i[15]=1}get type(){return this._type}get localOffset(){return this._localOffset}set localOffset(t){this._localOffset=t,this._compoundParent&&this._compoundParent._updateChildTransform(this)}get localRotation(){return this._localRotation}set localRotation(t){this._localRotation=t,this._compoundParent&&this._compoundParent._updateChildTransform(this)}_setScale(t){if(this._compoundParent)this.updateLocalTransformations();else{var r=e.ILaya3D.Physics3D._bullet;r.btVector3_setValue(i._btScale,t.x,t.y,t.z),r.btCollisionShape_setLocalScaling(this._btShape,i._btScale)}}_addReference(){this._referenceCount++}_removeReference(){this._referenceCount--}updateLocalTransformations(){if(this._compoundParent){var t=i._tempVector30;e.Vector3.multiply(this.localOffset,this._scale,t),i._createAffineTransformation(t,this.localRotation,this._centerMatrix.elements)}else i._createAffineTransformation(this.localOffset,this.localRotation,this._centerMatrix.elements)}cloneTo(t){var e=t;this._localOffset.cloneTo(e.localOffset),this._localRotation.cloneTo(e.localRotation),e.localOffset=e.localOffset,e.localRotation=e.localRotation}clone(){return null}destroy(){this._btShape&&(e.ILaya3D.Physics3D._bullet.btCollisionShape_destroy(this._btShape),this._btShape=null)}}i.SHAPEORIENTATION_UPX=0,i.SHAPEORIENTATION_UPY=1,i.SHAPEORIENTATION_UPZ=2,i.SHAPETYPES_BOX=0,i.SHAPETYPES_SPHERE=1,i.SHAPETYPES_CYLINDER=2,i.SHAPETYPES_CAPSULE=3,i.SHAPETYPES_CONVEXHULL=4,i.SHAPETYPES_COMPOUND=5,i.SHAPETYPES_STATICPLANE=6,i.SHAPETYPES_CONE=7,i._tempVector30=new e.Vector3;class r extends i{constructor(t=1,n=1,a=1){super(),this._sizeX=t,this._sizeY=n,this._sizeZ=a,this._type=i.SHAPETYPES_BOX;var o=e.ILaya3D.Physics3D._bullet;o.btVector3_setValue(r._btSize,t/2,n/2,a/2),this._btShape=o.btBoxShape_create(r._btSize)}static __init__(){r._btSize=e.ILaya3D.Physics3D._bullet.btVector3_create(0,0,0)}get sizeX(){return this._sizeX}get sizeY(){return this._sizeY}get sizeZ(){return this._sizeZ}clone(){var t=new r(this._sizeX,this._sizeY,this._sizeZ);return this.cloneTo(t),t}}class n extends i{constructor(t=.5,r=1.25,n=i.SHAPEORIENTATION_UPY){super(),this._radius=t,this._length=r,this._orientation=n,this._type=i.SHAPETYPES_CAPSULE;var a=e.ILaya3D.Physics3D._bullet;switch(n){case i.SHAPEORIENTATION_UPX:this._btShape=a.btCapsuleShapeX_create(t,r-2*t);break;case i.SHAPEORIENTATION_UPY:this._btShape=a.btCapsuleShape_create(t,r-2*t);break;case i.SHAPEORIENTATION_UPZ:this._btShape=a.btCapsuleShapeZ_create(t,r-2*t);break;default:throw"CapsuleColliderShape:unknown orientation."}}get radius(){return this._radius}get length(){return this._length}get orientation(){return this._orientation}_setScale(t){var e=n._tempVector30;switch(this.orientation){case i.SHAPEORIENTATION_UPX:e.x=t.x,e.y=e.z=Math.max(t.y,t.z);break;case i.SHAPEORIENTATION_UPY:e.y=t.y,e.x=e.z=Math.max(t.x,t.z);break;case i.SHAPEORIENTATION_UPZ:e.z=t.z,e.x=e.y=Math.max(t.x,t.y);break;default:throw"CapsuleColliderShape:unknown orientation."}super._setScale(e)}clone(){var t=new n(this._radius,this._length,this._orientation);return this.cloneTo(t),t}}n._tempVector30=new e.Vector3;class a extends i{constructor(){super(),this._childColliderShapes=[],this._type=i.SHAPETYPES_COMPOUND,this._btShape=e.ILaya3D.Physics3D._bullet.btCompoundShape_create()}static __init__(){var t=e.ILaya3D.Physics3D._bullet;a._btVector3One=t.btVector3_create(1,1,1),a._btTransform=t.btTransform_create(),a._btOffset=t.btVector3_create(0,0,0),a._btRotation=t.btQuaternion_create(0,0,0,1)}_clearChildShape(t){t._attatched=!1,t._compoundParent=null,t._indexInCompound=-1}_addReference(){}_removeReference(){}_updateChildTransform(t){var r=e.ILaya3D.Physics3D._bullet,n=t.localOffset,a=t.localRotation,o=i._btVector30,f=i._btQuaternion0,_=i._btTransform0;r.btVector3_setValue(o,-n.x,n.y,n.z),r.btQuaternion_setValue(f,-a.x,a.y,a.z,-a.w),r.btTransform_setOrigin(_,o),r.btTransform_setRotation(_,f),r.btCompoundShape_updateChildTransform(this._btShape,t._indexInCompound,_,!0)}addChildShape(t){if(t._attatched)throw"CompoundColliderShape: this shape has attatched to other entity.";t._attatched=!0,t._compoundParent=this,t._indexInCompound=this._childColliderShapes.length,this._childColliderShapes.push(t);var i=t.localOffset,r=t.localRotation,n=e.ILaya3D.Physics3D._bullet;n.btVector3_setValue(a._btOffset,-i.x,i.y,i.z),n.btQuaternion_setValue(a._btRotation,-r.x,r.y,r.z,-r.w),n.btTransform_setOrigin(a._btTransform,a._btOffset),n.btTransform_setRotation(a._btTransform,a._btRotation);var o=n.btCollisionShape_getLocalScaling(this._btShape);n.btCollisionShape_setLocalScaling(this._btShape,a._btVector3One),n.btCompoundShape_addChildShape(this._btShape,a._btTransform,t._btShape),n.btCollisionShape_setLocalScaling(this._btShape,o),this._attatchedCollisionObject&&(this._attatchedCollisionObject.colliderShape=this)}removeChildShape(t){if(t._compoundParent===this){var i=t._indexInCompound;this._clearChildShape(t);var r=this._childColliderShapes[this._childColliderShapes.length-1];r._indexInCompound=i,this._childColliderShapes[i]=r,this._childColliderShapes.pop(),e.ILaya3D.Physics3D._bullet.btCompoundShape_removeChildShapeByIndex(this._btShape,i)}}clearChildShape(){for(var t=0,i=this._childColliderShapes.length;t0&&r.btCollisionObject_setCollisionFlags(i,n^d.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK)}_onAdded(){this.enabled=this._enabled,this.restitution=this._restitution,this.friction=this._friction,this.rollingFriction=this._rollingFriction,this.ccdMotionThreshold=this._ccdMotionThreshold,this.ccdSweptSphereRadius=this._ccdSweptSphereRadius,this.owner.transform.on(e.Event.TRANSFORM_CHANGED,this,this._onTransformChanged)}_onTransformChanged(t){!d._addUpdateList&&this._controlBySimulation||(t&=e.Transform3D.TRANSFORM_WORLDPOSITION|e.Transform3D.TRANSFORM_WORLDQUATERNION|e.Transform3D.TRANSFORM_WORLDSCALE)&&(this._transformFlag|=t,this._isValid()&&-1===this._inPhysicUpdateListIndex&&this._simulation._physicsUpdateList.add(this))}_cloneTo(t){var e=t;e.restitution=this._restitution,e.friction=this._friction,e.rollingFriction=this._rollingFriction,e.ccdMotionThreshold=this._ccdMotionThreshold,e.ccdSweptSphereRadius=this._ccdSweptSphereRadius,e.collisionGroup=this._collisionGroup,e.canCollideWith=this._canCollideWith,e.canScaleShape=this.canScaleShape,this._colliderShape&&(e.colliderShape=this._colliderShape.clone())}}d.ACTIVATIONSTATE_ACTIVE_TAG=1,d.ACTIVATIONSTATE_ISLAND_SLEEPING=2,d.ACTIVATIONSTATE_WANTS_DEACTIVATION=3,d.ACTIVATIONSTATE_DISABLE_DEACTIVATION=4,d.ACTIVATIONSTATE_DISABLE_SIMULATION=5,d.COLLISIONFLAGS_STATIC_OBJECT=1,d.COLLISIONFLAGS_KINEMATIC_OBJECT=2,d.COLLISIONFLAGS_NO_CONTACT_RESPONSE=4,d.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK=8,d.COLLISIONFLAGS_CHARACTER_OBJECT=16,d.COLLISIONFLAGS_DISABLE_VISUALIZE_OBJECT=32,d.COLLISIONFLAGS_DISABLE_SPU_COLLISION_PROCESSING=64,d._tempVector30=new e.Vector3,d._tempQuaternion0=new e.Quaternion,d._tempQuaternion1=new e.Quaternion,d._tempMatrix4x40=new e.Matrix4x4,d._physicObjectsMap={},d._addUpdateList=!0;class C{}C._interactive={getWorldTransform:(t,e)=>{},setWorldTransform:(t,e)=>{var i=d._physicObjectsMap[t];i._simulation._updatedRigidbodies++,i._updateTransformComponent(e)}};class g extends d{constructor(t=.1,i=null,r=e.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER,n=e.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER){super(r,n),this._upAxis=new e.Vector3(0,1,0),this._maxSlope=45,this._jumpSpeed=10,this._fallSpeed=55,this._gravity=new e.Vector3(0,3*-9.8,0),this._btKinematicCharacter=null,this._stepHeight=t,i&&(this._upAxis=i),this._controlBySimulation=!0}static __init__(){g._btTempVector30=e.ILaya3D.Physics3D._bullet.btVector3_create(0,0,0)}get fallSpeed(){return this._fallSpeed}set fallSpeed(t){this._fallSpeed=t,e.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setFallSpeed(this._btKinematicCharacter,t)}get jumpSpeed(){return this._jumpSpeed}set jumpSpeed(t){this._jumpSpeed=t,e.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setJumpSpeed(this._btKinematicCharacter,t)}get gravity(){return this._gravity}set gravity(t){this._gravity=t;var i=e.ILaya3D.Physics3D._bullet,r=g._btTempVector30;i.btVector3_setValue(r,-t.x,t.y,t.z),i.btKinematicCharacterController_setGravity(this._btKinematicCharacter,r)}get maxSlope(){return this._maxSlope}set maxSlope(t){this._maxSlope=t,e.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setMaxSlope(this._btKinematicCharacter,t/180*Math.PI)}get isGrounded(){return e.ILaya3D.Physics3D._bullet.btKinematicCharacterController_onGround(this._btKinematicCharacter)}get stepHeight(){return this._stepHeight}set stepHeight(t){this._stepHeight=t,e.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setStepHeight(this._btKinematicCharacter,t)}get upAxis(){return this._upAxis}set upAxis(t){this._upAxis=t;var i=g._btTempVector30;e.Utils3D._convertToBulletVec3(t,i,!1),e.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setUp(this._btKinematicCharacter,i)}_constructCharacter(){var t=e.ILaya3D.Physics3D._bullet;this._btKinematicCharacter&&t.btKinematicCharacterController_destroy(this._btKinematicCharacter);var i=g._btTempVector30;t.btVector3_setValue(i,this._upAxis.x,this._upAxis.y,this._upAxis.z),this._btKinematicCharacter=t.btKinematicCharacterController_create(this._btColliderObject,this._colliderShape._btShape,this._stepHeight,i),this.fallSpeed=this._fallSpeed,this.maxSlope=this._maxSlope,this.jumpSpeed=this._jumpSpeed,this.gravity=this._gravity}_onShapeChange(t){super._onShapeChange(t),this._constructCharacter()}_onAdded(){var t=e.ILaya3D.Physics3D._bullet,i=t.btPairCachingGhostObject_create();t.btCollisionObject_setUserIndex(i,this.id),t.btCollisionObject_setCollisionFlags(i,d.COLLISIONFLAGS_CHARACTER_OBJECT),this._btColliderObject=i,this._colliderShape&&this._constructCharacter(),super._onAdded()}_addToSimulation(){this._simulation._characters.push(this),this._simulation._addCharacter(this,this._collisionGroup,this._canCollideWith)}_removeFromSimulation(){this._simulation._removeCharacter(this);var t=this._simulation._characters;t.splice(t.indexOf(this),1)}_cloneTo(t){super._cloneTo(t);var e=t;e.stepHeight=this._stepHeight,e.upAxis=this._upAxis,e.maxSlope=this._maxSlope,e.jumpSpeed=this._jumpSpeed,e.fallSpeed=this._fallSpeed,e.gravity=this._gravity}_onDestroy(){e.ILaya3D.Physics3D._bullet.btKinematicCharacterController_destroy(this._btKinematicCharacter),super._onDestroy(),this._btKinematicCharacter=null}move(t){var i=g._btVector30,r=e.ILaya3D.Physics3D._bullet;r.btVector3_setValue(i,-t.x,t.y,t.z),r.btKinematicCharacterController_setWalkDirection(this._btKinematicCharacter,i)}jump(t=null){var i=e.ILaya3D.Physics3D._bullet,r=g._btVector30;t?(e.Utils3D._convertToBulletVec3(t,r,!0),i.btKinematicCharacterController_jump(this._btKinematicCharacter,r)):(i.btVector3_setValue(r,0,0,0),i.btKinematicCharacterController_jump(this._btKinematicCharacter,r))}}g.UPAXIS_X=0,g.UPAXIS_Y=1,g.UPAXIS_Z=2;class m{constructor(){this._lastUpdateFrame=-2147483648,this._updateFrame=-2147483648,this._isTrigger=!1,this.contacts=[]}_setUpdateFrame(t){this._lastUpdateFrame=this._updateFrame,this._updateFrame=t}}class v{constructor(){this._idCounter=0,this.colliderA=null,this.colliderB=null,this.distance=0,this.normal=new e.Vector3,this.positionOnA=new e.Vector3,this.positionOnB=new e.Vector3,this._id=++this._idCounter}}class y{constructor(){this.succeeded=!1,this.collider=null,this.point=new e.Vector3,this.normal=new e.Vector3,this.hitFraction=0}}class p{constructor(){this._hitResultsPoolIndex=0,this._hitResultsPool=[],this._contactPonintsPoolIndex=0,this._contactPointsPool=[],this._collisionsPool=[],this._collisions={}}getHitResult(){var t=this._hitResultsPool[this._hitResultsPoolIndex++];return t||(t=new y,this._hitResultsPool.push(t)),t}recoverAllHitResultsPool(){this._hitResultsPoolIndex=0}getContactPoints(){var t=this._contactPointsPool[this._contactPonintsPoolIndex++];return t||(t=new v,this._contactPointsPool.push(t)),t}recoverAllContactPointsPool(){this._contactPonintsPoolIndex=0}getCollision(t,e){var i,r=t.id,n=e.id,a=this._collisions[r];return a&&(i=a[n]),i||(a||(a={},this._collisions[r]=a),(i=0===this._collisionsPool.length?new m:this._collisionsPool.pop())._colliderA=t,i._colliderB=e,a[n]=i),i}recoverCollision(t){var e=t._colliderA.id,i=t._colliderB.id;this._collisions[e][i]=null,this._collisionsPool.push(t)}garbageCollection(){for(var t in this._hitResultsPoolIndex=0,this._hitResultsPool.length=0,this._contactPonintsPoolIndex=0,this._contactPointsPool.length=0,this._collisionsPool.length=0,this._collisionsPool){var e=this._collisionsPool[t],i=!0;for(var r in e)e[r]?i=!1:delete e[r];i&&delete this._collisionsPool[t]}}}class R extends d{constructor(t,e){super(t,e),this._isTrigger=!1}get isTrigger(){return this._isTrigger}set isTrigger(t){this._isTrigger=t;var i=e.ILaya3D.Physics3D._bullet;if(this._btColliderObject){var r=i.btCollisionObject_getCollisionFlags(this._btColliderObject);t?0==(r&d.COLLISIONFLAGS_NO_CONTACT_RESPONSE)&&i.btCollisionObject_setCollisionFlags(this._btColliderObject,r|d.COLLISIONFLAGS_NO_CONTACT_RESPONSE):0!=(r&d.COLLISIONFLAGS_NO_CONTACT_RESPONSE)&&i.btCollisionObject_setCollisionFlags(this._btColliderObject,r^d.COLLISIONFLAGS_NO_CONTACT_RESPONSE)}}_onAdded(){super._onAdded(),this.isTrigger=this._isTrigger}_cloneTo(t){super._cloneTo(t),t.isTrigger=this._isTrigger}}class D extends e.SingletonList{constructor(){super()}add(t){if(-1!==t._inPhysicUpdateListIndex)throw"PhysicsUpdateList:element has in PhysicsUpdateList.";this._add(t),t._inPhysicUpdateListIndex=this.length++}remove(t){var e=t._inPhysicUpdateListIndex;if(this.length--,e!==this.length){var i=this.elements[this.length];this.elements[e]=i,i._inPhysicUpdateListIndex=e}t._inPhysicUpdateListIndex=-1}}class B{constructor(t){this._gravity=new e.Vector3(0,-10,0),this._btVector3Zero=e.ILaya3D.Physics3D._bullet.btVector3_create(0,0,0),this._btDefaultQuaternion=e.ILaya3D.Physics3D._bullet.btQuaternion_create(0,0,0,-1),this._collisionsUtils=new p,this._previousFrameCollisions=[],this._currentFrameCollisions=[],this._currentConstraint={},this._physicsUpdateList=new D,this._characters=[],this._updatedRigidbodies=0,this.maxSubSteps=1,this.fixedTimeStep=1/60,this.maxSubSteps=t.maxSubSteps,this.fixedTimeStep=t.fixedTimeStep;var i=e.ILaya3D.Physics3D._bullet;this._btCollisionConfiguration=i.btDefaultCollisionConfiguration_create(),this._btDispatcher=i.btCollisionDispatcher_create(this._btCollisionConfiguration),this._btBroadphase=i.btDbvtBroadphase_create(),i.btOverlappingPairCache_setInternalGhostPairCallback(i.btDbvtBroadphase_getOverlappingPairCache(this._btBroadphase),i.btGhostPairCallback_create());var r=t.flags;if(r&B.PHYSICSENGINEFLAGS_COLLISIONSONLY)this._btCollisionWorld=new i.btCollisionWorld(this._btDispatcher,this._btBroadphase,this._btCollisionConfiguration);else{if(r&B.PHYSICSENGINEFLAGS_SOFTBODYSUPPORT)throw"PhysicsSimulation:SoftBody processing is not yet available";var n=i.btSequentialImpulseConstraintSolver_create();this._btDiscreteDynamicsWorld=i.btDiscreteDynamicsWorld_create(this._btDispatcher,this._btBroadphase,n,this._btCollisionConfiguration),this._btCollisionWorld=this._btDiscreteDynamicsWorld}this._btDiscreteDynamicsWorld&&(this._btSolverInfo=i.btDynamicsWorld_getSolverInfo(this._btDiscreteDynamicsWorld),this._btDispatchInfo=i.btCollisionWorld_getDispatchInfo(this._btDiscreteDynamicsWorld)),this._btClosestRayResultCallback=i.ClosestRayResultCallback_create(this._btVector3Zero,this._btVector3Zero),this._btAllHitsRayResultCallback=i.AllHitsRayResultCallback_create(this._btVector3Zero,this._btVector3Zero),this._btClosestConvexResultCallback=i.ClosestConvexResultCallback_create(this._btVector3Zero,this._btVector3Zero),this._btAllConvexResultCallback=i.AllConvexResultCallback_create(this._btVector3Zero,this._btVector3Zero),this.setHitsRayResultCallbackFlag(),i.btGImpactCollisionAlgorithm_RegisterAlgorithm(this._btDispatcher)}static __init__(){var t=e.ILaya3D.Physics3D._bullet;B._btTempVector30=t.btVector3_create(0,0,0),B._btTempVector31=t.btVector3_create(0,0,0),B._btTempQuaternion0=t.btQuaternion_create(0,0,0,1),B._btTempQuaternion1=t.btQuaternion_create(0,0,0,1),B._btTempTransform0=t.btTransform_create(),B._btTempTransform1=t.btTransform_create()}static createConstraint(){}get continuousCollisionDetection(){return e.ILaya3D.Physics3D._bullet.btCollisionWorld_get_m_useContinuous(this._btDispatchInfo)}set continuousCollisionDetection(t){e.ILaya3D.Physics3D._bullet.btCollisionWorld_set_m_useContinuous(this._btDispatchInfo,t)}get gravity(){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";return this._gravity}set gravity(t){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";this._gravity=t;var i=e.ILaya3D.Physics3D._bullet,r=B._btTempVector30;i.btVector3_setValue(r,-t.x,t.y,t.z),i.btDiscreteDynamicsWorld_setGravity(this._btDiscreteDynamicsWorld,r)}get speculativeContactRestitution(){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot Cannot perform this action when the physics engine is set to CollisionsOnly";return e.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_getApplySpeculativeContactRestitution(this._btDiscreteDynamicsWorld)}set speculativeContactRestitution(t){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot Cannot perform this action when the physics engine is set to CollisionsOnly";e.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_setApplySpeculativeContactRestitution(this._btDiscreteDynamicsWorld,t)}_simulate(t){this._updatedRigidbodies=0;var i=e.ILaya3D.Physics3D._bullet;this._btDiscreteDynamicsWorld?i.btDiscreteDynamicsWorld_stepSimulation(this._btDiscreteDynamicsWorld,t,this.maxSubSteps,this.fixedTimeStep):i.PerformDiscreteCollisionDetection(this._btCollisionWorld)}_destroy(){var t=e.ILaya3D.Physics3D._bullet;this._btDiscreteDynamicsWorld?(t.btCollisionWorld_destroy(this._btDiscreteDynamicsWorld),this._btDiscreteDynamicsWorld=null):(t.btCollisionWorld_destroy(this._btCollisionWorld),this._btCollisionWorld=null),t.btDbvtBroadphase_destroy(this._btBroadphase),this._btBroadphase=null,t.btCollisionDispatcher_destroy(this._btDispatcher),this._btDispatcher=null,t.btDefaultCollisionConfiguration_destroy(this._btCollisionConfiguration),this._btCollisionConfiguration=null}_addPhysicsCollider(t,i,r){e.ILaya3D.Physics3D._bullet.btCollisionWorld_addCollisionObject(this._btCollisionWorld,t._btColliderObject,i,r)}_removePhysicsCollider(t){e.ILaya3D.Physics3D._bullet.btCollisionWorld_removeCollisionObject(this._btCollisionWorld,t._btColliderObject)}_addRigidBody(t,i,r){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";e.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_addRigidBody(this._btCollisionWorld,t._btColliderObject,i,r)}_removeRigidBody(t){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";e.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_removeRigidBody(this._btCollisionWorld,t._btColliderObject)}_addCharacter(t,i,r){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";var n=e.ILaya3D.Physics3D._bullet;n.btCollisionWorld_addCollisionObject(this._btCollisionWorld,t._btColliderObject,i,r),n.btDynamicsWorld_addAction(this._btCollisionWorld,t._btKinematicCharacter)}_removeCharacter(t){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";var i=e.ILaya3D.Physics3D._bullet;i.btCollisionWorld_removeCollisionObject(this._btCollisionWorld,t._btColliderObject),i.btDynamicsWorld_removeAction(this._btCollisionWorld,t._btKinematicCharacter)}raycastFromTo(t,i,r=null,n=e.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER,a=e.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER){var o=e.ILaya3D.Physics3D._bullet,f=this._btClosestRayResultCallback,_=B._btTempVector30,h=B._btTempVector31;if(o.btVector3_setValue(_,-t.x,t.y,t.z),o.btVector3_setValue(h,-i.x,i.y,i.z),o.ClosestRayResultCallback_set_m_rayFromWorld(f,_),o.ClosestRayResultCallback_set_m_rayToWorld(f,h),o.RayResultCallback_set_m_collisionFilterGroup(f,n),o.RayResultCallback_set_m_collisionFilterMask(f,a),o.RayResultCallback_set_m_collisionObject(f,null),o.RayResultCallback_set_m_closestHitFraction(f,1),o.btCollisionWorld_rayTest(this._btCollisionWorld,_,h,f),o.RayResultCallback_hasHit(f)){if(r){r.succeeded=!0,r.collider=d._physicObjectsMap[o.btCollisionObject_getUserIndex(o.RayResultCallback_get_m_collisionObject(f))],r.hitFraction=o.RayResultCallback_get_m_closestHitFraction(f);var C=o.ClosestRayResultCallback_get_m_hitPointWorld(f),g=r.point;g.x=-o.btVector3_x(C),g.y=o.btVector3_y(C),g.z=o.btVector3_z(C);var m=o.ClosestRayResultCallback_get_m_hitNormalWorld(f),v=r.normal;v.x=-o.btVector3_x(m),v.y=o.btVector3_y(m),v.z=o.btVector3_z(m)}return!0}return r&&(r.succeeded=!1),!1}raycastAllFromTo(t,i,r,n=e.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER,a=e.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER){var o=e.ILaya3D.Physics3D._bullet,f=this._btAllHitsRayResultCallback,_=B._btTempVector30,h=B._btTempVector31;r.length=0,o.btVector3_setValue(_,-t.x,t.y,t.z),o.btVector3_setValue(h,-i.x,i.y,i.z),o.AllHitsRayResultCallback_set_m_rayFromWorld(f,_),o.AllHitsRayResultCallback_set_m_rayToWorld(f,h),o.RayResultCallback_set_m_collisionFilterGroup(f,n),o.RayResultCallback_set_m_collisionFilterMask(f,a);var C=o.AllHitsRayResultCallback_get_m_collisionObjects(f),g=o.AllHitsRayResultCallback_get_m_hitPointWorld(f),m=o.AllHitsRayResultCallback_get_m_hitNormalWorld(f),v=o.AllHitsRayResultCallback_get_m_hitFractions(f);o.tBtCollisionObjectArray_clear(C),o.tVector3Array_clear(g),o.tVector3Array_clear(m),o.tScalarArray_clear(v),o.btCollisionWorld_rayTest(this._btCollisionWorld,_,h,f);var y=o.tBtCollisionObjectArray_size(C);if(y>0){this._collisionsUtils.recoverAllHitResultsPool();for(var p=0;p0){this._collisionsUtils.recoverAllHitResultsPool();for(var W=0;W0&&(a^=d.COLLISIONFLAGS_KINEMATIC_OBJECT),i.btCollisionObject_setCollisionFlags(n,a),i.btCollisionObject_setActivationState(this._btColliderObject,d.ACTIVATIONSTATE_ACTIVE_TAG),this._enableProcessCollisions=!0,this._updateMass(this._mass));var o=E._btVector3Zero;i.btCollisionObject_setInterpolationLinearVelocity(n,o),i.btRigidBody_setLinearVelocity(n,o),i.btCollisionObject_setInterpolationAngularVelocity(n,o),i.btRigidBody_setAngularVelocity(n,o),r&&this._addToSimulation()}get linearDamping(){return this._linearDamping}set linearDamping(t){this._linearDamping=t,this._btColliderObject&&e.ILaya3D.Physics3D._bullet.btRigidBody_setDamping(this._btColliderObject,t,this._angularDamping)}get angularDamping(){return this._angularDamping}set angularDamping(t){this._angularDamping=t,this._btColliderObject&&e.ILaya3D.Physics3D._bullet.btRigidBody_setDamping(this._btColliderObject,this._linearDamping,t)}get overrideGravity(){return this._overrideGravity}set overrideGravity(t){this._overrideGravity=t;var i=e.ILaya3D.Physics3D._bullet;if(this._btColliderObject){var r=i.btRigidBody_getFlags(this._btColliderObject);t?0==(r&E._BT_DISABLE_WORLD_GRAVITY)&&i.btRigidBody_setFlags(this._btColliderObject,r|E._BT_DISABLE_WORLD_GRAVITY):(r&E._BT_DISABLE_WORLD_GRAVITY)>0&&i.btRigidBody_setFlags(this._btColliderObject,r^E._BT_DISABLE_WORLD_GRAVITY)}}get gravity(){var t=e.ILaya3D.Physics3D._bullet;return E._btGravity=t.btRigidBody_getGravity(this._btColliderObject),e.Utils3D._convertToLayaVec3(E._btGravity,this._gravity,!0),this._gravity}set gravity(t){this._gravity=t;var i=e.ILaya3D.Physics3D._bullet;i.btVector3_setValue(E._btGravity,-t.x,t.y,t.z),i.btRigidBody_setGravity(this._btColliderObject,E._btGravity)}get totalForce(){if(this._btColliderObject){var t=e.ILaya3D.Physics3D._bullet.btRigidBody_getTotalForce(this._btColliderObject);return e.Utils3D._convertToLayaVec3(t,this._totalForce,!0),this._totalForce}return null}get linearFactor(){return this._linearFactor}set linearFactor(t){this._linearFactor=t;var i=E._btTempVector30;e.Utils3D._convertToBulletVec3(t,i,!1),e.ILaya3D.Physics3D._bullet.btRigidBody_setLinearFactor(this._btColliderObject,i)}get linearVelocity(){return this._btColliderObject&&e.Utils3D._convertToLayaVec3(e.ILaya3D.Physics3D._bullet.btRigidBody_getLinearVelocity(this._btColliderObject),this._linearVelocity,!0),this._linearVelocity}set linearVelocity(t){if(this._linearVelocity=t,this._btColliderObject){var i=E._btTempVector30;e.Utils3D._convertToBulletVec3(t,i,!0),this.isSleeping&&this.wakeUp(),e.ILaya3D.Physics3D._bullet.btRigidBody_setLinearVelocity(this._btColliderObject,i)}}get angularFactor(){return this._angularFactor}set angularFactor(t){this._angularFactor=t;var i=E._btTempVector30;e.Utils3D._convertToBulletVec3(t,i,!1),e.ILaya3D.Physics3D._bullet.btRigidBody_setAngularFactor(this._btColliderObject,i)}get angularVelocity(){return this._btColliderObject&&e.Utils3D._convertToLayaVec3(e.ILaya3D.Physics3D._bullet.btRigidBody_getAngularVelocity(this._btColliderObject),this._angularVelocity,!0),this._angularVelocity}set angularVelocity(t){if(this._angularVelocity=t,this._btColliderObject){var i=E._btTempVector30;e.Utils3D._convertToBulletVec3(t,i,!0),this.isSleeping&&this.wakeUp(),e.ILaya3D.Physics3D._bullet.btRigidBody_setAngularVelocity(this._btColliderObject,i)}}get totalTorque(){if(this._btColliderObject){var t=e.ILaya3D.Physics3D._bullet.btRigidBody_getTotalTorque(this._btColliderObject);return e.Utils3D._convertToLayaVec3(t,this._totalTorque,!0),this._totalTorque}return null}get detectCollisions(){return this._detectCollisions}set detectCollisions(t){this._detectCollisions!==t&&(this._detectCollisions=t,this._colliderShape&&this._enabled&&this._simulation&&(this._simulation._removeRigidBody(this),this._simulation._addRigidBody(this,this._collisionGroup,t?this._canCollideWith:0)))}get isSleeping(){return!!this._btColliderObject&&e.ILaya3D.Physics3D._bullet.btCollisionObject_getActivationState(this._btColliderObject)===d.ACTIVATIONSTATE_ISLAND_SLEEPING}get sleepLinearVelocity(){return e.ILaya3D.Physics3D._bullet.btRigidBody_getLinearSleepingThreshold(this._btColliderObject)}set sleepLinearVelocity(t){var i=e.ILaya3D.Physics3D._bullet;i.btRigidBody_setSleepingThresholds(this._btColliderObject,t,i.btRigidBody_getAngularSleepingThreshold(this._btColliderObject))}get sleepAngularVelocity(){return e.ILaya3D.Physics3D._bullet.btRigidBody_getAngularSleepingThreshold(this._btColliderObject)}set sleepAngularVelocity(t){var i=e.ILaya3D.Physics3D._bullet;i.btRigidBody_setSleepingThresholds(this._btColliderObject,i.btRigidBody_getLinearSleepingThreshold(this._btColliderObject),t)}get btColliderObject(){return this._btColliderObject}set constaintRigidbodyA(t){this._constaintRigidbodyA=t}get constaintRigidbodyA(){return this._constaintRigidbodyA}set constaintRigidbodyB(t){this._constaintRigidbodyB=t}get constaintRigidbodyB(){return this._constaintRigidbodyB}_updateMass(t){if(this._btColliderObject&&this._colliderShape){var i=e.ILaya3D.Physics3D._bullet;i.btCollisionShape_calculateLocalInertia(this._colliderShape._btShape,t,E._btInertia),i.btRigidBody_setMassProps(this._btColliderObject,t,E._btInertia),i.btRigidBody_updateInertiaTensor(this._btColliderObject)}}_onScaleChange(t){super._onScaleChange(t),this._updateMass(this._isKinematic?0:this._mass)}_derivePhysicsTransformation(t){var i=e.ILaya3D.Physics3D._bullet,r=this._btColliderObject,n=i.btCollisionObject_getWorldTransform(r),a=E._btTransform0;i.btTransform_equal(a,n),this._innerDerivePhysicsTransformation(a,t),i.btRigidBody_setCenterOfMassTransform(r,a)}_onAdded(){var t=e.ILaya3D.Physics3D._bullet,i=t.layaMotionState_create();t.layaMotionState_set_rigidBodyID(i,this._id),this._btLayaMotionState=i;var r=t.btRigidBodyConstructionInfo_create(0,i,null,E._btVector3Zero),n=t.btRigidBody_create(r);t.btCollisionObject_setUserIndex(n,this.id),this._btColliderObject=n,super._onAdded(),this.mass=this._mass,this.linearFactor=this._linearFactor,this.angularFactor=this._angularFactor,this.linearDamping=this._linearDamping,this.angularDamping=this._angularDamping,this.overrideGravity=this._overrideGravity,this.gravity=this._gravity,this.isKinematic=this._isKinematic,t.btRigidBodyConstructionInfo_destroy(r)}_onEnable(){super._onEnable(),this._constaintRigidbodyA&&this._constaintRigidbodyA.connectedBody._simulation&&(this._constaintRigidbodyA._createConstraint(),this._constaintRigidbodyA._onEnable()),this._constaintRigidbodyB&&this._constaintRigidbodyB.ownBody._simulation&&(this._constaintRigidbodyB._createConstraint(),this._constaintRigidbodyB._onEnable())}_onShapeChange(t){if(super._onShapeChange(t),this._isKinematic)this._updateMass(0);else{var i=e.ILaya3D.Physics3D._bullet;i.btRigidBody_setCenterOfMassTransform(this._btColliderObject,i.btCollisionObject_getWorldTransform(this._btColliderObject)),this._updateMass(this._mass)}}_parse(t){if(null!=t.friction&&(this.friction=t.friction),null!=t.rollingFriction&&(this.rollingFriction=t.rollingFriction),null!=t.restitution&&(this.restitution=t.restitution),null!=t.isTrigger&&(this.isTrigger=t.isTrigger),null!=t.mass&&(this.mass=t.mass),null!=t.linearDamping&&(this.linearDamping=t.linearDamping),null!=t.angularDamping&&(this.angularDamping=t.angularDamping),null!=t.overrideGravity&&(this.overrideGravity=t.overrideGravity),null!=t.linearFactor){var e=this.linearFactor;e.fromArray(t.linearFactor),this.linearFactor=e}if(null!=t.angularFactor){var i=this.angularFactor;i.fromArray(t.angularFactor),this.angularFactor=i}t.gravity&&(this.gravity.fromArray(t.gravity),this.gravity=this.gravity),super._parse(t),this._parseShape(t.shapes),null!=t.isKinematic&&(this.isKinematic=t.isKinematic)}_onDestroy(){e.ILaya3D.Physics3D._bullet.btMotionState_destroy(this._btLayaMotionState),super._onDestroy(),this._btLayaMotionState=null,this._gravity=null,this._totalTorque=null,this._linearVelocity=null,this._angularVelocity=null,this._linearFactor=null,this._angularFactor=null,this.constaintRigidbodyA&&this.constaintRigidbodyA._breakConstrained(),this.constaintRigidbodyB&&(this.constaintRigidbodyB.connectedBody=null,this.constaintRigidbodyB._onDisable())}_addToSimulation(){this._simulation._addRigidBody(this,this._collisionGroup,this._detectCollisions?this._canCollideWith:0)}_removeFromSimulation(){this._simulation._removeRigidBody(this)}_cloneTo(t){super._cloneTo(t);var e=t;e.isKinematic=this._isKinematic,e.mass=this._mass,e.gravity=this._gravity,e.angularDamping=this._angularDamping,e.linearDamping=this._linearDamping,e.overrideGravity=this._overrideGravity,e.linearVelocity=this._linearVelocity,e.angularVelocity=this._angularVelocity,e.linearFactor=this._linearFactor,e.angularFactor=this._angularFactor,e.detectCollisions=this._detectCollisions}applyForce(t,i=null){if(null==this._btColliderObject)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";var r=e.ILaya3D.Physics3D._bullet,n=E._btTempVector30;if(r.btVector3_setValue(n,-t.x,t.y,t.z),i){var a=E._btTempVector31;r.btVector3_setValue(a,-i.x,i.y,i.z),r.btRigidBody_applyForce(this._btColliderObject,n,a)}else r.btRigidBody_applyCentralForce(this._btColliderObject,n)}applyTorque(t){if(null==this._btColliderObject)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";var i=e.ILaya3D.Physics3D._bullet,r=E._btTempVector30;i.btVector3_setValue(r,-t.x,t.y,t.z),i.btRigidBody_applyTorque(this._btColliderObject,r)}applyImpulse(t,i=null){if(null==this._btColliderObject)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";var r=e.ILaya3D.Physics3D._bullet;r.btVector3_setValue(E._btImpulse,-t.x,t.y,t.z),i?(r.btVector3_setValue(E._btImpulseOffset,-i.x,i.y,i.z),r.btRigidBody_applyImpulse(this._btColliderObject,E._btImpulse,E._btImpulseOffset)):r.btRigidBody_applyCentralImpulse(this._btColliderObject,E._btImpulse)}applyTorqueImpulse(t){if(null==this._btColliderObject)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";var i=e.ILaya3D.Physics3D._bullet,r=E._btTempVector30;i.btVector3_setValue(r,-t.x,t.y,t.z),i.btRigidBody_applyTorqueImpulse(this._btColliderObject,r)}wakeUp(){this._btColliderObject&&e.ILaya3D.Physics3D._bullet.btCollisionObject_activate(this._btColliderObject,!1)}clearForces(){var t=this._btColliderObject;if(null==t)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";var i=e.ILaya3D.Physics3D._bullet;i.btRigidBody_clearForces(t);var r=E._btVector3Zero;i.btCollisionObject_setInterpolationLinearVelocity(t,r),i.btRigidBody_setLinearVelocity(t,r),i.btCollisionObject_setInterpolationAngularVelocity(t,r),i.btRigidBody_setAngularVelocity(t,r)}}E.TYPE_STATIC=0,E.TYPE_DYNAMIC=1,E.TYPE_KINEMATIC=2,E._BT_DISABLE_WORLD_GRAVITY=1,E._BT_ENABLE_GYROPSCOPIC_FORCE=2;class F extends e.Component{constructor(t){super(),this._anchor=new e.Vector3,this._connectAnchor=new e.Vector3,this._feedbackEnabled=!1,this._getJointFeedBack=!1,this._currentForce=new e.Vector3,this._currentTorque=new e.Vector3,this._constraintType=t;var i=e.Physics3D._bullet;this._btframATrans=i.btTransform_create(),this._btframBTrans=i.btTransform_create(),i.btTransform_setIdentity(this._btframATrans),i.btTransform_setIdentity(this._btframBTrans),this._btframAPos=i.btVector3_create(0,0,0),this._btframBPos=i.btVector3_create(0,0,0),i.btTransform_setOrigin(this._btframATrans,this._btframAPos),i.btTransform_setOrigin(this._btframBTrans,this._btframBPos),this._breakForce=-1,this._breakTorque=-1}get enabled(){return super.enabled}set enabled(t){super.enabled=t}get appliedImpulse(){return this._feedbackEnabled||(this._btConstraint.EnableFeedback(!0),this._feedbackEnabled=!0),this._btConstraint.AppliedImpulse}set connectedBody(t){this._connectedBody=t,t&&(t.constaintRigidbodyB=this)}get connectedBody(){return this._connectedBody}get ownBody(){return this._ownBody}set ownBody(t){this._ownBody=t,t.constaintRigidbodyA=this}get currentForce(){return this._getJointFeedBack||this._getFeedBackInfo(),this._currentForce}get currentTorque(){return this._getJointFeedBack||this._getFeedBackInfo(),this._currentTorque}get breakForce(){return this._breakForce}set breakForce(t){this._breakForce=t}get breakTorque(){return this._breakTorque}set breakTorque(t){this._breakTorque=t}set anchor(t){t.cloneTo(this._anchor),this.setFrames()}get anchor(){return this._anchor}set connectAnchor(t){t.cloneTo(this._connectAnchor),this.setFrames()}get connectAnchor(){return this._connectAnchor}setOverrideNumSolverIterations(t){e.Physics3D._bullet.btTypedConstraint_setOverrideNumSolverIterations(this._btConstraint,t)}setConstraintEnabled(t){e.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,t)}_onEnable(){super._onEnable(),this.enabled=!0}_onDisable(){super._onDisable(),this.enabled=!1}setFrames(){var t=e.Physics3D._bullet;t.btVector3_setValue(this._btframAPos,-this._anchor.x,this.anchor.y,this.anchor.z),t.btVector3_setValue(this._btframBPos,-this._connectAnchor.x,this._connectAnchor.y,this._connectAnchor.z),t.btTransform_setOrigin(this._btframATrans,this._btframAPos),t.btTransform_setOrigin(this._btframBTrans,this._btframBPos)}_addToSimulation(){}_removeFromSimulation(){}_createConstraint(){}setConnectRigidBody(t,e){var i=t&&!!(t._simulation&&t._enabled&&t.colliderShape),r=e&&!!(e._simulation&&e._enabled&&e.colliderShape);if(!i||!r)throw"ownerRigid or connectRigidBody is not in Simulation";t==this._ownBody&&e==this._connectedBody||(!(!this.enabled||!this._simulation)&&this._removeFromSimulation(),this._ownBody=t,this._connectedBody=e,this._ownBody.constaintRigidbodyA=this,this._connectedBody.constaintRigidbodyB=this,this._createConstraint())}getcurrentForce(t){if(!this._btJointFeedBackObj)throw"this Constraint is not simulation";var i=e.Physics3D._bullet,r=i.btJointFeedback_getAppliedForceBodyA(this._btJointFeedBackObj);t.setValue(i.btVector3_x(r),i.btVector3_y(r),i.btVector3_z(r))}getcurrentTorque(t){if(!this._btJointFeedBackObj)throw"this Constraint is not simulation";var i=e.Physics3D._bullet,r=i.btJointFeedback_getAppliedTorqueBodyA(this._btJointFeedBackObj);t.setValue(i.btVector3_x(r),i.btVector3_y(r),i.btVector3_z(r))}_onDestroy(){var t=e.Physics3D._bullet;this._simulation&&this._removeFromSimulation(),this._btConstraint&&this._btJointFeedBackObj&&this._simulation&&(t.btTypedConstraint_destroy(this._btConstraint),t.btJointFeedback_destroy(this._btJointFeedBackObj),this._btJointFeedBackObj=null,this._btConstraint=null),super._onDisable()}_isBreakConstrained(){if(this._getJointFeedBack=!1,-1==this.breakForce&&-1==this.breakTorque)return!1;this._getFeedBackInfo();var t=-1!=this._breakForce&&e.Vector3.scalarLength(this._currentForce)>this._breakForce,i=-1!=this._breakTorque&&e.Vector3.scalarLength(this._currentTorque)>this._breakTorque;return!(!t&&!i)&&(this._breakConstrained(),!0)}_parse(t){this._anchor.fromArray(t.anchor),this._connectAnchor.fromArray(t.connectAnchor),this.setFrames()}_getFeedBackInfo(){var t=e.Physics3D._bullet,i=t.btJointFeedback_getAppliedForceBodyA(this._btJointFeedBackObj),r=t.btJointFeedback_getAppliedTorqueBodyA(this._btJointFeedBackObj);this._currentTorque.setValue(t.btVector3_x(r),t.btVector3_y(r),t.btVector3_z(r)),this._currentForce.setValue(t.btVector3_x(i),t.btVector3_y(i),t.btVector3_z(i)),this._getJointFeedBack=!0}_breakConstrained(){this.ownBody.constaintRigidbodyA=null,this.connectedBody&&(this.connectedBody.constaintRigidbodyB=null),this.destroy()}}F.CONSTRAINT_POINT2POINT_CONSTRAINT_TYPE=3,F.CONSTRAINT_HINGE_CONSTRAINT_TYPE=4,F.CONSTRAINT_CONETWIST_CONSTRAINT_TYPE=5,F.CONSTRAINT_D6_CONSTRAINT_TYPE=6,F.CONSTRAINT_SLIDER_CONSTRAINT_TYPE=7,F.CONSTRAINT_CONTACT_CONSTRAINT_TYPE=8,F.CONSTRAINT_D6_SPRING_CONSTRAINT_TYPE=9,F.CONSTRAINT_GEAR_CONSTRAINT_TYPE=10,F.CONSTRAINT_FIXED_CONSTRAINT_TYPE=11,F.CONSTRAINT_MAX_CONSTRAINT_TYPE=12,F.CONSTRAINT_CONSTRAINT_ERP=1,F.CONSTRAINT_CONSTRAINT_STOP_ERP=2,F.CONSTRAINT_CONSTRAINT_CFM=3,F.CONSTRAINT_CONSTRAINT_STOP_CFM=4,F.tempForceV3=new e.Vector3;class V extends F{constructor(){super(F.CONSTRAINT_D6_SPRING_CONSTRAINT_TYPE),this._axis=new e.Vector3,this._secondaryAxis=new e.Vector3,this._minLinearLimit=new e.Vector3,this._maxLinearLimit=new e.Vector3,this._minAngularLimit=new e.Vector3,this._maxAngularLimit=new e.Vector3,this._linearLimitSpring=new e.Vector3,this._angularLimitSpring=new e.Vector3,this._linearBounce=new e.Vector3,this._angularBounce=new e.Vector3,this._linearDamp=new e.Vector3,this._angularDamp=new e.Vector3,this._xMotion=0,this._yMotion=0,this._zMotion=0,this._angularXMotion=0,this._angularYMotion=0,this._angularZMotion=0;var t=e.Physics3D._bullet;this._btAxis=t.btVector3_create(-1,0,0),this._btSecondaryAxis=t.btVector3_create(0,1,0)}get axis(){return this._axis}get secondaryAxis(){return this._secondaryAxis}set maxAngularLimit(t){t.cloneTo(this._maxAngularLimit)}set minAngularLimit(t){t.cloneTo(this._minAngularLimit)}get maxAngularLimit(){return this._maxAngularLimit}get minAngularLimit(){return this._minAngularLimit}set maxLinearLimit(t){t.cloneTo(this._maxLinearLimit)}set minLinearLimit(t){t.cloneTo(this._minLinearLimit)}get maxLinearLimit(){return this._maxLinearLimit}get minLinearLimit(){return this._minLinearLimit}set XMotion(t){this._xMotion!=t&&(this._xMotion=t,this.setLimit(V.MOTION_LINEAR_INDEX_X,t,-this._maxLinearLimit.x,-this._minLinearLimit.x))}get XMotion(){return this._xMotion}set YMotion(t){this._yMotion!=t&&(this._yMotion=t,this.setLimit(V.MOTION_LINEAR_INDEX_Y,t,this._minLinearLimit.y,this._maxLinearLimit.y))}get YMotion(){return this._yMotion}set ZMotion(t){this._zMotion!=t&&(this._zMotion=t,this.setLimit(V.MOTION_LINEAR_INDEX_Z,t,this._minLinearLimit.z,this._maxLinearLimit.z))}get ZMotion(){return this._zMotion}set angularXMotion(t){this._angularXMotion!=t&&(this._angularXMotion=t,this.setLimit(V.MOTION_ANGULAR_INDEX_X,t,-this._maxAngularLimit.x,-this._minAngularLimit.x))}get angularXMotion(){return this._angularXMotion}set angularYMotion(t){this._angularYMotion!=t&&(this._angularYMotion=t,this.setLimit(V.MOTION_ANGULAR_INDEX_Y,t,this._minAngularLimit.y,this._maxAngularLimit.y))}get angularYMotion(){return this._angularYMotion}set angularZMotion(t){this._angularZMotion!=t&&(this._angularZMotion=t,this.setLimit(V.MOTION_ANGULAR_INDEX_Z,t,this._minAngularLimit.z,this._maxAngularLimit.z))}get angularZMotion(){return this._angularZMotion}set linearLimitSpring(t){e.Vector3.equals(this._linearLimitSpring,t)||(t.cloneTo(this._linearLimitSpring),this.setSpring(V.MOTION_LINEAR_INDEX_X,t.x),this.setSpring(V.MOTION_LINEAR_INDEX_Y,t.y),this.setSpring(V.MOTION_LINEAR_INDEX_Z,t.z))}get linearLimitSpring(){return this._linearLimitSpring}set angularLimitSpring(t){e.Vector3.equals(this._angularLimitSpring,t)||(t.cloneTo(this._angularLimitSpring),this.setSpring(V.MOTION_ANGULAR_INDEX_X,t.x),this.setSpring(V.MOTION_ANGULAR_INDEX_Y,t.y),this.setSpring(V.MOTION_ANGULAR_INDEX_Z,t.z))}get angularLimitSpring(){return this._angularLimitSpring}set linearBounce(t){e.Vector3.equals(this._linearBounce,t)||(t.cloneTo(this._linearBounce),this.setBounce(V.MOTION_LINEAR_INDEX_X,t.x),this.setBounce(V.MOTION_LINEAR_INDEX_Y,t.y),this.setBounce(V.MOTION_LINEAR_INDEX_Z,t.z))}get linearBounce(){return this._linearBounce}set angularBounce(t){e.Vector3.equals(this._angularBounce,t)||(t.cloneTo(this._angularBounce),this.setBounce(V.MOTION_ANGULAR_INDEX_X,t.x),this.setBounce(V.MOTION_ANGULAR_INDEX_Y,t.y),this.setBounce(V.MOTION_ANGULAR_INDEX_Z,t.z))}get angularBounce(){return this._angularBounce}set linearDamp(t){e.Vector3.equals(this._linearDamp,t)||(t.cloneTo(this._linearDamp),this.setDamping(V.MOTION_LINEAR_INDEX_X,t.x),this.setDamping(V.MOTION_LINEAR_INDEX_Y,t.y),this.setDamping(V.MOTION_LINEAR_INDEX_Z,t.z))}get linearDamp(){return this._linearDamp}set angularDamp(t){e.Vector3.equals(this._angularDamp,t)||(t.cloneTo(this._angularDamp),this.setDamping(V.MOTION_ANGULAR_INDEX_X,t.x),this.setDamping(V.MOTION_ANGULAR_INDEX_Y,t.y),this.setDamping(V.MOTION_ANGULAR_INDEX_Z,t.z))}get angularDamp(){return this._angularDamp}set anchor(t){t.cloneTo(this._anchor),this.setFrames()}get anchor(){return this._anchor}set connectAnchor(t){t.cloneTo(this._connectAnchor),this.setFrames()}get connectAnchor(){return this._connectAnchor}setAxis(t,i){if(this._btConstraint){var r=e.Physics3D._bullet;this._axis.setValue(t.x,t.y,t.y),this._secondaryAxis.setValue(i.x,i.y,i.z),this._btAxis=r.btVector3_setValue(-t.x,t.y,t.z),this._btSecondaryAxis=r.btVector3_setValue(-i.x,i.y,i.z),r.btGeneric6DofSpring2Constraint_setAxis(this._btConstraint,this._btAxis,this._btSecondaryAxis)}}setLimit(t,i,r,n){if(this._btConstraint){var a=e.Physics3D._bullet;switch(i){case V.CONFIG_MOTION_TYPE_LOCKED:a.btGeneric6DofSpring2Constraint_setLimit(this._btConstraint,t,0,0);break;case V.CONFIG_MOTION_TYPE_LIMITED:r0;n.btGeneric6DofSpring2Constraint_enableSpring(this._btConstraint,t,a),a&&n.btGeneric6DofSpring2Constraint_setStiffness(this._btConstraint,t,i,r)}}setBounce(t,i){this._btConstraint&&(i=i<=0?0:i,e.Physics3D._bullet.btGeneric6DofSpring2Constraint_setBounce(this._btConstraint,t,i))}setDamping(t,i,r=!0){this._btConstraint&&(i=i<=0?0:i,e.Physics3D._bullet.btGeneric6DofSpring2Constraint_setDamping(this._btConstraint,t,i,r))}setEquilibriumPoint(t,i){e.Physics3D._bullet.btGeneric6DofSpring2Constraint_setEquilibriumPoint(this._btConstraint,t,i)}enableMotor(t,i){e.Physics3D._bullet.btGeneric6DofSpring2Constraint_enableMotor(this._btConstraint,t,i)}setServo(t,i){e.Physics3D._bullet.btGeneric6DofSpring2Constraint_setServo(this._btConstraint,t,i)}setTargetVelocity(t,i){e.Physics3D._bullet.btGeneric6DofSpring2Constraint_setTargetVelocity(this._btConstraint,t,i)}setTargetPosition(t,i){e.Physics3D._bullet.btGeneric6DofSpring2Constraint_setServoTarget(this._btConstraint,t,i)}setMaxMotorForce(t,i){e.Physics3D._bullet.btGeneric6DofSpring2Constraint_setMaxMotorForce(this._btConstraint,t,i)}setParam(t,i,r){e.Physics3D._bullet.btTypedConstraint_setParam(this._btConstraint,t,i,r)}setFrames(){super.setFrames();var t=e.Physics3D._bullet;this._btConstraint&&t.btGeneric6DofSpring2Constraint_setFrames(this._btConstraint,this._btframATrans,this._btframBTrans)}_addToSimulation(){this._simulation&&this._simulation.addConstraint(this,this.enabled)}_removeFromSimulation(){this._simulation.removeConstraint(this),this._simulation=null}_createConstraint(){var t=e.Physics3D._bullet;this._btConstraint=t.btGeneric6DofSpring2Constraint_create(this.ownBody.btColliderObject,this._btframAPos,this.connectedBody.btColliderObject,this._btframBPos,V.RO_XYZ),this._btJointFeedBackObj=t.btJointFeedback_create(this._btConstraint),t.btTypedConstraint_setJointFeedback(this._btConstraint,this._btJointFeedBackObj),this._simulation=this.owner._scene.physicsSimulation,this._initAllConstraintInfo(),this._addToSimulation(),e.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,!0)}_initAllConstraintInfo(){this.setLimit(V.MOTION_LINEAR_INDEX_X,this._xMotion,-this._maxLinearLimit.x,-this._minLinearLimit.x),this.setLimit(V.MOTION_LINEAR_INDEX_Y,this._yMotion,this._minLinearLimit.y,this._maxLinearLimit.y),this.setLimit(V.MOTION_LINEAR_INDEX_Z,this._zMotion,this._minLinearLimit.z,this._maxLinearLimit.z),this.setLimit(V.MOTION_ANGULAR_INDEX_X,this._angularXMotion,-this._maxAngularLimit.x,-this._minAngularLimit.x),this.setLimit(V.MOTION_ANGULAR_INDEX_Y,this._angularYMotion,this._minAngularLimit.y,this._maxAngularLimit.y),this.setLimit(V.MOTION_ANGULAR_INDEX_Z,this._angularZMotion,this._minAngularLimit.z,this._maxAngularLimit.z),this.setSpring(V.MOTION_LINEAR_INDEX_X,this._linearLimitSpring.x),this.setSpring(V.MOTION_LINEAR_INDEX_Y,this._linearLimitSpring.y),this.setSpring(V.MOTION_LINEAR_INDEX_Z,this._linearLimitSpring.z),this.setSpring(V.MOTION_ANGULAR_INDEX_X,this._angularLimitSpring.x),this.setSpring(V.MOTION_ANGULAR_INDEX_Y,this._angularLimitSpring.y),this.setSpring(V.MOTION_ANGULAR_INDEX_Z,this._angularLimitSpring.z),this.setBounce(V.MOTION_LINEAR_INDEX_X,this._linearBounce.x),this.setBounce(V.MOTION_LINEAR_INDEX_Y,this._linearBounce.y),this.setBounce(V.MOTION_LINEAR_INDEX_Z,this._linearBounce.z),this.setBounce(V.MOTION_ANGULAR_INDEX_X,this._angularBounce.x),this.setBounce(V.MOTION_ANGULAR_INDEX_Y,this._angularBounce.y),this.setBounce(V.MOTION_ANGULAR_INDEX_Z,this._angularBounce.z),this.setDamping(V.MOTION_LINEAR_INDEX_X,this._linearDamp.x),this.setDamping(V.MOTION_LINEAR_INDEX_Y,this._linearDamp.y),this.setDamping(V.MOTION_LINEAR_INDEX_Z,this._linearDamp.z),this.setDamping(V.MOTION_ANGULAR_INDEX_X,this._angularDamp.x),this.setDamping(V.MOTION_ANGULAR_INDEX_Y,this._angularDamp.y),this.setDamping(V.MOTION_ANGULAR_INDEX_Z,this._angularDamp.z),this.setFrames(),this.setEquilibriumPoint(0,0)}_onAdded(){super._onAdded()}_onEnable(){this._btConstraint&&(super._onEnable(),this._btConstraint&&e.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,!0))}_onDisable(){super._onDisable(),!this.connectedBody&&this._simulation&&this._removeFromSimulation(),this._btConstraint&&e.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,!1)}_parse(t,e=null){super._parse(t),this._axis.fromArray(t.axis),this._secondaryAxis.fromArray(t.secondaryAxis);var i=t.linearLimit;this._minLinearLimit.setValue(-i,-i,-i),this._maxLinearLimit.setValue(i,i,i);var r=t.linearLimitSpring;this._linearLimitSpring.setValue(r,r,r);var n=t.linearLimitDamper;this._linearDamp.setValue(n,n,n);var a=t.linearLimitBounciness;this._linearBounce.setValue(a,a,a);var o=t.lowAngularXLimit,f=t.highAngularXLimit,_=t.angularYLimit,h=t.angularZLimit;this._minAngularLimit.setValue(o,-_,-h),this._maxAngularLimit.setValue(f,_,h);var d=t.highAngularXLimitBounciness,C=t.angularYLimitBounciness,g=t.angularZLimitBounciness;this._angularBounce.setValue(d,C,g);var m=t.angularXLimitSpring,v=t.angularYZLimitSpring;this._angularLimitSpring.setValue(m,v,v);var y=t.angularXLimitDamper,p=t.angularYZLimitDamper;this._angularDamp.setValue(y,p,p),this.XMotion=t.xMotion,this.YMotion=t.yMotion,this.ZMotion=t.zMotion,this.angularXMotion=t.angularXMotion,this.angularYMotion=t.angularYMotion,this.angularZMotion=t.angularZMotion,-1!=t.rigidbodyID&&-1!=t.connectRigidbodyID&&(e.component.push(this),e.data.push(t)),null!=t.breakForce&&(this.breakForce=t.breakForce),null!=t.breakTorque&&(this.breakTorque=t.breakTorque)}_parseInteractive(t=null,e=null){var i=e[t.rigidbodyID].getComponent(E),r=e[t.connectRigidbodyID].getComponent(E);this.ownBody=i,this.connectedBody=r}_onDestroy(){super._onDestroy()}}V.CONFIG_MOTION_TYPE_LOCKED=0,V.CONFIG_MOTION_TYPE_LIMITED=1,V.CONFIG_MOTION_TYPE_FREE=2,V.MOTION_LINEAR_INDEX_X=0,V.MOTION_LINEAR_INDEX_Y=1,V.MOTION_LINEAR_INDEX_Z=2,V.MOTION_ANGULAR_INDEX_X=3,V.MOTION_ANGULAR_INDEX_Y=4,V.MOTION_ANGULAR_INDEX_Z=5,V.RO_XYZ=0,V.RO_XZY=1,V.RO_YXZ=2,V.RO_YZX=3,V.RO_ZXY=4,V.RO_ZYX=5;class G extends i{constructor(t,r){super(),this._normal=t,this._offset=r,this._type=i.SHAPETYPES_STATICPLANE;var n=e.ILaya3D.Physics3D._bullet;n.btVector3_setValue(G._btNormal,-t.x,t.y,t.z),this._btShape=n.btStaticPlaneShape_create(G._btNormal,r)}static __init__(){G._btNormal=e.ILaya3D.Physics3D._bullet.btVector3_create(0,0,0)}clone(){var t=new G(this._normal,this._offset);return this.cloneTo(t),t}}t.BoxColliderShape=r,t.BulletInteractive=C,t.CapsuleColliderShape=n,t.CharacterController=g,t.ColliderShape=i,t.Collision=m,t.CollisionTool=p,t.CompoundColliderShape=a,t.ConeColliderShape=o,t.ConfigurableConstraint=V,t.Constraint3D=class{constructor(){}},t.ConstraintComponent=F,t.ContactPoint=v,t.CylinderColliderShape=f,t.FixedConstraint=class extends F{constructor(){super(F.CONSTRAINT_FIXED_CONSTRAINT_TYPE),this.breakForce=-1,this.breakTorque=-1}_addToSimulation(){this._simulation&&this._simulation.addConstraint(this,this.enabled)}_removeFromSimulation(){this._simulation.removeConstraint(this),this._simulation=null}_createConstraint(){if(this.ownBody&&this.ownBody._simulation&&this.connectedBody&&this.connectedBody._simulation){var t=e.Physics3D._bullet;this._btConstraint=t.btFixedConstraint_create(this.ownBody.btColliderObject,this._btframATrans,this.connectedBody.btColliderObject,this._btframBTrans),this._btJointFeedBackObj=t.btJointFeedback_create(this._btConstraint),t.btTypedConstraint_setJointFeedback(this._btConstraint,this._btJointFeedBackObj),this._simulation=this.owner._scene.physicsSimulation,this._addToSimulation(),e.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,!0)}}_onAdded(){super._onAdded()}_onEnable(){this._btConstraint&&(super._onEnable(),this._btConstraint&&e.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,!0))}_onDisable(){super._onDisable(),this.connectedBody||this._removeFromSimulation(),this._btConstraint&&e.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,!1)}_onDestroy(){super._onDestroy()}_parse(t,e=null){super._parse(t),-1!=t.rigidbodyID&&-1!=t.connectRigidbodyID&&(e.component.push(this),e.data.push(t)),null!=t.breakForce&&(this.breakForce=t.breakForce),null!=t.breakTorque&&(this.breakTorque=t.breakTorque)}_parseInteractive(t=null,e=null){var i=e[t.rigidbodyID].getComponent(E),r=e[t.connectRigidbodyID].getComponent(E);this.ownBody=i,this.connectedBody=r}},t.HitResult=y,t.MeshColliderShape=_,t.PhysicsCollider=class extends R{constructor(t=e.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER,i=e.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER){super(t,i),this._enableProcessCollisions=!1}_addToSimulation(){this._simulation._addPhysicsCollider(this,this._collisionGroup,this._canCollideWith)}_removeFromSimulation(){this._simulation._removePhysicsCollider(this)}_parse(t){null!=t.friction&&(this.friction=t.friction),null!=t.rollingFriction&&(this.rollingFriction=t.rollingFriction),null!=t.restitution&&(this.restitution=t.restitution),null!=t.isTrigger&&(this.isTrigger=t.isTrigger),super._parse(t),this._parseShape(t.shapes)}_onAdded(){var t=e.Physics3D._bullet,i=t.btCollisionObject_create();t.btCollisionObject_setUserIndex(i,this.id),t.btCollisionObject_forceActivationState(i,d.ACTIVATIONSTATE_DISABLE_SIMULATION);var r=t.btCollisionObject_getCollisionFlags(i);this.owner.isStatic?((r&d.COLLISIONFLAGS_KINEMATIC_OBJECT)>0&&(r^=d.COLLISIONFLAGS_KINEMATIC_OBJECT),r|=d.COLLISIONFLAGS_STATIC_OBJECT):((r&d.COLLISIONFLAGS_STATIC_OBJECT)>0&&(r^=d.COLLISIONFLAGS_STATIC_OBJECT),r|=d.COLLISIONFLAGS_KINEMATIC_OBJECT),t.btCollisionObject_setCollisionFlags(i,r),this._btColliderObject=i,super._onAdded()}},t.PhysicsComponent=d,t.PhysicsSettings=class{constructor(){this.flags=0,this.maxSubSteps=1,this.fixedTimeStep=1/60}},t.PhysicsSimulation=B,t.PhysicsTriggerComponent=R,t.PhysicsUpdateList=D,t.Rigidbody3D=E,t.SphereColliderShape=h,t.StaticPlaneColliderShape=G}(window.Laya=window.Laya||{},Laya); \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/min/laya.physics3D.runtime.min.js b/examples/layaair/frontend/bin/libs/min/laya.physics3D.runtime.min.js new file mode 100644 index 0000000..db527d1 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/min/laya.physics3D.runtime.min.js @@ -0,0 +1 @@ +window.Physics3D=function(n,o){window.conch.setGetWorldTransformFunction(o.getWorldTransform),window.conch.setSetWorldTransformFunction(o.setWorldTransform);var r=window.layaConchBullet;return r.then=n=>{n()},window.Physics3D=r,r}; \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/min/laya.physics3D.wasm-wx.min.js b/examples/layaair/frontend/bin/libs/min/laya.physics3D.wasm-wx.min.js new file mode 100644 index 0000000..6ef80ae --- /dev/null +++ b/examples/layaair/frontend/bin/libs/min/laya.physics3D.wasm-wx.min.js @@ -0,0 +1 @@ +window.Physics3D=function(t,i){return new Promise(e=>{var s=new WXWebAssembly.Memory({initial:t});WXWebAssembly.instantiate("libs/min/laya.physics3D.wasm.wasm",{LayaAirInteractive:i,wasi_unstable:{fd_close:()=>{console.log("fd_close")},fd_seek:()=>{console.log("fd_seek")},fd_write:()=>{console.log("fd_write")}},env:{memory:s}}).then(t=>{window.Physics3D=t.instance.exports,e()})})},function(t,i){"use strict";class e{constructor(){this._scale=new i.Vector3(1,1,1),this._centerMatrix=new i.Matrix4x4,this._attatched=!1,this._indexInCompound=-1,this._compoundParent=null,this._attatchedCollisionObject=null,this._referenceCount=0,this._localOffset=new i.Vector3(0,0,0),this._localRotation=new i.Quaternion(0,0,0,1),this.needsCustomCollisionCallback=!1}static __init__(){var t=i.ILaya3D.Physics3D._bullet;e._btScale=t.btVector3_create(1,1,1),e._btVector30=t.btVector3_create(0,0,0),e._btQuaternion0=t.btQuaternion_create(0,0,0,1),e._btTransform0=t.btTransform_create()}static _createAffineTransformation(t,i,e){var s=i.x,o=i.y,r=i.z,a=i.w,n=s+s,l=o+o,_=r+r,h=s*n,c=s*l,b=s*_,d=o*l,u=o*_,C=r*_,y=a*n,m=a*l,p=a*_;e[0]=1-(d+C),e[1]=c+p,e[2]=b-m,e[3]=0,e[4]=c-p,e[5]=1-(h+C),e[6]=u+y,e[7]=0,e[8]=b+m,e[9]=u-y,e[10]=1-(h+d),e[11]=0,e[12]=t.x,e[13]=t.y,e[14]=t.z,e[15]=1}get type(){return this._type}get localOffset(){return this._localOffset}set localOffset(t){this._localOffset=t,this._compoundParent&&this._compoundParent._updateChildTransform(this)}get localRotation(){return this._localRotation}set localRotation(t){this._localRotation=t,this._compoundParent&&this._compoundParent._updateChildTransform(this)}_setScale(t){if(this._compoundParent)this.updateLocalTransformations();else{var s=i.ILaya3D.Physics3D._bullet;s.btVector3_setValue(e._btScale,t.x,t.y,t.z),s.btCollisionShape_setLocalScaling(this._btShape,e._btScale)}}_addReference(){this._referenceCount++}_removeReference(){this._referenceCount--}updateLocalTransformations(){if(this._compoundParent){var t=e._tempVector30;i.Vector3.multiply(this.localOffset,this._scale,t),e._createAffineTransformation(t,this.localRotation,this._centerMatrix.elements)}else e._createAffineTransformation(this.localOffset,this.localRotation,this._centerMatrix.elements)}cloneTo(t){var i=t;this._localOffset.cloneTo(i.localOffset),this._localRotation.cloneTo(i.localRotation),i.localOffset=i.localOffset,i.localRotation=i.localRotation}clone(){return null}destroy(){this._btShape&&(i.ILaya3D.Physics3D._bullet.btCollisionShape_destroy(this._btShape),this._btShape=null)}}e.SHAPEORIENTATION_UPX=0,e.SHAPEORIENTATION_UPY=1,e.SHAPEORIENTATION_UPZ=2,e.SHAPETYPES_BOX=0,e.SHAPETYPES_SPHERE=1,e.SHAPETYPES_CYLINDER=2,e.SHAPETYPES_CAPSULE=3,e.SHAPETYPES_CONVEXHULL=4,e.SHAPETYPES_COMPOUND=5,e.SHAPETYPES_STATICPLANE=6,e.SHAPETYPES_CONE=7,e._tempVector30=new i.Vector3;class s extends e{constructor(t=1,o=1,r=1){super(),this._sizeX=t,this._sizeY=o,this._sizeZ=r,this._type=e.SHAPETYPES_BOX;var a=i.ILaya3D.Physics3D._bullet;a.btVector3_setValue(s._btSize,t/2,o/2,r/2),this._btShape=a.btBoxShape_create(s._btSize)}static __init__(){s._btSize=i.ILaya3D.Physics3D._bullet.btVector3_create(0,0,0)}get sizeX(){return this._sizeX}get sizeY(){return this._sizeY}get sizeZ(){return this._sizeZ}clone(){var t=new s(this._sizeX,this._sizeY,this._sizeZ);return this.cloneTo(t),t}}class o extends e{constructor(t=.5,s=1.25,o=e.SHAPEORIENTATION_UPY){super(),this._radius=t,this._length=s,this._orientation=o,this._type=e.SHAPETYPES_CAPSULE;var r=i.ILaya3D.Physics3D._bullet;switch(o){case e.SHAPEORIENTATION_UPX:this._btShape=r.btCapsuleShapeX_create(t,s-2*t);break;case e.SHAPEORIENTATION_UPY:this._btShape=r.btCapsuleShape_create(t,s-2*t);break;case e.SHAPEORIENTATION_UPZ:this._btShape=r.btCapsuleShapeZ_create(t,s-2*t);break;default:throw"CapsuleColliderShape:unknown orientation."}}get radius(){return this._radius}get length(){return this._length}get orientation(){return this._orientation}_setScale(t){var i=o._tempVector30;switch(this.orientation){case e.SHAPEORIENTATION_UPX:i.x=t.x,i.y=i.z=Math.max(t.y,t.z);break;case e.SHAPEORIENTATION_UPY:i.y=t.y,i.x=i.z=Math.max(t.x,t.z);break;case e.SHAPEORIENTATION_UPZ:i.z=t.z,i.x=i.y=Math.max(t.x,t.y);break;default:throw"CapsuleColliderShape:unknown orientation."}super._setScale(i)}clone(){var t=new o(this._radius,this._length,this._orientation);return this.cloneTo(t),t}}o._tempVector30=new i.Vector3;class r extends e{constructor(){super(),this._childColliderShapes=[],this._type=e.SHAPETYPES_COMPOUND,this._btShape=i.ILaya3D.Physics3D._bullet.btCompoundShape_create()}static __init__(){var t=i.ILaya3D.Physics3D._bullet;r._btVector3One=t.btVector3_create(1,1,1),r._btTransform=t.btTransform_create(),r._btOffset=t.btVector3_create(0,0,0),r._btRotation=t.btQuaternion_create(0,0,0,1)}_clearChildShape(t){t._attatched=!1,t._compoundParent=null,t._indexInCompound=-1}_addReference(){}_removeReference(){}_updateChildTransform(t){var s=i.ILaya3D.Physics3D._bullet,o=t.localOffset,r=t.localRotation,a=e._btVector30,n=e._btQuaternion0,l=e._btTransform0;s.btVector3_setValue(a,-o.x,o.y,o.z),s.btQuaternion_setValue(n,-r.x,r.y,r.z,-r.w),s.btTransform_setOrigin(l,a),s.btTransform_setRotation(l,n),s.btCompoundShape_updateChildTransform(this._btShape,t._indexInCompound,l,!0)}addChildShape(t){if(t._attatched)throw"CompoundColliderShape: this shape has attatched to other entity.";t._attatched=!0,t._compoundParent=this,t._indexInCompound=this._childColliderShapes.length,this._childColliderShapes.push(t);var e=t.localOffset,s=t.localRotation,o=i.ILaya3D.Physics3D._bullet;o.btVector3_setValue(r._btOffset,-e.x,e.y,e.z),o.btQuaternion_setValue(r._btRotation,-s.x,s.y,s.z,-s.w),o.btTransform_setOrigin(r._btTransform,r._btOffset),o.btTransform_setRotation(r._btTransform,r._btRotation);var a=o.btCollisionShape_getLocalScaling(this._btShape);o.btCollisionShape_setLocalScaling(this._btShape,r._btVector3One),o.btCompoundShape_addChildShape(this._btShape,r._btTransform,t._btShape),o.btCollisionShape_setLocalScaling(this._btShape,a),this._attatchedCollisionObject&&(this._attatchedCollisionObject.colliderShape=this)}removeChildShape(t){if(t._compoundParent===this){var e=t._indexInCompound;this._clearChildShape(t);var s=this._childColliderShapes[this._childColliderShapes.length-1];s._indexInCompound=e,this._childColliderShapes[e]=s,this._childColliderShapes.pop(),i.ILaya3D.Physics3D._bullet.btCompoundShape_removeChildShapeByIndex(this._btShape,e)}}clearChildShape(){for(var t=0,e=this._childColliderShapes.length;t0&&s.btCollisionObject_setCollisionFlags(e,o^h.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK)}_onAdded(){this.enabled=this._enabled,this.restitution=this._restitution,this.friction=this._friction,this.rollingFriction=this._rollingFriction,this.ccdMotionThreshold=this._ccdMotionThreshold,this.ccdSweptSphereRadius=this._ccdSweptSphereRadius,this.owner.transform.on(i.Event.TRANSFORM_CHANGED,this,this._onTransformChanged)}_onTransformChanged(t){!h._addUpdateList&&this._controlBySimulation||(t&=i.Transform3D.TRANSFORM_WORLDPOSITION|i.Transform3D.TRANSFORM_WORLDQUATERNION|i.Transform3D.TRANSFORM_WORLDSCALE)&&(this._transformFlag|=t,this._isValid()&&-1===this._inPhysicUpdateListIndex&&this._simulation._physicsUpdateList.add(this))}_cloneTo(t){var i=t;i.restitution=this._restitution,i.friction=this._friction,i.rollingFriction=this._rollingFriction,i.ccdMotionThreshold=this._ccdMotionThreshold,i.ccdSweptSphereRadius=this._ccdSweptSphereRadius,i.collisionGroup=this._collisionGroup,i.canCollideWith=this._canCollideWith,i.canScaleShape=this.canScaleShape,this._colliderShape&&(i.colliderShape=this._colliderShape.clone())}}h.ACTIVATIONSTATE_ACTIVE_TAG=1,h.ACTIVATIONSTATE_ISLAND_SLEEPING=2,h.ACTIVATIONSTATE_WANTS_DEACTIVATION=3,h.ACTIVATIONSTATE_DISABLE_DEACTIVATION=4,h.ACTIVATIONSTATE_DISABLE_SIMULATION=5,h.COLLISIONFLAGS_STATIC_OBJECT=1,h.COLLISIONFLAGS_KINEMATIC_OBJECT=2,h.COLLISIONFLAGS_NO_CONTACT_RESPONSE=4,h.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK=8,h.COLLISIONFLAGS_CHARACTER_OBJECT=16,h.COLLISIONFLAGS_DISABLE_VISUALIZE_OBJECT=32,h.COLLISIONFLAGS_DISABLE_SPU_COLLISION_PROCESSING=64,h._tempVector30=new i.Vector3,h._tempQuaternion0=new i.Quaternion,h._tempQuaternion1=new i.Quaternion,h._tempMatrix4x40=new i.Matrix4x4,h._physicObjectsMap={},h._addUpdateList=!0;class c{}c._interactive={getWorldTransform:(t,i)=>{},setWorldTransform:(t,i)=>{var e=h._physicObjectsMap[t];e._simulation._updatedRigidbodies++,e._updateTransformComponent(i)}};class b extends h{constructor(t=.1,e=null,s=i.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER,o=i.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER){super(s,o),this._upAxis=new i.Vector3(0,1,0),this._maxSlope=45,this._jumpSpeed=10,this._fallSpeed=55,this._gravity=new i.Vector3(0,3*-9.8,0),this._btKinematicCharacter=null,this._stepHeight=t,e&&(this._upAxis=e),this._controlBySimulation=!0}static __init__(){b._btTempVector30=i.ILaya3D.Physics3D._bullet.btVector3_create(0,0,0)}get fallSpeed(){return this._fallSpeed}set fallSpeed(t){this._fallSpeed=t,i.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setFallSpeed(this._btKinematicCharacter,t)}get jumpSpeed(){return this._jumpSpeed}set jumpSpeed(t){this._jumpSpeed=t,i.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setJumpSpeed(this._btKinematicCharacter,t)}get gravity(){return this._gravity}set gravity(t){this._gravity=t;var e=i.ILaya3D.Physics3D._bullet,s=b._btTempVector30;e.btVector3_setValue(s,-t.x,t.y,t.z),e.btKinematicCharacterController_setGravity(this._btKinematicCharacter,s)}get maxSlope(){return this._maxSlope}set maxSlope(t){this._maxSlope=t,i.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setMaxSlope(this._btKinematicCharacter,t/180*Math.PI)}get isGrounded(){return i.ILaya3D.Physics3D._bullet.btKinematicCharacterController_onGround(this._btKinematicCharacter)}get stepHeight(){return this._stepHeight}set stepHeight(t){this._stepHeight=t,i.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setStepHeight(this._btKinematicCharacter,t)}get upAxis(){return this._upAxis}set upAxis(t){this._upAxis=t;var e=b._btTempVector30;i.Utils3D._convertToBulletVec3(t,e,!1),i.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setUp(this._btKinematicCharacter,e)}_constructCharacter(){var t=i.ILaya3D.Physics3D._bullet;this._btKinematicCharacter&&t.btKinematicCharacterController_destroy(this._btKinematicCharacter);var e=b._btTempVector30;t.btVector3_setValue(e,this._upAxis.x,this._upAxis.y,this._upAxis.z),this._btKinematicCharacter=t.btKinematicCharacterController_create(this._btColliderObject,this._colliderShape._btShape,this._stepHeight,e),this.fallSpeed=this._fallSpeed,this.maxSlope=this._maxSlope,this.jumpSpeed=this._jumpSpeed,this.gravity=this._gravity}_onShapeChange(t){super._onShapeChange(t),this._constructCharacter()}_onAdded(){var t=i.ILaya3D.Physics3D._bullet,e=t.btPairCachingGhostObject_create();t.btCollisionObject_setUserIndex(e,this.id),t.btCollisionObject_setCollisionFlags(e,h.COLLISIONFLAGS_CHARACTER_OBJECT),this._btColliderObject=e,this._colliderShape&&this._constructCharacter(),super._onAdded()}_addToSimulation(){this._simulation._characters.push(this),this._simulation._addCharacter(this,this._collisionGroup,this._canCollideWith)}_removeFromSimulation(){this._simulation._removeCharacter(this);var t=this._simulation._characters;t.splice(t.indexOf(this),1)}_cloneTo(t){super._cloneTo(t);var i=t;i.stepHeight=this._stepHeight,i.upAxis=this._upAxis,i.maxSlope=this._maxSlope,i.jumpSpeed=this._jumpSpeed,i.fallSpeed=this._fallSpeed,i.gravity=this._gravity}_onDestroy(){i.ILaya3D.Physics3D._bullet.btKinematicCharacterController_destroy(this._btKinematicCharacter),super._onDestroy(),this._btKinematicCharacter=null}move(t){var e=b._btVector30,s=i.ILaya3D.Physics3D._bullet;s.btVector3_setValue(e,-t.x,t.y,t.z),s.btKinematicCharacterController_setWalkDirection(this._btKinematicCharacter,e)}jump(t=null){var e=i.ILaya3D.Physics3D._bullet,s=b._btVector30;t?(i.Utils3D._convertToBulletVec3(t,s,!0),e.btKinematicCharacterController_jump(this._btKinematicCharacter,s)):(e.btVector3_setValue(s,0,0,0),e.btKinematicCharacterController_jump(this._btKinematicCharacter,s))}}b.UPAXIS_X=0,b.UPAXIS_Y=1,b.UPAXIS_Z=2;class d{constructor(){this._lastUpdateFrame=-2147483648,this._updateFrame=-2147483648,this._isTrigger=!1,this.contacts=[]}_setUpdateFrame(t){this._lastUpdateFrame=this._updateFrame,this._updateFrame=t}}class u{constructor(){this._idCounter=0,this.colliderA=null,this.colliderB=null,this.distance=0,this.normal=new i.Vector3,this.positionOnA=new i.Vector3,this.positionOnB=new i.Vector3,this._id=++this._idCounter}}class C{constructor(){this.succeeded=!1,this.collider=null,this.point=new i.Vector3,this.normal=new i.Vector3,this.hitFraction=0}}class y{constructor(){this._hitResultsPoolIndex=0,this._hitResultsPool=[],this._contactPonintsPoolIndex=0,this._contactPointsPool=[],this._collisionsPool=[],this._collisions={}}getHitResult(){var t=this._hitResultsPool[this._hitResultsPoolIndex++];return t||(t=new C,this._hitResultsPool.push(t)),t}recoverAllHitResultsPool(){this._hitResultsPoolIndex=0}getContactPoints(){var t=this._contactPointsPool[this._contactPonintsPoolIndex++];return t||(t=new u,this._contactPointsPool.push(t)),t}recoverAllContactPointsPool(){this._contactPonintsPoolIndex=0}getCollision(t,i){var e,s=t.id,o=i.id,r=this._collisions[s];return r&&(e=r[o]),e||(r||(r={},this._collisions[s]=r),(e=0===this._collisionsPool.length?new d:this._collisionsPool.pop())._colliderA=t,e._colliderB=i,r[o]=e),e}recoverCollision(t){var i=t._colliderA.id,e=t._colliderB.id;this._collisions[i][e]=null,this._collisionsPool.push(t)}garbageCollection(){for(var t in this._hitResultsPoolIndex=0,this._hitResultsPool.length=0,this._contactPonintsPoolIndex=0,this._contactPointsPool.length=0,this._collisionsPool.length=0,this._collisionsPool){var i=this._collisionsPool[t],e=!0;for(var s in i)i[s]?e=!1:delete i[s];e&&delete this._collisionsPool[t]}}}class m extends h{constructor(t,i){super(t,i),this._isTrigger=!1}get isTrigger(){return this._isTrigger}set isTrigger(t){this._isTrigger=t;var e=i.ILaya3D.Physics3D._bullet;if(this._btColliderObject){var s=e.btCollisionObject_getCollisionFlags(this._btColliderObject);t?0==(s&h.COLLISIONFLAGS_NO_CONTACT_RESPONSE)&&e.btCollisionObject_setCollisionFlags(this._btColliderObject,s|h.COLLISIONFLAGS_NO_CONTACT_RESPONSE):0!=(s&h.COLLISIONFLAGS_NO_CONTACT_RESPONSE)&&e.btCollisionObject_setCollisionFlags(this._btColliderObject,s^h.COLLISIONFLAGS_NO_CONTACT_RESPONSE)}}_onAdded(){super._onAdded(),this.isTrigger=this._isTrigger}_cloneTo(t){super._cloneTo(t),t.isTrigger=this._isTrigger}}class p extends i.SingletonList{constructor(){super()}add(t){if(-1!==t._inPhysicUpdateListIndex)throw"PhysicsUpdateList:element has in PhysicsUpdateList.";this._add(t),t._inPhysicUpdateListIndex=this.length++}remove(t){var i=t._inPhysicUpdateListIndex;if(this.length--,i!==this.length){var e=this.elements[this.length];this.elements[i]=e,e._inPhysicUpdateListIndex=i}t._inPhysicUpdateListIndex=-1}}class g{constructor(t){this._gravity=new i.Vector3(0,-10,0),this._btVector3Zero=i.ILaya3D.Physics3D._bullet.btVector3_create(0,0,0),this._btDefaultQuaternion=i.ILaya3D.Physics3D._bullet.btQuaternion_create(0,0,0,-1),this._collisionsUtils=new y,this._previousFrameCollisions=[],this._currentFrameCollisions=[],this._currentConstraint={},this._physicsUpdateList=new p,this._characters=[],this._updatedRigidbodies=0,this.maxSubSteps=1,this.fixedTimeStep=1/60,this.maxSubSteps=t.maxSubSteps,this.fixedTimeStep=t.fixedTimeStep;var e=i.ILaya3D.Physics3D._bullet;this._btCollisionConfiguration=e.btDefaultCollisionConfiguration_create(),this._btDispatcher=e.btCollisionDispatcher_create(this._btCollisionConfiguration),this._btBroadphase=e.btDbvtBroadphase_create(),e.btOverlappingPairCache_setInternalGhostPairCallback(e.btDbvtBroadphase_getOverlappingPairCache(this._btBroadphase),e.btGhostPairCallback_create());var s=t.flags;if(s&g.PHYSICSENGINEFLAGS_COLLISIONSONLY)this._btCollisionWorld=new e.btCollisionWorld(this._btDispatcher,this._btBroadphase,this._btCollisionConfiguration);else{if(s&g.PHYSICSENGINEFLAGS_SOFTBODYSUPPORT)throw"PhysicsSimulation:SoftBody processing is not yet available";var o=e.btSequentialImpulseConstraintSolver_create();this._btDiscreteDynamicsWorld=e.btDiscreteDynamicsWorld_create(this._btDispatcher,this._btBroadphase,o,this._btCollisionConfiguration),this._btCollisionWorld=this._btDiscreteDynamicsWorld}this._btDiscreteDynamicsWorld&&(this._btSolverInfo=e.btDynamicsWorld_getSolverInfo(this._btDiscreteDynamicsWorld),this._btDispatchInfo=e.btCollisionWorld_getDispatchInfo(this._btDiscreteDynamicsWorld)),this._btClosestRayResultCallback=e.ClosestRayResultCallback_create(this._btVector3Zero,this._btVector3Zero),this._btAllHitsRayResultCallback=e.AllHitsRayResultCallback_create(this._btVector3Zero,this._btVector3Zero),this._btClosestConvexResultCallback=e.ClosestConvexResultCallback_create(this._btVector3Zero,this._btVector3Zero),this._btAllConvexResultCallback=e.AllConvexResultCallback_create(this._btVector3Zero,this._btVector3Zero),this.setHitsRayResultCallbackFlag(),e.btGImpactCollisionAlgorithm_RegisterAlgorithm(this._btDispatcher)}static __init__(){var t=i.ILaya3D.Physics3D._bullet;g._btTempVector30=t.btVector3_create(0,0,0),g._btTempVector31=t.btVector3_create(0,0,0),g._btTempQuaternion0=t.btQuaternion_create(0,0,0,1),g._btTempQuaternion1=t.btQuaternion_create(0,0,0,1),g._btTempTransform0=t.btTransform_create(),g._btTempTransform1=t.btTransform_create()}static createConstraint(){}get continuousCollisionDetection(){return i.ILaya3D.Physics3D._bullet.btCollisionWorld_get_m_useContinuous(this._btDispatchInfo)}set continuousCollisionDetection(t){i.ILaya3D.Physics3D._bullet.btCollisionWorld_set_m_useContinuous(this._btDispatchInfo,t)}get gravity(){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";return this._gravity}set gravity(t){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";this._gravity=t;var e=i.ILaya3D.Physics3D._bullet,s=g._btTempVector30;e.btVector3_setValue(s,-t.x,t.y,t.z),e.btDiscreteDynamicsWorld_setGravity(this._btDiscreteDynamicsWorld,s)}get speculativeContactRestitution(){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot Cannot perform this action when the physics engine is set to CollisionsOnly";return i.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_getApplySpeculativeContactRestitution(this._btDiscreteDynamicsWorld)}set speculativeContactRestitution(t){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot Cannot perform this action when the physics engine is set to CollisionsOnly";i.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_setApplySpeculativeContactRestitution(this._btDiscreteDynamicsWorld,t)}_simulate(t){this._updatedRigidbodies=0;var e=i.ILaya3D.Physics3D._bullet;this._btDiscreteDynamicsWorld?e.btDiscreteDynamicsWorld_stepSimulation(this._btDiscreteDynamicsWorld,t,this.maxSubSteps,this.fixedTimeStep):e.PerformDiscreteCollisionDetection(this._btCollisionWorld)}_destroy(){var t=i.ILaya3D.Physics3D._bullet;this._btDiscreteDynamicsWorld?(t.btCollisionWorld_destroy(this._btDiscreteDynamicsWorld),this._btDiscreteDynamicsWorld=null):(t.btCollisionWorld_destroy(this._btCollisionWorld),this._btCollisionWorld=null),t.btDbvtBroadphase_destroy(this._btBroadphase),this._btBroadphase=null,t.btCollisionDispatcher_destroy(this._btDispatcher),this._btDispatcher=null,t.btDefaultCollisionConfiguration_destroy(this._btCollisionConfiguration),this._btCollisionConfiguration=null}_addPhysicsCollider(t,e,s){i.ILaya3D.Physics3D._bullet.btCollisionWorld_addCollisionObject(this._btCollisionWorld,t._btColliderObject,e,s)}_removePhysicsCollider(t){i.ILaya3D.Physics3D._bullet.btCollisionWorld_removeCollisionObject(this._btCollisionWorld,t._btColliderObject)}_addRigidBody(t,e,s){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";i.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_addRigidBody(this._btCollisionWorld,t._btColliderObject,e,s)}_removeRigidBody(t){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";i.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_removeRigidBody(this._btCollisionWorld,t._btColliderObject)}_addCharacter(t,e,s){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";var o=i.ILaya3D.Physics3D._bullet;o.btCollisionWorld_addCollisionObject(this._btCollisionWorld,t._btColliderObject,e,s),o.btDynamicsWorld_addAction(this._btCollisionWorld,t._btKinematicCharacter)}_removeCharacter(t){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";var e=i.ILaya3D.Physics3D._bullet;e.btCollisionWorld_removeCollisionObject(this._btCollisionWorld,t._btColliderObject),e.btDynamicsWorld_removeAction(this._btCollisionWorld,t._btKinematicCharacter)}raycastFromTo(t,e,s=null,o=i.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER,r=i.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER){var a=i.ILaya3D.Physics3D._bullet,n=this._btClosestRayResultCallback,l=g._btTempVector30,_=g._btTempVector31;if(a.btVector3_setValue(l,-t.x,t.y,t.z),a.btVector3_setValue(_,-e.x,e.y,e.z),a.ClosestRayResultCallback_set_m_rayFromWorld(n,l),a.ClosestRayResultCallback_set_m_rayToWorld(n,_),a.RayResultCallback_set_m_collisionFilterGroup(n,o),a.RayResultCallback_set_m_collisionFilterMask(n,r),a.RayResultCallback_set_m_collisionObject(n,null),a.RayResultCallback_set_m_closestHitFraction(n,1),a.btCollisionWorld_rayTest(this._btCollisionWorld,l,_,n),a.RayResultCallback_hasHit(n)){if(s){s.succeeded=!0,s.collider=h._physicObjectsMap[a.btCollisionObject_getUserIndex(a.RayResultCallback_get_m_collisionObject(n))],s.hitFraction=a.RayResultCallback_get_m_closestHitFraction(n);var c=a.ClosestRayResultCallback_get_m_hitPointWorld(n),b=s.point;b.x=-a.btVector3_x(c),b.y=a.btVector3_y(c),b.z=a.btVector3_z(c);var d=a.ClosestRayResultCallback_get_m_hitNormalWorld(n),u=s.normal;u.x=-a.btVector3_x(d),u.y=a.btVector3_y(d),u.z=a.btVector3_z(d)}return!0}return s&&(s.succeeded=!1),!1}raycastAllFromTo(t,e,s,o=i.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER,r=i.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER){var a=i.ILaya3D.Physics3D._bullet,n=this._btAllHitsRayResultCallback,l=g._btTempVector30,_=g._btTempVector31;s.length=0,a.btVector3_setValue(l,-t.x,t.y,t.z),a.btVector3_setValue(_,-e.x,e.y,e.z),a.AllHitsRayResultCallback_set_m_rayFromWorld(n,l),a.AllHitsRayResultCallback_set_m_rayToWorld(n,_),a.RayResultCallback_set_m_collisionFilterGroup(n,o),a.RayResultCallback_set_m_collisionFilterMask(n,r);var c=a.AllHitsRayResultCallback_get_m_collisionObjects(n),b=a.AllHitsRayResultCallback_get_m_hitPointWorld(n),d=a.AllHitsRayResultCallback_get_m_hitNormalWorld(n),u=a.AllHitsRayResultCallback_get_m_hitFractions(n);a.tBtCollisionObjectArray_clear(c),a.tVector3Array_clear(b),a.tVector3Array_clear(d),a.tScalarArray_clear(u),a.btCollisionWorld_rayTest(this._btCollisionWorld,l,_,n);var C=a.tBtCollisionObjectArray_size(c);if(C>0){this._collisionsUtils.recoverAllHitResultsPool();for(var y=0;y0){this._collisionsUtils.recoverAllHitResultsPool();for(var A=0;A0&&(r^=h.COLLISIONFLAGS_KINEMATIC_OBJECT),e.btCollisionObject_setCollisionFlags(o,r),e.btCollisionObject_setActivationState(this._btColliderObject,h.ACTIVATIONSTATE_ACTIVE_TAG),this._enableProcessCollisions=!0,this._updateMass(this._mass));var a=T._btVector3Zero;e.btCollisionObject_setInterpolationLinearVelocity(o,a),e.btRigidBody_setLinearVelocity(o,a),e.btCollisionObject_setInterpolationAngularVelocity(o,a),e.btRigidBody_setAngularVelocity(o,a),s&&this._addToSimulation()}get linearDamping(){return this._linearDamping}set linearDamping(t){this._linearDamping=t,this._btColliderObject&&i.ILaya3D.Physics3D._bullet.btRigidBody_setDamping(this._btColliderObject,t,this._angularDamping)}get angularDamping(){return this._angularDamping}set angularDamping(t){this._angularDamping=t,this._btColliderObject&&i.ILaya3D.Physics3D._bullet.btRigidBody_setDamping(this._btColliderObject,this._linearDamping,t)}get overrideGravity(){return this._overrideGravity}set overrideGravity(t){this._overrideGravity=t;var e=i.ILaya3D.Physics3D._bullet;if(this._btColliderObject){var s=e.btRigidBody_getFlags(this._btColliderObject);t?0==(s&T._BT_DISABLE_WORLD_GRAVITY)&&e.btRigidBody_setFlags(this._btColliderObject,s|T._BT_DISABLE_WORLD_GRAVITY):(s&T._BT_DISABLE_WORLD_GRAVITY)>0&&e.btRigidBody_setFlags(this._btColliderObject,s^T._BT_DISABLE_WORLD_GRAVITY)}}get gravity(){var t=i.ILaya3D.Physics3D._bullet;return T._btGravity=t.btRigidBody_getGravity(this._btColliderObject),i.Utils3D._convertToLayaVec3(T._btGravity,this._gravity,!0),this._gravity}set gravity(t){this._gravity=t;var e=i.ILaya3D.Physics3D._bullet;e.btVector3_setValue(T._btGravity,-t.x,t.y,t.z),e.btRigidBody_setGravity(this._btColliderObject,T._btGravity)}get totalForce(){if(this._btColliderObject){var t=i.ILaya3D.Physics3D._bullet.btRigidBody_getTotalForce(this._btColliderObject);return i.Utils3D._convertToLayaVec3(t,this._totalForce,!0),this._totalForce}return null}get linearFactor(){return this._linearFactor}set linearFactor(t){this._linearFactor=t;var e=T._btTempVector30;i.Utils3D._convertToBulletVec3(t,e,!1),i.ILaya3D.Physics3D._bullet.btRigidBody_setLinearFactor(this._btColliderObject,e)}get linearVelocity(){return this._btColliderObject&&i.Utils3D._convertToLayaVec3(i.ILaya3D.Physics3D._bullet.btRigidBody_getLinearVelocity(this._btColliderObject),this._linearVelocity,!0),this._linearVelocity}set linearVelocity(t){if(this._linearVelocity=t,this._btColliderObject){var e=T._btTempVector30;i.Utils3D._convertToBulletVec3(t,e,!0),this.isSleeping&&this.wakeUp(),i.ILaya3D.Physics3D._bullet.btRigidBody_setLinearVelocity(this._btColliderObject,e)}}get angularFactor(){return this._angularFactor}set angularFactor(t){this._angularFactor=t;var e=T._btTempVector30;i.Utils3D._convertToBulletVec3(t,e,!1),i.ILaya3D.Physics3D._bullet.btRigidBody_setAngularFactor(this._btColliderObject,e)}get angularVelocity(){return this._btColliderObject&&i.Utils3D._convertToLayaVec3(i.ILaya3D.Physics3D._bullet.btRigidBody_getAngularVelocity(this._btColliderObject),this._angularVelocity,!0),this._angularVelocity}set angularVelocity(t){if(this._angularVelocity=t,this._btColliderObject){var e=T._btTempVector30;i.Utils3D._convertToBulletVec3(t,e,!0),this.isSleeping&&this.wakeUp(),i.ILaya3D.Physics3D._bullet.btRigidBody_setAngularVelocity(this._btColliderObject,e)}}get totalTorque(){if(this._btColliderObject){var t=i.ILaya3D.Physics3D._bullet.btRigidBody_getTotalTorque(this._btColliderObject);return i.Utils3D._convertToLayaVec3(t,this._totalTorque,!0),this._totalTorque}return null}get detectCollisions(){return this._detectCollisions}set detectCollisions(t){this._detectCollisions!==t&&(this._detectCollisions=t,this._colliderShape&&this._enabled&&this._simulation&&(this._simulation._removeRigidBody(this),this._simulation._addRigidBody(this,this._collisionGroup,t?this._canCollideWith:0)))}get isSleeping(){return!!this._btColliderObject&&i.ILaya3D.Physics3D._bullet.btCollisionObject_getActivationState(this._btColliderObject)===h.ACTIVATIONSTATE_ISLAND_SLEEPING}get sleepLinearVelocity(){return i.ILaya3D.Physics3D._bullet.btRigidBody_getLinearSleepingThreshold(this._btColliderObject)}set sleepLinearVelocity(t){var e=i.ILaya3D.Physics3D._bullet;e.btRigidBody_setSleepingThresholds(this._btColliderObject,t,e.btRigidBody_getAngularSleepingThreshold(this._btColliderObject))}get sleepAngularVelocity(){return i.ILaya3D.Physics3D._bullet.btRigidBody_getAngularSleepingThreshold(this._btColliderObject)}set sleepAngularVelocity(t){var e=i.ILaya3D.Physics3D._bullet;e.btRigidBody_setSleepingThresholds(this._btColliderObject,e.btRigidBody_getLinearSleepingThreshold(this._btColliderObject),t)}get btColliderObject(){return this._btColliderObject}set constaintRigidbodyA(t){this._constaintRigidbodyA=t}get constaintRigidbodyA(){return this._constaintRigidbodyA}set constaintRigidbodyB(t){this._constaintRigidbodyB=t}get constaintRigidbodyB(){return this._constaintRigidbodyB}_updateMass(t){if(this._btColliderObject&&this._colliderShape){var e=i.ILaya3D.Physics3D._bullet;e.btCollisionShape_calculateLocalInertia(this._colliderShape._btShape,t,T._btInertia),e.btRigidBody_setMassProps(this._btColliderObject,t,T._btInertia),e.btRigidBody_updateInertiaTensor(this._btColliderObject)}}_onScaleChange(t){super._onScaleChange(t),this._updateMass(this._isKinematic?0:this._mass)}_derivePhysicsTransformation(t){var e=i.ILaya3D.Physics3D._bullet,s=this._btColliderObject,o=e.btCollisionObject_getWorldTransform(s),r=T._btTransform0;e.btTransform_equal(r,o),this._innerDerivePhysicsTransformation(r,t),e.btRigidBody_setCenterOfMassTransform(s,r)}_onAdded(){var t=i.ILaya3D.Physics3D._bullet,e=t.layaMotionState_create();t.layaMotionState_set_rigidBodyID(e,this._id),this._btLayaMotionState=e;var s=t.btRigidBodyConstructionInfo_create(0,e,null,T._btVector3Zero),o=t.btRigidBody_create(s);t.btCollisionObject_setUserIndex(o,this.id),this._btColliderObject=o,super._onAdded(),this.mass=this._mass,this.linearFactor=this._linearFactor,this.angularFactor=this._angularFactor,this.linearDamping=this._linearDamping,this.angularDamping=this._angularDamping,this.overrideGravity=this._overrideGravity,this.gravity=this._gravity,this.isKinematic=this._isKinematic,t.btRigidBodyConstructionInfo_destroy(s)}_onEnable(){super._onEnable(),this._constaintRigidbodyA&&this._constaintRigidbodyA.connectedBody._simulation&&(this._constaintRigidbodyA._createConstraint(),this._constaintRigidbodyA._onEnable()),this._constaintRigidbodyB&&this._constaintRigidbodyB.ownBody._simulation&&(this._constaintRigidbodyB._createConstraint(),this._constaintRigidbodyB._onEnable())}_onShapeChange(t){if(super._onShapeChange(t),this._isKinematic)this._updateMass(0);else{var e=i.ILaya3D.Physics3D._bullet;e.btRigidBody_setCenterOfMassTransform(this._btColliderObject,e.btCollisionObject_getWorldTransform(this._btColliderObject)),this._updateMass(this._mass)}}_parse(t){if(null!=t.friction&&(this.friction=t.friction),null!=t.rollingFriction&&(this.rollingFriction=t.rollingFriction),null!=t.restitution&&(this.restitution=t.restitution),null!=t.isTrigger&&(this.isTrigger=t.isTrigger),null!=t.mass&&(this.mass=t.mass),null!=t.linearDamping&&(this.linearDamping=t.linearDamping),null!=t.angularDamping&&(this.angularDamping=t.angularDamping),null!=t.overrideGravity&&(this.overrideGravity=t.overrideGravity),null!=t.linearFactor){var i=this.linearFactor;i.fromArray(t.linearFactor),this.linearFactor=i}if(null!=t.angularFactor){var e=this.angularFactor;e.fromArray(t.angularFactor),this.angularFactor=e}t.gravity&&(this.gravity.fromArray(t.gravity),this.gravity=this.gravity),super._parse(t),this._parseShape(t.shapes),null!=t.isKinematic&&(this.isKinematic=t.isKinematic)}_onDestroy(){i.ILaya3D.Physics3D._bullet.btMotionState_destroy(this._btLayaMotionState),super._onDestroy(),this._btLayaMotionState=null,this._gravity=null,this._totalTorque=null,this._linearVelocity=null,this._angularVelocity=null,this._linearFactor=null,this._angularFactor=null,this.constaintRigidbodyA&&this.constaintRigidbodyA._breakConstrained(),this.constaintRigidbodyB&&(this.constaintRigidbodyB.connectedBody=null,this.constaintRigidbodyB._onDisable())}_addToSimulation(){this._simulation._addRigidBody(this,this._collisionGroup,this._detectCollisions?this._canCollideWith:0)}_removeFromSimulation(){this._simulation._removeRigidBody(this)}_cloneTo(t){super._cloneTo(t);var i=t;i.isKinematic=this._isKinematic,i.mass=this._mass,i.gravity=this._gravity,i.angularDamping=this._angularDamping,i.linearDamping=this._linearDamping,i.overrideGravity=this._overrideGravity,i.linearVelocity=this._linearVelocity,i.angularVelocity=this._angularVelocity,i.linearFactor=this._linearFactor,i.angularFactor=this._angularFactor,i.detectCollisions=this._detectCollisions}applyForce(t,e=null){if(null==this._btColliderObject)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";var s=i.ILaya3D.Physics3D._bullet,o=T._btTempVector30;if(s.btVector3_setValue(o,-t.x,t.y,t.z),e){var r=T._btTempVector31;s.btVector3_setValue(r,-e.x,e.y,e.z),s.btRigidBody_applyForce(this._btColliderObject,o,r)}else s.btRigidBody_applyCentralForce(this._btColliderObject,o)}applyTorque(t){if(null==this._btColliderObject)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";var e=i.ILaya3D.Physics3D._bullet,s=T._btTempVector30;e.btVector3_setValue(s,-t.x,t.y,t.z),e.btRigidBody_applyTorque(this._btColliderObject,s)}applyImpulse(t,e=null){if(null==this._btColliderObject)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";var s=i.ILaya3D.Physics3D._bullet;s.btVector3_setValue(T._btImpulse,-t.x,t.y,t.z),e?(s.btVector3_setValue(T._btImpulseOffset,-e.x,e.y,e.z),s.btRigidBody_applyImpulse(this._btColliderObject,T._btImpulse,T._btImpulseOffset)):s.btRigidBody_applyCentralImpulse(this._btColliderObject,T._btImpulse)}applyTorqueImpulse(t){if(null==this._btColliderObject)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";var e=i.ILaya3D.Physics3D._bullet,s=T._btTempVector30;e.btVector3_setValue(s,-t.x,t.y,t.z),e.btRigidBody_applyTorqueImpulse(this._btColliderObject,s)}wakeUp(){this._btColliderObject&&i.ILaya3D.Physics3D._bullet.btCollisionObject_activate(this._btColliderObject,!1)}clearForces(){var t=this._btColliderObject;if(null==t)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";var e=i.ILaya3D.Physics3D._bullet;e.btRigidBody_clearForces(t);var s=T._btVector3Zero;e.btCollisionObject_setInterpolationLinearVelocity(t,s),e.btRigidBody_setLinearVelocity(t,s),e.btCollisionObject_setInterpolationAngularVelocity(t,s),e.btRigidBody_setAngularVelocity(t,s)}}T.TYPE_STATIC=0,T.TYPE_DYNAMIC=1,T.TYPE_KINEMATIC=2,T._BT_DISABLE_WORLD_GRAVITY=1,T._BT_ENABLE_GYROPSCOPIC_FORCE=2;class S extends i.Component{constructor(t){super(),this._anchor=new i.Vector3,this._connectAnchor=new i.Vector3,this._feedbackEnabled=!1,this._getJointFeedBack=!1,this._currentForce=new i.Vector3,this._currentTorque=new i.Vector3,this._constraintType=t;var e=i.Physics3D._bullet;this._btframATrans=e.btTransform_create(),this._btframBTrans=e.btTransform_create(),e.btTransform_setIdentity(this._btframATrans),e.btTransform_setIdentity(this._btframBTrans),this._btframAPos=e.btVector3_create(0,0,0),this._btframBPos=e.btVector3_create(0,0,0),e.btTransform_setOrigin(this._btframATrans,this._btframAPos),e.btTransform_setOrigin(this._btframBTrans,this._btframBPos),this._breakForce=-1,this._breakTorque=-1}get enabled(){return super.enabled}set enabled(t){super.enabled=t}get appliedImpulse(){return this._feedbackEnabled||(this._btConstraint.EnableFeedback(!0),this._feedbackEnabled=!0),this._btConstraint.AppliedImpulse}set connectedBody(t){this._connectedBody=t,t&&(t.constaintRigidbodyB=this)}get connectedBody(){return this._connectedBody}get ownBody(){return this._ownBody}set ownBody(t){this._ownBody=t,t.constaintRigidbodyA=this}get currentForce(){return this._getJointFeedBack||this._getFeedBackInfo(),this._currentForce}get currentTorque(){return this._getJointFeedBack||this._getFeedBackInfo(),this._currentTorque}get breakForce(){return this._breakForce}set breakForce(t){this._breakForce=t}get breakTorque(){return this._breakTorque}set breakTorque(t){this._breakTorque=t}set anchor(t){t.cloneTo(this._anchor),this.setFrames()}get anchor(){return this._anchor}set connectAnchor(t){t.cloneTo(this._connectAnchor),this.setFrames()}get connectAnchor(){return this._connectAnchor}setOverrideNumSolverIterations(t){i.Physics3D._bullet.btTypedConstraint_setOverrideNumSolverIterations(this._btConstraint,t)}setConstraintEnabled(t){i.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,t)}_onEnable(){super._onEnable(),this.enabled=!0}_onDisable(){super._onDisable(),this.enabled=!1}setFrames(){var t=i.Physics3D._bullet;t.btVector3_setValue(this._btframAPos,-this._anchor.x,this.anchor.y,this.anchor.z),t.btVector3_setValue(this._btframBPos,-this._connectAnchor.x,this._connectAnchor.y,this._connectAnchor.z),t.btTransform_setOrigin(this._btframATrans,this._btframAPos),t.btTransform_setOrigin(this._btframBTrans,this._btframBPos)}_addToSimulation(){}_removeFromSimulation(){}_createConstraint(){}setConnectRigidBody(t,i){var e=t&&!!(t._simulation&&t._enabled&&t.colliderShape),s=i&&!!(i._simulation&&i._enabled&&i.colliderShape);if(!e||!s)throw"ownerRigid or connectRigidBody is not in Simulation";t==this._ownBody&&i==this._connectedBody||(!(!this.enabled||!this._simulation)&&this._removeFromSimulation(),this._ownBody=t,this._connectedBody=i,this._ownBody.constaintRigidbodyA=this,this._connectedBody.constaintRigidbodyB=this,this._createConstraint())}getcurrentForce(t){if(!this._btJointFeedBackObj)throw"this Constraint is not simulation";var e=i.Physics3D._bullet,s=e.btJointFeedback_getAppliedForceBodyA(this._btJointFeedBackObj);t.setValue(e.btVector3_x(s),e.btVector3_y(s),e.btVector3_z(s))}getcurrentTorque(t){if(!this._btJointFeedBackObj)throw"this Constraint is not simulation";var e=i.Physics3D._bullet,s=e.btJointFeedback_getAppliedTorqueBodyA(this._btJointFeedBackObj);t.setValue(e.btVector3_x(s),e.btVector3_y(s),e.btVector3_z(s))}_onDestroy(){var t=i.Physics3D._bullet;this._simulation&&this._removeFromSimulation(),this._btConstraint&&this._btJointFeedBackObj&&this._simulation&&(t.btTypedConstraint_destroy(this._btConstraint),t.btJointFeedback_destroy(this._btJointFeedBackObj),this._btJointFeedBackObj=null,this._btConstraint=null),super._onDisable()}_isBreakConstrained(){if(this._getJointFeedBack=!1,-1==this.breakForce&&-1==this.breakTorque)return!1;this._getFeedBackInfo();var t=-1!=this._breakForce&&i.Vector3.scalarLength(this._currentForce)>this._breakForce,e=-1!=this._breakTorque&&i.Vector3.scalarLength(this._currentTorque)>this._breakTorque;return!(!t&&!e)&&(this._breakConstrained(),!0)}_parse(t){this._anchor.fromArray(t.anchor),this._connectAnchor.fromArray(t.connectAnchor),this.setFrames()}_getFeedBackInfo(){var t=i.Physics3D._bullet,e=t.btJointFeedback_getAppliedForceBodyA(this._btJointFeedBackObj),s=t.btJointFeedback_getAppliedTorqueBodyA(this._btJointFeedBackObj);this._currentTorque.setValue(t.btVector3_x(s),t.btVector3_y(s),t.btVector3_z(s)),this._currentForce.setValue(t.btVector3_x(e),t.btVector3_y(e),t.btVector3_z(e)),this._getJointFeedBack=!0}_breakConstrained(){this.ownBody.constaintRigidbodyA=null,this.connectedBody&&(this.connectedBody.constaintRigidbodyB=null),this.destroy()}}S.CONSTRAINT_POINT2POINT_CONSTRAINT_TYPE=3,S.CONSTRAINT_HINGE_CONSTRAINT_TYPE=4,S.CONSTRAINT_CONETWIST_CONSTRAINT_TYPE=5,S.CONSTRAINT_D6_CONSTRAINT_TYPE=6,S.CONSTRAINT_SLIDER_CONSTRAINT_TYPE=7,S.CONSTRAINT_CONTACT_CONSTRAINT_TYPE=8,S.CONSTRAINT_D6_SPRING_CONSTRAINT_TYPE=9,S.CONSTRAINT_GEAR_CONSTRAINT_TYPE=10,S.CONSTRAINT_FIXED_CONSTRAINT_TYPE=11,S.CONSTRAINT_MAX_CONSTRAINT_TYPE=12,S.CONSTRAINT_CONSTRAINT_ERP=1,S.CONSTRAINT_CONSTRAINT_STOP_ERP=2,S.CONSTRAINT_CONSTRAINT_CFM=3,S.CONSTRAINT_CONSTRAINT_STOP_CFM=4,S.tempForceV3=new i.Vector3;class I extends S{constructor(){super(S.CONSTRAINT_D6_SPRING_CONSTRAINT_TYPE),this._axis=new i.Vector3,this._secondaryAxis=new i.Vector3,this._minLinearLimit=new i.Vector3,this._maxLinearLimit=new i.Vector3,this._minAngularLimit=new i.Vector3,this._maxAngularLimit=new i.Vector3,this._linearLimitSpring=new i.Vector3,this._angularLimitSpring=new i.Vector3,this._linearBounce=new i.Vector3,this._angularBounce=new i.Vector3,this._linearDamp=new i.Vector3,this._angularDamp=new i.Vector3,this._xMotion=0,this._yMotion=0,this._zMotion=0,this._angularXMotion=0,this._angularYMotion=0,this._angularZMotion=0;var t=i.Physics3D._bullet;this._btAxis=t.btVector3_create(-1,0,0),this._btSecondaryAxis=t.btVector3_create(0,1,0)}get axis(){return this._axis}get secondaryAxis(){return this._secondaryAxis}set maxAngularLimit(t){t.cloneTo(this._maxAngularLimit)}set minAngularLimit(t){t.cloneTo(this._minAngularLimit)}get maxAngularLimit(){return this._maxAngularLimit}get minAngularLimit(){return this._minAngularLimit}set maxLinearLimit(t){t.cloneTo(this._maxLinearLimit)}set minLinearLimit(t){t.cloneTo(this._minLinearLimit)}get maxLinearLimit(){return this._maxLinearLimit}get minLinearLimit(){return this._minLinearLimit}set XMotion(t){this._xMotion!=t&&(this._xMotion=t,this.setLimit(I.MOTION_LINEAR_INDEX_X,t,-this._maxLinearLimit.x,-this._minLinearLimit.x))}get XMotion(){return this._xMotion}set YMotion(t){this._yMotion!=t&&(this._yMotion=t,this.setLimit(I.MOTION_LINEAR_INDEX_Y,t,this._minLinearLimit.y,this._maxLinearLimit.y))}get YMotion(){return this._yMotion}set ZMotion(t){this._zMotion!=t&&(this._zMotion=t,this.setLimit(I.MOTION_LINEAR_INDEX_Z,t,this._minLinearLimit.z,this._maxLinearLimit.z))}get ZMotion(){return this._zMotion}set angularXMotion(t){this._angularXMotion!=t&&(this._angularXMotion=t,this.setLimit(I.MOTION_ANGULAR_INDEX_X,t,-this._maxAngularLimit.x,-this._minAngularLimit.x))}get angularXMotion(){return this._angularXMotion}set angularYMotion(t){this._angularYMotion!=t&&(this._angularYMotion=t,this.setLimit(I.MOTION_ANGULAR_INDEX_Y,t,this._minAngularLimit.y,this._maxAngularLimit.y))}get angularYMotion(){return this._angularYMotion}set angularZMotion(t){this._angularZMotion!=t&&(this._angularZMotion=t,this.setLimit(I.MOTION_ANGULAR_INDEX_Z,t,this._minAngularLimit.z,this._maxAngularLimit.z))}get angularZMotion(){return this._angularZMotion}set linearLimitSpring(t){i.Vector3.equals(this._linearLimitSpring,t)||(t.cloneTo(this._linearLimitSpring),this.setSpring(I.MOTION_LINEAR_INDEX_X,t.x),this.setSpring(I.MOTION_LINEAR_INDEX_Y,t.y),this.setSpring(I.MOTION_LINEAR_INDEX_Z,t.z))}get linearLimitSpring(){return this._linearLimitSpring}set angularLimitSpring(t){i.Vector3.equals(this._angularLimitSpring,t)||(t.cloneTo(this._angularLimitSpring),this.setSpring(I.MOTION_ANGULAR_INDEX_X,t.x),this.setSpring(I.MOTION_ANGULAR_INDEX_Y,t.y),this.setSpring(I.MOTION_ANGULAR_INDEX_Z,t.z))}get angularLimitSpring(){return this._angularLimitSpring}set linearBounce(t){i.Vector3.equals(this._linearBounce,t)||(t.cloneTo(this._linearBounce),this.setBounce(I.MOTION_LINEAR_INDEX_X,t.x),this.setBounce(I.MOTION_LINEAR_INDEX_Y,t.y),this.setBounce(I.MOTION_LINEAR_INDEX_Z,t.z))}get linearBounce(){return this._linearBounce}set angularBounce(t){i.Vector3.equals(this._angularBounce,t)||(t.cloneTo(this._angularBounce),this.setBounce(I.MOTION_ANGULAR_INDEX_X,t.x),this.setBounce(I.MOTION_ANGULAR_INDEX_Y,t.y),this.setBounce(I.MOTION_ANGULAR_INDEX_Z,t.z))}get angularBounce(){return this._angularBounce}set linearDamp(t){i.Vector3.equals(this._linearDamp,t)||(t.cloneTo(this._linearDamp),this.setDamping(I.MOTION_LINEAR_INDEX_X,t.x),this.setDamping(I.MOTION_LINEAR_INDEX_Y,t.y),this.setDamping(I.MOTION_LINEAR_INDEX_Z,t.z))}get linearDamp(){return this._linearDamp}set angularDamp(t){i.Vector3.equals(this._angularDamp,t)||(t.cloneTo(this._angularDamp),this.setDamping(I.MOTION_ANGULAR_INDEX_X,t.x),this.setDamping(I.MOTION_ANGULAR_INDEX_Y,t.y),this.setDamping(I.MOTION_ANGULAR_INDEX_Z,t.z))}get angularDamp(){return this._angularDamp}set anchor(t){t.cloneTo(this._anchor),this.setFrames()}get anchor(){return this._anchor}set connectAnchor(t){t.cloneTo(this._connectAnchor),this.setFrames()}get connectAnchor(){return this._connectAnchor}setAxis(t,e){if(this._btConstraint){var s=i.Physics3D._bullet;this._axis.setValue(t.x,t.y,t.y),this._secondaryAxis.setValue(e.x,e.y,e.z),this._btAxis=s.btVector3_setValue(-t.x,t.y,t.z),this._btSecondaryAxis=s.btVector3_setValue(-e.x,e.y,e.z),s.btGeneric6DofSpring2Constraint_setAxis(this._btConstraint,this._btAxis,this._btSecondaryAxis)}}setLimit(t,e,s,o){if(this._btConstraint){var r=i.Physics3D._bullet;switch(e){case I.CONFIG_MOTION_TYPE_LOCKED:r.btGeneric6DofSpring2Constraint_setLimit(this._btConstraint,t,0,0);break;case I.CONFIG_MOTION_TYPE_LIMITED:s0;o.btGeneric6DofSpring2Constraint_enableSpring(this._btConstraint,t,r),r&&o.btGeneric6DofSpring2Constraint_setStiffness(this._btConstraint,t,e,s)}}setBounce(t,e){this._btConstraint&&(e=e<=0?0:e,i.Physics3D._bullet.btGeneric6DofSpring2Constraint_setBounce(this._btConstraint,t,e))}setDamping(t,e,s=!0){this._btConstraint&&(e=e<=0?0:e,i.Physics3D._bullet.btGeneric6DofSpring2Constraint_setDamping(this._btConstraint,t,e,s))}setEquilibriumPoint(t,e){i.Physics3D._bullet.btGeneric6DofSpring2Constraint_setEquilibriumPoint(this._btConstraint,t,e)}enableMotor(t,e){i.Physics3D._bullet.btGeneric6DofSpring2Constraint_enableMotor(this._btConstraint,t,e)}setServo(t,e){i.Physics3D._bullet.btGeneric6DofSpring2Constraint_setServo(this._btConstraint,t,e)}setTargetVelocity(t,e){i.Physics3D._bullet.btGeneric6DofSpring2Constraint_setTargetVelocity(this._btConstraint,t,e)}setTargetPosition(t,e){i.Physics3D._bullet.btGeneric6DofSpring2Constraint_setServoTarget(this._btConstraint,t,e)}setMaxMotorForce(t,e){i.Physics3D._bullet.btGeneric6DofSpring2Constraint_setMaxMotorForce(this._btConstraint,t,e)}setParam(t,e,s){i.Physics3D._bullet.btTypedConstraint_setParam(this._btConstraint,t,e,s)}setFrames(){super.setFrames();var t=i.Physics3D._bullet;this._btConstraint&&t.btGeneric6DofSpring2Constraint_setFrames(this._btConstraint,this._btframATrans,this._btframBTrans)}_addToSimulation(){this._simulation&&this._simulation.addConstraint(this,this.enabled)}_removeFromSimulation(){this._simulation.removeConstraint(this),this._simulation=null}_createConstraint(){var t=i.Physics3D._bullet;this._btConstraint=t.btGeneric6DofSpring2Constraint_create(this.ownBody.btColliderObject,this._btframAPos,this.connectedBody.btColliderObject,this._btframBPos,I.RO_XYZ),this._btJointFeedBackObj=t.btJointFeedback_create(this._btConstraint),t.btTypedConstraint_setJointFeedback(this._btConstraint,this._btJointFeedBackObj),this._simulation=this.owner._scene.physicsSimulation,this._initAllConstraintInfo(),this._addToSimulation(),i.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,!0)}_initAllConstraintInfo(){this.setLimit(I.MOTION_LINEAR_INDEX_X,this._xMotion,-this._maxLinearLimit.x,-this._minLinearLimit.x),this.setLimit(I.MOTION_LINEAR_INDEX_Y,this._yMotion,this._minLinearLimit.y,this._maxLinearLimit.y),this.setLimit(I.MOTION_LINEAR_INDEX_Z,this._zMotion,this._minLinearLimit.z,this._maxLinearLimit.z),this.setLimit(I.MOTION_ANGULAR_INDEX_X,this._angularXMotion,-this._maxAngularLimit.x,-this._minAngularLimit.x),this.setLimit(I.MOTION_ANGULAR_INDEX_Y,this._angularYMotion,this._minAngularLimit.y,this._maxAngularLimit.y),this.setLimit(I.MOTION_ANGULAR_INDEX_Z,this._angularZMotion,this._minAngularLimit.z,this._maxAngularLimit.z),this.setSpring(I.MOTION_LINEAR_INDEX_X,this._linearLimitSpring.x),this.setSpring(I.MOTION_LINEAR_INDEX_Y,this._linearLimitSpring.y),this.setSpring(I.MOTION_LINEAR_INDEX_Z,this._linearLimitSpring.z),this.setSpring(I.MOTION_ANGULAR_INDEX_X,this._angularLimitSpring.x),this.setSpring(I.MOTION_ANGULAR_INDEX_Y,this._angularLimitSpring.y),this.setSpring(I.MOTION_ANGULAR_INDEX_Z,this._angularLimitSpring.z),this.setBounce(I.MOTION_LINEAR_INDEX_X,this._linearBounce.x),this.setBounce(I.MOTION_LINEAR_INDEX_Y,this._linearBounce.y),this.setBounce(I.MOTION_LINEAR_INDEX_Z,this._linearBounce.z),this.setBounce(I.MOTION_ANGULAR_INDEX_X,this._angularBounce.x),this.setBounce(I.MOTION_ANGULAR_INDEX_Y,this._angularBounce.y),this.setBounce(I.MOTION_ANGULAR_INDEX_Z,this._angularBounce.z),this.setDamping(I.MOTION_LINEAR_INDEX_X,this._linearDamp.x),this.setDamping(I.MOTION_LINEAR_INDEX_Y,this._linearDamp.y),this.setDamping(I.MOTION_LINEAR_INDEX_Z,this._linearDamp.z),this.setDamping(I.MOTION_ANGULAR_INDEX_X,this._angularDamp.x),this.setDamping(I.MOTION_ANGULAR_INDEX_Y,this._angularDamp.y),this.setDamping(I.MOTION_ANGULAR_INDEX_Z,this._angularDamp.z),this.setFrames(),this.setEquilibriumPoint(0,0)}_onAdded(){super._onAdded()}_onEnable(){this._btConstraint&&(super._onEnable(),this._btConstraint&&i.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,!0))}_onDisable(){super._onDisable(),!this.connectedBody&&this._simulation&&this._removeFromSimulation(),this._btConstraint&&i.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,!1)}_parse(t,i=null){super._parse(t),this._axis.fromArray(t.axis),this._secondaryAxis.fromArray(t.secondaryAxis);var e=t.linearLimit;this._minLinearLimit.setValue(-e,-e,-e),this._maxLinearLimit.setValue(e,e,e);var s=t.linearLimitSpring;this._linearLimitSpring.setValue(s,s,s);var o=t.linearLimitDamper;this._linearDamp.setValue(o,o,o);var r=t.linearLimitBounciness;this._linearBounce.setValue(r,r,r);var a=t.lowAngularXLimit,n=t.highAngularXLimit,l=t.angularYLimit,_=t.angularZLimit;this._minAngularLimit.setValue(a,-l,-_),this._maxAngularLimit.setValue(n,l,_);var h=t.highAngularXLimitBounciness,c=t.angularYLimitBounciness,b=t.angularZLimitBounciness;this._angularBounce.setValue(h,c,b);var d=t.angularXLimitSpring,u=t.angularYZLimitSpring;this._angularLimitSpring.setValue(d,u,u);var C=t.angularXLimitDamper,y=t.angularYZLimitDamper;this._angularDamp.setValue(C,y,y),this.XMotion=t.xMotion,this.YMotion=t.yMotion,this.ZMotion=t.zMotion,this.angularXMotion=t.angularXMotion,this.angularYMotion=t.angularYMotion,this.angularZMotion=t.angularZMotion,-1!=t.rigidbodyID&&-1!=t.connectRigidbodyID&&(i.component.push(this),i.data.push(t)),null!=t.breakForce&&(this.breakForce=t.breakForce),null!=t.breakTorque&&(this.breakTorque=t.breakTorque)}_parseInteractive(t=null,i=null){var e=i[t.rigidbodyID].getComponent(T),s=i[t.connectRigidbodyID].getComponent(T);this.ownBody=e,this.connectedBody=s}_onDestroy(){super._onDestroy()}}I.CONFIG_MOTION_TYPE_LOCKED=0,I.CONFIG_MOTION_TYPE_LIMITED=1,I.CONFIG_MOTION_TYPE_FREE=2,I.MOTION_LINEAR_INDEX_X=0,I.MOTION_LINEAR_INDEX_Y=1,I.MOTION_LINEAR_INDEX_Z=2,I.MOTION_ANGULAR_INDEX_X=3,I.MOTION_ANGULAR_INDEX_Y=4,I.MOTION_ANGULAR_INDEX_Z=5,I.RO_XYZ=0,I.RO_XZY=1,I.RO_YXZ=2,I.RO_YZX=3,I.RO_ZXY=4,I.RO_ZYX=5;class O extends e{constructor(t,s){super(),this._normal=t,this._offset=s,this._type=e.SHAPETYPES_STATICPLANE;var o=i.ILaya3D.Physics3D._bullet;o.btVector3_setValue(O._btNormal,-t.x,t.y,t.z),this._btShape=o.btStaticPlaneShape_create(O._btNormal,s)}static __init__(){O._btNormal=i.ILaya3D.Physics3D._bullet.btVector3_create(0,0,0)}clone(){var t=new O(this._normal,this._offset);return this.cloneTo(t),t}}t.BoxColliderShape=s,t.BulletInteractive=c,t.CapsuleColliderShape=o,t.CharacterController=b,t.ColliderShape=e,t.Collision=d,t.CollisionTool=y,t.CompoundColliderShape=r,t.ConeColliderShape=a,t.ConfigurableConstraint=I,t.Constraint3D=class{constructor(){}},t.ConstraintComponent=S,t.ContactPoint=u,t.CylinderColliderShape=n,t.FixedConstraint=class extends S{constructor(){super(S.CONSTRAINT_FIXED_CONSTRAINT_TYPE),this.breakForce=-1,this.breakTorque=-1}_addToSimulation(){this._simulation&&this._simulation.addConstraint(this,this.enabled)}_removeFromSimulation(){this._simulation.removeConstraint(this),this._simulation=null}_createConstraint(){if(this.ownBody&&this.ownBody._simulation&&this.connectedBody&&this.connectedBody._simulation){var t=i.Physics3D._bullet;this._btConstraint=t.btFixedConstraint_create(this.ownBody.btColliderObject,this._btframATrans,this.connectedBody.btColliderObject,this._btframBTrans),this._btJointFeedBackObj=t.btJointFeedback_create(this._btConstraint),t.btTypedConstraint_setJointFeedback(this._btConstraint,this._btJointFeedBackObj),this._simulation=this.owner._scene.physicsSimulation,this._addToSimulation(),i.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,!0)}}_onAdded(){super._onAdded()}_onEnable(){this._btConstraint&&(super._onEnable(),this._btConstraint&&i.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,!0))}_onDisable(){super._onDisable(),this.connectedBody||this._removeFromSimulation(),this._btConstraint&&i.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,!1)}_onDestroy(){super._onDestroy()}_parse(t,i=null){super._parse(t),-1!=t.rigidbodyID&&-1!=t.connectRigidbodyID&&(i.component.push(this),i.data.push(t)),null!=t.breakForce&&(this.breakForce=t.breakForce),null!=t.breakTorque&&(this.breakTorque=t.breakTorque)}_parseInteractive(t=null,i=null){var e=i[t.rigidbodyID].getComponent(T),s=i[t.connectRigidbodyID].getComponent(T);this.ownBody=e,this.connectedBody=s}},t.HitResult=C,t.MeshColliderShape=l,t.PhysicsCollider=class extends m{constructor(t=i.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER,e=i.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER){super(t,e),this._enableProcessCollisions=!1}_addToSimulation(){this._simulation._addPhysicsCollider(this,this._collisionGroup,this._canCollideWith)}_removeFromSimulation(){this._simulation._removePhysicsCollider(this)}_parse(t){null!=t.friction&&(this.friction=t.friction),null!=t.rollingFriction&&(this.rollingFriction=t.rollingFriction),null!=t.restitution&&(this.restitution=t.restitution),null!=t.isTrigger&&(this.isTrigger=t.isTrigger),super._parse(t),this._parseShape(t.shapes)}_onAdded(){var t=i.Physics3D._bullet,e=t.btCollisionObject_create();t.btCollisionObject_setUserIndex(e,this.id),t.btCollisionObject_forceActivationState(e,h.ACTIVATIONSTATE_DISABLE_SIMULATION);var s=t.btCollisionObject_getCollisionFlags(e);this.owner.isStatic?((s&h.COLLISIONFLAGS_KINEMATIC_OBJECT)>0&&(s^=h.COLLISIONFLAGS_KINEMATIC_OBJECT),s|=h.COLLISIONFLAGS_STATIC_OBJECT):((s&h.COLLISIONFLAGS_STATIC_OBJECT)>0&&(s^=h.COLLISIONFLAGS_STATIC_OBJECT),s|=h.COLLISIONFLAGS_KINEMATIC_OBJECT),t.btCollisionObject_setCollisionFlags(e,s),this._btColliderObject=e,super._onAdded()}},t.PhysicsComponent=h,t.PhysicsSettings=class{constructor(){this.flags=0,this.maxSubSteps=1,this.fixedTimeStep=1/60}},t.PhysicsSimulation=g,t.PhysicsTriggerComponent=m,t.PhysicsUpdateList=p,t.Rigidbody3D=T,t.SphereColliderShape=_,t.StaticPlaneColliderShape=O}(window.Laya=window.Laya||{},Laya); \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/min/laya.physics3D.wasm.min.js b/examples/layaair/frontend/bin/libs/min/laya.physics3D.wasm.min.js new file mode 100644 index 0000000..a187a10 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/min/laya.physics3D.wasm.min.js @@ -0,0 +1 @@ +window.Physics3D=function(t,i){return new Promise(e=>{var s=new WebAssembly.Memory({initial:t});fetch("laya.physics3D.wasm.wasm").then(t=>{t.arrayBuffer().then(t=>{WebAssembly.instantiate(t,{LayaAirInteractive:i,wasi_unstable:{fd_close:()=>{console.log("fd_close")},fd_seek:()=>{console.log("fd_seek")},fd_write:()=>{console.log("fd_write")}},env:{memory:s}}).then(t=>{window.Physics3D=t.instance.exports,e()})})})})},function(t,i){"use strict";class e{constructor(){this._scale=new i.Vector3(1,1,1),this._centerMatrix=new i.Matrix4x4,this._attatched=!1,this._indexInCompound=-1,this._compoundParent=null,this._attatchedCollisionObject=null,this._referenceCount=0,this._localOffset=new i.Vector3(0,0,0),this._localRotation=new i.Quaternion(0,0,0,1),this.needsCustomCollisionCallback=!1}static __init__(){var t=i.ILaya3D.Physics3D._bullet;e._btScale=t.btVector3_create(1,1,1),e._btVector30=t.btVector3_create(0,0,0),e._btQuaternion0=t.btQuaternion_create(0,0,0,1),e._btTransform0=t.btTransform_create()}static _createAffineTransformation(t,i,e){var s=i.x,o=i.y,r=i.z,a=i.w,n=s+s,l=o+o,_=r+r,h=s*n,c=s*l,b=s*_,d=o*l,u=o*_,C=r*_,y=a*n,m=a*l,p=a*_;e[0]=1-(d+C),e[1]=c+p,e[2]=b-m,e[3]=0,e[4]=c-p,e[5]=1-(h+C),e[6]=u+y,e[7]=0,e[8]=b+m,e[9]=u-y,e[10]=1-(h+d),e[11]=0,e[12]=t.x,e[13]=t.y,e[14]=t.z,e[15]=1}get type(){return this._type}get localOffset(){return this._localOffset}set localOffset(t){this._localOffset=t,this._compoundParent&&this._compoundParent._updateChildTransform(this)}get localRotation(){return this._localRotation}set localRotation(t){this._localRotation=t,this._compoundParent&&this._compoundParent._updateChildTransform(this)}_setScale(t){if(this._compoundParent)this.updateLocalTransformations();else{var s=i.ILaya3D.Physics3D._bullet;s.btVector3_setValue(e._btScale,t.x,t.y,t.z),s.btCollisionShape_setLocalScaling(this._btShape,e._btScale)}}_addReference(){this._referenceCount++}_removeReference(){this._referenceCount--}updateLocalTransformations(){if(this._compoundParent){var t=e._tempVector30;i.Vector3.multiply(this.localOffset,this._scale,t),e._createAffineTransformation(t,this.localRotation,this._centerMatrix.elements)}else e._createAffineTransformation(this.localOffset,this.localRotation,this._centerMatrix.elements)}cloneTo(t){var i=t;this._localOffset.cloneTo(i.localOffset),this._localRotation.cloneTo(i.localRotation),i.localOffset=i.localOffset,i.localRotation=i.localRotation}clone(){return null}destroy(){this._btShape&&(i.ILaya3D.Physics3D._bullet.btCollisionShape_destroy(this._btShape),this._btShape=null)}}e.SHAPEORIENTATION_UPX=0,e.SHAPEORIENTATION_UPY=1,e.SHAPEORIENTATION_UPZ=2,e.SHAPETYPES_BOX=0,e.SHAPETYPES_SPHERE=1,e.SHAPETYPES_CYLINDER=2,e.SHAPETYPES_CAPSULE=3,e.SHAPETYPES_CONVEXHULL=4,e.SHAPETYPES_COMPOUND=5,e.SHAPETYPES_STATICPLANE=6,e.SHAPETYPES_CONE=7,e._tempVector30=new i.Vector3;class s extends e{constructor(t=1,o=1,r=1){super(),this._sizeX=t,this._sizeY=o,this._sizeZ=r,this._type=e.SHAPETYPES_BOX;var a=i.ILaya3D.Physics3D._bullet;a.btVector3_setValue(s._btSize,t/2,o/2,r/2),this._btShape=a.btBoxShape_create(s._btSize)}static __init__(){s._btSize=i.ILaya3D.Physics3D._bullet.btVector3_create(0,0,0)}get sizeX(){return this._sizeX}get sizeY(){return this._sizeY}get sizeZ(){return this._sizeZ}clone(){var t=new s(this._sizeX,this._sizeY,this._sizeZ);return this.cloneTo(t),t}}class o extends e{constructor(t=.5,s=1.25,o=e.SHAPEORIENTATION_UPY){super(),this._radius=t,this._length=s,this._orientation=o,this._type=e.SHAPETYPES_CAPSULE;var r=i.ILaya3D.Physics3D._bullet;switch(o){case e.SHAPEORIENTATION_UPX:this._btShape=r.btCapsuleShapeX_create(t,s-2*t);break;case e.SHAPEORIENTATION_UPY:this._btShape=r.btCapsuleShape_create(t,s-2*t);break;case e.SHAPEORIENTATION_UPZ:this._btShape=r.btCapsuleShapeZ_create(t,s-2*t);break;default:throw"CapsuleColliderShape:unknown orientation."}}get radius(){return this._radius}get length(){return this._length}get orientation(){return this._orientation}_setScale(t){var i=o._tempVector30;switch(this.orientation){case e.SHAPEORIENTATION_UPX:i.x=t.x,i.y=i.z=Math.max(t.y,t.z);break;case e.SHAPEORIENTATION_UPY:i.y=t.y,i.x=i.z=Math.max(t.x,t.z);break;case e.SHAPEORIENTATION_UPZ:i.z=t.z,i.x=i.y=Math.max(t.x,t.y);break;default:throw"CapsuleColliderShape:unknown orientation."}super._setScale(i)}clone(){var t=new o(this._radius,this._length,this._orientation);return this.cloneTo(t),t}}o._tempVector30=new i.Vector3;class r extends e{constructor(){super(),this._childColliderShapes=[],this._type=e.SHAPETYPES_COMPOUND,this._btShape=i.ILaya3D.Physics3D._bullet.btCompoundShape_create()}static __init__(){var t=i.ILaya3D.Physics3D._bullet;r._btVector3One=t.btVector3_create(1,1,1),r._btTransform=t.btTransform_create(),r._btOffset=t.btVector3_create(0,0,0),r._btRotation=t.btQuaternion_create(0,0,0,1)}_clearChildShape(t){t._attatched=!1,t._compoundParent=null,t._indexInCompound=-1}_addReference(){}_removeReference(){}_updateChildTransform(t){var s=i.ILaya3D.Physics3D._bullet,o=t.localOffset,r=t.localRotation,a=e._btVector30,n=e._btQuaternion0,l=e._btTransform0;s.btVector3_setValue(a,-o.x,o.y,o.z),s.btQuaternion_setValue(n,-r.x,r.y,r.z,-r.w),s.btTransform_setOrigin(l,a),s.btTransform_setRotation(l,n),s.btCompoundShape_updateChildTransform(this._btShape,t._indexInCompound,l,!0)}addChildShape(t){if(t._attatched)throw"CompoundColliderShape: this shape has attatched to other entity.";t._attatched=!0,t._compoundParent=this,t._indexInCompound=this._childColliderShapes.length,this._childColliderShapes.push(t);var e=t.localOffset,s=t.localRotation,o=i.ILaya3D.Physics3D._bullet;o.btVector3_setValue(r._btOffset,-e.x,e.y,e.z),o.btQuaternion_setValue(r._btRotation,-s.x,s.y,s.z,-s.w),o.btTransform_setOrigin(r._btTransform,r._btOffset),o.btTransform_setRotation(r._btTransform,r._btRotation);var a=o.btCollisionShape_getLocalScaling(this._btShape);o.btCollisionShape_setLocalScaling(this._btShape,r._btVector3One),o.btCompoundShape_addChildShape(this._btShape,r._btTransform,t._btShape),o.btCollisionShape_setLocalScaling(this._btShape,a),this._attatchedCollisionObject&&(this._attatchedCollisionObject.colliderShape=this)}removeChildShape(t){if(t._compoundParent===this){var e=t._indexInCompound;this._clearChildShape(t);var s=this._childColliderShapes[this._childColliderShapes.length-1];s._indexInCompound=e,this._childColliderShapes[e]=s,this._childColliderShapes.pop(),i.ILaya3D.Physics3D._bullet.btCompoundShape_removeChildShapeByIndex(this._btShape,e)}}clearChildShape(){for(var t=0,e=this._childColliderShapes.length;t0&&s.btCollisionObject_setCollisionFlags(e,o^h.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK)}_onAdded(){this.enabled=this._enabled,this.restitution=this._restitution,this.friction=this._friction,this.rollingFriction=this._rollingFriction,this.ccdMotionThreshold=this._ccdMotionThreshold,this.ccdSweptSphereRadius=this._ccdSweptSphereRadius,this.owner.transform.on(i.Event.TRANSFORM_CHANGED,this,this._onTransformChanged)}_onTransformChanged(t){!h._addUpdateList&&this._controlBySimulation||(t&=i.Transform3D.TRANSFORM_WORLDPOSITION|i.Transform3D.TRANSFORM_WORLDQUATERNION|i.Transform3D.TRANSFORM_WORLDSCALE)&&(this._transformFlag|=t,this._isValid()&&-1===this._inPhysicUpdateListIndex&&this._simulation._physicsUpdateList.add(this))}_cloneTo(t){var i=t;i.restitution=this._restitution,i.friction=this._friction,i.rollingFriction=this._rollingFriction,i.ccdMotionThreshold=this._ccdMotionThreshold,i.ccdSweptSphereRadius=this._ccdSweptSphereRadius,i.collisionGroup=this._collisionGroup,i.canCollideWith=this._canCollideWith,i.canScaleShape=this.canScaleShape,this._colliderShape&&(i.colliderShape=this._colliderShape.clone())}}h.ACTIVATIONSTATE_ACTIVE_TAG=1,h.ACTIVATIONSTATE_ISLAND_SLEEPING=2,h.ACTIVATIONSTATE_WANTS_DEACTIVATION=3,h.ACTIVATIONSTATE_DISABLE_DEACTIVATION=4,h.ACTIVATIONSTATE_DISABLE_SIMULATION=5,h.COLLISIONFLAGS_STATIC_OBJECT=1,h.COLLISIONFLAGS_KINEMATIC_OBJECT=2,h.COLLISIONFLAGS_NO_CONTACT_RESPONSE=4,h.COLLISIONFLAGS_CUSTOM_MATERIAL_CALLBACK=8,h.COLLISIONFLAGS_CHARACTER_OBJECT=16,h.COLLISIONFLAGS_DISABLE_VISUALIZE_OBJECT=32,h.COLLISIONFLAGS_DISABLE_SPU_COLLISION_PROCESSING=64,h._tempVector30=new i.Vector3,h._tempQuaternion0=new i.Quaternion,h._tempQuaternion1=new i.Quaternion,h._tempMatrix4x40=new i.Matrix4x4,h._physicObjectsMap={},h._addUpdateList=!0;class c{}c._interactive={getWorldTransform:(t,i)=>{},setWorldTransform:(t,i)=>{var e=h._physicObjectsMap[t];e._simulation._updatedRigidbodies++,e._updateTransformComponent(i)}};class b extends h{constructor(t=.1,e=null,s=i.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER,o=i.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER){super(s,o),this._upAxis=new i.Vector3(0,1,0),this._maxSlope=45,this._jumpSpeed=10,this._fallSpeed=55,this._gravity=new i.Vector3(0,3*-9.8,0),this._btKinematicCharacter=null,this._stepHeight=t,e&&(this._upAxis=e),this._controlBySimulation=!0}static __init__(){b._btTempVector30=i.ILaya3D.Physics3D._bullet.btVector3_create(0,0,0)}get fallSpeed(){return this._fallSpeed}set fallSpeed(t){this._fallSpeed=t,i.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setFallSpeed(this._btKinematicCharacter,t)}get jumpSpeed(){return this._jumpSpeed}set jumpSpeed(t){this._jumpSpeed=t,i.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setJumpSpeed(this._btKinematicCharacter,t)}get gravity(){return this._gravity}set gravity(t){this._gravity=t;var e=i.ILaya3D.Physics3D._bullet,s=b._btTempVector30;e.btVector3_setValue(s,-t.x,t.y,t.z),e.btKinematicCharacterController_setGravity(this._btKinematicCharacter,s)}get maxSlope(){return this._maxSlope}set maxSlope(t){this._maxSlope=t,i.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setMaxSlope(this._btKinematicCharacter,t/180*Math.PI)}get isGrounded(){return i.ILaya3D.Physics3D._bullet.btKinematicCharacterController_onGround(this._btKinematicCharacter)}get stepHeight(){return this._stepHeight}set stepHeight(t){this._stepHeight=t,i.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setStepHeight(this._btKinematicCharacter,t)}get upAxis(){return this._upAxis}set upAxis(t){this._upAxis=t;var e=b._btTempVector30;i.Utils3D._convertToBulletVec3(t,e,!1),i.ILaya3D.Physics3D._bullet.btKinematicCharacterController_setUp(this._btKinematicCharacter,e)}_constructCharacter(){var t=i.ILaya3D.Physics3D._bullet;this._btKinematicCharacter&&t.btKinematicCharacterController_destroy(this._btKinematicCharacter);var e=b._btTempVector30;t.btVector3_setValue(e,this._upAxis.x,this._upAxis.y,this._upAxis.z),this._btKinematicCharacter=t.btKinematicCharacterController_create(this._btColliderObject,this._colliderShape._btShape,this._stepHeight,e),this.fallSpeed=this._fallSpeed,this.maxSlope=this._maxSlope,this.jumpSpeed=this._jumpSpeed,this.gravity=this._gravity}_onShapeChange(t){super._onShapeChange(t),this._constructCharacter()}_onAdded(){var t=i.ILaya3D.Physics3D._bullet,e=t.btPairCachingGhostObject_create();t.btCollisionObject_setUserIndex(e,this.id),t.btCollisionObject_setCollisionFlags(e,h.COLLISIONFLAGS_CHARACTER_OBJECT),this._btColliderObject=e,this._colliderShape&&this._constructCharacter(),super._onAdded()}_addToSimulation(){this._simulation._characters.push(this),this._simulation._addCharacter(this,this._collisionGroup,this._canCollideWith)}_removeFromSimulation(){this._simulation._removeCharacter(this);var t=this._simulation._characters;t.splice(t.indexOf(this),1)}_cloneTo(t){super._cloneTo(t);var i=t;i.stepHeight=this._stepHeight,i.upAxis=this._upAxis,i.maxSlope=this._maxSlope,i.jumpSpeed=this._jumpSpeed,i.fallSpeed=this._fallSpeed,i.gravity=this._gravity}_onDestroy(){i.ILaya3D.Physics3D._bullet.btKinematicCharacterController_destroy(this._btKinematicCharacter),super._onDestroy(),this._btKinematicCharacter=null}move(t){var e=b._btVector30,s=i.ILaya3D.Physics3D._bullet;s.btVector3_setValue(e,-t.x,t.y,t.z),s.btKinematicCharacterController_setWalkDirection(this._btKinematicCharacter,e)}jump(t=null){var e=i.ILaya3D.Physics3D._bullet,s=b._btVector30;t?(i.Utils3D._convertToBulletVec3(t,s,!0),e.btKinematicCharacterController_jump(this._btKinematicCharacter,s)):(e.btVector3_setValue(s,0,0,0),e.btKinematicCharacterController_jump(this._btKinematicCharacter,s))}}b.UPAXIS_X=0,b.UPAXIS_Y=1,b.UPAXIS_Z=2;class d{constructor(){this._lastUpdateFrame=-2147483648,this._updateFrame=-2147483648,this._isTrigger=!1,this.contacts=[]}_setUpdateFrame(t){this._lastUpdateFrame=this._updateFrame,this._updateFrame=t}}class u{constructor(){this._idCounter=0,this.colliderA=null,this.colliderB=null,this.distance=0,this.normal=new i.Vector3,this.positionOnA=new i.Vector3,this.positionOnB=new i.Vector3,this._id=++this._idCounter}}class C{constructor(){this.succeeded=!1,this.collider=null,this.point=new i.Vector3,this.normal=new i.Vector3,this.hitFraction=0}}class y{constructor(){this._hitResultsPoolIndex=0,this._hitResultsPool=[],this._contactPonintsPoolIndex=0,this._contactPointsPool=[],this._collisionsPool=[],this._collisions={}}getHitResult(){var t=this._hitResultsPool[this._hitResultsPoolIndex++];return t||(t=new C,this._hitResultsPool.push(t)),t}recoverAllHitResultsPool(){this._hitResultsPoolIndex=0}getContactPoints(){var t=this._contactPointsPool[this._contactPonintsPoolIndex++];return t||(t=new u,this._contactPointsPool.push(t)),t}recoverAllContactPointsPool(){this._contactPonintsPoolIndex=0}getCollision(t,i){var e,s=t.id,o=i.id,r=this._collisions[s];return r&&(e=r[o]),e||(r||(r={},this._collisions[s]=r),(e=0===this._collisionsPool.length?new d:this._collisionsPool.pop())._colliderA=t,e._colliderB=i,r[o]=e),e}recoverCollision(t){var i=t._colliderA.id,e=t._colliderB.id;this._collisions[i][e]=null,this._collisionsPool.push(t)}garbageCollection(){for(var t in this._hitResultsPoolIndex=0,this._hitResultsPool.length=0,this._contactPonintsPoolIndex=0,this._contactPointsPool.length=0,this._collisionsPool.length=0,this._collisionsPool){var i=this._collisionsPool[t],e=!0;for(var s in i)i[s]?e=!1:delete i[s];e&&delete this._collisionsPool[t]}}}class m extends h{constructor(t,i){super(t,i),this._isTrigger=!1}get isTrigger(){return this._isTrigger}set isTrigger(t){this._isTrigger=t;var e=i.ILaya3D.Physics3D._bullet;if(this._btColliderObject){var s=e.btCollisionObject_getCollisionFlags(this._btColliderObject);t?0==(s&h.COLLISIONFLAGS_NO_CONTACT_RESPONSE)&&e.btCollisionObject_setCollisionFlags(this._btColliderObject,s|h.COLLISIONFLAGS_NO_CONTACT_RESPONSE):0!=(s&h.COLLISIONFLAGS_NO_CONTACT_RESPONSE)&&e.btCollisionObject_setCollisionFlags(this._btColliderObject,s^h.COLLISIONFLAGS_NO_CONTACT_RESPONSE)}}_onAdded(){super._onAdded(),this.isTrigger=this._isTrigger}_cloneTo(t){super._cloneTo(t),t.isTrigger=this._isTrigger}}class p extends i.SingletonList{constructor(){super()}add(t){if(-1!==t._inPhysicUpdateListIndex)throw"PhysicsUpdateList:element has in PhysicsUpdateList.";this._add(t),t._inPhysicUpdateListIndex=this.length++}remove(t){var i=t._inPhysicUpdateListIndex;if(this.length--,i!==this.length){var e=this.elements[this.length];this.elements[i]=e,e._inPhysicUpdateListIndex=i}t._inPhysicUpdateListIndex=-1}}class g{constructor(t){this._gravity=new i.Vector3(0,-10,0),this._btVector3Zero=i.ILaya3D.Physics3D._bullet.btVector3_create(0,0,0),this._btDefaultQuaternion=i.ILaya3D.Physics3D._bullet.btQuaternion_create(0,0,0,-1),this._collisionsUtils=new y,this._previousFrameCollisions=[],this._currentFrameCollisions=[],this._currentConstraint={},this._physicsUpdateList=new p,this._characters=[],this._updatedRigidbodies=0,this.maxSubSteps=1,this.fixedTimeStep=1/60,this.maxSubSteps=t.maxSubSteps,this.fixedTimeStep=t.fixedTimeStep;var e=i.ILaya3D.Physics3D._bullet;this._btCollisionConfiguration=e.btDefaultCollisionConfiguration_create(),this._btDispatcher=e.btCollisionDispatcher_create(this._btCollisionConfiguration),this._btBroadphase=e.btDbvtBroadphase_create(),e.btOverlappingPairCache_setInternalGhostPairCallback(e.btDbvtBroadphase_getOverlappingPairCache(this._btBroadphase),e.btGhostPairCallback_create());var s=t.flags;if(s&g.PHYSICSENGINEFLAGS_COLLISIONSONLY)this._btCollisionWorld=new e.btCollisionWorld(this._btDispatcher,this._btBroadphase,this._btCollisionConfiguration);else{if(s&g.PHYSICSENGINEFLAGS_SOFTBODYSUPPORT)throw"PhysicsSimulation:SoftBody processing is not yet available";var o=e.btSequentialImpulseConstraintSolver_create();this._btDiscreteDynamicsWorld=e.btDiscreteDynamicsWorld_create(this._btDispatcher,this._btBroadphase,o,this._btCollisionConfiguration),this._btCollisionWorld=this._btDiscreteDynamicsWorld}this._btDiscreteDynamicsWorld&&(this._btSolverInfo=e.btDynamicsWorld_getSolverInfo(this._btDiscreteDynamicsWorld),this._btDispatchInfo=e.btCollisionWorld_getDispatchInfo(this._btDiscreteDynamicsWorld)),this._btClosestRayResultCallback=e.ClosestRayResultCallback_create(this._btVector3Zero,this._btVector3Zero),this._btAllHitsRayResultCallback=e.AllHitsRayResultCallback_create(this._btVector3Zero,this._btVector3Zero),this._btClosestConvexResultCallback=e.ClosestConvexResultCallback_create(this._btVector3Zero,this._btVector3Zero),this._btAllConvexResultCallback=e.AllConvexResultCallback_create(this._btVector3Zero,this._btVector3Zero),this.setHitsRayResultCallbackFlag(),e.btGImpactCollisionAlgorithm_RegisterAlgorithm(this._btDispatcher)}static __init__(){var t=i.ILaya3D.Physics3D._bullet;g._btTempVector30=t.btVector3_create(0,0,0),g._btTempVector31=t.btVector3_create(0,0,0),g._btTempQuaternion0=t.btQuaternion_create(0,0,0,1),g._btTempQuaternion1=t.btQuaternion_create(0,0,0,1),g._btTempTransform0=t.btTransform_create(),g._btTempTransform1=t.btTransform_create()}static createConstraint(){}get continuousCollisionDetection(){return i.ILaya3D.Physics3D._bullet.btCollisionWorld_get_m_useContinuous(this._btDispatchInfo)}set continuousCollisionDetection(t){i.ILaya3D.Physics3D._bullet.btCollisionWorld_set_m_useContinuous(this._btDispatchInfo,t)}get gravity(){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";return this._gravity}set gravity(t){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";this._gravity=t;var e=i.ILaya3D.Physics3D._bullet,s=g._btTempVector30;e.btVector3_setValue(s,-t.x,t.y,t.z),e.btDiscreteDynamicsWorld_setGravity(this._btDiscreteDynamicsWorld,s)}get speculativeContactRestitution(){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot Cannot perform this action when the physics engine is set to CollisionsOnly";return i.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_getApplySpeculativeContactRestitution(this._btDiscreteDynamicsWorld)}set speculativeContactRestitution(t){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot Cannot perform this action when the physics engine is set to CollisionsOnly";i.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_setApplySpeculativeContactRestitution(this._btDiscreteDynamicsWorld,t)}_simulate(t){this._updatedRigidbodies=0;var e=i.ILaya3D.Physics3D._bullet;this._btDiscreteDynamicsWorld?e.btDiscreteDynamicsWorld_stepSimulation(this._btDiscreteDynamicsWorld,t,this.maxSubSteps,this.fixedTimeStep):e.PerformDiscreteCollisionDetection(this._btCollisionWorld)}_destroy(){var t=i.ILaya3D.Physics3D._bullet;this._btDiscreteDynamicsWorld?(t.btCollisionWorld_destroy(this._btDiscreteDynamicsWorld),this._btDiscreteDynamicsWorld=null):(t.btCollisionWorld_destroy(this._btCollisionWorld),this._btCollisionWorld=null),t.btDbvtBroadphase_destroy(this._btBroadphase),this._btBroadphase=null,t.btCollisionDispatcher_destroy(this._btDispatcher),this._btDispatcher=null,t.btDefaultCollisionConfiguration_destroy(this._btCollisionConfiguration),this._btCollisionConfiguration=null}_addPhysicsCollider(t,e,s){i.ILaya3D.Physics3D._bullet.btCollisionWorld_addCollisionObject(this._btCollisionWorld,t._btColliderObject,e,s)}_removePhysicsCollider(t){i.ILaya3D.Physics3D._bullet.btCollisionWorld_removeCollisionObject(this._btCollisionWorld,t._btColliderObject)}_addRigidBody(t,e,s){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";i.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_addRigidBody(this._btCollisionWorld,t._btColliderObject,e,s)}_removeRigidBody(t){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";i.ILaya3D.Physics3D._bullet.btDiscreteDynamicsWorld_removeRigidBody(this._btCollisionWorld,t._btColliderObject)}_addCharacter(t,e,s){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";var o=i.ILaya3D.Physics3D._bullet;o.btCollisionWorld_addCollisionObject(this._btCollisionWorld,t._btColliderObject,e,s),o.btDynamicsWorld_addAction(this._btCollisionWorld,t._btKinematicCharacter)}_removeCharacter(t){if(!this._btDiscreteDynamicsWorld)throw"Simulation:Cannot perform this action when the physics engine is set to CollisionsOnly";var e=i.ILaya3D.Physics3D._bullet;e.btCollisionWorld_removeCollisionObject(this._btCollisionWorld,t._btColliderObject),e.btDynamicsWorld_removeAction(this._btCollisionWorld,t._btKinematicCharacter)}raycastFromTo(t,e,s=null,o=i.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER,r=i.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER){var a=i.ILaya3D.Physics3D._bullet,n=this._btClosestRayResultCallback,l=g._btTempVector30,_=g._btTempVector31;if(a.btVector3_setValue(l,-t.x,t.y,t.z),a.btVector3_setValue(_,-e.x,e.y,e.z),a.ClosestRayResultCallback_set_m_rayFromWorld(n,l),a.ClosestRayResultCallback_set_m_rayToWorld(n,_),a.RayResultCallback_set_m_collisionFilterGroup(n,o),a.RayResultCallback_set_m_collisionFilterMask(n,r),a.RayResultCallback_set_m_collisionObject(n,null),a.RayResultCallback_set_m_closestHitFraction(n,1),a.btCollisionWorld_rayTest(this._btCollisionWorld,l,_,n),a.RayResultCallback_hasHit(n)){if(s){s.succeeded=!0,s.collider=h._physicObjectsMap[a.btCollisionObject_getUserIndex(a.RayResultCallback_get_m_collisionObject(n))],s.hitFraction=a.RayResultCallback_get_m_closestHitFraction(n);var c=a.ClosestRayResultCallback_get_m_hitPointWorld(n),b=s.point;b.x=-a.btVector3_x(c),b.y=a.btVector3_y(c),b.z=a.btVector3_z(c);var d=a.ClosestRayResultCallback_get_m_hitNormalWorld(n),u=s.normal;u.x=-a.btVector3_x(d),u.y=a.btVector3_y(d),u.z=a.btVector3_z(d)}return!0}return s&&(s.succeeded=!1),!1}raycastAllFromTo(t,e,s,o=i.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER,r=i.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER){var a=i.ILaya3D.Physics3D._bullet,n=this._btAllHitsRayResultCallback,l=g._btTempVector30,_=g._btTempVector31;s.length=0,a.btVector3_setValue(l,-t.x,t.y,t.z),a.btVector3_setValue(_,-e.x,e.y,e.z),a.AllHitsRayResultCallback_set_m_rayFromWorld(n,l),a.AllHitsRayResultCallback_set_m_rayToWorld(n,_),a.RayResultCallback_set_m_collisionFilterGroup(n,o),a.RayResultCallback_set_m_collisionFilterMask(n,r);var c=a.AllHitsRayResultCallback_get_m_collisionObjects(n),b=a.AllHitsRayResultCallback_get_m_hitPointWorld(n),d=a.AllHitsRayResultCallback_get_m_hitNormalWorld(n),u=a.AllHitsRayResultCallback_get_m_hitFractions(n);a.tBtCollisionObjectArray_clear(c),a.tVector3Array_clear(b),a.tVector3Array_clear(d),a.tScalarArray_clear(u),a.btCollisionWorld_rayTest(this._btCollisionWorld,l,_,n);var C=a.tBtCollisionObjectArray_size(c);if(C>0){this._collisionsUtils.recoverAllHitResultsPool();for(var y=0;y0){this._collisionsUtils.recoverAllHitResultsPool();for(var A=0;A0&&(r^=h.COLLISIONFLAGS_KINEMATIC_OBJECT),e.btCollisionObject_setCollisionFlags(o,r),e.btCollisionObject_setActivationState(this._btColliderObject,h.ACTIVATIONSTATE_ACTIVE_TAG),this._enableProcessCollisions=!0,this._updateMass(this._mass));var a=T._btVector3Zero;e.btCollisionObject_setInterpolationLinearVelocity(o,a),e.btRigidBody_setLinearVelocity(o,a),e.btCollisionObject_setInterpolationAngularVelocity(o,a),e.btRigidBody_setAngularVelocity(o,a),s&&this._addToSimulation()}get linearDamping(){return this._linearDamping}set linearDamping(t){this._linearDamping=t,this._btColliderObject&&i.ILaya3D.Physics3D._bullet.btRigidBody_setDamping(this._btColliderObject,t,this._angularDamping)}get angularDamping(){return this._angularDamping}set angularDamping(t){this._angularDamping=t,this._btColliderObject&&i.ILaya3D.Physics3D._bullet.btRigidBody_setDamping(this._btColliderObject,this._linearDamping,t)}get overrideGravity(){return this._overrideGravity}set overrideGravity(t){this._overrideGravity=t;var e=i.ILaya3D.Physics3D._bullet;if(this._btColliderObject){var s=e.btRigidBody_getFlags(this._btColliderObject);t?0==(s&T._BT_DISABLE_WORLD_GRAVITY)&&e.btRigidBody_setFlags(this._btColliderObject,s|T._BT_DISABLE_WORLD_GRAVITY):(s&T._BT_DISABLE_WORLD_GRAVITY)>0&&e.btRigidBody_setFlags(this._btColliderObject,s^T._BT_DISABLE_WORLD_GRAVITY)}}get gravity(){var t=i.ILaya3D.Physics3D._bullet;return T._btGravity=t.btRigidBody_getGravity(this._btColliderObject),i.Utils3D._convertToLayaVec3(T._btGravity,this._gravity,!0),this._gravity}set gravity(t){this._gravity=t;var e=i.ILaya3D.Physics3D._bullet;e.btVector3_setValue(T._btGravity,-t.x,t.y,t.z),e.btRigidBody_setGravity(this._btColliderObject,T._btGravity)}get totalForce(){if(this._btColliderObject){var t=i.ILaya3D.Physics3D._bullet.btRigidBody_getTotalForce(this._btColliderObject);return i.Utils3D._convertToLayaVec3(t,this._totalForce,!0),this._totalForce}return null}get linearFactor(){return this._linearFactor}set linearFactor(t){this._linearFactor=t;var e=T._btTempVector30;i.Utils3D._convertToBulletVec3(t,e,!1),i.ILaya3D.Physics3D._bullet.btRigidBody_setLinearFactor(this._btColliderObject,e)}get linearVelocity(){return this._btColliderObject&&i.Utils3D._convertToLayaVec3(i.ILaya3D.Physics3D._bullet.btRigidBody_getLinearVelocity(this._btColliderObject),this._linearVelocity,!0),this._linearVelocity}set linearVelocity(t){if(this._linearVelocity=t,this._btColliderObject){var e=T._btTempVector30;i.Utils3D._convertToBulletVec3(t,e,!0),this.isSleeping&&this.wakeUp(),i.ILaya3D.Physics3D._bullet.btRigidBody_setLinearVelocity(this._btColliderObject,e)}}get angularFactor(){return this._angularFactor}set angularFactor(t){this._angularFactor=t;var e=T._btTempVector30;i.Utils3D._convertToBulletVec3(t,e,!1),i.ILaya3D.Physics3D._bullet.btRigidBody_setAngularFactor(this._btColliderObject,e)}get angularVelocity(){return this._btColliderObject&&i.Utils3D._convertToLayaVec3(i.ILaya3D.Physics3D._bullet.btRigidBody_getAngularVelocity(this._btColliderObject),this._angularVelocity,!0),this._angularVelocity}set angularVelocity(t){if(this._angularVelocity=t,this._btColliderObject){var e=T._btTempVector30;i.Utils3D._convertToBulletVec3(t,e,!0),this.isSleeping&&this.wakeUp(),i.ILaya3D.Physics3D._bullet.btRigidBody_setAngularVelocity(this._btColliderObject,e)}}get totalTorque(){if(this._btColliderObject){var t=i.ILaya3D.Physics3D._bullet.btRigidBody_getTotalTorque(this._btColliderObject);return i.Utils3D._convertToLayaVec3(t,this._totalTorque,!0),this._totalTorque}return null}get detectCollisions(){return this._detectCollisions}set detectCollisions(t){this._detectCollisions!==t&&(this._detectCollisions=t,this._colliderShape&&this._enabled&&this._simulation&&(this._simulation._removeRigidBody(this),this._simulation._addRigidBody(this,this._collisionGroup,t?this._canCollideWith:0)))}get isSleeping(){return!!this._btColliderObject&&i.ILaya3D.Physics3D._bullet.btCollisionObject_getActivationState(this._btColliderObject)===h.ACTIVATIONSTATE_ISLAND_SLEEPING}get sleepLinearVelocity(){return i.ILaya3D.Physics3D._bullet.btRigidBody_getLinearSleepingThreshold(this._btColliderObject)}set sleepLinearVelocity(t){var e=i.ILaya3D.Physics3D._bullet;e.btRigidBody_setSleepingThresholds(this._btColliderObject,t,e.btRigidBody_getAngularSleepingThreshold(this._btColliderObject))}get sleepAngularVelocity(){return i.ILaya3D.Physics3D._bullet.btRigidBody_getAngularSleepingThreshold(this._btColliderObject)}set sleepAngularVelocity(t){var e=i.ILaya3D.Physics3D._bullet;e.btRigidBody_setSleepingThresholds(this._btColliderObject,e.btRigidBody_getLinearSleepingThreshold(this._btColliderObject),t)}get btColliderObject(){return this._btColliderObject}set constaintRigidbodyA(t){this._constaintRigidbodyA=t}get constaintRigidbodyA(){return this._constaintRigidbodyA}set constaintRigidbodyB(t){this._constaintRigidbodyB=t}get constaintRigidbodyB(){return this._constaintRigidbodyB}_updateMass(t){if(this._btColliderObject&&this._colliderShape){var e=i.ILaya3D.Physics3D._bullet;e.btCollisionShape_calculateLocalInertia(this._colliderShape._btShape,t,T._btInertia),e.btRigidBody_setMassProps(this._btColliderObject,t,T._btInertia),e.btRigidBody_updateInertiaTensor(this._btColliderObject)}}_onScaleChange(t){super._onScaleChange(t),this._updateMass(this._isKinematic?0:this._mass)}_derivePhysicsTransformation(t){var e=i.ILaya3D.Physics3D._bullet,s=this._btColliderObject,o=e.btCollisionObject_getWorldTransform(s),r=T._btTransform0;e.btTransform_equal(r,o),this._innerDerivePhysicsTransformation(r,t),e.btRigidBody_setCenterOfMassTransform(s,r)}_onAdded(){var t=i.ILaya3D.Physics3D._bullet,e=t.layaMotionState_create();t.layaMotionState_set_rigidBodyID(e,this._id),this._btLayaMotionState=e;var s=t.btRigidBodyConstructionInfo_create(0,e,null,T._btVector3Zero),o=t.btRigidBody_create(s);t.btCollisionObject_setUserIndex(o,this.id),this._btColliderObject=o,super._onAdded(),this.mass=this._mass,this.linearFactor=this._linearFactor,this.angularFactor=this._angularFactor,this.linearDamping=this._linearDamping,this.angularDamping=this._angularDamping,this.overrideGravity=this._overrideGravity,this.gravity=this._gravity,this.isKinematic=this._isKinematic,t.btRigidBodyConstructionInfo_destroy(s)}_onEnable(){super._onEnable(),this._constaintRigidbodyA&&this._constaintRigidbodyA.connectedBody._simulation&&(this._constaintRigidbodyA._createConstraint(),this._constaintRigidbodyA._onEnable()),this._constaintRigidbodyB&&this._constaintRigidbodyB.ownBody._simulation&&(this._constaintRigidbodyB._createConstraint(),this._constaintRigidbodyB._onEnable())}_onShapeChange(t){if(super._onShapeChange(t),this._isKinematic)this._updateMass(0);else{var e=i.ILaya3D.Physics3D._bullet;e.btRigidBody_setCenterOfMassTransform(this._btColliderObject,e.btCollisionObject_getWorldTransform(this._btColliderObject)),this._updateMass(this._mass)}}_parse(t){if(null!=t.friction&&(this.friction=t.friction),null!=t.rollingFriction&&(this.rollingFriction=t.rollingFriction),null!=t.restitution&&(this.restitution=t.restitution),null!=t.isTrigger&&(this.isTrigger=t.isTrigger),null!=t.mass&&(this.mass=t.mass),null!=t.linearDamping&&(this.linearDamping=t.linearDamping),null!=t.angularDamping&&(this.angularDamping=t.angularDamping),null!=t.overrideGravity&&(this.overrideGravity=t.overrideGravity),null!=t.linearFactor){var i=this.linearFactor;i.fromArray(t.linearFactor),this.linearFactor=i}if(null!=t.angularFactor){var e=this.angularFactor;e.fromArray(t.angularFactor),this.angularFactor=e}t.gravity&&(this.gravity.fromArray(t.gravity),this.gravity=this.gravity),super._parse(t),this._parseShape(t.shapes),null!=t.isKinematic&&(this.isKinematic=t.isKinematic)}_onDestroy(){i.ILaya3D.Physics3D._bullet.btMotionState_destroy(this._btLayaMotionState),super._onDestroy(),this._btLayaMotionState=null,this._gravity=null,this._totalTorque=null,this._linearVelocity=null,this._angularVelocity=null,this._linearFactor=null,this._angularFactor=null,this.constaintRigidbodyA&&this.constaintRigidbodyA._breakConstrained(),this.constaintRigidbodyB&&(this.constaintRigidbodyB.connectedBody=null,this.constaintRigidbodyB._onDisable())}_addToSimulation(){this._simulation._addRigidBody(this,this._collisionGroup,this._detectCollisions?this._canCollideWith:0)}_removeFromSimulation(){this._simulation._removeRigidBody(this)}_cloneTo(t){super._cloneTo(t);var i=t;i.isKinematic=this._isKinematic,i.mass=this._mass,i.gravity=this._gravity,i.angularDamping=this._angularDamping,i.linearDamping=this._linearDamping,i.overrideGravity=this._overrideGravity,i.linearVelocity=this._linearVelocity,i.angularVelocity=this._angularVelocity,i.linearFactor=this._linearFactor,i.angularFactor=this._angularFactor,i.detectCollisions=this._detectCollisions}applyForce(t,e=null){if(null==this._btColliderObject)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";var s=i.ILaya3D.Physics3D._bullet,o=T._btTempVector30;if(s.btVector3_setValue(o,-t.x,t.y,t.z),e){var r=T._btTempVector31;s.btVector3_setValue(r,-e.x,e.y,e.z),s.btRigidBody_applyForce(this._btColliderObject,o,r)}else s.btRigidBody_applyCentralForce(this._btColliderObject,o)}applyTorque(t){if(null==this._btColliderObject)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";var e=i.ILaya3D.Physics3D._bullet,s=T._btTempVector30;e.btVector3_setValue(s,-t.x,t.y,t.z),e.btRigidBody_applyTorque(this._btColliderObject,s)}applyImpulse(t,e=null){if(null==this._btColliderObject)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";var s=i.ILaya3D.Physics3D._bullet;s.btVector3_setValue(T._btImpulse,-t.x,t.y,t.z),e?(s.btVector3_setValue(T._btImpulseOffset,-e.x,e.y,e.z),s.btRigidBody_applyImpulse(this._btColliderObject,T._btImpulse,T._btImpulseOffset)):s.btRigidBody_applyCentralImpulse(this._btColliderObject,T._btImpulse)}applyTorqueImpulse(t){if(null==this._btColliderObject)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";var e=i.ILaya3D.Physics3D._bullet,s=T._btTempVector30;e.btVector3_setValue(s,-t.x,t.y,t.z),e.btRigidBody_applyTorqueImpulse(this._btColliderObject,s)}wakeUp(){this._btColliderObject&&i.ILaya3D.Physics3D._bullet.btCollisionObject_activate(this._btColliderObject,!1)}clearForces(){var t=this._btColliderObject;if(null==t)throw"Attempted to call a Physics function that is avaliable only when the Entity has been already added to the Scene.";var e=i.ILaya3D.Physics3D._bullet;e.btRigidBody_clearForces(t);var s=T._btVector3Zero;e.btCollisionObject_setInterpolationLinearVelocity(t,s),e.btRigidBody_setLinearVelocity(t,s),e.btCollisionObject_setInterpolationAngularVelocity(t,s),e.btRigidBody_setAngularVelocity(t,s)}}T.TYPE_STATIC=0,T.TYPE_DYNAMIC=1,T.TYPE_KINEMATIC=2,T._BT_DISABLE_WORLD_GRAVITY=1,T._BT_ENABLE_GYROPSCOPIC_FORCE=2;class S extends i.Component{constructor(t){super(),this._anchor=new i.Vector3,this._connectAnchor=new i.Vector3,this._feedbackEnabled=!1,this._getJointFeedBack=!1,this._currentForce=new i.Vector3,this._currentTorque=new i.Vector3,this._constraintType=t;var e=i.Physics3D._bullet;this._btframATrans=e.btTransform_create(),this._btframBTrans=e.btTransform_create(),e.btTransform_setIdentity(this._btframATrans),e.btTransform_setIdentity(this._btframBTrans),this._btframAPos=e.btVector3_create(0,0,0),this._btframBPos=e.btVector3_create(0,0,0),e.btTransform_setOrigin(this._btframATrans,this._btframAPos),e.btTransform_setOrigin(this._btframBTrans,this._btframBPos),this._breakForce=-1,this._breakTorque=-1}get enabled(){return super.enabled}set enabled(t){super.enabled=t}get appliedImpulse(){return this._feedbackEnabled||(this._btConstraint.EnableFeedback(!0),this._feedbackEnabled=!0),this._btConstraint.AppliedImpulse}set connectedBody(t){this._connectedBody=t,t&&(t.constaintRigidbodyB=this)}get connectedBody(){return this._connectedBody}get ownBody(){return this._ownBody}set ownBody(t){this._ownBody=t,t.constaintRigidbodyA=this}get currentForce(){return this._getJointFeedBack||this._getFeedBackInfo(),this._currentForce}get currentTorque(){return this._getJointFeedBack||this._getFeedBackInfo(),this._currentTorque}get breakForce(){return this._breakForce}set breakForce(t){this._breakForce=t}get breakTorque(){return this._breakTorque}set breakTorque(t){this._breakTorque=t}set anchor(t){t.cloneTo(this._anchor),this.setFrames()}get anchor(){return this._anchor}set connectAnchor(t){t.cloneTo(this._connectAnchor),this.setFrames()}get connectAnchor(){return this._connectAnchor}setOverrideNumSolverIterations(t){i.Physics3D._bullet.btTypedConstraint_setOverrideNumSolverIterations(this._btConstraint,t)}setConstraintEnabled(t){i.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,t)}_onEnable(){super._onEnable(),this.enabled=!0}_onDisable(){super._onDisable(),this.enabled=!1}setFrames(){var t=i.Physics3D._bullet;t.btVector3_setValue(this._btframAPos,-this._anchor.x,this.anchor.y,this.anchor.z),t.btVector3_setValue(this._btframBPos,-this._connectAnchor.x,this._connectAnchor.y,this._connectAnchor.z),t.btTransform_setOrigin(this._btframATrans,this._btframAPos),t.btTransform_setOrigin(this._btframBTrans,this._btframBPos)}_addToSimulation(){}_removeFromSimulation(){}_createConstraint(){}setConnectRigidBody(t,i){var e=t&&!!(t._simulation&&t._enabled&&t.colliderShape),s=i&&!!(i._simulation&&i._enabled&&i.colliderShape);if(!e||!s)throw"ownerRigid or connectRigidBody is not in Simulation";t==this._ownBody&&i==this._connectedBody||(!(!this.enabled||!this._simulation)&&this._removeFromSimulation(),this._ownBody=t,this._connectedBody=i,this._ownBody.constaintRigidbodyA=this,this._connectedBody.constaintRigidbodyB=this,this._createConstraint())}getcurrentForce(t){if(!this._btJointFeedBackObj)throw"this Constraint is not simulation";var e=i.Physics3D._bullet,s=e.btJointFeedback_getAppliedForceBodyA(this._btJointFeedBackObj);t.setValue(e.btVector3_x(s),e.btVector3_y(s),e.btVector3_z(s))}getcurrentTorque(t){if(!this._btJointFeedBackObj)throw"this Constraint is not simulation";var e=i.Physics3D._bullet,s=e.btJointFeedback_getAppliedTorqueBodyA(this._btJointFeedBackObj);t.setValue(e.btVector3_x(s),e.btVector3_y(s),e.btVector3_z(s))}_onDestroy(){var t=i.Physics3D._bullet;this._simulation&&this._removeFromSimulation(),this._btConstraint&&this._btJointFeedBackObj&&this._simulation&&(t.btTypedConstraint_destroy(this._btConstraint),t.btJointFeedback_destroy(this._btJointFeedBackObj),this._btJointFeedBackObj=null,this._btConstraint=null),super._onDisable()}_isBreakConstrained(){if(this._getJointFeedBack=!1,-1==this.breakForce&&-1==this.breakTorque)return!1;this._getFeedBackInfo();var t=-1!=this._breakForce&&i.Vector3.scalarLength(this._currentForce)>this._breakForce,e=-1!=this._breakTorque&&i.Vector3.scalarLength(this._currentTorque)>this._breakTorque;return!(!t&&!e)&&(this._breakConstrained(),!0)}_parse(t){this._anchor.fromArray(t.anchor),this._connectAnchor.fromArray(t.connectAnchor),this.setFrames()}_getFeedBackInfo(){var t=i.Physics3D._bullet,e=t.btJointFeedback_getAppliedForceBodyA(this._btJointFeedBackObj),s=t.btJointFeedback_getAppliedTorqueBodyA(this._btJointFeedBackObj);this._currentTorque.setValue(t.btVector3_x(s),t.btVector3_y(s),t.btVector3_z(s)),this._currentForce.setValue(t.btVector3_x(e),t.btVector3_y(e),t.btVector3_z(e)),this._getJointFeedBack=!0}_breakConstrained(){this.ownBody.constaintRigidbodyA=null,this.connectedBody&&(this.connectedBody.constaintRigidbodyB=null),this.destroy()}}S.CONSTRAINT_POINT2POINT_CONSTRAINT_TYPE=3,S.CONSTRAINT_HINGE_CONSTRAINT_TYPE=4,S.CONSTRAINT_CONETWIST_CONSTRAINT_TYPE=5,S.CONSTRAINT_D6_CONSTRAINT_TYPE=6,S.CONSTRAINT_SLIDER_CONSTRAINT_TYPE=7,S.CONSTRAINT_CONTACT_CONSTRAINT_TYPE=8,S.CONSTRAINT_D6_SPRING_CONSTRAINT_TYPE=9,S.CONSTRAINT_GEAR_CONSTRAINT_TYPE=10,S.CONSTRAINT_FIXED_CONSTRAINT_TYPE=11,S.CONSTRAINT_MAX_CONSTRAINT_TYPE=12,S.CONSTRAINT_CONSTRAINT_ERP=1,S.CONSTRAINT_CONSTRAINT_STOP_ERP=2,S.CONSTRAINT_CONSTRAINT_CFM=3,S.CONSTRAINT_CONSTRAINT_STOP_CFM=4,S.tempForceV3=new i.Vector3;class I extends S{constructor(){super(S.CONSTRAINT_D6_SPRING_CONSTRAINT_TYPE),this._axis=new i.Vector3,this._secondaryAxis=new i.Vector3,this._minLinearLimit=new i.Vector3,this._maxLinearLimit=new i.Vector3,this._minAngularLimit=new i.Vector3,this._maxAngularLimit=new i.Vector3,this._linearLimitSpring=new i.Vector3,this._angularLimitSpring=new i.Vector3,this._linearBounce=new i.Vector3,this._angularBounce=new i.Vector3,this._linearDamp=new i.Vector3,this._angularDamp=new i.Vector3,this._xMotion=0,this._yMotion=0,this._zMotion=0,this._angularXMotion=0,this._angularYMotion=0,this._angularZMotion=0;var t=i.Physics3D._bullet;this._btAxis=t.btVector3_create(-1,0,0),this._btSecondaryAxis=t.btVector3_create(0,1,0)}get axis(){return this._axis}get secondaryAxis(){return this._secondaryAxis}set maxAngularLimit(t){t.cloneTo(this._maxAngularLimit)}set minAngularLimit(t){t.cloneTo(this._minAngularLimit)}get maxAngularLimit(){return this._maxAngularLimit}get minAngularLimit(){return this._minAngularLimit}set maxLinearLimit(t){t.cloneTo(this._maxLinearLimit)}set minLinearLimit(t){t.cloneTo(this._minLinearLimit)}get maxLinearLimit(){return this._maxLinearLimit}get minLinearLimit(){return this._minLinearLimit}set XMotion(t){this._xMotion!=t&&(this._xMotion=t,this.setLimit(I.MOTION_LINEAR_INDEX_X,t,-this._maxLinearLimit.x,-this._minLinearLimit.x))}get XMotion(){return this._xMotion}set YMotion(t){this._yMotion!=t&&(this._yMotion=t,this.setLimit(I.MOTION_LINEAR_INDEX_Y,t,this._minLinearLimit.y,this._maxLinearLimit.y))}get YMotion(){return this._yMotion}set ZMotion(t){this._zMotion!=t&&(this._zMotion=t,this.setLimit(I.MOTION_LINEAR_INDEX_Z,t,this._minLinearLimit.z,this._maxLinearLimit.z))}get ZMotion(){return this._zMotion}set angularXMotion(t){this._angularXMotion!=t&&(this._angularXMotion=t,this.setLimit(I.MOTION_ANGULAR_INDEX_X,t,-this._maxAngularLimit.x,-this._minAngularLimit.x))}get angularXMotion(){return this._angularXMotion}set angularYMotion(t){this._angularYMotion!=t&&(this._angularYMotion=t,this.setLimit(I.MOTION_ANGULAR_INDEX_Y,t,this._minAngularLimit.y,this._maxAngularLimit.y))}get angularYMotion(){return this._angularYMotion}set angularZMotion(t){this._angularZMotion!=t&&(this._angularZMotion=t,this.setLimit(I.MOTION_ANGULAR_INDEX_Z,t,this._minAngularLimit.z,this._maxAngularLimit.z))}get angularZMotion(){return this._angularZMotion}set linearLimitSpring(t){i.Vector3.equals(this._linearLimitSpring,t)||(t.cloneTo(this._linearLimitSpring),this.setSpring(I.MOTION_LINEAR_INDEX_X,t.x),this.setSpring(I.MOTION_LINEAR_INDEX_Y,t.y),this.setSpring(I.MOTION_LINEAR_INDEX_Z,t.z))}get linearLimitSpring(){return this._linearLimitSpring}set angularLimitSpring(t){i.Vector3.equals(this._angularLimitSpring,t)||(t.cloneTo(this._angularLimitSpring),this.setSpring(I.MOTION_ANGULAR_INDEX_X,t.x),this.setSpring(I.MOTION_ANGULAR_INDEX_Y,t.y),this.setSpring(I.MOTION_ANGULAR_INDEX_Z,t.z))}get angularLimitSpring(){return this._angularLimitSpring}set linearBounce(t){i.Vector3.equals(this._linearBounce,t)||(t.cloneTo(this._linearBounce),this.setBounce(I.MOTION_LINEAR_INDEX_X,t.x),this.setBounce(I.MOTION_LINEAR_INDEX_Y,t.y),this.setBounce(I.MOTION_LINEAR_INDEX_Z,t.z))}get linearBounce(){return this._linearBounce}set angularBounce(t){i.Vector3.equals(this._angularBounce,t)||(t.cloneTo(this._angularBounce),this.setBounce(I.MOTION_ANGULAR_INDEX_X,t.x),this.setBounce(I.MOTION_ANGULAR_INDEX_Y,t.y),this.setBounce(I.MOTION_ANGULAR_INDEX_Z,t.z))}get angularBounce(){return this._angularBounce}set linearDamp(t){i.Vector3.equals(this._linearDamp,t)||(t.cloneTo(this._linearDamp),this.setDamping(I.MOTION_LINEAR_INDEX_X,t.x),this.setDamping(I.MOTION_LINEAR_INDEX_Y,t.y),this.setDamping(I.MOTION_LINEAR_INDEX_Z,t.z))}get linearDamp(){return this._linearDamp}set angularDamp(t){i.Vector3.equals(this._angularDamp,t)||(t.cloneTo(this._angularDamp),this.setDamping(I.MOTION_ANGULAR_INDEX_X,t.x),this.setDamping(I.MOTION_ANGULAR_INDEX_Y,t.y),this.setDamping(I.MOTION_ANGULAR_INDEX_Z,t.z))}get angularDamp(){return this._angularDamp}set anchor(t){t.cloneTo(this._anchor),this.setFrames()}get anchor(){return this._anchor}set connectAnchor(t){t.cloneTo(this._connectAnchor),this.setFrames()}get connectAnchor(){return this._connectAnchor}setAxis(t,e){if(this._btConstraint){var s=i.Physics3D._bullet;this._axis.setValue(t.x,t.y,t.y),this._secondaryAxis.setValue(e.x,e.y,e.z),this._btAxis=s.btVector3_setValue(-t.x,t.y,t.z),this._btSecondaryAxis=s.btVector3_setValue(-e.x,e.y,e.z),s.btGeneric6DofSpring2Constraint_setAxis(this._btConstraint,this._btAxis,this._btSecondaryAxis)}}setLimit(t,e,s,o){if(this._btConstraint){var r=i.Physics3D._bullet;switch(e){case I.CONFIG_MOTION_TYPE_LOCKED:r.btGeneric6DofSpring2Constraint_setLimit(this._btConstraint,t,0,0);break;case I.CONFIG_MOTION_TYPE_LIMITED:s0;o.btGeneric6DofSpring2Constraint_enableSpring(this._btConstraint,t,r),r&&o.btGeneric6DofSpring2Constraint_setStiffness(this._btConstraint,t,e,s)}}setBounce(t,e){this._btConstraint&&(e=e<=0?0:e,i.Physics3D._bullet.btGeneric6DofSpring2Constraint_setBounce(this._btConstraint,t,e))}setDamping(t,e,s=!0){this._btConstraint&&(e=e<=0?0:e,i.Physics3D._bullet.btGeneric6DofSpring2Constraint_setDamping(this._btConstraint,t,e,s))}setEquilibriumPoint(t,e){i.Physics3D._bullet.btGeneric6DofSpring2Constraint_setEquilibriumPoint(this._btConstraint,t,e)}enableMotor(t,e){i.Physics3D._bullet.btGeneric6DofSpring2Constraint_enableMotor(this._btConstraint,t,e)}setServo(t,e){i.Physics3D._bullet.btGeneric6DofSpring2Constraint_setServo(this._btConstraint,t,e)}setTargetVelocity(t,e){i.Physics3D._bullet.btGeneric6DofSpring2Constraint_setTargetVelocity(this._btConstraint,t,e)}setTargetPosition(t,e){i.Physics3D._bullet.btGeneric6DofSpring2Constraint_setServoTarget(this._btConstraint,t,e)}setMaxMotorForce(t,e){i.Physics3D._bullet.btGeneric6DofSpring2Constraint_setMaxMotorForce(this._btConstraint,t,e)}setParam(t,e,s){i.Physics3D._bullet.btTypedConstraint_setParam(this._btConstraint,t,e,s)}setFrames(){super.setFrames();var t=i.Physics3D._bullet;this._btConstraint&&t.btGeneric6DofSpring2Constraint_setFrames(this._btConstraint,this._btframATrans,this._btframBTrans)}_addToSimulation(){this._simulation&&this._simulation.addConstraint(this,this.enabled)}_removeFromSimulation(){this._simulation.removeConstraint(this),this._simulation=null}_createConstraint(){var t=i.Physics3D._bullet;this._btConstraint=t.btGeneric6DofSpring2Constraint_create(this.ownBody.btColliderObject,this._btframAPos,this.connectedBody.btColliderObject,this._btframBPos,I.RO_XYZ),this._btJointFeedBackObj=t.btJointFeedback_create(this._btConstraint),t.btTypedConstraint_setJointFeedback(this._btConstraint,this._btJointFeedBackObj),this._simulation=this.owner._scene.physicsSimulation,this._initAllConstraintInfo(),this._addToSimulation(),i.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,!0)}_initAllConstraintInfo(){this.setLimit(I.MOTION_LINEAR_INDEX_X,this._xMotion,-this._maxLinearLimit.x,-this._minLinearLimit.x),this.setLimit(I.MOTION_LINEAR_INDEX_Y,this._yMotion,this._minLinearLimit.y,this._maxLinearLimit.y),this.setLimit(I.MOTION_LINEAR_INDEX_Z,this._zMotion,this._minLinearLimit.z,this._maxLinearLimit.z),this.setLimit(I.MOTION_ANGULAR_INDEX_X,this._angularXMotion,-this._maxAngularLimit.x,-this._minAngularLimit.x),this.setLimit(I.MOTION_ANGULAR_INDEX_Y,this._angularYMotion,this._minAngularLimit.y,this._maxAngularLimit.y),this.setLimit(I.MOTION_ANGULAR_INDEX_Z,this._angularZMotion,this._minAngularLimit.z,this._maxAngularLimit.z),this.setSpring(I.MOTION_LINEAR_INDEX_X,this._linearLimitSpring.x),this.setSpring(I.MOTION_LINEAR_INDEX_Y,this._linearLimitSpring.y),this.setSpring(I.MOTION_LINEAR_INDEX_Z,this._linearLimitSpring.z),this.setSpring(I.MOTION_ANGULAR_INDEX_X,this._angularLimitSpring.x),this.setSpring(I.MOTION_ANGULAR_INDEX_Y,this._angularLimitSpring.y),this.setSpring(I.MOTION_ANGULAR_INDEX_Z,this._angularLimitSpring.z),this.setBounce(I.MOTION_LINEAR_INDEX_X,this._linearBounce.x),this.setBounce(I.MOTION_LINEAR_INDEX_Y,this._linearBounce.y),this.setBounce(I.MOTION_LINEAR_INDEX_Z,this._linearBounce.z),this.setBounce(I.MOTION_ANGULAR_INDEX_X,this._angularBounce.x),this.setBounce(I.MOTION_ANGULAR_INDEX_Y,this._angularBounce.y),this.setBounce(I.MOTION_ANGULAR_INDEX_Z,this._angularBounce.z),this.setDamping(I.MOTION_LINEAR_INDEX_X,this._linearDamp.x),this.setDamping(I.MOTION_LINEAR_INDEX_Y,this._linearDamp.y),this.setDamping(I.MOTION_LINEAR_INDEX_Z,this._linearDamp.z),this.setDamping(I.MOTION_ANGULAR_INDEX_X,this._angularDamp.x),this.setDamping(I.MOTION_ANGULAR_INDEX_Y,this._angularDamp.y),this.setDamping(I.MOTION_ANGULAR_INDEX_Z,this._angularDamp.z),this.setFrames(),this.setEquilibriumPoint(0,0)}_onAdded(){super._onAdded()}_onEnable(){this._btConstraint&&(super._onEnable(),this._btConstraint&&i.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,!0))}_onDisable(){super._onDisable(),!this.connectedBody&&this._simulation&&this._removeFromSimulation(),this._btConstraint&&i.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,!1)}_parse(t,i=null){super._parse(t),this._axis.fromArray(t.axis),this._secondaryAxis.fromArray(t.secondaryAxis);var e=t.linearLimit;this._minLinearLimit.setValue(-e,-e,-e),this._maxLinearLimit.setValue(e,e,e);var s=t.linearLimitSpring;this._linearLimitSpring.setValue(s,s,s);var o=t.linearLimitDamper;this._linearDamp.setValue(o,o,o);var r=t.linearLimitBounciness;this._linearBounce.setValue(r,r,r);var a=t.lowAngularXLimit,n=t.highAngularXLimit,l=t.angularYLimit,_=t.angularZLimit;this._minAngularLimit.setValue(a,-l,-_),this._maxAngularLimit.setValue(n,l,_);var h=t.highAngularXLimitBounciness,c=t.angularYLimitBounciness,b=t.angularZLimitBounciness;this._angularBounce.setValue(h,c,b);var d=t.angularXLimitSpring,u=t.angularYZLimitSpring;this._angularLimitSpring.setValue(d,u,u);var C=t.angularXLimitDamper,y=t.angularYZLimitDamper;this._angularDamp.setValue(C,y,y),this.XMotion=t.xMotion,this.YMotion=t.yMotion,this.ZMotion=t.zMotion,this.angularXMotion=t.angularXMotion,this.angularYMotion=t.angularYMotion,this.angularZMotion=t.angularZMotion,-1!=t.rigidbodyID&&-1!=t.connectRigidbodyID&&(i.component.push(this),i.data.push(t)),null!=t.breakForce&&(this.breakForce=t.breakForce),null!=t.breakTorque&&(this.breakTorque=t.breakTorque)}_parseInteractive(t=null,i=null){var e=i[t.rigidbodyID].getComponent(T),s=i[t.connectRigidbodyID].getComponent(T);this.ownBody=e,this.connectedBody=s}_onDestroy(){super._onDestroy()}}I.CONFIG_MOTION_TYPE_LOCKED=0,I.CONFIG_MOTION_TYPE_LIMITED=1,I.CONFIG_MOTION_TYPE_FREE=2,I.MOTION_LINEAR_INDEX_X=0,I.MOTION_LINEAR_INDEX_Y=1,I.MOTION_LINEAR_INDEX_Z=2,I.MOTION_ANGULAR_INDEX_X=3,I.MOTION_ANGULAR_INDEX_Y=4,I.MOTION_ANGULAR_INDEX_Z=5,I.RO_XYZ=0,I.RO_XZY=1,I.RO_YXZ=2,I.RO_YZX=3,I.RO_ZXY=4,I.RO_ZYX=5;class O extends e{constructor(t,s){super(),this._normal=t,this._offset=s,this._type=e.SHAPETYPES_STATICPLANE;var o=i.ILaya3D.Physics3D._bullet;o.btVector3_setValue(O._btNormal,-t.x,t.y,t.z),this._btShape=o.btStaticPlaneShape_create(O._btNormal,s)}static __init__(){O._btNormal=i.ILaya3D.Physics3D._bullet.btVector3_create(0,0,0)}clone(){var t=new O(this._normal,this._offset);return this.cloneTo(t),t}}t.BoxColliderShape=s,t.BulletInteractive=c,t.CapsuleColliderShape=o,t.CharacterController=b,t.ColliderShape=e,t.Collision=d,t.CollisionTool=y,t.CompoundColliderShape=r,t.ConeColliderShape=a,t.ConfigurableConstraint=I,t.Constraint3D=class{constructor(){}},t.ConstraintComponent=S,t.ContactPoint=u,t.CylinderColliderShape=n,t.FixedConstraint=class extends S{constructor(){super(S.CONSTRAINT_FIXED_CONSTRAINT_TYPE),this.breakForce=-1,this.breakTorque=-1}_addToSimulation(){this._simulation&&this._simulation.addConstraint(this,this.enabled)}_removeFromSimulation(){this._simulation.removeConstraint(this),this._simulation=null}_createConstraint(){if(this.ownBody&&this.ownBody._simulation&&this.connectedBody&&this.connectedBody._simulation){var t=i.Physics3D._bullet;this._btConstraint=t.btFixedConstraint_create(this.ownBody.btColliderObject,this._btframATrans,this.connectedBody.btColliderObject,this._btframBTrans),this._btJointFeedBackObj=t.btJointFeedback_create(this._btConstraint),t.btTypedConstraint_setJointFeedback(this._btConstraint,this._btJointFeedBackObj),this._simulation=this.owner._scene.physicsSimulation,this._addToSimulation(),i.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,!0)}}_onAdded(){super._onAdded()}_onEnable(){this._btConstraint&&(super._onEnable(),this._btConstraint&&i.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,!0))}_onDisable(){super._onDisable(),this.connectedBody||this._removeFromSimulation(),this._btConstraint&&i.Physics3D._bullet.btTypedConstraint_setEnabled(this._btConstraint,!1)}_onDestroy(){super._onDestroy()}_parse(t,i=null){super._parse(t),-1!=t.rigidbodyID&&-1!=t.connectRigidbodyID&&(i.component.push(this),i.data.push(t)),null!=t.breakForce&&(this.breakForce=t.breakForce),null!=t.breakTorque&&(this.breakTorque=t.breakTorque)}_parseInteractive(t=null,i=null){var e=i[t.rigidbodyID].getComponent(T),s=i[t.connectRigidbodyID].getComponent(T);this.ownBody=e,this.connectedBody=s}},t.HitResult=C,t.MeshColliderShape=l,t.PhysicsCollider=class extends m{constructor(t=i.Physics3DUtils.COLLISIONFILTERGROUP_DEFAULTFILTER,e=i.Physics3DUtils.COLLISIONFILTERGROUP_ALLFILTER){super(t,e),this._enableProcessCollisions=!1}_addToSimulation(){this._simulation._addPhysicsCollider(this,this._collisionGroup,this._canCollideWith)}_removeFromSimulation(){this._simulation._removePhysicsCollider(this)}_parse(t){null!=t.friction&&(this.friction=t.friction),null!=t.rollingFriction&&(this.rollingFriction=t.rollingFriction),null!=t.restitution&&(this.restitution=t.restitution),null!=t.isTrigger&&(this.isTrigger=t.isTrigger),super._parse(t),this._parseShape(t.shapes)}_onAdded(){var t=i.Physics3D._bullet,e=t.btCollisionObject_create();t.btCollisionObject_setUserIndex(e,this.id),t.btCollisionObject_forceActivationState(e,h.ACTIVATIONSTATE_DISABLE_SIMULATION);var s=t.btCollisionObject_getCollisionFlags(e);this.owner.isStatic?((s&h.COLLISIONFLAGS_KINEMATIC_OBJECT)>0&&(s^=h.COLLISIONFLAGS_KINEMATIC_OBJECT),s|=h.COLLISIONFLAGS_STATIC_OBJECT):((s&h.COLLISIONFLAGS_STATIC_OBJECT)>0&&(s^=h.COLLISIONFLAGS_STATIC_OBJECT),s|=h.COLLISIONFLAGS_KINEMATIC_OBJECT),t.btCollisionObject_setCollisionFlags(e,s),this._btColliderObject=e,super._onAdded()}},t.PhysicsComponent=h,t.PhysicsSettings=class{constructor(){this.flags=0,this.maxSubSteps=1,this.fixedTimeStep=1/60}},t.PhysicsSimulation=g,t.PhysicsTriggerComponent=m,t.PhysicsUpdateList=p,t.Rigidbody3D=T,t.SphereColliderShape=_,t.StaticPlaneColliderShape=O}(window.Laya=window.Laya||{},Laya); \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/min/laya.physics3D.wasm.wasm b/examples/layaair/frontend/bin/libs/min/laya.physics3D.wasm.wasm new file mode 100644 index 0000000..a33b255 Binary files /dev/null and b/examples/layaair/frontend/bin/libs/min/laya.physics3D.wasm.wasm differ diff --git a/examples/layaair/frontend/bin/libs/min/laya.qqmini.min.js b/examples/layaair/frontend/bin/libs/min/laya.qqmini.min.js new file mode 100644 index 0000000..3f8bdd6 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/min/laya.qqmini.min.js @@ -0,0 +1 @@ +window.qqMiniGame=function(e,t){"use strict";function ImageDataPolyfill(){let e,i,a;if(3==arguments.length){if(!(arguments[0]instanceof Uint8ClampedArray))throw new Error("Failed to construct 'ImageData': parameter 1 is not of type 'Uint8ClampedArray'.");if(arguments[0].length%4!=0)throw new Error("Failed to construct 'ImageData': The input data length is not a multiple of 4.");if(arguments[0].length!==arguments[1]*arguments[2]*4)throw new Error("Failed to construct 'ImageData': The input data length is not equal to (4 * width * height).");a=arguments[0],e=arguments[1],i=arguments[2]}else if(2==arguments.length)e=arguments[0],i=arguments[1],a=new Uint8ClampedArray(arguments[0]*arguments[1]*4);else if(arguments.length<2)throw new Error("Failed to construct 'ImageData': 2 arguments required, but only "+arguments.length+" present.");let n=t.Browser.canvas.getContext("2d").getImageData(0,0,e,i);for(let e=0;e=f&&(t.size>r.minClearSize&&(r.minClearSize=t.size),i.onClearCacheRes()),i.deleteFile(e,a,n,o,t.size)},fail:function(e){null!=n&&n.runWith([1,e])}}):null!=n&&n.runWith([0]):i.fs.getFileInfo({filePath:e,success:function(t){s&&m+4194304+t.size>=f&&(t.size>r.minClearSize&&(r.minClearSize=t.size),i.onClearCacheRes()),i.fs.copyFile({srcPath:e,destPath:h,success:function(e){i.onSaveFile(a,d,!0,o,n,t.size)},fail:function(e){null!=n&&n.runWith([1,e])}})},fail:function(e){null!=n&&n.runWith([1,e])}})}static onClearCacheRes(){var e=r.minClearSize,t=[];for(var a in i.filesListObj)"fileUsedSize"!=a&&t.push(i.filesListObj[a]);i.sortOn(t,"times",i.NUMERIC);for(var n=0,o=1,s=t.length;o=e)break;n+=l.size,i.deleteFile("",l.readyUrl)}}static sortOn(e,t,a=0){return a==i.NUMERIC?e.sort((function(e,i){return e[t]-i[t]})):a==(i.NUMERIC|i.DESCENDING)?e.sort((function(e,i){return i[t]-e[t]})):e.sort((function(e,i){return e[t]-i[t]}))}static getFileNativePath(e){return i.fileNativeDir+"/"+e}static deleteFile(e,t="",a=null,n="",o=0){var s=i.getFileInfo(t),l=i.getFileNativePath(s.md5);i.fs.unlink({filePath:l,success:function(s){if(""!=e){var l=i.getFileNativePath(e);i.fs.copyFile({srcPath:e,destPath:l,success:function(s){i.onSaveFile(t,e,!0,n,a,o)},fail:function(e){null!=a&&a.runWith([1,e])}})}else i.onSaveFile(t,e,!1,n,a,o)},fail:function(e){null!=a&&a.runWith([1,e])}})}static deleteAll(){var e=[];for(var t in i.filesListObj)"fileUsedSize"!=t&&e.push(i.filesListObj[t]);for(var a=1,n=e.length;a0&&this.loops--,this.startTime=0,this.play()}play(){this.isStopped=!1,t.SoundManager.addChannel(this),this._audio.play()}set startTime(e){this._audio&&(this._audio.startTime=e)}set autoplay(e){this._audio.autoplay=e}get autoplay(){return this._audio.autoplay}get position(){return this._audio?this._audio.currentTime:0}get duration(){return this._audio?this._audio.duration:0}stop(){this.isStopped=!0,t.SoundManager.removeChannel(this),this.completeHandler=null,this._audio&&(this._audio.stop(),this.loop||(this._audio.offEnded(null),this._miniSound.dispose(),this._audio=null,this._miniSound=null,this._onEnd=null))}pause(){this.isStopped=!0,this._audio.pause()}get loop(){return this._audio.loop}set loop(e){this._audio.loop=e}resume(){this._audio&&(this.isStopped=!1,t.SoundManager.addChannel(this),this._audio.play())}set volume(e){this._audio&&(this._audio.volume=e)}get volume(){return this._audio?this._audio.volume:1}}class n extends t.EventDispatcher{constructor(){super(),this.loaded=!1}static _createSound(){return n._id++,r.window.qq.createInnerAudioContext()}load(e){if(n._musicAudio||(n._musicAudio=n._createSound()),i.isLocalNativeFile(e)){if(-1!=e.indexOf("http://")||-1!=e.indexOf("https://"))if(""!=i.loadPath)e=e.split(i.loadPath)[1];else{var a=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath;""!=a&&(e=e.split(a)[1])}}else e=t.URL.formatURL(e);if(this.url=e,this.readyUrl=e,n._audioCache[this.readyUrl])this.event(t.Event.COMPLETE);else if(r.autoCacheFile&&i.getFileInfo(e))this.onDownLoadCallBack(e,0);else if(r.autoCacheFile)if(i.isLocalNativeFile(e)){var o=e;if(""!=(a=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath)&&(e=e.split(a)[1]),e||(e=o),r.subNativeFiles&&0==r.subNativeheads.length)for(var s in r.subNativeFiles){var l=r.subNativeFiles[s];r.subNativeheads=r.subNativeheads.concat(l);for(var d=0;d=0?"/":"\\",o=e.lastIndexOf(n),s=o>=0?e.substr(0,o+1):"",l=0,d=a.length;l>>"+n)}}return t},r._inited=!1,r.autoCacheFile=!0,r.minClearSize=5242880,r.sizeLimit=52428800,r.nativefiles=["layaNativeDir","wxlocal"],r.subNativeFiles=[],r.subNativeheads=[],r.subMaps=[],r.AutoCacheDownFile=!1,r.parseXMLFromString=function(e){var t;e=e.replace(/>\s+<");try{t=(new r.window.Parser.DOMParser).parseFromString(e,"text/xml")}catch(e){throw"需要引入xml解析库文件"}return t},r.idx=1;class d extends t.EventDispatcher{constructor(){super()}static __init__(){try{var e;if(!(e=t.Accelerator))return;e.prototype.on=d.prototype.on,e.prototype.off=d.prototype.off}catch(e){}}static startListen(e){if(d._callBack=e,!d._isListening){d._isListening=!0;try{r.window.qq.onAccelerometerChange(d.onAccelerometerChange)}catch(e){}}}static stopListen(){d._isListening=!1;try{r.window.qq.stopAccelerometer({})}catch(e){}}static onAccelerometerChange(e){var t;(t={}).acceleration=e,t.accelerationIncludingGravity=e,t.rotationRate={},null!=d._callBack&&d._callBack(t)}on(e,t,i,a=null){return super.on(e,t,i,a),d.startListen(this.onDeviceOrientationChange),this}off(e,t,i,a=!1){return this.hasListener(e)||d.stopListen(),super.off(e,t,i,a)}}d._isListening=!1;class u{_loadImage(e){if(r.isZiYu)u.onCreateImage(e,this,!0);else{var a;if(i.isLocalNativeFile(e)){if(-1==e.indexOf(r.window.qq.env.USER_DATA_PATH)&&(-1!=e.indexOf("http://")||-1!=e.indexOf("https://")))if(""!=i.loadPath)e=e.split(i.loadPath)[1];else{var n=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath,o=e;""!=n&&(e=e.split(n)[1]),e||(e=o)}if(r.subNativeFiles&&0==r.subNativeheads.length)for(var s in r.subNativeFiles){var l=r.subNativeFiles[s];r.subNativeheads=r.subNativeheads.concat(l);for(var d=0;d=f&&(t.size>l.minClearSize&&(l.minClearSize=t.size),i.onClearCacheRes()),i.deleteFile(e,a,n,s,t.size)},fail:function(e){null!=n&&n.runWith([1,e])}}):null!=n&&n.runWith([0]):i.fs.getFileInfo({filePath:e,success:function(t){o&&m+4194304+t.size>=f&&(t.size>l.minClearSize&&(l.minClearSize=t.size),i.onClearCacheRes()),i.fs.copyFile({srcPath:e,destPath:h,success:function(e){i.onSaveFile(a,d,!0,s,n,t.size)},fail:function(e){null!=n&&n.runWith([1,e])}})},fail:function(e){null!=n&&n.runWith([1,e])}})}static onClearCacheRes(){var e=l.minClearSize,t=[];for(var a in i.filesListObj)"fileUsedSize"!=a&&t.push(i.filesListObj[a]);i.sortOn(t,"times",i.NUMERIC);for(var n=0,s=1,o=t.length;s=e)break;n+=r.size,i.deleteFile("",r.readyUrl)}}static sortOn(e,t,a=0){return a==i.NUMERIC?e.sort((function(e,i){return e[t]-i[t]})):a==(i.NUMERIC|i.DESCENDING)?e.sort((function(e,i){return i[t]-e[t]})):e.sort((function(e,i){return e[t]-i[t]}))}static getFileNativePath(e){return i.fileNativeDir+"/"+e}static deleteFile(e,t="",a=null,n="",s=0){var o=i.getFileInfo(t),l=i.getFileNativePath(o.md5);i.fs.unlink({filePath:l,success:function(o){if(""!=e){var l=i.getFileNativePath(e);i.fs.copyFile({srcPath:e,destPath:l,success:function(o){i.onSaveFile(t,e,!0,n,a,s)},fail:function(e){null!=a&&a.runWith([1,e])}})}else i.onSaveFile(t,e,!1,n,a,s)},fail:function(e){null!=a&&a.runWith([1,e])}})}static deleteAll(){var e=[];for(var t in i.filesListObj)"fileUsedSize"!=t&&e.push(i.filesListObj[t]);for(var a=1,n=e.length;a0&&this.loops--,this.startTime=0,this.play()}play(){this.isStopped=!1,t.SoundManager.addChannel(this),this._audio.play()}set startTime(e){this._audio&&(this._audio.startTime=e)}set autoplay(e){this._audio.autoplay=e}get autoplay(){return this._audio.autoplay}get position(){return this._audio?this._audio.currentTime:0}get duration(){return this._audio?this._audio.duration:0}stop(){this.isStopped=!0,t.SoundManager.removeChannel(this),this.completeHandler=null,this._audio&&(this._audio.stop(),this.loop||(this._audio.offEnded(null),this._miniSound.dispose(),this._audio=null,this._miniSound=null,this._onEnd=null))}pause(){this.isStopped=!0,this._audio.pause()}get loop(){return this._audio.loop}set loop(e){this._audio.loop=e}resume(){this._audio&&(this.isStopped=!1,t.SoundManager.addChannel(this),this._audio.play())}set volume(e){this._audio&&(this._audio.volume=e)}get volume(){return this._audio?this._audio.volume:1}}class n extends t.EventDispatcher{constructor(){super(),this.loaded=!1}static _createSound(){return n._id++,l.window.qg.createInnerAudioContext()}load(e){if(n._musicAudio||(n._musicAudio=n._createSound()),i.isLocalNativeFile(e)){if(-1!=e.indexOf("http://")||-1!=e.indexOf("https://"))if(""!=i.loadPath)e=e.split(i.loadPath)[1];else{var a=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath;""!=a&&(e=e.split(a)[1])}}else e=t.URL.formatURL(e);if(this.url=e,this.readyUrl=e,n._audioCache[this.readyUrl])this.event(t.Event.COMPLETE);else if(l.autoCacheFile&&i.getFileInfo(e))this.onDownLoadCallBack(e,0);else if(l.autoCacheFile)if(i.isLocalNativeFile(e)){var s=e;if(""!=(a=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath)&&(e=e.split(a)[1]),e||(e=s),l.subNativeFiles&&0==l.subNativeheads.length)for(var o in l.subNativeFiles){var r=l.subNativeFiles[o];l.subNativeheads=l.subNativeheads.concat(r);for(var d=0;d=0?"/":"\\",s=e.lastIndexOf(n),o=s>=0?e.substr(0,s+1):"",r=0,d=a.length;r>>"+n)}}return t},l._inited=!1,l.systemInfo={},l.autoCacheFile=!0,l.minClearSize=5242880,l.sizeLimit=52428800,l.nativefiles=["layaNativeDir"],l.subNativeheads=[],l.subMaps=[],l.AutoCacheDownFile=!1,l.parseXMLFromString=function(e){var t;e=e.replace(/>\s+<");try{t=(new window.DOMParser).parseFromString(e,"text/xml")}catch(e){throw"需要引入xml解析库文件"}return t},l.idx=1;class r extends t.EventDispatcher{constructor(){super()}static __init__(){try{var e;if(!(e=t.Accelerator))return;e.prototype.on=r.prototype.on,e.prototype.off=r.prototype.off}catch(e){}}static startListen(e){if(r._callBack=e,!r._isListening){r._isListening=!0;try{l.window.qg.onAccelerometerChange(r.onAccelerometerChange)}catch(e){}}}static stopListen(){r._isListening=!1;try{l.window.qg.stopAccelerometer({})}catch(e){}}static onAccelerometerChange(e){var t;(t={}).acceleration=e,t.accelerationIncludingGravity=e,t.rotationRate={},null!=r._callBack&&r._callBack(t)}on(e,t,i,a=null){return super.on(e,t,i,a),r.startListen(this.onDeviceOrientationChange),this}off(e,t,i,a=!1){return this.hasListener(e)||r.stopListen(),super.off(e,t,i,a)}}r._isListening=!1;class d{_loadImage(e){if(l.isZiYu)d.onCreateImage(e,this,!0);else{var a;if(i.isLocalNativeFile(e)){if(-1==e.indexOf("http://usr/")&&(-1!=e.indexOf("http://")||-1!=e.indexOf("https://")))if(""!=i.loadPath)e=e.split(i.loadPath)[1];else{var n=""!=t.URL.rootPath?t.URL.rootPath:t.URL.basePath,s=e;""!=n&&(e=e.split(n)[1]),e||(e=s)}if(l.subNativeFiles&&0==l.subNativeheads.length)for(var o in l.subNativeFiles){var r=l.subNativeFiles[o];l.subNativeheads=l.subNativeheads.concat(r);for(var u=0;u=0&&s==E.data.index&&(v=!0),!v){u.clipEndWithSlot(E);continue}i>=0&&i==E.data.index&&(v=!1);let b,D=E.getAttachment(),C=null;if(D instanceof l){let e=D;y.vertices=this.vertices,y.numVertices=4,y.numFloats=w<<2,e.computeWorldVertices(E.bone,y.vertices,0,w),f=p.QUAD_TRIANGLES,A=e.uvs,C=e.region.renderObject.page.name,b=a[C],x=e.color}else{if(!(D instanceof h)){if(D instanceof o){let e=D;u.clipStart(E,e);continue}u.clipEndWithSlot(E);continue}{let e=D;y.vertices=this.vertices,y.numVertices=e.worldVerticesLength>>1,y.numFloats=y.numVertices*w,y.numFloats>y.vertices.length&&(y.vertices=this.vertices=r.newFloatArray(y.numFloats)),e.computeWorldVertices(E,0,e.worldVerticesLength,y.vertices,0,w),f=e.triangles,C=e.region.renderObject.page.name,b=a[C],A=e.uvs,x=e.color}}if(null!=b){let e=E.color,s=this.tempColor;s.r=S.r*e.r*x.r,s.g=S.g*e.g*x.g,s.b=S.b*e.b*x.b,s.a=S.a*e.a*x.a,d&&(s.r*=s.a,s.g*=s.a,s.b*=s.a);let i=E.data.blendMode;if(u.isClipping()){u.clipTriangles(y.vertices,y.numFloats,f,f.length,A,s,null,!1);let e=new Float32Array(u.clippedVertices),a=u.clippedTriangles,r=[],l=[],h=[];if(null!=this.vertexEffect){let t=this.vertexEffect,s=e;for(let i=0,n=e.length;in)throw new Error("SpineSkeleton: start must less than end.");if("number"==typeof l&&(l=this.getAniNameByIndex(e)),s||this._pause||this._currAniName!=l){this._currAniName=l,this.state.setAnimation(this.trackIndex,l,t);let e=this.state.getCurrent(this.trackIndex);e.animationStart=i,n&&n0&&this._onAniSoundStoped(!0))}paused(){if(!this._pause&&(this._pause=!0,this.timer.clear(this,this._update),this.event(t.Event.PAUSED),this._soundChannelArr.length>0))for(var e,s=this._soundChannelArr.length,i=0;i0))for(var e,t=this._soundChannelArr.length,s=0;s0&&this._onAniSoundStoped(!0)}get templet(){return this._templet}addAnimation(e,t=!1,s=0){s/=1e3;var i=e;"number"==typeof i&&(i=this.getAniNameByIndex(i)),this._currAniName=i,this.state.addAnimation(this.trackIndex,i,t,s)}setMix(e,t,s){s/=1e3;var i=e;"number"==typeof i&&(i=this.getAniNameByIndex(i));var n=t;"number"==typeof n&&(n=this.getAniNameByIndex(n)),this.stateData.setMix(i,n,s)}getBoneByName(e){return this.skeleton.findBone(e)}getSkeleton(){return this.skeleton}setSlotAttachment(e,t){this.skeleton.setAttachment(e,t)}set currentTime(e){if(this._currAniName&&this._templet){if((e/=1e3)this._playEnd||e>this._duration)throw new Error("AnimationPlayer: value must large than playStartTime,small than playEndTime.");this.state.update(e-this.currentPlayTime),this.currentPlayTime=e}}get playState(){return this._currAniName?this._pause?_.paused:_.playing:_.stopped}}_.stopped=0,_.paused=1,_.playing=2,t.ILaya.regClass(_),t.ClassUtils.regClass("laya.layaspine.SpineSkeleton",_),t.ClassUtils.regClass("Laya.SpineSkeleton",_);var y=spine.SharedAssetManager,A=spine.TextureAtlas,f=spine.AtlasAttachmentLoader,k=spine.SkeletonJson;class x extends t.Resource{constructor(){super(),this._textureDic={},this._isDestroyed=!1,this._layaPremultipliedAlpha=!0,this._spinePremultipliedAlpha=!1}loadAni(e,t=null){let s=e.lastIndexOf("/")+1,i=e.slice(0,s),n=(e=e.slice(s)).replace(".json",".atlas");t||(t=[e.replace(".json",".png")]),this._textureDic.root=i,this._textureUrlList=t,this.clientId=i,this.atlasUrl=n,this.jsonUrl=e,this.assetManager=new y(i),this.assetManager.loadJson(i,e),this.assetManager.loadText(i,n);for(var a,r=0,l=t.length;r=f&&(t.size>r.minClearSize&&(r.minClearSize=t.size),i.onClearCacheRes()),i.deleteFile(e,n,a,s,t.size)},fail:function(e){null!=a&&a.runWith([1,e])}}):null!=a&&a.runWith([0]):i.fs.getFileInfo({filePath:e,success:function(t){o&&p+4194304+t.size>=f&&(t.size>r.minClearSize&&(r.minClearSize=t.size),i.onClearCacheRes()),i.fs.copyFile({srcPath:e,destPath:h,success:function(e){i.onSaveFile(n,d,!0,s,a,t.size)},fail:function(e){null!=a&&a.runWith([1,e])}})},fail:function(e){null!=a&&a.runWith([1,e])}})}static onClearCacheRes(){var e=r.minClearSize,t=[];for(var n in i.filesListObj)"fileUsedSize"!=n&&t.push(i.filesListObj[n]);i.sortOn(t,"times",i.NUMERIC);for(var a=0,s=1,o=t.length;s=e)break;a+=l.size,i.deleteFile("",l.readyUrl)}}static sortOn(e,t,n=0){return n==i.NUMERIC?e.sort((function(e,i){return e[t]-i[t]})):n==(i.NUMERIC|i.DESCENDING)?e.sort((function(e,i){return i[t]-e[t]})):e.sort((function(e,i){return e[t]-i[t]}))}static getFileNativePath(e){return i.fileNativeDir+"/"+e}static deleteFile(e,t="",n=null,a="",s=0){var o=i.getFileInfo(t),l=i.getFileNativePath(o.md5);i.fs.unlink({filePath:l,success:function(o){if(""!=e){var l=i.getFileNativePath(e);i.fs.copyFile({srcPath:e,destPath:l,success:function(o){i.onSaveFile(t,e,!0,a,n,s)},fail:function(e){null!=n&&n.runWith([1,e])}})}else i.onSaveFile(t,e,!1,a,n,s)},fail:function(e){null!=n&&n.runWith([1,e])}})}static deleteAll(){var e=[];for(var t in i.filesListObj)"fileUsedSize"!=t&&e.push(i.filesListObj[t]);for(var n=1,a=e.length;n0&&this.loops--,this.startTime=0,this.play()}play(){this.isStopped=!1,t.SoundManager.addChannel(this),this._audio&&this._audio.play()}set startTime(e){this._audio&&(this._audio.startTime=e)}set autoplay(e){this._audio&&(this._audio.autoplay=e)}get autoplay(){return!!this._audio&&this._audio.autoplay}get position(){return this._audio?this._audio.currentTime:0}get duration(){return this._audio?this._audio.duration:0}stop(){super.stop(),this.isStopped=!0,t.SoundManager.removeChannel(this),this.completeHandler=null,this._audio&&(this._audio.stop(),this.loop||(this.offEventListener(),this._sound.dispose(),this._sound=null,this._audio=null))}pause(){this.isStopped=!0,this._audio&&this._audio.pause()}get loop(){return!!this._audio&&this._audio.loop}set loop(e){this._audio&&(this._audio.loop=e)}resume(){this.isStopped=!1,t.SoundManager.addChannel(this),this._audio&&this._audio.play()}set volume(e){this._audio&&(this._audio.volume=e)}get volume(){return this._audio?this._audio.volume:0}}class a extends t.EventDispatcher{constructor(){super(),this.loaded=!1,this._sound=a._createSound()}static __init__(){for(let e=0;e<10;e++){let e=r.window.my.createInnerAudioContext();a.cachePool.push(e)}}static _createSound(){return a.cachePool.length?a.cachePool.pop():r.window.my.createInnerAudioContext()}load(e){if(i.isLocalNativeFile(e)){if(-1==e.indexOf(r.window.my.env.USER_DATA_PATH)&&(-1!=e.indexOf("http://")||-1!=e.indexOf("https://")))if(""!=i.loadPath)e=e.split(i.loadPath)[1];else{var n=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath;""!=n&&(e=e.split(n)[1])}}else e=t.URL.formatURL(e);if(this.url=e,this.readyUrl=e,r.autoCacheFile&&i.getFileInfo(e))this.onDownLoadCallBack(e,0);else if(r.autoCacheFile)if(i.isLocalNativeFile(e)){if(r.subNativeFiles&&0==r.subNativeheads.length)for(var a in r.subNativeFiles){var s=r.subNativeFiles[a];r.subNativeheads=r.subNativeheads.concat(s);for(let e=0;e>>"+a)}}return t},r._inited=!1,r.autoCacheFile=!0,r.minClearSize=5242880,r.sizeLimit=52428800,r.nativefiles=["layaNativeDir"],r.subNativeFiles={},r.subNativeheads=[],r.subMaps=[],r.AutoCacheDownFile=!1,r.baseDir="pages/index/",r.parseXMLFromString=function(e){var t;e=e.replace(/>\s+<");try{t=(new r.window.Parser.DOMParser).parseFromString(e,"text/xml")}catch(e){throw"需要引入xml解析库文件"}return t},r.idx=1;class d extends t.EventDispatcher{constructor(){super()}static __init__(){try{var e;if(!(e=t.Accelerator))return;e.prototype.on=d.prototype.on,e.prototype.off=d.prototype.off}catch(e){}}static startListen(e){if(d._callBack=e,!d._isListening){d._isListening=!0;try{r.window.my.onAccelerometerChange(d.onAccelerometerChange)}catch(e){}}}static stopListen(){d._isListening=!1;try{r.window.my.stopAccelerometer({})}catch(e){}}static onAccelerometerChange(e){var t;(t={}).acceleration=e,t.accelerationIncludingGravity=e,t.rotationRate={},null!=d._callBack&&d._callBack(t)}on(e,t,i,n=null){return super.on(e,t,i,n),d.startListen(this.onDeviceOrientationChange),this}off(e,t,i,n=!1){return this.hasListener(e)||d.stopListen(),super.off(e,t,i,n)}}d._isListening=!1;class u{constructor(){}static __init__(){r.window.navigator.geolocation.getCurrentPosition=u.getCurrentPosition,r.window.navigator.geolocation.watchPosition=u.watchPosition,r.window.navigator.geolocation.clearWatch=u.clearWatch}static getCurrentPosition(e=null,t=null,i=null){var n;(n={}).success=function(t){null!=e&&e(t)},n.fail=t,r.window.my.getLocation(n)}static watchPosition(e=null,i=null,n=null){var a;return u._curID++,(a={}).success=e,a.error=i,u._watchDic[u._curID]=a,t.Laya.systemTimer.loop(1e3,null,u._myLoop),u._curID}static clearWatch(e){delete u._watchDic[e],u._hasWatch()||t.Laya.systemTimer.clear(null,u._myLoop)}static _hasWatch(){var e;for(e in u._watchDic)if(u._watchDic[e])return!0;return!1}static _myLoop(){u.getCurrentPosition(u._mySuccess,u._myError)}static _mySuccess(e){var i,n={};for(i in n.coords=e,n.timestamp=t.Browser.now(),u._watchDic)u._watchDic[i].success&&u._watchDic[i].success(n)}static _myError(e){var t;for(t in u._watchDic)u._watchDic[t].error&&u._watchDic[t].error(e)}}u._watchDic={},u._curID=0;e.ImageDataPolyfill=ImageDataPolyfill,e.MiniAccelerator=d,e.MiniFileMgr=i,e.MiniInput=s,e.MiniLoader=o,e.MiniLocalStorage=l,e.MiniLocation=u,e.MiniSound=a,e.MiniSoundChannel=n,e.MiniVideo=class{constructor(e=320,t=240){this.videoend=!1,this.videourl="",this.videoElement=r.window.my.createVideo({width:e,height:t,autoplay:!0})}static __init__(){}on(e,t,i){"loadedmetadata"==e?(this.onPlayFunc=i.bind(t),this.videoElement.onPlay=this.onPlayFunction.bind(this)):"ended"==e&&(this.onEndedFunC=i.bind(t),this.videoElement.onEnded=this.onEndedFunction.bind(this)),this.videoElement.onTimeUpdate=this.onTimeUpdateFunc.bind(this)}onTimeUpdateFunc(e){this.position=e.position,this._duration=e.duration}get duration(){return this._duration}onPlayFunction(){this.videoElement&&(this.videoElement.readyState=200),console.log("=====视频加载完成========"),null!=this.onPlayFunc&&this.onPlayFunc()}onEndedFunction(){this.videoElement&&(this.videoend=!0,console.log("=====视频播放完毕========"),null!=this.onEndedFunC&&this.onEndedFunC())}off(e,t,i){"loadedmetadata"==e?(this.onPlayFunc=i.bind(t),this.videoElement.offPlay=this.onPlayFunction.bind(this)):"ended"==e&&(this.onEndedFunC=i.bind(t),this.videoElement.offEnded=this.onEndedFunction.bind(this))}load(e){this.videoElement&&(this.videoElement.src=e)}play(){this.videoElement&&(this.videoend=!1,this.videoElement.play())}pause(){this.videoElement&&(this.videoend=!0,this.videoElement.pause())}get currentTime(){return this.videoElement?this.videoElement.initialTime:0}set currentTime(e){this.videoElement&&(this.videoElement.initialTime=e)}get videoWidth(){return this.videoElement?this.videoElement.width:0}get videoHeight(){return this.videoElement?this.videoElement.height:0}get ended(){return this.videoend}get loop(){return!!this.videoElement&&this.videoElement.loop}set loop(e){this.videoElement&&(this.videoElement.loop=e)}get playbackRate(){return this.videoElement?this.videoElement.playbackRate:0}set playbackRate(e){this.videoElement&&(this.videoElement.playbackRate=e)}get muted(){return!!this.videoElement&&this.videoElement.muted}set muted(e){this.videoElement&&(this.videoElement.muted=e)}get paused(){return!!this.videoElement&&this.videoElement.paused}size(e,t){this.videoElement&&(this.videoElement.width=e,this.videoElement.height=t)}get x(){return this.videoElement?this.videoElement.x:0}set x(e){this.videoElement&&(this.videoElement.x=e)}get y(){return this.videoElement?this.videoElement.y:0}set y(e){this.videoElement&&(this.videoElement.y=e)}get currentSrc(){return this.videoElement.src}destroy(){this.videoElement&&this.videoElement.destroy(),this.videoElement=null,this.onEndedFunC=null,this.onPlayFunc=null,this.videoend=!1,this.videourl=null}reload(){this.videoElement&&(this.videoElement.src=this.videourl)}},e.TBMiniAdapter=r}; \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/min/laya.tbpluginmini.min.js b/examples/layaair/frontend/bin/libs/min/laya.tbpluginmini.min.js new file mode 100644 index 0000000..d8b6c84 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/min/laya.tbpluginmini.min.js @@ -0,0 +1 @@ +window.tbMiniGame=function(e,t){"use strict";function ImageDataPolyfill(){let e,i,n;if(3==arguments.length){if(!(arguments[0]instanceof Uint8ClampedArray))throw new Error("Failed to construct 'ImageData': parameter 1 is not of type 'Uint8ClampedArray'.");if(arguments[0].length%4!=0)throw new Error("Failed to construct 'ImageData': The input data length is not a multiple of 4.");if(arguments[0].length!==arguments[1]*arguments[2]*4)throw new Error("Failed to construct 'ImageData': The input data length is not equal to (4 * width * height).");n=arguments[0],e=arguments[1],i=arguments[2]}else if(2==arguments.length)e=arguments[0],i=arguments[1],n=new Uint8ClampedArray(arguments[0]*arguments[1]*4);else if(arguments.length<2)throw new Error("Failed to construct 'ImageData': 2 arguments required, but only "+arguments.length+" present.");let a=t.Browser.canvas.getContext("2d").getImageData(0,0,e,i);for(let e=0;e=f&&(t.size>l.minClearSize&&(l.minClearSize=t.size),i.onClearCacheRes()),i.deleteFile(e,n,a,s,t.size)},fail:function(e){null!=a&&a.runWith([1,e])}}):null!=a&&a.runWith([0]):i.fs.getFileInfo({filePath:e,success:function(t){o&&p+4194304+t.size>=f&&(t.size>l.minClearSize&&(l.minClearSize=t.size),i.onClearCacheRes()),i.fs.copyFile({srcPath:e,destPath:h,success:function(e){i.onSaveFile(n,d,!0,s,a,t.size)},fail:function(e){null!=a&&a.runWith([1,e])}})},fail:function(e){null!=a&&a.runWith([1,e])}})}static onClearCacheRes(){var e=l.minClearSize,t=[];for(var n in i.filesListObj)"fileUsedSize"!=n&&t.push(i.filesListObj[n]);i.sortOn(t,"times",i.NUMERIC);for(var a=0,s=1,o=t.length;s=e)break;a+=r.size,i.deleteFile("",r.readyUrl)}}static sortOn(e,t,n=0){return n==i.NUMERIC?e.sort((function(e,i){return e[t]-i[t]})):n==(i.NUMERIC|i.DESCENDING)?e.sort((function(e,i){return i[t]-e[t]})):e.sort((function(e,i){return e[t]-i[t]}))}static getFileNativePath(e){return i.fileNativeDir+"/"+e}static deleteFile(e,t="",n=null,a="",s=0){var o=i.getFileInfo(t),r=i.getFileNativePath(o.md5);i.fs.unlink({filePath:r,success:function(o){if(""!=e){var r=i.getFileNativePath(e);i.fs.copyFile({srcPath:e,destPath:r,success:function(o){i.onSaveFile(t,e,!0,a,n,s)},fail:function(e){null!=n&&n.runWith([1,e])}})}else i.onSaveFile(t,e,!1,a,n,s)},fail:function(e){null!=n&&n.runWith([1,e])}})}static deleteAll(){var e=[];for(var t in i.filesListObj)"fileUsedSize"!=t&&e.push(i.filesListObj[t]);for(var n=1,a=e.length;n0&&this.loops--,this.startTime=0,this.play()}play(){this.isStopped=!1,t.SoundManager.addChannel(this),this._audio&&this._audio.play()}set startTime(e){this._audio&&(this._audio.startTime=e)}set autoplay(e){this._audio&&(this._audio.autoplay=e)}get autoplay(){return!!this._audio&&this._audio.autoplay}get position(){return this._audio?this._audio.currentTime:0}get duration(){return this._audio?this._audio.duration:0}stop(){super.stop(),this.isStopped=!0,t.SoundManager.removeChannel(this),this.completeHandler=null,this._audio&&(this._audio.stop(),this.loop||(this.offEventListener(),this._sound.dispose(),this._sound=null,this._audio=null))}pause(){this.isStopped=!0,this._audio&&this._audio.pause()}get loop(){return!!this._audio&&this._audio.loop}set loop(e){this._audio&&(this._audio.loop=e)}resume(){this.isStopped=!1,t.SoundManager.addChannel(this),this._audio&&this._audio.play()}set volume(e){this._audio&&(this._audio.volume=e)}get volume(){return this._audio?this._audio.volume:0}}class a extends t.EventDispatcher{constructor(){super(),this.loaded=!1,this._sound=a._createSound()}static __init__(){}static _createSound(){return null}load(e){this.event(t.Event.ERROR,"Not support play sound")}onDownLoadCallBack(e,n,a=null){var s;if(!n&&this._sound)if(l.autoCacheFile){if(a)s=a;else if(i.isLocalNativeFile(e)){var o=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath,r=e;""==o||-1==e.indexOf("http://")&&-1==e.indexOf("https://")||(s=e.split(o)[1]),s||(s=r),s=l.baseDir+s}else{var d=i.getFileInfo(e);if(d&&d.md5){var u=d.md5;s=i.getFileNativePath(u)}else s=-1==e.indexOf("http://")&&-1==e.indexOf("https://")&&-1==e.indexOf(l.window.my.env.USER_DATA_PATH)?l.baseDir+e:e}this._sound.src=this.readyUrl=s}else(i.isLocalNativeFile(e)||-1==e.indexOf("http://")&&-1==e.indexOf("https://")&&-1==e.indexOf(l.window.my.env.USER_DATA_PATH))&&(e=l.baseDir+e),this._sound.src=this.readyUrl=e;else this.event(t.Event.ERROR)}play(e=0,t=0){return null}get duration(){return this._sound.duration}dispose(){this._sound&&(a.cachePool.push(this._sound),this._sound=null,this.readyUrl=this.url=null)}}a.cachePool=[];class s{constructor(){}static _createInputElement(){t.Input._initInput(t.Input.area=t.Browser.createElement("textarea")),t.Input._initInput(t.Input.input=t.Browser.createElement("input")),t.Input.inputContainer=t.Browser.createElement("div"),t.Input.inputContainer.style.position="absolute",t.Input.inputContainer.style.zIndex=1e5,t.Browser.container.appendChild(t.Input.inputContainer),t.SoundManager._soundClass=a,t.SoundManager._musicClass=a;var e=l.systemInfo.model,i=l.systemInfo.system;-1!=e.indexOf("iPhone")&&(t.Browser.onIPhone=!0,t.Browser.onIOS=!0,t.Browser.onIPad=!0,t.Browser.onAndroid=!1),-1==i.indexOf("Android")&&-1==i.indexOf("Adr")||(t.Browser.onAndroid=!0,t.Browser.onIPhone=!1,t.Browser.onIOS=!1,t.Browser.onIPad=!1)}static _onStageResize(){t.Laya.stage._canvasTransform.identity().scale(t.Browser.width/t.Render.canvas.width/t.Browser.pixelRatio,t.Browser.height/t.Render.canvas.height/t.Browser.pixelRatio)}static wxinputFocus(e){}static inputEnter(){t.Input.inputElement.target.focus=!1}static wxinputblur(){s.hideKeyboard()}static hideKeyboard(){}}class o extends t.EventDispatcher{constructor(){super()}_loadResourceFilter(e,n){if(this.sourceUrl=t.URL.formatURL(n),i.isNetFile(n))if(""!=i.loadPath)n=n.split(i.loadPath)[1];else{var a=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath,s=n;""!=a&&(n=n.split(a)[1]),n||(n=s)}if(l.subNativeFiles&&0==l.subNativeheads.length)for(var r in l.subNativeFiles){var d=l.subNativeFiles[r];l.subNativeheads=l.subNativeheads.concat(d);for(var u=0;u>>"+a)}}return t},l._inited=!1,l.autoCacheFile=!1,l.minClearSize=5242880,l.sizeLimit=52428800,l.nativefiles=["layaNativeDir"],l.subNativeFiles=[],l.subNativeheads=[],l.subMaps=[],l.AutoCacheDownFile=!1,l.baseDir="component/",l.parseXMLFromString=function(e){var t;e=e.replace(/>\s+<");try{t=(new l.window.Parser.DOMParser).parseFromString(e,"text/xml")}catch(e){throw"需要引入xml解析库文件"}return t},l.idx=1;class d extends t.EventDispatcher{constructor(){super()}static __init__(){try{var e;if(!(e=t.Accelerator))return;e.prototype.on=d.prototype.on,e.prototype.off=d.prototype.off}catch(e){}}static startListen(e){if(d._callBack=e,!d._isListening){d._isListening=!0;try{l.window.my.onAccelerometerChange(d.onAccelerometerChange)}catch(e){}}}static stopListen(){d._isListening=!1;try{l.window.my.stopAccelerometer({})}catch(e){}}static onAccelerometerChange(e){var t;(t={}).acceleration=e,t.accelerationIncludingGravity=e,t.rotationRate={},null!=d._callBack&&d._callBack(t)}on(e,t,i,n=null){return super.on(e,t,i,n),d.startListen(this.onDeviceOrientationChange),this}off(e,t,i,n=!1){return this.hasListener(e)||d.stopListen(),super.off(e,t,i,n)}}d._isListening=!1;class u{constructor(){}static __init__(){l.window.navigator.geolocation.getCurrentPosition=u.getCurrentPosition,l.window.navigator.geolocation.watchPosition=u.watchPosition,l.window.navigator.geolocation.clearWatch=u.clearWatch}static getCurrentPosition(e=null,t=null,i=null){var n;(n={}).success=function(t){null!=e&&e(t)},n.fail=t,l.window.my.getLocation(n)}static watchPosition(e=null,i=null,n=null){var a;return u._curID++,(a={}).success=e,a.error=i,u._watchDic[u._curID]=a,t.Laya.systemTimer.loop(1e3,null,u._myLoop),u._curID}static clearWatch(e){delete u._watchDic[e],u._hasWatch()||t.Laya.systemTimer.clear(null,u._myLoop)}static _hasWatch(){var e;for(e in u._watchDic)if(u._watchDic[e])return!0;return!1}static _myLoop(){u.getCurrentPosition(u._mySuccess,u._myError)}static _mySuccess(e){var i,n={};for(i in n.coords=e,n.timestamp=t.Browser.now(),u._watchDic)u._watchDic[i].success&&u._watchDic[i].success(n)}static _myError(e){var t;for(t in u._watchDic)u._watchDic[t].error&&u._watchDic[t].error(e)}}u._watchDic={},u._curID=0;e.ImageDataPolyfill=ImageDataPolyfill,e.MiniAccelerator=d,e.MiniFileMgr=i,e.MiniInput=s,e.MiniLoader=o,e.MiniLocalStorage=r,e.MiniLocation=u,e.MiniSound=a,e.MiniSoundChannel=n,e.MiniVideo=class{constructor(e=320,t=240){this.videoend=!1,this.videourl="",this.videoElement=l.window.my.createVideo({width:e,height:t,autoplay:!0})}static __init__(){}on(e,t,i){"loadedmetadata"==e?(this.onPlayFunc=i.bind(t),this.videoElement.onPlay=this.onPlayFunction.bind(this)):"ended"==e&&(this.onEndedFunC=i.bind(t),this.videoElement.onEnded=this.onEndedFunction.bind(this)),this.videoElement.onTimeUpdate=this.onTimeUpdateFunc.bind(this)}onTimeUpdateFunc(e){this.position=e.position,this._duration=e.duration}get duration(){return this._duration}onPlayFunction(){this.videoElement&&(this.videoElement.readyState=200),console.log("=====视频加载完成========"),null!=this.onPlayFunc&&this.onPlayFunc()}onEndedFunction(){this.videoElement&&(this.videoend=!0,console.log("=====视频播放完毕========"),null!=this.onEndedFunC&&this.onEndedFunC())}off(e,t,i){"loadedmetadata"==e?(this.onPlayFunc=i.bind(t),this.videoElement.offPlay=this.onPlayFunction.bind(this)):"ended"==e&&(this.onEndedFunC=i.bind(t),this.videoElement.offEnded=this.onEndedFunction.bind(this))}load(e){this.videoElement&&(this.videoElement.src=e)}play(){this.videoElement&&(this.videoend=!1,this.videoElement.play())}pause(){this.videoElement&&(this.videoend=!0,this.videoElement.pause())}get currentTime(){return this.videoElement?this.videoElement.initialTime:0}set currentTime(e){this.videoElement&&(this.videoElement.initialTime=e)}get videoWidth(){return this.videoElement?this.videoElement.width:0}get videoHeight(){return this.videoElement?this.videoElement.height:0}get ended(){return this.videoend}get loop(){return!!this.videoElement&&this.videoElement.loop}set loop(e){this.videoElement&&(this.videoElement.loop=e)}get playbackRate(){return this.videoElement?this.videoElement.playbackRate:0}set playbackRate(e){this.videoElement&&(this.videoElement.playbackRate=e)}get muted(){return!!this.videoElement&&this.videoElement.muted}set muted(e){this.videoElement&&(this.videoElement.muted=e)}get paused(){return!!this.videoElement&&this.videoElement.paused}size(e,t){this.videoElement&&(this.videoElement.width=e,this.videoElement.height=t)}get x(){return this.videoElement?this.videoElement.x:0}set x(e){this.videoElement&&(this.videoElement.x=e)}get y(){return this.videoElement?this.videoElement.y:0}set y(e){this.videoElement&&(this.videoElement.y=e)}get currentSrc(){return this.videoElement.src}destroy(){this.videoElement&&this.videoElement.destroy(),this.videoElement=null,this.onEndedFunC=null,this.onPlayFunc=null,this.videoend=!1,this.videourl=null}reload(){this.videoElement&&(this.videoElement.src=this.videourl)}},e.TBMiniAdapter=l}; \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/min/laya.tiledmap.min.js b/examples/layaair/frontend/bin/libs/min/laya.tiledmap.min.js new file mode 100644 index 0000000..3e9ee19 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/min/laya.tiledmap.min.js @@ -0,0 +1 @@ +!function(t,i){"use strict";class e extends i.Sprite{constructor(){super(...arguments),this.relativeX=0,this.relativeY=0,this.isAloneObject=!1,this.isHaveAnimation=!1,this.drawImageNum=0,this._map=null}initData(t,i=!1){this._map=t,this.isAloneObject=i}addAniSprite(t){null==this.aniSpriteArray&&(this.aniSpriteArray=[]),this.aniSpriteArray.push(t)}show(){if(!this.visible){if(this.visible=!0,null==this.aniSpriteArray)return;for(var t=0;tthis._map.viewPortWidth||this.y<0||this.y>this._map.viewPortHeight?this.hide():this.show()):this._map&&(this.x=this.relativeX-this._map._viewPortX,this.y=this.relativeY-this._map._viewPortY)}clearAll(){if(this._map&&(this._map=null),this.visible=!1,null!=this.aniSpriteArray)for(var t=0;t0&&(this._objDic={},this._dataDic={});for(var n=0;n=0&&i=0&&t0&&t.updatePos()}drawTileTexture(t,i,e){if(e>=0&&e=0&&i0&&this.durationTimeArray&&this.durationTimeArray.length>0){var t=i.ILaya.Browser.now();this._interval=t-this._preFrameTime,this._preFrameTime=t,this._interval>this.animationTotalTime&&(this._interval=this._interval%this.animationTotalTime),this._time+=this._interval;for(var e=this.durationTimeArray[this._frameIndex];this._time>e;){this._time-=e,this._frameIndex++,(this._frameIndex>=this.durationTimeArray.length||this._frameIndex>=this.textureArray.length)&&(this._frameIndex=0);var r,h=this.textureArray[this._frameIndex];for(var a in this._aniDic)r=this._aniDic[a],this.drawTexture(r,h);e=this.durationTimeArray[this._frameIndex]}}}drawTexture(t,i){t.graphics.clear(!0),t.graphics.drawImage(i.texture,i.offX,i.offY)}removeAniSprite(t){this._aniDic&&this._aniDic[t]&&(delete this._aniDic[t],this._spriteNum--,0==this._spriteNum&&i.ILaya.timer.clear(this,this.animate))}showDebugInfo(){var t=null;return this._spriteNum>0&&(t="TileTextureSet::gid:"+this.gid.toString()+" 动画数:"+this._spriteNum.toString()),t}clearAll(){this.gid=-1,this.texture&&(this.texture.destroy(),this.texture=null),this.offX=0,this.offY=0,this.textureArray=null,this.durationTimeArray=null,this.isAnimation=!1,this._spriteNum=0,this._aniDic=null,this._frameIndex=0,this._preFrameTime=0,this._time=0,this._interval=0}}class l{constructor(){this._tileTexSetArr=[],this._texArray=[],this._x=0,this._y=0,this._width=0,this._height=0,this._mapW=0,this._mapH=0,this._mapTileW=0,this._mapTileH=0,this._rect=new i.Rectangle,this._paddingRect=new i.Rectangle,this._mapSprite=null,this._layerArray=[],this._renderLayerArray=[],this._gridArray=[],this._showGridKey=!1,this._totalGridNum=0,this._gridW=0,this._gridH=0,this._gridWidth=450,this._gridHeight=450,this._jsonLoader=null,this._loader=null,this._tileSetArray=[],this._currTileSet=null,this._completeHandler=null,this._mapRect=new _,this._mapLastRect=new _,this._index=0,this._animationDic={},this._tileProperties={},this._tileProperties2={},this._orientation="orthogonal",this._renderOrder="right-down",this._colorArray=["FF","00","33","66"],this._scale=1,this._pivotScaleX=.5,this._pivotScaleY=.5,this._centerX=0,this._centerY=0,this._viewPortX=0,this._viewPortY=0,this._viewPortWidth=0,this._viewPortHeight=0,this._enableLinear=!0,this._limitRange=!1,this.autoCache=!0,this.autoCacheType="normal",this.enableMergeLayer=!1,this.removeCoveredTile=!1,this.showGridTextureCount=!1,this.antiCrack=!0,this.cacheAllAfterInit=!1,this._texutreStartDic={}}createMap(t,e,r,h=null,a=null,s=!0,l=!1){this._enableLinear=s,this._limitRange=l,this._rect.x=e.x,this._rect.y=e.y,this._rect.width=e.width,this._rect.height=e.height,this._viewPortWidth=e.width/this._scale,this._viewPortHeight=e.height/this._scale,this._completeHandler=r,h?this._paddingRect.copyFrom(h):this._paddingRect.setTo(0,0,0,0),a&&(this._gridWidth=a.x,this._gridHeight=a.y);var _=t.lastIndexOf("/");_>-1?(this._resPath=t.substr(0,_),this._pathArray=this._resPath.split("/")):(this._resPath="",this._pathArray=[]),this._jsonLoader=new i.Loader,this._jsonLoader.once("complete",this,this.onJsonComplete),this._jsonLoader.load(t,i.Loader.JSON,!1)}onJsonComplete(t){this._mapSprite=new i.Sprite,i.ILaya.stage.addChild(this._mapSprite);var e=this._jsonData=t;this._properties=e.properties,this._orientation=e.orientation,this._renderOrder=e.renderorder,this._mapW=e.width,this._mapH=e.height,this._mapTileW=e.tilewidth,this._mapTileH=e.tileheight,this._width=this._mapTileW*this._mapW,this._height=this._mapTileH*this._mapH,this._orientation==l.ORIENTATION_STAGGERED&&(this._height=(.5+.5*this._mapH)*this._mapTileH),this._mapLastRect.top=this._mapLastRect.bottom=this._mapLastRect.left=this._mapLastRect.right=-1;var r,h,a=e.tilesets,s=0;for(s=0;s0){h=this._currTileSet=this._tileSetArray.shift(),this._loader=new i.Loader,this._loader.once("complete",this,this.onTextureComplete);var u=this.mergePath(this._resPath,h.image);this._loader.load(u,i.Loader.IMAGE,!1)}}mergePath(t,i){var e="",r=i.split("/"),h=0,a=0;for(a=r.length-1;a>=0;a--)".."==r[a]&&h++;if(0==h)return e=this._pathArray.length>0?t+"/"+i:i;var s=this._pathArray.length-h;for(s<0&&console.log("[error]path does not exist",this._pathArray,r,t,i),a=0;a0){r=this._currTileSet=this._tileSetArray.shift(),this._loader.once("complete",this,this.onTextureComplete);var g=this.mergePath(this._resPath,r.image);this._loader.load(g,i.Loader.IMAGE,!1)}else this._currTileSet=null,this.initMap()}adptTexture(t){if(t){var i=t.uv[0],e=t.uv[2],r=t.uv[1],h=t.uv[7],a=1/t.bitmap.width,s=1/t.bitmap.height,l=t;l.uv[0]=l.uv[6]=i+a,l.uv[2]=l.uv[4]=e-a,l.uv[1]=l.uv[3]=r+s,l.uv[5]=l.uv[7]=h-s}}initMap(){var t,i;for(var e in this._animationDic){var r,h=this._animationDic[e];r=this._texutreStartDic[h.image];var s=this.getTexture(parseInt(e)+r);if(h.mAniIdArray.length>0){for(s.textureArray=[],s.durationTimeArray=h.mDurationTimeArray,s.isAnimation=!0,s.animationTotalTime=0,t=0,i=s.durationTimeArray.length;t=0;t--)(i=this._layerArray[t]._mapData)&&(this.removeCoverd(i,e),this.collectCovers(i,e,t))}removeCoverd(t,i){var e,r;for(r=t.length,e=0;e0&&this.getTileUserData(a-1,"type",0)>0&&(i[r]=a)}getTexture(t){return tthis._width&&(this._viewPortX=this._width-this._viewPortWidth),this._viewPortY+this._viewPortHeight>this._height&&(this._viewPortY=this._height-this._viewPortHeight),this._viewPortX<0&&(this._viewPortX=0),this._viewPortY<0&&(this._viewPortY=0));var e=this._paddingRect;if(this._mapRect.top=Math.floor((this._viewPortY-e.y)/this._gridHeight),this._mapRect.bottom=Math.floor((this._viewPortY+this._viewPortHeight+e.height+e.y)/this._gridHeight),this._mapRect.left=Math.floor((this._viewPortX-e.x)/this._gridWidth),this._mapRect.right=Math.floor((this._viewPortX+this._viewPortWidth+e.width+e.x)/this._gridWidth),this._mapRect.top==this._mapLastRect.top&&this._mapRect.bottom==this._mapLastRect.bottom&&this._mapRect.left==this._mapLastRect.left&&this._mapRect.right==this._mapLastRect.right||(this.clipViewPort(),this._mapLastRect.top=this._mapRect.top,this._mapLastRect.bottom=this._mapRect.bottom,this._mapLastRect.left=this._mapRect.left,this._mapLastRect.right=this._mapRect.right,t=!0),t)for(var r,h=this._renderLayerArray.length,a=0;a0&&r.updateGridPos()}clipViewPort(){var t,i,e=0,r=0;if(this._mapRect.left>this._mapLastRect.left){if((e=this._mapRect.left-this._mapLastRect.left)>0)for(i=this._mapLastRect.left;i0)for(i=this._mapRect.left;ithis._mapLastRect.right){if((r=this._mapRect.right-this._mapLastRect.right)>0)for(i=Math.max(this._mapLastRect.right+1,this._mapRect.left);i<=this._mapLastRect.right+r;i++)for(t=this._mapRect.top;t<=this._mapRect.bottom;t++)this.showGrid(i,t)}else if((e=this._mapLastRect.right-this._mapRect.right)>0)for(i=this._mapRect.right+1;i<=this._mapRect.right+e;i++)for(t=this._mapLastRect.top;t<=this._mapLastRect.bottom;t++)this.hideGrid(i,t);if(this._mapRect.top>this._mapLastRect.top){if((e=this._mapRect.top-this._mapLastRect.top)>0)for(t=this._mapLastRect.top;t0)for(t=this._mapRect.top;tthis._mapLastRect.bottom){if((r=this._mapRect.bottom-this._mapLastRect.bottom)>0)for(t=Math.max(this._mapLastRect.bottom+1,this._mapRect.top);t<=this._mapLastRect.bottom+r;t++)for(i=this._mapRect.left;i<=this._mapRect.right;i++)this.showGrid(i,t)}else if((e=this._mapLastRect.bottom-this._mapRect.bottom)>0)for(t=this._mapRect.bottom+1;t<=this._mapRect.bottom+e;t++)for(i=this._mapLastRect.left;i<=this._mapLastRect.right;i++)this.hideGrid(i,t)}showGrid(t,i){if(!(t<0||t>=this._gridW||i<0||i>=this._gridH)){var e,r,h=this._gridArray[i][t];if(null==h)h=this.getGridArray(t,i);else for(e=0;e0&&r.show()}}}cacheAllGrid(){var t,i,e;for(t=0;t=N&&(c=N-1),u<0&&(n=0),u>=N&&(u=N-1),h.zOrder=this._totalGridNum*v+i*this._gridW+t,e=c;ed&&I<=g&&A.drawTileTexture(h,S,O)&&h.drawImageNum++}break;case l.ORIENTATION_STAGGERED:for(h.zOrder=v*this._totalGridNum+i*this._gridW+t,e=o;e=o;e--)for(r=s;r<_;r++)A.drawTileTexture(h,r,e)&&h.drawImageNum++;break;case l.RENDERORDER_LEFTDOWN:for(h.zOrder=v*this._totalGridNum+i*this._gridW+(this._gridW-1-t),e=o;e=s;r--)A.drawTileTexture(h,r,e)&&h.drawImageNum++;break;case l.RENDERORDER_LEFTUP:for(h.zOrder=v*this._totalGridNum+(this._gridH-1-i)*this._gridW+(this._gridW-1-t),e=n-1;e>=o;e--)for(r=_-1;r>=s;r--)A.drawTileTexture(h,r,e)&&h.drawImageNum++}}h.isHaveAnimation||(h.autoSize=!0,this.autoCache&&(h.cacheAs=this.autoCacheType),h.autoSize=!1),this.enableMergeLayer?T&&T.drawImageNum>0&&y&&y.addChild(T):(h.drawImageNum>0&&A.addChild(h),this._showGridKey&&h.graphics.drawRect(0,0,p,m,null,w))}this.enableMergeLayer&&this.showGridTextureCount&&T&&T.graphics.fillText(T.drawImageNum+"",20,20,null,"#ff0000","left")}return a}hideGrid(t,i){if(!(t<0||t>=this._gridW||i<0||i>=this._gridH)){var e=this._gridArray[i][t];if(e)for(var r,h=0;h0&&null!=r&&r.hide()}}getLayerObject(t,i){for(var e=null,r=0;r=f&&(t.size>l.minClearSize&&(l.minClearSize=t.size),i.onClearCacheRes()),i.deleteFile(e,a,n,o,t.size)},fail:function(e){null!=n&&n.runWith([1,e])}}):null!=n&&n.runWith([0]):i.fs.getFileInfo({filePath:e,success:function(t){s&&m+4194304+t.size>=f&&(t.size>l.minClearSize&&(l.minClearSize=t.size),i.onClearCacheRes()),i.fs.copyFile({srcPath:e,destPath:h,success:function(e){i.onSaveFile(a,d,!0,o,n,t.size)},fail:function(e){null!=n&&n.runWith([1,e])}})},fail:function(e){null!=n&&n.runWith([1,e])}})}static onClearCacheRes(){var e=l.minClearSize,t=[];for(var a in i.filesListObj)"fileUsedSize"!=a&&t.push(i.filesListObj[a]);i.sortOn(t,"times",i.NUMERIC);for(var n=0,o=1,s=t.length;o=e)break;n+=r.size,i.deleteFile("",r.readyUrl)}}static sortOn(e,t,a=0){return a==i.NUMERIC?e.sort((function(e,i){return e[t]-i[t]})):a==(i.NUMERIC|i.DESCENDING)?e.sort((function(e,i){return i[t]-e[t]})):e.sort((function(e,i){return e[t]-i[t]}))}static getFileNativePath(e){return i.fileNativeDir+"/"+e}static deleteFile(e,t="",a=null,n="",o=0){var s=i.getFileInfo(t),r=i.getFileNativePath(s.md5);i.fs.unlink({filePath:r,success:function(s){if(""!=e){var r=i.getFileNativePath(e);i.fs.copyFile({srcPath:e,destPath:r,success:function(s){i.onSaveFile(t,e,!0,n,a,o)},fail:function(e){null!=a&&a.runWith([1,e])}})}else i.onSaveFile(t,e,!1,n,a,o)},fail:function(e){null!=a&&a.runWith([1,e])}})}static deleteAll(){var e=[];for(var t in i.filesListObj)"fileUsedSize"!=t&&e.push(i.filesListObj[t]);for(var a=1,n=e.length;a0&&this.loops--,this.startTime=0,this.play()}play(){this.isStopped=!1,t.SoundManager.addChannel(this),this._audio.play()}set startTime(e){this._audio&&(this._audio.startTime=e)}set autoplay(e){this._audio.autoplay=e}get autoplay(){return this._audio.autoplay}get position(){return this._audio?this._audio.currentTime:0}get duration(){return this._audio?this._audio.duration:0}stop(){this.isStopped=!0,t.SoundManager.removeChannel(this),this.completeHandler=null,this._audio&&(this._audio.stop(),this.loop||(this._audio.offEnded(null),this._miniSound.dispose(),this._audio=null,this._miniSound=null,this._onEnd=null))}pause(){this.isStopped=!0,this._audio.pause()}get loop(){return this._audio.loop}set loop(e){this._audio.loop=e}resume(){this._audio&&(this.isStopped=!1,t.SoundManager.addChannel(this),this._audio.play())}set volume(e){this._audio&&(this._audio.volume=e)}get volume(){return this._audio?this._audio.volume:1}}class n extends t.EventDispatcher{constructor(){super(),this.loaded=!1}static _createSound(){return n._id++,l.window.tt.createInnerAudioContext()}load(e){if(n._musicAudio||(n._musicAudio=n._createSound()),i.isLocalNativeFile(e)){if(-1!=e.indexOf("http://")||-1!=e.indexOf("https://"))if(""!=i.loadPath)e=e.split(i.loadPath)[1];else{var a=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath;""!=a&&(e=e.split(a)[1])}}else e=t.URL.formatURL(e);if(this.url=e,this.readyUrl=e,n._audioCache[this.readyUrl])this.event(t.Event.COMPLETE);else if(l.autoCacheFile&&i.getFileInfo(e))this.onDownLoadCallBack(e,0);else if(l.autoCacheFile)if(i.isLocalNativeFile(e)){var o=e;if(""!=(a=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath)&&(e=e.split(a)[1]),e||(e=o),l.subNativeFiles&&0==l.subNativeheads.length)for(var s in l.subNativeFiles){var r=l.subNativeFiles[s];l.subNativeheads=l.subNativeheads.concat(r);for(var d=0;d=0?"/":"\\",o=e.lastIndexOf(n),s=o>=0?e.substr(0,o+1):"",r=0,d=a.length;r>>"+n)}}return t},l._inited=!1,l.autoCacheFile=!0,l.minClearSize=5242880,l.sizeLimit=52428800,l.nativefiles=["layaNativeDir","wxlocal"],l.subNativeFiles=[],l.subNativeheads=[],l.subMaps=[],l.AutoCacheDownFile=!1,l.parseXMLFromString=function(e){var t;e=e.replace(/>\s+<");try{t=(new l.window.Parser.DOMParser).parseFromString(e,"text/xml")}catch(e){throw"需要引入xml解析库文件"}return t},l.idx=1;class d extends t.EventDispatcher{constructor(){super()}static __init__(){try{var e;if(!(e=t.Accelerator))return;e.prototype.on=d.prototype.on,e.prototype.off=d.prototype.off}catch(e){}}static startListen(e){if(d._callBack=e,!d._isListening){d._isListening=!0;try{l.window.tt.onAccelerometerChange(d.onAccelerometerChange)}catch(e){}}}static stopListen(){d._isListening=!1;try{l.window.tt.stopAccelerometer({})}catch(e){}}static onAccelerometerChange(e){var t;(t={}).acceleration=e,t.accelerationIncludingGravity=e,t.rotationRate={},null!=d._callBack&&d._callBack(t)}on(e,t,i,a=null){return super.on(e,t,i,a),d.startListen(this.onDeviceOrientationChange),this}off(e,t,i,a=!1){return this.hasListener(e)||d.stopListen(),super.off(e,t,i,a)}}d._isListening=!1;class u{_loadImage(e){if(l.isZiYu)u.onCreateImage(e,this,!0);else{var a;if(i.isLocalNativeFile(e)){if(-1==e.indexOf(l.window.tt.env.USER_DATA_PATH)&&(-1!=e.indexOf("http://")||-1!=e.indexOf("https://")))if(""!=i.loadPath)e=e.split(i.loadPath)[1];else{var n=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath,o=e;""!=n&&(e=e.split(n)[1]),e||(e=o)}if(l.subNativeFiles&&0==l.subNativeheads.length)for(var s in l.subNativeFiles){var r=l.subNativeFiles[s];l.subNativeheads=l.subNativeheads.concat(r);for(var d=0;d+t),this._setChanged()}get width(){return this._width?this._width:this._source?this._source.sourceWidth:0}set width(t){this._width!=t&&(this._width=t,this._setChanged())}get height(){return this._height?this._height:this._source?this._source.sourceHeight:0}set height(t){this._height!=t&&(this._height=t,this._setChanged())}get source(){return this._source}set source(t){if(t)this._source=t,this._setChanged();else if(this._source=null,this._drawGridCmd){this._one&&this._one==this._drawGridCmd&&this.clear();let t=this.cmds;t&&t.length>0&&t[0]==this._drawGridCmd&&t.splice(0,1)}}_setChanged(){this._isChanged||(this._isChanged=!0,e.ILaya.timer.callLater(this,this.changeSource))}_createDrawTexture(t,s=0,i=0,h=0,a=0,r=null,l=1,n=null,o=null,_){if(!t||l<.01)return null;if(!t.getIsReady())return null;if(h||(h=t.sourceWidth),a||(a=t.sourceHeight),t.getIsReady()){var c=h/t.sourceWidth,d=a/t.sourceHeight;if(h=t.width*c,a=t.height*d,h<=0||a<=0)return null;s+=t.offsetX*c,i+=t.offsetY*d}return this._sp&&(this._sp._renderType|=e.SpriteConst.GRAPHICS,this._sp._setRenderType(this._sp._renderType)),e.DrawTextureCmd.create.call(this,t,s,i,h,a,r,l,n,o,_)}changeSource(){this._isChanged=!1;var t=this._source;if(t&&t.bitmap){var s=this.width,i=this.height,h=this._sizeGrid,a=t.sourceWidth,r=t.sourceHeight;if(!h||a===s&&r===i){let e=this._createDrawTexture(t,this._offset?this._offset[0]:0,this._offset?this._offset[1]:0,s,i,null,1,null,null,this.uv);e&&this._setDrawGridCmd(e)}else{let a=e.Draw9GridTexture.create(t,0,0,s,i,h);this._setDrawGridCmd(a)}this._repaint()}}drawBitmap(t,e,s,i,h=0,a=0){h<.1||a<.1||(!t||e.width==h&&e.height==a?this.drawImage(e,s,i,h,a):this.fillTexture(e,s,i,h,a))}static getTexture(t,s,i,h,a){var r;return h<=0&&(h=1),a<=0&&(a=1),t.$_GID||(t.$_GID=e.Utils.getGID()),r&&r._getSource()||(r=e.Texture.createFromTexture(t,s,i,h,a)),r}_setDrawGridCmd(t){var e=this._source;if(!e||!e.bitmap)return;let s=this.cmds;if(this._one||s&&!(s.length<=0)){let e=this._one;e?e==this._drawGridCmd?this._one=t:(this.clear(),this._saveToCmd(null,t),this._saveToCmd(null,e)):s.splice(0,0,t)}else this._saveToCmd(null,t);this._drawGridCmd=t}}e.ClassUtils.regClass("laya.ui.AutoBitmap",h),e.ClassUtils.regClass("Laya.AutoBitmap",h);class a extends e.Component{constructor(){super(...arguments),this._top=NaN,this._bottom=NaN,this._left=NaN,this._right=NaN,this._centerX=NaN,this._centerY=NaN}onReset(){this._top=this._bottom=this._left=this._right=this._centerX=this._centerY=NaN}_onEnable(){this.owner.parent?this._onAdded():this.owner.once(e.Event.ADDED,this,this._onAdded)}_onDisable(){this.owner.off(e.Event.ADDED,this,this._onAdded),this.owner.parent&&this.owner.parent.off(e.Event.RESIZE,this,this._onParentResize)}_onAdded(){this.owner.parent&&this.owner.parent.on(e.Event.RESIZE,this,this._onParentResize),this.resetLayoutX(),this.resetLayoutY()}_onParentResize(){var t=this.resetLayoutX(),s=this.resetLayoutY();(t||s)&&this.owner.event(e.Event.RESIZE)}resetLayoutX(){var t=this.owner;if(!t)return!1;var e=t.parent;if(e)if(isNaN(this.centerX)){if(isNaN(this.left))isNaN(this.right)||(t.x=Math.round(e.width-t.displayWidth-this.right+t.pivotX*t.scaleX));else if(t.x=Math.round(this.left+t.pivotX*t.scaleX),!isNaN(this.right)){if(!e._width)return!1;var s=(e._width-this.left-this.right)/(t.scaleX||.01);if(s!=t.width)return t.width=s,!0}}else t.x=Math.round(.5*(e.width-t.displayWidth)+this.centerX+t.pivotX*t.scaleX);return!1}resetLayoutY(){var t=this.owner;if(!t)return!1;var e=t.parent;if(e)if(isNaN(this.centerY)){if(isNaN(this.top))isNaN(this.bottom)||(t.y=Math.round(e.height-t.displayHeight-this.bottom+t.pivotY*t.scaleY));else if(t.y=Math.round(this.top+t.pivotY*t.scaleY),!isNaN(this.bottom)){if(!e._height)return!1;var s=(e._height-this.top-this.bottom)/(t.scaleY||.01);if(s!=t.height)return t.height=s,!0}}else t.y=Math.round(.5*(e.height-t.displayHeight)+this.centerY+t.pivotY*t.scaleY);return!1}resetLayout(){this.owner&&(this.resetLayoutX(),this.resetLayoutY())}get top(){return this._top}set top(t){this._top!=t&&(this._top=t,this.resetLayoutY())}get bottom(){return this._bottom}set bottom(t){this._bottom!=t&&(this._bottom=t,this.resetLayoutY())}get left(){return this._left}set left(t){this._left!=t&&(this._left=t,this.resetLayoutX())}get right(){return this._right}set right(t){this._right!=t&&(this._right=t,this.resetLayoutX())}get centerX(){return this._centerX}set centerX(t){this._centerX!=t&&(this._centerX=t,this.resetLayoutX())}get centerY(){return this._centerY}set centerY(t){this._centerY!=t&&(this._centerY=t,this.resetLayoutY())}}a.EMPTY=null,e.ILaya.regClass(a),a.EMPTY=new a,e.ClassUtils.regClass("laya.ui.Widget",a),e.ClassUtils.regClass("Laya.Widget",a);class r extends e.Event{}r.SHOW_TIP="showtip",r.HIDE_TIP="hidetip",e.ILaya.regClass(r),e.ClassUtils.regClass("laya.ui.UIEvent",r),e.ClassUtils.regClass("Laya.UIEvent",r);class l{static fillArray(t,e,s=null){var i=t.concat();if(e)for(var h=e.split(","),a=0,r=Math.min(i.length,h.length);a0){for(var i=s.length-1;i>-1;i--){s[i]instanceof e&&s.splice(i,1)}t.filters=s}}static _getReplaceStr(t){return l.escapeSequence[t]}static adptString(t){return t.replace(/\\(\w)/g,l._getReplaceStr)}static getBindFun(t){l._funMap||(l._funMap=new e.WeakObject);var s=l._funMap.get(t);if(null==s){var i='"'+t+'"',h="(function(data){if(data==null)return;with(data){try{\nreturn "+(i=i.replace(/^"\${|}"$/g,"").replace(/\${/g,'"+').replace(/}/g,'+"'))+"\n}catch(e){}}})";s=window.Laya._runScript(h),l._funMap.set(t,s)}return s}}l.grayFilter=new e.ColorFilter([.3086,.6094,.082,0,0,.3086,.6094,.082,0,0,.3086,.6094,.082,0,0,0,0,0,1,0]),l.escapeSequence={"\\n":"\n","\\t":"\t"},l._funMap=null,e.ClassUtils.regClass("laya.ui.UIUtils",l),e.ClassUtils.regClass("Laya.UIUtils",l);class n extends e.Sprite{constructor(t=!0){super(),this._anchorX=NaN,this._anchorY=NaN,this._widget=a.EMPTY,t&&(this.preinitialize(),this.createChildren(),this.initialize())}destroy(t=!0){super.destroy(t),this._dataSource=null,this._tag=null,this._toolTip=null}preinitialize(){}createChildren(){}initialize(){}get width(){return this.get_width()}get_width(){return this._width?this._width:this.measureWidth()}measureWidth(){var t=0;this.commitMeasure();for(var e=this.numChildren-1;e>-1;e--){var s=this.getChildAt(e);s._visible&&(t=Math.max(s._x+s.width*s.scaleX,t))}return t}commitMeasure(){}get height(){return this.get_height()}get_height(){return this._height?this._height:this.measureHeight()}measureHeight(){var t=0;this.commitMeasure();for(var e=this.numChildren-1;e>-1;e--){var s=this.getChildAt(e);s._visible&&(t=Math.max(s._y+s.height*s.scaleY,t))}return t}get dataSource(){return this.get_dataSource()}get_dataSource(){return this._dataSource}set dataSource(t){this.set_dataSource(t)}set_dataSource(t){for(var e in this._dataSource=t,this._dataSource)e in this&&"function"!=typeof this[e]&&(this[e]=this._dataSource[e])}get top(){return this.get_top()}get_top(){return this._widget.top}set top(t){this.set_top(t)}set_top(t){t!=this._widget.top&&(this._getWidget().top=t)}get bottom(){return this.get_bottom()}get_bottom(){return this._widget.bottom}set bottom(t){this.set_bottom(t)}set_bottom(t){t!=this._widget.bottom&&(this._getWidget().bottom=t)}get left(){return this._widget.left}set left(t){t!=this._widget.left&&(this._getWidget().left=t)}get right(){return this._widget.right}set right(t){t!=this._widget.right&&(this._getWidget().right=t)}get centerX(){return this._widget.centerX}set centerX(t){t!=this._widget.centerX&&(this._getWidget().centerX=t)}get centerY(){return this._widget.centerY}set centerY(t){t!=this._widget.centerY&&(this._getWidget().centerY=t)}_sizeChanged(){isNaN(this._anchorX)||(this.pivotX=this.anchorX*this.width),isNaN(this._anchorY)||(this.pivotY=this.anchorY*this.height),this.event(e.Event.RESIZE),this._widget!==a.EMPTY&&this._widget.resetLayout()}get tag(){return this._tag}set tag(t){this._tag=t}get toolTip(){return this._toolTip}set toolTip(t){this._toolTip!=t&&(this._toolTip=t,null!=t?(this.on(e.Event.MOUSE_OVER,this,this.onMouseOver),this.on(e.Event.MOUSE_OUT,this,this.onMouseOut)):(this.off(e.Event.MOUSE_OVER,this,this.onMouseOver),this.off(e.Event.MOUSE_OUT,this,this.onMouseOut)))}onMouseOver(t){e.ILaya.stage.event(r.SHOW_TIP,this._toolTip)}onMouseOut(t){e.ILaya.stage.event(r.HIDE_TIP,this._toolTip)}get gray(){return this._gray}set gray(t){t!==this._gray&&(this._gray=t,l.gray(this,t))}get disabled(){return this._disabled}set disabled(t){t!==this._disabled&&(this.gray=this._disabled=t,this.mouseEnabled=!t)}_getWidget(){return this._widget===a.EMPTY&&(this._widget=this.addComponent(a)),this._widget}set scaleX(t){this.set_scaleX(t)}set_scaleX(t){super.get_scaleX()!=t&&(super.set_scaleX(t),this.callLater(this._sizeChanged))}get scaleX(){return super.scaleX}set scaleY(t){this.set_scaleY(t)}set_scaleY(t){super.get_scaleY()!=t&&(super.set_scaleY(t),this.callLater(this._sizeChanged))}get scaleY(){return super.scaleY}onCompResize(){this._sizeChanged()}set width(t){this.set_width(t)}set_width(t){super.get_width()!=t&&(super.set_width(t),this.callLater(this._sizeChanged))}set height(t){this.set_height(t)}set_height(t){super.get_height()!=t&&(super.set_height(t),this.callLater(this._sizeChanged))}get anchorX(){return this.get_anchorX()}get_anchorX(){return this._anchorX}set anchorX(t){this.set_anchorX(t)}set_anchorX(t){this._anchorX!=t&&(this._anchorX=t,this.callLater(this._sizeChanged))}get anchorY(){return this.get_anchorY()}get_anchorY(){return this._anchorY}set anchorY(t){this.set_anchorY(t)}set_anchorY(t){this._anchorY!=t&&(this._anchorY=t,this.callLater(this._sizeChanged))}_childChanged(t=null){this.callLater(this._sizeChanged),super._childChanged(t)}}e.ILaya.regClass(n),e.ClassUtils.regClass("laya.ui.UIComponent",n),e.ClassUtils.regClass("Laya.UIComponent",n);class o extends n{constructor(t=null){super(),this.skin=t}destroy(t=!0){super.destroy(t),this._bitmap&&this._bitmap.destroy(),this._bitmap=null}dispose(){this.destroy(!0),e.ILaya.loader.clearRes(this._skin)}createChildren(){this.graphics=this._bitmap=new h,this._bitmap.autoCacheCmd=!1}get skin(){return this._skin}set skin(t){if(this._skin!=t)if(this._skin=t,t){var s=e.Loader.getRes(t);s?(this.source=s,this.onCompResize()):e.ILaya.loader.load(this._skin,e.Handler.create(this,this.setSource,[this._skin]),null,e.Loader.IMAGE,1,!0,this._group)}else this.source=null}get source(){return this._bitmap.source}set source(t){this._bitmap&&(this._bitmap.source=t,this.event(e.Event.LOADED),this.repaint())}get group(){return this._group}set group(t){t&&this._skin&&e.Loader.setGroup(this._skin,t),this._group=t}setSource(t,e=null){t===this._skin&&e&&(this.source=e,this.onCompResize())}measureWidth(){return this._bitmap.width}measureHeight(){return this._bitmap.height}set width(t){super.width=t,this._bitmap.width=0==t?1e-7:t}get width(){return super.width}set height(t){super.height=t,this._bitmap.height=0==t?1e-7:t}get height(){return super.height}get sizeGrid(){return this._bitmap.sizeGrid?this._bitmap.sizeGrid.join(","):null}set sizeGrid(t){this._bitmap.sizeGrid=l.fillArray(i.defaultSizeGrid,t,Number)}set dataSource(t){this._dataSource=t,"string"==typeof t?this.skin=t:super.dataSource=t}get dataSource(){return super.dataSource}}e.ILaya.regClass(o),e.ClassUtils.regClass("laya.ui.Image",o),e.ClassUtils.regClass("Laya.Image",o);class _ extends o{constructor(t=null){super(),this.advsListArr=[],this.resUrl="https://unioncdn.layabox.com/config/iconlist.json",this._http=new e.Browser.window.XMLHttpRequest,this._data=[],this._resquestTime=36e4,this._playIndex=0,this._lunboTime=5e3,this.skin=t,this.setLoadUrl(),this.init(),this.size(120,120)}setLoadUrl(){}init(){this.isSupportJump()?((e.Browser.onMiniGame||e.Browser.onBDMiniGame)&&e.ILaya.timer.loop(this._resquestTime,this,this.onGetAdvsListData),this.onGetAdvsListData(),this.initEvent()):this.visible=!1}initEvent(){this.on(e.Event.CLICK,this,this.onAdvsImgClick)}onAdvsImgClick(){this.getCurrentAppidObj()&&this.jumptoGame()}revertAdvsData(){this.advsListArr[this._playIndex]&&(this.visible=!0,this.skin=this.advsListArr[this._playIndex])}isSupportJump(){return e.Browser.onMiniGame?window.wx.navigateToMiniProgram instanceof Function:!!e.Browser.onBDMiniGame}jumptoGame(){var t=this.advsListArr[this._playIndex];parseInt(t.gameid),t.extendInfo,t.path;e.Browser.onMiniGame?this.isSupportJump()&&window.wx.navigateToMiniProgram({appId:this._appid,path:"",extraData:"",envVersion:"release",success:()=>{console.log("-------------跳转成功--------------")},fail:()=>{console.log("-------------跳转失败--------------")},complete:()=>{console.log("-------------跳转接口调用成功--------------"),this.updateAdvsInfo()}}):e.Browser.onBDMiniGame||(this.visible=!1)}updateAdvsInfo(){this.visible=!1,this.onLunbo(),e.ILaya.timer.loop(this._lunboTime,this,this.onLunbo)}onLunbo(){this._playIndex>=this.advsListArr.length-1?this._playIndex=0:this._playIndex+=1,this.visible=!0,this.revertAdvsData()}getCurrentAppidObj(){return this.advsListArr[this._playIndex]}onGetAdvsListData(){var t=this,e=_.randRange(1e4,1e6),s=this.resUrl+"?"+e;this._http.open("get",s,!0),this._http.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),this._http.responseType="text",this._http.onerror=function(e){t._onError(e)},this._http.onload=function(e){t._onLoad(e)},this._http.send(null)}static randRange(t,e){return Math.floor(Math.random()*(e-t+1))+t}_onError(t){this.error("Request failed Status:"+this._http.status+" text:"+this._http.statusText)}_onLoad(t){var e=this._http,s=void 0!==e.status?e.status:200;200===s||204===s||0===s?this.complete():this.error("["+e.status+"]"+e.statusText+":"+e.responseURL)}error(t){this.event(e.Event.ERROR,t)}complete(){try{this._data=this._http.response||this._http.responseText,this._data=JSON.parse(this._data),this.advsListArr=this._data.list,this._appid=this._data.appid,this.updateAdvsInfo(),this.revertAdvsData()}catch(t){this.error(t.message)}}getAdvsQArr(t){var s=[],i=e.LocalStorage.getJSON("gameObj");for(var h in t){var a=t[h];i&&i[a.gameid]&&!a.isQiangZhi||s.push(a)}return s}clear(){var t=this._http;t.onerror=t.onabort=t.onprogress=t.onload=null}destroy(t=!0){e.ILaya.timer.clear(this,this.onLunbo),super.destroy(!0),this.clear(),e.ILaya.timer.clear(this,this.onGetAdvsListData)}}e.ClassUtils.regClass("laya.ui.AdvImage",_),e.ClassUtils.regClass("Laya.AdvImage",_);class c extends n{set dataSource(t){for(var e in this._dataSource=t,t){var s=this.getChildByName(e);s?s.dataSource=t[e]:!(e in this)||this[e]instanceof Function||(this[e]=t[e])}}get dataSource(){return super.dataSource}get bgColor(){return this._bgColor}set bgColor(t){this._bgColor=t,t?(this._onResize(null),this.on(e.Event.RESIZE,this,this._onResize)):(this.graphics.clear(),this.off(e.Event.RESIZE,this,this._onResize))}_onResize(t){this.graphics.clear(),this.graphics.drawRect(0,0,this.width,this.height,this._bgColor)}}e.ILaya.regClass(c),e.ClassUtils.regClass("laya.ui.Box",c),e.ClassUtils.regClass("Laya.Box",c);class d extends n{constructor(t=null,e=""){super(),this._labelColors=i.buttonLabelColors,this._state=0,this._autoSize=!0,this._stateNum=i.buttonStateNum,this._stateChanged=!1,this.skin=t,this.label=e}destroy(t=!0){super.destroy(t),this._bitmap&&this._bitmap.destroy(),this._text&&this._text.destroy(t),this._bitmap=null,this._text=null,this._clickHandler=null,this._labelColors=this._sources=this._strokeColors=null}createChildren(){this.graphics=this._bitmap=new h}createText(){this._text||(this._text=new e.Text,this._text.overflow=e.Text.HIDDEN,this._text.align="center",this._text.valign="middle",this._text.width=this._width,this._text.height=this._height)}initialize(){1!==this._mouseState&&(this.mouseEnabled=!0,this._setBit(e.Const.HAS_MOUSE,!0)),this._createListener(e.Event.MOUSE_OVER,this,this.onMouse,null,!1,!1),this._createListener(e.Event.MOUSE_OUT,this,this.onMouse,null,!1,!1),this._createListener(e.Event.MOUSE_DOWN,this,this.onMouse,null,!1,!1),this._createListener(e.Event.MOUSE_UP,this,this.onMouse,null,!1,!1),this._createListener(e.Event.CLICK,this,this.onMouse,null,!1,!1)}onMouse(t){if(!1!==this.toggle||!this._selected)return t.type===e.Event.CLICK?(this.toggle&&(this.selected=!this._selected),void(this._clickHandler&&this._clickHandler.run())):void(!this._selected&&(this.state=d.stateMap[t.type]))}get skin(){return this._skin}set skin(t){this._skin!=t&&(this._skin=t,t?e.Loader.getRes(t)?this._skinLoaded():e.ILaya.loader.load(this._skin,e.Handler.create(this,this._skinLoaded),null,e.Loader.IMAGE,1):this._skinLoaded())}_skinLoaded(){this.callLater(this.changeClips),this._setStateChanged(),this._sizeChanged(),this.event(e.Event.LOADED)}get stateNum(){return this._stateNum}set stateNum(t){"string"==typeof t&&(t=parseInt(t)),this._stateNum!=t&&(this._stateNum=t<1?1:t>3?3:t,this.callLater(this.changeClips))}changeClips(){var t=e.Loader.getRes(this._skin);if(t){var s=t.sourceWidth,i=t.sourceHeight/this._stateNum;t.$_GID||(t.$_GID=e.Utils.getGID());var h=t.$_GID+"-"+this._stateNum,a=e.WeakObject.I.get(h);if(e.Utils.isOkTextureList(a)||(a=null),a)this._sources=a;else{if(this._sources=[],1===this._stateNum)this._sources.push(t);else for(var r=0;r-1&&this._index>=this._toIndex?this.stop():this._index>=this._sources.length&&(this._index=0),this.index=this._index)}stop(){this._isPlaying=!1,e.ILaya.timer.clear(this,this._loop),this.event(e.Event.COMPLETE)}set dataSource(t){this._dataSource=t,"number"==typeof t||"string"==typeof t?this.index=parseInt(t):super.dataSource=t}get dataSource(){return super.dataSource}get bitmap(){return this._bitmap}_setClipChanged(){this._clipChanged||(this._clipChanged=!0,this.callLater(this.changeClip))}}e.ILaya.regClass(g),e.ClassUtils.regClass("laya.ui.Clip",g),e.ClassUtils.regClass("Laya.Clip",g);class p extends n{constructor(t=!0){super(!1),this._gridSize=11,this._bgColor="#ffffff",this._borderColor="#000000",this._inputColor="#000000",this._inputBgColor="#efefef",this._colors=[],this._selectedColor="#000000",t&&(this.preinitialize(),this.createChildren(),this.initialize())}destroy(t=!0){e.ILaya.stage.off(e.Event.MOUSE_DOWN,this,this.removeColorBox),super.destroy(t),this._colorPanel&&this._colorPanel.destroy(t),this._colorButton&&this._colorButton.destroy(t),this._colorPanel=null,this._colorTiles=null,this._colorBlock=null,this._colorInput=null,this._colorButton=null,this._colors=null,this.changeHandler=null}createChildren(){this.addChild(this._colorButton=new d),this._colorPanel=new c,this._colorPanel.size(230,166),this._colorPanel.addChild(this._colorTiles=new e.Sprite),this._colorPanel.addChild(this._colorBlock=new e.Sprite),this._colorPanel.addChild(this._colorInput=new e.Input)}initialize(){this._colorButton.on(e.Event.CLICK,this,this.onColorButtonClick),this._colorBlock.pos(5,5),this._colorInput.pos(60,5),this._colorInput.size(60,20),this._colorInput.on(e.Event.CHANGE,this,this.onColorInputChange),this._colorInput.on(e.Event.KEY_DOWN,this,this.onColorFieldKeyDown),this._colorTiles.pos(5,30),this._colorTiles.on(e.Event.MOUSE_MOVE,this,this.onColorTilesMouseMove),this._colorTiles.on(e.Event.CLICK,this,this.onColorTilesClick),this._colorTiles.size(20*this._gridSize,12*this._gridSize),this._colorPanel.on(e.Event.MOUSE_DOWN,this,this.onPanelMouseDown),this.bgColor=this._bgColor}onPanelMouseDown(t){t.stopPropagation()}changePanel(){this._panelChanged=!1;var t=this._colorPanel.graphics;t.clear(!0),t.drawRect(0,0,230,166,this._bgColor,this._borderColor),this.drawBlock(this._selectedColor),this._colorInput.borderColor=this._borderColor,this._colorInput.bgColor=this._inputBgColor,this._colorInput.color=this._inputColor,(t=this._colorTiles.graphics).clear(!0);for(var e=[0,3355443,6710886,10066329,13421772,16777215,16711680,65280,255,16776960,65535,16711935],s=0;s<12;s++)for(var i=0;i<20;i++){var h;h=0===i?e[s]:1===i?0:51*(((3*s+i/6)%3<<0)+3*(s/6<<0))<<16|i%6*51<<8|(s<<0)%6*51;var a=l.toColor(h);this._colors.push(a);var r=i*this._gridSize,n=s*this._gridSize;t.drawRect(r,n,this._gridSize,this._gridSize,a,"#000000")}}onColorButtonClick(t){this._colorPanel.parent?this.close():this.open()}open(){let t=e.ILaya.stage;var s=this.localToGlobal(new e.Point),i=s.x+this._colorPanel.width<=t.width?s.x:t.width-this._colorPanel.width,h=s.y+this._colorButton.height;h=h+this._colorPanel.height<=t.height?h:s.y-this._colorPanel.height,this._colorPanel.pos(i,h),this._colorPanel.zOrder=1001,t.addChild(this._colorPanel),t.on(e.Event.MOUSE_DOWN,this,this.removeColorBox)}close(){e.ILaya.stage.off(e.Event.MOUSE_DOWN,this,this.removeColorBox),this._colorPanel.removeSelf()}removeColorBox(t=null){this.close()}onColorFieldKeyDown(t){13==t.keyCode&&(this._colorInput.text?this.selectedColor=this._colorInput.text:this.selectedColor=null,this.close(),t.stopPropagation())}onColorInputChange(t=null){this._colorInput.text?this.drawBlock(this._colorInput.text):this.drawBlock("#FFFFFF")}onColorTilesClick(t){this.selectedColor=this.getColorByMouse(),this.close()}onColorTilesMouseMove(t){this._colorInput.focus=!1;var e=this.getColorByMouse();this._colorInput.text=e,this.drawBlock(e)}getColorByMouse(){var t=this._colorTiles.getMousePoint(),e=Math.floor(t.x/this._gridSize),s=Math.floor(t.y/this._gridSize);return this._colors[20*s+e]}drawBlock(t){var e=this._colorBlock.graphics;e.clear(!0);var s=t||"#ffffff";e.drawRect(0,0,50,20,s,this._borderColor),t||e.drawLine(0,0,50,20,"#ff0000")}get selectedColor(){return this._selectedColor}set selectedColor(t){this._selectedColor!=t&&(this._selectedColor=this._colorInput.text=t,this.drawBlock(t),this.changeColor(),this.changeHandler&&this.changeHandler.runWith(this._selectedColor),this.event(e.Event.CHANGE,e.Event.EMPTY.setTo(e.Event.CHANGE,this,this)))}get skin(){return this._colorButton.skin}set skin(t){this._colorButton.once(e.Event.LOADED,this,this.changeColor),this._colorButton.skin=t}changeColor(){var t=this.graphics;t.clear(!0);var e=this._selectedColor||"#000000";t.drawRect(0,0,this._colorButton.width,this._colorButton.height,e)}get bgColor(){return this._bgColor}set bgColor(t){this._bgColor=t,this._setPanelChanged()}get borderColor(){return this._borderColor}set borderColor(t){this._borderColor=t,this._setPanelChanged()}get inputColor(){return this._inputColor}set inputColor(t){this._inputColor=t,this._setPanelChanged()}get inputBgColor(){return this._inputBgColor}set inputBgColor(t){this._inputBgColor=t,this._setPanelChanged()}_setPanelChanged(){this._panelChanged||(this._panelChanged=!0,this.callLater(this.changePanel))}}e.ILaya.regClass(p),e.ClassUtils.regClass("laya.ui.ColorPicker",p),e.ClassUtils.regClass("Laya.ColorPicker",p);class C extends n{constructor(t=""){super(),this.text=t}destroy(t=!0){super.destroy(t),this._tf=null}createChildren(){this.addChild(this._tf=new e.Text)}get text(){return this._tf.text}set text(t){this._tf.text!=t&&(t&&(t=l.adptString(t+"")),this._tf.text=t,this.event(e.Event.CHANGE),this._width&&this._height||this.onCompResize())}changeText(t){this._tf.changeText(t)}get wordWrap(){return this._tf.wordWrap}set wordWrap(t){this._tf.wordWrap=t}get color(){return this._tf.color}set color(t){this._tf.color=t}get font(){return this._tf.font}set font(t){this._tf.font=t}get align(){return this._tf.align}set align(t){this._tf.align=t}get valign(){return this._tf.valign}set valign(t){this._tf.valign=t}get bold(){return this._tf.bold}set bold(t){this._tf.bold=t}get italic(){return this._tf.italic}set italic(t){this._tf.italic=t}get leading(){return this._tf.leading}set leading(t){this._tf.leading=t}get fontSize(){return this._tf.fontSize}set fontSize(t){this._tf.fontSize=t}get padding(){return this._tf.padding.join(",")}set padding(t){this._tf.padding=l.fillArray(i.labelPadding,t,Number)}get bgColor(){return this._tf.bgColor}set bgColor(t){this._tf.bgColor=t}get borderColor(){return this._tf.borderColor}set borderColor(t){this._tf.borderColor=t}get stroke(){return this._tf.stroke}set stroke(t){this._tf.stroke=t}get strokeColor(){return this._tf.strokeColor}set strokeColor(t){this._tf.strokeColor=t}get textField(){return this._tf}measureWidth(){return this._tf.width}measureHeight(){return this._tf.height}get width(){return this._width||this._tf.text?super.width:0}set width(t){super.width=t,this._tf.width=t}get height(){return this._height||this._tf.text?super.height:0}set height(t){super.height=t,this._tf.height=t}set dataSource(t){this._dataSource=t,"number"==typeof t||"string"==typeof t?this.text=t+"":super.dataSource=t}get dataSource(){return super.dataSource}get overflow(){return this._tf.overflow}set overflow(t){this._tf.overflow=t}get underline(){return this._tf.underline}set underline(t){this._tf.underline=t}get underlineColor(){return this._tf.underlineColor}set underlineColor(t){this._tf.underlineColor=t}}e.ILaya.regClass(C),e.ClassUtils.regClass("laya.ui.Label",C),e.ClassUtils.regClass("Laya.Label",C);class m extends n{constructor(t=null){super(),this.isVertical=!0,this.showLabel=!0,this._max=100,this._min=0,this._tick=1,this._value=0,m.label||(m.label=new C),this.skin=t}destroy(t=!0){super.destroy(t),this._bg&&this._bg.destroy(t),this._bar&&this._bar.destroy(t),this._progress&&this._progress.destroy(t),this._bg=null,this._bar=null,this._progress=null,this.changeHandler=null}createChildren(){this.addChild(this._bg=new o),this.addChild(this._bar=new d)}initialize(){this._bar.on(e.Event.MOUSE_DOWN,this,this.onBarMouseDown),this._bg.sizeGrid=this._bar.sizeGrid="4,4,4,4,0",this._progress&&(this._progress.sizeGrid=this._bar.sizeGrid),this.allowClickBack=!0}onBarMouseDown(t){var s=e.ILaya;this._globalSacle||(this._globalSacle=new e.Point),this._globalSacle.setTo(this.globalScaleX||.01,this.globalScaleY||.01),this._maxMove=this.isVertical?this.height-this._bar.height:this.width-this._bar.width,this._tx=s.stage.mouseX,this._ty=s.stage.mouseY,s.stage.on(e.Event.MOUSE_MOVE,this,this.mouseMove),s.stage.once(e.Event.MOUSE_UP,this,this.mouseUp),s.stage.once(e.Event.MOUSE_OUT,this,this.mouseUp),this.showValueText()}showValueText(){if(this.showLabel){var t=m.label;this.addChild(t),t.textField.changeText(this._value+""),this.isVertical?(t.x=this._bar._x+20,t.y=.5*(this._bar.height-t.height)+this._bar._y):(t.y=this._bar._y-20,t.x=.5*(this._bar.width-t.width)+this._bar._x)}}hideValueText(){m.label&&m.label.removeSelf()}mouseUp(t){let s=e.ILaya.stage;s.off(e.Event.MOUSE_MOVE,this,this.mouseMove),s.off(e.Event.MOUSE_UP,this,this.mouseUp),s.off(e.Event.MOUSE_OUT,this,this.mouseUp),this.sendChangeEvent(e.Event.CHANGED),this.hideValueText()}mouseMove(t){let s=e.ILaya.stage;var i=this._value;if(this.isVertical?(this._bar.y+=(s.mouseY-this._ty)/this._globalSacle.y,this._bar._y>this._maxMove?this._bar.y=this._maxMove:this._bar._y<0&&(this._bar.y=0),this._value=this._bar._y/this._maxMove*(this._max-this._min)+this._min,this._progress&&(this._progress.height=this._bar._y+.5*this._bar.height)):(this._bar.x+=(s.mouseX-this._tx)/this._globalSacle.x,this._bar._x>this._maxMove?this._bar.x=this._maxMove:this._bar._x<0&&(this._bar.x=0),this._value=this._bar._x/this._maxMove*(this._max-this._min)+this._min,this._progress&&(this._progress.width=this._bar._x+.5*this._bar.width)),this._tx=s.mouseX,this._ty=s.mouseY,0!=this._tick){var h=Math.pow(10,(this._tick+"").length-1);this._value=Math.round(Math.round(this._value/this._tick)*this._tick*h)/h}this._value!=i&&this.sendChangeEvent(),this.showValueText()}sendChangeEvent(t=e.Event.CHANGE){this.event(t),this.changeHandler&&this.changeHandler.runWith(this._value)}get skin(){return this._skin}set skin(t){this._skin!=t&&(this._skin=t,this._skin&&!e.Loader.getRes(this._skin)?e.ILaya.loader.load([this._skin,this._skin.replace(".png","$bar.png")],e.Handler.create(this,this._skinLoaded)):this._skinLoaded())}_skinLoaded(){this._bg.skin=this._skin,this._bar.skin=this._skin.replace(".png","$bar.png");var t=this._skin.replace(".png","$progress.png");e.Loader.getRes(t)&&(this._progress||(this.addChild(this._progress=new o),this._progress.sizeGrid=this._bar.sizeGrid,this.setChildIndex(this._progress,1)),this._progress.skin=t),this.setBarPoint(),this.callLater(this.changeValue),this._sizeChanged(),this.event(e.Event.LOADED)}setBarPoint(){this.isVertical?this._bar.x=Math.round(.5*(this._bg.width-this._bar.width)):this._bar.y=Math.round(.5*(this._bg.height-this._bar.height))}measureWidth(){return Math.max(this._bg.width,this._bar.width)}measureHeight(){return Math.max(this._bg.height,this._bar.height)}_sizeChanged(){super._sizeChanged(),this.isVertical?this._bg.height=this.height:this._bg.width=this.width,this.setBarPoint(),this.changeValue()}get sizeGrid(){return this._bg.sizeGrid}set sizeGrid(t){this._bg.sizeGrid=t,this._bar.sizeGrid=t,this._progress&&(this._progress.sizeGrid=this._bar.sizeGrid)}setSlider(t,e,s){this._value=-1,this._min=t,this._max=e>t?e:t,this.value=se?e:s}get tick(){return this._tick}set tick(t){this._tick!=t&&(this._tick=t,this.callLater(this.changeValue))}changeValue(){if(0!=this.tick){var t=Math.pow(10,(this._tick+"").length-1);this._value=Math.round(Math.round(this._value/this._tick)*this._tick*t)/t}this._max>=this._max?this._value=this._value>this._max?this._max:this._valuethis._min?this._min:this._value0,!this._hide&&this.autoHide&&(this.visible=!1)}get max(){return this.slider.max}set max(t){this.slider.max=t}get min(){return this.slider.min}set min(t){this.slider.min=t}get value(){return this._value}set value(t){t!==this._value&&(this._value=t,this._isElastic||(this.slider._value!=t&&(this.slider._value=t,this.slider.changeValue()),this._value=this.slider._value),this.event(e.Event.CHANGE),this.changeHandler&&this.changeHandler.runWith(this._value))}get isVertical(){return this.slider.isVertical}set isVertical(t){this.slider.isVertical=t}get sizeGrid(){return this.slider.sizeGrid}set sizeGrid(t){this.slider.sizeGrid=t}get scrollSize(){return this._scrollSize}set scrollSize(t){this._scrollSize=t}set dataSource(t){this._dataSource=t,"number"==typeof t||"string"==typeof t?this.value=Number(t):super.dataSource=t}get dataSource(){return super.dataSource}get thumbPercent(){return this._thumbPercent}set thumbPercent(t){this.runCallLater(this.changeScrollBar),this.runCallLater(this._sizeChanged),t=t>=1?.99:t,this._thumbPercent=t,this.scaleBar&&(this.slider.isVertical?this.slider.bar.height=Math.max(this.slider.height*t,i.scrollBarMinNum):this.slider.bar.width=Math.max(this.slider.width*t,i.scrollBarMinNum))}get target(){return this._target}set target(t){this._target&&(this._target.off(e.Event.MOUSE_WHEEL,this,this.onTargetMouseWheel),this._target.off(e.Event.MOUSE_DOWN,this,this.onTargetMouseDown)),this._target=t,t&&(this._mouseWheelEnable&&this._target.on(e.Event.MOUSE_WHEEL,this,this.onTargetMouseWheel),this._touchScrollEnable&&this._target.on(e.Event.MOUSE_DOWN,this,this.onTargetMouseDown))}get hide(){return this._hide}set hide(t){this._hide=t,this.visible=!t}get showButtons(){return this._showButtons}set showButtons(t){this._showButtons=t,this.callLater(this.changeScrollBar)}get touchScrollEnable(){return this._touchScrollEnable}set touchScrollEnable(t){this._touchScrollEnable=t,this.target=this._target}get mouseWheelEnable(){return this._mouseWheelEnable}set mouseWheelEnable(t){this._mouseWheelEnable=t,this.target=this._target}onTargetMouseWheel(t){this.value-=t.delta*this._scrollSize,this.target=this._target}onTargetMouseDown(t){this.isLockedFun&&!this.isLockedFun(t)||(this.event(e.Event.END),this._clickOnly=!0,this._lastOffset=0,this._checkElastic=!1,this._lastPoint||(this._lastPoint=new e.Point),this._lastPoint.setTo(e.ILaya.stage.mouseX,e.ILaya.stage.mouseY),e.ILaya.timer.clear(this,this.tweenMove),e.Tween.clearTween(this),e.ILaya.stage.once(e.Event.MOUSE_UP,this,this.onStageMouseUp2),e.ILaya.stage.once(e.Event.MOUSE_OUT,this,this.onStageMouseUp2),e.ILaya.timer.frameLoop(1,this,this.loop))}startDragForce(){this._clickOnly=!0,this._lastOffset=0,this._checkElastic=!1,this._lastPoint||(this._lastPoint=new e.Point),this._lastPoint.setTo(e.ILaya.stage.mouseX,e.ILaya.stage.mouseY),e.ILaya.timer.clear(this,this.tweenMove),e.Tween.clearTween(this),e.ILaya.stage.once(e.Event.MOUSE_UP,this,this.onStageMouseUp2),e.ILaya.stage.once(e.Event.MOUSE_OUT,this,this.onStageMouseUp2),e.ILaya.timer.frameLoop(1,this,this.loop)}cancelDragOp(){e.ILaya.stage.off(e.Event.MOUSE_UP,this,this.onStageMouseUp2),e.ILaya.stage.off(e.Event.MOUSE_OUT,this,this.onStageMouseUp2),e.ILaya.timer.clear(this,this.tweenMove),e.ILaya.timer.clear(this,this.loop),this._target.mouseEnabled=!0}checkTriggers(t=!1){return this.value>=0&&this.value-this._lastOffset<=0&&this.triggerDownDragLimit&&this.triggerDownDragLimit(t)?(this.cancelDragOp(),this.value=0,!0):!!(this.value<=this.max&&this.value-this._lastOffset>=this.max&&this.triggerUpDragLimit&&this.triggerUpDragLimit(t))&&(this.cancelDragOp(),this.value=this.max,!0)}get lastOffset(){return this._lastOffset}startTweenMoveForce(t){this._lastOffset=t,e.ILaya.timer.frameLoop(1,this,this.tweenMove,[200])}loop(){var t=e.ILaya.stage.mouseY,s=e.ILaya.stage.mouseX;if(this._lastOffset=this.isVertical?t-this._lastPoint.y:s-this._lastPoint.x,this._clickOnly){if(!(Math.abs(this._lastOffset*(this.isVertical?e.ILaya.stage._canvasTransform.getScaleY():e.ILaya.stage._canvasTransform.getScaleX()))>1))return;if(this._clickOnly=!1,this.checkTriggers())return;this._offsets||(this._offsets=[]),this._offsets.length=0,this._target.mouseEnabled=!1,!this.hide&&this.autoHide&&(this.alpha=1,this.visible=!0),this.event(e.Event.START)}else if(this.checkTriggers())return;this._offsets.push(this._lastOffset),this._lastPoint.x=s,this._lastPoint.y=t,0!==this._lastOffset&&(this._checkElastic||(this.elasticDistance>0?this._checkElastic||0==this._lastOffset||(this._lastOffset>0&&this._value<=this.min||this._lastOffset<0&&this._value>=this.max?(this._isElastic=!0,this._checkElastic=!0):this._isElastic=!1):this._checkElastic=!0),this._isElastic?this._value<=this.min?this._lastOffset>0?this.value-=this._lastOffset*Math.max(0,1-(this.min-this._value)/this.elasticDistance):(this.value-=.5*this._lastOffset,this._value>=this.min&&(this._checkElastic=!1)):this._value>=this.max&&(this._lastOffset<0?this.value-=this._lastOffset*Math.max(0,1-(this._value-this.max)/this.elasticDistance):(this.value-=.5*this._lastOffset,this._value<=this.max&&(this._checkElastic=!1))):this.value-=this._lastOffset)}onStageMouseUp2(t){if(e.ILaya.stage.off(e.Event.MOUSE_UP,this,this.onStageMouseUp2),e.ILaya.stage.off(e.Event.MOUSE_OUT,this,this.onStageMouseUp2),e.ILaya.timer.clear(this,this.loop),!(this._clickOnly&&this._value>=this.min&&this._value<=this.max))if(this._target.mouseEnabled=!0,this._isElastic)this._valuethis.max&&e.Tween.to(this,{value:this.max},this.elasticBackTime,e.Ease.sineOut,e.Handler.create(this,this.elasticOver));else{if(!this._offsets)return;this._offsets.length<1&&(this._offsets[0]=this.isVertical?e.ILaya.stage.mouseY-this._lastPoint.y:e.ILaya.stage.mouseX-this._lastPoint.x);for(var s=0,i=Math.min(this._offsets.length,3),h=0;h250&&(this._lastOffset=this._lastOffset>0?250:-250);var a=Math.round(Math.abs(this.elasticDistance*(this._lastOffset/150)));e.ILaya.timer.frameLoop(1,this,this.tweenMove,[a])}}elasticOver(){this._isElastic=!1,!this.hide&&this.autoHide&&e.Tween.to(this,{alpha:0},500),this.event(e.Event.END)}tweenMove(t){var s;if((this._lastOffset*=this.rollRatio,!this.checkTriggers(!0))&&(t>0&&(this._lastOffset>0&&this.value<=this.min?(this._isElastic=!0,s=.5*-(this.min-t-this.value),this._lastOffset>s&&(this._lastOffset=s)):this._lastOffset<0&&this.value>=this.max&&(this._isElastic=!0,s=.5*-(this.max+t-this.value),this._lastOffsetthis.max?e.Tween.to(this,{value:this.max},this.elasticBackTime,e.Ease.sineOut,e.Handler.create(this,this.elasticOver)):this.elasticOver());this.event(e.Event.END),!this.hide&&this.autoHide&&e.Tween.to(this,{alpha:0},500)}}stopScroll(){this.onStageMouseUp2(null),e.ILaya.timer.clear(this,this.tweenMove),e.Tween.clearTween(this)}get tick(){return this.slider.tick}set tick(t){this.slider.tick=t}}e.ILaya.regClass(v),e.ClassUtils.regClass("laya.ui.ScrollBar",v),e.ClassUtils.regClass("Laya.ScrollBar",v);class f extends v{}e.ILaya.regClass(f),e.ClassUtils.regClass("laya.ui.VScrollBar",f),e.ClassUtils.regClass("Laya.VScrollBar",f);class S extends v{initialize(){super.initialize(),this.slider.isVertical=!1}}e.ILaya.regClass(S),e.ClassUtils.regClass("laya.ui.HScrollBar",S),e.ClassUtils.regClass("Laya.HScrollBar",S);class y extends c{constructor(){super(...arguments),this.selectEnable=!1,this.totalPage=0,this._$componentType="List",this._repeatX=0,this._repeatY=0,this._repeatX2=0,this._repeatY2=0,this._spaceX=0,this._spaceY=0,this._cells=[],this._startIndex=0,this._selectedIndex=-1,this._page=0,this._isVertical=!0,this._cellSize=20,this._cellOffset=0,this._createdLine=0,this._offset=new e.Point,this._usedCache=null,this._elasticEnabled=!1,this._preLen=0}destroy(t=!0){this._content&&this._content.destroy(t),this._scrollBar&&this._scrollBar.destroy(t),super.destroy(t),this._content=null,this._scrollBar=null,this._itemRender=null,this._cells=null,this._array=null,this.selectHandler=this.renderHandler=this.mouseHandler=null}createChildren(){this.addChild(this._content=new c)}set cacheAs(t){super.cacheAs=t,this._scrollBar&&(this._usedCache=null,"none"!==t?this._scrollBar.on(e.Event.START,this,this.onScrollStart):this._scrollBar.off(e.Event.START,this,this.onScrollStart))}get cacheAs(){return super.cacheAs}onScrollStart(){this._usedCache||(this._usedCache=super.cacheAs),super.cacheAs="none",this._scrollBar.once(e.Event.END,this,this.onScrollEnd)}onScrollEnd(){super.cacheAs=this._usedCache||"none"}get content(){return this._content}get vScrollBarSkin(){return this._scrollBar?this._scrollBar.skin:null}set vScrollBarSkin(t){this._removePreScrollBar();var e=new f;e.name="scrollBar",e.right=0,e.skin=t,e.elasticDistance=this._elasticEnabled?200:0,this.scrollBar=e,this.addChild(e),this._setCellChanged()}_removePreScrollBar(){var t=this.removeChildByName("scrollBar");t&&t.destroy(!0)}get hScrollBarSkin(){return this._scrollBar?this._scrollBar.skin:null}set hScrollBarSkin(t){this._removePreScrollBar();var e=new S;e.name="scrollBar",e.bottom=0,e.skin=t,e.elasticDistance=this._elasticEnabled?200:0,this.scrollBar=e,this.addChild(e),this._setCellChanged()}get scrollBar(){return this._scrollBar}set scrollBar(t){this._scrollBar!=t&&(this._scrollBar=t,t&&(this._isVertical=this._scrollBar.isVertical,this.addChild(this._scrollBar),this._scrollBar.on(e.Event.CHANGE,this,this.onScrollBarChange)))}get itemRender(){return this._itemRender}set itemRender(t){if(this._itemRender!=t){this._itemRender=t;for(var e=this._cells.length-1;e>-1;e--)this._cells[e].destroy();this._cells.length=0,this._setCellChanged()}}set width(t){t!=this._width&&(super.width=t,this._setCellChanged())}get width(){return super.width}set height(t){t!=this._height&&(super.height=t,this._setCellChanged())}get height(){return super.height}get repeatX(){return this._repeatX>0?this._repeatX:this._repeatX2>0?this._repeatX2:1}set repeatX(t){this._repeatX=t,this._setCellChanged()}get repeatY(){return this._repeatY>0?this._repeatY:this._repeatY2>0?this._repeatY2:1}set repeatY(t){this._repeatY=t,this._setCellChanged()}get spaceX(){return this._spaceX}set spaceX(t){this._spaceX=t,this._setCellChanged()}get spaceY(){return this._spaceY}set spaceY(t){this._spaceY=t,this._setCellChanged()}changeCells(){if(this._cellChanged=!1,this._itemRender){this.scrollBar=this.getChildByName("scrollBar");var t=this._getOneCell(),e=t.width+this._spaceX||1,s=t.height+this._spaceY||1;this._width>0&&(this._repeatX2=this._isVertical?Math.round(this._width/e):Math.ceil(this._width/e)),this._height>0&&(this._repeatY2=this._isVertical?Math.ceil(this._height/s):Math.round(this._height/s));var i=this._width?this._width:e*this.repeatX-this._spaceX,h=this._height?this._height:s*this.repeatY-this._spaceY;this._cellSize=this._isVertical?s:e,this._cellOffset=this._isVertical?s*Math.max(this._repeatY2,this._repeatY)-h-this._spaceY:e*Math.max(this._repeatX2,this._repeatX)-i-this._spaceX,this._isVertical&&this.vScrollBarSkin?this._scrollBar.height=h:!this._isVertical&&this.hScrollBarSkin&&(this._scrollBar.width=i),this.setContentSize(i,h);var a=this._isVertical?this.repeatX:this.repeatY,r=(this._isVertical?this.repeatY:this.repeatX)+(this._scrollBar?1:0);this._createItems(0,a,r),this._createdLine=r,this._array&&(this.array=this._array,this.runCallLater(this.renderItems))}}_getOneCell(){if(0===this._cells.length){var t=this.createItem();if(this._offset.setTo(t._x,t._y),this.cacheContent)return t;this._cells.push(t)}return this._cells[0]}_createItems(t,e,s){var i=this._content,h=this._getOneCell(),a=h.width+this._spaceX,r=h.height+this._spaceY;if(this.cacheContent){var l=new c;l.cacheAs="normal",l.pos((this._isVertical?0:t)*a,(this._isVertical?t:0)*r),this._content.addChild(l),i=l}else{for(var n=[],o=this._cells.length-1;o>-1;o--){var _=this._cells[o];_.removeSelf(),n.push(_)}this._cells.length=0}for(var d=t;dthis._startIndex?(r=a-this._startIndex,l=this._startIndex+s*(i+1),this._isMoved=!0):a0?t:0,this.callLater(this.renderItems)}renderItems(t=0,e=0){for(var s=t,i=e||this._cells.length;s=0&&s0?this.totalPage+1:this.totalPage)>1&&h>=i?(this._scrollBar.scrollSize=this._cellSize,this._scrollBar.thumbPercent=i/h,this._scrollBar.setScroll(0,(h-i)*this._cellSize+this._cellOffset,this._scrollBar.value),this._scrollBar.target=this._content):(this._scrollBar.setScroll(0,0,0),this._scrollBar.target=this._content)}}updateArray(t){if(this._array=t,this._array){let t=this._preLen-this._startIndex;t>=0&&this.renderItems(t),this._preLen=this._array.length}if(this._scrollBar){var e=t.length,s=this._isVertical?this.repeatX:this.repeatY,i=this._isVertical?this.repeatY:this.repeatX,h=Math.ceil(e/s);h>=i&&(this._scrollBar.thumbPercent=i/h,this._scrollBar.slider._max=(h-i)*this._cellSize+this._cellOffset)}}get page(){return this._page}set page(t){this._page=t,this._array&&(this._page=t>0?t:0,this._page=this._page-1&&t-1&&this._array&&t=this._startIndex&&t-1&&this._cells?this._cells[(t-this._startIndex)%this._cells.length]:null}scrollTo(t){if(this._scrollBar){var e=this._isVertical?this.repeatX:this.repeatY;this._scrollBar.value=Math.floor(t/e)*this._cellSize}else this.startIndex=t}tweenTo(t,s=200,i=null){if(this._scrollBar){this._scrollBar.stopScroll();var h=this._isVertical?this.repeatX:this.repeatY;e.Tween.to(this._scrollBar,{value:Math.floor(t/h)*this._cellSize},s,null,i,0,!0)}else this.startIndex=t,i&&i.run()}_setCellChanged(){this._cellChanged||(this._cellChanged=!0,this.callLater(this.changeCells))}commitMeasure(){this.runCallLater(this.changeCells)}}e.ILaya.regClass(y),e.ClassUtils.regClass("laya.ui.List",y),e.ClassUtils.regClass("Laya.List",y);class b extends n{constructor(t=null,e=null){super(),this._visibleNum=6,this._itemColors=i.comboBoxItemColors,this._itemSize=12,this._labels=[],this._selectedIndex=-1,this.itemRender=null,this.skin=t,this.labels=e}destroy(t=!0){e.ILaya.stage.off(e.Event.MOUSE_DOWN,this,this.removeList),e.ILaya.stage.off(e.Event.MOUSE_WHEEL,this,this._onStageMouseWheel),super.destroy(t),this._button&&this._button.destroy(t),this._list&&this._list.destroy(t),this._button=null,this._list=null,this._itemColors=null,this._labels=null,this._selectHandler=null}createChildren(){this.addChild(this._button=new d),this._button.text.align="left",this._button.labelPadding="0,0,0,5",this._button.on(e.Event.MOUSE_DOWN,this,this.onButtonMouseDown)}_createList(){this._list=new y,this._scrollBarSkin&&(this._list.vScrollBarSkin=this._scrollBarSkin),this._setListEvent(this._list)}_setListEvent(t){this._list.selectEnable=!0,this._list.on(e.Event.MOUSE_DOWN,this,this.onListDown),this._list.mouseHandler=e.Handler.create(this,this.onlistItemMouse,null,!1),this._list.scrollBar&&this._list.scrollBar.on(e.Event.MOUSE_DOWN,this,this.onScrollBarDown)}onListDown(t){t.stopPropagation()}onScrollBarDown(t){t.stopPropagation()}onButtonMouseDown(t){this.callLater(this.switchTo,[!this._isOpen])}get skin(){return this._button.skin}set skin(t){this._button.skin!=t&&(this._button.skin=t,this._listChanged=!0)}measureWidth(){return this._button.width}measureHeight(){return this._button.height}changeList(){this._listChanged=!1;var t=this.width-2,e=this._itemColors[2];this._itemHeight=this._itemSize+6,this._list.itemRender=this.itemRender||{type:"Box",child:[{type:"Label",props:{name:"label",x:1,padding:"3,3,3,3",width:t,height:this._itemHeight,fontSize:this._itemSize,color:e}}]},this._list.repeatY=this._visibleNum,this._list.refresh()}onlistItemMouse(t,s){var i=t.type;if(i===e.Event.MOUSE_OVER||i===e.Event.MOUSE_OUT){if(this._isCustomList)return;var h=this._list.getCell(s);if(!h)return;var a=h.getChildByName("label");a&&(i===e.Event.ROLL_OVER?(a.bgColor=this._itemColors[0],a.color=this._itemColors[1]):(a.bgColor=null,a.color=this._itemColors[2]))}else i===e.Event.CLICK&&(this.selectedIndex=s,this.isOpen=!1)}switchTo(t){this.isOpen=t}changeOpen(){this.isOpen=!this._isOpen}set width(t){super.width=t,this._button.width=this._width,this._itemChanged=!0,this._listChanged=!0}get width(){return super.width}set height(t){super.height=t,this._button.height=this._height}get height(){return super.height}get labels(){return this._labels.join(",")}set labels(t){this._labels.length>0&&(this.selectedIndex=-1),t?this._labels=t.split(","):this._labels.length=0,this._itemChanged=!0}changeItem(){if(this._itemChanged=!1,this._listHeight=this._labels.length>0?Math.min(this._visibleNum,this._labels.length)*this._itemHeight:this._itemHeight,!this._isCustomList){var t=this._list.graphics;t.clear(!0),t.drawRect(0,0,this.width-1,this._listHeight,this._itemColors[4],this._itemColors[3])}var e=this._list.array||[];e.length=0;for(var s=0,i=this._labels.length;s0?this.changeSelected():this.callLater(this.changeSelected),this.event(e.Event.CHANGE,[e.Event.EMPTY.setTo(e.Event.CHANGE,this,this)]),this._selectHandler&&this._selectHandler.runWith(this._selectedIndex))}changeSelected(){this._button.label=this.selectedLabel}get selectHandler(){return this._selectHandler}set selectHandler(t){this._selectHandler=t}get selectedLabel(){return this._selectedIndex>-1&&this._selectedIndex1?1:t<0?0:t,this._value=t,this.callLater(this.changeValue),this.event(e.Event.CHANGE),this.changeHandler&&this.changeHandler.runWith(t))}changeValue(){if(this.sizeGrid){var t=this.sizeGrid.split(","),e=Number(t[3]),s=Number(t[1]),i=(this.width-e-s)*this._value;this._bar.width=e+s+i,this._bar.visible=this._bar.width>e+s}else this._bar.width=this.width*this._value}get bar(){return this._bar}get bg(){return this._bg}get sizeGrid(){return this._bg.sizeGrid}set sizeGrid(t){this._bg.sizeGrid=this._bar.sizeGrid=t}set width(t){super.width=t,this._bg.width=this._width,this.callLater(this.changeValue)}get width(){return super.width}set height(t){super.height=t,this._bg.height=this._height,this._bar.height=this._height}get height(){return super.height}set dataSource(t){this._dataSource=t,"number"==typeof t||"string"==typeof t?this.value=Number(t):super.dataSource=t}get dataSource(){return super.dataSource}}e.ILaya.regClass(w),e.ClassUtils.regClass("laya.ui.ProgressBar",w),e.ClassUtils.regClass("Laya.ProgressBar",w);class x extends d{constructor(t=null,e=""){super(t,e),this.toggle=!1,this._autoSize=!1}destroy(t=!0){super.destroy(t),this._value=null}preinitialize(){super.preinitialize(),this.toggle=!1,this._autoSize=!1}initialize(){super.initialize(),this.createText(),this._text.align="left",this._text.valign="top",this._text.width=0,this.on(e.Event.CLICK,this,this.onClick)}onClick(t){this.selected=!0}get value(){return null!=this._value?this._value:this.label}set value(t){this._value=t}}e.ILaya.regClass(x),e.ClassUtils.regClass("laya.ui.Radio",x),e.ClassUtils.regClass("Laya.Radio",x);class L extends c{constructor(t=null,e=null){super(),this._selectedIndex=-1,this._direction="horizontal",this._space=0,this.skin=e,this.labels=t}preinitialize(){this.mouseEnabled=!0}destroy(t=!0){super.destroy(t),this._items&&(this._items.length=0),this._items=null,this.selectHandler=null}addItem(t,e=!0){var s=t,i=this._items.length;if(s.name="item"+i,this.addChild(s),this.initItems(),e&&i>0){var h=this._items[i-1];"horizontal"==this._direction?s.x=h._x+h.width+this._space:s.y=h._y+h.height+this._space}else e&&(s.x=0,s.y=0);return i}delItem(t,e=!0){var s=this._items.indexOf(t);if(-1!=s){var i,h=t;this.removeChild(h);for(var a=s+1,r=this._items.length;a-1)i=this._selectedIndex-1&&t-1&&this._selectedIndex-1&&t-1&&this._selectedIndex0,e=this._hScrollBar&&this._tf.maxScrollX>0,s=t?this._width-this._vScrollBar.width:this._width,h=e?this._height-this._hScrollBar.height:this._height,a=this._tf.padding||i.labelPadding;this._tf.width=s,this._tf.height=h,this._vScrollBar&&(this._vScrollBar.x=this._width-this._vScrollBar.width-a[2],this._vScrollBar.y=a[1],this._vScrollBar.height=this._height-(e?this._hScrollBar.height:0)-a[1]-a[3],this._vScrollBar.scrollSize=1,this._vScrollBar.thumbPercent=h/Math.max(this._tf.textHeight,h),this._vScrollBar.setScroll(1,this._tf.maxScrollY,this._tf.scrollY),this._vScrollBar.visible=t),this._hScrollBar&&(this._hScrollBar.x=a[0],this._hScrollBar.y=this._height-this._hScrollBar.height-a[3],this._hScrollBar.width=this._width-(t?this._vScrollBar.width:0)-a[0]-a[2],this._hScrollBar.scrollSize=Math.max(.033*s,1),this._hScrollBar.thumbPercent=s/Math.max(this._tf.textWidth,s),this._hScrollBar.setScroll(0,this.maxScrollX,this.scrollX),this._hScrollBar.visible=e)}scrollTo(t){this.commitMeasure(),this._tf.scrollY=t}}e.ILaya.regClass(M),e.ClassUtils.regClass("laya.ui.TextArea",M),e.ClassUtils.regClass("Laya.TextArea",M);class O extends c{constructor(){super(...arguments),this._oldW=0,this._oldH=0}onEnable(){e.ILaya.stage.on("resize",this,this.onResize),this.onResize()}onDisable(){e.ILaya.stage.off("resize",this,this.onResize)}onResize(){let t=e.ILaya.stage;if(this.width>0&&this.height>0){var s=Math.min(t.width/this._oldW,t.height/this._oldH);super.width=t.width,super.height=t.height,this.scale(s,s)}}set width(t){super.width=t,this._oldW=t}get width(){return super.width}set height(t){super.height=t,this._oldH=t}get height(){return super.height}}e.ILaya.regClass(O),e.ClassUtils.regClass("laya.ui.ScaleBox",O),e.ClassUtils.regClass("Laya.ScaleBox",O);class T extends m{constructor(t=null){super(t),this.isVertical=!1}}e.ILaya.regClass(T),e.ClassUtils.regClass("laya.ui.HSlider",T),e.ClassUtils.regClass("Laya.HSlider",T);class z extends c{constructor(){super(),this._usedCache=null,this._elasticEnabled=!1,this.width=this.height=100}destroy(t=!0){super.destroy(t),this._content&&this._content.destroy(t),this._vScrollBar&&this._vScrollBar.destroy(t),this._hScrollBar&&this._hScrollBar.destroy(t),this._vScrollBar=null,this._hScrollBar=null,this._content=null}destroyChildren(){this._content.destroyChildren()}createChildren(){super.addChild(this._content=new c)}addChild(t){return t.on(e.Event.RESIZE,this,this.onResize),this._setScrollChanged(),this._content.addChild(t)}onResize(){this._setScrollChanged()}addChildAt(t,s){return t.on(e.Event.RESIZE,this,this.onResize),this._setScrollChanged(),this._content.addChildAt(t,s)}removeChild(t){return t.off(e.Event.RESIZE,this,this.onResize),this._setScrollChanged(),this._content.removeChild(t)}removeChildAt(t){return this.getChildAt(t).off(e.Event.RESIZE,this,this.onResize),this._setScrollChanged(),this._content.removeChildAt(t)}removeChildren(t=0,e=2147483647){return this._content.removeChildren(t,e),this._setScrollChanged(),this}getChildAt(t){return this._content.getChildAt(t)}getChildByName(t){return this._content.getChildByName(t)}getChildIndex(t){return this._content.getChildIndex(t)}get numChildren(){return this._content.numChildren}changeScroll(){this._scrollChanged=!1;var t=this.contentWidth||1,e=this.contentHeight||1,s=this._vScrollBar,i=this._hScrollBar,h=s&&e>this._height,a=i&&t>this._width,r=h?this._width-s.width:this._width,l=a?this._height-i.height:this._height;s&&(s.x=this._width-s.width,s.y=0,s.height=this._height-(a?i.height:0),s.scrollSize=Math.max(.033*this._height,1),s.thumbPercent=l/e,s.setScroll(0,e-l,s.value)),i&&(i.x=0,i.y=this._height-i.height,i.width=this._width-(h?s.width:0),i.scrollSize=Math.max(.033*this._width,1),i.thumbPercent=r/t,i.setScroll(0,t-r,i.value))}_sizeChanged(){super._sizeChanged(),this.setContentSize(this._width,this._height)}get contentWidth(){for(var t=0,e=this._content.numChildren-1;e>-1;e--){var s=this._content.getChildAt(e);t=Math.max(s._x+s.width*s.scaleX-s.pivotX,t)}return t}get contentHeight(){for(var t=0,e=this._content.numChildren-1;e>-1;e--){var s=this._content.getChildAt(e);t=Math.max(s._y+s.height*s.scaleY-s.pivotY,t)}return t}setContentSize(t,s){var i=this._content;i.width=t,i.height=s,i._style.scrollRect||(i.scrollRect=e.Rectangle.create()),i._style.scrollRect.setTo(0,0,t,s),i.scrollRect=i.scrollRect}set width(t){super.width=t,this._setScrollChanged()}get width(){return super.width}set height(t){super.height=t,this._setScrollChanged()}get height(){return super.height}get vScrollBarSkin(){return this._vScrollBar?this._vScrollBar.skin:null}set vScrollBarSkin(t){null==this._vScrollBar&&(super.addChild(this._vScrollBar=new f),this._vScrollBar.on(e.Event.CHANGE,this,this.onScrollBarChange,[this._vScrollBar]),this._vScrollBar.target=this._content,this._vScrollBar.elasticDistance=this._elasticEnabled?200:0,this._setScrollChanged()),this._vScrollBar.skin=t}get hScrollBarSkin(){return this._hScrollBar?this._hScrollBar.skin:null}set hScrollBarSkin(t){null==this._hScrollBar&&(super.addChild(this._hScrollBar=new S),this._hScrollBar.on(e.Event.CHANGE,this,this.onScrollBarChange,[this._hScrollBar]),this._hScrollBar.target=this._content,this._hScrollBar.elasticDistance=this._elasticEnabled?200:0,this._setScrollChanged()),this._hScrollBar.skin=t}get vScrollBar(){return this._vScrollBar}get hScrollBar(){return this._hScrollBar}get content(){return this._content}onScrollBarChange(t){var e=this._content._style.scrollRect;if(e){var s=Math.round(t.value);t.isVertical?e.y=s:e.x=s,this._content.scrollRect=e}}scrollTo(t=0,e=0){this.vScrollBar&&(this.vScrollBar.value=e),this.hScrollBar&&(this.hScrollBar.value=t)}refresh(){this.changeScroll()}set cacheAs(t){super.cacheAs=t,this._usedCache=null,"none"!==t?(this._hScrollBar&&this._hScrollBar.on(e.Event.START,this,this.onScrollStart),this._vScrollBar&&this._vScrollBar.on(e.Event.START,this,this.onScrollStart)):(this._hScrollBar&&this._hScrollBar.off(e.Event.START,this,this.onScrollStart),this._vScrollBar&&this._vScrollBar.off(e.Event.START,this,this.onScrollStart))}get cacheAs(){return super.cacheAs}get elasticEnabled(){return this._elasticEnabled}set elasticEnabled(t){this._elasticEnabled=t,this._vScrollBar&&(this._vScrollBar.elasticDistance=t?200:0),this._hScrollBar&&(this._hScrollBar.elasticDistance=t?200:0)}onScrollStart(){this._usedCache||(this._usedCache=super.cacheAs),super.cacheAs="none",this._hScrollBar&&this._hScrollBar.once(e.Event.END,this,this.onScrollEnd),this._vScrollBar&&this._vScrollBar.once(e.Event.END,this,this.onScrollEnd)}onScrollEnd(){super.cacheAs=this._usedCache}_setScrollChanged(){this._scrollChanged||(this._scrollChanged=!0,this.callLater(this.changeScroll))}}e.ILaya.regClass(z),e.ClassUtils.regClass("laya.ui.Panel",z),e.ClassUtils.regClass("Laya.Panel",z);class U extends m{}e.ILaya.regClass(U),e.ClassUtils.regClass("laya.ui.VSlider",U),e.ClassUtils.regClass("Laya.VSlider",U);class D extends c{constructor(){super(),this._spaceLeft=10,this._spaceBottom=0,this._keepStatus=!0,this.width=this.height=200}destroy(t=!0){super.destroy(t),this._list&&this._list.destroy(t),this._list=null,this._source=null,this._renderHandler=null}createChildren(){this.addChild(this._list=new y),this._list.renderHandler=e.Handler.create(this,this.renderItem,null,!1),this._list.repeatX=1,this._list.on(e.Event.CHANGE,this,this.onListChange)}onListChange(t=null){this.event(e.Event.CHANGE)}get keepStatus(){return this._keepStatus}set keepStatus(t){this._keepStatus=t}get array(){return this._list.array}set array(t){this._keepStatus&&this._list.array&&t&&this.parseOpenStatus(this._list.array,t),this._source=t,this._list.array=this.getArray()}get source(){return this._source}get list(){return this._list}get itemRender(){return this._list.itemRender}set itemRender(t){this._list.itemRender=t}get scrollBarSkin(){return this._list.vScrollBarSkin}set scrollBarSkin(t){this._list.vScrollBarSkin=t}get scrollBar(){return this._list.scrollBar}get mouseHandler(){return this._list.mouseHandler}set mouseHandler(t){this._list.mouseHandler=t}get renderHandler(){return this._renderHandler}set renderHandler(t){this._renderHandler=t}get spaceLeft(){return this._spaceLeft}set spaceLeft(t){this._spaceLeft=t}get spaceBottom(){return this._list.spaceY}set spaceBottom(t){this._list.spaceY=t}get selectedIndex(){return this._list.selectedIndex}set selectedIndex(t){this._list.selectedIndex=t}get selectedItem(){return this._list.selectedItem}set selectedItem(t){this._list.selectedItem=t}set width(t){super.width=t,this._list.width=t}get width(){return super.width}set height(t){super.height=t,this._list.height=t}get height(){return super.height}getArray(){var t=[];for(let e in this._source){let s=this._source[e];this.getParentOpenStatus(s)&&(s.x=this._spaceLeft*this.getDepth(s),t.push(s))}return t}getDepth(t,e=0){return null==t.nodeParent?e:this.getDepth(t.nodeParent,e+1)}getParentOpenStatus(t){var e=t.nodeParent;return null==e||!!e.isOpen&&(null==e.nodeParent||this.getParentOpenStatus(e))}renderItem(t,s){var i=t.dataSource;if(i){t.left=i.x;var h=t.getChildByName("arrow");h&&(i.hasChild?(h.visible=!0,h.index=i.isOpen?1:0,h.tag=s,h.off(e.Event.CLICK,this,this.onArrowClick),h.on(e.Event.CLICK,this,this.onArrowClick)):h.visible=!1);var a=t.getChildByName("folder");a&&(2==a.clipY?a.index=i.isDirectory?0:1:a.index=i.isDirectory?i.isOpen?1:0:2),this._renderHandler&&this._renderHandler.runWith([t,s])}}onArrowClick(t){var s=t.currentTarget.tag;this._list.array[s].isOpen=!this._list.array[s].isOpen,this.event(e.Event.OPEN),this._list.array=this.getArray()}setItemState(t,e){this._list.array[t]&&(this._list.array[t].isOpen=e,this._list.array=this.getArray())}fresh(){this._list.array=this.getArray(),this.repaint()}set dataSource(t){this._dataSource=t,super.dataSource=t}get dataSource(){return super.dataSource}set xml(t){var e=[];this.parseXml(t.childNodes[0],e,null,!0),this.array=e}parseXml(t,e,s,i){var h,a=t.childNodes,r=a.length;if(!i){h={};var l=t.attributes;for(let t in l){var n=l[t],o=n.nodeName,_=n.nodeValue;h[o]="true"==_||"false"!=_&&_}h.nodeParent=s,r>0&&(h.isDirectory=!0),h.hasChild=r>0,e.push(h)}for(var c=0;c-1&&(i.x=0,e.push(i)),i.child&&i.child.length>0&&this.getFilterSource(i.child,e,s)}}e.ILaya.regClass(D),e.ClassUtils.regClass("laya.ui.Tree",D),e.ClassUtils.regClass("Laya.Tree",D);class H extends c{constructor(){super(...arguments),this._space=0,this._align="none",this._itemChanged=!1}addChild(t){return t.on(e.Event.RESIZE,this,this.onResize),this._setItemChanged(),super.addChild(t)}onResize(t){this._setItemChanged()}addChildAt(t,s){return t.on(e.Event.RESIZE,this,this.onResize),this._setItemChanged(),super.addChildAt(t,s)}removeChildAt(t){return this.getChildAt(t).off(e.Event.RESIZE,this,this.onResize),this._setItemChanged(),super.removeChildAt(t)}refresh(){this._setItemChanged()}changeItems(){this._itemChanged=!1}get space(){return this._space}set space(t){this._space=t,this._setItemChanged()}get align(){return this._align}set align(t){this._align=t,this._setItemChanged()}sortItem(t){t&&t.sort((function(t,e){return t.y-e.y}))}_setItemChanged(){this._itemChanged||(this._itemChanged=!0,this.callLater(this.changeItems))}}e.ILaya.regClass(H),e.ClassUtils.regClass("laya.ui.LayoutBox",H),e.ClassUtils.regClass("Laya.LayoutBox",H);class A extends H{sortItem(t){t&&t.sort((function(t,e){return t.x-e.x}))}set height(t){this._height!=t&&(super.height=t,this.callLater(this.changeItems))}get height(){return super.height}changeItems(){this._itemChanged=!1;for(var t=[],e=0,s=0,i=this.numChildren;s{t.scale(1,1),t._effectTween=e.Tween.from(t,{x:e.ILaya.stage.width/2,y:e.ILaya.stage.height/2,scaleX:0,scaleY:0},300,e.Ease.backOut,e.Handler.create(this,this.doOpen,[t]),0,!1,!1)},this.closeEffect=t=>{t._effectTween=e.Tween.to(t,{x:e.ILaya.stage.width/2,y:e.ILaya.stage.height/2,scaleX:0,scaleY:0},300,e.Ease.strongOut,e.Handler.create(this,this.doClose,[t]),0,!1,!1)},this.popupEffectHandler=new e.Handler(this,this.popupEffect),this.closeEffectHandler=new e.Handler(this,this.closeEffect),this.mouseEnabled=this.maskLayer.mouseEnabled=!0,this.zOrder=1e3,e.ILaya.stage.addChild(this),e.ILaya.stage.on(e.Event.RESIZE,this,this._onResize),s.closeDialogOnSide&&this.maskLayer.on("click",this,this._closeOnSide),this._onResize(null)}_closeOnSide(){var t=this.getChildAt(this.numChildren-1);t instanceof R.Dialog&&t.close("side")}setLockView(t){this.lockLayer||(this.lockLayer=new c,this.lockLayer.mouseEnabled=!0,this.lockLayer.size(e.ILaya.stage.width,e.ILaya.stage.height)),this.lockLayer.removeChildren(),t&&(t.centerX=t.centerY=0,this.lockLayer.addChild(t))}_onResize(t=null){var i=this.maskLayer.width=e.ILaya.stage.width,h=this.maskLayer.height=e.ILaya.stage.height;this.lockLayer&&this.lockLayer.size(i,h),this.maskLayer.graphics.clear(!0),this.maskLayer.graphics.drawRect(0,0,i,h,s.popupBgColor),this.maskLayer.alpha=s.popupBgAlpha;for(var a=this.numChildren-1;a>-1;a--){var r=this.getChildAt(a);r.isPopupCenter&&this._centerDialog(r)}}_centerDialog(t){t.x=Math.round((e.ILaya.stage.width-t.width>>1)+t.pivotX),t.y=Math.round((e.ILaya.stage.height-t.height>>1)+t.pivotY)}open(t,s=!1,i=!1){s&&this._closeAll(),this._clearDialogEffect(t),t.isPopupCenter&&this._centerDialog(t),this.addChild(t),(t.isModal||this._getBit(e.Const.HAS_ZORDER))&&e.ILaya.timer.callLater(this,this._checkMask),i&&null!=t.popupEffect?t.popupEffect.runWith(t):this.doOpen(t),this.event(e.Event.OPEN)}_clearDialogEffect(t){t._effectTween&&(e.Tween.clear(t._effectTween),t._effectTween=null)}doOpen(t){t.onOpened(t._param)}lock(t){this.lockLayer&&(t?this.addChild(this.lockLayer):this.lockLayer.removeSelf())}close(t){this._clearDialogEffect(t),t.isShowEffect&&null!=t.closeEffect?t.closeEffect.runWith([t]):this.doClose(t),this.event(e.Event.CLOSE)}doClose(t){t.removeSelf(),t.isModal&&this._checkMask(),t.closeHandler&&t.closeHandler.runWith(t.closeType),t.onClosed(t.closeType),t.autoDestroyAtClosed&&t.destroy()}closeAll(){this._closeAll(),this.event(e.Event.CLOSE)}_closeAll(){for(var t=this.numChildren-1;t>-1;t--){var e=this.getChildAt(t);e&&null!=e.close&&this.doClose(e)}}getDialogsByGroup(t){for(var e=[],s=this.numChildren-1;s>-1;s--){var i=this.getChildAt(s);i&&i.group===t&&e.push(i)}return e}closeByGroup(t){for(var e=[],s=this.numChildren-1;s>-1;s--){var i=this.getChildAt(s);i&&i.group===t&&(i.close(),e.push(i))}return e}_checkMask(){this.maskLayer.removeSelf();for(var t=this.numChildren-1;t>-1;t--){var e=this.getChildAt(t);if(e&&e.isModal)return void this.addChildAt(this.maskLayer,t)}}}e.ClassUtils.regClass("laya.ui.DialogManager",X),e.ClassUtils.regClass("Laya.DialogManager",X);class G extends Y{constructor(){super(),this.isShowEffect=!0,this.isPopupCenter=!0,this.popupEffect=G.manager.popupEffectHandler,this.closeEffect=G.manager.closeEffectHandler,this._dealDragArea(),this.on(e.Event.CLICK,this,this._onClick)}static get manager(){return G._manager=G._manager||new X}static set manager(t){G._manager=t}_dealDragArea(){var t=this.getChildByName("drag");t&&(this.dragArea=t._x+","+t._y+","+t.width+","+t.height,t.removeSelf())}get dragArea(){return this._dragArea?this._dragArea.toString():null}set dragArea(t){if(t){var s=l.fillArray([0,0,0,0],t,Number);this._dragArea=new e.Rectangle(s[0],s[1],s[2],s[3]),this.on(e.Event.MOUSE_DOWN,this,this._onMouseDown)}else this._dragArea=null,this.off(e.Event.MOUSE_DOWN,this,this._onMouseDown)}_onMouseDown(t){var e=this.getMousePoint();this._dragArea.contains(e.x,e.y)?this.startDrag():this.stopDrag()}_onClick(t){var e=t.target;if(e)switch(e.name){case G.CLOSE:case G.CANCEL:case G.SURE:case G.NO:case G.OK:case G.YES:return void this.close(e.name)}}open(t=!0,e=null){this._dealDragArea(),this._param=e,G.manager.open(this,t,this.isShowEffect),G.manager.lock(!1)}close(t=null){this.closeType=t,G.manager.close(this)}destroy(t=!0){this.closeHandler=null,this.popupEffect=null,this.closeEffect=null,this._dragArea=null,super.destroy(t)}show(t=!1,e=!0){this._open(!1,t,e)}popup(t=!1,e=!0){this._open(!0,t,e)}_open(t,e,s){this.isModal=t,this.isShowEffect=s,G.manager.lock(!0),this.open(e)}get isPopup(){return null!=this.parent}set zOrder(t){super.zOrder=t,G.manager._checkMask()}get zOrder(){return super.zOrder}static setLockView(t){G.manager.setLockView(t)}static lock(t){G.manager.lock(t)}static closeAll(){G.manager.closeAll()}static getDialogsByGroup(t){return G.manager.getDialogsByGroup(t)}static closeByGroup(t){return G.manager.closeByGroup(t)}}G.CLOSE="close",G.CANCEL="cancel",G.SURE="sure",G.NO="no",G.YES="yes",G.OK="ok",R.Dialog=G,e.ILaya.regClass(G),e.ClassUtils.regClass("laya.ui.Dialog",G),e.ClassUtils.regClass("Laya.Dialog",G);class W extends n{constructor(){super(),this._tipBox=new n,this._tipBox.addChild(this._tipText=new e.Text),this._tipText.x=this._tipText.y=5,this._tipText.color=W.tipTextColor,this._defaultTipHandler=this._showDefaultTip,e.ILaya.stage.on(r.SHOW_TIP,this,this._onStageShowTip),e.ILaya.stage.on(r.HIDE_TIP,this,this._onStageHideTip),this.zOrder=1100}_onStageHideTip(t){e.ILaya.timer.clear(this,this._showTip),this.closeAll(),this.removeSelf()}_onStageShowTip(t){e.ILaya.timer.once(W.tipDelay,this,this._showTip,[t],!0)}_showTip(t){if("string"==typeof t){var s=String(t);Boolean(s)&&this._defaultTipHandler(s)}else t instanceof e.Handler?t.run():t instanceof Function&&t.apply();e.ILaya.stage.on(e.Event.MOUSE_MOVE,this,this._onStageMouseMove),e.ILaya.stage.on(e.Event.MOUSE_DOWN,this,this._onStageMouseDown),this._onStageMouseMove(null)}_onStageMouseDown(t){this.closeAll()}_onStageMouseMove(t){this._showToStage(this,W.offsetX,W.offsetY)}_showToStage(t,s=0,i=0){var h=t.getBounds();t.x=e.ILaya.stage.mouseX+s,t.y=e.ILaya.stage.mouseY+i,t._x+h.width>e.ILaya.stage.width&&(t.x-=h.width+s),t._y+h.height>e.ILaya.stage.height&&(t.y-=h.height+i)}closeAll(){e.ILaya.timer.clear(this,this._showTip),e.ILaya.stage.off(e.Event.MOUSE_MOVE,this,this._onStageMouseMove),e.ILaya.stage.off(e.Event.MOUSE_DOWN,this,this._onStageMouseDown),this.removeChildren()}showDislayTip(t){this.addChild(t),this._showToStage(this),e.ILaya.stage.addChild(this)}_showDefaultTip(t){this._tipText.text=t;var s=this._tipBox.graphics;s.clear(!0),s.drawRect(0,0,this._tipText.width+10,this._tipText.height+10,W.tipBackColor),this.addChild(this._tipBox),this._showToStage(this),e.ILaya.stage.addChild(this)}get defaultTipHandler(){return this._defaultTipHandler}set defaultTipHandler(t){this._defaultTipHandler=t}}W.offsetX=10,W.offsetY=15,W.tipTextColor="#ffffff",W.tipBackColor="#111111",W.tipDelay=200,e.ILaya.regClass(W),e.ClassUtils.regClass("laya.ui.TipManager",W),e.ClassUtils.regClass("Laya.TipManager",W);class V extends n{constructor(){super(),this._width=this._height=200;var t=new e.Texture;t.bitmap=new e.Texture2D,this.texture=t}onEnable(){this.postMsg({type:"display",rate:e.Laya.stage.frameRate}),window.wx&&window.sharedCanvas&&e.Laya.timer.frameLoop(1,this,this._onLoop)}onDisable(){this.postMsg({type:"undisplay"}),e.Laya.timer.clear(this,this._onLoop)}_onLoop(){let t=window.sharedCanvas;this.texture.sourceWidth=t.width,this.texture.sourceHeight=t.height,this.texture.bitmap.loadImageSource(t)}set width(t){super.width=t,window.sharedCanvas&&(window.sharedCanvas.width=t),this.callLater(this._postMsg)}get width(){return super.width}set height(t){super.height=t,window.sharedCanvas&&(window.sharedCanvas.height=t),this.callLater(this._postMsg)}get height(){return super.height}set x(t){super.x=t,this.callLater(this._postMsg)}get x(){return super.x}set y(t){super.y=t,this.callLater(this._postMsg)}get y(){return super.y}_postMsg(){var t=new e.Matrix;t.translate(this.x,this.y);var s=e.Laya.stage;t.scale(s._canvasTransform.getScaleX()*this.globalScaleX*s.transform.getScaleX(),s._canvasTransform.getScaleY()*this.globalScaleY*s.transform.getScaleY()),this.postMsg({type:"changeMatrix",a:t.a,b:t.b,c:t.c,d:t.d,tx:t.tx,ty:t.ty,w:this.width,h:this.height})}postMsg(t){window.wx&&window.wx.getOpenDataContext&&window.wx.getOpenDataContext().postMessage(t)}}e.ILaya.regClass(V),e.ClassUtils.regClass("laya.ui.WXOpenDataViewer",V),e.ClassUtils.regClass("Laya.WXOpenDataViewer",V),t.AdvImage=_,t.AutoBitmap=h,t.Box=c,t.Button=d,t.CheckBox=u,t.Clip=g,t.ColorPicker=p,t.ComboBox=b,t.Dialog=G,t.DialogManager=X,t.FontClip=P,t.HBox=A,t.HScrollBar=S,t.HSlider=T,t.IUI=R,t.Image=o,t.Label=C,t.LayoutBox=H,t.List=y,t.Panel=z,t.ProgressBar=w,t.Radio=x,t.RadioGroup=E,t.ScaleBox=O,t.ScrollBar=v,t.Slider=m,t.Styles=i,t.Tab=I,t.TextArea=M,t.TextInput=k,t.TipManager=W,t.Tree=D,t.UIComponent=n,t.UIConfig=s,t.UIEvent=r,t.UIGroup=L,t.UILib=class{static __init__(){}},t.UIUtils=l,t.VBox=N,t.VScrollBar=f,t.VSlider=U,t.View=Y,t.ViewStack=B,t.WXOpenDataViewer=V,t.Widget=a}(window.Laya=window.Laya||{},Laya); \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/min/laya.vvmini.min.js b/examples/layaair/frontend/bin/libs/min/laya.vvmini.min.js new file mode 100644 index 0000000..4370888 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/min/laya.vvmini.min.js @@ -0,0 +1 @@ +window.vvMiniGame=function(e,t){"use strict";function ImageDataPolyfill(){let e,i,a;if(3==arguments.length){if(!(arguments[0]instanceof Uint8ClampedArray))throw new Error("Failed to construct 'ImageData': parameter 1 is not of type 'Uint8ClampedArray'.");if(arguments[0].length%4!=0)throw new Error("Failed to construct 'ImageData': The input data length is not a multiple of 4.");if(arguments[0].length!==arguments[1]*arguments[2]*4)throw new Error("Failed to construct 'ImageData': The input data length is not equal to (4 * width * height).");a=arguments[0],e=arguments[1],i=arguments[2]}else if(2==arguments.length)e=arguments[0],i=arguments[1],a=new Uint8ClampedArray(arguments[0]*arguments[1]*4);else if(arguments.length<2)throw new Error("Failed to construct 'ImageData': 2 arguments required, but only "+arguments.length+" present.");let n=t.Browser.canvas.getContext("2d").getImageData(0,0,e,i);for(let e=0;e=f&&(t.size>l.minClearSize&&(l.minClearSize=t.size),i.onClearCacheRes()),i.deleteFile(e,a,n,s,t.size)},fail:function(e){null!=n&&n.runWith([1,e])}}):null!=n&&n.runWith([0]):i.fs.getFileInfo({filePath:e,success:function(t){t.length&&(t.size=t.length),o&&g+4194304+t.size>=f&&(t.size>l.minClearSize&&(l.minClearSize=t.size),i.onClearCacheRes()),i.fs.copyFile({srcPath:e,destPath:h,success:function(e){i.onSaveFile(a,d,!0,s,n,t.size)},fail:function(e){null!=n&&n.runWith([1,e])}})},fail:function(e){null!=n&&n.runWith([1,e])}})}static onClearCacheRes(){var e=l.minClearSize,t=[];for(var a in i.filesListObj)"fileUsedSize"!=a&&t.push(i.filesListObj[a]);i.sortOn(t,"times",i.NUMERIC);for(var n=0,s=1,o=t.length;s=e)break;n+=r.size,i.deleteFile("",r.readyUrl)}}static sortOn(e,t,a=0){return a==i.NUMERIC?e.sort((function(e,i){return e[t]-i[t]})):a==(i.NUMERIC|i.DESCENDING)?e.sort((function(e,i){return i[t]-e[t]})):e.sort((function(e,i){return e[t]-i[t]}))}static getFileNativePath(e){return i.fileNativeDir+"/"+e}static deleteFile(e,t="",a=null,n="",s=0){var o=i.getFileInfo(t),l=i.getFileNativePath(o.md5);i.fs.unlink({filePath:l,success:function(o){if(""!=e){var l=i.getFileNativePath(e);i.fs.copyFile({srcPath:e,destPath:l,success:function(o){i.onSaveFile(t,e,!0,n,a,s)},fail:function(e){null!=a&&a.runWith([1,e])}})}else i.onSaveFile(t,e,!1,n,a,s)},fail:function(e){null!=a&&a.runWith([1,e])}})}static deleteAll(){var e=[];for(var t in i.filesListObj)"fileUsedSize"!=t&&e.push(i.filesListObj[t]);for(var a=1,n=e.length;a0&&this.loops--,this.startTime=0,this.play()}play(){this.isStopped=!1,t.SoundManager.addChannel(this),this._audio.play()}set startTime(e){this._audio&&(this._audio.startTime=e)}set autoplay(e){this._audio.autoplay=e}get autoplay(){return this._audio.autoplay}get position(){return this._audio?this._audio.currentTime:0}get duration(){return this._audio?this._audio.duration:0}stop(){this.isStopped=!0,t.SoundManager.removeChannel(this),this.completeHandler=null,this._audio&&(this._audio.stop(),this.loop||(this._audio.offEnded(null),this._miniSound.dispose(),this._audio=null,this._miniSound=null,this._onEnd=null))}pause(){this.isStopped=!0,this._audio.pause()}get loop(){return this._audio.loop}set loop(e){this._audio.loop=e}resume(){this._audio&&(this.isStopped=!1,t.SoundManager.addChannel(this),this._audio.play())}set volume(e){this._audio&&(this._audio.volume=e)}get volume(){return this._audio?this._audio.volume:1}}class n extends t.EventDispatcher{constructor(){super(),this.loaded=!1}static _createSound(){return n._id++,l.window.qg.createInnerAudioContext()}load(e){if(n._musicAudio||(n._musicAudio=n._createSound()),i.isLocalNativeFile(e)){if(-1!=e.indexOf("http://")||-1!=e.indexOf("https://"))if(""!=i.loadPath)e=e.split(i.loadPath)[1];else{var a=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath;""!=a&&(e=e.split(a)[1])}}else e=t.URL.formatURL(e);if(this.url=e,this.readyUrl=e,n._audioCache[this.readyUrl])this.event(t.Event.COMPLETE);else if(l.autoCacheFile&&i.getFileInfo(e))this.onDownLoadCallBack(e,0);else if(l.autoCacheFile)if(i.isLocalNativeFile(e)){var s=e;if(""!=(a=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath)&&(e=e.split(a)[1]),e||(e=s),l.subNativeFiles&&0==l.subNativeheads.length)for(var o in l.subNativeFiles){var r=l.subNativeFiles[o];l.subNativeheads=l.subNativeheads.concat(r);for(var d=0;d0&&this.onCanPlay(),t.Laya.timer.clear(this,this.onCheckComplete)}onError(e){try{console.log("-----1---------------minisound-----id:"+n._id),console.log(e)}catch(e){console.log("-----2---------------minisound-----id:"+n._id),console.log(e)}this.event(t.Event.ERROR),this._sound.offError(null)}onCanPlay(){this.loaded=!0,this.event(t.Event.COMPLETE),this._sound&&this._sound.offCanplay&&this._sound.offCanplay(null)}static bindToThis(e,t){return e.bind(t)}play(e=0,s=0){var o;if(this.url==t.SoundManager._bgMusic?(n._musicAudio||(n._musicAudio=n._createSound()),o=n._musicAudio):o=n._audioCache[this.readyUrl]?n._audioCache[this.readyUrl]._sound:n._createSound(),!o)return null;if(l.autoCacheFile&&i.getFileInfo(this.url)){var r=i.getFileInfo(this.url).md5;o.src=this.url=i.getFileNativePath(r)}else o.src=l.safeEncodeURI(this.url);var d=new a(o,this);return d.url=this.url,d.loops=s,d.loop=0===s,d.startTime=e,d.play(),t.SoundManager.addChannel(d),d}get duration(){return this._sound.duration}dispose(){var e=n._audioCache[this.readyUrl];e&&(e.src="",e._sound&&(e._sound.destroy(),e._sound=null,e=null),delete n._audioCache[this.readyUrl]),this._sound&&(this._sound.destroy(),this._sound=null,this.readyUrl=this.url=null)}}n._id=0,n._audioCache={};class s{constructor(){}static _createInputElement(){t.Input._initInput(t.Input.area=t.Browser.createElement("textarea")),t.Input._initInput(t.Input.input=t.Browser.createElement("input")),t.Input.inputContainer=t.Browser.createElement("div"),t.Input.inputContainer.style.position="absolute",t.Input.inputContainer.style.zIndex=1e5,t.Browser.container.appendChild(t.Input.inputContainer),t.Laya.stage.on("resize",null,s._onStageResize),l.window.qg.onWindowResize&&l.window.qg.onWindowResize((function(e){})),t.SoundManager._soundClass=n,t.SoundManager._musicClass=n,t.Browser.onAndroid=!0,t.Browser.onIPhone=!1,t.Browser.onIOS=!1,t.Browser.onIPad=!1}static _onStageResize(){t.Laya.stage._canvasTransform.identity().scale(t.Browser.width/t.Render.canvas.width/t.Browser.pixelRatio,t.Browser.height/t.Render.canvas.height/t.Browser.pixelRatio)}static wxinputFocus(e){var i=t.Input.inputElement.target;i&&!i.editable||(l.window.qg.offKeyboardConfirm(),l.window.qg.offKeyboardInput(),l.window.qg.showKeyboard({defaultValue:i.text,maxLength:i.maxChars,multiple:i.multiline,confirmHold:!0,confirmType:i.confirmType||"done",success:function(e){},fail:function(e){}}),l.window.qg.onKeyboardConfirm((function(e){var a=e?e.value:"";i._restrictPattern&&(a=a.replace(/\u2006|\x27/g,""),i._restrictPattern.test(a)&&(a=a.replace(i._restrictPattern,""))),i.text=a,i.event(t.Event.INPUT),s.inputEnter(),i.event("confirm")})),l.window.qg.onKeyboardInput((function(e){var a=e?e.value:"";i.multiline||-1==a.indexOf("\n")?(i._restrictPattern&&(a=a.replace(/\u2006|\x27/g,""),i._restrictPattern.test(a)&&(a=a.replace(i._restrictPattern,""))),i.text=a,i.event(t.Event.INPUT)):s.inputEnter()})))}static inputEnter(){t.Input.inputElement.target.focus=!1}static wxinputblur(){s.hideKeyboard()}static hideKeyboard(){l.window.qg.offKeyboardConfirm(),l.window.qg.offKeyboardInput(),l.window.qg.hideKeyboard({success:function(e){console.log("隐藏键盘")},fail:function(e){console.log("隐藏键盘出错:"+(e?e.errMsg:""))}})}}class o extends t.EventDispatcher{constructor(){super()}_loadResourceFilter(e,a){if(this.sourceUrl=t.URL.formatURL(a),i.isNetFile(a))if(""!=i.loadPath)a=a.split(i.loadPath)[1];else{var n=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath,s=a;""!=n&&(a=a.split(n)[1]),a||(a=s)}if(l.subNativeFiles&&0==l.subNativeheads.length)for(var r in l.subNativeFiles){var d=l.subNativeFiles[r];l.subNativeheads=l.subNativeheads.concat(d);for(var u=0;u=0?"/":"\\",s=e.lastIndexOf(n),o=s>=0?e.substr(0,s+1):"",r=0,d=a.length;r>>"+n)}}return t},l._inited=!1,l.autoCacheFile=!0,l.minClearSize=5242880,l.sizeLimit=52428800,l.nativefiles=["layaNativeDir","wxlocal"],l.subNativeheads=[],l.subMaps=[],l.AutoCacheDownFile=!1,l.parseXMLFromString=function(e){var t;e=e.replace(/>\s+<");try{t=(new DOMParser).parseFromString(e,"text/xml")}catch(e){throw"需要引入xml解析库文件"}return t},l.idx=1;class r extends t.EventDispatcher{constructor(){super()}static __init__(){try{var e;if(!(e=t.Accelerator))return;e.prototype.on=r.prototype.on,e.prototype.off=r.prototype.off}catch(e){}}static startListen(e){if(r._callBack=e,!r._isListening){r._isListening=!0;try{l.window.qg.onAccelerometerChange(r.onAccelerometerChange)}catch(e){}}}static stopListen(){r._isListening=!1;try{l.window.qg.stopAccelerometer({})}catch(e){}}static onAccelerometerChange(e){var t;(t={}).acceleration=e,t.accelerationIncludingGravity=e,t.rotationRate={},null!=r._callBack&&r._callBack(t)}on(e,t,i,a=null){return super.on(e,t,i,a),r.startListen(this.onDeviceOrientationChange),this}off(e,t,i,a=!1){return this.hasListener(e)||r.stopListen(),super.off(e,t,i,a)}}r._isListening=!1;class d{_loadImage(e){if(l.isZiYu)d.onCreateImage(e,this,!0);else{var a;if(i.isLocalNativeFile(e)){if(-1==e.indexOf("http://usr/")&&(-1!=e.indexOf("http://")||-1!=e.indexOf("https://")))if(""!=i.loadPath)e=e.split(i.loadPath)[1];else{var n=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath,s=e;""!=n&&(e=e.split(n)[1]),e||(e=s)}if(l.subNativeFiles&&0==l.subNativeheads.length)for(var o in l.subNativeFiles){var r=l.subNativeFiles[o];l.subNativeheads=l.subNativeheads.concat(r);for(var u=0;u=f&&(t.size>l.minClearSize&&(l.minClearSize=t.size),i.onClearCacheRes()),i.deleteFile(e,a,n,s,t.size)},fail:function(e){null!=n&&n.runWith([1,e])}}):null!=n&&n.runWith([0]):i.fs.getFileInfo({filePath:e,success:function(t){o&&p+4194304+t.size>=f&&(t.size>l.minClearSize&&(l.minClearSize=t.size),i.onClearCacheRes()),i.fs.copyFile({srcPath:e,destPath:h,success:function(e){i.onSaveFile(a,d,!0,s,n,t.size)},fail:function(e){null!=n&&n.runWith([1,e])}})},fail:function(e){null!=n&&n.runWith([1,e])}})}static onClearCacheRes(){var e=l.minClearSize,t=[];for(var a in i.filesListObj)"fileUsedSize"!=a&&t.push(i.filesListObj[a]);i.sortOn(t,"times",i.NUMERIC);for(var n=0,s=1,o=t.length;s=e)break;n+=r.size,i.deleteFile("",r.readyUrl)}}static sortOn(e,t,a=0){return a==i.NUMERIC?e.sort((function(e,i){return e[t]-i[t]})):a==(i.NUMERIC|i.DESCENDING)?e.sort((function(e,i){return i[t]-e[t]})):e.sort((function(e,i){return e[t]-i[t]}))}static getFileNativePath(e){return i.fileNativeDir+"/"+e}static deleteFile(e,t="",a=null,n="",s=0){var o=i.getFileInfo(t),r=i.getFileNativePath(o.md5);if(i.fs.unlink({filePath:r,success:function(o){if(""!=e){var r=i.getFileNativePath(e);i.fs.copyFile({srcPath:e,destPath:r,success:function(o){i.onSaveFile(t,e,!0,n,a,s)},fail:function(e){null!=a&&a.runWith([1,e])}})}else i.onSaveFile(t,e,!1,n,a,s)},fail:function(e){null!=a&&a.runWith([1,e])}}),t&&""!=t&&-1!=t.indexOf(".zip")){var d=l.zipHeadFiles[t];if(d)try{i.fs.rmdirSync(d,!0)}catch(e){console.log("目录:"+d+"delete fail"),console.log(e)}}}static deleteAll(){var e=[];for(var t in i.filesListObj)"fileUsedSize"!=t&&e.push(i.filesListObj[t]);for(var a=1,n=e.length;a0&&this.loops--,this.startTime=0,this.play()}play(){this.isStopped=!1,t.SoundManager.addChannel(this),this._audio&&this._audio.play()}set startTime(e){this._audio&&(this._audio.startTime=e)}set autoplay(e){this._audio&&(this._audio.autoplay=e)}get autoplay(){return!!this._audio&&this._audio.autoplay}get position(){return this._audio?this._audio.currentTime:0}get duration(){return this._audio?this._audio.duration:0}stop(){super.stop(),this.isStopped=!0,t.SoundManager.removeChannel(this),this.completeHandler=null,this._audio&&(this._audio.stop(),this.loop||(this.offEventListener(),this._sound.dispose(),this._sound=null,this._audio=null))}pause(){this.isStopped=!0,this._audio&&this._audio.pause()}get loop(){return!!this._audio&&this._audio.loop}set loop(e){this._audio&&(this._audio.loop=e)}resume(){this.isStopped=!1,t.SoundManager.addChannel(this),this._audio&&this._audio.play()}set volume(e){this._audio&&(this._audio.volume=e)}get volume(){return this._audio?this._audio.volume:0}}class n extends t.EventDispatcher{constructor(){super(),this.loaded=!1,this._sound=n._createSound()}static _createSound(){return n._id++,l.window.wx.createInnerAudioContext()}load(e){if(i.isLocalNativeFile(e)){if(!i.isLocalNativeZipFile(e)&&i.isNetFile(e))if(""!=i.loadPath)e=e.split(i.loadPath)[1];else{var a=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath;""!=a&&(e=e.split(a)[1])}}else e=t.URL.formatURL(e);if(this.url=e,this.readyUrl=e,l.autoCacheFile&&i.getFileInfo(e))this.onDownLoadCallBack(e,0);else if(l.autoCacheFile)if(i.isLocalNativeFile(e)){if(l.subNativeFiles&&0==l.subNativeheads.length)for(var n in l.subNativeFiles){var s=l.subNativeFiles[n];l.subNativeheads=l.subNativeheads.concat(s);for(let e=0;e=0?"/":"\\",s=e.lastIndexOf(n),o=s>=0?e.substr(0,s+1):"",r=0,d=a.length;r\s+<");try{t=(new l.window.Parser.DOMParser).parseFromString(e,"text/xml")}catch(e){throw"需要引入xml解析库文件"}return t},l.idx=1;class d extends t.EventDispatcher{constructor(){super()}static __init__(){try{var e;if(!(e=t.Accelerator))return;e.prototype.on=d.prototype.on,e.prototype.off=d.prototype.off}catch(e){}}static startListen(e){if(d._callBack=e,!d._isListening){d._isListening=!0;try{l.window.wx.onAccelerometerChange(d.onAccelerometerChange)}catch(e){}}}static stopListen(){d._isListening=!1;try{l.window.wx.stopAccelerometer({})}catch(e){}}static onAccelerometerChange(e){var t;(t={}).acceleration=e,t.accelerationIncludingGravity=e,t.rotationRate={},null!=d._callBack&&d._callBack(t)}on(e,t,i,a=null){return super.on(e,t,i,a),d.startListen(this.onDeviceOrientationChange),this}off(e,t,i,a=!1){return this.hasListener(e)||d.stopListen(),super.off(e,t,i,a)}}d._isListening=!1;class u{constructor(){}static __init__(){l.window.navigator.geolocation.getCurrentPosition=u.getCurrentPosition,l.window.navigator.geolocation.watchPosition=u.watchPosition,l.window.navigator.geolocation.clearWatch=u.clearWatch}static getCurrentPosition(e=null,t=null,i=null){var a;(a={}).success=function(t){null!=e&&e(t)},a.fail=t,l.window.wx.getLocation(a)}static watchPosition(e=null,i=null,a=null){var n;return u._curID++,(n={}).success=e,n.error=i,u._watchDic[u._curID]=n,t.Laya.systemTimer.loop(1e3,null,u._myLoop),u._curID}static clearWatch(e){delete u._watchDic[e],u._hasWatch()||t.Laya.systemTimer.clear(null,u._myLoop)}static _hasWatch(){var e;for(e in u._watchDic)if(u._watchDic[e])return!0;return!1}static _myLoop(){u.getCurrentPosition(u._mySuccess,u._myError)}static _mySuccess(e){var i,a={};for(i in a.coords=e,a.timestamp=t.Browser.now(),u._watchDic)u._watchDic[i].success&&u._watchDic[i].success(a)}static _myError(e){var t;for(t in u._watchDic)u._watchDic[t].error&&u._watchDic[t].error(e)}}u._watchDic={},u._curID=0;e.ImageDataPolyfill=ImageDataPolyfill,e.MiniAccelerator=d,e.MiniAdpter=l,e.MiniFileMgr=i,e.MiniInput=s,e.MiniLoader=o,e.MiniLocalStorage=r,e.MiniLocation=u,e.MiniSound=n,e.MiniSoundChannel=a,e.MiniVideo=class{constructor(e=320,t=240){this.videoend=!1,this.videourl="",this.videoElement=l.window.wx.createVideo({width:e,height:t,autoplay:!0})}static __init__(){}on(e,t,i){"loadedmetadata"==e?(this.onPlayFunc=i.bind(t),this.videoElement.onPlay=this.onPlayFunction.bind(this)):"ended"==e&&(this.onEndedFunC=i.bind(t),this.videoElement.onEnded=this.onEndedFunction.bind(this)),this.videoElement.onTimeUpdate=this.onTimeUpdateFunc.bind(this)}onTimeUpdateFunc(e){this.position=e.position,this._duration=e.duration}get duration(){return this._duration}onPlayFunction(){this.videoElement&&(this.videoElement.readyState=200),console.log("=====视频加载完成========"),null!=this.onPlayFunc&&this.onPlayFunc()}onEndedFunction(){this.videoElement&&(this.videoend=!0,console.log("=====视频播放完毕========"),null!=this.onEndedFunC&&this.onEndedFunC())}off(e,t,i){"loadedmetadata"==e?(this.onPlayFunc=i.bind(t),this.videoElement.offPlay=this.onPlayFunction.bind(this)):"ended"==e&&(this.onEndedFunC=i.bind(t),this.videoElement.offEnded=this.onEndedFunction.bind(this))}load(e){this.videoElement&&(this.videoElement.src=e)}play(){this.videoElement&&(this.videoend=!1,this.videoElement.play())}pause(){this.videoElement&&(this.videoend=!0,this.videoElement.pause())}get currentTime(){return this.videoElement?this.videoElement.initialTime:0}set currentTime(e){this.videoElement&&(this.videoElement.initialTime=e)}get videoWidth(){return this.videoElement?this.videoElement.width:0}get videoHeight(){return this.videoElement?this.videoElement.height:0}get ended(){return this.videoend}get loop(){return!!this.videoElement&&this.videoElement.loop}set loop(e){this.videoElement&&(this.videoElement.loop=e)}get playbackRate(){return this.videoElement?this.videoElement.playbackRate:0}set playbackRate(e){this.videoElement&&(this.videoElement.playbackRate=e)}get muted(){return!!this.videoElement&&this.videoElement.muted}set muted(e){this.videoElement&&(this.videoElement.muted=e)}get paused(){return!!this.videoElement&&this.videoElement.paused}size(e,t){this.videoElement&&(this.videoElement.width=e,this.videoElement.height=t)}get x(){return this.videoElement?this.videoElement.x:0}set x(e){this.videoElement&&(this.videoElement.x=e)}get y(){return this.videoElement?this.videoElement.y:0}set y(e){this.videoElement&&(this.videoElement.y=e)}get currentSrc(){return this.videoElement.src}destroy(){this.videoElement&&this.videoElement.destroy(),this.videoElement=null,this.onEndedFunC=null,this.onPlayFunc=null,this.videoend=!1,this.videourl=null}reload(){this.videoElement&&(this.videoElement.src=this.videourl)}}}; \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/min/laya.xmmini.min.js b/examples/layaair/frontend/bin/libs/min/laya.xmmini.min.js new file mode 100644 index 0000000..88990b2 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/min/laya.xmmini.min.js @@ -0,0 +1 @@ +window.miMiniGame=function(e,t){"use strict";function ImageDataPolyfill(){let e,i,a;if(3==arguments.length){if(!(arguments[0]instanceof Uint8ClampedArray))throw new Error("Failed to construct 'ImageData': parameter 1 is not of type 'Uint8ClampedArray'.");if(arguments[0].length%4!=0)throw new Error("Failed to construct 'ImageData': The input data length is not a multiple of 4.");if(arguments[0].length!==arguments[1]*arguments[2]*4)throw new Error("Failed to construct 'ImageData': The input data length is not equal to (4 * width * height).");a=arguments[0],e=arguments[1],i=arguments[2]}else if(2==arguments.length)e=arguments[0],i=arguments[1],a=new Uint8ClampedArray(arguments[0]*arguments[1]*4);else if(arguments.length<2)throw new Error("Failed to construct 'ImageData': 2 arguments required, but only "+arguments.length+" present.");let n=t.Browser.canvas.getContext("2d").getImageData(0,0,e,i);for(let e=0;e=f&&(t.size>l.minClearSize&&(l.minClearSize=t.size),i.onClearCacheRes()),i.deleteFile(e,a,n,s,t.size)},fail:function(e){null!=n&&n.runWith([1,e])}}):null!=n&&n.runWith([0]):i.fs.getFileInfo({filePath:e,success:function(t){o&&g+4194304+t.size>=f&&(t.size>l.minClearSize&&(l.minClearSize=t.size),i.onClearCacheRes()),i.fs.copyFile({srcPath:e,destPath:h,success:function(e){i.onSaveFile(a,d,!0,s,n,t.size)},fail:function(e){null!=n&&n.runWith([1,e])}})},fail:function(e){null!=n&&n.runWith([1,e])}})}static onClearCacheRes(){var e=l.minClearSize,t=[];for(var a in i.filesListObj)"fileUsedSize"!=a&&t.push(i.filesListObj[a]);i.sortOn(t,"times",i.NUMERIC);for(var n=0,s=1,o=t.length;s=e)break;n+=r.size,i.deleteFile("",r.readyUrl)}}static sortOn(e,t,a=0){return a==i.NUMERIC?e.sort((function(e,i){return e[t]-i[t]})):a==(i.NUMERIC|i.DESCENDING)?e.sort((function(e,i){return i[t]-e[t]})):e.sort((function(e,i){return e[t]-i[t]}))}static getFileNativePath(e){return i.fileNativeDir+"/"+e}static deleteFile(e,t="",a=null,n="",s=0){var o=i.getFileInfo(t),l=i.getFileNativePath(o.md5);i.fs.unlink({filePath:l,success:function(o){if(""!=e){var l=i.getFileNativePath(e);i.fs.copyFile({srcPath:e,destPath:l,success:function(o){i.onSaveFile(t,e,!0,n,a,s)},fail:function(e){null!=a&&a.runWith([1,e])}})}else i.onSaveFile(t,e,!1,n,a,s)},fail:function(e){null!=a&&a.runWith([1,e])}})}static deleteAll(){var e=[];for(var t in i.filesListObj)"fileUsedSize"!=t&&e.push(i.filesListObj[t]);for(var a=1,n=e.length;a0&&this.loops--,this.startTime=0,this.play()}play(){this.isStopped=!1,t.SoundManager.addChannel(this),this._audio.play()}set startTime(e){this._audio&&(this._audio.startTime=e)}set autoplay(e){this._audio.autoplay=e}get autoplay(){return this._audio.autoplay}get position(){return this._audio?this._audio.currentTime:0}get duration(){return this._audio?this._audio.duration:0}stop(){this.isStopped=!0,t.SoundManager.removeChannel(this),this.completeHandler=null,this._audio&&(this._audio.stop(),this.loop||(this._audio.offEnded(null),this._miniSound.dispose(),this._audio=null,this._miniSound=null,this._onEnd=null))}pause(){this.isStopped=!0,this._audio.pause()}get loop(){return this._audio.loop}set loop(e){this._audio.loop=e}resume(){this._audio&&(this.isStopped=!1,t.SoundManager.addChannel(this),this._audio.play())}set volume(e){this._audio&&(this._audio.volume=e)}get volume(){return this._audio?this._audio.volume:1}}class n extends t.EventDispatcher{constructor(){super(),this.loaded=!1}static _createSound(){return n._id++,l.window.qg.createInnerAudioContext()}load(e){if(n._musicAudio||(n._musicAudio=n._createSound()),i.isLocalNativeFile(e)){if(-1!=e.indexOf("http://")||-1!=e.indexOf("https://"))if(""!=i.loadPath)e=e.split(i.loadPath)[1];else{var a=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath;""!=a&&(e=e.split(a)[1])}}else e=t.URL.formatURL(e);if(this.url=e,this.readyUrl=e,n._audioCache[this.readyUrl])this.event(t.Event.COMPLETE);else if(l.autoCacheFile&&i.getFileInfo(e))this.onDownLoadCallBack(e,0);else if(l.autoCacheFile)if(i.isLocalNativeFile(e)){var s=e;if(""!=(a=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath)&&(e=e.split(a)[1]),e||(e=s),l.subNativeFiles&&0==l.subNativeheads.length)for(var o in l.subNativeFiles){var r=l.subNativeFiles[o];l.subNativeheads=l.subNativeheads.concat(r);for(var d=0;d=0?"/":"\\",s=e.lastIndexOf(n),o=s>=0?e.substr(0,s+1):"",r=0,d=a.length;r>>"+n)}}return t},l._inited=!1,l.autoCacheFile=!0,l.minClearSize=5242880,l.sizeLimit=52428800,l.nativefiles=["layaNativeDir","wxlocal"],l.subNativeFiles=[],l.subNativeheads=[],l.subMaps=[],l.AutoCacheDownFile=!1,l.parseXMLFromString=function(e){var t;e=e.replace(/>\s+<");try{t=(new l.window.Parser.DOMParser).parseFromString(e,"text/xml")}catch(e){throw"需要引入xml解析库文件"}return t},l.idx=1;class r extends t.EventDispatcher{constructor(){super()}static __init__(){try{var e;if(!(e=t.Accelerator))return;e.prototype.on=r.prototype.on,e.prototype.off=r.prototype.off}catch(e){}}static startListen(e){if(r._callBack=e,!r._isListening){r._isListening=!0;try{l.window.swan.onAccelerometerChange(r.onAccelerometerChange)}catch(e){}}}static stopListen(){r._isListening=!1;try{l.window.swan.stopAccelerometer({})}catch(e){}}static onAccelerometerChange(e){var t;(t={}).acceleration=e,t.accelerationIncludingGravity=e,t.rotationRate={},null!=r._callBack&&r._callBack(t)}on(e,t,i,a=null){return super.on(e,t,i,a),r.startListen(this.onDeviceOrientationChange),this}off(e,t,i,a=!1){return this.hasListener(e)||r.stopListen(),super.off(e,t,i,a)}}r._isListening=!1;class d{_loadImage(e){if(l.isZiYu)d.onCreateImage(e,this,!0);else{var a;if(i.isLocalNativeFile(e)){if(-1==e.indexOf("http://usr/")&&(-1!=e.indexOf("http://")||-1!=e.indexOf("https://")))if(""!=i.loadPath)e=e.split(i.loadPath)[1];else{var n=""!=t.URL.rootPath?t.URL.rootPath:t.URL._basePath,s=e;""!=n&&(e=e.split(n)[1]),e||(e=s)}if(l.subNativeFiles&&0==l.subNativeheads.length)for(var o in l.subNativeFiles){var r=l.subNativeFiles[o];l.subNativeheads=l.subNativeheads.concat(r);for(var u=0;u0&&(e%=this.duration));let o=this.timelines;for(let i=0,h=o.length;i>>1;for(;;){if(t[(n+1)*s]<=e?i=n+1:a=n,i==a)return(i+1)*s;n=i+a>>>1}}static linearSearch(t,e,s){for(let i=0,a=t.length-s;i<=a;i+=s)if(t[i]>e)return i;return-1}}let s,i,a;t.Animation=e,function(t){t[t.setup=0]="setup",t[t.first=1]="first",t[t.replace=2]="replace",t[t.add=3]="add"}(s=t.MixBlend||(t.MixBlend={})),function(t){t[t.in=0]="in",t[t.out=1]="out"}(i=t.MixDirection||(t.MixDirection={})),function(t){t[t.rotate=0]="rotate",t[t.translate=1]="translate",t[t.scale=2]="scale",t[t.shear=3]="shear",t[t.attachment=4]="attachment",t[t.color=5]="color",t[t.deform=6]="deform",t[t.event=7]="event",t[t.drawOrder=8]="drawOrder",t[t.ikConstraint=9]="ikConstraint",t[t.transformConstraint=10]="transformConstraint",t[t.pathConstraintPosition=11]="pathConstraintPosition",t[t.pathConstraintSpacing=12]="pathConstraintSpacing",t[t.pathConstraintMix=13]="pathConstraintMix",t[t.twoColor=14]="twoColor"}(a=t.TimelineType||(t.TimelineType={}));class n{constructor(e){if(e<=0)throw new Error("frameCount must be > 0: "+e);this.curves=t.Utils.newFloatArray((e-1)*n.BEZIER_SIZE)}getFrameCount(){return this.curves.length/n.BEZIER_SIZE+1}setLinear(t){this.curves[t*n.BEZIER_SIZE]=n.LINEAR}setStepped(t){this.curves[t*n.BEZIER_SIZE]=n.STEPPED}getCurveType(t){let e=t*n.BEZIER_SIZE;if(e==this.curves.length)return n.LINEAR;let s=this.curves[e];return s==n.LINEAR?n.LINEAR:s==n.STEPPED?n.STEPPED:n.BEZIER}setCurve(t,e,s,i,a){let r=.03*(2*-e+i),l=.03*(2*-s+a),o=.006*(3*(e-i)+1),h=.006*(3*(s-a)+1),u=2*r+o,d=2*l+h,c=.3*e+r+.16666667*o,f=.3*s+l+.16666667*h,m=t*n.BEZIER_SIZE,p=this.curves;p[m++]=n.BEZIER;let g=c,x=f;for(let t=m+n.BEZIER_SIZE-1;m=s){let e,n;return a==t?(e=0,n=0):(e=i[a-2],n=i[a-1]),n+(i[a+1]-n)*(s-e)/(l-e)}let o=i[a-1];return o+(1-o)*(s-l)/(1-l)}}n.LINEAR=0,n.STEPPED=1,n.BEZIER=2,n.BEZIER_SIZE=19,t.CurveTimeline=n;class r extends n{constructor(e){super(e),this.frames=t.Utils.newFloatArray(e<<1)}getPropertyId(){return(a.rotate<<24)+this.boneIndex}setFrame(t,e,s){t<<=1,this.frames[t]=e,this.frames[t+r.ROTATION]=s}apply(t,i,a,n,l,o,h){let u=this.frames,d=t.bones[this.boneIndex];if(a=u[u.length-r.ENTRIES]){let t=u[u.length+r.PREV_ROTATION];switch(o){case s.setup:d.rotation=d.data.rotation+t*l;break;case s.first:case s.replace:t+=d.data.rotation-d.rotation,t-=360*(16384-(16384.499999999996-t/360|0));case s.add:d.rotation+=t*l}return}let c=e.binarySearch(u,a,r.ENTRIES),f=u[c+r.PREV_ROTATION],m=u[c],p=this.getCurvePercent((c>>1)-1,1-(a-m)/(u[c+r.PREV_TIME]-m)),g=u[c+r.ROTATION]-f;switch(g=f+(g-360*(16384-(16384.499999999996-g/360|0)))*p,o){case s.setup:d.rotation=d.data.rotation+(g-360*(16384-(16384.499999999996-g/360|0)))*l;break;case s.first:case s.replace:g+=d.data.rotation-d.rotation;case s.add:d.rotation+=(g-360*(16384-(16384.499999999996-g/360|0)))*l}}}r.ENTRIES=2,r.PREV_TIME=-2,r.PREV_ROTATION=-1,r.ROTATION=1,t.RotateTimeline=r;class l extends n{constructor(e){super(e),this.frames=t.Utils.newFloatArray(e*l.ENTRIES)}getPropertyId(){return(a.translate<<24)+this.boneIndex}setFrame(t,e,s,i){t*=l.ENTRIES,this.frames[t]=e,this.frames[t+l.X]=s,this.frames[t+l.Y]=i}apply(t,i,a,n,r,o,h){let u=this.frames,d=t.bones[this.boneIndex];if(a=u[u.length-l.ENTRIES])c=u[u.length+l.PREV_X],f=u[u.length+l.PREV_Y];else{let t=e.binarySearch(u,a,l.ENTRIES);c=u[t+l.PREV_X],f=u[t+l.PREV_Y];let s=u[t],i=this.getCurvePercent(t/l.ENTRIES-1,1-(a-s)/(u[t+l.PREV_TIME]-s));c+=(u[t+l.X]-c)*i,f+=(u[t+l.Y]-f)*i}switch(o){case s.setup:d.x=d.data.x+c*r,d.y=d.data.y+f*r;break;case s.first:case s.replace:d.x+=(d.data.x+c-d.x)*r,d.y+=(d.data.y+f-d.y)*r;break;case s.add:d.x+=c*r,d.y+=f*r}}}l.ENTRIES=3,l.PREV_TIME=-3,l.PREV_X=-2,l.PREV_Y=-1,l.X=1,l.Y=2,t.TranslateTimeline=l;class o extends l{constructor(t){super(t)}getPropertyId(){return(a.scale<<24)+this.boneIndex}apply(a,n,r,l,h,u,d){let c=this.frames,f=a.bones[this.boneIndex];if(r=c[c.length-o.ENTRIES])m=c[c.length+o.PREV_X]*f.data.scaleX,p=c[c.length+o.PREV_Y]*f.data.scaleY;else{let t=e.binarySearch(c,r,o.ENTRIES);m=c[t+o.PREV_X],p=c[t+o.PREV_Y];let s=c[t],i=this.getCurvePercent(t/o.ENTRIES-1,1-(r-s)/(c[t+o.PREV_TIME]-s));m=(m+(c[t+o.X]-m)*i)*f.data.scaleX,p=(p+(c[t+o.Y]-p)*i)*f.data.scaleY}if(1==h)u==s.add?(f.scaleX+=m-f.data.scaleX,f.scaleY+=p-f.data.scaleY):(f.scaleX=m,f.scaleY=p);else{let e=0,a=0;if(d==i.out)switch(u){case s.setup:e=f.data.scaleX,a=f.data.scaleY,f.scaleX=e+(Math.abs(m)*t.MathUtils.signum(e)-e)*h,f.scaleY=a+(Math.abs(p)*t.MathUtils.signum(a)-a)*h;break;case s.first:case s.replace:e=f.scaleX,a=f.scaleY,f.scaleX=e+(Math.abs(m)*t.MathUtils.signum(e)-e)*h,f.scaleY=a+(Math.abs(p)*t.MathUtils.signum(a)-a)*h;break;case s.add:e=f.scaleX,a=f.scaleY,f.scaleX=e+(Math.abs(m)*t.MathUtils.signum(e)-f.data.scaleX)*h,f.scaleY=a+(Math.abs(p)*t.MathUtils.signum(a)-f.data.scaleY)*h}else switch(u){case s.setup:e=Math.abs(f.data.scaleX)*t.MathUtils.signum(m),a=Math.abs(f.data.scaleY)*t.MathUtils.signum(p),f.scaleX=e+(m-e)*h,f.scaleY=a+(p-a)*h;break;case s.first:case s.replace:e=Math.abs(f.scaleX)*t.MathUtils.signum(m),a=Math.abs(f.scaleY)*t.MathUtils.signum(p),f.scaleX=e+(m-e)*h,f.scaleY=a+(p-a)*h;break;case s.add:e=t.MathUtils.signum(m),a=t.MathUtils.signum(p),f.scaleX=Math.abs(f.scaleX)*e+(m-Math.abs(f.data.scaleX)*e)*h,f.scaleY=Math.abs(f.scaleY)*a+(p-Math.abs(f.data.scaleY)*a)*h}}}}t.ScaleTimeline=o;class h extends l{constructor(t){super(t)}getPropertyId(){return(a.shear<<24)+this.boneIndex}apply(t,i,a,n,r,l,o){let u=this.frames,d=t.bones[this.boneIndex];if(a=u[u.length-h.ENTRIES])c=u[u.length+h.PREV_X],f=u[u.length+h.PREV_Y];else{let t=e.binarySearch(u,a,h.ENTRIES);c=u[t+h.PREV_X],f=u[t+h.PREV_Y];let s=u[t],i=this.getCurvePercent(t/h.ENTRIES-1,1-(a-s)/(u[t+h.PREV_TIME]-s));c+=(u[t+h.X]-c)*i,f+=(u[t+h.Y]-f)*i}switch(l){case s.setup:d.shearX=d.data.shearX+c*r,d.shearY=d.data.shearY+f*r;break;case s.first:case s.replace:d.shearX+=(d.data.shearX+c-d.shearX)*r,d.shearY+=(d.data.shearY+f-d.shearY)*r;break;case s.add:d.shearX+=c*r,d.shearY+=f*r}}}t.ShearTimeline=h;class u extends n{constructor(e){super(e),this.frames=t.Utils.newFloatArray(e*u.ENTRIES)}getPropertyId(){return(a.color<<24)+this.slotIndex}setFrame(t,e,s,i,a,n){t*=u.ENTRIES,this.frames[t]=e,this.frames[t+u.R]=s,this.frames[t+u.G]=i,this.frames[t+u.B]=a,this.frames[t+u.A]=n}apply(t,i,a,n,r,l,o){let h=t.slots[this.slotIndex],d=this.frames;if(a=d[d.length-u.ENTRIES]){let t=d.length;c=d[t+u.PREV_R],f=d[t+u.PREV_G],m=d[t+u.PREV_B],p=d[t+u.PREV_A]}else{let t=e.binarySearch(d,a,u.ENTRIES);c=d[t+u.PREV_R],f=d[t+u.PREV_G],m=d[t+u.PREV_B],p=d[t+u.PREV_A];let s=d[t],i=this.getCurvePercent(t/u.ENTRIES-1,1-(a-s)/(d[t+u.PREV_TIME]-s));c+=(d[t+u.R]-c)*i,f+=(d[t+u.G]-f)*i,m+=(d[t+u.B]-m)*i,p+=(d[t+u.A]-p)*i}if(1==r)h.color.set(c,f,m,p);else{let t=h.color;l==s.setup&&t.setFromColor(h.data.color),t.add((c-t.r)*r,(f-t.g)*r,(m-t.b)*r,(p-t.a)*r)}}}u.ENTRIES=5,u.PREV_TIME=-5,u.PREV_R=-4,u.PREV_G=-3,u.PREV_B=-2,u.PREV_A=-1,u.R=1,u.G=2,u.B=3,u.A=4,t.ColorTimeline=u;class d extends n{constructor(e){super(e),this.frames=t.Utils.newFloatArray(e*d.ENTRIES)}getPropertyId(){return(a.twoColor<<24)+this.slotIndex}setFrame(t,e,s,i,a,n,r,l,o){t*=d.ENTRIES,this.frames[t]=e,this.frames[t+d.R]=s,this.frames[t+d.G]=i,this.frames[t+d.B]=a,this.frames[t+d.A]=n,this.frames[t+d.R2]=r,this.frames[t+d.G2]=l,this.frames[t+d.B2]=o}apply(t,i,a,n,r,l,o){let h=t.slots[this.slotIndex],u=this.frames;if(a=u[u.length-d.ENTRIES]){let t=u.length;c=u[t+d.PREV_R],f=u[t+d.PREV_G],m=u[t+d.PREV_B],p=u[t+d.PREV_A],g=u[t+d.PREV_R2],x=u[t+d.PREV_G2],M=u[t+d.PREV_B2]}else{let t=e.binarySearch(u,a,d.ENTRIES);c=u[t+d.PREV_R],f=u[t+d.PREV_G],m=u[t+d.PREV_B],p=u[t+d.PREV_A],g=u[t+d.PREV_R2],x=u[t+d.PREV_G2],M=u[t+d.PREV_B2];let s=u[t],i=this.getCurvePercent(t/d.ENTRIES-1,1-(a-s)/(u[t+d.PREV_TIME]-s));c+=(u[t+d.R]-c)*i,f+=(u[t+d.G]-f)*i,m+=(u[t+d.B]-m)*i,p+=(u[t+d.A]-p)*i,g+=(u[t+d.R2]-g)*i,x+=(u[t+d.G2]-x)*i,M+=(u[t+d.B2]-M)*i}if(1==r)h.color.set(c,f,m,p),h.darkColor.set(g,x,M,1);else{let t=h.color,e=h.darkColor;l==s.setup&&(t.setFromColor(h.data.color),e.setFromColor(h.data.darkColor)),t.add((c-t.r)*r,(f-t.g)*r,(m-t.b)*r,(p-t.a)*r),e.add((g-e.r)*r,(x-e.g)*r,(M-e.b)*r,0)}}}d.ENTRIES=8,d.PREV_TIME=-8,d.PREV_R=-7,d.PREV_G=-6,d.PREV_B=-5,d.PREV_A=-4,d.PREV_R2=-3,d.PREV_G2=-2,d.PREV_B2=-1,d.R=1,d.G=2,d.B=3,d.A=4,d.R2=5,d.G2=6,d.B2=7,t.TwoColorTimeline=d;t.AttachmentTimeline=class{constructor(e){this.frames=t.Utils.newFloatArray(e),this.attachmentNames=new Array(e)}getPropertyId(){return(a.attachment<<24)+this.slotIndex}getFrameCount(){return this.frames.length}setFrame(t,e,s){this.frames[t]=e,this.attachmentNames[t]=s}apply(t,a,n,r,l,o,h){let u=t.slots[this.slotIndex];if(h==i.out&&o==s.setup){let e=u.data.attachmentName;return void u.setAttachment(null==e?null:t.getAttachment(this.slotIndex,e))}let d=this.frames;if(n=d[d.length-1]?d.length-1:e.binarySearch(d,n,1)-1;let f=this.attachmentNames[c];t.slots[this.slotIndex].setAttachment(null==f?null:t.getAttachment(this.slotIndex,f))}};let c=null;t.DeformTimeline=class extends n{constructor(e){super(e),this.frames=t.Utils.newFloatArray(e),this.frameVertices=new Array(e),null==c&&(c=t.Utils.newFloatArray(64))}getPropertyId(){return(a.deform<<27)+ +this.attachment.id+this.slotIndex}setFrame(t,e,s){this.frames[t]=e,this.frameVertices[t]=s}apply(i,a,n,r,l,o,h){let u=i.slots[this.slotIndex],d=u.getAttachment();if(!(d instanceof t.VertexAttachment&&d.applyDeform(this.attachment)))return;let c=u.attachmentVertices;0==c.length&&(o=s.setup);let f=this.frameVertices,m=f[0].length,p=this.frames;if(n=p[p.length-1]){let e=f[p.length-1];if(1==l)if(o==s.add){let t=d;if(null==t.bones){let s=t.vertices;for(let t=0;ti)this.apply(t,s,Number.MAX_VALUE,a,n,r,l),s=-1;else if(s>=o[h-1])return;if(i0&&o[u-1]==t;)u--}for(;u=o[u];u++)a.push(this.events[u])}};t.DrawOrderTimeline=class{constructor(e){this.frames=t.Utils.newFloatArray(e),this.drawOrders=new Array(e)}getPropertyId(){return a.drawOrder<<24}getFrameCount(){return this.frames.length}setFrame(t,e,s){this.frames[t]=e,this.drawOrders[t]=s}apply(a,n,r,l,o,h,u){let d=a.drawOrder,c=a.slots;if(u==i.out&&h==s.setup)return void t.Utils.arrayCopy(a.slots,0,a.drawOrder,0,a.slots.length);let f=this.frames;if(r=f[f.length-1]?f.length-1:e.binarySearch(f,r)-1;let p=this.drawOrders[m];if(null==p)t.Utils.arrayCopy(c,0,d,0,c.length);else for(let t=0,e=p.length;t=u[u.length-f.ENTRIES])return void(o==s.setup?(d.mix=d.data.mix+(u[u.length+f.PREV_MIX]-d.data.mix)*l,h==i.out?(d.bendDirection=d.data.bendDirection,d.compress=d.data.compress,d.stretch=d.data.stretch):(d.bendDirection=u[u.length+f.PREV_BEND_DIRECTION],d.compress=0!=u[u.length+f.PREV_COMPRESS],d.stretch=0!=u[u.length+f.PREV_STRETCH])):(d.mix+=(u[u.length+f.PREV_MIX]-d.mix)*l,h==i.in&&(d.bendDirection=u[u.length+f.PREV_BEND_DIRECTION],d.compress=0!=u[u.length+f.PREV_COMPRESS],d.stretch=0!=u[u.length+f.PREV_STRETCH])));let c=e.binarySearch(u,n,f.ENTRIES),m=u[c+f.PREV_MIX],p=u[c],g=this.getCurvePercent(c/f.ENTRIES-1,1-(n-p)/(u[c+f.PREV_TIME]-p));o==s.setup?(d.mix=d.data.mix+(m+(u[c+f.MIX]-m)*g-d.data.mix)*l,h==i.out?(d.bendDirection=d.data.bendDirection,d.compress=d.data.compress,d.stretch=d.data.stretch):(d.bendDirection=u[c+f.PREV_BEND_DIRECTION],d.compress=0!=u[c+f.PREV_COMPRESS],d.stretch=0!=u[c+f.PREV_STRETCH])):(d.mix+=(m+(u[c+f.MIX]-m)*g-d.mix)*l,h==i.in&&(d.bendDirection=u[c+f.PREV_BEND_DIRECTION],d.compress=0!=u[c+f.PREV_COMPRESS],d.stretch=0!=u[c+f.PREV_STRETCH]))}}f.ENTRIES=5,f.PREV_TIME=-5,f.PREV_MIX=-4,f.PREV_BEND_DIRECTION=-3,f.PREV_COMPRESS=-2,f.PREV_STRETCH=-1,f.MIX=1,f.BEND_DIRECTION=2,f.COMPRESS=3,f.STRETCH=4,t.IkConstraintTimeline=f;class m extends n{constructor(e){super(e),this.frames=t.Utils.newFloatArray(e*m.ENTRIES)}getPropertyId(){return(a.transformConstraint<<24)+this.transformConstraintIndex}setFrame(t,e,s,i,a,n){t*=m.ENTRIES,this.frames[t]=e,this.frames[t+m.ROTATE]=s,this.frames[t+m.TRANSLATE]=i,this.frames[t+m.SCALE]=a,this.frames[t+m.SHEAR]=n}apply(t,i,a,n,r,l,o){let h=this.frames,u=t.transformConstraints[this.transformConstraintIndex];if(a=h[h.length-m.ENTRIES]){let t=h.length;d=h[t+m.PREV_ROTATE],c=h[t+m.PREV_TRANSLATE],f=h[t+m.PREV_SCALE],p=h[t+m.PREV_SHEAR]}else{let t=e.binarySearch(h,a,m.ENTRIES);d=h[t+m.PREV_ROTATE],c=h[t+m.PREV_TRANSLATE],f=h[t+m.PREV_SCALE],p=h[t+m.PREV_SHEAR];let s=h[t],i=this.getCurvePercent(t/m.ENTRIES-1,1-(a-s)/(h[t+m.PREV_TIME]-s));d+=(h[t+m.ROTATE]-d)*i,c+=(h[t+m.TRANSLATE]-c)*i,f+=(h[t+m.SCALE]-f)*i,p+=(h[t+m.SHEAR]-p)*i}if(l==s.setup){let t=u.data;u.rotateMix=t.rotateMix+(d-t.rotateMix)*r,u.translateMix=t.translateMix+(c-t.translateMix)*r,u.scaleMix=t.scaleMix+(f-t.scaleMix)*r,u.shearMix=t.shearMix+(p-t.shearMix)*r}else u.rotateMix+=(d-u.rotateMix)*r,u.translateMix+=(c-u.translateMix)*r,u.scaleMix+=(f-u.scaleMix)*r,u.shearMix+=(p-u.shearMix)*r}}m.ENTRIES=5,m.PREV_TIME=-5,m.PREV_ROTATE=-4,m.PREV_TRANSLATE=-3,m.PREV_SCALE=-2,m.PREV_SHEAR=-1,m.ROTATE=1,m.TRANSLATE=2,m.SCALE=3,m.SHEAR=4,t.TransformConstraintTimeline=m;class p extends n{constructor(e){super(e),this.frames=t.Utils.newFloatArray(e*p.ENTRIES)}getPropertyId(){return(a.pathConstraintPosition<<24)+this.pathConstraintIndex}setFrame(t,e,s){t*=p.ENTRIES,this.frames[t]=e,this.frames[t+p.VALUE]=s}apply(t,i,a,n,r,l,o){let h=this.frames,u=t.pathConstraints[this.pathConstraintIndex];if(a=h[h.length-p.ENTRIES])d=h[h.length+p.PREV_VALUE];else{let t=e.binarySearch(h,a,p.ENTRIES);d=h[t+p.PREV_VALUE];let s=h[t],i=this.getCurvePercent(t/p.ENTRIES-1,1-(a-s)/(h[t+p.PREV_TIME]-s));d+=(h[t+p.VALUE]-d)*i}l==s.setup?u.position=u.data.position+(d-u.data.position)*r:u.position+=(d-u.position)*r}}p.ENTRIES=2,p.PREV_TIME=-2,p.PREV_VALUE=-1,p.VALUE=1,t.PathConstraintPositionTimeline=p;class g extends p{constructor(t){super(t)}getPropertyId(){return(a.pathConstraintSpacing<<24)+this.pathConstraintIndex}apply(t,i,a,n,r,l,o){let h=this.frames,u=t.pathConstraints[this.pathConstraintIndex];if(a=h[h.length-g.ENTRIES])d=h[h.length+g.PREV_VALUE];else{let t=e.binarySearch(h,a,g.ENTRIES);d=h[t+g.PREV_VALUE];let s=h[t],i=this.getCurvePercent(t/g.ENTRIES-1,1-(a-s)/(h[t+g.PREV_TIME]-s));d+=(h[t+g.VALUE]-d)*i}l==s.setup?u.spacing=u.data.spacing+(d-u.data.spacing)*r:u.spacing+=(d-u.spacing)*r}}t.PathConstraintSpacingTimeline=g;class x extends n{constructor(e){super(e),this.frames=t.Utils.newFloatArray(e*x.ENTRIES)}getPropertyId(){return(a.pathConstraintMix<<24)+this.pathConstraintIndex}setFrame(t,e,s,i){t*=x.ENTRIES,this.frames[t]=e,this.frames[t+x.ROTATE]=s,this.frames[t+x.TRANSLATE]=i}apply(t,i,a,n,r,l,o){let h=this.frames,u=t.pathConstraints[this.pathConstraintIndex];if(a=h[h.length-x.ENTRIES])d=h[h.length+x.PREV_ROTATE],c=h[h.length+x.PREV_TRANSLATE];else{let t=e.binarySearch(h,a,x.ENTRIES);d=h[t+x.PREV_ROTATE],c=h[t+x.PREV_TRANSLATE];let s=h[t],i=this.getCurvePercent(t/x.ENTRIES-1,1-(a-s)/(h[t+x.PREV_TIME]-s));d+=(h[t+x.ROTATE]-d)*i,c+=(h[t+x.TRANSLATE]-c)*i}l==s.setup?(u.rotateMix=u.data.rotateMix+(d-u.data.rotateMix)*r,u.translateMix=u.data.translateMix+(c-u.data.translateMix)*r):(u.rotateMix+=(d-u.rotateMix)*r,u.translateMix+=(c-u.translateMix)*r)}}x.ENTRIES=3,x.PREV_TIME=-3,x.PREV_ROTATE=-2,x.PREV_TRANSLATE=-1,x.ROTATE=1,x.TRANSLATE=2,t.PathConstraintMixTimeline=x}(spine||(spine={})),function(t){class e{constructor(e){this.tracks=new Array,this.events=new Array,this.listeners=new Array,this.queue=new i(this),this.propertyIDs=new t.IntSet,this.animationsChanged=!1,this.timeScale=1,this.trackEntryPool=new t.Pool(()=>new s),this.data=e}update(t){t*=this.timeScale;let e=this.tracks;for(let s=0,i=e.length;s0){if(i.delay-=a,i.delay>0)continue;a=-i.delay,i.delay=0}let n=i.next;if(null!=n){let e=i.trackLast-n.delay;if(e>=0){for(n.delay=0,n.trackTime=0==i.timeScale?0:(e/i.timeScale+t)*n.timeScale,i.trackTime+=a,this.setCurrent(s,n,!0);null!=n.mixingFrom;)n.mixTime+=t,n=n.mixingFrom;continue}}else if(i.trackLast>=i.trackEnd&&null==i.mixingFrom){e[s]=null,this.queue.end(i),this.disposeNext(i);continue}if(null!=i.mixingFrom&&this.updateMixingFrom(i,t)){let t=i.mixingFrom;for(i.mixingFrom=null,null!=t&&(t.mixingTo=null);null!=t;)this.queue.end(t),t=t.mixingFrom}i.trackTime+=a}this.queue.drain()}updateMixingFrom(t,e){let s=t.mixingFrom;if(null==s)return!0;let i=this.updateMixingFrom(s,e);return s.animationLast=s.nextAnimationLast,s.trackLast=s.nextTrackLast,t.mixTime>0&&t.mixTime>=t.mixDuration?(0!=s.totalAlpha&&0!=t.mixDuration||(t.mixingFrom=s.mixingFrom,null!=s.mixingFrom&&(s.mixingFrom.mixingTo=t),t.interruptAlpha=s.interruptAlpha,this.queue.end(s)),i):(s.trackTime+=e*s.timeScale,t.mixTime+=e,!1)}apply(s){if(null==s)throw new Error("skeleton cannot be null.");this.animationsChanged&&this._animationsChanged();let i=this.events,a=this.tracks,n=!1;for(let r=0,l=a.length;r0)continue;n=!0;let o=0==r?t.MixBlend.first:l.mixBlend,h=l.alpha;null!=l.mixingFrom?h*=this.applyMixingFrom(l,s,o):l.trackTime>=l.trackEnd&&null==l.next&&(h=0);let u=l.animationLast,d=l.getAnimationTime(),c=l.animation.timelines.length,f=l.animation.timelines;if(0==r&&1==h||o==t.MixBlend.add)for(let e=0;e1&&(r=1),a!=t.MixBlend.first&&(a=n.mixBlend));let l=r0&&this.queueEvents(n,d),this.events.length=0,n.nextAnimationLast=d,n.nextTrackLast=n.trackTime,r}applyRotateTimeline(e,s,i,a,n,r,l,o){if(o&&(r[l]=0),1==a)return void e.apply(s,0,i,null,1,n,t.MixDirection.in);let h=e,u=h.frames,d=s.bones[h.boneIndex],c=0,f=0;if(i=u[u.length-t.RotateTimeline.ENTRIES])f=d.data.rotation+u[u.length+t.RotateTimeline.PREV_ROTATION];else{let e=t.Animation.binarySearch(u,i,t.RotateTimeline.ENTRIES),s=u[e+t.RotateTimeline.PREV_ROTATION],a=u[e],n=h.getCurvePercent((e>>1)-1,1-(i-a)/(u[e+t.RotateTimeline.PREV_TIME]-a));f=u[e+t.RotateTimeline.ROTATION]-s,f-=360*(16384-(16384.499999999996-f/360|0)),f=s+f*n+d.data.rotation,f-=360*(16384-(16384.499999999996-f/360|0))}let m=0,p=f-c;if(p-=360*(16384-(16384.499999999996-p/360|0)),0==p)m=r[l];else{let e=0,s=0;o?(e=0,s=p):(e=r[l],s=r[l+1]);let i=p>0,a=e>=0;t.MathUtils.signum(s)!=t.MathUtils.signum(p)&&Math.abs(s)<=90&&(Math.abs(e)>180&&(e+=360*t.MathUtils.signum(e)),a=i),m=p+e-e%360,a!=i&&(m+=360*t.MathUtils.signum(e)),r[l]=m}r[l+1]=p,c+=m*a,d.rotation=c-360*(16384-(16384.499999999996-c/360|0))}queueEvents(t,e){let s=t.animationStart,i=t.animationEnd,a=i-s,n=t.trackLast%a,r=this.events,l=0,o=r.length;for(;li||this.queue.event(t,e)}let h=!1;for(h=t.loop?0==a||n>t.trackTime%a:e>=i&&t.animationLast=this.tracks.length)return;let e=this.tracks[t];if(null==e)return;this.queue.end(e),this.disposeNext(e);let s=e;for(;;){let t=s.mixingFrom;if(null==t)break;this.queue.end(t),s.mixingFrom=null,s.mixingTo=null,s=t}this.tracks[e.trackIndex]=null,this.queue.drain()}setCurrent(t,e,s){let i=this.expandToIndex(t);this.tracks[t]=e,null!=i&&(s&&this.queue.interrupt(i),e.mixingFrom=i,i.mixingTo=e,e.mixTime=0,null!=i.mixingFrom&&i.mixDuration>0&&(e.interruptAlpha*=Math.min(1,i.mixTime/i.mixDuration)),i.timelinesRotation.length=0),this.queue.start(e)}setAnimation(t,e,s){let i=this.data.skeletonData.findAnimation(e);if(null==i)throw new Error("Animation not found: "+e);return this.setAnimationWith(t,i,s)}setAnimationWith(t,e,s){if(null==e)throw new Error("animation cannot be null.");let i=!0,a=this.expandToIndex(t);null!=a&&(-1==a.nextTrackLast?(this.tracks[t]=a.mixingFrom,this.queue.interrupt(a),this.queue.end(a),this.disposeNext(a),a=a.mixingFrom,i=!1):this.disposeNext(a));let n=this.trackEntry(t,e,s,a);return this.setCurrent(t,n,i),this.queue.drain(),n}addAnimation(t,e,s,i){let a=this.data.skeletonData.findAnimation(e);if(null==a)throw new Error("Animation not found: "+e);return this.addAnimationWith(t,a,s,i)}addAnimationWith(t,e,s,i){if(null==e)throw new Error("animation cannot be null.");let a=this.expandToIndex(t);if(null!=a)for(;null!=a.next;)a=a.next;let n=this.trackEntry(t,e,s,a);if(null==a)this.setCurrent(t,n,!0),this.queue.drain();else if(a.next=n,i<=0){let t=a.animationEnd-a.animationStart;0!=t?(a.loop?i+=t*(1+(a.trackTime/t|0)):i+=Math.max(t,a.trackTime),i-=this.data.getMix(a.animation,e)):i=a.trackTime}return n.delay=i,n}setEmptyAnimation(t,s){let i=this.setAnimationWith(t,e.emptyAnimation,!1);return i.mixDuration=s,i.trackEnd=s,i}addEmptyAnimation(t,s,i){i<=0&&(i-=s);let a=this.addAnimationWith(t,e.emptyAnimation,!1,i);return a.mixDuration=s,a.trackEnd=s,a}setEmptyAnimations(t){let e=this.queue.drainDisabled;this.queue.drainDisabled=!0;for(let e=0,s=this.tracks.length;e0){r[t]=e.HOLD_MIX,l[t]=a;continue t}break}r[t]=e.HOLD}else r[t]=e.FIRST;else r[t]=e.SUBSEQUENT}}hasTimeline(t,e){let s=t.animation.timelines;for(let t=0,i=s.length;t=this.tracks.length?null:this.tracks[t]}addListener(t){if(null==t)throw new Error("listener cannot be null.");this.listeners.push(t)}removeListener(t){let e=this.listeners.indexOf(t);e>=0&&this.listeners.splice(e,1)}clearListeners(){this.listeners.length=0}clearListenerNotifications(){this.queue.clear()}}e.emptyAnimation=new t.Animation("",[],0),e.SUBSEQUENT=0,e.FIRST=1,e.HOLD=2,e.HOLD_MIX=3,t.AnimationState=e;class s{constructor(){this.mixBlend=t.MixBlend.replace,this.timelineMode=new Array,this.timelineHoldMix=new Array,this.timelinesRotation=new Array}reset(){this.next=null,this.mixingFrom=null,this.mixingTo=null,this.animation=null,this.listener=null,this.timelineMode.length=0,this.timelineHoldMix.length=0,this.timelinesRotation.length=0}getAnimationTime(){if(this.loop){let t=this.animationEnd-this.animationStart;return 0==t?this.animationStart:this.trackTime%t+this.animationStart}return Math.min(this.trackTime+this.animationStart,this.animationEnd)}setAnimationLast(t){this.animationLast=t,this.nextAnimationLast=t}isComplete(){return this.trackTime>=this.animationEnd-this.animationStart}resetRotationDirections(){this.timelinesRotation.length=0}}t.TrackEntry=s;class i{constructor(t){this.objects=[],this.drainDisabled=!1,this.animState=t}start(t){this.objects.push(a.start),this.objects.push(t),this.animState.animationsChanged=!0}interrupt(t){this.objects.push(a.interrupt),this.objects.push(t)}end(t){this.objects.push(a.end),this.objects.push(t),this.animState.animationsChanged=!0}dispose(t){this.objects.push(a.dispose),this.objects.push(t)}complete(t){this.objects.push(a.complete),this.objects.push(t)}event(t,e){this.objects.push(a.event),this.objects.push(t),this.objects.push(e)}drain(){if(this.drainDisabled)return;this.drainDisabled=!0;let t=this.objects,e=this.animState.listeners;for(let s=0;s{200==i.status?e(i.responseText):s(i.status,i.responseText)},i.onerror=()=>{s(i.status,i.responseText)},i.send()}static downloadBinary(t,e,s){let i=new XMLHttpRequest;i.open("GET",t,!0),i.responseType="arraybuffer",i.onload=()=>{200==i.status?e(new Uint8Array(i.response)):s(i.status,i.responseText)},i.onerror=()=>{s(i.status,i.responseText)},i.send()}loadText(t,s=null,i=null){t=this.pathPrefix+t,this.toLoad++,e.downloadText(t,e=>{this.assets[t]=e,s&&s(t,e),this.toLoad--,this.loaded++},(e,s)=>{this.errors[t]=`Couldn't load text ${t}: status ${status}, ${s}`,i&&i(t,`Couldn't load text ${t}: status ${status}, ${s}`),this.toLoad--,this.loaded++})}loadTexture(t,e=null,s=null){t=this.pathPrefix+t,this.toLoad++;let i=new Image;i.crossOrigin="anonymous",i.onload=s=>{let a=this.textureLoader(i);this.assets[t]=a,this.toLoad--,this.loaded++,e&&e(t,i)},i.onerror=e=>{this.errors[t]="Couldn't load image "+t,this.toLoad--,this.loaded++,s&&s(t,"Couldn't load image "+t)},i.src=t}loadTextureData(t,e,s=null,i=null){t=this.pathPrefix+t,this.toLoad++;let a=new Image;a.onload=e=>{let i=this.textureLoader(a);this.assets[t]=i,this.toLoad--,this.loaded++,s&&s(t,a)},a.onerror=e=>{this.errors[t]="Couldn't load image "+t,this.toLoad--,this.loaded++,i&&i(t,"Couldn't load image "+t)},a.src=e}loadTextureAtlas(s,i=null,a=null){let n=s.lastIndexOf("/")>=0?s.substring(0,s.lastIndexOf("/")):"";s=this.pathPrefix+s,this.toLoad++,e.downloadText(s,e=>{let r={count:0},l=new Array;try{new t.TextureAtlas(e,e=>{l.push(n+"/"+e);let s=document.createElement("img");return s.width=16,s.height=16,new t.FakeTexture(s)})}catch(t){let e=t;return this.errors[s]=`Couldn't load texture atlas ${s}: ${e.message}`,a&&a(s,`Couldn't load texture atlas ${s}: ${e.message}`),this.toLoad--,void this.loaded++}for(let o of l){let h=!1;this.loadTexture(o,(o,u)=>{if(r.count++,r.count==l.length)if(h)this.errors[s]=`Couldn't load texture atlas page ${o}} of atlas ${s}`,a&&a(s,`Couldn't load texture atlas page ${o} of atlas ${s}`),this.toLoad--,this.loaded++;else try{let a=new t.TextureAtlas(e,t=>this.get(n+"/"+t));this.assets[s]=a,i&&i(s,a),this.toLoad--,this.loaded++}catch(t){let e=t;this.errors[s]=`Couldn't load texture atlas ${s}: ${e.message}`,a&&a(s,`Couldn't load texture atlas ${s}: ${e.message}`),this.toLoad--,this.loaded++}},(t,e)=>{h=!0,r.count++,r.count==l.length&&(this.errors[s]=`Couldn't load texture atlas page ${t}} of atlas ${s}`,a&&a(s,`Couldn't load texture atlas page ${t} of atlas ${s}`),this.toLoad--,this.loaded++)})}},(t,e)=>{this.errors[s]=`Couldn't load texture atlas ${s}: status ${status}, ${e}`,a&&a(s,`Couldn't load texture atlas ${s}: status ${status}, ${e}`),this.toLoad--,this.loaded++})}get(t){return t=this.pathPrefix+t,this.assets[t]}remove(t){t=this.pathPrefix+t;let e=this.assets[t];e.dispose&&e.dispose(),this.assets[t]=null}removeAll(){for(let t in this.assets){let e=this.assets[t];e.dispose&&e.dispose()}this.assets={}}isLoadingComplete(){return 0==this.toLoad}getToLoad(){return this.toLoad}getLoaded(){return this.loaded}dispose(){this.removeAll()}hasErrors(){return Object.keys(this.errors).length>0}getErrors(){return this.errors}}t.AssetManager=e}(spine||(spine={})),function(t){t.AtlasAttachmentLoader=class{constructor(t){this.atlas=t}newRegionAttachment(e,s,i){let a=this.atlas.findRegion(i);if(null==a)throw new Error("Region not found in atlas: "+i+" (region attachment: "+s+")");a.renderObject=a;let n=new t.RegionAttachment(s);return n.setRegion(a),n}newMeshAttachment(e,s,i){let a=this.atlas.findRegion(i);if(null==a)throw new Error("Region not found in atlas: "+i+" (mesh attachment: "+s+")");a.renderObject=a;let n=new t.MeshAttachment(s);return n.region=a,n}newBoundingBoxAttachment(e,s){return new t.BoundingBoxAttachment(s)}newPathAttachment(e,s){return new t.PathAttachment(s)}newPointAttachment(e,s){return new t.PointAttachment(s)}newClippingAttachment(e,s){return new t.ClippingAttachment(s)}}}(spine||(spine={})),function(t){let e;!function(t){t[t.Normal=0]="Normal",t[t.Additive=1]="Additive",t[t.Multiply=2]="Multiply",t[t.Screen=3]="Screen"}(e=t.BlendMode||(t.BlendMode={}))}(spine||(spine={})),function(t){t.Bone=class{constructor(t,e,s){if(this.children=new Array,this.x=0,this.y=0,this.rotation=0,this.scaleX=0,this.scaleY=0,this.shearX=0,this.shearY=0,this.ax=0,this.ay=0,this.arotation=0,this.ascaleX=0,this.ascaleY=0,this.ashearX=0,this.ashearY=0,this.appliedValid=!1,this.a=0,this.b=0,this.worldX=0,this.c=0,this.d=0,this.worldY=0,this.sorted=!1,null==t)throw new Error("data cannot be null.");if(null==e)throw new Error("skeleton cannot be null.");this.data=t,this.skeleton=e,this.parent=s,this.setToSetupPose()}update(){this.updateWorldTransformWith(this.x,this.y,this.rotation,this.scaleX,this.scaleY,this.shearX,this.shearY)}updateWorldTransform(){this.updateWorldTransformWith(this.x,this.y,this.rotation,this.scaleX,this.scaleY,this.shearX,this.shearY)}updateWorldTransformWith(e,s,i,a,n,r,l){this.ax=e,this.ay=s,this.arotation=i,this.ascaleX=a,this.ascaleY=n,this.ashearX=r,this.ashearY=l,this.appliedValid=!0;let o=this.parent;if(null==o){let o=this.skeleton,h=i+90+l,u=o.scaleX,d=o.scaleY;return this.a=t.MathUtils.cosDeg(i+r)*a*u,this.b=t.MathUtils.cosDeg(h)*n*u,this.c=t.MathUtils.sinDeg(i+r)*a*d,this.d=t.MathUtils.sinDeg(h)*n*d,this.worldX=e*u+o.x,void(this.worldY=s*d+o.y)}let h=o.a,u=o.b,d=o.c,c=o.d;switch(this.worldX=h*e+u*s+o.worldX,this.worldY=d*e+c*s+o.worldY,this.data.transformMode){case t.TransformMode.Normal:{let e=i+90+l,s=t.MathUtils.cosDeg(i+r)*a,o=t.MathUtils.cosDeg(e)*n,f=t.MathUtils.sinDeg(i+r)*a,m=t.MathUtils.sinDeg(e)*n;return this.a=h*s+u*f,this.b=h*o+u*m,this.c=d*s+c*f,void(this.d=d*o+c*m)}case t.TransformMode.OnlyTranslation:{let e=i+90+l;this.a=t.MathUtils.cosDeg(i+r)*a,this.b=t.MathUtils.cosDeg(e)*n,this.c=t.MathUtils.sinDeg(i+r)*a,this.d=t.MathUtils.sinDeg(e)*n;break}case t.TransformMode.NoRotationOrReflection:{let e=h*h+d*d,s=0;e>1e-4?(e=Math.abs(h*c-u*d)/e,u=d*e,c=h*e,s=Math.atan2(d,h)*t.MathUtils.radDeg):(h=0,d=0,s=90-Math.atan2(c,u)*t.MathUtils.radDeg);let o=i+r-s,f=i+l-s+90,m=t.MathUtils.cosDeg(o)*a,p=t.MathUtils.cosDeg(f)*n,g=t.MathUtils.sinDeg(o)*a,x=t.MathUtils.sinDeg(f)*n;this.a=h*m-u*g,this.b=h*p-u*x,this.c=d*m+c*g,this.d=d*p+c*x;break}case t.TransformMode.NoScale:case t.TransformMode.NoScaleOrReflection:{let e=t.MathUtils.cosDeg(i),s=t.MathUtils.sinDeg(i),o=(h*e+u*s)/this.skeleton.scaleX,f=(d*e+c*s)/this.skeleton.scaleY,m=Math.sqrt(o*o+f*f);m>1e-5&&(m=1/m),o*=m,f*=m,m=Math.sqrt(o*o+f*f),this.data.transformMode==t.TransformMode.NoScale&&h*c-u*d<0!=(this.skeleton.scaleX<0!=this.skeleton.scaleY<0)&&(m=-m);let p=Math.PI/2+Math.atan2(f,o),g=Math.cos(p)*m,x=Math.sin(p)*m,M=t.MathUtils.cosDeg(r)*a,w=t.MathUtils.cosDeg(90+l)*n,E=t.MathUtils.sinDeg(r)*a,T=t.MathUtils.sinDeg(90+l)*n;this.a=o*M+g*E,this.b=o*w+g*T,this.c=f*M+x*E,this.d=f*w+x*T;break}}this.a*=this.skeleton.scaleX,this.b*=this.skeleton.scaleX,this.c*=this.skeleton.scaleY,this.d*=this.skeleton.scaleY}setToSetupPose(){let t=this.data;this.x=t.x,this.y=t.y,this.rotation=t.rotation,this.scaleX=t.scaleX,this.scaleY=t.scaleY,this.shearX=t.shearX,this.shearY=t.shearY}getWorldRotationX(){return Math.atan2(this.c,this.a)*t.MathUtils.radDeg}getWorldRotationY(){return Math.atan2(this.d,this.b)*t.MathUtils.radDeg}getWorldScaleX(){return Math.sqrt(this.a*this.a+this.c*this.c)}getWorldScaleY(){return Math.sqrt(this.b*this.b+this.d*this.d)}updateAppliedTransform(){this.appliedValid=!0;let e=this.parent;if(null==e)return this.ax=this.worldX,this.ay=this.worldY,this.arotation=Math.atan2(this.c,this.a)*t.MathUtils.radDeg,this.ascaleX=Math.sqrt(this.a*this.a+this.c*this.c),this.ascaleY=Math.sqrt(this.b*this.b+this.d*this.d),this.ashearX=0,void(this.ashearY=Math.atan2(this.a*this.b+this.c*this.d,this.a*this.d-this.b*this.c)*t.MathUtils.radDeg);let s=e.a,i=e.b,a=e.c,n=e.d,r=1/(s*n-i*a),l=this.worldX-e.worldX,o=this.worldY-e.worldY;this.ax=l*n*r-o*i*r,this.ay=o*s*r-l*a*r;let h=r*n,u=r*s,d=r*i,c=r*a,f=h*this.a-d*this.c,m=h*this.b-d*this.d,p=u*this.c-c*this.a,g=u*this.d-c*this.b;if(this.ashearX=0,this.ascaleX=Math.sqrt(f*f+p*p),this.ascaleX>1e-4){let e=f*g-m*p;this.ascaleY=e/this.ascaleX,this.ashearY=Math.atan2(f*m+p*g,e)*t.MathUtils.radDeg,this.arotation=Math.atan2(p,f)*t.MathUtils.radDeg}else this.ascaleX=0,this.ascaleY=Math.sqrt(m*m+g*g),this.ashearY=0,this.arotation=90-Math.atan2(g,m)*t.MathUtils.radDeg}worldToLocal(t){let e=this.a,s=this.b,i=this.c,a=this.d,n=1/(e*a-s*i),r=t.x-this.worldX,l=t.y-this.worldY;return t.x=r*a*n-l*s*n,t.y=l*e*n-r*i*n,t}localToWorld(t){let e=t.x,s=t.y;return t.x=e*this.a+s*this.b+this.worldX,t.y=e*this.c+s*this.d+this.worldY,t}worldToLocalRotation(e){let s=t.MathUtils.sinDeg(e),i=t.MathUtils.cosDeg(e);return Math.atan2(this.a*s-this.c*i,this.d*i-this.b*s)*t.MathUtils.radDeg+this.rotation-this.shearX}localToWorldRotation(e){e-=this.rotation-this.shearX;let s=t.MathUtils.sinDeg(e),i=t.MathUtils.cosDeg(e);return Math.atan2(i*this.c+s*this.d,i*this.a+s*this.b)*t.MathUtils.radDeg}rotateWorld(e){let s=this.a,i=this.b,a=this.c,n=this.d,r=t.MathUtils.cosDeg(e),l=t.MathUtils.sinDeg(e);this.a=r*s-l*a,this.b=r*i-l*n,this.c=l*s+r*a,this.d=l*i+r*n,this.appliedValid=!1}}}(spine||(spine={})),function(t){let e;t.BoneData=class{constructor(t,s,i){if(this.x=0,this.y=0,this.rotation=0,this.scaleX=1,this.scaleY=1,this.shearX=0,this.shearY=0,this.transformMode=e.Normal,t<0)throw new Error("index must be >= 0.");if(null==s)throw new Error("name cannot be null.");this.index=t,this.name=s,this.parent=i}},function(t){t[t.Normal=0]="Normal",t[t.OnlyTranslation=1]="OnlyTranslation",t[t.NoRotationOrReflection=2]="NoRotationOrReflection",t[t.NoScale=3]="NoScale",t[t.NoScaleOrReflection=4]="NoScaleOrReflection"}(e=t.TransformMode||(t.TransformMode={}))}(spine||(spine={})),function(t){t.Event=class{constructor(t,e){if(null==e)throw new Error("data cannot be null.");this.time=t,this.data=e}}}(spine||(spine={})),function(t){t.EventData=class{constructor(t){this.name=t}}}(spine||(spine={})),function(t){t.IkConstraint=class{constructor(t,e){if(this.bendDirection=0,this.compress=!1,this.stretch=!1,this.mix=1,null==t)throw new Error("data cannot be null.");if(null==e)throw new Error("skeleton cannot be null.");this.data=t,this.mix=t.mix,this.bendDirection=t.bendDirection,this.compress=t.compress,this.stretch=t.stretch,this.bones=new Array;for(let s=0;s180?m-=360:m<-180&&(m+=360);let p=e.ascaleX,g=e.ascaleY;if(a||n){let t=e.data.length*p,s=Math.sqrt(c*c+f*f);if(a&&st&&t>1e-4){let e=(s/t-1)*l+1;p*=e,r&&(g*=e)}}e.updateWorldTransformWith(e.ax,e.ay,e.arotation+m*l,p,g,e.ashearX,e.ashearY)}apply2(e,s,i,a,n,r,l){if(0==l)return void s.updateWorldTransform();e.appliedValid||e.updateAppliedTransform(),s.appliedValid||s.updateAppliedTransform();let o=e.ax,h=e.ay,u=e.ascaleX,d=u,c=e.ascaleY,f=s.ascaleX,m=0,p=0,g=0;u<0?(u=-u,m=180,g=-1):(m=0,g=1),c<0&&(c=-c,g=-g),f<0?(f=-f,p=180):p=0;let x=s.ax,M=0,w=0,E=0,T=e.a,b=e.b,A=e.c,y=e.d,R=Math.abs(u-c)<=1e-4;R?(M=s.ay,w=T*x+b*M+e.worldX,E=A*x+y*M+e.worldY):(M=0,w=T*x+e.worldX,E=A*x+e.worldY);let S=e.parent;T=S.a,b=S.b,A=S.c,y=S.d;let I=1/(T*y-b*A),P=i-S.worldX,C=a-S.worldY,V=(P*y-C*b)*I-o,k=(C*T-P*A)*I-h,N=V*V+k*k;P=w-S.worldX,C=E-S.worldY;let v=(P*y-C*b)*I-o,Y=(C*T-P*A)*I-h,X=Math.sqrt(v*v+Y*Y),U=s.data.length*f,L=0,D=0;t:if(R){U*=u;let t=(N-X*X-U*U)/(2*X*U);t<-1?t=-1:t>1&&(t=1,r&&X+U>1e-4&&(d*=(Math.sqrt(N)/(X+U)-1)*l+1)),D=Math.acos(t)*n,T=X+U*t,b=U*Math.sin(D),L=Math.atan2(k*T-V*b,V*T+k*b)}else{T=u*U,b=c*U;let e=T*T,s=b*b,i=Math.atan2(k,V);A=s*X*X+e*N-e*s;let a=-2*s*X,r=s-e;if(y=a*a-4*r*A,y>=0){let t=Math.sqrt(y);a<0&&(t=-t),t=-(a+t)/2;let e=t/r,s=A/t,l=Math.abs(e)=-1&&A<=1&&(A=Math.acos(A),P=T*Math.cos(A)+X,C=b*Math.sin(A),y=P*P+C*C,yp&&(f=A,p=y,m=P,g=C)),N<=(h+p)/2?(L=i-Math.atan2(d*n,o),D=l*n):(L=i-Math.atan2(g*n,m),D=f*n)}let F=Math.atan2(M,x)*g,_=e.arotation;L=(L-F)*t.MathUtils.radDeg+m-_,L>180?L-=360:L<-180&&(L+=360),e.updateWorldTransformWith(o,h,_+L*l,d,e.ascaleY,0,0),_=s.arotation,D=((D+F)*t.MathUtils.radDeg-s.ashearX)*g+p-_,D>180?D-=360:D<-180&&(D+=360),s.updateWorldTransformWith(x,M,_+D*l,s.ascaleX,s.ascaleY,s.ashearX,s.ashearY)}}}(spine||(spine={})),function(t){t.IkConstraintData=class{constructor(t){this.order=0,this.bones=new Array,this.bendDirection=1,this.compress=!1,this.stretch=!1,this.uniform=!1,this.mix=1,this.name=t}}}(spine||(spine={})),function(t){class e{constructor(t,e){if(this.position=0,this.spacing=0,this.rotateMix=0,this.translateMix=0,this.spaces=new Array,this.positions=new Array,this.world=new Array,this.curves=new Array,this.lengths=new Array,this.segments=new Array,null==t)throw new Error("data cannot be null.");if(null==e)throw new Error("skeleton cannot be null.");this.data=t,this.bones=new Array;for(let s=0,i=t.bones.length;s0;if(!(a>0)&&!n)return;let r=this.data,l=r.spacingMode==t.SpacingMode.Percent,o=r.rotateMode,h=o==t.RotateMode.Tangent,u=o==t.RotateMode.ChainScale,d=this.bones.length,c=h?d:d+1,f=this.bones,m=t.Utils.setArraySize(this.spaces,c),p=null,g=this.spacing;if(u||!l){u&&(p=t.Utils.setArraySize(this.lengths,d));let s=r.spacingMode==t.SpacingMode.Length;for(let t=0,i=c-1;t0?t.MathUtils.degRad:-t.MathUtils.degRad}for(let e=0,s=3;et.MathUtils.PI?u-=t.MathUtils.PI2:u<-t.MathUtils.PI&&(u+=t.MathUtils.PI2),u*=i,f=Math.cos(u),p=Math.sin(u),r.a=f*a-p*l,r.b=f*n-p*o,r.c=p*a+f*l,r.d=p*n+f*o}r.appliedValid=!1}}computeWorldPositions(s,i,a,n,r){let l=this.target,o=this.position,h=this.spaces,u=t.Utils.setArraySize(this.positions,3*i+2),d=null,c=s.closed,f=s.worldVerticesLength,m=f/6,p=e.NONE;if(!s.constantSpeed){let g=s.lengths;m-=c?1:2;let x=g[m];if(n&&(o*=x),r)for(let t=1;tx){p!=e.AFTER&&(p=e.AFTER,s.computeWorldVertices(l,f-6,4,d,0,2)),this.addAfterPosition(M-x,d,0,u,n);continue}}for(;;r++){let t=g[r];if(!(M>t)){if(0==r)M/=t;else{let e=g[r-1];M=(M-e)/(t-e)}break}}r!=p&&(p=r,c&&r==m?(s.computeWorldVertices(l,f-4,4,d,0,2),s.computeWorldVertices(l,0,4,d,4,2)):s.computeWorldVertices(l,6*r+2,8,d,0,2)),this.addCurvePosition(M,d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],u,n,a||t>0&&0==i)}return u}c?(f+=2,d=t.Utils.setArraySize(this.world,f),s.computeWorldVertices(l,2,f-4,d,0,2),s.computeWorldVertices(l,0,2,d,f-4,2),d[f-2]=d[0],d[f-1]=d[1]):(m--,f-=4,d=t.Utils.setArraySize(this.world,f),s.computeWorldVertices(l,2,f,d,0,2));let g=t.Utils.setArraySize(this.curves,m),x=0,M=d[0],w=d[1],E=0,T=0,b=0,A=0,y=0,R=0,S=0,I=0,P=0,C=0,V=0,k=0,N=0,v=0;for(let t=0,e=2;tx){this.addAfterPosition(r-x,d,f-4,u,e);continue}}for(;;s++){let t=g[s];if(!(r>t)){if(0==s)r/=t;else{let e=g[s-1];r=(r-e)/(t-e)}break}}if(s!=p){p=s;let t=6*s;for(M=d[t],w=d[t+1],E=d[t+2],T=d[t+3],b=d[t+4],A=d[t+5],y=d[t+6],R=d[t+7],S=.03*(M-2*E+b),I=.03*(w-2*T+A),P=.006*(3*(E-b)-M+y),C=.006*(3*(T-A)-w+R),V=2*S+P,k=2*I+C,N=.3*(E-M)+S+.16666667*P,v=.3*(T-w)+I+.16666667*C,X=Math.sqrt(N*N+v*v),Y[0]=X,t=1;t<8;t++)N+=V,v+=k,V+=P,k+=C,X+=Math.sqrt(N*N+v*v),Y[t]=X;N+=V,v+=k,X+=Math.sqrt(N*N+v*v),Y[8]=X,N+=V+P,v+=k+C,X+=Math.sqrt(N*N+v*v),Y[9]=X,n=0}for(r*=X;;n++){let t=Y[n];if(!(r>t)){if(0==n)r/=t;else{let e=Y[n-1];r=n+(r-e)/(t-e)}break}}this.addCurvePosition(.1*r,M,w,E,T,b,A,y,R,u,e,a||t>0&&0==i)}return u}addBeforePosition(t,e,s,i,a){let n=e[s],r=e[s+1],l=e[s+2]-n,o=e[s+3]-r,h=Math.atan2(o,l);i[a]=n+t*Math.cos(h),i[a+1]=r+t*Math.sin(h),i[a+2]=h}addAfterPosition(t,e,s,i,a){let n=e[s+2],r=e[s+3],l=n-e[s],o=r-e[s+1],h=Math.atan2(o,l);i[a]=n+t*Math.cos(h),i[a+1]=r+t*Math.sin(h),i[a+2]=h}addCurvePosition(t,e,s,i,a,n,r,l,o,h,u,d){if(0==t||isNaN(t))return h[u]=e,h[u+1]=s,void(h[u+2]=Math.atan2(a-s,i-e));let c=t*t,f=c*t,m=1-t,p=m*m,g=p*m,x=m*t,M=3*x,w=m*M,E=M*t,T=e*g+i*w+n*E+l*f,b=s*g+a*w+r*E+o*f;h[u]=T,h[u+1]=b,d&&(h[u+2]=t<.001?Math.atan2(a-s,i-e):Math.atan2(b-(s*p+a*x*2+r*c),T-(e*p+i*x*2+n*c)))}getOrder(){return this.data.order}}e.NONE=-1,e.BEFORE=-2,e.AFTER=-3,e.epsilon=1e-5,t.PathConstraint=e}(spine||(spine={})),function(t){let e,s,i;t.PathConstraintData=class{constructor(t){this.order=0,this.bones=new Array,this.name=t}},function(t){t[t.Fixed=0]="Fixed",t[t.Percent=1]="Percent"}(e=t.PositionMode||(t.PositionMode={})),function(t){t[t.Length=0]="Length",t[t.Fixed=1]="Fixed",t[t.Percent=2]="Percent"}(s=t.SpacingMode||(t.SpacingMode={})),function(t){t[t.Tangent=0]="Tangent",t[t.Chain=1]="Chain",t[t.ChainScale=2]="ChainScale"}(i=t.RotateMode||(t.RotateMode={}))}(spine||(spine={})),function(t){class e{constructor(t){this.toLoad=new Array,this.assets={},this.clientId=t}loaded(){let t=0;for(let e in this.assets)t++;return t}}t.SharedAssetManager=class{constructor(t=""){this.clientAssets={},this.queuedAssets={},this.rawAssets={},this.errors={},this.pathPrefix=t}queueAsset(t,s,i){let a=this.clientAssets[t];return null==a&&(a=new e(t),this.clientAssets[t]=a),null!==s&&(a.textureLoader=s),a.toLoad.push(i),this.queuedAssets[i]!==i&&(this.queuedAssets[i]=i,!0)}loadText(t,e){if(e=this.pathPrefix+e,!this.queueAsset(t,null,e))return;let s=Laya.Laya?Laya.Laya:Laya;s.loader.load([{type:s.Loader.TEXT,url:e}],s.Handler.create(this,t=>{t?this.rawAssets[e]=s.loader.getRes(e):this.errors[e]="Couldn't load text "+e}))}loadJson(t,e){if(e=this.pathPrefix+e,!this.queueAsset(t,null,e))return;let s=Laya.Laya?Laya.Laya:Laya;s.loader.load([{type:s.Loader.JSON,url:e}],s.Handler.create(this,t=>{t?this.rawAssets[e]=s.loader.getRes(e):this.errors[e]="Couldn't load text "+e}))}loadTexture(t,e,s){if(s=this.pathPrefix+s,!this.queueAsset(t,e,s))return;let i=Laya.Laya?Laya.Laya:Laya;i.loader.load([{type:i.Loader.IMAGE,url:s}],i.Handler.create(this,t=>{t?this.rawAssets[s]=i.loader.getRes(s):this.errors[s]="Couldn't load text "+s}))}get(t,e){e=this.pathPrefix+e;let s=this.clientAssets[t];return null==s||s.assets[e]}updateClientAssets(t){for(let e=0;e0}getErrors(){return this.errors}destoryImg(t){window._imgref&&window._imgref[t]&&delete window._imgref[t]}}}(spine||(spine={})),function(t){t.Skeleton=class{constructor(e){if(this._updateCache=new Array,this.updateCacheReset=new Array,this.time=0,this.scaleX=1,this.scaleY=1,this.x=0,this.y=0,null==e)throw new Error("data cannot be null.");this.data=e,this.bones=new Array;for(let s=0;s1){let t=s[s.length-1];this._updateCache.indexOf(t)>-1||this.updateCacheReset.push(t)}this._updateCache.push(t),this.sortReset(i.children),s[s.length-1].sorted=!0}sortPathConstraint(e){let s=e.target,i=s.data.index,a=s.bone;null!=this.skin&&this.sortPathConstraintAttachment(this.skin,i,a),null!=this.data.defaultSkin&&this.data.defaultSkin!=this.skin&&this.sortPathConstraintAttachment(this.data.defaultSkin,i,a);for(let t=0,e=this.data.skins.length;t-1||this.updateCacheReset.push(s)}else for(let t=0;tt.Utils.newFloatArray(16))}update(e,s){if(null==e)throw new Error("skeleton cannot be null.");let i=this.boundingBoxes,a=this.polygons,n=this.polygonPool,r=e.slots,l=r.length;i.length=0,n.freeAll(a),a.length=0;for(let e=0;e=this.minX&&t<=this.maxX&&e>=this.minY&&e<=this.maxY}aabbIntersectsSegment(t,e,s,i){let a=this.minX,n=this.minY,r=this.maxX,l=this.maxY;if(t<=a&&s<=a||e<=n&&i<=n||t>=r&&s>=r||e>=l&&i>=l)return!1;let o=(i-e)/(s-t),h=o*(a-t)+e;if(h>n&&hn&&ha&&ua&&ut.minX&&this.minYt.minY}containsPoint(t,e){let s=this.polygons;for(let i=0,a=s.length;i=s||l=s){let o=i[t];o+(s-a)/(l-a)*(i[n]-o)=u&&x<=r||x>=r&&x<=u)&&(x>=e&&x<=i||x>=i&&x<=e)){let t=(h*p-o*f)/g;if((t>=d&&t<=c||t>=c&&t<=d)&&(t>=s&&t<=a||t>=a&&t<=s))return!0}u=r,d=c}return!1}getPolygon(t){if(null==t)throw new Error("boundingBox cannot be null.");let e=this.boundingBoxes.indexOf(t);return-1==e?null:this.polygons[e]}getWidth(){return this.maxX-this.minX}getHeight(){return this.maxY-this.minY}}}(spine||(spine={})),function(t){class e{constructor(){this.triangulator=new t.Triangulator,this.clippingPolygon=new Array,this.clipOutput=new Array,this.clippedVertices=new Array,this.clippedTriangles=new Array,this.scratch=new Array}clipStart(s,i){if(null!=this.clipAttachment)return 0;this.clipAttachment=i;let a=i.worldVerticesLength,n=t.Utils.setArraySize(this.clippingPolygon,a);i.computeWorldVertices(s,0,a,n,0,2);let r=this.clippingPolygon;e.makeClockwise(r);let l=this.clippingPolygons=this.triangulator.decompose(r,this.triangulator.triangulate(r));for(let t=0,s=l.length;t>1,C=this.clipOutput,V=t.Utils.setArraySize(u,s+P*m);for(let t=0;t=2?(u=l,l=this.scratch):u=this.scratch,u.length=0,u.push(t),u.push(e),u.push(s),u.push(i),u.push(a),u.push(n),u.push(t),u.push(e),l.length=0;let d=r,c=r.length-4;for(let t=0;;t+=2){let e=d[t],s=d[t+1],i=d[t+2],a=d[t+3],n=e-i,r=s-a,f=u,m=u.length-2,p=l.length;for(let t=0;t0;if(n*(u-a)-r*(o-i)>0){if(m){l.push(d),l.push(c);continue}let t=c-u,n=d-o,r=t*(i-e)-n*(a-s);if(Math.abs(r)>1e-6){let h=(n*(s-u)-t*(e-o))/r;l.push(e+(i-e)*h),l.push(s+(a-s)*h)}else l.push(e),l.push(s)}else if(m){let t=c-u,n=d-o,r=t*(i-e)-n*(a-s);if(Math.abs(r)>1e-6){let h=(n*(s-u)-t*(e-o))/r;l.push(e+(i-e)*h),l.push(s+(a-s)*h)}else l.push(e),l.push(s);l.push(d),l.push(c)}h=!0}if(p==l.length)return o.length=0,!0;if(l.push(l[0]),l.push(l[1]),t==c)break;let g=l;(l=u).length=0,u=g}if(o!=l){o.length=0;for(let t=0,e=l.length-2;t>1;t=0;t--)-1==o[t]&&(o[t]=e[--n])}e.setFrame(a++,r.time,o)}n.push(e),r=Math.max(r,e.frames[e.getFrameCount()-1])}if(e.events){let s=new t.EventTimeline(e.events.length),a=0;for(let n=0;n=i.length&&(i.length=t+1),i[t]||(i[t]={}),i[t][e]=s}getAttachment(t,e){let s=this.attachments[t];return s?s[e]:null}attachAll(t,e){let s=0;for(let i=0;i= 0.");if(null==s)throw new Error("name cannot be null.");if(null==i)throw new Error("boneData cannot be null.");this.index=e,this.name=s,this.boneData=i}}}(spine||(spine={})),function(t){class e{constructor(t){this._image=t}getImage(){return this._image}static filterFromString(t){switch(t.toLowerCase()){case"nearest":return s.Nearest;case"linear":return s.Linear;case"mipmap":return s.MipMap;case"mipmapnearestnearest":return s.MipMapNearestNearest;case"mipmaplinearnearest":return s.MipMapLinearNearest;case"mipmapnearestlinear":return s.MipMapNearestLinear;case"mipmaplinearlinear":return s.MipMapLinearLinear;default:throw new Error("Unknown texture filter "+t)}}static wrapFromString(t){switch(t.toLowerCase()){case"mirroredtepeat":return i.MirroredRepeat;case"clamptoedge":return i.ClampToEdge;case"repeat":return i.Repeat;default:throw new Error("Unknown texture wrap "+t)}}}let s,i;t.Texture=e,function(t){t[t.Nearest=9728]="Nearest",t[t.Linear=9729]="Linear",t[t.MipMap=9987]="MipMap",t[t.MipMapNearestNearest=9984]="MipMapNearestNearest",t[t.MipMapLinearNearest=9985]="MipMapLinearNearest",t[t.MipMapNearestLinear=9986]="MipMapNearestLinear",t[t.MipMapLinearLinear=9987]="MipMapLinearLinear"}(s=t.TextureFilter||(t.TextureFilter={})),function(t){t[t.MirroredRepeat=33648]="MirroredRepeat",t[t.ClampToEdge=33071]="ClampToEdge",t[t.Repeat=10497]="Repeat"}(i=t.TextureWrap||(t.TextureWrap={}));t.TextureRegion=class{constructor(){this.u=0,this.v=0,this.u2=0,this.v2=0,this.width=0,this.height=0,this.rotate=!1,this.offsetX=0,this.offsetY=0,this.originalWidth=0,this.originalHeight=0}};t.FakeTexture=class extends e{setFilters(t,e){}setWraps(t,e){}dispose(){}}}(spine||(spine={})),function(t){t.TextureAtlas=class{constructor(t,e){this.pages=new Array,this.regions=new Array,this.load(t,e)}load(a,n){if(null==n)throw new Error("textureLoader cannot be null.");let r=new e(a),l=new Array(4),o=null;for(;;){let e=r.readLine();if(null==e)break;if(e=e.trim(),0==e.length)o=null;else if(o){let t=new i;t.name=e,t.page=o,t.rotate="true"==r.readValue(),r.readTuple(l);let s=parseInt(l[0]),a=parseInt(l[1]);r.readTuple(l);let n=parseInt(l[0]),h=parseInt(l[1]);t.u=s/o.width,t.v=a/o.height,t.rotate?(t.u2=(s+h)/o.width,t.v2=(a+n)/o.height):(t.u2=(s+n)/o.width,t.v2=(a+h)/o.height),t.x=s,t.y=a,t.width=Math.abs(n),t.height=Math.abs(h),4==r.readTuple(l)&&4==r.readTuple(l)&&r.readTuple(l),t.originalWidth=parseInt(l[0]),t.originalHeight=parseInt(l[1]),r.readTuple(l),t.offsetX=parseInt(l[0]),t.offsetY=parseInt(l[1]),t.index=parseInt(r.readValue()),t.texture=o.texture,this.regions.push(t)}else{o=new s,o.name=e,2==r.readTuple(l)&&(o.width=parseInt(l[0]),o.height=parseInt(l[1]),r.readTuple(l)),r.readTuple(l),o.minFilter=t.Texture.filterFromString(l[0]),o.magFilter=t.Texture.filterFromString(l[1]);let i=r.readValue();o.uWrap=t.TextureWrap.ClampToEdge,o.vWrap=t.TextureWrap.ClampToEdge,"x"==i?o.uWrap=t.TextureWrap.Repeat:"y"==i?o.vWrap=t.TextureWrap.Repeat:"xy"==i&&(o.uWrap=o.vWrap=t.TextureWrap.Repeat),o.texture=n(e),o.texture.setFilters(o.minFilter,o.magFilter),o.texture.setWraps(o.uWrap,o.vWrap),o.width=o.texture.getImage().width,o.height=o.texture.getImage().height,this.pages.push(o)}}}findRegion(t){for(let e=0;e=this.lines.length?null:this.lines[this.index++]}readValue(){let t=this.readLine(),e=t.indexOf(":");if(-1==e)throw new Error("Invalid line: "+t);return t.substring(e+1).trim()}readTuple(t){let e=this.readLine(),s=e.indexOf(":");if(-1==s)throw new Error("Invalid line: "+e);let i=0,a=s+1;for(;i<3;i++){let s=e.indexOf(",",a);if(-1==s)break;t[i]=e.substr(a,s-a).trim(),a=s+1}return t[i]=e.substring(a).trim(),i+1}}class s{}t.TextureAtlasPage=s;class i extends t.TextureRegion{}t.TextureAtlasRegion=i}(spine||(spine={})),function(t){t.TransformConstraint=class{constructor(e,s){if(this.rotateMix=0,this.translateMix=0,this.scaleMix=0,this.shearMix=0,this.temp=new t.Vector2,null==e)throw new Error("data cannot be null.");if(null==s)throw new Error("skeleton cannot be null.");this.data=e,this.rotateMix=e.rotateMix,this.translateMix=e.translateMix,this.scaleMix=e.scaleMix,this.shearMix=e.shearMix,this.bones=new Array;for(let t=0;t0?t.MathUtils.degRad:-t.MathUtils.degRad,d=this.data.offsetRotation*u,c=this.data.offsetShearY*u,f=this.bones;for(let u=0,m=f.length;ut.MathUtils.PI?l-=t.MathUtils.PI2:l<-t.MathUtils.PI&&(l+=t.MathUtils.PI2),l*=e;let h=Math.cos(l),u=Math.sin(l);m.a=h*s-u*a,m.b=h*i-u*n,m.c=u*s+h*a,m.d=u*i+h*n,p=!0}if(0!=s){let t=this.temp;n.localToWorld(t.set(this.data.offsetX,this.data.offsetY)),m.worldX+=(t.x-m.worldX)*s,m.worldY+=(t.y-m.worldY)*s,p=!0}if(i>0){let t=Math.sqrt(m.a*m.a+m.c*m.c),e=Math.sqrt(r*r+o*o);t>1e-5&&(t=(t+(e-t+this.data.offsetScaleX)*i)/t),m.a*=t,m.c*=t,t=Math.sqrt(m.b*m.b+m.d*m.d),e=Math.sqrt(l*l+h*h),t>1e-5&&(t=(t+(e-t+this.data.offsetScaleY)*i)/t),m.b*=t,m.d*=t,p=!0}if(a>0){let e=m.b,s=m.d,i=Math.atan2(s,e),n=Math.atan2(h,l)-Math.atan2(o,r)-(i-Math.atan2(m.c,m.a));n>t.MathUtils.PI?n-=t.MathUtils.PI2:n<-t.MathUtils.PI&&(n+=t.MathUtils.PI2),n=i+(n+c)*a;let u=Math.sqrt(e*e+s*s);m.b=Math.cos(n)*u,m.d=Math.sin(n)*u,p=!0}p&&(m.appliedValid=!1)}}applyRelativeWorld(){let e=this.rotateMix,s=this.translateMix,i=this.scaleMix,a=this.shearMix,n=this.target,r=n.a,l=n.b,o=n.c,h=n.d,u=r*h-l*o>0?t.MathUtils.degRad:-t.MathUtils.degRad,d=this.data.offsetRotation*u,c=this.data.offsetShearY*u,f=this.bones;for(let u=0,m=f.length;ut.MathUtils.PI?l-=t.MathUtils.PI2:l<-t.MathUtils.PI&&(l+=t.MathUtils.PI2),l*=e;let h=Math.cos(l),u=Math.sin(l);m.a=h*s-u*a,m.b=h*i-u*n,m.c=u*s+h*a,m.d=u*i+h*n,p=!0}if(0!=s){let t=this.temp;n.localToWorld(t.set(this.data.offsetX,this.data.offsetY)),m.worldX+=t.x*s,m.worldY+=t.y*s,p=!0}if(i>0){let t=(Math.sqrt(r*r+o*o)-1+this.data.offsetScaleX)*i+1;m.a*=t,m.c*=t,t=(Math.sqrt(l*l+h*h)-1+this.data.offsetScaleY)*i+1,m.b*=t,m.d*=t,p=!0}if(a>0){let e=Math.atan2(h,l)-Math.atan2(o,r);e>t.MathUtils.PI?e-=t.MathUtils.PI2:e<-t.MathUtils.PI&&(e+=t.MathUtils.PI2);let s=m.b,i=m.d;e=Math.atan2(i,s)+(e-t.MathUtils.PI/2+c)*a;let n=Math.sqrt(s*s+i*i);m.b=Math.cos(e)*n,m.d=Math.sin(e)*n,p=!0}p&&(m.appliedValid=!1)}}applyAbsoluteLocal(){let t=this.rotateMix,e=this.translateMix,s=this.scaleMix,i=this.shearMix,a=this.target;a.appliedValid||a.updateAppliedTransform();let n=this.bones;for(let r=0,l=n.length;r1e-5&&(d=(d+(a.ascaleX-d+this.data.offsetScaleX)*s)/d),c>1e-5&&(c=(c+(a.ascaleY-c+this.data.offsetScaleY)*s)/c));let f=l.ashearY;if(0!=i){let t=a.ashearY-f+this.data.offsetShearY;t-=360*(16384-(16384.499999999996-t/360|0)),l.shearY+=t*i}l.updateWorldTransformWith(h,u,o,d,c,l.ashearX,f)}}applyRelativeLocal(){let t=this.rotateMix,e=this.translateMix,s=this.scaleMix,i=this.shearMix,a=this.target;a.appliedValid||a.updateAppliedTransform();let n=this.bones;for(let r=0,l=n.length;r1e-5&&(d*=(a.ascaleX-1+this.data.offsetScaleX)*s+1),c>1e-5&&(c*=(a.ascaleY-1+this.data.offsetScaleY)*s+1));let f=l.ashearY;0!=i&&(f+=(a.ashearY+this.data.offsetShearY)*i),l.updateWorldTransformWith(h,u,o,d,c,l.ashearX,f)}}getOrder(){return this.data.order}}}(spine||(spine={})),function(t){t.TransformConstraintData=class{constructor(t){if(this.order=0,this.bones=new Array,this.rotateMix=0,this.translateMix=0,this.scaleMix=0,this.shearMix=0,this.offsetRotation=0,this.offsetX=0,this.offsetY=0,this.offsetScaleX=0,this.offsetScaleY=0,this.offsetShearY=0,this.relative=!1,this.local=!1,null==t)throw new Error("name cannot be null.");this.name=t}}}(spine||(spine={})),function(t){class e{constructor(){this.convexPolygons=new Array,this.convexPolygonsIndices=new Array,this.indicesArray=new Array,this.isConcaveArray=new Array,this.triangles=new Array,this.polygonPool=new t.Pool(()=>new Array),this.polygonIndicesPool=new t.Pool(()=>new Array)}triangulate(t){let s=t,i=t.length>>1,a=this.indicesArray;a.length=0;for(let t=0;t3;){let t=i-1,l=0,o=1;for(;;){t:if(!n[l]){let r=a[t]<<1,h=a[l]<<1,u=a[o]<<1,d=s[r],c=s[r+1],f=s[h],m=s[h+1],p=s[u],g=s[u+1];for(let r=(o+1)%i;r!=t;r=(r+1)%i){if(!n[r])continue;let t=a[r]<<1,i=s[t],l=s[t+1];if(e.positiveArea(p,g,d,c,i,l)&&e.positiveArea(d,c,f,m,i,l)&&e.positiveArea(f,m,p,g,i,l))break t}break}if(0==o){do{if(!n[l])break;l--}while(l>0);break}t=l,l=o,o=(o+1)%i}r.push(a[(i+l-1)%i]),r.push(a[l]),r.push(a[(l+1)%i]),a.splice(l,1),n.splice(l,1),i--;let h=(i+l-1)%i,u=l==i?0:l;n[h]=e.isConcave(h,i,s,a),n[u]=e.isConcave(u,i,s,a)}return 3==i&&(r.push(a[2]),r.push(a[0]),r.push(a[1])),r}decompose(t,s){let i=t,a=this.convexPolygons;this.polygonPool.freeAll(a),a.length=0;let n=this.convexPolygonsIndices;this.polygonIndicesPool.freeAll(n),n.length=0;let r=this.polygonIndicesPool.obtain();r.length=0;let l=this.polygonPool.obtain();l.length=0;let o=-1,h=0;for(let t=0,u=s.length;t0?(a.push(l),n.push(r)):(this.polygonPool.free(l),this.polygonIndicesPool.free(r)),l=this.polygonPool.obtain(),l.length=0,l.push(f),l.push(m),l.push(p),l.push(g),l.push(x),l.push(M),r=this.polygonIndicesPool.obtain(),r.length=0,r.push(u),r.push(d),r.push(c),h=e.winding(f,m,p,g,x,M),o=u)}l.length>0&&(a.push(l),n.push(r));for(let t=0,s=a.length;t=0;t--)l=a[t],0==l.length&&(a.splice(t,1),this.polygonPool.free(l),r=n[t],n.splice(t,1),this.polygonIndicesPool.free(r));return a}static isConcave(t,e,s,i){let a=i[(e+t-1)%e]<<1,n=i[t]<<1,r=i[(t+1)%e]<<1;return!this.positiveArea(s[a],s[a+1],s[n],s[n+1],s[r],s[r+1])}static positiveArea(t,e,s,i,a,n){return t*(n-i)+s*(e-n)+a*(i-e)>=0}static winding(t,e,s,i,a,n){let r=s-t,l=i-e;return a*l-n*r+r*e-t*l>=0?1:-1}}t.Triangulator=e}(spine||(spine={})),function(t){t.IntSet=class{constructor(){this.array=new Array}add(t){let e=this.contains(t);return this.array[0|t]=0|t,!e}contains(t){return null!=this.array[0|t]}remove(t){this.array[0|t]=void 0}clear(){this.array.length=0}};class e{constructor(t=0,e=0,s=0,i=0){this.r=t,this.g=e,this.b=s,this.a=i}set(t,e,s,i){return this.r=t,this.g=e,this.b=s,this.a=i,this.clamp(),this}setFromColor(t){return this.r=t.r,this.g=t.g,this.b=t.b,this.a=t.a,this}setFromString(t){return t="#"==t.charAt(0)?t.substr(1):t,this.r=parseInt(t.substr(0,2),16)/255,this.g=parseInt(t.substr(2,2),16)/255,this.b=parseInt(t.substr(4,2),16)/255,this.a=(8!=t.length?255:parseInt(t.substr(6,2),16))/255,this}add(t,e,s,i){return this.r+=t,this.g+=e,this.b+=s,this.a+=i,this.clamp(),this}clamp(){return this.r<0?this.r=0:this.r>1&&(this.r=1),this.g<0?this.g=0:this.g>1&&(this.g=1),this.b<0?this.b=0:this.b>1&&(this.b=1),this.a<0?this.a=0:this.a>1&&(this.a=1),this}}e.WHITE=new e(1,1,1,1),e.RED=new e(1,0,0,1),e.GREEN=new e(0,1,0,1),e.BLUE=new e(0,0,1,1),e.MAGENTA=new e(1,0,1,1),t.Color=e;class s{static clamp(t,e,s){return ts?s:t}static cosDeg(t){return Math.cos(t*s.degRad)}static sinDeg(t){return Math.sin(t*s.degRad)}static signum(t){return t>0?1:t<0?-1:0}static toInt(t){return t>0?Math.floor(t):Math.ceil(t)}static cbrt(t){let e=Math.pow(Math.abs(t),1/3);return t<0?-e:e}static randomTriangular(t,e){return s.randomTriangularWith(t,e,.5*(t+e))}static randomTriangularWith(t,e,s){let i=Math.random(),a=e-t;return i<=(s-t)/a?t+Math.sqrt(i*a*(s-t)):e-Math.sqrt((1-i)*a*(e-s))}}s.PI=3.1415927,s.PI2=2*s.PI,s.radiansToDegrees=180/s.PI,s.radDeg=s.radiansToDegrees,s.degreesToRadians=s.PI/180,s.degRad=s.degreesToRadians,t.MathUtils=s;class i{apply(t,e,s){return t+(e-t)*this.applyInternal(s)}}t.Interpolation=i;class a extends i{constructor(t){super(),this.power=2,this.power=t}applyInternal(t){return t<=.5?Math.pow(2*t,this.power)/2:Math.pow(2*(t-1),this.power)/(this.power%2==0?-2:2)+1}}t.Pow=a;t.PowOut=class extends a{constructor(t){super(t)}applyInternal(t){return Math.pow(t-1,this.power)*(this.power%2==0?-1:1)+1}};class n{static arrayCopy(t,e,s,i,a){for(let n=e,r=i;n=e?t:n.setArraySize(t,e,s)}static newArray(t,e){let s=new Array(t);for(let i=0;i0?this.items.pop():this.instantiator()}free(t){t.reset&&t.reset(),this.items.push(t)}freeAll(t){for(let e=0;ethis.maxDelta&&(this.delta=this.maxDelta),this.lastTime=t,this.frameCount++,this.frameTime>1&&(this.framesPerSecond=this.frameCount/this.frameTime,this.frameTime=0,this.frameCount=0)}};t.WindowedMean=class{constructor(t=32){this.addedValues=0,this.lastValue=0,this.mean=0,this.dirty=!0,this.values=new Array(t)}hasEnoughData(){return this.addedValues>=this.values.length}addValue(t){this.addedValuesthis.values.length-1&&(this.lastValue=0),this.dirty=!0}getMean(){if(this.hasEnoughData()){if(this.dirty){let t=0;for(let e=0;e{var t;Math.fround||(Math.fround=(t=new Float32Array(1),function(e){return t[0]=e,t[0]}))})(),function(t){class e{constructor(t){if(null==t)throw new Error("name cannot be null.");this.name=t}}t.Attachment=e;class s extends e{constructor(t){super(t),this.id=(65535&s.nextID++)<<11,this.worldVerticesLength=0}computeWorldVertices(t,e,s,i,a,n){s=a+(s>>1)*n;let r=t.bone.skeleton,l=t.attachmentVertices,o=this.vertices,h=this.bones;if(null==h){l.length>0&&(o=l);let r=t.bone,h=r.worldX,u=r.worldY,d=r.a,c=r.b,f=r.c,m=r.d;for(let t=e,r=a;r0&&(e%=this.duration));let o=this.timelines;for(let s=0,h=o.length;s>>1;for(;;){if(t[(n+1)*a]<=e?s=n+1:i=n,s==i)return(s+1)*a;n=s+i>>>1}}static linearSearch(t,e,a){for(let s=0,i=t.length-a;s<=i;s+=a)if(t[s]>e)return s;return-1}}let a,s,i;t.Animation=e,function(t){t[t.setup=0]="setup",t[t.first=1]="first",t[t.replace=2]="replace",t[t.add=3]="add"}(a=t.MixBlend||(t.MixBlend={})),function(t){t[t.mixIn=0]="mixIn",t[t.mixOut=1]="mixOut"}(s=t.MixDirection||(t.MixDirection={})),function(t){t[t.rotate=0]="rotate",t[t.translate=1]="translate",t[t.scale=2]="scale",t[t.shear=3]="shear",t[t.attachment=4]="attachment",t[t.color=5]="color",t[t.deform=6]="deform",t[t.event=7]="event",t[t.drawOrder=8]="drawOrder",t[t.ikConstraint=9]="ikConstraint",t[t.transformConstraint=10]="transformConstraint",t[t.pathConstraintPosition=11]="pathConstraintPosition",t[t.pathConstraintSpacing=12]="pathConstraintSpacing",t[t.pathConstraintMix=13]="pathConstraintMix",t[t.twoColor=14]="twoColor"}(i=t.TimelineType||(t.TimelineType={}));class n{constructor(e){if(e<=0)throw new Error("frameCount must be > 0: "+e);this.curves=t.Utils.newFloatArray((e-1)*n.BEZIER_SIZE)}getFrameCount(){return this.curves.length/n.BEZIER_SIZE+1}setLinear(t){this.curves[t*n.BEZIER_SIZE]=n.LINEAR}setStepped(t){this.curves[t*n.BEZIER_SIZE]=n.STEPPED}getCurveType(t){let e=t*n.BEZIER_SIZE;if(e==this.curves.length)return n.LINEAR;let a=this.curves[e];return a==n.LINEAR?n.LINEAR:a==n.STEPPED?n.STEPPED:n.BEZIER}setCurve(t,e,a,s,i){let r=.03*(2*-e+s),l=.03*(2*-a+i),o=.006*(3*(e-s)+1),h=.006*(3*(a-i)+1),d=2*r+o,u=2*l+h,c=.3*e+r+.16666667*o,f=.3*a+l+.16666667*h,m=t*n.BEZIER_SIZE,g=this.curves;g[m++]=n.BEZIER;let p=c,w=f;for(let t=m+n.BEZIER_SIZE-1;m=a){let e,n;return i==t?(e=0,n=0):(e=s[i-2],n=s[i-1]),n+(s[i+1]-n)*(a-e)/(l-e)}let o=s[i-1];return o+(1-o)*(a-l)/(1-l)}}n.LINEAR=0,n.STEPPED=1,n.BEZIER=2,n.BEZIER_SIZE=19,t.CurveTimeline=n;class r extends n{constructor(e){super(e),this.frames=t.Utils.newFloatArray(e<<1)}getPropertyId(){return(i.rotate<<24)+this.boneIndex}setFrame(t,e,a){t<<=1,this.frames[t]=e,this.frames[t+r.ROTATION]=a}apply(t,s,i,n,l,o,h){let d=this.frames,u=t.bones[this.boneIndex];if(!u.active)return;if(i=d[d.length-r.ENTRIES]){let t=d[d.length+r.PREV_ROTATION];switch(o){case a.setup:u.rotation=u.data.rotation+t*l;break;case a.first:case a.replace:t+=u.data.rotation-u.rotation,t-=360*(16384-(16384.499999999996-t/360|0));case a.add:u.rotation+=t*l}return}let c=e.binarySearch(d,i,r.ENTRIES),f=d[c+r.PREV_ROTATION],m=d[c],g=this.getCurvePercent((c>>1)-1,1-(i-m)/(d[c+r.PREV_TIME]-m)),p=d[c+r.ROTATION]-f;switch(p=f+(p-360*(16384-(16384.499999999996-p/360|0)))*g,o){case a.setup:u.rotation=u.data.rotation+(p-360*(16384-(16384.499999999996-p/360|0)))*l;break;case a.first:case a.replace:p+=u.data.rotation-u.rotation;case a.add:u.rotation+=(p-360*(16384-(16384.499999999996-p/360|0)))*l}}}r.ENTRIES=2,r.PREV_TIME=-2,r.PREV_ROTATION=-1,r.ROTATION=1,t.RotateTimeline=r;class l extends n{constructor(e){super(e),this.frames=t.Utils.newFloatArray(e*l.ENTRIES)}getPropertyId(){return(i.translate<<24)+this.boneIndex}setFrame(t,e,a,s){t*=l.ENTRIES,this.frames[t]=e,this.frames[t+l.X]=a,this.frames[t+l.Y]=s}apply(t,s,i,n,r,o,h){let d=this.frames,u=t.bones[this.boneIndex];if(!u.active)return;if(i=d[d.length-l.ENTRIES])c=d[d.length+l.PREV_X],f=d[d.length+l.PREV_Y];else{let t=e.binarySearch(d,i,l.ENTRIES);c=d[t+l.PREV_X],f=d[t+l.PREV_Y];let a=d[t],s=this.getCurvePercent(t/l.ENTRIES-1,1-(i-a)/(d[t+l.PREV_TIME]-a));c+=(d[t+l.X]-c)*s,f+=(d[t+l.Y]-f)*s}switch(o){case a.setup:u.x=u.data.x+c*r,u.y=u.data.y+f*r;break;case a.first:case a.replace:u.x+=(u.data.x+c-u.x)*r,u.y+=(u.data.y+f-u.y)*r;break;case a.add:u.x+=c*r,u.y+=f*r}}}l.ENTRIES=3,l.PREV_TIME=-3,l.PREV_X=-2,l.PREV_Y=-1,l.X=1,l.Y=2,t.TranslateTimeline=l;class o extends l{constructor(t){super(t)}getPropertyId(){return(i.scale<<24)+this.boneIndex}apply(i,n,r,l,h,d,u){let c=this.frames,f=i.bones[this.boneIndex];if(!f.active)return;if(r=c[c.length-o.ENTRIES])m=c[c.length+o.PREV_X]*f.data.scaleX,g=c[c.length+o.PREV_Y]*f.data.scaleY;else{let t=e.binarySearch(c,r,o.ENTRIES);m=c[t+o.PREV_X],g=c[t+o.PREV_Y];let a=c[t],s=this.getCurvePercent(t/o.ENTRIES-1,1-(r-a)/(c[t+o.PREV_TIME]-a));m=(m+(c[t+o.X]-m)*s)*f.data.scaleX,g=(g+(c[t+o.Y]-g)*s)*f.data.scaleY}if(1==h)d==a.add?(f.scaleX+=m-f.data.scaleX,f.scaleY+=g-f.data.scaleY):(f.scaleX=m,f.scaleY=g);else{let e=0,i=0;if(u==s.mixOut)switch(d){case a.setup:e=f.data.scaleX,i=f.data.scaleY,f.scaleX=e+(Math.abs(m)*t.MathUtils.signum(e)-e)*h,f.scaleY=i+(Math.abs(g)*t.MathUtils.signum(i)-i)*h;break;case a.first:case a.replace:e=f.scaleX,i=f.scaleY,f.scaleX=e+(Math.abs(m)*t.MathUtils.signum(e)-e)*h,f.scaleY=i+(Math.abs(g)*t.MathUtils.signum(i)-i)*h;break;case a.add:e=f.scaleX,i=f.scaleY,f.scaleX=e+(Math.abs(m)*t.MathUtils.signum(e)-f.data.scaleX)*h,f.scaleY=i+(Math.abs(g)*t.MathUtils.signum(i)-f.data.scaleY)*h}else switch(d){case a.setup:e=Math.abs(f.data.scaleX)*t.MathUtils.signum(m),i=Math.abs(f.data.scaleY)*t.MathUtils.signum(g),f.scaleX=e+(m-e)*h,f.scaleY=i+(g-i)*h;break;case a.first:case a.replace:e=Math.abs(f.scaleX)*t.MathUtils.signum(m),i=Math.abs(f.scaleY)*t.MathUtils.signum(g),f.scaleX=e+(m-e)*h,f.scaleY=i+(g-i)*h;break;case a.add:e=t.MathUtils.signum(m),i=t.MathUtils.signum(g),f.scaleX=Math.abs(f.scaleX)*e+(m-Math.abs(f.data.scaleX)*e)*h,f.scaleY=Math.abs(f.scaleY)*i+(g-Math.abs(f.data.scaleY)*i)*h}}}}t.ScaleTimeline=o;class h extends l{constructor(t){super(t)}getPropertyId(){return(i.shear<<24)+this.boneIndex}apply(t,s,i,n,r,l,o){let d=this.frames,u=t.bones[this.boneIndex];if(!u.active)return;if(i=d[d.length-h.ENTRIES])c=d[d.length+h.PREV_X],f=d[d.length+h.PREV_Y];else{let t=e.binarySearch(d,i,h.ENTRIES);c=d[t+h.PREV_X],f=d[t+h.PREV_Y];let a=d[t],s=this.getCurvePercent(t/h.ENTRIES-1,1-(i-a)/(d[t+h.PREV_TIME]-a));c+=(d[t+h.X]-c)*s,f+=(d[t+h.Y]-f)*s}switch(l){case a.setup:u.shearX=u.data.shearX+c*r,u.shearY=u.data.shearY+f*r;break;case a.first:case a.replace:u.shearX+=(u.data.shearX+c-u.shearX)*r,u.shearY+=(u.data.shearY+f-u.shearY)*r;break;case a.add:u.shearX+=c*r,u.shearY+=f*r}}}t.ShearTimeline=h;class d extends n{constructor(e){super(e),this.frames=t.Utils.newFloatArray(e*d.ENTRIES)}getPropertyId(){return(i.color<<24)+this.slotIndex}setFrame(t,e,a,s,i,n){t*=d.ENTRIES,this.frames[t]=e,this.frames[t+d.R]=a,this.frames[t+d.G]=s,this.frames[t+d.B]=i,this.frames[t+d.A]=n}apply(t,s,i,n,r,l,o){let h=t.slots[this.slotIndex];if(!h.bone.active)return;let u=this.frames;if(i=u[u.length-d.ENTRIES]){let t=u.length;c=u[t+d.PREV_R],f=u[t+d.PREV_G],m=u[t+d.PREV_B],g=u[t+d.PREV_A]}else{let t=e.binarySearch(u,i,d.ENTRIES);c=u[t+d.PREV_R],f=u[t+d.PREV_G],m=u[t+d.PREV_B],g=u[t+d.PREV_A];let a=u[t],s=this.getCurvePercent(t/d.ENTRIES-1,1-(i-a)/(u[t+d.PREV_TIME]-a));c+=(u[t+d.R]-c)*s,f+=(u[t+d.G]-f)*s,m+=(u[t+d.B]-m)*s,g+=(u[t+d.A]-g)*s}if(1==r)h.color.set(c,f,m,g);else{let t=h.color;l==a.setup&&t.setFromColor(h.data.color),t.add((c-t.r)*r,(f-t.g)*r,(m-t.b)*r,(g-t.a)*r)}}}d.ENTRIES=5,d.PREV_TIME=-5,d.PREV_R=-4,d.PREV_G=-3,d.PREV_B=-2,d.PREV_A=-1,d.R=1,d.G=2,d.B=3,d.A=4,t.ColorTimeline=d;class u extends n{constructor(e){super(e),this.frames=t.Utils.newFloatArray(e*u.ENTRIES)}getPropertyId(){return(i.twoColor<<24)+this.slotIndex}setFrame(t,e,a,s,i,n,r,l,o){t*=u.ENTRIES,this.frames[t]=e,this.frames[t+u.R]=a,this.frames[t+u.G]=s,this.frames[t+u.B]=i,this.frames[t+u.A]=n,this.frames[t+u.R2]=r,this.frames[t+u.G2]=l,this.frames[t+u.B2]=o}apply(t,s,i,n,r,l,o){let h=t.slots[this.slotIndex];if(!h.bone.active)return;let d=this.frames;if(i=d[d.length-u.ENTRIES]){let t=d.length;c=d[t+u.PREV_R],f=d[t+u.PREV_G],m=d[t+u.PREV_B],g=d[t+u.PREV_A],p=d[t+u.PREV_R2],w=d[t+u.PREV_G2],x=d[t+u.PREV_B2]}else{let t=e.binarySearch(d,i,u.ENTRIES);c=d[t+u.PREV_R],f=d[t+u.PREV_G],m=d[t+u.PREV_B],g=d[t+u.PREV_A],p=d[t+u.PREV_R2],w=d[t+u.PREV_G2],x=d[t+u.PREV_B2];let a=d[t],s=this.getCurvePercent(t/u.ENTRIES-1,1-(i-a)/(d[t+u.PREV_TIME]-a));c+=(d[t+u.R]-c)*s,f+=(d[t+u.G]-f)*s,m+=(d[t+u.B]-m)*s,g+=(d[t+u.A]-g)*s,p+=(d[t+u.R2]-p)*s,w+=(d[t+u.G2]-w)*s,x+=(d[t+u.B2]-x)*s}if(1==r)h.color.set(c,f,m,g),h.darkColor.set(p,w,x,1);else{let t=h.color,e=h.darkColor;l==a.setup&&(t.setFromColor(h.data.color),e.setFromColor(h.data.darkColor)),t.add((c-t.r)*r,(f-t.g)*r,(m-t.b)*r,(g-t.a)*r),e.add((p-e.r)*r,(w-e.g)*r,(x-e.b)*r,0)}}}u.ENTRIES=8,u.PREV_TIME=-8,u.PREV_R=-7,u.PREV_G=-6,u.PREV_B=-5,u.PREV_A=-4,u.PREV_R2=-3,u.PREV_G2=-2,u.PREV_B2=-1,u.R=1,u.G=2,u.B=3,u.A=4,u.R2=5,u.G2=6,u.B2=7,t.TwoColorTimeline=u;t.AttachmentTimeline=class{constructor(e){this.frames=t.Utils.newFloatArray(e),this.attachmentNames=new Array(e)}getPropertyId(){return(i.attachment<<24)+this.slotIndex}getFrameCount(){return this.frames.length}setFrame(t,e,a){this.frames[t]=e,this.attachmentNames[t]=a}apply(t,i,n,r,l,o,h){let d=t.slots[this.slotIndex];if(!d.bone.active)return;if(h==s.mixOut)return void(o==a.setup&&this.setAttachment(t,d,d.data.attachmentName));let u=this.frames;if(n=u[u.length-1]?u.length-1:e.binarySearch(u,n,1)-1;let f=this.attachmentNames[c];t.slots[this.slotIndex].setAttachment(null==f?null:t.getAttachment(this.slotIndex,f))}setAttachment(t,e,a){e.attachment=null==a?null:t.getAttachment(this.slotIndex,a)}};let c=null;t.DeformTimeline=class extends n{constructor(e){super(e),this.frames=t.Utils.newFloatArray(e),this.frameVertices=new Array(e),null==c&&(c=t.Utils.newFloatArray(64))}getPropertyId(){return(i.deform<<27)+ +this.attachment.id+this.slotIndex}setFrame(t,e,a){this.frames[t]=e,this.frameVertices[t]=a}apply(s,i,n,r,l,o,h){let d=s.slots[this.slotIndex];if(!d.bone.active)return;let u=d.getAttachment();if(!(u instanceof t.VertexAttachment)||u.deformAttachment!=this.attachment)return;let c=d.deform;0==c.length&&(o=a.setup);let f=this.frameVertices,m=f[0].length,g=this.frames;if(n=g[g.length-1]){let e=f[g.length-1];if(1==l)if(o==a.add){let t=u;if(null==t.bones){let a=t.vertices;for(let t=0;ts)this.apply(t,a,Number.MAX_VALUE,i,n,r,l),a=-1;else if(a>=o[h-1])return;if(s0&&o[d-1]==t;)d--}for(;d=o[d];d++)i.push(this.events[d])}};t.DrawOrderTimeline=class{constructor(e){this.frames=t.Utils.newFloatArray(e),this.drawOrders=new Array(e)}getPropertyId(){return i.drawOrder<<24}getFrameCount(){return this.frames.length}setFrame(t,e,a){this.frames[t]=e,this.drawOrders[t]=a}apply(i,n,r,l,o,h,d){let u=i.drawOrder,c=i.slots;if(d==s.mixOut)return void(h==a.setup&&t.Utils.arrayCopy(i.slots,0,i.drawOrder,0,i.slots.length));let f=this.frames;if(r=f[f.length-1]?f.length-1:e.binarySearch(f,r)-1;let g=this.drawOrders[m];if(null==g)t.Utils.arrayCopy(c,0,u,0,c.length);else for(let t=0,e=g.length;t=d[d.length-f.ENTRIES])return void(o==a.setup?(u.mix=u.data.mix+(d[d.length+f.PREV_MIX]-u.data.mix)*l,u.softness=u.data.softness+(d[d.length+f.PREV_SOFTNESS]-u.data.softness)*l,h==s.mixOut?(u.bendDirection=u.data.bendDirection,u.compress=u.data.compress,u.stretch=u.data.stretch):(u.bendDirection=d[d.length+f.PREV_BEND_DIRECTION],u.compress=0!=d[d.length+f.PREV_COMPRESS],u.stretch=0!=d[d.length+f.PREV_STRETCH])):(u.mix+=(d[d.length+f.PREV_MIX]-u.mix)*l,u.softness+=(d[d.length+f.PREV_SOFTNESS]-u.softness)*l,h==s.mixIn&&(u.bendDirection=d[d.length+f.PREV_BEND_DIRECTION],u.compress=0!=d[d.length+f.PREV_COMPRESS],u.stretch=0!=d[d.length+f.PREV_STRETCH])));let c=e.binarySearch(d,n,f.ENTRIES),m=d[c+f.PREV_MIX],g=d[c+f.PREV_SOFTNESS],p=d[c],w=this.getCurvePercent(c/f.ENTRIES-1,1-(n-p)/(d[c+f.PREV_TIME]-p));o==a.setup?(u.mix=u.data.mix+(m+(d[c+f.MIX]-m)*w-u.data.mix)*l,u.softness=u.data.softness+(g+(d[c+f.SOFTNESS]-g)*w-u.data.softness)*l,h==s.mixOut?(u.bendDirection=u.data.bendDirection,u.compress=u.data.compress,u.stretch=u.data.stretch):(u.bendDirection=d[c+f.PREV_BEND_DIRECTION],u.compress=0!=d[c+f.PREV_COMPRESS],u.stretch=0!=d[c+f.PREV_STRETCH])):(u.mix+=(m+(d[c+f.MIX]-m)*w-u.mix)*l,u.softness+=(g+(d[c+f.SOFTNESS]-g)*w-u.softness)*l,h==s.mixIn&&(u.bendDirection=d[c+f.PREV_BEND_DIRECTION],u.compress=0!=d[c+f.PREV_COMPRESS],u.stretch=0!=d[c+f.PREV_STRETCH]))}}f.ENTRIES=6,f.PREV_TIME=-6,f.PREV_MIX=-5,f.PREV_SOFTNESS=-4,f.PREV_BEND_DIRECTION=-3,f.PREV_COMPRESS=-2,f.PREV_STRETCH=-1,f.MIX=1,f.SOFTNESS=2,f.BEND_DIRECTION=3,f.COMPRESS=4,f.STRETCH=5,t.IkConstraintTimeline=f;class m extends n{constructor(e){super(e),this.frames=t.Utils.newFloatArray(e*m.ENTRIES)}getPropertyId(){return(i.transformConstraint<<24)+this.transformConstraintIndex}setFrame(t,e,a,s,i,n){t*=m.ENTRIES,this.frames[t]=e,this.frames[t+m.ROTATE]=a,this.frames[t+m.TRANSLATE]=s,this.frames[t+m.SCALE]=i,this.frames[t+m.SHEAR]=n}apply(t,s,i,n,r,l,o){let h=this.frames,d=t.transformConstraints[this.transformConstraintIndex];if(!d.active)return;if(i=h[h.length-m.ENTRIES]){let t=h.length;u=h[t+m.PREV_ROTATE],c=h[t+m.PREV_TRANSLATE],f=h[t+m.PREV_SCALE],g=h[t+m.PREV_SHEAR]}else{let t=e.binarySearch(h,i,m.ENTRIES);u=h[t+m.PREV_ROTATE],c=h[t+m.PREV_TRANSLATE],f=h[t+m.PREV_SCALE],g=h[t+m.PREV_SHEAR];let a=h[t],s=this.getCurvePercent(t/m.ENTRIES-1,1-(i-a)/(h[t+m.PREV_TIME]-a));u+=(h[t+m.ROTATE]-u)*s,c+=(h[t+m.TRANSLATE]-c)*s,f+=(h[t+m.SCALE]-f)*s,g+=(h[t+m.SHEAR]-g)*s}if(l==a.setup){let t=d.data;d.rotateMix=t.rotateMix+(u-t.rotateMix)*r,d.translateMix=t.translateMix+(c-t.translateMix)*r,d.scaleMix=t.scaleMix+(f-t.scaleMix)*r,d.shearMix=t.shearMix+(g-t.shearMix)*r}else d.rotateMix+=(u-d.rotateMix)*r,d.translateMix+=(c-d.translateMix)*r,d.scaleMix+=(f-d.scaleMix)*r,d.shearMix+=(g-d.shearMix)*r}}m.ENTRIES=5,m.PREV_TIME=-5,m.PREV_ROTATE=-4,m.PREV_TRANSLATE=-3,m.PREV_SCALE=-2,m.PREV_SHEAR=-1,m.ROTATE=1,m.TRANSLATE=2,m.SCALE=3,m.SHEAR=4,t.TransformConstraintTimeline=m;class g extends n{constructor(e){super(e),this.frames=t.Utils.newFloatArray(e*g.ENTRIES)}getPropertyId(){return(i.pathConstraintPosition<<24)+this.pathConstraintIndex}setFrame(t,e,a){t*=g.ENTRIES,this.frames[t]=e,this.frames[t+g.VALUE]=a}apply(t,s,i,n,r,l,o){let h=this.frames,d=t.pathConstraints[this.pathConstraintIndex];if(!d.active)return;if(i=h[h.length-g.ENTRIES])u=h[h.length+g.PREV_VALUE];else{let t=e.binarySearch(h,i,g.ENTRIES);u=h[t+g.PREV_VALUE];let a=h[t],s=this.getCurvePercent(t/g.ENTRIES-1,1-(i-a)/(h[t+g.PREV_TIME]-a));u+=(h[t+g.VALUE]-u)*s}l==a.setup?d.position=d.data.position+(u-d.data.position)*r:d.position+=(u-d.position)*r}}g.ENTRIES=2,g.PREV_TIME=-2,g.PREV_VALUE=-1,g.VALUE=1,t.PathConstraintPositionTimeline=g;class p extends g{constructor(t){super(t)}getPropertyId(){return(i.pathConstraintSpacing<<24)+this.pathConstraintIndex}apply(t,s,i,n,r,l,o){let h=this.frames,d=t.pathConstraints[this.pathConstraintIndex];if(!d.active)return;if(i=h[h.length-p.ENTRIES])u=h[h.length+p.PREV_VALUE];else{let t=e.binarySearch(h,i,p.ENTRIES);u=h[t+p.PREV_VALUE];let a=h[t],s=this.getCurvePercent(t/p.ENTRIES-1,1-(i-a)/(h[t+p.PREV_TIME]-a));u+=(h[t+p.VALUE]-u)*s}l==a.setup?d.spacing=d.data.spacing+(u-d.data.spacing)*r:d.spacing+=(u-d.spacing)*r}}t.PathConstraintSpacingTimeline=p;class w extends n{constructor(e){super(e),this.frames=t.Utils.newFloatArray(e*w.ENTRIES)}getPropertyId(){return(i.pathConstraintMix<<24)+this.pathConstraintIndex}setFrame(t,e,a,s){t*=w.ENTRIES,this.frames[t]=e,this.frames[t+w.ROTATE]=a,this.frames[t+w.TRANSLATE]=s}apply(t,s,i,n,r,l,o){let h=this.frames,d=t.pathConstraints[this.pathConstraintIndex];if(!d.active)return;if(i=h[h.length-w.ENTRIES])u=h[h.length+w.PREV_ROTATE],c=h[h.length+w.PREV_TRANSLATE];else{let t=e.binarySearch(h,i,w.ENTRIES);u=h[t+w.PREV_ROTATE],c=h[t+w.PREV_TRANSLATE];let a=h[t],s=this.getCurvePercent(t/w.ENTRIES-1,1-(i-a)/(h[t+w.PREV_TIME]-a));u+=(h[t+w.ROTATE]-u)*s,c+=(h[t+w.TRANSLATE]-c)*s}l==a.setup?(d.rotateMix=d.data.rotateMix+(u-d.data.rotateMix)*r,d.translateMix=d.data.translateMix+(c-d.data.translateMix)*r):(d.rotateMix+=(u-d.rotateMix)*r,d.translateMix+=(c-d.translateMix)*r)}}w.ENTRIES=3,w.PREV_TIME=-3,w.PREV_ROTATE=-2,w.PREV_TRANSLATE=-1,w.ROTATE=1,w.TRANSLATE=2,t.PathConstraintMixTimeline=w}(spine||(spine={})),function(t){class e{constructor(e){this.tracks=new Array,this.timeScale=1,this.unkeyedState=0,this.events=new Array,this.listeners=new Array,this.queue=new s(this),this.propertyIDs=new t.IntSet,this.animationsChanged=!1,this.trackEntryPool=new t.Pool(()=>new a),this.data=e}update(t){t*=this.timeScale;let e=this.tracks;for(let a=0,s=e.length;a0){if(s.delay-=i,s.delay>0)continue;i=-s.delay,s.delay=0}let n=s.next;if(null!=n){let e=s.trackLast-n.delay;if(e>=0){for(n.delay=0,n.trackTime+=0==s.timeScale?0:(e/s.timeScale+t)*n.timeScale,s.trackTime+=i,this.setCurrent(a,n,!0);null!=n.mixingFrom;)n.mixTime+=t,n=n.mixingFrom;continue}}else if(s.trackLast>=s.trackEnd&&null==s.mixingFrom){e[a]=null,this.queue.end(s),this.disposeNext(s);continue}if(null!=s.mixingFrom&&this.updateMixingFrom(s,t)){let t=s.mixingFrom;for(s.mixingFrom=null,null!=t&&(t.mixingTo=null);null!=t;)this.queue.end(t),t=t.mixingFrom}s.trackTime+=i}this.queue.drain()}updateMixingFrom(t,e){let a=t.mixingFrom;if(null==a)return!0;let s=this.updateMixingFrom(a,e);return a.animationLast=a.nextAnimationLast,a.trackLast=a.nextTrackLast,t.mixTime>0&&t.mixTime>=t.mixDuration?(0!=a.totalAlpha&&0!=t.mixDuration||(t.mixingFrom=a.mixingFrom,null!=a.mixingFrom&&(a.mixingFrom.mixingTo=t),t.interruptAlpha=a.interruptAlpha,this.queue.end(a)),s):(a.trackTime+=e*a.timeScale,t.mixTime+=e,!1)}apply(a){if(null==a)throw new Error("skeleton cannot be null.");this.animationsChanged&&this._animationsChanged();let s=this.events,i=this.tracks,n=!1;for(let l=0,o=i.length;l0)continue;n=!0;let h=0==l?t.MixBlend.first:o.mixBlend,d=o.alpha;null!=o.mixingFrom?d*=this.applyMixingFrom(o,a,h):o.trackTime>=o.trackEnd&&null==o.next&&(d=0);let u=o.animationLast,c=o.getAnimationTime(),f=o.animation.timelines.length,m=o.animation.timelines;if(0==l&&1==d||h==t.MixBlend.add)for(let e=0;e1&&(r=1),i!=t.MixBlend.first&&(i=n.mixBlend));let l=r0&&this.queueEvents(n,u),this.events.length=0,n.nextAnimationLast=u,n.nextTrackLast=n.trackTime,r}applyAttachmentTimeline(a,s,i,n,r){var l=s.slots[a.slotIndex];if(l.bone.active){var o,h=a.frames;if(i=h[h.length-1]?h.length-1:t.Animation.binarySearch(h,i)-1,this.setAttachment(s,l,a.attachmentNames[o],r);l.attachmentState<=this.unkeyedState&&(l.attachmentState=this.unkeyedState+e.SETUP)}}setAttachment(t,a,s,i){a.attachment=null==s?null:t.getAttachment(a.data.index,s),i&&(a.attachmentState=this.unkeyedState+e.CURRENT)}applyRotateTimeline(e,a,s,i,n,r,l,o){if(o&&(r[l]=0),1==i)return void e.apply(a,0,s,null,1,n,t.MixDirection.mixIn);let h=e,d=h.frames,u=a.bones[h.boneIndex];if(!u.active)return;let c=0,f=0;if(s=d[d.length-t.RotateTimeline.ENTRIES])f=u.data.rotation+d[d.length+t.RotateTimeline.PREV_ROTATION];else{let e=t.Animation.binarySearch(d,s,t.RotateTimeline.ENTRIES),a=d[e+t.RotateTimeline.PREV_ROTATION],i=d[e],n=h.getCurvePercent((e>>1)-1,1-(s-i)/(d[e+t.RotateTimeline.PREV_TIME]-i));f=d[e+t.RotateTimeline.ROTATION]-a,f-=360*(16384-(16384.499999999996-f/360|0)),f=a+f*n+u.data.rotation,f-=360*(16384-(16384.499999999996-f/360|0))}let m=0,g=f-c;if(g-=360*(16384-(16384.499999999996-g/360|0)),0==g)m=r[l];else{let e=0,a=0;o?(e=0,a=g):(e=r[l],a=r[l+1]);let s=g>0,i=e>=0;t.MathUtils.signum(a)!=t.MathUtils.signum(g)&&Math.abs(a)<=90&&(Math.abs(e)>180&&(e+=360*t.MathUtils.signum(e)),i=s),m=g+e-e%360,i!=s&&(m+=360*t.MathUtils.signum(e)),r[l]=m}r[l+1]=g,c+=m*i,u.rotation=c-360*(16384-(16384.499999999996-c/360|0))}queueEvents(t,e){let a=t.animationStart,s=t.animationEnd,i=s-a,n=t.trackLast%i,r=this.events,l=0,o=r.length;for(;ls||this.queue.event(t,e)}let h=!1;for(h=t.loop?0==i||n>t.trackTime%i:e>=s&&t.animationLast=this.tracks.length)return;let e=this.tracks[t];if(null==e)return;this.queue.end(e),this.disposeNext(e);let a=e;for(;;){let t=a.mixingFrom;if(null==t)break;this.queue.end(t),a.mixingFrom=null,a.mixingTo=null,a=t}this.tracks[e.trackIndex]=null,this.queue.drain()}setCurrent(t,e,a){let s=this.expandToIndex(t);this.tracks[t]=e,null!=s&&(a&&this.queue.interrupt(s),e.mixingFrom=s,s.mixingTo=e,e.mixTime=0,null!=s.mixingFrom&&s.mixDuration>0&&(e.interruptAlpha*=Math.min(1,s.mixTime/s.mixDuration)),s.timelinesRotation.length=0),this.queue.start(e)}setAnimation(t,e,a){let s=this.data.skeletonData.findAnimation(e);if(null==s)throw new Error("Animation not found: "+e);return this.setAnimationWith(t,s,a)}setAnimationWith(t,e,a){if(null==e)throw new Error("animation cannot be null.");let s=!0,i=this.expandToIndex(t);null!=i&&(-1==i.nextTrackLast?(this.tracks[t]=i.mixingFrom,this.queue.interrupt(i),this.queue.end(i),this.disposeNext(i),i=i.mixingFrom,s=!1):this.disposeNext(i));let n=this.trackEntry(t,e,a,i);return this.setCurrent(t,n,s),this.queue.drain(),n}addAnimation(t,e,a,s){let i=this.data.skeletonData.findAnimation(e);if(null==i)throw new Error("Animation not found: "+e);return this.addAnimationWith(t,i,a,s)}addAnimationWith(t,e,a,s){if(null==e)throw new Error("animation cannot be null.");let i=this.expandToIndex(t);if(null!=i)for(;null!=i.next;)i=i.next;let n=this.trackEntry(t,e,a,i);if(null==i)this.setCurrent(t,n,!0),this.queue.drain();else if(i.next=n,s<=0){let t=i.animationEnd-i.animationStart;0!=t?(i.loop?s+=t*(1+(i.trackTime/t|0)):s+=Math.max(t,i.trackTime),s-=this.data.getMix(i.animation,e)):s=i.trackTime}return n.delay=s,n}setEmptyAnimation(t,a){let s=this.setAnimationWith(t,e.emptyAnimation,!1);return s.mixDuration=a,s.trackEnd=a,s}addEmptyAnimation(t,a,s){s<=0&&(s-=a);let i=this.addAnimationWith(t,e.emptyAnimation,!1,s);return i.mixDuration=a,i.trackEnd=a,i}setEmptyAnimations(t){let e=this.queue.drainDisabled;this.queue.drainDisabled=!0;for(let e=0,a=this.tracks.length;e0){r[h]=e.HOLD_MIX,l[h]=t;continue t}break}r[h]=e.HOLD}else r[h]=e.SUBSEQUENT}}getCurrent(t){return t>=this.tracks.length?null:this.tracks[t]}addListener(t){if(null==t)throw new Error("listener cannot be null.");this.listeners.push(t)}removeListener(t){let e=this.listeners.indexOf(t);e>=0&&this.listeners.splice(e,1)}clearListeners(){this.listeners.length=0}clearListenerNotifications(){this.queue.clear()}}e.emptyAnimation=new t.Animation("",[],0),e.SUBSEQUENT=0,e.FIRST=1,e.HOLD=2,e.HOLD_MIX=3,e.SETUP=1,e.CURRENT=2,t.AnimationState=e;class a{constructor(){this.mixBlend=t.MixBlend.replace,this.timelineMode=new Array,this.timelineHoldMix=new Array,this.timelinesRotation=new Array}reset(){this.next=null,this.mixingFrom=null,this.mixingTo=null,this.animation=null,this.listener=null,this.timelineMode.length=0,this.timelineHoldMix.length=0,this.timelinesRotation.length=0}getAnimationTime(){if(this.loop){let t=this.animationEnd-this.animationStart;return 0==t?this.animationStart:this.trackTime%t+this.animationStart}return Math.min(this.trackTime+this.animationStart,this.animationEnd)}setAnimationLast(t){this.animationLast=t,this.nextAnimationLast=t}isComplete(){return this.trackTime>=this.animationEnd-this.animationStart}resetRotationDirections(){this.timelinesRotation.length=0}}t.TrackEntry=a;class s{constructor(t){this.objects=[],this.drainDisabled=!1,this.animState=t}start(t){this.objects.push(i.start),this.objects.push(t),this.animState.animationsChanged=!0}interrupt(t){this.objects.push(i.interrupt),this.objects.push(t)}end(t){this.objects.push(i.end),this.objects.push(t),this.animState.animationsChanged=!0}dispose(t){this.objects.push(i.dispose),this.objects.push(t)}complete(t){this.objects.push(i.complete),this.objects.push(t)}event(t,e){this.objects.push(i.event),this.objects.push(t),this.objects.push(e)}drain(){if(this.drainDisabled)return;this.drainDisabled=!0;let t=this.objects,e=this.animState.listeners;for(let a=0;a{i?e(s.loader.getRes(t)):a("download text error: ",t)}))}downloadBinary(t,e,a){let s=Laya.Laya?Laya.Laya:Laya;s.loader.load([{type:s.Loader.BUFFER,url:t}],s.Handler.create(this,i=>{i?e(new Uint8Array(s.loader.getRes(t))):a("download binary error: ",t)}))}setRawDataURI(t,e){this.rawDataUris[this.pathPrefix+t]=e}loadBinary(t,e=null,a=null){t=this.pathPrefix+t,this.toLoad++,this.downloadBinary(t,a=>{this.assets[t]=a,e&&e(t,a),this.toLoad--,this.loaded++},(e,s)=>{this.errors[t]=`Couldn't load binary ${t}: status ${e}, ${s}`,a&&a(t,`Couldn't load binary ${t}: status ${e}, ${s}`),this.toLoad--,this.loaded++})}loadText(t,e=null,a=null){t=this.pathPrefix+t,this.toLoad++,this.downloadText(t,a=>{this.assets[t]=a,e&&e(t,a),this.toLoad--,this.loaded++},(e,s)=>{this.errors[t]=`Couldn't load text ${t}: status ${status}, ${s}`,a&&a(t,`Couldn't load text ${t}: status ${status}, ${s}`),this.toLoad--,this.loaded++})}loadTexture(t,e=null,a=null){t=this.pathPrefix+t;this.toLoad++;let s=Laya.Laya?Laya.Laya:Laya;s.loader.load([{type:s.Loader.IMAGE,url:t}],s.Handler.create(this,i=>{if(i){let a=this.textureLoader(s.loader.getRes(t));this.assets[t]=a,this.toLoad--,this.loaded++,e&&e(t,a)}else this.errors[t]="Couldn't load text "+t,this.toLoad--,this.loaded++,a&&a(t,"Couldn't load image "+t)}))}loadTextureAtlas(e,a=null,s=null){let i=e.lastIndexOf("/")>=0?e.substring(0,e.lastIndexOf("/")):"";e=this.pathPrefix+e,this.toLoad++,this.downloadText(e,n=>{let r={count:0},l=new Array;try{new t.TextureAtlas(n,e=>{l.push(""==i?e:i+"/"+e);let a=document.createElement("img");return new t.FakeTexture(a)})}catch(t){let a=t;return this.errors[e]=`Couldn't load texture atlas ${e}: ${a.message}`,s&&s(e,`Couldn't load texture atlas ${e}: ${a.message}`),this.toLoad--,void this.loaded++}for(let o of l){let h=!1;this.loadTexture(o,(o,d)=>{if(r.count++,r.count==l.length)if(h)this.errors[e]=`Couldn't load texture atlas page ${o}} of atlas ${e}`,s&&s(e,`Couldn't load texture atlas page ${o} of atlas ${e}`),this.toLoad--,this.loaded++;else try{let s=new t.TextureAtlas(n,t=>this.get(""==i?t:i+"/"+t));this.assets[e]=s,a&&a(e,s),this.toLoad--,this.loaded++}catch(t){let a=t;this.errors[e]=`Couldn't load texture atlas ${e}: ${a.message}`,s&&s(e,`Couldn't load texture atlas ${e}: ${a.message}`),this.toLoad--,this.loaded++}},(t,a)=>{h=!0,r.count++,r.count==l.length&&(this.errors[e]=`Couldn't load texture atlas page ${t}} of atlas ${e}`,s&&s(e,`Couldn't load texture atlas page ${t} of atlas ${e}`),this.toLoad--,this.loaded++)})}},(t,a)=>{this.errors[e]=`Couldn't load texture atlas ${e}: status ${status}, ${a}`,s&&s(e,`Couldn't load texture atlas ${e}: status ${status}, ${a}`),this.toLoad--,this.loaded++})}get(t){return t=this.pathPrefix+t,this.assets[t]}remove(t){t=this.pathPrefix+t;let e=this.assets[t];e.dispose&&e.dispose(),this.assets[t]=null}removeAll(){for(let t in this.assets){let e=this.assets[t];e.dispose&&e.dispose()}this.assets={}}isLoadingComplete(){return 0==this.toLoad}getToLoad(){return this.toLoad}getLoaded(){return this.loaded}dispose(){this.removeAll()}hasErrors(){return Object.keys(this.errors).length>0}getErrors(){return this.errors}}}(spine||(spine={})),function(t){t.AtlasAttachmentLoader=class{constructor(t){this.atlas=t}newRegionAttachment(e,a,s){let i=this.atlas.findRegion(s);if(null==i)throw new Error("Region not found in atlas: "+s+" (region attachment: "+a+")");i.renderObject=i;let n=new t.RegionAttachment(a);return n.setRegion(i),n}newMeshAttachment(e,a,s){let i=this.atlas.findRegion(s);if(null==i)throw new Error("Region not found in atlas: "+s+" (mesh attachment: "+a+")");i.renderObject=i;let n=new t.MeshAttachment(a);return n.region=i,n}newBoundingBoxAttachment(e,a){return new t.BoundingBoxAttachment(a)}newPathAttachment(e,a){return new t.PathAttachment(a)}newPointAttachment(e,a){return new t.PointAttachment(a)}newClippingAttachment(e,a){return new t.ClippingAttachment(a)}}}(spine||(spine={})),function(t){let e;!function(t){t[t.Normal=0]="Normal",t[t.Additive=1]="Additive",t[t.Multiply=2]="Multiply",t[t.Screen=3]="Screen"}(e=t.BlendMode||(t.BlendMode={}))}(spine||(spine={})),function(t){t.Bone=class{constructor(t,e,a){if(this.children=new Array,this.x=0,this.y=0,this.rotation=0,this.scaleX=0,this.scaleY=0,this.shearX=0,this.shearY=0,this.ax=0,this.ay=0,this.arotation=0,this.ascaleX=0,this.ascaleY=0,this.ashearX=0,this.ashearY=0,this.appliedValid=!1,this.a=0,this.b=0,this.c=0,this.d=0,this.worldY=0,this.worldX=0,this.sorted=!1,this.active=!1,null==t)throw new Error("data cannot be null.");if(null==e)throw new Error("skeleton cannot be null.");this.data=t,this.skeleton=e,this.parent=a,this.setToSetupPose()}isActive(){return this.active}update(){this.updateWorldTransformWith(this.x,this.y,this.rotation,this.scaleX,this.scaleY,this.shearX,this.shearY)}updateWorldTransform(){this.updateWorldTransformWith(this.x,this.y,this.rotation,this.scaleX,this.scaleY,this.shearX,this.shearY)}updateWorldTransformWith(e,a,s,i,n,r,l){this.ax=e,this.ay=a,this.arotation=s,this.ascaleX=i,this.ascaleY=n,this.ashearX=r,this.ashearY=l,this.appliedValid=!0;let o=this.parent;if(null==o){let o=this.skeleton,h=s+90+l,d=o.scaleX,u=o.scaleY;return this.a=t.MathUtils.cosDeg(s+r)*i*d,this.b=t.MathUtils.cosDeg(h)*n*d,this.c=t.MathUtils.sinDeg(s+r)*i*u,this.d=t.MathUtils.sinDeg(h)*n*u,this.worldX=e*d+o.x,void(this.worldY=a*u+o.y)}let h=o.a,d=o.b,u=o.c,c=o.d;switch(this.worldX=h*e+d*a+o.worldX,this.worldY=u*e+c*a+o.worldY,this.data.transformMode){case t.TransformMode.Normal:{let e=s+90+l,a=t.MathUtils.cosDeg(s+r)*i,o=t.MathUtils.cosDeg(e)*n,f=t.MathUtils.sinDeg(s+r)*i,m=t.MathUtils.sinDeg(e)*n;return this.a=h*a+d*f,this.b=h*o+d*m,this.c=u*a+c*f,void(this.d=u*o+c*m)}case t.TransformMode.OnlyTranslation:{let e=s+90+l;this.a=t.MathUtils.cosDeg(s+r)*i,this.b=t.MathUtils.cosDeg(e)*n,this.c=t.MathUtils.sinDeg(s+r)*i,this.d=t.MathUtils.sinDeg(e)*n;break}case t.TransformMode.NoRotationOrReflection:{let e=h*h+u*u,a=0;e>1e-4?(e=Math.abs(h*c-d*u)/e,d=u*e,c=h*e,a=Math.atan2(u,h)*t.MathUtils.radDeg):(h=0,u=0,a=90-Math.atan2(c,d)*t.MathUtils.radDeg);let o=s+r-a,f=s+l-a+90,m=t.MathUtils.cosDeg(o)*i,g=t.MathUtils.cosDeg(f)*n,p=t.MathUtils.sinDeg(o)*i,w=t.MathUtils.sinDeg(f)*n;return this.a=h*m-d*p,this.b=h*g-d*w,this.c=u*m+c*p,void(this.d=u*g+c*w)}case t.TransformMode.NoScale:case t.TransformMode.NoScaleOrReflection:{let e=t.MathUtils.cosDeg(s),a=t.MathUtils.sinDeg(s),o=(h*e+d*a)/this.skeleton.scaleX,f=(u*e+c*a)/this.skeleton.scaleY,m=Math.sqrt(o*o+f*f);m>1e-5&&(m=1/m),o*=m,f*=m,m=Math.sqrt(o*o+f*f),this.data.transformMode==t.TransformMode.NoScale&&h*c-d*u<0!=(this.skeleton.scaleX<0!=this.skeleton.scaleY<0)&&(m=-m);let g=Math.PI/2+Math.atan2(f,o),p=Math.cos(g)*m,w=Math.sin(g)*m,x=t.MathUtils.cosDeg(r)*i,M=t.MathUtils.cosDeg(90+l)*n,E=t.MathUtils.sinDeg(r)*i,T=t.MathUtils.sinDeg(90+l)*n;this.a=o*x+p*E,this.b=o*M+p*T,this.c=f*x+w*E,this.d=f*M+w*T;break}}this.a*=this.skeleton.scaleX,this.b*=this.skeleton.scaleX,this.c*=this.skeleton.scaleY,this.d*=this.skeleton.scaleY}setToSetupPose(){let t=this.data;this.x=t.x,this.y=t.y,this.rotation=t.rotation,this.scaleX=t.scaleX,this.scaleY=t.scaleY,this.shearX=t.shearX,this.shearY=t.shearY}getWorldRotationX(){return Math.atan2(this.c,this.a)*t.MathUtils.radDeg}getWorldRotationY(){return Math.atan2(this.d,this.b)*t.MathUtils.radDeg}getWorldScaleX(){return Math.sqrt(this.a*this.a+this.c*this.c)}getWorldScaleY(){return Math.sqrt(this.b*this.b+this.d*this.d)}updateAppliedTransform(){this.appliedValid=!0;let e=this.parent;if(null==e)return this.ax=this.worldX,this.ay=this.worldY,this.arotation=Math.atan2(this.c,this.a)*t.MathUtils.radDeg,this.ascaleX=Math.sqrt(this.a*this.a+this.c*this.c),this.ascaleY=Math.sqrt(this.b*this.b+this.d*this.d),this.ashearX=0,void(this.ashearY=Math.atan2(this.a*this.b+this.c*this.d,this.a*this.d-this.b*this.c)*t.MathUtils.radDeg);let a=e.a,s=e.b,i=e.c,n=e.d,r=1/(a*n-s*i),l=this.worldX-e.worldX,o=this.worldY-e.worldY;this.ax=l*n*r-o*s*r,this.ay=o*a*r-l*i*r;let h=r*n,d=r*a,u=r*s,c=r*i,f=h*this.a-u*this.c,m=h*this.b-u*this.d,g=d*this.c-c*this.a,p=d*this.d-c*this.b;if(this.ashearX=0,this.ascaleX=Math.sqrt(f*f+g*g),this.ascaleX>1e-4){let e=f*p-m*g;this.ascaleY=e/this.ascaleX,this.ashearY=Math.atan2(f*m+g*p,e)*t.MathUtils.radDeg,this.arotation=Math.atan2(g,f)*t.MathUtils.radDeg}else this.ascaleX=0,this.ascaleY=Math.sqrt(m*m+p*p),this.ashearY=0,this.arotation=90-Math.atan2(p,m)*t.MathUtils.radDeg}worldToLocal(t){let e=this.a,a=this.b,s=this.c,i=this.d,n=1/(e*i-a*s),r=t.x-this.worldX,l=t.y-this.worldY;return t.x=r*i*n-l*a*n,t.y=l*e*n-r*s*n,t}localToWorld(t){let e=t.x,a=t.y;return t.x=e*this.a+a*this.b+this.worldX,t.y=e*this.c+a*this.d+this.worldY,t}worldToLocalRotation(e){let a=t.MathUtils.sinDeg(e),s=t.MathUtils.cosDeg(e);return Math.atan2(this.a*a-this.c*s,this.d*s-this.b*a)*t.MathUtils.radDeg+this.rotation-this.shearX}localToWorldRotation(e){e-=this.rotation-this.shearX;let a=t.MathUtils.sinDeg(e),s=t.MathUtils.cosDeg(e);return Math.atan2(s*this.c+a*this.d,s*this.a+a*this.b)*t.MathUtils.radDeg}rotateWorld(e){let a=this.a,s=this.b,i=this.c,n=this.d,r=t.MathUtils.cosDeg(e),l=t.MathUtils.sinDeg(e);this.a=r*a-l*i,this.b=r*s-l*n,this.c=l*a+r*i,this.d=l*s+r*n,this.appliedValid=!1}}}(spine||(spine={})),function(t){let e;t.BoneData=class{constructor(a,s,i){if(this.x=0,this.y=0,this.rotation=0,this.scaleX=1,this.scaleY=1,this.shearX=0,this.shearY=0,this.transformMode=e.Normal,this.skinRequired=!1,this.color=new t.Color,a<0)throw new Error("index must be >= 0.");if(null==s)throw new Error("name cannot be null.");this.index=a,this.name=s,this.parent=i}},function(t){t[t.Normal=0]="Normal",t[t.OnlyTranslation=1]="OnlyTranslation",t[t.NoRotationOrReflection=2]="NoRotationOrReflection",t[t.NoScale=3]="NoScale",t[t.NoScaleOrReflection=4]="NoScaleOrReflection"}(e=t.TransformMode||(t.TransformMode={}))}(spine||(spine={})),function(t){t.ConstraintData=class{constructor(t,e,a){this.name=t,this.order=e,this.skinRequired=a}}}(spine||(spine={})),function(t){t.Event=class{constructor(t,e){if(null==e)throw new Error("data cannot be null.");this.time=t,this.data=e}}}(spine||(spine={})),function(t){t.EventData=class{constructor(t){this.name=t}}}(spine||(spine={})),function(t){t.IkConstraint=class{constructor(t,e){if(this.bendDirection=0,this.compress=!1,this.stretch=!1,this.mix=1,this.softness=0,this.active=!1,null==t)throw new Error("data cannot be null.");if(null==e)throw new Error("skeleton cannot be null.");this.data=t,this.mix=t.mix,this.softness=t.softness,this.bendDirection=t.bendDirection,this.compress=t.compress,this.stretch=t.stretch,this.bones=new Array;for(let a=0;a180?f-=360:f<-180&&(f+=360);let p=e.ascaleX,w=e.ascaleY;if(i||n){switch(e.data.transformMode){case t.TransformMode.NoScale:case t.TransformMode.NoScaleOrReflection:m=a-e.worldX,g=s-e.worldY}let o=e.data.length*p,h=Math.sqrt(m*m+g*g);if(i&&ho&&o>1e-4){let t=(h/o-1)*l+1;p*=t,r&&(w*=t)}}e.updateWorldTransformWith(e.ax,e.ay,e.arotation+f*l,p,w,e.ashearX,e.ashearY)}apply2(e,a,s,i,n,r,l,o){if(0==o)return void a.updateWorldTransform();e.appliedValid||e.updateAppliedTransform(),a.appliedValid||a.updateAppliedTransform();let h=e.ax,d=e.ay,u=e.ascaleX,c=u,f=e.ascaleY,m=a.ascaleX,g=0,p=0,w=0;u<0?(u=-u,g=180,w=-1):(g=0,w=1),f<0&&(f=-f,w=-w),m<0?(m=-m,p=180):p=0;let x=a.ax,M=0,E=0,T=0,A=e.a,b=e.b,y=e.c,S=e.d,I=Math.abs(u-f)<=1e-4;I?(M=a.ay,E=A*x+b*M+e.worldX,T=y*x+S*M+e.worldY):(M=0,E=A*x+e.worldX,T=y*x+e.worldY);let R=e.parent;A=R.a,b=R.b,y=R.c,S=R.d;let C,P,V=1/(A*S-b*y),k=E-R.worldX,v=T-R.worldY,F=(k*S-v*b)*V-h,N=(v*A-k*y)*V-d,L=Math.sqrt(F*F+N*N),U=a.data.length*m;if(L<1e-4)return this.apply1(e,s,i,!1,r,!1,o),void a.updateWorldTransformWith(x,M,0,a.ascaleX,a.ascaleY,a.ashearX,a.ashearY);k=s-R.worldX,v=i-R.worldY;let Y=(k*S-v*b)*V-h,X=(v*A-k*y)*V-d,B=Y*Y+X*X;if(0!=l){l*=u*(m+1)/2;let t=Math.sqrt(B),e=t-L-U*u+l;if(e>0){let a=Math.min(1,e/(2*l))-1;a=(e-l*(1-a*a))/t,Y-=a*Y,X-=a*X,B=Y*Y+X*X}}t:if(I){U*=u;let t=(B-L*L-U*U)/(2*L*U);t<-1?t=-1:t>1&&(t=1,r&&(c*=(Math.sqrt(B)/(L+U)-1)*o+1)),P=Math.acos(t)*n,A=L+U*t,b=U*Math.sin(P),C=Math.atan2(X*A-Y*b,Y*A+X*b)}else{A=u*U,b=f*U;let e=A*A,a=b*b,s=Math.atan2(X,Y);y=a*L*L+e*B-e*a;let i=-2*a*L,r=a-e;if(S=i*i-4*r*y,S>=0){let t=Math.sqrt(S);i<0&&(t=-t),t=-(i+t)/2;let e=t/r,a=y/t,l=Math.abs(e)=-1&&y<=1&&(y=Math.acos(y),k=A*Math.cos(y)+L,v=b*Math.sin(y),S=k*k+v*v,Sg&&(c=y,g=S,m=k,p=v)),B<=(h+g)/2?(C=s-Math.atan2(d*n,o),P=l*n):(C=s-Math.atan2(p*n,m),P=c*n)}let O=Math.atan2(M,x)*w,D=e.arotation;C=(C-O)*t.MathUtils.radDeg+g-D,C>180?C-=360:C<-180&&(C+=360),e.updateWorldTransformWith(h,d,D+C*o,c,e.ascaleY,0,0),D=a.arotation,P=((P+O)*t.MathUtils.radDeg-a.ashearX)*w+p-D,P>180?P-=360:P<-180&&(P+=360),a.updateWorldTransformWith(x,M,D+P*o,a.ascaleX,a.ascaleY,a.ashearX,a.ashearY)}}}(spine||(spine={})),function(t){class e extends t.ConstraintData{constructor(t){super(t,0,!1),this.bones=new Array,this.bendDirection=1,this.compress=!1,this.stretch=!1,this.uniform=!1,this.mix=1,this.softness=0}}t.IkConstraintData=e}(spine||(spine={})),function(t){class e{constructor(t,e){if(this.position=0,this.spacing=0,this.rotateMix=0,this.translateMix=0,this.spaces=new Array,this.positions=new Array,this.world=new Array,this.curves=new Array,this.lengths=new Array,this.segments=new Array,this.active=!1,null==t)throw new Error("data cannot be null.");if(null==e)throw new Error("skeleton cannot be null.");this.data=t,this.bones=new Array;for(let a=0,s=t.bones.length;a0;if(!(i>0)&&!n)return;let r=this.data,l=r.spacingMode==t.SpacingMode.Percent,o=r.rotateMode,h=o==t.RotateMode.Tangent,d=o==t.RotateMode.ChainScale,u=this.bones.length,c=h?u:u+1,f=this.bones,m=t.Utils.setArraySize(this.spaces,c),g=null,p=this.spacing;if(d||!l){d&&(g=t.Utils.setArraySize(this.lengths,u));let a=r.spacingMode==t.SpacingMode.Length;for(let t=0,s=c-1;t0?t.MathUtils.degRad:-t.MathUtils.degRad}for(let e=0,a=3;et.MathUtils.PI?d-=t.MathUtils.PI2:d<-t.MathUtils.PI&&(d+=t.MathUtils.PI2),d*=s,f=Math.cos(d),g=Math.sin(d),r.a=f*i-g*l,r.b=f*n-g*o,r.c=g*i+f*l,r.d=g*n+f*o}r.appliedValid=!1}}computeWorldPositions(a,s,i,n,r){let l=this.target,o=this.position,h=this.spaces,d=t.Utils.setArraySize(this.positions,3*s+2),u=null,c=a.closed,f=a.worldVerticesLength,m=f/6,g=e.NONE;if(!a.constantSpeed){let p=a.lengths;m-=c?1:2;let w=p[m];if(n&&(o*=w),r)for(let t=1;tw){g!=e.AFTER&&(g=e.AFTER,a.computeWorldVertices(l,f-6,4,u,0,2)),this.addAfterPosition(x-w,u,0,d,n);continue}}for(;;r++){let t=p[r];if(!(x>t)){if(0==r)x/=t;else{let e=p[r-1];x=(x-e)/(t-e)}break}}r!=g&&(g=r,c&&r==m?(a.computeWorldVertices(l,f-4,4,u,0,2),a.computeWorldVertices(l,0,4,u,4,2)):a.computeWorldVertices(l,6*r+2,8,u,0,2)),this.addCurvePosition(x,u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],d,n,i||t>0&&0==s)}return d}c?(f+=2,u=t.Utils.setArraySize(this.world,f),a.computeWorldVertices(l,2,f-4,u,0,2),a.computeWorldVertices(l,0,2,u,f-4,2),u[f-2]=u[0],u[f-1]=u[1]):(m--,f-=4,u=t.Utils.setArraySize(this.world,f),a.computeWorldVertices(l,2,f,u,0,2));let p=t.Utils.setArraySize(this.curves,m),w=0,x=u[0],M=u[1],E=0,T=0,A=0,b=0,y=0,S=0,I=0,R=0,C=0,P=0,V=0,k=0,v=0,F=0;for(let t=0,e=2;tw){this.addAfterPosition(r-w,u,f-4,d,e);continue}}for(;;a++){let t=p[a];if(!(r>t)){if(0==a)r/=t;else{let e=p[a-1];r=(r-e)/(t-e)}break}}if(a!=g){g=a;let t=6*a;for(x=u[t],M=u[t+1],E=u[t+2],T=u[t+3],A=u[t+4],b=u[t+5],y=u[t+6],S=u[t+7],I=.03*(x-2*E+A),R=.03*(M-2*T+b),C=.006*(3*(E-A)-x+y),P=.006*(3*(T-b)-M+S),V=2*I+C,k=2*R+P,v=.3*(E-x)+I+.16666667*C,F=.3*(T-M)+R+.16666667*P,L=Math.sqrt(v*v+F*F),N[0]=L,t=1;t<8;t++)v+=V,F+=k,V+=C,k+=P,L+=Math.sqrt(v*v+F*F),N[t]=L;v+=V,F+=k,L+=Math.sqrt(v*v+F*F),N[8]=L,v+=V+C,F+=k+P,L+=Math.sqrt(v*v+F*F),N[9]=L,n=0}for(r*=L;;n++){let t=N[n];if(!(r>t)){if(0==n)r/=t;else{let e=N[n-1];r=n+(r-e)/(t-e)}break}}this.addCurvePosition(.1*r,x,M,E,T,A,b,y,S,d,e,i||t>0&&0==s)}return d}addBeforePosition(t,e,a,s,i){let n=e[a],r=e[a+1],l=e[a+2]-n,o=e[a+3]-r,h=Math.atan2(o,l);s[i]=n+t*Math.cos(h),s[i+1]=r+t*Math.sin(h),s[i+2]=h}addAfterPosition(t,e,a,s,i){let n=e[a+2],r=e[a+3],l=n-e[a],o=r-e[a+1],h=Math.atan2(o,l);s[i]=n+t*Math.cos(h),s[i+1]=r+t*Math.sin(h),s[i+2]=h}addCurvePosition(t,e,a,s,i,n,r,l,o,h,d,u){if(0==t||isNaN(t))return h[d]=e,h[d+1]=a,void(h[d+2]=Math.atan2(i-a,s-e));let c=t*t,f=c*t,m=1-t,g=m*m,p=g*m,w=m*t,x=3*w,M=m*x,E=x*t,T=e*p+s*M+n*E+l*f,A=a*p+i*M+r*E+o*f;h[d]=T,h[d+1]=A,u&&(h[d+2]=t<.001?Math.atan2(i-a,s-e):Math.atan2(A-(a*g+i*w*2+r*c),T-(e*g+s*w*2+n*c)))}}e.NONE=-1,e.BEFORE=-2,e.AFTER=-3,e.epsilon=1e-5,t.PathConstraint=e}(spine||(spine={})),function(t){class e extends t.ConstraintData{constructor(t){super(t,0,!1),this.bones=new Array}}let a,s,i;t.PathConstraintData=e,function(t){t[t.Fixed=0]="Fixed",t[t.Percent=1]="Percent"}(a=t.PositionMode||(t.PositionMode={})),function(t){t[t.Length=0]="Length",t[t.Fixed=1]="Fixed",t[t.Percent=2]="Percent"}(s=t.SpacingMode||(t.SpacingMode={})),function(t){t[t.Tangent=0]="Tangent",t[t.Chain=1]="Chain",t[t.ChainScale=2]="ChainScale"}(i=t.RotateMode||(t.RotateMode={}))}(spine||(spine={})),function(t){class e{constructor(t){this.toLoad=new Array,this.assets={},this.clientId=t}loaded(){let t=0;for(let e in this.assets)t++;return t}}t.SharedAssetManager=class{constructor(t=""){this.clientAssets={},this.queuedAssets={},this.rawAssets={},this.errors={},this.pathPrefix=t}queueAsset(t,a,s){let i=this.clientAssets[t];return null==i&&(i=new e(t),this.clientAssets[t]=i),null!==a&&(i.textureLoader=a),i.toLoad.push(s),this.queuedAssets[s]!==s&&(this.queuedAssets[s]=s,!0)}loadText(t,e){if(e=this.pathPrefix+e,!this.queueAsset(t,null,e))return;let a=Laya.Laya?Laya.Laya:Laya;a.loader.load([{type:a.Loader.TEXT,url:e}],a.Handler.create(this,t=>{t?this.rawAssets[e]=a.loader.getRes(e):this.errors[e]="Couldn't load text "+e}))}loadJson(t,e){if(e=this.pathPrefix+e,!this.queueAsset(t,null,e))return;let a=Laya.Laya?Laya.Laya:Laya;a.loader.load([{type:a.Loader.JSON,url:e}],a.Handler.create(this,t=>{t?this.rawAssets[e]=a.loader.getRes(e):this.errors[e]="Couldn't load text "+e}))}loadTexture(t,e,a){if(a=this.pathPrefix+a,!this.queueAsset(t,e,a))return;let s=Laya.Laya?Laya.Laya:Laya;s.loader.load([{type:s.Loader.IMAGE,url:a}],s.Handler.create(this,t=>{t?this.rawAssets[a]=s.loader.getRes(a):this.errors[a]="Couldn't load text "+a}))}get(t,e){e=this.pathPrefix+e;let a=this.clientAssets[t];return null==a||a.assets[e]}updateClientAssets(t){for(let e=0;e0}getErrors(){return this.errors}}}(spine||(spine={})),function(t){t.Skeleton=class{constructor(e){if(this._updateCache=new Array,this.updateCacheReset=new Array,this.time=0,this.scaleX=1,this.scaleY=1,this.x=0,this.y=0,null==e)throw new Error("data cannot be null.");this.data=e,this.bones=new Array;for(let a=0;a1){let t=s[s.length-1];this._updateCache.indexOf(t)>-1||this.updateCacheReset.push(t)}this._updateCache.push(e),this.sortReset(i.children),s[s.length-1].sorted=!0}sortPathConstraint(e){if(e.active=e.target.bone.isActive()&&(!e.data.skinRequired||null!=this.skin&&t.Utils.contains(this.skin.constraints,e.data,!0)),!e.active)return;let a=e.target,s=a.data.index,i=a.bone;null!=this.skin&&this.sortPathConstraintAttachment(this.skin,s,i),null!=this.data.defaultSkin&&this.data.defaultSkin!=this.skin&&this.sortPathConstraintAttachment(this.data.defaultSkin,s,i);for(let t=0,e=this.data.skins.length;t-1||this.updateCacheReset.push(e)}else for(let t=0;t0){let e=new t.DrawOrderTimeline(d),s=i.slots.length;for(let i=0;i=0;t--)l[t]=-1;let o=t.Utils.newArray(s-r,0),h=0,d=0;for(let t=0;t=0;t--)-1==l[t]&&(l[t]=o[--d]);e.setFrame(i,n,l)}n.push(e),l=Math.max(l,e.frames[d-1])}let u=a.readInt(!0);if(u>0){let e=new t.EventTimeline(u);for(let s=0;s>>1^-(1&a)}readStringRef(){let t=this.readInt(!0);return 0==t?null:this.strings[t-1]}readString(){let t=this.readInt(!0);switch(t){case 0:return null;case 1:return""}t--;let e="";for(let a=0;a>4){case 12:case 13:e+=String.fromCharCode((31&t)<<6|63&this.readByte()),a+=2;break;case 14:e+=String.fromCharCode((15&t)<<12|(63&this.readByte())<<6|63&this.readByte()),a+=3;break;default:e+=String.fromCharCode(t),a++}}return e}readFloat(){let t=this.buffer.getFloat32(this.index);return this.index+=4,t}readBoolean(){return 0!=this.readByte()}}class s{constructor(t,e,a,s,i){this.mesh=t,this.skin=e,this.slotIndex=a,this.parent=s,this.inheritDeform=i}}class i{constructor(t=null,e=null){this.bones=t,this.vertices=e}}}(spine||(spine={})),function(t){t.SkeletonBounds=class{constructor(){this.minX=0,this.minY=0,this.maxX=0,this.maxY=0,this.boundingBoxes=new Array,this.polygons=new Array,this.polygonPool=new t.Pool(()=>t.Utils.newFloatArray(16))}update(e,a){if(null==e)throw new Error("skeleton cannot be null.");let s=this.boundingBoxes,i=this.polygons,n=this.polygonPool,r=e.slots,l=r.length;s.length=0,n.freeAll(i),i.length=0;for(let e=0;e=this.minX&&t<=this.maxX&&e>=this.minY&&e<=this.maxY}aabbIntersectsSegment(t,e,a,s){let i=this.minX,n=this.minY,r=this.maxX,l=this.maxY;if(t<=i&&a<=i||e<=n&&s<=n||t>=r&&a>=r||e>=l&&s>=l)return!1;let o=(s-e)/(a-t),h=o*(i-t)+e;if(h>n&&hn&&hi&&di&&dt.minX&&this.minYt.minY}containsPoint(t,e){let a=this.polygons;for(let s=0,i=a.length;s=a||l=a){let o=s[t];o+(a-i)/(l-i)*(s[n]-o)=d&&w<=r||w>=r&&w<=d)&&(w>=e&&w<=s||w>=s&&w<=e)){let t=(h*g-o*f)/p;if((t>=u&&t<=c||t>=c&&t<=u)&&(t>=a&&t<=i||t>=i&&t<=a))return!0}d=r,u=c}return!1}getPolygon(t){if(null==t)throw new Error("boundingBox cannot be null.");let e=this.boundingBoxes.indexOf(t);return-1==e?null:this.polygons[e]}getWidth(){return this.maxX-this.minX}getHeight(){return this.maxY-this.minY}}}(spine||(spine={})),function(t){class e{constructor(){this.triangulator=new t.Triangulator,this.clippingPolygon=new Array,this.clipOutput=new Array,this.clippedVertices=new Array,this.clippedTriangles=new Array,this.scratch=new Array}clipStart(a,s){if(null!=this.clipAttachment)return 0;this.clipAttachment=s;let i=s.worldVerticesLength,n=t.Utils.setArraySize(this.clippingPolygon,i);s.computeWorldVertices(a,0,i,n,0,2);let r=this.clippingPolygon;e.makeClockwise(r);let l=this.clippingPolygons=this.triangulator.decompose(r,this.triangulator.triangulate(r));for(let t=0,a=l.length;t>1,P=this.clipOutput,V=t.Utils.setArraySize(d,a+C*m);for(let t=0;t=2?(d=l,l=this.scratch):d=this.scratch,d.length=0,d.push(t),d.push(e),d.push(a),d.push(s),d.push(i),d.push(n),d.push(t),d.push(e),l.length=0;let u=r,c=r.length-4;for(let t=0;;t+=2){let e=u[t],a=u[t+1],s=u[t+2],i=u[t+3],n=e-s,r=a-i,f=d,m=d.length-2,g=l.length;for(let t=0;t0;if(n*(d-i)-r*(o-s)>0){if(m){l.push(u),l.push(c);continue}let t=c-d,n=u-o,r=t*(s-e)-n*(i-a);if(Math.abs(r)>1e-6){let h=(n*(a-d)-t*(e-o))/r;l.push(e+(s-e)*h),l.push(a+(i-a)*h)}else l.push(e),l.push(a)}else if(m){let t=c-d,n=u-o,r=t*(s-e)-n*(i-a);if(Math.abs(r)>1e-6){let h=(n*(a-d)-t*(e-o))/r;l.push(e+(s-e)*h),l.push(a+(i-a)*h)}else l.push(e),l.push(a);l.push(u),l.push(c)}h=!0}if(g==l.length)return o.length=0,!0;if(l.push(l[0]),l.push(l[1]),t==c)break;let p=l;(l=d).length=0,d=p}if(o!=l){o.length=0;for(let t=0,e=l.length-2;t>1;t=0;t--)-1==o[t]&&(o[t]=e[--n])}e.setFrame(i++,this.getValue(r,"time",0),o)}n.push(e),r=Math.max(r,e.frames[e.getFrameCount()-1])}if(e.events){let a=new t.EventTimeline(e.events.length),i=0;for(let n=0;n=s.length&&(s.length=t+1),s[t]||(s[t]={}),s[t][e]=a}addSkin(t){for(let e=0;e= 0.");if(null==a)throw new Error("name cannot be null.");if(null==s)throw new Error("boneData cannot be null.");this.index=e,this.name=a,this.boneData=s}}}(spine||(spine={})),function(t){class e{constructor(t){this._image=t}getImage(){return this._image}static filterFromString(t){switch(t.toLowerCase()){case"nearest":return a.Nearest;case"linear":return a.Linear;case"mipmap":return a.MipMap;case"mipmapnearestnearest":return a.MipMapNearestNearest;case"mipmaplinearnearest":return a.MipMapLinearNearest;case"mipmapnearestlinear":return a.MipMapNearestLinear;case"mipmaplinearlinear":return a.MipMapLinearLinear;default:throw new Error("Unknown texture filter "+t)}}static wrapFromString(t){switch(t.toLowerCase()){case"mirroredtepeat":return s.MirroredRepeat;case"clamptoedge":return s.ClampToEdge;case"repeat":return s.Repeat;default:throw new Error("Unknown texture wrap "+t)}}}let a,s;t.Texture=e,function(t){t[t.Nearest=9728]="Nearest",t[t.Linear=9729]="Linear",t[t.MipMap=9987]="MipMap",t[t.MipMapNearestNearest=9984]="MipMapNearestNearest",t[t.MipMapLinearNearest=9985]="MipMapLinearNearest",t[t.MipMapNearestLinear=9986]="MipMapNearestLinear",t[t.MipMapLinearLinear=9987]="MipMapLinearLinear"}(a=t.TextureFilter||(t.TextureFilter={})),function(t){t[t.MirroredRepeat=33648]="MirroredRepeat",t[t.ClampToEdge=33071]="ClampToEdge",t[t.Repeat=10497]="Repeat"}(s=t.TextureWrap||(t.TextureWrap={}));t.TextureRegion=class{constructor(){this.u=0,this.v=0,this.u2=0,this.v2=0,this.width=0,this.height=0,this.rotate=!1,this.offsetX=0,this.offsetY=0,this.originalWidth=0,this.originalHeight=0}};t.FakeTexture=class extends e{setFilters(t,e){}setWraps(t,e){}dispose(){}}}(spine||(spine={})),function(t){t.TextureAtlas=class{constructor(t,e){this.pages=new Array,this.regions=new Array,this.load(t,e)}load(i,n){if(null==n)throw new Error("textureLoader cannot be null.");let r=new e(i),l=new Array(4),o=null;for(;;){let e=r.readLine();if(null==e)break;if(e=e.trim(),0==e.length)o=null;else if(o){let t=new s;t.name=e,t.page=o;let a=r.readValue();"true"==a.toLocaleLowerCase()?t.degrees=90:"false"==a.toLocaleLowerCase()?t.degrees=0:t.degrees=parseFloat(a),t.rotate=90==t.degrees,r.readTuple(l);let i=parseInt(l[0]),n=parseInt(l[1]);r.readTuple(l);let h=parseInt(l[0]),d=parseInt(l[1]);t.u=i/o.width,t.v=n/o.height,t.rotate?(t.u2=(i+d)/o.width,t.v2=(n+h)/o.height):(t.u2=(i+h)/o.width,t.v2=(n+d)/o.height),t.x=i,t.y=n,t.width=Math.abs(h),t.height=Math.abs(d),4==r.readTuple(l)&&4==r.readTuple(l)&&r.readTuple(l),t.originalWidth=parseInt(l[0]),t.originalHeight=parseInt(l[1]),r.readTuple(l),t.offsetX=parseInt(l[0]),t.offsetY=parseInt(l[1]),t.index=parseInt(r.readValue()),t.texture=o.texture,this.regions.push(t)}else{o=new a,o.name=e,2==r.readTuple(l)&&(o.width=parseInt(l[0]),o.height=parseInt(l[1]),r.readTuple(l)),r.readTuple(l),o.minFilter=t.Texture.filterFromString(l[0]),o.magFilter=t.Texture.filterFromString(l[1]);let s=r.readValue();o.uWrap=t.TextureWrap.ClampToEdge,o.vWrap=t.TextureWrap.ClampToEdge,"x"==s?o.uWrap=t.TextureWrap.Repeat:"y"==s?o.vWrap=t.TextureWrap.Repeat:"xy"==s&&(o.uWrap=o.vWrap=t.TextureWrap.Repeat),o.texture=n(e),o.texture.setFilters(o.minFilter,o.magFilter),o.texture.setWraps(o.uWrap,o.vWrap),o.width=o.texture.getImage().width,o.height=o.texture.getImage().height,this.pages.push(o)}}}findRegion(t){for(let e=0;e=this.lines.length?null:this.lines[this.index++]}readValue(){let t=this.readLine(),e=t.indexOf(":");if(-1==e)throw new Error("Invalid line: "+t);return t.substring(e+1).trim()}readTuple(t){let e=this.readLine(),a=e.indexOf(":");if(-1==a)throw new Error("Invalid line: "+e);let s=0,i=a+1;for(;s<3;s++){let a=e.indexOf(",",i);if(-1==a)break;t[s]=e.substr(i,a-i).trim(),i=a+1}return t[s]=e.substring(i).trim(),s+1}}class a{}t.TextureAtlasPage=a;class s extends t.TextureRegion{}t.TextureAtlasRegion=s}(spine||(spine={})),function(t){t.TransformConstraint=class{constructor(e,a){if(this.rotateMix=0,this.translateMix=0,this.scaleMix=0,this.shearMix=0,this.temp=new t.Vector2,this.active=!1,null==e)throw new Error("data cannot be null.");if(null==a)throw new Error("skeleton cannot be null.");this.data=e,this.rotateMix=e.rotateMix,this.translateMix=e.translateMix,this.scaleMix=e.scaleMix,this.shearMix=e.shearMix,this.bones=new Array;for(let t=0;t0?t.MathUtils.degRad:-t.MathUtils.degRad,u=this.data.offsetRotation*d,c=this.data.offsetShearY*d,f=this.bones;for(let d=0,m=f.length;dt.MathUtils.PI?l-=t.MathUtils.PI2:l<-t.MathUtils.PI&&(l+=t.MathUtils.PI2),l*=e;let h=Math.cos(l),d=Math.sin(l);m.a=h*a-d*i,m.b=h*s-d*n,m.c=d*a+h*i,m.d=d*s+h*n,g=!0}if(0!=a){let t=this.temp;n.localToWorld(t.set(this.data.offsetX,this.data.offsetY)),m.worldX+=(t.x-m.worldX)*a,m.worldY+=(t.y-m.worldY)*a,g=!0}if(s>0){let t=Math.sqrt(m.a*m.a+m.c*m.c),e=Math.sqrt(r*r+o*o);t>1e-5&&(t=(t+(e-t+this.data.offsetScaleX)*s)/t),m.a*=t,m.c*=t,t=Math.sqrt(m.b*m.b+m.d*m.d),e=Math.sqrt(l*l+h*h),t>1e-5&&(t=(t+(e-t+this.data.offsetScaleY)*s)/t),m.b*=t,m.d*=t,g=!0}if(i>0){let e=m.b,a=m.d,s=Math.atan2(a,e),n=Math.atan2(h,l)-Math.atan2(o,r)-(s-Math.atan2(m.c,m.a));n>t.MathUtils.PI?n-=t.MathUtils.PI2:n<-t.MathUtils.PI&&(n+=t.MathUtils.PI2),n=s+(n+c)*i;let d=Math.sqrt(e*e+a*a);m.b=Math.cos(n)*d,m.d=Math.sin(n)*d,g=!0}g&&(m.appliedValid=!1)}}applyRelativeWorld(){let e=this.rotateMix,a=this.translateMix,s=this.scaleMix,i=this.shearMix,n=this.target,r=n.a,l=n.b,o=n.c,h=n.d,d=r*h-l*o>0?t.MathUtils.degRad:-t.MathUtils.degRad,u=this.data.offsetRotation*d,c=this.data.offsetShearY*d,f=this.bones;for(let d=0,m=f.length;dt.MathUtils.PI?l-=t.MathUtils.PI2:l<-t.MathUtils.PI&&(l+=t.MathUtils.PI2),l*=e;let h=Math.cos(l),d=Math.sin(l);m.a=h*a-d*i,m.b=h*s-d*n,m.c=d*a+h*i,m.d=d*s+h*n,g=!0}if(0!=a){let t=this.temp;n.localToWorld(t.set(this.data.offsetX,this.data.offsetY)),m.worldX+=t.x*a,m.worldY+=t.y*a,g=!0}if(s>0){let t=(Math.sqrt(r*r+o*o)-1+this.data.offsetScaleX)*s+1;m.a*=t,m.c*=t,t=(Math.sqrt(l*l+h*h)-1+this.data.offsetScaleY)*s+1,m.b*=t,m.d*=t,g=!0}if(i>0){let e=Math.atan2(h,l)-Math.atan2(o,r);e>t.MathUtils.PI?e-=t.MathUtils.PI2:e<-t.MathUtils.PI&&(e+=t.MathUtils.PI2);let a=m.b,s=m.d;e=Math.atan2(s,a)+(e-t.MathUtils.PI/2+c)*i;let n=Math.sqrt(a*a+s*s);m.b=Math.cos(e)*n,m.d=Math.sin(e)*n,g=!0}g&&(m.appliedValid=!1)}}applyAbsoluteLocal(){let t=this.rotateMix,e=this.translateMix,a=this.scaleMix,s=this.shearMix,i=this.target;i.appliedValid||i.updateAppliedTransform();let n=this.bones;for(let r=0,l=n.length;r1e-5&&(u=(u+(i.ascaleX-u+this.data.offsetScaleX)*a)/u),c>1e-5&&(c=(c+(i.ascaleY-c+this.data.offsetScaleY)*a)/c));let f=l.ashearY;if(0!=s){let t=i.ashearY-f+this.data.offsetShearY;t-=360*(16384-(16384.499999999996-t/360|0)),l.shearY+=t*s}l.updateWorldTransformWith(h,d,o,u,c,l.ashearX,f)}}applyRelativeLocal(){let t=this.rotateMix,e=this.translateMix,a=this.scaleMix,s=this.shearMix,i=this.target;i.appliedValid||i.updateAppliedTransform();let n=this.bones;for(let r=0,l=n.length;r1e-5&&(u*=(i.ascaleX-1+this.data.offsetScaleX)*a+1),c>1e-5&&(c*=(i.ascaleY-1+this.data.offsetScaleY)*a+1));let f=l.ashearY;0!=s&&(f+=(i.ashearY+this.data.offsetShearY)*s),l.updateWorldTransformWith(h,d,o,u,c,l.ashearX,f)}}}}(spine||(spine={})),function(t){class e extends t.ConstraintData{constructor(t){super(t,0,!1),this.bones=new Array,this.rotateMix=0,this.translateMix=0,this.scaleMix=0,this.shearMix=0,this.offsetRotation=0,this.offsetX=0,this.offsetY=0,this.offsetScaleX=0,this.offsetScaleY=0,this.offsetShearY=0,this.relative=!1,this.local=!1}}t.TransformConstraintData=e}(spine||(spine={})),function(t){class e{constructor(){this.convexPolygons=new Array,this.convexPolygonsIndices=new Array,this.indicesArray=new Array,this.isConcaveArray=new Array,this.triangles=new Array,this.polygonPool=new t.Pool(()=>new Array),this.polygonIndicesPool=new t.Pool(()=>new Array)}triangulate(t){let a=t,s=t.length>>1,i=this.indicesArray;i.length=0;for(let t=0;t3;){let t=s-1,l=0,o=1;for(;;){t:if(!n[l]){let r=i[t]<<1,h=i[l]<<1,d=i[o]<<1,u=a[r],c=a[r+1],f=a[h],m=a[h+1],g=a[d],p=a[d+1];for(let r=(o+1)%s;r!=t;r=(r+1)%s){if(!n[r])continue;let t=i[r]<<1,s=a[t],l=a[t+1];if(e.positiveArea(g,p,u,c,s,l)&&e.positiveArea(u,c,f,m,s,l)&&e.positiveArea(f,m,g,p,s,l))break t}break}if(0==o){do{if(!n[l])break;l--}while(l>0);break}t=l,l=o,o=(o+1)%s}r.push(i[(s+l-1)%s]),r.push(i[l]),r.push(i[(l+1)%s]),i.splice(l,1),n.splice(l,1),s--;let h=(s+l-1)%s,d=l==s?0:l;n[h]=e.isConcave(h,s,a,i),n[d]=e.isConcave(d,s,a,i)}return 3==s&&(r.push(i[2]),r.push(i[0]),r.push(i[1])),r}decompose(t,a){let s=t,i=this.convexPolygons;this.polygonPool.freeAll(i),i.length=0;let n=this.convexPolygonsIndices;this.polygonIndicesPool.freeAll(n),n.length=0;let r=this.polygonIndicesPool.obtain();r.length=0;let l=this.polygonPool.obtain();l.length=0;let o=-1,h=0;for(let t=0,d=a.length;t0?(i.push(l),n.push(r)):(this.polygonPool.free(l),this.polygonIndicesPool.free(r)),l=this.polygonPool.obtain(),l.length=0,l.push(f),l.push(m),l.push(g),l.push(p),l.push(w),l.push(x),r=this.polygonIndicesPool.obtain(),r.length=0,r.push(d),r.push(u),r.push(c),h=e.winding(f,m,g,p,w,x),o=d)}l.length>0&&(i.push(l),n.push(r));for(let t=0,a=i.length;t=0;t--)l=i[t],0==l.length&&(i.splice(t,1),this.polygonPool.free(l),r=n[t],n.splice(t,1),this.polygonIndicesPool.free(r));return i}static isConcave(t,e,a,s){let i=s[(e+t-1)%e]<<1,n=s[t]<<1,r=s[(t+1)%e]<<1;return!this.positiveArea(a[i],a[i+1],a[n],a[n+1],a[r],a[r+1])}static positiveArea(t,e,a,s,i,n){return t*(n-s)+a*(e-n)+i*(s-e)>=0}static winding(t,e,a,s,i,n){let r=a-t,l=s-e;return i*l-n*r+r*e-t*l>=0?1:-1}}t.Triangulator=e}(spine||(spine={})),function(t){t.IntSet=class{constructor(){this.array=new Array}add(t){let e=this.contains(t);return this.array[0|t]=0|t,!e}contains(t){return null!=this.array[0|t]}remove(t){this.array[0|t]=void 0}clear(){this.array.length=0}};class e{constructor(t=0,e=0,a=0,s=0){this.r=t,this.g=e,this.b=a,this.a=s}set(t,e,a,s){return this.r=t,this.g=e,this.b=a,this.a=s,this.clamp(),this}setFromColor(t){return this.r=t.r,this.g=t.g,this.b=t.b,this.a=t.a,this}setFromString(t){return t="#"==t.charAt(0)?t.substr(1):t,this.r=parseInt(t.substr(0,2),16)/255,this.g=parseInt(t.substr(2,2),16)/255,this.b=parseInt(t.substr(4,2),16)/255,this.a=(8!=t.length?255:parseInt(t.substr(6,2),16))/255,this}add(t,e,a,s){return this.r+=t,this.g+=e,this.b+=a,this.a+=s,this.clamp(),this}clamp(){return this.r<0?this.r=0:this.r>1&&(this.r=1),this.g<0?this.g=0:this.g>1&&(this.g=1),this.b<0?this.b=0:this.b>1&&(this.b=1),this.a<0?this.a=0:this.a>1&&(this.a=1),this}static rgba8888ToColor(t,e){t.r=((4278190080&e)>>>24)/255,t.g=((16711680&e)>>>16)/255,t.b=((65280&e)>>>8)/255,t.a=(255&e)/255}static rgb888ToColor(t,e){t.r=((16711680&e)>>>16)/255,t.g=((65280&e)>>>8)/255,t.b=(255&e)/255}}e.WHITE=new e(1,1,1,1),e.RED=new e(1,0,0,1),e.GREEN=new e(0,1,0,1),e.BLUE=new e(0,0,1,1),e.MAGENTA=new e(1,0,1,1),t.Color=e;class a{static clamp(t,e,a){return ta?a:t}static cosDeg(t){return Math.cos(t*a.degRad)}static sinDeg(t){return Math.sin(t*a.degRad)}static signum(t){return t>0?1:t<0?-1:0}static toInt(t){return t>0?Math.floor(t):Math.ceil(t)}static cbrt(t){let e=Math.pow(Math.abs(t),1/3);return t<0?-e:e}static randomTriangular(t,e){return a.randomTriangularWith(t,e,.5*(t+e))}static randomTriangularWith(t,e,a){let s=Math.random(),i=e-t;return s<=(a-t)/i?t+Math.sqrt(s*i*(a-t)):e-Math.sqrt((1-s)*i*(e-a))}}a.PI=3.1415927,a.PI2=2*a.PI,a.radiansToDegrees=180/a.PI,a.radDeg=a.radiansToDegrees,a.degreesToRadians=a.PI/180,a.degRad=a.degreesToRadians,t.MathUtils=a;class s{apply(t,e,a){return t+(e-t)*this.applyInternal(a)}}t.Interpolation=s;class i extends s{constructor(t){super(),this.power=2,this.power=t}applyInternal(t){return t<=.5?Math.pow(2*t,this.power)/2:Math.pow(2*(t-1),this.power)/(this.power%2==0?-2:2)+1}}t.Pow=i;t.PowOut=class extends i{constructor(t){super(t)}applyInternal(t){return Math.pow(t-1,this.power)*(this.power%2==0?-1:1)+1}};class n{static arrayCopy(t,e,a,s,i){for(let n=e,r=s;n=e?t:n.setArraySize(t,e,a)}static newArray(t,e){let a=new Array(t);for(let s=0;s0?this.items.pop():this.instantiator()}free(t){t.reset&&t.reset(),this.items.push(t)}freeAll(t){for(let e=0;ethis.maxDelta&&(this.delta=this.maxDelta),this.lastTime=t,this.frameCount++,this.frameTime>1&&(this.framesPerSecond=this.frameCount/this.frameTime,this.frameTime=0,this.frameCount=0)}};t.WindowedMean=class{constructor(t=32){this.addedValues=0,this.lastValue=0,this.mean=0,this.dirty=!0,this.values=new Array(t)}hasEnoughData(){return this.addedValues>=this.values.length}addValue(t){this.addedValuesthis.values.length-1&&(this.lastValue=0),this.dirty=!0}getMean(){if(this.hasEnoughData()){if(this.dirty){let t=0;for(let e=0;e{var t;Math.fround||(Math.fround=(t=new Float32Array(1),function(e){return t[0]=e,t[0]}))})(),function(t){class e{constructor(t){if(null==t)throw new Error("name cannot be null.");this.name=t}}t.Attachment=e;class a extends e{constructor(t){super(t),this.id=(65535&a.nextID++)<<11,this.worldVerticesLength=0,this.deformAttachment=this}computeWorldVertices(t,e,a,s,i,n){a=i+(a>>1)*n;let r=t.bone.skeleton,l=t.deform,o=this.vertices,h=this.bones;if(null==h){l.length>0&&(o=l);let r=t.bone,h=r.worldX,d=r.worldY,u=r.a,c=r.b,f=r.c,m=r.d;for(let t=e,r=i;ra)return i;for(var s=512;a>s;)s<<=1;for(var n=new Uint8Array(s),o=0;r>o;++o)n[o]=i[o];return this.buffer=n},getByte:function(){for(var a=this.pos;this.bufferLength<=a;){if(this.eof)return null;this.readBlock()}return this.buffer[this.pos++]},getBytes:function(a){var i=this.pos;if(a){this.ensureBuffer(i+a);for(var r=i+a;!this.eof&&this.bufferLengths&&(r=s)}else{for(;!this.eof;)this.readBlock();r=this.bufferLength}return this.pos=r,this.buffer.subarray(i,r)},lookChar:function(){for(var a=this.pos;this.bufferLength<=a;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos])},getChar:function(){for(var a=this.pos;this.bufferLength<=a;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos++])},makeSubStream:function(a,i,r){for(var s=a+i;this.bufferLength<=s&&!this.eof;)this.readBlock();return new Stream(this.buffer,a,i,r)},skip:function(a){a||(a=1),this.pos+=a},reset:function(){this.pos=0}},t}(),FlateStream=function(){function t(a){throw new Error(a)}function e(a){var i=0,r=a[i++],s=a[i++];-1!=r&&-1!=s||t("Invalid header in flate stream"),8!=(15&r)&&t("Unknown compression method in flate stream"),((r<<8)+s)%31!=0&&t("Bad FCHECK in flate stream"),32&s&&t("FDICT bit set in flate stream"),this.bytes=a,this.bytesPos=2,this.codeSize=0,this.codeBuf=0,DecodeStream.call(this)}var a=new Uint32Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),i=new Uint32Array([3,4,5,6,7,8,9,10,65547,65549,65551,65553,131091,131095,131099,131103,196643,196651,196659,196667,262211,262227,262243,262259,327811,327843,327875,327907,258,258,258]),r=new Uint32Array([1,2,3,4,65541,65543,131081,131085,196625,196633,262177,262193,327745,327777,393345,393409,459009,459137,524801,525057,590849,591361,657409,658433,724993,727041,794625,798721,868353,876545]),s=[new Uint32Array([459008,524368,524304,524568,459024,524400,524336,590016,459016,524384,524320,589984,524288,524416,524352,590048,459012,524376,524312,589968,459028,524408,524344,590032,459020,524392,524328,59e4,524296,524424,524360,590064,459010,524372,524308,524572,459026,524404,524340,590024,459018,524388,524324,589992,524292,524420,524356,590056,459014,524380,524316,589976,459030,524412,524348,590040,459022,524396,524332,590008,524300,524428,524364,590072,459009,524370,524306,524570,459025,524402,524338,590020,459017,524386,524322,589988,524290,524418,524354,590052,459013,524378,524314,589972,459029,524410,524346,590036,459021,524394,524330,590004,524298,524426,524362,590068,459011,524374,524310,524574,459027,524406,524342,590028,459019,524390,524326,589996,524294,524422,524358,590060,459015,524382,524318,589980,459031,524414,524350,590044,459023,524398,524334,590012,524302,524430,524366,590076,459008,524369,524305,524569,459024,524401,524337,590018,459016,524385,524321,589986,524289,524417,524353,590050,459012,524377,524313,589970,459028,524409,524345,590034,459020,524393,524329,590002,524297,524425,524361,590066,459010,524373,524309,524573,459026,524405,524341,590026,459018,524389,524325,589994,524293,524421,524357,590058,459014,524381,524317,589978,459030,524413,524349,590042,459022,524397,524333,590010,524301,524429,524365,590074,459009,524371,524307,524571,459025,524403,524339,590022,459017,524387,524323,589990,524291,524419,524355,590054,459013,524379,524315,589974,459029,524411,524347,590038,459021,524395,524331,590006,524299,524427,524363,590070,459011,524375,524311,524575,459027,524407,524343,590030,459019,524391,524327,589998,524295,524423,524359,590062,459015,524383,524319,589982,459031,524415,524351,590046,459023,524399,524335,590014,524303,524431,524367,590078,459008,524368,524304,524568,459024,524400,524336,590017,459016,524384,524320,589985,524288,524416,524352,590049,459012,524376,524312,589969,459028,524408,524344,590033,459020,524392,524328,590001,524296,524424,524360,590065,459010,524372,524308,524572,459026,524404,524340,590025,459018,524388,524324,589993,524292,524420,524356,590057,459014,524380,524316,589977,459030,524412,524348,590041,459022,524396,524332,590009,524300,524428,524364,590073,459009,524370,524306,524570,459025,524402,524338,590021,459017,524386,524322,589989,524290,524418,524354,590053,459013,524378,524314,589973,459029,524410,524346,590037,459021,524394,524330,590005,524298,524426,524362,590069,459011,524374,524310,524574,459027,524406,524342,590029,459019,524390,524326,589997,524294,524422,524358,590061,459015,524382,524318,589981,459031,524414,524350,590045,459023,524398,524334,590013,524302,524430,524366,590077,459008,524369,524305,524569,459024,524401,524337,590019,459016,524385,524321,589987,524289,524417,524353,590051,459012,524377,524313,589971,459028,524409,524345,590035,459020,524393,524329,590003,524297,524425,524361,590067,459010,524373,524309,524573,459026,524405,524341,590027,459018,524389,524325,589995,524293,524421,524357,590059,459014,524381,524317,589979,459030,524413,524349,590043,459022,524397,524333,590011,524301,524429,524365,590075,459009,524371,524307,524571,459025,524403,524339,590023,459017,524387,524323,589991,524291,524419,524355,590055,459013,524379,524315,589975,459029,524411,524347,590039,459021,524395,524331,590007,524299,524427,524363,590071,459011,524375,524311,524575,459027,524407,524343,590031,459019,524391,524327,589999,524295,524423,524359,590063,459015,524383,524319,589983,459031,524415,524351,590047,459023,524399,524335,590015,524303,524431,524367,590079]),9],n=[new Uint32Array([327680,327696,327688,327704,327684,327700,327692,327708,327682,327698,327690,327706,327686,327702,327694,0,327681,327697,327689,327705,327685,327701,327693,327709,327683,327699,327691,327707,327687,327703,327695,0]),5];return e.prototype=Object.create(DecodeStream.prototype),e.prototype.getBits=function(a){for(var i,r=this.codeSize,s=this.codeBuf,n=this.bytes,o=this.bytesPos;a>r;)void 0===(i=n[o++])&&t("Bad encoding in flate stream"),s|=i<>a,this.codeSize=r-=a,this.bytesPos=o,i},e.prototype.getCode=function(a){for(var i=a[0],r=a[1],s=this.codeSize,n=this.codeBuf,o=this.bytes,h=this.bytesPos;r>s;){var f;void 0===(f=o[h++])&&t("Bad encoding in flate stream"),n|=f<>16,l=65535&d;return(0==s||c>s||0==c)&&t("Bad encoding in flate stream"),this.codeBuf=n>>c,this.codeSize=s-c,this.bytesPos=h,l},e.prototype.generateHuffmanTable=function(a){for(var i=a.length,r=0,s=0;i>s;++s)a[s]>r&&(r=a[s]);for(var n=1<=h;++h,f<<=1,d<<=1)for(var c=0;i>c;++c)if(a[c]==h){var l=0,u=f;for(s=0;h>s;++s)l=l<<1|1&u,u>>=1;for(s=l;n>s;s+=d)o[s]=h<<16|c;++f}return[o,r]},e.prototype.readBlock=function(){function e(a,i,r,s,n){for(var o=a.getBits(r)+s;o-- >0;)i[p++]=n}var o=this.getBits(3);if(1&o&&(this.eof=!0),0!=(o>>=1)){var h,f;if(1==o)h=s,f=n;else if(2==o){for(var d=this.getBits(5)+257,c=this.getBits(5)+1,l=this.getBits(4)+4,u=Array(a.length),p=0;l>p;)u[a[p++]]=this.getBits(3);for(var g=this.generateHuffmanTable(u),m=0,y=(p=0,d+c),v=new Array(y);y>p;){var b=this.getCode(g);16==b?e(this,v,2,3,m):17==b?e(this,v,3,3,m=0):18==b?e(this,v,7,11,m=0):v[p++]=m=b}h=this.generateHuffmanTable(v.slice(0,d)),f=this.generateHuffmanTable(v.slice(d,y))}else t("Unknown block type in flate stream");for(var w=(L=this.buffer)?L.length:0,B=this.bufferLength;;){var T=this.getCode(h);if(256>T)B+1>=w&&(w=(L=this.ensureBuffer(B+1)).length),L[B++]=T;else{if(256==T)return void(this.bufferLength=B);var I=(T=i[T-=257])>>16;I>0&&(I=this.getBits(I));m=(65535&T)+I;T=this.getCode(f),(I=(T=r[T])>>16)>0&&(I=this.getBits(I));var U=(65535&T)+I;B+m>=w&&(w=(L=this.ensureBuffer(B+m)).length);for(var D=0;m>D;++D,++B)L[B]=L[B-U]}}}else{var k,A=this.bytes,C=this.bytesPos;void 0===(k=A[C++])&&t("Bad block header in flate stream");var S=k;void 0===(k=A[C++])&&t("Bad block header in flate stream"),S|=k<<8,void 0===(k=A[C++])&&t("Bad block header in flate stream");var P=k;void 0===(k=A[C++])&&t("Bad block header in flate stream"),(P|=k<<8)!=(65535&~S)&&t("Bad uncompressed block length in flate stream"),this.codeBuf=0,this.codeSize=0;var M=this.bufferLength,L=this.ensureBuffer(M+S),x=M+S;this.bufferLength=x;for(var N=M;x>N;++N){if(void 0===(k=A[C++])){this.eof=!0;break}L[N]=k}this.bytesPos=C}},e}();(function(){var a;a=function(){function t(a){var i,r,s,n,o,h,f,d,c,l,u,p,g;for(this.data=a,this.pos=8,this.palette=[],this.imgData=[],this.transparency={},this.animation=null,this.text={},o=null;;){switch(i=this.readUInt32(),d=function(){var a,i;for(i=[],a=0;4>a;++a)i.push(String.fromCharCode(this.data[this.pos++]));return i}.call(this).join("")){case"IHDR":if(this.width=this.readUInt32(),this.height=this.readUInt32(),this.bits=this.data[this.pos++],this.colorType=this.data[this.pos++],this.compressionMethod=this.data[this.pos++],this.filterMethod=this.data[this.pos++],this.interlaceMethod=this.data[this.pos++],0!=this.interlaceMethod)throw new Error("Invalid interlaceMethod: "+this.interlaceMethod);break;case"acTL":this.animation={numFrames:this.readUInt32(),numPlays:this.readUInt32()||1/0,frames:[]};break;case"PLTE":this.palette=this.read(i);break;case"fcTL":o&&this.animation.frames.push(o),this.pos+=4,o={width:this.readUInt32(),height:this.readUInt32(),xOffset:this.readUInt32(),yOffset:this.readUInt32()},n=this.readUInt16(),s=this.readUInt16()||100,o.delay=1e3*n/s,o.disposeOp=this.data[this.pos++],o.blendOp=this.data[this.pos++],o.data=[];break;case"IDAT":case"fdAT":for("fdAT"===d&&(this.pos+=4,i-=4),a=(null!=o?o.data:void 0)||this.imgData,u=0;i>=0?i>u:u>i;i>=0?++u:--u)a.push(this.data[this.pos++]);break;case"tRNS":switch(this.transparency={},this.colorType){case 3:if(this.transparency.indexed=this.read(i),(c=255-this.transparency.indexed.length)>0)for(p=0;c>=0?c>p:p>c;c>=0?++p:--p)this.transparency.indexed.push(255);break;case 0:this.transparency.grayscale=this.read(i)[0];break;case 2:this.transparency.rgb=this.read(i)}break;case"tEXt":h=(l=this.read(i)).indexOf(0),f=String.fromCharCode.apply(String,l.slice(0,h)),this.text[f]=String.fromCharCode.apply(String,l.slice(h+1));break;case"IEND":return o&&this.animation.frames.push(o),this.colors=function(){switch(this.colorType){case 0:case 3:case 4:return 1;case 2:case 6:return 3}}.call(this),this.hasAlphaChannel=4===(g=this.colorType)||6===g,r=this.colors+(this.hasAlphaChannel?1:0),this.pixelBitlength=this.bits*r,this.colorSpace=function(){switch(this.colors){case 1:return"DeviceGray";case 3:return"DeviceRGB"}}.call(this),void(this.imgData=new Uint8Array(this.imgData));default:this.pos+=i}if(this.pos+=4,this.pos>this.data.length)throw new Error("Incomplete or corrupt PNG file")}}return t.load=function(a,i){var r;return"function"==typeof canvas&&(i=canvas),(r=new XMLHttpRequest).open("GET",a,!0),r.responseType="arraybuffer",r.onload=function(){var s;return(s=new t(new Uint8Array(r.response||r.mozResponseArrayBuffer))).url=a,"function"==typeof i?i(s):void 0},r.send(null)},0,1,2,0,1,t.prototype.read=function(a){var i,r;for(r=[],i=0;a>=0?a>i:i>a;a>=0?++i:--i)r.push(this.data[this.pos++]);return r},t.prototype.readUInt32=function(){return this.data[this.pos++]<<24|this.data[this.pos++]<<16|this.data[this.pos++]<<8|this.data[this.pos++]},t.prototype.readUInt16=function(){return this.data[this.pos++]<<8|this.data[this.pos++]},t.prototype.decodePixels=function(a){var i,r,s,n,o,h,f,d,c,l,u,p,g,m,y,v,b,w,B,T,I,U,D;if(null==a&&(a=this.imgData),0===a.length)return new Uint8Array(0);for(a=(a=new FlateStream(a)).getBytes(),v=(p=this.pixelBitlength/8)*this.width,g=new Uint8Array(v*this.height),h=a.length,y=0,m=0,r=0;h>m;){switch(a[m++]){case 0:for(n=B=0;v>B;n=B+=1)g[r++]=a[m++];break;case 1:for(n=T=0;v>T;n=T+=1)i=a[m++],o=p>n?0:g[r-p],g[r++]=(i+o)%256;break;case 2:for(n=I=0;v>I;n=I+=1)i=a[m++],s=(n-n%p)/p,b=y&&g[(y-1)*v+s*p+n%p],g[r++]=(b+i)%256;break;case 3:for(n=U=0;v>U;n=U+=1)i=a[m++],s=(n-n%p)/p,o=p>n?0:g[r-p],b=y&&g[(y-1)*v+s*p+n%p],g[r++]=(i+Math.floor((o+b)/2))%256;break;case 4:for(n=D=0;v>D;n=D+=1)i=a[m++],s=(n-n%p)/p,o=p>n?0:g[r-p],0===y?b=w=0:(b=g[(y-1)*v+s*p+n%p],w=s&&g[(y-1)*v+(s-1)*p+n%p]),f=o+b-w,d=Math.abs(f-o),l=Math.abs(f-b),u=Math.abs(f-w),c=l>=d&&u>=d?o:u>=l?b:w,g[r++]=(i+c)%256;break;default:throw new Error("Invalid filter algorithm: "+a[m-1])}y++}return g},t.prototype.decodePalette=function(){var a,i,r,s,n,o,h,f,d,c;for(r=this.palette,o=this.transparency.indexed||[],c=4*r.length/3,n=new Uint8Array(c),s=0,r.length,a=0,i=h=0,f=r.length;f>h;i=h+=3)n[s++]=r[i],n[s++]=r[i+1],n[s++]=r[i+2],n[s++]=null!=(d=o[a++])?d:255;return n},t.prototype.getImageData=function(){var a=new self.ImageData(this.width,this.height);return this.copyToImageData(a,this.decodePixels()),a},t.prototype.getImageDataBuffer=function(){var a;return a=self.Uint8ClampedArray?new self.Uint8ClampedArray(this.width*this.height*4):new self.Uint8Array(this.width*this.height*4),this.copyToImageData(a,this.decodePixels()),a},t.prototype.copyToImageData=function(a,i){var r,s,n,o,h,f,d,c,l,u,p;if(s=this.colors,l=null,r=this.hasAlphaChannel,this.palette.length&&(l=null!=(p=this._decodedPalette)?p:this._decodedPalette=this.decodePalette(),s=4,r=!0),c=(n=a.data||a).length,h=l||i,o=f=0,1===s)for(;c>o;)d=l?4*i[o/4]:f,u=h[d++],n[o++]=u,n[o++]=u,n[o++]=u,n[o++]=r?h[d++]:255,f=d;else for(;c>o;)d=l?4*i[o/4]:f,n[o++]=h[d++],n[o++]=h[d++],n[o++]=h[d++],n[o++]=r?h[d++]:255,f=d},t.prototype.decode=function(){var a;return a=new Uint8Array(this.width*this.height*4),this.copyToImageData(a,this.decodePixels()),a},t.prototype.decodeFrames=function(a){var i,r,s,n,o,h,f,d;if(this.animation){for(d=[],r=o=0,h=(f=this.animation.frames).length;h>o;r=++o)i=f[r],s=a.createImageData(i.width,i.height),n=this.decodePixels(new Uint8Array(i.data)),this.copyToImageData(s,n),i.imageData=s,d.push(i.image=(void 0)(s));return d}},t}(),this.PNG=a}).call(this),onmessage=function(a){var i=a.data;switch(i.type){case"load":loadImage2(i)}};var canUseImageData=!1;testCanImageData(); \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/min/workerloader.min.js b/examples/layaair/frontend/bin/libs/min/workerloader.min.js new file mode 100644 index 0000000..655eda3 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/min/workerloader.min.js @@ -0,0 +1 @@ +var createImageBitmapOK=!!self.createImageBitmap;onmessage=function(e){loadImage2(e.data),isSet||(isSet=!0,setInterval(workerloop,1e3))};var isSet=!0;function workerloop(){myTrace("png:workerloop")}var enableTrace=!1,ifShowTraceToMain=!1;function myTrace(e){enableTrace&&(console.log("png:"+e),ifShowTraceToMain&&showMsgToMain(e))}function loadImage2(e){var a,o=!1;(a=new XMLHttpRequest).open("GET",e,!0),a.responseType="arraybuffer",myTrace("load:"+e),a.onload=function(){var t=a.response||a.mozResponseArrayBuffer;(myTrace("onload:"+e),200!=a.status&&0!=a.status||t.byteLength<10)?o||(o=!0,pngFail(e,"loadFail from onload"+a.status)):doCreateImageBitmap(new Uint8Array(t),e)},a.onerror=function(a){pngFail(e,"loadFail")},a.send(null)}function doCreateImageBitmap(e,a){try{var o=getTimeNow();e=new self.Blob([e],{type:"image/png"}),self.createImageBitmap(e).then((function(e){var t={};t.url=a,t.imageBitmap=e,t.dataType="imageBitmap",t.startTime=o,t.decodeTime=getTimeNow()-o,t.sendTime=getTimeNow(),myTrace("png:Decode By createImageBitmap,"+t.decodeTime,a),t.type="Image",postMessage(t,[t.imageBitmap])})).catch((function(e){showMsgToMain("catch e:"+e),pngFail(a,"parse fail"+e+":ya")}))}catch(e){pngFail(a,"parse fail"+e.toString()+":ya")}}function getTimeNow(){return(new Date).getTime()}function disableWorker(e){var a={};a.url=url,a.imagedata=null,a.type="Disable",a.msg=e,postMessage(a)}function pngFail(e,a){var o={};o.url=e,o.imagedata=null,o.type="Image",o.msg=a,console.log("png:"+a+" "+e),postMessage(o)}function showMsgToMain(e){var a={type:"Msg"};a.msg=e,postMessage(a)} \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/spine-core-3.7.js b/examples/layaair/frontend/bin/libs/spine-core-3.7.js new file mode 100644 index 0000000..0ab8989 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/spine-core-3.7.js @@ -0,0 +1,6750 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated January 1, 2020. Replaces all prior versions. + * + * Copyright (c) 2013-2020, Esoteric Software LLC + * + * Integration of the Spine Runtimes into software or otherwise creating + * derivative works of the Spine Runtimes is permitted under the terms and + * conditions of Section 2 of the Spine Editor License Agreement: + * http://esotericsoftware.com/spine-editor-license + * + * Otherwise, it is permitted to integrate the Spine Runtimes into software + * or otherwise create derivative works of the Spine Runtimes (collectively, + * "Products"), provided that each user of the Products must obtain their own + * Spine Editor license and redistribution of the Products in any form must + * include this license and copyright notice. + * + * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, + * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ +var spine; +(function (spine) { + class Animation { + constructor(name, timelines, duration) { + if (name == null) + throw new Error("name cannot be null."); + if (timelines == null) + throw new Error("timelines cannot be null."); + this.name = name; + this.timelines = timelines; + this.duration = duration; + } + apply(skeleton, lastTime, time, loop, events, alpha, blend, direction) { + if (skeleton == null) + throw new Error("skeleton cannot be null."); + if (loop && this.duration != 0) { + time %= this.duration; + if (lastTime > 0) + lastTime %= this.duration; + } + let timelines = this.timelines; + for (let i = 0, n = timelines.length; i < n; i++) + timelines[i].apply(skeleton, lastTime, time, events, alpha, blend, direction); + } + static binarySearch(values, target, step = 1) { + let low = 0; + let high = values.length / step - 2; + if (high == 0) + return step; + let current = high >>> 1; + while (true) { + if (values[(current + 1) * step] <= target) + low = current + 1; + else + high = current; + if (low == high) + return (low + 1) * step; + current = (low + high) >>> 1; + } + } + static linearSearch(values, target, step) { + for (let i = 0, last = values.length - step; i <= last; i += step) + if (values[i] > target) + return i; + return -1; + } + } + spine.Animation = Animation; + let MixBlend; + (function (MixBlend) { + MixBlend[MixBlend["setup"] = 0] = "setup"; + MixBlend[MixBlend["first"] = 1] = "first"; + MixBlend[MixBlend["replace"] = 2] = "replace"; + MixBlend[MixBlend["add"] = 3] = "add"; + })(MixBlend = spine.MixBlend || (spine.MixBlend = {})); + let MixDirection; + (function (MixDirection) { + MixDirection[MixDirection["in"] = 0] = "in"; + MixDirection[MixDirection["out"] = 1] = "out"; + })(MixDirection = spine.MixDirection || (spine.MixDirection = {})); + let TimelineType; + (function (TimelineType) { + TimelineType[TimelineType["rotate"] = 0] = "rotate"; + TimelineType[TimelineType["translate"] = 1] = "translate"; + TimelineType[TimelineType["scale"] = 2] = "scale"; + TimelineType[TimelineType["shear"] = 3] = "shear"; + TimelineType[TimelineType["attachment"] = 4] = "attachment"; + TimelineType[TimelineType["color"] = 5] = "color"; + TimelineType[TimelineType["deform"] = 6] = "deform"; + TimelineType[TimelineType["event"] = 7] = "event"; + TimelineType[TimelineType["drawOrder"] = 8] = "drawOrder"; + TimelineType[TimelineType["ikConstraint"] = 9] = "ikConstraint"; + TimelineType[TimelineType["transformConstraint"] = 10] = "transformConstraint"; + TimelineType[TimelineType["pathConstraintPosition"] = 11] = "pathConstraintPosition"; + TimelineType[TimelineType["pathConstraintSpacing"] = 12] = "pathConstraintSpacing"; + TimelineType[TimelineType["pathConstraintMix"] = 13] = "pathConstraintMix"; + TimelineType[TimelineType["twoColor"] = 14] = "twoColor"; + })(TimelineType = spine.TimelineType || (spine.TimelineType = {})); + class CurveTimeline { + constructor(frameCount) { + if (frameCount <= 0) + throw new Error("frameCount must be > 0: " + frameCount); + this.curves = spine.Utils.newFloatArray((frameCount - 1) * CurveTimeline.BEZIER_SIZE); + } + getFrameCount() { + return this.curves.length / CurveTimeline.BEZIER_SIZE + 1; + } + setLinear(frameIndex) { + this.curves[frameIndex * CurveTimeline.BEZIER_SIZE] = CurveTimeline.LINEAR; + } + setStepped(frameIndex) { + this.curves[frameIndex * CurveTimeline.BEZIER_SIZE] = CurveTimeline.STEPPED; + } + getCurveType(frameIndex) { + let index = frameIndex * CurveTimeline.BEZIER_SIZE; + if (index == this.curves.length) + return CurveTimeline.LINEAR; + let type = this.curves[index]; + if (type == CurveTimeline.LINEAR) + return CurveTimeline.LINEAR; + if (type == CurveTimeline.STEPPED) + return CurveTimeline.STEPPED; + return CurveTimeline.BEZIER; + } + setCurve(frameIndex, cx1, cy1, cx2, cy2) { + let tmpx = (-cx1 * 2 + cx2) * 0.03, tmpy = (-cy1 * 2 + cy2) * 0.03; + let dddfx = ((cx1 - cx2) * 3 + 1) * 0.006, dddfy = ((cy1 - cy2) * 3 + 1) * 0.006; + let ddfx = tmpx * 2 + dddfx, ddfy = tmpy * 2 + dddfy; + let dfx = cx1 * 0.3 + tmpx + dddfx * 0.16666667, dfy = cy1 * 0.3 + tmpy + dddfy * 0.16666667; + let i = frameIndex * CurveTimeline.BEZIER_SIZE; + let curves = this.curves; + curves[i++] = CurveTimeline.BEZIER; + let x = dfx, y = dfy; + for (let n = i + CurveTimeline.BEZIER_SIZE - 1; i < n; i += 2) { + curves[i] = x; + curves[i + 1] = y; + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + x += dfx; + y += dfy; + } + } + getCurvePercent(frameIndex, percent) { + percent = spine.MathUtils.clamp(percent, 0, 1); + let curves = this.curves; + let i = frameIndex * CurveTimeline.BEZIER_SIZE; + let type = curves[i]; + if (type == CurveTimeline.LINEAR) + return percent; + if (type == CurveTimeline.STEPPED) + return 0; + i++; + let x = 0; + for (let start = i, n = i + CurveTimeline.BEZIER_SIZE - 1; i < n; i += 2) { + x = curves[i]; + if (x >= percent) { + let prevX, prevY; + if (i == start) { + prevX = 0; + prevY = 0; + } + else { + prevX = curves[i - 2]; + prevY = curves[i - 1]; + } + return prevY + (curves[i + 1] - prevY) * (percent - prevX) / (x - prevX); + } + } + let y = curves[i - 1]; + return y + (1 - y) * (percent - x) / (1 - x); + } + } + CurveTimeline.LINEAR = 0; + CurveTimeline.STEPPED = 1; + CurveTimeline.BEZIER = 2; + CurveTimeline.BEZIER_SIZE = 10 * 2 - 1; + spine.CurveTimeline = CurveTimeline; + class RotateTimeline extends CurveTimeline { + constructor(frameCount) { + super(frameCount); + this.frames = spine.Utils.newFloatArray(frameCount << 1); + } + getPropertyId() { + return (TimelineType.rotate << 24) + this.boneIndex; + } + setFrame(frameIndex, time, degrees) { + frameIndex <<= 1; + this.frames[frameIndex] = time; + this.frames[frameIndex + RotateTimeline.ROTATION] = degrees; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let frames = this.frames; + let bone = skeleton.bones[this.boneIndex]; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + bone.rotation = bone.data.rotation; + return; + case MixBlend.first: + let r = bone.data.rotation - bone.rotation; + bone.rotation += (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha; + } + return; + } + if (time >= frames[frames.length - RotateTimeline.ENTRIES]) { + let r = frames[frames.length + RotateTimeline.PREV_ROTATION]; + switch (blend) { + case MixBlend.setup: + bone.rotation = bone.data.rotation + r * alpha; + break; + case MixBlend.first: + case MixBlend.replace: + r += bone.data.rotation - bone.rotation; + r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; + case MixBlend.add: + bone.rotation += r * alpha; + } + return; + } + let frame = Animation.binarySearch(frames, time, RotateTimeline.ENTRIES); + let prevRotation = frames[frame + RotateTimeline.PREV_ROTATION]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime)); + let r = frames[frame + RotateTimeline.ROTATION] - prevRotation; + r = prevRotation + (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * percent; + switch (blend) { + case MixBlend.setup: + bone.rotation = bone.data.rotation + (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha; + break; + case MixBlend.first: + case MixBlend.replace: + r += bone.data.rotation - bone.rotation; + case MixBlend.add: + bone.rotation += (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha; + } + } + } + RotateTimeline.ENTRIES = 2; + RotateTimeline.PREV_TIME = -2; + RotateTimeline.PREV_ROTATION = -1; + RotateTimeline.ROTATION = 1; + spine.RotateTimeline = RotateTimeline; + class TranslateTimeline extends CurveTimeline { + constructor(frameCount) { + super(frameCount); + this.frames = spine.Utils.newFloatArray(frameCount * TranslateTimeline.ENTRIES); + } + getPropertyId() { + return (TimelineType.translate << 24) + this.boneIndex; + } + setFrame(frameIndex, time, x, y) { + frameIndex *= TranslateTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + TranslateTimeline.X] = x; + this.frames[frameIndex + TranslateTimeline.Y] = y; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let frames = this.frames; + let bone = skeleton.bones[this.boneIndex]; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + bone.x = bone.data.x; + bone.y = bone.data.y; + return; + case MixBlend.first: + bone.x += (bone.data.x - bone.x) * alpha; + bone.y += (bone.data.y - bone.y) * alpha; + } + return; + } + let x = 0, y = 0; + if (time >= frames[frames.length - TranslateTimeline.ENTRIES]) { + x = frames[frames.length + TranslateTimeline.PREV_X]; + y = frames[frames.length + TranslateTimeline.PREV_Y]; + } + else { + let frame = Animation.binarySearch(frames, time, TranslateTimeline.ENTRIES); + x = frames[frame + TranslateTimeline.PREV_X]; + y = frames[frame + TranslateTimeline.PREV_Y]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / TranslateTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TranslateTimeline.PREV_TIME] - frameTime)); + x += (frames[frame + TranslateTimeline.X] - x) * percent; + y += (frames[frame + TranslateTimeline.Y] - y) * percent; + } + switch (blend) { + case MixBlend.setup: + bone.x = bone.data.x + x * alpha; + bone.y = bone.data.y + y * alpha; + break; + case MixBlend.first: + case MixBlend.replace: + bone.x += (bone.data.x + x - bone.x) * alpha; + bone.y += (bone.data.y + y - bone.y) * alpha; + break; + case MixBlend.add: + bone.x += x * alpha; + bone.y += y * alpha; + } + } + } + TranslateTimeline.ENTRIES = 3; + TranslateTimeline.PREV_TIME = -3; + TranslateTimeline.PREV_X = -2; + TranslateTimeline.PREV_Y = -1; + TranslateTimeline.X = 1; + TranslateTimeline.Y = 2; + spine.TranslateTimeline = TranslateTimeline; + class ScaleTimeline extends TranslateTimeline { + constructor(frameCount) { + super(frameCount); + } + getPropertyId() { + return (TimelineType.scale << 24) + this.boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let frames = this.frames; + let bone = skeleton.bones[this.boneIndex]; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + bone.scaleX = bone.data.scaleX; + bone.scaleY = bone.data.scaleY; + return; + case MixBlend.first: + bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha; + bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha; + } + return; + } + let x = 0, y = 0; + if (time >= frames[frames.length - ScaleTimeline.ENTRIES]) { + x = frames[frames.length + ScaleTimeline.PREV_X] * bone.data.scaleX; + y = frames[frames.length + ScaleTimeline.PREV_Y] * bone.data.scaleY; + } + else { + let frame = Animation.binarySearch(frames, time, ScaleTimeline.ENTRIES); + x = frames[frame + ScaleTimeline.PREV_X]; + y = frames[frame + ScaleTimeline.PREV_Y]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / ScaleTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ScaleTimeline.PREV_TIME] - frameTime)); + x = (x + (frames[frame + ScaleTimeline.X] - x) * percent) * bone.data.scaleX; + y = (y + (frames[frame + ScaleTimeline.Y] - y) * percent) * bone.data.scaleY; + } + if (alpha == 1) { + if (blend == MixBlend.add) { + bone.scaleX += x - bone.data.scaleX; + bone.scaleY += y - bone.data.scaleY; + } + else { + bone.scaleX = x; + bone.scaleY = y; + } + } + else { + let bx = 0, by = 0; + if (direction == MixDirection.out) { + switch (blend) { + case MixBlend.setup: + bx = bone.data.scaleX; + by = bone.data.scaleY; + bone.scaleX = bx + (Math.abs(x) * spine.MathUtils.signum(bx) - bx) * alpha; + bone.scaleY = by + (Math.abs(y) * spine.MathUtils.signum(by) - by) * alpha; + break; + case MixBlend.first: + case MixBlend.replace: + bx = bone.scaleX; + by = bone.scaleY; + bone.scaleX = bx + (Math.abs(x) * spine.MathUtils.signum(bx) - bx) * alpha; + bone.scaleY = by + (Math.abs(y) * spine.MathUtils.signum(by) - by) * alpha; + break; + case MixBlend.add: + bx = bone.scaleX; + by = bone.scaleY; + bone.scaleX = bx + (Math.abs(x) * spine.MathUtils.signum(bx) - bone.data.scaleX) * alpha; + bone.scaleY = by + (Math.abs(y) * spine.MathUtils.signum(by) - bone.data.scaleY) * alpha; + } + } + else { + switch (blend) { + case MixBlend.setup: + bx = Math.abs(bone.data.scaleX) * spine.MathUtils.signum(x); + by = Math.abs(bone.data.scaleY) * spine.MathUtils.signum(y); + bone.scaleX = bx + (x - bx) * alpha; + bone.scaleY = by + (y - by) * alpha; + break; + case MixBlend.first: + case MixBlend.replace: + bx = Math.abs(bone.scaleX) * spine.MathUtils.signum(x); + by = Math.abs(bone.scaleY) * spine.MathUtils.signum(y); + bone.scaleX = bx + (x - bx) * alpha; + bone.scaleY = by + (y - by) * alpha; + break; + case MixBlend.add: + bx = spine.MathUtils.signum(x); + by = spine.MathUtils.signum(y); + bone.scaleX = Math.abs(bone.scaleX) * bx + (x - Math.abs(bone.data.scaleX) * bx) * alpha; + bone.scaleY = Math.abs(bone.scaleY) * by + (y - Math.abs(bone.data.scaleY) * by) * alpha; + } + } + } + } + } + spine.ScaleTimeline = ScaleTimeline; + class ShearTimeline extends TranslateTimeline { + constructor(frameCount) { + super(frameCount); + } + getPropertyId() { + return (TimelineType.shear << 24) + this.boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let frames = this.frames; + let bone = skeleton.bones[this.boneIndex]; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + bone.shearX = bone.data.shearX; + bone.shearY = bone.data.shearY; + return; + case MixBlend.first: + bone.shearX += (bone.data.shearX - bone.shearX) * alpha; + bone.shearY += (bone.data.shearY - bone.shearY) * alpha; + } + return; + } + let x = 0, y = 0; + if (time >= frames[frames.length - ShearTimeline.ENTRIES]) { + x = frames[frames.length + ShearTimeline.PREV_X]; + y = frames[frames.length + ShearTimeline.PREV_Y]; + } + else { + let frame = Animation.binarySearch(frames, time, ShearTimeline.ENTRIES); + x = frames[frame + ShearTimeline.PREV_X]; + y = frames[frame + ShearTimeline.PREV_Y]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / ShearTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ShearTimeline.PREV_TIME] - frameTime)); + x = x + (frames[frame + ShearTimeline.X] - x) * percent; + y = y + (frames[frame + ShearTimeline.Y] - y) * percent; + } + switch (blend) { + case MixBlend.setup: + bone.shearX = bone.data.shearX + x * alpha; + bone.shearY = bone.data.shearY + y * alpha; + break; + case MixBlend.first: + case MixBlend.replace: + bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha; + bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha; + break; + case MixBlend.add: + bone.shearX += x * alpha; + bone.shearY += y * alpha; + } + } + } + spine.ShearTimeline = ShearTimeline; + class ColorTimeline extends CurveTimeline { + constructor(frameCount) { + super(frameCount); + this.frames = spine.Utils.newFloatArray(frameCount * ColorTimeline.ENTRIES); + } + getPropertyId() { + return (TimelineType.color << 24) + this.slotIndex; + } + setFrame(frameIndex, time, r, g, b, a) { + frameIndex *= ColorTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + ColorTimeline.R] = r; + this.frames[frameIndex + ColorTimeline.G] = g; + this.frames[frameIndex + ColorTimeline.B] = b; + this.frames[frameIndex + ColorTimeline.A] = a; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + let frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + slot.color.setFromColor(slot.data.color); + return; + case MixBlend.first: + let color = slot.color, setup = slot.data.color; + color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha, (setup.a - color.a) * alpha); + } + return; + } + let r = 0, g = 0, b = 0, a = 0; + if (time >= frames[frames.length - ColorTimeline.ENTRIES]) { + let i = frames.length; + r = frames[i + ColorTimeline.PREV_R]; + g = frames[i + ColorTimeline.PREV_G]; + b = frames[i + ColorTimeline.PREV_B]; + a = frames[i + ColorTimeline.PREV_A]; + } + else { + let frame = Animation.binarySearch(frames, time, ColorTimeline.ENTRIES); + r = frames[frame + ColorTimeline.PREV_R]; + g = frames[frame + ColorTimeline.PREV_G]; + b = frames[frame + ColorTimeline.PREV_B]; + a = frames[frame + ColorTimeline.PREV_A]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / ColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ColorTimeline.PREV_TIME] - frameTime)); + r += (frames[frame + ColorTimeline.R] - r) * percent; + g += (frames[frame + ColorTimeline.G] - g) * percent; + b += (frames[frame + ColorTimeline.B] - b) * percent; + a += (frames[frame + ColorTimeline.A] - a) * percent; + } + if (alpha == 1) + slot.color.set(r, g, b, a); + else { + let color = slot.color; + if (blend == MixBlend.setup) + color.setFromColor(slot.data.color); + color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha); + } + } + } + ColorTimeline.ENTRIES = 5; + ColorTimeline.PREV_TIME = -5; + ColorTimeline.PREV_R = -4; + ColorTimeline.PREV_G = -3; + ColorTimeline.PREV_B = -2; + ColorTimeline.PREV_A = -1; + ColorTimeline.R = 1; + ColorTimeline.G = 2; + ColorTimeline.B = 3; + ColorTimeline.A = 4; + spine.ColorTimeline = ColorTimeline; + class TwoColorTimeline extends CurveTimeline { + constructor(frameCount) { + super(frameCount); + this.frames = spine.Utils.newFloatArray(frameCount * TwoColorTimeline.ENTRIES); + } + getPropertyId() { + return (TimelineType.twoColor << 24) + this.slotIndex; + } + setFrame(frameIndex, time, r, g, b, a, r2, g2, b2) { + frameIndex *= TwoColorTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + TwoColorTimeline.R] = r; + this.frames[frameIndex + TwoColorTimeline.G] = g; + this.frames[frameIndex + TwoColorTimeline.B] = b; + this.frames[frameIndex + TwoColorTimeline.A] = a; + this.frames[frameIndex + TwoColorTimeline.R2] = r2; + this.frames[frameIndex + TwoColorTimeline.G2] = g2; + this.frames[frameIndex + TwoColorTimeline.B2] = b2; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + let frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + slot.color.setFromColor(slot.data.color); + slot.darkColor.setFromColor(slot.data.darkColor); + return; + case MixBlend.first: + let light = slot.color, dark = slot.darkColor, setupLight = slot.data.color, setupDark = slot.data.darkColor; + light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha, (setupLight.a - light.a) * alpha); + dark.add((setupDark.r - dark.r) * alpha, (setupDark.g - dark.g) * alpha, (setupDark.b - dark.b) * alpha, 0); + } + return; + } + let r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0; + if (time >= frames[frames.length - TwoColorTimeline.ENTRIES]) { + let i = frames.length; + r = frames[i + TwoColorTimeline.PREV_R]; + g = frames[i + TwoColorTimeline.PREV_G]; + b = frames[i + TwoColorTimeline.PREV_B]; + a = frames[i + TwoColorTimeline.PREV_A]; + r2 = frames[i + TwoColorTimeline.PREV_R2]; + g2 = frames[i + TwoColorTimeline.PREV_G2]; + b2 = frames[i + TwoColorTimeline.PREV_B2]; + } + else { + let frame = Animation.binarySearch(frames, time, TwoColorTimeline.ENTRIES); + r = frames[frame + TwoColorTimeline.PREV_R]; + g = frames[frame + TwoColorTimeline.PREV_G]; + b = frames[frame + TwoColorTimeline.PREV_B]; + a = frames[frame + TwoColorTimeline.PREV_A]; + r2 = frames[frame + TwoColorTimeline.PREV_R2]; + g2 = frames[frame + TwoColorTimeline.PREV_G2]; + b2 = frames[frame + TwoColorTimeline.PREV_B2]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / TwoColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TwoColorTimeline.PREV_TIME] - frameTime)); + r += (frames[frame + TwoColorTimeline.R] - r) * percent; + g += (frames[frame + TwoColorTimeline.G] - g) * percent; + b += (frames[frame + TwoColorTimeline.B] - b) * percent; + a += (frames[frame + TwoColorTimeline.A] - a) * percent; + r2 += (frames[frame + TwoColorTimeline.R2] - r2) * percent; + g2 += (frames[frame + TwoColorTimeline.G2] - g2) * percent; + b2 += (frames[frame + TwoColorTimeline.B2] - b2) * percent; + } + if (alpha == 1) { + slot.color.set(r, g, b, a); + slot.darkColor.set(r2, g2, b2, 1); + } + else { + let light = slot.color, dark = slot.darkColor; + if (blend == MixBlend.setup) { + light.setFromColor(slot.data.color); + dark.setFromColor(slot.data.darkColor); + } + light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha); + dark.add((r2 - dark.r) * alpha, (g2 - dark.g) * alpha, (b2 - dark.b) * alpha, 0); + } + } + } + TwoColorTimeline.ENTRIES = 8; + TwoColorTimeline.PREV_TIME = -8; + TwoColorTimeline.PREV_R = -7; + TwoColorTimeline.PREV_G = -6; + TwoColorTimeline.PREV_B = -5; + TwoColorTimeline.PREV_A = -4; + TwoColorTimeline.PREV_R2 = -3; + TwoColorTimeline.PREV_G2 = -2; + TwoColorTimeline.PREV_B2 = -1; + TwoColorTimeline.R = 1; + TwoColorTimeline.G = 2; + TwoColorTimeline.B = 3; + TwoColorTimeline.A = 4; + TwoColorTimeline.R2 = 5; + TwoColorTimeline.G2 = 6; + TwoColorTimeline.B2 = 7; + spine.TwoColorTimeline = TwoColorTimeline; + class AttachmentTimeline { + constructor(frameCount) { + this.frames = spine.Utils.newFloatArray(frameCount); + this.attachmentNames = new Array(frameCount); + } + getPropertyId() { + return (TimelineType.attachment << 24) + this.slotIndex; + } + getFrameCount() { + return this.frames.length; + } + setFrame(frameIndex, time, attachmentName) { + this.frames[frameIndex] = time; + this.attachmentNames[frameIndex] = attachmentName; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (direction == MixDirection.out && blend == MixBlend.setup) { + let attachmentName = slot.data.attachmentName; + slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName)); + return; + } + let frames = this.frames; + if (time < frames[0]) { + if (blend == MixBlend.setup || blend == MixBlend.first) { + let attachmentName = slot.data.attachmentName; + slot.setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName)); + } + return; + } + let frameIndex = 0; + if (time >= frames[frames.length - 1]) + frameIndex = frames.length - 1; + else + frameIndex = Animation.binarySearch(frames, time, 1) - 1; + let attachmentName = this.attachmentNames[frameIndex]; + skeleton.slots[this.slotIndex] + .setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName)); + } + } + spine.AttachmentTimeline = AttachmentTimeline; + let zeros = null; + class DeformTimeline extends CurveTimeline { + constructor(frameCount) { + super(frameCount); + this.frames = spine.Utils.newFloatArray(frameCount); + this.frameVertices = new Array(frameCount); + if (zeros == null) + zeros = spine.Utils.newFloatArray(64); + } + getPropertyId() { + return (TimelineType.deform << 27) + +this.attachment.id + this.slotIndex; + } + setFrame(frameIndex, time, vertices) { + this.frames[frameIndex] = time; + this.frameVertices[frameIndex] = vertices; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + let slotAttachment = slot.getAttachment(); + if (!(slotAttachment instanceof spine.VertexAttachment) || !slotAttachment.applyDeform(this.attachment)) + return; + let verticesArray = slot.attachmentVertices; + if (verticesArray.length == 0) + blend = MixBlend.setup; + let frameVertices = this.frameVertices; + let vertexCount = frameVertices[0].length; + let frames = this.frames; + if (time < frames[0]) { + let vertexAttachment = slotAttachment; + switch (blend) { + case MixBlend.setup: + verticesArray.length = 0; + return; + case MixBlend.first: + if (alpha == 1) { + verticesArray.length = 0; + break; + } + let vertices = spine.Utils.setArraySize(verticesArray, vertexCount); + if (vertexAttachment.bones == null) { + let setupVertices = vertexAttachment.vertices; + for (var i = 0; i < vertexCount; i++) + vertices[i] += (setupVertices[i] - vertices[i]) * alpha; + } + else { + alpha = 1 - alpha; + for (var i = 0; i < vertexCount; i++) + vertices[i] *= alpha; + } + } + return; + } + let vertices = spine.Utils.setArraySize(verticesArray, vertexCount); + if (time >= frames[frames.length - 1]) { + let lastVertices = frameVertices[frames.length - 1]; + if (alpha == 1) { + if (blend == MixBlend.add) { + let vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + let setupVertices = vertexAttachment.vertices; + for (let i = 0; i < vertexCount; i++) { + vertices[i] += lastVertices[i] - setupVertices[i]; + } + } + else { + for (let i = 0; i < vertexCount; i++) + vertices[i] += lastVertices[i]; + } + } + else { + spine.Utils.arrayCopy(lastVertices, 0, vertices, 0, vertexCount); + } + } + else { + switch (blend) { + case MixBlend.setup: { + let vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + let setupVertices = vertexAttachment.vertices; + for (let i = 0; i < vertexCount; i++) { + let setup = setupVertices[i]; + vertices[i] = setup + (lastVertices[i] - setup) * alpha; + } + } + else { + for (let i = 0; i < vertexCount; i++) + vertices[i] = lastVertices[i] * alpha; + } + break; + } + case MixBlend.first: + case MixBlend.replace: + for (let i = 0; i < vertexCount; i++) + vertices[i] += (lastVertices[i] - vertices[i]) * alpha; + case MixBlend.add: + let vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + let setupVertices = vertexAttachment.vertices; + for (let i = 0; i < vertexCount; i++) { + vertices[i] += (lastVertices[i] - setupVertices[i]) * alpha; + } + } + else { + for (let i = 0; i < vertexCount; i++) + vertices[i] += lastVertices[i] * alpha; + } + } + } + return; + } + let frame = Animation.binarySearch(frames, time); + let prevVertices = frameVertices[frame - 1]; + let nextVertices = frameVertices[frame]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime)); + if (alpha == 1) { + if (blend == MixBlend.add) { + let vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + let setupVertices = vertexAttachment.vertices; + for (let i = 0; i < vertexCount; i++) { + let prev = prevVertices[i]; + vertices[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i]; + } + } + else { + for (let i = 0; i < vertexCount; i++) { + let prev = prevVertices[i]; + vertices[i] += prev + (nextVertices[i] - prev) * percent; + } + } + } + else { + for (let i = 0; i < vertexCount; i++) { + let prev = prevVertices[i]; + vertices[i] = prev + (nextVertices[i] - prev) * percent; + } + } + } + else { + switch (blend) { + case MixBlend.setup: { + let vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + let setupVertices = vertexAttachment.vertices; + for (let i = 0; i < vertexCount; i++) { + let prev = prevVertices[i], setup = setupVertices[i]; + vertices[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha; + } + } + else { + for (let i = 0; i < vertexCount; i++) { + let prev = prevVertices[i]; + vertices[i] = (prev + (nextVertices[i] - prev) * percent) * alpha; + } + } + break; + } + case MixBlend.first: + case MixBlend.replace: + for (let i = 0; i < vertexCount; i++) { + let prev = prevVertices[i]; + vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha; + } + break; + case MixBlend.add: + let vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + let setupVertices = vertexAttachment.vertices; + for (let i = 0; i < vertexCount; i++) { + let prev = prevVertices[i]; + vertices[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha; + } + } + else { + for (let i = 0; i < vertexCount; i++) { + let prev = prevVertices[i]; + vertices[i] += (prev + (nextVertices[i] - prev) * percent) * alpha; + } + } + } + } + } + } + spine.DeformTimeline = DeformTimeline; + class EventTimeline { + constructor(frameCount) { + this.frames = spine.Utils.newFloatArray(frameCount); + this.events = new Array(frameCount); + } + getPropertyId() { + return TimelineType.event << 24; + } + getFrameCount() { + return this.frames.length; + } + setFrame(frameIndex, event) { + this.frames[frameIndex] = event.time; + this.events[frameIndex] = event; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + if (firedEvents == null) + return; + let frames = this.frames; + let frameCount = this.frames.length; + if (lastTime > time) { + this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, blend, direction); + lastTime = -1; + } + else if (lastTime >= frames[frameCount - 1]) + return; + if (time < frames[0]) + return; + let frame = 0; + if (lastTime < frames[0]) + frame = 0; + else { + frame = Animation.binarySearch(frames, lastTime); + let frameTime = frames[frame]; + while (frame > 0) { + if (frames[frame - 1] != frameTime) + break; + frame--; + } + } + for (; frame < frameCount && time >= frames[frame]; frame++) + firedEvents.push(this.events[frame]); + } + } + spine.EventTimeline = EventTimeline; + class DrawOrderTimeline { + constructor(frameCount) { + this.frames = spine.Utils.newFloatArray(frameCount); + this.drawOrders = new Array(frameCount); + } + getPropertyId() { + return TimelineType.drawOrder << 24; + } + getFrameCount() { + return this.frames.length; + } + setFrame(frameIndex, time, drawOrder) { + this.frames[frameIndex] = time; + this.drawOrders[frameIndex] = drawOrder; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let drawOrder = skeleton.drawOrder; + let slots = skeleton.slots; + if (direction == MixDirection.out && blend == MixBlend.setup) { + spine.Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); + return; + } + let frames = this.frames; + if (time < frames[0]) { + if (blend == MixBlend.setup || blend == MixBlend.first) + spine.Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); + return; + } + let frame = 0; + if (time >= frames[frames.length - 1]) + frame = frames.length - 1; + else + frame = Animation.binarySearch(frames, time) - 1; + let drawOrderToSetupIndex = this.drawOrders[frame]; + if (drawOrderToSetupIndex == null) + spine.Utils.arrayCopy(slots, 0, drawOrder, 0, slots.length); + else { + for (let i = 0, n = drawOrderToSetupIndex.length; i < n; i++) + drawOrder[i] = slots[drawOrderToSetupIndex[i]]; + } + } + } + spine.DrawOrderTimeline = DrawOrderTimeline; + class IkConstraintTimeline extends CurveTimeline { + constructor(frameCount) { + super(frameCount); + this.frames = spine.Utils.newFloatArray(frameCount * IkConstraintTimeline.ENTRIES); + } + getPropertyId() { + return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex; + } + setFrame(frameIndex, time, mix, bendDirection, compress, stretch) { + frameIndex *= IkConstraintTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + IkConstraintTimeline.MIX] = mix; + this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection; + this.frames[frameIndex + IkConstraintTimeline.COMPRESS] = compress ? 1 : 0; + this.frames[frameIndex + IkConstraintTimeline.STRETCH] = stretch ? 1 : 0; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let frames = this.frames; + let constraint = skeleton.ikConstraints[this.ikConstraintIndex]; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + constraint.mix = constraint.data.mix; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + return; + case MixBlend.first: + constraint.mix += (constraint.data.mix - constraint.mix) * alpha; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + return; + } + if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) { + if (blend == MixBlend.setup) { + constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha; + if (direction == MixDirection.out) { + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + else { + constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; + constraint.compress = frames[frames.length + IkConstraintTimeline.PREV_COMPRESS] != 0; + constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0; + } + } + else { + constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha; + if (direction == MixDirection.in) { + constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; + constraint.compress = frames[frames.length + IkConstraintTimeline.PREV_COMPRESS] != 0; + constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0; + } + } + return; + } + let frame = Animation.binarySearch(frames, time, IkConstraintTimeline.ENTRIES); + let mix = frames[frame + IkConstraintTimeline.PREV_MIX]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime)); + if (blend == MixBlend.setup) { + constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha; + if (direction == MixDirection.out) { + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + else { + constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; + constraint.compress = frames[frame + IkConstraintTimeline.PREV_COMPRESS] != 0; + constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0; + } + } + else { + constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha; + if (direction == MixDirection.in) { + constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; + constraint.compress = frames[frame + IkConstraintTimeline.PREV_COMPRESS] != 0; + constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0; + } + } + } + } + IkConstraintTimeline.ENTRIES = 5; + IkConstraintTimeline.PREV_TIME = -5; + IkConstraintTimeline.PREV_MIX = -4; + IkConstraintTimeline.PREV_BEND_DIRECTION = -3; + IkConstraintTimeline.PREV_COMPRESS = -2; + IkConstraintTimeline.PREV_STRETCH = -1; + IkConstraintTimeline.MIX = 1; + IkConstraintTimeline.BEND_DIRECTION = 2; + IkConstraintTimeline.COMPRESS = 3; + IkConstraintTimeline.STRETCH = 4; + spine.IkConstraintTimeline = IkConstraintTimeline; + class TransformConstraintTimeline extends CurveTimeline { + constructor(frameCount) { + super(frameCount); + this.frames = spine.Utils.newFloatArray(frameCount * TransformConstraintTimeline.ENTRIES); + } + getPropertyId() { + return (TimelineType.transformConstraint << 24) + this.transformConstraintIndex; + } + setFrame(frameIndex, time, rotateMix, translateMix, scaleMix, shearMix) { + frameIndex *= TransformConstraintTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + TransformConstraintTimeline.ROTATE] = rotateMix; + this.frames[frameIndex + TransformConstraintTimeline.TRANSLATE] = translateMix; + this.frames[frameIndex + TransformConstraintTimeline.SCALE] = scaleMix; + this.frames[frameIndex + TransformConstraintTimeline.SHEAR] = shearMix; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let frames = this.frames; + let constraint = skeleton.transformConstraints[this.transformConstraintIndex]; + if (time < frames[0]) { + let data = constraint.data; + switch (blend) { + case MixBlend.setup: + constraint.rotateMix = data.rotateMix; + constraint.translateMix = data.translateMix; + constraint.scaleMix = data.scaleMix; + constraint.shearMix = data.shearMix; + return; + case MixBlend.first: + constraint.rotateMix += (data.rotateMix - constraint.rotateMix) * alpha; + constraint.translateMix += (data.translateMix - constraint.translateMix) * alpha; + constraint.scaleMix += (data.scaleMix - constraint.scaleMix) * alpha; + constraint.shearMix += (data.shearMix - constraint.shearMix) * alpha; + } + return; + } + let rotate = 0, translate = 0, scale = 0, shear = 0; + if (time >= frames[frames.length - TransformConstraintTimeline.ENTRIES]) { + let i = frames.length; + rotate = frames[i + TransformConstraintTimeline.PREV_ROTATE]; + translate = frames[i + TransformConstraintTimeline.PREV_TRANSLATE]; + scale = frames[i + TransformConstraintTimeline.PREV_SCALE]; + shear = frames[i + TransformConstraintTimeline.PREV_SHEAR]; + } + else { + let frame = Animation.binarySearch(frames, time, TransformConstraintTimeline.ENTRIES); + rotate = frames[frame + TransformConstraintTimeline.PREV_ROTATE]; + translate = frames[frame + TransformConstraintTimeline.PREV_TRANSLATE]; + scale = frames[frame + TransformConstraintTimeline.PREV_SCALE]; + shear = frames[frame + TransformConstraintTimeline.PREV_SHEAR]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / TransformConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TransformConstraintTimeline.PREV_TIME] - frameTime)); + rotate += (frames[frame + TransformConstraintTimeline.ROTATE] - rotate) * percent; + translate += (frames[frame + TransformConstraintTimeline.TRANSLATE] - translate) * percent; + scale += (frames[frame + TransformConstraintTimeline.SCALE] - scale) * percent; + shear += (frames[frame + TransformConstraintTimeline.SHEAR] - shear) * percent; + } + if (blend == MixBlend.setup) { + let data = constraint.data; + constraint.rotateMix = data.rotateMix + (rotate - data.rotateMix) * alpha; + constraint.translateMix = data.translateMix + (translate - data.translateMix) * alpha; + constraint.scaleMix = data.scaleMix + (scale - data.scaleMix) * alpha; + constraint.shearMix = data.shearMix + (shear - data.shearMix) * alpha; + } + else { + constraint.rotateMix += (rotate - constraint.rotateMix) * alpha; + constraint.translateMix += (translate - constraint.translateMix) * alpha; + constraint.scaleMix += (scale - constraint.scaleMix) * alpha; + constraint.shearMix += (shear - constraint.shearMix) * alpha; + } + } + } + TransformConstraintTimeline.ENTRIES = 5; + TransformConstraintTimeline.PREV_TIME = -5; + TransformConstraintTimeline.PREV_ROTATE = -4; + TransformConstraintTimeline.PREV_TRANSLATE = -3; + TransformConstraintTimeline.PREV_SCALE = -2; + TransformConstraintTimeline.PREV_SHEAR = -1; + TransformConstraintTimeline.ROTATE = 1; + TransformConstraintTimeline.TRANSLATE = 2; + TransformConstraintTimeline.SCALE = 3; + TransformConstraintTimeline.SHEAR = 4; + spine.TransformConstraintTimeline = TransformConstraintTimeline; + class PathConstraintPositionTimeline extends CurveTimeline { + constructor(frameCount) { + super(frameCount); + this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintPositionTimeline.ENTRIES); + } + getPropertyId() { + return (TimelineType.pathConstraintPosition << 24) + this.pathConstraintIndex; + } + setFrame(frameIndex, time, value) { + frameIndex *= PathConstraintPositionTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + PathConstraintPositionTimeline.VALUE] = value; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let frames = this.frames; + let constraint = skeleton.pathConstraints[this.pathConstraintIndex]; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + constraint.position = constraint.data.position; + return; + case MixBlend.first: + constraint.position += (constraint.data.position - constraint.position) * alpha; + } + return; + } + let position = 0; + if (time >= frames[frames.length - PathConstraintPositionTimeline.ENTRIES]) + position = frames[frames.length + PathConstraintPositionTimeline.PREV_VALUE]; + else { + let frame = Animation.binarySearch(frames, time, PathConstraintPositionTimeline.ENTRIES); + position = frames[frame + PathConstraintPositionTimeline.PREV_VALUE]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / PathConstraintPositionTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintPositionTimeline.PREV_TIME] - frameTime)); + position += (frames[frame + PathConstraintPositionTimeline.VALUE] - position) * percent; + } + if (blend == MixBlend.setup) + constraint.position = constraint.data.position + (position - constraint.data.position) * alpha; + else + constraint.position += (position - constraint.position) * alpha; + } + } + PathConstraintPositionTimeline.ENTRIES = 2; + PathConstraintPositionTimeline.PREV_TIME = -2; + PathConstraintPositionTimeline.PREV_VALUE = -1; + PathConstraintPositionTimeline.VALUE = 1; + spine.PathConstraintPositionTimeline = PathConstraintPositionTimeline; + class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline { + constructor(frameCount) { + super(frameCount); + } + getPropertyId() { + return (TimelineType.pathConstraintSpacing << 24) + this.pathConstraintIndex; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let frames = this.frames; + let constraint = skeleton.pathConstraints[this.pathConstraintIndex]; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + constraint.spacing = constraint.data.spacing; + return; + case MixBlend.first: + constraint.spacing += (constraint.data.spacing - constraint.spacing) * alpha; + } + return; + } + let spacing = 0; + if (time >= frames[frames.length - PathConstraintSpacingTimeline.ENTRIES]) + spacing = frames[frames.length + PathConstraintSpacingTimeline.PREV_VALUE]; + else { + let frame = Animation.binarySearch(frames, time, PathConstraintSpacingTimeline.ENTRIES); + spacing = frames[frame + PathConstraintSpacingTimeline.PREV_VALUE]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / PathConstraintSpacingTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintSpacingTimeline.PREV_TIME] - frameTime)); + spacing += (frames[frame + PathConstraintSpacingTimeline.VALUE] - spacing) * percent; + } + if (blend == MixBlend.setup) + constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha; + else + constraint.spacing += (spacing - constraint.spacing) * alpha; + } + } + spine.PathConstraintSpacingTimeline = PathConstraintSpacingTimeline; + class PathConstraintMixTimeline extends CurveTimeline { + constructor(frameCount) { + super(frameCount); + this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintMixTimeline.ENTRIES); + } + getPropertyId() { + return (TimelineType.pathConstraintMix << 24) + this.pathConstraintIndex; + } + setFrame(frameIndex, time, rotateMix, translateMix) { + frameIndex *= PathConstraintMixTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + PathConstraintMixTimeline.ROTATE] = rotateMix; + this.frames[frameIndex + PathConstraintMixTimeline.TRANSLATE] = translateMix; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let frames = this.frames; + let constraint = skeleton.pathConstraints[this.pathConstraintIndex]; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + constraint.rotateMix = constraint.data.rotateMix; + constraint.translateMix = constraint.data.translateMix; + return; + case MixBlend.first: + constraint.rotateMix += (constraint.data.rotateMix - constraint.rotateMix) * alpha; + constraint.translateMix += (constraint.data.translateMix - constraint.translateMix) * alpha; + } + return; + } + let rotate = 0, translate = 0; + if (time >= frames[frames.length - PathConstraintMixTimeline.ENTRIES]) { + rotate = frames[frames.length + PathConstraintMixTimeline.PREV_ROTATE]; + translate = frames[frames.length + PathConstraintMixTimeline.PREV_TRANSLATE]; + } + else { + let frame = Animation.binarySearch(frames, time, PathConstraintMixTimeline.ENTRIES); + rotate = frames[frame + PathConstraintMixTimeline.PREV_ROTATE]; + translate = frames[frame + PathConstraintMixTimeline.PREV_TRANSLATE]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / PathConstraintMixTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintMixTimeline.PREV_TIME] - frameTime)); + rotate += (frames[frame + PathConstraintMixTimeline.ROTATE] - rotate) * percent; + translate += (frames[frame + PathConstraintMixTimeline.TRANSLATE] - translate) * percent; + } + if (blend == MixBlend.setup) { + constraint.rotateMix = constraint.data.rotateMix + (rotate - constraint.data.rotateMix) * alpha; + constraint.translateMix = constraint.data.translateMix + (translate - constraint.data.translateMix) * alpha; + } + else { + constraint.rotateMix += (rotate - constraint.rotateMix) * alpha; + constraint.translateMix += (translate - constraint.translateMix) * alpha; + } + } + } + PathConstraintMixTimeline.ENTRIES = 3; + PathConstraintMixTimeline.PREV_TIME = -3; + PathConstraintMixTimeline.PREV_ROTATE = -2; + PathConstraintMixTimeline.PREV_TRANSLATE = -1; + PathConstraintMixTimeline.ROTATE = 1; + PathConstraintMixTimeline.TRANSLATE = 2; + spine.PathConstraintMixTimeline = PathConstraintMixTimeline; +})(spine || (spine = {})); +var spine; +(function (spine) { + class AnimationState { + constructor(data) { + this.tracks = new Array(); + this.events = new Array(); + this.listeners = new Array(); + this.queue = new EventQueue(this); + this.propertyIDs = new spine.IntSet(); + this.animationsChanged = false; + this.timeScale = 1; + this.trackEntryPool = new spine.Pool(() => new TrackEntry()); + this.data = data; + } + update(delta) { + delta *= this.timeScale; + let tracks = this.tracks; + for (let i = 0, n = tracks.length; i < n; i++) { + let current = tracks[i]; + if (current == null) + continue; + current.animationLast = current.nextAnimationLast; + current.trackLast = current.nextTrackLast; + let currentDelta = delta * current.timeScale; + if (current.delay > 0) { + current.delay -= currentDelta; + if (current.delay > 0) + continue; + currentDelta = -current.delay; + current.delay = 0; + } + let next = current.next; + if (next != null) { + let nextTime = current.trackLast - next.delay; + if (nextTime >= 0) { + next.delay = 0; + next.trackTime = current.timeScale == 0 ? 0 : (nextTime / current.timeScale + delta) * next.timeScale; + current.trackTime += currentDelta; + this.setCurrent(i, next, true); + while (next.mixingFrom != null) { + next.mixTime += delta; + next = next.mixingFrom; + } + continue; + } + } + else if (current.trackLast >= current.trackEnd && current.mixingFrom == null) { + tracks[i] = null; + this.queue.end(current); + this.disposeNext(current); + continue; + } + if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) { + let from = current.mixingFrom; + current.mixingFrom = null; + if (from != null) + from.mixingTo = null; + while (from != null) { + this.queue.end(from); + from = from.mixingFrom; + } + } + current.trackTime += currentDelta; + } + this.queue.drain(); + } + updateMixingFrom(to, delta) { + let from = to.mixingFrom; + if (from == null) + return true; + let finished = this.updateMixingFrom(from, delta); + from.animationLast = from.nextAnimationLast; + from.trackLast = from.nextTrackLast; + if (to.mixTime > 0 && to.mixTime >= to.mixDuration) { + if (from.totalAlpha == 0 || to.mixDuration == 0) { + to.mixingFrom = from.mixingFrom; + if (from.mixingFrom != null) + from.mixingFrom.mixingTo = to; + to.interruptAlpha = from.interruptAlpha; + this.queue.end(from); + } + return finished; + } + from.trackTime += delta * from.timeScale; + to.mixTime += delta; + return false; + } + apply(skeleton) { + if (skeleton == null) + throw new Error("skeleton cannot be null."); + if (this.animationsChanged) + this._animationsChanged(); + let events = this.events; + let tracks = this.tracks; + let applied = false; + for (let i = 0, n = tracks.length; i < n; i++) { + let current = tracks[i]; + if (current == null || current.delay > 0) + continue; + applied = true; + let blend = i == 0 ? spine.MixBlend.first : current.mixBlend; + let mix = current.alpha; + if (current.mixingFrom != null) + mix *= this.applyMixingFrom(current, skeleton, blend); + else if (current.trackTime >= current.trackEnd && current.next == null) + mix = 0; + let animationLast = current.animationLast, animationTime = current.getAnimationTime(); + let timelineCount = current.animation.timelines.length; + let timelines = current.animation.timelines; + if ((i == 0 && mix == 1) || blend == spine.MixBlend.add) { + for (let ii = 0; ii < timelineCount; ii++) + timelines[ii].apply(skeleton, animationLast, animationTime, events, mix, blend, spine.MixDirection.in); + } + else { + let timelineMode = current.timelineMode; + let firstFrame = current.timelinesRotation.length == 0; + if (firstFrame) + spine.Utils.setArraySize(current.timelinesRotation, timelineCount << 1, null); + let timelinesRotation = current.timelinesRotation; + for (let ii = 0; ii < timelineCount; ii++) { + let timeline = timelines[ii]; + let timelineBlend = timelineMode[ii] == AnimationState.SUBSEQUENT ? blend : spine.MixBlend.setup; + if (timeline instanceof spine.RotateTimeline) { + this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame); + } + else { + spine.Utils.webkit602BugfixHelper(mix, blend); + timeline.apply(skeleton, animationLast, animationTime, events, mix, timelineBlend, spine.MixDirection.in); + } + } + } + this.queueEvents(current, animationTime); + events.length = 0; + current.nextAnimationLast = animationTime; + current.nextTrackLast = current.trackTime; + } + this.queue.drain(); + return applied; + } + applyMixingFrom(to, skeleton, blend) { + let from = to.mixingFrom; + if (from.mixingFrom != null) + this.applyMixingFrom(from, skeleton, blend); + let mix = 0; + if (to.mixDuration == 0) { + mix = 1; + if (blend == spine.MixBlend.first) + blend = spine.MixBlend.setup; + } + else { + mix = to.mixTime / to.mixDuration; + if (mix > 1) + mix = 1; + if (blend != spine.MixBlend.first) + blend = from.mixBlend; + } + let events = mix < from.eventThreshold ? this.events : null; + let attachments = mix < from.attachmentThreshold, drawOrder = mix < from.drawOrderThreshold; + let animationLast = from.animationLast, animationTime = from.getAnimationTime(); + let timelineCount = from.animation.timelines.length; + let timelines = from.animation.timelines; + let alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix); + if (blend == spine.MixBlend.add) { + for (let i = 0; i < timelineCount; i++) + timelines[i].apply(skeleton, animationLast, animationTime, events, alphaMix, blend, spine.MixDirection.out); + } + else { + let timelineMode = from.timelineMode; + let timelineHoldMix = from.timelineHoldMix; + let firstFrame = from.timelinesRotation.length == 0; + if (firstFrame) + spine.Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null); + let timelinesRotation = from.timelinesRotation; + from.totalAlpha = 0; + for (let i = 0; i < timelineCount; i++) { + let timeline = timelines[i]; + let direction = spine.MixDirection.out; + let timelineBlend; + let alpha = 0; + switch (timelineMode[i]) { + case AnimationState.SUBSEQUENT: + if (!attachments && timeline instanceof spine.AttachmentTimeline) + continue; + if (!drawOrder && timeline instanceof spine.DrawOrderTimeline) + continue; + timelineBlend = blend; + alpha = alphaMix; + break; + case AnimationState.FIRST: + timelineBlend = spine.MixBlend.setup; + alpha = alphaMix; + break; + case AnimationState.HOLD: + timelineBlend = spine.MixBlend.setup; + alpha = alphaHold; + break; + default: + timelineBlend = spine.MixBlend.setup; + let holdMix = timelineHoldMix[i]; + alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration); + break; + } + from.totalAlpha += alpha; + if (timeline instanceof spine.RotateTimeline) + this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation, i << 1, firstFrame); + else { + spine.Utils.webkit602BugfixHelper(alpha, blend); + if (timelineBlend == spine.MixBlend.setup) { + if (timeline instanceof spine.AttachmentTimeline) { + if (attachments) + direction = spine.MixDirection.out; + } + else if (timeline instanceof spine.DrawOrderTimeline) { + if (drawOrder) + direction = spine.MixDirection.out; + } + } + timeline.apply(skeleton, animationLast, animationTime, events, alpha, timelineBlend, direction); + } + } + } + if (to.mixDuration > 0) + this.queueEvents(from, animationTime); + this.events.length = 0; + from.nextAnimationLast = animationTime; + from.nextTrackLast = from.trackTime; + return mix; + } + applyRotateTimeline(timeline, skeleton, time, alpha, blend, timelinesRotation, i, firstFrame) { + if (firstFrame) + timelinesRotation[i] = 0; + if (alpha == 1) { + timeline.apply(skeleton, 0, time, null, 1, blend, spine.MixDirection.in); + return; + } + let rotateTimeline = timeline; + let frames = rotateTimeline.frames; + let bone = skeleton.bones[rotateTimeline.boneIndex]; + let r1 = 0, r2 = 0; + if (time < frames[0]) { + switch (blend) { + case spine.MixBlend.setup: + bone.rotation = bone.data.rotation; + default: + return; + case spine.MixBlend.first: + r1 = bone.rotation; + r2 = bone.data.rotation; + } + } + else { + r1 = blend == spine.MixBlend.setup ? bone.data.rotation : bone.rotation; + if (time >= frames[frames.length - spine.RotateTimeline.ENTRIES]) + r2 = bone.data.rotation + frames[frames.length + spine.RotateTimeline.PREV_ROTATION]; + else { + let frame = spine.Animation.binarySearch(frames, time, spine.RotateTimeline.ENTRIES); + let prevRotation = frames[frame + spine.RotateTimeline.PREV_ROTATION]; + let frameTime = frames[frame]; + let percent = rotateTimeline.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + spine.RotateTimeline.PREV_TIME] - frameTime)); + r2 = frames[frame + spine.RotateTimeline.ROTATION] - prevRotation; + r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360; + r2 = prevRotation + r2 * percent + bone.data.rotation; + r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360; + } + } + let total = 0, diff = r2 - r1; + diff -= (16384 - ((16384.499999999996 - diff / 360) | 0)) * 360; + if (diff == 0) { + total = timelinesRotation[i]; + } + else { + let lastTotal = 0, lastDiff = 0; + if (firstFrame) { + lastTotal = 0; + lastDiff = diff; + } + else { + lastTotal = timelinesRotation[i]; + lastDiff = timelinesRotation[i + 1]; + } + let current = diff > 0, dir = lastTotal >= 0; + if (spine.MathUtils.signum(lastDiff) != spine.MathUtils.signum(diff) && Math.abs(lastDiff) <= 90) { + if (Math.abs(lastTotal) > 180) + lastTotal += 360 * spine.MathUtils.signum(lastTotal); + dir = current; + } + total = diff + lastTotal - lastTotal % 360; + if (dir != current) + total += 360 * spine.MathUtils.signum(lastTotal); + timelinesRotation[i] = total; + } + timelinesRotation[i + 1] = diff; + r1 += total * alpha; + bone.rotation = r1 - (16384 - ((16384.499999999996 - r1 / 360) | 0)) * 360; + } + queueEvents(entry, animationTime) { + let animationStart = entry.animationStart, animationEnd = entry.animationEnd; + let duration = animationEnd - animationStart; + let trackLastWrapped = entry.trackLast % duration; + let events = this.events; + let i = 0, n = events.length; + for (; i < n; i++) { + let event = events[i]; + if (event.time < trackLastWrapped) + break; + if (event.time > animationEnd) + continue; + this.queue.event(entry, event); + } + let complete = false; + if (entry.loop) + complete = duration == 0 || trackLastWrapped > entry.trackTime % duration; + else + complete = animationTime >= animationEnd && entry.animationLast < animationEnd; + if (complete) + this.queue.complete(entry); + for (; i < n; i++) { + let event = events[i]; + if (event.time < animationStart) + continue; + this.queue.event(entry, events[i]); + } + } + clearTracks() { + let oldDrainDisabled = this.queue.drainDisabled; + this.queue.drainDisabled = true; + for (let i = 0, n = this.tracks.length; i < n; i++) + this.clearTrack(i); + this.tracks.length = 0; + this.queue.drainDisabled = oldDrainDisabled; + this.queue.drain(); + } + clearTrack(trackIndex) { + if (trackIndex >= this.tracks.length) + return; + let current = this.tracks[trackIndex]; + if (current == null) + return; + this.queue.end(current); + this.disposeNext(current); + let entry = current; + while (true) { + let from = entry.mixingFrom; + if (from == null) + break; + this.queue.end(from); + entry.mixingFrom = null; + entry.mixingTo = null; + entry = from; + } + this.tracks[current.trackIndex] = null; + this.queue.drain(); + } + setCurrent(index, current, interrupt) { + let from = this.expandToIndex(index); + this.tracks[index] = current; + if (from != null) { + if (interrupt) + this.queue.interrupt(from); + current.mixingFrom = from; + from.mixingTo = current; + current.mixTime = 0; + if (from.mixingFrom != null && from.mixDuration > 0) + current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration); + from.timelinesRotation.length = 0; + } + this.queue.start(current); + } + setAnimation(trackIndex, animationName, loop) { + let animation = this.data.skeletonData.findAnimation(animationName); + if (animation == null) + throw new Error("Animation not found: " + animationName); + return this.setAnimationWith(trackIndex, animation, loop); + } + setAnimationWith(trackIndex, animation, loop) { + if (animation == null) + throw new Error("animation cannot be null."); + let interrupt = true; + let current = this.expandToIndex(trackIndex); + if (current != null) { + if (current.nextTrackLast == -1) { + this.tracks[trackIndex] = current.mixingFrom; + this.queue.interrupt(current); + this.queue.end(current); + this.disposeNext(current); + current = current.mixingFrom; + interrupt = false; + } + else + this.disposeNext(current); + } + let entry = this.trackEntry(trackIndex, animation, loop, current); + this.setCurrent(trackIndex, entry, interrupt); + this.queue.drain(); + return entry; + } + addAnimation(trackIndex, animationName, loop, delay) { + let animation = this.data.skeletonData.findAnimation(animationName); + if (animation == null) + throw new Error("Animation not found: " + animationName); + return this.addAnimationWith(trackIndex, animation, loop, delay); + } + addAnimationWith(trackIndex, animation, loop, delay) { + if (animation == null) + throw new Error("animation cannot be null."); + let last = this.expandToIndex(trackIndex); + if (last != null) { + while (last.next != null) + last = last.next; + } + let entry = this.trackEntry(trackIndex, animation, loop, last); + if (last == null) { + this.setCurrent(trackIndex, entry, true); + this.queue.drain(); + } + else { + last.next = entry; + if (delay <= 0) { + let duration = last.animationEnd - last.animationStart; + if (duration != 0) { + if (last.loop) + delay += duration * (1 + ((last.trackTime / duration) | 0)); + else + delay += Math.max(duration, last.trackTime); + delay -= this.data.getMix(last.animation, animation); + } + else + delay = last.trackTime; + } + } + entry.delay = delay; + return entry; + } + setEmptyAnimation(trackIndex, mixDuration) { + let entry = this.setAnimationWith(trackIndex, AnimationState.emptyAnimation, false); + entry.mixDuration = mixDuration; + entry.trackEnd = mixDuration; + return entry; + } + addEmptyAnimation(trackIndex, mixDuration, delay) { + if (delay <= 0) + delay -= mixDuration; + let entry = this.addAnimationWith(trackIndex, AnimationState.emptyAnimation, false, delay); + entry.mixDuration = mixDuration; + entry.trackEnd = mixDuration; + return entry; + } + setEmptyAnimations(mixDuration) { + let oldDrainDisabled = this.queue.drainDisabled; + this.queue.drainDisabled = true; + for (let i = 0, n = this.tracks.length; i < n; i++) { + let current = this.tracks[i]; + if (current != null) + this.setEmptyAnimation(current.trackIndex, mixDuration); + } + this.queue.drainDisabled = oldDrainDisabled; + this.queue.drain(); + } + expandToIndex(index) { + if (index < this.tracks.length) + return this.tracks[index]; + spine.Utils.ensureArrayCapacity(this.tracks, index + 1, null); + this.tracks.length = index + 1; + return null; + } + trackEntry(trackIndex, animation, loop, last) { + let entry = this.trackEntryPool.obtain(); + entry.trackIndex = trackIndex; + entry.animation = animation; + entry.loop = loop; + entry.holdPrevious = false; + entry.eventThreshold = 0; + entry.attachmentThreshold = 0; + entry.drawOrderThreshold = 0; + entry.animationStart = 0; + entry.animationEnd = animation.duration; + entry.animationLast = -1; + entry.nextAnimationLast = -1; + entry.delay = 0; + entry.trackTime = 0; + entry.trackLast = -1; + entry.nextTrackLast = -1; + entry.trackEnd = Number.MAX_VALUE; + entry.timeScale = 1; + entry.alpha = 1; + entry.interruptAlpha = 1; + entry.mixTime = 0; + entry.mixDuration = last == null ? 0 : this.data.getMix(last.animation, animation); + return entry; + } + disposeNext(entry) { + let next = entry.next; + while (next != null) { + this.queue.dispose(next); + next = next.next; + } + entry.next = null; + } + _animationsChanged() { + this.animationsChanged = false; + this.propertyIDs.clear(); + for (let i = 0, n = this.tracks.length; i < n; i++) { + let entry = this.tracks[i]; + if (entry == null) + continue; + while (entry.mixingFrom != null) + entry = entry.mixingFrom; + do { + if (entry.mixingFrom == null || entry.mixBlend != spine.MixBlend.add) + this.setTimelineModes(entry); + entry = entry.mixingTo; + } while (entry != null); + } + } + setTimelineModes(entry) { + let to = entry.mixingTo; + let timelines = entry.animation.timelines; + let timelinesCount = entry.animation.timelines.length; + let timelineMode = spine.Utils.setArraySize(entry.timelineMode, timelinesCount); + entry.timelineHoldMix.length = 0; + let timelineDipMix = spine.Utils.setArraySize(entry.timelineHoldMix, timelinesCount); + let propertyIDs = this.propertyIDs; + if (to != null && to.holdPrevious) { + for (let i = 0; i < timelinesCount; i++) { + propertyIDs.add(timelines[i].getPropertyId()); + timelineMode[i] = AnimationState.HOLD; + } + return; + } + outer: for (let i = 0; i < timelinesCount; i++) { + let id = timelines[i].getPropertyId(); + if (!propertyIDs.add(id)) + timelineMode[i] = AnimationState.SUBSEQUENT; + else if (to == null || !this.hasTimeline(to, id)) + timelineMode[i] = AnimationState.FIRST; + else { + for (let next = to.mixingTo; next != null; next = next.mixingTo) { + if (this.hasTimeline(next, id)) + continue; + if (entry.mixDuration > 0) { + timelineMode[i] = AnimationState.HOLD_MIX; + timelineDipMix[i] = next; + continue outer; + } + break; + } + timelineMode[i] = AnimationState.HOLD; + } + } + } + hasTimeline(entry, id) { + let timelines = entry.animation.timelines; + for (let i = 0, n = timelines.length; i < n; i++) + if (timelines[i].getPropertyId() == id) + return true; + return false; + } + getCurrent(trackIndex) { + if (trackIndex >= this.tracks.length) + return null; + return this.tracks[trackIndex]; + } + addListener(listener) { + if (listener == null) + throw new Error("listener cannot be null."); + this.listeners.push(listener); + } + removeListener(listener) { + let index = this.listeners.indexOf(listener); + if (index >= 0) + this.listeners.splice(index, 1); + } + clearListeners() { + this.listeners.length = 0; + } + clearListenerNotifications() { + this.queue.clear(); + } + } + AnimationState.emptyAnimation = new spine.Animation("", [], 0); + AnimationState.SUBSEQUENT = 0; + AnimationState.FIRST = 1; + AnimationState.HOLD = 2; + AnimationState.HOLD_MIX = 3; + spine.AnimationState = AnimationState; + class TrackEntry { + constructor() { + this.mixBlend = spine.MixBlend.replace; + this.timelineMode = new Array(); + this.timelineHoldMix = new Array(); + this.timelinesRotation = new Array(); + } + reset() { + this.next = null; + this.mixingFrom = null; + this.mixingTo = null; + this.animation = null; + this.listener = null; + this.timelineMode.length = 0; + this.timelineHoldMix.length = 0; + this.timelinesRotation.length = 0; + } + getAnimationTime() { + if (this.loop) { + let duration = this.animationEnd - this.animationStart; + if (duration == 0) + return this.animationStart; + return (this.trackTime % duration) + this.animationStart; + } + return Math.min(this.trackTime + this.animationStart, this.animationEnd); + } + setAnimationLast(animationLast) { + this.animationLast = animationLast; + this.nextAnimationLast = animationLast; + } + isComplete() { + return this.trackTime >= this.animationEnd - this.animationStart; + } + resetRotationDirections() { + this.timelinesRotation.length = 0; + } + } + spine.TrackEntry = TrackEntry; + class EventQueue { + constructor(animState) { + this.objects = []; + this.drainDisabled = false; + this.animState = animState; + } + start(entry) { + this.objects.push(EventType.start); + this.objects.push(entry); + this.animState.animationsChanged = true; + } + interrupt(entry) { + this.objects.push(EventType.interrupt); + this.objects.push(entry); + } + end(entry) { + this.objects.push(EventType.end); + this.objects.push(entry); + this.animState.animationsChanged = true; + } + dispose(entry) { + this.objects.push(EventType.dispose); + this.objects.push(entry); + } + complete(entry) { + this.objects.push(EventType.complete); + this.objects.push(entry); + } + event(entry, event) { + this.objects.push(EventType.event); + this.objects.push(entry); + this.objects.push(event); + } + drain() { + if (this.drainDisabled) + return; + this.drainDisabled = true; + let objects = this.objects; + let listeners = this.animState.listeners; + for (let i = 0; i < objects.length; i += 2) { + let type = objects[i]; + let entry = objects[i + 1]; + switch (type) { + case EventType.start: + if (entry.listener != null && entry.listener.start) + entry.listener.start(entry); + for (let ii = 0; ii < listeners.length; ii++) + if (listeners[ii].start) + listeners[ii].start(entry); + break; + case EventType.interrupt: + if (entry.listener != null && entry.listener.interrupt) + entry.listener.interrupt(entry); + for (let ii = 0; ii < listeners.length; ii++) + if (listeners[ii].interrupt) + listeners[ii].interrupt(entry); + break; + case EventType.end: + if (entry.listener != null && entry.listener.end) + entry.listener.end(entry); + for (let ii = 0; ii < listeners.length; ii++) + if (listeners[ii].end) + listeners[ii].end(entry); + case EventType.dispose: + if (entry.listener != null && entry.listener.dispose) + entry.listener.dispose(entry); + for (let ii = 0; ii < listeners.length; ii++) + if (listeners[ii].dispose) + listeners[ii].dispose(entry); + this.animState.trackEntryPool.free(entry); + break; + case EventType.complete: + if (entry.listener != null && entry.listener.complete) + entry.listener.complete(entry); + for (let ii = 0; ii < listeners.length; ii++) + if (listeners[ii].complete) + listeners[ii].complete(entry); + break; + case EventType.event: + let event = objects[i++ + 2]; + if (entry.listener != null && entry.listener.event) + entry.listener.event(entry, event); + for (let ii = 0; ii < listeners.length; ii++) + if (listeners[ii].event) + listeners[ii].event(entry, event); + break; + } + } + this.clear(); + this.drainDisabled = false; + } + clear() { + this.objects.length = 0; + } + } + spine.EventQueue = EventQueue; + let EventType; + (function (EventType) { + EventType[EventType["start"] = 0] = "start"; + EventType[EventType["interrupt"] = 1] = "interrupt"; + EventType[EventType["end"] = 2] = "end"; + EventType[EventType["dispose"] = 3] = "dispose"; + EventType[EventType["complete"] = 4] = "complete"; + EventType[EventType["event"] = 5] = "event"; + })(EventType = spine.EventType || (spine.EventType = {})); + class AnimationStateAdapter2 { + start(entry) { + } + interrupt(entry) { + } + end(entry) { + } + dispose(entry) { + } + complete(entry) { + } + event(entry, event) { + } + } + spine.AnimationStateAdapter2 = AnimationStateAdapter2; +})(spine || (spine = {})); +var spine; +(function (spine) { + class AnimationStateData { + constructor(skeletonData) { + this.animationToMixTime = {}; + this.defaultMix = 0; + if (skeletonData == null) + throw new Error("skeletonData cannot be null."); + this.skeletonData = skeletonData; + } + setMix(fromName, toName, duration) { + let from = this.skeletonData.findAnimation(fromName); + if (from == null) + throw new Error("Animation not found: " + fromName); + let to = this.skeletonData.findAnimation(toName); + if (to == null) + throw new Error("Animation not found: " + toName); + this.setMixWith(from, to, duration); + } + setMixWith(from, to, duration) { + if (from == null) + throw new Error("from cannot be null."); + if (to == null) + throw new Error("to cannot be null."); + let key = from.name + "." + to.name; + this.animationToMixTime[key] = duration; + } + getMix(from, to) { + let key = from.name + "." + to.name; + let value = this.animationToMixTime[key]; + return value === undefined ? this.defaultMix : value; + } + } + spine.AnimationStateData = AnimationStateData; +})(spine || (spine = {})); +var spine; +(function (spine) { + class AssetManager { + constructor(textureLoader, pathPrefix = "") { + this.assets = {}; + this.errors = {}; + this.toLoad = 0; + this.loaded = 0; + this.textureLoader = textureLoader; + this.pathPrefix = pathPrefix; + } + static downloadText(url, success, error) { + let request = new XMLHttpRequest(); + request.open("GET", url, true); + request.onload = () => { + if (request.status == 200) { + success(request.responseText); + } + else { + error(request.status, request.responseText); + } + }; + request.onerror = () => { + error(request.status, request.responseText); + }; + request.send(); + } + static downloadBinary(url, success, error) { + let request = new XMLHttpRequest(); + request.open("GET", url, true); + request.responseType = "arraybuffer"; + request.onload = () => { + if (request.status == 200) { + success(new Uint8Array(request.response)); + } + else { + error(request.status, request.responseText); + } + }; + request.onerror = () => { + error(request.status, request.responseText); + }; + request.send(); + } + loadText(path, success = null, error = null) { + path = this.pathPrefix + path; + this.toLoad++; + AssetManager.downloadText(path, (data) => { + this.assets[path] = data; + if (success) + success(path, data); + this.toLoad--; + this.loaded++; + }, (state, responseText) => { + this.errors[path] = `Couldn't load text ${path}: status ${status}, ${responseText}`; + if (error) + error(path, `Couldn't load text ${path}: status ${status}, ${responseText}`); + this.toLoad--; + this.loaded++; + }); + } + loadTexture(path, success = null, error = null) { + path = this.pathPrefix + path; + this.toLoad++; + let img = new Image(); + img.crossOrigin = "anonymous"; + img.onload = (ev) => { + let texture = this.textureLoader(img); + this.assets[path] = texture; + this.toLoad--; + this.loaded++; + if (success) + success(path, img); + }; + img.onerror = (ev) => { + this.errors[path] = `Couldn't load image ${path}`; + this.toLoad--; + this.loaded++; + if (error) + error(path, `Couldn't load image ${path}`); + }; + img.src = path; + } + loadTextureData(path, data, success = null, error = null) { + path = this.pathPrefix + path; + this.toLoad++; + let img = new Image(); + img.onload = (ev) => { + let texture = this.textureLoader(img); + this.assets[path] = texture; + this.toLoad--; + this.loaded++; + if (success) + success(path, img); + }; + img.onerror = (ev) => { + this.errors[path] = `Couldn't load image ${path}`; + this.toLoad--; + this.loaded++; + if (error) + error(path, `Couldn't load image ${path}`); + }; + img.src = data; + } + loadTextureAtlas(path, success = null, error = null) { + let parent = path.lastIndexOf("/") >= 0 ? path.substring(0, path.lastIndexOf("/")) : ""; + path = this.pathPrefix + path; + this.toLoad++; + AssetManager.downloadText(path, (atlasData) => { + let pagesLoaded = { count: 0 }; + let atlasPages = new Array(); + try { + let atlas = new spine.TextureAtlas(atlasData, (path) => { + atlasPages.push(parent + "/" + path); + let image = document.createElement("img"); + image.width = 16; + image.height = 16; + return new spine.FakeTexture(image); + }); + } + catch (e) { + let ex = e; + this.errors[path] = `Couldn't load texture atlas ${path}: ${ex.message}`; + if (error) + error(path, `Couldn't load texture atlas ${path}: ${ex.message}`); + this.toLoad--; + this.loaded++; + return; + } + for (let atlasPage of atlasPages) { + let pageLoadError = false; + this.loadTexture(atlasPage, (imagePath, image) => { + pagesLoaded.count++; + if (pagesLoaded.count == atlasPages.length) { + if (!pageLoadError) { + try { + let atlas = new spine.TextureAtlas(atlasData, (path) => { + return this.get(parent + "/" + path); + }); + this.assets[path] = atlas; + if (success) + success(path, atlas); + this.toLoad--; + this.loaded++; + } + catch (e) { + let ex = e; + this.errors[path] = `Couldn't load texture atlas ${path}: ${ex.message}`; + if (error) + error(path, `Couldn't load texture atlas ${path}: ${ex.message}`); + this.toLoad--; + this.loaded++; + } + } + else { + this.errors[path] = `Couldn't load texture atlas page ${imagePath}} of atlas ${path}`; + if (error) + error(path, `Couldn't load texture atlas page ${imagePath} of atlas ${path}`); + this.toLoad--; + this.loaded++; + } + } + }, (imagePath, errorMessage) => { + pageLoadError = true; + pagesLoaded.count++; + if (pagesLoaded.count == atlasPages.length) { + this.errors[path] = `Couldn't load texture atlas page ${imagePath}} of atlas ${path}`; + if (error) + error(path, `Couldn't load texture atlas page ${imagePath} of atlas ${path}`); + this.toLoad--; + this.loaded++; + } + }); + } + }, (state, responseText) => { + this.errors[path] = `Couldn't load texture atlas ${path}: status ${status}, ${responseText}`; + if (error) + error(path, `Couldn't load texture atlas ${path}: status ${status}, ${responseText}`); + this.toLoad--; + this.loaded++; + }); + } + get(path) { + path = this.pathPrefix + path; + return this.assets[path]; + } + remove(path) { + path = this.pathPrefix + path; + let asset = this.assets[path]; + if (asset.dispose) + asset.dispose(); + this.assets[path] = null; + } + removeAll() { + for (let key in this.assets) { + let asset = this.assets[key]; + if (asset.dispose) + asset.dispose(); + } + this.assets = {}; + } + isLoadingComplete() { + return this.toLoad == 0; + } + getToLoad() { + return this.toLoad; + } + getLoaded() { + return this.loaded; + } + dispose() { + this.removeAll(); + } + hasErrors() { + return Object.keys(this.errors).length > 0; + } + getErrors() { + return this.errors; + } + } + spine.AssetManager = AssetManager; +})(spine || (spine = {})); +var spine; +(function (spine) { + class AtlasAttachmentLoader { + constructor(atlas) { + this.atlas = atlas; + } + newRegionAttachment(skin, name, path) { + let region = this.atlas.findRegion(path); + if (region == null) + throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")"); + region.renderObject = region; + let attachment = new spine.RegionAttachment(name); + attachment.setRegion(region); + return attachment; + } + newMeshAttachment(skin, name, path) { + let region = this.atlas.findRegion(path); + if (region == null) + throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")"); + region.renderObject = region; + let attachment = new spine.MeshAttachment(name); + attachment.region = region; + return attachment; + } + newBoundingBoxAttachment(skin, name) { + return new spine.BoundingBoxAttachment(name); + } + newPathAttachment(skin, name) { + return new spine.PathAttachment(name); + } + newPointAttachment(skin, name) { + return new spine.PointAttachment(name); + } + newClippingAttachment(skin, name) { + return new spine.ClippingAttachment(name); + } + } + spine.AtlasAttachmentLoader = AtlasAttachmentLoader; +})(spine || (spine = {})); +var spine; +(function (spine) { + let BlendMode; + (function (BlendMode) { + BlendMode[BlendMode["Normal"] = 0] = "Normal"; + BlendMode[BlendMode["Additive"] = 1] = "Additive"; + BlendMode[BlendMode["Multiply"] = 2] = "Multiply"; + BlendMode[BlendMode["Screen"] = 3] = "Screen"; + })(BlendMode = spine.BlendMode || (spine.BlendMode = {})); +})(spine || (spine = {})); +var spine; +(function (spine) { + class Bone { + constructor(data, skeleton, parent) { + this.children = new Array(); + this.x = 0; + this.y = 0; + this.rotation = 0; + this.scaleX = 0; + this.scaleY = 0; + this.shearX = 0; + this.shearY = 0; + this.ax = 0; + this.ay = 0; + this.arotation = 0; + this.ascaleX = 0; + this.ascaleY = 0; + this.ashearX = 0; + this.ashearY = 0; + this.appliedValid = false; + this.a = 0; + this.b = 0; + this.worldX = 0; + this.c = 0; + this.d = 0; + this.worldY = 0; + this.sorted = false; + if (data == null) + throw new Error("data cannot be null."); + if (skeleton == null) + throw new Error("skeleton cannot be null."); + this.data = data; + this.skeleton = skeleton; + this.parent = parent; + this.setToSetupPose(); + } + update() { + this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); + } + updateWorldTransform() { + this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); + } + updateWorldTransformWith(x, y, rotation, scaleX, scaleY, shearX, shearY) { + this.ax = x; + this.ay = y; + this.arotation = rotation; + this.ascaleX = scaleX; + this.ascaleY = scaleY; + this.ashearX = shearX; + this.ashearY = shearY; + this.appliedValid = true; + let parent = this.parent; + if (parent == null) { + let skeleton = this.skeleton; + let rotationY = rotation + 90 + shearY; + let sx = skeleton.scaleX; + let sy = skeleton.scaleY; + this.a = spine.MathUtils.cosDeg(rotation + shearX) * scaleX * sx; + this.b = spine.MathUtils.cosDeg(rotationY) * scaleY * sx; + this.c = spine.MathUtils.sinDeg(rotation + shearX) * scaleX * sy; + this.d = spine.MathUtils.sinDeg(rotationY) * scaleY * sy; + this.worldX = x * sx + skeleton.x; + this.worldY = y * sy + skeleton.y; + return; + } + let pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d; + this.worldX = pa * x + pb * y + parent.worldX; + this.worldY = pc * x + pd * y + parent.worldY; + switch (this.data.transformMode) { + case spine.TransformMode.Normal: { + let rotationY = rotation + 90 + shearY; + let la = spine.MathUtils.cosDeg(rotation + shearX) * scaleX; + let lb = spine.MathUtils.cosDeg(rotationY) * scaleY; + let lc = spine.MathUtils.sinDeg(rotation + shearX) * scaleX; + let ld = spine.MathUtils.sinDeg(rotationY) * scaleY; + this.a = pa * la + pb * lc; + this.b = pa * lb + pb * ld; + this.c = pc * la + pd * lc; + this.d = pc * lb + pd * ld; + return; + } + case spine.TransformMode.OnlyTranslation: { + let rotationY = rotation + 90 + shearY; + this.a = spine.MathUtils.cosDeg(rotation + shearX) * scaleX; + this.b = spine.MathUtils.cosDeg(rotationY) * scaleY; + this.c = spine.MathUtils.sinDeg(rotation + shearX) * scaleX; + this.d = spine.MathUtils.sinDeg(rotationY) * scaleY; + break; + } + case spine.TransformMode.NoRotationOrReflection: { + let s = pa * pa + pc * pc; + let prx = 0; + if (s > 0.0001) { + s = Math.abs(pa * pd - pb * pc) / s; + pb = pc * s; + pd = pa * s; + prx = Math.atan2(pc, pa) * spine.MathUtils.radDeg; + } + else { + pa = 0; + pc = 0; + prx = 90 - Math.atan2(pd, pb) * spine.MathUtils.radDeg; + } + let rx = rotation + shearX - prx; + let ry = rotation + shearY - prx + 90; + let la = spine.MathUtils.cosDeg(rx) * scaleX; + let lb = spine.MathUtils.cosDeg(ry) * scaleY; + let lc = spine.MathUtils.sinDeg(rx) * scaleX; + let ld = spine.MathUtils.sinDeg(ry) * scaleY; + this.a = pa * la - pb * lc; + this.b = pa * lb - pb * ld; + this.c = pc * la + pd * lc; + this.d = pc * lb + pd * ld; + break; + } + case spine.TransformMode.NoScale: + case spine.TransformMode.NoScaleOrReflection: { + let cos = spine.MathUtils.cosDeg(rotation); + let sin = spine.MathUtils.sinDeg(rotation); + let za = (pa * cos + pb * sin) / this.skeleton.scaleX; + let zc = (pc * cos + pd * sin) / this.skeleton.scaleY; + let s = Math.sqrt(za * za + zc * zc); + if (s > 0.00001) + s = 1 / s; + za *= s; + zc *= s; + s = Math.sqrt(za * za + zc * zc); + if (this.data.transformMode == spine.TransformMode.NoScale + && (pa * pd - pb * pc < 0) != (this.skeleton.scaleX < 0 != this.skeleton.scaleY < 0)) + s = -s; + let r = Math.PI / 2 + Math.atan2(zc, za); + let zb = Math.cos(r) * s; + let zd = Math.sin(r) * s; + let la = spine.MathUtils.cosDeg(shearX) * scaleX; + let lb = spine.MathUtils.cosDeg(90 + shearY) * scaleY; + let lc = spine.MathUtils.sinDeg(shearX) * scaleX; + let ld = spine.MathUtils.sinDeg(90 + shearY) * scaleY; + this.a = za * la + zb * lc; + this.b = za * lb + zb * ld; + this.c = zc * la + zd * lc; + this.d = zc * lb + zd * ld; + break; + } + } + this.a *= this.skeleton.scaleX; + this.b *= this.skeleton.scaleX; + this.c *= this.skeleton.scaleY; + this.d *= this.skeleton.scaleY; + } + setToSetupPose() { + let data = this.data; + this.x = data.x; + this.y = data.y; + this.rotation = data.rotation; + this.scaleX = data.scaleX; + this.scaleY = data.scaleY; + this.shearX = data.shearX; + this.shearY = data.shearY; + } + getWorldRotationX() { + return Math.atan2(this.c, this.a) * spine.MathUtils.radDeg; + } + getWorldRotationY() { + return Math.atan2(this.d, this.b) * spine.MathUtils.radDeg; + } + getWorldScaleX() { + return Math.sqrt(this.a * this.a + this.c * this.c); + } + getWorldScaleY() { + return Math.sqrt(this.b * this.b + this.d * this.d); + } + updateAppliedTransform() { + this.appliedValid = true; + let parent = this.parent; + if (parent == null) { + this.ax = this.worldX; + this.ay = this.worldY; + this.arotation = Math.atan2(this.c, this.a) * spine.MathUtils.radDeg; + this.ascaleX = Math.sqrt(this.a * this.a + this.c * this.c); + this.ascaleY = Math.sqrt(this.b * this.b + this.d * this.d); + this.ashearX = 0; + this.ashearY = Math.atan2(this.a * this.b + this.c * this.d, this.a * this.d - this.b * this.c) * spine.MathUtils.radDeg; + return; + } + let pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d; + let pid = 1 / (pa * pd - pb * pc); + let dx = this.worldX - parent.worldX, dy = this.worldY - parent.worldY; + this.ax = (dx * pd * pid - dy * pb * pid); + this.ay = (dy * pa * pid - dx * pc * pid); + let ia = pid * pd; + let id = pid * pa; + let ib = pid * pb; + let ic = pid * pc; + let ra = ia * this.a - ib * this.c; + let rb = ia * this.b - ib * this.d; + let rc = id * this.c - ic * this.a; + let rd = id * this.d - ic * this.b; + this.ashearX = 0; + this.ascaleX = Math.sqrt(ra * ra + rc * rc); + if (this.ascaleX > 0.0001) { + let det = ra * rd - rb * rc; + this.ascaleY = det / this.ascaleX; + this.ashearY = Math.atan2(ra * rb + rc * rd, det) * spine.MathUtils.radDeg; + this.arotation = Math.atan2(rc, ra) * spine.MathUtils.radDeg; + } + else { + this.ascaleX = 0; + this.ascaleY = Math.sqrt(rb * rb + rd * rd); + this.ashearY = 0; + this.arotation = 90 - Math.atan2(rd, rb) * spine.MathUtils.radDeg; + } + } + worldToLocal(world) { + let a = this.a, b = this.b, c = this.c, d = this.d; + let invDet = 1 / (a * d - b * c); + let x = world.x - this.worldX, y = world.y - this.worldY; + world.x = (x * d * invDet - y * b * invDet); + world.y = (y * a * invDet - x * c * invDet); + return world; + } + localToWorld(local) { + let x = local.x, y = local.y; + local.x = x * this.a + y * this.b + this.worldX; + local.y = x * this.c + y * this.d + this.worldY; + return local; + } + worldToLocalRotation(worldRotation) { + let sin = spine.MathUtils.sinDeg(worldRotation), cos = spine.MathUtils.cosDeg(worldRotation); + return Math.atan2(this.a * sin - this.c * cos, this.d * cos - this.b * sin) * spine.MathUtils.radDeg + this.rotation - this.shearX; + } + localToWorldRotation(localRotation) { + localRotation -= this.rotation - this.shearX; + let sin = spine.MathUtils.sinDeg(localRotation), cos = spine.MathUtils.cosDeg(localRotation); + return Math.atan2(cos * this.c + sin * this.d, cos * this.a + sin * this.b) * spine.MathUtils.radDeg; + } + rotateWorld(degrees) { + let a = this.a, b = this.b, c = this.c, d = this.d; + let cos = spine.MathUtils.cosDeg(degrees), sin = spine.MathUtils.sinDeg(degrees); + this.a = cos * a - sin * c; + this.b = cos * b - sin * d; + this.c = sin * a + cos * c; + this.d = sin * b + cos * d; + this.appliedValid = false; + } + } + spine.Bone = Bone; +})(spine || (spine = {})); +var spine; +(function (spine) { + class BoneData { + constructor(index, name, parent) { + this.x = 0; + this.y = 0; + this.rotation = 0; + this.scaleX = 1; + this.scaleY = 1; + this.shearX = 0; + this.shearY = 0; + this.transformMode = TransformMode.Normal; + if (index < 0) + throw new Error("index must be >= 0."); + if (name == null) + throw new Error("name cannot be null."); + this.index = index; + this.name = name; + this.parent = parent; + } + } + spine.BoneData = BoneData; + let TransformMode; + (function (TransformMode) { + TransformMode[TransformMode["Normal"] = 0] = "Normal"; + TransformMode[TransformMode["OnlyTranslation"] = 1] = "OnlyTranslation"; + TransformMode[TransformMode["NoRotationOrReflection"] = 2] = "NoRotationOrReflection"; + TransformMode[TransformMode["NoScale"] = 3] = "NoScale"; + TransformMode[TransformMode["NoScaleOrReflection"] = 4] = "NoScaleOrReflection"; + })(TransformMode = spine.TransformMode || (spine.TransformMode = {})); +})(spine || (spine = {})); +var spine; +(function (spine) { + class Event { + constructor(time, data) { + if (data == null) + throw new Error("data cannot be null."); + this.time = time; + this.data = data; + } + } + spine.Event = Event; +})(spine || (spine = {})); +var spine; +(function (spine) { + class EventData { + constructor(name) { + this.name = name; + } + } + spine.EventData = EventData; +})(spine || (spine = {})); +var spine; +(function (spine) { + class IkConstraint { + constructor(data, skeleton) { + this.bendDirection = 0; + this.compress = false; + this.stretch = false; + this.mix = 1; + if (data == null) + throw new Error("data cannot be null."); + if (skeleton == null) + throw new Error("skeleton cannot be null."); + this.data = data; + this.mix = data.mix; + this.bendDirection = data.bendDirection; + this.compress = data.compress; + this.stretch = data.stretch; + this.bones = new Array(); + for (let i = 0; i < data.bones.length; i++) + this.bones.push(skeleton.findBone(data.bones[i].name)); + this.target = skeleton.findBone(data.target.name); + } + getOrder() { + return this.data.order; + } + apply() { + this.update(); + } + update() { + let target = this.target; + let bones = this.bones; + switch (bones.length) { + case 1: + this.apply1(bones[0], target.worldX, target.worldY, this.compress, this.stretch, this.data.uniform, this.mix); + break; + case 2: + this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.mix); + break; + } + } + apply1(bone, targetX, targetY, compress, stretch, uniform, alpha) { + if (!bone.appliedValid) + bone.updateAppliedTransform(); + let p = bone.parent; + let id = 1 / (p.a * p.d - p.b * p.c); + let x = targetX - p.worldX, y = targetY - p.worldY; + let tx = (x * p.d - y * p.b) * id - bone.ax, ty = (y * p.a - x * p.c) * id - bone.ay; + let rotationIK = Math.atan2(ty, tx) * spine.MathUtils.radDeg - bone.ashearX - bone.arotation; + if (bone.ascaleX < 0) + rotationIK += 180; + if (rotationIK > 180) + rotationIK -= 360; + else if (rotationIK < -180) + rotationIK += 360; + let sx = bone.ascaleX, sy = bone.ascaleY; + if (compress || stretch) { + let b = bone.data.length * sx, dd = Math.sqrt(tx * tx + ty * ty); + if ((compress && dd < b) || (stretch && dd > b) && b > 0.0001) { + let s = (dd / b - 1) * alpha + 1; + sx *= s; + if (uniform) + sy *= s; + } + } + bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, bone.ashearY); + } + apply2(parent, child, targetX, targetY, bendDir, stretch, alpha) { + if (alpha == 0) { + child.updateWorldTransform(); + return; + } + if (!parent.appliedValid) + parent.updateAppliedTransform(); + if (!child.appliedValid) + child.updateAppliedTransform(); + let px = parent.ax, py = parent.ay, psx = parent.ascaleX, sx = psx, psy = parent.ascaleY, csx = child.ascaleX; + let os1 = 0, os2 = 0, s2 = 0; + if (psx < 0) { + psx = -psx; + os1 = 180; + s2 = -1; + } + else { + os1 = 0; + s2 = 1; + } + if (psy < 0) { + psy = -psy; + s2 = -s2; + } + if (csx < 0) { + csx = -csx; + os2 = 180; + } + else + os2 = 0; + let cx = child.ax, cy = 0, cwx = 0, cwy = 0, a = parent.a, b = parent.b, c = parent.c, d = parent.d; + let u = Math.abs(psx - psy) <= 0.0001; + if (!u) { + cy = 0; + cwx = a * cx + parent.worldX; + cwy = c * cx + parent.worldY; + } + else { + cy = child.ay; + cwx = a * cx + b * cy + parent.worldX; + cwy = c * cx + d * cy + parent.worldY; + } + let pp = parent.parent; + a = pp.a; + b = pp.b; + c = pp.c; + d = pp.d; + let id = 1 / (a * d - b * c), x = targetX - pp.worldX, y = targetY - pp.worldY; + let tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py, dd = tx * tx + ty * ty; + x = cwx - pp.worldX; + y = cwy - pp.worldY; + let dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py; + let l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1 = 0, a2 = 0; + outer: if (u) { + l2 *= psx; + let cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2); + if (cos < -1) + cos = -1; + else if (cos > 1) { + cos = 1; + if (stretch && l1 + l2 > 0.0001) + sx *= (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1; + } + a2 = Math.acos(cos) * bendDir; + a = l1 + l2 * cos; + b = l2 * Math.sin(a2); + a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b); + } + else { + a = psx * l2; + b = psy * l2; + let aa = a * a, bb = b * b, ta = Math.atan2(ty, tx); + c = bb * l1 * l1 + aa * dd - aa * bb; + let c1 = -2 * bb * l1, c2 = bb - aa; + d = c1 * c1 - 4 * c2 * c; + if (d >= 0) { + let q = Math.sqrt(d); + if (c1 < 0) + q = -q; + q = -(c1 + q) / 2; + let r0 = q / c2, r1 = c / q; + let r = Math.abs(r0) < Math.abs(r1) ? r0 : r1; + if (r * r <= dd) { + y = Math.sqrt(dd - r * r) * bendDir; + a1 = ta - Math.atan2(y, r); + a2 = Math.atan2(y / psy, (r - l1) / psx); + break outer; + } + } + let minAngle = spine.MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0; + let maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0; + c = -a * l1 / (aa - bb); + if (c >= -1 && c <= 1) { + c = Math.acos(c); + x = a * Math.cos(c) + l1; + y = b * Math.sin(c); + d = x * x + y * y; + if (d < minDist) { + minAngle = c; + minDist = d; + minX = x; + minY = y; + } + if (d > maxDist) { + maxAngle = c; + maxDist = d; + maxX = x; + maxY = y; + } + } + if (dd <= (minDist + maxDist) / 2) { + a1 = ta - Math.atan2(minY * bendDir, minX); + a2 = minAngle * bendDir; + } + else { + a1 = ta - Math.atan2(maxY * bendDir, maxX); + a2 = maxAngle * bendDir; + } + } + let os = Math.atan2(cy, cx) * s2; + let rotation = parent.arotation; + a1 = (a1 - os) * spine.MathUtils.radDeg + os1 - rotation; + if (a1 > 180) + a1 -= 360; + else if (a1 < -180) + a1 += 360; + parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, parent.ascaleY, 0, 0); + rotation = child.arotation; + a2 = ((a2 + os) * spine.MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation; + if (a2 > 180) + a2 -= 360; + else if (a2 < -180) + a2 += 360; + child.updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); + } + } + spine.IkConstraint = IkConstraint; +})(spine || (spine = {})); +var spine; +(function (spine) { + class IkConstraintData { + constructor(name) { + this.order = 0; + this.bones = new Array(); + this.bendDirection = 1; + this.compress = false; + this.stretch = false; + this.uniform = false; + this.mix = 1; + this.name = name; + } + } + spine.IkConstraintData = IkConstraintData; +})(spine || (spine = {})); +var spine; +(function (spine) { + class PathConstraint { + constructor(data, skeleton) { + this.position = 0; + this.spacing = 0; + this.rotateMix = 0; + this.translateMix = 0; + this.spaces = new Array(); + this.positions = new Array(); + this.world = new Array(); + this.curves = new Array(); + this.lengths = new Array(); + this.segments = new Array(); + if (data == null) + throw new Error("data cannot be null."); + if (skeleton == null) + throw new Error("skeleton cannot be null."); + this.data = data; + this.bones = new Array(); + for (let i = 0, n = data.bones.length; i < n; i++) + this.bones.push(skeleton.findBone(data.bones[i].name)); + this.target = skeleton.findSlot(data.target.name); + this.position = data.position; + this.spacing = data.spacing; + this.rotateMix = data.rotateMix; + this.translateMix = data.translateMix; + } + apply() { + this.update(); + } + update() { + let attachment = this.target.getAttachment(); + if (!(attachment instanceof spine.PathAttachment)) + return; + let rotateMix = this.rotateMix, translateMix = this.translateMix; + let translate = translateMix > 0, rotate = rotateMix > 0; + if (!translate && !rotate) + return; + let data = this.data; + let percentSpacing = data.spacingMode == spine.SpacingMode.Percent; + let rotateMode = data.rotateMode; + let tangents = rotateMode == spine.RotateMode.Tangent, scale = rotateMode == spine.RotateMode.ChainScale; + let boneCount = this.bones.length, spacesCount = tangents ? boneCount : boneCount + 1; + let bones = this.bones; + let spaces = spine.Utils.setArraySize(this.spaces, spacesCount), lengths = null; + let spacing = this.spacing; + if (scale || !percentSpacing) { + if (scale) + lengths = spine.Utils.setArraySize(this.lengths, boneCount); + let lengthSpacing = data.spacingMode == spine.SpacingMode.Length; + for (let i = 0, n = spacesCount - 1; i < n;) { + let bone = bones[i]; + let setupLength = bone.data.length; + if (setupLength < PathConstraint.epsilon) { + if (scale) + lengths[i] = 0; + spaces[++i] = 0; + } + else if (percentSpacing) { + if (scale) { + let x = setupLength * bone.a, y = setupLength * bone.c; + let length = Math.sqrt(x * x + y * y); + lengths[i] = length; + } + spaces[++i] = spacing; + } + else { + let x = setupLength * bone.a, y = setupLength * bone.c; + let length = Math.sqrt(x * x + y * y); + if (scale) + lengths[i] = length; + spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength; + } + } + } + else { + for (let i = 1; i < spacesCount; i++) + spaces[i] = spacing; + } + let positions = this.computeWorldPositions(attachment, spacesCount, tangents, data.positionMode == spine.PositionMode.Percent, percentSpacing); + let boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation; + let tip = false; + if (offsetRotation == 0) + tip = rotateMode == spine.RotateMode.Chain; + else { + tip = false; + let p = this.target.bone; + offsetRotation *= p.a * p.d - p.b * p.c > 0 ? spine.MathUtils.degRad : -spine.MathUtils.degRad; + } + for (let i = 0, p = 3; i < boneCount; i++, p += 3) { + let bone = bones[i]; + bone.worldX += (boneX - bone.worldX) * translateMix; + bone.worldY += (boneY - bone.worldY) * translateMix; + let x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY; + if (scale) { + let length = lengths[i]; + if (length != 0) { + let s = (Math.sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1; + bone.a *= s; + bone.c *= s; + } + } + boneX = x; + boneY = y; + if (rotate) { + let a = bone.a, b = bone.b, c = bone.c, d = bone.d, r = 0, cos = 0, sin = 0; + if (tangents) + r = positions[p - 1]; + else if (spaces[i + 1] == 0) + r = positions[p + 2]; + else + r = Math.atan2(dy, dx); + r -= Math.atan2(c, a); + if (tip) { + cos = Math.cos(r); + sin = Math.sin(r); + let length = bone.data.length; + boneX += (length * (cos * a - sin * c) - dx) * rotateMix; + boneY += (length * (sin * a + cos * c) - dy) * rotateMix; + } + else { + r += offsetRotation; + } + if (r > spine.MathUtils.PI) + r -= spine.MathUtils.PI2; + else if (r < -spine.MathUtils.PI) + r += spine.MathUtils.PI2; + r *= rotateMix; + cos = Math.cos(r); + sin = Math.sin(r); + bone.a = cos * a - sin * c; + bone.b = cos * b - sin * d; + bone.c = sin * a + cos * c; + bone.d = sin * b + cos * d; + } + bone.appliedValid = false; + } + } + computeWorldPositions(path, spacesCount, tangents, percentPosition, percentSpacing) { + let target = this.target; + let position = this.position; + let spaces = this.spaces, out = spine.Utils.setArraySize(this.positions, spacesCount * 3 + 2), world = null; + let closed = path.closed; + let verticesLength = path.worldVerticesLength, curveCount = verticesLength / 6, prevCurve = PathConstraint.NONE; + if (!path.constantSpeed) { + let lengths = path.lengths; + curveCount -= closed ? 1 : 2; + let pathLength = lengths[curveCount]; + if (percentPosition) + position *= pathLength; + if (percentSpacing) { + for (let i = 1; i < spacesCount; i++) + spaces[i] *= pathLength; + } + world = spine.Utils.setArraySize(this.world, 8); + for (let i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) { + let space = spaces[i]; + position += space; + let p = position; + if (closed) { + p %= pathLength; + if (p < 0) + p += pathLength; + curve = 0; + } + else if (p < 0) { + if (prevCurve != PathConstraint.BEFORE) { + prevCurve = PathConstraint.BEFORE; + path.computeWorldVertices(target, 2, 4, world, 0, 2); + } + this.addBeforePosition(p, world, 0, out, o); + continue; + } + else if (p > pathLength) { + if (prevCurve != PathConstraint.AFTER) { + prevCurve = PathConstraint.AFTER; + path.computeWorldVertices(target, verticesLength - 6, 4, world, 0, 2); + } + this.addAfterPosition(p - pathLength, world, 0, out, o); + continue; + } + for (;; curve++) { + let length = lengths[curve]; + if (p > length) + continue; + if (curve == 0) + p /= length; + else { + let prev = lengths[curve - 1]; + p = (p - prev) / (length - prev); + } + break; + } + if (curve != prevCurve) { + prevCurve = curve; + if (closed && curve == curveCount) { + path.computeWorldVertices(target, verticesLength - 4, 4, world, 0, 2); + path.computeWorldVertices(target, 0, 4, world, 4, 2); + } + else + path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2); + } + this.addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o, tangents || (i > 0 && space == 0)); + } + return out; + } + if (closed) { + verticesLength += 2; + world = spine.Utils.setArraySize(this.world, verticesLength); + path.computeWorldVertices(target, 2, verticesLength - 4, world, 0, 2); + path.computeWorldVertices(target, 0, 2, world, verticesLength - 4, 2); + world[verticesLength - 2] = world[0]; + world[verticesLength - 1] = world[1]; + } + else { + curveCount--; + verticesLength -= 4; + world = spine.Utils.setArraySize(this.world, verticesLength); + path.computeWorldVertices(target, 2, verticesLength, world, 0, 2); + } + let curves = spine.Utils.setArraySize(this.curves, curveCount); + let pathLength = 0; + let x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0; + let tmpx = 0, tmpy = 0, dddfx = 0, dddfy = 0, ddfx = 0, ddfy = 0, dfx = 0, dfy = 0; + for (let i = 0, w = 2; i < curveCount; i++, w += 6) { + cx1 = world[w]; + cy1 = world[w + 1]; + cx2 = world[w + 2]; + cy2 = world[w + 3]; + x2 = world[w + 4]; + y2 = world[w + 5]; + tmpx = (x1 - cx1 * 2 + cx2) * 0.1875; + tmpy = (y1 - cy1 * 2 + cy2) * 0.1875; + dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375; + dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375; + ddfx = tmpx * 2 + dddfx; + ddfy = tmpy * 2 + dddfy; + dfx = (cx1 - x1) * 0.75 + tmpx + dddfx * 0.16666667; + dfy = (cy1 - y1) * 0.75 + tmpy + dddfy * 0.16666667; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx; + dfy += ddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx + dddfx; + dfy += ddfy + dddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + curves[i] = pathLength; + x1 = x2; + y1 = y2; + } + if (percentPosition) + position *= pathLength; + else + position *= pathLength / path.lengths[curveCount - 1]; + if (percentSpacing) { + for (let i = 1; i < spacesCount; i++) + spaces[i] *= pathLength; + } + let segments = this.segments; + let curveLength = 0; + for (let i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) { + let space = spaces[i]; + position += space; + let p = position; + if (closed) { + p %= pathLength; + if (p < 0) + p += pathLength; + curve = 0; + } + else if (p < 0) { + this.addBeforePosition(p, world, 0, out, o); + continue; + } + else if (p > pathLength) { + this.addAfterPosition(p - pathLength, world, verticesLength - 4, out, o); + continue; + } + for (;; curve++) { + let length = curves[curve]; + if (p > length) + continue; + if (curve == 0) + p /= length; + else { + let prev = curves[curve - 1]; + p = (p - prev) / (length - prev); + } + break; + } + if (curve != prevCurve) { + prevCurve = curve; + let ii = curve * 6; + x1 = world[ii]; + y1 = world[ii + 1]; + cx1 = world[ii + 2]; + cy1 = world[ii + 3]; + cx2 = world[ii + 4]; + cy2 = world[ii + 5]; + x2 = world[ii + 6]; + y2 = world[ii + 7]; + tmpx = (x1 - cx1 * 2 + cx2) * 0.03; + tmpy = (y1 - cy1 * 2 + cy2) * 0.03; + dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006; + dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.006; + ddfx = tmpx * 2 + dddfx; + ddfy = tmpy * 2 + dddfy; + dfx = (cx1 - x1) * 0.3 + tmpx + dddfx * 0.16666667; + dfy = (cy1 - y1) * 0.3 + tmpy + dddfy * 0.16666667; + curveLength = Math.sqrt(dfx * dfx + dfy * dfy); + segments[0] = curveLength; + for (ii = 1; ii < 8; ii++) { + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[ii] = curveLength; + } + dfx += ddfx; + dfy += ddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[8] = curveLength; + dfx += ddfx + dddfx; + dfy += ddfy + dddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[9] = curveLength; + segment = 0; + } + p *= curveLength; + for (;; segment++) { + let length = segments[segment]; + if (p > length) + continue; + if (segment == 0) + p /= length; + else { + let prev = segments[segment - 1]; + p = segment + (p - prev) / (length - prev); + } + break; + } + this.addCurvePosition(p * 0.1, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space == 0)); + } + return out; + } + addBeforePosition(p, temp, i, out, o) { + let x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = Math.atan2(dy, dx); + out[o] = x1 + p * Math.cos(r); + out[o + 1] = y1 + p * Math.sin(r); + out[o + 2] = r; + } + addAfterPosition(p, temp, i, out, o) { + let x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = Math.atan2(dy, dx); + out[o] = x1 + p * Math.cos(r); + out[o + 1] = y1 + p * Math.sin(r); + out[o + 2] = r; + } + addCurvePosition(p, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents) { + if (p == 0 || isNaN(p)) { + out[o] = x1; + out[o + 1] = y1; + out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1); + return; + } + let tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u; + let ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p; + let x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt; + out[o] = x; + out[o + 1] = y; + if (tangents) { + if (p < 0.001) + out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1); + else + out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt)); + } + } + getOrder() { + return this.data.order; + } + } + PathConstraint.NONE = -1; + PathConstraint.BEFORE = -2; + PathConstraint.AFTER = -3; + PathConstraint.epsilon = 0.00001; + spine.PathConstraint = PathConstraint; +})(spine || (spine = {})); +var spine; +(function (spine) { + class PathConstraintData { + constructor(name) { + this.order = 0; + this.bones = new Array(); + this.name = name; + } + } + spine.PathConstraintData = PathConstraintData; + let PositionMode; + (function (PositionMode) { + PositionMode[PositionMode["Fixed"] = 0] = "Fixed"; + PositionMode[PositionMode["Percent"] = 1] = "Percent"; + })(PositionMode = spine.PositionMode || (spine.PositionMode = {})); + let SpacingMode; + (function (SpacingMode) { + SpacingMode[SpacingMode["Length"] = 0] = "Length"; + SpacingMode[SpacingMode["Fixed"] = 1] = "Fixed"; + SpacingMode[SpacingMode["Percent"] = 2] = "Percent"; + })(SpacingMode = spine.SpacingMode || (spine.SpacingMode = {})); + let RotateMode; + (function (RotateMode) { + RotateMode[RotateMode["Tangent"] = 0] = "Tangent"; + RotateMode[RotateMode["Chain"] = 1] = "Chain"; + RotateMode[RotateMode["ChainScale"] = 2] = "ChainScale"; + })(RotateMode = spine.RotateMode || (spine.RotateMode = {})); +})(spine || (spine = {})); +var spine; +(function (spine) { + class Assets { + constructor(clientId) { + this.toLoad = new Array(); + this.assets = {}; + this.clientId = clientId; + } + loaded() { + let i = 0; + for (let v in this.assets) + i++; + return i; + } + } + class SharedAssetManager { + constructor(pathPrefix = "") { + this.clientAssets = {}; + this.queuedAssets = {}; + this.rawAssets = {}; + this.errors = {}; + this.pathPrefix = pathPrefix; + } + queueAsset(clientId, textureLoader, path) { + let clientAssets = this.clientAssets[clientId]; + if (clientAssets === null || clientAssets === undefined) { + clientAssets = new Assets(clientId); + this.clientAssets[clientId] = clientAssets; + } + if (textureLoader !== null) + clientAssets.textureLoader = textureLoader; + clientAssets.toLoad.push(path); + if (this.queuedAssets[path] === path) { + return false; + } + else { + this.queuedAssets[path] = path; + return true; + } + } + loadText(clientId, path) { + path = this.pathPrefix + path; + if (!this.queueAsset(clientId, null, path)) + return; + // LayaBox_Modify + // let request = new XMLHttpRequest(); + // request.onreadystatechange = () => { + // if (request.readyState == 4 /* XMLHttpRequest.DONE */) { + // if (request.status >= 200 && request.status < 300 || request.status == 0) { + // this.rawAssets[path] = request.responseText; + // } + // else { + // this.errors[path] = `Couldn't load text ${path}: status ${request.status}, ${request.responseText}`; + // } + // } + // }; + // request.open("GET", path, true); + // request.send(); + let _Laya = Laya.Laya ? Laya.Laya : Laya; + _Laya.loader.load([{type: _Laya.Loader.TEXT, url: path}], _Laya.Handler.create(this, (re) => { + if (re) { + this.rawAssets[path] = _Laya.loader.getRes(path); + } else { + this.errors[path] = `Couldn't load text ${path}`; + } + })); + } + loadJson(clientId, path) { + path = this.pathPrefix + path; + if (!this.queueAsset(clientId, null, path)) + return; + // LayaBox_Modify + // let request = new XMLHttpRequest(); + // request.onreadystatechange = () => { + // if (request.readyState == 4 /* XMLHttpRequest.DONE */) { + // if (request.status >= 200 && request.status < 300 || request.status == 0) { + // this.rawAssets[path] = JSON.parse(request.responseText); + // } + // else { + // this.errors[path] = `Couldn't load text ${path}: status ${request.status}, ${request.responseText}`; + // } + // } + // }; + // request.open("GET", path, true); + // request.send(); + let _Laya = Laya.Laya ? Laya.Laya : Laya; + _Laya.loader.load([{type: _Laya.Loader.JSON, url: path}], _Laya.Handler.create(this, (re) => { + if (re) { + this.rawAssets[path] = _Laya.loader.getRes(path); + } else { + this.errors[path] = `Couldn't load text ${path}`; + } + })); + } + loadTexture(clientId, textureLoader, path) { + path = this.pathPrefix + path; + if (!this.queueAsset(clientId, textureLoader, path)) + return; + // LayaBox_Modify + // let img = new Image(); + // img.crossOrigin = "anonymous"; + // img.onload = (ev) => { + // this.rawAssets[path] = img; + // }; + // img.onerror = (ev) => { + // this.errors[path] = `Couldn't load image ${path}`; + // }; + // img.src = path; + // if(!window._imgref) + // window._imgref = {}; + // if(!window._imgref[clientId]) + // window._imgref[clientId] = []; + // window._imgref[clientId].push(img); + let _Laya = Laya.Laya ? Laya.Laya : Laya; + _Laya.loader.load([{type: _Laya.Loader.IMAGE, url: path}], _Laya.Handler.create(this, (re) => { + if (re) { + this.rawAssets[path] = _Laya.loader.getRes(path); + } else { + this.errors[path] = `Couldn't load text ${path}`; + } + })); + } + get(clientId, path) { + path = this.pathPrefix + path; + let clientAssets = this.clientAssets[clientId]; + if (clientAssets === null || clientAssets === undefined) + return true; + return clientAssets.assets[path]; + } + updateClientAssets(clientAssets) { + for (let i = 0; i < clientAssets.toLoad.length; i++) { + let path = clientAssets.toLoad[i]; + let asset = clientAssets.assets[path]; + if (asset === null || asset === undefined) { + let rawAsset = this.rawAssets[path]; + if (rawAsset === null || rawAsset === undefined) + continue; + // LayaBox_Modify + // if (rawAsset instanceof HTMLImageElement) { + if (typeof rawAsset == "object" && !!rawAsset._bitmap) { + clientAssets.assets[path] = clientAssets.textureLoader(rawAsset); + } + else { + clientAssets.assets[path] = rawAsset; + } + } + } + } + isLoadingComplete(clientId) { + let clientAssets = this.clientAssets[clientId]; + if (clientAssets === null || clientAssets === undefined) { + this.destoryImg(clientId); + return true; + } + this.updateClientAssets(clientAssets); + if (clientAssets.toLoad.length == clientAssets.loaded()) { + this.destoryImg(clientId); + return true; + } + return false; + } + dispose() { + } + hasErrors() { + return Object.keys(this.errors).length > 0; + } + getErrors() { + return this.errors; + } + destoryImg(clientId) { + if(!window._imgref || !window._imgref[clientId]) + return; + delete window._imgref[clientId]; + } + } + spine.SharedAssetManager = SharedAssetManager; +})(spine || (spine = {})); +var spine; +(function (spine) { + class Skeleton { + constructor(data) { + this._updateCache = new Array(); + this.updateCacheReset = new Array(); + this.time = 0; + this.scaleX = 1; + this.scaleY = 1; + this.x = 0; + this.y = 0; + if (data == null) + throw new Error("data cannot be null."); + this.data = data; + this.bones = new Array(); + for (let i = 0; i < data.bones.length; i++) { + let boneData = data.bones[i]; + let bone; + if (boneData.parent == null) + bone = new spine.Bone(boneData, this, null); + else { + let parent = this.bones[boneData.parent.index]; + bone = new spine.Bone(boneData, this, parent); + parent.children.push(bone); + } + this.bones.push(bone); + } + this.slots = new Array(); + this.drawOrder = new Array(); + for (let i = 0; i < data.slots.length; i++) { + let slotData = data.slots[i]; + let bone = this.bones[slotData.boneData.index]; + let slot = new spine.Slot(slotData, bone); + this.slots.push(slot); + this.drawOrder.push(slot); + } + this.ikConstraints = new Array(); + for (let i = 0; i < data.ikConstraints.length; i++) { + let ikConstraintData = data.ikConstraints[i]; + this.ikConstraints.push(new spine.IkConstraint(ikConstraintData, this)); + } + this.transformConstraints = new Array(); + for (let i = 0; i < data.transformConstraints.length; i++) { + let transformConstraintData = data.transformConstraints[i]; + this.transformConstraints.push(new spine.TransformConstraint(transformConstraintData, this)); + } + this.pathConstraints = new Array(); + for (let i = 0; i < data.pathConstraints.length; i++) { + let pathConstraintData = data.pathConstraints[i]; + this.pathConstraints.push(new spine.PathConstraint(pathConstraintData, this)); + } + this.color = new spine.Color(1, 1, 1, 1); + this.updateCache(); + } + updateCache() { + let updateCache = this._updateCache; + updateCache.length = 0; + this.updateCacheReset.length = 0; + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) + bones[i].sorted = false; + let ikConstraints = this.ikConstraints; + let transformConstraints = this.transformConstraints; + let pathConstraints = this.pathConstraints; + let ikCount = ikConstraints.length, transformCount = transformConstraints.length, pathCount = pathConstraints.length; + let constraintCount = ikCount + transformCount + pathCount; + outer: for (let i = 0; i < constraintCount; i++) { + for (let ii = 0; ii < ikCount; ii++) { + let constraint = ikConstraints[ii]; + if (constraint.data.order == i) { + this.sortIkConstraint(constraint); + continue outer; + } + } + for (let ii = 0; ii < transformCount; ii++) { + let constraint = transformConstraints[ii]; + if (constraint.data.order == i) { + this.sortTransformConstraint(constraint); + continue outer; + } + } + for (let ii = 0; ii < pathCount; ii++) { + let constraint = pathConstraints[ii]; + if (constraint.data.order == i) { + this.sortPathConstraint(constraint); + continue outer; + } + } + } + for (let i = 0, n = bones.length; i < n; i++) + this.sortBone(bones[i]); + } + sortIkConstraint(constraint) { + let target = constraint.target; + this.sortBone(target); + let constrained = constraint.bones; + let parent = constrained[0]; + this.sortBone(parent); + if (constrained.length > 1) { + let child = constrained[constrained.length - 1]; + if (!(this._updateCache.indexOf(child) > -1)) + this.updateCacheReset.push(child); + } + this._updateCache.push(constraint); + this.sortReset(parent.children); + constrained[constrained.length - 1].sorted = true; + } + sortPathConstraint(constraint) { + let slot = constraint.target; + let slotIndex = slot.data.index; + let slotBone = slot.bone; + if (this.skin != null) + this.sortPathConstraintAttachment(this.skin, slotIndex, slotBone); + if (this.data.defaultSkin != null && this.data.defaultSkin != this.skin) + this.sortPathConstraintAttachment(this.data.defaultSkin, slotIndex, slotBone); + for (let i = 0, n = this.data.skins.length; i < n; i++) + this.sortPathConstraintAttachment(this.data.skins[i], slotIndex, slotBone); + let attachment = slot.getAttachment(); + if (attachment instanceof spine.PathAttachment) + this.sortPathConstraintAttachmentWith(attachment, slotBone); + let constrained = constraint.bones; + let boneCount = constrained.length; + for (let i = 0; i < boneCount; i++) + this.sortBone(constrained[i]); + this._updateCache.push(constraint); + for (let i = 0; i < boneCount; i++) + this.sortReset(constrained[i].children); + for (let i = 0; i < boneCount; i++) + constrained[i].sorted = true; + } + sortTransformConstraint(constraint) { + this.sortBone(constraint.target); + let constrained = constraint.bones; + let boneCount = constrained.length; + if (constraint.data.local) { + for (let i = 0; i < boneCount; i++) { + let child = constrained[i]; + this.sortBone(child.parent); + if (!(this._updateCache.indexOf(child) > -1)) + this.updateCacheReset.push(child); + } + } + else { + for (let i = 0; i < boneCount; i++) { + this.sortBone(constrained[i]); + } + } + this._updateCache.push(constraint); + for (let ii = 0; ii < boneCount; ii++) + this.sortReset(constrained[ii].children); + for (let ii = 0; ii < boneCount; ii++) + constrained[ii].sorted = true; + } + sortPathConstraintAttachment(skin, slotIndex, slotBone) { + let attachments = skin.attachments[slotIndex]; + if (!attachments) + return; + for (let key in attachments) { + this.sortPathConstraintAttachmentWith(attachments[key], slotBone); + } + } + sortPathConstraintAttachmentWith(attachment, slotBone) { + if (!(attachment instanceof spine.PathAttachment)) + return; + let pathBones = attachment.bones; + if (pathBones == null) + this.sortBone(slotBone); + else { + let bones = this.bones; + let i = 0; + while (i < pathBones.length) { + let boneCount = pathBones[i++]; + for (let n = i + boneCount; i < n; i++) { + let boneIndex = pathBones[i]; + this.sortBone(bones[boneIndex]); + } + } + } + } + sortBone(bone) { + if (bone.sorted) + return; + let parent = bone.parent; + if (parent != null) + this.sortBone(parent); + bone.sorted = true; + this._updateCache.push(bone); + } + sortReset(bones) { + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (bone.sorted) + this.sortReset(bone.children); + bone.sorted = false; + } + } + updateWorldTransform() { + let updateCacheReset = this.updateCacheReset; + for (let i = 0, n = updateCacheReset.length; i < n; i++) { + let bone = updateCacheReset[i]; + bone.ax = bone.x; + bone.ay = bone.y; + bone.arotation = bone.rotation; + bone.ascaleX = bone.scaleX; + bone.ascaleY = bone.scaleY; + bone.ashearX = bone.shearX; + bone.ashearY = bone.shearY; + bone.appliedValid = true; + } + let updateCache = this._updateCache; + for (let i = 0, n = updateCache.length; i < n; i++) + updateCache[i].update(); + } + setToSetupPose() { + this.setBonesToSetupPose(); + this.setSlotsToSetupPose(); + } + setBonesToSetupPose() { + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) + bones[i].setToSetupPose(); + let ikConstraints = this.ikConstraints; + for (let i = 0, n = ikConstraints.length; i < n; i++) { + let constraint = ikConstraints[i]; + constraint.mix = constraint.data.mix; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + let transformConstraints = this.transformConstraints; + for (let i = 0, n = transformConstraints.length; i < n; i++) { + let constraint = transformConstraints[i]; + let data = constraint.data; + constraint.rotateMix = data.rotateMix; + constraint.translateMix = data.translateMix; + constraint.scaleMix = data.scaleMix; + constraint.shearMix = data.shearMix; + } + let pathConstraints = this.pathConstraints; + for (let i = 0, n = pathConstraints.length; i < n; i++) { + let constraint = pathConstraints[i]; + let data = constraint.data; + constraint.position = data.position; + constraint.spacing = data.spacing; + constraint.rotateMix = data.rotateMix; + constraint.translateMix = data.translateMix; + } + } + setSlotsToSetupPose() { + let slots = this.slots; + spine.Utils.arrayCopy(slots, 0, this.drawOrder, 0, slots.length); + for (let i = 0, n = slots.length; i < n; i++) + slots[i].setToSetupPose(); + } + getRootBone() { + if (this.bones.length == 0) + return null; + return this.bones[0]; + } + findBone(boneName) { + if (boneName == null) + throw new Error("boneName cannot be null."); + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (bone.data.name == boneName) + return bone; + } + return null; + } + findBoneIndex(boneName) { + if (boneName == null) + throw new Error("boneName cannot be null."); + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) + if (bones[i].data.name == boneName) + return i; + return -1; + } + findSlot(slotName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) { + let slot = slots[i]; + if (slot.data.name == slotName) + return slot; + } + return null; + } + findSlotIndex(slotName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) + if (slots[i].data.name == slotName) + return i; + return -1; + } + setSkinByName(skinName) { + let skin = this.data.findSkin(skinName); + if (skin == null) + throw new Error("Skin not found: " + skinName); + this.setSkin(skin); + } + setSkin(newSkin) { + if (newSkin != null) { + if (this.skin != null) + newSkin.attachAll(this, this.skin); + else { + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) { + let slot = slots[i]; + let name = slot.data.attachmentName; + if (name != null) { + let attachment = newSkin.getAttachment(i, name); + if (attachment != null) + slot.setAttachment(attachment); + } + } + } + } + this.skin = newSkin; + } + getAttachmentByName(slotName, attachmentName) { + return this.getAttachment(this.data.findSlotIndex(slotName), attachmentName); + } + getAttachment(slotIndex, attachmentName) { + if (attachmentName == null) + throw new Error("attachmentName cannot be null."); + if (this.skin != null) { + let attachment = this.skin.getAttachment(slotIndex, attachmentName); + if (attachment != null) + return attachment; + } + if (this.data.defaultSkin != null) + return this.data.defaultSkin.getAttachment(slotIndex, attachmentName); + return null; + } + setAttachment(slotName, attachmentName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) { + let slot = slots[i]; + if (slot.data.name == slotName) { + let attachment = null; + if (attachmentName != null) { + attachment = this.getAttachment(i, attachmentName); + if (attachment == null) + throw new Error("Attachment not found: " + attachmentName + ", for slot: " + slotName); + } + slot.setAttachment(attachment); + return; + } + } + throw new Error("Slot not found: " + slotName); + } + findIkConstraint(constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + let ikConstraints = this.ikConstraints; + for (let i = 0, n = ikConstraints.length; i < n; i++) { + let ikConstraint = ikConstraints[i]; + if (ikConstraint.data.name == constraintName) + return ikConstraint; + } + return null; + } + findTransformConstraint(constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + let transformConstraints = this.transformConstraints; + for (let i = 0, n = transformConstraints.length; i < n; i++) { + let constraint = transformConstraints[i]; + if (constraint.data.name == constraintName) + return constraint; + } + return null; + } + findPathConstraint(constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + let pathConstraints = this.pathConstraints; + for (let i = 0, n = pathConstraints.length; i < n; i++) { + let constraint = pathConstraints[i]; + if (constraint.data.name == constraintName) + return constraint; + } + return null; + } + getBounds(offset, size, temp = new Array(2)) { + if (offset == null) + throw new Error("offset cannot be null."); + if (size == null) + throw new Error("size cannot be null."); + let drawOrder = this.drawOrder; + let minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY; + for (let i = 0, n = drawOrder.length; i < n; i++) { + let slot = drawOrder[i]; + let verticesLength = 0; + let vertices = null; + let attachment = slot.getAttachment(); + if (attachment instanceof spine.RegionAttachment) { + verticesLength = 8; + vertices = spine.Utils.setArraySize(temp, verticesLength, 0); + attachment.computeWorldVertices(slot.bone, vertices, 0, 2); + } + else if (attachment instanceof spine.MeshAttachment) { + let mesh = attachment; + verticesLength = mesh.worldVerticesLength; + vertices = spine.Utils.setArraySize(temp, verticesLength, 0); + mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2); + } + if (vertices != null) { + for (let ii = 0, nn = vertices.length; ii < nn; ii += 2) { + let x = vertices[ii], y = vertices[ii + 1]; + minX = Math.min(minX, x); + minY = Math.min(minY, y); + maxX = Math.max(maxX, x); + maxY = Math.max(maxY, y); + } + } + } + offset.set(minX, minY); + size.set(maxX - minX, maxY - minY); + } + update(delta) { + this.time += delta; + } + } + spine.Skeleton = Skeleton; +})(spine || (spine = {})); +var spine; +(function (spine) { + class SkeletonBounds { + constructor() { + this.minX = 0; + this.minY = 0; + this.maxX = 0; + this.maxY = 0; + this.boundingBoxes = new Array(); + this.polygons = new Array(); + this.polygonPool = new spine.Pool(() => { + return spine.Utils.newFloatArray(16); + }); + } + update(skeleton, updateAabb) { + if (skeleton == null) + throw new Error("skeleton cannot be null."); + let boundingBoxes = this.boundingBoxes; + let polygons = this.polygons; + let polygonPool = this.polygonPool; + let slots = skeleton.slots; + let slotCount = slots.length; + boundingBoxes.length = 0; + polygonPool.freeAll(polygons); + polygons.length = 0; + for (let i = 0; i < slotCount; i++) { + let slot = slots[i]; + let attachment = slot.getAttachment(); + if (attachment instanceof spine.BoundingBoxAttachment) { + let boundingBox = attachment; + boundingBoxes.push(boundingBox); + let polygon = polygonPool.obtain(); + if (polygon.length != boundingBox.worldVerticesLength) { + polygon = spine.Utils.newFloatArray(boundingBox.worldVerticesLength); + } + polygons.push(polygon); + boundingBox.computeWorldVertices(slot, 0, boundingBox.worldVerticesLength, polygon, 0, 2); + } + } + if (updateAabb) { + this.aabbCompute(); + } + else { + this.minX = Number.POSITIVE_INFINITY; + this.minY = Number.POSITIVE_INFINITY; + this.maxX = Number.NEGATIVE_INFINITY; + this.maxY = Number.NEGATIVE_INFINITY; + } + } + aabbCompute() { + let minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY; + let polygons = this.polygons; + for (let i = 0, n = polygons.length; i < n; i++) { + let polygon = polygons[i]; + let vertices = polygon; + for (let ii = 0, nn = polygon.length; ii < nn; ii += 2) { + let x = vertices[ii]; + let y = vertices[ii + 1]; + minX = Math.min(minX, x); + minY = Math.min(minY, y); + maxX = Math.max(maxX, x); + maxY = Math.max(maxY, y); + } + } + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + } + aabbContainsPoint(x, y) { + return x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY; + } + aabbIntersectsSegment(x1, y1, x2, y2) { + let minX = this.minX; + let minY = this.minY; + let maxX = this.maxX; + let maxY = this.maxY; + if ((x1 <= minX && x2 <= minX) || (y1 <= minY && y2 <= minY) || (x1 >= maxX && x2 >= maxX) || (y1 >= maxY && y2 >= maxY)) + return false; + let m = (y2 - y1) / (x2 - x1); + let y = m * (minX - x1) + y1; + if (y > minY && y < maxY) + return true; + y = m * (maxX - x1) + y1; + if (y > minY && y < maxY) + return true; + let x = (minY - y1) / m + x1; + if (x > minX && x < maxX) + return true; + x = (maxY - y1) / m + x1; + if (x > minX && x < maxX) + return true; + return false; + } + aabbIntersectsSkeleton(bounds) { + return this.minX < bounds.maxX && this.maxX > bounds.minX && this.minY < bounds.maxY && this.maxY > bounds.minY; + } + containsPoint(x, y) { + let polygons = this.polygons; + for (let i = 0, n = polygons.length; i < n; i++) + if (this.containsPointPolygon(polygons[i], x, y)) + return this.boundingBoxes[i]; + return null; + } + containsPointPolygon(polygon, x, y) { + let vertices = polygon; + let nn = polygon.length; + let prevIndex = nn - 2; + let inside = false; + for (let ii = 0; ii < nn; ii += 2) { + let vertexY = vertices[ii + 1]; + let prevY = vertices[prevIndex + 1]; + if ((vertexY < y && prevY >= y) || (prevY < y && vertexY >= y)) { + let vertexX = vertices[ii]; + if (vertexX + (y - vertexY) / (prevY - vertexY) * (vertices[prevIndex] - vertexX) < x) + inside = !inside; + } + prevIndex = ii; + } + return inside; + } + intersectsSegment(x1, y1, x2, y2) { + let polygons = this.polygons; + for (let i = 0, n = polygons.length; i < n; i++) + if (this.intersectsSegmentPolygon(polygons[i], x1, y1, x2, y2)) + return this.boundingBoxes[i]; + return null; + } + intersectsSegmentPolygon(polygon, x1, y1, x2, y2) { + let vertices = polygon; + let nn = polygon.length; + let width12 = x1 - x2, height12 = y1 - y2; + let det1 = x1 * y2 - y1 * x2; + let x3 = vertices[nn - 2], y3 = vertices[nn - 1]; + for (let ii = 0; ii < nn; ii += 2) { + let x4 = vertices[ii], y4 = vertices[ii + 1]; + let det2 = x3 * y4 - y3 * x4; + let width34 = x3 - x4, height34 = y3 - y4; + let det3 = width12 * height34 - height12 * width34; + let x = (det1 * width34 - width12 * det2) / det3; + if (((x >= x3 && x <= x4) || (x >= x4 && x <= x3)) && ((x >= x1 && x <= x2) || (x >= x2 && x <= x1))) { + let y = (det1 * height34 - height12 * det2) / det3; + if (((y >= y3 && y <= y4) || (y >= y4 && y <= y3)) && ((y >= y1 && y <= y2) || (y >= y2 && y <= y1))) + return true; + } + x3 = x4; + y3 = y4; + } + return false; + } + getPolygon(boundingBox) { + if (boundingBox == null) + throw new Error("boundingBox cannot be null."); + let index = this.boundingBoxes.indexOf(boundingBox); + return index == -1 ? null : this.polygons[index]; + } + getWidth() { + return this.maxX - this.minX; + } + getHeight() { + return this.maxY - this.minY; + } + } + spine.SkeletonBounds = SkeletonBounds; +})(spine || (spine = {})); +var spine; +(function (spine) { + class SkeletonClipping { + constructor() { + this.triangulator = new spine.Triangulator(); + this.clippingPolygon = new Array(); + this.clipOutput = new Array(); + this.clippedVertices = new Array(); + this.clippedTriangles = new Array(); + this.scratch = new Array(); + } + clipStart(slot, clip) { + if (this.clipAttachment != null) + return 0; + this.clipAttachment = clip; + let n = clip.worldVerticesLength; + let vertices = spine.Utils.setArraySize(this.clippingPolygon, n); + clip.computeWorldVertices(slot, 0, n, vertices, 0, 2); + let clippingPolygon = this.clippingPolygon; + SkeletonClipping.makeClockwise(clippingPolygon); + let clippingPolygons = this.clippingPolygons = this.triangulator.decompose(clippingPolygon, this.triangulator.triangulate(clippingPolygon)); + for (let i = 0, n = clippingPolygons.length; i < n; i++) { + let polygon = clippingPolygons[i]; + SkeletonClipping.makeClockwise(polygon); + polygon.push(polygon[0]); + polygon.push(polygon[1]); + } + return clippingPolygons.length; + } + clipEndWithSlot(slot) { + if (this.clipAttachment != null && this.clipAttachment.endSlot == slot.data) + this.clipEnd(); + } + clipEnd() { + if (this.clipAttachment == null) + return; + this.clipAttachment = null; + this.clippingPolygons = null; + this.clippedVertices.length = 0; + this.clippedTriangles.length = 0; + this.clippingPolygon.length = 0; + } + isClipping() { + return this.clipAttachment != null; + } + clipTriangles(vertices, verticesLength, triangles, trianglesLength, uvs, light, dark, twoColor) { + let clipOutput = this.clipOutput, clippedVertices = this.clippedVertices; + let clippedTriangles = this.clippedTriangles; + let polygons = this.clippingPolygons; + let polygonsCount = this.clippingPolygons.length; + let vertexSize = twoColor ? 12 : 8; + let index = 0; + clippedVertices.length = 0; + clippedTriangles.length = 0; + outer: for (let i = 0; i < trianglesLength; i += 3) { + let vertexOffset = triangles[i] << 1; + let x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1]; + let u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1]; + vertexOffset = triangles[i + 1] << 1; + let x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1]; + let u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1]; + vertexOffset = triangles[i + 2] << 1; + let x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1]; + let u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1]; + for (let p = 0; p < polygonsCount; p++) { + let s = clippedVertices.length; + if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) { + let clipOutputLength = clipOutput.length; + if (clipOutputLength == 0) + continue; + let d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1; + let d = 1 / (d0 * d2 + d1 * (y1 - y3)); + let clipOutputCount = clipOutputLength >> 1; + let clipOutputItems = this.clipOutput; + let clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + clipOutputCount * vertexSize); + for (let ii = 0; ii < clipOutputLength; ii += 2) { + let x = clipOutputItems[ii], y = clipOutputItems[ii + 1]; + clippedVerticesItems[s] = x; + clippedVerticesItems[s + 1] = y; + clippedVerticesItems[s + 2] = light.r; + clippedVerticesItems[s + 3] = light.g; + clippedVerticesItems[s + 4] = light.b; + clippedVerticesItems[s + 5] = light.a; + let c0 = x - x3, c1 = y - y3; + let a = (d0 * c0 + d1 * c1) * d; + let b = (d4 * c0 + d2 * c1) * d; + let c = 1 - a - b; + clippedVerticesItems[s + 6] = u1 * a + u2 * b + u3 * c; + clippedVerticesItems[s + 7] = v1 * a + v2 * b + v3 * c; + if (twoColor) { + clippedVerticesItems[s + 8] = dark.r; + clippedVerticesItems[s + 9] = dark.g; + clippedVerticesItems[s + 10] = dark.b; + clippedVerticesItems[s + 11] = dark.a; + } + s += vertexSize; + } + s = clippedTriangles.length; + let clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2)); + clipOutputCount--; + for (let ii = 1; ii < clipOutputCount; ii++) { + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = (index + ii); + clippedTrianglesItems[s + 2] = (index + ii + 1); + s += 3; + } + index += clipOutputCount + 1; + } + else { + let clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + 3 * vertexSize); + clippedVerticesItems[s] = x1; + clippedVerticesItems[s + 1] = y1; + clippedVerticesItems[s + 2] = light.r; + clippedVerticesItems[s + 3] = light.g; + clippedVerticesItems[s + 4] = light.b; + clippedVerticesItems[s + 5] = light.a; + if (!twoColor) { + clippedVerticesItems[s + 6] = u1; + clippedVerticesItems[s + 7] = v1; + clippedVerticesItems[s + 8] = x2; + clippedVerticesItems[s + 9] = y2; + clippedVerticesItems[s + 10] = light.r; + clippedVerticesItems[s + 11] = light.g; + clippedVerticesItems[s + 12] = light.b; + clippedVerticesItems[s + 13] = light.a; + clippedVerticesItems[s + 14] = u2; + clippedVerticesItems[s + 15] = v2; + clippedVerticesItems[s + 16] = x3; + clippedVerticesItems[s + 17] = y3; + clippedVerticesItems[s + 18] = light.r; + clippedVerticesItems[s + 19] = light.g; + clippedVerticesItems[s + 20] = light.b; + clippedVerticesItems[s + 21] = light.a; + clippedVerticesItems[s + 22] = u3; + clippedVerticesItems[s + 23] = v3; + } + else { + clippedVerticesItems[s + 6] = u1; + clippedVerticesItems[s + 7] = v1; + clippedVerticesItems[s + 8] = dark.r; + clippedVerticesItems[s + 9] = dark.g; + clippedVerticesItems[s + 10] = dark.b; + clippedVerticesItems[s + 11] = dark.a; + clippedVerticesItems[s + 12] = x2; + clippedVerticesItems[s + 13] = y2; + clippedVerticesItems[s + 14] = light.r; + clippedVerticesItems[s + 15] = light.g; + clippedVerticesItems[s + 16] = light.b; + clippedVerticesItems[s + 17] = light.a; + clippedVerticesItems[s + 18] = u2; + clippedVerticesItems[s + 19] = v2; + clippedVerticesItems[s + 20] = dark.r; + clippedVerticesItems[s + 21] = dark.g; + clippedVerticesItems[s + 22] = dark.b; + clippedVerticesItems[s + 23] = dark.a; + clippedVerticesItems[s + 24] = x3; + clippedVerticesItems[s + 25] = y3; + clippedVerticesItems[s + 26] = light.r; + clippedVerticesItems[s + 27] = light.g; + clippedVerticesItems[s + 28] = light.b; + clippedVerticesItems[s + 29] = light.a; + clippedVerticesItems[s + 30] = u3; + clippedVerticesItems[s + 31] = v3; + clippedVerticesItems[s + 32] = dark.r; + clippedVerticesItems[s + 33] = dark.g; + clippedVerticesItems[s + 34] = dark.b; + clippedVerticesItems[s + 35] = dark.a; + } + s = clippedTriangles.length; + let clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3); + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = (index + 1); + clippedTrianglesItems[s + 2] = (index + 2); + index += 3; + continue outer; + } + } + } + } + clip(x1, y1, x2, y2, x3, y3, clippingArea, output) { + let originalOutput = output; + let clipped = false; + let input = null; + if (clippingArea.length % 4 >= 2) { + input = output; + output = this.scratch; + } + else + input = this.scratch; + input.length = 0; + input.push(x1); + input.push(y1); + input.push(x2); + input.push(y2); + input.push(x3); + input.push(y3); + input.push(x1); + input.push(y1); + output.length = 0; + let clippingVertices = clippingArea; + let clippingVerticesLast = clippingArea.length - 4; + for (let i = 0;; i += 2) { + let edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1]; + let edgeX2 = clippingVertices[i + 2], edgeY2 = clippingVertices[i + 3]; + let deltaX = edgeX - edgeX2, deltaY = edgeY - edgeY2; + let inputVertices = input; + let inputVerticesLength = input.length - 2, outputStart = output.length; + for (let ii = 0; ii < inputVerticesLength; ii += 2) { + let inputX = inputVertices[ii], inputY = inputVertices[ii + 1]; + let inputX2 = inputVertices[ii + 2], inputY2 = inputVertices[ii + 3]; + let side2 = deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0; + if (deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0) { + if (side2) { + output.push(inputX2); + output.push(inputY2); + continue; + } + let c0 = inputY2 - inputY, c2 = inputX2 - inputX; + let s = c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY); + if (Math.abs(s) > 0.000001) { + let ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / s; + output.push(edgeX + (edgeX2 - edgeX) * ua); + output.push(edgeY + (edgeY2 - edgeY) * ua); + } + else { + output.push(edgeX); + output.push(edgeY); + } + } + else if (side2) { + let c0 = inputY2 - inputY, c2 = inputX2 - inputX; + let s = c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY); + if (Math.abs(s) > 0.000001) { + let ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / s; + output.push(edgeX + (edgeX2 - edgeX) * ua); + output.push(edgeY + (edgeY2 - edgeY) * ua); + } + else { + output.push(edgeX); + output.push(edgeY); + } + output.push(inputX2); + output.push(inputY2); + } + clipped = true; + } + if (outputStart == output.length) { + originalOutput.length = 0; + return true; + } + output.push(output[0]); + output.push(output[1]); + if (i == clippingVerticesLast) + break; + let temp = output; + output = input; + output.length = 0; + input = temp; + } + if (originalOutput != output) { + originalOutput.length = 0; + for (let i = 0, n = output.length - 2; i < n; i++) + originalOutput[i] = output[i]; + } + else + originalOutput.length = originalOutput.length - 2; + return clipped; + } + static makeClockwise(polygon) { + let vertices = polygon; + let verticeslength = polygon.length; + let area = vertices[verticeslength - 2] * vertices[1] - vertices[0] * vertices[verticeslength - 1], p1x = 0, p1y = 0, p2x = 0, p2y = 0; + for (let i = 0, n = verticeslength - 3; i < n; i += 2) { + p1x = vertices[i]; + p1y = vertices[i + 1]; + p2x = vertices[i + 2]; + p2y = vertices[i + 3]; + area += p1x * p2y - p2x * p1y; + } + if (area < 0) + return; + for (let i = 0, lastX = verticeslength - 2, n = verticeslength >> 1; i < n; i += 2) { + let x = vertices[i], y = vertices[i + 1]; + let other = lastX - i; + vertices[i] = vertices[other]; + vertices[i + 1] = vertices[other + 1]; + vertices[other] = x; + vertices[other + 1] = y; + } + } + } + spine.SkeletonClipping = SkeletonClipping; +})(spine || (spine = {})); +var spine; +(function (spine) { + class SkeletonData { + constructor() { + this.bones = new Array(); + this.slots = new Array(); + this.skins = new Array(); + this.events = new Array(); + this.animations = new Array(); + this.ikConstraints = new Array(); + this.transformConstraints = new Array(); + this.pathConstraints = new Array(); + this.fps = 0; + } + findBone(boneName) { + if (boneName == null) + throw new Error("boneName cannot be null."); + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (bone.name == boneName) + return bone; + } + return null; + } + findBoneIndex(boneName) { + if (boneName == null) + throw new Error("boneName cannot be null."); + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) + if (bones[i].name == boneName) + return i; + return -1; + } + findSlot(slotName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) { + let slot = slots[i]; + if (slot.name == slotName) + return slot; + } + return null; + } + findSlotIndex(slotName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) + if (slots[i].name == slotName) + return i; + return -1; + } + findSkin(skinName) { + if (skinName == null) + throw new Error("skinName cannot be null."); + let skins = this.skins; + for (let i = 0, n = skins.length; i < n; i++) { + let skin = skins[i]; + if (skin.name == skinName) + return skin; + } + return null; + } + findEvent(eventDataName) { + if (eventDataName == null) + throw new Error("eventDataName cannot be null."); + let events = this.events; + for (let i = 0, n = events.length; i < n; i++) { + let event = events[i]; + if (event.name == eventDataName) + return event; + } + return null; + } + findAnimation(animationName) { + if (animationName == null) + throw new Error("animationName cannot be null."); + let animations = this.animations; + for (let i = 0, n = animations.length; i < n; i++) { + let animation = animations[i]; + if (animation.name == animationName) + return animation; + } + return null; + } + findIkConstraint(constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + let ikConstraints = this.ikConstraints; + for (let i = 0, n = ikConstraints.length; i < n; i++) { + let constraint = ikConstraints[i]; + if (constraint.name == constraintName) + return constraint; + } + return null; + } + findTransformConstraint(constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + let transformConstraints = this.transformConstraints; + for (let i = 0, n = transformConstraints.length; i < n; i++) { + let constraint = transformConstraints[i]; + if (constraint.name == constraintName) + return constraint; + } + return null; + } + findPathConstraint(constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + let pathConstraints = this.pathConstraints; + for (let i = 0, n = pathConstraints.length; i < n; i++) { + let constraint = pathConstraints[i]; + if (constraint.name == constraintName) + return constraint; + } + return null; + } + findPathConstraintIndex(pathConstraintName) { + if (pathConstraintName == null) + throw new Error("pathConstraintName cannot be null."); + let pathConstraints = this.pathConstraints; + for (let i = 0, n = pathConstraints.length; i < n; i++) + if (pathConstraints[i].name == pathConstraintName) + return i; + return -1; + } + } + spine.SkeletonData = SkeletonData; +})(spine || (spine = {})); +var spine; +(function (spine) { + class SkeletonJson { + constructor(attachmentLoader) { + this.scale = 1; + this.linkedMeshes = new Array(); + this.attachmentLoader = attachmentLoader; + } + readSkeletonData(json) { + let scale = this.scale; + let skeletonData = new spine.SkeletonData(); + let root = typeof (json) === "string" ? JSON.parse(json) : json; + let skeletonMap = root.skeleton; + if (skeletonMap != null) { + skeletonData.hash = skeletonMap.hash; + skeletonData.version = skeletonMap.spine; + skeletonData.width = skeletonMap.width; + skeletonData.height = skeletonMap.height; + skeletonData.fps = skeletonMap.fps; + skeletonData.imagesPath = skeletonMap.images; + } + if (root.bones) { + for (let i = 0; i < root.bones.length; i++) { + let boneMap = root.bones[i]; + let parent = null; + let parentName = this.getValue(boneMap, "parent", null); + if (parentName != null) { + parent = skeletonData.findBone(parentName); + if (parent == null) + throw new Error("Parent bone not found: " + parentName); + } + let data = new spine.BoneData(skeletonData.bones.length, boneMap.name, parent); + data.length = this.getValue(boneMap, "length", 0) * scale; + data.x = this.getValue(boneMap, "x", 0) * scale; + data.y = this.getValue(boneMap, "y", 0) * scale; + data.rotation = this.getValue(boneMap, "rotation", 0); + data.scaleX = this.getValue(boneMap, "scaleX", 1); + data.scaleY = this.getValue(boneMap, "scaleY", 1); + data.shearX = this.getValue(boneMap, "shearX", 0); + data.shearY = this.getValue(boneMap, "shearY", 0); + data.transformMode = SkeletonJson.transformModeFromString(this.getValue(boneMap, "transform", "normal")); + skeletonData.bones.push(data); + } + } + if (root.slots) { + for (let i = 0; i < root.slots.length; i++) { + let slotMap = root.slots[i]; + let slotName = slotMap.name; + let boneName = slotMap.bone; + let boneData = skeletonData.findBone(boneName); + if (boneData == null) + throw new Error("Slot bone not found: " + boneName); + let data = new spine.SlotData(skeletonData.slots.length, slotName, boneData); + let color = this.getValue(slotMap, "color", null); + if (color != null) + data.color.setFromString(color); + let dark = this.getValue(slotMap, "dark", null); + if (dark != null) { + data.darkColor = new spine.Color(1, 1, 1, 1); + data.darkColor.setFromString(dark); + } + data.attachmentName = this.getValue(slotMap, "attachment", null); + data.blendMode = SkeletonJson.blendModeFromString(this.getValue(slotMap, "blend", "normal")); + skeletonData.slots.push(data); + } + } + if (root.ik) { + for (let i = 0; i < root.ik.length; i++) { + let constraintMap = root.ik[i]; + let data = new spine.IkConstraintData(constraintMap.name); + data.order = this.getValue(constraintMap, "order", 0); + for (let j = 0; j < constraintMap.bones.length; j++) { + let boneName = constraintMap.bones[j]; + let bone = skeletonData.findBone(boneName); + if (bone == null) + throw new Error("IK bone not found: " + boneName); + data.bones.push(bone); + } + let targetName = constraintMap.target; + data.target = skeletonData.findBone(targetName); + if (data.target == null) + throw new Error("IK target bone not found: " + targetName); + data.mix = this.getValue(constraintMap, "mix", 1); + data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1; + data.compress = this.getValue(constraintMap, "compress", false); + data.stretch = this.getValue(constraintMap, "stretch", false); + data.uniform = this.getValue(constraintMap, "uniform", false); + skeletonData.ikConstraints.push(data); + } + } + if (root.transform) { + for (let i = 0; i < root.transform.length; i++) { + let constraintMap = root.transform[i]; + let data = new spine.TransformConstraintData(constraintMap.name); + data.order = this.getValue(constraintMap, "order", 0); + for (let j = 0; j < constraintMap.bones.length; j++) { + let boneName = constraintMap.bones[j]; + let bone = skeletonData.findBone(boneName); + if (bone == null) + throw new Error("Transform constraint bone not found: " + boneName); + data.bones.push(bone); + } + let targetName = constraintMap.target; + data.target = skeletonData.findBone(targetName); + if (data.target == null) + throw new Error("Transform constraint target bone not found: " + targetName); + data.local = this.getValue(constraintMap, "local", false); + data.relative = this.getValue(constraintMap, "relative", false); + data.offsetRotation = this.getValue(constraintMap, "rotation", 0); + data.offsetX = this.getValue(constraintMap, "x", 0) * scale; + data.offsetY = this.getValue(constraintMap, "y", 0) * scale; + data.offsetScaleX = this.getValue(constraintMap, "scaleX", 0); + data.offsetScaleY = this.getValue(constraintMap, "scaleY", 0); + data.offsetShearY = this.getValue(constraintMap, "shearY", 0); + data.rotateMix = this.getValue(constraintMap, "rotateMix", 1); + data.translateMix = this.getValue(constraintMap, "translateMix", 1); + data.scaleMix = this.getValue(constraintMap, "scaleMix", 1); + data.shearMix = this.getValue(constraintMap, "shearMix", 1); + skeletonData.transformConstraints.push(data); + } + } + if (root.path) { + for (let i = 0; i < root.path.length; i++) { + let constraintMap = root.path[i]; + let data = new spine.PathConstraintData(constraintMap.name); + data.order = this.getValue(constraintMap, "order", 0); + for (let j = 0; j < constraintMap.bones.length; j++) { + let boneName = constraintMap.bones[j]; + let bone = skeletonData.findBone(boneName); + if (bone == null) + throw new Error("Transform constraint bone not found: " + boneName); + data.bones.push(bone); + } + let targetName = constraintMap.target; + data.target = skeletonData.findSlot(targetName); + if (data.target == null) + throw new Error("Path target slot not found: " + targetName); + data.positionMode = SkeletonJson.positionModeFromString(this.getValue(constraintMap, "positionMode", "percent")); + data.spacingMode = SkeletonJson.spacingModeFromString(this.getValue(constraintMap, "spacingMode", "length")); + data.rotateMode = SkeletonJson.rotateModeFromString(this.getValue(constraintMap, "rotateMode", "tangent")); + data.offsetRotation = this.getValue(constraintMap, "rotation", 0); + data.position = this.getValue(constraintMap, "position", 0); + if (data.positionMode == spine.PositionMode.Fixed) + data.position *= scale; + data.spacing = this.getValue(constraintMap, "spacing", 0); + if (data.spacingMode == spine.SpacingMode.Length || data.spacingMode == spine.SpacingMode.Fixed) + data.spacing *= scale; + data.rotateMix = this.getValue(constraintMap, "rotateMix", 1); + data.translateMix = this.getValue(constraintMap, "translateMix", 1); + skeletonData.pathConstraints.push(data); + } + } + if (root.skins) { + for (let skinName in root.skins) { + let skinMap = root.skins[skinName]; + let skin = new spine.Skin(skinName); + for (let slotName in skinMap) { + let slotIndex = skeletonData.findSlotIndex(slotName); + if (slotIndex == -1) + throw new Error("Slot not found: " + slotName); + let slotMap = skinMap[slotName]; + for (let entryName in slotMap) { + let attachment = this.readAttachment(slotMap[entryName], skin, slotIndex, entryName, skeletonData); + if (attachment != null) + skin.addAttachment(slotIndex, entryName, attachment); + } + } + skeletonData.skins.push(skin); + if (skin.name == "default") + skeletonData.defaultSkin = skin; + } + } + for (let i = 0, n = this.linkedMeshes.length; i < n; i++) { + let linkedMesh = this.linkedMeshes[i]; + let skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin); + if (skin == null) + throw new Error("Skin not found: " + linkedMesh.skin); + let parent = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent); + if (parent == null) + throw new Error("Parent mesh not found: " + linkedMesh.parent); + linkedMesh.mesh.setParentMesh(parent); + linkedMesh.mesh.updateUVs(); + } + this.linkedMeshes.length = 0; + if (root.events) { + for (let eventName in root.events) { + let eventMap = root.events[eventName]; + let data = new spine.EventData(eventName); + data.intValue = this.getValue(eventMap, "int", 0); + data.floatValue = this.getValue(eventMap, "float", 0); + data.stringValue = this.getValue(eventMap, "string", ""); + data.audioPath = this.getValue(eventMap, "audio", null); + if (data.audioPath != null) { + data.volume = this.getValue(eventMap, "volume", 1); + data.balance = this.getValue(eventMap, "balance", 0); + } + skeletonData.events.push(data); + } + } + if (root.animations) { + for (let animationName in root.animations) { + let animationMap = root.animations[animationName]; + this.readAnimation(animationMap, animationName, skeletonData); + } + } + return skeletonData; + } + readAttachment(map, skin, slotIndex, name, skeletonData) { + let scale = this.scale; + name = this.getValue(map, "name", name); + let type = this.getValue(map, "type", "region"); + switch (type) { + case "region": { + let path = this.getValue(map, "path", name); + let region = this.attachmentLoader.newRegionAttachment(skin, name, path); + if (region == null) + return null; + region.path = path; + region.x = this.getValue(map, "x", 0) * scale; + region.y = this.getValue(map, "y", 0) * scale; + region.scaleX = this.getValue(map, "scaleX", 1); + region.scaleY = this.getValue(map, "scaleY", 1); + region.rotation = this.getValue(map, "rotation", 0); + region.width = map.width * scale; + region.height = map.height * scale; + let color = this.getValue(map, "color", null); + if (color != null) + region.color.setFromString(color); + region.updateOffset(); + return region; + } + case "boundingbox": { + let box = this.attachmentLoader.newBoundingBoxAttachment(skin, name); + if (box == null) + return null; + this.readVertices(map, box, map.vertexCount << 1); + let color = this.getValue(map, "color", null); + if (color != null) + box.color.setFromString(color); + return box; + } + case "mesh": + case "linkedmesh": { + let path = this.getValue(map, "path", name); + let mesh = this.attachmentLoader.newMeshAttachment(skin, name, path); + if (mesh == null) + return null; + mesh.path = path; + let color = this.getValue(map, "color", null); + if (color != null) + mesh.color.setFromString(color); + let parent = this.getValue(map, "parent", null); + if (parent != null) { + mesh.inheritDeform = this.getValue(map, "deform", true); + this.linkedMeshes.push(new LinkedMesh(mesh, this.getValue(map, "skin", null), slotIndex, parent)); + return mesh; + } + let uvs = map.uvs; + this.readVertices(map, mesh, uvs.length); + mesh.triangles = map.triangles; + mesh.regionUVs = uvs; + mesh.updateUVs(); + mesh.hullLength = this.getValue(map, "hull", 0) * 2; + return mesh; + } + case "path": { + let path = this.attachmentLoader.newPathAttachment(skin, name); + if (path == null) + return null; + path.closed = this.getValue(map, "closed", false); + path.constantSpeed = this.getValue(map, "constantSpeed", true); + let vertexCount = map.vertexCount; + this.readVertices(map, path, vertexCount << 1); + let lengths = spine.Utils.newArray(vertexCount / 3, 0); + for (let i = 0; i < map.lengths.length; i++) + lengths[i] = map.lengths[i] * scale; + path.lengths = lengths; + let color = this.getValue(map, "color", null); + if (color != null) + path.color.setFromString(color); + return path; + } + case "point": { + let point = this.attachmentLoader.newPointAttachment(skin, name); + if (point == null) + return null; + point.x = this.getValue(map, "x", 0) * scale; + point.y = this.getValue(map, "y", 0) * scale; + point.rotation = this.getValue(map, "rotation", 0); + let color = this.getValue(map, "color", null); + if (color != null) + point.color.setFromString(color); + return point; + } + case "clipping": { + let clip = this.attachmentLoader.newClippingAttachment(skin, name); + if (clip == null) + return null; + let end = this.getValue(map, "end", null); + if (end != null) { + let slot = skeletonData.findSlot(end); + if (slot == null) + throw new Error("Clipping end slot not found: " + end); + clip.endSlot = slot; + } + let vertexCount = map.vertexCount; + this.readVertices(map, clip, vertexCount << 1); + let color = this.getValue(map, "color", null); + if (color != null) + clip.color.setFromString(color); + return clip; + } + } + return null; + } + readVertices(map, attachment, verticesLength) { + let scale = this.scale; + attachment.worldVerticesLength = verticesLength; + let vertices = map.vertices; + if (verticesLength == vertices.length) { + let scaledVertices = spine.Utils.toFloatArray(vertices); + if (scale != 1) { + for (let i = 0, n = vertices.length; i < n; i++) + scaledVertices[i] *= scale; + } + attachment.vertices = scaledVertices; + return; + } + let weights = new Array(); + let bones = new Array(); + for (let i = 0, n = vertices.length; i < n;) { + let boneCount = vertices[i++]; + bones.push(boneCount); + for (let nn = i + boneCount * 4; i < nn; i += 4) { + bones.push(vertices[i]); + weights.push(vertices[i + 1] * scale); + weights.push(vertices[i + 2] * scale); + weights.push(vertices[i + 3]); + } + } + attachment.bones = bones; + attachment.vertices = spine.Utils.toFloatArray(weights); + } + readAnimation(map, name, skeletonData) { + let scale = this.scale; + let timelines = new Array(); + let duration = 0; + if (map.slots) { + for (let slotName in map.slots) { + let slotMap = map.slots[slotName]; + let slotIndex = skeletonData.findSlotIndex(slotName); + if (slotIndex == -1) + throw new Error("Slot not found: " + slotName); + for (let timelineName in slotMap) { + let timelineMap = slotMap[timelineName]; + if (timelineName == "attachment") { + let timeline = new spine.AttachmentTimeline(timelineMap.length); + timeline.slotIndex = slotIndex; + let frameIndex = 0; + for (let i = 0; i < timelineMap.length; i++) { + let valueMap = timelineMap[i]; + timeline.setFrame(frameIndex++, valueMap.time, valueMap.name); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); + } + else if (timelineName == "color") { + let timeline = new spine.ColorTimeline(timelineMap.length); + timeline.slotIndex = slotIndex; + let frameIndex = 0; + for (let i = 0; i < timelineMap.length; i++) { + let valueMap = timelineMap[i]; + let color = new spine.Color(); + color.setFromString(valueMap.color); + timeline.setFrame(frameIndex, valueMap.time, color.r, color.g, color.b, color.a); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.ColorTimeline.ENTRIES]); + } + else if (timelineName == "twoColor") { + let timeline = new spine.TwoColorTimeline(timelineMap.length); + timeline.slotIndex = slotIndex; + let frameIndex = 0; + for (let i = 0; i < timelineMap.length; i++) { + let valueMap = timelineMap[i]; + let light = new spine.Color(); + let dark = new spine.Color(); + light.setFromString(valueMap.light); + dark.setFromString(valueMap.dark); + timeline.setFrame(frameIndex, valueMap.time, light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.TwoColorTimeline.ENTRIES]); + } + else + throw new Error("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"); + } + } + } + if (map.bones) { + for (let boneName in map.bones) { + let boneMap = map.bones[boneName]; + let boneIndex = skeletonData.findBoneIndex(boneName); + if (boneIndex == -1) + throw new Error("Bone not found: " + boneName); + for (let timelineName in boneMap) { + let timelineMap = boneMap[timelineName]; + if (timelineName === "rotate") { + let timeline = new spine.RotateTimeline(timelineMap.length); + timeline.boneIndex = boneIndex; + let frameIndex = 0; + for (let i = 0; i < timelineMap.length; i++) { + let valueMap = timelineMap[i]; + timeline.setFrame(frameIndex, valueMap.time, valueMap.angle); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.RotateTimeline.ENTRIES]); + } + else if (timelineName === "translate" || timelineName === "scale" || timelineName === "shear") { + let timeline = null; + let timelineScale = 1; + if (timelineName === "scale") + timeline = new spine.ScaleTimeline(timelineMap.length); + else if (timelineName === "shear") + timeline = new spine.ShearTimeline(timelineMap.length); + else { + timeline = new spine.TranslateTimeline(timelineMap.length); + timelineScale = scale; + } + timeline.boneIndex = boneIndex; + let frameIndex = 0; + for (let i = 0; i < timelineMap.length; i++) { + let valueMap = timelineMap[i]; + let x = this.getValue(valueMap, "x", 0), y = this.getValue(valueMap, "y", 0); + timeline.setFrame(frameIndex, valueMap.time, x * timelineScale, y * timelineScale); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.TranslateTimeline.ENTRIES]); + } + else + throw new Error("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"); + } + } + } + if (map.ik) { + for (let constraintName in map.ik) { + let constraintMap = map.ik[constraintName]; + let constraint = skeletonData.findIkConstraint(constraintName); + let timeline = new spine.IkConstraintTimeline(constraintMap.length); + timeline.ikConstraintIndex = skeletonData.ikConstraints.indexOf(constraint); + let frameIndex = 0; + for (let i = 0; i < constraintMap.length; i++) { + let valueMap = constraintMap[i]; + timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false)); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.IkConstraintTimeline.ENTRIES]); + } + } + if (map.transform) { + for (let constraintName in map.transform) { + let constraintMap = map.transform[constraintName]; + let constraint = skeletonData.findTransformConstraint(constraintName); + let timeline = new spine.TransformConstraintTimeline(constraintMap.length); + timeline.transformConstraintIndex = skeletonData.transformConstraints.indexOf(constraint); + let frameIndex = 0; + for (let i = 0; i < constraintMap.length; i++) { + let valueMap = constraintMap[i]; + timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1)); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.TransformConstraintTimeline.ENTRIES]); + } + } + if (map.paths) { + for (let constraintName in map.paths) { + let constraintMap = map.paths[constraintName]; + let index = skeletonData.findPathConstraintIndex(constraintName); + if (index == -1) + throw new Error("Path constraint not found: " + constraintName); + let data = skeletonData.pathConstraints[index]; + for (let timelineName in constraintMap) { + let timelineMap = constraintMap[timelineName]; + if (timelineName === "position" || timelineName === "spacing") { + let timeline = null; + let timelineScale = 1; + if (timelineName === "spacing") { + timeline = new spine.PathConstraintSpacingTimeline(timelineMap.length); + if (data.spacingMode == spine.SpacingMode.Length || data.spacingMode == spine.SpacingMode.Fixed) + timelineScale = scale; + } + else { + timeline = new spine.PathConstraintPositionTimeline(timelineMap.length); + if (data.positionMode == spine.PositionMode.Fixed) + timelineScale = scale; + } + timeline.pathConstraintIndex = index; + let frameIndex = 0; + for (let i = 0; i < timelineMap.length; i++) { + let valueMap = timelineMap[i]; + timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, timelineName, 0) * timelineScale); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.PathConstraintPositionTimeline.ENTRIES]); + } + else if (timelineName === "mix") { + let timeline = new spine.PathConstraintMixTimeline(timelineMap.length); + timeline.pathConstraintIndex = index; + let frameIndex = 0; + for (let i = 0; i < timelineMap.length; i++) { + let valueMap = timelineMap[i]; + timeline.setFrame(frameIndex, valueMap.time, this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1)); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.PathConstraintMixTimeline.ENTRIES]); + } + } + } + } + if (map.deform) { + for (let deformName in map.deform) { + let deformMap = map.deform[deformName]; + let skin = skeletonData.findSkin(deformName); + if (skin == null) + throw new Error("Skin not found: " + deformName); + for (let slotName in deformMap) { + let slotMap = deformMap[slotName]; + let slotIndex = skeletonData.findSlotIndex(slotName); + if (slotIndex == -1) + throw new Error("Slot not found: " + slotMap.name); + for (let timelineName in slotMap) { + let timelineMap = slotMap[timelineName]; + let attachment = skin.getAttachment(slotIndex, timelineName); + if (attachment == null) + throw new Error("Deform attachment not found: " + timelineMap.name); + let weighted = attachment.bones != null; + let vertices = attachment.vertices; + let deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; + let timeline = new spine.DeformTimeline(timelineMap.length); + timeline.slotIndex = slotIndex; + timeline.attachment = attachment; + let frameIndex = 0; + for (let j = 0; j < timelineMap.length; j++) { + let valueMap = timelineMap[j]; + let deform; + let verticesValue = this.getValue(valueMap, "vertices", null); + if (verticesValue == null) + deform = weighted ? spine.Utils.newFloatArray(deformLength) : vertices; + else { + deform = spine.Utils.newFloatArray(deformLength); + let start = this.getValue(valueMap, "offset", 0); + spine.Utils.arrayCopy(verticesValue, 0, deform, start, verticesValue.length); + if (scale != 1) { + for (let i = start, n = i + verticesValue.length; i < n; i++) + deform[i] *= scale; + } + if (!weighted) { + for (let i = 0; i < deformLength; i++) + deform[i] += vertices[i]; + } + } + timeline.setFrame(frameIndex, valueMap.time, deform); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); + } + } + } + } + let drawOrderNode = map.drawOrder; + if (drawOrderNode == null) + drawOrderNode = map.draworder; + if (drawOrderNode != null) { + let timeline = new spine.DrawOrderTimeline(drawOrderNode.length); + let slotCount = skeletonData.slots.length; + let frameIndex = 0; + for (let j = 0; j < drawOrderNode.length; j++) { + let drawOrderMap = drawOrderNode[j]; + let drawOrder = null; + let offsets = this.getValue(drawOrderMap, "offsets", null); + if (offsets != null) { + drawOrder = spine.Utils.newArray(slotCount, -1); + let unchanged = spine.Utils.newArray(slotCount - offsets.length, 0); + let originalIndex = 0, unchangedIndex = 0; + for (let i = 0; i < offsets.length; i++) { + let offsetMap = offsets[i]; + let slotIndex = skeletonData.findSlotIndex(offsetMap.slot); + if (slotIndex == -1) + throw new Error("Slot not found: " + offsetMap.slot); + while (originalIndex != slotIndex) + unchanged[unchangedIndex++] = originalIndex++; + drawOrder[originalIndex + offsetMap.offset] = originalIndex++; + } + while (originalIndex < slotCount) + unchanged[unchangedIndex++] = originalIndex++; + for (let i = slotCount - 1; i >= 0; i--) + if (drawOrder[i] == -1) + drawOrder[i] = unchanged[--unchangedIndex]; + } + timeline.setFrame(frameIndex++, drawOrderMap.time, drawOrder); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); + } + if (map.events) { + let timeline = new spine.EventTimeline(map.events.length); + let frameIndex = 0; + for (let i = 0; i < map.events.length; i++) { + let eventMap = map.events[i]; + let eventData = skeletonData.findEvent(eventMap.name); + if (eventData == null) + throw new Error("Event not found: " + eventMap.name); + let event = new spine.Event(spine.Utils.toSinglePrecision(eventMap.time), eventData); + event.intValue = this.getValue(eventMap, "int", eventData.intValue); + event.floatValue = this.getValue(eventMap, "float", eventData.floatValue); + event.stringValue = this.getValue(eventMap, "string", eventData.stringValue); + if (event.data.audioPath != null) { + event.volume = this.getValue(eventMap, "volume", 1); + event.balance = this.getValue(eventMap, "balance", 0); + } + timeline.setFrame(frameIndex++, event); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); + } + if (isNaN(duration)) { + throw new Error("Error while parsing animation, duration is NaN"); + } + skeletonData.animations.push(new spine.Animation(name, timelines, duration)); + } + readCurve(map, timeline, frameIndex) { + if (!map.curve) + return; + if (map.curve === "stepped") + timeline.setStepped(frameIndex); + else if (Object.prototype.toString.call(map.curve) === '[object Array]') { + let curve = map.curve; + timeline.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]); + } + } + getValue(map, prop, defaultValue) { + return map[prop] !== undefined ? map[prop] : defaultValue; + } + static blendModeFromString(str) { + str = str.toLowerCase(); + if (str == "normal") + return spine.BlendMode.Normal; + if (str == "additive") + return spine.BlendMode.Additive; + if (str == "multiply") + return spine.BlendMode.Multiply; + if (str == "screen") + return spine.BlendMode.Screen; + throw new Error(`Unknown blend mode: ${str}`); + } + static positionModeFromString(str) { + str = str.toLowerCase(); + if (str == "fixed") + return spine.PositionMode.Fixed; + if (str == "percent") + return spine.PositionMode.Percent; + throw new Error(`Unknown position mode: ${str}`); + } + static spacingModeFromString(str) { + str = str.toLowerCase(); + if (str == "length") + return spine.SpacingMode.Length; + if (str == "fixed") + return spine.SpacingMode.Fixed; + if (str == "percent") + return spine.SpacingMode.Percent; + throw new Error(`Unknown position mode: ${str}`); + } + static rotateModeFromString(str) { + str = str.toLowerCase(); + if (str == "tangent") + return spine.RotateMode.Tangent; + if (str == "chain") + return spine.RotateMode.Chain; + if (str == "chainscale") + return spine.RotateMode.ChainScale; + throw new Error(`Unknown rotate mode: ${str}`); + } + static transformModeFromString(str) { + str = str.toLowerCase(); + if (str == "normal") + return spine.TransformMode.Normal; + if (str == "onlytranslation") + return spine.TransformMode.OnlyTranslation; + if (str == "norotationorreflection") + return spine.TransformMode.NoRotationOrReflection; + if (str == "noscale") + return spine.TransformMode.NoScale; + if (str == "noscaleorreflection") + return spine.TransformMode.NoScaleOrReflection; + throw new Error(`Unknown transform mode: ${str}`); + } + } + spine.SkeletonJson = SkeletonJson; + class LinkedMesh { + constructor(mesh, skin, slotIndex, parent) { + this.mesh = mesh; + this.skin = skin; + this.slotIndex = slotIndex; + this.parent = parent; + } + } +})(spine || (spine = {})); +var spine; +(function (spine) { + class Skin { + constructor(name) { + this.attachments = new Array(); + if (name == null) + throw new Error("name cannot be null."); + this.name = name; + } + addAttachment(slotIndex, name, attachment) { + if (attachment == null) + throw new Error("attachment cannot be null."); + let attachments = this.attachments; + if (slotIndex >= attachments.length) + attachments.length = slotIndex + 1; + if (!attachments[slotIndex]) + attachments[slotIndex] = {}; + attachments[slotIndex][name] = attachment; + } + getAttachment(slotIndex, name) { + let dictionary = this.attachments[slotIndex]; + return dictionary ? dictionary[name] : null; + } + attachAll(skeleton, oldSkin) { + let slotIndex = 0; + for (let i = 0; i < skeleton.slots.length; i++) { + let slot = skeleton.slots[i]; + let slotAttachment = slot.getAttachment(); + if (slotAttachment && slotIndex < oldSkin.attachments.length) { + let dictionary = oldSkin.attachments[slotIndex]; + for (let key in dictionary) { + let skinAttachment = dictionary[key]; + if (slotAttachment == skinAttachment) { + let attachment = this.getAttachment(slotIndex, key); + if (attachment != null) + slot.setAttachment(attachment); + break; + } + } + } + slotIndex++; + } + } + } + spine.Skin = Skin; +})(spine || (spine = {})); +var spine; +(function (spine) { + class Slot { + constructor(data, bone) { + this.attachmentVertices = new Array(); + if (data == null) + throw new Error("data cannot be null."); + if (bone == null) + throw new Error("bone cannot be null."); + this.data = data; + this.bone = bone; + this.color = new spine.Color(); + this.darkColor = data.darkColor == null ? null : new spine.Color(); + this.setToSetupPose(); + } + getAttachment() { + return this.attachment; + } + setAttachment(attachment) { + if (this.attachment == attachment) + return; + this.attachment = attachment; + this.attachmentTime = this.bone.skeleton.time; + this.attachmentVertices.length = 0; + } + setAttachmentTime(time) { + this.attachmentTime = this.bone.skeleton.time - time; + } + getAttachmentTime() { + return this.bone.skeleton.time - this.attachmentTime; + } + setToSetupPose() { + this.color.setFromColor(this.data.color); + if (this.darkColor != null) + this.darkColor.setFromColor(this.data.darkColor); + if (this.data.attachmentName == null) + this.attachment = null; + else { + this.attachment = null; + this.setAttachment(this.bone.skeleton.getAttachment(this.data.index, this.data.attachmentName)); + } + } + } + spine.Slot = Slot; +})(spine || (spine = {})); +var spine; +(function (spine) { + class SlotData { + constructor(index, name, boneData) { + this.color = new spine.Color(1, 1, 1, 1); + if (index < 0) + throw new Error("index must be >= 0."); + if (name == null) + throw new Error("name cannot be null."); + if (boneData == null) + throw new Error("boneData cannot be null."); + this.index = index; + this.name = name; + this.boneData = boneData; + } + } + spine.SlotData = SlotData; +})(spine || (spine = {})); +var spine; +(function (spine) { + class Texture { + constructor(image) { + this._image = image; + } + getImage() { + return this._image; + } + static filterFromString(text) { + switch (text.toLowerCase()) { + case "nearest": return TextureFilter.Nearest; + case "linear": return TextureFilter.Linear; + case "mipmap": return TextureFilter.MipMap; + case "mipmapnearestnearest": return TextureFilter.MipMapNearestNearest; + case "mipmaplinearnearest": return TextureFilter.MipMapLinearNearest; + case "mipmapnearestlinear": return TextureFilter.MipMapNearestLinear; + case "mipmaplinearlinear": return TextureFilter.MipMapLinearLinear; + default: throw new Error(`Unknown texture filter ${text}`); + } + } + static wrapFromString(text) { + switch (text.toLowerCase()) { + case "mirroredtepeat": return TextureWrap.MirroredRepeat; + case "clamptoedge": return TextureWrap.ClampToEdge; + case "repeat": return TextureWrap.Repeat; + default: throw new Error(`Unknown texture wrap ${text}`); + } + } + } + spine.Texture = Texture; + let TextureFilter; + (function (TextureFilter) { + TextureFilter[TextureFilter["Nearest"] = 9728] = "Nearest"; + TextureFilter[TextureFilter["Linear"] = 9729] = "Linear"; + TextureFilter[TextureFilter["MipMap"] = 9987] = "MipMap"; + TextureFilter[TextureFilter["MipMapNearestNearest"] = 9984] = "MipMapNearestNearest"; + TextureFilter[TextureFilter["MipMapLinearNearest"] = 9985] = "MipMapLinearNearest"; + TextureFilter[TextureFilter["MipMapNearestLinear"] = 9986] = "MipMapNearestLinear"; + TextureFilter[TextureFilter["MipMapLinearLinear"] = 9987] = "MipMapLinearLinear"; + })(TextureFilter = spine.TextureFilter || (spine.TextureFilter = {})); + let TextureWrap; + (function (TextureWrap) { + TextureWrap[TextureWrap["MirroredRepeat"] = 33648] = "MirroredRepeat"; + TextureWrap[TextureWrap["ClampToEdge"] = 33071] = "ClampToEdge"; + TextureWrap[TextureWrap["Repeat"] = 10497] = "Repeat"; + })(TextureWrap = spine.TextureWrap || (spine.TextureWrap = {})); + class TextureRegion { + constructor() { + this.u = 0; + this.v = 0; + this.u2 = 0; + this.v2 = 0; + this.width = 0; + this.height = 0; + this.rotate = false; + this.offsetX = 0; + this.offsetY = 0; + this.originalWidth = 0; + this.originalHeight = 0; + } + } + spine.TextureRegion = TextureRegion; + class FakeTexture extends Texture { + setFilters(minFilter, magFilter) { } + setWraps(uWrap, vWrap) { } + dispose() { } + } + spine.FakeTexture = FakeTexture; +})(spine || (spine = {})); +var spine; +(function (spine) { + class TextureAtlas { + constructor(atlasText, textureLoader) { + this.pages = new Array(); + this.regions = new Array(); + this.load(atlasText, textureLoader); + } + load(atlasText, textureLoader) { + if (textureLoader == null) + throw new Error("textureLoader cannot be null."); + let reader = new TextureAtlasReader(atlasText); + let tuple = new Array(4); + let page = null; + while (true) { + let line = reader.readLine(); + if (line == null) + break; + line = line.trim(); + if (line.length == 0) + page = null; + else if (!page) { + page = new TextureAtlasPage(); + page.name = line; + if (reader.readTuple(tuple) == 2) { + page.width = parseInt(tuple[0]); + page.height = parseInt(tuple[1]); + reader.readTuple(tuple); + } + reader.readTuple(tuple); + page.minFilter = spine.Texture.filterFromString(tuple[0]); + page.magFilter = spine.Texture.filterFromString(tuple[1]); + let direction = reader.readValue(); + page.uWrap = spine.TextureWrap.ClampToEdge; + page.vWrap = spine.TextureWrap.ClampToEdge; + if (direction == "x") + page.uWrap = spine.TextureWrap.Repeat; + else if (direction == "y") + page.vWrap = spine.TextureWrap.Repeat; + else if (direction == "xy") + page.uWrap = page.vWrap = spine.TextureWrap.Repeat; + page.texture = textureLoader(line); + page.texture.setFilters(page.minFilter, page.magFilter); + page.texture.setWraps(page.uWrap, page.vWrap); + page.width = page.texture.getImage().width; + page.height = page.texture.getImage().height; + this.pages.push(page); + } + else { + let region = new TextureAtlasRegion(); + region.name = line; + region.page = page; + region.rotate = reader.readValue() == "true"; + reader.readTuple(tuple); + let x = parseInt(tuple[0]); + let y = parseInt(tuple[1]); + reader.readTuple(tuple); + let width = parseInt(tuple[0]); + let height = parseInt(tuple[1]); + region.u = x / page.width; + region.v = y / page.height; + if (region.rotate) { + region.u2 = (x + height) / page.width; + region.v2 = (y + width) / page.height; + } + else { + region.u2 = (x + width) / page.width; + region.v2 = (y + height) / page.height; + } + region.x = x; + region.y = y; + region.width = Math.abs(width); + region.height = Math.abs(height); + if (reader.readTuple(tuple) == 4) { + if (reader.readTuple(tuple) == 4) { + reader.readTuple(tuple); + } + } + region.originalWidth = parseInt(tuple[0]); + region.originalHeight = parseInt(tuple[1]); + reader.readTuple(tuple); + region.offsetX = parseInt(tuple[0]); + region.offsetY = parseInt(tuple[1]); + region.index = parseInt(reader.readValue()); + region.texture = page.texture; + this.regions.push(region); + } + } + } + findRegion(name) { + for (let i = 0; i < this.regions.length; i++) { + if (this.regions[i].name == name) { + return this.regions[i]; + } + } + return null; + } + dispose() { + for (let i = 0; i < this.pages.length; i++) { + this.pages[i].texture.dispose(); + } + } + } + spine.TextureAtlas = TextureAtlas; + class TextureAtlasReader { + constructor(text) { + this.index = 0; + this.lines = text.split(/\r\n|\r|\n/); + } + readLine() { + if (this.index >= this.lines.length) + return null; + return this.lines[this.index++]; + } + readValue() { + let line = this.readLine(); + let colon = line.indexOf(":"); + if (colon == -1) + throw new Error("Invalid line: " + line); + return line.substring(colon + 1).trim(); + } + readTuple(tuple) { + let line = this.readLine(); + let colon = line.indexOf(":"); + if (colon == -1) + throw new Error("Invalid line: " + line); + let i = 0, lastMatch = colon + 1; + for (; i < 3; i++) { + let comma = line.indexOf(",", lastMatch); + if (comma == -1) + break; + tuple[i] = line.substr(lastMatch, comma - lastMatch).trim(); + lastMatch = comma + 1; + } + tuple[i] = line.substring(lastMatch).trim(); + return i + 1; + } + } + class TextureAtlasPage { + } + spine.TextureAtlasPage = TextureAtlasPage; + class TextureAtlasRegion extends spine.TextureRegion { + } + spine.TextureAtlasRegion = TextureAtlasRegion; +})(spine || (spine = {})); +var spine; +(function (spine) { + class TransformConstraint { + constructor(data, skeleton) { + this.rotateMix = 0; + this.translateMix = 0; + this.scaleMix = 0; + this.shearMix = 0; + this.temp = new spine.Vector2(); + if (data == null) + throw new Error("data cannot be null."); + if (skeleton == null) + throw new Error("skeleton cannot be null."); + this.data = data; + this.rotateMix = data.rotateMix; + this.translateMix = data.translateMix; + this.scaleMix = data.scaleMix; + this.shearMix = data.shearMix; + this.bones = new Array(); + for (let i = 0; i < data.bones.length; i++) + this.bones.push(skeleton.findBone(data.bones[i].name)); + this.target = skeleton.findBone(data.target.name); + } + apply() { + this.update(); + } + update() { + if (this.data.local) { + if (this.data.relative) + this.applyRelativeLocal(); + else + this.applyAbsoluteLocal(); + } + else { + if (this.data.relative) + this.applyRelativeWorld(); + else + this.applyAbsoluteWorld(); + } + } + applyAbsoluteWorld() { + let rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + let target = this.target; + let ta = target.a, tb = target.b, tc = target.c, td = target.d; + let degRadReflect = ta * td - tb * tc > 0 ? spine.MathUtils.degRad : -spine.MathUtils.degRad; + let offsetRotation = this.data.offsetRotation * degRadReflect; + let offsetShearY = this.data.offsetShearY * degRadReflect; + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + let modified = false; + if (rotateMix != 0) { + let a = bone.a, b = bone.b, c = bone.c, d = bone.d; + let r = Math.atan2(tc, ta) - Math.atan2(c, a) + offsetRotation; + if (r > spine.MathUtils.PI) + r -= spine.MathUtils.PI2; + else if (r < -spine.MathUtils.PI) + r += spine.MathUtils.PI2; + r *= rotateMix; + let cos = Math.cos(r), sin = Math.sin(r); + bone.a = cos * a - sin * c; + bone.b = cos * b - sin * d; + bone.c = sin * a + cos * c; + bone.d = sin * b + cos * d; + modified = true; + } + if (translateMix != 0) { + let temp = this.temp; + target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); + bone.worldX += (temp.x - bone.worldX) * translateMix; + bone.worldY += (temp.y - bone.worldY) * translateMix; + modified = true; + } + if (scaleMix > 0) { + let s = Math.sqrt(bone.a * bone.a + bone.c * bone.c); + let ts = Math.sqrt(ta * ta + tc * tc); + if (s > 0.00001) + s = (s + (ts - s + this.data.offsetScaleX) * scaleMix) / s; + bone.a *= s; + bone.c *= s; + s = Math.sqrt(bone.b * bone.b + bone.d * bone.d); + ts = Math.sqrt(tb * tb + td * td); + if (s > 0.00001) + s = (s + (ts - s + this.data.offsetScaleY) * scaleMix) / s; + bone.b *= s; + bone.d *= s; + modified = true; + } + if (shearMix > 0) { + let b = bone.b, d = bone.d; + let by = Math.atan2(d, b); + let r = Math.atan2(td, tb) - Math.atan2(tc, ta) - (by - Math.atan2(bone.c, bone.a)); + if (r > spine.MathUtils.PI) + r -= spine.MathUtils.PI2; + else if (r < -spine.MathUtils.PI) + r += spine.MathUtils.PI2; + r = by + (r + offsetShearY) * shearMix; + let s = Math.sqrt(b * b + d * d); + bone.b = Math.cos(r) * s; + bone.d = Math.sin(r) * s; + modified = true; + } + if (modified) + bone.appliedValid = false; + } + } + applyRelativeWorld() { + let rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + let target = this.target; + let ta = target.a, tb = target.b, tc = target.c, td = target.d; + let degRadReflect = ta * td - tb * tc > 0 ? spine.MathUtils.degRad : -spine.MathUtils.degRad; + let offsetRotation = this.data.offsetRotation * degRadReflect, offsetShearY = this.data.offsetShearY * degRadReflect; + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + let modified = false; + if (rotateMix != 0) { + let a = bone.a, b = bone.b, c = bone.c, d = bone.d; + let r = Math.atan2(tc, ta) + offsetRotation; + if (r > spine.MathUtils.PI) + r -= spine.MathUtils.PI2; + else if (r < -spine.MathUtils.PI) + r += spine.MathUtils.PI2; + r *= rotateMix; + let cos = Math.cos(r), sin = Math.sin(r); + bone.a = cos * a - sin * c; + bone.b = cos * b - sin * d; + bone.c = sin * a + cos * c; + bone.d = sin * b + cos * d; + modified = true; + } + if (translateMix != 0) { + let temp = this.temp; + target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); + bone.worldX += temp.x * translateMix; + bone.worldY += temp.y * translateMix; + modified = true; + } + if (scaleMix > 0) { + let s = (Math.sqrt(ta * ta + tc * tc) - 1 + this.data.offsetScaleX) * scaleMix + 1; + bone.a *= s; + bone.c *= s; + s = (Math.sqrt(tb * tb + td * td) - 1 + this.data.offsetScaleY) * scaleMix + 1; + bone.b *= s; + bone.d *= s; + modified = true; + } + if (shearMix > 0) { + let r = Math.atan2(td, tb) - Math.atan2(tc, ta); + if (r > spine.MathUtils.PI) + r -= spine.MathUtils.PI2; + else if (r < -spine.MathUtils.PI) + r += spine.MathUtils.PI2; + let b = bone.b, d = bone.d; + r = Math.atan2(d, b) + (r - spine.MathUtils.PI / 2 + offsetShearY) * shearMix; + let s = Math.sqrt(b * b + d * d); + bone.b = Math.cos(r) * s; + bone.d = Math.sin(r) * s; + modified = true; + } + if (modified) + bone.appliedValid = false; + } + } + applyAbsoluteLocal() { + let rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + let target = this.target; + if (!target.appliedValid) + target.updateAppliedTransform(); + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (!bone.appliedValid) + bone.updateAppliedTransform(); + let rotation = bone.arotation; + if (rotateMix != 0) { + let r = target.arotation - rotation + this.data.offsetRotation; + r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; + rotation += r * rotateMix; + } + let x = bone.ax, y = bone.ay; + if (translateMix != 0) { + x += (target.ax - x + this.data.offsetX) * translateMix; + y += (target.ay - y + this.data.offsetY) * translateMix; + } + let scaleX = bone.ascaleX, scaleY = bone.ascaleY; + if (scaleMix != 0) { + if (scaleX > 0.00001) + scaleX = (scaleX + (target.ascaleX - scaleX + this.data.offsetScaleX) * scaleMix) / scaleX; + if (scaleY > 0.00001) + scaleY = (scaleY + (target.ascaleY - scaleY + this.data.offsetScaleY) * scaleMix) / scaleY; + } + let shearY = bone.ashearY; + if (shearMix != 0) { + let r = target.ashearY - shearY + this.data.offsetShearY; + r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; + bone.shearY += r * shearMix; + } + bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); + } + } + applyRelativeLocal() { + let rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + let target = this.target; + if (!target.appliedValid) + target.updateAppliedTransform(); + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (!bone.appliedValid) + bone.updateAppliedTransform(); + let rotation = bone.arotation; + if (rotateMix != 0) + rotation += (target.arotation + this.data.offsetRotation) * rotateMix; + let x = bone.ax, y = bone.ay; + if (translateMix != 0) { + x += (target.ax + this.data.offsetX) * translateMix; + y += (target.ay + this.data.offsetY) * translateMix; + } + let scaleX = bone.ascaleX, scaleY = bone.ascaleY; + if (scaleMix != 0) { + if (scaleX > 0.00001) + scaleX *= ((target.ascaleX - 1 + this.data.offsetScaleX) * scaleMix) + 1; + if (scaleY > 0.00001) + scaleY *= ((target.ascaleY - 1 + this.data.offsetScaleY) * scaleMix) + 1; + } + let shearY = bone.ashearY; + if (shearMix != 0) + shearY += (target.ashearY + this.data.offsetShearY) * shearMix; + bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); + } + } + getOrder() { + return this.data.order; + } + } + spine.TransformConstraint = TransformConstraint; +})(spine || (spine = {})); +var spine; +(function (spine) { + class TransformConstraintData { + constructor(name) { + this.order = 0; + this.bones = new Array(); + this.rotateMix = 0; + this.translateMix = 0; + this.scaleMix = 0; + this.shearMix = 0; + this.offsetRotation = 0; + this.offsetX = 0; + this.offsetY = 0; + this.offsetScaleX = 0; + this.offsetScaleY = 0; + this.offsetShearY = 0; + this.relative = false; + this.local = false; + if (name == null) + throw new Error("name cannot be null."); + this.name = name; + } + } + spine.TransformConstraintData = TransformConstraintData; +})(spine || (spine = {})); +var spine; +(function (spine) { + class Triangulator { + constructor() { + this.convexPolygons = new Array(); + this.convexPolygonsIndices = new Array(); + this.indicesArray = new Array(); + this.isConcaveArray = new Array(); + this.triangles = new Array(); + this.polygonPool = new spine.Pool(() => { + return new Array(); + }); + this.polygonIndicesPool = new spine.Pool(() => { + return new Array(); + }); + } + triangulate(verticesArray) { + let vertices = verticesArray; + let vertexCount = verticesArray.length >> 1; + let indices = this.indicesArray; + indices.length = 0; + for (let i = 0; i < vertexCount; i++) + indices[i] = i; + let isConcave = this.isConcaveArray; + isConcave.length = 0; + for (let i = 0, n = vertexCount; i < n; ++i) + isConcave[i] = Triangulator.isConcave(i, vertexCount, vertices, indices); + let triangles = this.triangles; + triangles.length = 0; + while (vertexCount > 3) { + let previous = vertexCount - 1, i = 0, next = 1; + while (true) { + outer: if (!isConcave[i]) { + let p1 = indices[previous] << 1, p2 = indices[i] << 1, p3 = indices[next] << 1; + let p1x = vertices[p1], p1y = vertices[p1 + 1]; + let p2x = vertices[p2], p2y = vertices[p2 + 1]; + let p3x = vertices[p3], p3y = vertices[p3 + 1]; + for (let ii = (next + 1) % vertexCount; ii != previous; ii = (ii + 1) % vertexCount) { + if (!isConcave[ii]) + continue; + let v = indices[ii] << 1; + let vx = vertices[v], vy = vertices[v + 1]; + if (Triangulator.positiveArea(p3x, p3y, p1x, p1y, vx, vy)) { + if (Triangulator.positiveArea(p1x, p1y, p2x, p2y, vx, vy)) { + if (Triangulator.positiveArea(p2x, p2y, p3x, p3y, vx, vy)) + break outer; + } + } + } + break; + } + if (next == 0) { + do { + if (!isConcave[i]) + break; + i--; + } while (i > 0); + break; + } + previous = i; + i = next; + next = (next + 1) % vertexCount; + } + triangles.push(indices[(vertexCount + i - 1) % vertexCount]); + triangles.push(indices[i]); + triangles.push(indices[(i + 1) % vertexCount]); + indices.splice(i, 1); + isConcave.splice(i, 1); + vertexCount--; + let previousIndex = (vertexCount + i - 1) % vertexCount; + let nextIndex = i == vertexCount ? 0 : i; + isConcave[previousIndex] = Triangulator.isConcave(previousIndex, vertexCount, vertices, indices); + isConcave[nextIndex] = Triangulator.isConcave(nextIndex, vertexCount, vertices, indices); + } + if (vertexCount == 3) { + triangles.push(indices[2]); + triangles.push(indices[0]); + triangles.push(indices[1]); + } + return triangles; + } + decompose(verticesArray, triangles) { + let vertices = verticesArray; + let convexPolygons = this.convexPolygons; + this.polygonPool.freeAll(convexPolygons); + convexPolygons.length = 0; + let convexPolygonsIndices = this.convexPolygonsIndices; + this.polygonIndicesPool.freeAll(convexPolygonsIndices); + convexPolygonsIndices.length = 0; + let polygonIndices = this.polygonIndicesPool.obtain(); + polygonIndices.length = 0; + let polygon = this.polygonPool.obtain(); + polygon.length = 0; + let fanBaseIndex = -1, lastWinding = 0; + for (let i = 0, n = triangles.length; i < n; i += 3) { + let t1 = triangles[i] << 1, t2 = triangles[i + 1] << 1, t3 = triangles[i + 2] << 1; + let x1 = vertices[t1], y1 = vertices[t1 + 1]; + let x2 = vertices[t2], y2 = vertices[t2 + 1]; + let x3 = vertices[t3], y3 = vertices[t3 + 1]; + let merged = false; + if (fanBaseIndex == t1) { + let o = polygon.length - 4; + let winding1 = Triangulator.winding(polygon[o], polygon[o + 1], polygon[o + 2], polygon[o + 3], x3, y3); + let winding2 = Triangulator.winding(x3, y3, polygon[0], polygon[1], polygon[2], polygon[3]); + if (winding1 == lastWinding && winding2 == lastWinding) { + polygon.push(x3); + polygon.push(y3); + polygonIndices.push(t3); + merged = true; + } + } + if (!merged) { + if (polygon.length > 0) { + convexPolygons.push(polygon); + convexPolygonsIndices.push(polygonIndices); + } + else { + this.polygonPool.free(polygon); + this.polygonIndicesPool.free(polygonIndices); + } + polygon = this.polygonPool.obtain(); + polygon.length = 0; + polygon.push(x1); + polygon.push(y1); + polygon.push(x2); + polygon.push(y2); + polygon.push(x3); + polygon.push(y3); + polygonIndices = this.polygonIndicesPool.obtain(); + polygonIndices.length = 0; + polygonIndices.push(t1); + polygonIndices.push(t2); + polygonIndices.push(t3); + lastWinding = Triangulator.winding(x1, y1, x2, y2, x3, y3); + fanBaseIndex = t1; + } + } + if (polygon.length > 0) { + convexPolygons.push(polygon); + convexPolygonsIndices.push(polygonIndices); + } + for (let i = 0, n = convexPolygons.length; i < n; i++) { + polygonIndices = convexPolygonsIndices[i]; + if (polygonIndices.length == 0) + continue; + let firstIndex = polygonIndices[0]; + let lastIndex = polygonIndices[polygonIndices.length - 1]; + polygon = convexPolygons[i]; + let o = polygon.length - 4; + let prevPrevX = polygon[o], prevPrevY = polygon[o + 1]; + let prevX = polygon[o + 2], prevY = polygon[o + 3]; + let firstX = polygon[0], firstY = polygon[1]; + let secondX = polygon[2], secondY = polygon[3]; + let winding = Triangulator.winding(prevPrevX, prevPrevY, prevX, prevY, firstX, firstY); + for (let ii = 0; ii < n; ii++) { + if (ii == i) + continue; + let otherIndices = convexPolygonsIndices[ii]; + if (otherIndices.length != 3) + continue; + let otherFirstIndex = otherIndices[0]; + let otherSecondIndex = otherIndices[1]; + let otherLastIndex = otherIndices[2]; + let otherPoly = convexPolygons[ii]; + let x3 = otherPoly[otherPoly.length - 2], y3 = otherPoly[otherPoly.length - 1]; + if (otherFirstIndex != firstIndex || otherSecondIndex != lastIndex) + continue; + let winding1 = Triangulator.winding(prevPrevX, prevPrevY, prevX, prevY, x3, y3); + let winding2 = Triangulator.winding(x3, y3, firstX, firstY, secondX, secondY); + if (winding1 == winding && winding2 == winding) { + otherPoly.length = 0; + otherIndices.length = 0; + polygon.push(x3); + polygon.push(y3); + polygonIndices.push(otherLastIndex); + prevPrevX = prevX; + prevPrevY = prevY; + prevX = x3; + prevY = y3; + ii = 0; + } + } + } + for (let i = convexPolygons.length - 1; i >= 0; i--) { + polygon = convexPolygons[i]; + if (polygon.length == 0) { + convexPolygons.splice(i, 1); + this.polygonPool.free(polygon); + polygonIndices = convexPolygonsIndices[i]; + convexPolygonsIndices.splice(i, 1); + this.polygonIndicesPool.free(polygonIndices); + } + } + return convexPolygons; + } + static isConcave(index, vertexCount, vertices, indices) { + let previous = indices[(vertexCount + index - 1) % vertexCount] << 1; + let current = indices[index] << 1; + let next = indices[(index + 1) % vertexCount] << 1; + return !this.positiveArea(vertices[previous], vertices[previous + 1], vertices[current], vertices[current + 1], vertices[next], vertices[next + 1]); + } + static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y) { + return p1x * (p3y - p2y) + p2x * (p1y - p3y) + p3x * (p2y - p1y) >= 0; + } + static winding(p1x, p1y, p2x, p2y, p3x, p3y) { + let px = p2x - p1x, py = p2y - p1y; + return p3x * py - p3y * px + px * p1y - p1x * py >= 0 ? 1 : -1; + } + } + spine.Triangulator = Triangulator; +})(spine || (spine = {})); +var spine; +(function (spine) { + class IntSet { + constructor() { + this.array = new Array(); + } + add(value) { + let contains = this.contains(value); + this.array[value | 0] = value | 0; + return !contains; + } + contains(value) { + return this.array[value | 0] != undefined; + } + remove(value) { + this.array[value | 0] = undefined; + } + clear() { + this.array.length = 0; + } + } + spine.IntSet = IntSet; + class Color { + constructor(r = 0, g = 0, b = 0, a = 0) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + set(r, g, b, a) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + this.clamp(); + return this; + } + setFromColor(c) { + this.r = c.r; + this.g = c.g; + this.b = c.b; + this.a = c.a; + return this; + } + setFromString(hex) { + hex = hex.charAt(0) == '#' ? hex.substr(1) : hex; + this.r = parseInt(hex.substr(0, 2), 16) / 255.0; + this.g = parseInt(hex.substr(2, 2), 16) / 255.0; + this.b = parseInt(hex.substr(4, 2), 16) / 255.0; + this.a = (hex.length != 8 ? 255 : parseInt(hex.substr(6, 2), 16)) / 255.0; + return this; + } + add(r, g, b, a) { + this.r += r; + this.g += g; + this.b += b; + this.a += a; + this.clamp(); + return this; + } + clamp() { + if (this.r < 0) + this.r = 0; + else if (this.r > 1) + this.r = 1; + if (this.g < 0) + this.g = 0; + else if (this.g > 1) + this.g = 1; + if (this.b < 0) + this.b = 0; + else if (this.b > 1) + this.b = 1; + if (this.a < 0) + this.a = 0; + else if (this.a > 1) + this.a = 1; + return this; + } + } + Color.WHITE = new Color(1, 1, 1, 1); + Color.RED = new Color(1, 0, 0, 1); + Color.GREEN = new Color(0, 1, 0, 1); + Color.BLUE = new Color(0, 0, 1, 1); + Color.MAGENTA = new Color(1, 0, 1, 1); + spine.Color = Color; + class MathUtils { + static clamp(value, min, max) { + if (value < min) + return min; + if (value > max) + return max; + return value; + } + static cosDeg(degrees) { + return Math.cos(degrees * MathUtils.degRad); + } + static sinDeg(degrees) { + return Math.sin(degrees * MathUtils.degRad); + } + static signum(value) { + return value > 0 ? 1 : value < 0 ? -1 : 0; + } + static toInt(x) { + return x > 0 ? Math.floor(x) : Math.ceil(x); + } + static cbrt(x) { + let y = Math.pow(Math.abs(x), 1 / 3); + return x < 0 ? -y : y; + } + static randomTriangular(min, max) { + return MathUtils.randomTriangularWith(min, max, (min + max) * 0.5); + } + static randomTriangularWith(min, max, mode) { + let u = Math.random(); + let d = max - min; + if (u <= (mode - min) / d) + return min + Math.sqrt(u * d * (mode - min)); + return max - Math.sqrt((1 - u) * d * (max - mode)); + } + } + MathUtils.PI = 3.1415927; + MathUtils.PI2 = MathUtils.PI * 2; + MathUtils.radiansToDegrees = 180 / MathUtils.PI; + MathUtils.radDeg = MathUtils.radiansToDegrees; + MathUtils.degreesToRadians = MathUtils.PI / 180; + MathUtils.degRad = MathUtils.degreesToRadians; + spine.MathUtils = MathUtils; + class Interpolation { + apply(start, end, a) { + return start + (end - start) * this.applyInternal(a); + } + } + spine.Interpolation = Interpolation; + class Pow extends Interpolation { + constructor(power) { + super(); + this.power = 2; + this.power = power; + } + applyInternal(a) { + if (a <= 0.5) + return Math.pow(a * 2, this.power) / 2; + return Math.pow((a - 1) * 2, this.power) / (this.power % 2 == 0 ? -2 : 2) + 1; + } + } + spine.Pow = Pow; + class PowOut extends Pow { + constructor(power) { + super(power); + } + applyInternal(a) { + return Math.pow(a - 1, this.power) * (this.power % 2 == 0 ? -1 : 1) + 1; + } + } + spine.PowOut = PowOut; + class Utils { + static arrayCopy(source, sourceStart, dest, destStart, numElements) { + for (let i = sourceStart, j = destStart; i < sourceStart + numElements; i++, j++) { + dest[j] = source[i]; + } + } + static setArraySize(array, size, value = 0) { + let oldSize = array.length; + if (oldSize == size) + return array; + array.length = size; + if (oldSize < size) { + for (let i = oldSize; i < size; i++) + array[i] = value; + } + return array; + } + static ensureArrayCapacity(array, size, value = 0) { + if (array.length >= size) + return array; + return Utils.setArraySize(array, size, value); + } + static newArray(size, defaultValue) { + let array = new Array(size); + for (let i = 0; i < size; i++) + array[i] = defaultValue; + return array; + } + static newFloatArray(size) { + if (Utils.SUPPORTS_TYPED_ARRAYS) { + return new Float32Array(size); + } + else { + let array = new Array(size); + for (let i = 0; i < array.length; i++) + array[i] = 0; + return array; + } + } + static newShortArray(size) { + if (Utils.SUPPORTS_TYPED_ARRAYS) { + return new Int16Array(size); + } + else { + let array = new Array(size); + for (let i = 0; i < array.length; i++) + array[i] = 0; + return array; + } + } + static toFloatArray(array) { + return Utils.SUPPORTS_TYPED_ARRAYS ? new Float32Array(array) : array; + } + static toSinglePrecision(value) { + return Utils.SUPPORTS_TYPED_ARRAYS ? Math.fround(value) : value; + } + static webkit602BugfixHelper(alpha, blend) { + } + } + Utils.SUPPORTS_TYPED_ARRAYS = typeof (Float32Array) !== "undefined"; + spine.Utils = Utils; + class DebugUtils { + static logBones(skeleton) { + for (let i = 0; i < skeleton.bones.length; i++) { + let bone = skeleton.bones[i]; + console.log(bone.data.name + ", " + bone.a + ", " + bone.b + ", " + bone.c + ", " + bone.d + ", " + bone.worldX + ", " + bone.worldY); + } + } + } + spine.DebugUtils = DebugUtils; + class Pool { + constructor(instantiator) { + this.items = new Array(); + this.instantiator = instantiator; + } + obtain() { + return this.items.length > 0 ? this.items.pop() : this.instantiator(); + } + free(item) { + if (item.reset) + item.reset(); + this.items.push(item); + } + freeAll(items) { + for (let i = 0; i < items.length; i++) { + if (items[i].reset) + items[i].reset(); + this.items[i] = items[i]; + } + } + clear() { + this.items.length = 0; + } + } + spine.Pool = Pool; + class Vector2 { + constructor(x = 0, y = 0) { + this.x = x; + this.y = y; + } + set(x, y) { + this.x = x; + this.y = y; + return this; + } + length() { + let x = this.x; + let y = this.y; + return Math.sqrt(x * x + y * y); + } + normalize() { + let len = this.length(); + if (len != 0) { + this.x /= len; + this.y /= len; + } + return this; + } + } + spine.Vector2 = Vector2; + class TimeKeeper { + constructor() { + this.maxDelta = 0.064; + this.framesPerSecond = 0; + this.delta = 0; + this.totalTime = 0; + this.lastTime = Date.now() / 1000; + this.frameCount = 0; + this.frameTime = 0; + } + update() { + let now = Date.now() / 1000; + this.delta = now - this.lastTime; + this.frameTime += this.delta; + this.totalTime += this.delta; + if (this.delta > this.maxDelta) + this.delta = this.maxDelta; + this.lastTime = now; + this.frameCount++; + if (this.frameTime > 1) { + this.framesPerSecond = this.frameCount / this.frameTime; + this.frameTime = 0; + this.frameCount = 0; + } + } + } + spine.TimeKeeper = TimeKeeper; + class WindowedMean { + constructor(windowSize = 32) { + this.addedValues = 0; + this.lastValue = 0; + this.mean = 0; + this.dirty = true; + this.values = new Array(windowSize); + } + hasEnoughData() { + return this.addedValues >= this.values.length; + } + addValue(value) { + if (this.addedValues < this.values.length) + this.addedValues++; + this.values[this.lastValue++] = value; + if (this.lastValue > this.values.length - 1) + this.lastValue = 0; + this.dirty = true; + } + getMean() { + if (this.hasEnoughData()) { + if (this.dirty) { + let mean = 0; + for (let i = 0; i < this.values.length; i++) { + mean += this.values[i]; + } + this.mean = mean / this.values.length; + this.dirty = false; + } + return this.mean; + } + else { + return 0; + } + } + } + spine.WindowedMean = WindowedMean; +})(spine || (spine = {})); +(() => { + if (!Math.fround) { + Math.fround = (function (array) { + return function (x) { + return array[0] = x, array[0]; + }; + })(new Float32Array(1)); + } +})(); +var spine; +(function (spine) { + class Attachment { + constructor(name) { + if (name == null) + throw new Error("name cannot be null."); + this.name = name; + } + } + spine.Attachment = Attachment; + class VertexAttachment extends Attachment { + constructor(name) { + super(name); + this.id = (VertexAttachment.nextID++ & 65535) << 11; + this.worldVerticesLength = 0; + } + computeWorldVertices(slot, start, count, worldVertices, offset, stride) { + count = offset + (count >> 1) * stride; + let skeleton = slot.bone.skeleton; + let deformArray = slot.attachmentVertices; + let vertices = this.vertices; + let bones = this.bones; + if (bones == null) { + if (deformArray.length > 0) + vertices = deformArray; + let bone = slot.bone; + let x = bone.worldX; + let y = bone.worldY; + let a = bone.a, b = bone.b, c = bone.c, d = bone.d; + for (let v = start, w = offset; w < count; v += 2, w += stride) { + let vx = vertices[v], vy = vertices[v + 1]; + worldVertices[w] = vx * a + vy * b + x; + worldVertices[w + 1] = vx * c + vy * d + y; + } + return; + } + let v = 0, skip = 0; + for (let i = 0; i < start; i += 2) { + let n = bones[v]; + v += n + 1; + skip += n; + } + let skeletonBones = skeleton.bones; + if (deformArray.length == 0) { + for (let w = offset, b = skip * 3; w < count; w += stride) { + let wx = 0, wy = 0; + let n = bones[v++]; + n += v; + for (; v < n; v++, b += 3) { + let bone = skeletonBones[bones[v]]; + let vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2]; + wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight; + wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight; + } + worldVertices[w] = wx; + worldVertices[w + 1] = wy; + } + } + else { + let deform = deformArray; + for (let w = offset, b = skip * 3, f = skip << 1; w < count; w += stride) { + let wx = 0, wy = 0; + let n = bones[v++]; + n += v; + for (; v < n; v++, b += 3, f += 2) { + let bone = skeletonBones[bones[v]]; + let vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2]; + wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight; + wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight; + } + worldVertices[w] = wx; + worldVertices[w + 1] = wy; + } + } + } + applyDeform(sourceAttachment) { + return this == sourceAttachment; + } + } + VertexAttachment.nextID = 0; + spine.VertexAttachment = VertexAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + let AttachmentType; + (function (AttachmentType) { + AttachmentType[AttachmentType["Region"] = 0] = "Region"; + AttachmentType[AttachmentType["BoundingBox"] = 1] = "BoundingBox"; + AttachmentType[AttachmentType["Mesh"] = 2] = "Mesh"; + AttachmentType[AttachmentType["LinkedMesh"] = 3] = "LinkedMesh"; + AttachmentType[AttachmentType["Path"] = 4] = "Path"; + AttachmentType[AttachmentType["Point"] = 5] = "Point"; + })(AttachmentType = spine.AttachmentType || (spine.AttachmentType = {})); +})(spine || (spine = {})); +var spine; +(function (spine) { + class BoundingBoxAttachment extends spine.VertexAttachment { + constructor(name) { + super(name); + this.color = new spine.Color(1, 1, 1, 1); + } + } + spine.BoundingBoxAttachment = BoundingBoxAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + class ClippingAttachment extends spine.VertexAttachment { + constructor(name) { + super(name); + this.color = new spine.Color(0.2275, 0.2275, 0.8078, 1); + } + } + spine.ClippingAttachment = ClippingAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + class MeshAttachment extends spine.VertexAttachment { + constructor(name) { + super(name); + this.color = new spine.Color(1, 1, 1, 1); + this.inheritDeform = false; + this.tempColor = new spine.Color(0, 0, 0, 0); + } + updateUVs() { + let regionUVs = this.regionUVs; + if (this.uvs == null || this.uvs.length != regionUVs.length) + this.uvs = spine.Utils.newFloatArray(regionUVs.length); + let uvs = this.uvs; + let u = 0, v = 0, width = 0, height = 0; + if (this.region instanceof spine.TextureAtlasRegion) { + let region = this.region; + let textureWidth = region.texture.getImage().width, textureHeight = region.texture.getImage().height; + if (region.rotate) { + u = region.u - (region.originalHeight - region.offsetY - region.height) / textureWidth; + v = region.v - (region.originalWidth - region.offsetX - region.width) / textureHeight; + width = region.originalHeight / textureWidth; + height = region.originalWidth / textureHeight; + for (let i = 0, n = uvs.length; i < n; i += 2) { + uvs[i] = u + regionUVs[i + 1] * width; + uvs[i + 1] = v + height - regionUVs[i] * height; + } + return; + } + u = region.u - region.offsetX / textureWidth; + v = region.v - (region.originalHeight - region.offsetY - region.height) / textureHeight; + width = region.originalWidth / textureWidth; + height = region.originalHeight / textureHeight; + } + else if (this.region == null) { + u = v = 0; + width = height = 1; + } + else { + u = this.region.u; + v = this.region.v; + width = this.region.u2 - u; + height = this.region.v2 - v; + } + for (let i = 0, n = uvs.length; i < n; i += 2) { + uvs[i] = u + regionUVs[i] * width; + uvs[i + 1] = v + regionUVs[i + 1] * height; + } + } + applyDeform(sourceAttachment) { + return this == sourceAttachment || (this.inheritDeform && this.parentMesh == sourceAttachment); + } + getParentMesh() { + return this.parentMesh; + } + setParentMesh(parentMesh) { + this.parentMesh = parentMesh; + if (parentMesh != null) { + this.bones = parentMesh.bones; + this.vertices = parentMesh.vertices; + this.worldVerticesLength = parentMesh.worldVerticesLength; + this.regionUVs = parentMesh.regionUVs; + this.triangles = parentMesh.triangles; + this.hullLength = parentMesh.hullLength; + this.worldVerticesLength = parentMesh.worldVerticesLength; + } + } + } + spine.MeshAttachment = MeshAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + class PathAttachment extends spine.VertexAttachment { + constructor(name) { + super(name); + this.closed = false; + this.constantSpeed = false; + this.color = new spine.Color(1, 1, 1, 1); + } + } + spine.PathAttachment = PathAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + class PointAttachment extends spine.VertexAttachment { + constructor(name) { + super(name); + this.color = new spine.Color(0.38, 0.94, 0, 1); + } + computeWorldPosition(bone, point) { + point.x = this.x * bone.a + this.y * bone.b + bone.worldX; + point.y = this.x * bone.c + this.y * bone.d + bone.worldY; + return point; + } + computeWorldRotation(bone) { + let cos = spine.MathUtils.cosDeg(this.rotation), sin = spine.MathUtils.sinDeg(this.rotation); + let x = cos * bone.a + sin * bone.b; + let y = cos * bone.c + sin * bone.d; + return Math.atan2(y, x) * spine.MathUtils.radDeg; + } + } + spine.PointAttachment = PointAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + class RegionAttachment extends spine.Attachment { + constructor(name) { + super(name); + this.x = 0; + this.y = 0; + this.scaleX = 1; + this.scaleY = 1; + this.rotation = 0; + this.width = 0; + this.height = 0; + this.color = new spine.Color(1, 1, 1, 1); + this.offset = spine.Utils.newFloatArray(8); + this.uvs = spine.Utils.newFloatArray(8); + this.tempColor = new spine.Color(1, 1, 1, 1); + } + updateOffset() { + let regionScaleX = this.width / this.region.originalWidth * this.scaleX; + let regionScaleY = this.height / this.region.originalHeight * this.scaleY; + let localX = -this.width / 2 * this.scaleX + this.region.offsetX * regionScaleX; + let localY = -this.height / 2 * this.scaleY + this.region.offsetY * regionScaleY; + let localX2 = localX + this.region.width * regionScaleX; + let localY2 = localY + this.region.height * regionScaleY; + let radians = this.rotation * Math.PI / 180; + let cos = Math.cos(radians); + let sin = Math.sin(radians); + let localXCos = localX * cos + this.x; + let localXSin = localX * sin; + let localYCos = localY * cos + this.y; + let localYSin = localY * sin; + let localX2Cos = localX2 * cos + this.x; + let localX2Sin = localX2 * sin; + let localY2Cos = localY2 * cos + this.y; + let localY2Sin = localY2 * sin; + let offset = this.offset; + offset[RegionAttachment.OX1] = localXCos - localYSin; + offset[RegionAttachment.OY1] = localYCos + localXSin; + offset[RegionAttachment.OX2] = localXCos - localY2Sin; + offset[RegionAttachment.OY2] = localY2Cos + localXSin; + offset[RegionAttachment.OX3] = localX2Cos - localY2Sin; + offset[RegionAttachment.OY3] = localY2Cos + localX2Sin; + offset[RegionAttachment.OX4] = localX2Cos - localYSin; + offset[RegionAttachment.OY4] = localYCos + localX2Sin; + } + setRegion(region) { + this.region = region; + let uvs = this.uvs; + if (region.rotate) { + uvs[2] = region.u; + uvs[3] = region.v2; + uvs[4] = region.u; + uvs[5] = region.v; + uvs[6] = region.u2; + uvs[7] = region.v; + uvs[0] = region.u2; + uvs[1] = region.v2; + } + else { + uvs[0] = region.u; + uvs[1] = region.v2; + uvs[2] = region.u; + uvs[3] = region.v; + uvs[4] = region.u2; + uvs[5] = region.v; + uvs[6] = region.u2; + uvs[7] = region.v2; + } + } + computeWorldVertices(bone, worldVertices, offset, stride) { + let vertexOffset = this.offset; + let x = bone.worldX, y = bone.worldY; + let a = bone.a, b = bone.b, c = bone.c, d = bone.d; + let offsetX = 0, offsetY = 0; + offsetX = vertexOffset[RegionAttachment.OX1]; + offsetY = vertexOffset[RegionAttachment.OY1]; + worldVertices[offset] = offsetX * a + offsetY * b + x; + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[RegionAttachment.OX2]; + offsetY = vertexOffset[RegionAttachment.OY2]; + worldVertices[offset] = offsetX * a + offsetY * b + x; + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[RegionAttachment.OX3]; + offsetY = vertexOffset[RegionAttachment.OY3]; + worldVertices[offset] = offsetX * a + offsetY * b + x; + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[RegionAttachment.OX4]; + offsetY = vertexOffset[RegionAttachment.OY4]; + worldVertices[offset] = offsetX * a + offsetY * b + x; + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + } + } + RegionAttachment.OX1 = 0; + RegionAttachment.OY1 = 1; + RegionAttachment.OX2 = 2; + RegionAttachment.OY2 = 3; + RegionAttachment.OX3 = 4; + RegionAttachment.OY3 = 5; + RegionAttachment.OX4 = 6; + RegionAttachment.OY4 = 7; + RegionAttachment.X1 = 0; + RegionAttachment.Y1 = 1; + RegionAttachment.C1R = 2; + RegionAttachment.C1G = 3; + RegionAttachment.C1B = 4; + RegionAttachment.C1A = 5; + RegionAttachment.U1 = 6; + RegionAttachment.V1 = 7; + RegionAttachment.X2 = 8; + RegionAttachment.Y2 = 9; + RegionAttachment.C2R = 10; + RegionAttachment.C2G = 11; + RegionAttachment.C2B = 12; + RegionAttachment.C2A = 13; + RegionAttachment.U2 = 14; + RegionAttachment.V2 = 15; + RegionAttachment.X3 = 16; + RegionAttachment.Y3 = 17; + RegionAttachment.C3R = 18; + RegionAttachment.C3G = 19; + RegionAttachment.C3B = 20; + RegionAttachment.C3A = 21; + RegionAttachment.U3 = 22; + RegionAttachment.V3 = 23; + RegionAttachment.X4 = 24; + RegionAttachment.Y4 = 25; + RegionAttachment.C4R = 26; + RegionAttachment.C4G = 27; + RegionAttachment.C4B = 28; + RegionAttachment.C4A = 29; + RegionAttachment.U4 = 30; + RegionAttachment.V4 = 31; + spine.RegionAttachment = RegionAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + class JitterEffect { + constructor(jitterX, jitterY) { + this.jitterX = 0; + this.jitterY = 0; + this.jitterX = jitterX; + this.jitterY = jitterY; + } + begin(skeleton) { + } + transform(position, uv, light, dark) { + position.x += spine.MathUtils.randomTriangular(-this.jitterX, this.jitterY); + position.y += spine.MathUtils.randomTriangular(-this.jitterX, this.jitterY); + } + end() { + } + } + spine.JitterEffect = JitterEffect; +})(spine || (spine = {})); +var spine; +(function (spine) { + class SwirlEffect { + constructor(radius) { + this.centerX = 0; + this.centerY = 0; + this.radius = 0; + this.angle = 0; + this.worldX = 0; + this.worldY = 0; + this.radius = radius; + } + begin(skeleton) { + this.worldX = skeleton.x + this.centerX; + this.worldY = skeleton.y + this.centerY; + } + transform(position, uv, light, dark) { + let radAngle = this.angle * spine.MathUtils.degreesToRadians; + let x = position.x - this.worldX; + let y = position.y - this.worldY; + let dist = Math.sqrt(x * x + y * y); + if (dist < this.radius) { + let theta = SwirlEffect.interpolation.apply(0, radAngle, (this.radius - dist) / this.radius); + let cos = Math.cos(theta); + let sin = Math.sin(theta); + position.x = cos * x - sin * y + this.worldX; + position.y = sin * x + cos * y + this.worldY; + } + } + end() { + } + } + SwirlEffect.interpolation = new spine.PowOut(2); + spine.SwirlEffect = SwirlEffect; +})(spine || (spine = {})); +window.spine = spine; +//# sourceMappingURL=spine-core.js.map \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/spine-core-3.8.js b/examples/layaair/frontend/bin/libs/spine-core-3.8.js new file mode 100644 index 0000000..f5d1e70 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/spine-core-3.8.js @@ -0,0 +1,8067 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated January 1, 2020. Replaces all prior versions. + * + * Copyright (c) 2013-2020, Esoteric Software LLC + * + * Integration of the Spine Runtimes into software or otherwise creating + * derivative works of the Spine Runtimes is permitted under the terms and + * conditions of Section 2 of the Spine Editor License Agreement: + * http://esotericsoftware.com/spine-editor-license + * + * Otherwise, it is permitted to integrate the Spine Runtimes into software + * or otherwise create derivative works of the Spine Runtimes (collectively, + * "Products"), provided that each user of the Products must obtain their own + * Spine Editor license and redistribution of the Products in any form must + * include this license and copyright notice. + * + * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, + * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ +var spine; +(function (spine) { + class Animation { + constructor(name, timelines, duration) { + if (name == null) + throw new Error("name cannot be null."); + if (timelines == null) + throw new Error("timelines cannot be null."); + this.name = name; + this.timelines = timelines; + this.timelineIds = []; + for (var i = 0; i < timelines.length; i++) + this.timelineIds[timelines[i].getPropertyId()] = true; + this.duration = duration; + } + hasTimeline(id) { + return this.timelineIds[id] == true; + } + apply(skeleton, lastTime, time, loop, events, alpha, blend, direction) { + if (skeleton == null) + throw new Error("skeleton cannot be null."); + if (loop && this.duration != 0) { + time %= this.duration; + if (lastTime > 0) + lastTime %= this.duration; + } + let timelines = this.timelines; + for (let i = 0, n = timelines.length; i < n; i++) + timelines[i].apply(skeleton, lastTime, time, events, alpha, blend, direction); + } + static binarySearch(values, target, step = 1) { + let low = 0; + let high = values.length / step - 2; + if (high == 0) + return step; + let current = high >>> 1; + while (true) { + if (values[(current + 1) * step] <= target) + low = current + 1; + else + high = current; + if (low == high) + return (low + 1) * step; + current = (low + high) >>> 1; + } + } + static linearSearch(values, target, step) { + for (let i = 0, last = values.length - step; i <= last; i += step) + if (values[i] > target) + return i; + return -1; + } + } + spine.Animation = Animation; + let MixBlend; + (function (MixBlend) { + MixBlend[MixBlend["setup"] = 0] = "setup"; + MixBlend[MixBlend["first"] = 1] = "first"; + MixBlend[MixBlend["replace"] = 2] = "replace"; + MixBlend[MixBlend["add"] = 3] = "add"; + })(MixBlend = spine.MixBlend || (spine.MixBlend = {})); + let MixDirection; + (function (MixDirection) { + MixDirection[MixDirection["mixIn"] = 0] = "mixIn"; + MixDirection[MixDirection["mixOut"] = 1] = "mixOut"; + })(MixDirection = spine.MixDirection || (spine.MixDirection = {})); + let TimelineType; + (function (TimelineType) { + TimelineType[TimelineType["rotate"] = 0] = "rotate"; + TimelineType[TimelineType["translate"] = 1] = "translate"; + TimelineType[TimelineType["scale"] = 2] = "scale"; + TimelineType[TimelineType["shear"] = 3] = "shear"; + TimelineType[TimelineType["attachment"] = 4] = "attachment"; + TimelineType[TimelineType["color"] = 5] = "color"; + TimelineType[TimelineType["deform"] = 6] = "deform"; + TimelineType[TimelineType["event"] = 7] = "event"; + TimelineType[TimelineType["drawOrder"] = 8] = "drawOrder"; + TimelineType[TimelineType["ikConstraint"] = 9] = "ikConstraint"; + TimelineType[TimelineType["transformConstraint"] = 10] = "transformConstraint"; + TimelineType[TimelineType["pathConstraintPosition"] = 11] = "pathConstraintPosition"; + TimelineType[TimelineType["pathConstraintSpacing"] = 12] = "pathConstraintSpacing"; + TimelineType[TimelineType["pathConstraintMix"] = 13] = "pathConstraintMix"; + TimelineType[TimelineType["twoColor"] = 14] = "twoColor"; + })(TimelineType = spine.TimelineType || (spine.TimelineType = {})); + class CurveTimeline { + constructor(frameCount) { + if (frameCount <= 0) + throw new Error("frameCount must be > 0: " + frameCount); + this.curves = spine.Utils.newFloatArray((frameCount - 1) * CurveTimeline.BEZIER_SIZE); + } + getFrameCount() { + return this.curves.length / CurveTimeline.BEZIER_SIZE + 1; + } + setLinear(frameIndex) { + this.curves[frameIndex * CurveTimeline.BEZIER_SIZE] = CurveTimeline.LINEAR; + } + setStepped(frameIndex) { + this.curves[frameIndex * CurveTimeline.BEZIER_SIZE] = CurveTimeline.STEPPED; + } + getCurveType(frameIndex) { + let index = frameIndex * CurveTimeline.BEZIER_SIZE; + if (index == this.curves.length) + return CurveTimeline.LINEAR; + let type = this.curves[index]; + if (type == CurveTimeline.LINEAR) + return CurveTimeline.LINEAR; + if (type == CurveTimeline.STEPPED) + return CurveTimeline.STEPPED; + return CurveTimeline.BEZIER; + } + setCurve(frameIndex, cx1, cy1, cx2, cy2) { + let tmpx = (-cx1 * 2 + cx2) * 0.03, tmpy = (-cy1 * 2 + cy2) * 0.03; + let dddfx = ((cx1 - cx2) * 3 + 1) * 0.006, dddfy = ((cy1 - cy2) * 3 + 1) * 0.006; + let ddfx = tmpx * 2 + dddfx, ddfy = tmpy * 2 + dddfy; + let dfx = cx1 * 0.3 + tmpx + dddfx * 0.16666667, dfy = cy1 * 0.3 + tmpy + dddfy * 0.16666667; + let i = frameIndex * CurveTimeline.BEZIER_SIZE; + let curves = this.curves; + curves[i++] = CurveTimeline.BEZIER; + let x = dfx, y = dfy; + for (let n = i + CurveTimeline.BEZIER_SIZE - 1; i < n; i += 2) { + curves[i] = x; + curves[i + 1] = y; + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + x += dfx; + y += dfy; + } + } + getCurvePercent(frameIndex, percent) { + percent = spine.MathUtils.clamp(percent, 0, 1); + let curves = this.curves; + let i = frameIndex * CurveTimeline.BEZIER_SIZE; + let type = curves[i]; + if (type == CurveTimeline.LINEAR) + return percent; + if (type == CurveTimeline.STEPPED) + return 0; + i++; + let x = 0; + for (let start = i, n = i + CurveTimeline.BEZIER_SIZE - 1; i < n; i += 2) { + x = curves[i]; + if (x >= percent) { + let prevX, prevY; + if (i == start) { + prevX = 0; + prevY = 0; + } + else { + prevX = curves[i - 2]; + prevY = curves[i - 1]; + } + return prevY + (curves[i + 1] - prevY) * (percent - prevX) / (x - prevX); + } + } + let y = curves[i - 1]; + return y + (1 - y) * (percent - x) / (1 - x); + } + } + CurveTimeline.LINEAR = 0; + CurveTimeline.STEPPED = 1; + CurveTimeline.BEZIER = 2; + CurveTimeline.BEZIER_SIZE = 10 * 2 - 1; + spine.CurveTimeline = CurveTimeline; + class RotateTimeline extends CurveTimeline { + constructor(frameCount) { + super(frameCount); + this.frames = spine.Utils.newFloatArray(frameCount << 1); + } + getPropertyId() { + return (TimelineType.rotate << 24) + this.boneIndex; + } + setFrame(frameIndex, time, degrees) { + frameIndex <<= 1; + this.frames[frameIndex] = time; + this.frames[frameIndex + RotateTimeline.ROTATION] = degrees; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let frames = this.frames; + let bone = skeleton.bones[this.boneIndex]; + if (!bone.active) + return; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + bone.rotation = bone.data.rotation; + return; + case MixBlend.first: + let r = bone.data.rotation - bone.rotation; + bone.rotation += (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha; + } + return; + } + if (time >= frames[frames.length - RotateTimeline.ENTRIES]) { + let r = frames[frames.length + RotateTimeline.PREV_ROTATION]; + switch (blend) { + case MixBlend.setup: + bone.rotation = bone.data.rotation + r * alpha; + break; + case MixBlend.first: + case MixBlend.replace: + r += bone.data.rotation - bone.rotation; + r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; + case MixBlend.add: + bone.rotation += r * alpha; + } + return; + } + let frame = Animation.binarySearch(frames, time, RotateTimeline.ENTRIES); + let prevRotation = frames[frame + RotateTimeline.PREV_ROTATION]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime)); + let r = frames[frame + RotateTimeline.ROTATION] - prevRotation; + r = prevRotation + (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * percent; + switch (blend) { + case MixBlend.setup: + bone.rotation = bone.data.rotation + (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha; + break; + case MixBlend.first: + case MixBlend.replace: + r += bone.data.rotation - bone.rotation; + case MixBlend.add: + bone.rotation += (r - (16384 - ((16384.499999999996 - r / 360) | 0)) * 360) * alpha; + } + } + } + RotateTimeline.ENTRIES = 2; + RotateTimeline.PREV_TIME = -2; + RotateTimeline.PREV_ROTATION = -1; + RotateTimeline.ROTATION = 1; + spine.RotateTimeline = RotateTimeline; + class TranslateTimeline extends CurveTimeline { + constructor(frameCount) { + super(frameCount); + this.frames = spine.Utils.newFloatArray(frameCount * TranslateTimeline.ENTRIES); + } + getPropertyId() { + return (TimelineType.translate << 24) + this.boneIndex; + } + setFrame(frameIndex, time, x, y) { + frameIndex *= TranslateTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + TranslateTimeline.X] = x; + this.frames[frameIndex + TranslateTimeline.Y] = y; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let frames = this.frames; + let bone = skeleton.bones[this.boneIndex]; + if (!bone.active) + return; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + bone.x = bone.data.x; + bone.y = bone.data.y; + return; + case MixBlend.first: + bone.x += (bone.data.x - bone.x) * alpha; + bone.y += (bone.data.y - bone.y) * alpha; + } + return; + } + let x = 0, y = 0; + if (time >= frames[frames.length - TranslateTimeline.ENTRIES]) { + x = frames[frames.length + TranslateTimeline.PREV_X]; + y = frames[frames.length + TranslateTimeline.PREV_Y]; + } + else { + let frame = Animation.binarySearch(frames, time, TranslateTimeline.ENTRIES); + x = frames[frame + TranslateTimeline.PREV_X]; + y = frames[frame + TranslateTimeline.PREV_Y]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / TranslateTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TranslateTimeline.PREV_TIME] - frameTime)); + x += (frames[frame + TranslateTimeline.X] - x) * percent; + y += (frames[frame + TranslateTimeline.Y] - y) * percent; + } + switch (blend) { + case MixBlend.setup: + bone.x = bone.data.x + x * alpha; + bone.y = bone.data.y + y * alpha; + break; + case MixBlend.first: + case MixBlend.replace: + bone.x += (bone.data.x + x - bone.x) * alpha; + bone.y += (bone.data.y + y - bone.y) * alpha; + break; + case MixBlend.add: + bone.x += x * alpha; + bone.y += y * alpha; + } + } + } + TranslateTimeline.ENTRIES = 3; + TranslateTimeline.PREV_TIME = -3; + TranslateTimeline.PREV_X = -2; + TranslateTimeline.PREV_Y = -1; + TranslateTimeline.X = 1; + TranslateTimeline.Y = 2; + spine.TranslateTimeline = TranslateTimeline; + class ScaleTimeline extends TranslateTimeline { + constructor(frameCount) { + super(frameCount); + } + getPropertyId() { + return (TimelineType.scale << 24) + this.boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let frames = this.frames; + let bone = skeleton.bones[this.boneIndex]; + if (!bone.active) + return; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + bone.scaleX = bone.data.scaleX; + bone.scaleY = bone.data.scaleY; + return; + case MixBlend.first: + bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha; + bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha; + } + return; + } + let x = 0, y = 0; + if (time >= frames[frames.length - ScaleTimeline.ENTRIES]) { + x = frames[frames.length + ScaleTimeline.PREV_X] * bone.data.scaleX; + y = frames[frames.length + ScaleTimeline.PREV_Y] * bone.data.scaleY; + } + else { + let frame = Animation.binarySearch(frames, time, ScaleTimeline.ENTRIES); + x = frames[frame + ScaleTimeline.PREV_X]; + y = frames[frame + ScaleTimeline.PREV_Y]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / ScaleTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ScaleTimeline.PREV_TIME] - frameTime)); + x = (x + (frames[frame + ScaleTimeline.X] - x) * percent) * bone.data.scaleX; + y = (y + (frames[frame + ScaleTimeline.Y] - y) * percent) * bone.data.scaleY; + } + if (alpha == 1) { + if (blend == MixBlend.add) { + bone.scaleX += x - bone.data.scaleX; + bone.scaleY += y - bone.data.scaleY; + } + else { + bone.scaleX = x; + bone.scaleY = y; + } + } + else { + let bx = 0, by = 0; + if (direction == MixDirection.mixOut) { + switch (blend) { + case MixBlend.setup: + bx = bone.data.scaleX; + by = bone.data.scaleY; + bone.scaleX = bx + (Math.abs(x) * spine.MathUtils.signum(bx) - bx) * alpha; + bone.scaleY = by + (Math.abs(y) * spine.MathUtils.signum(by) - by) * alpha; + break; + case MixBlend.first: + case MixBlend.replace: + bx = bone.scaleX; + by = bone.scaleY; + bone.scaleX = bx + (Math.abs(x) * spine.MathUtils.signum(bx) - bx) * alpha; + bone.scaleY = by + (Math.abs(y) * spine.MathUtils.signum(by) - by) * alpha; + break; + case MixBlend.add: + bx = bone.scaleX; + by = bone.scaleY; + bone.scaleX = bx + (Math.abs(x) * spine.MathUtils.signum(bx) - bone.data.scaleX) * alpha; + bone.scaleY = by + (Math.abs(y) * spine.MathUtils.signum(by) - bone.data.scaleY) * alpha; + } + } + else { + switch (blend) { + case MixBlend.setup: + bx = Math.abs(bone.data.scaleX) * spine.MathUtils.signum(x); + by = Math.abs(bone.data.scaleY) * spine.MathUtils.signum(y); + bone.scaleX = bx + (x - bx) * alpha; + bone.scaleY = by + (y - by) * alpha; + break; + case MixBlend.first: + case MixBlend.replace: + bx = Math.abs(bone.scaleX) * spine.MathUtils.signum(x); + by = Math.abs(bone.scaleY) * spine.MathUtils.signum(y); + bone.scaleX = bx + (x - bx) * alpha; + bone.scaleY = by + (y - by) * alpha; + break; + case MixBlend.add: + bx = spine.MathUtils.signum(x); + by = spine.MathUtils.signum(y); + bone.scaleX = Math.abs(bone.scaleX) * bx + (x - Math.abs(bone.data.scaleX) * bx) * alpha; + bone.scaleY = Math.abs(bone.scaleY) * by + (y - Math.abs(bone.data.scaleY) * by) * alpha; + } + } + } + } + } + spine.ScaleTimeline = ScaleTimeline; + class ShearTimeline extends TranslateTimeline { + constructor(frameCount) { + super(frameCount); + } + getPropertyId() { + return (TimelineType.shear << 24) + this.boneIndex; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let frames = this.frames; + let bone = skeleton.bones[this.boneIndex]; + if (!bone.active) + return; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + bone.shearX = bone.data.shearX; + bone.shearY = bone.data.shearY; + return; + case MixBlend.first: + bone.shearX += (bone.data.shearX - bone.shearX) * alpha; + bone.shearY += (bone.data.shearY - bone.shearY) * alpha; + } + return; + } + let x = 0, y = 0; + if (time >= frames[frames.length - ShearTimeline.ENTRIES]) { + x = frames[frames.length + ShearTimeline.PREV_X]; + y = frames[frames.length + ShearTimeline.PREV_Y]; + } + else { + let frame = Animation.binarySearch(frames, time, ShearTimeline.ENTRIES); + x = frames[frame + ShearTimeline.PREV_X]; + y = frames[frame + ShearTimeline.PREV_Y]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / ShearTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ShearTimeline.PREV_TIME] - frameTime)); + x = x + (frames[frame + ShearTimeline.X] - x) * percent; + y = y + (frames[frame + ShearTimeline.Y] - y) * percent; + } + switch (blend) { + case MixBlend.setup: + bone.shearX = bone.data.shearX + x * alpha; + bone.shearY = bone.data.shearY + y * alpha; + break; + case MixBlend.first: + case MixBlend.replace: + bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha; + bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha; + break; + case MixBlend.add: + bone.shearX += x * alpha; + bone.shearY += y * alpha; + } + } + } + spine.ShearTimeline = ShearTimeline; + class ColorTimeline extends CurveTimeline { + constructor(frameCount) { + super(frameCount); + this.frames = spine.Utils.newFloatArray(frameCount * ColorTimeline.ENTRIES); + } + getPropertyId() { + return (TimelineType.color << 24) + this.slotIndex; + } + setFrame(frameIndex, time, r, g, b, a) { + frameIndex *= ColorTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + ColorTimeline.R] = r; + this.frames[frameIndex + ColorTimeline.G] = g; + this.frames[frameIndex + ColorTimeline.B] = b; + this.frames[frameIndex + ColorTimeline.A] = a; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) + return; + let frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + slot.color.setFromColor(slot.data.color); + return; + case MixBlend.first: + let color = slot.color, setup = slot.data.color; + color.add((setup.r - color.r) * alpha, (setup.g - color.g) * alpha, (setup.b - color.b) * alpha, (setup.a - color.a) * alpha); + } + return; + } + let r = 0, g = 0, b = 0, a = 0; + if (time >= frames[frames.length - ColorTimeline.ENTRIES]) { + let i = frames.length; + r = frames[i + ColorTimeline.PREV_R]; + g = frames[i + ColorTimeline.PREV_G]; + b = frames[i + ColorTimeline.PREV_B]; + a = frames[i + ColorTimeline.PREV_A]; + } + else { + let frame = Animation.binarySearch(frames, time, ColorTimeline.ENTRIES); + r = frames[frame + ColorTimeline.PREV_R]; + g = frames[frame + ColorTimeline.PREV_G]; + b = frames[frame + ColorTimeline.PREV_B]; + a = frames[frame + ColorTimeline.PREV_A]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / ColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + ColorTimeline.PREV_TIME] - frameTime)); + r += (frames[frame + ColorTimeline.R] - r) * percent; + g += (frames[frame + ColorTimeline.G] - g) * percent; + b += (frames[frame + ColorTimeline.B] - b) * percent; + a += (frames[frame + ColorTimeline.A] - a) * percent; + } + if (alpha == 1) + slot.color.set(r, g, b, a); + else { + let color = slot.color; + if (blend == MixBlend.setup) + color.setFromColor(slot.data.color); + color.add((r - color.r) * alpha, (g - color.g) * alpha, (b - color.b) * alpha, (a - color.a) * alpha); + } + } + } + ColorTimeline.ENTRIES = 5; + ColorTimeline.PREV_TIME = -5; + ColorTimeline.PREV_R = -4; + ColorTimeline.PREV_G = -3; + ColorTimeline.PREV_B = -2; + ColorTimeline.PREV_A = -1; + ColorTimeline.R = 1; + ColorTimeline.G = 2; + ColorTimeline.B = 3; + ColorTimeline.A = 4; + spine.ColorTimeline = ColorTimeline; + class TwoColorTimeline extends CurveTimeline { + constructor(frameCount) { + super(frameCount); + this.frames = spine.Utils.newFloatArray(frameCount * TwoColorTimeline.ENTRIES); + } + getPropertyId() { + return (TimelineType.twoColor << 24) + this.slotIndex; + } + setFrame(frameIndex, time, r, g, b, a, r2, g2, b2) { + frameIndex *= TwoColorTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + TwoColorTimeline.R] = r; + this.frames[frameIndex + TwoColorTimeline.G] = g; + this.frames[frameIndex + TwoColorTimeline.B] = b; + this.frames[frameIndex + TwoColorTimeline.A] = a; + this.frames[frameIndex + TwoColorTimeline.R2] = r2; + this.frames[frameIndex + TwoColorTimeline.G2] = g2; + this.frames[frameIndex + TwoColorTimeline.B2] = b2; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) + return; + let frames = this.frames; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + slot.color.setFromColor(slot.data.color); + slot.darkColor.setFromColor(slot.data.darkColor); + return; + case MixBlend.first: + let light = slot.color, dark = slot.darkColor, setupLight = slot.data.color, setupDark = slot.data.darkColor; + light.add((setupLight.r - light.r) * alpha, (setupLight.g - light.g) * alpha, (setupLight.b - light.b) * alpha, (setupLight.a - light.a) * alpha); + dark.add((setupDark.r - dark.r) * alpha, (setupDark.g - dark.g) * alpha, (setupDark.b - dark.b) * alpha, 0); + } + return; + } + let r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0; + if (time >= frames[frames.length - TwoColorTimeline.ENTRIES]) { + let i = frames.length; + r = frames[i + TwoColorTimeline.PREV_R]; + g = frames[i + TwoColorTimeline.PREV_G]; + b = frames[i + TwoColorTimeline.PREV_B]; + a = frames[i + TwoColorTimeline.PREV_A]; + r2 = frames[i + TwoColorTimeline.PREV_R2]; + g2 = frames[i + TwoColorTimeline.PREV_G2]; + b2 = frames[i + TwoColorTimeline.PREV_B2]; + } + else { + let frame = Animation.binarySearch(frames, time, TwoColorTimeline.ENTRIES); + r = frames[frame + TwoColorTimeline.PREV_R]; + g = frames[frame + TwoColorTimeline.PREV_G]; + b = frames[frame + TwoColorTimeline.PREV_B]; + a = frames[frame + TwoColorTimeline.PREV_A]; + r2 = frames[frame + TwoColorTimeline.PREV_R2]; + g2 = frames[frame + TwoColorTimeline.PREV_G2]; + b2 = frames[frame + TwoColorTimeline.PREV_B2]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / TwoColorTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TwoColorTimeline.PREV_TIME] - frameTime)); + r += (frames[frame + TwoColorTimeline.R] - r) * percent; + g += (frames[frame + TwoColorTimeline.G] - g) * percent; + b += (frames[frame + TwoColorTimeline.B] - b) * percent; + a += (frames[frame + TwoColorTimeline.A] - a) * percent; + r2 += (frames[frame + TwoColorTimeline.R2] - r2) * percent; + g2 += (frames[frame + TwoColorTimeline.G2] - g2) * percent; + b2 += (frames[frame + TwoColorTimeline.B2] - b2) * percent; + } + if (alpha == 1) { + slot.color.set(r, g, b, a); + slot.darkColor.set(r2, g2, b2, 1); + } + else { + let light = slot.color, dark = slot.darkColor; + if (blend == MixBlend.setup) { + light.setFromColor(slot.data.color); + dark.setFromColor(slot.data.darkColor); + } + light.add((r - light.r) * alpha, (g - light.g) * alpha, (b - light.b) * alpha, (a - light.a) * alpha); + dark.add((r2 - dark.r) * alpha, (g2 - dark.g) * alpha, (b2 - dark.b) * alpha, 0); + } + } + } + TwoColorTimeline.ENTRIES = 8; + TwoColorTimeline.PREV_TIME = -8; + TwoColorTimeline.PREV_R = -7; + TwoColorTimeline.PREV_G = -6; + TwoColorTimeline.PREV_B = -5; + TwoColorTimeline.PREV_A = -4; + TwoColorTimeline.PREV_R2 = -3; + TwoColorTimeline.PREV_G2 = -2; + TwoColorTimeline.PREV_B2 = -1; + TwoColorTimeline.R = 1; + TwoColorTimeline.G = 2; + TwoColorTimeline.B = 3; + TwoColorTimeline.A = 4; + TwoColorTimeline.R2 = 5; + TwoColorTimeline.G2 = 6; + TwoColorTimeline.B2 = 7; + spine.TwoColorTimeline = TwoColorTimeline; + class AttachmentTimeline { + constructor(frameCount) { + this.frames = spine.Utils.newFloatArray(frameCount); + this.attachmentNames = new Array(frameCount); + } + getPropertyId() { + return (TimelineType.attachment << 24) + this.slotIndex; + } + getFrameCount() { + return this.frames.length; + } + setFrame(frameIndex, time, attachmentName) { + this.frames[frameIndex] = time; + this.attachmentNames[frameIndex] = attachmentName; + } + apply(skeleton, lastTime, time, events, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) + return; + if (direction == MixDirection.mixOut) { + if (blend == MixBlend.setup) + this.setAttachment(skeleton, slot, slot.data.attachmentName); + return; + } + let frames = this.frames; + if (time < frames[0]) { + if (blend == MixBlend.setup || blend == MixBlend.first) + this.setAttachment(skeleton, slot, slot.data.attachmentName); + return; + } + let frameIndex = 0; + if (time >= frames[frames.length - 1]) + frameIndex = frames.length - 1; + else + frameIndex = Animation.binarySearch(frames, time, 1) - 1; + let attachmentName = this.attachmentNames[frameIndex]; + skeleton.slots[this.slotIndex] + .setAttachment(attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName)); + } + setAttachment(skeleton, slot, attachmentName) { + slot.attachment = attachmentName == null ? null : skeleton.getAttachment(this.slotIndex, attachmentName); + } + } + spine.AttachmentTimeline = AttachmentTimeline; + let zeros = null; + class DeformTimeline extends CurveTimeline { + constructor(frameCount) { + super(frameCount); + this.frames = spine.Utils.newFloatArray(frameCount); + this.frameVertices = new Array(frameCount); + if (zeros == null) + zeros = spine.Utils.newFloatArray(64); + } + getPropertyId() { + return (TimelineType.deform << 27) + +this.attachment.id + this.slotIndex; + } + setFrame(frameIndex, time, vertices) { + this.frames[frameIndex] = time; + this.frameVertices[frameIndex] = vertices; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let slot = skeleton.slots[this.slotIndex]; + if (!slot.bone.active) + return; + let slotAttachment = slot.getAttachment(); + if (!(slotAttachment instanceof spine.VertexAttachment) || !(slotAttachment.deformAttachment == this.attachment)) + return; + let deformArray = slot.deform; + if (deformArray.length == 0) + blend = MixBlend.setup; + let frameVertices = this.frameVertices; + let vertexCount = frameVertices[0].length; + let frames = this.frames; + if (time < frames[0]) { + let vertexAttachment = slotAttachment; + switch (blend) { + case MixBlend.setup: + deformArray.length = 0; + return; + case MixBlend.first: + if (alpha == 1) { + deformArray.length = 0; + break; + } + let deform = spine.Utils.setArraySize(deformArray, vertexCount); + if (vertexAttachment.bones == null) { + let setupVertices = vertexAttachment.vertices; + for (var i = 0; i < vertexCount; i++) + deform[i] += (setupVertices[i] - deform[i]) * alpha; + } + else { + alpha = 1 - alpha; + for (var i = 0; i < vertexCount; i++) + deform[i] *= alpha; + } + } + return; + } + let deform = spine.Utils.setArraySize(deformArray, vertexCount); + if (time >= frames[frames.length - 1]) { + let lastVertices = frameVertices[frames.length - 1]; + if (alpha == 1) { + if (blend == MixBlend.add) { + let vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + let setupVertices = vertexAttachment.vertices; + for (let i = 0; i < vertexCount; i++) { + deform[i] += lastVertices[i] - setupVertices[i]; + } + } + else { + for (let i = 0; i < vertexCount; i++) + deform[i] += lastVertices[i]; + } + } + else { + spine.Utils.arrayCopy(lastVertices, 0, deform, 0, vertexCount); + } + } + else { + switch (blend) { + case MixBlend.setup: { + let vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + let setupVertices = vertexAttachment.vertices; + for (let i = 0; i < vertexCount; i++) { + let setup = setupVertices[i]; + deform[i] = setup + (lastVertices[i] - setup) * alpha; + } + } + else { + for (let i = 0; i < vertexCount; i++) + deform[i] = lastVertices[i] * alpha; + } + break; + } + case MixBlend.first: + case MixBlend.replace: + for (let i = 0; i < vertexCount; i++) + deform[i] += (lastVertices[i] - deform[i]) * alpha; + break; + case MixBlend.add: + let vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + let setupVertices = vertexAttachment.vertices; + for (let i = 0; i < vertexCount; i++) { + deform[i] += (lastVertices[i] - setupVertices[i]) * alpha; + } + } + else { + for (let i = 0; i < vertexCount; i++) + deform[i] += lastVertices[i] * alpha; + } + } + } + return; + } + let frame = Animation.binarySearch(frames, time); + let prevVertices = frameVertices[frame - 1]; + let nextVertices = frameVertices[frame]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame - 1, 1 - (time - frameTime) / (frames[frame - 1] - frameTime)); + if (alpha == 1) { + if (blend == MixBlend.add) { + let vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + let setupVertices = vertexAttachment.vertices; + for (let i = 0; i < vertexCount; i++) { + let prev = prevVertices[i]; + deform[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i]; + } + } + else { + for (let i = 0; i < vertexCount; i++) { + let prev = prevVertices[i]; + deform[i] += prev + (nextVertices[i] - prev) * percent; + } + } + } + else { + for (let i = 0; i < vertexCount; i++) { + let prev = prevVertices[i]; + deform[i] = prev + (nextVertices[i] - prev) * percent; + } + } + } + else { + switch (blend) { + case MixBlend.setup: { + let vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + let setupVertices = vertexAttachment.vertices; + for (let i = 0; i < vertexCount; i++) { + let prev = prevVertices[i], setup = setupVertices[i]; + deform[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha; + } + } + else { + for (let i = 0; i < vertexCount; i++) { + let prev = prevVertices[i]; + deform[i] = (prev + (nextVertices[i] - prev) * percent) * alpha; + } + } + break; + } + case MixBlend.first: + case MixBlend.replace: + for (let i = 0; i < vertexCount; i++) { + let prev = prevVertices[i]; + deform[i] += (prev + (nextVertices[i] - prev) * percent - deform[i]) * alpha; + } + break; + case MixBlend.add: + let vertexAttachment = slotAttachment; + if (vertexAttachment.bones == null) { + let setupVertices = vertexAttachment.vertices; + for (let i = 0; i < vertexCount; i++) { + let prev = prevVertices[i]; + deform[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha; + } + } + else { + for (let i = 0; i < vertexCount; i++) { + let prev = prevVertices[i]; + deform[i] += (prev + (nextVertices[i] - prev) * percent) * alpha; + } + } + } + } + } + } + spine.DeformTimeline = DeformTimeline; + class EventTimeline { + constructor(frameCount) { + this.frames = spine.Utils.newFloatArray(frameCount); + this.events = new Array(frameCount); + } + getPropertyId() { + return TimelineType.event << 24; + } + getFrameCount() { + return this.frames.length; + } + setFrame(frameIndex, event) { + this.frames[frameIndex] = event.time; + this.events[frameIndex] = event; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + if (firedEvents == null) + return; + let frames = this.frames; + let frameCount = this.frames.length; + if (lastTime > time) { + this.apply(skeleton, lastTime, Number.MAX_VALUE, firedEvents, alpha, blend, direction); + lastTime = -1; + } + else if (lastTime >= frames[frameCount - 1]) + return; + if (time < frames[0]) + return; + let frame = 0; + if (lastTime < frames[0]) + frame = 0; + else { + frame = Animation.binarySearch(frames, lastTime); + let frameTime = frames[frame]; + while (frame > 0) { + if (frames[frame - 1] != frameTime) + break; + frame--; + } + } + for (; frame < frameCount && time >= frames[frame]; frame++) + firedEvents.push(this.events[frame]); + } + } + spine.EventTimeline = EventTimeline; + class DrawOrderTimeline { + constructor(frameCount) { + this.frames = spine.Utils.newFloatArray(frameCount); + this.drawOrders = new Array(frameCount); + } + getPropertyId() { + return TimelineType.drawOrder << 24; + } + getFrameCount() { + return this.frames.length; + } + setFrame(frameIndex, time, drawOrder) { + this.frames[frameIndex] = time; + this.drawOrders[frameIndex] = drawOrder; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let drawOrder = skeleton.drawOrder; + let slots = skeleton.slots; + if (direction == MixDirection.mixOut) { + if (blend == MixBlend.setup) + spine.Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); + return; + } + let frames = this.frames; + if (time < frames[0]) { + if (blend == MixBlend.setup || blend == MixBlend.first) + spine.Utils.arrayCopy(skeleton.slots, 0, skeleton.drawOrder, 0, skeleton.slots.length); + return; + } + let frame = 0; + if (time >= frames[frames.length - 1]) + frame = frames.length - 1; + else + frame = Animation.binarySearch(frames, time) - 1; + let drawOrderToSetupIndex = this.drawOrders[frame]; + if (drawOrderToSetupIndex == null) + spine.Utils.arrayCopy(slots, 0, drawOrder, 0, slots.length); + else { + for (let i = 0, n = drawOrderToSetupIndex.length; i < n; i++) + drawOrder[i] = slots[drawOrderToSetupIndex[i]]; + } + } + } + spine.DrawOrderTimeline = DrawOrderTimeline; + class IkConstraintTimeline extends CurveTimeline { + constructor(frameCount) { + super(frameCount); + this.frames = spine.Utils.newFloatArray(frameCount * IkConstraintTimeline.ENTRIES); + } + getPropertyId() { + return (TimelineType.ikConstraint << 24) + this.ikConstraintIndex; + } + setFrame(frameIndex, time, mix, softness, bendDirection, compress, stretch) { + frameIndex *= IkConstraintTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + IkConstraintTimeline.MIX] = mix; + this.frames[frameIndex + IkConstraintTimeline.SOFTNESS] = softness; + this.frames[frameIndex + IkConstraintTimeline.BEND_DIRECTION] = bendDirection; + this.frames[frameIndex + IkConstraintTimeline.COMPRESS] = compress ? 1 : 0; + this.frames[frameIndex + IkConstraintTimeline.STRETCH] = stretch ? 1 : 0; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let frames = this.frames; + let constraint = skeleton.ikConstraints[this.ikConstraintIndex]; + if (!constraint.active) + return; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + constraint.mix = constraint.data.mix; + constraint.softness = constraint.data.softness; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + return; + case MixBlend.first: + constraint.mix += (constraint.data.mix - constraint.mix) * alpha; + constraint.softness += (constraint.data.softness - constraint.softness) * alpha; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + return; + } + if (time >= frames[frames.length - IkConstraintTimeline.ENTRIES]) { + if (blend == MixBlend.setup) { + constraint.mix = constraint.data.mix + (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.data.mix) * alpha; + constraint.softness = constraint.data.softness + + (frames[frames.length + IkConstraintTimeline.PREV_SOFTNESS] - constraint.data.softness) * alpha; + if (direction == MixDirection.mixOut) { + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + else { + constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; + constraint.compress = frames[frames.length + IkConstraintTimeline.PREV_COMPRESS] != 0; + constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0; + } + } + else { + constraint.mix += (frames[frames.length + IkConstraintTimeline.PREV_MIX] - constraint.mix) * alpha; + constraint.softness += (frames[frames.length + IkConstraintTimeline.PREV_SOFTNESS] - constraint.softness) * alpha; + if (direction == MixDirection.mixIn) { + constraint.bendDirection = frames[frames.length + IkConstraintTimeline.PREV_BEND_DIRECTION]; + constraint.compress = frames[frames.length + IkConstraintTimeline.PREV_COMPRESS] != 0; + constraint.stretch = frames[frames.length + IkConstraintTimeline.PREV_STRETCH] != 0; + } + } + return; + } + let frame = Animation.binarySearch(frames, time, IkConstraintTimeline.ENTRIES); + let mix = frames[frame + IkConstraintTimeline.PREV_MIX]; + let softness = frames[frame + IkConstraintTimeline.PREV_SOFTNESS]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / IkConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + IkConstraintTimeline.PREV_TIME] - frameTime)); + if (blend == MixBlend.setup) { + constraint.mix = constraint.data.mix + (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.data.mix) * alpha; + constraint.softness = constraint.data.softness + + (softness + (frames[frame + IkConstraintTimeline.SOFTNESS] - softness) * percent - constraint.data.softness) * alpha; + if (direction == MixDirection.mixOut) { + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + else { + constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; + constraint.compress = frames[frame + IkConstraintTimeline.PREV_COMPRESS] != 0; + constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0; + } + } + else { + constraint.mix += (mix + (frames[frame + IkConstraintTimeline.MIX] - mix) * percent - constraint.mix) * alpha; + constraint.softness += (softness + (frames[frame + IkConstraintTimeline.SOFTNESS] - softness) * percent - constraint.softness) * alpha; + if (direction == MixDirection.mixIn) { + constraint.bendDirection = frames[frame + IkConstraintTimeline.PREV_BEND_DIRECTION]; + constraint.compress = frames[frame + IkConstraintTimeline.PREV_COMPRESS] != 0; + constraint.stretch = frames[frame + IkConstraintTimeline.PREV_STRETCH] != 0; + } + } + } + } + IkConstraintTimeline.ENTRIES = 6; + IkConstraintTimeline.PREV_TIME = -6; + IkConstraintTimeline.PREV_MIX = -5; + IkConstraintTimeline.PREV_SOFTNESS = -4; + IkConstraintTimeline.PREV_BEND_DIRECTION = -3; + IkConstraintTimeline.PREV_COMPRESS = -2; + IkConstraintTimeline.PREV_STRETCH = -1; + IkConstraintTimeline.MIX = 1; + IkConstraintTimeline.SOFTNESS = 2; + IkConstraintTimeline.BEND_DIRECTION = 3; + IkConstraintTimeline.COMPRESS = 4; + IkConstraintTimeline.STRETCH = 5; + spine.IkConstraintTimeline = IkConstraintTimeline; + class TransformConstraintTimeline extends CurveTimeline { + constructor(frameCount) { + super(frameCount); + this.frames = spine.Utils.newFloatArray(frameCount * TransformConstraintTimeline.ENTRIES); + } + getPropertyId() { + return (TimelineType.transformConstraint << 24) + this.transformConstraintIndex; + } + setFrame(frameIndex, time, rotateMix, translateMix, scaleMix, shearMix) { + frameIndex *= TransformConstraintTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + TransformConstraintTimeline.ROTATE] = rotateMix; + this.frames[frameIndex + TransformConstraintTimeline.TRANSLATE] = translateMix; + this.frames[frameIndex + TransformConstraintTimeline.SCALE] = scaleMix; + this.frames[frameIndex + TransformConstraintTimeline.SHEAR] = shearMix; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let frames = this.frames; + let constraint = skeleton.transformConstraints[this.transformConstraintIndex]; + if (!constraint.active) + return; + if (time < frames[0]) { + let data = constraint.data; + switch (blend) { + case MixBlend.setup: + constraint.rotateMix = data.rotateMix; + constraint.translateMix = data.translateMix; + constraint.scaleMix = data.scaleMix; + constraint.shearMix = data.shearMix; + return; + case MixBlend.first: + constraint.rotateMix += (data.rotateMix - constraint.rotateMix) * alpha; + constraint.translateMix += (data.translateMix - constraint.translateMix) * alpha; + constraint.scaleMix += (data.scaleMix - constraint.scaleMix) * alpha; + constraint.shearMix += (data.shearMix - constraint.shearMix) * alpha; + } + return; + } + let rotate = 0, translate = 0, scale = 0, shear = 0; + if (time >= frames[frames.length - TransformConstraintTimeline.ENTRIES]) { + let i = frames.length; + rotate = frames[i + TransformConstraintTimeline.PREV_ROTATE]; + translate = frames[i + TransformConstraintTimeline.PREV_TRANSLATE]; + scale = frames[i + TransformConstraintTimeline.PREV_SCALE]; + shear = frames[i + TransformConstraintTimeline.PREV_SHEAR]; + } + else { + let frame = Animation.binarySearch(frames, time, TransformConstraintTimeline.ENTRIES); + rotate = frames[frame + TransformConstraintTimeline.PREV_ROTATE]; + translate = frames[frame + TransformConstraintTimeline.PREV_TRANSLATE]; + scale = frames[frame + TransformConstraintTimeline.PREV_SCALE]; + shear = frames[frame + TransformConstraintTimeline.PREV_SHEAR]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / TransformConstraintTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + TransformConstraintTimeline.PREV_TIME] - frameTime)); + rotate += (frames[frame + TransformConstraintTimeline.ROTATE] - rotate) * percent; + translate += (frames[frame + TransformConstraintTimeline.TRANSLATE] - translate) * percent; + scale += (frames[frame + TransformConstraintTimeline.SCALE] - scale) * percent; + shear += (frames[frame + TransformConstraintTimeline.SHEAR] - shear) * percent; + } + if (blend == MixBlend.setup) { + let data = constraint.data; + constraint.rotateMix = data.rotateMix + (rotate - data.rotateMix) * alpha; + constraint.translateMix = data.translateMix + (translate - data.translateMix) * alpha; + constraint.scaleMix = data.scaleMix + (scale - data.scaleMix) * alpha; + constraint.shearMix = data.shearMix + (shear - data.shearMix) * alpha; + } + else { + constraint.rotateMix += (rotate - constraint.rotateMix) * alpha; + constraint.translateMix += (translate - constraint.translateMix) * alpha; + constraint.scaleMix += (scale - constraint.scaleMix) * alpha; + constraint.shearMix += (shear - constraint.shearMix) * alpha; + } + } + } + TransformConstraintTimeline.ENTRIES = 5; + TransformConstraintTimeline.PREV_TIME = -5; + TransformConstraintTimeline.PREV_ROTATE = -4; + TransformConstraintTimeline.PREV_TRANSLATE = -3; + TransformConstraintTimeline.PREV_SCALE = -2; + TransformConstraintTimeline.PREV_SHEAR = -1; + TransformConstraintTimeline.ROTATE = 1; + TransformConstraintTimeline.TRANSLATE = 2; + TransformConstraintTimeline.SCALE = 3; + TransformConstraintTimeline.SHEAR = 4; + spine.TransformConstraintTimeline = TransformConstraintTimeline; + class PathConstraintPositionTimeline extends CurveTimeline { + constructor(frameCount) { + super(frameCount); + this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintPositionTimeline.ENTRIES); + } + getPropertyId() { + return (TimelineType.pathConstraintPosition << 24) + this.pathConstraintIndex; + } + setFrame(frameIndex, time, value) { + frameIndex *= PathConstraintPositionTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + PathConstraintPositionTimeline.VALUE] = value; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let frames = this.frames; + let constraint = skeleton.pathConstraints[this.pathConstraintIndex]; + if (!constraint.active) + return; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + constraint.position = constraint.data.position; + return; + case MixBlend.first: + constraint.position += (constraint.data.position - constraint.position) * alpha; + } + return; + } + let position = 0; + if (time >= frames[frames.length - PathConstraintPositionTimeline.ENTRIES]) + position = frames[frames.length + PathConstraintPositionTimeline.PREV_VALUE]; + else { + let frame = Animation.binarySearch(frames, time, PathConstraintPositionTimeline.ENTRIES); + position = frames[frame + PathConstraintPositionTimeline.PREV_VALUE]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / PathConstraintPositionTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintPositionTimeline.PREV_TIME] - frameTime)); + position += (frames[frame + PathConstraintPositionTimeline.VALUE] - position) * percent; + } + if (blend == MixBlend.setup) + constraint.position = constraint.data.position + (position - constraint.data.position) * alpha; + else + constraint.position += (position - constraint.position) * alpha; + } + } + PathConstraintPositionTimeline.ENTRIES = 2; + PathConstraintPositionTimeline.PREV_TIME = -2; + PathConstraintPositionTimeline.PREV_VALUE = -1; + PathConstraintPositionTimeline.VALUE = 1; + spine.PathConstraintPositionTimeline = PathConstraintPositionTimeline; + class PathConstraintSpacingTimeline extends PathConstraintPositionTimeline { + constructor(frameCount) { + super(frameCount); + } + getPropertyId() { + return (TimelineType.pathConstraintSpacing << 24) + this.pathConstraintIndex; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let frames = this.frames; + let constraint = skeleton.pathConstraints[this.pathConstraintIndex]; + if (!constraint.active) + return; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + constraint.spacing = constraint.data.spacing; + return; + case MixBlend.first: + constraint.spacing += (constraint.data.spacing - constraint.spacing) * alpha; + } + return; + } + let spacing = 0; + if (time >= frames[frames.length - PathConstraintSpacingTimeline.ENTRIES]) + spacing = frames[frames.length + PathConstraintSpacingTimeline.PREV_VALUE]; + else { + let frame = Animation.binarySearch(frames, time, PathConstraintSpacingTimeline.ENTRIES); + spacing = frames[frame + PathConstraintSpacingTimeline.PREV_VALUE]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / PathConstraintSpacingTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintSpacingTimeline.PREV_TIME] - frameTime)); + spacing += (frames[frame + PathConstraintSpacingTimeline.VALUE] - spacing) * percent; + } + if (blend == MixBlend.setup) + constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha; + else + constraint.spacing += (spacing - constraint.spacing) * alpha; + } + } + spine.PathConstraintSpacingTimeline = PathConstraintSpacingTimeline; + class PathConstraintMixTimeline extends CurveTimeline { + constructor(frameCount) { + super(frameCount); + this.frames = spine.Utils.newFloatArray(frameCount * PathConstraintMixTimeline.ENTRIES); + } + getPropertyId() { + return (TimelineType.pathConstraintMix << 24) + this.pathConstraintIndex; + } + setFrame(frameIndex, time, rotateMix, translateMix) { + frameIndex *= PathConstraintMixTimeline.ENTRIES; + this.frames[frameIndex] = time; + this.frames[frameIndex + PathConstraintMixTimeline.ROTATE] = rotateMix; + this.frames[frameIndex + PathConstraintMixTimeline.TRANSLATE] = translateMix; + } + apply(skeleton, lastTime, time, firedEvents, alpha, blend, direction) { + let frames = this.frames; + let constraint = skeleton.pathConstraints[this.pathConstraintIndex]; + if (!constraint.active) + return; + if (time < frames[0]) { + switch (blend) { + case MixBlend.setup: + constraint.rotateMix = constraint.data.rotateMix; + constraint.translateMix = constraint.data.translateMix; + return; + case MixBlend.first: + constraint.rotateMix += (constraint.data.rotateMix - constraint.rotateMix) * alpha; + constraint.translateMix += (constraint.data.translateMix - constraint.translateMix) * alpha; + } + return; + } + let rotate = 0, translate = 0; + if (time >= frames[frames.length - PathConstraintMixTimeline.ENTRIES]) { + rotate = frames[frames.length + PathConstraintMixTimeline.PREV_ROTATE]; + translate = frames[frames.length + PathConstraintMixTimeline.PREV_TRANSLATE]; + } + else { + let frame = Animation.binarySearch(frames, time, PathConstraintMixTimeline.ENTRIES); + rotate = frames[frame + PathConstraintMixTimeline.PREV_ROTATE]; + translate = frames[frame + PathConstraintMixTimeline.PREV_TRANSLATE]; + let frameTime = frames[frame]; + let percent = this.getCurvePercent(frame / PathConstraintMixTimeline.ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PathConstraintMixTimeline.PREV_TIME] - frameTime)); + rotate += (frames[frame + PathConstraintMixTimeline.ROTATE] - rotate) * percent; + translate += (frames[frame + PathConstraintMixTimeline.TRANSLATE] - translate) * percent; + } + if (blend == MixBlend.setup) { + constraint.rotateMix = constraint.data.rotateMix + (rotate - constraint.data.rotateMix) * alpha; + constraint.translateMix = constraint.data.translateMix + (translate - constraint.data.translateMix) * alpha; + } + else { + constraint.rotateMix += (rotate - constraint.rotateMix) * alpha; + constraint.translateMix += (translate - constraint.translateMix) * alpha; + } + } + } + PathConstraintMixTimeline.ENTRIES = 3; + PathConstraintMixTimeline.PREV_TIME = -3; + PathConstraintMixTimeline.PREV_ROTATE = -2; + PathConstraintMixTimeline.PREV_TRANSLATE = -1; + PathConstraintMixTimeline.ROTATE = 1; + PathConstraintMixTimeline.TRANSLATE = 2; + spine.PathConstraintMixTimeline = PathConstraintMixTimeline; +})(spine || (spine = {})); +var spine; +(function (spine) { + class AnimationState { + constructor(data) { + this.tracks = new Array(); + this.timeScale = 1; + this.unkeyedState = 0; + this.events = new Array(); + this.listeners = new Array(); + this.queue = new EventQueue(this); + this.propertyIDs = new spine.IntSet(); + this.animationsChanged = false; + this.trackEntryPool = new spine.Pool(() => new TrackEntry()); + this.data = data; + } + update(delta) { + delta *= this.timeScale; + let tracks = this.tracks; + for (let i = 0, n = tracks.length; i < n; i++) { + let current = tracks[i]; + if (current == null) + continue; + current.animationLast = current.nextAnimationLast; + current.trackLast = current.nextTrackLast; + let currentDelta = delta * current.timeScale; + if (current.delay > 0) { + current.delay -= currentDelta; + if (current.delay > 0) + continue; + currentDelta = -current.delay; + current.delay = 0; + } + let next = current.next; + if (next != null) { + let nextTime = current.trackLast - next.delay; + if (nextTime >= 0) { + next.delay = 0; + next.trackTime += current.timeScale == 0 ? 0 : (nextTime / current.timeScale + delta) * next.timeScale; + current.trackTime += currentDelta; + this.setCurrent(i, next, true); + while (next.mixingFrom != null) { + next.mixTime += delta; + next = next.mixingFrom; + } + continue; + } + } + else if (current.trackLast >= current.trackEnd && current.mixingFrom == null) { + tracks[i] = null; + this.queue.end(current); + this.disposeNext(current); + continue; + } + if (current.mixingFrom != null && this.updateMixingFrom(current, delta)) { + let from = current.mixingFrom; + current.mixingFrom = null; + if (from != null) + from.mixingTo = null; + while (from != null) { + this.queue.end(from); + from = from.mixingFrom; + } + } + current.trackTime += currentDelta; + } + this.queue.drain(); + } + updateMixingFrom(to, delta) { + let from = to.mixingFrom; + if (from == null) + return true; + let finished = this.updateMixingFrom(from, delta); + from.animationLast = from.nextAnimationLast; + from.trackLast = from.nextTrackLast; + if (to.mixTime > 0 && to.mixTime >= to.mixDuration) { + if (from.totalAlpha == 0 || to.mixDuration == 0) { + to.mixingFrom = from.mixingFrom; + if (from.mixingFrom != null) + from.mixingFrom.mixingTo = to; + to.interruptAlpha = from.interruptAlpha; + this.queue.end(from); + } + return finished; + } + from.trackTime += delta * from.timeScale; + to.mixTime += delta; + return false; + } + apply(skeleton) { + if (skeleton == null) + throw new Error("skeleton cannot be null."); + if (this.animationsChanged) + this._animationsChanged(); + let events = this.events; + let tracks = this.tracks; + let applied = false; + for (let i = 0, n = tracks.length; i < n; i++) { + let current = tracks[i]; + if (current == null || current.delay > 0) + continue; + applied = true; + let blend = i == 0 ? spine.MixBlend.first : current.mixBlend; + let mix = current.alpha; + if (current.mixingFrom != null) + mix *= this.applyMixingFrom(current, skeleton, blend); + else if (current.trackTime >= current.trackEnd && current.next == null) + mix = 0; + let animationLast = current.animationLast, animationTime = current.getAnimationTime(); + let timelineCount = current.animation.timelines.length; + let timelines = current.animation.timelines; + if ((i == 0 && mix == 1) || blend == spine.MixBlend.add) { + for (let ii = 0; ii < timelineCount; ii++) { + spine.Utils.webkit602BugfixHelper(mix, blend); + var timeline = timelines[ii]; + if (timeline instanceof spine.AttachmentTimeline) + this.applyAttachmentTimeline(timeline, skeleton, animationTime, blend, true); + else + timeline.apply(skeleton, animationLast, animationTime, events, mix, blend, spine.MixDirection.mixIn); + } + } + else { + let timelineMode = current.timelineMode; + let firstFrame = current.timelinesRotation.length == 0; + if (firstFrame) + spine.Utils.setArraySize(current.timelinesRotation, timelineCount << 1, null); + let timelinesRotation = current.timelinesRotation; + for (let ii = 0; ii < timelineCount; ii++) { + let timeline = timelines[ii]; + let timelineBlend = timelineMode[ii] == AnimationState.SUBSEQUENT ? blend : spine.MixBlend.setup; + if (timeline instanceof spine.RotateTimeline) { + this.applyRotateTimeline(timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame); + } + else if (timeline instanceof spine.AttachmentTimeline) { + this.applyAttachmentTimeline(timeline, skeleton, animationTime, blend, true); + } + else { + spine.Utils.webkit602BugfixHelper(mix, blend); + timeline.apply(skeleton, animationLast, animationTime, events, mix, timelineBlend, spine.MixDirection.mixIn); + } + } + } + this.queueEvents(current, animationTime); + events.length = 0; + current.nextAnimationLast = animationTime; + current.nextTrackLast = current.trackTime; + } + var setupState = this.unkeyedState + AnimationState.SETUP; + var slots = skeleton.slots; + for (var i = 0, n = skeleton.slots.length; i < n; i++) { + var slot = slots[i]; + if (slot.attachmentState == setupState) { + var attachmentName = slot.data.attachmentName; + slot.attachment = (attachmentName == null ? null : skeleton.getAttachment(slot.data.index, attachmentName)); + } + } + this.unkeyedState += 2; + this.queue.drain(); + return applied; + } + applyMixingFrom(to, skeleton, blend) { + let from = to.mixingFrom; + if (from.mixingFrom != null) + this.applyMixingFrom(from, skeleton, blend); + let mix = 0; + if (to.mixDuration == 0) { + mix = 1; + if (blend == spine.MixBlend.first) + blend = spine.MixBlend.setup; + } + else { + mix = to.mixTime / to.mixDuration; + if (mix > 1) + mix = 1; + if (blend != spine.MixBlend.first) + blend = from.mixBlend; + } + let events = mix < from.eventThreshold ? this.events : null; + let attachments = mix < from.attachmentThreshold, drawOrder = mix < from.drawOrderThreshold; + let animationLast = from.animationLast, animationTime = from.getAnimationTime(); + let timelineCount = from.animation.timelines.length; + let timelines = from.animation.timelines; + let alphaHold = from.alpha * to.interruptAlpha, alphaMix = alphaHold * (1 - mix); + if (blend == spine.MixBlend.add) { + for (let i = 0; i < timelineCount; i++) + timelines[i].apply(skeleton, animationLast, animationTime, events, alphaMix, blend, spine.MixDirection.mixOut); + } + else { + let timelineMode = from.timelineMode; + let timelineHoldMix = from.timelineHoldMix; + let firstFrame = from.timelinesRotation.length == 0; + if (firstFrame) + spine.Utils.setArraySize(from.timelinesRotation, timelineCount << 1, null); + let timelinesRotation = from.timelinesRotation; + from.totalAlpha = 0; + for (let i = 0; i < timelineCount; i++) { + let timeline = timelines[i]; + let direction = spine.MixDirection.mixOut; + let timelineBlend; + let alpha = 0; + switch (timelineMode[i]) { + case AnimationState.SUBSEQUENT: + if (!drawOrder && timeline instanceof spine.DrawOrderTimeline) + continue; + timelineBlend = blend; + alpha = alphaMix; + break; + case AnimationState.FIRST: + timelineBlend = spine.MixBlend.setup; + alpha = alphaMix; + break; + case AnimationState.HOLD: + timelineBlend = spine.MixBlend.setup; + alpha = alphaHold; + break; + default: + timelineBlend = spine.MixBlend.setup; + let holdMix = timelineHoldMix[i]; + alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration); + break; + } + from.totalAlpha += alpha; + if (timeline instanceof spine.RotateTimeline) + this.applyRotateTimeline(timeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation, i << 1, firstFrame); + else if (timeline instanceof spine.AttachmentTimeline) + this.applyAttachmentTimeline(timeline, skeleton, animationTime, timelineBlend, attachments); + else { + spine.Utils.webkit602BugfixHelper(alpha, blend); + if (drawOrder && timeline instanceof spine.DrawOrderTimeline && timelineBlend == spine.MixBlend.setup) + direction = spine.MixDirection.mixIn; + timeline.apply(skeleton, animationLast, animationTime, events, alpha, timelineBlend, direction); + } + } + } + if (to.mixDuration > 0) + this.queueEvents(from, animationTime); + this.events.length = 0; + from.nextAnimationLast = animationTime; + from.nextTrackLast = from.trackTime; + return mix; + } + applyAttachmentTimeline(timeline, skeleton, time, blend, attachments) { + var slot = skeleton.slots[timeline.slotIndex]; + if (!slot.bone.active) + return; + var frames = timeline.frames; + if (time < frames[0]) { + if (blend == spine.MixBlend.setup || blend == spine.MixBlend.first) + this.setAttachment(skeleton, slot, slot.data.attachmentName, attachments); + } + else { + var frameIndex; + if (time >= frames[frames.length - 1]) + frameIndex = frames.length - 1; + else + frameIndex = spine.Animation.binarySearch(frames, time) - 1; + this.setAttachment(skeleton, slot, timeline.attachmentNames[frameIndex], attachments); + } + if (slot.attachmentState <= this.unkeyedState) + slot.attachmentState = this.unkeyedState + AnimationState.SETUP; + } + setAttachment(skeleton, slot, attachmentName, attachments) { + slot.attachment = attachmentName == null ? null : skeleton.getAttachment(slot.data.index, attachmentName); + if (attachments) + slot.attachmentState = this.unkeyedState + AnimationState.CURRENT; + } + applyRotateTimeline(timeline, skeleton, time, alpha, blend, timelinesRotation, i, firstFrame) { + if (firstFrame) + timelinesRotation[i] = 0; + if (alpha == 1) { + timeline.apply(skeleton, 0, time, null, 1, blend, spine.MixDirection.mixIn); + return; + } + let rotateTimeline = timeline; + let frames = rotateTimeline.frames; + let bone = skeleton.bones[rotateTimeline.boneIndex]; + if (!bone.active) + return; + let r1 = 0, r2 = 0; + if (time < frames[0]) { + switch (blend) { + case spine.MixBlend.setup: + bone.rotation = bone.data.rotation; + default: + return; + case spine.MixBlend.first: + r1 = bone.rotation; + r2 = bone.data.rotation; + } + } + else { + r1 = blend == spine.MixBlend.setup ? bone.data.rotation : bone.rotation; + if (time >= frames[frames.length - spine.RotateTimeline.ENTRIES]) + r2 = bone.data.rotation + frames[frames.length + spine.RotateTimeline.PREV_ROTATION]; + else { + let frame = spine.Animation.binarySearch(frames, time, spine.RotateTimeline.ENTRIES); + let prevRotation = frames[frame + spine.RotateTimeline.PREV_ROTATION]; + let frameTime = frames[frame]; + let percent = rotateTimeline.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + spine.RotateTimeline.PREV_TIME] - frameTime)); + r2 = frames[frame + spine.RotateTimeline.ROTATION] - prevRotation; + r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360; + r2 = prevRotation + r2 * percent + bone.data.rotation; + r2 -= (16384 - ((16384.499999999996 - r2 / 360) | 0)) * 360; + } + } + let total = 0, diff = r2 - r1; + diff -= (16384 - ((16384.499999999996 - diff / 360) | 0)) * 360; + if (diff == 0) { + total = timelinesRotation[i]; + } + else { + let lastTotal = 0, lastDiff = 0; + if (firstFrame) { + lastTotal = 0; + lastDiff = diff; + } + else { + lastTotal = timelinesRotation[i]; + lastDiff = timelinesRotation[i + 1]; + } + let current = diff > 0, dir = lastTotal >= 0; + if (spine.MathUtils.signum(lastDiff) != spine.MathUtils.signum(diff) && Math.abs(lastDiff) <= 90) { + if (Math.abs(lastTotal) > 180) + lastTotal += 360 * spine.MathUtils.signum(lastTotal); + dir = current; + } + total = diff + lastTotal - lastTotal % 360; + if (dir != current) + total += 360 * spine.MathUtils.signum(lastTotal); + timelinesRotation[i] = total; + } + timelinesRotation[i + 1] = diff; + r1 += total * alpha; + bone.rotation = r1 - (16384 - ((16384.499999999996 - r1 / 360) | 0)) * 360; + } + queueEvents(entry, animationTime) { + let animationStart = entry.animationStart, animationEnd = entry.animationEnd; + let duration = animationEnd - animationStart; + let trackLastWrapped = entry.trackLast % duration; + let events = this.events; + let i = 0, n = events.length; + for (; i < n; i++) { + let event = events[i]; + if (event.time < trackLastWrapped) + break; + if (event.time > animationEnd) + continue; + this.queue.event(entry, event); + } + let complete = false; + if (entry.loop) + complete = duration == 0 || trackLastWrapped > entry.trackTime % duration; + else + complete = animationTime >= animationEnd && entry.animationLast < animationEnd; + if (complete) + this.queue.complete(entry); + for (; i < n; i++) { + let event = events[i]; + if (event.time < animationStart) + continue; + this.queue.event(entry, events[i]); + } + } + clearTracks() { + let oldDrainDisabled = this.queue.drainDisabled; + this.queue.drainDisabled = true; + for (let i = 0, n = this.tracks.length; i < n; i++) + this.clearTrack(i); + this.tracks.length = 0; + this.queue.drainDisabled = oldDrainDisabled; + this.queue.drain(); + } + clearTrack(trackIndex) { + if (trackIndex >= this.tracks.length) + return; + let current = this.tracks[trackIndex]; + if (current == null) + return; + this.queue.end(current); + this.disposeNext(current); + let entry = current; + while (true) { + let from = entry.mixingFrom; + if (from == null) + break; + this.queue.end(from); + entry.mixingFrom = null; + entry.mixingTo = null; + entry = from; + } + this.tracks[current.trackIndex] = null; + this.queue.drain(); + } + setCurrent(index, current, interrupt) { + let from = this.expandToIndex(index); + this.tracks[index] = current; + if (from != null) { + if (interrupt) + this.queue.interrupt(from); + current.mixingFrom = from; + from.mixingTo = current; + current.mixTime = 0; + if (from.mixingFrom != null && from.mixDuration > 0) + current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration); + from.timelinesRotation.length = 0; + } + this.queue.start(current); + } + setAnimation(trackIndex, animationName, loop) { + let animation = this.data.skeletonData.findAnimation(animationName); + if (animation == null) + throw new Error("Animation not found: " + animationName); + return this.setAnimationWith(trackIndex, animation, loop); + } + setAnimationWith(trackIndex, animation, loop) { + if (animation == null) + throw new Error("animation cannot be null."); + let interrupt = true; + let current = this.expandToIndex(trackIndex); + if (current != null) { + if (current.nextTrackLast == -1) { + this.tracks[trackIndex] = current.mixingFrom; + this.queue.interrupt(current); + this.queue.end(current); + this.disposeNext(current); + current = current.mixingFrom; + interrupt = false; + } + else + this.disposeNext(current); + } + let entry = this.trackEntry(trackIndex, animation, loop, current); + this.setCurrent(trackIndex, entry, interrupt); + this.queue.drain(); + return entry; + } + addAnimation(trackIndex, animationName, loop, delay) { + let animation = this.data.skeletonData.findAnimation(animationName); + if (animation == null) + throw new Error("Animation not found: " + animationName); + return this.addAnimationWith(trackIndex, animation, loop, delay); + } + addAnimationWith(trackIndex, animation, loop, delay) { + if (animation == null) + throw new Error("animation cannot be null."); + let last = this.expandToIndex(trackIndex); + if (last != null) { + while (last.next != null) + last = last.next; + } + let entry = this.trackEntry(trackIndex, animation, loop, last); + if (last == null) { + this.setCurrent(trackIndex, entry, true); + this.queue.drain(); + } + else { + last.next = entry; + if (delay <= 0) { + let duration = last.animationEnd - last.animationStart; + if (duration != 0) { + if (last.loop) + delay += duration * (1 + ((last.trackTime / duration) | 0)); + else + delay += Math.max(duration, last.trackTime); + delay -= this.data.getMix(last.animation, animation); + } + else + delay = last.trackTime; + } + } + entry.delay = delay; + return entry; + } + setEmptyAnimation(trackIndex, mixDuration) { + let entry = this.setAnimationWith(trackIndex, AnimationState.emptyAnimation, false); + entry.mixDuration = mixDuration; + entry.trackEnd = mixDuration; + return entry; + } + addEmptyAnimation(trackIndex, mixDuration, delay) { + if (delay <= 0) + delay -= mixDuration; + let entry = this.addAnimationWith(trackIndex, AnimationState.emptyAnimation, false, delay); + entry.mixDuration = mixDuration; + entry.trackEnd = mixDuration; + return entry; + } + setEmptyAnimations(mixDuration) { + let oldDrainDisabled = this.queue.drainDisabled; + this.queue.drainDisabled = true; + for (let i = 0, n = this.tracks.length; i < n; i++) { + let current = this.tracks[i]; + if (current != null) + this.setEmptyAnimation(current.trackIndex, mixDuration); + } + this.queue.drainDisabled = oldDrainDisabled; + this.queue.drain(); + } + expandToIndex(index) { + if (index < this.tracks.length) + return this.tracks[index]; + spine.Utils.ensureArrayCapacity(this.tracks, index + 1, null); + this.tracks.length = index + 1; + return null; + } + trackEntry(trackIndex, animation, loop, last) { + let entry = this.trackEntryPool.obtain(); + entry.trackIndex = trackIndex; + entry.animation = animation; + entry.loop = loop; + entry.holdPrevious = false; + entry.eventThreshold = 0; + entry.attachmentThreshold = 0; + entry.drawOrderThreshold = 0; + entry.animationStart = 0; + entry.animationEnd = animation.duration; + entry.animationLast = -1; + entry.nextAnimationLast = -1; + entry.delay = 0; + entry.trackTime = 0; + entry.trackLast = -1; + entry.nextTrackLast = -1; + entry.trackEnd = Number.MAX_VALUE; + entry.timeScale = 1; + entry.alpha = 1; + entry.interruptAlpha = 1; + entry.mixTime = 0; + entry.mixDuration = last == null ? 0 : this.data.getMix(last.animation, animation); + entry.mixBlend = spine.MixBlend.replace; + return entry; + } + disposeNext(entry) { + let next = entry.next; + while (next != null) { + this.queue.dispose(next); + next = next.next; + } + entry.next = null; + } + _animationsChanged() { + this.animationsChanged = false; + this.propertyIDs.clear(); + for (let i = 0, n = this.tracks.length; i < n; i++) { + let entry = this.tracks[i]; + if (entry == null) + continue; + while (entry.mixingFrom != null) + entry = entry.mixingFrom; + do { + if (entry.mixingFrom == null || entry.mixBlend != spine.MixBlend.add) + this.computeHold(entry); + entry = entry.mixingTo; + } while (entry != null); + } + } + computeHold(entry) { + let to = entry.mixingTo; + let timelines = entry.animation.timelines; + let timelinesCount = entry.animation.timelines.length; + let timelineMode = spine.Utils.setArraySize(entry.timelineMode, timelinesCount); + entry.timelineHoldMix.length = 0; + let timelineDipMix = spine.Utils.setArraySize(entry.timelineHoldMix, timelinesCount); + let propertyIDs = this.propertyIDs; + if (to != null && to.holdPrevious) { + for (let i = 0; i < timelinesCount; i++) { + propertyIDs.add(timelines[i].getPropertyId()); + timelineMode[i] = AnimationState.HOLD; + } + return; + } + outer: for (let i = 0; i < timelinesCount; i++) { + let timeline = timelines[i]; + let id = timeline.getPropertyId(); + if (!propertyIDs.add(id)) + timelineMode[i] = AnimationState.SUBSEQUENT; + else if (to == null || timeline instanceof spine.AttachmentTimeline || timeline instanceof spine.DrawOrderTimeline + || timeline instanceof spine.EventTimeline || !to.animation.hasTimeline(id)) { + timelineMode[i] = AnimationState.FIRST; + } + else { + for (let next = to.mixingTo; next != null; next = next.mixingTo) { + if (next.animation.hasTimeline(id)) + continue; + if (entry.mixDuration > 0) { + timelineMode[i] = AnimationState.HOLD_MIX; + timelineDipMix[i] = next; + continue outer; + } + break; + } + timelineMode[i] = AnimationState.HOLD; + } + } + } + getCurrent(trackIndex) { + if (trackIndex >= this.tracks.length) + return null; + return this.tracks[trackIndex]; + } + addListener(listener) { + if (listener == null) + throw new Error("listener cannot be null."); + this.listeners.push(listener); + } + removeListener(listener) { + let index = this.listeners.indexOf(listener); + if (index >= 0) + this.listeners.splice(index, 1); + } + clearListeners() { + this.listeners.length = 0; + } + clearListenerNotifications() { + this.queue.clear(); + } + } + AnimationState.emptyAnimation = new spine.Animation("", [], 0); + AnimationState.SUBSEQUENT = 0; + AnimationState.FIRST = 1; + AnimationState.HOLD = 2; + AnimationState.HOLD_MIX = 3; + AnimationState.SETUP = 1; + AnimationState.CURRENT = 2; + spine.AnimationState = AnimationState; + class TrackEntry { + constructor() { + this.mixBlend = spine.MixBlend.replace; + this.timelineMode = new Array(); + this.timelineHoldMix = new Array(); + this.timelinesRotation = new Array(); + } + reset() { + this.next = null; + this.mixingFrom = null; + this.mixingTo = null; + this.animation = null; + this.listener = null; + this.timelineMode.length = 0; + this.timelineHoldMix.length = 0; + this.timelinesRotation.length = 0; + } + getAnimationTime() { + if (this.loop) { + let duration = this.animationEnd - this.animationStart; + if (duration == 0) + return this.animationStart; + return (this.trackTime % duration) + this.animationStart; + } + return Math.min(this.trackTime + this.animationStart, this.animationEnd); + } + setAnimationLast(animationLast) { + this.animationLast = animationLast; + this.nextAnimationLast = animationLast; + } + isComplete() { + return this.trackTime >= this.animationEnd - this.animationStart; + } + resetRotationDirections() { + this.timelinesRotation.length = 0; + } + } + spine.TrackEntry = TrackEntry; + class EventQueue { + constructor(animState) { + this.objects = []; + this.drainDisabled = false; + this.animState = animState; + } + start(entry) { + this.objects.push(EventType.start); + this.objects.push(entry); + this.animState.animationsChanged = true; + } + interrupt(entry) { + this.objects.push(EventType.interrupt); + this.objects.push(entry); + } + end(entry) { + this.objects.push(EventType.end); + this.objects.push(entry); + this.animState.animationsChanged = true; + } + dispose(entry) { + this.objects.push(EventType.dispose); + this.objects.push(entry); + } + complete(entry) { + this.objects.push(EventType.complete); + this.objects.push(entry); + } + event(entry, event) { + this.objects.push(EventType.event); + this.objects.push(entry); + this.objects.push(event); + } + drain() { + if (this.drainDisabled) + return; + this.drainDisabled = true; + let objects = this.objects; + let listeners = this.animState.listeners; + for (let i = 0; i < objects.length; i += 2) { + let type = objects[i]; + let entry = objects[i + 1]; + switch (type) { + case EventType.start: + if (entry.listener != null && entry.listener.start) + entry.listener.start(entry); + for (let ii = 0; ii < listeners.length; ii++) + if (listeners[ii].start) + listeners[ii].start(entry); + break; + case EventType.interrupt: + if (entry.listener != null && entry.listener.interrupt) + entry.listener.interrupt(entry); + for (let ii = 0; ii < listeners.length; ii++) + if (listeners[ii].interrupt) + listeners[ii].interrupt(entry); + break; + case EventType.end: + if (entry.listener != null && entry.listener.end) + entry.listener.end(entry); + for (let ii = 0; ii < listeners.length; ii++) + if (listeners[ii].end) + listeners[ii].end(entry); + case EventType.dispose: + if (entry.listener != null && entry.listener.dispose) + entry.listener.dispose(entry); + for (let ii = 0; ii < listeners.length; ii++) + if (listeners[ii].dispose) + listeners[ii].dispose(entry); + this.animState.trackEntryPool.free(entry); + break; + case EventType.complete: + if (entry.listener != null && entry.listener.complete) + entry.listener.complete(entry); + for (let ii = 0; ii < listeners.length; ii++) + if (listeners[ii].complete) + listeners[ii].complete(entry); + break; + case EventType.event: + let event = objects[i++ + 2]; + if (entry.listener != null && entry.listener.event) + entry.listener.event(entry, event); + for (let ii = 0; ii < listeners.length; ii++) + if (listeners[ii].event) + listeners[ii].event(entry, event); + break; + } + } + this.clear(); + this.drainDisabled = false; + } + clear() { + this.objects.length = 0; + } + } + spine.EventQueue = EventQueue; + let EventType; + (function (EventType) { + EventType[EventType["start"] = 0] = "start"; + EventType[EventType["interrupt"] = 1] = "interrupt"; + EventType[EventType["end"] = 2] = "end"; + EventType[EventType["dispose"] = 3] = "dispose"; + EventType[EventType["complete"] = 4] = "complete"; + EventType[EventType["event"] = 5] = "event"; + })(EventType = spine.EventType || (spine.EventType = {})); + class AnimationStateAdapter { + start(entry) { + } + interrupt(entry) { + } + end(entry) { + } + dispose(entry) { + } + complete(entry) { + } + event(entry, event) { + } + } + spine.AnimationStateAdapter = AnimationStateAdapter; +})(spine || (spine = {})); +var spine; +(function (spine) { + class AnimationStateData { + constructor(skeletonData) { + this.animationToMixTime = {}; + this.defaultMix = 0; + if (skeletonData == null) + throw new Error("skeletonData cannot be null."); + this.skeletonData = skeletonData; + } + setMix(fromName, toName, duration) { + let from = this.skeletonData.findAnimation(fromName); + if (from == null) + throw new Error("Animation not found: " + fromName); + let to = this.skeletonData.findAnimation(toName); + if (to == null) + throw new Error("Animation not found: " + toName); + this.setMixWith(from, to, duration); + } + setMixWith(from, to, duration) { + if (from == null) + throw new Error("from cannot be null."); + if (to == null) + throw new Error("to cannot be null."); + let key = from.name + "." + to.name; + this.animationToMixTime[key] = duration; + } + getMix(from, to) { + let key = from.name + "." + to.name; + let value = this.animationToMixTime[key]; + return value === undefined ? this.defaultMix : value; + } + } + spine.AnimationStateData = AnimationStateData; +})(spine || (spine = {})); +var spine; +(function (spine) { + class AssetManager { + constructor(textureLoader, pathPrefix = "") { + this.assets = {}; + this.errors = {}; + this.toLoad = 0; + this.loaded = 0; + this.rawDataUris = {}; + this.textureLoader = textureLoader; + this.pathPrefix = pathPrefix; + } + downloadText(url, success, error) { + // LayaBox_Modify + // let request = new XMLHttpRequest(); + // request.overrideMimeType("text/html"); + // if (this.rawDataUris[url]) + // url = this.rawDataUris[url]; + // request.open("GET", url, true); + // request.onload = () => { + // if (request.status == 200) { + // success(request.responseText); + // } + // else { + // error(request.status, request.responseText); + // } + // }; + // request.onerror = () => { + // error(request.status, request.responseText); + // }; + // request.send(); + let _Laya = Laya.Laya ? Laya.Laya : Laya; + _Laya.loader.load([{type: _Laya.Loader.TEXT, url: url}], _Laya.Handler.create(this, (re) => { + if (re) { + success(_Laya.loader.getRes(url)); + } else { + error("download text error: ", url); + } + })); + } + downloadBinary(url, success, error) { + // LayaBox_Modify + // let request = new XMLHttpRequest(); + // if (this.rawDataUris[url]) + // url = this.rawDataUris[url]; + // request.open("GET", url, true); + // request.responseType = "arraybuffer"; + // request.onload = () => { + // if (request.status == 200) { + // success(new Uint8Array(request.response)); + // } + // else { + // error(request.status, request.responseText); + // } + // }; + // request.onerror = () => { + // error(request.status, request.responseText); + // }; + // request.send(); + let _Laya = Laya.Laya ? Laya.Laya : Laya; + _Laya.loader.load([{type: _Laya.Loader.BUFFER, url: url}], _Laya.Handler.create(this, (re) => { + if (re) { + success(new Uint8Array(_Laya.loader.getRes(url))); + } else { + error("download binary error: ", url); + } + })); + } + setRawDataURI(path, data) { + this.rawDataUris[this.pathPrefix + path] = data; + } + loadBinary(path, success = null, error = null) { + path = this.pathPrefix + path; + this.toLoad++; + this.downloadBinary(path, (data) => { + this.assets[path] = data; + if (success) + success(path, data); + this.toLoad--; + this.loaded++; + }, (status, responseText) => { + this.errors[path] = `Couldn't load binary ${path}: status ${status}, ${responseText}`; + if (error) + error(path, `Couldn't load binary ${path}: status ${status}, ${responseText}`); + this.toLoad--; + this.loaded++; + }); + } + loadText(path, success = null, error = null) { + path = this.pathPrefix + path; + this.toLoad++; + this.downloadText(path, (data) => { + this.assets[path] = data; + if (success) + success(path, data); + this.toLoad--; + this.loaded++; + }, (state, responseText) => { + this.errors[path] = `Couldn't load text ${path}: status ${status}, ${responseText}`; + if (error) + error(path, `Couldn't load text ${path}: status ${status}, ${responseText}`); + this.toLoad--; + this.loaded++; + }); + } + loadTexture(path, success = null, error = null) { + path = this.pathPrefix + path; + let storagePath = path; + this.toLoad++; + // LayaBox_Modify + // let img = new Image(); + // img.crossOrigin = "anonymous"; + // img.onload = (ev) => { + // let texture = this.textureLoader(img); + // this.assets[storagePath] = texture; + // this.toLoad--; + // this.loaded++; + // if (success) + // success(path, img); + // }; + // img.onerror = (ev) => { + // this.errors[path] = `Couldn't load image ${path}`; + // this.toLoad--; + // this.loaded++; + // if (error) + // error(path, `Couldn't load image ${path}`); + // }; + // if (this.rawDataUris[path]) + // path = this.rawDataUris[path]; + // img.src = path; + let _Laya = Laya.Laya ? Laya.Laya : Laya; + _Laya.loader.load([{type: _Laya.Loader.IMAGE, url: path}], _Laya.Handler.create(this, (re) => { + if (re) { + let texture = this.textureLoader(_Laya.loader.getRes(path)); + this.assets[path] = texture; + this.toLoad--; + this.loaded++; + if (success) + success(path, texture); + } else { + this.errors[path] = `Couldn't load text ${path}`; + this.toLoad--; + this.loaded++; + if (error) + error(path, `Couldn't load image ${path}`); + } + })); + } + loadTextureAtlas(path, success = null, error = null) { + let parent = path.lastIndexOf("/") >= 0 ? path.substring(0, path.lastIndexOf("/")) : ""; + path = this.pathPrefix + path; + this.toLoad++; + this.downloadText(path, (atlasData) => { + let pagesLoaded = { count: 0 }; + let atlasPages = new Array(); + try { + let atlas = new spine.TextureAtlas(atlasData, (path) => { + atlasPages.push(parent == "" ? path : parent + "/" + path); + let image = document.createElement("img"); + // LayaBox_Modify + // QQ平台报错,无法设置width height + // image.width = 16; + // image.height = 16; + return new spine.FakeTexture(image); + }); + } + catch (e) { + let ex = e; + this.errors[path] = `Couldn't load texture atlas ${path}: ${ex.message}`; + if (error) + error(path, `Couldn't load texture atlas ${path}: ${ex.message}`); + this.toLoad--; + this.loaded++; + return; + } + for (let atlasPage of atlasPages) { + let pageLoadError = false; + this.loadTexture(atlasPage, (imagePath, image) => { + pagesLoaded.count++; + if (pagesLoaded.count == atlasPages.length) { + if (!pageLoadError) { + try { + let atlas = new spine.TextureAtlas(atlasData, (path) => { + return this.get(parent == "" ? path : parent + "/" + path); + }); + this.assets[path] = atlas; + if (success) + success(path, atlas); + this.toLoad--; + this.loaded++; + } + catch (e) { + let ex = e; + this.errors[path] = `Couldn't load texture atlas ${path}: ${ex.message}`; + if (error) + error(path, `Couldn't load texture atlas ${path}: ${ex.message}`); + this.toLoad--; + this.loaded++; + } + } + else { + this.errors[path] = `Couldn't load texture atlas page ${imagePath}} of atlas ${path}`; + if (error) + error(path, `Couldn't load texture atlas page ${imagePath} of atlas ${path}`); + this.toLoad--; + this.loaded++; + } + } + }, (imagePath, errorMessage) => { + pageLoadError = true; + pagesLoaded.count++; + if (pagesLoaded.count == atlasPages.length) { + this.errors[path] = `Couldn't load texture atlas page ${imagePath}} of atlas ${path}`; + if (error) + error(path, `Couldn't load texture atlas page ${imagePath} of atlas ${path}`); + this.toLoad--; + this.loaded++; + } + }); + } + }, (state, responseText) => { + this.errors[path] = `Couldn't load texture atlas ${path}: status ${status}, ${responseText}`; + if (error) + error(path, `Couldn't load texture atlas ${path}: status ${status}, ${responseText}`); + this.toLoad--; + this.loaded++; + }); + } + get(path) { + path = this.pathPrefix + path; + return this.assets[path]; + } + remove(path) { + path = this.pathPrefix + path; + let asset = this.assets[path]; + if (asset.dispose) + asset.dispose(); + this.assets[path] = null; + } + removeAll() { + for (let key in this.assets) { + let asset = this.assets[key]; + if (asset.dispose) + asset.dispose(); + } + this.assets = {}; + } + isLoadingComplete() { + return this.toLoad == 0; + } + getToLoad() { + return this.toLoad; + } + getLoaded() { + return this.loaded; + } + dispose() { + this.removeAll(); + } + hasErrors() { + return Object.keys(this.errors).length > 0; + } + getErrors() { + return this.errors; + } + } + spine.AssetManager = AssetManager; +})(spine || (spine = {})); +var spine; +(function (spine) { + class AtlasAttachmentLoader { + constructor(atlas) { + this.atlas = atlas; + } + newRegionAttachment(skin, name, path) { + let region = this.atlas.findRegion(path); + if (region == null) + throw new Error("Region not found in atlas: " + path + " (region attachment: " + name + ")"); + region.renderObject = region; + let attachment = new spine.RegionAttachment(name); + attachment.setRegion(region); + return attachment; + } + newMeshAttachment(skin, name, path) { + let region = this.atlas.findRegion(path); + if (region == null) + throw new Error("Region not found in atlas: " + path + " (mesh attachment: " + name + ")"); + region.renderObject = region; + let attachment = new spine.MeshAttachment(name); + attachment.region = region; + return attachment; + } + newBoundingBoxAttachment(skin, name) { + return new spine.BoundingBoxAttachment(name); + } + newPathAttachment(skin, name) { + return new spine.PathAttachment(name); + } + newPointAttachment(skin, name) { + return new spine.PointAttachment(name); + } + newClippingAttachment(skin, name) { + return new spine.ClippingAttachment(name); + } + } + spine.AtlasAttachmentLoader = AtlasAttachmentLoader; +})(spine || (spine = {})); +var spine; +(function (spine) { + let BlendMode; + (function (BlendMode) { + BlendMode[BlendMode["Normal"] = 0] = "Normal"; + BlendMode[BlendMode["Additive"] = 1] = "Additive"; + BlendMode[BlendMode["Multiply"] = 2] = "Multiply"; + BlendMode[BlendMode["Screen"] = 3] = "Screen"; + })(BlendMode = spine.BlendMode || (spine.BlendMode = {})); +})(spine || (spine = {})); +var spine; +(function (spine) { + class Bone { + constructor(data, skeleton, parent) { + this.children = new Array(); + this.x = 0; + this.y = 0; + this.rotation = 0; + this.scaleX = 0; + this.scaleY = 0; + this.shearX = 0; + this.shearY = 0; + this.ax = 0; + this.ay = 0; + this.arotation = 0; + this.ascaleX = 0; + this.ascaleY = 0; + this.ashearX = 0; + this.ashearY = 0; + this.appliedValid = false; + this.a = 0; + this.b = 0; + this.c = 0; + this.d = 0; + this.worldY = 0; + this.worldX = 0; + this.sorted = false; + this.active = false; + if (data == null) + throw new Error("data cannot be null."); + if (skeleton == null) + throw new Error("skeleton cannot be null."); + this.data = data; + this.skeleton = skeleton; + this.parent = parent; + this.setToSetupPose(); + } + isActive() { + return this.active; + } + update() { + this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); + } + updateWorldTransform() { + this.updateWorldTransformWith(this.x, this.y, this.rotation, this.scaleX, this.scaleY, this.shearX, this.shearY); + } + updateWorldTransformWith(x, y, rotation, scaleX, scaleY, shearX, shearY) { + this.ax = x; + this.ay = y; + this.arotation = rotation; + this.ascaleX = scaleX; + this.ascaleY = scaleY; + this.ashearX = shearX; + this.ashearY = shearY; + this.appliedValid = true; + let parent = this.parent; + if (parent == null) { + let skeleton = this.skeleton; + let rotationY = rotation + 90 + shearY; + let sx = skeleton.scaleX; + let sy = skeleton.scaleY; + this.a = spine.MathUtils.cosDeg(rotation + shearX) * scaleX * sx; + this.b = spine.MathUtils.cosDeg(rotationY) * scaleY * sx; + this.c = spine.MathUtils.sinDeg(rotation + shearX) * scaleX * sy; + this.d = spine.MathUtils.sinDeg(rotationY) * scaleY * sy; + this.worldX = x * sx + skeleton.x; + this.worldY = y * sy + skeleton.y; + return; + } + let pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d; + this.worldX = pa * x + pb * y + parent.worldX; + this.worldY = pc * x + pd * y + parent.worldY; + switch (this.data.transformMode) { + case spine.TransformMode.Normal: { + let rotationY = rotation + 90 + shearY; + let la = spine.MathUtils.cosDeg(rotation + shearX) * scaleX; + let lb = spine.MathUtils.cosDeg(rotationY) * scaleY; + let lc = spine.MathUtils.sinDeg(rotation + shearX) * scaleX; + let ld = spine.MathUtils.sinDeg(rotationY) * scaleY; + this.a = pa * la + pb * lc; + this.b = pa * lb + pb * ld; + this.c = pc * la + pd * lc; + this.d = pc * lb + pd * ld; + return; + } + case spine.TransformMode.OnlyTranslation: { + let rotationY = rotation + 90 + shearY; + this.a = spine.MathUtils.cosDeg(rotation + shearX) * scaleX; + this.b = spine.MathUtils.cosDeg(rotationY) * scaleY; + this.c = spine.MathUtils.sinDeg(rotation + shearX) * scaleX; + this.d = spine.MathUtils.sinDeg(rotationY) * scaleY; + break; + } + case spine.TransformMode.NoRotationOrReflection: { + let s = pa * pa + pc * pc; + let prx = 0; + if (s > 0.0001) { + s = Math.abs(pa * pd - pb * pc) / s; + pb = pc * s; + pd = pa * s; + prx = Math.atan2(pc, pa) * spine.MathUtils.radDeg; + } + else { + pa = 0; + pc = 0; + prx = 90 - Math.atan2(pd, pb) * spine.MathUtils.radDeg; + } + let rx = rotation + shearX - prx; + let ry = rotation + shearY - prx + 90; + let la = spine.MathUtils.cosDeg(rx) * scaleX; + let lb = spine.MathUtils.cosDeg(ry) * scaleY; + let lc = spine.MathUtils.sinDeg(rx) * scaleX; + let ld = spine.MathUtils.sinDeg(ry) * scaleY; + this.a = pa * la - pb * lc; + this.b = pa * lb - pb * ld; + this.c = pc * la + pd * lc; + this.d = pc * lb + pd * ld; + return; + } + case spine.TransformMode.NoScale: + case spine.TransformMode.NoScaleOrReflection: { + let cos = spine.MathUtils.cosDeg(rotation); + let sin = spine.MathUtils.sinDeg(rotation); + let za = (pa * cos + pb * sin) / this.skeleton.scaleX; + let zc = (pc * cos + pd * sin) / this.skeleton.scaleY; + let s = Math.sqrt(za * za + zc * zc); + if (s > 0.00001) + s = 1 / s; + za *= s; + zc *= s; + s = Math.sqrt(za * za + zc * zc); + if (this.data.transformMode == spine.TransformMode.NoScale + && (pa * pd - pb * pc < 0) != (this.skeleton.scaleX < 0 != this.skeleton.scaleY < 0)) + s = -s; + let r = Math.PI / 2 + Math.atan2(zc, za); + let zb = Math.cos(r) * s; + let zd = Math.sin(r) * s; + let la = spine.MathUtils.cosDeg(shearX) * scaleX; + let lb = spine.MathUtils.cosDeg(90 + shearY) * scaleY; + let lc = spine.MathUtils.sinDeg(shearX) * scaleX; + let ld = spine.MathUtils.sinDeg(90 + shearY) * scaleY; + this.a = za * la + zb * lc; + this.b = za * lb + zb * ld; + this.c = zc * la + zd * lc; + this.d = zc * lb + zd * ld; + break; + } + } + this.a *= this.skeleton.scaleX; + this.b *= this.skeleton.scaleX; + this.c *= this.skeleton.scaleY; + this.d *= this.skeleton.scaleY; + } + setToSetupPose() { + let data = this.data; + this.x = data.x; + this.y = data.y; + this.rotation = data.rotation; + this.scaleX = data.scaleX; + this.scaleY = data.scaleY; + this.shearX = data.shearX; + this.shearY = data.shearY; + } + getWorldRotationX() { + return Math.atan2(this.c, this.a) * spine.MathUtils.radDeg; + } + getWorldRotationY() { + return Math.atan2(this.d, this.b) * spine.MathUtils.radDeg; + } + getWorldScaleX() { + return Math.sqrt(this.a * this.a + this.c * this.c); + } + getWorldScaleY() { + return Math.sqrt(this.b * this.b + this.d * this.d); + } + updateAppliedTransform() { + this.appliedValid = true; + let parent = this.parent; + if (parent == null) { + this.ax = this.worldX; + this.ay = this.worldY; + this.arotation = Math.atan2(this.c, this.a) * spine.MathUtils.radDeg; + this.ascaleX = Math.sqrt(this.a * this.a + this.c * this.c); + this.ascaleY = Math.sqrt(this.b * this.b + this.d * this.d); + this.ashearX = 0; + this.ashearY = Math.atan2(this.a * this.b + this.c * this.d, this.a * this.d - this.b * this.c) * spine.MathUtils.radDeg; + return; + } + let pa = parent.a, pb = parent.b, pc = parent.c, pd = parent.d; + let pid = 1 / (pa * pd - pb * pc); + let dx = this.worldX - parent.worldX, dy = this.worldY - parent.worldY; + this.ax = (dx * pd * pid - dy * pb * pid); + this.ay = (dy * pa * pid - dx * pc * pid); + let ia = pid * pd; + let id = pid * pa; + let ib = pid * pb; + let ic = pid * pc; + let ra = ia * this.a - ib * this.c; + let rb = ia * this.b - ib * this.d; + let rc = id * this.c - ic * this.a; + let rd = id * this.d - ic * this.b; + this.ashearX = 0; + this.ascaleX = Math.sqrt(ra * ra + rc * rc); + if (this.ascaleX > 0.0001) { + let det = ra * rd - rb * rc; + this.ascaleY = det / this.ascaleX; + this.ashearY = Math.atan2(ra * rb + rc * rd, det) * spine.MathUtils.radDeg; + this.arotation = Math.atan2(rc, ra) * spine.MathUtils.radDeg; + } + else { + this.ascaleX = 0; + this.ascaleY = Math.sqrt(rb * rb + rd * rd); + this.ashearY = 0; + this.arotation = 90 - Math.atan2(rd, rb) * spine.MathUtils.radDeg; + } + } + worldToLocal(world) { + let a = this.a, b = this.b, c = this.c, d = this.d; + let invDet = 1 / (a * d - b * c); + let x = world.x - this.worldX, y = world.y - this.worldY; + world.x = (x * d * invDet - y * b * invDet); + world.y = (y * a * invDet - x * c * invDet); + return world; + } + localToWorld(local) { + let x = local.x, y = local.y; + local.x = x * this.a + y * this.b + this.worldX; + local.y = x * this.c + y * this.d + this.worldY; + return local; + } + worldToLocalRotation(worldRotation) { + let sin = spine.MathUtils.sinDeg(worldRotation), cos = spine.MathUtils.cosDeg(worldRotation); + return Math.atan2(this.a * sin - this.c * cos, this.d * cos - this.b * sin) * spine.MathUtils.radDeg + this.rotation - this.shearX; + } + localToWorldRotation(localRotation) { + localRotation -= this.rotation - this.shearX; + let sin = spine.MathUtils.sinDeg(localRotation), cos = spine.MathUtils.cosDeg(localRotation); + return Math.atan2(cos * this.c + sin * this.d, cos * this.a + sin * this.b) * spine.MathUtils.radDeg; + } + rotateWorld(degrees) { + let a = this.a, b = this.b, c = this.c, d = this.d; + let cos = spine.MathUtils.cosDeg(degrees), sin = spine.MathUtils.sinDeg(degrees); + this.a = cos * a - sin * c; + this.b = cos * b - sin * d; + this.c = sin * a + cos * c; + this.d = sin * b + cos * d; + this.appliedValid = false; + } + } + spine.Bone = Bone; +})(spine || (spine = {})); +var spine; +(function (spine) { + class BoneData { + constructor(index, name, parent) { + this.x = 0; + this.y = 0; + this.rotation = 0; + this.scaleX = 1; + this.scaleY = 1; + this.shearX = 0; + this.shearY = 0; + this.transformMode = TransformMode.Normal; + this.skinRequired = false; + this.color = new spine.Color(); + if (index < 0) + throw new Error("index must be >= 0."); + if (name == null) + throw new Error("name cannot be null."); + this.index = index; + this.name = name; + this.parent = parent; + } + } + spine.BoneData = BoneData; + let TransformMode; + (function (TransformMode) { + TransformMode[TransformMode["Normal"] = 0] = "Normal"; + TransformMode[TransformMode["OnlyTranslation"] = 1] = "OnlyTranslation"; + TransformMode[TransformMode["NoRotationOrReflection"] = 2] = "NoRotationOrReflection"; + TransformMode[TransformMode["NoScale"] = 3] = "NoScale"; + TransformMode[TransformMode["NoScaleOrReflection"] = 4] = "NoScaleOrReflection"; + })(TransformMode = spine.TransformMode || (spine.TransformMode = {})); +})(spine || (spine = {})); +var spine; +(function (spine) { + class ConstraintData { + constructor(name, order, skinRequired) { + this.name = name; + this.order = order; + this.skinRequired = skinRequired; + } + } + spine.ConstraintData = ConstraintData; +})(spine || (spine = {})); +var spine; +(function (spine) { + class Event { + constructor(time, data) { + if (data == null) + throw new Error("data cannot be null."); + this.time = time; + this.data = data; + } + } + spine.Event = Event; +})(spine || (spine = {})); +var spine; +(function (spine) { + class EventData { + constructor(name) { + this.name = name; + } + } + spine.EventData = EventData; +})(spine || (spine = {})); +var spine; +(function (spine) { + class IkConstraint { + constructor(data, skeleton) { + this.bendDirection = 0; + this.compress = false; + this.stretch = false; + this.mix = 1; + this.softness = 0; + this.active = false; + if (data == null) + throw new Error("data cannot be null."); + if (skeleton == null) + throw new Error("skeleton cannot be null."); + this.data = data; + this.mix = data.mix; + this.softness = data.softness; + this.bendDirection = data.bendDirection; + this.compress = data.compress; + this.stretch = data.stretch; + this.bones = new Array(); + for (let i = 0; i < data.bones.length; i++) + this.bones.push(skeleton.findBone(data.bones[i].name)); + this.target = skeleton.findBone(data.target.name); + } + isActive() { + return this.active; + } + apply() { + this.update(); + } + update() { + let target = this.target; + let bones = this.bones; + switch (bones.length) { + case 1: + this.apply1(bones[0], target.worldX, target.worldY, this.compress, this.stretch, this.data.uniform, this.mix); + break; + case 2: + this.apply2(bones[0], bones[1], target.worldX, target.worldY, this.bendDirection, this.stretch, this.softness, this.mix); + break; + } + } + apply1(bone, targetX, targetY, compress, stretch, uniform, alpha) { + if (!bone.appliedValid) + bone.updateAppliedTransform(); + let p = bone.parent; + let pa = p.a, pb = p.b, pc = p.c, pd = p.d; + let rotationIK = -bone.ashearX - bone.arotation, tx = 0, ty = 0; + switch (bone.data.transformMode) { + case spine.TransformMode.OnlyTranslation: + tx = targetX - bone.worldX; + ty = targetY - bone.worldY; + break; + case spine.TransformMode.NoRotationOrReflection: + rotationIK += Math.atan2(pc, pa) * spine.MathUtils.radDeg; + let ps = Math.abs(pa * pd - pb * pc) / (pa * pa + pc * pc); + pb = -pc * ps; + pd = pa * ps; + default: + let x = targetX - p.worldX, y = targetY - p.worldY; + let d = pa * pd - pb * pc; + tx = (x * pd - y * pb) / d - bone.ax; + ty = (y * pa - x * pc) / d - bone.ay; + } + rotationIK += Math.atan2(ty, tx) * spine.MathUtils.radDeg; + if (bone.ascaleX < 0) + rotationIK += 180; + if (rotationIK > 180) + rotationIK -= 360; + else if (rotationIK < -180) + rotationIK += 360; + let sx = bone.ascaleX, sy = bone.ascaleY; + if (compress || stretch) { + switch (bone.data.transformMode) { + case spine.TransformMode.NoScale: + case spine.TransformMode.NoScaleOrReflection: + tx = targetX - bone.worldX; + ty = targetY - bone.worldY; + } + let b = bone.data.length * sx, dd = Math.sqrt(tx * tx + ty * ty); + if ((compress && dd < b) || (stretch && dd > b) && b > 0.0001) { + let s = (dd / b - 1) * alpha + 1; + sx *= s; + if (uniform) + sy *= s; + } + } + bone.updateWorldTransformWith(bone.ax, bone.ay, bone.arotation + rotationIK * alpha, sx, sy, bone.ashearX, bone.ashearY); + } + apply2(parent, child, targetX, targetY, bendDir, stretch, softness, alpha) { + if (alpha == 0) { + child.updateWorldTransform(); + return; + } + if (!parent.appliedValid) + parent.updateAppliedTransform(); + if (!child.appliedValid) + child.updateAppliedTransform(); + let px = parent.ax, py = parent.ay, psx = parent.ascaleX, sx = psx, psy = parent.ascaleY, csx = child.ascaleX; + let os1 = 0, os2 = 0, s2 = 0; + if (psx < 0) { + psx = -psx; + os1 = 180; + s2 = -1; + } + else { + os1 = 0; + s2 = 1; + } + if (psy < 0) { + psy = -psy; + s2 = -s2; + } + if (csx < 0) { + csx = -csx; + os2 = 180; + } + else + os2 = 0; + let cx = child.ax, cy = 0, cwx = 0, cwy = 0, a = parent.a, b = parent.b, c = parent.c, d = parent.d; + let u = Math.abs(psx - psy) <= 0.0001; + if (!u) { + cy = 0; + cwx = a * cx + parent.worldX; + cwy = c * cx + parent.worldY; + } + else { + cy = child.ay; + cwx = a * cx + b * cy + parent.worldX; + cwy = c * cx + d * cy + parent.worldY; + } + let pp = parent.parent; + a = pp.a; + b = pp.b; + c = pp.c; + d = pp.d; + let id = 1 / (a * d - b * c), x = cwx - pp.worldX, y = cwy - pp.worldY; + let dx = (x * d - y * b) * id - px, dy = (y * a - x * c) * id - py; + let l1 = Math.sqrt(dx * dx + dy * dy), l2 = child.data.length * csx, a1, a2; + if (l1 < 0.0001) { + this.apply1(parent, targetX, targetY, false, stretch, false, alpha); + child.updateWorldTransformWith(cx, cy, 0, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); + return; + } + x = targetX - pp.worldX; + y = targetY - pp.worldY; + let tx = (x * d - y * b) * id - px, ty = (y * a - x * c) * id - py; + let dd = tx * tx + ty * ty; + if (softness != 0) { + softness *= psx * (csx + 1) / 2; + let td = Math.sqrt(dd), sd = td - l1 - l2 * psx + softness; + if (sd > 0) { + let p = Math.min(1, sd / (softness * 2)) - 1; + p = (sd - softness * (1 - p * p)) / td; + tx -= p * tx; + ty -= p * ty; + dd = tx * tx + ty * ty; + } + } + outer: if (u) { + l2 *= psx; + let cos = (dd - l1 * l1 - l2 * l2) / (2 * l1 * l2); + if (cos < -1) + cos = -1; + else if (cos > 1) { + cos = 1; + if (stretch) + sx *= (Math.sqrt(dd) / (l1 + l2) - 1) * alpha + 1; + } + a2 = Math.acos(cos) * bendDir; + a = l1 + l2 * cos; + b = l2 * Math.sin(a2); + a1 = Math.atan2(ty * a - tx * b, tx * a + ty * b); + } + else { + a = psx * l2; + b = psy * l2; + let aa = a * a, bb = b * b, ta = Math.atan2(ty, tx); + c = bb * l1 * l1 + aa * dd - aa * bb; + let c1 = -2 * bb * l1, c2 = bb - aa; + d = c1 * c1 - 4 * c2 * c; + if (d >= 0) { + let q = Math.sqrt(d); + if (c1 < 0) + q = -q; + q = -(c1 + q) / 2; + let r0 = q / c2, r1 = c / q; + let r = Math.abs(r0) < Math.abs(r1) ? r0 : r1; + if (r * r <= dd) { + y = Math.sqrt(dd - r * r) * bendDir; + a1 = ta - Math.atan2(y, r); + a2 = Math.atan2(y / psy, (r - l1) / psx); + break outer; + } + } + let minAngle = spine.MathUtils.PI, minX = l1 - a, minDist = minX * minX, minY = 0; + let maxAngle = 0, maxX = l1 + a, maxDist = maxX * maxX, maxY = 0; + c = -a * l1 / (aa - bb); + if (c >= -1 && c <= 1) { + c = Math.acos(c); + x = a * Math.cos(c) + l1; + y = b * Math.sin(c); + d = x * x + y * y; + if (d < minDist) { + minAngle = c; + minDist = d; + minX = x; + minY = y; + } + if (d > maxDist) { + maxAngle = c; + maxDist = d; + maxX = x; + maxY = y; + } + } + if (dd <= (minDist + maxDist) / 2) { + a1 = ta - Math.atan2(minY * bendDir, minX); + a2 = minAngle * bendDir; + } + else { + a1 = ta - Math.atan2(maxY * bendDir, maxX); + a2 = maxAngle * bendDir; + } + } + let os = Math.atan2(cy, cx) * s2; + let rotation = parent.arotation; + a1 = (a1 - os) * spine.MathUtils.radDeg + os1 - rotation; + if (a1 > 180) + a1 -= 360; + else if (a1 < -180) + a1 += 360; + parent.updateWorldTransformWith(px, py, rotation + a1 * alpha, sx, parent.ascaleY, 0, 0); + rotation = child.arotation; + a2 = ((a2 + os) * spine.MathUtils.radDeg - child.ashearX) * s2 + os2 - rotation; + if (a2 > 180) + a2 -= 360; + else if (a2 < -180) + a2 += 360; + child.updateWorldTransformWith(cx, cy, rotation + a2 * alpha, child.ascaleX, child.ascaleY, child.ashearX, child.ashearY); + } + } + spine.IkConstraint = IkConstraint; +})(spine || (spine = {})); +var spine; +(function (spine) { + class IkConstraintData extends spine.ConstraintData { + constructor(name) { + super(name, 0, false); + this.bones = new Array(); + this.bendDirection = 1; + this.compress = false; + this.stretch = false; + this.uniform = false; + this.mix = 1; + this.softness = 0; + } + } + spine.IkConstraintData = IkConstraintData; +})(spine || (spine = {})); +var spine; +(function (spine) { + class PathConstraint { + constructor(data, skeleton) { + this.position = 0; + this.spacing = 0; + this.rotateMix = 0; + this.translateMix = 0; + this.spaces = new Array(); + this.positions = new Array(); + this.world = new Array(); + this.curves = new Array(); + this.lengths = new Array(); + this.segments = new Array(); + this.active = false; + if (data == null) + throw new Error("data cannot be null."); + if (skeleton == null) + throw new Error("skeleton cannot be null."); + this.data = data; + this.bones = new Array(); + for (let i = 0, n = data.bones.length; i < n; i++) + this.bones.push(skeleton.findBone(data.bones[i].name)); + this.target = skeleton.findSlot(data.target.name); + this.position = data.position; + this.spacing = data.spacing; + this.rotateMix = data.rotateMix; + this.translateMix = data.translateMix; + } + isActive() { + return this.active; + } + apply() { + this.update(); + } + update() { + let attachment = this.target.getAttachment(); + if (!(attachment instanceof spine.PathAttachment)) + return; + let rotateMix = this.rotateMix, translateMix = this.translateMix; + let translate = translateMix > 0, rotate = rotateMix > 0; + if (!translate && !rotate) + return; + let data = this.data; + let percentSpacing = data.spacingMode == spine.SpacingMode.Percent; + let rotateMode = data.rotateMode; + let tangents = rotateMode == spine.RotateMode.Tangent, scale = rotateMode == spine.RotateMode.ChainScale; + let boneCount = this.bones.length, spacesCount = tangents ? boneCount : boneCount + 1; + let bones = this.bones; + let spaces = spine.Utils.setArraySize(this.spaces, spacesCount), lengths = null; + let spacing = this.spacing; + if (scale || !percentSpacing) { + if (scale) + lengths = spine.Utils.setArraySize(this.lengths, boneCount); + let lengthSpacing = data.spacingMode == spine.SpacingMode.Length; + for (let i = 0, n = spacesCount - 1; i < n;) { + let bone = bones[i]; + let setupLength = bone.data.length; + if (setupLength < PathConstraint.epsilon) { + if (scale) + lengths[i] = 0; + spaces[++i] = 0; + } + else if (percentSpacing) { + if (scale) { + let x = setupLength * bone.a, y = setupLength * bone.c; + let length = Math.sqrt(x * x + y * y); + lengths[i] = length; + } + spaces[++i] = spacing; + } + else { + let x = setupLength * bone.a, y = setupLength * bone.c; + let length = Math.sqrt(x * x + y * y); + if (scale) + lengths[i] = length; + spaces[++i] = (lengthSpacing ? setupLength + spacing : spacing) * length / setupLength; + } + } + } + else { + for (let i = 1; i < spacesCount; i++) + spaces[i] = spacing; + } + let positions = this.computeWorldPositions(attachment, spacesCount, tangents, data.positionMode == spine.PositionMode.Percent, percentSpacing); + let boneX = positions[0], boneY = positions[1], offsetRotation = data.offsetRotation; + let tip = false; + if (offsetRotation == 0) + tip = rotateMode == spine.RotateMode.Chain; + else { + tip = false; + let p = this.target.bone; + offsetRotation *= p.a * p.d - p.b * p.c > 0 ? spine.MathUtils.degRad : -spine.MathUtils.degRad; + } + for (let i = 0, p = 3; i < boneCount; i++, p += 3) { + let bone = bones[i]; + bone.worldX += (boneX - bone.worldX) * translateMix; + bone.worldY += (boneY - bone.worldY) * translateMix; + let x = positions[p], y = positions[p + 1], dx = x - boneX, dy = y - boneY; + if (scale) { + let length = lengths[i]; + if (length != 0) { + let s = (Math.sqrt(dx * dx + dy * dy) / length - 1) * rotateMix + 1; + bone.a *= s; + bone.c *= s; + } + } + boneX = x; + boneY = y; + if (rotate) { + let a = bone.a, b = bone.b, c = bone.c, d = bone.d, r = 0, cos = 0, sin = 0; + if (tangents) + r = positions[p - 1]; + else if (spaces[i + 1] == 0) + r = positions[p + 2]; + else + r = Math.atan2(dy, dx); + r -= Math.atan2(c, a); + if (tip) { + cos = Math.cos(r); + sin = Math.sin(r); + let length = bone.data.length; + boneX += (length * (cos * a - sin * c) - dx) * rotateMix; + boneY += (length * (sin * a + cos * c) - dy) * rotateMix; + } + else { + r += offsetRotation; + } + if (r > spine.MathUtils.PI) + r -= spine.MathUtils.PI2; + else if (r < -spine.MathUtils.PI) + r += spine.MathUtils.PI2; + r *= rotateMix; + cos = Math.cos(r); + sin = Math.sin(r); + bone.a = cos * a - sin * c; + bone.b = cos * b - sin * d; + bone.c = sin * a + cos * c; + bone.d = sin * b + cos * d; + } + bone.appliedValid = false; + } + } + computeWorldPositions(path, spacesCount, tangents, percentPosition, percentSpacing) { + let target = this.target; + let position = this.position; + let spaces = this.spaces, out = spine.Utils.setArraySize(this.positions, spacesCount * 3 + 2), world = null; + let closed = path.closed; + let verticesLength = path.worldVerticesLength, curveCount = verticesLength / 6, prevCurve = PathConstraint.NONE; + if (!path.constantSpeed) { + let lengths = path.lengths; + curveCount -= closed ? 1 : 2; + let pathLength = lengths[curveCount]; + if (percentPosition) + position *= pathLength; + if (percentSpacing) { + for (let i = 1; i < spacesCount; i++) + spaces[i] *= pathLength; + } + world = spine.Utils.setArraySize(this.world, 8); + for (let i = 0, o = 0, curve = 0; i < spacesCount; i++, o += 3) { + let space = spaces[i]; + position += space; + let p = position; + if (closed) { + p %= pathLength; + if (p < 0) + p += pathLength; + curve = 0; + } + else if (p < 0) { + if (prevCurve != PathConstraint.BEFORE) { + prevCurve = PathConstraint.BEFORE; + path.computeWorldVertices(target, 2, 4, world, 0, 2); + } + this.addBeforePosition(p, world, 0, out, o); + continue; + } + else if (p > pathLength) { + if (prevCurve != PathConstraint.AFTER) { + prevCurve = PathConstraint.AFTER; + path.computeWorldVertices(target, verticesLength - 6, 4, world, 0, 2); + } + this.addAfterPosition(p - pathLength, world, 0, out, o); + continue; + } + for (;; curve++) { + let length = lengths[curve]; + if (p > length) + continue; + if (curve == 0) + p /= length; + else { + let prev = lengths[curve - 1]; + p = (p - prev) / (length - prev); + } + break; + } + if (curve != prevCurve) { + prevCurve = curve; + if (closed && curve == curveCount) { + path.computeWorldVertices(target, verticesLength - 4, 4, world, 0, 2); + path.computeWorldVertices(target, 0, 4, world, 4, 2); + } + else + path.computeWorldVertices(target, curve * 6 + 2, 8, world, 0, 2); + } + this.addCurvePosition(p, world[0], world[1], world[2], world[3], world[4], world[5], world[6], world[7], out, o, tangents || (i > 0 && space == 0)); + } + return out; + } + if (closed) { + verticesLength += 2; + world = spine.Utils.setArraySize(this.world, verticesLength); + path.computeWorldVertices(target, 2, verticesLength - 4, world, 0, 2); + path.computeWorldVertices(target, 0, 2, world, verticesLength - 4, 2); + world[verticesLength - 2] = world[0]; + world[verticesLength - 1] = world[1]; + } + else { + curveCount--; + verticesLength -= 4; + world = spine.Utils.setArraySize(this.world, verticesLength); + path.computeWorldVertices(target, 2, verticesLength, world, 0, 2); + } + let curves = spine.Utils.setArraySize(this.curves, curveCount); + let pathLength = 0; + let x1 = world[0], y1 = world[1], cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0; + let tmpx = 0, tmpy = 0, dddfx = 0, dddfy = 0, ddfx = 0, ddfy = 0, dfx = 0, dfy = 0; + for (let i = 0, w = 2; i < curveCount; i++, w += 6) { + cx1 = world[w]; + cy1 = world[w + 1]; + cx2 = world[w + 2]; + cy2 = world[w + 3]; + x2 = world[w + 4]; + y2 = world[w + 5]; + tmpx = (x1 - cx1 * 2 + cx2) * 0.1875; + tmpy = (y1 - cy1 * 2 + cy2) * 0.1875; + dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375; + dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375; + ddfx = tmpx * 2 + dddfx; + ddfy = tmpy * 2 + dddfy; + dfx = (cx1 - x1) * 0.75 + tmpx + dddfx * 0.16666667; + dfy = (cy1 - y1) * 0.75 + tmpy + dddfy * 0.16666667; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx; + dfy += ddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + dfx += ddfx + dddfx; + dfy += ddfy + dddfy; + pathLength += Math.sqrt(dfx * dfx + dfy * dfy); + curves[i] = pathLength; + x1 = x2; + y1 = y2; + } + if (percentPosition) + position *= pathLength; + else + position *= pathLength / path.lengths[curveCount - 1]; + if (percentSpacing) { + for (let i = 1; i < spacesCount; i++) + spaces[i] *= pathLength; + } + let segments = this.segments; + let curveLength = 0; + for (let i = 0, o = 0, curve = 0, segment = 0; i < spacesCount; i++, o += 3) { + let space = spaces[i]; + position += space; + let p = position; + if (closed) { + p %= pathLength; + if (p < 0) + p += pathLength; + curve = 0; + } + else if (p < 0) { + this.addBeforePosition(p, world, 0, out, o); + continue; + } + else if (p > pathLength) { + this.addAfterPosition(p - pathLength, world, verticesLength - 4, out, o); + continue; + } + for (;; curve++) { + let length = curves[curve]; + if (p > length) + continue; + if (curve == 0) + p /= length; + else { + let prev = curves[curve - 1]; + p = (p - prev) / (length - prev); + } + break; + } + if (curve != prevCurve) { + prevCurve = curve; + let ii = curve * 6; + x1 = world[ii]; + y1 = world[ii + 1]; + cx1 = world[ii + 2]; + cy1 = world[ii + 3]; + cx2 = world[ii + 4]; + cy2 = world[ii + 5]; + x2 = world[ii + 6]; + y2 = world[ii + 7]; + tmpx = (x1 - cx1 * 2 + cx2) * 0.03; + tmpy = (y1 - cy1 * 2 + cy2) * 0.03; + dddfx = ((cx1 - cx2) * 3 - x1 + x2) * 0.006; + dddfy = ((cy1 - cy2) * 3 - y1 + y2) * 0.006; + ddfx = tmpx * 2 + dddfx; + ddfy = tmpy * 2 + dddfy; + dfx = (cx1 - x1) * 0.3 + tmpx + dddfx * 0.16666667; + dfy = (cy1 - y1) * 0.3 + tmpy + dddfy * 0.16666667; + curveLength = Math.sqrt(dfx * dfx + dfy * dfy); + segments[0] = curveLength; + for (ii = 1; ii < 8; ii++) { + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[ii] = curveLength; + } + dfx += ddfx; + dfy += ddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[8] = curveLength; + dfx += ddfx + dddfx; + dfy += ddfy + dddfy; + curveLength += Math.sqrt(dfx * dfx + dfy * dfy); + segments[9] = curveLength; + segment = 0; + } + p *= curveLength; + for (;; segment++) { + let length = segments[segment]; + if (p > length) + continue; + if (segment == 0) + p /= length; + else { + let prev = segments[segment - 1]; + p = segment + (p - prev) / (length - prev); + } + break; + } + this.addCurvePosition(p * 0.1, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents || (i > 0 && space == 0)); + } + return out; + } + addBeforePosition(p, temp, i, out, o) { + let x1 = temp[i], y1 = temp[i + 1], dx = temp[i + 2] - x1, dy = temp[i + 3] - y1, r = Math.atan2(dy, dx); + out[o] = x1 + p * Math.cos(r); + out[o + 1] = y1 + p * Math.sin(r); + out[o + 2] = r; + } + addAfterPosition(p, temp, i, out, o) { + let x1 = temp[i + 2], y1 = temp[i + 3], dx = x1 - temp[i], dy = y1 - temp[i + 1], r = Math.atan2(dy, dx); + out[o] = x1 + p * Math.cos(r); + out[o + 1] = y1 + p * Math.sin(r); + out[o + 2] = r; + } + addCurvePosition(p, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, tangents) { + if (p == 0 || isNaN(p)) { + out[o] = x1; + out[o + 1] = y1; + out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1); + return; + } + let tt = p * p, ttt = tt * p, u = 1 - p, uu = u * u, uuu = uu * u; + let ut = u * p, ut3 = ut * 3, uut3 = u * ut3, utt3 = ut3 * p; + let x = x1 * uuu + cx1 * uut3 + cx2 * utt3 + x2 * ttt, y = y1 * uuu + cy1 * uut3 + cy2 * utt3 + y2 * ttt; + out[o] = x; + out[o + 1] = y; + if (tangents) { + if (p < 0.001) + out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1); + else + out[o + 2] = Math.atan2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt)); + } + } + } + PathConstraint.NONE = -1; + PathConstraint.BEFORE = -2; + PathConstraint.AFTER = -3; + PathConstraint.epsilon = 0.00001; + spine.PathConstraint = PathConstraint; +})(spine || (spine = {})); +var spine; +(function (spine) { + class PathConstraintData extends spine.ConstraintData { + constructor(name) { + super(name, 0, false); + this.bones = new Array(); + } + } + spine.PathConstraintData = PathConstraintData; + let PositionMode; + (function (PositionMode) { + PositionMode[PositionMode["Fixed"] = 0] = "Fixed"; + PositionMode[PositionMode["Percent"] = 1] = "Percent"; + })(PositionMode = spine.PositionMode || (spine.PositionMode = {})); + let SpacingMode; + (function (SpacingMode) { + SpacingMode[SpacingMode["Length"] = 0] = "Length"; + SpacingMode[SpacingMode["Fixed"] = 1] = "Fixed"; + SpacingMode[SpacingMode["Percent"] = 2] = "Percent"; + })(SpacingMode = spine.SpacingMode || (spine.SpacingMode = {})); + let RotateMode; + (function (RotateMode) { + RotateMode[RotateMode["Tangent"] = 0] = "Tangent"; + RotateMode[RotateMode["Chain"] = 1] = "Chain"; + RotateMode[RotateMode["ChainScale"] = 2] = "ChainScale"; + })(RotateMode = spine.RotateMode || (spine.RotateMode = {})); +})(spine || (spine = {})); +var spine; +(function (spine) { + class Assets { + constructor(clientId) { + this.toLoad = new Array(); + this.assets = {}; + this.clientId = clientId; + } + loaded() { + let i = 0; + for (let v in this.assets) + i++; + return i; + } + } + class SharedAssetManager { + constructor(pathPrefix = "") { + this.clientAssets = {}; + this.queuedAssets = {}; + this.rawAssets = {}; + this.errors = {}; + this.pathPrefix = pathPrefix; + } + queueAsset(clientId, textureLoader, path) { + let clientAssets = this.clientAssets[clientId]; + if (clientAssets === null || clientAssets === undefined) { + clientAssets = new Assets(clientId); + this.clientAssets[clientId] = clientAssets; + } + if (textureLoader !== null) + clientAssets.textureLoader = textureLoader; + clientAssets.toLoad.push(path); + if (this.queuedAssets[path] === path) { + return false; + } + else { + this.queuedAssets[path] = path; + return true; + } + } + loadText(clientId, path) { + path = this.pathPrefix + path; + if (!this.queueAsset(clientId, null, path)) + return; + // LayaBox_Modify + // let request = new XMLHttpRequest(); + // request.overrideMimeType("text/html"); + // request.onreadystatechange = () => { + // if (request.readyState == XMLHttpRequest.DONE) { + // if (request.status >= 200 && request.status < 300) { + // this.rawAssets[path] = request.responseText; + // } + // else { + // this.errors[path] = `Couldn't load text ${path}: status ${request.status}, ${request.responseText}`; + // } + // } + // }; + // request.open("GET", path, true); + // request.send(); + let _Laya = Laya.Laya ? Laya.Laya : Laya; + _Laya.loader.load([{type: _Laya.Loader.TEXT, url: path}], _Laya.Handler.create(this, (re) => { + if (re) { + this.rawAssets[path] = _Laya.loader.getRes(path); + } else { + this.errors[path] = `Couldn't load text ${path}`; + } + })); + } + loadJson(clientId, path) { + path = this.pathPrefix + path; + if (!this.queueAsset(clientId, null, path)) + return; + // LayaBox_Modify + // let request = new XMLHttpRequest(); + // request.overrideMimeType("text/html"); + // request.onreadystatechange = () => { + // if (request.readyState == XMLHttpRequest.DONE) { + // if (request.status >= 200 && request.status < 300) { + // this.rawAssets[path] = JSON.parse(request.responseText); + // } + // else { + // this.errors[path] = `Couldn't load text ${path}: status ${request.status}, ${request.responseText}`; + // } + // } + // }; + // request.open("GET", path, true); + // request.send(); + let _Laya = Laya.Laya ? Laya.Laya : Laya; + _Laya.loader.load([{type: _Laya.Loader.JSON, url: path}], _Laya.Handler.create(this, (re) => { + if (re) { + this.rawAssets[path] = _Laya.loader.getRes(path); + } else { + this.errors[path] = `Couldn't load text ${path}`; + } + })); + } + loadTexture(clientId, textureLoader, path) { + path = this.pathPrefix + path; + if (!this.queueAsset(clientId, textureLoader, path)) + return; + // LayaBox_Modify + // let img = new Image(); + // img.crossOrigin = "anonymous"; + // img.onload = (ev) => { + // this.rawAssets[path] = img; + // }; + // img.onerror = (ev) => { + // this.errors[path] = `Couldn't load image ${path}`; + // }; + // img.src = path; + let _Laya = Laya.Laya ? Laya.Laya : Laya; + _Laya.loader.load([{type: _Laya.Loader.IMAGE, url: path}], _Laya.Handler.create(this, (re) => { + if (re) { + this.rawAssets[path] = _Laya.loader.getRes(path); + } else { + this.errors[path] = `Couldn't load text ${path}`; + } + })); + } + get(clientId, path) { + path = this.pathPrefix + path; + let clientAssets = this.clientAssets[clientId]; + if (clientAssets === null || clientAssets === undefined) + return true; + return clientAssets.assets[path]; + } + updateClientAssets(clientAssets) { + for (let i = 0; i < clientAssets.toLoad.length; i++) { + let path = clientAssets.toLoad[i]; + let asset = clientAssets.assets[path]; + if (asset === null || asset === undefined) { + let rawAsset = this.rawAssets[path]; + if (rawAsset === null || rawAsset === undefined) + continue; + // LayaBox_Modify + // if (rawAsset instanceof HTMLImageElement) { + if (typeof rawAsset == "object" && !!rawAsset._bitmap) { + clientAssets.assets[path] = clientAssets.textureLoader(rawAsset); + } + else { + clientAssets.assets[path] = rawAsset; + } + } + } + } + isLoadingComplete(clientId) { + let clientAssets = this.clientAssets[clientId]; + if (clientAssets === null || clientAssets === undefined) + return true; + this.updateClientAssets(clientAssets); + return clientAssets.toLoad.length == clientAssets.loaded(); + } + dispose() { + } + hasErrors() { + return Object.keys(this.errors).length > 0; + } + getErrors() { + return this.errors; + } + } + spine.SharedAssetManager = SharedAssetManager; +})(spine || (spine = {})); +var spine; +(function (spine) { + class Skeleton { + constructor(data) { + this._updateCache = new Array(); + this.updateCacheReset = new Array(); + this.time = 0; + this.scaleX = 1; + this.scaleY = 1; + this.x = 0; + this.y = 0; + if (data == null) + throw new Error("data cannot be null."); + this.data = data; + this.bones = new Array(); + for (let i = 0; i < data.bones.length; i++) { + let boneData = data.bones[i]; + let bone; + if (boneData.parent == null) + bone = new spine.Bone(boneData, this, null); + else { + let parent = this.bones[boneData.parent.index]; + bone = new spine.Bone(boneData, this, parent); + parent.children.push(bone); + } + this.bones.push(bone); + } + this.slots = new Array(); + this.drawOrder = new Array(); + for (let i = 0; i < data.slots.length; i++) { + let slotData = data.slots[i]; + let bone = this.bones[slotData.boneData.index]; + let slot = new spine.Slot(slotData, bone); + this.slots.push(slot); + this.drawOrder.push(slot); + } + this.ikConstraints = new Array(); + for (let i = 0; i < data.ikConstraints.length; i++) { + let ikConstraintData = data.ikConstraints[i]; + this.ikConstraints.push(new spine.IkConstraint(ikConstraintData, this)); + } + this.transformConstraints = new Array(); + for (let i = 0; i < data.transformConstraints.length; i++) { + let transformConstraintData = data.transformConstraints[i]; + this.transformConstraints.push(new spine.TransformConstraint(transformConstraintData, this)); + } + this.pathConstraints = new Array(); + for (let i = 0; i < data.pathConstraints.length; i++) { + let pathConstraintData = data.pathConstraints[i]; + this.pathConstraints.push(new spine.PathConstraint(pathConstraintData, this)); + } + this.color = new spine.Color(1, 1, 1, 1); + this.updateCache(); + } + updateCache() { + let updateCache = this._updateCache; + updateCache.length = 0; + this.updateCacheReset.length = 0; + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + bone.sorted = bone.data.skinRequired; + bone.active = !bone.sorted; + } + if (this.skin != null) { + let skinBones = this.skin.bones; + for (let i = 0, n = this.skin.bones.length; i < n; i++) { + let bone = this.bones[skinBones[i].index]; + do { + bone.sorted = false; + bone.active = true; + bone = bone.parent; + } while (bone != null); + } + } + let ikConstraints = this.ikConstraints; + let transformConstraints = this.transformConstraints; + let pathConstraints = this.pathConstraints; + let ikCount = ikConstraints.length, transformCount = transformConstraints.length, pathCount = pathConstraints.length; + let constraintCount = ikCount + transformCount + pathCount; + outer: for (let i = 0; i < constraintCount; i++) { + for (let ii = 0; ii < ikCount; ii++) { + let constraint = ikConstraints[ii]; + if (constraint.data.order == i) { + this.sortIkConstraint(constraint); + continue outer; + } + } + for (let ii = 0; ii < transformCount; ii++) { + let constraint = transformConstraints[ii]; + if (constraint.data.order == i) { + this.sortTransformConstraint(constraint); + continue outer; + } + } + for (let ii = 0; ii < pathCount; ii++) { + let constraint = pathConstraints[ii]; + if (constraint.data.order == i) { + this.sortPathConstraint(constraint); + continue outer; + } + } + } + for (let i = 0, n = bones.length; i < n; i++) + this.sortBone(bones[i]); + } + sortIkConstraint(constraint) { + constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true))); + if (!constraint.active) + return; + let target = constraint.target; + this.sortBone(target); + let constrained = constraint.bones; + let parent = constrained[0]; + this.sortBone(parent); + if (constrained.length > 1) { + let child = constrained[constrained.length - 1]; + if (!(this._updateCache.indexOf(child) > -1)) + this.updateCacheReset.push(child); + } + this._updateCache.push(constraint); + this.sortReset(parent.children); + constrained[constrained.length - 1].sorted = true; + } + sortPathConstraint(constraint) { + constraint.active = constraint.target.bone.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true))); + if (!constraint.active) + return; + let slot = constraint.target; + let slotIndex = slot.data.index; + let slotBone = slot.bone; + if (this.skin != null) + this.sortPathConstraintAttachment(this.skin, slotIndex, slotBone); + if (this.data.defaultSkin != null && this.data.defaultSkin != this.skin) + this.sortPathConstraintAttachment(this.data.defaultSkin, slotIndex, slotBone); + for (let i = 0, n = this.data.skins.length; i < n; i++) + this.sortPathConstraintAttachment(this.data.skins[i], slotIndex, slotBone); + let attachment = slot.getAttachment(); + if (attachment instanceof spine.PathAttachment) + this.sortPathConstraintAttachmentWith(attachment, slotBone); + let constrained = constraint.bones; + let boneCount = constrained.length; + for (let i = 0; i < boneCount; i++) + this.sortBone(constrained[i]); + this._updateCache.push(constraint); + for (let i = 0; i < boneCount; i++) + this.sortReset(constrained[i].children); + for (let i = 0; i < boneCount; i++) + constrained[i].sorted = true; + } + sortTransformConstraint(constraint) { + constraint.active = constraint.target.isActive() && (!constraint.data.skinRequired || (this.skin != null && spine.Utils.contains(this.skin.constraints, constraint.data, true))); + if (!constraint.active) + return; + this.sortBone(constraint.target); + let constrained = constraint.bones; + let boneCount = constrained.length; + if (constraint.data.local) { + for (let i = 0; i < boneCount; i++) { + let child = constrained[i]; + this.sortBone(child.parent); + if (!(this._updateCache.indexOf(child) > -1)) + this.updateCacheReset.push(child); + } + } + else { + for (let i = 0; i < boneCount; i++) { + this.sortBone(constrained[i]); + } + } + this._updateCache.push(constraint); + for (let ii = 0; ii < boneCount; ii++) + this.sortReset(constrained[ii].children); + for (let ii = 0; ii < boneCount; ii++) + constrained[ii].sorted = true; + } + sortPathConstraintAttachment(skin, slotIndex, slotBone) { + let attachments = skin.attachments[slotIndex]; + if (!attachments) + return; + for (let key in attachments) { + this.sortPathConstraintAttachmentWith(attachments[key], slotBone); + } + } + sortPathConstraintAttachmentWith(attachment, slotBone) { + if (!(attachment instanceof spine.PathAttachment)) + return; + let pathBones = attachment.bones; + if (pathBones == null) + this.sortBone(slotBone); + else { + let bones = this.bones; + let i = 0; + while (i < pathBones.length) { + let boneCount = pathBones[i++]; + for (let n = i + boneCount; i < n; i++) { + let boneIndex = pathBones[i]; + this.sortBone(bones[boneIndex]); + } + } + } + } + sortBone(bone) { + if (bone.sorted) + return; + let parent = bone.parent; + if (parent != null) + this.sortBone(parent); + bone.sorted = true; + this._updateCache.push(bone); + } + sortReset(bones) { + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (!bone.active) + continue; + if (bone.sorted) + this.sortReset(bone.children); + bone.sorted = false; + } + } + updateWorldTransform() { + let updateCacheReset = this.updateCacheReset; + for (let i = 0, n = updateCacheReset.length; i < n; i++) { + let bone = updateCacheReset[i]; + bone.ax = bone.x; + bone.ay = bone.y; + bone.arotation = bone.rotation; + bone.ascaleX = bone.scaleX; + bone.ascaleY = bone.scaleY; + bone.ashearX = bone.shearX; + bone.ashearY = bone.shearY; + bone.appliedValid = true; + } + let updateCache = this._updateCache; + for (let i = 0, n = updateCache.length; i < n; i++) + updateCache[i].update(); + } + setToSetupPose() { + this.setBonesToSetupPose(); + this.setSlotsToSetupPose(); + } + setBonesToSetupPose() { + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) + bones[i].setToSetupPose(); + let ikConstraints = this.ikConstraints; + for (let i = 0, n = ikConstraints.length; i < n; i++) { + let constraint = ikConstraints[i]; + constraint.mix = constraint.data.mix; + constraint.softness = constraint.data.softness; + constraint.bendDirection = constraint.data.bendDirection; + constraint.compress = constraint.data.compress; + constraint.stretch = constraint.data.stretch; + } + let transformConstraints = this.transformConstraints; + for (let i = 0, n = transformConstraints.length; i < n; i++) { + let constraint = transformConstraints[i]; + let data = constraint.data; + constraint.rotateMix = data.rotateMix; + constraint.translateMix = data.translateMix; + constraint.scaleMix = data.scaleMix; + constraint.shearMix = data.shearMix; + } + let pathConstraints = this.pathConstraints; + for (let i = 0, n = pathConstraints.length; i < n; i++) { + let constraint = pathConstraints[i]; + let data = constraint.data; + constraint.position = data.position; + constraint.spacing = data.spacing; + constraint.rotateMix = data.rotateMix; + constraint.translateMix = data.translateMix; + } + } + setSlotsToSetupPose() { + let slots = this.slots; + spine.Utils.arrayCopy(slots, 0, this.drawOrder, 0, slots.length); + for (let i = 0, n = slots.length; i < n; i++) + slots[i].setToSetupPose(); + } + getRootBone() { + if (this.bones.length == 0) + return null; + return this.bones[0]; + } + findBone(boneName) { + if (boneName == null) + throw new Error("boneName cannot be null."); + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (bone.data.name == boneName) + return bone; + } + return null; + } + findBoneIndex(boneName) { + if (boneName == null) + throw new Error("boneName cannot be null."); + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) + if (bones[i].data.name == boneName) + return i; + return -1; + } + findSlot(slotName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) { + let slot = slots[i]; + if (slot.data.name == slotName) + return slot; + } + return null; + } + findSlotIndex(slotName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) + if (slots[i].data.name == slotName) + return i; + return -1; + } + setSkinByName(skinName) { + let skin = this.data.findSkin(skinName); + if (skin == null) + throw new Error("Skin not found: " + skinName); + this.setSkin(skin); + } + setSkin(newSkin) { + if (newSkin == this.skin) + return; + if (newSkin != null) { + if (this.skin != null) + newSkin.attachAll(this, this.skin); + else { + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) { + let slot = slots[i]; + let name = slot.data.attachmentName; + if (name != null) { + let attachment = newSkin.getAttachment(i, name); + if (attachment != null) + slot.setAttachment(attachment); + } + } + } + } + this.skin = newSkin; + this.updateCache(); + } + getAttachmentByName(slotName, attachmentName) { + return this.getAttachment(this.data.findSlotIndex(slotName), attachmentName); + } + getAttachment(slotIndex, attachmentName) { + if (attachmentName == null) + throw new Error("attachmentName cannot be null."); + if (this.skin != null) { + let attachment = this.skin.getAttachment(slotIndex, attachmentName); + if (attachment != null) + return attachment; + } + if (this.data.defaultSkin != null) + return this.data.defaultSkin.getAttachment(slotIndex, attachmentName); + return null; + } + setAttachment(slotName, attachmentName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) { + let slot = slots[i]; + if (slot.data.name == slotName) { + let attachment = null; + if (attachmentName != null) { + attachment = this.getAttachment(i, attachmentName); + if (attachment == null) + throw new Error("Attachment not found: " + attachmentName + ", for slot: " + slotName); + } + slot.setAttachment(attachment); + return; + } + } + throw new Error("Slot not found: " + slotName); + } + findIkConstraint(constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + let ikConstraints = this.ikConstraints; + for (let i = 0, n = ikConstraints.length; i < n; i++) { + let ikConstraint = ikConstraints[i]; + if (ikConstraint.data.name == constraintName) + return ikConstraint; + } + return null; + } + findTransformConstraint(constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + let transformConstraints = this.transformConstraints; + for (let i = 0, n = transformConstraints.length; i < n; i++) { + let constraint = transformConstraints[i]; + if (constraint.data.name == constraintName) + return constraint; + } + return null; + } + findPathConstraint(constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + let pathConstraints = this.pathConstraints; + for (let i = 0, n = pathConstraints.length; i < n; i++) { + let constraint = pathConstraints[i]; + if (constraint.data.name == constraintName) + return constraint; + } + return null; + } + getBounds(offset, size, temp = new Array(2)) { + if (offset == null) + throw new Error("offset cannot be null."); + if (size == null) + throw new Error("size cannot be null."); + let drawOrder = this.drawOrder; + let minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY; + for (let i = 0, n = drawOrder.length; i < n; i++) { + let slot = drawOrder[i]; + if (!slot.bone.active) + continue; + let verticesLength = 0; + let vertices = null; + let attachment = slot.getAttachment(); + if (attachment instanceof spine.RegionAttachment) { + verticesLength = 8; + vertices = spine.Utils.setArraySize(temp, verticesLength, 0); + attachment.computeWorldVertices(slot.bone, vertices, 0, 2); + } + else if (attachment instanceof spine.MeshAttachment) { + let mesh = attachment; + verticesLength = mesh.worldVerticesLength; + vertices = spine.Utils.setArraySize(temp, verticesLength, 0); + mesh.computeWorldVertices(slot, 0, verticesLength, vertices, 0, 2); + } + if (vertices != null) { + for (let ii = 0, nn = vertices.length; ii < nn; ii += 2) { + let x = vertices[ii], y = vertices[ii + 1]; + minX = Math.min(minX, x); + minY = Math.min(minY, y); + maxX = Math.max(maxX, x); + maxY = Math.max(maxY, y); + } + } + } + offset.set(minX, minY); + size.set(maxX - minX, maxY - minY); + } + update(delta) { + this.time += delta; + } + } + spine.Skeleton = Skeleton; +})(spine || (spine = {})); +var spine; +(function (spine) { + class SkeletonBinary { + constructor(attachmentLoader) { + this.scale = 1; + this.linkedMeshes = new Array(); + this.attachmentLoader = attachmentLoader; + } + readSkeletonData(binary) { + let scale = this.scale; + let skeletonData = new spine.SkeletonData(); + skeletonData.name = ""; + let input = new BinaryInput(binary); + skeletonData.hash = input.readString(); + skeletonData.version = input.readString(); + if ("3.8.75" == skeletonData.version) + throw new Error("Unsupported skeleton data, please export with a newer version of Spine."); + skeletonData.x = input.readFloat(); + skeletonData.y = input.readFloat(); + skeletonData.width = input.readFloat(); + skeletonData.height = input.readFloat(); + let nonessential = input.readBoolean(); + if (nonessential) { + skeletonData.fps = input.readFloat(); + skeletonData.imagesPath = input.readString(); + skeletonData.audioPath = input.readString(); + } + let n = 0; + n = input.readInt(true); + for (let i = 0; i < n; i++) + input.strings.push(input.readString()); + n = input.readInt(true); + for (let i = 0; i < n; i++) { + let name = input.readString(); + let parent = i == 0 ? null : skeletonData.bones[input.readInt(true)]; + let data = new spine.BoneData(i, name, parent); + data.rotation = input.readFloat(); + data.x = input.readFloat() * scale; + data.y = input.readFloat() * scale; + data.scaleX = input.readFloat(); + data.scaleY = input.readFloat(); + data.shearX = input.readFloat(); + data.shearY = input.readFloat(); + data.length = input.readFloat() * scale; + data.transformMode = SkeletonBinary.TransformModeValues[input.readInt(true)]; + data.skinRequired = input.readBoolean(); + if (nonessential) + spine.Color.rgba8888ToColor(data.color, input.readInt32()); + skeletonData.bones.push(data); + } + n = input.readInt(true); + for (let i = 0; i < n; i++) { + let slotName = input.readString(); + let boneData = skeletonData.bones[input.readInt(true)]; + let data = new spine.SlotData(i, slotName, boneData); + spine.Color.rgba8888ToColor(data.color, input.readInt32()); + let darkColor = input.readInt32(); + if (darkColor != -1) + spine.Color.rgb888ToColor(data.darkColor = new spine.Color(), darkColor); + data.attachmentName = input.readStringRef(); + data.blendMode = SkeletonBinary.BlendModeValues[input.readInt(true)]; + skeletonData.slots.push(data); + } + n = input.readInt(true); + for (let i = 0, nn; i < n; i++) { + let data = new spine.IkConstraintData(input.readString()); + data.order = input.readInt(true); + data.skinRequired = input.readBoolean(); + nn = input.readInt(true); + for (let ii = 0; ii < nn; ii++) + data.bones.push(skeletonData.bones[input.readInt(true)]); + data.target = skeletonData.bones[input.readInt(true)]; + data.mix = input.readFloat(); + data.softness = input.readFloat() * scale; + data.bendDirection = input.readByte(); + data.compress = input.readBoolean(); + data.stretch = input.readBoolean(); + data.uniform = input.readBoolean(); + skeletonData.ikConstraints.push(data); + } + n = input.readInt(true); + for (let i = 0, nn; i < n; i++) { + let data = new spine.TransformConstraintData(input.readString()); + data.order = input.readInt(true); + data.skinRequired = input.readBoolean(); + nn = input.readInt(true); + for (let ii = 0; ii < nn; ii++) + data.bones.push(skeletonData.bones[input.readInt(true)]); + data.target = skeletonData.bones[input.readInt(true)]; + data.local = input.readBoolean(); + data.relative = input.readBoolean(); + data.offsetRotation = input.readFloat(); + data.offsetX = input.readFloat() * scale; + data.offsetY = input.readFloat() * scale; + data.offsetScaleX = input.readFloat(); + data.offsetScaleY = input.readFloat(); + data.offsetShearY = input.readFloat(); + data.rotateMix = input.readFloat(); + data.translateMix = input.readFloat(); + data.scaleMix = input.readFloat(); + data.shearMix = input.readFloat(); + skeletonData.transformConstraints.push(data); + } + n = input.readInt(true); + for (let i = 0, nn; i < n; i++) { + let data = new spine.PathConstraintData(input.readString()); + data.order = input.readInt(true); + data.skinRequired = input.readBoolean(); + nn = input.readInt(true); + for (let ii = 0; ii < nn; ii++) + data.bones.push(skeletonData.bones[input.readInt(true)]); + data.target = skeletonData.slots[input.readInt(true)]; + data.positionMode = SkeletonBinary.PositionModeValues[input.readInt(true)]; + data.spacingMode = SkeletonBinary.SpacingModeValues[input.readInt(true)]; + data.rotateMode = SkeletonBinary.RotateModeValues[input.readInt(true)]; + data.offsetRotation = input.readFloat(); + data.position = input.readFloat(); + if (data.positionMode == spine.PositionMode.Fixed) + data.position *= scale; + data.spacing = input.readFloat(); + if (data.spacingMode == spine.SpacingMode.Length || data.spacingMode == spine.SpacingMode.Fixed) + data.spacing *= scale; + data.rotateMix = input.readFloat(); + data.translateMix = input.readFloat(); + skeletonData.pathConstraints.push(data); + } + let defaultSkin = this.readSkin(input, skeletonData, true, nonessential); + if (defaultSkin != null) { + skeletonData.defaultSkin = defaultSkin; + skeletonData.skins.push(defaultSkin); + } + { + let i = skeletonData.skins.length; + spine.Utils.setArraySize(skeletonData.skins, n = i + input.readInt(true)); + for (; i < n; i++) + skeletonData.skins[i] = this.readSkin(input, skeletonData, false, nonessential); + } + n = this.linkedMeshes.length; + for (let i = 0; i < n; i++) { + let linkedMesh = this.linkedMeshes[i]; + let skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin); + if (skin == null) + throw new Error("Skin not found: " + linkedMesh.skin); + let parent = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent); + if (parent == null) + throw new Error("Parent mesh not found: " + linkedMesh.parent); + linkedMesh.mesh.deformAttachment = linkedMesh.inheritDeform ? parent : linkedMesh.mesh; + linkedMesh.mesh.setParentMesh(parent); + linkedMesh.mesh.updateUVs(); + } + this.linkedMeshes.length = 0; + n = input.readInt(true); + for (let i = 0; i < n; i++) { + let data = new spine.EventData(input.readStringRef()); + data.intValue = input.readInt(false); + data.floatValue = input.readFloat(); + data.stringValue = input.readString(); + data.audioPath = input.readString(); + if (data.audioPath != null) { + data.volume = input.readFloat(); + data.balance = input.readFloat(); + } + skeletonData.events.push(data); + } + n = input.readInt(true); + for (let i = 0; i < n; i++) + skeletonData.animations.push(this.readAnimation(input, input.readString(), skeletonData)); + return skeletonData; + } + readSkin(input, skeletonData, defaultSkin, nonessential) { + let skin = null; + let slotCount = 0; + if (defaultSkin) { + slotCount = input.readInt(true); + if (slotCount == 0) + return null; + skin = new spine.Skin("default"); + } + else { + skin = new spine.Skin(input.readStringRef()); + skin.bones.length = input.readInt(true); + for (let i = 0, n = skin.bones.length; i < n; i++) + skin.bones[i] = skeletonData.bones[input.readInt(true)]; + for (let i = 0, n = input.readInt(true); i < n; i++) + skin.constraints.push(skeletonData.ikConstraints[input.readInt(true)]); + for (let i = 0, n = input.readInt(true); i < n; i++) + skin.constraints.push(skeletonData.transformConstraints[input.readInt(true)]); + for (let i = 0, n = input.readInt(true); i < n; i++) + skin.constraints.push(skeletonData.pathConstraints[input.readInt(true)]); + slotCount = input.readInt(true); + } + for (let i = 0; i < slotCount; i++) { + let slotIndex = input.readInt(true); + for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { + let name = input.readStringRef(); + let attachment = this.readAttachment(input, skeletonData, skin, slotIndex, name, nonessential); + if (attachment != null) + skin.setAttachment(slotIndex, name, attachment); + } + } + return skin; + } + readAttachment(input, skeletonData, skin, slotIndex, attachmentName, nonessential) { + let scale = this.scale; + let name = input.readStringRef(); + if (name == null) + name = attachmentName; + let typeIndex = input.readByte(); + let type = SkeletonBinary.AttachmentTypeValues[typeIndex]; + switch (type) { + case spine.AttachmentType.Region: { + let path = input.readStringRef(); + let rotation = input.readFloat(); + let x = input.readFloat(); + let y = input.readFloat(); + let scaleX = input.readFloat(); + let scaleY = input.readFloat(); + let width = input.readFloat(); + let height = input.readFloat(); + let color = input.readInt32(); + if (path == null) + path = name; + let region = this.attachmentLoader.newRegionAttachment(skin, name, path); + if (region == null) + return null; + region.path = path; + region.x = x * scale; + region.y = y * scale; + region.scaleX = scaleX; + region.scaleY = scaleY; + region.rotation = rotation; + region.width = width * scale; + region.height = height * scale; + spine.Color.rgba8888ToColor(region.color, color); + region.updateOffset(); + return region; + } + case spine.AttachmentType.BoundingBox: { + let vertexCount = input.readInt(true); + let vertices = this.readVertices(input, vertexCount); + let color = nonessential ? input.readInt32() : 0; + let box = this.attachmentLoader.newBoundingBoxAttachment(skin, name); + if (box == null) + return null; + box.worldVerticesLength = vertexCount << 1; + box.vertices = vertices.vertices; + box.bones = vertices.bones; + if (nonessential) + spine.Color.rgba8888ToColor(box.color, color); + return box; + } + case spine.AttachmentType.Mesh: { + let path = input.readStringRef(); + let color = input.readInt32(); + let vertexCount = input.readInt(true); + let uvs = this.readFloatArray(input, vertexCount << 1, 1); + let triangles = this.readShortArray(input); + let vertices = this.readVertices(input, vertexCount); + let hullLength = input.readInt(true); + let edges = null; + let width = 0, height = 0; + if (nonessential) { + edges = this.readShortArray(input); + width = input.readFloat(); + height = input.readFloat(); + } + if (path == null) + path = name; + let mesh = this.attachmentLoader.newMeshAttachment(skin, name, path); + if (mesh == null) + return null; + mesh.path = path; + spine.Color.rgba8888ToColor(mesh.color, color); + mesh.bones = vertices.bones; + mesh.vertices = vertices.vertices; + mesh.worldVerticesLength = vertexCount << 1; + mesh.triangles = triangles; + mesh.regionUVs = uvs; + mesh.updateUVs(); + mesh.hullLength = hullLength << 1; + if (nonessential) { + mesh.edges = edges; + mesh.width = width * scale; + mesh.height = height * scale; + } + return mesh; + } + case spine.AttachmentType.LinkedMesh: { + let path = input.readStringRef(); + let color = input.readInt32(); + let skinName = input.readStringRef(); + let parent = input.readStringRef(); + let inheritDeform = input.readBoolean(); + let width = 0, height = 0; + if (nonessential) { + width = input.readFloat(); + height = input.readFloat(); + } + if (path == null) + path = name; + let mesh = this.attachmentLoader.newMeshAttachment(skin, name, path); + if (mesh == null) + return null; + mesh.path = path; + spine.Color.rgba8888ToColor(mesh.color, color); + if (nonessential) { + mesh.width = width * scale; + mesh.height = height * scale; + } + this.linkedMeshes.push(new LinkedMesh(mesh, skinName, slotIndex, parent, inheritDeform)); + return mesh; + } + case spine.AttachmentType.Path: { + let closed = input.readBoolean(); + let constantSpeed = input.readBoolean(); + let vertexCount = input.readInt(true); + let vertices = this.readVertices(input, vertexCount); + let lengths = spine.Utils.newArray(vertexCount / 3, 0); + for (let i = 0, n = lengths.length; i < n; i++) + lengths[i] = input.readFloat() * scale; + let color = nonessential ? input.readInt32() : 0; + let path = this.attachmentLoader.newPathAttachment(skin, name); + if (path == null) + return null; + path.closed = closed; + path.constantSpeed = constantSpeed; + path.worldVerticesLength = vertexCount << 1; + path.vertices = vertices.vertices; + path.bones = vertices.bones; + path.lengths = lengths; + if (nonessential) + spine.Color.rgba8888ToColor(path.color, color); + return path; + } + case spine.AttachmentType.Point: { + let rotation = input.readFloat(); + let x = input.readFloat(); + let y = input.readFloat(); + let color = nonessential ? input.readInt32() : 0; + let point = this.attachmentLoader.newPointAttachment(skin, name); + if (point == null) + return null; + point.x = x * scale; + point.y = y * scale; + point.rotation = rotation; + if (nonessential) + spine.Color.rgba8888ToColor(point.color, color); + return point; + } + case spine.AttachmentType.Clipping: { + let endSlotIndex = input.readInt(true); + let vertexCount = input.readInt(true); + let vertices = this.readVertices(input, vertexCount); + let color = nonessential ? input.readInt32() : 0; + let clip = this.attachmentLoader.newClippingAttachment(skin, name); + if (clip == null) + return null; + clip.endSlot = skeletonData.slots[endSlotIndex]; + clip.worldVerticesLength = vertexCount << 1; + clip.vertices = vertices.vertices; + clip.bones = vertices.bones; + if (nonessential) + spine.Color.rgba8888ToColor(clip.color, color); + return clip; + } + } + return null; + } + readVertices(input, vertexCount) { + let verticesLength = vertexCount << 1; + let vertices = new Vertices(); + let scale = this.scale; + if (!input.readBoolean()) { + vertices.vertices = this.readFloatArray(input, verticesLength, scale); + return vertices; + } + let weights = new Array(); + let bonesArray = new Array(); + for (let i = 0; i < vertexCount; i++) { + let boneCount = input.readInt(true); + bonesArray.push(boneCount); + for (let ii = 0; ii < boneCount; ii++) { + bonesArray.push(input.readInt(true)); + weights.push(input.readFloat() * scale); + weights.push(input.readFloat() * scale); + weights.push(input.readFloat()); + } + } + vertices.vertices = spine.Utils.toFloatArray(weights); + vertices.bones = bonesArray; + return vertices; + } + readFloatArray(input, n, scale) { + let array = new Array(n); + if (scale == 1) { + for (let i = 0; i < n; i++) + array[i] = input.readFloat(); + } + else { + for (let i = 0; i < n; i++) + array[i] = input.readFloat() * scale; + } + return array; + } + readShortArray(input) { + let n = input.readInt(true); + let array = new Array(n); + for (let i = 0; i < n; i++) + array[i] = input.readShort(); + return array; + } + readAnimation(input, name, skeletonData) { + let timelines = new Array(); + let scale = this.scale; + let duration = 0; + let tempColor1 = new spine.Color(); + let tempColor2 = new spine.Color(); + for (let i = 0, n = input.readInt(true); i < n; i++) { + let slotIndex = input.readInt(true); + for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { + let timelineType = input.readByte(); + let frameCount = input.readInt(true); + switch (timelineType) { + case SkeletonBinary.SLOT_ATTACHMENT: { + let timeline = new spine.AttachmentTimeline(frameCount); + timeline.slotIndex = slotIndex; + for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) + timeline.setFrame(frameIndex, input.readFloat(), input.readStringRef()); + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[frameCount - 1]); + break; + } + case SkeletonBinary.SLOT_COLOR: { + let timeline = new spine.ColorTimeline(frameCount); + timeline.slotIndex = slotIndex; + for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) { + let time = input.readFloat(); + spine.Color.rgba8888ToColor(tempColor1, input.readInt32()); + timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a); + if (frameIndex < frameCount - 1) + this.readCurve(input, frameIndex, timeline); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(frameCount - 1) * spine.ColorTimeline.ENTRIES]); + break; + } + case SkeletonBinary.SLOT_TWO_COLOR: { + let timeline = new spine.TwoColorTimeline(frameCount); + timeline.slotIndex = slotIndex; + for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) { + let time = input.readFloat(); + spine.Color.rgba8888ToColor(tempColor1, input.readInt32()); + spine.Color.rgb888ToColor(tempColor2, input.readInt32()); + timeline.setFrame(frameIndex, time, tempColor1.r, tempColor1.g, tempColor1.b, tempColor1.a, tempColor2.r, tempColor2.g, tempColor2.b); + if (frameIndex < frameCount - 1) + this.readCurve(input, frameIndex, timeline); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(frameCount - 1) * spine.TwoColorTimeline.ENTRIES]); + break; + } + } + } + } + for (let i = 0, n = input.readInt(true); i < n; i++) { + let boneIndex = input.readInt(true); + for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { + let timelineType = input.readByte(); + let frameCount = input.readInt(true); + switch (timelineType) { + case SkeletonBinary.BONE_ROTATE: { + let timeline = new spine.RotateTimeline(frameCount); + timeline.boneIndex = boneIndex; + for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) { + timeline.setFrame(frameIndex, input.readFloat(), input.readFloat()); + if (frameIndex < frameCount - 1) + this.readCurve(input, frameIndex, timeline); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(frameCount - 1) * spine.RotateTimeline.ENTRIES]); + break; + } + case SkeletonBinary.BONE_TRANSLATE: + case SkeletonBinary.BONE_SCALE: + case SkeletonBinary.BONE_SHEAR: { + let timeline; + let timelineScale = 1; + if (timelineType == SkeletonBinary.BONE_SCALE) + timeline = new spine.ScaleTimeline(frameCount); + else if (timelineType == SkeletonBinary.BONE_SHEAR) + timeline = new spine.ShearTimeline(frameCount); + else { + timeline = new spine.TranslateTimeline(frameCount); + timelineScale = scale; + } + timeline.boneIndex = boneIndex; + for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) { + timeline.setFrame(frameIndex, input.readFloat(), input.readFloat() * timelineScale, input.readFloat() * timelineScale); + if (frameIndex < frameCount - 1) + this.readCurve(input, frameIndex, timeline); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(frameCount - 1) * spine.TranslateTimeline.ENTRIES]); + break; + } + } + } + } + for (let i = 0, n = input.readInt(true); i < n; i++) { + let index = input.readInt(true); + let frameCount = input.readInt(true); + let timeline = new spine.IkConstraintTimeline(frameCount); + timeline.ikConstraintIndex = index; + for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) { + timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat() * scale, input.readByte(), input.readBoolean(), input.readBoolean()); + if (frameIndex < frameCount - 1) + this.readCurve(input, frameIndex, timeline); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(frameCount - 1) * spine.IkConstraintTimeline.ENTRIES]); + } + for (let i = 0, n = input.readInt(true); i < n; i++) { + let index = input.readInt(true); + let frameCount = input.readInt(true); + let timeline = new spine.TransformConstraintTimeline(frameCount); + timeline.transformConstraintIndex = index; + for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) { + timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat()); + if (frameIndex < frameCount - 1) + this.readCurve(input, frameIndex, timeline); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(frameCount - 1) * spine.TransformConstraintTimeline.ENTRIES]); + } + for (let i = 0, n = input.readInt(true); i < n; i++) { + let index = input.readInt(true); + let data = skeletonData.pathConstraints[index]; + for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { + let timelineType = input.readByte(); + let frameCount = input.readInt(true); + switch (timelineType) { + case SkeletonBinary.PATH_POSITION: + case SkeletonBinary.PATH_SPACING: { + let timeline; + let timelineScale = 1; + if (timelineType == SkeletonBinary.PATH_SPACING) { + timeline = new spine.PathConstraintSpacingTimeline(frameCount); + if (data.spacingMode == spine.SpacingMode.Length || data.spacingMode == spine.SpacingMode.Fixed) + timelineScale = scale; + } + else { + timeline = new spine.PathConstraintPositionTimeline(frameCount); + if (data.positionMode == spine.PositionMode.Fixed) + timelineScale = scale; + } + timeline.pathConstraintIndex = index; + for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) { + timeline.setFrame(frameIndex, input.readFloat(), input.readFloat() * timelineScale); + if (frameIndex < frameCount - 1) + this.readCurve(input, frameIndex, timeline); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(frameCount - 1) * spine.PathConstraintPositionTimeline.ENTRIES]); + break; + } + case SkeletonBinary.PATH_MIX: { + let timeline = new spine.PathConstraintMixTimeline(frameCount); + timeline.pathConstraintIndex = index; + for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) { + timeline.setFrame(frameIndex, input.readFloat(), input.readFloat(), input.readFloat()); + if (frameIndex < frameCount - 1) + this.readCurve(input, frameIndex, timeline); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(frameCount - 1) * spine.PathConstraintMixTimeline.ENTRIES]); + break; + } + } + } + } + for (let i = 0, n = input.readInt(true); i < n; i++) { + let skin = skeletonData.skins[input.readInt(true)]; + for (let ii = 0, nn = input.readInt(true); ii < nn; ii++) { + let slotIndex = input.readInt(true); + for (let iii = 0, nnn = input.readInt(true); iii < nnn; iii++) { + let attachment = skin.getAttachment(slotIndex, input.readStringRef()); + let weighted = attachment.bones != null; + let vertices = attachment.vertices; + let deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; + let frameCount = input.readInt(true); + let timeline = new spine.DeformTimeline(frameCount); + timeline.slotIndex = slotIndex; + timeline.attachment = attachment; + for (let frameIndex = 0; frameIndex < frameCount; frameIndex++) { + let time = input.readFloat(); + let deform; + let end = input.readInt(true); + if (end == 0) + deform = weighted ? spine.Utils.newFloatArray(deformLength) : vertices; + else { + deform = spine.Utils.newFloatArray(deformLength); + let start = input.readInt(true); + end += start; + if (scale == 1) { + for (let v = start; v < end; v++) + deform[v] = input.readFloat(); + } + else { + for (let v = start; v < end; v++) + deform[v] = input.readFloat() * scale; + } + if (!weighted) { + for (let v = 0, vn = deform.length; v < vn; v++) + deform[v] += vertices[v]; + } + } + timeline.setFrame(frameIndex, time, deform); + if (frameIndex < frameCount - 1) + this.readCurve(input, frameIndex, timeline); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[frameCount - 1]); + } + } + } + let drawOrderCount = input.readInt(true); + if (drawOrderCount > 0) { + let timeline = new spine.DrawOrderTimeline(drawOrderCount); + let slotCount = skeletonData.slots.length; + for (let i = 0; i < drawOrderCount; i++) { + let time = input.readFloat(); + let offsetCount = input.readInt(true); + let drawOrder = spine.Utils.newArray(slotCount, 0); + for (let ii = slotCount - 1; ii >= 0; ii--) + drawOrder[ii] = -1; + let unchanged = spine.Utils.newArray(slotCount - offsetCount, 0); + let originalIndex = 0, unchangedIndex = 0; + for (let ii = 0; ii < offsetCount; ii++) { + let slotIndex = input.readInt(true); + while (originalIndex != slotIndex) + unchanged[unchangedIndex++] = originalIndex++; + drawOrder[originalIndex + input.readInt(true)] = originalIndex++; + } + while (originalIndex < slotCount) + unchanged[unchangedIndex++] = originalIndex++; + for (let ii = slotCount - 1; ii >= 0; ii--) + if (drawOrder[ii] == -1) + drawOrder[ii] = unchanged[--unchangedIndex]; + timeline.setFrame(i, time, drawOrder); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[drawOrderCount - 1]); + } + let eventCount = input.readInt(true); + if (eventCount > 0) { + let timeline = new spine.EventTimeline(eventCount); + for (let i = 0; i < eventCount; i++) { + let time = input.readFloat(); + let eventData = skeletonData.events[input.readInt(true)]; + let event = new spine.Event(time, eventData); + event.intValue = input.readInt(false); + event.floatValue = input.readFloat(); + event.stringValue = input.readBoolean() ? input.readString() : eventData.stringValue; + if (event.data.audioPath != null) { + event.volume = input.readFloat(); + event.balance = input.readFloat(); + } + timeline.setFrame(i, event); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[eventCount - 1]); + } + return new spine.Animation(name, timelines, duration); + } + readCurve(input, frameIndex, timeline) { + switch (input.readByte()) { + case SkeletonBinary.CURVE_STEPPED: + timeline.setStepped(frameIndex); + break; + case SkeletonBinary.CURVE_BEZIER: + this.setCurve(timeline, frameIndex, input.readFloat(), input.readFloat(), input.readFloat(), input.readFloat()); + break; + } + } + setCurve(timeline, frameIndex, cx1, cy1, cx2, cy2) { + timeline.setCurve(frameIndex, cx1, cy1, cx2, cy2); + } + } + SkeletonBinary.AttachmentTypeValues = [0, 1, 2, 3, 4, 5, 6]; + SkeletonBinary.TransformModeValues = [spine.TransformMode.Normal, spine.TransformMode.OnlyTranslation, spine.TransformMode.NoRotationOrReflection, spine.TransformMode.NoScale, spine.TransformMode.NoScaleOrReflection]; + SkeletonBinary.PositionModeValues = [spine.PositionMode.Fixed, spine.PositionMode.Percent]; + SkeletonBinary.SpacingModeValues = [spine.SpacingMode.Length, spine.SpacingMode.Fixed, spine.SpacingMode.Percent]; + SkeletonBinary.RotateModeValues = [spine.RotateMode.Tangent, spine.RotateMode.Chain, spine.RotateMode.ChainScale]; + SkeletonBinary.BlendModeValues = [spine.BlendMode.Normal, spine.BlendMode.Additive, spine.BlendMode.Multiply, spine.BlendMode.Screen]; + SkeletonBinary.BONE_ROTATE = 0; + SkeletonBinary.BONE_TRANSLATE = 1; + SkeletonBinary.BONE_SCALE = 2; + SkeletonBinary.BONE_SHEAR = 3; + SkeletonBinary.SLOT_ATTACHMENT = 0; + SkeletonBinary.SLOT_COLOR = 1; + SkeletonBinary.SLOT_TWO_COLOR = 2; + SkeletonBinary.PATH_POSITION = 0; + SkeletonBinary.PATH_SPACING = 1; + SkeletonBinary.PATH_MIX = 2; + SkeletonBinary.CURVE_LINEAR = 0; + SkeletonBinary.CURVE_STEPPED = 1; + SkeletonBinary.CURVE_BEZIER = 2; + spine.SkeletonBinary = SkeletonBinary; + class BinaryInput { + constructor(data, strings = new Array(), index = 0, buffer = new DataView(data.buffer)) { + this.strings = strings; + this.index = index; + this.buffer = buffer; + } + readByte() { + return this.buffer.getInt8(this.index++); + } + readShort() { + let value = this.buffer.getInt16(this.index); + this.index += 2; + return value; + } + readInt32() { + let value = this.buffer.getInt32(this.index); + this.index += 4; + return value; + } + readInt(optimizePositive) { + let b = this.readByte(); + let result = b & 0x7F; + if ((b & 0x80) != 0) { + b = this.readByte(); + result |= (b & 0x7F) << 7; + if ((b & 0x80) != 0) { + b = this.readByte(); + result |= (b & 0x7F) << 14; + if ((b & 0x80) != 0) { + b = this.readByte(); + result |= (b & 0x7F) << 21; + if ((b & 0x80) != 0) { + b = this.readByte(); + result |= (b & 0x7F) << 28; + } + } + } + } + return optimizePositive ? result : ((result >>> 1) ^ -(result & 1)); + } + readStringRef() { + let index = this.readInt(true); + return index == 0 ? null : this.strings[index - 1]; + } + readString() { + let byteCount = this.readInt(true); + switch (byteCount) { + case 0: + return null; + case 1: + return ""; + } + byteCount--; + let chars = ""; + let charCount = 0; + for (let i = 0; i < byteCount;) { + let b = this.readByte(); + switch (b >> 4) { + case 12: + case 13: + chars += String.fromCharCode(((b & 0x1F) << 6 | this.readByte() & 0x3F)); + i += 2; + break; + case 14: + chars += String.fromCharCode(((b & 0x0F) << 12 | (this.readByte() & 0x3F) << 6 | this.readByte() & 0x3F)); + i += 3; + break; + default: + chars += String.fromCharCode(b); + i++; + } + } + return chars; + } + readFloat() { + let value = this.buffer.getFloat32(this.index); + this.index += 4; + return value; + } + readBoolean() { + return this.readByte() != 0; + } + } + class LinkedMesh { + constructor(mesh, skin, slotIndex, parent, inheritDeform) { + this.mesh = mesh; + this.skin = skin; + this.slotIndex = slotIndex; + this.parent = parent; + this.inheritDeform = inheritDeform; + } + } + class Vertices { + constructor(bones = null, vertices = null) { + this.bones = bones; + this.vertices = vertices; + } + } +})(spine || (spine = {})); +var spine; +(function (spine) { + class SkeletonBounds { + constructor() { + this.minX = 0; + this.minY = 0; + this.maxX = 0; + this.maxY = 0; + this.boundingBoxes = new Array(); + this.polygons = new Array(); + this.polygonPool = new spine.Pool(() => { + return spine.Utils.newFloatArray(16); + }); + } + update(skeleton, updateAabb) { + if (skeleton == null) + throw new Error("skeleton cannot be null."); + let boundingBoxes = this.boundingBoxes; + let polygons = this.polygons; + let polygonPool = this.polygonPool; + let slots = skeleton.slots; + let slotCount = slots.length; + boundingBoxes.length = 0; + polygonPool.freeAll(polygons); + polygons.length = 0; + for (let i = 0; i < slotCount; i++) { + let slot = slots[i]; + if (!slot.bone.active) + continue; + let attachment = slot.getAttachment(); + if (attachment instanceof spine.BoundingBoxAttachment) { + let boundingBox = attachment; + boundingBoxes.push(boundingBox); + let polygon = polygonPool.obtain(); + if (polygon.length != boundingBox.worldVerticesLength) { + polygon = spine.Utils.newFloatArray(boundingBox.worldVerticesLength); + } + polygons.push(polygon); + boundingBox.computeWorldVertices(slot, 0, boundingBox.worldVerticesLength, polygon, 0, 2); + } + } + if (updateAabb) { + this.aabbCompute(); + } + else { + this.minX = Number.POSITIVE_INFINITY; + this.minY = Number.POSITIVE_INFINITY; + this.maxX = Number.NEGATIVE_INFINITY; + this.maxY = Number.NEGATIVE_INFINITY; + } + } + aabbCompute() { + let minX = Number.POSITIVE_INFINITY, minY = Number.POSITIVE_INFINITY, maxX = Number.NEGATIVE_INFINITY, maxY = Number.NEGATIVE_INFINITY; + let polygons = this.polygons; + for (let i = 0, n = polygons.length; i < n; i++) { + let polygon = polygons[i]; + let vertices = polygon; + for (let ii = 0, nn = polygon.length; ii < nn; ii += 2) { + let x = vertices[ii]; + let y = vertices[ii + 1]; + minX = Math.min(minX, x); + minY = Math.min(minY, y); + maxX = Math.max(maxX, x); + maxY = Math.max(maxY, y); + } + } + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + } + aabbContainsPoint(x, y) { + return x >= this.minX && x <= this.maxX && y >= this.minY && y <= this.maxY; + } + aabbIntersectsSegment(x1, y1, x2, y2) { + let minX = this.minX; + let minY = this.minY; + let maxX = this.maxX; + let maxY = this.maxY; + if ((x1 <= minX && x2 <= minX) || (y1 <= minY && y2 <= minY) || (x1 >= maxX && x2 >= maxX) || (y1 >= maxY && y2 >= maxY)) + return false; + let m = (y2 - y1) / (x2 - x1); + let y = m * (minX - x1) + y1; + if (y > minY && y < maxY) + return true; + y = m * (maxX - x1) + y1; + if (y > minY && y < maxY) + return true; + let x = (minY - y1) / m + x1; + if (x > minX && x < maxX) + return true; + x = (maxY - y1) / m + x1; + if (x > minX && x < maxX) + return true; + return false; + } + aabbIntersectsSkeleton(bounds) { + return this.minX < bounds.maxX && this.maxX > bounds.minX && this.minY < bounds.maxY && this.maxY > bounds.minY; + } + containsPoint(x, y) { + let polygons = this.polygons; + for (let i = 0, n = polygons.length; i < n; i++) + if (this.containsPointPolygon(polygons[i], x, y)) + return this.boundingBoxes[i]; + return null; + } + containsPointPolygon(polygon, x, y) { + let vertices = polygon; + let nn = polygon.length; + let prevIndex = nn - 2; + let inside = false; + for (let ii = 0; ii < nn; ii += 2) { + let vertexY = vertices[ii + 1]; + let prevY = vertices[prevIndex + 1]; + if ((vertexY < y && prevY >= y) || (prevY < y && vertexY >= y)) { + let vertexX = vertices[ii]; + if (vertexX + (y - vertexY) / (prevY - vertexY) * (vertices[prevIndex] - vertexX) < x) + inside = !inside; + } + prevIndex = ii; + } + return inside; + } + intersectsSegment(x1, y1, x2, y2) { + let polygons = this.polygons; + for (let i = 0, n = polygons.length; i < n; i++) + if (this.intersectsSegmentPolygon(polygons[i], x1, y1, x2, y2)) + return this.boundingBoxes[i]; + return null; + } + intersectsSegmentPolygon(polygon, x1, y1, x2, y2) { + let vertices = polygon; + let nn = polygon.length; + let width12 = x1 - x2, height12 = y1 - y2; + let det1 = x1 * y2 - y1 * x2; + let x3 = vertices[nn - 2], y3 = vertices[nn - 1]; + for (let ii = 0; ii < nn; ii += 2) { + let x4 = vertices[ii], y4 = vertices[ii + 1]; + let det2 = x3 * y4 - y3 * x4; + let width34 = x3 - x4, height34 = y3 - y4; + let det3 = width12 * height34 - height12 * width34; + let x = (det1 * width34 - width12 * det2) / det3; + if (((x >= x3 && x <= x4) || (x >= x4 && x <= x3)) && ((x >= x1 && x <= x2) || (x >= x2 && x <= x1))) { + let y = (det1 * height34 - height12 * det2) / det3; + if (((y >= y3 && y <= y4) || (y >= y4 && y <= y3)) && ((y >= y1 && y <= y2) || (y >= y2 && y <= y1))) + return true; + } + x3 = x4; + y3 = y4; + } + return false; + } + getPolygon(boundingBox) { + if (boundingBox == null) + throw new Error("boundingBox cannot be null."); + let index = this.boundingBoxes.indexOf(boundingBox); + return index == -1 ? null : this.polygons[index]; + } + getWidth() { + return this.maxX - this.minX; + } + getHeight() { + return this.maxY - this.minY; + } + } + spine.SkeletonBounds = SkeletonBounds; +})(spine || (spine = {})); +var spine; +(function (spine) { + class SkeletonClipping { + constructor() { + this.triangulator = new spine.Triangulator(); + this.clippingPolygon = new Array(); + this.clipOutput = new Array(); + this.clippedVertices = new Array(); + this.clippedTriangles = new Array(); + this.scratch = new Array(); + } + clipStart(slot, clip) { + if (this.clipAttachment != null) + return 0; + this.clipAttachment = clip; + let n = clip.worldVerticesLength; + let vertices = spine.Utils.setArraySize(this.clippingPolygon, n); + clip.computeWorldVertices(slot, 0, n, vertices, 0, 2); + let clippingPolygon = this.clippingPolygon; + SkeletonClipping.makeClockwise(clippingPolygon); + let clippingPolygons = this.clippingPolygons = this.triangulator.decompose(clippingPolygon, this.triangulator.triangulate(clippingPolygon)); + for (let i = 0, n = clippingPolygons.length; i < n; i++) { + let polygon = clippingPolygons[i]; + SkeletonClipping.makeClockwise(polygon); + polygon.push(polygon[0]); + polygon.push(polygon[1]); + } + return clippingPolygons.length; + } + clipEndWithSlot(slot) { + if (this.clipAttachment != null && this.clipAttachment.endSlot == slot.data) + this.clipEnd(); + } + clipEnd() { + if (this.clipAttachment == null) + return; + this.clipAttachment = null; + this.clippingPolygons = null; + this.clippedVertices.length = 0; + this.clippedTriangles.length = 0; + this.clippingPolygon.length = 0; + } + isClipping() { + return this.clipAttachment != null; + } + clipTriangles(vertices, verticesLength, triangles, trianglesLength, uvs, light, dark, twoColor) { + let clipOutput = this.clipOutput, clippedVertices = this.clippedVertices; + let clippedTriangles = this.clippedTriangles; + let polygons = this.clippingPolygons; + let polygonsCount = this.clippingPolygons.length; + let vertexSize = twoColor ? 12 : 8; + let index = 0; + clippedVertices.length = 0; + clippedTriangles.length = 0; + outer: for (let i = 0; i < trianglesLength; i += 3) { + let vertexOffset = triangles[i] << 1; + let x1 = vertices[vertexOffset], y1 = vertices[vertexOffset + 1]; + let u1 = uvs[vertexOffset], v1 = uvs[vertexOffset + 1]; + vertexOffset = triangles[i + 1] << 1; + let x2 = vertices[vertexOffset], y2 = vertices[vertexOffset + 1]; + let u2 = uvs[vertexOffset], v2 = uvs[vertexOffset + 1]; + vertexOffset = triangles[i + 2] << 1; + let x3 = vertices[vertexOffset], y3 = vertices[vertexOffset + 1]; + let u3 = uvs[vertexOffset], v3 = uvs[vertexOffset + 1]; + for (let p = 0; p < polygonsCount; p++) { + let s = clippedVertices.length; + if (this.clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput)) { + let clipOutputLength = clipOutput.length; + if (clipOutputLength == 0) + continue; + let d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1; + let d = 1 / (d0 * d2 + d1 * (y1 - y3)); + let clipOutputCount = clipOutputLength >> 1; + let clipOutputItems = this.clipOutput; + let clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + clipOutputCount * vertexSize); + for (let ii = 0; ii < clipOutputLength; ii += 2) { + let x = clipOutputItems[ii], y = clipOutputItems[ii + 1]; + clippedVerticesItems[s] = x; + clippedVerticesItems[s + 1] = y; + clippedVerticesItems[s + 2] = light.r; + clippedVerticesItems[s + 3] = light.g; + clippedVerticesItems[s + 4] = light.b; + clippedVerticesItems[s + 5] = light.a; + let c0 = x - x3, c1 = y - y3; + let a = (d0 * c0 + d1 * c1) * d; + let b = (d4 * c0 + d2 * c1) * d; + let c = 1 - a - b; + clippedVerticesItems[s + 6] = u1 * a + u2 * b + u3 * c; + clippedVerticesItems[s + 7] = v1 * a + v2 * b + v3 * c; + if (twoColor) { + clippedVerticesItems[s + 8] = dark.r; + clippedVerticesItems[s + 9] = dark.g; + clippedVerticesItems[s + 10] = dark.b; + clippedVerticesItems[s + 11] = dark.a; + } + s += vertexSize; + } + s = clippedTriangles.length; + let clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3 * (clipOutputCount - 2)); + clipOutputCount--; + for (let ii = 1; ii < clipOutputCount; ii++) { + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = (index + ii); + clippedTrianglesItems[s + 2] = (index + ii + 1); + s += 3; + } + index += clipOutputCount + 1; + } + else { + let clippedVerticesItems = spine.Utils.setArraySize(clippedVertices, s + 3 * vertexSize); + clippedVerticesItems[s] = x1; + clippedVerticesItems[s + 1] = y1; + clippedVerticesItems[s + 2] = light.r; + clippedVerticesItems[s + 3] = light.g; + clippedVerticesItems[s + 4] = light.b; + clippedVerticesItems[s + 5] = light.a; + if (!twoColor) { + clippedVerticesItems[s + 6] = u1; + clippedVerticesItems[s + 7] = v1; + clippedVerticesItems[s + 8] = x2; + clippedVerticesItems[s + 9] = y2; + clippedVerticesItems[s + 10] = light.r; + clippedVerticesItems[s + 11] = light.g; + clippedVerticesItems[s + 12] = light.b; + clippedVerticesItems[s + 13] = light.a; + clippedVerticesItems[s + 14] = u2; + clippedVerticesItems[s + 15] = v2; + clippedVerticesItems[s + 16] = x3; + clippedVerticesItems[s + 17] = y3; + clippedVerticesItems[s + 18] = light.r; + clippedVerticesItems[s + 19] = light.g; + clippedVerticesItems[s + 20] = light.b; + clippedVerticesItems[s + 21] = light.a; + clippedVerticesItems[s + 22] = u3; + clippedVerticesItems[s + 23] = v3; + } + else { + clippedVerticesItems[s + 6] = u1; + clippedVerticesItems[s + 7] = v1; + clippedVerticesItems[s + 8] = dark.r; + clippedVerticesItems[s + 9] = dark.g; + clippedVerticesItems[s + 10] = dark.b; + clippedVerticesItems[s + 11] = dark.a; + clippedVerticesItems[s + 12] = x2; + clippedVerticesItems[s + 13] = y2; + clippedVerticesItems[s + 14] = light.r; + clippedVerticesItems[s + 15] = light.g; + clippedVerticesItems[s + 16] = light.b; + clippedVerticesItems[s + 17] = light.a; + clippedVerticesItems[s + 18] = u2; + clippedVerticesItems[s + 19] = v2; + clippedVerticesItems[s + 20] = dark.r; + clippedVerticesItems[s + 21] = dark.g; + clippedVerticesItems[s + 22] = dark.b; + clippedVerticesItems[s + 23] = dark.a; + clippedVerticesItems[s + 24] = x3; + clippedVerticesItems[s + 25] = y3; + clippedVerticesItems[s + 26] = light.r; + clippedVerticesItems[s + 27] = light.g; + clippedVerticesItems[s + 28] = light.b; + clippedVerticesItems[s + 29] = light.a; + clippedVerticesItems[s + 30] = u3; + clippedVerticesItems[s + 31] = v3; + clippedVerticesItems[s + 32] = dark.r; + clippedVerticesItems[s + 33] = dark.g; + clippedVerticesItems[s + 34] = dark.b; + clippedVerticesItems[s + 35] = dark.a; + } + s = clippedTriangles.length; + let clippedTrianglesItems = spine.Utils.setArraySize(clippedTriangles, s + 3); + clippedTrianglesItems[s] = index; + clippedTrianglesItems[s + 1] = (index + 1); + clippedTrianglesItems[s + 2] = (index + 2); + index += 3; + continue outer; + } + } + } + } + clip(x1, y1, x2, y2, x3, y3, clippingArea, output) { + let originalOutput = output; + let clipped = false; + let input = null; + if (clippingArea.length % 4 >= 2) { + input = output; + output = this.scratch; + } + else + input = this.scratch; + input.length = 0; + input.push(x1); + input.push(y1); + input.push(x2); + input.push(y2); + input.push(x3); + input.push(y3); + input.push(x1); + input.push(y1); + output.length = 0; + let clippingVertices = clippingArea; + let clippingVerticesLast = clippingArea.length - 4; + for (let i = 0;; i += 2) { + let edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1]; + let edgeX2 = clippingVertices[i + 2], edgeY2 = clippingVertices[i + 3]; + let deltaX = edgeX - edgeX2, deltaY = edgeY - edgeY2; + let inputVertices = input; + let inputVerticesLength = input.length - 2, outputStart = output.length; + for (let ii = 0; ii < inputVerticesLength; ii += 2) { + let inputX = inputVertices[ii], inputY = inputVertices[ii + 1]; + let inputX2 = inputVertices[ii + 2], inputY2 = inputVertices[ii + 3]; + let side2 = deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0; + if (deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0) { + if (side2) { + output.push(inputX2); + output.push(inputY2); + continue; + } + let c0 = inputY2 - inputY, c2 = inputX2 - inputX; + let s = c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY); + if (Math.abs(s) > 0.000001) { + let ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / s; + output.push(edgeX + (edgeX2 - edgeX) * ua); + output.push(edgeY + (edgeY2 - edgeY) * ua); + } + else { + output.push(edgeX); + output.push(edgeY); + } + } + else if (side2) { + let c0 = inputY2 - inputY, c2 = inputX2 - inputX; + let s = c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY); + if (Math.abs(s) > 0.000001) { + let ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / s; + output.push(edgeX + (edgeX2 - edgeX) * ua); + output.push(edgeY + (edgeY2 - edgeY) * ua); + } + else { + output.push(edgeX); + output.push(edgeY); + } + output.push(inputX2); + output.push(inputY2); + } + clipped = true; + } + if (outputStart == output.length) { + originalOutput.length = 0; + return true; + } + output.push(output[0]); + output.push(output[1]); + if (i == clippingVerticesLast) + break; + let temp = output; + output = input; + output.length = 0; + input = temp; + } + if (originalOutput != output) { + originalOutput.length = 0; + for (let i = 0, n = output.length - 2; i < n; i++) + originalOutput[i] = output[i]; + } + else + originalOutput.length = originalOutput.length - 2; + return clipped; + } + static makeClockwise(polygon) { + let vertices = polygon; + let verticeslength = polygon.length; + let area = vertices[verticeslength - 2] * vertices[1] - vertices[0] * vertices[verticeslength - 1], p1x = 0, p1y = 0, p2x = 0, p2y = 0; + for (let i = 0, n = verticeslength - 3; i < n; i += 2) { + p1x = vertices[i]; + p1y = vertices[i + 1]; + p2x = vertices[i + 2]; + p2y = vertices[i + 3]; + area += p1x * p2y - p2x * p1y; + } + if (area < 0) + return; + for (let i = 0, lastX = verticeslength - 2, n = verticeslength >> 1; i < n; i += 2) { + let x = vertices[i], y = vertices[i + 1]; + let other = lastX - i; + vertices[i] = vertices[other]; + vertices[i + 1] = vertices[other + 1]; + vertices[other] = x; + vertices[other + 1] = y; + } + } + } + spine.SkeletonClipping = SkeletonClipping; +})(spine || (spine = {})); +var spine; +(function (spine) { + class SkeletonData { + constructor() { + this.bones = new Array(); + this.slots = new Array(); + this.skins = new Array(); + this.events = new Array(); + this.animations = new Array(); + this.ikConstraints = new Array(); + this.transformConstraints = new Array(); + this.pathConstraints = new Array(); + this.fps = 0; + } + findBone(boneName) { + if (boneName == null) + throw new Error("boneName cannot be null."); + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (bone.name == boneName) + return bone; + } + return null; + } + findBoneIndex(boneName) { + if (boneName == null) + throw new Error("boneName cannot be null."); + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) + if (bones[i].name == boneName) + return i; + return -1; + } + findSlot(slotName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) { + let slot = slots[i]; + if (slot.name == slotName) + return slot; + } + return null; + } + findSlotIndex(slotName) { + if (slotName == null) + throw new Error("slotName cannot be null."); + let slots = this.slots; + for (let i = 0, n = slots.length; i < n; i++) + if (slots[i].name == slotName) + return i; + return -1; + } + findSkin(skinName) { + if (skinName == null) + throw new Error("skinName cannot be null."); + let skins = this.skins; + for (let i = 0, n = skins.length; i < n; i++) { + let skin = skins[i]; + if (skin.name == skinName) + return skin; + } + return null; + } + findEvent(eventDataName) { + if (eventDataName == null) + throw new Error("eventDataName cannot be null."); + let events = this.events; + for (let i = 0, n = events.length; i < n; i++) { + let event = events[i]; + if (event.name == eventDataName) + return event; + } + return null; + } + findAnimation(animationName) { + if (animationName == null) + throw new Error("animationName cannot be null."); + let animations = this.animations; + for (let i = 0, n = animations.length; i < n; i++) { + let animation = animations[i]; + if (animation.name == animationName) + return animation; + } + return null; + } + findIkConstraint(constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + let ikConstraints = this.ikConstraints; + for (let i = 0, n = ikConstraints.length; i < n; i++) { + let constraint = ikConstraints[i]; + if (constraint.name == constraintName) + return constraint; + } + return null; + } + findTransformConstraint(constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + let transformConstraints = this.transformConstraints; + for (let i = 0, n = transformConstraints.length; i < n; i++) { + let constraint = transformConstraints[i]; + if (constraint.name == constraintName) + return constraint; + } + return null; + } + findPathConstraint(constraintName) { + if (constraintName == null) + throw new Error("constraintName cannot be null."); + let pathConstraints = this.pathConstraints; + for (let i = 0, n = pathConstraints.length; i < n; i++) { + let constraint = pathConstraints[i]; + if (constraint.name == constraintName) + return constraint; + } + return null; + } + findPathConstraintIndex(pathConstraintName) { + if (pathConstraintName == null) + throw new Error("pathConstraintName cannot be null."); + let pathConstraints = this.pathConstraints; + for (let i = 0, n = pathConstraints.length; i < n; i++) + if (pathConstraints[i].name == pathConstraintName) + return i; + return -1; + } + } + spine.SkeletonData = SkeletonData; +})(spine || (spine = {})); +var spine; +(function (spine) { + class SkeletonJson { + constructor(attachmentLoader) { + this.scale = 1; + this.linkedMeshes = new Array(); + this.attachmentLoader = attachmentLoader; + } + readSkeletonData(json) { + let scale = this.scale; + let skeletonData = new spine.SkeletonData(); + let root = typeof (json) === "string" ? JSON.parse(json) : json; + let skeletonMap = root.skeleton; + if (skeletonMap != null) { + skeletonData.hash = skeletonMap.hash; + skeletonData.version = skeletonMap.spine; + if ("3.8.75" == skeletonData.version) + throw new Error("Unsupported skeleton data, please export with a newer version of Spine."); + skeletonData.x = skeletonMap.x; + skeletonData.y = skeletonMap.y; + skeletonData.width = skeletonMap.width; + skeletonData.height = skeletonMap.height; + skeletonData.fps = skeletonMap.fps; + skeletonData.imagesPath = skeletonMap.images; + } + if (root.bones) { + for (let i = 0; i < root.bones.length; i++) { + let boneMap = root.bones[i]; + let parent = null; + let parentName = this.getValue(boneMap, "parent", null); + if (parentName != null) { + parent = skeletonData.findBone(parentName); + if (parent == null) + throw new Error("Parent bone not found: " + parentName); + } + let data = new spine.BoneData(skeletonData.bones.length, boneMap.name, parent); + data.length = this.getValue(boneMap, "length", 0) * scale; + data.x = this.getValue(boneMap, "x", 0) * scale; + data.y = this.getValue(boneMap, "y", 0) * scale; + data.rotation = this.getValue(boneMap, "rotation", 0); + data.scaleX = this.getValue(boneMap, "scaleX", 1); + data.scaleY = this.getValue(boneMap, "scaleY", 1); + data.shearX = this.getValue(boneMap, "shearX", 0); + data.shearY = this.getValue(boneMap, "shearY", 0); + data.transformMode = SkeletonJson.transformModeFromString(this.getValue(boneMap, "transform", "normal")); + data.skinRequired = this.getValue(boneMap, "skin", false); + skeletonData.bones.push(data); + } + } + if (root.slots) { + for (let i = 0; i < root.slots.length; i++) { + let slotMap = root.slots[i]; + let slotName = slotMap.name; + let boneName = slotMap.bone; + let boneData = skeletonData.findBone(boneName); + if (boneData == null) + throw new Error("Slot bone not found: " + boneName); + let data = new spine.SlotData(skeletonData.slots.length, slotName, boneData); + let color = this.getValue(slotMap, "color", null); + if (color != null) + data.color.setFromString(color); + let dark = this.getValue(slotMap, "dark", null); + if (dark != null) { + data.darkColor = new spine.Color(1, 1, 1, 1); + data.darkColor.setFromString(dark); + } + data.attachmentName = this.getValue(slotMap, "attachment", null); + data.blendMode = SkeletonJson.blendModeFromString(this.getValue(slotMap, "blend", "normal")); + skeletonData.slots.push(data); + } + } + if (root.ik) { + for (let i = 0; i < root.ik.length; i++) { + let constraintMap = root.ik[i]; + let data = new spine.IkConstraintData(constraintMap.name); + data.order = this.getValue(constraintMap, "order", 0); + data.skinRequired = this.getValue(constraintMap, "skin", false); + for (let j = 0; j < constraintMap.bones.length; j++) { + let boneName = constraintMap.bones[j]; + let bone = skeletonData.findBone(boneName); + if (bone == null) + throw new Error("IK bone not found: " + boneName); + data.bones.push(bone); + } + let targetName = constraintMap.target; + data.target = skeletonData.findBone(targetName); + if (data.target == null) + throw new Error("IK target bone not found: " + targetName); + data.mix = this.getValue(constraintMap, "mix", 1); + data.softness = this.getValue(constraintMap, "softness", 0) * scale; + data.bendDirection = this.getValue(constraintMap, "bendPositive", true) ? 1 : -1; + data.compress = this.getValue(constraintMap, "compress", false); + data.stretch = this.getValue(constraintMap, "stretch", false); + data.uniform = this.getValue(constraintMap, "uniform", false); + skeletonData.ikConstraints.push(data); + } + } + if (root.transform) { + for (let i = 0; i < root.transform.length; i++) { + let constraintMap = root.transform[i]; + let data = new spine.TransformConstraintData(constraintMap.name); + data.order = this.getValue(constraintMap, "order", 0); + data.skinRequired = this.getValue(constraintMap, "skin", false); + for (let j = 0; j < constraintMap.bones.length; j++) { + let boneName = constraintMap.bones[j]; + let bone = skeletonData.findBone(boneName); + if (bone == null) + throw new Error("Transform constraint bone not found: " + boneName); + data.bones.push(bone); + } + let targetName = constraintMap.target; + data.target = skeletonData.findBone(targetName); + if (data.target == null) + throw new Error("Transform constraint target bone not found: " + targetName); + data.local = this.getValue(constraintMap, "local", false); + data.relative = this.getValue(constraintMap, "relative", false); + data.offsetRotation = this.getValue(constraintMap, "rotation", 0); + data.offsetX = this.getValue(constraintMap, "x", 0) * scale; + data.offsetY = this.getValue(constraintMap, "y", 0) * scale; + data.offsetScaleX = this.getValue(constraintMap, "scaleX", 0); + data.offsetScaleY = this.getValue(constraintMap, "scaleY", 0); + data.offsetShearY = this.getValue(constraintMap, "shearY", 0); + data.rotateMix = this.getValue(constraintMap, "rotateMix", 1); + data.translateMix = this.getValue(constraintMap, "translateMix", 1); + data.scaleMix = this.getValue(constraintMap, "scaleMix", 1); + data.shearMix = this.getValue(constraintMap, "shearMix", 1); + skeletonData.transformConstraints.push(data); + } + } + if (root.path) { + for (let i = 0; i < root.path.length; i++) { + let constraintMap = root.path[i]; + let data = new spine.PathConstraintData(constraintMap.name); + data.order = this.getValue(constraintMap, "order", 0); + data.skinRequired = this.getValue(constraintMap, "skin", false); + for (let j = 0; j < constraintMap.bones.length; j++) { + let boneName = constraintMap.bones[j]; + let bone = skeletonData.findBone(boneName); + if (bone == null) + throw new Error("Transform constraint bone not found: " + boneName); + data.bones.push(bone); + } + let targetName = constraintMap.target; + data.target = skeletonData.findSlot(targetName); + if (data.target == null) + throw new Error("Path target slot not found: " + targetName); + data.positionMode = SkeletonJson.positionModeFromString(this.getValue(constraintMap, "positionMode", "percent")); + data.spacingMode = SkeletonJson.spacingModeFromString(this.getValue(constraintMap, "spacingMode", "length")); + data.rotateMode = SkeletonJson.rotateModeFromString(this.getValue(constraintMap, "rotateMode", "tangent")); + data.offsetRotation = this.getValue(constraintMap, "rotation", 0); + data.position = this.getValue(constraintMap, "position", 0); + if (data.positionMode == spine.PositionMode.Fixed) + data.position *= scale; + data.spacing = this.getValue(constraintMap, "spacing", 0); + if (data.spacingMode == spine.SpacingMode.Length || data.spacingMode == spine.SpacingMode.Fixed) + data.spacing *= scale; + data.rotateMix = this.getValue(constraintMap, "rotateMix", 1); + data.translateMix = this.getValue(constraintMap, "translateMix", 1); + skeletonData.pathConstraints.push(data); + } + } + if (root.skins) { + for (let i = 0; i < root.skins.length; i++) { + let skinMap = root.skins[i]; + let skin = new spine.Skin(skinMap.name); + if (skinMap.bones) { + for (let ii = 0; ii < skinMap.bones.length; ii++) { + let bone = skeletonData.findBone(skinMap.bones[ii]); + if (bone == null) + throw new Error("Skin bone not found: " + skinMap.bones[i]); + skin.bones.push(bone); + } + } + if (skinMap.ik) { + for (let ii = 0; ii < skinMap.ik.length; ii++) { + let constraint = skeletonData.findIkConstraint(skinMap.ik[ii]); + if (constraint == null) + throw new Error("Skin IK constraint not found: " + skinMap.ik[i]); + skin.constraints.push(constraint); + } + } + if (skinMap.transform) { + for (let ii = 0; ii < skinMap.transform.length; ii++) { + let constraint = skeletonData.findTransformConstraint(skinMap.transform[ii]); + if (constraint == null) + throw new Error("Skin transform constraint not found: " + skinMap.transform[i]); + skin.constraints.push(constraint); + } + } + if (skinMap.path) { + for (let ii = 0; ii < skinMap.path.length; ii++) { + let constraint = skeletonData.findPathConstraint(skinMap.path[ii]); + if (constraint == null) + throw new Error("Skin path constraint not found: " + skinMap.path[i]); + skin.constraints.push(constraint); + } + } + for (let slotName in skinMap.attachments) { + let slot = skeletonData.findSlot(slotName); + if (slot == null) + throw new Error("Slot not found: " + slotName); + let slotMap = skinMap.attachments[slotName]; + for (let entryName in slotMap) { + let attachment = this.readAttachment(slotMap[entryName], skin, slot.index, entryName, skeletonData); + if (attachment != null) + skin.setAttachment(slot.index, entryName, attachment); + } + } + skeletonData.skins.push(skin); + if (skin.name == "default") + skeletonData.defaultSkin = skin; + } + } + for (let i = 0, n = this.linkedMeshes.length; i < n; i++) { + let linkedMesh = this.linkedMeshes[i]; + let skin = linkedMesh.skin == null ? skeletonData.defaultSkin : skeletonData.findSkin(linkedMesh.skin); + if (skin == null) + throw new Error("Skin not found: " + linkedMesh.skin); + let parent = skin.getAttachment(linkedMesh.slotIndex, linkedMesh.parent); + if (parent == null) + throw new Error("Parent mesh not found: " + linkedMesh.parent); + linkedMesh.mesh.deformAttachment = linkedMesh.inheritDeform ? parent : linkedMesh.mesh; + linkedMesh.mesh.setParentMesh(parent); + linkedMesh.mesh.updateUVs(); + } + this.linkedMeshes.length = 0; + if (root.events) { + for (let eventName in root.events) { + let eventMap = root.events[eventName]; + let data = new spine.EventData(eventName); + data.intValue = this.getValue(eventMap, "int", 0); + data.floatValue = this.getValue(eventMap, "float", 0); + data.stringValue = this.getValue(eventMap, "string", ""); + data.audioPath = this.getValue(eventMap, "audio", null); + if (data.audioPath != null) { + data.volume = this.getValue(eventMap, "volume", 1); + data.balance = this.getValue(eventMap, "balance", 0); + } + skeletonData.events.push(data); + } + } + if (root.animations) { + for (let animationName in root.animations) { + let animationMap = root.animations[animationName]; + this.readAnimation(animationMap, animationName, skeletonData); + } + } + return skeletonData; + } + readAttachment(map, skin, slotIndex, name, skeletonData) { + let scale = this.scale; + name = this.getValue(map, "name", name); + let type = this.getValue(map, "type", "region"); + switch (type) { + case "region": { + let path = this.getValue(map, "path", name); + let region = this.attachmentLoader.newRegionAttachment(skin, name, path); + if (region == null) + return null; + region.path = path; + region.x = this.getValue(map, "x", 0) * scale; + region.y = this.getValue(map, "y", 0) * scale; + region.scaleX = this.getValue(map, "scaleX", 1); + region.scaleY = this.getValue(map, "scaleY", 1); + region.rotation = this.getValue(map, "rotation", 0); + region.width = map.width * scale; + region.height = map.height * scale; + let color = this.getValue(map, "color", null); + if (color != null) + region.color.setFromString(color); + region.updateOffset(); + return region; + } + case "boundingbox": { + let box = this.attachmentLoader.newBoundingBoxAttachment(skin, name); + if (box == null) + return null; + this.readVertices(map, box, map.vertexCount << 1); + let color = this.getValue(map, "color", null); + if (color != null) + box.color.setFromString(color); + return box; + } + case "mesh": + case "linkedmesh": { + let path = this.getValue(map, "path", name); + let mesh = this.attachmentLoader.newMeshAttachment(skin, name, path); + if (mesh == null) + return null; + mesh.path = path; + let color = this.getValue(map, "color", null); + if (color != null) + mesh.color.setFromString(color); + mesh.width = this.getValue(map, "width", 0) * scale; + mesh.height = this.getValue(map, "height", 0) * scale; + let parent = this.getValue(map, "parent", null); + if (parent != null) { + this.linkedMeshes.push(new LinkedMesh(mesh, this.getValue(map, "skin", null), slotIndex, parent, this.getValue(map, "deform", true))); + return mesh; + } + let uvs = map.uvs; + this.readVertices(map, mesh, uvs.length); + mesh.triangles = map.triangles; + mesh.regionUVs = uvs; + mesh.updateUVs(); + mesh.edges = this.getValue(map, "edges", null); + mesh.hullLength = this.getValue(map, "hull", 0) * 2; + return mesh; + } + case "path": { + let path = this.attachmentLoader.newPathAttachment(skin, name); + if (path == null) + return null; + path.closed = this.getValue(map, "closed", false); + path.constantSpeed = this.getValue(map, "constantSpeed", true); + let vertexCount = map.vertexCount; + this.readVertices(map, path, vertexCount << 1); + let lengths = spine.Utils.newArray(vertexCount / 3, 0); + for (let i = 0; i < map.lengths.length; i++) + lengths[i] = map.lengths[i] * scale; + path.lengths = lengths; + let color = this.getValue(map, "color", null); + if (color != null) + path.color.setFromString(color); + return path; + } + case "point": { + let point = this.attachmentLoader.newPointAttachment(skin, name); + if (point == null) + return null; + point.x = this.getValue(map, "x", 0) * scale; + point.y = this.getValue(map, "y", 0) * scale; + point.rotation = this.getValue(map, "rotation", 0); + let color = this.getValue(map, "color", null); + if (color != null) + point.color.setFromString(color); + return point; + } + case "clipping": { + let clip = this.attachmentLoader.newClippingAttachment(skin, name); + if (clip == null) + return null; + let end = this.getValue(map, "end", null); + if (end != null) { + let slot = skeletonData.findSlot(end); + if (slot == null) + throw new Error("Clipping end slot not found: " + end); + clip.endSlot = slot; + } + let vertexCount = map.vertexCount; + this.readVertices(map, clip, vertexCount << 1); + let color = this.getValue(map, "color", null); + if (color != null) + clip.color.setFromString(color); + return clip; + } + } + return null; + } + readVertices(map, attachment, verticesLength) { + let scale = this.scale; + attachment.worldVerticesLength = verticesLength; + let vertices = map.vertices; + if (verticesLength == vertices.length) { + let scaledVertices = spine.Utils.toFloatArray(vertices); + if (scale != 1) { + for (let i = 0, n = vertices.length; i < n; i++) + scaledVertices[i] *= scale; + } + attachment.vertices = scaledVertices; + return; + } + let weights = new Array(); + let bones = new Array(); + for (let i = 0, n = vertices.length; i < n;) { + let boneCount = vertices[i++]; + bones.push(boneCount); + for (let nn = i + boneCount * 4; i < nn; i += 4) { + bones.push(vertices[i]); + weights.push(vertices[i + 1] * scale); + weights.push(vertices[i + 2] * scale); + weights.push(vertices[i + 3]); + } + } + attachment.bones = bones; + attachment.vertices = spine.Utils.toFloatArray(weights); + } + readAnimation(map, name, skeletonData) { + let scale = this.scale; + let timelines = new Array(); + let duration = 0; + if (map.slots) { + for (let slotName in map.slots) { + let slotMap = map.slots[slotName]; + let slotIndex = skeletonData.findSlotIndex(slotName); + if (slotIndex == -1) + throw new Error("Slot not found: " + slotName); + for (let timelineName in slotMap) { + let timelineMap = slotMap[timelineName]; + if (timelineName == "attachment") { + let timeline = new spine.AttachmentTimeline(timelineMap.length); + timeline.slotIndex = slotIndex; + let frameIndex = 0; + for (let i = 0; i < timelineMap.length; i++) { + let valueMap = timelineMap[i]; + timeline.setFrame(frameIndex++, this.getValue(valueMap, "time", 0), valueMap.name); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); + } + else if (timelineName == "color") { + let timeline = new spine.ColorTimeline(timelineMap.length); + timeline.slotIndex = slotIndex; + let frameIndex = 0; + for (let i = 0; i < timelineMap.length; i++) { + let valueMap = timelineMap[i]; + let color = new spine.Color(); + color.setFromString(valueMap.color); + timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), color.r, color.g, color.b, color.a); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.ColorTimeline.ENTRIES]); + } + else if (timelineName == "twoColor") { + let timeline = new spine.TwoColorTimeline(timelineMap.length); + timeline.slotIndex = slotIndex; + let frameIndex = 0; + for (let i = 0; i < timelineMap.length; i++) { + let valueMap = timelineMap[i]; + let light = new spine.Color(); + let dark = new spine.Color(); + light.setFromString(valueMap.light); + dark.setFromString(valueMap.dark); + timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), light.r, light.g, light.b, light.a, dark.r, dark.g, dark.b); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.TwoColorTimeline.ENTRIES]); + } + else + throw new Error("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"); + } + } + } + if (map.bones) { + for (let boneName in map.bones) { + let boneMap = map.bones[boneName]; + let boneIndex = skeletonData.findBoneIndex(boneName); + if (boneIndex == -1) + throw new Error("Bone not found: " + boneName); + for (let timelineName in boneMap) { + let timelineMap = boneMap[timelineName]; + if (timelineName === "rotate") { + let timeline = new spine.RotateTimeline(timelineMap.length); + timeline.boneIndex = boneIndex; + let frameIndex = 0; + for (let i = 0; i < timelineMap.length; i++) { + let valueMap = timelineMap[i]; + timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "angle", 0)); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.RotateTimeline.ENTRIES]); + } + else if (timelineName === "translate" || timelineName === "scale" || timelineName === "shear") { + let timeline = null; + let timelineScale = 1, defaultValue = 0; + if (timelineName === "scale") { + timeline = new spine.ScaleTimeline(timelineMap.length); + defaultValue = 1; + } + else if (timelineName === "shear") + timeline = new spine.ShearTimeline(timelineMap.length); + else { + timeline = new spine.TranslateTimeline(timelineMap.length); + timelineScale = scale; + } + timeline.boneIndex = boneIndex; + let frameIndex = 0; + for (let i = 0; i < timelineMap.length; i++) { + let valueMap = timelineMap[i]; + let x = this.getValue(valueMap, "x", defaultValue), y = this.getValue(valueMap, "y", defaultValue); + timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), x * timelineScale, y * timelineScale); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.TranslateTimeline.ENTRIES]); + } + else + throw new Error("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"); + } + } + } + if (map.ik) { + for (let constraintName in map.ik) { + let constraintMap = map.ik[constraintName]; + let constraint = skeletonData.findIkConstraint(constraintName); + let timeline = new spine.IkConstraintTimeline(constraintMap.length); + timeline.ikConstraintIndex = skeletonData.ikConstraints.indexOf(constraint); + let frameIndex = 0; + for (let i = 0; i < constraintMap.length; i++) { + let valueMap = constraintMap[i]; + timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "mix", 1), this.getValue(valueMap, "softness", 0) * scale, this.getValue(valueMap, "bendPositive", true) ? 1 : -1, this.getValue(valueMap, "compress", false), this.getValue(valueMap, "stretch", false)); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.IkConstraintTimeline.ENTRIES]); + } + } + if (map.transform) { + for (let constraintName in map.transform) { + let constraintMap = map.transform[constraintName]; + let constraint = skeletonData.findTransformConstraint(constraintName); + let timeline = new spine.TransformConstraintTimeline(constraintMap.length); + timeline.transformConstraintIndex = skeletonData.transformConstraints.indexOf(constraint); + let frameIndex = 0; + for (let i = 0; i < constraintMap.length; i++) { + let valueMap = constraintMap[i]; + timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1), this.getValue(valueMap, "scaleMix", 1), this.getValue(valueMap, "shearMix", 1)); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.TransformConstraintTimeline.ENTRIES]); + } + } + if (map.path) { + for (let constraintName in map.path) { + let constraintMap = map.path[constraintName]; + let index = skeletonData.findPathConstraintIndex(constraintName); + if (index == -1) + throw new Error("Path constraint not found: " + constraintName); + let data = skeletonData.pathConstraints[index]; + for (let timelineName in constraintMap) { + let timelineMap = constraintMap[timelineName]; + if (timelineName === "position" || timelineName === "spacing") { + let timeline = null; + let timelineScale = 1; + if (timelineName === "spacing") { + timeline = new spine.PathConstraintSpacingTimeline(timelineMap.length); + if (data.spacingMode == spine.SpacingMode.Length || data.spacingMode == spine.SpacingMode.Fixed) + timelineScale = scale; + } + else { + timeline = new spine.PathConstraintPositionTimeline(timelineMap.length); + if (data.positionMode == spine.PositionMode.Fixed) + timelineScale = scale; + } + timeline.pathConstraintIndex = index; + let frameIndex = 0; + for (let i = 0; i < timelineMap.length; i++) { + let valueMap = timelineMap[i]; + timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, timelineName, 0) * timelineScale); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.PathConstraintPositionTimeline.ENTRIES]); + } + else if (timelineName === "mix") { + let timeline = new spine.PathConstraintMixTimeline(timelineMap.length); + timeline.pathConstraintIndex = index; + let frameIndex = 0; + for (let i = 0; i < timelineMap.length; i++) { + let valueMap = timelineMap[i]; + timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), this.getValue(valueMap, "rotateMix", 1), this.getValue(valueMap, "translateMix", 1)); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[(timeline.getFrameCount() - 1) * spine.PathConstraintMixTimeline.ENTRIES]); + } + } + } + } + if (map.deform) { + for (let deformName in map.deform) { + let deformMap = map.deform[deformName]; + let skin = skeletonData.findSkin(deformName); + if (skin == null) + throw new Error("Skin not found: " + deformName); + for (let slotName in deformMap) { + let slotMap = deformMap[slotName]; + let slotIndex = skeletonData.findSlotIndex(slotName); + if (slotIndex == -1) + throw new Error("Slot not found: " + slotMap.name); + for (let timelineName in slotMap) { + let timelineMap = slotMap[timelineName]; + let attachment = skin.getAttachment(slotIndex, timelineName); + if (attachment == null) + throw new Error("Deform attachment not found: " + timelineMap.name); + let weighted = attachment.bones != null; + let vertices = attachment.vertices; + let deformLength = weighted ? vertices.length / 3 * 2 : vertices.length; + let timeline = new spine.DeformTimeline(timelineMap.length); + timeline.slotIndex = slotIndex; + timeline.attachment = attachment; + let frameIndex = 0; + for (let j = 0; j < timelineMap.length; j++) { + let valueMap = timelineMap[j]; + let deform; + let verticesValue = this.getValue(valueMap, "vertices", null); + if (verticesValue == null) + deform = weighted ? spine.Utils.newFloatArray(deformLength) : vertices; + else { + deform = spine.Utils.newFloatArray(deformLength); + let start = this.getValue(valueMap, "offset", 0); + spine.Utils.arrayCopy(verticesValue, 0, deform, start, verticesValue.length); + if (scale != 1) { + for (let i = start, n = i + verticesValue.length; i < n; i++) + deform[i] *= scale; + } + if (!weighted) { + for (let i = 0; i < deformLength; i++) + deform[i] += vertices[i]; + } + } + timeline.setFrame(frameIndex, this.getValue(valueMap, "time", 0), deform); + this.readCurve(valueMap, timeline, frameIndex); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); + } + } + } + } + let drawOrderNode = map.drawOrder; + if (drawOrderNode == null) + drawOrderNode = map.draworder; + if (drawOrderNode != null) { + let timeline = new spine.DrawOrderTimeline(drawOrderNode.length); + let slotCount = skeletonData.slots.length; + let frameIndex = 0; + for (let j = 0; j < drawOrderNode.length; j++) { + let drawOrderMap = drawOrderNode[j]; + let drawOrder = null; + let offsets = this.getValue(drawOrderMap, "offsets", null); + if (offsets != null) { + drawOrder = spine.Utils.newArray(slotCount, -1); + let unchanged = spine.Utils.newArray(slotCount - offsets.length, 0); + let originalIndex = 0, unchangedIndex = 0; + for (let i = 0; i < offsets.length; i++) { + let offsetMap = offsets[i]; + let slotIndex = skeletonData.findSlotIndex(offsetMap.slot); + if (slotIndex == -1) + throw new Error("Slot not found: " + offsetMap.slot); + while (originalIndex != slotIndex) + unchanged[unchangedIndex++] = originalIndex++; + drawOrder[originalIndex + offsetMap.offset] = originalIndex++; + } + while (originalIndex < slotCount) + unchanged[unchangedIndex++] = originalIndex++; + for (let i = slotCount - 1; i >= 0; i--) + if (drawOrder[i] == -1) + drawOrder[i] = unchanged[--unchangedIndex]; + } + timeline.setFrame(frameIndex++, this.getValue(drawOrderMap, "time", 0), drawOrder); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); + } + if (map.events) { + let timeline = new spine.EventTimeline(map.events.length); + let frameIndex = 0; + for (let i = 0; i < map.events.length; i++) { + let eventMap = map.events[i]; + let eventData = skeletonData.findEvent(eventMap.name); + if (eventData == null) + throw new Error("Event not found: " + eventMap.name); + let event = new spine.Event(spine.Utils.toSinglePrecision(this.getValue(eventMap, "time", 0)), eventData); + event.intValue = this.getValue(eventMap, "int", eventData.intValue); + event.floatValue = this.getValue(eventMap, "float", eventData.floatValue); + event.stringValue = this.getValue(eventMap, "string", eventData.stringValue); + if (event.data.audioPath != null) { + event.volume = this.getValue(eventMap, "volume", 1); + event.balance = this.getValue(eventMap, "balance", 0); + } + timeline.setFrame(frameIndex++, event); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); + } + if (isNaN(duration)) { + throw new Error("Error while parsing animation, duration is NaN"); + } + skeletonData.animations.push(new spine.Animation(name, timelines, duration)); + } + readCurve(map, timeline, frameIndex) { + if (!map.hasOwnProperty("curve")) + return; + if (map.curve == "stepped") + timeline.setStepped(frameIndex); + else { + let curve = map.curve; + timeline.setCurve(frameIndex, curve, this.getValue(map, "c2", 0), this.getValue(map, "c3", 1), this.getValue(map, "c4", 1)); + } + } + getValue(map, prop, defaultValue) { + return map[prop] !== undefined ? map[prop] : defaultValue; + } + static blendModeFromString(str) { + str = str.toLowerCase(); + if (str == "normal") + return spine.BlendMode.Normal; + if (str == "additive") + return spine.BlendMode.Additive; + if (str == "multiply") + return spine.BlendMode.Multiply; + if (str == "screen") + return spine.BlendMode.Screen; + throw new Error(`Unknown blend mode: ${str}`); + } + static positionModeFromString(str) { + str = str.toLowerCase(); + if (str == "fixed") + return spine.PositionMode.Fixed; + if (str == "percent") + return spine.PositionMode.Percent; + throw new Error(`Unknown position mode: ${str}`); + } + static spacingModeFromString(str) { + str = str.toLowerCase(); + if (str == "length") + return spine.SpacingMode.Length; + if (str == "fixed") + return spine.SpacingMode.Fixed; + if (str == "percent") + return spine.SpacingMode.Percent; + throw new Error(`Unknown position mode: ${str}`); + } + static rotateModeFromString(str) { + str = str.toLowerCase(); + if (str == "tangent") + return spine.RotateMode.Tangent; + if (str == "chain") + return spine.RotateMode.Chain; + if (str == "chainscale") + return spine.RotateMode.ChainScale; + throw new Error(`Unknown rotate mode: ${str}`); + } + static transformModeFromString(str) { + str = str.toLowerCase(); + if (str == "normal") + return spine.TransformMode.Normal; + if (str == "onlytranslation") + return spine.TransformMode.OnlyTranslation; + if (str == "norotationorreflection") + return spine.TransformMode.NoRotationOrReflection; + if (str == "noscale") + return spine.TransformMode.NoScale; + if (str == "noscaleorreflection") + return spine.TransformMode.NoScaleOrReflection; + throw new Error(`Unknown transform mode: ${str}`); + } + } + spine.SkeletonJson = SkeletonJson; + class LinkedMesh { + constructor(mesh, skin, slotIndex, parent, inheritDeform) { + this.mesh = mesh; + this.skin = skin; + this.slotIndex = slotIndex; + this.parent = parent; + this.inheritDeform = inheritDeform; + } + } +})(spine || (spine = {})); +var spine; +(function (spine) { + class SkinEntry { + constructor(slotIndex, name, attachment) { + this.slotIndex = slotIndex; + this.name = name; + this.attachment = attachment; + } + } + spine.SkinEntry = SkinEntry; + class Skin { + constructor(name) { + this.attachments = new Array(); + this.bones = Array(); + this.constraints = new Array(); + if (name == null) + throw new Error("name cannot be null."); + this.name = name; + } + setAttachment(slotIndex, name, attachment) { + if (attachment == null) + throw new Error("attachment cannot be null."); + let attachments = this.attachments; + if (slotIndex >= attachments.length) + attachments.length = slotIndex + 1; + if (!attachments[slotIndex]) + attachments[slotIndex] = {}; + attachments[slotIndex][name] = attachment; + } + addSkin(skin) { + for (let i = 0; i < skin.bones.length; i++) { + let bone = skin.bones[i]; + let contained = false; + for (let j = 0; j < this.bones.length; j++) { + if (this.bones[j] == bone) { + contained = true; + break; + } + } + if (!contained) + this.bones.push(bone); + } + for (let i = 0; i < skin.constraints.length; i++) { + let constraint = skin.constraints[i]; + let contained = false; + for (let j = 0; j < this.constraints.length; j++) { + if (this.constraints[j] == constraint) { + contained = true; + break; + } + } + if (!contained) + this.constraints.push(constraint); + } + let attachments = skin.getAttachments(); + for (let i = 0; i < attachments.length; i++) { + var attachment = attachments[i]; + this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); + } + } + copySkin(skin) { + for (let i = 0; i < skin.bones.length; i++) { + let bone = skin.bones[i]; + let contained = false; + for (let j = 0; j < this.bones.length; j++) { + if (this.bones[j] == bone) { + contained = true; + break; + } + } + if (!contained) + this.bones.push(bone); + } + for (let i = 0; i < skin.constraints.length; i++) { + let constraint = skin.constraints[i]; + let contained = false; + for (let j = 0; j < this.constraints.length; j++) { + if (this.constraints[j] == constraint) { + contained = true; + break; + } + } + if (!contained) + this.constraints.push(constraint); + } + let attachments = skin.getAttachments(); + for (let i = 0; i < attachments.length; i++) { + var attachment = attachments[i]; + if (attachment.attachment == null) + continue; + if (attachment.attachment instanceof spine.MeshAttachment) { + attachment.attachment = attachment.attachment.newLinkedMesh(); + this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); + } + else { + attachment.attachment = attachment.attachment.copy(); + this.setAttachment(attachment.slotIndex, attachment.name, attachment.attachment); + } + } + } + getAttachment(slotIndex, name) { + let dictionary = this.attachments[slotIndex]; + return dictionary ? dictionary[name] : null; + } + removeAttachment(slotIndex, name) { + let dictionary = this.attachments[slotIndex]; + if (dictionary) + dictionary[name] = null; + } + getAttachments() { + let entries = new Array(); + for (var i = 0; i < this.attachments.length; i++) { + let slotAttachments = this.attachments[i]; + if (slotAttachments) { + for (let name in slotAttachments) { + let attachment = slotAttachments[name]; + if (attachment) + entries.push(new SkinEntry(i, name, attachment)); + } + } + } + return entries; + } + getAttachmentsForSlot(slotIndex, attachments) { + let slotAttachments = this.attachments[slotIndex]; + if (slotAttachments) { + for (let name in slotAttachments) { + let attachment = slotAttachments[name]; + if (attachment) + attachments.push(new SkinEntry(slotIndex, name, attachment)); + } + } + } + clear() { + this.attachments.length = 0; + this.bones.length = 0; + this.constraints.length = 0; + } + attachAll(skeleton, oldSkin) { + let slotIndex = 0; + for (let i = 0; i < skeleton.slots.length; i++) { + let slot = skeleton.slots[i]; + let slotAttachment = slot.getAttachment(); + if (slotAttachment && slotIndex < oldSkin.attachments.length) { + let dictionary = oldSkin.attachments[slotIndex]; + for (let key in dictionary) { + let skinAttachment = dictionary[key]; + if (slotAttachment == skinAttachment) { + let attachment = this.getAttachment(slotIndex, key); + if (attachment != null) + slot.setAttachment(attachment); + break; + } + } + } + slotIndex++; + } + } + } + spine.Skin = Skin; +})(spine || (spine = {})); +var spine; +(function (spine) { + class Slot { + constructor(data, bone) { + this.deform = new Array(); + if (data == null) + throw new Error("data cannot be null."); + if (bone == null) + throw new Error("bone cannot be null."); + this.data = data; + this.bone = bone; + this.color = new spine.Color(); + this.darkColor = data.darkColor == null ? null : new spine.Color(); + this.setToSetupPose(); + } + getSkeleton() { + return this.bone.skeleton; + } + getAttachment() { + return this.attachment; + } + setAttachment(attachment) { + if (this.attachment == attachment) + return; + this.attachment = attachment; + this.attachmentTime = this.bone.skeleton.time; + this.deform.length = 0; + } + setAttachmentTime(time) { + this.attachmentTime = this.bone.skeleton.time - time; + } + getAttachmentTime() { + return this.bone.skeleton.time - this.attachmentTime; + } + setToSetupPose() { + this.color.setFromColor(this.data.color); + if (this.darkColor != null) + this.darkColor.setFromColor(this.data.darkColor); + if (this.data.attachmentName == null) + this.attachment = null; + else { + this.attachment = null; + this.setAttachment(this.bone.skeleton.getAttachment(this.data.index, this.data.attachmentName)); + } + } + } + spine.Slot = Slot; +})(spine || (spine = {})); +var spine; +(function (spine) { + class SlotData { + constructor(index, name, boneData) { + this.color = new spine.Color(1, 1, 1, 1); + if (index < 0) + throw new Error("index must be >= 0."); + if (name == null) + throw new Error("name cannot be null."); + if (boneData == null) + throw new Error("boneData cannot be null."); + this.index = index; + this.name = name; + this.boneData = boneData; + } + } + spine.SlotData = SlotData; +})(spine || (spine = {})); +var spine; +(function (spine) { + class Texture { + constructor(image) { + this._image = image; + } + getImage() { + return this._image; + } + static filterFromString(text) { + switch (text.toLowerCase()) { + case "nearest": return TextureFilter.Nearest; + case "linear": return TextureFilter.Linear; + case "mipmap": return TextureFilter.MipMap; + case "mipmapnearestnearest": return TextureFilter.MipMapNearestNearest; + case "mipmaplinearnearest": return TextureFilter.MipMapLinearNearest; + case "mipmapnearestlinear": return TextureFilter.MipMapNearestLinear; + case "mipmaplinearlinear": return TextureFilter.MipMapLinearLinear; + default: throw new Error(`Unknown texture filter ${text}`); + } + } + static wrapFromString(text) { + switch (text.toLowerCase()) { + case "mirroredtepeat": return TextureWrap.MirroredRepeat; + case "clamptoedge": return TextureWrap.ClampToEdge; + case "repeat": return TextureWrap.Repeat; + default: throw new Error(`Unknown texture wrap ${text}`); + } + } + } + spine.Texture = Texture; + let TextureFilter; + (function (TextureFilter) { + TextureFilter[TextureFilter["Nearest"] = 9728] = "Nearest"; + TextureFilter[TextureFilter["Linear"] = 9729] = "Linear"; + TextureFilter[TextureFilter["MipMap"] = 9987] = "MipMap"; + TextureFilter[TextureFilter["MipMapNearestNearest"] = 9984] = "MipMapNearestNearest"; + TextureFilter[TextureFilter["MipMapLinearNearest"] = 9985] = "MipMapLinearNearest"; + TextureFilter[TextureFilter["MipMapNearestLinear"] = 9986] = "MipMapNearestLinear"; + TextureFilter[TextureFilter["MipMapLinearLinear"] = 9987] = "MipMapLinearLinear"; + })(TextureFilter = spine.TextureFilter || (spine.TextureFilter = {})); + let TextureWrap; + (function (TextureWrap) { + TextureWrap[TextureWrap["MirroredRepeat"] = 33648] = "MirroredRepeat"; + TextureWrap[TextureWrap["ClampToEdge"] = 33071] = "ClampToEdge"; + TextureWrap[TextureWrap["Repeat"] = 10497] = "Repeat"; + })(TextureWrap = spine.TextureWrap || (spine.TextureWrap = {})); + class TextureRegion { + constructor() { + this.u = 0; + this.v = 0; + this.u2 = 0; + this.v2 = 0; + this.width = 0; + this.height = 0; + this.rotate = false; + this.offsetX = 0; + this.offsetY = 0; + this.originalWidth = 0; + this.originalHeight = 0; + } + } + spine.TextureRegion = TextureRegion; + class FakeTexture extends Texture { + setFilters(minFilter, magFilter) { } + setWraps(uWrap, vWrap) { } + dispose() { } + } + spine.FakeTexture = FakeTexture; +})(spine || (spine = {})); +var spine; +(function (spine) { + class TextureAtlas { + constructor(atlasText, textureLoader) { + this.pages = new Array(); + this.regions = new Array(); + this.load(atlasText, textureLoader); + } + load(atlasText, textureLoader) { + if (textureLoader == null) + throw new Error("textureLoader cannot be null."); + let reader = new TextureAtlasReader(atlasText); + let tuple = new Array(4); + let page = null; + while (true) { + let line = reader.readLine(); + if (line == null) + break; + line = line.trim(); + if (line.length == 0) + page = null; + else if (!page) { + page = new TextureAtlasPage(); + page.name = line; + if (reader.readTuple(tuple) == 2) { + page.width = parseInt(tuple[0]); + page.height = parseInt(tuple[1]); + reader.readTuple(tuple); + } + reader.readTuple(tuple); + page.minFilter = spine.Texture.filterFromString(tuple[0]); + page.magFilter = spine.Texture.filterFromString(tuple[1]); + let direction = reader.readValue(); + page.uWrap = spine.TextureWrap.ClampToEdge; + page.vWrap = spine.TextureWrap.ClampToEdge; + if (direction == "x") + page.uWrap = spine.TextureWrap.Repeat; + else if (direction == "y") + page.vWrap = spine.TextureWrap.Repeat; + else if (direction == "xy") + page.uWrap = page.vWrap = spine.TextureWrap.Repeat; + page.texture = textureLoader(line); + page.texture.setFilters(page.minFilter, page.magFilter); + page.texture.setWraps(page.uWrap, page.vWrap); + page.width = page.texture.getImage().width; + page.height = page.texture.getImage().height; + this.pages.push(page); + } + else { + let region = new TextureAtlasRegion(); + region.name = line; + region.page = page; + let rotateValue = reader.readValue(); + if (rotateValue.toLocaleLowerCase() == "true") { + region.degrees = 90; + } + else if (rotateValue.toLocaleLowerCase() == "false") { + region.degrees = 0; + } + else { + region.degrees = parseFloat(rotateValue); + } + region.rotate = region.degrees == 90; + reader.readTuple(tuple); + let x = parseInt(tuple[0]); + let y = parseInt(tuple[1]); + reader.readTuple(tuple); + let width = parseInt(tuple[0]); + let height = parseInt(tuple[1]); + region.u = x / page.width; + region.v = y / page.height; + if (region.rotate) { + region.u2 = (x + height) / page.width; + region.v2 = (y + width) / page.height; + } + else { + region.u2 = (x + width) / page.width; + region.v2 = (y + height) / page.height; + } + region.x = x; + region.y = y; + region.width = Math.abs(width); + region.height = Math.abs(height); + if (reader.readTuple(tuple) == 4) { + if (reader.readTuple(tuple) == 4) { + reader.readTuple(tuple); + } + } + region.originalWidth = parseInt(tuple[0]); + region.originalHeight = parseInt(tuple[1]); + reader.readTuple(tuple); + region.offsetX = parseInt(tuple[0]); + region.offsetY = parseInt(tuple[1]); + region.index = parseInt(reader.readValue()); + region.texture = page.texture; + this.regions.push(region); + } + } + } + findRegion(name) { + for (let i = 0; i < this.regions.length; i++) { + if (this.regions[i].name == name) { + return this.regions[i]; + } + } + return null; + } + dispose() { + for (let i = 0; i < this.pages.length; i++) { + this.pages[i].texture.dispose(); + } + } + } + spine.TextureAtlas = TextureAtlas; + class TextureAtlasReader { + constructor(text) { + this.index = 0; + this.lines = text.split(/\r\n|\r|\n/); + } + readLine() { + if (this.index >= this.lines.length) + return null; + return this.lines[this.index++]; + } + readValue() { + let line = this.readLine(); + let colon = line.indexOf(":"); + if (colon == -1) + throw new Error("Invalid line: " + line); + return line.substring(colon + 1).trim(); + } + readTuple(tuple) { + let line = this.readLine(); + let colon = line.indexOf(":"); + if (colon == -1) + throw new Error("Invalid line: " + line); + let i = 0, lastMatch = colon + 1; + for (; i < 3; i++) { + let comma = line.indexOf(",", lastMatch); + if (comma == -1) + break; + tuple[i] = line.substr(lastMatch, comma - lastMatch).trim(); + lastMatch = comma + 1; + } + tuple[i] = line.substring(lastMatch).trim(); + return i + 1; + } + } + class TextureAtlasPage { + } + spine.TextureAtlasPage = TextureAtlasPage; + class TextureAtlasRegion extends spine.TextureRegion { + } + spine.TextureAtlasRegion = TextureAtlasRegion; +})(spine || (spine = {})); +var spine; +(function (spine) { + class TransformConstraint { + constructor(data, skeleton) { + this.rotateMix = 0; + this.translateMix = 0; + this.scaleMix = 0; + this.shearMix = 0; + this.temp = new spine.Vector2(); + this.active = false; + if (data == null) + throw new Error("data cannot be null."); + if (skeleton == null) + throw new Error("skeleton cannot be null."); + this.data = data; + this.rotateMix = data.rotateMix; + this.translateMix = data.translateMix; + this.scaleMix = data.scaleMix; + this.shearMix = data.shearMix; + this.bones = new Array(); + for (let i = 0; i < data.bones.length; i++) + this.bones.push(skeleton.findBone(data.bones[i].name)); + this.target = skeleton.findBone(data.target.name); + } + isActive() { + return this.active; + } + apply() { + this.update(); + } + update() { + if (this.data.local) { + if (this.data.relative) + this.applyRelativeLocal(); + else + this.applyAbsoluteLocal(); + } + else { + if (this.data.relative) + this.applyRelativeWorld(); + else + this.applyAbsoluteWorld(); + } + } + applyAbsoluteWorld() { + let rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + let target = this.target; + let ta = target.a, tb = target.b, tc = target.c, td = target.d; + let degRadReflect = ta * td - tb * tc > 0 ? spine.MathUtils.degRad : -spine.MathUtils.degRad; + let offsetRotation = this.data.offsetRotation * degRadReflect; + let offsetShearY = this.data.offsetShearY * degRadReflect; + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + let modified = false; + if (rotateMix != 0) { + let a = bone.a, b = bone.b, c = bone.c, d = bone.d; + let r = Math.atan2(tc, ta) - Math.atan2(c, a) + offsetRotation; + if (r > spine.MathUtils.PI) + r -= spine.MathUtils.PI2; + else if (r < -spine.MathUtils.PI) + r += spine.MathUtils.PI2; + r *= rotateMix; + let cos = Math.cos(r), sin = Math.sin(r); + bone.a = cos * a - sin * c; + bone.b = cos * b - sin * d; + bone.c = sin * a + cos * c; + bone.d = sin * b + cos * d; + modified = true; + } + if (translateMix != 0) { + let temp = this.temp; + target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); + bone.worldX += (temp.x - bone.worldX) * translateMix; + bone.worldY += (temp.y - bone.worldY) * translateMix; + modified = true; + } + if (scaleMix > 0) { + let s = Math.sqrt(bone.a * bone.a + bone.c * bone.c); + let ts = Math.sqrt(ta * ta + tc * tc); + if (s > 0.00001) + s = (s + (ts - s + this.data.offsetScaleX) * scaleMix) / s; + bone.a *= s; + bone.c *= s; + s = Math.sqrt(bone.b * bone.b + bone.d * bone.d); + ts = Math.sqrt(tb * tb + td * td); + if (s > 0.00001) + s = (s + (ts - s + this.data.offsetScaleY) * scaleMix) / s; + bone.b *= s; + bone.d *= s; + modified = true; + } + if (shearMix > 0) { + let b = bone.b, d = bone.d; + let by = Math.atan2(d, b); + let r = Math.atan2(td, tb) - Math.atan2(tc, ta) - (by - Math.atan2(bone.c, bone.a)); + if (r > spine.MathUtils.PI) + r -= spine.MathUtils.PI2; + else if (r < -spine.MathUtils.PI) + r += spine.MathUtils.PI2; + r = by + (r + offsetShearY) * shearMix; + let s = Math.sqrt(b * b + d * d); + bone.b = Math.cos(r) * s; + bone.d = Math.sin(r) * s; + modified = true; + } + if (modified) + bone.appliedValid = false; + } + } + applyRelativeWorld() { + let rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + let target = this.target; + let ta = target.a, tb = target.b, tc = target.c, td = target.d; + let degRadReflect = ta * td - tb * tc > 0 ? spine.MathUtils.degRad : -spine.MathUtils.degRad; + let offsetRotation = this.data.offsetRotation * degRadReflect, offsetShearY = this.data.offsetShearY * degRadReflect; + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + let modified = false; + if (rotateMix != 0) { + let a = bone.a, b = bone.b, c = bone.c, d = bone.d; + let r = Math.atan2(tc, ta) + offsetRotation; + if (r > spine.MathUtils.PI) + r -= spine.MathUtils.PI2; + else if (r < -spine.MathUtils.PI) + r += spine.MathUtils.PI2; + r *= rotateMix; + let cos = Math.cos(r), sin = Math.sin(r); + bone.a = cos * a - sin * c; + bone.b = cos * b - sin * d; + bone.c = sin * a + cos * c; + bone.d = sin * b + cos * d; + modified = true; + } + if (translateMix != 0) { + let temp = this.temp; + target.localToWorld(temp.set(this.data.offsetX, this.data.offsetY)); + bone.worldX += temp.x * translateMix; + bone.worldY += temp.y * translateMix; + modified = true; + } + if (scaleMix > 0) { + let s = (Math.sqrt(ta * ta + tc * tc) - 1 + this.data.offsetScaleX) * scaleMix + 1; + bone.a *= s; + bone.c *= s; + s = (Math.sqrt(tb * tb + td * td) - 1 + this.data.offsetScaleY) * scaleMix + 1; + bone.b *= s; + bone.d *= s; + modified = true; + } + if (shearMix > 0) { + let r = Math.atan2(td, tb) - Math.atan2(tc, ta); + if (r > spine.MathUtils.PI) + r -= spine.MathUtils.PI2; + else if (r < -spine.MathUtils.PI) + r += spine.MathUtils.PI2; + let b = bone.b, d = bone.d; + r = Math.atan2(d, b) + (r - spine.MathUtils.PI / 2 + offsetShearY) * shearMix; + let s = Math.sqrt(b * b + d * d); + bone.b = Math.cos(r) * s; + bone.d = Math.sin(r) * s; + modified = true; + } + if (modified) + bone.appliedValid = false; + } + } + applyAbsoluteLocal() { + let rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + let target = this.target; + if (!target.appliedValid) + target.updateAppliedTransform(); + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (!bone.appliedValid) + bone.updateAppliedTransform(); + let rotation = bone.arotation; + if (rotateMix != 0) { + let r = target.arotation - rotation + this.data.offsetRotation; + r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; + rotation += r * rotateMix; + } + let x = bone.ax, y = bone.ay; + if (translateMix != 0) { + x += (target.ax - x + this.data.offsetX) * translateMix; + y += (target.ay - y + this.data.offsetY) * translateMix; + } + let scaleX = bone.ascaleX, scaleY = bone.ascaleY; + if (scaleMix != 0) { + if (scaleX > 0.00001) + scaleX = (scaleX + (target.ascaleX - scaleX + this.data.offsetScaleX) * scaleMix) / scaleX; + if (scaleY > 0.00001) + scaleY = (scaleY + (target.ascaleY - scaleY + this.data.offsetScaleY) * scaleMix) / scaleY; + } + let shearY = bone.ashearY; + if (shearMix != 0) { + let r = target.ashearY - shearY + this.data.offsetShearY; + r -= (16384 - ((16384.499999999996 - r / 360) | 0)) * 360; + bone.shearY += r * shearMix; + } + bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); + } + } + applyRelativeLocal() { + let rotateMix = this.rotateMix, translateMix = this.translateMix, scaleMix = this.scaleMix, shearMix = this.shearMix; + let target = this.target; + if (!target.appliedValid) + target.updateAppliedTransform(); + let bones = this.bones; + for (let i = 0, n = bones.length; i < n; i++) { + let bone = bones[i]; + if (!bone.appliedValid) + bone.updateAppliedTransform(); + let rotation = bone.arotation; + if (rotateMix != 0) + rotation += (target.arotation + this.data.offsetRotation) * rotateMix; + let x = bone.ax, y = bone.ay; + if (translateMix != 0) { + x += (target.ax + this.data.offsetX) * translateMix; + y += (target.ay + this.data.offsetY) * translateMix; + } + let scaleX = bone.ascaleX, scaleY = bone.ascaleY; + if (scaleMix != 0) { + if (scaleX > 0.00001) + scaleX *= ((target.ascaleX - 1 + this.data.offsetScaleX) * scaleMix) + 1; + if (scaleY > 0.00001) + scaleY *= ((target.ascaleY - 1 + this.data.offsetScaleY) * scaleMix) + 1; + } + let shearY = bone.ashearY; + if (shearMix != 0) + shearY += (target.ashearY + this.data.offsetShearY) * shearMix; + bone.updateWorldTransformWith(x, y, rotation, scaleX, scaleY, bone.ashearX, shearY); + } + } + } + spine.TransformConstraint = TransformConstraint; +})(spine || (spine = {})); +var spine; +(function (spine) { + class TransformConstraintData extends spine.ConstraintData { + constructor(name) { + super(name, 0, false); + this.bones = new Array(); + this.rotateMix = 0; + this.translateMix = 0; + this.scaleMix = 0; + this.shearMix = 0; + this.offsetRotation = 0; + this.offsetX = 0; + this.offsetY = 0; + this.offsetScaleX = 0; + this.offsetScaleY = 0; + this.offsetShearY = 0; + this.relative = false; + this.local = false; + } + } + spine.TransformConstraintData = TransformConstraintData; +})(spine || (spine = {})); +var spine; +(function (spine) { + class Triangulator { + constructor() { + this.convexPolygons = new Array(); + this.convexPolygonsIndices = new Array(); + this.indicesArray = new Array(); + this.isConcaveArray = new Array(); + this.triangles = new Array(); + this.polygonPool = new spine.Pool(() => { + return new Array(); + }); + this.polygonIndicesPool = new spine.Pool(() => { + return new Array(); + }); + } + triangulate(verticesArray) { + let vertices = verticesArray; + let vertexCount = verticesArray.length >> 1; + let indices = this.indicesArray; + indices.length = 0; + for (let i = 0; i < vertexCount; i++) + indices[i] = i; + let isConcave = this.isConcaveArray; + isConcave.length = 0; + for (let i = 0, n = vertexCount; i < n; ++i) + isConcave[i] = Triangulator.isConcave(i, vertexCount, vertices, indices); + let triangles = this.triangles; + triangles.length = 0; + while (vertexCount > 3) { + let previous = vertexCount - 1, i = 0, next = 1; + while (true) { + outer: if (!isConcave[i]) { + let p1 = indices[previous] << 1, p2 = indices[i] << 1, p3 = indices[next] << 1; + let p1x = vertices[p1], p1y = vertices[p1 + 1]; + let p2x = vertices[p2], p2y = vertices[p2 + 1]; + let p3x = vertices[p3], p3y = vertices[p3 + 1]; + for (let ii = (next + 1) % vertexCount; ii != previous; ii = (ii + 1) % vertexCount) { + if (!isConcave[ii]) + continue; + let v = indices[ii] << 1; + let vx = vertices[v], vy = vertices[v + 1]; + if (Triangulator.positiveArea(p3x, p3y, p1x, p1y, vx, vy)) { + if (Triangulator.positiveArea(p1x, p1y, p2x, p2y, vx, vy)) { + if (Triangulator.positiveArea(p2x, p2y, p3x, p3y, vx, vy)) + break outer; + } + } + } + break; + } + if (next == 0) { + do { + if (!isConcave[i]) + break; + i--; + } while (i > 0); + break; + } + previous = i; + i = next; + next = (next + 1) % vertexCount; + } + triangles.push(indices[(vertexCount + i - 1) % vertexCount]); + triangles.push(indices[i]); + triangles.push(indices[(i + 1) % vertexCount]); + indices.splice(i, 1); + isConcave.splice(i, 1); + vertexCount--; + let previousIndex = (vertexCount + i - 1) % vertexCount; + let nextIndex = i == vertexCount ? 0 : i; + isConcave[previousIndex] = Triangulator.isConcave(previousIndex, vertexCount, vertices, indices); + isConcave[nextIndex] = Triangulator.isConcave(nextIndex, vertexCount, vertices, indices); + } + if (vertexCount == 3) { + triangles.push(indices[2]); + triangles.push(indices[0]); + triangles.push(indices[1]); + } + return triangles; + } + decompose(verticesArray, triangles) { + let vertices = verticesArray; + let convexPolygons = this.convexPolygons; + this.polygonPool.freeAll(convexPolygons); + convexPolygons.length = 0; + let convexPolygonsIndices = this.convexPolygonsIndices; + this.polygonIndicesPool.freeAll(convexPolygonsIndices); + convexPolygonsIndices.length = 0; + let polygonIndices = this.polygonIndicesPool.obtain(); + polygonIndices.length = 0; + let polygon = this.polygonPool.obtain(); + polygon.length = 0; + let fanBaseIndex = -1, lastWinding = 0; + for (let i = 0, n = triangles.length; i < n; i += 3) { + let t1 = triangles[i] << 1, t2 = triangles[i + 1] << 1, t3 = triangles[i + 2] << 1; + let x1 = vertices[t1], y1 = vertices[t1 + 1]; + let x2 = vertices[t2], y2 = vertices[t2 + 1]; + let x3 = vertices[t3], y3 = vertices[t3 + 1]; + let merged = false; + if (fanBaseIndex == t1) { + let o = polygon.length - 4; + let winding1 = Triangulator.winding(polygon[o], polygon[o + 1], polygon[o + 2], polygon[o + 3], x3, y3); + let winding2 = Triangulator.winding(x3, y3, polygon[0], polygon[1], polygon[2], polygon[3]); + if (winding1 == lastWinding && winding2 == lastWinding) { + polygon.push(x3); + polygon.push(y3); + polygonIndices.push(t3); + merged = true; + } + } + if (!merged) { + if (polygon.length > 0) { + convexPolygons.push(polygon); + convexPolygonsIndices.push(polygonIndices); + } + else { + this.polygonPool.free(polygon); + this.polygonIndicesPool.free(polygonIndices); + } + polygon = this.polygonPool.obtain(); + polygon.length = 0; + polygon.push(x1); + polygon.push(y1); + polygon.push(x2); + polygon.push(y2); + polygon.push(x3); + polygon.push(y3); + polygonIndices = this.polygonIndicesPool.obtain(); + polygonIndices.length = 0; + polygonIndices.push(t1); + polygonIndices.push(t2); + polygonIndices.push(t3); + lastWinding = Triangulator.winding(x1, y1, x2, y2, x3, y3); + fanBaseIndex = t1; + } + } + if (polygon.length > 0) { + convexPolygons.push(polygon); + convexPolygonsIndices.push(polygonIndices); + } + for (let i = 0, n = convexPolygons.length; i < n; i++) { + polygonIndices = convexPolygonsIndices[i]; + if (polygonIndices.length == 0) + continue; + let firstIndex = polygonIndices[0]; + let lastIndex = polygonIndices[polygonIndices.length - 1]; + polygon = convexPolygons[i]; + let o = polygon.length - 4; + let prevPrevX = polygon[o], prevPrevY = polygon[o + 1]; + let prevX = polygon[o + 2], prevY = polygon[o + 3]; + let firstX = polygon[0], firstY = polygon[1]; + let secondX = polygon[2], secondY = polygon[3]; + let winding = Triangulator.winding(prevPrevX, prevPrevY, prevX, prevY, firstX, firstY); + for (let ii = 0; ii < n; ii++) { + if (ii == i) + continue; + let otherIndices = convexPolygonsIndices[ii]; + if (otherIndices.length != 3) + continue; + let otherFirstIndex = otherIndices[0]; + let otherSecondIndex = otherIndices[1]; + let otherLastIndex = otherIndices[2]; + let otherPoly = convexPolygons[ii]; + let x3 = otherPoly[otherPoly.length - 2], y3 = otherPoly[otherPoly.length - 1]; + if (otherFirstIndex != firstIndex || otherSecondIndex != lastIndex) + continue; + let winding1 = Triangulator.winding(prevPrevX, prevPrevY, prevX, prevY, x3, y3); + let winding2 = Triangulator.winding(x3, y3, firstX, firstY, secondX, secondY); + if (winding1 == winding && winding2 == winding) { + otherPoly.length = 0; + otherIndices.length = 0; + polygon.push(x3); + polygon.push(y3); + polygonIndices.push(otherLastIndex); + prevPrevX = prevX; + prevPrevY = prevY; + prevX = x3; + prevY = y3; + ii = 0; + } + } + } + for (let i = convexPolygons.length - 1; i >= 0; i--) { + polygon = convexPolygons[i]; + if (polygon.length == 0) { + convexPolygons.splice(i, 1); + this.polygonPool.free(polygon); + polygonIndices = convexPolygonsIndices[i]; + convexPolygonsIndices.splice(i, 1); + this.polygonIndicesPool.free(polygonIndices); + } + } + return convexPolygons; + } + static isConcave(index, vertexCount, vertices, indices) { + let previous = indices[(vertexCount + index - 1) % vertexCount] << 1; + let current = indices[index] << 1; + let next = indices[(index + 1) % vertexCount] << 1; + return !this.positiveArea(vertices[previous], vertices[previous + 1], vertices[current], vertices[current + 1], vertices[next], vertices[next + 1]); + } + static positiveArea(p1x, p1y, p2x, p2y, p3x, p3y) { + return p1x * (p3y - p2y) + p2x * (p1y - p3y) + p3x * (p2y - p1y) >= 0; + } + static winding(p1x, p1y, p2x, p2y, p3x, p3y) { + let px = p2x - p1x, py = p2y - p1y; + return p3x * py - p3y * px + px * p1y - p1x * py >= 0 ? 1 : -1; + } + } + spine.Triangulator = Triangulator; +})(spine || (spine = {})); +var spine; +(function (spine) { + class IntSet { + constructor() { + this.array = new Array(); + } + add(value) { + let contains = this.contains(value); + this.array[value | 0] = value | 0; + return !contains; + } + contains(value) { + return this.array[value | 0] != undefined; + } + remove(value) { + this.array[value | 0] = undefined; + } + clear() { + this.array.length = 0; + } + } + spine.IntSet = IntSet; + class Color { + constructor(r = 0, g = 0, b = 0, a = 0) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + set(r, g, b, a) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + this.clamp(); + return this; + } + setFromColor(c) { + this.r = c.r; + this.g = c.g; + this.b = c.b; + this.a = c.a; + return this; + } + setFromString(hex) { + hex = hex.charAt(0) == '#' ? hex.substr(1) : hex; + this.r = parseInt(hex.substr(0, 2), 16) / 255.0; + this.g = parseInt(hex.substr(2, 2), 16) / 255.0; + this.b = parseInt(hex.substr(4, 2), 16) / 255.0; + this.a = (hex.length != 8 ? 255 : parseInt(hex.substr(6, 2), 16)) / 255.0; + return this; + } + add(r, g, b, a) { + this.r += r; + this.g += g; + this.b += b; + this.a += a; + this.clamp(); + return this; + } + clamp() { + if (this.r < 0) + this.r = 0; + else if (this.r > 1) + this.r = 1; + if (this.g < 0) + this.g = 0; + else if (this.g > 1) + this.g = 1; + if (this.b < 0) + this.b = 0; + else if (this.b > 1) + this.b = 1; + if (this.a < 0) + this.a = 0; + else if (this.a > 1) + this.a = 1; + return this; + } + static rgba8888ToColor(color, value) { + color.r = ((value & 0xff000000) >>> 24) / 255; + color.g = ((value & 0x00ff0000) >>> 16) / 255; + color.b = ((value & 0x0000ff00) >>> 8) / 255; + color.a = ((value & 0x000000ff)) / 255; + } + static rgb888ToColor(color, value) { + color.r = ((value & 0x00ff0000) >>> 16) / 255; + color.g = ((value & 0x0000ff00) >>> 8) / 255; + color.b = ((value & 0x000000ff)) / 255; + } + } + Color.WHITE = new Color(1, 1, 1, 1); + Color.RED = new Color(1, 0, 0, 1); + Color.GREEN = new Color(0, 1, 0, 1); + Color.BLUE = new Color(0, 0, 1, 1); + Color.MAGENTA = new Color(1, 0, 1, 1); + spine.Color = Color; + class MathUtils { + static clamp(value, min, max) { + if (value < min) + return min; + if (value > max) + return max; + return value; + } + static cosDeg(degrees) { + return Math.cos(degrees * MathUtils.degRad); + } + static sinDeg(degrees) { + return Math.sin(degrees * MathUtils.degRad); + } + static signum(value) { + return value > 0 ? 1 : value < 0 ? -1 : 0; + } + static toInt(x) { + return x > 0 ? Math.floor(x) : Math.ceil(x); + } + static cbrt(x) { + let y = Math.pow(Math.abs(x), 1 / 3); + return x < 0 ? -y : y; + } + static randomTriangular(min, max) { + return MathUtils.randomTriangularWith(min, max, (min + max) * 0.5); + } + static randomTriangularWith(min, max, mode) { + let u = Math.random(); + let d = max - min; + if (u <= (mode - min) / d) + return min + Math.sqrt(u * d * (mode - min)); + return max - Math.sqrt((1 - u) * d * (max - mode)); + } + } + MathUtils.PI = 3.1415927; + MathUtils.PI2 = MathUtils.PI * 2; + MathUtils.radiansToDegrees = 180 / MathUtils.PI; + MathUtils.radDeg = MathUtils.radiansToDegrees; + MathUtils.degreesToRadians = MathUtils.PI / 180; + MathUtils.degRad = MathUtils.degreesToRadians; + spine.MathUtils = MathUtils; + class Interpolation { + apply(start, end, a) { + return start + (end - start) * this.applyInternal(a); + } + } + spine.Interpolation = Interpolation; + class Pow extends Interpolation { + constructor(power) { + super(); + this.power = 2; + this.power = power; + } + applyInternal(a) { + if (a <= 0.5) + return Math.pow(a * 2, this.power) / 2; + return Math.pow((a - 1) * 2, this.power) / (this.power % 2 == 0 ? -2 : 2) + 1; + } + } + spine.Pow = Pow; + class PowOut extends Pow { + constructor(power) { + super(power); + } + applyInternal(a) { + return Math.pow(a - 1, this.power) * (this.power % 2 == 0 ? -1 : 1) + 1; + } + } + spine.PowOut = PowOut; + class Utils { + static arrayCopy(source, sourceStart, dest, destStart, numElements) { + for (let i = sourceStart, j = destStart; i < sourceStart + numElements; i++, j++) { + dest[j] = source[i]; + } + } + static setArraySize(array, size, value = 0) { + let oldSize = array.length; + if (oldSize == size) + return array; + array.length = size; + if (oldSize < size) { + for (let i = oldSize; i < size; i++) + array[i] = value; + } + return array; + } + static ensureArrayCapacity(array, size, value = 0) { + if (array.length >= size) + return array; + return Utils.setArraySize(array, size, value); + } + static newArray(size, defaultValue) { + let array = new Array(size); + for (let i = 0; i < size; i++) + array[i] = defaultValue; + return array; + } + static newFloatArray(size) { + if (Utils.SUPPORTS_TYPED_ARRAYS) { + return new Float32Array(size); + } + else { + let array = new Array(size); + for (let i = 0; i < array.length; i++) + array[i] = 0; + return array; + } + } + static newShortArray(size) { + if (Utils.SUPPORTS_TYPED_ARRAYS) { + return new Int16Array(size); + } + else { + let array = new Array(size); + for (let i = 0; i < array.length; i++) + array[i] = 0; + return array; + } + } + static toFloatArray(array) { + return Utils.SUPPORTS_TYPED_ARRAYS ? new Float32Array(array) : array; + } + static toSinglePrecision(value) { + return Utils.SUPPORTS_TYPED_ARRAYS ? Math.fround(value) : value; + } + static webkit602BugfixHelper(alpha, blend) { + } + static contains(array, element, identity = true) { + for (var i = 0; i < array.length; i++) { + if (array[i] == element) + return true; + } + return false; + } + } + Utils.SUPPORTS_TYPED_ARRAYS = typeof (Float32Array) !== "undefined"; + spine.Utils = Utils; + class DebugUtils { + static logBones(skeleton) { + for (let i = 0; i < skeleton.bones.length; i++) { + let bone = skeleton.bones[i]; + console.log(bone.data.name + ", " + bone.a + ", " + bone.b + ", " + bone.c + ", " + bone.d + ", " + bone.worldX + ", " + bone.worldY); + } + } + } + spine.DebugUtils = DebugUtils; + class Pool { + constructor(instantiator) { + this.items = new Array(); + this.instantiator = instantiator; + } + obtain() { + return this.items.length > 0 ? this.items.pop() : this.instantiator(); + } + free(item) { + if (item.reset) + item.reset(); + this.items.push(item); + } + freeAll(items) { + for (let i = 0; i < items.length; i++) { + if (items[i].reset) + items[i].reset(); + this.items[i] = items[i]; + } + } + clear() { + this.items.length = 0; + } + } + spine.Pool = Pool; + class Vector2 { + constructor(x = 0, y = 0) { + this.x = x; + this.y = y; + } + set(x, y) { + this.x = x; + this.y = y; + return this; + } + length() { + let x = this.x; + let y = this.y; + return Math.sqrt(x * x + y * y); + } + normalize() { + let len = this.length(); + if (len != 0) { + this.x /= len; + this.y /= len; + } + return this; + } + } + spine.Vector2 = Vector2; + class TimeKeeper { + constructor() { + this.maxDelta = 0.064; + this.framesPerSecond = 0; + this.delta = 0; + this.totalTime = 0; + this.lastTime = Date.now() / 1000; + this.frameCount = 0; + this.frameTime = 0; + } + update() { + let now = Date.now() / 1000; + this.delta = now - this.lastTime; + this.frameTime += this.delta; + this.totalTime += this.delta; + if (this.delta > this.maxDelta) + this.delta = this.maxDelta; + this.lastTime = now; + this.frameCount++; + if (this.frameTime > 1) { + this.framesPerSecond = this.frameCount / this.frameTime; + this.frameTime = 0; + this.frameCount = 0; + } + } + } + spine.TimeKeeper = TimeKeeper; + class WindowedMean { + constructor(windowSize = 32) { + this.addedValues = 0; + this.lastValue = 0; + this.mean = 0; + this.dirty = true; + this.values = new Array(windowSize); + } + hasEnoughData() { + return this.addedValues >= this.values.length; + } + addValue(value) { + if (this.addedValues < this.values.length) + this.addedValues++; + this.values[this.lastValue++] = value; + if (this.lastValue > this.values.length - 1) + this.lastValue = 0; + this.dirty = true; + } + getMean() { + if (this.hasEnoughData()) { + if (this.dirty) { + let mean = 0; + for (let i = 0; i < this.values.length; i++) { + mean += this.values[i]; + } + this.mean = mean / this.values.length; + this.dirty = false; + } + return this.mean; + } + else { + return 0; + } + } + } + spine.WindowedMean = WindowedMean; +})(spine || (spine = {})); +(() => { + if (!Math.fround) { + Math.fround = (function (array) { + return function (x) { + return array[0] = x, array[0]; + }; + })(new Float32Array(1)); + } +})(); +var spine; +(function (spine) { + class Attachment { + constructor(name) { + if (name == null) + throw new Error("name cannot be null."); + this.name = name; + } + } + spine.Attachment = Attachment; + class VertexAttachment extends Attachment { + constructor(name) { + super(name); + this.id = (VertexAttachment.nextID++ & 65535) << 11; + this.worldVerticesLength = 0; + this.deformAttachment = this; + } + computeWorldVertices(slot, start, count, worldVertices, offset, stride) { + count = offset + (count >> 1) * stride; + let skeleton = slot.bone.skeleton; + let deformArray = slot.deform; + let vertices = this.vertices; + let bones = this.bones; + if (bones == null) { + if (deformArray.length > 0) + vertices = deformArray; + let bone = slot.bone; + let x = bone.worldX; + let y = bone.worldY; + let a = bone.a, b = bone.b, c = bone.c, d = bone.d; + for (let v = start, w = offset; w < count; v += 2, w += stride) { + let vx = vertices[v], vy = vertices[v + 1]; + worldVertices[w] = vx * a + vy * b + x; + worldVertices[w + 1] = vx * c + vy * d + y; + } + return; + } + let v = 0, skip = 0; + for (let i = 0; i < start; i += 2) { + let n = bones[v]; + v += n + 1; + skip += n; + } + let skeletonBones = skeleton.bones; + if (deformArray.length == 0) { + for (let w = offset, b = skip * 3; w < count; w += stride) { + let wx = 0, wy = 0; + let n = bones[v++]; + n += v; + for (; v < n; v++, b += 3) { + let bone = skeletonBones[bones[v]]; + let vx = vertices[b], vy = vertices[b + 1], weight = vertices[b + 2]; + wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight; + wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight; + } + worldVertices[w] = wx; + worldVertices[w + 1] = wy; + } + } + else { + let deform = deformArray; + for (let w = offset, b = skip * 3, f = skip << 1; w < count; w += stride) { + let wx = 0, wy = 0; + let n = bones[v++]; + n += v; + for (; v < n; v++, b += 3, f += 2) { + let bone = skeletonBones[bones[v]]; + let vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2]; + wx += (vx * bone.a + vy * bone.b + bone.worldX) * weight; + wy += (vx * bone.c + vy * bone.d + bone.worldY) * weight; + } + worldVertices[w] = wx; + worldVertices[w + 1] = wy; + } + } + } + copyTo(attachment) { + if (this.bones != null) { + attachment.bones = new Array(this.bones.length); + spine.Utils.arrayCopy(this.bones, 0, attachment.bones, 0, this.bones.length); + } + else + attachment.bones = null; + if (this.vertices != null) { + attachment.vertices = spine.Utils.newFloatArray(this.vertices.length); + spine.Utils.arrayCopy(this.vertices, 0, attachment.vertices, 0, this.vertices.length); + } + else + attachment.vertices = null; + attachment.worldVerticesLength = this.worldVerticesLength; + attachment.deformAttachment = this.deformAttachment; + } + } + VertexAttachment.nextID = 0; + spine.VertexAttachment = VertexAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + let AttachmentType; + (function (AttachmentType) { + AttachmentType[AttachmentType["Region"] = 0] = "Region"; + AttachmentType[AttachmentType["BoundingBox"] = 1] = "BoundingBox"; + AttachmentType[AttachmentType["Mesh"] = 2] = "Mesh"; + AttachmentType[AttachmentType["LinkedMesh"] = 3] = "LinkedMesh"; + AttachmentType[AttachmentType["Path"] = 4] = "Path"; + AttachmentType[AttachmentType["Point"] = 5] = "Point"; + AttachmentType[AttachmentType["Clipping"] = 6] = "Clipping"; + })(AttachmentType = spine.AttachmentType || (spine.AttachmentType = {})); +})(spine || (spine = {})); +var spine; +(function (spine) { + class BoundingBoxAttachment extends spine.VertexAttachment { + constructor(name) { + super(name); + this.color = new spine.Color(1, 1, 1, 1); + } + copy() { + let copy = new BoundingBoxAttachment(name); + this.copyTo(copy); + copy.color.setFromColor(this.color); + return copy; + } + } + spine.BoundingBoxAttachment = BoundingBoxAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + class ClippingAttachment extends spine.VertexAttachment { + constructor(name) { + super(name); + this.color = new spine.Color(0.2275, 0.2275, 0.8078, 1); + } + copy() { + let copy = new ClippingAttachment(name); + this.copyTo(copy); + copy.endSlot = this.endSlot; + copy.color.setFromColor(this.color); + return copy; + } + } + spine.ClippingAttachment = ClippingAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + class MeshAttachment extends spine.VertexAttachment { + constructor(name) { + super(name); + this.color = new spine.Color(1, 1, 1, 1); + this.tempColor = new spine.Color(0, 0, 0, 0); + } + updateUVs() { + let regionUVs = this.regionUVs; + if (this.uvs == null || this.uvs.length != regionUVs.length) + this.uvs = spine.Utils.newFloatArray(regionUVs.length); + let uvs = this.uvs; + let n = this.uvs.length; + let u = this.region.u, v = this.region.v, width = 0, height = 0; + if (this.region instanceof spine.TextureAtlasRegion) { + let region = this.region; + let textureWidth = region.texture.getImage().width, textureHeight = region.texture.getImage().height; + switch (region.degrees) { + case 90: + u -= (region.originalHeight - region.offsetY - region.height) / textureWidth; + v -= (region.originalWidth - region.offsetX - region.width) / textureHeight; + width = region.originalHeight / textureWidth; + height = region.originalWidth / textureHeight; + for (let i = 0; i < n; i += 2) { + uvs[i] = u + regionUVs[i + 1] * width; + uvs[i + 1] = v + (1 - regionUVs[i]) * height; + } + return; + case 180: + u -= (region.originalWidth - region.offsetX - region.width) / textureWidth; + v -= region.offsetY / textureHeight; + width = region.originalWidth / textureWidth; + height = region.originalHeight / textureHeight; + for (let i = 0; i < n; i += 2) { + uvs[i] = u + (1 - regionUVs[i]) * width; + uvs[i + 1] = v + (1 - regionUVs[i + 1]) * height; + } + return; + case 270: + u -= region.offsetY / textureWidth; + v -= region.offsetX / textureHeight; + width = region.originalHeight / textureWidth; + height = region.originalWidth / textureHeight; + for (let i = 0; i < n; i += 2) { + uvs[i] = u + (1 - regionUVs[i + 1]) * width; + uvs[i + 1] = v + regionUVs[i] * height; + } + return; + } + u -= region.offsetX / textureWidth; + v -= (region.originalHeight - region.offsetY - region.height) / textureHeight; + width = region.originalWidth / textureWidth; + height = region.originalHeight / textureHeight; + } + else if (this.region == null) { + u = v = 0; + width = height = 1; + } + else { + width = this.region.u2 - u; + height = this.region.v2 - v; + } + for (let i = 0; i < n; i += 2) { + uvs[i] = u + regionUVs[i] * width; + uvs[i + 1] = v + regionUVs[i + 1] * height; + } + } + getParentMesh() { + return this.parentMesh; + } + setParentMesh(parentMesh) { + this.parentMesh = parentMesh; + if (parentMesh != null) { + this.bones = parentMesh.bones; + this.vertices = parentMesh.vertices; + this.worldVerticesLength = parentMesh.worldVerticesLength; + this.regionUVs = parentMesh.regionUVs; + this.triangles = parentMesh.triangles; + this.hullLength = parentMesh.hullLength; + this.worldVerticesLength = parentMesh.worldVerticesLength; + } + } + copy() { + if (this.parentMesh != null) + return this.newLinkedMesh(); + let copy = new MeshAttachment(this.name); + copy.region = this.region; + copy.path = this.path; + copy.color.setFromColor(this.color); + this.copyTo(copy); + copy.regionUVs = new Array(this.regionUVs.length); + spine.Utils.arrayCopy(this.regionUVs, 0, copy.regionUVs, 0, this.regionUVs.length); + copy.uvs = new Array(this.uvs.length); + spine.Utils.arrayCopy(this.uvs, 0, copy.uvs, 0, this.uvs.length); + copy.triangles = new Array(this.triangles.length); + spine.Utils.arrayCopy(this.triangles, 0, copy.triangles, 0, this.triangles.length); + copy.hullLength = this.hullLength; + if (this.edges != null) { + copy.edges = new Array(this.edges.length); + spine.Utils.arrayCopy(this.edges, 0, copy.edges, 0, this.edges.length); + } + copy.width = this.width; + copy.height = this.height; + return copy; + } + newLinkedMesh() { + let copy = new MeshAttachment(this.name); + copy.region = this.region; + copy.path = this.path; + copy.color.setFromColor(this.color); + copy.deformAttachment = this.deformAttachment; + copy.setParentMesh(this.parentMesh != null ? this.parentMesh : this); + copy.updateUVs(); + return copy; + } + } + spine.MeshAttachment = MeshAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + class PathAttachment extends spine.VertexAttachment { + constructor(name) { + super(name); + this.closed = false; + this.constantSpeed = false; + this.color = new spine.Color(1, 1, 1, 1); + } + copy() { + let copy = new PathAttachment(name); + this.copyTo(copy); + copy.lengths = new Array(this.lengths.length); + spine.Utils.arrayCopy(this.lengths, 0, copy.lengths, 0, this.lengths.length); + copy.closed = closed; + copy.constantSpeed = this.constantSpeed; + copy.color.setFromColor(this.color); + return copy; + } + } + spine.PathAttachment = PathAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + class PointAttachment extends spine.VertexAttachment { + constructor(name) { + super(name); + this.color = new spine.Color(0.38, 0.94, 0, 1); + } + computeWorldPosition(bone, point) { + point.x = this.x * bone.a + this.y * bone.b + bone.worldX; + point.y = this.x * bone.c + this.y * bone.d + bone.worldY; + return point; + } + computeWorldRotation(bone) { + let cos = spine.MathUtils.cosDeg(this.rotation), sin = spine.MathUtils.sinDeg(this.rotation); + let x = cos * bone.a + sin * bone.b; + let y = cos * bone.c + sin * bone.d; + return Math.atan2(y, x) * spine.MathUtils.radDeg; + } + copy() { + let copy = new PointAttachment(name); + copy.x = this.x; + copy.y = this.y; + copy.rotation = this.rotation; + copy.color.setFromColor(this.color); + return copy; + } + } + spine.PointAttachment = PointAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + class RegionAttachment extends spine.Attachment { + constructor(name) { + super(name); + this.x = 0; + this.y = 0; + this.scaleX = 1; + this.scaleY = 1; + this.rotation = 0; + this.width = 0; + this.height = 0; + this.color = new spine.Color(1, 1, 1, 1); + this.offset = spine.Utils.newFloatArray(8); + this.uvs = spine.Utils.newFloatArray(8); + this.tempColor = new spine.Color(1, 1, 1, 1); + } + updateOffset() { + let regionScaleX = this.width / this.region.originalWidth * this.scaleX; + let regionScaleY = this.height / this.region.originalHeight * this.scaleY; + let localX = -this.width / 2 * this.scaleX + this.region.offsetX * regionScaleX; + let localY = -this.height / 2 * this.scaleY + this.region.offsetY * regionScaleY; + let localX2 = localX + this.region.width * regionScaleX; + let localY2 = localY + this.region.height * regionScaleY; + let radians = this.rotation * Math.PI / 180; + let cos = Math.cos(radians); + let sin = Math.sin(radians); + let localXCos = localX * cos + this.x; + let localXSin = localX * sin; + let localYCos = localY * cos + this.y; + let localYSin = localY * sin; + let localX2Cos = localX2 * cos + this.x; + let localX2Sin = localX2 * sin; + let localY2Cos = localY2 * cos + this.y; + let localY2Sin = localY2 * sin; + let offset = this.offset; + offset[RegionAttachment.OX1] = localXCos - localYSin; + offset[RegionAttachment.OY1] = localYCos + localXSin; + offset[RegionAttachment.OX2] = localXCos - localY2Sin; + offset[RegionAttachment.OY2] = localY2Cos + localXSin; + offset[RegionAttachment.OX3] = localX2Cos - localY2Sin; + offset[RegionAttachment.OY3] = localY2Cos + localX2Sin; + offset[RegionAttachment.OX4] = localX2Cos - localYSin; + offset[RegionAttachment.OY4] = localYCos + localX2Sin; + } + setRegion(region) { + this.region = region; + let uvs = this.uvs; + if (region.rotate) { + uvs[2] = region.u; + uvs[3] = region.v2; + uvs[4] = region.u; + uvs[5] = region.v; + uvs[6] = region.u2; + uvs[7] = region.v; + uvs[0] = region.u2; + uvs[1] = region.v2; + } + else { + uvs[0] = region.u; + uvs[1] = region.v2; + uvs[2] = region.u; + uvs[3] = region.v; + uvs[4] = region.u2; + uvs[5] = region.v; + uvs[6] = region.u2; + uvs[7] = region.v2; + } + } + computeWorldVertices(bone, worldVertices, offset, stride) { + let vertexOffset = this.offset; + let x = bone.worldX, y = bone.worldY; + let a = bone.a, b = bone.b, c = bone.c, d = bone.d; + let offsetX = 0, offsetY = 0; + offsetX = vertexOffset[RegionAttachment.OX1]; + offsetY = vertexOffset[RegionAttachment.OY1]; + worldVertices[offset] = offsetX * a + offsetY * b + x; + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[RegionAttachment.OX2]; + offsetY = vertexOffset[RegionAttachment.OY2]; + worldVertices[offset] = offsetX * a + offsetY * b + x; + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[RegionAttachment.OX3]; + offsetY = vertexOffset[RegionAttachment.OY3]; + worldVertices[offset] = offsetX * a + offsetY * b + x; + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + offset += stride; + offsetX = vertexOffset[RegionAttachment.OX4]; + offsetY = vertexOffset[RegionAttachment.OY4]; + worldVertices[offset] = offsetX * a + offsetY * b + x; + worldVertices[offset + 1] = offsetX * c + offsetY * d + y; + } + copy() { + let copy = new RegionAttachment(name); + copy.region = this.region; + copy.rendererObject = this.rendererObject; + copy.path = this.path; + copy.x = this.x; + copy.y = this.y; + copy.scaleX = this.scaleX; + copy.scaleY = this.scaleY; + copy.rotation = this.rotation; + copy.width = this.width; + copy.height = this.height; + spine.Utils.arrayCopy(this.uvs, 0, copy.uvs, 0, 8); + spine.Utils.arrayCopy(this.offset, 0, copy.offset, 0, 8); + copy.color.setFromColor(this.color); + return copy; + } + } + RegionAttachment.OX1 = 0; + RegionAttachment.OY1 = 1; + RegionAttachment.OX2 = 2; + RegionAttachment.OY2 = 3; + RegionAttachment.OX3 = 4; + RegionAttachment.OY3 = 5; + RegionAttachment.OX4 = 6; + RegionAttachment.OY4 = 7; + RegionAttachment.X1 = 0; + RegionAttachment.Y1 = 1; + RegionAttachment.C1R = 2; + RegionAttachment.C1G = 3; + RegionAttachment.C1B = 4; + RegionAttachment.C1A = 5; + RegionAttachment.U1 = 6; + RegionAttachment.V1 = 7; + RegionAttachment.X2 = 8; + RegionAttachment.Y2 = 9; + RegionAttachment.C2R = 10; + RegionAttachment.C2G = 11; + RegionAttachment.C2B = 12; + RegionAttachment.C2A = 13; + RegionAttachment.U2 = 14; + RegionAttachment.V2 = 15; + RegionAttachment.X3 = 16; + RegionAttachment.Y3 = 17; + RegionAttachment.C3R = 18; + RegionAttachment.C3G = 19; + RegionAttachment.C3B = 20; + RegionAttachment.C3A = 21; + RegionAttachment.U3 = 22; + RegionAttachment.V3 = 23; + RegionAttachment.X4 = 24; + RegionAttachment.Y4 = 25; + RegionAttachment.C4R = 26; + RegionAttachment.C4G = 27; + RegionAttachment.C4B = 28; + RegionAttachment.C4A = 29; + RegionAttachment.U4 = 30; + RegionAttachment.V4 = 31; + spine.RegionAttachment = RegionAttachment; +})(spine || (spine = {})); +var spine; +(function (spine) { + class JitterEffect { + constructor(jitterX, jitterY) { + this.jitterX = 0; + this.jitterY = 0; + this.jitterX = jitterX; + this.jitterY = jitterY; + } + begin(skeleton) { + } + transform(position, uv, light, dark) { + position.x += spine.MathUtils.randomTriangular(-this.jitterX, this.jitterY); + position.y += spine.MathUtils.randomTriangular(-this.jitterX, this.jitterY); + } + end() { + } + } + spine.JitterEffect = JitterEffect; +})(spine || (spine = {})); +var spine; +(function (spine) { + class SwirlEffect { + constructor(radius) { + this.centerX = 0; + this.centerY = 0; + this.radius = 0; + this.angle = 0; + this.worldX = 0; + this.worldY = 0; + this.radius = radius; + } + begin(skeleton) { + this.worldX = skeleton.x + this.centerX; + this.worldY = skeleton.y + this.centerY; + } + transform(position, uv, light, dark) { + let radAngle = this.angle * spine.MathUtils.degreesToRadians; + let x = position.x - this.worldX; + let y = position.y - this.worldY; + let dist = Math.sqrt(x * x + y * y); + if (dist < this.radius) { + let theta = SwirlEffect.interpolation.apply(0, radAngle, (this.radius - dist) / this.radius); + let cos = Math.cos(theta); + let sin = Math.sin(theta); + position.x = cos * x - sin * y + this.worldX; + position.y = sin * x + cos * y + this.worldY; + } + } + end() { + } + } + SwirlEffect.interpolation = new spine.PowOut(2); + spine.SwirlEffect = SwirlEffect; +})(spine || (spine = {})); +window.spine = spine; diff --git a/examples/layaair/frontend/bin/libs/worker.js b/examples/layaair/frontend/bin/libs/worker.js new file mode 100644 index 0000000..8abbabb --- /dev/null +++ b/examples/layaair/frontend/bin/libs/worker.js @@ -0,0 +1 @@ +function testCanImageData(){try{cc=new ImageData(20,20),canUseImageData=!0}catch(t){}}function loadImage(t){PNG.load(t.url,pngLoaded)}function loadImage2(t){var e,a=t.url;e=new XMLHttpRequest,e.open("GET",a,!0),e.responseType="arraybuffer",e.onload=function(){var t,i,r=e.response||e.mozResponseArrayBuffer;if(t=new Uint8Array(r),self.createImageBitmap)return void doCreateImageBitmap(t,a);try{startTime=getTimeNow(),i=new PNG(t),i.url=a,i.startTime=startTime,i.decodeEndTime=getTimeNow(),i.decodeTime=i.decodeEndTime-startTime,pngLoaded(i)}catch(s){pngFail(a,"parse fail"+s.toString()+":ya")}},e.onerror=function(t){pngFail(a,"loadFail")},e.send(null)}function doCreateImageBitmap(t,e){try{var a=getTimeNow();t=new self.Blob([t],{type:"image/png"}),self.createImageBitmap(t).then(function(t){var i={};i.url=e,i.imageBitmap=t,i.dataType="imageBitmap",i.startTime=a,i.decodeTime=getTimeNow()-a,i.sendTime=getTimeNow(),console.log("Decode By createImageBitmap,"+i.decodeTime,e),i.type="Image",postMessage(i,[i.imageBitmap])})["catch"](function(t){showMsgToMain("cache:"+t),pngFail(e,"parse fail"+t+":ya")})}catch(i){pngFail(e,"parse fail"+i.toString()+":ya")}}function getTimeNow(){return(new Date).getTime()}function pngFail(t,e){var a={};a.url=t,a.imagedata=null,a.type="Image",a.msg=e,console.log(e),postMessage(a)}function showMsgToMain(t){var e={};e.type="Msg",e.msg=t,postMessage(e)}function pngLoaded(t){var e={};e.url=t.url,canUseImageData?(e.imagedata=t.getImageData(),e.dataType="imagedata"):(e.buffer=t.getImageDataBuffer(),e.dataType="buffer"),e.width=t.width,e.height=t.height,e.decodeTime=getTimeNow()-t.startTime,console.log("Decode By PNG.js,"+(getTimeNow()-t.startTime),t.url),e.type="Image",canUseImageData?postMessage(e,[e.imagedata.data.buffer]):postMessage(e,[e.buffer.buffer])}var DecodeStream=function(){function t(){this.pos=0,this.bufferLength=0,this.eof=!1,this.buffer=null}return t.prototype={ensureBuffer:function(t){var e=this.buffer,a=e?e.byteLength:0;if(a>t)return e;for(var i=512;t>i;)i<<=1;for(var r=new Uint8Array(i),s=0;a>s;++s)r[s]=e[s];return this.buffer=r},getByte:function(){for(var t=this.pos;this.bufferLength<=t;){if(this.eof)return null;this.readBlock()}return this.buffer[this.pos++]},getBytes:function(t){var e=this.pos;if(t){this.ensureBuffer(e+t);for(var a=e+t;!this.eof&&this.bufferLengthi&&(a=i)}else{for(;!this.eof;)this.readBlock();var a=this.bufferLength}return this.pos=a,this.buffer.subarray(e,a)},lookChar:function(){for(var t=this.pos;this.bufferLength<=t;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos])},getChar:function(){for(var t=this.pos;this.bufferLength<=t;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos++])},makeSubStream:function(t,e,a){for(var i=t+e;this.bufferLength<=i&&!this.eof;)this.readBlock();return new Stream(this.buffer,t,e,a)},skip:function(t){t||(t=1),this.pos+=t},reset:function(){this.pos=0}},t}(),FlateStream=function(){function t(t){throw new Error(t)}function e(e){var a=0,i=e[a++],r=e[a++];-1!=i&&-1!=r||t("Invalid header in flate stream"),8!=(15&i)&&t("Unknown compression method in flate stream"),((i<<8)+r)%31!=0&&t("Bad FCHECK in flate stream"),32&r&&t("FDICT bit set in flate stream"),this.bytes=e,this.bytesPos=a,this.codeSize=0,this.codeBuf=0,DecodeStream.call(this)}var a=new Uint32Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),i=new Uint32Array([3,4,5,6,7,8,9,10,65547,65549,65551,65553,131091,131095,131099,131103,196643,196651,196659,196667,262211,262227,262243,262259,327811,327843,327875,327907,258,258,258]),r=new Uint32Array([1,2,3,4,65541,65543,131081,131085,196625,196633,262177,262193,327745,327777,393345,393409,459009,459137,524801,525057,590849,591361,657409,658433,724993,727041,794625,798721,868353,876545]),s=[new Uint32Array([459008,524368,524304,524568,459024,524400,524336,590016,459016,524384,524320,589984,524288,524416,524352,590048,459012,524376,524312,589968,459028,524408,524344,590032,459020,524392,524328,59e4,524296,524424,524360,590064,459010,524372,524308,524572,459026,524404,524340,590024,459018,524388,524324,589992,524292,524420,524356,590056,459014,524380,524316,589976,459030,524412,524348,590040,459022,524396,524332,590008,524300,524428,524364,590072,459009,524370,524306,524570,459025,524402,524338,590020,459017,524386,524322,589988,524290,524418,524354,590052,459013,524378,524314,589972,459029,524410,524346,590036,459021,524394,524330,590004,524298,524426,524362,590068,459011,524374,524310,524574,459027,524406,524342,590028,459019,524390,524326,589996,524294,524422,524358,590060,459015,524382,524318,589980,459031,524414,524350,590044,459023,524398,524334,590012,524302,524430,524366,590076,459008,524369,524305,524569,459024,524401,524337,590018,459016,524385,524321,589986,524289,524417,524353,590050,459012,524377,524313,589970,459028,524409,524345,590034,459020,524393,524329,590002,524297,524425,524361,590066,459010,524373,524309,524573,459026,524405,524341,590026,459018,524389,524325,589994,524293,524421,524357,590058,459014,524381,524317,589978,459030,524413,524349,590042,459022,524397,524333,590010,524301,524429,524365,590074,459009,524371,524307,524571,459025,524403,524339,590022,459017,524387,524323,589990,524291,524419,524355,590054,459013,524379,524315,589974,459029,524411,524347,590038,459021,524395,524331,590006,524299,524427,524363,590070,459011,524375,524311,524575,459027,524407,524343,590030,459019,524391,524327,589998,524295,524423,524359,590062,459015,524383,524319,589982,459031,524415,524351,590046,459023,524399,524335,590014,524303,524431,524367,590078,459008,524368,524304,524568,459024,524400,524336,590017,459016,524384,524320,589985,524288,524416,524352,590049,459012,524376,524312,589969,459028,524408,524344,590033,459020,524392,524328,590001,524296,524424,524360,590065,459010,524372,524308,524572,459026,524404,524340,590025,459018,524388,524324,589993,524292,524420,524356,590057,459014,524380,524316,589977,459030,524412,524348,590041,459022,524396,524332,590009,524300,524428,524364,590073,459009,524370,524306,524570,459025,524402,524338,590021,459017,524386,524322,589989,524290,524418,524354,590053,459013,524378,524314,589973,459029,524410,524346,590037,459021,524394,524330,590005,524298,524426,524362,590069,459011,524374,524310,524574,459027,524406,524342,590029,459019,524390,524326,589997,524294,524422,524358,590061,459015,524382,524318,589981,459031,524414,524350,590045,459023,524398,524334,590013,524302,524430,524366,590077,459008,524369,524305,524569,459024,524401,524337,590019,459016,524385,524321,589987,524289,524417,524353,590051,459012,524377,524313,589971,459028,524409,524345,590035,459020,524393,524329,590003,524297,524425,524361,590067,459010,524373,524309,524573,459026,524405,524341,590027,459018,524389,524325,589995,524293,524421,524357,590059,459014,524381,524317,589979,459030,524413,524349,590043,459022,524397,524333,590011,524301,524429,524365,590075,459009,524371,524307,524571,459025,524403,524339,590023,459017,524387,524323,589991,524291,524419,524355,590055,459013,524379,524315,589975,459029,524411,524347,590039,459021,524395,524331,590007,524299,524427,524363,590071,459011,524375,524311,524575,459027,524407,524343,590031,459019,524391,524327,589999,524295,524423,524359,590063,459015,524383,524319,589983,459031,524415,524351,590047,459023,524399,524335,590015,524303,524431,524367,590079]),9],n=[new Uint32Array([327680,327696,327688,327704,327684,327700,327692,327708,327682,327698,327690,327706,327686,327702,327694,0,327681,327697,327689,327705,327685,327701,327693,327709,327683,327699,327691,327707,327687,327703,327695,0]),5];return e.prototype=Object.create(DecodeStream.prototype),e.prototype.getBits=function(e){for(var a,i=this.codeSize,r=this.codeBuf,s=this.bytes,n=this.bytesPos;e>i;)"undefined"==typeof(a=s[n++])&&t("Bad encoding in flate stream"),r|=a<>e,this.codeSize=i-=e,this.bytesPos=n,a},e.prototype.getCode=function(e){for(var a=e[0],i=e[1],r=this.codeSize,s=this.codeBuf,n=this.bytes,o=this.bytesPos;i>r;){var h;"undefined"==typeof(h=n[o++])&&t("Bad encoding in flate stream"),s|=h<>16,c=65535&f;return(0==r||d>r||0==d)&&t("Bad encoding in flate stream"),this.codeBuf=s>>d,this.codeSize=r-d,this.bytesPos=o,c},e.prototype.generateHuffmanTable=function(t){for(var e=t.length,a=0,i=0;e>i;++i)t[i]>a&&(a=t[i]);for(var r=1<=n;++n,o<<=1,h<<=1)for(var f=0;e>f;++f)if(t[f]==n){for(var d=0,c=o,i=0;n>i;++i)d=d<<1|1&c,c>>=1;for(var i=d;r>i;i+=h)s[i]=n<<16|f;++o}return[s,a]},e.prototype.readBlock=function(){function e(t,e,a,i,r){for(var s=t.getBits(a)+i;s-- >0;)e[I++]=r}var o=this.getBits(3);if(1&o&&(this.eof=!0),o>>=1,0==o){var h,f=this.bytes,d=this.bytesPos;"undefined"==typeof(h=f[d++])&&t("Bad block header in flate stream");var c=h;"undefined"==typeof(h=f[d++])&&t("Bad block header in flate stream"),c|=h<<8,"undefined"==typeof(h=f[d++])&&t("Bad block header in flate stream");var l=h;"undefined"==typeof(h=f[d++])&&t("Bad block header in flate stream"),l|=h<<8,l!=(65535&~c)&&t("Bad uncompressed block length in flate stream"),this.codeBuf=0,this.codeSize=0;var u=this.bufferLength,p=this.ensureBuffer(u+c),g=u+c;this.bufferLength=g;for(var m=u;g>m;++m){if("undefined"==typeof(h=f[d++])){this.eof=!0;break}p[m]=h}return void(this.bytesPos=d)}var y,v;if(1==o)y=s,v=n;else if(2==o){for(var b=this.getBits(5)+257,w=this.getBits(5)+1,B=this.getBits(4)+4,T=Array(a.length),I=0;B>I;)T[a[I++]]=this.getBits(3);for(var U=this.generateHuffmanTable(T),D=0,I=0,k=b+w,A=new Array(k);k>I;){var C=this.getCode(U);16==C?e(this,A,2,3,D):17==C?e(this,A,3,3,D=0):18==C?e(this,A,7,11,D=0):A[I++]=D=C}y=this.generateHuffmanTable(A.slice(0,b)),v=this.generateHuffmanTable(A.slice(b,k))}else t("Unknown block type in flate stream");for(var p=this.buffer,S=p?p.length:0,P=this.bufferLength;;){var M=this.getCode(y);if(256>M)P+1>=S&&(p=this.ensureBuffer(P+1),S=p.length),p[P++]=M;else{if(256==M)return void(this.bufferLength=P);M-=257,M=i[M];var L=M>>16;L>0&&(L=this.getBits(L));var D=(65535&M)+L;M=this.getCode(v),M=r[M],L=M>>16,L>0&&(L=this.getBits(L));var x=(65535&M)+L;P+D>=S&&(p=this.ensureBuffer(P+D),S=p.length);for(var N=0;D>N;++N,++P)p[P]=p[P-x]}}},e}();(function(){var t;t=function(){function t(t){var e,a,i,r,s,n,o,h,f,d,c,l,u,p;for(this.data=t,this.pos=8,this.palette=[],this.imgData=[],this.transparency={},this.animation=null,this.text={},s=null;;){switch(e=this.readUInt32(),f=function(){var t,e;for(e=[],n=t=0;4>t;n=++t)e.push(String.fromCharCode(this.data[this.pos++]));return e}.call(this).join("")){case"IHDR":if(this.width=this.readUInt32(),this.height=this.readUInt32(),this.bits=this.data[this.pos++],this.colorType=this.data[this.pos++],this.compressionMethod=this.data[this.pos++],this.filterMethod=this.data[this.pos++],this.interlaceMethod=this.data[this.pos++],0!=this.interlaceMethod)throw new Error("Invalid interlaceMethod: "+this.interlaceMethod);break;case"acTL":this.animation={numFrames:this.readUInt32(),numPlays:this.readUInt32()||1/0,frames:[]};break;case"PLTE":this.palette=this.read(e);break;case"fcTL":s&&this.animation.frames.push(s),this.pos+=4,s={width:this.readUInt32(),height:this.readUInt32(),xOffset:this.readUInt32(),yOffset:this.readUInt32()},r=this.readUInt16(),i=this.readUInt16()||100,s.delay=1e3*r/i,s.disposeOp=this.data[this.pos++],s.blendOp=this.data[this.pos++],s.data=[];break;case"IDAT":case"fdAT":for("fdAT"===f&&(this.pos+=4,e-=4),t=(null!=s?s.data:void 0)||this.imgData,n=l=0;e>=0?e>l:l>e;n=e>=0?++l:--l)t.push(this.data[this.pos++]);break;case"tRNS":switch(this.transparency={},this.colorType){case 3:if(this.transparency.indexed=this.read(e),d=255-this.transparency.indexed.length,d>0)for(n=u=0;d>=0?d>u:u>d;n=d>=0?++u:--u)this.transparency.indexed.push(255);break;case 0:this.transparency.grayscale=this.read(e)[0];break;case 2:this.transparency.rgb=this.read(e)}break;case"tEXt":c=this.read(e),o=c.indexOf(0),h=String.fromCharCode.apply(String,c.slice(0,o)),this.text[h]=String.fromCharCode.apply(String,c.slice(o+1));break;case"IEND":return s&&this.animation.frames.push(s),this.colors=function(){switch(this.colorType){case 0:case 3:case 4:return 1;case 2:case 6:return 3}}.call(this),this.hasAlphaChannel=4===(p=this.colorType)||6===p,a=this.colors+(this.hasAlphaChannel?1:0),this.pixelBitlength=this.bits*a,this.colorSpace=function(){switch(this.colors){case 1:return"DeviceGray";case 3:return"DeviceRGB"}}.call(this),void(this.imgData=new Uint8Array(this.imgData));default:this.pos+=e}if(this.pos+=4,this.pos>this.data.length)throw new Error("Incomplete or corrupt PNG file")}}var e,a,i,r,s,n;return t.load=function(e,a){var i;return"function"==typeof canvas&&(a=canvas),i=new XMLHttpRequest,i.open("GET",e,!0),i.responseType="arraybuffer",i.onload=function(){var r,s;return r=new Uint8Array(i.response||i.mozResponseArrayBuffer),s=new t(r),s.url=e,"function"==typeof a?a(s):void 0},i.send(null)},r=0,i=1,s=2,a=0,e=1,t.prototype.read=function(t){var e,a,i;for(i=[],e=a=0;t>=0?t>a:a>t;e=t>=0?++a:--a)i.push(this.data[this.pos++]);return i},t.prototype.readUInt32=function(){var t,e,a,i;return t=this.data[this.pos++]<<24,e=this.data[this.pos++]<<16,a=this.data[this.pos++]<<8,i=this.data[this.pos++],t|e|a|i},t.prototype.readUInt16=function(){var t,e;return t=this.data[this.pos++]<<8,e=this.data[this.pos++],t|e},t.prototype.decodePixels=function(t){var e,a,i,r,s,n,o,h,f,d,c,l,u,p,g,m,y,v,b,w,B,T,I;if(null==t&&(t=this.imgData),0===t.length)return new Uint8Array(0);for(t=new FlateStream(t),t=t.getBytes(),l=this.pixelBitlength/8,m=l*this.width,u=new Uint8Array(m*this.height),n=t.length,g=0,p=0,a=0;n>p;){switch(t[p++]){case 0:for(r=b=0;m>b;r=b+=1)u[a++]=t[p++];break;case 1:for(r=w=0;m>w;r=w+=1)e=t[p++],s=l>r?0:u[a-l],u[a++]=(e+s)%256;break;case 2:for(r=B=0;m>B;r=B+=1)e=t[p++],i=(r-r%l)/l,y=g&&u[(g-1)*m+i*l+r%l],u[a++]=(y+e)%256;break;case 3:for(r=T=0;m>T;r=T+=1)e=t[p++],i=(r-r%l)/l,s=l>r?0:u[a-l],y=g&&u[(g-1)*m+i*l+r%l],u[a++]=(e+Math.floor((s+y)/2))%256;break;case 4:for(r=I=0;m>I;r=I+=1)e=t[p++],i=(r-r%l)/l,s=l>r?0:u[a-l],0===g?y=v=0:(y=u[(g-1)*m+i*l+r%l],v=i&&u[(g-1)*m+(i-1)*l+r%l]),o=s+y-v,h=Math.abs(o-s),d=Math.abs(o-y),c=Math.abs(o-v),f=d>=h&&c>=h?s:c>=d?y:v,u[a++]=(e+f)%256;break;default:throw new Error("Invalid filter algorithm: "+t[p-1])}g++}return u},t.prototype.decodePalette=function(){var t,e,a,i,r,s,n,o,h,f;i=this.palette,n=this.transparency.indexed||[];var d;for(d=4*i.length/3,s=new Uint8Array(d),r=0,a=i.length,t=0,e=o=0,h=i.length;h>o;e=o+=3)s[r++]=i[e],s[r++]=i[e+1],s[r++]=i[e+2],s[r++]=null!=(f=n[t++])?f:255;return s},t.prototype.getImageData=function(){var t=new self.ImageData(this.width,this.height);return this.copyToImageData(t,this.decodePixels()),t},t.prototype.getImageDataBuffer=function(){var t;return t=self.Uint8ClampedArray?new self.Uint8ClampedArray(this.width*this.height*4):new self.Uint8Array(this.width*this.height*4),this.copyToImageData(t,this.decodePixels()),t},t.prototype.copyToImageData=function(t,e){var a,i,r,s,n,o,h,f,d,c,l;if(i=this.colors,d=null,a=this.hasAlphaChannel,this.palette.length&&(d=null!=(l=this._decodedPalette)?l:this._decodedPalette=this.decodePalette(),i=4,a=!0),r=t.data||t,f=r.length,n=d||e,s=o=0,1===i)for(;f>s;)h=d?4*e[s/4]:o,c=n[h++],r[s++]=c,r[s++]=c,r[s++]=c,r[s++]=a?n[h++]:255,o=h;else for(;f>s;)h=d?4*e[s/4]:o,r[s++]=n[h++],r[s++]=n[h++],r[s++]=n[h++],r[s++]=a?n[h++]:255,o=h},t.prototype.decode=function(){var t;return t=new Uint8Array(this.width*this.height*4),this.copyToImageData(t,this.decodePixels()),t},t.prototype.decodeFrames=function(t){var e,a,i,r,s,o,h,f;if(this.animation){for(h=this.animation.frames,f=[],a=s=0,o=h.length;o>s;a=++s)e=h[a],i=t.createImageData(e.width,e.height),r=this.decodePixels(new Uint8Array(e.data)),this.copyToImageData(i,r),e.imageData=i,f.push(e.image=n(i));return f}},t}(),this.PNG=t}).call(this),onmessage=function(t){var e=t.data;switch(e.type){case"load":loadImage2(e)}};var canUseImageData=!1;testCanImageData(); \ No newline at end of file diff --git a/examples/layaair/frontend/bin/libs/workerloader.js b/examples/layaair/frontend/bin/libs/workerloader.js new file mode 100644 index 0000000..23023e8 --- /dev/null +++ b/examples/layaair/frontend/bin/libs/workerloader.js @@ -0,0 +1,132 @@ +var createImageBitmapOK=self.createImageBitmap?true:false; +onmessage =function (evt){ + + var data = evt.data;//通过evt.data获得发送来的数据 + loadImage2(data); + if(!isSet) + { + isSet=true; + setInterval(workerloop,1000); + } +} +var isSet=true; +function workerloop() +{ + myTrace("png:workerloop"); +} + + +var enableTrace=false; +var ifShowTraceToMain=false; +function myTrace(msg) +{ + if(!enableTrace) return; + console.log("png:"+msg) + if(ifShowTraceToMain) + { + showMsgToMain(msg); + } +} +function loadImage2(url) +{ + var xhr, + _this = this; + var failed=false; + xhr = new XMLHttpRequest; + xhr.open("GET", url, true); + //showMsgToMain("loadImage2"); + xhr.responseType = "arraybuffer"; + myTrace("load:"+url); + xhr.onload = function() { + var response=xhr.response || xhr.mozResponseArrayBuffer; + //showMsgToMain("onload:"); + myTrace("onload:"+url); + if((xhr.status != 200&&xhr.status!=0)||response.byteLength<10) + { + if(!failed) + { + failed=true; + pngFail(url,"loadFail from onload"+xhr.status); + } + + return; + } + var data, png; + data = new Uint8Array(response); + doCreateImageBitmap(data,url); + + }; + xhr.onerror = function(e){ + pngFail(url,"loadFail"); + } + + xhr.send(null); +} +function doCreateImageBitmap(response,url) +{ + try + { + //showMsgToMain("hihidoCreateImageBitmap"); + //showMsgToMain("doCreateImageBitmap:"+response); + //var startTime=getTimeNow(); + //showMsgToMain("new self.Blob"); + var startTime=getTimeNow(); + + response = new self.Blob([response],{type:"image/png"}); + self.createImageBitmap(response).then(function(imageBitmap) { + //showMsgToMain("imageBitmapCreated:"); + var data={}; + data.url=url; + data.imageBitmap=imageBitmap; + data.dataType="imageBitmap"; + + data.startTime=startTime; + data.decodeTime=getTimeNow()-startTime; + data.sendTime=getTimeNow(); + + myTrace("png:Decode By createImageBitmap,"+data.decodeTime,url); + + data.type="Image"; + postMessage(data,[data.imageBitmap]); + }).catch( + function(e) + { + showMsgToMain("catch e:"+e); + pngFail(url,"parse fail"+e+":ya"); + } + ) + }catch(e) + { + pngFail(url,"parse fail"+e.toString()+":ya"); + } +} +function getTimeNow() +{ + return new Date().getTime(); +} +function disableWorker(msg) +{ + var data={}; + data.url=url; + data.imagedata=null; + data.type="Disable"; + data.msg=msg; + postMessage(data); +} +function pngFail(url,msg) +{ + var data={}; + data.url=url; + data.imagedata=null; + data.type="Image"; + data.msg=msg; + console.log("png:"+msg+" "+url); + postMessage(data); +} +function showMsgToMain(msg) +{ + var data={}; + data.type="Msg"; + data.msg=msg; + postMessage(data); +} diff --git a/examples/layaair/frontend/bin/prefab/Bullet.json b/examples/layaair/frontend/bin/prefab/Bullet.json new file mode 100644 index 0000000..c264e46 --- /dev/null +++ b/examples/layaair/frontend/bin/prefab/Bullet.json @@ -0,0 +1 @@ +{"type":"Sprite","props":{"y":0,"x":0,"texture":"test/c2.png","presetID":1,"name":"buttle","isPresetRoot":true,"group":-2},"compId":1,"child":[{"type":"Script","props":{"radius":15,"presetID":2,"label":"buttle","isSensor":true,"runtime":"Laya.CircleCollider"},"compId":2},{"type":"Script","props":{"type":"kinematic","presetID":3,"group":-2,"runtime":"Laya.RigidBody"},"compId":3},{"type":"Script","props":{"presetID":4,"runtime":"script/Bullet.ts"},"compId":6}],"loadList":["test/c2.png"],"loadList3D":[]} \ No newline at end of file diff --git a/examples/layaair/frontend/bin/prefab/DropBox.json b/examples/layaair/frontend/bin/prefab/DropBox.json new file mode 100644 index 0000000..f549798 --- /dev/null +++ b/examples/layaair/frontend/bin/prefab/DropBox.json @@ -0,0 +1 @@ +{"type":"Sprite","props":{"texture":"test/b1.png","presetID":1,"pivotY":50,"pivotX":50,"name":"levelTxt","isPresetRoot":true,"group":1,"gravityScale":0.5},"compId":1,"child":[{"type":"Script","props":{"width":100,"presetID":2,"height":100,"runtime":"Laya.BoxCollider"},"compId":2},{"type":"Script","props":{"type":"dynamic","presetID":3,"group":-1,"gravityScale":0.5,"runtime":"Laya.RigidBody"},"compId":3},{"type":"Text","props":{"y":0,"x":11.5,"width":77,"valign":"middle","text":"1","presetID":4,"name":"levelTxt","height":100,"fontSize":100,"color":"#ffffff","align":"center","runtime":"Laya.Text"},"compId":4},{"type":"Script","props":{"presetID":5,"runtime":"script/DropBox.ts"},"compId":9}],"loadList":["test/b1.png"],"loadList3D":[]} \ No newline at end of file diff --git a/examples/layaair/frontend/bin/res/atlas/.rec b/examples/layaair/frontend/bin/res/atlas/.rec new file mode 100644 index 0000000..37d5e5c --- /dev/null +++ b/examples/layaair/frontend/bin/res/atlas/.rec @@ -0,0 +1,53 @@ +D . +D comp +P 316AD948 btn_close.png +P 5B258D17 button.png +P 3C493DD4 check_circle.png +P 98E54F0D checkbox.png +P 6B7AB858 clip_num.png +P 63A22FAC clip_tree_arrow.png +P D749C312 clip_tree_folder.png +P 8E9C8386 colorPicker.png +P 704C5D70 combobox.png +P D566AE8B fontClip.png +P 38AB8F3F fontClip_num.png +P 6EF336AE hscroll$bar.png +P 7FF47AC5 hscroll$down.png +P 3D7B147A hscroll$up.png +P 750BD445 hscroll.png +P 9A5EF899 hslider$bar.png +P 9CED7132 hslider.png +P BA2A0579 html.png +P 8236CD48 image.png +P 4ACB7AEF img_bg.png +P FCD04607 img_bg2.png +P 23FB4D29 img_bg3.png +P 5FD17798 img_bg4.png +P 2BE22124 img_bg5.png +P BA28BD65 img_blank.png +P BA2A0579 label.png +P B017E53E progress$bar.png +P C05839CD progress.png +P 3C493DD4 radio.png +P 3C493DD4 radiogroup.png +P 5BA25C15 tab.png +P A3D7A036 textarea.png +P A3D7A036 textinput.png +P 2DCE1DF9 vscroll$bar.png +P 6FE7EA34 vscroll$down.png +P 0587871F vscroll$up.png +P 5FD17798 vscroll.png +P DDDDFB9E vslider$bar.png +P 01BAE7F5 vslider.png +D sound +R 1DC3ABD8 destroy.wav +R FF0B6E8D hit.wav +D test +P 1DFA6065 b1.png +P 90AE1DE1 b2.png +P 9A09F804 block.png +P 65CC7075 c1.png +P 4D16AC06 c2.png +P 39B957DA p1.png +P 2E1973F5 t1.png +P F8700A3B tra.png diff --git a/examples/layaair/frontend/bin/res/atlas/comp.atlas b/examples/layaair/frontend/bin/res/atlas/comp.atlas new file mode 100644 index 0000000..aced843 --- /dev/null +++ b/examples/layaair/frontend/bin/res/atlas/comp.atlas @@ -0,0 +1 @@ +{"frames":{"btn_close.png":{"frame":{"h":96,"idx":0,"w":32,"x":564,"y":632},"sourceSize":{"h":96,"w":32},"spriteSourceSize":{"x":0,"y":0}},"button.png":{"frame":{"h":141,"idx":0,"w":128,"x":0,"y":465},"sourceSize":{"h":141,"w":128},"spriteSourceSize":{"x":0,"y":0}},"check_circle.png":{"frame":{"h":192,"idx":0,"w":64,"x":448,"y":461},"sourceSize":{"h":192,"w":64},"spriteSourceSize":{"x":0,"y":0}},"checkbox.png":{"frame":{"h":192,"idx":0,"w":64,"x":383,"y":461},"sourceSize":{"h":192,"w":64},"spriteSourceSize":{"x":0,"y":0}},"clip_num.png":{"frame":{"h":32,"idx":0,"w":251,"x":0,"y":607},"sourceSize":{"h":64,"w":260},"spriteSourceSize":{"x":4,"y":18}},"clip_tree_arrow.png":{"frame":{"h":77,"idx":0,"w":15,"x":257,"y":658},"sourceSize":{"h":128,"w":64},"spriteSourceSize":{"x":25,"y":25}},"clip_tree_folder.png":{"frame":{"h":76,"idx":0,"w":16,"x":228,"y":465},"sourceSize":{"h":95,"w":32},"spriteSourceSize":{"x":8,"y":10}},"colorPicker.png":{"frame":{"h":180,"idx":0,"w":61,"x":513,"y":415},"sourceSize":{"h":180,"w":61},"spriteSourceSize":{"x":0,"y":0}},"combobox.png":{"frame":{"h":210,"idx":0,"w":256,"x":450,"y":0},"sourceSize":{"h":210,"w":256},"spriteSourceSize":{"x":0,"y":0}},"fontClip.png":{"frame":{"h":63,"idx":0,"w":252,"x":0,"y":640},"sourceSize":{"h":64,"w":256},"spriteSourceSize":{"x":2,"y":0}},"fontClip_num.png":{"frame":{"h":50,"idx":0,"w":378,"x":257,"y":364},"sourceSize":{"h":51,"w":380},"spriteSourceSize":{"x":1,"y":1}},"hscroll$bar.png":{"frame":{"h":96,"idx":0,"w":32,"x":674,"y":461},"sourceSize":{"h":96,"w":32},"spriteSourceSize":{"x":0,"y":0}},"hscroll$down.png":{"frame":{"h":96,"idx":0,"w":32,"x":641,"y":461},"sourceSize":{"h":96,"w":32},"spriteSourceSize":{"x":0,"y":0}},"hscroll$up.png":{"frame":{"h":96,"idx":0,"w":32,"x":531,"y":632},"sourceSize":{"h":96,"w":32},"spriteSourceSize":{"x":0,"y":0}},"hscroll.png":{"frame":{"h":32,"idx":0,"w":256,"x":0,"y":704},"sourceSize":{"h":32,"w":256},"spriteSourceSize":{"x":0,"y":0}},"hslider$bar.png":{"frame":{"h":216,"idx":0,"w":32,"x":575,"y":415},"sourceSize":{"h":216,"w":32},"spriteSourceSize":{"x":0,"y":0}},"hslider.png":{"frame":{"h":32,"idx":0,"w":209,"x":257,"y":415},"sourceSize":{"h":32,"w":209},"spriteSourceSize":{"x":0,"y":0}},"html.png":{"frame":{"h":1,"idx":0,"w":1,"x":255,"y":658},"sourceSize":{"h":1,"w":1},"spriteSourceSize":{"x":0,"y":0}},"image.png":{"frame":{"h":313,"idx":0,"w":449,"x":0,"y":0},"sourceSize":{"h":313,"w":512},"spriteSourceSize":{"x":28,"y":0}},"img_bg.png":{"frame":{"h":152,"idx":0,"w":256,"x":450,"y":211},"sourceSize":{"h":152,"w":256},"spriteSourceSize":{"x":0,"y":0}},"img_bg2.png":{"frame":{"h":32,"idx":0,"w":128,"x":273,"y":671},"sourceSize":{"h":32,"w":128},"spriteSourceSize":{"x":0,"y":0}},"img_bg3.png":{"frame":{"h":32,"idx":0,"w":128,"x":273,"y":704},"sourceSize":{"h":32,"w":128},"spriteSourceSize":{"x":0,"y":0}},"img_bg4.png":{"frame":{"h":64,"idx":0,"w":32,"x":597,"y":671},"sourceSize":{"h":64,"w":32},"spriteSourceSize":{"x":0,"y":0}},"img_bg5.png":{"frame":{"h":64,"idx":0,"w":32,"x":630,"y":671},"sourceSize":{"h":64,"w":32},"spriteSourceSize":{"x":0,"y":0}},"img_blank.png":{"frame":{"h":10,"idx":0,"w":10,"x":597,"y":632},"sourceSize":{"h":10,"w":10},"spriteSourceSize":{"x":0,"y":0}},"label.png":{"frame":{"h":1,"idx":0,"w":1,"x":253,"y":658},"sourceSize":{"h":1,"w":1},"spriteSourceSize":{"x":0,"y":0}},"progress$bar.png":{"frame":{"h":32,"idx":0,"w":128,"x":402,"y":704},"sourceSize":{"h":32,"w":128},"spriteSourceSize":{"x":0,"y":0}},"progress.png":{"frame":{"h":24,"idx":0,"w":116,"x":129,"y":562},"sourceSize":{"h":24,"w":116},"spriteSourceSize":{"x":0,"y":0}},"radio.png":{"frame":{"h":192,"idx":0,"w":64,"x":318,"y":461},"sourceSize":{"h":192,"w":64},"spriteSourceSize":{"x":0,"y":0}},"radiogroup.png":{"frame":{"h":192,"idx":0,"w":64,"x":253,"y":465},"sourceSize":{"h":192,"w":64},"spriteSourceSize":{"x":0,"y":0}},"tab.png":{"frame":{"h":150,"idx":0,"w":256,"x":0,"y":314},"sourceSize":{"h":150,"w":256},"spriteSourceSize":{"x":0,"y":0}},"textarea.png":{"frame":{"h":32,"idx":0,"w":128,"x":402,"y":671},"sourceSize":{"h":32,"w":128},"spriteSourceSize":{"x":0,"y":0}},"textinput.png":{"frame":{"h":32,"idx":0,"w":128,"x":257,"y":314},"sourceSize":{"h":32,"w":128},"spriteSourceSize":{"x":0,"y":0}},"vscroll$bar.png":{"frame":{"h":96,"idx":0,"w":32,"x":162,"y":465},"sourceSize":{"h":96,"w":32},"spriteSourceSize":{"x":0,"y":0}},"vscroll$down.png":{"frame":{"h":96,"idx":0,"w":32,"x":195,"y":465},"sourceSize":{"h":96,"w":32},"spriteSourceSize":{"x":0,"y":0}},"vscroll$up.png":{"frame":{"h":96,"idx":0,"w":32,"x":129,"y":465},"sourceSize":{"h":96,"w":32},"spriteSourceSize":{"x":0,"y":0}},"vscroll.png":{"frame":{"h":64,"idx":0,"w":32,"x":663,"y":558},"sourceSize":{"h":64,"w":32},"spriteSourceSize":{"x":0,"y":0}},"vslider$bar.png":{"frame":{"h":96,"idx":0,"w":90,"x":636,"y":364},"sourceSize":{"h":96,"w":147},"spriteSourceSize":{"x":41,"y":0}},"vslider.png":{"frame":{"h":209,"idx":0,"w":32,"x":608,"y":461},"sourceSize":{"h":209,"w":32},"spriteSourceSize":{"x":0,"y":0}}},"meta":{"image":"comp.png","prefix":"comp/"}} \ No newline at end of file diff --git a/examples/layaair/frontend/bin/res/atlas/comp.png b/examples/layaair/frontend/bin/res/atlas/comp.png new file mode 100644 index 0000000..16f9ff4 Binary files /dev/null and b/examples/layaair/frontend/bin/res/atlas/comp.png differ diff --git a/examples/layaair/frontend/bin/res/atlas/test.atlas b/examples/layaair/frontend/bin/res/atlas/test.atlas new file mode 100644 index 0000000..e69ca35 --- /dev/null +++ b/examples/layaair/frontend/bin/res/atlas/test.atlas @@ -0,0 +1 @@ +{"frames":{"b1.png":{"frame":{"h":100,"idx":0,"w":100,"x":155,"y":0},"sourceSize":{"h":100,"w":100},"spriteSourceSize":{"x":0,"y":0}},"b2.png":{"frame":{"h":30,"idx":0,"w":30,"x":57,"y":186},"sourceSize":{"h":30,"w":30},"spriteSourceSize":{"x":0,"y":0}},"block.png":{"frame":{"h":20,"idx":0,"w":20,"x":57,"y":217},"sourceSize":{"h":20,"w":20},"spriteSourceSize":{"x":0,"y":0}},"c1.png":{"frame":{"h":100,"idx":0,"w":100,"x":0,"y":85},"sourceSize":{"h":100,"w":100},"spriteSourceSize":{"x":0,"y":0}},"c2.png":{"frame":{"h":30,"idx":0,"w":30,"x":88,"y":202},"sourceSize":{"h":30,"w":30},"spriteSourceSize":{"x":0,"y":0}},"p1.png":{"frame":{"h":54,"idx":0,"w":56,"x":0,"y":186},"sourceSize":{"h":64,"w":64},"spriteSourceSize":{"x":4,"y":5}},"t1.png":{"frame":{"h":100,"idx":0,"w":100,"x":101,"y":101},"sourceSize":{"h":100,"w":100},"spriteSourceSize":{"x":0,"y":0}},"tra.png":{"frame":{"h":84,"idx":0,"w":154,"x":0,"y":0},"sourceSize":{"h":84,"w":154},"spriteSourceSize":{"x":0,"y":0}}},"meta":{"image":"test.png","prefix":"test/"}} \ No newline at end of file diff --git a/examples/layaair/frontend/bin/res/atlas/test.png b/examples/layaair/frontend/bin/res/atlas/test.png new file mode 100644 index 0000000..11994fe Binary files /dev/null and b/examples/layaair/frontend/bin/res/atlas/test.png differ diff --git a/examples/layaair/frontend/bin/sound/destroy.wav b/examples/layaair/frontend/bin/sound/destroy.wav new file mode 100644 index 0000000..75270c8 Binary files /dev/null and b/examples/layaair/frontend/bin/sound/destroy.wav differ diff --git a/examples/layaair/frontend/bin/sound/hit.wav b/examples/layaair/frontend/bin/sound/hit.wav new file mode 100644 index 0000000..e12b711 Binary files /dev/null and b/examples/layaair/frontend/bin/sound/hit.wav differ diff --git a/examples/layaair/frontend/bin/test/TestAni.ani b/examples/layaair/frontend/bin/test/TestAni.ani new file mode 100644 index 0000000..304d3b8 --- /dev/null +++ b/examples/layaair/frontend/bin/test/TestAni.ani @@ -0,0 +1 @@ +{"type":"View","props":{"sceneWidth":600,"sceneHeight":400,"sceneColor":"#000000"},"compId":1,"child":[{"type":"GraphicNode","props":{"y":0,"x":0,"width":20,"skin":"test/b1.png","pivotY":10,"pivotX":10,"height":20},"compId":36},{"type":"GraphicNode","props":{"y":20,"x":20,"width":20,"skin":"test/b1.png","pivotY":10,"pivotX":10,"height":20},"compId":37},{"type":"GraphicNode","props":{"y":20,"x":0,"width":20,"skin":"test/b1.png","pivotY":10,"pivotX":10,"height":20},"compId":38},{"type":"GraphicNode","props":{"y":20,"x":-20,"width":20,"skin":"test/b1.png","pivotY":10,"pivotX":10,"height":20},"compId":39},{"type":"GraphicNode","props":{"y":0,"x":20,"width":20,"skin":"test/b1.png","pivotY":10,"pivotX":10,"height":20},"compId":40},{"type":"GraphicNode","props":{"y":0,"x":-20,"width":20,"skin":"test/b1.png","pivotY":10,"pivotX":10,"height":20},"compId":41},{"type":"GraphicNode","props":{"y":-20,"x":20,"width":20,"skin":"test/b1.png","pivotY":10,"pivotX":10,"height":20},"compId":42},{"type":"GraphicNode","props":{"y":-20,"x":0,"width":20,"skin":"test/b1.png","pivotY":10,"pivotX":10,"height":20},"compId":43},{"type":"GraphicNode","props":{"y":-20,"x":-20,"width":20,"skin":"test/b1.png","pivotY":10,"pivotX":10,"height":20},"compId":44}],"animations":[{"nodes":[{"target":36,"keyframes":{"y":[{"value":0,"tweenMethod":"linearNone","tween":true,"target":36,"key":"y","index":0},{"value":-30,"tweenMethod":"linearNone","tween":true,"target":36,"key":"y","index":5}],"x":[{"value":0,"tweenMethod":"linearNone","tween":true,"target":36,"key":"x","index":0},{"value":-165,"tweenMethod":"linearNone","tween":true,"target":36,"key":"x","index":5}],"alpha":[{"value":1,"tweenMethod":"linearNone","tween":true,"target":36,"key":"alpha","index":0},{"value":0.2,"tweenMethod":"linearNone","tween":true,"target":36,"key":"alpha","index":5}]}},{"target":37,"keyframes":{"y":[{"value":20,"tweenMethod":"linearNone","tween":true,"target":37,"key":"y","index":0},{"value":30,"tweenMethod":"linearNone","tween":true,"target":37,"key":"y","index":5}],"x":[{"value":20,"tweenMethod":"linearNone","tween":true,"target":37,"key":"x","index":0},{"value":155,"tweenMethod":"linearNone","tween":true,"target":37,"key":"x","index":5}],"alpha":[{"value":1,"tweenMethod":"linearNone","tween":true,"target":37,"key":"alpha","index":0},{"value":0.7,"tweenMethod":"linearNone","tween":true,"target":37,"key":"alpha","index":5}]}},{"target":38,"keyframes":{"y":[{"value":20,"tweenMethod":"linearNone","tween":true,"target":38,"key":"y","index":0},{"value":116,"tweenMethod":"linearNone","tween":true,"target":38,"key":"y","index":5}],"x":[{"value":0,"tweenMethod":"linearNone","tween":true,"target":38,"key":"x","index":0},{"value":73,"tweenMethod":"linearNone","tween":true,"target":38,"key":"x","index":5}],"alpha":[{"value":1,"tweenMethod":"linearNone","tween":true,"target":38,"key":"alpha","index":0},{"value":0.2,"tweenMethod":"linearNone","tween":true,"target":38,"key":"alpha","index":5}]}},{"target":39,"keyframes":{"y":[{"value":20,"tweenMethod":"linearNone","tween":true,"target":39,"key":"y","index":0},{"value":116,"tweenMethod":"linearNone","tween":true,"target":39,"key":"y","index":5}],"x":[{"value":-20,"tweenMethod":"linearNone","tween":true,"target":39,"key":"x","index":0},{"value":-51,"tweenMethod":"linearNone","tween":true,"target":39,"key":"x","index":5}],"alpha":[{"value":1,"tweenMethod":"linearNone","tween":true,"target":39,"key":"alpha","index":0},{"value":0.4,"tweenMethod":"linearNone","tween":true,"target":39,"key":"alpha","index":5}]}},{"target":40,"keyframes":{"y":[{"value":0,"tweenMethod":"linearNone","tween":true,"target":40,"key":"y","index":0},{"value":-79,"tweenMethod":"linearNone","tween":true,"target":40,"key":"y","index":5}],"x":[{"value":20,"tweenMethod":"linearNone","tween":true,"target":40,"key":"x","index":0},{"value":124,"tweenMethod":"linearNone","tween":true,"target":40,"key":"x","index":5}],"alpha":[{"value":1,"tweenMethod":"linearNone","tween":true,"target":40,"key":"alpha","index":0},{"value":0.3,"tweenMethod":"linearNone","tween":true,"target":40,"key":"alpha","index":5}]}},{"target":41,"keyframes":{"y":[{"value":0,"tweenMethod":"linearNone","tween":true,"target":41,"key":"y","index":0},{"value":71,"tweenMethod":"linearNone","tween":true,"target":41,"key":"y","index":5}],"x":[{"value":-20,"tweenMethod":"linearNone","tween":true,"target":41,"key":"x","index":0},{"value":-111,"tweenMethod":"linearNone","tween":true,"target":41,"key":"x","index":5}],"alpha":[{"value":1,"tweenMethod":"linearNone","tween":true,"target":41,"key":"alpha","index":0},{"value":0.6,"tweenMethod":"linearNone","tween":true,"target":41,"key":"alpha","index":5}]}},{"target":42,"keyframes":{"y":[{"value":-20,"tweenMethod":"linearNone","tween":true,"target":42,"key":"y","index":0},{"value":-49,"tweenMethod":"linearNone","tween":true,"target":42,"key":"y","index":5}],"x":[{"value":20,"tweenMethod":"linearNone","tween":true,"target":42,"key":"x","index":0},{"value":53,"tweenMethod":"linearNone","tween":true,"target":42,"key":"x","index":5}],"alpha":[{"value":1,"tweenMethod":"linearNone","tween":true,"target":42,"key":"alpha","index":0},{"value":0,"tweenMethod":"linearNone","tween":true,"target":42,"key":"alpha","index":5}]}},{"target":43,"keyframes":{"y":[{"value":-20,"tweenMethod":"linearNone","tween":true,"target":43,"key":"y","index":0},{"value":-136,"tweenMethod":"linearNone","tween":true,"target":43,"key":"y","index":5}],"alpha":[{"value":1,"tweenMethod":"linearNone","tween":true,"target":43,"key":"alpha","index":0},{"value":0.2,"tweenMethod":"linearNone","tween":true,"target":43,"key":"alpha","index":5}]}},{"target":44,"keyframes":{"y":[{"value":-20,"tweenMethod":"linearNone","tween":true,"target":44,"key":"y","index":0},{"value":-69,"tweenMethod":"linearNone","tween":true,"target":44,"key":"y","index":5}],"x":[{"value":-20,"tweenMethod":"linearNone","tween":true,"target":44,"key":"x","index":0},{"value":-91,"tweenMethod":"linearNone","tween":true,"target":44,"key":"x","index":5}],"alpha":[{"value":1,"tweenMethod":"linearNone","tween":true,"target":44,"key":"alpha","index":0},{"value":0.5,"tweenMethod":"linearNone","tween":true,"target":44,"key":"alpha","index":5}]}}],"name":"ani1","id":1,"frameRate":30,"events":[],"action":0}],"loadList":["test/b1.png"],"loadList3D":[]} \ No newline at end of file diff --git a/examples/layaair/frontend/bin/test/TestScene.json b/examples/layaair/frontend/bin/test/TestScene.json new file mode 100644 index 0000000..a4e066b --- /dev/null +++ b/examples/layaair/frontend/bin/test/TestScene.json @@ -0,0 +1 @@ +{"type":"Scene","props":{"width":640,"runtime":"script/GameUI.ts","name":"gameBox","height":1136},"compId":1,"child":[{"type":"Sprite","props":{"y":1116,"x":-83,"width":805,"texture":"test/block.png","name":"ground","height":20},"compId":3,"child":[{"type":"Script","props":{"y":0,"x":0,"width":805,"label":"ground","height":20,"runtime":"Laya.BoxCollider"},"compId":5},{"type":"Script","props":{"type":"static","runtime":"Laya.RigidBody"},"compId":6}]},{"type":"Sprite","props":{"y":0,"x":0,"name":"gameBox"},"compId":18},{"type":"Sprite","props":{"y":0,"x":0,"name":"UI"},"compId":14,"child":[{"type":"Label","props":{"y":50,"x":158,"width":272,"var":"scoreLbl","height":47,"fontSize":40,"color":"#51c524","align":"center"},"compId":17},{"type":"Label","props":{"y":0,"x":0,"width":640,"var":"tipLbll","valign":"middle","text":"别让箱子掉下来\\n\\n点击屏幕开始游戏","height":1136,"fontSize":40,"color":"#c6302e","align":"center"},"compId":16}]},{"type":"Script","props":{"enabled":true,"dropBox":"@Prefab:prefab/DropBox.prefab","bullet":"@Prefab:prefab/Bullet.prefab","runtime":"script/GameControl.ts"},"compId":20}],"loadList":["test/block.png","prefab/DropBox.prefab","prefab/Bullet.prefab"],"loadList3D":[]} \ No newline at end of file diff --git a/examples/layaair/frontend/bin/version.json b/examples/layaair/frontend/bin/version.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/examples/layaair/frontend/bin/version.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/examples/layaair/frontend/laya/.laya b/examples/layaair/frontend/laya/.laya new file mode 100644 index 0000000..f98b3da --- /dev/null +++ b/examples/layaair/frontend/laya/.laya @@ -0,0 +1,53 @@ + + img,temp,sound + embed + png,jpg + bin/res/atlas + bin + src/ui + + + 3 + bin/ui.json + Sprite,Box,List,Tab,RadioGroup,ViewStack,Panel,HBox,VBox,Tree + Scene,View,Dialog + + 1 + + 80 + + + + 2048 + 2048 + 512 + 512 + false + true + + 2D + fixedwidth + none + top + left + 640 + 1136 + src/view + 0 + 1 + + false + true + true + false + + 2.0 + false + false + true + false + + \ No newline at end of file diff --git a/examples/layaair/frontend/laya/assets/comp/btn_close.png b/examples/layaair/frontend/laya/assets/comp/btn_close.png new file mode 100644 index 0000000..f50c6ce Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/btn_close.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/button.png b/examples/layaair/frontend/laya/assets/comp/button.png new file mode 100644 index 0000000..fa64e62 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/button.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/check_circle.png b/examples/layaair/frontend/laya/assets/comp/check_circle.png new file mode 100644 index 0000000..a33d91c Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/check_circle.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/checkbox.png b/examples/layaair/frontend/laya/assets/comp/checkbox.png new file mode 100644 index 0000000..8dc13ad Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/checkbox.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/clip_num.png b/examples/layaair/frontend/laya/assets/comp/clip_num.png new file mode 100644 index 0000000..2e5a039 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/clip_num.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/clip_tree_arrow.png b/examples/layaair/frontend/laya/assets/comp/clip_tree_arrow.png new file mode 100644 index 0000000..60f0fed Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/clip_tree_arrow.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/clip_tree_folder.png b/examples/layaair/frontend/laya/assets/comp/clip_tree_folder.png new file mode 100644 index 0000000..bddabe5 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/clip_tree_folder.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/colorPicker.png b/examples/layaair/frontend/laya/assets/comp/colorPicker.png new file mode 100644 index 0000000..4d59a3e Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/colorPicker.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/combobox.png b/examples/layaair/frontend/laya/assets/comp/combobox.png new file mode 100644 index 0000000..d809144 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/combobox.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/fontClip.png b/examples/layaair/frontend/laya/assets/comp/fontClip.png new file mode 100644 index 0000000..0f4d4f4 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/fontClip.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/fontClip_num.png b/examples/layaair/frontend/laya/assets/comp/fontClip_num.png new file mode 100644 index 0000000..c32175a Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/fontClip_num.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/hscroll$bar.png b/examples/layaair/frontend/laya/assets/comp/hscroll$bar.png new file mode 100644 index 0000000..016a2ea Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/hscroll$bar.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/hscroll$down.png b/examples/layaair/frontend/laya/assets/comp/hscroll$down.png new file mode 100644 index 0000000..78597a9 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/hscroll$down.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/hscroll$up.png b/examples/layaair/frontend/laya/assets/comp/hscroll$up.png new file mode 100644 index 0000000..99b1fe8 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/hscroll$up.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/hscroll.png b/examples/layaair/frontend/laya/assets/comp/hscroll.png new file mode 100644 index 0000000..d38328c Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/hscroll.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/hslider$bar.png b/examples/layaair/frontend/laya/assets/comp/hslider$bar.png new file mode 100644 index 0000000..c095bde Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/hslider$bar.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/hslider.png b/examples/layaair/frontend/laya/assets/comp/hslider.png new file mode 100644 index 0000000..59e6d5e Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/hslider.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/html.png b/examples/layaair/frontend/laya/assets/comp/html.png new file mode 100644 index 0000000..fcee416 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/html.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/image.png b/examples/layaair/frontend/laya/assets/comp/image.png new file mode 100644 index 0000000..9eb763f Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/image.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/img_bg.png b/examples/layaair/frontend/laya/assets/comp/img_bg.png new file mode 100644 index 0000000..6b440f7 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/img_bg.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/img_bg2.png b/examples/layaair/frontend/laya/assets/comp/img_bg2.png new file mode 100644 index 0000000..49b1678 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/img_bg2.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/img_bg3.png b/examples/layaair/frontend/laya/assets/comp/img_bg3.png new file mode 100644 index 0000000..e349135 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/img_bg3.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/img_bg4.png b/examples/layaair/frontend/laya/assets/comp/img_bg4.png new file mode 100644 index 0000000..5bd3b67 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/img_bg4.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/img_bg5.png b/examples/layaair/frontend/laya/assets/comp/img_bg5.png new file mode 100644 index 0000000..6632dbc Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/img_bg5.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/img_blank.png b/examples/layaair/frontend/laya/assets/comp/img_blank.png new file mode 100644 index 0000000..89608f1 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/img_blank.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/label.png b/examples/layaair/frontend/laya/assets/comp/label.png new file mode 100644 index 0000000..fcee416 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/label.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/progress$bar.png b/examples/layaair/frontend/laya/assets/comp/progress$bar.png new file mode 100644 index 0000000..88f46d1 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/progress$bar.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/progress.png b/examples/layaair/frontend/laya/assets/comp/progress.png new file mode 100644 index 0000000..076895d Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/progress.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/radio.png b/examples/layaair/frontend/laya/assets/comp/radio.png new file mode 100644 index 0000000..a33d91c Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/radio.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/radiogroup.png b/examples/layaair/frontend/laya/assets/comp/radiogroup.png new file mode 100644 index 0000000..a33d91c Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/radiogroup.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/tab.png b/examples/layaair/frontend/laya/assets/comp/tab.png new file mode 100644 index 0000000..0676324 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/tab.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/textarea.png b/examples/layaair/frontend/laya/assets/comp/textarea.png new file mode 100644 index 0000000..fc58a4e Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/textarea.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/textinput.png b/examples/layaair/frontend/laya/assets/comp/textinput.png new file mode 100644 index 0000000..fc58a4e Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/textinput.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/vscroll$bar.png b/examples/layaair/frontend/laya/assets/comp/vscroll$bar.png new file mode 100644 index 0000000..3e9a397 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/vscroll$bar.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/vscroll$down.png b/examples/layaair/frontend/laya/assets/comp/vscroll$down.png new file mode 100644 index 0000000..e6a0f14 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/vscroll$down.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/vscroll$up.png b/examples/layaair/frontend/laya/assets/comp/vscroll$up.png new file mode 100644 index 0000000..bee7a53 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/vscroll$up.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/vscroll.png b/examples/layaair/frontend/laya/assets/comp/vscroll.png new file mode 100644 index 0000000..5bd3b67 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/vscroll.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/vslider$bar.png b/examples/layaair/frontend/laya/assets/comp/vslider$bar.png new file mode 100644 index 0000000..a9eeb15 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/vslider$bar.png differ diff --git a/examples/layaair/frontend/laya/assets/comp/vslider.png b/examples/layaair/frontend/laya/assets/comp/vslider.png new file mode 100644 index 0000000..3bc3b0d Binary files /dev/null and b/examples/layaair/frontend/laya/assets/comp/vslider.png differ diff --git a/examples/layaair/frontend/laya/assets/sound/destroy.wav b/examples/layaair/frontend/laya/assets/sound/destroy.wav new file mode 100644 index 0000000..75270c8 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/sound/destroy.wav differ diff --git a/examples/layaair/frontend/laya/assets/sound/hit.wav b/examples/layaair/frontend/laya/assets/sound/hit.wav new file mode 100644 index 0000000..e12b711 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/sound/hit.wav differ diff --git a/examples/layaair/frontend/laya/assets/test/b1.png b/examples/layaair/frontend/laya/assets/test/b1.png new file mode 100644 index 0000000..90a7e4b Binary files /dev/null and b/examples/layaair/frontend/laya/assets/test/b1.png differ diff --git a/examples/layaair/frontend/laya/assets/test/b2.png b/examples/layaair/frontend/laya/assets/test/b2.png new file mode 100644 index 0000000..c219e2a Binary files /dev/null and b/examples/layaair/frontend/laya/assets/test/b2.png differ diff --git a/examples/layaair/frontend/laya/assets/test/block.png b/examples/layaair/frontend/laya/assets/test/block.png new file mode 100644 index 0000000..8076b40 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/test/block.png differ diff --git a/examples/layaair/frontend/laya/assets/test/c1.png b/examples/layaair/frontend/laya/assets/test/c1.png new file mode 100644 index 0000000..7661d66 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/test/c1.png differ diff --git a/examples/layaair/frontend/laya/assets/test/c2.png b/examples/layaair/frontend/laya/assets/test/c2.png new file mode 100644 index 0000000..2dcf432 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/test/c2.png differ diff --git a/examples/layaair/frontend/laya/assets/test/p1.png b/examples/layaair/frontend/laya/assets/test/p1.png new file mode 100644 index 0000000..5ec3d78 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/test/p1.png differ diff --git a/examples/layaair/frontend/laya/assets/test/t1.png b/examples/layaair/frontend/laya/assets/test/t1.png new file mode 100644 index 0000000..25f0008 Binary files /dev/null and b/examples/layaair/frontend/laya/assets/test/t1.png differ diff --git a/examples/layaair/frontend/laya/assets/test/tra.png b/examples/layaair/frontend/laya/assets/test/tra.png new file mode 100644 index 0000000..793b58f Binary files /dev/null and b/examples/layaair/frontend/laya/assets/test/tra.png differ diff --git a/examples/layaair/frontend/laya/ignore.cfg b/examples/layaair/frontend/laya/ignore.cfg new file mode 100644 index 0000000..0f9f370 --- /dev/null +++ b/examples/layaair/frontend/laya/ignore.cfg @@ -0,0 +1 @@ +{"src/Main.ts":true,"src/GameConfig.ts":true,"src/ui":true} \ No newline at end of file diff --git a/examples/layaair/frontend/laya/pageStyles.xml b/examples/layaair/frontend/laya/pageStyles.xml new file mode 100644 index 0000000..1fdd4f8 --- /dev/null +++ b/examples/layaair/frontend/laya/pageStyles.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/examples/layaair/frontend/laya/pages/prefab/Bullet.prefab b/examples/layaair/frontend/laya/pages/prefab/Bullet.prefab new file mode 100644 index 0000000..80500a8 --- /dev/null +++ b/examples/layaair/frontend/laya/pages/prefab/Bullet.prefab @@ -0,0 +1,71 @@ +{ + "x":0, + "type":"Sprite", + "selectedBox":1, + "selecteID":5, + "referenceLines":null, + "props":{"y":0,"x":0,"texture":"test/c2.png","presetID":1,"preset":"laya/pages/prefab/Bullet.prefab","name":"buttle","isPresetRoot":true,"group":-2}, + "nodeParent":-1, + "label":"buttle", + "isOpen":true, + "isDirectory":true, + "isAniNode":true, + "hasChild":true, + "compId":1, + "child":[ + { + "x":15, + "type":"CircleCollider", + "switchAble":true, + "removeAble":true, + "props":{"radius":15,"presetID":2,"preset":"laya/pages/prefab/Bullet.prefab","label":"buttle","isSensor":true}, + "nodeParent":1, + "label":"CircleCollider(Bullet)", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":2, + "child":[ + ] + }, + { + "x":15, + "type":"RigidBody", + "switchAble":true, + "removeAble":true, + "props":{"type":"kinematic","presetID":3,"preset":"laya/pages/prefab/Bullet.prefab","group":-2}, + "nodeParent":1, + "label":"RigidBody(Bullet)", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":3, + "child":[ + ] + }, + { + "x":15, + "type":"Script", + "switchAble":true, + "source":"src/script/Bullet.ts", + "removeAble":true, + "props":{"presetID":4,"preset":"laya/pages/prefab/Bullet.prefab"}, + "nodeParent":1, + "label":"Bullet", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":6, + "child":[ + ] + }], + "animations":[ + { + "nodes":[ + ], + "name":"ani1", + "id":1, + "frameRate":24, + "action":0 + }] +} \ No newline at end of file diff --git a/examples/layaair/frontend/laya/pages/prefab/DropBox.prefab b/examples/layaair/frontend/laya/pages/prefab/DropBox.prefab new file mode 100644 index 0000000..d65f4d6 --- /dev/null +++ b/examples/layaair/frontend/laya/pages/prefab/DropBox.prefab @@ -0,0 +1,85 @@ +{ + "x":0, + "type":"Sprite", + "selectedBox":1, + "selecteID":8, + "props":{"texture":"test/b1.png","presetID":1,"preset":"laya/pages/prefab/DropBox.prefab","pivotY":50,"pivotX":50,"name":"levelTxt","isPresetRoot":true,"group":1,"gravityScale":0.5}, + "nodeParent":-1, + "label":"levelTxt", + "isOpen":true, + "isDirectory":true, + "isAniNode":true, + "hasChild":true, + "compId":1, + "child":[ + { + "x":15, + "type":"BoxCollider", + "switchAble":true, + "removeAble":true, + "props":{"width":100,"presetID":2,"preset":"laya/pages/prefab/DropBox.prefab","height":100}, + "nodeParent":1, + "label":"BoxCollider(DropBox)", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":2, + "child":[ + ] + }, + { + "x":15, + "type":"RigidBody", + "switchAble":true, + "removeAble":true, + "props":{"type":"dynamic","presetID":3,"preset":"laya/pages/prefab/DropBox.prefab","group":-1,"gravityScale":0.5}, + "nodeParent":1, + "label":"RigidBody(DropBox)", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":3, + "child":[ + ] + }, + { + "x":15, + "type":"Text", + "props":{"y":0,"x":11.5,"width":77,"valign":"middle","text":"1","presetID":4,"preset":"laya/pages/prefab/DropBox.prefab","name":"levelTxt","height":100,"fontSize":100,"color":"#ffffff","align":"center"}, + "nodeParent":1, + "label":"levelTxt", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":4, + "child":[ + ] + }, + { + "x":15, + "type":"Script", + "switchAble":true, + "source":"src/script/DropBox.ts", + "removeAble":true, + "props":{"presetID":5,"preset":"laya/pages/prefab/DropBox.prefab"}, + "nodeParent":1, + "label":"DropBox", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":9, + "child":[ + ] + }], + "animations":[ + { + "nodes":[ + ], + "name":"ani1", + "id":1, + "frameRate":24, + "events":[ + ], + "action":0 + }] +} \ No newline at end of file diff --git a/examples/layaair/frontend/laya/pages/test/TestAni.ani b/examples/layaair/frontend/laya/pages/test/TestAni.ani new file mode 100644 index 0000000..e30c835 --- /dev/null +++ b/examples/layaair/frontend/laya/pages/test/TestAni.ani @@ -0,0 +1,620 @@ +{ + "type":"View", + "selectedBox":1, + "selecteID":36, + "referenceLines":null, + "props":{"sceneWidth":600,"sceneHeight":400,"sceneColor":"#000000"}, + "nodeParent":-1, + "label":"View", + "isOpen":true, + "isDirectory":true, + "isAniNode":true, + "hasChild":true, + "compId":1, + "child":[ + { + "type":"GraphicNode", + "props":{"y":0,"x":0,"width":20,"skin":"test/b1.png","pivotY":10,"pivotX":10,"height":20}, + "nodeParent":1, + "label":"GraphicNode", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":36, + "child":[ + ] + }, + { + "type":"GraphicNode", + "props":{"y":20,"x":20,"width":20,"skin":"test/b1.png","pivotY":10,"pivotX":10,"height":20}, + "nodeParent":1, + "label":"GraphicNode", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":37, + "child":[ + ] + }, + { + "type":"GraphicNode", + "props":{"y":20,"x":0,"width":20,"skin":"test/b1.png","pivotY":10,"pivotX":10,"height":20}, + "nodeParent":1, + "label":"GraphicNode", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":38, + "child":[ + ] + }, + { + "type":"GraphicNode", + "props":{"y":20,"x":-20,"width":20,"skin":"test/b1.png","pivotY":10,"pivotX":10,"height":20}, + "nodeParent":1, + "label":"GraphicNode", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":39, + "child":[ + ] + }, + { + "type":"GraphicNode", + "props":{"y":0,"x":20,"width":20,"skin":"test/b1.png","pivotY":10,"pivotX":10,"height":20}, + "nodeParent":1, + "label":"GraphicNode", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":40, + "child":[ + ] + }, + { + "type":"GraphicNode", + "props":{"y":0,"x":-20,"width":20,"skin":"test/b1.png","pivotY":10,"pivotX":10,"height":20}, + "nodeParent":1, + "label":"GraphicNode", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":41, + "child":[ + ] + }, + { + "type":"GraphicNode", + "props":{"y":-20,"x":20,"width":20,"skin":"test/b1.png","pivotY":10,"pivotX":10,"height":20}, + "nodeParent":1, + "label":"GraphicNode", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":42, + "child":[ + ] + }, + { + "type":"GraphicNode", + "props":{"y":-20,"x":0,"width":20,"skin":"test/b1.png","pivotY":10,"pivotX":10,"height":20}, + "nodeParent":1, + "label":"GraphicNode", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":43, + "child":[ + ] + }, + { + "type":"GraphicNode", + "props":{"y":-20,"x":-20,"width":20,"skin":"test/b1.png","pivotY":10,"pivotX":10,"height":20}, + "nodeParent":1, + "label":"GraphicNode", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":44, + "child":[ + ] + }], + "animations":[ + { + "nodes":[ + { + "target":36, + "keyframes":{ + "y":[ + { + "value":0, + "tweenMethod":"linearNone", + "tween":true, + "target":36, + "key":"y", + "index":0 + }, + { + "value":-30, + "tweenMethod":"linearNone", + "tween":true, + "target":36, + "key":"y", + "index":5 + }], + "x":[ + { + "value":0, + "tweenMethod":"linearNone", + "tween":true, + "target":36, + "key":"x", + "index":0 + }, + { + "value":-165, + "tweenMethod":"linearNone", + "tween":true, + "target":36, + "key":"x", + "index":5 + }], + "alpha":[ + { + "value":1, + "tweenMethod":"linearNone", + "tween":true, + "target":36, + "key":"alpha", + "index":0 + }, + { + "value":0.2, + "tweenMethod":"linearNone", + "tween":true, + "target":36, + "key":"alpha", + "index":5 + }] + } + }, + { + "target":37, + "keyframes":{ + "y":[ + { + "value":20, + "tweenMethod":"linearNone", + "tween":true, + "target":37, + "key":"y", + "index":0 + }, + { + "value":30, + "tweenMethod":"linearNone", + "tween":true, + "target":37, + "key":"y", + "index":5 + }], + "x":[ + { + "value":20, + "tweenMethod":"linearNone", + "tween":true, + "target":37, + "key":"x", + "index":0 + }, + { + "value":155, + "tweenMethod":"linearNone", + "tween":true, + "target":37, + "key":"x", + "index":5 + }], + "alpha":[ + { + "value":1, + "tweenMethod":"linearNone", + "tween":true, + "target":37, + "key":"alpha", + "index":0 + }, + { + "value":0.7, + "tweenMethod":"linearNone", + "tween":true, + "target":37, + "key":"alpha", + "index":5 + }] + } + }, + { + "target":38, + "keyframes":{ + "y":[ + { + "value":20, + "tweenMethod":"linearNone", + "tween":true, + "target":38, + "key":"y", + "index":0 + }, + { + "value":116, + "tweenMethod":"linearNone", + "tween":true, + "target":38, + "key":"y", + "index":5 + }], + "x":[ + { + "value":0, + "tweenMethod":"linearNone", + "tween":true, + "target":38, + "key":"x", + "index":0 + }, + { + "value":73, + "tweenMethod":"linearNone", + "tween":true, + "target":38, + "key":"x", + "index":5 + }], + "alpha":[ + { + "value":1, + "tweenMethod":"linearNone", + "tween":true, + "target":38, + "key":"alpha", + "index":0 + }, + { + "value":0.2, + "tweenMethod":"linearNone", + "tween":true, + "target":38, + "key":"alpha", + "index":5 + }] + } + }, + { + "target":39, + "keyframes":{ + "y":[ + { + "value":20, + "tweenMethod":"linearNone", + "tween":true, + "target":39, + "key":"y", + "index":0 + }, + { + "value":116, + "tweenMethod":"linearNone", + "tween":true, + "target":39, + "key":"y", + "index":5 + }], + "x":[ + { + "value":-20, + "tweenMethod":"linearNone", + "tween":true, + "target":39, + "key":"x", + "index":0 + }, + { + "value":-51, + "tweenMethod":"linearNone", + "tween":true, + "target":39, + "key":"x", + "index":5 + }], + "alpha":[ + { + "value":1, + "tweenMethod":"linearNone", + "tween":true, + "target":39, + "key":"alpha", + "index":0 + }, + { + "value":0.4, + "tweenMethod":"linearNone", + "tween":true, + "target":39, + "key":"alpha", + "index":5 + }] + } + }, + { + "target":40, + "keyframes":{ + "y":[ + { + "value":0, + "tweenMethod":"linearNone", + "tween":true, + "target":40, + "key":"y", + "index":0 + }, + { + "value":-79, + "tweenMethod":"linearNone", + "tween":true, + "target":40, + "key":"y", + "index":5 + }], + "x":[ + { + "value":20, + "tweenMethod":"linearNone", + "tween":true, + "target":40, + "key":"x", + "index":0 + }, + { + "value":124, + "tweenMethod":"linearNone", + "tween":true, + "target":40, + "key":"x", + "index":5 + }], + "alpha":[ + { + "value":1, + "tweenMethod":"linearNone", + "tween":true, + "target":40, + "key":"alpha", + "index":0 + }, + { + "value":0.3, + "tweenMethod":"linearNone", + "tween":true, + "target":40, + "key":"alpha", + "index":5 + }] + } + }, + { + "target":41, + "keyframes":{ + "y":[ + { + "value":0, + "tweenMethod":"linearNone", + "tween":true, + "target":41, + "key":"y", + "index":0 + }, + { + "value":71, + "tweenMethod":"linearNone", + "tween":true, + "target":41, + "key":"y", + "index":5 + }], + "x":[ + { + "value":-20, + "tweenMethod":"linearNone", + "tween":true, + "target":41, + "key":"x", + "index":0 + }, + { + "value":-111, + "tweenMethod":"linearNone", + "tween":true, + "target":41, + "key":"x", + "index":5 + }], + "alpha":[ + { + "value":1, + "tweenMethod":"linearNone", + "tween":true, + "target":41, + "key":"alpha", + "index":0 + }, + { + "value":0.6, + "tweenMethod":"linearNone", + "tween":true, + "target":41, + "key":"alpha", + "index":5 + }] + } + }, + { + "target":42, + "keyframes":{ + "y":[ + { + "value":-20, + "tweenMethod":"linearNone", + "tween":true, + "target":42, + "key":"y", + "index":0 + }, + { + "value":-49, + "tweenMethod":"linearNone", + "tween":true, + "target":42, + "key":"y", + "index":5 + }], + "x":[ + { + "value":20, + "tweenMethod":"linearNone", + "tween":true, + "target":42, + "key":"x", + "index":0 + }, + { + "value":53, + "tweenMethod":"linearNone", + "tween":true, + "target":42, + "key":"x", + "index":5 + }], + "alpha":[ + { + "value":1, + "tweenMethod":"linearNone", + "tween":true, + "target":42, + "key":"alpha", + "index":0 + }, + { + "value":0, + "tweenMethod":"linearNone", + "tween":true, + "target":42, + "key":"alpha", + "index":5 + }] + } + }, + { + "target":43, + "keyframes":{ + "y":[ + { + "value":-20, + "tweenMethod":"linearNone", + "tween":true, + "target":43, + "key":"y", + "index":0 + }, + { + "value":-136, + "tweenMethod":"linearNone", + "tween":true, + "target":43, + "key":"y", + "index":5 + }], + "alpha":[ + { + "value":1, + "tweenMethod":"linearNone", + "tween":true, + "target":43, + "key":"alpha", + "index":0 + }, + { + "value":0.2, + "tweenMethod":"linearNone", + "tween":true, + "target":43, + "key":"alpha", + "index":5 + }] + } + }, + { + "target":44, + "keyframes":{ + "y":[ + { + "value":-20, + "tweenMethod":"linearNone", + "tween":true, + "target":44, + "key":"y", + "index":0 + }, + { + "value":-69, + "tweenMethod":"linearNone", + "tween":true, + "target":44, + "key":"y", + "index":5 + }], + "x":[ + { + "value":-20, + "tweenMethod":"linearNone", + "tween":true, + "target":44, + "key":"x", + "index":0 + }, + { + "value":-91, + "tweenMethod":"linearNone", + "tween":true, + "target":44, + "key":"x", + "index":5 + }], + "alpha":[ + { + "value":1, + "tweenMethod":"linearNone", + "tween":true, + "target":44, + "key":"alpha", + "index":0 + }, + { + "value":0.5, + "tweenMethod":"linearNone", + "tween":true, + "target":44, + "key":"alpha", + "index":5 + }] + } + }], + "name":"ani1", + "id":1, + "frameRate":30, + "events":[ + ], + "action":0 + }] +} \ No newline at end of file diff --git a/examples/layaair/frontend/laya/pages/test/TestScene.scene b/examples/layaair/frontend/laya/pages/test/TestScene.scene new file mode 100644 index 0000000..76f0856 --- /dev/null +++ b/examples/layaair/frontend/laya/pages/test/TestScene.scene @@ -0,0 +1,140 @@ +{ + "x":0, + "type":"Scene", + "selectedBox":1, + "searchKey":"Scene,gameBox", + "referenceLines":null, + "props":{"width":640,"sceneColor":"#000000","runtime":"script/GameUI.ts","name":"gameBox","height":1136}, + "nodeParent":-1, + "maxID":21, + "label":"gameBox", + "isOpen":true, + "isDirectory":true, + "isAniNode":true, + "hasChild":true, + "compId":1, + "child":[ + { + "x":15, + "type":"Sprite", + "searchKey":"Sprite,ground", + "props":{"y":1116,"x":-83,"width":805,"texture":"test/block.png","name":"ground","height":20}, + "nodeParent":1, + "label":"ground", + "isOpen":false, + "isDirectory":true, + "isAniNode":true, + "hasChild":true, + "compId":3, + "child":[ + { + "type":"BoxCollider", + "searchKey":"BoxCollider", + "props":{"y":0,"x":0,"width":805,"label":"ground","height":20}, + "nodeParent":3, + "label":"BoxCollider", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":5, + "child":[ + ] + }, + { + "type":"RigidBody", + "searchKey":"RigidBody", + "props":{"type":"static"}, + "nodeParent":3, + "label":"RigidBody", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":6, + "child":[ + ] + }] + }, + { + "x":15, + "type":"Sprite", + "searchKey":"Sprite,gameBox", + "props":{"y":0,"x":0,"name":"gameBox"}, + "nodeParent":1, + "label":"gameBox", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":18, + "child":[ + ] + }, + { + "x":15, + "type":"Sprite", + "searchKey":"Sprite,UI", + "props":{"y":0,"x":0,"name":"UI"}, + "nodeParent":1, + "label":"UI", + "isOpen":true, + "isDirectory":true, + "isAniNode":true, + "hasChild":true, + "compId":14, + "child":[ + { + "x":30, + "type":"Label", + "searchKey":"Label,scoreLbl", + "props":{"y":50,"x":158,"width":272,"var":"scoreLbl","height":47,"fontSize":40,"color":"#51c524","align":"center"}, + "nodeParent":14, + "label":"scoreLbl", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":17, + "child":[ + ] + }, + { + "x":30, + "type":"Label", + "searchKey":"Label,tipLbll", + "props":{"y":0,"x":0,"width":640,"var":"tipLbll","valign":"middle","text":"别让箱子掉下来\\n\\n点击屏幕开始游戏","height":1136,"fontSize":40,"color":"#c6302e","align":"center"}, + "nodeParent":14, + "label":"tipLbll", + "isDirectory":false, + "isAniNode":true, + "hasChild":false, + "compId":16, + "child":[ + ] + }] + }, + { + "x":15, + "type":"Script", + "switchAble":true, + "source":"src/script/GameControl.ts", + "searchKey":"Script,GameControl", + "removeAble":true, + "props":{"enabled":true,"dropBox":"@Prefab:prefab/DropBox.prefab","bullet":"@Prefab:prefab/Bullet.prefab"}, + "nodeParent":1, + "label":"GameControl", + "isDirectory":false, + "isClose":false, + "isAniNode":true, + "hasChild":false, + "compId":20, + "child":[ + ] + }], + "animations":[ + { + "nodes":[ + ], + "name":"ani1", + "id":1, + "frameRate":24, + "action":0 + }] +} \ No newline at end of file diff --git a/examples/layaair/frontend/libs/LayaAir.d.ts b/examples/layaair/frontend/libs/LayaAir.d.ts new file mode 100644 index 0000000..7fa0b7c --- /dev/null +++ b/examples/layaair/frontend/libs/LayaAir.d.ts @@ -0,0 +1,45795 @@ + + /** + * Config 用于配置一些全局参数。如需更改,请在初始化引擎之前设置。 + */ + declare class Config { + + /** + * 动画 Animation 的默认播放时间间隔,单位为毫秒。 + */ + static animationInterval:number; + + /** + * 设置是否抗锯齿,只对2D(WebGL)、3D有效。 + */ + static isAntialias:boolean; + + /** + * 设置画布是否透明,只对2D(WebGL)、3D有效。 + */ + static isAlpha:boolean; + + /** + * 设置画布是否预乘,只对2D(WebGL)、3D有效。 + */ + static premultipliedAlpha:boolean; + + /** + * 设置画布的是否开启模板缓冲,只对2D(WebGL)、3D有效。 + */ + static isStencil:boolean; + + /** + * 是否保留渲染缓冲区。 + */ + static preserveDrawingBuffer:boolean; + + /** + * 当使用webGL渲染2d的时候,每次创建vb是否直接分配足够64k个顶点的缓存。这样可以提高效率。 + */ + static webGL2D_MeshAllocMaxMem:boolean; + + /** + * 是否强制使用像素采样。适用于像素风格游戏 + */ + static is2DPixelArtGame:boolean; + + /** + * 是否使用webgl2 + */ + static useWebGL2:boolean; + + /** + * 是否打印Webgl指令,同时定位webgl报错 + */ + static printWebglOrder:boolean; + + /** + * 是否允许GPUInstance动态合并,仅对3D有效。 + */ + static allowGPUInstanceDynamicBatch:boolean; + + /** + * 是否允许静态合并 + */ + static enableStaticBatch:boolean; + static useRetinalCanvas:boolean; + } + + /** + * Config3D 类用于创建3D初始化配置。 + */ + declare class Config3D implements Laya.IClone { + static get useCannonPhysics():boolean; + static set useCannonPhysics(value:boolean); + static set enableDynamicManager(value:boolean); + static get enableDynamicManager():boolean; + static set enableStaticManager(value:boolean); + static get enableStaticManager():boolean; + + /** + * 是否开启抗锯齿。 + */ + isAntialias:boolean; + + /** + * 画布是否包含透明通道。 + */ + isAlpha:boolean; + + /** + * 画布是否预乘。 + */ + premultipliedAlpha:boolean; + + /** + * 画布是否开启模板缓冲。 + */ + isStencil:boolean; + + /** + * 是否开启多光源,如果场景不需要多光源,关闭后可提升性能。 + */ + enableMultiLight:boolean; + + /** + * 是否开启八叉树裁剪。 + */ + octreeCulling:boolean; + + /** + * 八叉树初始化尺寸。 + */ + octreeInitialSize:number; + + /** + * 八叉树初始化中心。 + */ + octreeInitialCenter:Laya.Vector3; + + /** + * 八叉树最小尺寸。 + */ + octreeMinNodeSize:number; + + /** + * 八叉树松散值。 + */ + octreeLooseness:number; + + /** + * 是否开启视锥裁剪调试。 + * 如果开启八叉树裁剪,使用红色绘制高层次八叉树节点包围盒,使用蓝色绘制低层次八叉节点包围盒,精灵包围盒和八叉树节点包围盒颜色一致,但Alpha为非透明。如果视锥完全包含八叉树节点,八叉树节点包围盒和精灵包围盒变为蓝色,同样精灵包围盒的Alpha为非透明。 + * 如果不开启八叉树裁剪,使用绿色像素线绘制精灵包围盒。 + */ + debugFrustumCulling:boolean; + + /** + * PBR材质渲染质量。 + */ + pbrRenderQuality:Laya.PBRRenderQuality; + + /** + * 是否使用CANNONJS物理引擎 + */ + isUseCannonPhysicsEngine:boolean; + + /** + * 默认物理功能初始化内存,单位为M。 + */ + get defaultPhysicsMemory():number; + set defaultPhysicsMemory(value:number); + + /** + * 最大光源数量。 + */ + get maxLightCount():number; + set maxLightCount(value:number); + + /** + * X、Y、Z轴的光照集群数量,Z值会影响Cluster接受区域光(点光、聚光)影响的数量,Math.floor(2048 / lightClusterCount.z - 1) * 4 为每个Cluster的最大平均接受区域光数量,如果每个Cluster所接受光源影响的平均数量大于该值,则较远的Cluster会忽略其中多余的光照影响。 + */ + get lightClusterCount():Laya.Vector3; + set lightClusterCount(value:Laya.Vector3); + + /** + * 创建一个 Config3D 实例。 + */ + + constructor(); + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(dest:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * Laya 是全局对象的引用入口集。 + * Laya类引用了一些常用的全局对象,比如Laya.stage:舞台,Laya.timer:时间管理器,Laya.loader:加载管理器,使用时注意大小写。 + */ + declare class Laya { + + /** + * 舞台对象的引用。 + */ + static stage:Laya.Stage; + + /** + * @private 系统时钟管理器,引擎内部使用 + */ + static systemTimer:Laya.Timer; + + /** + * @private 组件的start时钟管理器 + */ + static startTimer:Laya.Timer; + + /** + * @private 组件的物理时钟管理器 + */ + static physicsTimer:Laya.Timer; + + /** + * @private 组件的update时钟管理器 + */ + static updateTimer:Laya.Timer; + + /** + * @private 组件的lateUpdate时钟管理器 + */ + static lateTimer:Laya.Timer; + + /** + * 游戏主时针,同时也是管理场景,动画,缓动等效果时钟,通过控制本时针缩放,达到快进慢播效果 + */ + static timer:Laya.Timer; + + /** + * 加载管理器的引用。 + */ + static loader:Laya.LoaderManager; + + /** + * 当前引擎版本。 + */ + static version:string; + + /** + * @private Render 类的引用。 + */ + static render:Laya.Render; + + /** + * 是否是微信小游戏子域,默认为false* + */ + static isWXOpenDataContext:boolean; + + /** + * 微信小游戏是否需要在主域中自动将加载的文本数据自动传递到子域,默认 false* + */ + static isWXPosMsg:boolean; + + /** + * 兼容as3编译工具 + */ + static __init(_classs:any[]):void; + + /** + * 初始化引擎。使用引擎需要先初始化引擎,否则可能会报错。 + * @param width 初始化的游戏窗口宽度,又称设计宽度。 + * @param height 初始化的游戏窗口高度,又称设计高度。 + * @param plugins 插件列表,比如 WebGL(使用WebGL方式渲染)。 + * @return 返回原生canvas引用,方便对canvas属性进行修改 + */ + static init(width:number,height:number,...plugins:any[]):any; + + /** + * 表示是否捕获全局错误并弹出提示。默认为false。 + * 适用于移动设备等不方便调试的时候,设置为true后,如有未知错误,可以弹窗抛出详细错误堆栈。 + */ + static alertGlobalError(value:boolean):void; + + /** + * 开启DebugPanel + * @param debugJsPath laya.debugtool.js文件路径 + */ + static enableDebugPanel(debugJsPath?:string):void; + private static isNativeRender_enable:any; + + /** + * @private + */ + private static enableWebGLPlus:any; + + /** + * @private + */ + private static enableNative:any; + } + + /** + * Laya3D 类用于初始化3D设置。 + */ + declare class Laya3D { + + /** + * Hierarchy资源。 + */ + static HIERARCHY:string; + + /** + * Mesh资源。 + */ + static MESH:string; + + /** + * Material资源。 + */ + static MATERIAL:string; + + /** + * Texture2D资源。 + */ + static TEXTURE2D:string; + + /** + * TextureCube资源。 + */ + static TEXTURECUBE:string; + + /** + * TextureCube资源。 + */ + static TEXTURECUBEBIN:string; + + /** + * AnimationClip资源。 + */ + static ANIMATIONCLIP:string; + + /** + * Avatar资源。 + */ + static AVATAR:string; + + /** + * Terrain资源。 + */ + static TERRAINHEIGHTDATA:string; + + /** + * Terrain资源。 + */ + static TERRAINRES:string; + + /** + * SimpleAnimator资源。 + */ + static SIMPLEANIMATORBIN:string; + + /** + * 获取是否可以启用物理。 + * @param 是否启用物理 。 + */ + static get enablePhysics():any; + private static enableNative3D:any; + + /** + * @private + */ + private static formatRelativePath:any; + + /** + * 初始化Laya3D相关设置。 + * @param width 3D画布宽度。 + * @param height 3D画布高度。 + */ + static init(width:number,height:number,config?:Config3D,compolete?:Laya.Handler):void; + + /** + * 创建一个 Laya3D 实例。 + */ + + constructor(); + } + + /** + * 全局配置 + */ + declare class UIConfig { + + /** + * 是否开启触摸滚动(针对滚动条) + */ + static touchScrollEnable:boolean; + + /** + * 是否开启滑轮滚动(针对滚动条) + */ + static mouseWheelEnable:boolean; + + /** + * 是否显示滚动条按钮 + */ + static showButtons:boolean; + + /** + * 弹出框背景颜色 + */ + static popupBgColor:string; + + /** + * 弹出框背景透明度 + */ + static popupBgAlpha:number; + + /** + * 模式窗口点击边缘,是否关闭窗口,默认是关闭的 + */ + static closeDialogOnSide:boolean; + } +declare module Laya { + + /** + * 开始播放时调度。 + * @eventType Event.PLAYED + */ + + /** + * 暂停时调度。 + * @eventType Event.PAUSED + */ + + /** + * 完成一次循环时调度。 + * @eventType Event.COMPLETE + */ + + /** + * 停止时调度。 + * @eventType Event.STOPPED + */ + + /** + * AnimationPlayer 类用于动画播放器。 + */ + class AnimationPlayer extends EventDispatcher implements IDestroy { + + /** + * 是否缓存 + */ + isCache:boolean; + + /** + * 播放速率 + */ + playbackRate:number; + + /** + * 停止时是否归零 + */ + returnToZeroStopped:boolean; + + /** + * 获取动画数据模板 + * @param value 动画数据模板 + */ + get templet():AnimationTemplet; + + /** + * 设置动画数据模板,注意:修改此值会有计算开销。 + * @param value 动画数据模板 + */ + set templet(value:AnimationTemplet); + + /** + * 动画播放的起始时间位置。 + * @return 起始时间位置。 + */ + get playStart():number; + + /** + * 动画播放的结束时间位置。 + * @return 结束时间位置。 + */ + get playEnd():number; + + /** + * 获取动画播放一次的总时间 + * @return 动画播放一次的总时间 + */ + get playDuration():number; + + /** + * 获取动画播放的总总时间 + * @return 动画播放的总时间 + */ + get overallDuration():number; + + /** + * 获取当前动画索引 + * @return value 当前动画索引 + */ + get currentAnimationClipIndex():number; + + /** + * 获取当前帧数 + * @return 当前帧数 + */ + get currentKeyframeIndex():number; + + /** + * 获取当前精确时间,不包括重播时间 + * @return value 当前时间 + */ + get currentPlayTime():number; + + /** + * 获取当前帧时间,不包括重播时间 + * @return value 当前时间 + */ + get currentFrameTime():number; + + /** + * 获取缓存播放速率。* + * @return 缓存播放速率。 + */ + get cachePlayRate():number; + + /** + * 设置缓存播放速率,默认值为1.0,注意:修改此值会有计算开销。* + * @return value 缓存播放速率。 + */ + set cachePlayRate(value:number); + + /** + * 获取默认帧率* + * @return value 默认帧率 + */ + get cacheFrameRate():number; + + /** + * 设置默认帧率,每秒60帧,注意:修改此值会有计算开销。* + * @return value 缓存帧率 + */ + set cacheFrameRate(value:number); + + /** + * 设置当前播放位置 + * @param value 当前时间 + */ + set currentTime(value:number); + + /** + * 获取当前是否暂停 + * @return 是否暂停 + */ + get paused():boolean; + + /** + * 设置是否暂停 + * @param value 是否暂停 + */ + set paused(value:boolean); + + /** + * 获取缓存帧率间隔时间 + * @return 缓存帧率间隔时间 + */ + get cacheFrameRateInterval():number; + + /** + * 获取当前播放状态 + * @return 当前播放状态 + */ + get state():number; + + /** + * 获取是否已销毁。 + * @return 是否已销毁。 + */ + get destroyed():boolean; + + /** + * 创建一个 AnimationPlayer 实例。 + */ + + constructor(); + + /** + * @private + */ + private _setPlayParams:any; + + /** + * 动画停止了对应的参数。目前都是设置时间为最后 + * @private + */ + private _setPlayParamsWhenStop:any; + + /** + * 播放动画。 + * @param index 动画索引。 + * @param playbackRate 播放速率。 + * @param duration 播放时长(0为1次,Number.MAX_VALUE为循环播放)。 + * @param playStart 播放的起始时间位置。 + * @param playEnd 播放的结束时间位置。(0为动画一次循环的最长结束时间位置)。 + */ + play(index?:number,playbackRate?:number,overallDuration?:number,playStart?:number,playEnd?:number):void; + + /** + * 播放动画。 + * @param index 动画索引。 + * @param playbackRate 播放速率。 + * @param duration 播放时长(0为1次,Number.MAX_VALUE为循环播放)。 + * @param playStartFrame 播放的原始起始帧率位置。 + * @param playEndFrame 播放的原始结束帧率位置。(0为动画一次循环的最长结束时间位置)。 + */ + playByFrame(index?:number,playbackRate?:number,overallDuration?:number,playStartFrame?:number,playEndFrame?:number,fpsIn3DBuilder?:number):void; + + /** + * 停止播放当前动画 + * 如果不是立即停止就等待动画播放完成后再停止 + * @param immediate 是否立即停止 + */ + stop(immediate?:boolean):void; + + /** + * @private + */ + destroy():void; + } + + /** + * AnimationTemplet 类用于动画模板资源。 + */ + class AnimationTemplet extends Resource { + + /** + * 插值函数 + */ + static interpolation:any[]; + + /** + * @private + */ + private static _LinearInterpolation_0:any; + + /** + * @private + */ + private static _QuaternionInterpolation_1:any; + + /** + * @private + */ + private static _AngleInterpolation_2:any; + + /** + * @private + */ + private static _RadiansInterpolation_3:any; + + /** + * @private + */ + private static _Matrix4x4Interpolation_4:any; + + /** + * @private + */ + private static _NoInterpolation_5:any; + + /** + * @private + */ + private static _BezierInterpolation_6:any; + + /** + * @private + */ + private static _BezierInterpolation_7:any; + + /** + * @private + */ + protected unfixedCurrentFrameIndexes:Uint32Array; + + /** + * @private + */ + protected unfixedCurrentTimes:Float32Array; + + /** + * @private + */ + protected unfixedKeyframes:KeyFramesContent[]; + + /** + * @private + */ + protected unfixedLastAniIndex:number; + + /** + * @private + */ + private _boneCurKeyFrm:any; + + constructor(); + + /** + * @private + */ + parse(data:ArrayBuffer):void; + + /** + * 获取动画数量 + */ + getAnimationCount():number; + + /** + * 通过索引获取动画 + * @param aniIndex + */ + getAnimation(aniIndex:number):any; + + /** + * 获取动画时长 + * @param aniIndex + */ + getAniDuration(aniIndex:number):number; + + /** + * 获取动画nodes信息 + */ + getNodes(aniIndex:number):any; + + /** + * 获取动画骨骼信息 + */ + getNodeIndexWithName(aniIndex:number,name:string):number; + + /** + * 获取nodes长度 + */ + getNodeCount(aniIndex:number):number; + + /** + * 获取keyframes长度 + */ + getTotalkeyframesLength(aniIndex:number):number; + + /** + * 获取附加数据 + */ + getPublicExtData():ArrayBuffer; + + /** + * 获取动画信息数据 + */ + getAnimationDataWithCache(key:any,cacheDatas:any,aniIndex:number,frameIndex:number):Float32Array; + + /** + * 设置动画信息数据 + */ + setAnimationDataWithCache(key:any,cacheDatas:any[],aniIndex:number,frameIndex:number,data:any):void; + + /** + * 计算当前时间应该对应关键帧的哪一帧 + * @param nodeframes 当前骨骼的关键帧数据 + * @param nodeid 骨骼id,因为要使用和更新 _boneCurKeyFrm + * @param tm + * @return 问题 最后一帧有问题,例如倒数第二帧时间是0.033ms,则后两帧非常靠近,当实际给最后一帧的时候,根据帧数计算出的时间实际上落在倒数第二帧 使用与AnimationPlayer一致的累积时间就行 + */ + getNodeKeyFrame(nodeframes:KeyFramesContent[],nodeid:number,tm:number):number; + + /** + * 获取原始数据 + * @param aniIndex + * @param originalData + * @param nodesFrameIndices + * @param frameIndex + * @param playCurTime + */ + getOriginalData(aniIndex:number,originalData:Float32Array,nodesFrameIndices:any[],frameIndex:number,playCurTime:number):void; + + /** + * 获取nodes信息 + */ + getNodesCurrentFrameIndex(aniIndex:number,playCurTime:number):Uint32Array; + + /** + * 获取原始数据 + */ + getOriginalDataUnfixedRate(aniIndex:number,originalData:Float32Array,playCurTime:number):void; + } + + /** + * @private + */ + class Bone { + static ShowBones:any; + name:string; + root:Bone; + parentBone:Bone; + length:number; + transform:Transform; + resultTransform:Transform; + resultMatrix:Matrix; + inheritScale:boolean; + inheritRotation:boolean; + rotation:number; + resultRotation:number; + d:number; + + constructor(); + setTempMatrix(matrix:Matrix):void; + update(pMatrix?:Matrix|null):void; + updateChild():void; + setRotation(rd:number):void; + updateDraw(x:number,y:number):void; + addChild(bone:Bone):void; + findBone(boneName:string):Bone|null; + localToWorld(local:number[]):void; + } + class BoneSlot { + + /** + * 插槽名称 + */ + name:string; + + /** + * 插槽绑定的骨骼名称 + */ + parent:string; + + /** + * 插糟显示数据数据的名称 + */ + attachmentName:string; + + /** + * 原始数据的索引 + */ + srcDisplayIndex:number; + + /** + * 判断对象是否是原对象 + */ + type:string; + + /** + * 模板的指针 + */ + templet:Templet; + + /** + * 当前插槽对应的数据 + */ + currSlotData:SlotData; + + /** + * 当前插槽显示的纹理 + */ + currTexture:Texture|null; + + /** + * 显示对象对应的数据 + */ + currDisplayData:SkinSlotDisplayData|null; + + /** + * 显示皮肤的索引 + */ + displayIndex:number; + + /** + * @private + */ + originalIndex:number; + + /** + * @private 变形动画数据 + */ + deformData:any[]; + + /** + * 设置要显示的插槽数据 + * @param slotData + * @param disIndex + * @param freshIndex 是否重置纹理 + */ + showSlotData(slotData:SlotData,freshIndex?:boolean):void; + + /** + * 通过名字显示指定对象 + * @param name + */ + showDisplayByName(name:string):void; + + /** + * 替换贴图名 + * @param tarName 要替换的贴图名 + * @param newName 替换后的贴图名 + */ + replaceDisplayByName(tarName:string,newName:string):void; + + /** + * 替换贴图索引 + * @param tarIndex 要替换的索引 + * @param newIndex 替换后的索引 + */ + replaceDisplayByIndex(tarIndex:number,newIndex:number):void; + + /** + * 指定显示对象 + * @param index + */ + showDisplayByIndex(index:number):void; + + /** + * 替换皮肤 + * @param _texture + */ + replaceSkin(_texture:Texture):void; + + /** + * 保存父矩阵的索引 + * @param parentMatrix + */ + setParentMatrix(parentMatrix:Matrix):void; + private _mVerticleArr:any; + private static _tempMatrix:any; + static createSkinMesh():any; + private static isSameArr:any; + private getSaveVerticle:any; + static isSameMatrix(mtA:Matrix,mtB:Matrix):boolean; + private _preGraphicMatrix:any; + private static useSameMatrixAndVerticle:any; + private getSaveMatrix:any; + + /** + * 把纹理画到Graphics上 + * @param graphics + * @param noUseSave 不使用共享的矩阵对象 _tempResultMatrix,只有实时计算的时候才设置为true + */ + draw(graphics:GraphicsAni,boneMatrixArray:any[],noUseSave?:boolean,alpha?:number):void; + + /** + * 显示蒙皮动画 + * @param boneMatrixArray 当前帧的骨骼矩阵 + */ + private skinMesh:any; + + /** + * 画骨骼的起始点,方便调试 + * @param graphics + */ + drawBonePoint(graphics:Graphics):void; + + /** + * 得到显示对象的矩阵 + * @return + */ + private getDisplayMatrix:any; + + /** + * 得到插糟的矩阵 + * @return + */ + getMatrix():Matrix; + + /** + * 用原始数据拷贝出一个 + * @return + */ + copy():BoneSlot; + } + + /** + */ + class MeshData { + + /** + * 纹理 + */ + texture:Texture; + + /** + * uv数据 + */ + uvs:Float32Array; + + /** + * 顶点数据 + */ + vertices:Float32Array; + + /** + * 顶点索引 + */ + indexes:Uint16Array; + + /** + * uv变换矩阵 + */ + uvTransform:Matrix; + + /** + * 是否有uv变化矩阵 + */ + useUvTransform:boolean; + + /** + * 扩展像素,用来去除黑边 + */ + canvasPadding:number; + + /** + * 计算mesh的Bounds + * @return + */ + getBounds():Rectangle; + } + class SkinMeshForGraphic extends MeshData { + + constructor(); + + /** + * 矩阵 + */ + transform:Matrix|null; + init2(texture:Texture,ps:any[],verticles:any[],uvs:any[]):void; + } + + /** + * 事件数据 + */ + class EventData { + + /** + * 事件名称 + */ + name:string; + + /** + * 整数数据 + */ + intValue:number; + + /** + * 单精度浮点数数据 + */ + floatValue:number; + + /** + * 字符串数据 + */ + stringValue:string; + + /** + * 多媒体数据 + */ + audioValue:string; + + /** + * 事件数据 + */ + time:number; + + constructor(); + } + + /** + * 动画开始播放调度 + * @eventType Event.PLAYED + */ + + /** + * 动画停止播放调度 + * @eventType Event.STOPPED + */ + + /** + * 动画暂停播放调度 + * @eventType Event.PAUSED + */ + + /** + * 自定义事件。 + * @eventType Event.LABEL + */ + + /** + * 骨骼动画由TempletAnimationPlayerSkeleton三部分组成。 + */ + class Skeleton extends Sprite { + + /** + * 在canvas模式是否使用简化版的mesh绘制,简化版的mesh将不进行三角形绘制,而改为矩形绘制,能极大提高性能,但是可能某些mesh动画效果会不太正常 + */ + static useSimpleMeshInCanvas:boolean; + + /** + * 创建一个Skeleton对象 + * @param templet 骨骼动画模板 + * @param aniMode 动画模式,0不支持换装,1、2支持换装 + */ + + constructor(templet?:Templet,aniMode?:number); + + /** + * 初始化动画 + * @param templet 模板 + * @param aniMode 动画模式
模式描述
0 使用模板缓冲的数据,模板缓冲的数据,不允许修改(内存开销小,计算开销小,不支持换装)
1 使用动画自己的缓冲区,每个动画都会有自己的缓冲区,相当耗费内存 (内存开销大,计算开销小,支持换装)
2 使用动态方式,去实时去画(内存开销小,计算开销大,支持换装,不建议使用)
+ */ + init(templet:Templet,aniMode?:number):void; + + /** + * 得到资源的URL + */ + get url():string; + + /** + * 设置动画路径 + */ + set url(path:string); + + /** + * 通过加载直接创建动画 + * @param path 要加载的动画文件路径 + * @param complete 加载完成的回调函数 + * @param aniMode 与Skeleton.initaniMode作用一致 + */ + load(path:string,complete?:Handler,aniMode?:number):void; + private _checkIsAllParsed:any; + + /** + * *****************************************定义接口************************************************ + */ + + /** + * 得到当前动画的数量 + * @return 当前动画的数量 + */ + getAnimNum():number; + + /** + * 得到指定动画的名字 + * @param index 动画的索引 + */ + getAniNameByIndex(index:number):string; + + /** + * 通过名字得到插槽的引用 + * @param name 动画的名字 + * @return 插槽的引用 + */ + getSlotByName(name:string):BoneSlot; + + /** + * 通过名字显示一套皮肤 + * @param name 皮肤的名字 + * @param freshSlotIndex 是否将插槽纹理重置到初始化状态 + */ + showSkinByName(name:string,freshSlotIndex?:boolean):void; + + /** + * 通过索引显示一套皮肤 + * @param skinIndex 皮肤索引 + * @param freshSlotIndex 是否将插槽纹理重置到初始化状态 + */ + showSkinByIndex(skinIndex:number,freshSlotIndex?:boolean):void; + + /** + * 设置某插槽的皮肤 + * @param slotName 插槽名称 + * @param index 插糟皮肤的索引 + */ + showSlotSkinByIndex(slotName:string,index:number):void; + + /** + * 设置某插槽的皮肤 + * @param slotName 插槽名称 + * @param name 皮肤名称 + */ + showSlotSkinByName(slotName:string,name:string):void; + + /** + * 替换插槽贴图名 + * @param slotName 插槽名称 + * @param oldName 要替换的贴图名 + * @param newName 替换后的贴图名 + */ + replaceSlotSkinName(slotName:string,oldName:string,newName:string):void; + + /** + * 替换插槽的贴图索引 + * @param slotName 插槽名称 + * @param oldIndex 要替换的索引 + * @param newIndex 替换后的索引 + */ + replaceSlotSkinByIndex(slotName:string,oldIndex:number,newIndex:number):void; + + /** + * 设置自定义皮肤 + * @param name 插糟的名字 + * @param texture 自定义的纹理 + */ + setSlotSkin(slotName:string,texture:Texture):void; + + /** + * 播放动画 + * @param nameOrIndex 动画名字或者索引 + * @param loop 是否循环播放 + * @param force false,如果要播的动画跟上一个相同就不生效,true,强制生效 + * @param start 起始时间 + * @param end 结束时间 + * @param freshSkin 是否刷新皮肤数据 + * @param playAudio 是否播放音频 + */ + play(nameOrIndex:any,loop:boolean,force?:boolean,start?:number,end?:number,freshSkin?:boolean,playAudio?:boolean):void; + + /** + * 停止动画 + */ + stop():void; + + /** + * 设置动画播放速率 + * @param value 1为标准速率 + */ + playbackRate(value:number):void; + + /** + * 暂停动画的播放 + */ + paused():void; + + /** + * 恢复动画的播放 + */ + resume():void; + + /** + * 销毁当前动画 + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * @private 得到帧索引 + */ + get index():number; + + /** + * @private 设置帧索引 + */ + set index(value:number); + + /** + * 得到总帧数据 + */ + get total():number; + + /** + * 得到播放器的引用 + */ + get player():AnimationPlayer; + + /** + * 得到动画模板的引用 + * @return templet. + */ + get templet():Templet; + } + + /** + * 插槽显示数据 + */ + class SkinSlotDisplayData { + + /** + * 名称 + */ + name:string; + + /** + * 附件名称 + */ + attachmentName:string; + + /** + * 类型 + */ + type:number; + + /** + * 变换 + */ + transform:Transform; + + /** + * 宽度 + */ + width:number; + + /** + * 高度 + */ + height:number; + + /** + * 纹理 + */ + texture:Texture; + + /** + * 骨骼数据 + */ + bones:any[]; + + /** + * uv数据 + */ + uvs:any[]; + + /** + * 权重 + */ + weights:any[]; + + /** + * 三角面数据 + */ + triangles:any[]; + + /** + * 顶点数据 + */ + vertices:any[]; + + /** + * 长度数据 + */ + lengths:any[]; + + /** + * 版本号 + */ + verLen:number; + createTexture(currTexture:Texture):Texture; + destory():void; + } + class SlotData { + name:string; + displayArr:any[]; + + /** + * 通过附件名称获取位置 + * @param name + */ + getDisplayByName(name:string):number; + } + + /** + * 数据解析完成后的调度。 + * @eventType Event.COMPLETE + */ + + /** + * 数据解析错误后的调度。 + * @eventType Event.ERROR + */ + + /** + * 动画模板类 + */ + class Templet extends AnimationTemplet { + + /** + * 存放原始骨骼信息 + */ + srcBoneMatrixArr:any[]; + + /** + * IK数据 + */ + ikArr:any[]; + + /** + * transform数据 + */ + tfArr:any[]; + + /** + * path数据 + */ + pathArr:any[]; + + /** + * 存放插槽数据的字典 + */ + boneSlotDic:any; + + /** + * 绑定插槽数据的字典 + */ + bindBoneBoneSlotDic:any; + + /** + * 存放插糟数据的数组 + */ + boneSlotArray:any[]; + + /** + * 皮肤数据 + */ + skinDataArray:any[]; + + /** + * 皮肤的字典数据 + */ + skinDic:any; + + /** + * 存放纹理数据 + */ + subTextureDic:any; + + /** + * 是否解析失败 + */ + isParseFail:boolean; + + /** + * 反转矩阵,有些骨骼动画要反转才能显示 + */ + yReverseMatrix:Matrix; + + /** + * 渲染顺序动画数据 + */ + drawOrderAniArr:any[]; + + /** + * 事件动画数据 + */ + eventAniArr:any[]; + + /** + * @private 索引对应的名称 + */ + attachmentNames:any[]; + + /** + * 顶点动画数据 + */ + deformAniArr:any[]; + + /** + * 实际显示对象列表,用于销毁用 + */ + skinSlotDisplayDataArr:SkinSlotDisplayData[]; + isParserComplete:boolean; + aniSectionDic:any; + + /** + * @private + */ + tMatrixDataLen:number; + mRootBone:Bone; + mBoneArr:Bone[]; + loadAni(url:string):void; + private onComplete:any; + + /** + * 解析骨骼动画数据 + * @param texture 骨骼动画用到的纹理 + * @param skeletonData 骨骼动画信息及纹理分块信息 + * @param playbackRate 缓冲的帧率数据(会根据帧率去分帧) + */ + parseData(texture:Texture,skeletonData:ArrayBuffer,playbackRate?:number):void; + + /** + * 创建动画 + * 0,使用模板缓冲的数据,模板缓冲的数据,不允许修改 (内存开销小,计算开销小,不支持换装) + * 1,使用动画自己的缓冲区,每个动画都会有自己的缓冲区,相当耗费内存 (内存开销大,计算开销小,支持换装) + * 2,使用动态方式,去实时去画 (内存开销小,计算开销大,支持换装,不建议使用) + * @param aniMode 0 动画模式,0:不支持换装,1,2支持换装 + * @return + */ + buildArmature(aniMode?:number):Skeleton; + + /** + * @private 解析动画 + * @param data 解析的二进制数据 + * @param playbackRate 帧率 + * @override + */ + parse(data:ArrayBuffer):void; + + /** + * 得到指定的纹理 + * @param name 纹理的名字 + * @return + */ + getTexture(name:string):Texture; + + /** + * @private 显示指定的皮肤 + * @param boneSlotDic 插糟字典的引用 + * @param skinIndex 皮肤的索引 + * @param freshDisplayIndex 是否重置插槽纹理 + */ + showSkinByIndex(boneSlotDic:any,skinIndex:number,freshDisplayIndex?:boolean):boolean; + + /** + * 通过皮肤名字得到皮肤索引 + * @param skinName 皮肤名称 + * @return + */ + getSkinIndexByName(skinName:string):number; + + /** + * @private 得到缓冲数据 + * @param aniIndex 动画索引 + * @param frameIndex 帧索引 + * @return + */ + getGrahicsDataWithCache(aniIndex:number,frameIndex:number):Graphics; + + /** + * @private 保存缓冲grahpics + * @param aniIndex 动画索引 + * @param frameIndex 帧索引 + * @param graphics 要保存的数据 + */ + setGrahicsDataWithCache(aniIndex:number,frameIndex:number,graphics:Graphics):void; + deleteAniData(aniIndex:number):void; + + /** + * 释放纹理 + * @override + */ + destroy():void; + + /** + * *********************************下面为一些儿访问接口**************************************** + */ + + /** + * 通过索引得动画名称 + * @param index + * @return + */ + getAniNameByIndex(index:number):string; + get rate():number; + set rate(v:number); + } + class Transform { + + /** + * 水平方向旋转角度 + */ + skX:number; + + /** + * 垂直方向旋转角度 + */ + skY:number; + + /** + * 水平方向缩放 + */ + scX:number; + + /** + * 垂直方向缩放 + */ + scY:number; + + /** + * 水平方向偏移 + */ + x:number; + + /** + * 垂直方向偏移 + */ + y:number; + + /** + * 水平方向倾斜角度 + */ + skewX:number; + + /** + * 垂直方向倾斜角度 + */ + skewY:number; + private mMatrix:any; + + /** + * 初始化数据 + * @param data + */ + initData(data:any):void; + + /** + * 获取当前矩阵 + */ + getMatrix():Matrix; + + /** + * 获取倾斜矩阵 + * @param m + * @param x + * @param y + */ + skew(m:Matrix,x:number,y:number):Matrix; + } + + /** + * 动画 + */ + class GraphicsAni extends Graphics { + + /** + * @private 画自定义蒙皮动画 + * @param skin + */ + drawSkin(skinA:SkinMeshForGraphic,alpha:number):void; + private static _caches:any; + static create():GraphicsAni; + + /** + * 回收清理 + * @param graphics + */ + static recycle(graphics:GraphicsAni):void; + } + + /** + * 关键帧 + */ + class KeyFramesContent { + + /** + * 开始时间 + */ + startTime:number; + + /** + * 持续时间 + */ + duration:number; + + /** + * 私有插值方式 + */ + interpolationData:any[]; + + /** + * 数据 + */ + data:Float32Array; + + /** + * 数据变化量 + */ + dData:Float32Array; + + /** + * 下一次的数据 + */ + nextData:Float32Array; + } + + /** + * 动画播放完毕后调度。 + * @eventType Event.COMPLETE + */ + + /** + * 播放到某标签后调度。 + * @eventType Event.LABEL + */ + + /** + * 加载完成后调度。 + * @eventType Event.LOADED + */ + + /** + * 进入帧后调度。 + * @eventType Event.FRAME + */ + + /** + *

MovieClip 用于播放经过工具处理后的 swf 动画。

+ */ + class MovieClip extends Sprite { + + /** + * 资源根目录。 + */ + basePath:string; + + /** + * 播放间隔(单位:毫秒)。 + */ + interval:number; + + /** + * 是否循环播放 + */ + loop:boolean; + + /** + * 创建一个 MovieClip 实例。 + * @param parentMovieClip 父MovieClip,自己创建时不需要传该参数 + */ + + constructor(parentMovieClip?:MovieClip); + + /** + *

销毁此对象。以及销毁引用的Texture

+ * @param destroyChild 是否同时销毁子节点,若值为true,则销毁子节点,否则不销毁子节点。 + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * @private 更新时间轴 + */ + updates():void; + + /** + * 当前播放索引。 + */ + get index():number; + set index(value:number); + + /** + * 增加一个标签到index帧上,播放到此index后会派发label事件 + * @param label 标签名称 + * @param index 索引位置 + */ + addLabel(label:string,index:number):void; + + /** + * 删除某个标签 + * @param label 标签名字,如果label为空,则删除所有Label + */ + removeLabel(label:string):void; + + /** + * 帧总数。 + */ + get count():number; + + /** + * 是否在播放中 + */ + get playing():boolean; + + /** + * 停止播放动画。 + */ + stop():void; + + /** + * 跳到某帧并停止播放动画。 + * @param frame 要跳到的帧 + */ + gotoAndStop(index:number):void; + + /** + * 播放动画。 + * @param index 帧索引。 + */ + play(index?:number,loop?:boolean):void; + + /** + * 资源地址。 + */ + set url(path:string); + + /** + * 加载资源。 + * @param url swf 资源地址。 + * @param atlas 是否使用图集资源 + * @param atlasPath 图集路径,默认使用与swf同名的图集 + */ + load(url:string,atlas?:boolean,atlasPath?:string):void; + + /** + * 从开始索引播放到结束索引,结束之后出发complete回调 + * @param start 开始索引 + * @param end 结束索引 + * @param complete 结束回调 + */ + playTo(start:number,end:number,complete?:Handler):void; + } + + /** + * CommonScript 类用于创建公共脚本类。 + */ + class CommonScript extends Component { + + /** + * @inheritDoc + * @override + */ + get isSingleton():boolean; + + constructor(); + + /** + * 创建后只执行一次 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onAwake():void; + + /** + * 每次启动后执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onEnable():void; + + /** + * 第一次执行update之前执行,只会执行一次 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onStart():void; + + /** + * 每帧更新时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onUpdate():void; + + /** + * 每帧更新时执行,在update之后执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onLateUpdate():void; + + /** + * 禁用时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onDisable():void; + + /** + * 销毁时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onDestroy():void; + } + + /** + * Component 类用于创建组件的基类。 + */ + class Component implements ISingletonElement,IDestroy { + + /** + * [只读]获取所属Node节点。 + * @readonly + */ + owner:Node; + + /** + * 创建一个新的 Component 实例。 + */ + + constructor(); + + /** + * 唯一标识ID。 + */ + get id():number; + + /** + * 是否启用组件。 + */ + get enabled():boolean; + set enabled(value:boolean); + + /** + * 是否为单实例组件。 + */ + get isSingleton():boolean; + + /** + * 是否已经销毁 。 + */ + get destroyed():boolean; + + /** + * [实现IListPool接口] + */ + _getIndexInList():number; + + /** + * [实现IListPool接口] + */ + _setIndexInList(index:number):void; + + /** + * 重置组件参数到默认值,如果实现了这个函数,则组件会被重置并且自动回收到对象池,方便下次复用 + * 如果没有重置,则不进行回收复用 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onReset():void; + + /** + * 销毁组件 + */ + destroy():void; + } + + /** + * 模板,预制件 + */ + class Prefab { + + /** + * @private + */ + json:any; + + /** + * 通过预制创建实例 + */ + create():any; + } + + /** + * Script 类用于创建脚本的父类,该类为抽象类,不允许实例。 + * 组件的生命周期 + */ + class Script extends Component { + + /** + * @inheritDoc + * @override + */ + get isSingleton():boolean; + + /** + * 组件被激活后执行,此时所有节点和组件均已创建完毕,次方法只执行一次 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onAwake():void; + + /** + * 组件被启用后执行,比如节点被添加到舞台后 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onEnable():void; + + /** + * 第一次执行update之前执行,只会执行一次 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onStart():void; + + /** + * 开始碰撞时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onTriggerEnter(other:any,self:any,contact:any):void; + + /** + * 持续碰撞时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onTriggerStay(other:any,self:any,contact:any):void; + + /** + * 结束碰撞时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onTriggerExit(other:any,self:any,contact:any):void; + + /** + * 鼠标按下时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onMouseDown(e:Event):void; + + /** + * 鼠标抬起时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onMouseUp(e:Event):void; + + /** + * 鼠标点击时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onClick(e:Event):void; + + /** + * 鼠标在舞台按下时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onStageMouseDown(e:Event):void; + + /** + * 鼠标在舞台抬起时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onStageMouseUp(e:Event):void; + + /** + * 鼠标在舞台点击时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onStageClick(e:Event):void; + + /** + * 鼠标在舞台移动时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onStageMouseMove(e:Event):void; + + /** + * 鼠标双击时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onDoubleClick(e:Event):void; + + /** + * 鼠标右键点击时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onRightClick(e:Event):void; + + /** + * 鼠标移动时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onMouseMove(e:Event):void; + + /** + * 鼠标经过节点时触发 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onMouseOver(e:Event):void; + + /** + * 鼠标离开节点时触发 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onMouseOut(e:Event):void; + + /** + * 键盘按下时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onKeyDown(e:Event):void; + + /** + * 键盘产生一个字符时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onKeyPress(e:Event):void; + + /** + * 键盘抬起时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onKeyUp(e:Event):void; + + /** + * 每帧更新时执行,尽量不要在这里写大循环逻辑或者使用getComponent方法 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onUpdate():void; + + /** + * 每帧更新时执行,在update之后执行,尽量不要在这里写大循环逻辑或者使用getComponent方法 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onLateUpdate():void; + + /** + * 渲染之前执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onPreRender():void; + + /** + * 渲染之后执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onPostRender():void; + + /** + * 组件被禁用时执行,比如从节点从舞台移除后 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onDisable():void; + + /** + * 手动调用节点销毁时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onDestroy():void; + } + + /** + * @private 静态常量集合 + */ + class Const { + static NOT_ACTIVE:number; + static ACTIVE_INHIERARCHY:number; + static AWAKED:number; + static NOT_READY:number; + static DISPLAY:number; + static HAS_ZORDER:number; + static HAS_MOUSE:number; + static DISPLAYED_INSTAGE:number; + static DRAWCALL_OPTIMIZE:number; + } + + /** + * AnimationClip 类用于动画片段资源。 + */ + class AnimationClip extends Resource { + + /** + * AnimationClip资源。 + */ + static ANIMATIONCLIP:string; + + /** + * 加载动画片段。 + * @param url 动画片段地址。 + * @param complete 完成回掉。load + */ + static load(url:string,complete:Handler):void; + + /** + * 是否循环。 + */ + islooping:boolean; + + /** + * 动画持续时间 + * @returns 返回动画持续时间 + */ + duration():number; + + /** + * 创建一个 AnimationClip 实例。 + */ + + constructor(); + private _evaluateFrameNodeVector3DatasRealTime:any; + private _evaluateFrameNodeQuaternionDatasRealTime:any; + private _binarySearchEventIndex:any; + + /** + * 添加动画事件。 + * @param event 动画事件 + */ + addEvent(event:AnimationEvent):void; + + /** + * @inheritDoc + * @override + */ + protected _disposeResource():void; + } + + /** + * AnimationEvent 类用于实现动画事件。 + */ + class AnimationEvent { + + /** + * 事件触发时间。 + */ + time:number; + + /** + * 事件触发名称。 + */ + eventName:string; + + /** + * 事件触发参数。 + */ + params:any[]; + + /** + * 创建一个 AnimationEvent 实例。 + */ + + constructor(); + } + + /** + * BoneNode 类用于实现骨骼节点。 + */ + class AnimationNode implements IClone { + private _children:any; + + /** + * 节点名称。 + */ + name:string|null; + + /** + * 创建一个新的 AnimationNode 实例。 + */ + + constructor(); + + /** + * 添加子节点。 + * @param child 子节点。 + */ + addChild(child:AnimationNode):void; + + /** + * 移除子节点。 + * @param child 子节点。 + */ + removeChild(child:AnimationNode):void; + + /** + * 根据名字获取子节点。 + * @param name 名字。 + */ + getChildByName(name:string):AnimationNode|null; + + /** + * 根据索引获取子节点。 + * @param index 索引。 + */ + getChildByIndex(index:number):AnimationNode; + + /** + * 获取子节点的个数。 + */ + getChildCount():number; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * AnimationTransform3D 类用于实现3D变换。 + */ + class AnimationTransform3D extends EventDispatcher { + private static _tempVector3:any; + private static _angleToRandin:any; + private _localMatrix:any; + private _worldMatrix:any; + private _localPosition:any; + private _localRotation:any; + private _localScale:any; + private _localQuaternionUpdate:any; + private _locaEulerlUpdate:any; + private _localUpdate:any; + private _parent:any; + private _children:any; + + /** + * 创建一个 Transform3D 实例。 + * @param owner 所属精灵。 + */ + + constructor(owner:AnimationNode); + private _getlocalMatrix:any; + private _onWorldTransform:any; + + /** + * 获取世界矩阵。 + * @return 世界矩阵。 + */ + getWorldMatrix():Float32Array; + + /** + * 设置父3D变换。 + * @param value 父3D变换。 + */ + setParent(value:AnimationTransform3D):void; + } + + /** + * AnimatorStateScript 类用于动画状态脚本的父类,该类为抽象类,不允许实例。 + */ + class AnimatorStateScript { + + /** + * 创建一个新的 AnimatorStateScript 实例。 + */ + + constructor(); + + /** + * 动画状态开始时执行。 + */ + onStateEnter():void; + + /** + * 动画状态更新时执行。 + */ + onStateUpdate():void; + + /** + * 动画状态退出时执行。 + */ + onStateExit():void; + } + + /** + * /** + * CastShadowList 类用于实现产生阴影者队列。 + */ + class CastShadowList extends SingletonList { + + /** + * 创建一个新的 CastShadowList 实例。 + */ + + constructor(); + } + + /** + * Animator 类用于创建动画组件。 + */ + class Animator extends Component { + + /** + * 裁剪模式_始终播放动画。 + */ + static CULLINGMODE_ALWAYSANIMATE:number; + + /** + * 裁剪模式_不可见时完全不播放动画。 + */ + static CULLINGMODE_CULLCOMPLETELY:number; + + /** + * 裁剪模式 + */ + cullingMode:number; + + /** + * 动画的播放速度,1.0为正常播放速度。 + */ + get speed():number; + set speed(value:number); + get controllerLayerCount():number; + + /** + * 创建一个 Animation 实例。 + */ + + constructor(); + + /** + * 赋值Node数据 + * @param stateInfo 动画状态 + * @param additive 是否为addtive + * @param weight state权重 + * @param isFirstLayer 是否是第一层 + */ + private _setClipDatasToNode:any; + + /** + * 获取默认动画状态。 + * @param layerIndex 层索引。 + * @return 默认动画状态。 + */ + getDefaultState(layerIndex?:number):AnimatorState; + + /** + * 添加动画状态。 + * @param state 动画状态。 + * @param layerIndex 层索引。 + */ + addState(state:AnimatorState,layerIndex?:number):void; + + /** + * 移除动画状态。 + * @param state 动画状态。 + * @param layerIndex 层索引。 + */ + removeState(state:AnimatorState,layerIndex?:number):void; + + /** + * 添加控制器层。 + */ + addControllerLayer(controllderLayer:AnimatorControllerLayer):void; + + /** + * 获取控制器层。 + */ + getControllerLayer(layerInex?:number):AnimatorControllerLayer; + + /** + * 播放动画。 + * @param name 如果为null则播放默认动画,否则按名字播放动画片段。 + * @param layerIndex 层索引。 + * @param normalizedTime 归一化的播放起始时间。 + */ + play(name?:string|null,layerIndex?:number,normalizedTime?:number):void; + + /** + * 在当前动画状态和目标动画状态之间进行融合过渡播放。 + * @param name 目标动画状态。 + * @param transitionDuration 过渡时间,该值为当前动画状态的归一化时间,值在0.0~1.0之间。 + * @param layerIndex 层索引。 + * @param normalizedTime 归一化的播放起始时间。 + */ + crossFade(name:string,transitionDuration:number,layerIndex?:number,normalizedTime?:number):void; + + /** + * @deprecated 请使用animator.getControllerLayer(layerIndex).getCurrentPlayState()替换。use animator.getControllerLayer(layerIndex).getCurrentPlayState() instead 获取当前的播放状态。 + * @param layerIndex 层索引。 + * @return 动画播放状态。 + */ + getCurrentAnimatorPlayState(layerInex?:number):AnimatorPlayState; + + /** + * avatar。 + */ + get avatar():Avatar; + set avatar(value:Avatar); + + /** + * 关联精灵节点到Avatar节点,此Animator必须有Avatar文件。 + * @param nodeName 关联节点的名字。 + * @param sprite3D 精灵节点。 + * @return 是否关联成功。 + */ + linkSprite3DToAvatarNode(nodeName:string,sprite3D:Sprite3D):boolean; + + /** + * 解除精灵节点到Avatar节点的关联,此Animator必须有Avatar文件。 + * @param sprite3D 精灵节点。 + * @return 是否解除关联成功。 + */ + unLinkSprite3DToAvatarNode(sprite3D:Sprite3D):boolean; + } + + /** + * AnimatorControllerLayer 类用于创建动画控制器层。 + */ + class AnimatorControllerLayer implements IReferenceCounter,IClone { + + /** + * 混合模式_覆盖。 + */ + static BLENDINGMODE_OVERRIDE:number; + + /** + * 混合模式_叠加。 + */ + static BLENDINGMODE_ADDTIVE:number; + + /** + * 层的名称。 + */ + name:string; + + /** + * 混合模式。 + */ + blendingMode:number; + + /** + * 默认权重。 + */ + defaultWeight:number; + + /** + * 激活时是否自动播放。 + */ + playOnWake:boolean; + + /** + * 默认动画状态机。 + */ + get defaultState():AnimatorState; + set defaultState(value:AnimatorState); + + /** + * 骨骼遮罩 + */ + get avatarMask():AvatarMask; + set avatarMask(value:AvatarMask); + + /** + * 创建一个 AnimatorControllerLayer 实例。 + * @param 动画层名称 + */ + + constructor(name:string); + + /** + * @implements + */ + _getReferenceCount():number; + + /** + * @implements + */ + _addReference(count?:number):void; + + /** + * @implements + */ + _removeReference(count?:number):void; + + /** + * @implements + */ + _clearReference():void; + + /** + * 获取当前的播放状态。 + * @return 动画播放状态。 + */ + getCurrentPlayState():AnimatorPlayState; + + /** + * 获取动画状态。 + * @return 动画状态。 + */ + getAnimatorState(name:string):AnimatorState|null; + + /** + * 添加动画状态。 + * @param state 动画状态。 + * @param layerIndex 层索引。 + */ + addState(state:AnimatorState):void; + + /** + * 移除动画状态。 + * @param state 动画状态。 + * @param layerIndex 层索引。 + */ + removeState(state:AnimatorState):void; + + /** + * 销毁。 + */ + destroy():void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * AnimatorPlayState 类用于创建动画播放状态信息。 + */ + class AnimatorPlayState { + + /** + * 播放状态的归一化时间,整数为循环次数,小数为单次播放时间。 + */ + get normalizedTime():number; + + /** + * 当前动画的持续时间,以秒为单位。 + */ + get duration():number; + + /** + * 动画状态机。 + */ + get animatorState():AnimatorState; + + /** + * 创建一个 AnimatorPlayState 实例。 + */ + + constructor(); + } + + /** + * AnimatorState 类用于创建动作状态。 + */ + class AnimatorState implements IReferenceCounter,IClone { + + /** + * 名称。 + */ + name:string; + + /** + * 动画播放速度,1.0为正常播放速度。 + */ + speed:number; + + /** + * 动作播放起始时间。 + */ + clipStart:number; + + /** + * 动作播放结束时间。 + */ + clipEnd:number; + + /** + * 动作。 + */ + get clip():AnimationClip|null; + set clip(value:AnimationClip|null); + + /** + * 创建一个 AnimatorState 实例。 + */ + + constructor(); + + /** + * @implements + */ + _getReferenceCount():number; + + /** + * @implements + */ + _addReference(count?:number):void; + + /** + * @implements + */ + _removeReference(count?:number):void; + + /** + * @implements + */ + _clearReference():void; + + /** + * 添加脚本。 + * @param type 组件类型。 + * @return 脚本。 + */ + addScript(type:typeof AnimatorStateScript):AnimatorStateScript; + + /** + * 获取脚本。 + * @param type 组件类型。 + * @return 脚本。 + */ + getScript(type:typeof AnimatorStateScript):AnimatorStateScript|null; + + /** + * 获取脚本集合。 + * @param type 组件类型。 + * @return 脚本集合。 + */ + getScripts(type:typeof AnimatorStateScript):AnimatorStateScript[]|null; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * 用来描述动画层遮罩 + */ + class AvatarMask { + private _catchAnimator:any; + + /** + * 创建一个AvatarMask实例 + */ + + constructor(animator:Animator); + + /** + * 获得动态 + */ + get getCatchAnimator():Animator; + + /** + * 查找节点路径遮罩 + * @param path + * @returns + */ + getTransformActive(path:string):boolean; + + /** + * 设置 + * @param path + * @param value + */ + setTransformActive(path:string,value:boolean):void; + + /** + * 获得遮罩信息 + * @returns + */ + getAllTranfromPath():{[key:string]:boolean;}; + } + + /** + * PostProcess 类用于创建后期处理组件。 + */ + class PostProcess { + + /** + * 创建一个 PostProcess 实例。 + */ + + constructor(); + get enable():boolean; + set enable(value:boolean); + + /** + * 添加后期处理效果。 + */ + addEffect(effect:PostProcessEffect):void; + + /** + * 移除后期处理效果。 + */ + removeEffect(effect:PostProcessEffect):void; + } + + /** + * Script3D 类用于创建脚本的父类,该类为抽象类,不允许实例。 + */ + class Script3D extends Component { + + /** + * @inheritDoc + * @override + */ + get isSingleton():boolean; + + /** + * 创建后只执行一次 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onAwake():void; + + /** + * 每次启动后执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onEnable():void; + + /** + * 第一次执行update之前执行,只会执行一次 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onStart():void; + + /** + * 开始触发时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onTriggerEnter(other:PhysicsComponent):void; + + /** + * 持续触发时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onTriggerStay(other:PhysicsComponent):void; + + /** + * 结束触发时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onTriggerExit(other:PhysicsComponent):void; + + /** + * 开始碰撞时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onCollisionEnter(collision:Collision):void; + + /** + * 持续碰撞时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onCollisionStay(collision:Collision):void; + + /** + * 结束碰撞时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onCollisionExit(collision:Collision):void; + + /** + * 关节破坏时执行此方法 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onJointBreak():void; + + /** + * 鼠标按下时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onMouseDown():void; + + /** + * 鼠标拖拽时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onMouseDrag():void; + + /** + * 鼠标点击时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onMouseClick():void; + + /** + * 鼠标弹起时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onMouseUp():void; + + /** + * 鼠标进入时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onMouseEnter():void; + + /** + * 鼠标经过时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onMouseOver():void; + + /** + * 鼠标离开时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onMouseOut():void; + + /** + * 每帧更新时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onUpdate():void; + + /** + * 每帧更新时执行,在update之后执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onLateUpdate():void; + + /** + * 渲染之前执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onPreRender():void; + + /** + * 渲染之后执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onPostRender():void; + + /** + * 禁用时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onDisable():void; + + /** + * 销毁时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onDestroy():void; + } + + /** + * SimpleSingletonList 类用于实现单例队列。 + */ + class SimpleSingletonList extends SingletonList { + + /** + * 创建一个新的 SimpleSingletonList 实例。 + */ + + constructor(); + clearElement():void; + } + + /** + * SingletonList 类用于实现单例队列。 + */ + class SingletonList { + + /** + * 创建一个新的 SingletonList 实例。 + */ + + constructor(); + } + + /** + * Avatar 类用于创建Avatar。 + */ + class Avatar extends Resource implements IClone { + + /** + * Avatar资源。 + */ + static AVATAR:string; + + /** + * @inheritDoc + */ + static _parse(data:any,propertyParams?:any,constructParams?:any[]):Avatar; + + /** + * 加载Avatar文件。 + * @param url Avatar文件。 + * @param complete 完成回掉。 + */ + static load(url:string,complete:Handler):void; + + /** + * [NATIVE] + */ + private _nativeNodeCount:any; + + /** + * 创建一个 Avatar 实例。 + */ + + constructor(); + private _initCloneToAnimator:any; + private _parseNode:any; + + /** + * 克隆数据到Avatr。 + * @param destObject 克隆源。 + */ + _cloneDatasToAnimator(destAnimator:Animator):void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * BaseCamera 类用于创建摄像机的父类。 + */ + class BaseCamera extends Sprite3D { + + /** + * 渲染模式,延迟光照渲染,暂未开放。 + */ + static RENDERINGTYPE_DEFERREDLIGHTING:string; + + /** + * 渲染模式,前向渲染。 + */ + static RENDERINGTYPE_FORWARDRENDERING:string; + protected static _invertYScaleMatrix:Matrix4x4; + protected static _invertYProjectionMatrix:Matrix4x4; + protected static _invertYProjectionViewMatrix:Matrix4x4; + + /** + * 近裁剪面。 + */ + protected _nearPlane:number; + + /** + * 远裁剪面。 + */ + protected _farPlane:number; + + /** + * 视野。 + */ + private _fieldOfView:any; + + /** + * 正交投影的垂直尺寸。 + */ + private _orthographicVerticalSize:any; + private _skyRenderer:any; + private _forward:any; + private _up:any; + + /** + * 摄像机的清除颜色,默认颜色为CornflowerBlue。 + */ + clearColor:Vector4; + + /** + * 可视层位标记遮罩值,支持混合 例:cullingMask=Math.pow(2,0)|Math.pow(2,1)为第0层和第1层可见。 + */ + cullingMask:number; + + /** + * 渲染时是否用遮挡剔除。 + */ + useOcclusionCulling:boolean; + + /** + * 天空渲染器。 + */ + get skyRenderer():SkyRenderer; + + /** + * 视野。 + */ + get fieldOfView():number; + set fieldOfView(value:number); + + /** + * 近裁面。 + */ + get nearPlane():number; + set nearPlane(value:number); + + /** + * 远裁面。 + */ + get farPlane():number; + set farPlane(vaule:number); + + /** + * 是否正交投影矩阵。 + */ + get orthographic():boolean; + set orthographic(vaule:boolean); + + /** + * 正交投影垂直矩阵尺寸。 + */ + get orthographicVerticalSize():number; + set orthographicVerticalSize(vaule:number); + + /** + * 渲染顺序 + */ + get renderingOrder():number; + set renderingOrder(value:number); + + /** + * 创建一个 BaseCamera 实例。 + * @param fieldOfView 视野。 + * @param nearPlane 近裁面。 + * @param farPlane 远裁面。 + */ + + constructor(nearPlane?:number,farPlane?:number); + + /** + * 相机渲染。 + * @param shader 着色器。 + * @param replacementTag 着色器替换标记。 + */ + render(shader?:Shader3D,replacementTag?:string):void; + + /** + * 增加可视图层,layer值为0到31层。 + * @param layer 图层。 + */ + addLayer(layer:number):void; + + /** + * 移除可视图层,layer值为0到31层。 + * @param layer 图层。 + */ + removeLayer(layer:number):void; + + /** + * 增加所有图层。 + */ + addAllLayers():void; + + /** + * 移除所有图层。 + */ + removeAllLayers():void; + + /** + * 重算计算投影矩阵 + */ + resetProjectionMatrix():void; + + /** + * @inheritDoc + * @override + */ + protected _onActive():void; + + /** + * @inheritDoc + * @override + */ + protected _onInActive():void; + + /** + * 删除相机 + * @inheritDoc + * @override + * @param 是否删除节点 + */ + destroy(destroyChild?:boolean):void; + + /** + * @deprecated plaease use CameraClearFlags.SolidColor instead. + */ + static CLEARFLAG_SOLIDCOLOR:number; + + /** + * @deprecated plaease use CameraClearFlags.Sky instead. + */ + static CLEARFLAG_SKY:number; + + /** + * @deprecated plaease use CameraClearFlags.DepthOnly instead. + */ + static CLEARFLAG_DEPTHONLY:number; + + /** + * @deprecated plaease use CameraClearFlags.Nothing instead. + */ + static CLEARFLAG_NONE:number; + } + + /** + * Bounds 类用于创建包围体。 + */ + class Bounds implements IClone { + static TEMP_VECTOR3_MAX0:Vector3; + static TEMP_VECTOR3_MAX1:Vector3; + private _updateFlag:any; + + /** + */ + _boundBox:BoundBox; + + /** + * 设置包围盒的最小点。 + * @param value 包围盒的最小点。 + */ + setMin(value:Vector3):void; + + /** + * 获取包围盒的最小点。 + * @return 包围盒的最小点。 + */ + getMin():Vector3; + + /** + * 设置包围盒的最大点。 + * @param value 包围盒的最大点。 + */ + setMax(value:Vector3):void; + + /** + * 获取包围盒的最大点。 + * @return 包围盒的最大点。 + */ + getMax():Vector3; + + /** + * 设置包围盒的中心点。 + * @param value 包围盒的中心点。 + */ + setCenter(value:Vector3):void; + + /** + * 获取包围盒的中心点。 + * @return 包围盒的中心点。 + */ + getCenter():Vector3; + + /** + * 设置包围盒的范围。 + * @param value 包围盒的范围。 + */ + setExtent(value:Vector3):void; + + /** + * 获取包围盒的范围。 + * @return 包围盒的范围。 + */ + getExtent():Vector3; + + /** + * 创建一个 Bounds 实例。 + * @param min min 最小坐标 + * @param max max 最大坐标。 + */ + + constructor(min:Vector3,max:Vector3); + private _getUpdateFlag:any; + private _setUpdateFlag:any; + private _getCenter:any; + private _getExtent:any; + private _getMin:any; + private _getMax:any; + private _rotateExtents:any; + + /** + * @returns -1为不相交 不为0的时候返回值为相交体积 + */ + calculateBoundsintersection(bounds:Bounds):number; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + +enum CameraClearFlags { + /**固定颜色。*/ + SolidColor = 0, + /**天空。*/ + Sky = 1, + /**仅深度。*/ + DepthOnly = 2, + /**不清除。*/ + Nothing = 3 +} + +enum CameraEventFlags { + /**在渲染非透明物体之前。*/ + BeforeForwardOpaque = 0, + /**在渲染天空盒之前。*/ + BeforeSkyBox = 2, + /**在渲染透明物体之前。*/ + BeforeTransparent = 4, + /**在后期处理之前。*/ + BeforeImageEffect = 6, + /**所有渲染之后。*/ + AfterEveryThing = 8 +} + + /** + * Camera 类用于创建摄像机。 + */ + class Camera extends BaseCamera { + + /** + * 根据相机、scene信息获得scene中某一位置的渲染结果 + * @param camera 相机 + * @param scene 需要渲染的场景 + * @param shader 着色器 + * @param replacementTag 替换标记。 + */ + static drawRenderTextureByScene(camera:Camera,scene:Scene3D,renderTexture:RenderTexture,shader?:Shader3D,replacementTag?:string):RenderTexture; + + /** + * 深度贴图 + */ + private _depthTexture:any; + + /** + * 深度法线贴图 + */ + private _depthNormalsTexture:any; + private _cameraEventCommandBuffer:any; + + /** + * 是否允许渲染。 + */ + enableRender:boolean; + + /** + * 清除标记。 + */ + clearFlag:CameraClearFlags; + + /** + * 横纵比。 + */ + get aspectRatio():number; + set aspectRatio(value:number); + + /** + * 获取屏幕像素坐标的视口。 + */ + get viewport():Viewport; + set viewport(value:Viewport); + + /** + * 裁剪空间的视口。 + */ + get normalizedViewport():Viewport; + set normalizedViewport(value:Viewport); + + /** + * 获取视图矩阵。 + */ + get viewMatrix():Matrix4x4; + + /** + * 投影矩阵。 + */ + get projectionMatrix():Matrix4x4; + set projectionMatrix(value:Matrix4x4); + + /** + * 获取视图投影矩阵。 + */ + get projectionViewMatrix():Matrix4x4; + + /** + * 获取摄像机视锥。 + */ + get boundFrustum():BoundFrustum; + + /** + * 自定义渲染场景的渲染目标。 + */ + get renderTarget():RenderTexture; + set renderTarget(value:RenderTexture); + + /** + * 后期处理。 + */ + get postProcess():PostProcess; + set postProcess(value:PostProcess); + + /** + * 是否开启HDR。 + * 开启后对性能有一定影响。 + */ + get enableHDR():boolean; + set enableHDR(value:boolean); + + /** + * 是否使用正在渲染的RenderTexture为CommandBuffer服务,设置为true + * 一般和CommandBuffer一起使用 + */ + get enableBuiltInRenderTexture():boolean; + set enableBuiltInRenderTexture(value:boolean); + + /** + * 深度贴图模式 + */ + get depthTextureMode():number; + set depthTextureMode(value:number); + + /** + * 创建一个 Camera 实例。 + * @param aspectRatio 横纵比。 + * @param nearPlane 近裁面。 + * @param farPlane 远裁面。 + */ + + constructor(aspectRatio?:number,nearPlane?:number,farPlane?:number); + + /** + * 通过蒙版值获取蒙版是否显示。 + * @param layer 层。 + * @return 是否显示。 + */ + _isLayerVisible(layer:number):boolean; + clone():Camera; + + /** + * 调用渲染命令流 + * @param event + * @param renderTarget + * @param context + */ + _applyCommandBuffer(event:number,context:RenderContext3D):void; + set depthTexture(value:RenderTexture); + set depthNormalTexture(value:RenderTexture); + + /** + * @override + * @param shader 着色器 + * @param replacementTag 替换标记。 + */ + render(shader?:Shader3D,replacementTag?:string):void; + + /** + * 计算从屏幕空间生成的射线。 + * @param point 屏幕空间的位置位置。 + * @param out 输出射线。 + */ + viewportPointToRay(point:Vector2,out:Ray):void; + + /** + * 计算从裁切空间生成的射线。 + * @param point 裁切空间的位置。 + * @param out 输出射线。 + */ + normalizedViewportPointToRay(point:Vector2,out:Ray):void; + + /** + * 将一个点从世界空间转换到视口空间。 + * @param position 世界空间的坐标。 + * @param out x、y、z为视口空间坐标,w为相对于摄像机的z轴坐标。 + */ + worldToViewportPoint(position:Vector3,out:Vector4):void; + + /** + * 将一个点从世界空间转换到归一化视口空间。 + * @param position 世界空间的坐标。 + * @param out x、y、z为归一化视口空间坐标,w为相对于摄像机的z轴坐标。 + */ + worldToNormalizedViewportPoint(position:Vector3,out:Vector4):void; + + /** + * 转换2D屏幕坐标系统到3D正交投影下的坐标系统,注:只有正交模型下有效。 + * @param source 源坐标。 + * @param out 输出坐标。 + * @return 是否转换成功。 + */ + convertScreenCoordToOrthographicCoord(source:Vector3,out:Vector3):boolean; + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * 增加camera渲染节点渲染缓存 + * @param event 相机事件标志 + * @param commandBuffer 渲染命令流 + */ + addCommandBuffer(event:CameraEventFlags,commandBuffer:CommandBuffer):void; + + /** + * 移除camera渲染节点渲染缓存 + * @param event 相机事件标志 + * @param commandBuffer 渲染命令流 + */ + removeCommandBuffer(event:CameraEventFlags,commandBuffer:CommandBuffer):void; + + /** + * 移除camera相机节点的所有渲染缓存 + * @param event 相机事件标志 + */ + removeCommandBuffers(event:CameraEventFlags):void; + } + + /** + * FloatKeyFrame 类用于创建浮点关键帧实例。 + */ + class FloatKeyframe extends Keyframe { + + /** + * 内切线 + */ + inTangent:number; + + /** + * 外切线 + */ + outTangent:number; + + /** + * 帧数据 + */ + value:number; + + /** + * 创建一个 FloatKeyFrame 实例。 + */ + + constructor(); + + /** + * 克隆数据 + * @inheritDoc + * @override + */ + cloneTo(destObject:any):void; + } + + /** + * GeometryElement 类用于实现几何体元素,该类为抽象类。 + */ + class GeometryElement implements IDestroy { + + /** + * 获取是否销毁。 + * @return 是否销毁。 + */ + get destroyed():boolean; + + /** + * 创建一个 GeometryElement 实例。 + */ + + constructor(); + + /** + * 获取几何体类型。 + */ + _getType():number; + + /** + * 销毁。 + */ + destroy():void; + } + + /** + * Gradient 类用于创建颜色渐变。 + */ + class Gradient implements IClone { + private _mode:any; + private _maxColorRGBKeysCount:any; + private _maxColorAlphaKeysCount:any; + private _colorRGBKeysCount:any; + private _colorAlphaKeysCount:any; + + /** + * 获取梯度模式。 + * @return 梯度模式。 + */ + get mode():number; + + /** + * 设置梯度模式。 + * @param value 梯度模式。 + */ + set mode(value:number); + + /** + * 获取颜色RGB数量。 + * @return 颜色RGB数量。 + */ + get colorRGBKeysCount():number; + + /** + * 获取颜色Alpha数量。 + * @return 颜色Alpha数量。 + */ + get colorAlphaKeysCount():number; + + /** + * 获取最大颜色RGB帧数量。 + * @return 最大RGB帧数量。 + */ + get maxColorRGBKeysCount():number; + + /** + * 获取最大颜色Alpha帧数量。 + * @return 最大Alpha帧数量。 + */ + get maxColorAlphaKeysCount():number; + + /** + * 创建一个 Gradient 实例。 + * @param maxColorRGBKeyCount 最大RGB帧个数。 + * @param maxColorAlphaKeyCount 最大Alpha帧个数。 + */ + + constructor(maxColorRGBKeyCount:number,maxColorAlphaKeyCount:number); + + /** + * 增加颜色RGB帧。 + * @param key 生命周期,范围为0到1。 + * @param value RGB值。 + */ + addColorRGB(key:number,value:Color):void; + + /** + * 增加颜色Alpha帧。 + * @param key 生命周期,范围为0到1。 + * @param value Alpha值。 + */ + addColorAlpha(key:number,value:number):void; + + /** + * 更新颜色RGB帧。 + * @param index 索引。 + * @param key 生命周期,范围为0到1。 + * @param value RGB值。 + */ + updateColorRGB(index:number,key:number,value:Color):void; + + /** + * 更新颜色Alpha帧。 + * @param index 索引。 + * @param key 生命周期,范围为0到1。 + * @param value Alpha值。 + */ + updateColorAlpha(index:number,key:number,value:number):void; + + /** + * 通过插值获取RGB颜色。 + * @param lerpFactor 插值因子。 + * @param out 颜色结果。 + * @param 开始查找索引 。 + * @return 结果索引。 + */ + evaluateColorRGB(lerpFactor:number,out:Color,startSearchIndex?:number,reverseSearch?:boolean):number; + + /** + * 通过插值获取透明值。 + * @param lerpFactor 插值因子。 + * @param out 颜色结果。 + * @param 开始查找索引 。 + * @return 结果索引 。 + */ + evaluateColorAlpha(lerpFactor:number,outColor:Color,startSearchIndex?:number,reverseSearch?:boolean):number; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * ... + * @author ... + */ + class GradientMode { + + /** + * 找到与请求的评估时间相邻的两个键,并线性插值在他们之间,以获得一种混合的颜色。 + */ + static Blend:number; + + /** + * 返回一个固定的颜色,通过查找第一个键的时间值大于所请求的评估时间。 + */ + static Fixed:number; + } + + /** + * HeightMap 类用于实现高度图数据。 + */ + class HeightMap { + private static _tempRay:any; + + /** + * 从网格精灵生成高度图。 + * @param meshSprite 网格精灵。 + * @param width 高度图宽度。 + * @param height 高度图高度。 + * @param outCellSize 输出 单元尺寸。 + */ + static creatFromMesh(mesh:Mesh,width:number,height:number,outCellSize:Vector2):HeightMap; + + /** + * 从图片生成高度图。 + * @param image 图片。 + * @param maxHeight 最小高度。 + * @param maxHeight 最大高度。 + */ + static createFromImage(texture:Texture2D,minHeight:number,maxHeight:number):HeightMap; + private static _getPosition:any; + private _datas:any; + private _w:any; + private _h:any; + private _minHeight:any; + private _maxHeight:any; + + /** + * 获取宽度。 + * @return value 宽度。 + */ + get width():number; + + /** + * 获取高度。 + * @return value 高度。 + */ + get height():number; + + /** + * 最大高度。 + * @return value 最大高度。 + */ + get maxHeight():number; + + /** + * 最大高度。 + * @return value 最大高度。 + */ + get minHeight():number; + + /** + * 创建一个 HeightMap 实例。 + * @param width 宽度。 + * @param height 高度。 + * @param minHeight 最大高度。 + * @param maxHeight 最大高度。 + */ + + constructor(width:number,height:number,minHeight:number,maxHeight:number); + + /** + * 获取高度。 + * @param row 列数。 + * @param col 行数。 + * @return 高度。 + */ + getHeight(row:number,col:number):number; + } + + interface IClone{ + clone():any; + cloneTo(destObject:any):void; + } + + + /** + * KeyFrame 类用于创建关键帧实例。 + */ + class Keyframe implements IClone { + + /** + * 时间。 + */ + time:number; + + /** + * 创建一个 KeyFrame 实例。 + */ + + constructor(); + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * DirectionLight 类用于创建平行光。 + */ + class DirectionLight extends LightSprite { + + /** + * 阴影级联数量。 + */ + get shadowCascadesMode():ShadowCascadesMode; + set shadowCascadesMode(value:ShadowCascadesMode); + + /** + * 二级级联阴影分割比例。 + */ + get shadowTwoCascadeSplits():number; + set shadowTwoCascadeSplits(value:number); + + /** + * 四级级联阴影分割比例,X、Y、Z依次为其分割比例,Z必须大于Y,Y必须大于X。 + */ + get shadowFourCascadeSplits():Vector3; + set shadowFourCascadeSplits(value:Vector3); + + /** + * 创建一个 DirectionLight 实例。 + */ + + constructor(); + } + + /** + * LightSprite 类用于创建灯光的父类。 + */ + class LightSprite extends Sprite3D { + + /** + * 灯光烘培类型-实时。 + */ + static LIGHTMAPBAKEDTYPE_REALTIME:number; + + /** + * 灯光烘培类型-混合。 + */ + static LIGHTMAPBAKEDTYPE_MIXED:number; + + /** + * 灯光烘培类型-烘焙。 + */ + static LIGHTMAPBAKEDTYPE_BAKED:number; + + /** + * 灯光颜色。 + */ + color:Vector3; + + /** + * 灯光强度。 + */ + get intensity():number; + set intensity(value:number); + + /** + * 阴影模式。 + */ + get shadowMode():ShadowMode; + set shadowMode(value:ShadowMode); + + /** + * 最大阴影距离。 + */ + get shadowDistance():number; + set shadowDistance(value:number); + + /** + * 阴影贴图分辨率。 + */ + get shadowResolution():number; + set shadowResolution(value:number); + + /** + * 阴影深度偏差。 + */ + get shadowDepthBias():number; + set shadowDepthBias(value:number); + + /** + * 阴影法线偏差。 + */ + get shadowNormalBias():number; + set shadowNormalBias(value:number); + + /** + * 阴影强度。 + */ + get shadowStrength():number; + set shadowStrength(value:number); + + /** + * 阴影视锥的近裁面。 + */ + get shadowNearPlane():number; + set shadowNearPlane(value:number); + + /** + * 灯光烘培类型。 + */ + get lightmapBakedType():number; + set lightmapBakedType(value:number); + get lightWorldMatrix():Matrix4x4; + + /** + * 创建一个 LightSprite 实例。 + */ + + constructor(); + + /** + * @inheritDoc + * @override + */ + protected _onActive():void; + + /** + * @inheritDoc + * @override + */ + protected _onInActive():void; + + /** + * @deprecated please use color property instead. + */ + get diffuseColor():Vector3; + set diffuseColor(value:Vector3); + } + + /** + * PointLight 类用于创建点光。 + */ + class PointLight extends LightSprite { + + /** + * 点光的范围。 + * @return 点光的范围。 + */ + get range():number; + set range(value:number); + + /** + * 创建一个 PointLight 实例。 + */ + + constructor(); + } + +enum ShadowCascadesMode { + /** 无级联。 */ + NoCascades = 0, + /** 二级级联。 */ + TwoCascades = 1, + /** 四级级联。 */ + FourCascades = 2 +} + +enum ShadowMode { + /**不产生阴影。*/ + None = 0, + /**硬阴影,对性能要求较低。*/ + Hard = 1, + /**低强度软阴影,对性能要求一般。*/ + SoftLow = 2, + /**高强度软阴影,对性能要求较高。*/ + SoftHigh = 3 +} + + /** + * SpotLight 类用于创建聚光。 + */ + class SpotLight extends LightSprite { + + /** + * 聚光灯的锥形角度。 + */ + get spotAngle():number; + set spotAngle(value:number); + + /** + * 聚光的范围。 + */ + get range():number; + set range(value:number); + + /** + * 创建一个 SpotLight 实例。 + */ + + constructor(); + } + + /** + * BaseMaterial has deprecated,please use Material instead废弃的类,请使用Material类. + * @deprecated + */ + class BaseMaterial { + + /** + * @deprecated 废弃请使用Material类 use Material.MATERIAL instead + */ + static MATERIAL:string; + + /** + * @deprecated 废弃请使用Material类 use Material.RENDERQUEUE_OPAQUE instead + */ + static RENDERQUEUE_OPAQUE:number; + + /** + * @deprecated 废弃请使用Material类 use Material.RENDERQUEUE_ALPHATEST instead + */ + static RENDERQUEUE_ALPHATEST:number; + + /** + * @deprecated 废弃请使用Material类 use Material.RENDERQUEUE_TRANSPARENT instead + */ + static RENDERQUEUE_TRANSPARENT:number; + + /** + * @deprecated 废弃请使用Material类 use Material.ALPHATESTVALUE instead + */ + static ALPHATESTVALUE:number; + + /** + * @deprecated 废弃请使用Material类 use Material.SHADERDEFINE_ALPHATEST instead + */ + static SHADERDEFINE_ALPHATEST:ShaderDefine; + + /** + * @deprecated 废弃请使用Material类 BaseMaterial has deprecated,please use Material instead. + * @param 资源路径 + * @param 处理句柄 + */ + static load(url:string,complete:Handler):void; + } + + /** + * BlinnPhongMaterial 类用于实现Blinn-Phong材质。 + */ + class BlinnPhongMaterial extends Material { + + /** + * 高光强度数据源_漫反射贴图的Alpha通道。 + */ + static SPECULARSOURCE_DIFFUSEMAPALPHA:number; + + /** + * 高光强度数据源_高光贴图的RGB通道。 + */ + static SPECULARSOURCE_SPECULARMAP:number; + + /** + * 渲染状态_不透明。 + */ + static RENDERMODE_OPAQUE:number; + + /** + * 渲染状态_阿尔法测试。 + */ + static RENDERMODE_CUTOUT:number; + + /** + * 渲染状态_透明混合。 + */ + static RENDERMODE_TRANSPARENT:number; + + /** + * 默认材质,禁止修改 + */ + static defaultMaterial:BlinnPhongMaterial; + set _ColorR(value:number); + set _ColorG(value:number); + set _ColorB(value:number); + set _ColorA(value:number); + set _Color(value:Vector4); + set _SpecColorR(value:number); + set _SpecColorG(value:number); + set _SpecColorB(value:number); + set _SpecColorA(value:number); + set _SpecColor(value:Vector4); + set _Shininess(value:number); + set _MainTex_STX(x:number); + set _MainTex_STY(y:number); + set _MainTex_STZ(z:number); + set _MainTex_STW(w:number); + set _MainTex_ST(value:Vector4); + set _Cutoff(value:number); + + /** + * 设置渲染模式。 + * @param 渲染模式 + */ + set renderMode(value:number); + + /** + * 是否支持顶点色。 + */ + get enableVertexColor():boolean; + set enableVertexColor(value:boolean); + + /** + * 纹理平铺和偏移X分量。 + */ + get tilingOffsetX():number; + set tilingOffsetX(x:number); + + /** + * 纹理平铺和偏移Y分量。 + */ + get tilingOffsetY():number; + set tilingOffsetY(y:number); + + /** + * 纹理平铺和偏移Z分量。 + */ + get tilingOffsetZ():number; + set tilingOffsetZ(z:number); + + /** + * 纹理平铺和偏移W分量。 + */ + get tilingOffsetW():number; + set tilingOffsetW(w:number); + + /** + * 纹理平铺和偏移。 + */ + get tilingOffset():Vector4; + set tilingOffset(value:Vector4); + + /** + * 反照率颜色R分量。 + */ + get albedoColorR():number; + set albedoColorR(value:number); + + /** + * 反照率颜色G分量。 + */ + get albedoColorG():number; + set albedoColorG(value:number); + + /** + * 反照率颜色B分量。 + */ + get albedoColorB():number; + set albedoColorB(value:number); + + /** + * 反照率颜色Z分量。 + */ + get albedoColorA():number; + set albedoColorA(value:number); + + /** + * 反照率颜色。 + */ + get albedoColor():Vector4; + set albedoColor(value:Vector4); + + /** + * 反照率强度。 + */ + get albedoIntensity():number; + set albedoIntensity(value:number); + + /** + * 高光颜色R轴分量。 + */ + get specularColorR():number; + set specularColorR(value:number); + + /** + * 高光颜色G分量。 + */ + get specularColorG():number; + set specularColorG(value:number); + + /** + * 高光颜色B分量。 + */ + get specularColorB():number; + set specularColorB(value:number); + + /** + * 高光颜色A分量。 + */ + get specularColorA():number; + set specularColorA(value:number); + + /** + * 高光颜色。 + */ + get specularColor():Vector4; + set specularColor(value:Vector4); + + /** + * 高光强度,范围为0到1。 + */ + get shininess():number; + set shininess(value:number); + + /** + * 反照率贴图。 + */ + get albedoTexture():BaseTexture; + set albedoTexture(value:BaseTexture); + + /** + * 法线贴图。 + */ + get normalTexture():BaseTexture; + set normalTexture(value:BaseTexture); + + /** + * 高光贴图。 + */ + get specularTexture():BaseTexture; + set specularTexture(value:BaseTexture); + + /** + * 是否支持顶点色。 + */ + get enableTransmission():boolean; + set enableTransmission(value:boolean); + + /** + * 透光率,会影响漫反射以及透光强度 + */ + get transmissionRate():number; + set transmissionRata(value:number); + + /** + * 透射影响范围指数 + */ + get backDiffuse():number; + set backDiffuse(value:number); + + /** + * 透射光强度 + */ + get backScale():number; + set backScale(value:number); + + /** + * 厚度贴图,会影响透视光,越厚,透射光越弱 + */ + get thinknessTexture():BaseTexture; + set thinknessTexture(value:BaseTexture); + + /** + * 透光颜色。模拟透光物质内部颜色吸收率 + */ + get transmissionColor():Vector4; + set transmissionColor(value:Vector4); + + /** + * 创建一个 BlinnPhongMaterial 实例。 + */ + + constructor(); + + /** + * 克隆。 + * @return 克隆副本。 + * @override + */ + clone():any; + + /** + * @inheritDoc + * @override + */ + cloneTo(destObject:any):void; + } + + /** + * EffectMaterial 类用于实现Mesh特效材质。 + */ + class EffectMaterial extends Material { + + /** + * 渲染状态_加色法混合。 + */ + static RENDERMODE_ADDTIVE:number; + + /** + * 渲染状态_透明混合。 + */ + static RENDERMODE_ALPHABLENDED:number; + + /** + * 默认材质,禁止修改 + */ + static defaultMaterial:EffectMaterial; + set _TintColorR(value:number); + set _TintColorG(value:number); + set _TintColorB(value:number); + set _TintColorA(value:number); + set _TintColor(value:Vector4); + set _MainTex_STX(x:number); + set _MainTex_STY(y:number); + set _MainTex_STZ(z:number); + set _MainTex_STW(w:number); + set _MainTex_ST(value:Vector4); + + /** + * 设置渲染模式。 + */ + set renderMode(value:number); + + /** + * 颜色R分量。 + */ + get colorR():number; + set colorR(value:number); + + /** + * 颜色G分量。 + */ + get colorG():number; + set colorG(value:number); + + /** + * 颜色B分量。 + */ + get colorB():number; + set colorB(value:number); + + /** + * 颜色A分量。 + */ + get colorA():number; + set colorA(value:number); + + /** + * 获取颜色。 + */ + get color():Vector4; + set color(value:Vector4); + + /** + * 贴图。 + */ + get texture():BaseTexture; + set texture(value:BaseTexture); + + /** + * 纹理平铺和偏移X分量。 + */ + get tilingOffsetX():number; + set tilingOffsetX(x:number); + + /** + * 纹理平铺和偏移Y分量。 + */ + get tilingOffsetY():number; + set tilingOffsetY(y:number); + + /** + * 纹理平铺和偏移Z分量。 + */ + get tilingOffsetZ():number; + set tilingOffsetZ(z:number); + + /** + * 纹理平铺和偏移W分量。 + */ + get tilingOffsetW():number; + set tilingOffsetW(w:number); + + /** + * 纹理平铺和偏移。 + */ + get tilingOffset():Vector4; + set tilingOffset(value:Vector4); + + /** + * 创建一个 EffectMaterial 实例。 + */ + + constructor(); + + /** + * 克隆。 + * @return 克隆副本。 + * @override + */ + clone():any; + } + + /** + * ... + * @author ... + */ + class ExtendTerrainMaterial extends Material { + + /** + * 渲染状态_不透明。 + */ + static RENDERMODE_OPAQUE:number; + + /** + * 渲染状态_透明混合。 + */ + static RENDERMODE_TRANSPARENT:number; + + /** + * splatAlpha贴图。 + */ + get splatAlphaTexture():BaseTexture; + set splatAlphaTexture(value:BaseTexture); + + /** + * 第一层贴图。 + */ + get diffuseTexture1():BaseTexture; + set diffuseTexture1(value:BaseTexture); + + /** + * 第二层贴图。 + */ + get diffuseTexture2():BaseTexture; + set diffuseTexture2(value:BaseTexture); + + /** + * 第三层贴图。 + */ + get diffuseTexture3():BaseTexture; + set diffuseTexture3(value:BaseTexture); + + /** + * 第四层贴图。 + */ + get diffuseTexture4():BaseTexture; + set diffuseTexture4(value:BaseTexture); + + /** + * 第五层贴图。 + */ + get diffuseTexture5():BaseTexture; + set diffuseTexture5(value:BaseTexture); + + /** + * 第一层贴图缩放偏移。 + */ + set diffuseScaleOffset1(scaleOffset1:Vector4); + + /** + * 第二层贴图缩放偏移。 + */ + set diffuseScaleOffset2(scaleOffset2:Vector4); + + /** + * 第三层贴图缩放偏移。 + */ + set diffuseScaleOffset3(scaleOffset3:Vector4); + + /** + * 第四层贴图缩放偏移。 + */ + set diffuseScaleOffset4(scaleOffset4:Vector4); + + /** + * 第五层贴图缩放偏移。 + */ + set diffuseScaleOffset5(scaleOffset5:Vector4); + + /** + * 设置渲染模式。 + */ + set renderMode(value:number); + + /** + * 创建一个 ExtendTerrainMaterial 实例。 + */ + + constructor(); + + /** + * 克隆。 + * @return 克隆副本。 + * @override + */ + clone():any; + } + + /** + * Material 类用于创建材质。 + */ + class Material extends Resource implements IClone { + + /** + * Material资源。 + */ + static MATERIAL:string; + + /** + * 渲染队列_不透明。 + */ + static RENDERQUEUE_OPAQUE:number; + + /** + * 渲染队列_阿尔法裁剪。 + */ + static RENDERQUEUE_ALPHATEST:number; + + /** + * 渲染队列_透明。 + */ + static RENDERQUEUE_TRANSPARENT:number; + + /** + * 着色器变量,透明测试值。 + */ + static ALPHATESTVALUE:number; + + /** + * 材质级着色器宏定义,透明测试。 + */ + static SHADERDEFINE_ALPHATEST:ShaderDefine; + + /** + * 加载材质。 + * @param url 材质地址。 + * @param complete 完成回掉。 + */ + static load(url:string,complete:Handler):void; + + /** + * @inheritDoc + */ + static _parse(data:any,propertyParams?:any,constructParams?:any[]):Material; + + /** + * @private + */ + _shaderValues:ShaderData|null; + + /** + * 所属渲染队列. + */ + renderQueue:number; + + /** + * 着色器数据。 + */ + get shaderData():ShaderData; + + /** + * 透明测试模式裁剪值。 + */ + get alphaTestValue():number; + set alphaTestValue(value:number); + + /** + * 是否透明裁剪。 + */ + get alphaTest():boolean; + set alphaTest(value:boolean); + + /** + * 是否写入深度。 + */ + get depthWrite():boolean; + set depthWrite(value:boolean); + + /** + * 剔除方式。 + */ + get cull():number; + set cull(value:number); + + /** + * 混合方式。 + */ + get blend():number; + set blend(value:number); + + /** + * 混合源。 + */ + get blendSrc():number; + set blendSrc(value:number); + + /** + * 混合目标。 + */ + get blendDst():number; + set blendDst(value:number); + + /** + * 深度测试方式。 + */ + get depthTest():number; + set depthTest(value:number); + + /** + * 获得材质属性 + */ + get MaterialProperty():any; + + /** + * 获得材质宏 + */ + get MaterialDefine():Array; + + /** + * 创建一个 BaseMaterial 实例。 + */ + + constructor(); + + /** + * @inheritDoc + * @override + */ + protected _disposeResource():void; + + /** + * 设置使用Shader名字。 + * @param name 名称。 + */ + setShaderName(name:string):void; + + /** + * 设置属性值 + * @param name + * @param value + */ + setShaderPropertyValue(name:string,value:any):void; + + /** + * 获取属性值 + * @param name + */ + getShaderPropertyValue(name:string):any; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + get _defineDatas():DefineDatas; + } + +enum PBRRenderMode { + /**不透明。*/ + Opaque = 0, + /**透明裁剪。*/ + Cutout = 1, + /**透明混合_游戏中经常使用的透明。*/ + Fade = 2, + /**透明混合_物理上看似合理的透明。*/ + Transparent = 3 +} + + /** + * PBR材质的父类,该类为抽象类。 + */ + class PBRMaterial extends Material { + + /** + * 渲染质量。 + */ + static renderQuality:PBRRenderQuality; + + /** + * @private + */ + static __init__():void; + + /** + * 漫反射颜色。 + */ + get albedoColor():Vector4; + set albedoColor(value:Vector4); + + /** + * 漫反射贴图。 + */ + get albedoTexture():BaseTexture; + set albedoTexture(value:BaseTexture); + + /** + * 法线贴图。 + */ + get normalTexture():BaseTexture; + set normalTexture(value:BaseTexture); + + /** + * 法线贴图缩放系数。 + */ + get normalTextureScale():number; + set normalTextureScale(value:number); + + /** + * 视差贴图。 + */ + get parallaxTexture():BaseTexture; + set parallaxTexture(value:BaseTexture); + + /** + * 视差贴图缩放系数。 + */ + get parallaxTextureScale():number; + set parallaxTextureScale(value:number); + + /** + * 遮挡贴图。 + */ + get occlusionTexture():BaseTexture; + set occlusionTexture(value:BaseTexture); + + /** + * 遮挡贴图强度,范围为0到1。 + */ + get occlusionTextureStrength():number; + set occlusionTextureStrength(value:number); + + /** + * 光滑度,范围为0到1。 + */ + get smoothness():number; + set smoothness(value:number); + + /** + * 光滑度缩放系数,范围为0到1。 + */ + get smoothnessTextureScale():number; + set smoothnessTextureScale(value:number); + + /** + * 是否开启自发光。 + */ + get enableEmission():boolean; + set enableEmission(value:boolean); + + /** + * 自发光颜色。 + */ + get emissionColor():Vector4; + set emissionColor(value:Vector4); + + /** + * 自发光贴图。 + */ + get emissionTexture():BaseTexture; + set emissionTexture(value:BaseTexture); + + /** + * 纹理平铺和偏移。 + */ + get tilingOffset():Vector4; + set tilingOffset(value:Vector4); + + /** + * 渲染模式。 + */ + set renderMode(value:number); + + constructor(); + } + +enum PBRRenderQuality { + /**高质量。*/ + High = 0, + /**低质量。*/ + Low = 1 +} + +enum PBRSpecularSmoothnessSource { + /**金属度贴图的Alpha通道。*/ + SpecularTextureAlpha = 0, + /**反射率贴图的Alpha通道。*/ + AlbedoTextureAlpha = 1 +} + + /** + * PBRSpecularMaterial 类用于实现PBR(Specular)材质。 + */ + class PBRSpecularMaterial extends PBRMaterial { + + /** + * 默认材质,禁止修改 + */ + static defaultMaterial:PBRSpecularMaterial; + + /** + * 高光贴图。 + */ + get specularTexture():BaseTexture; + set specularTexture(value:BaseTexture); + + /** + * 高光颜色。 + */ + get specularColor():Vector4; + set specularColor(value:Vector4); + + /** + * 创建一个 PBRSpecularMaterial 实例。 + */ + + constructor(); + + /** + * 克隆。 + * @return 克隆副本。 + * @override + */ + clone():any; + } + +enum PBRMetallicSmoothnessSource { + /**金属度贴图的Alpha通道。*/ + MetallicGlossTextureAlpha = 0, + /**反射率贴图的Alpha通道。*/ + AlbedoTextureAlpha = 1 +} + + /** + * PBRStandardMaterial 类用于实现PBR材质。 + */ + class PBRStandardMaterial extends PBRMaterial { + + /** + * 默认材质,禁止修改 + */ + static defaultMaterial:PBRStandardMaterial; + + /** + * 金属光滑度贴图。 + */ + get metallicGlossTexture():BaseTexture; + set metallicGlossTexture(value:BaseTexture); + + /** + * 获取金属度,范围为0到1。 + */ + get metallic():number; + set metallic(value:number); + + /** + * 光滑度数据源,0或1。 + */ + get smoothnessSource():PBRMetallicSmoothnessSource; + set smoothnessSource(value:PBRMetallicSmoothnessSource); + + /** + * 创建一个 PBRStandardMaterial 实例。 + */ + + constructor(); + + /** + * 克隆。 + * @return 克隆副本。 + * @override + */ + clone():any; + } + + /** + * RenderState 类用于控制渲染状态。 + */ + class RenderState implements IClone { + + /** + * 剔除枚举_不剔除。 + */ + static CULL_NONE:number; + + /** + * 剔除枚举_剔除正面。 + */ + static CULL_FRONT:number; + + /** + * 剔除枚举_剔除背面。 + */ + static CULL_BACK:number; + + /** + * 混合枚举_禁用。 + */ + static BLEND_DISABLE:number; + + /** + * 混合枚举_启用_RGB和Alpha统一混合。 + */ + static BLEND_ENABLE_ALL:number; + + /** + * 混合枚举_启用_RGB和Alpha单独混合。 + */ + static BLEND_ENABLE_SEPERATE:number; + + /** + * 混合参数枚举_零,例:RGB(0,0,0),Alpha:(1)。 + */ + static BLENDPARAM_ZERO:number; + + /** + * 混合参数枚举_一,例:RGB(1,1,1),Alpha:(1)。 + */ + static BLENDPARAM_ONE:number; + + /** + * 混合参数枚举_源颜色,例:RGB(Rs, Gs, Bs),Alpha(As)。 + */ + static BLENDPARAM_SRC_COLOR:number; + + /** + * 混合参数枚举_一减源颜色,例:RGB(1-Rs, 1-Gs, 1-Bs),Alpha(1-As)。 + */ + static BLENDPARAM_ONE_MINUS_SRC_COLOR:number; + + /** + * 混合参数枚举_目标颜色,例:RGB(Rd, Gd, Bd),Alpha(Ad)。 + */ + static BLENDPARAM_DST_COLOR:number; + + /** + * 混合参数枚举_一减目标颜色,例:RGB(1-Rd, 1-Gd, 1-Bd),Alpha(1-Ad)。 + */ + static BLENDPARAM_ONE_MINUS_DST_COLOR:number; + + /** + * 混合参数枚举_源透明,例:RGB(As, As, As),Alpha(1-As)。 + */ + static BLENDPARAM_SRC_ALPHA:number; + + /** + * 混合参数枚举_一减源阿尔法,例:RGB(1-As, 1-As, 1-As),Alpha(1-As)。 + */ + static BLENDPARAM_ONE_MINUS_SRC_ALPHA:number; + + /** + * 混合参数枚举_目标阿尔法,例:RGB(Ad, Ad, Ad),Alpha(Ad)。 + */ + static BLENDPARAM_DST_ALPHA:number; + + /** + * 混合参数枚举_一减目标阿尔法,例:RGB(1-Ad, 1-Ad, 1-Ad),Alpha(Ad)。 + */ + static BLENDPARAM_ONE_MINUS_DST_ALPHA:number; + + /** + * 混合参数枚举_阿尔法饱和,例:RGB(min(As, 1 - Ad), min(As, 1 - Ad), min(As, 1 - Ad)),Alpha(1)。 + */ + static BLENDPARAM_SRC_ALPHA_SATURATE:number; + + /** + * 混合方程枚举_加法,例:source + destination + */ + static BLENDEQUATION_ADD:number; + + /** + * 混合方程枚举_减法,例:source - destination + */ + static BLENDEQUATION_SUBTRACT:number; + + /** + * 混合方程枚举_反序减法,例:destination - source + */ + static BLENDEQUATION_REVERSE_SUBTRACT:number; + + /** + * 深度测试函数枚举_关闭深度测试。 + */ + static DEPTHTEST_OFF:number; + + /** + * 深度测试函数枚举_从不通过。 + */ + static DEPTHTEST_NEVER:number; + + /** + * 深度测试函数枚举_小于时通过。 + */ + static DEPTHTEST_LESS:number; + + /** + * 深度测试函数枚举_等于时通过。 + */ + static DEPTHTEST_EQUAL:number; + + /** + * 深度测试函数枚举_小于等于时通过。 + */ + static DEPTHTEST_LEQUAL:number; + + /** + * 深度测试函数枚举_大于时通过。 + */ + static DEPTHTEST_GREATER:number; + + /** + * 深度测试函数枚举_不等于时通过。 + */ + static DEPTHTEST_NOTEQUAL:number; + + /** + * 深度测试函数枚举_大于等于时通过。 + */ + static DEPTHTEST_GEQUAL:number; + + /** + * 深度测试函数枚举_总是通过。 + */ + static DEPTHTEST_ALWAYS:number; + + /** + * 渲染剔除状态。 + */ + cull:number; + + /** + * 透明混合。 + */ + blend:number; + + /** + * 源混合参数,在blend为BLEND_ENABLE_ALL时生效。 + */ + srcBlend:number; + + /** + * 目标混合参数,在blend为BLEND_ENABLE_ALL时生效。 + */ + dstBlend:number; + + /** + * RGB源混合参数,在blend为BLEND_ENABLE_SEPERATE时生效。 + */ + srcBlendRGB:number; + + /** + * RGB目标混合参数,在blend为BLEND_ENABLE_SEPERATE时生效。 + */ + dstBlendRGB:number; + + /** + * Alpha源混合参数,在blend为BLEND_ENABLE_SEPERATE时生效。 + */ + srcBlendAlpha:number; + + /** + * Alpha目标混合参数,在blend为BLEND_ENABLE_SEPERATE时生效。 + */ + dstBlendAlpha:number; + + /** + * 混合常量颜色。 + */ + blendConstColor:Vector4; + + /** + * 混合方程。 + */ + blendEquation:number; + + /** + * RGB混合方程。 + */ + blendEquationRGB:number; + + /** + * Alpha混合方程。 + */ + blendEquationAlpha:number; + + /** + * 深度测试函数。 + */ + depthTest:number; + + /** + * 是否深度写入。 + */ + depthWrite:boolean; + + /** + * 创建一个 RenderState 实例。 + */ + + constructor(); + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(dest:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * SkyBoxMaterial 类用于实现SkyBoxMaterial材质。 + */ + class SkyBoxMaterial extends Material { + static TINTCOLOR:number; + static EXPOSURE:number; + static ROTATION:number; + static TEXTURECUBE:number; + + /** + * 默认材质,禁止修改 + */ + static defaultMaterial:SkyBoxMaterial; + + /** + * 颜色。 + */ + get tintColor():Vector4; + set tintColor(value:Vector4); + + /** + * 曝光强度。 + */ + get exposure():number; + set exposure(value:number); + + /** + * 旋转角度。 + */ + get rotation():number; + set rotation(value:number); + + /** + * 天空盒纹理。 + */ + get textureCube():TextureCube; + set textureCube(value:TextureCube); + + /** + * 克隆。 + * @return 克隆副本。 + * @override + */ + clone():any; + + /** + * 创建一个 SkyBoxMaterial 实例。 + */ + + constructor(); + } + + /** + * SkyPanoramicMaterial 类用于实现SkyPanoramicMaterial材质。 + */ + class SkyPanoramicMaterial extends Material { + static TINTCOLOR:number; + static EXPOSURE:number; + static ROTATION:number; + static TEXTURE:number; + static TEXTURE_HDR_PARAMS:number; + + /** + * 颜色。 + */ + get tintColor():Vector4; + set tintColor(value:Vector4); + + /** + * 曝光强度。 + */ + get exposure():number; + set exposure(value:number); + + /** + * 旋转角度。 + */ + get rotation():number; + set rotation(value:number); + + /** + * 全景天空纹理。 + */ + get panoramicTexture():Texture2D; + set panoramicTexture(value:Texture2D); + + /** + * 全景天空纹理解码格式。 + */ + get panoramicTextureDecodeFormat():TextureDecodeFormat; + set panoramicTextureDecodeFormat(value:TextureDecodeFormat); + + /** + * 创建一个 SkyPanoramicMaterial 实例。 + */ + + constructor(); + } + + /** + * SkyProceduralMaterial 类用于实现SkyProceduralMaterial材质。 + */ + class SkyProceduralMaterial extends Material { + + /** + * 太阳_无 + */ + static SUN_NODE:number; + + /** + * 太阳_精简 + */ + static SUN_SIMPLE:number; + + /** + * 太阳_高质量 + */ + static SUN_HIGH_QUALITY:number; + + /** + * 默认材质,禁止修改 + */ + static defaultMaterial:SkyProceduralMaterial; + + /** + * 太阳状态。 + */ + get sunDisk():number; + set sunDisk(value:number); + + /** + * 太阳尺寸,范围是0到1。 + */ + get sunSize():number; + set sunSize(value:number); + + /** + * 太阳尺寸收缩,范围是0到20。 + */ + get sunSizeConvergence():number; + set sunSizeConvergence(value:number); + + /** + * 大气厚度,范围是0到5。 + */ + get atmosphereThickness():number; + set atmosphereThickness(value:number); + + /** + * 天空颜色。 + */ + get skyTint():Vector4; + set skyTint(value:Vector4); + + /** + * 地面颜色。 + */ + get groundTint():Vector4; + set groundTint(value:Vector4); + + /** + * 曝光强度,范围是0到8。 + */ + get exposure():number; + set exposure(value:number); + + /** + * 创建一个 SkyProceduralMaterial 实例。 + */ + + constructor(); + + /** + * 克隆。 + * @return 克隆副本。 + * @override + */ + clone():any; + } + + /** + * UnlitMaterial 类用于实现不受光照影响的材质。 + */ + class UnlitMaterial extends Material { + + /** + * 渲染状态_不透明。 + */ + static RENDERMODE_OPAQUE:number; + + /** + * 渲染状态_阿尔法测试。 + */ + static RENDERMODE_CUTOUT:number; + + /** + * 渲染状态__透明混合。 + */ + static RENDERMODE_TRANSPARENT:number; + + /** + * 渲染状态__加色法混合。 + */ + static RENDERMODE_ADDTIVE:number; + static SHADERDEFINE_ALBEDOTEXTURE:ShaderDefine; + static SHADERDEFINE_ENABLEVERTEXCOLOR:ShaderDefine; + static ALBEDOTEXTURE:number; + static ALBEDOCOLOR:number; + static TILINGOFFSET:number; + + /** + * 默认材质,禁止修改 + */ + static defaultMaterial:UnlitMaterial; + private _albedoIntensity:any; + set _ColorR(value:number); + set _ColorG(value:number); + set _ColorB(value:number); + set _ColorA(value:number); + set _Color(value:Vector4); + set _AlbedoIntensity(value:number); + set _MainTex_STX(x:number); + set _MainTex_STY(y:number); + set _MainTex_STZ(z:number); + set _MainTex_STW(w:number); + set _MainTex_ST(value:Vector4); + set _Cutoff(value:number); + + /** + * 反照率颜色R分量。 + */ + get albedoColorR():number; + set albedoColorR(value:number); + + /** + * 反照率颜色G分量。 + */ + get albedoColorG():number; + set albedoColorG(value:number); + + /** + * 反照率颜色B分量。 + */ + get albedoColorB():number; + set albedoColorB(value:number); + + /** + * 反照率颜色Z分量。 + */ + get albedoColorA():number; + set albedoColorA(value:number); + + /** + * 反照率颜色。 + */ + get albedoColor():Vector4; + set albedoColor(value:Vector4); + + /** + * 反照率强度。 + */ + get albedoIntensity():number; + set albedoIntensity(value:number); + + /** + * 反照率贴图。 + */ + get albedoTexture():BaseTexture; + set albedoTexture(value:BaseTexture); + + /** + * 纹理平铺和偏移X分量。 + */ + get tilingOffsetX():number; + set tilingOffsetX(x:number); + + /** + * 纹理平铺和偏移Y分量。 + */ + get tilingOffsetY():number; + set tilingOffsetY(y:number); + + /** + * 纹理平铺和偏移Z分量。 + */ + get tilingOffsetZ():number; + set tilingOffsetZ(z:number); + + /** + * 纹理平铺和偏移W分量。 + */ + get tilingOffsetW():number; + set tilingOffsetW(w:number); + + /** + * 纹理平铺和偏移。 + */ + get tilingOffset():Vector4; + set tilingOffset(value:Vector4); + + /** + * 是否支持顶点色。 + */ + get enableVertexColor():boolean; + set enableVertexColor(value:boolean); + + /** + * 渲染模式。 + */ + set renderMode(value:number); + + constructor(); + + /** + * 克隆。 + * @return 克隆副本。 + * @override + */ + clone():any; + } + + /** + * WaterPrimaryMaterial 类用于实现水材质。 + */ + class WaterPrimaryMaterial extends Material { + static HORIZONCOLOR:number; + static MAINTEXTURE:number; + static NORMALTEXTURE:number; + static WAVESCALE:number; + static WAVESPEED:number; + static SHADERDEFINE_MAINTEXTURE:ShaderDefine; + static SHADERDEFINE_NORMALTEXTURE:ShaderDefine; + + /** + * 默认材质,禁止修改 + */ + static defaultMaterial:WaterPrimaryMaterial; + + /** + * 地平线颜色。 + */ + get horizonColor():Vector4; + set horizonColor(value:Vector4); + + /** + * 主贴图。 + */ + get mainTexture():BaseTexture; + set mainTexture(value:BaseTexture); + + /** + * 法线贴图。 + */ + get normalTexture():BaseTexture; + set normalTexture(value:BaseTexture); + + /** + * 波动缩放系数。 + */ + get waveScale():number; + set waveScale(value:number); + + /** + * 波动速率。 + */ + get waveSpeed():Vector4; + set waveSpeed(value:Vector4); + + constructor(); + + /** + * 克隆。 + * @return 克隆副本。 + * @override + */ + clone():any; + } + + /** + * MeshFilter 类用于创建网格过滤器。 + */ + class MeshFilter { + + /** + * 共享网格。 + */ + get sharedMesh():Mesh; + set sharedMesh(value:Mesh); + + /** + * 创建一个新的 MeshFilter 实例。 + * @param owner 所属网格精灵。 + */ + + constructor(owner:RenderableSprite3D); + + /** + * @inheritDoc + */ + destroy():void; + } + + /** + * MeshRenderer 类用于网格渲染器。 + */ + class MeshRenderer extends BaseRender { + + /** + * 创建一个新的 MeshRender 实例。 + */ + + constructor(owner:RenderableSprite3D); + } + + /** + * MeshSprite3D 类用于创建网格。 + */ + class MeshSprite3D extends RenderableSprite3D { + private _meshFilter:any; + + /** + * 网格过滤器。 + */ + get meshFilter():MeshFilter; + + /** + * 网格渲染器。 + */ + get meshRenderer():MeshRenderer; + + /** + * 创建一个 MeshSprite3D 实例。 + * @param mesh 网格,同时会加载网格所用默认材质。 + * @param name 名字。 + */ + + constructor(mesh?:Mesh,name?:string); + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + } + + /** + * 类用来记录精灵数据宏 + */ + class MeshSprite3DShaderDeclaration { + + /** + * UV0通道顶点数据宏 + */ + static SHADERDEFINE_UV0:ShaderDefine; + + /** + * 顶点色顶点数据宏 + */ + static SHADERDEFINE_COLOR:ShaderDefine; + + /** + * UV1通道顶点数据宏 + */ + static SHADERDEFINE_UV1:ShaderDefine; + + /** + * instance调用宏 + */ + static SHADERDEFINE_GPU_INSTANCE:ShaderDefine; + + /** + * 盒子反射宏 + */ + static SHADERDEFINE_SPECCUBE_BOX_PROJECTION:ShaderDefine; + } + + /** + * TerrainMeshSprite3D 类用于地形节点转换普通mesh渲染。 + */ + class MeshTerrainSprite3D extends MeshSprite3D { + private static _tempVector3:any; + private static _tempMatrix4x4:any; + + /** + * 从网格创建一个TerrainMeshSprite3D实例和其高度图属性。 + * @param mesh 网格。 + * @param heightMapWidth 高度图宽度。 + * @param heightMapHeight 高度图高度。 + * @param name 名字。 + */ + static createFromMesh(mesh:Mesh,heightMapWidth:number,heightMapHeight:number,name?:string):MeshTerrainSprite3D; + + /** + * 从网格创建一个TerrainMeshSprite3D实例、图片读取高度图属性。 + * @param mesh 网格。 + * @param image 高度图。 + * @param name 名字。 + * @returns 地形渲染节点 + */ + static createFromMeshAndHeightMap(mesh:Mesh,texture:Texture2D,minHeight:number,maxHeight:number,name?:string):MeshTerrainSprite3D; + private _minX:any; + private _minZ:any; + private _cellSize:any; + private _heightMap:any; + + /** + * 获取地形X轴最小位置。 + * @return 地形X轴最小位置。 + */ + get minX():number; + + /** + * 获取地形Z轴最小位置。 + * @return 地形X轴最小位置。 + */ + get minZ():number; + + /** + * 获取地形X轴长度。 + * @return 地形X轴长度。 + */ + get width():number; + + /** + * 获取地形Z轴长度。 + * @return 地形Z轴长度。 + */ + get depth():number; + + /** + * 创建一个 TerrainMeshSprite3D 实例。 + * @param mesh 网格。 + * @param heightMap 高度图。 + * @param name 名字。 + */ + + constructor(mesh:Mesh,heightMap:HeightMap,name?:string); + private _disableRotation:any; + private _getScaleX:any; + private _getScaleZ:any; + private _initCreateFromMesh:any; + private _initCreateFromMeshHeightMap:any; + private _computeCellSize:any; + + /** + * 获取地形高度。 + * @param x X轴坐标。 + * @param z Z轴坐标。 + */ + getHeight(x:number,z:number):number; + } + + /** + * Burst 类用于粒子的爆裂描述。 + */ + class Burst implements IClone { + + /** + * 爆裂时间,单位为秒。 + */ + private _time:any; + + /** + * 爆裂的最小数量。 + */ + private _minCount:any; + + /** + * 爆裂的最大数量。 + */ + private _maxCount:any; + + /** + * 获取爆裂时间,单位为秒。 + * @return 爆裂时间,单位为秒。 + */ + get time():number; + + /** + * 获取爆裂的最小数量。 + * @return 爆裂的最小数量。 + */ + get minCount():number; + + /** + * 获取爆裂的最大数量。 + * @return 爆裂的最大数量。 + */ + get maxCount():number; + + /** + * 创建一个 Burst 实例。 + * @param time 爆裂时间,单位为秒。 + * @param minCount 爆裂的最小数量。 + * @param time 爆裂的最大数量。 + */ + + constructor(time:number,minCount:number,maxCount:number); + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * ColorOverLifetime 类用于粒子的生命周期颜色。 + */ + class ColorOverLifetime { + private _color:any; + + /** + * 是否启用。 + */ + enable:boolean; + + /** + * 获取颜色。 + */ + get color():GradientColor; + + /** + * 创建一个 ColorOverLifetime 实例。 + */ + + constructor(color:GradientColor); + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * Emission 类用于粒子发射器。 + */ + class Emission implements IClone,IDestroy { + + /** + * 是否启用。 + */ + enable:boolean; + + /** + * 设置粒子发射速率。 + * @param emissionRate 粒子发射速率 (个/秒)。 + */ + set emissionRate(value:number); + + /** + * 获取粒子发射速率。 + * @return 粒子发射速率 (个/秒)。 + */ + get emissionRate():number; + + /** + * 获取是否已销毁。 + * @return 是否已销毁。 + */ + get destroyed():boolean; + + /** + * 创建一个 Emission 实例。 + */ + + constructor(); + + /** + * @private + */ + destroy():void; + + /** + * 获取粒子爆裂个数。 + * @return 粒子爆裂个数。 + */ + getBurstsCount():number; + + /** + * 通过索引获取粒子爆裂。 + * @param index 爆裂索引。 + * @return 粒子爆裂。 + */ + getBurstByIndex(index:number):Burst; + + /** + * 增加粒子爆裂。 + * @param burst 爆裂。 + */ + addBurst(burst:Burst):void; + + /** + * 移除粒子爆裂。 + * @param burst 爆裂。 + */ + removeBurst(burst:Burst):void; + + /** + * 通过索引移除粒子爆裂。 + * @param index 爆裂索引。 + */ + removeBurstByIndex(index:number):void; + + /** + * 清空粒子爆裂。 + */ + clearBurst():void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * FrameOverTime 类用于创建时间帧。 + */ + class FrameOverTime implements IClone { + + /** + * 通过固定帧创建一个 FrameOverTime 实例。 + * @param constant 固定帧。 + * @return 时间帧。 + */ + static createByConstant(constant?:number):FrameOverTime; + + /** + * 通过时间帧创建一个 FrameOverTime 实例。 + * @param overTime 时间帧。 + * @return 时间帧。 + */ + static createByOverTime(overTime:GradientDataInt):FrameOverTime; + + /** + * 通过随机双固定帧创建一个 FrameOverTime 实例。 + * @param constantMin 最小固定帧。 + * @param constantMax 最大固定帧。 + * @return 时间帧。 + */ + static createByRandomTwoConstant(constantMin?:number,constantMax?:number):FrameOverTime; + + /** + * 通过随机双时间帧创建一个 FrameOverTime 实例。 + * @param gradientFrameMin 最小时间帧。 + * @param gradientFrameMax 最大时间帧。 + * @return 时间帧。 + */ + static createByRandomTwoOverTime(gradientFrameMin:GradientDataInt,gradientFrameMax:GradientDataInt):FrameOverTime; + private _type:any; + private _constant:any; + private _overTime:any; + private _constantMin:any; + private _constantMax:any; + private _overTimeMin:any; + private _overTimeMax:any; + + /** + * 生命周期旋转类型,0常量模式,1曲线模式,2随机双常量模式,3随机双曲线模式。 + */ + get type():number; + + /** + * 固定帧。 + */ + get constant():number; + + /** + * 时间帧。 + */ + get frameOverTimeData():GradientDataInt; + + /** + * 最小固定帧。 + */ + get constantMin():number; + + /** + * 最大固定帧。 + */ + get constantMax():number; + + /** + * 最小时间帧。 + */ + get frameOverTimeDataMin():GradientDataInt; + + /** + * 最大时间帧。 + */ + get frameOverTimeDataMax():GradientDataInt; + + /** + * 创建一个 FrameOverTime,不允许new,请使用静态创建函数。 实例。 + */ + + constructor(); + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * GradientRotation 类用于创建渐变角速度。 + */ + class GradientAngularVelocity implements IClone { + + /** + * 通过固定角速度创建一个 GradientAngularVelocity 实例。 + * @param constant 固定角速度。 + * @return 渐变角速度。 + */ + static createByConstant(constant:number):GradientAngularVelocity; + + /** + * 通过分轴固定角速度创建一个 GradientAngularVelocity 实例。 + * @param separateConstant 分轴固定角速度。 + * @return 渐变角速度。 + */ + static createByConstantSeparate(separateConstant:Vector3):GradientAngularVelocity; + + /** + * 通过渐变角速度创建一个 GradientAngularVelocity 实例。 + * @param gradient 渐变角速度。 + * @return 渐变角速度。 + */ + static createByGradient(gradient:GradientDataNumber):GradientAngularVelocity; + + /** + * 通过分轴渐变角速度创建一个 GradientAngularVelocity 实例。 + * @param gradientX X轴渐变角速度。 + * @param gradientY Y轴渐变角速度。 + * @param gradientZ Z轴渐变角速度。 + * @return 渐变角速度。 + */ + static createByGradientSeparate(gradientX:GradientDataNumber,gradientY:GradientDataNumber,gradientZ:GradientDataNumber):GradientAngularVelocity; + + /** + * 通过随机双固定角速度创建一个 GradientAngularVelocity 实例。 + * @param constantMin 最小固定角速度。 + * @param constantMax 最大固定角速度。 + * @return 渐变角速度。 + */ + static createByRandomTwoConstant(constantMin:number,constantMax:number):GradientAngularVelocity; + + /** + * 通过随机分轴双固定角速度创建一个 GradientAngularVelocity 实例。 + * @param separateConstantMin 最小分轴固定角速度。 + * @param separateConstantMax 最大分轴固定角速度。 + * @return 渐变角速度。 + */ + static createByRandomTwoConstantSeparate(separateConstantMin:Vector3,separateConstantMax:Vector3):GradientAngularVelocity; + + /** + * 通过随机双渐变角速度创建一个 GradientAngularVelocity 实例。 + * @param gradientMin 最小渐变角速度。 + * @param gradientMax 最大渐变角速度。 + * @return 渐变角速度。 + */ + static createByRandomTwoGradient(gradientMin:GradientDataNumber,gradientMax:GradientDataNumber):GradientAngularVelocity; + + /** + * 通过分轴随机双渐变角速度创建一个 GradientAngularVelocity 实例。 + * @param gradientXMin 最小X轴渐变角速度。 + * @param gradientXMax 最大X轴渐变角速度。 + * @param gradientYMin 最小Y轴渐变角速度。 + * @param gradientYMax 最大Y轴渐变角速度。 + * @param gradientZMin 最小Z轴渐变角速度。 + * @param gradientZMax 最大Z轴渐变角速度。 + * @return 渐变角速度。 + */ + static createByRandomTwoGradientSeparate(gradientXMin:GradientDataNumber,gradientXMax:GradientDataNumber,gradientYMin:GradientDataNumber,gradientYMax:GradientDataNumber,gradientZMin:GradientDataNumber,gradientZMax:GradientDataNumber,gradientWMin:GradientDataNumber,gradientWMax:GradientDataNumber):GradientAngularVelocity; + private _type:any; + private _separateAxes:any; + private _constant:any; + private _constantSeparate:any; + private _gradient:any; + private _gradientX:any; + private _gradientY:any; + private _gradientZ:any; + private _gradientW:any; + private _constantMin:any; + private _constantMax:any; + private _constantMinSeparate:any; + private _constantMaxSeparate:any; + private _gradientMin:any; + private _gradientMax:any; + private _gradientXMin:any; + private _gradientXMax:any; + private _gradientYMin:any; + private _gradientYMax:any; + private _gradientZMin:any; + private _gradientZMax:any; + private _gradientWMin:any; + private _gradientWMax:any; + + /** + * 生命周期角速度类型,0常量模式,1曲线模式,2随机双常量模式,3随机双曲线模式。 + */ + get type():number; + + /** + * 是否分轴。 + */ + get separateAxes():boolean; + + /** + * 固定角速度。 + */ + get constant():number; + + /** + * 分轴固定角速度。 + */ + get constantSeparate():Vector3; + + /** + * 渐变角速度。 + */ + get gradient():GradientDataNumber; + + /** + * 渐变角角速度X。 + */ + get gradientX():GradientDataNumber; + + /** + * 渐变角速度Y。 + */ + get gradientY():GradientDataNumber; + + /** + * 渐变角速度Z。 + */ + get gradientZ():GradientDataNumber; + + /** + * 渐变角速度Z。 + */ + get gradientW():GradientDataNumber; + + /** + * 最小随机双固定角速度。 + */ + get constantMin():number; + + /** + * 最大随机双固定角速度。 + */ + get constantMax():number; + + /** + * 最小分轴随机双固定角速度。 + */ + get constantMinSeparate():Vector3; + + /** + * 最大分轴随机双固定角速度。 + */ + get constantMaxSeparate():Vector3; + + /** + * 最小渐变角速度。 + */ + get gradientMin():GradientDataNumber; + + /** + * 最大渐变角速度。 + */ + get gradientMax():GradientDataNumber; + + /** + * 最小渐变角速度X。 + */ + get gradientXMin():GradientDataNumber; + + /** + * 最大渐变角速度X。 + */ + get gradientXMax():GradientDataNumber; + + /** + * 最小渐变角速度Y。 + */ + get gradientYMin():GradientDataNumber; + + /** + * 最大渐变角速度Y。 + */ + get gradientYMax():GradientDataNumber; + + /** + * 最小渐变角速度Z。 + */ + get gradientZMin():GradientDataNumber; + + /** + * 最大渐变角速度Z。 + */ + get gradientZMax():GradientDataNumber; + + /** + * 最小渐变角速度Z。 + */ + get gradientWMin():GradientDataNumber; + + /** + * 最大渐变角速度Z。 + */ + get gradientWMax():GradientDataNumber; + + /** + * 创建一个 GradientAngularVelocity,不允许new,请使用静态创建函数。 实例。 + */ + + constructor(); + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * GradientColor 类用于创建渐变颜色。 + */ + class GradientColor implements IClone { + + /** + * 通过固定颜色创建一个 GradientColor 实例。 + * @param constant 固定颜色。 + */ + static createByConstant(constant:Vector4):GradientColor; + + /** + * 通过渐变颜色创建一个 GradientColor 实例。 + * @param gradient 渐变色。 + */ + static createByGradient(gradient:Gradient):GradientColor; + + /** + * 通过随机双固定颜色创建一个 GradientColor 实例。 + * @param minConstant 最小固定颜色。 + * @param maxConstant 最大固定颜色。 + */ + static createByRandomTwoConstant(minConstant:Vector4,maxConstant:Vector4):GradientColor; + + /** + * 通过随机双渐变颜色创建一个 GradientColor 实例。 + * @param minGradient 最小渐变颜色。 + * @param maxGradient 最大渐变颜色。 + */ + static createByRandomTwoGradient(minGradient:Gradient,maxGradient:Gradient):GradientColor; + private _type:any; + private _constant:any; + private _constantMin:any; + private _constantMax:any; + private _gradient:any; + private _gradientMin:any; + private _gradientMax:any; + + /** + * 生命周期颜色类型,0为固定颜色模式,1渐变模式,2为随机双固定颜色模式,3随机双渐变模式。 + */ + get type():number; + + /** + * 固定颜色。 + */ + get constant():Vector4; + + /** + * 最小固定颜色。 + */ + get constantMin():Vector4; + + /** + * 最大固定颜色。 + */ + get constantMax():Vector4; + + /** + * 渐变颜色。 + */ + get gradient():Gradient; + + /** + * 最小渐变颜色。 + */ + get gradientMin():Gradient; + + /** + * 最大渐变颜色。 + */ + get gradientMax():Gradient; + + /** + * 创建一个 GradientColor,不允许new,请使用静态创建函数。 实例。 + */ + + constructor(); + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * GradientDataInt 类用于创建整形渐变。 + */ + class GradientDataInt implements IClone { + private _currentLength:any; + + /** + * 整形渐变数量。 + */ + get gradientCount():number; + + /** + * 创建一个 GradientDataInt 实例。 + */ + + constructor(); + + /** + * 增加整形渐变。 + * @param key 生命周期,范围为0到1。 + * @param value 整形值。 + */ + add(key:number,value:number):void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * GradientDataNumber 类用于创建浮点渐变。 + */ + class GradientDataNumber implements IClone { + private _currentLength:any; + + /** + * 渐变浮点数量。 + */ + get gradientCount():number; + + /** + * 创建一个 GradientDataNumber 实例。 + */ + + constructor(); + + /** + * 增加浮点渐变。 + * @param key 生命周期,范围为0到1。 + * @param value 浮点值。 + */ + add(key:number,value:number):void; + + /** + * 通过索引获取键。 + * @param index 索引。 + * @return value 键。 + */ + getKeyByIndex(index:number):number; + + /** + * 通过索引获取值。 + * @param index 索引。 + * @return value 值。 + */ + getValueByIndex(index:number):number; + + /** + * 获取平均值。 + */ + getAverageValue():number; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * GradientDataVector2 类用于创建二维向量渐变。 + */ + class GradientDataVector2 implements IClone { + private _currentLength:any; + + /** + * 二维向量渐变数量。 + */ + get gradientCount():number; + + /** + * 创建一个 GradientDataVector2 实例。 + */ + + constructor(); + + /** + * 增加二维向量渐变。 + * @param key 生命周期,范围为0到1。 + * @param value 二维向量值。 + */ + add(key:number,value:Vector2):void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * GradientSize 类用于创建渐变尺寸。 + */ + class GradientSize implements IClone { + + /** + * 通过渐变尺寸创建一个 GradientSize 实例。 + * @param gradient 渐变尺寸。 + * @return 渐变尺寸。 + */ + static createByGradient(gradient:GradientDataNumber):GradientSize; + + /** + * 通过分轴渐变尺寸创建一个 GradientSize 实例。 + * @param gradientX 渐变尺寸X。 + * @param gradientY 渐变尺寸Y。 + * @param gradientZ 渐变尺寸Z。 + * @return 渐变尺寸。 + */ + static createByGradientSeparate(gradientX:GradientDataNumber,gradientY:GradientDataNumber,gradientZ:GradientDataNumber):GradientSize; + + /** + * 通过随机双固定尺寸创建一个 GradientSize 实例。 + * @param constantMin 最小固定尺寸。 + * @param constantMax 最大固定尺寸。 + * @return 渐变尺寸。 + */ + static createByRandomTwoConstant(constantMin:number,constantMax:number):GradientSize; + + /** + * 通过分轴随机双固定尺寸创建一个 GradientSize 实例。 + * @param constantMinSeparate 分轴最小固定尺寸. + * @param constantMaxSeparate 分轴最大固定尺寸。 + * @return 渐变尺寸。 + */ + static createByRandomTwoConstantSeparate(constantMinSeparate:Vector3,constantMaxSeparate:Vector3):GradientSize; + + /** + * 通过随机双渐变尺寸创建一个 GradientSize 实例。 + * @param gradientMin 最小渐变尺寸。 + * @param gradientMax 最大渐变尺寸。 + * @return 渐变尺寸。 + */ + static createByRandomTwoGradient(gradientMin:GradientDataNumber,gradientMax:GradientDataNumber):GradientSize; + + /** + * 通过分轴随机双渐变尺寸创建一个 GradientSize 实例。 + * @param gradientXMin X轴最小渐变尺寸。 + * @param gradientXMax X轴最大渐变尺寸。 + * @param gradientYMin Y轴最小渐变尺寸。 + * @param gradientYMax Y轴最大渐变尺寸。 + * @param gradientZMin Z轴最小渐变尺寸。 + * @param gradientZMax Z轴最大渐变尺寸。 + * @return 渐变尺寸。 + */ + static createByRandomTwoGradientSeparate(gradientXMin:GradientDataNumber,gradientXMax:GradientDataNumber,gradientYMin:GradientDataNumber,gradientYMax:GradientDataNumber,gradientZMin:GradientDataNumber,gradientZMax:GradientDataNumber):GradientSize; + private _type:any; + private _separateAxes:any; + private _gradient:any; + private _gradientX:any; + private _gradientY:any; + private _gradientZ:any; + private _constantMin:any; + private _constantMax:any; + private _constantMinSeparate:any; + private _constantMaxSeparate:any; + private _gradientMin:any; + private _gradientMax:any; + private _gradientXMin:any; + private _gradientXMax:any; + private _gradientYMin:any; + private _gradientYMax:any; + private _gradientZMin:any; + private _gradientZMax:any; + + /** + * 生命周期尺寸类型,0曲线模式,1随机双常量模式,2随机双曲线模式。 + */ + get type():number; + + /** + * 是否分轴。 + */ + get separateAxes():boolean; + + /** + * 渐变尺寸。 + */ + get gradient():GradientDataNumber; + + /** + * 渐变尺寸X。 + */ + get gradientX():GradientDataNumber; + + /** + * 渐变尺寸Y。 + */ + get gradientY():GradientDataNumber; + + /** + * 渐变尺寸Z。 + */ + get gradientZ():GradientDataNumber; + + /** + * 最小随机双固定尺寸。 + */ + get constantMin():number; + + /** + * 最大随机双固定尺寸。 + */ + get constantMax():number; + + /** + * 最小分轴随机双固定尺寸。 + */ + get constantMinSeparate():Vector3; + + /** + * 最小分轴随机双固定尺寸。 + */ + get constantMaxSeparate():Vector3; + + /** + * 渐变最小尺寸。 + */ + get gradientMin():GradientDataNumber; + + /** + * 渐变最大尺寸。 + */ + get gradientMax():GradientDataNumber; + + /** + * 渐变最小尺寸X。 + */ + get gradientXMin():GradientDataNumber; + + /** + * 渐变最大尺寸X。 + */ + get gradientXMax():GradientDataNumber; + + /** + * 渐变最小尺寸Y。 + */ + get gradientYMin():GradientDataNumber; + + /** + * 渐变最大尺寸Y。 + */ + get gradientYMax():GradientDataNumber; + + /** + * 渐变最小尺寸Z。 + */ + get gradientZMin():GradientDataNumber; + + /** + * 渐变最大尺寸Z。 + */ + get gradientZMax():GradientDataNumber; + + /** + * 创建一个 GradientSize,不允许new,请使用静态创建函数。 实例。 + */ + + constructor(); + + /** + * 获取最大尺寸。 + */ + getMaxSizeInGradient(meshMode?:boolean):number; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * GradientVelocity 类用于创建渐变速度。 + */ + class GradientVelocity implements IClone { + + /** + * 通过固定速度创建一个 GradientVelocity 实例。 + * @param constant 固定速度。 + * @return 渐变速度。 + */ + static createByConstant(constant:Vector3):GradientVelocity; + + /** + * 通过渐变速度创建一个 GradientVelocity 实例。 + * @param gradientX 渐变速度X。 + * @param gradientY 渐变速度Y。 + * @param gradientZ 渐变速度Z。 + * @return 渐变速度。 + */ + static createByGradient(gradientX:GradientDataNumber,gradientY:GradientDataNumber,gradientZ:GradientDataNumber):GradientVelocity; + + /** + * 通过随机双固定速度创建一个 GradientVelocity 实例。 + * @param constantMin 最小固定角速度。 + * @param constantMax 最大固定角速度。 + * @return 渐变速度。 + */ + static createByRandomTwoConstant(constantMin:Vector3,constantMax:Vector3):GradientVelocity; + + /** + * 通过随机双渐变速度创建一个 GradientVelocity 实例。 + * @param gradientXMin X轴最小渐变速度。 + * @param gradientXMax X轴最大渐变速度。 + * @param gradientYMin Y轴最小渐变速度。 + * @param gradientYMax Y轴最大渐变速度。 + * @param gradientZMin Z轴最小渐变速度。 + * @param gradientZMax Z轴最大渐变速度。 + * @return 渐变速度。 + */ + static createByRandomTwoGradient(gradientXMin:GradientDataNumber,gradientXMax:GradientDataNumber,gradientYMin:GradientDataNumber,gradientYMax:GradientDataNumber,gradientZMin:GradientDataNumber,gradientZMax:GradientDataNumber):GradientVelocity; + private _type:any; + private _constant:any; + private _gradientX:any; + private _gradientY:any; + private _gradientZ:any; + private _constantMin:any; + private _constantMax:any; + private _gradientXMin:any; + private _gradientXMax:any; + private _gradientYMin:any; + private _gradientYMax:any; + private _gradientZMin:any; + private _gradientZMax:any; + + /** + * 生命周期速度类型,0常量模式,1曲线模式,2随机双常量模式,3随机双曲线模式。 + */ + get type():number; + + /** + * 固定速度。 + */ + get constant():Vector3; + + /** + * 渐变速度X。 + */ + get gradientX():GradientDataNumber; + + /** + * 渐变速度Y。 + */ + get gradientY():GradientDataNumber; + + /** + * 渐变速度Z。 + */ + get gradientZ():GradientDataNumber; + + /** + * 最小固定速度。 + */ + get constantMin():Vector3; + + /** + * 最大固定速度。 + */ + get constantMax():Vector3; + + /** + * 渐变最小速度X。 + */ + get gradientXMin():GradientDataNumber; + + /** + * 渐变最大速度X。 + */ + get gradientXMax():GradientDataNumber; + + /** + * 渐变最小速度Y。 + */ + get gradientYMin():GradientDataNumber; + + /** + * 渐变最大速度Y。 + */ + get gradientYMax():GradientDataNumber; + + /** + * 渐变最小速度Z。 + */ + get gradientZMin():GradientDataNumber; + + /** + * 渐变最大速度Z。 + */ + get gradientZMax():GradientDataNumber; + + /** + * 创建一个 GradientVelocity,不允许new,请使用静态创建函数。 实例。 + */ + + constructor(); + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * RotationOverLifetime 类用于粒子的生命周期旋转。 + */ + class RotationOverLifetime implements IClone { + private _angularVelocity:any; + + /** + * 是否启用 + */ + enable:boolean; + + /** + * 获取角速度。 + */ + get angularVelocity():GradientAngularVelocity; + + /** + * 创建一个 RotationOverLifetime,不允许new,请使用静态创建函数。 实例。 + */ + + constructor(angularVelocity:GradientAngularVelocity); + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + +enum ParticleSystemShapeType { + /**盒体 */ + Box = 0, + /**环形 */ + Circle = 1, + /**锥体 */ + Cone = 2, + /**半球体 */ + Hemisphere = 3, + /**球体 */ + Sphere = 4 +} + + /** + * BaseShape 类用于粒子形状。 + */ + class BaseShape implements IClone { + + /** + * 是否启用。 + */ + enable:boolean; + + /** + * 随机方向。 + */ + randomDirection:number; + + /** + * 粒子类型 + */ + shapeType:ParticleSystemShapeType; + + /** + * 创建一个 BaseShape 实例。 + */ + + constructor(); + + /** + * 用于生成粒子初始位置和方向。 + * @param position 粒子位置。 + * @param direction 粒子方向。 + */ + generatePositionAndDirection(position:Vector3,direction:Vector3,rand?:Rand,randomSeeds?:Uint32Array):void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * BoxShape 类用于创建球形粒子形状。 + */ + class BoxShape extends BaseShape { + + /** + * 发射器X轴长度。 + */ + x:number; + + /** + * 发射器Y轴长度。 + */ + y:number; + + /** + * 发射器Z轴长度。 + */ + z:number; + + /** + * 创建一个 BoxShape 实例。 + */ + + constructor(); + + /** + * 用于生成粒子初始位置和方向。 + * @param position 粒子位置。 + * @param direction 粒子方向。 + * @override + */ + generatePositionAndDirection(position:Vector3,direction:Vector3,rand?:Rand,randomSeeds?:Uint32Array):void; + + /** + * @param destObject + * @override + */ + cloneTo(destObject:any):void; + + /** + * @override 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * CircleShape 类用于创建环形粒子形状。 + */ + class CircleShape extends BaseShape { + + /** + * 发射器半径。 + */ + radius:number; + + /** + * 环形弧度。 + */ + arc:number; + + /** + * 从边缘发射。 + */ + emitFromEdge:boolean; + + /** + * 创建一个 CircleShape 实例。 + */ + + constructor(); + + /** + * 用于生成粒子初始位置和方向。 + * @param position 粒子位置。 + * @param direction 粒子方向。 + * @override + */ + generatePositionAndDirection(position:Vector3,direction:Vector3,rand?:Rand,randomSeeds?:Uint32Array):void; + + /** + * @param destObject + * @override + */ + cloneTo(destObject:any):void; + + /** + * @override 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * ConeShape 类用于创建锥形粒子形状。 + */ + class ConeShape extends BaseShape { + + /** + * 发射角度。 + */ + angle:number; + + /** + * 发射器半径。 + */ + radius:number; + + /** + * 椎体长度。 + */ + length:number; + + /** + * 发射类型,0为Base,1为BaseShell,2为Volume,3为VolumeShell。 + */ + emitType:number; + + /** + * 创建一个 ConeShape 实例。 + */ + + constructor(); + + /** + * 用于生成粒子初始位置和方向。 + * @param position 粒子位置。 + * @param direction 粒子方向。 + * @override + */ + generatePositionAndDirection(position:Vector3,direction:Vector3,rand?:Rand,randomSeeds?:Uint32Array):void; + + /** + * @override + */ + cloneTo(destObject:any):void; + + /** + * @override 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * HemisphereShape 类用于创建半球形粒子形状。 + */ + class HemisphereShape extends BaseShape { + + /** + * 发射器半径。 + */ + radius:number; + + /** + * 从外壳发射。 + */ + emitFromShell:boolean; + + /** + * 创建一个 HemisphereShape 实例。 + */ + + constructor(); + + /** + * 用于生成粒子初始位置和方向。 + * @param position 粒子位置。 + * @param direction 粒子方向。 + * @override + */ + generatePositionAndDirection(position:Vector3,direction:Vector3,rand?:Rand,randomSeeds?:Uint32Array):void; + + /** + * @override + */ + cloneTo(destObject:any):void; + + /** + * @override 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * SphereShape 类用于创建球形粒子形状。 + */ + class SphereShape extends BaseShape { + + /** + * 发射器半径。 + */ + radius:number; + + /** + * 从外壳发射。 + */ + emitFromShell:boolean; + + /** + * 创建一个 SphereShape 实例。 + */ + + constructor(); + + /** + * 用于生成粒子初始位置和方向。 + * @param position 粒子位置。 + * @param direction 粒子方向。 + * @override + */ + generatePositionAndDirection(position:Vector3,direction:Vector3,rand?:Rand,randomSeeds?:Uint32Array):void; + + /** + * @override + */ + cloneTo(destObject:any):void; + + /** + * @override 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * SizeOverLifetime 类用于粒子的生命周期尺寸。 + */ + class SizeOverLifetime implements IClone { + private _size:any; + + /** + * 是否启用 + */ + enable:boolean; + + /** + * 获取尺寸。 + */ + get size():GradientSize; + + /** + * 创建一个 SizeOverLifetime 实例。 + */ + + constructor(size:GradientSize); + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * StartFrame 类用于创建开始帧。 + */ + class StartFrame implements IClone { + + /** + * 通过随机常量旋转创建一个 StartFrame 实例。 + * @param constant 固定帧。 + * @return 开始帧。 + */ + static createByConstant(constant?:number):StartFrame; + + /** + * 通过随机双常量旋转创建一个 StartFrame 实例。 + * @param constantMin 最小固定帧。 + * @param constantMax 最大固定帧。 + * @return 开始帧。 + */ + static createByRandomTwoConstant(constantMin?:number,constantMax?:number):StartFrame; + private _type:any; + private _constant:any; + private _constantMin:any; + private _constantMax:any; + + /** + * 开始帧类型,0常量模式,1随机双常量模式。 + */ + get type():number; + + /** + * 固定帧。 + */ + get constant():number; + + /** + * 最小固定帧。 + */ + get constantMin():number; + + /** + * 最大固定帧。 + */ + get constantMax():number; + + /** + * 创建一个 StartFrame,不允许new,请使用静态创建函数。 实例。 + */ + + constructor(); + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * TextureSheetAnimation 类用于创建粒子帧动画。 + */ + class TextureSheetAnimation implements IClone { + + /** + * 纹理平铺。 + */ + tiles:Vector2; + + /** + * 类型,0为whole sheet、1为singal row。 + */ + type:number; + + /** + * 是否随机行,type为1时有效。 + */ + randomRow:boolean; + + /** + * 行索引,type为1时有效。 + */ + rowIndex:number; + + /** + * 循环次数。 + */ + cycles:number; + + /** + * UV通道类型,0为Noting,1为Everything,待补充,暂不支持。 + */ + enableUVChannels:number; + + /** + * 是否启用 + */ + enable:boolean; + + /** + * 获取时间帧率。 + */ + get frame():FrameOverTime; + + /** + * 获取开始帧率。 + */ + get startFrame():StartFrame; + + /** + * 创建一个 TextureSheetAnimation 实例。 + * @param frame 动画帧。 + * @param startFrame 开始帧。 + */ + + constructor(frame:FrameOverTime,startFrame:StartFrame); + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * VelocityOverLifetime 类用于粒子的生命周期速度。 + */ + class VelocityOverLifetime implements IClone { + + /** + * 是否启用 + */ + enable:boolean; + + /** + * 速度空间,0为local,1为world。 + */ + space:number; + + /** + * 获取尺寸。 + */ + get velocity():GradientVelocity; + + /** + * 创建一个 VelocityOverLifetime 实例。 + */ + + constructor(velocity:GradientVelocity); + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * ShuriKenParticle3D 3D粒子。 + */ + class ShuriKenParticle3D extends RenderableSprite3D { + + /** + * 粒子系统。 + */ + get particleSystem():ShurikenParticleSystem; + + /** + * 粒子渲染器。 + */ + get particleRenderer():ShurikenParticleRenderer; + + /** + * 创建一个 Particle3D 实例。 + */ + + constructor(); + + /** + *

销毁此对象。

+ * @param destroyChild 是否同时销毁子节点,若值为true,则销毁子节点,否则不销毁子节点。 + * @override + */ + destroy(destroyChild?:boolean):void; + } + + /** + * ShurikenParticleMaterial 类用于实现粒子材质。 + */ + class ShurikenParticleMaterial extends Material { + + /** + * 渲染状态_透明混合。 + */ + static RENDERMODE_ALPHABLENDED:number; + + /** + * 渲染状态_加色法混合。 + */ + static RENDERMODE_ADDTIVE:number; + + /** + * @interanl + */ + static SHADERDEFINE_ADDTIVEFOG:ShaderDefine; + + /** + * 默认材质,禁止修改 + */ + static defaultMaterial:ShurikenParticleMaterial; + + /** + * 渲染模式。 + */ + set renderMode(value:number); + + /** + * 颜色R分量。 + */ + get colorR():number; + set colorR(value:number); + + /** + * 颜色G分量。 + */ + get colorG():number; + set colorG(value:number); + + /** + * 颜色B分量。 + */ + get colorB():number; + set colorB(value:number); + + /** + * 颜色Z分量。 + */ + get colorA():number; + set colorA(value:number); + + /** + * 颜色。 + */ + get color():Vector4; + set color(value:Vector4); + + /** + * 纹理平铺和偏移X分量。 + */ + get tilingOffsetX():number; + set tilingOffsetX(x:number); + + /** + * 纹理平铺和偏移Y分量。 + */ + get tilingOffsetY():number; + set tilingOffsetY(y:number); + + /** + * 纹理平铺和偏移Z分量。 + */ + get tilingOffsetZ():number; + set tilingOffsetZ(z:number); + + /** + * 纹理平铺和偏移W分量。 + */ + get tilingOffsetW():number; + set tilingOffsetW(w:number); + + /** + * 纹理平铺和偏移。 + */ + get tilingOffset():Vector4; + set tilingOffset(value:Vector4); + + /** + * 漫反射贴图。 + */ + get texture():BaseTexture; + set texture(value:BaseTexture); + + /** + * 创建一个 ShurikenParticleMaterial 实例。 + */ + + constructor(); + + /** + * 克隆。 + * @return 克隆副本。 + * @override + */ + clone():any; + } + + /** + * ShurikenParticleRender 类用于创建3D粒子渲染器。 + */ + class ShurikenParticleRenderer extends BaseRender { + + /** + * 拉伸广告牌模式摄像机速度缩放,暂不支持。 + */ + stretchedBillboardCameraSpeedScale:number; + + /** + * 拉伸广告牌模式速度缩放。 + */ + stretchedBillboardSpeedScale:number; + + /** + * 拉伸广告牌模式长度缩放。 + */ + stretchedBillboardLengthScale:number; + + /** + * 获取渲染模式,0为BILLBOARD、1为STRETCHEDBILLBOARD、2为HORIZONTALBILLBOARD、3为VERTICALBILLBOARD、4为MESH。 + */ + get renderMode():number; + set renderMode(value:number); + + /** + * 获取网格渲染模式所使用的Mesh,rendderMode为4时生效。 + */ + get mesh():Mesh; + set mesh(value:Mesh); + + /** + * 创建一个 ShurikenParticleRender 实例。 + */ + + constructor(owner:ShuriKenParticle3D); + + /** + * @inheritDoc + * @override + */ + get bounds():Bounds; + } + + /** + * ShurikenParticleSystem 类用于创建3D粒子数据模板。 + */ + class ShurikenParticleSystem extends GeometryElement implements IClone { + + /** + * 粒子运行的总时长,单位为秒。 + */ + duration:number; + + /** + * 是否循环。 + */ + looping:boolean; + + /** + * 是否预热。暂不支持 + */ + prewarm:boolean; + + /** + * 开始延迟类型,0为常量模式,1为随机随机双常量模式,不能和prewarm一起使用。 + */ + startDelayType:number; + + /** + * 开始播放延迟,不能和prewarm一起使用。 + */ + startDelay:number; + + /** + * 开始播放最小延迟,不能和prewarm一起使用。 + */ + startDelayMin:number; + + /** + * 开始播放最大延迟,不能和prewarm一起使用。 + */ + startDelayMax:number; + + /** + * 开始速度模式,0为恒定速度,2为两个恒定速度的随机插值。缺少1、3模式 + */ + startSpeedType:number; + + /** + * 开始速度,0模式。 + */ + startSpeedConstant:number; + + /** + * 最小开始速度,1模式。 + */ + startSpeedConstantMin:number; + + /** + * 最大开始速度,1模式。 + */ + startSpeedConstantMax:number; + + /** + * 开始尺寸是否为3D模式。 + */ + threeDStartSize:boolean; + + /** + * 开始尺寸模式,0为恒定尺寸,2为两个恒定尺寸的随机插值。缺少1、3模式和对应的二种3D模式 + */ + startSizeType:number; + + /** + * 开始尺寸,0模式。 + */ + startSizeConstant:number; + + /** + * 开始三维尺寸,0模式。 + */ + startSizeConstantSeparate:Vector3; + + /** + * 最小开始尺寸,2模式。 + */ + startSizeConstantMin:number; + + /** + * 最大开始尺寸,2模式。 + */ + startSizeConstantMax:number; + + /** + * 最小三维开始尺寸,2模式。 + */ + startSizeConstantMinSeparate:Vector3; + + /** + * 最大三维开始尺寸,2模式。 + */ + startSizeConstantMaxSeparate:Vector3; + + /** + * 3D开始旋转。 + */ + threeDStartRotation:boolean; + + /** + * 开始旋转模式,0为恒定尺寸,2为两个恒定旋转的随机插值,缺少2种模式,和对应的四种3D模式。 + */ + startRotationType:number; + + /** + * 开始旋转,0模式。 + */ + startRotationConstant:number; + + /** + * 开始三维旋转,0模式。 + */ + startRotationConstantSeparate:Vector3; + + /** + * 最小开始旋转,1模式。 + */ + startRotationConstantMin:number; + + /** + * 最大开始旋转,1模式。 + */ + startRotationConstantMax:number; + + /** + * 最小开始三维旋转,1模式。 + */ + startRotationConstantMinSeparate:Vector3; + + /** + * 最大开始三维旋转,1模式。 + */ + startRotationConstantMaxSeparate:Vector3; + + /** + * 随机旋转方向,范围为0.0到1.0 + */ + randomizeRotationDirection:number; + + /** + * 开始颜色模式,0为恒定颜色,2为两个恒定颜色的随机插值,缺少2种模式。 + */ + startColorType:number; + + /** + * 开始颜色,0模式。 + */ + startColorConstant:Vector4; + + /** + * 最小开始颜色,1模式。 + */ + startColorConstantMin:Vector4; + + /** + * 最大开始颜色,1模式。 + */ + startColorConstantMax:Vector4; + + /** + * 重力敏感度。 + */ + gravityModifier:number; + + /** + * 模拟器空间,0为World,1为Local。暂不支持Custom。 + */ + simulationSpace:number; + + /** + * 粒子的播放速度。 + */ + simulationSpeed:number; + + /** + * 缩放模式,0为Hiercachy,1为Local,2为World。 + */ + scaleMode:number; + + /** + * 激活时是否自动播放。 + */ + playOnAwake:boolean; + + /** + * 随机种子,注:play()前设置有效。 + */ + randomSeed:Uint32Array; + + /** + * 是否使用随机种子。 + */ + autoRandomSeed:boolean; + + /** + * 是否为性能模式,性能模式下会延迟粒子释放。 + */ + isPerformanceMode:boolean; + + /** + * 最大粒子数。 + */ + get maxParticles():number; + set maxParticles(value:number); + + /** + * 获取发射器。 + */ + get emission():Emission; + + /** + * 粒子存活个数。 + */ + get aliveParticleCount():number; + + /** + * 一次循环内的累计时间。 + */ + get emissionTime():number; + + /** + * 形状。 + */ + get shape():BaseShape; + set shape(value:BaseShape); + + /** + * 是否存活。 + */ + get isAlive():boolean; + + /** + * 是否正在发射。 + */ + get isEmitting():boolean; + + /** + * 是否正在播放。 + */ + get isPlaying():boolean; + + /** + * 是否已暂停。 + */ + get isPaused():boolean; + + /** + * 开始生命周期模式,0为固定时间,1为渐变时间,2为两个固定之间的随机插值,3为两个渐变时间的随机插值。 + */ + get startLifetimeType():number; + set startLifetimeType(value:number); + + /** + * 开始生命周期,0模式,单位为秒。 + */ + get startLifetimeConstant():number; + set startLifetimeConstant(value:number); + + /** + * 开始渐变生命周期,1模式,单位为秒。 + */ + get startLifeTimeGradient():GradientDataNumber; + set startLifeTimeGradient(value:GradientDataNumber); + + /** + * 最小开始生命周期,2模式,单位为秒。 + */ + get startLifetimeConstantMin():number; + set startLifetimeConstantMin(value:number); + + /** + * 最大开始生命周期,2模式,单位为秒。 + */ + get startLifetimeConstantMax():number; + set startLifetimeConstantMax(value:number); + + /** + * 开始渐变最小生命周期,3模式,单位为秒。 + */ + get startLifeTimeGradientMin():GradientDataNumber; + set startLifeTimeGradientMin(value:GradientDataNumber); + + /** + * 开始渐变最大生命周期,3模式,单位为秒。 + */ + get startLifeTimeGradientMax():GradientDataNumber; + set startLifeTimeGradientMax(value:GradientDataNumber); + + /** + * 生命周期速度,注意:如修改该值的某些属性,需重新赋值此属性才可生效。 + */ + get velocityOverLifetime():VelocityOverLifetime; + set velocityOverLifetime(value:VelocityOverLifetime); + + /** + * 生命周期颜色,注意:如修改该值的某些属性,需重新赋值此属性才可生效。 + */ + get colorOverLifetime():ColorOverLifetime; + set colorOverLifetime(value:ColorOverLifetime); + + /** + * 生命周期尺寸,注意:如修改该值的某些属性,需重新赋值此属性才可生效。 + */ + get sizeOverLifetime():SizeOverLifetime; + set sizeOverLifetime(value:SizeOverLifetime); + + /** + * 生命周期旋转,注意:如修改该值的某些属性,需重新赋值此属性才可生效。 + */ + get rotationOverLifetime():RotationOverLifetime; + set rotationOverLifetime(value:RotationOverLifetime); + + /** + * 生命周期纹理动画,注意:如修改该值的某些属性,需重新赋值此属性才可生效。 + */ + get textureSheetAnimation():TextureSheetAnimation; + set textureSheetAnimation(value:TextureSheetAnimation); + + constructor(owner:ShuriKenParticle3D); + + /** + * 设置 自定义 包围盒 + */ + get customBounds():Bounds; + set customBounds(value:Bounds); + + /** + * 发射一个粒子。 + */ + emit(time:number):boolean; + addParticle(position:Vector3,direction:Vector3,time:number):boolean; + addNewParticlesToVertexBuffer():void; + + /** + * @inheritDoc + * @override + */ + _getType():number; + + /** + * 开始发射粒子。 + */ + play():void; + + /** + * 暂停发射粒子。 + */ + pause():void; + + /** + * 通过指定时间增加粒子播放进度,并暂停播放。 + * @param time 进度时间.如果restart为true,粒子播放时间会归零后再更新进度。 + * @param restart 是否重置播放状态。 + */ + simulate(time:number,restart?:boolean):void; + + /** + * 停止发射粒子。 + */ + stop():void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * PixelLineData 类用于表示线数据。 + */ + class PixelLineData { + + /** + * 线开始位置 + */ + startPosition:Vector3; + + /** + * 线结束位置 + */ + endPosition:Vector3; + + /** + * 线开始颜色 + */ + startColor:Color; + + /** + * 线结束颜色 + */ + endColor:Color; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:PixelLineData):void; + } + + /** + * PixelLineFilter 类用于线过滤器。 + */ + class PixelLineFilter extends GeometryElement { + + /** + * @private + */ + private static _tempVector0:any; + + /** + * @private + */ + private static _tempVector1:any; + + /** + * 创建一个PixelLineFilter实例 + * @param owner 渲染精灵节点 + * @param maxLineCount 最大线长 + */ + + constructor(owner:PixelLineSprite3D,maxLineCount:number); + + /** + * 获取线段数据 + * @return 线段数据。 + */ + _getLineData(index:number,out:PixelLineData):void; + + /** + * @inheritDoc + * @override 删除 + */ + destroy():void; + } + + /** + * PixelLineMaterial 类用于实现像素线材质。 + */ + class PixelLineMaterial extends Material { + + /** + * 默认材质,禁止修改 + */ + static defaultMaterial:PixelLineMaterial; + + /** + * 获取颜色。 + * @return 颜色。 + */ + get color():Vector4; + + /** + * 设置颜色。 + * @param value 颜色。 + */ + set color(value:Vector4); + + /** + * 创建一个 PixelLineMaterial 实例。 + */ + + constructor(); + } + + /** + * PixelLineRenderer 类用于线渲染器。 + */ + class PixelLineRenderer extends BaseRender { + + /** + * 创建一个PixelLineRenderer实例 + * @param owner 线渲染精灵 + */ + + constructor(owner:PixelLineSprite3D); + } + + /** + * PixelLineSprite3D 类用于像素线渲染精灵。 + */ + class PixelLineSprite3D extends RenderableSprite3D { + + /** + * @private 是否调用active + */ + private _isRenderActive:any; + + /** + * @private 是否加入渲染队列 + */ + private _isInRenders:any; + + /** + * 最大线数量 + */ + get maxLineCount():number; + set maxLineCount(value:number); + + /** + * 获取线数量。 + */ + get lineCount():number; + set lineCount(value:number); + + /** + * line渲染器。 + */ + get pixelLineRenderer():PixelLineRenderer; + + /** + * 创建一个 PixelLineSprite3D 实例。 + * @param maxCount 最大线段数量。 + * @param name 名字。 + */ + + constructor(maxCount?:number,name?:string); + + /** + * @inheritDoc + * @override + */ + protected _onInActive():void; + + /** + * @inheritDoc + * @override + */ + protected _onActive():void; + + /** + * @inheritDoc + */ + _changeRenderObjects(index:number,material:Material):void; + + /** + * 增加一条线。 + * @param startPosition 初始点位置 + * @param endPosition 结束点位置 + * @param startColor 初始点颜色 + * @param endColor 结束点颜色 + */ + addLine(startPosition:Vector3,endPosition:Vector3,startColor:Color,endColor:Color):void; + + /** + * 添加多条线段。 + * @param lines 线段数据 + */ + addLines(lines:PixelLineData[]):void; + + /** + * 移除一条线段。 + * @param index 索引。 + */ + removeLine(index:number):void; + + /** + * 更新线 + * @param index 索引 + * @param startPosition 初始点位置 + * @param endPosition 结束点位置 + * @param startColor 初始点颜色 + * @param endColor 结束点颜色 + */ + setLine(index:number,startPosition:Vector3,endPosition:Vector3,startColor:Color,endColor:Color):void; + + /** + * 获取线段数据 + * @param out 线段数据。 + */ + getLine(index:number,out:PixelLineData):void; + + /** + * 清除所有线段。 + */ + clear():void; + } + + /** + * QuaternionKeyframe 类用于创建四元数关键帧实例。 + */ + class QuaternionKeyframe extends Keyframe { + inTangent:Vector4; + outTangent:Vector4; + value:Quaternion; + + /** + * 创建一个 QuaternionKeyframe 实例。 + */ + + constructor(); + + /** + * 克隆。 + * @param destObject 克隆源。 + * @override + */ + cloneTo(dest:any):void; + } + +enum ReflectionProbeMode { + /**烘培模式 */ + off = 0, + /**实时简单采样模式 还未支持*/ + simple = 1 +} + + /** + * ReflectionProbe 类用于实现反射探针组件 + * @miner + */ + class ReflectionProbe extends Sprite3D { + static TEMPVECTOR3:Vector3; + + /** + * 默认解码数据 + */ + static defaultTextureHDRDecodeValues:Vector4; + + /** + * 盒子反射是否开启 + */ + private _boxProjection:any; + + /** + * 探针重要度 + */ + private _importance:any; + + /** + * 反射探针图片 + */ + private _reflectionTexture:any; + + /** + * 包围盒大小 + */ + private _size:any; + + /** + * 包围盒偏移 + */ + private _offset:any; + + /** + * 包围盒 + */ + private _bounds:any; + + /** + * 反射强度 + */ + private _intensity:any; + + /** + * 反射参数 + */ + private _reflectionHDRParams:any; + + /** + * 反射探针解码格式 + */ + private _reflectionDecodeFormat:any; + + /** + * 队列索引 + */ + private _indexInReflectProbList:any; + + /** + * 是否是场景探针 + */ + _isScene:boolean; + + constructor(); + + /** + * 是否开启正交反射。 + */ + get boxProjection():boolean; + set boxProjection(value:boolean); + + /** + * 设置反射探针的重要度 + */ + get importance():number; + set importance(value:number); + + /** + * 设置反射探针资源 + */ + get intensity():number; + set intensity(value:number); + + /** + * 设置反射贴图 + */ + get reflectionTexture():TextureCube; + set reflectionTexture(value:TextureCube); + + /** + * 获得反射探针的包围盒 + */ + get bounds():Bounds; + get boundsMax():Vector3; + get boundsMin():Vector3; + get probePosition():Vector3; + + /** + * 反射参数 + */ + get reflectionHDRParams():Vector4; + + /** + * 设置队列索引 + * @param value + */ + _setIndexInReflectionList(value:number):void; + + /** + * 获得队列索引 + */ + _getIndexInReflectionList():number; + + /** + * @inheritDoc + * @override + */ + protected _onActive():void; + + /** + * @inheritDoc + * @override + */ + protected _onInActive():void; + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + } + + /** + * ReflectionProbeList 类用于实现反射探针队列。 + * @miner + */ + class ReflectionProbeList extends SingletonList { + + /** + * 创建一个新的 ReflectionProbeList 实例。 + */ + + constructor(); + } + + /** + * ReflectionProbeManager 类用于反射探针管理 + * @miner + */ + class ReflectionProbeManager { + + constructor(); + set sceneReflectionProbe(value:TextureCube); + set sceneReflectionCubeHDRParam(value:Vector4); + + /** + * 更新baseRender的反射探针 + * @param baseRender + */ + _updateMotionObjects(baseRender:BaseRender):void; + + /** + * 添加运动物体。 + * @param 运动物体 。 + */ + addMotionObject(renderObject:BaseRender):void; + + /** + * 更新运动物体的反射探针信息 + */ + update():void; + + /** + * 更新传入所有渲染器反射探针 + * @param 渲染器列表 + */ + updateAllRenderObjects(baseRenders:SimpleSingletonList):void; + + /** + * 清楚变动队列 + */ + clearMotionObjects():void; + destroy():void; + } + + /** + * Render 类用于渲染器的父类,抽象类不允许实例。 + */ + class BaseRender extends EventDispatcher implements ISingletonElement,IOctreeObject { + + /** + * 排序矫正值。 + */ + sortingFudge:number; + + /** + * 获取唯一标识ID,通常用于识别。 + */ + get id():number; + + /** + * 光照贴图的索引。 + */ + get lightmapIndex():number; + set lightmapIndex(value:number); + + /** + * 光照贴图的缩放和偏移。 + */ + get lightmapScaleOffset():Vector4; + set lightmapScaleOffset(value:Vector4); + + /** + * 是否可用。 + */ + get enable():boolean; + set enable(value:boolean); + + /** + * 返回第一个实例材质,第一次使用会拷贝实例对象。 + */ + get material():Material; + set material(value:Material); + + /** + * 潜拷贝实例材质列表,第一次使用会拷贝实例对象。 + */ + get materials():Material[]; + set materials(value:Material[]); + + /** + * 返回第一个材质。 + */ + get sharedMaterial():Material; + set sharedMaterial(value:Material); + + /** + * 浅拷贝材质列表。 + */ + get sharedMaterials():Material[]; + set sharedMaterials(value:Material[]); + + /** + * 包围盒,只读,不允许修改其值。 + */ + get bounds():Bounds; + set receiveShadow(value:boolean); + + /** + * 是否接收阴影属性 + */ + get receiveShadow():boolean; + + /** + * 是否产生阴影。 + */ + get castShadow():boolean; + set castShadow(value:boolean); + + /** + * 是否是静态的一部分。 + */ + get isPartOfStaticBatch():boolean; + + /** + * 是否被渲染。 + */ + get isRender():boolean; + set reflectionMode(value:ReflectionProbeMode); + get reflectionMode():ReflectionProbeMode; + + /** + */ + _getOctreeNode():BoundsOctreeNode; + + /** + */ + _setOctreeNode(value:BoundsOctreeNode):void; + + /** + */ + _getIndexInMotionList():number; + + /** + */ + _setIndexInMotionList(value:number):void; + + /** + * [实现ISingletonElement接口] + */ + _getIndexInList():number; + + /** + * [实现ISingletonElement接口] + */ + _setIndexInList(index:number):void; + _setUnBelongScene():void; + + /** + * 标记为非静态,静态合并后可用于取消静态限制。 + */ + markAsUnStatic():void; + } + + /** + * BloomEffect 类用于创建泛光效果。 + */ + class BloomEffect extends PostProcessEffect { + + /** + * 限制泛光像素的数量,该值在伽马空间。 + */ + clamp:number; + + /** + * 泛光颜色。 + */ + color:Color; + + /** + * 是否开启快速模式。该模式通过降低质量来提升性能。 + */ + fastMode:boolean; + + /** + * 镜头污渍纹路,用于为泛光特效增加污渍灰尘效果 + */ + dirtTexture:Texture2D; + + /** + * 获取泛光过滤器强度,最小值为0。 + * @return 强度。 + */ + get intensity():number; + + /** + * 设置泛光过滤器强度,最小值为0。 + * @param value 强度。 + */ + set intensity(value:number); + + /** + * 设置泛光阈值,在该阈值亮度以下的像素会被过滤掉,该值在伽马空间。 + * @return 阈值。 + */ + get threshold():number; + + /** + * 获取泛光阈值,在该阈值亮度以下的像素会被过滤掉,该值在伽马空间。 + * @param value 阈值。 + */ + set threshold(value:number); + + /** + * 获取软膝盖过渡强度,在阈值以下进行渐变过渡(0为完全硬过度,1为完全软过度)。 + * @return 软膝盖值。 + */ + get softKnee():number; + + /** + * 设置软膝盖过渡强度,在阈值以下进行渐变过渡(0为完全硬过度,1为完全软过度)。 + * @param value 软膝盖值。 + */ + set softKnee(value:number); + + /** + * 获取扩散值,改变泛光的扩散范围,最好使用整数值保证效果,该值会改变内部的迭代次数,范围是1到10。 + * @return 光晕的扩散范围。 + */ + get diffusion():number; + + /** + * 设置扩散值,改变泛光的扩散范围,最好使用整数值保证效果,该值会改变内部的迭代次数,范围是1到10。 + * @param value 光晕的扩散范围。 + */ + set diffusion(value:number); + + /** + * 获取形变比,通过扭曲泛光产生视觉上形变,负值为垂直扭曲,正值为水平扭曲。 + * @return 形变比。 + */ + get anamorphicRatio():number; + + /** + * 设置形变比,通过扭曲泛光产生视觉上形变,负值为垂直扭曲,正值为水平扭曲。 + * @param value 形变比。 + */ + set anamorphicRatio(value:number); + + /** + * 获取污渍强度。 + * @return 污渍强度。 + */ + get dirtIntensity():number; + + /** + * 设置污渍强度。 + * @param value 污渍强度。 + */ + set dirtIntensity(value:number); + + /** + * 创建一个 BloomEffect 实例。 + */ + + constructor(); + } + + /** + * BlitScreenQuadCMD 类用于创建从一张渲染目标输出到另外一张渲染目标指令。 + */ + class BlitScreenQuadCMD extends Command { + + /** + * 创建命令流 + * @param source 原始贴图 如果设置为null 将会使用默认的Camera流程中的原RenderTexture + * @param dest 目标贴图 如果设置为null,将会使用默认的camera渲染目标 + * @param offsetScale 偏移缩放 + * @param shader 渲染shader + * @param shaderData 渲染数据 + * @param subShader subshader的节点 + * @param screenType + */ + static create(source:BaseTexture,dest:RenderTexture,offsetScale?:Vector4,shader?:Shader3D,shaderData?:ShaderData,subShader?:number,screenType?:number,commandbuffer?:CommandBuffer,definedCanvas?:boolean):BlitScreenQuadCMD; + + /** + * @inheritDoc + * @override + */ + run():void; + + /** + * @inheritDoc + * @override + */ + recover():void; + } + + /** + * Command 类用于创建指令。 + */ + class Command { + + /** + * 创建一个 Command 实例。 + */ + + constructor(); + + /** + * 运行渲染指令 + */ + run():void; + + /** + * 回收渲染指令 + */ + recover():void; + + /** + * 设置渲染上下文 + * @param context 渲染上下文 + */ + setContext(context:RenderContext3D):void; + } + + /** + * CommandBuffer 类用于创建命令流。 + */ + class CommandBuffer { + + /** + * 创建一个 CommandBuffer 实例。 + */ + + constructor(); + + /** + * 设置shader图片数据 + * @param shaderData shader数据集合 + * @param nameID 图片UniformID + * @param source 图片源 + */ + setShaderDataTexture(shaderData:ShaderData,nameID:number,source:BaseTexture):void; + + /** + * 设置全局纹理数据 + * @param nameID 图片uniformID + * @param source 图片源 + */ + setGlobalTexture(nameID:number,source:BaseTexture):void; + + /** + * 设置shader Vector4数据 + * @param shaderData shader数据集合 + * @param nameID 数据ID + * @param value 数据 + */ + setShaderDataVector(shaderData:ShaderData,nameID:number,value:Vector4):void; + + /** + * 设置全局Vector4数据 + * @param nameID Vector4数据ID + * @param source 数据 + */ + setGlobalVector(nameID:number,source:Vector4):void; + + /** + * 设置shader Vector3数据 + * @param shaderData shader数据集合 + * @param nameID 数据ID + * @param value 数据 + */ + setShaderDataVector3(shaderData:ShaderData,nameID:number,value:Vector3):void; + + /** + * 设置全局Vector3数据 + * @param nameID 数据ID + * @param source 数据 + */ + setGlobalVector3(nameID:number,source:Vector3):void; + + /** + * 设置shader Vector2数据 + * @param shaderData shader数据集合 + * @param nameID 数据ID + * @param value 数据 + */ + setShaderDataVector2(shaderData:ShaderData,nameID:number,value:Vector2):void; + + /** + * 设置全局Vector2数据 + * @param nameID 数据ID + * @param source 数据 + */ + setGlobalVector2(nameID:number,source:Vector2):void; + + /** + * 设置shader Number属性 + * @param shaderData shader数据集合 + * @param nameID 数据ID + * @param value 数据 + */ + setShaderDataNumber(shaderData:ShaderData,nameID:number,value:number):void; + + /** + * 设置全局number属性 + * @param nameID 数据ID + * @param source 数据 + */ + setGlobalNumber(nameID:number,source:number):void; + + /** + * 设置shader Int属性 + * @param shaderData shader数据集合 + * @param nameID 数据ID + * @param value 数据 + */ + setShaderDataInt(shaderData:ShaderData,nameID:number,value:number):void; + + /** + * 设置全局int属性 + * @param nameID 数据ID + * @param source 数据 + */ + setGlobalInt(nameID:number,source:number):void; + + /** + * 设置shader Matrix属性 + * @param shaderData shader数据集合 + * @param nameID 数据ID + * @param value 数据 + */ + setShaderDataMatrix(shaderData:ShaderData,nameID:number,value:Matrix4x4):void; + + /** + * 设置全局Matrix属性 + * @param nameID 数据ID + * @param source 数据 + */ + setGlobalMatrix(nameID:number,source:number):void; + + /** + * 添加一条通过全屏四边形将源纹理渲染到目标渲染纹理指令。 + * @param source 源纹理. 如果为null,前渲染结果为原纹理 + * @param dest 目标纹理. 如果为null,直接渲染到最终画布 + * @param offsetScale 偏移缩放。 + * @param shader 着色器,如果为null使用内部拷贝着色器,不做任何处理。 + * @param shaderData 着色器数据,如果为null只接收sourceTexture。 + * @param subShader subShader索引,默认值为0。 + */ + blitScreenQuad(source:BaseTexture,dest:RenderTexture,offsetScale?:Vector4,shader?:Shader3D,shaderData?:ShaderData,subShader?:number,definedCanvas?:boolean):void; + + /** + * 添加一条通过全屏四边形将源纹理渲染到目标渲染纹理指令。 + * @param source 源纹理 如果为null,前渲染结果为原纹理 + * @param dest 目标纹理 如果为null,直接渲染到最终画布 + * @param offsetScale 偏移缩放 + * @param material 材质 + * @param subShader shader索引 + */ + blitScreenQuadByMaterial(source:BaseTexture,dest:RenderTexture,offsetScale?:Vector4,material?:Material,subShader?:number):void; + + /** + * 添加一条通过全屏三角形将源纹理渲染到目标渲染纹理指令。 + * @param source 源纹理。 + * @param dest 目标纹理。 + * @param offsetScale 偏移缩放。 + * @param shader 着色器,如果为null使用内部拷贝着色器,不做任何处理。 + * @param shaderData 着色器数据,如果为null只接收sourceTexture。 + * @param subShader subShader索引,默认值为0。 + */ + blitScreenTriangle(source:BaseTexture,dest:RenderTexture,offsetScale?:Vector4,shader?:Shader3D,shaderData?:ShaderData,subShader?:number,defineCanvas?:boolean):void; + + /** + * 设置指令渲染目标 + * @param renderTexture RT渲染目标 + */ + setRenderTarget(renderTexture:RenderTexture):void; + + /** + * clear渲染纹理 + * @param clearColor + * @param clearDepth + * @param backgroundColor + * @param depth + */ + clearRenderTarget(clearColor:boolean,clearDepth:boolean,backgroundColor:Vector4,depth?:number):void; + + /** + * 渲染一个Mesh + * @param mesh 原始网格信息 + * @param matrix 网格世界矩阵 + * @param material 材质 + * @param submeshIndex 子网格索引 如果索引为 + * @param subShaderIndex 子shader索引 一般为0 + */ + drawMesh(mesh:Mesh,matrix:Matrix4x4,material:Material,submeshIndex:number,subShaderIndex:number):void; + + /** + * 渲染一个Render + * @param render 渲染器 + * @param material 材质 + * @param subShaderIndex 子shader索引 一般为0 + */ + drawRender(render:BaseRender,material:Material,subShaderIndex:number):void; + + /** + * 使用instance动态合批的方式渲染一个Mesh + * @param mesh 原始网格信息 + * @param subMeshIndex mesh索引 + * @param matrixs 渲染的世界矩阵数组,用来描述每个Mesh需要渲染的位置,如果为null,将不创建更新世界矩阵Buffer + * @param material 渲染材质 + * @param subShaderIndex 渲染材质shader索引 + * @param instanceProperty Instance自定义属性 + * @param drawnums 渲染个数 + */ + drawMeshInstance(mesh:Mesh,subMeshIndex:number,matrixs:Matrix4x4[],material:Material,subShaderIndex:number,instanceProperty:MaterialInstancePropertyBlock,drawnums:number):any; + } + + /** + * SetShaderDataTextureCMD 类用于创建设置渲染目标指令。 + */ + class DrawMeshInstancedCMD extends Command { + + /** + * 设置最大DrawInstance数 + */ + static maxInstanceCount:number; + + constructor(); + + /** + * @inheritDoc + * @override + */ + run():void; + + /** + * 重置DrawInstance的世界矩阵数组 + * @param worldMatrixArray + */ + setWorldMatrix(worldMatrixArray:Matrix4x4[]):void; + + /** + * 重置渲染个数 + * @param drawNums + */ + setDrawNums(drawNums:number):void; + + /** + * @inheritDoc + * @override + */ + recover():void; + } + +enum InstanceLocation { + CUSTOME0 = 12, + CUSTOME1 = 13, + CUSTOME2 = 14, + CUSTOME3 = 15 +} + + /** + * Mesh 类用于创建CustomInstance属性块。 + */ + class MaterialInstancePropertyBlock { + + /** + * Instance合并方案 + */ + + /** + * attribute instance渲染方案 优点:合并数量多,合并效率高,渲染性能优 缺点:instance变量元素少 + */ + static INSTANCETYPE_ATTRIBUTE:number; + + /** + * uniform instance渲染方案 优点:instance变量多,灵活 缺点:合并数量受WebGLContext._maxUniformFragmentVectors的影响,合并效率低 + */ + static INSTANCETYPE_UNIFORMBUFFER:number; + + constructor(); + + /** + * 创建instance属性 + * @param attributeName name + * @param arrays data + * @param vertexStride vertex size + * @param vertexformat vertexFormat + * @param attributeLocation attribute location + */ + private _creatProperty:any; + + /** + * 设置Vector4材质数组属性 + * @param attributeName 属性名称(要对应到Shader中) + * @param arrays 数据 + * @param attributeLocation 属性Shader位置(需要与shader中的声明Attribute一一对应) + */ + setVectorArray(attributeName:string,arrays:Vector4[]|Float32Array,attributeLocation:InstanceLocation):void; + + /** + * 设置Vector3材质数组属性 + * @param attributeName 属性名称(要对应到Shader中) + * @param arrays 数据 + * @param attributeLocation 属性shader位置(需要与shader中的声明Attribute一一对应) + */ + setVector3Array(attributeName:string,arrays:Vector3[]|Float32Array,attributeLocation:InstanceLocation):void; + + /** + * 设置Vector2材质数组属性 + * @param attributeName 属性名称(要对应到Shader中) + * @param arrays 数据 + * @param attributeLocation 属性shader位置(需要与shader中的声明Attribute一一对应) + */ + setVector2Array(attributeName:string,arrays:Vector2[]|Float32Array,attributeLocation:InstanceLocation):void; + + /** + * 设置Number材质数组属性 + * @param attributeName 属性名称(要对应到Shader中) + * @param arrays 数据 + * @param attributeLocation 属性shader位置(需要与shader中的声明Attribute一一对应) + */ + setNumberArray(attributeName:string,arrays:Float32Array,attributeLocation:InstanceLocation):void; + + /** + * 获得属性数据 + * @param attributeLocation 属性shader位置 + */ + getPropertyArray(attributeLocation:InstanceLocation):Vector4[]|Vector3[]|Vector2[]|Float32Array; + clear():void; + } + +enum ShaderDataType { + /**整数 */ + Int = 0, + /**布尔 */ + Bool = 1, + /**浮点数 */ + Number = 2, + /**2维数结构 */ + Vector2 = 3, + /**3维数结构 */ + Vector3 = 4, + /**4维数结构 */ + Vector4 = 5, + /**四元数 */ + Quaternion = 6, + /**矩阵 */ + Matrix4x4 = 7, + /**数组 */ + Buffer = 8, + /**图片 */ + Texture = 9 +} + + /** + * PostProcessEffect 类用于创建后期处理渲染效果。 + */ + class PostProcessEffect { + + /** + * 创建一个 PostProcessEffect 实例。 + */ + + constructor(); + } + + /** + * * PostProcessRenderContext 类用于创建后期处理渲染上下文。 + */ + class PostProcessRenderContext { + + /** + * 源纹理。 + */ + source:RenderTexture|null; + + /** + * 输出纹理。 + */ + destination:RenderTexture|null; + + /** + * 渲染相机。 + */ + camera:Camera|null; + + /** + * 合成着色器数据。 + */ + compositeShaderData:ShaderData|null; + + /** + * 后期处理指令流。 + */ + command:CommandBuffer|null; + + /** + * 临时纹理数组。 + */ + deferredReleaseTextures:RenderTexture[]; + } + + /** + * RenderContext3D 类用于实现渲染状态。 + */ + class RenderContext3D { + + /** + * 渲染区宽度。 + */ + static clientWidth:number; + + /** + * 渲染区高度。 + */ + static clientHeight:number; + + /** + * 设置渲染管线 + */ + configPipeLineMode:string; + + /** + * 创建一个 RenderContext3D 实例。 + */ + + constructor(); + } + + /** + * RenderElement 类用于实现渲染元素。 + */ + class RenderElement { + + /** + * 创建一个 RenderElement 实例。 + */ + + constructor(); + } + + /** + * ScreenQuad 类用于创建全屏四边形。 + */ + class ScreenQuad extends Resource { + + /** + * 创建一个 ScreenQuad 实例,禁止使用。 + */ + + constructor(); + + /** + * @inheritDoc + * @override + */ + destroy():void; + } + + /** + * ScreenTriangle 类用于创建全屏三角形。 + */ + class ScreenTriangle extends Resource { + + /** + * 创建一个 ScreenTriangle 实例,禁止使用。 + */ + + constructor(); + + /** + * @inheritDoc + * @override + */ + destroy():void; + } + + /** + * RenderableSprite3D 类用于可渲染3D精灵的父类,抽象类不允许实例。 + */ + class RenderableSprite3D extends Sprite3D { + + /** + * 精灵级着色器宏定义,接收阴影。 + */ + static SHADERDEFINE_RECEIVE_SHADOW:ShaderDefine; + + /** + * 精灵级着色器宏定义,光照贴图。 + */ + static SAHDERDEFINE_LIGHTMAP:ShaderDefine; + + /** + * 精灵级着色器宏定义,光照贴图方向。 + */ + static SHADERDEFINE_LIGHTMAP_DIRECTIONAL:ShaderDefine; + + /** + * 着色器变量名,光照贴图缩放和偏移。 + */ + static LIGHTMAPSCALEOFFSET:number; + + /** + * 着色器变量名,光照贴图。 + */ + static LIGHTMAP:number; + + /** + * 着色器变量名,光照贴图方向。 + */ + static LIGHTMAP_DIRECTION:number; + + /** + * 拾取颜色。 + */ + static PICKCOLOR:number; + + /** + * 反射贴图 + */ + static REFLECTIONTEXTURE:number; + + /** + * 反射贴图参数 + */ + static REFLECTIONCUBE_HDR_PARAMS:number; + + /** + * 反射探针位置 最大最小值 + */ + static REFLECTIONCUBE_PROBEPOSITION:number; + static REFLECTIONCUBE_PROBEBOXMAX:number; + static REFLECTIONCUBE_PROBEBOXMIN:number; + pickColor:Vector4; + + /** + * 创建一个 RenderableSprite3D 实例。 + */ + + constructor(name:string); + + /** + * @inheritDoc + * @override + */ + protected _onInActive():void; + + /** + * @inheritDoc + * @override + */ + protected _onActive():void; + + /** + * @inheritDoc + * @override + */ + protected _onActiveInScene():void; + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + } + + /** + * BoundsOctree 类用于创建八叉树。 + */ + class BoundsOctree { + + /** + * 创建一个 BoundsOctree 实例。 + * @param initialWorldSize 八叉树尺寸 + * @param initialWorldPos 八叉树中心 + * @param minNodeSize 节点最小尺寸 + * @param loosenessVal 松散值 + */ + + constructor(initialWorldSize:number,initialWorldPos:Vector3,minNodeSize:number,looseness:number); + + /** + * 添加物体 + * @param object + */ + add(object:IOctreeObject):void; + + /** + * 移除物体 + * @return 是否成功 + */ + remove(object:IOctreeObject):boolean; + + /** + * 更新物体 + */ + update(object:IOctreeObject):boolean; + + /** + * 如果可能则收缩根节点。 + */ + shrinkRootIfPossible():void; + + /** + * 添加运动物体。 + * @param 运动物体 。 + */ + addMotionObject(object:IOctreeObject):void; + + /** + * 移除运动物体。 + * @param 运动物体 。 + */ + removeMotionObject(object:IOctreeObject):void; + + /** + * 更新所有运动物体。 + */ + updateMotionObjects():void; + + /** + * 获取是否与指定包围盒相交。 + * @param checkBound AABB包围盒。 + * @return 是否相交。 + */ + isCollidingWithBoundBox(checkBounds:BoundBox):boolean; + + /** + * 获取是否与指定射线相交。 + * @param ray 射线。 + * @param maxDistance 射线的最大距离。 + * @return 是否相交。 + */ + isCollidingWithRay(ray:Ray,maxDistance?:number):boolean; + + /** + * 获取与指定包围盒相交的物体列表。 + * @param checkBound AABB包围盒。 + * @param result 相交物体列表 + */ + getCollidingWithBoundBox(checkBound:BoundBox,result:any[]):void; + + /** + * 获取与指定射线相交的的物理列表。 + * @param ray 射线。 + * @param result 相交物体列表。 + * @param maxDistance 射线的最大距离。 + */ + getCollidingWithRay(ray:Ray,result:any[],maxDistance?:number):void; + + /** + * 获取与指定视锥相交的的物理列表。 + * @param 渲染上下文 。 + */ + getCollidingWithFrustum(cameraCullInfo:CameraCullInfo,context:RenderContext3D,shader:Shader3D,replacementTag:string,isShadowCasterCull:boolean):void; + + /** + * 获取最大包围盒 + * @return 最大包围盒 + */ + getMaxBounds():BoundBox; + } + + /** + * BoundsOctreeNode 类用于创建八叉树节点。 + */ + class BoundsOctreeNode { + + /** + * 创建一个 BoundsOctreeNode 实例。 + * @param octree 所属八叉树。 + * @param parent 父节点。 + * @param baseLength 节点基本长度。 + * @param center 节点的中心位置。 + */ + + constructor(octree:BoundsOctree,parent:BoundsOctreeNode,baseLength:number,center:Vector3); + private _getCollidingWithCastShadowFrustum:any; + + /** + * 添加指定物体。 + * @param object 指定物体。 + */ + add(object:IOctreeObject):boolean; + + /** + * 移除指定物体。 + * @param obejct 指定物体。 + * @return 是否成功。 + */ + remove(object:IOctreeObject):boolean; + + /** + * 更新制定物体, + * @param obejct 指定物体。 + * @return 是否成功。 + */ + update(object:IOctreeObject):boolean; + + /** + * 收缩八叉树节点。 + * -所有物体都在根节点的八分之一区域 + * -该节点无子节点或有子节点但1/8的子节点不包含物体 + * @param minLength 最小尺寸。 + * @return 新的根节点。 + */ + shrinkIfPossible(minLength:number):BoundsOctreeNode; + + /** + * 检查该节点和其子节点是否包含任意物体。 + * @return 是否包含任意物体。 + */ + hasAnyObjects():boolean; + + /** + * 获取与指定包围盒相交的物体列表。 + * @param checkBound AABB包围盒。 + * @param result 相交物体列表 + */ + getCollidingWithBoundBox(checkBound:BoundBox,result:any[]):void; + + /** + * 获取与指定射线相交的的物理列表。 + * @param ray 射线。 + * @param result 相交物体列表。 + * @param maxDistance 射线的最大距离。 + */ + getCollidingWithRay(ray:Ray,result:any[],maxDistance?:number):void; + + /** + * 获取与指定视锥相交的的物理列表。 + * @param ray 射线。. + * @param result 相交物体列表。 + */ + getCollidingWithFrustum(cameraCullInfo:CameraCullInfo,context:RenderContext3D,customShader:Shader3D,replacementTag:string,isShadowCasterCull:boolean):void; + getCollidingWithCastShadowFrustum(cameraCullInfo:ShadowCullInfo,contect:RenderContext3D):void; + + /** + * 获取是否与指定包围盒相交。 + * @param checkBound AABB包围盒。 + * @return 是否相交。 + */ + isCollidingWithBoundBox(checkBound:BoundBox):boolean; + + /** + * 获取是否与指定射线相交。 + * @param ray 射线。 + * @param maxDistance 射线的最大距离。 + * @return 是否相交。 + */ + isCollidingWithRay(ray:Ray,maxDistance?:number):boolean; + + /** + * 获取包围盒。 + */ + getBound():BoundBox; + } + + interface IOctreeObject{ + + /** + * 获得八叉树节点 + */ + _getOctreeNode():BoundsOctreeNode; + + /** + * 设置八叉树节点 + */ + _setOctreeNode(value:BoundsOctreeNode):void; + + /** + * 获得动态列表中的Index + */ + _getIndexInMotionList():number; + + /** + * 设置动态列表中的Index + */ + _setIndexInMotionList(value:number):void; + + /** + * 包围盒 + */ + bounds:Bounds; + } + + + /** + * 光照贴图。 + */ + class Lightmap { + + /** + * 光照贴图颜色。 + */ + lightmapColor:Texture2D; + + /** + * 光照贴图方向。 + */ + lightmapDirection:Texture2D; + } + + /** + * OctreeMotionList 类用于实现物理更新队列。 + */ + class OctreeMotionList extends SingletonList { + + /** + * 创建一个新的 OctreeMotionList 实例。 + */ + + constructor(); + } + +enum AmbientMode { + /** 固定颜色。*/ + SolidColor = 0, + /** 球谐光照,例如通过天空盒生成的球谐数据。 */ + SphericalHarmonics = 1 +} + + /** + * 用于实现3D场景。 + */ + class Scene3D extends Sprite implements ISubmit,ICreateResource { + + /** + * Hierarchy资源。 + */ + static HIERARCHY:string; + + /** + * 是否开启八叉树裁剪。 + */ + static octreeCulling:boolean; + + /** + * 八叉树初始化尺寸。 + */ + static octreeInitialSize:number; + + /** + * 八叉树初始化中心。 + */ + static octreeInitialCenter:Vector3; + + /** + * 八叉树最小尺寸。 + */ + static octreeMinNodeSize:number; + + /** + * 八叉树松散值。 + */ + static octreeLooseness:number; + static REFLECTIONMODE_SKYBOX:number; + static REFLECTIONMODE_CUSTOM:number; + static SCENERENDERFLAG_RENDERQPAQUE:number; + static SCENERENDERFLAG_SKYBOX:number; + static SCENERENDERFLAG_RENDERTRANSPARENT:number; + + /** + * 加载场景,注意:不缓存。 + * @param url 模板地址。 + * @param complete 完成回调。 + */ + static load(url:string,complete:Handler):void; + + /** + * 当前创建精灵所属遮罩层。 + */ + currentCreationLayer:number; + + /** + * 是否启用灯光。 + */ + enableLight:boolean; + + /** + * 资源的URL地址。 + */ + get url():string; + + /** + * 是否允许雾化。 + */ + get enableFog():boolean; + set enableFog(value:boolean); + + /** + * 雾化颜色。 + */ + get fogColor():Vector3; + set fogColor(value:Vector3); + + /** + * 雾化起始位置。 + */ + get fogStart():number; + set fogStart(value:number); + + /** + * 雾化范围。 + */ + get fogRange():number; + set fogRange(value:number); + + /** + * 环境光模式。 + * 如果值为AmbientMode.SolidColor一般使用ambientColor作为环境光源,如果值为如果值为AmbientMode.SphericalHarmonics一般使用ambientSphericalHarmonics作为环境光源。 + */ + get ambientMode():AmbientMode; + set ambientMode(value:AmbientMode); + + /** + * 固定颜色环境光。 + */ + get ambientColor():Vector3; + set ambientColor(value:Vector3); + + /** + * 球谐环境光,修改后必须重新赋值。 + */ + get ambientSphericalHarmonics():SphericalHarmonicsL2; + set ambientSphericalHarmonics(value:SphericalHarmonicsL2); + + /** + * 环境球谐强度。 + */ + get ambientSphericalHarmonicsIntensity():number; + set ambientSphericalHarmonicsIntensity(value:number); + + /** + * 反射立方体纹理。 + */ + get reflection():TextureCube; + set reflection(value:TextureCube); + + /** + * 反射立方体纹理解码格式。 + */ + get reflectionDecodingFormat():TextureDecodeFormat; + set reflectionDecodingFormat(value:TextureDecodeFormat); + + /** + * 反射强度。 + */ + get reflectionIntensity():number; + set reflectionIntensity(value:number); + + /** + * 天空渲染器。 + */ + get skyRenderer():SkyRenderer; + + /** + * 物理模拟器。 + */ + get physicsSimulation():PhysicsSimulation; + get cannonPhysicsSimulation():CannonPhysicsSimulation; + + /** + * 场景时钟。 + * @override + */ + get timer():Timer; + set timer(value:Timer); + + /** + * 输入。 + */ + get input():Input3D; + + /** + * 光照贴图数组,返回值为浅拷贝数组。 + */ + get lightmaps():Lightmap[]; + set lightmaps(value:Lightmap[]); + + /** + * 创建一个 Scene3D 实例。 + */ + + constructor(); + + /** + * @param url 路径 + */ + _setCreateURL(url:string):void; + + /** + * @inheritDoc + * @override + */ + protected _onActive():void; + + /** + * @inheritDoc + * @override + */ + protected _onInActive():void; + + /** + * @inheritDoc + * @override 删除资源 + */ + destroy(destroyChild?:boolean):void; + + /** + * 渲染入口 + */ + renderSubmit():number; + + /** + * 获得渲染类型 + */ + getRenderType():number; + + /** + * 删除渲染 + */ + releaseRender():void; + + /** + * 设置全局渲染数据 + * @param name 数据对应着色器名字 + * @param shaderDataType 渲染数据类型 + * @param value 渲染数据值 + */ + setGlobalShaderValue(name:string,shaderDataType:ShaderDataType,value:any):void; + + /** + * @deprecated + */ + get customReflection():TextureCube; + set customReflection(value:TextureCube); + + /** + * @deprecated + */ + get reflectionMode():number; + set reflectionMode(value:number); + + /** + * @deprecated 设置光照贴图。 + * @param value 光照贴图。 + */ + setlightmaps(value:Texture2D[]):void; + + /** + * @deprecated 获取光照贴图浅拷贝列表。 + * @return 获取光照贴图浅拷贝列表。 + */ + getlightmaps():Texture2D[]; + } + class SimpleSkinnedMeshRenderer extends SkinnedMeshRenderer { + + /** + * 创建一个 SkinnedMeshRender 实例。 + */ + + constructor(owner:RenderableSprite3D); + + /** + * 删除节点 + */ + _destroy():void; + } + + /** + * SkinnedMeshSprite3D 类用于创建网格。 + */ + class SimpleSkinnedMeshSprite3D extends RenderableSprite3D { + + /** + */ + static SIMPLE_SIMPLEANIMATORTEXTURE:number; + static SIMPLE_SIMPLEANIMATORPARAMS:number; + static SIMPLE_SIMPLEANIMATORTEXTURESIZE:number; + + /** + * 网格过滤器。 + */ + get meshFilter():MeshFilter; + + /** + * 网格渲染器。 + */ + get simpleSkinnedMeshRenderer():SimpleSkinnedMeshRenderer; + + /** + * 创建一个 MeshSprite3D 实例。 + * @param mesh 网格,同时会加载网格所用默认材质。 + * @param name 名字。 + */ + + constructor(mesh?:Mesh,name?:string); + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + } + + /** + * SkinMeshRenderer 类用于蒙皮渲染器。 + */ + class SkinnedMeshRenderer extends MeshRenderer { + + /** + * 局部边界。 + */ + get localBounds():Bounds; + set localBounds(value:Bounds); + + /** + * 根节点。 + */ + get rootBone():Sprite3D; + set rootBone(value:Sprite3D); + + /** + * 用于蒙皮的骨骼。 + */ + get bones():Sprite3D[]; + + /** + * 创建一个 SkinnedMeshRender 实例。 + */ + + constructor(owner:RenderableSprite3D); + + /** + * @override 包围盒。 + */ + get bounds():Bounds; + } + + /** + * SkinnedMeshSprite3D 类用于绑点骨骼节点精灵。 + */ + class SkinnedMeshSprite3D extends RenderableSprite3D { + + /** + * 着色器变量名,蒙皮动画。 + */ + static BONES:number; + + /** + * 简单动画变量名,贴图蒙皮动画 + */ + static SIMPLE_SIMPLEANIMATORTEXTURE:number; + static SIMPLE_SIMPLEANIMATORPARAMS:number; + static SIMPLE_SIMPLEANIMATORTEXTURESIZE:number; + + /** + * 网格过滤器。 + */ + get meshFilter():MeshFilter; + + /** + * 网格渲染器。 + */ + get skinnedMeshRenderer():SkinnedMeshRenderer; + + /** + * 创建一个 MeshSprite3D 实例。 + * @param mesh 网格,同时会加载网格所用默认材质。 + * @param name 名字。 + */ + + constructor(mesh?:Mesh,name?:string); + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + } + class SkinnedMeshSprite3DShaderDeclaration { + + /** + * 精灵级着色器宏定义,蒙皮动画。 + */ + static SHADERDEFINE_BONE:ShaderDefine; + static SHADERDEFINE_SIMPLEBONE:ShaderDefine; + } + + /** + * Sprite3D 类用于实现3D精灵。 + */ + class Sprite3D extends Node implements ICreateResource { + + /** + * Hierarchy资源。 + */ + static HIERARCHY:string; + + /** + * 创建精灵的克隆实例。 + * @param original 原始精灵。 + * @param parent 父节点。 + * @param worldPositionStays 是否保持自身世界变换。 + * @param position 世界位置,worldPositionStays为false时生效。 + * @param rotation 世界旋转,worldPositionStays为false时生效。 + * @return 克隆实例。 + */ + static instantiate(original:Sprite3D,parent?:Node,worldPositionStays?:boolean,position?:Vector3,rotation?:Quaternion):Sprite3D; + + /** + * 加载网格模板。 + * @param url 模板地址。 + * @param complete 完成回掉。 + */ + static load(url:string,complete:Handler):void; + + /** + * 唯一标识ID。 + */ + get id():number; + + /** + * 蒙版层。 + */ + get layer():number; + set layer(value:number); + + /** + * 资源的URL地址。 + */ + get url():string; + + /** + * 是否为静态。 + */ + get isStatic():boolean; + + /** + * 精灵变换。 + */ + get transform():Transform3D; + + /** + * 创建一个 Sprite3D 实例。 + * @param name 精灵名称。 + * @param isStatic 是否为静态。 + */ + + constructor(name?:string,isStatic?:boolean); + + /** + */ + _setCreateURL(url:string):void; + + /** + * @private + */ + protected _onInActiveInScene():void; + + /** + * @inheritDoc + * @override + */ + protected _onAdded():void; + + /** + * @inheritDoc + * @override + */ + protected _onRemoved():void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():Node; + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + } + class TextureMode { + + /** + * 拉伸模式。 + */ + static Stretch:number; + + /** + * 平铺模式。 + */ + static Tile:number; + } + +enum TrailAlignment { + /** 使拖尾面向摄像机。*/ + View = 0, + /** 使拖尾的与组件的方向对齐*/ + TransformZ = 1 +} + + /** + * TrailFilter 类用于创建拖尾过滤器。 + */ + class TrailFilter { + static CURTIME:number; + static LIFETIME:number; + static WIDTHCURVE:number; + static WIDTHCURVEKEYLENGTH:number; + _owner:TrailSprite3D; + _lastPosition:Vector3; + _curtime:number; + + /** + * 轨迹准线。 + */ + alignment:number; + + /** + * 获取淡出时间。 + * @return 淡出时间。 + */ + get time():number; + + /** + * 设置淡出时间。 + * @param value 淡出时间。 + */ + set time(value:number); + + /** + * 获取新旧顶点之间最小距离。 + * @return 新旧顶点之间最小距离。 + */ + get minVertexDistance():number; + + /** + * 设置新旧顶点之间最小距离。 + * @param value 新旧顶点之间最小距离。 + */ + set minVertexDistance(value:number); + + /** + * 获取宽度倍数。 + * @return 宽度倍数。 + */ + get widthMultiplier():number; + + /** + * 设置宽度倍数。 + * @param value 宽度倍数。 + */ + set widthMultiplier(value:number); + + /** + * 获取宽度曲线。 + * @return 宽度曲线。 + */ + get widthCurve():FloatKeyframe[]; + + /** + * 设置宽度曲线。最多10个 + * @param value 宽度曲线。 + */ + set widthCurve(value:FloatKeyframe[]); + + /** + * 获取颜色梯度。 + * @return 颜色梯度。 + */ + get colorGradient():Gradient; + + /** + * 设置颜色梯度。 + * @param value 颜色梯度。 + */ + set colorGradient(value:Gradient); + + /** + * 获取纹理模式。 + * @return 纹理模式。 + */ + get textureMode():number; + + /** + * 设置纹理模式。 + * @param value 纹理模式。 + */ + set textureMode(value:number); + + constructor(owner:TrailSprite3D); + clear():void; + + /** + * 轨迹准线_面向摄像机。 + */ + static ALIGNMENT_VIEW:number; + + /** + * 轨迹准线_面向运动方向。 + */ + static ALIGNMENT_TRANSFORM_Z:number; + } + + /** + * TrailGeometry 类用于创建拖尾渲染单元。 + */ + class TrailGeometry extends GeometryElement { + + /** + * 轨迹准线_面向摄像机。 + */ + static ALIGNMENT_VIEW:number; + + /** + * 轨迹准线_面向运动方向。 + */ + static ALIGNMENT_TRANSFORM_Z:number; + private tmpColor:any; + + /** + * @private + */ + private _disappearBoundsMode:any; + + constructor(owner:TrailFilter); + + /** + * @inheritDoc + * @override + */ + _getType():number; + + /** + * @inheritDoc + * @override + */ + destroy():void; + clear():void; + } + + /** + * TrailMaterial 类用于实现拖尾材质。 + */ + class TrailMaterial extends Material { + + /** + * 渲染状态_透明混合。 + */ + static RENDERMODE_ALPHABLENDED:number; + + /** + * 渲染状态_加色法混合。 + */ + static RENDERMODE_ADDTIVE:number; + + /** + * 默认材质,禁止修改 + */ + static defaultMaterial:TrailMaterial; + static SHADERDEFINE_MAINTEXTURE:ShaderDefine; + static SHADERDEFINE_ADDTIVEFOG:ShaderDefine; + static MAINTEXTURE:number; + static TINTCOLOR:number; + static TILINGOFFSET:number; + + /** + * 设置渲染模式。 + * @return 渲染模式。 + */ + set renderMode(value:number); + + /** + * 获取颜色R分量。 + * @return 颜色R分量。 + */ + get colorR():number; + + /** + * 设置颜色R分量。 + * @param value 颜色R分量。 + */ + set colorR(value:number); + + /** + * 获取颜色G分量。 + * @return 颜色G分量。 + */ + get colorG():number; + + /** + * 设置颜色G分量。 + * @param value 颜色G分量。 + */ + set colorG(value:number); + + /** + * 获取颜色B分量。 + * @return 颜色B分量。 + */ + get colorB():number; + + /** + * 设置颜色B分量。 + * @param value 颜色B分量。 + */ + set colorB(value:number); + + /** + * 获取颜色Z分量。 + * @return 颜色Z分量。 + */ + get colorA():number; + + /** + * 设置颜色alpha分量。 + * @param value 颜色alpha分量。 + */ + set colorA(value:number); + + /** + * 获取颜色。 + * @return 颜色。 + */ + get color():Vector4; + + /** + * 设置颜色。 + * @param value 颜色。 + */ + set color(value:Vector4); + + /** + * 获取贴图。 + * @return 贴图。 + */ + get texture():BaseTexture; + + /** + * 设置贴图。 + * @param value 贴图。 + */ + set texture(value:BaseTexture); + + /** + * 获取纹理平铺和偏移X分量。 + * @return 纹理平铺和偏移X分量。 + */ + get tilingOffsetX():number; + + /** + * 获取纹理平铺和偏移X分量。 + * @param x 纹理平铺和偏移X分量。 + */ + set tilingOffsetX(x:number); + + /** + * 获取纹理平铺和偏移Y分量。 + * @return 纹理平铺和偏移Y分量。 + */ + get tilingOffsetY():number; + + /** + * 获取纹理平铺和偏移Y分量。 + * @param y 纹理平铺和偏移Y分量。 + */ + set tilingOffsetY(y:number); + + /** + * 获取纹理平铺和偏移Z分量。 + * @return 纹理平铺和偏移Z分量。 + */ + get tilingOffsetZ():number; + + /** + * 获取纹理平铺和偏移Z分量。 + * @param z 纹理平铺和偏移Z分量。 + */ + set tilingOffsetZ(z:number); + + /** + * 获取纹理平铺和偏移W分量。 + * @return 纹理平铺和偏移W分量。 + */ + get tilingOffsetW():number; + + /** + * 获取纹理平铺和偏移W分量。 + * @param w 纹理平铺和偏移W分量。 + */ + set tilingOffsetW(w:number); + + /** + * 获取纹理平铺和偏移。 + * @return 纹理平铺和偏移。 + */ + get tilingOffset():Vector4; + + /** + * 设置纹理平铺和偏移。 + * @param value 纹理平铺和偏移。 + */ + set tilingOffset(value:Vector4); + + constructor(); + + /** + * @inheritdoc + * @override + */ + clone():any; + } + + /** + * TrailRenderer 类用于创建拖尾渲染器。 + */ + class TrailRenderer extends BaseRender { + + constructor(owner:TrailSprite3D); + protected _projectionViewWorldMatrix:Matrix4x4; + } + + /** + * TrailSprite3D 类用于创建拖尾渲染精灵。 + */ + class TrailSprite3D extends RenderableSprite3D { + + /** + * Trail过滤器。 + */ + get trailFilter():TrailFilter; + + /** + * Trail渲染器。 + */ + get trailRenderer():TrailRenderer; + + constructor(name?:string); + + /** + * @inheritDoc + * @override + */ + protected _onActive():void; + + /** + *

销毁此对象。

+ * @param destroyChild 是否同时销毁子节点,若值为true,则销毁子节点,否则不销毁子节点。 + * @override + */ + destroy(destroyChild?:boolean):void; + clear():void; + } + + /** + * VertexTrail 类用于创建拖尾顶点结构。 + */ + class VertexTrail implements IVertex { + static TRAIL_POSITION0:number; + static TRAIL_OFFSETVECTOR:number; + static TRAIL_TIME0:number; + static TRAIL_TEXTURECOORDINATE0Y:number; + static TRAIL_TEXTURECOORDINATE0X:number; + static TRAIL_COLOR:number; + static get vertexDeclaration1():VertexDeclaration; + static get vertexDeclaration2():VertexDeclaration; + get vertexDeclaration():VertexDeclaration; + } + + /** + * Transform3D 类用于实现3D变换。 + */ + class Transform3D extends EventDispatcher { + + /** + * 所属精灵。 + */ + get owner():Sprite3D; + + /** + * 世界矩阵是否需要更新。 + */ + get worldNeedUpdate():boolean; + + /** + * 局部位置X轴分量。 + */ + get localPositionX():number; + set localPositionX(x:number); + + /** + * 局部位置Y轴分量。 + */ + get localPositionY():number; + set localPositionY(y:number); + + /** + * 局部位置Z轴分量。 + */ + get localPositionZ():number; + set localPositionZ(z:number); + + /** + * 局部位置。 + */ + get localPosition():Vector3; + set localPosition(value:Vector3); + + /** + * 局部旋转四元数X分量。 + */ + get localRotationX():number; + set localRotationX(x:number); + + /** + * 局部旋转四元数Y分量。 + */ + get localRotationY():number; + set localRotationY(y:number); + + /** + * 局部旋转四元数Z分量。 + */ + get localRotationZ():number; + set localRotationZ(z:number); + + /** + * 局部旋转四元数W分量。 + */ + get localRotationW():number; + set localRotationW(w:number); + + /** + * 局部旋转。 + */ + get localRotation():Quaternion; + set localRotation(value:Quaternion); + + /** + * 局部缩放X。 + */ + get localScaleX():number; + set localScaleX(value:number); + + /** + * 局部缩放Y。 + */ + get localScaleY():number; + set localScaleY(value:number); + + /** + * 局部缩放Z。 + */ + get localScaleZ():number; + set localScaleZ(value:number); + + /** + * 局部缩放。 + */ + get localScale():Vector3; + set localScale(value:Vector3); + + /** + * 局部空间的X轴欧拉角。 + */ + get localRotationEulerX():number; + set localRotationEulerX(value:number); + + /** + * 局部空间的Y轴欧拉角。 + */ + get localRotationEulerY():number; + set localRotationEulerY(value:number); + + /** + * 局部空间的Z轴欧拉角。 + */ + get localRotationEulerZ():number; + set localRotationEulerZ(value:number); + + /** + * 局部空间欧拉角。 + */ + get localRotationEuler():Vector3; + set localRotationEuler(value:Vector3); + + /** + * 局部矩阵。 + */ + get localMatrix():Matrix4x4; + set localMatrix(value:Matrix4x4); + + /** + * 世界位置。 + */ + get position():Vector3; + set position(value:Vector3); + + /** + * 世界旋转。 + */ + get rotation():Quaternion; + set rotation(value:Quaternion); + + /** + * 世界空间的旋转角度,顺序为x、y、z。 + */ + get rotationEuler():Vector3; + set rotationEuler(value:Vector3); + + /** + * 世界矩阵。 + */ + get worldMatrix():Matrix4x4; + set worldMatrix(value:Matrix4x4); + + /** + * 创建一个 Transform3D 实例。 + * @param owner 所属精灵。 + */ + + constructor(owner:Sprite3D); + + /** + * 平移变换。 + * @param translation 移动距离。 + * @param isLocal 是否局部空间。 + */ + translate(translation:Vector3,isLocal?:boolean):void; + + /** + * 旋转变换。 + * @param rotations 旋转幅度。 + * @param isLocal 是否局部空间。 + * @param isRadian 是否弧度制。 + */ + rotate(rotation:Vector3,isLocal?:boolean,isRadian?:boolean):void; + + /** + * 获取向前方向。 + * @param forward 前方向。 + */ + getForward(forward:Vector3):void; + + /** + * 获取向上方向。 + * @param up 上方向。 + */ + getUp(up:Vector3):void; + + /** + * 获取向右方向。 + * @param 右方向 。 + */ + getRight(right:Vector3):void; + + /** + * 观察目标位置。 + * @param target 观察目标。 + * @param up 向上向量。 + * @param isLocal 是否局部空间。 + */ + lookAt(target:Vector3,up:Vector3,isLocal?:boolean):void; + + /** + * 世界缩放。 + * 某种条件下获取该值可能不正确(例如:父节点有缩放,子节点有旋转),缩放会倾斜,无法使用Vector3正确表示,必须使用Matrix3x3矩阵才能正确表示。 + * @return 世界缩放。 + */ + getWorldLossyScale():Vector3; + + /** + * 设置世界缩放。 + * 某种条件下设置该值可能不正确(例如:父节点有缩放,子节点有旋转),缩放会倾斜,无法使用Vector3正确表示,必须使用Matrix3x3矩阵才能正确表示。 + * @return 世界缩放。 + */ + setWorldLossyScale(value:Vector3):void; + + /** + * @deprecated + */ + get scale():Vector3; + + /** + * @deprecated + */ + set scale(value:Vector3); + } + + /** + * Vector3Keyframe 类用于创建三维向量关键帧实例。 + */ + class Vector3Keyframe extends Keyframe { + inTangent:Vector3; + outTangent:Vector3; + value:Vector3; + + /** + * 创建一个 Vector3Keyframe 实例。 + */ + + constructor(); + + /** + * 克隆。 + * @param destObject 克隆源。 + * @override + */ + cloneTo(dest:any):void; + } + +enum DepthTextureMode { + /**不生成深度贴图 */ + None = 0, + /**生成深度贴图 */ + Depth = 1, + /**生成深度+法线贴图 */ + DepthNormals = 2, + /**是否应渲染运动矢量 TODO*/ + MotionVectors = 4 +} + + /** + * ShadowCasterPass 类用于实现阴影渲染管线 + */ + class DepthPass { + private static SHADOW_BIAS:any; + + constructor(); + + /** + * 渲染深度更新 + * @param camera + * @param depthType + */ + update(camera:Camera,depthType:DepthTextureMode):void; + + /** + * 渲染深度帧缓存 + * @param context + * @param depthType + */ + render(context:RenderContext3D,depthType:DepthTextureMode):void; + } + + /** + * camera裁剪数据 + */ + class CameraCullInfo { + + /** + * 位置 + */ + position:Vector3; + + /** + * 是否遮挡剔除 + */ + useOcclusionCulling:Boolean; + + /** + * 锥体包围盒 + */ + boundFrustum:BoundFrustum; + + /** + * 遮挡标记 + */ + cullingMask:number; + } + + /** + * 阴影裁剪数据 + */ + class ShadowCullInfo { + position:Vector3; + cullPlanes:Plane[]; + cullSphere:BoundSphere; + cullPlaneCount:number; + direction:Vector3; + } + + /** + * IndexBuffer3D 类用于创建索引缓冲。 + */ + class IndexBuffer3D extends Buffer { + + /** + * 索引类型。 + */ + get indexType():IndexFormat; + + /** + * 索引类型字节数量。 + */ + get indexTypeByteCount():number; + + /** + * 索引个数。 + */ + get indexCount():number; + + /** + * 是否可读。 + */ + get canRead():boolean; + + /** + * 创建一个 IndexBuffer3D,不建议开发者使用并用IndexBuffer3D.create()代替 实例。 + * @param indexType 索引类型。 + * @param indexCount 索引个数。 + * @param bufferUsage IndexBuffer3D用途类型。 + * @param canRead 是否可读。 + */ + + constructor(indexType:IndexFormat,indexCount:number,bufferUsage?:number,canRead?:boolean); + + /** + * @inheritDoc + * @override + */ + _bindForVAO():void; + + /** + * @inheritDoc + * @override + */ + bind():boolean; + + /** + * 设置数据。 + * @param data 索引数据。 + * @param bufferOffset 索引缓冲中的偏移。 + * @param dataStartIndex 索引数据的偏移。 + * @param dataCount 索引数据的数量。 + */ + setData(data:any,bufferOffset?:number,dataStartIndex?:number,dataCount?:number):void; + + /** + * 获取索引数据。 + * @return 索引数据。 + */ + getData():Uint16Array; + + /** + * @inheritDoc + * @override + */ + destroy():void; + } + +enum IndexFormat { + /** 8 位无符号整型索引格式。*/ + UInt8 = 0, + /** 16 位无符号整型索引格式。*/ + UInt16 = 1, + /** 32 位无符号整型索引格式。*/ + UInt32 = 2 +} + + interface IVertex{ + + /** + * 顶点声明 + */ + vertexDeclaration:VertexDeclaration; + } + + + /** + * 二阶球谐函数。 + */ + class SphericalHarmonicsL2 { + + /** + * 获取颜色通道的系数。 + * @param i 通道索引,范围0到2。 + * @param j 系数索引,范围0到8。 + */ + getCoefficient(i:number,j:number):number; + + /** + * 设置颜色通道的系数。 + * @param i 通道索引,范围0到2。 + * @param j 系数索引,范围0到8。 + */ + setCoefficient(i:number,j:number,coefficient:number):void; + + /** + * 设置颜色通道的系数。 + * @param i 通道索引,范围0到2。 + * @param coefficient0 系数0 + * @param coefficient1 系数1 + * @param coefficient2 系数2 + * @param coefficient3 系数3 + * @param coefficient4 系数4 + * @param coefficient5 系数5 + * @param coefficient6 系数6 + * @param coefficient7 系数7 + * @param coefficient8 系数8 + */ + setCoefficients(i:number,coefficient0:number,coefficient1:number,coefficient2:number,coefficient3:number,coefficient4:number,coefficient5:number,coefficient6:number,coefficient7:number,coefficient8:number):void; + + /** + * 克隆 + * @param dest + */ + cloneTo(dest:SphericalHarmonicsL2):void; + } + + /** + * StaticBatchManager 类用于静态批处理管理的父类。 + */ + class StaticBatchManager { + + /** + * 静态批处理合并,合并后子节点修改Transform属性无效,根节点staticBatchRoot可为null,如果根节点不为null,根节点可移动。 + * 如果renderableSprite3Ds为null,合并staticBatchRoot以及其所有子节点为静态批处理,staticBatchRoot作为静态根节点。 + * 如果renderableSprite3Ds不为null,合并renderableSprite3Ds为静态批处理,staticBatchRoot作为静态根节点。 + * @param staticBatchRoot 静态批处理根节点。 + * @param renderableSprite3Ds 静态批处理子节点队列。 + */ + static combine(staticBatchRoot:Sprite3D,renderableSprite3Ds?:RenderableSprite3D[]):void; + + /** + * 创建一个 StaticBatchManager 实例。 + */ + + constructor(); + } + + /** + * ... + * @author ... + */ + class VertexMesh { + + /** + * 顶点位置数据 + */ + static MESH_POSITION0:number; + + /** + * 顶点顶点色数据 + */ + static MESH_COLOR0:number; + + /** + * 顶点UV0数据 + */ + static MESH_TEXTURECOORDINATE0:number; + + /** + * 顶点法线数据 + */ + static MESH_NORMAL0:number; + + /** + * 顶点切线数据 + */ + static MESH_TANGENT0:number; + + /** + * 顶点骨骼索引数据 + */ + static MESH_BLENDINDICES0:number; + + /** + * 顶点骨骼权重数据 + */ + static MESH_BLENDWEIGHT0:number; + + /** + * 顶点UV1数据 + */ + static MESH_TEXTURECOORDINATE1:number; + + /** + * 顶点世界矩阵数据Row0 + */ + static MESH_WORLDMATRIX_ROW0:number; + + /** + * 顶点世界矩阵数据Row1 + */ + static MESH_WORLDMATRIX_ROW1:number; + + /** + * 顶点世界矩阵数据Row2 + */ + static MESH_WORLDMATRIX_ROW2:number; + + /** + * 顶点世界矩阵数据Row3 + */ + static MESH_WORLDMATRIX_ROW3:number; + + /** + * 简单数据动画数据 + */ + static MESH_SIMPLEANIMATOR:number; + + /** + * instanceworld顶点描述 + */ + static instanceWorldMatrixDeclaration:VertexDeclaration; + + /** + * instanceSimple动画数据顶点描述 + */ + static instanceSimpleAnimatorDeclaration:VertexDeclaration; + + /** + * 自定义attribute instance 预留位 + */ + + /** + * 顶点自定义数据0 + */ + static MESH_CUSTOME0:number; + + /** + * 顶点自定义数据1 + */ + static MESH_CUSTOME1:number; + + /** + * 顶点自定义数据2 + */ + static MESH_CUSTOME2:number; + + /** + * 顶点自定义数据3 + */ + static MESH_CUSTOME3:number; + + /** + * 获取顶点声明。 + * @param vertexFlag 顶点声明标记字符,格式为:"POSITION,NORMAL,COLOR,UV,UV1,BLENDWEIGHT,BLENDINDICES,TANGENT"。 + * @return 顶点声明。 + */ + static getVertexDeclaration(vertexFlag:string,compatible?:boolean):VertexDeclaration; + } + + /** + * VertexBuffer3D 类用于创建顶点缓冲。 + */ + class VertexBuffer3D extends Buffer { + + /** + * 数据类型_Float32Array类型。 + */ + static DATATYPE_FLOAT32ARRAY:number; + + /** + * 数据类型_Uint8Array类型。 + */ + static DATATYPE_UINT8ARRAY:number; + + /** + * 获取顶点声明。 + */ + get vertexDeclaration():VertexDeclaration|null; + set vertexDeclaration(value:VertexDeclaration|null); + + /** + * 是否可读。 + */ + get canRead():boolean; + + /** + * 创建一个 VertexBuffer3D 实例。 + * @param byteLength 字节长度。 + * @param bufferUsage VertexBuffer3D用途类型。 + * @param canRead 是否可读。 + */ + + constructor(byteLength:number,bufferUsage:number,canRead?:boolean); + + /** + * @inheritDoc + * @override + */ + bind():boolean; + + /** + * 剥离内存块存储。 + */ + orphanStorage():void; + + /** + * 设置数据。 + * @param data 顶点数据。 + * @param bufferOffset 顶点缓冲中的偏移,以字节为单位。 + * @param dataStartIndex 顶点数据的偏移,以字节为单位。 + * @param dataCount 顶点数据的长度,以字节为单位。 + */ + setData(buffer:ArrayBuffer,bufferOffset?:number,dataStartIndex?:number,dataCount?:number):void; + + /** + * 获取顶点数据。 + * @return 顶点数据。 + */ + getUint8Data():Uint8Array; + + /** + * @ignore + */ + getFloat32Data():Float32Array|null; + + /** + * @ignore + */ + markAsUnreadbale():void; + + /** + * @inheritDoc + * @override + */ + destroy():void; + } + + /** + * VertexDeclaration 类用于生成顶点声明。 + */ + class VertexDeclaration { + + /** + * 获取唯一标识ID(通常用于优化或识别)。 + * @return 唯一标识ID + */ + get id():number; + + /** + * 顶点跨度,以字节为单位。 + */ + get vertexStride():number; + + /** + * 顶点元素的数量。 + */ + get vertexElementCount():number; + + /** + * 创建一个 VertexDeclaration 实例。 + * @param vertexStride 顶点跨度。 + * @param vertexElements 顶点元素集合。 + */ + + constructor(vertexStride:number,vertexElements:Array); + + /** + * 通过索引获取顶点元素。 + * @param index 索引。 + */ + getVertexElementByIndex(index:number):VertexElement; + } + + /** + * VertexElement 类用于创建顶点结构分配。 + */ + class VertexElement { + + /** + * 顶点偏移 + */ + get offset():number; + + /** + * 顶点信息名称 + */ + get elementFormat():string; + + /** + * 顶点宏标记 + */ + get elementUsage():number; + + /** + * 创建顶点结构分配实例 + * @param offset 顶点偏移 + * @param elementFormat 顶点数据格式名称 + * @param elementUsage 顶点宏标记 + */ + + constructor(offset:number,elementFormat:string,elementUsage:number); + } + + /** + * 类用来定义顶点元素格式 + */ + class VertexElementFormat { + + /** + * 单精度浮点数 + */ + static Single:string; + + /** + * vec2 数据 + */ + static Vector2:string; + + /** + * vec3 数据 + */ + static Vector3:string; + + /** + * vec4 数据 + */ + static Vector4:string; + + /** + * 颜色 + */ + static Color:string; + + /** + * 字节数组4 + */ + static Byte4:string; + + /** + * 字节数组3 + */ + static Byte3:string; + + /** + * 字节数组2 + */ + static Byte2:string; + + /** + * 字节数组1 + */ + static ByteOne:string; + + /** + * 半精度浮点数数组2 + */ + static Short2:string; + + /** + * 半精度浮点数数组4 + */ + static Short4:string; + + /** + * 归一化半精度浮点数组2 + */ + static NormalizedShort2:string; + + /** + * 归一化半精度浮点数组4 + */ + static NormalizedShort4:string; + + /** + * 获取顶点元素格式信息。 + * @param element 元素名称 + * @returns 返回顶点元素信息 + */ + static getElementInfos(element:string):any[]; + } + + /** + * Input3D 类用于实现3D输入。 + */ + class Input3D { + + /** + * 获取触摸点个数。 + * @return 触摸点个数。 + */ + touchCount():number; + + /** + * 获取是否可以使用多点触摸。 + * @return 是否可以使用多点触摸。 + */ + get multiTouchEnabled():boolean; + + /** + * 设置是否可以使用多点触摸。 + * @param 是否可以使用多点触摸 。 + */ + set multiTouchEnabled(value:boolean); + + /** + * 获取触摸点。 + * @param index 索引。 + * @return 触摸点。 + */ + getTouch(index:number):Touch; + } + + /** + * BoundBox 类用于创建包围盒。 + */ + class BoundBox implements IClone { + + /** + * 最小顶点。 + */ + min:Vector3; + + /** + * 最大顶点。 + */ + max:Vector3; + + /** + * 创建一个 BoundBox 实例。 + * @param min 包围盒的最小顶点。 + * @param max 包围盒的最大顶点。 + */ + + constructor(min:Vector3,max:Vector3); + + /** + * 获取包围盒的8个角顶点。 + * @param corners 返回顶点的输出队列。 + */ + getCorners(corners:Vector3[]):void; + + /** + * 获取中心点。 + * @param out + */ + getCenter(out:Vector3):void; + + /** + * 获取范围。 + * @param out + */ + getExtent(out:Vector3):void; + + /** + * 设置中心点和范围。 + * @param center + */ + setCenterAndExtent(center:Vector3,extent:Vector3):void; + toDefault():void; + + /** + * 从顶点生成包围盒。 + * @param points 所需顶点队列。 + * @param out 生成的包围盒。 + */ + static createfromPoints(points:Vector3[],out:BoundBox):void; + + /** + * 合并两个包围盒。 + * @param box1 包围盒1。 + * @param box2 包围盒2。 + * @param out 生成的包围盒。 + */ + static merge(box1:BoundBox,box2:BoundBox,out:BoundBox):void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * BoundFrustum 类用于创建锥截体。 + */ + class BoundFrustum { + + /** + * 根据矩阵获取6个包围平面。 + * @param m 描述矩阵。 + * @param np 近平面。 + * @param fp 远平面。 + * @param lp 左平面。 + * @param rp 右平面。 + * @param tp 顶平面。 + * @param bp 底平面。 + */ + static getPlanesFromMatrix(m:Matrix4x4,np:Plane,fp:Plane,lp:Plane,rp:Plane,tp:Plane,bp:Plane):void; + + /** + * 创建一个 BoundFrustum 实例。 + * @param matrix 锥截体的描述4x4矩阵。 + */ + + constructor(matrix:Matrix4x4); + + /** + * 描述矩阵。 + */ + get matrix():Matrix4x4; + set matrix(matrix:Matrix4x4); + + /** + * 近平面。 + */ + get near():Plane; + + /** + * 远平面。 + */ + get far():Plane; + + /** + * 左平面。 + */ + get left():Plane; + + /** + * 右平面。 + */ + get right():Plane; + + /** + * 顶平面。 + */ + get top():Plane; + + /** + * 底平面。 + */ + get bottom():Plane; + + /** + * 判断是否与其他锥截体相等。 + * @param other 锥截体。 + */ + equalsBoundFrustum(other:BoundFrustum):boolean; + + /** + * 判断是否与其他对象相等。 + * @param obj 对象。 + */ + equalsObj(obj:any):boolean; + + /** + * 获取锥截体的任意一平面。 + * 0:近平面 + * 1:远平面 + * 2:左平面 + * 3:右平面 + * 4:顶平面 + * 5:底平面 + * @param index 索引。 + */ + getPlane(index:number):Plane; + + /** + * 锥截体三个相交平面的交点。 + * @param p1 平面1。 + * @param p2 平面2。 + * @param p3 平面3。 + */ + static get3PlaneInterPoint(p1:Plane,p2:Plane,p3:Plane,out:Vector3):void; + + /** + * 锥截体的8个顶点。 + * @param corners 返回顶点的输出队列。 + */ + getCorners(corners:Vector3[]):void; + + /** + * 与点的关系。 + * @param point 点。 + * @returns 包涵:1,相交:2,不相交:0 + */ + containsPoint(point:Vector3):number; + + /** + * 是否与包围盒交叉。 + * @param box 包围盒。 + * @returns boolean 是否相交 + */ + intersects(box:BoundBox):boolean; + + /** + * 与包围盒的位置关系。 + * @param box 包围盒。 + * @returns 包涵:1,相交:2,不相交:0 + */ + containsBoundBox(box:BoundBox):number; + + /** + * 与包围球的位置关系 + * @param sphere 包围球。 + * @returns 包涵:1,相交:2,不相交:0 + */ + containsBoundSphere(sphere:BoundSphere):number; + } + + /** + * BoundSphere 类用于创建包围球。 + */ + class BoundSphere implements IClone { + private static _tempVector3:any; + + /** + * 包围球的中心。 + */ + center:Vector3; + + /** + * 包围球的半径。 + */ + radius:number; + + /** + * 创建一个 BoundSphere 实例。 + * @param center 包围球的中心。 + * @param radius 包围球的半径。 + */ + + constructor(center:Vector3,radius:number); + toDefault():void; + + /** + * 从顶点的子队列生成包围球。 + * @param points 顶点的队列。 + * @param start 顶点子队列的起始偏移。 + * @param count 顶点子队列的顶点数。 + * @param result 生成的包围球。 + */ + static createFromSubPoints(points:Vector3[],start:number,count:number,out:BoundSphere):void; + + /** + * 从顶点队列生成包围球。 + * @param points 顶点的队列。 + * @param result 生成的包围球。 + */ + static createfromPoints(points:Vector3[],out:BoundSphere):void; + + /** + * 判断射线是否与碰撞球交叉,并返回交叉距离。 + * @param ray 射线。 + * @return 距离交叉点的距离,-1表示不交叉。 + */ + intersectsRayDistance(ray:Ray):number; + + /** + * 判断射线是否与碰撞球交叉,并返回交叉点。 + * @param ray 射线。 + * @param outPoint 交叉点。 + * @return 距离交叉点的距离,-1表示不交叉。 + */ + intersectsRayPoint(ray:Ray,outPoint:Vector3):number; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * Collision 类用于检测碰撞。 + */ + class CollisionUtils { + + /** + * 创建一个 Collision 实例。 + */ + + constructor(); + + /** + * 空间中点到平面的距离 + * @param plane 平面 + * @param point 点 + */ + static distancePlaneToPoint(plane:Plane,point:Vector3):number; + + /** + * 空间中点到包围盒的距离 + * @param box 包围盒 + * @param point 点 + */ + static distanceBoxToPoint(box:BoundBox,point:Vector3):number; + + /** + * 空间中包围盒到包围盒的距离 + * @param box1 包围盒1 + * @param box2 包围盒2 + */ + static distanceBoxToBox(box1:BoundBox,box2:BoundBox):number; + + /** + * 空间中点到包围球的距离 + * @param sphere 包围球 + * @param point 点 + */ + static distanceSphereToPoint(sphere:BoundSphere,point:Vector3):number; + + /** + * 空间中包围球到包围球的距离 + * @param sphere1 包围球1 + * @param sphere2 包围球2 + */ + static distanceSphereToSphere(sphere1:BoundSphere,sphere2:BoundSphere):number; + + /** + * 空间中射线和三角面是否相交,输出距离 + * @param ray 射线 + * @param vertex1 三角面顶点1 + * @param vertex2 三角面顶点2 + * @param vertex3 三角面顶点3 + * @param out 点和三角面的距离 + * @return 是否相交 + */ + static intersectsRayAndTriangleRD(ray:Ray,vertex1:Vector3,vertex2:Vector3,vertex3:Vector3,out:number):boolean; + + /** + * 空间中射线和三角面是否相交,输出相交点 + * @param ray 射线 + * @param vertex1 三角面顶点1 + * @param vertex2 三角面顶点2 + * @param vertex3 三角面顶点3 + * @param out 相交点 + * @return 是否相交 + */ + static intersectsRayAndTriangleRP(ray:Ray,vertex1:Vector3,vertex2:Vector3,vertex3:Vector3,out:Vector3):boolean; + + /** + * 空间中射线和点是否相交 + * @param sphere1 包围球1 + * @param sphere2 包围球2 + */ + static intersectsRayAndPoint(ray:Ray,point:Vector3):boolean; + + /** + * 空间中射线和射线是否相交 + * @param ray1 射线1 + * @param ray2 射线2 + * @param out 相交点 + */ + static intersectsRayAndRay(ray1:Ray,ray2:Ray,out:Vector3):boolean; + + /** + * 空间中平面和三角面是否相交 + * @param plane 平面 + * @param vertex1 三角面顶点1 + * @param vertex2 三角面顶点2 + * @param vertex3 三角面顶点3 + * @return 返回空间位置关系 + */ + static intersectsPlaneAndTriangle(plane:Plane,vertex1:Vector3,vertex2:Vector3,vertex3:Vector3):number; + + /** + * 射线和平面是否相交,并返回相交距离。 + * @param ray 射线。 + * @param plane 平面。 + * @return 相交距离,-1为不相交。 + */ + static intersectsRayAndPlaneRD(ray:Ray,plane:Plane):number; + + /** + * 空间中射线和平面是否相交,并返回相交点。 + * @param ray 射线。 + * @param plane 平面。 + * @param out 相交点。 + */ + static intersectsRayAndPlaneRP(ray:Ray,plane:Plane,out:Vector3):boolean; + + /** + * 空间中射线和包围盒是否相交 + * @param ray 射线 + * @param box 包围盒 + * @param out 相交距离,如果为0,不相交 + */ + static intersectsRayAndBoxRD(ray:Ray,box:BoundBox):number; + + /** + * 空间中射线和包围盒是否相交 + * @param ray 射线 + * @param box 包围盒 + * @param out 相交点 + */ + static intersectsRayAndBoxRP(ray:Ray,box:BoundBox,out:Vector3):number; + + /** + * 空间中射线和包围球是否相交 + * @param ray 射线 + * @param sphere 包围球 + * @return 相交距离,-1表示不相交 + */ + static intersectsRayAndSphereRD(ray:Ray,sphere:BoundSphere):number; + + /** + * 空间中射线和包围球是否相交 + * @param ray 射线 + * @param sphere 包围球 + * @param out 相交点 + * @return 相交距离,-1表示不相交 + */ + static intersectsRayAndSphereRP(ray:Ray,sphere:BoundSphere,out:Vector3):number; + + /** + * 空间中包围球和三角面是否相交 + * @param sphere 包围球 + * @param vertex1 三角面顶点1 + * @param vertex2 三角面顶点2 + * @param vertex3 三角面顶点3 + * @return 返回是否相交 + */ + static intersectsSphereAndTriangle(sphere:BoundSphere,vertex1:Vector3,vertex2:Vector3,vertex3:Vector3):boolean; + + /** + * 空间中点和平面是否相交 + * @param plane 平面 + * @param point 点 + * @return 碰撞状态 + */ + static intersectsPlaneAndPoint(plane:Plane,point:Vector3):number; + + /** + * 空间中平面和平面是否相交 + * @param plane1 平面1 + * @param plane2 平面2 + * @return 是否相交 + */ + static intersectsPlaneAndPlane(plane1:Plane,plane2:Plane):boolean; + + /** + * 空间中平面和平面是否相交 + * @param plane1 平面1 + * @param plane2 平面2 + * @param line 相交线 + * @return 是否相交 + */ + static intersectsPlaneAndPlaneRL(plane1:Plane,plane2:Plane,line:Ray):boolean; + + /** + * 空间中平面和包围盒是否相交 + * @param plane 平面 + * @param box 包围盒 + * @return 碰撞状态 + */ + static intersectsPlaneAndBox(plane:Plane,box:BoundBox):number; + + /** + * 空间中平面和包围球是否相交 + * @param plane 平面 + * @param sphere 包围球 + * @return 碰撞状态 + */ + static intersectsPlaneAndSphere(plane:Plane,sphere:BoundSphere):number; + + /** + * 空间中包围盒和包围盒是否相交 + * @param box1 包围盒1 + * @param box2 包围盒2 + * @return 是否相交 + */ + static intersectsBoxAndBox(box1:BoundBox,box2:BoundBox):boolean; + + /** + * 空间中包围盒和包围球是否相交 + * @param box 包围盒 + * @param sphere 包围球 + * @return 是否相交 + */ + static intersectsBoxAndSphere(box:BoundBox,sphere:BoundSphere):boolean; + + /** + * 空间中包围球和包围球是否相交 + * @param sphere1 包围球1 + * @param sphere2 包围球2 + * @return 是否相交 + */ + static intersectsSphereAndSphere(sphere1:BoundSphere,sphere2:BoundSphere):boolean; + + /** + * 空间中包围盒是否包含另一个点 + * @param box 包围盒 + * @param point 点 + * @return 位置关系:0 不想交,1 包含, 2 相交 + */ + static boxContainsPoint(box:BoundBox,point:Vector3):number; + + /** + * 空间中包围盒是否包含另一个包围盒 + * @param box1 包围盒1 + * @param box2 包围盒2 + * @return 位置关系:0 不想交,1 包含, 2 相交 + */ + static boxContainsBox(box1:BoundBox,box2:BoundBox):number; + + /** + * 空间中包围盒是否包含另一个包围球 + * @param box 包围盒 + * @param sphere 包围球 + * @return 位置关系:0 不想交,1 包含, 2 相交 + */ + static boxContainsSphere(box:BoundBox,sphere:BoundSphere):number; + + /** + * 空间中包围球是否包含另一个点 + * @param sphere 包围球 + * @param point 点 + * @return 位置关系:0 不想交,1 包含, 2 相交 + */ + static sphereContainsPoint(sphere:BoundSphere,point:Vector3):number; + + /** + * 空间中包围球是否包含另一个三角面 + * @param sphere + * @param vertex1 三角面顶点1 + * @param vertex2 三角面顶点2 + * @param vertex3 三角面顶点3 + * @return 返回空间位置关系 + */ + static sphereContainsTriangle(sphere:BoundSphere,vertex1:Vector3,vertex2:Vector3,vertex3:Vector3):number; + + /** + * 空间中包围球是否包含另一包围盒 + * @param sphere 包围球 + * @param box 包围盒 + * @return 位置关系:0 不想交,1 包含, 2 相交 + */ + static sphereContainsBox(sphere:BoundSphere,box:BoundBox):number; + + /** + * 空间中包围球是否包含另一包围球 + * @param sphere1 包围球 + * @param sphere2 包围球 + * @return 位置关系:0 不想交,1 包含, 2 相交 + */ + static sphereContainsSphere(sphere1:BoundSphere,sphere2:BoundSphere):number; + + /** + * 空间中点与三角面的最近点 + * @param point 点 + * @param vertex1 三角面顶点1 + * @param vertex2 三角面顶点2 + * @param vertex3 三角面顶点3 + * @param out 最近点 + */ + static closestPointPointTriangle(point:Vector3,vertex1:Vector3,vertex2:Vector3,vertex3:Vector3,out:Vector3):void; + + /** + * 空间中平面与一点的最近点 + * @param plane 平面 + * @param point 点 + * @param out 最近点 + */ + static closestPointPlanePoint(plane:Plane,point:Vector3,out:Vector3):void; + + /** + * 空间中包围盒与一点的最近点 + * @param box 包围盒 + * @param point 点 + * @param out 最近点 + */ + static closestPointBoxPoint(box:BoundBox,point:Vector3,out:Vector3):void; + + /** + * 空间中包围球与一点的最近点 + * @param sphere 包围球 + * @param point 点 + * @param out 最近点 + */ + static closestPointSpherePoint(sphere:BoundSphere,point:Vector3,out:Vector3):void; + + /** + * 空间中包围球与包围球的最近点 + * @param sphere1 包围球1 + * @param sphere2 包围球2 + * @param out 最近点 + */ + static closestPointSphereSphere(sphere1:BoundSphere,sphere2:BoundSphere,out:Vector3):void; + } + + /** + * Color 类用于创建颜色实例。 + */ + class Color implements IClone { + + /** + * 红色 + */ + static RED:Color; + + /** + * 绿色 + */ + static GREEN:Color; + + /** + * 蓝色 + */ + static BLUE:Color; + + /** + * 蓝绿色 + */ + static CYAN:Color; + + /** + * 黄色 + */ + static YELLOW:Color; + + /** + * 品红色 + */ + static MAGENTA:Color; + + /** + * 灰色 + */ + static GRAY:Color; + + /** + * 白色 + */ + static WHITE:Color; + + /** + * 黑色 + */ + static BLACK:Color; + + /** + * Gamma空间值转换到线性空间。 + * @param value gamma空间值。 + */ + static gammaToLinearSpace(value:number):number; + + /** + * 线性空间值转换到Gamma空间。 + * @param value 线性空间值。 + */ + static linearToGammaSpace(value:number):number; + + /** + * red分量 + */ + r:number; + + /** + * green分量 + */ + g:number; + + /** + * blue分量 + */ + b:number; + + /** + * alpha分量 + */ + a:number; + + /** + * 创建一个 Color 实例。 + * @param r 颜色的red分量。 + * @param g 颜色的green分量。 + * @param b 颜色的blue分量。 + * @param a 颜色的alpha分量。 + */ + + constructor(r?:number,g?:number,b?:number,a?:number); + + /** + * Gamma空间转换到线性空间。 + * @param linear 线性空间颜色。 + */ + toLinear(out:Color):void; + + /** + * 线性空间转换到Gamma空间。 + * @param gamma Gamma空间颜色。 + */ + toGamma(out:Color):void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + forNativeElement():void; + } + + /** + * ContainmentType 类用于定义空间物体位置关系。 + */ + class ContainmentType { + + /** + * 不相交 + */ + static Disjoint:number; + + /** + * 包含 + */ + static Contains:number; + + /** + * 相交 + */ + static Intersects:number; + } + + /** + * MathUtils3D 类用于创建数学工具。 + */ + class MathUtils3D { + + /** + * 单精度浮点(float)零的容差 + */ + static zeroTolerance:number; + + /** + * 浮点数默认最大值 + */ + static MaxValue:number; + + /** + * 浮点数默认最小值 + */ + static MinValue:number; + + /** + * 角度转弧度系数 + */ + static Deg2Rad:number; + + /** + * 创建一个 MathUtils 实例。 + */ + + constructor(); + + /** + * 是否在容差的范围内近似于0 + * @param 判断值 + * @return 是否近似于0 + */ + static isZero(v:number):boolean; + + /** + * 两个值是否在容差的范围内近似相等Sqr Magnitude + * @param 判断值 + * @return 是否近似于0 + */ + static nearEqual(n1:number,n2:number):boolean; + static fastInvSqrt(value:number):number; + } + + /** + * Matrix3x3 类用于创建3x3矩阵。 + */ + class Matrix3x3 implements IClone { + + /** + * 默认矩阵,禁止修改 + */ + static DEFAULT:Matrix3x3; + + /** + * 通过四元数创建旋转矩阵。 + * @param rotation 旋转四元数。 + * @param out 旋转矩阵。 + */ + static createRotationQuaternion(rotation:Quaternion,out:Matrix3x3):void; + + /** + * 根据指定平移生成3x3矩阵 + * @param tra 平移 + * @param out 输出矩阵 + */ + static createFromTranslation(trans:Vector2,out:Matrix3x3):void; + + /** + * 根据指定旋转生成3x3矩阵 + * @param rad 旋转值 + * @param out 输出矩阵 + */ + static createFromRotation(rad:number,out:Matrix3x3):void; + + /** + * 根据制定缩放生成3x3矩阵 + * @param scale 缩放值 + * @param out 输出矩阵 + */ + static createFromScaling(scale:Vector3,out:Matrix3x3):void; + + /** + * 从4x4矩阵转换为一个3x3的矩阵(原则为upper-left,忽略第四行四列) + * @param sou 4x4源矩阵 + * @param out 3x3输出矩阵 + */ + static createFromMatrix4x4(sou:Matrix4x4,out:Matrix3x3):void; + + /** + * 两个3x3矩阵的相乘 + * @param left 左矩阵 + * @param right 右矩阵 + * @param out 输出矩阵 + */ + static multiply(left:Matrix3x3,right:Matrix3x3,out:Matrix3x3):void; + + /** + * 矩阵元素数组 + */ + elements:Float32Array; + + /** + * 创建一个 Matrix3x3 实例。 + */ + + constructor(); + + /** + * 计算3x3矩阵的行列式 + * @return 矩阵的行列式 + */ + determinant():number; + + /** + * 通过一个二维向量转换3x3矩阵 + * @param tra 转换向量 + * @param out 输出矩阵 + */ + translate(trans:Vector2,out:Matrix3x3):void; + + /** + * 根据指定角度旋转3x3矩阵 + * @param rad 旋转角度 + * @param out 输出矩阵 + */ + rotate(rad:number,out:Matrix3x3):void; + + /** + * 根据制定缩放3x3矩阵 + * @param scale 缩放值 + * @param out 输出矩阵 + */ + scale(scale:Vector2,out:Matrix3x3):void; + + /** + * 计算3x3矩阵的逆矩阵 + * @param out 输出的逆矩阵 + */ + invert(out:Matrix3x3):void; + + /** + * 计算3x3矩阵的转置矩阵 + * @param out 输出矩阵 + */ + transpose(out:Matrix3x3):void; + + /** + * 设置已有的矩阵为单位矩阵 + */ + identity():void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + + /** + * 计算观察3x3矩阵 + * @param eye 观察者位置 + * @param target 目标位置 + * @param up 上向量 + * @param out 输出3x3矩阵 + */ + static lookAt(eye:Vector3,target:Vector3,up:Vector3,out:Matrix3x3):void; + } + + /** + * Matrix4x4 类用于创建4x4矩阵。 + */ + class Matrix4x4 implements IClone { + + /** + * 默认矩阵,禁止修改 + */ + static DEFAULT:Matrix4x4; + + /** + * 默认矩阵,禁止修改 + */ + static ZERO:Matrix4x4; + + /** + * 绕X轴旋转 + * @param rad 旋转角度 + * @param out 输出矩阵 + */ + static createRotationX(rad:number,out:Matrix4x4):void; + + /** + * 绕Y轴旋转 + * @param rad 旋转角度 + * @param out 输出矩阵 + */ + static createRotationY(rad:number,out:Matrix4x4):void; + + /** + * 绕Z轴旋转 + * @param rad 旋转角度 + * @param out 输出矩阵 + */ + static createRotationZ(rad:number,out:Matrix4x4):void; + + /** + * 通过yaw pitch roll旋转创建旋转矩阵。 + * @param yaw + * @param pitch + * @param roll + * @param result + */ + static createRotationYawPitchRoll(yaw:number,pitch:number,roll:number,result:Matrix4x4):void; + + /** + * 通过旋转轴axis和旋转角度angle计算旋转矩阵。 + * @param axis 旋转轴,假定已经归一化。 + * @param angle 旋转角度。 + * @param result 结果矩阵。 + */ + static createRotationAxis(axis:Vector3,angle:number,result:Matrix4x4):void; + setRotation(rotation:Quaternion):void; + setPosition(position:Vector3):void; + + /** + * 通过四元数创建旋转矩阵。 + * @param rotation 旋转四元数。 + * @param result 输出旋转矩阵 + */ + static createRotationQuaternion(rotation:Quaternion,result:Matrix4x4):void; + + /** + * 根据平移计算输出矩阵 + * @param trans 平移向量 + * @param out 输出矩阵 + */ + static createTranslate(trans:Vector3,out:Matrix4x4):void; + + /** + * 根据缩放计算输出矩阵 + * @param scale 缩放值 + * @param out 输出矩阵 + */ + static createScaling(scale:Vector3,out:Matrix4x4):void; + + /** + * 计算两个矩阵的乘法 + * @param left left矩阵 + * @param right right矩阵 + * @param out 输出矩阵 + */ + static multiply(left:Matrix4x4,right:Matrix4x4,out:Matrix4x4):void; + static multiplyForNative(left:Matrix4x4,right:Matrix4x4,out:Matrix4x4):void; + + /** + * 从四元数计算旋转矩阵 + * @param rotation 四元数 + * @param out 输出矩阵 + */ + static createFromQuaternion(rotation:Quaternion,out:Matrix4x4):void; + + /** + * 计算仿射矩阵 + * @param trans 平移 + * @param rot 旋转 + * @param scale 缩放 + * @param out 输出矩阵 + */ + static createAffineTransformation(trans:Vector3,rot:Quaternion,scale:Vector3,out:Matrix4x4):void; + + /** + * 计算观察矩阵 + * @param eye 视点位置 + * @param target 视点目标 + * @param up 向上向量 + * @param out 输出矩阵 + */ + static createLookAt(eye:Vector3,target:Vector3,up:Vector3,out:Matrix4x4):void; + + /** + * 通过FOV创建透视投影矩阵。 + * @param fov 视角。 + * @param aspect 横纵比。 + * @param near 近裁面。 + * @param far 远裁面。 + * @param out 输出矩阵。 + */ + static createPerspective(fov:number,aspect:number,znear:number,zfar:number,out:Matrix4x4):void; + + /** + * 创建透视投影矩阵。 + * @param left 视椎左边界。 + * @param right 视椎右边界。 + * @param bottom 视椎底边界。 + * @param top 视椎顶边界。 + * @param znear 视椎近边界。 + * @param zfar 视椎远边界。 + * @param out 输出矩阵。 + */ + static createPerspectiveOffCenter(left:number,right:number,bottom:number,top:number,znear:number,zfar:number,out:Matrix4x4):void; + + /** + * 计算正交投影矩阵。 + * @param left 视椎左边界。 + * @param right 视椎右边界。 + * @param bottom 视椎底边界。 + * @param top 视椎顶边界。 + * @param near 视椎近边界。 + * @param far 视椎远边界。 + * @param out 输出矩阵。 + */ + static createOrthoOffCenter(left:number,right:number,bottom:number,top:number,znear:number,zfar:number,out:Matrix4x4):void; + + /** + * 矩阵元素数组 + */ + elements:Float32Array; + + /** + * 创建一个 Matrix4x4 实例。 + * @param 4x4矩阵的各元素 + */ + + constructor(m11?:number,m12?:number,m13?:number,m14?:number,m21?:number,m22?:number,m23?:number,m24?:number,m31?:number,m32?:number,m33?:number,m34?:number,m41?:number,m42?:number,m43?:number,m44?:number,elements?:Float32Array); + getElementByRowColumn(row:number,column:number):number; + setElementByRowColumn(row:number,column:number,value:number):void; + + /** + * 判断两个4x4矩阵的值是否相等。 + * @param other 4x4矩阵 + */ + equalsOtherMatrix(other:Matrix4x4):boolean; + + /** + * 分解矩阵为平移向量、旋转四元数、缩放向量。 + * @param translation 平移向量。 + * @param rotation 旋转四元数。 + * @param scale 缩放向量。 + * @return 是否分解成功。 + */ + decomposeTransRotScale(translation:Vector3,rotation:Quaternion,scale:Vector3):boolean; + + /** + * 分解矩阵为平移向量、旋转矩阵、缩放向量。 + * @param translation 平移向量。 + * @param rotationMatrix 旋转矩阵。 + * @param scale 缩放向量。 + * @return 是否分解成功。 + */ + decomposeTransRotMatScale(translation:Vector3,rotationMatrix:Matrix4x4,scale:Vector3):boolean; + + /** + * 分解旋转矩阵的旋转为YawPitchRoll欧拉角。 + * @param out float yaw + * @param out float pitch + * @param out float roll + * @return + */ + decomposeYawPitchRoll(yawPitchRoll:Vector3):void; + + /** + * 归一化矩阵 + */ + normalize():void; + + /** + * 计算矩阵的转置矩阵 + */ + transpose():Matrix4x4; + + /** + * 计算一个矩阵的逆矩阵 + * @param out 输出矩阵 + */ + invert(out:Matrix4x4):void; + + /** + * 计算BlillBoard矩阵 + * @param objectPosition 物体位置 + * @param cameraPosition 相机位置 + * @param cameraUp 相机上向量 + * @param cameraForward 相机前向量 + * @param mat 变换矩阵 + */ + static billboard(objectPosition:Vector3,cameraPosition:Vector3,cameraUp:Vector3,cameraForward:Vector3,mat:Matrix4x4):void; + + /** + * 设置矩阵为单位矩阵 + */ + identity():void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + static translation(v3:Vector3,out:Matrix4x4):void; + + /** + * 获取平移向量。 + * @param out 平移向量。 + */ + getTranslationVector(out:Vector3):void; + + /** + * 设置平移向量。 + * @param translate 平移向量。 + */ + setTranslationVector(translate:Vector3):void; + + /** + * 获取前向量。 + * @param out 前向量。 + */ + getForward(out:Vector3):void; + + /** + * 设置前向量。 + * @param forward 前向量。 + */ + setForward(forward:Vector3):void; + + /** + * 判断此矩阵是否是反向矩阵 + */ + getInvertFront():boolean; + } + + /** + * Quaternion 类用于创建四元数。 + */ + class ConchQuaternion implements IClone { + + /** + * 默认矩阵,禁止修改 + */ + static DEFAULT:ConchQuaternion; + + /** + * 无效矩阵,禁止修改 + */ + static NAN:ConchQuaternion; + + /** + * 从欧拉角生成四元数(顺序为Yaw、Pitch、Roll) + * @param yaw yaw值 + * @param pitch pitch值 + * @param roll roll值 + * @param out 输出四元数 + */ + static createFromYawPitchRoll(yaw:number,pitch:number,roll:number,out:ConchQuaternion):void; + + /** + * 计算两个四元数相乘 + * @param left left四元数 + * @param right right四元数 + * @param out 输出四元数 + */ + static multiply(left:ConchQuaternion,right:ConchQuaternion,out:ConchQuaternion):void; + private static arcTanAngle:any; + private static angleTo:any; + + /** + * 从指定的轴和角度计算四元数 + * @param axis 轴 + * @param rad 角度 + * @param out 输出四元数 + */ + static createFromAxisAngle(axis:ConchVector3,rad:number,out:ConchQuaternion):void; + + /** + * 根据3x3矩阵计算四元数 + * @param sou 源矩阵 + * @param out 输出四元数 + */ + static createFromMatrix3x3(sou:Matrix3x3,out:ConchQuaternion):void; + + /** + * 从旋转矩阵计算四元数 + * @param mat 旋转矩阵 + * @param out 输出四元数 + */ + static createFromMatrix4x4(mat:Matrix4x4,out:ConchQuaternion):void; + + /** + * 球面插值 + * @param left left四元数 + * @param right right四元数 + * @param a 插值比例 + * @param out 输出四元数 + * @return 输出Float32Array + */ + static slerp(left:ConchQuaternion,right:ConchQuaternion,t:number,out:ConchQuaternion):Float32Array; + + /** + * 计算两个四元数的线性插值 + * @param left left四元数 + * @param right right四元数b + * @param t 插值比例 + * @param out 输出四元数 + */ + static lerp(left:ConchQuaternion,right:ConchQuaternion,amount:number,out:ConchQuaternion):void; + + /** + * 计算两个四元数的和 + * @param left left四元数 + * @param right right 四元数 + * @param out 输出四元数 + */ + static add(left:any,right:ConchQuaternion,out:ConchQuaternion):void; + + /** + * 计算两个四元数的点积 + * @param left left四元数 + * @param right right四元数 + * @return 点积 + */ + static dot(left:any,right:ConchQuaternion):number; + + /** + * 四元数元素数组 + */ + elements:Float32Array; + + /** + * 获取四元数的x值 + */ + get x():number; + + /** + * 设置四元数的x值 + */ + set x(value:number); + + /** + * 获取四元数的y值 + */ + get y():number; + + /** + * 设置四元数的y值 + */ + set y(value:number); + + /** + * 获取四元数的z值 + */ + get z():number; + + /** + * 设置四元数的z值 + */ + set z(value:number); + + /** + * 获取四元数的w值 + */ + get w():number; + + /** + * 设置四元数的w值 + */ + set w(value:number); + + /** + * 创建一个 Quaternion 实例。 + * @param x 四元数的x值 + * @param y 四元数的y值 + * @param z 四元数的z值 + * @param w 四元数的w值 + */ + + constructor(x?:number,y?:number,z?:number,w?:number,nativeElements?:Float32Array); + + /** + * 根据缩放值缩放四元数 + * @param scale 缩放值 + * @param out 输出四元数 + */ + scaling(scaling:number,out:ConchQuaternion):void; + + /** + * 归一化四元数 + * @param out 输出四元数 + */ + normalize(out:ConchQuaternion):void; + + /** + * 计算四元数的长度 + * @return 长度 + */ + length():number; + + /** + * 根据绕X轴的角度旋转四元数 + * @param rad 角度 + * @param out 输出四元数 + */ + rotateX(rad:number,out:ConchQuaternion):void; + + /** + * 根据绕Y轴的制定角度旋转四元数 + * @param rad 角度 + * @param out 输出四元数 + */ + rotateY(rad:number,out:ConchQuaternion):void; + + /** + * 根据绕Z轴的制定角度旋转四元数 + * @param rad 角度 + * @param out 输出四元数 + */ + rotateZ(rad:number,out:ConchQuaternion):void; + + /** + * 分解四元数到欧拉角(顺序为Yaw、Pitch、Roll),参考自http://xboxforums.create.msdn.com/forums/p/4574/23988.aspx#23988,问题绕X轴翻转超过±90度时有,会产生瞬间反转 + * @param quaternion 源四元数 + * @param out 欧拉角值 + */ + getYawPitchRoll(out:ConchVector3):void; + + /** + * 求四元数的逆 + * @param out 输出四元数 + */ + invert(out:ConchQuaternion):void; + + /** + * 设置四元数为单位算数 + * @param out 输出四元数 + */ + identity():void; + + /** + * 从Array数组拷贝值。 + * @param array 数组。 + * @param offset 数组偏移。 + */ + fromArray(array:any[],offset?:number):void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + equals(b:ConchQuaternion):boolean; + + /** + * 计算旋转观察四元数 + * @param forward 方向 + * @param up 上向量 + * @param out 输出四元数 + */ + static rotationLookAt(forward:ConchVector3,up:ConchVector3,out:ConchQuaternion):void; + + /** + * 计算观察四元数 + * @param eye 观察者位置 + * @param target 目标位置 + * @param up 上向量 + * @param out 输出四元数 + */ + static lookAt(eye:any,target:any,up:any,out:ConchQuaternion):void; + + /** + * 计算长度的平方。 + * @return 长度的平方。 + */ + lengthSquared():number; + + /** + * 计算四元数的逆四元数。 + * @param value 四元数。 + * @param out 逆四元数。 + */ + static invert(value:ConchQuaternion,out:ConchQuaternion):void; + + /** + * 通过一个3x3矩阵创建一个四元数 + * @param matrix3x3 3x3矩阵 + * @param out 四元数 + */ + static rotationMatrix(matrix3x3:Matrix3x3,out:ConchQuaternion):void; + } + + /** + * Vector3 类用于创建三维向量。 + */ + class ConchVector3 implements IClone { + + /** + * 零向量,禁止修改 + */ + static ZERO:ConchVector3; + + /** + * 一向量,禁止修改 + */ + static ONE:ConchVector3; + + /** + * X轴单位向量,禁止修改 + */ + static NegativeUnitX:ConchVector3; + + /** + * X轴单位向量,禁止修改 + */ + static UnitX:ConchVector3; + + /** + * Y轴单位向量,禁止修改 + */ + static UnitY:ConchVector3; + + /** + * Z轴单位向量,禁止修改 + */ + static UnitZ:ConchVector3; + + /** + * 右手坐标系统前向量,禁止修改 + */ + static ForwardRH:ConchVector3; + + /** + * 左手坐标系统前向量,禁止修改 + */ + static ForwardLH:ConchVector3; + + /** + * 上向量,禁止修改 + */ + static Up:ConchVector3; + + /** + * 无效矩阵,禁止修改 + */ + static NAN:ConchVector3; + + /** + * [只读]向量元素集合。 + */ + elements:Float32Array; + + /** + * 两个三维向量距离的平方。 + * @param value1 向量1。 + * @param value2 向量2。 + * @return 距离的平方。 + */ + static distanceSquared(value1:ConchVector3,value2:ConchVector3):number; + + /** + * 两个三维向量距离。 + * @param value1 向量1。 + * @param value2 向量2。 + * @return 距离。 + */ + static distance(value1:ConchVector3,value2:ConchVector3):number; + + /** + * 分别取两个三维向量x、y、z的最小值计算新的三维向量。 + * @param a 。 + * @param b 。 + * @param out 。 + */ + static min(a:ConchVector3,b:ConchVector3,out:ConchVector3):void; + + /** + * 分别取两个三维向量x、y、z的最大值计算新的三维向量。 + * @param a a三维向量。 + * @param b b三维向量。 + * @param out 结果三维向量。 + */ + static max(a:ConchVector3,b:ConchVector3,out:ConchVector3):void; + + /** + * 根据四元数旋转三维向量。 + * @param source 源三维向量。 + * @param rotation 旋转四元数。 + * @param out 输出三维向量。 + */ + static transformQuat(source:ConchVector3,rotation:ConchQuaternion,out:ConchVector3):void; + + /** + * 计算标量长度。 + * @param a 源三维向量。 + * @return 标量长度。 + */ + static scalarLength(a:ConchVector3):number; + + /** + * 计算标量长度的平方。 + * @param a 源三维向量。 + * @return 标量长度的平方。 + */ + static scalarLengthSquared(a:ConchVector3):number; + + /** + * 归一化三维向量。 + * @param s 源三维向量。 + * @param out 输出三维向量。 + */ + static normalize(s:ConchVector3,out:ConchVector3):void; + + /** + * 计算两个三维向量的乘积。 + * @param a left三维向量。 + * @param b right三维向量。 + * @param out 输出三维向量。 + */ + static multiply(a:ConchVector3,b:ConchVector3,out:ConchVector3):void; + + /** + * 缩放三维向量。 + * @param a 源三维向量。 + * @param b 缩放值。 + * @param out 输出三维向量。 + */ + static scale(a:ConchVector3,b:number,out:ConchVector3):void; + + /** + * 插值三维向量。 + * @param a left向量。 + * @param b right向量。 + * @param t 插值比例。 + * @param out 输出向量。 + */ + static lerp(a:ConchVector3,b:ConchVector3,t:number,out:ConchVector3):void; + + /** + * 通过矩阵转换一个三维向量到另外一个三维向量。 + * @param vector 源三维向量。 + * @param transform 变换矩阵。 + * @param result 输出三维向量。 + */ + static transformV3ToV3(vector:ConchVector3,transform:any,result:ConchVector3):void; + + /** + * 通过矩阵转换一个三维向量到另外一个四维向量。 + * @param vector 源三维向量。 + * @param transform 变换矩阵。 + * @param result 输出四维向量。 + */ + static transformV3ToV4(vector:ConchVector3,transform:any,result:ConchVector4):void; + + /** + * 通过法线矩阵转换一个法线三维向量到另外一个三维向量。 + * @param normal 源法线三维向量。 + * @param transform 法线变换矩阵。 + * @param result 输出法线三维向量。 + */ + static TransformNormal(normal:ConchVector3,transform:any,result:ConchVector3):void; + + /** + * 通过矩阵转换一个三维向量到另外一个归一化的三维向量。 + * @param vector 源三维向量。 + * @param transform 变换矩阵。 + * @param result 输出三维向量。 + */ + static transformCoordinate(coordinate:ConchVector3,transform:any,result:ConchVector3):void; + + /** + * 求一个指定范围的向量 + * @param value clamp向量 + * @param min 最小 + * @param max 最大 + * @param out 输出向量 + */ + static Clamp(value:ConchVector3,min:ConchVector3,max:ConchVector3,out:ConchVector3):void; + + /** + * 求两个三维向量的和。 + * @param a left三维向量。 + * @param b right三维向量。 + * @param out 输出向量。 + */ + static add(a:ConchVector3,b:ConchVector3,out:ConchVector3):void; + + /** + * 求两个三维向量的差。 + * @param a left三维向量。 + * @param b right三维向量。 + * @param o out 输出向量。 + */ + static subtract(a:ConchVector3,b:ConchVector3,o:ConchVector3):void; + + /** + * 求两个三维向量的叉乘。 + * @param a left向量。 + * @param b right向量。 + * @param o 输出向量。 + */ + static cross(a:ConchVector3,b:ConchVector3,o:ConchVector3):void; + + /** + * 求两个三维向量的点积。 + * @param a left向量。 + * @param b right向量。 + * @return 点积。 + */ + static dot(a:ConchVector3,b:ConchVector3):number; + + /** + * 判断两个三维向量是否相等。 + * @param a 三维向量。 + * @param b 三维向量。 + * @return 是否相等。 + */ + static equals(a:ConchVector3,b:ConchVector3):boolean; + + /** + * 获取X轴坐标。 + * @return X轴坐标。 + */ + get x():number; + + /** + * 设置X轴坐标。 + * @param value X轴坐标。 + */ + set x(value:number); + + /** + * 获取Y轴坐标。 + * @return Y轴坐标。 + */ + get y():number; + + /** + * 设置Y轴坐标。 + * @param value Y轴坐标。 + */ + set y(value:number); + + /** + * 获取Z轴坐标。 + * @return Z轴坐标。 + */ + get z():number; + + /** + * 设置Z轴坐标。 + * @param value Z轴坐标。 + */ + set z(value:number); + + /** + * 创建一个 Vector3 实例。 + * @param x X轴坐标。 + * @param y Y轴坐标。 + * @param z Z轴坐标。 + */ + + constructor(x?:number,y?:number,z?:number,nativeElements?:Float32Array); + + /** + * 设置xyz值。 + * @param x X值。 + * @param y Y值。 + * @param z Z值。 + */ + setValue(x:number,y:number,z:number):void; + + /** + * 从Array数组拷贝值。 + * @param array 数组。 + * @param offset 数组偏移。 + */ + fromArray(array:any[],offset?:number):void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + toDefault():void; + } + + /** + * Vector4 类用于创建四维向量。 + */ + class ConchVector4 implements IClone { + + /** + * 零向量,禁止修改 + */ + static ZERO:ConchVector4; + static ONE:ConchVector4; + static UnitX:ConchVector4; + static UnitY:ConchVector4; + static UnitZ:ConchVector4; + static UnitW:ConchVector4; + + /** + * [只读]向量元素集合。 + */ + elements:Float32Array; + + /** + * 获取X轴坐标。 + * @return X轴坐标。 + */ + get x():number; + + /** + * 设置X轴坐标。 + * @param value X轴坐标。 + */ + set x(value:number); + + /** + * 获取Y轴坐标。 + * @return Y轴坐标。 + */ + get y():number; + + /** + * 设置Y轴坐标。 + * @param value Y轴坐标。 + */ + set y(value:number); + + /** + * 获取Z轴坐标。 + * @return Z轴坐标。 + */ + get z():number; + + /** + * 设置Z轴坐标。 + * @param value Z轴坐标。 + */ + set z(value:number); + + /** + * 获取W轴坐标。 + * @return W轴坐标。 + */ + get w():number; + + /** + * 设置W轴坐标。 + * @param value W轴坐标。 + */ + set w(value:number); + + /** + * 创建一个 Vector4 实例。 + * @param x X轴坐标。 + * @param y Y轴坐标。 + * @param z Z轴坐标。 + * @param w W轴坐标。 + */ + + constructor(x?:number,y?:number,z?:number,w?:number); + + /** + * 从Array数组拷贝值。 + * @param array 数组。 + * @param offset 数组偏移。 + */ + fromArray(array:any[],offset?:number):void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + + /** + * 插值四维向量。 + * @param a left向量。 + * @param b right向量。 + * @param t 插值比例。 + * @param out 输出向量。 + */ + static lerp(a:ConchVector4,b:ConchVector4,t:number,out:ConchVector4):void; + + /** + * 通过4x4矩阵把一个四维向量转换为另一个四维向量 + * @param vector4 带转换四维向量。 + * @param M4x4 4x4矩阵。 + * @param out 转换后四维向量。 + */ + static transformByM4x4(vector4:ConchVector4,m4x4:any,out:ConchVector4):void; + + /** + * 判断两个四维向量是否相等。 + * @param a 四维向量。 + * @param b 四维向量。 + * @return 是否相等。 + */ + static equals(a:ConchVector4,b:ConchVector4):boolean; + + /** + * 求四维向量的长度。 + * @return 长度。 + */ + length():number; + + /** + * 求四维向量长度的平方。 + * @return 长度的平方。 + */ + lengthSquared():number; + + /** + * 归一化四维向量。 + * @param s 源四维向量。 + * @param out 输出四维向量。 + */ + static normalize(s:ConchVector4,out:ConchVector4):void; + + /** + * 求两个四维向量的和。 + * @param a 四维向量。 + * @param b 四维向量。 + * @param out 输出向量。 + */ + static add(a:ConchVector4,b:ConchVector4,out:ConchVector4):void; + + /** + * 求两个四维向量的差。 + * @param a 四维向量。 + * @param b 四维向量。 + * @param out 输出向量。 + */ + static subtract(a:ConchVector4,b:ConchVector4,out:ConchVector4):void; + + /** + * 计算两个四维向量的乘积。 + * @param a 四维向量。 + * @param b 四维向量。 + * @param out 输出向量。 + */ + static multiply(a:ConchVector4,b:ConchVector4,out:ConchVector4):void; + + /** + * 缩放四维向量。 + * @param a 源四维向量。 + * @param b 缩放值。 + * @param out 输出四维向量。 + */ + static scale(a:ConchVector4,b:number,out:ConchVector4):void; + + /** + * 求一个指定范围的四维向量 + * @param value clamp向量 + * @param min 最小 + * @param max 最大 + * @param out 输出向量 + */ + static Clamp(value:ConchVector4,min:ConchVector4,max:ConchVector4,out:ConchVector4):void; + + /** + * 两个四维向量距离的平方。 + * @param value1 向量1。 + * @param value2 向量2。 + * @return 距离的平方。 + */ + static distanceSquared(value1:ConchVector4,value2:ConchVector4):number; + + /** + * 两个四维向量距离。 + * @param value1 向量1。 + * @param value2 向量2。 + * @return 距离。 + */ + static distance(value1:ConchVector4,value2:ConchVector4):number; + + /** + * 求两个四维向量的点积。 + * @param a 向量。 + * @param b 向量。 + * @return 点积。 + */ + static dot(a:ConchVector4,b:ConchVector4):number; + + /** + * 分别取两个四维向量x、y、z的最小值计算新的四维向量。 + * @param a 四维向量。 + * @param b 四维向量。 + * @param out 结果三维向量。 + */ + static min(a:ConchVector4,b:ConchVector4,out:ConchVector4):void; + + /** + * 分别取两个四维向量x、y、z的最大值计算新的四维向量。 + * @param a 四维向量。 + * @param b 四维向量。 + * @param out 结果三维向量。 + */ + static max(a:ConchVector4,b:ConchVector4,out:ConchVector4):void; + } + + /** + * 平面。 + */ + class Plane { + + /** + * 平面的向量 + */ + normal:Vector3; + + /** + * 平面到坐标系原点的距离 + */ + distance:number; + + /** + * 平面与其他几何体相交类型 + */ + static PlaneIntersectionType_Back:number; + static PlaneIntersectionType_Front:number; + static PlaneIntersectionType_Intersecting:number; + + /** + * 创建一个 Plane 实例。 + * @param normal 平面的向量 + * @param d 平面到原点的距离 + */ + + constructor(normal:Vector3,d?:number); + + /** + * 通过三个点创建一个平面。 + * @param point0 第零个点 + * @param point1 第一个点 + * @param point2 第二个点 + */ + static createPlaneBy3P(point0:Vector3,point1:Vector3,point2:Vector3,out:Plane):void; + + /** + * 更改平面法线向量的系数,使之成单位长度。 + */ + normalize():void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():Plane; + } + + /** + * Quaternion 类用于创建四元数。 + */ + class Quaternion implements IClone { + + /** + * 默认矩阵,禁止修改 + */ + static DEFAULT:Quaternion; + + /** + * 无效矩阵,禁止修改 + */ + static NAN:Quaternion; + + /** + * 从欧拉角生成四元数(顺序为Yaw、Pitch、Roll) + * @param yaw yaw值 + * @param pitch pitch值 + * @param roll roll值 + * @param out 输出四元数 + */ + static createFromYawPitchRoll(yaw:number,pitch:number,roll:number,out:Quaternion):void; + + /** + * 计算两个四元数相乘 + * @param left left四元数 + * @param right right四元数 + * @param out 输出四元数 + */ + static multiply(left:Quaternion,right:Quaternion,out:Quaternion):void; + private static arcTanAngle:any; + private static angleTo:any; + + /** + * 从指定的轴和角度计算四元数 + * @param axis 轴 + * @param rad 角度 + * @param out 输出四元数 + */ + static createFromAxisAngle(axis:Vector3,rad:number,out:Quaternion):void; + + /** + * 从旋转矩阵计算四元数 + * @param mat 旋转矩阵 + * @param out 输出四元数 + */ + static createFromMatrix4x4(mat:Matrix4x4,out:Quaternion):void; + + /** + * 球面插值 + * @param left left四元数 + * @param right right四元数 + * @param t 插值比例 + * @param out 输出四元数 + * @returns 输出Float32Array + */ + static slerp(left:Quaternion,right:Quaternion,t:number,out:Quaternion):Quaternion; + + /** + * 计算两个四元数的线性插值 + * @param left left四元数 + * @param right right四元数b + * @param t 插值比例 + * @param out 输出四元数 + */ + static lerp(left:Quaternion,right:Quaternion,amount:number,out:Quaternion):void; + + /** + * 计算两个四元数的和 + * @param left left四元数 + * @param right right 四元数 + * @param out 输出四元数 + */ + static add(left:Quaternion,right:Quaternion,out:Quaternion):void; + + /** + * 计算两个四元数的点积 + * @param left left四元数 + * @param right right四元数 + * @return 点积 + */ + static dot(left:Quaternion,right:Quaternion):number; + + /** + * X轴坐标 + */ + x:number; + + /** + * Y轴坐标 + */ + y:number; + + /** + * Z轴坐标 + */ + z:number; + + /** + * W轴坐标 + */ + w:number; + + /** + * 创建一个 Quaternion 实例。 + * @param x 四元数的x值 + * @param y 四元数的y值 + * @param z 四元数的z值 + * @param w 四元数的w值 + */ + + constructor(x?:number,y?:number,z?:number,w?:number); + + /** + * 根据缩放值缩放四元数 + * @param scale 缩放值 + * @param out 输出四元数 + */ + scaling(scaling:number,out:Quaternion):void; + + /** + * 归一化四元数 + * @param out 输出四元数 + */ + normalize(out:Quaternion):void; + + /** + * 计算四元数的长度 + * @return 长度 + */ + length():number; + + /** + * 根据绕X轴的角度旋转四元数 + * @param rad 角度 + * @param out 输出四元数 + */ + rotateX(rad:number,out:Quaternion):void; + + /** + * 根据绕Y轴的制定角度旋转四元数 + * @param rad 角度 + * @param out 输出四元数 + */ + rotateY(rad:number,out:Quaternion):void; + + /** + * 根据绕Z轴的制定角度旋转四元数 + * @param rad 角度 + * @param out 输出四元数 + */ + rotateZ(rad:number,out:Quaternion):void; + + /** + * 分解四元数到欧拉角(顺序为Yaw、Pitch、Roll),参考自http://xboxforums.create.msdn.com/forums/p/4574/23988.aspx#23988,问题绕X轴翻转超过±90度时有,会产生瞬间反转 + * @param quaternion 源四元数 + * @param out 欧拉角值 + */ + getYawPitchRoll(out:Vector3):void; + + /** + * 求四元数的逆 + * @param out 输出四元数 + */ + invert(out:Quaternion):void; + + /** + * 设置四元数为单位算数 + * @param out 输出四元数 + */ + identity():void; + + /** + * 从Array数组拷贝值。 + * @param array 数组。 + * @param offset 数组偏移。 + */ + fromArray(array:any[],offset?:number):void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + equals(b:Quaternion):boolean; + + /** + * 计算旋转观察四元数 + * @param forward 方向 + * @param up 上向量 + * @param out 输出四元数 + */ + static rotationLookAt(forward:Vector3,up:Vector3,out:Quaternion):void; + + /** + * 计算观察四元数 + * @param eye 观察者位置 + * @param target 目标位置 + * @param up 上向量 + * @param out 输出四元数 + */ + static lookAt(eye:Vector3,target:Vector3,up:Vector3,out:Quaternion):void; + + /** + * 计算长度的平方。 + * @return 长度的平方。 + */ + lengthSquared():number; + + /** + * 计算四元数的逆四元数。 + * @param value 四元数。 + * @param out 逆四元数。 + */ + static invert(value:Quaternion,out:Quaternion):void; + + /** + * 通过一个3x3矩阵创建一个四元数 + * @param matrix3x3 3x3矩阵 + * @param out 四元数 + */ + static rotationMatrix(matrix3x3:Matrix3x3,out:Quaternion):void; + forNativeElement(nativeElements?:Float32Array):void; + } + + /** + * Rand 类用于通过32位无符号整型随机种子创建随机数。 + */ + class Rand { + + /** + * 通过无符号32位整形,获取32位浮点随机数。 + * @param 无符号32位整形随机数 。 + * @return 32位浮点随机数。 + */ + static getFloatFromInt(v:number):number; + + /** + * 通过无符号32位整形,获取无符号8位字节随机数。 + * @param 无符号32位整形随机数 。 + * @return 无符号8位字节随机数。 + */ + static getByteFromInt(v:number):number; + + /** + * 获取随机种子。 + */ + seeds:Uint32Array; + + /** + * 获取随机种子。 + * @return 随机种子。 + */ + get seed():number; + + /** + * 设置随机种子。 + * @param seed 随机种子。 + */ + set seed(seed:number); + + /** + * 创建一个 Rand 实例。 + * @param seed 32位无符号整型随机种子。 + */ + + constructor(seed:number); + + /** + * 获取无符号32位整形随机数。 + * @return 无符号32位整形随机数。 + */ + getUint():number; + + /** + * 获取0到1之间的浮点随机数。 + * @return 0到1之间的浮点随机数。 + */ + getFloat():number; + + /** + * 获取-1到1之间的浮点随机数。 + * @return -1到1之间的浮点随机数。 + */ + getSignedFloat():number; + } + + /** + * Rand 类用于通过128位整型种子创建随机数,算法来自:https://github.com/AndreasMadsen/xorshift。 + */ + class RandX { + + /** + * 基于时间种子的随机数。 + */ + static defaultRand:RandX; + + /** + * 创建一个 Rand 实例。 + * @param seed 随机种子。 + */ + + constructor(seed:any[]); + + /** + * 通过2x32位的数组,返回64位的随机数。 + * @return 64位的随机数。 + */ + randomint():any[]; + + /** + * 返回[0,1)之间的随机数。 + * @return + */ + random():number; + } + + /** + * Ray 类用于创建射线。 + */ + class Ray { + + /** + * 原点 + */ + origin:Vector3; + + /** + * 方向 + */ + direction:Vector3; + + /** + * 创建一个 Ray 实例。 + * @param origin 射线的起点 + * @param direction 射线的方向 + */ + + constructor(origin:Vector3,direction:Vector3); + } + + /** + * Vector2 类用于创建二维向量。 + */ + class Vector2 implements IClone { + + /** + * 零向量,禁止修改 + */ + static ZERO:Vector2; + + /** + * 一向量,禁止修改 + */ + static ONE:Vector2; + + /** + * X轴坐标 + */ + x:number; + + /** + * Y轴坐标 + */ + y:number; + + /** + * 创建一个 Vector2 实例。 + * @param x X轴坐标。 + * @param y Y轴坐标。 + */ + + constructor(x?:number,y?:number); + + /** + * 设置xy值。 + * @param x X值。 + * @param y Y值。 + */ + setValue(x:number,y:number):void; + + /** + * 缩放二维向量。 + * @param a 源二维向量。 + * @param b 缩放值。 + * @param out 输出二维向量。 + */ + static scale(a:Vector2,b:number,out:Vector2):void; + + /** + * 从Array数组拷贝值。 + * @param array 数组。 + * @param offset 数组偏移。 + */ + fromArray(array:any[],offset?:number):void; + + /** + * 写入Array数组 + * @param array 数组。 + * @param offset 数组偏移。 + */ + toArray(array:Float32Array,offset?:number):void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 求两个二维向量的点积。 + * @param a left向量。 + * @param b right向量。 + * @return 点积。 + */ + static dot(a:Vector2,b:Vector2):number; + + /** + * 归一化二维向量。 + * @param s 源三维向量。 + * @param out 输出三维向量。 + */ + static normalize(s:Vector2,out:Vector2):void; + + /** + * 计算标量长度。 + * @param a 源三维向量。 + * @return 标量长度。 + */ + static scalarLength(a:Vector2):number; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + forNativeElement(nativeElements?:Float32Array|null):void; + static rewriteNumProperty(proto:any,name:string,index:number):void; + } + + /** + * Vector3 类用于创建三维向量。 + */ + class Vector3 implements IClone { + + /** + * 两个三维向量距离的平方。 + * @param value1 向量1。 + * @param value2 向量2。 + * @return 距离的平方。 + */ + static distanceSquared(value1:Vector3,value2:Vector3):number; + + /** + * 两个三维向量距离。 + * @param value1 向量1。 + * @param value2 向量2。 + * @return 距离。 + */ + static distance(value1:Vector3,value2:Vector3):number; + + /** + * 分别取两个三维向量x、y、z的最小值计算新的三维向量。 + * @param a 。 + * @param b 。 + * @param out 。 + */ + static min(a:Vector3,b:Vector3,out:Vector3):void; + + /** + * 分别取两个三维向量x、y、z的最大值计算新的三维向量。 + * @param a a三维向量。 + * @param b b三维向量。 + * @param out 结果三维向量。 + */ + static max(a:Vector3,b:Vector3,out:Vector3):void; + + /** + * 根据四元数旋转三维向量。 + * @param source 源三维向量。 + * @param rotation 旋转四元数。 + * @param out 输出三维向量。 + */ + static transformQuat(source:Vector3,rotation:Quaternion,out:Vector3):void; + + /** + * 计算标量长度。 + * @param a 源三维向量。 + * @return 标量长度。 + */ + static scalarLength(a:Vector3):number; + + /** + * 计算标量长度的平方。 + * @param a 源三维向量。 + * @return 标量长度的平方。 + */ + static scalarLengthSquared(a:Vector3):number; + + /** + * 归一化三维向量。 + * @param s 源三维向量。 + * @param out 输出三维向量。 + */ + static normalize(s:Vector3,out:Vector3):void; + + /** + * 计算两个三维向量的乘积。 + * @param a left三维向量。 + * @param b right三维向量。 + * @param out 输出三维向量。 + */ + static multiply(a:Vector3,b:Vector3,out:Vector3):void; + + /** + * 缩放三维向量。 + * @param a 源三维向量。 + * @param b 缩放值。 + * @param out 输出三维向量。 + */ + static scale(a:Vector3,b:number,out:Vector3):void; + + /** + * 插值三维向量。 + * @param a left向量。 + * @param b right向量。 + * @param t 插值比例。 + * @param out 输出向量。 + */ + static lerp(a:Vector3,b:Vector3,t:number,out:Vector3):void; + + /** + * 通过矩阵转换一个三维向量到另外一个三维向量。 + * @param vector 源三维向量。 + * @param transform 变换矩阵。 + * @param result 输出三维向量。 + */ + static transformV3ToV3(vector:Vector3,transform:Matrix4x4,result:Vector3):void; + + /** + * 通过矩阵转换一个三维向量到另外一个四维向量。 + * @param vector 源三维向量。 + * @param transform 变换矩阵。 + * @param result 输出四维向量。 + */ + static transformV3ToV4(vector:Vector3,transform:Matrix4x4,result:Vector4):void; + + /** + * 通过法线矩阵转换一个法线三维向量到另外一个三维向量。 + * @param normal 源法线三维向量。 + * @param transform 法线变换矩阵。 + * @param result 输出法线三维向量。 + */ + static TransformNormal(normal:Vector3,transform:Matrix4x4,result:Vector3):void; + + /** + * 通过矩阵转换一个三维向量到另外一个归一化的三维向量。 + * @param vector 源三维向量。 + * @param transform 变换矩阵。 + * @param result 输出三维向量。 + */ + static transformCoordinate(coordinate:Vector3,transform:Matrix4x4,result:Vector3):void; + + /** + * 求一个指定范围的向量 + * @param value clamp向量 + * @param min 最小 + * @param max 最大 + * @param out 输出向量 + */ + static Clamp(value:Vector3,min:Vector3,max:Vector3,out:Vector3):void; + + /** + * 求两个三维向量的和。 + * @param a left三维向量。 + * @param b right三维向量。 + * @param out 输出向量。 + */ + static add(a:Vector3,b:Vector3,out:Vector3):void; + + /** + * 求两个三维向量的差。 + * @param a left三维向量。 + * @param b right三维向量。 + * @param o out 输出向量。 + */ + static subtract(a:Vector3,b:Vector3,o:Vector3):void; + + /** + * 求两个三维向量的叉乘。 + * @param a left向量。 + * @param b right向量。 + * @param o 输出向量。 + */ + static cross(a:Vector3,b:Vector3,o:Vector3):void; + + /** + * 求两个三维向量的点积。 + * @param a left向量。 + * @param b right向量。 + * @return 点积。 + */ + static dot(a:Vector3,b:Vector3):number; + + /** + * 判断两个三维向量是否相等。 + * @param a 三维向量。 + * @param b 三维向量。 + * @return 是否相等。 + */ + static equals(a:Vector3,b:Vector3):boolean; + + /** + * X轴坐标 + */ + x:number; + + /** + * Y轴坐标 + */ + y:number; + + /** + * Z轴坐标 + */ + z:number; + + /** + * 创建一个 Vector3 实例。 + * @param x X轴坐标。 + * @param y Y轴坐标。 + * @param z Z轴坐标。 + */ + + constructor(x?:number,y?:number,z?:number); + + /** + * 设置xyz值。 + * @param x X值。 + * @param y Y值。 + * @param z Z值。 + */ + setValue(x:number,y:number,z:number):void; + + /** + * 从Array数组拷贝值。 + * @param array 数组。 + * @param offset 数组偏移。 + */ + fromArray(array:any[],offset?:number):void; + + /** + * 写入Array数组 + * @param array 数组。 + * @param offset 数组偏移。 + */ + toArray(array:Float32Array,offset?:number):void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + toDefault():void; + forNativeElement(nativeElements?:Float32Array):void; + } + + /** + * Vector4 类用于创建四维向量。 + */ + class Vector4 implements IClone { + + /** + * 零向量,禁止修改 + */ + static ZERO:Vector4; + static ONE:Vector4; + static UnitX:Vector4; + static UnitY:Vector4; + static UnitZ:Vector4; + static UnitW:Vector4; + + /** + * X轴坐标 + */ + x:number; + + /** + * Y轴坐标 + */ + y:number; + + /** + * Z轴坐标 + */ + z:number; + + /** + * W轴坐标 + */ + w:number; + + /** + * 创建一个 Vector4 实例。 + * @param x X轴坐标。 + * @param y Y轴坐标。 + * @param z Z轴坐标。 + * @param w W轴坐标。 + */ + + constructor(x?:number,y?:number,z?:number,w?:number); + + /** + * 设置xyzw值。 + * @param x X值。 + * @param y Y值。 + * @param z Z值。 + * @param w W值。 + */ + setValue(x:number,y:number,z:number,w:number):void; + + /** + * 从Array数组拷贝值。 + * @param array 数组。 + * @param offset 数组偏移。 + */ + fromArray(array:any[],offset?:number):void; + + /** + * 写入Array数组 + * @param array 数组。 + * @param offset 数组偏移。 + */ + toArray(array:Float32Array,offset?:number):void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + + /** + * 插值四维向量。 + * @param a left向量。 + * @param b right向量。 + * @param t 插值比例。 + * @param out 输出向量。 + */ + static lerp(a:Vector4,b:Vector4,t:number,out:Vector4):void; + + /** + * 通过4x4矩阵把一个四维向量转换为另一个四维向量 + * @param vector4 带转换四维向量。 + * @param M4x4 4x4矩阵。 + * @param out 转换后四维向量。 + */ + static transformByM4x4(vector4:Vector4,m4x4:Matrix4x4,out:Vector4):void; + + /** + * 判断两个四维向量是否相等。 + * @param a 四维向量。 + * @param b 四维向量。 + * @return 是否相等。 + */ + static equals(a:Vector4,b:Vector4):boolean; + + /** + * 求四维向量的长度。 + * @return 长度。 + */ + length():number; + + /** + * 求四维向量长度的平方。 + * @return 长度的平方。 + */ + lengthSquared():number; + + /** + * 归一化四维向量。 + * @param s 源四维向量。 + * @param out 输出四维向量。 + */ + static normalize(s:Vector4,out:Vector4):void; + + /** + * 求两个四维向量的和。 + * @param a 四维向量。 + * @param b 四维向量。 + * @param out 输出向量。 + */ + static add(a:Vector4,b:Vector4,out:Vector4):void; + + /** + * 求两个四维向量的差。 + * @param a 四维向量。 + * @param b 四维向量。 + * @param out 输出向量。 + */ + static subtract(a:Vector4,b:Vector4,out:Vector4):void; + + /** + * 计算两个四维向量的乘积。 + * @param a 四维向量。 + * @param b 四维向量。 + * @param out 输出向量。 + */ + static multiply(a:Vector4,b:Vector4,out:Vector4):void; + + /** + * 缩放四维向量。 + * @param a 源四维向量。 + * @param b 缩放值。 + * @param out 输出四维向量。 + */ + static scale(a:Vector4,b:number,out:Vector4):void; + + /** + * 求一个指定范围的四维向量 + * @param value clamp向量 + * @param min 最小 + * @param max 最大 + * @param out 输出向量 + */ + static Clamp(value:Vector4,min:Vector4,max:Vector4,out:Vector4):void; + + /** + * 两个四维向量距离的平方。 + * @param value1 向量1。 + * @param value2 向量2。 + * @return 距离的平方。 + */ + static distanceSquared(value1:Vector4,value2:Vector4):number; + + /** + * 两个四维向量距离。 + * @param value1 向量1。 + * @param value2 向量2。 + * @return 距离。 + */ + static distance(value1:Vector4,value2:Vector4):number; + + /** + * 求两个四维向量的点积。 + * @param a 向量。 + * @param b 向量。 + * @return 点积。 + */ + static dot(a:Vector4,b:Vector4):number; + + /** + * 分别取两个四维向量x、y、z的最小值计算新的四维向量。 + * @param a 四维向量。 + * @param b 四维向量。 + * @param out 结果三维向量。 + */ + static min(a:Vector4,b:Vector4,out:Vector4):void; + + /** + * 分别取两个四维向量x、y、z的最大值计算新的四维向量。 + * @param a 四维向量。 + * @param b 四维向量。 + * @param out 结果三维向量。 + */ + static max(a:Vector4,b:Vector4,out:Vector4):void; + forNativeElement(nativeElements?:Float32Array):void; + } + + /** + * Viewport 类用于创建视口。 + */ + class Viewport { + + /** + * X轴坐标 + */ + x:number; + + /** + * Y轴坐标 + */ + y:number; + + /** + * 宽度 + */ + width:number; + + /** + * 高度 + */ + height:number; + + /** + * 最小深度 + */ + minDepth:number; + + /** + * 最大深度 + */ + maxDepth:number; + + /** + * 创建一个 Viewport 实例。 + * @param x x坐标。 + * @param y y坐标。 + * @param width 宽度。 + * @param height 高度。 + */ + + constructor(x:number,y:number,width:number,height:number); + + /** + * 投影一个三维向量到视口空间。 + * @param source 三维向量。 + * @param matrix 变换矩阵。 + * @param out x、y、z为视口空间坐标,透视投影下w为相对于变换矩阵的z轴坐标。 + */ + project(source:Vector3,matrix:Matrix4x4,out:Vector4):void; + + /** + * 反变换一个三维向量。 + * @param source 源三维向量。 + * @param matrix 变换矩阵。 + * @param out 输出三维向量。 + */ + unprojectFromMat(source:Vector3,matrix:Matrix4x4,out:Vector3):void; + + /** + * 反变换一个三维向量。 + * @param source 源三维向量。 + * @param projection 透视投影矩阵。 + * @param view 视图矩阵。 + * @param world 世界矩阵,可设置为null。 + * @param out 输出向量。 + */ + unprojectFromWVP(source:Vector3,projection:Matrix4x4,view:Matrix4x4,world:Matrix4x4,out:Vector3):void; + + /** + * 克隆 + * @param out + */ + cloneTo(out:Viewport):void; + } + + /** + * CharacterController 类用于创建角色控制器。 + */ + class CharacterController extends PhysicsComponent { + static UPAXIS_X:number; + static UPAXIS_Y:number; + static UPAXIS_Z:number; + + /** + * 角色降落速度。 + */ + get fallSpeed():number; + set fallSpeed(value:number); + + /** + * 角色跳跃速度。 + */ + get jumpSpeed():number; + set jumpSpeed(value:number); + + /** + * 重力。 + */ + get gravity():Vector3; + set gravity(value:Vector3); + + /** + * 最大坡度。 + */ + get maxSlope():number; + set maxSlope(value:number); + + /** + * 角色是否在地表。 + */ + get isGrounded():boolean; + + /** + * 角色行走的脚步高度,表示可跨越的最大高度。 + */ + get stepHeight():number; + set stepHeight(value:number); + + /** + * 角色的Up轴。 + */ + get upAxis():Vector3; + set upAxis(value:Vector3); + + /** + * 创建一个 CharacterController 实例。 + * @param stepheight 角色脚步高度。 + * @param upAxis 角色Up轴 + * @param collisionGroup 所属碰撞组。 + * @param canCollideWith 可产生碰撞的碰撞组。 + */ + + constructor(stepheight?:number,upAxis?:Vector3,collisionGroup?:number,canCollideWith?:number); + + /** + * 通过指定移动向量移动角色。 + * @param movement 移动向量。 + */ + move(movement:Vector3):void; + + /** + * 跳跃。 + * @param velocity 跳跃速度。 + */ + jump(velocity?:Vector3):void; + } + + /** + * Collision 类用于创建物理碰撞信息。 + */ + class Collision { + + /** + * @readonly + */ + contacts:ContactPoint[]; + + /** + * @readonly + */ + other:PhysicsComponent; + + /** + * 创建一个 Collision 实例。 + */ + + constructor(); + } + + /** + * CollisionMap 类用于实现碰撞组合实例图。 + */ + class CollisionTool { + + /** + * 创建一个 CollisionMap 实例。 + */ + + constructor(); + } + + /** + * ... + * @author ... + */ + class Constraint3D { + + /** + * 获取刚体A。[只读] + */ + rigidbodyA:Rigidbody3D; + + /** + * 获取刚体A。[只读] + */ + rigidbodyB:Rigidbody3D; + + constructor(); + } + + /** + * ConfigurableConstraint类用于可设置的约束组件 + */ + class ConfigurableConstraint extends ConstraintComponent { + + /** + * 约束限制模式 完全限制 + */ + static CONFIG_MOTION_TYPE_LOCKED:number; + + /** + * 约束限制模式 范围限制 + */ + static CONFIG_MOTION_TYPE_LIMITED:number; + + /** + * 约束限制模式 不限制 + */ + static CONFIG_MOTION_TYPE_FREE:number; + + /** + * 创建一个ConfigurableConstraint实例 可设置的约束组件 + */ + + constructor(); + + /** + * 主轴 + */ + get axis():Vector3; + + /** + * 副轴 + */ + get secondaryAxis():Vector3; + + /** + * 旋转角度最大值 + */ + set maxAngularLimit(value:Vector3); + + /** + * 旋转角度最小值 + */ + set minAngularLimit(value:Vector3); + get maxAngularLimit():Vector3; + get minAngularLimit():Vector3; + + /** + * 最大线性位置 + */ + set maxLinearLimit(value:Vector3); + + /** + * 最小线性位置 + */ + set minLinearLimit(value:Vector3); + get maxLinearLimit():Vector3; + get minLinearLimit():Vector3; + + /** + * X轴线性约束模式 + */ + set XMotion(value:number); + get XMotion():number; + + /** + * Y轴线性约束模式 + */ + set YMotion(value:number); + get YMotion():number; + + /** + * Z轴线性约束模式 + */ + set ZMotion(value:number); + get ZMotion():number; + + /** + * X轴旋转约束模式 + */ + set angularXMotion(value:number); + get angularXMotion():number; + + /** + * Y轴旋转约束模式 + */ + set angularYMotion(value:number); + get angularYMotion():number; + + /** + * Z轴旋转约束模式 + */ + set angularZMotion(value:number); + get angularZMotion():number; + + /** + * 线性弹簧 + */ + set linearLimitSpring(value:Vector3); + get linearLimitSpring():Vector3; + + /** + * 角度弹簧 + */ + set angularLimitSpring(value:Vector3); + get angularLimitSpring():Vector3; + + /** + * 线性弹力 + */ + set linearBounce(value:Vector3); + get linearBounce():Vector3; + + /** + * 角度弹力 + */ + set angularBounce(value:Vector3); + get angularBounce():Vector3; + + /** + * 线性阻力 + */ + set linearDamp(value:Vector3); + get linearDamp():Vector3; + + /** + * 角度阻力 + */ + set angularDamp(value:Vector3); + get angularDamp():Vector3; + + /** + * 设置锚点 + */ + set anchor(value:Vector3); + get anchor():Vector3; + + /** + * 设置链接锚点 + */ + set connectAnchor(value:Vector3); + get connectAnchor():Vector3; + + /** + * 设置对象自然旋转的局部轴主轴,axis2为副轴 + * @param axis1 + * @param axis2 + */ + setAxis(axis:Vector3,secondaryAxis:Vector3):void; + _initAllConstraintInfo():void; + _onDisable():void; + } + + /** + * ConstraintComponent 类用于创建约束的父类。 + */ + class ConstraintComponent extends Component { + + /** + * @inheritDoc + * @override + */ + get enabled():boolean; + + /** + * @inheritDoc + * @override + */ + set enabled(value:boolean); + + /** + * 获取应用的冲力。 + */ + get appliedImpulse():number; + + /** + * 获取连接的刚体B。 + * @return 已连接刚体B。 + */ + get connectedBody():Rigidbody3D; + + /** + * 获取连接的刚体A。 + * @return 已连接刚体A。 + */ + get ownBody():Rigidbody3D; + + /** + * 获得收到的总力 + */ + get currentForce():Vector3; + + /** + * 获取的总力矩 + */ + get currentTorque():Vector3; + + /** + * 设置最大承受力 + * @param value 最大承受力 + */ + get breakForce():number; + set breakForce(value:number); + + /** + * 设置最大承受力矩 + * @param value 最大承受力矩 + */ + get breakTorque():number; + set breakTorque(value:number); + + /** + * 设置锚点 + */ + set anchor(value:Vector3); + get anchor():Vector3; + + /** + * 设置链接锚点 + */ + set connectAnchor(value:Vector3); + get connectAnchor():Vector3; + + /** + * 创建一个 ConstraintComponent 实例。 + */ + + constructor(constraintType:number); + + /** + * 设置迭代的次数,次数越高,越精确 + * @param overideNumIterations + */ + setOverrideNumSolverIterations(overideNumIterations:number):void; + + /** + * 设置约束是否可用 + * @param enable + */ + setConstraintEnabled(enable:boolean):void; + _onDisable():void; + + /** + * 设置约束刚体 + * @param ownerRigid + * @param connectRigidBody + * @override + */ + setConnectRigidBody(ownerRigid:Rigidbody3D,connectRigidBody:Rigidbody3D):void; + + /** + * 获得当前力 + * @param out + */ + getcurrentForce(out:Vector3):void; + + /** + * 获得当前力矩 + * @param out + */ + getcurrentTorque(out:Vector3):void; + } + class FixedConstraint extends ConstraintComponent { + + /** + * 创建一个FixedConstraint实例 + */ + + constructor(); + _onDisable():void; + } + + /** + * ContactPoint 类用于创建物理碰撞信息。 + */ + class ContactPoint { + + /** + * 碰撞器A。 + */ + colliderA:PhysicsComponent; + + /** + * 碰撞器B。 + */ + colliderB:PhysicsComponent; + + /** + * 距离。 + */ + distance:number; + + /** + * 法线。 + */ + normal:Vector3; + + /** + * 碰撞器A的碰撞点。 + */ + positionOnA:Vector3; + + /** + * 碰撞器B的碰撞点。 + */ + positionOnB:Vector3; + + /** + * 创建一个 ContactPoint 实例。 + */ + + constructor(); + } + + /** + * HitResult 类用于实现射线检测或形状扫描的结果。 + */ + class HitResult { + + /** + * 是否成功。 + */ + succeeded:boolean; + + /** + * 发生碰撞的碰撞组件。 + */ + collider:PhysicsComponent; + + /** + * 碰撞点。 + */ + point:Vector3; + + /** + * 碰撞法线。 + */ + normal:Vector3; + + /** + * 碰撞分数。 + */ + hitFraction:number; + + /** + * 创建一个 HitResult 实例。 + */ + + constructor(); + } + + /** + * PhysicsCollider 类用于创建物理碰撞器。 + */ + class PhysicsCollider extends PhysicsTriggerComponent { + + /** + * 创建一个 PhysicsCollider 实例。 + * @param collisionGroup 所属碰撞组。 + * @param canCollideWith 可产生碰撞的碰撞组。 + */ + + constructor(collisionGroup?:number,canCollideWith?:number); + } + + /** + * PhysicsComponent 类用于创建物理组件的父类。 + */ + class PhysicsComponent extends Component { + + /** + * 是否可以缩放Shape。 + */ + canScaleShape:boolean; + + /** + * 弹力。 + */ + get restitution():number; + set restitution(value:number); + + /** + * 摩擦力。 + */ + get friction():number; + set friction(value:number); + + /** + * 滚动摩擦力。 + */ + get rollingFriction():number; + set rollingFriction(value:number); + + /** + * 用于连续碰撞检测(CCD)的速度阈值,当物体移动速度小于该值时不进行CCD检测,防止快速移动物体(例如:子弹)错误的穿过其它物体,0表示禁止。 + */ + get ccdMotionThreshold():number; + set ccdMotionThreshold(value:number); + + /** + * 获取用于进入连续碰撞检测(CCD)范围的球半径。 + */ + get ccdSweptSphereRadius():number; + set ccdSweptSphereRadius(value:number); + + /** + * 获取是否激活。 + */ + get isActive():boolean; + + /** + * 碰撞形状。 + */ + get colliderShape():ColliderShape; + set colliderShape(value:ColliderShape); + + /** + * 模拟器。 + */ + get simulation():PhysicsSimulation; + + /** + * 所属碰撞组。 + */ + get collisionGroup():number; + set collisionGroup(value:number); + + /** + * 可碰撞的碰撞组,基于位运算。 + */ + get canCollideWith():number; + set canCollideWith(value:number); + + /** + * 创建一个 PhysicsComponent 实例。 + * @param collisionGroup 所属碰撞组。 + * @param canCollideWith 可产生碰撞的碰撞组。 + */ + + constructor(collisionGroup:number,canCollideWith:number); + } + + /** + * PhysicsSettings 类用于创建物理配置信息。 + */ + class PhysicsSettings { + + /** + * 标志集合。 + */ + flags:number; + + /** + * 物理引擎在一帧中用于补偿减速的最大次数。 + */ + maxSubSteps:number; + + /** + * 物理模拟器帧的间隔时间。 + */ + fixedTimeStep:number; + + /** + * 创建一个 PhysicsSettings 实例。 + */ + + constructor(); + } + + /** + * Simulation 类用于创建物理模拟器。 + */ + class PhysicsSimulation { + static disableSimulation:boolean; + + /** + * 创建限制刚体运动的约束条件。 + */ + static createConstraint():void; + + /** + * 物理引擎在一帧中用于补偿减速的最大次数:模拟器每帧允许的最大模拟次数,如果引擎运行缓慢,可能需要增加该次数,否则模拟器会丢失“时间",引擎间隔时间小于maxSubSteps*fixedTimeStep非常重要。 + */ + maxSubSteps:number; + + /** + * 物理模拟器帧的间隔时间:通过减少fixedTimeStep可增加模拟精度,默认是1.0 / 60.0。 + */ + fixedTimeStep:number; + + /** + * 是否进行连续碰撞检测。 + */ + get continuousCollisionDetection():boolean; + set continuousCollisionDetection(value:boolean); + + /** + * 获取重力。 + */ + get gravity():Vector3; + set gravity(value:Vector3); + + /** + * 射线检测第一个碰撞物体。 + * @param from 起始位置。 + * @param to 结束位置。 + * @param out 碰撞结果。 + * @param collisonGroup 射线所属碰撞组。 + * @param collisionMask 与射线可产生碰撞的组。 + * @return 是否成功。 + */ + raycastFromTo(from:Vector3,to:Vector3,out?:HitResult,collisonGroup?:number,collisionMask?:number):boolean; + + /** + * 射线检测所有碰撞的物体。 + * @param from 起始位置。 + * @param to 结束位置。 + * @param out 碰撞结果[数组元素会被回收]。 + * @param collisonGroup 射线所属碰撞组。 + * @param collisionMask 与射线可产生碰撞的组。 + * @return 是否成功。 + */ + raycastAllFromTo(from:Vector3,to:Vector3,out:HitResult[],collisonGroup?:number,collisionMask?:number):boolean; + + /** + * 射线检测第一个碰撞物体。 + * @param ray 射线 + * @param outHitInfo 与该射线发生碰撞的第一个碰撞器的碰撞信息 + * @param distance 射线长度,默认为最大值 + * @param collisonGroup 射线所属碰撞组。 + * @param collisionMask 与射线可产生碰撞的组。 + * @return 是否检测成功。 + */ + rayCast(ray:Ray,outHitResult?:HitResult,distance?:number,collisonGroup?:number,collisionMask?:number):boolean; + + /** + * 射线检测所有碰撞的物体。 + * @param ray 射线 + * @param out 碰撞结果[数组元素会被回收]。 + * @param distance 射线长度,默认为最大值 + * @param collisonGroup 射线所属碰撞组。 + * @param collisionMask 与射线可产生碰撞的组。 + * @return 是否检测成功。 + */ + rayCastAll(ray:Ray,out:HitResult[],distance?:number,collisonGroup?:number,collisionMask?:number):boolean; + + /** + * 形状检测第一个碰撞的物体。 + * @param shape 形状。 + * @param fromPosition 世界空间起始位置。 + * @param toPosition 世界空间结束位置。 + * @param out 碰撞结果。 + * @param fromRotation 起始旋转。 + * @param toRotation 结束旋转。 + * @param collisonGroup 射线所属碰撞组。 + * @param collisionMask 与射线可产生碰撞的组。 + * @return 是否成功。 + */ + shapeCast(shape:ColliderShape,fromPosition:Vector3,toPosition:Vector3,out?:HitResult,fromRotation?:Quaternion,toRotation?:Quaternion,collisonGroup?:number,collisionMask?:number,allowedCcdPenetration?:number):boolean; + + /** + * 形状检测所有碰撞的物体。 + * @param shape 形状。 + * @param fromPosition 世界空间起始位置。 + * @param toPosition 世界空间结束位置。 + * @param out 碰撞结果[数组元素会被回收]。 + * @param fromRotation 起始旋转。 + * @param toRotation 结束旋转。 + * @param collisonGroup 射线所属碰撞组。 + * @param collisionMask 与射线可产生碰撞的组。 + * @return 是否成功。 + */ + shapeCastAll(shape:ColliderShape,fromPosition:Vector3,toPosition:Vector3,out:HitResult[],fromRotation?:Quaternion,toRotation?:Quaternion,collisonGroup?:number,collisionMask?:number,allowedCcdPenetration?:number):boolean; + + /** + * 添加刚体运动的约束条件。 + * @param constraint 约束。 + * @param disableCollisionsBetweenLinkedBodies 是否禁用 + */ + addConstraint(constraint:ConstraintComponent,disableCollisionsBetweenLinkedBodies?:boolean):void; + + /** + * 移除刚体运动的约束条件。 + */ + removeConstraint(constraint:ConstraintComponent):void; + + /** + * 设置射线检测回调 + * @param HITSRAYRESULTCALLBACK_FLAG值 + */ + setHitsRayResultCallbackFlag(flag?:number):void; + + /** + * 清除力。 + */ + clearForces():void; + } + + /** + * PhysicsTriggerComponent 类用于创建物理触发器组件。 + */ + class PhysicsTriggerComponent extends PhysicsComponent { + + /** + * 是否为触发器。 + */ + get isTrigger():boolean; + set isTrigger(value:boolean); + + /** + * 创建一个 PhysicsTriggerComponent 实例。 + * @param collisionGroup 所属碰撞组。 + * @param canCollideWith 可产生碰撞的碰撞组。 + */ + + constructor(collisionGroup:number,canCollideWith:number); + } + + /** + * PhysicsUpdateList 类用于实现物理更新队列。 + */ + class PhysicsUpdateList extends SingletonList { + + /** + * 创建一个新的 PhysicsUpdateList 实例。 + */ + + constructor(); + } + + /** + * Rigidbody3D 类用于创建刚体碰撞器。 + */ + class Rigidbody3D extends PhysicsTriggerComponent { + static TYPE_STATIC:number; + static TYPE_DYNAMIC:number; + static TYPE_KINEMATIC:number; + + /** + * 质量。 + */ + get mass():number; + set mass(value:number); + + /** + * 是否为运动物体,如果为true仅可通过transform属性移动物体,而非其他力相关属性。 + */ + get isKinematic():boolean; + set isKinematic(value:boolean); + + /** + * 刚体的线阻力。 + */ + get linearDamping():number; + set linearDamping(value:number); + + /** + * 刚体的角阻力。 + */ + get angularDamping():number; + set angularDamping(value:number); + + /** + * 是否重载重力。 + */ + get overrideGravity():boolean; + set overrideGravity(value:boolean); + + /** + * 重力。 + */ + get gravity():Vector3; + set gravity(value:Vector3); + + /** + * 总力。 + */ + get totalForce():Vector3; + + /** + * 每个轴的线性运动缩放因子,如果某一轴的值为0表示冻结在该轴的线性运动。 + */ + get linearFactor():Vector3; + set linearFactor(value:Vector3); + + /** + * 线速度 + */ + get linearVelocity():Vector3; + set linearVelocity(value:Vector3); + + /** + * 每个轴的角度运动缩放因子,如果某一轴的值为0表示冻结在该轴的角度运动。 + */ + get angularFactor():Vector3; + set angularFactor(value:Vector3); + + /** + * 角速度。 + */ + get angularVelocity():Vector3; + set angularVelocity(value:Vector3); + + /** + * 刚体所有扭力。 + */ + get totalTorque():Vector3; + + /** + * 是否进行碰撞检测。 + */ + get detectCollisions():boolean; + set detectCollisions(value:boolean); + + /** + * 是否处于睡眠状态。 + */ + get isSleeping():boolean; + + /** + * 刚体睡眠的线速度阈值。 + */ + get sleepLinearVelocity():number; + set sleepLinearVelocity(value:number); + + /** + * 刚体睡眠的角速度阈值。 + */ + get sleepAngularVelocity():number; + set sleepAngularVelocity(value:number); + get btColliderObject():number; + + /** + * 创建一个 RigidBody3D 实例。 + * @param collisionGroup 所属碰撞组。 + * @param canCollideWith 可产生碰撞的碰撞组。 + */ + + constructor(collisionGroup?:number,canCollideWith?:number); + + /** + * 应用作用力。 + * @param force 作用力。 + * @param localOffset 偏移,如果为null则为中心点 + */ + applyForce(force:Vector3,localOffset?:Vector3):void; + + /** + * 应用扭转力。 + * @param torque 扭转力。 + */ + applyTorque(torque:Vector3):void; + + /** + * 应用冲量。 + * @param impulse 冲量。 + * @param localOffset 偏移,如果为null则为中心点。 + */ + applyImpulse(impulse:Vector3,localOffset?:Vector3):void; + + /** + * 应用扭转冲量。 + * @param torqueImpulse + */ + applyTorqueImpulse(torqueImpulse:Vector3):void; + + /** + * 唤醒刚体。 + */ + wakeUp():void; + + /** + * 清除应用到刚体上的所有力。 + */ + clearForces():void; + } + + /** + * BoxColliderShape 类用于创建盒子形状碰撞器。 + */ + class BoxColliderShape extends ColliderShape { + + /** + * X轴尺寸。 + */ + get sizeX():number; + + /** + * Y轴尺寸。 + */ + get sizeY():number; + + /** + * Z轴尺寸。 + */ + get sizeZ():number; + + /** + * 创建一个新的 BoxColliderShape 实例。 + * @param sizeX 盒子X轴尺寸。 + * @param sizeY 盒子Y轴尺寸。 + * @param sizeZ 盒子Z轴尺寸。 + */ + + constructor(sizeX?:number,sizeY?:number,sizeZ?:number); + + /** + * @inheritDoc + * @override + */ + clone():any; + } + + /** + * CapsuleColliderShape 类用于创建胶囊形状碰撞器。 + */ + class CapsuleColliderShape extends ColliderShape { + + /** + * 半径。 + */ + get radius():number; + + /** + * 长度。 + */ + get length():number; + + /** + * 方向。 + */ + get orientation():number; + + /** + * 创建一个新的 CapsuleColliderShape 实例。 + * @param 半径 。 + * @param 高 (包含半径)。 + * @param orientation 胶囊体方向。 + */ + + constructor(radius?:number,length?:number,orientation?:number); + + /** + * @inheritDoc + * @override + */ + clone():any; + } + + /** + * ColliderShape 类用于创建形状碰撞器的父类,该类为抽象类。 + */ + class ColliderShape implements IClone { + + /** + * 形状方向_X轴正向 + */ + static SHAPEORIENTATION_UPX:number; + + /** + * 形状方向_Y轴正向 + */ + static SHAPEORIENTATION_UPY:number; + + /** + * 形状方向_Z轴正向 + */ + static SHAPEORIENTATION_UPZ:number; + needsCustomCollisionCallback:boolean; + + /** + * 碰撞类型。 + */ + get type():number; + + /** + * Shape的本地偏移。 + */ + get localOffset():Vector3; + set localOffset(value:Vector3); + + /** + * Shape的本地旋转。 + */ + get localRotation():Quaternion; + set localRotation(value:Quaternion); + + /** + * 创建一个新的 ColliderShape 实例。 + */ + + constructor(); + + /** + * 更新本地偏移,如果修改LocalOffset或LocalRotation需要调用。 + */ + updateLocalTransformations():void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + + /** + * 销毁。 + */ + destroy():void; + } + + /** + * CompoundColliderShape 类用于创建组合碰撞器。 + */ + class CompoundColliderShape extends ColliderShape { + + /** + * 创建一个新的 CompoundColliderShape 实例。 + */ + + constructor(); + + /** + * 添加子碰撞器形状。 + * @param shape 子碰撞器形状。 + */ + addChildShape(shape:ColliderShape):void; + + /** + * 移除子碰撞器形状。 + * @param shape 子碰撞器形状。 + */ + removeChildShape(shape:ColliderShape):void; + + /** + * 清空子碰撞器形状。 + */ + clearChildShape():void; + + /** + * 获取子形状数量。 + * @return + */ + getChildShapeCount():number; + + /** + * @inheritDoc + * @override + */ + cloneTo(destObject:any):void; + + /** + * @inheritDoc + * @override + */ + clone():any; + + /** + * @inheritDoc + * @override + */ + destroy():void; + } + + /** + * ConeColliderShape 类用于创建圆锥碰撞器。 + */ + class ConeColliderShape extends ColliderShape { + private _orientation:any; + private _radius:any; + private _height:any; + + /** + * 半径。 + */ + get radius():number; + + /** + * 高度。 + */ + get height():number; + + /** + * 方向。 + */ + get orientation():number; + + /** + * 创建一个新的 ConeColliderShape 实例。 + * @param height 高。 + * @param radius 半径。 + */ + + constructor(radius?:number,height?:number,orientation?:number); + + /** + * 克隆 + * @inheritDoc + * @override + * @returns 克隆的ConeColliderShape实例 + */ + clone():any; + } + + /** + * CylinderColliderShape 类用于创建圆柱碰撞器。 + */ + class CylinderColliderShape extends ColliderShape { + private _orientation:any; + private _radius:any; + private _height:any; + + /** + * 半径。 + */ + get radius():number; + + /** + * 高度。 + */ + get height():number; + + /** + * 方向。 + */ + get orientation():number; + + /** + * 创建一个新的 CylinderColliderShape 实例。 + * @param height 高。 + * @param radius 半径。 + */ + + constructor(radius?:number,height?:number,orientation?:number); + + /** + * @inheritDoc + * @override + */ + clone():any; + } + + /** + * MeshColliderShape 类用于创建网格碰撞器。 + */ + class MeshColliderShape extends ColliderShape { + + /** + * 网格。 + */ + get mesh():Mesh; + set mesh(value:Mesh); + + /** + * 是否使用凸多边形。 + */ + get convex():boolean; + set convex(value:boolean); + + /** + * 创建一个新的 MeshColliderShape 实例。 + */ + + constructor(); + + /** + * @inheritDoc + * @override + */ + cloneTo(destObject:any):void; + + /** + * @inheritDoc + * @override + */ + clone():any; + } + + /** + * SphereColliderShape 类用于创建球形碰撞器。 + */ + class SphereColliderShape extends ColliderShape { + + /** + * 半径。 + */ + get radius():number; + + /** + * 创建一个新的 SphereColliderShape 实例。 + * @param radius 半径。 + */ + + constructor(radius?:number); + + /** + * @inheritDoc + * @override + */ + clone():any; + } + + /** + * StaticPlaneColliderShape 类用于创建静态平面碰撞器。 + */ + class StaticPlaneColliderShape extends ColliderShape { + + /** + * 创建一个新的 StaticPlaneColliderShape 实例。 + */ + + constructor(normal:Vector3,offset:number); + + /** + * @inheritDoc + * @override + */ + clone():any; + } + + /** + * Laya物理类 + * internal + */ + class Physics3D { + } + + /** + * Collision 类用于创建物理碰撞信息。 + */ + class CannonCollision { + + /** + * @readonly + */ + contacts:CannonContactPoint[]; + + /** + * @readonly + */ + other:CannonPhysicsComponent; + + /** + * 创建一个 Collision 实例。 + */ + + constructor(); + } + + /** + * CollisionMap 类用于实现碰撞组合实例图。 + */ + class CannonCollisionTool { + + /** + * 创建一个 CollisionMap 实例。 + */ + + constructor(); + } + + /** + * ContactPoint 类用于创建物理碰撞信息。 + */ + class CannonContactPoint { + + /** + * 碰撞器A。 + */ + colliderA:CannonPhysicsComponent; + + /** + * 碰撞器B。 + */ + colliderB:CannonPhysicsComponent; + + /** + * 距离。 + */ + distance:number; + + /** + * 法线。 + */ + normal:Vector3; + + /** + * 碰撞器A的碰撞点。 + */ + positionOnA:Vector3; + + /** + * 碰撞器B的碰撞点。 + */ + positionOnB:Vector3; + + /** + * 创建一个 ContactPoint 实例。 + */ + + constructor(); + } + + /** + * HitResult 类用于实现射线检测或形状扫描的结果。 + */ + class CannonHitResult { + + /** + * 是否成功。 + */ + succeeded:boolean; + + /** + * 发生碰撞的碰撞组件。 + */ + collider:CannonPhysicsComponent; + + /** + * 碰撞点。 + */ + point:Vector3; + + /** + * 碰撞法线。 + */ + normal:Vector3; + + /** + * 碰撞分数。 + */ + hitFraction:number; + + /** + * 创建一个 HitResult 实例。 + */ + + constructor(); + } + + /** + * PhysicsCollider 类用于创建物理碰撞器。 + */ + class CannonPhysicsCollider extends CannonPhysicsTriggerComponent { + + /** + * 创建一个 PhysicsCollider 实例。 + * @param collisionGroup 所属碰撞组。 + * @param canCollideWith 可产生碰撞的碰撞组。 + */ + + constructor(collisionGroup?:number,canCollideWith?:number); + } + + /** + * PhysicsComponent 类用于创建物理组件的父类。 + */ + class CannonPhysicsComponent extends Component { + + /** + * 是否可以缩放Shape。 + */ + canScaleShape:boolean; + + /** + * 弹力。 + */ + get restitution():number; + set restitution(value:number); + + /** + * 摩擦力。 + */ + get friction():number; + set friction(value:number); + + /** + * 碰撞形状。 + */ + get colliderShape():CannonColliderShape; + set colliderShape(value:CannonColliderShape); + + /** + * 模拟器。 + */ + get simulation():CannonPhysicsSimulation; + + /** + * 所属碰撞组。 + */ + get collisionGroup():number; + set collisionGroup(value:number); + + /** + * 可碰撞的碰撞组,基于位运算。 + */ + get canCollideWith():number; + set canCollideWith(value:number); + + /** + * 创建一个 PhysicsComponent 实例。 + * @param collisionGroup 所属碰撞组。 + * @param canCollideWith 可产生碰撞的碰撞组。 + */ + + constructor(collisionGroup:number,canCollideWith:number); + } + + /** + * PhysicsSettings 类用于创建物理配置信息。 + */ + class CannonPhysicsSettings { + + /** + * 标志集合。 + */ + flags:number; + + /** + * 物理引擎在一帧中用于补偿减速的最大次数。 + */ + maxSubSteps:number; + + /** + * 物理模拟器帧的间隔时间。 + */ + fixedTimeStep:number; + + /** + * 物理松弛系数 + */ + contactEquationRelaxation:number; + + /** + * 刚度系数 + */ + contactEquationStiffness:number; + + /** + * 创建一个 PhysicsSettings 实例。 + */ + + constructor(); + } + + /** + * Simulation 类用于创建物理模拟器。 + */ + class CannonPhysicsSimulation { + private static _cannonPhysicsSimulation:any; + static disableSimulation:boolean; + + /** + * 创建限制刚体运动的约束条件。 + */ + static createConstraint():void; + + /** + * 物理引擎在一帧中用于补偿减速的最大次数:模拟器每帧允许的最大模拟次数,如果引擎运行缓慢,可能需要增加该次数,否则模拟器会丢失“时间",引擎间隔时间小于maxSubSteps*fixedTimeStep非常重要。 + */ + maxSubSteps:number; + + /** + * 物理模拟器帧的间隔时间:通过减少fixedTimeStep可增加模拟精度,默认是1.0 / 60.0。 + */ + fixedTimeStep:number; + + /** + * 获取重力。 + */ + get gravity():Vector3; + set gravity(value:Vector3); + + /** + * 获取重力。 + */ + get solverIterations():number; + set solverIterations(value:number); + + /** + * 射线检测第一个碰撞物体。 + * @param from 起始位置。 + * @param to 结束位置。 + * @param out 碰撞结果。 + * @param collisonGroup 射线所属碰撞组。 + * @param collisionMask 与射线可产生碰撞的组。 + * @return 是否成功。 + */ + raycastFromTo(from:Vector3,to:Vector3,out?:CannonHitResult,collisonGroup?:number,collisionMask?:number):boolean; + + /** + * 射线检测所有碰撞的物体。 + * @param from 起始位置。 + * @param to 结束位置。 + * @param out 碰撞结果[数组元素会被回收]。 + * @param collisonGroup 射线所属碰撞组。 + * @param collisionMask 与射线可产生碰撞的组。 + * @return 是否成功。 + */ + raycastAllFromTo(from:Vector3,to:Vector3,out:CannonHitResult[],collisonGroup?:number,collisionMask?:number):boolean; + + /** + * 射线检测第一个碰撞物体。 + * @param ray 射线 + * @param outHitInfo 与该射线发生碰撞的第一个碰撞器的碰撞信息 + * @param distance 射线长度,默认为最大值 + * @param collisonGroup 射线所属碰撞组。 + * @param collisionMask 与射线可产生碰撞的组。 + * @return 是否检测成功。 + */ + rayCast(ray:Ray,outHitResult?:CannonHitResult,distance?:number,collisonGroup?:number,collisionMask?:number):boolean; + + /** + * 射线检测所有碰撞的物体。 + * @param ray 射线 + * @param out 碰撞结果[数组元素会被回收]。 + * @param distance 射线长度,默认为最大值 + * @param collisonGroup 射线所属碰撞组。 + * @param collisionMask 与射线可产生碰撞的组。 + * @return 是否检测成功。 + */ + rayCastAll(ray:Ray,out:CannonHitResult[],distance?:number,collisonGroup?:number,collisionMask?:number):boolean; + + /** + * 清除力。 + */ + clearForces():void; + } + + /** + * PhysicsTriggerComponent 类用于创建物理触发器组件。 + */ + class CannonPhysicsTriggerComponent extends CannonPhysicsComponent { + + /** + * 是否为触发器。 + */ + get isTrigger():boolean; + set isTrigger(value:boolean); + + /** + * 创建一个 PhysicsTriggerComponent 实例。 + * @param collisionGroup 所属碰撞组。 + * @param canCollideWith 可产生碰撞的碰撞组。 + */ + + constructor(collisionGroup:number,canCollideWith:number); + } + + /** + * PhysicsUpdateList 类用于实现物理更新队列。 + */ + class CannonPhysicsUpdateList extends SingletonList { + + /** + * 创建一个新的 PhysicsUpdateList 实例。 + */ + + constructor(); + } + + /** + * Rigidbody3D 类用于创建刚体碰撞器。 + */ + class CannonRigidbody3D extends CannonPhysicsCollider { + static TYPE_STATIC:number; + static TYPE_DYNAMIC:number; + static TYPE_KINEMATIC:number; + + /** + * 质量。 + */ + get mass():number; + set mass(value:number); + + /** + * 是否为运动物体,如果为true仅可通过transform属性移动物体,而非其他力相关属性。 + */ + get isKinematic():boolean; + set isKinematic(value:boolean); + + /** + * 刚体的线阻力。 + */ + get linearDamping():number; + set linearDamping(value:number); + + /** + * 刚体的角阻力。 + */ + get angularDamping():number; + set angularDamping(value:number); + + /** + * 总力。 + */ + get totalForce():Vector3; + + /** + * 线速度 + */ + get linearVelocity():Vector3; + set linearVelocity(value:Vector3); + + /** + * 角速度。 + */ + get angularVelocity():Vector3; + set angularVelocity(value:Vector3); + + /** + * 刚体所有扭力。 + */ + get totalTorque():Vector3; + + /** + * 是否处于睡眠状态。 + */ + get isSleeping():boolean; + + /** + * 刚体睡眠的线速度阈值。 + */ + get sleepLinearVelocity():number; + set sleepLinearVelocity(value:number); + get btColliderObject():CANNON.Body; + + /** + * 创建一个 RigidBody3D 实例。 + * @param collisionGroup 所属碰撞组。 + * @param canCollideWith 可产生碰撞的碰撞组。 + */ + + constructor(collisionGroup?:number,canCollideWith?:number); + + /** + * 应用作用力。 + * @param force 作用力。 + * @param localOffset 偏移,如果为null则为中心点 + */ + applyForce(force:Vector3,localOffset?:Vector3):void; + + /** + * 应用扭转力。 + * @param torque 扭转力。 + */ + applyTorque(torque:Vector3):void; + + /** + * 应用冲量。 + * @param impulse 冲量。 + * @param localOffset 偏移,如果为null则为中心点。 + */ + applyImpulse(impulse:Vector3,localOffset?:Vector3):void; + + /** + * 唤醒刚体。 + */ + wakeUp():void; + + /** + * 清除应用到刚体上的所有力。 + */ + clearForces():void; + } + + /** + * BoxColliderShape 类用于创建盒子形状碰撞器。 + */ + class CannonBoxColliderShape extends CannonColliderShape { + + /** + * X轴尺寸。 + */ + get sizeX():number; + + /** + * Y轴尺寸。 + */ + get sizeY():number; + + /** + * Z轴尺寸。 + */ + get sizeZ():number; + + /** + * 创建一个新的 BoxColliderShape 实例。 + * @param sizeX 盒子X轴尺寸。 + * @param sizeY 盒子Y轴尺寸。 + * @param sizeZ 盒子Z轴尺寸。 + */ + + constructor(sizeX?:number,sizeY?:number,sizeZ?:number); + + /** + * @inheritDoc + * @override + */ + _setScale(scale:Vector3):void; + + /** + * @inheritDoc + * @override + */ + clone():any; + } + + /** + * ColliderShape 类用于创建形状碰撞器的父类,该类为抽象类。 + */ + class CannonColliderShape implements IClone { + + /** + * 形状方向_X轴正向 + */ + static SHAPEORIENTATION_UPX:number; + + /** + * 形状方向_Y轴正向 + */ + static SHAPEORIENTATION_UPY:number; + + /** + * 形状方向_Z轴正向 + */ + static SHAPEORIENTATION_UPZ:number; + needsCustomCollisionCallback:boolean; + + /** + * 碰撞类型。 + */ + get type():number; + + /** + * Shape的本地偏移。 + */ + get localOffset():Vector3; + set localOffset(value:Vector3); + + /** + * Shape的本地旋转。 + */ + get localRotation():Quaternion; + set localRotation(value:Quaternion); + + /** + * 创建一个新的 ColliderShape 实例。 + */ + + constructor(); + + /** + * 更新本地偏移,如果修改LocalOffset或LocalRotation需要调用。 + */ + updateLocalTransformations():void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + + /** + * 销毁。 + */ + destroy():void; + } + + /** + * CompoundColliderShape 类用于创建盒子形状碰撞器。 + */ + class CannonCompoundColliderShape extends CannonColliderShape { + private static _tempCannonQue:any; + private static _tempCannonVec:any; + private physicColliderObject:any; + + /** + * 创建一个新的 CompoundColliderShape 实例。 + */ + + constructor(); + addChildShape(shape:CannonColliderShape,localOffset?:Vector3):void; + + /** + * 移除子碰撞器形状。 + * @param shape 子碰撞器形状。 + */ + removeChildShape(shape:CannonColliderShape):void; + bindRigidBody(rigidbody:CannonPhysicsComponent):void; + + /** + * @inheritDoc + * @override + */ + _setScale(scale:Vector3):void; + + /** + * 获取子形状数量。 + * @return + */ + getChildShapeCount():number; + + /** + * @inheritDoc + * @override + */ + cloneTo(destObject:any):void; + + /** + * @inheritDoc + * @override + */ + clone():any; + + /** + * @inheritDoc + * @override + */ + destroy():void; + } + + /** + * SphereColliderShape 类用于创建球形碰撞器。 + */ + class CannonSphereColliderShape extends CannonColliderShape { + + /** + * 半径。 + */ + get radius():number; + + /** + * 创建一个新的 SphereColliderShape 实例。 + * @param radius 半径。 + */ + + constructor(radius?:number); + + /** + * @inheritDoc + * @override + */ + _setScale(scale:Vector3):void; + + /** + * @inheritDoc + * @override + */ + clone():any; + } + + interface IReferenceCounter{ + + /** + * 获得引用计数 + */ + _getReferenceCount():number; + + /** + * 增加引用计数 + */ + _addReference(count:number):void; + + /** + * 删除引用计数 + */ + _removeReference(count:number):void; + + /** + * 清除引用计数 + */ + _clearReference():void; + } + + + /** + * Mesh 类用于创建文件网格数据模板。 + */ + class Mesh extends Resource implements IClone { + + /** + * Mesh资源。 + */ + static MESH:string; + static MESH_INSTANCEBUFFER_TYPE_NORMAL:number; + static MESH_INSTANCEBUFFER_TYPE_SIMPLEANIMATOR:number; + + /** + * 加载网格模板。 + * @param url 模板地址。 + * @param complete 完成回调。 + */ + static load(url:string,complete:Handler):void; + + /** + * 网格的全局默认绑定动作逆矩阵。 + */ + get inverseAbsoluteBindPoses():Matrix4x4[]; + + /** + * 获取顶点个数。 + */ + get vertexCount():number; + + /** + * 获取索引个数。 + */ + get indexCount():number; + + /** + * SubMesh的个数。 + */ + get subMeshCount():number; + + /** + * 边界。 + */ + get bounds():Bounds; + set bounds(value:Bounds); + + /** + * 索引格式。 + */ + get indexFormat():IndexFormat; + + /** + * 创建一个 Mesh 实例,禁止使用。 + * @param isReadable 是否可读。 + */ + + constructor(isReadable?:boolean); + + /** + * @inheritDoc + * @override + */ + protected _disposeResource():void; + + /** + * 根据获取子网格。 + * @param index 索引。 + */ + getSubMesh(index:number):SubMesh; + + /** + * 拷贝并填充位置数据至数组。 + * @param positions 位置数组。 + * @remark 该方法为拷贝操作,比较耗费性能。 + */ + getPositions(positions:Vector3[]):void; + + /** + * 设置位置数据。 + * @param positions 位置。 + */ + setPositions(positions:Vector3[]):void; + + /** + * 拷贝并填充颜色数据至数组。 + * @param colors 颜色数组。 + * @remark 该方法为拷贝操作,比较耗费性能。 + */ + getColors(colors:Color[]):void; + + /** + * 设置颜色数据。 + * @param colors 颜色。 + */ + setColors(colors:Color[]):void; + + /** + * 拷贝并填充纹理坐标数据至数组。 + * @param uvs 纹理坐标数组。 + * @param channel 纹理坐标通道。 + * @remark 该方法为拷贝操作,比较耗费性能。 + */ + getUVs(uvs:Vector2[],channel?:number):void; + + /** + * 设置纹理坐标数据。 + * @param uvs 纹理坐标。 + * @param channel 纹理坐标通道。 + */ + setUVs(uvs:Vector2[],channel?:number):void; + + /** + * 拷贝并填充法线数据至数组。 + * @param normals 法线数组。 + * @remark 该方法为拷贝操作,比较耗费性能。 + */ + getNormals(normals:Vector3[]):void; + + /** + * 设置法线数据。 + * @param normals 法线。 + */ + setNormals(normals:Vector3[]):void; + + /** + * 拷贝并填充切线数据至数组。 + * @param tangents 切线。 + */ + getTangents(tangents:Vector4[]):void; + + /** + * 设置切线数据。 + * @param tangents 切线。 + */ + setTangents(tangents:Vector4[]):void; + + /** + * 获取骨骼权重。 + * @param boneWeights 骨骼权重。 + */ + getBoneWeights(boneWeights:Vector4[]):void; + + /** + * 拷贝并填充骨骼权重数据至数组。 + * @param boneWeights 骨骼权重。 + */ + setBoneWeights(boneWeights:Vector4[]):void; + + /** + * 获取骨骼索引。 + * @param boneIndices 骨骼索引。 + */ + getBoneIndices(boneIndices:Vector4[]):void; + + /** + * 拷贝并填充骨骼索引数据至数组。 + * @param boneWeights 骨骼索引。 + */ + setBoneIndices(boneIndices:Vector4[]):void; + + /** + * 将Mesh标记为不可读,可减少内存,标记后不可再调用相关读取方法。 + */ + markAsUnreadbale():void; + + /** + * 获取顶点声明。 + */ + getVertexDeclaration():VertexDeclaration; + + /** + * 拷贝并获取顶点数据的副本。 + * @return 顶点数据。 + */ + getVertices():ArrayBuffer; + + /** + * 设置顶点数据。 + * @param vertices 顶点数据。 + */ + setVertices(vertices:ArrayBuffer):void; + + /** + * 拷贝并获取网格索引的副本。 + * @return 网格索引。 + */ + getIndices():Uint8Array|Uint16Array|Uint32Array; + + /** + * 设置网格索引。 + * @param indices 网格索引。 + */ + setIndices(indices:Uint8Array|Uint16Array|Uint32Array):void; + + /** + * 从模型位置数据生成包围盒。 + */ + calculateBounds():void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * PrimitiveMesh 类用于创建简单网格。 + */ + class PrimitiveMesh { + static __init__():void; + + /** + * 创建Box网格。 + * @param long 半径 + * @param height 垂直层数 + * @param width 水平层数 + * @return + */ + static createBox(long?:number,height?:number,width?:number):Mesh; + + /** + * 创建一个胶囊体模型 + * @param radius 半径 + * @param height 高度 + * @param stacks 水平层数,一般设为垂直层数的一半 + * @param slices 垂直层数 + */ + static createCapsule(radius?:number,height?:number,stacks?:number,slices?:number):Mesh; + + /** + * 创建一个圆锥体模型 + * @param radius 半径 + * @param height 高度 + * @param slices 分段数 + */ + static createCone(radius?:number,height?:number,slices?:number):Mesh; + + /** + * 创建一个圆柱体模型 + * @param radius 半径 + * @param height 高度 + * @param slices 垂直层数 + */ + static createCylinder(radius?:number,height?:number,slices?:number):Mesh; + + /** + * 创建一个平面模型 + * @param long 长 + * @param width 宽 + */ + static createPlane(long?:number,width?:number,stacks?:number,slices?:number):Mesh; + + /** + * 创建一个四边形模型 + * @param long 长 + * @param width 宽 + */ + static createQuad(long?:number,width?:number):Mesh; + + /** + * 创建一个球体模型 + * @param radius 半径 + * @param stacks 水平层数 + * @param slices 垂直层数 + */ + static createSphere(radius?:number,stacks?:number,slices?:number):Mesh; + } + + /** + * SkyBox 类用于创建天空盒。 + */ + class SkyBox extends SkyMesh { + static instance:SkyBox; + + /** + * 创建一个 SkyBox 实例。 + */ + + constructor(); + } + + /** + * SkyDome 类用于创建天空盒。 + */ + class SkyDome extends SkyMesh { + static instance:SkyDome; + + /** + * 获取堆数。 + */ + get stacks():number; + + /** + * 获取层数。 + */ + get slices():number; + + /** + * 创建一个 SkyDome 实例。 + * @param stacks 堆数。 + * @param slices 层数。 + */ + + constructor(stacks?:number,slices?:number); + } + + /** + * SkyMesh 类用于实现天空网格。 + */ + class SkyMesh { + + /** + * 创建一个新的 SkyMesh 实例。 + */ + + constructor(); + } + + /** + * SkyRenderer 类用于实现天空渲染器。 + */ + class SkyRenderer { + + /** + * 材质。 + */ + get material():Material; + set material(value:Material); + + /** + * 网格。 + */ + get mesh():SkyMesh; + set mesh(value:SkyMesh); + + /** + * 创建一个新的 SkyRenderer 实例。 + */ + + constructor(); + } + + /** + * SubMesh 类用于创建子网格数据模板。 + */ + class SubMesh extends GeometryElement { + + /** + * 获取索引数量。 + */ + get indexCount():number; + + /** + * 创建一个 SubMesh 实例。 + * @param mesh 网格数据模板。 + */ + + constructor(mesh:Mesh); + + /** + * 拷贝并获取子网格索引数据的副本。 + */ + getIndices():Uint16Array|Uint32Array; + + /** + * 设置子网格索引。 + * @param indices + */ + setIndices(indices:Uint16Array):void; + + /** + * {@inheritDoc GeometryElement.destroy} + * @override + */ + destroy():void; + } + + /** + * RenderTexture 类用于创建渲染目标。 + */ + class RenderTexture extends BaseTexture { + + /** + * 获取当前激活的Rendertexture。 + */ + static get currentActive():RenderTexture; + + /** + * 从对象池获取临时渲染目标。 + */ + static createFromPool(width:number,height:number,format?:number,depthStencilFormat?:number,mulSamples?:number):RenderTexture; + + /** + * 回收渲染目标到对象池,释放后可通过createFromPool复用。 + */ + static recoverToPool(renderTexture:RenderTexture):void; + + /** + * @inrernal 是否使用多重采样 + */ + private _mulSamplerRT:any; + + /** + * 深度格式。 + */ + get depthStencilFormat():number; + + /** + * @override + */ + get defaulteTexture():BaseTexture; + get mulSampler():number; + + /** + * @param width 宽度。 + * @param height 高度。 + * @param format 纹理格式。 + * @param depthStencilFormat 深度格式。 创建一个 RenderTexture 实例。 + */ + + constructor(width:number,height:number,format?:RenderTextureFormat,depthStencilFormat?:RenderTextureDepthFormat,mulSampler?:number); + + /** + * 获得像素数据。 + * @param x X像素坐标。 + * @param y Y像素坐标。 + * @param width 宽度。 + * @param height 高度。 + * @return 像素数据。 + */ + getData(x:number,y:number,width:number,height:number,out:Uint8Array|Float32Array):Uint8Array|Float32Array; + + /** + * @inheritDoc + * @override + */ + protected _disposeResource():void; + } + +enum TextureCubeFace { + /**+x */ + PositiveX = 0, + /**-x */ + NegativeX = 1, + /**+y */ + PositiveY = 2, + /**-y */ + NegativeY = 3, + /**+z */ + PositiveZ = 4, + /**-z */ + NegativeZ = 5 +} + + /** + * TextureCube 类用于生成立方体纹理。 + */ + class TextureCube extends BaseTexture { + + /** + * TextureCube资源。 + */ + static TEXTURECUBE:string; + static TEXTURECUBEBIN:string; + + /** + * @private + */ + private static _blackTexture:any; + + /** + * @private + */ + private static _grayTexture:any; + + /** + * 黑色纯色纹理。 + */ + static get blackTexture():TextureCube; + + /** + * 灰色纯色纹理。 + */ + static get grayTexture():TextureCube; + + /** + * @inheritDoc + */ + static _parse(data:any,propertyParams?:any,constructParams?:any[]):TextureCube; + + /** + * @inheritDoc + */ + static _parseBin(data:any,propertyParams?:any,constructParams?:any[]):TextureCube; + + /** + * 加载TextureCube。 + * @param url TextureCube地址。 + * @param complete 完成回调。 + */ + static load(url:string,complete:Handler):void; + + /** + * @inheritDoc + * @override + */ + get defaulteTexture():BaseTexture; + + /** + * 创建一个 TextureCube 实例。 + * @param format 贴图格式。 + * @param mipmap 是否生成mipmap。 + */ + + constructor(size:number,format?:number,mipmap?:boolean); + + /** + * @private + */ + private _setPixels:any; + + /** + * 通过六张图片源填充纹理。 + * @param 图片源数组 。 + */ + setSixSideImageSources(source:any[],premultiplyAlpha?:boolean):void; + + /** + * 通过六张图片源填充纹理。 + * @param 图片源数组 。 + */ + setSixSidePixels(pixels:Array,miplevel?:number):void; + + /** + * 通过图源设置一个面的颜色。 + * @param face 面。 + * @param imageSource 图源。 + * @param miplevel 层级。 + */ + setImageSource(face:TextureCubeFace,imageSource:HTMLImageElement|HTMLCanvasElement,miplevel?:number):void; + } + + /** + * DefineDatas 类用于创建宏定义数据集合。 + */ + class DefineDatas implements IClone { + + /** + * 创建一个 DefineDatas 实例。 + */ + + constructor(); + + /** + * 添加宏定义值。 + * @param define 宏定义值。 + */ + add(define:ShaderDefine):void; + + /** + * 移除宏定义。 + * @param define 宏定义。 + */ + remove(define:ShaderDefine):void; + + /** + * 添加宏定义集合。 + * @param define 宏定义集合。 + */ + addDefineDatas(define:DefineDatas):void; + + /** + * 移除宏定义集合。 + * @param define 宏定义集合。 + */ + removeDefineDatas(define:DefineDatas):void; + + /** + * 是否有宏定义。 + * @param define 宏定义。 + */ + has(define:ShaderDefine):boolean; + + /** + * 清空宏定义。 + */ + clear():void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:any):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + } + + /** + * Shader3D 类用于创建Shader3D。 + */ + class Shader3D { + + /** + * 渲染状态_剔除。 + */ + static RENDER_STATE_CULL:number; + + /** + * 渲染状态_混合。 + */ + static RENDER_STATE_BLEND:number; + + /** + * 渲染状态_混合源。 + */ + static RENDER_STATE_BLEND_SRC:number; + + /** + * 渲染状态_混合目标。 + */ + static RENDER_STATE_BLEND_DST:number; + + /** + * 渲染状态_混合源RGB。 + */ + static RENDER_STATE_BLEND_SRC_RGB:number; + + /** + * 渲染状态_混合目标RGB。 + */ + static RENDER_STATE_BLEND_DST_RGB:number; + + /** + * 渲染状态_混合源ALPHA。 + */ + static RENDER_STATE_BLEND_SRC_ALPHA:number; + + /** + * 渲染状态_混合目标ALPHA。 + */ + static RENDER_STATE_BLEND_DST_ALPHA:number; + + /** + * 渲染状态_混合常量颜色。 + */ + static RENDER_STATE_BLEND_CONST_COLOR:number; + + /** + * 渲染状态_混合方程。 + */ + static RENDER_STATE_BLEND_EQUATION:number; + + /** + * 渲染状态_RGB混合方程。 + */ + static RENDER_STATE_BLEND_EQUATION_RGB:number; + + /** + * 渲染状态_ALPHA混合方程。 + */ + static RENDER_STATE_BLEND_EQUATION_ALPHA:number; + + /** + * 渲染状态_深度测试。 + */ + static RENDER_STATE_DEPTH_TEST:number; + + /** + * 渲染状态_深度写入。 + */ + static RENDER_STATE_DEPTH_WRITE:number; + + /** + * shader变量提交周期,自定义。 + */ + static PERIOD_CUSTOM:number; + + /** + * shader变量提交周期,逐材质。 + */ + static PERIOD_MATERIAL:number; + + /** + * shader变量提交周期,逐精灵和相机,注:因为精灵包含MVP矩阵,为复合属性,所以摄像机发生变化时也应提交。 + */ + static PERIOD_SPRITE:number; + + /** + * shader变量提交周期,逐相机。 + */ + static PERIOD_CAMERA:number; + + /** + * shader变量提交周期,逐场景。 + */ + static PERIOD_SCENE:number; + + /** + * 是否开启调试模式。 + */ + static debugMode:boolean; + + /** + * 调试着色器变种集合。 + */ + static readonly debugShaderVariantCollection:ShaderVariantCollection; + + /** + * 注册宏定义。 + * @param name + */ + static getDefineByName(name:string):ShaderDefine; + + /** + * 通过Shader属性名称获得唯一ID。 + * @param name Shader属性名称。 + * @return 唯一ID。 + */ + static propertyNameToID(name:string):number; + + /** + * 添加函数库引用。 + * @param fileName 文件名字。 + * @param txt 文件内容 + */ + static addInclude(fileName:string,txt:string):void; + + /** + * 通过宏定义名字编译shader。 + * @param shaderName Shader名称。 + * @param subShaderIndex 子着色器索引。 + * @param passIndex 通道索引。 + * @param defineNames 宏定义名字集合。 + */ + static compileShaderByDefineNames(shaderName:string,subShaderIndex:number,passIndex:number,defineNames:string[]):void; + + /** + * 添加预编译shader文件,主要是处理宏定义 + */ + static add(name:string,attributeMap?:any,uniformMap?:any,enableInstancing?:boolean,supportReflectionProbe?:boolean):Shader3D; + + /** + * 获取ShaderCompile3D。 + * @param name + * @return ShaderCompile3D。 + */ + static find(name:string):Shader3D; + + /** + * 名字。 + */ + get name():string; + + /** + * 创建一个 Shader3D 实例。 + */ + + constructor(name:string,attributeMap:any,uniformMap:any,enableInstancing:boolean,supportReflectionProbe:boolean); + + /** + * 添加子着色器。 + * @param 子着色器 。 + */ + addSubShader(subShader:SubShader):void; + + /** + * 在特定索引获取子着色器。 + * @param index 索引。 + * @return 子着色器。 + */ + getSubShaderAt(index:number):SubShader; + + /** + * @deprecated 通过宏定义遮罩编译shader,建议使用compileShaderByDefineNames。 + * @param shaderName Shader名称。 + * @param subShaderIndex 子着色器索引。 + * @param passIndex 通道索引。 + * @param defineMask 宏定义遮罩集合。 + */ + static compileShader(shaderName:string,subShaderIndex:number,passIndex:number,...defineMask:any[]):void; + } + + /** + * 着色器数据类。 + */ + class ShaderData implements IClone { + + /** + * 增加Shader宏定义。 + * @param value 宏定义。 + */ + addDefine(define:ShaderDefine):void; + + /** + * 移除Shader宏定义。 + * @param value 宏定义。 + */ + removeDefine(define:ShaderDefine):void; + + /** + * 是否包含Shader宏定义。 + * @param value 宏定义。 + */ + hasDefine(define:ShaderDefine):boolean; + + /** + * 清空宏定义。 + */ + clearDefine():void; + + /** + * 获取布尔。 + * @param index shader索引。 + * @return 布尔。 + */ + getBool(index:number):boolean; + + /** + * 设置布尔。 + * @param index shader索引。 + * @param value 布尔。 + */ + setBool(index:number,value:boolean):void; + + /** + * 获取整形。 + * @param index shader索引。 + * @return 整形。 + */ + getInt(index:number):number; + + /** + * 设置整型。 + * @param index shader索引。 + * @param value 整形。 + */ + setInt(index:number,value:number):void; + + /** + * 获取浮点。 + * @param index shader索引。 + * @return 浮点。 + */ + getNumber(index:number):number; + + /** + * 设置浮点。 + * @param index shader索引。 + * @param value 浮点。 + */ + setNumber(index:number,value:number):void; + + /** + * 获取Vector2向量。 + * @param index shader索引。 + * @return Vector2向量。 + */ + getVector2(index:number):Vector2; + + /** + * 设置Vector2向量。 + * @param index shader索引。 + * @param value Vector2向量。 + */ + setVector2(index:number,value:Vector2):void; + + /** + * 获取Vector3向量。 + * @param index shader索引。 + * @return Vector3向量。 + */ + getVector3(index:number):Vector3; + + /** + * 设置Vector3向量。 + * @param index shader索引。 + * @param value Vector3向量。 + */ + setVector3(index:number,value:Vector3):void; + + /** + * 获取颜色。 + * @param index shader索引。 + * @return 颜色向量。 + */ + getVector(index:number):Vector4; + + /** + * 设置向量。 + * @param index shader索引。 + * @param value 向量。 + */ + setVector(index:number,value:Vector4):void; + + /** + * 获取四元数。 + * @param index shader索引。 + * @return 四元。 + */ + getQuaternion(index:number):Quaternion; + + /** + * 设置四元数。 + * @param index shader索引。 + * @param value 四元数。 + */ + setQuaternion(index:number,value:Quaternion):void; + + /** + * 获取矩阵。 + * @param index shader索引。 + * @return 矩阵。 + */ + getMatrix4x4(index:number):Matrix4x4; + + /** + * 设置矩阵。 + * @param index shader索引。 + * @param value 矩阵。 + */ + setMatrix4x4(index:number,value:Matrix4x4):void; + + /** + * 获取Buffer。 + * @param index shader索引。 + * @return + */ + getBuffer(shaderIndex:number):Float32Array; + + /** + * 设置Buffer。 + * @param index shader索引。 + * @param value buffer数据。 + */ + setBuffer(index:number,value:Float32Array):void; + + /** + * 设置纹理。 + * @param index shader索引。 + * @param value 纹理。 + */ + setTexture(index:number,value:BaseTexture):void; + + /** + * 获取纹理。 + * @param index shader索引。 + * @return 纹理。 + */ + getTexture(index:number):BaseTexture; + setValueData(index:number,value:any):void; + getValueData(index:number):any; + + /** + * 设置Attribute。 + * @param index shader索引。 + * @param value 纹理。 + */ + setAttribute(index:number,value:Int32Array):void; + + /** + * 获取Attribute。 + * @param index shader索引。 + * @return 纹理。 + */ + getAttribute(index:number):any[]; + + /** + * 获取长度。 + * @return 长度。 + */ + getLength():number; + + /** + * 设置长度。 + * @param 长度 。 + */ + setLength(value:number):void; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneTo(destObject:ShaderData):void; + + /** + * 克隆。 + * @return 克隆副本。 + */ + clone():any; + + /** + * 克隆。 + * @param destObject 克隆源。 + */ + cloneToForNative(destObject:any):void; + needRenewArrayBufferForNative(index:number):void; + getDataForNative():any[]; + setReferenceForNative(value:any):number; + static setRuntimeValueMode(bReference:boolean):void; + clearRuntimeCopyArray():void; + } + + /** + * ShaderDefine 类用于定义宏数据。 + */ + class ShaderDefine { + + /** + * 创建一个宏定义的实例 + * @param index 宏索引 + * @param value 宏值 + */ + + constructor(index:number,value:number); + } + + /** + * ShaderPass 类用于实现ShaderPass。 + */ + class ShaderPass extends ShaderCompile { + + /** + * 渲染状态。 + */ + get renderState():RenderState; + + constructor(owner:SubShader,vs:string,ps:string,stateMap:{[key:string]:number;}); + + /** + * @private + */ + protected _compileToTree(parent:ShaderNode,lines:any[],start:number,includefiles:any[],defs:any):void; + + /** + * 添加标记。 + * @param key 标记键。 + * @param value 标记值。 + */ + setTag(key:string,value:string):void; + + /** + * 获取标记值。 + * @return key 标记键。 + */ + getTag(key:string):string; + } + + /** + * 着色器变种。 + */ + class ShaderVariant { + + /** + * 着色器。 + */ + get shader():Shader3D; + + /** + * 子着色器索引。 + */ + get subShaderIndex():number; + + /** + * 通道索引。 + */ + get passIndex():number; + + /** + * 宏定义集合。 + */ + get defineNames():Readonly; + + /** + * 创建着色器变种。 + * @param shader 着色器 + * @param subShaderIndex 子着色器索引 + * @param passIndex 通道索引 + * @param defines 宏定义集合 + */ + + constructor(shader:Shader3D,subShaderIndex:number,passIndex:number,defines:string[]); + + /** + * 给着色器变种赋值。 + * @param shader 着色器 + * @param subShaderIndex 子着色器索引 + * @param passIndex 通道索引 + * @param defineNames 宏定义集合 + */ + setValue(shader:Shader3D,subShaderIndex:number,passIndex:number,defineNames:string[]):void; + + /** + * 是否相等。 + * @param other 其它着色器变种 + * @return 是否相等。 + */ + equal(other:ShaderVariant):boolean; + + /** + * 克隆。 + * @return 着色器变种。 + */ + clone():ShaderVariant; + } + + /** + * 着色器变种集合。 + */ + class ShaderVariantCollection { + + /** + * 是否已经全部编译。 + */ + get allCompiled():boolean; + + /** + * 包含的变种数量。 + */ + get variantCount():number; + + /** + * 添加着色器变种。 + * @param variant 着色器变种。 + * @param 是否添加成功 。 + */ + add(variant:ShaderVariant):boolean; + + /** + * 移除着色器变种。 + * @param variant 着色器变种。 + * @return 是否移除成功。 + */ + remove(variant:ShaderVariant):boolean; + + /** + * 是否包含着色器变种。 + * @param variant 着色器变种。 + */ + contatins(variant:ShaderVariant):boolean; + + /** + * 通过索引获取着色器变种。 + * @param index 索引。 + * @returns 着色器变种。 + */ + getByIndex(index:number):ShaderVariant; + + /** + * 清空。 + */ + clear():void; + + /** + * 执行编译。 + */ + compile():void; + } + + /** + * SubShader 类用于创建SubShader。 + */ + class SubShader { + + /** + * 创建一个 SubShader 实例。 + * @param attributeMap 顶点属性表。 + * @param uniformMap uniform属性表。 + */ + + constructor(attributeMap:any,uniformMap:any); + + /** + * 添加标记。 + * @param key 标记键。 + * @param value 标记值。 + */ + setFlag(key:string,value:string):void; + + /** + * 获取标记值。 + * @return key 标记键。 + */ + getFlag(key:string):string; + + /** + * 添加着色器Pass + * @param vs + * @param ps + * @param stateMap + * @param pipelineMode 渲染管线模式。 + */ + addShaderPass(vs:string,ps:string,stateMap?:{[key:string]:number;},pipelineMode?:string):ShaderPass; + } + +enum ShadowLightType { + /**直射光 */ + DirectionLight = 0, + /**聚光 */ + SpotLight = 1, + /**点光 */ + PointLight = 2 +} + + /** + * TextMesh 类用于创建文本网格。 + */ + class TextMesh { + private _text:any; + private _fontSize:any; + private _color:any; + + /** + * 获取文本。 + * @return 文本。 + */ + get text():string; + + /** + * 设置文本。 + * @param value 文本。 + */ + set text(value:string); + + /** + * 获取字体尺寸。 + * @param value 字体尺寸。 + */ + get fontSize():number; + + /** + * 设置字体储存。 + * @return 字体尺寸。 + */ + set fontSize(value:number); + + /** + * 获取颜色。 + * @return 颜色。 + */ + get color():Color; + + /** + * 设置颜色。 + * @param 颜色 。 + */ + set color(value:Color); + + /** + * 创建一个新的 TextMesh 实例。 + */ + + constructor(); + } + + /** + * Touch 类用于实现触摸描述。 + */ + class Touch implements ISingletonElement { + + /** + * [实现IListPool接口] + */ + private _indexInList:any; + + /** + * 获取唯一识别ID。 + * @return 唯一识别ID。 + */ + get identifier():number; + + /** + * 获取触摸点的像素坐标。 + * @return 触摸点的像素坐标 [只读]。 + */ + get position():Vector2; + + /** + * [实现ISingletonElement接口] + */ + _getIndexInList():number; + + /** + * [实现ISingletonElement接口] + */ + _setIndexInList(index:number):void; + } + + /** + * Physics 类用于简单物理检测。 + */ + class Physics3DUtils { + + /** + * 默认碰撞组 + */ + static COLLISIONFILTERGROUP_DEFAULTFILTER:number; + + /** + * 静态碰撞组 + */ + static COLLISIONFILTERGROUP_STATICFILTER:number; + + /** + * 运动学刚体碰撞组 + */ + static COLLISIONFILTERGROUP_KINEMATICFILTER:number; + + /** + * 碎片碰撞组 + */ + static COLLISIONFILTERGROUP_DEBRISFILTER:number; + + /** + * 传感器触发器 + */ + static COLLISIONFILTERGROUP_SENSORTRIGGER:number; + + /** + * 字符过滤器 + */ + static COLLISIONFILTERGROUP_CHARACTERFILTER:number; + + /** + * 自定义过滤1 + */ + static COLLISIONFILTERGROUP_CUSTOMFILTER1:number; + + /** + * 自定义过滤2 + */ + static COLLISIONFILTERGROUP_CUSTOMFILTER2:number; + + /** + * 自定义过滤3 + */ + static COLLISIONFILTERGROUP_CUSTOMFILTER3:number; + + /** + * 自定义过滤4 + */ + static COLLISIONFILTERGROUP_CUSTOMFILTER4:number; + + /** + * 自定义过滤5 + */ + static COLLISIONFILTERGROUP_CUSTOMFILTER5:number; + + /** + * 自定义过滤6 + */ + static COLLISIONFILTERGROUP_CUSTOMFILTER6:number; + + /** + * 自定义过滤7 + */ + static COLLISIONFILTERGROUP_CUSTOMFILTER7:number; + + /** + * 自定义过滤8 + */ + static COLLISIONFILTERGROUP_CUSTOMFILTER8:number; + + /** + * 自定义过滤9 + */ + static COLLISIONFILTERGROUP_CUSTOMFILTER9:number; + + /** + * 自定义过滤10 + */ + static COLLISIONFILTERGROUP_CUSTOMFILTER10:number; + + /** + * 所有过滤 + */ + static COLLISIONFILTERGROUP_ALLFILTER:number; + + /** + * 重力值。 + */ + static gravity:Vector3; + + /** + * 创建一个 Physics 实例。 + */ + + constructor(); + + /** + * 是否忽略两个碰撞器的碰撞检测。 + * @param collider1 碰撞器一。 + * @param collider2 碰撞器二。 + * @param ignore 是否忽略。 + */ + static setColliderCollision(collider1:PhysicsComponent,collider2:PhysicsComponent,collsion:boolean):void; + + /** + * 获取是否忽略两个碰撞器的碰撞检测。 + * @param collider1 碰撞器一。 + * @param collider2 碰撞器二。 + * @return 是否忽略。 + */ + static getIColliderCollision(collider1:PhysicsComponent,collider2:PhysicsComponent):boolean; + } + + /** + * Picker 类用于创建拾取。 + */ + class Picker { + private static _tempVector30:any; + private static _tempVector31:any; + private static _tempVector32:any; + private static _tempVector33:any; + private static _tempVector34:any; + + /** + * 创建一个 Picker 实例。 + */ + + constructor(); + + /** + * 计算鼠标生成的射线。 + * @param point 鼠标位置。 + * @param viewPort 视口。 + * @param projectionMatrix 透视投影矩阵。 + * @param viewMatrix 视图矩阵。 + * @param world 世界偏移矩阵。 + * @return out 输出射线。 + */ + static calculateCursorRay(point:Vector2,viewPort:Viewport,projectionMatrix:Matrix4x4,viewMatrix:Matrix4x4,world:Matrix4x4,out:Ray):void; + + /** + * 计算射线和三角形碰撞并返回碰撞距离。 + * @param ray 射线。 + * @param vertex1 顶点1。 + * @param vertex2 顶点2。 + * @param vertex3 顶点3。 + * @return 射线距离三角形的距离,返回Number.NaN则不相交。 + */ + static rayIntersectsTriangle(ray:Ray,vertex1:Vector3,vertex2:Vector3,vertex3:Vector3):number; + } + + /** + */ + class Size { + + /** + * 全局场景的屏幕大小 + */ + static get fullScreen():Size; + private _width:any; + private _height:any; + + /** + * 宽度 + */ + get width():number; + + /** + * 高度 + */ + get height():number; + + /** + * 创建Size实例 + * @param width 宽度 + * @param height 高度 + */ + + constructor(width:number,height:number); + } + + /** + * Utils3D 类用于创建3D工具。 + */ + class Utils3D { + private static _tempVector3_0:any; + private static _tempVector3_1:any; + private static _tempArray16_0:any; + private static _tempArray16_1:any; + private static _tempArray16_2:any; + private static _tempArray16_3:any; + + /** + * 通过数平移、旋转、缩放值计算到结果矩阵数组,骨骼动画专用。 + * @param tx left矩阵数组。 + * @param ty left矩阵数组的偏移。 + * @param tz right矩阵数组。 + * @param qx right矩阵数组的偏移。 + * @param qy 输出矩阵数组。 + * @param qz 输出矩阵数组的偏移。 + * @param qw 输出矩阵数组的偏移。 + * @param sx 输出矩阵数组的偏移。 + * @param sy 输出矩阵数组的偏移。 + * @param sz 输出矩阵数组的偏移。 + * @param outArray 结果矩阵数组。 + * @param outOffset 结果矩阵数组的偏移。 + */ + private static _rotationTransformScaleSkinAnimation:any; + + /** + * 根据四元数旋转三维向量。 + * @param source 源三维向量。 + * @param rotation 旋转四元数。 + * @param out 输出三维向量。 + */ + static transformVector3ArrayByQuat(sourceArray:Float32Array,sourceOffset:number,rotation:Quaternion,outArray:Float32Array,outOffset:number):void; + + /** + * 通过数组数据计算矩阵乘法。 + * @param leftArray left矩阵数组。 + * @param leftOffset left矩阵数组的偏移。 + * @param rightArray right矩阵数组。 + * @param rightOffset right矩阵数组的偏移。 + * @param outArray 输出矩阵数组。 + * @param outOffset 输出矩阵数组的偏移。 + */ + static mulMatrixByArray(leftArray:Float32Array,leftOffset:number,rightArray:Float32Array,rightOffset:number,outArray:Float32Array,outOffset:number):void; + + /** + * 通过数组数据计算矩阵乘法,rightArray和outArray不能为同一数组引用。 + * @param leftArray left矩阵数组。 + * @param leftOffset left矩阵数组的偏移。 + * @param rightArray right矩阵数组。 + * @param rightOffset right矩阵数组的偏移。 + * @param outArray 结果矩阵数组。 + * @param outOffset 结果矩阵数组的偏移。 + */ + static mulMatrixByArrayFast(leftArray:Float32Array,leftOffset:number,rightArray:Float32Array,rightOffset:number,outArray:Float32Array,outOffset:number):void; + + /** + * 通过数组数据计算矩阵乘法,rightArray和outArray不能为同一数组引用。 + * @param leftArray left矩阵数组。 + * @param leftOffset left矩阵数组的偏移。 + * @param rightMatrix right矩阵。 + * @param outArray 结果矩阵数组。 + * @param outOffset 结果矩阵数组的偏移。 + */ + static mulMatrixByArrayAndMatrixFast(leftArray:Float32Array,leftOffset:number,rightMatrix:Matrix4x4,outArray:Float32Array,outOffset:number):void; + + /** + * 通过数平移、旋转、缩放值计算到结果矩阵数组。 + * @param tX left矩阵数组。 + * @param tY left矩阵数组的偏移。 + * @param tZ right矩阵数组。 + * @param qX right矩阵数组的偏移。 + * @param qY 输出矩阵数组。 + * @param qZ 输出矩阵数组的偏移。 + * @param qW 输出矩阵数组的偏移。 + * @param sX 输出矩阵数组的偏移。 + * @param sY 输出矩阵数组的偏移。 + * @param sZ 输出矩阵数组的偏移。 + * @param outArray 结果矩阵数组。 + * @param outOffset 结果矩阵数组的偏移。 + */ + static createAffineTransformationArray(tX:number,tY:number,tZ:number,rX:number,rY:number,rZ:number,rW:number,sX:number,sY:number,sZ:number,outArray:Float32Array,outOffset:number):void; + + /** + * 通过矩阵转换一个三维向量数组到另外一个三维向量数组。 + * @param source 源三维向量所在数组。 + * @param sourceOffset 源三维向量数组偏移。 + * @param transform 变换矩阵。 + * @param result 输出三维向量所在数组。 + * @param resultOffset 输出三维向量数组偏移。 + */ + static transformVector3ArrayToVector3ArrayCoordinate(source:Float32Array,sourceOffset:number,transform:Matrix4x4,result:Float32Array,resultOffset:number):void; + + /** + * 通过矩阵转换一个三维向量数组到另外一个归一化的三维向量数组。 + * @param source 源三维向量所在数组。 + * @param sourceOffset 源三维向量数组偏移。 + * @param transform 变换矩阵。 + * @param result 输出三维向量所在数组。 + * @param resultOffset 输出三维向量数组偏移。 + */ + static transformVector3ArrayToVector3ArrayNormal(source:Float32Array,sourceOffset:number,transform:Matrix4x4,result:Float32Array,resultOffset:number):void; + + /** + * 获取URL版本字符。 + * @param url + * @return + */ + static getURLVerion(url:string):string; + + /** + * 四元数旋转矩阵 + * @param source 源数据 + * @param rotation 旋转四元数Array + * @param out 输出数据 + */ + static transformQuat(source:Vector3,rotation:Float32Array,out:Vector3):void; + + /** + * 修改四元数权重 + * @param f 元数据 + * @param weight 权重 + * @param e 目标数据 + */ + static quaternionWeight(f:Quaternion,weight:number,e:Quaternion):void; + + /** + * 将RenderTexture转换为Base64 + * @param rendertexture 渲染Buffer + * @returns + */ + static uint8ArrayToArrayBuffer(rendertexture:RenderTexture):String; + } + + /** + * 使用前可用supported查看浏览器支持。 + */ + class Geolocation { + private static navigator:any; + private static position:any; + + /** + * 由于权限被拒绝造成的地理信息获取失败。 + */ + static PERMISSION_DENIED:number; + + /** + * 由于内部位置源返回了内部错误导致地理信息获取失败。 + */ + static POSITION_UNAVAILABLE:number; + + /** + * 信息获取所用时长超出timeout所设置时长。 + */ + static TIMEOUT:number; + + /** + * 是否支持。 + */ + static supported:boolean; + + /** + * 如果enableHighAccuracy为true,并且设备能够提供一个更精确的位置,则会获取最佳可能的结果。 + * 请注意,这可能会导致较慢的响应时间或增加电量消耗(如使用GPS)。 + * 另一方面,如果设置为false,将会得到更快速的响应和更少的电量消耗。 + * 默认值为false。 + */ + static enableHighAccuracy:boolean; + + /** + * 表示允许设备获取位置的最长时间。默认为Infinity,意味着getCurentPosition()直到位置可用时才会返回信息。 + */ + static timeout:number; + + /** + * 表示可被返回的缓存位置信息的最大时限。 + * 如果设置为0,意味着设备不使用缓存位置,并且尝试获取实时位置。 + * 如果设置为Infinity,设备必须返回缓存位置而无论其时限。 + */ + static maximumAge:number; + + constructor(); + + /** + * 获取设备当前位置。 + * @param onSuccess 带有唯一Position参数的回调处理器。 + * @param onError 可选的。带有错误信息的回调处理器。错误代码为Geolocation.PERMISSION_DENIED、Geolocation.POSITION_UNAVAILABLE和Geolocation.TIMEOUT之一。 + */ + static getCurrentPosition(onSuccess:Handler,onError?:Handler):void; + + /** + * 监视设备当前位置。回调处理器在设备位置改变时被执行。 + * @param onSuccess 带有唯一Position参数的回调处理器。 + * @param onError 可选的。带有错误信息的回调处理器。错误代码为Geolocation.PERMISSION_DENIED、Geolocation.POSITION_UNAVAILABLE和Geolocation.TIMEOUT之一。 + */ + static watchPosition(onSuccess:Handler,onError:Handler):number; + + /** + * 移除watchPosition安装的指定处理器。 + * @param id + */ + static clearWatch(id:number):void; + } + class GeolocationInfo { + private pos:any; + private coords:any; + + /** + * 设置设备经纬度 + * @param pos + */ + setPosition(pos:any):void; + + /** + * 获取设备当前地理坐标的纬度 + */ + get latitude():number; + + /** + * 获取设备当前地理坐标的经度 + */ + get longitude():number; + + /** + * 获取设备当前地理坐标的高度 + */ + get altitude():number; + + /** + * 获取设备当前地理坐标的精度 + */ + get accuracy():number; + + /** + * 获取设备当前地理坐标的高度精度 + */ + get altitudeAccuracy():number; + + /** + * 获取设备当前行进方向 + */ + get heading():number; + + /** + * 获取设备当前的速度 + */ + get speed():number; + + /** + * 获取设备得到当前位置的时间 + */ + get timestamp():number; + } + + /** + * html多媒体数据 + */ + class HtmlVideo extends Bitmap { + video:HTMLVideoElement; + protected _source:any; + protected _w:number; + protected _h:number; + + constructor(); + + /** + * 创建一个 HtmlVideo 实例 + */ + static create:Function; + private createDomElement:any; + + /** + * 设置播放源路径 + * @param url 播放源路径 + * @param extension 播放源类型(1: MP4, 2: OGG) + */ + setSource(url:string,extension:number):void; + private appendSource:any; + + /** + * 获取播放源 + */ + getVideo():any; + + /** + * 销毁 + * @override + */ + destroy():void; + } + + /** + * Media用于捕捉摄像头和麦克风。可以捕捉任意之一,或者同时捕捉两者。getCamera前可以使用supported()检查当前浏览器是否支持。 + * NOTE: + *

目前Media在移动平台只支持Android,不支持IOS。只可在FireFox完整地使用,Chrome测试时无法捕捉视频。

+ */ + class Media { + + constructor(); + + /** + * 检查浏览器兼容性。 + */ + static supported():boolean; + + /** + * 获取用户媒体。 + * @param options 简单的可选项可以使{ audio:true, video:true }表示同时捕捉两者。详情见https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia。 + * @param onSuccess 获取成功的处理器,唯一参数返回媒体的Blob地址,可以将其传给Video。 + * @param onError 获取失败的处理器,唯一参数是Error。 + */ + static getMedia(options:any,onSuccess:Handler,onError:Handler):void; + } + +const enum VIDEOTYPE { + MP4 = 1, + OGG = 2, + CAMERA = 4, + WEBM = 8 +} + + /** + * Video将视频显示到Canvas上。Video可能不会在所有浏览器有效。 + *

关于Video支持的所有事件参见:http://www.w3school.com.cn/tags/html_ref_audio_video_dom.asp

+ *

+ * 注意:
+ * 在PC端可以在任何时机调用play()因此,可以在程序开始运行时就使Video开始播放。但是在移动端,只有在用户第一次触碰屏幕后才可以调用play(),所以移动端不可能在程序开始运行时就自动开始播放Video。 + *

+ * + *

MDN Video链接: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video

+ */ + class Video extends Sprite { + static MP4:number; + static OGG:number; + static CAMERA:number; + static WEBM:number; + + /** + * 表示最有可能支持。 + */ + static SUPPORT_PROBABLY:string; + + /** + * 表示可能支持。 + */ + static SUPPORT_MAYBY:string; + + /** + * 表示不支持。 + */ + static SUPPORT_NO:string; + private htmlVideo:any; + videoElement:any; + private internalTexture:any; + private _clickhandle:any; + + constructor(width?:number,height?:number); + private static onAbort:any; + private static onCanplay:any; + private static onCanplaythrough:any; + private static onDurationchange:any; + private static onEmptied:any; + private static onError:any; + private static onLoadeddata:any; + private static onLoadedmetadata:any; + private static onLoadstart:any; + private static onPause:any; + private static onPlay:any; + private static onPlaying:any; + private static onProgress:any; + private static onRatechange:any; + private static onSeeked:any; + private static onSeeking:any; + private static onStalled:any; + private static onSuspend:any; + private static onTimeupdate:any; + private static onVolumechange:any; + private static onWaiting:any; + private onPlayComplete:any; + + /** + * 设置播放源。 + * @param url 播放源路径。 + */ + load(url:string):void; + + /** + * 开始播放视频。 + */ + play():void; + + /** + * 暂停视频播放。 + */ + pause():void; + + /** + * 重新加载视频。 + */ + reload():void; + + /** + * 检测是否支持播放指定格式视频。 + * @param type 参数为Video.MP4 / Video.OGG / Video.WEBM之一。 + * @return 表示支持的级别。可能的值:
  • "probably",Video.SUPPORT_PROBABLY - 浏览器最可能支持该音频/视频类型
  • "maybe",Video.SUPPORT_MAYBY - 浏览器也许支持该音频/视频类型
  • "",Video.SUPPORT_NO- (空字符串)浏览器不支持该音频/视频类型
+ */ + canPlayType(type:number):string; + private renderCanvas:any; + private onDocumentClick:any; + + /** + * buffered 属性返回 TimeRanges(JS)对象。TimeRanges 对象表示用户的音视频缓冲范围。缓冲范围指的是已缓冲音视频的时间范围。如果用户在音视频中跳跃播放,会得到多个缓冲范围。 + *

buffered.length返回缓冲范围个数。如获取第一个缓冲范围则是buffered.start(0)和buffered.end(0)。以秒计。

+ * @return TimeRanges(JS)对象 + */ + get buffered():any; + + /** + * 获取当前播放源路径。 + */ + get currentSrc():string; + + /** + * 设置和获取当前播放头位置。 + */ + get currentTime():number; + set currentTime(value:number); + + /** + * 设置和获取当前音量。 + */ + set volume(value:number); + get volume():number; + + /** + * 表示视频元素的就绪状态: + *
    + *
  • 0 = HAVE_NOTHING - 没有关于音频/视频是否就绪的信息
  • + *
  • 1 = HAVE_METADATA - 关于音频/视频就绪的元数据
  • + *
  • 2 = HAVE_CURRENT_DATA - 关于当前播放位置的数据是可用的,但没有足够的数据来播放下一帧/毫秒
  • + *
  • 3 = HAVE_FUTURE_DATA - 当前及至少下一帧的数据是可用的
  • + *
  • 4 = HAVE_ENOUGH_DATA - 可用数据足以开始播放
  • + *
+ */ + get readyState():any; + + /** + * 获取视频源尺寸。ready事件触发后可用。 + */ + get videoWidth():number; + get videoHeight():number; + + /** + * 获取视频长度(秒)。ready事件触发后可用。 + */ + get duration():number; + + /** + * 返回音频/视频的播放是否已结束 + */ + get ended():boolean; + + /** + * 返回表示音频/视频错误状态的 MediaError(JS)对象。 + */ + get error():boolean; + + /** + * 设置或返回音频/视频是否应在结束时重新播放。 + */ + get loop():boolean; + set loop(value:boolean); + + /** + * 设置视频的x坐标 + * @override + */ + set x(val:number); + + /** + * @override + */ + get x():number; + + /** + * 设置视频的y坐标 + * @override + */ + set y(val:number); + + /** + * @override + */ + get y():number; + + /** + * playbackRate 属性设置或返回音频/视频的当前播放速度。如: + *
    + *
  • 1.0 正常速度
  • + *
  • 0.5 半速(更慢)
  • + *
  • 2.0 倍速(更快)
  • + *
  • -1.0 向后,正常速度
  • + *
  • -0.5 向后,半速
  • + *
+ *

只有 Google Chrome 和 Safari 支持 playbackRate 属性。

+ */ + get playbackRate():number; + set playbackRate(value:number); + + /** + * 获取和设置静音状态。 + */ + get muted():boolean; + set muted(value:boolean); + + /** + * 返回视频是否暂停 + */ + get paused():boolean; + + /** + * preload 属性设置或返回是否在页面加载后立即加载视频。可赋值如下: + *
    + *
  • auto 指示一旦页面加载,则开始加载视频。
  • + *
  • metadata 指示当页面加载后仅加载音频/视频的元数据。
  • + *
  • none 指示页面加载后不应加载音频/视频。
  • + *
+ */ + get preload():string; + set preload(value:string); + + /** + * 参见 http://www.w3school.com.cn/tags/av_prop_seekable.asp。 + */ + get seekable():any; + + /** + * seeking 属性返回用户目前是否在音频/视频中寻址。 + * 寻址中(Seeking)指的是用户在音频/视频中移动/跳跃到新的位置。 + */ + get seeking():boolean; + + /** + * @param width + * @param height + * @override + */ + size(width:number,height:number):Sprite; + + /** + * @override + */ + set width(value:number); + + /** + * @override + */ + get width():number; + + /** + * @override + */ + set height(value:number); + + /** + * @override + */ + get height():number; + + /** + * 销毁内部事件绑定。 + * @override + */ + destroy(detroyChildren?:boolean):void; + private syncVideoPosition:any; + } + + /** + * 加速度x/y/z的单位均为m/s²。 + * 在硬件(陀螺仪)不支持的情况下,alpha、beta和gamma值为null。 + * @author Survivor + */ + class AccelerationInfo { + + /** + * x轴上的加速度值。 + */ + x:number; + + /** + * y轴上的加速度值。 + */ + y:number; + + /** + * z轴上的加速度值。 + */ + z:number; + + constructor(); + } + + /** + * Accelerator.instance获取唯一的Accelerator引用,请勿调用构造函数。 + * + *

+ * listen()的回调处理器接受四个参数: + *

    + *
  1. acceleration: 表示用户给予设备的加速度。
  2. + *
  3. accelerationIncludingGravity: 设备受到的总加速度(包含重力)。
  4. + *
  5. rotationRate: 设备的自转速率。
  6. + *
  7. interval: 加速度获取的时间间隔(毫秒)。
  8. + *
+ *

+ *

+ * NOTE
+ * 如,rotationRate的alpha在apple和moz文档中都是z轴旋转角度,但是实测是x轴旋转角度。为了使各属性表示的值与文档所述相同,实际值与其他属性进行了对调。 + * 其中: + *

    + *
  • alpha使用gamma值。
  • + *
  • beta使用alpha值。
  • + *
  • gamma使用beta。
  • + *
+ * 目前孰是孰非尚未可知,以此为注。 + *

+ */ + class Accelerator extends EventDispatcher { + + /** + * Accelerator的唯一引用。 + */ + private static _instance:any; + static get instance():Accelerator; + private static acceleration:any; + private static accelerationIncludingGravity:any; + private static rotationRate:any; + + constructor(singleton:number); + + /** + * 侦听加速器运动。 + * @param observer 回调函数接受4个参数,见类说明。 + * @override + */ + on(type:string,caller:any,listener:Function,args?:any[]):EventDispatcher; + + /** + * 取消侦听加速器。 + * @param handle 侦听加速器所用处理器。 + * @override + */ + off(type:string,caller:any,listener:Function,onceOnly?:boolean):EventDispatcher; + private onDeviceOrientationChange:any; + private static transformedAcceleration:any; + + /** + * 把加速度值转换为视觉上正确的加速度值。依赖于Browser.window.orientation,可能在部分低端机无效。 + * @param acceleration + * @return + */ + static getTransformedAcceleration(acceleration:AccelerationInfo):AccelerationInfo; + } + + /** + * 使用Gyroscope.instance获取唯一的Gyroscope引用,请勿调用构造函数。 + * + *

+ * listen()的回调处理器接受两个参数: + * function onOrientationChange(absolute:Boolean, info:RotationInfo):void + *

    + *
  1. absolute: 指示设备是否可以提供绝对方位数据(指向地球坐标系),或者设备决定的任意坐标系。关于坐标系参见https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Orientation_and_motion_data_explained
  2. + *
  3. info: RotationInfo类型参数,保存设备的旋转值。
  4. + *
+ *

+ * + *

+ * 浏览器兼容性参见:http://caniuse.com/#search=deviceorientation + *

+ */ + class Gyroscope extends EventDispatcher { + private static info:any; + + /** + * Gyroscope的唯一引用。 + */ + private static _instance:any; + static get instance():Gyroscope; + + constructor(singleton:number); + + /** + * 监视陀螺仪运动。 + * @param observer 回调函数接受一个Boolean类型的absoluteGyroscopeInfo类型参数。 + * @override + */ + on(type:string,caller:any,listener:Function,args?:any[]):EventDispatcher; + + /** + * 取消指定处理器对陀螺仪的监视。 + * @param observer + * @override + */ + off(type:string,caller:any,listener:Function,onceOnly?:boolean):EventDispatcher; + private onDeviceOrientationChange:any; + } + + /** + * 保存旋转信息的类。请勿修改本类的属性。 + * @author Survivor + */ + class RotationInfo { + + /** + *

+ * 指示设备是否可以提供绝对方位数据(指向地球坐标系),或者设备决定的任意坐标系。 + * 关于坐标系参见https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Orientation_and_motion_data_explained。 + *

+ * 需要注意的是,IOS环境下,该值始终为false。即使如此,你依旧可以从alpha中取得正确的值。 + */ + absolute:boolean; + + /** + * Z轴旋转角度,其值范围从0至360。 + * 若absolute为true或者在IOS中,alpha值是从北方到当前设备方向的角度值。 + */ + alpha:number; + + /** + * X轴旋转角度, 其值范围从-180至180。代表设备从前至后的运动。 + */ + beta:number; + + /** + * Y轴旋转角度,其值范围从-90至90。代表设备从左至右的运动。 + */ + gamma:number; + + /** + * 罗盘数据的精确度(角度)。仅IOS可用。 + */ + compassAccuracy:number; + + constructor(); + } + + /** + * Shake只能在支持此操作的设备上有效。 + */ + class Shake extends EventDispatcher { + private throushold:any; + private shakeInterval:any; + private callback:any; + private lastX:any; + private lastY:any; + private lastZ:any; + private lastMillSecond:any; + + constructor(); + private static _instance:any; + static get instance():Shake; + + /** + * 开始响应设备摇晃。 + * @param throushold 响应的瞬时速度阈值,轻度摇晃的值约在5~10间。 + * @param timeout 设备摇晃的响应间隔时间。 + * @param callback 在设备摇晃触发时调用的处理器。 + */ + start(throushold:number,interval:number):void; + + /** + * 停止响应设备摇晃。 + */ + stop():void; + private onShake:any; + private isShaked:any; + } + + /** + * 动画播放完毕后调度。 + * @eventType Event.COMPLETE + */ + + /** + * 播放到某标签后调度。 + * @eventType Event.LABEL + */ + + /** + *

Animation 是Graphics动画类。实现了基于Graphics的动画创建、播放、控制接口。

+ *

本类使用了动画模版缓存池,它以一定的内存开销来节省CPU开销,当相同的动画模版被多次使用时,相比于每次都创建新的动画模版,使用动画模版缓存池,只需创建一次,缓存之后多次复用,从而节省了动画模版创建的开销。

+ *

动画模版缓存池,以key-value键值对存储,key可以自定义,也可以从指定的配置文件中读取,value为对应的动画模版,是一个Graphics对象数组,每个Graphics对象对应一个帧图像,动画的播放实质就是定时切换Graphics对象。

+ *

使用set source、loadImages(...)、loadAtlas(...)、loadAnimation(...)方法可以创建动画模版。使用play(...)可以播放指定动画。

+ * @example 以下示例代码,创建了一个 Text 实例。 package { import laya.display.Animation; import laya.net.Loader; import laya.utils.Handler; public class Animation_Example { public function Animation_Example() { Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 init();//初始化 } private function init():void { var animation:Animation = new Animation();//创建一个 Animation 类的实例对象 animation 。 animation.loadAtlas("resource/ani/fighter.json");//加载图集并播放 animation.x = 200;//设置 animation 对象的属性 x 的值,用于控制 animation 对象的显示位置。 animation.y = 200;//设置 animation 对象的属性 x 的值,用于控制 animation 对象的显示位置。 animation.interval = 50;//设置 animation 对象的动画播放间隔时间,单位:毫秒。 animation.play();//播放动画。 Laya.stage.addChild(animation);//将 animation 对象添加到显示列表。 } } } + * @example Animation_Example(); function Animation_Example(){ Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 init();//初始化 } function init() { var animation = new Laya.Animation();//创建一个 Animation 类的实例对象 animation 。 animation.loadAtlas("resource/ani/fighter.json");//加载图集并播放 animation.x = 200;//设置 animation 对象的属性 x 的值,用于控制 animation 对象的显示位置。 animation.y = 200;//设置 animation 对象的属性 x 的值,用于控制 animation 对象的显示位置。 animation.interval = 50;//设置 animation 对象的动画播放间隔时间,单位:毫秒。 animation.play();//播放动画。 Laya.stage.addChild(animation);//将 animation 对象添加到显示列表。 } + * @example import Animation = laya.display.Animation; class Animation_Example { constructor() { Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 this.init(); } private init(): void { var animation:Animation = new Laya.Animation();//创建一个 Animation 类的实例对象 animation 。 animation.loadAtlas("resource/ani/fighter.json");//加载图集并播放 animation.x = 200;//设置 animation 对象的属性 x 的值,用于控制 animation 对象的显示位置。 animation.y = 200;//设置 animation 对象的属性 x 的值,用于控制 animation 对象的显示位置。 animation.interval = 50;//设置 animation 对象的动画播放间隔时间,单位:毫秒。 animation.play();//播放动画。 Laya.stage.addChild(animation);//将 animation 对象添加到显示列表。 } } new Animation_Example(); + */ + class Animation extends AnimationBase { + + /** + *

动画模版缓存池,以key-value键值对存储,key可以自定义,也可以从指定的配置文件中读取,value为对应的动画模版,是一个Graphics对象数组,每个Graphics对象对应一个帧图像,动画的播放实质就是定时切换Graphics对象。

+ *

使用loadImages(...)、loadAtlas(...)、loadAnimation(...)、set source方法可以创建动画模版。使用play(...)可以播放指定动画。

+ */ + static framesMap:any; + + /** + * @private + */ + protected _frames:any[]; + + /** + * @private + */ + protected _url:string; + + /** + * 创建一个新的 Animation 实例。 + */ + + constructor(); + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + *

开始播放动画。会在动画模版缓存池中查找key值为name的动画模版,存在则用此动画模版初始化当前序列帧, 如果不存在,则使用当前序列帧。

+ *

play(...)方法被设计为在创建实例后的任何时候都可以被调用,调用后就处于播放状态,当相应的资源加载完毕、调用动画帧填充方法(set frames)或者将实例显示在舞台上时,会判断是否处于播放状态,如果是,则开始播放。

+ *

配合wrapMode属性,可设置动画播放顺序类型。

+ * @param start (可选)指定动画播放开始的索引(int)或帧标签(String)。帧标签可以通过addLabel(...)和removeLabel(...)进行添加和删除。 + * @param loop (可选)是否循环播放。 + * @param name (可选)动画模板在动画模版缓存池中的key,也可认为是动画名称。如果name为空,则播放当前动画序列帧;如果不为空,则在动画模版缓存池中寻找key值为name的动画模版,如果存在则用此动画模版初始化当前序列帧并播放,如果不存在,则仍然播放当前动画序列帧;如果没有当前动画的帧数据,则不播放,但该实例仍然处于播放状态。 + * @override + */ + play(start?:any,loop?:boolean,name?:string):void; + + /** + * @private + */ + protected _setFramesFromCache(name:string,showWarn?:boolean):boolean; + + /** + * @private + */ + private _copyLabels:any; + + /** + * @private + * @override + */ + protected _frameLoop():void; + + /** + * @private + * @override + */ + protected _displayToIndex(value:number):void; + + /** + * 当前动画的帧图像数组。本类中,每个帧图像是一个Graphics对象,而动画播放就是定时切换Graphics对象的过程。 + */ + get frames():any[]; + set frames(value:any[]); + + /** + *

动画数据源。

+ *

类型如下:
+ * 1. LayaAir IDE动画文件路径:使用此类型需要预加载所需的图集资源,否则会创建失败,如果不想预加载或者需要创建完毕的回调,请使用loadAnimation(...)方法;
+ * 2. 图集路径:使用此类型创建的动画模版不会被缓存到动画模版缓存池中,如果需要缓存或者创建完毕的回调,请使用loadAtlas(...)方法;
+ * 3. 图片路径集合:使用此类型创建的动画模版不会被缓存到动画模版缓存池中,如果需要缓存,请使用loadImages(...)方法。

+ * @param value 数据源。比如:图集:"xx/a1.atlas";图片集合:"a1.png,a2.png,a3.png";LayaAir IDE动画"xx/a1.ani"。 + */ + set source(value:string); + + /** + * 设置自动播放的动画名称,在LayaAir IDE中可以创建的多个动画组成的动画集合,选择其中一个动画名称进行播放。 + */ + set autoAnimation(value:string); + + /** + * 是否自动播放,默认为false。如果设置为true,则动画被创建并添加到舞台后自动播放。 + */ + set autoPlay(value:boolean); + + /** + * 停止动画播放,并清理对象属性。之后可存入对象池,方便对象复用。 + * @override + */ + clear():AnimationBase; + + /** + *

根据指定的动画模版初始化当前动画序列帧。选择动画模版的过程如下:1. 动画模版缓存池中key为cacheName的动画模版;2. 如果不存在,则加载指定的图片集合并创建动画模版。注意:只有指定不为空的cacheName,才能将创建好的动画模版以此为key缓存到动画模版缓存池,否则不进行缓存。

+ *

动画模版缓存池是以一定的内存开销来节省CPU开销,当相同的动画模版被多次使用时,相比于每次都创建新的动画模版,使用动画模版缓存池,只需创建一次,缓存之后多次复用,从而节省了动画模版创建的开销。

+ *

因为返回值为Animation对象本身,所以可以使用如下语法:loadImages(...).loadImages(...).play(...);。

+ * @param urls 图片路径集合。需要创建动画模版时,会以此为数据源。参数形如:[url1,url2,url3,...]。 + * @param cacheName (可选)动画模板在动画模版缓存池中的key。如果此参数不为空,表示使用动画模版缓存池。如果动画模版缓存池中存在key为cacheName的动画模版,则使用此模版。否则,创建新的动画模版,如果cacheName不为空,则以cacheName为key缓存到动画模版缓存池中,如果cacheName为空,不进行缓存。 + * @return 返回Animation对象本身。 + */ + loadImages(urls:any[],cacheName?:string):Animation; + + /** + *

根据指定的动画模版初始化当前动画序列帧。选择动画模版的过程如下:1. 动画模版缓存池中key为cacheName的动画模版;2. 如果不存在,则加载指定的图集并创建动画模版。

+ *

注意:只有指定不为空的cacheName,才能将创建好的动画模版以此为key缓存到动画模版缓存池,否则不进行缓存。

+ *

动画模版缓存池是以一定的内存开销来节省CPU开销,当相同的动画模版被多次使用时,相比于每次都创建新的动画模版,使用动画模版缓存池,只需创建一次,缓存之后多次复用,从而节省了动画模版创建的开销。

+ *

因为返回值为Animation对象本身,所以可以使用如下语法:loadAtlas(...).loadAtlas(...).play(...);。

+ * @param url 图集路径。需要创建动画模版时,会以此为数据源。 + * @param loaded (可选)使用指定图集初始化动画完毕的回调。 + * @param cacheName (可选)动画模板在动画模版缓存池中的key。如果此参数不为空,表示使用动画模版缓存池。如果动画模版缓存池中存在key为cacheName的动画模版,则使用此模版。否则,创建新的动画模版,如果cacheName不为空,则以cacheName为key缓存到动画模版缓存池中,如果cacheName为空,不进行缓存。 + * @return 返回动画本身。 + */ + loadAtlas(url:string,loaded?:Handler,cacheName?:string):Animation; + + /** + *

加载并解析由LayaAir IDE制作的动画文件,此文件中可能包含多个动画。默认帧率为在IDE中设计的帧率,如果调用过set interval,则使用此帧间隔对应的帧率。加载后创建动画模版,并缓存到动画模版缓存池,key "url#动画名称" 对应相应动画名称的动画模板,key "url#" 对应动画模版集合的默认动画模版。

+ *

注意:如果调用本方法前,还没有预加载动画使用的图集,请将atlas参数指定为对应的图集路径,否则会导致动画创建失败。

+ *

动画模版缓存池是以一定的内存开销来节省CPU开销,当相同的动画模版被多次使用时,相比于每次都创建新的动画模版,使用动画模版缓存池,只需创建一次,缓存之后多次复用,从而节省了动画模版创建的开销。

+ *

因为返回值为Animation对象本身,所以可以使用如下语法:loadAnimation(...).loadAnimation(...).play(...);。

+ * @param url 动画文件路径。可由LayaAir IDE创建并发布。 + * @param loaded (可选)使用指定动画资源初始化动画完毕的回调。 + * @param atlas (可选)动画用到的图集地址(可选)。 + * @return 返回动画本身。 + */ + loadAnimation(url:string,loaded?:Handler,atlas?:string):Animation; + + /** + * @private + */ + private _loadAnimationData:any; + + /** + *

创建动画模板,多个动画可共享同一份动画模板,而不必每次都创建一份新的,从而节省创建Graphics集合的开销。

+ * @param url 图集路径或者图片路径数组。如果是图集路径,需要相应图集已经被预加载,如果没有预加载,会导致创建失败。 + * @param name 动画模板在动画模版缓存池中的key。如果不为空,则以此为key缓存动画模板,否则不缓存。 + * @return 动画模板。 + */ + static createFrames(url:string|string[],name:string):any[]; + + /** + *

从动画模版缓存池中清除指定key值的动画数据。

+ *

开发者在调用创建动画模版函数时,可以手动指定此值。而如果是由LayaAir IDE创建的动画集,解析后的key格式为:"url#":表示动画集的默认动画模版,如果以此值为参数,会清除整个动画集数据;"url#aniName":表示相应名称的动画模版。

+ * @param key 动画模板在动画模版缓存池中的key。 + */ + static clearCache(key:string):void; + } + + /** + * 动画播放完毕后调度。 + * @eventType Event.COMPLETE + */ + + /** + * 播放到某标签后调度。 + * @eventType Event.LABEL + */ + + /** + *

动画基类,提供了基础的动画播放控制方法和帧标签事件相关功能。

+ *

可以继承此类,但不要直接实例化此类,因为有些方法需要由子类实现。

+ */ + class AnimationBase extends Sprite { + + /** + * 动画播放顺序类型:正序播放。 + */ + static WRAP_POSITIVE:number; + + /** + * 动画播放顺序类型:逆序播放。 + */ + static WRAP_REVERSE:number; + + /** + * 动画播放顺序类型:pingpong播放(当按指定顺序播放完结尾后,如果继续播放,则会改变播放顺序)。 + */ + static WRAP_PINGPONG:number; + + /** + * 是否循环播放,调用play(...)方法时,会将此值设置为指定的参数值。 + */ + loop:boolean; + + /** + * 播放顺序类型:AnimationBase.WRAP_POSITIVE为正序播放(默认值),AnimationBase.WRAP_REVERSE为倒序播放,AnimationBase.WRAP_PINGPONG为pingpong播放(当按指定顺序播放完结尾后,如果继续播发,则会改变播放顺序)。 + */ + wrapMode:number; + + /** + * @private 播放间隔(单位:毫秒)。 + */ + protected _interval:number; + + /** + * @private + */ + protected _index:number; + + /** + * @private + */ + protected _count:number; + + /** + * @private + */ + protected _isPlaying:boolean; + + /** + * @private + */ + protected _labels:any; + + /** + * 是否是逆序播放 + */ + protected _isReverse:boolean; + + /** + * @private + */ + protected _frameRateChanged:boolean; + + /** + * @private + */ + protected _actionName:string; + + /** + * @private + */ + private _controlNode:any; + + /** + * 可以继承此类,但不要直接实例化此类,因为有些方法需要由子类实现。 + */ + + constructor(); + + /** + *

开始播放动画。play(...)方法被设计为在创建实例后的任何时候都可以被调用,当相应的资源加载完毕、调用动画帧填充方法(set frames)或者将实例显示在舞台上时,会判断是否正在播放中,如果是,则进行播放。

+ *

配合wrapMode属性,可设置动画播放顺序类型。

+ * @param start (可选)指定动画播放开始的索引(int)或帧标签(String)。帧标签可以通过addLabel(...)和removeLabel(...)进行添加和删除。 + * @param loop (可选)是否循环播放。 + * @param name (可选)动画名称。 + */ + play(start?:any,loop?:boolean,name?:string):void; + + /** + *

动画播放的帧间隔时间(单位:毫秒)。默认值依赖于Config.animationInterval=50,通过Config.animationInterval可以修改默认帧间隔时间。

+ *

要想为某动画设置独立的帧间隔时间,可以使用set interval,注意:如果动画正在播放,设置后会重置帧循环定时器的起始时间为当前时间,也就是说,如果频繁设置interval,会导致动画帧更新的时间间隔会比预想的要慢,甚至不更新。

+ */ + get interval():number; + set interval(value:number); + + /** + * @private + */ + protected _getFrameByLabel(label:string):number; + + /** + * @private + */ + protected _frameLoop():void; + + /** + * @private + */ + protected _resumePlay():void; + + /** + * 停止动画播放。 + */ + stop():void; + + /** + * 是否正在播放中。 + */ + get isPlaying():boolean; + + /** + * 增加一个帧标签到指定索引的帧上。当动画播放到此索引的帧时会派发Event.LABEL事件,派发事件是在完成当前帧画面更新之后。 + * @param label 帧标签名称 + * @param index 帧索引 + */ + addLabel(label:string,index:number):void; + + /** + * 删除指定的帧标签。 + * @param label 帧标签名称。注意:如果为空,则删除所有帧标签! + */ + removeLabel(label:string):void; + + /** + * @private + */ + private _removeLabelFromList:any; + + /** + * 将动画切换到指定帧并停在那里。 + * @param position 帧索引或帧标签 + */ + gotoAndStop(position:any):void; + + /** + * 动画当前帧的索引。 + */ + get index():number; + set index(value:number); + + /** + * @private 显示到某帧 + * @param value 帧索引 + */ + protected _displayToIndex(value:number):void; + + /** + * 当前动画中帧的总数。 + */ + get count():number; + + /** + * 停止动画播放,并清理对象属性。之后可存入对象池,方便对象复用。 + * @return 返回对象本身 + */ + clear():AnimationBase; + } + + /** + * BitmapFont 是位图字体类,用于定义位图字体信息。 + * 字体制作及使用方法,请参考文章 + * @see http://ldc2.layabox.com/doc/?nav=ch-js-1-2-5 + */ + class BitmapFont { + private _texture:any; + private _fontCharDic:any; + private _fontWidthMap:any; + private _complete:any; + private _path:any; + private _maxWidth:any; + private _spaceWidth:any; + private _padding:any; + + /** + * 当前位图字体字号,使用时,如果字号和设置不同,并且autoScaleSize=true,则按照设置字号比率进行缩放显示。 + */ + fontSize:number; + + /** + * 表示是否根据实际使用的字体大小缩放位图字体大小。 + */ + autoScaleSize:boolean; + + /** + * 字符间距(以像素为单位)。 + */ + letterSpacing:number; + + /** + * 通过指定位图字体文件路径,加载位图字体文件,加载完成后会自动解析。 + * @param path 位图字体文件的路径。 + * @param complete 加载并解析完成的回调。 + */ + loadFont(path:string,complete:Handler):void; + + /** + * @private + */ + private _onLoaded:any; + + /** + * 解析字体文件。 + * @param xml 字体文件XML。 + * @param texture 字体的纹理。 + */ + parseFont(xml:XMLDocument,texture:Texture):void; + + /** + * 解析字体文件。 + * @param xml 字体文件XML。 + * @param texture 字体的纹理。 + */ + parseFont2(xml:XMLDocument,texture:Texture):void; + + /** + * 获取指定字符的字体纹理对象。 + * @param char 字符。 + * @return 指定的字体纹理对象。 + */ + getCharTexture(char:string):Texture; + + /** + * 销毁位图字体,调用Text.unregisterBitmapFont 时,默认会销毁。 + */ + destroy():void; + + /** + * 设置空格的宽(如果字体库有空格,这里就可以不用设置了)。 + * @param spaceWidth 宽度,单位为像素。 + */ + setSpaceWidth(spaceWidth:number):void; + + /** + * 获取指定字符的宽度。 + * @param char 字符。 + * @return 宽度。 + */ + getCharWidth(char:string):number; + + /** + * 获取指定文本内容的宽度。 + * @param text 文本内容。 + * @return 宽度。 + */ + getTextWidth(text:string):number; + + /** + * 获取最大字符宽度。 + */ + getMaxWidth():number; + + /** + * 获取最大字符高度。 + */ + getMaxHeight():number; + } + + /** + * 透明命令 + */ + class AlphaCmd { + static ID:string; + + /** + * 透明度 + */ + alpha:number; + + /** + * @private + */ + static create(alpha:number):AlphaCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 裁剪命令 + */ + class ClipRectCmd { + static ID:string; + + /** + * X 轴偏移量。 + */ + x:number; + + /** + * Y 轴偏移量。 + */ + y:number; + + /** + * 宽度。 + */ + width:number; + + /** + * 高度。 + */ + height:number; + + /** + * @private + */ + static create(x:number,y:number,width:number,height:number):ClipRectCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 绘制圆形 + */ + class DrawCircleCmd { + static ID:string; + + /** + * 圆点X 轴位置。 + */ + x:number; + + /** + * 圆点Y 轴位置。 + */ + y:number; + + /** + * 半径。 + */ + radius:number; + + /** + * 填充颜色,或者填充绘图的渐变对象。 + */ + fillColor:any; + + /** + * (可选)边框颜色,或者填充绘图的渐变对象。 + */ + lineColor:any; + + /** + * (可选)边框宽度。 + */ + lineWidth:number; + + /** + * @private + */ + vid:number; + + /** + * @private + */ + static create(x:number,y:number,radius:number,fillColor:any,lineColor:any,lineWidth:number,vid:number):DrawCircleCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 绘制曲线 + */ + class DrawCurvesCmd { + static ID:string; + + /** + * 开始绘制的 X 轴位置。 + */ + x:number; + + /** + * 开始绘制的 Y 轴位置。 + */ + y:number; + + /** + * 线段的点集合,格式[controlX, controlY, anchorX, anchorY...]。 + */ + points:number[]|null; + + /** + * 线段颜色,或者填充绘图的渐变对象。 + */ + lineColor:any; + + /** + * (可选)线段宽度。 + */ + lineWidth:number; + + /** + * @private + */ + static create(x:number,y:number,points:any[],lineColor:any,lineWidth:number):DrawCurvesCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 绘制图片 + */ + class DrawImageCmd { + static ID:string; + + /** + * 纹理。 + */ + texture:Texture|null; + + /** + * (可选)X轴偏移量。 + */ + x:number; + + /** + * (可选)Y轴偏移量。 + */ + y:number; + + /** + * (可选)宽度。 + */ + width:number; + + /** + * (可选)高度。 + */ + height:number; + + /** + * @private + */ + static create(texture:Texture,x:number,y:number,width:number,height:number):DrawImageCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 绘制单条曲线 + */ + class DrawLineCmd { + static ID:string; + + /** + * X轴开始位置。 + */ + fromX:number; + + /** + * Y轴开始位置。 + */ + fromY:number; + + /** + * X轴结束位置。 + */ + toX:number; + + /** + * Y轴结束位置。 + */ + toY:number; + + /** + * 颜色。 + */ + lineColor:string; + + /** + * (可选)线条宽度。 + */ + lineWidth:number; + + /** + * @private + */ + vid:number; + + /** + * @private + */ + static create(fromX:number,fromY:number,toX:number,toY:number,lineColor:string,lineWidth:number,vid:number):DrawLineCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 绘制连续曲线 + */ + class DrawLinesCmd { + static ID:string; + + /** + * 开始绘制的X轴位置。 + */ + x:number; + + /** + * 开始绘制的Y轴位置。 + */ + y:number; + + /** + * 线段的点集合。格式:[x1,y1,x2,y2,x3,y3...]。 + */ + points:number[]|null; + + /** + * 线段颜色,或者填充绘图的渐变对象。 + */ + lineColor:any; + + /** + * (可选)线段宽度。 + */ + lineWidth:number; + + /** + * @private + */ + vid:number; + + /** + * @private + */ + static create(x:number,y:number,points:any[],lineColor:any,lineWidth:number,vid:number):DrawLinesCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 绘制粒子 + * @private + */ + class DrawParticleCmd { + static ID:string; + private _templ:any; + + /** + * @private + */ + static create(_temp:any):DrawParticleCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 根据路径绘制矢量图形 + */ + class DrawPathCmd { + static ID:string; + + /** + * 开始绘制的 X 轴位置。 + */ + x:number; + + /** + * 开始绘制的 Y 轴位置。 + */ + y:number; + + /** + * 路径集合,路径支持以下格式:[["moveTo",x,y],["lineTo",x,y],["arcTo",x1,y1,x2,y2,r],["closePath"]]。 + */ + paths:any[]|null; + + /** + * (可选)刷子定义,支持以下设置{fillStyle:"#FF0000"}。 + */ + brush:any; + + /** + * (可选)画笔定义,支持以下设置{strokeStyle,lineWidth,lineJoin:"bevel|round|miter",lineCap:"butt|round|square",miterLimit}。 + */ + pen:any; + + /** + * @private + */ + static create(x:number,y:number,paths:any[],brush:any,pen:any):DrawPathCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 绘制扇形 + */ + class DrawPieCmd { + static ID:string; + + /** + * 开始绘制的 X 轴位置。 + */ + x:number; + + /** + * 开始绘制的 Y 轴位置。 + */ + y:number; + + /** + * 扇形半径。 + */ + radius:number; + private _startAngle:any; + private _endAngle:any; + + /** + * 填充颜色,或者填充绘图的渐变对象。 + */ + fillColor:any; + + /** + * (可选)边框颜色,或者填充绘图的渐变对象。 + */ + lineColor:any; + + /** + * (可选)边框宽度。 + */ + lineWidth:number; + + /** + * @private + */ + vid:number; + + /** + * @private + */ + static create(x:number,y:number,radius:number,startAngle:number,endAngle:number,fillColor:any,lineColor:any,lineWidth:number,vid:number):DrawPieCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + + /** + * 开始角度。 + */ + get startAngle():number; + set startAngle(value:number); + + /** + * 结束角度。 + */ + get endAngle():number; + set endAngle(value:number); + } + + /** + * 绘制多边形 + */ + class DrawPolyCmd { + static ID:string; + + /** + * 开始绘制的 X 轴位置。 + */ + x:number; + + /** + * 开始绘制的 Y 轴位置。 + */ + y:number; + + /** + * 多边形的点集合。 + */ + points:number[]|null; + + /** + * 填充颜色,或者填充绘图的渐变对象。 + */ + fillColor:any; + + /** + * (可选)边框颜色,或者填充绘图的渐变对象。 + */ + lineColor:any; + + /** + * 可选)边框宽度。 + */ + lineWidth:number; + + /** + * @private + */ + isConvexPolygon:boolean; + + /** + * @private + */ + vid:number; + + /** + * @private + */ + static create(x:number,y:number,points:any[],fillColor:any,lineColor:any,lineWidth:number,isConvexPolygon:boolean,vid:number):DrawPolyCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 绘制矩形 + */ + class DrawRectCmd { + static ID:string; + + /** + * 开始绘制的 X 轴位置。 + */ + x:number; + + /** + * 开始绘制的 Y 轴位置。 + */ + y:number; + + /** + * 矩形宽度。 + */ + width:number; + + /** + * 矩形高度。 + */ + height:number; + + /** + * 填充颜色,或者填充绘图的渐变对象。 + */ + fillColor:any; + + /** + * (可选)边框颜色,或者填充绘图的渐变对象。 + */ + lineColor:any; + + /** + * (可选)边框宽度。 + */ + lineWidth:number; + + /** + * @private + */ + static create(x:number,y:number,width:number,height:number,fillColor:any,lineColor:any,lineWidth:number):DrawRectCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 绘制单个贴图 + */ + class DrawTextureCmd { + static ID:string; + + /** + * 纹理。 + */ + texture:Texture|null; + + /** + * (可选)X轴偏移量。 + */ + x:number; + + /** + * (可选)Y轴偏移量。 + */ + y:number; + + /** + * (可选)宽度。 + */ + width:number; + + /** + * (可选)高度。 + */ + height:number; + + /** + * (可选)矩阵信息。 + */ + matrix:Matrix|null; + + /** + * (可选)透明度。 + */ + alpha:number; + + /** + * (可选)颜色滤镜。 + */ + color:string|null; + colorFlt:ColorFilter|null; + + /** + * (可选)混合模式。 + */ + blendMode:string|null; + uv:number[]|null; + + /** + * @private + */ + static create(texture:Texture,x:number,y:number,width:number,height:number,matrix:Matrix|null,alpha:number,color:string|null,blendMode:string|null,uv?:number[]):DrawTextureCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 根据坐标集合绘制多个贴图 + */ + class DrawTexturesCmd { + static ID:string; + + /** + * 纹理。 + */ + texture:Texture; + + /** + * 绘制次数和坐标。 + */ + pos:any[]; + + /** + * @private + */ + static create(texture:Texture,pos:any[]):DrawTexturesCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 绘制三角形命令 + */ + class DrawTrianglesCmd { + static ID:string; + + /** + * 纹理。 + */ + texture:Texture|null; + + /** + * X轴偏移量。 + */ + x:number; + + /** + * Y轴偏移量。 + */ + y:number; + + /** + * 顶点数组。 + */ + vertices:Float32Array; + + /** + * UV数据。 + */ + uvs:Float32Array; + + /** + * 顶点索引。 + */ + indices:Uint16Array; + + /** + * 缩放矩阵。 + */ + matrix:Matrix|null; + + /** + * alpha + */ + alpha:number; + + /** + * blend模式 + */ + blendMode:string|null; + + /** + * 颜色变换 + */ + color:ColorFilter; + colorNum:number|null; + + /** + * @private + */ + static create(texture:Texture,x:number,y:number,vertices:Float32Array,uvs:Float32Array,indices:Uint16Array,matrix:Matrix|null,alpha:number,color:string|null,blendMode:string|null,colorNum:number|null):DrawTrianglesCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 绘制文字 + */ + class FillTextCmd { + static ID:string; + private _text:any; + _words:HTMLChar[]|null; + + /** + * 开始绘制文本的 x 坐标位置(相对于画布)。 + */ + x:number; + + /** + * 开始绘制文本的 y 坐标位置(相对于画布)。 + */ + y:number; + private _font:any; + private _color:any; + private _borderColor:any; + private _lineWidth:any; + private _textAlign:any; + private _fontColor:any; + private _strokeColor:any; + private static _defFontObj:any; + private _fontObj:any; + private _nTexAlign:any; + + /** + * @private + */ + static create(text:string|WordText|null,words:HTMLChar[]|null,x:number,y:number,font:string,color:string|null,textAlign:string,lineWidth:number,borderColor:string|null):FillTextCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + + /** + * 在画布上输出的文本。 + */ + get text():string|WordText|null; + set text(value:string|WordText|null); + + /** + * 定义字号和字体,比如"20px Arial"。 + */ + get font():string; + set font(value:string); + + /** + * 定义文本颜色,比如"#ff0000"。 + */ + get color():string; + set color(value:string); + + /** + * 文本对齐方式,可选值:"left","center","right"。 + */ + get textAlign():string; + set textAlign(value:string); + } + + /** + * 填充贴图 + */ + class FillTextureCmd { + static ID:string; + + /** + * 纹理。 + */ + texture:Texture; + + /** + * X轴偏移量。 + */ + x:number; + + /** + * Y轴偏移量。 + */ + y:number; + + /** + * (可选)宽度。 + */ + width:number; + + /** + * (可选)高度。 + */ + height:number; + + /** + * (可选)填充类型 repeat|repeat-x|repeat-y|no-repeat + */ + type:string; + + /** + * (可选)贴图纹理偏移 + */ + offset:Point; + + /** + * @private + */ + other:any; + + /** + * @private + */ + static create(texture:Texture,x:number,y:number,width:number,height:number,type:string,offset:Point,other:any):FillTextureCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 恢复命令,和save配套使用 + */ + class RestoreCmd { + static ID:string; + + /** + * @private + */ + static create():RestoreCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 旋转命令 + */ + class RotateCmd { + static ID:string; + + /** + * 旋转角度,以弧度计。 + */ + angle:number; + + /** + * (可选)水平方向轴心点坐标。 + */ + pivotX:number; + + /** + * (可选)垂直方向轴心点坐标。 + */ + pivotY:number; + + /** + * @private + */ + static create(angle:number,pivotX:number,pivotY:number):RotateCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 存储命令,和restore配套使用 + */ + class SaveCmd { + static ID:string; + + /** + * @private + */ + static create():SaveCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 缩放命令 + */ + class ScaleCmd { + static ID:string; + + /** + * 水平方向缩放值。 + */ + scaleX:number; + + /** + * 垂直方向缩放值。 + */ + scaleY:number; + + /** + * (可选)水平方向轴心点坐标。 + */ + pivotX:number; + + /** + * (可选)垂直方向轴心点坐标。 + */ + pivotY:number; + + /** + * @private + */ + static create(scaleX:number,scaleY:number,pivotX:number,pivotY:number):ScaleCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 矩阵命令 + */ + class TransformCmd { + static ID:string; + + /** + * 矩阵。 + */ + matrix:Matrix; + + /** + * (可选)水平方向轴心点坐标。 + */ + pivotX:number; + + /** + * (可选)垂直方向轴心点坐标。 + */ + pivotY:number; + + /** + * @private + */ + static create(matrix:Matrix,pivotX:number,pivotY:number):TransformCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 位移命令 + */ + class TranslateCmd { + static ID:string; + + /** + * 添加到水平坐标(x)上的值。 + */ + tx:number; + + /** + * 添加到垂直坐标(y)上的值。 + */ + ty:number; + + /** + * @private + */ + static create(tx:number,ty:number):TranslateCmd; + + /** + * 回收到对象池 + */ + recover():void; + + /** + * @private + */ + run(context:Context,gx:number,gy:number):void; + + /** + * @private + */ + get cmdID():string; + } + + /** + * 元素样式 + */ + class SpriteStyle { + static EMPTY:SpriteStyle; + + /** + * 水平缩放 + */ + scaleX:number; + + /** + * 垂直缩放 + */ + scaleY:number; + + /** + * 水平倾斜角度 + */ + skewX:number; + + /** + * 垂直倾斜角度 + */ + skewY:number; + + /** + * X轴心点 + */ + pivotX:number; + + /** + * Y轴心点 + */ + pivotY:number; + + /** + * 旋转角度 + */ + rotation:number; + + /** + * 透明度 + */ + alpha:number; + + /** + * 滚动区域 + */ + scrollRect:Rectangle; + + /** + * 视口 + */ + viewport:Rectangle; + + /** + * 点击区域 + */ + hitArea:any; + + /** + * 滑动 + */ + dragging:Dragging; + + /** + * 混合模式 + */ + blendMode:string; + + constructor(); + + /** + * 重置,方便下次复用 + */ + reset():SpriteStyle; + + /** + * 回收 + */ + recover():void; + + /** + * 从对象池中创建 + */ + static create():SpriteStyle; + } + + /** + * 文本的样式类 + */ + class TextStyle extends SpriteStyle { + + /** + * 一个已初始化的 TextStyle 实例。 + */ + static EMPTY:TextStyle; + + /** + * 表示使用此文本格式的文本是否为斜体。 + * @default false + */ + italic:boolean; + + /** + *

表示使用此文本格式的文本段落的水平对齐方式。

+ * @default "left" + */ + align:string; + + /** + *

表示使用此文本格式的文本字段是否自动换行。

+ * 如果 wordWrap 的值为 true,则该文本字段自动换行;如果值为 false,则该文本字段不自动换行。 + * @default false。 + */ + wordWrap:boolean; + + /** + *

垂直行间距(以像素为单位)

+ */ + leading:number; + + /** + *

默认边距信息

+ *

[左边距,上边距,右边距,下边距](边距以像素为单位)

+ */ + padding:any[]; + + /** + * 文本背景颜色,以字符串表示。 + */ + bgColor:string|null; + + /** + * 文本边框背景颜色,以字符串表示。 + */ + borderColor:string|null; + + /** + *

指定文本字段是否是密码文本字段。

+ * 如果此属性的值为 true,则文本字段被视为密码文本字段,并使用星号而不是实际字符来隐藏输入的字符。如果为 false,则不会将文本字段视为密码文本字段。 + */ + asPassword:boolean; + + /** + *

描边宽度(以像素为单位)。

+ * 默认值0,表示不描边。 + * @default 0 + */ + stroke:number; + + /** + *

描边颜色,以字符串表示。

+ * @default "#000000"; + */ + strokeColor:string; + + /** + * 是否为粗体 + */ + bold:boolean; + + /** + * 是否显示下划线 + */ + underline:boolean; + + /** + * 下划线颜色 + */ + underlineColor:string|null; + + /** + * 当前使用的位置字体。 + */ + currBitmapFont:BitmapFont|null; + + /** + * @override + */ + reset():SpriteStyle; + + /** + * @override + */ + recover():void; + + /** + * 从对象池中创建 + */ + static create():TextStyle; + + /** + * @inheritDoc + */ + render(sprite:Sprite,context:Context,x:number,y:number):void; + } + + /** + *

动效模板。用于为指定目标对象添加动画效果。每个动效有唯一的目标对象,而同一个对象可以添加多个动效。 当一个动效开始播放时,其他动效会自动停止播放。

+ *

可以通过LayaAir IDE创建。

+ */ + class EffectAnimation extends FrameAnimation { + + /** + * @private 动效开始事件。 + */ + private static EFFECT_BEGIN:any; + + /** + * 本实例的目标对象。通过本实例控制目标对象的属性变化。 + * @param v 指定的目标对象。 + */ + set target(v:any); + get target():any; + + /** + * @private + */ + private _onOtherBegin:any; + + /** + * 设置开始播放的事件。本实例会侦听目标对象的指定事件,触发后播放相应动画效果。 + * @param event + */ + set playEvent(event:string); + + /** + * @param start + * @param loop + * @param name + * @override + */ + play(start?:any,loop?:boolean,name?:string):void; + + /** + * @private + */ + private _recordInitData:any; + + /** + * 设置提供数据的类。 + * @param classStr 类路径 + */ + set effectClass(classStr:string); + + /** + * 设置动画数据。 + * @param uiData + */ + set effectData(uiData:any); + + /** + * @override + */ + protected _displayNodeToFrame(node:any,frame:number,targetDic?:any):void; + } + + /** + * 动画播放完毕后调度。 + * @eventType Event.COMPLETE + */ + + /** + * 播放到某标签后调度。 + * @eventType Event.LABEL + */ + + /** + * 节点关键帧动画播放类。解析播放IDE内制作的节点动画。 + */ + class FrameAnimation extends AnimationBase { + + /** + * @private + */ + private static _sortIndexFun:any; + + /** + * @private + */ + protected _usedFrames:any[]; + + constructor(); + + /** + * @inheritDoc + * @override + */ + clear():AnimationBase; + + /** + * @inheritDoc + * @override + */ + protected _displayToIndex(value:number):void; + + /** + * @private 将节点设置到某一帧的状态 + * @param node 节点ID + * @param frame + * @param targetDic 节点表 + */ + protected _displayNodeToFrame(node:any,frame:number,targetDic?:any):void; + + /** + * @private 计算帧数据 + */ + private _calculateDatas:any; + + /** + * @private 计算某个节点的帧数据 + */ + protected _calculateKeyFrames(node:any):void; + + /** + * 重置节点,使节点恢复到动画之前的状态,方便其他动画控制 + */ + resetNodes():void; + + /** + * @private 计算节点某个属性的帧数据 + */ + private _calculateNodePropFrames:any; + + /** + * @private + */ + private _dealKeyFrame:any; + + /** + * @private 计算两个关键帧直接的帧数据 + */ + private _calculateFrameValues:any; + } + + /** + * Graphics 类用于创建绘图显示对象。Graphics可以同时绘制多个位图或者矢量图,还可以结合save,restore,transform,scale,rotate,translate,alpha等指令对绘图效果进行变化。 + * Graphics以命令流方式存储,可以通过cmds属性访问所有命令流。Graphics是比Sprite更轻量级的对象,合理使用能提高应用性能(比如把大量的节点绘图改为一个节点的Graphics命令集合,能减少大量节点创建消耗)。 + * @see laya.display.Sprite#graphics + */ + class Graphics { + + /** + * @private + */ + private _cmds:any; + + /** + * @private + */ + protected _vectorgraphArray:any[]|null; + + /** + * @private + */ + private _graphicBounds:any; + + /** + * @private + */ + autoDestroy:boolean; + + constructor(); + + /** + *

销毁此对象。

+ */ + destroy():void; + + /** + *

清空绘制命令。

+ * @param recoverCmds 是否回收绘图指令数组,设置为true,则对指令数组进行回收以节省内存开销,建议设置为true进行回收,但如果手动引用了数组,不建议回收 + */ + clear(recoverCmds?:boolean):void; + + /** + * @private + */ + private _clearBoundsCache:any; + + /** + * @private + */ + private _initGraphicBounds:any; + + /** + * @private 命令流。存储了所有绘制命令。 + */ + get cmds():any[]; + set cmds(value:any[]); + + /** + * 获取位置及宽高信息矩阵(比较耗CPU,频繁使用会造成卡顿,尽量少用)。 + * @param realSize (可选)使用图片的真实大小,默认为false + * @return 位置与宽高组成的 一个 Rectangle 对象。 + */ + getBounds(realSize?:boolean):Rectangle; + + /** + * @private + * @param realSize (可选)使用图片的真实大小,默认为false 获取端点列表。 + */ + getBoundPoints(realSize?:boolean):any[]; + + /** + * 绘制单独图片 + * @param texture 纹理。 + * @param x (可选)X轴偏移量。 + * @param y (可选)Y轴偏移量。 + * @param width (可选)宽度。 + * @param height (可选)高度。 + */ + drawImage(texture:Texture,x?:number,y?:number,width?:number,height?:number):DrawImageCmd|null; + + /** + * 绘制纹理,相比drawImage功能更强大,性能会差一些 + * @param texture 纹理。 + * @param x (可选)X轴偏移量。 + * @param y (可选)Y轴偏移量。 + * @param width (可选)宽度。 + * @param height (可选)高度。 + * @param matrix (可选)矩阵信息。 + * @param alpha (可选)透明度。 + * @param color (可选)颜色滤镜。 + * @param blendMode (可选)混合模式。 + */ + drawTexture(texture:Texture|null,x?:number,y?:number,width?:number,height?:number,matrix?:Matrix|null,alpha?:number,color?:string|null,blendMode?:string|null,uv?:number[]):DrawTextureCmd|null; + + /** + * 批量绘制同样纹理。 + * @param texture 纹理。 + * @param pos 绘制次数和坐标。 + */ + drawTextures(texture:Texture,pos:any[]):DrawTexturesCmd|null; + + /** + * 绘制一组三角形 + * @param texture 纹理。 + * @param x X轴偏移量。 + * @param y Y轴偏移量。 + * @param vertices 顶点数组。 + * @param indices 顶点索引。 + * @param uvData UV数据。 + * @param matrix 缩放矩阵。 + * @param alpha alpha + * @param color 颜色变换 + * @param blendMode blend模式 + */ + drawTriangles(texture:Texture,x:number,y:number,vertices:Float32Array,uvs:Float32Array,indices:Uint16Array,matrix?:Matrix|null,alpha?:number,color?:string|null,blendMode?:string|null,colorNum?:number):DrawTrianglesCmd; + + /** + * 用texture填充。 + * @param texture 纹理。 + * @param x X轴偏移量。 + * @param y Y轴偏移量。 + * @param width (可选)宽度。 + * @param height (可选)高度。 + * @param type (可选)填充类型 repeat|repeat-x|repeat-y|no-repeat + * @param offset (可选)贴图纹理偏移 + */ + fillTexture(texture:Texture,x:number,y:number,width?:number,height?:number,type?:string,offset?:Point|null):FillTextureCmd|null; + + /** + * 设置剪裁区域,超出剪裁区域的坐标不显示。 + * @param x X 轴偏移量。 + * @param y Y 轴偏移量。 + * @param width 宽度。 + * @param height 高度。 + */ + clipRect(x:number,y:number,width:number,height:number):ClipRectCmd; + + /** + * 在画布上绘制文本。 + * @param text 在画布上输出的文本。 + * @param x 开始绘制文本的 x 坐标位置(相对于画布)。 + * @param y 开始绘制文本的 y 坐标位置(相对于画布)。 + * @param font 定义字号和字体,比如"20px Arial"。 + * @param color 定义文本颜色,比如"#ff0000"。 + * @param textAlign 文本对齐方式,可选值:"left","center","right"。 + */ + fillText(text:string,x:number,y:number,font:string,color:string,textAlign:string):FillTextCmd; + + /** + * 在画布上绘制“被填充且镶边的”文本。 + * @param text 在画布上输出的文本。 + * @param x 开始绘制文本的 x 坐标位置(相对于画布)。 + * @param y 开始绘制文本的 y 坐标位置(相对于画布)。 + * @param font 定义字体和字号,比如"20px Arial"。 + * @param fillColor 定义文本颜色,比如"#ff0000"。 + * @param textAlign 文本对齐方式,可选值:"left","center","right"。 + * @param lineWidth 镶边线条宽度。 + * @param borderColor 定义镶边文本颜色。 + */ + fillBorderText(text:string,x:number,y:number,font:string,fillColor:string,textAlign:string,lineWidth:number,borderColor:string):FillTextCmd; + + /** + * * @private + */ + fillWords(words:any[],x:number,y:number,font:string,color:string):FillTextCmd; + + /** + * * @private + */ + fillBorderWords(words:any[],x:number,y:number,font:string,fillColor:string,borderColor:string,lineWidth:number):FillTextCmd; + + /** + * 在画布上绘制文本(没有填色)。文本的默认颜色是黑色。 + * @param text 在画布上输出的文本。 + * @param x 开始绘制文本的 x 坐标位置(相对于画布)。 + * @param y 开始绘制文本的 y 坐标位置(相对于画布)。 + * @param font 定义字体和字号,比如"20px Arial"。 + * @param color 定义文本颜色,比如"#ff0000"。 + * @param lineWidth 线条宽度。 + * @param textAlign 文本对齐方式,可选值:"left","center","right"。 + */ + strokeText(text:string,x:number,y:number,font:string,color:string,lineWidth:number,textAlign:string):FillTextCmd; + + /** + * 设置透明度。 + * @param value 透明度。 + */ + alpha(alpha:number):AlphaCmd; + + /** + * 替换绘图的当前转换矩阵。 + * @param mat 矩阵。 + * @param pivotX (可选)水平方向轴心点坐标。 + * @param pivotY (可选)垂直方向轴心点坐标。 + */ + transform(matrix:Matrix,pivotX?:number,pivotY?:number):TransformCmd; + + /** + * 旋转当前绘图。(推荐使用transform,性能更高) + * @param angle 旋转角度,以弧度计。 + * @param pivotX (可选)水平方向轴心点坐标。 + * @param pivotY (可选)垂直方向轴心点坐标。 + */ + rotate(angle:number,pivotX?:number,pivotY?:number):RotateCmd; + + /** + * 缩放当前绘图至更大或更小。(推荐使用transform,性能更高) + * @param scaleX 水平方向缩放值。 + * @param scaleY 垂直方向缩放值。 + * @param pivotX (可选)水平方向轴心点坐标。 + * @param pivotY (可选)垂直方向轴心点坐标。 + */ + scale(scaleX:number,scaleY:number,pivotX?:number,pivotY?:number):ScaleCmd; + + /** + * 重新映射画布上的 (0,0) 位置。 + * @param x 添加到水平坐标(x)上的值。 + * @param y 添加到垂直坐标(y)上的值。 + */ + translate(tx:number,ty:number):TranslateCmd; + + /** + * 保存当前环境的状态。 + */ + save():SaveCmd; + + /** + * 返回之前保存过的路径状态和属性。 + */ + restore():RestoreCmd; + + /** + * @private 替换文本内容。 + * @param text 文本内容。 + * @return 替换成功则值为true,否则值为flase。 + */ + replaceText(text:string):boolean; + + /** + * @private + */ + private _isTextCmd:any; + + /** + * @private 替换文本颜色。 + * @param color 颜色。 + */ + replaceTextColor(color:string):void; + + /** + * @private + */ + private _setTextCmdColor:any; + + /** + * 加载并显示一个图片。 + * @param url 图片地址。 + * @param x (可选)显示图片的x位置。 + * @param y (可选)显示图片的y位置。 + * @param width (可选)显示图片的宽度,设置为0表示使用图片默认宽度。 + * @param height (可选)显示图片的高度,设置为0表示使用图片默认高度。 + * @param complete (可选)加载完成回调。 + */ + loadImage(url:string,x?:number,y?:number,width?:number,height?:number,complete?:Function|null):void; + + /** + * 绘制一条线。 + * @param fromX X轴开始位置。 + * @param fromY Y轴开始位置。 + * @param toX X轴结束位置。 + * @param toY Y轴结束位置。 + * @param lineColor 颜色。 + * @param lineWidth (可选)线条宽度。 + */ + drawLine(fromX:number,fromY:number,toX:number,toY:number,lineColor:string,lineWidth?:number):DrawLineCmd; + + /** + * 绘制一系列线段。 + * @param x 开始绘制的X轴位置。 + * @param y 开始绘制的Y轴位置。 + * @param points 线段的点集合。格式:[x1,y1,x2,y2,x3,y3...]。 + * @param lineColor 线段颜色,或者填充绘图的渐变对象。 + * @param lineWidth (可选)线段宽度。 + */ + drawLines(x:number,y:number,points:any[],lineColor:any,lineWidth?:number):DrawLinesCmd|null; + + /** + * 绘制一系列曲线。 + * @param x 开始绘制的 X 轴位置。 + * @param y 开始绘制的 Y 轴位置。 + * @param points 线段的点集合,格式[controlX, controlY, anchorX, anchorY...]。 + * @param lineColor 线段颜色,或者填充绘图的渐变对象。 + * @param lineWidth (可选)线段宽度。 + */ + drawCurves(x:number,y:number,points:any[],lineColor:any,lineWidth?:number):DrawCurvesCmd; + + /** + * 绘制矩形。 + * @param x 开始绘制的 X 轴位置。 + * @param y 开始绘制的 Y 轴位置。 + * @param width 矩形宽度。 + * @param height 矩形高度。 + * @param fillColor 填充颜色,或者填充绘图的渐变对象。 + * @param lineColor (可选)边框颜色,或者填充绘图的渐变对象。 + * @param lineWidth (可选)边框宽度。 + */ + drawRect(x:number,y:number,width:number,height:number,fillColor:any,lineColor?:any,lineWidth?:number):DrawRectCmd; + + /** + * 绘制圆形。 + * @param x 圆点X 轴位置。 + * @param y 圆点Y 轴位置。 + * @param radius 半径。 + * @param fillColor 填充颜色,或者填充绘图的渐变对象。 + * @param lineColor (可选)边框颜色,或者填充绘图的渐变对象。 + * @param lineWidth (可选)边框宽度。 + */ + drawCircle(x:number,y:number,radius:number,fillColor:any,lineColor?:any,lineWidth?:number):DrawCircleCmd; + + /** + * 绘制扇形。 + * @param x 开始绘制的 X 轴位置。 + * @param y 开始绘制的 Y 轴位置。 + * @param radius 扇形半径。 + * @param startAngle 开始角度。 + * @param endAngle 结束角度。 + * @param fillColor 填充颜色,或者填充绘图的渐变对象。 + * @param lineColor (可选)边框颜色,或者填充绘图的渐变对象。 + * @param lineWidth (可选)边框宽度。 + */ + drawPie(x:number,y:number,radius:number,startAngle:number,endAngle:number,fillColor:any,lineColor?:any,lineWidth?:number):DrawPieCmd; + + /** + * 绘制多边形。 + * @param x 开始绘制的 X 轴位置。 + * @param y 开始绘制的 Y 轴位置。 + * @param points 多边形的点集合。 + * @param fillColor 填充颜色,或者填充绘图的渐变对象。 + * @param lineColor (可选)边框颜色,或者填充绘图的渐变对象。 + * @param lineWidth (可选)边框宽度。 + */ + drawPoly(x:number,y:number,points:any[],fillColor:any,lineColor?:any,lineWidth?:number):DrawPolyCmd; + + /** + * 绘制路径。 + * @param x 开始绘制的 X 轴位置。 + * @param y 开始绘制的 Y 轴位置。 + * @param paths 路径集合,路径支持以下格式:[["moveTo",x,y],["lineTo",x,y],["arcTo",x1,y1,x2,y2,r],["closePath"]]。 + * @param brush (可选)刷子定义,支持以下设置{fillStyle:"#FF0000"}。 + * @param pen (可选)画笔定义,支持以下设置{strokeStyle,lineWidth,lineJoin:"bevel|round|miter",lineCap:"butt|round|square",miterLimit}。 + */ + drawPath(x:number,y:number,paths:any[],brush?:any,pen?:any):DrawPathCmd; + + /** + * @private 绘制带九宫格的图片 + * @param texture + * @param x + * @param y + * @param width + * @param height + * @param sizeGrid + */ + draw9Grid(texture:Texture,x:number,y:number,width:number,height:number,sizeGrid:any[]):void; + } + + /** + * @private Graphic bounds数据类 + */ + class GraphicsBounds { + + /** + * @private + */ + private static _tempMatrix:any; + + /** + * @private + */ + private static _initMatrix:any; + + /** + * @private + */ + private static _tempPoints:any; + + /** + * @private + */ + private static _tempMatrixArrays:any; + + /** + * @private + */ + private static _tempCmds:any; + + /** + * @private + */ + private _temp:any; + + /** + * @private + */ + private _bounds:any; + + /** + * @private + */ + private _rstBoundPoints:any; + + /** + * @private + */ + private _cacheBoundsType:any; + + /** + * 销毁 + */ + destroy():void; + + /** + * 创建 + */ + static create():GraphicsBounds; + + /** + * 重置数据 + */ + reset():void; + + /** + * 获取位置及宽高信息矩阵(比较耗CPU,频繁使用会造成卡顿,尽量少用)。 + * @param realSize (可选)使用图片的真实大小,默认为false + * @return 位置与宽高组成的 一个 Rectangle 对象。 + */ + getBounds(realSize?:boolean):Rectangle; + + /** + * @private + * @param realSize (可选)使用图片的真实大小,默认为false 获取端点列表。 + */ + getBoundPoints(realSize?:boolean):any[]; + private _getCmdPoints:any; + private _switchMatrix:any; + private static _addPointArrToRst:any; + private static _addPointToRst:any; + + /** + * 获得drawPie命令可能的产生的点。注意 这里只假设用在包围盒计算上。 + * @param x + * @param y + * @param radius + * @param startAngle + * @param endAngle + * @return + */ + private _getPiePoints:any; + private _getTriAngBBXPoints:any; + private _getDraw9GridBBXPoints:any; + private _getPathPoints:any; + } + + /** + * 用户输入一个或多个文本字符时后调度。 + * @eventType Event.INPUT + */ + + /** + * 文本发生变化后调度。 + * @eventType Event.CHANGE + */ + + /** + * 用户在输入框内敲回车键后,将会调度 enter 事件。 + * @eventType Event.ENTER + */ + + /** + * 显示对象获得焦点后调度。 + * @eventType Event.FOCUS + */ + + /** + * 显示对象失去焦点后调度。 + * @eventType Event.BLUR + */ + + /** + *

Input 类用于创建显示对象以显示和输入文本。

+ *

Input 类封装了原生的文本输入框,由于不同浏览器的差异,会导致此对象的默认文本的位置与用户点击输入时的文本的位置有少许的偏差。

+ */ + class Input extends Text { + + /** + * 常规文本域。 + */ + static TYPE_TEXT:string; + + /** + * password 类型用于密码域输入。 + */ + static TYPE_PASSWORD:string; + + /** + * email 类型用于应该包含 e-mail 地址的输入域。 + */ + static TYPE_EMAIL:string; + + /** + * url 类型用于应该包含 URL 地址的输入域。 + */ + static TYPE_URL:string; + + /** + * number 类型用于应该包含数值的输入域。 + */ + static TYPE_NUMBER:string; + + /** + *

range 类型用于应该包含一定范围内数字值的输入域。

+ *

range 类型显示为滑动条。

+ *

您还能够设定对所接受的数字的限定。

+ */ + static TYPE_RANGE:string; + + /** + * 选取日、月、年。 + */ + static TYPE_DATE:string; + + /** + * month - 选取月、年。 + */ + static TYPE_MONTH:string; + + /** + * week - 选取周和年。 + */ + static TYPE_WEEK:string; + + /** + * time - 选取时间(小时和分钟)。 + */ + static TYPE_TIME:string; + + /** + * datetime - 选取时间、日、月、年(UTC 时间)。 + */ + static TYPE_DATE_TIME:string; + + /** + * datetime-local - 选取时间、日、月、年(本地时间)。 + */ + static TYPE_DATE_TIME_LOCAL:string; + + /** + *

search 类型用于搜索域,比如站点搜索或 Google 搜索。

+ *

search 域显示为常规的文本域。

+ */ + static TYPE_SEARCH:string; + + /** + * @private + */ + protected static input:HTMLInputElement; + + /** + * @private + */ + protected static area:HTMLTextAreaElement; + + /** + * @private + */ + protected static inputElement:HTMLInputElement|HTMLTextAreaElement; + + /** + * @private + */ + protected static inputContainer:HTMLDivElement; + + /** + * @private + */ + protected static confirmButton:any; + + /** + * @private + */ + protected static promptStyleDOM:any; + + /** + * @private + */ + protected _focus:boolean; + + /** + * @private + */ + protected _multiline:boolean; + + /** + * @private + */ + protected _editable:boolean; + + /** + * @private + */ + protected _restrictPattern:any; + + /** + * @private + */ + protected _maxChars:number; + private _type:any; + + /** + * 输入提示符。 + */ + private _prompt:any; + + /** + * 输入提示符颜色。 + */ + private _promptColor:any; + private _originColor:any; + private _content:any; + + /** + * @private + */ + static IOS_IFRAME:boolean; + private static inputHeight:any; + + /** + * 表示是否处于输入状态。 + */ + static isInputting:boolean; + + /** + * 创建一个新的 Input 类实例。 + */ + + constructor(); + private static _popupInputMethod:any; + private static _createInputElement:any; + private static _initInput:any; + private static _processInputting:any; + private static _stopEvent:any; + + /** + * 设置光标位置和选取字符。 + * @param startIndex 光标起始位置。 + * @param endIndex 光标结束位置。 + */ + setSelection(startIndex:number,endIndex:number):void; + + /** + * 表示是否是多行输入框。 + */ + get multiline():boolean; + set multiline(value:boolean); + + /** + * 获取对输入框的引用实例。 + */ + get nativeInput():HTMLInputElement|HTMLTextAreaElement; + private _onUnDisplay:any; + private _onMouseDown:any; + private static stageMatrix:any; + + /** + * 在输入期间,如果 Input 实例的位置改变,调用_syncInputTransform同步输入框的位置。 + */ + private _syncInputTransform:any; + + /** + * 选中当前实例的所有文本。 + */ + select():void; + + /** + * 表示焦点是否在此实例上。 + */ + get focus():boolean; + set focus(value:boolean); + private _setInputMethod:any; + private _focusIn:any; + private _setPromptColor:any; + + /** + * @private + */ + private _focusOut:any; + + /** + * @private + */ + private _onKeyDown:any; + + /** + * @inheritDoc + * @override + */ + set text(value:string); + + /** + * @override + */ + get text():string; + + /** + * @param text + * @override + */ + changeText(text:string):void; + + /** + * @inheritDoc + * @override + */ + set color(value:string); + get color():string; + + /** + * @inheritDoc + * @override + */ + set bgColor(value:string); + get bgColor():string; + + /** + * 限制输入的字符。 + */ + get restrict():string; + set restrict(pattern:string); + + /** + * 是否可编辑。 + */ + set editable(value:boolean); + get editable():boolean; + + /** + *

字符数量限制,默认为10000。

+ *

设置字符数量限制时,小于等于0的值将会限制字符数量为10000。

+ */ + get maxChars():number; + set maxChars(value:number); + + /** + * 设置输入提示符。 + */ + get prompt():string; + set prompt(value:string); + + /** + * 设置输入提示符颜色。 + */ + get promptColor():string; + set promptColor(value:string); + + /** + *

输入框类型为Input静态常量之一。

+ *
    + *
  • TYPE_TEXT
  • + *
  • TYPE_PASSWORD
  • + *
  • TYPE_EMAIL
  • + *
  • TYPE_URL
  • + *
  • TYPE_NUMBER
  • + *
  • TYPE_RANGE
  • + *
  • TYPE_DATE
  • + *
  • TYPE_MONTH
  • + *
  • TYPE_WEEK
  • + *
  • TYPE_TIME
  • + *
  • TYPE_DATE_TIME
  • + *
  • TYPE_DATE_TIME_LOCAL
  • + *
+ *

平台兼容性参见http://www.w3school.com.cn/html5/html_5_form_input_types.asp。

+ */ + get type():string; + set type(value:string); + } + + /** + * 添加到父对象后调度。 + * @eventType Event.ADDED + */ + + /** + * 被父对象移除后调度。 + * @eventType Event.REMOVED + */ + + /** + * 加入节点树时调度。 + * @eventType Event.DISPLAY + */ + + /** + * 从节点树移除时调度。 + * @eventType Event.UNDISPLAY + */ + + /** + * Node 类是可放在显示列表中的所有对象的基类。该显示列表管理 Laya 运行时中显示的所有对象。使用 Node 类排列显示列表中的显示对象。Node 对象可以有子显示对象。 + */ + class Node extends EventDispatcher { + + /** + * @private + */ + protected static ARRAY_EMPTY:any[]; + + /** + * @private + */ + private _bits:any; + + /** + * 节点名称。 + */ + name:string; + + /** + * [只读]是否已经销毁。对象销毁后不能再使用。 + */ + destroyed:boolean; + + constructor(); + createGLBuffer():void; + + /** + *

增加事件侦听器,以使侦听器能够接收事件通知。

+ *

如果侦听鼠标事件,则会自动设置自己和父亲节点的属性 mouseEnabled 的值为 true(如果父节点mouseEnabled=false,则停止设置父节点mouseEnabled属性)。

+ * @param type 事件的类型。 + * @param caller 事件侦听函数的执行域。 + * @param listener 事件侦听函数。 + * @param args (可选)事件侦听函数的回调参数。 + * @return 此 EventDispatcher 对象。 + * @override + */ + on(type:string,caller:any,listener:Function,args?:any[]):EventDispatcher; + + /** + *

增加事件侦听器,以使侦听器能够接收事件通知,此侦听事件响应一次后则自动移除侦听。

+ *

如果侦听鼠标事件,则会自动设置自己和父亲节点的属性 mouseEnabled 的值为 true(如果父节点mouseEnabled=false,则停止设置父节点mouseEnabled属性)。

+ * @param type 事件的类型。 + * @param caller 事件侦听函数的执行域。 + * @param listener 事件侦听函数。 + * @param args (可选)事件侦听函数的回调参数。 + * @return 此 EventDispatcher 对象。 + * @override + */ + once(type:string,caller:any,listener:Function,args?:any[]):EventDispatcher; + + /** + *

销毁此对象。destroy对象默认会把自己从父节点移除,并且清理自身引用关系,等待js自动垃圾回收机制回收。destroy后不能再使用。

+ *

destroy时会移除自身的事情监听,自身的timer监听,移除子对象及从父节点移除自己。

+ * @param destroyChild (可选)是否同时销毁子节点,若值为true,则销毁子节点,否则不销毁子节点。 + */ + destroy(destroyChild?:boolean):void; + + /** + * 销毁时执行 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onDestroy():void; + + /** + * 销毁所有子对象,不销毁自己本身。 + */ + destroyChildren():void; + + /** + * 添加子节点。 + * @param node 节点对象 + * @return 返回添加的节点 + */ + addChild(node:Node):Node; + addInputChild(node:Node):Node; + removeInputChild(node:Node):void; + + /** + * 批量增加子节点 + * @param ...args 无数子节点。 + */ + addChildren(...args:any[]):void; + + /** + * 添加子节点到指定的索引位置。 + * @param node 节点对象。 + * @param index 索引位置。 + * @return 返回添加的节点。 + */ + addChildAt(node:Node,index:number):Node; + + /** + * 根据子节点对象,获取子节点的索引位置。 + * @param node 子节点。 + * @return 子节点所在的索引位置。 + */ + getChildIndex(node:Node):number; + + /** + * 根据子节点的名字,获取子节点对象。 + * @param name 子节点的名字。 + * @return 节点对象。 + */ + getChildByName(name:string):Node; + + /** + * 根据子节点的索引位置,获取子节点对象。 + * @param index 索引位置 + * @return 子节点 + */ + getChildAt(index:number):Node; + + /** + * 设置子节点的索引位置。 + * @param node 子节点。 + * @param index 新的索引。 + * @return 返回子节点本身。 + */ + setChildIndex(node:Node,index:number):Node; + + /** + * 子节点发生改变。 + * @private + * @param child 子节点。 + */ + protected _childChanged(child?:Node):void; + + /** + * 删除子节点。 + * @param node 子节点 + * @return 被删除的节点 + */ + removeChild(node:Node):Node; + + /** + * 从父容器删除自己,如已经被删除不会抛出异常。 + * @return 当前节点( Node )对象。 + */ + removeSelf():Node; + + /** + * 根据子节点名字删除对应的子节点对象,如果找不到不会抛出异常。 + * @param name 对象名字。 + * @return 查找到的节点( Node )对象。 + */ + removeChildByName(name:string):Node; + + /** + * 根据子节点索引位置,删除对应的子节点对象。 + * @param index 节点索引位置。 + * @return 被删除的节点。 + */ + removeChildAt(index:number):Node; + + /** + * 删除指定索引区间的所有子对象。 + * @param beginIndex 开始索引。 + * @param endIndex 结束索引。 + * @return 当前节点对象。 + */ + removeChildren(beginIndex?:number,endIndex?:number):Node; + + /** + * 替换子节点。 + * 将传入的新节点对象替换到已有子节点索引位置处。 + * @param newNode 新节点。 + * @param oldNode 老节点。 + * @return 返回新节点。 + */ + replaceChild(newNode:Node,oldNode:Node):Node; + + /** + * 子对象数量。 + */ + get numChildren():number; + + /** + * 父节点。 + */ + get parent():Node; + + /** + * @private + */ + protected _setParent(value:Node):void; + + /** + * 表示是否在显示列表中显示。 + */ + get displayedInStage():boolean; + + /** + * @private + */ + private _updateDisplayedInstage:any; + + /** + * 设置指定节点对象是否可见(是否在渲染列表中)。 + * @private + * @param node 节点。 + * @param display 是否可见。 + */ + private _displayChild:any; + + /** + * 当前容器是否包含指定的 Node 节点对象 。 + * @param node 指定的 Node 节点对象 。 + * @return 一个布尔值表示是否包含指定的 Node 节点对象 。 + */ + contains(node:Node):boolean; + + /** + * 定时重复执行某函数。功能同Laya.timer.timerLoop()。 + * @param delay 间隔时间(单位毫秒)。 + * @param caller 执行域(this)。 + * @param method 结束时的回调方法。 + * @param args (可选)回调参数。 + * @param coverBefore (可选)是否覆盖之前的延迟执行,默认为true。 + * @param jumpFrame 时钟是否跳帧。基于时间的循环回调,单位时间间隔内,如能执行多次回调,出于性能考虑,引擎默认只执行一次,设置jumpFrame=true后,则回调会连续执行多次 + */ + timerLoop(delay:number,caller:any,method:Function,args?:any[],coverBefore?:boolean,jumpFrame?:boolean):void; + + /** + * 定时执行某函数一次。功能同Laya.timer.timerOnce()。 + * @param delay 延迟时间(单位毫秒)。 + * @param caller 执行域(this)。 + * @param method 结束时的回调方法。 + * @param args (可选)回调参数。 + * @param coverBefore (可选)是否覆盖之前的延迟执行,默认为true。 + */ + timerOnce(delay:number,caller:any,method:Function,args?:any[],coverBefore?:boolean):void; + + /** + * 定时重复执行某函数(基于帧率)。功能同Laya.timer.frameLoop()。 + * @param delay 间隔几帧(单位为帧)。 + * @param caller 执行域(this)。 + * @param method 结束时的回调方法。 + * @param args (可选)回调参数。 + * @param coverBefore (可选)是否覆盖之前的延迟执行,默认为true。 + */ + frameLoop(delay:number,caller:any,method:Function,args?:any[],coverBefore?:boolean):void; + + /** + * 定时执行一次某函数(基于帧率)。功能同Laya.timer.frameOnce()。 + * @param delay 延迟几帧(单位为帧)。 + * @param caller 执行域(this) + * @param method 结束时的回调方法 + * @param args (可选)回调参数 + * @param coverBefore (可选)是否覆盖之前的延迟执行,默认为true + */ + frameOnce(delay:number,caller:any,method:Function,args?:any[],coverBefore?:boolean):void; + + /** + * 清理定时器。功能同Laya.timer.clearTimer()。 + * @param caller 执行域(this)。 + * @param method 结束时的回调方法。 + */ + clearTimer(caller:any,method:Function):void; + + /** + *

延迟运行指定的函数。

+ *

在控件被显示在屏幕之前调用,一般用于延迟计算数据。

+ * @param method 要执行的函数的名称。例如,functionName。 + * @param args 传递给 method 函数的可选参数列表。 + * @see #runCallLater() + */ + callLater(method:Function,args?:any[]):void; + + /** + *

如果有需要延迟调用的函数(通过 callLater 函数设置),则立即执行延迟调用函数。

+ * @param method 要执行的函数名称。例如,functionName。 + * @see #callLater() + */ + runCallLater(method:Function):void; + + /** + * @private + */ + private _components:any; + + /** + * @private + */ + private _activeChangeScripts:any; + + /** + * 获得所属场景。 + * @return 场景。 + */ + get scene():any; + + /** + * 获取自身是否激活。 + * @return 自身是否激活。 + */ + get active():boolean; + + /** + * 设置是否激活。 + * @param value 是否激活。 + */ + set active(value:boolean); + + /** + * 获取在场景中是否激活。 + * @return 在场景中是否激活。 + */ + get activeInHierarchy():boolean; + + /** + * @private + */ + protected _onActive():void; + + /** + * @private + */ + protected _onInActive():void; + + /** + * @private + */ + protected _onActiveInScene():void; + + /** + * @private + */ + protected _onInActiveInScene():void; + + /** + * 组件被激活后执行,此时所有节点和组件均已创建完毕,次方法只执行一次 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onAwake():void; + + /** + * 组件被启用后执行,比如节点被添加到舞台后 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onEnable():void; + + /** + * @private + */ + private _activeScripts:any; + + /** + * @private + */ + private _processInActive:any; + + /** + * @private + */ + private _inActiveScripts:any; + + /** + * 组件被禁用时执行,比如从节点从舞台移除后 + * 此方法为虚方法,使用时重写覆盖即可 + */ + onDisable():void; + + /** + * @private + */ + protected _onAdded():void; + + /** + * @private + */ + protected _onRemoved():void; + + /** + * 添加组件实例。 + * @param component 组建实例。 + * @return 组件。 + */ + addComponentIntance(component:Component):any; + + /** + * 添加组件。 + * @param componentType 组件类型。 + * @return 组件。 + */ + addComponent(componentType:typeof Component):any; + + /** + * 获得组件实例,如果没有则返回为null + * @param componentType 组建类型 + * @return 返回组件 + */ + getComponent(componentType:typeof Component):any; + + /** + * 获得组件实例,如果没有则返回为null + * @param componentType 组建类型 + * @return 返回组件数组 + */ + getComponents(componentType:typeof Component):any[]; + + /** + * @private 获取timer + */ + get timer():Timer; + } + + /** + * 场景类,负责场景创建,加载,销毁等功能 + * 场景被从节点移除后,并不会被自动垃圾机制回收,如果想回收,请调用destroy接口,可以通过unDestroyedScenes属性查看还未被销毁的场景列表 + */ + class Scene extends Sprite { + + /** + * 创建后,还未被销毁的场景列表,方便查看还未被销毁的场景列表,方便内存管理,本属性只读,请不要直接修改 + */ + static unDestroyedScenes:any[]; + + /** + * 获取根节点 + */ + private static _root:any; + + /** + * @private + */ + private static _loadPage:any; + + /** + * 场景被关闭后,是否自动销毁(销毁节点和使用到的资源),默认为false + */ + autoDestroyAtClosed:boolean; + + /** + * 场景地址 + */ + url:string; + + /** + * 场景时钟 + */ + private _timer:any; + + /** + * @private + */ + private _viewCreated:any; + + constructor(createChildren?:boolean); + + /** + * @private 兼容老项目 + */ + protected createChildren():void; + + /** + * 兼容加载模式 + * 加载模式设置uimap + * @param url uimapJosn的url + */ + static setUIMap(url:string):void; + + /** + * @private 兼容老项目 装载场景视图。用于加载模式。 + * @param path 场景地址。 + */ + loadScene(path:string):void; + private _onSceneLoaded:any; + + /** + * @private 兼容老项目 通过视图数据创建视图。 + * @param uiView 视图数据信息。 + */ + createView(view:any):void; + + /** + * 根据IDE内的节点id,获得节点实例 + */ + getNodeByID(id:number):any; + + /** + * 打开场景。【注意】被关闭的场景,如果没有设置autoDestroyAtRemoved=true,则资源可能不能被回收,需要自己手动回收 + * @param closeOther 是否关闭其他场景,默认为true(可选) + * @param param 打开页面的参数,会传递给onOpened方法(可选) + */ + open(closeOther?:boolean,param?:any):void; + + /** + * 场景打开完成后,调用此方法(如果有弹出动画,则在动画完成后执行) + */ + onOpened(param:any):void; + + /** + * 关闭场景 + * 【注意】被关闭的场景,如果没有设置autoDestroyAtRemoved=true,则资源可能不能被回收,需要自己手动回收 + * @param type 关闭的原因,会传递给onClosed函数 + */ + close(type?:string):void; + + /** + * 关闭完成后,调用此方法(如果有关闭动画,则在动画完成后执行) + * @param type 如果是点击默认关闭按钮触发,则传入关闭按钮的名字(name),否则为null。 + */ + onClosed(type?:string):void; + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * @inheritDoc + * @override + */ + set scaleX(value:number); + + /** + * @inheritDoc + * @override + */ + get scaleX():number; + + /** + * @inheritDoc + * @override + */ + set scaleY(value:number); + + /** + * @inheritDoc + * @override + */ + get scaleY():number; + + /** + * @inheritDoc + * @override + */ + get width():number; + + /** + * @inheritDoc + * @override + */ + set width(value:number); + + /** + * @inheritDoc + * @override + */ + get height():number; + + /** + * @inheritDoc + * @override + */ + set height(value:number); + + /** + * @private + */ + protected _sizeChanged():void; + + /** + * 获取场景根容器 + */ + static get root():Sprite; + + /** + * 场景时钟 + * @override + */ + get timer():Timer; + set timer(value:Timer); + + /** + * 加载场景及场景使用到的资源 + * @param url 场景地址 + * @param complete 加载完成回调,返回场景实例(可选) + * @param progress 加载进度回调(可选) + */ + static load(url:string,complete?:Handler,progress?:Handler):void; + + /** + * 加载并打开场景 + * @param url 场景地址 + * @param closeOther 是否关闭其他场景,默认为true(可选),【注意】被关闭的场景,如果没有设置autoDestroyAtRemoved=true,则资源可能不能被回收,需要自己手动回收 + * @param param 打开页面的参数,会传递给onOpened方法(可选) + * @param complete 打开完成回调,返回场景实例(可选) + * @param progress 加载进度回调(可选) + */ + static open(url:string,closeOther?:boolean,param?:any,complete?:Handler,progress?:Handler):void; + + /** + * @private + */ + private static _onSceneLoaded:any; + + /** + * 根据地址,关闭场景(包括对话框) + * @param url 场景地址 + * @param name 如果name不为空,name必须相同才能关闭 + * @return 返回是否关闭成功,如果url找不到,则不成功 + */ + static close(url:string,name?:string):boolean; + + /** + * 关闭所有场景,不包括对话框,如果关闭对话框,请使用Dialog.closeAll() + * 【注意】被关闭的场景,如果没有设置autoDestroyAtRemoved=true,则资源可能不能被回收,需要自己手动回收 + */ + static closeAll():void; + + /** + * 根据地址,销毁场景(包括对话框) + * @param url 场景地址 + * @param name 如果name不为空,name必须相同才能关闭 + * @return 返回是否销毁成功,如果url找不到,则不成功 + */ + static destroy(url:string,name?:string):boolean; + + /** + * 销毁当前没有被使用的资源,该函数会忽略lock=true的资源。 + */ + static gc():void; + + /** + * 设置loading界面,引擎会在调用open方法后,延迟打开loading界面,在页面添加到舞台之后,关闭loading界面 + * @param loadPage load界面实例 + */ + static setLoadingPage(loadPage:Scene):void; + + /** + * 显示loading界面 + * @param param 打开参数,如果是scene,则会传递给onOpened方法 + * @param delay 延迟打开时间,默认500毫秒 + */ + static showLoadingPage(param?:any,delay?:number):void; + private static _showLoading:any; + private static _hideLoading:any; + + /** + * 隐藏loading界面 + * @param delay 延迟关闭时间,默认500毫秒 + */ + static hideLoadingPage(delay?:number):void; + } + + /** + * 在显示对象上按下后调度。 + * @eventType Event.MOUSE_DOWN + */ + + /** + * 在显示对象抬起后调度。 + * @eventType Event.MOUSE_UP + */ + + /** + * 鼠标在对象身上进行移动后调度 + * @eventType Event.MOUSE_MOVE + */ + + /** + * 鼠标经过对象后调度。 + * @eventType Event.MOUSE_OVER + */ + + /** + * 鼠标离开对象后调度。 + * @eventType Event.MOUSE_OUT + */ + + /** + * 鼠标点击对象后调度。 + * @eventType Event.CLICK + */ + + /** + * 开始拖动后调度。 + * @eventType Event.DRAG_START + */ + + /** + * 拖动中调度。 + * @eventType Event.DRAG_MOVE + */ + + /** + * 拖动结束后调度。 + * @eventType Event.DRAG_END + */ + + /** + *

Sprite 是基本的显示图形的显示列表节点。 Sprite 默认没有宽高,默认不接受鼠标事件。通过 graphics 可以绘制图片或者矢量图,支持旋转,缩放,位移等操作。Sprite同时也是容器类,可用来添加多个子节点。

+ *

注意: Sprite 默认没有宽高,可以通过getBounds函数获取;也可手动设置宽高;还可以设置autoSize=true,然后再获取宽高。Sprite的宽高一般用于进行碰撞检测和排版,并不影响显示图像大小,如果需要更改显示图像大小,请使用 scaleXscaleYscale

+ *

Sprite 默认不接受鼠标事件,即mouseEnabled=false,但是只要对其监听任意鼠标事件,会自动打开自己以及所有父对象的mouseEnabled=true。所以一般也无需手动设置mouseEnabled

+ *

LayaAir引擎API设计精简巧妙。核心显示类只有一个SpriteSprite针对不同的情况做了渲染优化,所以保证一个类实现丰富功能的同时,又达到高性能。

+ * @example 创建了一个 Sprite 实例。 package { import laya.display.Sprite; import laya.events.Event; public class Sprite_Example { private var sprite:Sprite; private var shape:Sprite public function Sprite_Example() { Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 onInit(); } private function onInit():void { sprite = new Sprite();//创建一个 Sprite 类的实例对象 sprite 。 sprite.loadImage("resource/ui/bg.png");//加载并显示图片。 sprite.x = 200;//设置 sprite 对象相对于父容器的水平方向坐标值。 sprite.y = 200;//设置 sprite 对象相对于父容器的垂直方向坐标值。 sprite.pivotX = 0;//设置 sprite 对象的水平方法轴心点坐标。 sprite.pivotY = 0;//设置 sprite 对象的垂直方法轴心点坐标。 Laya.stage.addChild(sprite);//将此 sprite 对象添加到显示列表。 sprite.on(Event.CLICK, this, onClickSprite);//给 sprite 对象添加点击事件侦听。 shape = new Sprite();//创建一个 Sprite 类的实例对象 sprite 。 shape.graphics.drawRect(0, 0, 100, 100, "#ccff00", "#ff0000", 2);//绘制一个有边框的填充矩形。 shape.x = 400;//设置 shape 对象相对于父容器的水平方向坐标值。 shape.y = 200;//设置 shape 对象相对于父容器的垂直方向坐标值。 shape.width = 100;//设置 shape 对象的宽度。 shape.height = 100;//设置 shape 对象的高度。 shape.pivotX = 50;//设置 shape 对象的水平方法轴心点坐标。 shape.pivotY = 50;//设置 shape 对象的垂直方法轴心点坐标。 Laya.stage.addChild(shape);//将此 shape 对象添加到显示列表。 shape.on(Event.CLICK, this, onClickShape);//给 shape 对象添加点击事件侦听。 } private function onClickSprite():void { trace("点击 sprite 对象。"); sprite.rotation += 5;//旋转 sprite 对象。 } private function onClickShape():void { trace("点击 shape 对象。"); shape.rotation += 5;//旋转 shape 对象。 } } } + * @example var sprite; var shape; Sprite_Example(); function Sprite_Example() { Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 onInit(); } function onInit() { sprite = new laya.display.Sprite();//创建一个 Sprite 类的实例对象 sprite 。 sprite.loadImage("resource/ui/bg.png");//加载并显示图片。 sprite.x = 200;//设置 sprite 对象相对于父容器的水平方向坐标值。 sprite.y = 200;//设置 sprite 对象相对于父容器的垂直方向坐标值。 sprite.pivotX = 0;//设置 sprite 对象的水平方法轴心点坐标。 sprite.pivotY = 0;//设置 sprite 对象的垂直方法轴心点坐标。 Laya.stage.addChild(sprite);//将此 sprite 对象添加到显示列表。 sprite.on(Event.CLICK, this, onClickSprite);//给 sprite 对象添加点击事件侦听。 shape = new laya.display.Sprite();//创建一个 Sprite 类的实例对象 sprite 。 shape.graphics.drawRect(0, 0, 100, 100, "#ccff00", "#ff0000", 2);//绘制一个有边框的填充矩形。 shape.x = 400;//设置 shape 对象相对于父容器的水平方向坐标值。 shape.y = 200;//设置 shape 对象相对于父容器的垂直方向坐标值。 shape.width = 100;//设置 shape 对象的宽度。 shape.height = 100;//设置 shape 对象的高度。 shape.pivotX = 50;//设置 shape 对象的水平方法轴心点坐标。 shape.pivotY = 50;//设置 shape 对象的垂直方法轴心点坐标。 Laya.stage.addChild(shape);//将此 shape 对象添加到显示列表。 shape.on(laya.events.Event.CLICK, this, onClickShape);//给 shape 对象添加点击事件侦听。 } function onClickSprite() { console.log("点击 sprite 对象。"); sprite.rotation += 5;//旋转 sprite 对象。 } function onClickShape() { console.log("点击 shape 对象。"); shape.rotation += 5;//旋转 shape 对象。 } + * @example import Sprite = laya.display.Sprite; class Sprite_Example { private sprite: Sprite; private shape: Sprite public Sprite_Example() { Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 this.onInit(); } private onInit(): void { this.sprite = new Sprite();//创建一个 Sprite 类的实例对象 sprite 。 this.sprite.loadImage("resource/ui/bg.png");//加载并显示图片。 this.sprite.x = 200;//设置 sprite 对象相对于父容器的水平方向坐标值。 this.sprite.y = 200;//设置 sprite 对象相对于父容器的垂直方向坐标值。 this.sprite.pivotX = 0;//设置 sprite 对象的水平方法轴心点坐标。 this.sprite.pivotY = 0;//设置 sprite 对象的垂直方法轴心点坐标。 Laya.stage.addChild(this.sprite);//将此 sprite 对象添加到显示列表。 this.sprite.on(laya.events.Event.CLICK, this, this.onClickSprite);//给 sprite 对象添加点击事件侦听。 this.shape = new Sprite();//创建一个 Sprite 类的实例对象 sprite 。 this.shape.graphics.drawRect(0, 0, 100, 100, "#ccff00", "#ff0000", 2);//绘制一个有边框的填充矩形。 this.shape.x = 400;//设置 shape 对象相对于父容器的水平方向坐标值。 this.shape.y = 200;//设置 shape 对象相对于父容器的垂直方向坐标值。 this.shape.width = 100;//设置 shape 对象的宽度。 this.shape.height = 100;//设置 shape 对象的高度。 this.shape.pivotX = 50;//设置 shape 对象的水平方法轴心点坐标。 this.shape.pivotY = 50;//设置 shape 对象的垂直方法轴心点坐标。 Laya.stage.addChild(this.shape);//将此 shape 对象添加到显示列表。 this.shape.on(laya.events.Event.CLICK, this, this.onClickShape);//给 shape 对象添加点击事件侦听。 } private onClickSprite(): void { console.log("点击 sprite 对象。"); this.sprite.rotation += 5;//旋转 sprite 对象。 } private onClickShape(): void { console.log("点击 shape 对象。"); this.shape.rotation += 5;//旋转 shape 对象。 } } + */ + class Sprite extends Node { + + /** + *

鼠标事件与此对象的碰撞检测是否可穿透。碰撞检测发生在鼠标事件的捕获阶段,此阶段引擎会从stage开始递归检测stage及其子对象,直到找到命中的目标对象或者未命中任何对象。

+ *

穿透表示鼠标事件发生的位置处于本对象绘图区域内时,才算命中,而与对象宽高和值为Rectangle对象的hitArea属性无关。如果sprite.hitArea值是HitArea对象,表示显式声明了此对象的鼠标事件响应区域,而忽略对象的宽高、mouseThrough属性。

+ *

影响对象鼠标事件响应区域的属性为:width、height、hitArea,优先级顺序为:hitArea(type:HitArea)>hitArea(type:Rectangle)>width/height。

+ * @default false 不可穿透,此对象的鼠标响应区域由width、height、hitArea属性决定。

+ */ + mouseThrough:boolean; + + /** + *

指定是否自动计算宽高数据。默认值为 false 。

+ *

Sprite宽高默认为0,并且不会随着绘制内容的变化而变化,如果想根据绘制内容获取宽高,可以设置本属性为true,或者通过getBounds方法获取。设置为true,对性能有一定影响。

+ */ + autoSize:boolean; + + /** + *

指定鼠标事件检测是优先检测自身,还是优先检测其子对象。鼠标事件检测发生在鼠标事件的捕获阶段,此阶段引擎会从stage开始递归检测stage及其子对象,直到找到命中的目标对象或者未命中任何对象。

+ *

如果为false,优先检测子对象,当有子对象被命中时,中断检测,获得命中目标。如果未命中任何子对象,最后再检测此对象;如果为true,则优先检测本对象,如果本对象没有被命中,直接中断检测,表示没有命中目标;如果本对象被命中,则进一步递归检测其子对象,以确认最终的命中目标。

+ *

合理使用本属性,能减少鼠标事件检测的节点,提高性能。可以设置为true的情况:开发者并不关心此节点的子节点的鼠标事件检测结果,也就是以此节点作为其子节点的鼠标事件检测依据。

+ *

Stage对象和UI的View组件默认为true。

+ * @default false 优先检测此对象的子对象,当递归检测完所有子对象后,仍然没有找到目标对象,最后再检测此对象。 + */ + hitTestPrior:boolean; + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + constructor(); + + /** + * 根据zOrder进行重新排序。 + */ + updateZOrder():void; + + /** + * 设置是否开启自定义渲染,只有开启自定义渲染,才能使用customRender函数渲染。 + */ + set customRenderEnable(b:boolean); + + /** + * 指定显示对象是否缓存为静态图像,cacheAs时,子对象发生变化,会自动重新缓存,同时也可以手动调用reCache方法更新缓存。 + * 建议把不经常变化的“复杂内容”缓存为静态图像,能极大提高渲染性能。cacheAs有"none","normal"和"bitmap"三个值可选。 + * 默认为"none",不做任何缓存。 + * 当值为"normal"时,canvas模式下进行画布缓存,webgl模式下进行命令缓存。 + * 当值为"bitmap"时,canvas模式下进行依然是画布缓存,webgl模式下使用renderTarget缓存。 + * webgl下renderTarget缓存模式缺点:会额外创建renderTarget对象,增加内存开销,缓存面积有最大2048限制,不断重绘时会增加CPU开销。优点:大幅减少drawcall,渲染性能最高。 + * webgl下命令缓存模式缺点:只会减少节点遍历及命令组织,不会减少drawcall数,性能中等。优点:没有额外内存开销,无需renderTarget支持。 + */ + get cacheAs():string; + set cacheAs(value:string); + + /** + * 更新_cnavas相关的状态 + */ + private _checkCanvasEnable:any; + + /** + * 设置cacheAs为非空时此值才有效,staticCache=true时,子对象变化时不会自动更新缓存,只能通过调用reCache方法手动刷新。 + */ + get staticCache():boolean; + set staticCache(value:boolean); + + /** + * 在设置cacheAs的情况下,调用此方法会重新刷新缓存。 + */ + reCache():void; + getRepaint():number; + + /** + * 表示显示对象相对于父容器的水平方向坐标值。 + */ + get x():number; + set x(value:number); + + /** + * 表示显示对象相对于父容器的垂直方向坐标值。 + */ + get y():number; + set y(value:number); + + /** + *

显示对象的宽度,单位为像素,默认为0。

+ *

此宽度用于鼠标碰撞检测,并不影响显示对象图像大小。需要对显示对象的图像进行缩放,请使用scale、scaleX、scaleY。

+ *

可以通过getbounds获取显示对象图像的实际宽度。

+ */ + get width():number; + set width(value:number); + set_width(value:number):void; + get_width():number; + + /** + *

显示对象的高度,单位为像素,默认为0。

+ *

此高度用于鼠标碰撞检测,并不影响显示对象图像大小。需要对显示对象的图像进行缩放,请使用scale、scaleX、scaleY。

+ *

可以通过getbounds获取显示对象图像的实际高度。

+ */ + get height():number; + set height(value:number); + set_height(value:number):void; + get_height():number; + + /** + *

对象的显示宽度(以像素为单位)。

+ */ + get displayWidth():number; + + /** + *

对象的显示高度(以像素为单位)。

+ */ + get displayHeight():number; + + /** + * 设置对象bounds大小,如果有设置,则不再通过getBounds计算,合理使用能提高性能。 + * @param bound bounds矩形区域 + */ + setSelfBounds(bound:Rectangle):void; + + /** + *

获取本对象在父容器坐标系的矩形显示区域。

+ *

注意:计算量较大,尽量少用。

+ * @return 矩形区域。 + */ + getBounds():Rectangle; + + /** + * 获取本对象在自己坐标系的矩形显示区域。 + *

注意:计算量较大,尽量少用。

+ * @return 矩形区域。 + */ + getSelfBounds():Rectangle; + + /** + * 返回此实例中的绘图对象( Graphics )的显示区域,不包括子对象。 + * @param realSize (可选)使用图片的真实大小,默认为false + * @return 一个 Rectangle 对象,表示获取到的显示区域。 + */ + getGraphicBounds(realSize?:boolean):Rectangle; + + /** + * @private 获取样式。 + * @return 样式 Style 。 + */ + getStyle():SpriteStyle; + + /** + * @private 设置样式。 + * @param value 样式。 + */ + setStyle(value:SpriteStyle):void; + + /** + * X轴缩放值,默认值为1。设置为负数,可以实现水平反转效果,比如scaleX=-1。 + */ + get scaleX():number; + set scaleX(value:number); + + /** + * Y轴缩放值,默认值为1。设置为负数,可以实现垂直反转效果,比如scaleX=-1。 + */ + get scaleY():number; + set scaleY(value:number); + set_scaleX(value:number):void; + get_scaleX():number; + set_scaleY(value:number):void; + get_scaleY():number; + + /** + * 旋转角度,默认值为0。以角度为单位。 + */ + get rotation():number; + set rotation(value:number); + + /** + * 水平倾斜角度,默认值为0。以角度为单位。 + */ + get skewX():number; + set skewX(value:number); + + /** + * 垂直倾斜角度,默认值为0。以角度为单位。 + */ + get skewY():number; + set skewY(value:number); + + /** + * @private + */ + protected _adjustTransform():Matrix; + + /** + *

对象的矩阵信息。通过设置矩阵可以实现节点旋转,缩放,位移效果。

+ *

矩阵更多信息请参考 Matrix

+ */ + get transform():Matrix; + set transform(value:Matrix); + get_transform():Matrix; + set_transform(value:Matrix):void; + + /** + * X轴 轴心点的位置,单位为像素,默认为0。轴心点会影响对象位置,缩放中心,旋转中心。 + */ + get pivotX():number; + set pivotX(value:number); + + /** + * Y轴 轴心点的位置,单位为像素,默认为0。轴心点会影响对象位置,缩放中心,旋转中心。 + */ + get pivotY():number; + set pivotY(value:number); + + /** + * 透明度,值为0-1,默认值为1,表示不透明。更改alpha值会影响drawcall。 + */ + get alpha():number; + set alpha(value:number); + + /** + * 表示是否可见,默认为true。如果设置不可见,节点将不被渲染。 + */ + get visible():boolean; + set visible(value:boolean); + get_visible():boolean; + set_visible(value:boolean):void; + + /** + * 指定要使用的混合模式。目前只支持"lighter"。 + */ + get blendMode():string; + set blendMode(value:string); + + /** + * 绘图对象。封装了绘制位图和矢量图的接口,Sprite所有的绘图操作都通过Graphics来实现的。 + */ + get graphics():Graphics; + set graphics(value:Graphics); + + /** + *

显示对象的滚动矩形范围,具有裁剪效果(如果只想限制子对象渲染区域,请使用viewport)

+ *

srollRect和viewport的区别:
+ * 1.srollRect自带裁剪效果,viewport只影响子对象渲染是否渲染,不具有裁剪效果(性能更高)。
+ * 2.设置rect的x,y属性均能实现区域滚动效果,但scrollRect会保持0,0点位置不变。

+ */ + get scrollRect():Rectangle; + set scrollRect(value:Rectangle); + + /** + *

设置坐标位置。相当于分别设置x和y属性。

+ *

因为返回值为Sprite对象本身,所以可以使用如下语法:spr.pos(...).scale(...);

+ * @param x X轴坐标。 + * @param y Y轴坐标。 + * @param speedMode (可选)是否极速模式,正常是调用this.x=value进行赋值,极速模式直接调用内部函数处理,如果未重写x,y属性,建议设置为急速模式性能更高。 + * @return 返回对象本身。 + */ + pos(x:number,y:number,speedMode?:boolean):Sprite; + + /** + *

设置轴心点。相当于分别设置pivotX和pivotY属性。

+ *

因为返回值为Sprite对象本身,所以可以使用如下语法:spr.pivot(...).pos(50, 100);

+ * @param x X轴心点。 + * @param y Y轴心点。 + * @return 返回对象本身。 + */ + pivot(x:number,y:number):Sprite; + + /** + *

设置宽高。相当于分别设置width和height属性。

+ *

因为返回值为Sprite对象本身,所以可以使用如下语法:spr.size(...).pos(50, 100);

+ * @param width 宽度值。 + * @param hegiht 高度值。 + * @return 返回对象本身。 + */ + size(width:number,height:number):Sprite; + + /** + *

设置缩放。相当于分别设置scaleX和scaleY属性。

+ *

因为返回值为Sprite对象本身,所以可以使用如下语法:spr.scale(...).pos(50, 100);

+ * @param scaleX X轴缩放比例。 + * @param scaleY Y轴缩放比例。 + * @param speedMode (可选)是否极速模式,正常是调用this.scaleX=value进行赋值,极速模式直接调用内部函数处理,如果未重写scaleX,scaleY属性,建议设置为急速模式性能更高。 + * @return 返回对象本身。 + */ + scale(scaleX:number,scaleY:number,speedMode?:boolean):Sprite; + + /** + *

设置倾斜角度。相当于分别设置skewX和skewY属性。

+ *

因为返回值为Sprite对象本身,所以可以使用如下语法:spr.skew(...).pos(50, 100);

+ * @param skewX 水平倾斜角度。 + * @param skewY 垂直倾斜角度。 + * @return 返回对象本身 + */ + skew(skewX:number,skewY:number):Sprite; + + /** + * 更新、呈现显示对象。由系统调用。 + * @param context 渲染的上下文引用。 + * @param x X轴坐标。 + * @param y Y轴坐标。 + */ + render(ctx:Context,x:number,y:number):void; + + /** + *

绘制 当前SpriteCanvas 上,并返回一个HtmlCanvas。

+ *

绘制的结果可以当作图片源,再次绘制到其他Sprite里面,示例:

+ * + * var htmlCanvas:HTMLCanvas = sprite.drawToCanvas(100, 100, 0, 0);//把精灵绘制到canvas上面 + * var sp:Sprite = new Sprite();//创建精灵 + * sp.graphics.drawTexture(htmlCanvas.getTexture());//把截图绘制到精灵上 + * Laya.stage.addChild(sp);//把精灵显示到舞台 + * + *

也可以获取原始图片数据,分享到网上,从而实现截图效果,示例:

+ * + * var htmlCanvas:HTMLCanvas = sprite.drawToCanvas(100, 100, 0, 0);//把精灵绘制到canvas上面 + * htmlCanvas.toBase64("image/png",0.9);//打印图片base64信息,可以发给服务器或者保存为图片 + * @param canvasWidth 画布宽度。 + * @param canvasHeight 画布高度。 + * @param x 绘制的 X 轴偏移量。 + * @param y 绘制的 Y 轴偏移量。 + * @return HTMLCanvas 对象。 + */ + drawToCanvas(canvasWidth:number,canvasHeight:number,offsetX:number,offsetY:number):HTMLCanvas; + + /** + * 绘制到一个Texture对象 + * @param canvasWidth + * @param canvasHeight + * @param offsetX + * @param offsetY + */ + drawToTexture(canvasWidth:number,canvasHeight:number,offsetX:number,offsetY:number,rt?:RenderTexture2D|null):Texture|RenderTexture2D; + + /** + * 把当前对象渲染到指定的贴图上。贴图由外部指定,避免每次都创建。 + * @param offx + * @param offy + * @param tex 输出渲染结果 + */ + drawToTexture3D(offx:number,offy:number,tex:Texture2D):void; + + /** + * @private 绘制到画布。 + */ + static drawToCanvas(sprite:Sprite,_renderType:number,canvasWidth:number,canvasHeight:number,offsetX:number,offsetY:number):HTMLCanvas; + static drawtocanvCtx:Context; + + /** + * @private + */ + static drawToTexture(sprite:Sprite,_renderType:number,canvasWidth:number,canvasHeight:number,offsetX:number,offsetY:number,rt?:RenderTexture2D|null):Texture|RenderTexture2D; + + /** + *

自定义更新、呈现显示对象。一般用来扩展渲染模式,请合理使用,可能会导致在加速器上无法渲染。

+ *

注意不要在此函数内增加或删除树节点,否则会对树节点遍历造成影响。

+ * @param context 渲染的上下文引用。 + * @param x X轴坐标。 + * @param y Y轴坐标。 + */ + customRender(context:Context,x:number,y:number):void; + + /** + * 滤镜集合。可以设置多个滤镜组合。 + */ + get filters():any[]; + set filters(value:any[]); + + /** + * 把本地坐标转换为相对stage的全局坐标。 + * @param point 本地坐标点。 + * @param createNewPoint (可选)是否创建一个新的Point对象作为返回值,默认为false,使用输入的point对象返回,减少对象创建开销。 + * @param globalNode global节点,默认为Laya.stage + * @return 转换后的坐标的点。 + */ + localToGlobal(point:Point,createNewPoint?:boolean,globalNode?:Sprite|null):Point; + + /** + * 把stage的全局坐标转换为本地坐标。 + * @param point 全局坐标点。 + * @param createNewPoint (可选)是否创建一个新的Point对象作为返回值,默认为false,使用输入的point对象返回,减少对象创建开销。 + * @param globalNode global节点,默认为Laya.stage + * @return 转换后的坐标的点。 + */ + globalToLocal(point:Point,createNewPoint?:boolean,globalNode?:Sprite|null):Point; + + /** + * 将本地坐标系坐标转转换到父容器坐标系。 + * @param point 本地坐标点。 + * @return 转换后的点。 + */ + toParentPoint(point:Point):Point; + + /** + * 将父容器坐标系坐标转换到本地坐标系。 + * @param point 父容器坐标点。 + * @return 转换后的点。 + */ + fromParentPoint(point:Point):Point; + + /** + * 将Stage坐标系坐标转换到本地坐标系。 + * @param point 父容器坐标点。 + * @return 转换后的点。 + */ + fromStagePoint(point:Point):Point; + + /** + *

增加事件侦听器,以使侦听器能够接收事件通知。

+ *

如果侦听鼠标事件,则会自动设置自己和父亲节点的属性 mouseEnabled 的值为 true(如果父节点mouseEnabled=false,则停止设置父节点mouseEnabled属性)。

+ * @param type 事件的类型。 + * @param caller 事件侦听函数的执行域。 + * @param listener 事件侦听函数。 + * @param args (可选)事件侦听函数的回调参数。 + * @return 此 EventDispatcher 对象。 + * @override + */ + on(type:string,caller:any,listener:Function,args?:any[]):EventDispatcher; + + /** + *

增加事件侦听器,以使侦听器能够接收事件通知,此侦听事件响应一次后则自动移除侦听。

+ *

如果侦听鼠标事件,则会自动设置自己和父亲节点的属性 mouseEnabled 的值为 true(如果父节点mouseEnabled=false,则停止设置父节点mouseEnabled属性)。

+ * @param type 事件的类型。 + * @param caller 事件侦听函数的执行域。 + * @param listener 事件侦听函数。 + * @param args (可选)事件侦听函数的回调参数。 + * @return 此 EventDispatcher 对象。 + * @override + */ + once(type:string,caller:any,listener:Function,args?:any[]):EventDispatcher; + + /** + * @private + */ + protected _onDisplay(v?:boolean):void; + + /** + * @private + * @override + */ + protected _setParent(value:Node):void; + + /** + *

加载并显示一个图片。相当于加载图片后,设置texture属性

+ *

注意:2.0改动:多次调用,只会显示一个图片(1.0会显示多个图片),x,y,width,height参数取消。

+ * @param url 图片地址。 + * @param complete (可选)加载完成回调。 + * @return 返回精灵对象本身。 + */ + loadImage(url:string,complete?:Handler):Sprite; + + /** + * 根据图片地址创建一个新的 Sprite 对象用于加载并显示此图片。 + * @param url 图片地址。 + * @return 返回新的 Sprite 对象。 + */ + static fromImage(url:string):Sprite; + + /** + * cacheAs后,设置自己和父对象缓存失效。 + */ + repaint(type?:number):void; + + /** + * @private + * @override + */ + protected _childChanged(child?:Node):void; + + /** + * cacheAs时,设置所有父对象缓存失效。 + */ + parentRepaint(type?:number):void; + + /** + * 对舞台 stage 的引用。 + */ + get stage():Stage; + + /** + *

可以设置一个Rectangle区域作为点击区域,或者设置一个HitArea实例作为点击区域,HitArea内可以设置可点击和不可点击区域。

+ *

如果不设置hitArea,则根据宽高形成的区域进行碰撞。

+ */ + get hitArea():any; + set hitArea(value:any); + + /** + *

遮罩,可以设置一个对象(支持位图和矢量图),根据对象形状进行遮罩显示。

+ *

【注意】遮罩对象坐标系是相对遮罩对象本身的,和Flash机制不同

+ */ + get mask():Sprite; + set mask(value:Sprite); + + /** + * 是否接受鼠标事件。 + * 默认为false,如果监听鼠标事件,则会自动设置本对象及父节点的属性 mouseEnable 的值都为 true(如果父节点手动设置为false,则不会更改)。 + */ + get mouseEnabled():boolean; + set mouseEnabled(value:boolean); + + /** + * 开始拖动此对象。 + * @param area (可选)拖动区域,此区域为当前对象注册点活动区域(不包括对象宽高),可选。 + * @param hasInertia (可选)鼠标松开后,是否还惯性滑动,默认为false,可选。 + * @param elasticDistance (可选)橡皮筋效果的距离值,0为无橡皮筋效果,默认为0,可选。 + * @param elasticBackTime (可选)橡皮筋回弹时间,单位为毫秒,默认为300毫秒,可选。 + * @param data (可选)拖动事件携带的数据,可选。 + * @param disableMouseEvent (可选)禁用其他对象的鼠标检测,默认为false,设置为true能提高性能。 + * @param ratio (可选)惯性阻尼系数,影响惯性力度和时长。 + */ + startDrag(area?:Rectangle,hasInertia?:boolean,elasticDistance?:number,elasticBackTime?:number,data?:any,disableMouseEvent?:boolean,ratio?:number):void; + + /** + * 停止拖动此对象。 + */ + stopDrag():void; + + /** + * 检测某个点是否在此对象内。 + * @param x 全局x坐标。 + * @param y 全局y坐标。 + * @return 表示是否在对象内。 + */ + hitTestPoint(x:number,y:number):boolean; + + /** + * 获得相对于本对象上的鼠标坐标信息。 + */ + getMousePoint():Point; + + /** + * 获得相对于stage的全局X轴缩放值(会叠加父亲节点的缩放值)。 + */ + get globalScaleX():number; + + /** + * 获得相对于stage的全局旋转值(会叠加父亲节点的旋转值)。 + */ + get globalRotation():number; + + /** + * 获得相对于stage的全局Y轴缩放值(会叠加父亲节点的缩放值)。 + */ + get globalScaleY():number; + + /** + * 返回鼠标在此对象坐标系上的 X 轴坐标信息。 + */ + get mouseX():number; + + /** + * 返回鼠标在此对象坐标系上的 Y 轴坐标信息。 + */ + get mouseY():number; + + /** + * z排序,更改此值,则会按照值的大小对同一容器的所有对象重新排序。值越大,越靠上。默认为0,则根据添加顺序排序。 + */ + get zOrder():number; + set zOrder(value:number); + + /** + * 设置一个Texture实例,并显示此图片(如果之前有其他绘制,则会被清除掉)。 + * 等同于graphics.clear();graphics.drawImage(),但性能更高 + * 还可以赋值一个图片地址,则会自动加载图片,然后显示 + */ + get texture():Texture; + set texture(value:Texture); + + /** + *

视口大小,视口外的子对象,将不被渲染(如果想实现裁剪效果,请使用srollRect),合理使用能提高渲染性能。比如由一个个小图片拼成的地图块,viewport外面的小图片将不渲染

+ *

srollRect和viewport的区别:
+ * 1. srollRect自带裁剪效果,viewport只影响子对象渲染是否渲染,不具有裁剪效果(性能更高)。
+ * 2. 设置rect的x,y属性均能实现区域滚动效果,但scrollRect会保持0,0点位置不变。

+ * @default null + */ + get viewport():Rectangle; + set viewport(value:Rectangle); + + /** + * @private + */ + captureMouseEvent(exclusive:boolean):void; + + /** + * @private + */ + releaseMouseEvent():void; + set drawCallOptimize(value:boolean); + get drawCallOptimize():boolean; + } + + /** + * @private + */ + class SpriteConst { + + /** + * @private + */ + static ALPHA:number; + + /** + * @private + */ + static TRANSFORM:number; + + /** + * @private + */ + static BLEND:number; + + /** + * @private + */ + static CANVAS:number; + + /** + * @private + */ + static FILTERS:number; + + /** + * @private + */ + static MASK:number; + + /** + * @private + */ + static CLIP:number; + + /** + * @private + */ + static STYLE:number; + + /** + * @private + */ + static TEXTURE:number; + + /** + * @private + */ + static GRAPHICS:number; + + /** + * @private + */ + static LAYAGL3D:number; + + /** + * @private + */ + static CUSTOM:number; + + /** + * @private + */ + static ONECHILD:number; + + /** + * @private + */ + static CHILDS:number; + + /** + * @private + */ + static REPAINT_NONE:number; + + /** + * @private + */ + static REPAINT_NODE:number; + + /** + * @private + */ + static REPAINT_CACHE:number; + + /** + * @private + */ + static REPAINT_ALL:number; + } + + /** + * stage大小经过重新调整时进行调度。 + * @eventType Event.RESIZE + */ + + /** + * 舞台获得焦点时调度。比如浏览器或者当前标签处于后台,重新切换回来时进行调度。 + * @eventType Event.FOCUS + */ + + /** + * 舞台失去焦点时调度。比如浏览器或者当前标签被切换到后台后调度。 + * @eventType Event.BLUR + */ + + /** + * 舞台焦点变化时调度,使用Laya.stage.isFocused可以获取当前舞台是否获得焦点。 + * @eventType Event.FOCUS_CHANGE + */ + + /** + * 舞台可见性发生变化时调度(比如浏览器或者当前标签被切换到后台后调度),使用Laya.stage.isVisibility可以获取当前是否处于显示状态。 + * @eventType Event.VISIBILITY_CHANGE + */ + + /** + * 浏览器全屏更改时调度,比如进入全屏或者退出全屏。 + * @eventType Event.FULL_SCREEN_CHANGE + */ + + /** + *

Stage 是舞台类,显示列表的根节点,所有显示对象都在舞台上显示。通过 Laya.stage 单例访问。

+ *

Stage提供几种适配模式,不同的适配模式会产生不同的画布大小,画布越大,渲染压力越大,所以要选择合适的适配方案。

+ *

Stage提供不同的帧率模式,帧率越高,渲染压力越大,越费电,合理使用帧率甚至动态更改帧率有利于改进手机耗电。

+ */ + class Stage extends Sprite { + + /** + * 应用保持设计宽高不变,不缩放不变形,stage的宽高等于设计宽高。 + */ + static SCALE_NOSCALE:string; + + /** + * 应用根据屏幕大小铺满全屏,非等比缩放会变形,stage的宽高等于设计宽高。 + */ + static SCALE_EXACTFIT:string; + + /** + * 应用显示全部内容,按照最小比率缩放,等比缩放不变形,一边可能会留空白,stage的宽高等于设计宽高。 + */ + static SCALE_SHOWALL:string; + + /** + * 应用按照最大比率缩放显示,宽或高方向会显示一部分,等比缩放不变形,stage的宽高等于设计宽高。 + */ + static SCALE_NOBORDER:string; + + /** + * 应用保持设计宽高不变,不缩放不变形,stage的宽高等于屏幕宽高。 + */ + static SCALE_FULL:string; + + /** + * 应用保持设计宽度不变,高度根据屏幕比缩放,stage的宽度等于设计高度,高度根据屏幕比率大小而变化 + */ + static SCALE_FIXED_WIDTH:string; + + /** + * 应用保持设计高度不变,宽度根据屏幕比缩放,stage的高度等于设计宽度,宽度根据屏幕比率大小而变化 + */ + static SCALE_FIXED_HEIGHT:string; + + /** + * 应用保持设计比例不变,全屏显示全部内容(类似showall,但showall非全屏,会有黑边),根据屏幕长宽比,自动选择使用SCALE_FIXED_WIDTH或SCALE_FIXED_HEIGHT + */ + static SCALE_FIXED_AUTO:string; + + /** + * 画布水平居左对齐。 + */ + static ALIGN_LEFT:string; + + /** + * 画布水平居右对齐。 + */ + static ALIGN_RIGHT:string; + + /** + * 画布水平居中对齐。 + */ + static ALIGN_CENTER:string; + + /** + * 画布垂直居上对齐。 + */ + static ALIGN_TOP:string; + + /** + * 画布垂直居中对齐。 + */ + static ALIGN_MIDDLE:string; + + /** + * 画布垂直居下对齐。 + */ + static ALIGN_BOTTOM:string; + + /** + * 不更改屏幕。 + */ + static SCREEN_NONE:string; + + /** + * 自动横屏。 + */ + static SCREEN_HORIZONTAL:string; + + /** + * 自动竖屏。 + */ + static SCREEN_VERTICAL:string; + + /** + * 全速模式,以60的帧率运行。 + */ + static FRAME_FAST:string; + + /** + * 慢速模式,以30的帧率运行。 + */ + static FRAME_SLOW:string; + + /** + * 自动模式,以30的帧率运行,但鼠标活动后会自动加速到60,鼠标不动2秒后降低为30帧,以节省消耗。 + */ + static FRAME_MOUSE:string; + + /** + * 休眠模式,以1的帧率运行 + */ + static FRAME_SLEEP:string; + + /** + * 当前焦点对象,此对象会影响当前键盘事件的派发主体。 + */ + focus:Node; + + /** + * @private 相对浏览器左上角的偏移,弃用,请使用_canvasTransform。 + */ + offset:Point; + + /** + * 帧率类型,支持三种模式:fast-60帧(默认),slow-30帧,mouse-30帧(鼠标活动后会自动加速到60,鼠标不动2秒后降低为30帧,以节省消耗),sleep-1帧。 + */ + private _frameRate:any; + + /** + * 设计宽度(初始化时设置的宽度Laya.init(width,height)) + */ + designWidth:number; + + /** + * 设计高度(初始化时设置的高度Laya.init(width,height)) + */ + designHeight:number; + + /** + * 画布是否发生翻转。 + */ + canvasRotation:boolean; + + /** + * 画布的旋转角度。 + */ + canvasDegree:number; + + /** + *

设置是否渲染,设置为false,可以停止渲染,画面会停留到最后一次渲染上,减少cpu消耗,此设置不影响时钟。

+ *

比如非激活状态,可以设置renderingEnabled=false以节省消耗。

+ */ + renderingEnabled:boolean; + + /** + * 是否启用屏幕适配,可以适配后,在某个时候关闭屏幕适配,防止某些操作导致的屏幕意外改变 + */ + screenAdaptationEnabled:boolean; + + /** + * @private + */ + private _screenMode:any; + + /** + * @private + */ + private _scaleMode:any; + + /** + * @private + */ + private _alignV:any; + + /** + * @private + */ + private _alignH:any; + + /** + * @private + */ + private _bgColor:any; + + /** + * @private + */ + private _mouseMoveTime:any; + + /** + * @private + */ + private _renderCount:any; + + /** + * @private + */ + private _safariOffsetY:any; + + /** + * @private + */ + private _frameStartTime:any; + + /** + * @private + */ + private _previousOrientation:any; + + /** + * @private + */ + private _isFocused:any; + + /** + * @private + */ + private _isVisibility:any; + + /** + * @private + */ + private _globalRepaintSet:any; + + /** + * @private + */ + private _globalRepaintGet:any; + + /** + * 使用物理分辨率作为canvas大小,会改进渲染效果,但是会降低性能 + */ + useRetinalCanvas:boolean; + + /** + * 场景类,引擎中只有一个stage实例,此实例可以通过Laya.stage访问。 + */ + + constructor(); + + /** + * @private 在移动端输入时,输入法弹出期间不进行画布尺寸重置。 + */ + private _isInputting:any; + + /** + * @inheritDoc + * @override + */ + set width(value:number); + + /** + * @inheritDoc + * @override + */ + get width():number; + + /** + * @inheritDoc + * @override + */ + set height(value:number); + + /** + * @override + */ + get height():number; + + /** + * @override + */ + set transform(value:Matrix); + + /** + * @inheritDoc + * @override + */ + get transform():Matrix; + + /** + * 舞台是否获得焦点。 + */ + get isFocused():boolean; + + /** + * 舞台是否处于可见状态(是否进入后台)。 + */ + get isVisibility():boolean; + + /** + * @private + */ + private _changeCanvasSize:any; + + /** + * @private + */ + protected _resetCanvas():void; + + /** + * 设置屏幕大小,场景会根据屏幕大小进行适配。可以动态调用此方法,来更改游戏显示的大小。 + * @param screenWidth 屏幕宽度。 + * @param screenHeight 屏幕高度。 + */ + setScreenSize(screenWidth:number,screenHeight:number):void; + + /** + * @private + */ + private _formatData:any; + + /** + *

缩放模式。默认值为 "noscale"。

+ *

    取值范围: + *
  • "noscale" :不缩放;
  • + *
  • "exactfit" :全屏不等比缩放;
  • + *
  • "showall" :最小比例缩放;
  • + *
  • "noborder" :最大比例缩放;
  • + *
  • "full" :不缩放,stage的宽高等于屏幕宽高;
  • + *
  • "fixedwidth" :宽度不变,高度根据屏幕比缩放;
  • + *
  • "fixedheight" :高度不变,宽度根据屏幕比缩放;
  • + *
  • "fixedauto" :根据宽高比,自动选择使用fixedwidth或fixedheight;
  • + *

+ */ + get scaleMode():string; + set scaleMode(value:string); + + /** + *

水平对齐方式。默认值为"left"。

+ *

    取值范围: + *
  • "left" :居左对齐;
  • + *
  • "center" :居中对齐;
  • + *
  • "right" :居右对齐;
  • + *

+ */ + get alignH():string; + set alignH(value:string); + + /** + *

垂直对齐方式。默认值为"top"。

+ *

    取值范围: + *
  • "top" :居顶部对齐;
  • + *
  • "middle" :居中对齐;
  • + *
  • "bottom" :居底部对齐;
  • + *

+ */ + get alignV():string; + set alignV(value:string); + + /** + * 舞台的背景颜色,默认为黑色,null为透明。 + */ + get bgColor():string; + set bgColor(value:string); + + /** + * 鼠标在 Stage 上的 X 轴坐标。@override + */ + get mouseX():number; + + /** + * 鼠标在 Stage 上的 Y 轴坐标。@override + */ + get mouseY():number; + + /** + * @inheritDoc + * @override + */ + getMousePoint():Point; + + /** + * 当前视窗由缩放模式导致的 X 轴缩放系数。 + */ + get clientScaleX():number; + + /** + * 当前视窗由缩放模式导致的 Y 轴缩放系数。 + */ + get clientScaleY():number; + + /** + *

场景布局类型。

+ *

    取值范围: + *
  • "none" :不更改屏幕
  • + *
  • "horizontal" :自动横屏
  • + *
  • "vertical" :自动竖屏
  • + *

+ */ + get screenMode():string; + set screenMode(value:string); + + /** + * @inheritDoc + * @override + */ + repaint(type?:number):void; + + /** + * @inheritDoc + * @override + */ + parentRepaint(type?:number):void; + + /** + * @private + */ + getFrameTm():number; + + /** + * @private + */ + private _onmouseMove:any; + + /** + *

获得距当前帧开始后,过了多少时间,单位为毫秒。

+ *

可以用来判断函数内时间消耗,通过合理控制每帧函数处理消耗时长,避免一帧做事情太多,对复杂计算分帧处理,能有效降低帧率波动。

+ */ + getTimeFromFrameStart():number; + + /** + * @inheritDoc + * @override + */ + set visible(value:boolean); + + /** + * @inheritDoc + * @override + */ + get visible():boolean; + + /** + * @private + */ + static clear:Function; + + /** + * @inheritDoc + * @override + */ + render(context:Context,x:number,y:number):void; + renderToNative(context:Context,x:number,y:number):void; + private _updateTimers:any; + + /** + *

是否开启全屏,用户点击后进入全屏。

+ *

兼容性提示:部分浏览器不允许点击进入全屏,比如Iphone等。

+ */ + set fullScreenEnabled(value:boolean); + get frameRate():string; + set frameRate(value:string); + + /** + * @private + */ + private _requestFullscreen:any; + + /** + * @private + */ + private _fullScreenChanged:any; + + /** + * 退出全屏模式 + */ + exitFullscreen():void; + + /** + * @private + */ + isGlobalRepaint():boolean; + + /** + * @private + */ + setGlobalRepaint():void; + + /** + * @private + */ + add3DUI(uibase:Sprite):void; + + /** + * @private + */ + remove3DUI(uibase:Sprite):boolean; + } + + /** + * 文本内容发生改变后调度。 + * @eventType Event.CHANGE + */ + + /** + *

Text 类用于创建显示对象以显示文本。

+ *

+ * 注意:如果运行时系统找不到设定的字体,则用系统默认的字体渲染文字,从而导致显示异常。(通常电脑上显示正常,在一些移动端因缺少设置的字体而显示异常)。 + *

+ * @example package { import laya.display.Text; public class Text_Example { public function Text_Example() { Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 onInit(); } private function onInit():void { var text:Text = new Text();//创建一个 Text 类的实例对象 text 。 text.text = "这个是一个 Text 文本示例。"; text.color = "#008fff";//设置 text 的文本颜色。 text.font = "Arial";//设置 text 的文本字体。 text.bold = true;//设置 text 的文本显示为粗体。 text.fontSize = 30;//设置 text 的字体大小。 text.wordWrap = true;//设置 text 的文本自动换行。 text.x = 100;//设置 text 对象的属性 x 的值,用于控制 text 对象的显示位置。 text.y = 100;//设置 text 对象的属性 y 的值,用于控制 text 对象的显示位置。 text.width = 300;//设置 text 的宽度。 text.height = 200;//设置 text 的高度。 text.italic = true;//设置 text 的文本显示为斜体。 text.borderColor = "#fff000";//设置 text 的文本边框颜色。 Laya.stage.addChild(text);//将 text 添加到显示列表。 } } } + * @example Text_Example(); function Text_Example() { Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 onInit(); } function onInit() { var text = new laya.display.Text();//创建一个 Text 类的实例对象 text 。 text.text = "这个是一个 Text 文本示例。"; text.color = "#008fff";//设置 text 的文本颜色。 text.font = "Arial";//设置 text 的文本字体。 text.bold = true;//设置 text 的文本显示为粗体。 text.fontSize = 30;//设置 text 的字体大小。 text.wordWrap = true;//设置 text 的文本自动换行。 text.x = 100;//设置 text 对象的属性 x 的值,用于控制 text 对象的显示位置。 text.y = 100;//设置 text 对象的属性 y 的值,用于控制 text 对象的显示位置。 text.width = 300;//设置 text 的宽度。 text.height = 200;//设置 text 的高度。 text.italic = true;//设置 text 的文本显示为斜体。 text.borderColor = "#fff000";//设置 text 的文本边框颜色。 Laya.stage.addChild(text);//将 text 添加到显示列表。 } + * @example class Text_Example { constructor() { Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 this.onInit(); } private onInit(): void { var text: laya.display.Text = new laya.display.Text();//创建一个 Text 类的实例对象 text 。 text.text = "这个是一个 Text 文本示例。"; text.color = "#008fff";//设置 text 的文本颜色。 text.font = "Arial";//设置 text 的文本字体。 text.bold = true;//设置 text 的文本显示为粗体。 text.fontSize = 30;//设置 text 的字体大小。 text.wordWrap = true;//设置 text 的文本自动换行。 text.x = 100;//设置 text 对象的属性 x 的值,用于控制 text 对象的显示位置。 text.y = 100;//设置 text 对象的属性 y 的值,用于控制 text 对象的显示位置。 text.width = 300;//设置 text 的宽度。 text.height = 200;//设置 text 的高度。 text.italic = true;//设置 text 的文本显示为斜体。 text.borderColor = "#fff000";//设置 text 的文本边框颜色。 Laya.stage.addChild(text);//将 text 添加到显示列表。 } } + */ + class Text extends Sprite { + + /** + * visible不进行任何裁切。 + */ + static VISIBLE:string; + + /** + * scroll 不显示文本域外的字符像素,并且支持 scroll 接口。 + */ + static SCROLL:string; + + /** + * hidden 不显示超出文本域的字符。 + */ + static HIDDEN:string; + + /** + * 默认文本大小,默认为12 + */ + static defaultFontSize:number; + + /** + * 默认文本字体,默认为Arial + */ + static defaultFont:string; + + /** + * @private + */ + static defaultFontStr():string; + + /** + * 语言包,是一个包含key:value的集合,用key索引,替换为目标value语言 + */ + static langPacks:any; + + /** + * WebGL下,文字会被拆分为单个字符进行渲染,一些语系不能拆开显示,比如阿拉伯文,这时可以设置isComplexText=true,禁用文字拆分。 + */ + static isComplexText:boolean; + + /** + * 在IOS下,一些字体会找不到,引擎提供了字体映射功能,比如默认会把 "黑体" 映射为 "黑体-简",更多映射,可以自己添加 + */ + static fontFamilyMap:any; + + /** + * @private 位图字体字典。 + */ + private static _bitmapFonts:any; + static CharacterCache:boolean; + + /** + * 是否是从右向左的显示顺序 + */ + static RightToLeft:boolean; + + /** + * @private + */ + private _clipPoint:any; + + /** + * @private 表示文本内容字符串。 + */ + protected _text:string; + + /** + * @private 表示文本内容是否发生改变。 + */ + protected _isChanged:boolean; + + /** + * @private 表示文本的宽度,以像素为单位。 + */ + protected _textWidth:number; + + /** + * @private 表示文本的高度,以像素为单位。 + */ + protected _textHeight:number; + + /** + * @private 存储文字行数信息。 + */ + protected _lines:string[]|null; + + /** + * @private 保存每行宽度 + */ + protected _lineWidths:number[]|null; + + /** + * @private 文本的内容位置 X 轴信息。 + */ + protected _startX:number; + + /** + * @private 文本的内容位置X轴信息。 + */ + protected _startY:number; + + /** + * @private + */ + protected _words:WordText[]|null; + + /** + * @private + */ + protected _charSize:any; + + /** + * @private + */ + protected _valign:string; + + /** + * @private + */ + private _singleCharRender:any; + + /** + *

overflow 指定文本超出文本域后的行为。其值为"hidden"、"visible"和"scroll"之一。

+ *

性能从高到低依次为:hidden > visible > scroll。

+ */ + overflow:string; + + /** + * 创建一个新的 Text 实例。 + */ + + constructor(); + + /** + * @private 获取样式。 + * @return 样式 Style 。 + * @override + */ + getStyle():SpriteStyle; + protected _getTextStyle():TextStyle; + + /** + * 注册位图字体。 + * @param name 位图字体的名称。 + * @param bitmapFont 位图字体文件。 + */ + static registerBitmapFont(name:string,bitmapFont:BitmapFont):void; + + /** + * 移除注册的位图字体文件。 + * @param name 位图字体的名称。 + * @param destroy 是否销毁指定的字体文件。 + */ + static unregisterBitmapFont(name:string,destroy?:boolean):void; + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * @inheritDoc + * @override + */ + getGraphicBounds(realSize?:boolean):Rectangle; + + /** + * @inheritDoc + * @override + */ + get width():number; + + /** + * @override + */ + set width(value:number); + + /** + * @inheritDoc + * @override + */ + get height():number; + + /** + * @override + */ + set height(value:number); + + /** + * 表示文本的宽度,以像素为单位。 + */ + get textWidth():number; + + /** + * 表示文本的高度,以像素为单位。 + */ + get textHeight():number; + + /** + * 当前文本的内容字符串。 + */ + get text():string; + get_text():string; + set_text(value:string):void; + set text(value:string); + + /** + *

根据指定的文本,从语言包中取当前语言的文本内容。并对此文本中的{i}文本进行替换。

+ *

设置Text.langPacks语言包后,即可使用lang获取里面的语言

+ *

例如: + *

  • (1)text 的值为“我的名字”,先取到这个文本对应的当前语言版本里的值“My name”,将“My name”设置为当前文本的内容。
  • + *
  • (2)text 的值为“恭喜你赢得{0}个钻石,{1}经验。”,arg1 的值为100,arg2 的值为200。 + * 则先取到这个文本对应的当前语言版本里的值“Congratulations on your winning {0} diamonds, {1} experience.”, + * 然后将文本里的{0}、{1},依据括号里的数字从0开始替换为 arg1、arg2 的值。 + * 将替换处理后的文本“Congratulations on your winning 100 diamonds, 200 experience.”设置为当前文本的内容。 + *
  • + *

    + * @param text 文本内容。 + * @param ...args 文本替换参数。 + */ + lang(text:string,arg1?:any,arg2?:any,arg3?:any,arg4?:any,arg5?:any,arg6?:any,arg7?:any,arg8?:any,arg9?:any,arg10?:any):void; + + /** + *

    文本的字体名称,以字符串形式表示。

    + *

    默认值为:"Arial",可以通过Text.defaultFont设置默认字体。

    + *

    如果运行时系统找不到设定的字体,则用系统默认的字体渲染文字,从而导致显示异常。(通常电脑上显示正常,在一些移动端因缺少设置的字体而显示异常)。

    + * @see laya.display.Text#defaultFont + */ + get font():string; + set font(value:string); + + /** + *

    指定文本的字体大小(以像素为单位)。

    + *

    默认为20像素,可以通过 Text.defaultFontSize 设置默认大小。

    + */ + get fontSize():number; + set fontSize(value:number); + + /** + *

    指定文本是否为粗体字。

    + *

    默认值为 false,这意味着不使用粗体字。如果值为 true,则文本为粗体字。

    + */ + get bold():boolean; + set bold(value:boolean); + + /** + *

    表示文本的颜色值。可以通过 Text.defaultColor 设置默认颜色。

    + *

    默认值为黑色。

    + */ + get color():string; + set color(value:string); + get_color():string; + set_color(value:string):void; + + /** + *

    表示使用此文本格式的文本是否为斜体。

    + *

    默认值为 false,这意味着不使用斜体。如果值为 true,则文本为斜体。

    + */ + get italic():boolean; + set italic(value:boolean); + + /** + *

    表示文本的水平显示方式。

    + *

    取值: + *

  • "left": 居左对齐显示。
  • + *
  • "center": 居中对齐显示。
  • + *
  • "right": 居右对齐显示。
  • + *

    + */ + get align():string; + set align(value:string); + + /** + *

    表示文本的垂直显示方式。

    + *

    取值: + *

  • "top": 居顶部对齐显示。
  • + *
  • "middle": 居中对齐显示。
  • + *
  • "bottom": 居底部对齐显示。
  • + *

    + */ + get valign():string; + set valign(value:string); + + /** + *

    表示文本是否自动换行,默认为false。

    + *

    若值为true,则自动换行;否则不自动换行。

    + */ + get wordWrap():boolean; + set wordWrap(value:boolean); + + /** + * 垂直行间距(以像素为单位)。 + */ + get leading():number; + set leading(value:number); + + /** + *

    边距信息。

    + *

    数据格式:[上边距,右边距,下边距,左边距](边距以像素为单位)。

    + */ + get padding():any[]; + set padding(value:any[]); + + /** + * 文本背景颜色,以字符串表示。 + */ + get bgColor():string; + set bgColor(value:string); + set_bgColor(value:string):void; + get_bgColor():string; + + /** + * 文本边框背景颜色,以字符串表示。 + */ + get borderColor():string; + set borderColor(value:string); + + /** + *

    描边宽度(以像素为单位)。

    + *

    默认值0,表示不描边。

    + */ + get stroke():number; + set stroke(value:number); + + /** + *

    描边颜色,以字符串表示。

    + *

    默认值为 "#000000"(黑色);

    + */ + get strokeColor():string; + set strokeColor(value:string); + + /** + * @private 一个布尔值,表示文本的属性是否有改变。若为true表示有改变。 + */ + protected set isChanged(value:boolean); + + /** + * @private + */ + protected _getContextFont():string; + + /** + * @private + */ + protected _isPassWordMode():boolean; + + /** + * @private + */ + protected _getPassWordTxt(txt:string):string; + + /** + * @private 渲染文字。 + * @param begin 开始渲染的行索引。 + * @param visibleLineCount 渲染的行数。 + */ + protected _renderText():void; + + /** + * @private 绘制下划线 + * @param x 本行坐标 + * @param y 本行坐标 + * @param lineIndex 本行索引 + */ + private _drawUnderline:any; + + /** + *

    排版文本。

    + *

    进行宽高计算,渲染、重绘文本。

    + */ + typeset():void; + + /** + * @private + */ + private _evalTextSize:any; + + /** + * @private + */ + private _checkEnabledViewportOrNot:any; + + /** + *

    快速更改显示文本。不进行排版计算,效率较高。

    + *

    如果只更改文字内容,不更改文字样式,建议使用此接口,能提高效率。

    + * @param text 文本内容。 + */ + changeText(text:string):void; + + /** + * @private 分析文本换行。 + */ + protected _parseLines(text:string):void; + + /** + * @private 解析行文本。 + * @param line 某行的文本。 + * @param wordWrapWidth 文本的显示宽度。 + */ + protected _parseLine(line:string,wordWrapWidth:number):void; + + /** + * @private + */ + private _getTextWidth:any; + + /** + * @private 获取换行所需的宽度。 + */ + private _getWordWrapWidth:any; + + /** + * 返回字符在本类实例的父坐标系下的坐标。 + * @param charIndex 索引位置。 + * @param out (可选)输出的Point引用。 + * @return Point 字符在本类实例的父坐标系下的坐标。如果out参数不为空,则将结果赋值给指定的Point对象,否则创建一个新的Point对象返回。建议使用Point.TEMP作为out参数,可以省去Point对象创建和垃圾回收的开销,尤其是在需要频繁执行的逻辑中,比如帧循环和MOUSE_MOVE事件回调函数里面。 + */ + getCharPoint(charIndex:number,out?:Point):Point; + + /** + *

    设置横向滚动量。

    + *

    即使设置超出滚动范围的值,也会被自动限制在可能的最大值处。

    + */ + set scrollX(value:number); + + /** + * 获取横向滚动量。 + */ + get scrollX():number; + + /** + * 设置纵向滚动量(px)。即使设置超出滚动范围的值,也会被自动限制在可能的最大值处。 + */ + set scrollY(value:number); + + /** + * 获取纵向滚动量。 + */ + get scrollY():number; + + /** + * 获取横向可滚动最大值。 + */ + get maxScrollX():number; + + /** + * 获取纵向可滚动最大值。 + */ + get maxScrollY():number; + + /** + * 返回文字行信息 + */ + get lines():any[]; + + /** + * 下划线的颜色,为null则使用字体颜色。 + */ + get underlineColor():string; + set underlineColor(value:string); + + /** + * 是否显示下划线。 + */ + get underline():boolean; + set underline(value:boolean); + + /** + * 设置是否单个字符渲染,如果Textd的内容一直改变,例如是一个增加的数字,就设置这个,防止无效占用缓存 + */ + set singleCharRender(value:boolean); + get singleCharRender():boolean; + } + + /** + * ... + * @author ww + */ + class BlurFilterSetter extends FilterSetterBase { + private _strength:any; + + constructor(); + + /** + * @override + */ + protected buildFilter():void; + get strength():number; + set strength(value:number); + } + + /** + * @Script {name:ButtonEffect} + * @author ww + */ + class ButtonEffect { + private _tar:any; + private _curState:any; + private _curTween:any; + + /** + * effectScale + * @prop {name:effectScale,type:number, tips:"缩放值",default:"1.5"} + */ + effectScale:number; + + /** + * tweenTime + * @prop {name:tweenTime,type:number, tips:"缓动时长",default:"300"} + */ + tweenTime:number; + + /** + * effectEase + * @prop {name:effectEase,type:ease, tips:"效果缓动类型"} + */ + effectEase:string; + + /** + * backEase + * @prop {name:backEase,type:ease, tips:"恢复缓动类型"} + */ + backEase:string; + + /** + * 设置控制对象 + * @param tar + */ + set target(tar:Sprite); + private toChangedState:any; + private toInitState:any; + private tweenComplete:any; + } + + /** + * ... + * @author ww + */ + class ColorFilterSetter extends FilterSetterBase { + + /** + * brightness 亮度,范围:-100~100 + */ + private _brightness:any; + + /** + * contrast 对比度,范围:-100~100 + */ + private _contrast:any; + + /** + * saturation 饱和度,范围:-100~100 + */ + private _saturation:any; + + /** + * hue 色调,范围:-180~180 + */ + private _hue:any; + + /** + * red red增量,范围:0~255 + */ + private _red:any; + + /** + * green green增量,范围:0~255 + */ + private _green:any; + + /** + * blue blue增量,范围:0~255 + */ + private _blue:any; + + /** + * alpha alpha增量,范围:0~255 + */ + private _alpha:any; + + constructor(); + + /** + * @override + */ + protected buildFilter():void; + get brightness():number; + set brightness(value:number); + get contrast():number; + set contrast(value:number); + get saturation():number; + set saturation(value:number); + get hue():number; + set hue(value:number); + get red():number; + set red(value:number); + get green():number; + set green(value:number); + get blue():number; + set blue(value:number); + private _color:any; + get color():string; + set color(value:string); + get alpha():number; + set alpha(value:number); + } + + /** + * 效果插件基类,基于对象池管理 + */ + class EffectBase extends Component { + + /** + * 动画持续时间,单位为毫秒 + */ + duration:number; + + /** + * 动画延迟时间,单位为毫秒 + */ + delay:number; + + /** + * 重复次数,默认为播放一次 + */ + repeat:number; + + /** + * 缓动类型,如果为空,则默认为匀速播放 + */ + ease:string; + + /** + * 触发事件,如果为空,则创建时触发 + */ + eventName:string; + + /** + * 效用作用的目标对象,如果为空,则是脚本所在的节点本身 + */ + target:Sprite; + + /** + * 效果结束后,是否自动移除节点 + */ + autoDestroyAtComplete:boolean; + protected _comlete:Handler; + protected _tween:Tween; + protected _exeTween():void; + protected _doTween():Tween; + + /** + * @override + */ + onReset():void; + } + + /** + * 淡入效果 + */ + class FadeIn extends EffectBase { + + /** + * @override + */ + protected _doTween():Tween; + } + + /** + * 淡出效果 + */ + class FadeOut extends EffectBase { + + /** + * @override + */ + protected _doTween():Tween; + } + + /** + * ... + * @author ww + */ + class FilterSetterBase { + _filter:any; + + constructor(); + paramChanged():void; + protected buildFilter():void; + protected addFilter(sprite:Sprite):void; + protected removeFilter(sprite:Sprite):void; + private _target:any; + set target(value:any); + } + + /** + * ... + * @author ww + */ + class GlowFilterSetter extends FilterSetterBase { + + /** + * 滤镜的颜色 + */ + private _color:any; + + /** + * 边缘模糊的大小 0~20 + */ + private _blur:any; + + /** + * X轴方向的偏移 + */ + private _offX:any; + + /** + * Y轴方向的偏移 + */ + private _offY:any; + + constructor(); + + /** + * @override + */ + protected buildFilter():void; + get color():string; + set color(value:string); + get blur():number; + set blur(value:number); + get offX():number; + set offX(value:number); + get offY():number; + set offY(value:number); + } + + /** + * Event 是事件类型的集合。一般当发生事件时,Event 对象将作为参数传递给事件侦听器。 + */ + class Event { + + /** + * 一个空的 Event 对象。用于事件派发中转使用。 + */ + static EMPTY:Event; + + /** + * 定义 mousedown 事件对象的 type 属性值。 + */ + static MOUSE_DOWN:string; + + /** + * 定义 mouseup 事件对象的 type 属性值。 + */ + static MOUSE_UP:string; + + /** + * 定义 click 事件对象的 type 属性值。 + */ + static CLICK:string; + + /** + * 定义 rightmousedown 事件对象的 type 属性值。 + */ + static RIGHT_MOUSE_DOWN:string; + + /** + * 定义 rightmouseup 事件对象的 type 属性值。 + */ + static RIGHT_MOUSE_UP:string; + + /** + * 定义 rightclick 事件对象的 type 属性值。 + */ + static RIGHT_CLICK:string; + + /** + * 定义 mousemove 事件对象的 type 属性值。 + */ + static MOUSE_MOVE:string; + + /** + * 定义 mouseover 事件对象的 type 属性值。 + */ + static MOUSE_OVER:string; + + /** + * 定义 mouseout 事件对象的 type 属性值。 + */ + static MOUSE_OUT:string; + + /** + * 定义 mousewheel 事件对象的 type 属性值。 + */ + static MOUSE_WHEEL:string; + + /** + * 定义 mouseover 事件对象的 type 属性值。 + */ + static ROLL_OVER:string; + + /** + * 定义 mouseout 事件对象的 type 属性值。 + */ + static ROLL_OUT:string; + + /** + * 定义 doubleclick 事件对象的 type 属性值。 + */ + static DOUBLE_CLICK:string; + + /** + * 定义 change 事件对象的 type 属性值。 + */ + static CHANGE:string; + + /** + * 定义 changed 事件对象的 type 属性值。 + */ + static CHANGED:string; + + /** + * 定义 resize 事件对象的 type 属性值。 + */ + static RESIZE:string; + + /** + * 定义 added 事件对象的 type 属性值。 + */ + static ADDED:string; + + /** + * 定义 removed 事件对象的 type 属性值。 + */ + static REMOVED:string; + + /** + * 定义 display 事件对象的 type 属性值。 + */ + static DISPLAY:string; + + /** + * 定义 undisplay 事件对象的 type 属性值。 + */ + static UNDISPLAY:string; + + /** + * 定义 error 事件对象的 type 属性值。 + */ + static ERROR:string; + + /** + * 定义 complete 事件对象的 type 属性值。 + */ + static COMPLETE:string; + + /** + * 定义 loaded 事件对象的 type 属性值。 + */ + static LOADED:string; + + /** + * 定义 loaded 事件对象的 type 属性值。 + */ + static READY:string; + + /** + * 定义 progress 事件对象的 type 属性值。 + */ + static PROGRESS:string; + + /** + * 定义 input 事件对象的 type 属性值。 + */ + static INPUT:string; + + /** + * 定义 render 事件对象的 type 属性值。 + */ + static RENDER:string; + + /** + * 定义 open 事件对象的 type 属性值。 + */ + static OPEN:string; + + /** + * 定义 message 事件对象的 type 属性值。 + */ + static MESSAGE:string; + + /** + * 定义 close 事件对象的 type 属性值。 + */ + static CLOSE:string; + + /** + * 定义 keydown 事件对象的 type 属性值。 + */ + static KEY_DOWN:string; + + /** + * 定义 keypress 事件对象的 type 属性值。 + */ + static KEY_PRESS:string; + + /** + * 定义 keyup 事件对象的 type 属性值。 + */ + static KEY_UP:string; + + /** + * 定义 frame 事件对象的 type 属性值。 + */ + static FRAME:string; + + /** + * 定义 dragstart 事件对象的 type 属性值。 + */ + static DRAG_START:string; + + /** + * 定义 dragmove 事件对象的 type 属性值。 + */ + static DRAG_MOVE:string; + + /** + * 定义 dragend 事件对象的 type 属性值。 + */ + static DRAG_END:string; + + /** + * 定义 enter 事件对象的 type 属性值。 + */ + static ENTER:string; + + /** + * 定义 select 事件对象的 type 属性值。 + */ + static SELECT:string; + + /** + * 定义 blur 事件对象的 type 属性值。 + */ + static BLUR:string; + + /** + * 定义 focus 事件对象的 type 属性值。 + */ + static FOCUS:string; + + /** + * 定义 visibilitychange 事件对象的 type 属性值。 + */ + static VISIBILITY_CHANGE:string; + + /** + * 定义 focuschange 事件对象的 type 属性值。 + */ + static FOCUS_CHANGE:string; + + /** + * 定义 played 事件对象的 type 属性值。 + */ + static PLAYED:string; + + /** + * 定义 paused 事件对象的 type 属性值。 + */ + static PAUSED:string; + + /** + * 定义 stopped 事件对象的 type 属性值。 + */ + static STOPPED:string; + + /** + * 定义 start 事件对象的 type 属性值。 + */ + static START:string; + + /** + * 定义 end 事件对象的 type 属性值。 + */ + static END:string; + + /** + * 定义 componentadded 事件对象的 type 属性值。 + */ + static COMPONENT_ADDED:string; + + /** + * 定义 componentremoved 事件对象的 type 属性值。 + */ + static COMPONENT_REMOVED:string; + + /** + * 定义 released 事件对象的 type 属性值。 + */ + static RELEASED:string; + + /** + * 定义 link 事件对象的 type 属性值。 + */ + static LINK:string; + + /** + * 定义 label 事件对象的 type 属性值。 + */ + static LABEL:string; + + /** + * 浏览器全屏更改时触发 + */ + static FULL_SCREEN_CHANGE:string; + + /** + * 显卡设备丢失时触发 + */ + static DEVICE_LOST:string; + + /** + * 世界矩阵更新时触发。 + */ + static TRANSFORM_CHANGED:string; + + /** + * 更换动作时触发。 + */ + static ANIMATION_CHANGED:string; + + /** + * 拖尾渲染节点改变时触发。 + */ + static TRAIL_FILTER_CHANGE:string; + + /** + * 物理碰撞开始 + */ + static TRIGGER_ENTER:string; + + /** + * 物理碰撞持续 + */ + static TRIGGER_STAY:string; + + /** + * 物理碰撞结束 + */ + static TRIGGER_EXIT:string; + + /** + * 事件类型。 + */ + type:string; + + /** + * 原生浏览器事件。 + */ + nativeEvent:any; + + /** + * 事件目标触发对象。 + */ + target:Sprite; + + /** + * 事件当前冒泡对象。 + */ + currentTarget:Sprite; + + /** + * 分配给触摸点的唯一标识号(作为 int)。 + */ + touchId:number; + + /** + * 键盘值 + */ + keyCode:number; + + /** + * 滚轮滑动增量 + */ + delta:number; + + /** + * 设置事件数据。 + * @param type 事件类型。 + * @param currentTarget 事件目标触发对象。 + * @param target 事件当前冒泡对象。 + * @return 返回当前 Event 对象。 + */ + setTo(type:string,currentTarget:Sprite,target:Sprite):Event; + + /** + * 阻止对事件流中当前节点的后续节点中的所有事件侦听器进行处理。此方法不会影响当前节点 (currentTarget) 中的任何事件侦听器。 + */ + stopPropagation():void; + + /** + * 触摸点列表。 + */ + get touches():any[]; + + /** + * 表示 Alt 键是处于活动状态 (true) 还是非活动状态 (false)。 + */ + get altKey():boolean; + + /** + * 表示 Ctrl 键是处于活动状态 (true) 还是非活动状态 (false)。 + */ + get ctrlKey():boolean; + + /** + * 表示 Shift 键是处于活动状态 (true) 还是非活动状态 (false)。 + */ + get shiftKey():boolean; + + /** + * 包含按下或释放的键的字符代码值。字符代码值为英文键盘值。 + */ + get charCode():boolean; + + /** + * 表示键在键盘上的位置。这对于区分在键盘上多次出现的键非常有用。
    + * 例如,您可以根据此属性的值来区分左 Shift 键和右 Shift 键:左 Shift 键的值为 KeyLocation.LEFT,右 Shift 键的值为 KeyLocation.RIGHT。另一个示例是区分标准键盘 (KeyLocation.STANDARD) 与数字键盘 (KeyLocation.NUM_PAD) 上按下的数字键。 + */ + get keyLocation():number; + + /** + * 鼠标在 Stage 上的 X 轴坐标 + */ + get stageX():number; + + /** + * 鼠标在 Stage 上的 Y 轴坐标 + */ + get stageY():number; + } + + /** + * EventDispatcher 类是可调度事件的所有类的基类。 + */ + class EventDispatcher { + + /** + * @private + */ + static MOUSE_EVENTS:any; + + /** + * @private + */ + private _events:any; + + /** + * 检查 EventDispatcher 对象是否为特定事件类型注册了任何侦听器。 + * @param type 事件的类型。 + * @return 如果指定类型的侦听器已注册,则值为 true;否则,值为 false。 + */ + hasListener(type:string):boolean; + + /** + * 派发事件。 + * @param type 事件类型。 + * @param data (可选)回调数据。注意:如果是需要传递多个参数 p1,p2,p3,...可以使用数组结构如:[p1,p2,p3,...] ;如果需要回调单个参数 p ,且 p 是一个数组,则需要使用结构如:[p],其他的单个参数 p ,可以直接传入参数 p。 + * @return 此事件类型是否有侦听者,如果有侦听者则值为 true,否则值为 false。 + */ + event(type:string,data?:any):boolean; + + /** + * 使用 EventDispatcher 对象注册指定类型的事件侦听器对象,以使侦听器能够接收事件通知。 + * @param type 事件的类型。 + * @param caller 事件侦听函数的执行域。 + * @param listener 事件侦听函数。 + * @param args (可选)事件侦听函数的回调参数。 + * @return 此 EventDispatcher 对象。 + */ + on(type:string,caller:any,listener:Function,args?:any[]):EventDispatcher; + + /** + * 使用 EventDispatcher 对象注册指定类型的事件侦听器对象,以使侦听器能够接收事件通知,此侦听事件响应一次后自动移除。 + * @param type 事件的类型。 + * @param caller 事件侦听函数的执行域。 + * @param listener 事件侦听函数。 + * @param args (可选)事件侦听函数的回调参数。 + * @return 此 EventDispatcher 对象。 + */ + once(type:string,caller:any,listener:Function,args?:any[]):EventDispatcher; + + /** + * 从 EventDispatcher 对象中删除侦听器。 + * @param type 事件的类型。 + * @param caller 事件侦听函数的执行域。 + * @param listener 事件侦听函数。 + * @param onceOnly (可选)如果值为 true ,则只移除通过 once 方法添加的侦听器。 + * @return 此 EventDispatcher 对象。 + */ + off(type:string,caller:any,listener:Function,onceOnly?:boolean):EventDispatcher; + + /** + * 从 EventDispatcher 对象中删除指定事件类型的所有侦听器。 + * @param type (可选)事件类型,如果值为 null,则移除本对象所有类型的侦听器。 + * @return 此 EventDispatcher 对象。 + */ + offAll(type?:string):EventDispatcher; + + /** + * 移除caller为target的所有事件监听 + * @param caller caller对象 + */ + offAllCaller(caller:any):EventDispatcher; + private _recoverHandlers:any; + + /** + * 检测指定事件类型是否是鼠标事件。 + * @param type 事件的类型。 + * @return 如果是鼠标事件,则值为 true;否则,值为 false。 + */ + isMouseEvent(type:string):boolean; + } + + /** + * Keyboard 类的属性是一些常数,这些常数表示控制游戏时最常用的键。 + */ + class Keyboard { + + /** + * 与 0 的键控代码值 (48) 关联的常数。 + */ + static NUMBER_0:number; + + /** + * 与 1 的键控代码值 (49) 关联的常数。 + */ + static NUMBER_1:number; + + /** + * 与 2 的键控代码值 (50) 关联的常数。 + */ + static NUMBER_2:number; + + /** + * 与 3 的键控代码值 (51) 关联的常数。 + */ + static NUMBER_3:number; + + /** + * 与 4 的键控代码值 (52) 关联的常数。 + */ + static NUMBER_4:number; + + /** + * 与 5 的键控代码值 (53) 关联的常数。 + */ + static NUMBER_5:number; + + /** + * 与 6 的键控代码值 (54) 关联的常数。 + */ + static NUMBER_6:number; + + /** + * 与 7 的键控代码值 (55) 关联的常数。 + */ + static NUMBER_7:number; + + /** + * 与 8 的键控代码值 (56) 关联的常数。 + */ + static NUMBER_8:number; + + /** + * 与 9 的键控代码值 (57) 关联的常数。 + */ + static NUMBER_9:number; + + /** + * 与 A 键的键控代码值 (65) 关联的常数。 + */ + static A:number; + + /** + * 与 B 键的键控代码值 (66) 关联的常数。 + */ + static B:number; + + /** + * 与 C 键的键控代码值 (67) 关联的常数。 + */ + static C:number; + + /** + * 与 D 键的键控代码值 (68) 关联的常数。 + */ + static D:number; + + /** + * 与 E 键的键控代码值 (69) 关联的常数。 + */ + static E:number; + + /** + * 与 F 键的键控代码值 (70) 关联的常数。 + */ + static F:number; + + /** + * 与 G 键的键控代码值 (71) 关联的常数。 + */ + static G:number; + + /** + * 与 H 键的键控代码值 (72) 关联的常数。 + */ + static H:number; + + /** + * 与 I 键的键控代码值 (73) 关联的常数。 + */ + static I:number; + + /** + * 与 J 键的键控代码值 (74) 关联的常数。 + */ + static J:number; + + /** + * 与 K 键的键控代码值 (75) 关联的常数。 + */ + static K:number; + + /** + * 与 L 键的键控代码值 (76) 关联的常数。 + */ + static L:number; + + /** + * 与 M 键的键控代码值 (77) 关联的常数。 + */ + static M:number; + + /** + * 与 N 键的键控代码值 (78) 关联的常数。 + */ + static N:number; + + /** + * 与 O 键的键控代码值 (79) 关联的常数。 + */ + static O:number; + + /** + * 与 P 键的键控代码值 (80) 关联的常数。 + */ + static P:number; + + /** + * 与 Q 键的键控代码值 (81) 关联的常数。 + */ + static Q:number; + + /** + * 与 R 键的键控代码值 (82) 关联的常数。 + */ + static R:number; + + /** + * 与 S 键的键控代码值 (83) 关联的常数。 + */ + static S:number; + + /** + * 与 T 键的键控代码值 (84) 关联的常数。 + */ + static T:number; + + /** + * 与 U 键的键控代码值 (85) 关联的常数。 + */ + static U:number; + + /** + * 与 V 键的键控代码值 (86) 关联的常数。 + */ + static V:number; + + /** + * 与 W 键的键控代码值 (87) 关联的常数。 + */ + static W:number; + + /** + * 与 X 键的键控代码值 (88) 关联的常数。 + */ + static X:number; + + /** + * 与 Y 键的键控代码值 (89) 关联的常数。 + */ + static Y:number; + + /** + * 与 Z 键的键控代码值 (90) 关联的常数。 + */ + static Z:number; + + /** + * 与 F1 的键控代码值 (112) 关联的常数。 + */ + static F1:number; + + /** + * 与 F2 的键控代码值 (113) 关联的常数。 + */ + static F2:number; + + /** + * 与 F3 的键控代码值 (114) 关联的常数。 + */ + static F3:number; + + /** + * 与 F4 的键控代码值 (115) 关联的常数。 + */ + static F4:number; + + /** + * 与 F5 的键控代码值 (116) 关联的常数。 + */ + static F5:number; + + /** + * 与 F6 的键控代码值 (117) 关联的常数。 + */ + static F6:number; + + /** + * 与 F7 的键控代码值 (118) 关联的常数。 + */ + static F7:number; + + /** + * 与 F8 的键控代码值 (119) 关联的常数。 + */ + static F8:number; + + /** + * 与 F9 的键控代码值 (120) 关联的常数。 + */ + static F9:number; + + /** + * 与 F10 的键控代码值 (121) 关联的常数。 + */ + static F10:number; + + /** + * 与 F11 的键控代码值 (122) 关联的常数。 + */ + static F11:number; + + /** + * 与 F12 的键控代码值 (123) 关联的常数。 + */ + static F12:number; + + /** + * 与 F13 的键控代码值 (124) 关联的常数。 + */ + static F13:number; + + /** + * 与 F14 的键控代码值 (125) 关联的常数。 + */ + static F14:number; + + /** + * 与 F15 的键控代码值 (126) 关联的常数。 + */ + static F15:number; + + /** + * 与数字键盘的伪键控代码 (21) 关联的常数。 + */ + static NUMPAD:number; + + /** + * 与数字键盘上的数字 0 的键控代码值 (96) 关联的常数。 + */ + static NUMPAD_0:number; + + /** + * 与数字键盘上的数字 1 的键控代码值 (97) 关联的常数。 + */ + static NUMPAD_1:number; + + /** + * 与数字键盘上的数字 2 的键控代码值 (98) 关联的常数。 + */ + static NUMPAD_2:number; + + /** + * 与数字键盘上的数字 3 的键控代码值 (99) 关联的常数。 + */ + static NUMPAD_3:number; + + /** + * 与数字键盘上的数字 4 的键控代码值 (100) 关联的常数。 + */ + static NUMPAD_4:number; + + /** + * 与数字键盘上的数字 5 的键控代码值 (101) 关联的常数。 + */ + static NUMPAD_5:number; + + /** + * 与数字键盘上的数字 6 的键控代码值 (102) 关联的常数。 + */ + static NUMPAD_6:number; + + /** + * 与数字键盘上的数字 7 的键控代码值 (103) 关联的常数。 + */ + static NUMPAD_7:number; + + /** + * 与数字键盘上的数字 8 的键控代码值 (104) 关联的常数。 + */ + static NUMPAD_8:number; + + /** + * 与数字键盘上的数字 9 的键控代码值 (105) 关联的常数。 + */ + static NUMPAD_9:number; + + /** + * 与数字键盘上的加号 (+) 的键控代码值 (107) 关联的常数。 + */ + static NUMPAD_ADD:number; + + /** + * 与数字键盘上的小数点 (.) 的键控代码值 (110) 关联的常数。 + */ + static NUMPAD_DECIMAL:number; + + /** + * 与数字键盘上的除号 (/) 的键控代码值 (111) 关联的常数。 + */ + static NUMPAD_DIVIDE:number; + + /** + * 与数字键盘上的 Enter 的键控代码值 (108) 关联的常数。 + */ + static NUMPAD_ENTER:number; + + /** + * 与数字键盘上的乘号 (*) 的键控代码值 (106) 关联的常数。 + */ + static NUMPAD_MULTIPLY:number; + + /** + * 与数字键盘上的减号 (-) 的键控代码值 (109) 关联的常数。 + */ + static NUMPAD_SUBTRACT:number; + + /** + * 与 ; 键的键控代码值 (186) 关联的常数。 + */ + static SEMICOLON:number; + + /** + * 与 = 键的键控代码值 (187) 关联的常数。 + */ + static EQUAL:number; + + /** + * 与 F15 的键控代码值 (188) 关联的常数。 + */ + static COMMA:number; + + /** + * 与 - 键的键控代码值 (189) 关联的常数。 + */ + static MINUS:number; + + /** + * 与 . 键的键控代码值 (190) 关联的常数。 + */ + static PERIOD:number; + + /** + * 与 / 键的键控代码值 (191) 关联的常数。 + */ + static SLASH:number; + + /** + * 与 ` 键的键控代码值 (192) 关联的常数。 + */ + static BACKQUOTE:number; + + /** + * 与 [ 键的键控代码值 (219) 关联的常数。 + */ + static LEFTBRACKET:number; + + /** + * 与 \ 键的键控代码值 (220) 关联的常数。 + */ + static BACKSLASH:number; + + /** + * 与 ] 键的键控代码值 (221) 关联的常数。 + */ + static RIGHTBRACKET:number; + + /** + * 与 ' 键的键控代码值 (222) 关联的常数。 + */ + static QUOTE:number; + + /** + * 与 Alternate (Option) 键的键控代码值 (18) 关联的常数。 + */ + static ALTERNATE:number; + + /** + * 与 Backspace 的键控代码值 (8) 关联的常数。 + */ + static BACKSPACE:number; + + /** + * 与 Caps Lock 的键控代码值 (20) 关联的常数。 + */ + static CAPS_LOCK:number; + + /** + * 与 Mac 命令键 (15) 关联的常数。 + */ + static COMMAND:number; + + /** + * 与 Ctrl 的键控代码值 (17) 关联的常数。 + */ + static CONTROL:number; + + /** + * 与 Delete 的键控代码值 (46) 关联的常数。 + */ + static DELETE:number; + + /** + * 与 Enter 的键控代码值 (13) 关联的常数。 + */ + static ENTER:number; + + /** + * 与 Esc 的键控代码值 (27) 关联的常数。 + */ + static ESCAPE:number; + + /** + * 与 Page Up 的键控代码值 (33) 关联的常数。 + */ + static PAGE_UP:number; + + /** + * 与 Page Down 的键控代码值 (34) 关联的常数。 + */ + static PAGE_DOWN:number; + + /** + * 与 End 的键控代码值 (35) 关联的常数。 + */ + static END:number; + + /** + * 与 Home 的键控代码值 (36) 关联的常数。 + */ + static HOME:number; + + /** + * 与向左箭头键的键控代码值 (37) 关联的常数。 + */ + static LEFT:number; + + /** + * 与向上箭头键的键控代码值 (38) 关联的常数。 + */ + static UP:number; + + /** + * 与向右箭头键的键控代码值 (39) 关联的常数。 + */ + static RIGHT:number; + + /** + * 与向下箭头键的键控代码值 (40) 关联的常数。 + */ + static DOWN:number; + + /** + * 与 Shift 的键控代码值 (16) 关联的常数。 + */ + static SHIFT:number; + + /** + * 与空格键的键控代码值 (32) 关联的常数。 + */ + static SPACE:number; + + /** + * 与 Tab 的键控代码值 (9) 关联的常数。 + */ + static TAB:number; + + /** + * 与 Insert 的键控代码值 (45) 关联的常数。 + */ + static INSERT:number; + } + + /** + *

    KeyBoardManager 是键盘事件管理类。该类从浏览器中接收键盘事件,并派发该事件。

    + *

    派发事件时若 Stage.focus 为空则只从 Stage 上派发该事件,否则将从 Stage.focus 对象开始一直冒泡派发该事件。所以在 Laya.stage 上监听键盘事件一定能够收到,如果在其他地方监听,则必须处在Stage.focus的冒泡链上才能收到该事件。

    + *

    用户可以通过代码 Laya.stage.focus=someNode 的方式来设置focus对象。

    + *

    用户可统一的根据事件对象中 e.keyCode 来判断按键类型,该属性兼容了不同浏览器的实现。

    + */ + class KeyBoardManager { + private static _pressKeys:any; + + /** + * 是否开启键盘事件,默认为true + */ + static enabled:boolean; + private static _addEvent:any; + private static _dispatch:any; + + /** + * 返回指定键是否被按下。 + * @param key 键值。 + * @return 是否被按下。 + */ + static hasKeyDown(key:number):boolean; + } + + /** + *

    KeyLocation 类包含表示在键盘或类似键盘的输入设备上按键位置的常量。

    + *

    KeyLocation 常数用在键盘事件对象的 keyLocation 属性中。

    + */ + class KeyLocation { + + /** + * 表示激活的键不区分位于左侧还是右侧,也不区分是否位于数字键盘(或者是使用对应于数字键盘的虚拟键激活的)。 + */ + static STANDARD:number; + + /** + * 表示激活的键在左侧键位置(此键有多个可能的位置)。 + */ + static LEFT:number; + + /** + * 表示激活的键在右侧键位置(此键有多个可能的位置)。 + */ + static RIGHT:number; + + /** + *

    表示激活的键位于数字键盘或者是使用对应于数字键盘的虚拟键激活的。

    + *

    注意:此属性只在flash模式下有效。

    + */ + static NUM_PAD:number; + } + + /** + *

    MouseManager 是鼠标、触摸交互管理器。

    + *

    鼠标事件流包括捕获阶段、目标阶段、冒泡阶段。
    + * 捕获阶段:此阶段引擎会从stage开始递归检测stage及其子对象,直到找到命中的目标对象或者未命中任何对象;
    + * 目标阶段:找到命中的目标对象;
    + * 冒泡阶段:事件离开目标对象,按节点层级向上逐层通知,直到到达舞台的过程。

    + */ + class MouseManager { + + /** + * MouseManager 单例引用。 + */ + static instance:MouseManager; + + /** + * 是否开启鼠标检测,默认为true + */ + static enabled:boolean; + + /** + * 是否开启多点触控 + */ + static multiTouchEnabled:boolean; + + /** + * canvas 上的鼠标X坐标。 + */ + mouseX:number; + + /** + * canvas 上的鼠标Y坐标。 + */ + mouseY:number; + + /** + * 是否禁用除 stage 以外的鼠标事件检测。 + */ + disableMouseEvent:boolean; + + /** + * 鼠标按下的时间。单位为毫秒。 + */ + mouseDownTime:number; + + /** + * 鼠标移动精度。 + */ + mouseMoveAccuracy:number; + + /** + * @private + */ + private static _isTouchRespond:any; + private _stage:any; + + /** + * @private 希望capture鼠标事件的对象。 + */ + private _captureSp:any; + + /** + * @private 现在不支持直接把绝对坐标转到本地坐标,只能一级一级做下去,因此记录一下这个链 + */ + private _captureChain:any; + + /** + * @private capture对象独占消息 + */ + private _captureExlusiveMode:any; + + /** + * @private 在发送事件的过程中,是否发送给了_captureSp + */ + private _hitCaputreSp:any; + private _point:any; + private _rect:any; + private _target:any; + private _lastMoveTimer:any; + private _isLeftMouse:any; + private _prePoint:any; + private _touchIDs:any; + private _curTouchID:any; + private _id:any; + private static _isFirstTouch:any; + + /** + * @private 初始化。 + */ + __init__(stage:Stage,canvas:any):void; + private _tTouchID:any; + private initEvent:any; + private checkMouseWheel:any; + private onMouseMove:any; + private onMouseDown:any; + private onMouseUp:any; + private check:any; + private hitTest:any; + private _checkAllBaseUI:any; + + /** + * 处理3d界面。 + * @param mousex + * @param mousey + * @param callback + * @return + */ + check3DUI(mousex:number,mousey:number,callback:Function):boolean; + handleExclusiveCapture(mousex:number,mousey:number,callback:Function):boolean; + handleCapture(mousex:number,mousey:number,callback:Function):boolean; + + /** + * 执行事件处理。 + */ + runEvent(evt:any):void; + + /** + * @param sp + * @param exlusive 是否是独占模式 + */ + setCapture(sp:Sprite,exclusive?:boolean):void; + releaseCapture():void; + } + + /** + * @private Touch事件管理类,处理多点触控下的鼠标事件 + */ + class TouchManager { + static I:TouchManager; + private static _oldArr:any; + private static _newArr:any; + private static _tEleArr:any; + + /** + * 当前over的touch表 + */ + private preOvers:any; + + /** + * 当前down的touch表 + */ + private preDowns:any; + private preRightDowns:any; + + /** + * 是否启用 + */ + enable:boolean; + private _lastClickTime:any; + private _clearTempArrs:any; + + /** + * 从touch表里查找对应touchID的数据 + * @param touchID touch ID + * @param arr touch表 + * @return + */ + private getTouchFromArr:any; + + /** + * 从touch表里移除一个元素 + * @param touchID touch ID + * @param arr touch表 + */ + private removeTouchFromArr:any; + + /** + * 创建一个touch数据 + * @param ele 当前的根节点 + * @param touchID touchID + * @return + */ + private createTouchO:any; + + /** + * 处理touchStart + * @param ele 根节点 + * @param touchID touchID + * @param isLeft (可选)是否为左键 + */ + onMouseDown(ele:any,touchID:number,isLeft?:boolean):void; + + /** + * 派发事件。 + * @param eles 对象列表。 + * @param type 事件类型。 + */ + private sendEvents:any; + + /** + * 获取对象列表。 + * @param start 起始节点。 + * @param end 结束节点。 + * @param rst 返回值。如果此值不为空,则将其赋值为计算结果,从而避免创建新数组;如果此值为空,则创建新数组返回。 + * @return Array 返回节点列表。 + */ + private getEles:any; + + /** + * touchMove时处理out事件和over时间。 + * @param eleNew 新的根节点。 + * @param elePre 旧的根节点。 + * @param touchID (可选)touchID,默认为0。 + */ + private checkMouseOutAndOverOfMove:any; + + /** + * 处理TouchMove事件 + * @param ele 根节点 + * @param touchID touchID + */ + onMouseMove(ele:any,touchID:number):void; + getLastOvers():any[]; + stageMouseOut():void; + + /** + * 处理TouchEnd事件 + * @param ele 根节点 + * @param touchID touchID + * @param isLeft 是否为左键 + */ + onMouseUp(ele:any,touchID:number,isLeft?:boolean):void; + } + + /** + * 模糊滤镜 + */ + class BlurFilter extends Filter { + + /** + * 模糊滤镜的强度(值越大,越不清晰 + */ + strength:number; + strength_sig2_2sig2_gauss1:any[]; + strength_sig2_native:Float32Array; + renderFunc:any; + + /** + * 模糊滤镜 + * @param strength 模糊滤镜的强度值 + */ + + constructor(strength?:number); + + /** + * @private 当前滤镜的类型 + * @override + */ + get type():number; + getStrenth_sig2_2sig2_native():Float32Array; + } + + /** + * @private + */ + class BlurFilterGLRender { + private static blurinfo:any; + render(rt:RenderTexture2D,ctx:Context,width:number,height:number,filter:BlurFilter):void; + setShaderInfo(shader:Value2D,filter:BlurFilter,w:number,h:number):void; + } + + /** + *

    ColorFilter 是颜色滤镜。使用 ColorFilter 类可以将 4 x 5 矩阵转换应用于输入图像上的每个像素的 RGBA 颜色和 Alpha 值,以生成具有一组新的 RGBA 颜色和 Alpha 值的结果。该类允许饱和度更改、色相旋转、亮度转 Alpha 以及各种其他效果。您可以将滤镜应用于任何显示对象(即,从 Sprite 类继承的对象)。

    + *

    注意:对于 RGBA 值,最高有效字节代表红色通道值,其后的有效字节分别代表绿色、蓝色和 Alpha 通道值。

    + */ + class ColorFilter extends Filter implements IFilter { + + /** + * 对比度列表 + */ + private static DELTA_INDEX:any; + + /** + * 灰色矩阵 + */ + private static GRAY_MATRIX:any; + + /** + * 单位矩阵,表示什么效果都没有 + */ + private static IDENTITY_MATRIX:any; + + /** + * 标准矩阵长度 + */ + private static LENGTH:any; + + /** + * 当前使用的矩阵 + */ + private _matrix:any; + + /** + * 创建一个 ColorFilter 实例。 + * @param mat (可选)由 20 个项目(排列成 4 x 5 矩阵)组成的数组,用于颜色转换。 + */ + + constructor(mat?:any[]); + + /** + * 设置为灰色滤镜 + */ + gray():ColorFilter; + + /** + * 设置为变色滤镜 + * @param red 红色增量,范围:0~255 + * @param green 绿色增量,范围:0~255 + * @param blue 蓝色增量,范围:0~255 + * @param alpha alpha,范围:0~1 + */ + color(red?:number,green?:number,blue?:number,alpha?:number):ColorFilter; + + /** + * 设置滤镜色 + * @param color 颜色值 + */ + setColor(color:string):ColorFilter; + + /** + * 设置矩阵数据 + * @param matrix 由 20 个项目(排列成 4 x 5 矩阵)组成的数组 + * @return this + */ + setByMatrix(matrix:any[]):ColorFilter; + + /** + * @private + * @override + */ + get type():number; + + /** + * 调整颜色,包括亮度,对比度,饱和度和色调 + * @param brightness 亮度,范围:-100~100 + * @param contrast 对比度,范围:-100~100 + * @param saturation 饱和度,范围:-100~100 + * @param hue 色调,范围:-180~180 + * @return this + */ + adjustColor(brightness:number,contrast:number,saturation:number,hue:number):ColorFilter; + + /** + * 调整亮度 + * @param brightness 亮度,范围:-100~100 + * @return this + */ + adjustBrightness(brightness:number):ColorFilter; + + /** + * 调整对比度 + * @param contrast 对比度,范围:-100~100 + * @return this + */ + adjustContrast(contrast:number):ColorFilter; + + /** + * 调整饱和度 + * @param saturation 饱和度,范围:-100~100 + * @return this + */ + adjustSaturation(saturation:number):ColorFilter; + + /** + * 调整色调 + * @param hue 色调,范围:-180~180 + * @return this + */ + adjustHue(hue:number):ColorFilter; + + /** + * 重置成单位矩阵,去除滤镜效果 + */ + reset():ColorFilter; + + /** + * 矩阵乘法 + * @param matrix + * @return this + */ + private _multiplyMatrix:any; + + /** + * 规范值的范围 + * @param val 当前值 + * @param limit 值的范围-limit~limit + */ + private _clampValue:any; + + /** + * 规范矩阵,将矩阵调整到正确的大小 + * @param matrix 需要调整的矩阵 + */ + private _fixMatrix:any; + + /** + * 复制矩阵 + */ + private _copyMatrix:any; + } + + /** + * Filter 是滤镜基类。 + */ + class Filter implements IFilter { + + /** + * @private 模糊滤镜。 + */ + static BLUR:number; + + /** + * @private 颜色滤镜。 + */ + static COLOR:number; + + /** + * @private 发光滤镜。 + */ + static GLOW:number; + + /** + * 创建一个 Filter 实例。 + */ + + constructor(); + + /** + * @private 滤镜类型。 + */ + get type():number; + static _filter:(this:RenderSprite,sprite:Sprite,context:Context,x:number,y:number) =>void; + } + + /** + * 发光滤镜(也可以当成阴影滤使用) + */ + class GlowFilter extends Filter { + + /** + * 数据的存储,顺序R,G,B,A,blurWidth,offX,offY; + */ + private _elements:any; + + /** + * 滤镜的颜色 + */ + private _color:any; + + /** + * 创建发光滤镜 + * @param color 滤镜的颜色 + * @param blur 边缘模糊的大小 + * @param offX X轴方向的偏移 + * @param offY Y轴方向的偏移 + */ + + constructor(color:string,blur?:number,offX?:number,offY?:number); + + /** + * @private 滤镜类型 + * @override + */ + get type():number; + + /** + * @private + */ + get offY():number; + + /** + * @private + */ + set offY(value:number); + + /** + * @private + */ + get offX():number; + + /** + * @private + */ + set offX(value:number); + + /** + * @private + */ + getColor():any[]; + + /** + * @private + */ + get blur():number; + + /** + * @private + */ + set blur(value:number); + getColorNative():Float32Array; + getBlurInfo1Native():Float32Array; + getBlurInfo2Native():Float32Array; + } + + /** + * @private + */ + class GlowFilterGLRender { + private setShaderInfo:any; + render(rt:RenderTexture2D,ctx:Context,width:number,height:number,filter:GlowFilter):void; + } + + interface IFilter{ + type:number; + } + + +const enum glTFAccessorComponentType { + /** Byte */ + BYTE = 5120, + /** Unsigned Byte */ + UNSIGNED_BYTE = 5121, + /** Short */ + SHORT = 5122, + /** Unsigned Short */ + UNSIGNED_SHORT = 5123, + /** Unsigned Int */ + UNSIGNED_INT = 5125, + /** Float */ + FLOAT = 5126 +} + +const enum glTFAccessorType { + /** Scalar */ + SCALAR = "SCALAR", + /** Vector2 */ + VEC2 = "VEC2", + /** Vector3 */ + VEC3 = "VEC3", + /** Vector4 */ + VEC4 = "VEC4", + /** Matrix2x2 */ + MAT2 = "MAT2", + /** Matrix3x3 */ + MAT3 = "MAT3", + /** Matrix4x4 */ + MAT4 = "MAT4" +} + +const enum glTFAnimationChannelTargetPath { + /** Translation */ + TRANSLATION = "translation", + /** Rotation */ + ROTATION = "rotation", + /** Scale */ + SCALE = "scale", + /** Weights */ + WEIGHTS = "weights" +} + +const enum glTFAnimationSamplerInterpolation { + /** The animated values are linearly interpolated between keyframes */ + LINEAR = "LINEAR", + /** The animated values remain constant to the output of the first keyframe, until the next keyframe */ + STEP = "STEP", + /** The animation's interpolation is computed using a cubic spline with specified tangents */ + CUBICSPLINE = "CUBICSPLINE" +} + +const enum glTFCameraType { + /** A perspective camera containing properties to create a perspective projection matrix */ + PERSPECTIVE = "perspective", + /** An orthographic camera containing properties to create an orthographic projection matrix */ + ORTHOGRAPHIC = "orthographic" +} + +const enum glTFImageMimeType { + /** JPEG Mime-type */ + JPEG = "image/jpeg", + /** PNG Mime-type */ + PNG = "image/png" +} + +const enum glTFMaterialAlphaMode { + /** The alpha value is ignored and the rendered output is fully opaque */ + OPAQUE = "OPAQUE", + /** The rendered output is either fully opaque or fully transparent depending on the alpha value and the specified alpha cutoff value */ + MASK = "MASK", + /** The alpha value is used to composite the source and destination areas. The rendered output is combined with the background using the normal painting operation (i.e. the Porter and Duff over operator) */ + BLEND = "BLEND" +} + +const enum glTFMeshPrimitiveMode { + /** Points */ + POINTS = 0, + /** Lines */ + LINES = 1, + /** Line Loop */ + LINE_LOOP = 2, + /** Line Strip */ + LINE_STRIP = 3, + /** Triangles */ + TRIANGLES = 4, + /** Triangle Strip */ + TRIANGLE_STRIP = 5, + /** Triangle Fan */ + TRIANGLE_FAN = 6 +} + +const enum glTFTextureMagFilter { + /** Nearest */ + NEAREST = 9728, + /** Linear */ + LINEAR = 9729 +} + +const enum glTFTextureMinFilter { + /** Nearest */ + NEAREST = 9728, + /** Linear */ + LINEAR = 9729, + /** Nearest Mip-Map Nearest */ + NEAREST_MIPMAP_NEAREST = 9984, + /** Linear Mipmap Nearest */ + LINEAR_MIPMAP_NEAREST = 9985, + /** Nearest Mipmap Linear */ + NEAREST_MIPMAP_LINEAR = 9986, + /** Linear Mipmap Linear */ + LINEAR_MIPMAP_LINEAR = 9987 +} + +const enum glTFTextureWrapMode { + /** Clamp to Edge */ + CLAMP_TO_EDGE = 33071, + /** Mirrored Repeat */ + MIRRORED_REPEAT = 33648, + /** Repeat */ + REPEAT = 10497 +} + + interface glTFNodeProperty{ + + /** + * Dictionary object with extension-specific objects. + */ + extensions?:{[key:string]:any;}; + + /** + * Application-specific data. + */ + extras?:any; + } + + + interface glTFChildNodeProperty{ + + /** + * The user-defined name of this object. + */ + name?:string; + } + + + interface glTFAccessorSparseIndeces extends glTFNodeProperty { + + /** + * The index of the bufferView with sparse indices. Referenced bufferView can't have ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target + */ + bufferView:number; + + /** + * The offset relative to the start of the bufferView in bytes. Must be aligned + */ + byteOffset?:number; + + /** + * The indices data type. Valid values correspond to WebGL enums: 5121 (UNSIGNED_BYTE), 5123 (UNSIGNED_SHORT), 5125 (UNSIGNED_INT) + */ + componentType:glTFAccessorComponentType; + } + + + interface glTFAccessorSparseValues extends glTFNodeProperty { + + /** + * The index of the bufferView with sparse values. Referenced bufferView can't have ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target + */ + bufferView:number; + + /** + * The offset relative to the start of the bufferView in bytes. Must be aligned + */ + byteOffset?:number; + } + + + interface glTFAccessorSparse extends glTFNodeProperty { + + /** + * Number of entries stored in the sparse array. + */ + count:number; + + /** + * Index array of size count that points to those accessor attributes that deviate from their initialization value. Indices must strictly increase + */ + indices:glTFAccessorSparseIndeces; + + /** + * Array of size count times number of components, storing the displaced accessor attributes pointed by indices. Substituted values must have the same componentType and number of components as the base accessor + */ + values:glTFAccessorSparseValues; + } + + + interface glTFAccessor extends glTFNodeProperty { + + /** + * The index of the bufferView. + */ + bufferView?:number; + + /** + * The offset relative to the start of the bufferView in bytes. + */ + byteOffset?:number; + + /** + * The datatype of components in the attribute. + */ + componentType:glTFAccessorComponentType; + + /** + * Specifies whether integer data values should be normalized. + */ + normalized?:boolean; + + /** + * The number of attributes referenced by this accessor. + */ + count:number; + + /** + * Specifies if the attribute is a scalar, vector, or matrix. + */ + type:glTFAccessorType; + + /** + * Maximum value of each component in this attribute. + */ + max?:number[]; + + /** + * Minimum value of each component in this attribute. + */ + min?:number[]; + + /** + * Sparse storage of attributes that deviate from their initialization value. + */ + sparse?:glTFAccessorSparse; + } + + + interface glTFAnimationChannelTarget extends glTFNodeProperty { + + /** + * The index of the node to target + */ + node:number; + + /** + * The name of the node's TRS property to modify, or the weights of the Morph Targets it instantiates + */ + path:glTFAnimationChannelTargetPath; + } + + + interface glTFAnimationChannel extends glTFNodeProperty { + + /** + * * The index of a sampler in this animation used to compute the value for the target + */ + sampler:number; + + /** + * * The index of the node and TRS property to target + */ + target:glTFAnimationChannelTarget; + } + + + interface glTFAnimationSampler extends glTFNodeProperty { + + /** + * The index of an accessor containing keyframe input values, e.g., time + */ + input:number; + + /** + * Interpolation algorithm + */ + interpolation?:glTFAnimationSamplerInterpolation; + + /** + * The index of an accessor, containing keyframe output values + */ + output:number; + } + + + interface glTFAnimation extends glTFNodeProperty,glTFChildNodeProperty { + + /** + * An array of channels, each of which targets an animation's sampler at a node's property + */ + channels:glTFAnimationChannel[]; + + /** + * An array of samplers that combines input and output accessors with an interpolation algorithm to define a keyframe graph (but not its target) + */ + samplers:glTFAnimationSampler[]; + } + + + interface glTFAsset extends glTFChildNodeProperty { + + /** + * A copyright message suitable for display to credit the content creator. + */ + copyright?:string; + + /** + * Tool that generated this glTF model. Useful for debugging. + */ + generator?:string; + + /** + * The glTF version that this asset targets. + */ + version:string; + + /** + * The minimum glTF version that this asset targets. + */ + minVersion?:string; + } + + + interface glTFBuffer extends glTFChildNodeProperty,glTFNodeProperty { + + /** + * The uri of the buffer. Relative paths are relative to the .gltf file. Instead of referencing an external file, the uri can also be a data-uri + */ + uri?:string; + + /** + * The length of the buffer in bytes + */ + byteLength:number; + } + + + interface glTFBufferView extends glTFChildNodeProperty,glTFNodeProperty { + + /** + * The index of the buffer + */ + buffer:number; + + /** + * The offset into the buffer in bytes + */ + byteOffset?:number; + + /** + * The lenth of the bufferView in bytes + */ + byteLength:number; + + /** + * The stride, in bytes + */ + byteStride?:number; + } + + + interface glTFCameraOrthographic extends glTFNodeProperty { + + /** + * The floating-point horizontal magnification of the view. Must not be zero + */ + xmag:number; + + /** + * The floating-point vertical magnification of the view. Must not be zero + */ + ymag:number; + + /** + * The floating-point distance to the far clipping plane. zfar must be greater than znear + */ + zfar:number; + + /** + * The floating-point distance to the near clipping plane + */ + znear:number; + } + + + interface glTFCameraPerspective extends glTFNodeProperty { + + /** + * The floating-point aspect ratio of the field of view + */ + aspectRatio?:number; + + /** + * The floating-point vertical field of view in radians + */ + yfov:number; + + /** + * The floating-point distance to the far clipping plane + */ + zfar?:number; + + /** + * The floating-point distance to the near clipping plane + */ + znear:number; + } + + + interface glTFCamera extends glTFChildNodeProperty,glTFNodeProperty { + + /** + * An orthographic camera containing properties to create an orthographic projection matrix + */ + orthographic?:glTFCameraOrthographic; + + /** + * A perspective camera containing properties to create a perspective projection matrix + */ + perspective?:glTFCameraPerspective; + + /** + * Specifies if the camera uses a perspective or orthographic projection + */ + type:glTFCameraType; + } + + + interface glTFImage extends glTFChildNodeProperty,glTFNodeProperty { + + /** + * The uri of the image. Relative paths are relative to the .gltf file. Instead of referencing an external file, the uri can also be a data-uri. The image format must be jpg or png + */ + uri?:string; + + /** + * The image's MIME type + */ + mimeType?:glTFImageMimeType; + + /** + * The index of the bufferView that contains the image. Use this instead of the image's uri property + */ + bufferView?:number; + } + + + interface glTFTextureInfo extends glTFNodeProperty { + + /** + * The index of the texture + */ + index:number; + + /** + * The set index of texture's TEXCOORD attribute used for texture coordinate mapping + */ + texCoord?:number; + } + + + interface glTFMaterialPbrMetallicRoughness extends glTFNodeProperty { + + /** + * The material's base color factor + */ + baseColorFactor?:number[]; + + /** + * The base color texture + */ + baseColorTexture?:glTFTextureInfo; + + /** + * The metalness of the material + */ + metallicFactor?:number; + + /** + * The roughness of the material + */ + roughnessFactor?:number; + + /** + * The metallic-roughness texture + */ + metallicRoughnessTexture?:glTFTextureInfo; + } + + + interface glTFMaterialNormalTextureInfo extends glTFTextureInfo { + + /** + * The scalar multiplier applied to each normal vector of the normal texture + */ + scale?:number; + } + + + interface glTFMaterialOcclusionTextureInfo extends glTFTextureInfo { + + /** + * A scalar multiplier controlling the amount of occlusion applied + */ + strength?:number; + } + + + interface glTFMaterial extends glTFChildNodeProperty,glTFNodeProperty { + + /** + * A set of parameter values that are used to define the metallic-roughness material model from Physically-Based Rendering (PBR) methodology. When not specified, all the default values of pbrMetallicRoughness apply + */ + pbrMetallicRoughness?:glTFMaterialPbrMetallicRoughness; + + /** + * The normal map texture + */ + normalTexture?:glTFMaterialNormalTextureInfo; + + /** + * The occlusion map texture + */ + occlusionTexture?:glTFMaterialOcclusionTextureInfo; + + /** + * The emissive map texture + */ + emissiveTexture?:glTFTextureInfo; + + /** + * The RGB components of the emissive color of the material. These values are linear. If an emissiveTexture is specified, this value is multiplied with the texel values + */ + emissiveFactor?:number[]; + + /** + * The alpha rendering mode of the material + */ + alphaMode?:glTFMaterialAlphaMode; + + /** + * The alpha cutoff value of the material + */ + alphaCutoff?:number; + + /** + * Specifies whether the material is double sided + */ + doubleSided?:boolean; + } + + + interface glTFMeshPrimitive extends glTFNodeProperty { + + /** + * A dictionary object, where each key corresponds to mesh attribute semantic and each value is the index of the accessor containing attribute's data + */ + attributes:{[key:string]:number;}; + + /** + * The index of the accessor that contains the indices + */ + indices?:number; + + /** + * The index of the material to apply to this primitive when rendering + */ + material?:number; + + /** + * The type of primitives to render. All valid values correspond to WebGL enums + */ + mode?:glTFMeshPrimitiveMode; + + /** + * An array of Morph Targets, each Morph Target is a dictionary mapping attributes (only POSITION, NORMAL, and TANGENT supported) to their deviations in the Morph Target + */ + targets?:{ + [name: string]: number; + }[]; + } + + + interface glTFMesh extends glTFChildNodeProperty,glTFNodeProperty { + + /** + * An array of primitives, each defining geometry to be rendered with a material + */ + primitives:glTFMeshPrimitive[]; + + /** + * Array of weights to be applied to the Morph Targets + */ + weights?:number[]; + } + + + interface glTFNode extends glTFChildNodeProperty,glTFNodeProperty { + + /** + * The index of the camera referenced by this node + */ + camera?:number; + + /** + * The indices of this node's children + */ + children?:number[]; + + /** + * The index of the skin referenced by this node + */ + skin?:number; + + /** + * A floating-point 4x4 transformation matrix stored in column-major order + */ + matrix?:number[]; + + /** + * The index of the mesh in this node + */ + mesh?:number; + + /** + * The node's unit quaternion rotation in the order (x, y, z, w), where w is the scalar + */ + rotation?:number[]; + + /** + * The node's non-uniform scale, given as the scaling factors along the x, y, and z axes + */ + scale?:number[]; + + /** + * The node's translation along the x, y, and z axes + */ + translation?:number[]; + + /** + * The weights of the instantiated Morph Target. Number of elements must match number of Morph Targets of used mesh + */ + weights?:number[]; + } + + + interface glTFSampler extends glTFChildNodeProperty,glTFNodeProperty { + + /** + * Magnification filter. Valid values correspond to WebGL enums: 9728 (NEAREST) and 9729 (LINEAR) + */ + magFilter?:glTFTextureMagFilter; + + /** + * Minification filter. All valid values correspond to WebGL enums + */ + minFilter?:glTFTextureMinFilter; + + /** + * S (U) wrapping mode. All valid values correspond to WebGL enums + */ + wrapS?:glTFTextureWrapMode; + + /** + * T (V) wrapping mode. All valid values correspond to WebGL enums + */ + wrapT?:glTFTextureWrapMode; + } + + + interface glTFScene extends glTFChildNodeProperty,glTFNodeProperty { + + /** + * The indices of each root node + */ + nodes:number[]; + } + + + interface glTFSkin extends glTFChildNodeProperty,glTFNodeProperty { + + /** + * The index of the accessor containing the floating-point 4x4 inverse-bind matrices. The default is that each matrix is a 4x4 identity matrix, which implies that inverse-bind matrices were pre-applied + */ + inverseBindMatrices?:number; + + /** + * The index of the node used as a skeleton root. When undefined, joints transforms resolve to scene root + */ + skeleton?:number; + + /** + * Indices of skeleton nodes, used as joints in this skin. The array length must be the same as the count property of the inverseBindMatrices accessor (when defined) + */ + joints:number[]; + } + + + interface glTFTexture extends glTFChildNodeProperty,glTFNodeProperty { + + /** + * The index of the sampler used by this texture. When undefined, a sampler with repeat wrapping and auto filtering should be used + */ + sampler?:number; + + /** + * The index of the image used by this texture + */ + source:number; + } + + + interface glTF extends glTFNodeProperty { + + /** + * An array of accessors. An accessor is a typed view into a bufferView + */ + accessors?:glTFAccessor[]; + + /** + * An array of keyframe animations + */ + animations?:glTFAnimation[]; + + /** + * Metadata about the glTF asset + */ + asset:glTFAsset; + + /** + * An array of buffers. A buffer points to binary geometry, animation, or skins + */ + buffers?:glTFBuffer[]; + + /** + * An array of bufferViews. A bufferView is a view into a buffer generally representing a subset of the buffer + */ + bufferViews?:glTFBufferView[]; + + /** + * An array of cameras + */ + cameras?:glTFCamera[]; + + /** + * Names of glTF extensions used somewhere in this asset + */ + extensionsUsed?:string[]; + + /** + * Names of glTF extensions required to properly load this asset + */ + extensionsRequired?:string[]; + + /** + * An array of images. An image defines data used to create a texture + */ + images?:glTFImage[]; + + /** + * An array of materials. A material defines the appearance of a primitive + */ + materials?:glTFMaterial[]; + + /** + * An array of meshes. A mesh is a set of primitives to be rendered + */ + meshes?:glTFMesh[]; + + /** + * An array of nodes + */ + nodes?:glTFNode[]; + + /** + * An array of samplers. A sampler contains properties for texture filtering and wrapping modes + */ + samplers?:glTFSampler[]; + + /** + * The index of the default scene + */ + scene?:number; + + /** + * An array of scenes + */ + scenes?:glTFScene[]; + + /** + * An array of skins. A skin is defined by joints and matrices + */ + skins?:glTFSkin[]; + + /** + * An array of textures + */ + textures?:glTFTexture[]; + } + + + /** + * glTFLoader 类可用来加载 gltf 2.0 文件 + */ + class glTFLoader { + + /** + * glTF 资源 + */ + static GLTF:string; + + /** + * glTF base64 Texture + */ + static GLTFBASE64TEX:string; + + /** + * 初始化 glTF Loader + */ + static init():void; + } + + /** + * glTFUtils 用于解析 glTF 2.0 对象 + */ + class glTFUtils { + static Extensions:{[key:string]:Handler;}; + + /** + * 保存 extra 处理函数对象 + */ + static Extras:{[key:string]:{[key:string]:Handler;};}; + + /** + * 注册 extra 处理函数 + * @param context + * @param extraName + * @param handler + */ + static RegisterExtra(context:string,extraName:string,handler:Handler):void; + + /** + * 取消注册 extra 处理函数 + * @param context + * @param extraName + * @param recoverHandler + */ + static UnRegisterExtra(context:string,extraName:string,recoverHandler?:boolean):void; + + /** + * 根据数据类型获取分量 + * @param type + */ + static getAccessorComponentsNum(type:glTFAccessorType):number; + + /** + * 获取 attribute 分量 + * @param attriStr + */ + static getAttributeNum(attriStr:string):number; + + /** + * 获取 accessor buffer 数据 + * @param accessorIndex + */ + static getBufferwithAccessorIndex(accessorIndex:number):Float32Array|Int16Array|Uint8Array|Uint32Array|Uint16Array|Int8Array; + + /** + * 判断 Texture 是否需要 mipmap + * @param glTFImage + * @param glTFSampler + */ + static getTextureMipmap(glTFSampler:glTFSampler):boolean; + + /** + * 获取 Texture format + * @param glTFImage + */ + static getTextureFormat(glTFImage:glTFImage):number; + + /** + * 获取 Texture filter mode + * @param glTFSampler + */ + static getTextureFilterMode(glTFSampler:glTFSampler):number; + + /** + * 获取 Texture warp mode + * @param mode + */ + static getTextureWrapMode(mode:glTFTextureWrapMode):number; + + /** + * 获取 Texture 初始化参数 + * @param glTFImage + * @param glTFSampler + */ + static getTextureConstructParams(glTFImage:glTFImage,glTFSampler:glTFSampler):any[]; + + /** + * 获取 Texture 属性参数 + * @param glTFImage + * @param glTFSampler + */ + static getTexturePropertyParams(glTFSampler:glTFSampler):any; + + /** + * 根据 glTFTextureInfo 获取 Texture2D + * @param glTFTextureInfo + */ + static getTexturewithInfo(glTFTextureInfo:glTFTextureInfo):Texture2D; + + /** + * 根据 glTFMaterial 节点数据创建 default Material + * @param glTFMaterial + */ + static _createdefaultMaterial(glTFMaterial:glTFMaterial):PBRStandardMaterial; + + /** + * 应用 pbrMetallicRoughness 数据 + * @param pbrMetallicRoughness + * @param layaPBRMaterial + */ + static applyPBRMetallicRoughness(pbrMetallicRoughness:glTFMaterialPbrMetallicRoughness,layaPBRMaterial:PBRStandardMaterial):void; + + /** + * 获取 gltf mesh 中 material + * @param glTFMesh + */ + static pickMeshMaterials(glTFMesh:glTFMesh):Material[]; + + /** + * 创建 glTFScene 节点 + * @param glTFScene + */ + static _createSceneNode(glTFScene:glTFScene):Sprite3D; + + /** + * 应用 Transform 信息 + * @param glTFNode + * @param sprite + */ + static applyTransform(glTFNode:glTFNode,sprite:Sprite3D):void; + + /** + * 创建 节点对象 + * @param glTFNode + */ + static _createSprite3D(glTFNode:glTFNode):Sprite3D; + + /** + * 创建 MeshSprite3D 对象 + * @param glTFNode + */ + static _createMeshSprite3D(glTFNode:glTFNode):MeshSprite3D; + + /** + * 创建 MeshSprite3D 对象 + * @param glTFNode + */ + static _createSkinnedMeshSprite3D(glTFNode:glTFNode):SkinnedMeshSprite3D; + + /** + * 创建 Mesh + * @param mesh + */ + static _createMesh(glTFMesh:glTFMesh,glTFSkin?:glTFSkin):Mesh; + + /** + * 计算 SkinnedMeshSprite3D local bounds + * @param skinned + */ + static calSkinnedSpriteLocalBounds(skinned:SkinnedMeshSprite3D):void; + + /** + * @interna 获取 Animator 根节点 + */ + static getAnimationRoot(channels:glTFAnimationChannel[]):Sprite3D; + } + + /** + * HTML图文类,用于显示html内容 + * + * 支持的标签如下: + * a:链接标签,点击后会派发"link"事件 比如:
    a + * div:div容器标签,比如:
    abc
    + * span:行内元素标签,比如:abc + * p:行元素标签,p标签会自动换行,div不会,比如:

    abc

    + * img:图片标签,比如: + * br:换行标签,比如:
    abc
    def
    + * style:样式标签,比如:
    abc
    + * link:外链样式标签,可以加载一个css文件来当style使用,比如: + * + * style支持的属性如下: + * italic:true|false; 是否是斜体 + * bold:true|false; 是否是粗体 + * letter-spacing:10px; 字间距 + * font-family:宋体; 字体 + * font-size:20px; 字体大小 + * font-weight:bold:none; 字体是否是粗体,功能同bold + * color:#ff0000; 字体颜色 + * stroke:2px; 字体描边宽度 + * strokeColor:#ff0000; 字体描边颜色 + * padding:10px 10px 20px 20px; 边缘的距离 + * vertical-align:top|bottom|middle; 垂直对齐方式 + * align:left|right|center; 水平对齐方式 + * line-height:20px; 行高 + * background-color:#ff0000; 背景颜色 + * border-color:#ff0000; 边框颜色 + * width:100px; 对象宽度 + * height:100px; 对象高度 + * + * 示例用法: + * var div:HTMLDivElement=new HTMLDivElement(); + * div.innerHTML = "a
    div

    spanspan2

    p

    "; + */ + class HTMLDivElement extends Sprite { + + /** + * @private + */ + private _recList:any; + + /** + * @private + */ + private _innerHTML:any; + + /** + * @private + */ + private _repaintState:any; + + constructor(); + + /** + * @private + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * @private + */ + private _htmlDivRepaint:any; + private _updateGraphicWork:any; + private _setGraphicDirty:any; + + /** + * @private + */ + private _doClears:any; + + /** + * @private + */ + private _updateGraphic:any; + + /** + * 获取HTML样式 + */ + get style():HTMLStyle; + + /** + * 设置标签内容 + */ + set innerHTML(text:string); + private _refresh:any; + set width(value:number); + get width():number; + set height(value:number); + get height():number; + + /** + * 获取內容宽度 + */ + get contextWidth():number; + + /** + * 获取內容高度 + */ + get contextHeight():number; + + /** + * @private + */ + private _onMouseClick:any; + + /** + * @private + */ + private _eventLink:any; + } + + /** + * @private + */ + class HTMLDivParser extends HTMLElement { + + /** + * 实际内容的高 + */ + contextHeight:number; + + /** + * 实际内容的宽 + */ + contextWidth:number; + + /** + * @private + */ + private _htmlBounds:any; + + /** + * @private + */ + private _boundsRec:any; + + /** + * 重绘回调 + */ + repaintHandler:Handler; + + /** + * @override + */ + reset():HTMLElement; + + /** + * 设置标签内容 + */ + set innerHTML(text:string); + + /** + * @override + */ + set width(value:number); + + /** + * 追加内容,解析并对显示对象排版 + * @param text + */ + appendHTML(text:string):void; + + /** + * 获取bounds + * @return + */ + getBounds():Rectangle; + + /** + * @override + */ + parentRepaint(recreate?:boolean):void; + + /** + * @private 对显示内容进行排版 + */ + layout():void; + + /** + * 获取对象的高 + * @override + */ + get height():number; + + /** + * @override + */ + set height(value:number); + + /** + * 获取对象的宽 + * @override + */ + get width():number; + } + + /** + * @private + */ + class HTMLDocument { + static document:HTMLDocument; + all:{[key:string]:HTMLElement;}; + styleSheets:any; + getElementById(id:string):HTMLElement; + setElementById(id:string,e:HTMLElement):void; + } + +enum HTMLElementType { + /**基础类型 */ + BASE = 0, + /**图片类型 */ + IMAGE = 1 +} + + /** + * @private + */ + class HTMLElement { + private static _EMPTYTEXT:any; + eletype:HTMLElementType; + URI:URL; + parent:HTMLElement; + _style:HTMLStyle; + protected _text:any; + protected _children:any[]; + protected _x:number; + protected _y:number; + protected _width:number; + protected _height:number; + + /** + * 格式化指定的地址并返回。 + * @param url 地址。 + * @param base 基础路径,如果没有,则使用basePath。 + * @return 格式化处理后的地址。 + */ + static formatURL1(url:string,basePath?:string):string; + + constructor(); + protected _creates():void; + + /** + * 重置 + */ + reset():HTMLElement; + set id(value:string); + repaint(recreate?:boolean):void; + parentRepaint(recreate?:boolean):void; + set innerTEXT(value:string); + get innerTEXT():string; + protected _setParent(value:HTMLElement):void; + appendChild(c:HTMLElement):HTMLElement; + addChild(c:HTMLElement):HTMLElement; + removeChild(c:HTMLElement):HTMLElement; + static getClassName(tar:any):string; + + /** + *

    销毁此对象。destroy对象默认会把自己从父节点移除,并且清理自身引用关系,等待js自动垃圾回收机制回收。destroy后不能再使用。

    + *

    destroy时会移除自身的事情监听,自身的timer监听,移除子对象及从父节点移除自己。

    + * @param destroyChild (可选)是否同时销毁子节点,若值为true,则销毁子节点,否则不销毁子节点。 + */ + destroy():void; + + /** + * 销毁所有子对象,不销毁自己本身。 + */ + destroyChildren():void; + get style():HTMLStyle; + set x(v:number); + get x():number; + set y(v:number); + get y():number; + get width():number; + set width(value:number); + get height():number; + set height(value:number); + set href(url:string); + get href():string; + formatURL(url:string):string; + set color(value:string); + set className(value:string); + drawToGraphic(graphic:Graphics,gX:number,gY:number,recList:any[]):void; + renderSelfToGraphic(graphic:Graphics,gX:number,gY:number,recList:any[]):void; + private workLines:any; + private createOneLine:any; + } + + /** + * @private + */ + class HTMLHitRect { + rec:Rectangle; + href:string; + + constructor(); + reset():HTMLHitRect; + recover():void; + static create():HTMLHitRect; + } + + /** + * iframe标签类,目前用于加载外并解析数据 + */ + class HTMLIframeElement extends HTMLDivElement { + + constructor(); + + /** + * 加载html文件,并解析数据 + * @param url + */ + set href(url:string); + } + + /** + * @private + */ + class HTMLImageElement extends HTMLElement { + private _tex:any; + private _url:any; + + constructor(); + + /** + * @override + */ + reset():HTMLElement; + set src(url:string); + private onloaded:any; + + /** + * @param graphic + * @param gX + * @param gY + * @param recList + * @override + */ + renderSelfToGraphic(graphic:Graphics,gX:number,gY:number,recList:any[]):void; + } + + /** + * @private + */ + class HTMLLinkElement extends HTMLElement { + static _cuttingStyle:RegExp; + type:string; + private _loader:any; + + /** + * @override + */ + protected _creates():void; + + /** + * @param graphic + * @param gX + * @param gY + * @param recList + * @override + */ + drawToGraphic(graphic:Graphics,gX:number,gY:number,recList:any[]):void; + + /** + * @override + */ + reset():HTMLElement; + + /** + * @override + */ + set href(url:string); + + /** + * @override + */ + get href():string; + } + + /** + * @private + */ + class HTMLStyleElement extends HTMLElement { + + /** + * @override + */ + protected _creates():void; + + /** + * @param graphic + * @param gX + * @param gY + * @param recList + * @override + */ + drawToGraphic(graphic:Graphics,gX:number,gY:number,recList:any[]):void; + + /** + * @override + */ + reset():HTMLElement; + + /** + * 解析样式 + * @override + */ + set innerTEXT(value:string); + + /** + * @override + */ + get innerTEXT():string; + } + + /** + * @private + */ + class HTMLExtendStyle { + static EMPTY:HTMLExtendStyle; + + /** + *

    描边宽度(以像素为单位)。

    + * 默认值0,表示不描边。 + * @default 0 + */ + stroke:number; + + /** + *

    描边颜色,以字符串表示。

    + * @default "#000000"; + */ + strokeColor:string; + + /** + *

    垂直行间距(以像素为单位)

    + */ + leading:number; + + /** + * 行高。 + */ + lineHeight:number; + letterSpacing:number; + href:string; + + constructor(); + reset():HTMLExtendStyle; + recover():void; + + /** + * 从对象池中创建 + */ + static create():HTMLExtendStyle; + } + + /** + * @private + */ + class HTMLParse { + private static char255:any; + private static spacePattern:any; + private static char255AndOneSpacePattern:any; + private static _htmlClassMapShort:any; + + /** + * 根据类型获取对应的节点 + * @param type + */ + static getInstance(type:string):any; + + /** + * 解析HTML + * @param ower + * @param xmlString + * @param url + */ + static parse(ower:HTMLDivParser,xmlString:string,url:URL):void; + + /** + * 解析xml节点 该函数会被递归调用 + * @param xml + */ + private static _parseXML:any; + } + + /** + * @private + */ + class HTMLStyle { + private static _CSSTOVALUE:any; + private static _parseCSSRegExp:any; + + /** + * 需要继承的属性 + */ + private static _inheritProps:any; + + /** + * 水平居左对齐方式。 + */ + static ALIGN_LEFT:string; + + /** + * 水平居中对齐方式。 + */ + static ALIGN_CENTER:string; + + /** + * 水平居右对齐方式。 + */ + static ALIGN_RIGHT:string; + + /** + * 垂直居中对齐方式。 + */ + static VALIGN_TOP:string; + + /** + * 垂直居中对齐方式。 + */ + static VALIGN_MIDDLE:string; + + /** + * 垂直居底部对齐方式。 + */ + static VALIGN_BOTTOM:string; + + /** + * 样式表信息。 + */ + static styleSheets:any; + + /** + * 添加布局。 + */ + static ADDLAYOUTED:number; + private static _PADDING:any; + protected static _HEIGHT_SET:number; + protected static _LINE_ELEMENT:number; + protected static _NOWARP:number; + protected static _WIDTHAUTO:number; + protected static _BOLD:number; + protected static _ITALIC:number; + + /** + * @private + */ + protected static _CSS_BLOCK:number; + + /** + * @private + */ + protected static _DISPLAY_NONE:number; + + /** + * @private + */ + protected static _ABSOLUTE:number; + + /** + * @private + */ + protected static _WIDTH_SET:number; + protected static alignVDic:any; + protected static align_Value:any; + protected static vAlign_Value:any; + protected static _ALIGN:number; + protected static _VALIGN:number; + fontSize:number; + family:string; + color:string; + ower:HTMLElement; + private _extendStyle:any; + textDecoration:string; + + /** + * 文本背景颜色,以字符串表示。 + */ + bgColor:string; + + /** + * 文本边框背景颜色,以字符串表示。 + */ + borderColor:string; + + /** + * 边距信息。 + */ + padding:any[]; + + constructor(); + private _getExtendStyle:any; + get href():string; + set href(value:string); + + /** + *

    描边宽度(以像素为单位)。

    + * 默认值0,表示不描边。 + * @default 0 + */ + get stroke():number; + set stroke(value:number); + + /** + *

    描边颜色,以字符串表示。

    + * @default "#000000"; + */ + get strokeColor():string; + set strokeColor(value:string); + + /** + *

    垂直行间距(以像素为单位)

    + */ + get leading():number; + set leading(value:number); + + /** + * 行高。 + */ + get lineHeight():number; + set lineHeight(value:number); + set align(v:string); + + /** + *

    表示使用此文本格式的文本段落的水平对齐方式。

    + * @default "left" + */ + get align():string; + set valign(v:string); + + /** + *

    表示使用此文本格式的文本段落的水平对齐方式。

    + * @default "left" + */ + get valign():string; + + /** + * 字体样式字符串。 + */ + set font(value:string); + get font():string; + + /** + * 是否显示为块级元素。 + */ + set block(value:boolean); + + /** + * 表示元素是否显示为块级元素。 + */ + get block():boolean; + + /** + * 重置,方便下次复用 + */ + reset():HTMLStyle; + + /** + * 回收 + */ + recover():void; + + /** + * 从对象池中创建 + */ + static create():HTMLStyle; + + /** + * 复制传入的 CSSStyle 属性值。 + * @param src 待复制的 CSSStyle 对象。 + */ + inherit(src:HTMLStyle):void; + + /** + * 表示是否换行。 + */ + get wordWrap():boolean; + set wordWrap(value:boolean); + + /** + * 是否为粗体 + */ + get bold():boolean; + set bold(value:boolean); + get fontWeight():string; + set fontWeight(value:string); + + /** + * 表示使用此文本格式的文本是否为斜体。 + * @default false + */ + get italic():boolean; + set italic(value:boolean); + + /** + * @inheritDoc + */ + widthed(sprite:any):boolean; + set whiteSpace(type:string); + + /** + * 设置如何处理元素内的空白。 + */ + get whiteSpace():string; + + /** + * 宽度。 + */ + set width(w:any); + + /** + * 高度。 + */ + set height(h:any); + + /** + * 是否已设置高度。 + * @param sprite 显示对象 Sprite。 + * @return 一个Boolean 表示是否已设置高度。 + */ + heighted(sprite:any):boolean; + + /** + * 设置宽高。 + * @param w 宽度。 + * @param h 高度。 + */ + size(w:number,h:number):void; + + /** + * 是否是行元素。 + */ + getLineElement():boolean; + setLineElement(value:boolean):void; + + /** + * 间距。 + */ + get letterSpacing():number; + set letterSpacing(d:number); + + /** + * 设置 CSS 样式字符串。 + * @param text CSS样式字符串。 + */ + cssText(text:string):void; + + /** + * 根据传入的属性名、属性值列表,设置此对象的属性值。 + * @param attrs 属性名与属性值列表。 + */ + attrs(attrs:any[]):void; + set position(value:string); + + /** + * 元素的定位类型。 + */ + get position():string; + + /** + * @inheritDoc + */ + get absolute():boolean; + + /** + * @inheritDoc + */ + get paddingLeft():number; + + /** + * @inheritDoc + */ + get paddingTop():number; + + /** + * 通过传入的分割符,分割解析CSS样式字符串,返回样式列表。 + * @param text CSS样式字符串。 + * @param clipWord 分割符; + * @return 样式列表。 + */ + static parseOneCSS(text:string,clipWord:string):any[]; + + /** + * 解析 CSS 样式文本。 + * @param text CSS 样式文本。 + * @param uri URL对象。 + */ + static parseCSS(text:string,uri:URL):void; + } + + interface ILayout{ + x:number; + y:number; + width:number; + height:number; + } + + + /** + * @private HTML的布局类 对HTML的显示对象进行排版 + */ + class Layout { + private static DIV_ELEMENT_PADDING:any; + private static _will:any; + static later(element:HTMLElement):void; + static layout(element:HTMLElement):any[]; + static _multiLineLayout(element:HTMLElement):any[]; + } + + /** + * @private + */ + class LayoutLine { + elements:ILayout[]; + x:number; + y:number; + w:number; + h:number; + wordStartIndex:number; + minTextHeight:number; + mWidth:number; + + /** + * 底对齐(默认) + * @param left + * @param width + * @param dy + * @param align 水平 + * @param valign 垂直 + * @param lineHeight 行高 + */ + updatePos(left:number,width:number,lineNum:number,dy:number,align:string,valign:string,lineHeight:number):void; + } + + /** + * @private CommandEncoder + */ + class CommandEncoder { + + constructor(layagl:any,reserveSize:number,adjustSize:number,isSyncToRenderThread:boolean); + getArrayData():any[]; + getPtrID():number; + beginEncoding():void; + endEncoding():void; + clearEncoding():void; + getCount():number; + add_ShaderValue(o:any):void; + addShaderUniform(one:any):void; + } + + /** + * ... + * @author ww + */ + class QuickTestTool { + private static showedDic:any; + private static _rendertypeToStrDic:any; + private static _typeToNameDic:any; + static getMCDName(type:number):string; + static showRenderTypeInfo(type:any,force?:boolean):void; + static __init__():void; + _renderType:number; + _repaint:number; + _x:number; + _y:number; + + constructor(); + + /** + * 更新、呈现显示对象。由系统调用。 + * @param context 渲染的上下文引用。 + * @param x X轴坐标。 + * @param y Y轴坐标。 + */ + render(context:Context,x:number,y:number):void; + private static _PreStageRender:any; + private static _countDic:any; + private static _countStart:any; + private static _i:any; + private static _countEnd:any; + static showCountInfo():void; + static enableQuickTest():void; + } + + /** + * 地图的每层都会分块渲染处理 + * 本类就是地图的块数据 + * @author ... + */ + class GridSprite extends Sprite { + + /** + * 相对于地图X轴的坐标 + */ + relativeX:number; + + /** + * 相对于地图Y轴的坐标 + */ + relativeY:number; + + /** + * 是否用于对象层的独立物件 + */ + isAloneObject:boolean; + + /** + * 当前GRID中是否有动画 + */ + isHaveAnimation:boolean; + + /** + * 当前GRID包含的动画 + */ + aniSpriteArray:any[]; + + /** + * 当前GRID包含多少个TILE(包含动画) + */ + drawImageNum:number; + private _map:any; + + /** + * 传入必要的参数,用于裁剪,跟确认此对象类型 + * @param map 把地图的引用传进来,参与一些裁剪计算 + * @param objectKey true:表示当前GridSprite是个活动对象,可以控制,false:地图层的组成块 + */ + initData(map:TiledMap,objectKey?:boolean):void; + + /** + * 把一个动画对象绑定到当前GridSprite + * @param sprite 动画的显示对象 + */ + addAniSprite(sprite:TileAniSprite):void; + + /** + * 显示当前GridSprite,并把上面的动画全部显示 + */ + show():void; + + /** + * 隐藏当前GridSprite,并把上面绑定的动画全部移除 + */ + hide():void; + + /** + * 刷新坐标,当我们自己控制一个GridSprite移动时,需要调用此函数,手动刷新 + */ + updatePos():void; + + /** + * 重置当前对象的所有属性 + */ + clearAll():void; + } + + /** + * 地图支持多层渲染(例如,地表层,植被层,建筑层等) + * 本类就是层级类 + * @author ... + */ + class MapLayer extends Sprite { + private _map:any; + private _tileWidthHalf:any; + private _tileHeightHalf:any; + private _mapWidthHalf:any; + private _mapHeightHalf:any; + private _objDic:any; + private _dataDic:any; + private _tempMapPos:any; + private _properties:any; + + /** + * 被合到的层 + */ + tarLayer:MapLayer; + + /** + * 当前Layer的名称 + */ + layerName:string; + + /** + * 解析LAYER数据,以及初始化一些数据 + * @param layerData 地图数据中,layer数据的引用 + * @param map 地图的引用 + */ + init(layerData:any,map:TiledMap):void; + + /** + * ****************************************对外接口******************************************** + */ + + /** + * 通过名字获取控制对象,如果找不到返回为null + * @param objName 所要获取对象的名字 + * @return + */ + getObjectByName(objName:string):GridSprite; + + /** + * 通过名字获取数据,如果找不到返回为null + * @param objName 所要获取对象的名字 + * @return + */ + getObjectDataByName(objName:string):any; + + /** + * 得到地图层的自定义属性 + * @param name + * @return + */ + getLayerProperties(name:string):any; + + /** + * 得到指定格子的数据 + * @param tileX 格子坐标X + * @param tileY 格子坐标Y + * @return + */ + getTileData(tileX:number,tileY:number):number; + + /** + * 通过地图坐标得到屏幕坐标 + * @param tileX 格子坐标X + * @param tileY 格子坐标Y + * @param screenPos 把计算好的屏幕坐标数据,放到此对象中 + */ + getScreenPositionByTilePos(tileX:number,tileY:number,screenPos?:Point):void; + + /** + * 通过屏幕坐标来获取选中格子的数据 + * @param screenX 屏幕坐标x + * @param screenY 屏幕坐标y + * @return + */ + getTileDataByScreenPos(screenX:number,screenY:number):number; + + /** + * 通过屏幕坐标来获取选中格子的索引 + * @param screenX 屏幕坐标x + * @param screenY 屏幕坐标y + * @param result 把计算好的格子坐标,放到此对象中 + * @return + */ + getTilePositionByScreenPos(screenX:number,screenY:number,result?:Point):boolean; + + /** + * ******************************************************************************************** + */ + + /** + * 得到一个GridSprite + * @param gridX 当前Grid的X轴索引 + * @param gridY 当前Grid的Y轴索引 + * @return 一个GridSprite对象 + */ + getDrawSprite(gridX:number,gridY:number):GridSprite; + + /** + * 更新此层中块的坐标 + * 手动刷新的目的是,保持层级的宽和高保持最小,加快渲染 + */ + updateGridPos():void; + + /** + * @private 把tile画到指定的显示对象上 + * @param gridSprite 被指定显示的目标 + * @param tileX 格子的X轴坐标 + * @param tileY 格子的Y轴坐标 + * @return + */ + drawTileTexture(gridSprite:GridSprite,tileX:number,tileY:number):boolean; + + /** + * @private 清理当前对象 + */ + clearAll():void; + } + + /** + * TildMap的动画显示对象(一个动画(TileTexSet),可以绑定多个动画显示对象(TileAniSprite)) + * @author ... + */ + class TileAniSprite extends Sprite { + private _tileTextureSet:any; + private _aniName:any; + + /** + * 确定当前显示对象的名称以及属于哪个动画 + * @param aniName 当前动画显示对象的名字,名字唯一 + * @param tileTextureSet 当前显示对象属于哪个动画(一个动画,可以绑定多个同类显示对象) + */ + setTileTextureSet(aniName:string,tileTextureSet:TileTexSet):void; + + /** + * 把当前动画加入到对应的动画刷新列表中 + */ + show():void; + + /** + * 把当前动画从对应的动画刷新列表中移除 + */ + hide():void; + + /** + * 清理 + */ + clearAll():void; + } + + /** + * tiledMap是整个地图的核心 + * 地图以层级来划分地图(例如:地表层,植被层,建筑层) + * 每层又以分块(GridSprite)来处理显示对象,只显示在视口区域的区 + * 每块又包括N*N个格子(tile) + * 格子类型又分为动画格子跟图片格子两种 + * @author ... + */ + class TiledMap { + + /** + * 四边形地图 + */ + static ORIENTATION_ORTHOGONAL:string; + + /** + * 菱形地图 + */ + static ORIENTATION_ISOMETRIC:string; + + /** + * 45度交错地图 + */ + static ORIENTATION_STAGGERED:string; + + /** + * 六边形地图 + */ + static ORIENTATION_HEXAGONAL:string; + + /** + * 地图格子从左上角开始渲染 + */ + static RENDERORDER_RIGHTDOWN:string; + + /** + * 地图格子从左下角开始渲染 + */ + static RENDERORDER_RIGHTUP:string; + + /** + * 地图格子从右上角开始渲染 + */ + static RENDERORDER_LEFTDOWN:string; + + /** + * 地图格子右下角开始渲染 + */ + static RENDERORDER_LEFTUP:string; + private _jsonData:any; + private _tileTexSetArr:any; + private _texArray:any; + private _x:any; + private _y:any; + private _width:any; + private _height:any; + private _mapW:any; + private _mapH:any; + private _mapTileW:any; + private _mapTileH:any; + private _rect:any; + private _paddingRect:any; + private _mapSprite:any; + private _layerArray:any; + private _renderLayerArray:any; + private _gridArray:any; + private _showGridKey:any; + private _totalGridNum:any; + private _gridW:any; + private _gridH:any; + private _gridWidth:any; + private _gridHeight:any; + private _jsonLoader:any; + private _loader:any; + private _tileSetArray:any; + private _currTileSet:any; + private _completeHandler:any; + private _mapRect:any; + private _mapLastRect:any; + private _index:any; + private _animationDic:any; + private _properties:any; + private _tileProperties:any; + private _tileProperties2:any; + private _orientation:any; + private _renderOrder:any; + private _colorArray:any; + private _scale:any; + private _pivotScaleX:any; + private _pivotScaleY:any; + private _centerX:any; + private _centerY:any; + private _viewPortWidth:any; + private _viewPortHeight:any; + private _enableLinear:any; + private _resPath:any; + private _pathArray:any; + private _limitRange:any; + + /** + * 是否自动缓存没有动画的地块 + */ + autoCache:boolean; + + /** + * 自动缓存类型,地图较大时建议使用normal + */ + autoCacheType:string; + + /** + * 是否合并图层,开启合并图层时,图层属性内可添加layer属性,运行时将会将相邻的layer属性相同的图层进行合并以提高性能 + */ + enableMergeLayer:boolean; + + /** + * 是否移除被覆盖的格子,地块可添加type属性,type不为0时表示不透明,被不透明地块遮挡的地块将会被剔除以提高性能 + */ + removeCoveredTile:boolean; + + /** + * 是否显示大格子里显示的贴图数量 + */ + showGridTextureCount:boolean; + + /** + * 是否调整地块边缘消除缩放导致的缝隙 + */ + antiCrack:boolean; + + /** + * 是否在加载完成之后cache所有大格子 + */ + cacheAllAfterInit:boolean; + + constructor(); + + /** + * 创建地图 + * @param mapName JSON文件名字 + * @param viewRect 视口区域 + * @param completeHandler 地图创建完成的回调函数 + * @param viewRectPadding 视口扩充区域,把视口区域上、下、左、右扩充一下,防止视口移动时的穿帮 + * @param gridSize grid大小 + * @param enableLinear 是否开启线性取样(为false时,可以解决地图黑线的问题,但画质会锐化) + * @param limitRange 把地图限制在显示区域 + */ + createMap(mapName:string,viewRect:Rectangle,completeHandler:Handler,viewRectPadding?:Rectangle,gridSize?:Point,enableLinear?:boolean,limitRange?:boolean):void; + + /** + * json文件读取成功后,解析里面的纹理数据,进行加载 + * @param e JSON数据 + */ + private onJsonComplete:any; + + /** + * 合并路径 + * @param resPath + * @param relativePath + * @return + */ + private mergePath:any; + private _texutreStartDic:any; + + /** + * 纹理加载完成,如果所有的纹理加载,开始初始化地图 + * @param e 纹理数据 + */ + private onTextureComplete:any; + private adptTexture:any; + + /** + * 初始化地图 + */ + private initMap:any; + private addTileProperties:any; + getTileUserData(id:number,sign:string,defaultV?:any):any; + private adptTiledMapData:any; + private removeCoverd:any; + private collectCovers:any; + + /** + * 得到一块指定的地图纹理 + * @param index 纹理的索引值,默认从1开始 + * @return + */ + getTexture(index:number):TileTexSet; + + /** + * 得到地图的自定义属性 + * @param name 属性名称 + * @return + */ + getMapProperties(name:string):any; + + /** + * 得到tile自定义属性 + * @param index 地图块索引 + * @param id 具体的TileSetID + * @param name 属性名称 + * @return + */ + getTileProperties(index:number,id:number,name:string):any; + + /** + * 通过纹理索引,生成一个可控制物件 + * @param index 纹理的索引值,默认从1开始 + * @return + */ + getSprite(index:number,width:number,height:number):GridSprite; + + /** + * 设置视口的缩放中心点(例如:scaleX= scaleY= 0.5,就是以视口中心缩放) + * @param scaleX + * @param scaleY + */ + setViewPortPivotByScale(scaleX:number,scaleY:number):void; + + /** + * 设置地图缩放 + * @param scale + */ + set scale(scale:number); + + /** + * 得到当前地图的缩放 + */ + get scale():number; + + /** + * 移动视口 + * @param moveX 视口的坐标x + * @param moveY 视口的坐标y + */ + moveViewPort(moveX:number,moveY:number):void; + + /** + * 改变视口大小 + * @param moveX 视口的坐标x + * @param moveY 视口的坐标y + * @param width 视口的宽 + * @param height 视口的高 + */ + changeViewPort(moveX:number,moveY:number,width:number,height:number):void; + + /** + * 在锚点的基础上计算,通过宽和高,重新计算视口 + * @param width 新视口宽 + * @param height 新视口高 + * @param rect 返回的结果 + * @return + */ + changeViewPortBySize(width:number,height:number,rect?:Rectangle):Rectangle; + + /** + * 刷新视口 + */ + private updateViewPort:any; + + /** + * GRID裁剪 + */ + private clipViewPort:any; + + /** + * 显示指定的GRID + * @param gridX + * @param gridY + */ + private showGrid:any; + private cacheAllGrid:any; + private static _tempCanvas:any; + private cacheGridsArray:any; + private getGridArray:any; + + /** + * 隐藏指定的GRID + * @param gridX + * @param gridY + */ + private hideGrid:any; + + /** + * 得到对象层上的某一个物品 + * @param layerName 层的名称 + * @param objectName 所找物品的名称 + * @return + */ + getLayerObject(layerName:string,objectName:string):GridSprite; + + /** + * 销毁地图 + */ + destroy():void; + + /** + * **************************地图的基本数据************************** + */ + + /** + * 格子的宽度 + */ + get tileWidth():number; + + /** + * 格子的高度 + */ + get tileHeight():number; + + /** + * 地图的宽度 + */ + get width():number; + + /** + * 地图的高度 + */ + get height():number; + + /** + * 地图横向的格子数 + */ + get numColumnsTile():number; + + /** + * 地图竖向的格子数 + */ + get numRowsTile():number; + + /** + * @private 视口x坐标 + */ + get viewPortX():number; + + /** + * @private 视口的y坐标 + */ + get viewPortY():number; + + /** + * @private 视口的宽度 + */ + get viewPortWidth():number; + + /** + * @private 视口的高度 + */ + get viewPortHeight():number; + + /** + * 地图的x坐标 + */ + get x():number; + + /** + * 地图的y坐标 + */ + get y():number; + + /** + * 块的宽度 + */ + get gridWidth():number; + + /** + * 块的高度 + */ + get gridHeight():number; + + /** + * 地图的横向块数 + */ + get numColumnsGrid():number; + + /** + * 地图的坚向块数 + */ + get numRowsGrid():number; + + /** + * 当前地图类型 + */ + get orientation():string; + + /** + * tile渲染顺序 + */ + get renderOrder():string; + + /** + * ***************************************对外接口********************************************* + */ + + /** + * 整个地图的显示容器 + * @return 地图的显示容器 + */ + mapSprite():Sprite; + + /** + * 得到指定的MapLayer + * @param layerName 要找的层名称 + * @return + */ + getLayerByName(layerName:string):MapLayer; + + /** + * 通过索引得MapLayer + * @param index 要找的层索引 + * @return + */ + getLayerByIndex(index:number):MapLayer; + } + + /** + * 此类是子纹理类,也包括同类动画的管理 + * TiledMap会把纹理分割成无数子纹理,也可以把其中的某块子纹理替换成一个动画序列 + * 本类的实现就是如果发现子纹理被替换成一个动画序列,animationKey会被设为true + * 即animationKey为true,就使用TileAniSprite来做显示,把动画序列根据时间画到TileAniSprite上 + * @author ... + */ + class TileTexSet { + + /** + * 唯一标识 + */ + gid:number; + + /** + * 子纹理的引用 + */ + texture:Texture; + + /** + * 纹理显示时的坐标偏移X + */ + offX:number; + + /** + * 纹理显示时的坐标偏移Y + */ + offY:number; + + /** + * 当前要播放动画的纹理序列 + */ + textureArray:any[]; + + /** + * 当前动画每帧的时间间隔 + */ + durationTimeArray:any[]; + + /** + * 动画播放的总时间 + */ + animationTotalTime:number; + + /** + * true表示当前纹理,是一组动画,false表示当前只有一个纹理 + */ + isAnimation:boolean; + private _spriteNum:any; + private _aniDic:any; + private _frameIndex:any; + private _time:any; + private _interval:any; + private _preFrameTime:any; + + /** + * 加入一个动画显示对象到此动画中 + * @param aniName //显示对象的名字 + * @param sprite //显示对象 + */ + addAniSprite(aniName:string,sprite:TileAniSprite):void; + + /** + * 把动画画到所有注册的SPRITE上 + */ + private animate:any; + private drawTexture:any; + + /** + * 移除不需要更新的SPRITE + * @param _name + */ + removeAniSprite(_name:string):void; + + /** + * 显示当前动画的使用情况 + */ + showDebugInfo():string; + + /** + * 清理 + */ + clearAll():void; + } + + /** + * @private 计算贝塞尔曲线的工具类。 + */ + class Bezier { + + /** + * 工具类单例 + */ + static I:Bezier; + + /** + * @private + */ + private _controlPoints:any; + + /** + * @private + */ + private _calFun:any; + + /** + * @private + */ + private _switchPoint:any; + + /** + * 计算二次贝塞尔点。 + */ + getPoint2(t:number,rst:any[]):void; + + /** + * 计算三次贝塞尔点 + */ + getPoint3(t:number,rst:any[]):void; + + /** + * 计算贝塞尔点序列 + */ + insertPoints(count:number,rst:any[]):void; + + /** + * 获取贝塞尔曲线上的点。 + * @param pList 控制点[x0,y0,x1,y1...] + * @param inSertCount 每次曲线的插值数量 + */ + getBezierPoints(pList:any[],inSertCount?:number,count?:number):any[]; + } + + /** + * @private 凸包算法。 + */ + class GrahamScan { + private static _mPointList:any; + private static _tempPointList:any; + private static _temPList:any; + private static _temArr:any; + static multiply(p1:Point,p2:Point,p0:Point):number; + + /** + * 计算两个点的距离。 + * @param p1 + * @param p2 + * @return + */ + static dis(p1:Point,p2:Point):number; + private static _getPoints:any; + + /** + * 将数组 src 从索引0位置 依次取 cout 个项添加至 tst 数组的尾部。 + * @param rst 原始数组,用于添加新的子元素。 + * @param src 用于取子元素的数组。 + * @param count 需要取得子元素个数。 + * @return 添加完子元素的 rst 对象。 + */ + static getFrom(rst:any[],src:any[],count:number):any[]; + + /** + * 将数组 src 从末尾索引位置往头部索引位置方向 依次取 cout 个项添加至 tst 数组的尾部。 + * @param rst 原始数组,用于添加新的子元素。 + * @param src 用于取子元素的数组。 + * @param count 需要取得子元素个数。 + * @return 添加完子元素的 rst 对象。 + */ + static getFromR(rst:any[],src:any[],count:number):any[]; + + /** + * [x,y...]列表 转 Point列表 + * @param pList Point列表 + * @return [x,y...]列表 + */ + static pListToPointList(pList:any[],tempUse?:boolean):any[]; + + /** + * Point列表转[x,y...]列表 + * @param pointList Point列表 + * @return [x,y...]列表 + */ + static pointListToPlist(pointList:any[]):any[]; + + /** + * 寻找包括所有点的最小多边形顶点集合 + * @param pList 形如[x0,y0,x1,y1...]的点列表 + * @return 最小多边形顶点集合 + */ + static scanPList(pList:any[]):any[]; + + /** + * 寻找包括所有点的最小多边形顶点集合 + * @param PointSet Point列表 + * @return 最小多边形顶点集合 + */ + static scan(PointSet:any[]):any[]; + } + + /** + * @private MathUtil 是一个数据处理工具类。 + */ + class MathUtil { + static subtractVector3(l:Float32Array,r:Float32Array,o:Float32Array):void; + static lerp(left:number,right:number,amount:number):number; + static scaleVector3(f:Float32Array,b:number,e:Float32Array):void; + static lerpVector3(l:Float32Array,r:Float32Array,t:number,o:Float32Array):void; + static lerpVector4(l:Float32Array,r:Float32Array,t:number,o:Float32Array):void; + static slerpQuaternionArray(a:Float32Array,Offset1:number,b:Float32Array,Offset2:number,t:number,out:Float32Array,Offset3:number):Float32Array; + + /** + * 获取指定的两个点组成的线段的角度值。 + * @param x0 点一的 X 轴坐标值。 + * @param y0 点一的 Y 轴坐标值。 + * @param x1 点二的 X 轴坐标值。 + * @param y1 点二的 Y 轴坐标值。 + * @return 角度值。 + */ + static getRotation(x0:number,y0:number,x1:number,y1:number):number; + + /** + * 一个用来确定数组元素排序顺序的比较函数。 + * @param a 待比较数字。 + * @param b 待比较数字。 + * @return 如果a等于b 则值为0;如果b>a则值为1;如果b<则值为-1。 + */ + static sortBigFirst(a:number,b:number):number; + + /** + * 一个用来确定数组元素排序顺序的比较函数。 + * @param a 待比较数字。 + * @param b 待比较数字。 + * @return 如果a等于b 则值为0;如果b>a则值为-1;如果b<则值为1。 + */ + static sortSmallFirst(a:number,b:number):number; + + /** + * 将指定的元素转为数字进行比较。 + * @param a 待比较元素。 + * @param b 待比较元素。 + * @return b、a转化成数字的差值 (b-a)。 + */ + static sortNumBigFirst(a:any,b:any):number; + + /** + * 将指定的元素转为数字进行比较。 + * @param a 待比较元素。 + * @param b 待比较元素。 + * @return a、b转化成数字的差值 (a-b)。 + */ + static sortNumSmallFirst(a:any,b:any):number; + + /** + * 返回根据对象指定的属性进行排序的比较函数。 + * @param key 排序要依据的元素属性名。 + * @param bigFirst 如果值为true,则按照由大到小的顺序进行排序,否则按照由小到大的顺序进行排序。 + * @param forceNum 如果值为true,则将排序的元素转为数字进行比较。 + * @return 排序函数。 + */ + static sortByKey(key:string,bigFirst?:boolean,forceNum?:boolean):(a:any,b:any) =>number; + } + + /** + *

    Matrix 类表示一个转换矩阵,它确定如何将点从一个坐标空间映射到另一个坐标空间。

    + *

    您可以对一个显示对象执行不同的图形转换,方法是设置 Matrix 对象的属性,将该 Matrix 对象应用于 Transform 对象的 matrix 属性,然后应用该 Transform 对象作为显示对象的 transform 属性。这些转换函数包括平移(x 和 y 重新定位)、旋转、缩放和倾斜。

    + */ + class Matrix { + + /** + * @private 一个初始化的 Matrix 对象,不允许修改此对象内容。 + */ + static EMPTY:Matrix; + + /** + * 用于中转使用的 Matrix 对象。 + */ + static TEMP:Matrix; + + /** + * 缩放或旋转图像时影响像素沿 x 轴定位的值。 + */ + a:number; + + /** + * 旋转或倾斜图像时影响像素沿 y 轴定位的值。 + */ + b:number; + + /** + * 旋转或倾斜图像时影响像素沿 x 轴定位的值。 + */ + c:number; + + /** + * 缩放或旋转图像时影响像素沿 y 轴定位的值。 + */ + d:number; + + /** + * 沿 x 轴平移每个点的距离。 + */ + tx:number; + + /** + * 沿 y 轴平移每个点的距离。 + */ + ty:number; + + /** + * 使用指定参数创建新的 Matrix 对象。 + * @param a (可选)缩放或旋转图像时影响像素沿 x 轴定位的值。 + * @param b (可选)旋转或倾斜图像时影响像素沿 y 轴定位的值。 + * @param c (可选)旋转或倾斜图像时影响像素沿 x 轴定位的值。 + * @param d (可选)缩放或旋转图像时影响像素沿 y 轴定位的值。 + * @param tx (可选)沿 x 轴平移每个点的距离。 + * @param ty (可选)沿 y 轴平移每个点的距离。 + */ + + constructor(a?:number,b?:number,c?:number,d?:number,tx?:number,ty?:number,nums?:number); + + /** + * 将本矩阵设置为单位矩阵。 + * @return 返回当前矩形。 + */ + identity():Matrix; + + /** + * 设置沿 x 、y 轴平移每个点的距离。 + * @param x 沿 x 轴平移每个点的距离。 + * @param y 沿 y 轴平移每个点的距离。 + * @return 返回对象本身 + */ + setTranslate(x:number,y:number):Matrix; + + /** + * 沿 x 和 y 轴平移矩阵,平移的变化量由 x 和 y 参数指定。 + * @param x 沿 x 轴向右移动的量(以像素为单位)。 + * @param y 沿 y 轴向下移动的量(以像素为单位)。 + * @return 返回此矩形对象。 + */ + translate(x:number,y:number):Matrix; + + /** + * 对矩阵应用缩放转换。 + * @param x 用于沿 x 轴缩放对象的乘数。 + * @param y 用于沿 y 轴缩放对象的乘数。 + * @return 返回矩阵对象本身 + */ + scale(x:number,y:number):Matrix; + + /** + * 对 Matrix 对象应用旋转转换。 + * @param angle 以弧度为单位的旋转角度。 + * @return 返回矩阵对象本身 + */ + rotate(angle:number):Matrix; + + /** + * 对 Matrix 对象应用倾斜转换。 + * @param x 沿着 X 轴的 2D 倾斜弧度。 + * @param y 沿着 Y 轴的 2D 倾斜弧度。 + * @return 当前 Matrix 对象。 + */ + skew(x:number,y:number):Matrix; + + /** + * 对指定的点应用当前矩阵的逆转化并返回此点。 + * @param out 待转化的点 Point 对象。 + * @return 返回out + */ + invertTransformPoint(out:Point):Point; + + /** + * 将 Matrix 对象表示的几何转换应用于指定点。 + * @param out 用来设定输出结果的点。 + * @return 返回out + */ + transformPoint(out:Point):Point; + + /** + * 将 Matrix 对象表示的几何转换应用于指定点,忽略tx、ty。 + * @param out 用来设定输出结果的点。 + * @return 返回out + */ + transformPointN(out:Point):Point; + + /** + * 获取 X 轴缩放值。 + * @return X 轴缩放值。 + */ + getScaleX():number; + + /** + * 获取 Y 轴缩放值。 + * @return Y 轴缩放值。 + */ + getScaleY():number; + + /** + * 执行原始矩阵的逆转换。 + * @return 当前矩阵对象。 + */ + invert():Matrix; + + /** + * 将 Matrix 的成员设置为指定值。 + * @param a 缩放或旋转图像时影响像素沿 x 轴定位的值。 + * @param b 旋转或倾斜图像时影响像素沿 y 轴定位的值。 + * @param c 旋转或倾斜图像时影响像素沿 x 轴定位的值。 + * @param d 缩放或旋转图像时影响像素沿 y 轴定位的值。 + * @param tx 沿 x 轴平移每个点的距离。 + * @param ty 沿 y 轴平移每个点的距离。 + * @return 当前矩阵对象。 + */ + setTo(a:number,b:number,c:number,d:number,tx:number,ty:number):Matrix; + + /** + * 将指定矩阵与当前矩阵连接,从而将这两个矩阵的几何效果有效地结合在一起。 + * @param matrix 要连接到源矩阵的矩阵。 + * @return 当前矩阵。 + */ + concat(matrix:Matrix):Matrix; + + /** + * 将指定的两个矩阵相乘后的结果赋值给指定的输出对象。 + * @param m1 矩阵一。 + * @param m2 矩阵二。 + * @param out 输出对象。 + * @return 结果输出对象 out。 + */ + static mul(m1:Matrix,m2:Matrix,out:Matrix):Matrix; + + /** + * 将指定的两个矩阵相乘,结果赋值给指定的输出数组,长度为16。 + * @param m1 矩阵一。 + * @param m2 矩阵二。 + * @param out 输出对象Array。 + * @return 结果输出对象 out。 + */ + static mul16(m1:Matrix,m2:Matrix,out:any[]):any[]; + + /** + * @private 对矩阵应用缩放转换。反向相乘 + * @param x 用于沿 x 轴缩放对象的乘数。 + * @param y 用于沿 y 轴缩放对象的乘数。 + */ + scaleEx(x:number,y:number):void; + + /** + * @private 对 Matrix 对象应用旋转转换。反向相乘 + * @param angle 以弧度为单位的旋转角度。 + */ + rotateEx(angle:number):void; + + /** + * 返回此 Matrix 对象的副本。 + * @return 与原始实例具有完全相同的属性的新 Matrix 实例。 + */ + clone():Matrix; + + /** + * 将当前 Matrix 对象中的所有矩阵数据复制到指定的 Matrix 对象中。 + * @param dec 要复制当前矩阵数据的 Matrix 对象。 + * @return 已复制当前矩阵数据的 Matrix 对象。 + */ + copyTo(dec:Matrix):Matrix; + + /** + * 返回列出该 Matrix 对象属性的文本值。 + * @return 一个字符串,它包含 Matrix 对象的属性值:a、b、c、d、tx 和 ty。 + */ + toString():string; + + /** + * 销毁此对象。 + */ + destroy():void; + + /** + * 回收到对象池,方便复用 + */ + recover():void; + + /** + * 从对象池中创建一个 Matrix 对象。 + * @return Matrix 对象。 + */ + static create():Matrix; + } + + /** + * Point 对象表示二维坐标系统中的某个位置,其中 x 表示水平轴,y 表示垂直轴。 + */ + class Point { + + /** + * 临时使用的公用对象。 + */ + static TEMP:Point; + + /** + * @private 全局空的point对象(x=0,y=0),不允许修改此对象内容 + */ + static EMPTY:Point; + + /** + * 该点的水平坐标。 + */ + x:number; + + /** + * 该点的垂直坐标。 + */ + y:number; + + /** + * 根据指定坐标,创建一个新的 Point 对象。 + * @param x (可选)水平坐标。 + * @param y (可选)垂直坐标。 + */ + + constructor(x?:number,y?:number); + + /** + * 从对象池创建 + */ + static create():Point; + + /** + * 将 Point 的成员设置为指定值。 + * @param x 水平坐标。 + * @param y 垂直坐标。 + * @return 当前 Point 对象。 + */ + setTo(x:number,y:number):Point; + + /** + * 重置 + */ + reset():Point; + + /** + * 回收到对象池,方便复用 + */ + recover():void; + + /** + * 计算当前点和目标点(x,y)的距离。 + * @param x 水平坐标。 + * @param y 垂直坐标。 + * @return 返回当前点和目标点之间的距离。 + */ + distance(x:number,y:number):number; + + /** + * 返回包含 x 和 y 坐标的值的字符串。 + */ + toString():string; + + /** + * 标准化向量。 + */ + normalize():void; + + /** + * copy point坐标 + * @param point 需要被copy的point + */ + copy(point:Point):Point; + } + + /** + *

    Rectangle 对象是按其位置(由它左上角的点 (x, y) 确定)以及宽度和高度定义的区域。

    + *

    Rectangle 类的 x、y、width 和 height 属性相互独立;更改一个属性的值不会影响其他属性。

    + */ + class Rectangle { + + /** + * @private 全局空的矩形区域x=0,y=0,width=0,height=0,不允许修改此对象内容 + */ + static EMPTY:Rectangle; + + /** + * 全局临时的矩形区域,此对象用于全局复用,以减少对象创建 + */ + static TEMP:Rectangle; + + /** + * @private + */ + private static _temB:any; + + /** + * @private + */ + private static _temA:any; + + /** + * 矩形左上角的 X 轴坐标。 + */ + x:number; + + /** + * 矩形左上角的 Y 轴坐标。 + */ + y:number; + + /** + * 矩形的宽度。 + */ + width:number; + + /** + * 矩形的高度。 + */ + height:number; + + /** + * 创建一个 Rectangle 对象。 + * @param x 矩形左上角的 X 轴坐标。 + * @param y 矩形左上角的 Y 轴坐标。 + * @param width 矩形的宽度。 + * @param height 矩形的高度。 + */ + + constructor(x?:number,y?:number,width?:number,height?:number); + + /** + * 此矩形右侧的 X 轴坐标。 x 和 width 属性的和。 + */ + get right():number; + + /** + * 此矩形底端的 Y 轴坐标。y 和 height 属性的和。 + */ + get bottom():number; + + /** + * 将 Rectangle 的属性设置为指定值。 + * @param x x 矩形左上角的 X 轴坐标。 + * @param y x 矩形左上角的 Y 轴坐标。 + * @param width 矩形的宽度。 + * @param height 矩形的高。 + * @return 返回属性值修改后的矩形对象本身。 + */ + setTo(x:number,y:number,width:number,height:number):Rectangle; + + /** + * 重置 + */ + reset():Rectangle; + + /** + * 回收 + */ + recover():void; + + /** + * 创建 + */ + static create():Rectangle; + + /** + * 复制 source 对象的属性值到此矩形对象中。 + * @param sourceRect 源 Rectangle 对象。 + * @return 返回属性值修改后的矩形对象本身。 + */ + copyFrom(source:Rectangle):Rectangle; + + /** + * 确定由此 Rectangle 对象定义的矩形区域内是否包含指定的点。 + * @param x 点的 X 轴坐标值(水平位置)。 + * @param y 点的 Y 轴坐标值(垂直位置)。 + * @return 如果 Rectangle 对象包含指定的点,则值为 true;否则为 false。 + */ + contains(x:number,y:number):boolean; + + /** + * 确定在 rect 参数中指定的对象是否与此 Rectangle 对象相交。此方法检查指定的 Rectangle 对象的 x、y、width 和 height 属性,以查看它是否与此 Rectangle 对象相交。 + * @param rect Rectangle 对象。 + * @return 如果传入的矩形对象与此对象相交,则返回 true 值,否则返回 false。 + */ + intersects(rect:Rectangle):boolean; + + /** + * 如果在 rect 参数中指定的 Rectangle 对象与此 Rectangle 对象相交,则返回交集区域作为 Rectangle 对象。如果矩形不相交,则此方法返回null。 + * @param rect 待比较的矩形区域。 + * @param out (可选)待输出的矩形区域。如果为空则创建一个新的。建议:尽量复用对象,减少对象创建消耗。 + * @return 返回相交的矩形区域对象。 + */ + intersection(rect:Rectangle,out?:Rectangle|null):Rectangle|null; + + /** + *

    矩形联合,通过填充两个矩形之间的水平和垂直空间,将这两个矩形组合在一起以创建一个新的 Rectangle 对象。

    + *

    注意:union() 方法忽略高度或宽度值为 0 的矩形,如:var rect2:Rectangle = new Rectangle(300,300,50,0);

    + * @param 要添加到此 Rectangle 对象的 Rectangle 对象。 + * @param out 用于存储输出结果的矩形对象。如果为空,则创建一个新的。建议:尽量复用对象,减少对象创建消耗。Rectangle.TEMP对象用于对象复用。 + * @return 充当两个矩形的联合的新 Rectangle 对象。 + */ + union(source:Rectangle,out?:Rectangle|null):Rectangle; + + /** + * 返回一个 Rectangle 对象,其 x、y、width 和 height 属性的值与当前 Rectangle 对象的对应值相同。 + * @param out (可选)用于存储结果的矩形对象。如果为空,则创建一个新的。建议:尽量复用对象,减少对象创建消耗。。Rectangle.TEMP对象用于对象复用。 + * @return Rectangle 对象,其 x、y、width 和 height 属性的值与当前 Rectangle 对象的对应值相同。 + */ + clone(out?:Rectangle|null):Rectangle; + + /** + * 当前 Rectangle 对象的水平位置 x 和垂直位置 y 以及高度 width 和宽度 height 以逗号连接成的字符串。 + */ + toString():string; + + /** + * 检测传入的 Rectangle 对象的属性是否与当前 Rectangle 对象的属性 x、y、width、height 属性值都相等。 + * @param rect 待比较的 Rectangle 对象。 + * @return 如果判断的属性都相等,则返回 true ,否则返回 false。 + */ + equals(rect:Rectangle):boolean; + + /** + *

    为当前矩形对象加一个点,以使当前矩形扩展为包含当前矩形和此点的最小矩形。

    + *

    此方法会修改本对象。

    + * @param x 点的 X 坐标。 + * @param y 点的 Y 坐标。 + * @return 返回此 Rectangle 对象。 + */ + addPoint(x:number,y:number):Rectangle; + + /** + * 确定此 Rectangle 对象是否为空。 + * @return 如果 Rectangle 对象的宽度或高度小于等于 0,则返回 true 值,否则返回 false。 + */ + isEmpty():boolean; + } + + /** + * @private 使用Audio标签播放声音 + */ + class AudioSound extends EventDispatcher { + + /** + * @private + */ + private static _audioCache:any; + + /** + * 声音URL + */ + url:string; + + /** + * 播放用的audio标签 + */ + audio:HTMLAudioElement; + + /** + * 是否已加载完成 + */ + loaded:boolean; + + /** + * 释放声音 + */ + dispose():void; + + /** + * @private + */ + private static _makeMusicOK:any; + + /** + * 加载声音 + * @param url + */ + load(url:string):void; + + /** + * 播放声音 + * @param startTime 起始时间 + * @param loops 循环次数 + * @return + */ + play(startTime?:number,loops?:number):SoundChannel; + + /** + * 获取总时间。 + */ + get duration():number; + } + + /** + * @private audio标签播放声音的音轨控制 + */ + class AudioSoundChannel extends SoundChannel { + + /** + * 播放用的audio标签 + */ + private _audio:any; + private _onEnd:any; + private _resumePlay:any; + + constructor(audio:HTMLAudioElement); + private __onEnd:any; + private __resumePlay:any; + + /** + * 播放 + * @override + */ + play():void; + + /** + * 当前播放到的位置 + * @return + * @override + */ + get position():number; + + /** + * 获取总时间。 + * @override + */ + get duration():number; + + /** + * 停止播放 + * @override + */ + stop():void; + + /** + * @override + */ + pause():void; + + /** + * @override + */ + resume():void; + + /** + * 设置音量 + * @param v + * @override + */ + set volume(v:number); + + /** + * 获取音量 + * @return + * @override + */ + get volume():number; + } + + /** + * Sound 类是用来播放控制声音的类。 + * 引擎默认有两套声音方案,优先使用WebAudio播放声音,如果WebAudio不可用,则用H5Audio播放,H5Audio在部分机器上有兼容问题(比如不能混音,播放有延迟等)。 + */ + class Sound extends EventDispatcher { + + /** + * 加载声音。 + * @param url 地址。 + */ + load(url:string):void; + + /** + * 播放声音。 + * @param startTime 开始时间,单位秒 + * @param loops 循环次数,0表示一直循环 + * @return 声道 SoundChannel 对象。 + */ + play(startTime?:number,loops?:number):SoundChannel; + + /** + * 获取总时间。 + */ + get duration():number; + + /** + * 释放声音资源。 + */ + dispose():void; + } + + /** + *

    SoundChannel 用来控制程序中的声音。每个声音均分配给一个声道,而且应用程序可以具有混合在一起的多个声道。

    + *

    SoundChannel 类包含控制声音的播放、暂停、停止、音量的方法,以及获取声音的播放状态、总时间、当前播放时间、总循环次数、播放地址等信息的方法。

    + */ + class SoundChannel extends EventDispatcher { + + /** + * 声音地址。 + */ + url:string; + + /** + * 循环次数。 + */ + loops:number; + + /** + * 播放声音开始时间。 + */ + startTime:number; + + /** + * 表示声音是否已暂停。 + */ + isStopped:boolean; + + /** + * 播放完成处理器。 + */ + completeHandler:Handler; + + /** + * 音量范围从 0(静音)至 1(最大音量)。 + */ + set volume(v:number); + get volume():number; + + /** + * 获取当前播放时间,单位是秒。 + */ + get position():number; + + /** + * 获取总时间,单位是秒。 + */ + get duration():number; + + /** + * 播放声音。 + */ + play():void; + + /** + * 停止播放。 + */ + stop():void; + + /** + * 暂停播放。 + */ + pause():void; + + /** + * 继续播放。 + */ + resume():void; + + /** + * private + */ + protected __runComplete(handler:Handler):void; + } + + /** + * SoundManager 是一个声音管理类。提供了对背景音乐、音效的播放控制方法。 + * 引擎默认有两套声音方案:WebAudio和H5Audio + * 播放音效,优先使用WebAudio播放声音,如果WebAudio不可用,则用H5Audio播放,H5Audio在部分机器上有兼容问题(比如不能混音,播放有延迟等)。 + * 播放背景音乐,则使用H5Audio播放(使用WebAudio会增加特别大的内存,并且要等加载完毕后才能播放,有延迟) + * 建议背景音乐用mp3类型,音效用wav或者mp3类型(如果打包为app,音效只能用wav格式)。 + * 详细教程及声音格式请参考:http://ldc2.layabox.com/doc/?nav=ch-as-1-7-0 + */ + class SoundManager { + + /** + * 背景音乐音量。 + * @default 1 + */ + static musicVolume:number; + + /** + * 音效音量。 + * @default 1 + */ + static soundVolume:number; + + /** + * 声音播放速率。 + * @default 1 + */ + static playbackRate:number; + + /** + * 背景音乐使用Audio标签播放。 + * @default true + */ + private static _useAudioMusic:any; + + /** + * @private 是否静音,默认为false。 + */ + private static _muted:any; + + /** + * @private 是否音效静音,默认为false。 + */ + private static _soundMuted:any; + + /** + * @private 是否背景音乐静音,默认为false。 + */ + private static _musicMuted:any; + + /** + * @private 当前背景音乐声道。 + */ + private static _musicChannel:any; + + /** + * @private 当前播放的Channel列表。 + */ + private static _channels:any; + + /** + * @private + */ + private static _autoStopMusic:any; + + /** + * @private + */ + private static _blurPaused:any; + + /** + * @private + */ + private static _isActive:any; + + /** + * @private + */ + private static _lastSoundUsedTimeDic:any; + + /** + * @private + */ + private static _isCheckingDispose:any; + + /** + * 音效播放后自动删除。 + * @default true + */ + static autoReleaseSound:boolean; + + /** + * 添加播放的声音实例。 + * @param channel SoundChannel 对象。 + */ + static addChannel(channel:SoundChannel):void; + + /** + * 移除播放的声音实例。 + * @param channel SoundChannel 对象。 + */ + static removeChannel(channel:SoundChannel):void; + + /** + * @private + */ + static disposeSoundLater(url:string):void; + + /** + * @private + */ + private static _checkDisposeSound:any; + + /** + * @private + */ + static disposeSoundIfNotUsed(url:string):void; + + /** + * 失去焦点后是否自动停止背景音乐。 + * @param v Boolean 失去焦点后是否自动停止背景音乐。 + */ + static set autoStopMusic(v:boolean); + + /** + * 失去焦点后是否自动停止背景音乐。 + */ + static get autoStopMusic():boolean; + private static _visibilityChange:any; + private static _stageOnBlur:any; + private static _recoverWebAudio:any; + private static _stageOnFocus:any; + + /** + * 背景音乐和所有音效是否静音。 + */ + static set muted(value:boolean); + static get muted():boolean; + + /** + * 所有音效(不包括背景音乐)是否静音。 + */ + static set soundMuted(value:boolean); + static get soundMuted():boolean; + + /** + * 背景音乐(不包括音效)是否静音。 + */ + static set musicMuted(value:boolean); + static get musicMuted():boolean; + static get useAudioMusic():boolean; + static set useAudioMusic(value:boolean); + + /** + * 播放音效。音效可以同时播放多个。 + * @param url 声音文件地址。 + * @param loops 循环次数,0表示无限循环。 + * @param complete 声音播放完成回调 Handler对象。 + * @param soundClass 使用哪个声音类进行播放,null表示自动选择。 + * @param startTime 声音播放起始时间。 + * @return SoundChannel对象,通过此对象可以对声音进行控制,以及获取声音信息。 + */ + static playSound(url:string,loops?:number,complete?:Handler,soundClass?:new () => any,startTime?:number):SoundChannel; + + /** + * 释放声音资源。 + * @param url 声音播放地址。 + */ + static destroySound(url:string):void; + + /** + * 播放背景音乐。背景音乐同时只能播放一个,如果在播放背景音乐时再次调用本方法,会先停止之前的背景音乐,再播放当前的背景音乐。 + * @param url 声音文件地址。 + * @param loops 循环次数,0表示无限循环。 + * @param complete 声音播放完成回调,complete 结果参数 true: 播放完成, false/undefined :stop触发的complete。 + * @param startTime 声音播放起始时间。 + * @return SoundChannel对象,通过此对象可以对声音进行控制,以及获取声音信息。 + */ + static playMusic(url:string,loops?:number,complete?:Handler,startTime?:number):SoundChannel; + + /** + * 停止声音播放。此方法能够停止任意声音的播放(包括背景音乐和音效),只需传入对应的声音播放地址。 + * @param url 声音文件地址。 + */ + static stopSound(url:string):void; + + /** + * 停止播放所有声音(包括背景音乐和音效)。 + */ + static stopAll():void; + + /** + * 停止播放所有音效(不包括背景音乐)。 + */ + static stopAllSound():void; + + /** + * 停止播放背景音乐(不包括音效)。 + * @param url 声音文件地址。 + */ + static stopMusic():void; + + /** + * 设置声音音量。根据参数不同,可以分别设置指定声音(背景音乐或音效)音量或者所有音效(不包括背景音乐)音量。 + * @param volume 音量。初始值为1。音量范围从 0(静音)至 1(最大音量)。 + * @param url (default = null)声音播放地址。默认为null。为空表示设置所有音效(不包括背景音乐)的音量,不为空表示设置指定声音(背景音乐或音效)的音量。 + */ + static setSoundVolume(volume:number,url?:string):void; + + /** + * 设置背景音乐音量。音量范围从 0(静音)至 1(最大音量)。 + * @param volume 音量。初始值为1。音量范围从 0(静音)至 1(最大音量)。 + */ + static setMusicVolume(volume:number):void; + + /** + * 设置指定声音的音量。 + * @param url 声音文件url + * @param volume 音量。初始值为1。 + */ + private static _setVolume:any; + } + + /** + * @private + */ + class SoundNode extends Sprite { + url:string; + private _channel:any; + private _tar:any; + private _playEvents:any; + private _stopEvents:any; + + constructor(); + + /** + * @private + */ + private _onParentChange:any; + + /** + * 播放 + * @param loops 循环次数 + * @param complete 完成回调 + */ + play(loops?:number,complete?:Handler):void; + + /** + * 停止播放 + */ + stop():void; + + /** + * @private + */ + private _setPlayAction:any; + + /** + * @private + */ + private _setPlayActions:any; + + /** + * 设置触发播放的事件 + * @param events + */ + set playEvent(events:string); + + /** + * 设置控制播放的对象 + * @param tar + */ + set target(tar:Sprite); + + /** + * 设置触发停止的事件 + * @param events + */ + set stopEvent(events:string); + } + + /** + * @private web audio api方式播放声音 + */ + class WebAudioSound extends EventDispatcher { + private static _dataCache:any; + + /** + * 是否支持web audio api + */ + static webAudioEnabled:boolean; + + /** + * 播放设备 + */ + static ctx:any; + + /** + * 当前要解码的声音文件列表 + */ + static buffs:any[]; + + /** + * 是否在解码中 + */ + static isDecoding:boolean; + + /** + * 用于播放解锁声音以及解决Ios9版本的内存释放 + */ + static _miniBuffer:any; + + /** + * 事件派发器,用于处理加载解码完成事件的广播 + */ + static e:EventDispatcher; + + /** + * 是否已解锁声音播放 + */ + private static _unlocked:any; + + /** + * 当前解码的声音信息 + */ + static tInfo:any; + private static __loadingSound:any; + + /** + * 声音URL + */ + url:string; + + /** + * 是否已加载完成 + */ + loaded:boolean; + + /** + * 声音文件数据 + */ + data:ArrayBuffer; + + /** + * 声音原始文件数据 + */ + audioBuffer:any; + + /** + * 待播放的声音列表 + */ + private __toPlays:any; + + /** + * @private + */ + private _disposed:any; + + /** + * 解码声音文件 + */ + static decode():void; + + /** + * 解码成功回调 + * @param audioBuffer + */ + private static _done:any; + + /** + * 解码失败回调 + * @return + */ + private static _fail:any; + + /** + * 播放声音以解锁IOS的声音 + */ + private static _playEmptySound:any; + + /** + * 尝试解锁声音 + */ + private static _unlock:any; + static initWebAudio():void; + + /** + * 加载声音 + * @param url + */ + load(url:string):void; + private _err:any; + private _loaded:any; + private _removeLoadEvents:any; + private __playAfterLoaded:any; + + /** + * 播放声音 + * @param startTime 起始时间 + * @param loops 循环次数 + * @return + */ + play(startTime?:number,loops?:number,channel?:WebAudioSoundChannel):SoundChannel; + get duration():number; + dispose():void; + } + + /** + * @private web audio api方式播放声音的音轨控制 + */ + class WebAudioSoundChannel extends SoundChannel { + + /** + * 声音原始文件数据 + */ + audioBuffer:any; + + /** + * gain节点 + */ + private gain:any; + + /** + * 播放用的数据 + */ + private bufferSource:any; + + /** + * 当前时间 + */ + private _currentTime:any; + + /** + * 当前音量 + */ + private _volume:any; + + /** + * 播放开始时的时间戳 + */ + private _startTime:any; + private _pauseTime:any; + + /** + * 播放设备 + */ + private context:any; + private _onPlayEnd:any; + private static _tryCleanFailed:any; + static SetTargetDelay:number; + + constructor(); + + /** + * 播放声音 + * @override + */ + play():void; + private __onPlayEnd:any; + + /** + * 获取当前播放位置 + * @override + */ + get position():number; + + /** + * @override + */ + get duration():number; + private _clearBufferSource:any; + private _tryClearBuffer:any; + + /** + * 停止播放 + * @override + */ + stop():void; + + /** + * @override + */ + pause():void; + + /** + * @override + */ + resume():void; + + /** + * 设置音量 + * @override + */ + set volume(v:number); + + /** + * 获取音量 + * @override + */ + get volume():number; + } + + /** + * @private + */ + class AtlasInfoManager { + private static _fileLoadDic:any; + static enable(infoFile:string,callback?:Handler|null):void; + + /** + * @private + */ + private static _onInfoLoaded:any; + static getFileLoadPath(file:string):string; + } + + /** + * 请求进度改变时调度。 + * @eventType Event.PROGRESS + */ + + /** + * 请求结束后调度。 + * @eventType Event.COMPLETE + */ + + /** + * 请求出错时调度。 + * @eventType Event.ERROR + */ + + /** + *

    HttpRequest 通过封装 HTML XMLHttpRequest 对象提供了对 HTTP 协议的完全的访问,包括做出 POST 和 HEAD 请求以及普通的 GET 请求的能力。 HttpRequest 只提供以异步的形式返回 Web 服务器的响应,并且能够以文本或者二进制的形式返回内容。

    + *

    注意:建议每次请求都使用新的 HttpRequest 对象,因为每次调用该对象的send方法时,都会清空之前设置的数据,并重置 HTTP 请求的状态,这会导致之前还未返回响应的请求被重置,从而得不到之前请求的响应结果。

    + */ + class HttpRequest extends EventDispatcher { + + /** + * @private + */ + protected _http:XMLHttpRequest; + + /** + * @private + */ + private static _urlEncode:any; + + /** + * @private + */ + protected _responseType:string; + + /** + * @private + */ + protected _data:any; + + /** + * @private + */ + protected _url:string; + + /** + * 发送 HTTP 请求。 + * @param url 请求的地址。大多数浏览器实施了一个同源安全策略,并且要求这个 URL 与包含脚本的文本具有相同的主机名和端口。 + * @param data (default = null)发送的数据。 + * @param method (default = "get")用于请求的 HTTP 方法。值包括 "get"、"post"、"head"。 + * @param responseType (default = "text")Web 服务器的响应类型,可设置为 "text"、"json"、"xml"、"arraybuffer"。 + * @param headers (default = null) HTTP 请求的头部信息。参数形如key-value数组:key是头部的名称,不应该包括空白、冒号或换行;value是头部的值,不应该包括换行。比如["Content-Type", "application/json"]。 + */ + send(url:string,data?:any,method?:string,responseType?:string,headers?:any[]|null):void; + + /** + * @private 请求进度的侦听处理函数。 + * @param e 事件对象。 + */ + protected _onProgress(e:any):void; + + /** + * @private 请求中断的侦听处理函数。 + * @param e 事件对象。 + */ + protected _onAbort(e:any):void; + + /** + * @private 请求出错侦的听处理函数。 + * @param e 事件对象。 + */ + protected _onError(e:any):void; + + /** + * @private 请求消息返回的侦听处理函数。 + * @param e 事件对象。 + */ + protected _onLoad(e:any):void; + + /** + * @private 请求错误的处理函数。 + * @param message 错误信息。 + */ + protected error(message:string):void; + + /** + * @private 请求成功完成的处理函数。 + */ + protected complete():void; + + /** + * @private 清除当前请求。 + */ + protected clear():void; + + /** + * 请求的地址。 + */ + get url():string; + + /** + * 返回的数据。 + */ + get data():any; + + /** + * 本对象所封装的原生 XMLHttpRequest 引用。 + */ + get http():any; + } + + /** + * 加载进度发生改变时调度。 + * @eventType Event.PROGRESS + */ + + /** + * 加载完成后调度。 + * @eventType Event.COMPLETE + */ + + /** + * 加载出错时调度。 + * @eventType Event.ERROR + */ + + /** + * Loader 类可用来加载文本、JSON、XML、二进制、图像等资源。 + */ + class Loader extends EventDispatcher { + + /** + * 文本类型,加载完成后返回文本。 + */ + static TEXT:string; + + /** + * JSON 类型,加载完成后返回json数据。 + */ + static JSON:string; + + /** + * prefab 类型,加载完成后返回Prefab实例。 + */ + static PREFAB:string; + + /** + * XML 类型,加载完成后返回domXML。 + */ + static XML:string; + + /** + * 二进制类型,加载完成后返回arraybuffer二进制数据。 + */ + static BUFFER:string; + + /** + * 纹理类型,加载完成后返回Texture。 + */ + static IMAGE:string; + + /** + * 声音类型,加载完成后返回sound。 + */ + static SOUND:string; + + /** + * 图集类型,加载完成后返回图集json信息(并创建图集内小图Texture)。 + */ + static ATLAS:string; + + /** + * 位图字体类型,加载完成后返回BitmapFont,加载后,会根据文件名自动注册为位图字体。 + */ + static FONT:string; + + /** + * TTF字体类型,加载完成后返回null。 + */ + static TTF:string; + + /** + * 预加载文件类型,加载完成后自动解析到preLoadedMap。 + */ + static PLF:string; + + /** + * 二进制预加载文件类型,加载完成后自动解析到preLoadedMap。 + */ + static PLFB:string; + + /** + * Hierarchy资源。 + */ + static HIERARCHY:string; + + /** + * Mesh资源。 + */ + static MESH:string; + + /** + * Material资源。 + */ + static MATERIAL:string; + + /** + * Texture2D资源。 + */ + static TEXTURE2D:string; + + /** + * TextureCube资源。 + */ + static TEXTURECUBE:string; + + /** + * AnimationClip资源。 + */ + static ANIMATIONCLIP:string; + + /** + * Avatar资源。 + */ + static AVATAR:string; + + /** + * Terrain资源。 + */ + static TERRAINHEIGHTDATA:string; + + /** + * Terrain资源。 + */ + static TERRAINRES:string; + + /** + * 文件后缀和类型对应表。 + */ + static typeMap:{[key:string]:string;}; + + /** + * 资源解析函数对应表,用来扩展更多类型的资源加载解析。 + */ + static parserMap:any; + + /** + * 每帧加载完成回调使用的最大超时时间,如果超时,则下帧再处理,防止帧卡顿。 + */ + static maxTimeOut:number; + + /** + * 资源分组对应表。 + */ + static groupMap:{[key:string]:string[];}; + + /** + * 已加载的资源池。 + */ + static loadedMap:{[key:string]:any;}; + + /** + * 已加载的图集资源池。 + */ + static atlasMap:{[key:string]:any[];}; + + /** + * 已加载的纹理资源池。 + */ + static textureMap:{[key:string]:Texture;}; + + /** + * @private 已加载的数据文件。 + */ + static preLoadedMap:{[key:string]:ArrayBuffer;}; + + /** + * @private 引用image对象,防止垃圾回收 + */ + protected static _imgCache:{[key:string]:HTMLImageElement;}; + + /** + * @private + */ + protected static _loaders:Loader[]; + + /** + * @private + */ + protected static _isWorking:boolean; + + /** + * @private + */ + protected static _startIndex:number; + + /** + * 获取指定资源地址的数据类型。 + * @param url 资源地址。 + * @return 数据类型。 + */ + static getTypeFromUrl(url:string):string; + + /** + * @private + */ + protected _url:string; + + /** + * @private + */ + protected _type:string; + + /** + * @private + */ + protected _http:HttpRequest; + + /** + * @private + */ + protected _useWorkerLoader:boolean; + + /** + * 加载资源。加载错误会派发 Event.ERROR 事件,参数为错误信息。 + * @param url 资源地址。 + * @param type (default = null)资源类型。可选值为:Loader.TEXT、Loader.JSON、Loader.XML、Loader.BUFFER、Loader.IMAGE、Loader.SOUND、Loader.ATLAS、Loader.FONT。如果为null,则根据文件后缀分析类型。 + * @param cache (default = true)是否缓存数据。 + * @param group (default = null)分组名称。 + * @param ignoreCache (default = false)是否忽略缓存,强制重新加载。 + * @param useWorkerLoader (default = false)是否使用worker加载(只针对IMAGE类型和ATLAS类型,并且浏览器支持的情况下生效) + */ + load(url:string,type?:string|null,cache?:boolean,group?:string|null,ignoreCache?:boolean,useWorkerLoader?:boolean):void; + + /** + * @private onload、onprocess、onerror必须写在本类 + */ + private _loadHttpRequest:any; + + /** + * @private + */ + private _loadHtmlImage:any; + + /** + * @private 加载TTF资源。 + * @param url 资源地址。 + */ + protected _loadTTF(url:string):void; + + /** + * @private + */ + protected _loadImage(url:string,isformatURL?:boolean):void; + + /** + * @private + */ + protected onProgress(value:number):void; + + /** + * @private + */ + protected onError(message:string):void; + + /** + * 资源加载完成的处理函数。 + * @param data 数据。 + */ + protected onLoaded(data?:any):void; + private parsePLFData:any; + private parsePLFBData:any; + private parseOnePLFBFile:any; + + /** + * 加载完成。 + * @param data 加载的数据。 + */ + protected complete(data:any):void; + + /** + * @private + */ + private static checkNext:any; + + /** + * 结束加载,处理是否缓存及派发完成事件 Event.COMPLETE 。 + * @param content 加载后的数据 + */ + endLoad(content?:any):void; + + /** + * 加载地址。 + */ + get url():string; + + /** + * 加载类型。 + */ + get type():string; + + /** + * 是否缓存。 + */ + get cache():boolean; + + /** + * 返回的数据。 + */ + get data():any; + + /** + * 清理指定资源地址的缓存。 + * @param url 资源地址。 + */ + static clearRes(url:string):void; + + /** + * 销毁Texture使用的图片资源,保留texture壳,如果下次渲染的时候,发现texture使用的图片资源不存在,则会自动恢复 + * 相比clearRes,clearTextureRes只是清理texture里面使用的图片资源,并不销毁texture,再次使用到的时候会自动恢复图片资源 + * 而clearRes会彻底销毁texture,导致不能再使用;clearTextureRes能确保立即销毁图片资源,并且不用担心销毁错误,clearRes则采用引用计数方式销毁 + * 【注意】如果图片本身在自动合集里面(默认图片小于512*512),内存是不能被销毁的,此图片被大图合集管理器管理 + * @param url 图集地址或者texture地址,比如 Loader.clearTextureRes("res/atlas/comp.atlas"); Loader.clearTextureRes("hall/bg.jpg"); + */ + static clearTextureRes(url:string):void; + + /** + * 获取指定资源地址的资源或纹理。 + * @param url 资源地址。 + * @return 返回资源。 + */ + static getRes(url:string):any; + + /** + * 获取指定资源地址的图集地址列表。 + * @param url 图集地址。 + * @return 返回地址集合。 + */ + static getAtlas(url:string):any[]; + + /** + * 缓存资源。 + * 如果资源已经存在则缓存失败。 + * @param url 资源地址。 + * @param data 要缓存的内容。 + */ + static cacheRes(url:string,data:any):void; + + /** + * 强制缓存资源。不做任何检查。 + * @param url 资源地址。 + * @param data 要缓存的内容。 + */ + static cacheResForce(url:string,data:any):void; + + /** + * 缓存Teture。 + * @param url 资源地址。 + * @param data 要缓存的Texture。 + */ + static cacheTexture(url:string,data:Texture):void; + + /** + * 设置资源分组。 + * @param url 资源地址。 + * @param group 分组名。 + */ + static setGroup(url:string,group:string):void; + + /** + * 根据分组清理资源。 + * @param group 分组名。 + */ + static clearResByGroup(group:string):void; + } + + /** + * 所有资源加载完成时调度。 + * @eventType Event.COMPLETE + */ + + /** + * 任何资源加载出错时调度。 + * @eventType Event.ERROR + */ + + /** + *

    LoaderManager 类用于用于批量加载资源。此类是单例,不要手动实例化此类,请通过Laya.loader访问。

    + *

    全部队列加载完成,会派发 Event.COMPLETE 事件;如果队列中任意一个加载失败,会派发 Event.ERROR 事件,事件回调参数值为加载出错的资源地址。

    + *

    LoaderManager 类提供了以下几种功能:
    + * 多线程:默认5个加载线程,可以通过maxLoader属性修改线程数量;
    + * 多优先级:有0-4共5个优先级,优先级高的优先加载。0最高,4最低;
    + * 重复过滤:自动过滤重复加载(不会有多个相同地址的资源同时加载)以及复用缓存资源,防止重复加载;
    + * 错误重试:资源加载失败后,会重试加载(以最低优先级插入加载队列),retryNum设定加载失败后重试次数,retryDelay设定加载重试的时间间隔。

    + * @see laya.net.Loader + */ + class LoaderManager extends EventDispatcher { + + /** + * @private + */ + private static _resMap:any; + + /** + * @private + */ + static createMap:any; + + /** + * 加载出错后的重试次数,默认重试一次 + */ + retryNum:number; + + /** + * 延迟时间多久再进行错误重试,默认立即重试 + */ + retryDelay:number; + + /** + * 最大下载线程,默认为5个 + */ + maxLoader:number; + + /** + * @private + */ + private _loaders:any; + + /** + * @private + */ + private _loaderCount:any; + + /** + * @private + */ + private _resInfos:any; + + /** + * @private + */ + private _infoPool:any; + + /** + * @private + */ + private _maxPriority:any; + + /** + * @private + */ + private _failRes:any; + + /** + * @private + */ + private _statInfo:any; + + /** + * @private + */ + getProgress():number; + + /** + * @private + */ + resetProgress():void; + + /** + *

    创建一个新的 LoaderManager 实例。

    + *

    注意:请使用Laya.loader加载资源,这是一个单例,不要手动实例化此类,否则会导致不可预料的问题。

    + */ + + constructor(); + + /** + *

    根据clas类型创建一个未初始化资源的对象,随后进行异步加载,资源加载完成后,初始化对象的资源,并通过此对象派发 Event.LOADED 事件,事件回调参数值为此对象本身。套嵌资源的子资源会保留资源路径"?"后的部分。

    + *

    如果url为数组,返回true;否则返回指定的资源类对象,可以通过侦听此对象的 Event.LOADED 事件来判断资源是否已经加载完毕。

    + *

    注意:cache参数只能对文件后缀为atlas的资源进行缓存控制,其他资源会忽略缓存,强制重新加载。

    + * @param url 资源地址或者数组。如果url和clas同时指定了资源类型,优先使用url指定的资源类型。参数形如:[{url:xx,clas:xx,priority:xx,params:xx},{url:xx,clas:xx,priority:xx,params:xx}]。 + * @param complete 加载结束回调。根据url类型不同分为2种情况:1. url为String类型,也就是单个资源地址,如果加载成功,则回调参数值为加载完成的资源,否则为null;2. url为数组类型,指定了一组要加载的资源,如果全部加载成功,则回调参数值为true,否则为false。 + * @param progress 资源加载进度回调,回调参数值为当前资源加载的进度信息(0-1)。 + * @param type 资源类型。 + * @param constructParams 资源构造函数参数。 + * @param propertyParams 资源属性参数。 + * @param priority (default = 1)加载的优先级,优先级高的优先加载。有0-4共5个优先级,0最高,4最低。 + * @param cache 是否缓存加载的资源。 + * @return 如果url为数组,返回true;否则返回指定的资源类对象。 + */ + create(url:string|(string | createItem)[],complete?:Handler|null,progress?:Handler|null,type?:string|null,constructParams?:any[]|null,propertyParams?:any,priority?:number,cache?:boolean):void; + + /** + * @private + */ + private _createOne:any; + + /** + *

    加载资源。资源加载错误时,本对象会派发 Event.ERROR 事件,事件回调参数值为加载出错的资源地址。

    + *

    因为返回值为 LoaderManager 对象本身,所以可以使用如下语法:loaderManager.load(...).load(...);

    + * @param url 要加载的单个资源地址或资源信息数组。比如:简单数组:["a.png","b.png"];复杂数组[{url:"a.png",type:Loader.IMAGE,size:100,priority:1},{url:"b.json",type:Loader.JSON,size:50,priority:1}]。 + * @param complete 加载结束回调。根据url类型不同分为2种情况:1. url为String类型,也就是单个资源地址,如果加载成功,则回调参数值为加载完成的资源,否则为null;2. url为数组类型,指定了一组要加载的资源,如果全部加载成功,则回调参数值为true,否则为false。 + * @param progress 加载进度回调。回调参数值为当前资源的加载进度信息(0-1)。 + * @param type 资源类型。比如:Loader.IMAGE。 + * @param priority (default = 1)加载的优先级,优先级高的优先加载。有0-4共5个优先级,0最高,4最低。 + * @param cache 是否缓存加载结果。 + * @param group 分组,方便对资源进行管理。 + * @param ignoreCache 是否忽略缓存,强制重新加载。 + * @param useWorkerLoader (default = false)是否使用worker加载(只针对IMAGE类型和ATLAS类型,并且浏览器支持的情况下生效) + * @return 此 LoaderManager 对象本身。 + */ + load(url:string|(string | loadItem)[],complete?:Handler|null,progress?:Handler|null,type?:string|null,priority?:number,cache?:boolean,group?:string|null,ignoreCache?:boolean,useWorkerLoader?:boolean):LoaderManager; + private _resInfoLoaded:any; + private _next:any; + private _doLoad:any; + private _endLoad:any; + private _addReTry:any; + + /** + * 清理指定资源地址缓存。 + * @param url 资源地址。 + */ + clearRes(url:string):void; + + /** + * 销毁Texture使用的图片资源,保留texture壳,如果下次渲染的时候,发现texture使用的图片资源不存在,则会自动恢复 + * 相比clearRes,clearTextureRes只是清理texture里面使用的图片资源,并不销毁texture,再次使用到的时候会自动恢复图片资源 + * 而clearRes会彻底销毁texture,导致不能再使用;clearTextureRes能确保立即销毁图片资源,并且不用担心销毁错误,clearRes则采用引用计数方式销毁 + * 【注意】如果图片本身在自动合集里面(默认图片小于512*512),内存是不能被销毁的,此图片被大图合集管理器管理 + * @param url 图集地址或者texture地址,比如 Loader.clearTextureRes("res/atlas/comp.atlas"); Loader.clearTextureRes("hall/bg.jpg"); + */ + clearTextureRes(url:string):void; + + /** + * 获取指定资源地址的资源。 + * @param url 资源地址。 + * @return 返回资源。 + */ + getRes(url:string):any; + + /** + * 缓存资源。 + * @param url 资源地址。 + * @param data 要缓存的内容。 + */ + cacheRes(url:string,data:any):void; + + /** + * 设置资源分组。 + * @param url 资源地址。 + * @param group 分组名 + */ + setGroup(url:string,group:string):void; + + /** + * 根据分组清理资源。 + * @param group 分组名 + */ + clearResByGroup(group:string):void; + + /** + * @private 缓存资源。 + * @param url 资源地址。 + * @param data 要缓存的内容。 + */ + static cacheRes(url:string,data:any):void; + + /** + * 清理当前未完成的加载,所有未加载的内容全部停止加载。 + */ + clearUnLoaded():void; + + /** + * 根据地址集合清理掉未加载的内容 + * @param urls 资源地址集合 + */ + cancelLoadByUrls(urls:any[]):void; + + /** + * 根据地址清理掉未加载的内容 + * @param url 资源地址 + */ + cancelLoadByUrl(url:string):void; + + /** + * @private 加载数组里面的资源。 + * @param arr 简单:["a.png","b.png"],复杂[{url:"a.png",type:Loader.IMAGE,size:100,priority:1,useWorkerLoader:true},{url:"b.json",type:Loader.JSON,size:50,priority:1}] + */ + private _loadAssets:any; + + /** + * 解码Texture或者图集 + * @param urls texture地址或者图集地址集合 + */ + decodeBitmaps(urls:any[]):void; + private _decodeTexture:any; + } + + interface loadItem{ + } + + + interface createItem{ + url:string; + + /** + * 资源类型 + */ + type?:string; + priority?:number; + group?:string; + + /** + * 资源属性参数。 + */ + propertyParams?:any[]; + + /** + * 资源构造函数参数。 + */ + constructParams?:any[]; + progress?:number; + } + + + /** + *

    LocalStorage 类用于没有时间限制的数据存储。

    + */ + class LocalStorage { + + /** + * @ 基础类 + */ + static _baseClass:any; + + /** + * 数据列表。 + */ + static items:any; + + /** + * 表示是否支持 LocalStorage。 + */ + static support:boolean; + + /** + * 存储指定键名和键值,字符串类型。 + * @param key 键名。 + * @param value 键值。 + */ + static setItem(key:string,value:string):void; + + /** + * 获取指定键名的值。 + * @param key 键名。 + * @return 字符串型值。 + */ + static getItem(key:string):string; + + /** + * 存储指定键名及其对应的 Object 类型值。 + * @param key 键名。 + * @param value 键值。是 Object 类型,此致会被转化为 JSON 字符串存储。 + */ + static setJSON(key:string,value:any):void; + + /** + * 获取指定键名对应的 Object 类型值。 + * @param key 键名。 + * @return Object 类型值 + */ + static getJSON(key:string):any; + + /** + * 删除指定键名的信息。 + * @param key 键名。 + */ + static removeItem(key:string):void; + + /** + * 清除本地存储信息。 + */ + static clear():void; + } + + /** + *

    资源版本的生成由layacmd或IDE完成,使用 ResourceVersion 简化使用过程。

    + *

    调用 enable 启用资源版本管理。

    + */ + class ResourceVersion { + + /** + * 基于文件夹的资源管理方式(老版本IDE默认类型) + */ + static FOLDER_VERSION:number; + + /** + * 基于文件名映射管理方式(新版本IDE默认类型) + */ + static FILENAME_VERSION:number; + + /** + * 版本清单 + */ + static manifest:any; + + /** + * 当前使用的版本管理类型 + */ + static type:number; + + /** + *

    启用资源版本管理。

    + *

    由于只有发布版本需要资源管理。因此没有资源管理文件时,可以设置manifestFile为null或者不存在的路径。

    + * @param manifestFile 清单(json)文件的路径。 + * @param callback 清单(json)文件加载完成后执行。 + * @param type FOLDER_VERSION为基于文件夹管理方式(老版本IDE默认类型),FILENAME_VERSION为基于文件名映射管理(新版本IDE默认类型 + */ + static enable(manifestFile:string,callback:Handler,type?:number):void; + private static onManifestLoaded:any; + + /** + * 为加载路径添加版本前缀。 + * @param originURL 源路径。 + * @return 格式化后的新路径。 + */ + static addVersionPrefix(originURL:string):string; + } + + /** + * @private 场景资源加载器 + */ + class SceneLoader extends EventDispatcher { + static LoadableExtensions:any; + static No3dLoadTypes:any; + totalCount:number; + private _completeHandler:any; + private _toLoadList:any; + private _isLoading:any; + private _curUrl:any; + + constructor(); + reset():void; + get leftCount():number; + get loadedCount():number; + load(url:any,is3D?:boolean,ifCheck?:boolean):void; + private _addToLoadList:any; + private _checkNext:any; + private loadOne:any; + private onOneLoadComplete:any; + getProgress():number; + } + + /** + * 连接建立成功后调度。 + * @eventType Event.OPEN + */ + + /** + * 接收到数据后调度。 + * @eventType Event.MESSAGE + */ + + /** + * 连接被关闭后调度。 + * @eventType Event.CLOSE + */ + + /** + * 出现异常后调度。 + * @eventType Event.ERROR + */ + + /** + *

    Socket 封装了 HTML5 WebSocket ,允许服务器端与客户端进行全双工(full-duplex)的实时通信,并且允许跨域通信。在建立连接后,服务器和 Browser/Client Agent 都能主动的向对方发送或接收文本和二进制数据。

    + *

    要使用 Socket 类的方法,请先使用构造函数 new Socket 创建一个 Socket 对象。 Socket 以异步方式传输和接收数据。

    + */ + class Socket extends EventDispatcher { + + /** + *

    主机字节序,是 CPU 存放数据的两种不同顺序,包括小端字节序和大端字节序。

    + *

    LITTLE_ENDIAN :小端字节序,地址低位存储值的低位,地址高位存储值的高位。

    + *

    BIG_ENDIAN :大端字节序,地址低位存储值的高位,地址高位存储值的低位。有时也称之为网络字节序。

    + */ + static LITTLE_ENDIAN:string; + + /** + *

    主机字节序,是 CPU 存放数据的两种不同顺序,包括小端字节序和大端字节序。

    + *

    BIG_ENDIAN :大端字节序,地址低位存储值的高位,地址高位存储值的低位。有时也称之为网络字节序。

    + *

    LITTLE_ENDIAN :小端字节序,地址低位存储值的低位,地址高位存储值的高位。

    + */ + static BIG_ENDIAN:string; + + /** + * @private + */ + protected _socket:any; + + /** + * @private + */ + private _connected:any; + + /** + * @private + */ + private _addInputPosition:any; + + /** + * @private + */ + private _input:any; + + /** + * @private + */ + private _output:any; + + /** + * 不再缓存服务端发来的数据,如果传输的数据为字符串格式,建议设置为true,减少二进制转换消耗。 + */ + disableInput:boolean; + + /** + * 用来发送和接收数据的 Byte 类。 + */ + private _byteClass:any; + + /** + *

    子协议名称。子协议名称字符串,或由多个子协议名称字符串构成的数组。必须在调用 connect 或者 connectByUrl 之前进行赋值,否则无效。

    + *

    指定后,只有当服务器选择了其中的某个子协议,连接才能建立成功,否则建立失败,派发 Event.ERROR 事件。

    + * @see https://html.spec.whatwg.org/multipage/comms.html#dom-websocket + */ + protocols:any; + + /** + * 缓存的服务端发来的数据。 + */ + get input():any; + + /** + * 表示需要发送至服务端的缓冲区中的数据。 + */ + get output():any; + + /** + * 表示此 Socket 对象目前是否已连接。 + */ + get connected():boolean; + + /** + *

    主机字节序,是 CPU 存放数据的两种不同顺序,包括小端字节序和大端字节序。

    + *

    LITTLE_ENDIAN :小端字节序,地址低位存储值的低位,地址高位存储值的高位。

    + *

    BIG_ENDIAN :大端字节序,地址低位存储值的高位,地址高位存储值的低位。

    + */ + get endian():string; + set endian(value:string); + + /** + *

    创建新的 Socket 对象。默认字节序为 Socket.BIG_ENDIAN 。若未指定参数,将创建一个最初处于断开状态的套接字。若指定了有效参数,则尝试连接到指定的主机和端口。

    + * @param host 服务器地址。 + * @param port 服务器端口。 + * @param byteClass 用于接收和发送数据的 Byte 类。如果为 null ,则使用 Byte 类,也可传入 Byte 类的子类。 + * @param protocols 子协议名称。子协议名称字符串,或由多个子协议名称字符串构成的数组 + * @see laya.utils.Byte + */ + + constructor(host?:string|null,port?:number,byteClass?:new () => any,protocols?:any[]|null); + + /** + *

    连接到指定的主机和端口。

    + *

    连接成功派发 Event.OPEN 事件;连接失败派发 Event.ERROR 事件;连接被关闭派发 Event.CLOSE 事件;接收到数据派发 Event.MESSAGE 事件; 除了 Event.MESSAGE 事件参数为数据内容,其他事件参数都是原生的 HTML DOM Event 对象。

    + * @param host 服务器地址。 + * @param port 服务器端口。 + */ + connect(host:string,port:number):void; + + /** + *

    连接到指定的服务端 WebSocket URL。 URL 类似 ws://yourdomain:port。

    + *

    连接成功派发 Event.OPEN 事件;连接失败派发 Event.ERROR 事件;连接被关闭派发 Event.CLOSE 事件;接收到数据派发 Event.MESSAGE 事件; 除了 Event.MESSAGE 事件参数为数据内容,其他事件参数都是原生的 HTML DOM Event 对象。

    + * @param url 要连接的服务端 WebSocket URL。 URL 类似 ws://yourdomain:port。 + */ + connectByUrl(url:string):void; + + /** + * 清理Socket:关闭Socket链接,关闭事件监听,重置Socket + */ + cleanSocket():void; + + /** + * 关闭连接。 + */ + close():void; + + /** + * @private 连接建立成功 。 + */ + protected _onOpen(e:any):void; + + /** + * @private 接收到数据处理方法。 + * @param msg 数据。 + */ + protected _onMessage(msg:any):void; + + /** + * @private 连接被关闭处理方法。 + */ + protected _onClose(e:any):void; + + /** + * @private 出现异常处理方法。 + */ + protected _onError(e:any):void; + + /** + * 发送数据到服务器。 + * @param data 需要发送的数据,可以是String或者ArrayBuffer。 + */ + send(data:any):void; + + /** + * 发送缓冲区中的数据到服务器。 + */ + flush():void; + } + + /** + * @private + */ + class TTFLoader { + private static _testString:any; + fontName:string; + complete:Handler|null; + err:Handler|null; + private _fontTxt:any; + private _url:any; + private _div:any; + private _txtWidth:any; + private _http:any; + load(fontPath:string):void; + private _loadConch:any; + private _onHttpLoaded:any; + private _clearHttp:any; + private _onErr:any; + private _complete:any; + private _checkComplete:any; + private _loadWithFontFace:any; + private _createDiv:any; + private _loadWithCSS:any; + } + + /** + *

    URL 提供URL格式化,URL版本管理的类。

    + *

    引擎加载资源的时候,会自动调用formatURL函数格式化URL路径

    + *

    通过basePath属性可以设置网络基础路径

    + *

    通过设置customFormat函数,可以自定义URL格式化的方式

    + *

    除了默认的通过增加后缀的格式化外,通过VersionManager类,可以开启IDE提供的,基于目录的管理方式来替代 "?v=" 的管理方式

    + * @see laya.net.VersionManager + */ + class URL { + + /** + * URL地址版本映射表,比如{"aaa/bb.png":99,"aaa/bb.png":12},默认情况下,通过formatURL格式化后,会自动生成为"aaa/bb.png?v=99"的一个地址 + */ + static version:any; + + /** + * @private + */ + private _url:any; + + /** + * @private + */ + private _path:any; + + /** + * 兼容微信不支持加载scene后缀场景,设置为true,则会把scene加载替换为json + */ + static exportSceneToJson:boolean; + + /** + * 创建一个新的 URL 实例。 + */ + + constructor(url:string); + + /** + * 格式化后的地址。 + */ + get url():string; + + /** + * 地址的文件夹路径(不包括文件名)。 + */ + get path():string; + + /** + * root路径。只针对'~'类型的url路径有效 + */ + static rootPath:string; + static set basePath(value:string); + + /** + * 基础路径。如果不设置,默认为当前网页的路径。最终地址将被格式化为 basePath+相对URL地址, + */ + static get basePath():string; + + /** + * 自定义URL格式化的方式。例如: customFormat = function(url:String):String{} + */ + static customFormat:Function; + + /** + * 格式化指定的地址并返回。 + * @param url 地址。 + * @param base 基础路径,如果没有,则使用basePath。 + * @return 格式化处理后的地址。 + */ + static formatURL(url:string):string; + + /** + * 获取指定 URL 的文件夹路径(不包括文件名)。 + *

    注意:末尾有斜杠(/)。

    + * @param url url地址。 + * @return 返回文件夹路径。 + */ + static getPath(url:string):string; + + /** + * 获取指定 URL 的文件名。 + * @param url 地址。 + * @return 返回文件名。 + */ + static getFileName(url:string):string; + + /** + * @private + */ + private static _adpteTypeList:any; + + /** + * @private 兼容微信 + */ + static getAdptedFilePath(url:string):string; + } + + /** + * @private Worker Image加载器 + */ + class WorkerLoader extends EventDispatcher { + + /** + * 单例 + */ + static I:WorkerLoader; + + /** + * worker.js的路径 + */ + static workerPath:string; + + /** + * @private + */ + private static _preLoadFun:any; + + /** + * @private + */ + private static _enable:any; + + /** + * @private + */ + private static _tryEnabled:any; + + /** + * 使用的Worker对象。 + */ + worker:Worker; + + /** + * @private + */ + protected _useWorkerLoader:boolean; + + constructor(); + + /** + * 是否支持worker + * @return 是否支持worker + */ + static workerSupported():boolean; + + /** + * 尝试启用WorkerLoader,只有第一次调用有效 + */ + static enableWorkerLoader():void; + + /** + * 是否启用。 + */ + static set enable(value:boolean); + static get enable():boolean; + + /** + * @private + */ + private workerMessage:any; + + /** + * @private + */ + private imageLoaded:any; + + /** + * 加载图片 + * @param url 图片地址 + */ + loadImage(url:string):void; + + /** + * @private 加载图片资源。 + * @param url 资源地址。 + */ + protected _loadImage(url:string):void; + } + + /** + * @private + */ + class Emitter2D extends EmitterBase { + setting:ParticleSetting; + private _posRange:any; + private _canvasTemplate:any; + private _emitFun:any; + + constructor(_template:ParticleTemplateBase); + set template(template:ParticleTemplateBase); + get template():ParticleTemplateBase; + + /** + * @override + */ + emit():void; + getRandom(value:number):number; + webGLEmit():void; + canvasEmit():void; + } + + /** + * EmitterBase 类是粒子发射器类 + */ + class EmitterBase { + + /** + * 积累的帧时间 + */ + protected _frameTime:number; + + /** + * 粒子发射速率 + */ + protected _emissionRate:number; + + /** + * 当前剩余发射时间 + */ + protected _emissionTime:number; + + /** + * 发射粒子最小时间间隔 + */ + minEmissionTime:number; + + /** + * 设置粒子粒子模板 + * @param particleTemplate 粒子模板 + */ + set particleTemplate(particleTemplate:ParticleTemplateBase); + + /** + * 设置粒子发射速率 + * @param emissionRate 粒子发射速率 (个/秒) + */ + set emissionRate(_emissionRate:number); + + /** + * 获取粒子发射速率 + * @return 发射速率 粒子发射速率 (个/秒) + */ + get emissionRate():number; + + /** + * 开始发射粒子 + * @param duration 发射持续的时间(秒) + */ + start(duration?:number):void; + + /** + * 停止发射粒子 + * @param clearParticles 是否清理当前的粒子 + */ + stop():void; + + /** + * 清理当前的活跃粒子 + * @param clearTexture 是否清理贴图数据,若清除贴图数据将无法再播放 + */ + clear():void; + + /** + * 发射一个粒子 + */ + emit():void; + + /** + * 时钟前进 + * @param passedTime 前进时间 + */ + advanceTime(passedTime?:number):void; + } + + /** + * Particle2D 类是2D粒子播放类 + */ + class Particle2D extends Sprite { + + /** + * @private + */ + private _matrix4:any; + + /** + * @private + */ + private _particleTemplate:any; + + /** + * @private + */ + private _canvasTemplate:any; + + /** + * @private + */ + private _emitter:any; + + /** + * 是否自动播放 + */ + autoPlay:boolean; + tempCmd:any; + + /** + * 创建一个新的 Particle2D 类实例。 + * @param setting 粒子配置数据 + */ + + constructor(setting:ParticleSetting); + + /** + * 设置 粒子文件地址 + * @param path 粒子文件地址 + */ + set url(url:string); + + /** + * 加载粒子文件 + * @param url 粒子文件地址 + */ + load(url:string):void; + + /** + * 设置粒子配置数据 + * @param settings 粒子配置数据 + */ + setParticleSetting(setting:ParticleSetting):void; + + /** + * 获取粒子发射器 + */ + get emitter():EmitterBase; + + /** + * 播放 + */ + play():void; + + /** + * 停止 + */ + stop():void; + + /** + * @private + */ + private _loop:any; + + /** + * 时钟前进 + * @param passedTime 时钟前进时间 + */ + advanceTime(passedTime?:number):void; + + /** + * @param context + * @param x + * @param y + * @override + */ + customRender(context:Context,x:number,y:number):void; + + /** + * @param destroyChild + * @override + */ + destroy(destroyChild?:boolean):void; + } + + /** + * @private + */ + class ParticleData { + private static _tempVelocity:any; + private static _tempStartColor:any; + private static _tempEndColor:any; + private static _tempSizeRotation:any; + private static _tempRadius:any; + private static _tempRadian:any; + position:Float32Array; + velocity:Float32Array; + startColor:Float32Array; + endColor:Float32Array; + sizeRotation:Float32Array; + radius:Float32Array; + radian:Float32Array; + durationAddScale:number; + time:number; + + constructor(); + static Create(settings:ParticleSetting,position:Float32Array,velocity:Float32Array,time:number):ParticleData; + } + + /** + * @private + */ + class ParticleEmitter { + private _templet:any; + private _timeBetweenParticles:any; + private _previousPosition:any; + private _timeLeftOver:any; + private _tempVelocity:any; + private _tempPosition:any; + + constructor(templet:ParticleTemplateBase,particlesPerSecond:number,initialPosition:Float32Array); + update(elapsedTime:number,newPosition:Float32Array):void; + } + + /** + * ParticleSettings 类是粒子配置数据类 + */ + class ParticleSetting { + + /** + * 贴图 + */ + textureName:string; + + /** + * 贴图个数,默认为1可不设置 + */ + textureCount:number; + + /** + * 由于循环队列判断算法,最大饱和粒子数为maxPartices-1 + */ + maxPartices:number; + + /** + * 粒子持续时间(单位:秒) + */ + duration:number; + + /** + * 如果大于0,某些粒子的持续时间会小于其他粒子,并具有随机性(单位:无) + */ + ageAddScale:number; + + /** + * 粒子受发射器速度的敏感度(需在自定义发射器中编码设置) + */ + emitterVelocitySensitivity:number; + + /** + * 最小开始尺寸(单位:2D像素、3D坐标) + */ + minStartSize:number; + + /** + * 最大开始尺寸(单位:2D像素、3D坐标) + */ + maxStartSize:number; + + /** + * 最小结束尺寸(单位:2D像素、3D坐标) + */ + minEndSize:number; + + /** + * 最大结束尺寸(单位:2D像素、3D坐标) + */ + maxEndSize:number; + + /** + * 最小水平速度(单位:2D像素、3D坐标) + */ + minHorizontalVelocity:number; + + /** + * 最大水平速度(单位:2D像素、3D坐标) + */ + maxHorizontalVelocity:number; + + /** + * 最小垂直速度(单位:2D像素、3D坐标) + */ + minVerticalVelocity:number; + + /** + * 最大垂直速度(单位:2D像素、3D坐标) + */ + maxVerticalVelocity:number; + + /** + * 等于1时粒子从出生到消亡保持一致的速度,等于0时粒子消亡时速度为0,大于1时粒子会保持加速(单位:无) + */ + endVelocity:number; + + /** + * (单位:2D像素、3D坐标) + */ + gravity:Float32Array; + + /** + * 最小旋转速度(单位:2D弧度/秒、3D弧度/秒) + */ + minRotateSpeed:number; + + /** + * 最大旋转速度(单位:2D弧度/秒、3D弧度/秒) + */ + maxRotateSpeed:number; + + /** + * 最小开始半径(单位:2D像素、3D坐标) + */ + minStartRadius:number; + + /** + * 最大开始半径(单位:2D像素、3D坐标) + */ + maxStartRadius:number; + + /** + * 最小结束半径(单位:2D像素、3D坐标) + */ + minEndRadius:number; + + /** + * 最大结束半径(单位:2D像素、3D坐标) + */ + maxEndRadius:number; + + /** + * 最小水平开始弧度(单位:2D弧度、3D弧度) + */ + minHorizontalStartRadian:number; + + /** + * 最大水平开始弧度(单位:2D弧度、3D弧度) + */ + maxHorizontalStartRadian:number; + + /** + * 最小垂直开始弧度(单位:2D弧度、3D弧度) + */ + minVerticalStartRadian:number; + + /** + * 最大垂直开始弧度(单位:2D弧度、3D弧度) + */ + maxVerticalStartRadian:number; + + /** + * 是否使用结束弧度,false为结束时与起始弧度保持一致,true为根据minHorizontalEndRadian、maxHorizontalEndRadian、minVerticalEndRadian、maxVerticalEndRadian计算结束弧度。 + */ + useEndRadian:boolean; + + /** + * 最小水平结束弧度(单位:2D弧度、3D弧度) + */ + minHorizontalEndRadian:number; + + /** + * 最大水平结束弧度(单位:2D弧度、3D弧度) + */ + maxHorizontalEndRadian:number; + + /** + * 最小垂直结束弧度(单位:2D弧度、3D弧度) + */ + minVerticalEndRadian:number; + + /** + * 最大垂直结束弧度(单位:2D弧度、3D弧度) + */ + maxVerticalEndRadian:number; + + /** + * 最小开始颜色 + */ + minStartColor:Float32Array; + + /** + * 最大开始颜色 + */ + maxStartColor:Float32Array; + + /** + * 最小结束颜色 + */ + minEndColor:Float32Array; + + /** + * 最大结束颜色 + */ + maxEndColor:Float32Array; + + /** + * false代表RGBA整体插值,true代表RGBA逐分量插值 + */ + colorComponentInter:boolean; + + /** + * false代表使用参数颜色数据,true代表使用原图颜色数据 + */ + disableColor:boolean; + + /** + * 混合模式,待调整,引擎中暂无BlendState抽象 + */ + blendState:number; + + /** + * 发射器类型,"point","box","sphere","ring" + */ + emitterType:string; + + /** + * 发射器发射速率 + */ + emissionRate:number; + + /** + * 点发射器位置 + */ + pointEmitterPosition:Float32Array; + + /** + * 点发射器位置随机值 + */ + pointEmitterPositionVariance:Float32Array; + + /** + * 点发射器速度 + */ + pointEmitterVelocity:Float32Array; + + /** + * 点发射器速度随机值 + */ + pointEmitterVelocityAddVariance:Float32Array; + + /** + * 盒发射器中心位置 + */ + boxEmitterCenterPosition:Float32Array; + + /** + * 盒发射器尺寸 + */ + boxEmitterSize:Float32Array; + + /** + * 盒发射器速度 + */ + boxEmitterVelocity:Float32Array; + + /** + * 盒发射器速度随机值 + */ + boxEmitterVelocityAddVariance:Float32Array; + + /** + * 球发射器中心位置 + */ + sphereEmitterCenterPosition:Float32Array; + + /** + * 球发射器半径 + */ + sphereEmitterRadius:number; + + /** + * 球发射器速度 + */ + sphereEmitterVelocity:number; + + /** + * 球发射器速度随机值 + */ + sphereEmitterVelocityAddVariance:number; + + /** + * 环发射器中心位置 + */ + ringEmitterCenterPosition:Float32Array; + + /** + * 环发射器半径 + */ + ringEmitterRadius:number; + + /** + * 环发射器速度 + */ + ringEmitterVelocity:number; + + /** + * 环发射器速度随机值 + */ + ringEmitterVelocityAddVariance:number; + + /** + * 环发射器up向量,0代表X轴,1代表Y轴,2代表Z轴 + */ + ringEmitterUp:number; + + /** + * 发射器位置随机值,2D使用 + */ + positionVariance:Float32Array; + + /** + * 创建一个新的 ParticleSettings 类实例。 + */ + + constructor(); + private static _defaultSetting:any; + static checkSetting(setting:any):void; + } + + /** + * ParticleTemplateBase 类是粒子模板基类 + */ + class ParticleTemplateBase { + + /** + * 粒子配置数据 + */ + settings:ParticleSetting; + + /** + * 粒子贴图 + */ + protected texture:Texture; + + /** + * 创建一个新的 ParticleTemplateBase 类实例。 + */ + + constructor(); + + /** + * 添加一个粒子 + * @param position 粒子位置 + * @param velocity 粒子速度 + */ + addParticleArray(position:Float32Array,velocity:Float32Array):void; + } + + /** + * @private + */ + class ParticleTemplateWebGL extends ParticleTemplateBase { + protected _vertices:Float32Array; + protected _mesh:MeshParticle2D; + protected _conchMesh:any; + protected _floatCountPerVertex:number; + protected _firstActiveElement:number; + protected _firstNewElement:number; + protected _firstFreeElement:number; + protected _firstRetiredElement:number; + protected _drawCounter:number; + + constructor(parSetting:ParticleSetting); + reUse(context:Context,pos:number):number; + protected initialize():void; + update(elapsedTime:number):void; + private retireActiveParticles:any; + private freeRetiredParticles:any; + addNewParticlesToVertexBuffer():void; + + /** + * @param position + * @param velocity + * @override + */ + addParticleArray(position:Float32Array,velocity:Float32Array):void; + } + + /** + * @private + */ + class ParticleShader extends Shader { + static vs:string; + static ps:string; + + constructor(); + } + + /** + * 2D矩形碰撞体 + */ + class BoxCollider extends ColliderBase { + + /** + * 相对节点的x轴偏移 + */ + private _x:any; + + /** + * 相对节点的y轴偏移 + */ + private _y:any; + + /** + * 矩形宽度 + */ + private _width:any; + + /** + * 矩形高度 + */ + private _height:any; + + /** + * @override + */ + protected getDef():any; + private _setShape:any; + + /** + * 相对节点的x轴偏移 + */ + get x():number; + set x(value:number); + + /** + * 相对节点的y轴偏移 + */ + get y():number; + set y(value:number); + + /** + * 矩形宽度 + */ + get width():number; + set width(value:number); + + /** + * 矩形高度 + */ + get height():number; + set height(value:number); + + /** + * @private 重置形状 + * @override + */ + resetShape(re?:boolean):void; + } + + /** + * 2D线形碰撞体 + */ + class ChainCollider extends ColliderBase { + + /** + * 相对节点的x轴偏移 + */ + private _x:any; + + /** + * 相对节点的y轴偏移 + */ + private _y:any; + + /** + * 用逗号隔开的点的集合,格式:x,y,x,y ... + */ + private _points:any; + + /** + * 是否是闭环,注意不要有自相交的链接形状,它可能不能正常工作 + */ + private _loop:any; + + /** + * @override + */ + protected getDef():any; + private _setShape:any; + + /** + * 相对节点的x轴偏移 + */ + get x():number; + set x(value:number); + + /** + * 相对节点的y轴偏移 + */ + get y():number; + set y(value:number); + + /** + * 用逗号隔开的点的集合,格式:x,y,x,y ... + */ + get points():string; + set points(value:string); + + /** + * 是否是闭环,注意不要有自相交的链接形状,它可能不能正常工作 + */ + get loop():boolean; + set loop(value:boolean); + } + + /** + * 2D圆形碰撞体 + */ + class CircleCollider extends ColliderBase { + + /** + * @private + */ + private static _temp:any; + + /** + * 相对节点的x轴偏移 + */ + private _x:any; + + /** + * 相对节点的y轴偏移 + */ + private _y:any; + + /** + * 圆形半径,必须为正数 + */ + private _radius:any; + + /** + * @override + */ + protected getDef():any; + private _setShape:any; + + /** + * 相对节点的x轴偏移 + */ + get x():number; + set x(value:number); + + /** + * 相对节点的y轴偏移 + */ + get y():number; + set y(value:number); + + /** + * 圆形半径,必须为正数 + */ + get radius():number; + set radius(value:number); + + /** + * @private 重置形状 + * @override + */ + resetShape(re?:boolean):void; + } + + /** + * 碰撞体基类 + */ + class ColliderBase extends Component { + + /** + * 是否是传感器,传感器能够触发碰撞事件,但不会产生碰撞反应 + */ + private _isSensor:any; + + /** + * 密度值,值可以为零或者是正数,建议使用相似的密度,这样做可以改善堆叠稳定性,默认值为10 + */ + private _density:any; + + /** + * 摩擦力,取值范围0-1,值越大,摩擦越大,默认值为0.2 + */ + private _friction:any; + + /** + * 弹性系数,取值范围0-1,值越大,弹性越大,默认值为0 + */ + private _restitution:any; + + /** + * 标签 + */ + label:string; + + /** + * @private b2Shape对象 + */ + protected _shape:any; + + /** + * @private b2FixtureDef对象 + */ + protected _def:any; + + /** + * [只读]b2Fixture对象 + */ + fixture:any; + + /** + * [只读]刚体引用 + */ + rigidBody:RigidBody; + + /** + * @private 获取碰撞体信息 + */ + protected getDef():any; + private _checkRigidBody:any; + + /** + * 是否是传感器,传感器能够触发碰撞事件,但不会产生碰撞反应 + */ + get isSensor():boolean; + set isSensor(value:boolean); + + /** + * 密度值,值可以为零或者是正数,建议使用相似的密度,这样做可以改善堆叠稳定性,默认值为10 + */ + get density():number; + set density(value:number); + + /** + * 摩擦力,取值范围0-1,值越大,摩擦越大,默认值为0.2 + */ + get friction():number; + set friction(value:number); + + /** + * 弹性系数,取值范围0-1,值越大,弹性越大,默认值为0 + */ + get restitution():number; + set restitution(value:number); + + /** + * @private 碰撞体参数发生变化后,刷新物理世界碰撞信息 + */ + refresh():void; + + /** + * @private 重置形状 + */ + resetShape(re?:boolean):void; + + /** + * 获取是否为单实例组件。 + * @override + */ + get isSingleton():boolean; + } + + /** + * JS实现Box2D SayGoodbyeParticle + * 相关类型对象被隐性移除时触发对应的SayGoodBye方法 + */ + class DestructionListener { + + /** + * Joint被隐性移除时触发 + * @param params box2d的Joint相关对象 + */ + SayGoodbyeJoint(params:any):void; + + /** + * Fixtures被隐性移除时触发 + * @param params box2d的Fixtures相关对象 + */ + SayGoodbyeFixture(params:any):void; + + /** + * ParticleGroup被隐性移除时触发 + * @param params box2d的ParticleGroup相关对象 + */ + SayGoodbyeParticleGroup(params:any):void; + + /** + * Particle被隐性移除时触发 + * @param params box2d的Particle相关对象 + */ + SayGoodbyeParticle(params:any):void; + } + + /** + * 2D边框碰撞体 + */ + class EdgeCollider extends ColliderBase { + + /** + * 相对节点的x轴偏移 + */ + private _x:any; + + /** + * 相对节点的y轴偏移 + */ + private _y:any; + + /** + * 用逗号隔开的点的集合,注意只有两个点,格式:x,y,x,y + */ + private _points:any; + + /** + * @override + */ + protected getDef():any; + private _setShape:any; + + /** + * 相对节点的x轴偏移 + */ + get x():number; + set x(value:number); + + /** + * 相对节点的y轴偏移 + */ + get y():number; + set y(value:number); + + /** + * 用逗号隔开的点的集合,注意只有两个点,格式:x,y,x,y + */ + get points():string; + set points(value:string); + } + + /** + * 距离关节:两个物体上面各自有一点,两点之间的距离固定不变 + */ + class DistanceJoint extends JointBase { + + /** + * @private + */ + private static _temp:any; + + /** + * [首次设置有效]关节的自身刚体 + */ + selfBody:RigidBody; + + /** + * [首次设置有效]关节的连接刚体,可不设置,默认为左上角空刚体 + */ + otherBody:RigidBody; + + /** + * [首次设置有效]自身刚体链接点,是相对于自身刚体的左上角位置偏移 + */ + selfAnchor:any[]; + + /** + * [首次设置有效]链接刚体链接点,是相对于otherBody的左上角位置偏移 + */ + otherAnchor:any[]; + + /** + * [首次设置有效]两个刚体是否可以发生碰撞,默认为false + */ + collideConnected:boolean; + + /** + * 约束的目标静止长度 + */ + private _length:any; + + /** + * 约束的最小长度,-1表示使用默认值 + */ + private _maxLength:any; + + /** + * 约束的最大长度,-1表示使用默认值 + */ + private _minLength:any; + + /** + * 弹簧系统的震动频率,可以视为弹簧的弹性系数,通常频率应该小于时间步长频率的一半 + */ + private _frequency:any; + + /** + * 刚体在回归到节点过程中受到的阻尼比,建议取值0~1 + */ + private _dampingRatio:any; + + /** + * @override + */ + protected _createJoint():void; + + /** + * 约束的目标静止长度 + */ + get length():number; + set length(value:number); + + /** + * 约束的最小长度 + */ + get minLength():number; + set minLength(value:number); + + /** + * 约束的最大长度 + */ + get maxLength():number; + set maxLength(value:number); + + /** + * 弹簧系统的震动频率,可以视为弹簧的弹性系数,通常频率应该小于时间步长频率的一半 + */ + get frequency():number; + set frequency(value:number); + + /** + * 刚体在回归到节点过程中受到的阻尼比,建议取值0~1 + */ + get damping():number; + set damping(value:number); + } + + /** + * 齿轮关节:用来模拟两个齿轮间的约束关系,齿轮旋转时,产生的动量有两种输出方式,一种是齿轮本身的角速度,另一种是齿轮表面的线速度 + */ + class GearJoint extends JointBase { + + /** + * @private + */ + private static _temp:any; + + /** + * [首次设置有效]要绑定的第1个关节,类型可以是RevoluteJoint或者PrismaticJoint + */ + joint1:any; + + /** + * [首次设置有效]要绑定的第2个关节,类型可以是RevoluteJoint或者PrismaticJoint + */ + joint2:any; + + /** + * [首次设置有效]两个刚体是否可以发生碰撞,默认为false + */ + collideConnected:boolean; + + /** + * 两个齿轮角速度比例,默认1 + */ + private _ratio:any; + + /** + * @override + */ + protected _createJoint():void; + + /** + * 两个齿轮角速度比例,默认1 + */ + get ratio():number; + set ratio(value:number); + } + + /** + * 关节基类 + */ + class JointBase extends Component { + + /** + * 原生关节对象 + */ + protected _joint:any; + + /** + * [只读]原生关节对象 + */ + get joint():any; + protected _createJoint():void; + + /** + * 获取是否为单实例组件。 + * @override + */ + get isSingleton():boolean; + } + + /** + * 马达关节:用来限制两个刚体,使其相对位置和角度保持不变 + */ + class MotorJoint extends JointBase { + + /** + * @private + */ + private static _temp:any; + + /** + * [首次设置有效]关节的自身刚体 + */ + selfBody:RigidBody; + + /** + * [首次设置有效]关节的连接刚体 + */ + otherBody:RigidBody; + + /** + * [首次设置有效]两个刚体是否可以发生碰撞,默认为false + */ + collideConnected:boolean; + + /** + * 基于otherBody坐标位置的偏移量,也是selfBody的目标位置 + */ + private _linearOffset:any; + + /** + * 基于otherBody的角度偏移量,也是selfBody的目标角度 + */ + private _angularOffset:any; + + /** + * 当selfBody偏离目标位置时,为使其恢复到目标位置,马达关节所施加的最大作用力 + */ + private _maxForce:any; + + /** + * 当selfBody角度与目标角度不同时,为使其达到目标角度,马达关节施加的最大扭力 + */ + private _maxTorque:any; + + /** + * selfBody向目标位置移动时的缓动因子,取值0~1,值越大速度越快 + */ + private _correctionFactor:any; + + /** + * @override + */ + protected _createJoint():void; + + /** + * 基于otherBody坐标位置的偏移量,也是selfBody的目标位置 + */ + get linearOffset():any[]; + set linearOffset(value:any[]); + + /** + * 基于otherBody的角度偏移量,也是selfBody的目标角度 + */ + get angularOffset():number; + set angularOffset(value:number); + + /** + * 当selfBody偏离目标位置时,为使其恢复到目标位置,马达关节所施加的最大作用力 + */ + get maxForce():number; + set maxForce(value:number); + + /** + * 当selfBody角度与目标角度不同时,为使其达到目标角度,马达关节施加的最大扭力 + */ + get maxTorque():number; + set maxTorque(value:number); + + /** + * selfBody向目标位置移动时的缓动因子,取值0~1,值越大速度越快 + */ + get correctionFactor():number; + set correctionFactor(value:number); + } + + /** + * 鼠标关节:鼠标关节用于通过鼠标来操控物体。它试图将物体拖向当前鼠标光标的位置。而在旋转方面就没有限制。 + */ + class MouseJoint extends JointBase { + + /** + * @private + */ + private static _temp:any; + + /** + * [首次设置有效]关节的自身刚体 + */ + selfBody:RigidBody; + + /** + * [首次设置有效]关节的链接点,是相对于自身刚体的左上角位置偏移,如果不设置,则根据鼠标点击点作为连接点 + */ + anchor:any[]; + + /** + * 鼠标关节在拖曳刚体bodyB时施加的最大作用力 + */ + private _maxForce:any; + + /** + * 弹簧系统的震动频率,可以视为弹簧的弹性系数,通常频率应该小于时间步长频率的一半 + */ + private _frequency:any; + + /** + * 刚体在回归到节点过程中受到的阻尼比,建议取值0~1 + */ + private _dampingRatio:any; + private onMouseDown:any; + + /** + * @override + */ + protected _createJoint():void; + private onStageMouseUp:any; + private onMouseMove:any; + + /** + * 鼠标关节在拖曳刚体bodyB时施加的最大作用力 + */ + get maxForce():number; + set maxForce(value:number); + + /** + * 弹簧系统的震动频率,可以视为弹簧的弹性系数,通常频率应该小于时间步长频率的一半 + */ + get frequency():number; + set frequency(value:number); + + /** + * 刚体在回归到节点过程中受到的阻尼比,建议取值0~1 + */ + get damping():number; + set damping(value:number); + } + + /** + * 平移关节:移动关节允许两个物体沿指定轴相对移动,它会阻止相对旋转 + */ + class PrismaticJoint extends JointBase { + + /** + * @private + */ + private static _temp:any; + + /** + * [首次设置有效]关节的自身刚体 + */ + selfBody:RigidBody; + + /** + * [首次设置有效]关节的连接刚体,可不设置,默认为左上角空刚体 + */ + otherBody:RigidBody; + + /** + * [首次设置有效]关节的控制点,是相对于自身刚体的左上角位置偏移 + */ + anchor:any[]; + + /** + * [首次设置有效]一个向量值,描述运动方向,比如1,0是沿X轴向右 + */ + axis:any[]; + + /** + * [首次设置有效]两个刚体是否可以发生碰撞,默认为false + */ + collideConnected:boolean; + + /** + * 是否开启马达,开启马达可使目标刚体运动 + */ + private _enableMotor:any; + + /** + * 启用马达后,在axis坐标轴上移动可以达到的最大速度 + */ + private _motorSpeed:any; + + /** + * 启用马达后,可以施加的最大作用力 + */ + private _maxMotorForce:any; + + /** + * 是否对刚体的移动范围加以约束 + */ + private _enableLimit:any; + + /** + * 启用约束后,刚体移动范围的下限,是距离anchor的偏移量 + */ + private _lowerTranslation:any; + + /** + * 启用约束后,刚体移动范围的上限,是距离anchor的偏移量 + */ + private _upperTranslation:any; + + /** + * @override + */ + protected _createJoint():void; + + /** + * 是否开启马达,开启马达可使目标刚体运动 + */ + get enableMotor():boolean; + set enableMotor(value:boolean); + + /** + * 启用马达后,在axis坐标轴上移动可以达到的最大速度 + */ + get motorSpeed():number; + set motorSpeed(value:number); + + /** + * 启用马达后,可以施加的最大作用力 + */ + get maxMotorForce():number; + set maxMotorForce(value:number); + + /** + * 是否对刚体的移动范围加以约束 + */ + get enableLimit():boolean; + set enableLimit(value:boolean); + + /** + * 启用约束后,刚体移动范围的下限,是距离anchor的偏移量 + */ + get lowerTranslation():number; + set lowerTranslation(value:number); + + /** + * 启用约束后,刚体移动范围的上限,是距离anchor的偏移量 + */ + get upperTranslation():number; + set upperTranslation(value:number); + } + + /** + * 滑轮关节:它将两个物体接地(ground)并彼此连接,当一个物体上升,另一个物体就会下降 + */ + class PulleyJoint extends JointBase { + + /** + * @private + */ + private static _temp:any; + + /** + * [首次设置有效]关节的自身刚体 + */ + selfBody:RigidBody; + + /** + * [首次设置有效]关节的连接刚体 + */ + otherBody:RigidBody; + + /** + * [首次设置有效]自身刚体链接点,是相对于自身刚体的左上角位置偏移 + */ + selfAnchor:any[]; + + /** + * [首次设置有效]链接刚体链接点,是相对于otherBody的左上角位置偏移 + */ + otherAnchor:any[]; + + /** + * [首次设置有效]滑轮上与节点selfAnchor相连接的节点,是相对于自身刚体的左上角位置偏移 + */ + selfGroundPoint:any[]; + + /** + * [首次设置有效]滑轮上与节点otherAnchor相连接的节点,是相对于otherBody的左上角位置偏移 + */ + otherGroundPoint:any[]; + + /** + * [首次设置有效]两刚体移动距离比率 + */ + ratio:number; + + /** + * [首次设置有效]两个刚体是否可以发生碰撞,默认为false + */ + collideConnected:boolean; + + /** + * @override + */ + protected _createJoint():void; + } + + /** + * 旋转关节强制两个物体共享一个锚点,两个物体相对旋转 + */ + class RevoluteJoint extends JointBase { + + /** + * @private + */ + private static _temp:any; + + /** + * [首次设置有效]关节的自身刚体 + */ + selfBody:RigidBody; + + /** + * [首次设置有效]关节的连接刚体,可不设置 + */ + otherBody:RigidBody; + + /** + * [首次设置有效]关节的链接点,是相对于自身刚体的左上角位置偏移 + */ + anchor:any[]; + + /** + * [首次设置有效]两个刚体是否可以发生碰撞,默认为false + */ + collideConnected:boolean; + + /** + * 是否开启马达,开启马达可使目标刚体运动 + */ + private _enableMotor:any; + + /** + * 启用马达后,可以达到的最大旋转速度 + */ + private _motorSpeed:any; + + /** + * 启用马达后,可以施加的最大扭距,如果最大扭矩太小,会导致不旋转 + */ + private _maxMotorTorque:any; + + /** + * 是否对刚体的旋转范围加以约束 + */ + private _enableLimit:any; + + /** + * 启用约束后,刚体旋转范围的下限弧度 + */ + private _lowerAngle:any; + + /** + * 启用约束后,刚体旋转范围的上限弧度 + */ + private _upperAngle:any; + + /** + * @override + */ + protected _createJoint():void; + + /** + * 是否开启马达,开启马达可使目标刚体运动 + */ + get enableMotor():boolean; + set enableMotor(value:boolean); + + /** + * 启用马达后,可以达到的最大旋转速度 + */ + get motorSpeed():number; + set motorSpeed(value:number); + + /** + * 启用马达后,可以施加的最大扭距,如果最大扭矩太小,会导致不旋转 + */ + get maxMotorTorque():number; + set maxMotorTorque(value:number); + + /** + * 是否对刚体的旋转范围加以约束 + */ + get enableLimit():boolean; + set enableLimit(value:boolean); + + /** + * 启用约束后,刚体旋转范围的下限弧度 + */ + get lowerAngle():number; + set lowerAngle(value:number); + + /** + * 启用约束后,刚体旋转范围的上限弧度 + */ + get upperAngle():number; + set upperAngle(value:number); + } + + /** + * 焊接关节:焊接关节的用途是使两个物体不能相对运动,受到关节的限制,两个刚体的相对位置和角度都保持不变,看上去像一个整体 + */ + class WeldJoint extends JointBase { + + /** + * @private + */ + private static _temp:any; + + /** + * [首次设置有效]关节的自身刚体 + */ + selfBody:RigidBody; + + /** + * [首次设置有效]关节的连接刚体 + */ + otherBody:RigidBody; + + /** + * [首次设置有效]关节的链接点,是相对于自身刚体的左上角位置偏移 + */ + anchor:any[]; + + /** + * [首次设置有效]两个刚体是否可以发生碰撞,默认为false + */ + collideConnected:boolean; + + /** + * 弹簧系统的震动频率,可以视为弹簧的弹性系数,通常频率应该小于时间步长频率的一半 + */ + private _frequency:any; + + /** + * 刚体在回归到节点过程中受到的阻尼比,建议取值0~1 + */ + private _dampingRatio:any; + + /** + * @override + */ + protected _createJoint():void; + + /** + * 弹簧系统的震动频率,可以视为弹簧的弹性系数,通常频率应该小于时间步长频率的一半 + */ + get frequency():number; + set frequency(value:number); + + /** + * 刚体在回归到节点过程中受到的阻尼比,建议取值0~1 + */ + get damping():number; + set damping(value:number); + } + + /** + * 轮子关节:围绕节点旋转,包含弹性属性,使得刚体在节点位置发生弹性偏移 + */ + class WheelJoint extends JointBase { + + /** + * @private + */ + private static _temp:any; + + /** + * [首次设置有效]关节的自身刚体 + */ + selfBody:RigidBody; + + /** + * [首次设置有效]关节的连接刚体 + */ + otherBody:RigidBody; + + /** + * [首次设置有效]关节的链接点,是相对于自身刚体的左上角位置偏移 + */ + anchor:any[]; + + /** + * [首次设置有效]两个刚体是否可以发生碰撞,默认为false + */ + collideConnected:boolean; + + /** + * [首次设置有效]一个向量值,描述运动方向,比如1,0是沿X轴向右 + */ + axis:any[]; + + /** + * 弹簧系统的震动频率,可以视为弹簧的弹性系数,通常频率应该小于时间步长频率的一半 + */ + private _frequency:any; + + /** + * 刚体在回归到节点过程中受到的阻尼比,建议取值0~1 + */ + private _dampingRatio:any; + + /** + * 是否开启马达,开启马达可使目标刚体运动 + */ + private _enableMotor:any; + + /** + * 启用马达后,可以达到的最大旋转速度 + */ + private _motorSpeed:any; + + /** + * 启用马达后,可以施加的最大扭距,如果最大扭矩太小,会导致不旋转 + */ + private _maxMotorTorque:any; + + /** + * 是否对刚体的移动范围加以约束 + */ + private _enableLimit:any; + + /** + * 启用约束后,刚体移动范围的下限,是距离anchor的偏移量 + */ + private _lowerTranslation:any; + + /** + * 启用约束后,刚体移动范围的上限,是距离anchor的偏移量 + */ + private _upperTranslation:any; + + /** + * @override + */ + protected _createJoint():void; + + /** + * 弹簧系统的震动频率,可以视为弹簧的弹性系数,通常频率应该小于时间步长频率的一半 + */ + get frequency():number; + set frequency(value:number); + + /** + * 刚体在回归到节点过程中受到的阻尼比,建议取值0~1 + */ + get damping():number; + set damping(value:number); + + /** + * 是否开启马达,开启马达可使目标刚体运动 + */ + get enableMotor():boolean; + set enableMotor(value:boolean); + + /** + * 启用马达后,可以达到的最大旋转速度 + */ + get motorSpeed():number; + set motorSpeed(value:number); + + /** + * 启用马达后,可以施加的最大扭距,如果最大扭矩太小,会导致不旋转 + */ + get maxMotorTorque():number; + set maxMotorTorque(value:number); + + /** + * 是否对刚体的移动范围加以约束 + */ + get enableLimit():boolean; + set enableLimit(value:boolean); + + /** + * 启用约束后,刚体移动范围的下限,是距离anchor的偏移量 + */ + get lowerTranslation():number; + set lowerTranslation(value:number); + + /** + * 启用约束后,刚体移动范围的上限,是距离anchor的偏移量 + */ + get upperTranslation():number; + set upperTranslation(value:number); + } + + /** + * 2D物理引擎,使用Box2d驱动 + */ + class Physics extends EventDispatcher { + + /** + * 2D游戏默认单位为像素,物理默认单位为米,此值设置了像素和米的转换比率,默认50像素=1米 + */ + static PIXEL_RATIO:number; + + /** + * @private + */ + private static _I:any; + + /** + * Box2d引擎的全局引用,更多属性和api请参考 http://box2d.org + */ + box2d:any; + + /** + * [只读]物理世界引用,更多属性请参考官网 + */ + world:any; + + /** + * 旋转迭代次数,增大数字会提高精度,但是会降低性能 + */ + velocityIterations:number; + + /** + * 位置迭代次数,增大数字会提高精度,但是会降低性能 + */ + positionIterations:number; + + /** + * @private 是否已经激活 + */ + private _enabled:any; + + /** + * @private 根容器 + */ + private _worldRoot:any; + + /** + * @private 空的body节点,给一些不需要节点的关节使用 + */ + _emptyBody:any; + + /** + * @private + */ + _eventList:any[]; + + /** + * 全局物理单例 + */ + static get I():Physics; + + constructor(); + + /** + * 开启物理世界 + * options值参考如下: + * allowSleeping:true, + * gravity:10, + * customUpdate:false 自己控制物理更新时机,自己调用Physics.update + */ + static enable(options?:any):void; + + /** + * 开启物理世界 + * options值参考如下: + * allowSleeping:true, + * gravity:10, + * customUpdate:false 自己控制物理更新时机,自己调用Physics.update + */ + start(options?:any):void; + private _update:any; + private _sendEvent:any; + + /** + * @private + */ + _createBody(def:any):any; + + /** + * @private + */ + _removeBody(body:any):void; + + /** + * @private + */ + _createJoint(def:any):any; + + /** + * @private + */ + _removeJoint(joint:any):void; + + /** + * 停止物理世界 + */ + stop():void; + + /** + * 设置是否允许休眠,休眠可以提高稳定性和性能,但通常会牺牲准确性 + */ + get allowSleeping():boolean; + set allowSleeping(value:boolean); + + /** + * 物理世界重力环境,默认值为{x:0,y:1} + * 如果修改y方向重力方向向上,可以直接设置gravity.y=-1; + */ + get gravity():any; + set gravity(value:any); + + /** + * 获得刚体总数量 + */ + getBodyCount():number; + + /** + * 获得碰撞总数量 + */ + getContactCount():number; + + /** + * 获得关节总数量 + */ + getJointCount():number; + + /** + * 物理世界根容器,将根据此容器作为物理世界坐标世界,进行坐标变换,默认值为stage + * 设置特定容器后,就可整体位移物理对象,保持物理世界不变。 + * 注意,仅会在 set worldRoot 时平移一次,其他情况请配合 updatePhysicsByWorldRoot 函数使用 + */ + get worldRoot():Sprite; + set worldRoot(value:Sprite); + + /** + * 设定 worldRoot 后,手动触发物理世界更新 + */ + updatePhysicsByWorldRoot():void; + } + + /** + * 物理辅助线,调用PhysicsDebugDraw.enable()开启,或者通过IDE设置打开 + */ + class PhysicsDebugDraw extends Sprite { + + /** + * @private + */ + m_drawFlags:number; + + /** + * @private + */ + static box2d:any; + + /** + * @private + */ + static DrawString_s_color:any; + + /** + * @private + */ + static DrawStringWorld_s_p:any; + + /** + * @private + */ + static DrawStringWorld_s_cc:any; + + /** + * @private + */ + static DrawStringWorld_s_color:any; + + /** + * @private + */ + world:any; + + /** + * @private + */ + private _camera:any; + + /** + * @private + */ + private static _canvas:any; + + /** + * @private + */ + private static _inited:any; + + /** + * @private + */ + private _mG:any; + + /** + * @private + */ + private _textSp:any; + + /** + * @private + */ + private _textG:any; + + /** + * @private + */ + static init():void; + + constructor(); + + /** + * @private + * @override + */ + render(ctx:Context,x:number,y:number):void; + + /** + * @private + */ + private lineWidth:any; + + /** + * @private + */ + private _renderToGraphic:any; + + /** + * @private + */ + SetFlags(flags:number):void; + + /** + * @private + */ + GetFlags():number; + + /** + * @private + */ + AppendFlags(flags:number):void; + + /** + * @private + */ + ClearFlags(flags:any):void; + + /** + * @private + */ + PushTransform(xf:any):void; + + /** + * @private + */ + PopTransform(xf:any):void; + + /** + * @private + */ + DrawPolygon(vertices:any,vertexCount:any,color:any):void; + + /** + * @private + */ + DrawSolidPolygon(vertices:any,vertexCount:any,color:any):void; + + /** + * @private + */ + DrawCircle(center:any,radius:any,color:any):void; + + /** + * @private + */ + DrawSolidCircle(center:any,radius:any,axis:any,color:any):void; + + /** + * @private + */ + DrawParticles(centers:any,radius:any,colors:any,count:any):void; + + /** + * @private + */ + DrawSegment(p1:any,p2:any,color:any):void; + + /** + * @private + */ + DrawTransform(xf:any):void; + + /** + * @private + */ + DrawPoint(p:any,size:any,color:any):void; + + /** + * @private + */ + DrawString(x:any,y:any,message:any):void; + + /** + * @private + */ + DrawStringWorld(x:any,y:any,message:any):void; + + /** + * @private + */ + DrawAABB(aabb:any,color:any):void; + + /** + * @private + */ + static I:PhysicsDebugDraw; + + /** + * 激活物理辅助线 + * @param flags 位标记值,其值是AND的结果,其值有-1:显示形状,2:显示关节,4:显示AABB包围盒,8:显示broad-phase pairs,16:显示质心 + * @return 返回一个Sprite对象,本对象用来显示物理辅助线 + */ + static enable(flags?:number):PhysicsDebugDraw; + } + + /** + * 2D多边形碰撞体,暂时不支持凹多边形,如果是凹多边形,先手动拆分为多个凸多边形 + * 节点个数最多是b2_maxPolygonVertices,这数值默认是8,所以点的数量不建议超过8个,也不能小于3个 + */ + class PolygonCollider extends ColliderBase { + + /** + * 相对节点的x轴偏移 + */ + private _x:any; + + /** + * 相对节点的y轴偏移 + */ + private _y:any; + + /** + * 用逗号隔开的点的集合,格式:x,y,x,y ... + */ + private _points:any; + + /** + * @override + */ + protected getDef():any; + private _setShape:any; + + /** + * 相对节点的x轴偏移 + */ + get x():number; + set x(value:number); + + /** + * 相对节点的y轴偏移 + */ + get y():number; + set y(value:number); + + /** + * 用逗号隔开的点的集合,格式:x,y,x,y ... + */ + get points():string; + set points(value:string); + } + + /** + * 2D刚体,显示对象通过RigidBody和物理世界进行绑定,保持物理和显示对象之间的位置同步 + * 物理世界的位置变化会自动同步到显示对象,显示对象本身的位移,旋转(父对象位移无效)也会自动同步到物理世界 + * 由于引擎限制,暂时不支持以下情形: + * 1.不支持绑定节点缩放 + * 2.不支持绑定节点的父节点缩放和旋转 + * 3.不支持实时控制父对象位移,IDE内父对象位移是可以的 + * 如果想整体位移物理世界,可以Physics.I.worldRoot=场景,然后移动场景即可 + * 可以通过IDE-"项目设置" 开启物理辅助线显示,或者通过代码PhysicsDebugDraw.enable(); + */ + class RigidBody extends Component { + + /** + * 刚体类型,支持三种类型static,dynamic和kinematic类型,默认为dynamic类型 + * static为静态类型,静止不动,不受重力影响,质量无限大,可以通过节点移动,旋转,缩放进行控制 + * dynamic为动态类型,受重力影响 + * kinematic为运动类型,不受重力影响,可以通过施加速度或者力的方式使其运动 + */ + protected _type:string; + + /** + * 是否允许休眠,允许休眠能提高性能 + */ + protected _allowSleep:boolean; + + /** + * 角速度,设置会导致旋转 + */ + protected _angularVelocity:number; + + /** + * 旋转速度阻尼系数,范围可以在0到无穷大之间,0表示没有阻尼,无穷大表示满阻尼,通常阻尼的值应该在0到0.1之间 + */ + protected _angularDamping:number; + + /** + * 线性运动速度,比如{x:10,y:10} + */ + protected _linearVelocity:any; + + /** + * 线性速度阻尼系数,范围可以在0到无穷大之间,0表示没有阻尼,无穷大表示满阻尼,通常阻尼的值应该在0到0.1之间 + */ + protected _linearDamping:number; + + /** + * 是否高速移动的物体,设置为true,可以防止高速穿透 + */ + protected _bullet:boolean; + + /** + * 是否允许旋转,如果不希望刚体旋转,这设置为false + */ + protected _allowRotation:boolean; + + /** + * 重力缩放系数,设置为0为没有重力 + */ + protected _gravityScale:number; + + /** + * [只读] 指定了该主体所属的碰撞组,默认为0,碰撞规则如下: + * 1.如果两个对象group相等 + * group值大于零,它们将始终发生碰撞 + * group值小于零,它们将永远不会发生碰撞 + * group值等于0,则使用规则3 + * 2.如果group值不相等,则使用规则3 + * 3.每个刚体都有一个category类别,此属性接收位字段,范围为[1,2^31]范围内的2的幂 + * 每个刚体也都有一个mask类别,指定与其碰撞的类别值之和(值是所有category按位AND的值) + */ + group:number; + + /** + * [只读]碰撞类别,使用2的幂次方值指定,有32种不同的碰撞类别可用 + */ + category:number; + + /** + * [只读]指定冲突位掩码碰撞的类别,category位操作的结果 + */ + mask:number; + + /** + * [只读]自定义标签 + */ + label:string; + + /** + * [只读]原始刚体 + */ + protected _body:any; + private _createBody:any; + + /** + * 获取对象某属性的get set方法 + * 通过其本身无法获取该方法,只能从原型上获取 + * @param obj + * @param prop + * @param accessor + */ + private accessGetSetFunc:any; + + /** + * 重置Collider + * @param resetShape 是否先重置形状,比如缩放导致碰撞体变化 + */ + private resetCollider:any; + + /** + * @private 同步物理坐标到游戏坐标 + */ + private _sysPhysicToNode:any; + + /** + * @private 同步节点坐标及旋转到物理世界 + */ + private _sysNodeToPhysic:any; + + /** + * @private 同步节点坐标到物理世界 + */ + private _sysPosToPhysic:any; + + /** + * @private + */ + private _overSet:any; + + /** + * 获得原始body对象 + */ + getBody():any; + _getOriBody():any; + + /** + * [只读]获得原始body对象 + */ + get body():any; + + /** + * 对刚体施加力 + * @param position 施加力的点,如{x:100,y:100},全局坐标 + * @param force 施加的力,如{x:0.1,y:0.1} + */ + applyForce(position:any,force:any):void; + + /** + * 从中心点对刚体施加力,防止对象旋转 + * @param force 施加的力,如{x:0.1,y:0.1} + */ + applyForceToCenter(force:any):void; + + /** + * 施加速度冲量,添加的速度冲量会与刚体原有的速度叠加,产生新的速度 + * @param position 施加力的点,如{x:100,y:100},全局坐标 + * @param impulse 施加的速度冲量,如{x:0.1,y:0.1} + */ + applyLinearImpulse(position:any,impulse:any):void; + + /** + * 施加速度冲量,添加的速度冲量会与刚体原有的速度叠加,产生新的速度 + * @param impulse 施加的速度冲量,如{x:0.1,y:0.1} + */ + applyLinearImpulseToCenter(impulse:any):void; + + /** + * 对刚体施加扭矩,使其旋转 + * @param torque 施加的扭矩 + */ + applyTorque(torque:number):void; + + /** + * 设置速度,比如{x:10,y:10} + * @param velocity + */ + setVelocity(velocity:any):void; + + /** + * 设置角度 + * @param value 单位为弧度 + */ + setAngle(value:any):void; + + /** + * 获得刚体质量 + */ + getMass():number; + + /** + * 获得质心的相对节点0,0点的位置偏移 + */ + getCenter():any; + + /** + * 获得质心的世界坐标,相对于Physics.I.worldRoot节点 + */ + getWorldCenter():any; + + /** + * 刚体类型,支持三种类型static,dynamic和kinematic类型 + * static为静态类型,静止不动,不受重力影响,质量无限大,可以通过节点移动,旋转,缩放进行控制 + * dynamic为动态类型,接受重力影响 + * kinematic为运动类型,不受重力影响,可以通过施加速度或者力的方式使其运动 + */ + get type():string; + set type(value:string); + + /** + * 重力缩放系数,设置为0为没有重力 + */ + get gravityScale():number; + set gravityScale(value:number); + + /** + * 是否允许旋转,如果不希望刚体旋转,这设置为false + */ + get allowRotation():boolean; + set allowRotation(value:boolean); + + /** + * 是否允许休眠,允许休眠能提高性能 + */ + get allowSleep():boolean; + set allowSleep(value:boolean); + + /** + * 旋转速度阻尼系数,范围可以在0到无穷大之间,0表示没有阻尼,无穷大表示满阻尼,通常阻尼的值应该在0到0.1之间 + */ + get angularDamping():number; + set angularDamping(value:number); + + /** + * 角速度,设置会导致旋转 + */ + get angularVelocity():number; + set angularVelocity(value:number); + + /** + * 线性速度阻尼系数,范围可以在0到无穷大之间,0表示没有阻尼,无穷大表示满阻尼,通常阻尼的值应该在0到0.1之间 + */ + get linearDamping():number; + set linearDamping(value:number); + + /** + * 线性运动速度,比如{x:5,y:5} + */ + get linearVelocity():any; + set linearVelocity(value:any); + + /** + * 是否高速移动的物体,设置为true,可以防止高速穿透 + */ + get bullet():boolean; + set bullet(value:boolean); + } + + /** + * Render 是渲染管理类。它是一个单例,可以使用 Laya.render 访问。 + */ + class Render { + static supportWebGLPlusAnimation:boolean; + static supportWebGLPlusRendering:boolean; + + /** + * 是否是加速器 只读 + */ + static isConchApp:boolean; + + /** + * 表示是否是 3D 模式。 + */ + static is3DMode:boolean; + + /** + * 初始化引擎。 + * @param width 游戏窗口宽度。 + * @param height 游戏窗口高度。 + */ + + constructor(width:number,height:number,mainCanv:HTMLCanvas); + + /** + * @private + */ + private _timeId:any; + + /** + * @private + */ + private _onVisibilitychange:any; + initRender(canvas:HTMLCanvas,w:number,h:number):boolean; + + /** + * @private + */ + private _replaceWebglcall:any; + + /** + * @private + */ + private _enterFrame:any; + + /** + * 目前使用的渲染器。 + */ + static get context():Context; + + /** + * 渲染使用的原生画布引用。 + */ + static get canvas():any; + } + + /** + * @author laya + */ + class RenderInfo { + + /** + * 当前帧的开始时间 + */ + static loopStTm:number; + + /** + * 主舞台 Stage 渲染次数计数。 + */ + static loopCount:number; + } + + interface _RenderFunction{ +(sp:Sprite,ctx:Context,x:number,y:number):void } + + + /** + * @private 精灵渲染器 + */ + class RenderSprite { + + /** + * @private + */ + + /** + * @private + */ + + /** + * @private + */ + + /** + * @private + */ + + /** + * @private + */ + + /** + * @private + */ + + /** + * @private + */ + + /** + * @private + */ + + /** + * @private + */ + + /** + * @private + */ + + /** + * @private + */ + + /** + * @private + */ + + /** + * @private + */ + static INIT:number; + + /** + * @private + */ + static renders:RenderSprite[]; + + /** + * @private + */ + protected static NORENDER:RenderSprite; + private static _initRenderFun:any; + private static _getTypeRender:any; + + constructor(type:number,next:RenderSprite|null); + protected onCreate(type:number):void; + static tempUV:any[]; + static tmpTarget(ctx:Context,rt:RenderTexture2D,w:number,h:number):void; + static recycleTarget(rt:RenderTexture2D):void; + static setBlendMode(blendMode:string):void; + } + + /** + * BaseTexture 纹理的父类,抽象类,不允许实例。 + */ + class BaseTexture extends Bitmap { + + /** + * 是否使用mipLevel + */ + get mipmap():boolean; + + /** + * 纹理格式 + */ + get format():number; + + /** + * 纹理横向循环模式。 + */ + get wrapModeU():number; + set wrapModeU(value:number); + + /** + * 纹理纵向循环模式。 + */ + get wrapModeV():number; + set wrapModeV(value:number); + + /** + * 缩小过滤器 + */ + get filterMode():FilterMode; + set filterMode(value:FilterMode); + + /** + * 各向异性等级 + */ + get anisoLevel():number; + set anisoLevel(value:number); + + /** + * 获取mipmap数量。 + */ + get mipmapCount():number; + get defaulteTexture():BaseTexture; + + /** + * 创建一个 BaseTexture 实例。 + */ + + constructor(format:number,mipMap:boolean); + + /** + * 处理资源 + * @inheritDoc + * @override + */ + protected _disposeResource():void; + + /** + * 通过基础数据生成mipMap。 + */ + generateMipmap():void; + + /** + * @deprecated use TextureFormat.FORMAT_R8G8B8 instead. + */ + static FORMAT_R8G8B8:number; + + /** + * @deprecated use TextureFormat.FORMAT_R8G8B8A8 instead. + */ + static FORMAT_R8G8B8A8:number; + + /** + * @deprecated use TextureFormat.FORMAT_ALPHA8 instead. + */ + static FORMAT_ALPHA8:number; + + /** + * @deprecated use TextureFormat.FORMAT_DXT1 instead. + */ + static FORMAT_DXT1:number; + + /** + * @deprecated use TextureFormat.FORMAT_DXT5 instead. + */ + static FORMAT_DXT5:number; + + /** + * @deprecated use TextureFormat.FORMAT_ETC1RGB instead. + */ + static FORMAT_ETC1RGB:number; + + /** + * @deprecated use TextureFormat.FORMAT_PVRTCRGB_2BPPV instead. + */ + static FORMAT_PVRTCRGB_2BPPV:number; + + /** + * @deprecated use TextureFormat.FORMAT_PVRTCRGBA_2BPPV instead. + */ + static FORMAT_PVRTCRGBA_2BPPV:number; + + /** + * @deprecated use TextureFormat.FORMAT_PVRTCRGB_4BPPV instead. + */ + static FORMAT_PVRTCRGB_4BPPV:number; + + /** + * @deprecated use TextureFormat.FORMAT_PVRTCRGBA_4BPPV instead. + */ + static FORMAT_PVRTCRGBA_4BPPV:number; + + /** + * @deprecated use RenderTextureFormat.R16G16B16A16 instead. + */ + static RENDERTEXTURE_FORMAT_RGBA_HALF_FLOAT:number; + + /** + * @deprecated use TextureFormat.R32G32B32A32 instead. + */ + static FORMAT_R32G32B32A32:number; + + /** + * @deprecated use RenderTextureDepthFormat.DEPTH_16 instead. + */ + static FORMAT_DEPTH_16:number; + + /** + * @deprecated use RenderTextureDepthFormat.STENCIL_8 instead. + */ + static FORMAT_STENCIL_8:number; + + /** + * @deprecated use RenderTextureDepthFormat.DEPTHSTENCIL_16_8 instead. + */ + static FORMAT_DEPTHSTENCIL_16_8:number; + + /** + * @deprecated use RenderTextureDepthFormat.DEPTHSTENCIL_NONE instead. + */ + static FORMAT_DEPTHSTENCIL_NONE:number; + + /** + * @deprecated use FilterMode.Point instead. + */ + static FILTERMODE_POINT:number; + + /** + * @deprecated use FilterMode.Bilinear instead. + */ + static FILTERMODE_BILINEAR:number; + + /** + * @deprecated use FilterMode.Trilinear instead. + */ + static FILTERMODE_TRILINEAR:number; + + /** + * @deprecated use WarpMode.Repeat instead. + */ + static WARPMODE_REPEAT:number; + + /** + * @deprecated use WarpMode.Clamp instead. + */ + static WARPMODE_CLAMP:number; + } + + /** + * @private Bitmap 图片资源类。 + */ + class Bitmap extends Resource { + + /** + * @private + */ + protected _width:number; + + /** + * @private + */ + protected _height:number; + + /** + * 获取宽度。 + */ + get width():number; + set width(width:number); + + /** + * * + * 获取高度。 + */ + get height():number; + set height(height:number); + + /** + * 创建一个 Bitmap 实例。 + */ + + constructor(); + } + + /** + * @private Context扩展类 + */ + class Context { + static ENUM_TEXTALIGN_DEFAULT:number; + static ENUM_TEXTALIGN_CENTER:number; + static ENUM_TEXTALIGN_RIGHT:number; + static _SUBMITVBSIZE:number; + static _MAXSIZE:number; + private static _MAXVERTNUM:any; + static MAXCLIPRECT:Rectangle; + static _COUNT:number; + private static SEGNUM:any; + private static _contextcount:any; + private _drawTexToDrawTri_Vert:any; + private _drawTexToDrawTri_Index:any; + private _tempUV:any; + private _drawTriUseAbsMatrix:any; + static __init__():void; + + /** + * @private + */ + drawImage(...args:any[]):void; + + /** + * @private + */ + getImageData(...args:any[]):any; + + /** + * @private + */ + measureText(text:string):any; + + /** + * @private + */ + setTransform(...args:any[]):void; + + /** + * @private + */ + $transform(a:number,b:number,c:number,d:number,tx:number,ty:number):void; + + /** + * @private + */ + get lineJoin():string; + + /** + * @private + */ + set lineJoin(value:string); + + /** + * @private + */ + get lineCap():string; + + /** + * @private + */ + set lineCap(value:string); + + /** + * @private + */ + get miterLimit():string; + + /** + * @private + */ + set miterLimit(value:string); + + /** + * @private + */ + clearRect(x:number,y:number,width:number,height:number):void; + + /** + * @private + */ + + /** + * @private + */ + drawTexture2(x:number,y:number,pivotX:number,pivotY:number,m:Matrix,args2:any[]):void; + transformByMatrix(matrix:Matrix,tx:number,ty:number):void; + saveTransform(matrix:Matrix):void; + restoreTransform(matrix:Matrix):void; + drawRect(x:number,y:number,width:number,height:number,fillColor:any,lineColor:any,lineWidth:number):void; + alpha(value:number):void; + drawCurves(x:number,y:number,points:any[],lineColor:any,lineWidth:number):void; + private _fillAndStroke:any; + + /** + * Math.PI*2的结果缓存 + */ + static PI2:number; + static set2DRenderConfig():void; + private _other:any; + private _renderNextSubmitIndex:any; + private _path:any; + private _width:any; + private _height:any; + private _renderCount:any; + meshlist:any[]; + private _transedPoints:any; + private _temp4Points:any; + private _clipID_Gen:any; + private _lastMat_a:any; + private _lastMat_b:any; + private _lastMat_c:any; + private _lastMat_d:any; + + /** + * 所cacheAs精灵 + * 对于cacheas bitmap的情况,如果图片还没准备好,需要有机会重画,所以要保存sprite。例如在图片 + * 加载完成后,调用repaint + */ + sprite:Sprite|null; + private _fillColor:any; + private _flushCnt:any; + private defTexture:any; + drawTexAlign:boolean; + isMain:boolean; + + constructor(); + clearBG(r:number,g:number,b:number,a:number):void; + + /** + * 释放占用内存 + * @param keepRT 是否保留rendertarget + */ + private _releaseMem:any; + + /** + * 释放所有资源 + * @param keepRT 是否保留rendertarget + */ + destroy(keepRT?:boolean):void; + clear():void; + + /** + * 设置ctx的size,这个不允许直接设置,必须是canvas调过来的。所以这个函数里也不用考虑canvas相关的东西 + * @param w + * @param h + */ + size(w:number,h:number):void; + + /** + * 当前canvas请求保存渲染结果。 + * 实现: + * 如果value==true,就要给_target赋值 + * @param value + */ + set asBitmap(value:boolean); + + /** + * 获得当前矩阵的缩放值 + * 避免每次都计算getScaleX + * @return + */ + getMatScaleX():number; + getMatScaleY():number; + setFillColor(color:number):void; + getFillColor():number; + set fillStyle(value:any); + get fillStyle():any; + set globalAlpha(value:number); + get globalAlpha():number; + set textAlign(value:string); + get textAlign():string; + set textBaseline(value:string); + get textBaseline():string; + set globalCompositeOperation(value:string); + get globalCompositeOperation():string; + set strokeStyle(value:any); + get strokeStyle():any; + translate(x:number,y:number):void; + set lineWidth(value:number); + get lineWidth():number; + save():void; + restore():void; + set font(str:string); + fillText(txt:string|WordText,x:number,y:number,fontStr:string,color:string,align:string,lineWidth?:number,borderColor?:string):void; + drawText(text:string|WordText,x:number,y:number,font:string,color:string,textAlign:string):void; + fillWords(words:HTMLChar[],x:number,y:number,fontStr:string,color:string):void; + strokeWord(text:string|WordText,x:number,y:number,font:string,color:string,lineWidth:number,textAlign:string):void; + fillBorderText(txt:string|WordText,x:number,y:number,font:string,color:string,borderColor:string,lineWidth:number,textAlign:string):void; + fillBorderWords(words:HTMLChar[],x:number,y:number,font:string,color:string,borderColor:string,lineWidth:number):void; + private _fillRect:any; + fillRect(x:number,y:number,width:number,height:number,fillStyle:any):void; + fillTexture(texture:Texture,x:number,y:number,width:number,height:number,type:string,offset:Point,other:any):void; + + /** + * 反正只支持一种filter,就不要叫setFilter了,直接叫setColorFilter + * @param value + */ + setColorFilter(filter:ColorFilter):void; + drawTexture(tex:Texture,x:number,y:number,width:number,height:number):void; + drawTextures(tex:Texture,pos:any[],tx:number,ty:number):void; + + /** + * 为drawTexture添加一个新的submit。类型是 SubmitTexture + * @param vbSize + * @param alpha + * @param webGLImg + * @param tex + */ + private _drawTextureAddSubmit:any; + submitDebugger():void; + private isSameClipInfo:any; + drawCallOptimize(enable:boolean):boolean; + + /** + * 转换4个顶点。为了效率这个不做任何检查。需要调用者的配合。 + * @param a 输入。8个元素表示4个点 + * @param out 输出 + */ + transform4Points(a:any[],m:Matrix,out:any[]):void; + + /** + * pt所描述的多边形完全在clip外边,整个被裁掉了 + * @param pt + * @return + */ + clipedOff(pt:any[]):boolean; + + /** + * 应用当前矩阵。把转换后的位置放到输出数组中。 + * @param x + * @param y + * @param w + * @param h + * @param italicDeg 倾斜角度,单位是度。0度无,目前是下面不动。以后要做成可调的 + */ + transformQuad(x:number,y:number,w:number,h:number,italicDeg:number,m:Matrix,out:any[]):void; + pushRT():void; + popRT():void; + useRT(rt:RenderTexture2D):void; + + /** + * 异步执行rt的restore函数 + * @param rt + */ + RTRestore(rt:RenderTexture2D):void; + + /** + * 强制拒绝submit合并 + * 例如切换rt的时候 + */ + breakNextMerge():void; + private _repaintSprite:any; + + /** + * @param tex + * @param x + * @param y + * @param width + * @param height + * @param transform 图片本身希望的矩阵 + * @param tx 节点的位置 + * @param ty + * @param alpha + */ + drawTextureWithTransform(tex:Texture,x:number,y:number,width:number,height:number,transform:Matrix|null,tx:number,ty:number,alpha:number,blendMode:string|null,colorfilter?:ColorFilter|null,uv?:number[]):void; + + /** + * * 把ctx中的submits提交。结果渲染到target上 + * @param ctx + * @param target + */ + private _flushToTarget:any; + drawCanvas(canvas:HTMLCanvas,x:number,y:number,width:number,height:number):void; + drawTarget(rt:RenderTexture2D,x:number,y:number,width:number,height:number,m:Matrix,shaderValue:Value2D,uv?:ArrayLike|null,blend?:number):boolean; + drawTriangles(tex:Texture,x:number,y:number,vertices:Float32Array,uvs:Float32Array,indices:Uint16Array,matrix:Matrix,alpha:number,color:ColorFilter,blendMode:string,colorNum?:number):void; + transform(a:number,b:number,c:number,d:number,tx:number,ty:number):void; + setTransformByMatrix(value:Matrix):void; + rotate(angle:number):void; + scale(scaleX:number,scaleY:number):void; + clipRect(x:number,y:number,width:number,height:number):void; + + /** + * 从setIBVB改为drawMesh + * type 参数不知道是干什么的,先删掉。offset好像跟attribute有关,删掉 + * @param x + * @param y + * @param ib + * @param vb + * @param numElement + * @param mat + * @param shader + * @param shaderValues + * @param startIndex + * @param offset + */ + drawMesh(x:number,y:number,ib:IndexBuffer2D,vb:VertexBuffer2D,numElement:number,mat:Matrix,shader:Shader,shaderValues:Value2D,startIndex?:number):void; + addRenderObject(o:ISubmit):void; + + /** + * @param start + * @param end + */ + submitElement(start:number,end:number):number; + flush():number; + + /** + * *****************************************start矢量绘制************************************************** + */ + beginPath(convex?:boolean):void; + closePath():void; + + /** + * 添加一个path。 + * @param points [x,y,x,y....] 这个会被保存下来,所以调用者需要注意复制。 + * @param close 是否闭合 + * @param convex 是否是凸多边形。convex的优先级是这个最大。fill的时候的次之。其实fill的时候不应该指定convex,因为可以多个path + * @param dx 需要添加的平移。这个需要在应用矩阵之前应用。 + * @param dy + */ + addPath(points:any[],close:boolean,convex:boolean,dx:number,dy:number):void; + fill():void; + private addVGSubmit:any; + stroke():void; + moveTo(x:number,y:number):void; + + /** + * @param x + * @param y + * @param b 是否应用矩阵 + */ + lineTo(x:number,y:number):void; + arcTo(x1:number,y1:number,x2:number,y2:number,r:number):void; + arc(cx:number,cy:number,r:number,startAngle:number,endAngle:number,counterclockwise?:boolean,b?:boolean):void; + quadraticCurveTo(cpx:number,cpy:number,x:number,y:number):void; + + /** + * 把颜色跟当前设置的alpha混合 + * @return + */ + mixRGBandAlpha(color:number):number; + strokeRect(x:number,y:number,width:number,height:number,parameterLineWidth:number):void; + clip():void; + + /** + * *****************************************end矢量绘制************************************************** + */ + drawParticle(x:number,y:number,pt:any):void; + private _getPath:any; + + /** + * 获取canvas + */ + get canvas():HTMLCanvas; + private static tmpuv1:any; + + /** + * 专用函数。通过循环创建来水平填充 + * @param tex + * @param bmpid + * @param uv 希望循环的部分的uv + * @param oriw + * @param orih + * @param x + * @param y + * @param w + */ + private _fillTexture_h:any; + + /** + * 专用函数。通过循环创建来垂直填充 + * @param tex + * @param imgid + * @param uv + * @param oriw + * @param orih + * @param x + * @param y + * @param h + */ + private _fillTexture_v:any; + private static tmpUV:any; + private static tmpUVRect:any; + drawTextureWithSizeGrid(tex:Texture,tx:number,ty:number,width:number,height:number,sizeGrid:any[],gx:number,gy:number):void; + } + +enum FilterMode { + /**点过滤。*/ + Point = 0, + /**双线性过滤。*/ + Bilinear = 1, + /**三线性过滤。*/ + Trilinear = 2 +} + + /** + * HTMLCanvas 是 Html Canvas 的代理类,封装了 Canvas 的属性和方法。 + */ + class HTMLCanvas extends Bitmap { + private _ctx:any; + + /** + * @inheritDoc + */ + get source():HTMLCanvasElement; + + /** + * 根据指定的类型,创建一个 HTMLCanvas 实例。 + */ + + constructor(createCanvas?:boolean); + + /** + * 清空画布内容。 + */ + clear():void; + + /** + * 销毁。 + * @override + */ + destroy():void; + + /** + * 释放。 + */ + release():void; + + /** + * Canvas 渲染上下文。 + */ + get context():Context; + + /** + * 获取 Canvas 渲染上下文。 + * @param contextID 上下文ID. + * @param other + * @return Canvas 渲染上下文 Context 对象。 + */ + getContext(contextID:string,other?:any):Context; + + /** + * 获取内存大小。 + * @return 内存大小。 + */ + getMemSize():number; + + /** + * 设置宽高。 + * @param w 宽度。 + * @param h 高度。 + */ + size(w:number,h:number):void; + + /** + * 获取texture实例 + */ + getTexture():Texture|null|RenderTexture2D; + + /** + * 把图片转换为base64信息 + * @param type "image/png" + * @param encoderOptions 质量参数,取值范围为0-1 + */ + toBase64(type:string,encoderOptions:number):string|null; + toBase64Async(type:string,encoderOptions:number,callBack:Function):void; + } + + /** + * @private

    HTMLImage 用于创建 HTML Image 元素。

    请使用 HTMLImage.create()获取新实例,不要直接使用 new HTMLImage

    + */ + class HTMLImage extends Bitmap { + + /** + *

    不支持canvas了,所以备Texture2D替换了

    + *

    创建一个 HTMLImage 实例。

    + *

    请使用 HTMLImage.create()创建实例,不要直接使用 new HTMLImage

    + */ + static create:Function; + } + + interface ICreateResource{ + _setCreateURL(url:string):void; + } + + + interface IDestroy{ + destroyed:boolean; + destroy():void; + } + + + interface ISingletonElement{ + _getIndexInList():number; + _setIndexInList(index:number):void; + } + + + /** + * RenderTexture 类用于创建渲染目标。 + */ + class RenderTexture2D extends BaseTexture { + + /** + * @private + */ + private static _currentActive:any; + private _lastRT:any; + private _lastWidth:any; + private _lastHeight:any; + private static rtStack:any; + static defuv:any[]; + static flipyuv:any[]; + + /** + * 获取当前激活的Rendertexture + */ + static get currentActive():RenderTexture2D; + + /** + * @private + */ + private _frameBuffer:any; + + /** + * @private + */ + private _depthStencilBuffer:any; + + /** + * @private + */ + private _depthStencilFormat:any; + + /** + * 获取深度格式。 + * @return 深度格式。 + */ + get depthStencilFormat():number; + + /** + * @inheritDoc + * @override + */ + get defaulteTexture():BaseTexture; + getIsReady():boolean; + + /** + * 获取宽度。 + */ + get sourceWidth():number; + + /** + * * + * 获取高度。 + */ + get sourceHeight():number; + + /** + * 获取offsetX。 + */ + get offsetX():number; + + /** + * * + * 获取offsetY + */ + get offsetY():number; + + /** + * @param width 宽度。 + * @param height 高度。 + * @param format 纹理格式。 + * @param depthStencilFormat 深度格式。 创建一个 RenderTexture 实例。 + */ + + constructor(width:number,height:number,format?:number,depthStencilFormat?:number); + + /** + * @private + */ + private _create:any; + + /** + * 生成mipMap。 + * @override + */ + generateMipmap():void; + + /** + * 保存当前的RT信息。 + */ + static pushRT():void; + + /** + * 恢复上次保存的RT信息 + */ + static popRT():void; + + /** + * 开始绑定。 + */ + start():void; + + /** + * 结束绑定。 + */ + end():void; + + /** + * 恢复上一次的RenderTarge.由于使用自己保存的,所以如果被外面打断了的话,会出错。 + */ + restore():void; + clear(r?:number,g?:number,b?:number,a?:number):void; + + /** + * 获得像素数据。 + * @param x X像素坐标。 + * @param y Y像素坐标。 + * @param width 宽度。 + * @param height 高度。 + * @return 像素数据。 + */ + getData(x:number,y:number,width:number,height:number):Uint8Array; + + /** + * native多线程 + */ + getDataAsync(x:number,y:number,width:number,height:number,callBack:Function):void; + recycle():void; + } + +enum RenderTextureFormat { + /**RGB格式,每个通道8位。*/ + R8G8B8 = 0, + /**RGBA格式,每个通道8位。*/ + R8G8B8A8 = 1, + /**Alpha格式,8位。*/ + Alpha8 = 2, + /**RGBA格式,每个通道16位。*/ + R16G16B16A16 = 14, + /**深度格式。*/ + Depth = 15, + /**阴影贴图格式格式。*/ + ShadowMap = 16 +} + +enum RenderTextureDepthFormat { + /**深度格式_DEPTH_16。*/ + DEPTH_16 = 0, + /**深度格式_STENCIL_8。*/ + STENCIL_8 = 1, + /**深度格式_DEPTHSTENCIL_24_8。*/ + DEPTHSTENCIL_24_8 = 2, + /**深度格式_DEPTHSTENCIL_NONE。*/ + DEPTHSTENCIL_NONE = 3, + /** @deprecated*/ + DEPTHSTENCIL_16_8 = 2 +} + + /** + * Resource 资源存取类。 + */ + class Resource extends EventDispatcher implements ICreateResource,IDestroy { + + /** + * @private + */ + private static _uniqueIDCounter:any; + + /** + * @private + */ + private static _idResourcesMap:any; + + /** + * @private + */ + private static _urlResourcesMap:any; + + /** + * @private 以字节为单位。 + */ + private static _cpuMemory:any; + + /** + * @private 以字节为单位。 + */ + private static _gpuMemory:any; + + /** + * 当前内存,以字节为单位。 + */ + static get cpuMemory():number; + + /** + * 当前显存,以字节为单位。 + */ + static get gpuMemory():number; + + /** + * 通过资源ID返回已载入资源。 + * @param id 资源ID + * @return 资源 Resource 对象。 + */ + static getResourceByID(id:number):Resource; + + /** + * 通过url返回已载入资源。 + * @param url 资源URL + * @param index 索引 + * @return 资源 Resource 对象。 + */ + static getResourceByURL(url:string,index?:number):Resource; + + /** + * 销毁当前没有被使用的资源,该函数会忽略lock=true的资源。 + * @param group 指定分组。 + */ + static destroyUnusedResources():void; + + /** + * @private + */ + protected _id:number; + + /** + * @private + */ + private _url:any; + + /** + * @private + */ + private _cpuMemory:any; + + /** + * @private + */ + private _gpuMemory:any; + + /** + * @private + */ + private _destroyed:any; + + /** + * @private + */ + protected _referenceCount:number; + + /** + * 是否加锁,如果true为不能使用自动释放机制。 + */ + lock:boolean; + + /** + * 名称。 + */ + name:string; + + /** + * 获取唯一标识ID,通常用于识别。 + */ + get id():number; + + /** + * 获取资源的URL地址。 + * @return URL地址。 + */ + get url():string; + + /** + * 内存大小。 + */ + get cpuMemory():number; + + /** + * 显存大小。 + */ + get gpuMemory():number; + + /** + * 是否已处理。 + */ + get destroyed():boolean; + + /** + * 获取资源的引用计数。 + */ + get referenceCount():number; + + /** + * 创建一个 Resource 实例。 + */ + + constructor(); + + /** + * @private + */ + _setCreateURL(url:string):void; + + /** + * @private + */ + protected _recoverResource():void; + + /** + * @private + */ + protected _disposeResource():void; + + /** + * @private + */ + protected _activeResource():void; + + /** + * 销毁资源,销毁后资源不能恢复。 + */ + destroy():void; + } + + /** + * 资源加载完成后调度。 + * @eventType Event.READY + */ + + /** + * Texture 是一个纹理处理类。 + */ + class Texture extends EventDispatcher { + + /** + * @private 默认 UV 信息。 + */ + static DEF_UV:Float32Array; + + /** + * @private + */ + static NO_UV:Float32Array; + + /** + * @private 反转 UV 信息。 + */ + static INV_UV:Float32Array; + + /** + * @private + */ + private static _rect1:any; + + /** + * @private + */ + private static _rect2:any; + + /** + * @private uv的范围 + */ + uvrect:any[]; + + /** + * @private + */ + private _destroyed:any; + + /** + * @private + */ + private _bitmap:any; + + /** + * @private + */ + private _referenceCount:any; + + /** + * 沿 X 轴偏移量。 + */ + offsetX:number; + + /** + * 沿 Y 轴偏移量。 + */ + offsetY:number; + + /** + * @private + */ + private _w:any; + + /** + * @private + */ + private _h:any; + + /** + * 原始宽度(包括被裁剪的透明区域)。 + */ + sourceWidth:number; + + /** + * 原始高度(包括被裁剪的透明区域)。 + */ + sourceHeight:number; + + /** + * 图片地址 + */ + url:string; + + /** + * @private + */ + scaleRate:number; + + /** + * 平移 UV。 + * @param offsetX 沿 X 轴偏移量。 + * @param offsetY 沿 Y 轴偏移量。 + * @param uv 需要平移操作的的 UV。 + * @return 平移后的UV。 + */ + static moveUV(offsetX:number,offsetY:number,uv:any[]):any[]; + + /** + * 根据指定资源和坐标、宽高、偏移量等创建 Texture 对象。 + * @param source 绘图资源 Texture2D 或者 Texture对象。 + * @param x 起始绝对坐标 x 。 + * @param y 起始绝对坐标 y 。 + * @param width 宽绝对值。 + * @param height 高绝对值。 + * @param offsetX X 轴偏移量(可选)。 就是[x,y]相对于原始小图片的位置。一般都是正的,表示裁掉了空白边的大小,如果是负的一般表示加了保护边 + * @param offsetY Y 轴偏移量(可选)。 + * @param sourceWidth 原始宽度,包括被裁剪的透明区域(可选)。 + * @param sourceHeight 原始高度,包括被裁剪的透明区域(可选)。 + * @return Texture 对象。 + */ + static create(source:Texture2D|Texture,x:number,y:number,width:number,height:number,offsetX?:number,offsetY?:number,sourceWidth?:number,sourceHeight?:number):Texture; + + /** + * 截取Texture的一部分区域,生成新的Texture,如果两个区域没有相交,则返回null。 + * @param texture 目标Texture。 + * @param x 相对于目标Texture的x位置。 + * @param y 相对于目标Texture的y位置。 + * @param width 截取的宽度。 + * @param height 截取的高度。 + * @return 返回一个新的Texture。 + */ + static createFromTexture(texture:Texture,x:number,y:number,width:number,height:number):Texture; + get uv():ArrayLike; + set uv(value:ArrayLike); + + /** + * 实际宽度。 + */ + get width():number; + set width(value:number); + + /** + * 实际高度。 + */ + get height():number; + set height(value:number); + + /** + * 获取位图。 + * @return 位图。 + */ + get bitmap():Texture2D|Texture|RenderTexture; + + /** + * 设置位图。 + * @param 位图 。 + */ + set bitmap(value:Texture2D|Texture|RenderTexture); + + /** + * 获取是否已经销毁。 + * @return 是否已经销毁。 + */ + get destroyed():boolean; + + /** + * 创建一个 Texture 实例。 + * @param bitmap 位图资源。 + * @param uv UV 数据信息。 + */ + + constructor(bitmap?:Texture2D|Texture|RenderTexture,uv?:ArrayLike,sourceWidth?:number,sourceHeight?:number); + + /** + * @private + */ + private _onLoaded:any; + + /** + * 获取是否可以使用。 + */ + getIsReady():boolean; + + /** + * 设置此对象的位图资源、UV数据信息。 + * @param bitmap 位图资源 + * @param uv UV数据信息 + */ + setTo(bitmap?:Texture2D|Texture|RenderTexture,uv?:ArrayLike,sourceWidth?:number,sourceHeight?:number):void; + + /** + * 加载指定地址的图片。 + * @param url 图片地址。 + * @param complete 加载完成回调 + */ + load(url:string,complete?:Handler):void; + getTexturePixels(x:number,y:number,width:number,height:number):Uint8Array; + + /** + * 获取Texture上的某个区域的像素点 + * @param x + * @param y + * @param width + * @param height + * @return 返回像素点集合 + */ + getPixels(x:number,y:number,width:number,height:number):Uint8Array; + + /** + * 通过url强制恢复bitmap。 + */ + recoverBitmap(onok?:() =>void):void; + + /** + * 强制释放Bitmap,无论是否被引用。 + */ + disposeBitmap():void; + + /** + * 销毁纹理。 + */ + destroy(force?:boolean):void; + } + + /** + * Texture2D 类用于生成2D纹理。 + */ + class Texture2D extends BaseTexture { + + /** + * Texture2D资源。 + */ + static TEXTURE2D:string; + + /** + * 纯灰色纹理。 + */ + static grayTexture:Texture2D; + + /** + * 纯白色纹理。 + */ + static whiteTexture:Texture2D; + + /** + * 纯黑色纹理。 + */ + static blackTexture:Texture2D; + + /** + * 错误纹理 + */ + static erroTextur:Texture2D; + + /** + * 加载Texture2D。 + * @param url Texture2D地址。 + * @param complete 完成回掉。 + */ + static load(url:string,complete:Handler):void; + + /** + * @inheritDoc + * @override + */ + get defaulteTexture():BaseTexture; + + /** + * 创建一个 Texture2D 实例。 + * @param width 宽。 + * @param height 高。 + * @param format 贴图格式。 + * @param mipmap 是否生成mipmap。 + * @param canRead 是否可读像素,如果为true,会在内存保留像素数据。 + */ + + constructor(width?:number,height?:number,format?:TextureFormat,mipmap?:boolean,canRead?:boolean); + + /** + * 通过图片源填充纹理,可为HTMLImageElement、HTMLCanvasElement、HTMLVideoElement、ImageBitmap、ImageData, + * 设置之后纹理宽高可能会发生变化。 + */ + loadImageSource(source:any,premultiplyAlpha?:boolean):void; + + /** + * 通过像素填充纹理。 + * @param pixels 像素。 + * @param miplevel 层级。 + */ + setPixels(pixels:Uint8Array|Uint16Array|Float32Array,miplevel?:number):void; + + /** + * 通过像素填充部分纹理。 + * @param x X轴像素起点。 + * @param y Y轴像素起点。 + * @param width 像素宽度。 + * @param height 像素高度。 + * @param pixels 像素数组。 + * @param miplevel 层级。 + */ + setSubPixels(x:number,y:number,width:number,height:number,pixels:Uint8Array|Uint16Array|Float32Array,miplevel?:number):void; + + /** + * 通过压缩数据填充纹理。 + * @param data 压缩数据。 + * @param miplevel 层级。 + */ + setCompressData(data:ArrayBuffer):void; + + /** + * 返回图片像素。 + * @return 图片像素。 + */ + getPixels():Uint8Array|Uint16Array|Float32Array; + } + +enum TextureDecodeFormat { + /** 常规解码方式,直接采样纹理颜色。*/ + Normal = 0, + /** 按照RGBM方式解码并计算最终RGB颜色。 */ + RGBM = 1 +} + +enum TextureFormat { + /**纹理格式_R8G8B8。*/ + R8G8B8 = 0, + /**纹理格式_R8G8B8A8。*/ + R8G8B8A8 = 1, + /**RGB格式纹理,R通道5位,G通道6位,B通道5位。*/ + R5G6B5 = 16, + /**纹理格式_ALPHA8。*/ + Alpha8 = 2, + /**纹理格式_DXT1。*/ + DXT1 = 3, + /**纹理格式_DXT5。*/ + DXT5 = 4, + /**纹理格式_ETC2RGB。*/ + ETC1RGB = 5, + ETC2RGB = 6, + ETC2RGBA = 7, + /**纹理格式_ETC2RGB_PUNCHTHROUGHALPHA。*/ + /**纹理格式_PVRTCRGB_2BPPV。*/ + ETC2RGB_Alpha8 = 8, + ETC2SRGB = 28, + PVRTCRGB_2BPPV = 9, + /**纹理格式_PVRTCRGBA_2BPPV。*/ + PVRTCRGBA_2BPPV = 10, + /**纹理格式_PVRTCRGB_4BPPV。*/ + PVRTCRGB_4BPPV = 11, + /**纹理格式_PVRTCRGBA_4BPPV。*/ + PVRTCRGBA_4BPPV = 12, + /**RGBA格式纹理,每个通道32位浮点数。*/ + R32G32B32A32 = 15, + /**RGBA格式纹理,每个通道16位浮点数。 */ + R16G16B16A16 = 17, + /**ASTC 4x4*/ + ASTC4x4 = 18, + /**ASTC sRGB 4x4 */ + ASTC4x4SRGB = 23, + /**ASTC 6x6*/ + ASTC6x6 = 19, + /**ASTC 6x6*/ + ASTC6x6SRGB = 24, + /**ASTC 8x8 */ + ASTC8x8 = 20, + ASTC8x8SRGB = 25, + /**ASTC 10x10 */ + ASTC10x10 = 21, + ASTC10x10SRGB = 26, + /**ASTC 12x12 */ + ASTC12x12 = 22, + ASTC12x12SRGB = 27, + /**ktx图片 */ + KTXTEXTURE = -1, + /**pvr图片 */ + PVRTEXTURE = -2 +} + + /** + * VideoTexture 多媒体纹理 + */ + class VideoTexture extends BaseTexture { + + /** + * videoTexture对象池 + */ + static _videoTexturePool:Array; + private _video:any; + private _needUpdate:any; + + /** + * 创建VideoTexture对象, + */ + + constructor(); + + /** + * 获得绑定的资源Video + * return HTMLVideoElement + */ + get video():any; + + /** + * @value 输入Video资源 + */ + set video(value:any); + + /** + * 开始播放视频 + */ + videoPlay():void; + + /** + * 暂停播放视频 + */ + videoPause():void; + destroy():void; + } + + /** + * WebGLRTMgr 管理WebGLRenderTarget的创建和回收 + * TODO 需求不大,管理成本高。先去掉。 + */ + class WebGLRTMgr { + private static dict:any; + + /** + * 获得一个renderTarget + * 暂时先按照严格大小判断。 + * @param w + * @param h + * @return + */ + static getRT(w:number,h:number):RenderTexture2D; + + /** + * 回收一个renderTarget + * @param rt + */ + static releaseRT(rt:RenderTexture2D):void; + } + +enum WarpMode { + /** 循环平铺。*/ + Repeat = 0, + /** 超过UV边界后采用最后一个像素。*/ + Clamp = 1 +} + class SpineGLTexture extends Texture { + + constructor(tex:Texture2D|Texture); + getImage():Object; + setFilters(minFilter:spine.TextureFilter,magFilter:spine.TextureFilter):void; + setWraps(uWrap:spine.TextureWrap,vWrap:spine.TextureWrap):void; + } + + /** + * 动画开始播放调度 + * @eventType Event.PLAYED + */ + + /** + * 动画停止播放调度 + * @eventType Event.STOPPED + */ + + /** + * 动画暂停播放调度 + * @eventType Event.PAUSED + */ + + /** + * 自定义事件。 + * @eventType Event.LABEL + */ + + /** + * spine动画由SpineTempletSpineSkeletonRenderSpineSkeleton三部分组成。 + */ + class SpineSkeleton extends Sprite { + static stopped:number; + static paused:number; + static playing:number; + private _templet:any; + private timeKeeper:any; + private skeleton:any; + private state:any; + private stateData:any; + private currentPlayTime:any; + private skeletonRenderer:any; + _ins:SpineSkeleton; + + /** + * 播放速率 + */ + private _playbackRate:any; + private trackIndex:any; + + /** + * 创建一个Skeleton对象 + * @param templet 骨骼动画模板 + */ + + constructor(templet?:SpineTemplet|SpineTempletBinary); + init(templet:SpineTemplet|SpineTempletBinary):void; + + /** + * 播放动画 + * @param nameOrIndex 动画名字或者索引 + * @param loop 是否循环播放 + * @param force false,如果要播的动画跟上一个相同就不生效,true,强制生效 + * @param start 起始时间 + * @param end 结束时间 + * @param freshSkin 是否刷新皮肤数据 + * @param playAudio 是否播放音频 + */ + play(nameOrIndex:any,loop:boolean,force?:boolean,start?:number,end?:number,freshSkin?:boolean,playAudio?:boolean):void; + private _update:any; + + /** + * 得到当前动画的数量 + * @return 当前动画的数量 + */ + getAnimNum():number; + + /** + * 得到指定动画的名字 + * @param index 动画的索引 + */ + getAniNameByIndex(index:number):string; + + /** + * 通过名字得到插槽的引用 + * @param slotName + */ + getSlotByName(slotName:string):spine.Slot; + + /** + * 设置动画播放速率 + * @param value 1为标准速率 + */ + playbackRate(value:number):void; + + /** + * 通过名字显示一套皮肤 + * @param name 皮肤的名字 + */ + showSkinByName(name:string):void; + + /** + * 通过索引显示一套皮肤 + * @param skinIndex 皮肤索引 + */ + showSkinByIndex(skinIndex:number):void; + + /** + * 停止动画 + */ + stop():void; + + /** + * 暂停动画的播放 + */ + paused():void; + + /** + * 恢复动画的播放 + */ + resume():void; + + /** + * 销毁当前动画 + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * 得到动画模板的引用 + * @return templet + */ + get templet():SpineTemplet|SpineTempletBinary; + + /** + * 添加一个动画 + * @param nameOrIndex 动画名字或者索引 + * @param loop 是否循环播放 + * @param delay 延迟调用,可以为负数 + */ + addAnimation(nameOrIndex:any,loop?:boolean,delay?:number):void; + + /** + * 设置当动画被改变时,存储混合(交叉淡出)的持续时间 + * @param fromNameOrIndex + * @param toNameOrIndex + * @param duration + */ + setMix(fromNameOrIndex:any,toNameOrIndex:any,duration:number):void; + + /** + * 获取骨骼信息(spine.Bone) + * 注意: 获取到的是spine运行时的骨骼信息(spine.Bone),不适用引擎的方法 + * @param boneName + */ + getBoneByName(boneName:string):spine.Bone; + + /** + * 获取Skeleton(spine.Skeleton) + */ + getSkeleton():Skeleton; + + /** + * 替换插槽皮肤 + * @param slotName + * @param attachmentName + */ + setSlotAttachment(slotName:string,attachmentName:string):void; + + /** + * 设置当前播放位置 + * @param value 当前时间 + */ + set currentTime(value:number); + + /** + * 获取当前播放状态 + * @return 当前播放状态 + */ + get playState():number; + } + class SpineSkeletonRenderer { + static QUAD_TRIANGLES:number[]; + premultipliedAlpha:boolean; + vertexEffect:spine.VertexEffect; + private tempColor:any; + private tempColor2:any; + private vertices:any; + private vertexSize:any; + private twoColorTint:any; + private renderable:any; + private clipper:any; + private temp:any; + private temp2:any; + private temp3:any; + private temp4:any; + + constructor(twoColorTint?:boolean); + draw(skeleton:Skeleton,slotRangeStart:number,slotRangeEnd:number,spineSkeletonIns:SpineSkeleton,textureList:any):void; + } + + /** + * 数据解析完成后的调度。 + * @eventType Event.COMPLETE + */ + + /** + * 数据解析错误后的调度。 + * @eventType Event.ERROR + */ + + /** + * spine动画模板类 + */ + class SpineTemplet extends Resource { + private clientId:any; + private assetManager:any; + skeletonData:spine.SkeletonData; + private skeletonJson:any; + private atlasUrl:any; + private jsonUrl:any; + private _textureUrlList:any; + private _layaPremultipliedAlpha:any; + _spinePremultipliedAlpha:boolean; + + constructor(); + loadAni(jsonUrl:string,textureUrlList?:Array):void; + private textureLoader:any; + private loop:any; + private parseSpineAni:any; + + /** + * 创建动画 + * @return + */ + buildArmature():SpineSkeleton; + + /** + * 通过索引得动画名称 + * @param index + * @return + */ + getAniNameByIndex(index:number):string; + + /** + * 通过皮肤名字得到皮肤索引 + * @param skinName 皮肤名称 + * @return + */ + getSkinIndexByName(skinName:string):number; + + /** + * 释放纹理 + * @override + */ + destroy():void; + } + + /** + * 数据解析完成后的调度。 + * @eventType Event.COMPLETE + */ + + /** + * 数据解析错误后的调度。 + * @eventType Event.ERROR + */ + + /** + * spine动画模板类 + */ + class SpineTempletBinary extends Resource { + private pathPrefix:any; + private assetManager:any; + skeletonData:spine.SkeletonData; + private skeletonBinary:any; + private skelUrl:any; + private atlasUrl:any; + private textureUrlList:any; + private _layaPremultipliedAlpha:any; + _spinePremultipliedAlpha:boolean; + + constructor(); + loadAni(skelUrl:string,textureUrlList?:Array):void; + private textureLoader:any; + private loop:any; + private parseSpineAni:any; + + /** + * 创建动画 + * @return + */ + buildArmature():SpineSkeleton; + + /** + * 通过索引得动画名称 + * @param index + * @return + */ + getAniNameByIndex(index:number):string; + + /** + * 通过皮肤名字得到皮肤索引 + * @param skinName 皮肤名称 + * @return + */ + getSkinIndexByName(skinName:string):number; + + /** + * 释放纹理 + * @override + */ + destroy():void; + } + + /** + * @private + */ + class System { + + /** + * 替换指定名称的定义。用来动态更改类的定义。 + * @param name 属性名。 + * @param classObj 属性值。 + */ + static changeDefinition(name:string,classObj:any):void; + } + + /** + * 广告插件 + * @author 小松 + * @date -2018-09-19 + */ + class AdvImage extends Image { + + /** + * 广告列表数据* + */ + private advsListArr:any; + + /** + * 资源列表请求地址* + */ + private resUrl:any; + + /** + * 加载请求实例* + */ + private _http:any; + + /** + * 广告列表信息* + */ + private _data:any; + + /** + * 每6分钟重新请求一次新广告列表* + */ + private _resquestTime:any; + + /** + * 微信跳转appid* + */ + private _appid:any; + + /** + * 播放索引* + */ + private _playIndex:any; + + /** + * 轮播间隔时间* + */ + private _lunboTime:any; + + constructor(skin?:string); + + /** + * 设置导量加载地址* + */ + private setLoadUrl:any; + private init:any; + private initEvent:any; + private onAdvsImgClick:any; + private revertAdvsData:any; + + /** + * 当前小游戏环境是否支持游戏跳转功能* + */ + isSupportJump():boolean; + + /** + * 跳转游戏 + * @param callBack Function 回调参数说明:type 0 跳转成功;1跳转失败;2跳转接口调用成功 + */ + private jumptoGame:any; + private updateAdvsInfo:any; + private onLunbo:any; + + /** + * 获取轮播数据* + */ + private getCurrentAppidObj:any; + + /** + * 获取广告列表数据信息 + */ + private onGetAdvsListData:any; + + /** + * 生成指定范围的随机数 + * @param minNum 最小值 + * @param maxNum 最大值 + */ + static randRange(minNum:number,maxNum:number):number; + + /** + * @private 请求出错侦的听处理函数。 + * @param e 事件对象。 + */ + private _onError:any; + + /** + * @private 请求消息返回的侦听处理函数。 + * @param e 事件对象。 + */ + private _onLoad:any; + + /** + * @private 请求错误的处理函数。 + * @param message 错误信息。 + */ + private error:any; + + /** + * @private 请求成功完成的处理函数。 + */ + private complete:any; + + /** + * 转换数据* + */ + private getAdvsQArr:any; + + /** + * @private 清除当前请求。 + */ + private clear:any; + + /** + * @override + * @param destroyChild + */ + destroy(destroyChild?:boolean):void; + } + + /** + * AutoBitmap 类是用于表示位图图像或绘制图形的显示对象。 + *

    封装了位置,宽高及九宫格的处理,供UI组件使用。

    + */ + class AutoBitmap extends Graphics { + + /** + * @private 是否自动缓存命令 + */ + autoCacheCmd:boolean; + + /** + * @private 宽度 + */ + private _width:any; + + /** + * @private 高度 + */ + private _height:any; + + /** + * @private 源数据 + */ + private _source:any; + + /** + * @private 网格数据 + */ + private _sizeGrid:any; + + /** + * @private + */ + protected _isChanged:boolean; + uv:number[]; + private _drawGridCmd:any; + + /** + * @inheritDoc + * @override + */ + destroy():void; + + /** + * 当前实例的有效缩放网格数据。 + *

    如果设置为null,则在应用任何缩放转换时,将正常缩放整个显示对象。

    + *

    数据格式:[上边距,右边距,下边距,左边距,是否重复填充(值为0:不重复填充,1:重复填充)]。 + *

    • 例如:[4,4,4,4,1]

    + *

    sizeGrid 的值如下所示: + *

      + *
    1. 上边距
    2. + *
    3. 右边距
    4. + *
    5. 下边距
    6. + *
    7. 左边距
    8. + *
    9. 是否重复填充(值为0:不重复填充,1:重复填充)
    10. + *

    + *

    当定义 sizeGrid 属性时,该显示对象被分割到以 sizeGrid 数据中的"上边距,右边距,下边距,左边距" 组成的矩形为基础的具有九个区域的网格中,该矩形定义网格的中心区域。网格的其它八个区域如下所示: + *

      + *
    • 矩形上方的区域
    • + *
    • 矩形外的右上角
    • + *
    • 矩形左侧的区域
    • + *
    • 矩形右侧的区域
    • + *
    • 矩形外的左下角
    • + *
    • 矩形下方的区域
    • + *
    • 矩形外的右下角
    • + *
    • 矩形外的左上角
    • + *
    + * 同时也支持3宫格,比如0,4,0,4,1为水平3宫格,4,0,4,0,1为垂直3宫格,3宫格性能比9宫格高。 + *

    + */ + get sizeGrid():number[]; + set sizeGrid(value:number[]); + + /** + * 表示显示对象的宽度,以像素为单位。 + */ + get width():number; + set width(value:number); + + /** + * 表示显示对象的高度,以像素为单位。 + */ + get height():number; + set height(value:number); + + /** + * 对象的纹理资源。 + * @see laya.resource.Texture + */ + get source():Texture; + set source(value:Texture); + + /** + * @private + */ + protected _setChanged():void; + private _createDrawTexture:any; + + /** + * @private 修改纹理资源。 + */ + protected changeSource():void; + private drawBitmap:any; + private static getTexture:any; + + /** + * 由于可能有其他的graphic命令,因此不能用原来的直接clear()的方法 + */ + private _setDrawGridCmd:any; + } + + /** + * Box 类是一个控件容器类。 + */ + class Box extends UIComponent implements IBox { + private _bgColor:any; + + /** + * @inheritDoc + * @override + */ + set dataSource(value:any); + + /** + * @inheritDoc + * @override + */ + get dataSource():any; + + /** + * 背景颜色 + */ + get bgColor():string; + set bgColor(value:string); + private _onResize:any; + } + + /** + * 当按钮的选中状态( selected 属性)发生改变时调度。 + * @eventType laya.events.Event + */ + + /** + * Button 组件用来表示常用的多态按钮。 Button 组件可显示文本标签、图标或同时显示两者。 * + *

    可以是单态,两态和三态,默认三态(up,over,down)。

    + * @example 以下示例代码,创建了一个 Button 实例。 package { import laya.ui.Button; import laya.utils.Handler; public class Button_Example { public function Button_Example() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load("resource/ui/button.png", Handler.create(this,onLoadComplete));//加载资源。 } private function onLoadComplete():void { trace("资源加载完成!"); var button:Button = new Button("resource/ui/button.png","label");//创建一个 Button 类的实例对象 button ,并传入它的皮肤。 button.x = 100;//设置 button 对象的属性 x 的值,用于控制 button 对象的显示位置。 button.y = 100;//设置 button 对象的属性 y 的值,用于控制 button 对象的显示位置。 button.clickHandler = new Handler(this, onClickButton,[button]);//设置 button 的点击事件处理器。 Laya.stage.addChild(button);//将此 button 对象添加到显示列表。 } private function onClickButton(button:Button):void { trace("按钮button被点击了!"); } } } + * @example Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load("resource/ui/button.png",laya.utils.Handler.create(this,loadComplete));//加载资源 function loadComplete() { console.log("资源加载完成!"); var button = new laya.ui.Button("resource/ui/button.png","label");//创建一个 Button 类的实例对象 button ,传入它的皮肤skin和标签label。 button.x =100;//设置 button 对象的属性 x 的值,用于控制 button 对象的显示位置。 button.y =100;//设置 button 对象的属性 y 的值,用于控制 button 对象的显示位置。 button.clickHandler = laya.utils.Handler.create(this,onClickButton,[button],false);//设置 button 的点击事件处理函数。 Laya.stage.addChild(button);//将此 button 对象添加到显示列表。 } function onClickButton(button) { console.log("按钮被点击了。",button); } + * @example import Button=laya.ui.Button; import Handler=laya.utils.Handler; class Button_Example{ constructor() { Laya.init(640, 800); Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load("resource/ui/button.png", laya.utils.Handler.create(this,this.onLoadComplete));//加载资源。 } private onLoadComplete() { var button:Button = new Button("resource/ui/button.png","label");//创建一个 Button 类的实例对象 button ,并传入它的皮肤。 button.x = 100;//设置 button 对象的属性 x 的值,用于控制 button 对象的显示位置。 button.y = 100;//设置 button 对象的属性 y 的值,用于控制 button 对象的显示位置。 button.clickHandler = new Handler(this, this.onClickButton,[button]);//设置 button 的点击事件处理器。 Laya.stage.addChild(button);//将此 button 对象添加到显示列表。 } private onClickButton(button:Button):void { console.log("按钮button被点击了!") } } + */ + class Button extends UIComponent implements ISelect { + + /** + * 按钮状态集。 + */ + protected static stateMap:any; + + /** + * 指定按钮按下时是否是切换按钮的显示状态。 + * @example 以下示例代码,创建了一个 Button 实例,并设置为切换按钮。 + * @example package { import laya.ui.Button; import laya.utils.Handler; public class Button_toggle { public function Button_toggle() { Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load("resource/ui/button.png", Handler.create(this,onLoadComplete)); } private function onLoadComplete():void { trace("资源加载完成!"); var button:Button = new Button("resource/ui/button.png","label");//创建一个 Button 实例对象 button ,传入它的皮肤skin和标签label。 button.x = 100;//设置 button 对象的属性 x 的值,用于控制 button 对象的显示位置。 button.y = 100;//设置 button 对象的属性 y 的值,用于控制 button 对象的显示位置。 button.toggle = true;//设置 button 对象为切换按钮。 button.clickHandler = new Handler(this, onClickButton,[button]);//设置 button 的点击事件处理器。 Laya.stage.addChild(button);//将此 button 对象添加到显示列表。 } private function onClickButton(button:Button):void { trace("button.selected = "+ button.selected); } } } + * @example Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load("resource/ui/button.png",laya.utils.Handler.create(this,loadComplete));//加载资源 function loadComplete() { console.log("资源加载完成!"); var button = new laya.ui.Button("resource/ui/button.png","label");//创建一个 Button 类的实例对象 button ,传入它的皮肤skin和标签label。 button.x =100;//设置 button 对象的属性 x 的值,用于控制 button 对象的显示位置。 button.y =100;//设置 button 对象的属性 y 的值,用于控制 button 对象的显示位置。 button.toggle = true;//设置 button 对象为切换按钮。 button.clickHandler = laya.utils.Handler.create(this,onClickButton,[button],false);//设置 button 的点击事件处理器。 Laya.stage.addChild(button);//将此 button 对象添加到显示列表。 } function onClickButton(button) { console.log("button.selected = ",button.selected); } + * @example Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load("button.png", null,null, null, null, null);//加载资源 function loadComplete() { console.log("资源加载完成!"); var button:laya.ui.Button = new laya.ui.Button("button.png", "label");//创建一个 Button 类的实例对象 button ,传入它的皮肤skin和标签label。 button.x = 100;//设置 button 对象的属性 x 的值,用于控制 button 对象的显示位置。 button.y = 100;//设置 button 对象的属性 y 的值,用于控制 button 对象的显示位置。 button.toggle = true;//设置 button 对象为切换按钮。 button.clickHandler = laya.utils.Handler.create(this, onClickButton, [button], false);//设置 button 的点击事件处理器。 Laya.stage.addChild(button);//将此 button 对象添加到显示列表。 } function onClickButton(button) { console.log("button.selected = ", button.selected); } + */ + toggle:boolean; + + /** + * @private + */ + protected _bitmap:AutoBitmap; + + /** + * @private 按钮上的文本。 + */ + protected _text:Text; + + /** + * @private 按钮文本标签的颜色值。 + */ + protected _labelColors:any[]; + + /** + * @private 按钮文本标签描边的颜色值。 + */ + protected _strokeColors:any[]; + + /** + * @private 按钮的状态值。 + */ + protected _state:number; + + /** + * @private 表示按钮的选中状态。 + */ + protected _selected:boolean; + + /** + * @private 按钮的皮肤资源。 + */ + protected _skin:string; + + /** + * @private 指定此显示对象是否自动计算并改变大小等属性。 + */ + protected _autoSize:boolean; + + /** + * @private 按钮的状态数。 + */ + protected _stateNum:number; + + /** + * @private 源数据。 + */ + protected _sources:any[]; + + /** + * @private 按钮的点击事件函数。 + */ + protected _clickHandler:Handler; + + /** + * @private + */ + protected _stateChanged:boolean; + + /** + * 创建一个新的 Button 类实例。 + * @param skin 皮肤资源地址。 + * @param label 按钮的文本内容。 + */ + + constructor(skin?:string,label?:string); + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * @inheritDoc + * @override + */ + protected createChildren():void; + + /** + * @private + */ + protected createText():void; + + /** + * @inheritDoc + * @override + */ + protected initialize():void; + + /** + * 对象的 Event.MOUSE_OVER、Event.MOUSE_OUT、Event.MOUSE_DOWN、Event.MOUSE_UP、Event.CLICK 事件侦听处理函数。 + * @param e Event 对象。 + */ + protected onMouse(e:Event):void; + + /** + *

    对象的皮肤资源地址。

    + * 支持单态,两态和三态,用 stateNum 属性设置 + *

    对象的皮肤地址,以字符串表示。

    + * @see #stateNum + */ + get skin():string; + set skin(value:string); + protected _skinLoaded():void; + + /** + *

    指定对象的状态值,以数字表示。

    + *

    默认值为3。此值决定皮肤资源图片的切割方式。

    + *

    取值: + *

  • 1:单态。图片不做切割,按钮的皮肤状态只有一种。
  • + *
  • 2:两态。图片将以竖直方向被等比切割为2部分,从上向下,依次为 + * 弹起状态皮肤、 + * 按下和经过及选中状态皮肤。
  • + *
  • 3:三态。图片将以竖直方向被等比切割为3部分,从上向下,依次为 + * 弹起状态皮肤、 + * 经过状态皮肤、 + * 按下和选中状态皮肤
  • + *

    + */ + get stateNum():number; + set stateNum(value:number); + + /** + * @private 对象的资源切片发生改变。 + */ + protected changeClips():void; + + /** + * @inheritDoc + * @override + */ + protected measureWidth():number; + + /** + * @inheritDoc + * @override + */ + protected measureHeight():number; + + /** + * 按钮的文本内容。 + */ + get label():string; + set label(value:string); + + /** + * 表示按钮的选中状态。 + *

    如果值为true,表示该对象处于选中状态。否则该对象处于未选中状态。

    + * @implements + */ + get selected():boolean; + set selected(value:boolean); + + /** + * 对象的状态值。 + * @see #stateMap + */ + protected get state():number; + protected set state(value:number); + + /** + * @private 改变对象的状态。 + */ + protected changeState():void; + + /** + * 表示按钮各个状态下的文本颜色。 + *

    格式: "upColor,overColor,downColor,disableColor"。

    + */ + get labelColors():string; + set labelColors(value:string); + + /** + * 表示按钮各个状态下的描边颜色。 + *

    格式: "upColor,overColor,downColor,disableColor"。

    + */ + get strokeColors():string; + set strokeColors(value:string); + + /** + * 表示按钮文本标签的边距。 + *

    格式:"上边距,右边距,下边距,左边距"。

    + */ + get labelPadding():string; + set labelPadding(value:string); + + /** + * 表示按钮文本标签的字体大小。 + * @see laya.display.Text.fontSize() + */ + get labelSize():number; + set labelSize(value:number); + + /** + *

    描边宽度(以像素为单位)。

    + * 默认值0,表示不描边。 + * @see laya.display.Text.stroke() + */ + get labelStroke():number; + set labelStroke(value:number); + + /** + *

    描边颜色,以字符串表示。

    + * 默认值为 "#000000"(黑色); + * @see laya.display.Text.strokeColor() + */ + get labelStrokeColor():string; + set labelStrokeColor(value:string); + + /** + * 表示按钮文本标签是否为粗体字。 + * @see laya.display.Text.bold() + */ + get labelBold():boolean; + set labelBold(value:boolean); + + /** + * 表示按钮文本标签的字体名称,以字符串形式表示。 + * @see laya.display.Text.font() + */ + get labelFont():string; + set labelFont(value:string); + + /** + * 标签对齐模式,默认为居中对齐。 + */ + get labelAlign():string; + set labelAlign(value:string); + + /** + * 对象的点击事件处理器函数(无默认参数)。 + * @implements + */ + get clickHandler():Handler; + set clickHandler(value:Handler); + + /** + * 按钮文本标签 Text 控件。 + */ + get text():Text; + + /** + *

    当前实例的位图 AutoImage 实例的有效缩放网格数据。

    + *

    数据格式:"上边距,右边距,下边距,左边距,是否重复填充(值为0:不重复填充,1:重复填充)",以逗号分隔。 + *

    • 例如:"4,4,4,4,1"

    + * @see laya.ui.AutoBitmap.sizeGrid + */ + get sizeGrid():string; + set sizeGrid(value:string); + + /** + * @inheritDoc + * @override + */ + set width(value:number); + + /** + * @inheritDoc + * @override + */ + get width():number; + + /** + * @inheritDoc + * @override + */ + set height(value:number); + + /** + * @inheritDoc + * @override + */ + get height():number; + + /** + * @inheritDoc + * @override + */ + set dataSource(value:any); + + /** + * @inheritDoc + * @override + */ + get dataSource():any; + + /** + * 图标x,y偏移,格式:100,100 + */ + get iconOffset():string; + set iconOffset(value:string); + + /** + * @private + */ + protected _setStateChanged():void; + } + + /** + * 当按钮的选中状态( selected 属性)发生改变时调度。 + * @eventType laya.events.Event + */ + + /** + * CheckBox 组件显示一个小方框,该方框内可以有选中标记。 + * CheckBox 组件还可以显示可选的文本标签,默认该标签位于 CheckBox 右侧。 + *

    CheckBox 使用 dataSource赋值时的的默认属性是:selected

    + * @example 以下示例代码,创建了一个 CheckBox 实例。 package { import laya.ui.CheckBox; import laya.utils.Handler; public class CheckBox_Example { public function CheckBox_Example() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load("resource/ui/check.png", Handler.create(this,onLoadComplete));//加载资源。 } private function onLoadComplete():void { trace("资源加载完成!"); var checkBox:CheckBox = new CheckBox("resource/ui/check.png", "这个是一个CheckBox组件。");//创建一个 CheckBox 类的实例对象 checkBox ,传入它的皮肤skin和标签label。 checkBox.x = 100;//设置 checkBox 对象的属性 x 的值,用于控制 checkBox 对象的显示位置。 checkBox.y = 100;//设置 checkBox 对象的属性 y 的值,用于控制 checkBox 对象的显示位置。 checkBox.clickHandler = new Handler(this, onClick, [checkBox]);//设置 checkBox 的点击事件处理器。 Laya.stage.addChild(checkBox);//将此 checkBox 对象添加到显示列表。 } private function onClick(checkBox:CheckBox):void { trace("输出选中状态: checkBox.selected = " + checkBox.selected); } } } + * @example Laya.init(640, 800);//设置游戏画布宽高 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色 Laya.loader.load("resource/ui/check.png",laya.utils.Handler.create(this,loadComplete));//加载资源 function loadComplete() { console.log("资源加载完成!"); var checkBox:laya.ui.CheckBox= new laya.ui.CheckBox("resource/ui/check.png", "这个是一个CheckBox组件。");//创建一个 CheckBox 类的类的实例对象 checkBox ,传入它的皮肤skin和标签label。 checkBox.x =100;//设置 checkBox 对象的属性 x 的值,用于控制 checkBox 对象的显示位置。 checkBox.y =100;//设置 checkBox 对象的属性 y 的值,用于控制 checkBox 对象的显示位置。 checkBox.clickHandler = new laya.utils.Handler(this,this.onClick,[checkBox],false);//设置 checkBox 的点击事件处理器。 Laya.stage.addChild(checkBox);//将此 checkBox 对象添加到显示列表。 } function onClick(checkBox) { console.log("checkBox.selected = ",checkBox.selected); } + * @example import CheckBox= laya.ui.CheckBox; import Handler=laya.utils.Handler; class CheckBox_Example{ constructor() { Laya.init(640, 800); Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load("resource/ui/check.png", Handler.create(this,this.onLoadComplete));//加载资源。 } private onLoadComplete() { var checkBox:CheckBox = new CheckBox("resource/ui/check.png", "这个是一个CheckBox组件。");//创建一个 CheckBox 类的实例对象 checkBox ,传入它的皮肤skin和标签label。 checkBox.x = 100;//设置 checkBox 对象的属性 x 的值,用于控制 checkBox 对象的显示位置。 checkBox.y = 100;//设置 checkBox 对象的属性 y 的值,用于控制 checkBox 对象的显示位置。 checkBox.clickHandler = new Handler(this, this.onClick,[checkBox]);//设置 checkBox 的点击事件处理器。 Laya.stage.addChild(checkBox);//将此 checkBox 对象添加到显示列表。 } private onClick(checkBox:CheckBox):void { console.log("输出选中状态: checkBox.selected = " + checkBox.selected); } } + */ + class CheckBox extends Button { + + /** + * 创建一个新的 CheckBox 组件实例。 + * @param skin 皮肤资源地址。 + * @param label 文本标签的内容。 + */ + + constructor(skin?:string,label?:string); + + /** + * @inheritDoc + * @override + */ + protected preinitialize():void; + + /** + * @inheritDoc + * @override + */ + protected initialize():void; + + /** + * @inheritDoc + * @override + */ + set dataSource(value:any); + + /** + * @inheritDoc + * @override + */ + get dataSource():any; + } + + /** + * 图片加载完成后调度。 + * @eventType Event.LOADED + */ + + /** + * 当前帧发生变化后调度。 + * @eventType laya.events.Event + */ + + /** + *

    Clip 类是位图切片动画。

    + *

    Clip 可将一张图片,按横向分割数量 clipX 、竖向分割数量 clipY , + * 或横向分割每个切片的宽度 clipWidth 、竖向分割每个切片的高度 clipHeight , + * 从左向右,从上到下,分割组合为一个切片动画。

    + * Image和Clip组件是唯一支持异步加载的两个组件,比如clip.skin = "abc/xxx.png",其他UI组件均不支持异步加载。 + * @example 以下示例代码,创建了一个 Clip 实例。 package { import laya.ui.Clip; public class Clip_Example { private var clip:Clip; public function Clip_Example() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 onInit(); } private function onInit():void { clip = new Clip("resource/ui/clip_num.png", 10, 1);//创建一个 Clip 类的实例对象 clip ,传入它的皮肤skin和横向分割数量、竖向分割数量。 clip.autoPlay = true;//设置 clip 动画自动播放。 clip.interval = 100;//设置 clip 动画的播放时间间隔。 clip.x = 100;//设置 clip 对象的属性 x 的值,用于控制 clip 对象的显示位置。 clip.y = 100;//设置 clip 对象的属性 y 的值,用于控制 clip 对象的显示位置。 clip.on(Event.CLICK, this, onClick);//给 clip 添加点击事件函数侦听。 Laya.stage.addChild(clip);//将此 clip 对象添加到显示列表。 } private function onClick():void { trace("clip 的点击事件侦听处理函数。clip.total="+ clip.total); if (clip.isPlaying == true) { clip.stop();//停止动画。 }else { clip.play();//播放动画。 } } } } + * @example Laya.init(640, 800);//设置游戏画布宽高 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色 var clip; Laya.loader.load("resource/ui/clip_num.png",laya.utils.Handler.create(this,loadComplete));//加载资源 function loadComplete() { console.log("资源加载完成!"); clip = new laya.ui.Clip("resource/ui/clip_num.png",10,1);//创建一个 Clip 类的实例对象 clip ,传入它的皮肤skin和横向分割数量、竖向分割数量。 clip.autoPlay = true;//设置 clip 动画自动播放。 clip.interval = 100;//设置 clip 动画的播放时间间隔。 clip.x =100;//设置 clip 对象的属性 x 的值,用于控制 clip 对象的显示位置。 clip.y =100;//设置 clip 对象的属性 y 的值,用于控制 clip 对象的显示位置。 clip.on(Event.CLICK,this,onClick);//给 clip 添加点击事件函数侦听。 Laya.stage.addChild(clip);//将此 clip 对象添加到显示列表。 } function onClick() { console.log("clip 的点击事件侦听处理函数。"); if(clip.isPlaying == true) { clip.stop(); }else { clip.play(); } } + * @example import Clip = laya.ui.Clip; import Handler = laya.utils.Handler; class Clip_Example { private clip: Clip; constructor() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 this.onInit(); } private onInit(): void { this.clip = new Clip("resource/ui/clip_num.png", 10, 1);//创建一个 Clip 类的实例对象 clip ,传入它的皮肤skin和横向分割数量、竖向分割数量。 this.clip.autoPlay = true;//设置 clip 动画自动播放。 this.clip.interval = 100;//设置 clip 动画的播放时间间隔。 this.clip.x = 100;//设置 clip 对象的属性 x 的值,用于控制 clip 对象的显示位置。 this.clip.y = 100;//设置 clip 对象的属性 y 的值,用于控制 clip 对象的显示位置。 this.clip.on(laya.events.Event.CLICK, this, this.onClick);//给 clip 添加点击事件函数侦听。 Laya.stage.addChild(this.clip);//将此 clip 对象添加到显示列表。 } private onClick(): void { console.log("clip 的点击事件侦听处理函数。clip.total=" + this.clip.total); if (this.clip.isPlaying == true) { this.clip.stop();//停止动画。 } else { this.clip.play();//播放动画。 } } } + */ + class Clip extends UIComponent { + + /** + * @private + */ + protected _sources:any[]; + + /** + * @private + */ + protected _bitmap:AutoBitmap; + + /** + * @private + */ + protected _skin:string; + + /** + * @private + */ + protected _clipX:number; + + /** + * @private + */ + protected _clipY:number; + + /** + * @private + */ + protected _clipWidth:number; + + /** + * @private + */ + protected _clipHeight:number; + + /** + * @private + */ + protected _autoPlay:boolean; + + /** + * @private + */ + protected _interval:number; + + /** + * @private + */ + protected _complete:Handler; + + /** + * @private + */ + protected _isPlaying:boolean; + + /** + * @private + */ + protected _index:number; + + /** + * @private + */ + protected _clipChanged:boolean; + + /** + * @private + */ + protected _group:string; + + /** + * @private + */ + protected _toIndex:number; + + /** + * 创建一个新的 Clip 示例。 + * @param url 资源类库名或者地址 + * @param clipX x方向分割个数 + * @param clipY y方向分割个数 + */ + + constructor(url?:string,clipX?:number,clipY?:number); + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * 销毁对象并释放加载的皮肤资源。 + */ + dispose():void; + + /** + * @inheritDoc + * @override + */ + protected createChildren():void; + + /** + * @private + * @override + */ + protected _onDisplay(e?:boolean):void; + + /** + * @copy laya.ui.Image#skin + */ + get skin():string; + set skin(value:string); + protected _skinLoaded():void; + + /** + * X轴(横向)切片数量。 + */ + get clipX():number; + set clipX(value:number); + + /** + * Y轴(竖向)切片数量。 + */ + get clipY():number; + set clipY(value:number); + + /** + * 横向分割时每个切片的宽度,与 clipX 同时设置时优先级高于 clipX 。 + */ + get clipWidth():number; + set clipWidth(value:number); + + /** + * 竖向分割时每个切片的高度,与 clipY 同时设置时优先级高于 clipY 。 + */ + get clipHeight():number; + set clipHeight(value:number); + + /** + * @private 改变切片的资源、切片的大小。 + */ + protected changeClip():void; + + /** + * @private 加载切片图片资源完成函数。 + * @param url 资源地址。 + * @param img 纹理。 + */ + protected loadComplete(url:string,img:Texture):void; + + /** + * 源数据。 + */ + get sources():any[]; + set sources(value:any[]); + + /** + * 资源分组。 + */ + get group():string; + set group(value:string); + + /** + * @inheritDoc + * @override + */ + set width(value:number); + + /** + * @inheritDoc + * @override + */ + get width():number; + + /** + * @inheritDoc + * @override + */ + set height(value:number); + + /** + * @inheritDoc + * @override + */ + get height():number; + + /** + * @inheritDoc + * @override + */ + protected measureWidth():number; + + /** + * @inheritDoc + * @override + */ + protected measureHeight():number; + + /** + *

    当前实例的位图 AutoImage 实例的有效缩放网格数据。

    + *

    数据格式:"上边距,右边距,下边距,左边距,是否重复填充(值为0:不重复填充,1:重复填充)",以逗号分隔。 + *

    • 例如:"4,4,4,4,1"

    + * @see laya.ui.AutoBitmap.sizeGrid + */ + get sizeGrid():string; + set sizeGrid(value:string); + + /** + * 当前帧索引。 + */ + get index():number; + set index(value:number); + + /** + * 切片动画的总帧数。 + */ + get total():number; + + /** + * 表示是否自动播放动画,若自动播放值为true,否则值为false; + *

    可控制切片动画的播放、停止。

    + */ + get autoPlay():boolean; + set autoPlay(value:boolean); + + /** + * 表示动画播放间隔时间(以毫秒为单位)。 + */ + get interval():number; + set interval(value:number); + + /** + * 表示动画的当前播放状态。 + * 如果动画正在播放中,则为true,否则为flash。 + */ + get isPlaying():boolean; + set isPlaying(value:boolean); + + /** + * 播放动画。 + * @param from 开始索引 + * @param to 结束索引,-1为不限制 + */ + play(from?:number,to?:number):void; + + /** + * @private + */ + protected _loop():void; + + /** + * 停止动画。 + */ + stop():void; + + /** + * @inheritDoc + * @override + */ + set dataSource(value:any); + + /** + * @inheritDoc + * @override + */ + get dataSource():any; + + /** + * AutoBitmap 位图实例。 + */ + get bitmap():AutoBitmap; + + /** + * @private + */ + protected _setClipChanged():void; + } + + /** + * 选择项改变后调度。 + * @eventType laya.events.Event + */ + + /** + * ColorPicker 组件将显示包含多个颜色样本的列表,用户可以从中选择颜色。 + * @example 以下示例代码,创建了一个 ColorPicker 实例。 package { import laya.ui.ColorPicker; import laya.utils.Handler; public class ColorPicker_Example { public function ColorPicker_Example() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load("resource/ui/color.png", Handler.create(this,onLoadComplete));//加载资源。 } private function onLoadComplete():void { trace("资源加载完成!"); var colorPicket:ColorPicker = new ColorPicker();//创建一个 ColorPicker 类的实例对象 colorPicket 。 colorPicket.skin = "resource/ui/color.png";//设置 colorPicket 的皮肤。 colorPicket.x = 100;//设置 colorPicket 对象的属性 x 的值,用于控制 colorPicket 对象的显示位置。 colorPicket.y = 100;//设置 colorPicket 对象的属性 y 的值,用于控制 colorPicket 对象的显示位置。 colorPicket.changeHandler = new Handler(this, onChangeColor,[colorPicket]);//设置 colorPicket 的颜色改变回调函数。 Laya.stage.addChild(colorPicket);//将此 colorPicket 对象添加到显示列表。 } private function onChangeColor(colorPicket:ColorPicker):void { trace("当前选择的颜色: " + colorPicket.selectedColor); } } } + * @example Laya.init(640, 800);//设置游戏画布宽高 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色 Laya.loader.load("resource/ui/color.png",laya.utils.Handler.create(this,loadComplete));//加载资源 function loadComplete() { console.log("资源加载完成!"); var colorPicket = new laya.ui.ColorPicker();//创建一个 ColorPicker 类的实例对象 colorPicket 。 colorPicket.skin = "resource/ui/color.png";//设置 colorPicket 的皮肤。 colorPicket.x = 100;//设置 colorPicket 对象的属性 x 的值,用于控制 colorPicket 对象的显示位置。 colorPicket.y = 100;//设置 colorPicket 对象的属性 y 的值,用于控制 colorPicket 对象的显示位置。 colorPicket.changeHandler = laya.utils.Handler.create(this, onChangeColor,[colorPicket],false);//设置 colorPicket 的颜色改变回调函数。 Laya.stage.addChild(colorPicket);//将此 colorPicket 对象添加到显示列表。 } function onChangeColor(colorPicket) { console.log("当前选择的颜色: " + colorPicket.selectedColor); } + * @example import ColorPicker = laya.ui.ColorPicker; import Handler = laya.utils.Handler; class ColorPicker_Example { constructor() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load("resource/ui/color.png", Handler.create(this, this.onLoadComplete));//加载资源。 } private onLoadComplete(): void { console.log("资源加载完成!"); var colorPicket: ColorPicker = new ColorPicker();//创建一个 ColorPicker 类的实例对象 colorPicket 。 colorPicket.skin = "resource/ui/color.png";//设置 colorPicket 的皮肤。 colorPicket.x = 100;//设置 colorPicket 对象的属性 x 的值,用于控制 colorPicket 对象的显示位置。 colorPicket.y = 100;//设置 colorPicket 对象的属性 y 的值,用于控制 colorPicket 对象的显示位置。 colorPicket.changeHandler = new Handler(this, this.onChangeColor, [colorPicket]);//设置 colorPicket 的颜色改变回调函数。 Laya.stage.addChild(colorPicket);//将此 colorPicket 对象添加到显示列表。 } private onChangeColor(colorPicket: ColorPicker): void { console.log("当前选择的颜色: " + colorPicket.selectedColor); } } + */ + class ColorPicker extends UIComponent { + + /** + * 当颜色发生改变时执行的函数处理器。 + * 默认返回参数color:颜色值字符串。 + */ + changeHandler:Handler; + + /** + * @private 指定每个正方形的颜色小格子的宽高(以像素为单位)。 + */ + protected _gridSize:number; + + /** + * @private 表示颜色样本列表面板的背景颜色值。 + */ + protected _bgColor:string; + + /** + * @private 表示颜色样本列表面板的边框颜色值。 + */ + protected _borderColor:string; + + /** + * @private 表示颜色样本列表面板选择或输入的颜色值。 + */ + protected _inputColor:string; + + /** + * @private 表示颜色输入框的背景颜色值。 + */ + protected _inputBgColor:string; + + /** + * @private 表示颜色样本列表面板。 + */ + protected _colorPanel:Box; + + /** + * @private 表示颜色网格。 + */ + protected _colorTiles:Sprite; + + /** + * @private 表示颜色块显示对象。 + */ + protected _colorBlock:Sprite; + + /** + * @private 表示颜色输入框控件 Input 。 + */ + protected _colorInput:Input; + + /** + * @private 表示点击后显示颜色样本列表面板的按钮控件 Button 。 + */ + protected _colorButton:Button; + + /** + * @private 表示颜色值列表。 + */ + protected _colors:any[]; + + /** + * @private 表示选择的颜色值。 + */ + protected _selectedColor:string; + + /** + * @private + */ + protected _panelChanged:boolean; + + constructor(createChildren?:boolean); + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * @inheritDoc + * @override + */ + protected createChildren():void; + + /** + * @inheritDoc + * @override + */ + protected initialize():void; + private onPanelMouseDown:any; + + /** + * 改变颜色样本列表面板。 + */ + protected changePanel():void; + + /** + * 颜色样本列表面板的显示按钮的 Event.MOUSE_DOWN 事件侦听处理函数。 + */ + private onColorButtonClick:any; + + /** + * 打开颜色样本列表面板。 + */ + open():void; + + /** + * 关闭颜色样本列表面板。 + */ + close():void; + + /** + * 舞台的 Event.MOUSE_DOWN 事件侦听处理函数。 + */ + private removeColorBox:any; + + /** + * 小格子色块的 Event.KEY_DOWN 事件侦听处理函数。 + */ + private onColorFieldKeyDown:any; + + /** + * 颜色值输入框 Event.CHANGE 事件侦听处理函数。 + */ + private onColorInputChange:any; + + /** + * 小格子色块的 Event.CLICK 事件侦听处理函数。 + */ + private onColorTilesClick:any; + + /** + * @private 小格子色块的 Event.MOUSE_MOVE 事件侦听处理函数。 + */ + private onColorTilesMouseMove:any; + + /** + * 通过鼠标位置取对应的颜色块的颜色值。 + */ + protected getColorByMouse():string; + + /** + * 绘制颜色块。 + * @param color 需要绘制的颜色块的颜色值。 + */ + private drawBlock:any; + + /** + * 表示选择的颜色值。 + */ + get selectedColor():string; + set selectedColor(value:string); + + /** + * @copy laya.ui.Button#skin + */ + get skin():string; + set skin(value:string); + + /** + * 改变颜色。 + */ + private changeColor:any; + + /** + * 表示颜色样本列表面板的背景颜色值。 + */ + get bgColor():string; + set bgColor(value:string); + + /** + * 表示颜色样本列表面板的边框颜色值。 + */ + get borderColor():string; + set borderColor(value:string); + + /** + * 表示颜色样本列表面板选择或输入的颜色值。 + */ + get inputColor():string; + set inputColor(value:string); + + /** + * 表示颜色输入框的背景颜色值。 + */ + get inputBgColor():string; + set inputBgColor(value:string); + + /** + * @private + */ + protected _setPanelChanged():void; + } + + /** + * 当用户更改 ComboBox 组件中的选定内容时调度。 + * @eventType laya.events.Event selectedIndex属性变化时调度。 + */ + + /** + * ComboBox 组件包含一个下拉列表,用户可以从该列表中选择单个值。 + * @example 以下示例代码,创建了一个 ComboBox 实例。 package { import laya.ui.ComboBox; import laya.utils.Handler; public class ComboBox_Example { public function ComboBox_Example() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load("resource/ui/button.png", Handler.create(this,onLoadComplete));//加载资源。 } private function onLoadComplete():void { trace("资源加载完成!"); var comboBox:ComboBox = new ComboBox("resource/ui/button.png", "item0,item1,item2,item3,item4,item5");//创建一个 ComboBox 类的实例对象 comboBox ,传入它的皮肤和标签集。 comboBox.x = 100;//设置 comboBox 对象的属性 x 的值,用于控制 comboBox 对象的显示位置。 comboBox.y = 100;//设置 comboBox 对象的属性 x 的值,用于控制 comboBox 对象的显示位置。 comboBox.selectHandler = new Handler(this, onSelect);//设置 comboBox 选择项改变时执行的处理器。 Laya.stage.addChild(comboBox);//将此 comboBox 对象添加到显示列表。 } private function onSelect(index:int):void { trace("当前选中的项对象索引: ",index); } } } + * @example Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load("resource/ui/button.png",laya.utils.Handler.create(this,loadComplete));//加载资源 function loadComplete() { console.log("资源加载完成!"); var comboBox = new laya.ui.ComboBox("resource/ui/button.png", "item0,item1,item2,item3,item4,item5");//创建一个 ComboBox 类的实例对象 comboBox ,传入它的皮肤和标签集。 comboBox.x = 100;//设置 comboBox 对象的属性 x 的值,用于控制 comboBox 对象的显示位置。 comboBox.y = 100;//设置 comboBox 对象的属性 x 的值,用于控制 comboBox 对象的显示位置。 comboBox.selectHandler = new laya.utils.Handler(this, onSelect);//设置 comboBox 选择项改变时执行的处理器。 Laya.stage.addChild(comboBox);//将此 comboBox 对象添加到显示列表。 } function onSelect(index) { console.log("当前选中的项对象索引: ",index); } + * @example import ComboBox = laya.ui.ComboBox; import Handler = laya.utils.Handler; class ComboBox_Example { constructor() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load("resource/ui/button.png", Handler.create(this, this.onLoadComplete));//加载资源。 } private onLoadComplete(): void { console.log("资源加载完成!"); var comboBox: ComboBox = new ComboBox("resource/ui/button.png", "item0,item1,item2,item3,item4,item5");//创建一个 ComboBox 类的实例对象 comboBox ,传入它的皮肤和标签集。 comboBox.x = 100;//设置 comboBox 对象的属性 x 的值,用于控制 comboBox 对象的显示位置。 comboBox.y = 100;//设置 comboBox 对象的属性 x 的值,用于控制 comboBox 对象的显示位置。 comboBox.selectHandler = new Handler(this, this.onSelect);//设置 comboBox 选择项改变时执行的处理器。 Laya.stage.addChild(comboBox);//将此 comboBox 对象添加到显示列表。 } private onSelect(index: number): void { console.log("当前选中的项对象索引: ", index); } } + */ + class ComboBox extends UIComponent { + + /** + * @private + */ + protected _visibleNum:number; + + /** + * @private + */ + protected _button:Button; + + /** + * @private + */ + protected _list:List; + + /** + * @private + */ + protected _isOpen:boolean; + + /** + * @private + */ + protected _itemColors:any[]; + + /** + * @private + */ + protected _itemSize:number; + + /** + * @private + */ + protected _labels:any[]; + + /** + * @private + */ + protected _selectedIndex:number; + + /** + * @private + */ + protected _selectHandler:Handler; + + /** + * @private + */ + protected _itemHeight:number; + + /** + * @private + */ + protected _listHeight:number; + + /** + * @private + */ + protected _listChanged:boolean; + + /** + * @private + */ + protected _itemChanged:boolean; + + /** + * @private + */ + protected _scrollBarSkin:string; + + /** + * @private + */ + protected _isCustomList:boolean; + + /** + * 渲染项,用来显示下拉列表展示对象 + */ + itemRender:any; + + /** + * 创建一个新的 ComboBox 组件实例。 + * @param skin 皮肤资源地址。 + * @param labels 下拉列表的标签集字符串。以逗号做分割,如"item0,item1,item2,item3,item4,item5"。 + */ + + constructor(skin?:string,labels?:string); + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * @inheritDoc + * @override + */ + protected createChildren():void; + private _createList:any; + private _setListEvent:any; + + /** + * @private + */ + private onListDown:any; + private onScrollBarDown:any; + private onButtonMouseDown:any; + + /** + * @copy laya.ui.Button#skin + */ + get skin():string; + set skin(value:string); + + /** + * @inheritDoc + * @override + */ + protected measureWidth():number; + + /** + * @inheritDoc + * @override + */ + protected measureHeight():number; + + /** + * @private + */ + protected changeList():void; + + /** + * @private 下拉列表的鼠标事件响应函数。 + */ + protected onlistItemMouse(e:Event,index:number):void; + + /** + * @private + */ + private switchTo:any; + + /** + * 更改下拉列表的打开状态。 + */ + protected changeOpen():void; + + /** + * @inheritDoc + * @override + */ + set width(value:number); + + /** + * @inheritDoc + * @override + */ + get width():number; + + /** + * @inheritDoc + * @override + */ + set height(value:number); + + /** + * @inheritDoc + * @override + */ + get height():number; + + /** + * 标签集合字符串。 + */ + get labels():string; + set labels(value:string); + + /** + * 更改下拉列表。 + */ + protected changeItem():void; + + /** + * 表示选择的下拉列表项的索引。 + */ + get selectedIndex():number; + set selectedIndex(value:number); + private changeSelected:any; + + /** + * 改变下拉列表的选择项时执行的处理器(默认返回参数index:int)。 + */ + get selectHandler():Handler; + set selectHandler(value:Handler); + + /** + * 表示选择的下拉列表项的的标签。 + */ + get selectedLabel():string; + set selectedLabel(value:string); + + /** + * 获取或设置没有滚动条的下拉列表中可显示的最大行数。 + */ + get visibleNum():number; + set visibleNum(value:number); + + /** + * 下拉列表项颜色。 + *

    格式:"悬停或被选中时背景颜色,悬停或被选中时标签颜色,标签颜色,边框颜色,背景颜色"

    + */ + get itemColors():string; + set itemColors(value:string); + + /** + * 下拉列表项标签的字体大小。 + */ + get itemSize():number; + set itemSize(value:number); + + /** + * 表示下拉列表的打开状态。 + */ + get isOpen():boolean; + set isOpen(value:boolean); + private _onStageMouseWheel:any; + + /** + * 关闭下拉列表。 + */ + protected removeList(e:Event):void; + + /** + * 滚动条皮肤。 + */ + get scrollBarSkin():string; + set scrollBarSkin(value:string); + + /** + *

    当前实例的位图 AutoImage 实例的有效缩放网格数据。

    + *

    数据格式:"上边距,右边距,下边距,左边距,是否重复填充(值为0:不重复填充,1:重复填充)",以逗号分隔。 + *

    • 例如:"4,4,4,4,1"

    + * @see laya.ui.AutoBitmap.sizeGrid + */ + get sizeGrid():string; + set sizeGrid(value:string); + + /** + * 获取对 ComboBox 组件所包含的 VScrollBar 滚动条组件的引用。 + */ + get scrollBar():VScrollBar; + + /** + * 获取对 ComboBox 组件所包含的 Button 组件的引用。 + */ + get button():Button; + + /** + * 获取对 ComboBox 组件所包含的 List 列表组件的引用。 + */ + get list():List; + set list(value:List); + + /** + * @inheritDoc + * @override + */ + set dataSource(value:any); + + /** + * @inheritDoc + * @override + */ + get dataSource():any; + + /** + * 获取或设置对 ComboBox 组件所包含的 Button 组件的文本标签颜色。 + *

    格式:upColor,overColor,downColor,disableColor

    + */ + get labelColors():string; + set labelColors(value:string); + + /** + * 获取或设置对 ComboBox 组件所包含的 Button 组件的文本边距。 + *

    格式:上边距,右边距,下边距,左边距

    + */ + get labelPadding():string; + set labelPadding(value:string); + + /** + * 获取或设置对 ComboBox 组件所包含的 Button 组件的标签字体大小。 + */ + get labelSize():number; + set labelSize(value:number); + + /** + * 表示按钮文本标签是否为粗体字。 + * @see laya.display.Text#bold + */ + get labelBold():boolean; + set labelBold(value:boolean); + + /** + * 表示按钮文本标签的字体名称,以字符串形式表示。 + * @see laya.display.Text#font + */ + get labelFont():string; + set labelFont(value:string); + + /** + * 表示按钮的状态值。 + * @see laya.ui.Button#stateNum + */ + get stateNum():number; + set stateNum(value:number); + } + + /** + * Dialog 组件是一个弹出对话框,实现对话框弹出,拖动,模式窗口功能。 + * 可以通过UIConfig设置弹出框背景透明度,模式窗口点击边缘是否关闭等 + * 通过设置zOrder属性,可以更改弹出的层次 + * 通过设置popupEffect和closeEffect可以设置弹出效果和关闭效果,如果不想有任何弹出关闭效果,可以设置前述属性为空 + * @example 以下示例代码,创建了一个 Dialog 实例。 package { import laya.ui.Dialog; import laya.utils.Handler; public class Dialog_Example { private var dialog:Dialog_Instance; public function Dialog_Example() { Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load("resource/ui/btn_close.png", Handler.create(this, onLoadComplete));//加载资源。 } private function onLoadComplete():void { dialog = new Dialog_Instance();//创建一个 Dialog_Instance 类的实例对象 dialog。 dialog.dragArea = "0,0,150,50";//设置 dialog 的拖拽区域。 dialog.show();//显示 dialog。 dialog.closeHandler = new Handler(this, onClose);//设置 dialog 的关闭函数处理器。 } private function onClose(name:String):void { if (name == Dialog.CLOSE) { trace("通过点击 name 为" + name +"的组件,关闭了dialog。"); } } } } import laya.ui.Button; import laya.ui.Dialog; import laya.ui.Image; class Dialog_Instance extends Dialog { function Dialog_Instance():void { var bg:Image = new Image("resource/ui/bg.png"); bg.sizeGrid = "40,10,5,10"; bg.width = 150; bg.height = 250; addChild(bg); var image:Image = new Image("resource/ui/image.png"); addChild(image); var button:Button = new Button("resource/ui/btn_close.png"); button.name = Dialog.CLOSE;//设置button的name属性值。 button.x = 0; button.y = 0; addChild(button); } } + * @example Laya.init(640, 800);//设置游戏画布宽高、渲染模式 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色 var dialog; Laya.loader.load("resource/ui/btn_close.png", laya.utils.Handler.create(this, loadComplete));//加载资源 (function (_super) {//新建一个类Dialog_Instance继承自laya.ui.Dialog。 function Dialog_Instance() { Dialog_Instance.__super.call(this);//初始化父类 var bg = new laya.ui.Image("resource/ui/bg.png");//新建一个 Image 类的实例 bg 。 bg.sizeGrid = "10,40,10,5";//设置 bg 的网格信息。 bg.width = 150;//设置 bg 的宽度。 bg.height = 250;//设置 bg 的高度。 this.addChild(bg);//将 bg 添加到显示列表。 var image = new laya.ui.Image("resource/ui/image.png");//新建一个 Image 类的实例 image 。 this.addChild(image);//将 image 添加到显示列表。 var button = new laya.ui.Button("resource/ui/btn_close.png");//新建一个 Button 类的实例 bg 。 button.name = laya.ui.Dialog.CLOSE;//设置 button 的 name 属性值。 button.x = 0;//设置 button 对象的属性 x 的值,用于控制 button 对象的显示位置。 button.y = 0;//设置 button 对象的属性 y 的值,用于控制 button 对象的显示位置。 this.addChild(button);//将 button 添加到显示列表。 }; Laya.class(Dialog_Instance,"mypackage.dialogExample.Dialog_Instance",_super);//注册类Dialog_Instance。 })(laya.ui.Dialog); function loadComplete() { console.log("资源加载完成!"); dialog = new mypackage.dialogExample.Dialog_Instance();//创建一个 Dialog_Instance 类的实例对象 dialog。 dialog.dragArea = "0,0,150,50";//设置 dialog 的拖拽区域。 dialog.show();//显示 dialog。 dialog.closeHandler = new laya.utils.Handler(this, onClose);//设置 dialog 的关闭函数处理器。 } function onClose(name) { if (name == laya.ui.Dialog.CLOSE) { console.log("通过点击 name 为" + name + "的组件,关闭了dialog。"); } } + * @example import Dialog = laya.ui.Dialog; import Handler = laya.utils.Handler; class Dialog_Example { private dialog: Dialog_Instance; constructor() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load("resource/ui/btn_close.png", Handler.create(this, this.onLoadComplete));//加载资源。 } private onLoadComplete(): void { this.dialog = new Dialog_Instance();//创建一个 Dialog_Instance 类的实例对象 dialog。 this.dialog.dragArea = "0,0,150,50";//设置 dialog 的拖拽区域。 this.dialog.show();//显示 dialog。 this.dialog.closeHandler = new Handler(this, this.onClose);//设置 dialog 的关闭函数处理器。 } private onClose(name: string): void { if (name == Dialog.CLOSE) { console.log("通过点击 name 为" + name + "的组件,关闭了dialog。"); } } } import Button = laya.ui.Button; class Dialog_Instance extends Dialog { Dialog_Instance(): void { var bg: laya.ui.Image = new laya.ui.Image("resource/ui/bg.png"); bg.sizeGrid = "40,10,5,10"; bg.width = 150; bg.height = 250; this.addChild(bg); var image: laya.ui.Image = new laya.ui.Image("resource/ui/image.png"); this.addChild(image); var button: Button = new Button("resource/ui/btn_close.png"); button.name = Dialog.CLOSE;//设置button的name属性值。 button.x = 0; button.y = 0; this.addChild(button); } } + */ + class Dialog extends View { + + /** + * 对话框内的某个按钮命名为close,点击此按钮则会关闭 + */ + static CLOSE:string; + + /** + * 对话框内的某个按钮命名为cancel,点击此按钮则会关闭 + */ + static CANCEL:string; + + /** + * 对话框内的某个按钮命名为sure,点击此按钮则会关闭 + */ + static SURE:string; + + /** + * 对话框内的某个按钮命名为no,点击此按钮则会关闭 + */ + static NO:string; + + /** + * 对话框内的某个按钮命名为yes,点击此按钮则会关闭 + */ + static YES:string; + + /** + * 对话框内的某个按钮命名为ok,点击此按钮则会关闭 + */ + static OK:string; + + /** + * @private 表示对话框管理器。 + */ + private static _manager:any; + + /** + * 对话框管理容器,所有的对话框都在该容器内,并且受管理器管理,可以自定义自己的管理器,来更改窗口管理的流程。 + * 任意对话框打开和关闭,都会触发管理类的open和close事件 + */ + static get manager():DialogManager; + static set manager(value:DialogManager); + + /** + * 对话框被关闭时会触发的回调函数处理器。 + *

    回调函数参数为用户点击的按钮名字name:String。

    + */ + closeHandler:Handler; + + /** + * 弹出对话框效果,可以设置一个效果代替默认的弹出效果,如果不想有任何效果,可以赋值为null + * 全局默认弹出效果可以通过manager.popupEffect修改 + */ + popupEffect:Handler; + + /** + * 关闭对话框效果,可以设置一个效果代替默认的关闭效果,如果不想有任何效果,可以赋值为null + * 全局默认关闭效果可以通过manager.closeEffect修改 + */ + closeEffect:Handler; + + /** + * 组名称 + */ + group:string; + + /** + * 是否是模式窗口 + */ + isModal:boolean; + + /** + * 是否显示弹出效果 + */ + isShowEffect:boolean; + + /** + * 指定对话框是否居中弹。

    如果值为true,则居中弹出,否则,则根据对象坐标显示,默认为true。

    + */ + isPopupCenter:boolean; + + /** + * 关闭类型,点击name为"close","cancel","sure","no","yes","no"的按钮时,会自动记录点击按钮的名称 + */ + closeType:string; + + /** + * @private + */ + private _dragArea:any; + + constructor(); + + /** + * @private 提取拖拽区域 + */ + protected _dealDragArea():void; + + /** + * 用来指定对话框的拖拽区域。默认值为"0,0,0,0"。 + *

    格式:构成一个矩形所需的 x,y,width,heith 值,用逗号连接为字符串。 + * 例如:"0,0,100,200"。

    + * @see #includeExamplesSummary 请参考示例 + */ + get dragArea():string; + set dragArea(value:string); + + /** + * @private + */ + private _onMouseDown:any; + + /** + * @private 处理默认点击事件 + */ + protected _onClick(e:Event):void; + + /** + * @inheritDoc + * @override + */ + open(closeOther?:boolean,param?:any):void; + + /** + * 关闭对话框。 + * @param type 关闭的原因,会传递给onClosed函数 + * @override + */ + close(type?:string):void; + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * 显示对话框(以非模式窗口方式显示)。 + * @param closeOther 是否关闭其它的对话框。若值为true则关闭其它对话框。 + * @param showEffect 是否显示弹出效果 + */ + show(closeOther?:boolean,showEffect?:boolean):void; + + /** + * 显示对话框(以模式窗口方式显示)。 + * @param closeOther 是否关闭其它的对话框。若值为true则关闭其它对话框。 + * @param showEffect 是否显示弹出效果 + */ + popup(closeOther?:boolean,showEffect?:boolean):void; + + /** + * @private + */ + protected _open(modal:boolean,closeOther:boolean,showEffect:boolean):void; + + /** + * 弹出框的显示状态;如果弹框处于显示中,则为true,否则为false; + */ + get isPopup():boolean; + + /** + * @inheritDoc + * @override + */ + set zOrder(value:number); + + /** + * @inheritDoc + * @override + */ + get zOrder():number; + + /** + * 设置锁定界面,在界面未准备好前显示锁定界面,准备完毕后则移除锁定层,如果为空则什么都不显示 + * @param view 锁定界面内容 + */ + static setLockView(view:UIComponent):void; + + /** + * 锁定所有层,显示加载条信息,防止下面内容被点击 + */ + static lock(value:boolean):void; + + /** + * 关闭所有对话框。 + */ + static closeAll():void; + + /** + * 根据组获取对话框集合 + * @param group 组名称 + * @return 对话框数组 + */ + static getDialogsByGroup(group:string):any[]; + + /** + * 根据组关闭所有弹出框 + * @param group 需要关闭的组名称 + */ + static closeByGroup(group:string):any[]; + } + + /** + * 打开任意窗口后调度。 + * @eventType Event.OPEN + */ + + /** + * 关闭任意窗口后调度。 + * @eventType Event.CLOSE + */ + + /** + * DialogManager 对话框管理容器,所有的对话框都在该容器内,并且受管理器管理。 + * 任意对话框打开和关闭,都会出发管理类的open和close事件 + * 可以通过UIConfig设置弹出框背景透明度,模式窗口点击边缘是否关闭,点击窗口是否切换层次等 + * 通过设置对话框的zOrder属性,可以更改弹出的层次 + */ + class DialogManager extends Sprite { + + /** + * 遮罩层 + */ + maskLayer:Sprite; + + /** + * 锁屏层 + */ + lockLayer:Sprite; + + /** + * @private 全局默认弹出对话框效果,可以设置一个效果代替默认的弹出效果,如果不想有任何效果,可以赋值为null + */ + popupEffect:(dialog:Dialog) =>void; + + /** + * @private 全局默认关闭对话框效果,可以设置一个效果代替默认的关闭效果,如果不想有任何效果,可以赋值为null + */ + closeEffect:(dialog:Dialog) =>void; + + /** + * 全局默认关闭对话框效果,可以设置一个效果代替默认的关闭效果,如果不想有任何效果,可以赋值为null + */ + popupEffectHandler:Handler; + + /** + * 全局默认弹出对话框效果,可以设置一个效果代替默认的弹出效果,如果不想有任何效果,可以赋值为null + */ + closeEffectHandler:Handler; + + /** + * 创建一个新的 DialogManager 类实例。 + */ + + constructor(); + private _closeOnSide:any; + + /** + * 设置锁定界面,如果为空则什么都不显示 + */ + setLockView(value:UIComponent):void; + + /** + * @private + */ + private _onResize:any; + private _centerDialog:any; + + /** + * 显示对话框 + * @param dialog 需要显示的对象框 Dialog 实例。 + * @param closeOther 是否关闭其它对话框,若值为ture,则关闭其它的对话框。 + * @param showEffect 是否显示弹出效果 + */ + open(dialog:Dialog,closeOther?:boolean,showEffect?:boolean):void; + + /** + * @private + */ + private _clearDialogEffect:any; + + /** + * 执行打开对话框。 + * @param dialog 需要关闭的对象框 Dialog 实例。 + */ + doOpen(dialog:Dialog):void; + + /** + * 锁定所有层,显示加载条信息,防止双击 + */ + lock(value:boolean):void; + + /** + * 关闭对话框。 + * @param dialog 需要关闭的对象框 Dialog 实例。 + */ + close(dialog:Dialog):void; + + /** + * 执行关闭对话框。 + * @param dialog 需要关闭的对象框 Dialog 实例。 + */ + doClose(dialog:Dialog):void; + + /** + * 关闭所有的对话框。 + */ + closeAll():void; + + /** + * @private + */ + private _closeAll:any; + + /** + * 根据组获取所有对话框 + * @param group 组名称 + * @return 对话框数组 + */ + getDialogsByGroup(group:string):any[]; + + /** + * 根据组关闭所有弹出框 + * @param group 需要关闭的组名称 + * @return 需要关闭的对话框数组 + */ + closeByGroup(group:string):any[]; + } + + /** + * 字体切片,简化版的位图字体,只需设置一个切片图片和文字内容即可使用,效果同位图字体 + * 使用方式:设置位图字体皮肤skin,设置皮肤对应的字体内容sheet(如果多行,可以使用空格换行),示例: + * fontClip.skin = "font1.png";//设置皮肤 + * fontClip.sheet = "abc123 456";//设置皮肤对应的内容,空格换行。此皮肤为2行5列(显示时skin会被等分为2行5列),第一行对应的文字为"abc123",第二行为"456" + * fontClip.value = "a1326";//显示"a1326"文字 + */ + class FontClip extends Clip { + + /** + * 数值 + */ + protected _valueArr:string; + + /** + * 文字内容数组* + */ + protected _indexMap:any; + + /** + * 位图字体内容* + */ + protected _sheet:string; + + /** + * @private + */ + protected _direction:string; + + /** + * X方向间隙 + */ + protected _spaceX:number; + + /** + * Y方向间隙 + */ + protected _spaceY:number; + + /** + * @private 水平对齐方式 + */ + private _align:any; + + /** + * @private 显示文字宽 + */ + private _wordsW:any; + + /** + * @private 显示文字高 + */ + private _wordsH:any; + + /** + * @param skin 位图字体皮肤 + * @param sheet 位图字体内容,空格代表换行 + */ + + constructor(skin?:string,sheet?:string); + + /** + * @override + */ + protected createChildren():void; + + /** + * 资源加载完毕 + */ + private _onClipLoaded:any; + + /** + * 设置位图字体内容,空格代表换行。比如"abc123 456",代表第一行对应的文字为"abc123",第二行为"456" + */ + get sheet():string; + set sheet(value:string); + + /** + * 设置位图字体的显示内容 + */ + get value():string; + set value(value:string); + + /** + * 布局方向。 + *

    默认值为"horizontal"。

    + *

    取值: + *

  • "horizontal":表示水平布局。
  • + *
  • "vertical":表示垂直布局。
  • + *

    + */ + get direction():string; + set direction(value:string); + + /** + * X方向文字间隙 + */ + get spaceX():number; + set spaceX(value:number); + + /** + * Y方向文字间隙 + */ + get spaceY():number; + set spaceY(value:number); + set align(v:string); + + /** + * 水平对齐方式 + */ + get align():string; + + /** + * 渲染数值 + */ + protected changeValue():void; + + /** + * @override + */ + set width(value:number); + + /** + * @inheritDoc + * @override + */ + get width():number; + + /** + * @override + */ + set height(value:number); + + /** + * @inheritDoc + * @override + */ + get height():number; + + /** + * @override + */ + protected measureWidth():number; + + /** + * @override + */ + protected measureHeight():number; + + /** + * @param destroyChild + * @override + */ + destroy(destroyChild?:boolean):void; + } + + /** + * HBox 是一个水平布局容器类。 + */ + class HBox extends LayoutBox { + + /** + * 无对齐。 + */ + static NONE:string; + + /** + * 居顶部对齐。 + */ + static TOP:string; + + /** + * 居中对齐。 + */ + static MIDDLE:string; + + /** + * 居底部对齐。 + */ + static BOTTOM:string; + + /** + * @inheritDoc + * @override + */ + protected sortItem(items:any[]):void; + + /** + * @inheritDoc + * @override + */ + set height(value:number); + + /** + * @inheritDoc + * @override + */ + get height():number; + + /** + * @inheritDoc + * @override + */ + protected changeItems():void; + } + + /** + * 使用 HScrollBar (水平 ScrollBar )控件,可以在因数据太多而不能在显示区域完全显示时控制显示的数据部分。 + * @example 以下示例代码,创建了一个 HScrollBar 实例。 package { import laya.ui.HScrollBar; import laya.utils.Handler; public class HScrollBar_Example { private var hScrollBar:HScrollBar; public function HScrollBar_Example() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/hscroll.png", "resource/ui/hscroll$bar.png", "resource/ui/hscroll$down.png", "resource/ui/hscroll$up.png"], Handler.create(this, onLoadComplete));//加载资源。 } private function onLoadComplete():void { hScrollBar = new HScrollBar();//创建一个 HScrollBar 类的实例对象 hScrollBar 。 hScrollBar.skin = "resource/ui/hscroll.png";//设置 hScrollBar 的皮肤。 hScrollBar.x = 100;//设置 hScrollBar 对象的属性 x 的值,用于控制 hScrollBar 对象的显示位置。 hScrollBar.y = 100;//设置 hScrollBar 对象的属性 y 的值,用于控制 hScrollBar 对象的显示位置。 hScrollBar.changeHandler = new Handler(this, onChange);//设置 hScrollBar 的滚动变化处理器。 Laya.stage.addChild(hScrollBar);//将此 hScrollBar 对象添加到显示列表。 } private function onChange(value:Number):void { trace("滚动条的位置: value=" + value); } } } + * @example Laya.init(640, 800);//设置游戏画布宽高 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色 var hScrollBar; var res = ["resource/ui/hscroll.png", "resource/ui/hscroll$bar.png", "resource/ui/hscroll$down.png", "resource/ui/hscroll$up.png"]; Laya.loader.load(res,laya.utils.Handler.create(this, onLoadComplete));//加载资源。 function onLoadComplete() { console.log("资源加载完成!"); hScrollBar = new laya.ui.HScrollBar();//创建一个 HScrollBar 类的实例对象 hScrollBar 。 hScrollBar.skin = "resource/ui/hscroll.png";//设置 hScrollBar 的皮肤。 hScrollBar.x = 100;//设置 hScrollBar 对象的属性 x 的值,用于控制 hScrollBar 对象的显示位置。 hScrollBar.y = 100;//设置 hScrollBar 对象的属性 y 的值,用于控制 hScrollBar 对象的显示位置。 hScrollBar.changeHandler = new laya.utils.Handler(this, onChange);//设置 hScrollBar 的滚动变化处理器。 Laya.stage.addChild(hScrollBar);//将此 hScrollBar 对象添加到显示列表。 } function onChange(value) { console.log("滚动条的位置: value=" + value); } + * @example import HScrollBar = laya.ui.HScrollBar; import Handler = laya.utils.Handler; class HScrollBar_Example { private hScrollBar: HScrollBar; constructor() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/hscroll.png", "resource/ui/hscroll$bar.png", "resource/ui/hscroll$down.png", "resource/ui/hscroll$up.png"], Handler.create(this, this.onLoadComplete));//加载资源。 } private onLoadComplete(): void { this.hScrollBar = new HScrollBar();//创建一个 HScrollBar 类的实例对象 hScrollBar 。 this.hScrollBar.skin = "resource/ui/hscroll.png";//设置 hScrollBar 的皮肤。 this.hScrollBar.x = 100;//设置 hScrollBar 对象的属性 x 的值,用于控制 hScrollBar 对象的显示位置。 this.hScrollBar.y = 100;//设置 hScrollBar 对象的属性 y 的值,用于控制 hScrollBar 对象的显示位置。 this.hScrollBar.changeHandler = new Handler(this, this.onChange);//设置 hScrollBar 的滚动变化处理器。 Laya.stage.addChild(this.hScrollBar);//将此 hScrollBar 对象添加到显示列表。 } private onChange(value: number): void { console.log("滚动条的位置: value=" + value); } } + */ + class HScrollBar extends ScrollBar { + + /** + * @override + * @inheritDoc + */ + protected initialize():void; + } + + /** + * 使用 HSlider 控件,用户可以通过在滑块轨道的终点之间移动滑块来选择值。 + *

    HSlider 控件采用水平方向。滑块轨道从左向右扩展,而标签位于轨道的顶部或底部。

    + * @example 以下示例代码,创建了一个 HSlider 实例。 package { import laya.ui.HSlider; import laya.utils.Handler; public class HSlider_Example { private var hSlider:HSlider; public function HSlider_Example() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/hslider.png", "resource/ui/hslider$bar.png"], Handler.create(this, onLoadComplete));//加载资源。 } private function onLoadComplete():void { hSlider = new HSlider();//创建一个 HSlider 类的实例对象 hSlider 。 hSlider.skin = "resource/ui/hslider.png";//设置 hSlider 的皮肤。 hSlider.min = 0;//设置 hSlider 最低位置值。 hSlider.max = 10;//设置 hSlider 最高位置值。 hSlider.value = 2;//设置 hSlider 当前位置值。 hSlider.tick = 1;//设置 hSlider 刻度值。 hSlider.x = 100;//设置 hSlider 对象的属性 x 的值,用于控制 hSlider 对象的显示位置。 hSlider.y = 100;//设置 hSlider 对象的属性 y 的值,用于控制 hSlider 对象的显示位置。 hSlider.changeHandler = new Handler(this, onChange);//设置 hSlider 位置变化处理器。 Laya.stage.addChild(hSlider);//把 hSlider 添加到显示列表。 } private function onChange(value:Number):void { trace("滑块的位置: value=" + value); } } } + * @example Laya.init(640, 800, "canvas");//设置游戏画布宽高、渲染模式 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色 var hSlider; var res = ["resource/ui/hslider.png", "resource/ui/hslider$bar.png"]; Laya.loader.load(res, laya.utils.Handler.create(this, onLoadComplete)); function onLoadComplete() { console.log("资源加载完成!"); hSlider = new laya.ui.HSlider();//创建一个 HSlider 类的实例对象 hSlider 。 hSlider.skin = "resource/ui/hslider.png";//设置 hSlider 的皮肤。 hSlider.min = 0;//设置 hSlider 最低位置值。 hSlider.max = 10;//设置 hSlider 最高位置值。 hSlider.value = 2;//设置 hSlider 当前位置值。 hSlider.tick = 1;//设置 hSlider 刻度值。 hSlider.x = 100;//设置 hSlider 对象的属性 x 的值,用于控制 hSlider 对象的显示位置。 hSlider.y = 100;//设置 hSlider 对象的属性 y 的值,用于控制 hSlider 对象的显示位置。 hSlider.changeHandler = new laya.utils.Handler(this, onChange);//设置 hSlider 位置变化处理器。 Laya.stage.addChild(hSlider);//把 hSlider 添加到显示列表。 } function onChange(value) { console.log("滑块的位置: value=" + value); } + * @example import Handler = laya.utils.Handler; import HSlider = laya.ui.HSlider; class HSlider_Example { private hSlider: HSlider; constructor() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/hslider.png", "resource/ui/hslider$bar.png"], Handler.create(this, this.onLoadComplete));//加载资源。 } private onLoadComplete(): void { this.hSlider = new HSlider();//创建一个 HSlider 类的实例对象 hSlider 。 this.hSlider.skin = "resource/ui/hslider.png";//设置 hSlider 的皮肤。 this.hSlider.min = 0;//设置 hSlider 最低位置值。 this.hSlider.max = 10;//设置 hSlider 最高位置值。 this.hSlider.value = 2;//设置 hSlider 当前位置值。 this.hSlider.tick = 1;//设置 hSlider 刻度值。 this.hSlider.x = 100;//设置 hSlider 对象的属性 x 的值,用于控制 hSlider 对象的显示位置。 this.hSlider.y = 100;//设置 hSlider 对象的属性 y 的值,用于控制 hSlider 对象的显示位置。 this.hSlider.changeHandler = new Handler(this, this.onChange);//设置 hSlider 位置变化处理器。 Laya.stage.addChild(this.hSlider);//把 hSlider 添加到显示列表。 } private onChange(value: number): void { console.log("滑块的位置: value=" + value); } } + * @see laya.ui.Slider + */ + class HSlider extends Slider { + + /** + * 创建一个 HSlider 类实例。 + * @param skin 皮肤。 + */ + + constructor(skin?:string); + } + + interface IBox{ + } + + + interface IItem{ + + /** + * 初始化列表项。 + */ + initItems():void; + } + + + /** + * 资源加载完成后调度。 + * @eventType Event.LOADED + */ + + /** + * Image 类是用于表示位图图像或绘制图形的显示对象。 + * Image和Clip组件是唯一支持异步加载的两个组件,比如img.skin = "abc/xxx.png",其他UI组件均不支持异步加载。 + * @example 以下示例代码,创建了一个新的 Image 实例,设置了它的皮肤、位置信息,并添加到舞台上。 package { import laya.ui.Image; public class Image_Example { public function Image_Example() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 onInit(); } private function onInit():void { var bg:Image = new Image("resource/ui/bg.png");//创建一个 Image 类的实例对象 bg ,并传入它的皮肤。 bg.x = 100;//设置 bg 对象的属性 x 的值,用于控制 bg 对象的显示位置。 bg.y = 100;//设置 bg 对象的属性 y 的值,用于控制 bg 对象的显示位置。 bg.sizeGrid = "40,10,5,10";//设置 bg 对象的网格信息。 bg.width = 150;//设置 bg 对象的宽度。 bg.height = 250;//设置 bg 对象的高度。 Laya.stage.addChild(bg);//将此 bg 对象添加到显示列表。 var image:Image = new Image("resource/ui/image.png");//创建一个 Image 类的实例对象 image ,并传入它的皮肤。 image.x = 100;//设置 image 对象的属性 x 的值,用于控制 image 对象的显示位置。 image.y = 100;//设置 image 对象的属性 y 的值,用于控制 image 对象的显示位置。 Laya.stage.addChild(image);//将此 image 对象添加到显示列表。 } } } + * @example Laya.init(640, 800);//设置游戏画布宽高 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色 onInit(); function onInit() { var bg = new laya.ui.Image("resource/ui/bg.png");//创建一个 Image 类的实例对象 bg ,并传入它的皮肤。 bg.x = 100;//设置 bg 对象的属性 x 的值,用于控制 bg 对象的显示位置。 bg.y = 100;//设置 bg 对象的属性 y 的值,用于控制 bg 对象的显示位置。 bg.sizeGrid = "40,10,5,10";//设置 bg 对象的网格信息。 bg.width = 150;//设置 bg 对象的宽度。 bg.height = 250;//设置 bg 对象的高度。 Laya.stage.addChild(bg);//将此 bg 对象添加到显示列表。 var image = new laya.ui.Image("resource/ui/image.png");//创建一个 Image 类的实例对象 image ,并传入它的皮肤。 image.x = 100;//设置 image 对象的属性 x 的值,用于控制 image 对象的显示位置。 image.y = 100;//设置 image 对象的属性 y 的值,用于控制 image 对象的显示位置。 Laya.stage.addChild(image);//将此 image 对象添加到显示列表。 } + * @example class Image_Example { constructor() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 this.onInit(); } private onInit(): void { var bg: laya.ui.Image = new laya.ui.Image("resource/ui/bg.png");//创建一个 Image 类的实例对象 bg ,并传入它的皮肤。 bg.x = 100;//设置 bg 对象的属性 x 的值,用于控制 bg 对象的显示位置。 bg.y = 100;//设置 bg 对象的属性 y 的值,用于控制 bg 对象的显示位置。 bg.sizeGrid = "40,10,5,10";//设置 bg 对象的网格信息。 bg.width = 150;//设置 bg 对象的宽度。 bg.height = 250;//设置 bg 对象的高度。 Laya.stage.addChild(bg);//将此 bg 对象添加到显示列表。 var image: laya.ui.Image = new laya.ui.Image("resource/ui/image.png");//创建一个 Image 类的实例对象 image ,并传入它的皮肤。 image.x = 100;//设置 image 对象的属性 x 的值,用于控制 image 对象的显示位置。 image.y = 100;//设置 image 对象的属性 y 的值,用于控制 image 对象的显示位置。 Laya.stage.addChild(image);//将此 image 对象添加到显示列表。 } } + * @see laya.ui.AutoBitmap + */ + class Image extends UIComponent { + + /** + * @private + */ + protected _skin:string; + + /** + * @private + */ + protected _group:string; + + /** + * 创建一个 Image 实例。 + * @param skin 皮肤资源地址。 + */ + + constructor(skin?:string|null); + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * 销毁对象并释放加载的皮肤资源。 + */ + dispose():void; + + /** + * @inheritDoc + * @override + */ + protected createChildren():void; + + /** + *

    对象的皮肤地址,以字符串表示。

    + *

    如果资源未加载,则先加载资源,加载完成后应用于此对象。

    + * 注意:资源加载完成后,会自动缓存至资源库中。 + */ + get skin():string; + set skin(value:string); + + /** + * @copy laya.ui.AutoBitmap#source + */ + get source():Texture; + set source(value:Texture); + + /** + * 资源分组。 + */ + get group():string; + set group(value:string); + + /** + * @private 设置皮肤资源。 + */ + protected setSource(url:string,img?:any):void; + + /** + * @inheritDoc + * @override + */ + protected measureWidth():number; + + /** + * @inheritDoc + * @override + */ + protected measureHeight():number; + + /** + * @inheritDoc + * @override + */ + set width(value:number); + + /** + * @inheritDoc + * @override + */ + get width():number; + + /** + * @inheritDoc + * @override + */ + set height(value:number); + + /** + * @inheritDoc + * @override + */ + get height():number; + + /** + *

    当前实例的位图 AutoImage 实例的有效缩放网格数据。

    + *

    数据格式:"上边距,右边距,下边距,左边距,是否重复填充(值为0:不重复填充,1:重复填充)",以逗号分隔。 + *

    • 例如:"4,4,4,4,1"。

    + * @see laya.ui.AutoBitmap#sizeGrid + */ + get sizeGrid():string; + set sizeGrid(value:string); + + /** + * @inheritDoc + * @override + */ + set dataSource(value:any); + + /** + * @inheritDoc + * @override + */ + get dataSource():any; + } + + interface IRender{ + + /** + * 渲染项。 + */ + itemRender:any; + } + + + interface ISelect{ + + /** + * 一个布尔值,表示是否被选择。 + */ + selected:boolean; + + /** + * 对象的点击事件回掉函数处理器。 + */ + clickHandler:Handler; + } + + + /** + * 文本内容发生改变后调度。 + * @eventType laya.events.Event + */ + + /** + *

    Label 类用于创建显示对象以显示文本。

    + * @example 以下示例代码,创建了一个 Label 实例。 package { import laya.ui.Label; public class Label_Example { public function Label_Example() { Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 onInit(); } private function onInit():void { var label:Label = new Label();//创建一个 Label 类的实例对象 label 。 label.font = "Arial";//设置 label 的字体。 label.bold = true;//设置 label 显示为粗体。 label.leading = 4;//设置 label 的行间距。 label.wordWrap = true;//设置 label 自动换行。 label.padding = "10,10,10,10";//设置 label 的边距。 label.color = "#ff00ff";//设置 label 的颜色。 label.text = "Hello everyone,我是一个可爱的文本!";//设置 label 的文本内容。 label.x = 100;//设置 label 对象的属性 x 的值,用于控制 label 对象的显示位置。 label.y = 100;//设置 label 对象的属性 y 的值,用于控制 label 对象的显示位置。 label.width = 300;//设置 label 的宽度。 label.height = 200;//设置 label 的高度。 Laya.stage.addChild(label);//将 label 添加到显示列表。 var passwordLabel:Label = new Label("请原谅我,我不想被人看到我心里话。");//创建一个 Label 类的实例对象 passwordLabel 。 passwordLabel.asPassword = true;//设置 passwordLabel 的显示反式为密码显示。 passwordLabel.x = 100;//设置 passwordLabel 对象的属性 x 的值,用于控制 passwordLabel 对象的显示位置。 passwordLabel.y = 350;//设置 passwordLabel 对象的属性 y 的值,用于控制 passwordLabel 对象的显示位置。 passwordLabel.width = 300;//设置 passwordLabel 的宽度。 passwordLabel.color = "#000000";//设置 passwordLabel 的文本颜色。 passwordLabel.bgColor = "#ccffff";//设置 passwordLabel 的背景颜色。 passwordLabel.fontSize = 20;//设置 passwordLabel 的文本字体大小。 Laya.stage.addChild(passwordLabel);//将 passwordLabel 添加到显示列表。 } } } + * @example Laya.init(640, 800);//设置游戏画布宽高 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色 onInit(); function onInit(){ var label = new laya.ui.Label();//创建一个 Label 类的实例对象 label 。 label.font = "Arial";//设置 label 的字体。 label.bold = true;//设置 label 显示为粗体。 label.leading = 4;//设置 label 的行间距。 label.wordWrap = true;//设置 label 自动换行。 label.padding = "10,10,10,10";//设置 label 的边距。 label.color = "#ff00ff";//设置 label 的颜色。 label.text = "Hello everyone,我是一个可爱的文本!";//设置 label 的文本内容。 label.x = 100;//设置 label 对象的属性 x 的值,用于控制 label 对象的显示位置。 label.y = 100;//设置 label 对象的属性 y 的值,用于控制 label 对象的显示位置。 label.width = 300;//设置 label 的宽度。 label.height = 200;//设置 label 的高度。 Laya.stage.addChild(label);//将 label 添加到显示列表。 var passwordLabel = new laya.ui.Label("请原谅我,我不想被人看到我心里话。");//创建一个 Label 类的实例对象 passwordLabel 。 passwordLabel.asPassword = true;//设置 passwordLabel 的显示反式为密码显示。 passwordLabel.x = 100;//设置 passwordLabel 对象的属性 x 的值,用于控制 passwordLabel 对象的显示位置。 passwordLabel.y = 350;//设置 passwordLabel 对象的属性 y 的值,用于控制 passwordLabel 对象的显示位置。 passwordLabel.width = 300;//设置 passwordLabel 的宽度。 passwordLabel.color = "#000000";//设置 passwordLabel 的文本颜色。 passwordLabel.bgColor = "#ccffff";//设置 passwordLabel 的背景颜色。 passwordLabel.fontSize = 20;//设置 passwordLabel 的文本字体大小。 Laya.stage.addChild(passwordLabel);//将 passwordLabel 添加到显示列表。 } + * @example import Label = laya.ui.Label; class Label_Example { constructor() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 this.onInit(); } private onInit(): void { var label: Label = new Label();//创建一个 Label 类的实例对象 label 。 label.font = "Arial";//设置 label 的字体。 label.bold = true;//设置 label 显示为粗体。 label.leading = 4;//设置 label 的行间距。 label.wordWrap = true;//设置 label 自动换行。 label.padding = "10,10,10,10";//设置 label 的边距。 label.color = "#ff00ff";//设置 label 的颜色。 label.text = "Hello everyone,我是一个可爱的文本!";//设置 label 的文本内容。 label.x = 100;//设置 label 对象的属性 x 的值,用于控制 label 对象的显示位置。 label.y = 100;//设置 label 对象的属性 y 的值,用于控制 label 对象的显示位置。 label.width = 300;//设置 label 的宽度。 label.height = 200;//设置 label 的高度。 Laya.stage.addChild(label);//将 label 添加到显示列表。 var passwordLabel: Label = new Label("请原谅我,我不想被人看到我心里话。");//创建一个 Label 类的实例对象 passwordLabel 。 passwordLabel.asPassword = true;//设置 passwordLabel 的显示反式为密码显示。 passwordLabel.x = 100;//设置 passwordLabel 对象的属性 x 的值,用于控制 passwordLabel 对象的显示位置。 passwordLabel.y = 350;//设置 passwordLabel 对象的属性 y 的值,用于控制 passwordLabel 对象的显示位置。 passwordLabel.width = 300;//设置 passwordLabel 的宽度。 passwordLabel.color = "#000000";//设置 passwordLabel 的文本颜色。 passwordLabel.bgColor = "#ccffff";//设置 passwordLabel 的背景颜色。 passwordLabel.fontSize = 20;//设置 passwordLabel 的文本字体大小。 Laya.stage.addChild(passwordLabel);//将 passwordLabel 添加到显示列表。 } } + * @see laya.display.Text + */ + class Label extends UIComponent { + + /** + * @private 文本 Text 实例。 + */ + protected _tf:Text; + + /** + * 创建一个新的 Label 实例。 + * @param text 文本内容字符串。 + */ + + constructor(text?:string); + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * @override + * @inheritDoc + */ + protected createChildren():void; + + /** + * 当前文本内容字符串。 + * @see laya.display.Text.text + */ + get text():string; + set text(value:string); + + /** + * @copy laya.display.Text#changeText() + */ + changeText(text:string):void; + + /** + * @copy laya.display.Text#wordWrap + */ + get wordWrap():boolean; + + /** + * @copy laya.display.Text#wordWrap + */ + set wordWrap(value:boolean); + + /** + * @copy laya.display.Text#color + */ + get color():string; + set color(value:string); + + /** + * @copy laya.display.Text#font + */ + get font():string; + set font(value:string); + + /** + * @copy laya.display.Text#align + */ + get align():string; + set align(value:string); + + /** + * @copy laya.display.Text#valign + */ + get valign():string; + set valign(value:string); + + /** + * @copy laya.display.Text#bold + */ + get bold():boolean; + set bold(value:boolean); + + /** + * @copy laya.display.Text#italic + */ + get italic():boolean; + set italic(value:boolean); + + /** + * @copy laya.display.Text#leading + */ + get leading():number; + set leading(value:number); + + /** + * @copy laya.display.Text#fontSize + */ + get fontSize():number; + set fontSize(value:number); + + /** + *

    边距信息

    + *

    "上边距,右边距,下边距 , 左边距(边距以像素为单位)"

    + * @see laya.display.Text.padding + */ + get padding():string; + set padding(value:string); + + /** + * @copy laya.display.Text#bgColor + */ + get bgColor():string; + set bgColor(value:string); + + /** + * @copy laya.display.Text#borderColor + */ + get borderColor():string; + set borderColor(value:string); + + /** + * @copy laya.display.Text#stroke + */ + get stroke():number; + set stroke(value:number); + + /** + * @copy laya.display.Text#strokeColor + */ + get strokeColor():string; + set strokeColor(value:string); + + /** + * 文本控件实体 Text 实例。 + */ + get textField():Text; + + /** + * @inheritDoc + * @override + */ + protected measureWidth():number; + + /** + * @inheritDoc + * @override + */ + protected measureHeight():number; + + /** + * @inheritDoc + * @override + */ + get width():number; + + /** + * @inheritDoc + * @override + */ + set width(value:number); + + /** + * @inheritDoc + * @override + */ + get height():number; + + /** + * @inheritDoc + * @override + */ + set height(value:number); + + /** + * @inheritDoc + * @override + */ + set dataSource(value:any); + + /** + * @inheritDoc + * @override + */ + get dataSource():any; + + /** + * @copy laya.display.Text#overflow + */ + get overflow():string; + + /** + * @copy laya.display.Text#overflow + */ + set overflow(value:string); + + /** + * @copy laya.display.Text#underline + */ + get underline():boolean; + + /** + * @copy laya.display.Text#underline + */ + set underline(value:boolean); + + /** + * @copy laya.display.Text#underlineColor + */ + get underlineColor():string; + + /** + * @copy laya.display.Text#underlineColor + */ + set underlineColor(value:string); + } + + /** + * LayoutBox 是一个布局容器类。 + */ + class LayoutBox extends Box { + + /** + * @private + */ + protected _space:number; + + /** + * @private + */ + protected _align:string; + + /** + * @private + */ + protected _itemChanged:boolean; + + /** + * @inheritDoc + * @override + */ + addChild(child:Node):Node; + private onResize:any; + + /** + * @inheritDoc + * @override + */ + addChildAt(child:Node,index:number):Node; + + /** + * @inheritDoc + * @override + */ + removeChildAt(index:number):Node; + + /** + * 刷新。 + */ + refresh():void; + + /** + * 改变子对象的布局。 + */ + protected changeItems():void; + + /** + * 子对象的间隔。 + */ + get space():number; + set space(value:number); + + /** + * 子对象对齐方式。 + */ + get align():string; + set align(value:string); + + /** + * 排序项目列表。可通过重写改变默认排序规则。 + * @param items 项目列表。 + */ + protected sortItem(items:any[]):void; + protected _setItemChanged():void; + } + + /** + * 当对象的 selectedIndex 属性发生变化时调度。 + * @eventType laya.events.Event + */ + + /** + * 渲染列表的单元项对象时调度。 + * @eventType Event.RENDER + */ + + /** + * List 控件可显示项目列表。默认为垂直方向列表。可通过UI编辑器自定义列表。 + * @example 以下示例代码,创建了一个 List 实例。 package { import laya.ui.List; import laya.utils.Handler; public class List_Example { public function List_Example() { Laya.init(640, 800, "false");//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/vscroll.png", "resource/ui/vscroll$bar.png", "resource/ui/vscroll$down.png", "resource/ui/vscroll$up.png"], Handler.create(this, onLoadComplete)); } private function onLoadComplete():void { var arr:Array = [];//创建一个数组,用于存贮列表的数据信息。 for (var i:int = 0; i < 20; i++) { arr.push({label: "item" + i}); } var list:List = new List();//创建一个 List 类的实例对象 list 。 list.itemRender = Item;//设置 list 的单元格渲染器。 list.repeatX = 1;//设置 list 的水平方向单元格数量。 list.repeatY = 10;//设置 list 的垂直方向单元格数量。 list.vScrollBarSkin = "resource/ui/vscroll.png";//设置 list 的垂直方向滚动条皮肤。 list.array = arr;//设置 list 的列表数据源。 list.pos(100, 100);//设置 list 的位置。 list.selectEnable = true;//设置 list 可选。 list.selectHandler = new Handler(this, onSelect);//设置 list 改变选择项执行的处理器。 Laya.stage.addChild(list);//将 list 添加到显示列表。 } private function onSelect(index:int):void { trace("当前选择的项目索引: index= ", index); } } } import laya.ui.Box; import laya.ui.Label; class Item extends Box { public function Item() { graphics.drawRect(0, 0, 100, 20,null, "#ff0000"); var label:Label = new Label(); label.text = "100000"; label.name = "label";//设置 label 的name属性值。 label.size(100, 20); addChild(label); } } + * @example (function (_super){ function Item(){ Item.__super.call(this);//初始化父类 this.graphics.drawRect(0, 0, 100, 20, "#ff0000"); var label = new laya.ui.Label();//创建一个 Label 类的实例对象 label 。 label.text = "100000";//设置 label 的文本内容。 label.name = "label";//设置 label 的name属性值。 label.size(100, 20);//设置 label 的宽度、高度。 this.addChild(label);//将 label 添加到显示列表。 }; Laya.class(Item,"mypackage.listExample.Item",_super);//注册类 Item 。 })(laya.ui.Box); Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 var res = ["resource/ui/vscroll.png", "resource/ui/vscroll$bar.png", "resource/ui/vscroll$down.png", "resource/ui/vscroll$up.png"]; Laya.loader.load(res, new laya.utils.Handler(this, onLoadComplete));//加载资源。 function onLoadComplete() { var arr = [];//创建一个数组,用于存贮列表的数据信息。 for (var i = 0; i < 20; i++) { arr.push({label: "item" + i}); } var list = new laya.ui.List();//创建一个 List 类的实例对象 list 。 list.itemRender = mypackage.listExample.Item;//设置 list 的单元格渲染器。 list.repeatX = 1;//设置 list 的水平方向单元格数量。 list.repeatY = 10;//设置 list 的垂直方向单元格数量。 list.vScrollBarSkin = "resource/ui/vscroll.png";//设置 list 的垂直方向滚动条皮肤。 list.array = arr;//设置 list 的列表数据源。 list.pos(100, 100);//设置 list 的位置。 list.selectEnable = true;//设置 list 可选。 list.selectHandler = new laya.utils.Handler(this, onSelect);//设置 list 改变选择项执行的处理器。 Laya.stage.addChild(list);//将 list 添加到显示列表。 } function onSelect(index) { console.log("当前选择的项目索引: index= ", index); } + * @example import List = laya.ui.List; import Handler = laya.utils.Handler; public class List_Example { public List_Example() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/vscroll.png", "resource/ui/vscroll$bar.png", "resource/ui/vscroll$down.png", "resource/ui/vscroll$up.png"], Handler.create(this, this.onLoadComplete)); } private onLoadComplete(): void { var arr= [];//创建一个数组,用于存贮列表的数据信息。 for (var i: number = 0; i < 20; i++) { arr.push({ label: "item" + i }); } var list: List = new List();//创建一个 List 类的实例对象 list 。 list.itemRender = Item;//设置 list 的单元格渲染器。 list.repeatX = 1;//设置 list 的水平方向单元格数量。 list.repeatY = 10;//设置 list 的垂直方向单元格数量。 list.vScrollBarSkin = "resource/ui/vscroll.png";//设置 list 的垂直方向滚动条皮肤。 list.array = arr;//设置 list 的列表数据源。 list.pos(100, 100);//设置 list 的位置。 list.selectEnable = true;//设置 list 可选。 list.selectHandler = new Handler(this, this.onSelect);//设置 list 改变选择项执行的处理器。 Laya.stage.addChild(list);//将 list 添加到显示列表。 } private onSelect(index: number): void { console.log("当前选择的项目索引: index= ", index); } } import Box = laya.ui.Box; import Label = laya.ui.Label; class Item extends Box { constructor() { this.graphics.drawRect(0, 0, 100, 20, null, "#ff0000"); var label: Label = new Label(); label.text = "100000"; label.name = "label";//设置 label 的name属性值。 label.size(100, 20); this.addChild(label); } } + */ + class List extends Box implements IRender,IItem { + + /** + * 改变 List 的选择项时执行的处理器,(默认返回参数: 项索引(index:int))。 + */ + selectHandler:Handler|null; + + /** + * 单元格渲染处理器(默认返回参数cell:Box,index:int)。 + */ + renderHandler:Handler|null; + + /** + * 单元格鼠标事件处理器(默认返回参数e:Event,index:int)。 + */ + mouseHandler:Handler|null; + + /** + * 指定是否可以选择,若值为true则可以选择,否则不可以选择。 @default false + */ + selectEnable:boolean; + + /** + * 最大分页数。 + */ + totalPage:number; + + /** + * @private + */ + protected _content:Box; + + /** + * @private + */ + protected _scrollBar:ScrollBar|null; + + /** + * @private + */ + protected _itemRender:any; + + /** + * @private + */ + protected _repeatX:number; + + /** + * @private + */ + protected _repeatY:number; + + /** + * @private + */ + protected _repeatX2:number; + + /** + * @private + */ + protected _repeatY2:number; + + /** + * @private + */ + protected _spaceX:number; + + /** + * @private + */ + protected _spaceY:number; + + /** + * @private + */ + protected _cells:Box[]; + + /** + * @private + */ + protected _array:any[]|null; + + /** + * @private + */ + protected _startIndex:number; + + /** + * @private + */ + protected _selectedIndex:number; + + /** + * @private + */ + protected _page:number; + + /** + * @private + */ + protected _isVertical:boolean; + + /** + * @private + */ + protected _cellSize:number; + + /** + * @private + */ + protected _cellOffset:number; + + /** + * @private + */ + protected _isMoved:boolean; + + /** + * 是否缓存内容,如果数据源较少,并且list内无动画,设置此属性为true能大大提高性能 + */ + cacheContent:boolean; + + /** + * @private + */ + protected _createdLine:number; + + /** + * @private + */ + protected _cellChanged:boolean; + + /** + * @private + */ + protected _offset:Point; + + /** + * @private + */ + protected _usedCache:string|null; + + /** + * @private + */ + protected _elasticEnabled:boolean; + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * @inheritDoc + * @override + */ + protected createChildren():void; + + /** + * @inheritDoc + * @override + */ + set cacheAs(value:string); + + /** + * @inheritDoc + * @override + */ + get cacheAs():string; + private onScrollStart:any; + private onScrollEnd:any; + + /** + * 获取对 List 组件所包含的内容容器 Box 组件的引用。 + */ + get content():Box; + + /** + * 垂直方向滚动条皮肤。 + */ + get vScrollBarSkin():string; + set vScrollBarSkin(value:string); + private _removePreScrollBar:any; + + /** + * 水平方向滚动条皮肤。 + */ + get hScrollBarSkin():string; + set hScrollBarSkin(value:string); + + /** + * 获取对 List 组件所包含的滚动条 ScrollBar 组件的引用。 + */ + get scrollBar():ScrollBar|null; + set scrollBar(value:ScrollBar|null); + + /** + * 单元格渲染器。 + *

    取值: + *

      + *
    1. 单元格类对象。
    2. + *
    3. UI 的 JSON 描述。
    4. + *

    + * @implements + */ + get itemRender():any; + set itemRender(value:any); + + /** + * @inheritDoc + * @override + */ + set width(value:number); + + /** + * @inheritDoc + * @override + */ + get width():number; + + /** + * @inheritDoc + * @override + */ + set height(value:number); + + /** + * @inheritDoc + * @override + */ + get height():number; + + /** + * 水平方向显示的单元格数量。 + */ + get repeatX():number; + set repeatX(value:number); + + /** + * 垂直方向显示的单元格数量。 + */ + get repeatY():number; + set repeatY(value:number); + + /** + * 水平方向显示的单元格之间的间距(以像素为单位)。 + */ + get spaceX():number; + set spaceX(value:number); + + /** + * 垂直方向显示的单元格之间的间距(以像素为单位)。 + */ + get spaceY():number; + set spaceY(value:number); + + /** + * @private 更改单元格的信息。 在此销毁、创建单元格,并设置单元格的位置等属性。相当于此列表内容发送改变时调用此函数。 + */ + protected changeCells():void; + private _getOneCell:any; + private _createItems:any; + protected createItem():Box; + + /** + * @private 添加单元格。 + * @param cell 需要添加的单元格对象。 + */ + protected addCell(cell:Box):void; + + /** + * 初始化单元格信息。 + */ + initItems():void; + + /** + * 设置可视区域大小。 + *

    以(0,0,width参数,height参数)组成的矩形区域为可视区域。

    + * @param width 可视区域宽度。 + * @param height 可视区域高度。 + */ + setContentSize(width:number,height:number):void; + + /** + * @private 单元格的鼠标事件侦听处理函数。 + */ + protected onCellMouse(e:Event):void; + + /** + * @private 改变单元格的可视状态。 + * @param cell 单元格对象。 + * @param visable 是否显示。 + * @param index 单元格的属性 index 值。 + */ + protected changeCellState(cell:Box,visible:boolean,index:number):void; + + /** + * @inheritDoc + * @override + */ + protected _sizeChanged():void; + + /** + * @private 滚动条的 Event.CHANGE 事件侦听处理函数。 + */ + protected onScrollBarChange(e?:Event|null):void; + private posCell:any; + + /** + * 表示当前选择的项索引。selectedIndex值更改会引起list重新渲染 + */ + get selectedIndex():number; + set selectedIndex(value:number); + + /** + * @private 改变单元格的选择状态。 + */ + protected changeSelectStatus():void; + + /** + * 当前选中的单元格数据源。 + */ + get selectedItem():any; + set selectedItem(value:any); + + /** + * 获取或设置当前选择的单元格对象。 + */ + get selection():Box; + set selection(value:Box); + + /** + * 当前显示的单元格列表的开始索引。 + */ + get startIndex():number; + set startIndex(value:number); + + /** + * @private 渲染单元格列表。 + */ + protected renderItems(from?:number,to?:number):void; + + /** + * 渲染一个单元格。 + * @param cell 需要渲染的单元格对象。 + * @param index 单元格索引。 + */ + protected renderItem(cell:Box,index:number):void; + private _bindData:any; + + /** + * 列表数据源。 + */ + get array():any[]; + private _preLen:any; + set array(value:any[]); + + /** + * 更新数据源,不刷新list,只增加滚动长度 + * @param array 数据源 + */ + updateArray(array:any[]):void; + + /** + * 列表的当前页码。 + */ + get page():number; + set page(value:number); + + /** + * 列表的数据总个数。 + */ + get length():number; + + /** + * @inheritDoc + * @override + */ + set dataSource(value:any); + + /** + * @inheritDoc + * @override + */ + get dataSource():any; + + /** + * 单元格集合。 + */ + get cells():Box[]; + + /** + * 是否开启橡皮筋效果 + */ + get elasticEnabled():boolean; + set elasticEnabled(value:boolean); + + /** + * 刷新列表数据源。 + */ + refresh():void; + + /** + * 获取单元格数据源。 + * @param index 单元格索引。 + */ + getItem(index:number):any; + + /** + * 修改单元格数据源。 + * @param index 单元格索引。 + * @param source 单元格数据源。 + */ + changeItem(index:number,source:any):void; + + /** + * 设置单元格数据源。 + * @param index 单元格索引。 + * @param source 单元格数据源。 + */ + setItem(index:number,source:any):void; + + /** + * 添加单元格数据源。 + * @param source 数据源。 + */ + addItem(source:any):void; + + /** + * 添加单元格数据源到对应的数据索引处。 + * @param souce 单元格数据源。 + * @param index 索引。 + */ + addItemAt(souce:any,index:number):void; + + /** + * 通过数据源索引删除单元格数据源。 + * @param index 需要删除的数据源索引值。 + */ + deleteItem(index:number):void; + + /** + * 通过可视单元格索引,获取单元格。 + * @param index 可视单元格索引。 + * @return 单元格对象。 + */ + getCell(index:number):Box|null; + + /** + *

    滚动列表,以设定的数据索引对应的单元格为当前可视列表的第一项。

    + * @param index 单元格在数据列表中的索引。 + */ + scrollTo(index:number):void; + + /** + *

    缓动滚动列表,以设定的数据索引对应的单元格为当前可视列表的第一项。

    + * @param index 单元格在数据列表中的索引。 + * @param time 缓动时间。 + * @param complete 缓动结束回掉 + */ + tweenTo(index:number,time?:number,complete?:Handler|null):void; + + /** + * @private + */ + protected _setCellChanged():void; + + /** + * @override + */ + protected commitMeasure():void; + } + + /** + * Panel 是一个面板容器类。 + */ + class Panel extends Box { + + /** + * @private + */ + protected _content:Box; + + /** + * @private + */ + protected _vScrollBar:VScrollBar; + + /** + * @private + */ + protected _hScrollBar:HScrollBar; + + /** + * @private + */ + protected _scrollChanged:boolean; + + /** + * @private + */ + protected _usedCache:string; + + /** + * @private + */ + protected _elasticEnabled:boolean; + + /** + * 创建一个新的 Panel 类实例。 + *

    Panel 构造函数中设置属性width、height的值都为100。

    + */ + + constructor(); + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * @inheritDoc + * @override + */ + destroyChildren():void; + + /** + * @inheritDoc + * @override + */ + protected createChildren():void; + + /** + * @inheritDoc + * @override + */ + addChild(child:Node):Node; + + /** + * @private 子对象的 Event.RESIZE 事件侦听处理函数。 + */ + private onResize:any; + + /** + * @inheritDoc + * @override + */ + addChildAt(child:Node,index:number):Node; + + /** + * @inheritDoc + * @override + */ + removeChild(child:Node):Node; + + /** + * @inheritDoc + * @override + */ + removeChildAt(index:number):Node; + + /** + * @inheritDoc + * @override + */ + removeChildren(beginIndex?:number,endIndex?:number):Node; + + /** + * @inheritDoc + * @override + */ + getChildAt(index:number):Node; + + /** + * @inheritDoc + * @override + */ + getChildByName(name:string):Node; + + /** + * @inheritDoc + * @override + */ + getChildIndex(child:Node):number; + + /** + * @inheritDoc + * @override + */ + get numChildren():number; + + /** + * @private + */ + private changeScroll:any; + + /** + * @inheritDoc + * @override + */ + protected _sizeChanged():void; + + /** + * @private 获取内容宽度(以像素为单位)。 + */ + get contentWidth():number; + + /** + * @private 获取内容高度(以像素为单位)。 + */ + get contentHeight():number; + + /** + * @private 设置内容的宽度、高度(以像素为单位)。 + * @param width 宽度。 + * @param height 高度。 + */ + private setContentSize:any; + + /** + * @inheritDoc + * @override + */ + set width(value:number); + + /** + * @inheritDoc + * @override + */ + get width():number; + + /** + * @inheritDoc + * @override + */ + set height(value:number); + + /** + * @inheritDoc + * @override + */ + get height():number; + + /** + * 垂直方向滚动条皮肤。 + */ + get vScrollBarSkin():string; + set vScrollBarSkin(value:string); + + /** + * 水平方向滚动条皮肤。 + */ + get hScrollBarSkin():string; + set hScrollBarSkin(value:string); + + /** + * 垂直方向滚动条对象。 + */ + get vScrollBar():ScrollBar; + + /** + * 水平方向滚动条对象。 + */ + get hScrollBar():ScrollBar; + + /** + * 获取内容容器对象。 + */ + get content():Sprite; + + /** + * @private 滚动条的Event.MOUSE_DOWN事件侦听处理函数。事件侦听处理函数。 + * @param scrollBar 滚动条对象。 + * @param e Event 对象。 + */ + protected onScrollBarChange(scrollBar:ScrollBar):void; + + /** + *

    滚动内容容器至设定的垂直、水平方向滚动条位置。

    + * @param x 水平方向滚动条属性value值。滚动条位置数字。 + * @param y 垂直方向滚动条属性value值。滚动条位置数字。 + */ + scrollTo(x?:number,y?:number):void; + + /** + * 刷新滚动内容。 + */ + refresh():void; + + /** + * @inheritDoc + * @override + */ + set cacheAs(value:string); + + /** + * @inheritDoc + * @override + */ + get cacheAs():string; + + /** + * 是否开启橡皮筋效果 + */ + get elasticEnabled():boolean; + set elasticEnabled(value:boolean); + private onScrollStart:any; + private onScrollEnd:any; + + /** + * @private + */ + protected _setScrollChanged():void; + } + + /** + * 值发生改变后调度。 + * @eventType laya.events.Event + */ + + /** + * ProgressBar 组件显示内容的加载进度。 + * @example 以下示例代码,创建了一个新的 ProgressBar 实例,设置了它的皮肤、位置、宽高、网格等信息,并添加到舞台上。 package { import laya.ui.ProgressBar; import laya.utils.Handler; public class ProgressBar_Example { private var progressBar:ProgressBar; public function ProgressBar_Example() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/progress.png", "resource/ui/progress$bar.png"], Handler.create(this, onLoadComplete));//加载资源。 } private function onLoadComplete():void { progressBar = new ProgressBar("resource/ui/progress.png");//创建一个 ProgressBar 类的实例对象 progressBar 。 progressBar.x = 100;//设置 progressBar 对象的属性 x 的值,用于控制 progressBar 对象的显示位置。 progressBar.y = 100;//设置 progressBar 对象的属性 y 的值,用于控制 progressBar 对象的显示位置。 progressBar.value = 0.3;//设置 progressBar 的进度值。 progressBar.width = 200;//设置 progressBar 的宽度。 progressBar.height = 50;//设置 progressBar 的高度。 progressBar.sizeGrid = "5,10,5,10";//设置 progressBar 的网格信息。 progressBar.changeHandler = new Handler(this, onChange);//设置 progressBar 的value值改变时执行的处理器。 Laya.stage.addChild(progressBar);//将 progressBar 添加到显示列表。 Laya.timer.once(3000, this, changeValue);//设定 3000ms(毫秒)后,执行函数changeValue。 } private function changeValue():void { trace("改变进度条的进度值。"); progressBar.value = 0.6; } private function onChange(value:Number):void { trace("进度发生改变: value=" ,value); } } } + * @example Laya.init(640, 800);//设置游戏画布宽高 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色 var res = ["resource/ui/progress.png", "resource/ui/progress$bar.png"]; Laya.loader.load(res, laya.utils.Handler.create(this, onLoadComplete));//加载资源。 function onLoadComplete() { progressBar = new laya.ui.ProgressBar("resource/ui/progress.png");//创建一个 ProgressBar 类的实例对象 progressBar 。 progressBar.x = 100;//设置 progressBar 对象的属性 x 的值,用于控制 progressBar 对象的显示位置。 progressBar.y = 100;//设置 progressBar 对象的属性 y 的值,用于控制 progressBar 对象的显示位置。 progressBar.value = 0.3;//设置 progressBar 的进度值。 progressBar.width = 200;//设置 progressBar 的宽度。 progressBar.height = 50;//设置 progressBar 的高度。 progressBar.sizeGrid = "10,5,10,5";//设置 progressBar 的网格信息。 progressBar.changeHandler = new laya.utils.Handler(this, onChange);//设置 progressBar 的value值改变时执行的处理器。 Laya.stage.addChild(progressBar);//将 progressBar 添加到显示列表。 Laya.timer.once(3000, this, changeValue);//设定 3000ms(毫秒)后,执行函数changeValue。 } function changeValue() { console.log("改变进度条的进度值。"); progressBar.value = 0.6; } function onChange(value) { console.log("进度发生改变: value=" ,value); } + * @example import ProgressBar = laya.ui.ProgressBar; import Handler = laya.utils.Handler; class ProgressBar_Example { private progressBar: ProgressBar; public ProgressBar_Example() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/progress.png", "resource/ui/progress$bar.png"], Handler.create(this, this.onLoadComplete));//加载资源。 } private onLoadComplete(): void { this.progressBar = new ProgressBar("resource/ui/progress.png");//创建一个 ProgressBar 类的实例对象 progressBar 。 this.progressBar.x = 100;//设置 progressBar 对象的属性 x 的值,用于控制 progressBar 对象的显示位置。 this.progressBar.y = 100;//设置 progressBar 对象的属性 y 的值,用于控制 progressBar 对象的显示位置。 this.progressBar.value = 0.3;//设置 progressBar 的进度值。 this.progressBar.width = 200;//设置 progressBar 的宽度。 this.progressBar.height = 50;//设置 progressBar 的高度。 this.progressBar.sizeGrid = "5,10,5,10";//设置 progressBar 的网格信息。 this.progressBar.changeHandler = new Handler(this, this.onChange);//设置 progressBar 的value值改变时执行的处理器。 Laya.stage.addChild(this.progressBar);//将 progressBar 添加到显示列表。 Laya.timer.once(3000, this, this.changeValue);//设定 3000ms(毫秒)后,执行函数changeValue。 } private changeValue(): void { console.log("改变进度条的进度值。"); this.progressBar.value = 0.6; } private onChange(value: number): void { console.log("进度发生改变: value=", value); } } + */ + class ProgressBar extends UIComponent { + + /** + * 当 ProgressBar 实例的 value 属性发生变化时的函数处理器。 + *

    默认返回参数value 属性(进度值)。

    + */ + changeHandler:Handler; + + /** + * @private + */ + protected _bg:Image; + + /** + * @private + */ + protected _bar:Image; + + /** + * @private + */ + protected _skin:string; + + /** + * @private + */ + protected _value:number; + + /** + * 创建一个新的 ProgressBar 类实例。 + * @param skin 皮肤地址。 + */ + + constructor(skin?:string); + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * @inheritDoc + * @override + */ + protected createChildren():void; + + /** + * @copy laya.ui.Image#skin + */ + get skin():string; + set skin(value:string); + protected _skinLoaded():void; + + /** + * @inheritDoc + * @override + */ + protected measureWidth():number; + + /** + * @inheritDoc + * @override + */ + protected measureHeight():number; + + /** + * 当前的进度量。 + *

    取值:介于0和1之间。

    + */ + get value():number; + set value(num:number); + + /** + * @private 更改进度值的显示。 + */ + protected changeValue():void; + + /** + * 获取进度条对象。 + */ + get bar():Image; + + /** + * 获取背景条对象。 + */ + get bg():Image; + + /** + *

    当前 ProgressBar 实例的进度条背景位图( Image 实例)的有效缩放网格数据。

    + *

    数据格式:"上边距,右边距,下边距,左边距,是否重复填充(值为0:不重复填充,1:重复填充)",以逗号分隔。 + *

    • 例如:"4,4,4,4,1"

    + * @see laya.ui.AutoBitmap.sizeGrid + */ + get sizeGrid():string; + set sizeGrid(value:string); + + /** + * @inheritDoc + * @override + */ + set width(value:number); + + /** + * @inheritDoc + * @override + */ + get width():number; + + /** + * @inheritDoc + * @override + */ + set height(value:number); + + /** + * @inheritDoc + * @override + */ + get height():number; + + /** + * @inheritDoc + * @override + */ + set dataSource(value:any); + + /** + * @inheritDoc + * @override + */ + get dataSource():any; + } + + /** + * Radio 控件使用户可在一组互相排斥的选择中做出一种选择。 + * 用户一次只能选择 Radio 组中的一个成员。选择未选中的组成员将取消选择该组中当前所选的 Radio 控件。 + * @see laya.ui.RadioGroup + */ + class Radio extends Button { + + /** + * @private + */ + protected _value:any; + + /** + * 创建一个新的 Radio 类实例。 + * @param skin 皮肤。 + * @param label 标签。 + */ + + constructor(skin?:string,label?:string); + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * @override + */ + protected preinitialize():void; + + /** + * @inheritDoc + * @override + */ + protected initialize():void; + + /** + * @private 对象的Event.CLICK事件侦听处理函数。 + */ + protected onClick(e:Event):void; + + /** + * 获取或设置 Radio 关联的可选用户定义值。 + */ + get value():any; + set value(obj:any); + } + + /** + * 当 Group 实例的 selectedIndex 属性发生变化时调度。 + * @eventType laya.events.Event + */ + + /** + * RadioGroup 控件定义一组 Radio 控件,这些控件相互排斥; + * 因此,用户每次只能选择一个 Radio 控件。 + * @example 以下示例代码,创建了一个 RadioGroup 实例。 package { import laya.ui.Radio; import laya.ui.RadioGroup; import laya.utils.Handler; public class RadioGroup_Example { public function RadioGroup_Example() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/radio.png"], Handler.create(this, onLoadComplete));//加载资源。 } private function onLoadComplete():void { var radioGroup:RadioGroup = new RadioGroup();//创建一个 RadioGroup 类的实例对象 radioGroup 。 radioGroup.pos(100, 100);//设置 radioGroup 的位置信息。 radioGroup.labels = "item0,item1,item2";//设置 radioGroup 的标签集。 radioGroup.skin = "resource/ui/radio.png";//设置 radioGroup 的皮肤。 radioGroup.space = 10;//设置 radioGroup 的项间隔距离。 radioGroup.selectHandler = new Handler(this, onSelect);//设置 radioGroup 的选择项发生改变时执行的处理器。 Laya.stage.addChild(radioGroup);//将 radioGroup 添加到显示列表。 } private function onSelect(index:int):void { trace("当前选择的单选按钮索引: index= ", index); } } } + * @example Laya.init(640, 800);//设置游戏画布宽高、渲染模式 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色 Laya.loader.load(["resource/ui/radio.png"], laya.utils.Handler.create(this, onLoadComplete)); function onLoadComplete() { var radioGroup= new laya.ui.RadioGroup();//创建一个 RadioGroup 类的实例对象 radioGroup 。 radioGroup.pos(100, 100);//设置 radioGroup 的位置信息。 radioGroup.labels = "item0,item1,item2";//设置 radioGroup 的标签集。 radioGroup.skin = "resource/ui/radio.png";//设置 radioGroup 的皮肤。 radioGroup.space = 10;//设置 radioGroup 的项间隔距离。 radioGroup.selectHandler = new laya.utils.Handler(this, onSelect);//设置 radioGroup 的选择项发生改变时执行的处理器。 Laya.stage.addChild(radioGroup);//将 radioGroup 添加到显示列表。 } function onSelect(index) { console.log("当前选择的单选按钮索引: index= ", index); } + * @example import Radio = laya.ui.Radio; import RadioGroup = laya.ui.RadioGroup; import Handler = laya.utils.Handler; class RadioGroup_Example { constructor() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/radio.png"], Handler.create(this, this.onLoadComplete));//加载资源。 } private onLoadComplete(): void { var radioGroup: RadioGroup = new RadioGroup();//创建一个 RadioGroup 类的实例对象 radioGroup 。 radioGroup.pos(100, 100);//设置 radioGroup 的位置信息。 radioGroup.labels = "item0,item1,item2";//设置 radioGroup 的标签集。 radioGroup.skin = "resource/ui/radio.png";//设置 radioGroup 的皮肤。 radioGroup.space = 10;//设置 radioGroup 的项间隔距离。 radioGroup.selectHandler = new Handler(this, this.onSelect);//设置 radioGroup 的选择项发生改变时执行的处理器。 Laya.stage.addChild(radioGroup);//将 radioGroup 添加到显示列表。 } private onSelect(index: number): void { console.log("当前选择的单选按钮索引: index= ", index); } } + */ + class RadioGroup extends UIGroup { + + /** + * @inheritDoc + * @override + */ + protected createItem(skin:string,label:string):Sprite; + } + + /** + * 自适应缩放容器,容器设置大小后,容器大小始终保持stage大小,子内容按照原始最小宽高比缩放 + */ + class ScaleBox extends Box { + private _oldW:any; + private _oldH:any; + + /** + * @override + */ + onEnable():void; + + /** + * @override + */ + onDisable():void; + private onResize:any; + + /** + * @override + */ + set width(value:number); + + /** + * @inheritDoc + * @override + */ + get width():number; + + /** + * @override + */ + set height(value:number); + + /** + * @inheritDoc + * @override + */ + get height():number; + } + + /** + * 滚动条滑块位置发生变化后调度。 + * @eventType laya.events.Event + */ + + /** + * 开始滑动。 + * @eventType laya.events.Event + */ + + /** + * 结束滑动。 + * @eventType laya.events.Event + */ + + /** + * ScrollBar 组件是一个滚动条组件。 + *

    当数据太多以至于显示区域无法容纳时,最终用户可以使用 ScrollBar 组件控制所显示的数据部分。

    + *

    滚动条由四部分组成:两个箭头按钮、一个轨道和一个滑块。

    * + * @see laya.ui.VScrollBar + * @see laya.ui.HScrollBar + */ + class ScrollBar extends UIComponent { + + /** + * 滚动衰减系数 + */ + rollRatio:number; + + /** + * 滚动变化时回调,回传value参数。 + */ + changeHandler:Handler; + + /** + * 是否缩放滑动条,默认值为true。 + */ + scaleBar:boolean; + + /** + * 一个布尔值,指定是否自动隐藏滚动条(无需滚动时),默认值为false。 + */ + autoHide:boolean; + + /** + * 橡皮筋效果极限距离,0为没有橡皮筋效果。 + */ + elasticDistance:number; + + /** + * 橡皮筋回弹时间,单位为毫秒。 + */ + elasticBackTime:number; + + /** + * 上按钮 + */ + upButton:Button; + + /** + * 下按钮 + */ + downButton:Button; + + /** + * 滑条 + */ + slider:Slider; + + /** + * @private + */ + protected _showButtons:boolean; + + /** + * @private + */ + protected _scrollSize:number; + + /** + * @private + */ + protected _skin:string; + + /** + * @private + */ + protected _thumbPercent:number; + + /** + * @private + */ + protected _target:Sprite; + + /** + * @private + */ + protected _lastPoint:Point; + + /** + * @private + */ + protected _lastOffset:number; + + /** + * @private + */ + protected _checkElastic:boolean; + + /** + * @private + */ + protected _isElastic:boolean; + + /** + * @private + */ + protected _value:number; + + /** + * @private + */ + protected _hide:boolean; + + /** + * @private + */ + protected _clickOnly:boolean; + + /** + * @private + */ + protected _offsets:any[]; + + /** + * @private + */ + protected _touchScrollEnable:boolean; + + /** + * @private + */ + protected _mouseWheelEnable:boolean; + + /** + * 创建一个新的 ScrollBar 实例。 + * @param skin 皮肤资源地址。 + */ + + constructor(skin?:string); + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * @override + */ + protected createChildren():void; + + /** + * @override + */ + protected initialize():void; + + /** + * @private 滑块位置发生改变的处理函数。 + */ + protected onSliderChange():void; + + /** + * @private 向上和向下按钮的 Event.MOUSE_DOWN 事件侦听处理函数。 + */ + protected onButtonMouseDown(e:Event):void; + + /** + * @private + */ + protected startLoop(isUp:boolean):void; + + /** + * @private + */ + protected slide(isUp:boolean):void; + + /** + * @private 舞台的 Event.MOUSE_DOWN 事件侦听处理函数。 + */ + protected onStageMouseUp(e:Event):void; + + /** + * @copy laya.ui.Image#skin + */ + get skin():string; + set skin(value:string); + protected _skinLoaded():void; + + /** + * @private 更改对象的皮肤及位置。 + */ + protected changeScrollBar():void; + + /** + * @inheritDoc + * @override + */ + protected _sizeChanged():void; + + /** + * @private + */ + private resetPositions:any; + + /** + * @private + */ + protected resetButtonPosition():void; + + /** + * @inheritDoc + * @override + */ + protected measureWidth():number; + + /** + * @inheritDoc + * @override + */ + protected measureHeight():number; + + /** + * 设置滚动条信息。 + * @param min 滚动条最小位置值。 + * @param max 滚动条最大位置值。 + * @param value 滚动条当前位置值。 + */ + setScroll(min:number,max:number,value:number):void; + + /** + * 获取或设置表示最高滚动位置的数字。 + */ + get max():number; + set max(value:number); + + /** + * 获取或设置表示最低滚动位置的数字。 + */ + get min():number; + set min(value:number); + + /** + * 获取或设置表示当前滚动位置的数字。 + */ + get value():number; + set value(v:number); + + /** + * 一个布尔值,指示滚动条是否为垂直滚动。如果值为true,则为垂直滚动,否则为水平滚动。 + *

    默认值为:true。

    + */ + get isVertical():boolean; + set isVertical(value:boolean); + + /** + *

    当前实例的 Slider 实例的有效缩放网格数据。

    + *

    数据格式:"上边距,右边距,下边距,左边距,是否重复填充(值为0:不重复填充,1:重复填充)",以逗号分隔。 + *

    • 例如:"4,4,4,4,1"

    + * @see laya.ui.AutoBitmap.sizeGrid + */ + get sizeGrid():string; + set sizeGrid(value:string); + + /** + * 获取或设置一个值,该值表示按下滚动条轨道时页面滚动的增量。 + */ + get scrollSize():number; + set scrollSize(value:number); + + /** + * @inheritDoc + * @override + */ + set dataSource(value:any); + + /** + * @inheritDoc + * @override + */ + get dataSource():any; + + /** + * 获取或设置一个值,该值表示滑条长度比例,值为:(0-1)。 + */ + get thumbPercent():number; + set thumbPercent(value:number); + + /** + * 设置滚动对象。 + * @see laya.ui.TouchScroll#target + */ + get target():Sprite; + set target(value:Sprite); + + /** + * 是否隐藏滚动条,不显示滚动条,但是可以正常滚动,默认为false。 + */ + get hide():boolean; + set hide(value:boolean); + + /** + * 一个布尔值,指定是否显示向上、向下按钮,默认值为true。 + */ + get showButtons():boolean; + set showButtons(value:boolean); + + /** + * 一个布尔值,指定是否开启触摸,默认值为true。 + */ + get touchScrollEnable():boolean; + set touchScrollEnable(value:boolean); + + /** + * 一个布尔值,指定是否滑轮滚动,默认值为true。 + */ + get mouseWheelEnable():boolean; + set mouseWheelEnable(value:boolean); + + /** + * @private + */ + protected onTargetMouseWheel(e:Event):void; + isLockedFun:Function; + + /** + * @private + */ + protected onTargetMouseDown(e:Event):void; + startDragForce():void; + private cancelDragOp:any; + triggerDownDragLimit:Function; + triggerUpDragLimit:Function; + private checkTriggers:any; + get lastOffset():number; + startTweenMoveForce(lastOffset:number):void; + + /** + * @private + */ + protected loop():void; + + /** + * @private + */ + protected onStageMouseUp2(e:Event):void; + + /** + * @private + */ + private elasticOver:any; + + /** + * @private + */ + protected tweenMove(maxDistance:number):void; + + /** + * 停止滑动。 + */ + stopScroll():void; + + /** + * 滚动的刻度值,滑动数值为tick的整数倍。默认值为1。 + */ + get tick():number; + set tick(value:number); + } + + /** + * 移动滑块位置时调度。 + * @eventType laya.events.Event + */ + + /** + * 移动滑块位置完成(用户鼠标抬起)后调度。 + * @eventType + * @eventType laya.events.EventD + */ + + /** + * 使用 Slider 控件,用户可以通过在滑块轨道的终点之间移动滑块来选择值。 + *

    滑块的当前值由滑块端点(对应于滑块的最小值和最大值)之间滑块的相对位置确定。

    + *

    滑块允许最小值和最大值之间特定间隔内的值。滑块还可以使用数据提示显示其当前值。

    + * @see laya.ui.HSlider + * @see laya.ui.VSlider + */ + class Slider extends UIComponent { + + /** + * @private 获取对 Slider 组件所包含的 Label 组件的引用。 + */ + static label:Label; + + /** + * 数据变化处理器。 + *

    默认回调参数为滑块位置属性 value属性值:Number 。

    + */ + changeHandler:Handler; + + /** + * 一个布尔值,指示是否为垂直滚动。如果值为true,则为垂直方向,否则为水平方向。 + *

    默认值为:true。

    + * @default true + */ + isVertical:boolean; + + /** + * 一个布尔值,指示是否显示标签。 + * @default true + */ + showLabel:boolean; + + /** + * @private + */ + protected _allowClickBack:boolean; + + /** + * @private + */ + protected _max:number; + + /** + * @private + */ + protected _min:number; + + /** + * @private + */ + protected _tick:number; + + /** + * @private + */ + protected _value:number; + + /** + * @private + */ + protected _skin:string; + + /** + * @private + */ + protected _bg:Image; + + /** + * @private + */ + protected _progress:Image; + + /** + * @private + */ + protected _bar:Button; + + /** + * @private + */ + protected _tx:number; + + /** + * @private + */ + protected _ty:number; + + /** + * @private + */ + protected _maxMove:number; + + /** + * @private + */ + protected _globalSacle:Point; + + /** + * 创建一个新的 Slider 类示例。 + * @param skin 皮肤。 + */ + + constructor(skin?:string); + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * @inheritDoc + * @override + */ + protected createChildren():void; + + /** + * @inheritDoc + * @override + */ + protected initialize():void; + + /** + * @private 滑块的的 Event.MOUSE_DOWN 事件侦听处理函数。 + */ + protected onBarMouseDown(e:Event):void; + + /** + * @private 显示标签。 + */ + protected showValueText():void; + + /** + * @private 隐藏标签。 + */ + protected hideValueText():void; + + /** + * @private + */ + private mouseUp:any; + + /** + * @private + */ + private mouseMove:any; + + /** + * @private + */ + protected sendChangeEvent(type?:string):void; + + /** + * @copy laya.ui.Image#skin + */ + get skin():string; + set skin(value:string); + protected _skinLoaded():void; + + /** + * @private 设置滑块的位置信息。 + */ + protected setBarPoint():void; + + /** + * @inheritDoc + * @override + */ + protected measureWidth():number; + + /** + * @inheritDoc + * @override + */ + protected measureHeight():number; + + /** + * @inheritDoc + * @override + */ + protected _sizeChanged():void; + + /** + *

    当前实例的背景图( Image )和滑块按钮( Button )实例的有效缩放网格数据。

    + *

    数据格式:"上边距,右边距,下边距,左边距,是否重复填充(值为0:不重复填充,1:重复填充)",以逗号分隔。 + *

    • 例如:"4,4,4,4,1"

    + * @see laya.ui.AutoBitmap.sizeGrid + */ + get sizeGrid():string; + set sizeGrid(value:string); + + /** + * 设置滑动条的信息。 + * @param min 滑块的最小值。 + * @param max 滑块的最小值。 + * @param value 滑块的当前值。 + */ + setSlider(min:number,max:number,value:number):void; + + /** + * 滑动的刻度值,滑动数值为tick的整数倍。默认值为1。 + */ + get tick():number; + set tick(value:number); + + /** + * @private 改变滑块的位置值。 + */ + changeValue():void; + + /** + * 获取或设置表示最高位置的数字。 默认值为100。 + */ + get max():number; + set max(value:number); + + /** + * 获取或设置表示最低位置的数字。 默认值为0。 + */ + get min():number; + set min(value:number); + + /** + * 获取或设置表示当前滑块位置的数字。 + */ + get value():number; + set value(num:number); + + /** + * 一个布尔值,指定是否允许通过点击滑动条改变 Slidervalue 属性值。 + */ + get allowClickBack():boolean; + set allowClickBack(value:boolean); + + /** + * @private 滑动条的 Event.MOUSE_DOWN 事件侦听处理函数。 + */ + protected onBgMouseDown(e:Event):void; + + /** + * @inheritDoc + * @override + */ + set dataSource(value:any); + + /** + * @inheritDoc + * @override + */ + get dataSource():any; + + /** + * 表示滑块按钮的引用。 + */ + get bar():Button; + } + + /** + * Styles 定义了组件常用的样式属性。 + */ + class Styles { + + /** + * 默认九宫格信息。 + * @see laya.ui.AutoBitmap#sizeGrid + */ + static defaultSizeGrid:any[]; + + /** + * 标签颜色。 + */ + static labelColor:string; + + /** + * 标签的边距。 + *

    格式:[上边距,右边距,下边距,左边距]。

    + */ + static labelPadding:any[]; + + /** + * 标签的边距。 + *

    格式:[上边距,右边距,下边距,左边距]。

    + */ + static inputLabelPadding:any[]; + + /** + * 按钮皮肤的状态数,支持1,2,3三种状态值。 + */ + static buttonStateNum:number; + + /** + * 按钮标签颜色。 + *

    格式:[upColor,overColor,downColor,disableColor]。

    + */ + static buttonLabelColors:any[]; + + /** + * 下拉框项颜色。 + *

    格式:[overBgColor,overLabelColor,outLabelColor,borderColor,bgColor]。

    + */ + static comboBoxItemColors:any[]; + + /** + * 滚动条的最小值。 + */ + static scrollBarMinNum:number; + + /** + * 长按按钮,等待时间,使其可激活连续滚动。 + */ + static scrollBarDelayTime:number; + } + + /** + * 当 Group 实例的 selectedIndex 属性发生变化时调度。 + * @eventType laya.events.Event + */ + + /** + * Tab 组件用来定义选项卡按钮组。 * + *

    属性:selectedIndex 的默认值为-1。

    + * @example 以下示例代码,创建了一个 Tab 实例。 package { import laya.ui.Tab; import laya.utils.Handler; public class Tab_Example { public function Tab_Example() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/tab.png"], Handler.create(this, onLoadComplete));//加载资源。 } private function onLoadComplete():void { var tab:Tab = new Tab();//创建一个 Tab 类的实例对象 tab 。 tab.skin = "resource/ui/tab.png";//设置 tab 的皮肤。 tab.labels = "item0,item1,item2";//设置 tab 的标签集。 tab.x = 100;//设置 tab 对象的属性 x 的值,用于控制 tab 对象的显示位置。 tab.y = 100;//设置 tab 对象的属性 y 的值,用于控制 tab 对象的显示位置。 tab.selectHandler = new Handler(this, onSelect);//设置 tab 的选择项发生改变时执行的处理器。 Laya.stage.addChild(tab);//将 tab 添到显示列表。 } private function onSelect(index:int):void { trace("当前选择的表情页索引: index= ", index); } } } + * @example Laya.init(640, 800);//设置游戏画布宽高 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色 Laya.loader.load(["resource/ui/tab.png"], laya.utils.Handler.create(this, onLoadComplete)); function onLoadComplete() { var tab = new laya.ui.Tab();//创建一个 Tab 类的实例对象 tab 。 tab.skin = "resource/ui/tab.png";//设置 tab 的皮肤。 tab.labels = "item0,item1,item2";//设置 tab 的标签集。 tab.x = 100;//设置 tab 对象的属性 x 的值,用于控制 tab 对象的显示位置。 tab.y = 100;//设置 tab 对象的属性 y 的值,用于控制 tab 对象的显示位置。 tab.selectHandler = new laya.utils.Handler(this, onSelect);//设置 tab 的选择项发生改变时执行的处理器。 Laya.stage.addChild(tab);//将 tab 添到显示列表。 } function onSelect(index) { console.log("当前选择的标签页索引: index= ", index); } + * @example import Tab = laya.ui.Tab; import Handler = laya.utils.Handler; class Tab_Example { constructor() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/tab.png"], Handler.create(this, this.onLoadComplete));//加载资源。 } private onLoadComplete(): void { var tab: Tab = new Tab();//创建一个 Tab 类的实例对象 tab 。 tab.skin = "resource/ui/tab.png";//设置 tab 的皮肤。 tab.labels = "item0,item1,item2";//设置 tab 的标签集。 tab.x = 100;//设置 tab 对象的属性 x 的值,用于控制 tab 对象的显示位置。 tab.y = 100;//设置 tab 对象的属性 y 的值,用于控制 tab 对象的显示位置。 tab.selectHandler = new Handler(this, this.onSelect);//设置 tab 的选择项发生改变时执行的处理器。 Laya.stage.addChild(tab);//将 tab 添到显示列表。 } private onSelect(index: number): void { console.log("当前选择的表情页索引: index= ", index); } } + */ + class Tab extends UIGroup { + + /** + * @private + * @inheritDoc + * @override + */ + protected createItem(skin:string,label:string):Sprite; + } + + /** + * TextArea 类用于创建显示对象以显示和输入文本。 + * @example 以下示例代码,创建了一个 TextArea 实例。 package { import laya.ui.TextArea; import laya.utils.Handler; public class TextArea_Example { public function TextArea_Example() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/input.png"], Handler.create(this, onLoadComplete));//加载资源。 } private function onLoadComplete():void { var textArea:TextArea = new TextArea("这个一个TextArea实例。");//创建一个 TextArea 类的实例对象 textArea 。 textArea.skin = "resource/ui/input.png";//设置 textArea 的皮肤。 textArea.sizeGrid = "4,4,4,4";//设置 textArea 的网格信息。 textArea.color = "#008fff";//设置 textArea 的文本颜色。 textArea.font = "Arial";//设置 textArea 的字体。 textArea.bold = true;//设置 textArea 的文本显示为粗体。 textArea.fontSize = 20;//设置 textArea 的文本字体大小。 textArea.wordWrap = true;//设置 textArea 的文本自动换行。 textArea.x = 100;//设置 textArea 对象的属性 x 的值,用于控制 textArea 对象的显示位置。 textArea.y = 100;//设置 textArea 对象的属性 y 的值,用于控制 textArea 对象的显示位置。 textArea.width = 300;//设置 textArea 的宽度。 textArea.height = 200;//设置 textArea 的高度。 Laya.stage.addChild(textArea);//将 textArea 添加到显示列表。 } } } + * @example Laya.init(640, 800);//设置游戏画布宽高、渲染模式 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色 Laya.loader.load(["resource/ui/input.png"], laya.utils.Handler.create(this, onLoadComplete));//加载资源。 function onLoadComplete() { var textArea = new laya.ui.TextArea("这个一个TextArea实例。");//创建一个 TextArea 类的实例对象 textArea 。 textArea.skin = "resource/ui/input.png";//设置 textArea 的皮肤。 textArea.sizeGrid = "4,4,4,4";//设置 textArea 的网格信息。 textArea.color = "#008fff";//设置 textArea 的文本颜色。 textArea.font = "Arial";//设置 textArea 的字体。 textArea.bold = true;//设置 textArea 的文本显示为粗体。 textArea.fontSize = 20;//设置 textArea 的文本字体大小。 textArea.wordWrap = true;//设置 textArea 的文本自动换行。 textArea.x = 100;//设置 textArea 对象的属性 x 的值,用于控制 textArea 对象的显示位置。 textArea.y = 100;//设置 textArea 对象的属性 y 的值,用于控制 textArea 对象的显示位置。 textArea.width = 300;//设置 textArea 的宽度。 textArea.height = 200;//设置 textArea 的高度。 Laya.stage.addChild(textArea);//将 textArea 添加到显示列表。 } + * @example import TextArea = laya.ui.TextArea; import Handler = laya.utils.Handler; class TextArea_Example { constructor() { Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/input.png"], Handler.create(this, this.onLoadComplete));//加载资源。 } private onLoadComplete(): void { var textArea: TextArea = new TextArea("这个一个TextArea实例。");//创建一个 TextArea 类的实例对象 textArea 。 textArea.skin = "resource/ui/input.png";//设置 textArea 的皮肤。 textArea.sizeGrid = "4,4,4,4";//设置 textArea 的网格信息。 textArea.color = "#008fff";//设置 textArea 的文本颜色。 textArea.font = "Arial";//设置 textArea 的字体。 textArea.bold = true;//设置 textArea 的文本显示为粗体。 textArea.fontSize = 20;//设置 textArea 的文本字体大小。 textArea.wordWrap = true;//设置 textArea 的文本自动换行。 textArea.x = 100;//设置 textArea 对象的属性 x 的值,用于控制 textArea 对象的显示位置。 textArea.y = 100;//设置 textArea 对象的属性 y 的值,用于控制 textArea 对象的显示位置。 textArea.width = 300;//设置 textArea 的宽度。 textArea.height = 200;//设置 textArea 的高度。 Laya.stage.addChild(textArea);//将 textArea 添加到显示列表。 } } + */ + class TextArea extends TextInput { + + /** + * @private + */ + protected _vScrollBar:VScrollBar; + + /** + * @private + */ + protected _hScrollBar:HScrollBar; + + /** + *

    创建一个新的 TextArea 示例。

    + * @param text 文本内容字符串。 + */ + + constructor(text?:string); + private _onTextChange:any; + + /** + * @param destroyChild + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * @override + */ + protected initialize():void; + + /** + * @override + */ + set width(value:number); + + /** + * @inheritDoc + * @override + */ + get width():number; + + /** + * @override + */ + set height(value:number); + + /** + * @inheritDoc + * @override + */ + get height():number; + + /** + * 垂直滚动条皮肤 + */ + get vScrollBarSkin():string; + set vScrollBarSkin(value:string); + + /** + * 水平滚动条皮肤 + */ + get hScrollBarSkin():string; + set hScrollBarSkin(value:string); + protected onVBarChanged(e:Event):void; + protected onHBarChanged(e:Event):void; + + /** + * 垂直滚动条实体 + */ + get vScrollBar():VScrollBar; + + /** + * 水平滚动条实体 + */ + get hScrollBar():HScrollBar; + + /** + * 垂直滚动最大值 + */ + get maxScrollY():number; + + /** + * 垂直滚动值 + */ + get scrollY():number; + + /** + * 水平滚动最大值 + */ + get maxScrollX():number; + + /** + * 水平滚动值 + */ + get scrollX():number; + private changeScroll:any; + + /** + * 滚动到某个位置 + */ + scrollTo(y:number):void; + } + + /** + * 输入文本后调度。 + * @eventType Event.INPUT + */ + + /** + * 在输入框内敲回车键后调度。 + * @eventType Event.ENTER + */ + + /** + * 当获得输入焦点后调度。 + * @eventType Event.FOCUS + */ + + /** + * 当失去输入焦点后调度。 + * @eventType Event.BLUR + */ + + /** + * TextInput 类用于创建显示对象以显示和输入文本。 + * @example 以下示例代码,创建了一个 TextInput 实例。 package { import laya.display.Stage; import laya.ui.TextInput; import laya.utils.Handler; public class TextInput_Example { public function TextInput_Example() { Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/input.png"], Handler.create(this, onLoadComplete));//加载资源。 } private function onLoadComplete():void { var textInput:TextInput = new TextInput("这是一个TextInput实例。");//创建一个 TextInput 类的实例对象 textInput 。 textInput.skin = "resource/ui/input.png";//设置 textInput 的皮肤。 textInput.sizeGrid = "4,4,4,4";//设置 textInput 的网格信息。 textInput.color = "#008fff";//设置 textInput 的文本颜色。 textInput.font = "Arial";//设置 textInput 的文本字体。 textInput.bold = true;//设置 textInput 的文本显示为粗体。 textInput.fontSize = 30;//设置 textInput 的字体大小。 textInput.wordWrap = true;//设置 textInput 的文本自动换行。 textInput.x = 100;//设置 textInput 对象的属性 x 的值,用于控制 textInput 对象的显示位置。 textInput.y = 100;//设置 textInput 对象的属性 y 的值,用于控制 textInput 对象的显示位置。 textInput.width = 300;//设置 textInput 的宽度。 textInput.height = 200;//设置 textInput 的高度。 Laya.stage.addChild(textInput);//将 textInput 添加到显示列表。 } } } + * @example Laya.init(640, 800);//设置游戏画布宽高 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色 Laya.loader.load(["resource/ui/input.png"], laya.utils.Handler.create(this, onLoadComplete));//加载资源。 function onLoadComplete() { var textInput = new laya.ui.TextInput("这是一个TextInput实例。");//创建一个 TextInput 类的实例对象 textInput 。 textInput.skin = "resource/ui/input.png";//设置 textInput 的皮肤。 textInput.sizeGrid = "4,4,4,4";//设置 textInput 的网格信息。 textInput.color = "#008fff";//设置 textInput 的文本颜色。 textInput.font = "Arial";//设置 textInput 的文本字体。 textInput.bold = true;//设置 textInput 的文本显示为粗体。 textInput.fontSize = 30;//设置 textInput 的字体大小。 textInput.wordWrap = true;//设置 textInput 的文本自动换行。 textInput.x = 100;//设置 textInput 对象的属性 x 的值,用于控制 textInput 对象的显示位置。 textInput.y = 100;//设置 textInput 对象的属性 y 的值,用于控制 textInput 对象的显示位置。 textInput.width = 300;//设置 textInput 的宽度。 textInput.height = 200;//设置 textInput 的高度。 Laya.stage.addChild(textInput);//将 textInput 添加到显示列表。 } + * @example import Stage = laya.display.Stage; import TextInput = laya.ui.TextInput; import Handler = laya.utils.Handler; class TextInput_Example { constructor() { Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/input.png"], Handler.create(this, this.onLoadComplete));//加载资源。 } private onLoadComplete(): void { var textInput: TextInput = new TextInput("这是一个TextInput实例。");//创建一个 TextInput 类的实例对象 textInput 。 textInput.skin = "resource/ui/input.png";//设置 textInput 的皮肤。 textInput.sizeGrid = "4,4,4,4";//设置 textInput 的网格信息。 textInput.color = "#008fff";//设置 textInput 的文本颜色。 textInput.font = "Arial";//设置 textInput 的文本字体。 textInput.bold = true;//设置 textInput 的文本显示为粗体。 textInput.fontSize = 30;//设置 textInput 的字体大小。 textInput.wordWrap = true;//设置 textInput 的文本自动换行。 textInput.x = 100;//设置 textInput 对象的属性 x 的值,用于控制 textInput 对象的显示位置。 textInput.y = 100;//设置 textInput 对象的属性 y 的值,用于控制 textInput 对象的显示位置。 textInput.width = 300;//设置 textInput 的宽度。 textInput.height = 200;//设置 textInput 的高度。 Laya.stage.addChild(textInput);//将 textInput 添加到显示列表。 } } + */ + class TextInput extends Label { + + /** + * @private + */ + protected _bg:AutoBitmap; + + /** + * @private + */ + protected _skin:string; + + /** + * 创建一个新的 TextInput 类实例。 + * @param text 文本内容。 + */ + + constructor(text?:string); + + /** + * @inheritDoc + * @override + */ + protected preinitialize():void; + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * @inheritDoc + * @override + */ + protected createChildren():void; + + /** + * @private + */ + private _onFocus:any; + + /** + * @private + */ + private _onBlur:any; + + /** + * @private + */ + private _onInput:any; + + /** + * @private + */ + private _onEnter:any; + + /** + * @inheritDoc + * @override + */ + protected initialize():void; + + /** + * 表示此对象包含的文本背景 AutoBitmap 组件实例。 + */ + get bg():AutoBitmap; + set bg(value:AutoBitmap); + + /** + * @copy laya.ui.Image#skin + */ + get skin():string; + set skin(value:string); + protected _skinLoaded():void; + + /** + *

    当前实例的背景图( AutoBitmap )实例的有效缩放网格数据。

    + *

    数据格式:"上边距,右边距,下边距,左边距,是否重复填充(值为0:不重复填充,1:重复填充)",以逗号分隔。 + *

    • 例如:"4,4,4,4,1"

    + * @see laya.ui.AutoBitmap.sizeGrid + */ + get sizeGrid():string; + set sizeGrid(value:string); + + /** + * 当前文本内容字符串。 + * @see laya.display.Text.text + * @override + */ + set text(value:string); + + /** + * @override + */ + get text():string; + + /** + * @inheritDoc + * @override + */ + set width(value:number); + + /** + * @inheritDoc + * @override + */ + get width():number; + + /** + * @inheritDoc + * @override + */ + set height(value:number); + + /** + * @inheritDoc + * @override + */ + get height():number; + + /** + *

    指示当前是否是文本域。

    + * 值为true表示当前是文本域,否则不是文本域。 + */ + get multiline():boolean; + set multiline(value:boolean); + + /** + * 设置可编辑状态。 + */ + set editable(value:boolean); + get editable():boolean; + + /** + * 选中输入框内的文本。 + */ + select():void; + + /** + * 限制输入的字符。 + */ + get restrict():string; + set restrict(pattern:string); + + /** + * @copy laya.display.Input#prompt + */ + get prompt():string; + set prompt(value:string); + + /** + * @copy laya.display.Input#promptColor + */ + get promptColor():string; + set promptColor(value:string); + + /** + * @copy laya.display.Input#maxChars + */ + get maxChars():number; + set maxChars(value:number); + + /** + * @copy laya.display.Input#focus + */ + get focus():boolean; + set focus(value:boolean); + + /** + * @copy laya.display.Input#type + */ + get type():string; + set type(value:string); + setSelection(startIndex:number,endIndex:number):void; + } + + /** + * 鼠标提示管理类 + */ + class TipManager extends UIComponent { + static offsetX:number; + static offsetY:number; + static tipTextColor:string; + static tipBackColor:string; + static tipDelay:number; + private _tipBox:any; + private _tipText:any; + private _defaultTipHandler:any; + + constructor(); + + /** + * @private + */ + private _onStageHideTip:any; + + /** + * @private + */ + private _onStageShowTip:any; + + /** + * @private + */ + private _showTip:any; + + /** + * @private + */ + private _onStageMouseDown:any; + + /** + * @private + */ + private _onStageMouseMove:any; + + /** + * @private + */ + private _showToStage:any; + + /** + * 关闭所有鼠标提示 + */ + closeAll():void; + + /** + * 显示显示对象类型的tip + */ + showDislayTip(tip:Sprite):void; + + /** + * @private + */ + private _showDefaultTip:any; + + /** + * 默认鼠标提示函数 + */ + get defaultTipHandler():Function; + set defaultTipHandler(value:Function); + } + + /** + * 实例的 selectedIndex 属性发生变化时调度。 + * @eventType laya.events.Event + */ + + /** + * 节点打开关闭时触发。 + * @eventType laya.events.Event + */ + + /** + * Tree 控件使用户可以查看排列为可扩展树的层次结构数据。 + * @example package { import laya.ui.Tree; import laya.utils.Browser; import laya.utils.Handler; public class Tree_Example { public function Tree_Example() { Laya.init(640, 800); Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/vscroll.png", "resource/ui/vscroll$bar.png", "resource/ui/vscroll$down.png", "resource/ui/vscroll$up.png", "resource/ui/clip_selectBox.png", "resource/ui/clip_tree_folder.png", "resource/ui/clip_tree_arrow.png"], Handler.create(this, onLoadComplete)); } private function onLoadComplete():void { var xmlString:String;//创建一个xml字符串,用于存储树结构数据。 xmlString = "<root><item label='box1'><abc label='child1'/><abc label='child2'/><abc label='child3'/><abc label='child4'/><abc label='child5'/></item><item label='box2'><abc label='child1'/><abc label='child2'/><abc label='child3'/><abc label='child4'/></item></root>"; var domParser:* = new Browser.window.DOMParser();//创建一个DOMParser实例domParser。 var xml:* = domParser.parseFromString(xmlString, "text/xml");//解析xml字符。 var tree:Tree = new Tree();//创建一个 Tree 类的实例对象 tree 。 tree.scrollBarSkin = "resource/ui/vscroll.png";//设置 tree 的皮肤。 tree.itemRender = Item;//设置 tree 的项渲染器。 tree.xml = xml;//设置 tree 的树结构数据。 tree.x = 100;//设置 tree 对象的属性 x 的值,用于控制 tree 对象的显示位置。 tree.y = 100;//设置 tree 对象的属性 y 的值,用于控制 tree 对象的显示位置。 tree.width = 200;//设置 tree 的宽度。 tree.height = 100;//设置 tree 的高度。 Laya.stage.addChild(tree);//将 tree 添加到显示列表。 } } } import laya.ui.Box; import laya.ui.Clip; import laya.ui.Label; class Item extends Box { public function Item() { this.name = "render"; this.right = 0; this.left = 0; var selectBox:Clip = new Clip("resource/ui/clip_selectBox.png", 1, 2); selectBox.name = "selectBox"; selectBox.height = 24; selectBox.x = 13; selectBox.y = 0; selectBox.left = 12; addChild(selectBox); var folder:Clip = new Clip("resource/ui/clip_tree_folder.png", 1, 3); folder.name = "folder"; folder.x = 14; folder.y = 4; addChild(folder); var label:Label = new Label("treeItem"); label.name = "label"; label.color = "#ffff00"; label.width = 150; label.height = 22; label.x = 33; label.y = 1; label.left = 33; label.right = 0; addChild(label); var arrow:Clip = new Clip("resource/ui/clip_tree_arrow.png", 1, 2); arrow.name = "arrow"; arrow.x = 0; arrow.y = 5; addChild(arrow); } } + * @example Laya.init(640, 800);//设置游戏画布宽高、渲染模式 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色 var res = ["resource/ui/vscroll.png", "resource/ui/vscroll$bar.png", "resource/ui/vscroll$down.png", "resource/ui/vscroll$up.png", "resource/ui/clip_selectBox.png", "resource/ui/clip_tree_folder.png", "resource/ui/clip_tree_arrow.png"]; Laya.loader.load(res, new laya.utils.Handler(this, onLoadComplete)); function onLoadComplete() { var xmlString;//创建一个xml字符串,用于存储树结构数据。 xmlString = "<root><item label='box1'><abc label='child1'/><abc label='child2'/><abc label='child3'/><abc label='child4'/><abc label='child5'/></item><item label='box2'><abc label='child1'/><abc label='child2'/><abc label='child3'/><abc label='child4'/></item></root>"; var domParser = new laya.utils.Browser.window.DOMParser();//创建一个DOMParser实例domParser。 var xml = domParser.parseFromString(xmlString, "text/xml");//解析xml字符。 var tree = new laya.ui.Tree();//创建一个 Tree 类的实例对象 tree 。 tree.scrollBarSkin = "resource/ui/vscroll.png";//设置 tree 的皮肤。 tree.itemRender = mypackage.treeExample.Item;//设置 tree 的项渲染器。 tree.xml = xml;//设置 tree 的树结构数据。 tree.x = 100;//设置 tree 对象的属性 x 的值,用于控制 tree 对象的显示位置。 tree.y = 100;//设置 tree 对象的属性 y 的值,用于控制 tree 对象的显示位置。 tree.width = 200;//设置 tree 的宽度。 tree.height = 100;//设置 tree 的高度。 Laya.stage.addChild(tree);//将 tree 添加到显示列表。 } (function (_super) { function Item() { Item.__super.call(this);//初始化父类。 this.right = 0; this.left = 0; var selectBox = new laya.ui.Clip("resource/ui/clip_selectBox.png", 1, 2); selectBox.name = "selectBox";//设置 selectBox 的name 为“selectBox”时,将被识别为树结构的项的背景。2帧:悬停时背景、选中时背景。 selectBox.height = 24; selectBox.x = 13; selectBox.y = 0; selectBox.left = 12; this.addChild(selectBox);//需要使用this.访问父类的属性或方法。 var folder = new laya.ui.Clip("resource/ui/clip_tree_folder.png", 1, 3); folder.name = "folder";//设置 folder 的name 为“folder”时,将被识别为树结构的文件夹开启状态图表。2帧:折叠状态、打开状态。 folder.x = 14; folder.y = 4; this.addChild(folder); var label = new laya.ui.Label("treeItem"); label.name = "label";//设置 label 的name 为“label”时,此值将用于树结构数据赋值。 label.color = "#ffff00"; label.width = 150; label.height = 22; label.x = 33; label.y = 1; label.left = 33; label.right = 0; this.addChild(label); var arrow = new laya.ui.Clip("resource/ui/clip_tree_arrow.png", 1, 2); arrow.name = "arrow";//设置 arrow 的name 为“arrow”时,将被识别为树结构的文件夹开启状态图表。2帧:折叠状态、打开状态。 arrow.x = 0; arrow.y = 5; this.addChild(arrow); }; Laya.class(Item,"mypackage.treeExample.Item",_super);//注册类 Item 。 })(laya.ui.Box); + * @example import Tree = laya.ui.Tree; import Browser = laya.utils.Browser; import Handler = laya.utils.Handler; class Tree_Example { constructor() { Laya.init(640, 800); Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/vscroll.png", "resource/ui/vscroll$bar.png", "resource/ui/vscroll$down.png", "resource/ui/vscroll$up.png", "resource/ui/vscroll$up.png", "resource/ui/clip_selectBox.png", "resource/ui/clip_tree_folder * . * png", "resource/ui/clip_tree_arrow.png"], Handler.create(this, this.onLoadComplete)); } private onLoadComplete(): void { var xmlString: String;//创建一个xml字符串,用于存储树结构数据。 xmlString = "<root><item label='box1'><abc label='child1'/><abc label='child2'/><abc label='child3'/><abc label='child4'/><abc label='child5'/></item><item label='box2'><abc * label='child1'/><abc label='child2'/><abc label='child3'/><abc label='child4'/></item></root>"; var domParser: any = new Browser.window.DOMParser();//创建一个DOMParser实例domParser。 var xml: any = domParser.parseFromString(xmlString, "text/xml");//解析xml字符。 var tree: Tree = new Tree();//创建一个 Tree 类的实例对象 tree 。 tree.scrollBarSkin = "resource/ui/vscroll.png";//设置 tree 的皮肤。 tree.itemRender = Item;//设置 tree 的项渲染器。 tree.xml = xml;//设置 tree 的树结构数据。 tree.x = 100;//设置 tree 对象的属性 x 的值,用于控制 tree 对象的显示位置。 tree.y = 100;//设置 tree 对象的属性 y 的值,用于控制 tree 对象的显示位置。 tree.width = 200;//设置 tree 的宽度。 tree.height = 100;//设置 tree 的高度。 Laya.stage.addChild(tree);//将 tree 添加到显示列表。 } } import Box = laya.ui.Box; import Clip = laya.ui.Clip; import Label = laya.ui.Label; class Item extends Box { constructor() { super(); this.name = "render"; this.right = 0; this.left = 0; var selectBox: Clip = new Clip("resource/ui/clip_selectBox.png", 1, 2); selectBox.name = "selectBox"; selectBox.height = 24; selectBox.x = 13; selectBox.y = 0; selectBox.left = 12; this.addChild(selectBox); var folder: Clip = new Clip("resource/ui/clip_tree_folder.png", 1, 3); folder.name = "folder"; folder.x = 14; folder.y = 4; this.addChild(folder); var label: Label = new Label("treeItem"); label.name = "label"; label.color = "#ffff00"; label.width = 150; label.height = 22; label.x = 33; label.y = 1; label.left = 33; label.right = 0; this.addChild(label); var arrow: Clip = new Clip("resource/ui/clip_tree_arrow.png", 1, 2); arrow.name = "arrow"; arrow.x = 0; arrow.y = 5; this.addChild(arrow); } } + */ + class Tree extends Box implements IRender { + + /** + * @private + */ + protected _list:List; + + /** + * @private + */ + protected _source:any[]; + + /** + * @private + */ + protected _renderHandler:Handler; + + /** + * @private + */ + protected _spaceLeft:number; + + /** + * @private + */ + protected _spaceBottom:number; + + /** + * @private + */ + protected _keepStatus:boolean; + + /** + * 创建一个新的 Tree 类实例。 + *

    Tree 构造函数中设置属性width、height的值都为200。

    + */ + + constructor(); + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * @override + */ + protected createChildren():void; + + /** + * @private 此对象包含的List实例的Event.CHANGE事件侦听处理函数。 + */ + protected onListChange(e?:Event):void; + + /** + * 数据源发生变化后,是否保持之前打开状态,默认为true。 + *

    取值: + *

  • true:保持之前打开状态。
  • + *
  • false:不保持之前打开状态。
  • + *

    + */ + get keepStatus():boolean; + set keepStatus(value:boolean); + + /** + * 列表数据源,只包含当前可视节点数据。 + */ + get array():any[]; + set array(value:any[]); + + /** + * 数据源,全部节点数据。 + */ + get source():any[]; + + /** + * 此对象包含的List实例对象。 + */ + get list():List; + + /** + * 此对象包含的List实例的单元格渲染器。 + *

    取值: + *

      + *
    1. 单元格类对象。
    2. + *
    3. UI 的 JSON 描述。
    4. + *

    + * @implements + */ + get itemRender():any; + set itemRender(value:any); + + /** + * 滚动条皮肤。 + */ + get scrollBarSkin():string; + set scrollBarSkin(value:string); + + /** + * 滚动条 + */ + get scrollBar():ScrollBar; + + /** + * 单元格鼠标事件处理器。 + *

    默认返回参数(e:Event,index:int)。

    + */ + get mouseHandler():Handler; + set mouseHandler(value:Handler); + + /** + * Tree 实例的渲染处理器。 + */ + get renderHandler():Handler; + set renderHandler(value:Handler); + + /** + * 左侧缩进距离(以像素为单位)。 + */ + get spaceLeft():number; + set spaceLeft(value:number); + + /** + * 每一项之间的间隔距离(以像素为单位)。 + */ + get spaceBottom():number; + set spaceBottom(value:number); + + /** + * 表示当前选择的项索引。 + */ + get selectedIndex():number; + set selectedIndex(value:number); + + /** + * 当前选中的项对象的数据源。 + */ + get selectedItem():any; + set selectedItem(value:any); + + /** + * @inheritDoc + * @override + */ + set width(value:number); + + /** + * @inheritDoc + * @override + */ + get width():number; + + /** + * @inheritDoc + * @override + */ + set height(value:number); + + /** + * @inheritDoc + * @override + */ + get height():number; + + /** + * @private 获取数据源集合。 + */ + protected getArray():any[]; + + /** + * @private 获取项对象的深度。 + */ + protected getDepth(item:any,num?:number):number; + + /** + * @private 获取项对象的上一级的打开状态。 + */ + protected getParentOpenStatus(item:any):boolean; + + /** + * @private 渲染一个项对象。 + * @param cell 一个项对象。 + * @param index 项的索引。 + */ + protected renderItem(cell:Box,index:number):void; + + /** + * @private + */ + private onArrowClick:any; + + /** + * 设置指定项索引的项对象的打开状态。 + * @param index 项索引。 + * @param isOpen 是否处于打开状态。 + */ + setItemState(index:number,isOpen:boolean):void; + + /** + * 刷新项列表。 + */ + fresh():void; + + /** + * @inheritDoc + * @override + */ + set dataSource(value:any); + + /** + * @inheritDoc + * @override + */ + get dataSource():any; + + /** + * xml结构的数据源。 + */ + set xml(value:XMLDocument); + + /** + * @private 解析并处理XML类型的数据源。 + */ + protected parseXml(xml:ChildNode,source:any[],nodeParent:any,isRoot:boolean):void; + + /** + * @private 处理数据项的打开状态。 + */ + protected parseOpenStatus(oldSource:any[],newSource:any[]):void; + + /** + * @private 判断两个项对象在树结构中的父节点是否相同。 + * @param item1 项对象。 + * @param item2 项对象。 + * @return 如果父节点相同值为true,否则值为false。 + */ + protected isSameParent(item1:any,item2:any):boolean; + + /** + * 表示选择的树节点项的path属性值。 + */ + get selectedPath():string; + + /** + * 更新项列表,显示指定键名的数据项。 + * @param key 键名。 + */ + filter(key:string):void; + + /** + * @private 获取数据源中指定键名的值。 + */ + private getFilterSource:any; + } + + /** + * Component 是ui控件类的基类。 + *

    生命周期:preinitialize > createChildren > initialize > 组件构造函数

    + */ + class UIComponent extends Sprite { + + /** + * X锚点,值为0-1,设置anchorX值最终通过pivotX值来改变节点轴心点。 + */ + protected _anchorX:number; + + /** + * Y锚点,值为0-1,设置anchorY值最终通过pivotY值来改变节点轴心点。 + */ + protected _anchorY:number; + + /** + * @private 控件的数据源。 + */ + protected _dataSource:any; + + /** + * @private 鼠标悬停提示 + */ + protected _toolTip:any; + + /** + * @private 标签 + */ + protected _tag:any; + + /** + * @private 禁用 + */ + protected _disabled:boolean; + + /** + * @private 变灰 + */ + protected _gray:boolean; + + /** + * @private 相对布局组件 + */ + protected _widget:Widget; + + /** + *

    创建一个新的 Component 实例。

    + */ + + constructor(createChildren?:boolean); + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + *

    预初始化。

    + * 子类可在此函数内设置、修改属性默认值 + */ + protected preinitialize():void; + + /** + *

    创建并添加控件子节点。

    + * 子类可在此函数内创建并添加子节点。 + */ + protected createChildren():void; + + /** + *

    控件初始化。

    + * 在此子对象已被创建,可以对子对象进行修改。 + */ + protected initialize():void; + + /** + *

    表示显示对象的宽度,以像素为单位。

    + *

    注:当值为0时,宽度为自适应大小。

    + * @override + */ + get width():number; + + /** + * @override + */ + get_width():number; + + /** + *

    显示对象的实际显示区域宽度(以像素为单位)。

    + */ + protected measureWidth():number; + + /** + *

    立即执行影响宽高度量的延迟调用函数。

    + *

    使用 runCallLater 函数,立即执行影响宽高度量的延迟运行函数(使用 callLater 设置延迟执行函数)。

    + * @see #callLater() + * @see #runCallLater() + */ + protected commitMeasure():void; + + /** + *

    表示显示对象的高度,以像素为单位。

    + *

    注:当值为0时,高度为自适应大小。

    + * @override + */ + get height():number; + + /** + * @override + */ + get_height():number; + + /** + *

    显示对象的实际显示区域高度(以像素为单位)。

    + */ + protected measureHeight():number; + + /** + * @implements 数据赋值,通过对UI赋值来控制UI显示逻辑。

    简单赋值会更改组件的默认属性,使用大括号可以指定组件的任意属性进行赋值。

    + * @example //默认属性赋值 dataSource = {label1: "改变了label", checkbox1: true};//(更改了label1的text属性值,更改checkbox1的selected属性)。 //任意属性赋值 dataSource = {label2: {text:"改变了label",size:14}, checkbox2: {selected:true,x:10}}; + */ + get dataSource():any; + get_dataSource():any; + set dataSource(value:any); + set_dataSource(value:any):void; + + /** + *

    从组件顶边到其内容区域顶边之间的垂直距离(以像素为单位)。

    + */ + get top():number; + get_top():number; + set top(value:number); + set_top(value:number):void; + + /** + *

    从组件底边到其内容区域底边之间的垂直距离(以像素为单位)。

    + */ + get bottom():number; + get_bottom():number; + set bottom(value:number); + set_bottom(value:number):void; + + /** + *

    从组件左边到其内容区域左边之间的水平距离(以像素为单位)。

    + */ + get left():number; + set left(value:number); + + /** + *

    从组件右边到其内容区域右边之间的水平距离(以像素为单位)。

    + */ + get right():number; + set right(value:number); + + /** + *

    在父容器中,此对象的水平方向中轴线与父容器的水平方向中心线的距离(以像素为单位)。

    + */ + get centerX():number; + set centerX(value:number); + + /** + *

    在父容器中,此对象的垂直方向中轴线与父容器的垂直方向中心线的距离(以像素为单位)。

    + */ + get centerY():number; + set centerY(value:number); + protected _sizeChanged():void; + + /** + *

    对象的标签。

    + * 冗余字段,可以用来储存数据。 + */ + get tag():any; + set tag(value:any); + + /** + *

    鼠标悬停提示。

    + *

    可以赋值为文本 String 或函数 Handler ,用来实现自定义样式的鼠标提示和参数携带等。

    + * @example private var _testTips:TestTipsUI = new TestTipsUI(); private function testTips():void { //简单鼠标提示 btn2.toolTip = "这里是鼠标提示<b>粗体</b><br>换行"; //自定义的鼠标提示 btn1.toolTip = showTips1; //带参数的自定义鼠标提示 clip.toolTip = new Handler(this,showTips2, ["clip"]); } private function showTips1():void { _testTips.label.text = "这里是按钮[" + btn1.label + "]"; tip.addChild(_testTips); } private function showTips2(name:String):void { _testTips.label.text = "这里是" + name; tip.addChild(_testTips); } + */ + get toolTip():any; + set toolTip(value:any); + + /** + * 对象的 Event.MOUSE_OVER 事件侦听处理函数。 + */ + private onMouseOver:any; + + /** + * 对象的 Event.MOUSE_OUT 事件侦听处理函数。 + */ + private onMouseOut:any; + + /** + * 是否变灰。 + */ + get gray():boolean; + set gray(value:boolean); + + /** + * 是否禁用页面,设置为true后,会变灰并且禁用鼠标。 + */ + get disabled():boolean; + set disabled(value:boolean); + + /** + * @private

    获取对象的布局样式。请不要直接修改此对象

    + */ + private _getWidget:any; + + /** + * @inheritDoc + * @override + */ + set scaleX(value:number); + + /** + * @override + */ + set_scaleX(value:number):void; + + /** + * @inheritDoc + * @override + */ + get scaleX():number; + + /** + * @inheritDoc + * @override + */ + set scaleY(value:number); + + /** + * @override + */ + set_scaleY(value:number):void; + + /** + * @inheritDoc + * @override + */ + get scaleY():number; + + /** + * @private + */ + protected onCompResize():void; + + /** + * @inheritDoc + * @override + */ + set width(value:number); + + /** + * @override + */ + set_width(value:number):void; + + /** + * @inheritDoc + * @override + */ + set height(value:number); + + /** + * @override + */ + set_height(value:number):void; + + /** + * X锚点,值为0-1,设置anchorX值最终通过pivotX值来改变节点轴心点。 + */ + get anchorX():number; + get_anchorX():number; + set anchorX(value:number); + set_anchorX(value:number):void; + + /** + * Y锚点,值为0-1,设置anchorY值最终通过pivotY值来改变节点轴心点。 + */ + get anchorY():number; + get_anchorY():number; + set anchorY(value:number); + set_anchorY(value:number):void; + + /** + * @param child + * @override + */ + protected _childChanged(child?:Node):void; + } + + /** + * UIEvent 类用来定义UI组件类的事件类型。 + */ + class UIEvent extends Event { + + /** + * 显示提示信息。 + */ + static SHOW_TIP:string; + + /** + * 隐藏提示信息。 + */ + static HIDE_TIP:string; + } + + /** + * 当 Group 实例的 selectedIndex 属性发生变化时调度。 + * @eventType laya.events.Event + */ + + /** + * Group 是一个可以自动布局的项集合控件。 + *

    Group 的默认项对象为 Button 类实例。 + * GroupTabRadioGroup 的基类。

    + */ + class UIGroup extends Box implements IItem { + + /** + * 改变 Group 的选择项时执行的处理器,(默认返回参数: 项索引(index:int))。 + */ + selectHandler:Handler; + + /** + * @private + */ + protected _items:ISelect[]; + + /** + * @private + */ + protected _selectedIndex:number; + + /** + * @private + */ + protected _skin:string; + + /** + * @private + */ + protected _direction:string; + + /** + * @private + */ + protected _space:number; + + /** + * @private + */ + protected _labels:string; + + /** + * @private + */ + protected _labelColors:string; + + /** + * @private + */ + private _labelFont:any; + + /** + * @private + */ + protected _labelStrokeColor:string; + + /** + * @private + */ + protected _strokeColors:string; + + /** + * @private + */ + protected _labelStroke:number; + + /** + * @private + */ + protected _labelSize:number; + + /** + * @private + */ + protected _labelBold:boolean; + + /** + * @private + */ + protected _labelPadding:string; + + /** + * @private + */ + protected _labelAlign:string; + + /** + * @private + */ + protected _stateNum:number; + + /** + * @private + */ + protected _labelChanged:boolean; + + /** + * 创建一个新的 Group 类实例。 + * @param labels 标签集字符串。以逗号做分割,如"item0,item1,item2,item3,item4,item5"。 + * @param skin 皮肤。 + */ + + constructor(labels?:string,skin?:string); + + /** + * @override + */ + protected preinitialize():void; + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * 添加一个项对象,返回此项对象的索引id。 + * @param item 需要添加的项对象。 + * @param autoLayOut 是否自动布局,如果为true,会根据 directionspace 属性计算item的位置。 + * @return + */ + addItem(item:ISelect,autoLayOut?:boolean):number; + + /** + * 删除一个项对象。 + * @param item 需要删除的项对象。 + * @param autoLayOut 是否自动布局,如果为true,会根据 directionspace 属性计算item的位置。 + */ + delItem(item:ISelect,autoLayOut?:boolean):void; + + /** + * 初始化项对象们。 + */ + initItems():void; + + /** + * @private 项对象的点击事件侦听处理函数。 + * @param index 项索引。 + */ + protected itemClick(index:number):void; + + /** + * 表示当前选择的项索引。默认值为-1。 + */ + get selectedIndex():number; + set selectedIndex(value:number); + + /** + * @private 通过对象的索引设置项对象的 selected 属性值。 + * @param index 需要设置的项对象的索引。 + * @param selected 表示项对象的选中状态。 + */ + protected setSelect(index:number,selected:boolean):void; + + /** + * @copy laya.ui.Image#skin + */ + get skin():string; + set skin(value:string); + protected _skinLoaded():void; + + /** + * 标签集合字符串。以逗号做分割,如"item0,item1,item2,item3,item4,item5"。 + */ + get labels():string; + set labels(value:string); + + /** + * @private 创建一个项显示对象。 + * @param skin 项对象的皮肤。 + * @param label 项对象标签。 + */ + protected createItem(skin:string,label:string):Sprite; + + /** + * @copy laya.ui.Button#labelColors() + */ + get labelColors():string; + set labelColors(value:string); + + /** + *

    描边宽度(以像素为单位)。

    + * 默认值0,表示不描边。 + * @see laya.display.Text.stroke() + */ + get labelStroke():number; + set labelStroke(value:number); + + /** + *

    描边颜色,以字符串表示。

    + * 默认值为 "#000000"(黑色); + * @see laya.display.Text.strokeColor() + */ + get labelStrokeColor():string; + set labelStrokeColor(value:string); + + /** + *

    表示各个状态下的描边颜色。

    + * @see laya.display.Text.strokeColor() + */ + get strokeColors():string; + set strokeColors(value:string); + + /** + * 表示按钮文本标签的字体大小。 + */ + get labelSize():number; + set labelSize(value:number); + + /** + * 表示按钮的状态值,以数字表示,默认为3态。 + * @see laya.ui.Button#stateNum + */ + get stateNum():number; + set stateNum(value:number); + + /** + * 表示按钮文本标签是否为粗体字。 + */ + get labelBold():boolean; + set labelBold(value:boolean); + + /** + * 表示按钮文本标签的字体名称,以字符串形式表示。 + * @see laya.display.Text.font() + */ + get labelFont():string; + set labelFont(value:string); + + /** + * 表示按钮文本标签的边距。 + *

    格式:"上边距,右边距,下边距,左边距"。

    + */ + get labelPadding():string; + set labelPadding(value:string); + + /** + * 布局方向。 + *

    默认值为"horizontal"。

    + *

    取值: + *

  • "horizontal":表示水平布局。
  • + *
  • "vertical":表示垂直布局。
  • + *

    + */ + get direction():string; + set direction(value:string); + + /** + * 项对象们之间的间隔(以像素为单位)。 + */ + get space():number; + set space(value:number); + + /** + * @private 更改项对象的属性值。 + */ + protected changeLabels():void; + + /** + * @inheritDoc + * @override + */ + protected commitMeasure():void; + + /** + * 项对象们的存放数组。 + */ + get items():ISelect[]; + + /** + * 获取或设置当前选择的项对象。 + */ + get selection():ISelect; + set selection(value:ISelect); + + /** + * @inheritDoc + * @override + */ + set dataSource(value:any); + + /** + * @inheritDoc + * @override + */ + get dataSource():any; + + /** + * @private + */ + protected _setLabelChanged():void; + } + class UILib { + static __init__():void; + } + + /** + * UIUtils 是文本工具集。 + */ + class UIUtils { + private static grayFilter:any; + + /** + * 需要替换的转义字符表 + */ + static escapeSequence:any; + + /** + * 用字符串填充数组,并返回数组副本。 + * @param arr 源数组对象。 + * @param str 用逗号连接的字符串。如"p1,p2,p3,p4"。 + * @param type 如果值不为null,则填充的是新增值得类型。 + * @return 填充后的数组。 + */ + static fillArray(arr:any[],str:string,type?:typeof Number|typeof String):any[]; + + /** + * 转换uint类型颜色值为字符型颜色值。 + * @param color uint颜色值。 + * @return 字符型颜色值。 + */ + static toColor(color:number):string; + + /** + * 给指定的目标显示对象添加或移除灰度滤镜。 + * @param traget 目标显示对象。 + * @param isGray 如果值true,则添加灰度滤镜,否则移除灰度滤镜。 + */ + static gray(traget:Sprite,isGray?:boolean):void; + + /** + * 给指定的目标显示对象添加滤镜。 + * @param target 目标显示对象。 + * @param filter 滤镜对象。 + */ + static addFilter(target:Sprite,filter:IFilter):void; + + /** + * 移除目标显示对象的指定类型滤镜。 + * @param target 目标显示对象。 + * @param filterType 滤镜类型。 + */ + static clearFilter(target:Sprite,filterType:new () => any):void; + + /** + * 获取当前要替换的转移字符 + * @param word + * @return + */ + private static _getReplaceStr:any; + + /** + * 替换字符串中的转义字符 + * @param str + */ + static adptString(str:string):string; + + /** + * @private + */ + private static _funMap:any; + + /** + * @private 根据字符串,返回函数表达式 + */ + static getBindFun(value:string):Function; + } + + /** + * VBox 是一个垂直布局容器类。 + */ + class VBox extends LayoutBox { + + /** + * 无对齐。 + */ + static NONE:string; + + /** + * 左对齐。 + */ + static LEFT:string; + + /** + * 居中对齐。 + */ + static CENTER:string; + + /** + * 右对齐。 + */ + static RIGHT:string; + + /** + * @override + */ + set width(value:number); + + /** + * @inheritDoc + * @override + */ + get width():number; + + /** + * 兼容以前的changeItems逻辑,是否在发生变动时,使用 sortItem 排序所有item + */ + isSortItem:boolean; + + /** + * @inheritDoc + * @override + */ + protected changeItems():void; + } + + /** + * View 是一个视图类,2.0开始,更改继承至Scene类,相对于Scene,增加相对布局功能。 + */ + class View extends Scene { + + /** + * @private 兼容老版本 + */ + static uiMap:any; + + /** + * @private 相对布局组件 + */ + protected _widget:Widget; + + /** + * @private 控件的数据源。 + */ + protected _dataSource:any; + + /** + * X锚点,值为0-1,设置anchorX值最终通过pivotX值来改变节点轴心点。 + */ + protected _anchorX:number; + + /** + * Y锚点,值为0-1,设置anchorY值最终通过pivotY值来改变节点轴心点。 + */ + protected _anchorY:number; + static __init__():void; + + constructor(); + + /** + * @private 兼容老版本 注册组件类映射。

    用于扩展组件及修改组件对应关系。

    + * @param key 组件类的关键字。 + * @param compClass 组件类对象。 + */ + static regComponent(key:string,compClass:new () => any):void; + + /** + * @private 兼容老版本 注册UI视图类的逻辑处理类。 注册runtime解析。 + * @param key UI视图类的关键字。 + * @param compClass UI视图类对应的逻辑处理类。 + */ + static regViewRuntime(key:string,compClass:new () => any):void; + + /** + * @private 兼容老版本 注册UI配置信息,比如注册一个路径为"test/TestPage"的页面,UI内容是IDE生成的json + * @param url UI的路径 + * @param json UI内容 + */ + static regUI(url:string,json:any):void; + + /** + * @inheritDoc + * @override + */ + destroy(destroyChild?:boolean):void; + + /** + * @private + */ + changeData(key:string):void; + + /** + *

    从组件顶边到其内容区域顶边之间的垂直距离(以像素为单位)。

    + */ + get top():number; + set top(value:number); + + /** + *

    从组件底边到其内容区域底边之间的垂直距离(以像素为单位)。

    + */ + get bottom():number; + set bottom(value:number); + + /** + *

    从组件左边到其内容区域左边之间的水平距离(以像素为单位)。

    + */ + get left():number; + set left(value:number); + + /** + *

    从组件右边到其内容区域右边之间的水平距离(以像素为单位)。

    + */ + get right():number; + set right(value:number); + + /** + *

    在父容器中,此对象的水平方向中轴线与父容器的水平方向中心线的距离(以像素为单位)。

    + */ + get centerX():number; + set centerX(value:number); + + /** + *

    在父容器中,此对象的垂直方向中轴线与父容器的垂直方向中心线的距离(以像素为单位)。

    + */ + get centerY():number; + set centerY(value:number); + + /** + * X锚点,值为0-1,设置anchorX值最终通过pivotX值来改变节点轴心点。 + */ + get anchorX():number; + set anchorX(value:number); + + /** + * Y锚点,值为0-1,设置anchorY值最终通过pivotY值来改变节点轴心点。 + */ + get anchorY():number; + set anchorY(value:number); + + /** + * @private + * @override + */ + protected _sizeChanged():void; + + /** + * @private

    获取对象的布局样式。请不要直接修改此对象

    + */ + private _getWidget:any; + + /** + * @private 兼容老版本 + */ + protected loadUI(path:string):void; + + /** + * @implements #dataSource + */ + get dataSource():any; + set dataSource(value:any); + } + + /** + * ViewStack 类用于视图堆栈类,用于视图的显示等设置处理。 + */ + class ViewStack extends Box implements IItem { + + /** + * @private + */ + protected _items:any[]; + + /** + * @private + */ + protected _setIndexHandler:Handler; + + /** + * @private + */ + protected _selectedIndex:number; + + /** + * 批量设置视图对象。 + * @param views 视图对象数组。 + */ + setItems(views:any[]):void; + + /** + * 添加视图。 + * 添加视图对象,并设置此视图对象的name 属性。 + * @param view 需要添加的视图对象。 + */ + addItem(view:Node):void; + + /** + * 初始化视图对象集合。 + */ + initItems():void; + + /** + * 表示当前视图索引。 + */ + get selectedIndex():number; + set selectedIndex(value:number); + + /** + * @private 通过对象的索引设置项对象的 selected 属性值。 + * @param index 需要设置的对象的索引。 + * @param selected 表示对象的选中状态。 + */ + protected setSelect(index:number,selected:boolean):void; + + /** + * 获取或设置当前选择的项对象。 + */ + get selection():Node; + set selection(value:Node); + + /** + * 索引设置处理器。 + *

    默认回调参数:index:int

    + */ + get setIndexHandler():Handler; + set setIndexHandler(value:Handler); + + /** + * @private 设置属性selectedIndex的值。 + * @param index 选中项索引值。 + */ + protected setIndex(index:number):void; + + /** + * 视图集合数组。 + */ + get items():any[]; + + /** + * @inheritDoc + * @override + */ + set dataSource(value:any); + + /** + * @inheritDoc + * @override + */ + get dataSource():any; + } + + /** + * 使用 VScrollBar (垂直 ScrollBar )控件,可以在因数据太多而不能在显示区域完全显示时控制显示的数据部分。 + * @example 以下示例代码,创建了一个 VScrollBar 实例。 package { import laya.ui.vScrollBar; import laya.ui.VScrollBar; import laya.utils.Handler; public class VScrollBar_Example { private var vScrollBar:VScrollBar; public function VScrollBar_Example() { Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/vscroll.png", "resource/ui/vscroll$bar.png", "resource/ui/vscroll$down.png", "resource/ui/vscroll$up.png"], Handler.create(this, onLoadComplete)); } private function onLoadComplete():void { vScrollBar = new VScrollBar();//创建一个 vScrollBar 类的实例对象 hScrollBar 。 vScrollBar.skin = "resource/ui/vscroll.png";//设置 vScrollBar 的皮肤。 vScrollBar.x = 100;//设置 vScrollBar 对象的属性 x 的值,用于控制 vScrollBar 对象的显示位置。 vScrollBar.y = 100;//设置 vScrollBar 对象的属性 y 的值,用于控制 vScrollBar 对象的显示位置。 vScrollBar.changeHandler = new Handler(this, onChange);//设置 vScrollBar 的滚动变化处理器。 Laya.stage.addChild(vScrollBar);//将此 vScrollBar 对象添加到显示列表。 } private function onChange(value:Number):void { trace("滚动条的位置: value=" + value); } } } + * @example Laya.init(640, 800);//设置游戏画布宽高 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色 var vScrollBar; var res = ["resource/ui/vscroll.png", "resource/ui/vscroll$bar.png", "resource/ui/vscroll$down.png", "resource/ui/vscroll$up.png"]; Laya.loader.load(res, laya.utils.Handler.create(this, onLoadComplete));//加载资源。 function onLoadComplete() { vScrollBar = new laya.ui.VScrollBar();//创建一个 vScrollBar 类的实例对象 hScrollBar 。 vScrollBar.skin = "resource/ui/vscroll.png";//设置 vScrollBar 的皮肤。 vScrollBar.x = 100;//设置 vScrollBar 对象的属性 x 的值,用于控制 vScrollBar 对象的显示位置。 vScrollBar.y = 100;//设置 vScrollBar 对象的属性 y 的值,用于控制 vScrollBar 对象的显示位置。 vScrollBar.changeHandler = new laya.utils.Handler(this, onChange);//设置 vScrollBar 的滚动变化处理器。 Laya.stage.addChild(vScrollBar);//将此 vScrollBar 对象添加到显示列表。 } function onChange(value) { console.log("滚动条的位置: value=" + value); } + * @example import VScrollBar = laya.ui.VScrollBar; import Handler = laya.utils.Handler; class VScrollBar_Example { private vScrollBar: VScrollBar; constructor() { Laya.init(640, 800);//设置游戏画布宽高、渲染模式。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/vscroll.png", "resource/ui/vscroll$bar.png", "resource/ui/vscroll$down.png", "resource/ui/vscroll$up.png"], Handler.create(this, this.onLoadComplete)); } private onLoadComplete(): void { this.vScrollBar = new VScrollBar();//创建一个 vScrollBar 类的实例对象 hScrollBar 。 this.vScrollBar.skin = "resource/ui/vscroll.png";//设置 vScrollBar 的皮肤。 this.vScrollBar.x = 100;//设置 vScrollBar 对象的属性 x 的值,用于控制 vScrollBar 对象的显示位置。 this.vScrollBar.y = 100;//设置 vScrollBar 对象的属性 y 的值,用于控制 vScrollBar 对象的显示位置。 this.vScrollBar.changeHandler = new Handler(this, this.onChange);//设置 vScrollBar 的滚动变化处理器。 Laya.stage.addChild(this.vScrollBar);//将此 vScrollBar 对象添加到显示列表。 } private onChange(value: number): void { console.log("滚动条的位置: value=" + value); } } + */ + class VScrollBar extends ScrollBar { + } + + /** + * 使用 VSlider 控件,用户可以通过在滑块轨道的终点之间移动滑块来选择值。 + *

    VSlider 控件采用垂直方向。滑块轨道从下往上扩展,而标签位于轨道的左右两侧。

    + * @example 以下示例代码,创建了一个 VSlider 实例。 package { import laya.ui.HSlider; import laya.ui.VSlider; import laya.utils.Handler; public class VSlider_Example { private var vSlider:VSlider; public function VSlider_Example() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/vslider.png", "resource/ui/vslider$bar.png"], Handler.create(this, onLoadComplete));//加载资源。 } private function onLoadComplete():void { vSlider = new VSlider();//创建一个 VSlider 类的实例对象 vSlider 。 vSlider.skin = "resource/ui/vslider.png";//设置 vSlider 的皮肤。 vSlider.min = 0;//设置 vSlider 最低位置值。 vSlider.max = 10;//设置 vSlider 最高位置值。 vSlider.value = 2;//设置 vSlider 当前位置值。 vSlider.tick = 1;//设置 vSlider 刻度值。 vSlider.x = 100;//设置 vSlider 对象的属性 x 的值,用于控制 vSlider 对象的显示位置。 vSlider.y = 100;//设置 vSlider 对象的属性 y 的值,用于控制 vSlider 对象的显示位置。 vSlider.changeHandler = new Handler(this, onChange);//设置 vSlider 位置变化处理器。 Laya.stage.addChild(vSlider);//把 vSlider 添加到显示列表。 } private function onChange(value:Number):void { trace("滑块的位置: value=" + value); } } } + * @example Laya.init(640, 800);//设置游戏画布宽高 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色 var vSlider; Laya.loader.load(["resource/ui/vslider.png", "resource/ui/vslider$bar.png"], laya.utils.Handler.create(this, onLoadComplete));//加载资源。 function onLoadComplete() { vSlider = new laya.ui.VSlider();//创建一个 VSlider 类的实例对象 vSlider 。 vSlider.skin = "resource/ui/vslider.png";//设置 vSlider 的皮肤。 vSlider.min = 0;//设置 vSlider 最低位置值。 vSlider.max = 10;//设置 vSlider 最高位置值。 vSlider.value = 2;//设置 vSlider 当前位置值。 vSlider.tick = 1;//设置 vSlider 刻度值。 vSlider.x = 100;//设置 vSlider 对象的属性 x 的值,用于控制 vSlider 对象的显示位置。 vSlider.y = 100;//设置 vSlider 对象的属性 y 的值,用于控制 vSlider 对象的显示位置。 vSlider.changeHandler = new laya.utils.Handler(this, onChange);//设置 vSlider 位置变化处理器。 Laya.stage.addChild(vSlider);//把 vSlider 添加到显示列表。 } function onChange(value) { console.log("滑块的位置: value=" + value); } + * @example import HSlider = laya.ui.HSlider; import VSlider = laya.ui.VSlider; import Handler = laya.utils.Handler; class VSlider_Example { private vSlider: VSlider; constructor() { Laya.init(640, 800);//设置游戏画布宽高。 Laya.stage.bgColor = "#efefef";//设置画布的背景颜色。 Laya.loader.load(["resource/ui/vslider.png", "resource/ui/vslider$bar.png"], Handler.create(this, this.onLoadComplete));//加载资源。 } private onLoadComplete(): void { this.vSlider = new VSlider();//创建一个 VSlider 类的实例对象 vSlider 。 this.vSlider.skin = "resource/ui/vslider.png";//设置 vSlider 的皮肤。 this.vSlider.min = 0;//设置 vSlider 最低位置值。 this.vSlider.max = 10;//设置 vSlider 最高位置值。 this.vSlider.value = 2;//设置 vSlider 当前位置值。 this.vSlider.tick = 1;//设置 vSlider 刻度值。 this.vSlider.x = 100;//设置 vSlider 对象的属性 x 的值,用于控制 vSlider 对象的显示位置。 this.vSlider.y = 100;//设置 vSlider 对象的属性 y 的值,用于控制 vSlider 对象的显示位置。 this.vSlider.changeHandler = new Handler(this, this.onChange);//设置 vSlider 位置变化处理器。 Laya.stage.addChild(this.vSlider);//把 vSlider 添加到显示列表。 } private onChange(value: number): void { console.log("滑块的位置: value=" + value); } } + * @see laya.ui.Slider + */ + class VSlider extends Slider { + } + + /** + * 相对布局插件 + */ + class Widget extends Component { + + /** + * 一个已初始化的 Widget 实例。 + */ + static EMPTY:Widget; + private _top:any; + private _bottom:any; + private _left:any; + private _right:any; + private _centerX:any; + private _centerY:any; + + /** + * @override + */ + onReset():void; + + /** + * 父容器的 Event.RESIZE 事件侦听处理函数。 + */ + protected _onParentResize():void; + + /** + *

    重置对象的 X 轴(水平方向)布局。

    + * @private + */ + resetLayoutX():boolean; + + /** + *

    重置对象的 Y 轴(垂直方向)布局。

    + * @private + */ + resetLayoutY():boolean; + + /** + * 重新计算布局 + */ + resetLayout():void; + + /** + * 表示距顶边的距离(以像素为单位)。 + */ + get top():number; + set top(value:number); + + /** + * 表示距底边的距离(以像素为单位)。 + */ + get bottom():number; + set bottom(value:number); + + /** + * 表示距左边的距离(以像素为单位)。 + */ + get left():number; + set left(value:number); + + /** + * 表示距右边的距离(以像素为单位)。 + */ + get right():number; + set right(value:number); + + /** + * 表示距水平方向中心轴的距离(以像素为单位)。 + */ + get centerX():number; + set centerX(value:number); + + /** + * 表示距垂直方向中心轴的距离(以像素为单位)。 + */ + get centerY():number; + set centerY(value:number); + } + + /** + * 微信开放数据展示组件,直接实例本组件,即可根据组件宽高,位置,以最优的方式显示开放域数据 + */ + class WXOpenDataViewer extends UIComponent { + + constructor(); + + /** + * @override + */ + onEnable():void; + + /** + * @override + */ + onDisable():void; + private _onLoop:any; + + /** + * @override + */ + set width(value:number); + + /** + * @override + */ + get width():number; + + /** + * @override + */ + set height(value:number); + + /** + * @override + */ + get height():number; + + /** + * @override + */ + set x(value:number); + + /** + * @override + */ + get x():number; + + /** + * @override + */ + set y(value:number); + + /** + * @override + */ + get y():number; + private _postMsg:any; + + /** + * 向开放数据域发送消息 + */ + postMsg(msg:any):void; + } + + /** + * Browser 是浏览器代理类。封装浏览器及原生 js 提供的一些功能。 + */ + class Browser { + + /** + * 浏览器代理信息。 + */ + static userAgent:string; + + /** + * 表示是否在移动设备,包括IOS和安卓等设备内。 + */ + static onMobile:boolean; + + /** + * 表示是否在 IOS 设备内。 + */ + static onIOS:boolean; + + /** + * 表示是否在 Mac 设备。 + */ + static onMac:boolean; + + /** + * 表示是否在 IPhone 设备内。 + */ + static onIPhone:boolean; + + /** + * 表示是否在 IPad 设备内。 + */ + static onIPad:boolean; + + /** + * 表示是否在 Android 设备内。 + */ + static onAndroid:boolean; + + /** + * 表示是否在 Windows Phone 设备内。 + */ + static onWP:boolean; + + /** + * 表示是否在 QQ 浏览器内。 + */ + static onQQBrowser:boolean; + + /** + * 表示是否在移动端 QQ 或 QQ 浏览器内。 + */ + static onMQQBrowser:boolean; + + /** + * 表示是否在 Safari 内。 + */ + static onSafari:boolean; + + /** + * 表示是否在 IE 浏览器内 + */ + static onIE:boolean; + + /** + * 表示是否在 微信 内 + */ + static onWeiXin:boolean; + + /** + * 表示是否在 PC 端。 + */ + static onPC:boolean; + + /** + * 微信小游戏 * + */ + static onMiniGame:boolean; + + /** + * 百度小游戏 * + */ + static onBDMiniGame:boolean; + + /** + * 小米戏小游戏 * + */ + static onKGMiniGame:boolean; + + /** + * OPPO小游戏 * + */ + static onQGMiniGame:boolean; + + /** + * VIVO小游戏 * + */ + static onVVMiniGame:boolean; + + /** + * 阿里小游戏 * + */ + static onAlipayMiniGame:boolean; + + /** + * *手机QQ小游戏 + */ + static onQQMiniGame:boolean; + + /** + * * BILIBILI小游戏 + */ + static onBLMiniGame:boolean; + + /** + * 字节跳动小游戏 + */ + static onTTMiniGame:boolean; + + /** + * 华为快游戏 + */ + static onHWMiniGame:boolean; + + /** + * 淘宝小程序 + */ + static onTBMiniGame:boolean; + + /** + * @private + */ + static onFirefox:boolean; + + /** + * @private + */ + static onEdge:boolean; + + /** + * @private + */ + static onLayaRuntime:boolean; + + /** + * 表示是否支持WebAudio + */ + static supportWebAudio:boolean; + + /** + * 表示是否支持LocalStorage + */ + static supportLocalStorage:boolean; + + /** + * 全局离线画布(非主画布)。主要用来测量字体、获取image数据。 + */ + static canvas:HTMLCanvas; + + /** + * 全局离线画布上绘图的环境(非主画布)。 + */ + static context:CanvasRenderingContext2D; + + /** + * @private + */ + private static _window:any; + + /** + * @private + */ + private static _document:any; + + /** + * @private + */ + private static _container:any; + + /** + * @private + */ + private static _pixelRatio:any; + + /** + * @private + */ + static mainCanvas:HTMLCanvas; + + /** + * @private + */ + private static hanzi:any; + + /** + * @private + */ + private static fontMap:any; + + /** + * @private + */ + static measureText:Function; + + /** + * 获取是否为小游戏环境 + * @returns onMiniGame || onBDMiniGame || onQGMiniGame || onKGMiniGame || onVVMiniGame || onAlipayMiniGame || onQQMiniGame || onBLMiniGame || onTTMiniGame || onHWMiniGame || onTBMiniGame + */ + static get _isMiniGame():boolean; + + /** + * 创建浏览器原生节点。 + * @param type 节点类型。 + * @return 创建的节点对象的引用。 + */ + static createElement(type:string):any; + + /** + * 返回 Document 对象中拥有指定 id 的第一个对象的引用。 + * @param type 节点id。 + * @return 节点对象。 + */ + static getElementById(type:string):any; + + /** + * 移除指定的浏览器原生节点对象。 + * @param type 节点对象。 + */ + static removeElement(ele:any):void; + + /** + * 获取浏览器当前时间戳,单位为毫秒。 + */ + static now():number; + + /** + * 浏览器窗口可视宽度。 + * 通过分析浏览器信息获得。浏览器多个属性值优先级为:window.innerWidth(包含滚动条宽度) > document.body.clientWidth(不包含滚动条宽度),如果前者为0或为空,则选择后者。 + */ + static get clientWidth():number; + + /** + * 浏览器窗口可视高度。 + * 通过分析浏览器信息获得。浏览器多个属性值优先级为:window.innerHeight(包含滚动条高度) > document.body.clientHeight(不包含滚动条高度) > document.documentElement.clientHeight(不包含滚动条高度),如果前者为0或为空,则选择后者。 + */ + static get clientHeight():number; + + /** + * 浏览器窗口物理宽度。考虑了设备像素比。 + */ + static get width():number; + + /** + * 浏览器窗口物理高度。考虑了设备像素比。 + */ + static get height():number; + + /** + * 获得设备像素比。 + */ + static get pixelRatio():number; + + /** + * 画布容器,用来盛放画布的容器。方便对画布进行控制 + */ + static get container():any; + static set container(value:any); + + /** + * 浏览器原生 window 对象的引用。 + */ + static get window():any; + + /** + * 浏览器原生 document 对象的引用。 + */ + static get document():any; + } + + /** + *

    Byte 类提供用于优化读取、写入以及处理二进制数据的方法和属性。

    + *

    Byte 类适用于需要在字节层访问数据的高级开发人员。

    + */ + class Byte { + + /** + *

    主机字节序,是 CPU 存放数据的两种不同顺序,包括小端字节序和大端字节序。通过 getSystemEndian 可以获取当前系统的字节序。

    + *

    BIG_ENDIAN :大端字节序,地址低位存储值的高位,地址高位存储值的低位。有时也称之为网络字节序。
    + * LITTLE_ENDIAN :小端字节序,地址低位存储值的低位,地址高位存储值的高位。

    + */ + static BIG_ENDIAN:string; + + /** + *

    主机字节序,是 CPU 存放数据的两种不同顺序,包括小端字节序和大端字节序。通过 getSystemEndian 可以获取当前系统的字节序。

    + *

    LITTLE_ENDIAN :小端字节序,地址低位存储值的低位,地址高位存储值的高位。
    + * BIG_ENDIAN :大端字节序,地址低位存储值的高位,地址高位存储值的低位。有时也称之为网络字节序。

    + */ + static LITTLE_ENDIAN:string; + + /** + * @private + */ + private static _sysEndian:any; + + /** + * @private 是否为小端数据。 + */ + protected _xd_:boolean; + + /** + * @private + */ + private _allocated_:any; + + /** + * @private 原始数据。 + */ + protected _d_:any; + + /** + * @private DataView + */ + protected _u8d_:any; + + /** + * @private + */ + protected _pos_:number; + + /** + * @private + */ + protected _length:number; + + /** + *

    获取当前主机的字节序。

    + *

    主机字节序,是 CPU 存放数据的两种不同顺序,包括小端字节序和大端字节序。

    + *

    BIG_ENDIAN :大端字节序,地址低位存储值的高位,地址高位存储值的低位。有时也称之为网络字节序。
    + * LITTLE_ENDIAN :小端字节序,地址低位存储值的低位,地址高位存储值的高位。

    + * @return 当前系统的字节序。 + */ + static getSystemEndian():string; + + /** + * 创建一个 Byte 类的实例。 + * @param data 用于指定初始化的元素数目,或者用于初始化的TypedArray对象、ArrayBuffer对象。如果为 null ,则预分配一定的内存空间,当可用空间不足时,优先使用这部分内存,如果还不够,则重新分配所需内存。 + */ + + constructor(data?:any); + + /** + * 获取此对象的 ArrayBuffer 数据,数据只包含有效数据部分。 + */ + get buffer():ArrayBuffer; + + /** + *

    Byte 实例的字节序。取值为:BIG_ENDIANBIG_ENDIAN

    + *

    主机字节序,是 CPU 存放数据的两种不同顺序,包括小端字节序和大端字节序。通过 getSystemEndian 可以获取当前系统的字节序。

    + *

    BIG_ENDIAN :大端字节序,地址低位存储值的高位,地址高位存储值的低位。有时也称之为网络字节序。
    + * LITTLE_ENDIAN :小端字节序,地址低位存储值的低位,地址高位存储值的高位。

    + */ + get endian():string; + set endian(value:string); + + /** + *

    Byte 对象的长度(以字节为单位)。

    + *

    如果将长度设置为大于当前长度的值,则用零填充字节数组的右侧;如果将长度设置为小于当前长度的值,将会截断该字节数组。

    + *

    如果要设置的长度大于当前已分配的内存空间的字节长度,则重新分配内存空间,大小为以下两者较大者:要设置的长度、当前已分配的长度的2倍,并将原有数据拷贝到新的内存空间中;如果要设置的长度小于当前已分配的内存空间的字节长度,也会重新分配内存空间,大小为要设置的长度,并将原有数据从头截断为要设置的长度存入新的内存空间中。

    + */ + set length(value:number); + get length():number; + + /** + * @private + */ + private _resizeBuffer:any; + + /** + * @private

    常用于解析固定格式的字节流。

    先从字节流的当前字节偏移位置处读取一个 Uint16 值,然后以此值为长度,读取此长度的字符串。

    + * @return 读取的字符串。 + */ + getString():string; + + /** + *

    常用于解析固定格式的字节流。

    + *

    先从字节流的当前字节偏移位置处读取一个 Uint16 值,然后以此值为长度,读取此长度的字符串。

    + * @return 读取的字符串。 + */ + readString():string; + + /** + * @private

    从字节流中 start 参数指定的位置开始,读取 len 参数指定的字节数的数据,用于创建一个 Float32Array 对象并返回此对象。

    注意:返回的 Float32Array 对象,在 JavaScript 环境下,是原生的 HTML5 Float32Array 对象,对此对象的读取操作都是基于运行此程序的当前主机字节序,此顺序可能与实际数据的字节序不同,如果使用此对象进行读取,需要用户知晓实际数据的字节序和当前主机字节序,如果相同,可正常读取,否则需要用户对实际数据(Float32Array.buffer)包装一层 DataView ,使用 DataView 对象可按照指定的字节序进行读取。

    + * @param start 开始位置。 + * @param len 需要读取的字节长度。如果要读取的长度超过可读取范围,则只返回可读范围内的值。 + * @return 读取的 Float32Array 对象。 + */ + getFloat32Array(start:number,len:number):any; + + /** + * 从字节流中 start 参数指定的位置开始,读取 len 参数指定的字节数的数据,用于创建一个 Float32Array 对象并返回此对象。 + * @param start 开始位置。 + * @param len 需要读取的字节长度。如果要读取的长度超过可读取范围,则只返回可读范围内的值。 + * @return 读取的 Float32Array 对象。 + */ + readFloat32Array(start:number,len:number):any; + + /** + * @private 从字节流中 start 参数指定的位置开始,读取 len 参数指定的字节数的数据,用于创建一个 Uint8Array 对象并返回此对象。 + * @param start 开始位置。 + * @param len 需要读取的字节长度。如果要读取的长度超过可读取范围,则只返回可读范围内的值。 + * @return 读取的 Uint8Array 对象。 + */ + getUint8Array(start:number,len:number):Uint8Array; + + /** + * 从字节流中 start 参数指定的位置开始,读取 len 参数指定的字节数的数据,用于创建一个 Uint8Array 对象并返回此对象。 + * @param start 开始位置。 + * @param len 需要读取的字节长度。如果要读取的长度超过可读取范围,则只返回可读范围内的值。 + * @return 读取的 Uint8Array 对象。 + */ + readUint8Array(start:number,len:number):Uint8Array; + + /** + * @private

    从字节流中 start 参数指定的位置开始,读取 len 参数指定的字节数的数据,用于创建一个 Int16Array 对象并返回此对象。

    注意:返回的 Int16Array 对象,在 JavaScript 环境下,是原生的 HTML5 Int16Array 对象,对此对象的读取操作都是基于运行此程序的当前主机字节序,此顺序可能与实际数据的字节序不同,如果使用此对象进行读取,需要用户知晓实际数据的字节序和当前主机字节序,如果相同,可正常读取,否则需要用户对实际数据(Int16Array.buffer)包装一层 DataView ,使用 DataView 对象可按照指定的字节序进行读取。

    + * @param start 开始读取的字节偏移量位置。 + * @param len 需要读取的字节长度。如果要读取的长度超过可读取范围,则只返回可读范围内的值。 + * @return 读取的 Int16Array 对象。 + */ + getInt16Array(start:number,len:number):any; + + /** + * 从字节流中 start 参数指定的位置开始,读取 len 参数指定的字节数的数据,用于创建一个 Int16Array 对象并返回此对象。 + * @param start 开始读取的字节偏移量位置。 + * @param len 需要读取的字节长度。如果要读取的长度超过可读取范围,则只返回可读范围内的值。 + * @return 读取的 Uint8Array 对象。 + */ + readInt16Array(start:number,len:number):any; + + /** + * @private 从字节流的当前字节偏移位置处读取一个 IEEE 754 单精度(32 位)浮点数。 + * @return 单精度(32 位)浮点数。 + */ + getFloat32():number; + + /** + * 从字节流的当前字节偏移位置处读取一个 IEEE 754 单精度(32 位)浮点数。 + * @return 单精度(32 位)浮点数。 + */ + readFloat32():number; + + /** + * @private 从字节流的当前字节偏移量位置处读取一个 IEEE 754 双精度(64 位)浮点数。 + * @return 双精度(64 位)浮点数。 + */ + getFloat64():number; + + /** + * 从字节流的当前字节偏移量位置处读取一个 IEEE 754 双精度(64 位)浮点数。 + * @return 双精度(64 位)浮点数。 + */ + readFloat64():number; + + /** + * 在字节流的当前字节偏移量位置处写入一个 IEEE 754 单精度(32 位)浮点数。 + * @param value 单精度(32 位)浮点数。 + */ + writeFloat32(value:number):void; + + /** + * 在字节流的当前字节偏移量位置处写入一个 IEEE 754 双精度(64 位)浮点数。 + * @param value 双精度(64 位)浮点数。 + */ + writeFloat64(value:number):void; + + /** + * @private 从字节流的当前字节偏移量位置处读取一个 Int32 值。 + * @return Int32 值。 + */ + getInt32():number; + + /** + * 从字节流的当前字节偏移量位置处读取一个 Int32 值。 + * @return Int32 值。 + */ + readInt32():number; + + /** + * @private 从字节流的当前字节偏移量位置处读取一个 Uint32 值。 + * @return Uint32 值。 + */ + getUint32():number; + + /** + * 从字节流的当前字节偏移量位置处读取一个 Uint32 值。 + * @return Uint32 值。 + */ + readUint32():number; + + /** + * 在字节流的当前字节偏移量位置处写入指定的 Int32 值。 + * @param value 需要写入的 Int32 值。 + */ + writeInt32(value:number):void; + + /** + * 在字节流的当前字节偏移量位置处写入 Uint32 值。 + * @param value 需要写入的 Uint32 值。 + */ + writeUint32(value:number):void; + + /** + * @private 从字节流的当前字节偏移量位置处读取一个 Int16 值。 + * @return Int16 值。 + */ + getInt16():number; + + /** + * 从字节流的当前字节偏移量位置处读取一个 Int16 值。 + * @return Int16 值。 + */ + readInt16():number; + + /** + * @private 从字节流的当前字节偏移量位置处读取一个 Uint16 值。 + * @return Uint16 值。 + */ + getUint16():number; + + /** + * 从字节流的当前字节偏移量位置处读取一个 Uint16 值。 + * @return Uint16 值。 + */ + readUint16():number; + + /** + * 在字节流的当前字节偏移量位置处写入指定的 Uint16 值。 + * @param value 需要写入的Uint16 值。 + */ + writeUint16(value:number):void; + + /** + * 在字节流的当前字节偏移量位置处写入指定的 Int16 值。 + * @param value 需要写入的 Int16 值。 + */ + writeInt16(value:number):void; + + /** + * @private 从字节流的当前字节偏移量位置处读取一个 Uint8 值。 + * @return Uint8 值。 + */ + getUint8():number; + + /** + * 从字节流的当前字节偏移量位置处读取一个 Uint8 值。 + * @return Uint8 值。 + */ + readUint8():number; + + /** + * 在字节流的当前字节偏移量位置处写入指定的 Uint8 值。 + * @param value 需要写入的 Uint8 值。 + */ + writeUint8(value:number):void; + + /** + * @private 读取指定长度的 UTF 型字符串。 + * @param len 需要读取的长度。 + * @return 读取的字符串。 + */ + private _rUTF:any; + + /** + * @private 读取 len 参数指定的长度的字符串。 + * @param len 要读取的字符串的长度。 + * @return 指定长度的字符串。 + */ + getCustomString(len:number):string; + + /** + * @private 读取 len 参数指定的长度的字符串。 + * @param len 要读取的字符串的长度。 + * @return 指定长度的字符串。 + */ + readCustomString(len:number):string; + + /** + * 移动或返回 Byte 对象的读写指针的当前位置(以字节为单位)。下一次调用读取方法时将在此位置开始读取,或者下一次调用写入方法时将在此位置开始写入。 + */ + get pos():number; + set pos(value:number); + + /** + * 可从字节流的当前位置到末尾读取的数据的字节数。 + */ + get bytesAvailable():number; + + /** + * 清除字节数组的内容,并将 length 和 pos 属性重置为 0。调用此方法将释放 Byte 实例占用的内存。 + */ + clear():void; + + /** + *

    将 UTF-8 字符串写入字节流。类似于 writeUTF() 方法,但 writeUTFBytes() 不使用 16 位长度的字为字符串添加前缀。

    + *

    对应的读取方法为: getUTFBytes 。

    + * @param value 要写入的字符串。 + */ + writeUTFBytes(value:string):void; + + /** + *

    将 UTF-8 字符串写入字节流。先写入以字节表示的 UTF-8 字符串长度(作为 16 位整数),然后写入表示字符串字符的字节。

    + *

    对应的读取方法为: getUTFString 。

    + * @param value 要写入的字符串值。 + */ + writeUTFString(value:string):void; + + /** + *

    将 UTF-8 字符串写入字节流。先写入以字节表示的 UTF-8 字符串长度(作为 32 位整数),然后写入表示字符串字符的字节。

    + * @param value 要写入的字符串值。 + */ + writeUTFString32(value:string):void; + + /** + * @private 读取 UTF-8 字符串。 + * @return 读取的字符串。 + */ + readUTFString():string; + + /** + * @private + */ + readUTFString32():string; + + /** + *

    从字节流中读取一个 UTF-8 字符串。假定字符串的前缀是一个无符号的短整型(以此字节表示要读取的长度)。

    + *

    对应的写入方法为: writeUTFString 。

    + * @return 读取的字符串。 + */ + getUTFString():string; + + /** + * @private 读字符串,必须是 writeUTFBytes 方法写入的字符串。 + * @param len 要读的buffer长度,默认将读取缓冲区全部数据。 + * @return 读取的字符串。 + */ + readUTFBytes(len?:number):string; + + /** + *

    从字节流中读取一个由 length 参数指定的长度的 UTF-8 字节序列,并返回一个字符串。

    + *

    一般读取的是由 writeUTFBytes 方法写入的字符串。

    + * @param len 要读的buffer长度,默认将读取缓冲区全部数据。 + * @return 读取的字符串。 + */ + getUTFBytes(len?:number):string; + + /** + *

    在字节流中写入一个字节。

    + *

    使用参数的低 8 位。忽略高 24 位。

    + * @param value + */ + writeByte(value:number):void; + + /** + *

    从字节流中读取带符号的字节。

    + *

    返回值的范围是从 -128 到 127。

    + * @return 介于 -128 和 127 之间的整数。 + */ + readByte():number; + + /** + * @private 从字节流中读取带符号的字节。 + */ + getByte():number; + + /** + *

    将指定 arraybuffer 对象中的以 offset 为起始偏移量, length 为长度的字节序列写入字节流。

    + *

    如果省略 length 参数,则使用默认长度 0,该方法将从 offset 开始写入整个缓冲区;如果还省略了 offset 参数,则写入整个缓冲区。

    + *

    如果 offset 或 length 小于0,本函数将抛出异常。

    + * @param arraybuffer 需要写入的 Arraybuffer 对象。 + * @param offset Arraybuffer 对象的索引的偏移量(以字节为单位) + * @param length 从 Arraybuffer 对象写入到 Byte 对象的长度(以字节为单位) + */ + writeArrayBuffer(arraybuffer:any,offset?:number,length?:number):void; + + /** + * 读取ArrayBuffer数据 + * @param length + * @return + */ + readArrayBuffer(length:number):ArrayBuffer; + } + + /** + * @private 对象缓存统一管理类 + */ + class CacheManger { + + /** + * 单次清理检测允许执行的时间,单位ms。 + */ + static loopTimeLimit:number; + + /** + * @private + */ + private static _cacheList:any; + + /** + * @private 当前检测的索引 + */ + private static _index:any; + + constructor(); + + /** + * 注册cache管理函数 + * @param disposeFunction 释放函数 fun(force:Boolean) + * @param getCacheListFunction 获取cache列表函数fun():Array + */ + static regCacheByFunction(disposeFunction:Function,getCacheListFunction:Function):void; + + /** + * 移除cache管理函数 + * @param disposeFunction 释放函数 fun(force:Boolean) + * @param getCacheListFunction 获取cache列表函数fun():Array + */ + static unRegCacheByFunction(disposeFunction:Function,getCacheListFunction:Function):void; + + /** + * 强制清理所有管理器 + */ + static forceDispose():void; + + /** + * 开始检测循环 + * @param waitTime 检测间隔时间 + */ + static beginCheck(waitTime?:number):void; + + /** + * 停止检测循环 + */ + static stopCheck():void; + + /** + * @private 检测函数 + */ + private static _checkLoop:any; + } + + /** + * @private + */ + class CallLater { + static I:CallLater; + + /** + * @private + */ + private _pool:any; + + /** + * @private + */ + private _map:any; + + /** + * @private + */ + private _laters:any; + + /** + * @private + */ + private _getHandler:any; + + /** + * 延迟执行。 + * @param caller 执行域(this)。 + * @param method 定时器回调函数。 + * @param args 回调参数。 + */ + callLater(caller:any,method:Function,args?:any[]):void; + + /** + * 立即执行 callLater 。 + * @param caller 执行域(this)。 + * @param method 定时器回调函数。 + */ + runCallLater(caller:any,method:Function):void; + } + + /** + * ClassUtils 是一个类工具类。 + */ + class ClassUtils { + + /** + * @private + */ + private static DrawTypeDic:any; + + /** + * @private + */ + private static _temParam:any; + + /** + * @private + */ + private static _classMap:any; + + /** + * @private + */ + private static _tM:any; + + /** + * @private + */ + private static _alpha:any; + + /** + * 注册 Class 映射,方便在class反射时获取。 + * @param className 映射的名字或者别名。 + * @param classDef 类的全名或者类的引用,全名比如:"laya.display.Sprite"。 + */ + static regClass(className:string,classDef:any):void; + + /** + * 根据类名短名字注册类,比如传入[Sprite],功能同regClass("Sprite",Sprite); + * @param classes 类数组 + */ + static regShortClassName(classes:any[]):void; + + /** + * 返回注册的 Class 映射。 + * @param className 映射的名字。 + */ + static getRegClass(className:string):any; + + /** + * 根据名字返回类对象。 + * @param className 类名(比如laya.display.Sprite)或者注册的别名(比如Sprite)。 + * @return 类对象 + */ + static getClass(className:string):any; + + /** + * 根据名称创建 Class 实例。 + * @param className 类名(比如laya.display.Sprite)或者注册的别名(比如Sprite)。 + * @return 返回类的实例。 + */ + static getInstance(className:string):any; + + /** + * 根据指定的 json 数据创建节点对象。 + * 比如: + * { + * "type":"Sprite", + * "props":{ + * "x":100, + * "y":50, + * "name":"item1", + * "scale":[2,2] + * }, + * "customProps":{ + * "x":100, + * "y":50, + * "name":"item1", + * "scale":[2,2] + * }, + * "child":[ + * { + * "type":"Text", + * "props":{ + * "text":"this is a test", + * "var":"label", + * "rumtime":"" + * } + * } + * ] + * } + * @param json json字符串或者Object对象。 + * @param node node节点,如果为空,则新创建一个。 + * @param root 根节点,用来设置var定义。 + * @return 生成的节点。 + */ + static createByJson(json:any,node?:any,root?:Node,customHandler?:Handler,instanceHandler?:Handler):any; + + /** + * @private + */ + private static _getGraphicsFromSprite:any; + + /** + * @private + */ + private static _getTransformData:any; + + /** + * @private + */ + private static _addGraphicToGraphics:any; + + /** + * @private + */ + private static _adptLineData:any; + + /** + * @private + */ + private static _adptTextureData:any; + + /** + * @private + */ + private static _adptLinesData:any; + + /** + * @private + */ + private static _getParams:any; + + /** + * @private + */ + private static _getObjVar:any; + } + + /** + * @private ColorUtils 是一个颜色值处理类。 + */ + class ColorUtils { + + /** + * @private + */ + static _SAVE:any; + + /** + * @private + */ + static _SAVE_SIZE:number; + + /** + * @private + */ + private static _COLOR_MAP:any; + + /** + * @private + */ + private static _DEFAULT:any; + + /** + * @private + */ + private static _COLODID:any; + + /** + * rgba 取值范围0-1 + */ + arrColor:any[]; + + /** + * 字符串型颜色值。 + */ + strColor:string; + + /** + * uint 型颜色值。 + */ + numColor:number; + + /** + * 根据指定的属性值,创建一个 Color 类的实例。 + * @param value 颜色值,可以是字符串:"#ff0000"或者16进制颜色 0xff0000。 + */ + + constructor(value:any); + + /** + * @private + */ + static _initDefault():any; + + /** + * @private 缓存太大,则清理缓存 + */ + static _initSaveMap():void; + + /** + * 根据指定的属性值,创建并返回一个 Color 类的实例。 + * @param value 颜色值,可以是字符串:"#ff0000"或者16进制颜色 0xff0000。 + * @return 一个 Color 类的实例。 + */ + static create(value:any):ColorUtils; + } + + /** + * @private Dragging 类是触摸滑动控件。 + */ + class Dragging { + + /** + * 被拖动的对象。 + */ + target:Sprite; + + /** + * 缓动衰减系数。 + */ + ratio:number; + + /** + * 单帧最大偏移量。 + */ + maxOffset:number; + + /** + * 滑动范围。 + */ + area:Rectangle; + + /** + * 表示拖动是否有惯性。 + */ + hasInertia:boolean; + + /** + * 橡皮筋最大值。 + */ + elasticDistance:number; + + /** + * 橡皮筋回弹时间,单位为毫秒。 + */ + elasticBackTime:number; + + /** + * 事件携带数据。 + */ + data:any; + private _dragging:any; + private _clickOnly:any; + private _elasticRateX:any; + private _elasticRateY:any; + private _lastX:any; + private _lastY:any; + private _offsetX:any; + private _offsetY:any; + private _offsets:any; + private _disableMouseEvent:any; + private _tween:any; + private _parent:any; + + /** + * 开始拖拽。 + * @param target 待拖拽的 Sprite 对象。 + * @param area 滑动范围。 + * @param hasInertia 拖动是否有惯性。 + * @param elasticDistance 橡皮筋最大值。 + * @param elasticBackTime 橡皮筋回弹时间,单位为毫秒。 + * @param data 事件携带数据。 + * @param disableMouseEvent 鼠标事件是否有效。 + * @param ratio 惯性阻尼系数 + */ + start(target:Sprite,area:Rectangle,hasInertia:boolean,elasticDistance:number,elasticBackTime:number,data:any,disableMouseEvent:boolean,ratio?:number):void; + + /** + * 清除计时器。 + */ + private clearTimer:any; + + /** + * 停止拖拽。 + */ + stop():void; + + /** + * 拖拽的循环处理函数。 + */ + private loop:any; + + /** + * 拖拽区域检测。 + */ + private checkArea:any; + + /** + * 移动至设定的拖拽区域。 + */ + private backToArea:any; + + /** + * 舞台的抬起事件侦听函数。 + * @param e Event 对象。 + */ + private onStageMouseUp:any; + + /** + * 橡皮筋效果检测。 + */ + private checkElastic:any; + + /** + * 移动。 + */ + private tweenMove:any; + + /** + * 结束拖拽。 + */ + private clear:any; + } + + /** + * Ease 类定义了缓动函数,以便实现 Tween 动画的缓动效果。 + */ + class Ease { + + /** + * @private + */ + private static HALF_PI:any; + + /** + * @private + */ + private static PI2:any; + + /** + * 定义无加速持续运动。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static linearNone(t:number,b:number,c:number,d:number):number; + + /** + * 定义无加速持续运动。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static linearIn(t:number,b:number,c:number,d:number):number; + + /** + * 定义无加速持续运动。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static linearInOut(t:number,b:number,c:number,d:number):number; + + /** + * 定义无加速持续运动。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static linearOut(t:number,b:number,c:number,d:number):number; + + /** + * 方法以零速率开始运动,然后在执行时加快运动速度。 + * 它的运动是类似一个球落向地板又弹起后,几次逐渐减小的回弹运动。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static bounceIn(t:number,b:number,c:number,d:number):number; + + /** + * 开始运动时速率为零,先对运动进行加速,再减速直到速率为零。 + * 它的运动是类似一个球落向地板又弹起后,几次逐渐减小的回弹运动。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static bounceInOut(t:number,b:number,c:number,d:number):number; + + /** + * 以较快速度开始运动,然后在执行时减慢运动速度,直至速率为零。 + * 它的运动是类似一个球落向地板又弹起后,几次逐渐减小的回弹运动。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static bounceOut(t:number,b:number,c:number,d:number):number; + + /** + * 开始时往后运动,然后反向朝目标移动。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @param s 指定过冲量,此处数值越大,过冲越大。 + * @return 指定时间的插补属性的值。 + */ + static backIn(t:number,b:number,c:number,d:number,s?:number):number; + + /** + * 开始运动时是向后跟踪,再倒转方向并朝目标移动,稍微过冲目标,然后再次倒转方向,回来朝目标移动。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @param s 指定过冲量,此处数值越大,过冲越大。 + * @return 指定时间的插补属性的值。 + */ + static backInOut(t:number,b:number,c:number,d:number,s?:number):number; + + /** + * 开始运动时是朝目标移动,稍微过冲,再倒转方向回来朝着目标。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @param s 指定过冲量,此处数值越大,过冲越大。 + * @return 指定时间的插补属性的值。 + */ + static backOut(t:number,b:number,c:number,d:number,s?:number):number; + + /** + * 方法以零速率开始运动,然后在执行时加快运动速度。 + * 其中的运动由按照指数方式衰减的正弦波来定义。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @param a 指定正弦波的幅度。 + * @param p 指定正弦波的周期。 + * @return 指定时间的插补属性的值。 + */ + static elasticIn(t:number,b:number,c:number,d:number,a?:number,p?:number):number; + + /** + * 开始运动时速率为零,先对运动进行加速,再减速直到速率为零。 + * 其中的运动由按照指数方式衰减的正弦波来定义。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @param a 指定正弦波的幅度。 + * @param p 指定正弦波的周期。 + * @return 指定时间的插补属性的值。 + */ + static elasticInOut(t:number,b:number,c:number,d:number,a?:number,p?:number):number; + + /** + * 以较快速度开始运动,然后在执行时减慢运动速度,直至速率为零。 + * 其中的运动由按照指数方式衰减的正弦波来定义。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @param a 指定正弦波的幅度。 + * @param p 指定正弦波的周期。 + * @return 指定时间的插补属性的值。 + */ + static elasticOut(t:number,b:number,c:number,d:number,a?:number,p?:number):number; + + /** + * 以零速率开始运动,然后在执行时加快运动速度。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static strongIn(t:number,b:number,c:number,d:number):number; + + /** + * 开始运动时速率为零,先对运动进行加速,再减速直到速率为零。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static strongInOut(t:number,b:number,c:number,d:number):number; + + /** + * 以较快速度开始运动,然后在执行时减慢运动速度,直至速率为零。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static strongOut(t:number,b:number,c:number,d:number):number; + + /** + * 开始运动时速率为零,先对运动进行加速,再减速直到速率为零。 + * Sine 缓动方程中的运动加速度小于 Quad 方程中的运动加速度。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static sineInOut(t:number,b:number,c:number,d:number):number; + + /** + * 以零速率开始运动,然后在执行时加快运动速度。 + * Sine 缓动方程中的运动加速度小于 Quad 方程中的运动加速度。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static sineIn(t:number,b:number,c:number,d:number):number; + + /** + * 以较快速度开始运动,然后在执行时减慢运动速度,直至速率为零。 + * Sine 缓动方程中的运动加速度小于 Quad 方程中的运动加速度。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static sineOut(t:number,b:number,c:number,d:number):number; + + /** + * 以零速率开始运动,然后在执行时加快运动速度。 + * Quint 缓动方程的运动加速大于 Quart 缓动方程。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static quintIn(t:number,b:number,c:number,d:number):number; + + /** + * 开始运动时速率为零,先对运动进行加速,再减速直到速率为零。 + * Quint 缓动方程的运动加速大于 Quart 缓动方程。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static quintInOut(t:number,b:number,c:number,d:number):number; + + /** + * 以较快速度开始运动,然后在执行时减慢运动速度,直至速率为零。 + * Quint 缓动方程的运动加速大于 Quart 缓动方程。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static quintOut(t:number,b:number,c:number,d:number):number; + + /** + * 方法以零速率开始运动,然后在执行时加快运动速度。 + * Quart 缓动方程的运动加速大于 Cubic 缓动方程。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static quartIn(t:number,b:number,c:number,d:number):number; + + /** + * 开始运动时速率为零,先对运动进行加速,再减速直到速率为零。 + * Quart 缓动方程的运动加速大于 Cubic 缓动方程。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static quartInOut(t:number,b:number,c:number,d:number):number; + + /** + * 以较快速度开始运动,然后在执行时减慢运动速度,直至速率为零。 + * Quart 缓动方程的运动加速大于 Cubic 缓动方程。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static quartOut(t:number,b:number,c:number,d:number):number; + + /** + * 方法以零速率开始运动,然后在执行时加快运动速度。 + * Cubic 缓动方程的运动加速大于 Quad 缓动方程。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static cubicIn(t:number,b:number,c:number,d:number):number; + + /** + * 开始运动时速率为零,先对运动进行加速,再减速直到速率为零。 + * Cubic 缓动方程的运动加速大于 Quad 缓动方程。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static cubicInOut(t:number,b:number,c:number,d:number):number; + + /** + * 以较快速度开始运动,然后在执行时减慢运动速度,直至速率为零。 + * Cubic 缓动方程的运动加速大于 Quad 缓动方程。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static cubicOut(t:number,b:number,c:number,d:number):number; + + /** + * 方法以零速率开始运动,然后在执行时加快运动速度。 + * Quad 缓动方程中的运动加速度等于 100% 缓动的时间轴补间的运动加速度,并且显著小于 Cubic 缓动方程中的运动加速度。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static quadIn(t:number,b:number,c:number,d:number):number; + + /** + * 开始运动时速率为零,先对运动进行加速,再减速直到速率为零。 + * Quad 缓动方程中的运动加速度等于 100% 缓动的时间轴补间的运动加速度,并且显著小于 Cubic 缓动方程中的运动加速度。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static quadInOut(t:number,b:number,c:number,d:number):number; + + /** + * 以较快速度开始运动,然后在执行时减慢运动速度,直至速率为零。 + * Quad 缓动方程中的运动加速度等于 100% 缓动的时间轴补间的运动加速度,并且显著小于 Cubic 缓动方程中的运动加速度。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static quadOut(t:number,b:number,c:number,d:number):number; + + /** + * 方法以零速率开始运动,然后在执行时加快运动速度。 + * 其中每个时间间隔是剩余距离减去一个固定比例部分。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static expoIn(t:number,b:number,c:number,d:number):number; + + /** + * 开始运动时速率为零,先对运动进行加速,再减速直到速率为零。 + * 其中每个时间间隔是剩余距离减去一个固定比例部分。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static expoInOut(t:number,b:number,c:number,d:number):number; + + /** + * 以较快速度开始运动,然后在执行时减慢运动速度,直至速率为零。 + * 其中每个时间间隔是剩余距离减去一个固定比例部分。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static expoOut(t:number,b:number,c:number,d:number):number; + + /** + * 方法以零速率开始运动,然后在执行时加快运动速度。 + * 缓动方程的运动加速会产生突然的速率变化。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static circIn(t:number,b:number,c:number,d:number):number; + + /** + * 开始运动时速率为零,先对运动进行加速,再减速直到速率为零。 + * 缓动方程的运动加速会产生突然的速率变化。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static circInOut(t:number,b:number,c:number,d:number):number; + + /** + * 以较快速度开始运动,然后在执行时减慢运动速度,直至速率为零。 + * 缓动方程的运动加速会产生突然的速率变化。 + * @param t 指定当前时间,介于 0 和持续时间之间(包括二者)。 + * @param b 指定动画属性的初始值。 + * @param c 指定动画属性的更改总计。 + * @param d 指定运动的持续时间。 + * @return 指定时间的插补属性的值。 + */ + static circOut(t:number,b:number,c:number,d:number):number; + } + class FontInfo { + static EMPTY:FontInfo; + private static _cache:any; + private static _gfontID:any; + private static _lastFont:any; + private static _lastFontInfo:any; + + /** + * 解析字体模型 + * @param font + */ + static Parse(font:string):FontInfo; + + constructor(font:string|null); + + /** + * 设置字体格式 + * @param value + */ + setFont(value:string):void; + } + + /** + * Graphics动画解析器 + * @private + */ + class GraphicAnimation extends FrameAnimation { + + /** + * @private + */ + animationList:any[]; + + /** + * @private + */ + animationDic:any; + + /** + * @private + */ + protected _nodeList:any[]; + + /** + * @private + */ + protected _nodeDefaultProps:any; + + /** + * @private + */ + protected _gList:any[]; + + /** + * @private + */ + protected _nodeIDAniDic:any; + + /** + * @private + */ + protected static _drawTextureCmd:any[]; + + /** + * @private + */ + protected static _temParam:any[]; + + /** + * @private + */ + private static _I:any; + + /** + * @private + */ + private static _rootMatrix:any; + + /** + * @private + */ + private _rootNode:any; + + /** + * @private + */ + protected _nodeGDic:any; + + /** + * @private + */ + private _parseNodeList:any; + + /** + * @private + */ + private _calGraphicData:any; + + /** + * @private + */ + private _createGraphicData:any; + + /** + * @private + */ + protected _createFrameGraphic(frame:number):any; + protected _updateNodeGraphic(node:any,frame:number,parentTransfrom:Matrix,g:Graphics,alpha?:number):void; + protected _updateNodeGraphic2(node:any,frame:number,g:Graphics):void; + + /** + * @private + * @override + */ + protected _calculateKeyFrames(node:any):void; + + /** + * @private + */ + protected getNodeDataByID(nodeID:number):any; + + /** + * @private + */ + protected _getParams(obj:any,params:any[],frame:number,obj2:any):any[]; + + /** + * @private + */ + private _getObjVar:any; + private static _tempMt:any; + + /** + * @private + */ + protected _getTextureByUrl(url:string):any; + + /** + * @private + */ + setAniData(uiView:any,aniName?:string):void; + parseByData(aniData:any):any; + + /** + * @private + */ + setUpAniData(uiView:any):void; + + /** + * @private + */ + protected _clear():void; + static parseAnimationByData(animationObject:any):any; + static parseAnimationData(aniData:any):any; + } + + /** + * HalfFloatUtils 类用于创建HalfFloat工具。 + */ + class HalfFloatUtils { + + /** + * round a number to a half float number bits. + * @param num + */ + static roundToFloat16Bits(num:number):number; + + /** + * convert a half float number bits to a number. + * @param float16bits - half float number bits + */ + static convertToNumber(float16bits:number):number; + } + + /** + *

    Handler 是事件处理器类。

    + *

    推荐使用 Handler.create() 方法从对象池创建,减少对象创建消耗。创建的 Handler 对象不再使用后,可以使用 Handler.recover() 将其回收到对象池,回收后不要再使用此对象,否则会导致不可预料的错误。

    + *

    注意:由于鼠标事件也用本对象池,不正确的回收及调用,可能会影响鼠标事件的执行。

    + */ + class Handler { + + /** + * @private handler对象池 + */ + protected static _pool:Handler[]; + + /** + * @private + */ + private static _gid:any; + + /** + * 执行域(this)。 + */ + caller:Object|null; + + /** + * 处理方法。 + */ + method:Function|null; + + /** + * 参数。 + */ + args:any[]|null; + + /** + * 表示是否只执行一次。如果为true,回调后执行recover()进行回收,回收后会被再利用,默认为false 。 + */ + once:boolean; + + /** + * @private + */ + protected _id:number; + + /** + * 根据指定的属性值,创建一个 Handler 类的实例。 + * @param caller 执行域。 + * @param method 处理函数。 + * @param args 函数参数。 + * @param once 是否只执行一次。 + */ + + constructor(caller?:Object|null,method?:Function|null,args?:any[]|null,once?:boolean); + + /** + * 设置此对象的指定属性值。 + * @param caller 执行域(this)。 + * @param method 回调方法。 + * @param args 携带的参数。 + * @param once 是否只执行一次,如果为true,执行后执行recover()进行回收。 + * @return 返回 handler 本身。 + */ + setTo(caller:any,method:Function|null,args:any[]|null,once?:boolean):Handler; + + /** + * 执行处理器。 + */ + run():any; + + /** + * 执行处理器,并携带额外数据。 + * @param data 附加的回调数据,可以是单数据或者Array(作为多参)。 + */ + runWith(data:any):any; + + /** + * 清理对象引用。 + */ + clear():Handler; + + /** + * 清理并回收到 Handler 对象池内。 + */ + recover():void; + + /** + * 从对象池内创建一个Handler,默认会执行一次并立即回收,如果不需要自动回收,设置once参数为false。 + * @param caller 执行域(this)。 + * @param method 回调方法。 + * @param args 携带的参数。 + * @param once 是否只执行一次,如果为true,回调后执行recover()进行回收,默认为true。 + * @return 返回创建的handler实例。 + */ + static create(caller:any,method:Function|null,args?:any[]|null,once?:boolean):Handler; + } + + /** + * 鼠标点击区域,可以设置绘制一系列矢量图作为点击区域和非点击区域(目前只支持圆形,矩形,多边形) + */ + class HitArea { + + /** + * @private + */ + private static _cmds:any; + + /** + * @private + */ + private static _rect:any; + + /** + * @private + */ + private static _ptPoint:any; + + /** + * @private + */ + private _hit:any; + + /** + * @private + */ + private _unHit:any; + + /** + * 检测对象是否包含指定的点。 + * @param x 点的 X 轴坐标值(水平位置)。 + * @param y 点的 Y 轴坐标值(垂直位置)。 + * @return 如果包含指定的点,则值为 true;否则为 false。 + */ + contains(x:number,y:number):boolean; + + /** + * 可点击区域,可以设置绘制一系列矢量图作为点击区域(目前只支持圆形,矩形,多边形) + */ + get hit():Graphics; + set hit(value:Graphics); + + /** + * 不可点击区域,可以设置绘制一系列矢量图作为非点击区域(目前只支持圆形,矩形,多边形) + */ + get unHit():Graphics; + set unHit(value:Graphics); + } + + /** + * @private HTMLChar 是一个 HTML 字符类。 + */ + class HTMLChar { + private static _isWordRegExp:any; + + /** + * x坐标 + */ + x:number; + + /** + * y坐标 + */ + y:number; + + /** + * 宽 + */ + width:number; + + /** + * 高 + */ + height:number; + + /** + * 表示是否是正常单词(英文|.|数字)。 + */ + isWord:boolean; + + /** + * 字符。 + */ + char:string|null; + + /** + * 字符数量。 + */ + charNum:number; + + /** + * CSS 样式。 + */ + style:any; + + /** + * 创建实例 + */ + + constructor(); + + /** + * 根据指定的字符、宽高、样式,创建一个 HTMLChar 类的实例。 + * @param char 字符。 + * @param w 宽度。 + * @param h 高度。 + * @param style CSS 样式。 + */ + setData(char:string,w:number,h:number,style:any):HTMLChar; + + /** + * 重置 + */ + reset():HTMLChar; + + /** + * 回收 + */ + recover():void; + + /** + * 创建 + */ + static create():HTMLChar; + } + + /** + * @author laya + */ + class IStatRender { + + /** + * 显示性能统计信息。 + * @param x X轴显示位置。 + * @param y Y轴显示位置。 + */ + show(x?:number,y?:number):void; + + /** + * 激活性能统计 + */ + enable():void; + + /** + * 隐藏性能统计信息。 + */ + hide():void; + + /** + * 点击性能统计显示区域的处理函数。 + */ + set_onclick(fn:Function):void; + isCanvasRender():boolean; + renderNotCanvas(ctx:any,x:number,y:number):void; + } + + /** + * Log 类用于在界面内显示日志记录信息。 + * 注意:在加速器内不可使用 + */ + class Log { + + /** + * @private + */ + private static _logdiv:any; + + /** + * @private + */ + private static _btn:any; + + /** + * @private + */ + private static _count:any; + + /** + * 最大打印数量,超过这个数量,则自动清理一次,默认为50次 + */ + static maxCount:number; + + /** + * 是否自动滚动到底部,默认为true + */ + static autoScrollToBottom:boolean; + + /** + * 激活Log系统,使用方法Laya.init(800,600,Laya.Log); + */ + static enable():void; + + /** + * 隐藏/显示日志面板 + */ + static toggle():void; + + /** + * 增加日志内容。 + * @param value 需要增加的日志内容。 + */ + static print(value:string):void; + + /** + * 清理日志 + */ + static clear():void; + } + + /** + * Mouse 类用于控制鼠标光标样式。 + */ + class Mouse { + + /** + * @private + */ + private static _style:any; + + /** + * @private + */ + private static _preCursor:any; + + /** + * 设置鼠标样式 + * @param cursorStr 例如auto move no-drop col-resize all-scroll pointer not-allowed row-resize crosshair progress e-resize ne-resize default text n-resize nw-resize help vertical-text s-resize se-resize inherit wait w-resize sw-resize + */ + static set cursor(cursorStr:string); + static get cursor():string; + + /** + * 隐藏鼠标 + */ + static hide():void; + + /** + * 显示鼠标 + */ + static show():void; + } + class PerformancePlugin { + static _enable:boolean; + static PERFORMANCE_LAYA:string; + static PERFORMANCE_LAYA_3D:string; + static PERFORMANCE_LAYA_2D:string; + static PERFORMANCE_LAYA_3D_PRERENDER:string; + static PERFORMANCE_LAYA_3D_UPDATESCRIPT:string; + static PERFORMANCE_LAYA_3D_PHYSICS:string; + static PERFORMANCE_LAYA_3D_PHYSICS_SIMULATE:string; + static PERFORMANCE_LAYA_3D_PHYSICS_CHARACTORCOLLISION:string; + static PERFORMANCE_LAYA_3D_PHYSICS_EVENTSCRIPTS:string; + static PERFORMANCE_LAYA_3D_RENDER:string; + static PERFORMANCE_LAYA_3D_RENDER_SHADOWMAP:string; + static PERFORMANCE_LAYA_3D_RENDER_CLUSTER:string; + static PERFORMANCE_LAYA_3D_RENDER_CULLING:string; + static PERFORMANCE_LAYA_3D_RENDER_RENDERDEPTHMDOE:string; + static PERFORMANCE_LAYA_3D_RENDER_RENDEROPAQUE:string; + static PERFORMANCE_LAYA_3D_RENDER_RENDERCOMMANDBUFFER:string; + static PERFORMANCE_LAYA_3D_RENDER_RENDERTRANSPARENT:string; + static PERFORMANCE_LAYA_3D_RENDER_POSTPROCESS:string; + static setPerformanceDataTool(tool:any):void; + static begainSample(path:string):void; + static endSample(path:string):number; + static expoertFile(path:string):any; + static showFunSampleFun(path:string):void; + static set enable(value:boolean); + static get enable():boolean; + static set enableDataExport(value:boolean); + static get enableDataExport():boolean; + } + + /** + *

    Pool 是对象池类,用于对象的存储、重复使用。

    + *

    合理使用对象池,可以有效减少对象创建的开销,避免频繁的垃圾回收,从而优化游戏流畅度。

    + */ + class Pool { + + /** + * @private + */ + private static _CLSID:any; + + /** + * @private + */ + private static POOLSIGN:any; + + /** + * @private 对象存放池。 + */ + private static _poolDic:any; + + /** + * 根据对象类型标识字符,获取对象池。 + * @param sign 对象类型标识字符。 + * @return 对象池。 + */ + static getPoolBySign(sign:string):any[]; + + /** + * 清除对象池的对象。 + * @param sign 对象类型标识字符。 + */ + static clearBySign(sign:string):void; + + /** + * 将对象放到对应类型标识的对象池中。 + * @param sign 对象类型标识字符。 + * @param item 对象。 + */ + static recover(sign:string,item:any):void; + + /** + * 根据类名进行回收,如果类有类名才进行回收,没有则不回收 + * @param instance 类的具体实例 + */ + static recoverByClass(instance:any):void; + + /** + * 返回类的唯一标识 + */ + private static _getClassSign:any; + + /** + * 根据类名回收类的实例 + * @param instance 类的具体实例 + */ + static createByClass(cls:new () => T):T; + + /** + *

    根据传入的对象类型标识字符,获取对象池中此类型标识的一个对象实例。

    + *

    当对象池中无此类型标识的对象时,则根据传入的类型,创建一个新的对象返回。

    + * @param sign 对象类型标识字符。 + * @param cls 用于创建该类型对象的类。 + * @return 此类型标识的一个对象。 + */ + static getItemByClass(sign:string,cls:new () => T):T; + + /** + *

    根据传入的对象类型标识字符,获取对象池中此类型标识的一个对象实例。

    + *

    当对象池中无此类型标识的对象时,则使用传入的创建此类型对象的函数,新建一个对象返回。

    + * @param sign 对象类型标识字符。 + * @param createFun 用于创建该类型对象的方法。 + * @param caller this对象 + * @return 此类型标识的一个对象。 + */ + static getItemByCreateFun(sign:string,createFun:Function,caller?:any):any; + + /** + * 根据传入的对象类型标识字符,获取对象池中已存储的此类型的一个对象,如果对象池中无此类型的对象,则返回 null 。 + * @param sign 对象类型标识字符。 + * @return 对象池中此类型的一个对象,如果对象池中无此类型的对象,则返回 null 。 + */ + static getItem(sign:string):any; + } + + /** + * @private 基于个数的对象缓存管理器 + */ + class PoolCache { + + /** + * 对象在Pool中的标识 + */ + sign:string; + + /** + * 允许缓存的最大数量 + */ + maxCount:number; + + /** + * 获取缓存的对象列表 + * @return + */ + getCacheList():any[]; + + /** + * 尝试清理缓存 + * @param force 是否强制清理 + */ + tryDispose(force:boolean):void; + + /** + * 添加对象缓存管理 + * @param sign 对象在Pool中的标识 + * @param maxCount 允许缓存的最大数量 + */ + static addPoolCacheManager(sign:string,maxCount?:number):void; + } + + /** + * @private + */ + class RunDriver { + static createShaderCondition:Function; + + /** + * 用于改变 WebGL宽高信息。 + */ + static changeWebGLSize:Function; + } + + /** + * @private 场景辅助类 + */ + class SceneUtils { + + /** + * @private + */ + private static _funMap:any; + + /** + * @private + */ + private static _parseWatchData:any; + + /** + * @private + */ + private static _parseKeyWord:any; + static __init():void; + + /** + * @private 根据字符串,返回函数表达式 + */ + static getBindFun(value:string):Function; + + /** + * @private 通过视图数据创建视图。 + * @param uiView 视图数据信息。 + */ + static createByData(root:any,uiView:any):any; + static createInitTool():InitTool; + + /** + * 根据UI数据实例化组件。 + * @param uiView UI数据。 + * @param comp 组件本体,如果为空,会新创建一个。 + * @param view 组件所在的视图实例,用来注册var全局变量,如果值为空则不注册。 + * @return 一个 Component 对象。 + */ + static createComp(uiView:any,comp?:any,view?:any,dataMap?:any[],initTool?:InitTool):any; + + /** + * @private 设置组件的属性值。 + * @param comp 组件实例。 + * @param prop 属性名称。 + * @param value 属性值。 + * @param view 组件所在的视图实例,用来注册var全局变量,如果值为空则不注册。 + */ + private static setCompValue:any; + + /** + * @private 通过组建UI数据,获取组件实例。 + * @param json UI数据。 + * @return Component 对象。 + */ + static getCompInstance(json:any):any; + } + + /** + * @private 场景辅助类 + */ + class InitTool { + + /** + * @private + */ + private _nodeRefList:any; + + /** + * @private + */ + private _initList:any; + private _loadList:any; + reset():void; + recover():void; + static create():InitTool; + addLoadRes(url:string,type?:string):void; + + /** + * @private + */ + addNodeRef(node:any,prop:string,referStr:string):void; + + /** + * @private + */ + setNodeRef():void; + + /** + * @private + */ + getReferData(referStr:string):any; + + /** + * @private + */ + addInitItem(item:any):void; + + /** + * @private + */ + doInits():void; + + /** + * @private + */ + finish():void; + + /** + * @private + */ + beginLoad(scene:Scene):void; + } + + /** + *

    Stat 是一个性能统计面板,可以实时更新相关的性能参数。

    + *

    参与统计的性能参数如下(所有参数都是每大约1秒进行更新):
    + * FPS(WebGL):WebGL 模式下的帧频,也就是每秒显示的帧数,值越高、越稳定,感觉越流畅;
    + * Sprite:统计所有渲染节点(包括容器)数量,它的大小会影响引擎进行节点遍历、数据组织和渲染的效率。其值越小,游戏运行效率越高;
    + * DrawCall:此值是决定性能的重要指标,其值越小,游戏运行效率越高。Canvas模式下表示每大约1秒的图像绘制次数;WebGL模式下表示每大约1秒的渲染提交批次,每次准备数据并通知GPU渲染绘制的过程称为1次DrawCall,在每次DrawCall中除了在通知GPU的渲染上比较耗时之外,切换材质与shader也是非常耗时的操作;
    + * CurMem:Canvas模式下,表示内存占用大小,值越小越好,过高会导致游戏闪退;WebGL模式下,表示内存与显存的占用,值越小越好;
    + * Shader:是 WebGL 模式独有的性能指标,表示每大约1秒 Shader 提交次数,值越小越好;
    + * Canvas:由三个数值组成,只有设置 CacheAs 后才会有值,默认为0/0/0。从左到右数值的意义分别为:每帧重绘的画布数量 / 缓存类型为"normal"类型的画布数量 / 缓存类型为"bitmap"类型的画布数量。

    + */ + class Stat { + + /** + * 每秒帧数。 + */ + static FPS:number; + + /** + * 主舞台 Stage 渲染次数计数。 + */ + static loopCount:number; + + /** + * 着色器请求次数。 + */ + static shaderCall:number; + + /** + * 渲染批次。 + */ + static renderBatches:number; + + /** + * 节省的渲染批次。 + */ + static savedRenderBatches:number; + + /** + * 三角形面数。 + */ + static trianglesFaces:number; + + /** + * 精灵Sprite 的数量。 + */ + static spriteCount:number; + + /** + * 精灵渲染使用缓存Sprite 的数量。 + */ + static spriteRenderUseCacheCount:number; + + /** + * 视锥剔除次数。 + */ + static frustumCulling:number; + + /** + * 八叉树节点剔除次数。 + */ + static octreeNodeCulling:number; + + /** + * 画布 canvas 使用标准渲染的次数。 + */ + static canvasNormal:number; + + /** + * 画布 canvas 使用位图渲染的次数。 + */ + static canvasBitmap:number; + + /** + * 画布 canvas 缓冲区重绘次数。 + */ + static canvasReCache:number; + + /** + * 表示当前使用的是否为慢渲染模式。 + */ + static renderSlow:boolean; + + /** + * 资源管理器所管理资源的累计内存,以字节为单位。 + */ + static gpuMemory:number; + static cpuMemory:number; + + /** + * 显示性能统计信息。 + * @param x X轴显示位置。 + * @param y Y轴显示位置。 + */ + static show(x?:number,y?:number):void; + + /** + * 激活性能统计 + */ + static enable():void; + + /** + * 隐藏性能统计信息。 + */ + static hide():void; + + /** + * @private 清零性能统计计算相关的数据。 + */ + static clear():void; + + /** + * 点击性能统计显示区域的处理函数。 + */ + static set onclick(fn:Function); + } + + /** + * 显示Stat的结果。由于stat会引入很多的循环引用,所以把显示部分拆开 + * @author laya + */ + class StatUI extends IStatRender { + private static _fontSize:any; + private _txt:any; + private _leftText:any; + private _canvas:any; + private _ctx:any; + private _first:any; + private _vx:any; + private _width:any; + private _height:any; + private _view:any; + + /** + * @override 显示性能统计信息。 + * @param x X轴显示位置。 + * @param y Y轴显示位置。 + */ + show(x?:number,y?:number):void; + private createUIPre:any; + private createUI:any; + + /** + * @override 激活性能统计 + */ + enable():void; + + /** + * @override 隐藏性能统计信息。 + */ + hide():void; + + /** + * @override 点击性能统计显示区域的处理函数。 + */ + set_onclick(fn:(this:GlobalEventHandlers,ev:MouseEvent) =>any):void; + + /** + * @private 性能统计参数计算循环处理函数。 + */ + loop():void; + private renderInfoPre:any; + private renderInfo:any; + + /** + * @override + */ + isCanvasRender():boolean; + + /** + * @override 非canvas模式的渲染 + */ + renderNotCanvas(ctx:any,x:number,y:number):void; + } + + /** + * @private StringKey 类用于存取字符串对应的数字。 + */ + class StringKey { + private _strsToID:any; + private _idToStrs:any; + private _length:any; + + /** + * 添加一个字符。 + * @param str 字符,将作为key 存储相应生成的数字。 + * @return 此字符对应的数字。 + */ + add(str:string):number; + + /** + * 获取指定字符对应的ID。 + * @param str 字符。 + * @return 此字符对应的ID。 + */ + getID(str:string):number; + + /** + * 根据指定ID获取对应字符。 + * @param id ID。 + * @return 此id对应的字符。 + */ + getName(id:number):string; + } + + /** + * 整个缓动结束的时候会调度 + * @eventType Event.COMPLETE + */ + + /** + * 当缓动到达标签时会调度。 + * @eventType Event.LABEL + */ + + /** + * TimeLine 是一个用来创建时间轴动画的类。 + */ + class TimeLine extends EventDispatcher { + private _labelDic:any; + private _tweenDic:any; + private _tweenDataList:any; + private _endTweenDataList:any; + private _currTime:any; + private _lastTime:any; + private _startTime:any; + + /** + * 当前动画数据播放到第几个了 + */ + private _index:any; + + /** + * 为TWEEN创建属于自己的唯一标识,方便管理 + */ + private _gidIndex:any; + + /** + * 保留所有对象第一次注册动画时的状态(根据时间跳转时,需要把对象的恢复,再计算接下来的状态) + */ + private _firstTweenDic:any; + + /** + * 是否需要排序 + */ + private _startTimeSort:any; + private _endTimeSort:any; + + /** + * 是否循环 + */ + private _loopKey:any; + + /** + * 缩放动画播放的速度。 + */ + scale:number; + private _frameRate:any; + private _frameIndex:any; + private _total:any; + + /** + * 控制一个对象,从当前点移动到目标点。 + * @param target 要控制的对象。 + * @param props 要控制对象的属性。 + * @param duration 对象TWEEN的时间。 + * @param ease 缓动类型 + * @param offset 相对于上一个对象,偏移多长时间(单位:毫秒)。 + */ + static to(target:any,props:any,duration:number,ease?:Function,offset?:number):TimeLine; + + /** + * 从 props 属性,缓动到当前状态。 + * @param target target 目标对象(即将更改属性值的对象) + * @param props 要控制对象的属性 + * @param duration 对象TWEEN的时间 + * @param ease 缓动类型 + * @param offset 相对于上一个对象,偏移多长时间(单位:毫秒) + */ + static from(target:any,props:any,duration:number,ease?:Function,offset?:number):TimeLine; + + /** + * 控制一个对象,从当前点移动到目标点。 + * @param target 要控制的对象。 + * @param props 要控制对象的属性。 + * @param duration 对象TWEEN的时间。 + * @param ease 缓动类型 + * @param offset 相对于上一个对象,偏移多长时间(单位:毫秒)。 + */ + to(target:any,props:any,duration:number,ease?:Function,offset?:number):TimeLine; + + /** + * 从 props 属性,缓动到当前状态。 + * @param target target 目标对象(即将更改属性值的对象) + * @param props 要控制对象的属性 + * @param duration 对象TWEEN的时间 + * @param ease 缓动类型 + * @param offset 相对于上一个对象,偏移多长时间(单位:毫秒) + */ + from(target:any,props:any,duration:number,ease?:Function,offset?:number):TimeLine; + + /** + * @private + */ + private _create:any; + + /** + * 在时间队列中加入一个标签。 + * @param label 标签名称。 + * @param offset 标签相对于上个动画的偏移时间(单位:毫秒)。 + */ + addLabel(label:string,offset:number):TimeLine; + + /** + * 移除指定的标签 + * @param label + */ + removeLabel(label:string):void; + + /** + * 动画从整个动画的某一时间开始。 + * @param time (单位:毫秒)。 + */ + gotoTime(time:number):void; + + /** + * 从指定的标签开始播。 + * @param Label 标签名。 + */ + gotoLabel(Label:string):void; + + /** + * 暂停整个动画。 + */ + pause():void; + + /** + * 恢复暂停动画的播放。 + */ + resume():void; + + /** + * 播放动画。 + * @param timeOrLabel 开启播放的时间点或标签名。 + * @param loop 是否循环播放。 + */ + play(timeOrLabel?:any,loop?:boolean):void; + + /** + * 更新当前动画。 + */ + private _update:any; + + /** + * 指定的动画索引处的动画播放完成后,把此动画从列表中删除。 + * @param index + */ + private _animComplete:any; + + /** + * @private + */ + private _complete:any; + + /** + * @private 得到帧索引 + */ + get index():number; + + /** + * @private 设置帧索引 + */ + set index(value:number); + + /** + * 得到总帧数。 + */ + get total():number; + + /** + * 重置所有对象,复用对象的时候使用。 + */ + reset():void; + + /** + * 彻底销毁此对象。 + */ + destroy():void; + } + + /** + * Timer 是时钟管理类。它是一个单例,不要手动实例化此类,应该通过 Laya.timer 访问。 + */ + class Timer { + + /** + * @private + */ + static gSysTimer:Timer; + + /** + * @private + */ + private static _pool:any; + + /** + * @private + */ + static _mid:number; + + /** + * 时针缩放。 + */ + scale:number; + + /** + * 当前帧开始的时间。 + */ + currTimer:number; + + /** + * 当前的帧数。 + */ + currFrame:number; + + /** + * @private + */ + private _map:any; + + /** + * @private + */ + private _handlers:any; + + /** + * @private + */ + private _temp:any; + + /** + * @private + */ + private _count:any; + + /** + * 创建 Timer 类的一个实例。 + */ + + constructor(autoActive?:boolean); + + /** + * 两帧之间的时间间隔,单位毫秒。 + */ + get delta():number; + + /** + * @private + */ + private _clearHandlers:any; + + /** + * @private + */ + private _recoverHandler:any; + + /** + * @private + */ + private _indexHandler:any; + + /** + * 定时执行一次。 + * @param delay 延迟时间(单位为毫秒)。 + * @param caller 执行域(this)。 + * @param method 定时器回调函数。 + * @param args 回调参数。 + * @param coverBefore 是否覆盖之前的延迟执行,默认为 true 。 + */ + once(delay:number,caller:any,method:Function,args?:any[],coverBefore?:boolean):void; + + /** + * 定时重复执行。 + * @param delay 间隔时间(单位毫秒)。 + * @param caller 执行域(this)。 + * @param method 定时器回调函数。 + * @param args 回调参数。 + * @param coverBefore 是否覆盖之前的延迟执行,默认为 true 。 + * @param jumpFrame 时钟是否跳帧。基于时间的循环回调,单位时间间隔内,如能执行多次回调,出于性能考虑,引擎默认只执行一次,设置jumpFrame=true后,则回调会连续执行多次 + */ + loop(delay:number,caller:any,method:Function,args?:any[],coverBefore?:boolean,jumpFrame?:boolean):void; + + /** + * 定时执行一次(基于帧率)。 + * @param delay 延迟几帧(单位为帧)。 + * @param caller 执行域(this)。 + * @param method 定时器回调函数。 + * @param args 回调参数。 + * @param coverBefore 是否覆盖之前的延迟执行,默认为 true 。 + */ + frameOnce(delay:number,caller:any,method:Function,args?:any[],coverBefore?:boolean):void; + + /** + * 定时重复执行(基于帧率)。 + * @param delay 间隔几帧(单位为帧)。 + * @param caller 执行域(this)。 + * @param method 定时器回调函数。 + * @param args 回调参数。 + * @param coverBefore 是否覆盖之前的延迟执行,默认为 true 。 + */ + frameLoop(delay:number,caller:any,method:Function,args?:any[],coverBefore?:boolean):void; + + /** + * 返回统计信息。 + */ + toString():string; + + /** + * 清理定时器。 + * @param caller 执行域(this)。 + * @param method 定时器回调函数。 + */ + clear(caller:any,method:Function):void; + + /** + * 清理对象身上的所有定时器。 + * @param caller 执行域(this)。 + */ + clearAll(caller:any):void; + + /** + * @private + */ + private _getHandler:any; + + /** + * 延迟执行。 + * @param caller 执行域(this)。 + * @param method 定时器回调函数。 + * @param args 回调参数。 + */ + callLater(caller:any,method:Function,args?:any[]):void; + + /** + * 立即执行 callLater 。 + * @param caller 执行域(this)。 + * @param method 定时器回调函数。 + */ + runCallLater(caller:any,method:Function):void; + + /** + * 立即提前执行定时器,执行之后从队列中删除 + * @param caller 执行域(this)。 + * @param method 定时器回调函数。 + */ + runTimer(caller:any,method:Function):void; + + /** + * 暂停时钟 + */ + pause():void; + + /** + * 恢复时钟 + */ + resume():void; + } + + /** + * Tween 是一个缓动类。使用此类能够实现对目标对象属性的渐变。 + */ + class Tween { + + /** + * @private + */ + private static tweenMap:any; + + /** + * @private + */ + private _complete:any; + + /** + * @private + */ + private _target:any; + + /** + * @private + */ + private _ease:any; + + /** + * @private + */ + private _props:any; + + /** + * @private + */ + private _duration:any; + + /** + * @private + */ + private _delay:any; + + /** + * @private + */ + private _startTimer:any; + + /** + * @private + */ + private _usedTimer:any; + + /** + * @private + */ + private _usedPool:any; + + /** + * @private + */ + private _delayParam:any; + + /** + * @private 唯一标识,TimeLintLite用到 + */ + gid:number; + + /** + * 更新回调,缓动数值发生变化时,回调变化的值 + */ + update:Handler; + + /** + * 重播次数,如果repeat=0,则表示无限循环播放 + */ + repeat:number; + + /** + * 当前播放次数 + */ + private _count:any; + + /** + * 缓动对象的props属性到目标值。 + * @param target 目标对象(即将更改属性值的对象)。 + * @param props 变化的属性列表,比如{x:100,y:20,ease:Ease.backOut,complete:Handler.create(this,onComplete),update:new Handler(this,onComplete)}。 + * @param duration 花费的时间,单位毫秒。 + * @param ease 缓动类型,默认为匀速运动。 + * @param complete 结束回调函数。 + * @param delay 延迟执行时间。 + * @param coverBefore 是否覆盖之前的缓动。 + * @param autoRecover 是否自动回收,默认为true,缓动结束之后自动回收到对象池。 + * @return 返回Tween对象。 + */ + static to(target:any,props:any,duration:number,ease?:Function|null,complete?:Handler|null,delay?:number,coverBefore?:boolean,autoRecover?:boolean):Tween; + + /** + * 从props属性,缓动到当前状态。 + * @param target 目标对象(即将更改属性值的对象)。 + * @param props 变化的属性列表,比如{x:100,y:20,ease:Ease.backOut,complete:Handler.create(this,onComplete),update:new Handler(this,onComplete)}。 + * @param duration 花费的时间,单位毫秒。 + * @param ease 缓动类型,默认为匀速运动。 + * @param complete 结束回调函数。 + * @param delay 延迟执行时间。 + * @param coverBefore 是否覆盖之前的缓动。 + * @param autoRecover 是否自动回收,默认为true,缓动结束之后自动回收到对象池。 + * @return 返回Tween对象。 + */ + static from(target:any,props:any,duration:number,ease?:Function,complete?:Handler,delay?:number,coverBefore?:boolean,autoRecover?:boolean):Tween; + + /** + * 缓动对象的props属性到目标值。 + * @param target 目标对象(即将更改属性值的对象)。 + * @param props 变化的属性列表,比如{x:100,y:20,ease:Ease.backOut,complete:Handler.create(this,onComplete),update:new Handler(this,onComplete)}。 + * @param duration 花费的时间,单位毫秒。 + * @param ease 缓动类型,默认为匀速运动。 + * @param complete 结束回调函数。 + * @param delay 延迟执行时间。 + * @param coverBefore 是否覆盖之前的缓动。 + * @return 返回Tween对象。 + */ + to(target:any,props:any,duration:number,ease?:Function,complete?:Handler,delay?:number,coverBefore?:boolean):Tween; + + /** + * 从props属性,缓动到当前状态。 + * @param target 目标对象(即将更改属性值的对象)。 + * @param props 变化的属性列表,比如{x:100,y:20,ease:Ease.backOut,complete:Handler.create(this,onComplete),update:new Handler(this,onComplete)}。 + * @param duration 花费的时间,单位毫秒。 + * @param ease 缓动类型,默认为匀速运动。 + * @param complete 结束回调函数。 + * @param delay 延迟执行时间。 + * @param coverBefore 是否覆盖之前的缓动。 + * @return 返回Tween对象。 + */ + from(target:any,props:any,duration:number,ease?:Function|null,complete?:Handler|null,delay?:number,coverBefore?:boolean):Tween; + private firstStart:any; + private _initProps:any; + private _beginLoop:any; + + /** + * 执行缓动* + */ + private _doEase:any; + + /** + * 设置当前执行比例* + */ + set progress(v:number); + + /** + * 立即结束缓动并到终点。 + */ + complete():void; + + /** + * 暂停缓动,可以通过resume或restart重新开始。 + */ + pause():void; + + /** + * 设置开始时间。 + * @param startTime 开始时间。 + */ + setStartTime(startTime:number):void; + + /** + * 清理指定目标对象上的所有缓动。 + * @param target 目标对象。 + */ + static clearAll(target:any):void; + + /** + * 清理某个缓动。 + * @param tween 缓动对象。 + */ + static clear(tween:Tween):void; + + /** + * @private 同clearAll,废弃掉,尽量别用。 + */ + static clearTween(target:any):void; + + /** + * 停止并清理当前缓动。 + */ + clear():void; + + /** + * 回收到对象池。 + */ + recover():void; + private _remove:any; + + /** + * 重新开始暂停的缓动。 + */ + restart():void; + + /** + * 恢复暂停的缓动。 + */ + resume():void; + private static easeNone:any; + } + + /** + * Utils 是工具类。 + */ + class Utils { + + /** + * @private + */ + static gStage:Stage; + + /** + * @private + */ + private static _gid:any; + + /** + * @private + */ + private static _pi:any; + + /** + * @private + */ + private static _pi2:any; + + /** + * @private + */ + protected static _extReg:RegExp; + + /** + * 角度转弧度。 + * @param angle 角度值。 + * @return 返回弧度值。 + */ + static toRadian(angle:number):number; + + /** + * 弧度转换为角度。 + * @param radian 弧度值。 + * @return 返回角度值。 + */ + static toAngle(radian:number):number; + + /** + * 将传入的 uint 类型颜色值转换为字符串型颜色值。 + * @param color 颜色值。 + * @return 字符串型颜色值。 + */ + static toHexColor(color:number):string; + + /** + * 获取一个全局唯一ID。 + */ + static getGID():number; + + /** + * 将字符串解析成 XML 对象。 + * @param value 需要解析的字符串。 + * @return js原生的XML对象。 + */ + static parseXMLFromString:Function; + + /** + * @private

    连接数组。和array的concat相比,此方法不创建新对象

    注意:若 参数 a 不为空,则会改变参数 source 的值为连接后的数组。 + * @param source 待连接的数组目标对象。 + * @param array 待连接的数组对象。 + * @return 连接后的数组。 + */ + static concatArray(source:any[],array:any[]):any[]; + + /** + * @private 清空数组对象。 + * @param array 数组。 + * @return 清空后的 array 对象。 + */ + static clearArray(array:any[]):any[]; + + /** + * @private 清空source数组,复制array数组的值。 + * @param source 需要赋值的数组。 + * @param array 新的数组值。 + * @return 复制后的数据 source 。 + */ + static copyArray(source:any[],array:any[]):any[]; + + /** + * @private 根据传入的显示对象 Sprite 和此显示对象上的 两个点,返回此对象上的两个点在舞台坐标系上组成的最小的矩形区域对象。 + * @param sprite 显示对象 Sprite。 + * @param x0 点一的 X 轴坐标点。 + * @param y0 点一的 Y 轴坐标点。 + * @param x1 点二的 X 轴坐标点。 + * @param y1 点二的 Y 轴坐标点。 + * @return 两个点在舞台坐标系组成的矩形对象 Rectangle。 + */ + static getGlobalRecByPoints(sprite:Sprite,x0:number,y0:number,x1:number,y1:number):Rectangle; + + /** + * 计算传入的显示对象 Sprite 的全局坐标系的坐标和缩放值,返回 Rectangle 对象存放计算出的坐标X值、Y值、ScaleX值、ScaleY值。 + * @param sprite Sprite 对象。 + * @return 矩形对象 Rectangle + */ + static getGlobalPosAndScale(sprite:Sprite):Rectangle; + + /** + * 给传入的函数绑定作用域,返回绑定后的函数。 + * @param fun 函数对象。 + * @param scope 函数作用域。 + * @return 绑定后的函数。 + */ + static bind(fun:Function,scope:any):Function; + + /** + * @private 对传入的数组列表,根据子项的属性 Z 值进行重新排序。返回是否已重新排序的 Boolean 值。 + * @param array 子对象数组。 + * @return Boolean 值,表示是否已重新排序。 + */ + static updateOrder(array:any[]):boolean; + + /** + * @private 批量移动点坐标。 + * @param points 坐标列表。 + * @param x x轴偏移量。 + * @param y y轴偏移量。 + */ + static transPointList(points:any[],x:number,y:number):void; + + /** + * 解析一个字符串,并返回一个整数。和JS原生的parseInt不同:如果str为空或者非数字,原生返回NaN,这里返回0。 + * @param str 要被解析的字符串。 + * @param radix 表示要解析的数字的基数。默认值为0,表示10进制,其他值介于 2 ~ 36 之间。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。如果该参数不在上述范围内,则此方法返回 0。 + * @return 返回解析后的数字。 + */ + static parseInt(str:string,radix?:number):number; + + /** + * @private + */ + static getFileExtension(path:string):string; + + /** + * @private 为兼容平台后缀名不能用的特殊兼容TODO: + */ + static getFilecompatibleExtension(path:string):string; + + /** + * 获取指定区域内相对于窗口左上角的transform。 + * @param coordinateSpace 坐标空间,不能是Stage引用 + * @param x 相对于coordinateSpace的x坐标 + * @param y 相对于coordinateSpace的y坐标 + * @return + */ + static getTransformRelativeToWindow(coordinateSpace:Sprite,x:number,y:number):any; + + /** + * 使DOM元素使用舞台内的某块区域内。 + * @param dom DOM元素引用 + * @param coordinateSpace 坐标空间,不能是Stage引用 + * @param x 相对于coordinateSpace的x坐标 + * @param y 相对于coordinateSpace的y坐标 + * @param width 宽度 + * @param height 高度 + */ + static fitDOMElementInArea(dom:any,coordinateSpace:Sprite,x:number,y:number,width:number,height:number):void; + + /** + * @private 是否是可用的Texture数组 + * @param textureList + * @return + */ + static isOkTextureList(textureList:any[]):boolean; + + /** + * @private 是否是可用的绘图指令数组 + * @param cmds + * @return + */ + static isOKCmdList(cmds:any[]):boolean; + + /** + * 获得URL参数值 + * @param name 参数名称 + * @return 参数值 + */ + static getQueryString(name:string):string; + } + + /** + * @private TODO: + */ + class VectorGraphManager { + static instance:VectorGraphManager; + useDic:any; + shapeDic:any; + shapeLineDic:any; + private _id:any; + private _checkKey:any; + private _freeIdArray:any; + + constructor(); + static getInstance():VectorGraphManager; + + /** + * 得到个空闲的ID + * @return + */ + getId():number; + + /** + * 添加一个图形到列表中 + * @param id + * @param shape + */ + addShape(id:number,shape:any):void; + + /** + * 添加一个线图形到列表中 + * @param id + * @param Line + */ + addLine(id:number,Line:any):void; + + /** + * 检测一个对象是否在使用中 + * @param id + */ + getShape(id:number):void; + + /** + * 删除一个图形对象 + * @param id + */ + deleteShape(id:number):void; + + /** + * 得到缓存列表 + * @return + */ + getCacheList():any[]; + + /** + * 开始清理状态,准备销毁 + */ + startDispose(key:boolean):void; + + /** + * 确认销毁 + */ + endDispose():void; + } + + /** + * 封装弱引用WeakMap + * 如果支持WeakMap,则使用WeakMap,如果不支持,则用Object代替 + * 注意:如果采用Object,为了防止内存泄漏,则采用定时清理缓存策略 + * + * 这里的设计是错误的,为了兼容,先不删掉这个类,直接采用Object + */ + class WeakObject { + + /** + * 是否支持WeakMap + */ + static supportWeakMap:boolean; + + /** + * 如果不支持WeakMap,则多少时间清理一次缓存,默认10分钟清理一次 + */ + static delInterval:number; + + /** + * 全局WeakObject单例 + */ + static I:WeakObject; + + /** + * @private + */ + private static _maps:any; + + /** + * 清理缓存,回收内存 + */ + static clearCache():void; + + constructor(); + + /** + * 设置缓存 + * @param key kye对象,可被回收 + * @param value object对象,可被回收 + */ + set(key:any,value:any):void; + + /** + * 获取缓存 + * @param key kye对象,可被回收 + */ + get(key:any):any; + + /** + * 删除缓存 + */ + del(key:any):void; + + /** + * 是否有缓存 + */ + has(key:any):boolean; + } + + /** + * @private + */ + class WordText { + id:number; + save:any[]; + toUpperCase:string; + changed:boolean; + width:number; + pageChars:any[]; + startID:number; + startIDStroke:number; + lastGCCnt:number; + splitRender:boolean; + scalex:number; + scaley:number; + setText(txt:string):void; + toString():string; + get length():number; + charCodeAt(i:number):number; + charAt(i:number):string; + + /** + * 自己主动清理缓存,需要把关联的贴图删掉 + * 不做也可以,textrender会自动清理不用的 + * TODO 重用 + */ + cleanCache():void; + } + + /** + * ... + * @author ... + */ + class BufferState2D extends BufferStateBase { + + constructor(); + } + + /** + * ... + * @author ... + */ + class BufferStateBase { + + /** + * @private [只读] + */ + private _nativeVertexArrayObject:any; + + constructor(); + + /** + * @private + */ + bind():void; + + /** + * @private + */ + unBind():void; + + /** + * @private + */ + destroy():void; + + /** + * @private + */ + bindForNative():void; + + /** + * @private + */ + unBindForNative():void; + } + class BlendMode { + static activeBlendFunction:Function; + static NORMAL:string; + static MASK:string; + static LIGHTER:string; + static fns:any[]; + static targetFns:any[]; + static BlendNormal(gl:WebGLRenderingContext):void; + static BlendAdd(gl:WebGLRenderingContext):void; + static BlendMultiply(gl:WebGLRenderingContext):void; + static BlendScreen(gl:WebGLRenderingContext):void; + static BlendOverlay(gl:WebGLRenderingContext):void; + static BlendLight(gl:WebGLRenderingContext):void; + static BlendNormalTarget(gl:WebGLRenderingContext):void; + static BlendAddTarget(gl:WebGLRenderingContext):void; + static BlendMultiplyTarget(gl:WebGLRenderingContext):void; + static BlendScreenTarget(gl:WebGLRenderingContext):void; + static BlendOverlayTarget(gl:WebGLRenderingContext):void; + static BlendLightTarget(gl:WebGLRenderingContext):void; + static BlendMask(gl:WebGLRenderingContext):void; + static BlendDestinationOut(gl:WebGLRenderingContext):void; + } + class DrawStyle { + static DEFAULT:DrawStyle; + _color:ColorUtils; + static create(value:any):DrawStyle; + + constructor(value:any); + setValue(value:any):void; + reset():void; + toInt():number; + equal(value:any):boolean; + toColorStr():string; + } + class Path { + paths:any[]; + private _curPath:any; + + constructor(); + beginPath(convex:boolean):void; + closePath():void; + newPath():void; + addPoint(pointX:number,pointY:number):void; + push(points:any[],convex:boolean):void; + reset():void; + } + + interface ISaveData{ + isSaveMark():boolean; + restore(context:Context):void; + } + + class SaveBase implements ISaveData { + static TYPE_ALPHA:number; + static TYPE_FILESTYLE:number; + static TYPE_FONT:number; + static TYPE_LINEWIDTH:number; + static TYPE_STROKESTYLE:number; + static TYPE_MARK:number; + static TYPE_TRANSFORM:number; + static TYPE_TRANSLATE:number; + static TYPE_ENABLEMERGE:number; + static TYPE_TEXTBASELINE:number; + static TYPE_TEXTALIGN:number; + static TYPE_GLOBALCOMPOSITEOPERATION:number; + static TYPE_CLIPRECT:number; + static TYPE_CLIPRECT_STENCIL:number; + static TYPE_IBVB:number; + static TYPE_SHADER:number; + static TYPE_FILTERS:number; + static TYPE_FILTERS_TYPE:number; + static TYPE_COLORFILTER:number; + private static POOL:any; + private static _namemap:any; + private _valueName:any; + private _value:any; + private _dataObj:any; + private _newSubmit:any; + + constructor(); + isSaveMark():boolean; + restore(context:Context):void; + static save(context:Context,type:number,dataObj:any,newSubmit:boolean):void; + } + class SaveClipRect implements ISaveData { + private static POOL:any; + private _globalClipMatrix:any; + private _clipInfoID:any; + incache:boolean; + isSaveMark():boolean; + restore(context:Context):void; + static save(context:Context):void; + } + class SaveMark implements ISaveData { + private static POOL:any; + + constructor(); + isSaveMark():boolean; + restore(context:Context):void; + static Create(context:Context):SaveMark; + } + class SaveTransform implements ISaveData { + private static POOL:any; + + constructor(); + isSaveMark():boolean; + restore(context:Context):void; + static save(context:Context):void; + } + class SaveTranslate implements ISaveData { + private static POOL:any; + isSaveMark():boolean; + restore(context:Context):void; + static save(context:Context):void; + } + + /** + * 对象 cacheas normal的时候,本质上只是想把submit缓存起来,以后直接执行 + * 为了避免各种各样的麻烦,这里采用复制相应部分的submit的方法。执行环境还是在原来的context中 + * 否则包括clip等都非常难以处理 + */ + class WebGLCacheAsNormalCanvas { + submitStartPos:number; + submitEndPos:number; + context:Context; + touches:any[]; + submits:any[]; + sprite:Sprite|null; + private _pathMesh:any; + private _triangleMesh:any; + meshlist:any[]; + private _oldMesh:any; + private _oldPathMesh:any; + private _oldTriMesh:any; + private _oldMeshList:any; + private cachedClipInfo:any; + private oldTx:any; + private oldTy:any; + private static matI:any; + invMat:Matrix; + + constructor(ctx:Context,sp:Sprite); + startRec():void; + endRec():void; + + /** + * 当前缓存是否还有效。例如clip变了就失效了,因为clip太难自动处理 + * @return + */ + isCacheValid():boolean; + flushsubmit():void; + releaseMem():void; + } + + /** + * ... + * @author ... + */ + class BaseShader extends Resource { + static activeShader:BaseShader|null; + static bindShader:BaseShader; + + constructor(); + } + class Shader2D { + ALPHA:number; + shader:Shader; + filters:any[]; + defines:ShaderDefines2D; + shaderType:number; + colorAdd:any[]; + fillStyle:DrawStyle; + strokeStyle:DrawStyle; + destroy():void; + static __init__():void; + } + class Shader2X extends Shader { + _params2dQuick2:any[]|null; + _shaderValueWidth:number; + _shaderValueHeight:number; + + constructor(vs:string,ps:string,saveName?:any,nameMap?:any,bindAttrib?:any[]|null); + + /** + * @override + */ + protected _disposeResource():void; + upload2dQuick2(shaderValue:ShaderValue):void; + _make2dQuick2():any[]; + static create(vs:string,ps:string,saveName?:any,nameMap?:any,bindAttrib?:any[]|null):Shader; + } + class ShaderDefines2D extends ShaderDefinesBase { + static TEXTURE2D:number; + static PRIMITIVE:number; + static FILTERGLOW:number; + static FILTERBLUR:number; + static FILTERCOLOR:number; + static COLORADD:number; + static WORLDMAT:number; + static FILLTEXTURE:number; + static SKINMESH:number; + static MVP3D:number; + static NOOPTMASK:number; + private static __name2int:any; + private static __int2name:any; + private static __int2nameMap:any; + static __init__():void; + + constructor(); + static reg(name:string,value:number):void; + static toText(value:number,int2name:any[],int2nameMap:any):any; + static toInt(names:string):number; + } + class SkinMeshBuffer { + ib:IndexBuffer2D; + vb:VertexBuffer2D; + static instance:SkinMeshBuffer; + + constructor(); + static getInstance():SkinMeshBuffer; + addSkinMesh(skinMesh:any):void; + reset():void; + } + class SkinSV extends Value2D { + texcoord:any; + position:any; + offsetX:number; + offsetY:number; + + constructor(type:any); + } + class PrimitiveSV extends Value2D { + + constructor(args:any); + } + class TextureSV extends Value2D { + u_colorMatrix:any[]; + strength:number; + blurInfo:any[]; + colorMat:Float32Array; + colorAlpha:Float32Array; + + constructor(subID?:number); + + /** + * @override + */ + clear():void; + } + class Value2D { + protected static _cache:any[]; + protected static _typeClass:any; + static TEMPMAT4_ARRAY:any[]; + static _initone(type:number,classT:any):void; + static __init__():void; + defines:ShaderDefines2D; + size:any[]; + alpha:number; + mmat:any[]; + u_MvpMatrix:any[]; + texture:any; + ALPHA:number; + shader:Shader; + mainID:number; + subID:number; + filters:any[]; + textureHost:Texture; + color:any[]; + colorAdd:any[]; + u_mmat2:any[]; + ref:number; + protected _attribLocation:any[]; + private _inClassCache:any; + private _cacheID:any; + clipMatDir:any[]; + clipMatPos:any[]; + clipOff:any[]; + + constructor(mainID:number,subID:number); + setValue(value:Shader2D):void; + private _ShaderWithCompile:any; + upload():void; + setFilters(value:any[]):void; + clear():void; + release():void; + static create(mainType:number,subType:number):Value2D; + } + class Shader extends BaseShader { + private static _count:any; + private _attribInfo:any; + static SHADERNAME2ID:number; + static nameKey:StringKey; + static sharders:any[]; + static getShader(name:any):Shader; + static create(vs:string,ps:string,saveName?:any,nameMap?:any,bindAttrib?:any[]):Shader; + + /** + * 根据宏动态生成shader文件,支持#include?COLOR_FILTER "parts/ColorFilter_ps_logic.glsl";条件嵌入文件 + * @param name + * @param vs + * @param ps + * @param define 宏定义,格式:{name:value...} + * @return + */ + static withCompile(nameID:number,define:any,shaderName:any,createShader:Function):Shader; + + /** + * 根据宏动态生成shader文件,支持#include?COLOR_FILTER "parts/ColorFilter_ps_logic.glsl";条件嵌入文件 + * @param name + * @param vs + * @param ps + * @param define 宏定义,格式:{name:value...} + * @return + */ + static withCompile2D(nameID:number,mainID:number,define:any,shaderName:any,createShader:Function,bindAttrib?:any[]):Shader; + static addInclude(fileName:string,txt:string):void; + + /** + * 预编译shader文件,主要是处理宏定义 + * @param nameID ,一般是特殊宏+shaderNameID*0.0002组成的一个浮点数当做唯一标识 + * @param vs + * @param ps + */ + static preCompile(nameID:number,vs:string,ps:string,nameMap:any):void; + + /** + * 预编译shader文件,主要是处理宏定义 + * @param nameID ,一般是特殊宏+shaderNameID*0.0002组成的一个浮点数当做唯一标识 + * @param vs + * @param ps + */ + static preCompile2D(nameID:number,mainID:number,vs:string,ps:string,nameMap:any):void; + private customCompile:any; + private _nameMap:any; + private _vs:any; + private _ps:any; + private _curActTexIndex:any; + private _reCompile:any; + tag:any; + + /** + * 根据vs和ps信息生成shader对象 + * 把自己存储在 sharders 数组中 + * @param vs + * @param ps + * @param name : + * @param nameMap 帮助里要详细解释为什么需要nameMap + */ + + constructor(vs:string,ps:string,saveName?:any,nameMap?:any,bindAttrib?:any[]|null); + protected recreateResource():void; + + /** + * @override + */ + protected _disposeResource():void; + private _compile:any; + private static _createShader:any; + + /** + * 根据变量名字获得 + * @param name + * @return + */ + getUniform(name:string):any; + private _uniform1f:any; + private _uniform1fv:any; + private _uniform_vec2:any; + private _uniform_vec2v:any; + private _uniform_vec3:any; + private _uniform_vec3v:any; + private _uniform_vec4:any; + private _uniform_vec4v:any; + private _uniformMatrix2fv:any; + private _uniformMatrix3fv:any; + private _uniformMatrix4fv:any; + private _uniform1i:any; + private _uniform1iv:any; + private _uniform_ivec2:any; + private _uniform_ivec2v:any; + private _uniform_vec3i:any; + private _uniform_vec3vi:any; + private _uniform_vec4i:any; + private _uniform_vec4vi:any; + private _uniform_sampler2D:any; + private _uniform_samplerCube:any; + private _noSetValue:any; + uploadOne(name:string,value:any):void; + uploadTexture2D(value:any):void; + + /** + * 提交shader到GPU + * @param shaderValue + */ + upload(shaderValue:ShaderValue,params?:any[]):void; + + /** + * 按数组的定义提交 + * @param shaderValue 数组格式[name,value,...] + */ + uploadArray(shaderValue:any[],length:number,_bufferUsage:any):void; + + /** + * 得到编译后的变量及相关预定义 + * @return + */ + getParams():any[]; + + /** + * 设置shader里面的attribute绑定到哪个location,必须与mesh2d的对应起来, + * 这个必须在编译之前设置。 + * @param attribDesc 属性描述,格式是 [attributeName, location, attributeName, location ... ] + */ + setAttributesLocation(attribDesc:any[]):void; + } + class ShaderDefinesBase { + private _name2int:any; + private _int2name:any; + private _int2nameMap:any; + + constructor(name2int:any,int2name:any[],int2nameMap:any[]); + add(value:any):number; + addInt(value:number):number; + remove(value:any):number; + isDefine(def:number):boolean; + getValue():number; + setValue(value:number):void; + toNameDic():any; + static _reg(name:string,value:number,_name2int:any,_int2name:any[]):void; + static _toText(value:number,_int2name:any[],_int2nameMap:any):any; + static _toInt(names:string,_name2int:any):number; + } + class ShaderValue { + + constructor(); + } + class BasePoly { + private static tempData:any; + + /** + * 构造线的三角形数据。根据一个位置数组生成vb和ib + * @param p + * @param indices + * @param lineWidth + * @param indexBase 顶点开始的值,ib中的索引会加上这个 + * @param outVertex + * @return + */ + static createLine2(p:any[],indices:any[],lineWidth:number,indexBase:number,outVertex:any[],loop:boolean):any[]; + + /** + * 相邻的两段线,边界会相交,这些交点可以作为三角形的顶点。有两种可选,一种是采用左左,右右交点,一种是采用 左右,左右交点。当两段线夹角很小的时候,如果采用 + * 左左,右右会产生很长很长的交点,这时候就要采用左右左右交点,相当于把尖角截断。 + * 当采用左左右右交点的时候,直接用切线的垂线。采用左右左右的时候,用切线 + * 切线直接采用两个方向的平均值。不能用3-1的方式,那样垂线和下一段可能都在同一方向(例如都在右方) + * 注意把重合的点去掉 + * @param path + * @param color + * @param width + * @param loop + * @param outvb + * @param vbstride 顶点占用几个float,(bytelength/4) + * @param outib test: 横线 [100,100, 400,100] 竖线 [100,100, 100,400] 直角 [100,100, 400,100, 400,400] 重合点 [100,100,100,100,400,100] 同一直线上的点 [100,100,100,200,100,3000] 像老式电视的左边不封闭的图形 [98,176, 163,178, 95,66, 175,177, 198,178, 252,56, 209,178, 248,175, 248,266, 209,266, 227,277, 203,280, 188,271, 150,271, 140,283, 122,283, 131,268, 99,268] + */ + static createLineTriangle(path:any[],color:number,width:number,loop:boolean,outvb:Float32Array,vbstride:number,outib:Uint16Array):void; + } + class Earcut { + static earcut(data:any,holeIndices:any,dim:any):any; + static linkedList(data:any,start:any,end:any,dim:any,clockwise:any):any; + static filterPoints(start:any,end:any):any; + static earcutLinked(ear:any,triangles:any,dim:any,minX:any,minY:any,invSize:any,pass?:any):any; + static isEar(ear:any):any; + static isEarHashed(ear:any,minX:any,minY:any,invSize:any):boolean; + static cureLocalIntersections(start:any,triangles:any,dim:any):any; + static splitEarcut(start:any,triangles:any,dim:any,minX:any,minY:any,invSize:any):void; + static eliminateHoles(data:any,holeIndices:any,outerNode:any,dim:any):any; + static compareX(a:any,b:any):any; + static eliminateHole(hole:any,outerNode:any):void; + static findHoleBridge(hole:any,outerNode:any):any; + static indexCurve(start:any,minX:any,minY:any,invSize:any):void; + static sortLinked(list:any):any; + static zOrder(x:any,y:any,minX:any,minY:any,invSize:any):any; + static getLeftmost(start:any):any; + static pointInTriangle(ax:any,ay:any,bx:any,by:any,cx:any,cy:any,px:any,py:any):boolean; + static isValidDiagonal(a:any,b:any):boolean; + static area(p:any,q:any,r:any):any; + static equals(p1:any,p2:any):boolean; + static intersects(p1:any,q1:any,p2:any,q2:any):boolean; + static intersectsPolygon(a:any,b:any):boolean; + static locallyInside(a:any,b:any):boolean; + static middleInside(a:any,b:any):boolean; + static splitPolygon(a:any,b:any):any; + static insertNode(i:any,x:any,y:any,last:any):any; + static removeNode(p:any):void; + static signedArea(data:any,start:any,end:any,dim:any):any; + } + class EarcutNode { + i:any; + x:any; + y:any; + prev:any; + next:any; + z:any; + prevZ:any; + nextZ:any; + steiner:any; + + constructor(i:any,x:any,y:any); + } + + interface ISubmit{ + renderSubmit():number; + getRenderType():number; + releaseRender():void; + } + + class Submit extends SubmitBase { + protected static _poolSize:number; + protected static POOL:Submit[]; + + constructor(renderType?:number); + + /** + * @override + */ + renderSubmit():number; + + /** + * @override + */ + releaseRender():void; + + /** + * create方法只传对submit设置的值 + */ + static create(context:Context,mesh:Mesh2D,sv:Value2D):Submit; + + /** + * 创建一个矢量submit + * @param ctx + * @param mesh + * @param numEle 对应drawElement的第二个参数:count + * @param offset drawElement的时候的ib的偏移。 + * @param sv Value2D + * @return + */ + static createShape(ctx:Context,mesh:Mesh2D,numEle:number,sv:Value2D):Submit; + } + class SubmitBase implements ISubmit { + static TYPE_2D:number; + static TYPE_CANVAS:number; + static TYPE_CMDSETRT:number; + static TYPE_CUSTOM:number; + static TYPE_BLURRT:number; + static TYPE_CMDDESTORYPRERT:number; + static TYPE_DISABLESTENCIL:number; + static TYPE_OTHERIBVB:number; + static TYPE_PRIMITIVE:number; + static TYPE_RT:number; + static TYPE_BLUR_RT:number; + static TYPE_TARGET:number; + static TYPE_CHANGE_VALUE:number; + static TYPE_SHAPE:number; + static TYPE_TEXTURE:number; + static TYPE_FILLTEXTURE:number; + static KEY_ONCE:number; + static KEY_FILLRECT:number; + static KEY_DRAWTEXTURE:number; + static KEY_VG:number; + static KEY_TRIANGLES:number; + static RENDERBASE:SubmitBase; + static ID:number; + static preRender:ISubmit; + clipInfoID:number; + protected _id:number; + shaderValue:Value2D; + static __init__():void; + + constructor(renderType?:number); + getID():number; + getRenderType():number; + toString():string; + renderSubmit():number; + releaseRender():void; + } + + /** + * cache as normal 模式下的生成的canvas的渲染。 + */ + class SubmitCanvas extends SubmitBase { + canv:Context; + static POOL:SubmitCanvas[]; + static create(canvas:any,alpha:number,filters:any[]):SubmitCanvas; + + constructor(); + + /** + * @override + */ + renderSubmit():number; + + /** + * @override + */ + releaseRender():void; + + /** + * @override + */ + getRenderType():number; + } + class SubmitCMD implements ISubmit { + static POOL:SubmitCMD[]; + fun:Function; + args:any[]; + + constructor(); + renderSubmit():number; + getRenderType():number; + releaseRender():void; + static create(args:any[],fun:Function,thisobj:any):SubmitCMD; + } + + /** + * ... + * @author xie + */ + class SubmitKey { + blendShader:number; + submitType:number; + other:number; + + constructor(); + clear():void; + copyFrom(src:SubmitKey):void; + copyFrom2(src:SubmitKey,submitType:number,other:number):void; + equal3_2(next:SubmitKey,submitType:number,other:number):boolean; + equal4_2(next:SubmitKey,submitType:number,other:number):boolean; + equal_3(next:SubmitKey):boolean; + equal(next:SubmitKey):boolean; + } + class SubmitTarget implements ISubmit { + shaderValue:Value2D; + blendType:number; + srcRT:RenderTexture2D; + + constructor(); + static POOL:SubmitTarget[]; + renderSubmit():number; + blend():void; + getRenderType():number; + releaseRender():void; + static create(context:Context,mesh:Mesh2D,sv:Value2D,rt:RenderTexture2D):SubmitTarget; + } + class SubmitTexture extends SubmitBase { + private static _poolSize:any; + private static POOL:any; + + constructor(renderType?:number); + + /** + * @override + */ + releaseRender():void; + renderSubmit():number; + static create(context:Context,mesh:Mesh2D,sv:Value2D):SubmitTexture; + } + + /** + * 系统工具。 + */ + class SystemUtils { + + /** + * 图形设备支持的最大纹理数量。 + */ + static get maxTextureCount():number; + + /** + * 图形设备支持的最大纹理尺寸。 + */ + static get maxTextureSize():number; + + /** + * 图形设备着色器的大致能力等级,类似于DirectX的shader model概念。 + */ + static get shaderCapailityLevel():number; + + /** + * 是否支持纹理格式。 + * @param format 纹理格式。 + * @returns 是否支持。 + */ + static supportTextureFormat(format:number):boolean; + + /** + * 是否支持渲染纹理格式。 + * @param format 渲染纹理格式。 + * @returns 是否支持。 + */ + static supportRenderTextureFormat(format:number):boolean; + } + + /** + * 阿拉伯文的转码。把unicode的阿拉伯文字母编码转成他们的老的能描述不同写法的编码。 + * 这个是从GitHub上 Javascript-Arabic-Reshaper 项目转来的 + * https://github.com/louy/Javascript-Arabic-Reshaper/blob/master/src/index.js + */ + + /** + * Javascript Arabic Reshaper by Louy Alakkad + * https://github.com/louy/Javascript-Arabic-Reshaper + * Based on (http://git.io/vsnAd) + */ + class ArabicReshaper { + private static charsMap:any; + private static combCharsMap:any; + private static transChars:any; + characterMapContains(c:number):boolean; + getCharRep(c:number):boolean; + getCombCharRep(c1:number,c2:number):boolean; + isTransparent(c:number):boolean; + getOriginalCharsFromCode(code:number):string; + + /** + * 转换函数。从normal转到presentB + * 这个返回的字符串可以直接按照从左到右的顺序渲染。 + * 例如 + * graphics.fillText(convertArabic('سلام'),....) + */ + convertArabic(normal:any):string; + convertArabicBack(apfb:any):string; + } + class AtlasGrid { + atlasID:number; + private _width:any; + private _height:any; + private _texCount:any; + private _rowInfo:any; + private _cells:any; + _used:number; + + constructor(width?:number,height?:number,id?:number); + addRect(type:number,width:number,height:number,pt:Point):boolean; + private _release:any; + private _init:any; + private _get:any; + private _fill:any; + private _check:any; + private _clear:any; + } + + /** + * TODO如果占用内存较大,这个结构有很多成员可以临时计算 + */ + class CharRenderInfo { + char:string; + tex:any; + deleted:boolean; + uv:any[]; + pos:number; + width:number; + height:number; + bmpWidth:number; + bmpHeight:number; + orix:number; + oriy:number; + touchTick:number; + isSpace:boolean; + touch():void; + } + class CharRender_Canvas extends ICharRender { + private static canvas:any; + private ctx:any; + private lastScaleX:any; + private lastScaleY:any; + private maxTexW:any; + private maxTexH:any; + private scaleFontSize:any; + private showDbgInfo:any; + private supportImageData:any; + + constructor(maxw:number,maxh:number,scalefont?:boolean,useImageData?:boolean,showdbg?:boolean); + + /** + * @override + */ + get canvasWidth():number; + + /** + * @override + */ + set canvasWidth(w:number); + + /** + * @param font + * @param str + * @override + */ + getWidth(font:string,str:string):number; + + /** + * @param sx + * @param sy + * @override + */ + scale(sx:number,sy:number):void; + + /** + * TODO stroke + * @param char + * @param font + * @param cri 修改里面的width。 + * @return + * @override + */ + getCharBmp(char:string,font:string,lineWidth:number,colStr:string,strokeColStr:string,cri:CharRenderInfo,margin_left:number,margin_top:number,margin_right:number,margin_bottom:number,rect?:any[]|null):ImageData|null; + getCharCanvas(char:string,font:string,lineWidth:number,colStr:string,strokeColStr:string,cri:CharRenderInfo,margin_left:number,margin_top:number,margin_right:number,margin_bottom:number):ImageData; + } + class CharRender_Native extends ICharRender { + private lastFont:any; + private lastScaleX:any; + private lastScaleY:any; + + constructor(); + + /** + * @param font + * @param str + * @override + */ + getWidth(font:string,str:string):number; + + /** + * @param sx + * @param sy + * @override + */ + scale(sx:number,sy:number):void; + + /** + * TODO stroke + * @param char + * @param font + * @param size 返回宽高 + * @return + * @override + */ + getCharBmp(char:string,font:string,lineWidth:number,colStr:string,strokeColStr:string,size:CharRenderInfo,margin_left:number,margin_top:number,margin_right:number,margin_bottom:number,rect?:any[]|null):ImageData|null; + } + + /** + * ... + * @author laoxie + */ + class CharSubmitCache { + private static __posPool:any; + private static __nPosPool:any; + private _data:any; + private _ndata:any; + private _tex:any; + private _imgId:any; + private _clipid:any; + private _clipMatrix:any; + + constructor(); + clear():void; + destroy():void; + add(ctx:Context,tex:Texture,imgid:number,pos:any[],uv:ArrayLike,color:number):void; + getPos():any[]; + enable(value:boolean,ctx:Context):void; + submit(ctx:Context):void; + } + class ICharRender { + fontsz:number; + getWidth(font:string,str:string):number; + scale(sx:number,sy:number):void; + get canvasWidth():number; + set canvasWidth(w:number); + + /** + * TODO stroke + * @param char + * @param font + * @param size 返回宽高 + * @return + */ + getCharBmp(char:string,font:string,lineWidth:number,colStr:string,strokeColStr:string,size:CharRenderInfo,margin_left:number,margin_top:number,margin_right:number,margin_bottom:number,rect?:any[]|null):ImageData|null; + } + + /** + * 文字贴图的大图集。 + */ + class TextAtlas { + texWidth:number; + texHeight:number; + private atlasgrid:any; + texture:TextTexture|null; + charMaps:any; + static atlasGridW:number; + + constructor(); + setProtecteDist(d:number):void; + + /** + * 如果返回null,则表示无法加入了 + * 分配的时候优先选择最接近自己高度的节点 + * @param w + * @param h + * @return + */ + getAEmpty(w:number,h:number,pt:Point):boolean; + + /** + * 大图集格子单元的占用率,老的也算上了。只是表示这个大图集还能插入多少东西。 + */ + get usedRate():number; + destroy():void; + printDebugInfo():void; + } + class TextRender { + static useOldCharBook:boolean; + static atlasWidth:number; + static noAtlas:boolean; + static forceSplitRender:boolean; + static forceWholeRender:boolean; + static scaleFontWithCtx:boolean; + static standardFontSize:number; + static destroyAtlasDt:number; + static checkCleanTextureDt:number; + static destroyUnusedTextureDt:number; + static cleanMem:number; + static isWan1Wan:boolean; + static showLog:boolean; + static debugUV:boolean; + + /** + * fontSizeInfo + * 记录每种字体的像素的大小。标准是32px的字体。由4个byte组成,分别表示[xdist,ydist,w,h]。 + * xdist,ydist 是像素起点到排版原点的距离,都是正的,表示实际数据往左和上偏多少,如果实际往右和下偏,则算作0,毕竟这个只是一个大概 + * 例如 [Arial]=0x00002020, 表示宽高都是32 + */ + private fontSizeInfo:any; + static atlasWidth2:number; + private charRender:any; + private static tmpRI:any; + private static pixelBBX:any; + private mapFont:any; + private fontID:any; + private fontScaleX:any; + private fontScaleY:any; + private _curStrPos:any; + static textRenderInst:TextRender; + textAtlases:TextAtlas[]; + private isoTextures:any; + private bmpData32:any; + private static imgdtRect:any; + private lastFont:any; + private fontSizeW:any; + private fontSizeH:any; + private fontSizeOffX:any; + private fontSizeOffY:any; + private renderPerChar:any; + private tmpAtlasPos:any; + private textureMem:any; + private fontStr:any; + static simClean:boolean; + + constructor(); + + /** + * 设置当前字体,获得字体的大小信息。 + * @param font + */ + setFont(font:FontInfo):void; + + /** + * 从string中取出一个完整的char,例如emoji的话要多个 + * 会修改 _curStrPos + * TODO 由于各种文字中的组合写法,这个需要能扩展,以便支持泰文等 + * @param str + * @param start 开始位置 + */ + getNextChar(str:string):string|null; + filltext(ctx:Context,data:string|WordText,x:number,y:number,fontStr:string,color:string,strokeColor:string,lineWidth:number,textAlign:string,underLine?:number):void; + fillWords(ctx:Context,data:HTMLChar[],x:number,y:number,fontStr:string|FontInfo,color:string,strokeColor:string|null,lineWidth:number):void; + _fast_filltext(ctx:Context,data:string|WordText|null,htmlchars:HTMLChar[]|null,x:number,y:number,font:FontInfo,color:string,strokeColor:string|null,lineWidth:number,textAlign:number,underLine?:number):void; + + /** + * 画出重新按照贴图顺序分组的文字。 + * @param samePagesData + * @param startx 保存的数据是相对位置,所以需要加上这个偏移。用相对位置更灵活一些。 + * @param y 因为这个只能画在一行上所以没有必要保存y。所以这里再把y传进来 + */ + protected _drawResortedWords(ctx:Context,startx:number,starty:number,samePagesData:any[]):void; + + /** + * 检查 txts数组中有没有被释放的资源 + * @param txts + * @param startid + * @return + */ + hasFreedText(txts:any[]):boolean; + getCharRenderInfo(str:string,font:FontInfo,color:string,strokeColor:string|null,lineWidth:number,isoTexture?:boolean):CharRenderInfo; + + /** + * 添加数据到大图集 + * @param w + * @param h + * @return + */ + addBmpData(data:ImageData,ri:CharRenderInfo):TextAtlas; + + /** + * 清理利用率低的大图集 + */ + GC():void; + + /** + * 尝试清理大图集 + */ + cleanAtlases():void; + getCharBmp(c:string):any; + + /** + * 检查当前线是否存在数据 + * @param data + * @param l + * @param sx + * @param ex + * @return + */ + private checkBmpLine:any; + + /** + * 根据bmp数据和当前的包围盒,更新包围盒 + * 由于选择的文字是连续的,所以可以用二分法 + * @param data + * @param curbbx [l,t,r,b] + * @param onlyH 不检查左右 + */ + private updateBbx:any; + getFontSizeInfo(font:string):number; + printDbgInfo():void; + showAtlas(n:number,bgcolor:string,x:number,y:number,w:number,h:number):Sprite; + filltext_native(ctx:Context,data:string|WordText,htmlchars:HTMLChar[],x:number,y:number,fontStr:string,color:string,strokeColor:string,lineWidth:number,textAlign:string,underLine?:number):void; + } + class TextTexture extends Resource { + static gTextRender:ITextRender; + private static pool:any; + private static poolLen:any; + private static cleanTm:any; + genID:number; + bitmap:any; + curUsedCovRate:number; + curUsedCovRateAtlas:number; + lastTouchTm:number; + ri:CharRenderInfo; + + constructor(textureW:number,textureH:number); + recreateResource():void; + + /** + * @param data + * @param x 拷贝位置。 + * @param y + * @param uv + * @return uv数组 如果uv不为空就返回传入的uv,否则new一个数组 + */ + addChar(data:ImageData,x:number,y:number,uv?:any[]):any[]; + + /** + * 玩一玩不支持 getImageData + * @param canv + * @param x + * @param y + */ + addCharCanvas(canv:any,x:number,y:number,uv?:any[]):any[]; + + /** + * 填充白色。调试用。 + */ + fillWhite():void; + discard():void; + static getTextTexture(w:number,h:number):TextTexture; + + /** + * @override + */ + destroy():void; + + /** + * 定期清理 + * 为了简单,只有发生 getAPage 或者 discardPage的时候才检测是否需要清理 + */ + static clean():void; + touchRect(ri:CharRenderInfo,curloop:number):void; + get texture():any; + drawOnScreen(x:number,y:number):void; + } + + interface ITextRender{ + atlasWidth:number; + checkCleanTextureDt:number; + debugUV:boolean; + isWan1Wan:boolean; + destroyUnusedTextureDt:number; + } + + class Buffer { + static _bindedVertexBuffer:any; + static _bindedIndexBuffer:any; + protected _glBuffer:any; + protected _buffer:any; + protected _bufferType:number; + protected _bufferUsage:number; + _byteLength:number; + get bufferUsage():number; + + constructor(); + + /** + * @private 绕过全局状态判断,例如VAO局部状态设置 + */ + _bindForVAO():void; + + /** + * @private + */ + bind():boolean; + + /** + * @private + */ + destroy():void; + } + class Buffer2D extends Buffer { + static FLOAT32:number; + static SHORT:number; + static __int__(gl:WebGLContext):void; + protected _maxsize:number; + _upload:boolean; + protected _uploadSize:number; + protected _bufferSize:number; + protected _u8Array:Uint8Array; + get bufferLength():number; + set byteLength(value:number); + setByteLength(value:number):void; + + /** + * 在当前的基础上需要多大空间,单位是byte + * @param sz + * @return 增加大小之前的写位置。单位是byte + */ + needSize(sz:number):number; + + constructor(); + protected _bufferData():void; + protected _bufferSubData(offset?:number,dataStart?:number,dataLength?:number):void; + + /** + * buffer重新分配了,继承类根据需要做相应的处理。 + */ + protected _checkArrayUse():void; + + /** + * 给vao使用的 _bind_upload函数。不要与已经绑定的判断是否相同 + * @return + */ + _bind_uploadForVAO():boolean; + _bind_upload():boolean; + _bind_subUpload(offset?:number,dataStart?:number,dataLength?:number):boolean; + + /** + * 重新分配buffer大小,如果nsz比原来的小则什么都不做。 + * @param nsz buffer大小,单位是byte。 + * @param copy 是否拷贝原来的buffer的数据。 + * @return + */ + _resizeBuffer(nsz:number,copy:boolean):Buffer2D; + append(data:any):void; + + /** + * 附加Uint16Array的数据。数据长度是len。byte的话要*2 + * @param data + * @param len + */ + appendU16Array(data:Uint16Array,len:number):void; + appendEx(data:any,type:new (buf: any, len: any) => any):void; + appendEx2(data:any,type:new (buff: any, len: any) => any,dataLen:number,perDataLen?:number):void; + getBuffer():ArrayBuffer; + setNeedUpload():void; + getNeedUpload():boolean; + upload():boolean; + subUpload(offset?:number,dataStart?:number,dataLength?:number):boolean; + protected _disposeResource():void; + + /** + * 清理数据。保留ArrayBuffer + */ + clear():void; + } + class CONST3D2D { + static BYTES_PE:number; + static BYTES_PIDX:number; + static defaultMatrix4:any[]; + static defaultMinusYMatrix4:any[]; + static uniformMatrix3:any[]; + static _TMPARRAY:any[]; + static _OFFSETX:number; + static _OFFSETY:number; + } + class IndexBuffer2D extends Buffer2D { + static create:Function; + protected _uint16Array:Uint16Array; + + constructor(bufferUsage?:number); + + /** + * @override + */ + protected _checkArrayUse():void; + getUint16Array():Uint16Array; + + /** + * @inheritDoc + * @override + */ + _bindForVAO():void; + + /** + * @inheritDoc + * @override + */ + bind():boolean; + destory():void; + disposeResource():void; + } + class InlcudeFile { + script:string; + codes:any; + funs:any; + curUseID:number; + funnames:string; + + constructor(txt:string); + getWith(name?:string|null):string; + getFunsScript(funsdef:string):string; + } + class MatirxArray { + + /** + * 4*4矩阵数组相乘。 + * o=a*b; + * @param a 4*4矩阵数组。 + * @param b 4*4矩阵数组。 + * @param o 4*4矩阵数组。 + */ + static ArrayMul(a:any[],b:any[],o:any[]):void; + static copyArray(f:any[],t:any[]):void; + } + + /** + * Mesh2d只是保存数据。描述attribute用的。本身不具有渲染功能。 + */ + class Mesh2D { + _stride:number; + vertNum:number; + indexNum:number; + protected _applied:boolean; + _vb:VertexBuffer2D; + _ib:IndexBuffer2D; + private _vao:any; + private static _gvaoid:any; + private _attribInfo:any; + protected _quadNum:number; + canReuse:boolean; + + /** + * @param stride + * @param vballoc vb预分配的大小。主要是用来提高效率。防止不断的resizebfufer + * @param iballoc + */ + + constructor(stride:number,vballoc:number,iballoc:number); + + /** + * 重新创建一个mesh。复用这个对象的vertex结构,ib对象和attribinfo对象 + */ + cloneWithNewVB():Mesh2D; + + /** + * 创建一个mesh,使用当前对象的vertex结构。vb和ib自己提供。 + * @return + */ + cloneWithNewVBIB():Mesh2D; + + /** + * 获得一个可以写的vb对象 + */ + getVBW():VertexBuffer2D; + + /** + * 获得一个只读vb + */ + getVBR():VertexBuffer2D; + getIBR():IndexBuffer2D; + + /** + * 获得一个可写的ib + */ + getIBW():IndexBuffer2D; + + /** + * 直接创建一个固定的ib。按照固定四边形的索引。 + * @param var QuadNum + */ + createQuadIB(QuadNum:number):void; + + /** + * 设置mesh的属性。每3个一组,对应的location分别是0,1,2... + * 含义是:type,size,offset + * 不允许多流。因此stride是固定的,offset只是在一个vertex之内。 + * @param attribs + */ + setAttributes(attribs:any[]):void; + + /** + * 初始化VAO的配置,只需要执行一次。以后使用的时候直接bind就行 + * @param gl + */ + private configVAO:any; + + /** + * 应用这个mesh + * @param gl + */ + useMesh(gl:WebGLRenderingContext):void; + getEleNum():number; + + /** + * 子类实现。用来把自己放到对应的回收池中,以便复用。 + */ + releaseMesh():void; + + /** + * 释放资源。 + */ + destroy():void; + + /** + * 清理vb数据 + */ + clearVB():void; + } + + /** + * drawImage,fillRect等会用到的简单的mesh。每次添加必然是一个四边形。 + */ + class MeshParticle2D extends Mesh2D { + static const_stride:number; + private static _fixattriInfo:any; + private static _POOL:any; + static __init__():void; + + constructor(maxNum:number); + setMaxParticleNum(maxNum:number):void; + + /** + */ + static getAMesh(maxNum:number):MeshParticle2D; + + /** + * 把本对象放到回收池中,以便getMesh能用。 + * @override + */ + releaseMesh():void; + + /** + * @override + */ + destroy():void; + } + + /** + * drawImage,fillRect等会用到的简单的mesh。每次添加必然是一个四边形。 + */ + class MeshQuadTexture extends Mesh2D { + static const_stride:number; + private static _fixib:any; + private static _maxIB:any; + private static _fixattriInfo:any; + private static _POOL:any; + static __int__():void; + + constructor(); + + /** + */ + static getAMesh(mainctx:boolean):MeshQuadTexture; + + /** + * 把本对象放到回收池中,以便getMesh能用。 + * @override + */ + releaseMesh():void; + + /** + * @override + */ + destroy():void; + + /** + * @param pos + * @param uv + * @param color + * @param clip ox,oy,xx,xy,yx,yy + * @param useTex 是否使用贴图。false的话是给fillRect用的 + */ + addQuad(pos:any[],uv:ArrayLike,color:number,useTex:boolean):void; + } + + /** + * 与MeshQuadTexture基本相同。不过index不是固定的 + */ + class MeshTexture extends Mesh2D { + static const_stride:number; + private static _fixattriInfo:any; + private static _POOL:any; + static __init__():void; + + constructor(); + + /** + */ + static getAMesh(mainctx:boolean):MeshTexture; + addData(vertices:Float32Array,uvs:Float32Array,idx:Uint16Array,matrix:Matrix,rgba:number):void; + + /** + * 把本对象放到回收池中,以便getMesh能用。 + * @override + */ + releaseMesh():void; + + /** + * @override + */ + destroy():void; + } + + /** + * 用来画矢量的mesh。顶点格式固定为 x,y,rgba + */ + class MeshVG extends Mesh2D { + static const_stride:number; + private static _fixattriInfo:any; + private static _POOL:any; + static __init__():void; + + constructor(); + static getAMesh(mainctx:boolean):MeshVG; + + /** + * 往矢量mesh中添加顶点和index。会把rgba和points在mesh中合并。 + * @param points 顶点数组,只包含x,y。[x,y,x,y...] + * @param rgba rgba颜色 + * @param ib index数组。 + */ + addVertAndIBToMesh(ctx:Context,points:any[],rgba:number,ib:any[]):void; + + /** + * 把本对象放到回收池中,以便getMesh能用。 + * @override + */ + releaseMesh():void; + + /** + * @override + */ + destroy():void; + } + class RenderState2D { + static _MAXSIZE:number; + + /** + * @private 一个初始化的 Matrix 对象,不允许修改此对象内容。 + */ + static EMPTYMAT4_ARRAY:number[]; + static TEMPMAT4_ARRAY:number[]; + static worldMatrix4:number[]; + static worldMatrix:Matrix; + static matWVP:any; + static worldAlpha:number; + static worldScissorTest:boolean; + static worldShaderDefines:ShaderDefines2D; + static worldFilters:any[]; + static width:number; + static height:number; + static mat2MatArray(mat:Matrix,matArray:any[]):any[]; + static restoreTempArray():void; + static clear():void; + } + + /** + * @private ShaderCompile 类用于实现Shader编译。 + */ + class ShaderCompile { + static IFDEF_NO:number; + static IFDEF_YES:number; + static IFDEF_ELSE:number; + static IFDEF_PARENT:number; + static _removeAnnotation:RegExp; + static _reg:RegExp; + static _splitToWordExps:RegExp; + static includes:any; + static shaderParamsMap:any; + private _nameMap:any; + private static _parseOne:any; + static addInclude(fileName:string,txt:string):void; + static preGetParams(vs:string,ps:string):any; + static splitToWords(str:string,block:ShaderNode):any[]; + static _clearCR:RegExp; + defs:Object; + + constructor(vs:string,ps:string,nameMap:any); + static _splitToWordExps3:RegExp; + + /** + * @private + */ + protected _compileToTree(parent:ShaderNode,lines:any[],start:number,includefiles:any[],defs:any):void; + createShader(define:any,shaderName:any,createShader:Function,bindAttrib:any[]):Shader; + } + class ShaderNode { + private static __id:any; + childs:any[]; + text:string; + parent:ShaderNode; + name:string; + noCompile:boolean; + includefiles:any[]; + condition:any; + conditionType:number; + useFuns:string; + z:number; + src:string; + + constructor(includefiles:any[]); + setParent(parent:ShaderNode):void; + setCondition(condition:string,type:number):void; + toscript(def:any,out:any[]):any[]; + private _toscript:any; + } + class VertexBuffer2D extends Buffer2D { + static create:Function; + _floatArray32:Float32Array; + _uint32Array:Uint32Array; + private _vertexStride:any; + get vertexStride():number; + + constructor(vertexStride:number,bufferUsage:number); + getFloat32Array():Float32Array; + + /** + * 在当前位置插入float数组。 + * @param data + * @param pos + */ + appendArray(data:any[]):void; + + /** + * @override + */ + protected _checkArrayUse():void; + deleteBuffer():void; + + /** + * @inheritDoc + * @override + */ + _bindForVAO():void; + + /** + * @inheritDoc + * @override + */ + bind():boolean; + + /** + * @override + */ + destroy():void; + } + class VertexArrayObject { + + constructor(); + } + + /** + * @private + */ + class WebGL { + static _isWebGL2:boolean; + static isNativeRender_enable:boolean; + private static _uint8ArraySlice:any; + private static _float32ArraySlice:any; + private static _uint16ArraySlice:any; + static _nativeRender_enable():void; + static enable():boolean; + static inner_enable():boolean; + static onStageResize(width:number,height:number):void; + } + + /** + * @private + */ + class WebGLContext { + static getUniformMaxVector():number; + } + +} diff --git a/examples/layaair/frontend/libs/box2d.d.ts b/examples/layaair/frontend/libs/box2d.d.ts new file mode 100644 index 0000000..7b1b297 --- /dev/null +++ b/examples/layaair/frontend/libs/box2d.d.ts @@ -0,0 +1,2683 @@ +declare function b2Assert(condition: boolean, ...args: any[]): void /**asserts condition*/; +declare function b2Maybe(value: T | undefined, def: T): T; +declare const b2_maxFloat: number; +declare const b2_epsilon: number; +declare const b2_epsilon_sq: number; +declare const b2_pi: number; +declare const b2_lengthUnitsPerMeter: number; +declare const b2_maxPolygonVertices: number; +declare const b2_maxManifoldPoints: number; +declare const b2_aabbExtension: number; +declare const b2_aabbMultiplier: number; +declare const b2_linearSlop: number; +declare const b2_angularSlop: number; +declare const b2_polygonRadius: number; +declare const b2_maxSubSteps: number; +declare const b2_maxTOIContacts: number; +declare const b2_maxLinearCorrection: number; +declare const b2_maxAngularCorrection: number; +declare const b2_maxTranslation: number; +declare const b2_maxTranslationSquared: number; +declare const b2_maxRotation: number; +declare const b2_maxRotationSquared: number; +declare const b2_baumgarte: number; +declare const b2_toiBaumgarte: number; +declare const b2_timeToSleep: number; +declare const b2_linearSleepTolerance: number; +declare const b2_angularSleepTolerance: number; +declare class b2Version { + major: number; + minor: number; + revision: number; + constructor(major?: number, minor?: number, revision?: number); + toString(): string; +} +declare const b2_version: b2Version; +declare const b2_branch: string; +declare const b2_commit: string; +declare function b2ParseInt(v: string): number; +declare function b2ParseUInt(v: string): number; +declare function b2MakeArray(length: number, init: (i: number) => T): T[]; +declare function b2MakeNullArray(length: number): Array; +declare function b2MakeNumberArray(length: number, init?: number): number[]; + +declare function b2Alloc(size: number): any; +declare function b2Free(mem: any): void; +declare function b2Log(message: string, ...args: any[]): void; + +declare const b2_pi_over_180: number; +declare const b2_180_over_pi: number; +declare const b2_two_pi: number; +declare const b2Abs: (x: number) => number; +declare function b2Min(a: number, b: number): number; +declare function b2Max(a: number, b: number): number; +declare function b2Clamp(a: number, lo: number, hi: number): number; +declare function b2Swap(a: T[], b: T[]): void; +declare const b2IsValid: typeof isFinite; +declare function b2Sq(n: number): number; +declare function b2InvSqrt(n: number): number; +declare const b2Sqrt: (x: number) => number; +declare const b2Pow: (x: number, y: number) => number; +declare function b2DegToRad(degrees: number): number; +declare function b2RadToDeg(radians: number): number; +declare const b2Cos: (x: number) => number; +declare const b2Sin: (x: number) => number; +declare const b2Acos: (x: number) => number; +declare const b2Asin: (x: number) => number; +declare const b2Atan2: (y: number, x: number) => number; +declare function b2NextPowerOfTwo(x: number): number; +declare function b2IsPowerOfTwo(x: number): boolean; +declare function b2Random(): number; +declare function b2RandomRange(lo: number, hi: number): number; +interface XY { + x: number; + y: number; +} +declare class b2Vec2 implements XY { + x: number; + y: number; + static readonly ZERO: Readonly; + static readonly UNITX: Readonly; + static readonly UNITY: Readonly; + static readonly s_t0: b2Vec2; + static readonly s_t1: b2Vec2; + static readonly s_t2: b2Vec2; + static readonly s_t3: b2Vec2; + constructor(x?: number, y?: number); + Clone(): b2Vec2; + SetZero(): this; + Set(x: number, y: number): this; + Copy(other: XY): this; + SelfAdd(v: XY): this; + SelfAddXY(x: number, y: number): this; + SelfSub(v: XY): this; + SelfSubXY(x: number, y: number): this; + SelfMul(s: number): this; + SelfMulAdd(s: number, v: XY): this; + SelfMulSub(s: number, v: XY): this; + Dot(v: XY): number; + Cross(v: XY): number; + Length(): number; + LengthSquared(): number; + Normalize(): number; + SelfNormalize(): this; + SelfRotate(radians: number): this; + SelfRotateCosSin(c: number, s: number): this; + IsValid(): boolean; + SelfCrossVS(s: number): this; + SelfCrossSV(s: number): this; + SelfMinV(v: XY): this; + SelfMaxV(v: XY): this; + SelfAbs(): this; + SelfNeg(): this; + SelfSkew(): this; + static MakeArray(length: number): b2Vec2[]; + static AbsV(v: XY, out: T): T; + static MinV(a: XY, b: XY, out: T): T; + static MaxV(a: XY, b: XY, out: T): T; + static ClampV(v: XY, lo: XY, hi: XY, out: T): T; + static RotateV(v: XY, radians: number, out: T): T; + static DotVV(a: XY, b: XY): number; + static CrossVV(a: XY, b: XY): number; + static CrossVS(v: XY, s: number, out: T): T; + static CrossVOne(v: XY, out: T): T; + static CrossSV(s: number, v: XY, out: T): T; + static CrossOneV(v: XY, out: T): T; + static AddVV(a: XY, b: XY, out: T): T; + static SubVV(a: XY, b: XY, out: T): T; + static MulSV(s: number, v: XY, out: T): T; + static MulVS(v: XY, s: number, out: T): T; + static AddVMulSV(a: XY, s: number, b: XY, out: T): T; + static SubVMulSV(a: XY, s: number, b: XY, out: T): T; + static AddVCrossSV(a: XY, s: number, v: XY, out: T): T; + static MidVV(a: XY, b: XY, out: T): T; + static ExtVV(a: XY, b: XY, out: T): T; + static IsEqualToV(a: XY, b: XY): boolean; + static DistanceVV(a: XY, b: XY): number; + static DistanceSquaredVV(a: XY, b: XY): number; + static NegV(v: XY, out: T): T; +} +declare const b2Vec2_zero: Readonly; +declare class b2TypedVec2 implements b2Vec2 { + readonly data: Float32Array; + get x(): number; + set x(value: number); + get y(): number; + set y(value: number); + constructor(); + constructor(data: Float32Array); + constructor(x: number, y: number); + Clone(): b2TypedVec2; + SetZero(): this; + Set(x: number, y: number): this; + Copy(other: XY): this; + SelfAdd(v: XY): this; + SelfAddXY(x: number, y: number): this; + SelfSub(v: XY): this; + SelfSubXY(x: number, y: number): this; + SelfMul(s: number): this; + SelfMulAdd(s: number, v: XY): this; + SelfMulSub(s: number, v: XY): this; + Dot(v: XY): number; + Cross(v: XY): number; + Length(): number; + LengthSquared(): number; + Normalize(): number; + SelfNormalize(): this; + SelfRotate(radians: number): this; + SelfRotateCosSin(c: number, s: number): this; + IsValid(): boolean; + SelfCrossVS(s: number): this; + SelfCrossSV(s: number): this; + SelfMinV(v: XY): this; + SelfMaxV(v: XY): this; + SelfAbs(): this; + SelfNeg(): this; + SelfSkew(): this; +} +interface XYZ extends XY { + z: number; +} +declare class b2Vec3 implements XYZ { + static readonly ZERO: Readonly; + static readonly s_t0: b2Vec3; + readonly data: Float32Array; + get x(): number; + set x(value: number); + get y(): number; + set y(value: number); + get z(): number; + set z(value: number); + constructor(); + constructor(data: Float32Array); + constructor(x: number, y: number, z: number); + Clone(): b2Vec3; + SetZero(): this; + SetXYZ(x: number, y: number, z: number): this; + Copy(other: XYZ): this; + SelfNeg(): this; + SelfAdd(v: XYZ): this; + SelfAddXYZ(x: number, y: number, z: number): this; + SelfSub(v: XYZ): this; + SelfSubXYZ(x: number, y: number, z: number): this; + SelfMul(s: number): this; + static DotV3V3(a: XYZ, b: XYZ): number; + static CrossV3V3(a: XYZ, b: XYZ, out: T): T; +} +declare class b2Mat22 { + static readonly IDENTITY: Readonly; + readonly ex: b2Vec2; + readonly ey: b2Vec2; + Clone(): b2Mat22; + static FromVV(c1: XY, c2: XY): b2Mat22; + static FromSSSS(r1c1: number, r1c2: number, r2c1: number, r2c2: number): b2Mat22; + static FromAngle(radians: number): b2Mat22; + SetSSSS(r1c1: number, r1c2: number, r2c1: number, r2c2: number): this; + SetVV(c1: XY, c2: XY): this; + SetAngle(radians: number): this; + Copy(other: b2Mat22): this; + SetIdentity(): this; + SetZero(): this; + GetAngle(): number; + GetInverse(out: b2Mat22): b2Mat22; + Solve(b_x: number, b_y: number, out: T): T; + SelfAbs(): this; + SelfInv(): this; + SelfAddM(M: b2Mat22): this; + SelfSubM(M: b2Mat22): this; + static AbsM(M: b2Mat22, out: b2Mat22): b2Mat22; + static MulMV(M: b2Mat22, v: XY, out: T): T; + static MulTMV(M: b2Mat22, v: XY, out: T): T; + static AddMM(A: b2Mat22, B: b2Mat22, out: b2Mat22): b2Mat22; + static MulMM(A: b2Mat22, B: b2Mat22, out: b2Mat22): b2Mat22; + static MulTMM(A: b2Mat22, B: b2Mat22, out: b2Mat22): b2Mat22; +} +declare class b2Mat33 { + static readonly IDENTITY: Readonly; + readonly data: Float32Array; + readonly ex: b2Vec3; + readonly ey: b2Vec3; + readonly ez: b2Vec3; + Clone(): b2Mat33; + SetVVV(c1: XYZ, c2: XYZ, c3: XYZ): this; + Copy(other: b2Mat33): this; + SetIdentity(): this; + SetZero(): this; + SelfAddM(M: b2Mat33): this; + Solve33(b_x: number, b_y: number, b_z: number, out: T): T; + Solve22(b_x: number, b_y: number, out: T): T; + GetInverse22(M: b2Mat33): void; + GetSymInverse33(M: b2Mat33): void; + static MulM33V3(A: b2Mat33, v: XYZ, out: T): T; + static MulM33XYZ(A: b2Mat33, x: number, y: number, z: number, out: T): T; + static MulM33V2(A: b2Mat33, v: XY, out: T): T; + static MulM33XY(A: b2Mat33, x: number, y: number, out: T): T; +} +declare class b2Rot { + static readonly IDENTITY: Readonly; + s: number; + c: number; + constructor(angle?: number); + Clone(): b2Rot; + Copy(other: b2Rot): this; + SetAngle(angle: number): this; + SetIdentity(): this; + GetAngle(): number; + GetXAxis(out: T): T; + GetYAxis(out: T): T; + static MulRR(q: b2Rot, r: b2Rot, out: b2Rot): b2Rot; + static MulTRR(q: b2Rot, r: b2Rot, out: b2Rot): b2Rot; + static MulRV(q: b2Rot, v: XY, out: T): T; + static MulTRV(q: b2Rot, v: XY, out: T): T; +} +declare class b2Transform { + static readonly IDENTITY: Readonly; + readonly p: b2Vec2; + readonly q: b2Rot; + Clone(): b2Transform; + Copy(other: b2Transform): this; + SetIdentity(): this; + SetPositionRotation(position: XY, q: Readonly): this; + SetPositionAngle(pos: XY, a: number): this; + SetPosition(position: XY): this; + SetPositionXY(x: number, y: number): this; + SetRotation(rotation: Readonly): this; + SetRotationAngle(radians: number): this; + GetPosition(): Readonly; + GetRotation(): Readonly; + GetRotationAngle(): number; + GetAngle(): number; + static MulXV(T: b2Transform, v: XY, out: T): T; + static MulTXV(T: b2Transform, v: XY, out: T): T; + static MulXX(A: b2Transform, B: b2Transform, out: b2Transform): b2Transform; + static MulTXX(A: b2Transform, B: b2Transform, out: b2Transform): b2Transform; +} +declare class b2Sweep { + readonly localCenter: b2Vec2; + readonly c0: b2Vec2; + readonly c: b2Vec2; + a0: number; + a: number; + alpha0: number; + Clone(): b2Sweep; + Copy(other: b2Sweep): this; + GetTransform(xf: b2Transform, beta: number): b2Transform; + Advance(alpha: number): void; + Normalize(): void; +} + +interface RGB { + r: number; + g: number; + b: number; +} +interface RGBA extends RGB { + a: number; +} +declare class b2Color implements RGBA { + r: number; + g: number; + b: number; + a: number; + static readonly ZERO: Readonly; + static readonly RED: Readonly; + static readonly GREEN: Readonly; + static readonly BLUE: Readonly; + constructor(r?: number, g?: number, b?: number, a?: number); + Clone(): b2Color; + Copy(other: RGBA): this; + IsEqual(color: RGBA): boolean; + IsZero(): boolean; + Set(r: number, g: number, b: number, a?: number): void; + SetByteRGB(r: number, g: number, b: number): this; + SetByteRGBA(r: number, g: number, b: number, a: number): this; + SetRGB(rr: number, gg: number, bb: number): this; + SetRGBA(rr: number, gg: number, bb: number, aa: number): this; + SelfAdd(color: RGBA): this; + Add(color: RGBA, out: T): T; + SelfSub(color: RGBA): this; + Sub(color: RGBA, out: T): T; + SelfMul(s: number): this; + Mul(s: number, out: T): T; + Mix(mixColor: RGBA, strength: number): void; + static MixColors(colorA: RGBA, colorB: RGBA, strength: number): void; + MakeStyleString(alpha?: number): string; + static MakeStyleString(r: number, g: number, b: number, a?: number): string; +} +declare class b2TypedColor implements b2Color { + readonly data: Float32Array; + get r(): number; + set r(value: number); + get g(): number; + set g(value: number); + get b(): number; + set b(value: number); + get a(): number; + set a(value: number); + constructor(); + constructor(data: Float32Array); + constructor(rr: number, gg: number, bb: number); + constructor(rr: number, gg: number, bb: number, aa: number); + Clone(): b2TypedColor; + Copy(other: RGBA): this; + IsEqual(color: RGBA): boolean; + IsZero(): boolean; + Set(r: number, g: number, b: number, a?: number): void; + SetByteRGB(r: number, g: number, b: number): this; + SetByteRGBA(r: number, g: number, b: number, a: number): this; + SetRGB(rr: number, gg: number, bb: number): this; + SetRGBA(rr: number, gg: number, bb: number, aa: number): this; + SelfAdd(color: RGBA): this; + Add(color: RGBA, out: T): T; + SelfSub(color: RGBA): this; + Sub(color: RGBA, out: T): T; + SelfMul(s: number): this; + Mul(s: number, out: T): T; + Mix(mixColor: RGBA, strength: number): void; + MakeStyleString(alpha?: number): string; +} +declare enum b2DrawFlags { + e_none = 0, + e_shapeBit = 1, + e_jointBit = 2, + e_aabbBit = 4, + e_pairBit = 8, + e_centerOfMassBit = 16, + e_all = 63 +} +declare abstract class b2Draw { + m_drawFlags: b2DrawFlags; + SetFlags(flags: b2DrawFlags): void; + GetFlags(): b2DrawFlags; + AppendFlags(flags: b2DrawFlags): void; + ClearFlags(flags: b2DrawFlags): void; + abstract PushTransform(xf: b2Transform): void; + abstract PopTransform(xf: b2Transform): void; + abstract DrawPolygon(vertices: XY[], vertexCount: number, color: RGBA): void; + abstract DrawSolidPolygon(vertices: XY[], vertexCount: number, color: RGBA): void; + abstract DrawCircle(center: XY, radius: number, color: RGBA): void; + abstract DrawSolidCircle(center: XY, radius: number, axis: XY, color: RGBA): void; + abstract DrawSegment(p1: XY, p2: XY, color: RGBA): void; + abstract DrawTransform(xf: b2Transform): void; + abstract DrawPoint(p: XY, size: number, color: RGBA): void; +} + +declare class b2Timer { + m_start: number; + Reset(): b2Timer; + GetMilliseconds(): number; +} +declare class b2Counter { + m_count: number; + m_min_count: number; + m_max_count: number; + GetCount(): number; + GetMinCount(): number; + GetMaxCount(): number; + ResetCount(): number; + ResetMinCount(): void; + ResetMaxCount(): void; + Increment(): void; + Decrement(): void; +} + +declare class b2GrowableStack { + m_stack: Array; + m_count: number; + constructor(N: number); + Reset(): this; + Push(element: T): void; + Pop(): T | null; + GetCount(): number; +} + +declare class b2BlockAllocator { +} + +declare class b2StackAllocator { +} + +declare class b2DistanceProxy { + readonly m_buffer: b2Vec2[]; + m_vertices: b2Vec2[]; + m_count: number; + m_radius: number; + Copy(other: Readonly): this; + Reset(): b2DistanceProxy; + SetShape(shape: b2Shape, index: number): void; + SetVerticesRadius(vertices: b2Vec2[], count: number, radius: number): void; + Set(shape: b2Shape, index: number): void; + Set(vertices: b2Vec2[], count: number, radius: number): void; + GetSupport(d: b2Vec2): number; + GetSupportVertex(d: b2Vec2): b2Vec2; + GetVertexCount(): number; + GetVertex(index: number): b2Vec2; +} +declare class b2SimplexCache { + metric: number; + count: number; + readonly indexA: [number, number, number]; + readonly indexB: [number, number, number]; + Reset(): b2SimplexCache; +} +declare class b2DistanceInput { + readonly proxyA: b2DistanceProxy; + readonly proxyB: b2DistanceProxy; + readonly transformA: b2Transform; + readonly transformB: b2Transform; + useRadii: boolean; + Reset(): b2DistanceInput; +} +declare class b2DistanceOutput { + readonly pointA: b2Vec2; + readonly pointB: b2Vec2; + distance: number; + iterations: number; + Reset(): b2DistanceOutput; +} +declare class b2ShapeCastInput { + readonly proxyA: b2DistanceProxy; + readonly proxyB: b2DistanceProxy; + readonly transformA: b2Transform; + readonly transformB: b2Transform; + readonly translationB: b2Vec2; +} +declare class b2ShapeCastOutput { + readonly point: b2Vec2; + readonly normal: b2Vec2; + lambda: number; + iterations: number; +} +declare let b2_gjkCalls: number; +declare let b2_gjkIters: number; +declare let b2_gjkMaxIters: number; +declare function b2_gjk_reset(): void; +declare class b2SimplexVertex { + readonly wA: b2Vec2; + readonly wB: b2Vec2; + readonly w: b2Vec2; + a: number; + indexA: number; + indexB: number; + Copy(other: b2SimplexVertex): b2SimplexVertex; +} +declare class b2Simplex { + readonly m_v1: b2SimplexVertex; + readonly m_v2: b2SimplexVertex; + readonly m_v3: b2SimplexVertex; + readonly m_vertices: b2SimplexVertex[]; + m_count: number; + constructor(); + ReadCache(cache: b2SimplexCache, proxyA: b2DistanceProxy, transformA: b2Transform, proxyB: b2DistanceProxy, transformB: b2Transform): void; + WriteCache(cache: b2SimplexCache): void; + GetSearchDirection(out: b2Vec2): b2Vec2; + GetClosestPoint(out: b2Vec2): b2Vec2; + GetWitnessPoints(pA: b2Vec2, pB: b2Vec2): void; + GetMetric(): number; + Solve2(): void; + Solve3(): void; + private static s_e12; + private static s_e13; + private static s_e23; +} +declare function b2Distance(output: b2DistanceOutput, cache: b2SimplexCache, input: b2DistanceInput): void; +declare function b2ShapeCast(output: b2ShapeCastOutput, input: b2ShapeCastInput): boolean; + +declare class b2MassData { + mass: number; + readonly center: b2Vec2; + I: number; +} +declare enum b2ShapeType { + e_unknown = -1, + e_circleShape = 0, + e_edgeShape = 1, + e_polygonShape = 2, + e_chainShape = 3, + e_shapeTypeCount = 4 +} +declare abstract class b2Shape { + readonly m_type: b2ShapeType; + m_radius: number; + constructor(type: b2ShapeType, radius: number); + abstract Clone(): b2Shape; + Copy(other: b2Shape): b2Shape; + GetType(): b2ShapeType; + abstract GetChildCount(): number; + abstract TestPoint(xf: b2Transform, p: XY): boolean; + abstract RayCast(output: b2RayCastOutput, input: b2RayCastInput, transform: b2Transform, childIndex: number): boolean; + abstract ComputeAABB(aabb: b2AABB, xf: b2Transform, childIndex: number): void; + abstract ComputeMass(massData: b2MassData, density: number): void; + abstract SetupDistanceProxy(proxy: b2DistanceProxy, index: number): void; + abstract ComputeSubmergedArea(normal: b2Vec2, offset: number, xf: b2Transform, c: b2Vec2): number; + abstract Dump(log: (format: string, ...args: any[]) => void): void; +} + +declare enum b2ContactFeatureType { + e_vertex = 0, + e_face = 1 +} +declare class b2ContactFeature { + private _key; + private _key_invalid; + private _indexA; + private _indexB; + private _typeA; + private _typeB; + get key(): number; + set key(value: number); + get indexA(): number; + set indexA(value: number); + get indexB(): number; + set indexB(value: number); + get typeA(): number; + set typeA(value: number); + get typeB(): number; + set typeB(value: number); +} +declare class b2ContactID { + readonly cf: b2ContactFeature; + Copy(o: b2ContactID): b2ContactID; + Clone(): b2ContactID; + get key(): number; + set key(value: number); +} +declare class b2ManifoldPoint { + readonly localPoint: b2Vec2; + normalImpulse: number; + tangentImpulse: number; + readonly id: b2ContactID; + static MakeArray(length: number): b2ManifoldPoint[]; + Reset(): void; + Copy(o: b2ManifoldPoint): b2ManifoldPoint; +} +declare enum b2ManifoldType { + e_unknown = -1, + e_circles = 0, + e_faceA = 1, + e_faceB = 2 +} +declare class b2Manifold { + readonly points: b2ManifoldPoint[]; + readonly localNormal: b2Vec2; + readonly localPoint: b2Vec2; + type: b2ManifoldType; + pointCount: number; + Reset(): void; + Copy(o: b2Manifold): b2Manifold; + Clone(): b2Manifold; +} +declare class b2WorldManifold { + readonly normal: b2Vec2; + readonly points: b2Vec2[]; + readonly separations: number[]; + private static Initialize_s_pointA; + private static Initialize_s_pointB; + private static Initialize_s_cA; + private static Initialize_s_cB; + private static Initialize_s_planePoint; + private static Initialize_s_clipPoint; + Initialize(manifold: b2Manifold, xfA: b2Transform, radiusA: number, xfB: b2Transform, radiusB: number): void; +} +declare enum b2PointState { + b2_nullState = 0, + b2_addState = 1, + b2_persistState = 2, + b2_removeState = 3 +} +declare function b2GetPointStates(state1: b2PointState[], state2: b2PointState[], manifold1: b2Manifold, manifold2: b2Manifold): void; +declare class b2ClipVertex { + readonly v: b2Vec2; + readonly id: b2ContactID; + static MakeArray(length: number): b2ClipVertex[]; + Copy(other: b2ClipVertex): b2ClipVertex; +} +declare class b2RayCastInput { + readonly p1: b2Vec2; + readonly p2: b2Vec2; + maxFraction: number; + Copy(o: b2RayCastInput): b2RayCastInput; +} +declare class b2RayCastOutput { + readonly normal: b2Vec2; + fraction: number; + Copy(o: b2RayCastOutput): b2RayCastOutput; +} +declare class b2AABB { + readonly lowerBound: b2Vec2; + readonly upperBound: b2Vec2; + private readonly m_cache_center; + private readonly m_cache_extent; + Copy(o: b2AABB): b2AABB; + IsValid(): boolean; + GetCenter(): b2Vec2; + GetExtents(): b2Vec2; + GetPerimeter(): number; + Combine1(aabb: b2AABB): b2AABB; + Combine2(aabb1: b2AABB, aabb2: b2AABB): b2AABB; + static Combine(aabb1: b2AABB, aabb2: b2AABB, out: b2AABB): b2AABB; + Contains(aabb: b2AABB): boolean; + RayCast(output: b2RayCastOutput, input: b2RayCastInput): boolean; + TestContain(point: XY): boolean; + TestOverlap(other: b2AABB): boolean; +} +declare function b2TestOverlapAABB(a: b2AABB, b: b2AABB): boolean; +declare function b2ClipSegmentToLine(vOut: [b2ClipVertex, b2ClipVertex], vIn: [b2ClipVertex, b2ClipVertex], normal: b2Vec2, offset: number, vertexIndexA: number): number; +declare function b2TestOverlapShape(shapeA: b2Shape, indexA: number, shapeB: b2Shape, indexB: number, xfA: b2Transform, xfB: b2Transform): boolean; + +declare class b2TreeNode { + readonly m_id: number; + readonly aabb: b2AABB; + private _userData; + get userData(): T; + set userData(value: T); + parent: b2TreeNode | null; + child1: b2TreeNode | null; + child2: b2TreeNode | null; + height: number; + moved: boolean; + constructor(id?: number); + Reset(): void; + IsLeaf(): boolean; +} +declare class b2DynamicTree { + m_root: b2TreeNode | null; + m_freeList: b2TreeNode | null; + m_insertionCount: number; + readonly m_stack: b2GrowableStack | null>; + static readonly s_r: b2Vec2; + static readonly s_v: b2Vec2; + static readonly s_abs_v: b2Vec2; + static readonly s_segmentAABB: b2AABB; + static readonly s_subInput: b2RayCastInput; + static readonly s_combinedAABB: b2AABB; + static readonly s_aabb: b2AABB; + Query(callback: (node: b2TreeNode) => boolean, aabb: b2AABB): void; + Query(aabb: b2AABB, callback: (node: b2TreeNode) => boolean): void; + QueryPoint(point: XY, callback: (node: b2TreeNode) => boolean): void; + RayCast(callback: (input: b2RayCastInput, node: b2TreeNode) => number, input: b2RayCastInput): void; + RayCast(input: b2RayCastInput, callback: (input: b2RayCastInput, node: b2TreeNode) => number): void; + static s_node_id: number; + AllocateNode(): b2TreeNode; + FreeNode(node: b2TreeNode): void; + CreateProxy(aabb: b2AABB, userData: T): b2TreeNode; + DestroyProxy(node: b2TreeNode): void; + private static MoveProxy_s_fatAABB; + private static MoveProxy_s_hugeAABB; + MoveProxy(node: b2TreeNode, aabb: b2AABB, displacement: b2Vec2): boolean; + InsertLeaf(leaf: b2TreeNode): void; + RemoveLeaf(leaf: b2TreeNode): void; + Balance(A: b2TreeNode): b2TreeNode; + GetHeight(): number; + private static GetAreaNode; + GetAreaRatio(): number; + static ComputeHeightNode(node: b2TreeNode | null): number; + ComputeHeight(): number; + ValidateStructure(node: b2TreeNode | null): void; + ValidateMetrics(node: b2TreeNode | null): void; + Validate(): void; + private static GetMaxBalanceNode; + GetMaxBalance(): number; + RebuildBottomUp(): void; + private static ShiftOriginNode; + ShiftOrigin(newOrigin: XY): void; +} + +declare class b2Pair { + proxyA: b2TreeNode; + proxyB: b2TreeNode; + constructor(proxyA: b2TreeNode, proxyB: b2TreeNode); +} +declare class b2BroadPhase { + readonly m_tree: b2DynamicTree; + m_proxyCount: number; + m_moveCount: number; + readonly m_moveBuffer: Array | null>; + m_pairCount: number; + readonly m_pairBuffer: Array>; + CreateProxy(aabb: b2AABB, userData: T): b2TreeNode; + DestroyProxy(proxy: b2TreeNode): void; + MoveProxy(proxy: b2TreeNode, aabb: b2AABB, displacement: b2Vec2): void; + TouchProxy(proxy: b2TreeNode): void; + GetProxyCount(): number; + UpdatePairs(callback: (a: T, b: T) => void): void; + Query(callback: (node: b2TreeNode) => boolean, aabb: b2AABB): void; + Query(aabb: b2AABB, callback: (node: b2TreeNode) => boolean): void; + QueryPoint(point: XY, callback: (node: b2TreeNode) => boolean): void; + RayCast(input: b2RayCastInput, callback: (input: b2RayCastInput, node: b2TreeNode) => number): void; + GetTreeHeight(): number; + GetTreeBalance(): number; + GetTreeQuality(): number; + ShiftOrigin(newOrigin: XY): void; + BufferMove(proxy: b2TreeNode): void; + UnBufferMove(proxy: b2TreeNode): void; +} + +declare let b2_toiTime: number; +declare let b2_toiMaxTime: number; +declare let b2_toiCalls: number; +declare let b2_toiIters: number; +declare let b2_toiMaxIters: number; +declare let b2_toiRootIters: number; +declare let b2_toiMaxRootIters: number; +declare function b2_toi_reset(): void; +declare class b2TOIInput { + readonly proxyA: b2DistanceProxy; + readonly proxyB: b2DistanceProxy; + readonly sweepA: b2Sweep; + readonly sweepB: b2Sweep; + tMax: number; +} +declare enum b2TOIOutputState { + e_unknown = 0, + e_failed = 1, + e_overlapped = 2, + e_touching = 3, + e_separated = 4 +} +declare class b2TOIOutput { + state: b2TOIOutputState; + t: number; +} +declare enum b2SeparationFunctionType { + e_unknown = -1, + e_points = 0, + e_faceA = 1, + e_faceB = 2 +} +declare class b2SeparationFunction { + m_proxyA: b2DistanceProxy; + m_proxyB: b2DistanceProxy; + readonly m_sweepA: b2Sweep; + readonly m_sweepB: b2Sweep; + m_type: b2SeparationFunctionType; + readonly m_localPoint: b2Vec2; + readonly m_axis: b2Vec2; + Initialize(cache: b2SimplexCache, proxyA: b2DistanceProxy, sweepA: b2Sweep, proxyB: b2DistanceProxy, sweepB: b2Sweep, t1: number): number; + FindMinSeparation(indexA: [number], indexB: [number], t: number): number; + Evaluate(indexA: number, indexB: number, t: number): number; +} +declare function b2TimeOfImpact(output: b2TOIOutput, input: b2TOIInput): void; + +declare class b2CircleShape extends b2Shape { + readonly m_p: b2Vec2; + constructor(radius?: number); + Set(position: XY, radius?: number): this; + Clone(): b2CircleShape; + Copy(other: b2CircleShape): b2CircleShape; + GetChildCount(): number; + private static TestPoint_s_center; + private static TestPoint_s_d; + TestPoint(transform: b2Transform, p: XY): boolean; + private static RayCast_s_position; + private static RayCast_s_s; + private static RayCast_s_r; + RayCast(output: b2RayCastOutput, input: b2RayCastInput, transform: b2Transform, childIndex: number): boolean; + private static ComputeAABB_s_p; + ComputeAABB(aabb: b2AABB, transform: b2Transform, childIndex: number): void; + ComputeMass(massData: b2MassData, density: number): void; + SetupDistanceProxy(proxy: b2DistanceProxy, index: number): void; + ComputeSubmergedArea(normal: b2Vec2, offset: number, xf: b2Transform, c: b2Vec2): number; + Dump(log: (format: string, ...args: any[]) => void): void; +} + +declare class b2PolygonShape extends b2Shape { + readonly m_centroid: b2Vec2; + m_vertices: b2Vec2[]; + m_normals: b2Vec2[]; + m_count: number; + constructor(); + Clone(): b2PolygonShape; + Copy(other: b2PolygonShape): b2PolygonShape; + GetChildCount(): number; + private static Set_s_r; + private static Set_s_v; + Set(vertices: XY[]): b2PolygonShape; + Set(vertices: XY[], count: number): b2PolygonShape; + Set(vertices: number[]): b2PolygonShape; + _Set(vertices: (index: number) => XY, count: number): b2PolygonShape; + SetAsBox(hx: number, hy: number, center?: XY, angle?: number): b2PolygonShape; + private static TestPoint_s_pLocal; + TestPoint(xf: b2Transform, p: XY): boolean; + private static RayCast_s_p1; + private static RayCast_s_p2; + private static RayCast_s_d; + RayCast(output: b2RayCastOutput, input: b2RayCastInput, xf: b2Transform, childIndex: number): boolean; + private static ComputeAABB_s_v; + ComputeAABB(aabb: b2AABB, xf: b2Transform, childIndex: number): void; + private static ComputeMass_s_center; + private static ComputeMass_s_s; + private static ComputeMass_s_e1; + private static ComputeMass_s_e2; + ComputeMass(massData: b2MassData, density: number): void; + private static Validate_s_e; + private static Validate_s_v; + Validate(): boolean; + SetupDistanceProxy(proxy: b2DistanceProxy, index: number): void; + private static ComputeSubmergedArea_s_normalL; + private static ComputeSubmergedArea_s_md; + private static ComputeSubmergedArea_s_intoVec; + private static ComputeSubmergedArea_s_outoVec; + private static ComputeSubmergedArea_s_center; + ComputeSubmergedArea(normal: b2Vec2, offset: number, xf: b2Transform, c: b2Vec2): number; + Dump(log: (format: string, ...args: any[]) => void): void; + private static ComputeCentroid_s_s; + private static ComputeCentroid_s_p1; + private static ComputeCentroid_s_p2; + private static ComputeCentroid_s_p3; + private static ComputeCentroid_s_e1; + private static ComputeCentroid_s_e2; + static ComputeCentroid(vs: b2Vec2[], count: number, out: b2Vec2): b2Vec2; +} + +declare function b2CollideCircles(manifold: b2Manifold, circleA: b2CircleShape, xfA: b2Transform, circleB: b2CircleShape, xfB: b2Transform): void; +declare function b2CollidePolygonAndCircle(manifold: b2Manifold, polygonA: b2PolygonShape, xfA: b2Transform, circleB: b2CircleShape, xfB: b2Transform): void; + +declare function b2CollidePolygons(manifold: b2Manifold, polyA: b2PolygonShape, xfA: b2Transform, polyB: b2PolygonShape, xfB: b2Transform): void; + +declare class b2EdgeShape extends b2Shape { + readonly m_vertex1: b2Vec2; + readonly m_vertex2: b2Vec2; + readonly m_vertex0: b2Vec2; + readonly m_vertex3: b2Vec2; + m_oneSided: boolean; + constructor(); + SetOneSided(v0: XY, v1: XY, v2: XY, v3: XY): b2EdgeShape; + SetTwoSided(v1: XY, v2: XY): b2EdgeShape; + Clone(): b2EdgeShape; + Copy(other: b2EdgeShape): b2EdgeShape; + GetChildCount(): number; + TestPoint(xf: b2Transform, p: XY): boolean; + private static RayCast_s_p1; + private static RayCast_s_p2; + private static RayCast_s_d; + private static RayCast_s_e; + private static RayCast_s_q; + private static RayCast_s_r; + RayCast(output: b2RayCastOutput, input: b2RayCastInput, xf: b2Transform, childIndex: number): boolean; + private static ComputeAABB_s_v1; + private static ComputeAABB_s_v2; + ComputeAABB(aabb: b2AABB, xf: b2Transform, childIndex: number): void; + ComputeMass(massData: b2MassData, density: number): void; + SetupDistanceProxy(proxy: b2DistanceProxy, index: number): void; + ComputeSubmergedArea(normal: b2Vec2, offset: number, xf: b2Transform, c: b2Vec2): number; + Dump(log: (format: string, ...args: any[]) => void): void; +} + +declare function b2CollideEdgeAndCircle(manifold: b2Manifold, edgeA: b2EdgeShape, xfA: b2Transform, circleB: b2CircleShape, xfB: b2Transform): void; +declare function b2CollideEdgeAndPolygon(manifold: b2Manifold, edgeA: b2EdgeShape, xfA: b2Transform, polygonB: b2PolygonShape, xfB: b2Transform): void; + +declare class b2ChainShape extends b2Shape { + m_vertices: b2Vec2[]; + m_count: number; + readonly m_prevVertex: b2Vec2; + readonly m_nextVertex: b2Vec2; + constructor(); + CreateLoop(vertices: XY[]): b2ChainShape; + CreateLoop(vertices: XY[], count: number): b2ChainShape; + CreateLoop(vertices: number[]): b2ChainShape; + private _CreateLoop; + CreateChain(vertices: XY[], prevVertex: Readonly, nextVertex: Readonly): b2ChainShape; + CreateChain(vertices: XY[], count: number, prevVertex: Readonly, nextVertex: Readonly): b2ChainShape; + CreateChain(vertices: number[], prevVertex: Readonly, nextVertex: Readonly): b2ChainShape; + private _CreateChain; + Clone(): b2ChainShape; + Copy(other: b2ChainShape): b2ChainShape; + GetChildCount(): number; + GetChildEdge(edge: b2EdgeShape, index: number): void; + TestPoint(xf: b2Transform, p: XY): boolean; + private static RayCast_s_edgeShape; + RayCast(output: b2RayCastOutput, input: b2RayCastInput, xf: b2Transform, childIndex: number): boolean; + private static ComputeAABB_s_v1; + private static ComputeAABB_s_v2; + private static ComputeAABB_s_lower; + private static ComputeAABB_s_upper; + ComputeAABB(aabb: b2AABB, xf: b2Transform, childIndex: number): void; + ComputeMass(massData: b2MassData, density: number): void; + SetupDistanceProxy(proxy: b2DistanceProxy, index: number): void; + ComputeSubmergedArea(normal: b2Vec2, offset: number, xf: b2Transform, c: b2Vec2): number; + Dump(log: (format: string, ...args: any[]) => void): void; +} + +declare class b2Profile { + step: number; + collide: number; + solve: number; + solveInit: number; + solveVelocity: number; + solvePosition: number; + broadphase: number; + solveTOI: number; + Reset(): this; +} +declare class b2TimeStep { + dt: number; + inv_dt: number; + dtRatio: number; + velocityIterations: number; + positionIterations: number; + warmStarting: boolean; + Copy(step: b2TimeStep): b2TimeStep; +} +declare class b2Position { + readonly c: b2Vec2; + a: number; + static MakeArray(length: number): b2Position[]; +} +declare class b2Velocity { + readonly v: b2Vec2; + w: number; + static MakeArray(length: number): b2Velocity[]; +} +declare class b2SolverData { + readonly step: b2TimeStep; + positions: b2Position[]; + velocities: b2Velocity[]; +} + +declare enum b2JointType { + e_unknownJoint = 0, + e_revoluteJoint = 1, + e_prismaticJoint = 2, + e_distanceJoint = 3, + e_pulleyJoint = 4, + e_mouseJoint = 5, + e_gearJoint = 6, + e_wheelJoint = 7, + e_weldJoint = 8, + e_frictionJoint = 9, + e_ropeJoint = 10, + e_motorJoint = 11, + e_areaJoint = 12 +} +declare class b2Jacobian { + readonly linear: b2Vec2; + angularA: number; + angularB: number; + SetZero(): b2Jacobian; + Set(x: XY, a1: number, a2: number): b2Jacobian; +} +declare class b2JointEdge { + private _other; + get other(): b2Body; + set other(value: b2Body); + readonly joint: b2Joint; + prev: b2JointEdge | null; + next: b2JointEdge | null; + constructor(joint: b2Joint); + Reset(): void; +} +interface b2IJointDef { + type: b2JointType; + userData?: any; + bodyA: b2Body; + bodyB: b2Body; + collideConnected?: boolean; +} +declare abstract class b2JointDef implements b2IJointDef { + readonly type: b2JointType; + userData: any; + bodyA: b2Body; + bodyB: b2Body; + collideConnected: boolean; + constructor(type: b2JointType); +} +declare function b2LinearStiffness(def: { + stiffness: number; + damping: number; +}, frequencyHertz: number, dampingRatio: number, bodyA: b2Body, bodyB: b2Body): void; +declare function b2AngularStiffness(def: { + stiffness: number; + damping: number; +}, frequencyHertz: number, dampingRatio: number, bodyA: b2Body, bodyB: b2Body): void; +declare abstract class b2Joint { + readonly m_type: b2JointType; + m_prev: b2Joint | null; + m_next: b2Joint | null; + readonly m_edgeA: b2JointEdge; + readonly m_edgeB: b2JointEdge; + m_bodyA: b2Body; + m_bodyB: b2Body; + m_index: number; + m_islandFlag: boolean; + m_collideConnected: boolean; + m_userData: any; + constructor(def: b2IJointDef); + GetType(): b2JointType; + GetBodyA(): b2Body; + GetBodyB(): b2Body; + abstract GetAnchorA(out: T): T; + abstract GetAnchorB(out: T): T; + abstract GetReactionForce(inv_dt: number, out: T): T; + abstract GetReactionTorque(inv_dt: number): number; + GetNext(): b2Joint | null; + GetUserData(): any; + SetUserData(data: any): void; + IsEnabled(): boolean; + GetCollideConnected(): boolean; + Dump(log: (format: string, ...args: any[]) => void): void; + ShiftOrigin(newOrigin: XY): void; + private static Draw_s_p1; + private static Draw_s_p2; + private static Draw_s_color; + private static Draw_s_c; + Draw(draw: b2Draw): void; + abstract InitVelocityConstraints(data: b2SolverData): void; + abstract SolveVelocityConstraints(data: b2SolverData): void; + abstract SolvePositionConstraints(data: b2SolverData): boolean; +} + +declare class b2DestructionListener { + SayGoodbyeJoint(joint: b2Joint): void; + SayGoodbyeFixture(fixture: b2Fixture): void; +} +declare class b2ContactFilter { + ShouldCollide(fixtureA: b2Fixture, fixtureB: b2Fixture): boolean; + static readonly b2_defaultFilter: b2ContactFilter; +} +declare class b2ContactImpulse { + normalImpulses: number[]; + tangentImpulses: number[]; + count: number; +} +declare class b2ContactListener { + BeginContact(contact: b2Contact): void; + EndContact(contact: b2Contact): void; + PreSolve(contact: b2Contact, oldManifold: b2Manifold): void; + PostSolve(contact: b2Contact, impulse: b2ContactImpulse): void; + static readonly b2_defaultListener: b2ContactListener; +} +declare class b2QueryCallback { + ReportFixture(fixture: b2Fixture): boolean; +} +declare type b2QueryCallbackFunction = (fixture: b2Fixture) => boolean; +declare class b2RayCastCallback { + ReportFixture(fixture: b2Fixture, point: b2Vec2, normal: b2Vec2, fraction: number): number; +} +declare type b2RayCastCallbackFunction = (fixture: b2Fixture, point: b2Vec2, normal: b2Vec2, fraction: number) => number; + +declare function b2MixFriction(friction1: number, friction2: number): number; +declare function b2MixRestitution(restitution1: number, restitution2: number): number; +declare function b2MixRestitutionThreshold(threshold1: number, threshold2: number): number; +declare class b2ContactEdge { + private _other; + get other(): b2Body; + set other(value: b2Body); + readonly contact: b2Contact; + prev: b2ContactEdge | null; + next: b2ContactEdge | null; + constructor(contact: b2Contact); + Reset(): void; +} +declare abstract class b2Contact { + m_islandFlag: boolean; + m_touchingFlag: boolean; + m_enabledFlag: boolean; + m_filterFlag: boolean; + m_bulletHitFlag: boolean; + m_toiFlag: boolean; + m_prev: b2Contact | null; + m_next: b2Contact | null; + readonly m_nodeA: b2ContactEdge; + readonly m_nodeB: b2ContactEdge; + m_fixtureA: b2Fixture; + m_fixtureB: b2Fixture; + m_indexA: number; + m_indexB: number; + m_manifold: b2Manifold; + m_toiCount: number; + m_toi: number; + m_friction: number; + m_restitution: number; + m_restitutionThreshold: number; + m_tangentSpeed: number; + m_oldManifold: b2Manifold; + GetManifold(): b2Manifold; + GetWorldManifold(worldManifold: b2WorldManifold): void; + IsTouching(): boolean; + SetEnabled(flag: boolean): void; + IsEnabled(): boolean; + GetNext(): b2Contact | null; + GetFixtureA(): b2Fixture; + GetChildIndexA(): number; + GetShapeA(): A; + GetFixtureB(): b2Fixture; + GetChildIndexB(): number; + GetShapeB(): B; + abstract Evaluate(manifold: b2Manifold, xfA: b2Transform, xfB: b2Transform): void; + FlagForFiltering(): void; + SetFriction(friction: number): void; + GetFriction(): number; + ResetFriction(): void; + SetRestitution(restitution: number): void; + GetRestitution(): number; + ResetRestitution(): void; + SetRestitutionThreshold(threshold: number): void; + GetRestitutionThreshold(): number; + ResetRestitutionThreshold(): void; + SetTangentSpeed(speed: number): void; + GetTangentSpeed(): number; + Reset(fixtureA: b2Fixture, indexA: number, fixtureB: b2Fixture, indexB: number): void; + Update(listener: b2ContactListener): void; + private static ComputeTOI_s_input; + private static ComputeTOI_s_output; + ComputeTOI(sweepA: b2Sweep, sweepB: b2Sweep): number; +} + +interface b2IDistanceJointDef extends b2IJointDef { + localAnchorA?: XY; + localAnchorB?: XY; + length?: number; + minLength?: number; + maxLength?: number; + stiffness?: number; + damping?: number; +} +declare class b2DistanceJointDef extends b2JointDef implements b2IDistanceJointDef { + readonly localAnchorA: b2Vec2; + readonly localAnchorB: b2Vec2; + length: number; + minLength: number; + maxLength: number; + stiffness: number; + damping: number; + constructor(); + Initialize(b1: b2Body, b2: b2Body, anchor1: XY, anchor2: XY): void; +} +declare class b2DistanceJoint extends b2Joint { + m_stiffness: number; + m_damping: number; + m_bias: number; + m_length: number; + m_minLength: number; + m_maxLength: number; + readonly m_localAnchorA: b2Vec2; + readonly m_localAnchorB: b2Vec2; + m_gamma: number; + m_impulse: number; + m_lowerImpulse: number; + m_upperImpulse: number; + m_indexA: number; + m_indexB: number; + readonly m_u: b2Vec2; + readonly m_rA: b2Vec2; + readonly m_rB: b2Vec2; + readonly m_localCenterA: b2Vec2; + readonly m_localCenterB: b2Vec2; + m_currentLength: number; + m_invMassA: number; + m_invMassB: number; + m_invIA: number; + m_invIB: number; + m_softMass: number; + m_mass: number; + readonly m_qA: b2Rot; + readonly m_qB: b2Rot; + readonly m_lalcA: b2Vec2; + readonly m_lalcB: b2Vec2; + constructor(def: b2IDistanceJointDef); + GetAnchorA(out: T): T; + GetAnchorB(out: T): T; + GetReactionForce(inv_dt: number, out: T): T; + GetReactionTorque(inv_dt: number): number; + GetLocalAnchorA(): Readonly; + GetLocalAnchorB(): Readonly; + SetLength(length: number): number; + GetLength(): number; + SetMinLength(minLength: number): number; + SetMaxLength(maxLength: number): number; + GetCurrentLength(): number; + SetStiffness(stiffness: number): void; + GetStiffness(): number; + SetDamping(damping: number): void; + GetDamping(): number; + Dump(log: (format: string, ...args: any[]) => void): void; + private static InitVelocityConstraints_s_P; + InitVelocityConstraints(data: b2SolverData): void; + private static SolveVelocityConstraints_s_vpA; + private static SolveVelocityConstraints_s_vpB; + private static SolveVelocityConstraints_s_P; + SolveVelocityConstraints(data: b2SolverData): void; + private static SolvePositionConstraints_s_P; + SolvePositionConstraints(data: b2SolverData): boolean; + private static Draw_s_pA; + private static Draw_s_pB; + private static Draw_s_axis; + private static Draw_s_c1; + private static Draw_s_c2; + private static Draw_s_c3; + private static Draw_s_c4; + private static Draw_s_pRest; + private static Draw_s_pMin; + private static Draw_s_pMax; + Draw(draw: b2Draw): void; +} + +interface b2IAreaJointDef extends b2IJointDef { + bodies: b2Body[]; + stiffness?: number; + damping?: number; +} +declare class b2AreaJointDef extends b2JointDef implements b2IAreaJointDef { + bodies: b2Body[]; + stiffness: number; + damping: number; + constructor(); + AddBody(body: b2Body): void; +} +declare class b2AreaJoint extends b2Joint { + m_bodies: b2Body[]; + m_stiffness: number; + m_damping: number; + m_impulse: number; + readonly m_targetLengths: number[]; + m_targetArea: number; + readonly m_normals: b2Vec2[]; + readonly m_joints: b2DistanceJoint[]; + readonly m_deltas: b2Vec2[]; + readonly m_delta: b2Vec2; + constructor(def: b2IAreaJointDef); + GetAnchorA(out: T): T; + GetAnchorB(out: T): T; + GetReactionForce(inv_dt: number, out: T): T; + GetReactionTorque(inv_dt: number): number; + SetStiffness(stiffness: number): void; + GetStiffness(): number; + SetDamping(damping: number): void; + GetDamping(): number; + Dump(log: (format: string, ...args: any[]) => void): void; + InitVelocityConstraints(data: b2SolverData): void; + SolveVelocityConstraints(data: b2SolverData): void; + SolvePositionConstraints(data: b2SolverData): boolean; +} + +interface b2IFrictionJointDef extends b2IJointDef { + localAnchorA?: XY; + localAnchorB?: XY; + maxForce?: number; + maxTorque?: number; +} +declare class b2FrictionJointDef extends b2JointDef implements b2IFrictionJointDef { + readonly localAnchorA: b2Vec2; + readonly localAnchorB: b2Vec2; + maxForce: number; + maxTorque: number; + constructor(); + Initialize(bA: b2Body, bB: b2Body, anchor: b2Vec2): void; +} +declare class b2FrictionJoint extends b2Joint { + readonly m_localAnchorA: b2Vec2; + readonly m_localAnchorB: b2Vec2; + readonly m_linearImpulse: b2Vec2; + m_angularImpulse: number; + m_maxForce: number; + m_maxTorque: number; + m_indexA: number; + m_indexB: number; + readonly m_rA: b2Vec2; + readonly m_rB: b2Vec2; + readonly m_localCenterA: b2Vec2; + readonly m_localCenterB: b2Vec2; + m_invMassA: number; + m_invMassB: number; + m_invIA: number; + m_invIB: number; + readonly m_linearMass: b2Mat22; + m_angularMass: number; + readonly m_qA: b2Rot; + readonly m_qB: b2Rot; + readonly m_lalcA: b2Vec2; + readonly m_lalcB: b2Vec2; + readonly m_K: b2Mat22; + constructor(def: b2IFrictionJointDef); + InitVelocityConstraints(data: b2SolverData): void; + private static SolveVelocityConstraints_s_Cdot_v2; + private static SolveVelocityConstraints_s_impulseV; + private static SolveVelocityConstraints_s_oldImpulseV; + SolveVelocityConstraints(data: b2SolverData): void; + SolvePositionConstraints(data: b2SolverData): boolean; + GetAnchorA(out: T): T; + GetAnchorB(out: T): T; + GetReactionForce(inv_dt: number, out: T): T; + GetReactionTorque(inv_dt: number): number; + GetLocalAnchorA(): Readonly; + GetLocalAnchorB(): Readonly; + SetMaxForce(force: number): void; + GetMaxForce(): number; + SetMaxTorque(torque: number): void; + GetMaxTorque(): number; + Dump(log: (format: string, ...args: any[]) => void): void; +} + +interface b2IPrismaticJointDef extends b2IJointDef { + localAnchorA?: XY; + localAnchorB?: XY; + localAxisA?: XY; + referenceAngle?: number; + enableLimit?: boolean; + lowerTranslation?: number; + upperTranslation?: number; + enableMotor?: boolean; + maxMotorForce?: number; + motorSpeed?: number; +} +declare class b2PrismaticJointDef extends b2JointDef implements b2IPrismaticJointDef { + readonly localAnchorA: b2Vec2; + readonly localAnchorB: b2Vec2; + readonly localAxisA: b2Vec2; + referenceAngle: number; + enableLimit: boolean; + lowerTranslation: number; + upperTranslation: number; + enableMotor: boolean; + maxMotorForce: number; + motorSpeed: number; + constructor(); + Initialize(bA: b2Body, bB: b2Body, anchor: b2Vec2, axis: b2Vec2): void; +} +declare class b2PrismaticJoint extends b2Joint { + readonly m_localAnchorA: b2Vec2; + readonly m_localAnchorB: b2Vec2; + readonly m_localXAxisA: b2Vec2; + readonly m_localYAxisA: b2Vec2; + m_referenceAngle: number; + readonly m_impulse: b2Vec2; + m_motorImpulse: number; + m_lowerImpulse: number; + m_upperImpulse: number; + m_lowerTranslation: number; + m_upperTranslation: number; + m_maxMotorForce: number; + m_motorSpeed: number; + m_enableLimit: boolean; + m_enableMotor: boolean; + m_indexA: number; + m_indexB: number; + readonly m_localCenterA: b2Vec2; + readonly m_localCenterB: b2Vec2; + m_invMassA: number; + m_invMassB: number; + m_invIA: number; + m_invIB: number; + readonly m_axis: b2Vec2; + readonly m_perp: b2Vec2; + m_s1: number; + m_s2: number; + m_a1: number; + m_a2: number; + readonly m_K: b2Mat22; + readonly m_K3: b2Mat33; + readonly m_K2: b2Mat22; + m_translation: number; + m_axialMass: number; + readonly m_qA: b2Rot; + readonly m_qB: b2Rot; + readonly m_lalcA: b2Vec2; + readonly m_lalcB: b2Vec2; + readonly m_rA: b2Vec2; + readonly m_rB: b2Vec2; + constructor(def: b2IPrismaticJointDef); + private static InitVelocityConstraints_s_d; + private static InitVelocityConstraints_s_P; + InitVelocityConstraints(data: b2SolverData): void; + private static SolveVelocityConstraints_s_P; + private static SolveVelocityConstraints_s_df; + SolveVelocityConstraints(data: b2SolverData): void; + private static SolvePositionConstraints_s_d; + private static SolvePositionConstraints_s_impulse; + private static SolvePositionConstraints_s_impulse1; + private static SolvePositionConstraints_s_P; + SolvePositionConstraints(data: b2SolverData): boolean; + GetAnchorA(out: T): T; + GetAnchorB(out: T): T; + GetReactionForce(inv_dt: number, out: T): T; + GetReactionTorque(inv_dt: number): number; + GetLocalAnchorA(): Readonly; + GetLocalAnchorB(): Readonly; + GetLocalAxisA(): Readonly; + GetReferenceAngle(): number; + private static GetJointTranslation_s_pA; + private static GetJointTranslation_s_pB; + private static GetJointTranslation_s_d; + private static GetJointTranslation_s_axis; + GetJointTranslation(): number; + GetJointSpeed(): number; + IsLimitEnabled(): boolean; + EnableLimit(flag: boolean): void; + GetLowerLimit(): number; + GetUpperLimit(): number; + SetLimits(lower: number, upper: number): void; + IsMotorEnabled(): boolean; + EnableMotor(flag: boolean): void; + SetMotorSpeed(speed: number): void; + GetMotorSpeed(): number; + SetMaxMotorForce(force: number): void; + GetMaxMotorForce(): number; + GetMotorForce(inv_dt: number): number; + Dump(log: (format: string, ...args: any[]) => void): void; + private static Draw_s_pA; + private static Draw_s_pB; + private static Draw_s_axis; + private static Draw_s_c1; + private static Draw_s_c2; + private static Draw_s_c3; + private static Draw_s_c4; + private static Draw_s_c5; + private static Draw_s_lower; + private static Draw_s_upper; + private static Draw_s_perp; + Draw(draw: b2Draw): void; +} + +interface b2IRevoluteJointDef extends b2IJointDef { + localAnchorA?: XY; + localAnchorB?: XY; + referenceAngle?: number; + enableLimit?: boolean; + lowerAngle?: number; + upperAngle?: number; + enableMotor?: boolean; + motorSpeed?: number; + maxMotorTorque?: number; +} +declare class b2RevoluteJointDef extends b2JointDef implements b2IRevoluteJointDef { + readonly localAnchorA: b2Vec2; + readonly localAnchorB: b2Vec2; + referenceAngle: number; + enableLimit: boolean; + lowerAngle: number; + upperAngle: number; + enableMotor: boolean; + motorSpeed: number; + maxMotorTorque: number; + constructor(); + Initialize(bA: b2Body, bB: b2Body, anchor: XY): void; +} +declare class b2RevoluteJoint extends b2Joint { + readonly m_localAnchorA: b2Vec2; + readonly m_localAnchorB: b2Vec2; + readonly m_impulse: b2Vec2; + m_motorImpulse: number; + m_lowerImpulse: number; + m_upperImpulse: number; + m_enableMotor: boolean; + m_maxMotorTorque: number; + m_motorSpeed: number; + m_enableLimit: boolean; + m_referenceAngle: number; + m_lowerAngle: number; + m_upperAngle: number; + m_indexA: number; + m_indexB: number; + readonly m_rA: b2Vec2; + readonly m_rB: b2Vec2; + readonly m_localCenterA: b2Vec2; + readonly m_localCenterB: b2Vec2; + m_invMassA: number; + m_invMassB: number; + m_invIA: number; + m_invIB: number; + readonly m_K: b2Mat22; + m_angle: number; + m_axialMass: number; + readonly m_qA: b2Rot; + readonly m_qB: b2Rot; + readonly m_lalcA: b2Vec2; + readonly m_lalcB: b2Vec2; + constructor(def: b2IRevoluteJointDef); + private static InitVelocityConstraints_s_P; + InitVelocityConstraints(data: b2SolverData): void; + private static SolveVelocityConstraints_s_Cdot_v2; + private static SolveVelocityConstraints_s_impulse_v2; + SolveVelocityConstraints(data: b2SolverData): void; + private static SolvePositionConstraints_s_C_v2; + private static SolvePositionConstraints_s_impulse; + SolvePositionConstraints(data: b2SolverData): boolean; + GetAnchorA(out: T): T; + GetAnchorB(out: T): T; + GetReactionForce(inv_dt: number, out: T): T; + GetReactionTorque(inv_dt: number): number; + GetLocalAnchorA(): Readonly; + GetLocalAnchorB(): Readonly; + GetReferenceAngle(): number; + GetJointAngle(): number; + GetJointSpeed(): number; + IsMotorEnabled(): boolean; + EnableMotor(flag: boolean): void; + GetMotorTorque(inv_dt: number): number; + GetMotorSpeed(): number; + SetMaxMotorTorque(torque: number): void; + GetMaxMotorTorque(): number; + IsLimitEnabled(): boolean; + EnableLimit(flag: boolean): void; + GetLowerLimit(): number; + GetUpperLimit(): number; + SetLimits(lower: number, upper: number): void; + SetMotorSpeed(speed: number): void; + Dump(log: (format: string, ...args: any[]) => void): void; + private static Draw_s_pA; + private static Draw_s_pB; + private static Draw_s_c1; + private static Draw_s_c2; + private static Draw_s_c3; + private static Draw_s_c4; + private static Draw_s_c5; + private static Draw_s_color_; + private static Draw_s_r; + private static Draw_s_rlo; + private static Draw_s_rhi; + Draw(draw: b2Draw): void; +} + +interface b2IGearJointDef extends b2IJointDef { + joint1: b2RevoluteJoint | b2PrismaticJoint; + joint2: b2RevoluteJoint | b2PrismaticJoint; + ratio?: number; +} +declare class b2GearJointDef extends b2JointDef implements b2IGearJointDef { + joint1: b2RevoluteJoint | b2PrismaticJoint; + joint2: b2RevoluteJoint | b2PrismaticJoint; + ratio: number; + constructor(); +} +declare class b2GearJoint extends b2Joint { + m_joint1: b2RevoluteJoint | b2PrismaticJoint; + m_joint2: b2RevoluteJoint | b2PrismaticJoint; + m_typeA: b2JointType; + m_typeB: b2JointType; + m_bodyC: b2Body; + m_bodyD: b2Body; + readonly m_localAnchorA: b2Vec2; + readonly m_localAnchorB: b2Vec2; + readonly m_localAnchorC: b2Vec2; + readonly m_localAnchorD: b2Vec2; + readonly m_localAxisC: b2Vec2; + readonly m_localAxisD: b2Vec2; + m_referenceAngleA: number; + m_referenceAngleB: number; + m_constant: number; + m_ratio: number; + m_impulse: number; + m_indexA: number; + m_indexB: number; + m_indexC: number; + m_indexD: number; + readonly m_lcA: b2Vec2; + readonly m_lcB: b2Vec2; + readonly m_lcC: b2Vec2; + readonly m_lcD: b2Vec2; + m_mA: number; + m_mB: number; + m_mC: number; + m_mD: number; + m_iA: number; + m_iB: number; + m_iC: number; + m_iD: number; + readonly m_JvAC: b2Vec2; + readonly m_JvBD: b2Vec2; + m_JwA: number; + m_JwB: number; + m_JwC: number; + m_JwD: number; + m_mass: number; + readonly m_qA: b2Rot; + readonly m_qB: b2Rot; + readonly m_qC: b2Rot; + readonly m_qD: b2Rot; + readonly m_lalcA: b2Vec2; + readonly m_lalcB: b2Vec2; + readonly m_lalcC: b2Vec2; + readonly m_lalcD: b2Vec2; + constructor(def: b2IGearJointDef); + private static InitVelocityConstraints_s_u; + private static InitVelocityConstraints_s_rA; + private static InitVelocityConstraints_s_rB; + private static InitVelocityConstraints_s_rC; + private static InitVelocityConstraints_s_rD; + InitVelocityConstraints(data: b2SolverData): void; + SolveVelocityConstraints(data: b2SolverData): void; + private static SolvePositionConstraints_s_u; + private static SolvePositionConstraints_s_rA; + private static SolvePositionConstraints_s_rB; + private static SolvePositionConstraints_s_rC; + private static SolvePositionConstraints_s_rD; + SolvePositionConstraints(data: b2SolverData): boolean; + GetAnchorA(out: T): T; + GetAnchorB(out: T): T; + GetReactionForce(inv_dt: number, out: T): T; + GetReactionTorque(inv_dt: number): number; + GetJoint1(): b2PrismaticJoint | b2RevoluteJoint; + GetJoint2(): b2PrismaticJoint | b2RevoluteJoint; + GetRatio(): number; + SetRatio(ratio: number): void; + Dump(log: (format: string, ...args: any[]) => void): void; +} + +interface b2IMotorJointDef extends b2IJointDef { + linearOffset?: XY; + angularOffset?: number; + maxForce?: number; + maxTorque?: number; + correctionFactor?: number; +} +declare class b2MotorJointDef extends b2JointDef implements b2IMotorJointDef { + readonly linearOffset: b2Vec2; + angularOffset: number; + maxForce: number; + maxTorque: number; + correctionFactor: number; + constructor(); + Initialize(bA: b2Body, bB: b2Body): void; +} +declare class b2MotorJoint extends b2Joint { + readonly m_linearOffset: b2Vec2; + m_angularOffset: number; + readonly m_linearImpulse: b2Vec2; + m_angularImpulse: number; + m_maxForce: number; + m_maxTorque: number; + m_correctionFactor: number; + m_indexA: number; + m_indexB: number; + readonly m_rA: b2Vec2; + readonly m_rB: b2Vec2; + readonly m_localCenterA: b2Vec2; + readonly m_localCenterB: b2Vec2; + readonly m_linearError: b2Vec2; + m_angularError: number; + m_invMassA: number; + m_invMassB: number; + m_invIA: number; + m_invIB: number; + readonly m_linearMass: b2Mat22; + m_angularMass: number; + readonly m_qA: b2Rot; + readonly m_qB: b2Rot; + readonly m_K: b2Mat22; + constructor(def: b2IMotorJointDef); + GetAnchorA(out: T): T; + GetAnchorB(out: T): T; + GetReactionForce(inv_dt: number, out: T): T; + GetReactionTorque(inv_dt: number): number; + SetLinearOffset(linearOffset: b2Vec2): void; + GetLinearOffset(): b2Vec2; + SetAngularOffset(angularOffset: number): void; + GetAngularOffset(): number; + SetMaxForce(force: number): void; + GetMaxForce(): number; + SetMaxTorque(torque: number): void; + GetMaxTorque(): number; + InitVelocityConstraints(data: b2SolverData): void; + private static SolveVelocityConstraints_s_Cdot_v2; + private static SolveVelocityConstraints_s_impulse_v2; + private static SolveVelocityConstraints_s_oldImpulse_v2; + SolveVelocityConstraints(data: b2SolverData): void; + SolvePositionConstraints(data: b2SolverData): boolean; + Dump(log: (format: string, ...args: any[]) => void): void; +} + +interface b2IMouseJointDef extends b2IJointDef { + target?: XY; + maxForce?: number; + stiffness?: number; + damping?: number; +} +declare class b2MouseJointDef extends b2JointDef implements b2IMouseJointDef { + readonly target: b2Vec2; + maxForce: number; + stiffness: number; + damping: number; + constructor(); +} +declare class b2MouseJoint extends b2Joint { + readonly m_localAnchorB: b2Vec2; + readonly m_targetA: b2Vec2; + m_stiffness: number; + m_damping: number; + m_beta: number; + readonly m_impulse: b2Vec2; + m_maxForce: number; + m_gamma: number; + m_indexA: number; + m_indexB: number; + readonly m_rB: b2Vec2; + readonly m_localCenterB: b2Vec2; + m_invMassB: number; + m_invIB: number; + readonly m_mass: b2Mat22; + readonly m_C: b2Vec2; + readonly m_qB: b2Rot; + readonly m_lalcB: b2Vec2; + readonly m_K: b2Mat22; + constructor(def: b2IMouseJointDef); + SetTarget(target: b2Vec2): void; + GetTarget(): b2Vec2; + SetMaxForce(maxForce: number): void; + GetMaxForce(): number; + SetStiffness(stiffness: number): void; + GetStiffness(): number; + SetDamping(damping: number): void; + GetDamping(): number; + InitVelocityConstraints(data: b2SolverData): void; + private static SolveVelocityConstraints_s_Cdot; + private static SolveVelocityConstraints_s_impulse; + private static SolveVelocityConstraints_s_oldImpulse; + SolveVelocityConstraints(data: b2SolverData): void; + SolvePositionConstraints(data: b2SolverData): boolean; + GetAnchorA(out: T): T; + GetAnchorB(out: T): T; + GetReactionForce(inv_dt: number, out: T): T; + GetReactionTorque(inv_dt: number): number; + Dump(log: (format: string, ...args: any[]) => void): void; + ShiftOrigin(newOrigin: b2Vec2): void; +} + +declare const b2_minPulleyLength: number; +interface b2IPulleyJointDef extends b2IJointDef { + groundAnchorA?: XY; + groundAnchorB?: XY; + localAnchorA?: XY; + localAnchorB?: XY; + lengthA?: number; + lengthB?: number; + ratio?: number; +} +declare class b2PulleyJointDef extends b2JointDef implements b2IPulleyJointDef { + readonly groundAnchorA: b2Vec2; + readonly groundAnchorB: b2Vec2; + readonly localAnchorA: b2Vec2; + readonly localAnchorB: b2Vec2; + lengthA: number; + lengthB: number; + ratio: number; + constructor(); + Initialize(bA: b2Body, bB: b2Body, groundA: b2Vec2, groundB: b2Vec2, anchorA: b2Vec2, anchorB: b2Vec2, r: number): void; +} +declare class b2PulleyJoint extends b2Joint { + readonly m_groundAnchorA: b2Vec2; + readonly m_groundAnchorB: b2Vec2; + m_lengthA: number; + m_lengthB: number; + readonly m_localAnchorA: b2Vec2; + readonly m_localAnchorB: b2Vec2; + m_constant: number; + m_ratio: number; + m_impulse: number; + m_indexA: number; + m_indexB: number; + readonly m_uA: b2Vec2; + readonly m_uB: b2Vec2; + readonly m_rA: b2Vec2; + readonly m_rB: b2Vec2; + readonly m_localCenterA: b2Vec2; + readonly m_localCenterB: b2Vec2; + m_invMassA: number; + m_invMassB: number; + m_invIA: number; + m_invIB: number; + m_mass: number; + readonly m_qA: b2Rot; + readonly m_qB: b2Rot; + readonly m_lalcA: b2Vec2; + readonly m_lalcB: b2Vec2; + constructor(def: b2IPulleyJointDef); + private static InitVelocityConstraints_s_PA; + private static InitVelocityConstraints_s_PB; + InitVelocityConstraints(data: b2SolverData): void; + private static SolveVelocityConstraints_s_vpA; + private static SolveVelocityConstraints_s_vpB; + private static SolveVelocityConstraints_s_PA; + private static SolveVelocityConstraints_s_PB; + SolveVelocityConstraints(data: b2SolverData): void; + private static SolvePositionConstraints_s_PA; + private static SolvePositionConstraints_s_PB; + SolvePositionConstraints(data: b2SolverData): boolean; + GetAnchorA(out: T): T; + GetAnchorB(out: T): T; + GetReactionForce(inv_dt: number, out: T): T; + GetReactionTorque(inv_dt: number): number; + GetGroundAnchorA(): b2Vec2; + GetGroundAnchorB(): b2Vec2; + GetLengthA(): number; + GetLengthB(): number; + GetRatio(): number; + private static GetCurrentLengthA_s_p; + GetCurrentLengthA(): number; + private static GetCurrentLengthB_s_p; + GetCurrentLengthB(): number; + Dump(log: (format: string, ...args: any[]) => void): void; + ShiftOrigin(newOrigin: b2Vec2): void; +} + +interface b2IWeldJointDef extends b2IJointDef { + localAnchorA?: XY; + localAnchorB?: XY; + referenceAngle?: number; + stiffness?: number; + damping?: number; +} +declare class b2WeldJointDef extends b2JointDef implements b2IWeldJointDef { + readonly localAnchorA: b2Vec2; + readonly localAnchorB: b2Vec2; + referenceAngle: number; + stiffness: number; + damping: number; + constructor(); + Initialize(bA: b2Body, bB: b2Body, anchor: b2Vec2): void; +} +declare class b2WeldJoint extends b2Joint { + m_stiffness: number; + m_damping: number; + m_bias: number; + readonly m_localAnchorA: b2Vec2; + readonly m_localAnchorB: b2Vec2; + m_referenceAngle: number; + m_gamma: number; + readonly m_impulse: b2Vec3; + m_indexA: number; + m_indexB: number; + readonly m_rA: b2Vec2; + readonly m_rB: b2Vec2; + readonly m_localCenterA: b2Vec2; + readonly m_localCenterB: b2Vec2; + m_invMassA: number; + m_invMassB: number; + m_invIA: number; + m_invIB: number; + readonly m_mass: b2Mat33; + readonly m_qA: b2Rot; + readonly m_qB: b2Rot; + readonly m_lalcA: b2Vec2; + readonly m_lalcB: b2Vec2; + readonly m_K: b2Mat33; + constructor(def: b2IWeldJointDef); + private static InitVelocityConstraints_s_P; + InitVelocityConstraints(data: b2SolverData): void; + private static SolveVelocityConstraints_s_Cdot1; + private static SolveVelocityConstraints_s_impulse1; + private static SolveVelocityConstraints_s_impulse; + private static SolveVelocityConstraints_s_P; + SolveVelocityConstraints(data: b2SolverData): void; + private static SolvePositionConstraints_s_C1; + private static SolvePositionConstraints_s_P; + private static SolvePositionConstraints_s_impulse; + SolvePositionConstraints(data: b2SolverData): boolean; + GetAnchorA(out: T): T; + GetAnchorB(out: T): T; + GetReactionForce(inv_dt: number, out: T): T; + GetReactionTorque(inv_dt: number): number; + GetLocalAnchorA(): Readonly; + GetLocalAnchorB(): Readonly; + GetReferenceAngle(): number; + SetStiffness(stiffness: number): void; + GetStiffness(): number; + SetDamping(damping: number): void; + GetDamping(): number; + Dump(log: (format: string, ...args: any[]) => void): void; +} + +interface b2IWheelJointDef extends b2IJointDef { + localAnchorA?: XY; + localAnchorB?: XY; + localAxisA?: XY; + enableLimit?: boolean; + lowerTranslation?: number; + upperTranslation?: number; + enableMotor?: boolean; + maxMotorTorque?: number; + motorSpeed?: number; + stiffness?: number; + damping?: number; +} +declare class b2WheelJointDef extends b2JointDef implements b2IWheelJointDef { + readonly localAnchorA: b2Vec2; + readonly localAnchorB: b2Vec2; + readonly localAxisA: b2Vec2; + enableLimit: boolean; + lowerTranslation: number; + upperTranslation: number; + enableMotor: boolean; + maxMotorTorque: number; + motorSpeed: number; + stiffness: number; + damping: number; + constructor(); + Initialize(bA: b2Body, bB: b2Body, anchor: b2Vec2, axis: b2Vec2): void; +} +declare class b2WheelJoint extends b2Joint { + readonly m_localAnchorA: b2Vec2; + readonly m_localAnchorB: b2Vec2; + readonly m_localXAxisA: b2Vec2; + readonly m_localYAxisA: b2Vec2; + m_impulse: number; + m_motorImpulse: number; + m_springImpulse: number; + m_lowerImpulse: number; + m_upperImpulse: number; + m_translation: number; + m_lowerTranslation: number; + m_upperTranslation: number; + m_maxMotorTorque: number; + m_motorSpeed: number; + m_enableLimit: boolean; + m_enableMotor: boolean; + m_stiffness: number; + m_damping: number; + m_indexA: number; + m_indexB: number; + readonly m_localCenterA: b2Vec2; + readonly m_localCenterB: b2Vec2; + m_invMassA: number; + m_invMassB: number; + m_invIA: number; + m_invIB: number; + readonly m_ax: b2Vec2; + readonly m_ay: b2Vec2; + m_sAx: number; + m_sBx: number; + m_sAy: number; + m_sBy: number; + m_mass: number; + m_motorMass: number; + m_axialMass: number; + m_springMass: number; + m_bias: number; + m_gamma: number; + readonly m_qA: b2Rot; + readonly m_qB: b2Rot; + readonly m_lalcA: b2Vec2; + readonly m_lalcB: b2Vec2; + readonly m_rA: b2Vec2; + readonly m_rB: b2Vec2; + constructor(def: b2IWheelJointDef); + GetMotorSpeed(): number; + GetMaxMotorTorque(): number; + SetStiffness(hz: number): void; + GetStiffness(): number; + SetDamping(ratio: number): void; + GetDamping(): number; + private static InitVelocityConstraints_s_d; + private static InitVelocityConstraints_s_P; + InitVelocityConstraints(data: b2SolverData): void; + private static SolveVelocityConstraints_s_P; + SolveVelocityConstraints(data: b2SolverData): void; + private static SolvePositionConstraints_s_d; + private static SolvePositionConstraints_s_P; + SolvePositionConstraints(data: b2SolverData): boolean; + GetDefinition(def: b2WheelJointDef): b2WheelJointDef; + GetAnchorA(out: T): T; + GetAnchorB(out: T): T; + GetReactionForce(inv_dt: number, out: T): T; + GetReactionTorque(inv_dt: number): number; + GetLocalAnchorA(): Readonly; + GetLocalAnchorB(): Readonly; + GetLocalAxisA(): Readonly; + GetJointTranslation(): number; + GetJointLinearSpeed(): number; + GetJointAngle(): number; + GetJointAngularSpeed(): number; + GetPrismaticJointTranslation(): number; + GetPrismaticJointSpeed(): number; + GetRevoluteJointAngle(): number; + GetRevoluteJointSpeed(): number; + IsMotorEnabled(): boolean; + EnableMotor(flag: boolean): void; + SetMotorSpeed(speed: number): void; + SetMaxMotorTorque(force: number): void; + GetMotorTorque(inv_dt: number): number; + IsLimitEnabled(): boolean; + EnableLimit(flag: boolean): void; + GetLowerLimit(): number; + GetUpperLimit(): number; + SetLimits(lower: number, upper: number): void; + Dump(log: (format: string, ...args: any[]) => void): void; + private static Draw_s_pA; + private static Draw_s_pB; + private static Draw_s_axis; + private static Draw_s_c1; + private static Draw_s_c2; + private static Draw_s_c3; + private static Draw_s_c4; + private static Draw_s_c5; + private static Draw_s_lower; + private static Draw_s_upper; + private static Draw_s_perp; + Draw(draw: b2Draw): void; +} + +declare class b2ContactRegister { + pool: b2Contact[]; + createFcn: (() => b2Contact) | null; + destroyFcn: ((contact: b2Contact) => void) | null; + primary: boolean; +} +declare class b2ContactFactory { + readonly m_registers: b2ContactRegister[][]; + constructor(); + private AddType; + private InitializeRegisters; + Create(fixtureA: b2Fixture, indexA: number, fixtureB: b2Fixture, indexB: number): b2Contact | null; + Destroy(contact: b2Contact): void; +} + +declare class b2ContactManager { + readonly m_broadPhase: b2BroadPhase; + m_contactList: b2Contact | null; + m_contactCount: number; + m_contactFilter: b2ContactFilter; + m_contactListener: b2ContactListener; + readonly m_contactFactory: b2ContactFactory; + AddPair(proxyA: b2FixtureProxy, proxyB: b2FixtureProxy): void; + FindNewContacts(): void; + Destroy(c: b2Contact): void; + Collide(): void; +} + +declare let g_blockSolve: boolean; +declare function get_g_blockSolve(): boolean; +declare function set_g_blockSolve(value: boolean): void; +declare class b2VelocityConstraintPoint { + readonly rA: b2Vec2; + readonly rB: b2Vec2; + normalImpulse: number; + tangentImpulse: number; + normalMass: number; + tangentMass: number; + velocityBias: number; + static MakeArray(length: number): b2VelocityConstraintPoint[]; +} +declare class b2ContactVelocityConstraint { + readonly points: b2VelocityConstraintPoint[]; + readonly normal: b2Vec2; + readonly tangent: b2Vec2; + readonly normalMass: b2Mat22; + readonly K: b2Mat22; + indexA: number; + indexB: number; + invMassA: number; + invMassB: number; + invIA: number; + invIB: number; + friction: number; + restitution: number; + threshold: number; + tangentSpeed: number; + pointCount: number; + contactIndex: number; + static MakeArray(length: number): b2ContactVelocityConstraint[]; +} +declare class b2ContactPositionConstraint { + readonly localPoints: b2Vec2[]; + readonly localNormal: b2Vec2; + readonly localPoint: b2Vec2; + indexA: number; + indexB: number; + invMassA: number; + invMassB: number; + readonly localCenterA: b2Vec2; + readonly localCenterB: b2Vec2; + invIA: number; + invIB: number; + type: b2ManifoldType; + radiusA: number; + radiusB: number; + pointCount: number; + static MakeArray(length: number): b2ContactPositionConstraint[]; +} +declare class b2ContactSolverDef { + readonly step: b2TimeStep; + contacts: b2Contact[]; + count: number; + positions: b2Position[]; + velocities: b2Velocity[]; +} +declare class b2PositionSolverManifold { + readonly normal: b2Vec2; + readonly point: b2Vec2; + separation: number; + private static Initialize_s_pointA; + private static Initialize_s_pointB; + private static Initialize_s_planePoint; + private static Initialize_s_clipPoint; + Initialize(pc: b2ContactPositionConstraint, xfA: b2Transform, xfB: b2Transform, index: number): void; +} +declare class b2ContactSolver { + readonly m_step: b2TimeStep; + m_positions: b2Position[]; + m_velocities: b2Velocity[]; + readonly m_positionConstraints: b2ContactPositionConstraint[]; + readonly m_velocityConstraints: b2ContactVelocityConstraint[]; + m_contacts: b2Contact[]; + m_count: number; + Initialize(def: b2ContactSolverDef): b2ContactSolver; + private static InitializeVelocityConstraints_s_xfA; + private static InitializeVelocityConstraints_s_xfB; + private static InitializeVelocityConstraints_s_worldManifold; + InitializeVelocityConstraints(): void; + private static WarmStart_s_P; + WarmStart(): void; + private static SolveVelocityConstraints_s_dv; + private static SolveVelocityConstraints_s_dv1; + private static SolveVelocityConstraints_s_dv2; + private static SolveVelocityConstraints_s_P; + private static SolveVelocityConstraints_s_a; + private static SolveVelocityConstraints_s_b; + private static SolveVelocityConstraints_s_x; + private static SolveVelocityConstraints_s_d; + private static SolveVelocityConstraints_s_P1; + private static SolveVelocityConstraints_s_P2; + private static SolveVelocityConstraints_s_P1P2; + SolveVelocityConstraints(): void; + StoreImpulses(): void; + private static SolvePositionConstraints_s_xfA; + private static SolvePositionConstraints_s_xfB; + private static SolvePositionConstraints_s_psm; + private static SolvePositionConstraints_s_rA; + private static SolvePositionConstraints_s_rB; + private static SolvePositionConstraints_s_P; + SolvePositionConstraints(): boolean; + private static SolveTOIPositionConstraints_s_xfA; + private static SolveTOIPositionConstraints_s_xfB; + private static SolveTOIPositionConstraints_s_psm; + private static SolveTOIPositionConstraints_s_rA; + private static SolveTOIPositionConstraints_s_rB; + private static SolveTOIPositionConstraints_s_P; + SolveTOIPositionConstraints(toiIndexA: number, toiIndexB: number): boolean; +} + +declare class b2Island { + m_listener: b2ContactListener; + readonly m_bodies: b2Body[]; + readonly m_contacts: b2Contact[]; + readonly m_joints: b2Joint[]; + readonly m_positions: b2Position[]; + readonly m_velocities: b2Velocity[]; + m_bodyCount: number; + m_jointCount: number; + m_contactCount: number; + m_bodyCapacity: number; + m_contactCapacity: number; + m_jointCapacity: number; + Initialize(bodyCapacity: number, contactCapacity: number, jointCapacity: number, listener: b2ContactListener): void; + Clear(): void; + AddBody(body: b2Body): void; + AddContact(contact: b2Contact): void; + AddJoint(joint: b2Joint): void; + private static s_timer; + private static s_solverData; + private static s_contactSolverDef; + private static s_contactSolver; + private static s_translation; + Solve(profile: b2Profile, step: b2TimeStep, gravity: b2Vec2, allowSleep: boolean): void; + SolveTOI(subStep: b2TimeStep, toiIndexA: number, toiIndexB: number): void; + private static s_impulse; + Report(constraints: b2ContactVelocityConstraint[]): void; +} + +declare class b2World { + readonly m_contactManager: b2ContactManager; + m_bodyList: b2Body | null; + m_jointList: b2Joint | null; + m_bodyCount: number; + m_jointCount: number; + readonly m_gravity: b2Vec2; + m_allowSleep: boolean; + m_destructionListener: b2DestructionListener | null; + m_debugDraw: b2Draw | null; + m_inv_dt0: number; + m_newContacts: boolean; + m_locked: boolean; + m_clearForces: boolean; + m_warmStarting: boolean; + m_continuousPhysics: boolean; + m_subStepping: boolean; + m_stepComplete: boolean; + readonly m_profile: b2Profile; + readonly m_island: b2Island; + readonly s_stack: Array; + constructor(gravity: XY); + SetDestructionListener(listener: b2DestructionListener | null): void; + SetContactFilter(filter: b2ContactFilter): void; + SetContactListener(listener: b2ContactListener): void; + SetDebugDraw(debugDraw: b2Draw | null): void; + CreateBody(def?: b2IBodyDef): b2Body; + DestroyBody(b: b2Body): void; + private static _Joint_Create; + private static _Joint_Destroy; + CreateJoint(def: b2IAreaJointDef): b2AreaJoint; + CreateJoint(def: b2IDistanceJointDef): b2DistanceJoint; + CreateJoint(def: b2IFrictionJointDef): b2FrictionJoint; + CreateJoint(def: b2IGearJointDef): b2GearJoint; + CreateJoint(def: b2IMotorJointDef): b2MotorJoint; + CreateJoint(def: b2IMouseJointDef): b2MouseJoint; + CreateJoint(def: b2IPrismaticJointDef): b2PrismaticJoint; + CreateJoint(def: b2IPulleyJointDef): b2PulleyJoint; + CreateJoint(def: b2IRevoluteJointDef): b2RevoluteJoint; + CreateJoint(def: b2IWeldJointDef): b2WeldJoint; + CreateJoint(def: b2IWheelJointDef): b2WheelJoint; + DestroyJoint(j: b2Joint): void; + private static Step_s_step; + private static Step_s_stepTimer; + private static Step_s_timer; + Step(dt: number, velocityIterations: number, positionIterations: number): void; + ClearForces(): void; + private static DebugDraw_s_color; + private static DebugDraw_s_vs; + private static DebugDraw_s_xf; + DebugDraw(): void; + QueryAABB(callback: b2QueryCallback, aabb: b2AABB): void; + QueryAABB(aabb: b2AABB, fn: b2QueryCallbackFunction): void; + private _QueryAABB; + QueryAllAABB(aabb: b2AABB, out?: b2Fixture[]): b2Fixture[]; + QueryPointAABB(callback: b2QueryCallback, point: XY): void; + QueryPointAABB(point: XY, fn: b2QueryCallbackFunction): void; + private _QueryPointAABB; + QueryAllPointAABB(point: XY, out?: b2Fixture[]): b2Fixture[]; + QueryFixtureShape(callback: b2QueryCallback, shape: b2Shape, index: number, transform: b2Transform): void; + QueryFixtureShape(shape: b2Shape, index: number, transform: b2Transform, fn: b2QueryCallbackFunction): void; + private static QueryFixtureShape_s_aabb; + private _QueryFixtureShape; + QueryAllFixtureShape(shape: b2Shape, index: number, transform: b2Transform, out?: b2Fixture[]): b2Fixture[]; + QueryFixturePoint(callback: b2QueryCallback, point: XY): void; + QueryFixturePoint(point: XY, fn: b2QueryCallbackFunction): void; + private _QueryFixturePoint; + QueryAllFixturePoint(point: XY, out?: b2Fixture[]): b2Fixture[]; + RayCast(callback: b2RayCastCallback, point1: XY, point2: XY): void; + RayCast(point1: XY, point2: XY, fn: b2RayCastCallbackFunction): void; + private static RayCast_s_input; + private static RayCast_s_output; + private static RayCast_s_point; + private _RayCast; + RayCastOne(point1: XY, point2: XY): b2Fixture | null; + RayCastAll(point1: XY, point2: XY, out?: b2Fixture[]): b2Fixture[]; + GetBodyList(): b2Body | null; + GetJointList(): b2Joint | null; + GetContactList(): b2Contact | null; + SetAllowSleeping(flag: boolean): void; + GetAllowSleeping(): boolean; + SetWarmStarting(flag: boolean): void; + GetWarmStarting(): boolean; + SetContinuousPhysics(flag: boolean): void; + GetContinuousPhysics(): boolean; + SetSubStepping(flag: boolean): void; + GetSubStepping(): boolean; + GetProxyCount(): number; + GetBodyCount(): number; + GetJointCount(): number; + GetContactCount(): number; + GetTreeHeight(): number; + GetTreeBalance(): number; + GetTreeQuality(): number; + SetGravity(gravity: XY, wake?: boolean): void; + GetGravity(): Readonly; + IsLocked(): boolean; + SetAutoClearForces(flag: boolean): void; + GetAutoClearForces(): boolean; + ShiftOrigin(newOrigin: XY): void; + GetContactManager(): b2ContactManager; + GetProfile(): b2Profile; + Dump(log: (format: string, ...args: any[]) => void): void; + DrawShape(fixture: b2Fixture, color: b2Color): void; + Solve(step: b2TimeStep): void; + private static SolveTOI_s_subStep; + private static SolveTOI_s_backup; + private static SolveTOI_s_backup1; + private static SolveTOI_s_backup2; + private static SolveTOI_s_toi_input; + private static SolveTOI_s_toi_output; + SolveTOI(step: b2TimeStep): void; +} + +declare enum b2BodyType { + b2_unknown = -1, + b2_staticBody = 0, + b2_kinematicBody = 1, + b2_dynamicBody = 2 +} +interface b2IBodyDef { + type?: b2BodyType; + position?: XY; + angle?: number; + linearVelocity?: XY; + angularVelocity?: number; + linearDamping?: number; + angularDamping?: number; + allowSleep?: boolean; + awake?: boolean; + fixedRotation?: boolean; + bullet?: boolean; + enabled?: boolean; + userData?: any; + gravityScale?: number; +} +declare class b2BodyDef implements b2IBodyDef { + type: b2BodyType; + readonly position: b2Vec2; + angle: number; + readonly linearVelocity: b2Vec2; + angularVelocity: number; + linearDamping: number; + angularDamping: number; + allowSleep: boolean; + awake: boolean; + fixedRotation: boolean; + bullet: boolean; + enabled: boolean; + userData: any; + gravityScale: number; +} +declare class b2Body { + m_type: b2BodyType; + m_islandFlag: boolean; + m_awakeFlag: boolean; + m_autoSleepFlag: boolean; + m_bulletFlag: boolean; + m_fixedRotationFlag: boolean; + m_enabledFlag: boolean; + m_toiFlag: boolean; + m_islandIndex: number; + readonly m_xf: b2Transform; + readonly m_sweep: b2Sweep; + readonly m_linearVelocity: b2Vec2; + m_angularVelocity: number; + readonly m_force: b2Vec2; + m_torque: number; + m_world: b2World; + m_prev: b2Body | null; + m_next: b2Body | null; + m_fixtureList: b2Fixture | null; + m_fixtureCount: number; + m_jointList: b2JointEdge | null; + m_contactList: b2ContactEdge | null; + m_mass: number; + m_invMass: number; + m_I: number; + m_invI: number; + m_linearDamping: number; + m_angularDamping: number; + m_gravityScale: number; + m_sleepTime: number; + m_userData: any; + constructor(bd: b2IBodyDef, world: b2World); + CreateFixture(def: b2IFixtureDef): b2Fixture; + CreateFixture(shape: b2Shape): b2Fixture; + CreateFixture(shape: b2Shape, density: number): b2Fixture; + CreateFixtureDef(def: b2IFixtureDef): b2Fixture; + private static CreateFixtureShapeDensity_s_def; + CreateFixtureShapeDensity(shape: b2Shape, density?: number): b2Fixture; + DestroyFixture(fixture: b2Fixture): void; + SetTransformVec(position: XY, angle: number): void; + SetTransformXY(x: number, y: number, angle: number): void; + SetTransform(position: XY, angle: number): void; + GetTransform(): Readonly; + GetPosition(): Readonly; + SetPosition(position: XY): void; + SetPositionXY(x: number, y: number): void; + GetAngle(): number; + SetAngle(angle: number): void; + GetWorldCenter(): Readonly; + GetLocalCenter(): Readonly; + SetLinearVelocity(v: XY): void; + GetLinearVelocity(): Readonly; + SetAngularVelocity(w: number): void; + GetAngularVelocity(): number; + GetDefinition(bd: b2BodyDef): b2BodyDef; + ApplyForce(force: XY, point: XY, wake?: boolean): void; + ApplyForceToCenter(force: XY, wake?: boolean): void; + ApplyTorque(torque: number, wake?: boolean): void; + ApplyLinearImpulse(impulse: XY, point: XY, wake?: boolean): void; + ApplyLinearImpulseToCenter(impulse: XY, wake?: boolean): void; + ApplyAngularImpulse(impulse: number, wake?: boolean): void; + GetMass(): number; + GetInertia(): number; + GetMassData(data: b2MassData): b2MassData; + private static SetMassData_s_oldCenter; + SetMassData(massData: b2MassData): void; + private static ResetMassData_s_localCenter; + private static ResetMassData_s_oldCenter; + private static ResetMassData_s_massData; + ResetMassData(): void; + GetWorldPoint(localPoint: XY, out: T): T; + GetWorldVector(localVector: XY, out: T): T; + GetLocalPoint(worldPoint: XY, out: T): T; + GetLocalVector(worldVector: XY, out: T): T; + GetLinearVelocityFromWorldPoint(worldPoint: XY, out: T): T; + GetLinearVelocityFromLocalPoint(localPoint: XY, out: T): T; + GetLinearDamping(): number; + SetLinearDamping(linearDamping: number): void; + GetAngularDamping(): number; + SetAngularDamping(angularDamping: number): void; + GetGravityScale(): number; + SetGravityScale(scale: number): void; + SetType(type: b2BodyType): void; + GetType(): b2BodyType; + SetBullet(flag: boolean): void; + IsBullet(): boolean; + SetSleepingAllowed(flag: boolean): void; + IsSleepingAllowed(): boolean; + SetAwake(flag: boolean): void; + IsAwake(): boolean; + SetEnabled(flag: boolean): void; + IsEnabled(): boolean; + SetFixedRotation(flag: boolean): void; + IsFixedRotation(): boolean; + GetFixtureList(): b2Fixture | null; + GetJointList(): b2JointEdge | null; + GetContactList(): b2ContactEdge | null; + GetNext(): b2Body | null; + GetUserData(): any; + SetUserData(data: any): void; + GetWorld(): b2World; + Dump(log: (format: string, ...args: any[]) => void): void; + private static SynchronizeFixtures_s_xf1; + SynchronizeFixtures(): void; + SynchronizeTransform(): void; + ShouldCollide(other: b2Body): boolean; + ShouldCollideConnected(other: b2Body): boolean; + Advance(alpha: number): void; +} + +interface b2IFilter { + categoryBits: number; + maskBits: number; + groupIndex?: number; +} +declare class b2Filter implements b2IFilter { + static readonly DEFAULT: Readonly; + categoryBits: number; + maskBits: number; + groupIndex: number; + Clone(): b2Filter; + Copy(other: b2IFilter): this; +} +interface b2IFixtureDef { + shape: b2Shape; + userData?: any; + friction?: number; + restitution?: number; + restitutionThreshold?: number; + density?: number; + isSensor?: boolean; + filter?: b2IFilter; +} +declare class b2FixtureDef implements b2IFixtureDef { + shape: b2Shape; + userData: any; + friction: number; + restitution: number; + restitutionThreshold: number; + density: number; + isSensor: boolean; + readonly filter: b2Filter; +} +declare class b2FixtureProxy { + readonly aabb: b2AABB; + readonly fixture: b2Fixture; + readonly childIndex: number; + treeNode: b2TreeNode; + constructor(fixture: b2Fixture, childIndex: number); + Reset(): void; + Touch(): void; + private static Synchronize_s_aabb1; + private static Synchronize_s_aabb2; + private static Synchronize_s_displacement; + Synchronize(transform1: b2Transform, transform2: b2Transform): void; +} +declare class b2Fixture { + m_density: number; + m_next: b2Fixture | null; + readonly m_body: b2Body; + readonly m_shape: b2Shape; + m_friction: number; + m_restitution: number; + m_restitutionThreshold: number; + readonly m_proxies: b2FixtureProxy[]; + get m_proxyCount(): number; + readonly m_filter: b2Filter; + m_isSensor: boolean; + m_userData: any; + constructor(body: b2Body, def: b2IFixtureDef); + Create(allocator: any, body: any, def: any): void; + Destroy(): void; + Reset(): void; + GetType(): b2ShapeType; + GetShape(): b2Shape; + SetSensor(sensor: boolean): void; + IsSensor(): boolean; + SetFilterData(filter: b2Filter): void; + GetFilterData(): Readonly; + Refilter(): void; + GetBody(): b2Body; + GetNext(): b2Fixture | null; + GetUserData(): any; + SetUserData(data: any): void; + TestPoint(p: XY): boolean; + RayCast(output: b2RayCastOutput, input: b2RayCastInput, childIndex: number): boolean; + GetMassData(massData?: b2MassData): b2MassData; + SetDensity(density: number): void; + GetDensity(): number; + GetFriction(): number; + SetFriction(friction: number): void; + GetRestitution(): number; + SetRestitution(restitution: number): void; + GetRestitutionThreshold(): number; + SetRestitutionThreshold(threshold: number): void; + GetAABB(childIndex: number): Readonly; + Dump(log: (format: string, ...args: any[]) => void, bodyIndex: number): void; + CreateProxies(): void; + DestroyProxies(): void; + TouchProxies(): void; + Synchronize(broadPhase: any, transform1: b2Transform, transform2: b2Transform): void; + SynchronizeProxies(transform1: b2Transform, transform2: b2Transform): void; +} + +declare class b2CircleContact extends b2Contact { + static Create(): b2Contact; + static Destroy(contact: b2Contact): void; + Evaluate(manifold: b2Manifold, xfA: b2Transform, xfB: b2Transform): void; +} + +declare class b2PolygonContact extends b2Contact { + static Create(): b2Contact; + static Destroy(contact: b2Contact): void; + Evaluate(manifold: b2Manifold, xfA: b2Transform, xfB: b2Transform): void; +} + +declare class b2PolygonAndCircleContact extends b2Contact { + static Create(): b2Contact; + static Destroy(contact: b2Contact): void; + Evaluate(manifold: b2Manifold, xfA: b2Transform, xfB: b2Transform): void; +} + +declare class b2EdgeAndCircleContact extends b2Contact { + static Create(): b2Contact; + static Destroy(contact: b2Contact): void; + Evaluate(manifold: b2Manifold, xfA: b2Transform, xfB: b2Transform): void; +} + +declare class b2EdgeAndPolygonContact extends b2Contact { + static Create(): b2Contact; + static Destroy(contact: b2Contact): void; + Evaluate(manifold: b2Manifold, xfA: b2Transform, xfB: b2Transform): void; +} + +declare class b2ChainAndCircleContact extends b2Contact { + static Create(): b2Contact; + static Destroy(contact: b2Contact): void; + private static Evaluate_s_edge; + Evaluate(manifold: b2Manifold, xfA: b2Transform, xfB: b2Transform): void; +} + +declare class b2ChainAndPolygonContact extends b2Contact { + static Create(): b2Contact; + static Destroy(contact: b2Contact): void; + private static Evaluate_s_edge; + Evaluate(manifold: b2Manifold, xfA: b2Transform, xfB: b2Transform): void; +} + +declare enum b2StretchingModel { + b2_pbdStretchingModel = 0, + b2_xpbdStretchingModel = 1 +} +declare enum b2BendingModel { + b2_springAngleBendingModel = 0, + b2_pbdAngleBendingModel = 1, + b2_xpbdAngleBendingModel = 2, + b2_pbdDistanceBendingModel = 3, + b2_pbdHeightBendingModel = 4, + b2_pbdTriangleBendingModel = 5 +} +declare class b2RopeTuning { + stretchingModel: b2StretchingModel; + bendingModel: b2BendingModel; + damping: number; + stretchStiffness: number; + stretchHertz: number; + stretchDamping: number; + bendStiffness: number; + bendHertz: number; + bendDamping: number; + isometric: boolean; + fixedEffectiveMass: boolean; + warmStart: boolean; + Copy(other: Readonly): this; +} +declare class b2RopeDef { + readonly position: b2Vec2; + readonly vertices: b2Vec2[]; + count: number; + readonly masses: number[]; + readonly gravity: b2Vec2; + readonly tuning: b2RopeTuning; +} +declare class b2Rope { + private readonly m_position; + private m_count; + private m_stretchCount; + private m_bendCount; + private readonly m_stretchConstraints; + private readonly m_bendConstraints; + private readonly m_bindPositions; + private readonly m_ps; + private readonly m_p0s; + private readonly m_vs; + private readonly m_invMasses; + private readonly m_gravity; + private readonly m_tuning; + Create(def: b2RopeDef): void; + SetTuning(tuning: b2RopeTuning): void; + Step(dt: number, iterations: number, position: Readonly): void; + Reset(position: Readonly): void; + Draw(draw: b2Draw): void; + private SolveStretch_PBD; + private SolveStretch_XPBD; + private SolveBend_PBD_Angle; + private SolveBend_XPBD_Angle; + private SolveBend_PBD_Distance; + private SolveBend_PBD_Height; + private SolveBend_PBD_Triangle; + private ApplyBendForces; +} + +export { RGB, RGBA, XY, XYZ, b2AABB, b2Abs, b2Acos, b2Alloc, b2AngularStiffness, b2AreaJoint, b2AreaJointDef, b2Asin, b2Assert, b2Atan2, b2BendingModel, b2BlockAllocator, b2Body, b2BodyDef, b2BodyType, b2BroadPhase, b2ChainAndCircleContact, b2ChainAndPolygonContact, b2ChainShape, b2CircleContact, b2CircleShape, b2Clamp, b2ClipSegmentToLine, b2ClipVertex, b2CollideCircles, b2CollideEdgeAndCircle, b2CollideEdgeAndPolygon, b2CollidePolygonAndCircle, b2CollidePolygons, b2Color, b2Contact, b2ContactEdge, b2ContactFactory, b2ContactFeature, b2ContactFeatureType, b2ContactFilter, b2ContactID, b2ContactImpulse, b2ContactListener, b2ContactManager, b2ContactPositionConstraint, b2ContactRegister, b2ContactSolver, b2ContactSolverDef, b2ContactVelocityConstraint, b2Cos, b2Counter, b2DegToRad, b2DestructionListener, b2Distance, b2DistanceInput, b2DistanceJoint, b2DistanceJointDef, b2DistanceOutput, b2DistanceProxy, b2Draw, b2DrawFlags, b2DynamicTree, b2EdgeAndCircleContact, b2EdgeAndPolygonContact, b2EdgeShape, b2Filter, b2Fixture, b2FixtureDef, b2FixtureProxy, b2Free, b2FrictionJoint, b2FrictionJointDef, b2GearJoint, b2GearJointDef, b2GetPointStates, b2GrowableStack, b2IAreaJointDef, b2IBodyDef, b2IDistanceJointDef, b2IFilter, b2IFixtureDef, b2IFrictionJointDef, b2IGearJointDef, b2IJointDef, b2IMotorJointDef, b2IMouseJointDef, b2IPrismaticJointDef, b2IPulleyJointDef, b2IRevoluteJointDef, b2IWeldJointDef, b2IWheelJointDef, b2InvSqrt, b2IsPowerOfTwo, b2IsValid, b2Island, b2Jacobian, b2Joint, b2JointDef, b2JointEdge, b2JointType, b2LinearStiffness, b2Log, b2MakeArray, b2MakeNullArray, b2MakeNumberArray, b2Manifold, b2ManifoldPoint, b2ManifoldType, b2MassData, b2Mat22, b2Mat33, b2Max, b2Maybe, b2Min, b2MixFriction, b2MixRestitution, b2MixRestitutionThreshold, b2MotorJoint, b2MotorJointDef, b2MouseJoint, b2MouseJointDef, b2NextPowerOfTwo, b2Pair, b2ParseInt, b2ParseUInt, b2PointState, b2PolygonAndCircleContact, b2PolygonContact, b2PolygonShape, b2Position, b2PositionSolverManifold, b2Pow, b2PrismaticJoint, b2PrismaticJointDef, b2Profile, b2PulleyJoint, b2PulleyJointDef, b2QueryCallback, b2QueryCallbackFunction, b2RadToDeg, b2Random, b2RandomRange, b2RayCastCallback, b2RayCastCallbackFunction, b2RayCastInput, b2RayCastOutput, b2RevoluteJoint, b2RevoluteJointDef, b2Rope, b2RopeDef, b2RopeTuning, b2Rot, b2SeparationFunction, b2SeparationFunctionType, b2Shape, b2ShapeCast, b2ShapeCastInput, b2ShapeCastOutput, b2ShapeType, b2Simplex, b2SimplexCache, b2SimplexVertex, b2Sin, b2SolverData, b2Sq, b2Sqrt, b2StackAllocator, b2StretchingModel, b2Swap, b2Sweep, b2TOIInput, b2TOIOutput, b2TOIOutputState, b2TestOverlapAABB, b2TestOverlapShape, b2TimeOfImpact, b2TimeStep, b2Timer, b2Transform, b2TreeNode, b2TypedColor, b2TypedVec2, b2Vec2, b2Vec2_zero, b2Vec3, b2Velocity, b2VelocityConstraintPoint, b2Version, b2WeldJoint, b2WeldJointDef, b2WheelJoint, b2WheelJointDef, b2World, b2WorldManifold, b2_180_over_pi, b2_aabbExtension, b2_aabbMultiplier, b2_angularSleepTolerance, b2_angularSlop, b2_baumgarte, b2_branch, b2_commit, b2_epsilon, b2_epsilon_sq, b2_gjkCalls, b2_gjkIters, b2_gjkMaxIters, b2_gjk_reset, b2_lengthUnitsPerMeter, b2_linearSleepTolerance, b2_linearSlop, b2_maxAngularCorrection, b2_maxFloat, b2_maxLinearCorrection, b2_maxManifoldPoints, b2_maxPolygonVertices, b2_maxRotation, b2_maxRotationSquared, b2_maxSubSteps, b2_maxTOIContacts, b2_maxTranslation, b2_maxTranslationSquared, b2_minPulleyLength, b2_pi, b2_pi_over_180, b2_polygonRadius, b2_timeToSleep, b2_toiBaumgarte, b2_toiCalls, b2_toiIters, b2_toiMaxIters, b2_toiMaxRootIters, b2_toiMaxTime, b2_toiRootIters, b2_toiTime, b2_toi_reset, b2_two_pi, b2_version, g_blockSolve, get_g_blockSolve, set_g_blockSolve }; diff --git a/examples/layaair/frontend/libs/cannon.d.ts b/examples/layaair/frontend/libs/cannon.d.ts new file mode 100644 index 0000000..2578cc0 --- /dev/null +++ b/examples/layaair/frontend/libs/cannon.d.ts @@ -0,0 +1,1210 @@ +declare module CANNON { + + export interface IAABBOptions { + + upperBound?: Vec3; + lowerBound?: Vec3; + + } + + export class AABB { + + lowerBound: Vec3; + upperBound: Vec3; + + constructor(options?: IAABBOptions); + + clone() : AABB; + setFromPoints(points: Vec3[], position?: Vec3, quaternion?: Quaternion, skinSize?: number): void; + copy(aabb: AABB): void; + extend(aabb: AABB): void; + getCorners( a: Vec3, b: Vec3, c: Vec3, d: Vec3, e: Vec3, f: Vec3, g: Vec3, h: Vec3 ) : void; + overlaps(aabb: AABB): boolean; + toLocalFrame( frame: Transform, target: AABB ) : AABB; + toWorldFrame( frame: Transform, target: AABB ) : AABB; + } + + export class ArrayCollisionMatrix { + + matrix: Mat3[]; + + get(i: number, j: number): number; + set(i: number, j: number, value?: number): void; + reset(): void; + setNumObjects(n: number): void; + + } + + export class Broadphase { + + world: World; + useBoundingBoxes: boolean; + dirty: boolean; + + collisionPairs(world: World, p1: Body[], p2: Body[]): void; + needBroadphaseCollision(bodyA: Body, bodyB: Body): boolean; + intersectionTest(bodyA: Body, bodyB: Body, pairs1: Body[], pairs2: Body[]): void; + doBoundingSphereBroadphase(bodyA: Body, bodyB: Body, pairs1: Body[], pairs2: Body[]): void; + doBoundingBoxBroadphase(bodyA: Body, bodyB: Body, pairs1: Body[], pairs2: Body[]): void; + makePairsUnique(pairs1: Body[], pairs2: Body[]): void; + setWorld(world: World): void; + boundingSphereCheck(bodyA: Body, bodyB: Body): boolean; + aabbQuery(world: World, aabb: AABB, result: Body[]): Body[]; + + } + + export class GridBroadphase extends Broadphase { + + nx: number; + ny: number; + nz: number; + aabbMin: Vec3; + aabbMax: Vec3; + bins: any[]; + + constructor(aabbMin?: Vec3, aabbMax?: Vec3, nx?: number, ny?: number, nz?: number); + + } + + export class NaiveBroadphase extends Broadphase { + } + + export class ObjectCollisionMatrix { + + matrix: number[]; + + get(i: number, j: number): number; + set(i: number, j: number, value: number): void; + reset(): void; + setNumObjects(n: number): void; + + } + + export interface IRayIntersectWorldOptions { + + mode: number; + result: boolean; + skipBackfaces: boolean; + collisionFilterMask: number; + collisionFilterGroup: number; + from: Vec3; + to: Vec3; + callback: Function; + + } + + export class Ray { + + static CLOSEST: number; + static ANY: number; + static ALL: number; + + from: Vec3; + to: Vec3; + precision: number; + checkCollisionResponse: boolean; + callback: Function; + collisionFilterGroup: number; + collisionFilterMask: number; + hasHit: boolean; + mode: number; + result: RaycastResult; + skipBackfaces: boolean; + + constructor(from?: Vec3, to?: Vec3); + + getAABB(result: RaycastResult): void; + intersectBodies(bodies: Body[], result?: RaycastResult): void; + intersectWorld(world: World, options: any): boolean; + + } + + export class RaycastResult { + + rayFromWorld: Vec3; + rayToWorld: Vec3; + hitNormalWorld: Vec3; + hitPointWorld: Vec3; + hitFaceIndex: number; + hasHit: boolean; + shape: Shape; + body: Body; + distance: number; + + abort(): void; + reset(): void; + set(rayFromWorld: Vec3, rayToWorld: Vec3, hitNormalWorld: Vec3, hitPointWorld: Vec3, shape: Shape, body: Body, distance: number): void; + + } + + export class SAPBroadphase extends Broadphase { + + static insertionSortX(a: any[]): any[]; + static insertionSortY(a: any[]): any[]; + static insertionSortZ(a: any[]): any[]; + static checkBounds(bi: Body, bj: Body, axisIndex?: number): boolean; + + axisList: any[]; + world: World; + axisIndex: number; + + constructor(world?: World); + + autoDetectAxis(): void; + aabbQuery(world: World, aabb: AABB, result?: Body[]): Body[]; + + } + + export interface IConstraintOptions { + + collideConnected?: boolean; + wakeUpBodies?: boolean; + + } + + export class Constraint { + + equations: any[]; + bodyA: Body; + bodyB: Body; + id: number; + collideConnected: boolean; + + constructor(bodyA: Body, bodyB: Body, options?: IConstraintOptions); + + update(): void; + disable(): void; + enable(): void; + + } + + export class DistanceConstraint extends Constraint { + + distance: number; + distanceEquation: ContactEquation; + + constructor(bodyA: Body, bodyB: Body, distance?: number, maxForce?: number); + + } + + export interface IHingeConstraintOptions { + + pivotA?: Vec3; + axisA?: Vec3; + pivotB?: Vec3; + axisB?: Vec3; + maxForce?: number; + + } + + export class HingeConstraint extends Constraint { + + axisA: Vec3; + axisB: Vec3; + rotationalEquation1: RotationalEquation; + rotationalEquation2: RotationalEquation; + motorEnabled: boolean; + motorTargetVelocity: number; + motorMinForce: number; + motorMaxForce: number; + motorEquation: RotationalMotorEquation; + + constructor(bodyA: Body, bodyB: Body, options?: IHingeConstraintOptions); + + enableMotor(): void; + disableMotor(): void; + setMotorMaxForce(maxForce: number): void; + setMotorSpeed(speed: number): void; + + } + + export class PointToPointConstraint extends Constraint { + + equationX: ContactEquation; + equationY: ContactEquation; + equationZ: ContactEquation; + pivotA: Vec3; + pivotB: Vec3; + + constructor(bodyA: Body, pivotA: Vec3, bodyB: Body, pivotB: Vec3, maxForce?: number); + + } + + export class ConeTwistConstraint extends PointToPointConstraint { + + coneEquation: ConeEquation; + twistEquation: RotationalEquation; + + constructor(bodyA: Body, bodyB: Body, options?: IHingeConstraintOptions); + + } + + export class LockConstraint extends PointToPointConstraint { + + rotationalEquation1: RotationalEquation; + rotationalEquation2: RotationalEquation; + rotationalEquation3: RotationalEquation; + + constructor(bodyA: Body, bodyB: Body, maxForce?: number); + + } + + export class Equation { + + id: number; + minForce: number; + maxForce: number; + bi: Body; + bj: Body; + a: number; + b: number; + eps: number; + jacobianElementA: JacobianElement; + jacobianElementB: JacobianElement; + enabled: boolean; + + constructor(bi: Body, bj: Body, minForce?: number, maxForce?: number); + + setSpookParams(stiffness: number, relaxation: number, timeStep: number): void; + computeB(a: number, b: number, h: number): number; + computeGq(): number; + computeGW(): number; + computeGWlamda(): number; + computeGiMf(): number; + computeGiMGt(): number; + addToWlamda(deltalambda: number): number; + computeC(): number; + computeInvC( eps: number ): number; + } + + export class FrictionEquation extends Equation { + + constructor(bi: Body, bj: Body, slipForce: number); + + } + + export interface IRotationalEquationOptions { + + axisA?: Vec3; + axisB?: Vec3; + maxForce?: number; + + } + + export class RotationalEquation extends Equation { + + ni: Vec3; + nj: Vec3; + nixnj: Vec3; + njxni: Vec3; + invIi: Mat3; + invIj: Mat3; + relVel: Vec3; + relForce: Vec3; + + constructor(bodyA: Body, bodyB: Body, options?: IRotationalEquationOptions); + + } + + export class RotationalMotorEquation extends Equation { + + axisA: Vec3; + axisB: Vec3; + invLi: Mat3; + invIj: Mat3; + targetVelocity: number; + + constructor(bodyA: Body, bodyB: Body, maxForce?: number); + + } + + export interface IConeEquationOptions { + + axisA?: Vec3; + axisB?: Vec3; + maxForce?: number; + + } + + export class ConeEquation extends Equation { + + angle: number; + + constructor(bodyA: Body, bodyB: Body, options?: IConeEquationOptions); + + } + + export class ContactEquation extends Equation { + + restitution: number; + ri: Vec3; + rj: Vec3; + ni: Vec3; + + constructor(bi: Body, bj: Body); + + getImpactVelocityAlongNormal(): number; + + } + + export interface IContactMaterialOptions { + + friction?: number; + restitution?: number; + contactEquationStiffness?: number; + contactEquationRelaxation?: number; + frictionEquationStiffness?: number; + frictionEquationRelaxation?: number; + + } + + export class ContactMaterial { + + id: number; + materials: Material[]; + friction: number; + restitution: number; + contactEquationStiffness: number; + contactEquationRelaxation: number; + frictionEquationStiffness: number; + frictionEquationRelaxation: number; + + constructor(m1: Material, m2: Material, options?: IContactMaterialOptions); + + } + + export interface IMaterialOptions { + + friction?: number; + restitution?: number; + + } + + export class Material { + + name: string; + id: number; + friction:number; + restitution:number; + + constructor(options?: string|IMaterialOptions); + + } + + export class JacobianElement { + + spatial: Vec3; + rotational: Vec3; + + multiplyElement(element: JacobianElement): number; + multiplyVectors(spacial: Vec3, rotational: Vec3): number; + + } + + export class Mat3 { + + elements: number[]; + + constructor(elements?: number[]); + + identity(): void; + setZero(): void; + setTrace(vec3: Vec3): void; + getTrace(target: Vec3): void; + vmult(v: Vec3, target?: Vec3): Vec3; + smult(s: number): void; + mmult(m: Mat3): Mat3; + scale(v: Vec3, target?: Mat3): Mat3; + solve(b: Vec3, target?: Vec3): Vec3; + e(row: number, column: number, value?: number): number; + copy(source: Mat3): Mat3; + toString(): string; + reverse(target?: Mat3): Mat3; + setRotationFromQuaternion(q: Quaternion): Mat3; + transpose(target?: Mat3): Mat3; + + } + + export class Trimesh extends Shape { + + aabb: AABB; + edges: number[]; + indices: number[]; + normals: number[]; + scale: Vec3; + tree: Octree; + vertices: number[]; + + static computeNormal(va: Vec3, vb: Vec3, vc: Vec3, target: Vec3): void; + static createTorus(radius?: number, tube?: number, radialSegments?: number, tubularSegments?: number, arc?: number): Trimesh; + + constructor(vertices: number[], indices: number[]); + + calculateWorldAABB(pos: Vec3, quat: Quaternion, min: Vec3, max: Vec3): void; + computeLocalAABB(aabb: AABB): void; + getEdgeVector(edgeIndex: number, vectorStore: Vec3): void; + getEdgeVertex(edgeIndex: number, firstOrSecond: number, vertexStore: Vec3): void; + getNormal(i: number, target: Vec3): Vec3; + getTrianglesAABB(aabb: AABB, result: number[]): void; + getTriangleVertices(i: number, a: Vec3, b: Vec3, c: Vec3): void; + getVertex(i: number, out: Vec3): Vec3; + getWorldVertex(i: number, pos: Vec3, quat: Quaternion, out: Vec3): Vec3; + setScale(scale: Vec3): void; + updateAABB(): void; + updateEdges(): void; + updateNormals(): void; + updateTree(): void; + + } + + export class Quaternion { + + x: number; + y: number; + z: number; + w: number; + + constructor(x?: number, y?: number, z?: number, w?: number); + + set(x: number, y: number, z: number, w: number): void; + toString(): string; + toArray(): number[]; + setFromAxisAngle(axis: Vec3, angle: number): void; + toAxisAngle(targetAxis?: Vec3): any[]; + setFromVectors(u: Vec3, v: Vec3): void; + mult(q: Quaternion, target?: Quaternion): Quaternion; + inverse(target?: Quaternion): Quaternion; + conjugate(target?: Quaternion): Quaternion; + normalize(): void; + normalizeFast(): void; + vmult(v: Vec3, target?: Vec3): Vec3; + copy(source: Quaternion): Quaternion; + toEuler(target: Vec3, order?: string): void; + setFromEuler(x: number, y: number, z: number, order?: string): Quaternion; + clone(): Quaternion; + + } + + export class Transform { + + static pointToLocalFrame(position: Vec3, quaternion: Quaternion, worldPoint: Vec3, result?: Vec3): Vec3; + static pointToWorldFrame(position: Vec3, quaternion: Quaternion, localPoint: Vec3, result?: Vec3): Vec3; + static vectorToWorldFrame(quaternion: Quaternion, localVector: Vec3, result: Vec3): Vec3; + static vectorToLocalFrame(position: Vec3, quaternion: Quaternion, worldVector: Vec3, result?: Vec3): Vec3; + + position: Vec3; + quaternion: Quaternion; + + pointToLocal(point: Vec3, result: Vec3): Vec3; + pointToWorld(point: Vec3, result: Vec3): Vec3; + + } + + export class Vec3 { + + static ZERO: Vec3; + static UNIT_X: Vec3; + static UNIT_Y: Vec3; + static UNIT_Z: Vec3; + + x: number; + y: number; + z: number; + + constructor(x?: number, y?: number, z?: number); + + cross(v: Vec3, target?: Vec3): Vec3; + set(x: number, y: number, z: number): Vec3; + setZero(): void; + vadd(v: Vec3, target?: Vec3): Vec3; + vsub(v: Vec3, target?: Vec3): Vec3; + crossmat(): Mat3; + normalize(): number; + unit(target?: Vec3): Vec3; + norm(): number; + norm2(): number; + distanceTo(p: Vec3): number; + distanceSquared(p: Vec3): number; + mult(scalar: number, target?: Vec3): Vec3; + scale(scalar: number, target?: Vec3): Vec3; + dot(v: Vec3): number; + isZero(): boolean; + negate(target?: Vec3): Vec3; + tangents(t1: Vec3, t2: Vec3): void; + toString(): string; + toArray(): number[]; + copy(source: Vec3): Vec3; + length(): number; + lengthSquared(): number; + lerp(v: Vec3, t: number, target?: Vec3): void; + almostEquals(v: Vec3, precision?: number): boolean; + almostZero(precision?: number): boolean; + isAntiparallelTo(v: Vec3, prescision?: number): boolean; + clone(): Vec3; + + } + + export interface IBodyOptions { + + position?: Vec3; + velocity?: Vec3; + angularVelocity?: Vec3; + quaternion?: Quaternion; + mass?: number; + material?: Material; + type?: number; + linearDamping?: number; + angularDamping?: number; + allowSleep?: boolean; + sleepSpeedLimit?: number; + sleepTimeLimit?: number; + collisionFilterGroup?: number; + collisionFilterMask?: number; + fixedRotation?: boolean; + shape?: Shape; + + } + + export class Body extends EventTarget { + + static DYNAMIC: number; + static STATIC: number; + static KINEMATIC: number; + static AWAKE: number; + static SLEEPY: number; + static SLEEPING: number; + static sleepyEvent: IEvent; + static sleepEvent: IEvent; + + id: number; + //miner + layaID:number; + //miner + isTrigger:boolean; + world: World; + preStep: Function; + postStep: Function; + vlambda: Vec3; + collisionFilterGroup: number; + collisionFilterMask: number; + collisionResponse: boolean; + position: Vec3; + previousPosition: Vec3; + initPosition: Vec3; + boundingRadius: number; + velocity: Vec3; + initVelocity: Vec3; + force: Vec3; + mass: number; + invMass: number; + material: Material; + linearDamping: number; + type: number; + allowSleep: boolean; + sleepState: number; + sleepSpeedLimit: number; + sleepTimeLimit: number; + timeLastSleepy: number; + torque: Vec3; + quaternion: Quaternion; + initQuaternion: Quaternion; + angularVelocity: Vec3; + initAngularVelocity: Vec3; + interpolatedPosition: Vec3; + interpolatedQuaternion: Quaternion; + shapes: Shape[]; + shapeOffsets: any[]; + shapeOrientations: any[]; + inertia: Vec3; + invInertia: Vec3; + invInertiaWorld: Mat3; + invMassSolve: number; + invInertiaSolve: Vec3; + invInteriaWorldSolve: Mat3; + fixedRotation: boolean; + angularDamping: number; + aabb: AABB; + aabbNeedsUpdate: boolean; + wlambda: Vec3; + + constructor(options?: IBodyOptions); + + wakeUp(): void; + sleep(): void; + sleepTick(time: number): void; + pointToLocalFrame(worldPoint: Vec3, result?: Vec3): Vec3; + pointToWorldFrame(localPoint: Vec3, result?: Vec3): Vec3; + vectorToLocalFrame(worldPoint: Vec3, result?: Vec3): Vec3; + vectorToWorldFrame(localVector: Vec3, result?: Vec3): Vec3; + addShape(shape: Shape, offset?: Vec3, orientation?: Vec3): void; + computeAABB(): void; + applyForce(force: Vec3, worldPoint: Vec3): void; + applyImpulse(impulse: Vec3, worldPoint: Vec3): void; + applyLocalForce(force: Vec3, localPoint: Vec3): void; + applyLocalImplse(impulse: Vec3, localPoint: Vec3): void; + updateBoundingRadius(): void; + updateMassProperties(): void; + updateInertiaWorld(force: Vec3): void; + updateSolveMassProperties(): void; + getVelocityAtWorldPoint(worldPoint: Vec3, result: Vec3): Vec3; + + } + + export interface IWheelInfoOptions { + + chassisConnectionPointLocal?: Vec3; + chassisConnectionPointWorld?: Vec3; + directionLocal?: Vec3; + directionWorld?: Vec3; + axleLocal?: Vec3; + axleWorld?: Vec3; + suspensionRestLength?: number; + suspensionMaxLength?: number; + radius?: number; + suspensionStiffness?: number; + dampingCompression?: number; + dampingRelaxation?: number; + frictionSlip?: number; + steering?: number; + rotation?: number; + deltaRotation?: number; + rollInfluence?: number; + maxSuspensionForce?: number; + isFrontWheel?: boolean; + clippedInvContactDotSuspension?: number; + suspensionRelativeVelocity?: number; + suspensionForce?: number; + skidInfo?: number; + suspensionLength?: number; + maxSuspensionTravel?: number; + useCustomSlidingRotationalSpeed?: boolean; + customSlidingRotationalSpeed?: number; + + position?: Vec3; + direction?: Vec3; + axis?: Vec3; + body?: Body; + + } + + export class WheelInfo { + + axleLocal: Vec3; + axleWorld: Vec3; + brake: number; + chassisConnectionPointLocal: Vec3; + chassisConnectionPointWorld: Vec3; + clippedInvContactDotSuspension: number; + customSlidingRotationalSpeed: number; + dampingCompression: number; + dampingRelaxation: number; + deltaRotation: number; + directionLocal: Vec3; + directionWorld: Vec3; + engineForce: number; + forwardImpulse: number; + frictionSlip: number; + isFrontWheel: boolean; + isInContact: boolean; + maxSuspensionForce: number; + maxSuspensionTravel: number; + radius: number; + raycastResult: RaycastResult; + rollInfluence: number; + rotation: number; + sideImpulse: number; + skidInfo: number; + sliding: boolean; + steering: number; + suspensionForce: number; + suspensionLength: number; + suspensionMaxLength: number; + suspensionRelativeVelocity: number; + suspensionStiffness: number; + suspensionRestLength: number; + useCustomSlidingRotationalSpeed: boolean; + worldTransform: Transform; + + constructor(options?: IWheelInfoOptions); + + } + + export interface IRaycastVehicleOptions { + + chassisBody?: Body; + indexRightAxis?: number; + indexLeftAxis?: number; + indexUpAxis?: number; + + } + + export class RaycastVehicle { + + chassisBody: Body; + wheelInfos: IWheelInfoOptions[]; + sliding: boolean; + world: World; + iindexRightAxis: number; + indexForwardAxis: number; + indexUpAxis: number; + + constructor(options?: IRaycastVehicleOptions); + + addWheel(options?: IWheelInfoOptions): void; + setSteeringValue(value: number, wheelIndex: number): void; + applyEngineForce(value: number, wheelIndex: number): void; + setBrake(brake: number, wheelIndex: number): void; + addToWorld(world: World): void; + getVehicleAxisWorld(axisIndex: number, result: Vec3): Vec3; + updateVehicle(timeStep: number): void; + updateSuspension(deltaTime: number): void; + updateWheelTransform(wheelIndex: number): void; + removeFromWorld(world: World): void; + getWheelTransformWorld(wheelIndex: number): Transform; + + } + + export interface IRigidVehicleOptions { + + chassisBody: Body; + + } + + export class RigidVehicle { + + wheelBodies: Body[]; + coordinateSystem: Vec3; + chassisBody: Body; + constraints: Constraint[]; + wheelAxes: Vec3[]; + wheelForces: Vec3[]; + + constructor(options?: IRigidVehicleOptions); + + addWheel(options?: IWheelInfoOptions): Body; + setSteeringValue(value: number, wheelIndex: number): void; + setMotorSpeed(value: number, wheelIndex: number): void; + disableMotor(wheelIndex: number): void; + setWheelForce(value: number, wheelIndex: number): void; + applyWheelForce(value: number, wheelIndex: number): void; + addToWorld(world: World): void; + removeFromWorld(world: World): void; + getWheelSpeed(wheelIndex: number): number; + + } + + export class SPHSystem { + + particles: Particle[]; + density: number; + smoothingRadius: number; + speedOfSound: number; + viscosity: number; + eps: number; + pressures: number[]; + densities: number[]; + neighbors: number[]; + + add(particle: Particle): void; + remove(particle: Particle): void; + getNeighbors(particle: Particle, neighbors: Particle[]): void; + update(): void; + w(r: number): number; + gradw(rVec: Vec3, resultVec: Vec3): void; + nablaw(r: number): number; + + } + + export interface ISpringOptions { + + restLength?: number; + stiffness?: number; + damping?: number; + worldAnchorA?: Vec3; + worldAnchorB?: Vec3; + localAnchorA?: Vec3; + localAnchorB?: Vec3; + + } + + export class Spring { + + restLength: number; + stffness: number; + damping: number; + bodyA: Body; + bodyB: Body; + localAnchorA: Vec3; + localAnchorB: Vec3; + + constructor(options?: ISpringOptions); + + setWorldAnchorA(worldAnchorA: Vec3): void; + setWorldAnchorB(worldAnchorB: Vec3): void; + getWorldAnchorA(result: Vec3): void; + getWorldAnchorB(result: Vec3): void; + applyForce(): void; + + } + + export class Box extends Shape { + + static calculateInertia(halfExtents: Vec3, mass: number, target: Vec3): void; + + halfExtents: Vec3; + convexPolyhedronRepresentation: ConvexPolyhedron; + + constructor(halfExtents: Vec3); + + updateConvexPolyhedronRepresentation(): void; + getSideNormals(sixTargetVectors: boolean, quat?: Quaternion): Vec3[]; + forEachWorldCorner(pos: Vec3, quat: Quaternion, callback: Function): void; + + } + + export class ConvexPolyhedron extends Shape { + + static computeNormal(va: Vec3, vb: Vec3, vc: Vec3, target: Vec3): void; + static project(hull: ConvexPolyhedron, axis: Vec3, pos: Vec3, quat: Quaternion, result: number[]): void; + static getFaceNormal(va: Vec3, vb: Vec3, vc: Vec3, target: Vec3): void; + + vertices: Vec3[]; + worldVertices: Vec3[]; + worldVerticesNeedsUpdate: boolean; + faces: number[]; + faceNormals: Vec3[]; + uniqueEdges: Vec3[]; + uniqueAxes: Vec3[]; + + constructor(points?: Vec3[], faces?: number[]); + + computeEdges(): void; + computeNormals(): void; + getFaceNormal(i: number, target: Vec3): Vec3; + clipAgainstHull(posA: Vec3, quatA: Quaternion, hullB: Vec3, quatB: Quaternion, separatingNormal: Vec3, minDist: number, maxDist: number, result: any[]): void; + findSeparatingAxis(hullB: ConvexPolyhedron, posA: Vec3, quatA: Quaternion, posB: Vec3, quatB: Quaternion, target: Vec3, faceListA: any[], faceListB: any[]): boolean; + testSepAxis(axis: Vec3, hullB: ConvexPolyhedron, posA: Vec3, quatA: Quaternion, posB: Vec3, quatB: Quaternion): number; + getPlaneConstantOfFace(face_i: number): number; + clipFaceAgainstHull(separatingNormal: Vec3, posA: Vec3, quatA: Quaternion, worldVertsB1: Vec3[], minDist: number, maxDist: number, result: any[]): void; + clipFaceAgainstPlane(inVertices: Vec3[], outVertices: Vec3[], planeNormal: Vec3, planeConstant: number): Vec3; + computeWorldVertices(position: Vec3, quat: Quaternion): void; + computeLocalAABB(aabbmin: Vec3, aabbmax: Vec3): void; + computeWorldFaceNormals(quat: Quaternion): void; + calculateWorldAABB(pos: Vec3, quat: Quaternion, min: Vec3, max: Vec3): void; + getAveragePointLocal(target: Vec3): Vec3; + transformAllPoints(offset: Vec3, quat: Quaternion): void; + pointIsInside(p: Vec3): boolean; + + } + + export class Cylinder extends ConvexPolyhedron { + + constructor(radiusTop: number, radiusBottom: number, height: number, numSegments: number); + + } + + export interface IHightfieldOptions { + + minValue?: number; + maxValue?: number; + elementSize: number; + + } + + export class Heightfield extends Shape { + + data: number[]; + maxValue: number; + minValue: number; + elementSize: number; + cacheEnabled: boolean; + pillarConvex: ConvexPolyhedron; + pillarOffset: Vec3; + type: number; + + constructor(data: number[], options?: IHightfieldOptions); + + update(): void; + updateMinValue(): void; + updateMaxValue(): void; + setHeightValueAtIndex(xi: number, yi: number, value: number): void; + getRectMinMax(iMinX: number, iMinY: number, iMaxX: number, iMaxY: number, result: any[]): void; + getIndexOfPosition(x: number, y: number, result: any[], clamp: boolean): boolean; + getConvexTrianglePillar(xi: number, yi: number, getUpperTriangle: boolean): void; + + } + + export class Particle extends Shape { + + } + + export class Plane extends Shape { + + worldNormal: Vec3; + worldNormalNeedsUpdate: boolean; + boundingSphereRadius: number; + + computeWorldNormal(quat: Quaternion): void; + calculateWorldAABB(pos: Vec3, quat: Quaternion, min: number, max: number): void; + + } + + export class Shape { + + static types: { + + SPHERE: number; + PLANE: number; + BOX: number; + COMPOUND: number; + CONVEXPOLYHEDRON: number; + HEIGHTFIELD: number; + PARTICLE: number; + CYLINDER: number; + + } + + id: number; + type: number; + boundingSphereRadius: number; + collisionResponse: boolean; + + updateBoundingSphereRadius(): number; + volume(): number; + calculateLocalInertia(mass: number, target?: Vec3): Vec3; + + } + + export class Sphere extends Shape { + + radius: number; + + constructor(radius: number); + + } + + export class GSSolver extends Solver { + + iterations: number; + tolerance: number; + + solve(dy: number, world: World): number; + + + } + + export class Solver { + + equations: Equation[]; + + solve(dy: number, world: World): number; + addEquation(eq: Equation): void; + removeEquation(eq: Equation): void; + removeAllEquations(): void; + + } + + export class SplitSolver extends Solver { + + subsolver: Solver; + + constructor(subsolver: Solver); + + solve(dy: number, world: World): number; + + } + + export class EventTarget { + + addEventListener(type: string, listener: Function): EventTarget; + hasEventListener(type: string, listener: Function): boolean; + removeEventListener(type: string, listener: Function): EventTarget; + dispatchEvent(event: IEvent): IEvent; + + } + + export class Pool { + + objects: any[]; + type: any[]; + + release(): any; + get(): any; + constructObject(): any; + + } + + export class TupleDictionary { + + data: { + keys: any[]; + }; + + get(i: number, j: number): number; + set(i: number, j: number, value: number): void; + reset(): void; + + } + + export class Utils { + + static defaults(options?: any, defaults?: any): any; + + } + + export class Vec3Pool extends Pool { + + static defaults(options: Object, defaults: Object): Object; + + constructObject(): Vec3; + + } + + export class NarrowPhase { + + contactPointPool: Pool[]; + enableFrictionReduction: boolean; + v3pool: Vec3Pool; + + convexHeightfield(convexShape: Shape, hfShape: Heightfield, convexPos: Vec3, hfPos: Vec3, convexQuat: Quaternion, hfQuat: Quaternion, convexBody: Body, hfBody: Body): void; + convexConvex(si: Shape, sj: Shape, xi: Vec3, xj: Vec3, qi: Quaternion, qj: Quaternion, bi: Body, bj: Body): void; + convexParticle(result: ContactEquation[], si: Shape, sj: Shape, xi: Vec3, xj: Vec3, qi: Quaternion, qj: Quaternion, bi: Body, bj: Body): void; + convexTrimesh( result: ContactEquation[], si: Shape, sj: Shape, xi: Vec3, xj: Vec3, qi: Quaternion, qj: Quaternion, bi: Body, bj: Body): void; + createContactEquation(bi: Body, bj: Body, si: Shape, sj: Shape, rsi: Shape, rsj: Shape): ContactEquation; + getContacts(p1: Body[], p2: Body[], world: World, result: ContactEquation[], oldcontacts: ContactEquation[]): void; + particlePlane( result: ContactEquation[], si: Shape, sj: Shape, xi: Vec3, xj: Vec3, qi: Quaternion, qj: Quaternion, bi: Body, bj: Body): void; + particleSphere(result: ContactEquation[], si: Shape, sj: Shape, xi: Vec3, xj: Vec3, qi: Quaternion, qj: Quaternion, bi: Body, bj: Body): void; + planeBox(result: ContactEquation[], si: Shape, sj: Shape, xi: Vec3, xj: Vec3, qi: Quaternion, qj: Quaternion, bi: Body, bj: Body): void; + planeConvex(si: Shape, sj: Shape, xi: Vec3, xj: Vec3, qi: Quaternion, qj: Quaternion, bi: Body, bj: Body): void; + planeTrimesh(si: Shape, sj: Shape, xi: Vec3, xj: Vec3, qi: Quaternion, qj: Quaternion, bi: Body, bj: Body): void; + sphereBox(si: Shape, sj: Shape, xi: Vec3, xj: Vec3, qi: Quaternion, qj: Quaternion, bi: Body, bj: Body): void; + sphereConvex(si: Shape, sj: Shape, xi: Vec3, xj: Vec3, qi: Quaternion, qj: Quaternion, bi: Body, bj: Body): void; + sphereHeightfield(sphereShape: Shape, hfShape: Heightfield, spherePos: Vec3, hfPos: Vec3, sphereQuat: Quaternion, hfQuat: Quaternion, sphereBody: Body, hfBody: Body): void; + spherePlane( si: Shape, sj: Shape, xi: Vec3, xj: Vec3, qi: Quaternion, qj: Quaternion, bi: Body, bj: Body): void; + sphereSphere(si: Shape, sj: Shape, xi: Vec3, xj: Vec3, qi: Quaternion, qj: Quaternion, bi: Body, bj: Body): void; + sphereTrimesh(sphereShape: Shape, trimeshShape: Shape, spherePos: Vec3, trimeshPos: Vec3, sphereQuat: Quaternion, trimeshQuat: Quaternion, sphereBody: Body, trimeshBody: Body): void; + + } + + export interface IOctreeOptions { + + root: Octree; + aabb: AABB; + + } + + export class OctreeNode { + + aabb: AABB; + children: Octree[]; + data: number[]; + root: OctreeNode; + + } + + export class Octree extends OctreeNode { + + maxDepth: number; + + constructor(aabb: AABB, options: IOctreeOptions); + + aabbQuery(aabb: AABB, result: Object[]): Object[]; + insert(aabb: AABB, elementData: Object): boolean; + rayQuery(ray: Ray, treeTransform: Transform, result: Object[]): Object[]; + removeEmptyNodes(): void; + subdivide(): void; + + } + + export interface IWorld { + + collisisonFilterMask?: number; + collisionFilterGroup?: number; + skipBackfaces?: boolean; + checkCollisionResponse?: boolean; + + } + + export class World extends EventTarget { + + dt: number; + allowSleep: boolean; + contacts: ContactEquation[]; + frictionEquations: FrictionEquation[]; + quatNormalizeSkip: number; + quatNormalizeFast: boolean; + time: number; + stepnumber: number; + default_dt: number; + nextId: number; + gravity: Vec3; + broadphase: NaiveBroadphase; + bodies: Body[]; + //miner + allContacts:ContactEquation[]; + callBackBody:Body[]; + solver: Solver; + constraints: Constraint[]; + narrowPhase: NarrowPhase; + collisionMatrix: ArrayCollisionMatrix; + collisionMatrixPrevious: ArrayCollisionMatrix; + materials: Material[]; + contactMaterials: ContactMaterial[]; + contactMaterialTable: TupleDictionary; + defaultMaterial: Material; + defaultContactMaterial: ContactMaterial; + doProfiling: boolean; + profile: { + solve: number; + makeContactConstraints: number; + broadphaser: number; + integrate: number; + narrowphase: number; + }; + subsystems: any[]; + addBodyEvent: IBodyEvent; + removeBodyEvent: IBodyEvent; + + addBody(body: Body): void; + addConstraint(c: Constraint): void; + addContactMaterial(cmat: ContactMaterial): void; + addEventListener(type: string, listener: Function): EventTarget; + addMaterial(m: Material): void; + clearForces(): void; + collisionMatrixTick(): void; + getContactMaterial(m1: Material, m2: Material): ContactMaterial; + numObjects(): number; + raycastAll(from: Vec3, to: Vec3, options: IWorld, callback: Function): boolean; + raycastAny(from: Vec3, to: Vec3, options: IWorld, result: RaycastResult): boolean; + raycastClosest(from: Vec3, to: Vec3, options: IWorld, result: RaycastResult): boolean; + rayTest(from: Vec3, to: Vec3, result: RaycastResult): void; + remove(body: Body): void; + removeBody(body: Body): void; + removeConstraint(c: Constraint): void; + removeEventListener(type: string, listener: Function): EventTarget; + step(dy: number, timeSinceLastCalled?: number, maxSubSteps?: number): void; + + } + + export interface IEvent { + + type: string; + + } + + export interface IBodyEvent extends IEvent { + + body: Body; + + } + + export class Demo { + + constructor( options: Object ); + + addScene( title: string, initfunc: Function ): void; + restartCurrentScene(): void; + + } + +} \ No newline at end of file diff --git a/examples/layaair/frontend/libs/glsl.d.ts b/examples/layaair/frontend/libs/glsl.d.ts new file mode 100644 index 0000000..f391e69 --- /dev/null +++ b/examples/layaair/frontend/libs/glsl.d.ts @@ -0,0 +1,14 @@ +declare module '*.glsl' { + const value: string + export default value +} + +declare module '*.vs' { + const value: string + export default value +} + +declare module '*.fs' { + const value: string + export default value +} \ No newline at end of file diff --git a/examples/layaair/frontend/libs/hbs.d.ts b/examples/layaair/frontend/libs/hbs.d.ts new file mode 100644 index 0000000..fa047b7 --- /dev/null +++ b/examples/layaair/frontend/libs/hbs.d.ts @@ -0,0 +1,5956 @@ + +interface CanvasContext { + /** + * 创建一个颜色的渐变点。 + */ + addColorStop: () => void; + + /** + * 画一条弧线。 + */ + arc: () => void; + + /** + * 开始创建一个路径,需要调用fill或者stroke才会使用路径进行填充或描边。 + */ + beginPath: () => void; + + /** + * 创建三次方贝塞尔曲线路径。 + */ + bezierCurveTo: () => void; + + /** + * 清空绘图上下文的绘图动作。 + */ + clearActions: () => void; + + /** + * 清除画布上在该矩形区域内的内容。 + */ + clearRect: () => void; + + /** + * clip() 方法从原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内(不能访问画布上的其他区域)。可以在使用 clip() 方法前通过使用 save() 方法对当前画布区域进行保存,并在以后的任意时间对其进行恢复(通过 restore() 方法)。 + */ + clip: () => void; + + /** + * 关闭一个路径 + */ + closePath: () => void; + + /** + * 创建一个圆形的渐变颜色。 + */ + createCircularGradient: () => void; + + /** + * 创建一个线性的渐变颜色。 + */ + createLinearGradient: () => void; + + /** + * 将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中。 + */ + draw: () => void; + + /** + * 绘制图像到画布。 + */ + drawImage: () => void; + + /** + * 对当前路径中的内容进行填充。默认的填充色为黑色。 + */ + fill: () => void; + + /** + * 填充一个矩形。 + */ + fillRect: () => void; + + /** + * 在画布上绘制被填充的文本。 + */ + fillText: () => void; + + /** + * const ctx = hbs.createCanvasContext('myCanvas') + */ + lineTo: () => void; + + /** + * 把路径移动到画布中的指定点,不创建线条。 + */ + moveTo: () => void; + + /** + * 创建二次贝塞尔曲线路径。 + */ + quadraticCurveTo: () => void; + + /** + * 创建一个矩形。 + */ + rect: () => void; + + /** + * 以原点为中心,原点可以用 [translate](#translate)方法修改。顺时针旋转当前坐标轴。多次调用`rotate`,旋转的角度会叠加。 + */ + rotate: () => void; + + /** + * 保存当前的绘图上下文。 + */ + save: () => void; + + /** + * 在调用`scale`方法后,之后创建的路径其横纵坐标会被缩放。多次调用`scale`,倍数会相乘。 + */ + scale: () => void; + + /** + * 设置填充色。 + */ + setFillStyle: () => void; + + /** + * 设置字体的字号。 + */ + setFontSize: () => void; + + /** + * 设置全局画笔透明度。 + */ + setGlobalAlpha: () => void; + + /** + * 设置线条的端点样式。 + */ + setLineCap: () => void; + + /** + * 设置线条的宽度。 + */ + setLineDash: () => void; + + /** + * 设置线条的交点样式。 + */ + setLineJoin: () => void; + + /** + * 设置线条的宽度。 + */ + setLineWidth: () => void; + + /** + * 设置最大斜接长度,斜接长度指的是在两条线交汇处内角和外角之间的距离。 当 `setLineJoin()` 为 miter 时才有效。超过最大倾斜长度的,连接处将以 lineJoin 为 bevel 来显示 + */ + setMiterLimit: () => void; + + /** + * 设置阴影样式。 + */ + setShadow: () => void; + + /** + * 设置边框颜色。 + */ + setStrokeStyle: () => void; + + /** + * 用于设置文字的对齐 + */ + setTextAlign: () => void; + + /** + * 用于设置文字的水平对齐 + */ + setTextBaseline: () => void; + + /** + * 画出当前路径的边框。默认颜色色为黑色。 + */ + stroke: () => void; + + /** + * 画一个矩形(非填充)。 + */ + strokeRect: () => void; + + /** + * 对当前坐标系的原点(0, 0)进行变换,默认的坐标系原点为页面左上角。 + */ + translate: () => void; + } + + interface _writeBLECharacteristicValueObject { + /** + * 蓝牙设备 id,参考 device 对象 + */ + deviceId: string; + + /** + * 蓝牙特征值对应服务的 uuid + */ + serviceId: string; + + /** + * 蓝牙特征值的 uuid + */ + characteristicId: string; + + /** + * 蓝牙设备特征值对应的二进制值 + */ + value: any; + + /** + * 成功则返回本机蓝牙适配器状态 + */ + success: (result: _writeBLECharacteristicValueSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + + interface _writeBLECharacteristicValueSuccessObject { + /** + * 成功:ok,错误:详细信息 + */ + errMsg: string; + } + + interface _vibrateShortObject { + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _vibrateLongObject { + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _uploadFileObject { + /** + * 开发者服务器 url + */ + url: string; + + /** + * 要上传文件资源的路径 + */ + filePath: string; + + /** + * 文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容 + */ + name: string; + + /** + * HTTP 请求 Header, header 中不能设置 Referer + */ + header: object; + + /** + * HTTP 请求中其他额外的 form data + */ + formData: object; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _uploadFileSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _uploadFileSuccessObject { + /** + * 开发者服务器返回的数据 + */ + data: string; + + /** + * 开发者服务器返回的 HTTP 状态码 + */ + statusCode: number; + } + + interface _updateShareMenuObject { + /** + * 是否使用带 shareTicket 的转发[详情](./share.md#获取更多转发信息) + */ + withShareTicket: boolean; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _switchTabObject { + /** + * 需要跳转的 tabBar 页面的路径(需在 app.json 的 [tabBar](../framework/config.md#tabbar) 字段定义的页面),路径后不能带参数 + */ + url: string; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _stopWifiObject { + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _stopHCEObject { + /** + * 接口调用成功的回调函数 + */ + success: (result: _stopHCESuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _stopHCESuccessObject { + /** + * 错误信息 + */ + errMsg: string; + + /** + * 错误码 + */ + errCode: number; + } + + interface _stopCompassObject { + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _stopBluetoothDevicesDiscoveryObject { + /** + * 成功则返回本机蓝牙适配器状态 + */ + success: (result: _stopBluetoothDevicesDiscoverySuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _stopBluetoothDevicesDiscoverySuccessObject { + /** + * 成功:ok,错误:详细信息 + */ + errMsg: string; + } + + interface _stopBeaconDiscoveryObject { + /** + * 接口调用成功的回调函数 + */ + success: (result: _stopBeaconDiscoverySuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _stopBeaconDiscoverySuccessObject { + /** + * 调用结果 + */ + errMsg: string; + } + + interface _stopAccelerometerObject { + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _startWifiObject { + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _startSoterAuthenticationObject { + /** + * 请求使用的可接受的生物认证方式 + */ + requestAuthModes: any; + + /** + * 挑战因子。挑战因子为调用者为此次生物鉴权准备的用于签名的字符串关键是别信息,将作为result_json的一部分,供调用者识别本次请求。例如:如果场景为请求用户对某订单进行授权确认,则可以将订单号填入此参数。 + */ + challenge: string; + + /** + * 验证描述,即识别过程中显示在界面上的对话框提示内容 + */ + authContent: string; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _startSoterAuthenticationSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _startSoterAuthenticationSuccessObject { + /** + * 错误码 + */ + errCode: number; + + /** + * 生物认证方式 + */ + authMode: string; + + /** + * 在设备安全区域(TEE)内获得的本机安全信息(如TEE名称版本号等以及防重放参数)以及本次认证信息(仅Android支持,本次认证的指纹ID)(仅Android支持,本次认证的指纹ID) + */ + resultJSON: string; + + /** + * 用SOTER安全密钥对result_json的签名(SHA256withRSA/PSS, saltlen=20) + */ + resultJSONSignature: string; + + /** + * 接口调用结果 + */ + errMsg: string; + } + + interface _startRecordObject { + /** + * 录音成功后调用,返回录音文件的临时文件路径,res = {tempFilePath: '录音文件的临时路径'} + */ + success: (result: _startRecordSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _startRecordSuccessObject { + /** + * 录音文件的临时路径 + */ + tempFilePath: any; + } + + interface _startPullDownRefreshObject { + /** + * 接口调用成功的回调函数 + */ + success: (result: _startPullDownRefreshSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _startPullDownRefreshSuccessObject { + /** + * 接口调用结果 + */ + errMsg: string; + } + + interface _startHCEObject { + /** + * 需要注册到系统的 AID 列表,每个 AID 为 String 类型 + */ + aid_list: any; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _startHCESuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _startHCESuccessObject { + /** + * 错误信息 + */ + errMsg: string; + + /** + * 错误码 + */ + errCode: number; + } + + interface _startCompassObject { + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _startBluetoothDevicesDiscoveryObject { + /** + * 蓝牙设备主 service 的 uuid 列表 + */ + services: any; + + /** + * 是否允许重复上报同一设备, 如果允许重复上报,则onDeviceFound 方法会多次上报同一设备,但是 RSSI 值会有不同 + */ + allowDuplicatesKey: boolean; + + /** + * 上报设备的间隔,默认为0,意思是找到新设备立即上报,否则根据传入的间隔上报 + */ + interval: number; + + /** + * 成功则返回本机蓝牙适配器状态 + */ + success: (result: _startBluetoothDevicesDiscoverySuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _startBluetoothDevicesDiscoverySuccessObject { + /** + * 成功:ok,错误:详细信息 + */ + errMsg: string; + } + + interface _startBeaconDiscoveryObject { + /** + * iBeacon设备广播的 uuids + */ + uuids: any; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _startBeaconDiscoverySuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _startBeaconDiscoverySuccessObject { + /** + * 调用结果 + */ + errMsg: string; + } + + interface _startAccelerometerObject { + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _showToastObject { + /** + * 提示的内容 + */ + title: string; + + /** + * 图标,有效值 "success", "loading", "none" + */ + icon: string; + + /** + * 自定义图标的本地路径,image 的优先级高于 icon + */ + image: string; + + /** + * 提示的延迟时间,单位毫秒,默认:1500 + */ + duration: number; + + /** + * 是否显示透明蒙层,防止触摸穿透,默认:false + */ + mask: boolean; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _showTabBarRedDotObject { + /** + * tabBar的哪一项,从左边算起 + */ + index: number; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _showTabBarObject { + /** + * 是否需要动画效果,默认无 + */ + aniamtion: boolean; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _showShareMenuObject { + /** + * 是否使用带 shareTicket 的转发[详情](./share.md#获取更多转发信息) + */ + withShareTicket: boolean; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _showModalObject { + /** + * 提示的标题 + */ + title: string; + + /** + * 提示的内容 + */ + content: string; + + /** + * 是否显示取消按钮,默认为 true + */ + showCancel: boolean; + + /** + * 取消按钮的文字,默认为"取消",最多 4 个字符 + */ + cancelText: string; + + /** + * 取消按钮的文字颜色,默认为"#000000" + */ + cancelColor: any; + + /** + * 确定按钮的文字,默认为"确定",最多 4 个字符 + */ + confirmText: string; + + /** + * 确定按钮的文字颜色,默认为"#3CC51F" + */ + confirmColor: any; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _showModalSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _showModalSuccessObject { + /** + * 为 true 时,表示用户点击了确定按钮 + */ + confirm: boolean; + + /** + * 为 true 时,表示用户点击了取消(用于 Android 系统区分点击蒙层关闭还是点击取消按钮关闭) + */ + cancel: boolean; + } + + interface _showLoadingObject { + /** + * 提示的内容 + */ + title: string; + + /** + * 是否显示透明蒙层,防止触摸穿透,默认:false + */ + mask: boolean; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _showActionSheetObject { + /** + * 按钮的文字数组,数组长度最大为6个 + */ + itemList: any; + + /** + * 按钮的文字颜色,默认为"#000000" + */ + itemColor: any; + + /** + * 接口调用成功的回调函数,详见返回参数说明 + */ + success: (result: _showActionSheetSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _showActionSheetSuccessObject { + /** + * 用户点击的按钮,从上到下的顺序,从0开始 + */ + tapIndex: number; + } + + interface _setWifiListObject { + /** + * 提供预设的 Wi-Fi 信息列表 + */ + wifiList: any; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _setTopBarTextObject { + /** + * 置顶栏文字内容 + */ + text: string; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _setTabBarStyleObject { + /** + * tab 上的文字默认颜色 + */ + color: any; + + /** + * tab 上的文字选中时的颜色 + */ + selectedColor: any; + + /** + * tab 的背景色 + */ + backgroundColor: any; + + /** + * tabbar上边框的颜色, 仅支持 black/white + */ + borderStyle: string; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _setTabBarItemObject { + /** + * tabBar 的哪一项,从左边算起 + */ + index: number; + + /** + * tab 上按钮文字 + */ + text: string; + + /** + * 图片路径,icon 大小限制为40kb,建议尺寸为 81px * 81px,当 postion 为 top 时,此参数无效,不支持网络图片 + */ + iconPath: string; + + /** + * 选中时的图片路径,icon 大小限制为40kb,建议尺寸为 81px * 81px ,当 postion 为 top 时,此参数无效 + */ + selectedIconPath: string; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _setTabBarBadgeObject { + /** + * tabBar的哪一项,从左边算起 + */ + index: number; + + /** + * 显示的文本,超过 3 个字符则显示成“…” + */ + text: string; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _setStorageObject { + /** + * 本地缓存中的指定的 key + */ + key: string; + + /** + * 需要存储的内容 + */ + data: any; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _setScreenBrightnessObject { + /** + * 屏幕亮度值,范围 0~1,0 最暗,1 最亮 + */ + value: number; + + /** + * 接口调用成功 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _setNavigationBarTitleObject { + /** + * 页面标题 + */ + title: string; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _setNavigationBarColorObject { + /** + * 前景颜色值,包括按钮、标题、状态栏的颜色,仅支持 #ffffff 和 #000000 + */ + frontColor: string; + + /** + * 背景颜色值,有效值为十六进制颜色 + */ + backgroundColor: string; + + /** + * 动画效果 + */ + animation: object; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _setNavigationBarColorSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _setNavigationBarColorSuccessObject { + /** + * 调用结果 + */ + errMsg: string; + } + + interface _setKeepScreenOnObject { + /** + * 是否保持屏幕常亮 + */ + keepScreenOn: boolean; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _setKeepScreenOnSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _setKeepScreenOnSuccessObject { + /** + * 调用结果 + */ + errMsg: string; + } + + interface _setEnableDebugObject { + /** + * 是否打开调试 + */ + enableDebug: boolean; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _setEnableDebugSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _setEnableDebugSuccessObject { + /** + * 调用结果 + */ + errMsg: string; + } + + interface _setClipboardDataObject { + /** + * 需要设置的内容 + */ + data: string; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _sendSocketMessageObject { + /** + * 需要发送的内容 + */ + data: any; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _sendHCEMessageObject { + /** + * 二进制数据 + */ + data: any; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _sendHCEMessageSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _sendHCEMessageSuccessObject { + /** + * 错误信息 + */ + errMsg: string; + + /** + * 错误码 + */ + errCode: number; + } + + interface _seekBackgroundAudioObject { + /** + * 音乐位置,单位:秒 + */ + position: number; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _scanCodeObject { + /** + * 是否只能从相机扫码,不允许从相册选择图片 + */ + onlyFromCamera: boolean; + + /** + * 扫码类型,参数类型是数组,二维码是'qrCode',一维码是'barCode',DataMatrix是‘datamatrix’,pdf417是‘pdf417’。 + */ + scanType: any; + + /** + * 接口调用成功的回调函数,返回内容详见返回参数说明。 + */ + success: (result: _scanCodeSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _scanCodeSuccessObject { + /** + * 所扫码的内容 + */ + result: any; + + /** + * 所扫码的类型 + */ + scanType: any; + + /** + * 所扫码的字符集 + */ + charSet: any; + + /** + * 当所扫的码为当前小程序的合法二维码时,会返回此字段,内容为二维码携带的 path + */ + path: any; + } + + interface _saveVideoToPhotosAlbumObject { + /** + * 视频文件路径,可以是临时文件路径也可以是永久文件路径 + */ + filePath: string; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _saveVideoToPhotosAlbumSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _saveVideoToPhotosAlbumSuccessObject { + /** + * 调用结果 + */ + errMsg: string; + } + + interface _saveImageToPhotosAlbumObject { + /** + * 图片文件路径,可以是临时文件路径也可以是永久文件路径,不支持网络图片路径 + */ + filePath: string; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _saveImageToPhotosAlbumSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _saveImageToPhotosAlbumSuccessObject { + /** + * 调用结果 + */ + errMsg: string; + } + + interface _saveFileObject { + /** + * 需要保存的文件的临时路径 + */ + tempFilePath: string; + + /** + * 返回文件的保存路径,res = {savedFilePath: '文件的保存路径'} + */ + success: (result: _saveFileSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _saveFileSuccessObject { + /** + * 文件的保存路径 + */ + savedFilePath: any; + } + + interface _requestPaymentObject { + /** + * 时间戳从1970年1月1日00:00:00至今的秒数,即当前的时间 + */ + timeStamp: string; + + /** + * 随机字符串,长度为32个字符以下。 + */ + nonceStr: string; + + /** + * 统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*** + */ + package: string; + + /** + * 签名算法,暂支持 MD5 + */ + signType: string; + + /** + * 签名,具体签名方案参见[小程序支付接口文档](https://pay.weixin.qq.com/wiki/doc/api/hbsa/hbsa_api.php?chapter=7_7&index=3); + */ + paySign: string; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _requestObject { + /** + * 开发者服务器接口地址 + */ + url: string; + + /** + * 请求的参数 + */ + data: any; + + /** + * 设置请求的 header,header 中不能设置 Referer。 + */ + header: object; + + /** + * (需大写)有效值:OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT + */ + method: string; + + /** + * 如果设为json,会尝试对返回的数据做一次 JSON.parse + */ + dataType: string; + + /** + * 设置响应的数据类型。合法值:text、arraybuffer + */ + responseType: string; + + /** + * 收到开发者服务成功返回的回调函数 + */ + success: (result: _requestSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _requestSuccessObject { + /** + * 开发者服务器返回的数据 + */ + data: any; + + /** + * 开发者服务器返回的 HTTP 状态码 + */ + statusCode: number; + + /** + * 开发者服务器返回的 HTTP Response Header + */ + header: object; + } + + interface _removeTabBarBadgeObject { + /** + * tabBar的哪一项,从左边算起 + */ + index: number; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _removeStorageObject { + /** + * 本地缓存中的指定的 key + */ + key: string; + + /** + * 接口调用的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _removeSavedFileObject { + /** + * 需要删除的文件路径 + */ + filePath: string; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _redirectToObject { + /** + * 需要跳转的应用内非 tabBar 的页面的路径,路径后可以带参数。参数与路径之间使用`?`分隔,参数键与参数值用`=`相连,不同参数用`&`分隔;如 'path?key=value&key2=value2' + */ + url: string; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _readBLECharacteristicValueObject { + /** + * 蓝牙设备 id,参考 device 对象 + */ + deviceId: string; + + /** + * 蓝牙特征值对应服务的 uuid + */ + serviceId: string; + + /** + * 蓝牙特征值的 uuid + */ + characteristicId: string; + + /** + * 成功则返回本机蓝牙适配器状态 + */ + success: (result: _readBLECharacteristicValueSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _readBLECharacteristicValueSuccessObject { + /** + * 错误码 + */ + errCode: number; + + /** + * 成功:ok,错误:详细信息 + */ + errMsg: string; + } + + interface _reLaunchObject { + /** + * 需要跳转的应用内页面路径 , 路径后可以带参数。参数与路径之间使用`?`分隔,参数键与参数值用`=`相连,不同参数用`&`分隔;如 'path?key=value&key2=value2',如果跳转的页面路径是 tabBar 页面则不能带参数 + */ + url: string; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _previewImageObject { + /** + * 当前显示图片的链接,不填则默认为 urls 的第一张 + */ + current: string; + + /** + * 需要预览的图片链接列表 + */ + urls: any; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _playVoiceObject { + /** + * 需要播放的语音文件的文件路径 + */ + filePath: string; + + /** + * 指定录音时长,到达指定的录音时长后会自动停止录音,单位:秒,默认值:60 + */ + duration: number; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _playBackgroundAudioObject { + /** + * 音乐链接,目前支持的格式有 m4a, aac, mp3, wav + */ + dataUrl: string; + + /** + * 音乐标题 + */ + title: string; + + /** + * 封面URL + */ + coverImgUrl: string; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _pageScrollToObject { + /** + * 滚动到页面的目标位置(单位px) + */ + scrollTop: number; + + /** + * 滚动动画的时长,默认300ms,单位 ms + */ + duration: number; + } + interface _openSettingObject { + /** + * 接口调用成功的回调函数,返回内容详见返回参数说明。 + */ + success: (result: _openSettingSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _openSettingSuccessObject { + /** + * 用户授权结果,其中 key 为 scope 值,value 为 Bool 值,表示用户是否允许授权,详见 [scope 列表](./authorize-index.md#scope-列表) + */ + authSetting: object; + } + + interface _openLocationObject { + /** + * 纬度,范围为-90~90,负数表示南纬 + */ + latitude: any; + + /** + * 经度,范围为-180~180,负数表示西经 + */ + longitude: any; + + /** + * 缩放比例,范围5~18,默认为18 + */ + scale: any; + + /** + * 位置名 + */ + name: string; + + /** + * 地址的详细说明 + */ + address: string; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _openDocumentObject { + /** + * 文件路径,可通过 downFile 获得 + */ + filePath: any; + + /** + * 文件类型,指定文件类型打开文件,有效值 doc, xls, ppt, pdf, docx, xlsx, pptx + */ + fileType: any; + + /** + * 接口调用成功的回调函数 + */ + success: any; + + /** + * 接口调用失败的回调函数 + */ + fail: any; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: any; + } + interface _openCardObject { + /** + * 需要打开的卡券列表,列表内参数详见[openCard 请求对象说明](#opencard-请求对象说明) + */ + cardList: any; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _openBluetoothAdapterObject { + /** + * 成功则返回成功初始化信息 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _onWifiConnectedCallbackResult { + /** + * Wi-Fi 信息 + */ + wifi: object; + } + interface _onUserCaptureScreenCallbackResult {} + interface _onSocketMessageCallbackResult { + /** + * 服务器返回的消息 + */ + data: any; + } + interface _onNetworkStatusChangeCallbackResult { + /** + * 当前是否有网络连接 + */ + isConnected: boolean; + + /** + * 网络类型 + */ + networkType: string; + } + interface _onHCEMessageCallbackResult { + /** + * 消息类型 + */ + messageType: number; + + /** + * 客户端接收到 NFC 设备的指令,此参数当且仅当 `messageType=1` 时有效 + */ + data: any; + + /** + * 此参数当且仅当 `messageType=2` 时有效 + */ + reason: number; + } + interface _onGetWifiListCallbackResult { + /** + * Wi-Fi 列表数据 + */ + wifiList: any; + } + interface _onEvaluateWifiCallbackResult { + /** + * Wi-Fi 信息 + */ + wifi: object; + } + interface _onCompassChangeCallbackResult { + /** + * 面对的方向度数 + */ + direction: number; + } + interface _onBluetoothDeviceFoundCallbackResult { + /** + * 新搜索到的设备列表 + */ + devices: any; + } + interface _onBluetoothAdapterStateChangeCallbackResult { + /** + * 蓝牙适配器是否可用 + */ + available: boolean; + + /** + * 蓝牙适配器是否处于搜索状态 + */ + discovering: boolean; + } + interface _onBeaconUpdateCallbackResult { + /** + * 当前搜寻到的所有 iBeacon 设备列表 + */ + beacons: any; + } + interface _onBeaconServiceChangeCallbackResult { + /** + * 服务目前是否可用 + */ + available: boolean; + + /** + * 目前是否处于搜索状态 + */ + discovering: boolean; + } + interface _onBLEConnectionStateChangeCallbackResult { + /** + * 蓝牙设备 id,参考 device 对象 + */ + deviceId: string; + + /** + * 连接目前的状态 + */ + connected: boolean; + } + interface _onBLECharacteristicValueChangeCallbackResult { + /** + * 蓝牙设备 id,参考 device 对象 + */ + deviceId: string; + + /** + * 特征值所属服务 uuid + */ + serviceId: string; + + /** + * 特征值 uuid + */ + characteristicId: string; + + /** + * 特征值最新的值 **(注意:vConsole 无法打印出 ArrayBuffer 类型数据)** + */ + value: any; + } + interface _onAccelerometerChangeCallbackResult { + /** + * X 轴 + */ + x: number; + + /** + * Y 轴 + */ + y: number; + + /** + * Z 轴 + */ + z: number; + } + interface _notifyBLECharacteristicValueChangeObject { + /** + * 蓝牙设备 id,参考 device 对象 + */ + deviceId: string; + + /** + * 蓝牙特征值对应服务的 uuid + */ + serviceId: string; + + /** + * 蓝牙特征值的 uuid + */ + characteristicId: string; + + /** + * true: 启用 notify; false: 停用 notify + */ + state: boolean; + + /** + * 成功则返回本机蓝牙适配器状态 + */ + success: (result: _notifyBLECharacteristicValueChangeSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _notifyBLECharacteristicValueChangeSuccessObject { + /** + * 成功:ok,错误:详细信息 + */ + errMsg: string; + } + + interface _navigateToMiniProgramObject { + /** + * 要打开的小程序 appId + */ + appId: string; + + /** + * 打开的页面路径,如果为空则打开首页 + */ + path: string; + + /** + * 需要传递给目标小程序的数据,目标小程序可在 `App.onLaunch()`,`App.onShow()` 中获取到这份数据。[详情](../framework/app-service/app.md) + */ + extraData: object; + + /** + * 要打开的小程序版本,有效值 develop(开发版),trial(体验版),release(正式版) ,仅在当前小程序为开发版或体验版时此参数有效;如果当前小程序是体验版或正式版,则打开的小程序必定是正式版。默认值 release + */ + envVersion: string; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _navigateToMiniProgramSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _navigateToMiniProgramSuccessObject { + /** + * 调用结果 + */ + errMsg: string; + } + + interface _navigateToObject { + /** + * 需要跳转的应用内非 tabBar 的页面的路径 , 路径后可以带参数。参数与路径之间使用`?`分隔,参数键与参数值用`=`相连,不同参数用`&`分隔;如 'path?key=value&key2=value2' + */ + url: string; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _navigateBackMiniProgramObject { + /** + * 需要返回给上一个小程序的数据,上一个小程序可在 `App.onShow()` 中获取到这份数据。[详情](../framework/app-service/app.md) + */ + extraData: object; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _navigateBackMiniProgramSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _navigateBackMiniProgramSuccessObject { + /** + * 调用结果 + */ + errMsg: string; + } + + interface _navigateBackObject { + /** + * 返回的页面数,如果 delta 大于现有页面数,则返回到首页。 + */ + delta: number; + } + interface _makeVoIPCallObject { + /** + * 是否展示切换按钮以允许用户转换到后置摄像头 + */ + allowBackCamera: boolean; + + /** + * 是否显示对端视频流 + */ + showOther: boolean; + + /** + * 客服头像的图像链接 + */ + avatarUrl: string; + + /** + * 用于区分业务上下文的透传值 + */ + context: string; + + /** + * 返回用户选择的收货地址信息 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _makePhoneCallObject { + /** + * 需要拨打的电话号码 + */ + phoneNumber: string; + + /** + * 接口调用成功的回调 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _loginObject { + /** + * 接口调用成功的回调函数 + */ + success: (result: _loginSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _loginSuccessObject { + /** + * 调用结果 + */ + errMsg: string; + + /** + * 用户登录凭证(有效期五分钟)。开发者需要在开发者服务器后台调用 api,使用 code 换取 openid 和 session_key 等信息 + */ + code: string; + } + + interface _hideTabBarRedDotObject { + /** + * tabBar的哪一项,从左边算起 + */ + index: number; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _hideTabBarObject { + /** + * 是否需要动画效果,默认无 + */ + aniamtion: boolean; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _hideShareMenuObject { + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getWifiListObject { + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getWeRunDataObject { + /** + * 接口调用成功的回调函数 + */ + success: (result: _getWeRunDataSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getWeRunDataSuccessObject { + /** + * 调用结果 + */ + errMsg: string; + + /** + * 包括敏感数据在内的完整用户信息的加密数据,详细见[加密数据解密算法](./signature.md#加密数据解密算法) + */ + encryptedData: string; + + /** + * 加密算法的初始向量,详细见[加密数据解密算法](./signature.md#加密数据解密算法) + */ + iv: string; + } + + interface _getUserInfoObject { + /** + * 是否带上登录态信息 + */ + withCredentials: boolean; + + /** + * 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。默认为en。 + */ + lang: string; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _getUserInfoSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getUserInfoSuccessObject { + /** + * 用户信息对象,不包含 openid 等敏感信息 + */ + userInfo: object; + + /** + * 不包括敏感信息的原始数据字符串,用于计算签名。 + */ + rawData: string; + + /** + * 使用 sha1( rawData + sessionkey ) 得到字符串,用于校验用户信息,参考文档 [signature](./signature.md)。 + */ + signature: string; + + /** + * 包括敏感数据在内的完整用户信息的加密数据,详细见[加密数据解密算法](./signature.md#加密数据解密算法) + */ + encryptedData: string; + + /** + * 加密算法的初始向量,详细见[加密数据解密算法](./signature.md#加密数据解密算法) + */ + iv: string; + } + + interface _getSystemInfoSyncReturnValue { + /** + * 手机品牌 + */ + brand: any; + + /** + * 手机型号 + */ + model: any; + + /** + * 设备像素比 + */ + pixelRatio: any; + + /** + * 屏幕宽度 + */ + screenWidth: any; + + /** + * 屏幕高度 + */ + screenHeight: any; + + /** + * 可使用窗口宽度 + */ + windowWidth: any; + + /** + * 可使用窗口高度 + */ + windowHeight: any; + + /** + * 状态栏的高度 + */ + statusBarHeight: any; + + /** + * 设置的语言 + */ + language: any; + + /** + * 版本号 + */ + version: any; + + /** + * 操作系统版本 + */ + system: any; + + /** + * 客户端平台 + */ + platform: any; + + /** + * 用户字体大小设置。以“我-设置-通用-字体大小”中的设置为准,单位:px + */ + fontSizeSetting: any; + + /** + * 客户端基础库版本 + */ + SDKVersion: any; + } + + interface _getSystemInfoObject { + /** + * 接口调用成功的回调 + */ + success: (result: _getSystemInfoSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getSystemInfoSuccessObject { + /** + * 手机品牌 + */ + brand: any; + + /** + * 手机型号 + */ + model: any; + + /** + * 设备像素比 + */ + pixelRatio: any; + + /** + * 屏幕宽度 + */ + screenWidth: any; + + /** + * 屏幕高度 + */ + screenHeight: any; + + /** + * 可使用窗口宽度 + */ + windowWidth: any; + + /** + * 可使用窗口高度 + */ + windowHeight: any; + + /** + * 状态栏的高度 + */ + statusBarHeight: any; + + /** + * 设置的语言 + */ + language: any; + + /** + * 版本号 + */ + version: any; + + /** + * 操作系统版本 + */ + system: any; + + /** + * 客户端平台 + */ + platform: any; + + /** + * 用户字体大小设置。以“我-设置-通用-字体大小”中的设置为准,单位:px + */ + fontSizeSetting: any; + + /** + * 客户端基础库版本 + */ + SDKVersion: any; + } + + interface _getStorageInfoObject { + /** + * 接口调用的回调函数,详见返回参数说明 + */ + success: (result: _getStorageInfoSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getStorageInfoSuccessObject { + /** + * 当前storage中所有的key + */ + keys: any; + + /** + * 当前占用的空间大小, 单位kb + */ + currentSize: number; + + /** + * 限制的空间大小,单位kb + */ + limitSize: number; + } + + interface _getStorageObject { + /** + * 本地缓存中的指定的 key + */ + key: string; + + /** + * 接口调用的回调函数,res = {data: key对应的内容} + */ + success: (result: _getStorageSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getStorageSuccessObject { + /** + * key对应的内容 + */ + data: string; + } + + interface _getShareInfoObject { + /** + * shareTicket + */ + shareTicket: string; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _getShareInfoSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getShareInfoSuccessObject { + /** + * 错误信息 + */ + errMsg: string; + + /** + * 包括敏感数据在内的完整转发信息的加密数据,详细见[加密数据解密算法](./signature.md#加密数据解密算法) + */ + encryptedData: string; + + /** + * 加密算法的初始向量,详细见[加密数据解密算法](./signature.md#加密数据解密算法) + */ + iv: string; + } + + interface _getSettingObject { + /** + * 接口调用成功的回调函数,返回内容详见返回参数说明。 + */ + success: (result: _getSettingSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getSettingSuccessObject { + /** + * 用户授权结果,其中 key 为 scope 值,value 为 Bool 值,表示用户是否允许授权,详见 [scope 列表](./authorize-index.md#scope-列表) + */ + authSetting: object; + } + + interface _getScreenBrightnessObject { + /** + * 接口调用成功 + */ + success: (result: _getScreenBrightnessSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getScreenBrightnessSuccessObject { + /** + * 屏幕亮度值,范围 0~1,0 最暗,1 最亮 + */ + value: number; + } + + interface _getSavedFileListObject { + /** + * 接口调用成功的回调函数,返回结果见`success返回参数说明` + */ + success: (result: _getSavedFileListSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getSavedFileListSuccessObject { + /** + * 接口调用结果 + */ + errMsg: string; + + /** + * 文件列表 + */ + fileList: any; + } + + interface _getSavedFileInfoObject { + /** + * 文件路径 + */ + filePath: string; + + /** + * 接口调用成功的回调函数,返回结果见`success返回参数说明` + */ + success: (result: _getSavedFileInfoSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getSavedFileInfoSuccessObject { + /** + * 接口调用结果 + */ + errMsg: string; + + /** + * 文件大小,单位B + */ + size: number; + + /** + * 文件保存时的时间戳,从1970/01/01 08:00:00 到该时刻的秒数 + */ + createTime: number; + } + + interface _getOpenDeviceIdObject { + /** + * 接口调用成功的回调函数 + */ + success: (result: _getOpenDeviceIdSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getOpenDeviceIdSuccessObject { + /** + * 接口调用结果 + */ + errMsg: string; + + /** + * 包括敏感数据在内的完整用户信息的加密数据,详细见[加密数据解密算法](./signature.md#加密数据解密算法) + */ + encryptedData: string; + + /** + * 加密算法的初始向量,详细见[加密数据解密算法](./signature.md#加密数据解密算法) + */ + iv: string; + } + + interface _getNetworkTypeObject { + /** + * 接口调用成功,返回网络类型 networkType + */ + success: (result: _getNetworkTypeSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getNetworkTypeSuccessObject { + /** + * 网络类型 + */ + networkType: any; + } + + interface _getLocationObject { + /** + * 默认为 wgs84 返回 gps 坐标,gcj02 返回可用于`hbs.openLocation`的坐标 + */ + type: string; + + /** + * 传入 true 会返回高度信息,由于获取高度需要较高精确度,会减慢接口返回速度 + */ + altitude: boolean; + + /** + * 接口调用成功的回调函数,返回内容详见返回参数说明。 + */ + success: (result: _getLocationSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getLocationSuccessObject { + /** + * 纬度,浮点数,范围为-90~90,负数表示南纬 + */ + latitude: any; + + /** + * 经度,浮点数,范围为-180~180,负数表示西经 + */ + longitude: any; + + /** + * 速度,浮点数,单位m/s + */ + speed: any; + + /** + * 位置的精确度 + */ + accuracy: any; + + /** + * 高度,单位 m + */ + altitude: any; + + /** + * 垂直精度,单位 m(Android 无法获取,返回 0) + */ + verticalAccuracy: any; + + /** + * 水平精度,单位 m + */ + horizontalAccuracy: any; + } + + interface _getImageInfoObject { + /** + * 图片的路径,可以是相对路径,临时文件路径,存储文件路径,网络图片路径 + */ + src: string; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _getImageInfoSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getImageInfoSuccessObject { + /** + * 图片宽度,单位px + */ + width: number; + + /** + * 图片高度,单位px + */ + height: number; + + /** + * 返回图片的本地路径 + */ + path: string; + } + + interface _getHCEStateObject { + /** + * 接口调用成功的回调函数 + */ + success: (result: _getHCEStateSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getHCEStateSuccessObject { + /** + * 错误信息 + */ + errMsg: string; + + /** + * 错误码 + */ + errCode: number; + } + + interface _getFileInfoObject { + /** + * 本地文件路径 + */ + filePath: string; + + /** + * 计算文件摘要的算法,默认值 md5,有效值:md5,sha1 + */ + digestAlgorithm: string; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _getFileInfoSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getFileInfoSuccessObject { + /** + * 文件大小,单位:B + */ + size: number; + + /** + * 按照传入的 digestAlgorithm 计算得出的的文件摘要 + */ + digest: string; + + /** + * 调用结果 + */ + errMsg: string; + } + + interface _getExtConfigSyncReturnValue { + /** + * 第三方平台自定义的数据 + */ + extConfig: object; + } + + interface _getExtConfigObject { + /** + * 返回第三方平台自定义的数据 + */ + success: (result: _getExtConfigSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getExtConfigSuccessObject { + /** + * 调用结果 + */ + errMsg: string; + + /** + * 第三方平台自定义的数据 + */ + extConfig: object; + } + + interface _getConnectedWifiObject { + /** + * 接口调用成功的回调函数 + */ + success: (result: _getConnectedWifiSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getConnectedWifiSuccessObject { + /** + * Wi-Fi 信息 + */ + wifi: object; + } + + interface _getConnectedBluetoothDevicesObject { + /** + * 蓝牙设备主 service 的 uuid 列表 + */ + services: any; + + /** + * 成功则返回本机蓝牙适配器状态 + */ + success: (result: _getConnectedBluetoothDevicesSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getConnectedBluetoothDevicesSuccessObject { + /** + * 搜索到的设备列表 + */ + devices: any; + + /** + * 成功:ok,错误:详细信息 + */ + errMsg: string; + } + + interface _getClipboardDataObject { + /** + * 接口调用成功的回调函数 + */ + success: (result: _getClipboardDataSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getClipboardDataSuccessObject { + /** + * 剪贴板的内容 + */ + data: string; + } + + interface _getBluetoothDevicesObject { + /** + * 成功则返回本机蓝牙适配器状态 + */ + success: (result: _getBluetoothDevicesSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getBluetoothDevicesSuccessObject { + /** + * uuid 对应的的已连接设备列表 + */ + devices: any; + + /** + * 成功:ok,错误:详细信息 + */ + errMsg: string; + } + + interface _getBluetoothAdapterStateObject { + /** + * 成功则返回本机蓝牙适配器状态 + */ + success: (result: _getBluetoothAdapterStateSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getBluetoothAdapterStateSuccessObject { + /** + * 是否正在搜索设备 + */ + discovering: boolean; + + /** + * 蓝牙适配器是否可用 + */ + available: boolean; + + /** + * 成功:ok,错误:详细信息 + */ + errMsg: string; + } + + interface _getBeaconsObject { + /** + * 接口调用成功的回调函数 + */ + success: (result: _getBeaconsSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getBeaconsSuccessObject { + /** + * iBeacon 设备列表 + */ + beacons: any; + + /** + * 调用结果 + */ + errMsg: string; + } + + interface _getBackgroundAudioPlayerStateObject { + /** + * 接口调用成功的回调函数 + */ + success: (result: _getBackgroundAudioPlayerStateSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getBackgroundAudioPlayerStateSuccessObject { + /** + * 选定音频的长度(单位:s),只有在当前有音乐播放时返回 + */ + duration: any; + + /** + * 选定音频的播放位置(单位:s),只有在当前有音乐播放时返回 + */ + currentPosition: any; + + /** + * 播放状态(2:没有音乐在播放,1:播放中,0:暂停中) + */ + status: any; + + /** + * 音频的下载进度(整数,80 代表 80%),只有在当前有音乐播放时返回 + */ + downloadPercent: any; + + /** + * 歌曲数据链接,只有在当前有音乐播放时返回 + */ + dataUrl: any; + } + + interface _getBackgroundAudioManagerReturnValue { + /** + * 当前音频的长度(单位:s),只有在当前有合法的 src 时返回 + */ + duration: number; + + /** + * 当前音频的播放位置(单位:s),只有在当前有合法的 src 时返回 + */ + currentTime: number; + + /** + * 当前是是否暂停或停止状态,true 表示暂停或停止,false 表示正在播放 + */ + paused: boolean; + + /** + * 音频的数据源,默认为空字符串,**当设置了新的 src 时,会自动开始播放** ,目前支持的格式有 m4a, aac, mp3, wav + */ + src: string; + + /** + * 音频开始播放的位置(单位:s) + */ + startTime: number; + + /** + * 音频缓冲的时间点,仅保证当前播放时间点到此时间点内容已缓冲。 + */ + buffered: number; + + /** + * 音频标题,用于做原生音频播放器音频标题。原生音频播放器中的分享功能,分享出去的卡片标题,也将使用该值。 + */ + title: string; + + /** + * 专辑名,原生音频播放器中的分享功能,分享出去的卡片简介,也将使用该值。 + */ + epname: string; + + /** + * 歌手名,原生音频播放器中的分享功能,分享出去的卡片简介,也将使用该值。 + */ + singer: string; + + /** + * 封面图url,用于做原生音频播放器背景图。原生音频播放器中的分享功能,分享出去的卡片配图及背景也将使用该图。 + */ + coverImgUrl: string; + + /** + * 页面链接,原生音频播放器中的分享功能,分享出去的卡片简介,也将使用该值。 + */ + webUrl: string; + + /** + * 播放 + */ + play: () => void; + + /** + * 暂停 + */ + pause: () => void; + + /** + * 停止 + */ + stop: () => void; + + /** + * 跳转到指定位置,单位 s + */ + seek: () => void; + /** + * 监听快应用需要打开的页面不存在事件。该事件与 App.onPageNotFound 的回调时机一致。 + */ + onPageNotFound:()=>void; + /** + * 背景音频进入可以播放状态,但不保证后面可以流畅播放 + */ + onCanplay: () => void; + + /** + * 背景音频播放事件 + */ + onPlay: () => void; + + /** + * 背景音频暂停事件 + */ + onPause: () => void; + + /** + * 背景音频停止事件 + */ + onStop: () => void; + + /** + * 背景音频自然播放结束事件 + */ + onEnded: () => void; + + /** + * 背景音频播放进度更新事件 + */ + onTimeUpdate: () => void; + + /** + * 用户在系统音乐播放面板点击上一曲事件(iOS only) + */ + onPrev: () => void; + + /** + * 用户在系统音乐播放面板点击下一曲事件(iOS only) + */ + onNext: () => void; + + /** + * 背景音频播放错误事件 + */ + onError: () => void; + + /** + * 音频加载中事件,当音频因为数据不足,需要停下来加载时会触发 + */ + onWaiting: () => void; + } + + interface _getBLEDeviceServicesObject { + /** + * 蓝牙设备 id,参考 getDevices 接口 + */ + deviceId: string; + + /** + * 成功则返回本机蓝牙适配器状态 + */ + success: (result: _getBLEDeviceServicesSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getBLEDeviceServicesSuccessObject { + /** + * 设备服务列表 + */ + services: any; + + /** + * 成功:ok,错误:详细信息 + */ + errMsg: string; + } + + interface _getBLEDeviceCharacteristicsObject { + /** + * 蓝牙设备 id,参考 device 对象 + */ + deviceId: string; + + /** + * 蓝牙服务 uuid + */ + serviceId: string; + + /** + * 成功则返回本机蓝牙适配器状态 + */ + success: (result: _getBLEDeviceCharacteristicsSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _getBLEDeviceCharacteristicsSuccessObject { + /** + * 设备特征值列表 + */ + characteristics: any; + + /** + * 成功:ok,错误:详细信息 + */ + errMsg: string; + } + + interface _downloadFileObject { + /** + * undefined + */ + url: string; + + /** + * undefined + */ + header: object; + + /** + * undefined + */ + success: (result: _downloadFileSuccessObject) => void; + + /** + * undefined + */ + fail: () => void; + + /** + * undefined + */ + complete: () => void; + } + interface _downloadFileSuccessObject { + /** + * 临时文件路径,下载后的文件会存储到一个临时文件 + */ + tempFilePath: string; + + /** + * 开发者服务器返回的 HTTP 状态码 + */ + statusCode: number; + } + + interface _createBLEConnectionObject { + /** + * 蓝牙设备 id,参考 getDevices 接口 + */ + deviceId: string; + + /** + * 成功则返回本机蓝牙适配器状态 + */ + success: (result: _createBLEConnectionSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _createBLEConnectionSuccessObject { + /** + * 成功:ok,错误:详细信息 + */ + errMsg: string; + } + + interface _createAnimationObject { + /** + * 动画持续时间,单位ms + */ + duration: any; + + /** + * 定义动画的效果 + */ + timingFunction: string; + + /** + * 动画延迟时间,单位 ms + */ + delay: any; + + /** + * 设置transform-origin + */ + transformOrigin: string; + } + interface _connectWifiObject { + /** + * Wi-Fi 设备ssid + */ + SSID: string; + + /** + * Wi-Fi 设备bssid + */ + BSSID: string; + + /** + * Wi-Fi 设备密码 + */ + password: string; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _connectSocketObject { + /** + * 开发者服务器接口地址,必须是 wss 协议,且域名必须是后台配置的合法域名 + */ + url: string; + + /** + * HTTP Header , header 中不能设置 Referer + */ + header: object; + + /** + * 默认是GET,有效值:OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT + */ + method: string; + + /** + * 子协议数组 + */ + protocols: any; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _closeSocketObject { + /** + * 一个数字值表示关闭连接的状态号,表示连接被关闭的原因。如果这个参数没有被指定,默认的取值是1000 (表示正常连接关闭) + */ + code: number; + + /** + * 一个可读的字符串,表示连接被关闭的原因。这个字符串必须是不长于123字节的UTF-8 文本(不是字符) + */ + reason: string; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _closeBluetoothAdapterObject { + /** + * 成功则返回成功关闭模块信息 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _closeBLEConnectionObject { + /** + * 蓝牙设备 id,参考 getDevices 接口 + */ + deviceId: string; + + /** + * 成功则返回本机蓝牙适配器状态 + */ + success: (result: _closeBLEConnectionSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _closeBLEConnectionSuccessObject { + /** + * 成功:ok,错误:详细信息 + */ + errMsg: string; + } + + interface _chooseVideoObject { + /** + * album 从相册选视频,camera 使用相机拍摄,默认为:['album', 'camera'] + */ + sourceType: any; + + /** + * 是否压缩所选的视频源文件,默认值为true,需要压缩 + */ + compressed: any; + + /** + * 拍摄视频最长拍摄时间,单位秒。最长支持 60 秒 + */ + maxDuration: number; + + /** + * 接口调用成功,返回视频文件的临时文件路径,详见返回参数说明 + */ + success: (result: _chooseVideoSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _chooseVideoSuccessObject { + /** + * 选定视频的临时文件路径 + */ + tempFilePath: any; + + /** + * 选定视频的时间长度 + */ + duration: any; + + /** + * 选定视频的数据量大小 + */ + size: any; + + /** + * 返回选定视频的长 + */ + height: any; + + /** + * 返回选定视频的宽 + */ + width: any; + } + + interface _chooseLocationObject { + /** + * 接口调用成功的回调函数,返回内容详见返回参数说明。 + */ + success: (result: _chooseLocationSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _chooseLocationSuccessObject { + /** + * 位置名称 + */ + name: any; + + /** + * 详细地址 + */ + address: any; + + /** + * 纬度,浮点数,范围为-90~90,负数表示南纬 + */ + latitude: any; + + /** + * 经度,浮点数,范围为-180~180,负数表示西经 + */ + longitude: any; + } + + interface _chooseInvoiceTitleObject { + /** + * 接口调用成功的回调函数 + */ + success: (result: _chooseInvoiceTitleSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _chooseInvoiceTitleSuccessObject { + /** + * 抬头类型(0:单位,1:个人) + */ + type: string; + + /** + * 抬头名称 + */ + title: string; + + /** + * 抬头税号 + */ + taxNumber: string; + + /** + * 单位地址 + */ + companyAddress: string; + + /** + * 手机号码 + */ + telephone: string; + + /** + * 银行名称 + */ + bankName: string; + + /** + * 银行账号 + */ + bankAccount: string; + + /** + * 接口调用结果 + */ + errMsg: string; + } + + interface _chooseImageObject { + /** + * 最多可以选择的图片张数,默认9 + */ + count: number; + + /** + * original 原图,compressed 压缩图,默认二者都有 + */ + sizeType: any; + + /** + * album 从相册选图,camera 使用相机,默认二者都有 + */ + sourceType: any; + + /** + * 成功则返回图片的本地文件路径列表 tempFilePaths + */ + success: (result: _chooseImageSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _chooseImageSuccessObject { + /** + * 图片的本地文件路径列表 + */ + tempFilePaths: any; + + /** + * 图片的本地文件列表,每一项是一个 File 对象 + */ + tempFiles: any; + } + + interface _chooseContactObject { + /** + * 返回用户选择的联系人信息 + */ + success: (result: _chooseContactSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _chooseContactSuccessObject { + /** + * 电话号码 + */ + phoneNumber: any; + + /** + * 联系人名称 + */ + displayName: any; + } + + interface _chooseAddressObject { + /** + * 返回用户选择的收货地址信息 + */ + success: (result: _chooseAddressSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _chooseAddressSuccessObject { + /** + * 调用结果 + */ + errMsg: string; + + /** + * 收货人姓名 + */ + userName: string; + + /** + * 邮编 + */ + postalCode: string; + + /** + * 国标收货地址第一级地址 + */ + provinceName: string; + + /** + * 国标收货地址第二级地址 + */ + cityName: string; + + /** + * 国标收货地址第三级地址 + */ + countyName: string; + + /** + * 详细收货地址信息 + */ + detailInfo: string; + + /** + * 收货地址国家码 + */ + nationalCode: string; + + /** + * 收货人手机号码 + */ + telNumber: string; + } + + interface _checkSessionObject { + /** + * 接口调用成功的回调函数,登录态未过期 + */ + success: () => void; + + /** + * 接口调用失败的回调函数,登录态已过期 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _checkIsSupportSoterAuthenticationObject { + /** + * 接口调用成功的回调函数 + */ + success: (result: _checkIsSupportSoterAuthenticationSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _checkIsSupportSoterAuthenticationSuccessObject { + /** + * 该设备支持的可被SOTER识别的生物识别方式 + */ + supportMode: any; + + /** + * 接口调用结果 + */ + errMsg: string; + } + + interface _checkIsSoterEnrolledInDeviceObject { + /** + * 认证方式 + */ + checkAuthMode: string; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _checkIsSoterEnrolledInDeviceSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _checkIsSoterEnrolledInDeviceSuccessObject { + /** + * 是否已录入信息 + */ + isEnrolled: boolean; + + /** + * 接口调用结果 + */ + errMsg: string; + } + + interface _canvasToTempFilePathObject { + /** + * 画布x轴起点(默认0) + */ + x: number; + + /** + * 画布y轴起点(默认0) + */ + y: number; + + /** + * 画布宽度(默认为canvas宽度-x) + */ + width: number; + + /** + * 画布高度(默认为canvas高度-y) + */ + height: number; + + /** + * 输出图片宽度(默认为width) + */ + destWidth: number; + + /** + * 输出图片高度(默认为height) + */ + destHeight: number; + + /** + * 画布标识,传入 [``](../../component/canvas.md) 的 canvas-id + */ + canvasId: string; + + /** + * 目标文件的类型,只支持 'jpg' 或 'png'。默认为 'png' + */ + fileType: string; + + /** + * 图片的质量,取值范围为 (0, 1],不在范围内时当作1.0处理 + */ + quality: number; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _canvasPutImageDataObject { + /** + * 画布标识,传入 [``](../../component/canvas.md) 的 canvas-id + */ + canvasId: string; + + /** + * 图像像素点数据,一维数组,每四项表示一个像素点的rgba + */ + data: any; + + /** + * 源图像数据在目标画布中的位置偏移量(x 轴方向的偏移量) + */ + x: number; + + /** + * 源图像数据在目标画布中的位置偏移量(y 轴方向的偏移量) + */ + y: number; + + /** + * 源图像数据矩形区域的宽度 + */ + width: number; + + /** + * 源图像数据矩形区域的高度 + */ + height: number; + + /** + * 接口调用成功的回调函数 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _canvasGetImageDataObject { + /** + * 画布标识,传入 [``](../../component/canvas.md) 的 canvas-id + */ + canvasId: string; + + /** + * 将要被提取的图像数据矩形区域的左上角 x 坐标 + */ + x: number; + + /** + * 将要被提取的图像数据矩形区域的左上角 y 坐标 + */ + y: number; + + /** + * 将要被提取的图像数据矩形区域的宽度 + */ + width: number; + + /** + * 将要被提取的图像数据矩形区域的高度 + */ + height: number; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _canvasGetImageDataSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _canvasGetImageDataSuccessObject { + /** + * + */ + errMsg: string; + + /** + * 图像数据矩形的宽度 + */ + width: number; + + /** + * 图像数据矩形的高度 + */ + height: number; + + /** + * 图像像素点数据,一维数组,每四项表示一个像素点的rgba + */ + data: any; + } + + interface _authorizeObject { + /** + * 需要获取权限的scope,详见 [scope 列表](./authorize-index.md#scope-列表) + */ + scope: string; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _authorizeSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _authorizeSuccessObject { + /** + * 调用结果 + */ + errMsg: string; + } + + interface _addPhoneContactObject { + /** + * 头像本地文件路径 + */ + photoFilePath: string; + + /** + * 昵称 + */ + nickName: string; + + /** + * 姓氏 + */ + lastName: string; + + /** + * 中间名 + */ + middleName: string; + + /** + * 名字 + */ + firstName: string; + + /** + * 备注 + */ + remark: string; + + /** + * 手机号 + */ + mobilePhoneNumber: string; + + /** + * 号 + */ + weChatNumber: string; + + /** + * 联系地址国家 + */ + addressCountry: string; + + /** + * 联系地址省份 + */ + addressState: string; + + /** + * 联系地址城市 + */ + addressCity: string; + + /** + * 联系地址街道 + */ + addressStreet: string; + + /** + * 联系地址邮政编码 + */ + addressPostalCode: string; + + /** + * 公司 + */ + organization: string; + + /** + * 职位 + */ + title: string; + + /** + * 工作传真 + */ + workFaxNumber: string; + + /** + * 工作电话 + */ + workPhoneNumber: string; + + /** + * 公司电话 + */ + hostNumber: string; + + /** + * 电子邮件 + */ + email: string; + + /** + * 网站 + */ + url: string; + + /** + * 工作地址国家 + */ + workAddressCountry: string; + + /** + * 工作地址省份 + */ + workAddressState: string; + + /** + * 工作地址城市 + */ + workAddressCity: string; + + /** + * 工作地址街道 + */ + workAddressStreet: string; + + /** + * 工作地址邮政编码 + */ + workAddressPostalCode: string; + + /** + * 住宅传真 + */ + homeFaxNumber: string; + + /** + * 住宅电话 + */ + homePhoneNumber: string; + + /** + * 住宅地址国家 + */ + homeAddressCountry: string; + + /** + * 住宅地址省份 + */ + homeAddressState: string; + + /** + * 住宅地址城市 + */ + homeAddressCity: string; + + /** + * 住宅地址街道 + */ + homeAddressStreet: string; + + /** + * 住宅地址邮政编码 + */ + homeAddressPostalCode: string; + + /** + * 接口调用成功 + */ + success: () => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _addCardObject { + /** + * 需要添加的卡券列表,列表内对象说明请参见[请求对象说明](#请求对象说明) + */ + cardList: any; + + /** + * 接口调用成功的回调函数 + */ + success: (result: _addCardSuccessObject) => void; + + /** + * 接口调用失败的回调函数 + */ + fail: () => void; + + /** + * 接口调用结束的回调函数(调用成功、失败都会执行) + */ + complete: () => void; + } + interface _addCardSuccessObject { + /** + * 卡券添加结果列表,列表内对象说明请详见[返回对象说明](#返回对象说明) + */ + cardList: any; + } + + interface _ShareAppMessageReturnObject { + /** + * 分享标题。默认为当前小程序名称。 + */ + + title: string; + + /** + * 分享路径。默认为当前页面 path,必须是以 / 开头的完整路径。 + */ + + path: string; + } + + interface _AppShowOptions { + /** + * 打开小程序的路径 + */ + path: string; + + /** + * 打开小程序的query + */ + query: object; + + /** + * 打开小程序的场景值 + */ + scene: number; + + /** + * shareTicket + */ + shareTicket: string; + } + + declare interface _AppOptions { + /** + * 当小程序初始化完成时,会触发 onLaunch(全局只触发一次) + */ + onLaunch?: (options: _AppShowOptions) => void; + + /** + * 当小程序启动,或从后台进入前台显示,会触发 onShow + */ + onShow?: (options: _AppShowOptions) => void; + + /** + * 当小程序从前台进入后台,会触发 onHide + */ + onHide?: () => void; + + /** + * 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息 + */ + onError?: (msg: string) => void; + } + + declare function App(options: _AppOptions): void; + + /** + * 获取到小程序实例 + */ + declare function getApp(): object; + + declare interface PageOptions { + /** + * 页面的初始数据 + */ + data?: any; + + /** + * 生命周期函数--监听页面加载 + */ + onLoad?: (options?: object) => void; + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + + onReady?: () => void; + + /** + * 生命周期函数--监听页面显示 + */ + + onShow?: () => void; + + /** + * 生命周期函数--监听页面隐藏 + */ + + onHide?: () => void; + + /** + * 生命周期函数--监听页面卸载 + */ + + onUnload?: () => void; + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + + onPullDownRefresh?: () => void; + + /** + * 页面上拉触底事件的处理函数 + */ + + onReachBottom?: () => void; + + /** + * 用户点击右上角分享 + */ + + onShareAppMessage?: () => _ShareAppMessageReturnObject; + } + + declare function Page(page: PageOptions): void; + + declare function getCurrentPages(): object[]; + + declare namespace hbs { + /** + * 游戏登陆 + */ + export function gameLogin(object:Object):void; + + /** + * 根据国家要求对未成年人的游戏时间进行防沉迷监控。调用此接口实现游戏登录即可接入防沉迷的能力。 + */ + export function gameLoginWithReal(object:Object); + + /** + * 当用户完成选择区服信息进入游戏后,或者用户的等级发生变化时,游戏可以调用此接口存储用户的角色信息。如果游戏本身不具有游戏等级、角色名称、游戏区服或者游戏公会这些信息则可以不接入此接口。 + */ + export function savePlayerInfo(object:Object); + /** + * 存储用户角色信息 + */ + export function savePlayerInfoWithReal(object:Object); + /** + * 获取玩家帐户ID + */ + export function getCachePlayerId(object:Object); + + /** + * 获取玩家的额外信息(仅支持中国大陆地区游戏)。 + */ + export function getPlayerExtraInfo(object:Object); + + /** + * 上报进入和退出游戏的事件 + */ + export function submitPlayerEvent(object:Object); + + /** + * 非托管商品的支付,即开发者在接口中自行设置商品价格,而不是从华为开发者平台获取价格 + */ + export function hwPay(object:Object); + + /** + * 用于从华为PMS系统获取商品详情 + */ + export function hwGetProductDetails(object:Object); + + /** + * 托管商品的支付,托管商品是指在华为AppGallery Connect中维护的商品 + */ + export function hwProductPay(object:Object); + + /** + * 查询订单详情,所有调用pay接口的订单均可查询,用于在丢单的情况下复核订单 + */ + export function hwGetOrderDetail(object:Object); + + /** + * 订阅push服务,后续可以收到push消息 + */ + export function pushSubscribe(object:Object); + + /** + * 查询当前用户已订购的非消耗商品订单信息 + */ + export function hwGetPurchaseInfo(object:Object); + + /** + * 取消订阅 + */ + export function pushUnsubscribe(object:Object); + + /** + * 添加push事件回调 + */ + export function pushOn(callback:Function); + + /** + * 移除push事件回调,push.on中的callback将不会再收到透传内容 + */ + export function pushOff(callback:Function); + + /** + * 通过系统分享,分享数据到其他app + */ + export function systemShare(object:Object); + + /** + * 第三方分享 + */ + export function serviceShare(object:Object); + + /** + * 向用户发起授权请求 + */ + export function authorize(object:Object); + + /** + * 获取用户信息 + */ + export function getUserInfo(object:Object); + + /** + * 该接口用于校验应用是否有通过authorize接口完成过登录授权,及应用登录后,帐号是否有退出登录的场景。 + */ + export function checkUserSession(object:Object); + + /** + * 创建 native 广告组件,如果已经创建过 native 广告组件,则返回已创建的广告组件 + */ + export function createNativeAd(object:Object); + + /** + * 创建激励视频广告,同一个 adUnitId,如果已经创建,会复用之前的对象,创建后会加载广告素材,该方法返回的是一个单例,该实例仅对当前页面有效,不允许跨页面使用 + */ + export function createRewardedVideoAd(object:Object); + + /** + * 拉取广告数据,成功回调 onLoad,失败回调 onError。 + */ + export function load(object:Object); + + /** + * 上报广告曝光,一个广告只有一次上报有效,adId 为 load 方法获取的广告数据的 adId 字段 + */ + export function reportAdShow(object:Object); + + /** + * 上报广告点击,一个广告只有一次上报有效,adId 为 load 方法获取的广告数据的 adId 字段。 + */ + export function reportAdClick(object:Object); + + /** + * 获取用户的当前设置,返回值中只会出现已经请求过的权限。 + */ + export function getSetting(object:Object); + + /** + * 调起客户端小游戏设置界面,返回用户设置的操作结果,设置界面只会出现已经请求过的权限。 + */ + export function openSetting(object:Object); + + /** + * 下载分包,返回LoadSubpackageTask对象 + */ + export function loadSubpackage(object:Object); + + /** + * 获取性能管理器对象Performance。Performance对象仅支持一个now()方法,Performance.now() 获取当前时间以微秒为单位的时间戳。 + */ + export function getPerformance(object:Object); + + /** + * 加快触发JS GC,但不保证一定能立即触发JS GC。 + */ + export function triggerGC(object:Object); + + /** + * 获取当前的地理位置、速度。 + */ + export function getLocation(object:Object); + + /** + * 异步将二进制图像数据保存为本地临时图片文件。 + */ + export function saveImageTemp(object:Object); + + /** + * 同步将二进制图像数据保存为本地临时图片文件,保存完成后,返回本地临时文件路径。 + */ + export function saveImageTempSync(object:Object); + + /** + * 获取全局唯一的文件管理器,返回FileSystemManager对象。 + */ + export function getFileSystemManager(object:Object); + + /** + * 监听加速度数据。 + */ + export function getTextLineHeight(object:Object); + + /** + * 开始监听加速度数据。 + */ + export function startAccelerometer(object:Object); + + /** + * 停止监听加速度数据。 + */ + export function stopAccelerometer(object:Object); + + /** + * 获取设备电量。 + */ + export function getBatteryInfo(object:Object); + + /** + * 获取系统剪切板内容。 + */ + export function getClipboardData(object:Object); + + /** + * 设置系统剪切板内容 + */ + export function setClipboardData(object:Object); + + /** + * 监听罗盘数据,频率:5 次/秒,接口调用后会自动开始监听。 + */ + export function onCompassChange(object:Object); + + /** + * 开始监听罗盘数据 + */ + export function startCompass(object:Object); + + /** + * 停止监听罗盘数据 + */ + export function stopCompass(object:Object); + +   /** +      * 获取网络类型 +      */ +     export function getNetworkType(object:Object); + +  /** +      *监听网络状态变化事件 +      */ +     export function onNetworkStatusChange(object:Object); + + /** +      *取消监听网络状态变化事件 +      */ +     export function offNetworkStatusChange(object:Object); + + /** + * 获取屏幕亮度 + */ + export function getScreenBrightness(object:Object); + + /** + * 设置是否保持常亮状态。 + */ + export function setKeepScreenOn(object:Object); + + /** + * 设置屏幕亮度。 + */ + export function setScreenBrightness(object:Object); + + /** + * 使手机振动较短时间。 + */ + export function vibrateShort(object:Object); + + /** + * 使手机振动较长时间。 + */ + export function vibrateLong(object:Object); + + /** + * 隐藏软键盘 + */ + export function hideKeyboard(object:Object); + + /** + * 显示软键盘 + */ + export function showKeyboard(object:Object); + + /** + * 监听键盘输入事件 + */ + export function onKeyboardInput(object:Object); + + /** + * 取消监听键盘输入事件 + */ + export function offKeyboardInput(object:Object); + + /** + * 监听用户点击键盘 confirm 按钮时的事件。 + */ + export function onKeyboardConfirm(object:Object); + + /** + * 取消监听用户点击键盘 confirm 按钮时的事件 + */ + export function offKeyboardConfirm(object:Object); + + /** + * 监听键盘收起的事件 + */ + export function onKeyboardComplete(object:Object); + + /** + * 取消监听键盘收起的事件 + */ + export function offKeyboardComplete(object:Object); + + + + + + + + + + + + + /** + * 批量添加卡券。 + */ + export function addCard(object: _addCardObject): void; + + /** + * 调用后,用户可以选择将该表单以“新增联系人”或“添加到已有联系人”的方式,写入手机系统通讯录,完成手机通讯录联系人和联系方式的增加。 + */ + export function addPhoneContact(object: _addPhoneContactObject): void; + + /** + * 将 ArrayBuffer 数据转成 Base64 字符串 + */ + export function arrayBufferToBase64(): void; + + /** + * 提前向用户发起授权请求。调用后会立刻弹窗询问用户是否同意授权小程序使用某项功能或获取用户的某些数据,但不会实际调用对应接口。如果用户之前已经同意授权,则不会出现弹窗,直接返回成功。 + */ + export function authorize(object: _authorizeObject): void; + + /** + * 将 Base64 字符串转成 ArrayBuffer 数据 + */ + export function base64ToArrayBuffer(base64: string): void; + + /** + * 判断小程序的API,回调,参数,组件等是否在当前版本可用。 + */ + export function canIUse(string: string): void; + + /** + * 返回一个数组,用来描述 canvas 区域隐含的像素数据 + */ + export function canvasGetImageData(object: _canvasGetImageDataObject): void; + + /** + * 将像素数据绘制到画布的方法 + */ + export function canvasPutImageData(object: _canvasPutImageDataObject): void; + + /** + * 把当前画布指定区域的内容导出生成指定大小的图片,并返回文件路径。 + */ + export function canvasToTempFilePath( + this: string, + object: _canvasToTempFilePathObject + ): void; + + /** + * 获取设备内是否录入如指纹等生物信息的接口 + */ + export function checkIsSoterEnrolledInDevice( + object: _checkIsSoterEnrolledInDeviceObject + ): void; + + /** + * 获取本机支持的 SOTER 生物认证方式 + */ + export function checkIsSupportSoterAuthentication( + object: _checkIsSupportSoterAuthenticationObject + ): void; + + /** + * 通过上述接口获得的用户登录态拥有一定的时效性。用户越久未使用小程序,用户登录态越有可能失效。反之如果用户一直在使用小程序,则用户登录态一直保持有效。具体时效逻辑由维护,对开发者透明。开发者只需要调用hbs.checkSession接口**检测当前用户登录态是否有效**。登录态过期后开发者可以再调用hbs.login获取新的用户登录态。 + */ + export function checkSession(object: _checkSessionObject): void; + + /** + * 调起用户编辑收货地址原生界面,并在编辑完成后返回用户选择的地址。 + */ + export function chooseAddress(object: _chooseAddressObject): void; + + /** + * 调起选择手机通讯录联系人界面,返回用户选择的联系人信息。 + */ + export function chooseContact(object: _chooseContactObject): void; + + /** + * 从本地相册选择图片或使用相机拍照。 + */ + export function chooseImage(object: _chooseImageObject): void; + + /** + * 选择用户的发票抬头。 + */ + export function chooseInvoiceTitle(object: _chooseInvoiceTitleObject): void; + + /** + * 打开地图选择位置。 + */ + export function chooseLocation(object: _chooseLocationObject): void; + + /** + * 拍摄视频或从手机相册中选视频,返回视频的临时文件路径。 + */ + export function chooseVideo(object: _chooseVideoObject): void; + + /** + * 清理本地数据缓存。 + */ + export function clearStorage(): void; + + /** + * 同步清理本地数据缓存 + */ + export function clearStorageSync(): void; + + /** + * 断开与低功耗蓝牙设备的连接 + */ + export function closeBLEConnection(object: _closeBLEConnectionObject): void; + + /** + * 关闭蓝牙模块,使其进入未初始化状态。调用该方法将断开所有已建立的链接并释放系统资源。建议在使用小程序蓝牙流程后调用,与`hbs.openBluetoothAdapter`成对调用。 + */ + export function closeBluetoothAdapter( + object: _closeBluetoothAdapterObject + ): void; + + /** + * 关闭 WebSocket 连接。 + */ + export function closeSocket(object: _closeSocketObject): void; + + /** + * 创建一个 [WebSocket](https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket) 连接。**使用前请先阅读[说明](./api-network.md)**。 + */ + export function connectSocket(object: _connectSocketObject): void; + + /** + * 连接 Wi-Fi。若已知 Wi-Fi 信息,可以直接利用该接口连接。仅 Android 与 iOS 11 以上版本支持。 + */ + export function connectWifi(object: _connectWifiObject): void; + + /** + * 创建一个动画实例[animation](#animation)。调用实例的方法来描述动画。最后通过动画实例的`export`方法导出动画数据传递给组件的`animation`属性。 + */ + export function createAnimation(object: _createAnimationObject): void; + + /** + * 创建并返回 audio 上下文 `audioContext` 对象。在自定义组件下,第二个参数传入组件实例this,以操作组件内 ` | PickOmit + else if (child.type === SchemaType.Union) { + var newSchema = { + type: SchemaType.Union, + members: child.members.map(function (v) { + // 从里面往外装 + var type = v.type; + + for (var i = parents.length - 1; i > -1; --i) { + var parent_1 = parents[i]; + type = __assign(__assign({}, parent_1), { + target: type + }); + } + + return { + id: v.id, + type: type + }; + }) + }; + return newSchema; + } else { + throw new Error("Unsupported pattern " + schema.type + "<" + child.type + ">"); + } + }; + + return ProtoHelper; +}(); + +var _a; +/** @internal */ + + +var ErrorType; + +(function (ErrorType) { + ErrorType["TypeError"] = "TypeError"; + ErrorType["InvalidScalarType"] = "InvalidScalarType"; + ErrorType["TupleOverLength"] = "TupleOverLength"; + ErrorType["InvalidEnumValue"] = "InvalidEnumValue"; + ErrorType["InvalidLiteralValue"] = "InvalidLiteralValue"; + ErrorType["MissingRequiredProperty"] = "MissingRequiredProperty"; + ErrorType["ExcessProperty"] = "ExcessProperty"; + ErrorType["InvalidNumberKey"] = "InvalidNumberKey"; + ErrorType["UnionTypesNotMatch"] = "UnionTypesNotMatch"; + ErrorType["UnionMembersNotMatch"] = "UnionMembersNotMatch"; +})(ErrorType || (ErrorType = {})); +/** @internal */ + + +var ErrorMsg = (_a = {}, _a[ErrorType.TypeError] = function (expect, actual) { + return "Expected type to be `" + expect + "`, actually `" + actual + "`."; +}, _a[ErrorType.InvalidScalarType] = function (value, scalarType) { + return "`" + value + "` is not a valid `" + scalarType + "`."; +}, _a[ErrorType.TupleOverLength] = function (valueLength, schemaLength) { + return "Value has " + valueLength + " elements but schema allows only " + schemaLength + "."; +}, _a[ErrorType.InvalidEnumValue] = function (value) { + return "`" + value + "` is not a valid enum member."; +}, _a[ErrorType.InvalidLiteralValue] = function (expected, actual) { + return "Expected to equals `" + stringify(expected) + "`, actually `" + stringify(actual) + "`"; +}, _a[ErrorType.MissingRequiredProperty] = function (propName) { + return "Missing required property `" + propName + "`."; +}, _a[ErrorType.ExcessProperty] = function (propName) { + return "Excess property `" + propName + "` should not exists."; +}, _a[ErrorType.InvalidNumberKey] = function (key) { + return "`" + key + "` is not a valid key, the key here should be a `number`."; +}, // Union +_a[ErrorType.UnionTypesNotMatch] = function (value, types) { + return "`" + stringify(value) + "` is not matched to `" + types.join(' | ') + "`"; +}, _a[ErrorType.UnionMembersNotMatch] = function (memberErrors) { + return "No union member matched, detail:\n" + memberErrors.map(function (v, i) { + return " <" + i + "> " + v.errMsg; + }).join('\n'); +}, _a); +/** @internal */ + +function stringify(value) { + if (typeof value === 'string') { + var output = JSON.stringify(value); + return "'" + output.substr(1, output.length - 2) + "'"; + } + + return JSON.stringify(value); +} +/** @internal */ + + +var ValidateResultError = +/** @class */ +function () { + function ValidateResultError(error) { + this.isSucc = false; + this.error = error; + } + + Object.defineProperty(ValidateResultError.prototype, "errMsg", { + get: function get() { + return ValidateResultError.getErrMsg(this.error); + }, + enumerable: false, + configurable: true + }); + + ValidateResultError.getErrMsg = function (error) { + var _a; + + var errMsg = ErrorMsg[error.type].apply(ErrorMsg, error.params); + + if ((_a = error.inner) === null || _a === void 0 ? void 0 : _a.property.length) { + return "Property `" + error.inner.property.join('.') + "`: " + errMsg; + } else { + return errMsg; + } + }; + + return ValidateResultError; +}(); +/** @internal */ + + +var ValidateResultUtil = +/** @class */ +function () { + function ValidateResultUtil() {} + + ValidateResultUtil.error = function (type) { + var params = []; + + for (var _i = 1; _i < arguments.length; _i++) { + params[_i - 1] = arguments[_i]; + } + + return new ValidateResultError({ + type: type, + params: params + }); + }; + + ValidateResultUtil.innerError = function (property, value, schema, error) { + var _a; + + if (error.error.inner) { + if (typeof property === 'string') { + error.error.inner.property.unshift(property); + } else { + (_a = error.error.inner.property).unshift.apply(_a, property); + } + } else { + error.error.inner = { + property: typeof property === 'string' ? [property] : property, + value: value, + schema: schema + }; + } + + return error; + }; + + ValidateResultUtil.succ = { + isSucc: true + }; + return ValidateResultUtil; +}(); + +var typedArrays = { + Int8Array: Int8Array, + Int16Array: Int16Array, + Int32Array: Int32Array, + BigInt64Array: typeof BigInt64Array !== 'undefined' ? BigInt64Array : undefined, + Uint8Array: Uint8Array, + Uint16Array: Uint16Array, + Uint32Array: Uint32Array, + BigUint64Array: typeof BigUint64Array !== 'undefined' ? BigUint64Array : undefined, + Float32Array: Float32Array, + Float64Array: Float64Array +}; +/** + * TSBuffer Schema Validator + * @public + */ + +var TSBufferValidator = +/** @class */ +function () { + function TSBufferValidator(proto, options) { + /** + * Default options + */ + this.options = { + excessPropertyChecks: true, + strictNullChecks: true, + cloneProto: true + }; + + if (options) { + this.options = __assign(__assign({}, this.options), options); + } + + this.proto = this.options.cloneProto ? Object.merge({}, proto) : proto; + this.protoHelper = new ProtoHelper(this.proto); + } + /** + * Validate whether the value is valid to the schema + * @param value - Value to be validated. + * @param schemaId - Schema or schema ID. + * For example, the schema ID for type `Test` in `a/b.ts` may be `a/b/Test`. + */ + + + TSBufferValidator.prototype.validate = function (value, schemaOrId, options) { + var _a, _b; + + var schema; + var schemaId; // Get schema + + if (typeof schemaOrId === 'string') { + schemaId = schemaOrId; + schema = this.proto[schemaId]; + + if (!schema) { + throw new Error("Cannot find schema: " + schemaId); + } + } else { + schema = schemaOrId; + } // Merge default options + + + return this._validate(value, schema, __assign(__assign({}, options), { + excessPropertyChecks: (_a = options === null || options === void 0 ? void 0 : options.excessPropertyChecks) !== null && _a !== void 0 ? _a : this.options.excessPropertyChecks, + strictNullChecks: (_b = options === null || options === void 0 ? void 0 : options.strictNullChecks) !== null && _b !== void 0 ? _b : this.options.strictNullChecks + })); + }; + + TSBufferValidator.prototype._validate = function (value, schema, options) { + var _a; + + var vRes; // Validate + + switch (schema.type) { + case SchemaType.Boolean: + vRes = this._validateBooleanType(value, schema); + break; + + case SchemaType.Number: + vRes = this._validateNumberType(value, schema); + break; + + case SchemaType.String: + vRes = this._validateStringType(value, schema); + break; + + case SchemaType.Array: + vRes = this._validateArrayType(value, schema, options); + break; + + case SchemaType.Tuple: + vRes = this._validateTupleType(value, schema, options); + break; + + case SchemaType.Enum: + vRes = this._validateEnumType(value, schema); + break; + + case SchemaType.Any: + vRes = this._validateAnyType(value); + break; + + case SchemaType.Literal: + vRes = this._validateLiteralType(value, schema, (_a = options === null || options === void 0 ? void 0 : options.strictNullChecks) !== null && _a !== void 0 ? _a : this.options.strictNullChecks); + break; + + case SchemaType.Object: + vRes = this._validateObjectType(value, schema); + break; + + case SchemaType.Interface: + vRes = this._validateInterfaceType(value, schema, options); + break; + + case SchemaType.Buffer: + vRes = this._validateBufferType(value, schema); + break; + + case SchemaType.IndexedAccess: + case SchemaType.Reference: + vRes = this._validateReferenceType(value, schema, options); + break; + + case SchemaType.Union: + vRes = this._validateUnionType(value, schema, options); + break; + + case SchemaType.Intersection: + vRes = this._validateIntersectionType(value, schema, options); + break; + + case SchemaType.Pick: + case SchemaType.Omit: + case SchemaType.Partial: + case SchemaType.Overwrite: + vRes = this._validateMappedType(value, schema, options); + break; + + case SchemaType.Date: + vRes = this._validateDateType(value); + break; + + case SchemaType.NonNullable: + vRes = this._validateNonNullableType(value, schema, options); + break; + // 错误的type + + default: + throw new Error("Unsupported schema type: " + schema.type); + } // prune + + + if (options === null || options === void 0 ? void 0 : options.prune) { + // don't need prune, return original value + if (options.prune.output === undefined) { + options.prune.output = value; + } // output to parent + + + if (options.prune.parent) { + options.prune.parent.value[options.prune.parent.key] = options.prune.output; + } + } + + return vRes; + }; + /** + * 修剪 Object,移除 Schema 中未定义的 Key + * 需要确保 value 类型合法 + * @param value - value to be validated + * @param schemaOrId -Schema or schema ID. + * @returns Validate result and pruned value. if validate failed, `pruneOutput` would be undefined. + */ + + + TSBufferValidator.prototype.prune = function (value, schemaOrId, options) { + var _a; + + var schema = typeof schemaOrId === 'string' ? this.proto[schemaOrId] : schemaOrId; + + if (!schema) { + throw new Error('Cannot find schema: ' + schemaOrId); + } + + var prune = {}; + + var vRes = this._validate(value, schema, __assign(__assign({}, options), { + prune: prune, + excessPropertyChecks: false, + strictNullChecks: (_a = options === null || options === void 0 ? void 0 : options.strictNullChecks) !== null && _a !== void 0 ? _a : this.options.strictNullChecks + })); + + if (vRes.isSucc) { + vRes.pruneOutput = prune.output; + } + + return vRes; + }; + + TSBufferValidator.prototype._validateBooleanType = function (value, schema) { + var type = this._getTypeof(value); + + if (type === 'boolean') { + return ValidateResultUtil.succ; + } else { + return ValidateResultUtil.error(ErrorType.TypeError, 'boolean', type); + } + }; + + TSBufferValidator.prototype._validateNumberType = function (value, schema) { + // 默认为double + var scalarType = schema.scalarType || 'double'; // Wrong Type + + var type = this._getTypeof(value); + + var rightType = scalarType.indexOf('big') > -1 ? 'bigint' : 'number'; + + if (type !== rightType) { + return ValidateResultUtil.error(ErrorType.TypeError, rightType, type); + } // scalarType类型检测 + // 整形却为小数 + + + if (scalarType !== 'double' && type === 'number' && !Number.isInteger(value)) { + return ValidateResultUtil.error(ErrorType.InvalidScalarType, value, scalarType); + } // 无符号整形却为负数 + + + if (scalarType.indexOf('uint') > -1 && value < 0) { + return ValidateResultUtil.error(ErrorType.InvalidScalarType, value, scalarType); + } + + return ValidateResultUtil.succ; + }; + + TSBufferValidator.prototype._validateStringType = function (value, schema) { + var type = this._getTypeof(value); + + return type === 'string' ? ValidateResultUtil.succ : ValidateResultUtil.error(ErrorType.TypeError, 'string', type); + }; + + TSBufferValidator.prototype._validateArrayType = function (value, schema, options) { + // is Array type + var type = this._getTypeof(value); + + if (type !== SchemaType.Array) { + return ValidateResultUtil.error(ErrorType.TypeError, SchemaType.Array, type); + } // prune output + + + var prune = options.prune; + + if (prune) { + prune.output = Array.from({ + length: value.length + }); + } // validate elementType + + + for (var i = 0; i < value.length; ++i) { + var elemValidateResult = this._validate(value[i], schema.elementType, __assign(__assign({}, options), { + prune: (prune === null || prune === void 0 ? void 0 : prune.output) ? { + parent: { + value: prune.output, + key: i + } + } : undefined + })); + + if (!elemValidateResult.isSucc) { + return ValidateResultUtil.innerError('' + i, value[i], schema.elementType, elemValidateResult); + } + } + + return ValidateResultUtil.succ; + }; + + TSBufferValidator.prototype._validateTupleType = function (value, schema, options) { + // is Array type + var type = this._getTypeof(value); + + if (type !== SchemaType.Array) { + return ValidateResultUtil.error(ErrorType.TypeError, SchemaType.Array, type); + } + + var prune = options.prune; // validate length + // excessPropertyChecks 与 prune互斥 + + if (!prune && options.excessPropertyChecks && value.length > schema.elementTypes.length) { + return ValidateResultUtil.error(ErrorType.TupleOverLength, value.length, schema.elementTypes.length); + } // prune output + + + if (prune) { + prune.output = Array.from({ + length: Math.min(value.length, schema.elementTypes.length) + }); + } // validate elementType + + + for (var i = 0; i < schema.elementTypes.length; ++i) { + // MissingRequiredProperty: NotOptional && is undefined + if (value[i] === undefined || value[i] === null && !options.strictNullChecks) { + var isOptional = schema.optionalStartIndex !== undefined && i >= schema.optionalStartIndex || this._canBeUndefined(schema.elementTypes[i]); // skip undefined property + + + if (isOptional) { + continue; + } else { + return ValidateResultUtil.error(ErrorType.MissingRequiredProperty, i); + } + } // element type check + + + var elemValidateResult = this._validate(value[i], schema.elementTypes[i], { + prune: (prune === null || prune === void 0 ? void 0 : prune.output) ? { + parent: { + value: prune.output, + key: i + } + } : undefined, + strictNullChecks: options.strictNullChecks, + excessPropertyChecks: options.excessPropertyChecks + }); + + if (!elemValidateResult.isSucc) { + return ValidateResultUtil.innerError('' + i, value[i], schema.elementTypes[i], elemValidateResult); + } + } + + return ValidateResultUtil.succ; + }; + + TSBufferValidator.prototype._canBeUndefined = function (schema) { + var _this = this; + + if (schema.type === SchemaType.Union) { + return schema.members.some(function (v) { + return _this._canBeUndefined(v.type); + }); + } + + if (schema.type === SchemaType.Literal && schema.literal === undefined) { + return true; + } + + return false; + }; + + TSBufferValidator.prototype._validateEnumType = function (value, schema) { + // must be string or number + var type = this._getTypeof(value); + + if (type !== 'string' && type !== 'number') { + return ValidateResultUtil.error(ErrorType.TypeError, 'string | number', type); + } // 有值与预设相同 + + + if (schema.members.some(function (v) { + return v.value === value; + })) { + return ValidateResultUtil.succ; + } else { + return ValidateResultUtil.error(ErrorType.InvalidEnumValue, value); + } + }; + + TSBufferValidator.prototype._validateAnyType = function (value) { + return ValidateResultUtil.succ; + }; + + TSBufferValidator.prototype._validateLiteralType = function (value, schema, strictNullChecks) { + // 非strictNullChecks严格模式,null undefined同等对待 + if (!strictNullChecks && (schema.literal === null || schema.literal === undefined)) { + return value === null || value === undefined ? ValidateResultUtil.succ : ValidateResultUtil.error(ErrorType.InvalidLiteralValue, schema.literal, value); + } + + return value === schema.literal ? ValidateResultUtil.succ : ValidateResultUtil.error(ErrorType.InvalidLiteralValue, schema.literal, value); + }; + + TSBufferValidator.prototype._validateObjectType = function (value, schema) { + var type = this._getTypeof(value); + + return type === 'Object' || type === 'Array' ? ValidateResultUtil.succ : ValidateResultUtil.error(ErrorType.TypeError, 'Object', type); + }; + + TSBufferValidator.prototype._validateInterfaceType = function (value, schema, options) { + var type = this._getTypeof(value); + + if (type !== 'Object') { + return ValidateResultUtil.error(ErrorType.TypeError, 'Object', type); + } // 先展平 + + + var flatSchema = this.protoHelper.getFlatInterfaceSchema(schema); // From union or intersecton type + + if (options.unionProperties) { + flatSchema = this.protoHelper.applyUnionProperties(flatSchema, options.unionProperties); + } + + return this._validateFlatInterface(value, flatSchema, options); + }; + + TSBufferValidator.prototype._validateMappedType = function (value, schema, options) { + var parsed = this.protoHelper.parseMappedType(schema); + + if (parsed.type === SchemaType.Interface) { + return this._validateInterfaceType(value, schema, options); + } else if (parsed.type === SchemaType.Union) { + return this._validateUnionType(value, parsed, options); + } + + throw new Error(); + }; + + TSBufferValidator.prototype._validateFlatInterface = function (value, schema, options) { + // interfaceSignature强制了key必须是数字的情况 + if (schema.indexSignature && schema.indexSignature.keyType === SchemaType.Number) { + for (var key in value) { + if (!this._isNumberKey(key)) { + return ValidateResultUtil.error(ErrorType.InvalidNumberKey, key); + } + } + } + + var prune = options.prune; + + if (prune) { + prune.output = {}; + } // Excess property check (与prune互斥) + + + if (!prune && options.excessPropertyChecks && !schema.indexSignature) { + var validProperties_1 = schema.properties.map(function (v) { + return v.name; + }); + var firstExcessProperty = Object.keys(value).find(function (v) { + return validProperties_1.indexOf(v) === -1; + }); + + if (firstExcessProperty) { + return ValidateResultUtil.error(ErrorType.ExcessProperty, firstExcessProperty); + } + } // 校验properties + + + if (schema.properties) { + for (var _i = 0, _a = schema.properties; _i < _a.length; _i++) { + var property = _a[_i]; // MissingRequiredProperty: is undefined && !isOptional + + if (value[property.name] === undefined || value[property.name] === null && !options.strictNullChecks) { + var isOptional = property.optional || this._canBeUndefined(property.type); // skip undefined optional property + + + if (isOptional) { + continue; + } else { + return ValidateResultUtil.error(ErrorType.MissingRequiredProperty, property.name); + } + } // property本身验证 + + + var vRes = this._validate(value[property.name], property.type, { + prune: (prune === null || prune === void 0 ? void 0 : prune.output) && property.id > -1 ? { + parent: { + value: prune.output, + key: property.name + } + } : undefined, + strictNullChecks: options.strictNullChecks, + excessPropertyChecks: options.excessPropertyChecks + }); + + if (!vRes.isSucc) { + return ValidateResultUtil.innerError(property.name, value[property.name], property.type, vRes); + } + } + } // 检测indexSignature + + + if (schema.indexSignature) { + for (var key in value) { + // only prune is (property is pruned already) + // let memberPrune: ValidatePruneOptions | undefined = schema.properties.some(v => v.name === key) ? undefined : {}; + // validate each field + var vRes = this._validate(value[key], schema.indexSignature.type, { + prune: (prune === null || prune === void 0 ? void 0 : prune.output) ? { + parent: { + value: prune.output, + key: key + } + } : undefined, + strictNullChecks: options.strictNullChecks, + excessPropertyChecks: options.excessPropertyChecks + }); + + if (!vRes.isSucc) { + return ValidateResultUtil.innerError(key, value[key], schema.indexSignature.type, vRes); + } + } + } + + return ValidateResultUtil.succ; + }; + + TSBufferValidator.prototype._validateBufferType = function (value, schema) { + var _a, _b; + + var type = this._getTypeof(value); + + if (type !== 'Object') { + return ValidateResultUtil.error(ErrorType.TypeError, schema.arrayType || 'ArrayBuffer', type); + } else if (schema.arrayType) { + var typeArrayClass = typedArrays[schema.arrayType]; + + if (!typeArrayClass) { + throw new Error("Error TypedArray type: " + schema.arrayType); + } + + return value instanceof typeArrayClass ? ValidateResultUtil.succ : ValidateResultUtil.error(ErrorType.TypeError, schema.arrayType, (_a = value === null || value === void 0 ? void 0 : value.constructor) === null || _a === void 0 ? void 0 : _a.name); + } else { + return value instanceof ArrayBuffer ? ValidateResultUtil.succ : ValidateResultUtil.error(ErrorType.TypeError, 'ArrayBuffer', (_b = value === null || value === void 0 ? void 0 : value.constructor) === null || _b === void 0 ? void 0 : _b.name); + } + }; + + TSBufferValidator.prototype._validateReferenceType = function (value, schema, options) { + return this._validate(value, this.protoHelper.parseReference(schema), options); + }; + + TSBufferValidator.prototype._validateUnionType = function (value, schema, options) { + var _this = this; + + options.unionProperties = options.unionProperties || this.protoHelper.getUnionProperties(schema); + var isObjectPrune = false; + var prune = options.prune; + + if (prune && value && Object.getPrototypeOf(value) === Object.prototype) { + isObjectPrune = true; + prune.output = {}; + } // 有一成功则成功 + + + var isSomeSucc = false; + var memberErrors = []; + + for (var i = 0; i < schema.members.length; ++i) { + var member = schema.members[i]; + var memberType = this.protoHelper.isTypeReference(member.type) ? this.protoHelper.parseReference(member.type) : member.type; + var memberPrune = prune ? {} : undefined; + + var vRes = this._validate(value, memberType, __assign(__assign({}, options), { + prune: memberPrune + })); + + if (vRes.isSucc) { + isSomeSucc = true; // if prune object: must prune all members + + if (isObjectPrune) { + prune.output = __assign(__assign({}, prune.output), memberPrune.output); + } // not prune object: stop checking after 1st member matched + else { + break; + } + } else { + memberErrors.push(vRes); + } + } // 有一成功则成功; + + + if (isSomeSucc) { + return ValidateResultUtil.succ; + } // 全部失败,则失败 + else { + // All member error is the same, return the first + var msg0_1 = memberErrors[0].errMsg; + + if (memberErrors.every(function (v) { + return v.errMsg === msg0_1; + })) { + return memberErrors[0]; + } // mutual exclusion: return the only one + + + var nonLiteralErrors = memberErrors.filter(function (v) { + return v.error.type !== ErrorType.InvalidLiteralValue; + }); + + if (nonLiteralErrors.length === 1) { + return nonLiteralErrors[0]; + } // All member error without inner: show simple msg + + + if (memberErrors.every(function (v) { + return !v.error.inner && (v.error.type === ErrorType.TypeError || v.error.type === ErrorType.InvalidLiteralValue); + })) { + var valueType = this._getTypeof(value); + + var expectedTypes = memberErrors.map(function (v) { + return v.error.type === ErrorType.TypeError ? v.error.params[0] : _this._getTypeof(v.error.params[0]); + }).distinct(); // Expected type A|B|C, actually type D + + if (expectedTypes.indexOf(valueType) === -1) { + return ValidateResultUtil.error(ErrorType.TypeError, expectedTypes.join(' | '), this._getTypeof(value)); + } // `'D'` is not matched to `'A'|'B'|'C'` + + + if (valueType !== 'Object' && valueType !== SchemaType.Array) { + var types = memberErrors.map(function (v) { + return v.error.type === ErrorType.TypeError ? v.error.params[0] : stringify(v.error.params[0]); + }).distinct(); + return ValidateResultUtil.error(ErrorType.UnionTypesNotMatch, value, types); + } + } // other errors + + + return ValidateResultUtil.error(ErrorType.UnionMembersNotMatch, memberErrors); + } + }; + + TSBufferValidator.prototype._validateIntersectionType = function (value, schema, options) { + options.unionProperties = options.unionProperties || this.protoHelper.getUnionProperties(schema); + var isObjectPrune = false; + var prune = options.prune; + + if (prune && value && Object.getPrototypeOf(value) === Object.prototype) { + prune.output = {}; + isObjectPrune = true; + } // 有一失败则失败 + + + for (var i = 0, len = schema.members.length; i < len; ++i) { + // 验证member + var memberType = schema.members[i].type; + memberType = this.protoHelper.isTypeReference(memberType) ? this.protoHelper.parseReference(memberType) : memberType; + var memberPrune = prune ? {} : undefined; + + var vRes = this._validate(value, memberType, __assign(__assign({}, options), { + prune: memberPrune + })); // 有一失败则失败 + + + if (!vRes.isSucc) { + return vRes; + } + + if (isObjectPrune) { + prune.output = __assign(__assign({}, prune.output), memberPrune.output); + } + } // 全成功则成功 + + + return ValidateResultUtil.succ; + }; + + TSBufferValidator.prototype._validateDateType = function (value) { + if (value instanceof Date) { + return ValidateResultUtil.succ; + } else { + return ValidateResultUtil.error(ErrorType.TypeError, 'Date', this._getTypeof(value)); + } + }; + + TSBufferValidator.prototype._validateNonNullableType = function (value, schema, options) { + var type = this._getTypeof(value); + + if ((type === 'null' || type === 'undefined') && schema.target.type !== 'Any') { + return ValidateResultUtil.error(ErrorType.TypeError, 'NonNullable', type); + } + + return this._validate(value, schema.target, options); + }; + + TSBufferValidator.prototype._isNumberKey = function (key) { + var int = parseInt(key); + return !(isNaN(int) || '' + int !== key); + }; + + TSBufferValidator.prototype._getTypeof = function (value) { + var type = _typeof(value); + + if (type === 'object') { + if (value === null) { + return 'null'; + } else if (Array.isArray(value)) { + return SchemaType.Array; + } else { + return 'Object'; + } + } + + return type; + }; + + return TSBufferValidator; +}(); + +/** @internal */ + +var IdBlockUtil = +/** @class */ +function () { + function IdBlockUtil() {} + + IdBlockUtil.getPayloadLengthInfo = function (parsedSchema) { + switch (parsedSchema.type) { + case SchemaType.Boolean: + case SchemaType.Enum: + return { + lengthType: LengthType.Varint + }; + + case SchemaType.Number: + if (!parsedSchema.scalarType || parsedSchema.scalarType.includes('64') || parsedSchema.scalarType === 'double') { + return { + lengthType: LengthType.Bit64 + }; + } else if (parsedSchema.scalarType && parsedSchema.scalarType.startsWith('big')) { + return { + lengthType: LengthType.LengthDelimited + }; + } else { + return { + lengthType: LengthType.Varint + }; + } + + case SchemaType.Buffer: + case SchemaType.String: + case SchemaType.Any: + case SchemaType.Object: + return { + lengthType: LengthType.LengthDelimited + }; + + case SchemaType.Interface: + case SchemaType.Pick: + case SchemaType.Partial: + case SchemaType.Omit: + case SchemaType.Union: + case SchemaType.Intersection: + return { + lengthType: LengthType.IdBlock + }; + + case SchemaType.Array: + case SchemaType.Overwrite: + case SchemaType.Tuple: + return { + lengthType: LengthType.LengthDelimited, + needLengthPrefix: true + }; + + case SchemaType.Literal: + return { + lengthType: LengthType.LengthDelimited, + needLengthPrefix: false + }; + + case SchemaType.Date: + return { + lengthType: LengthType.Varint + }; + + default: + throw new Error("Unrecognized schema type: " + parsedSchema.type); + } + }; + + return IdBlockUtil; +}(); +/** @internal */ + + +var LengthType; + +(function (LengthType) { + LengthType[LengthType["LengthDelimited"] = 0] = "LengthDelimited"; + LengthType[LengthType["Varint"] = 1] = "Varint"; + LengthType[LengthType["Bit64"] = 2] = "Bit64"; + LengthType[LengthType["IdBlock"] = 3] = "IdBlock"; +})(LengthType || (LengthType = {})); +/** @internal */ + + +var SchemaUtil = +/** @class */ +function () { + function SchemaUtil() {} + /** type类型是否能编码为该literal */ + + + SchemaUtil.canBeLiteral = function (schema, literal) { + var _this = this; + + if (schema.type === SchemaType.Union) { + return schema.members.some(function (v) { + return _this.canBeLiteral(v.type, literal); + }); + } + + if (schema.type === SchemaType.Any) { + return true; + } + + if (schema.type === SchemaType.Literal && schema.literal === literal) { + return true; + } + + return false; + }; + + return SchemaUtil; +}(); + +var TypedArrays = { + Int8Array: Int8Array, + Int16Array: Int16Array, + Int32Array: Int32Array, + Uint8Array: Uint8Array, + Uint16Array: Uint16Array, + Uint32Array: Uint32Array, + Float32Array: Float32Array, + Float64Array: Float64Array +}; +var Utf8CoderJS = { + measureLength: function measureLength(str) { + var len = 0, + c = 0; + + for (var i = 0; i < str.length; ++i) { + c = str.charCodeAt(i); + if (c < 128) len += 1;else if (c < 2048) len += 2;else if ((c & 0xFC00) === 0xD800 && (str.charCodeAt(i + 1) & 0xFC00) === 0xDC00) { + ++i; + len += 4; + } else len += 3; + } + + return len; + }, + write: function write(str, buf, pos) { + var start = pos, + c1, + // character 1 + c2; // character 2 + + for (var i = 0; i < str.length; ++i) { + c1 = str.charCodeAt(i); + + if (c1 < 128) { + buf[pos++] = c1; + } else if (c1 < 2048) { + buf[pos++] = c1 >> 6 | 192; + buf[pos++] = c1 & 63 | 128; + } else if ((c1 & 0xFC00) === 0xD800 && ((c2 = str.charCodeAt(i + 1)) & 0xFC00) === 0xDC00) { + c1 = 0x10000 + ((c1 & 0x03FF) << 10) + (c2 & 0x03FF); + ++i; + buf[pos++] = c1 >> 18 | 240; + buf[pos++] = c1 >> 12 & 63 | 128; + buf[pos++] = c1 >> 6 & 63 | 128; + buf[pos++] = c1 & 63 | 128; + } else { + buf[pos++] = c1 >> 12 | 224; + buf[pos++] = c1 >> 6 & 63 | 128; + buf[pos++] = c1 & 63 | 128; + } + } + + return pos - start; + }, + read: function read(buf, pos, length) { + if (length < 1) return ""; + var parts = undefined, + chunk = [], + i = 0, + // char offset + t; // temporary + + var end = pos + length; + + while (pos < end) { + t = buf[pos++]; + if (t < 128) chunk[i++] = t;else if (t > 191 && t < 224) chunk[i++] = (t & 31) << 6 | buf[pos++] & 63;else if (t > 239 && t < 365) { + t = ((t & 7) << 18 | (buf[pos++] & 63) << 12 | (buf[pos++] & 63) << 6 | buf[pos++] & 63) - 0x10000; + chunk[i++] = 0xD800 + (t >> 10); + chunk[i++] = 0xDC00 + (t & 1023); + } else chunk[i++] = (t & 15) << 12 | (buf[pos++] & 63) << 6 | buf[pos++] & 63; + + if (i > 8191) { + (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk)); + i = 0; + } + } + + if (parts) { + if (i) parts.push(String.fromCharCode.apply(String, chunk.slice(0, i))); + return parts.join(""); + } + + return String.fromCharCode.apply(String, chunk.slice(0, i)); + } +}; +var Utf8CoderNode = { + measureLength: function measureLength(str) { + return Buffer.byteLength(str, 'utf-8'); + }, + write: function write(str, buf, pos) { + return Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength).write(str, pos, 'utf-8'); + }, + read: function read(buf, pos, length) { + return Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength).toString('utf-8', pos, pos + length); + } +}; +/** + * 自动判断环境,选择使用NodeJS Native方法编码或是JS编码 + */ + +var Utf8Coder = typeof Buffer !== 'undefined' && Buffer.from && Buffer.prototype.write ? Utf8CoderNode : Utf8CoderJS; +/** @internal */ + +var Varint64 = +/** @class */ +function () { + function Varint64(high, low, byteLength) { + this.uint32s = new Uint32Array([high, low]); + + if (byteLength !== undefined) { + this._byteLength = byteLength; + } + } + + Varint64.from = function (value) { + if (value === 0) { + return this.Zero; + } + + var sign = value < 0; + + if (sign) { + value = -value; + } + + var lo = value >>> 0, + hi = (value - lo) / 4294967296 >>> 0; + + if (sign) { + hi = ~hi >>> 0; + lo = ~lo >>> 0; + + if (++lo > 4294967295) { + lo = 0; + if (++hi > 4294967295) hi = 0; + } + } + + return new Varint64(hi, lo); + }; + + Varint64.prototype.toNumber = function (unsigned) { + if (!unsigned && this.uint32s[0] >>> 31) { + var low = ~this.uint32s[1] + 1 >>> 0, + high = ~this.uint32s[0] >>> 0; + if (!low) high = high + 1 >>> 0; + return -(low + high * 4294967296); + } + + return this.uint32s[1] + this.uint32s[0] * 4294967296; + }; + + Varint64.prototype.zzEncode = function () { + var mask = this.uint32s[0] >> 31; + this.uint32s[0] = ((this.uint32s[0] << 1 | this.uint32s[1] >>> 31) ^ mask) >>> 0; + this.uint32s[1] = (this.uint32s[1] << 1 ^ mask) >>> 0; + return this; + }; + + Varint64.prototype.zzDecode = function () { + var mask = -(this.uint32s[1] & 1); + this.uint32s[1] = ((this.uint32s[1] >>> 1 | this.uint32s[0] << 31) ^ mask) >>> 0; + this.uint32s[0] = (this.uint32s[0] >>> 1 ^ mask) >>> 0; + return this; + }; + + Object.defineProperty(Varint64.prototype, "byteLength", { + get: function get() { + if (this._byteLength === undefined) { + var part0 = this.uint32s[1], + part1 = (this.uint32s[1] >>> 28 | this.uint32s[0] << 4) >>> 0, + part2 = this.uint32s[0] >>> 24; + this._byteLength = part2 === 0 ? part1 === 0 ? part0 < 16384 ? part0 < 128 ? 1 : 2 : part0 < 2097152 ? 3 : 4 : part1 < 16384 ? part1 < 128 ? 5 : 6 : part1 < 2097152 ? 7 : 8 : part2 < 128 ? 9 : 10; + } + + return this._byteLength; + }, + enumerable: false, + configurable: true + }); + /** + * 编码 + * @param buf + * @param pos + * @returns 编码后最新的pos + */ + + Varint64.prototype.writeToBuffer = function (buf, pos) { + while (this.uint32s[0]) { + buf[pos++] = this.uint32s[1] & 127 | 128; + this.uint32s[1] = (this.uint32s[1] >>> 7 | this.uint32s[0] << 25) >>> 0; + this.uint32s[0] >>>= 7; + } + + while (this.uint32s[1] > 127) { + buf[pos++] = this.uint32s[1] & 127 | 128; + this.uint32s[1] = this.uint32s[1] >>> 7; + } + + buf[pos++] = this.uint32s[1]; + return pos; + }; + + Varint64.readFromBuffer = function (buf, pos) { + var startPos = pos; + var hi = 0, + lo = 0; + var i = 0; + + if (buf.byteLength - pos > 4) { + // fast route (lo) + for (; i < 4; ++i) { + // 1st..4th + lo = (lo | (buf[pos] & 127) << i * 7) >>> 0; + if (buf[pos++] < 128) return new Varint64(hi, lo, pos - startPos); + } // 5th + + + lo = (lo | (buf[pos] & 127) << 28) >>> 0; + hi = (hi | (buf[pos] & 127) >> 4) >>> 0; + if (buf[pos++] < 128) return new Varint64(hi, lo, pos - startPos); + i = 0; + } else { + for (; i < 3; ++i) { + /* istanbul ignore if */ + if (pos >= buf.byteLength) throw new Error('Read varint error: index out of range'); // 1st..3th + + lo = (lo | (buf[pos] & 127) << i * 7) >>> 0; + if (buf[pos++] < 128) return new Varint64(hi, lo, pos - startPos); + } // 4th + + + lo = (lo | (buf[pos++] & 127) << i * 7) >>> 0; + return new Varint64(hi, lo, pos - startPos); + } + + if (buf.byteLength - pos > 4) { + // fast route (hi) + for (; i < 5; ++i) { + // 6th..10th + hi = (hi | (buf[pos] & 127) << i * 7 + 3) >>> 0; + if (buf[pos++] < 128) return new Varint64(hi, lo, pos - startPos); + } + } else { + for (; i < 5; ++i) { + /* istanbul ignore if */ + if (pos >= buf.byteLength) throw new Error('Read varint error: index out of range'); // 6th..10th + + hi = (hi | (buf[pos] & 127) << i * 7 + 3) >>> 0; + if (buf[pos++] < 128) return new Varint64(hi, lo, pos - startPos); + } + } + /* istanbul ignore next */ + + + throw Error("invalid varint encoding"); + }; + + Varint64.Zero = new Varint64(0, 0); + return Varint64; +}(); + +var BufferReader = +/** @class */ +function () { + function BufferReader() { + this._pos = 0; + } + + BufferReader.prototype.load = function (buf, pos) { + if (pos === void 0) { + pos = 0; + } + + this._buf = buf; + this._pos = pos; + this._view = new DataView(buf.buffer); + }; + + BufferReader.prototype.readVarint = function () { + var varint = Varint64.readFromBuffer(this._buf, this._pos); + this._pos += varint.byteLength; + return varint; + }; + + BufferReader.prototype.readUint = function () { + return this.readVarint().toNumber(true); + }; + + BufferReader.prototype.readInt = function () { + return this.readVarint().zzDecode().toNumber(); + }; + + BufferReader.prototype.readDouble = function () { + var pos = this._pos; + this._pos += 8; + return this._view.getFloat64(this._buf.byteOffset + pos); + }; + + BufferReader.prototype.readString = function () { + var strByteLength = this.readUint(); + var str = Utf8Coder.read(this._buf, this._pos, strByteLength); + this._pos += strByteLength; + return str; + }; + + BufferReader.prototype.readBuffer = function () { + var bufByteLength = this.readUint(); + + var buf = this._buf.subarray(this._pos, this._pos + bufByteLength); + + this._pos += bufByteLength; + return buf; + }; + + BufferReader.prototype.skip = function (byteLength) { + this._pos += byteLength; + }; + + BufferReader.prototype.skipByLengthType = function (lengthType) { + if (lengthType === LengthType.Bit64) { + this._pos += 8; + } else if (lengthType === LengthType.Varint) { + this.readVarint(); + } else if (lengthType === LengthType.LengthDelimited) { + var bufByteLength = this.readUint(); + this._pos += bufByteLength; + } else if (lengthType === LengthType.IdBlock) { + this.skipIdBlock(); + } else { + throw new Error('Unknown lengthType: ' + lengthType); + } + }; + + BufferReader.prototype.skipIdBlock = function () { + var idNum = this.readUint(); + + for (var i = 0; i < idNum; ++i) { + var id = this.readUint(); + var lengthType = id & 3; + this.skipByLengthType(lengthType); + } + }; + + BufferReader.prototype.readBoolean = function () { + var value = this._view.getUint8(this._buf.byteOffset + this._pos++); + + if (value === 255) { + return true; + } else if (value === 0) { + return false; + } else { + throw new Error("Invalid boolean encoding [" + value + "] at pos " + (this._pos - 1)); + } + }; + + Object.defineProperty(BufferReader.prototype, "unreadByteLength", { + get: function get() { + return this._buf.byteLength - this._pos; + }, + enumerable: false, + configurable: true + }); + + BufferReader.prototype.dispose = function () { + this._buf = this._view = undefined; + }; + + return BufferReader; +}(); +/** @internal */ + + +var Decoder = +/** @class */ +function () { + function Decoder(options) { + this._options = options; + this._reader = new BufferReader(); + this._validator = options.validator; + } + + Decoder.prototype.decode = function (buffer, schema) { + this._reader.load(buffer); + + return this._read(schema); + }; + + Decoder.prototype._read = function (schema) { + switch (schema.type) { + case SchemaType.Boolean: + return this._reader.readBoolean(); + + case SchemaType.Number: + return this._readNumber(schema); + + case SchemaType.String: + return this._reader.readString(); + + case SchemaType.Array: + { + var output = []; // 数组长度:Varint + + var length_1 = this._reader.readUint(); + + for (var i = 0; i < length_1; ++i) { + var item = this._read(schema.elementType); + + output.push(item); + } + + return output; + } + + case SchemaType.Tuple: + { + if (schema.elementTypes.length > 64) { + throw new Error('Elements oversized, maximum supported tuple elements is 64, now get ' + schema.elementTypes.length); + } + + var output = []; // PayloadMask: Varint64 + + var payloadMask = this._reader.readVarint(); // 计算maskIndices + + + var maskIndices = []; // Low + + for (var i = 0; i < 32; ++i) { + if (payloadMask.uint32s[1] & 1 << i) { + maskIndices.push(i); + } + } // High + + + for (var i = 0; i < 32; ++i) { + if (payloadMask.uint32s[0] & 1 << i) { + maskIndices.push(i + 32); + } + } + + if (!maskIndices.length) { + return []; + } + + var maxIndex = maskIndices.last(); + + for (var i = 0, nextMaskIndex = 0, next = maskIndices[0]; i <= maxIndex; ++i) { + if (i === next) { + output[i] = this._read(schema.elementTypes[i]); + ++nextMaskIndex; + next = maskIndices[nextMaskIndex]; + } else { + output[i] = undefined; + } + } // undefined as null + + + for (var i = 0; i < schema.elementTypes.length; ++i) { + if (this._undefinedAsNull(output[i], schema.elementTypes[i], schema.optionalStartIndex !== undefined && i >= schema.optionalStartIndex)) { + output[i] = null; + } + } + + return output; + } + + case SchemaType.Enum: + var enumId_1 = this._reader.readVarint().toNumber(); + + var enumItem = schema.members.find(function (v) { + return v.id === enumId_1; + }); + + if (!enumItem) { + throw new Error("Invalid enum encoding: unexpected id " + enumId_1); + } + + return enumItem.value; + + case SchemaType.Any: + case SchemaType.Object: + var jsonStr = this._reader.readString(); + + if (jsonStr === 'undefined') { + return undefined; + } + + return JSON.parse(jsonStr); + + case SchemaType.Literal: + return schema.literal; + + case SchemaType.Interface: + return this._readInterface(schema); + + case SchemaType.Buffer: + var uint8Arr = this._reader.readBuffer(); + + if (schema.arrayType) { + if (schema.arrayType === 'BigInt64Array' || schema.arrayType === 'BigUint64Array') { + throw new Error('Unsupported arrayType: ' + schema.arrayType); + } // Uint8Array 性能最高 + else if (schema.arrayType === 'Uint8Array') { + return uint8Arr; + } // 其余TypedArray 可能需要内存拷贝 性能次之 + else { + var typedArr = TypedArrays[schema.arrayType]; // 字节对齐,可以直接转,无需拷贝内存 + + if (uint8Arr.byteOffset % typedArr.BYTES_PER_ELEMENT === 0) { + return new typedArr(uint8Arr.buffer, uint8Arr.byteOffset, uint8Arr.byteLength / typedArr.BYTES_PER_ELEMENT); + } // 字节不对齐,不能直接转,只能拷贝内存后再生成 + else { + var arrBuf = uint8Arr.buffer.slice(uint8Arr.byteOffset, uint8Arr.byteOffset + uint8Arr.byteLength); + return new typedArr(arrBuf); + } + } + } else { + // ArrayBuffer涉及内存拷贝,性能较低,不建议用 + return uint8Arr.buffer.slice(uint8Arr.byteOffset, uint8Arr.byteOffset + uint8Arr.byteLength); + } + + case SchemaType.IndexedAccess: + case SchemaType.Reference: + return this._read(this._validator.protoHelper.parseReference(schema)); + + case SchemaType.Partial: + case SchemaType.Pick: + case SchemaType.Omit: + case SchemaType.Overwrite: + var parsed = this._validator.protoHelper.parseMappedType(schema); + + if (parsed.type === 'Interface') { + return this._readPureMappedType(schema); + } else if (parsed.type === 'Union') { + return this._readUnionOrIntersection(parsed); + } + + break; + + case SchemaType.Union: + case SchemaType.Intersection: + return this._readUnionOrIntersection(schema); + + case SchemaType.Date: + return new Date(this._reader.readUint()); + + case SchemaType.NonNullable: + return this._read(schema.target); + + default: + throw new Error("Unrecognized schema type: " + schema.type); + } + }; + /** + * PureMappedType 每一层的target 都是MappedType或Interface(最终层) + */ + + + Decoder.prototype._readPureMappedType = function (schema) { + var output; + var overwrite; + + if (schema.type === 'Overwrite') { + // Overwrite Block + overwrite = this._read(schema.overwrite); + } + + var parsedTarget = this._validator.protoHelper.parseReference(schema.target); + + if (parsedTarget.type === 'Interface') { + output = this._readInterface(parsedTarget); + } else if (parsedTarget.type === 'Pick' || parsedTarget.type === 'Omit' || parsedTarget.type === 'Partial' || parsedTarget.type === 'Overwrite') { + output = this._readPureMappedType(parsedTarget); + } else { + throw new Error('Invalid PureMappedType child: ' + schema.type); + } // filter key + + + if (schema.type === 'Pick') { + // 把Pick以外的剔除 + for (var key in output) { + if (schema.keys.indexOf(key) === -1) { + delete output[key]; + } + } + } else if (schema.type === 'Omit') { + // 剔除Omit + for (var key in output) { + if (schema.keys.indexOf(key) > -1) { + delete output[key]; + } + } + } else if (schema.type === 'Overwrite') { + Object.assign(output, overwrite); + } // Partial 原样返回 + + + return output; + }; + + Decoder.prototype._readNumber = function (schema) { + // 默认为double + var scalarType = schema.scalarType || 'double'; + + switch (scalarType) { + // 定长编码 + case 'double': + return this._reader.readDouble(); + // Varint编码 + + case 'int': + return this._reader.readInt(); + + case 'uint': + return this._reader.readUint(); + + default: + throw new Error('Scalar type not support : ' + scalarType); + } + }; + + Decoder.prototype._readInterface = function (schema) { + var output = {}; + + var flatSchema = this._validator.protoHelper.getFlatInterfaceSchema(schema); // BlockID数量 + + + var blockIdNum = this._reader.readUint(); + + var _loop_1 = function _loop_1(i) { + // ReadBlock + var readBlockId = this_1._reader.readUint(); + + var lengthType = readBlockId & 3; + var blockId = readBlockId >> 2; // indexSignature + + if (blockId === 0) { + if (flatSchema.indexSignature) { + var type = flatSchema.indexSignature.type; + + var fieldName = this_1._reader.readString(); + + this_1._skipIdLengthPrefix(this_1._validator.protoHelper.parseReference(type)); + + output[fieldName] = this_1._read(type); + } // indexSignature未定义,可能是新协议,此处兼容,根据lengthType跳过 + else { + // skip fieldName + this_1._reader.skipByLengthType(LengthType.LengthDelimited); // skipPayload + + + this_1._reader.skipByLengthType(lengthType); + } + } // extend block + else if (blockId <= 9) { + var extendId_1 = blockId - 1; + var extend = schema.extends && schema.extends.find(function (v) { + return v.id === extendId_1; + }); + + if (extend) { + this_1._skipIdLengthPrefix(this_1._validator.protoHelper.parseReference(extend.type)); + + var extendValue = this_1._read(extend.type); + + Object.assign(output, extendValue); + } // 未知的extendId 可能是新协议 跳过 + else { + // skipPayload + this_1._reader.skipByLengthType(lengthType); + } + } // property + else { + var propertyId_1 = blockId - 10; + var property = schema.properties && schema.properties.find(function (v) { + return v.id === propertyId_1; + }); + + if (property) { + this_1._skipIdLengthPrefix(this_1._validator.protoHelper.parseReference(property.type)); + + output[property.name] = this_1._read(property.type); + } // 未知的PropertyID 可能是新协议 跳过 + else { + // skipPayload + this_1._reader.skipByLengthType(lengthType); + } + } + }; + + var this_1 = this; + + for (var i = 0; i < blockIdNum; ++i) { + _loop_1(); + } // Literal property 由于不编码 将其补回 + // undefined as null + + + for (var _i = 0, _a = flatSchema.properties; _i < _a.length; _i++) { + var property = _a[_i]; + + if (output.hasOwnProperty(property.name)) { + continue; + } // Literal + + + var parsedType = this._validator.protoHelper.parseReference(property.type); + + if (parsedType.type === 'Literal') { + output[property.name] = parsedType.literal; + continue; + } // undefined as null + + + if (this._undefinedAsNull(output[property.name], parsedType, property.optional)) { + output[property.name] = null; + continue; + } + } + + return output; + }; + /** @internal 是否该null值小于当做undefined编码 */ + + + Decoder.prototype._undefinedAsNull = function (value, type, isOptional) { + return value === undefined && this._options.undefinedAsNull && !SchemaUtil.canBeLiteral(type, undefined) && !isOptional && SchemaUtil.canBeLiteral(type, null); + }; + + Decoder.prototype._skipIdLengthPrefix = function (parsedSchema) { + var lengthInfo = IdBlockUtil.getPayloadLengthInfo(parsedSchema); + + if (lengthInfo.needLengthPrefix) { + // skip length prefix + this._reader.skipByLengthType(LengthType.Varint); + } + }; + + Decoder.prototype._readUnionOrIntersection = function (schema) { + var output; + + var idNum = this._reader.readUint(); + + var _loop_2 = function _loop_2(i) { + var readId = this_2._reader.readUint(); + + var lengthType = readId & 3; + var id = readId >> 2; + var member = schema.members.find(function (v) { + return v.id === id; + }); // 不可识别的Member,可能是新协议,跳过使兼容 + + if (!member) { + this_2._reader.skipByLengthType(lengthType); + + return "continue"; + } + + this_2._skipIdLengthPrefix(this_2._validator.protoHelper.parseReference(member.type)); + + var value = this_2._read(member.type); + + if (this_2._isObject(output) && this_2._isObject(value)) { + Object.assign(output, value); + } else { + output = value; + } + }; + + var this_2 = this; + + for (var i = 0; i < idNum; ++i) { + _loop_2(); + } + + if (this._undefinedAsNull(output, schema)) { + output = null; + } + + return output; + }; + + Decoder.prototype._isObject = function (value) { + return _typeof(value) === 'object' && value !== null; + }; + + return Decoder; +}(); +/** @internal */ + + +var Config = { + interface: { + maxExtendsNum: 9 + } +}; +/** + * 用Op来串联 next + * Op包含 function next length + * 先度量长度再执行编码 + * 一次性编码 + * 使用BufferPool + * writer.uint32(xx).string(xxx).finish(); + * @internal + */ + +var BufferWriter = +/** @class */ +function () { + function BufferWriter() { + this._ops = []; + } + + Object.defineProperty(BufferWriter.prototype, "ops", { + get: function get() { + return this._ops; + }, + enumerable: false, + configurable: true + }); + + BufferWriter.prototype.clear = function () { + this._ops = []; + }; + + BufferWriter.prototype.push = function (req) { + this._ops.push(this.req2op(req)); + + return this; + }; + + BufferWriter.prototype.req2op = function (req) { + if (req.type === 'string' || req.type === 'buffer') { + var valueLength = this.measureLength(req); // Length + + this.push({ + type: 'varint', + value: Varint64.from(valueLength) + }); // Value + + return __assign(__assign({}, req), { + length: valueLength + }); + } else { + var length_1 = this.measureLength(req); + return __assign(__assign({}, req), { + length: length_1 + }); + } + }; + + BufferWriter.prototype.measureLength = function (req) { + switch (req.type) { + case 'varint': + return req.value.byteLength; + + case 'string': + return Utf8Coder.measureLength(req.value); + + case 'buffer': + return req.value.byteLength; + + case 'double': + return 8; + + case 'boolean': + return 1; + + default: + return NaN; + } + }; + + BufferWriter.prototype.finish = function () { + var byteLength = this._ops.sum(function (v) { + return v.length; + }); + + var pos = 0; + var buf = new Uint8Array(byteLength); + var view = new DataView(buf.buffer); + + for (var _i = 0, _a = this._ops; _i < _a.length; _i++) { + var op = _a[_i]; + + switch (op.type) { + case 'varint': + var newPos = op.value.writeToBuffer(buf, pos); + + if (newPos !== pos + op.length) { + throw new Error("Error varint measuredLength " + op.length + ", actual is " + (newPos - pos) + ", value is " + op.value.toNumber()); + } + + break; + + case 'double': + view.setFloat64(buf.byteOffset + pos, op.value); + break; + + case 'string': + var encLen = Utf8Coder.write(op.value, buf, pos); + + if (encLen !== op.length) { + throw new Error("Expect " + op.length + " bytes but encoded " + encLen + " bytes"); + } + + break; + + case 'buffer': + buf.subarray(pos, pos + op.length).set(op.value); + break; + + case 'boolean': + view.setUint8(buf.byteOffset + pos, op.value ? 255 : 0); + break; + } + + pos += op.length; + } + + return buf; + }; + + return BufferWriter; +}(); +/** @internal */ + + +var Encoder = +/** @class */ +function () { + function Encoder(options) { + this._options = options; + this._writer = new BufferWriter(); + this._validator = options.validator; + } + + Encoder.prototype.encode = function (value, schema) { + this._writer.clear(); + + this._write(value, schema); + + return this._writer.finish(); + }; + + Encoder.prototype._write = function (value, schema, options) { + switch (schema.type) { + case SchemaType.Boolean: + this._writer.push({ + type: 'boolean', + value: value + }); + + break; + + case SchemaType.Number: + this._writeNumber(value, schema); + + break; + + case SchemaType.String: + this._writer.push({ + type: 'string', + value: value + }); + + break; + + case SchemaType.Array: + { + var _v = value; // 数组长度:Varint + + this._writer.push({ + type: 'varint', + value: Varint64.from(_v.length) + }); // Element Payload + + + for (var i = 0; i < _v.length; ++i) { + this._write(_v[i], schema.elementType); + } + + break; + } + + case SchemaType.Tuple: + { + if (schema.elementTypes.length > 64) { + throw new Error('Elements oversized, maximum supported tuple elements is 64, now get ' + schema.elementTypes.length); + } + + var _v = value; // 计算maskPos(要编码的值的index) + + var maskIndices = []; + + for (var i = 0; i < _v.length; ++i) { + // undefined 不编码 + // null as undefined + if (_v[i] === undefined || this._nullAsUndefined(_v[i], schema.elementTypes[i])) { + continue; + } + + maskIndices.push(i); + } // 生成PayloadMask:Varint64 + + + var lo = 0; + var hi = 0; + + for (var _i = 0, maskIndices_1 = maskIndices; _i < maskIndices_1.length; _i++) { + var v = maskIndices_1[_i]; + + if (v < 32) { + lo |= 1 << v; + } else { + hi |= 1 << v - 32; + } + } + + this._writer.push({ + type: 'varint', + value: new Varint64(hi, lo) + }); // Element Payload + + + for (var _a = 0, maskIndices_2 = maskIndices; _a < maskIndices_2.length; _a++) { + var i = maskIndices_2[_a]; + + this._write(_v[i], schema.elementTypes[i]); + } + + break; + } + + case SchemaType.Enum: + var enumItem = schema.members.find(function (v) { + return v.value === value; + }); + + if (!enumItem) { + throw new Error("Unexpect enum value: " + value); + } + + this._writer.push({ + type: 'varint', + value: Varint64.from(enumItem.id) + }); + + break; + + case SchemaType.Any: + if (value === undefined) { + this._writer.push({ + type: 'string', + value: 'undefined' + }); + } else { + this._writer.push({ + type: 'string', + value: JSON.stringify(value) + }); + } + + break; + + case SchemaType.Object: + this._writer.push({ + type: 'string', + value: JSON.stringify(value) + }); + + break; + + case SchemaType.Literal: + break; + + case SchemaType.Interface: + this._writeInterface(value, schema, options); + + break; + + case SchemaType.Buffer: + this._writeBuffer(value, schema); + + break; + + case SchemaType.IndexedAccess: + case SchemaType.Reference: + this._write(value, this._validator.protoHelper.parseReference(schema), options); + + break; + + case SchemaType.Partial: + case SchemaType.Pick: + case SchemaType.Omit: + case SchemaType.Overwrite: + var parsed = this._validator.protoHelper.parseMappedType(schema); + + if (parsed.type === 'Interface') { + this._writePureMappedType(value, schema, options); + } else { + this._writeUnion(value, parsed, options === null || options === void 0 ? void 0 : options.skipFields); + } + + break; + + case SchemaType.Union: + this._writeUnion(value, schema, options === null || options === void 0 ? void 0 : options.skipFields); + + break; + + case SchemaType.Intersection: + this._writeIntersection(value, schema, options === null || options === void 0 ? void 0 : options.skipFields); + + break; + + case SchemaType.Date: + this._writer.push({ + type: 'varint', + value: Varint64.from(value.getTime()) + }); + + break; + + case SchemaType.NonNullable: + this._write(value, schema.target, options); + + break; + + default: + throw new Error("Unrecognized schema type: " + schema.type); + } + }; + + Encoder.prototype._writePureMappedType = function (value, schema, options) { + if (!options) { + options = {}; + } + + if (schema.type === 'Pick') { + // 已存在 取交集 + if (options.pickFields) { + var newPickFields = {}; + + for (var _i = 0, _a = schema.keys; _i < _a.length; _i++) { + var v = _a[_i]; + + if (options.pickFields[v]) { + newPickFields[v] = 1; + } + } + + options.pickFields = newPickFields; + } // 不存在 初始化 + else { + options.pickFields = {}; + + for (var _b = 0, _c = schema.keys; _b < _c.length; _b++) { + var v = _c[_b]; + options.pickFields[v] = 1; + } + } + } else if (schema.type === 'Omit') { + // 不存在 初始化 + if (!(options === null || options === void 0 ? void 0 : options.skipFields)) { + if (!options) { + options = {}; + } + + options.skipFields = {}; + } // 取并集 + + + for (var _d = 0, _e = schema.keys; _d < _e.length; _d++) { + var v = _e[_d]; + options.skipFields[v] = 1; + } + } else if (schema.type === 'Overwrite') { + var parsed = this._parseOverwrite(value, schema); // 写入Overwrite部分 + + + this._write(parsed.overwriteValue, parsed.overwrite, options); + } else if (schema.type === 'Partial') ;else { + throw new Error('Invalid PureMappedType child: ' + schema.type); + } // Write Interface + + + var parsedTarget = this._validator.protoHelper.parseReference(schema.target); + + if (parsedTarget.type === 'Interface') { + this._writeInterface(value, parsedTarget, options); + } else { + this._writePureMappedType(value, parsedTarget, options); + } + }; + + Encoder.prototype._writeNumber = function (value, schema) { + // 默认为double + var scalarType = schema.scalarType || 'double'; + + switch (scalarType) { + // 定长编码 + case 'double': + this._writer.push({ + type: scalarType, + value: value + }); + + break; + // Varint编码 + + case 'int': + this._writer.push({ + type: 'varint', + value: Varint64.from(value).zzEncode() + }); + + break; + + case 'uint': + this._writer.push({ + type: 'varint', + value: Varint64.from(value) + }); + + break; + + default: + throw new Error('Scalar type not support : ' + scalarType); + } + }; + + Encoder.prototype._writeInterface = function (value, schema, options) { + // skipFields默认值 + if (!options) { + options = {}; + } + + if (!options.skipFields) { + options.skipFields = {}; + } // 记录起始op位置,用于最后插入BlockID数量 + + + var opStartOps = this._writer.ops.length; + var blockIdCount = 0; // 以下,interface + // extends + + if (schema.extends) { + // 支持的继承数量有上限 + if (schema.extends.length > Config.interface.maxExtendsNum) { + throw new Error("Max support " + Config.interface.maxExtendsNum + " extends, actual: " + schema.extends.length); + } + + for (var _i = 0, _a = schema.extends; _i < _a.length; _i++) { + var extend = _a[_i]; // BlockID = extend.id + 1 + + var blockId = extend.id + 1; + + this._writer.push({ + type: 'varint', + value: Varint64.from(blockId) + }); + + var blockIdPos = this._writer.ops.length - 1; // 写入extend interface前 writeOps的长度 + + var opsLengthBeforeWrite = this._writer.ops.length; // extend Block + + var parsedExtend = this._validator.protoHelper.parseReference(extend.type); + + this._writeInterface(value, parsedExtend, __assign(__assign({}, options), { + // 确保indexSignature是在最小层级编码 + skipIndexSignature: !!schema.indexSignature || options.skipIndexSignature // 如果父级有indexSignature 或 父级跳过 则跳过indexSignature + + })); // 写入前后writeOps只增加了一个(block length),说明该extend并未写入任何property字段,取消编码这个block + + + if (this._writer.ops.length === opsLengthBeforeWrite + 1) { + // 移除BlockID + this._writer.ops.splice(this._writer.ops.length - 2, 2); + } // extend写入成功 blockId数量+1 + else { + ++blockIdCount; + + this._processIdWithLengthType(blockIdPos, extend.type); + } + } + } // property + + + if (schema.properties) { + for (var _b = 0, _c = schema.properties; _b < _c.length; _b++) { + var property = _c[_b]; + + var parsedType = this._validator.protoHelper.parseReference(property.type); + + var propValue = value[property.name]; // PickFields + + if (options.pickFields && !options.pickFields[property.name]) { + continue; + } // Literal不编码 直接跳过 + + + if (parsedType.type === 'Literal') { + options.skipFields[property.name] = 1; + continue; + } // null as undefined + + + if (this._nullAsUndefined(propValue, property.type)) { + propValue = undefined; + } // undefined不编码 + + + if (propValue === undefined) { + continue; + } // SkipFields + + + if (options.skipFields[property.name]) { + continue; + } + + options.skipFields[property.name] = 1; + var blockId = property.id + Config.interface.maxExtendsNum + 1; // BlockID (propertyID) + + this._writer.push({ + type: 'varint', + value: Varint64.from(blockId) + }); + + var blockIdPos = this._writer.ops.length - 1; // Value Payload + + this._write(propValue, parsedType); + + ++blockIdCount; + + this._processIdWithLengthType(blockIdPos, parsedType); + } + } // indexSignature + + + if (!options.skipIndexSignature) { + var flat = this._validator.protoHelper.getFlatInterfaceSchema(schema); + + if (flat.indexSignature) { + for (var key in value) { + if (value[key] === undefined || this._nullAsUndefined(value[key], flat.indexSignature.type)) { + continue; + } // PickFields + + + if (options.pickFields && !options.pickFields[key]) { + continue; + } // SkipFields + + + if (options.skipFields[key]) { + continue; + } + + options.skipFields[key] = 1; // BlockID == 0 + + this._writer.push({ + type: 'varint', + value: Varint64.from(0) + }); + + var blockIdPos = this._writer.ops.length - 1; // 字段名 + + this._writer.push({ + type: 'string', + value: key + }); + + var lengthPrefixPos = this._writer.ops.length; // Value Payload + + this._write(value[key], flat.indexSignature.type); + + ++blockIdCount; + + this._processIdWithLengthType(blockIdPos, flat.indexSignature.type, lengthPrefixPos); + } + } + } + + this._writer.ops.splice(opStartOps, 0, this._writer.req2op({ + type: 'varint', + value: Varint64.from(blockIdCount) + })); + }; + /** @internal 是否该null值小于当做undefined编码 */ + + + Encoder.prototype._nullAsUndefined = function (value, type) { + return value === null && this._options.nullAsUndefined && !SchemaUtil.canBeLiteral(type, null); // && SchemaUtil.canBeLiteral(type, undefined) 一定为true 因为先validate过了 + }; + + Encoder.prototype._parseOverwrite = function (value, schema) { + var skipFields = {}; // 解引用 + + var target = this._validator.protoHelper.parseReference(schema.target); + + var overwrite = this._validator.protoHelper.parseReference(schema.overwrite); + + var flatTarget = this._validator.protoHelper.getFlatInterfaceSchema(target); + + var flatOverwrite = this._validator.protoHelper.getFlatInterfaceSchema(overwrite); // 先区分哪些字段进入Target块,哪些字段进入Overwrite块 + + + var overwriteValue = {}; + var targetValue = {}; // Overwrite块 property + + if (flatOverwrite.properties) { + // 只要Overwrite中有此Property,即在Overwrite块编码 + for (var _i = 0, _a = flatOverwrite.properties; _i < _a.length; _i++) { + var property = _a[_i]; // undefined不编码,跳过SkipFIelds + + if (value[property.name] !== undefined && !skipFields[property.name]) { + overwriteValue[property.name] = value[property.name]; + skipFields[property.name] = 1; + } + } + } // Target块 property + + + if (flatTarget.properties) { + for (var _b = 0, _c = flatTarget.properties; _b < _c.length; _b++) { + var property = _c[_b]; // undefined不编码,跳过SkipFields + + if (value[property.name] !== undefined && !skipFields[property.name]) { + targetValue[property.name] = value[property.name]; + skipFields[property.name] = 1; + } + } + } // indexSignature + + + var indexSignatureWriteValue; // indexSignature要写入的目标(overwrite或target) + + var indexSignature; // IndexSignature,优先使用Overwrite的 + + if (flatOverwrite.indexSignature) { + indexSignature = flatOverwrite.indexSignature; + indexSignatureWriteValue = overwriteValue; + } else if (flatTarget.indexSignature) { + indexSignature = flatTarget.indexSignature; + indexSignatureWriteValue = targetValue; + } + + if (indexSignature) { + for (var key in value) { + if (skipFields[key]) { + continue; + } + + indexSignatureWriteValue[key] = value[key]; + skipFields[key] = 1; + } + } // 编码,此处不再需要SkipFields,因为已经筛选过 + + + return { + target: target, + targetValue: targetValue, + overwrite: overwrite, + overwriteValue: overwriteValue + }; + }; + + Encoder.prototype._writeUnion = function (value, schema, skipFields, unionProperties) { + // 计算unionProperties + // if (!unionProperties) { + // unionProperties = skipFields ? Object.keys(skipFields) : []; + // } + // this._validator.protoHelper.getUnionProperties(schema).forEach(v => { + // unionProperties!.binaryInsert(v, true); + // }) + if (skipFields === void 0) { + skipFields = {}; + } // 记住编码起点 + + + var encodeStartPos = this._writer.ops.length; + var idNum = 0; // null as undefined + + if (this._nullAsUndefined(value, schema)) { + value = undefined; + } + + for (var _i = 0, _a = schema.members; _i < _a.length; _i++) { + var member = _a[_i]; // 验证该member是否可以编码 + + var vRes = this._validator.validate(value, member.type, { + // 禁用excessPropertyChecks(以代替unionProperties) + excessPropertyChecks: false, + // 启用strictNullChecks(null as undefined已经前置处理) + strictNullChecks: true + }); + + if (vRes.isSucc) { + // 编码 + // Part2: ID + this._writer.push({ + type: 'varint', + value: Varint64.from(member.id) + }); + + var idPos = this._writer.ops.length - 1; // Part3: Payload + + if (member.type.type === 'Union') { + this._writeUnion(value, member.type, skipFields); + } else { + this._write(value, member.type, { + skipFields: skipFields + }); + } + + idNum++; + + this._processIdWithLengthType(idPos, member.type); // 非object的value,类型一定互斥,只编码一个足矣 + + + if (_typeof(value) !== 'object') { + break; + } + } + } // 已经编码 + + + if (idNum > 0) { + // 前置ID数量 + this._writer.ops.splice(encodeStartPos, 0, this._writer.req2op({ + type: 'varint', + value: Varint64.from(idNum) + })); + + return; + } else { + // 未编码,没有任何条件满足,抛出异常 + throw new Error('Non member is satisfied for union type'); + } + }; + + Encoder.prototype._writeIntersection = function (value, schema, skipFields) { + if (skipFields === void 0) { + skipFields = {}; + } // ID数量(member数量) + + + this._writer.push({ + type: 'varint', + value: Varint64.from(schema.members.length) + }); // 按Member依次编码 + + + for (var _i = 0, _a = schema.members; _i < _a.length; _i++) { + var member = _a[_i]; // ID + + this._writer.push({ + type: 'varint', + value: Varint64.from(member.id) + }); + + var idPos = this._writer.ops.length - 1; // 编码块 + + this._write(value, member.type, { + skipFields: skipFields + }); + + this._processIdWithLengthType(idPos, member.type); + } + }; + + Encoder.prototype._writeBuffer = function (value, schema) { + // ArrayBuffer 转为Uint8Array + if (value instanceof ArrayBuffer) { + this._writer.push({ + type: 'buffer', + value: new Uint8Array(value) + }); + } // Uint8Array 直接写入 + else if (value instanceof Uint8Array) { + this._writer.push({ + type: 'buffer', + value: value + }); + } // 其它TypedArray 转为Uint8Array + else { + var key = value.constructor.name; + var arrType = TypedArrays[key]; + var uint8Arr = new Uint8Array(value.buffer, value.byteOffset, value.length * arrType.BYTES_PER_ELEMENT); + + this._writer.push({ + type: 'buffer', + value: uint8Arr + }); + } + }; // private _writeIdBlocks(blocks: IDBlockItem[]) { + // // 字段数量: Varint + // this._writer.push({ type: 'varint', value: Varint64.from(blocks.length) }); + // // 依次编码 + // for (let item of blocks) { + // // ID + // this._writer.push({ type: 'varint', value: Varint64.from(item.id) }); + // // Payload + // this._write(item.value, item.schema) + // } + // } + + /** + * 重新处理ID位,使其加入末位长度信息2Bit + * @param idPos + */ + + + Encoder.prototype._processIdWithLengthType = function (idPos, payloadType, lengthPrefixPos) { + var idOp = this._writer.ops[idPos]; + + if (idOp.type !== 'varint') { + throw new Error('Error idPos: ' + idPos); + } // 解引用 + + + var parsedSchema = this._validator.protoHelper.parseReference(payloadType); + + var lengthInfo = IdBlockUtil.getPayloadLengthInfo(parsedSchema); + var newId = (idOp.value.toNumber() << 2) + lengthInfo.lengthType; + this._writer.ops[idPos] = this._writer.req2op({ + type: 'varint', + value: Varint64.from(newId) + }); + + if (lengthInfo.needLengthPrefix) { + var payloadByteLength = this._writer.ops.filter(function (v, i) { + return i > idPos; + }).sum(function (v) { + return v.length; + }); + + this._writer.ops.splice(lengthPrefixPos == undefined ? idPos + 1 : lengthPrefixPos, 0, this._writer.req2op({ + type: 'varint', + value: Varint64.from(payloadByteLength) + })); + } + }; + + return Encoder; +}(); +/** + * @public + */ + + +var TSBuffer = +/** @class */ +function () { + function TSBuffer(proto, options) { + /** @internal 默认配置 */ + this._options = { + excessPropertyChecks: true, + strictNullChecks: true, + skipEncodeValidate: false, + skipDecodeValidate: false, + cloneProto: true + }; // but `options.validatorOptions` has higher priority to validate process (don't affect encode) + + this._options = __assign(__assign({}, this._options), options); + this._proto = this._options.cloneProto ? Object.merge({}, proto) : proto; + this._validator = new TSBufferValidator(this._proto, { + excessPropertyChecks: this._options.excessPropertyChecks, + strictNullChecks: this._options.strictNullChecks + }); + this.validate = this._validator.validate.bind(this._validator); + this.prune = this._validator.prune.bind(this._validator); + this._encoder = new Encoder({ + validator: this._validator, + // if !strictNullChecks, then encoder can convert null to undefined + nullAsUndefined: !this._options.strictNullChecks + }); + this._decoder = new Decoder({ + validator: this._validator, + // if !strictNullChecks, then decoder can convert undefined to null + undefinedAsNull: !this._options.strictNullChecks + }); + } + /** + * 编码 + * @param value - 要编码的值 + * @param schemaOrId - Schema 或 SchemaID,例如`a/b.ts`下的`Test`类型,其ID为`a/b/Test` + */ + + + TSBuffer.prototype.encode = function (value, schemaOrId, options) { + var _a; + + var schema; + + if (typeof schemaOrId === 'string') { + schema = this._proto[schemaOrId]; + + if (!schema) { + return { + isSucc: false, + errMsg: "Cannot find schema\uFF1A " + schemaOrId + }; + } + } else { + schema = schemaOrId; + } // validate before encode + + + if (!((_a = options === null || options === void 0 ? void 0 : options.skipValidate) !== null && _a !== void 0 ? _a : this._options.skipEncodeValidate)) { + var vRes = this._validator.validate(value, schema, { + // 禁用excessPropertyChecks,因为不会编码excess property + excessPropertyChecks: false + }); + + if (!vRes.isSucc) { + return vRes; + } + } + + var buf; + + try { + buf = this._encoder.encode(value, schema); + } catch (e) { + return { + isSucc: false, + errMsg: e.message + }; + } + + return { + isSucc: true, + buf: buf + }; + }; + /** + * 解码 + * @param buf - 待解码的二进制数据 + * @param schemaOrId - Schema 或 SchemaID,例如`a/b.ts`下的`Test`类型,其ID为`a/b/Test` + */ + + + TSBuffer.prototype.decode = function (buf, schemaOrId, options) { + var _a; + + var schema; + + if (typeof schemaOrId === 'string') { + schema = this._proto[schemaOrId]; + + if (!schema) { + return { + isSucc: false, + errMsg: "Cannot find schema\uFF1A " + schemaOrId + }; + } + } else { + schema = schemaOrId; + } + + var value; + + try { + value = this._decoder.decode(buf, schema); + } catch (e) { + return { + isSucc: false, + errMsg: e.message + }; + } + + if (!((_a = options === null || options === void 0 ? void 0 : options.skipValidate) !== null && _a !== void 0 ? _a : this._options.skipDecodeValidate)) { + var vRes = this._validator.validate(value, schema); + + if (!vRes.isSucc) { + return vRes; + } + } + + return { + isSucc: true, + value: value + }; + }; + + return TSBuffer; +}(); + +/*! + * TSRPC Base Client v1.0.6 + * ----------------------------------------- + * Copyright (c) Kingworks Corporation. + * MIT License + * https://github.com/k8w/tsrpc-base-client + */ +/** + * An auto-increment counter + */ + +var Counter = +/** @class */ +function () { + function Counter(min, max) { + if (min === void 0) { + min = 1; + } + + if (max === void 0) { + max = Number.MAX_SAFE_INTEGER; + } + + this._min = min; + this._max = max; + this._last = max; + } + /** + * Reset the counter, makes `getNext()` restart from `0` + */ + + + Counter.prototype.reset = function () { + this._last = this._max; + }; + /** + * Get next counter value, and auto increment `1` + * @param notInc - Just get the next possible value, not actually increasing the sequence + */ + + + Counter.prototype.getNext = function (notInc) { + return this._last >= this._max ? this._last = this._min : notInc ? this._last : ++this._last; + }; + + Object.defineProperty(Counter.prototype, "last", { + /** + * Last return of `getNext()` + */ + get: function get() { + return this._last; + }, + enumerable: false, + configurable: true + }); + return Counter; +}(); +/** + * A `Flow` is consists of many `FlowNode`, which is function with the same input and output (like pipeline). + * + * @remarks + * `Flow` is like a hook or event, executed at a specific time. + * The difference to event is it can be used to **interrupt** an action, by return `undefined` or `null` in a node. + */ + + +var Flow = +/** @class */ +function () { + function Flow() { + /** + * All node functions, if you want to adjust the sort you can modify this. + */ + this.nodes = []; + /** + * Event when error throwed from a `FlowNode` function. + * By default, it does nothing except print a `Uncaught FlowError` error log. + * @param e + * @param last + * @param input + * @param logger + */ + + this.onError = function (e, last, input, logger) { + logger === null || logger === void 0 ? void 0 : logger.error('Uncaught FlowError:', e); + }; + } + /** + * Execute all node function one by one, the previous output is the next input, + * until the last output would be return to the caller. + * + * @remarks + * If any node function return `null | undefined`, or throws an error, + * the latter node functions would not be executed. + * And it would return `null | undefined` immediately to the caller, + * which tell the caller it means a interruption, + * to let the caller stop latter behaviours. + * + * @param input The input of the first `FlowNode` + * @param logger Logger to print log, `undefined` means to hide all log. + * @returns + */ + + + Flow.prototype.exec = function (input, logger) { + return __awaiter(this, void 0, void 0, function () { + var res, i, e_1; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + res = input; + i = 0; + _a.label = 1; + + case 1: + if (!(i < this.nodes.length)) return [3 + /*break*/ + , 7]; + _a.label = 2; + + case 2: + _a.trys.push([2, 4,, 5]); + + return [4 + /*yield*/ + , this.nodes[i](res)]; + + case 3: + res = _a.sent(); + return [3 + /*break*/ + , 5]; + + case 4: + e_1 = _a.sent(); + this.onError(e_1, res, input, logger); + return [2 + /*return*/ + , undefined]; + + case 5: + // Return 非true 表示不继续后续流程 立即中止 + if (res === null || res === undefined) { + return [2 + /*return*/ + , res]; + } + + _a.label = 6; + + case 6: + ++i; + return [3 + /*break*/ + , 1]; + + case 7: + return [2 + /*return*/ + , res]; + } + }); + }); + }; + /** + * Append a node function to the last + * @param node + * @returns + */ + + + Flow.prototype.push = function (node) { + this.nodes.push(node); + return node; + }; + /** + * Remove a node function + * @param node + * @returns + */ + + + Flow.prototype.remove = function (node) { + return this.nodes.remove(function (v) { + return v === node; + }); + }; + + return Flow; +}(); +/** + * A manager for TSRPC receiving messages + */ + + +var MsgHandlerManager = +/** @class */ +function () { + function MsgHandlerManager() { + this._handlers = {}; + } + /** + * Execute all handlers parallelly + * @returns handlers count + */ + + + MsgHandlerManager.prototype.forEachHandler = function (msgName, logger) { + var args = []; + + for (var _i = 2; _i < arguments.length; _i++) { + args[_i - 2] = arguments[_i]; + } + + var handlers = this._handlers[msgName]; + + if (!handlers) { + return []; + } + + var output = []; + + for (var _a = 0, handlers_1 = handlers; _a < handlers_1.length; _a++) { + var handler = handlers_1[_a]; + + try { + output.push(handler.apply(void 0, args)); + } catch (e) { + logger === null || logger === void 0 ? void 0 : logger.error('[MsgHandlerError]', e); + } + } + + return output; + }; + /** + * Add message handler, duplicate handlers to the same `msgName` would be ignored. + * @param msgName + * @param handler + * @returns + */ + + + MsgHandlerManager.prototype.addHandler = function (msgName, handler) { + var handlers = this._handlers[msgName]; // 初始化Handlers + + if (!handlers) { + handlers = this._handlers[msgName] = []; + } // 防止重复监听 + else if (handlers.some(function (v) { + return v === handler; + })) { + return; + } + + handlers.push(handler); + }; + /** + * Remove handler from the specific `msgName` + * @param msgName + * @param handler + * @returns + */ + + + MsgHandlerManager.prototype.removeHandler = function (msgName, handler) { + var handlers = this._handlers[msgName]; + + if (!handlers) { + return; + } + + handlers.removeOne(function (v) { + return v === handler; + }); + }; + /** + * Remove all handlers for the specific `msgName` + * @param msgName + */ + + + MsgHandlerManager.prototype.removeAllHandlers = function (msgName) { + this._handlers[msgName] = undefined; + }; + + return MsgHandlerManager; +}(); +/** A utility for generate `ServiceMap` */ + + +var ServiceMapUtil = +/** @class */ +function () { + function ServiceMapUtil() {} + + ServiceMapUtil.getServiceMap = function (proto) { + var map = { + id2Service: {}, + apiName2Service: {}, + msgName2Service: {} + }; + + for (var _i = 0, _a = proto.services; _i < _a.length; _i++) { + var v = _a[_i]; + var match = v.name.match(/(.+\/)?([^\/]+)$/); + var path = match[1] || ''; + var name_1 = match[2]; + + if (v.type === 'api') { + var svc = __assign(__assign({}, v), { + reqSchemaId: path + "Ptl" + name_1 + "/Req" + name_1, + resSchemaId: path + "Ptl" + name_1 + "/Res" + name_1 + }); + + map.apiName2Service[v.name] = svc; + map.id2Service[v.id] = svc; + } else { + var svc = __assign(__assign({}, v), { + msgSchemaId: path + "Msg" + name_1 + "/Msg" + name_1 + }); + + map.msgName2Service[v.name] = svc; + map.id2Service[v.id] = svc; + } + } + + return map; + }; + + return ServiceMapUtil; +}(); + +var TransportDataUtil = +/** @class */ +function () { + function TransportDataUtil() {} + + Object.defineProperty(TransportDataUtil, "tsbuffer", { + get: function get() { + if (!this._tsbuffer) { + this._tsbuffer = new TSBuffer(TransportDataProto); + } + + return this._tsbuffer; + }, + enumerable: false, + configurable: true + }); + + TransportDataUtil.encodeApiReturn = function (tsbuffer, service, apiReturn, sn) { + var serverOutputData = { + sn: sn, + serviceId: sn !== undefined ? service.id : undefined + }; + + if (apiReturn.isSucc) { + var op = tsbuffer.encode(apiReturn.res, service.resSchemaId); + + if (!op.isSucc) { + return op; + } + + serverOutputData.buffer = op.buf; + } else { + serverOutputData.error = apiReturn.err; + } + + return this.tsbuffer.encode(serverOutputData, 'ServerOutputData'); + }; + + TransportDataUtil.encodeClientMsg = function (tsbuffer, service, msg) { + var op = tsbuffer.encode(msg, service.msgSchemaId); + + if (!op.isSucc) { + return op; + } + + var serverInputData = { + serviceId: service.id, + buffer: op.buf + }; + return this.tsbuffer.encode(serverInputData, 'ServerInputData'); + }; + + TransportDataUtil.encodeApiReq = function (tsbuffer, service, req, sn) { + var op = tsbuffer.encode(req, service.reqSchemaId); + + if (!op.isSucc) { + return op; + } + + var serverInputData = { + serviceId: service.id, + buffer: op.buf, + sn: sn + }; + return this.tsbuffer.encode(serverInputData, 'ServerInputData'); + }; + + TransportDataUtil.encodeServerMsg = function (tsbuffer, service, msg) { + var op = tsbuffer.encode(msg, service.msgSchemaId); + + if (!op.isSucc) { + return op; + } + + var serverOutputData = { + serviceId: service.id, + buffer: op.buf + }; + return this.tsbuffer.encode(serverOutputData, 'ServerOutputData'); + }; + + TransportDataUtil.parseServerInput = function (tsbuffer, serviceMap, buf) { + var opServerInputData = this.tsbuffer.decode(buf, 'ServerInputData'); + + if (!opServerInputData.isSucc) { + return opServerInputData; + } + + var serverInput = opServerInputData.value; // 确认是哪个Service + + var service = serviceMap.id2Service[serverInput.serviceId]; + + if (!service) { + return { + isSucc: false, + errMsg: "Cannot find service ID: " + serverInput.serviceId + }; + } // 解码Body + + + if (service.type === 'api') { + var opReq = tsbuffer.decode(serverInput.buffer, service.reqSchemaId); + return opReq.isSucc ? { + isSucc: true, + result: { + type: 'api', + service: service, + req: opReq.value, + sn: serverInput.sn + } + } : opReq; + } else { + var opMsg = tsbuffer.decode(serverInput.buffer, service.msgSchemaId); + return opMsg.isSucc ? { + isSucc: true, + result: { + type: 'msg', + service: service, + msg: opMsg.value + } + } : opMsg; + } + }; + + TransportDataUtil.parseServerOutout = function (tsbuffer, serviceMap, buf, serviceId) { + var opServerOutputData = this.tsbuffer.decode(buf, 'ServerOutputData'); + + if (!opServerOutputData.isSucc) { + return opServerOutputData; + } + + var serverOutputData = opServerOutputData.value; + serviceId = serviceId !== null && serviceId !== void 0 ? serviceId : serverOutputData.serviceId; + + if (serviceId === undefined) { + return { + isSucc: false, + errMsg: "Missing 'serviceId' in ServerOutput" + }; + } + + var service = serviceMap.id2Service[serviceId]; + + if (!service) { + return { + isSucc: false, + errMsg: "Invalid service ID: " + serviceId + " (from ServerOutput)" + }; + } + + if (service.type === 'msg') { + if (!serverOutputData.buffer) { + return { + isSucc: false, + errMsg: 'Empty msg buffer (from ServerOutput)' + }; + } + + var opMsg = tsbuffer.decode(serverOutputData.buffer, service.msgSchemaId); + + if (!opMsg.isSucc) { + return opMsg; + } + + return { + isSucc: true, + result: { + type: 'msg', + service: service, + msg: opMsg.value + } + }; + } else { + if (serverOutputData.error) { + return { + isSucc: true, + result: { + type: 'api', + service: service, + sn: serverOutputData.sn, + ret: { + isSucc: false, + err: new TsrpcError(serverOutputData.error) + } + } + }; + } else { + if (!serverOutputData.buffer) { + return { + isSucc: false, + errMsg: 'Empty API res buffer (from ServerOutput)' + }; + } + + var opRes = tsbuffer.decode(serverOutputData.buffer, service.resSchemaId); + + if (!opRes.isSucc) { + return opRes; + } + + return { + isSucc: true, + result: { + type: 'api', + service: service, + sn: serverOutputData.sn, + ret: { + isSucc: true, + res: opRes.value + } + } + }; + } + } + }; + + return TransportDataUtil; +}(); +/** + * An abstract base class for TSRPC Client, + * which includes some common buffer process flows. + * + * @remarks + * You can implement a client on a specific transportation protocol (like HTTP, WebSocket, QUIP) by extend this. + * + * @typeParam ServiceType - `ServiceType` from generated `proto.ts` + * + * @see + * {@link https://github.com/k8w/tsrpc} + * {@link https://github.com/k8w/tsrpc-browser} + * {@link https://github.com/k8w/tsrpc-miniapp} + */ + + +var BaseClient = +/** @class */ +function () { + function BaseClient(proto, options) { + this._msgHandlers = new MsgHandlerManager(); + /** + * {@link Flow} to process `callApi`, `sendMsg`, buffer input/output, etc... + */ + + this.flows = { + // callApi + preCallApiFlow: new Flow(), + preApiReturnFlow: new Flow(), + postApiReturnFlow: new Flow(), + // sendMsg + preSendMsgFlow: new Flow(), + postSendMsgFlow: new Flow(), + // buffer + preSendBufferFlow: new Flow(), + preRecvBufferFlow: new Flow(), + // Connection Flows (Only for WebSocket) + + /** Before connect to WebSocket server */ + preConnectFlow: new Flow(), + + /** After WebSocket connect successfully */ + postConnectFlow: new Flow(), + + /** After WebSocket disconnected (from connected status) */ + postDisconnectFlow: new Flow() + }; + this._apiSnCounter = new Counter(1); + /** + * Pending API Requests + */ + + this._pendingApis = []; + this.options = options; + this.serviceMap = ServiceMapUtil.getServiceMap(proto); + this.tsbuffer = new TSBuffer(proto.types); + this.logger = this.options.logger; + } + + Object.defineProperty(BaseClient.prototype, "lastSN", { + /** + * The `SN` number of the last `callApi()`, + * which can be passed to `abort()` to abort an API request. + * @example + * ```ts + * client.callApi('xxx', { value: 'xxx' }) + * .then(ret=>{ console.log('succ', ret) }); + * let lastSN = client.lastSN; + * client.abort(lastSN); + * ``` + */ + get: function get() { + return this._apiSnCounter.last; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(BaseClient.prototype, "nextSN", { + /** + * The `SN` number of the next `callApi()`, + * which can be passed to `abort()` to abort an API request. + * @example + * ```ts + * let nextSN = client.nextSN; + * client.callApi('xxx', { value: 'xxx' }) + * ``` + */ + get: function get() { + return this._apiSnCounter.getNext(true); + }, + enumerable: false, + configurable: true + }); + /** + * Send request and wait for the return + * @param apiName + * @param req - Request body + * @param options - Transport options + * @returns return a `ApiReturn`, all error (network error, business error, code exception...) is unified as `TsrpcError`. + * The promise is never rejected, so you just need to process all error in one place. + */ + + BaseClient.prototype.callApi = function (apiName, req, options) { + if (options === void 0) { + options = {}; + } + + return __awaiter(this, void 0, void 0, function () { + var sn, pendingItem, promise; + + var _this = this; + + return __generator(this, function (_a) { + sn = this._apiSnCounter.getNext(); + pendingItem = { + sn: sn, + abortKey: options.abortKey, + service: this.serviceMap.apiName2Service[apiName] + }; + + this._pendingApis.push(pendingItem); + + promise = new Promise(function (rs) { + return __awaiter(_this, void 0, void 0, function () { + var pre, ret, preReturn; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + return [4 + /*yield*/ + , this.flows.preCallApiFlow.exec({ + apiName: apiName, + req: req, + options: options + }, this.logger)]; + + case 1: + pre = _a.sent(); + + if (!pre || pendingItem.isAborted) { + this.abort(pendingItem.sn); + return [2 + /*return*/ + ]; + } + + if (!pre.return) return [3 + /*break*/ + , 2]; + ret = pre.return; + return [3 + /*break*/ + , 4]; + + case 2: + return [4 + /*yield*/ + , this._doCallApi(pre.apiName, pre.req, pre.options, pendingItem)]; + + case 3: + // do call means it will send buffer via network + ret = _a.sent(); + _a.label = 4; + + case 4: + if (pendingItem.isAborted) { + return [2 + /*return*/ + ]; + } + + return [4 + /*yield*/ + , this.flows.preApiReturnFlow.exec(__assign(__assign({}, pre), { + return: ret + }), this.logger)]; + + case 5: + preReturn = _a.sent(); + + if (!preReturn) { + this.abort(pendingItem.sn); + return [2 + /*return*/ + ]; + } + + rs(preReturn.return); // Post Flow + + this.flows.postApiReturnFlow.exec(preReturn, this.logger); + return [2 + /*return*/ + ]; + } + }); + }); + }); // Finally clear pendings + + promise.catch().then(function () { + _this._pendingApis.removeOne(function (v) { + return v.sn === pendingItem.sn; + }); + }); + return [2 + /*return*/ + , promise]; + }); + }); + }; + + BaseClient.prototype._doCallApi = function (apiName, req, options, pendingItem) { + var _a; + + if (options === void 0) { + options = {}; + } + + return __awaiter(this, void 0, void 0, function () { + var promise; + + var _this = this; + + return __generator(this, function (_b) { + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.log("[ApiReq] #" + pendingItem.sn, apiName, req); + promise = new Promise(function (rs) { + return __awaiter(_this, void 0, void 0, function () { + var service, opEncode, promiseReturn, promiseSend, opSend, ret; + + var _a, _b, _c; + + return __generator(this, function (_d) { + switch (_d.label) { + case 0: + service = this.serviceMap.apiName2Service[apiName]; + + if (!service) { + rs({ + isSucc: false, + err: new TsrpcError('Invalid api name: ' + apiName, { + code: 'INVALID_API_NAME', + type: TsrpcErrorType.ClientError + }) + }); + return [2 + /*return*/ + ]; + } + + pendingItem.service = service; + opEncode = this._encodeApiReq(service, req, pendingItem); + + if (!opEncode.isSucc) { + rs({ + isSucc: false, + err: new TsrpcError(opEncode.errMsg, { + type: TsrpcErrorType.ClientError, + code: 'ENCODE_REQ_ERR' + }) + }); + return [2 + /*return*/ + ]; + } + + promiseReturn = this._waitApiReturn(pendingItem, (_a = options.timeout) !== null && _a !== void 0 ? _a : this.options.timeout); + promiseSend = this._sendBuf(opEncode.buf, options, service.id, pendingItem); + return [4 + /*yield*/ + , promiseSend]; + + case 1: + opSend = _d.sent(); + + if (opSend.err) { + rs({ + isSucc: false, + err: opSend.err + }); + return [2 + /*return*/ + ]; + } + + return [4 + /*yield*/ + , promiseReturn]; + + case 2: + ret = _d.sent(); + + if (pendingItem.isAborted) { + return [2 + /*return*/ + ]; + } + + if (ret.isSucc) { + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.log("[ApiRes] #" + pendingItem.sn + " " + apiName, ret.res); + } else { + (_c = this.logger) === null || _c === void 0 ? void 0 : _c.log("[ApiErr] #" + pendingItem.sn + " " + apiName, ret.err); + } + + rs(ret); + return [2 + /*return*/ + ]; + } + }); + }); + }); + return [2 + /*return*/ + , promise]; + }); + }); + }; + + BaseClient.prototype._encodeApiReq = function (service, req, pendingItem) { + return TransportDataUtil.encodeApiReq(this.tsbuffer, service, req, this.type === 'LONG' ? pendingItem.sn : undefined); + }; + /** + * Send message, without response, not ensuring the server is received and processed correctly. + * @param msgName + * @param msg - Message body + * @param options - Transport options + * @returns If the promise is resolved, it means the request is sent to system kernel successfully. + * Notice that not means the server received and processed the message correctly. + */ + + + BaseClient.prototype.sendMsg = function (msgName, msg, options) { + var _this = this; + + if (options === void 0) { + options = {}; + } + + var promise = new Promise(function (rs) { + return __awaiter(_this, void 0, void 0, function () { + var pre, service, opEncode, promiseSend, opSend; + + var _a, _b; + + return __generator(this, function (_c) { + switch (_c.label) { + case 0: + return [4 + /*yield*/ + , this.flows.preSendMsgFlow.exec({ + msgName: msgName, + msg: msg, + options: options + }, this.logger)]; + + case 1: + pre = _c.sent(); + + if (!pre) { + return [2 + /*return*/ + ]; + } // The msg is not prevented by pre flow + + + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.log("[SendMsg]", msgName, msg); + service = this.serviceMap.msgName2Service[msgName]; + + if (!service) { + (_b = this.logger) === null || _b === void 0 ? void 0 : _b.error('Invalid msg name: ' + msgName); + rs({ + isSucc: false, + err: new TsrpcError('Invalid msg name: ' + msgName, { + code: 'INVALID_MSG_NAME', + type: TsrpcErrorType.ClientError + }) + }); + return [2 + /*return*/ + ]; + } + + opEncode = this._encodeClientMsg(service, msg); + + if (!opEncode.isSucc) { + rs({ + isSucc: false, + err: new TsrpcError(opEncode.errMsg, { + type: TsrpcErrorType.ClientError, + code: 'ENCODE_MSG_ERR' + }) + }); + return [2 + /*return*/ + ]; + } + + promiseSend = this._sendBuf(opEncode.buf, options, service.id); + return [4 + /*yield*/ + , promiseSend]; + + case 2: + opSend = _c.sent(); + + if (opSend.err) { + rs({ + isSucc: false, + err: opSend.err + }); + return [2 + /*return*/ + ]; + } + + rs({ + isSucc: true + }); // Post Flow + + this.flows.postSendMsgFlow.exec(pre, this.logger); + return [2 + /*return*/ + ]; + } + }); + }); + }); + return promise; + }; + + BaseClient.prototype._encodeClientMsg = function (service, msg) { + return TransportDataUtil.encodeClientMsg(this.tsbuffer, service, msg); + }; + /** + * Add a message handler, + * duplicate handlers to the same `msgName` would be ignored. + * @param msgName + * @param handler + * @returns + */ + + + BaseClient.prototype.listenMsg = function (msgName, handler) { + this._msgHandlers.addHandler(msgName, handler); + + return handler; + }; + /** + * Remove a message handler + */ + + + BaseClient.prototype.unlistenMsg = function (msgName, handler) { + this._msgHandlers.removeHandler(msgName, handler); + }; + /** + * Remove all handlers from a message + */ + + + BaseClient.prototype.unlistenMsgAll = function (msgName) { + this._msgHandlers.removeAllHandlers(msgName); + }; + /** + * Abort a pending API request, it makes the promise returned by `callApi()` neither resolved nor rejected forever. + * @param sn - Every api request has a unique `sn` number, you can get it by `this.lastSN` + */ + + + BaseClient.prototype.abort = function (sn) { + var _a, _b; // Find + + + var index = this._pendingApis.findIndex(function (v) { + return v.sn === sn; + }); + + if (index === -1) { + return; + } + + var pendingItem = this._pendingApis[index]; // Clear + + this._pendingApis.splice(index, 1); + + pendingItem.onReturn = undefined; + pendingItem.isAborted = true; // Log + + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.log("[ApiAbort] #" + pendingItem.sn + " " + pendingItem.service.name); // onAbort + + (_b = pendingItem.onAbort) === null || _b === void 0 ? void 0 : _b.call(pendingItem); + }; + /** + * Abort all API requests that has the `abortKey`. + * It makes the promise returned by `callApi` neither resolved nor rejected forever. + * @param abortKey - The `abortKey` of options when `callApi()`, see {@link TransportOptions.abortKey}. + * @example + * ```ts + * // Send API request many times + * client.callApi('SendData', { data: 'AAA' }, { abortKey: 'Session#123' }); + * client.callApi('SendData', { data: 'BBB' }, { abortKey: 'Session#123' }); + * client.callApi('SendData', { data: 'CCC' }, { abortKey: 'Session#123' }); + * + * // And abort the at once + * client.abortByKey('Session#123'); + * ``` + */ + + + BaseClient.prototype.abortByKey = function (abortKey) { + var _this = this; + + this._pendingApis.filter(function (v) { + return v.abortKey === abortKey; + }).forEach(function (v) { + _this.abort(v.sn); + }); + }; + /** + * Abort all pending API requests. + * It makes the promise returned by `callApi` neither resolved nor rejected forever. + */ + + + BaseClient.prototype.abortAll = function () { + var _this = this; + + this._pendingApis.slice().forEach(function (v) { + return _this.abort(v.sn); + }); + }; + + BaseClient.prototype._onRecvBuf = function (buf, pendingApiItem) { + var _a, _b, _c, _d, _e, _f, _g; + + return __awaiter(this, void 0, void 0, function () { + var sn, pre, opParsed, parsed; + return __generator(this, function (_h) { + switch (_h.label) { + case 0: + sn = pendingApiItem === null || pendingApiItem === void 0 ? void 0 : pendingApiItem.sn; + this.options.debugBuf && ((_a = this.logger) === null || _a === void 0 ? void 0 : _a.debug('[RecvBuf]' + (sn ? ' #' + sn : ''), 'length=' + buf.length, buf)); + return [4 + /*yield*/ + , this.flows.preRecvBufferFlow.exec({ + buf: buf, + sn: sn + }, this.logger)]; + + case 1: + pre = _h.sent(); + + if (!pre) { + return [2 + /*return*/ + ]; + } + + buf = pre.buf; + opParsed = TransportDataUtil.parseServerOutout(this.tsbuffer, this.serviceMap, buf, pendingApiItem === null || pendingApiItem === void 0 ? void 0 : pendingApiItem.service.id); + + if (opParsed.isSucc) { + parsed = opParsed.result; + + if (parsed.type === 'api') { + sn = sn !== null && sn !== void 0 ? sn : parsed.sn; // call ApiReturn listeners + + (_c = (_b = this._pendingApis.find(function (v) { + return v.sn === sn; + })) === null || _b === void 0 ? void 0 : _b.onReturn) === null || _c === void 0 ? void 0 : _c.call(_b, parsed.ret); + } else if (parsed.type === 'msg') { + (_d = this.logger) === null || _d === void 0 ? void 0 : _d.log("[RecvMsg] " + parsed.service.name, parsed.msg); + + this._msgHandlers.forEachHandler(parsed.service.name, this.logger, parsed.msg, this); + } + } else { + (_e = this.logger) === null || _e === void 0 ? void 0 : _e.error('ParseServerOutputError: ' + opParsed.errMsg); + (_f = this.logger) === null || _f === void 0 ? void 0 : _f.error('Please check whether the proto on the server is the same as that on the client'); + + if (pendingApiItem) { + (_g = pendingApiItem.onReturn) === null || _g === void 0 ? void 0 : _g.call(pendingApiItem, { + isSucc: false, + err: new TsrpcError('Parse server output error', { + type: TsrpcErrorType.ServerError + }) + }); + } + } + + return [2 + /*return*/ + ]; + } + }); + }); + }; + /** + * @param sn + * @param timeout + * @returns `undefined` 代表 canceled + */ + + + BaseClient.prototype._waitApiReturn = function (pendingItem, timeout) { + return __awaiter(this, void 0, void 0, function () { + var _this = this; + + return __generator(this, function (_a) { + return [2 + /*return*/ + , new Promise(function (rs) { + // Timeout + var timer; + + if (timeout) { + timer = setTimeout(function () { + timer = undefined; + + _this._pendingApis.removeOne(function (v) { + return v.sn === pendingItem.sn; + }); + + rs({ + isSucc: false, + err: new TsrpcError('Request Timeout', { + type: TsrpcErrorType.NetworkError, + code: 'TIMEOUT' + }) + }); + }, timeout); + } // Listener (trigger by `this._onRecvBuf`) + + + pendingItem.onReturn = function (ret) { + if (timer) { + clearTimeout(timer); + timer = undefined; + } + + _this._pendingApis.removeOne(function (v) { + return v.sn === pendingItem.sn; + }); + + rs(ret); + }; + })]; + }); + }); + }; + + return BaseClient; +}(); + +var defaultBaseClientOptions = {}; +/** + * Base HTTP Client + */ + +var BaseHttpClient = +/** @class */ +function (_super) { + __extends(BaseHttpClient, _super); + + function BaseHttpClient(proto, http, options) { + var _a; + + var _this = _super.call(this, proto, __assign(__assign({}, defaultBaseHttpClientOptions), options)) || this; + + _this.type = 'SHORT'; + _this._http = http; + _this._jsonServer = _this.options.server + (_this.options.server.endsWith('/') ? '' : '/'); + (_a = _this.logger) === null || _a === void 0 ? void 0 : _a.log('TSRPC HTTP Client :', _this.options.server); + return _this; + } // Hack for JSON compatibility + + + BaseHttpClient.prototype._encodeApiReq = function (service, req, pendingItem) { + if (this.options.json) { + if (this.options.jsonPrune) { + var opPrune = this.tsbuffer.prune(req, pendingItem.service.reqSchemaId); + + if (!opPrune.isSucc) { + return opPrune; + } + + req = opPrune.pruneOutput; + } + + return { + isSucc: true, + buf: JSON.stringify(req) + }; + } else { + return TransportDataUtil.encodeApiReq(this.tsbuffer, service, req, undefined); + } + }; // Hack for JSON compatibility + + + BaseHttpClient.prototype._encodeClientMsg = function (service, msg) { + if (this.options.json) { + if (this.options.jsonPrune) { + var opPrune = this.tsbuffer.prune(msg, service.msgSchemaId); + + if (!opPrune.isSucc) { + return opPrune; + } + + msg = opPrune.pruneOutput; + } + + return { + isSucc: true, + buf: JSON.stringify(msg) + }; + } else { + return TransportDataUtil.encodeClientMsg(this.tsbuffer, service, msg); + } + }; + + BaseHttpClient.prototype._sendBuf = function (buf, options, serviceId, pendingApiItem) { + return __awaiter(this, void 0, void 0, function () { + var sn, promise; + + var _this = this; + + return __generator(this, function (_a) { + // JSON Compatible Mode + if (this.options.json) { + return [2 + /*return*/ + , this._sendJSON(buf, options, serviceId, pendingApiItem)]; + } + + sn = pendingApiItem === null || pendingApiItem === void 0 ? void 0 : pendingApiItem.sn; + promise = new Promise(function (rs) { + return __awaiter(_this, void 0, void 0, function () { + var pre, _a, fetchPromise, abort, fetchRes; + + var _b; + + return __generator(this, function (_c) { + switch (_c.label) { + case 0: + return [4 + /*yield*/ + , this.flows.preSendBufferFlow.exec({ + buf: buf, + sn: pendingApiItem === null || pendingApiItem === void 0 ? void 0 : pendingApiItem.sn + }, this.logger)]; + + case 1: + pre = _c.sent(); + + if (!pre) { + return [2 + /*return*/ + ]; + } + + buf = pre.buf; // Do Send + + this.options.debugBuf && ((_b = this.logger) === null || _b === void 0 ? void 0 : _b.debug('[SendBuf]' + (sn ? ' #' + sn : ''), "length=" + buf.length, buf)); + _a = this._http.fetch({ + url: this.options.server, + data: buf, + method: 'POST', + timeout: options.timeout || this.options.timeout, + transportOptions: options, + responseType: 'arraybuffer' + }), fetchPromise = _a.promise, abort = _a.abort; + + if (pendingApiItem) { + pendingApiItem.onAbort = function () { + abort(); + }; + } // Aborted + + + if (pendingApiItem === null || pendingApiItem === void 0 ? void 0 : pendingApiItem.isAborted) { + return [2 + /*return*/ + ]; + } + + return [4 + /*yield*/ + , fetchPromise]; + + case 2: + fetchRes = _c.sent(); + + if (!fetchRes.isSucc) { + rs({ + err: fetchRes.err + }); + return [2 + /*return*/ + ]; + } + + rs({}); + + this._onRecvBuf(fetchRes.res, pendingApiItem); + + return [2 + /*return*/ + ]; + } + }); + }); + }); // Finally + + promise.catch(function (e) {}).then(function () { + if (pendingApiItem) { + pendingApiItem.onAbort = undefined; + } + }); + return [2 + /*return*/ + , promise]; + }); + }); + }; + + BaseHttpClient.prototype._sendJSON = function (jsonStr, options, serviceId, pendingApiItem) { + return __awaiter(this, void 0, void 0, function () { + var _this = this; + + return __generator(this, function (_a) { + return [2 + /*return*/ + , new Promise(function (rs) { + return __awaiter(_this, void 0, void 0, function () { + var _a, fetchPromise, abort, fetchRes, ret, opPrune; + + var _b; + + return __generator(this, function (_c) { + switch (_c.label) { + case 0: + _a = this._http.fetch({ + url: this._jsonServer + this.serviceMap.id2Service[serviceId].name, + data: jsonStr, + method: 'POST', + timeout: options.timeout || this.options.timeout, + headers: { + 'Content-Type': 'application/json' + }, + transportOptions: options, + responseType: 'text' + }), fetchPromise = _a.promise, abort = _a.abort; + + if (pendingApiItem) { + pendingApiItem.onAbort = function () { + abort(); + }; + } // Aborted + + + if (pendingApiItem === null || pendingApiItem === void 0 ? void 0 : pendingApiItem.isAborted) { + return [2 + /*return*/ + ]; + } + + return [4 + /*yield*/ + , fetchPromise]; + + case 1: + fetchRes = _c.sent(); + + if (!fetchRes.isSucc) { + rs({ + err: fetchRes.err + }); + return [2 + /*return*/ + ]; + } + + rs({}); + + try { + ret = JSON.parse(fetchRes.res); + } catch (e) { + ret = { + isSucc: false, + err: new TsrpcError({ + message: e.message, + type: TsrpcError.Type.ServerError, + res: fetchRes.res + }) + }; + } // API Return + + + if (pendingApiItem) { + if (ret.isSucc) { + if (this.options.jsonPrune) { + opPrune = this.tsbuffer.prune(ret.res, pendingApiItem.service.resSchemaId); + + if (opPrune.isSucc) { + ret.res = opPrune.pruneOutput; + } else { + ret = { + isSucc: false, + err: new TsrpcError('Invalid Server Output', { + type: TsrpcError.Type.ClientError, + innerErr: opPrune.errMsg + }) + }; + } + } + } else { + ret.err = new TsrpcError(ret.err); + } + + (_b = pendingApiItem.onReturn) === null || _b === void 0 ? void 0 : _b.call(pendingApiItem, ret); + } + + return [2 + /*return*/ + ]; + } + }); + }); + })]; + }); + }); + }; + + return BaseHttpClient; +}(BaseClient); + +var defaultBaseHttpClientOptions = __assign(__assign({}, defaultBaseClientOptions), { + server: 'http://localhost:3000', + // logger: new TerminalColorLogger(), + json: false, + jsonPrune: true +}); +/** + * WebSocket Client for TSRPC. + * It uses native `WebSocket` of browser. + * @typeParam ServiceType - `ServiceType` from generated `proto.ts` + */ + + +var BaseWsClient = +/** @class */ +function (_super) { + __extends(BaseWsClient, _super); + + function BaseWsClient(proto, wsp, options) { + var _a; + + var _this = _super.call(this, proto, __assign(__assign({}, defaultBaseWsClientOptions), options)) || this; + + _this.type = 'LONG'; + + _this._onWsOpen = function () { + var _a; + + if (!_this._connecting) { + return; + } + + _this._status = WsClientStatus.Opened; + + _this._connecting.rs({ + isSucc: true + }); + + _this._connecting = undefined; + (_a = _this.logger) === null || _a === void 0 ? void 0 : _a.log('WebSocket connection to server successful'); + + _this.flows.postConnectFlow.exec({}, _this.logger); + }; + + _this._onWsClose = function (code, reason) { + var _a, _b; + + var isConnectedBefore = _this.isConnected; + _this._status = WsClientStatus.Closed; // 连接中,返回连接失败 + + if (_this._connecting) { + _this._connecting.rs({ + isSucc: false, + errMsg: 'WebSocket connection to server failed' + }); + + _this._connecting = undefined; + } // disconnect中,返回成功 + + + var isManual = !!_this._rsDisconnecting; + + if (_this._rsDisconnecting) { + _this._rsDisconnecting(); + + _this._rsDisconnecting = undefined; + (_a = _this.logger) === null || _a === void 0 ? void 0 : _a.log('Disconnected succ', "code=" + code + " reason=" + reason); + } // 非 disconnect 中,从连接中意外断开 + else if (isConnectedBefore) { + (_b = _this.logger) === null || _b === void 0 ? void 0 : _b.log("Lost connection to " + _this.options.server, "code=" + code + " reason=" + reason); + } // postDisconnectFlow,仅从连接状态断开时触发 + + + if (isConnectedBefore) { + _this.flows.postDisconnectFlow.exec({ + reason: reason, + isManual: isManual + }, _this.logger); + } + }; + + _this._onWsError = function (e) { + var _a; + + (_a = _this.logger) === null || _a === void 0 ? void 0 : _a.error('[WebSocket Error]', e); + }; + + _this._onWsMessage = function (data) { + var _a; + + if (typeof data === 'string') { + (_a = _this.logger) === null || _a === void 0 ? void 0 : _a.warn('[RecvText]', data); + } else { + _this._onRecvBuf(data); + } + }; + + _this._status = WsClientStatus.Closed; + _this._wsp = wsp; + wsp.options = { + onOpen: _this._onWsOpen, + onClose: _this._onWsClose, + onError: _this._onWsError, + onMessage: _this._onWsMessage, + logger: _this.logger + }; + (_a = _this.logger) === null || _a === void 0 ? void 0 : _a.log('TSRPC WebSocket Client :', _this.options.server); + return _this; + } + + BaseWsClient.prototype._sendBuf = function (buf, options, serviceId, pendingApiItem) { + return __awaiter(this, void 0, void 0, function () { + var _this = this; + + return __generator(this, function (_a) { + return [2 + /*return*/ + , new Promise(function (rs) { + return __awaiter(_this, void 0, void 0, function () { + var pre; + + var _a; + + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + return [4 + /*yield*/ + , this.flows.preSendBufferFlow.exec({ + buf: buf, + sn: pendingApiItem === null || pendingApiItem === void 0 ? void 0 : pendingApiItem.sn + }, this.logger)]; + + case 1: + pre = _b.sent(); + + if (!pre) { + return [2 + /*return*/ + ]; + } + + buf = pre.buf; + + if (!this.isConnected) { + rs({ + err: new TsrpcError('WebSocket is not connected', { + code: 'WS_NOT_OPEN', + type: TsrpcError.Type.ClientError + }) + }); + return [2 + /*return*/ + ]; + } // Do Send + + + if (this.options.debugBuf && buf instanceof Uint8Array) { + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.debug('[SendBuf]' + (pendingApiItem ? ' #' + pendingApiItem.sn : ''), "length=" + buf.byteLength, buf); + } + + rs(this._wsp.send(buf)); + return [2 + /*return*/ + ]; + } + }); + }); + })]; + }); + }); + }; + + Object.defineProperty(BaseWsClient.prototype, "status", { + get: function get() { + return this._status; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(BaseWsClient.prototype, "isConnected", { + get: function get() { + return this._status === WsClientStatus.Opened; + }, + enumerable: false, + configurable: true + }); + /** + * Start connecting, you must connect first before `callApi()` and `sendMsg()`. + * @throws never + */ + + BaseWsClient.prototype.connect = function () { + var _a; + + return __awaiter(this, void 0, void 0, function () { + var pre, promiseConnect; + + var _this = this; + + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + // 已连接成功 + if (this.isConnected) { + return [2 + /*return*/ + , { + isSucc: true + }]; + } // 已连接中 + + + if (this._connecting) { + return [2 + /*return*/ + , this._connecting.promise]; + } + + return [4 + /*yield*/ + , this.flows.preConnectFlow.exec({}, this.logger)]; + + case 1: + pre = _b.sent(); // Pre return + + if (pre === null || pre === void 0 ? void 0 : pre.return) { + return [2 + /*return*/ + , pre.return]; + } // Canceled + + + if (!pre) { + return [2 + /*return*/ + , new Promise(function (rs) {})]; + } + + try { + this._wsp.connect(this.options.server); + } catch (e) { + return [2 + /*return*/ + , { + isSucc: false, + errMsg: e.message + }]; + } + + this._status = WsClientStatus.Opening; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.log("Start connecting " + this.options.server + "..."); + this._connecting = {}; + promiseConnect = new Promise(function (rs) { + _this._connecting.rs = rs; + }); + this._connecting.promise = promiseConnect; + return [2 + /*return*/ + , promiseConnect]; + } + }); + }); + }; + /** + * Disconnect immediately + * @throws never + */ + + + BaseWsClient.prototype.disconnect = function (code, reason) { + var _a; + + return __awaiter(this, void 0, void 0, function () { + var _this = this; + + return __generator(this, function (_b) { + if (this._status === WsClientStatus.Closed) { + return [2 + /*return*/ + ]; + } + + this._status = WsClientStatus.Closing; + (_a = this.logger) === null || _a === void 0 ? void 0 : _a.log('Start disconnecting...'); + return [2 + /*return*/ + , new Promise(function (rs) { + _this._rsDisconnecting = rs; + + _this._wsp.close(code, reason); + })]; + }); + }); + }; + + return BaseWsClient; +}(BaseClient); + +var defaultBaseWsClientOptions = __assign(__assign({}, defaultBaseClientOptions), { + server: 'ws://localhost:3000' +}); + +var WsClientStatus; + +(function (WsClientStatus) { + WsClientStatus["Opening"] = "OPENING"; + WsClientStatus["Opened"] = "OPENED"; + WsClientStatus["Closing"] = "CLOSING"; + WsClientStatus["Closed"] = "CLOSED"; +})(WsClientStatus || (WsClientStatus = {})); + +/** + * @internal + */ +var HttpProxy = /** @class */ (function () { + function HttpProxy() { + } + HttpProxy.prototype.fetch = function (options) { + var _this = this; + var rs; + var promise = new Promise(function (_rs) { + rs = _rs; + }); + var xhr = new XMLHttpRequest(); + if (navigator.userAgent.indexOf('MSIE 8.0;') > -1) { + //IE8 不支持onload onabort onerror事件 + xhr.onreadystatechange = function () { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + if (xhr.readyState == 4) { + //Network Error + if (xhr.status == 0 || (xhr.response == null && xhr.responseText == null)) { + rs({ + isSucc: false, + err: new TsrpcError('Network Error', { + type: TsrpcError.Type.NetworkError, + httpCode: xhr.status + }) + }); + return [2 /*return*/]; + } + //IE9 wrongURL 会返回12029 + if (xhr.status == 12029) { + rs({ + isSucc: false, + err: new TsrpcError({ + message: 'Network Error', + type: TsrpcError.Type.NetworkError, + httpCode: xhr.status + }) + }); + return [2 /*return*/]; + } + // Res + rs({ + isSucc: true, + res: options.responseType === 'text' ? xhr.responseText : new Uint8Array(xhr.response) + }); + } + return [2 /*return*/]; + }); + }); }; + } + else { + xhr.onerror = function () { + rs({ + isSucc: false, + err: new TsrpcError({ + message: 'Network Error', + type: TsrpcError.Type.NetworkError, + httpCode: xhr.status + }) + }); + }; + // 有的平台 超时不触发onerror + xhr.ontimeout = function () { + rs({ + isSucc: false, + err: new TsrpcError({ + message: 'Request Timeout', + type: TsrpcError.Type.NetworkError, + code: 'TIMEOUT' + }) + }); + }; + // Res + xhr.onload = function () { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + rs({ + isSucc: true, + res: xhr.response && (options.responseType === 'text' ? xhr.responseText : new Uint8Array(xhr.response)) + }); + return [2 /*return*/]; + }); + }); }; + var transportOptions_1 = options.transportOptions; + if (!!transportOptions_1.onProgress) { + xhr.upload.onprogress = function (e) { + var _a; + (_a = transportOptions_1.onProgress) === null || _a === void 0 ? void 0 : _a.call(transportOptions_1, e.loaded / e.total); + }; + } + } + xhr.open(options.method, options.url, true); + if (options.headers) { + for (var key in options.headers) { + xhr.setRequestHeader(key, options.headers[key]); + } + } + xhr.responseType = options.responseType; + var timeout = options.timeout; + if (timeout) { + xhr.timeout = timeout; + } + xhr.send(options.data); + var abort = xhr.abort.bind(xhr); + return { + promise: promise, + abort: abort + }; + }; + return HttpProxy; +}()); + +/** + * HTTP Client for TSRPC. + * It uses XMLHttpRequest to send requests. + * @typeParam ServiceType - `ServiceType` from generated `proto.ts` + */ +var HttpClient = /** @class */ (function (_super) { + __extends(HttpClient, _super); + function HttpClient(proto, options) { + var _this = this; + var httpProxy = new HttpProxy; + _this = _super.call(this, proto, httpProxy, __assign(__assign({}, defaultHttpClientOptions), options)) || this; + return _this; + } + HttpClient.prototype.callApi = function (apiName, req, options) { + if (options === void 0) { options = {}; } + return _super.prototype.callApi.call(this, apiName, req, options); + }; + HttpClient.prototype.sendMsg = function (msgName, msg, options) { + if (options === void 0) { options = {}; } + return _super.prototype.sendMsg.call(this, msgName, msg, options); + }; + return HttpClient; +}(BaseHttpClient)); +var defaultHttpClientOptions = __assign({}, defaultBaseHttpClientOptions); + +/** + * @internal + */ +var WebSocketProxy = /** @class */ (function () { + function WebSocketProxy() { + } + WebSocketProxy.prototype.connect = function (server) { + var _this = this; + this._ws = new WebSocket(server); + this._ws.binaryType = 'arraybuffer'; + this._ws.onopen = this.options.onOpen; + this._ws.onclose = function (e) { + _this.options.onClose(e.code, e.reason); + _this._ws = undefined; + }; + this._ws.onmessage = function (e) { + var _a; + if (e.data instanceof ArrayBuffer) { + _this.options.onMessage(new Uint8Array(e.data)); + } + else if (typeof e.data === 'string') { + _this.options.onMessage(e.data); + } + else { + (_a = _this.options.logger) === null || _a === void 0 ? void 0 : _a.warn('[Unresolved Recv]', e.data); + } + }; + }; + WebSocketProxy.prototype.close = function (code, reason) { + var _a; + (_a = this._ws) === null || _a === void 0 ? void 0 : _a.close(code, reason); + this._ws = undefined; + }; + WebSocketProxy.prototype.send = function (data) { + return __awaiter(this, void 0, void 0, function () { + var sendData, buf; + return __generator(this, function (_a) { + try { + sendData = void 0; + if (typeof data === 'string') { + sendData = data; + } + else { + buf = data; + if (buf.byteOffset === 0 && buf.byteLength === buf.buffer.byteLength) { + sendData = buf.buffer; + } + else { + sendData = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + } + } + this._ws.send(sendData); + return [2 /*return*/, {}]; + } + catch (err) { + return [2 /*return*/, { + err: new TsrpcError('Network Error', { + code: 'SEND_BUF_ERR', + type: TsrpcError.Type.NetworkError, + innerErr: err + }) + }]; + } + return [2 /*return*/]; + }); + }); + }; + return WebSocketProxy; +}()); + +/** + * Client for TSRPC WebSocket Server. + * @typeParam ServiceType - `ServiceType` from generated `proto.ts` + */ +var WsClient = /** @class */ (function (_super) { + __extends(WsClient, _super); + function WsClient(proto, options) { + var _this = this; + var wsp = new WebSocketProxy(); + _this = _super.call(this, proto, wsp, __assign(__assign({}, defaultWsClientOptions), options)) || this; + return _this; + } + return WsClient; +}(BaseWsClient)); +var defaultWsClientOptions = __assign({}, defaultBaseWsClientOptions); + +export { HttpClient, TransportDataProto, TsrpcError, TsrpcErrorType, WsClient }; diff --git a/examples/layaair/frontend/src/ui/layaMaxUI.ts b/examples/layaair/frontend/src/ui/layaMaxUI.ts new file mode 100644 index 0000000..0a0dce7 --- /dev/null +++ b/examples/layaair/frontend/src/ui/layaMaxUI.ts @@ -0,0 +1,17 @@ +/**This class is automatically generated by LayaAirIDE, please do not make any modifications. */ +import View=Laya.View; +import Dialog=Laya.Dialog; +import Scene=Laya.Scene; +var REG: Function = Laya.ClassUtils.regClass; +export module ui.test { + export class TestSceneUI extends Scene { + public scoreLbl:Laya.Label; + public tipLbll:Laya.Label; + constructor(){ super()} + createChildren():void { + super.createChildren(); + this.loadScene("test/TestScene"); + } + } + REG("ui.test.TestSceneUI",TestSceneUI); +} \ No newline at end of file diff --git a/examples/layaair/frontend/tsconfig.json b/examples/layaair/frontend/tsconfig.json new file mode 100644 index 0000000..83d33de --- /dev/null +++ b/examples/layaair/frontend/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "module": "es6", + "target": "es6", + "noEmitHelpers": true, + "sourceMap": false + }, + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/examples/layaair/frontend/tsrpc-laya.laya b/examples/layaair/frontend/tsrpc-laya.laya new file mode 100644 index 0000000..f48d043 --- /dev/null +++ b/examples/layaair/frontend/tsrpc-laya.laya @@ -0,0 +1 @@ +{"proName":"tsrpc-laya","engineType":0,"proType":1,"layaProType":1,"version":"2.1.0"} \ No newline at end of file